From 528a778e3864064bfccd8295abd1ec23da778843 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Thu, 18 Feb 2021 14:16:15 +0100 Subject: [PATCH] open-converged-wireless: Import 21.02 based uCentral tree Signed-off-by: John Crispin --- .gitignore | 1 + Makefile | 8 + ...el-image-before-building-modules-pac.patch | 48 + .../0002-kernel-add-linux-5.10-support.patch | 33391 +++++ ...ar8216-fix-kernel-5.10-compile-error.patch | 41 + ...pdate-version-switch-for-of_get_phy_.patch | 45 + ...-busy-wait-loop-in-mediatek-PPE-code.patch | 36 + ...0-make-UDP-tunneling-user-selectable.patch | 43 + ...missing-partitions-doc-syntax-commit.patch | 347 + .../0008-kernel-5.10-refresh-patches.patch | 226 + ...ild-with-CONFIG_STRIP_KERNEL_EXPORTS.patch | 46 + ...kernel-update-kernel-5.10-to-5.10.16.patch | 60 + ...nt-bad-block-management-table-suppor.patch | 910 + ...-work-in-progress-linux-5.10-support.patch | 106266 +++++++++++++++ ...port-for-configuring-BMT-table-size-.patch | 215 + ...rt-for-enabling-fit-firmware-partiti.patch | 43 + ...5-mediatek-add-linksys-e8450-support.patch | 757 + ...atek-linksys-e8450-fix-wifi-and-lan4.patch | 42 + ...t-for-building-FIT-image-with-filesy.patch | 754 + ...allow-limiting-rootfs_data-by-settin.patch | 74 + ...diatek-add-support-for-linksys-e8450.patch | 1351 + ...s-add-defaults-for-linksys-e8450-ubi.patch | 49 + ...-e8450-ubi-add-alternative-UBI-NAND-.patch | 1584 + ...2-realtek-update-to-latest-owrt-HEAD.patch | 1506 + build.sh | 41 + config.yml | 8 + dock-run.sh | 9 + docker/Dockerfile | 12 + feeds/bluetooth/bluetooth-6lowpand/Makefile | 53 + .../files/bluetooth_6lowpand.conf | 0 .../files/bluetooth_6lowpand.init | 24 + feeds/bluetooth/bluez-ibeacon/Makefile | 33 + feeds/bluetooth/bluez-ibeacon/files/ibeacon | 25 + feeds/bluetooth/ubtled/Makefile | 32 + feeds/bluetooth/ubtled/files/99-btle | 8 + feeds/bluetooth/ubtled/files/btle.config | 11 + feeds/bluetooth/ubtled/files/ubtled.init | 24 + feeds/ipq807x/aq-fw-download/Makefile | 55 + feeds/ipq807x/aq-fw-download/src/Makefile | 14 + .../aq-fw-download/src/include/AQ_API.h | 246 + .../src/include/AQ_PhyInterface.h | 171 + .../src/include/AQ_PlatformRoutines.h | 71 + .../aq-fw-download/src/include/AQ_RegMacro.h | 323 + .../src/include/AQ_ReturnCodes.h | 113 + .../aq-fw-download/src/include/AQ_User.h | 97 + .../APPIA/AQ_APPIA_Global_registers.h | 5581 + .../APPIA/AQ_APPIA_Global_registers_Defines.h | 2134 + .../AQ_APPIA_Global_registers_reversed.h | 5581 + .../include/registerMap/AQ_RegGroupMaxSizes.h | 387 + .../src/include/registerMap/AQ_RegMaps.h | 69 + .../registerMap/HHD/AQ_HHD_Global_registers.h | 12123 ++ .../HHD/AQ_HHD_Global_registers_Defines.h | 4413 + .../HHD/AQ_HHD_Global_registers_reversed.h | 12123 ++ .../aq-fw-download/src/mdioBootLoadCLD.c | 193 + feeds/ipq807x/aq-fw-download/src/src/AQ_API.c | 1021 + .../aq-fw-download/src/src/AQ_PhyInterface.c | 141 + feeds/ipq807x/protobuf-c/Makefile | 67 + ...d-code2-cxx-generate-packed-data-fix.patch | 13 + feeds/ipq807x/protobuf/Makefile | 110 + feeds/ipq807x/qca-nss-dp/Makefile | 52 + feeds/ipq807x/qca-nss-dp/src/Makefile | 56 + .../qca-nss-dp/src/exports/nss_dp_api_if.h | 219 + .../src/hal/arch/ipq50xx/nss_ipq50xx.c | 148 + .../src/hal/arch/ipq50xx/nss_ipq50xx.h | 130 + .../src/hal/arch/ipq60xx/nss_ipq60xx.c | 53 + .../src/hal/arch/ipq60xx/nss_ipq60xx.h | 34 + .../src/hal/arch/ipq807x/nss_ipq807x.c | 53 + .../src/hal/arch/ipq807x/nss_ipq807x.h | 34 + .../qca-nss-dp/src/hal/edma/edma_cfg.c | 967 + .../qca-nss-dp/src/hal/edma/edma_data_plane.c | 906 + .../qca-nss-dp/src/hal/edma/edma_data_plane.h | 287 + .../qca-nss-dp/src/hal/edma/edma_regs.h | 454 + .../qca-nss-dp/src/hal/edma/edma_tx_rx.c | 773 + .../src/hal/gmac_hal_ops/qcom/qcom_dev.h | 697 + .../src/hal/gmac_hal_ops/qcom/qcom_if.c | 479 + .../src/hal/gmac_hal_ops/qcom/qcom_reg.h | 156 + .../src/hal/gmac_hal_ops/syn/gmac/syn_dev.h | 30 + .../src/hal/gmac_hal_ops/syn/gmac/syn_if.c | 959 + .../src/hal/gmac_hal_ops/syn/gmac/syn_reg.h | 531 + .../src/hal/gmac_hal_ops/syn/xgmac/syn_dev.h | 189 + .../src/hal/gmac_hal_ops/syn/xgmac/syn_if.c | 505 + .../src/hal/gmac_hal_ops/syn/xgmac/syn_reg.h | 255 + .../ipq807x/qca-nss-dp/src/hal/include/edma.h | 31 + .../qca-nss-dp/src/hal/include/nss_dp_hal.h | 48 + .../src/hal/include/nss_dp_hal_if.h | 162 + .../src/hal/syn_gmac_dp/syn_data_plane.c | 336 + .../src/hal/syn_gmac_dp/syn_data_plane.h | 109 + .../src/hal/syn_gmac_dp/syn_dma_desc.h | 342 + .../src/hal/syn_gmac_dp/syn_dp_cfg.c | 195 + .../src/hal/syn_gmac_dp/syn_dp_tx_rx.c | 425 + .../qca-nss-dp/src/include/nss_dp_dev.h | 132 + feeds/ipq807x/qca-nss-dp/src/nss_dp_attach.c | 192 + .../ipq807x/qca-nss-dp/src/nss_dp_ethtools.c | 378 + feeds/ipq807x/qca-nss-dp/src/nss_dp_main.c | 830 + .../ipq807x/qca-nss-dp/src/nss_dp_switchdev.c | 337 + feeds/ipq807x/qca-nss-drv/Makefile | 111 + .../qca-nss-drv/files/qca-nss-drv.conf | 6 + .../qca-nss-drv/files/qca-nss-drv.debug | 26 + .../qca-nss-drv/files/qca-nss-drv.hotplug | 70 + .../qca-nss-drv/files/qca-nss-drv.init | 50 + .../qca-nss-drv/files/qca-nss-drv.sysctl | 4 + .../qca-nss-drv/patches/100-compile.patch | 15 + feeds/ipq807x/qca-nss-drv/src/Makefile | 472 + feeds/ipq807x/qca-nss-drv/src/Makefile.fsm | 123 + .../src/exports/arch/nss_fsm9010.h | 43 + .../src/exports/arch/nss_ipq40xx.h | 43 + .../src/exports/arch/nss_ipq50xx.h | 40 + .../src/exports/arch/nss_ipq50xx_64.h | 40 + .../src/exports/arch/nss_ipq60xx.h | 41 + .../src/exports/arch/nss_ipq60xx_64.h | 41 + .../src/exports/arch/nss_ipq806x.h | 43 + .../src/exports/arch/nss_ipq807x.h | 44 + .../src/exports/arch/nss_ipq807x_64.h | 44 + .../qca-nss-drv/src/exports/nss_api_if.h | 825 + .../qca-nss-drv/src/exports/nss_bridge.h | 362 + .../qca-nss-drv/src/exports/nss_c2c_rx.h | 86 + .../qca-nss-drv/src/exports/nss_c2c_tx.h | 308 + .../qca-nss-drv/src/exports/nss_capwap.h | 648 + .../qca-nss-drv/src/exports/nss_clmap.h | 308 + .../ipq807x/qca-nss-drv/src/exports/nss_cmn.h | 471 + .../qca-nss-drv/src/exports/nss_crypto.h | 392 + .../qca-nss-drv/src/exports/nss_crypto_cmn.h | 460 + .../ipq807x/qca-nss-drv/src/exports/nss_def.h | 57 + .../ipq807x/qca-nss-drv/src/exports/nss_dma.h | 264 + .../qca-nss-drv/src/exports/nss_dtls.h | 335 + .../qca-nss-drv/src/exports/nss_dtls_cmn.h | 395 + .../src/exports/nss_dynamic_interface.h | 338 + .../qca-nss-drv/src/exports/nss_edma.h | 373 + .../qca-nss-drv/src/exports/nss_eth_rx.h | 100 + .../qca-nss-drv/src/exports/nss_freq.h | 64 + .../ipq807x/qca-nss-drv/src/exports/nss_gre.h | 445 + .../qca-nss-drv/src/exports/nss_gre_redir.h | 601 + .../src/exports/nss_gre_redir_lag.h | 622 + .../src/exports/nss_gre_redir_mark.h | 281 + .../qca-nss-drv/src/exports/nss_gre_tunnel.h | 354 + .../ipq807x/qca-nss-drv/src/exports/nss_if.h | 378 + .../ipq807x/qca-nss-drv/src/exports/nss_igs.h | 213 + .../qca-nss-drv/src/exports/nss_ipsec.h | 550 + .../qca-nss-drv/src/exports/nss_ipsec_cmn.h | 622 + .../qca-nss-drv/src/exports/nss_ipsecmgr.h | 443 + .../qca-nss-drv/src/exports/nss_ipv4.h | 1167 + .../qca-nss-drv/src/exports/nss_ipv4_reasm.h | 89 + .../qca-nss-drv/src/exports/nss_ipv6.h | 1146 + .../qca-nss-drv/src/exports/nss_ipv6_reasm.h | 92 + .../qca-nss-drv/src/exports/nss_l2tpv2.h | 327 + .../ipq807x/qca-nss-drv/src/exports/nss_lag.h | 211 + .../qca-nss-drv/src/exports/nss_lso_rx.h | 88 + .../qca-nss-drv/src/exports/nss_map_t.h | 372 + .../qca-nss-drv/src/exports/nss_match.h | 296 + .../qca-nss-drv/src/exports/nss_mirror.h | 265 + .../ipq807x/qca-nss-drv/src/exports/nss_n2h.h | 572 + .../ipq807x/qca-nss-drv/src/exports/nss_oam.h | 145 + .../qca-nss-drv/src/exports/nss_phy_if.h | 67 + .../ipq807x/qca-nss-drv/src/exports/nss_pm.h | 114 + .../qca-nss-drv/src/exports/nss_portid.h | 284 + .../ipq807x/qca-nss-drv/src/exports/nss_ppe.h | 61 + .../qca-nss-drv/src/exports/nss_pppoe.h | 384 + .../qca-nss-drv/src/exports/nss_pptp.h | 345 + .../qca-nss-drv/src/exports/nss_profiler.h | 406 + .../qca-nss-drv/src/exports/nss_project.h | 176 + .../qca-nss-drv/src/exports/nss_pvxlan.h | 371 + .../qca-nss-drv/src/exports/nss_qrfs.h | 193 + .../qca-nss-drv/src/exports/nss_qvpn.h | 488 + .../qca-nss-drv/src/exports/nss_rmnet_rx.h | 378 + .../ipq807x/qca-nss-drv/src/exports/nss_rps.h | 55 + .../qca-nss-drv/src/exports/nss_shaper.h | 901 + .../qca-nss-drv/src/exports/nss_sjack.h | 154 + .../src/exports/nss_stats_public.h | 131 + .../ipq807x/qca-nss-drv/src/exports/nss_tls.h | 384 + .../qca-nss-drv/src/exports/nss_trustsec_tx.h | 234 + .../qca-nss-drv/src/exports/nss_tstamp.h | 125 + .../qca-nss-drv/src/exports/nss_tun6rd.h | 198 + .../qca-nss-drv/src/exports/nss_tunipip6.h | 293 + .../qca-nss-drv/src/exports/nss_unaligned.h | 121 + .../qca-nss-drv/src/exports/nss_virt_if.h | 436 + .../qca-nss-drv/src/exports/nss_vlan.h | 265 + .../qca-nss-drv/src/exports/nss_vxlan.h | 349 + .../qca-nss-drv/src/exports/nss_wifi.h | 1011 + .../src/exports/nss_wifi_ext_vdev_if.h | 283 + .../qca-nss-drv/src/exports/nss_wifi_if.h | 292 + .../src/exports/nss_wifi_mac_db_if.h | 242 + .../qca-nss-drv/src/exports/nss_wifi_vdev.h | 1263 + .../qca-nss-drv/src/exports/nss_wifili_if.h | 1978 + feeds/ipq807x/qca-nss-drv/src/nss_bridge.c | 501 + .../ipq807x/qca-nss-drv/src/nss_bridge_log.c | 135 + .../ipq807x/qca-nss-drv/src/nss_bridge_log.h | 41 + feeds/ipq807x/qca-nss-drv/src/nss_c2c_rx.c | 113 + .../qca-nss-drv/src/nss_c2c_rx_stats.c | 173 + .../qca-nss-drv/src/nss_c2c_rx_stats.h | 63 + .../qca-nss-drv/src/nss_c2c_rx_strings.c | 61 + .../qca-nss-drv/src/nss_c2c_rx_strings.h | 23 + feeds/ipq807x/qca-nss-drv/src/nss_c2c_tx.c | 439 + .../ipq807x/qca-nss-drv/src/nss_c2c_tx_log.c | 121 + .../ipq807x/qca-nss-drv/src/nss_c2c_tx_log.h | 36 + .../qca-nss-drv/src/nss_c2c_tx_stats.c | 168 + .../qca-nss-drv/src/nss_c2c_tx_stats.h | 29 + .../qca-nss-drv/src/nss_c2c_tx_strings.c | 61 + .../qca-nss-drv/src/nss_c2c_tx_strings.h | 23 + feeds/ipq807x/qca-nss-drv/src/nss_capwap.c | 573 + .../ipq807x/qca-nss-drv/src/nss_capwap_log.c | 282 + .../ipq807x/qca-nss-drv/src/nss_capwap_log.h | 37 + .../qca-nss-drv/src/nss_capwap_stats.c | 303 + .../qca-nss-drv/src/nss_capwap_stats.h | 26 + .../qca-nss-drv/src/nss_capwap_strings.c | 102 + .../qca-nss-drv/src/nss_capwap_strings.h | 28 + feeds/ipq807x/qca-nss-drv/src/nss_clmap.c | 342 + feeds/ipq807x/qca-nss-drv/src/nss_clmap_log.c | 207 + feeds/ipq807x/qca-nss-drv/src/nss_clmap_log.h | 37 + .../ipq807x/qca-nss-drv/src/nss_clmap_stats.c | 274 + .../ipq807x/qca-nss-drv/src/nss_clmap_stats.h | 80 + feeds/ipq807x/qca-nss-drv/src/nss_cmn.c | 346 + feeds/ipq807x/qca-nss-drv/src/nss_core.c | 3253 + feeds/ipq807x/qca-nss-drv/src/nss_core.h | 1035 + feeds/ipq807x/qca-nss-drv/src/nss_coredump.c | 257 + feeds/ipq807x/qca-nss-drv/src/nss_crypto.c | 302 + .../ipq807x/qca-nss-drv/src/nss_crypto_cmn.c | 371 + .../qca-nss-drv/src/nss_crypto_cmn_log.c | 210 + .../qca-nss-drv/src/nss_crypto_cmn_log.h | 37 + .../ipq807x/qca-nss-drv/src/nss_crypto_log.c | 151 + .../ipq807x/qca-nss-drv/src/nss_crypto_log.h | 37 + .../hal/include/nss_data_plane_hal.h | 37 + .../src/nss_data_plane/hal/nss_ipq50xx.c | 168 + .../src/nss_data_plane/hal/nss_ipq60xx.c | 106 + .../src/nss_data_plane/hal/nss_ipq807x.c | 106 + .../nss_data_plane/include/nss_data_plane.h | 60 + .../src/nss_data_plane/nss_data_plane.c | 405 + .../nss_data_plane/nss_data_plane_common.c | 84 + .../src/nss_data_plane/nss_data_plane_gmac.c | 396 + feeds/ipq807x/qca-nss-drv/src/nss_dma.c | 501 + feeds/ipq807x/qca-nss-drv/src/nss_dma_log.c | 140 + feeds/ipq807x/qca-nss-drv/src/nss_dma_log.h | 38 + feeds/ipq807x/qca-nss-drv/src/nss_dma_stats.c | 119 + feeds/ipq807x/qca-nss-drv/src/nss_dma_stats.h | 65 + .../ipq807x/qca-nss-drv/src/nss_dma_strings.c | 88 + .../ipq807x/qca-nss-drv/src/nss_dma_strings.h | 25 + feeds/ipq807x/qca-nss-drv/src/nss_drv_stats.c | 166 + feeds/ipq807x/qca-nss-drv/src/nss_drv_stats.h | 80 + .../ipq807x/qca-nss-drv/src/nss_drv_strings.c | 92 + .../ipq807x/qca-nss-drv/src/nss_drv_strings.h | 26 + feeds/ipq807x/qca-nss-drv/src/nss_dscp_map.h | 212 + feeds/ipq807x/qca-nss-drv/src/nss_dtls.c | 468 + feeds/ipq807x/qca-nss-drv/src/nss_dtls_cmn.c | 523 + .../qca-nss-drv/src/nss_dtls_cmn_log.c | 178 + .../qca-nss-drv/src/nss_dtls_cmn_log.h | 37 + feeds/ipq807x/qca-nss-drv/src/nss_dtls_log.c | 185 + feeds/ipq807x/qca-nss-drv/src/nss_dtls_log.h | 37 + .../ipq807x/qca-nss-drv/src/nss_dtls_stats.c | 143 + .../ipq807x/qca-nss-drv/src/nss_dtls_stats.h | 115 + .../qca-nss-drv/src/nss_dynamic_interface.c | 420 + .../src/nss_dynamic_interface_log.c | 145 + .../src/nss_dynamic_interface_log.h | 37 + .../src/nss_dynamic_interface_stats.c | 158 + .../src/nss_dynamic_interface_stats.h | 33 + feeds/ipq807x/qca-nss-drv/src/nss_edma.c | 139 + .../ipq807x/qca-nss-drv/src/nss_edma_stats.c | 821 + .../ipq807x/qca-nss-drv/src/nss_edma_stats.h | 36 + .../qca-nss-drv/src/nss_edma_strings.c | 349 + .../qca-nss-drv/src/nss_edma_strings.h | 30 + feeds/ipq807x/qca-nss-drv/src/nss_eth_rx.c | 77 + .../qca-nss-drv/src/nss_eth_rx_stats.c | 187 + .../qca-nss-drv/src/nss_eth_rx_stats.h | 65 + .../qca-nss-drv/src/nss_eth_rx_strings.c | 106 + .../qca-nss-drv/src/nss_eth_rx_strings.h | 26 + feeds/ipq807x/qca-nss-drv/src/nss_freq.c | 467 + feeds/ipq807x/qca-nss-drv/src/nss_freq_log.c | 100 + feeds/ipq807x/qca-nss-drv/src/nss_freq_log.h | 35 + .../ipq807x/qca-nss-drv/src/nss_freq_stats.c | 86 + .../ipq807x/qca-nss-drv/src/nss_freq_stats.h | 29 + .../ipq807x/qca-nss-drv/src/nss_gmac_stats.c | 83 + .../ipq807x/qca-nss-drv/src/nss_gmac_stats.h | 33 + feeds/ipq807x/qca-nss-drv/src/nss_gre.c | 407 + feeds/ipq807x/qca-nss-drv/src/nss_gre_log.c | 187 + feeds/ipq807x/qca-nss-drv/src/nss_gre_log.h | 41 + feeds/ipq807x/qca-nss-drv/src/nss_gre_redir.c | 778 + .../qca-nss-drv/src/nss_gre_redir_lag_ds.c | 448 + .../src/nss_gre_redir_lag_ds_log.c | 164 + .../src/nss_gre_redir_lag_ds_log.h | 37 + .../src/nss_gre_redir_lag_ds_stats.c | 163 + .../src/nss_gre_redir_lag_ds_stats.h | 30 + .../qca-nss-drv/src/nss_gre_redir_lag_us.c | 746 + .../src/nss_gre_redir_lag_us_log.c | 191 + .../src/nss_gre_redir_lag_us_log.h | 37 + .../src/nss_gre_redir_lag_us_stats.c | 203 + .../src/nss_gre_redir_lag_us_stats.h | 40 + .../qca-nss-drv/src/nss_gre_redir_log.c | 242 + .../qca-nss-drv/src/nss_gre_redir_log.h | 41 + .../qca-nss-drv/src/nss_gre_redir_mark.c | 418 + .../qca-nss-drv/src/nss_gre_redir_mark_log.c | 119 + .../qca-nss-drv/src/nss_gre_redir_mark_log.h | 37 + .../src/nss_gre_redir_mark_stats.c | 163 + .../src/nss_gre_redir_mark_stats.h | 52 + .../qca-nss-drv/src/nss_gre_redir_stats.c | 260 + .../qca-nss-drv/src/nss_gre_redir_stats.h | 58 + feeds/ipq807x/qca-nss-drv/src/nss_gre_stats.c | 311 + feeds/ipq807x/qca-nss-drv/src/nss_gre_stats.h | 95 + .../ipq807x/qca-nss-drv/src/nss_gre_tunnel.c | 392 + .../qca-nss-drv/src/nss_gre_tunnel_log.c | 168 + .../qca-nss-drv/src/nss_gre_tunnel_log.h | 41 + .../qca-nss-drv/src/nss_gre_tunnel_stats.c | 249 + .../qca-nss-drv/src/nss_gre_tunnel_stats.h | 76 + .../src/nss_hal/fsm9010/nss_hal_pvt.c | 341 + .../qca-nss-drv/src/nss_hal/include/nss_hal.h | 129 + .../src/nss_hal/include/nss_hal_ops.h | 49 + .../src/nss_hal/include/nss_regs.h | 108 + .../src/nss_hal/ipq50xx/nss_hal_pvt.c | 667 + .../src/nss_hal/ipq60xx/nss_hal_pvt.c | 739 + .../src/nss_hal/ipq806x/nss_clocks.h | 131 + .../src/nss_hal/ipq806x/nss_hal_pvt.c | 1236 + .../src/nss_hal/ipq807x/nss_hal_pvt.c | 770 + .../ipq807x/qca-nss-drv/src/nss_hal/nss_hal.c | 813 + feeds/ipq807x/qca-nss-drv/src/nss_hlos_if.h | 377 + feeds/ipq807x/qca-nss-drv/src/nss_if.c | 270 + feeds/ipq807x/qca-nss-drv/src/nss_if_log.c | 429 + feeds/ipq807x/qca-nss-drv/src/nss_if_log.h | 40 + feeds/ipq807x/qca-nss-drv/src/nss_igs.c | 207 + feeds/ipq807x/qca-nss-drv/src/nss_igs_stats.c | 307 + feeds/ipq807x/qca-nss-drv/src/nss_igs_stats.h | 45 + feeds/ipq807x/qca-nss-drv/src/nss_init.c | 942 + feeds/ipq807x/qca-nss-drv/src/nss_ipsec.c | 597 + feeds/ipq807x/qca-nss-drv/src/nss_ipsec_cmn.c | 611 + .../qca-nss-drv/src/nss_ipsec_cmn_log.c | 354 + .../qca-nss-drv/src/nss_ipsec_cmn_log.h | 37 + feeds/ipq807x/qca-nss-drv/src/nss_ipsec_log.c | 205 + feeds/ipq807x/qca-nss-drv/src/nss_ipsec_log.h | 37 + feeds/ipq807x/qca-nss-drv/src/nss_ipv4.c | 767 + feeds/ipq807x/qca-nss-drv/src/nss_ipv4_log.c | 351 + .../ipq807x/qca-nss-drv/src/nss_ipv4_reasm.c | 76 + .../qca-nss-drv/src/nss_ipv4_reasm_stats.c | 167 + .../qca-nss-drv/src/nss_ipv4_reasm_stats.h | 27 + .../qca-nss-drv/src/nss_ipv4_reasm_strings.c | 55 + .../qca-nss-drv/src/nss_ipv4_reasm_strings.h | 25 + .../ipq807x/qca-nss-drv/src/nss_ipv4_stats.c | 236 + .../ipq807x/qca-nss-drv/src/nss_ipv4_stats.h | 29 + .../qca-nss-drv/src/nss_ipv4_strings.c | 205 + .../qca-nss-drv/src/nss_ipv4_strings.h | 26 + feeds/ipq807x/qca-nss-drv/src/nss_ipv6.c | 776 + feeds/ipq807x/qca-nss-drv/src/nss_ipv6_log.c | 383 + .../ipq807x/qca-nss-drv/src/nss_ipv6_reasm.c | 72 + .../qca-nss-drv/src/nss_ipv6_reasm_stats.c | 167 + .../qca-nss-drv/src/nss_ipv6_reasm_stats.h | 27 + .../qca-nss-drv/src/nss_ipv6_reasm_strings.c | 55 + .../qca-nss-drv/src/nss_ipv6_reasm_strings.h | 25 + .../ipq807x/qca-nss-drv/src/nss_ipv6_stats.c | 240 + .../ipq807x/qca-nss-drv/src/nss_ipv6_stats.h | 29 + .../qca-nss-drv/src/nss_ipv6_strings.c | 182 + .../qca-nss-drv/src/nss_ipv6_strings.h | 26 + feeds/ipq807x/qca-nss-drv/src/nss_l2tpv2.c | 284 + .../ipq807x/qca-nss-drv/src/nss_l2tpv2_log.c | 143 + .../ipq807x/qca-nss-drv/src/nss_l2tpv2_log.h | 41 + .../qca-nss-drv/src/nss_l2tpv2_stats.c | 156 + .../qca-nss-drv/src/nss_l2tpv2_stats.h | 33 + .../qca-nss-drv/src/nss_l2tpv2_strings.c | 57 + .../qca-nss-drv/src/nss_l2tpv2_strings.h | 25 + feeds/ipq807x/qca-nss-drv/src/nss_lag.c | 273 + feeds/ipq807x/qca-nss-drv/src/nss_lag_log.c | 103 + feeds/ipq807x/qca-nss-drv/src/nss_lag_log.h | 41 + feeds/ipq807x/qca-nss-drv/src/nss_log.c | 602 + feeds/ipq807x/qca-nss-drv/src/nss_log.h | 115 + feeds/ipq807x/qca-nss-drv/src/nss_lso_rx.c | 62 + .../qca-nss-drv/src/nss_lso_rx_stats.c | 172 + .../qca-nss-drv/src/nss_lso_rx_stats.h | 67 + .../qca-nss-drv/src/nss_lso_rx_strings.c | 57 + .../qca-nss-drv/src/nss_lso_rx_strings.h | 25 + feeds/ipq807x/qca-nss-drv/src/nss_map_t.c | 412 + feeds/ipq807x/qca-nss-drv/src/nss_map_t_log.c | 151 + feeds/ipq807x/qca-nss-drv/src/nss_map_t_log.h | 41 + .../ipq807x/qca-nss-drv/src/nss_map_t_stats.c | 154 + .../ipq807x/qca-nss-drv/src/nss_map_t_stats.h | 36 + .../qca-nss-drv/src/nss_map_t_strings.c | 65 + .../qca-nss-drv/src/nss_map_t_strings.h | 25 + feeds/ipq807x/qca-nss-drv/src/nss_match.c | 296 + feeds/ipq807x/qca-nss-drv/src/nss_match_log.c | 225 + feeds/ipq807x/qca-nss-drv/src/nss_match_log.h | 39 + .../ipq807x/qca-nss-drv/src/nss_match_stats.c | 166 + .../ipq807x/qca-nss-drv/src/nss_match_stats.h | 27 + feeds/ipq807x/qca-nss-drv/src/nss_meminfo.c | 781 + feeds/ipq807x/qca-nss-drv/src/nss_meminfo.h | 135 + feeds/ipq807x/qca-nss-drv/src/nss_mirror.c | 293 + .../ipq807x/qca-nss-drv/src/nss_mirror_log.c | 198 + .../ipq807x/qca-nss-drv/src/nss_mirror_log.h | 39 + .../qca-nss-drv/src/nss_mirror_stats.c | 287 + .../qca-nss-drv/src/nss_mirror_stats.h | 76 + feeds/ipq807x/qca-nss-drv/src/nss_n2h.c | 2250 + feeds/ipq807x/qca-nss-drv/src/nss_n2h_stats.c | 214 + feeds/ipq807x/qca-nss-drv/src/nss_n2h_stats.h | 27 + .../ipq807x/qca-nss-drv/src/nss_n2h_strings.c | 85 + .../ipq807x/qca-nss-drv/src/nss_n2h_strings.h | 25 + feeds/ipq807x/qca-nss-drv/src/nss_oam.c | 141 + feeds/ipq807x/qca-nss-drv/src/nss_oam_log.c | 101 + feeds/ipq807x/qca-nss-drv/src/nss_oam_log.h | 41 + feeds/ipq807x/qca-nss-drv/src/nss_phys_if.c | 629 + feeds/ipq807x/qca-nss-drv/src/nss_phys_if.h | 326 + feeds/ipq807x/qca-nss-drv/src/nss_pm.c | 447 + feeds/ipq807x/qca-nss-drv/src/nss_pm.h | 164 + feeds/ipq807x/qca-nss-drv/src/nss_portid.c | 423 + .../ipq807x/qca-nss-drv/src/nss_portid_log.c | 129 + .../ipq807x/qca-nss-drv/src/nss_portid_log.h | 41 + .../qca-nss-drv/src/nss_portid_stats.c | 153 + .../qca-nss-drv/src/nss_portid_stats.h | 39 + feeds/ipq807x/qca-nss-drv/src/nss_ppe.c | 371 + feeds/ipq807x/qca-nss-drv/src/nss_ppe.h | 423 + feeds/ipq807x/qca-nss-drv/src/nss_ppe_log.c | 189 + feeds/ipq807x/qca-nss-drv/src/nss_ppe_stats.c | 1238 + feeds/ipq807x/qca-nss-drv/src/nss_ppe_stats.h | 423 + feeds/ipq807x/qca-nss-drv/src/nss_ppe_vp.c | 414 + feeds/ipq807x/qca-nss-drv/src/nss_ppe_vp.h | 117 + .../ipq807x/qca-nss-drv/src/nss_ppe_vp_log.c | 128 + .../qca-nss-drv/src/nss_ppe_vp_stats.c | 236 + .../qca-nss-drv/src/nss_ppe_vp_stats.h | 63 + feeds/ipq807x/qca-nss-drv/src/nss_pppoe.c | 435 + feeds/ipq807x/qca-nss-drv/src/nss_pppoe_log.c | 133 + feeds/ipq807x/qca-nss-drv/src/nss_pppoe_log.h | 41 + .../ipq807x/qca-nss-drv/src/nss_pppoe_stats.c | 265 + .../ipq807x/qca-nss-drv/src/nss_pppoe_stats.h | 28 + .../qca-nss-drv/src/nss_pppoe_strings.c | 121 + .../qca-nss-drv/src/nss_pppoe_strings.h | 26 + feeds/ipq807x/qca-nss-drv/src/nss_pptp.c | 472 + feeds/ipq807x/qca-nss-drv/src/nss_pptp_log.c | 129 + feeds/ipq807x/qca-nss-drv/src/nss_pptp_log.h | 41 + .../ipq807x/qca-nss-drv/src/nss_pptp_stats.c | 154 + .../ipq807x/qca-nss-drv/src/nss_pptp_stats.h | 36 + .../qca-nss-drv/src/nss_pptp_strings.c | 79 + .../qca-nss-drv/src/nss_pptp_strings.h | 25 + feeds/ipq807x/qca-nss-drv/src/nss_profiler.c | 254 + feeds/ipq807x/qca-nss-drv/src/nss_project.c | 338 + feeds/ipq807x/qca-nss-drv/src/nss_pvxlan.c | 446 + .../ipq807x/qca-nss-drv/src/nss_pvxlan_log.c | 244 + .../ipq807x/qca-nss-drv/src/nss_pvxlan_log.h | 37 + .../qca-nss-drv/src/nss_pvxlan_stats.c | 213 + .../qca-nss-drv/src/nss_pvxlan_stats.h | 66 + feeds/ipq807x/qca-nss-drv/src/nss_qrfs.c | 472 + feeds/ipq807x/qca-nss-drv/src/nss_qrfs_log.c | 174 + feeds/ipq807x/qca-nss-drv/src/nss_qrfs_log.h | 37 + .../ipq807x/qca-nss-drv/src/nss_qrfs_stats.c | 148 + .../ipq807x/qca-nss-drv/src/nss_qrfs_stats.h | 38 + feeds/ipq807x/qca-nss-drv/src/nss_qvpn.c | 370 + feeds/ipq807x/qca-nss-drv/src/nss_qvpn_log.c | 262 + feeds/ipq807x/qca-nss-drv/src/nss_qvpn_log.h | 37 + .../ipq807x/qca-nss-drv/src/nss_qvpn_stats.c | 86 + .../ipq807x/qca-nss-drv/src/nss_qvpn_stats.h | 26 + feeds/ipq807x/qca-nss-drv/src/nss_rmnet_rx.c | 760 + .../qca-nss-drv/src/nss_rmnet_rx_stats.c | 209 + .../qca-nss-drv/src/nss_rmnet_rx_stats.h | 61 + feeds/ipq807x/qca-nss-drv/src/nss_rps.c | 638 + feeds/ipq807x/qca-nss-drv/src/nss_shaper.c | 367 + feeds/ipq807x/qca-nss-drv/src/nss_sjack.c | 189 + feeds/ipq807x/qca-nss-drv/src/nss_sjack_log.c | 133 + feeds/ipq807x/qca-nss-drv/src/nss_sjack_log.h | 41 + .../ipq807x/qca-nss-drv/src/nss_sjack_stats.c | 94 + .../ipq807x/qca-nss-drv/src/nss_sjack_stats.h | 45 + feeds/ipq807x/qca-nss-drv/src/nss_stats.c | 481 + feeds/ipq807x/qca-nss-drv/src/nss_stats.h | 76 + feeds/ipq807x/qca-nss-drv/src/nss_strings.c | 148 + feeds/ipq807x/qca-nss-drv/src/nss_strings.h | 52 + feeds/ipq807x/qca-nss-drv/src/nss_tls.c | 550 + feeds/ipq807x/qca-nss-drv/src/nss_tls_log.c | 167 + feeds/ipq807x/qca-nss-drv/src/nss_tls_log.h | 39 + .../ipq807x/qca-nss-drv/src/nss_trustsec_tx.c | 299 + .../qca-nss-drv/src/nss_trustsec_tx_log.c | 170 + .../qca-nss-drv/src/nss_trustsec_tx_log.h | 37 + .../qca-nss-drv/src/nss_trustsec_tx_stats.c | 145 + .../qca-nss-drv/src/nss_trustsec_tx_stats.h | 44 + feeds/ipq807x/qca-nss-drv/src/nss_tstamp.c | 423 + .../qca-nss-drv/src/nss_tstamp_stats.c | 165 + .../qca-nss-drv/src/nss_tstamp_stats.h | 48 + feeds/ipq807x/qca-nss-drv/src/nss_tun6rd.c | 183 + .../ipq807x/qca-nss-drv/src/nss_tun6rd_log.c | 132 + .../ipq807x/qca-nss-drv/src/nss_tun6rd_log.h | 41 + feeds/ipq807x/qca-nss-drv/src/nss_tunipip6.c | 291 + .../qca-nss-drv/src/nss_tunipip6_log.c | 189 + .../qca-nss-drv/src/nss_tunipip6_log.h | 41 + .../qca-nss-drv/src/nss_tunipip6_stats.c | 124 + .../qca-nss-drv/src/nss_tunipip6_stats.h | 34 + .../ipq807x/qca-nss-drv/src/nss_tx_msg_sync.c | 197 + .../ipq807x/qca-nss-drv/src/nss_tx_msg_sync.h | 82 + .../qca-nss-drv/src/nss_tx_rx_common.h | 113 + feeds/ipq807x/qca-nss-drv/src/nss_unaligned.c | 91 + .../qca-nss-drv/src/nss_unaligned_log.c | 75 + .../qca-nss-drv/src/nss_unaligned_log.h | 31 + .../qca-nss-drv/src/nss_unaligned_stats.c | 88 + .../qca-nss-drv/src/nss_unaligned_stats.h | 22 + feeds/ipq807x/qca-nss-drv/src/nss_virt_if.c | 736 + .../qca-nss-drv/src/nss_virt_if_stats.c | 339 + .../qca-nss-drv/src/nss_virt_if_stats.h | 51 + feeds/ipq807x/qca-nss-drv/src/nss_vlan.c | 411 + feeds/ipq807x/qca-nss-drv/src/nss_vlan_log.c | 120 + feeds/ipq807x/qca-nss-drv/src/nss_vlan_log.h | 37 + feeds/ipq807x/qca-nss-drv/src/nss_vxlan.c | 326 + feeds/ipq807x/qca-nss-drv/src/nss_vxlan_log.c | 257 + feeds/ipq807x/qca-nss-drv/src/nss_vxlan_log.h | 37 + .../ipq807x/qca-nss-drv/src/nss_vxlan_stats.c | 122 + .../ipq807x/qca-nss-drv/src/nss_vxlan_stats.h | 32 + feeds/ipq807x/qca-nss-drv/src/nss_wifi.c | 198 + .../qca-nss-drv/src/nss_wifi_ext_vdev.c | 337 + .../qca-nss-drv/src/nss_wifi_ext_vdev_log.c | 146 + .../qca-nss-drv/src/nss_wifi_ext_vdev_log.h | 34 + .../qca-nss-drv/src/nss_wifi_ext_vdev_stats.c | 234 + .../qca-nss-drv/src/nss_wifi_ext_vdev_stats.h | 60 + feeds/ipq807x/qca-nss-drv/src/nss_wifi_if.c | 516 + .../qca-nss-drv/src/nss_wifi_if_stats.c | 210 + .../qca-nss-drv/src/nss_wifi_if_stats.h | 26 + feeds/ipq807x/qca-nss-drv/src/nss_wifi_log.c | 806 + feeds/ipq807x/qca-nss-drv/src/nss_wifi_log.h | 37 + .../ipq807x/qca-nss-drv/src/nss_wifi_mac_db.c | 215 + .../ipq807x/qca-nss-drv/src/nss_wifi_stats.c | 213 + .../ipq807x/qca-nss-drv/src/nss_wifi_stats.h | 62 + feeds/ipq807x/qca-nss-drv/src/nss_wifi_vdev.c | 379 + feeds/ipq807x/qca-nss-drv/src/nss_wifili.c | 597 + .../ipq807x/qca-nss-drv/src/nss_wifili_log.c | 553 + .../ipq807x/qca-nss-drv/src/nss_wifili_log.h | 37 + .../qca-nss-drv/src/nss_wifili_stats.c | 512 + .../qca-nss-drv/src/nss_wifili_stats.h | 35 + .../qca-nss-drv/src/nss_wifili_strings.c | 366 + .../qca-nss-drv/src/nss_wifili_strings.h | 44 + feeds/ipq807x/qca-nss-fw/Makefile | 54 + .../qca-nss-fw/files/IPQ6018/Notice.txt | 236 + .../qca-nss-fw/files/IPQ6018/ReadMe.txt | 10 + .../qca-nss-fw/files/IPQ6018/qca-nss0.bin | Bin 0 -> 796196 bytes .../qca-nss-fw/files/IPQ8074/Notice.txt | 236 + .../qca-nss-fw/files/IPQ8074/ReadMe.txt | 10 + .../qca-nss-fw/files/IPQ8074/qca-nss0.bin | Bin 0 -> 757908 bytes .../qca-nss-fw/files/IPQ8074/qca-nss1.bin | Bin 0 -> 289536 bytes feeds/ipq807x/qca-ssdk-shell/Makefile | 43 + feeds/ipq807x/qca-ssdk-shell/src/Makefile | 47 + feeds/ipq807x/qca-ssdk-shell/src/config | 153 + .../src/include/api/api_access.h | 39 + .../qca-ssdk-shell/src/include/api/api_desc.h | 4240 + .../qca-ssdk-shell/src/include/api/sw_api.h | 282 + .../qca-ssdk-shell/src/include/api/sw_ioctl.h | 981 + .../src/include/common/aos_head.h | 21 + .../src/include/common/shared_func.h | 110 + .../qca-ssdk-shell/src/include/common/sw.h | 33 + .../src/include/common/sw_config.h | 37 + .../src/include/common/sw_error.h | 62 + .../qca-ssdk-shell/src/include/common/util.h | 92 + .../qca-ssdk-shell/src/include/fal/fal.h | 67 + .../qca-ssdk-shell/src/include/fal/fal_acl.h | 619 + .../qca-ssdk-shell/src/include/fal/fal_api.h | 2115 + .../qca-ssdk-shell/src/include/fal/fal_bm.h | 130 + .../src/include/fal/fal_cosmap.h | 138 + .../src/include/fal/fal_ctrlpkt.h | 90 + .../qca-ssdk-shell/src/include/fal/fal_fdb.h | 364 + .../qca-ssdk-shell/src/include/fal/fal_flow.h | 236 + .../qca-ssdk-shell/src/include/fal/fal_igmp.h | 161 + .../qca-ssdk-shell/src/include/fal/fal_init.h | 80 + .../src/include/fal/fal_interface_ctrl.h | 183 + .../qca-ssdk-shell/src/include/fal/fal_ip.h | 633 + .../src/include/fal/fal_leaky.h | 107 + .../qca-ssdk-shell/src/include/fal/fal_led.h | 123 + .../qca-ssdk-shell/src/include/fal/fal_mib.h | 245 + .../src/include/fal/fal_mirror.h | 87 + .../qca-ssdk-shell/src/include/fal/fal_misc.h | 263 + .../src/include/fal/fal_multi.h | 73 + .../qca-ssdk-shell/src/include/fal/fal_nat.h | 293 + .../src/include/fal/fal_policer.h | 149 + .../src/include/fal/fal_port_ctrl.h | 777 + .../src/include/fal/fal_portvlan.h | 725 + .../src/include/fal/fal_pppoe.h | 110 + .../qca-ssdk-shell/src/include/fal/fal_ptp.h | 471 + .../qca-ssdk-shell/src/include/fal/fal_qm.h | 325 + .../qca-ssdk-shell/src/include/fal/fal_qos.h | 456 + .../qca-ssdk-shell/src/include/fal/fal_rate.h | 234 + .../src/include/fal/fal_reg_access.h | 95 + .../src/include/fal/fal_rss_hash.h | 69 + .../qca-ssdk-shell/src/include/fal/fal_sec.h | 250 + .../src/include/fal/fal_servcode.h | 125 + .../qca-ssdk-shell/src/include/fal/fal_sfp.h | 578 + .../src/include/fal/fal_shaper.h | 162 + .../qca-ssdk-shell/src/include/fal/fal_stp.h | 76 + .../src/include/fal/fal_trunk.h | 86 + .../qca-ssdk-shell/src/include/fal/fal_type.h | 135 + .../src/include/fal/fal_uk_if.h | 42 + .../qca-ssdk-shell/src/include/fal/fal_vlan.h | 129 + .../qca-ssdk-shell/src/include/fal/fal_vsi.h | 131 + .../src/include/init/ssdk_init.h | 280 + .../src/include/init/ssdk_plat.h | 178 + .../qca-ssdk-shell/src/include/ref/ref_api.h | 47 + .../qca-ssdk-shell/src/include/ref/ref_vlan.h | 58 + .../src/include/sal/os/aos_lock.h | 47 + .../src/include/sal/os/aos_mem.h | 116 + .../src/include/sal/os/aos_timer.h | 50 + .../src/include/sal/os/aos_types.h | 184 + .../include/sal/os/linux_user/aos_lock_pvt.h | 46 + .../include/sal/os/linux_user/aos_mem_pvt.h | 61 + .../include/sal/os/linux_user/aos_timer_pvt.h | 36 + .../include/sal/os/linux_user/aos_types_pvt.h | 41 + .../sal/sd/linux/uk_interface/sw_api_us.h | 36 + .../qca-ssdk-shell/src/include/sal/sd/sd.h | 58 + .../qca-ssdk-shell/src/include/shell/shell.h | 43 + .../src/include/shell/shell_config.h | 91 + .../src/include/shell/shell_io.h | 1039 + .../src/include/shell/shell_lib.h | 31 + .../src/include/shell/shell_sw.h | 53 + .../qca-ssdk-shell/src/make/components.mk | 36 + .../ipq807x/qca-ssdk-shell/src/make/config.mk | 91 + feeds/ipq807x/qca-ssdk-shell/src/make/defs.mk | 28 + .../qca-ssdk-shell/src/make/linux_opt.mk | 328 + .../ipq807x/qca-ssdk-shell/src/make/target.mk | 49 + .../ipq807x/qca-ssdk-shell/src/make/tools.mk | 12 + .../qca-ssdk-shell/src/src/api/Makefile | 12 + .../qca-ssdk-shell/src/src/api/api_access.c | 293 + .../qca-ssdk-shell/src/src/fal_uk/Makefile | 141 + .../qca-ssdk-shell/src/src/fal_uk/fal_acl.c | 207 + .../qca-ssdk-shell/src/src/fal_uk/fal_bm.c | 160 + .../src/src/fal_uk/fal_cosmap.c | 225 + .../src/src/fal_uk/fal_ctrlpkt.c | 96 + .../qca-ssdk-shell/src/src/fal_uk/fal_fdb.c | 459 + .../qca-ssdk-shell/src/src/fal_uk/fal_flow.c | 190 + .../qca-ssdk-shell/src/src/fal_uk/fal_igmp.c | 277 + .../qca-ssdk-shell/src/src/fal_uk/fal_init.c | 60 + .../src/src/fal_uk/fal_interface_ctrl.c | 119 + .../qca-ssdk-shell/src/src/fal_uk/fal_ip.c | 728 + .../qca-ssdk-shell/src/src/fal_uk/fal_leaky.c | 110 + .../qca-ssdk-shell/src/src/fal_uk/fal_led.c | 43 + .../qca-ssdk-shell/src/src/fal_uk/fal_mib.c | 93 + .../src/src/fal_uk/fal_mirror.c | 98 + .../qca-ssdk-shell/src/src/fal_uk/fal_misc.c | 500 + .../qca-ssdk-shell/src/src/fal_uk/fal_nat.c | 360 + .../src/src/fal_uk/fal_policer.c | 138 + .../src/src/fal_uk/fal_port_ctrl.c | 956 + .../src/src/fal_uk/fal_portvlan.c | 754 + .../qca-ssdk-shell/src/src/fal_uk/fal_pppoe.c | 167 + .../qca-ssdk-shell/src/src/fal_uk/fal_ptp.c | 497 + .../qca-ssdk-shell/src/src/fal_uk/fal_qm.c | 404 + .../qca-ssdk-shell/src/src/fal_uk/fal_qos.c | 612 + .../qca-ssdk-shell/src/src/fal_uk/fal_rate.c | 263 + .../src/src/fal_uk/fal_reg_access.c | 159 + .../src/src/fal_uk/fal_rss_hash.c | 41 + .../qca-ssdk-shell/src/src/fal_uk/fal_sec.c | 94 + .../src/src/fal_uk/fal_servcode.c | 57 + .../qca-ssdk-shell/src/src/fal_uk/fal_sfp.c | 202 + .../src/src/fal_uk/fal_shaper.c | 221 + .../qca-ssdk-shell/src/src/fal_uk/fal_stp.c | 42 + .../qca-ssdk-shell/src/src/fal_uk/fal_trunk.c | 101 + .../qca-ssdk-shell/src/src/fal_uk/fal_uk_if.c | 67 + .../qca-ssdk-shell/src/src/fal_uk/fal_vlan.c | 145 + .../qca-ssdk-shell/src/src/fal_uk/fal_vsi.c | 148 + .../qca-ssdk-shell/src/src/ref/Makefile | 16 + .../qca-ssdk-shell/src/src/ref/ref_vlan.c | 38 + .../qca-ssdk-shell/src/src/sal/Makefile | 12 + .../qca-ssdk-shell/src/src/sal/sd/Makefile | 12 + .../src/src/sal/sd/linux/Makefile | 12 + .../src/sal/sd/linux/uk_interface/Makefile | 34 + .../sd/linux/uk_interface/sw_api_us_ioctl.c | 127 + .../sd/linux/uk_interface/sw_api_us_netlink.c | 228 + .../qca-ssdk-shell/src/src/sal/sd/sd.c | 204 + .../qca-ssdk-shell/src/src/shell/Makefile | 24 + .../qca-ssdk-shell/src/src/shell/shell.c | 858 + .../src/src/shell/shell_config.c | 1451 + .../qca-ssdk-shell/src/src/shell/shell_io.c | 30033 ++++ .../qca-ssdk-shell/src/src/shell/shell_lib.c | 917 + .../src/src/shell/shell_module_ctrl.c | 1069 + .../qca-ssdk-shell/src/src/shell/shell_sw.c | 739 + feeds/ipq807x/qca-ssdk/Makefile | 85 + feeds/ipq807x/qca-ssdk/files/qca-ssdk | 206 + feeds/ipq807x/qca-ssdk/patches/100-aq.patch | 47 + feeds/ipq807x/qca-ssdk/src/ChangeLog | 129 + feeds/ipq807x/qca-ssdk/src/Makefile | 52 + .../src/app/nathelper/linux/host_helper.c | 2253 + .../app/nathelper/linux/lib/nat_helper_dt.c | 1352 + .../app/nathelper/linux/lib/nat_helper_dt.h | 22 + .../app/nathelper/linux/lib/nat_helper_hsl.c | 879 + .../app/nathelper/linux/lib/nat_helper_hsl.h | 257 + .../src/app/nathelper/linux/napt_acl.c | 1622 + .../src/app/nathelper/linux/napt_acl.h | 94 + .../src/app/nathelper/linux/napt_helper.c | 406 + .../src/app/nathelper/linux/napt_helper.h | 91 + .../src/app/nathelper/linux/napt_procfs.c | 1316 + .../src/app/nathelper/linux/nat_helper.c | 69 + .../src/app/nathelper/linux/nat_helper.h | 54 + .../src/app/nathelper/linux/nat_ipt_helper.c | 761 + feeds/ipq807x/qca-ssdk/src/config | 345 + .../ipq807x/qca-ssdk/src/include/adpt/adpt.h | 1598 + .../src/include/adpt/cppe/adpt_cppe_flow.h | 38 + .../src/include/adpt/cppe/adpt_cppe_mib.h | 52 + .../src/include/adpt/cppe/adpt_cppe_misc.h | 37 + .../include/adpt/cppe/adpt_cppe_portctrl.h | 103 + .../src/include/adpt/cppe/adpt_cppe_qm.h | 41 + .../src/include/adpt/cppe/adpt_cppe_qos.h | 68 + .../src/include/adpt/cppe/adpt_cppe_uniphy.h | 47 + .../src/include/adpt/hppe/adpt_hppe.h | 112 + .../qca-ssdk/src/include/adpt/mp/adpt_mp.h | 43 + .../src/include/adpt/mp/adpt_mp_portctrl.h | 45 + .../src/include/adpt/mp/adpt_mp_uniphy.h | 45 + .../qca-ssdk/src/include/adpt/sfp/adpt_sfp.h | 32 + .../qca-ssdk/src/include/api/api_access.h | 39 + .../qca-ssdk/src/include/api/api_desc.h | 4762 + .../ipq807x/qca-ssdk/src/include/api/sw_api.h | 276 + .../qca-ssdk/src/include/api/sw_ioctl.h | 987 + .../qca-ssdk/src/include/common/aos_head.h | 19 + .../qca-ssdk/src/include/common/shared_func.h | 120 + .../ipq807x/qca-ssdk/src/include/common/sw.h | 33 + .../qca-ssdk/src/include/common/sw_config.h | 37 + .../qca-ssdk/src/include/common/sw_error.h | 62 + .../qca-ssdk/src/include/common/util.h | 92 + feeds/ipq807x/qca-ssdk/src/include/fal/fal.h | 68 + .../qca-ssdk/src/include/fal/fal_acl.h | 616 + .../qca-ssdk/src/include/fal/fal_api.h | 2419 + .../ipq807x/qca-ssdk/src/include/fal/fal_bm.h | 144 + .../qca-ssdk/src/include/fal/fal_cosmap.h | 140 + .../qca-ssdk/src/include/fal/fal_ctrlpkt.h | 100 + .../qca-ssdk/src/include/fal/fal_fdb.h | 338 + .../qca-ssdk/src/include/fal/fal_flow.h | 244 + .../qca-ssdk/src/include/fal/fal_flowcookie.h | 43 + .../qca-ssdk/src/include/fal/fal_igmp.h | 161 + .../qca-ssdk/src/include/fal/fal_init.h | 84 + .../src/include/fal/fal_interface_ctrl.h | 181 + .../ipq807x/qca-ssdk/src/include/fal/fal_ip.h | 646 + .../qca-ssdk/src/include/fal/fal_leaky.h | 107 + .../qca-ssdk/src/include/fal/fal_led.h | 142 + .../qca-ssdk/src/include/fal/fal_mib.h | 260 + .../qca-ssdk/src/include/fal/fal_mirror.h | 86 + .../qca-ssdk/src/include/fal/fal_misc.h | 256 + .../qca-ssdk/src/include/fal/fal_multi.h | 73 + .../qca-ssdk/src/include/fal/fal_nat.h | 294 + .../qca-ssdk/src/include/fal/fal_policer.h | 152 + .../qca-ssdk/src/include/fal/fal_port_ctrl.h | 801 + .../qca-ssdk/src/include/fal/fal_portvlan.h | 738 + .../qca-ssdk/src/include/fal/fal_pppoe.h | 109 + .../qca-ssdk/src/include/fal/fal_ptp.h | 496 + .../ipq807x/qca-ssdk/src/include/fal/fal_qm.h | 344 + .../qca-ssdk/src/include/fal/fal_qos.h | 442 + .../qca-ssdk/src/include/fal/fal_rate.h | 234 + .../qca-ssdk/src/include/fal/fal_reg_access.h | 97 + .../qca-ssdk/src/include/fal/fal_rfs.h | 90 + .../qca-ssdk/src/include/fal/fal_rss_hash.h | 77 + .../qca-ssdk/src/include/fal/fal_sec.h | 251 + .../qca-ssdk/src/include/fal/fal_servcode.h | 137 + .../qca-ssdk/src/include/fal/fal_sfp.h | 578 + .../qca-ssdk/src/include/fal/fal_shaper.h | 163 + .../qca-ssdk/src/include/fal/fal_stp.h | 75 + .../qca-ssdk/src/include/fal/fal_trunk.h | 84 + .../qca-ssdk/src/include/fal/fal_type.h | 137 + .../qca-ssdk/src/include/fal/fal_uk_if.h | 42 + .../qca-ssdk/src/include/fal/fal_vlan.h | 129 + .../qca-ssdk/src/include/fal/fal_vsi.h | 137 + .../src/include/hsl/athena/athena_api.h | 198 + .../src/include/hsl/athena/athena_fdb.h | 76 + .../src/include/hsl/athena/athena_init.h | 45 + .../src/include/hsl/athena/athena_mib.h | 51 + .../src/include/hsl/athena/athena_port_ctrl.h | 127 + .../src/include/hsl/athena/athena_portvlan.h | 94 + .../src/include/hsl/athena/athena_reg.h | 2157 + .../include/hsl/athena/athena_reg_access.h | 63 + .../src/include/hsl/athena/athena_vlan.h | 94 + .../src/include/hsl/cppe/cppe_loopback.h | 213 + .../src/include/hsl/cppe/cppe_loopback_reg.h | 578 + .../src/include/hsl/cppe/cppe_portctrl.h | 204 + .../src/include/hsl/cppe/cppe_portctrl_reg.h | 166 + .../qca-ssdk/src/include/hsl/cppe/cppe_qos.h | 186 + .../src/include/hsl/cppe/cppe_qos_reg.h | 113 + .../qca-ssdk/src/include/hsl/dess/dess_acl.h | 144 + .../qca-ssdk/src/include/hsl/dess/dess_api.h | 1174 + .../src/include/hsl/dess/dess_cosmap.h | 141 + .../qca-ssdk/src/include/hsl/dess/dess_fdb.h | 168 + .../src/include/hsl/dess/dess_fdb_prv.h | 49 + .../qca-ssdk/src/include/hsl/dess/dess_igmp.h | 165 + .../qca-ssdk/src/include/hsl/dess/dess_init.h | 44 + .../include/hsl/dess/dess_interface_ctrl.h | 58 + .../qca-ssdk/src/include/hsl/dess/dess_ip.h | 201 + .../src/include/hsl/dess/dess_leaky.h | 94 + .../qca-ssdk/src/include/hsl/dess/dess_led.h | 61 + .../qca-ssdk/src/include/hsl/dess/dess_mib.h | 69 + .../src/include/hsl/dess/dess_mirror.h | 73 + .../qca-ssdk/src/include/hsl/dess/dess_misc.h | 258 + .../qca-ssdk/src/include/hsl/dess/dess_nat.h | 147 + .../src/include/hsl/dess/dess_nat_helper.h | 50 + .../src/include/hsl/dess/dess_port_ctrl.h | 360 + .../src/include/hsl/dess/dess_portvlan.h | 228 + .../src/include/hsl/dess/dess_psgmii.h | 310 + .../qca-ssdk/src/include/hsl/dess/dess_qos.h | 180 + .../qca-ssdk/src/include/hsl/dess/dess_rate.h | 96 + .../qca-ssdk/src/include/hsl/dess/dess_reg.h | 5011 + .../src/include/hsl/dess/dess_reg_access.h | 78 + .../qca-ssdk/src/include/hsl/dess/dess_sec.h | 53 + .../qca-ssdk/src/include/hsl/dess/dess_stp.h | 55 + .../src/include/hsl/dess/dess_trunk.h | 59 + .../qca-ssdk/src/include/hsl/dess/dess_vlan.h | 99 + .../src/include/hsl/garuda/garuda_acl.h | 120 + .../src/include/hsl/garuda/garuda_api.h | 531 + .../src/include/hsl/garuda/garuda_fdb.h | 120 + .../src/include/hsl/garuda/garuda_igmp.h | 111 + .../src/include/hsl/garuda/garuda_init.h | 47 + .../src/include/hsl/garuda/garuda_leaky.h | 107 + .../src/include/hsl/garuda/garuda_led.h | 57 + .../src/include/hsl/garuda/garuda_mib.h | 68 + .../src/include/hsl/garuda/garuda_mirror.h | 84 + .../src/include/hsl/garuda/garuda_misc.h | 147 + .../src/include/hsl/garuda/garuda_port_ctrl.h | 145 + .../src/include/hsl/garuda/garuda_portvlan.h | 151 + .../src/include/hsl/garuda/garuda_qos.h | 169 + .../src/include/hsl/garuda/garuda_rate.h | 111 + .../include/hsl/garuda/garuda_reduced_acl.h | 54 + .../src/include/hsl/garuda/garuda_reg.h | 3614 + .../include/hsl/garuda/garuda_reg_access.h | 63 + .../src/include/hsl/garuda/garuda_stp.h | 62 + .../src/include/hsl/garuda/garuda_vlan.h | 82 + .../src/include/hsl/horus/horus_api.h | 559 + .../src/include/hsl/horus/horus_fdb.h | 108 + .../src/include/hsl/horus/horus_igmp.h | 133 + .../src/include/hsl/horus/horus_init.h | 49 + .../src/include/hsl/horus/horus_leaky.h | 100 + .../src/include/hsl/horus/horus_led.h | 55 + .../src/include/hsl/horus/horus_mib.h | 65 + .../src/include/hsl/horus/horus_mirror.h | 78 + .../src/include/hsl/horus/horus_misc.h | 167 + .../src/include/hsl/horus/horus_port_ctrl.h | 145 + .../src/include/hsl/horus/horus_portvlan.h | 160 + .../src/include/hsl/horus/horus_qos.h | 164 + .../src/include/hsl/horus/horus_rate.h | 89 + .../src/include/hsl/horus/horus_reg.h | 2431 + .../src/include/hsl/horus/horus_reg_access.h | 63 + .../src/include/hsl/horus/horus_stp.h | 61 + .../src/include/hsl/horus/horus_vlan.h | 78 + .../qca-ssdk/src/include/hsl/hppe/hppe_acl.h | 1256 + .../src/include/hsl/hppe/hppe_acl_reg.h | 842 + .../qca-ssdk/src/include/hsl/hppe/hppe_bm.h | 1218 + .../src/include/hsl/hppe/hppe_bm_reg.h | 1036 + .../src/include/hsl/hppe/hppe_ctrlpkt.h | 245 + .../src/include/hsl/hppe/hppe_ctrlpkt_reg.h | 154 + .../qca-ssdk/src/include/hsl/hppe/hppe_fdb.h | 900 + .../src/include/hsl/hppe/hppe_fdb_reg.h | 838 + .../qca-ssdk/src/include/hsl/hppe/hppe_flow.h | 2264 + .../src/include/hsl/hppe/hppe_flow_reg.h | 2856 + .../src/include/hsl/hppe/hppe_global.h | 1204 + .../src/include/hsl/hppe/hppe_global_reg.h | 988 + .../qca-ssdk/src/include/hsl/hppe/hppe_init.h | 117 + .../qca-ssdk/src/include/hsl/hppe/hppe_ip.h | 2696 + .../src/include/hsl/hppe/hppe_ip_reg.h | 2240 + .../qca-ssdk/src/include/hsl/hppe/hppe_mib.h | 1150 + .../src/include/hsl/hppe/hppe_mib_reg.h | 1006 + .../src/include/hsl/hppe/hppe_mirror.h | 92 + .../src/include/hsl/hppe/hppe_mirror_reg.h | 83 + .../src/include/hsl/hppe/hppe_policer.h | 1173 + .../src/include/hsl/hppe/hppe_policer_reg.h | 795 + .../src/include/hsl/hppe/hppe_portctrl.h | 1413 + .../src/include/hsl/hppe/hppe_portctrl_reg.h | 1119 + .../src/include/hsl/hppe/hppe_portvlan.h | 1609 + .../src/include/hsl/hppe/hppe_portvlan_reg.h | 1045 + .../src/include/hsl/hppe/hppe_pppoe.h | 173 + .../src/include/hsl/hppe/hppe_pppoe_reg.h | 127 + .../qca-ssdk/src/include/hsl/hppe/hppe_qm.h | 3811 + .../src/include/hsl/hppe/hppe_qm_reg.h | 2748 + .../qca-ssdk/src/include/hsl/hppe/hppe_qos.h | 2163 + .../src/include/hsl/hppe/hppe_qos_reg.h | 1676 + .../src/include/hsl/hppe/hppe_reg_access.h | 54 + .../qca-ssdk/src/include/hsl/hppe/hppe_rss.h | 249 + .../src/include/hsl/hppe/hppe_rss_reg.h | 231 + .../qca-ssdk/src/include/hsl/hppe/hppe_sec.h | 416 + .../src/include/hsl/hppe/hppe_sec_reg.h | 373 + .../src/include/hsl/hppe/hppe_servcode.h | 220 + .../src/include/hsl/hppe/hppe_servcode_reg.h | 150 + .../src/include/hsl/hppe/hppe_shaper.h | 1055 + .../src/include/hsl/hppe/hppe_shaper_reg.h | 730 + .../qca-ssdk/src/include/hsl/hppe/hppe_stp.h | 51 + .../src/include/hsl/hppe/hppe_stp_reg.h | 46 + .../src/include/hsl/hppe/hppe_trunk.h | 320 + .../src/include/hsl/hppe/hppe_trunk_reg.h | 230 + .../src/include/hsl/hppe/hppe_uniphy.h | 2440 + .../src/include/hsl/hppe/hppe_uniphy_reg.h | 1594 + .../qca-ssdk/src/include/hsl/hppe/hppe_vsi.h | 270 + .../src/include/hsl/hppe/hppe_vsi_reg.h | 192 + .../src/include/hsl/hppe/hppe_xgmacmib.h | 2252 + .../src/include/hsl/hppe/hppe_xgmacmib_reg.h | 1956 + .../src/include/hsl/hppe/hppe_xgportctrl.h | 2758 + .../include/hsl/hppe/hppe_xgportctrl_reg.h | 1627 + feeds/ipq807x/qca-ssdk/src/include/hsl/hsl.h | 244 + .../qca-ssdk/src/include/hsl/hsl_acl.h | 46 + .../qca-ssdk/src/include/hsl/hsl_api.h | 2619 + .../qca-ssdk/src/include/hsl/hsl_dev.h | 78 + .../qca-ssdk/src/include/hsl/hsl_lock.h | 30 + .../qca-ssdk/src/include/hsl/hsl_port_prop.h | 81 + .../qca-ssdk/src/include/hsl/hsl_shared_api.h | 220 + .../qca-ssdk/src/include/hsl/isis/isis_acl.h | 134 + .../qca-ssdk/src/include/hsl/isis/isis_api.h | 992 + .../src/include/hsl/isis/isis_cosmap.h | 109 + .../qca-ssdk/src/include/hsl/isis/isis_fdb.h | 162 + .../qca-ssdk/src/include/hsl/isis/isis_igmp.h | 162 + .../qca-ssdk/src/include/hsl/isis/isis_init.h | 51 + .../include/hsl/isis/isis_interface_ctrl.h | 64 + .../qca-ssdk/src/include/hsl/isis/isis_ip.h | 153 + .../src/include/hsl/isis/isis_leaky.h | 94 + .../qca-ssdk/src/include/hsl/isis/isis_led.h | 57 + .../qca-ssdk/src/include/hsl/isis/isis_mib.h | 59 + .../src/include/hsl/isis/isis_mirror.h | 73 + .../qca-ssdk/src/include/hsl/isis/isis_misc.h | 212 + .../qca-ssdk/src/include/hsl/isis/isis_nat.h | 153 + .../src/include/hsl/isis/isis_nat_helper.h | 50 + .../src/include/hsl/isis/isis_port_ctrl.h | 224 + .../src/include/hsl/isis/isis_portvlan.h | 216 + .../qca-ssdk/src/include/hsl/isis/isis_qos.h | 157 + .../qca-ssdk/src/include/hsl/isis/isis_rate.h | 89 + .../qca-ssdk/src/include/hsl/isis/isis_reg.h | 5229 + .../src/include/hsl/isis/isis_reg_access.h | 124 + .../qca-ssdk/src/include/hsl/isis/isis_sec.h | 53 + .../qca-ssdk/src/include/hsl/isis/isis_stp.h | 55 + .../src/include/hsl/isis/isis_trunk.h | 69 + .../qca-ssdk/src/include/hsl/isis/isis_vlan.h | 99 + .../src/include/hsl/isisc/isisc_acl.h | 143 + .../src/include/hsl/isisc/isisc_api.h | 1093 + .../src/include/hsl/isisc/isisc_cosmap.h | 109 + .../src/include/hsl/isisc/isisc_fdb.h | 168 + .../src/include/hsl/isisc/isisc_fdb_prv.h | 49 + .../src/include/hsl/isisc/isisc_igmp.h | 165 + .../src/include/hsl/isisc/isisc_init.h | 51 + .../include/hsl/isisc/isisc_interface_ctrl.h | 78 + .../qca-ssdk/src/include/hsl/isisc/isisc_ip.h | 153 + .../src/include/hsl/isisc/isisc_leaky.h | 94 + .../src/include/hsl/isisc/isisc_led.h | 57 + .../src/include/hsl/isisc/isisc_mib.h | 69 + .../src/include/hsl/isisc/isisc_mirror.h | 73 + .../src/include/hsl/isisc/isisc_misc.h | 238 + .../src/include/hsl/isisc/isisc_nat.h | 153 + .../src/include/hsl/isisc/isisc_nat_helper.h | 50 + .../src/include/hsl/isisc/isisc_port_ctrl.h | 226 + .../src/include/hsl/isisc/isisc_portvlan.h | 228 + .../src/include/hsl/isisc/isisc_qos.h | 180 + .../src/include/hsl/isisc/isisc_rate.h | 96 + .../src/include/hsl/isisc/isisc_reg.h | 5478 + .../src/include/hsl/isisc/isisc_reg_access.h | 70 + .../src/include/hsl/isisc/isisc_sec.h | 53 + .../src/include/hsl/isisc/isisc_stp.h | 55 + .../src/include/hsl/isisc/isisc_trunk.h | 69 + .../src/include/hsl/isisc/isisc_vlan.h | 99 + .../qca-ssdk/src/include/hsl/mp/mp_mib.h | 392 + .../qca-ssdk/src/include/hsl/mp/mp_mib_reg.h | 875 + .../qca-ssdk/src/include/hsl/mp/mp_portctrl.h | 113 + .../src/include/hsl/mp/mp_portctrl_reg.h | 219 + .../qca-ssdk/src/include/hsl/mp/mp_uniphy.h | 40 + .../src/include/hsl/mp/mp_uniphy_reg.h | 60 + .../src/include/hsl/phy/aquantia_phy.h | 394 + .../qca-ssdk/src/include/hsl/phy/f1_phy.h | 479 + .../qca-ssdk/src/include/hsl/phy/f2_phy.h | 399 + .../qca-ssdk/src/include/hsl/phy/hsl_phy.h | 722 + .../qca-ssdk/src/include/hsl/phy/malibu_phy.h | 676 + .../qca-ssdk/src/include/hsl/phy/mpge_led.h | 41 + .../qca-ssdk/src/include/hsl/phy/mpge_phy.h | 95 + .../src/include/hsl/phy/qca803x_phy.h | 425 + .../qca-ssdk/src/include/hsl/phy/qca808x.h | 135 + .../src/include/hsl/phy/qca808x_led.h | 52 + .../src/include/hsl/phy/qca808x_phy.h | 630 + .../src/include/hsl/phy/qca808x_ptp.h | 223 + .../src/include/hsl/phy/qca808x_ptp_api.h | 5858 + .../src/include/hsl/phy/qca808x_ptp_reg.h | 5853 + .../qca-ssdk/src/include/hsl/phy/sfp_phy.h | 47 + .../src/include/hsl/scomphy/scomphy_init.h | 42 + .../include/hsl/scomphy/scomphy_port_ctrl.h | 233 + .../include/hsl/scomphy/scomphy_reg_access.h | 62 + .../qca-ssdk/src/include/hsl/sfp/sfp.h | 956 + .../qca-ssdk/src/include/hsl/sfp/sfp_access.h | 53 + .../qca-ssdk/src/include/hsl/sfp/sfp_reg.h | 1319 + .../src/include/hsl/shiva/shiva_acl.h | 114 + .../src/include/hsl/shiva/shiva_api.h | 609 + .../src/include/hsl/shiva/shiva_fdb.h | 109 + .../src/include/hsl/shiva/shiva_igmp.h | 133 + .../src/include/hsl/shiva/shiva_init.h | 51 + .../src/include/hsl/shiva/shiva_leaky.h | 100 + .../src/include/hsl/shiva/shiva_led.h | 55 + .../src/include/hsl/shiva/shiva_mib.h | 65 + .../src/include/hsl/shiva/shiva_mirror.h | 79 + .../src/include/hsl/shiva/shiva_misc.h | 188 + .../src/include/hsl/shiva/shiva_port_ctrl.h | 151 + .../src/include/hsl/shiva/shiva_portvlan.h | 211 + .../src/include/hsl/shiva/shiva_qos.h | 164 + .../src/include/hsl/shiva/shiva_rate.h | 102 + .../src/include/hsl/shiva/shiva_reduced_acl.h | 54 + .../src/include/hsl/shiva/shiva_reg.h | 4075 + .../src/include/hsl/shiva/shiva_reg_access.h | 63 + .../src/include/hsl/shiva/shiva_stp.h | 61 + .../src/include/hsl/shiva/shiva_vlan.h | 83 + .../qca-ssdk/src/include/init/ssdk_clk.h | 307 + .../qca-ssdk/src/include/init/ssdk_dts.h | 188 + .../qca-ssdk/src/include/init/ssdk_hppe.h | 32 + .../qca-ssdk/src/include/init/ssdk_init.h | 390 + .../src/include/init/ssdk_interrupt.h | 29 + .../qca-ssdk/src/include/init/ssdk_led.h | 53 + .../qca-ssdk/src/include/init/ssdk_mp.h | 35 + .../qca-ssdk/src/include/init/ssdk_phy_i2c.h | 76 + .../qca-ssdk/src/include/init/ssdk_plat.h | 413 + .../qca-ssdk/src/include/init/ssdk_scomphy.h | 33 + .../qca-ssdk/src/include/init/ssdk_uci.h | 31 + .../qca-ssdk/src/include/ref/ref_api.h | 47 + .../qca-ssdk/src/include/ref/ref_fdb.h | 54 + .../qca-ssdk/src/include/ref/ref_mib.h | 50 + .../qca-ssdk/src/include/ref/ref_misc.h | 41 + .../qca-ssdk/src/include/ref/ref_port_ctrl.h | 58 + .../qca-ssdk/src/include/ref/ref_uci.h | 35 + .../qca-ssdk/src/include/ref/ref_vlan.h | 88 + .../qca-ssdk/src/include/ref/ref_vsi.h | 73 + .../qca-ssdk/src/include/sal/os/aos_lock.h | 47 + .../qca-ssdk/src/include/sal/os/aos_mem.h | 112 + .../qca-ssdk/src/include/sal/os/aos_timer.h | 46 + .../qca-ssdk/src/include/sal/os/aos_types.h | 180 + .../src/include/sal/os/linux/aos_lock_pvt.h | 47 + .../src/include/sal/os/linux/aos_mem_pvt.h | 60 + .../src/include/sal/os/linux/aos_timer_pvt.h | 43 + .../src/include/sal/os/linux/aos_types_pvt.h | 70 + .../sal/sd/linux/uk_interface/sw_api_ks.h | 34 + .../ipq807x/qca-ssdk/src/include/sal/sd/sd.h | 77 + .../qca-ssdk/src/include/shell_lib/shell.h | 43 + .../src/include/shell_lib/shell_config.h | 78 + .../qca-ssdk/src/include/shell_lib/shell_io.h | 484 + .../qca-ssdk/src/include/shell_lib/shell_sw.h | 32 + feeds/ipq807x/qca-ssdk/src/ko_Makefile | 3 + feeds/ipq807x/qca-ssdk/src/make/.build_number | 1 + feeds/ipq807x/qca-ssdk/src/make/components.mk | 36 + feeds/ipq807x/qca-ssdk/src/make/config.mk | 119 + feeds/ipq807x/qca-ssdk/src/make/defs.mk | 28 + feeds/ipq807x/qca-ssdk/src/make/linux_opt.mk | 698 + feeds/ipq807x/qca-ssdk/src/make/target.mk | 49 + feeds/ipq807x/qca-ssdk/src/make/tools.mk | 12 + feeds/ipq807x/qca-ssdk/src/src/adpt/Makefile | 12 + feeds/ipq807x/qca-ssdk/src/src/adpt/adpt.c | 658 + .../qca-ssdk/src/src/adpt/cppe/Makefile | 48 + .../src/src/adpt/cppe/adpt_cppe_flow.c | 77 + .../src/src/adpt/cppe/adpt_cppe_mib.c | 181 + .../src/src/adpt/cppe/adpt_cppe_misc.c | 121 + .../src/src/adpt/cppe/adpt_cppe_portctrl.c | 541 + .../qca-ssdk/src/src/adpt/cppe/adpt_cppe_qm.c | 60 + .../src/src/adpt/cppe/adpt_cppe_qos.c | 289 + .../src/src/adpt/cppe/adpt_cppe_uniphy.c | 304 + .../qca-ssdk/src/src/adpt/hppe/Makefile | 112 + .../src/src/adpt/hppe/adpt_hppe_acl.c | 4021 + .../qca-ssdk/src/src/adpt/hppe/adpt_hppe_bm.c | 452 + .../src/src/adpt/hppe/adpt_hppe_ctrlpkt.c | 385 + .../src/src/adpt/hppe/adpt_hppe_fdb.c | 1520 + .../src/src/adpt/hppe/adpt_hppe_flow.c | 1850 + .../qca-ssdk/src/src/adpt/hppe/adpt_hppe_ip.c | 1355 + .../src/src/adpt/hppe/adpt_hppe_mib.c | 1019 + .../src/src/adpt/hppe/adpt_hppe_mirror.c | 345 + .../src/src/adpt/hppe/adpt_hppe_misc.c | 1011 + .../src/src/adpt/hppe/adpt_hppe_policer.c | 1080 + .../src/src/adpt/hppe/adpt_hppe_portctrl.c | 5560 + .../src/src/adpt/hppe/adpt_hppe_portvlan.c | 2212 + .../src/src/adpt/hppe/adpt_hppe_pppoe.c | 330 + .../src/src/adpt/hppe/adpt_hppe_ptp.c | 1382 + .../qca-ssdk/src/src/adpt/hppe/adpt_hppe_qm.c | 1413 + .../src/src/adpt/hppe/adpt_hppe_qos.c | 1235 + .../src/src/adpt/hppe/adpt_hppe_rss_hash.c | 296 + .../src/src/adpt/hppe/adpt_hppe_sec.c | 261 + .../src/src/adpt/hppe/adpt_hppe_servcode.c | 172 + .../src/src/adpt/hppe/adpt_hppe_shaper.c | 1591 + .../src/src/adpt/hppe/adpt_hppe_stp.c | 135 + .../src/src/adpt/hppe/adpt_hppe_trunk.c | 369 + .../src/src/adpt/hppe/adpt_hppe_uniphy.c | 791 + .../src/src/adpt/hppe/adpt_hppe_vsi.c | 637 + .../ipq807x/qca-ssdk/src/src/adpt/mp/Makefile | 32 + .../src/src/adpt/mp/adpt_mp_interrupt.c | 119 + .../qca-ssdk/src/src/adpt/mp/adpt_mp_led.c | 138 + .../qca-ssdk/src/src/adpt/mp/adpt_mp_mib.c | 360 + .../src/src/adpt/mp/adpt_mp_portctrl.c | 1337 + .../qca-ssdk/src/src/adpt/mp/adpt_mp_uniphy.c | 398 + .../qca-ssdk/src/src/adpt/sfp/Makefile | 16 + .../qca-ssdk/src/src/adpt/sfp/adpt_sfp.c | 668 + feeds/ipq807x/qca-ssdk/src/src/api/Makefile | 12 + .../ipq807x/qca-ssdk/src/src/api/api_access.c | 177 + feeds/ipq807x/qca-ssdk/src/src/fal/Makefile | 140 + feeds/ipq807x/qca-ssdk/src/src/fal/fal_acl.c | 741 + feeds/ipq807x/qca-ssdk/src/src/fal/fal_bm.c | 422 + .../ipq807x/qca-ssdk/src/src/fal/fal_cosmap.c | 783 + .../qca-ssdk/src/src/fal/fal_ctrlpkt.c | 248 + feeds/ipq807x/qca-ssdk/src/src/fal/fal_fdb.c | 1942 + feeds/ipq807x/qca-ssdk/src/src/fal/fal_flow.c | 467 + feeds/ipq807x/qca-ssdk/src/src/fal/fal_igmp.c | 961 + feeds/ipq807x/qca-ssdk/src/src/fal/fal_init.c | 212 + .../qca-ssdk/src/src/fal/fal_interface_ctrl.c | 386 + feeds/ipq807x/qca-ssdk/src/src/fal/fal_ip.c | 2370 + .../ipq807x/qca-ssdk/src/src/fal/fal_leaky.c | 353 + feeds/ipq807x/qca-ssdk/src/src/fal/fal_led.c | 158 + feeds/ipq807x/qca-ssdk/src/src/fal/fal_mib.c | 688 + .../ipq807x/qca-ssdk/src/src/fal/fal_mirror.c | 344 + feeds/ipq807x/qca-ssdk/src/src/fal/fal_misc.c | 1772 + feeds/ipq807x/qca-ssdk/src/src/fal/fal_nat.c | 1341 + .../qca-ssdk/src/src/fal/fal_policer.c | 343 + .../qca-ssdk/src/src/fal/fal_port_ctrl.c | 3728 + .../qca-ssdk/src/src/fal/fal_portvlan.c | 2538 + .../ipq807x/qca-ssdk/src/src/fal/fal_pppoe.c | 609 + feeds/ipq807x/qca-ssdk/src/src/fal/fal_ptp.c | 1208 + feeds/ipq807x/qca-ssdk/src/src/fal/fal_qm.c | 1089 + feeds/ipq807x/qca-ssdk/src/src/fal/fal_qos.c | 2000 + feeds/ipq807x/qca-ssdk/src/src/fal/fal_rate.c | 840 + .../qca-ssdk/src/src/fal/fal_reg_access.c | 570 + .../qca-ssdk/src/src/fal/fal_rss_hash.c | 85 + feeds/ipq807x/qca-ssdk/src/src/fal/fal_sec.c | 247 + .../qca-ssdk/src/src/fal/fal_servcode.c | 143 + feeds/ipq807x/qca-ssdk/src/src/fal/fal_sfp.c | 508 + .../ipq807x/qca-ssdk/src/src/fal/fal_shaper.c | 601 + feeds/ipq807x/qca-ssdk/src/src/fal/fal_stp.c | 130 + .../ipq807x/qca-ssdk/src/src/fal/fal_trunk.c | 324 + feeds/ipq807x/qca-ssdk/src/src/fal/fal_vlan.c | 933 + feeds/ipq807x/qca-ssdk/src/src/fal/fal_vsi.c | 343 + feeds/ipq807x/qca-ssdk/src/src/hsl/Makefile | 39 + .../qca-ssdk/src/src/hsl/athena/Makefile | 44 + .../qca-ssdk/src/src/hsl/athena/athena_fdb.c | 639 + .../qca-ssdk/src/src/hsl/athena/athena_init.c | 290 + .../qca-ssdk/src/src/hsl/athena/athena_mib.c | 406 + .../src/src/hsl/athena/athena_port_ctrl.c | 811 + .../src/src/hsl/athena/athena_portvlan.c | 451 + .../src/src/hsl/athena/athena_reg_access.c | 272 + .../qca-ssdk/src/src/hsl/athena/athena_vlan.c | 622 + .../qca-ssdk/src/src/hsl/cppe/Makefile | 23 + .../qca-ssdk/src/src/hsl/cppe/cppe_loopback.c | 440 + .../qca-ssdk/src/src/hsl/cppe/cppe_portctrl.c | 488 + .../qca-ssdk/src/src/hsl/cppe/cppe_qos.c | 428 + .../qca-ssdk/src/src/hsl/dess/Makefile | 114 + .../qca-ssdk/src/src/hsl/dess/dess_acl.c | 2039 + .../src/src/hsl/dess/dess_acl_parse.c | 2452 + .../qca-ssdk/src/src/hsl/dess/dess_acl_prv.h | 126 + .../qca-ssdk/src/src/hsl/dess/dess_cosmap.c | 945 + .../qca-ssdk/src/src/hsl/dess/dess_fdb.c | 2431 + .../qca-ssdk/src/src/hsl/dess/dess_igmp.c | 1147 + .../qca-ssdk/src/src/hsl/dess/dess_init.c | 343 + .../src/src/hsl/dess/dess_interface_ctrl.c | 299 + .../qca-ssdk/src/src/hsl/dess/dess_ip.c | 3668 + .../qca-ssdk/src/src/hsl/dess/dess_leaky.c | 526 + .../qca-ssdk/src/src/hsl/dess/dess_led.c | 670 + .../qca-ssdk/src/src/hsl/dess/dess_mib.c | 861 + .../qca-ssdk/src/src/hsl/dess/dess_mirror.c | 316 + .../qca-ssdk/src/src/hsl/dess/dess_misc.c | 2450 + .../src/src/hsl/dess/dess_multicast_acl.c | 1030 + .../qca-ssdk/src/src/hsl/dess/dess_nat.c | 3213 + .../src/src/hsl/dess/dess_port_ctrl.c | 3983 + .../qca-ssdk/src/src/hsl/dess/dess_portvlan.c | 2336 + .../qca-ssdk/src/src/hsl/dess/dess_psgmii.c | 722 + .../qca-ssdk/src/src/hsl/dess/dess_qos.c | 1562 + .../qca-ssdk/src/src/hsl/dess/dess_rate.c | 1672 + .../src/src/hsl/dess/dess_reg_access.c | 644 + .../qca-ssdk/src/src/hsl/dess/dess_sec.c | 787 + .../qca-ssdk/src/src/hsl/dess/dess_stp.c | 193 + .../qca-ssdk/src/src/hsl/dess/dess_trunk.c | 327 + .../qca-ssdk/src/src/hsl/dess/dess_vlan.c | 906 + .../qca-ssdk/src/src/hsl/garuda/Makefile | 84 + .../qca-ssdk/src/src/hsl/garuda/garuda_acl.c | 3034 + .../qca-ssdk/src/src/hsl/garuda/garuda_fdb.c | 1007 + .../qca-ssdk/src/src/hsl/garuda/garuda_igmp.c | 610 + .../qca-ssdk/src/src/hsl/garuda/garuda_init.c | 642 + .../src/src/hsl/garuda/garuda_leaky.c | 531 + .../qca-ssdk/src/src/hsl/garuda/garuda_led.c | 370 + .../qca-ssdk/src/src/hsl/garuda/garuda_mib.c | 378 + .../src/src/hsl/garuda/garuda_mirror.c | 318 + .../qca-ssdk/src/src/hsl/garuda/garuda_misc.c | 1009 + .../src/src/hsl/garuda/garuda_port_ctrl.c | 1069 + .../src/src/hsl/garuda/garuda_portvlan.c | 912 + .../qca-ssdk/src/src/hsl/garuda/garuda_qos.c | 1191 + .../qca-ssdk/src/src/hsl/garuda/garuda_rate.c | 851 + .../src/src/hsl/garuda/garuda_reduced_acl.c | 170 + .../src/src/hsl/garuda/garuda_reg_access.c | 271 + .../qca-ssdk/src/src/hsl/garuda/garuda_stp.c | 193 + .../qca-ssdk/src/src/hsl/garuda/garuda_vlan.c | 498 + .../qca-ssdk/src/src/hsl/horus/Makefile | 80 + .../qca-ssdk/src/src/hsl/horus/horus_fdb.c | 999 + .../qca-ssdk/src/src/hsl/horus/horus_igmp.c | 979 + .../qca-ssdk/src/src/hsl/horus/horus_init.c | 432 + .../qca-ssdk/src/src/hsl/horus/horus_leaky.c | 525 + .../qca-ssdk/src/src/hsl/horus/horus_led.c | 427 + .../qca-ssdk/src/src/hsl/horus/horus_mib.c | 377 + .../qca-ssdk/src/src/hsl/horus/horus_mirror.c | 317 + .../qca-ssdk/src/src/hsl/horus/horus_misc.c | 1396 + .../src/src/hsl/horus/horus_port_ctrl.c | 1061 + .../src/src/hsl/horus/horus_portvlan.c | 1184 + .../qca-ssdk/src/src/hsl/horus/horus_qos.c | 1260 + .../qca-ssdk/src/src/hsl/horus/horus_rate.c | 578 + .../src/src/hsl/horus/horus_reg_access.c | 273 + .../qca-ssdk/src/src/hsl/horus/horus_stp.c | 192 + .../qca-ssdk/src/src/hsl/horus/horus_vlan.c | 518 + .../qca-ssdk/src/src/hsl/hppe/Makefile | 110 + .../qca-ssdk/src/src/hsl/hppe/hppe_acl.c | 3164 + .../qca-ssdk/src/src/hsl/hppe/hppe_bm.c | 3027 + .../qca-ssdk/src/src/hsl/hppe/hppe_ctrlpkt.c | 581 + .../qca-ssdk/src/src/hsl/hppe/hppe_fdb.c | 2178 + .../qca-ssdk/src/src/hsl/hppe/hppe_flow.c | 5814 + .../qca-ssdk/src/src/hsl/hppe/hppe_global.c | 3117 + .../qca-ssdk/src/src/hsl/hppe/hppe_init.c | 234 + .../qca-ssdk/src/src/hsl/hppe/hppe_ip.c | 6892 + .../qca-ssdk/src/src/hsl/hppe/hppe_mib.c | 2167 + .../qca-ssdk/src/src/hsl/hppe/hppe_mirror.c | 194 + .../qca-ssdk/src/src/hsl/hppe/hppe_policer.c | 2928 + .../qca-ssdk/src/src/hsl/hppe/hppe_portctrl.c | 3441 + .../qca-ssdk/src/src/hsl/hppe/hppe_portvlan.c | 4057 + .../qca-ssdk/src/src/hsl/hppe/hppe_pppoe.c | 388 + .../qca-ssdk/src/src/hsl/hppe/hppe_qm.c | 9622 ++ .../qca-ssdk/src/src/hsl/hppe/hppe_qos.c | 4548 + .../src/src/hsl/hppe/hppe_reg_access.c | 77 + .../qca-ssdk/src/src/hsl/hppe/hppe_rss.c | 585 + .../qca-ssdk/src/src/hsl/hppe/hppe_sec.c | 1041 + .../qca-ssdk/src/src/hsl/hppe/hppe_servcode.c | 511 + .../qca-ssdk/src/src/hsl/hppe/hppe_shaper.c | 2396 + .../qca-ssdk/src/src/hsl/hppe/hppe_stp.c | 85 + .../qca-ssdk/src/src/hsl/hppe/hppe_trunk.c | 790 + .../qca-ssdk/src/src/hsl/hppe/hppe_uniphy.c | 6120 + .../qca-ssdk/src/src/hsl/hppe/hppe_vsi.c | 650 + .../qca-ssdk/src/src/hsl/hppe/hppe_xgmacmib.c | 4210 + .../src/src/hsl/hppe/hppe_xgportctrl.c | 6074 + feeds/ipq807x/qca-ssdk/src/src/hsl/hsl_acl.c | 972 + feeds/ipq807x/qca-ssdk/src/src/hsl/hsl_api.c | 42 + feeds/ipq807x/qca-ssdk/src/src/hsl/hsl_dev.c | 705 + feeds/ipq807x/qca-ssdk/src/src/hsl/hsl_lock.c | 30 + .../qca-ssdk/src/src/hsl/hsl_port_prop.c | 226 + .../qca-ssdk/src/src/hsl/isis/Makefile | 124 + .../qca-ssdk/src/src/hsl/isis/isis_acl.c | 1904 + .../src/src/hsl/isis/isis_acl_parse.c | 2452 + .../qca-ssdk/src/src/hsl/isis/isis_acl_prv.h | 125 + .../qca-ssdk/src/src/hsl/isis/isis_cosmap.c | 637 + .../qca-ssdk/src/src/hsl/isis/isis_fdb.c | 2217 + .../qca-ssdk/src/src/hsl/isis/isis_igmp.c | 1143 + .../qca-ssdk/src/src/hsl/isis/isis_init.c | 340 + .../src/src/hsl/isis/isis_interface_ctrl.c | 1710 + .../qca-ssdk/src/src/hsl/isis/isis_ip.c | 2516 + .../qca-ssdk/src/src/hsl/isis/isis_leaky.c | 526 + .../qca-ssdk/src/src/hsl/isis/isis_led.c | 405 + .../src/src/hsl/isis/isis_mac_block.c | 388 + .../qca-ssdk/src/src/hsl/isis/isis_mib.c | 663 + .../qca-ssdk/src/src/hsl/isis/isis_mirror.c | 315 + .../qca-ssdk/src/src/hsl/isis/isis_misc.c | 1835 + .../src/src/hsl/isis/isis_multicast_acl.c | 985 + .../qca-ssdk/src/src/hsl/isis/isis_nat.c | 2457 + .../src/src/hsl/isis/isis_port_ctrl.c | 2356 + .../qca-ssdk/src/src/hsl/isis/isis_portvlan.c | 2130 + .../qca-ssdk/src/src/hsl/isis/isis_qos.c | 1325 + .../qca-ssdk/src/src/hsl/isis/isis_rate.c | 1549 + .../src/src/hsl/isis/isis_reg_access.c | 507 + .../qca-ssdk/src/src/hsl/isis/isis_sec.c | 787 + .../qca-ssdk/src/src/hsl/isis/isis_stp.c | 193 + .../qca-ssdk/src/src/hsl/isis/isis_trunk.c | 692 + .../qca-ssdk/src/src/hsl/isis/isis_vlan.c | 909 + .../qca-ssdk/src/src/hsl/isisc/Makefile | 122 + .../qca-ssdk/src/src/hsl/isisc/isisc_acl.c | 2035 + .../src/src/hsl/isisc/isisc_acl_parse.c | 2452 + .../src/src/hsl/isisc/isisc_acl_prv.h | 126 + .../qca-ssdk/src/src/hsl/isisc/isisc_cosmap.c | 647 + .../qca-ssdk/src/src/hsl/isisc/isisc_fdb.c | 2294 + .../qca-ssdk/src/src/hsl/isisc/isisc_igmp.c | 1147 + .../qca-ssdk/src/src/hsl/isisc/isisc_init.c | 337 + .../src/src/hsl/isisc/isisc_interface_ctrl.c | 2324 + .../qca-ssdk/src/src/hsl/isisc/isisc_ip.c | 2555 + .../qca-ssdk/src/src/hsl/isisc/isisc_leaky.c | 526 + .../qca-ssdk/src/src/hsl/isisc/isisc_led.c | 405 + .../qca-ssdk/src/src/hsl/isisc/isisc_mib.c | 860 + .../qca-ssdk/src/src/hsl/isisc/isisc_mirror.c | 315 + .../qca-ssdk/src/src/hsl/isisc/isisc_misc.c | 2207 + .../src/src/hsl/isisc/isisc_multicast_acl.c | 1024 + .../qca-ssdk/src/src/hsl/isisc/isisc_nat.c | 2468 + .../src/src/hsl/isisc/isisc_port_ctrl.c | 2797 + .../src/src/hsl/isisc/isisc_portvlan.c | 2277 + .../qca-ssdk/src/src/hsl/isisc/isisc_qos.c | 1639 + .../qca-ssdk/src/src/hsl/isisc/isisc_rate.c | 1662 + .../src/src/hsl/isisc/isisc_reg_access.c | 459 + .../qca-ssdk/src/src/hsl/isisc/isisc_sec.c | 787 + .../qca-ssdk/src/src/hsl/isisc/isisc_stp.c | 193 + .../qca-ssdk/src/src/hsl/isisc/isisc_trunk.c | 692 + .../qca-ssdk/src/src/hsl/isisc/isisc_vlan.c | 906 + .../ipq807x/qca-ssdk/src/src/hsl/mp/Makefile | 26 + .../ipq807x/qca-ssdk/src/src/hsl/mp/mp_mib.c | 816 + .../qca-ssdk/src/src/hsl/mp/mp_portctrl.c | 231 + .../qca-ssdk/src/src/hsl/mp/mp_uniphy.c | 55 + .../ipq807x/qca-ssdk/src/src/hsl/phy/Makefile | 96 + .../qca-ssdk/src/src/hsl/phy/aquantia_phy.c | 2205 + .../ipq807x/qca-ssdk/src/src/hsl/phy/f1_phy.c | 1534 + .../ipq807x/qca-ssdk/src/src/hsl/phy/f2_phy.c | 918 + .../qca-ssdk/src/src/hsl/phy/hsl_phy.c | 818 + .../qca-ssdk/src/src/hsl/phy/malibu_phy.c | 2872 + .../qca-ssdk/src/src/hsl/phy/mpge_led.c | 66 + .../qca-ssdk/src/src/hsl/phy/mpge_phy.c | 1090 + .../qca-ssdk/src/src/hsl/phy/qca803x_phy.c | 2341 + .../qca-ssdk/src/src/hsl/phy/qca808x.c | 595 + .../qca-ssdk/src/src/hsl/phy/qca808x_led.c | 272 + .../qca-ssdk/src/src/hsl/phy/qca808x_phc.c | 1472 + .../qca-ssdk/src/src/hsl/phy/qca808x_phy.c | 2265 + .../qca-ssdk/src/src/hsl/phy/qca808x_ptp.c | 2843 + .../src/src/hsl/phy/qca808x_ptp_api.c | 15319 +++ .../qca-ssdk/src/src/hsl/phy/sfp_phy.c | 254 + .../qca-ssdk/src/src/hsl/scomphy/Makefile | 28 + .../src/src/hsl/scomphy/scomphy_init.c | 196 + .../src/src/hsl/scomphy/scomphy_port_ctrl.c | 2078 + .../src/src/hsl/scomphy/scomphy_reg_access.c | 147 + .../ipq807x/qca-ssdk/src/src/hsl/sfp/Makefile | 16 + feeds/ipq807x/qca-ssdk/src/src/hsl/sfp/sfp.c | 2296 + .../qca-ssdk/src/src/hsl/sfp/sfp_access.c | 59 + .../qca-ssdk/src/src/hsl/shiva/Makefile | 84 + .../qca-ssdk/src/src/hsl/shiva/shiva_acl.c | 3171 + .../qca-ssdk/src/src/hsl/shiva/shiva_fdb.c | 1135 + .../qca-ssdk/src/src/hsl/shiva/shiva_igmp.c | 980 + .../qca-ssdk/src/src/hsl/shiva/shiva_init.c | 448 + .../qca-ssdk/src/src/hsl/shiva/shiva_leaky.c | 526 + .../qca-ssdk/src/src/hsl/shiva/shiva_led.c | 428 + .../qca-ssdk/src/src/hsl/shiva/shiva_mib.c | 663 + .../qca-ssdk/src/src/hsl/shiva/shiva_mirror.c | 317 + .../qca-ssdk/src/src/hsl/shiva/shiva_misc.c | 1749 + .../src/src/hsl/shiva/shiva_port_ctrl.c | 1384 + .../src/src/hsl/shiva/shiva_portvlan.c | 1859 + .../qca-ssdk/src/src/hsl/shiva/shiva_qos.c | 1288 + .../qca-ssdk/src/src/hsl/shiva/shiva_rate.c | 852 + .../src/src/hsl/shiva/shiva_reduced_acl.c | 178 + .../src/src/hsl/shiva/shiva_reg_access.c | 271 + .../qca-ssdk/src/src/hsl/shiva/shiva_stp.c | 193 + .../qca-ssdk/src/src/hsl/shiva/shiva_vlan.c | 524 + feeds/ipq807x/qca-ssdk/src/src/init/Makefile | 40 + .../ipq807x/qca-ssdk/src/src/init/ssdk_clk.c | 1207 + .../ipq807x/qca-ssdk/src/src/init/ssdk_dts.c | 1199 + .../ipq807x/qca-ssdk/src/src/init/ssdk_hppe.c | 1271 + .../ipq807x/qca-ssdk/src/src/init/ssdk_init.c | 3651 + .../qca-ssdk/src/src/init/ssdk_interrupt.c | 209 + .../ipq807x/qca-ssdk/src/src/init/ssdk_led.c | 159 + feeds/ipq807x/qca-ssdk/src/src/init/ssdk_mp.c | 117 + .../qca-ssdk/src/src/init/ssdk_phy_i2c.c | 462 + .../ipq807x/qca-ssdk/src/src/init/ssdk_plat.c | 1417 + .../qca-ssdk/src/src/init/ssdk_scomphy.c | 40 + .../ipq807x/qca-ssdk/src/src/init/ssdk_uci.c | 196 + feeds/ipq807x/qca-ssdk/src/src/ref/Makefile | 45 + feeds/ipq807x/qca-ssdk/src/src/ref/ref_fdb.c | 164 + feeds/ipq807x/qca-ssdk/src/src/ref/ref_mib.c | 520 + feeds/ipq807x/qca-ssdk/src/src/ref/ref_misc.c | 193 + .../qca-ssdk/src/src/ref/ref_port_ctrl.c | 712 + feeds/ipq807x/qca-ssdk/src/src/ref/ref_uci.c | 11809 ++ feeds/ipq807x/qca-ssdk/src/src/ref/ref_vlan.c | 562 + feeds/ipq807x/qca-ssdk/src/src/ref/ref_vsi.c | 494 + feeds/ipq807x/qca-ssdk/src/src/sal/Makefile | 12 + .../ipq807x/qca-ssdk/src/src/sal/sd/Makefile | 12 + .../qca-ssdk/src/src/sal/sd/linux/Makefile | 12 + .../src/sal/sd/linux/uk_interface/Makefile | 34 + .../sd/linux/uk_interface/sw_api_ks_ioctl.c | 316 + .../sd/linux/uk_interface/sw_api_ks_netlink.c | 789 + feeds/ipq807x/qca-ssdk/src/src/sal/sd/sd.c | 371 + .../qca-ssdk/src/src/shell_lib/Makefile | 12 + .../qca-ssdk/src/src/shell_lib/shell.c | 555 + .../qca-ssdk/src/src/shell_lib/shell_config.c | 1512 + .../qca-ssdk/src/src/shell_lib/shell_io.c | 14042 ++ .../qca-ssdk/src/src/shell_lib/shell_sw.c | 53 + feeds/ipq807x/qca-ssdk/src/src/util/Makefile | 12 + feeds/ipq807x/qca-ssdk/src/src/util/util.c | 486 + feeds/ipq807x/qca-thermald-10.4/Makefile | 44 + .../qca-thermald-10.4/files/thermal.config | 2 + .../qca-thermald-10.4/files/thermal.init | 23 + .../ipq807x/qca-thermald-10.4/src/Android.mk | 236 + feeds/ipq807x/qca-thermald-10.4/src/Makefile | 74 + .../ipq807x/qca-thermald-10.4/src/Makefile.am | 35 + .../qca-thermald-10.4/src/adc-sensor.c | 119 + .../qca-thermald-10.4/src/adc-sensor.h | 17 + .../qca-thermald-10.4/src/bcl-sensor.c | 674 + .../qca-thermald-10.4/src/bcl-sensor.h | 21 + .../qca-thermald-10.4/src/configure.ac | 67 + .../qca-thermald-10.4/src/gen-sensor.c | 76 + .../qca-thermald-10.4/src/gen-sensor.h | 17 + .../src/ipq-thermald-8064.conf | 77 + .../src/ipq-thermald-8066.conf | 77 + .../src/ipq-thermald-8069.conf | 77 + .../src/modem_mitigation_oncrpc.c | 480 + .../src/modem_mitigation_qmi.c | 565 + .../qca-thermald-10.4/src/modem_sensor_qmi.c | 470 + .../qca-thermald-10.4/src/pm8821-sensor.c | 242 + .../qca-thermald-10.4/src/pm8821-sensor.h | 19 + .../qca-thermald-10.4/src/qmi-ts-sensor.c | 372 + .../qca-thermald-10.4/src/qmi-ts-sensor.h | 20 + .../ipq807x/qca-thermald-10.4/src/readme.txt | 173 + .../qca-thermald-10.4/src/sensors-7x30.c | 159 + .../qca-thermald-10.4/src/sensors-8660.c | 223 + .../qca-thermald-10.4/src/sensors-8960.c | 991 + .../qca-thermald-10.4/src/sensors-8974.c | 322 + .../qca-thermald-10.4/src/sensors-8x25.c | 182 + .../qca-thermald-10.4/src/sensors-hw.h | 95 + .../qca-thermald-10.4/src/sensors-ipq.c | 417 + feeds/ipq807x/qca-thermald-10.4/src/thermal.c | 211 + feeds/ipq807x/qca-thermald-10.4/src/thermal.h | 391 + .../qca-thermald-10.4/src/thermal_actions.c | 1418 + .../qca-thermald-10.4/src/thermal_client.c | 357 + .../qca-thermald-10.4/src/thermal_client.h | 22 + .../qca-thermald-10.4/src/thermal_config.c | 1141 + .../src/thermal_lib_common.c | 146 + .../src/thermal_lib_common.h | 38 + .../thermal_mitigation_device_service_v01.c | 231 + .../thermal_mitigation_device_service_v01.h | 338 + .../qca-thermald-10.4/src/thermal_monitor.c | 318 + .../src/thermal_sensor_service_v01.c | 179 + .../src/thermal_sensor_service_v01.h | 272 + .../qca-thermald-10.4/src/thermal_server.c | 467 + .../qca-thermald-10.4/src/thermal_server.h | 25 + .../qca-thermald-10.4/src/thermal_util.c | 492 + .../qca-thermald-10.4/src/thermald-7x30.conf | 9 + .../qca-thermald-10.4/src/thermald-8064.conf | 92 + .../src/thermald-8064ab.conf | 92 + .../qca-thermald-10.4/src/thermald-8660.conf | 15 + .../qca-thermald-10.4/src/thermald-8930.conf | 79 + .../src/thermald-8930ab.conf | 79 + .../qca-thermald-10.4/src/thermald-8960.conf | 44 + .../src/thermald-8960ab.conf | 44 + .../qca-thermald-10.4/src/thermald-8974.conf | 80 + .../src/thermald-8x25-msm1-pmic_therm.conf | 10 + .../src/thermald-8x25-msm2-msm_therm.conf | 10 + .../src/thermald-8x25-msm2-pmic_therm.conf | 10 + .../src/thermald.conf_sample | 22 + .../qca-thermald-10.4/src/tsens-sensor.c | 408 + .../qca-thermald-10.4/src/tsens-sensor.h | 25 + feeds/p4/libjudy/Makefile | 40 + feeds/p4/libjudy/src/AUTHORS | 8 + feeds/p4/libjudy/src/COPYING | 516 + feeds/p4/libjudy/src/ChangeLog | 60 + feeds/p4/libjudy/src/INSTALL | 20 + feeds/p4/libjudy/src/Makefile.am | 19 + feeds/p4/libjudy/src/README | 149 + feeds/p4/libjudy/src/bootstrap | 14 + feeds/p4/libjudy/src/configure.ac | 265 + feeds/p4/libjudy/src/doc/Makefile.am | 209 + feeds/p4/libjudy/src/doc/ext/COPYRIGHT | 0 feeds/p4/libjudy/src/doc/ext/Judy1_3.htm | 309 + .../p4/libjudy/src/doc/ext/Judy1_funcs_3.htm | 260 + feeds/p4/libjudy/src/doc/ext/JudyHS_3.htm | 197 + .../p4/libjudy/src/doc/ext/JudyHS_funcs_3.htm | 150 + feeds/p4/libjudy/src/doc/ext/JudyL_3.htm | 358 + .../p4/libjudy/src/doc/ext/JudyL_funcs_3.htm | 248 + feeds/p4/libjudy/src/doc/ext/JudySL_3.htm | 246 + .../p4/libjudy/src/doc/ext/JudySL_funcs_3.htm | 186 + feeds/p4/libjudy/src/doc/ext/Judy_3.htm | 283 + feeds/p4/libjudy/src/doc/ext/LICENSE | 0 feeds/p4/libjudy/src/doc/ext/README | 20 + feeds/p4/libjudy/src/doc/ext/README_deliver | 20 + feeds/p4/libjudy/src/doc/int/10minutes.htm | 190 + feeds/p4/libjudy/src/examples/Judy1Dup.c | 47 + feeds/p4/libjudy/src/examples/Judy1Dup.h | 31 + feeds/p4/libjudy/src/examples/Judy1DupCheck.c | 80 + feeds/p4/libjudy/src/examples/Judy1Op.c | 150 + feeds/p4/libjudy/src/examples/Judy1Op.h | 15 + feeds/p4/libjudy/src/examples/Judy1OpCheck.c | 150 + feeds/p4/libjudy/src/examples/Makefile | 13 + feeds/p4/libjudy/src/examples/README | 8 + feeds/p4/libjudy/src/src/Judy.h | 622 + feeds/p4/libjudy/src/src/Judy.h.check.c | 139 + feeds/p4/libjudy/src/src/Judy1/Judy1.h | 551 + feeds/p4/libjudy/src/src/Judy1/Makefile.am | 114 + feeds/p4/libjudy/src/src/Judy1/README | 11 + .../libjudy/src/src/JudyCommon/JudyByCount.c | 954 + .../libjudy/src/src/JudyCommon/JudyCascade.c | 1942 + .../p4/libjudy/src/src/JudyCommon/JudyCount.c | 1195 + .../src/src/JudyCommon/JudyCreateBranch.c | 314 + .../src/src/JudyCommon/JudyDecascade.c | 1206 + feeds/p4/libjudy/src/src/JudyCommon/JudyDel.c | 2146 + .../p4/libjudy/src/src/JudyCommon/JudyFirst.c | 213 + .../src/src/JudyCommon/JudyFreeArray.c | 363 + feeds/p4/libjudy/src/src/JudyCommon/JudyGet.c | 1094 + feeds/p4/libjudy/src/src/JudyCommon/JudyIns.c | 1873 + .../libjudy/src/src/JudyCommon/JudyInsArray.c | 1178 + .../src/src/JudyCommon/JudyInsertBranch.c | 135 + .../libjudy/src/src/JudyCommon/JudyMalloc.c | 87 + .../libjudy/src/src/JudyCommon/JudyMallocIF.c | 782 + .../src/src/JudyCommon/JudyMemActive.c | 259 + .../libjudy/src/src/JudyCommon/JudyMemUsed.c | 61 + .../libjudy/src/src/JudyCommon/JudyPrevNext.c | 1890 + .../src/src/JudyCommon/JudyPrevNextEmpty.c | 1390 + .../libjudy/src/src/JudyCommon/JudyPrintJP.c | 401 + .../libjudy/src/src/JudyCommon/JudyPrivate.h | 1613 + .../src/src/JudyCommon/JudyPrivate1L.h | 485 + .../src/src/JudyCommon/JudyPrivateBranch.h | 788 + .../libjudy/src/src/JudyCommon/JudyTables.c | 296 + .../p4/libjudy/src/src/JudyCommon/Makefile.am | 8 + feeds/p4/libjudy/src/src/JudyCommon/README | 66 + feeds/p4/libjudy/src/src/JudyHS/JudyHS.c | 771 + feeds/p4/libjudy/src/src/JudyHS/JudyHS.h | 35 + feeds/p4/libjudy/src/src/JudyHS/Makefile.am | 8 + feeds/p4/libjudy/src/src/JudyHS/README | 10 + feeds/p4/libjudy/src/src/JudyL/JudyL.h | 505 + feeds/p4/libjudy/src/src/JudyL/Makefile.am | 114 + feeds/p4/libjudy/src/src/JudyL/README | 8 + feeds/p4/libjudy/src/src/JudySL/JudySL.c | 1127 + feeds/p4/libjudy/src/src/JudySL/Makefile.am | 8 + feeds/p4/libjudy/src/src/JudySL/README | 6 + feeds/p4/libjudy/src/src/Makefile.am | 3 + feeds/p4/libjudy/src/src/README | 20 + feeds/p4/libjudy/src/src/apps/README | 21 + feeds/p4/libjudy/src/src/apps/demo/JudySort.c | 34 + .../src/src/apps/demo/Makefile_deliver | 52 + feeds/p4/libjudy/src/src/apps/demo/README | 24 + .../libjudy/src/src/apps/demo/README_deliver | 17 + feeds/p4/libjudy/src/src/apps/demo/funhist.c | 243 + feeds/p4/libjudy/src/src/apps/demo/interL.c | 31 + feeds/p4/libjudy/src/src/apps/demo/interSL.c | 135 + feeds/p4/libjudy/src/src/apps/demo/run_demo | 64 + feeds/p4/libjudy/src/src/build.bat | 185 + feeds/p4/libjudy/src/src/obj/Makefile.am | 15 + feeds/p4/libjudy/src/src/sh_build | 206 + .../test/Centrino_1.3Mhz_Plots/Hash_CO.plot | 565 + .../test/Centrino_1.3Mhz_Plots/JLHash_CO.plot | 560 + .../test/Centrino_1.3Mhz_Plots/JudyHS_CO.plot | 563 + .../test/Centrino_1.3Mhz_Plots/JudySL_CO.plot | 567 + feeds/p4/libjudy/src/test/CheckDupLines.c | 44 + feeds/p4/libjudy/src/test/Checkit | 104 + feeds/p4/libjudy/src/test/Judy1LCheck.c | 908 + feeds/p4/libjudy/src/test/Judy1LHCheck.c | 1018 + feeds/p4/libjudy/src/test/Judy1LHTime.c | 2235 + feeds/p4/libjudy/src/test/Judy1LTime.c | 1620 + feeds/p4/libjudy/src/test/JudyString.c | 106 + feeds/p4/libjudy/src/test/Makefile.am | 8 + feeds/p4/libjudy/src/test/README | 22 + feeds/p4/libjudy/src/test/SLcompare.c | 1079 + feeds/p4/libjudy/src/test/StringCompare.c | 2551 + feeds/p4/libjudy/src/test/jbgraph | 1022 + feeds/p4/libjudy/src/test/malloc-pre2.8a.c | 5387 + feeds/p4/libjudy/src/test/simple.c | 24 + feeds/p4/libjudy/src/test/testjbgraph | 22 + feeds/p4/libjudy/src/test/timeit.c | 311 + feeds/p4/libjudy/src/test/timeit.h | 221 + feeds/p4/libjudy/src/tool/Makefile.am | 8 + feeds/p4/libjudy/src/tool/README | 134 + feeds/p4/libjudy/src/tool/jhton.c | 1920 + feeds/p4/libjudy/src/tool/listJPtype.c | 239 + feeds/p4/p4-bmv2/Makefile | 36 + feeds/p4/thrift/Makefile | 57 + feeds/p4/thrift/autoscan.log | 0 feeds/p4/thrift/configure.scan | 18 + feeds/p4/thrift/patches/100-compile.patch | 34 + feeds/realtek/rtl83xx-poe/Makefile | 29 + feeds/realtek/rtl83xx-poe/files/bin/poe.lua | 316 + .../realtek/rtl83xx-poe/files/etc/config/poe | 10 + .../realtek/rtl83xx-poe/files/etc/init.d/poe | 24 + .../rtl83xx-poe/files/etc/uci-defaults/30-poe | 21 + feeds/ubpf/ubpf/Makefile | 30 + feeds/ubpf/ubpf/src/CMakeLists.txt | 25 + feeds/ubpf/ubpf/src/map.c | 83 + feeds/ubpf/ubpf/src/net.c | 69 + feeds/ubpf/ubpf/src/prog.c | 67 + feeds/ubpf/ubpf/src/stats.c | 172 + feeds/ubpf/ubpf/src/uxdp.c | 79 + feeds/ubpf/ubpf/src/uxdp.h | 50 + feeds/ubpf/ubpf/src/xdp.c | 67 + feeds/ubpf/ubpf/src/xdplist.c | 12 + feeds/ubpf/ubpf/src/xdpload.c | 56 + feeds/ucentral/libwebsockets/Makefile | 103 + feeds/ucentral/luci/luci-mod-simple/Makefile | 15 + .../luci-static/resources/view/setup.js | 458 + .../luci/luci-mod-simple/root/sbin/certupdate | 8 + .../usr/share/luci/menu.d/luci-simple.json | 10 + .../usr/share/rpcd/acl.d/luci-mod-simple.json | 28 + .../luci/luci-theme-ucentral/Makefile | 14 + .../htdocs/luci-static/ucentral/._logo.svg | Bin 0 -> 758 bytes .../htdocs/luci-static/ucentral/cascade.css | 1919 + .../htdocs/luci-static/ucentral/favicon.png | Bin 0 -> 970 bytes .../htdocs/luci-static/ucentral/logo.png | Bin 0 -> 1069 bytes .../htdocs/luci-static/ucentral/logo.svg | 87 + .../htdocs/luci-static/ucentral/spinner.svg | 12 + .../luasrc/view/themes/ucentral/footer.htm | 16 + .../luasrc/view/themes/ucentral/header.htm | 235 + .../etc/uci-defaults/30_luci-theme-ucentral | 11 + feeds/ucentral/luci/luci.mk | 294 + feeds/ucentral/poco/Makefile | 110 + .../ucentral/poco/patches/100-configure.patch | 15 + .../ucentral/poco/patches/200-strerror.patch | 11 + feeds/ucentral/rtty/Makefile | 71 + feeds/ucentral/rtty/files/rtty.config | 14 + feeds/ucentral/rtty/files/rtty.init | 65 + feeds/ucentral/rtty/patches/100-oneshot.patch | 65 + feeds/ucentral/ucentral-client/Makefile | 37 + .../ucentral-client/files/etc/config/ucentral | 5 + .../ucentral-client/files/etc/config/ustats | 10 + .../ucentral-client/files/etc/init.d/ucentral | 33 + .../ucentral-client/files/etc/init.d/ustats | 23 + .../files/etc/ucentral/ucentral.failsafe | 60 + .../files/etc/uci-defaults/zzz-ucentral | 25 + .../usr/libexec/ucentral/ucentral_apply.sh | 39 + .../usr/libexec/ucentral/ucentral_cmd.sh | 18 + .../usr/libexec/ucentral/ucentral_factory.sh | 4 + .../usr/libexec/ucentral/ucentral_failsafe.sh | 3 + .../libexec/ucentral/ucentral_led_blink.sh | 7 + .../usr/libexec/ucentral/ucentral_state.sh | 3 + .../libexec/ucentral/ucentral_sysupgrade.sh | 4 + .../usr/libexec/ucentral/ucentral_verify.sh | 21 + feeds/ucentral/ucentral-client/git-src | 1 + feeds/ucentral/ucentral-defaults/Makefile | 34 + .../files/etc/uci-defaults/99-ucentral-lldp | 13 + .../files/etc/uci-defaults/99-ucentral-rtty | 7 + feeds/ucentral/ucentral-jsonschema/Makefile | 29 + feeds/ucentral/ucentral-mqtt/Makefile | 32 + .../ucentral-mqtt/files/ucentral-mqtt | 39 + .../ucentral-mqtt/files/ucentral_stats.sh | 4 + .../ucentral/ucentral-mqtt/files/umqtt.config | 6 + feeds/ucentral/ucentral-schema/Makefile | 34 + feeds/ucentral/ucentral-tools/Makefile | 29 + .../files/etc/hotplug.d/iface/90-ip-collide | 4 + feeds/ucentral/ucentral-wifi/Makefile | 34 + .../ucentral-wifi/files/ucentral-wifi | 13 + feeds/ucentral/ucentral-wifi/git-src | 1 + feeds/ucentral/ucentralgw/Makefile | 43 + .../ucentralgw/files/etc/init.d/ucentralgw | 14 + .../files/etc/ucentral/ucentral.properties | 155 + .../ucentralgw/patches/100-cmake.patch | 22 + feeds/ucentral/ucode/Makefile | 121 + feeds/ucentral/ucode/patches/000-fix.patch | 13 + feeds/ucentral/udevmand/Makefile | 37 + .../udevmand/files/etc/init.d/udevmand | 11 + feeds/ucentral/udevmand/git-src | 1 + feeds/ucentral/usteer/Makefile | 33 + feeds/ucentral/usteer/files/etc/config/usteer | 4 + feeds/ucentral/usteer/files/etc/init.d/usteer | 120 + feeds/wifi-ax/ath11k-firmware/Makefile | 71 + .../ath11k-firmware/files/IPQ6018/Notice.txt | 795 + .../ath11k-firmware/files/IPQ6018/m3_fw.b00 | Bin 0 -> 148 bytes .../ath11k-firmware/files/IPQ6018/m3_fw.b01 | Bin 0 -> 6712 bytes .../ath11k-firmware/files/IPQ6018/m3_fw.b02 | Bin 0 -> 294912 bytes .../ath11k-firmware/files/IPQ6018/m3_fw.flist | 3 + .../ath11k-firmware/files/IPQ6018/m3_fw.mdt | Bin 0 -> 6860 bytes .../ath11k-firmware/files/IPQ6018/q6_fw.b00 | Bin 0 -> 340 bytes .../ath11k-firmware/files/IPQ6018/q6_fw.b01 | Bin 0 -> 7000 bytes .../ath11k-firmware/files/IPQ6018/q6_fw.b02 | Bin 0 -> 4696 bytes .../ath11k-firmware/files/IPQ6018/q6_fw.b03 | Bin 0 -> 2514704 bytes .../ath11k-firmware/files/IPQ6018/q6_fw.b04 | Bin 0 -> 459904 bytes .../ath11k-firmware/files/IPQ6018/q6_fw.b05 | Bin 0 -> 197028 bytes .../ath11k-firmware/files/IPQ6018/q6_fw.b07 | Bin 0 -> 9320 bytes .../ath11k-firmware/files/IPQ6018/q6_fw.b08 | Bin 0 -> 425572 bytes .../ath11k-firmware/files/IPQ6018/q6_fw.flist | 8 + .../ath11k-firmware/files/IPQ6018/q6_fw.mdt | Bin 0 -> 7340 bytes .../ath11k-firmware/files/IPQ8074/Notice.txt | 795 + .../ath11k-firmware/files/IPQ8074/m3_fw.b00 | Bin 0 -> 148 bytes .../ath11k-firmware/files/IPQ8074/m3_fw.b01 | Bin 0 -> 136 bytes .../ath11k-firmware/files/IPQ8074/m3_fw.b02 | Bin 0 -> 327680 bytes .../ath11k-firmware/files/IPQ8074/m3_fw.flist | 3 + .../ath11k-firmware/files/IPQ8074/m3_fw.mdt | Bin 0 -> 284 bytes .../ath11k-firmware/files/IPQ8074/q6_fw.b00 | Bin 0 -> 340 bytes .../ath11k-firmware/files/IPQ8074/q6_fw.b01 | Bin 0 -> 328 bytes .../ath11k-firmware/files/IPQ8074/q6_fw.b02 | Bin 0 -> 4696 bytes .../ath11k-firmware/files/IPQ8074/q6_fw.b03 | Bin 0 -> 2885200 bytes .../ath11k-firmware/files/IPQ8074/q6_fw.b04 | Bin 0 -> 1058176 bytes .../ath11k-firmware/files/IPQ8074/q6_fw.b05 | Bin 0 -> 242372 bytes .../ath11k-firmware/files/IPQ8074/q6_fw.b07 | Bin 0 -> 9680 bytes .../ath11k-firmware/files/IPQ8074/q6_fw.b08 | Bin 0 -> 455666 bytes .../ath11k-firmware/files/IPQ8074/q6_fw.flist | 8 + .../ath11k-firmware/files/IPQ8074/q6_fw.mdt | Bin 0 -> 668 bytes .../ath11k-firmware/files/QCN9000/Notice.txt | 786 + .../ath11k-firmware/files/QCN9000/amss.bin | Bin 0 -> 6516864 bytes .../ath11k-firmware/files/QCN9000/board-2.bin | Bin 0 -> 786836 bytes .../ath11k-firmware/files/QCN9000/m3.bin | Bin 0 -> 340422 bytes feeds/wifi-ax/ath11k-wifi/Makefile | 120 + feeds/wifi-ax/ath11k-wifi/bdwlan_EX227.bin | Bin 0 -> 131072 bytes feeds/wifi-ax/ath11k-wifi/bdwlan_EX447.bin | Bin 0 -> 131072 bytes feeds/wifi-ax/ath11k-wifi/board-2.bin.IPQ6018 | Bin 0 -> 787208 bytes feeds/wifi-ax/ath11k-wifi/board-2.bin.IPQ8074 | Bin 0 -> 1311380 bytes .../ath11k-wifi/board-cig-wf188.bin.IPQ6018 | Bin 0 -> 65536 bytes .../ath11k-wifi/board-cig-wf188n.bin.IPQ6018 | Bin 0 -> 65536 bytes .../ath11k-wifi/board-cig-wf194c.bin.IPQ8074 | Bin 0 -> 131072 bytes .../board-edgecore-eap101.bin.IPQ6018 | Bin 0 -> 65536 bytes .../board-edgecore-eap102.bin.IPQ8074 | Bin 0 -> 131072 bytes .../board-sercomm-wallaby.bin.IPQ8074 | Bin 0 -> 131072 bytes .../board-tplink-ex227.bin.IPQ8074 | Bin 0 -> 131072 bytes .../board-tplink-ex447.bin.IPQ8074 | Bin 0 -> 131072 bytes feeds/wifi-ax/batman-adv/Config.in | 111 + feeds/wifi-ax/batman-adv/Makefile | 101 + .../etc/uci-defaults/99-migrate-batadv_hardif | 97 + .../files/lib/netifd/proto/batadv.sh | 123 + .../files/lib/netifd/proto/batadv_hardif.sh | 49 + .../files/lib/netifd/proto/batadv_vlan.sh | 25 + ...adv-Fix-duplicated-OGMs-on-NETDEV_UP.patch | 77 + ...etlink-dumping-of-all-mcast_flags-bu.patch | 29 + ...ninit-value-in-batadv_netlink_get_if.patch | 58 + ...read-OGM-tvlv_len-after-buffer-len-c.patch | 74 + ...read-OGM2-tvlv_len-after-buffer-len-.patch | 62 + ...-free-alloc-race-when-handling-OGM2-.patch | 119 + ...-free-alloc-race-when-handling-OGM-b.patch | 136 + ...-adv-Introduce-own-OGM2-buffer-mutex.patch | 138 + ...-OGM-workqueue-synchronous-cancel-de.patch | 263 + ...AT-candidate-selection-on-little-end.patch | 43 + ...-schedule-OGM-for-disabled-interface.patch | 37 + ...n-adv-fix-batadv_nc_random_weight_tq.patch | 59 + ...efcnt-leak-in-batadv_show_throughput.patch | 38 + ...efcnt-leak-in-batadv_store_throughpu.patch | 39 + ...-refcnt-leak-in-batadv_v_ogm_process.patch | 39 + ...t-disable-ethtool-link-speed-detecti.patch | 76 + ...-uninitialized-chaddr-when-handling-.patch | 42 + ...Fix-own-OGM-check-in-aggregated-OGMs.patch | 59 + ...se-netif_rx_ni-when-not-in-interrupt.patch | 31 + feeds/wifi-ax/batman-adv/src/compat-hacks.h | 278 + feeds/wifi-ax/hostapd/Config.in | 88 + feeds/wifi-ax/hostapd/Makefile | 642 + .../hostapd/files/hostapd-basic.config | 401 + .../wifi-ax/hostapd/files/hostapd-full.config | 401 + .../wifi-ax/hostapd/files/hostapd-mini.config | 401 + feeds/wifi-ax/hostapd/files/hostapd.sh | 1424 + feeds/wifi-ax/hostapd/files/multicall.c | 28 + .../hostapd/files/wpa_supplicant-basic.config | 625 + .../hostapd/files/wpa_supplicant-full.config | 625 + .../hostapd/files/wpa_supplicant-mini.config | 625 + .../hostapd/files/wpa_supplicant-p2p.config | 625 + feeds/wifi-ax/hostapd/files/wpad.init | 25 + feeds/wifi-ax/hostapd/files/wps-hotplug.sh | 62 + ...ompletion-callback-to-complete-mesh-.patch | 124 + ...-frequency-as-pri-sec-channel-switch.patch | 26 + ...rnel-driver-DFS-handler-in-userspace.patch | 48 + ...annel-attributes-before-running-Mesh.patch | 47 + ...hannels-to-be-selected-if-dfs-is-ena.patch | 78 + ...-do-not-allow-pri-sec-channel-switch.patch | 29 + ...sh-do-not-use-offchan-mgmt-tx-on-DFS.patch | 52 + ...-fix-channel-switch-error-during-CAC.patch | 61 + ...18-mesh-make-forwarding-configurable.patch | 219 + .../hostapd/patches/100-daemonize_fix.patch | 97 + .../hostapd/patches/200-multicall.patch | 355 + .../wifi-ax/hostapd/patches/300-noscan.patch | 58 + .../hostapd/patches/301-mesh-noscan.patch | 68 + .../patches/310-rescan_immediately.patch | 11 + .../hostapd/patches/320-optional_rfkill.patch | 61 + .../patches/330-nl80211_fix_set_freq.patch | 11 + .../patches/340-reload_freq_change.patch | 75 + .../341-mesh-ctrl-iface-channel-switch.patch | 39 + .../patches/350-nl80211_del_beacon_bss.patch | 56 + .../patches/360-ctrl_iface_reload.patch | 106 + .../hostapd/patches/370-ap_sta_support.patch | 403 + .../patches/380-disable_ctrl_iface_mib.patch | 193 + .../381-hostapd_cli_UNKNOWN-COMMAND.patch | 11 + .../patches/390-wpa_ie_cap_workaround.patch | 56 + .../400-wps_single_auth_enc_type.patch | 23 + .../patches/410-limit_debug_messages.patch | 210 + .../patches/420-indicate-features.patch | 62 + .../patches/430-hostapd_cli_ifdef.patch | 56 + .../hostapd/patches/431-wpa_cli_ifdef.patch | 18 + .../hostapd/patches/432-missing-typedef.patch | 10 + .../hostapd/patches/450-scan_wait.patch | 73 + ...dd-new-config-params-to-be-used-with.patch | 189 + ...-use-new-parameters-during-ibss-join.patch | 59 + .../patches/463-add-mcast_rate-to-11s.patch | 68 + .../patches/464-fix-mesh-obss-check.patch | 19 + .../patches/470-survey_data_fallback.patch | 45 + .../patches/500-lto-jobserver-support.patch | 50 + .../599-wpa_supplicant-fix-warnings.patch | 19 + .../hostapd/patches/600-ubus_support.patch | 426 + .../hostapd/patches/700-wifi-reload.patch | 219 + ...ate-if-no-available-channel-is-found.patch | 37 + ..._request-ignore-when-rssi-is-too-low.patch | 68 + ...0-client-disconnect-when-rssi-is-low.patch | 242 + .../900-hapd-netlink-ubus-bridge.patch | 881 + .../hostapd/patches/900-max-sta-limit.patch | 100 + ...-test-RADAR-detection-probablity-in-.patch | 153 + ...-108-supplicant-tdls-peer-inactivity.patch | 402 + ...n-issue-related-with-wpa_group_state.patch | 18 + ...b00-004-hostap-fix-compilation-issue.patch | 120 + .../b00-014-hostapd-add-ht40-allow-map.patch | 130 + ...stapd-disable-MAC-ACL-if-WPS-enabled.patch | 18 + ...on-t-initate-TDLS-connection-if-stat.patch | 28 + ...rate-information-into-STATUS-and-STA.patch | 224 + .../b00-036-hostapd-disable-40mhz-scan.patch | 41 + .../c00-002-hostapd-he-update-nl-header.patch | 49 + ...E-fix-ieee80211_he_capabilities-size.patch | 50 + .../patches/c00-004-add-HE-cross-check.patch | 107 + ...force-VHT-channel-definition-with-HE.patch | 33 + ...-active-sta-using-TX-duration-in-ATF.patch | 26 + ...00-010-hostapd-fix-enabling-he-in-5G.patch | 11 + .../c00-011-hostapd-add-mbo-support.patch | 267 + ...ading-to-20MHz-based-on-OBSS-results.patch | 29 + ...01-add-HE-support-to-chan-switch-cmd.patch | 182 + ...-wpa-supplicant-override-HE-toVHT-2G.patch | 116 + ...dd-param-to-enable-disable-ul-mumimo.patch | 79 + ...005-hostapd-fix-btm-cand-pref-update.patch | 105 + ...6-hostapd-fix-sending-proper-vlan-id.patch | 11 + .../patches/d00-007-fixing-warning.patch | 83 + ...ix-enable-40-80mhz-bandwidth-in-6Ghz.patch | 235 + ...d00-009-hostapd-update-muedca-params.patch | 233 + ...Unsolicited-Bcast-Probe-Resp-Support.patch | 724 + ...1-multiple_bssid-add-the-config-file.patch | 726 + ...support-for-reduced-neighbour-report.patch | 66 + ...support-for-reduced-neighbour-report.patch | 113 + ...support-for-reduced-neighbour-report.patch | 47 + ...support-for-reduced-neighbour-report.patch | 200 + ...-cap-to-kernel-and-fix-6ghz-op-class.patch | 72 + ...-TX-power-envelope-IE-incase-of-6GHz.patch | 62 + .../e00-003-6G-security-constraints.patch | 314 + .../e00-003-hostapd-chan-switch-6ghz.patch | 44 + ...esh-support-6ghz-support-in-11s-mesh.patch | 237 + ...le-160MHz-support-for-6G-in-11s-mesh.patch | 57 + ...iple_bssid-set-extended-capabilities.patch | 152 + ...-Remove-unnecessary-nl80211-messages.patch | 86 + ...P-Extend-Spatial-Reuse-Parameter-Set.patch | 276 + ...on-element-in-multiple-BSSID-element.patch | 106 + ...e00-007-add-EMA-configuration-option.patch | 167 + ...ation-ID-with-multiple-BSSID-element.patch | 38 + .../e00-008-multiple_bssid-DTIM-setting.patch | 271 + ...9-fix-reduced-neighbor-report-length.patch | 58 + ...en-SSID-support-in-multiple-BSSID-IE.patch | 262 + ...-011-6ghz-out-of-band-advertisements.patch | 659 + ...-collision-events-and-triggering-CCA.patch | 278 + ...g-hostapd_disassoc_accept_mac-in-CLI.patch | 46 + ...code-required-to-generate-the-CCA-IE.patch | 104 + ...-code-to-generic-to-be-used-for-mesh.patch | 620 + ...03-Extend-acl-config-support-to-mesh.patch | 232 + ...oloring-disable-BSS-color-during-CCA.patch | 26 + ..._color-handler-to-the-nl80211-driver.patch | 157 + ...CL-management-over-control-interface.patch | 310 + ...nd-CCA-events-coming-from-the-kernel.patch | 228 + ...-allow-using-a-random-starting-color.patch | 48 + ...add-intelligence-color-choose-in-CCA.patch | 126 + ..._support_to_change_bss_color_by_user.patch | 185 + ...ountdown-zero-in-color-change-beacon.patch | 96 + ...loring-check-free-color-periodically.patch | 77 + feeds/wifi-ax/hostapd/src/src/ap/ubus.c | 1292 + feeds/wifi-ax/hostapd/src/src/ap/ubus.h | 103 + .../hostapd/src/src/utils/build_features.h | 53 + .../wifi-ax/hostapd/src/wpa_supplicant/ubus.c | 426 + .../wifi-ax/hostapd/src/wpa_supplicant/ubus.h | 66 + feeds/wifi-ax/iw/Makefile | 72 + .../iw/patches/001-nl80211_h_sync.patch | 21 + .../wifi-ax/iw/patches/120-antenna_gain.patch | 36 + .../wifi-ax/iw/patches/200-reduce_size.patch | 454 + ...ttribure-support-for-nl80211-message.patch | 40 + ...command-for-tid-specific-retry-count.patch | 200 + ...r-command-for-tid-specific-aggr-conf.patch | 114 + .../507-Add-peer-address-in-noack-map-command | 54 + ...iw-add-airtime-weight-config-support.patch | 107 + .../patches/510-iw-wifi-config-vendor.patch | 71 + .../512-iw-add-wide-band-scan-support.patch | 138 + .../513-iw-add-HE-rate-gi-ltf-support.patch | 398 + ...o-chan-mappings-for-6GHz-band-per-IE.patch | 61 + ...enable-80M-support-for-6GHz-11s-mesh.patch | 48 + ...nal-argument-to-specify-6Ghz-channel.patch | 109 + ...-HE-rate-configuration-in-6-GHz-band.patch | 125 + ...9-iw-Add-HE-UL-MU-fixed-rate-setting.patch | 165 + feeds/wifi-ax/mac80211/Makefile | 272 + feeds/wifi-ax/mac80211/ath.mk | 337 + .../mac80211/files/lib/netifd/mac80211.sh | 36 + .../files/lib/netifd/wireless/mac80211.sh | 1270 + .../wifi-ax/mac80211/files/lib/performance.sh | 27 + .../files/lib/smp_affinity_settings.sh | 73 + .../mac80211/files/lib/wifi/mac80211.sh | 124 + feeds/wifi-ax/mac80211/files/mac80211.hotplug | 5 + .../patches/pending/200-6ghz-fix.patch | 13 + .../patches/pending/201-log-spam.patch | 26 + .../mac80211/patches/pending/202-dfs.patch | 13 + .../patches/pending/203-ath11k-mac.patch | 72 + .../patches/pending/210-memory-optimize.patch | 26 + .../patches/pending/211-coldboot.patch | 13 + .../mac80211/patches/qca/001-fix_build.patch | 160 + .../qca/002-disable_addr_notifier.patch | 67 + .../patches/qca/003-ath_move_debug_code.patch | 31 + .../patches/qca/004-ath_regd_optional.patch | 68 + .../qca/005-ath9k_compilation_fix.patch | 22 + .../qca/006-backport_skb_put_fix.patch | 73 + .../qca/007-fix_compilation_issue.patch | 214 + .../008-Enabling_vht_capability_for_2G.patch | 76 + .../qca/009-ath11k-Enable-VHT-for-2G.patch | 35 + ...0-mac80211-disable-signed-regulatory.patch | 11 + ...12-ath11k-add-pktlog-debugfs-support.patch | 768 + .../qca/015-add-raw-mode-support.patch | 324 + ...017-ath11k-factory-test-mode-support.patch | 582 + ...h11k-fix-invalid-msdu-len-print-info.patch | 88 + .../qca/020-ath11k-add-btcoex-config.patch | 612 + ...ath11k-cold-boot-calibration-support.patch | 201 + .../qca/022-ath11k-add-ap-ps-support.patch | 324 + ...dd-vdev-delete-synchro-with-firmware.patch | 333 + ...dd-peer-delete-synchro-with-firmware.patch | 273 + ...ist-monitor-mode-can-t-capture-data-.patch | 487 + .../qca/031-ath11k-print-stats-on-crash.patch | 140 + ...th11k-fix-for-peer-memory-corruption.patch | 104 + .../qca/034-ath11k-fix-len-warnings.patch | 32 + ...appropriate-board-data-from-board-id.patch | 48 + ...6-nl80211-add-wide-band-scan-support.patch | 204 + ...37-ath11k-add-wide-band-scan-support.patch | 347 + .../038-ath11k-Adding-support-for-QDSS.patch | 528 + ...add-HE-TX-rate-reporting-to-radiotap.patch | 56 + ...1k-add-new-api-to-get-ar-from-arvifs.patch | 229 + ...11k-use-regular-tx-path-for-raw-mode.patch | 27 + .../047-ath11k-set-eapol-minrate-conf.patch | 22 + .../qca/056-ath11k-mac80211-twt-support.patch | 642 + .../patches/qca/058-enable-ipq6018.patch | 1185 + ...k-add-he-fields-into-radiotap-header.patch | 1152 + ...addba-req-during-invalid-ext-element.patch | 11 + ...211-fix-low-tput-for-mesh-forwarding.patch | 123 + .../065-ath11k-add-HE-fix-rate-support.patch | 927 + ...-ath11k-add-support-spectral-ipq6018.patch | 87 + .../068-ath11k-add-rx-histogram-stats.patch | 638 + ...69-ath11k-add-HE-stats-in-peer-stats.patch | 828 + ...ostapd-config-to-enable-disable-he-m.patch | 379 + ...8-mac80211-ethernet-rx-decap-support.patch | 293 + ...080-ath11k-ethernet-rx-decap-offload.patch | 513 + ...dma-counter-always-zero-in-peer-stat.patch | 81 + ...ted-capabilities-and-mcs-rates-in-he.patch | 65 + ...or-channel-rx-tx-time-in-survey-dump.patch | 54 + ...dma-counter-increamenting-improperly.patch | 51 + .../qca/088-ath11k-add-htt-stats.patch | 636 + .../qca/090-ath11k-fix-fixrate-issue.patch | 195 + ...-stats-remove-fixed-size-array-usage.patch | 4111 + ...irmware-crash-due-to-invalid-vdev-id.patch | 139 + .../qca/103-ath11k-add-he-ampdu-factor.patch | 41 + ...validation-for-tx-stats-and-rx-stats.patch | 28 + ...nitor-crash-if-tx-offload-is-enabled.patch | 67 + ...rx_packet-counter-in-offload-rx-path.patch | 10 + .../qca/107-ath11k-tid-counter-fix.patch | 32 + ...ul-ofdma-ru-allocation-in-peer-stats.patch | 450 + ...avoid-user-cc-setting-in-active-vdev.patch | 54 + .../qca/110-ath11k-boot-without-caldata.patch | 15 + ...fix-setting-range-of-mcs-rates-in-he.patch | 80 + ...12-ath11k-add-btcoex-debugfs-support.patch | 394 + .../112-ath11k-fix-parsing-pktlog-lite.patch | 155 + .../113-ath11k-add-8023-undecap-support.patch | 55 + ...116-ath11k-clean-up-monitor-vdev-del.patch | 512 + .../qca/117-ath11k-fixed-gi-ltf-support.patch | 253 + .../qca/118-ath11k-reset-bcc-counter.patch | 46 + ...1k-enable-ppdu-stats-in-coexist-mode.patch | 217 + ...11k-fill-vdev-pdev-id-for-fwtest-cmd.patch | 49 + ...9-ath11k-add-debugfs-to-set-ratemask.patch | 168 + ...ding-console-with-ath11k_warn-prints.patch | 27 + ...-adding-support-for-mgmt-frame-stats.patch | 276 + ...11k-disabling-credit-flow-for-ath11k.patch | 404 + ...th11k-fix-htt-stats-10-rx-rssi-chain.patch | 44 + ...e-TKIP-when-using-encapsulation-offloading | 40 + .../qca/147-fix-signal-station-dump.patch | 45 + ...ify-4addr-capability-event-to-driver.patch | 180 + ...1k-fix-4addr-tx-failure-AP-STA-modes.patch | 147 + .../qca/164-ath11k-add-qcn9000-support.patch | 609 + ...se-static-window-for-register-access.patch | 178 + .../173-ath11k-add-qcn9000-hal-support.patch | 745 + ...174-ath11k-add-qcn9000-dp-rx-support.patch | 2048 + ...ath11k-fix-ce-interrupts-for-qcn9000.patch | 240 + ...1k-fix-wmi-init-cmd-for-single-radio.patch | 30 + .../179-ath11k-abstract-ext-interrupts.patch | 175 + ...11k-remove-error-on-soc-debugfs-fail.patch | 198 + .../patches/qca/184-ath11k-pci-reload.patch | 30 + ...ath11k-cleanup-bdf-download-sequence.patch | 510 + .../188-ath11k-m3-ssr-dump-collection.patch | 643 + ...89-ath11k-add-new-dfs-region-name-JP.patch | 20 + ...h11k-add-support-for-device-recovery.patch | 189 + ...91-ath11k-add-mgmt-and-data-ack-rssi.patch | 127 + ...h11k-update-ulmumimo-ofdma-htt-stats.patch | 205 + ...x-rx-bytes-value-not-updated-on-mesh.patch | 111 + .../192-ath11k-support-for-2g-phyb-mode.patch | 444 + ...-ath11k-add-htt-stats-30-ext-rx-rate.patch | 165 + ...93-ath11k-war-pdevid-for-phyb2g-mode.patch | 90 + ...se-dev_coredumpm-API-to-collect-rddm.patch | 486 + ...add-coldboot-calibration-for-qcn9000.patch | 228 + .../196-ath11k-Fix-pci-get-msi-address.patch | 57 + ...-ath11k-add-qdss-support-for-qcn9000.patch | 767 + ...or-accepting-bcast-presp-in-GHz-scan.patch | 303 + .../qca/196-ath11k-tpc-stats-support.patch | 1434 + ...1k-add-support-to-collect-q6mem-dump.patch | 215 + ...th11k-use-frame-mode-for-encap-decap.patch | 74 + .../199-001-mac80211-add-nss-support.patch | 388 + ...-ath11k_nss-add-nss-driver-interface.patch | 2715 + .../qca/199-003-ath11k-add-nss-support.patch | 908 + ...-ath11k-Fix-thermal-temperature-read.patch | 92 + ...t-callback-when-hwencap-enable-in-st.patch | 35 + ...dd-support-spectral-scan-for-QCN9000.patch | 189 + ...h11k-check-valid-fixed-rate-settings.patch | 117 + .../qca/201-ath11k-ipq5018-support.patch | 980 + ...-Fix-radiotap-channel-flags-for-6GHz.patch | 12 + ...03-mac80211-ath11k-fw-dynamic-muedca.patch | 364 + ...valid-he-rates-in-fixed-rate-setting.patch | 93 + ...204-ath11k-support-for-native-160MHz.patch | 322 + .../qca/204-frame-size-warning-fix.patch | 114 + ...Unsolicited-Bcast-Probe-Resp-Support.patch | 1010 + ...211-add-basic-multiple-bssid-support.patch | 1274 + .../205-0011-ath11k-fix-mbssid-crash.patch | 241 + .../patches/qca/205-monitor-crash-fix.patch | 35 + .../qca/205-monitor-ring-stuck-fix.patch | 109 + ...1k-add-6ghz-params-in-peer-assoc-cmd.patch | 216 + ...-ath11k-Add-support-for-dynamic-vlan.patch | 377 + ...th11k-Enable-512MB-profile-in-ath11k.patch | 110 + ...7-ath11k-allow-multiple-single-rates.patch | 269 + ...-ath11k-changes-for-coredump-scripts.patch | 19 + ...07-mac80211-add-nss-redirect-support.patch | 262 + ...ocessor_id-based-ring_selector-logic.patch | 46 + ...et-proper-txpower-maxregpower-values.patch | 85 + .../209-fix-wrong-wmi-config-ipq8074.patch | 39 + ...-caused-by-uninitialized-MBSSID-list.patch | 46 + ...ded-capability-bit-for-Enhanced-Mult.patch | 26 + ...-ath11k-full-mon-support-for-qcn9000.patch | 1132 + ...sa-counter-attributes-countdown-coun.patch | 105 + ...load-changes-to-NSS-driver-interface.patch | 595 + ...-support-on-NSS-offload-for-STA-mode.patch | 940 + ...lve-firmware-crash-on-monitor-delete.patch | 51 + .../qca/211-ath11k-add-obss-pd-support.patch | 655 + ...1k-use-reserved-memory-from-bootargs.patch | 105 + ...e-csa-counters-to-countdown-counters.patch | 501 + ...nl80211-add-support-for-BSS-coloring.patch | 471 + ...ac80211-add-support-for-BSS-coloring.patch | 517 + ...4-ath11k-Enable-WMI-based-FW-Logging.patch | 361 + ...-ath11k-add-support-for-BSS-coloring.patch | 216 + ...14-ath11k-qos-null-frame-tx-over-wmi.patch | 491 + ...h11k-Add-offchannel-scanning-support.patch | 135 + ...h11k-improve-station-wds-performance.patch | 67 + ...restrict-peer-s-HE-capability-to-own.patch | 74 + ...w-crash-caused-by-wrong-peer_nss-con.patch | 54 + ...on-detection-on-non-transmitting-BSS.patch | 27 + .../216-ath11k-send-multicast-in-4addr.patch | 127 + ...on-transmitting-BSS-of-color-changes.patch | 81 + ...rt-to-enable-disable-color-collision.patch | 39 + ...ountdown-zero-in-color-change-beacon.patch | 100 + ...-detection-in-case-of-no-free-colors.patch | 110 + ...21-ath11k-add-more-htt-stats-support.patch | 606 + ...ev_up-params-to-avoid-invalid-values.patch | 31 + .../222-ath11k-add-module-param-for-ftm.patch | 691 + ...mmod-failure-on-qmi-sequence-failure.patch | 222 + ...-disable-TX-STBC-with-single-antenna.patch | 55 + .../mac80211/scripts/import-backports.sh | 109 + ...1-.gitignore-add-the-profiles-folder.patch | 25 + ...olchain-gcc-Remove-support-for-GCC-5.patch | 3699 + ...03-pending-scripts-add-gen_config.py.patch | 210 + patches/0004-scripts-update-feed-script.patch | 131 + ...image.sh-allow-setting-the-rootfs-na.patch | 63 + ...les-set-default-password-to-openwifi.patch | 49 + patches/0007-base-files-update-banner.patch | 34 + ...base-files-add-the-wlan-ap-repo-hash.patch | 84 + ...iles-make-sysupgrade-work-on-qcom-AX.patch | 256 + ...upport-for-v4.4-style-netdev-led-tri.patch | 30 + ...011-busybox-enable-the-watchdog-tool.patch | 29 + ...he-base-uci-section-into-a-named-one.patch | 25 + ...0013-ubox-add-log-priority-filtering.patch | 94 + ...all-tune-lan-wan-into-named-sections.patch | 45 + ...ystem-patches-required-by-the-target.patch | 4817 + ...x-modules-fix-some-v4.4-dependencies.patch | 660 + ...x-add-the-Qualcomm-AX-target-support.patch | 13663 ++ patches/0018-Revert-lldpd-bump-to-1.0.7.patch | 33 + patches/0019-lldp-add-TIP-tweaks.patch | 66 + patches/0020-ramips-make-wifi-work.patch | 25 + ...fix-SFP-support-on-zyxel-gs1900-10hp.patch | 35 + ...-files-add-sysctl-to-reboot-upon-OOM.patch | 22 + ...3-ipq40xx-add-ath10k-ct-fw.cfg-stubs.patch | 137 + profiles/container.yml | 6 + profiles/e8450.yml | 7 + profiles/ea8300.yml | 13 + profiles/eap101.yml | 10 + profiles/eap102.yml | 10 + profiles/edgecore_ecs4100-12ph.yml | 7 + profiles/gs110tpp.yml | 7 + profiles/p4.yml | 12 + profiles/realtek.yml | 8 + profiles/rpi.yml | 11 + profiles/ucentral-ap.yml | 52 + profiles/ucentral-switch.yml | 23 + profiles/webui.yml | 16 + profiles/wf188n.yml | 10 + profiles/wf194c.yml | 13 + profiles/wifi-ax.yml | 5 + profiles/zyxel_gs1900-10hp.yml | 7 + setup.py | 162 + 2024 files changed, 1084952 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 backports/0001-build-build-kernel-image-before-building-modules-pac.patch create mode 100644 backports/0002-kernel-add-linux-5.10-support.patch create mode 100644 backports/0003-generic-ar8216-fix-kernel-5.10-compile-error.patch create mode 100644 backports/0004-generic-ar8216-update-version-switch-for-of_get_phy_.patch create mode 100644 backports/0005-kernel-5.10-fix-busy-wait-loop-in-mediatek-PPE-code.patch create mode 100644 backports/0006-kernel-hack-5.10-make-UDP-tunneling-user-selectable.patch create mode 100644 backports/0007-kernel-5.10-add-missing-partitions-doc-syntax-commit.patch create mode 100644 backports/0008-kernel-5.10-refresh-patches.patch create mode 100644 backports/0009-build-fix-build-with-CONFIG_STRIP_KERNEL_EXPORTS.patch create mode 100644 backports/0010-kernel-update-kernel-5.10-to-5.10.16.patch create mode 100644 backports/0011-mediatek-implement-bad-block-management-table-suppor.patch create mode 100644 backports/0012-mediatek-add-work-in-progress-linux-5.10-support.patch create mode 100644 backports/0013-mediatek-add-support-for-configuring-BMT-table-size-.patch create mode 100644 backports/0014-kernel-add-support-for-enabling-fit-firmware-partiti.patch create mode 100644 backports/0015-mediatek-add-linksys-e8450-support.patch create mode 100644 backports/0016-mediatek-linksys-e8450-fix-wifi-and-lan4.patch create mode 100644 backports/0017-image-add-support-for-building-FIT-image-with-filesy.patch create mode 100644 backports/0018-sysupgrade-nand-allow-limiting-rootfs_data-by-settin.patch create mode 100644 backports/0019-uboot-mediatek-add-support-for-linksys-e8450.patch create mode 100644 backports/0020-uboot-envtools-add-defaults-for-linksys-e8450-ubi.patch create mode 100644 backports/0021-mediatek-linksys-e8450-ubi-add-alternative-UBI-NAND-.patch create mode 100644 backports/0022-realtek-update-to-latest-owrt-HEAD.patch create mode 100755 build.sh create mode 100644 config.yml create mode 100755 dock-run.sh create mode 100644 docker/Dockerfile create mode 100644 feeds/bluetooth/bluetooth-6lowpand/Makefile create mode 100644 feeds/bluetooth/bluetooth-6lowpand/files/bluetooth_6lowpand.conf create mode 100644 feeds/bluetooth/bluetooth-6lowpand/files/bluetooth_6lowpand.init create mode 100644 feeds/bluetooth/bluez-ibeacon/Makefile create mode 100644 feeds/bluetooth/bluez-ibeacon/files/ibeacon create mode 100644 feeds/bluetooth/ubtled/Makefile create mode 100644 feeds/bluetooth/ubtled/files/99-btle create mode 100644 feeds/bluetooth/ubtled/files/btle.config create mode 100644 feeds/bluetooth/ubtled/files/ubtled.init create mode 100755 feeds/ipq807x/aq-fw-download/Makefile create mode 100755 feeds/ipq807x/aq-fw-download/src/Makefile create mode 100755 feeds/ipq807x/aq-fw-download/src/include/AQ_API.h create mode 100755 feeds/ipq807x/aq-fw-download/src/include/AQ_PhyInterface.h create mode 100755 feeds/ipq807x/aq-fw-download/src/include/AQ_PlatformRoutines.h create mode 100755 feeds/ipq807x/aq-fw-download/src/include/AQ_RegMacro.h create mode 100755 feeds/ipq807x/aq-fw-download/src/include/AQ_ReturnCodes.h create mode 100755 feeds/ipq807x/aq-fw-download/src/include/AQ_User.h create mode 100755 feeds/ipq807x/aq-fw-download/src/include/registerMap/APPIA/AQ_APPIA_Global_registers.h create mode 100755 feeds/ipq807x/aq-fw-download/src/include/registerMap/APPIA/AQ_APPIA_Global_registers_Defines.h create mode 100755 feeds/ipq807x/aq-fw-download/src/include/registerMap/APPIA/AQ_APPIA_Global_registers_reversed.h create mode 100755 feeds/ipq807x/aq-fw-download/src/include/registerMap/AQ_RegGroupMaxSizes.h create mode 100755 feeds/ipq807x/aq-fw-download/src/include/registerMap/AQ_RegMaps.h create mode 100755 feeds/ipq807x/aq-fw-download/src/include/registerMap/HHD/AQ_HHD_Global_registers.h create mode 100755 feeds/ipq807x/aq-fw-download/src/include/registerMap/HHD/AQ_HHD_Global_registers_Defines.h create mode 100755 feeds/ipq807x/aq-fw-download/src/include/registerMap/HHD/AQ_HHD_Global_registers_reversed.h create mode 100755 feeds/ipq807x/aq-fw-download/src/mdioBootLoadCLD.c create mode 100755 feeds/ipq807x/aq-fw-download/src/src/AQ_API.c create mode 100755 feeds/ipq807x/aq-fw-download/src/src/AQ_PhyInterface.c create mode 100644 feeds/ipq807x/protobuf-c/Makefile create mode 100644 feeds/ipq807x/protobuf-c/patches/001-t-generated-code2-cxx-generate-packed-data-fix.patch create mode 100644 feeds/ipq807x/protobuf/Makefile create mode 100644 feeds/ipq807x/qca-nss-dp/Makefile create mode 100644 feeds/ipq807x/qca-nss-dp/src/Makefile create mode 100644 feeds/ipq807x/qca-nss-dp/src/exports/nss_dp_api_if.h create mode 100644 feeds/ipq807x/qca-nss-dp/src/hal/arch/ipq50xx/nss_ipq50xx.c create mode 100644 feeds/ipq807x/qca-nss-dp/src/hal/arch/ipq50xx/nss_ipq50xx.h create mode 100644 feeds/ipq807x/qca-nss-dp/src/hal/arch/ipq60xx/nss_ipq60xx.c create mode 100644 feeds/ipq807x/qca-nss-dp/src/hal/arch/ipq60xx/nss_ipq60xx.h create mode 100644 feeds/ipq807x/qca-nss-dp/src/hal/arch/ipq807x/nss_ipq807x.c create mode 100644 feeds/ipq807x/qca-nss-dp/src/hal/arch/ipq807x/nss_ipq807x.h create mode 100644 feeds/ipq807x/qca-nss-dp/src/hal/edma/edma_cfg.c create mode 100644 feeds/ipq807x/qca-nss-dp/src/hal/edma/edma_data_plane.c create mode 100644 feeds/ipq807x/qca-nss-dp/src/hal/edma/edma_data_plane.h create mode 100644 feeds/ipq807x/qca-nss-dp/src/hal/edma/edma_regs.h create mode 100644 feeds/ipq807x/qca-nss-dp/src/hal/edma/edma_tx_rx.c create mode 100644 feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/qcom/qcom_dev.h create mode 100644 feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/qcom/qcom_if.c create mode 100644 feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/qcom/qcom_reg.h create mode 100644 feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/syn/gmac/syn_dev.h create mode 100644 feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/syn/gmac/syn_if.c create mode 100644 feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/syn/gmac/syn_reg.h create mode 100644 feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/syn/xgmac/syn_dev.h create mode 100644 feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/syn/xgmac/syn_if.c create mode 100644 feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/syn/xgmac/syn_reg.h create mode 100644 feeds/ipq807x/qca-nss-dp/src/hal/include/edma.h create mode 100644 feeds/ipq807x/qca-nss-dp/src/hal/include/nss_dp_hal.h create mode 100644 feeds/ipq807x/qca-nss-dp/src/hal/include/nss_dp_hal_if.h create mode 100644 feeds/ipq807x/qca-nss-dp/src/hal/syn_gmac_dp/syn_data_plane.c create mode 100644 feeds/ipq807x/qca-nss-dp/src/hal/syn_gmac_dp/syn_data_plane.h create mode 100644 feeds/ipq807x/qca-nss-dp/src/hal/syn_gmac_dp/syn_dma_desc.h create mode 100644 feeds/ipq807x/qca-nss-dp/src/hal/syn_gmac_dp/syn_dp_cfg.c create mode 100644 feeds/ipq807x/qca-nss-dp/src/hal/syn_gmac_dp/syn_dp_tx_rx.c create mode 100644 feeds/ipq807x/qca-nss-dp/src/include/nss_dp_dev.h create mode 100644 feeds/ipq807x/qca-nss-dp/src/nss_dp_attach.c create mode 100644 feeds/ipq807x/qca-nss-dp/src/nss_dp_ethtools.c create mode 100644 feeds/ipq807x/qca-nss-dp/src/nss_dp_main.c create mode 100644 feeds/ipq807x/qca-nss-dp/src/nss_dp_switchdev.c create mode 100644 feeds/ipq807x/qca-nss-drv/Makefile create mode 100644 feeds/ipq807x/qca-nss-drv/files/qca-nss-drv.conf create mode 100644 feeds/ipq807x/qca-nss-drv/files/qca-nss-drv.debug create mode 100644 feeds/ipq807x/qca-nss-drv/files/qca-nss-drv.hotplug create mode 100644 feeds/ipq807x/qca-nss-drv/files/qca-nss-drv.init create mode 100644 feeds/ipq807x/qca-nss-drv/files/qca-nss-drv.sysctl create mode 100644 feeds/ipq807x/qca-nss-drv/patches/100-compile.patch create mode 100644 feeds/ipq807x/qca-nss-drv/src/Makefile create mode 100644 feeds/ipq807x/qca-nss-drv/src/Makefile.fsm create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_fsm9010.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_ipq40xx.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_ipq50xx.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_ipq50xx_64.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_ipq60xx.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_ipq60xx_64.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_ipq806x.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_ipq807x.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_ipq807x_64.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_api_if.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_bridge.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_c2c_rx.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_c2c_tx.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_capwap.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_clmap.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_cmn.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_crypto.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_crypto_cmn.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_def.h create mode 100755 feeds/ipq807x/qca-nss-drv/src/exports/nss_dma.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_dtls.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_dtls_cmn.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_dynamic_interface.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_edma.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_eth_rx.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_freq.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_gre.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_gre_redir.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_gre_redir_lag.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_gre_redir_mark.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_gre_tunnel.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_if.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_igs.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_ipsec.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_ipsec_cmn.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_ipsecmgr.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_ipv4.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_ipv4_reasm.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_ipv6.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_ipv6_reasm.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_l2tpv2.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_lag.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_lso_rx.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_map_t.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_match.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_mirror.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_n2h.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_oam.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_phy_if.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_pm.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_portid.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_ppe.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_pppoe.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_pptp.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_profiler.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_project.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_pvxlan.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_qrfs.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_qvpn.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_rmnet_rx.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_rps.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_shaper.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_sjack.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_stats_public.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_tls.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_trustsec_tx.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_tstamp.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_tun6rd.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_tunipip6.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_unaligned.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_virt_if.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_vlan.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_vxlan.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_wifi.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_wifi_ext_vdev_if.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_wifi_if.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_wifi_mac_db_if.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_wifi_vdev.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/exports/nss_wifili_if.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_bridge.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_bridge_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_bridge_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_c2c_rx.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_c2c_rx_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_c2c_rx_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_c2c_rx_strings.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_c2c_rx_strings.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_c2c_tx.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_c2c_tx_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_c2c_tx_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_c2c_tx_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_c2c_tx_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_c2c_tx_strings.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_c2c_tx_strings.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_capwap.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_capwap_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_capwap_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_capwap_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_capwap_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_capwap_strings.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_capwap_strings.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_clmap.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_clmap_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_clmap_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_clmap_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_clmap_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_cmn.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_core.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_core.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_coredump.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_crypto.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_crypto_cmn.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_crypto_cmn_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_crypto_cmn_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_crypto_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_crypto_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_data_plane/hal/include/nss_data_plane_hal.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_data_plane/hal/nss_ipq50xx.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_data_plane/hal/nss_ipq60xx.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_data_plane/hal/nss_ipq807x.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_data_plane/include/nss_data_plane.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_data_plane/nss_data_plane.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_data_plane/nss_data_plane_common.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_data_plane/nss_data_plane_gmac.c create mode 100755 feeds/ipq807x/qca-nss-drv/src/nss_dma.c create mode 100755 feeds/ipq807x/qca-nss-drv/src/nss_dma_log.c create mode 100755 feeds/ipq807x/qca-nss-drv/src/nss_dma_log.h create mode 100755 feeds/ipq807x/qca-nss-drv/src/nss_dma_stats.c create mode 100755 feeds/ipq807x/qca-nss-drv/src/nss_dma_stats.h create mode 100755 feeds/ipq807x/qca-nss-drv/src/nss_dma_strings.c create mode 100755 feeds/ipq807x/qca-nss-drv/src/nss_dma_strings.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_drv_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_drv_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_drv_strings.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_drv_strings.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_dscp_map.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_dtls.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_dtls_cmn.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_dtls_cmn_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_dtls_cmn_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_dtls_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_dtls_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_dtls_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_dtls_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_dynamic_interface.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_dynamic_interface_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_dynamic_interface_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_dynamic_interface_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_dynamic_interface_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_edma.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_edma_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_edma_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_edma_strings.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_edma_strings.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_eth_rx.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_eth_rx_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_eth_rx_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_eth_rx_strings.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_eth_rx_strings.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_freq.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_freq_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_freq_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_freq_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_freq_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_gmac_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_gmac_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_gre.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_gre_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_gre_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_gre_redir.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_ds.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_ds_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_ds_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_ds_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_ds_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_us.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_us_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_us_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_us_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_us_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_mark.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_mark_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_mark_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_mark_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_mark_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_gre_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_gre_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_gre_tunnel.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_gre_tunnel_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_gre_tunnel_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_gre_tunnel_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_gre_tunnel_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_hal/fsm9010/nss_hal_pvt.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_hal/include/nss_hal.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_hal/include/nss_hal_ops.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_hal/include/nss_regs.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_hal/ipq50xx/nss_hal_pvt.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_hal/ipq60xx/nss_hal_pvt.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_hal/ipq806x/nss_clocks.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_hal/ipq806x/nss_hal_pvt.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_hal/ipq807x/nss_hal_pvt.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_hal/nss_hal.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_hlos_if.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_if.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_if_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_if_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_igs.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_igs_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_igs_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_init.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ipsec.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ipsec_cmn.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ipsec_cmn_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ipsec_cmn_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ipsec_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ipsec_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ipv4.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ipv4_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ipv4_reasm.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ipv4_reasm_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ipv4_reasm_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ipv4_reasm_strings.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ipv4_reasm_strings.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ipv4_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ipv4_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ipv4_strings.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ipv4_strings.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ipv6.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ipv6_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ipv6_reasm.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ipv6_reasm_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ipv6_reasm_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ipv6_reasm_strings.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ipv6_reasm_strings.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ipv6_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ipv6_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ipv6_strings.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ipv6_strings.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_l2tpv2.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_l2tpv2_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_l2tpv2_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_l2tpv2_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_l2tpv2_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_l2tpv2_strings.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_l2tpv2_strings.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_lag.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_lag_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_lag_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_lso_rx.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_lso_rx_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_lso_rx_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_lso_rx_strings.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_lso_rx_strings.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_map_t.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_map_t_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_map_t_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_map_t_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_map_t_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_map_t_strings.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_map_t_strings.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_match.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_match_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_match_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_match_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_match_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_meminfo.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_meminfo.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_mirror.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_mirror_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_mirror_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_mirror_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_mirror_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_n2h.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_n2h_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_n2h_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_n2h_strings.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_n2h_strings.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_oam.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_oam_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_oam_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_phys_if.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_phys_if.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_pm.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_pm.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_portid.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_portid_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_portid_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_portid_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_portid_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ppe.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ppe.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ppe_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ppe_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ppe_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ppe_vp.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ppe_vp.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ppe_vp_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ppe_vp_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_ppe_vp_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_pppoe.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_pppoe_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_pppoe_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_pppoe_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_pppoe_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_pppoe_strings.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_pppoe_strings.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_pptp.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_pptp_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_pptp_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_pptp_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_pptp_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_pptp_strings.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_pptp_strings.h create mode 100755 feeds/ipq807x/qca-nss-drv/src/nss_profiler.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_project.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_pvxlan.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_pvxlan_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_pvxlan_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_pvxlan_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_pvxlan_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_qrfs.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_qrfs_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_qrfs_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_qrfs_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_qrfs_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_qvpn.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_qvpn_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_qvpn_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_qvpn_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_qvpn_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_rmnet_rx.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_rmnet_rx_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_rmnet_rx_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_rps.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_shaper.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_sjack.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_sjack_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_sjack_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_sjack_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_sjack_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_strings.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_strings.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_tls.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_tls_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_tls_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_trustsec_tx.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_trustsec_tx_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_trustsec_tx_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_trustsec_tx_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_trustsec_tx_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_tstamp.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_tstamp_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_tstamp_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_tun6rd.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_tun6rd_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_tun6rd_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_tunipip6.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_tunipip6_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_tunipip6_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_tunipip6_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_tunipip6_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_tx_msg_sync.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_tx_msg_sync.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_tx_rx_common.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_unaligned.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_unaligned_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_unaligned_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_unaligned_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_unaligned_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_virt_if.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_virt_if_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_virt_if_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_vlan.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_vlan_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_vlan_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_vxlan.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_vxlan_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_vxlan_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_vxlan_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_vxlan_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_wifi.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_wifi_ext_vdev.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_wifi_ext_vdev_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_wifi_ext_vdev_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_wifi_ext_vdev_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_wifi_ext_vdev_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_wifi_if.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_wifi_if_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_wifi_if_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_wifi_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_wifi_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_wifi_mac_db.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_wifi_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_wifi_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_wifi_vdev.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_wifili.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_wifili_log.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_wifili_log.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_wifili_stats.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_wifili_stats.h create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_wifili_strings.c create mode 100644 feeds/ipq807x/qca-nss-drv/src/nss_wifili_strings.h create mode 100644 feeds/ipq807x/qca-nss-fw/Makefile create mode 100644 feeds/ipq807x/qca-nss-fw/files/IPQ6018/Notice.txt create mode 100644 feeds/ipq807x/qca-nss-fw/files/IPQ6018/ReadMe.txt create mode 100755 feeds/ipq807x/qca-nss-fw/files/IPQ6018/qca-nss0.bin create mode 100644 feeds/ipq807x/qca-nss-fw/files/IPQ8074/Notice.txt create mode 100644 feeds/ipq807x/qca-nss-fw/files/IPQ8074/ReadMe.txt create mode 100755 feeds/ipq807x/qca-nss-fw/files/IPQ8074/qca-nss0.bin create mode 100755 feeds/ipq807x/qca-nss-fw/files/IPQ8074/qca-nss1.bin create mode 100755 feeds/ipq807x/qca-ssdk-shell/Makefile create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/Makefile create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/config create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/api/api_access.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/api/api_desc.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/api/sw_api.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/api/sw_ioctl.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/common/aos_head.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/common/shared_func.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/common/sw.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/common/sw_config.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/common/sw_error.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/common/util.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_acl.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_api.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_bm.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_cosmap.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_ctrlpkt.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_fdb.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_flow.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_igmp.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_init.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_interface_ctrl.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_ip.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_leaky.h create mode 100644 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_led.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_mib.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_mirror.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_misc.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_multi.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_nat.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_policer.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_port_ctrl.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_portvlan.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_pppoe.h create mode 100644 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_ptp.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_qm.h create mode 100644 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_qos.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_rate.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_reg_access.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_rss_hash.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_sec.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_servcode.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_sfp.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_shaper.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_stp.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_trunk.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_type.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_uk_if.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_vlan.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_vsi.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/init/ssdk_init.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/init/ssdk_plat.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/ref/ref_api.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/ref/ref_vlan.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/sal/os/aos_lock.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/sal/os/aos_mem.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/sal/os/aos_timer.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/sal/os/aos_types.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/sal/os/linux_user/aos_lock_pvt.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/sal/os/linux_user/aos_mem_pvt.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/sal/os/linux_user/aos_timer_pvt.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/sal/os/linux_user/aos_types_pvt.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/sal/sd/linux/uk_interface/sw_api_us.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/sal/sd/sd.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/shell/shell.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/shell/shell_config.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/shell/shell_io.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/shell/shell_lib.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/include/shell/shell_sw.h create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/make/components.mk create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/make/config.mk create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/make/defs.mk create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/make/linux_opt.mk create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/make/target.mk create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/make/tools.mk create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/api/Makefile create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/api/api_access.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/Makefile create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_acl.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_bm.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_cosmap.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_ctrlpkt.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_fdb.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_flow.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_igmp.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_init.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_interface_ctrl.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_ip.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_leaky.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_led.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_mib.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_mirror.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_misc.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_nat.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_policer.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_port_ctrl.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_portvlan.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_pppoe.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_ptp.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_qm.c create mode 100644 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_qos.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_rate.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_reg_access.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_rss_hash.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_sec.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_servcode.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_sfp.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_shaper.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_stp.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_trunk.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_uk_if.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_vlan.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_vsi.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/ref/Makefile create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/ref/ref_vlan.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/sal/Makefile create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/sal/sd/Makefile create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/sal/sd/linux/Makefile create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/sal/sd/linux/uk_interface/Makefile create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/sal/sd/linux/uk_interface/sw_api_us_ioctl.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/sal/sd/linux/uk_interface/sw_api_us_netlink.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/sal/sd/sd.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/shell/Makefile create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/shell/shell.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/shell/shell_config.c create mode 100644 feeds/ipq807x/qca-ssdk-shell/src/src/shell/shell_io.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/shell/shell_lib.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/shell/shell_module_ctrl.c create mode 100755 feeds/ipq807x/qca-ssdk-shell/src/src/shell/shell_sw.c create mode 100755 feeds/ipq807x/qca-ssdk/Makefile create mode 100755 feeds/ipq807x/qca-ssdk/files/qca-ssdk create mode 100644 feeds/ipq807x/qca-ssdk/patches/100-aq.patch create mode 100644 feeds/ipq807x/qca-ssdk/src/ChangeLog create mode 100755 feeds/ipq807x/qca-ssdk/src/Makefile create mode 100755 feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/host_helper.c create mode 100755 feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/lib/nat_helper_dt.c create mode 100755 feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/lib/nat_helper_dt.h create mode 100755 feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/lib/nat_helper_hsl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/lib/nat_helper_hsl.h create mode 100755 feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/napt_acl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/napt_acl.h create mode 100755 feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/napt_helper.c create mode 100755 feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/napt_helper.h create mode 100755 feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/napt_procfs.c create mode 100755 feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/nat_helper.c create mode 100755 feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/nat_helper.h create mode 100755 feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/nat_ipt_helper.c create mode 100644 feeds/ipq807x/qca-ssdk/src/config create mode 100644 feeds/ipq807x/qca-ssdk/src/include/adpt/adpt.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/adpt/cppe/adpt_cppe_flow.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/adpt/cppe/adpt_cppe_mib.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/adpt/cppe/adpt_cppe_misc.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/adpt/cppe/adpt_cppe_portctrl.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/adpt/cppe/adpt_cppe_qm.h create mode 100644 feeds/ipq807x/qca-ssdk/src/include/adpt/cppe/adpt_cppe_qos.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/adpt/cppe/adpt_cppe_uniphy.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/adpt/hppe/adpt_hppe.h create mode 100644 feeds/ipq807x/qca-ssdk/src/include/adpt/mp/adpt_mp.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/adpt/mp/adpt_mp_portctrl.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/adpt/mp/adpt_mp_uniphy.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/adpt/sfp/adpt_sfp.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/api/api_access.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/api/api_desc.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/api/sw_api.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/api/sw_ioctl.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/common/aos_head.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/common/shared_func.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/common/sw.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/common/sw_config.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/common/sw_error.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/common/util.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_acl.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_api.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_bm.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_cosmap.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_ctrlpkt.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_fdb.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_flow.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_flowcookie.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_igmp.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_init.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_interface_ctrl.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_ip.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_leaky.h create mode 100644 feeds/ipq807x/qca-ssdk/src/include/fal/fal_led.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_mib.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_mirror.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_misc.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_multi.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_nat.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_policer.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_port_ctrl.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_portvlan.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_pppoe.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_ptp.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_qm.h create mode 100644 feeds/ipq807x/qca-ssdk/src/include/fal/fal_qos.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_rate.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_reg_access.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_rfs.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_rss_hash.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_sec.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_servcode.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_sfp.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_shaper.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_stp.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_trunk.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_type.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_uk_if.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_vlan.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/fal/fal_vsi.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_api.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_fdb.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_init.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_mib.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_port_ctrl.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_portvlan.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_reg_access.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_vlan.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/cppe/cppe_loopback.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/cppe/cppe_loopback_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/cppe/cppe_portctrl.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/cppe/cppe_portctrl_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/cppe/cppe_qos.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/cppe/cppe_qos_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_acl.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_api.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_cosmap.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_fdb.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_fdb_prv.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_igmp.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_init.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_interface_ctrl.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_ip.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_leaky.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_led.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_mib.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_mirror.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_misc.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_nat.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_nat_helper.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_port_ctrl.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_portvlan.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_psgmii.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_qos.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_rate.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_reg_access.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_sec.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_stp.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_trunk.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_vlan.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_acl.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_api.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_fdb.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_igmp.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_init.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_leaky.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_led.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_mib.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_mirror.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_misc.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_port_ctrl.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_portvlan.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_qos.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_rate.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_reduced_acl.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_reg_access.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_stp.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_vlan.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_api.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_fdb.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_igmp.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_init.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_leaky.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_led.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_mib.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_mirror.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_misc.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_port_ctrl.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_portvlan.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_qos.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_rate.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_reg_access.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_stp.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_vlan.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_acl.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_acl_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_bm.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_bm_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_ctrlpkt.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_ctrlpkt_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_fdb.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_fdb_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_flow.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_flow_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_global.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_global_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_init.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_ip.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_ip_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_mib.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_mib_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_mirror.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_mirror_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_policer.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_policer_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_portctrl.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_portctrl_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_portvlan.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_portvlan_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_pppoe.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_pppoe_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_qm.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_qm_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_qos.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_qos_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_reg_access.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_rss.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_rss_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_sec.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_sec_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_servcode.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_servcode_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_shaper.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_shaper_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_stp.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_stp_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_trunk.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_trunk_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_uniphy.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_uniphy_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_vsi.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_vsi_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_xgmacmib.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_xgmacmib_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_xgportctrl.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_xgportctrl_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hsl.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hsl_acl.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hsl_api.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hsl_dev.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hsl_lock.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hsl_port_prop.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/hsl_shared_api.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_acl.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_api.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_cosmap.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_fdb.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_igmp.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_init.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_interface_ctrl.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_ip.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_leaky.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_led.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_mib.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_mirror.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_misc.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_nat.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_nat_helper.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_port_ctrl.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_portvlan.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_qos.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_rate.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_reg_access.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_sec.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_stp.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_trunk.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_vlan.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_acl.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_api.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_cosmap.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_fdb.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_fdb_prv.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_igmp.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_init.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_interface_ctrl.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_ip.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_leaky.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_led.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_mib.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_mirror.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_misc.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_nat.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_nat_helper.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_port_ctrl.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_portvlan.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_qos.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_rate.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_reg_access.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_sec.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_stp.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_trunk.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_vlan.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/mp/mp_mib.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/mp/mp_mib_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/mp/mp_portctrl.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/mp/mp_portctrl_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/mp/mp_uniphy.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/mp/mp_uniphy_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/phy/aquantia_phy.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/phy/f1_phy.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/phy/f2_phy.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/phy/hsl_phy.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/phy/malibu_phy.h create mode 100644 feeds/ipq807x/qca-ssdk/src/include/hsl/phy/mpge_led.h create mode 100644 feeds/ipq807x/qca-ssdk/src/include/hsl/phy/mpge_phy.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/phy/qca803x_phy.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/phy/qca808x.h create mode 100644 feeds/ipq807x/qca-ssdk/src/include/hsl/phy/qca808x_led.h create mode 100644 feeds/ipq807x/qca-ssdk/src/include/hsl/phy/qca808x_phy.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/phy/qca808x_ptp.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/phy/qca808x_ptp_api.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/phy/qca808x_ptp_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/phy/sfp_phy.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/scomphy/scomphy_init.h create mode 100644 feeds/ipq807x/qca-ssdk/src/include/hsl/scomphy/scomphy_port_ctrl.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/scomphy/scomphy_reg_access.h create mode 100644 feeds/ipq807x/qca-ssdk/src/include/hsl/sfp/sfp.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/sfp/sfp_access.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/sfp/sfp_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_acl.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_api.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_fdb.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_igmp.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_init.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_leaky.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_led.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_mib.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_mirror.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_misc.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_port_ctrl.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_portvlan.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_qos.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_rate.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_reduced_acl.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_reg.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_reg_access.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_stp.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_vlan.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/init/ssdk_clk.h create mode 100644 feeds/ipq807x/qca-ssdk/src/include/init/ssdk_dts.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/init/ssdk_hppe.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/init/ssdk_init.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/init/ssdk_interrupt.h create mode 100644 feeds/ipq807x/qca-ssdk/src/include/init/ssdk_led.h create mode 100644 feeds/ipq807x/qca-ssdk/src/include/init/ssdk_mp.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/init/ssdk_phy_i2c.h create mode 100644 feeds/ipq807x/qca-ssdk/src/include/init/ssdk_plat.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/init/ssdk_scomphy.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/init/ssdk_uci.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/ref/ref_api.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/ref/ref_fdb.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/ref/ref_mib.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/ref/ref_misc.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/ref/ref_port_ctrl.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/ref/ref_uci.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/ref/ref_vlan.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/ref/ref_vsi.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/sal/os/aos_lock.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/sal/os/aos_mem.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/sal/os/aos_timer.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/sal/os/aos_types.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/sal/os/linux/aos_lock_pvt.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/sal/os/linux/aos_mem_pvt.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/sal/os/linux/aos_timer_pvt.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/sal/os/linux/aos_types_pvt.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/sal/sd/linux/uk_interface/sw_api_ks.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/sal/sd/sd.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/shell_lib/shell.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/shell_lib/shell_config.h create mode 100644 feeds/ipq807x/qca-ssdk/src/include/shell_lib/shell_io.h create mode 100755 feeds/ipq807x/qca-ssdk/src/include/shell_lib/shell_sw.h create mode 100755 feeds/ipq807x/qca-ssdk/src/ko_Makefile create mode 100644 feeds/ipq807x/qca-ssdk/src/make/.build_number create mode 100755 feeds/ipq807x/qca-ssdk/src/make/components.mk create mode 100755 feeds/ipq807x/qca-ssdk/src/make/config.mk create mode 100755 feeds/ipq807x/qca-ssdk/src/make/defs.mk create mode 100755 feeds/ipq807x/qca-ssdk/src/make/linux_opt.mk create mode 100755 feeds/ipq807x/qca-ssdk/src/make/target.mk create mode 100755 feeds/ipq807x/qca-ssdk/src/make/tools.mk create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/Makefile create mode 100644 feeds/ipq807x/qca-ssdk/src/src/adpt/adpt.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/cppe/Makefile create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/cppe/adpt_cppe_flow.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/cppe/adpt_cppe_mib.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/cppe/adpt_cppe_misc.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/cppe/adpt_cppe_portctrl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/cppe/adpt_cppe_qm.c create mode 100644 feeds/ipq807x/qca-ssdk/src/src/adpt/cppe/adpt_cppe_qos.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/cppe/adpt_cppe_uniphy.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/Makefile create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_acl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_bm.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_ctrlpkt.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_fdb.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_flow.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_ip.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_mib.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_mirror.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_misc.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_policer.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_portctrl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_portvlan.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_pppoe.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_ptp.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_qm.c create mode 100644 feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_qos.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_rss_hash.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_sec.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_servcode.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_shaper.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_stp.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_trunk.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_uniphy.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_vsi.c create mode 100644 feeds/ipq807x/qca-ssdk/src/src/adpt/mp/Makefile create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/mp/adpt_mp_interrupt.c create mode 100644 feeds/ipq807x/qca-ssdk/src/src/adpt/mp/adpt_mp_led.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/mp/adpt_mp_mib.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/mp/adpt_mp_portctrl.c create mode 100644 feeds/ipq807x/qca-ssdk/src/src/adpt/mp/adpt_mp_uniphy.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/sfp/Makefile create mode 100755 feeds/ipq807x/qca-ssdk/src/src/adpt/sfp/adpt_sfp.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/api/Makefile create mode 100755 feeds/ipq807x/qca-ssdk/src/src/api/api_access.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/fal/Makefile create mode 100755 feeds/ipq807x/qca-ssdk/src/src/fal/fal_acl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/fal/fal_bm.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/fal/fal_cosmap.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/fal/fal_ctrlpkt.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/fal/fal_fdb.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/fal/fal_flow.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/fal/fal_igmp.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/fal/fal_init.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/fal/fal_interface_ctrl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/fal/fal_ip.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/fal/fal_leaky.c create mode 100644 feeds/ipq807x/qca-ssdk/src/src/fal/fal_led.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/fal/fal_mib.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/fal/fal_mirror.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/fal/fal_misc.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/fal/fal_nat.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/fal/fal_policer.c create mode 100644 feeds/ipq807x/qca-ssdk/src/src/fal/fal_port_ctrl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/fal/fal_portvlan.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/fal/fal_pppoe.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/fal/fal_ptp.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/fal/fal_qm.c create mode 100644 feeds/ipq807x/qca-ssdk/src/src/fal/fal_qos.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/fal/fal_rate.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/fal/fal_reg_access.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/fal/fal_rss_hash.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/fal/fal_sec.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/fal/fal_servcode.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/fal/fal_sfp.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/fal/fal_shaper.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/fal/fal_stp.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/fal/fal_trunk.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/fal/fal_vlan.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/fal/fal_vsi.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/Makefile create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/athena/Makefile create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/athena/athena_fdb.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/athena/athena_init.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/athena/athena_mib.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/athena/athena_port_ctrl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/athena/athena_portvlan.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/athena/athena_reg_access.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/athena/athena_vlan.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/cppe/Makefile create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/cppe/cppe_loopback.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/cppe/cppe_portctrl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/cppe/cppe_qos.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/dess/Makefile create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_acl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_acl_parse.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_acl_prv.h create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_cosmap.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_fdb.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_igmp.c create mode 100644 feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_init.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_interface_ctrl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_ip.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_leaky.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_led.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_mib.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_mirror.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_misc.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_multicast_acl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_nat.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_port_ctrl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_portvlan.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_psgmii.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_qos.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_rate.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_reg_access.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_sec.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_stp.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_trunk.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_vlan.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/Makefile create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_acl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_fdb.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_igmp.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_init.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_leaky.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_led.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_mib.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_mirror.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_misc.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_port_ctrl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_portvlan.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_qos.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_rate.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_reduced_acl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_reg_access.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_stp.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_vlan.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/horus/Makefile create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_fdb.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_igmp.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_init.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_leaky.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_led.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_mib.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_mirror.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_misc.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_port_ctrl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_portvlan.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_qos.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_rate.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_reg_access.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_stp.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_vlan.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/Makefile create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_acl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_bm.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_ctrlpkt.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_fdb.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_flow.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_global.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_init.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_ip.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_mib.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_mirror.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_policer.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_portctrl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_portvlan.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_pppoe.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_qm.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_qos.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_reg_access.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_rss.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_sec.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_servcode.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_shaper.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_stp.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_trunk.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_uniphy.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_vsi.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_xgmacmib.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_xgportctrl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/hsl_acl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/hsl_api.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/hsl_dev.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/hsl_lock.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/hsl_port_prop.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isis/Makefile create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_acl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_acl_parse.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_acl_prv.h create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_cosmap.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_fdb.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_igmp.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_init.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_interface_ctrl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_ip.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_leaky.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_led.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_mac_block.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_mib.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_mirror.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_misc.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_multicast_acl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_nat.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_port_ctrl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_portvlan.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_qos.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_rate.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_reg_access.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_sec.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_stp.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_trunk.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_vlan.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/Makefile create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_acl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_acl_parse.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_acl_prv.h create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_cosmap.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_fdb.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_igmp.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_init.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_interface_ctrl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_ip.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_leaky.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_led.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_mib.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_mirror.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_misc.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_multicast_acl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_nat.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_port_ctrl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_portvlan.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_qos.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_rate.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_reg_access.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_sec.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_stp.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_trunk.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_vlan.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/mp/Makefile create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/mp/mp_mib.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/mp/mp_portctrl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/mp/mp_uniphy.c create mode 100644 feeds/ipq807x/qca-ssdk/src/src/hsl/phy/Makefile create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/phy/aquantia_phy.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/phy/f1_phy.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/phy/f2_phy.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/phy/hsl_phy.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/phy/malibu_phy.c create mode 100644 feeds/ipq807x/qca-ssdk/src/src/hsl/phy/mpge_led.c create mode 100644 feeds/ipq807x/qca-ssdk/src/src/hsl/phy/mpge_phy.c create mode 100644 feeds/ipq807x/qca-ssdk/src/src/hsl/phy/qca803x_phy.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/phy/qca808x.c create mode 100644 feeds/ipq807x/qca-ssdk/src/src/hsl/phy/qca808x_led.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/phy/qca808x_phc.c create mode 100644 feeds/ipq807x/qca-ssdk/src/src/hsl/phy/qca808x_phy.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/phy/qca808x_ptp.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/phy/qca808x_ptp_api.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/phy/sfp_phy.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/scomphy/Makefile create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/scomphy/scomphy_init.c create mode 100644 feeds/ipq807x/qca-ssdk/src/src/hsl/scomphy/scomphy_port_ctrl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/scomphy/scomphy_reg_access.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/sfp/Makefile create mode 100644 feeds/ipq807x/qca-ssdk/src/src/hsl/sfp/sfp.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/sfp/sfp_access.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/Makefile create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_acl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_fdb.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_igmp.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_init.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_leaky.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_led.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_mib.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_mirror.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_misc.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_port_ctrl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_portvlan.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_qos.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_rate.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_reduced_acl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_reg_access.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_stp.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_vlan.c create mode 100644 feeds/ipq807x/qca-ssdk/src/src/init/Makefile create mode 100755 feeds/ipq807x/qca-ssdk/src/src/init/ssdk_clk.c create mode 100644 feeds/ipq807x/qca-ssdk/src/src/init/ssdk_dts.c create mode 100644 feeds/ipq807x/qca-ssdk/src/src/init/ssdk_hppe.c create mode 100644 feeds/ipq807x/qca-ssdk/src/src/init/ssdk_init.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/init/ssdk_interrupt.c create mode 100644 feeds/ipq807x/qca-ssdk/src/src/init/ssdk_led.c create mode 100644 feeds/ipq807x/qca-ssdk/src/src/init/ssdk_mp.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/init/ssdk_phy_i2c.c create mode 100644 feeds/ipq807x/qca-ssdk/src/src/init/ssdk_plat.c create mode 100644 feeds/ipq807x/qca-ssdk/src/src/init/ssdk_scomphy.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/init/ssdk_uci.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/ref/Makefile create mode 100755 feeds/ipq807x/qca-ssdk/src/src/ref/ref_fdb.c create mode 100644 feeds/ipq807x/qca-ssdk/src/src/ref/ref_mib.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/ref/ref_misc.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/ref/ref_port_ctrl.c create mode 100644 feeds/ipq807x/qca-ssdk/src/src/ref/ref_uci.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/ref/ref_vlan.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/ref/ref_vsi.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/sal/Makefile create mode 100755 feeds/ipq807x/qca-ssdk/src/src/sal/sd/Makefile create mode 100755 feeds/ipq807x/qca-ssdk/src/src/sal/sd/linux/Makefile create mode 100755 feeds/ipq807x/qca-ssdk/src/src/sal/sd/linux/uk_interface/Makefile create mode 100755 feeds/ipq807x/qca-ssdk/src/src/sal/sd/linux/uk_interface/sw_api_ks_ioctl.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/sal/sd/linux/uk_interface/sw_api_ks_netlink.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/sal/sd/sd.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/shell_lib/Makefile create mode 100755 feeds/ipq807x/qca-ssdk/src/src/shell_lib/shell.c create mode 100644 feeds/ipq807x/qca-ssdk/src/src/shell_lib/shell_config.c create mode 100644 feeds/ipq807x/qca-ssdk/src/src/shell_lib/shell_io.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/shell_lib/shell_sw.c create mode 100755 feeds/ipq807x/qca-ssdk/src/src/util/Makefile create mode 100755 feeds/ipq807x/qca-ssdk/src/src/util/util.c create mode 100755 feeds/ipq807x/qca-thermald-10.4/Makefile create mode 100755 feeds/ipq807x/qca-thermald-10.4/files/thermal.config create mode 100755 feeds/ipq807x/qca-thermald-10.4/files/thermal.init create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/Android.mk create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/Makefile create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/Makefile.am create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/adc-sensor.c create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/adc-sensor.h create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/bcl-sensor.c create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/bcl-sensor.h create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/configure.ac create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/gen-sensor.c create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/gen-sensor.h create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/ipq-thermald-8064.conf create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/ipq-thermald-8066.conf create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/ipq-thermald-8069.conf create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/modem_mitigation_oncrpc.c create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/modem_mitigation_qmi.c create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/modem_sensor_qmi.c create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/pm8821-sensor.c create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/pm8821-sensor.h create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/qmi-ts-sensor.c create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/qmi-ts-sensor.h create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/readme.txt create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/sensors-7x30.c create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/sensors-8660.c create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/sensors-8960.c create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/sensors-8974.c create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/sensors-8x25.c create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/sensors-hw.h create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/sensors-ipq.c create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/thermal.c create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/thermal.h create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/thermal_actions.c create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/thermal_client.c create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/thermal_client.h create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/thermal_config.c create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/thermal_lib_common.c create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/thermal_lib_common.h create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/thermal_mitigation_device_service_v01.c create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/thermal_mitigation_device_service_v01.h create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/thermal_monitor.c create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/thermal_sensor_service_v01.c create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/thermal_sensor_service_v01.h create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/thermal_server.c create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/thermal_server.h create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/thermal_util.c create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/thermald-7x30.conf create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/thermald-8064.conf create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/thermald-8064ab.conf create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/thermald-8660.conf create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/thermald-8930.conf create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/thermald-8930ab.conf create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/thermald-8960.conf create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/thermald-8960ab.conf create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/thermald-8974.conf create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/thermald-8x25-msm1-pmic_therm.conf create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/thermald-8x25-msm2-msm_therm.conf create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/thermald-8x25-msm2-pmic_therm.conf create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/thermald.conf_sample create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/tsens-sensor.c create mode 100755 feeds/ipq807x/qca-thermald-10.4/src/tsens-sensor.h create mode 100644 feeds/p4/libjudy/Makefile create mode 100644 feeds/p4/libjudy/src/AUTHORS create mode 100644 feeds/p4/libjudy/src/COPYING create mode 100644 feeds/p4/libjudy/src/ChangeLog create mode 100644 feeds/p4/libjudy/src/INSTALL create mode 100644 feeds/p4/libjudy/src/Makefile.am create mode 100644 feeds/p4/libjudy/src/README create mode 100755 feeds/p4/libjudy/src/bootstrap create mode 100644 feeds/p4/libjudy/src/configure.ac create mode 100644 feeds/p4/libjudy/src/doc/Makefile.am create mode 100644 feeds/p4/libjudy/src/doc/ext/COPYRIGHT create mode 100644 feeds/p4/libjudy/src/doc/ext/Judy1_3.htm create mode 100644 feeds/p4/libjudy/src/doc/ext/Judy1_funcs_3.htm create mode 100644 feeds/p4/libjudy/src/doc/ext/JudyHS_3.htm create mode 100644 feeds/p4/libjudy/src/doc/ext/JudyHS_funcs_3.htm create mode 100644 feeds/p4/libjudy/src/doc/ext/JudyL_3.htm create mode 100644 feeds/p4/libjudy/src/doc/ext/JudyL_funcs_3.htm create mode 100644 feeds/p4/libjudy/src/doc/ext/JudySL_3.htm create mode 100644 feeds/p4/libjudy/src/doc/ext/JudySL_funcs_3.htm create mode 100644 feeds/p4/libjudy/src/doc/ext/Judy_3.htm create mode 100644 feeds/p4/libjudy/src/doc/ext/LICENSE create mode 100644 feeds/p4/libjudy/src/doc/ext/README create mode 100644 feeds/p4/libjudy/src/doc/ext/README_deliver create mode 100644 feeds/p4/libjudy/src/doc/int/10minutes.htm create mode 100644 feeds/p4/libjudy/src/examples/Judy1Dup.c create mode 100644 feeds/p4/libjudy/src/examples/Judy1Dup.h create mode 100644 feeds/p4/libjudy/src/examples/Judy1DupCheck.c create mode 100644 feeds/p4/libjudy/src/examples/Judy1Op.c create mode 100644 feeds/p4/libjudy/src/examples/Judy1Op.h create mode 100644 feeds/p4/libjudy/src/examples/Judy1OpCheck.c create mode 100644 feeds/p4/libjudy/src/examples/Makefile create mode 100644 feeds/p4/libjudy/src/examples/README create mode 100644 feeds/p4/libjudy/src/src/Judy.h create mode 100644 feeds/p4/libjudy/src/src/Judy.h.check.c create mode 100644 feeds/p4/libjudy/src/src/Judy1/Judy1.h create mode 100644 feeds/p4/libjudy/src/src/Judy1/Makefile.am create mode 100644 feeds/p4/libjudy/src/src/Judy1/README create mode 100644 feeds/p4/libjudy/src/src/JudyCommon/JudyByCount.c create mode 100644 feeds/p4/libjudy/src/src/JudyCommon/JudyCascade.c create mode 100644 feeds/p4/libjudy/src/src/JudyCommon/JudyCount.c create mode 100644 feeds/p4/libjudy/src/src/JudyCommon/JudyCreateBranch.c create mode 100644 feeds/p4/libjudy/src/src/JudyCommon/JudyDecascade.c create mode 100644 feeds/p4/libjudy/src/src/JudyCommon/JudyDel.c create mode 100644 feeds/p4/libjudy/src/src/JudyCommon/JudyFirst.c create mode 100644 feeds/p4/libjudy/src/src/JudyCommon/JudyFreeArray.c create mode 100644 feeds/p4/libjudy/src/src/JudyCommon/JudyGet.c create mode 100644 feeds/p4/libjudy/src/src/JudyCommon/JudyIns.c create mode 100644 feeds/p4/libjudy/src/src/JudyCommon/JudyInsArray.c create mode 100644 feeds/p4/libjudy/src/src/JudyCommon/JudyInsertBranch.c create mode 100644 feeds/p4/libjudy/src/src/JudyCommon/JudyMalloc.c create mode 100644 feeds/p4/libjudy/src/src/JudyCommon/JudyMallocIF.c create mode 100644 feeds/p4/libjudy/src/src/JudyCommon/JudyMemActive.c create mode 100644 feeds/p4/libjudy/src/src/JudyCommon/JudyMemUsed.c create mode 100644 feeds/p4/libjudy/src/src/JudyCommon/JudyPrevNext.c create mode 100644 feeds/p4/libjudy/src/src/JudyCommon/JudyPrevNextEmpty.c create mode 100644 feeds/p4/libjudy/src/src/JudyCommon/JudyPrintJP.c create mode 100644 feeds/p4/libjudy/src/src/JudyCommon/JudyPrivate.h create mode 100644 feeds/p4/libjudy/src/src/JudyCommon/JudyPrivate1L.h create mode 100644 feeds/p4/libjudy/src/src/JudyCommon/JudyPrivateBranch.h create mode 100644 feeds/p4/libjudy/src/src/JudyCommon/JudyTables.c create mode 100644 feeds/p4/libjudy/src/src/JudyCommon/Makefile.am create mode 100644 feeds/p4/libjudy/src/src/JudyCommon/README create mode 100644 feeds/p4/libjudy/src/src/JudyHS/JudyHS.c create mode 100644 feeds/p4/libjudy/src/src/JudyHS/JudyHS.h create mode 100644 feeds/p4/libjudy/src/src/JudyHS/Makefile.am create mode 100644 feeds/p4/libjudy/src/src/JudyHS/README create mode 100644 feeds/p4/libjudy/src/src/JudyL/JudyL.h create mode 100644 feeds/p4/libjudy/src/src/JudyL/Makefile.am create mode 100644 feeds/p4/libjudy/src/src/JudyL/README create mode 100644 feeds/p4/libjudy/src/src/JudySL/JudySL.c create mode 100644 feeds/p4/libjudy/src/src/JudySL/Makefile.am create mode 100644 feeds/p4/libjudy/src/src/JudySL/README create mode 100644 feeds/p4/libjudy/src/src/Makefile.am create mode 100644 feeds/p4/libjudy/src/src/README create mode 100644 feeds/p4/libjudy/src/src/apps/README create mode 100644 feeds/p4/libjudy/src/src/apps/demo/JudySort.c create mode 100644 feeds/p4/libjudy/src/src/apps/demo/Makefile_deliver create mode 100644 feeds/p4/libjudy/src/src/apps/demo/README create mode 100644 feeds/p4/libjudy/src/src/apps/demo/README_deliver create mode 100644 feeds/p4/libjudy/src/src/apps/demo/funhist.c create mode 100644 feeds/p4/libjudy/src/src/apps/demo/interL.c create mode 100644 feeds/p4/libjudy/src/src/apps/demo/interSL.c create mode 100755 feeds/p4/libjudy/src/src/apps/demo/run_demo create mode 100755 feeds/p4/libjudy/src/src/build.bat create mode 100644 feeds/p4/libjudy/src/src/obj/Makefile.am create mode 100755 feeds/p4/libjudy/src/src/sh_build create mode 100644 feeds/p4/libjudy/src/test/Centrino_1.3Mhz_Plots/Hash_CO.plot create mode 100644 feeds/p4/libjudy/src/test/Centrino_1.3Mhz_Plots/JLHash_CO.plot create mode 100644 feeds/p4/libjudy/src/test/Centrino_1.3Mhz_Plots/JudyHS_CO.plot create mode 100644 feeds/p4/libjudy/src/test/Centrino_1.3Mhz_Plots/JudySL_CO.plot create mode 100644 feeds/p4/libjudy/src/test/CheckDupLines.c create mode 100755 feeds/p4/libjudy/src/test/Checkit create mode 100644 feeds/p4/libjudy/src/test/Judy1LCheck.c create mode 100644 feeds/p4/libjudy/src/test/Judy1LHCheck.c create mode 100644 feeds/p4/libjudy/src/test/Judy1LHTime.c create mode 100644 feeds/p4/libjudy/src/test/Judy1LTime.c create mode 100644 feeds/p4/libjudy/src/test/JudyString.c create mode 100644 feeds/p4/libjudy/src/test/Makefile.am create mode 100644 feeds/p4/libjudy/src/test/README create mode 100644 feeds/p4/libjudy/src/test/SLcompare.c create mode 100644 feeds/p4/libjudy/src/test/StringCompare.c create mode 100755 feeds/p4/libjudy/src/test/jbgraph create mode 100644 feeds/p4/libjudy/src/test/malloc-pre2.8a.c create mode 100644 feeds/p4/libjudy/src/test/simple.c create mode 100755 feeds/p4/libjudy/src/test/testjbgraph create mode 100644 feeds/p4/libjudy/src/test/timeit.c create mode 100644 feeds/p4/libjudy/src/test/timeit.h create mode 100644 feeds/p4/libjudy/src/tool/Makefile.am create mode 100644 feeds/p4/libjudy/src/tool/README create mode 100644 feeds/p4/libjudy/src/tool/jhton.c create mode 100644 feeds/p4/libjudy/src/tool/listJPtype.c create mode 100644 feeds/p4/p4-bmv2/Makefile create mode 100644 feeds/p4/thrift/Makefile create mode 100644 feeds/p4/thrift/autoscan.log create mode 100644 feeds/p4/thrift/configure.scan create mode 100644 feeds/p4/thrift/patches/100-compile.patch create mode 100644 feeds/realtek/rtl83xx-poe/Makefile create mode 100755 feeds/realtek/rtl83xx-poe/files/bin/poe.lua create mode 100644 feeds/realtek/rtl83xx-poe/files/etc/config/poe create mode 100755 feeds/realtek/rtl83xx-poe/files/etc/init.d/poe create mode 100644 feeds/realtek/rtl83xx-poe/files/etc/uci-defaults/30-poe create mode 100644 feeds/ubpf/ubpf/Makefile create mode 100644 feeds/ubpf/ubpf/src/CMakeLists.txt create mode 100644 feeds/ubpf/ubpf/src/map.c create mode 100644 feeds/ubpf/ubpf/src/net.c create mode 100644 feeds/ubpf/ubpf/src/prog.c create mode 100644 feeds/ubpf/ubpf/src/stats.c create mode 100644 feeds/ubpf/ubpf/src/uxdp.c create mode 100644 feeds/ubpf/ubpf/src/uxdp.h create mode 100644 feeds/ubpf/ubpf/src/xdp.c create mode 100644 feeds/ubpf/ubpf/src/xdplist.c create mode 100644 feeds/ubpf/ubpf/src/xdpload.c create mode 100644 feeds/ucentral/libwebsockets/Makefile create mode 100644 feeds/ucentral/luci/luci-mod-simple/Makefile create mode 100644 feeds/ucentral/luci/luci-mod-simple/htdocs/luci-static/resources/view/setup.js create mode 100755 feeds/ucentral/luci/luci-mod-simple/root/sbin/certupdate create mode 100644 feeds/ucentral/luci/luci-mod-simple/root/usr/share/luci/menu.d/luci-simple.json create mode 100644 feeds/ucentral/luci/luci-mod-simple/root/usr/share/rpcd/acl.d/luci-mod-simple.json create mode 100644 feeds/ucentral/luci/luci-theme-ucentral/Makefile create mode 100644 feeds/ucentral/luci/luci-theme-ucentral/htdocs/luci-static/ucentral/._logo.svg create mode 100644 feeds/ucentral/luci/luci-theme-ucentral/htdocs/luci-static/ucentral/cascade.css create mode 100644 feeds/ucentral/luci/luci-theme-ucentral/htdocs/luci-static/ucentral/favicon.png create mode 100644 feeds/ucentral/luci/luci-theme-ucentral/htdocs/luci-static/ucentral/logo.png create mode 100644 feeds/ucentral/luci/luci-theme-ucentral/htdocs/luci-static/ucentral/logo.svg create mode 100644 feeds/ucentral/luci/luci-theme-ucentral/htdocs/luci-static/ucentral/spinner.svg create mode 100644 feeds/ucentral/luci/luci-theme-ucentral/luasrc/view/themes/ucentral/footer.htm create mode 100644 feeds/ucentral/luci/luci-theme-ucentral/luasrc/view/themes/ucentral/header.htm create mode 100755 feeds/ucentral/luci/luci-theme-ucentral/root/etc/uci-defaults/30_luci-theme-ucentral create mode 100644 feeds/ucentral/luci/luci.mk create mode 100644 feeds/ucentral/poco/Makefile create mode 100644 feeds/ucentral/poco/patches/100-configure.patch create mode 100644 feeds/ucentral/poco/patches/200-strerror.patch create mode 100644 feeds/ucentral/rtty/Makefile create mode 100644 feeds/ucentral/rtty/files/rtty.config create mode 100644 feeds/ucentral/rtty/files/rtty.init create mode 100644 feeds/ucentral/rtty/patches/100-oneshot.patch create mode 100644 feeds/ucentral/ucentral-client/Makefile create mode 100644 feeds/ucentral/ucentral-client/files/etc/config/ucentral create mode 100644 feeds/ucentral/ucentral-client/files/etc/config/ustats create mode 100644 feeds/ucentral/ucentral-client/files/etc/init.d/ucentral create mode 100644 feeds/ucentral/ucentral-client/files/etc/init.d/ustats create mode 100644 feeds/ucentral/ucentral-client/files/etc/ucentral/ucentral.failsafe create mode 100644 feeds/ucentral/ucentral-client/files/etc/uci-defaults/zzz-ucentral create mode 100755 feeds/ucentral/ucentral-client/files/usr/libexec/ucentral/ucentral_apply.sh create mode 100755 feeds/ucentral/ucentral-client/files/usr/libexec/ucentral/ucentral_cmd.sh create mode 100644 feeds/ucentral/ucentral-client/files/usr/libexec/ucentral/ucentral_factory.sh create mode 100755 feeds/ucentral/ucentral-client/files/usr/libexec/ucentral/ucentral_failsafe.sh create mode 100755 feeds/ucentral/ucentral-client/files/usr/libexec/ucentral/ucentral_led_blink.sh create mode 100755 feeds/ucentral/ucentral-client/files/usr/libexec/ucentral/ucentral_state.sh create mode 100644 feeds/ucentral/ucentral-client/files/usr/libexec/ucentral/ucentral_sysupgrade.sh create mode 100755 feeds/ucentral/ucentral-client/files/usr/libexec/ucentral/ucentral_verify.sh create mode 120000 feeds/ucentral/ucentral-client/git-src create mode 100644 feeds/ucentral/ucentral-defaults/Makefile create mode 100755 feeds/ucentral/ucentral-defaults/files/etc/uci-defaults/99-ucentral-lldp create mode 100755 feeds/ucentral/ucentral-defaults/files/etc/uci-defaults/99-ucentral-rtty create mode 100644 feeds/ucentral/ucentral-jsonschema/Makefile create mode 100644 feeds/ucentral/ucentral-mqtt/Makefile create mode 100644 feeds/ucentral/ucentral-mqtt/files/ucentral-mqtt create mode 100755 feeds/ucentral/ucentral-mqtt/files/ucentral_stats.sh create mode 100644 feeds/ucentral/ucentral-mqtt/files/umqtt.config create mode 100644 feeds/ucentral/ucentral-schema/Makefile create mode 100644 feeds/ucentral/ucentral-tools/Makefile create mode 100644 feeds/ucentral/ucentral-tools/files/etc/hotplug.d/iface/90-ip-collide create mode 100644 feeds/ucentral/ucentral-wifi/Makefile create mode 100644 feeds/ucentral/ucentral-wifi/files/ucentral-wifi create mode 120000 feeds/ucentral/ucentral-wifi/git-src create mode 100644 feeds/ucentral/ucentralgw/Makefile create mode 100755 feeds/ucentral/ucentralgw/files/etc/init.d/ucentralgw create mode 100644 feeds/ucentral/ucentralgw/files/etc/ucentral/ucentral.properties create mode 100644 feeds/ucentral/ucentralgw/patches/100-cmake.patch create mode 100644 feeds/ucentral/ucode/Makefile create mode 100644 feeds/ucentral/ucode/patches/000-fix.patch create mode 100644 feeds/ucentral/udevmand/Makefile create mode 100755 feeds/ucentral/udevmand/files/etc/init.d/udevmand create mode 120000 feeds/ucentral/udevmand/git-src create mode 100644 feeds/ucentral/usteer/Makefile create mode 100644 feeds/ucentral/usteer/files/etc/config/usteer create mode 100755 feeds/ucentral/usteer/files/etc/init.d/usteer create mode 100644 feeds/wifi-ax/ath11k-firmware/Makefile create mode 100644 feeds/wifi-ax/ath11k-firmware/files/IPQ6018/Notice.txt create mode 100644 feeds/wifi-ax/ath11k-firmware/files/IPQ6018/m3_fw.b00 create mode 100644 feeds/wifi-ax/ath11k-firmware/files/IPQ6018/m3_fw.b01 create mode 100644 feeds/wifi-ax/ath11k-firmware/files/IPQ6018/m3_fw.b02 create mode 100644 feeds/wifi-ax/ath11k-firmware/files/IPQ6018/m3_fw.flist create mode 100644 feeds/wifi-ax/ath11k-firmware/files/IPQ6018/m3_fw.mdt create mode 100644 feeds/wifi-ax/ath11k-firmware/files/IPQ6018/q6_fw.b00 create mode 100644 feeds/wifi-ax/ath11k-firmware/files/IPQ6018/q6_fw.b01 create mode 100644 feeds/wifi-ax/ath11k-firmware/files/IPQ6018/q6_fw.b02 create mode 100644 feeds/wifi-ax/ath11k-firmware/files/IPQ6018/q6_fw.b03 create mode 100644 feeds/wifi-ax/ath11k-firmware/files/IPQ6018/q6_fw.b04 create mode 100644 feeds/wifi-ax/ath11k-firmware/files/IPQ6018/q6_fw.b05 create mode 100644 feeds/wifi-ax/ath11k-firmware/files/IPQ6018/q6_fw.b07 create mode 100644 feeds/wifi-ax/ath11k-firmware/files/IPQ6018/q6_fw.b08 create mode 100644 feeds/wifi-ax/ath11k-firmware/files/IPQ6018/q6_fw.flist create mode 100644 feeds/wifi-ax/ath11k-firmware/files/IPQ6018/q6_fw.mdt create mode 100644 feeds/wifi-ax/ath11k-firmware/files/IPQ8074/Notice.txt create mode 100644 feeds/wifi-ax/ath11k-firmware/files/IPQ8074/m3_fw.b00 create mode 100644 feeds/wifi-ax/ath11k-firmware/files/IPQ8074/m3_fw.b01 create mode 100644 feeds/wifi-ax/ath11k-firmware/files/IPQ8074/m3_fw.b02 create mode 100644 feeds/wifi-ax/ath11k-firmware/files/IPQ8074/m3_fw.flist create mode 100644 feeds/wifi-ax/ath11k-firmware/files/IPQ8074/m3_fw.mdt create mode 100644 feeds/wifi-ax/ath11k-firmware/files/IPQ8074/q6_fw.b00 create mode 100644 feeds/wifi-ax/ath11k-firmware/files/IPQ8074/q6_fw.b01 create mode 100644 feeds/wifi-ax/ath11k-firmware/files/IPQ8074/q6_fw.b02 create mode 100644 feeds/wifi-ax/ath11k-firmware/files/IPQ8074/q6_fw.b03 create mode 100644 feeds/wifi-ax/ath11k-firmware/files/IPQ8074/q6_fw.b04 create mode 100644 feeds/wifi-ax/ath11k-firmware/files/IPQ8074/q6_fw.b05 create mode 100644 feeds/wifi-ax/ath11k-firmware/files/IPQ8074/q6_fw.b07 create mode 100644 feeds/wifi-ax/ath11k-firmware/files/IPQ8074/q6_fw.b08 create mode 100644 feeds/wifi-ax/ath11k-firmware/files/IPQ8074/q6_fw.flist create mode 100644 feeds/wifi-ax/ath11k-firmware/files/IPQ8074/q6_fw.mdt create mode 100644 feeds/wifi-ax/ath11k-firmware/files/QCN9000/Notice.txt create mode 100644 feeds/wifi-ax/ath11k-firmware/files/QCN9000/amss.bin create mode 100644 feeds/wifi-ax/ath11k-firmware/files/QCN9000/board-2.bin create mode 100644 feeds/wifi-ax/ath11k-firmware/files/QCN9000/m3.bin create mode 100644 feeds/wifi-ax/ath11k-wifi/Makefile create mode 100644 feeds/wifi-ax/ath11k-wifi/bdwlan_EX227.bin create mode 100644 feeds/wifi-ax/ath11k-wifi/bdwlan_EX447.bin create mode 100644 feeds/wifi-ax/ath11k-wifi/board-2.bin.IPQ6018 create mode 100644 feeds/wifi-ax/ath11k-wifi/board-2.bin.IPQ8074 create mode 100644 feeds/wifi-ax/ath11k-wifi/board-cig-wf188.bin.IPQ6018 create mode 100644 feeds/wifi-ax/ath11k-wifi/board-cig-wf188n.bin.IPQ6018 create mode 100644 feeds/wifi-ax/ath11k-wifi/board-cig-wf194c.bin.IPQ8074 create mode 100644 feeds/wifi-ax/ath11k-wifi/board-edgecore-eap101.bin.IPQ6018 create mode 100644 feeds/wifi-ax/ath11k-wifi/board-edgecore-eap102.bin.IPQ8074 create mode 100755 feeds/wifi-ax/ath11k-wifi/board-sercomm-wallaby.bin.IPQ8074 create mode 100644 feeds/wifi-ax/ath11k-wifi/board-tplink-ex227.bin.IPQ8074 create mode 100644 feeds/wifi-ax/ath11k-wifi/board-tplink-ex447.bin.IPQ8074 create mode 100644 feeds/wifi-ax/batman-adv/Config.in create mode 100644 feeds/wifi-ax/batman-adv/Makefile create mode 100755 feeds/wifi-ax/batman-adv/files/etc/uci-defaults/99-migrate-batadv_hardif create mode 100755 feeds/wifi-ax/batman-adv/files/lib/netifd/proto/batadv.sh create mode 100755 feeds/wifi-ax/batman-adv/files/lib/netifd/proto/batadv_hardif.sh create mode 100755 feeds/wifi-ax/batman-adv/files/lib/netifd/proto/batadv_vlan.sh create mode 100644 feeds/wifi-ax/batman-adv/patches/0005-batman-adv-Fix-duplicated-OGMs-on-NETDEV_UP.patch create mode 100644 feeds/wifi-ax/batman-adv/patches/0006-batman-adv-Fix-netlink-dumping-of-all-mcast_flags-bu.patch create mode 100644 feeds/wifi-ax/batman-adv/patches/0007-batman-adv-fix-uninit-value-in-batadv_netlink_get_if.patch create mode 100644 feeds/wifi-ax/batman-adv/patches/0008-batman-adv-Only-read-OGM-tvlv_len-after-buffer-len-c.patch create mode 100644 feeds/wifi-ax/batman-adv/patches/0009-batman-adv-Only-read-OGM2-tvlv_len-after-buffer-len-.patch create mode 100644 feeds/wifi-ax/batman-adv/patches/0010-batman-adv-Avoid-free-alloc-race-when-handling-OGM2-.patch create mode 100644 feeds/wifi-ax/batman-adv/patches/0011-batman-adv-Avoid-free-alloc-race-when-handling-OGM-b.patch create mode 100644 feeds/wifi-ax/batman-adv/patches/0012-batman-adv-Introduce-own-OGM2-buffer-mutex.patch create mode 100644 feeds/wifi-ax/batman-adv/patches/0013-batman-adv-Avoid-OGM-workqueue-synchronous-cancel-de.patch create mode 100644 feeds/wifi-ax/batman-adv/patches/0014-batman-adv-Fix-DAT-candidate-selection-on-little-end.patch create mode 100644 feeds/wifi-ax/batman-adv/patches/0015-batman-adv-Don-t-schedule-OGM-for-disabled-interface.patch create mode 100644 feeds/wifi-ax/batman-adv/patches/0016-batman-adv-fix-batadv_nc_random_weight_tq.patch create mode 100644 feeds/wifi-ax/batman-adv/patches/0017-batman-adv-Fix-refcnt-leak-in-batadv_show_throughput.patch create mode 100644 feeds/wifi-ax/batman-adv/patches/0018-batman-adv-Fix-refcnt-leak-in-batadv_store_throughpu.patch create mode 100644 feeds/wifi-ax/batman-adv/patches/0019-batman-adv-Fix-refcnt-leak-in-batadv_v_ogm_process.patch create mode 100644 feeds/wifi-ax/batman-adv/patches/0020-batman-adv-Revert-disable-ethtool-link-speed-detecti.patch create mode 100644 feeds/wifi-ax/batman-adv/patches/0021-batman-adv-Avoid-uninitialized-chaddr-when-handling-.patch create mode 100644 feeds/wifi-ax/batman-adv/patches/0022-batman-adv-Fix-own-OGM-check-in-aggregated-OGMs.patch create mode 100644 feeds/wifi-ax/batman-adv/patches/0023-batman-adv-bla-use-netif_rx_ni-when-not-in-interrupt.patch create mode 100644 feeds/wifi-ax/batman-adv/src/compat-hacks.h create mode 100644 feeds/wifi-ax/hostapd/Config.in create mode 100644 feeds/wifi-ax/hostapd/Makefile create mode 100644 feeds/wifi-ax/hostapd/files/hostapd-basic.config create mode 100644 feeds/wifi-ax/hostapd/files/hostapd-full.config create mode 100644 feeds/wifi-ax/hostapd/files/hostapd-mini.config create mode 100644 feeds/wifi-ax/hostapd/files/hostapd.sh create mode 100644 feeds/wifi-ax/hostapd/files/multicall.c create mode 100644 feeds/wifi-ax/hostapd/files/wpa_supplicant-basic.config create mode 100644 feeds/wifi-ax/hostapd/files/wpa_supplicant-full.config create mode 100644 feeds/wifi-ax/hostapd/files/wpa_supplicant-mini.config create mode 100644 feeds/wifi-ax/hostapd/files/wpa_supplicant-p2p.config create mode 100644 feeds/wifi-ax/hostapd/files/wpad.init create mode 100644 feeds/wifi-ax/hostapd/files/wps-hotplug.sh create mode 100644 feeds/wifi-ax/hostapd/patches/004-mesh-use-setup-completion-callback-to-complete-mesh-.patch create mode 100644 feeds/wifi-ax/hostapd/patches/005-mesh-update-ssid-frequency-as-pri-sec-channel-switch.patch create mode 100644 feeds/wifi-ax/hostapd/patches/006-mesh-inform-kernel-driver-DFS-handler-in-userspace.patch create mode 100644 feeds/wifi-ax/hostapd/patches/007-mesh-apply-channel-attributes-before-running-Mesh.patch create mode 100644 feeds/wifi-ax/hostapd/patches/011-mesh-Allow-DFS-channels-to-be-selected-if-dfs-is-ena.patch create mode 100644 feeds/wifi-ax/hostapd/patches/013-mesh-do-not-allow-pri-sec-channel-switch.patch create mode 100644 feeds/wifi-ax/hostapd/patches/015-mesh-do-not-use-offchan-mgmt-tx-on-DFS.patch create mode 100644 feeds/wifi-ax/hostapd/patches/016-mesh-fix-channel-switch-error-during-CAC.patch create mode 100644 feeds/wifi-ax/hostapd/patches/018-mesh-make-forwarding-configurable.patch create mode 100644 feeds/wifi-ax/hostapd/patches/100-daemonize_fix.patch create mode 100644 feeds/wifi-ax/hostapd/patches/200-multicall.patch create mode 100644 feeds/wifi-ax/hostapd/patches/300-noscan.patch create mode 100644 feeds/wifi-ax/hostapd/patches/301-mesh-noscan.patch create mode 100644 feeds/wifi-ax/hostapd/patches/310-rescan_immediately.patch create mode 100644 feeds/wifi-ax/hostapd/patches/320-optional_rfkill.patch create mode 100644 feeds/wifi-ax/hostapd/patches/330-nl80211_fix_set_freq.patch create mode 100644 feeds/wifi-ax/hostapd/patches/340-reload_freq_change.patch create mode 100644 feeds/wifi-ax/hostapd/patches/341-mesh-ctrl-iface-channel-switch.patch create mode 100644 feeds/wifi-ax/hostapd/patches/350-nl80211_del_beacon_bss.patch create mode 100644 feeds/wifi-ax/hostapd/patches/360-ctrl_iface_reload.patch create mode 100644 feeds/wifi-ax/hostapd/patches/370-ap_sta_support.patch create mode 100644 feeds/wifi-ax/hostapd/patches/380-disable_ctrl_iface_mib.patch create mode 100644 feeds/wifi-ax/hostapd/patches/381-hostapd_cli_UNKNOWN-COMMAND.patch create mode 100644 feeds/wifi-ax/hostapd/patches/390-wpa_ie_cap_workaround.patch create mode 100644 feeds/wifi-ax/hostapd/patches/400-wps_single_auth_enc_type.patch create mode 100644 feeds/wifi-ax/hostapd/patches/410-limit_debug_messages.patch create mode 100644 feeds/wifi-ax/hostapd/patches/420-indicate-features.patch create mode 100644 feeds/wifi-ax/hostapd/patches/430-hostapd_cli_ifdef.patch create mode 100644 feeds/wifi-ax/hostapd/patches/431-wpa_cli_ifdef.patch create mode 100644 feeds/wifi-ax/hostapd/patches/432-missing-typedef.patch create mode 100644 feeds/wifi-ax/hostapd/patches/450-scan_wait.patch create mode 100644 feeds/wifi-ax/hostapd/patches/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch create mode 100644 feeds/wifi-ax/hostapd/patches/461-driver_nl80211-use-new-parameters-during-ibss-join.patch create mode 100644 feeds/wifi-ax/hostapd/patches/463-add-mcast_rate-to-11s.patch create mode 100644 feeds/wifi-ax/hostapd/patches/464-fix-mesh-obss-check.patch create mode 100644 feeds/wifi-ax/hostapd/patches/470-survey_data_fallback.patch create mode 100644 feeds/wifi-ax/hostapd/patches/500-lto-jobserver-support.patch create mode 100644 feeds/wifi-ax/hostapd/patches/599-wpa_supplicant-fix-warnings.patch create mode 100644 feeds/wifi-ax/hostapd/patches/600-ubus_support.patch create mode 100644 feeds/wifi-ax/hostapd/patches/700-wifi-reload.patch create mode 100644 feeds/wifi-ax/hostapd/patches/800-dfs-enter-DFS-state-if-no-available-channel-is-found.patch create mode 100644 feeds/wifi-ax/hostapd/patches/800-probe_request-ignore-when-rssi-is-too-low.patch create mode 100644 feeds/wifi-ax/hostapd/patches/810-client-disconnect-when-rssi-is-low.patch create mode 100644 feeds/wifi-ax/hostapd/patches/900-hapd-netlink-ubus-bridge.patch create mode 100644 feeds/wifi-ax/hostapd/patches/900-max-sta-limit.patch create mode 100644 feeds/wifi-ax/hostapd/patches/a00-004-Add-provision-to-test-RADAR-detection-probablity-in-.patch create mode 100644 feeds/wifi-ax/hostapd/patches/a00-108-supplicant-tdls-peer-inactivity.patch create mode 100644 feeds/wifi-ax/hostapd/patches/b00-001-hostapd-fix-an-issue-related-with-wpa_group_state.patch create mode 100644 feeds/wifi-ax/hostapd/patches/b00-004-hostap-fix-compilation-issue.patch create mode 100644 feeds/wifi-ax/hostapd/patches/b00-014-hostapd-add-ht40-allow-map.patch create mode 100644 feeds/wifi-ax/hostapd/patches/b00-029-hostapd-disable-MAC-ACL-if-WPS-enabled.patch create mode 100644 feeds/wifi-ax/hostapd/patches/b00-033-wpa_supplicant-don-t-initate-TDLS-connection-if-stat.patch create mode 100644 feeds/wifi-ax/hostapd/patches/b00-034-hostapd-Add-max-rate-information-into-STATUS-and-STA.patch create mode 100644 feeds/wifi-ax/hostapd/patches/b00-036-hostapd-disable-40mhz-scan.patch create mode 100644 feeds/wifi-ax/hostapd/patches/c00-002-hostapd-he-update-nl-header.patch create mode 100644 feeds/wifi-ax/hostapd/patches/c00-003-HE-fix-ieee80211_he_capabilities-size.patch create mode 100644 feeds/wifi-ax/hostapd/patches/c00-004-add-HE-cross-check.patch create mode 100644 feeds/wifi-ax/hostapd/patches/c00-008-nl80211-Don-t-force-VHT-channel-definition-with-HE.patch create mode 100644 feeds/wifi-ax/hostapd/patches/c00-009-hostapd-detect-active-sta-using-TX-duration-in-ATF.patch create mode 100644 feeds/wifi-ax/hostapd/patches/c00-010-hostapd-fix-enabling-he-in-5G.patch create mode 100644 feeds/wifi-ax/hostapd/patches/c00-011-hostapd-add-mbo-support.patch create mode 100644 feeds/wifi-ax/hostapd/patches/c00-012-AP-Allow-downgrading-to-20MHz-based-on-OBSS-results.patch create mode 100644 feeds/wifi-ax/hostapd/patches/d00-001-add-HE-support-to-chan-switch-cmd.patch create mode 100644 feeds/wifi-ax/hostapd/patches/d00-003-wpa-supplicant-override-HE-toVHT-2G.patch create mode 100644 feeds/wifi-ax/hostapd/patches/d00-004-hostapd-Add-param-to-enable-disable-ul-mumimo.patch create mode 100644 feeds/wifi-ax/hostapd/patches/d00-005-hostapd-fix-btm-cand-pref-update.patch create mode 100644 feeds/wifi-ax/hostapd/patches/d00-006-hostapd-fix-sending-proper-vlan-id.patch create mode 100644 feeds/wifi-ax/hostapd/patches/d00-007-fixing-warning.patch create mode 100644 feeds/wifi-ax/hostapd/patches/d00-008-hostapd-fix-enable-40-80mhz-bandwidth-in-6Ghz.patch create mode 100644 feeds/wifi-ax/hostapd/patches/d00-009-hostapd-update-muedca-params.patch create mode 100644 feeds/wifi-ax/hostapd/patches/d00-010-hostapd-FILS-discovery-Unsolicited-Bcast-Probe-Resp-Support.patch create mode 100644 feeds/wifi-ax/hostapd/patches/d00-011-01-multiple_bssid-add-the-config-file.patch create mode 100644 feeds/wifi-ax/hostapd/patches/d00-012a-hostapd-add-support-for-reduced-neighbour-report.patch create mode 100644 feeds/wifi-ax/hostapd/patches/d00-012b-hostapd-add-support-for-reduced-neighbour-report.patch create mode 100644 feeds/wifi-ax/hostapd/patches/d00-012c-hostapd-add-support-for-reduced-neighbour-report.patch create mode 100644 feeds/wifi-ax/hostapd/patches/d00-012d-hostapd-add-support-for-reduced-neighbour-report.patch create mode 100644 feeds/wifi-ax/hostapd/patches/e00-001-send-6ghz-cap-to-kernel-and-fix-6ghz-op-class.patch create mode 100644 feeds/wifi-ax/hostapd/patches/e00-002-6G-enable-TX-power-envelope-IE-incase-of-6GHz.patch create mode 100644 feeds/wifi-ax/hostapd/patches/e00-003-6G-security-constraints.patch create mode 100644 feeds/wifi-ax/hostapd/patches/e00-003-hostapd-chan-switch-6ghz.patch create mode 100644 feeds/wifi-ax/hostapd/patches/e00-003-mesh-support-6ghz-support-in-11s-mesh.patch create mode 100644 feeds/wifi-ax/hostapd/patches/e00-004-hostapd-Enable-160MHz-support-for-6G-in-11s-mesh.patch create mode 100644 feeds/wifi-ax/hostapd/patches/e00-004-multiple_bssid-set-extended-capabilities.patch create mode 100644 feeds/wifi-ax/hostapd/patches/e00-005-Remove-unnecessary-nl80211-messages.patch create mode 100644 feeds/wifi-ax/hostapd/patches/e00-006-AP-Extend-Spatial-Reuse-Parameter-Set.patch create mode 100644 feeds/wifi-ax/hostapd/patches/e00-007-Add-RSN-extension-element-in-multiple-BSSID-element.patch create mode 100644 feeds/wifi-ax/hostapd/patches/e00-007-add-EMA-configuration-option.patch create mode 100644 feeds/wifi-ax/hostapd/patches/e00-008-fix-lowest-association-ID-with-multiple-BSSID-element.patch create mode 100644 feeds/wifi-ax/hostapd/patches/e00-008-multiple_bssid-DTIM-setting.patch create mode 100644 feeds/wifi-ax/hostapd/patches/e00-009-fix-reduced-neighbor-report-length.patch create mode 100644 feeds/wifi-ax/hostapd/patches/e00-010-hidden-SSID-support-in-multiple-BSSID-IE.patch create mode 100644 feeds/wifi-ax/hostapd/patches/e00-011-6ghz-out-of-band-advertisements.patch create mode 100644 feeds/wifi-ax/hostapd/patches/f00-001-bss-coloring-add-support-for-handling-collision-events-and-triggering-CCA.patch create mode 100644 feeds/wifi-ax/hostapd/patches/f00-001-hostapd-Fix-calling-hostapd_disassoc_accept_mac-in-CLI.patch create mode 100644 feeds/wifi-ax/hostapd/patches/f00-002-bss_coloring-add-the-code-required-to-generate-the-CCA-IE.patch create mode 100644 feeds/wifi-ax/hostapd/patches/f00-002-hostap-Move-acl-related-code-to-generic-to-be-used-for-mesh.patch create mode 100644 feeds/wifi-ax/hostapd/patches/f00-003-Extend-acl-config-support-to-mesh.patch create mode 100644 feeds/wifi-ax/hostapd/patches/f00-003-bss-coloring-disable-BSS-color-during-CCA.patch create mode 100644 feeds/wifi-ax/hostapd/patches/f00-004-bss-coloring-add-the-switch_color-handler-to-the-nl80211-driver.patch create mode 100644 feeds/wifi-ax/hostapd/patches/f00-004-mesh-Dynamic-MAC-ACL-management-over-control-interface.patch create mode 100644 feeds/wifi-ax/hostapd/patches/f00-005-bss-coloring-handle-the-collision-and-CCA-events-coming-from-the-kernel.patch create mode 100644 feeds/wifi-ax/hostapd/patches/f00-006-bss_coloring-allow-using-a-random-starting-color.patch create mode 100644 feeds/wifi-ax/hostapd/patches/f00-007-bss_coloring-add-intelligence-color-choose-in-CCA.patch create mode 100644 feeds/wifi-ax/hostapd/patches/f00-008-bss_coloring_add_support_to_change_bss_color_by_user.patch create mode 100644 feeds/wifi-ax/hostapd/patches/f00-009-add-bcca-IE-with-countdown-zero-in-color-change-beacon.patch create mode 100644 feeds/wifi-ax/hostapd/patches/f00-010-bss_coloring-check-free-color-periodically.patch create mode 100644 feeds/wifi-ax/hostapd/src/src/ap/ubus.c create mode 100644 feeds/wifi-ax/hostapd/src/src/ap/ubus.h create mode 100644 feeds/wifi-ax/hostapd/src/src/utils/build_features.h create mode 100644 feeds/wifi-ax/hostapd/src/wpa_supplicant/ubus.c create mode 100644 feeds/wifi-ax/hostapd/src/wpa_supplicant/ubus.h create mode 100644 feeds/wifi-ax/iw/Makefile create mode 100644 feeds/wifi-ax/iw/patches/001-nl80211_h_sync.patch create mode 100644 feeds/wifi-ax/iw/patches/120-antenna_gain.patch create mode 100644 feeds/wifi-ax/iw/patches/200-reduce_size.patch create mode 100644 feeds/wifi-ax/iw/patches/502-Add-channel-attribure-support-for-nl80211-message.patch create mode 100644 feeds/wifi-ax/iw/patches/505-Add-user-command-for-tid-specific-retry-count.patch create mode 100644 feeds/wifi-ax/iw/patches/506-Add-user-command-for-tid-specific-aggr-conf.patch create mode 100644 feeds/wifi-ax/iw/patches/507-Add-peer-address-in-noack-map-command create mode 100644 feeds/wifi-ax/iw/patches/508-iw-add-airtime-weight-config-support.patch create mode 100644 feeds/wifi-ax/iw/patches/510-iw-wifi-config-vendor.patch create mode 100644 feeds/wifi-ax/iw/patches/512-iw-add-wide-band-scan-support.patch create mode 100644 feeds/wifi-ax/iw/patches/513-iw-add-HE-rate-gi-ltf-support.patch create mode 100644 feeds/wifi-ax/iw/patches/514-iw-update-freq-to-chan-mappings-for-6GHz-band-per-IE.patch create mode 100644 feeds/wifi-ax/iw/patches/516-iw-enable-80M-support-for-6GHz-11s-mesh.patch create mode 100644 feeds/wifi-ax/iw/patches/517-iw-support-optional-argument-to-specify-6Ghz-channel.patch create mode 100644 feeds/wifi-ax/iw/patches/518-iw-support-HE-rate-configuration-in-6-GHz-band.patch create mode 100644 feeds/wifi-ax/iw/patches/519-iw-Add-HE-UL-MU-fixed-rate-setting.patch create mode 100644 feeds/wifi-ax/mac80211/Makefile create mode 100644 feeds/wifi-ax/mac80211/ath.mk create mode 100644 feeds/wifi-ax/mac80211/files/lib/netifd/mac80211.sh create mode 100644 feeds/wifi-ax/mac80211/files/lib/netifd/wireless/mac80211.sh create mode 100644 feeds/wifi-ax/mac80211/files/lib/performance.sh create mode 100755 feeds/wifi-ax/mac80211/files/lib/smp_affinity_settings.sh create mode 100644 feeds/wifi-ax/mac80211/files/lib/wifi/mac80211.sh create mode 100644 feeds/wifi-ax/mac80211/files/mac80211.hotplug create mode 100644 feeds/wifi-ax/mac80211/patches/pending/200-6ghz-fix.patch create mode 100644 feeds/wifi-ax/mac80211/patches/pending/201-log-spam.patch create mode 100644 feeds/wifi-ax/mac80211/patches/pending/202-dfs.patch create mode 100644 feeds/wifi-ax/mac80211/patches/pending/203-ath11k-mac.patch create mode 100644 feeds/wifi-ax/mac80211/patches/pending/210-memory-optimize.patch create mode 100644 feeds/wifi-ax/mac80211/patches/pending/211-coldboot.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/001-fix_build.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/002-disable_addr_notifier.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/003-ath_move_debug_code.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/004-ath_regd_optional.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/005-ath9k_compilation_fix.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/006-backport_skb_put_fix.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/007-fix_compilation_issue.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/008-Enabling_vht_capability_for_2G.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/009-ath11k-Enable-VHT-for-2G.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/010-mac80211-disable-signed-regulatory.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/012-ath11k-add-pktlog-debugfs-support.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/015-add-raw-mode-support.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/017-ath11k-factory-test-mode-support.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/018-ath11k-fix-invalid-msdu-len-print-info.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/020-ath11k-add-btcoex-config.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/021-ath11k-cold-boot-calibration-support.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/022-ath11k-add-ap-ps-support.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/025-ath11k-add-vdev-delete-synchro-with-firmware.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/026-ath11k-add-peer-delete-synchro-with-firmware.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/030-ath11k-fix-co-exist-monitor-mode-can-t-capture-data-.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/031-ath11k-print-stats-on-crash.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/033-ath11k-fix-for-peer-memory-corruption.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/034-ath11k-fix-len-warnings.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/035-ath11k-load-appropriate-board-data-from-board-id.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/036-nl80211-add-wide-band-scan-support.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/037-ath11k-add-wide-band-scan-support.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/038-ath11k-Adding-support-for-QDSS.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/039-mac80211-ath11k-add-HE-TX-rate-reporting-to-radiotap.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/040-ath11k-add-new-api-to-get-ar-from-arvifs.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/043-ath11k-use-regular-tx-path-for-raw-mode.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/047-ath11k-set-eapol-minrate-conf.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/056-ath11k-mac80211-twt-support.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/058-enable-ipq6018.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/059-ath11k-add-he-fields-into-radiotap-header.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/061-mac80211-process-addba-req-during-invalid-ext-element.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/063-mac80211-fix-low-tput-for-mesh-forwarding.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/065-ath11k-add-HE-fix-rate-support.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/066-ath11k-add-support-spectral-ipq6018.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/068-ath11k-add-rx-histogram-stats.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/069-ath11k-add-HE-stats-in-peer-stats.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/072-ath11k-support-hostapd-config-to-enable-disable-he-m.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/078-mac80211-ethernet-rx-decap-support.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/080-ath11k-ethernet-rx-decap-offload.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/084-ath11k-fix-ul-ofdma-counter-always-zero-in-peer-stat.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/085-ath11k-Fix-supported-capabilities-and-mcs-rates-in-he.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/086-ath11k-add-support-for-channel-rx-tx-time-in-survey-dump.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/087-ath11k-fix-ul-ofdma-counter-increamenting-improperly.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/088-ath11k-add-htt-stats.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/090-ath11k-fix-fixrate-issue.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/097-ath11k-htt-stats-remove-fixed-size-array-usage.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/098-ath11k-fix-firmware-crash-due-to-invalid-vdev-id.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/103-ath11k-add-he-ampdu-factor.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/105-ath11k-adding-validation-for-tx-stats-and-rx-stats.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/105-ath11k-fix-monitor-crash-if-tx-offload-is-enabled.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/106-mac80211-enable-rx_packet-counter-in-offload-rx-path.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/107-ath11k-tid-counter-fix.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/108-ath11k-enable-ul-ofdma-ru-allocation-in-peer-stats.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/110-ath11k-avoid-user-cc-setting-in-active-vdev.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/110-ath11k-boot-without-caldata.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/110-ath11k-fix-setting-range-of-mcs-rates-in-he.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/112-ath11k-add-btcoex-debugfs-support.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/112-ath11k-fix-parsing-pktlog-lite.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/113-ath11k-add-8023-undecap-support.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/116-ath11k-clean-up-monitor-vdev-del.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/117-ath11k-fixed-gi-ltf-support.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/118-ath11k-reset-bcc-counter.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/120-ath11k-enable-ppdu-stats-in-coexist-mode.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/138-ath11k-fill-vdev-pdev-id-for-fwtest-cmd.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/139-ath11k-add-debugfs-to-set-ratemask.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/141-ath11k-fixing-flooding-console-with-ath11k_warn-prints.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/142-ath11k-adding-support-for-mgmt-frame-stats.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/143-ath11k-disabling-credit-flow-for-ath11k.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/146-ath11k-fix-htt-stats-10-rx-rssi-chain.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/146-mac80211-enable-TKIP-when-using-encapsulation-offloading create mode 100644 feeds/wifi-ax/mac80211/patches/qca/147-fix-signal-station-dump.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/148-cfg80211-notify-4addr-capability-event-to-driver.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/149-ath11k-fix-4addr-tx-failure-AP-STA-modes.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/164-ath11k-add-qcn9000-support.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/171-ath11k-use-static-window-for-register-access.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/173-ath11k-add-qcn9000-hal-support.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/174-ath11k-add-qcn9000-dp-rx-support.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/175-ath11k-fix-ce-interrupts-for-qcn9000.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/176-ath11k-fix-wmi-init-cmd-for-single-radio.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/179-ath11k-abstract-ext-interrupts.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/181-ath11k-remove-error-on-soc-debugfs-fail.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/184-ath11k-pci-reload.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/186-ath11k-cleanup-bdf-download-sequence.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/188-ath11k-m3-ssr-dump-collection.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/189-ath11k-add-new-dfs-region-name-JP.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/189-ath11k-add-support-for-device-recovery.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/191-ath11k-add-mgmt-and-data-ack-rssi.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/191-ath11k-update-ulmumimo-ofdma-htt-stats.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/192-ath11k-fix-rx-bytes-value-not-updated-on-mesh.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/192-ath11k-support-for-2g-phyb-mode.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/193-ath11k-add-htt-stats-30-ext-rx-rate.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/193-ath11k-war-pdevid-for-phyb2g-mode.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/194-ath11k-use-dev_coredumpm-API-to-collect-rddm.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/195-ath11k-add-coldboot-calibration-for-qcn9000.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/196-ath11k-Fix-pci-get-msi-address.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/196-ath11k-add-qdss-support-for-qcn9000.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/196-ath11k-fix-for-accepting-bcast-presp-in-GHz-scan.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/196-ath11k-tpc-stats-support.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/197-ath11k-add-support-to-collect-q6mem-dump.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/198-ath11k-use-frame-mode-for-encap-decap.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/199-001-mac80211-add-nss-support.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/199-002-ath11k_nss-add-nss-driver-interface.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/199-003-ath11k-add-nss-support.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/199-ath11k-Fix-thermal-temperature-read.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/199-mac80211-fix-xmit-callback-when-hwencap-enable-in-st.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/200-ath11k-Add-support-spectral-scan-for-QCN9000.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/201-ath11k-check-valid-fixed-rate-settings.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/201-ath11k-ipq5018-support.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/202-mac80211-Fix-radiotap-channel-flags-for-6GHz.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/203-mac80211-ath11k-fw-dynamic-muedca.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/204-ath11k-fix-invalid-he-rates-in-fixed-rate-setting.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/204-ath11k-support-for-native-160MHz.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/204-frame-size-warning-fix.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/204-mac80211-FILS-discovery-Unsolicited-Bcast-Probe-Resp-Support.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/205-0001-nl80211-add-basic-multiple-bssid-support.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/205-0011-ath11k-fix-mbssid-crash.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/205-monitor-crash-fix.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/205-monitor-ring-stuck-fix.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/206-ath11k-add-6ghz-params-in-peer-assoc-cmd.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/207-ath11k-Add-support-for-dynamic-vlan.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/207-ath11k-Enable-512MB-profile-in-ath11k.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/207-ath11k-allow-multiple-single-rates.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/207-ath11k-changes-for-coredump-scripts.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/207-mac80211-add-nss-redirect-support.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/208-ath11k-add-processor_id-based-ring_selector-logic.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/209-ath11k-set-proper-txpower-maxregpower-values.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/209-fix-wrong-wmi-config-ipq8074.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/209-mac80211-Fix-crash-caused-by-uninitialized-MBSSID-list.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/210-ath11k-Fix-extended-capability-bit-for-Enhanced-Mult.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/210-ath11k-full-mon-support-for-qcn9000.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/210-nl80211-rename-csa-counter-attributes-countdown-coun.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/211-001-ath11k-add-WDS-offload-changes-to-NSS-driver-interface.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/211-002-ath11k-add-WDS-offload-support-on-NSS-offload-for-STA-mode.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/211-ath11k-Resolve-firmware-crash-on-monitor-delete.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/211-ath11k-add-obss-pd-support.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/211-ath11k-use-reserved-memory-from-bootargs.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/211-mac80211-rename-csa-counters-to-countdown-counters.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/212-nl80211-add-support-for-BSS-coloring.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/213-mac80211-add-support-for-BSS-coloring.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/214-ath11k-Enable-WMI-based-FW-Logging.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/214-ath11k-add-support-for-BSS-coloring.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/214-ath11k-qos-null-frame-tx-over-wmi.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/215-ath11k-Add-offchannel-scanning-support.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/215-ath11k-improve-station-wds-performance.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/215-mac80211-restrict-peer-s-HE-capability-to-own.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/216-ath11k-Resolve-fw-crash-caused-by-wrong-peer_nss-con.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/216-ath11k-dont-enable-bss-color-collision-detection-on-non-transmitting-BSS.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/216-ath11k-send-multicast-in-4addr.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/217-mac80211-notify-non-transmitting-BSS-of-color-changes.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/218-ath11k-add-support-to-enable-disable-color-collision.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/219-ath11k-add-bcca-with-countdown-zero-in-color-change-beacon.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/220-mac80211-disable-color-collision-detection-in-case-of-no-free-colors.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/221-ath11k-add-more-htt-stats-support.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/221-ath11k-initialize-vdev_up-params-to-avoid-invalid-values.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/222-ath11k-add-module-param-for-ftm.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/223-fix-rmmod-failure-on-qmi-sequence-failure.patch create mode 100644 feeds/wifi-ax/mac80211/patches/qca/224-ath11k-update-HT-cap-to-disable-TX-STBC-with-single-antenna.patch create mode 100755 feeds/wifi-ax/mac80211/scripts/import-backports.sh create mode 100644 patches/0001-.gitignore-add-the-profiles-folder.patch create mode 100644 patches/0002-Revert-toolchain-gcc-Remove-support-for-GCC-5.patch create mode 100644 patches/0003-pending-scripts-add-gen_config.py.patch create mode 100644 patches/0004-scripts-update-feed-script.patch create mode 100644 patches/0005-scripts-ubinize-image.sh-allow-setting-the-rootfs-na.patch create mode 100644 patches/0006-base-files-set-default-password-to-openwifi.patch create mode 100644 patches/0007-base-files-update-banner.patch create mode 100644 patches/0008-base-files-add-the-wlan-ap-repo-hash.patch create mode 100644 patches/0009-base-files-make-sysupgrade-work-on-qcom-AX.patch create mode 100644 patches/0010-base-files-add-support-for-v4.4-style-netdev-led-tri.patch create mode 100644 patches/0011-busybox-enable-the-watchdog-tool.patch create mode 100644 patches/0012-dnsmasq-turn-the-base-uci-section-into-a-named-one.patch create mode 100644 patches/0013-ubox-add-log-priority-filtering.patch create mode 100644 patches/0014-firewall-tune-lan-wan-into-named-sections.patch create mode 100644 patches/0015-ipq807x-buildsystem-patches-required-by-the-target.patch create mode 100644 patches/0016-linux-modules-fix-some-v4.4-dependencies.patch create mode 100644 patches/0017-ipq807x-add-the-Qualcomm-AX-target-support.patch create mode 100644 patches/0018-Revert-lldpd-bump-to-1.0.7.patch create mode 100644 patches/0019-lldp-add-TIP-tweaks.patch create mode 100644 patches/0020-ramips-make-wifi-work.patch create mode 100644 patches/0021-realtek-fix-SFP-support-on-zyxel-gs1900-10hp.patch create mode 100644 patches/0022-base-files-add-sysctl-to-reboot-upon-OOM.patch create mode 100644 patches/0023-ipq40xx-add-ath10k-ct-fw.cfg-stubs.patch create mode 100644 profiles/container.yml create mode 100644 profiles/e8450.yml create mode 100644 profiles/ea8300.yml create mode 100644 profiles/eap101.yml create mode 100644 profiles/eap102.yml create mode 100644 profiles/edgecore_ecs4100-12ph.yml create mode 100644 profiles/gs110tpp.yml create mode 100644 profiles/p4.yml create mode 100644 profiles/realtek.yml create mode 100644 profiles/rpi.yml create mode 100644 profiles/ucentral-ap.yml create mode 100644 profiles/ucentral-switch.yml create mode 100644 profiles/webui.yml create mode 100644 profiles/wf188n.yml create mode 100644 profiles/wf194c.yml create mode 100644 profiles/wifi-ax.yml create mode 100644 profiles/zyxel_gs1900-10hp.yml create mode 100755 setup.py 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 0000000000000000000000000000000000000000..da083e8597c3baebb5858db73b0eda07ce070ec1 GIT binary patch literal 796196 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�G*Zfumr0JYCWW%9Vd*--?am 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

Lmpe=NzOjSIn~*e_fzI2 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⪼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
    3z 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", SW_API_FLOW_CTRL_SET, NULL}, + {"mgmt", "get", "get flow mgmt", " ", SW_API_FLOW_CTRL_GET, NULL}, + {"entry", "add", "add flow entry", "", SW_API_FLOW_ENTRY_ADD, NULL}, + {"entry", "del", "del flow entry", "", SW_API_FLOW_ENTRY_DEL, NULL}, + {"entry", "get", "get flow entry", "", SW_API_FLOW_ENTRY_GET, NULL}, + {"flowipv43tuple", "show", "show flow ipv4 3 tuple entries", "", SW_CMD_FLOW_IPV43T_SHOW, cmd_show_flow_ipv4_3tuple}, + {"flowipv45tuple", "show", "show flow ipv4 5 tuple entries", "", SW_CMD_FLOW_IPV45T_SHOW, cmd_show_flow_ipv4_5tuple}, + {"flowipv63tuple", "show", "show flow ipv6 3 tuple entries", "", SW_CMD_FLOW_IPV63T_SHOW, cmd_show_flow_ipv6_3tuple}, + {"flowipv65tuple", "show", "show flow ipv6 5 tuple entries", "", SW_CMD_FLOW_IPV65T_SHOW, cmd_show_flow_ipv6_5tuple}, + {"host", "add", "add flow host entry", "", SW_API_FLOW_HOST_ADD, NULL}, + {"host", "del", "del flow host entry", "", SW_API_FLOW_HOST_DEL, NULL}, + {"host", "get", "get flow host entry", "", SW_API_FLOW_HOST_GET, NULL}, + {"global", "get", "get flow global cfg", "", SW_API_FLOW_GLOBAL_CFG_GET, NULL}, + {"global", "set", "set flow global cfg", "", SW_API_FLOW_GLOBAL_CFG_SET, NULL}, + {NULL, NULL, NULL, NULL, SW_API_INVALID, NULL}/*end of desc*/ + }, + }, +#endif + + /* NAT */ +#ifdef IN_NAT + { + "nat", "config nat", + { + {"natentry", "add", "add nat entry", "", SW_API_NAT_ADD, NULL}, + {"natentry", "del", "del nat entry", "", SW_API_NAT_DEL, NULL}, + {"natentry", "get", "get nat entry", "", SW_API_NAT_GET, NULL}, + {"natentry", "next", "next nat entry", "", SW_API_NAT_NEXT, NULL}, + {"natentry", "show", "show whole nat entries", "", SW_CMD_NAT_SHOW, cmd_show_nat}, + {"natentry", "bindcnt", "bind counter to nat entry", " ", SW_API_NAT_COUNTER_BIND, NULL}, + {"naptentry", "add", "add napt entry", "", SW_API_NAPT_ADD, NULL}, + {"naptentry", "del", "del napt entry", "", SW_API_NAPT_DEL, NULL}, + {"naptentry", "get", "get napt entry", "", SW_API_NAPT_GET, NULL}, + {"naptentry", "next", "next napt entry", "", SW_API_NAPT_NEXT, NULL}, + {"naptentry", "show", "show whole napt entries", "", SW_CMD_NAPT_SHOW, cmd_show_napt}, + {"naptentry", "bindcnt", "bind counter to napt entry", " ", SW_API_NAPT_COUNTER_BIND, NULL}, + {"flowentry", "add", "add flow entry", "", SW_API_FLOW_ADD, NULL}, + {"flowentry", "del", "del flow entry", "", SW_API_FLOW_DEL, NULL}, + {"flowentry", "get", "get flow entry", "", SW_API_FLOW_GET, NULL}, + {"flowentry", "next", "next flow entry", "", SW_API_FLOW_NEXT, NULL}, + {"flowentry", "show", "show whole flow entries", "", SW_CMD_FLOW_SHOW, cmd_show_flow}, + {"flowentry", "bindcnt", "bind counter to flow entry", " ", SW_API_FLOW_COUNTER_BIND, NULL}, + {"natstatus", "set", "set nat status", "", SW_API_NAT_STATUS_SET, NULL}, + {"natstatus", "get", "get nat status", "", SW_API_NAT_STATUS_GET, NULL}, + {"naptstatus", "set", "set napt status", "", SW_API_NAPT_STATUS_SET, NULL}, + {"naptstatus", "get", "get napt status", "", SW_API_NAPT_STATUS_GET, NULL}, + {"nathash", "set", "set nat hash mode", "", SW_API_NAT_HASH_MODE_SET, NULL}, + {"nathash", "get", "get nat hash mode", "", SW_API_NAT_HASH_MODE_GET, NULL}, + {"naptmode", "set", "set napt mode", "", SW_API_NAPT_MODE_SET, NULL}, + {"naptmode", "get", "get napt mode", "", SW_API_NAPT_MODE_GET, NULL}, + {"prvbaseaddr", "set", "set nat prv base address", "", SW_API_PRV_BASE_ADDR_SET, NULL}, + {"prvbaseaddr", "get", "get nat prv base address", "", SW_API_PRV_BASE_ADDR_GET, NULL}, + {"prvaddrmode", "set", "set nat prv address map mode", "", SW_API_PRV_ADDR_MODE_SET, NULL}, + {"prvaddrmode", "get", "get nat prv address map mode", "", SW_API_PRV_ADDR_MODE_GET, NULL}, + {"pubaddr", "add", "add pub address", "", SW_API_PUB_ADDR_ENTRY_ADD, NULL}, + {"pubaddr", "del", "del pub address", "", SW_API_PUB_ADDR_ENTRY_DEL, NULL}, + {"pubaddr", "show", "show whole pub address entries", "", SW_CMD_PUBADDR_SHOW, cmd_show_pubaddr}, + {"natunksess", "set", "set nat unkown session command", "", SW_API_NAT_UNK_SESSION_CMD_SET, NULL}, + {"natunksess", "get", "get nat unkown session command", "", SW_API_NAT_UNK_SESSION_CMD_GET, NULL}, + {"prvbasemask", "set", "set nat prv base mask", "", SW_API_PRV_BASE_MASK_SET, NULL}, + {"prvbasemask", "get", "get nat prv base mask", "", SW_API_PRV_BASE_MASK_GET, NULL}, + {"global", "set", "set global nat function", " ", SW_API_NAT_GLOBAL_SET, NULL}, + {"flowcookie", "set", "set flow cookie", "", SW_API_FLOW_COOKIE_SET, NULL}, + {"flowrfs", "set", "set flow rfs", "", SW_API_FLOW_RFS_SET, NULL}, + {NULL, NULL, NULL, NULL, SW_API_INVALID, NULL}/*end of desc*/ + }, + }, +#endif + + /*Trunk*/ +#ifdef IN_TRUNK + { + "trunk", "config trunk", + { + {"group", "set", "set trunk group member info", " ", SW_API_TRUNK_GROUP_SET, NULL}, + {"group", "get", "get trunk group member info", "", SW_API_TRUNK_GROUP_GET, NULL}, + {"hashmode", "set", "set trunk hash mode", "", SW_API_TRUNK_HASH_SET, NULL}, + {"hashmode", "get", "get trunk hash mode", "", SW_API_TRUNK_HASH_GET, NULL}, + {"mansa", "set", "set trunk manipulable sa", "", SW_API_TRUNK_MAN_SA_SET, NULL}, + {"mansa", "get", "get trunk manipulable sa", "", SW_API_TRUNK_MAN_SA_GET, NULL}, + {"failover", "set", "set failover status of trunk", " ", SW_API_TRUNK_FAILOVER_EN_SET, NULL}, + {"failover", "get", "get failover status of trunk", "", SW_API_TRUNK_FAILOVER_EN_GET, NULL}, + {NULL, NULL, NULL, NULL, SW_API_INVALID, NULL}/*end of desc*/ + }, + }, +#endif + + /*Interface Control*/ +#ifdef IN_INTERFACECONTROL + { + "interface", "config interface", + { + {"macmode", "set", "set mac mode info", "", SW_API_MAC_MODE_SET, NULL}, + {"macmode", "get", "get mac mode info", "", SW_API_MAC_MODE_GET, NULL}, + {"pt3azstatus", "set", "get mac mode info", " ", SW_API_PORT_3AZ_STATUS_SET, NULL}, + {"pt3azstatus", "get", "get mac mode info", "", SW_API_PORT_3AZ_STATUS_GET, NULL}, + {"phymode", "set", "set phy mode info", "", SW_API_PHY_MODE_SET, NULL}, + {"phymode", "get", "get phy mode info", "", SW_API_PHY_MODE_GET, NULL}, + {"fx100ctrl", "set", "set fx100 config", "", SW_API_FX100_CTRL_SET, NULL}, + {"fx100ctrl", "get", "get fx100 config", "", SW_API_FX100_CTRL_GET, NULL}, + {"fx100status", "get", "get fx100 status", "", SW_API_FX100_STATUS_GET, NULL}, + {"mac06exch", "set", "set mac0 and mac6 exchange status", "", SW_API_MAC06_EXCH_SET, NULL}, + {"mac06exch", "get", "get mac0 and mac6 exchange status", "", SW_API_MAC06_EXCH_GET, NULL}, + {NULL, NULL, NULL, NULL, SW_API_INVALID, NULL}/*end of desc*/ + }, + }, +#endif + +#ifdef IN_VSI + { + "vsi", "config vsi", + { + {"vsiid", "alloc", "Alloc new vsi", "", SW_API_VSI_ALLOC, NULL}, + {"vsiid", "free", "Free vsi", "", SW_API_VSI_FREE, NULL}, + {"portbasedvsi", "set", "Set port based vsi", " ", SW_API_PORT_VSI_SET, NULL}, + {"portbasedvsi", "get", "Get port based vsi", "", SW_API_PORT_VSI_GET, NULL}, + {"vlanbasedvsi", "set", "Set vlan vsi", " ", SW_API_PORT_VLAN_VSI_SET, NULL}, + {"vlanbasedvsi", "get", "Get vlan vsi", " ", SW_API_PORT_VLAN_VSI_GET, NULL}, + {"table", "dump", "Dump VSI SW and HW table", "", SW_API_VSI_TBL_DUMP, NULL}, + {"learnctrl", "set", "Set vsi based new address learn", " ", SW_API_VSI_NEWADDR_LRN_SET, NULL}, + {"learnctrl", "get", "Get vsi based new address learn", "", SW_API_VSI_NEWADDR_LRN_GET, NULL}, + {"stationmove", "set", "Set vsi based station move", " ", SW_API_VSI_STAMOVE_SET, NULL}, + {"stationmove", "get", "Get vsi based station move", "", SW_API_VSI_STAMOVE_GET, NULL}, + {"member", "set", "Set vsi based member ports", " ", SW_API_VSI_MEMBER_SET, NULL}, + {"member", "get", "Get vsi based member ports", "", SW_API_VSI_MEMBER_GET, NULL}, + {"counter", "get", "Get vsi based counter", "", SW_API_VSI_COUNTER_GET, NULL}, + {"counter", "cleanup", "Cleanup vsi based counter", "", SW_API_VSI_COUNTER_CLEANUP, NULL}, + {NULL, NULL, NULL, NULL, SW_API_INVALID, NULL}/*end of desc*/ + }, + }, +#endif + + /*QM*/ +#ifdef IN_QM + { + "qm", "config qm", + { + {"ucastqbase", "set", "set unicast queue base and profile", " ", SW_API_UCAST_QUEUE_BASE_PROFILE_SET, NULL}, + {"ucastqbase", "get", "get unicast queue base and profile", "", SW_API_UCAST_QUEUE_BASE_PROFILE_GET, NULL}, + {"ucastpriclass", "set", "set unicast pri class", " ", SW_API_UCAST_PRIORITY_CLASS_SET, NULL}, + {"ucastpriclass", "get", "get unicast pri class", " ", SW_API_UCAST_PRIORITY_CLASS_GET, NULL}, + {"mcastpriclass", "set", "set mcast pri class", " ", SW_API_MCAST_PRIORITY_CLASS_SET, NULL}, + {"mcastpriclass", "get", "get mcast pri class", " ", SW_API_MCAST_PRIORITY_CLASS_GET, NULL}, + {"queue", "flush", "flush queue", " ", SW_API_QUEUE_FLUSH, NULL}, + {"ucasthash", "set", "set unicast queue hash", " ", SW_API_UCAST_HASH_MAP_SET, NULL}, + {"ucasthash", "get", "get unicast queue hash", " ", SW_API_UCAST_HASH_MAP_GET, NULL}, + {"ucastdflthash", "set", "set unicast queue dflt hash", "", SW_API_UCAST_DFLT_HASH_MAP_SET, NULL}, + {"ucastdflthash", "get", "get unicast queue dflt hash", "", SW_API_UCAST_DFLT_HASH_MAP_GET, NULL}, + {"mcastcpucode", "set", "set mcast cpucode map", " ", SW_API_MCAST_CPUCODE_CLASS_SET, NULL}, + {"mcastcpucode", "get", "get mcast cpucode map", "", SW_API_MCAST_CPUCODE_CLASS_GET, NULL}, + {"acctrl", "set", "set ac ctrl", " ", SW_API_AC_CTRL_SET, NULL}, + {"acctrl", "get", "get ac ctrl", "", SW_API_AC_CTRL_GET, NULL}, + {"acprebuffer", "set", "set ac prealloc", " ", SW_API_AC_PRE_BUFFER_SET, NULL}, + {"acprebuffer", "get", "get ac prealloc", "", SW_API_AC_PRE_BUFFER_GET, NULL}, + {"acqgroup", "set", "set ac queue group", " ", SW_API_QUEUE_GROUP_SET, NULL}, + {"acqgroup", "get", "get ac queue group", "", SW_API_QUEUE_GROUP_GET, NULL}, + {"acstaticthresh", "set", "set ac static thresh", " ", SW_API_STATIC_THRESH_SET, NULL}, + {"acstaticthresh", "get", "get ac static thresh", "", SW_API_STATIC_THRESH_GET, NULL}, + {"acdynamicthresh", "set", "set ac dynamic thresh", " ", SW_API_DYNAMIC_THRESH_SET, NULL}, + {"acdynamicthresh", "get", "get ac dynamic thresh", "", SW_API_DYNAMIC_THRESH_GET, NULL}, + {"acgroupbuff", "set", "set ac group buffer", " ", SW_API_GOURP_BUFFER_SET, NULL}, + {"acgroupbuff", "get", "get ac group buffer", "", SW_API_GOURP_BUFFER_GET, NULL}, + {"cntctrl", "get", "get queue counter enable flag", "", SW_API_QUEUE_CNT_CTRL_GET, NULL}, + {"cntctrl", "set", "set queue counter enable flag", "", SW_API_QUEUE_CNT_CTRL_SET, NULL}, + {"cnt", "get", "get queue counter", "", SW_API_QUEUE_CNT_GET, NULL}, + {"cnt", "cleanup", "cleanup queue counter", "", SW_API_QUEUE_CNT_CLEANUP, NULL}, + {"enqueue", "set", "set enqueue control", " ", SW_API_QM_ENQUEUE_CTRL_SET, NULL}, + {"enqueue", "get", "get enqueue control", "", SW_API_QM_ENQUEUE_CTRL_GET, NULL}, + {"srcprofile", "set", "set source profile", " ", SW_API_QM_SOURCE_PROFILE_SET, NULL}, + {"srcprofile", "get", "get source profile", "", SW_API_QM_SOURCE_PROFILE_GET, NULL}, + {NULL, NULL, NULL, NULL, SW_API_INVALID, NULL}/*end of desc*/ + }, + }, +#endif + + /*Ctrlpkt Control*/ +#ifdef IN_CTRLPKT + { + "ctrlpkt", "config control packet", + { + {"ethernettype", "set", "set ethernet type profile", " ", SW_API_MGMTCTRL_ETHTYPE_PROFILE_SET, NULL}, + {"ethernettype", "get", "get ethernet type profile", "", SW_API_MGMTCTRL_ETHTYPE_PROFILE_GET, NULL}, + {"rfdb", "set", "set rfdb profile", " ", SW_API_MGMTCTRL_RFDB_PROFILE_SET, NULL}, + {"rfdb", "get", "get rfdb profile", "", SW_API_MGMTCTRL_RFDB_PROFILE_GET, NULL}, + {"appprofile", "add", "add app profile entry", "", SW_API_MGMTCTRL_CTRLPKT_PROFILE_ADD, NULL}, + {"appprofile", "del", "del app profile entry", "", SW_API_MGMTCTRL_CTRLPKT_PROFILE_DEL, NULL}, + {"appprofile", "getfirst", "get first app profile entry", "", SW_API_MGMTCTRL_CTRLPKT_PROFILE_GETFIRST, NULL}, + {"appprofile", "getnext", "get next app profile entry", "", SW_API_MGMTCTRL_CTRLPKT_PROFILE_GETNEXT, NULL}, + {"appprofile", "show", "show whole app profile entries", "", SW_CMD_CTRLPKT_SHOW, cmd_show_ctrlpkt}, + {NULL, NULL, NULL, NULL, SW_API_INVALID, NULL}/*end of desc*/ + }, + }, +#endif + + /*Servcode Control*/ +#ifdef IN_SERVCODE + { + "servcode", "config service profile", + { + {"Config", "set", "set a servcode config by index", "", SW_API_SERVCODE_CONFIG_SET, NULL}, + {"Config", "get", "get a servcode config by index", "", SW_API_SERVCODE_CONFIG_GET, NULL}, + {"Loopcheck", "set", "set servcode loopcheck status", "", SW_API_SERVCODE_LOOPCHECK_EN, NULL}, + {"Loopcheck", "get", "get servcode loopcheck status", "", SW_API_SERVCODE_LOOPCHECK_STATUS_GET, NULL}, + {NULL, NULL, NULL, NULL, SW_API_INVALID, NULL}/*end of desc*/ + }, + }, +#endif + + /*RSS HASH*/ +#ifdef IN_RSS_HASH + { + "rsshash", "config rss hash code", + { + {"Config", "set", "set ipv4/ipv6 rss hash code", "", SW_API_RSS_HASH_CONFIG_SET, NULL}, + {"Config", "get", "get ipv4/ipv6 rss hash code", "", SW_API_RSS_HASH_CONFIG_GET, NULL}, + {NULL, NULL, NULL, NULL, SW_API_INVALID, NULL}/*end of desc*/ + }, + }, +#endif + +#ifdef IN_POLICER + { + "policer", "config policer", + { + {"timeslot", "set", "Set timeslot value", " ", SW_API_POLICER_TIMESLOT_SET, NULL}, + {"timeslot", "get", "Get timeslot value", "", SW_API_POLICER_TIMESLOT_GET, NULL}, + {"portcounter", "get", "Get port policer statistics", "", SW_API_POLICER_PORT_COUNTER_GET, NULL}, + {"aclcounter", "get", "Get acl policer statistics", "", SW_API_POLICER_ACL_COUNTER_GET, NULL}, + {"fcscompensation", "set", "Set port policer compensation byte", " ", SW_API_POLICER_COMPENSATION_SET, NULL}, + {"fcscompensation", "get", "Get port policer compensation byte", "", SW_API_POLICER_COMPENSATION_GET, NULL}, + {"portentry", "set", "Set port policer entry", "", SW_API_POLICER_PORT_ENTRY_SET, NULL}, + {"portentry", "get", "Get port policer entry", "", SW_API_POLICER_PORT_ENTRY_GET, NULL}, + {"aclentry", "set", "Set acl policer entry", "", SW_API_POLICER_ACL_ENTRY_SET, NULL}, + {"aclentry", "get", "Get acl policer entry", "", SW_API_POLICER_ACL_ENTRY_GET, NULL}, + {"globalcounter", "get", "Get policer global counter", "", SW_API_POLICER_GLOBAL_COUNTER_GET, NULL}, + {NULL, NULL, NULL, NULL, SW_API_INVALID, NULL}/*end of desc*/ + }, + }, +#endif + +#ifdef IN_SHAPER + { + "shaper", "config shaper", + { + {"porttimeslot", "set", "Set port shaper timeslot value", " ", SW_API_PORT_SHAPER_TIMESLOT_SET, NULL}, + {"porttimeslot", "get", "Get port shaper timeslot value", "", SW_API_PORT_SHAPER_TIMESLOT_GET, NULL}, + {"flowtimeslot", "set", "Set flow shaper timeslot value", " ", SW_API_FLOW_SHAPER_TIMESLOT_SET, NULL}, + {"flowtimeslot", "get", "Get flow shaper timeslot value", "", SW_API_FLOW_SHAPER_TIMESLOT_GET, NULL}, + {"queuetimeslot", "set", "Set queue shaper timeslot value", " ", SW_API_QUEUE_SHAPER_TIMESLOT_SET, NULL}, + {"queuetimeslot", "get", "Get queue shaper timeslot value", "", SW_API_QUEUE_SHAPER_TIMESLOT_GET, NULL}, + {"porttoken", "set", "Set port shaper token value", " ", SW_API_PORT_SHAPER_TOKEN_NUMBER_SET, NULL}, + {"porttoken", "get", "Get port shaper token value", "", SW_API_PORT_SHAPER_TOKEN_NUMBER_GET, NULL}, + {"flowtoken", "set", "Set flow shaper token value", " ", SW_API_FLOW_SHAPER_TOKEN_NUMBER_SET, NULL}, + {"flowtoken", "get", "Get flow shaper token value", "", SW_API_FLOW_SHAPER_TOKEN_NUMBER_GET, NULL}, + {"queuetoken", "set", "Set queue shaper token value", " ", SW_API_QUEUE_SHAPER_TOKEN_NUMBER_SET, NULL}, + {"queuetoken", "get", "Get queue shaper token value", "", SW_API_QUEUE_SHAPER_TOKEN_NUMBER_GET, NULL}, + {"portshaper", "set", "Set port shaper entry", " ", SW_API_PORT_SHAPER_SET, NULL}, + {"portshaper", "get", "Get port shaper entry", " ", SW_API_PORT_SHAPER_GET, NULL}, + {"flowshaper", "set", "Set flow shaper entry", " ", SW_API_FLOW_SHAPER_SET, NULL}, + {"flowshaper", "get", "Get flow shaper entry", " ", SW_API_FLOW_SHAPER_GET, NULL}, + {"queueshaper", "set", "Set queue shaper entry", " ", SW_API_QUEUE_SHAPER_SET, NULL}, + {"queueshaper", "get", "Get queue shaper entry", " ", SW_API_QUEUE_SHAPER_GET, NULL}, + {"ipgcompensation", "set", "Set shaper IPG and Preamble value", " ", SW_API_SHAPER_IPG_PRE_SET, NULL}, + {"ipgcompensation", "get", "Get port shaper IPG and Preamble value", "", SW_API_SHAPER_IPG_PRE_GET, NULL}, + {NULL, NULL, NULL, NULL, SW_API_INVALID, NULL}/*end of desc*/ + }, + }, +#endif + +/*BM*/ +#ifdef IN_BM + { + "bm", "config bm", + { + {"ctrl", "set", "set flowctrl mode", " ", SW_API_BM_CTRL_SET, NULL}, + {"ctrl", "get", "get flowctrl mode", "", SW_API_BM_CTRL_GET, NULL}, + {"portgroupmap", "set", "set port group mapping", " ", SW_API_BM_PORTGROUP_MAP_SET, NULL}, + {"portgroupmap", "get", "get port group mapping", "", SW_API_BM_PORTGROUP_MAP_GET, NULL}, + {"groupbuff", "set", "set group buffer", " ", SW_API_BM_GROUP_BUFFER_SET, NULL}, + {"groupbuff", "get", "get group buffer", "", SW_API_BM_GROUP_BUFFER_GET, NULL}, + {"portrsvbuff", "set", "set port reserved buffer", " ", SW_API_BM_PORT_RSVBUFFER_SET, NULL}, + {"portrsvbuff", "get", "get port reserved buffer", "", SW_API_BM_PORT_RSVBUFFER_GET, NULL}, + {"portsthresh", "set", "set port static threshold", "", SW_API_BM_STATIC_THRESH_SET, NULL}, + {"portsthresh", "get", "get port static threshold", "", SW_API_BM_STATIC_THRESH_GET, NULL}, + {"portdthresh", "set", "set port dynamic threshold", "", SW_API_BM_DYNAMIC_THRESH_SET, NULL}, + {"portdthresh", "get", "get port dynamic threshold", "", SW_API_BM_DYNAMIC_THRESH_GET, NULL}, + {"portcounter", "get", "get port counter", "", SW_API_BM_PORT_COUNTER_GET, NULL}, + {NULL, NULL, NULL, NULL, SW_API_INVALID, NULL}/*end of desc*/ + }, + }, +#endif +/*qca808x_start*/ + /* debug */ + { + "debug", "read/write register", + { + {"phy", "get", "read phy register", " ", SW_API_PHY_GET, NULL}, + {"phy", "set", "write phy register", " ", SW_API_PHY_SET, NULL}, +/*qca808x_end*/ + {"reg", "get", "read switch register", " <4>", SW_API_REG_GET, NULL}, + {"reg", "set", "write switch register", " <4>", SW_API_REG_SET, NULL}, + {"reg", "dump", "dump switch register group", " <0-6>", SW_API_REG_DUMP, NULL}, + {"dbgreg", "dump", "dump switch dbg register group", "", SW_API_DBG_REG_DUMP, NULL}, + {"psgmii", "selftest", "ess switch psgmii self test", " ", SW_API_DBG_PSGMII_SELF_TEST, NULL}, + {"phy", "dump", "dump phy register group", " <0-4>", SW_API_PHY_DUMP, NULL}, + {"preg", "get", "read psgmii register", " <4>", SW_API_PSGMII_REG_GET, NULL}, + {"preg", "set", "write psgmii register", " <4>", SW_API_PSGMII_REG_SET, NULL}, + {"field", "get", "read switch register field", " <4>", SW_API_REG_FIELD_GET, NULL}, + {"field", "set", "write switch register field", " <4>", SW_API_REG_FIELD_SET, NULL}, + {"aclList", "dump", "dump all acl list", "", SW_API_ACL_LIST_DUMP, NULL}, + {"aclRule", "dump", "dump all acl rule", "", SW_API_ACL_RULE_DUMP, NULL}, + {"device", "reset", "reset device", "", SW_API_SWITCH_RESET, NULL}, + {"module_func", "set", "set the module function bitmap", "", SW_API_MODULE_FUNC_CTRL_SET, NULL}, + {"module_func", "get", "set the module function bitmap", "", SW_API_MODULE_FUNC_CTRL_GET, NULL}, + {"ssdk", "config", "show ssdk configuration", "", SW_API_SSDK_CFG, NULL}, + {"portCounterEn", "get", "get counter status based on port", "", SW_API_DEBUG_PORT_COUNTER_STATUS_GET, NULL}, + {"portCounterEn", "set", "set counter status based on port", "", SW_API_DEBUG_PORT_COUNTER_ENABLE, NULL}, +/*qca808x_start*/ + {"phycounter", "set", "set counter status of a port", " ", SW_API_DEBUG_PHYCOUNTER_SET, NULL}, + {"phycounter", "get", "get counter status of a port", "", SW_API_DEBUG_PHYCOUNTER_GET, NULL}, + {"phycounter", "show", "show counter of a port", "", SW_API_DEBUG_PHYCOUNTER_SHOW, NULL}, +/*qca808x_end*/ + {"uniphy", "get", "read uniphy register", " <4>", SW_API_UNIPHY_REG_GET, NULL}, + {"uniphy", "set", "write uniphy register", " <4>", SW_API_UNIPHY_REG_SET, NULL}, +/*qca808x_start*/ + {NULL, NULL, NULL, NULL, SW_API_INVALID, NULL}/*end of desc*/ + }, + }, +/*qca808x_end*/ + /*debug*/ + { + "device", "set device id", + { + {"id", "set", "set device id", "", SW_CMD_SET_DEVID, cmd_set_devid}, + {NULL, NULL, NULL, NULL, SW_API_INVALID, NULL}/*end of desc*/ + }, + }, + + /* PTP */ +#ifdef IN_PTP + { + "ptp", "config ptp", + { + {"Config", "set", "set PTP config", "", + SW_API_PTP_CONFIG_SET, NULL}, + {"Config", "get", "get PTP config", "", + SW_API_PTP_CONFIG_GET, NULL}, + {"ReferenceClock", "set", "set PTP reference clock", + " ", + SW_API_PTP_REFERENCE_CLOCK_SET, NULL}, + {"ReferenceClock", "get", "get PTP reference clock", "", + SW_API_PTP_REFERENCE_CLOCK_GET, NULL}, + {"RxTimestampMode", "set", "set PTP RX side timestamp mode", + " ", + SW_API_PTP_RX_TIMESTAMP_MODE_SET, NULL}, + {"RxTimestampMode", "get", "get PTP RX side timestamp mode", + "", SW_API_PTP_RX_TIMESTAMP_MODE_GET, NULL}, + {"Timestamp", "get", "get PTP RX/TX side timestamp", + " ", SW_API_PTP_TIMESTAMP_GET, NULL}, + {"PktTimestamp", "set", "set PTP packet received timestamp", + "", SW_API_PTP_PKT_TIMESTAMP_SET, NULL}, + {"PktTimestamp", "get", "get PTP packet received timestamp", + "", SW_API_PTP_PKT_TIMESTAMP_GET, NULL}, + {"GrandmasterMode", "set", "set PTP grandmaster mode", + "", SW_API_PTP_GRANDMASTER_MODE_SET, NULL}, + {"GrandmasterMode", "get", "get PTP grandmaster mode", + "", SW_API_PTP_GRANDMASTER_MODE_GET, NULL}, + {"Time", "set", "set PTP local RTC time", + "", SW_API_PTP_RTC_TIME_SET, NULL}, + {"Time", "get", "get PTP local RTC time", + "", SW_API_PTP_RTC_TIME_GET, NULL}, + {"Time", "clear", "clear PTP local RTC time", + "", SW_API_PTP_RTC_TIME_CLEAR, NULL}, + {"AdjustTime", "set", "set adjust time to PTP local RTC time", + "", SW_API_PTP_RTC_ADJTIME_SET, NULL}, + {"AdjustFreq", "set", "set adjust frequency of PTP local RTC time", + "", SW_API_PTP_RTC_ADJFREQ_SET, NULL}, + {"AdjustFreq", "get", "get adjust frequency of PTP local RTC time", + "", SW_API_PTP_RTC_ADJFREQ_GET, NULL}, + {"LinkDelay", "set", "set PTP link delay value", + "", SW_API_PTP_LINK_DELAY_SET, NULL}, + {"LinkDelay", "get", "get PTP link delay value", + "", SW_API_PTP_LINK_DELAY_GET, NULL}, + {"Security", "set", "set PTP security value", + "", SW_API_PTP_SECURITY_SET, NULL}, + {"Security", "get", "get PTP security value", + "", SW_API_PTP_SECURITY_GET, NULL}, + {"PPSSigCtrl", "set", "set PTP PPS Signal Control", + "", SW_API_PTP_PPS_SIGNAL_CONTROL_SET, NULL}, + {"PPSSigCtrl", "get", "get PTP PPS Signal Control", + "", SW_API_PTP_PPS_SIGNAL_CONTROL_GET, NULL}, + {"CRCRecalc", "set", "set PTP RX CRC recalculate status", + " ", + SW_API_PTP_RX_CRC_RECALC_SET, NULL}, + {"CRCRecalc", "get", "get PTP RX CRC recalculate status", + "", SW_API_PTP_RX_CRC_RECALC_GET, NULL}, + {"AsymCorrection", "set", "set PTP Asymmetry correction", + "", SW_API_PTP_ASYM_CORRECTION_SET, NULL}, + {"AsymCorrection", "get", "get PTP Asymmetry correction", + "", SW_API_PTP_ASYM_CORRECTION_GET, NULL}, + {"Waveform", "set", "set PTP output waveform", + "", SW_API_PTP_OUTPUT_WAVEFORM_SET, NULL}, + {"Waveform", "get", "get PTP output waveform", + "", SW_API_PTP_OUTPUT_WAVEFORM_GET, NULL}, + {"TimeSnapshot", "set", "set PTP RTC Time Snapshot", + " ", + SW_API_PTP_RTC_TIME_SNAPSHOT_SET, NULL}, + {"TimeSnapshot", "get", "get PTP RTC Time Snapshot", + "", SW_API_PTP_RTC_TIME_SNAPSHOT_GET, NULL}, + {"IncrementSyncFromClock", "set", + "set PTP RTC increment Sync from clock", + " ", + SW_API_PTP_INCREMENT_SYNC_FROM_CLOCK_SET, NULL}, + {"IncrementSyncFromClock", "get", + "get PTP RTC increment Sync from clock", + "", SW_API_PTP_INCREMENT_SYNC_FROM_CLOCK_GET, NULL}, + {"ToDUart", "set", "set PTP TOD UART configuration", + "", SW_API_PTP_TOD_UART_SET, NULL}, + {"ToDUart", "get", "get PTP TOD UART configuration", + "", SW_API_PTP_TOD_UART_GET, NULL}, + {"EnhancedTimestampEngine", "set", "set PTP Enhanced Timestamp Engine", + " ", + SW_API_PTP_ENHANCED_TIMESTAMP_ENGINE_SET, NULL}, + {"EnhancedTimestampEngine", "get", "get PTP Enhanced Timestamp Engine", + " ", + SW_API_PTP_ENHANCED_TIMESTAMP_ENGINE_GET, NULL}, + {"Trigger", "set", "set PTP Trigger configuration", + " ", SW_API_PTP_TRIGGER_SET, NULL}, + {"Trigger", "get", "get PTP Trigger configuration", + " ", SW_API_PTP_TRIGGER_GET, NULL}, + {"Capture", "set", "set PTP Capture configuration", + " ", SW_API_PTP_CAPTURE_SET, NULL}, + {"Capture", "get", "get PTP Capture configuration", + " ", SW_API_PTP_CAPTURE_GET, NULL}, + {"Interrupt", "set", "set PTP Interrupt mask", + "", SW_API_PTP_INTERRUPT_SET, NULL}, + {"Interrupt", "get", "get PTP Interrupt mask", + "", SW_API_PTP_INTERRUPT_GET, NULL}, + {NULL, NULL, NULL, NULL, SW_API_INVALID, NULL}/*end of desc*/ + }, + }, +#endif + /* SFP */ +#ifdef IN_SFP + { + "sfp", "sfp data", + { + {"Data", "get", "get sfp data", "", + SW_API_SFP_DATA_GET, NULL}, + {"Data", "set", "set sfp data", "", + SW_API_SFP_DATA_SET, NULL}, + {"DevType", "get", "get sfp device type", "", + SW_API_SFP_DEV_TYPE_GET, NULL}, + {"TransceiverCode", "get", "get sfp transceiver code", "", + SW_API_SFP_TRANSC_CODE_GET, NULL}, + {"RateEncode", "get", "get sfp rate encode", "", + SW_API_SFP_RATE_ENCODE_GET, NULL}, + {"LinkLength", "get", "get sfp link length", "", + SW_API_SFP_LINK_LENGTH_GET, NULL}, + {"VendorInfo", "get", "get sfp vendor info", "", + SW_API_SFP_VENDOR_INFO_GET, NULL}, + {"LaserWaveLength", "get", "get sfp laser wavelength", "", + SW_API_SFP_LASER_WAVELENGTH_GET, NULL}, + {"Option", "get", "get sfp option", "", + SW_API_SFP_OPTION_GET, NULL}, + {"CtrlRate", "get", "get sfp control rate limit", "", + SW_API_SFP_CTRL_RATE_GET, NULL}, + {"EnhancedCfg", "get", "get sfp enhanced config", "", + SW_API_SFP_ENHANCED_CFG_GET, NULL}, + {"DiagThreshold", "get", "get sfp diagnostic threshold", + "", SW_API_SFP_DIAG_THRESHOLD_GET, NULL}, + {"DiagCalConst", "get", "get sfp diagnostic calibration constants", + "", SW_API_SFP_DIAG_CAL_CONST_GET, NULL}, + {"DiagRealTimeData", "get", "get sfp diagnostic monitor data", + "", SW_API_SFP_DIAG_REALTIME_GET, NULL}, + {"DiagCtrlStatue", "get", "get sfp diagnostic control & status bits", + "", SW_API_SFP_DIAG_CTRL_STATUS_GET, NULL}, + {"DiagAlarmWarnFlag", "get", "get sfp diagnostic alarm warning flag", + "", SW_API_SFP_DIAG_ALARM_WARN_FLAG_GET, NULL}, + {"CheckCode", "get", "get sfp check code", + " ", SW_API_SFP_CHECKCODE_GET, NULL}, + {NULL, NULL, NULL, NULL, SW_API_INVALID, NULL}/*end of desc*/ + }, + }, +#endif +/*qca808x_start*/ + {"help", "type ? get help", {{NULL, NULL, NULL, NULL, SW_API_INVALID, NULL}/*end of desc*/}}, + + {"quit", "type quit/q quit shell", {{NULL, NULL, NULL, NULL, SW_API_INVALID, NULL}/*end of desc*/}}, + + {NULL, NULL, {{NULL, NULL, NULL, NULL, SW_API_INVALID, NULL}}} /*end of desc*/ +}; +/*qca808x_end*/ diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/shell/shell_io.c b/feeds/ipq807x/qca-ssdk-shell/src/src/shell/shell_io.c new file mode 100644 index 000000000..e30051e15 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/shell/shell_io.c @@ -0,0 +1,30033 @@ +/* + * 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. + */ +/*qca808x_start*/ +#include +#include "shell_io.h" +#include "shell.h" + +#define SW_RTN_ON_NULL_PARAM(rtn) \ + do { if ((rtn) == NULL) return SW_BAD_PARAM; } while(0); + +#define DEFAULT_FLAG "default" +static char **full_cmdstrp; +static int talk_mode = 1; + +char g_aclcmd[500] = "\0"; +a_uint32_t g_aclcmd_len = 0;; + +void append_acl_cmd(char * cmd) +{ + if(500 > (g_aclcmd_len+1)) { + g_aclcmd_len += snprintf(g_aclcmd+g_aclcmd_len, 500-g_aclcmd_len, "%s", cmd); + g_aclcmd_len += snprintf(g_aclcmd+g_aclcmd_len, 500-g_aclcmd_len, "%s", " "); + } +} + +int +get_talk_mode(void) +{ + return talk_mode ; +} + +void +set_talk_mode(int mode) +{ + talk_mode = mode; +} + +char ** full_cmdstrp_bak; + +void +set_full_cmdstrp(char **cmdstrp) +{ + full_cmdstrp = cmdstrp; + full_cmdstrp_bak = cmdstrp; +} + +int +get_jump(void) +{ + return (full_cmdstrp-full_cmdstrp_bak); +} + +static char * +get_cmd_buf(char *tag, char *defval) +{ + if(!full_cmdstrp || !(*full_cmdstrp)) + { + dprintf("parameter (%s) or default (%s) absent\n", tag, defval); + exit(1); + } + + if (!strcasecmp(*(full_cmdstrp), DEFAULT_FLAG)) + { + full_cmdstrp++; + return defval; + } + else + { + return *(full_cmdstrp++); + } +} + +static char * +get_cmd_stdin(char *tag, char *defval) +{ + static char gsubcmdstr[256]; + int pos = 0; + int c; + + if(defval) + { + dprintf("%s(%s): ", tag, defval); + } + else + { + dprintf("%s: ", tag); + } + + fflush(stdout); + memset(gsubcmdstr, 0, sizeof(gsubcmdstr)); + + while ((c = getchar()) != '\n') + { + gsubcmdstr[pos++] = c; + if (pos == (sizeof(gsubcmdstr) - 1)) + { + dprintf("too long command\n"); + return NULL; + } + } + + gsubcmdstr[pos] = '\0'; + if ('\0' == gsubcmdstr[0]) + { + return defval; + } + else + { + return gsubcmdstr; + } +} + +static char * +get_sub_cmd(char *tag, char *defval) +{ + if(talk_mode) + return get_cmd_stdin(tag, defval); + else + return get_cmd_buf(tag, defval); +} + + +static inline a_bool_t +is_hex(char c) +{ + if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') + || (c >= 'A' && c <= 'F')) + return A_TRUE; + + return A_FALSE; +} + +static inline a_bool_t +is_dec(char c) +{ + if ((c >= '0') && (c <= '9')) + return A_TRUE; + + return A_FALSE; +} + +static sw_data_type_t sw_data_type[] = +{ + SW_TYPE_DEF(SW_UINT8, cmd_data_check_uint8, cmd_data_print_uint8), + SW_TYPE_DEF(SW_INT8, NULL, NULL), + SW_TYPE_DEF(SW_UINT16, cmd_data_check_uint16, cmd_data_print_uint16), + SW_TYPE_DEF(SW_INT16, NULL, NULL), + SW_TYPE_DEF(SW_UINT32, cmd_data_check_uint32, cmd_data_print_uint32), + SW_TYPE_DEF(SW_INT32, NULL, NULL), + SW_TYPE_DEF(SW_UINT64, cmd_data_check_uint64, cmd_data_print_uint64), + SW_TYPE_DEF(SW_INT64, NULL, NULL), + SW_TYPE_DEF(SW_CAP, cmd_data_check_capable, cmd_data_print_capable), + SW_TYPE_DEF(SW_DUPLEX, cmd_data_check_duplex, cmd_data_print_duplex), + SW_TYPE_DEF(SW_SPEED, cmd_data_check_speed, cmd_data_print_speed), +/*qca808x_end*/ + SW_TYPE_DEF(SW_1QMODE, cmd_data_check_1qmode, cmd_data_print_1qmode), + SW_TYPE_DEF(SW_EGMODE, cmd_data_check_egmode, cmd_data_print_egmode), + SW_TYPE_DEF(SW_MIB, NULL, cmd_data_print_mib), + SW_TYPE_DEF(SW_XGMIB, NULL, cmd_data_print_xgmib), + SW_TYPE_DEF(SW_MIB_CNTR, NULL, cmd_data_print_mib_cntr), + SW_TYPE_DEF(SW_VLAN, cmd_data_check_vlan, cmd_data_print_vlan), + SW_TYPE_DEF(SW_LAN_WAN_CFG, cmd_data_check_lan_wan_cfg, cmd_data_print_lan_wan_cfg), +/*qca808x_start*/ + SW_TYPE_DEF(SW_PBMP, cmd_data_check_pbmp, cmd_data_print_pbmp), + SW_TYPE_DEF(SW_ENABLE, cmd_data_check_enable, cmd_data_print_enable), + SW_TYPE_DEF(SW_MACADDR, cmd_data_check_macaddr, cmd_data_print_macaddr), +/*qca808x_end*/ + SW_TYPE_DEF(SW_FDBENTRY, cmd_data_check_fdbentry, cmd_data_print_fdbentry), + SW_TYPE_DEF(SW_MACLIMIT_CTRL, cmd_data_check_maclimit_ctrl, cmd_data_print_maclimit_ctrl), + SW_TYPE_DEF(SW_SCH, cmd_data_check_qos_sch, cmd_data_print_qos_sch), + SW_TYPE_DEF(SW_QOS, cmd_data_check_qos_pt, cmd_data_print_qos_pt), + SW_TYPE_DEF(SW_STORM, cmd_data_check_storm, cmd_data_print_storm), + SW_TYPE_DEF(SW_STP, cmd_data_check_stp_state, cmd_data_print_stp_state), + SW_TYPE_DEF(SW_LEAKY, cmd_data_check_leaky, cmd_data_print_leaky), + SW_TYPE_DEF(SW_MACCMD, cmd_data_check_maccmd, cmd_data_print_maccmd), + SW_TYPE_DEF(SW_FLOWCMD, cmd_data_check_flowcmd, cmd_data_print_flowcmd), + SW_TYPE_DEF(SW_FLOWTYPE, cmd_data_check_flowtype, cmd_data_print_flowtype), + SW_TYPE_DEF(SW_UINT_A, cmd_data_check_uinta, cmd_data_print_uinta), + SW_TYPE_DEF(SW_ACLRULE, cmd_data_check_aclrule, cmd_data_print_aclrule), + SW_TYPE_DEF(SW_LEDPATTERN, cmd_data_check_ledpattern, cmd_data_print_ledpattern), + SW_TYPE_DEF(SW_MIRR_ANALYSIS_CONFIG, cmd_data_check_mirr_analy_cfg, cmd_data_print_mirr_analy_cfg), + SW_TYPE_DEF(SW_MIRR_DIRECTION, cmd_data_check_mirr_direction, cmd_data_print_mirr_direction), + SW_TYPE_DEF(SW_INVLAN, cmd_data_check_invlan_mode, cmd_data_print_invlan_mode), + SW_TYPE_DEF(SW_VLANPROPAGATION, cmd_data_check_vlan_propagation, cmd_data_print_vlan_propagation), + SW_TYPE_DEF(SW_VLANTRANSLATION, cmd_data_check_vlan_translation, cmd_data_print_vlan_translation), + SW_TYPE_DEF(SW_QINQMODE, cmd_data_check_qinq_mode, cmd_data_print_qinq_mode), + SW_TYPE_DEF(SW_QINQROLE, cmd_data_check_qinq_role, cmd_data_print_qinq_role), +/*qca808x_start*/ + SW_TYPE_DEF(SW_CABLESTATUS, NULL, cmd_data_print_cable_status), + SW_TYPE_DEF(SW_CABLELEN, NULL, cmd_data_print_cable_len), + SW_TYPE_DEF(SW_SSDK_CFG, NULL, cmd_data_print_ssdk_cfg), +/*qca808x_end*/ + SW_TYPE_DEF(SW_HDRMODE, cmd_data_check_hdrmode, cmd_data_print_hdrmode), + SW_TYPE_DEF(SW_FDBOPRATION, cmd_data_check_fdboperation, NULL), + SW_TYPE_DEF(SW_PPPOE, cmd_data_check_pppoe, cmd_data_print_pppoe), + SW_TYPE_DEF(SW_PPPOE_LESS, cmd_data_check_pppoe_less, cmd_data_print_pppoe), + SW_TYPE_DEF(SW_ACL_UDF_TYPE, cmd_data_check_udf_type, cmd_data_print_udf_type), + SW_TYPE_DEF(SW_IP_HOSTENTRY, cmd_data_check_host_entry, cmd_data_print_host_entry), + SW_TYPE_DEF(SW_ARP_LEARNMODE, cmd_data_check_arp_learn_mode, cmd_data_print_arp_learn_mode), + SW_TYPE_DEF(SW_IP_GUARDMODE, cmd_data_check_ip_guard_mode, cmd_data_print_ip_guard_mode), + SW_TYPE_DEF(SW_NATENTRY, cmd_data_check_nat_entry, cmd_data_print_nat_entry), + SW_TYPE_DEF(SW_NAPTENTRY, cmd_data_check_napt_entry, cmd_data_print_napt_entry), + SW_TYPE_DEF(SW_FLOWENTRY, cmd_data_check_flow_entry, cmd_data_print_flow_entry), + SW_TYPE_DEF(SW_NAPTMODE, cmd_data_check_napt_mode, cmd_data_print_napt_mode), + SW_TYPE_DEF(SW_IP4ADDR, cmd_data_check_ip4addr, cmd_data_print_ip4addr), + SW_TYPE_DEF(SW_IP6ADDR, cmd_data_check_ip6addr, cmd_data_print_ip6addr), + SW_TYPE_DEF(SW_INTFMACENTRY, cmd_data_check_intf_mac_entry, cmd_data_print_intf_mac_entry), + SW_TYPE_DEF(SW_PUBADDRENTRY, cmd_data_check_pub_addr_entry, cmd_data_print_pub_addr_entry), + SW_TYPE_DEF(SW_INGPOLICER, cmd_data_check_port_policer, cmd_data_print_port_policer), + SW_TYPE_DEF(SW_EGSHAPER, cmd_data_check_egress_shaper, cmd_data_print_egress_shaper), + SW_TYPE_DEF(SW_ACLPOLICER, cmd_data_check_acl_policer, cmd_data_print_acl_policer), + SW_TYPE_DEF(SW_MACCONFIG, cmd_data_check_mac_config, cmd_data_print_mac_config), + SW_TYPE_DEF(SW_PHYCONFIG, cmd_data_check_phy_config, cmd_data_print_phy_config), + SW_TYPE_DEF(SW_FDBSMODE, cmd_data_check_fdb_smode, cmd_data_print_fdb_smode), + SW_TYPE_DEF(SW_FDB_CTRL_MODE, NULL, cmd_data_print_fdb_ctrl_mode), + SW_TYPE_DEF(SW_FX100CONFIG, cmd_data_check_fx100_config, cmd_data_print_fx100_config), + SW_TYPE_DEF(SW_SGENTRY, cmd_data_check_multi, cmd_data_print_multi), + SW_TYPE_DEF(SW_SEC_MAC, cmd_data_check_sec_mac, NULL), + SW_TYPE_DEF(SW_SEC_IP, cmd_data_check_sec_ip, NULL), + SW_TYPE_DEF(SW_SEC_IP4, cmd_data_check_sec_ip4, NULL), + SW_TYPE_DEF(SW_SEC_IP6, cmd_data_check_sec_ip6, NULL), + SW_TYPE_DEF(SW_SEC_TCP, cmd_data_check_sec_tcp, NULL), + SW_TYPE_DEF(SW_SEC_UDP, cmd_data_check_sec_udp, NULL), + SW_TYPE_DEF(SW_SEC_ICMP4, cmd_data_check_sec_icmp4, NULL), + SW_TYPE_DEF(SW_SEC_ICMP6, cmd_data_check_sec_icmp6, NULL), + SW_TYPE_DEF(SW_REMARKENTRY, cmd_data_check_remark_entry, cmd_data_print_remark_entry), + SW_TYPE_DEF(SW_DEFAULT_ROUTE_ENTRY, cmd_data_check_default_route_entry, cmd_data_print_default_route_entry), + SW_TYPE_DEF(SW_HOST_ROUTE_ENTRY, cmd_data_check_host_route_entry, cmd_data_print_host_route_entry), + SW_TYPE_DEF(SW_IP_WCMP_ENTRY, cmd_data_check_ip_wcmp_entry, cmd_data_print_ip_wcmp_entry), + SW_TYPE_DEF(SW_IP_RFS_IP4, cmd_data_check_ip4_rfs_entry, NULL), + SW_TYPE_DEF(SW_IP_RFS_IP6, cmd_data_check_ip6_rfs_entry, NULL), + SW_TYPE_DEF(SW_FLOWCOOKIE, cmd_data_check_flow_cookie, NULL), + SW_TYPE_DEF(SW_FLOWRFS, cmd_data_check_flow_rfs, NULL), + SW_TYPE_DEF(SW_FDB_RFS, cmd_data_check_fdb_rfs, NULL), +/*qca808x_start*/ + SW_TYPE_DEF(SW_CROSSOVER_MODE, cmd_data_check_crossover_mode, cmd_data_print_crossover_mode), + SW_TYPE_DEF(SW_CROSSOVER_STATUS, cmd_data_check_crossover_status, cmd_data_print_crossover_status), +/*qca808x_end*/ + SW_TYPE_DEF(SW_PORT_EEE_CONFIG, cmd_data_check_port_eee_config, cmd_data_print_port_eee_config), + SW_TYPE_DEF(SW_PREFER_MEDIUM, cmd_data_check_prefer_medium, cmd_data_print_prefer_medium), + SW_TYPE_DEF(SW_FIBER_MODE, cmd_data_check_fiber_mode, cmd_data_print_fiber_mode), + SW_TYPE_DEF(SW_SRC_FILTER_CONFIG, cmd_data_check_src_filter_config, cmd_data_print_src_filter_config), + SW_TYPE_DEF(SW_PORT_LOOPBACK_CONFIG, cmd_data_check_switch_port_loopback_config, cmd_data_print_switch_port_loopback_config), +/*qca808x_start*/ + SW_TYPE_DEF(SW_INTERFACE_MODE, cmd_data_check_interface_mode, cmd_data_print_interface_mode), + SW_TYPE_DEF(SW_COUNTER_INFO, NULL, cmd_data_print_counter_info), + SW_TYPE_DEF(SW_REG_DUMP, NULL, cmd_data_print_register_info), + SW_TYPE_DEF(SW_PHY_DUMP, NULL, cmd_data_print_phy_register_info), + SW_TYPE_DEF(SW_DBG_REG_DUMP, NULL, cmd_data_print_debug_register_info), +/*qca808x_end*/ + SW_TYPE_DEF(SW_VSI_NEWADDR_LRN, cmd_data_check_newadr_lrn, cmd_data_print_newaddr_lrn_entry), + SW_TYPE_DEF(SW_VSI_STAMOVE, cmd_data_check_stamove, cmd_data_print_stamove_entry), + SW_TYPE_DEF(SW_VSI_MEMBER, cmd_data_check_vsi_member, cmd_data_print_vsi_member_entry), + SW_TYPE_DEF(SW_VSI_COUNTER, NULL, cmd_data_print_vsi_counter), + SW_TYPE_DEF(SW_MTU_INFO, NULL, cmd_data_print_mtu_info), + SW_TYPE_DEF(SW_MRU_INFO, NULL, cmd_data_print_mru_info), + SW_TYPE_DEF(SW_MTU_ENTRY, cmd_data_check_mtu_entry, NULL), + SW_TYPE_DEF(SW_MRU_ENTRY, cmd_data_check_mru_entry, NULL), + SW_TYPE_DEF(SW_ARP_SG_CFG, cmd_data_check_arp_sg, cmd_data_print_arp_sg), + SW_TYPE_DEF(SW_IP_NETWORK_ROUTE, cmd_data_check_network_route, cmd_data_print_network_route), + SW_TYPE_DEF(SW_IP_INTF, cmd_data_check_intf, cmd_data_print_intf), + SW_TYPE_DEF(SW_IP_VSI_INTF, cmd_data_check_vsi_intf, cmd_data_print_vsi_intf), + SW_TYPE_DEF(SW_IP_NEXTHOP, cmd_data_check_nexthop, cmd_data_print_nexthop), + SW_TYPE_DEF(SW_UCAST_QUEUE_MAP, cmd_data_check_u_qmap, NULL), + SW_TYPE_DEF(SW_IP_SG, cmd_data_check_ip_sg, cmd_data_print_ip_sg), + SW_TYPE_DEF(SW_IP_PUB, cmd_data_check_ip_pub, cmd_data_print_ip_pub), + SW_TYPE_DEF(SW_IP_PORTMAC, cmd_data_check_ip_portmac, cmd_data_print_ip_portmac), + SW_TYPE_DEF(SW_IP_MCMODE, cmd_data_check_ip_mcmode, cmd_data_print_ip_mcmode), + SW_TYPE_DEF(SW_FLOW_AGE, cmd_data_check_flow_age, cmd_data_print_flow_age), + SW_TYPE_DEF(SW_FLOW_CTRL, cmd_data_check_flow_ctrl, cmd_data_print_flow_ctrl), + SW_TYPE_DEF(SW_STATIC_THRESH, cmd_data_check_ac_static_thresh, cmd_data_print_ac_static_thresh), + SW_TYPE_DEF(SW_DYNAMIC_THRESH, cmd_data_check_ac_dynamic_thresh, cmd_data_print_ac_dynamic_thresh), + SW_TYPE_DEF(SW_GROUP_BUFFER, cmd_data_check_ac_group_buff, cmd_data_print_ac_group_buff), + SW_TYPE_DEF(SW_AC_CTRL, cmd_data_check_ac_ctrl, cmd_data_print_ac_ctrl), + SW_TYPE_DEF(SW_AC_OBJ, cmd_data_check_ac_obj, cmd_data_print_ac_obj), + SW_TYPE_DEF(SW_FLOW_ENTRY, cmd_data_check_flow, cmd_data_print_flow), + SW_TYPE_DEF(SW_FLOW_HOST, cmd_data_check_flow_host, cmd_data_print_flow_host), + SW_TYPE_DEF(SW_IP_GLOBAL, cmd_data_check_ip_global, cmd_data_print_ip_global), + SW_TYPE_DEF(SW_FLOW_GLOBAL, cmd_data_check_flow_global, cmd_data_print_flow_global), + SW_TYPE_DEF(SW_GLOBAL_QINQMODE, cmd_data_check_global_qinqmode, cmd_data_print_global_qinqmode), + SW_TYPE_DEF(SW_PT_QINQMODE, cmd_data_check_port_qinqmode, cmd_data_print_port_qinqmode), + SW_TYPE_DEF(SW_TPID, cmd_data_check_tpid, cmd_data_print_tpid), + SW_TYPE_DEF(SW_INGRESS_FILTER, cmd_data_check_ingress_filter, cmd_data_print_ingress_filter), + SW_TYPE_DEF(SW_PT_DEF_VID_EN, cmd_data_check_port_default_vid_en, cmd_data_print_port_default_vid_en), + SW_TYPE_DEF(SW_PT_VLAN_TAG, cmd_data_check_port_vlan_tag, cmd_data_print_port_vlan_tag), + SW_TYPE_DEF(SW_PT_VLAN_DIRECTION, cmd_data_check_port_vlan_direction, cmd_data_print_port_vlan_direction), + SW_TYPE_DEF(SW_PT_VLAN_TRANS_ADV_RULE, cmd_data_check_port_vlan_translation_adv_rule, cmd_data_print_port_vlan_translation_adv_rule), + SW_TYPE_DEF(SW_PT_VLAN_TRANS_ADV_ACTION, cmd_data_check_port_vlan_translation_adv_action, cmd_data_print_port_vlan_translation_adv_action), + SW_TYPE_DEF(SW_PT_VLAN_COUNTER, NULL, cmd_data_print_port_vlan_counter), + SW_TYPE_DEF(SW_DEBUG_COUNTER_EN, cmd_data_check_debug_port_counter_status, cmd_data_print_debug_port_counter_status), + SW_TYPE_DEF(SW_TAG_PROPAGATION, cmd_data_check_tag_propagation, cmd_data_print_tag_propagation), + SW_TYPE_DEF(SW_EGRESS_MODE, cmd_data_check_egress_mode, cmd_data_print_egress_mode), + SW_TYPE_DEF(SW_CTRLPKT_PROFILE, cmd_data_check_ctrlpkt_profile, cmd_data_print_ctrlpkt_profile), + SW_TYPE_DEF(SW_SERVCODE_CONFIG, cmd_data_check_servcode_config, cmd_data_print_servcode_config), + SW_TYPE_DEF(SW_RSS_HASH_MODE, cmd_data_check_rss_hash_mode, NULL), + SW_TYPE_DEF(SW_RSS_HASH_CONFIG, cmd_data_check_rss_hash_config, cmd_data_print_rss_hash_config), + SW_TYPE_DEF(SW_L3_PARSER, cmd_data_check_l3_parser, cmd_data_print_l3_parser), + SW_TYPE_DEF(SW_L4_PARSER, cmd_data_check_l4_parser, cmd_data_print_l4_parser), + SW_TYPE_DEF(SW_EXP_CTRL, cmd_data_check_exp_ctrl, cmd_data_print_exp_ctrl), + SW_TYPE_DEF(SW_ACL_UDF_PKT_TYPE, cmd_data_check_udf_pkt_type, cmd_data_print_udf_pkt_type), + SW_TYPE_DEF(SW_PORTGROUP, cmd_data_check_port_group, cmd_data_print_port_group), + SW_TYPE_DEF(SW_PORTPRI, cmd_data_check_port_pri, cmd_data_print_port_pri), + SW_TYPE_DEF(SW_PORTREMARK, cmd_data_check_port_remark, cmd_data_print_port_remark), + SW_TYPE_DEF(SW_COSMAP, cmd_data_check_cosmap, cmd_data_print_cosmap), + SW_TYPE_DEF(SW_SCHEDULER, cmd_data_check_queue_scheduler, cmd_data_print_queue_scheduler), + SW_TYPE_DEF(SW_QUEUEBMP, cmd_data_check_ring_queue, cmd_data_print_ring_queue), + SW_TYPE_DEF(SW_PORT_SHAPER_TOKEN_CONFIG, cmd_data_check_port_shaper_token_config, + cmd_data_print_port_shaper_token_config), + SW_TYPE_DEF(SW_SHAPER_TOKEN_CONFIG, cmd_data_check_shaper_token_config, + cmd_data_print_shaper_token_config), + SW_TYPE_DEF(SW_PORT_SHAPER_CONFIG, cmd_data_check_port_shaper_config, + cmd_data_print_port_shaper_config), + SW_TYPE_DEF(SW_SHAPER_CONFIG, cmd_data_check_shaper_config, + cmd_data_print_shaper_config), + SW_TYPE_DEF(SW_BMSTHRESH, cmd_data_check_bm_static_thresh, + cmd_data_print_bm_static_thresh), + SW_TYPE_DEF(SW_BMDTHRESH, cmd_data_check_bm_dynamic_thresh, + cmd_data_print_bm_dynamic_thresh), + SW_TYPE_DEF(SW_BMPORTCNT, NULL, cmd_data_print_bm_port_counter), + SW_TYPE_DEF(SW_MODULE, cmd_data_check_module, cmd_data_print_module), + SW_TYPE_DEF(SW_FUNC_CTRL, cmd_data_check_func_ctrl, cmd_data_print_func_ctrl), + SW_TYPE_DEF(SW_QM_CNT, NULL, cmd_data_print_queue_cnt), + SW_TYPE_DEF(SW_POLICER_ACL_CONFIG, cmd_data_check_acl_policer_config, + cmd_data_print_acl_policer_config), + SW_TYPE_DEF(SW_POLICER_PORT_CONFIG, cmd_data_check_port_policer_config, + cmd_data_print_port_policer_config), + SW_TYPE_DEF(SW_POLICER_CMD_CONFIG, cmd_data_check_policer_cmd_config, + cmd_data_print_policer_cmd_config), + SW_TYPE_DEF(SW_POLICER_COUNTER, NULL, cmd_data_print_policer_counter_infor), + SW_TYPE_DEF(SW_POLICER_GLOBAL_COUNTER, NULL, cmd_data_print_policer_global_counter_infor), + SW_TYPE_DEF(SW_RESOURCE_SCHE, NULL, cmd_data_print_port_scheduler_resource), + SW_TYPE_DEF(SW_PTP_CONFIG, cmd_data_check_ptp_config, cmd_data_print_ptp_config), + SW_TYPE_DEF(SW_PTP_REFERENCE_CLOCK, cmd_data_check_ptp_reference_clock, + cmd_data_print_ptp_reference_clock), + SW_TYPE_DEF(SW_PTP_RX_TIMESTAMP_MODE, cmd_data_check_ptp_rx_timestamp_mode, + cmd_data_print_ptp_rx_timestamp_mode), + SW_TYPE_DEF(SW_PTP_DIRECTION, cmd_data_check_ptp_direction, NULL), + SW_TYPE_DEF(SW_PTP_PKT_INFO, cmd_data_check_ptp_pkt_info, cmd_data_print_ptp_pkt_info), + SW_TYPE_DEF(SW_PTP_TIME, cmd_data_check_ptp_time, cmd_data_print_ptp_time), + SW_TYPE_DEF(SW_PTP_GRANDMASTER_MODE, cmd_data_check_ptp_grandmaster_mode, + cmd_data_print_ptp_grandmaster_mode), + SW_TYPE_DEF(SW_PTP_SECURITY, cmd_data_check_ptp_security, + cmd_data_print_ptp_security), + SW_TYPE_DEF(SW_PTP_PPS_SIGNAL_CONTROL, cmd_data_check_ptp_pps_sig_ctrl, + cmd_data_print_ptp_pps_sig_ctrl), + SW_TYPE_DEF(SW_PTP_ASYM_CORRECTION, cmd_data_check_ptp_asym_correction, + cmd_data_print_ptp_asym_correction), + SW_TYPE_DEF(SW_PTP_OUTPUT_WAVEFORM, cmd_data_check_ptp_waveform, + cmd_data_print_ptp_waveform), + SW_TYPE_DEF(SW_PTP_TOD_UART, cmd_data_check_ptp_tod_uart, + cmd_data_print_ptp_tod_uart), + SW_TYPE_DEF(SW_PTP_ENHANCED_TS_ENGINE, cmd_data_check_ptp_enhanced_timestamp_engine, + cmd_data_print_ptp_enhanced_timestamp_engine), + SW_TYPE_DEF(SW_PTP_TRIGGER, cmd_data_check_ptp_trigger, cmd_data_print_ptp_trigger), + SW_TYPE_DEF(SW_PTP_CAPTURE, cmd_data_check_ptp_capture, cmd_data_print_ptp_capture), + SW_TYPE_DEF(SW_PTP_INTERRUPT, cmd_data_check_ptp_interrupt, cmd_data_print_ptp_interrupt), + SW_TYPE_DEF(SW_SFP_DATA, cmd_data_check_sfp_data, cmd_data_print_sfp_data), + SW_TYPE_DEF(SW_SFP_DEV_TYPE, NULL, cmd_data_print_sfp_dev_type), + SW_TYPE_DEF(SW_SFP_TRANSC_CODE, NULL, cmd_data_print_sfp_transc_code), + SW_TYPE_DEF(SW_SFP_RATE_ENCODE, NULL, cmd_data_print_sfp_rate_encode), + SW_TYPE_DEF(SW_SFP_LINK_LENGTH, NULL, cmd_data_print_sfp_link_length), + SW_TYPE_DEF(SW_SFP_VENDOR_INFO, NULL, cmd_data_print_sfp_vendor_info), + SW_TYPE_DEF(SW_SFP_LASER_WAVELENGTH, NULL, cmd_data_print_sfp_laser_wavelength), + SW_TYPE_DEF(SW_SFP_OPTION, NULL, cmd_data_print_sfp_option), + SW_TYPE_DEF(SW_SFP_CTRL_RATE, NULL, cmd_data_print_sfp_ctrl_rate), + SW_TYPE_DEF(SW_SFP_ENHANCED_CFG, NULL, cmd_data_print_sfp_enhanced_cfg), + SW_TYPE_DEF(SW_SFP_DIAG_THRESHOLD, NULL, cmd_data_print_sfp_diag_threshold), + SW_TYPE_DEF(SW_SFP_DIAG_CAL_CONST, NULL, cmd_data_print_sfp_diag_cal_const), + SW_TYPE_DEF(SW_SFP_DIAG_REALTIME, NULL, cmd_data_print_sfp_diag_realtime), + SW_TYPE_DEF(SW_SFP_CTRL_STATUS, NULL, cmd_data_print_sfp_ctrl_status), + SW_TYPE_DEF(SW_SFP_ALARM_WARN_FLAG, NULL, cmd_data_print_sfp_alarm_warn_flag), + SW_TYPE_DEF(SW_SFP_CCODE_TYPE, cmd_data_check_sfp_ccode_type, NULL), +/*qca808x_start*/ +}; + +sw_data_type_t * +cmd_data_type_find(sw_data_type_e type) +{ + a_uint16_t i = 0; + + do + { + if (type == sw_data_type[i].data_type) + return &sw_data_type[i]; + } + while ( ++i < sizeof(sw_data_type)/sizeof(sw_data_type[0])); + + return NULL; +} + +sw_error_t __cmd_data_check_quit_help(char *cmd, char *usage) +{ + sw_error_t ret = SW_OK; + + if (!strncasecmp(cmd, "quit", 4)) { + return SW_ABORTED; + } else if (!strncasecmp(cmd, "help", 4)) { + dprintf("%s", usage); + ret = SW_BAD_VALUE; + } + + return ret; +} + +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 ret; + char *cmd; + + do { + cmd = get_sub_cmd(info, defval); + SW_RTN_ON_NULL_PARAM(cmd); + + ret = __cmd_data_check_quit_help(cmd, usage); + if (ret == SW_ABORTED) + return ret; + else if (ret == SW_OK) { + ret = chk_func(cmd, arg_val, size); + if (ret) + dprintf("%s", usage); + } + } while (talk_mode && (SW_OK != ret)); + + return SW_OK; +} + +sw_error_t +cmd_data_check_uint8(char *cmd_str, a_uint32_t *arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + + if (0 == cmd_str[0]) + { + return SW_BAD_VALUE; + } + + if (cmd_str[0] == '0' && (cmd_str[1] == 'x' || cmd_str[1] == 'X')) + sscanf(cmd_str, "%x", arg_val); + else + sscanf(cmd_str, "%d", arg_val); + + if (255 < *arg_val) + { + return SW_BAD_PARAM; + } + + return SW_OK; +} + +void +cmd_data_print_uint8(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:0x%x", param_name, *(a_uint8_t *) buf); + +} + + +sw_error_t +cmd_data_check_uint32(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + + if (0 == cmd_str[0]) + { + return SW_BAD_VALUE; + } + + if (strspn(cmd_str, "1234567890abcdefABCDEFXx") != strlen(cmd_str)){ + return SW_BAD_VALUE; + } + + if (cmd_str[0] == '0' && (cmd_str[1] == 'x' || cmd_str[1] == 'X')) + sscanf(cmd_str, "%x", arg_val); + else + sscanf(cmd_str, "%d", arg_val); + + return SW_OK; +} + +void +cmd_data_print_uint32(a_char_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:0x%x", param_name, *(a_uint32_t *) buf); +} + +sw_error_t +cmd_data_check_uint64(char *cmd_str, a_uint64_t * arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + + if (0 == cmd_str[0]) + { + return SW_BAD_VALUE; + } + + if (strspn(cmd_str, "1234567890abcdefABCDEFXx") != strlen(cmd_str)){ + return SW_BAD_VALUE; + } + + if (cmd_str[0] == '0' && (cmd_str[1] == 'x' || cmd_str[1] == 'X')) + sscanf(cmd_str, "%llx", arg_val); + else + sscanf(cmd_str, "%lld", arg_val); + + return SW_OK; +} + +void +cmd_data_print_uint64(a_uint8_t * param_name, a_uint64_t * buf, a_uint32_t size) +{ + dprintf("[%s]:0x%llx", param_name, *(a_uint64_t *) buf); +} + +sw_error_t +cmd_data_check_uint16(char *cmd_str, a_uint32_t *arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + + if (0 == cmd_str[0]) + { + return SW_BAD_VALUE; + } + + if (cmd_str[0] == '0' && (cmd_str[1] == 'x' || cmd_str[1] == 'X')) + sscanf(cmd_str, "%x", arg_val); + else + sscanf(cmd_str, "%d", arg_val); + + if (65535 < *arg_val) + { + return SW_BAD_PARAM; + } + + return SW_OK; +} + +void +cmd_data_print_uint16(a_char_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:0x%04x", param_name, *(a_uint16_t *) buf); + +} + +sw_error_t +cmd_data_check_pbmp(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + + if (cmd_str[0] == '0' && (cmd_str[1] == 'x' || cmd_str[1] == 'X')) + sscanf(cmd_str, "%x", arg_val); + else + sscanf(cmd_str, "%d", arg_val); + + return SW_OK; + +} + +void +cmd_data_print_pbmp(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:0x%x", param_name, *(a_uint32_t *) buf); + +} + +sw_error_t +cmd_data_check_enable(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + + if (!strcasecmp(cmd_str, "disable")) + *arg_val = FAL_DISABLE; + else if (!strcasecmp(cmd_str, "enable")) + *arg_val = FAL_ENABLE; + else + { + //dprintf("input error"); + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_enable(a_char_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:", param_name); + if (*(a_uint32_t *) buf == 1) + { + dprintf("ENABLE"); + } + else if (*(a_uint32_t *) buf == 0) + { + dprintf("DISABLE"); + } + else + { + dprintf("UNKNOWN VALUE"); + } +} +/*qca808x_end*/ +/*mib*/ +static char *mib_regname[] = +{ + "RxBroad", + "RxPause", + "RxMulti", + "RxFcsErr", + "RxAlignErr", + "RxRunt", + "RxFragment", + "Rx64Byte", + "Rx128Byte", + "Rx256Byte", + "Rx512Byte", + "Rx1024Byte", + "Rx1518Byte", + "RxMaxByte", + "RxTooLong", + "RxGoodByte", + "RxGoodByte1", + "RxBadByte", + "RxBadByte1", + "RxOverFlow", + "Filtered", + "TxBroad", + "TxPause", + "TxMulti", + "TxUnderRun", + "Tx64Byte", + "Tx128Byte", + "Tx256Byte", + "Tx512Byte", + "Tx1024Byte", + "Tx1518Byte", + "TxMaxByte", + "TxOverSize", + "TxByte", + "TxByte1", + "TxCollision", + "TxAbortCol", + "TxMultiCol", + "TxSingleCol", + "TxExcDefer", + "TxDefer", + "TxLateCol", + "RxUniCast", + "TxUniCast", + "RxJmFcsErr", + "RxJmAligErr", + "Rx14To63", + "RxTooLongByte", + "RxTooLongByte1", + "RxRuntByte", + "RxRuntByte1", +}; + +static char *mib_cntr_regname[] = +{ + "RxBroad", + "RxPause", + "RxMulti", + "RxFcsErr", + "RxAlignErr", + "RxRunt", + "RxFragment", + "Rx64Byte", + "Rx128Byte", + "Rx256Byte", + "Rx512Byte", + "Rx1024Byte", + "Rx1518Byte", + "RxMaxByte", + "RxTooLong", + "RxGoodByte", + "RxBadByte", + "RxOverFlow", + "Filtered", + "TxBroad", + "TxPause", + "TxMulti", + "TxUnderRun", + "Tx64Byte", + "Tx128Byte", + "Tx256Byte", + "Tx512Byte", + "Tx1024Byte", + "Tx1518Byte", + "TxMaxByte", + "TxOverSize", + "TxByte", + "TxCollision", + "TxAbortCol", + "TxMultiCol", + "TxSingleCol", + "TxExcDefer", + "TxDefer", + "TxLateCol", + "RxUniCast", + "TxUniCast", + "RxJmFcsErr", + "RxJmAligErr", + "Rx14To63", + "RxTooLongByte", + "RxRuntByte", +}; + +static char *xgmib_regname[] = +{ + "RxFrame", + "RxByte", + "RxByteGood", + "RxBroadGood", + "RxMultiGood", + "RxFcsErr", + "RxRuntErr", + "RxJabberError", + "RxUndersizeGood", + "RxOversizeGood", + "Rx64Byte", + "Rx128Byte", + "Rx256Byte", + "Rx512Byte", + "Rx1024Byte", + "RxMaxByte", + "RxUnicastGood", + "RxLengthError", + "RxOutOfRangeError", + "RxPause", + "RxOverFlow", + "RxVLANFrameGoodBad", + "RxWatchDogError", + "RxLPIUsec", + "RxLPITran", + "RxDropFrameGoodBad", + "RxDropByteGoodBad", + "TxByte" , + "TxFrame" , + "TxBroadGood", + "TxMultiGood", + "Tx64Byte" , + "Tx128Byte", + "Tx256Byte", + "Tx512Byte", + "Tx1024Byte", + "TxMaxByte", + "TxUnicast", + "TxMulti" , + "TxBroad", + "TxUnderFlowError", + "TxByteGood", + "TxFrameGood", + "TxPause", + "TxVLANFrameGood", + "TxLPIUsec" , + "TxLPITran" +}; + + +void +cmd_data_print_mib(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("\n[%s] \n", param_name); + a_uint32_t offset = 0; + for (offset = 0; offset < (sizeof (fal_mib_info_t) / sizeof (a_uint32_t)); + offset++) + { + + dprintf("%-15s<0x%015x> ", mib_regname[offset], *(buf + offset)); + if ((offset + 1) % 3 == 0) + dprintf("\n"); + } +} + +void +cmd_data_print_mib_cntr(a_uint8_t * param_name, a_uint64_t * buf, a_uint32_t size) +{ + dprintf("\n[%s] \n", param_name); + a_uint32_t offset = 0; + + for (offset = 0; offset < (sizeof (fal_mib_counter_t) / sizeof (a_uint64_t)); + offset++) + { + dprintf("%-14s<0x%014llx> ", mib_cntr_regname[offset], *(buf + offset)); + if ((offset + 1) % 3 == 0) + dprintf("\n"); + } +} + + +void +cmd_data_print_xgmib(a_uint8_t * param_name, a_uint64_t * buf, a_uint64_t size) +{ + dprintf("\n[%s] \n", param_name); + a_uint64_t offset = 0, number; + + number = sizeof (fal_xgmib_info_t) / sizeof (a_uint64_t); + for (offset = 0; offset < number; offset++) + { + dprintf("%-20s<0x%016llx> ", xgmib_regname[offset], *(buf + offset)); + + if ((offset + 1) % 3 == 0) + dprintf("\n"); + } +} +/*qca808x_start*/ +/*port counter*/ +static char *counter_regname[] = +{ + "RxGoodFrame", + "RxBadCRC ", + "TxGoodFrame", + "TxBadCRC ", + "SysRxGoodFrame", + "SysRxBadCRC", + "SysTxGoodFrame", + "SysTxBadCRC", +}; + +void +cmd_data_print_counter_info(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("\n[%s] \n", param_name); + a_uint32_t offset = 0; + for (offset = 0; offset < (sizeof (fal_port_counter_info_t) / sizeof (a_uint32_t)); + offset++) + { + + dprintf("%s<0x%08x>\n", counter_regname[offset], *(buf + offset)); + + } +} + +void +cmd_data_print_debug_register_info(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("\n[%s]", param_name); + fal_debug_reg_dump_t * reg_dump = (fal_debug_reg_dump_t * )buf; + + a_uint32_t reg_count; + + dprintf("\n%s. ", reg_dump->reg_name); + + reg_count = 0; + dprintf("\n"); + for (;reg_count < reg_dump->reg_count;reg_count++) + { + dprintf("%08x:%08x ",reg_dump->reg_addr[reg_count], reg_dump->reg_value[reg_count]); + if ((reg_count + 1) % 4 == 0) + dprintf("\n"); + } + + dprintf("\n\n\n"); +} + + + +void +cmd_data_print_register_info(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("\n[%s]", param_name); + fal_reg_dump_t * reg_dump = (fal_reg_dump_t * )buf; + a_uint32_t n[8]={0,4,8,0xc,0x10,0x14,0x18,0x1c}; + a_uint32_t dump_addr, reg_count; + + dprintf("\n%s. ", reg_dump->reg_name); + dprintf("\n %8x %8x %8x %8x %8x %8x %8x %8x\n", + n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); + dprintf(" [%04x] ", reg_dump->reg_base); + + reg_count = 0; + for (dump_addr = reg_dump->reg_base; + (dump_addr <= reg_dump->reg_end )&& (reg_count <= reg_dump->reg_count); + reg_count++) + { + dprintf("%08x ", reg_dump->reg_value[reg_count]); + dump_addr += 4; + if ((reg_count + 1) % 8 == 0) + dprintf("\n [%04x] ", dump_addr); + } + + dprintf("\n\n\n"); +} + +void +cmd_data_print_phy_register_info(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("\n[%s]", param_name); + fal_phy_dump_t * phy_dump = (fal_phy_dump_t * )buf; + + a_uint32_t n[8]={0,1,2,3,4,5,6,7}; + + a_uint32_t dump_addr, reg_count; + + dprintf("\n%s. ", phy_dump->phy_name); + dprintf("\n %8x %8x %8x %8x %8x %8x %8x %8x\n", + n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); + dprintf(" [%04x] ", phy_dump->phy_base); + + reg_count = 0; + for (dump_addr = phy_dump->phy_base; + (dump_addr <= phy_dump->phy_end )&& (reg_count <= phy_dump->phy_count); + reg_count++) + { + dprintf("%08x ", phy_dump->phy_value[reg_count]); + dump_addr ++; + if ((reg_count + 1) % 8 == 0) + dprintf("\n [%04x] ", dump_addr); + } + + dprintf("\n\n\n"); +} + + +/*port ctrl*/ +sw_error_t +cmd_data_check_duplex(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + + if (!strcasecmp(cmd_str, "half")) + *arg_val = FAL_HALF_DUPLEX; + else if (!strcasecmp(cmd_str, "full")) + *arg_val = FAL_FULL_DUPLEX; + else + { + //dprintf("input error \n"); + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_duplex(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:", param_name); + if (*(a_uint32_t *) buf == 0) + { + dprintf("HALF"); + } + else if (*(a_uint32_t *) buf == 1) + { + dprintf("FULL"); + } + else + { + dprintf("UNKNOWN VALUE"); + } +} + +sw_error_t +cmd_data_check_speed(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + + if (!strncasecmp(cmd_str, "10", 3)) + *arg_val = FAL_SPEED_10; + else if (!strncasecmp(cmd_str, "100", 4)) + *arg_val = FAL_SPEED_100; + else if (!strncasecmp(cmd_str, "1000", 5)) + *arg_val = FAL_SPEED_1000; + else if (!strncasecmp(cmd_str, "2500", 5)) + *arg_val = FAL_SPEED_2500; + else if (!strncasecmp(cmd_str, "5000", 5)) + *arg_val = FAL_SPEED_5000; + else if (!strncasecmp(cmd_str, "10000", 6)) + *arg_val = FAL_SPEED_10000; + else + { + //dprintf("input error \n"); + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_speed(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:", param_name); + if (*(a_uint32_t *) buf == FAL_SPEED_10) + { + dprintf("10(Mbps)"); + } + else if (*(a_uint32_t *) buf == FAL_SPEED_100) + { + dprintf("100(Mbps)"); + } + else if (*(a_uint32_t *) buf == FAL_SPEED_1000) + { + dprintf("1000(Mbps)"); + } + else if (*(a_uint32_t *) buf == FAL_SPEED_2500) + { + dprintf("2500(Mbps)"); + } + else if (*(a_uint32_t *) buf == FAL_SPEED_5000) + { + dprintf("5000(Mbps)"); + } + else if (*(a_uint32_t *) buf == FAL_SPEED_10000) + { + dprintf("10000(Mbps)"); + } + else + { + dprintf("UNKNOWN VALUE"); + } +} + +sw_error_t +cmd_data_check_capable(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + + cmd_strtol(cmd_str, arg_val); + if (*arg_val & (~FAL_PHY_COMBO_ADV_ALL)) + { + //dprintf("input error should be within 0x3f\n"); + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_capable(a_uint8_t * param_name, a_uint32_t * buf, + a_uint32_t size) +{ + dprintf("[%s]:", param_name); + + if (*(a_uint32_t *) buf == 0) + { + dprintf("None Capable"); + return; + } + + if (*(a_uint32_t *) buf & FAL_PHY_ADV_10000T_FD) + { + dprintf("10000TX_FD|"); + } + if (*(a_uint32_t *) buf & FAL_PHY_ADV_5000T_FD) + { + dprintf("5000TX_FD|"); + } + if (*(a_uint32_t *) buf & FAL_PHY_ADV_2500T_FD) + { + dprintf("2500TX_FD|"); + } + if (*(a_uint32_t *) buf & FAL_PHY_ADV_1000BX_FD) + { + dprintf("1000BX_FD|"); + } + if (*(a_uint32_t *) buf & FAL_PHY_ADV_1000BX_HD) + { + dprintf("1000BX_HD|"); + } + if (*(a_uint32_t *) buf & FAL_PHY_ADV_1000T_FD) + { + dprintf("1000T_FD|"); + } + if (*(a_uint32_t *) buf & FAL_PHY_ADV_100TX_FD) + { + dprintf("100TX_FD|"); + } + if (*(a_uint32_t *) buf & FAL_PHY_ADV_100TX_HD) + { + dprintf("100TX_HD|"); + } + if (*(a_uint32_t *) buf & FAL_PHY_ADV_10T_HD) + { + dprintf("10T_HD|"); + } + if (*(a_uint32_t *) buf & FAL_PHY_ADV_10T_FD) + { + dprintf("10T_FD|"); + } + if (*(a_uint32_t *) buf & FAL_PHY_ADV_PAUSE) + { + dprintf("PAUSE|"); + } + if (*(a_uint32_t *) buf & FAL_PHY_ADV_ASY_PAUSE) + { + dprintf("ASY_PAUSE|"); + } +} + +sw_error_t +cmd_data_check_crossover_mode(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + + if (!strncasecmp(cmd_str, "auto", 5)) + *arg_val = PHY_MDIX_AUTO; + else if (!strncasecmp(cmd_str, "mdi", 4)) + *arg_val = PHY_MDIX_MDI; + else if (!strncasecmp(cmd_str, "mdix", 5)) + *arg_val = PHY_MDIX_MDIX; + else + { + //dprintf("input error \n"); + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_crossover_mode(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:", param_name); + if (*(a_uint32_t *) buf == PHY_MDIX_AUTO) + { + dprintf("AUTO"); + } + else if (*(a_uint32_t *) buf == PHY_MDIX_MDI) + { + dprintf("MDI"); + } + else if (*(a_uint32_t *) buf == PHY_MDIX_MDIX) + { + dprintf("MDIX"); + } + else + { + dprintf("UNKNOWN VALUE"); + } +} + +sw_error_t +cmd_data_check_crossover_status(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + if (!strncasecmp(cmd_str, "mdi", 4)) + *arg_val = PHY_MDIX_STATUS_MDI; + else if (!strncasecmp(cmd_str, "mdix", 5)) + *arg_val = PHY_MDIX_STATUS_MDIX; + else + { + //dprintf("input error \n"); + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_crossover_status(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:", param_name); + if (*(a_uint32_t *) buf == PHY_MDIX_STATUS_MDI) + { + dprintf("MDI"); + } + else if (*(a_uint32_t *) buf == PHY_MDIX_STATUS_MDIX) + { + dprintf("MDIX"); + } + else + { + dprintf("UNKNOWN VALUE"); + } +} +/*qca808x_end*/ +sw_error_t +cmd_data_check_prefer_medium(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + if (!strncasecmp(cmd_str, "copper", 7)) + *arg_val = PHY_MEDIUM_COPPER; + else if (!strncasecmp(cmd_str, "fiber", 6)) + *arg_val = PHY_MEDIUM_FIBER; + else + { + //dprintf("input error \n"); + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_prefer_medium(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:", param_name); + if (*(a_uint32_t *) buf == PHY_MEDIUM_COPPER) + { + dprintf("COPPER"); + } + else if (*(a_uint32_t *) buf == PHY_MEDIUM_FIBER) + { + dprintf("FIBER"); + } + else + { + dprintf("UNKNOWN VALUE"); + } +} + +sw_error_t +cmd_data_check_fiber_mode(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + if (!strncasecmp(cmd_str, "100fx", 6)) + *arg_val = PHY_FIBER_100FX; + else if (!strncasecmp(cmd_str, "1000bx", 7)) + *arg_val = PHY_FIBER_1000BX; + else if (!strncasecmp(cmd_str, "10g_r", 7)) + *arg_val = PHY_FIBER_10G_R; + else + { + //dprintf("input error \n"); + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_fiber_mode(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:", param_name); + if (*(a_uint32_t *) buf == PHY_FIBER_100FX) + { + dprintf("100FX"); + } + else if (*(a_uint32_t *) buf == PHY_FIBER_1000BX) + { + dprintf("1000BX"); + } + else + { + dprintf("UNKNOWN VALUE"); + } +} +/*qca808x_start*/ +sw_error_t +cmd_data_check_interface_mode(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + + if (!strncasecmp(cmd_str, "psgmii_baset", 13)) + *arg_val = PHY_PSGMII_BASET; + else if (!strncasecmp(cmd_str, "psgmii_bx1000", 14)) + *arg_val = PHY_PSGMII_BX1000; + else if (!strncasecmp(cmd_str, "psgmii_fx100", 13)) + *arg_val = PHY_PSGMII_FX100; + else if (!strncasecmp(cmd_str, "psgmii_amdet", 13)) + *arg_val = PHY_PSGMII_AMDET; + else if (!strncasecmp(cmd_str, "rgmii_amdet", 13)) + *arg_val = PORT_RGMII_AMDET; + else if (!strncasecmp(cmd_str, "rgmii_baset", 13)) + *arg_val = PORT_RGMII_BASET; + else if (!strncasecmp(cmd_str, "rgmii_bx1000", 13)) + *arg_val = PORT_RGMII_BX1000; + else if (!strncasecmp(cmd_str, "rgmii_fx100", 13)) + *arg_val = PORT_RGMII_FX100; + else if (!strncasecmp(cmd_str, "sgmii_baset", 13)) + *arg_val = PHY_SGMII_BASET; + else if (!strncasecmp(cmd_str, "qsgmii", 13)) + *arg_val = PORT_QSGMII; + else if (!strncasecmp(cmd_str, "sgmii_plus", 13)) + *arg_val = PORT_SGMII_PLUS; + else if (!strncasecmp(cmd_str, "usxgmii", 13)) + *arg_val = PORT_USXGMII; + else if (!strncasecmp(cmd_str, "10gbase_r", 13)) + *arg_val = PORT_10GBASE_R; + else if (!strncasecmp(cmd_str, "sgmii_fiber", 20)) + *arg_val = PORT_SGMII_FIBER; + else if (!strncasecmp(cmd_str, "psgmii_fiber", 20)) + *arg_val = PHY_PSGMII_FIBER; + else if (!strncasecmp(cmd_str, "interfacemode_max", 20)) + *arg_val = PORT_INTERFACE_MODE_MAX; + else + { + //dprintf("input error \n"); + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_interface_mode(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:", param_name); + if (*(a_uint32_t *) buf == PHY_PSGMII_BASET) + { + dprintf("PSGMII_BASET"); + } + else if (*(a_uint32_t *) buf == PHY_PSGMII_BX1000) + { + dprintf("PSGMII_BX1000"); + } + else if (*(a_uint32_t *) buf == PHY_PSGMII_FX100) + { + dprintf("PSGMII_FX100"); + } + else if (*(a_uint32_t *) buf == PHY_PSGMII_AMDET) + { + dprintf("PSGMII_AMDET"); + } + else if (*(a_uint32_t *) buf == PORT_RGMII_AMDET) + { + dprintf("RGMII_AMDET"); + } + else if (*(a_uint32_t *) buf == PORT_RGMII_BASET) + { + dprintf("RGMII_BASET"); + } + else if (*(a_uint32_t *) buf == PORT_RGMII_BX1000) + { + dprintf("RGMII_BX1000"); + } + else if (*(a_uint32_t *) buf == PORT_RGMII_FX100) + { + dprintf("RGMII_FX100"); + } + else if (*(a_uint32_t *) buf == PHY_SGMII_BASET) + { + dprintf("SGMII_BASET"); + } + else if (*(a_uint32_t *) buf == PORT_QSGMII) + { + dprintf("QSGMII"); + } + else if (*(a_uint32_t *) buf == PORT_SGMII_PLUS) + { + dprintf("SGMII PLUS"); + } + else if (*(a_uint32_t *) buf == PORT_USXGMII) + { + dprintf("USXGMII"); + } + else if (*(a_uint32_t *) buf == PORT_10GBASE_R) + { + dprintf("10gbase_r"); + } + else if (*(a_uint32_t *) buf == PORT_SGMII_FIBER) + { + dprintf("sgmii_fiber"); + } + else if (*(a_uint32_t *) buf == PHY_PSGMII_FIBER) + { + dprintf("psgmii_fiber"); + } + else if (*(a_uint32_t *) buf == PORT_INTERFACE_MODE_MAX) + { + dprintf("INTERFACEMODE_MAX"); + } + else + { + dprintf("UNKNOWN VALUE"); + } +} +/*qca808x_end*/ +void +cmd_data_print_mtu_info(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_mtu_ctrl_t *mtu; + mtu = (fal_mtu_ctrl_t *) buf; + + dprintf("\n[%s] \n", param_name); + + dprintf("mtu_size:0x%x\n",mtu->mtu_size); + if(mtu->action == MRU_MTU_FORWARD) + dprintf("mtu_action:forward\n"); + else if(mtu->action == MRU_MTU_DROP) + dprintf("mtu_action:drop\n"); + else if(mtu->action == MRU_MTU_CPYCPU) + dprintf("mtu_action:cpycpu\n"); + else if(mtu->action == MRU_MTU_RDTCPU) + dprintf("mtu_action:rdtcpu\n"); + else + dprintf("mtu_action:unknown\n"); +} + +void +cmd_data_print_mru_info(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_mru_ctrl_t *mru; + mru = (fal_mru_ctrl_t *) buf; + + dprintf("\n[%s] \n", param_name); + + dprintf("mru_size:0x%x\n",mru->mru_size); + if(mru->action == MRU_MRU_FORWARD) + { + dprintf("mru_action:forward\n"); + } + else if(mru->action == MRU_MRU_DROP) + { + dprintf("mru_action:drop\n"); + } + else if(mru->action == MRU_MRU_CPYCPU) + { + dprintf("mru_action:cpycpu\n"); + } + else if(mru->action == MRU_MRU_RDTCPU) + { + dprintf("mru_action:rdtcpu\n"); + } + else + { + dprintf("mru_action:unknown\n"); + } +} + +sw_error_t +cmd_data_check_mtu_entry(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_mtu_ctrl_t entry; + + aos_mem_zero(&entry, sizeof (fal_mtu_ctrl_t)); + + do + { + cmd = get_sub_cmd("mtu_size", "1514"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 1514 - 32767 \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.mtu_size), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: usage: 1514 - 32767 \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("mtu_action", "forward"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: usage: forward/drop/cpycpu/rdtcpu\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_maccmd(cmd, (fal_fwd_cmd_t *) (&(entry.action)), + sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: usage: forward/drop/cpycpu/rdtcpu\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + *(fal_mtu_ctrl_t *)val = entry; + return SW_OK; +} + +sw_error_t +cmd_data_check_mru_entry(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_mru_ctrl_t entry; + + aos_mem_zero(&entry, sizeof (fal_mru_ctrl_t)); + + do + { + cmd = get_sub_cmd("mru_size", "1514"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 1514 - 32767 \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.mru_size), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: usage: 1514 - 32767 \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("mru_action", "forward"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: usage: forward/drop/cpycpu/rdtcpu\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_maccmd(cmd,(fal_fwd_cmd_t *) (&(entry.action)), + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: usage: forward/drop/cpycpu/rdtcpu\n"); + } + } + } + while (talk_mode && (SW_OK != rv)); + + *(fal_mru_ctrl_t *)val = entry; + return SW_OK; +} + +/*portvlan*/ +sw_error_t +cmd_data_check_1qmode(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + + if (!strcasecmp(cmd_str, "disable")) + { + *arg_val = FAL_1Q_DISABLE; + } + else if (!strcasecmp(cmd_str, "secure")) + { + *arg_val = FAL_1Q_SECURE; + } + else if (!strcasecmp(cmd_str, "check")) + { + *arg_val = FAL_1Q_CHECK; + } + else if (!strcasecmp(cmd_str, "fallback")) + { + *arg_val = FAL_1Q_FALLBACK; + } + else + { + //dprintf("input error \n"); + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_1qmode(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:", param_name); + if (*(a_uint32_t *) buf == FAL_1Q_DISABLE) + { + dprintf("DISABLE\n"); + } + else if (*(a_uint32_t *) buf == FAL_1Q_SECURE) + { + dprintf("SECURE\n"); + } + else if (*(a_uint32_t *) buf == FAL_1Q_CHECK) + { + dprintf("CHECK\n"); + } + else if (*(a_uint32_t *) buf == FAL_1Q_FALLBACK) + { + dprintf("FALLBACK\n"); + } + else + { + dprintf("UNKNOWN VALUE"); + } +} + +sw_error_t +cmd_data_check_egmode(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + + if (!strcasecmp(cmd_str, "unmodified")) + { + *arg_val = FAL_EG_UNMODIFIED; + } + else if (!strcasecmp(cmd_str, "untagged")) + { + *arg_val = FAL_EG_UNTAGGED; + } + else if (!strcasecmp(cmd_str, "tagged")) + { + *arg_val = FAL_EG_TAGGED; + } + else if (!strcasecmp(cmd_str, "hybrid")) + { + *arg_val = FAL_EG_HYBRID; + } + else if (!strcasecmp(cmd_str, "untouched")) + { + *arg_val = FAL_EG_UNTOUCHED; + } + else + { + //dprintf("input error \n"); + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_egmode(a_char_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:", param_name); + if (*(a_uint32_t *) buf == FAL_EG_UNMODIFIED) + { + dprintf("UNMODIFIED"); + } + else if (*(a_uint32_t *) buf == FAL_EG_UNTAGGED) + { + dprintf("UNTAGGED"); + } + else if (*(a_uint32_t *) buf == FAL_EG_TAGGED) + { + dprintf("TAGGED"); + } + else if (*(a_uint32_t *) buf == FAL_EG_HYBRID) + { + dprintf("HYBRID"); + } + else if (*(a_uint32_t *) buf == FAL_EG_UNTOUCHED) + { + dprintf("UNTOUCHED"); + } + else + { + dprintf("UNKNOWN VALUE"); + } +} + +/*vlan*/ +sw_error_t +cmd_data_check_vlan(char *cmdstr, fal_vlan_t * val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_vlan_t entry; + a_uint32_t tmp = 0; + + memset(&entry, 0, sizeof (fal_vlan_t)); + + do + { + cmd = get_sub_cmd("vlanid", NULL); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 4095\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: the range is 0 -- 4095\n"); + } + + } + while (talk_mode && (SW_OK != rv)); + entry.vid = tmp & 0xffff; + + do + { + cmd = get_sub_cmd("fid", NULL); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 4095 or 65535\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: the range is 0 -- 4095 or 65535\n"); + } + + } + while (talk_mode && (SW_OK != rv)); + entry.fid = tmp & 0xffff; + + do + { + cmd = get_sub_cmd("port member", "null"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: input port number such as 1,3\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_portmap(cmd, &entry.mem_ports, + sizeof (fal_pbmp_t)); + if (SW_OK != rv) + dprintf("usage: input port number such as 1,3\n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("tagged member", "null"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: input port number such as 1,3\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_portmap(cmd, &entry.tagged_ports, + sizeof (fal_pbmp_t)); + if (SW_OK != rv) + dprintf("usage: input port number such as 1,3\n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("untagged member", "null"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: input port number such as 1,3\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_portmap(cmd, &entry.untagged_ports, + sizeof (fal_pbmp_t)); + if (SW_OK != rv) + dprintf("usage: input port number such as 1,3\n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("unmodify member", "null"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: input port number such as 1,3\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_portmap(cmd, &entry.unmodify_ports, + sizeof (fal_pbmp_t)); + if (SW_OK != rv) + dprintf("usage: input port number such as 1,3\n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("learn disable", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.learn_dis, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("queue override", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.vid_pri_en, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + if (A_TRUE == entry.vid_pri_en) + { + do + { + cmd = get_sub_cmd("queue", NULL); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: input number such as <0/1/2/3>\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: input number such as <0/1/2/3>\n"); + } + + } + while (talk_mode && (SW_OK != rv)); + entry.vid_pri = tmp; + } + + *val = entry; + return SW_OK; +} + +void +cmd_data_print_vlan(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_vlan_t *sw_vlan = (fal_vlan_t *) buf; + + dprintf("\n[vid]:%-4d [fid]:%-5d [member]:0x%-4x", + sw_vlan->vid, sw_vlan->fid, sw_vlan->mem_ports); + + dprintf("\n[tagged_member]:0x%-4x [untagged_member]:0x%-4x [unmodify_member]:0x%-4x ", + sw_vlan->tagged_ports, sw_vlan->untagged_ports, sw_vlan->unmodify_ports); + + if (sw_vlan->learn_dis == 1) + { + dprintf("[learn_dis]:enable "); + } + else + { + dprintf("[learn_dis]:disable "); + } + + if (sw_vlan->vid_pri_en == 1) + { + dprintf("[pri_en]:enable [pri]:0x%-4x\n", sw_vlan->vid_pri); + } + else + { + dprintf("[pri_en]:disable [pri]:0x%-4x\n", 0); + } +} + +sw_error_t +cmd_data_check_lan_wan_cfg(char *cmdstr, void *val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + char *tmp = NULL, *str_save; + a_uint32_t port; + a_uint32_t vid, pvlan_ports = 0, i = 0, j = 0; + qca_lan_wan_cfg_t entry; + + memset(&entry, 0, sizeof (qca_lan_wan_cfg_t)); + + do { + cmd = get_sub_cmd("lan_ports", NULL); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) { + dprintf("usage: input port number such as 1,3\n"); + rv = SW_BAD_VALUE; + } + else { + tmp = (void *) strtok_r(cmd, ",", &str_save); + while (tmp) { + sscanf(tmp, "%d", &port); + if (SW_MAX_NR_PORT <= port) { + return SW_BAD_VALUE; + } + + entry.v_port_info[i].port_id = port; + entry.v_port_info[i].is_wan_port = A_FALSE; + entry.v_port_info[i].valid = A_TRUE; + + tmp = (void *) strtok_r(NULL, ",", &str_save); + i++; + } + } + if (i == 0) { + dprintf("usage: input port number such as 1,3\n"); + rv = SW_BAD_VALUE; + } else { + rv = SW_OK; + } + } while (talk_mode && (SW_OK != rv)); + + entry.lan_only_mode = A_TRUE; + do { + cmd = get_sub_cmd("lan_vids", NULL); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) { + dprintf("usage: input vlan ids such as 1,1, the vlan id range 0--4095\n"); + rv = SW_BAD_VALUE; + } + else { + tmp = (void *) strtok_r(cmd, ",", &str_save); + while (tmp) { + sscanf(tmp, "%d", &vid); + if (0xfff <= vid) { + return SW_BAD_VALUE; + } + + entry.v_port_info[j].vid = vid; + + if (vid == 0) { + pvlan_ports++; + } else { + entry.lan_only_mode = A_FALSE; + } + + tmp = (void *) strtok_r(NULL, ",", &str_save); + j++; + } + } + if (j == 0) { + dprintf("usage: input vlan ids such as 1,1, the vlan id range 0--4095\n"); + rv = SW_BAD_VALUE; + } else { + rv = SW_OK; + } + } while (talk_mode && (SW_OK != rv)); + + if (i != j) { + dprintf("the lan ports and vids are unmatched\n"); + return SW_BAD_VALUE; + } + + /* + * portbased vlan used: + * ssdk_sh vlan lan_wan_cfg set 1,2,3,4 0,0,0,0 + */ + if (pvlan_ports == i && entry.lan_only_mode) { + *(qca_lan_wan_cfg_t *)val = entry; + return SW_OK; + } + + do { + cmd = get_sub_cmd("wan_ports", NULL); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) { + dprintf("usage: input port number such as 1,3\n"); + rv = SW_BAD_VALUE; + } + else { + tmp = (void *) strtok_r(cmd, ",", &str_save); + while (tmp) { + sscanf(tmp, "%d", &port); + if (SW_MAX_NR_PORT <= port) { + return SW_BAD_VALUE; + } + + entry.v_port_info[i].port_id = port; + entry.v_port_info[i].is_wan_port = A_TRUE; + entry.v_port_info[i].valid = A_TRUE; + + tmp = (void *) strtok_r(NULL, ",", &str_save); + i++; + } + } + if (i == 0) { + dprintf("usage: input port number such as 1,3\n"); + rv = SW_BAD_VALUE; + } else { + rv = SW_OK; + } + } while (talk_mode && (SW_OK != rv)); + + do { + cmd = get_sub_cmd("wan_vids", NULL); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) { + dprintf("usage: input vlan ids such as 1,1, the vlan id range 0--4095\n"); + rv = SW_BAD_VALUE; + } + else { + tmp = (void *) strtok_r(cmd, ",", &str_save); + while (tmp) { + sscanf(tmp, "%d", &vid); + if (0xfff <= vid) { + return SW_BAD_VALUE; + } + + entry.v_port_info[j].vid = vid; + + tmp = (void *) strtok_r(NULL, ",", &str_save); + j++; + } + } + if (j == 0) { + dprintf("usage: input vlan ids such as 1,1, the vlan id range 0--4095\n"); + rv = SW_BAD_VALUE; + } else { + rv = SW_OK; + } + } while (talk_mode && (SW_OK != rv)); + + if (i != j) { + dprintf("the wan ports and vids are unmatched\n"); + return SW_BAD_VALUE; + } + + *(qca_lan_wan_cfg_t *)val = entry; + + return SW_OK; +} + +void +cmd_data_print_lan_wan_cfg(a_uint8_t *param_name, a_ulong_t *buf, a_uint32_t size) +{ + qca_lan_wan_cfg_t *entry = (qca_lan_wan_cfg_t *)buf; + a_uint32_t i; + + dprintf("\n[%s] \n", param_name); + dprintf("[lan_only_mode]: %s\n", entry->lan_only_mode ? "enabled" : "disabled"); + + dprintf("port_id\tvlan_id\tport_type\n"); + for (i = 0; i < sizeof(entry->v_port_info)/sizeof(entry->v_port_info[0]); i++) { + if (entry->v_port_info[i].valid) { + dprintf("%7d\t%7d\t%9s\n", + entry->v_port_info[i].port_id, + entry->v_port_info[i].vid, + entry->v_port_info[i].is_wan_port ? "wan" : "lan"); + } + } + dprintf("\n"); +} + +/*qos*/ +sw_error_t +cmd_data_check_qos_sch(char *cmdstr, fal_sch_mode_t * val, a_uint32_t size) +{ + if (cmdstr == NULL) + return SW_BAD_PARAM; + + if (!strcasecmp(cmdstr, "sp")) + { + *val = FAL_SCH_SP_MODE; + } + else if (!strcasecmp(cmdstr, "wrr")) + { + *val = FAL_SCH_WRR_MODE; + } + else if (!strcasecmp(cmdstr, "mixplus")) + { + *val = FAL_SCH_MIX_PLUS_MODE; + } + else if (!strcasecmp(cmdstr, "mix")) + { + *val = FAL_SCH_MIX_MODE; + } + else + { + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_qos_sch(a_uint8_t * param_name, a_uint32_t * buf, + a_uint32_t size) +{ + dprintf("[%s]:", param_name); + if (*(a_uint32_t *) buf == FAL_SCH_SP_MODE) + { + dprintf("SP"); + } + else if (*(a_uint32_t *) buf == FAL_SCH_WRR_MODE) + { + dprintf("WRR"); + } + else if (*(a_uint32_t *) buf == FAL_SCH_MIX_MODE) + { + dprintf("MIX"); + } + else if (*(a_uint32_t *) buf == FAL_SCH_MIX_PLUS_MODE) + { + dprintf("MIXPLUS"); + } + else + { + dprintf("UNKNOWN VALUE"); + } +} + +sw_error_t +cmd_data_check_qos_pt(char *cmdstr, fal_qos_mode_t * val, a_uint32_t size) +{ + if (cmdstr == NULL) + return SW_BAD_PARAM; + + if (!strcasecmp(cmdstr, "da")) + { + *val = FAL_QOS_DA_MODE; + } + else if (!strcasecmp(cmdstr, "up")) + { + *val = FAL_QOS_UP_MODE; + } + else if (!strcasecmp(cmdstr, "dscp")) + { + *val = FAL_QOS_DSCP_MODE; + } + else if (!strcasecmp(cmdstr, "port")) + { + *val = FAL_QOS_PORT_MODE; + } + else if (!strcasecmp(cmdstr, "flow")) + { + *val = FAL_QOS_FLOW_MODE; + } + else + { + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_qos_pt(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:", param_name); + if (*(a_uint32_t *) buf == FAL_QOS_DA_MODE) + { + dprintf("DA"); + } + else if (*(a_uint32_t *) buf == FAL_QOS_UP_MODE) + { + dprintf("UP"); + } + else if (*(a_uint32_t *) buf == FAL_QOS_DSCP_MODE) + { + dprintf("DSCP"); + } + else if (*(a_uint32_t *) buf == FAL_QOS_PORT_MODE) + { + dprintf("PORT"); + } + else if (*(a_uint32_t *) buf == FAL_QOS_FLOW_MODE) + { + dprintf("FLOW"); + } + else + { + dprintf("UNKNOWN VALUE"); + } +} + +/*rate*/ +sw_error_t +cmd_data_check_storm(char *cmdstr, fal_storm_type_t * val, a_uint32_t size) +{ + if (cmdstr == NULL) + return SW_BAD_PARAM; + + if (!strcasecmp(cmdstr, "unicast")) + { + *val = FAL_UNICAST_STORM; + } + else if (!strcasecmp(cmdstr, "multicast")) + { + *val = FAL_MULTICAST_STORM; + } + else if (!strcasecmp(cmdstr, "broadcast")) + { + *val = FAL_BROADCAST_STORM; + } + else + { + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_storm(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:", param_name); + if (*(a_uint32_t *) buf == FAL_UNICAST_STORM) + { + dprintf("UNICAST"); + } + else if (*(a_uint32_t *) buf == FAL_MULTICAST_STORM) + { + dprintf("MULTICAST"); + } + else if (*(a_uint32_t *) buf == FAL_BROADCAST_STORM) + { + dprintf("BROADCAST"); + } + else + { + dprintf("UNKNOWN VALUE"); + } +} + +/*stp*/ +sw_error_t +cmd_data_check_stp_state(char *cmdstr, fal_stp_state_t * val, a_uint32_t size) +{ + if (cmdstr == NULL) + return SW_BAD_PARAM; + + if (!strcasecmp(cmdstr, "disable")) + { + *val = FAL_STP_DISABLED; + } + else if (!strcasecmp(cmdstr, "block")) + { + *val = FAL_STP_BLOKING; + } + else if (!strcasecmp(cmdstr, "listen")) + { + *val = FAL_STP_LISTENING; + } + else if (!strcasecmp(cmdstr, "learn")) + { + *val = FAL_STP_LEARNING; + } + else if (!strcasecmp(cmdstr, "forward")) + { + *val = FAL_STP_FARWARDING; + } + else + { + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_stp_state(a_uint8_t * param_name, a_uint32_t * buf, + a_uint32_t size) +{ + dprintf("[%s]:", param_name); + if (*(a_uint32_t *) buf == FAL_STP_DISABLED) + { + dprintf("DISABLE"); + } + else if (*(a_uint32_t *) buf == FAL_STP_BLOKING) + { + dprintf("BLOCK"); + } + else if (*(a_uint32_t *) buf == FAL_STP_LISTENING) + { + dprintf("LISTEN"); + } + else if (*(a_uint32_t *) buf == FAL_STP_LEARNING) + { + dprintf("LEARN"); + } + else if (*(a_uint32_t *) buf == FAL_STP_FARWARDING) + { + dprintf("FORWARD"); + } + else + { + dprintf("UNKNOWN VALUE"); + } +} + +/*general*/ +sw_error_t +cmd_data_check_leaky(char *cmdstr, fal_leaky_ctrl_mode_t * val, a_uint32_t size) +{ + if (cmdstr == NULL) + return SW_BAD_VALUE; + + if (!strcasecmp(cmdstr, "port")) + { + *val = FAL_LEAKY_PORT_CTRL; + } + else if (!strcasecmp(cmdstr, "fdb")) + { + *val = FAL_LEAKY_FDB_CTRL; + } + else + { + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_leaky(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:", param_name); + if (*(a_uint32_t *) buf == FAL_LEAKY_PORT_CTRL) + { + dprintf("PORT"); + } + else if (*(a_uint32_t *) buf == FAL_LEAKY_FDB_CTRL) + { + dprintf("FDB"); + } + else + { + dprintf("UNKNOWN VALUE"); + } +} +sw_error_t +cmd_data_check_uinta(char *cmdstr, a_uint32_t * val, a_uint32_t size) +{ + char *tmp_str = NULL, *str_save; + a_uint32_t *tmp_ptr = val; + a_uint32_t i = 0; + + tmp_str = (void *) strtok_r(cmdstr, ",", &str_save); + while (tmp_str) + { + if (i >= (size / 4)) + { + return SW_BAD_VALUE; + } + + sscanf(tmp_str, "%d", tmp_ptr); + tmp_ptr++; + + i++; + tmp_str = (void *) strtok_r(NULL, ",", &str_save); + } + + if (i != (size / 4)) + { + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_uinta(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + a_uint32_t i; + a_uint32_t *tmp_ptr; + + dprintf("[%s]:", param_name); + + tmp_ptr = buf; + for (i = 0; i < (size / 4); i++) + { + dprintf(" %d, ", *tmp_ptr); + tmp_ptr++; + } +} + +/*fdb*/ +sw_error_t +cmd_data_check_maccmd(char *cmdstr, fal_fwd_cmd_t * val, a_uint32_t size) +{ + if (NULL == cmdstr) + { + return SW_BAD_VALUE; + } + + if (0 == cmdstr[0]) + { + *val = FAL_MAC_FRWRD; //defualt + } + else if (!strcasecmp(cmdstr, "forward")) + { + *val = FAL_MAC_FRWRD; + } + else if (!strcasecmp(cmdstr, "drop")) + { + *val = FAL_MAC_DROP; + } + else if (!strcasecmp(cmdstr, "cpycpu")) + { + *val = FAL_MAC_CPY_TO_CPU; + } + else if (!strcasecmp(cmdstr, "rdtcpu")) + { + *val = FAL_MAC_RDT_TO_CPU; + } + else + { + return SW_BAD_VALUE; + } + + return SW_OK; +} +void +cmd_data_print_maccmd(a_char_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:", param_name); + if (*(a_uint32_t *) buf == FAL_MAC_FRWRD) + { + dprintf("FORWARD"); + } + else if (*(a_uint32_t *) buf == FAL_MAC_DROP) + { + dprintf("DROP"); + } + else if (*(a_uint32_t *) buf == FAL_MAC_CPY_TO_CPU) + { + dprintf("CPYCPU"); + } + else if (*(a_uint32_t *) buf == FAL_MAC_RDT_TO_CPU) + { + dprintf("RDTCPU"); + } + else + { + dprintf("UNKNOWN VALUE"); + } +} +/*flow*/ +sw_error_t +cmd_data_check_flowcmd(char *cmdstr, fal_default_flow_cmd_t * val, a_uint32_t size) +{ + if (NULL == cmdstr) + { + return SW_BAD_VALUE; + } + + if (0 == cmdstr[0]) + { + *val = FAL_DEFAULT_FLOW_FORWARD; //defualt + } + else if (!strcasecmp(cmdstr, "forward")) + { + *val = FAL_DEFAULT_FLOW_FORWARD; + } + else if (!strcasecmp(cmdstr, "drop")) + { + *val = FAL_DEFAULT_FLOW_DROP; + } + else if (!strcasecmp(cmdstr, "rdtcpu")) + { + *val = FAL_DEFAULT_FLOW_RDT_TO_CPU; + } + else if (!strcasecmp(cmdstr, "admit_all")) + { + *val = FAL_DEFAULT_FLOW_ADMIT_ALL; + } + else + { + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_flowcmd(a_char_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:", param_name); + if (*(a_uint32_t *) buf == FAL_DEFAULT_FLOW_FORWARD) + { + dprintf("FORWARD"); + } + else if (*(a_uint32_t *) buf == FAL_DEFAULT_FLOW_DROP) + { + dprintf("DROP"); + } + else if (*(a_uint32_t *) buf == FAL_DEFAULT_FLOW_RDT_TO_CPU) + { + dprintf("RDTCPU"); + } + else if (*(a_uint32_t *) buf == FAL_DEFAULT_FLOW_ADMIT_ALL) + { + dprintf("ADMIT_ALL"); + } + else + { + dprintf("UNKNOWN VALUE"); + } +} + +sw_error_t +cmd_data_check_flowtype(char *cmd_str, fal_flow_type_t * arg_val, + a_uint32_t size) +{ + if (NULL == cmd_str) + { + return SW_BAD_VALUE; + } + + if (!strcasecmp(cmd_str, "lan2lan")) + { + *arg_val = FAL_FLOW_LAN_TO_LAN; + } + else if (!strcasecmp(cmd_str, "wan2lan")) + { + *arg_val = FAL_FLOW_WAN_TO_LAN; + } + else if (!strcasecmp(cmd_str, "lan2wan")) + { + *arg_val = FAL_FLOW_LAN_TO_WAN; + } + else if (!strcasecmp(cmd_str, "wan2wan")) + { + *arg_val = FAL_FLOW_WAN_TO_WAN; + } + else + { + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_flowtype(a_char_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:", param_name); + if (*(a_uint32_t *) buf == FAL_FLOW_LAN_TO_LAN) + { + dprintf("lan2lan"); + } + else if (*(a_uint32_t *) buf == FAL_FLOW_WAN_TO_LAN) + { + dprintf("wan2lan"); + } + else if (*(a_uint32_t *) buf == FAL_FLOW_LAN_TO_WAN) + { + dprintf("lan2wan"); + } + else if (*(a_uint32_t *) buf == FAL_FLOW_WAN_TO_WAN) + { + dprintf("wan2wan"); + } + else + { + dprintf("UNKNOWN VALUE"); + } +} +/*qca808x_start*/ +sw_error_t +cmd_data_check_confirm(char *cmdstr, a_bool_t def, a_bool_t * val, + a_uint32_t size) +{ + if (0 == cmdstr[0]) + { + *val = def; + } + else if ((!strcasecmp(cmdstr, "yes")) || (!strcasecmp(cmdstr, "y"))) + { + *val = A_TRUE; + } + else if ((!strcasecmp(cmdstr, "no")) || (!strcasecmp(cmdstr, "n"))) + { + *val = A_FALSE; + } + else + { + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_confirm(char * param_name, a_bool_t val, a_uint32_t size) +{ + dprintf("%s", param_name); + if (A_TRUE == val) + { + dprintf("YES"); + } + else + { + dprintf("NO"); + } + + return; +} + +sw_error_t +cmd_data_check_portid(char *cmdstr, fal_port_t * val, a_uint32_t size) +{ + *val = 0; + //default input null + if(!strcasecmp(cmdstr, "null")) + { + if (ssdk_cfg.init_cfg.chip_type == CHIP_HPPE) + return SW_BAD_VALUE; + return SW_OK; + } + if (strstr(cmdstr, "0x") == NULL) + sscanf(cmdstr, "%d", val); + else + sscanf(cmdstr, "%x", val); + + return SW_OK; +} + +sw_error_t +cmd_data_check_portmap(char *cmdstr, fal_pbmp_t * val, a_uint32_t size) +{ + char *tmp = NULL, *str_save; + a_uint32_t port; + + *val = 0; + //default input null + if(!strcasecmp(cmdstr, "null")) + { + return SW_OK; + } + + tmp = (void *) strtok_r(cmdstr, ",", &str_save); + while (tmp) + { + sscanf(tmp, "%d", &port); + if (SW_MAX_NR_PORT <= port) + { + return SW_BAD_VALUE; + } + + *val |= (0x1 << port); + tmp = (void *) strtok_r(NULL, ",", &str_save); + } + + return SW_OK; +} + +void +cmd_data_print_portmap(char * param_name, fal_pbmp_t val, a_uint32_t size) +{ + a_uint32_t i; + char tmp[16]; + tmp[0] = '\0'; + + dprintf("%s", param_name); + for (i = 0; i < SW_MAX_NR_PORT; i++) + { + if (val & (0x1 << i)) + { + if(strlen(tmp) == 0) + snprintf(tmp, sizeof(tmp), "%d", i); + else + snprintf(tmp+strlen(tmp), sizeof(tmp+strlen(tmp)), ",%d", i); + } + } + dprintf("%s ", tmp); + return; +} + +sw_error_t +cmd_data_check_macaddr(char *cmdstr, void *val, a_uint32_t size) +{ + char *tmp = NULL, *str_save; + a_uint32_t i = 0, j; + a_uint32_t addr; + fal_mac_addr_t mac; + + memset(&mac, 0, sizeof (fal_mac_addr_t)); + if (NULL == cmdstr) + { + *(fal_mac_addr_t *) val = mac; + return SW_BAD_VALUE; /*was: SW_OK;*/ + } + + if (0 == cmdstr[0]) + { + *(fal_mac_addr_t *) val = mac; + return SW_OK; + } + + tmp = (void *) strtok_r(cmdstr, "-", &str_save); + while (tmp) + { + if (6 <= i) + { + return SW_BAD_VALUE; + } + + if ((2 < strlen(tmp)) || (0 == strlen(tmp))) + { + return SW_BAD_VALUE; + } + + for (j = 0; j < strlen(tmp); j++) + { + if (A_FALSE == is_hex(tmp[j])) + return SW_BAD_VALUE; + } + + sscanf(tmp, "%x", &addr); + if (0xff < addr) + { + return SW_BAD_VALUE; + } + + mac.uc[i++] = addr; + tmp = (void *) strtok_r(NULL, "-", &str_save); + } + + if (6 != i) + { + return SW_BAD_VALUE; + } + + *(fal_mac_addr_t *) val = mac; + return SW_OK; +} + +void +cmd_data_print_macaddr(a_char_t * param_name, a_uint32_t * buf, + a_uint32_t size) +{ + a_uint32_t i; + fal_mac_addr_t *val; + + val = (fal_mac_addr_t *) buf; + dprintf("%s", param_name); + for (i = 0; i < 5; i++) + { + dprintf("%02x-", val->uc[i]); + } + dprintf("%02x", val->uc[5]); + fflush(stdout); + +} +/*qca808x_end*/ +sw_error_t +cmd_data_check_fdbentry(char *info, void *val, a_uint32_t size) +{ + char *cmd, *cmd_find; + sw_error_t rv; + fal_fdb_entry_t entry; + a_uint32_t tmp = 0; + + memset(&entry, 0, sizeof (fal_fdb_entry_t)); + + do + { + cmd = get_sub_cmd("addr", NULL); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the format is xx-xx-xx-xx-xx-xx \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_macaddr(cmd, &entry.addr, + sizeof (fal_mac_addr_t)); + if (SW_OK != rv) + dprintf("usage: the format is xx-xx-xx-xx-xx-xx \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("fid", "65535"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 1 -- 4095 or 65535\n"); + rv = SW_BAD_VALUE; + } + else if (0 == cmd[0]) + { + entry.fid = 65535; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: the range is 1 -- 4095 or 65535\n"); + } + } + while (talk_mode && (SW_OK != rv)); + entry.fid = tmp & 0xffff; + + do + { + cmd = get_sub_cmd("dacmd", "forward"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_maccmd(cmd, &entry.dacmd, + sizeof (fal_fwd_cmd_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("sacmd", "forward"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_maccmd(cmd, &entry.sacmd, + sizeof (fal_fwd_cmd_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("dest port", "null"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: input port number such as 1,3\n"); + rv = SW_BAD_VALUE; + } + else + { + cmd_find = strstr(cmd, ","); + if (cmd_find == NULL) + { + rv = cmd_data_check_portid(cmd, &entry.port.id, sizeof (fal_port_t)); + entry.portmap_en = A_FALSE; + } + else + { + rv = cmd_data_check_portmap(cmd, &entry.port.map, sizeof (fal_pbmp_t)); + entry.portmap_en = A_TRUE; + } + if (SW_OK != rv) + dprintf("usage: input port number such as 1,3\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("static", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.static_en, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("leaky", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.leaky_en, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("mirror", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.mirror_en, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("clone", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.clone_en, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("queue override", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.da_pri_en, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + if (A_TRUE == entry.da_pri_en) + { + do + { + cmd = get_sub_cmd("queue", NULL); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: input number such as <0/1/2/3>\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: input number such as <0/1/2/3>\n"); + } + + } + while (talk_mode && (SW_OK != rv)); + entry.da_queue = tmp; + } + + do + { + cmd = get_sub_cmd("cross_pt_state", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.cross_pt_state, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("white_list_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.white_list_en, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("load_balance_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.load_balance_en, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + if (A_TRUE == entry.load_balance_en) + { + do + { + cmd = get_sub_cmd("load_balance", NULL); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: input number such as <0/1/2/3>\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: input number such as <0/1/2/3>\n"); + } + + } + while (talk_mode && (SW_OK != rv)); + entry.load_balance = tmp; + } + + *(fal_fdb_entry_t *) val = entry; + + return SW_OK; +} + +void +cmd_data_print_fdbentry(a_uint8_t * param_name, a_uint32_t * buf, + a_uint32_t size) +{ + a_uint32_t tmp, port_type; + fal_fdb_entry_t *entry; + + entry = (fal_fdb_entry_t *) buf; + dprintf("\n"); + cmd_data_print_macaddr("[addr]:", (a_uint32_t *) & (entry->addr), + sizeof (fal_mac_addr_t)); + dprintf(" "); + dprintf("[fid]:%d", entry->fid); + dprintf(" "); + cmd_data_print_confirm("[static]:", entry->static_en, sizeof (a_bool_t)); + dprintf(" "); + if (entry->portmap_en == A_TRUE) + cmd_data_print_portmap("[dest_port]:", entry->port.map, sizeof (fal_pbmp_t)); + else { + port_type = FAL_PORT_ID_TYPE(entry->port.id); + if (port_type == 1 && entry->port.id == 0x1000020) + dprintf("[dest_port]:0x%x(trunk0)", entry->port.id); + else if (port_type == 1 && entry->port.id == 0x1000021) + dprintf("[dest_port]:0x%x(trunk1)", entry->port.id); + else if (port_type == 2) + dprintf("[dest_port]:0x%x(virtual port)", entry->port.id); + else + dprintf("[dest_port]:%d", entry->port.id); + } + dprintf(" \n"); + cmd_data_print_maccmd("dacmd", (a_uint32_t *) & (entry->dacmd), + sizeof (fal_fwd_cmd_t)); + dprintf(" "); + cmd_data_print_maccmd("sacmd", (a_uint32_t *) & (entry->sacmd), + sizeof (fal_fwd_cmd_t)); + dprintf(" "); + cmd_data_print_confirm("[leaky]:", entry->leaky_en, sizeof (a_bool_t)); + dprintf(" "); + cmd_data_print_confirm("[mirror]:", entry->mirror_en, sizeof (a_bool_t)); + dprintf(" "); + cmd_data_print_confirm("[clone]:", entry->clone_en, sizeof (a_bool_t)); + dprintf(" "); + cmd_data_print_confirm("[da_pri]:", entry->da_pri_en, sizeof (a_bool_t)); + dprintf(" "); + if (A_TRUE == entry->da_pri_en) + { + tmp = entry->da_queue; + dprintf("[queue]:%d", tmp); + } + else + { + dprintf("[queue]:0"); + } + dprintf(" "); + cmd_data_print_confirm("[cross_pt_state]:", entry->cross_pt_state, sizeof (a_bool_t)); + dprintf(" "); + cmd_data_print_confirm("[white_list_en]:", entry->white_list_en, sizeof (a_bool_t)); + dprintf(" "); + cmd_data_print_confirm("[load_balance_en]:", entry->load_balance_en, sizeof (a_bool_t)); + if (A_TRUE == entry->load_balance_en) + { + tmp = entry->load_balance; + dprintf(" "); + dprintf("[load_balance]:%d", tmp); + } + dprintf("\n"); + + return; +} + +sw_error_t +cmd_data_check_maclimit_ctrl(char *info, void *val, a_uint32_t size) +{ + a_char_t *cmd; + sw_error_t rv; + fal_maclimit_ctrl_t maclimit_ctrl; + + memset(&maclimit_ctrl, 0, sizeof (fal_maclimit_ctrl_t)); + + do + { + cmd = get_sub_cmd("maclimit status", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &maclimit_ctrl.enable, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("maclimit counter", "2048"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 2048 \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &maclimit_ctrl.limit_num, + sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: the range is 0 -- 2048 \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("maclimit exceed action", "forward"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_maccmd(cmd, &maclimit_ctrl.action, + sizeof (fal_fwd_cmd_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + *(fal_maclimit_ctrl_t *) val = maclimit_ctrl; + + return SW_OK; +} + +void +cmd_data_print_maclimit_ctrl(a_uint8_t * param_name, a_uint32_t * buf, + a_uint32_t size) +{ + fal_maclimit_ctrl_t *maclimit_ctrl; + + maclimit_ctrl = (fal_maclimit_ctrl_t *) buf; + dprintf("\n"); + cmd_data_print_confirm("[maclimit status]:", maclimit_ctrl->enable, sizeof (a_bool_t)); + dprintf(" "); + cmd_data_print_uint32("maclimit counter", (a_uint32_t *) & (maclimit_ctrl->limit_num), 4); + dprintf(" "); + cmd_data_print_maccmd("maclimit exceed action", (a_uint32_t *) & (maclimit_ctrl->action), + sizeof (fal_fwd_cmd_t)); + dprintf("\n"); + + return; +} +/*qca808x_start*/ + +#define cmd_data_check_element(info, defval, usage, chk_func, param) \ +{\ + sw_error_t ret;\ + do {\ + cmd = get_sub_cmd(info, defval);\ + SW_RTN_ON_NULL_PARAM(cmd);\ + \ + if (!strncasecmp(cmd, "quit", 4)) {\ + return SW_BAD_VALUE;\ + } else if (!strncasecmp(cmd, "help", 4)) {\ + dprintf("%s", usage);\ + ret = SW_BAD_VALUE;\ + } else {\ + ret = chk_func param; \ + if (SW_OK != ret)\ + dprintf("%s", usage);\ + else\ + append_acl_cmd(cmd);\ + }\ + } while (talk_mode && (SW_OK != ret));\ +} + +sw_error_t +cmd_data_check_integer(char *cmd_str, a_uint32_t * arg_val, a_uint32_t max_val, + a_uint32_t min_val) +{ + a_uint32_t tmp; + a_uint32_t i; + + if (NULL == cmd_str) + { + return SW_BAD_PARAM; + } + + if (0 == cmd_str[0]) + { + return SW_BAD_PARAM; + } + + if ((cmd_str[0] == '0') && ((cmd_str[1] == 'x') || (cmd_str[1] == 'X'))) + { + for (i = 2; i < strlen(cmd_str); i++) + { + if (A_FALSE == is_hex(cmd_str[i])) + { + return SW_BAD_VALUE; + } + } + sscanf(cmd_str, "%x", &tmp); + } + else + { + for (i = 0; i < strlen(cmd_str); i++) + { + if (A_FALSE == is_dec(cmd_str[i])) + { + return SW_BAD_VALUE; + } + } + sscanf(cmd_str, "%d", &tmp); + } + + if ((tmp > max_val) || (tmp < min_val)) + return SW_BAD_PARAM; + + *arg_val = tmp; + return SW_OK; +} +/*qca808x_end*/ +sw_error_t +cmd_data_check_ruletype(char *cmd_str, fal_acl_rule_type_t * arg_val, + a_uint32_t size) +{ + if (NULL == cmd_str) + { + return SW_BAD_VALUE; + } + + if (!strcasecmp(cmd_str, "mac")) + { + *arg_val = FAL_ACL_RULE_MAC; + } + else if (!strcasecmp(cmd_str, "ip4")) + { + *arg_val = FAL_ACL_RULE_IP4; + } + else if (!strcasecmp(cmd_str, "ip6")) + { + *arg_val = FAL_ACL_RULE_IP6; + } + else if (!strcasecmp(cmd_str, "udf")) + { + *arg_val = FAL_ACL_RULE_UDF; + } + else + { + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_ruletype(char * param_name, a_uint32_t * buf, + a_uint32_t size) +{ + fal_acl_rule_type_t *val; + + val = (fal_acl_rule_type_t *) buf; + dprintf("%s", param_name); + + if (FAL_ACL_RULE_MAC == *val) + { + dprintf("mac"); + } + else if (FAL_ACL_RULE_IP4 == *val) + { + dprintf("ip4"); + } + else if (FAL_ACL_RULE_IP6 == *val) + { + dprintf("ip6"); + } + else if (FAL_ACL_RULE_UDF == *val) + { + dprintf("udf"); + } + else + { + dprintf("unknow"); + } +} +sw_error_t +cmd_data_check_ip_packet_type(char *cmd_str, a_uint32_t * arg_val, + a_uint32_t size) +{ + if (NULL == cmd_str) + { + return SW_BAD_VALUE; + } + + if (!strcasecmp(cmd_str, "tcp")) + { + *arg_val = 0; + } + else if (!strcasecmp(cmd_str, "udp")) + { + *arg_val = 1; + } + else if (!strcasecmp(cmd_str, "udp-lite")) + { + *arg_val = 3; + } + else if (!strcasecmp(cmd_str, "arp")) + { + *arg_val = 5; + } + else if (!strcasecmp(cmd_str, "icmp")) + { + *arg_val = 7; + } + else + { + return SW_BAD_VALUE; + } + + return SW_OK; +} + + +void +cmd_data_print_ip_packet_type(char * param_name, a_uint16_t * buf, + a_uint32_t size) +{ + a_uint16_t *val; + + val = buf; + dprintf("%s", param_name); + + if (0 == *val) + { + dprintf("tcp"); + } + else if (1 == *val) + { + dprintf("udp"); + } + else if (3 == *val) + { + dprintf("udp-lite"); + } + else if (5 == *val) + { + dprintf("arp"); + } + else if (7 == *val) + { + dprintf("icmp"); + } + else + { + dprintf("unknow"); + } +} + +sw_error_t +cmd_data_check_fieldop(char *cmdstr, fal_acl_field_op_t def, + fal_acl_field_op_t * val) +{ + if (0 == cmdstr[0]) + { + *val = def; + } + else if ((!strcasecmp(cmdstr, "mask")) || (!strcasecmp(cmdstr, "m"))) + { + *val = FAL_ACL_FIELD_MASK; + } + else if ((!strcasecmp(cmdstr, "range")) || (!strcasecmp(cmdstr, "r"))) + { + *val = FAL_ACL_FIELD_RANGE; + } + else if ((!strcasecmp(cmdstr, "le")) || (!strcasecmp(cmdstr, "l"))) + { + *val = FAL_ACL_FIELD_LE; + } + else if ((!strcasecmp(cmdstr, "ge")) || (!strcasecmp(cmdstr, "g"))) + { + *val = FAL_ACL_FIELD_GE; + } + else if ((!strcasecmp(cmdstr, "ne")) || (!strcasecmp(cmdstr, "n"))) + { + *val = FAL_ACL_FIELD_NE; + } + else + { + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_fieldop(char * param_name, a_uint32_t * buf, + a_uint32_t size) +{ + fal_acl_field_op_t *val; + + val = (fal_acl_field_op_t *) buf; + dprintf("%s", param_name); + + if (FAL_ACL_FIELD_MASK == *val) + { + dprintf("mask"); + } + else if (FAL_ACL_FIELD_RANGE == *val) + { + dprintf("range"); + } + else if (FAL_ACL_FIELD_LE == *val) + { + dprintf("le"); + } + else if (FAL_ACL_FIELD_GE == *val) + { + dprintf("ge"); + } + else if (FAL_ACL_FIELD_NE == *val) + { + dprintf("ne"); + } + else + { + dprintf("unknow"); + } +} + +sw_error_t +cmd_data_check_ip4addr(char *cmdstr, void * val, a_uint32_t size) +{ + char *tmp = NULL, *str_save; + a_uint32_t i = 0, j; + a_uint32_t addr; + fal_ip4_addr_t ip4; + char cmd[128+1] = { 0 }; + + memset(&ip4, 0, sizeof (fal_ip4_addr_t)); + if (NULL == cmdstr) + { + return SW_BAD_VALUE; + } + + if (0 == cmdstr[0]) + { + return SW_BAD_VALUE; + } + + for (i = 0; i < 128; i++) + { + if (0 == cmdstr[i]) + { + break; + } + } + + i++; + if (128 < i) + { + i = 128; + } + + memcpy(cmd, cmdstr, i); + + /* make sure the string can be terminated */ + cmd[i] = '\0'; + tmp = (void *) strtok_r(cmd, ".", &str_save); + i = 0; + while (tmp) + { + if (4 <= i) + { + return SW_BAD_VALUE; + } + + if ((3 < strlen(tmp)) || (0 == strlen(tmp))) + { + return SW_BAD_VALUE; + } + + for (j = 0; j < strlen(tmp); j++) + { + if (A_FALSE == is_dec(tmp[j])) + { + return SW_BAD_VALUE; + } + } + + sscanf(tmp, "%d", &addr); + if (255 < addr) + { + return SW_BAD_VALUE; + } + + ip4 |= ((addr & 0xff) << (24 - i * 8)); + i++; + tmp = (void *) strtok_r(NULL, ".", &str_save); + } + + if (4 != i) + { + return SW_BAD_VALUE; + } + + *(fal_ip4_addr_t*)val = ip4; + return SW_OK; +} + +void +cmd_data_print_ip4addr(a_char_t * param_name, a_uint32_t * buf, + a_uint32_t size) +{ + a_uint32_t i; + fal_ip4_addr_t ip4; + + ip4 = *((fal_ip4_addr_t *) buf); + dprintf("%s", param_name); + for (i = 0; i < 3; i++) + { + dprintf("%d.", (ip4 >> (24 - i * 8)) & 0xff); + } + dprintf("%d", (ip4 & 0xff)); +} + +sw_error_t +cmd_data_check_multi(char *info, void *val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_igmp_sg_entry_t entry; + + memset(&entry, 0, sizeof (fal_igmp_sg_entry_t)); + + do + { + cmd = get_sub_cmd("group type", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.group.type), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + if(entry.group.type==0) + { + cmd_data_check_element("group ip4 addr", "0.0.0.0", + "usage: the format is xx.xx.xx.xx \n", + cmd_data_check_ip4addr, (cmd, &(entry.group.u.ip4_addr), 4)); + } + else + cmd_data_check_element("group ip6 addr", NULL, + "usage: the format is xxxx::xxxx \n", + cmd_data_check_ip6addr, (cmd, &(entry.group.u.ip6_addr), 16)); + + do + { + cmd = get_sub_cmd("source type", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.source.type), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + if(entry.source.type==0) + { + cmd_data_check_element("source ip4 addr", "0.0.0.0", + "usage: the format is xx.xx.xx.xx \n", + cmd_data_check_ip4addr, (cmd, &(entry.source.u.ip4_addr), 4)); + } + else + cmd_data_check_element("source ip6 addr", NULL, + "usage: the format is xxxx::xxxx \n", + cmd_data_check_ip6addr, (cmd, &(entry.source.u.ip6_addr), 16)); + + do + { + cmd = get_sub_cmd("portmap", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.port_map), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("vlanid", "0xffff"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 4095 or 65535\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.vlan_id), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: the range is 0 -- 4095 or 65535\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + *(fal_igmp_sg_entry_t *)val = entry; + + return SW_OK; +} +void +cmd_data_print_multi(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_igmp_sg_entry_t *entry; + + entry = (fal_igmp_sg_entry_t *) buf; + + dprintf("\n[multicast info]: [group type]:%x [source type]:%x ", entry->group.type, entry->source.type); + + if(entry->group.type == 0) + cmd_data_print_ip4addr("\n[group ip4 addr]:", + (a_uint32_t *) & (entry->group.u.ip4_addr), + sizeof (fal_ip4_addr_t)); + else + cmd_data_print_ip6addr("\n[group ip6 addr]:", + (a_uint32_t *) & (entry->group.u.ip6_addr), + sizeof (fal_ip6_addr_t)); + + if(entry->source.type == 0) + cmd_data_print_ip4addr("\n[source ip4 addr]:", + (a_uint32_t *) & (entry->source.u.ip4_addr), + sizeof (fal_ip4_addr_t)); + else + cmd_data_print_ip6addr("\n[source ip6 addr]:", + (a_uint32_t *) & (entry->source.u.ip6_addr), + sizeof (fal_ip6_addr_t)); + + dprintf("\n[entry portmap]: [portmap]:0x%x ", entry->port_map); + dprintf("\n[entry vlanid]: [vlanid]:%d ", entry->vlan_id); + +} + +sw_error_t +cmd_data_check_ip6addr(char *cmdstr, void * val, a_uint32_t size) +{ + char *tmp = NULL, *str_save; + a_uint32_t j; + a_uint32_t i = 0, cnt = 0, rep = 0, loc = 0; + a_uint32_t data; + a_uint32_t addr[8]; + fal_ip6_addr_t ip6; + + if (NULL == cmdstr) + { + return SW_BAD_VALUE; + } + + if (0 == cmdstr[0]) + { + return SW_BAD_VALUE; + } + + for (i = 0; i < 8; i++) + { + addr[i] = 0; + } + + for (i = 0; i < strlen(cmdstr); i++) + { + if (':' == cmdstr[i]) + { + if ((i == (strlen(cmdstr) - 1)) + || (0 == i)) + { + return SW_BAD_VALUE; + } + cnt++; + + if (':' == cmdstr[i - 1]) + { + rep++; + loc = cnt - 1; + } + } + } + + if (1 < rep) + { + return SW_BAD_VALUE; + } + + tmp = (void *) strtok_r(cmdstr, ":", &str_save); + i = 0; + while (tmp) + { + if (8 <= i) + { + return SW_BAD_VALUE; + } + + if ((4 < strlen(tmp)) || (0 == strlen(tmp))) + { + return SW_BAD_VALUE; + } + + for (j = 0; j < strlen(tmp); j++) + { + if (A_FALSE == is_hex(tmp[j])) + { + return SW_BAD_VALUE; + } + } + + sscanf(tmp, "%x", &data); + if (65535 < data) + { + return SW_BAD_VALUE; + } + + addr[i++] = data; + tmp = (void *) strtok_r(NULL, ":", &str_save); + } + + if (0 == rep) + { + if (8 != i) + { + return SW_BAD_VALUE; + } + } + else + { + if (8 <= i) + { + return SW_BAD_VALUE; + } + + for (j = i - 1; j >= loc; j--) + { + addr[8 - i + j] = addr[j]; + addr[j] = 0; + } + } + + for (i = 0; i < 4; i++) + { + ip6.ul[i] = (addr[i * 2] << 16) | addr[i * 2 + 1]; + } + + dprintf("\n"); + for (i = 0; i < 4; i++) + { + dprintf("%08x ", ip6.ul[i]); + } + dprintf("\n"); + + *(fal_ip6_addr_t*)val = ip6; + return SW_OK; +} + +void +cmd_data_print_ip6addr(a_char_t * param_name, a_uint32_t * buf, + a_uint32_t size) +{ + a_uint32_t i; + fal_ip6_addr_t ip6; + + ip6 = *(fal_ip6_addr_t *) buf; + dprintf("%s", param_name); + for (i = 0; i < 3; i++) + { + dprintf("%x:%x:", (ip6.ul[i] >> 16) & 0xffff, ip6.ul[i] & 0xffff); + } + dprintf("%x:%x", (ip6.ul[3] >> 16) & 0xffff, ip6.ul[3] & 0xffff); +} + +sw_error_t +cmd_data_check_mac_field(fal_acl_rule_t * entry) +{ + char *cmd; + a_uint32_t tmpdata = 0; + + /* get fake mac header field configuration */ + cmd_data_check_element("Fake mac header field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if(tmpdata) + { + entry->is_fake_mac_header_mask = 1; + cmd_data_check_element("Is fake mac header", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &entry->is_fake_mac_header_val, + sizeof (a_bool_t))); + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_FAKE_MAC_HEADER); + } + + /* get SNAP field configuration */ + cmd_data_check_element("SNAP/LLC other field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if(tmpdata) + { + entry->is_snap_mask= 1; + cmd_data_check_element("Is SNAP packet", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &entry->is_snap_val, + sizeof (a_bool_t))); + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_SNAP); + } + + /* get ethernet field configuration */ + cmd_data_check_element("ethernet/other field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if(tmpdata) + { + entry->is_ethernet_mask = 1; + cmd_data_check_element("Is ethernet packet", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &entry->is_ethernet_val, + sizeof (a_bool_t))); + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_ETHERNET); + } + + /* get IP/NON-IP field configuration */ + cmd_data_check_element("IP/NON-IP field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if(tmpdata) + { + entry->is_ip_mask = 1; + cmd_data_check_element("Is IP packet", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &entry->is_ip_val, + sizeof (a_bool_t))); + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_IP); + } + /* get IPv4/IPv6 field configuration */ + cmd_data_check_element("IPv4/IPv6 field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if(tmpdata) + { + entry->is_ipv6_mask = 1; + cmd_data_check_element("Is IPv6 packet", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &entry->is_ipv6_val, + sizeof (a_bool_t))); + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_IPV6); + } + /* get destination mac address field configuration */ + cmd_data_check_element("mac dst addr field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + + if (tmpdata) + { + cmd_data_check_element("dst mac addr", NULL, + "usage: the format is xx-xx-xx-xx-xx-xx \n", + cmd_data_check_macaddr, (cmd, + &(entry->dest_mac_val), + sizeof + (fal_mac_addr_t))); + + cmd_data_check_element("dst mac addr mask", NULL, + "usage: the format is xx-xx-xx-xx-xx-xx \n", + cmd_data_check_macaddr, (cmd, + &(entry->dest_mac_mask), + sizeof + (fal_mac_addr_t))); + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_MAC_DA); + } + + /* get source mac address field configuration */ + cmd_data_check_element("mac src addr field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + + if (tmpdata) + { + cmd_data_check_element("src mac addr", NULL, + "usage: the format is xx-xx-xx-xx-xx-xx \n", + cmd_data_check_macaddr, (cmd, + &(entry->src_mac_val), + sizeof + (fal_mac_addr_t))); + + cmd_data_check_element("src mac addr mask", NULL, + "usage: the format is xx-xx-xx-xx-xx-xx \n", + cmd_data_check_macaddr, (cmd, + &(entry->src_mac_mask), + sizeof + (fal_mac_addr_t))); + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_MAC_SA); + } + + /* get ethernet type field configuration */ + cmd_data_check_element("ethernet type field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + + if (tmpdata) + { + cmd_data_check_element("ethernet type", NULL, + "usage: the format is 0x0-0xffff or 0-65535\n", + cmd_data_check_integer, (cmd, &tmpdata, 0xffff, + 0x0)); + entry->ethtype_val = tmpdata & 0xffff; + + cmd_data_check_element("ethernet type mask", NULL, + "usage: the format is 0x0-0xffff or 0-65535\n", + cmd_data_check_integer, (cmd, &tmpdata, 0xffff, + 0x0)); + entry->ethtype_mask = tmpdata & 0xffff; + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_MAC_ETHTYPE); + } + + /* get vlanid field configuration */ + cmd_data_check_element("vlanid field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + + if (tmpdata) + { + cmd_data_check_element("vlanid opration", "mask", + "usage: \n", + cmd_data_check_fieldop, (cmd, FAL_ACL_FIELD_MASK, + &(entry->vid_op))); + + if (FAL_ACL_FIELD_MASK == entry->vid_op) + { + cmd_data_check_element("vlanid", NULL, + "usage: the format is 0x0-0xfff or 0-4095 \n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xfff, 0x0)); + entry->vid_val = tmpdata & 0xfff; + + cmd_data_check_element("vlanid mask", NULL, + "usage: the format is 0x0-0xfff or 0-4095 \n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xfff, 0x0)); + entry->vid_mask = tmpdata & 0xfff; + } + else if (FAL_ACL_FIELD_RANGE == entry->vid_op) + { + cmd_data_check_element("vlanid low", NULL, + "usage: the format is 0x0-0xfff or 0-4095 \n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xfff, 0x0)); + entry->vid_val = tmpdata & 0xfff; + + cmd_data_check_element("vlanid high", NULL, + "usage: the format is 0x0-0xfff or 0-4095 \n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xfff, 0x0)); + entry->vid_mask = tmpdata & 0xfff; + } + else + { + cmd_data_check_element("vlanid", NULL, + "usage: the format is 0x0-0xfff or 0-4095 \n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xfff, 0x0)); + entry->vid_val = tmpdata & 0xfff; + } + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_MAC_VID); + } + + /* get vlan tagged field configuration */ + cmd_data_check_element("vlan tagged field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + + if (tmpdata) + { + cmd_data_check_element("tagged", NULL, + "usage: the format is 0x0-0x1 or 0-1 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0x1, + 0x0)); + entry->tagged_val = tmpdata & 0x1; + + cmd_data_check_element("tagged mask", NULL, + "usage: the format is 0x0-0x1 or 0-1 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0x1, + 0x0)); + entry->tagged_mask = tmpdata & 0x1; + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_MAC_TAGGED); + } + + /* get up field configuration */ + cmd_data_check_element("up field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + + if (tmpdata) + { + cmd_data_check_element("up", NULL, + "usage: the format is 0x0-0x7 or 0-7 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0x7, + 0x0)); + entry->up_val = tmpdata & 0x7; + + cmd_data_check_element("up mask", NULL, + "usage: the format is 0x0-0x7 or 0-7 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0x7, + 0x0)); + entry->up_mask = tmpdata & 0x7; + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_MAC_UP); + } + + /* get cfi field configuration */ + cmd_data_check_element("cfi field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + + if (tmpdata) + { + cmd_data_check_element("cfi", NULL, + "usage: the format is 0x0-0x1 or 0-1 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0x1, + 0x0)); + entry->cfi_val = tmpdata & 0x1; + + cmd_data_check_element("cfi mask", NULL, + "usage: the format is 0x0-0x1 or 0-1 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0x1, + 0x0)); + entry->cfi_mask = tmpdata & 0x1; + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_MAC_CFI); + } + + /* get svlan tagged field configuration */ + cmd_data_check_element("svlan tagged field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + + if (tmpdata) + { + cmd_data_check_element("stagged", NULL, + "usage: the format is 0x0-0x7\n", + cmd_data_check_integer, (cmd, &tmpdata, 0x7, + 0x0)); + entry->stagged_val = tmpdata & 0x7; + + cmd_data_check_element("stagged mask", NULL, + "usage: the format is 0x0-0x7\n", + cmd_data_check_integer, (cmd, &tmpdata, 0x7, + 0x0)); + entry->stagged_mask = tmpdata & 0x7; + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_MAC_STAGGED); + } + + /* get stag vlanid field configuration */ + cmd_data_check_element("stag vid field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + + if (tmpdata) + { + cmd_data_check_element("stag vid opration", "mask", + "usage: \n", + cmd_data_check_fieldop, (cmd, FAL_ACL_FIELD_MASK, + &(entry->stag_vid_op))); + if (FAL_ACL_FIELD_MASK == entry->stag_vid_op) + { + cmd_data_check_element("stag vid", NULL, + "usage: the format is 0x0-0xfff or 0-4095 \n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xfff, 0x0)); + entry->stag_vid_val = tmpdata & 0xfff; + + cmd_data_check_element("stag vid mask", NULL, + "usage: the format is 0x0-0xfff or 0-4095 \n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xfff, 0x0)); + entry->stag_vid_mask = tmpdata & 0xfff; + } + else if (FAL_ACL_FIELD_RANGE == entry->stag_vid_op) + { + cmd_data_check_element("stag vid low", NULL, + "usage: the format is 0x0-0xfff or 0-4095 \n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xfff, 0x0)); + entry->stag_vid_val = tmpdata & 0xfff; + + cmd_data_check_element("stag vid high", NULL, + "usage: the format is 0x0-0xfff or 0-4095 \n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xfff, 0x0)); + entry->stag_vid_mask = tmpdata & 0xfff; + } + else + { + cmd_data_check_element("stag vid", NULL, + "usage: the format is 0x0-0xfff or 0-4095 \n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xfff, 0x0)); + entry->stag_vid_val = tmpdata & 0xfff; + } + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_MAC_STAG_VID); + } + + + /* get stag priority field configuration */ + cmd_data_check_element("stag pri field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + + if (tmpdata) + { + cmd_data_check_element("stag pri", NULL, + "usage: the format is 0x0-0x7 or 0-7 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0x7, + 0x0)); + entry->stag_pri_val = tmpdata & 0x7; + + cmd_data_check_element("stag pri mask", NULL, + "usage: the format is 0x0-0x7 or 0-7 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0x7, + 0x0)); + entry->stag_pri_mask = tmpdata & 0x7; + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_MAC_STAG_PRI); + } + + /* get stag dei field configuration */ + cmd_data_check_element("stag dei field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + + if (tmpdata) + { + cmd_data_check_element("stag dei", NULL, + "usage: the format is 0x0-0x1 or 0-1 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0x1, + 0x0)); + entry->stag_dei_val = tmpdata & 0x1; + + cmd_data_check_element("stag dei mask", NULL, + "usage: the format is 0x0-0x1 or 0-1 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0x1, + 0x0)); + entry->stag_dei_mask = tmpdata & 0x1; + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_MAC_STAG_DEI); + } + + /* get cvlan tagged field configuration */ + cmd_data_check_element("cvlan tagged field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + + if (tmpdata) + { + cmd_data_check_element("ctagged", NULL, + "usage: the format is 0x0-0x7\n", + cmd_data_check_integer, (cmd, &tmpdata, 0x7, + 0x0)); + entry->ctagged_val = tmpdata & 0x7; + + cmd_data_check_element("ctagged mask", NULL, + "usage: the format is 0x0-0x7\n", + cmd_data_check_integer, (cmd, &tmpdata, 0x7, + 0x0)); + entry->ctagged_mask = tmpdata & 0x7; + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_MAC_CTAGGED); + } + + /* get ctag vlanid field configuration */ + cmd_data_check_element("ctag vid field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + + if (tmpdata) + { + cmd_data_check_element("ctag vid opration", "mask", + "usage: \n", + cmd_data_check_fieldop, (cmd, FAL_ACL_FIELD_MASK, + &(entry->ctag_vid_op))); + + if (FAL_ACL_FIELD_MASK == entry->ctag_vid_op) + { + cmd_data_check_element("ctag vid", NULL, + "usage: the format is 0x0-0xfff or 0-4095 \n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xfff, 0x0)); + entry->ctag_vid_val = tmpdata & 0xfff; + + cmd_data_check_element("ctag vid mask", NULL, + "usage: the format is 0x0-0xfff or 0-4095 \n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xfff, 0x0)); + entry->ctag_vid_mask = tmpdata & 0xfff; + } + else if (FAL_ACL_FIELD_RANGE == entry->ctag_vid_op) + { + cmd_data_check_element("ctag vid low", NULL, + "usage: the format is 0x0-0xfff or 0-4095 \n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xfff, 0x0)); + entry->ctag_vid_val = tmpdata & 0xfff; + + cmd_data_check_element("ctag vid high", NULL, + "usage: the format is 0x0-0xfff or 0-4095 \n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xfff, 0x0)); + entry->ctag_vid_mask = tmpdata & 0xfff; + } + else + { + cmd_data_check_element("ctag vid", NULL, + "usage: the format is 0x0-0xfff or 0-4095 \n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xfff, 0x0)); + entry->ctag_vid_val = tmpdata & 0xfff; + } + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_MAC_CTAG_VID); + } + + /* get ctag priority field configuration */ + cmd_data_check_element("ctag pri field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + + if (tmpdata) + { + cmd_data_check_element("ctag pri", NULL, + "usage: the format is 0x0-0x7 or 0-7 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0x7, + 0x0)); + entry->ctag_pri_val = tmpdata & 0x7; + + cmd_data_check_element("ctag pri mask", NULL, + "usage: the format is 0x0-0x7 or 0-7 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0x7, + 0x0)); + entry->ctag_pri_mask = tmpdata & 0x7; + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_MAC_CTAG_PRI); + } + + /* get ctag cfi field configuration */ + cmd_data_check_element("ctag cfi field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + + if (tmpdata) + { + cmd_data_check_element("ctag cfi", NULL, + "usage: the format is 0x0-0x1 or 0-1 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0x1, + 0x0)); + entry->ctag_cfi_val = tmpdata & 0x1; + + cmd_data_check_element("ctag cfi mask", NULL, + "usage: the format is 0x0-0x1 or 0-1 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0x1, + 0x0)); + entry->ctag_cfi_mask = tmpdata & 0x1; + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_MAC_CTAG_CFI); + } + + /* get vsi valid field configuration */ + cmd_data_check_element("vsi valid field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if(tmpdata) + { + entry->vsi_valid_mask = 1; + cmd_data_check_element("is vsi valid", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &entry->vsi_valid, + sizeof (a_bool_t))); + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_VSI_VALID); + } + + /* get vsi field configuration */ + cmd_data_check_element("vsi field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + + if (tmpdata) + { + cmd_data_check_element("vsi", "0x0", + "usage: the format is 0x0-0x1f or 0-31 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0x1f, + 0x0)); + entry->vsi = tmpdata & 0x1f; + + cmd_data_check_element("vsi mask", NULL, + "usage: the format is 0x0-0x1f or 0-31 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0x1f, + 0x0)); + entry->vsi_mask = tmpdata & 0x1f; + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_VSI); + } + + /* get pppoe session id field configuration */ + cmd_data_check_element("pppoe session id field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + + if (tmpdata) + { + cmd_data_check_element("pppoe session id", "0x0", + "usage: the format is 0x0-0xffff or 0-65535 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0xffff, + 0x0)); + entry->pppoe_sessionid = tmpdata & 0xffff; + + cmd_data_check_element("pppoe session id mask", NULL, + "usage: the format is 0x0-0xffff or 0-65535 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0xffff, + 0x0)); + entry->pppoe_sessionid_mask = tmpdata & 0xffff; + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_PPPOE_SESSIONID); + } + return SW_OK; +} + +sw_error_t +cmd_data_check_ip4_field(fal_acl_rule_t * entry) +{ + char *cmd; + a_uint32_t tmpdata = 0; + + /* get ip4 source address field configuration */ + cmd_data_check_element("ip4 src address field", "no", + "usage: \n", cmd_data_check_confirm, + (cmd, A_FALSE, &tmpdata, sizeof (tmpdata))); + + if (tmpdata) + { + cmd_data_check_element("ip4 src addr", NULL, + "usage: the format is xx.xx.xx.xx \n", + cmd_data_check_ip4addr, (cmd, + &(entry->src_ip4_val), 4)); + + cmd_data_check_element("ip4 src addr mask", NULL, + "usage: the format is xx.xx.xx.xx \n", + cmd_data_check_ip4addr, (cmd, + &(entry->src_ip4_mask), 4)); + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_IP4_SIP); + } + + /* get ip4 destination address field configuration */ + cmd_data_check_element("ip4 dst address field", "no", + "usage: \n", cmd_data_check_confirm, + (cmd, A_FALSE, &tmpdata, sizeof (tmpdata))); + + if (tmpdata) + { + cmd_data_check_element("ip4 dst addr", NULL, + "usage: the format is xx.xx.xx.xx \n", + cmd_data_check_ip4addr, (cmd, + &(entry-> + dest_ip4_val), 4)); + + cmd_data_check_element("ip4 dst addr mask", NULL, + "usage: the format is xx.xx.xx.xx \n", + cmd_data_check_ip4addr, (cmd, + &(entry-> + dest_ip4_mask), 4)); + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_IP4_DIP); + } + + /* get ripv1 field configuration */ + cmd_data_check_element("ripv1 field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (tmpdata))); + + if (tmpdata) + { + cmd_data_check_element("ripv1", NULL, + "usage: the format is 0x0-0x1 or 0-1 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0x1, + 0x0)); + entry->ripv1_val = tmpdata & 0x1; + + cmd_data_check_element("ripv1 mask", NULL, + "usage: the format is 0x0-0x1 or 0-1 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0x1, + 0x0)); + entry->ripv1_mask = tmpdata & 0x1; + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_RIPV1); + } + + /* get dhcpv4 field configuration */ + cmd_data_check_element("dhcpv4 field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (tmpdata))); + + if (tmpdata) + { + cmd_data_check_element("dhcpv4", NULL, + "usage: the format is 0x0-0x1 or 0-1 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0x1, + 0x0)); + entry->dhcpv4_val = tmpdata & 0x1; + + cmd_data_check_element("dhcpv4 mask", NULL, + "usage: the format is 0x0-0x1 or 0-1 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0x1, + 0x0)); + entry->dhcpv4_mask = tmpdata & 0x1; + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_DHCPV4); + } + + /* get ipv4 option field configuration */ + cmd_data_check_element("ipv4 option field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (tmpdata))); + + if (tmpdata) + { + entry->is_ipv4_option_mask = 1; + cmd_data_check_element("Is ipv4 option", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &entry->is_ipv4_option_val, + sizeof (a_bool_t))); + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_IPV4_OPTION); + } + + return SW_OK; +} + +sw_error_t +cmd_data_check_ip6_field(fal_acl_rule_t * entry) +{ + char *cmd; + a_uint32_t tmpdata = 0; + + /* get ip6 source address field configuration */ + cmd_data_check_element("ip6 src address field", "no", + "usage: \n", cmd_data_check_confirm, + (cmd, A_FALSE, &tmpdata, sizeof (tmpdata))); + + if (tmpdata) + { + cmd_data_check_element("ip6 src addr", NULL, + "usage: the format is xxxx::xxxx \n", + cmd_data_check_ip6addr, (cmd, + &(entry->src_ip6_val), 16)); + + cmd_data_check_element("ip6 src addr mask", NULL, + "usage: the format is xxxx::xxxx \n", + cmd_data_check_ip6addr, (cmd, + &(entry-> + src_ip6_mask), 16)); + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_IP6_SIP); + } + + /* get ip6 destination address field configuration */ + cmd_data_check_element("ip6 dst address field", "no", + "usage: \n", cmd_data_check_confirm, + (cmd, A_FALSE, &tmpdata, sizeof (tmpdata))); + + if (tmpdata) + { + cmd_data_check_element("ip6 dst addr", NULL, + "usage: the format is xxxx::xxxx \n", + cmd_data_check_ip6addr, (cmd, + &(entry-> + dest_ip6_val), 16)); + + cmd_data_check_element("ip6 dst addr mask", NULL, + "usage: the format is xxxx::xxxx \n", + cmd_data_check_ip6addr, (cmd, + &(entry-> + dest_ip6_mask), 16)); + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_IP6_DIP); + } + + /* get ip6 flow label field configuration */ + cmd_data_check_element("ip6 flow label field", "no", + "usage: \n", cmd_data_check_confirm, + (cmd, A_FALSE, &tmpdata, sizeof (tmpdata))); + + if (tmpdata) + { + cmd_data_check_element("ip6 label", NULL, + "usage: the format is 0x0-0xfffff or 0-1048575\n", + cmd_data_check_integer, (cmd, + &(entry->ip6_lable_val), + 0xfffff, 0x0)); + + cmd_data_check_element("ip6 label mask", NULL, + "usage: the format is 0x0-0xfffff or 0-1048575\n", + cmd_data_check_integer, (cmd, + &(entry-> + ip6_lable_mask), + 0xfffff, 0x0)); + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_IP6_LABEL); + } + + /* get dhcpv6 field configuration */ + cmd_data_check_element("dhcpv6 field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (tmpdata))); + + if (tmpdata) + { + cmd_data_check_element("dhcpv6", NULL, + "usage: the format is 0x0-0x1 or 0-1 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0xff, + 0x0)); + entry->dhcpv6_val = tmpdata & 0xff; + + cmd_data_check_element("dhcpv6 mask", NULL, + "usage: the format is 0x0-0x1 or 0-1 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0xff, + 0x0)); + entry->dhcpv6_mask = tmpdata & 0xff; + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_DHCPV6); + } + + /* get mobility header field configuration */ + cmd_data_check_element("mobility header field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (tmpdata))); + + if (tmpdata) + { + entry->is_mobility_header_mask = 1; + cmd_data_check_element("Is mobility header", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &entry->is_mobility_header_val, + sizeof (a_bool_t))); + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_MOBILITY_HEADER); + } + + /* get fragment header field configuration */ + cmd_data_check_element("fragment header field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (tmpdata))); + + if (tmpdata) + { + entry->is_fragment_header_mask = 1; + cmd_data_check_element("Is fragment header", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &entry->is_fragment_header_val, + sizeof (a_bool_t))); + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_FRAGMENT_HEADER); + } + + /* get other header field configuration */ + cmd_data_check_element("other header field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (tmpdata))); + + if (tmpdata) + { + entry->is_other_header_mask = 1; + cmd_data_check_element("Is other header", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &entry->is_other_header_val, + sizeof (a_bool_t))); + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_OTHER_EXT_HEADER); + } + + return SW_OK; +} + +sw_error_t +cmd_data_check_ip_field(fal_acl_rule_t * entry) +{ + char *cmd; + a_uint32_t tmpdata = 0; + + /* get ip protocol field configuration */ + cmd_data_check_element("ip protocol field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (tmpdata))); + + if (tmpdata) + { + cmd_data_check_element("ip protocol", NULL, + "usage: the format is 0x0-0xff or 0-255 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0xff, + 0x0)); + entry->ip_proto_val = tmpdata & 0xff; + + cmd_data_check_element("ip protocol mask", NULL, + "usage: the format is 0x0-0xff or 0-255 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0xff, + 0x0)); + entry->ip_proto_mask = tmpdata & 0xff; + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_IP_PROTO); + } + + /* get ip dscp field configuration */ + cmd_data_check_element("ip dscp field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (tmpdata))); + if (tmpdata) + { + cmd_data_check_element("ip dscp", NULL, + "usage: the format is 0x0-0xff or 0-255 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0xff, + 0x0)); + entry->ip_dscp_val = tmpdata & 0xff; + + cmd_data_check_element("ip dscp mask", NULL, + "usage: the format is 0x0-0xff or 0-255 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0xff, + 0x0)); + entry->ip_dscp_mask = tmpdata & 0xff; + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_IP_DSCP); + } + + /* get ip l4 destination port field configuration */ + cmd_data_check_element("ip l4 dst port field", "no", + "usage: \n", cmd_data_check_confirm, + (cmd, A_FALSE, &tmpdata, sizeof (tmpdata))); + + if (tmpdata) + { + cmd_data_check_element("ip l4 dst port opration", "mask", + "usage: \n", + cmd_data_check_fieldop, (cmd, FAL_ACL_FIELD_MASK, + &(entry->dest_l4port_op))); + + if (FAL_ACL_FIELD_MASK == entry->dest_l4port_op) + { + cmd_data_check_element("ip l4 dst port", NULL, + "usage: the format is 0x0-0xffff or 0-65535 \n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xffff, 0x0)); + entry->dest_l4port_val = tmpdata & 0xffff; + + cmd_data_check_element("ip l4 dst port mask", NULL, + "usage: the format is 0x0-0xffff or 0-65535 \n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xffff, 0x0)); + entry->dest_l4port_mask = tmpdata & 0xffff; + } + else if (FAL_ACL_FIELD_RANGE == entry->dest_l4port_op) + { + cmd_data_check_element("ip l4 dst port low", NULL, + "usage: the format is 0x0-0xffff or 0-65535 \n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xffff, 0x0)); + entry->dest_l4port_val = tmpdata & 0xffff; + + cmd_data_check_element("ip l4 dst port high", NULL, + "usage: the format is 0x0-0xffff or 0-65535 \n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xffff, 0x0)); + entry->dest_l4port_mask = tmpdata & 0xffff; + } + else + { + cmd_data_check_element("ip l4 dst port", NULL, + "usage: the format is 0x0-0xffff or 0-65535 \n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xffff, 0x0)); + entry->dest_l4port_val = tmpdata & 0xffff; + } + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_L4_DPORT); + } + + /* get ip l4 source port field configuration */ + cmd_data_check_element("ip l4 src port field", "no", + "usage: \n", cmd_data_check_confirm, + (cmd, A_FALSE, &tmpdata, sizeof (tmpdata))); + + if (tmpdata) + { + cmd_data_check_element("ip l4 src port opration", "mask", + "usage: \n", + cmd_data_check_fieldop, (cmd, FAL_ACL_FIELD_MASK, + &(entry->src_l4port_op))); + + if (FAL_ACL_FIELD_MASK == entry->src_l4port_op) + { + cmd_data_check_element("ip l4 src port", NULL, + "usage: the format is 0x0-0xffff or 0-65535 \n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xffff, 0x0)); + entry->src_l4port_val = tmpdata & 0xffff; + + cmd_data_check_element("ip l4 src port mask", NULL, + "usage: the format is 0x0-0xffff or 0-65535 \n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xffff, 0x0)); + entry->src_l4port_mask = tmpdata & 0xffff; + } + else if (FAL_ACL_FIELD_RANGE == entry->src_l4port_op) + { + cmd_data_check_element("ip l4 src port low", NULL, + "usage: the format is 0x0-0xffff or 0-65535 \n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xffff, 0x0)); + entry->src_l4port_val = tmpdata & 0xffff; + + cmd_data_check_element("ip l4 src port high", NULL, + "usage: the format is 0x0-0xffff or 0-65535 \n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xffff, 0x0)); + entry->src_l4port_mask = tmpdata & 0xffff; + } + else + { + cmd_data_check_element("ip l4 src port", NULL, + "usage: the format is 0x0-0xffff or 0-65535 \n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xffff, 0x0)); + entry->src_l4port_val = tmpdata & 0xffff; + } + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_L4_SPORT); + } + + /* get tcp flags field configuration */ + cmd_data_check_element("tcp flags field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (tmpdata))); + + if (tmpdata) + { + cmd_data_check_element("tcp flags", NULL, + "usage: the format is 0x0-0x3f or 0-63 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0x3f, + 0x0)); + entry->tcp_flag_val = tmpdata & 0x3f; + + cmd_data_check_element("tcp flags mask", NULL, + "usage: the format is 0x0-0x3f or 0-63 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0x3f, + 0x0)); + entry->tcp_flag_mask = tmpdata & 0x3f; + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_TCP_FLAG); + } + + + /* get icmp type/code field configuration */ + cmd_data_check_element("icmp type code field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (tmpdata))); + + if (tmpdata) + { + cmd_data_check_element("icmp type code operation", "mask", + "usage: \n", + cmd_data_check_fieldop, (cmd, FAL_ACL_FIELD_MASK, + &(entry->icmp_type_code_op))); + + if (FAL_ACL_FIELD_MASK == entry->icmp_type_code_op) + { + /* get icmp type field configuration */ + cmd_data_check_element("icmp type field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (tmpdata))); + + if (tmpdata) + { + cmd_data_check_element("icmp type", NULL, + "usage: the format is 0x0-0xff or 0-255 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0xff, + 0x0)); + entry->icmp_type_val = tmpdata & 0xff; + + cmd_data_check_element("icmp type mask", NULL, + "usage: the format is 0x0-0xff or 0-255 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0xff, + 0x0)); + entry->icmp_type_mask = tmpdata & 0xff; + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_ICMP_TYPE); + } + + /* get icmp code field configuration */ + cmd_data_check_element("icmp code field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (tmpdata))); + + if (tmpdata) + { + cmd_data_check_element("icmp code", NULL, + "usage: the format is 0x0-0xff or 0-255 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0xff, + 0x0)); + entry->icmp_code_val = tmpdata & 0xff; + + cmd_data_check_element("icmp code mask", NULL, + "usage: the format is 0x0-0xff or 0-255 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0xff, + 0x0)); + entry->icmp_code_mask = tmpdata & 0xff; + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_ICMP_CODE); + } + } + else if (FAL_ACL_FIELD_RANGE == entry->icmp_type_code_op) + { + cmd_data_check_element("icmp type code low", NULL, + "usage: the format is 0x0-0xffff or 0-65535 \n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xffff, 0x0)); + entry->icmp_type_val= (tmpdata>>8) & 0xff; + entry->icmp_code_val= tmpdata & 0xff; + + cmd_data_check_element("icmp type code high", NULL, + "usage: the format is 0x0-0xffff or 0-65535 \n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xffff, 0x0)); + entry->icmp_type_mask = (tmpdata>>8) & 0xff; + entry->icmp_code_mask= tmpdata & 0xff; + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_ICMP_TYPE); + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_ICMP_CODE); + } + else + { + cmd_data_check_element("icmp type code", NULL, + "usage: the format is 0x0-0xffff or 0-65535 \n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xffff, 0x0)); + entry->icmp_type_val= (tmpdata>>8) & 0xff; + entry->icmp_code_val= tmpdata & 0xff; + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_ICMP_TYPE); + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_ICMP_CODE); + } + } + + /* get fragment field configuration */ + cmd_data_check_element("fragment field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (tmpdata))); + + if (tmpdata) + { + entry->is_fragement_mask = 1; + cmd_data_check_element("Is fragment packet", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &entry->is_fragement_val, + sizeof (a_bool_t))); + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_L3_FRAGMENT); + } + + /* get first fragment field configuration */ + cmd_data_check_element("first fragment field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (tmpdata))); + + if (tmpdata) + { + entry->is_first_frag_mask = 1; + cmd_data_check_element("Is first fragment packet", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &entry->is_first_frag_val, + sizeof (a_bool_t))); + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_FIRST_FRAGMENT); + } + + /* get L3 TTL field configuration */ + cmd_data_check_element("l3 ttl field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (tmpdata))); + + if (tmpdata) + { + entry->l3_ttl_mask = 0x3; + cmd_data_check_element("l3 ttl", "0", + "usage: 0-ttl/hoplimit is 0, 1-ttl/hoplimit is 1, 2-ttl/hoplimit is 255, 3-ttl/hoplimit is other \n", + cmd_data_check_integer, (cmd, &tmpdata, 0x3, + 0x0)); + entry->l3_ttl = tmpdata & 0x3; + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_L3_TTL); + } + + /* get l3 length field configuration */ + cmd_data_check_element("l3 length field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (tmpdata))); + + if (tmpdata) + { + cmd_data_check_element("l3 length operation", "mask", + "usage: \n", + cmd_data_check_fieldop, (cmd, FAL_ACL_FIELD_MASK, + &(entry->l3_length_op))); + + if (FAL_ACL_FIELD_MASK == entry->l3_length_op) + { + cmd_data_check_element("l3 length", NULL, + "usage: the format is 0x0-0xffff or 0-65535 \n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xffff, 0x0)); + entry->l3_length = tmpdata & 0xffff; + + cmd_data_check_element("l3 length mask", NULL, + "usage: the format is 0x0-0xffff or 0-65535 \n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xffff, 0x0)); + entry->l3_length_mask = tmpdata & 0xffff; + } + else if (FAL_ACL_FIELD_RANGE == entry->l3_length_op) + { + cmd_data_check_element("l3 length low", NULL, + "usage: the format is 0x0-0xffff or 0-65535 \n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xffff, 0x0)); + entry->l3_length = tmpdata & 0xffff; + + cmd_data_check_element("l3 length high", NULL, + "usage: the format is 0x0-0xffff or 0-65535 \n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xffff, 0x0)); + entry->l3_length_mask = tmpdata & 0xffff; + } + else + { + cmd_data_check_element("l3 length", NULL, + "usage: the format is 0x0-0xffff or 0-65535 \n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xffff, 0x0)); + entry->l3_length = tmpdata & 0xffff; + } + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_L3_LENGTH); + } + + /* get L3 packet type field configuration */ + cmd_data_check_element("l3 packet type field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (tmpdata))); + + if (tmpdata) + { + entry->l3_pkt_type_mask = 0x7; + cmd_data_check_element("l3 packet type", "tcp", + "usage: TCP, UDP, UDP-Lite, ARP, ICMP \n", + cmd_data_check_ip_packet_type, (cmd, &tmpdata,sizeof(tmpdata))); + entry->l3_pkt_type = tmpdata & 0x7; + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_IP_PKT_TYPE); + } + + /* get ah header field configuration */ + cmd_data_check_element("ah header field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (tmpdata))); + + if (tmpdata) + { + entry->is_ah_header_mask = 1; + cmd_data_check_element("Is AH header", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &entry->is_ah_header_val, + sizeof (a_bool_t))); + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_AH_HEADER); + } + + /* get esp header field configuration */ + cmd_data_check_element("esp header field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (tmpdata))); + + if (tmpdata) + { + entry->is_esp_header_mask = 1; + cmd_data_check_element("Is ESP header", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &entry->is_esp_header_val, + sizeof (a_bool_t))); + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_ESP_HEADER); + } + + return SW_OK; +} + + +sw_error_t +cmd_data_check_udf_type(char *cmdstr, fal_acl_udf_type_t * arg_val, a_uint32_t size) +{ + if (NULL == cmdstr) + { + return SW_BAD_VALUE; + } + + if (!strcasecmp(cmdstr, "l2")) + { + *arg_val = FAL_ACL_UDF_TYPE_L2; + } + else if (!strcasecmp(cmdstr, "l2snap")) + { + *arg_val = FAL_ACL_UDF_TYPE_L2_SNAP; + } + else if (!strcasecmp(cmdstr, "l3")) + { + *arg_val = FAL_ACL_UDF_TYPE_L3; + } + else if (!strcasecmp(cmdstr, "l3plus")) + { + *arg_val = FAL_ACL_UDF_TYPE_L3_PLUS; + } + else if (!strcasecmp(cmdstr, "l4")) + { + *arg_val = FAL_ACL_UDF_TYPE_L4; + } + else + { + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_udf_type(a_char_t * param_name, a_uint32_t * buf, + a_uint32_t size) +{ + fal_acl_udf_type_t *val; + + val = (fal_acl_udf_type_t *) buf; + dprintf("[%s]:", param_name); + + if (FAL_ACL_UDF_TYPE_L2 == *val) + { + dprintf("l2"); + } + else if (FAL_ACL_UDF_TYPE_L2_SNAP == *val) + { + dprintf("l2snap"); + } + else if (FAL_ACL_UDF_TYPE_L3 == *val) + { + dprintf("l3"); + } + else if (FAL_ACL_UDF_TYPE_L3_PLUS == *val) + { + dprintf("l3plus"); + } + else if (FAL_ACL_UDF_TYPE_L4 == *val) + { + dprintf("l4"); + } + else + { + dprintf("unknow"); + } +} + +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) +{ + if (NULL == cmdstr) + { + return SW_BAD_VALUE; + } + + if (!strcasecmp(cmdstr, "non-ip")) + { + *arg_val = FAL_ACL_UDF_NON_IP; + } + else if (!strcasecmp(cmdstr, "ipv4")) + { + *arg_val = FAL_ACL_UDF_IP4; + } + else if (!strcasecmp(cmdstr, "ipv6")) + { + *arg_val = FAL_ACL_UDF_IP6; + } + else + { + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_udf_pkt_type(a_char_t * param_name, a_uint32_t * buf, + a_uint32_t size) +{ + fal_acl_udf_pkt_type_t *val; + + val = (fal_acl_udf_pkt_type_t *) buf; + dprintf("%s", param_name); + + if (FAL_ACL_UDF_NON_IP== *val) + { + dprintf("non-ip"); + } + else if (FAL_ACL_UDF_IP4 == *val) + { + dprintf("ipv4"); + } + else if (FAL_ACL_UDF_IP6== *val) + { + dprintf("ipv6"); + } + else + { + dprintf("unknow"); + } +} + +sw_error_t +cmd_data_check_udf_element(char *cmdstr, a_uint8_t * val, a_uint32_t * len) +{ + char *tmp = NULL, *str_save; + a_uint32_t i = 0, j; + a_uint32_t data; + + memset(val, 0, 16); + if (NULL == cmdstr) + { + return SW_BAD_VALUE; + } + + if (0 == cmdstr[0]) + { + return SW_BAD_VALUE; + } + + tmp = (void *) strtok_r(cmdstr, "-", &str_save); + while (tmp) + { + if (16 <= i) + { + return SW_BAD_VALUE; + } + + if ((2 < strlen(tmp)) || (0 == strlen(tmp))) + { + return SW_BAD_VALUE; + } + + for (j = 0; j < strlen(tmp); j++) + { + if (A_FALSE == is_hex(tmp[j])) + { + return SW_BAD_VALUE; + } + } + + sscanf(tmp, "%x", &data); + + val[i++] = data & 0xff; + tmp = (void *) strtok_r(NULL, "-", &str_save); + } + + if (0 == i) + { + return SW_BAD_VALUE; + } + + *len = i; + return SW_OK; +} + +void +cmd_data_print_udf_element(char * param_name, a_uint32_t * buf, + a_uint32_t size) +{ + a_uint8_t *val, i; + + if (size) + { + val = (a_uint8_t *) buf; + dprintf("%s", param_name); + + for (i = 0; i < (size - 1); i++) + { + dprintf("%02x-", *val); + val++; + } + dprintf("%02x", *val); + } +} + + +sw_error_t +cmd_data_check_udf_field(fal_acl_rule_t * entry) +{ + char *cmd; + a_uint32_t tmpdata = 0, vlen = 0, mlen = 0; + + /* get udf field configuration */ + cmd_data_check_element("user define field", "no", + "usage: \n", cmd_data_check_confirm, + (cmd, A_FALSE, &tmpdata, sizeof (tmpdata))); + + if (tmpdata) + { + cmd_data_check_element("udf type", NULL, + "usage: \n", + cmd_data_check_udf_type, (cmd, + &(entry->udf_type), 4)); + + cmd_data_check_element("udf offset", NULL, + "usage: <0-126, must be even>\n", + cmd_data_check_uint32, (cmd, &tmpdata, vlen)); + entry->udf_offset = tmpdata; + + cmd_data_check_element("udf value", NULL, + "usage: the format is xx-xx-xx-xx-xx\n", + cmd_data_check_udf_element, (cmd, + &(entry->udf_val[0]), &vlen)); + + cmd_data_check_element("udf mask", NULL, + "usage: the format is xx-xx-xx-xx-xx\n", + cmd_data_check_udf_element, (cmd, + &(entry->udf_mask[0]), &mlen)); + + if (vlen != mlen) + { + return SW_BAD_VALUE; + } + entry->udf_len = vlen; + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_UDF); + } + + /* get udf0 field configuration */ + cmd_data_check_element("udf0", "no", + "usage: \n", cmd_data_check_confirm, + (cmd, A_FALSE, &tmpdata, sizeof (tmpdata))); + if (tmpdata) + { + cmd_data_check_element("udf0 opration", "mask", + "usage: \n", + cmd_data_check_fieldop, (cmd, FAL_ACL_FIELD_MASK, + &(entry->udf0_op))); + + if (FAL_ACL_FIELD_MASK == entry->udf0_op) + { + cmd_data_check_element("udf0", NULL, + "usage: the format is 0x0-0xffff\n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xffff, 0x0)); + entry->udf0_val = tmpdata & 0xffff; + + cmd_data_check_element("udf0 mask", NULL, + "usage: the format is 0x0-0xffff\n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xffff, 0x0)); + entry->udf0_mask = tmpdata & 0xffff; + } + else if (FAL_ACL_FIELD_RANGE == entry->udf0_op) + { + cmd_data_check_element("udf0 low", NULL, + "usage: the format is 0x0-0xffff or\n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xffff, 0x0)); + entry->udf0_val= tmpdata & 0xffff; + + cmd_data_check_element("udf0 high", NULL, + "usage: the format is 0x0-0xffff\n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xffff, 0x0)); + entry->udf0_mask = tmpdata & 0xffff; + } + else + { + cmd_data_check_element("udf0", NULL, + "usage: the format is 0x0-0xffff\n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xffff, 0x0)); + entry->udf0_val = tmpdata & 0xffff; + } + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_UDF0); + } + + /* get udf1 field configuration */ + cmd_data_check_element("udf1", "no", + "usage: \n", cmd_data_check_confirm, + (cmd, A_FALSE, &tmpdata, sizeof (tmpdata))); + if (tmpdata) + { + cmd_data_check_element("udf1 opration", "mask", + "usage: \n", + cmd_data_check_fieldop, (cmd, FAL_ACL_FIELD_MASK, + &(entry->udf1_op))); + + if (FAL_ACL_FIELD_MASK == entry->udf1_op) + { + cmd_data_check_element("udf1", NULL, + "usage: the format is 0x0-0xffff\n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xffff, 0x0)); + entry->udf1_val = tmpdata & 0xffff; + + cmd_data_check_element("udf1 mask", NULL, + "usage: the format is 0x0-0xffff\n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xffff, 0x0)); + entry->udf1_mask = tmpdata & 0xffff; + } + else if (FAL_ACL_FIELD_RANGE == entry->udf1_op) + { + cmd_data_check_element("udf1 low", NULL, + "usage: the format is 0x0-0xffff or\n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xffff, 0x0)); + entry->udf1_val= tmpdata & 0xffff; + + cmd_data_check_element("udf1 high", NULL, + "usage: the format is 0x0-0xffff\n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xffff, 0x0)); + entry->udf1_mask = tmpdata & 0xffff; + } + else + { + cmd_data_check_element("udf1", NULL, + "usage: the format is 0x0-0xffff\n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xffff, 0x0)); + entry->udf1_val = tmpdata & 0xffff; + } + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_UDF1); + } + + /* get udf2 field configuration */ + cmd_data_check_element("udf2", "no", + "usage: \n", cmd_data_check_confirm, + (cmd, A_FALSE, &tmpdata, sizeof (tmpdata))); + if (tmpdata) + { + + cmd_data_check_element("udf2", NULL, + "usage: the format is 0x0-0xffff\n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xffff, 0x0)); + entry->udf2_val = tmpdata & 0xffff; + + cmd_data_check_element("udf2 mask", NULL, + "usage: the format is 0x0-0xffff\n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xffff, 0x0)); + entry->udf2_mask = tmpdata & 0xffff; + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_UDF2); + } + /* get udf3 field configuration */ + cmd_data_check_element("udf3", "no", + "usage: \n", cmd_data_check_confirm, + (cmd, A_FALSE, &tmpdata, sizeof (tmpdata))); + if (tmpdata) + { + + cmd_data_check_element("udf3", NULL, + "usage: the format is 0x0-0xffff\n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xffff, 0x0)); + entry->udf3_val = tmpdata & 0xffff; + + cmd_data_check_element("udf3 mask", NULL, + "usage: the format is 0x0-0xffff\n", + cmd_data_check_integer, (cmd, &tmpdata, + 0xffff, 0x0)); + entry->udf3_mask = tmpdata & 0xffff; + + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_UDF3); + } + + if(entry->rule_type == FAL_ACL_RULE_UDF) + { + /* get IP/NON-IP field configuration */ + cmd_data_check_element("IP/NON-IP field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if(tmpdata) + { + entry->is_ip_mask = 1; + cmd_data_check_element("Is IP packet", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &entry->is_ip_val, + sizeof (a_bool_t))); + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_IP); + } + /* get IPv4/IPv6 field configuration */ + cmd_data_check_element("IPv4/IPv6 field", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if(tmpdata) + { + entry->is_ipv6_mask = 1; + cmd_data_check_element("Is IPv6 packet", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &entry->is_ipv6_val, + sizeof (a_bool_t))); + FAL_FIELD_FLG_SET(entry->field_flg, FAL_ACL_FIELD_IPV6); + } + } + + return SW_OK; +} + +sw_error_t +cmd_data_check_acl_action(fal_acl_rule_t * entry) +{ + char *cmd, *cmd_find; + a_uint32_t tmpdata = 0; + sw_error_t rv; + + /* get permit action configuration */ + cmd_data_check_element("permit", "yes", "usage: \n", + cmd_data_check_confirm, (cmd, A_TRUE, &tmpdata, + sizeof (a_bool_t))); + + if (tmpdata) + { + FAL_ACTION_FLG_SET(entry->action_flg, FAL_ACL_ACTION_PERMIT); + } + + /* get deny action configuration */ + cmd_data_check_element("deny", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + + if (tmpdata) + { + FAL_ACTION_FLG_SET(entry->action_flg, FAL_ACL_ACTION_DENY); + } + + /* get redirect to cpu action configuration */ + cmd_data_check_element("rdt to cpu", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + + if (tmpdata) + { + FAL_ACTION_FLG_SET(entry->action_flg, FAL_ACL_ACTION_RDTCPU); + } + + /* get port redirection action configuration */ + cmd_data_check_element("rdt to port", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + + if (tmpdata) + { + do + { + cmd = get_sub_cmd("dest port", "null"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: physical port such as 1,3\n"); + dprintf(" nexthop with highest 8bits as 0x1\n"); + dprintf(" vp and trunk with highest 8bits as 0x2\n"); + return SW_BAD_VALUE; + } + else + { + cmd_find = strstr(cmd, ","); + if (cmd_find == NULL) + { + rv = cmd_data_check_portid(cmd, &entry->ports, sizeof (fal_pbmp_t)); + if(entry->ports <= SW_MAX_NR_PORT) + { + entry->ports = 1<<(entry->ports); + } + } + else + { + rv = cmd_data_check_portmap(cmd, &entry->ports, sizeof (fal_pbmp_t)); + } + if(rv != SW_OK) + { + dprintf("usage: physical port such as 1,3\n"); + dprintf(" nexthop with highest 8bits as 0x1\n"); + dprintf(" vp and trunk with highest 8bits as 0x2\n"); + } + FAL_ACTION_FLG_SET(entry->action_flg, FAL_ACL_ACTION_REDPT); + } + }while (talk_mode && (SW_OK != rv)); + } + + /* get copy to cpu action configuration */ + cmd_data_check_element("copy to cpu", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + + if (tmpdata) + { + FAL_ACTION_FLG_SET(entry->action_flg, FAL_ACL_ACTION_CPYCPU); + } + + /* get mirror action configuration */ + cmd_data_check_element("mirror", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + + if (tmpdata) + { + FAL_ACTION_FLG_SET(entry->action_flg, FAL_ACL_ACTION_MIRROR); + } + + /* get remark dscp action configuration */ + cmd_data_check_element("remark dscp", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + + if (A_TRUE == tmpdata) + { + cmd_data_check_element("dscp", NULL, + "usage: the format is 0x0-0xff or 0-255\n", + cmd_data_check_integer, (cmd, &tmpdata, 0xff, + 0x0)); + entry->dscp = tmpdata & 0xff; + + cmd_data_check_element("dscp mask", NULL, + "usage: the format is 0x0-0xff or 0-255\n", + cmd_data_check_integer, (cmd, &tmpdata, 0xff, + 0x0)); + entry->dscp_mask = tmpdata & 0xff; + + FAL_ACTION_FLG_SET(entry->action_flg, FAL_ACL_ACTION_REMARK_DSCP); + } + + /* get remark up action configuration */ + cmd_data_check_element("remark up", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + + if (A_TRUE == tmpdata) + { + cmd_data_check_element("up", NULL, + "usage: the format is 0x0-0x7 or 0-7 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0x7, + 0x0)); + entry->up = tmpdata & 0x7; + + FAL_ACTION_FLG_SET(entry->action_flg, FAL_ACL_ACTION_REMARK_UP); + } + + /* get remark queue action configuration */ + cmd_data_check_element("remark queue", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + + if (tmpdata) + { + cmd_data_check_element("queue", NULL, + "usage: the format is 0x0-0xff or 0-255 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0xff, + 0x0)); + entry->queue = tmpdata & 0xff; + + FAL_ACTION_FLG_SET(entry->action_flg, FAL_ACL_ACTION_REMARK_QUEUE); + } + + /* get modify vlan action configuration */ + cmd_data_check_element("modify vlan", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + + if (A_TRUE == tmpdata) + { + cmd_data_check_element("vlan", NULL, + "usage: the format is 0x0-0xfff or 0-4095 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0xfff, + 0x0)); + entry->vid = tmpdata & 0xfff; + FAL_ACTION_FLG_SET(entry->action_flg, FAL_ACL_ACTION_MODIFY_VLAN); + + if (!FAL_ACTION_FLG_TST(entry->action_flg, FAL_ACL_ACTION_REDPT)) + { + cmd_data_check_element("port member", "null", + "usage: input port number such as 1,3\n", + cmd_data_check_portmap, (cmd, &entry->ports, + sizeof (fal_pbmp_t))); + } + } + + /* get nest vlan action configuration */ + cmd_data_check_element("nest vlan", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + + if (A_TRUE == tmpdata) + { + cmd_data_check_element("vlan", NULL, + "usage: the format is 0x1-0xfff or 1-4095 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0xfff, + 0x1)); + entry->vid = tmpdata & 0xfff; + + FAL_ACTION_FLG_SET(entry->action_flg, FAL_ACL_ACTION_NEST_VLAN); + } + + cmd_data_check_element("stag vid", "0", + "usage: the format is 0x0-0xfff or 0-4095 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0xfff, + 0x0)); + entry->stag_vid = tmpdata & 0xfff; + + cmd_data_check_element("ctag vid", "0", + "usage: the format is 0x0-0xfff or 0-4095 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0xfff, + 0x0)); + entry->ctag_vid = tmpdata & 0xfff; + + /* chang lookup vid action configuration */ + cmd_data_check_element("lookup vid change", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (A_TRUE == tmpdata) + { + FAL_ACTION_FLG_SET(entry->action_flg, FAL_ACL_ACTION_REMARK_LOOKUP_VID); + } + + /* chang stag vid action configuration */ + cmd_data_check_element("stag vid change", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (A_TRUE == tmpdata) + { + FAL_ACTION_FLG_SET(entry->action_flg, FAL_ACL_ACTION_REMARK_STAG_VID); + cmd_data_check_element("stag format", NULL, + "usage: 0-untaged, 1-pritagged or tagged\n", + cmd_data_check_integer, (cmd, &tmpdata, 0x1, + 0x0)); + entry->stag_fmt = tmpdata & 0x1; + } + + /* chang stag pri action configuration */ + cmd_data_check_element("stag pri change", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (A_TRUE == tmpdata) + { + cmd_data_check_element("stag pri", NULL, + "usage: the format is 0x1-0x7 or 0-7 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0x7, + 0x0)); + entry->stag_pri = tmpdata & 0x7; + + FAL_ACTION_FLG_SET(entry->action_flg, FAL_ACL_ACTION_REMARK_STAG_PRI); + } + + /* chang stag dei action configuration */ + cmd_data_check_element("stag dei change", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (A_TRUE == tmpdata) + { + cmd_data_check_element("stag dei", NULL, + "usage: the format is 0x0-0x1 or 0-1 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0x1, + 0x0)); + entry->stag_dei = tmpdata & 0x1; + + FAL_ACTION_FLG_SET(entry->action_flg, FAL_ACL_ACTION_REMARK_STAG_DEI); + } + + /* chang ctag vid action configuration */ + cmd_data_check_element("ctag vid change", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (A_TRUE == tmpdata) + { + FAL_ACTION_FLG_SET(entry->action_flg, FAL_ACL_ACTION_REMARK_CTAG_VID); + + cmd_data_check_element("ctag format", NULL, + "usage: 0-untaged, 1-pritagged or tagged\n", + cmd_data_check_integer, (cmd, &tmpdata, 0x1, + 0x0)); + entry->ctag_fmt = tmpdata & 0x1; + + } + + + /* chang ctag pri action configuration */ + cmd_data_check_element("ctag pri change", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (A_TRUE == tmpdata) + { + cmd_data_check_element("ctag pri", NULL, + "usage: the format is 0x1-0x7 or 0-7 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0x7, + 0x0)); + entry->ctag_pri = tmpdata & 0x7; + + FAL_ACTION_FLG_SET(entry->action_flg, FAL_ACL_ACTION_REMARK_CTAG_PRI); + } + + /* chang ctag cfi action configuration */ + cmd_data_check_element("ctag cfi change", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (A_TRUE == tmpdata) + { + cmd_data_check_element("ctag cfi", NULL, + "usage: the format is 0x0-0x1 or 0-1 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0x1, + 0x0)); + entry->ctag_cfi = tmpdata & 0x1; + + FAL_ACTION_FLG_SET(entry->action_flg, FAL_ACL_ACTION_REMARK_CTAG_CFI); + } + + /* police action configuration */ + cmd_data_check_element("policer en", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (A_TRUE == tmpdata) + { + cmd_data_check_element("policer ptr", NULL, + "usage: the format is integer \n", + cmd_data_check_integer, (cmd, &tmpdata, 0xffffffff, + 0x0)); + entry->policer_ptr = tmpdata; + + FAL_ACTION_FLG_SET(entry->action_flg, FAL_ACL_ACTION_POLICER_EN); + } + + /* wcmp action configuration */ + cmd_data_check_element("wcmp en", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (A_TRUE == tmpdata) + { + cmd_data_check_element("wcmp ptr", NULL, + "usage: the format is integer \n", + cmd_data_check_integer, (cmd, &tmpdata, 0xffffffff, + 0x0)); + entry->wcmp_ptr = tmpdata; + + FAL_ACTION_FLG_SET(entry->action_flg, FAL_ACL_ACTION_WCMP_EN); + } + + /* arp action configuration */ + cmd_data_check_element("arp en", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (A_TRUE == tmpdata) + { + cmd_data_check_element("arp ptr", "0", + "usage: the format is integer \n", + cmd_data_check_integer, (cmd, &tmpdata, 0xffffffff, + 0x0)); + entry->arp_ptr = tmpdata; + + FAL_ACTION_FLG_SET(entry->action_flg, FAL_ACL_ACTION_ARP_EN); + } + + /* policy forward action configuration */ + cmd_data_check_element("policy en", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (A_TRUE == tmpdata) + { + cmd_data_check_element("route", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (tmpdata) + { + entry->policy_fwd = FAL_ACL_POLICY_ROUTE; + } + + cmd_data_check_element("snat", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (tmpdata) + { + entry->policy_fwd = FAL_ACL_POLICY_SNAT; + } + + cmd_data_check_element("dnat", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (tmpdata) + { + entry->policy_fwd = FAL_ACL_POLICY_DNAT; + } + + FAL_ACTION_FLG_SET(entry->action_flg, FAL_ACL_ACTION_POLICY_FORWARD_EN); + } + + cmd_data_check_element("eg bypass", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + + if (tmpdata) + { + FAL_ACTION_FLG_SET(entry->action_flg, FAL_ACL_ACTION_BYPASS_EGRESS_TRANS); + } + + cmd_data_check_element("trigger intr", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + + if (tmpdata) + { + FAL_ACTION_FLG_SET(entry->action_flg, FAL_ACL_ACTION_MATCH_TRIGGER_INTR); + } + + /* by pass action configuration */ + cmd_data_check_element("bypass bitmap change", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (A_TRUE == tmpdata) + { + cmd_data_check_element("bypass in vlan miss", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (tmpdata) + { + entry->bypass_bitmap |= (1<\n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (tmpdata) + { + entry->bypass_bitmap |= (1<\n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (tmpdata) + { + entry->bypass_bitmap |= (1<\n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (tmpdata) + { + entry->bypass_bitmap |= (1<\n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (tmpdata) + { + entry->bypass_bitmap |= (1<\n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (tmpdata) + { + entry->bypass_bitmap |= (1<\n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (tmpdata) + { + entry->bypass_bitmap |= (1<\n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (tmpdata) + { + entry->bypass_bitmap |= (1<\n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (tmpdata) + { + entry->bypass_bitmap |= (1<\n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (tmpdata) + { + entry->bypass_bitmap |= (1<\n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (tmpdata) + { + entry->bypass_bitmap |= (1<\n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (tmpdata) + { + entry->bypass_bitmap |= (1<\n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (tmpdata) + { + entry->bypass_bitmap |= (1<\n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (tmpdata) + { + entry->bypass_bitmap |= (1<\n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (tmpdata) + { + entry->bypass_bitmap |= (1<\n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (tmpdata) + { + entry->bypass_bitmap |= (1<\n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (tmpdata) + { + entry->bypass_bitmap |= (1<\n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (tmpdata) + { + entry->bypass_bitmap |= (1<\n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (tmpdata) + { + entry->bypass_bitmap |= (1<\n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (A_TRUE == tmpdata) + { + cmd_data_check_element("enqueue priority", NULL, + "usage: the format is integer, 0-15\n", + cmd_data_check_integer, (cmd, &tmpdata, 0xf, + 0x0)); + entry->enqueue_pri = tmpdata & 0xf; + + FAL_ACTION_FLG_SET(entry->action_flg, FAL_ACL_ACTION_ENQUEUE_PRI); + } + + /*internal dp action configuration */ + cmd_data_check_element("internal dp change", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (A_TRUE == tmpdata) + { + cmd_data_check_element("internal dp", NULL, + "usage: integer value, 0-3\n", + cmd_data_check_integer, (cmd, &tmpdata, 0x3, + 0x0)); + entry->int_dp = tmpdata & 0x3; + + FAL_ACTION_FLG_SET(entry->action_flg, FAL_ACL_ACTION_INT_DP); + } + + /*service code action configuration */ + cmd_data_check_element("service code change", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (A_TRUE == tmpdata) + { + cmd_data_check_element("service code", NULL, + "usage: 0-255\n", + cmd_data_check_integer, (cmd, &tmpdata, 0xff, + 0x0)); + entry->service_code = tmpdata & 0xff; + + FAL_ACTION_FLG_SET(entry->action_flg, FAL_ACL_ACTION_SERVICE_CODE); + } + + /*cpu code action configuration */ + cmd_data_check_element("cpu code change", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (A_TRUE == tmpdata) + { + cmd_data_check_element("cpu code", NULL, + "usage: 0-255\n", + cmd_data_check_integer, (cmd, &tmpdata, 0xff, + 0x0)); + entry->cpu_code = tmpdata & 0xff; + + FAL_ACTION_FLG_SET(entry->action_flg, FAL_ACL_ACTION_CPU_CODE); + } + + /*sync toggle action configuration */ + cmd_data_check_element("sync toggle", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (A_TRUE == tmpdata) + { + FAL_ACTION_FLG_SET(entry->action_flg, FAL_ACL_ACTION_SYN_TOGGLE); + } + + /*meta data action configuration */ + cmd_data_check_element("meta data enable", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (A_TRUE == tmpdata) + { + FAL_ACTION_FLG_SET(entry->action_flg, FAL_ACL_ACTION_METADATA_EN); + } + + cmd_data_check_element("qos res prec", "0", + "usage: the format is 0x0-0x7 or 0-7\n", + cmd_data_check_integer, (cmd, &tmpdata, 0x7, + 0x0)); + entry->qos_res_prec = tmpdata; + + return SW_OK; +} + +sw_error_t +cmd_data_check_aclrule(char *info, void *val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_acl_rule_t entry; + a_uint32_t tmpdata = 0; + + memset(&entry, 0, sizeof (fal_acl_rule_t)); + + dprintf("\n"); + g_aclcmd_len = snprintf(g_aclcmd, 500-g_aclcmd_len, "ssdk_sh acl rule add [listid] [ruleid] 1 "); + + cmd_data_check_element("post routing enable", "no", + "usage: \n", cmd_data_check_confirm, + (cmd, A_FALSE, &entry.post_routing, sizeof (a_bool_t))); + + cmd_data_check_element("priority", "0x0", + "usage: the format is 0x0-0x7 or 0-7 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0x7, + 0x0)); + entry.pri = tmpdata; + cmd_data_check_element("acl pool", "0x0", + "usage: the format is 0x0-0x1 or 0-1 \n", + cmd_data_check_integer, (cmd, &tmpdata, 0x1, + 0x0)); + entry.acl_pool = tmpdata; + /* get rule type configuration */ + cmd_data_check_element("rule type", NULL, "usage: \n", + cmd_data_check_ruletype, (cmd, &entry.rule_type, + sizeof + (fal_acl_rule_type_t))); + + if (FAL_ACL_RULE_MAC == entry.rule_type) + { + rv = cmd_data_check_mac_field(&entry); + if (SW_OK != rv) + { + return rv; + } + } + + if (FAL_ACL_RULE_IP4 == entry.rule_type) + { + rv = cmd_data_check_mac_field(&entry); + if (SW_OK != rv) + { + return rv; + } + + rv = cmd_data_check_ip4_field(&entry); + if (SW_OK != rv) + { + return rv; + } + + rv = cmd_data_check_ip_field(&entry); + if (SW_OK != rv) + { + return rv; + } + } + + if (FAL_ACL_RULE_IP6 == entry.rule_type) + { + rv = cmd_data_check_mac_field(&entry); + if (SW_OK != rv) + { + return rv; + } + + rv = cmd_data_check_ip6_field(&entry); + if (SW_OK != rv) + { + return rv; + } + + rv = cmd_data_check_ip_field(&entry); + if (SW_OK != rv) + { + return rv; + } + } + + rv = cmd_data_check_udf_field(&entry); + if (SW_OK != rv) + { + return rv; + } + + /* get rule inverse configuration */ + cmd_data_check_element("rule inverse", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + + if (tmpdata) + { + FAL_FIELD_FLG_SET(entry.field_flg, FAL_ACL_FIELD_INVERSE_ALL); + } + + rv = cmd_data_check_acl_action(&entry); + if (SW_OK != rv) + { + return rv; + } + //printf("\n %s \n", g_aclcmd); + *(fal_acl_rule_t *) val = entry; + return SW_OK; +} + +static void cmd_data_print_acl_bypass_bitmap(a_uint32_t bitmap) +{ + dprintf("\t[bypass_in_vlan_miss]:0x%x\n", (bitmap>>FAL_ACL_BYPASS_IN_VLAN_MISS)&0x1); + dprintf("\t[bypass_source_guard]:0x%x\n", (bitmap>>FAL_ACL_BYPASS_SOUCE_GUARD)&0x1); + dprintf("\t[bypass_mru_mtu_check]:0x%x\n", (bitmap>>FAL_ACL_BYPASS_MRU_MTU_CHECK)&0x1); + dprintf("\t[bypass_eg_vsi_member_check]:0x%x\n", (bitmap>>FAL_ACL_BYPASS_EG_VSI_MEMBER_CHECK)&0x1); + dprintf("\t[bypass_eg_vlan_translation]:0x%x\n", (bitmap>>FAL_ACL_BYPASS_EG_VLAN_TRANSLATION)&0x1); + dprintf("\t[bypass_eg_vlan_tag_ctrl]:0x%x\n", (bitmap>>FAL_ACL_BYPASS_EG_VLAN_TAG_CTRL)&0x1); + dprintf("\t[bypass_fdb_learning]:0x%x\n", (bitmap>>FAL_ACL_BYPASS_FDB_LEARNING)&0x1); + dprintf("\t[bypass_fdb_refresh]:0x%x\n", (bitmap>>FAL_ACL_BYPASS_FDB_REFRESH)&0x1); + dprintf("\t[bypass_l2_security]:0x%x\n", (bitmap>>FAL_ACL_BYPASS_L2_SECURITY)&0x1); + dprintf("\t[bypass_management_fwd]:0x%x\n", (bitmap>>FAL_ACL_BYPASS_MANAGEMENT_FWD)&0x1); + dprintf("\t[bypass_l2_fwd]:0x%x\n", (bitmap>>FAL_ACL_BYPASS_L2_FWD)&0x1); + dprintf("\t[bypass_in_stp_check]:0x%x\n", (bitmap>>FAL_ACL_BYPASS_IN_STP_CHECK)&0x1); + dprintf("\t[bypass_eg_stp_check]:0x%x\n", (bitmap>>FAL_ACL_BYPASS_EG_STP_CHECK)&0x1); + dprintf("\t[bypass_source_filter]:0x%x\n", (bitmap>>FAL_ACL_BYPASS_SOURCE_FILTER)&0x1); + dprintf("\t[bypass_policer]:0x%x\n", (bitmap>>FAL_ACL_BYPASS_POLICYER)&0x1); + dprintf("\t[bypass_l2_edit]:0x%x\n", (bitmap>>FAL_ACL_BYPASS_L2_EDIT)&0x1); + dprintf("\t[bypass_l3_edit]:0x%x\n", (bitmap>>FAL_ACL_BYPASS_L3_EDIT)&0x1); + dprintf("\t[bypass_post_acl_check_routing]:0x%x\n", (bitmap>>FAL_ACL_BYPASS_POST_ACL_CHECK_ROUTING)&0x1); + dprintf("\t[bypass_port_isolation]:0x%x\n", (bitmap>>FAL_ACL_BYPASS_PORT_ISOLATION)&0x1); + return; +} +void +cmd_data_print_aclrule(a_char_t * param_name, a_uint32_t * buf, + a_uint32_t size) +{ + fal_acl_rule_t *rule; + + rule = (fal_acl_rule_t *) buf; + + cmd_data_print_ruletype("\n[rule_type]:", + (a_uint32_t *) & (rule->rule_type), + sizeof (fal_acl_rule_type_t)); + + dprintf("\n[priority]:0x%x", rule->pri); + cmd_data_print_confirm("\n[post_routing_en]:", rule->post_routing, sizeof(a_uint32_t)); + dprintf("\n[acl_pool]:0x%x", rule->acl_pool); + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_FAKE_MAC_HEADER)) + { + cmd_data_print_confirm("\n[fake_mac_header]:", rule->is_fake_mac_header_val, sizeof(a_uint32_t)); + } + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_SNAP)) + { + cmd_data_print_confirm("\n[snap]:", rule->is_snap_val, sizeof(a_uint32_t)); + } + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ETHERNET)) + { + cmd_data_print_confirm("\n[ethernet]:", rule->is_ethernet_val, sizeof(a_uint32_t)); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_DA)) + { + cmd_data_print_macaddr("\n[mac_dst_addr]:", + (a_uint32_t *) & (rule->dest_mac_val), + sizeof (fal_mac_addr_t)); + cmd_data_print_macaddr(" [mac_dst_addr_mask]:", + (a_uint32_t *) & (rule->dest_mac_mask), + sizeof (fal_mac_addr_t)); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_SA)) + { + cmd_data_print_macaddr("\n[mac_src_addr]:", + (a_uint32_t *) & (rule->src_mac_val), + sizeof (fal_mac_addr_t)); + cmd_data_print_macaddr(" [mac_src_addr_mask]:", + (a_uint32_t *) & (rule->src_mac_mask), + sizeof (fal_mac_addr_t)); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_ETHTYPE)) + { + dprintf("\n[mac_eth_type]:0x%x", rule->ethtype_val); + dprintf(" [mac_eth_type_mask]:0x%x", rule->ethtype_mask); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_TAGGED)) + { + dprintf("\n[mac_tagged]:0x%x", rule->tagged_val); + dprintf(" [mac_tagged_mask]:0x%x", rule->tagged_mask); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_UP)) + { + dprintf("\n[mac_up]:0x%x", rule->up_val); + dprintf(" [mac_up_mask]:0x%x", rule->up_mask); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_CFI)) + { + dprintf("\n[mac_cfi]:0x%x", rule->cfi_val); + dprintf(" [mac_cfi_mask]:0x%x", rule->cfi_mask); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_VID)) + { + cmd_data_print_fieldop("\n[mac_vlanid_op]:", + (a_uint32_t *) & (rule->vid_op), + sizeof (fal_acl_field_op_t)); + if (FAL_ACL_FIELD_MASK == rule->vid_op) + { + dprintf(" [vlanid]:0x%x", rule->vid_val); + dprintf(" [vlanid_mask]:0x%x", rule->vid_mask); + } + else + { + dprintf(" [vlanid_low]:0x%x", rule->vid_val); + dprintf(" [vlanid_high]:0x%x", rule->vid_mask); + } + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_STAGGED)) + { + dprintf("\n[mac_stagged]:0x%x", rule->stagged_val); + dprintf(" [mac_stagged_mask]:0x%x", rule->stagged_mask); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_STAG_PRI)) + { + dprintf("\n[mac_stag_pri]:0x%x", rule->stag_pri_val); + dprintf(" [mac_stag_pri_mask]:0x%x", rule->stag_pri_mask); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_STAG_DEI)) + { + dprintf("\n[mac_stag_dei]:0x%x", rule->stag_dei_val); + dprintf(" [mac_stag_dei_mask]:0x%x", rule->stag_dei_mask); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_STAG_VID)) + { + cmd_data_print_fieldop("\n[mac_stag_vlanid_op]:", + (a_uint32_t *) & (rule->stag_vid_op), + sizeof (fal_acl_field_op_t)); + if (FAL_ACL_FIELD_MASK == rule->stag_vid_op) + { + dprintf(" [stag_vlanid]:0x%x", rule->stag_vid_val); + dprintf(" [stag_vlanid_mask]:0x%x", rule->stag_vid_mask); + } + else + { + dprintf(" [stag_vlanid_low]:0x%x", rule->stag_vid_val); + dprintf(" [stag_vlanid_high]:0x%x", rule->stag_vid_mask); + } + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_CTAGGED)) + { + dprintf("\n[mac_ctagged]:0x%x", rule->ctagged_val); + dprintf(" [mac_ctagged_mask]:0x%x", rule->ctagged_mask); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_CTAG_PRI)) + { + dprintf("\n[mac_ctag_pri]:0x%x", rule->ctag_pri_val); + dprintf(" [mac_ctag_pri_mask]:0x%x", rule->ctag_pri_mask); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_CTAG_CFI)) + { + dprintf("\n[mac_ctag_cfi]:0x%x", rule->ctag_cfi_val); + dprintf(" [mac_ctag_cfi_mask]:0x%x", rule->ctag_cfi_mask); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_CTAG_VID)) + { + cmd_data_print_fieldop("\n[mac_ctag_vlanid_op]:", + (a_uint32_t *) & (rule->ctag_vid_op), + sizeof (fal_acl_field_op_t)); + if (FAL_ACL_FIELD_MASK == rule->ctag_vid_op) + { + dprintf(" [ctag_vlanid]:0x%x", rule->ctag_vid_val); + dprintf(" [ctag_vlanid_mask]:0x%x", rule->ctag_vid_mask); + } + else + { + dprintf(" [ctag_vlanid_low]:0x%x", rule->ctag_vid_val); + dprintf(" [ctag_vlanid_high]:0x%x", rule->ctag_vid_mask); + } + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_VSI_VALID)) + { + cmd_data_print_confirm("\n[vsi_valid]:", rule->vsi_valid, sizeof(a_uint32_t)); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_VSI)) + { + dprintf("\n[vsi]:0x%x", rule->vsi); + dprintf(" [vsi_mask]:0x%x", rule->vsi_mask); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_PPPOE_SESSIONID)) + { + dprintf("\n[pppoe_session_id]:0x%x", rule->pppoe_sessionid); + dprintf(" [pppoe_session_id_mask]:0x%x", rule->pppoe_sessionid_mask); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP)) + { + cmd_data_print_confirm("\n[is_ip]:", rule->is_ip_val, sizeof(a_uint32_t)); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IPV6)) + { + cmd_data_print_confirm("\n[is_ipv6]:", rule->is_ipv6_val, sizeof(a_uint32_t)); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP4_DIP)) + { + cmd_data_print_ip4addr("\n[ip4_dst_addr]:", + (a_uint32_t *) & (rule->dest_ip4_val), + sizeof (fal_ip4_addr_t)); + cmd_data_print_ip4addr(" [ip4_dst_addr_mask]:", + (a_uint32_t *) & (rule->dest_ip4_mask), + sizeof (fal_ip4_addr_t)); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP4_SIP)) + { + cmd_data_print_ip4addr("\n[ip4_src_addr]:", + (a_uint32_t *) & (rule->src_ip4_val), + sizeof (fal_ip4_addr_t)); + cmd_data_print_ip4addr(" [ip4_src_addr_mask]:", + (a_uint32_t *) & (rule->src_ip4_mask), + sizeof (fal_ip4_addr_t)); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_RIPV1)) + { + dprintf("\n[ip4_ripv1]:0x%x", rule->ripv1_val); + dprintf(" [ip4_ripv1_mask]:0x%x", rule->ripv1_mask); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_DHCPV4)) + { + dprintf("\n[ip4_dhcpv4]:0x%x", rule->dhcpv4_val); + dprintf(" [ip4_dhcpv4_mask]:0x%x", rule->dhcpv4_mask); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP6_DIP)) + { + cmd_data_print_ip6addr("\n[ip6_dst_addr]:", + (a_uint32_t *) & (rule->dest_ip6_val), + sizeof (fal_ip6_addr_t)); + cmd_data_print_ip6addr("\n[ip6_dst_addr_mask]:", + (a_uint32_t *) & (rule->dest_ip6_mask), + sizeof (fal_ip6_addr_t)); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP6_SIP)) + { + cmd_data_print_ip6addr("\n[ip6_src_addr]:", + (a_uint32_t *) & (rule->src_ip6_val), + sizeof (fal_ip6_addr_t)); + cmd_data_print_ip6addr("\n[ip6_src_addr_mask]:", + (a_uint32_t *) & (rule->src_ip6_mask), + sizeof (fal_ip6_addr_t)); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP6_LABEL)) + { + dprintf("\n[ip6_flow_label]:0x%x", rule->ip6_lable_val); + dprintf(" [ip6_flow_label_mask]:0x%x", rule->ip6_lable_mask); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_DHCPV6)) + { + dprintf("\n[ip6_dhcpv6]:0x%x", rule->dhcpv6_val); + dprintf(" [ip6_dhcpv6_mask]:0x%x", rule->dhcpv6_mask); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_AH_HEADER)) + { + cmd_data_print_confirm("\n[is_ah_header]:", rule->is_ah_header_val, sizeof(a_uint32_t)); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ESP_HEADER)) + { + cmd_data_print_confirm("\n[is_esp_header]:", rule->is_esp_header_val, sizeof(a_uint32_t)); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MOBILITY_HEADER)) + { + cmd_data_print_confirm("\n[is_mobility_header]:", rule->is_mobility_header_val, sizeof(a_uint32_t)); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_FRAGMENT_HEADER)) + { + cmd_data_print_confirm("\n[is_fragment_header]:", rule->is_fragment_header_val, sizeof(a_uint32_t)); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_OTHER_EXT_HEADER)) + { + cmd_data_print_confirm("\n[is_other_header]:", rule->is_other_header_val, sizeof(a_uint32_t)); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L3_TTL)) + { + dprintf("\n[l3_ttl]:0x%x", rule->l3_ttl); + dprintf(" [l3_ttl_mask]:0x%x", rule->l3_ttl_mask); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IPV4_OPTION)) + { + cmd_data_print_confirm("\n[is_ipv4_option]:", rule->is_ipv4_option_val, sizeof(a_uint32_t)); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_FIRST_FRAGMENT)) + { + cmd_data_print_confirm("\n[is_first_fragment]:", rule->is_first_frag_val, sizeof(a_uint32_t)); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L3_LENGTH)) + { + dprintf("\n[l3_length]:0x%x", rule->l3_length); + dprintf(" [l3_length_mask]:0x%x", rule->l3_length_mask); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP_PKT_TYPE)) + { + cmd_data_print_ip_packet_type("\n[l3_packet_type]:", &rule->l3_pkt_type, sizeof(a_uint16_t)); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP_PROTO)) + { + dprintf("\n[ip_proto]:0x%x", rule->ip_proto_val); + dprintf(" [ip_proto_mask]:0x%x", rule->ip_proto_mask); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP_DSCP)) + { + dprintf("\n[ip_dscp]:0x%x", rule->ip_dscp_val); + dprintf(" [ip_dscp_mask]:0x%x", rule->ip_dscp_mask); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L3_FRAGMENT)) + { + cmd_data_print_confirm("\n[is_l3_fragment]:", rule->is_fragement_val, sizeof(a_uint32_t)); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L4_DPORT)) + { + cmd_data_print_fieldop("\n[ip_l4_dport_op]:", + (a_uint32_t *) & (rule->dest_l4port_op), + sizeof (fal_acl_field_op_t)); + if (FAL_ACL_FIELD_MASK == rule->dest_l4port_op) + { + dprintf(" [dport]:0x%x", rule->dest_l4port_val); + dprintf(" [dport_mask]:0x%x", rule->dest_l4port_mask); + } + else + { + dprintf(" [dport_low]:0x%x", rule->dest_l4port_val); + dprintf(" [dport_high]:0x%x", rule->dest_l4port_mask); + } + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L4_SPORT)) + { + cmd_data_print_fieldop("\n[ip_l4_sport_op]:", + (a_uint32_t *) & (rule->src_l4port_op), + sizeof (fal_acl_field_op_t)); + if (FAL_ACL_FIELD_MASK == rule->src_l4port_op) + { + dprintf(" [sport]:0x%x", rule->src_l4port_val); + dprintf(" [sport_mask]:0x%x", rule->src_l4port_mask); + } + else + { + dprintf(" [sport_low]:0x%x", rule->src_l4port_val); + dprintf(" [sport_high]:0x%x", rule->src_l4port_mask); + } + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_TCP_FLAG)) + { + dprintf("\n[ip_tcp_flags]:0x%x", rule->tcp_flag_val); + dprintf(" [ip_tcp_flags_mask]:0x%x", rule->tcp_flag_mask); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ICMP_TYPE)) + { + dprintf("\n[ip_icmp_type]:0x%x", rule->icmp_type_val); + dprintf(" [ip_icmp_type_mask]:0x%x", rule->icmp_type_mask); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ICMP_CODE)) + { + dprintf("\n[ip_icmp_code]:0x%x", rule->icmp_code_val); + dprintf(" [ip_icmp_code_mask]:0x%x", rule->icmp_code_mask); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_UDF)) + { + cmd_data_print_udf_type("\n[udf_type]:", + (a_uint32_t *) & (rule->udf_type), + sizeof (fal_acl_udf_type_t)); + + dprintf(" [offset]:%d", rule->udf_offset); + + cmd_data_print_udf_element("\n[udf_value]:", + (a_uint32_t *) & (rule->udf_val[0]), + rule->udf_len); + + cmd_data_print_udf_element("\n[udf_mask]:", + (a_uint32_t *) & (rule->udf_mask[0]), + rule->udf_len); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_UDF0)) + { + cmd_data_print_fieldop("\n[udf0_op]:", + (a_uint32_t *) & (rule->udf0_op), + sizeof (fal_acl_field_op_t)); + if (FAL_ACL_FIELD_MASK == rule->udf0_op) + { + dprintf(" [udf0]:0x%x", rule->udf0_val); + dprintf(" [udf0_mask]:0x%x", rule->udf0_mask); + } + else + { + dprintf(" [udf0_low]:0x%x", rule->udf0_val); + dprintf(" [udf0_high]:0x%x", rule->udf0_mask); + } + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_UDF1)) + { + cmd_data_print_fieldop("\n[udf1_op]:", + (a_uint32_t *) & (rule->udf1_op), + sizeof (fal_acl_field_op_t)); + if (FAL_ACL_FIELD_MASK == rule->udf1_op) + { + dprintf(" [udf1]:0x%x", rule->udf1_val); + dprintf(" [udf1_mask]:0x%x", rule->udf1_mask); + } + else + { + dprintf(" [udf1_low]:0x%x", rule->udf1_val); + dprintf(" [udf1_high]:0x%x", rule->udf1_mask); + } + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_UDF2)) + { + dprintf(" [udf2]:0x%x", rule->udf2_val); + dprintf(" [udf2_mask]:0x%x", rule->udf2_mask); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_UDF3)) + { + dprintf(" [udf3]:0x%x", rule->udf3_val); + dprintf(" [udf3_mask]:0x%x", rule->udf3_mask); + } + + if (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_INVERSE_ALL)) + { + dprintf("\n[rule_inverse]:yes"); + } + + if (FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_PERMIT)) + { + dprintf("\n[permit]:yes"); + } + + if (FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_DENY)) + { + dprintf("\n[deny]:yes"); + } + + if (FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_RDTCPU)) + { + dprintf("\n[rdt_to_cpu]:yes"); + } + + if (FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_CPYCPU)) + { + dprintf("\n[cpy_to_cpu]:yes"); + } + + if (FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_MIRROR)) + { + dprintf("\n[mirror]:yes"); + } + if (FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_REDPT)) + { + a_uint32_t dest_type = FAL_ACL_DEST_TYPE(rule->ports); + a_uint32_t dest_val = FAL_ACL_DEST_VALUE(rule->ports); + dprintf("\n[rdt_to_port]:yes "); + if(dest_type == FAL_ACL_DEST_PORT_BMP) + { + cmd_data_print_portmap("[dest_port]:", + dest_val, sizeof(a_uint32_t)); + } + else if(dest_type == FAL_ACL_DEST_PORT_ID) + { + cmd_data_print_uint32("dest_port", + &dest_val, sizeof(a_uint32_t)); + } + else if(dest_type == FAL_ACL_DEST_NEXTHOP) + { + cmd_data_print_uint32("dest_port(next_hop)", + &dest_val, sizeof(a_uint32_t)); + } + } + + if (FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_MODIFY_VLAN)) + { + dprintf("\n[modify_vlan_id]:yes"); + dprintf(" [vlan_id]:%d", rule->vid); + if (!FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_REDPT)) + { + cmd_data_print_portmap(" [port_member]:", rule->ports, + sizeof (fal_pbmp_t)); + } + } + + if (FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_NEST_VLAN)) + { + dprintf("\n[nest_vlan]:yes"); + dprintf(" [vlan_id]:%d", rule->vid); + } + + if (FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_REMARK_DSCP)) + { + dprintf("\n[remark_dscp]:yes"); + dprintf(" [dscp]:%d", rule->dscp); + dprintf(" [dscp_mask]:%d", rule->dscp_mask); + } + + if (FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_REMARK_UP)) + { + dprintf("\n[remark_up]:yes"); + dprintf(" [up]:%d", rule->up); + } + + if (FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_REMARK_QUEUE)) + { + dprintf("\n[remark_queue]:yes"); + dprintf(" [queue]:%d", rule->queue); + } + + dprintf("\n[stag_fmt]:%d", rule->stag_fmt); + dprintf("\n[stag_vid]:%d", rule->stag_vid); + dprintf("\n[ctag_fmt]:%d", rule->ctag_fmt); + dprintf("\n[ctag_vid]:%d", rule->ctag_vid); + + if (FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_REMARK_LOOKUP_VID)) + { + dprintf("\n[change_lookup_vid]:yes"); + } + + if (FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_REMARK_STAG_VID)) + { + dprintf("\n[change_stag_vid]:yes"); + } + + if (FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_REMARK_CTAG_VID)) + { + dprintf("\n[change_ctag_vid]:yes"); + } + + if (FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_REMARK_STAG_PRI)) + { + dprintf("\n[change_stag_pri]:yes"); + dprintf(" [stag_pri]:%d", rule->stag_pri); + } + + if (FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_REMARK_STAG_DEI)) + { + dprintf("\n[change_stag_dei]:yes"); + dprintf(" [stag_dei]:%d", rule->stag_dei); + } + + if (FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_REMARK_CTAG_PRI)) + { + dprintf("\n[change_ctag_pri]:yes"); + dprintf(" [ctag_pri]:%d", rule->ctag_pri); + } + + if (FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_REMARK_CTAG_CFI)) + { + dprintf("\n[change_ctag_cfi]:yes"); + dprintf(" [ctag_cfi]:%d", rule->ctag_cfi); + } + + if (FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_POLICER_EN)) + { + dprintf("\n[policer_en]:yes"); + dprintf(" [policer_ptr]:%d", rule->policer_ptr); + } + + if (FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_WCMP_EN)) + { + dprintf("\n[wcmp_en]:yes"); + dprintf(" [wcmp_ptr]:%d", rule->wcmp_ptr); + } + + if (FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_ARP_EN)) + { + dprintf("\n[arp_en]:yes"); + dprintf(" [arp_ptr]:%d", rule->arp_ptr); + } + + if (FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_POLICY_FORWARD_EN)) + { + if (FAL_ACL_POLICY_ROUTE == rule->policy_fwd) + { + dprintf("\n[policy_forward]:route"); + } + + if (FAL_ACL_POLICY_SNAT == rule->policy_fwd) + { + dprintf("\n[policy_forward]:snat"); + } + + if (FAL_ACL_POLICY_DNAT == rule->policy_fwd) + { + dprintf("\n[policy_forward]:dnat"); + } + } + + if (FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_BYPASS_EGRESS_TRANS)) + { + dprintf("\n[eg_bypass]:yes"); + } + + if (FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_MATCH_TRIGGER_INTR)) + { + dprintf("\n[trigger_intr]:yes"); + } + + if (rule->bypass_bitmap != 0) + { + dprintf("\n[bypass_bitmap]:0x%x\n", rule->bypass_bitmap); + cmd_data_print_acl_bypass_bitmap(rule->bypass_bitmap); + } + + if (FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_ENQUEUE_PRI)) + { + dprintf("\n[enqueue_priority]:0x%x", rule->enqueue_pri); + } + + if (FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_INT_DP)) + { + dprintf("\n[int_dp]:0x%x", rule->int_dp); + } + + if (FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_SERVICE_CODE)) + { + dprintf("\n[service_code]:0x%x", rule->service_code); + } + + if (FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_CPU_CODE)) + { + dprintf("\n[cpu_code]:0x%x", rule->cpu_code); + } + + if (FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_SYN_TOGGLE)) + { + dprintf("\n[syn_toggle]:yes"); + } + else + { + dprintf("\n[syn_toggle]:no"); + } + + if (FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_METADATA_EN)) + { + dprintf("\n[meta_data]:yes"); + } + else + { + dprintf("\n[meta_data]:no"); + } + + dprintf("\n[qos_res_prec]:%d", rule->qos_res_prec); + dprintf("\n[match_counter]:%d", rule->match_cnt); + dprintf("\n[match_bytes]:%lld", rule->match_bytes); + + return; +} + +sw_error_t +cmd_data_check_patternmode(char *cmd_str, led_pattern_mode_t * arg_val, + a_uint32_t size) +{ + if (NULL == cmd_str) + { + return SW_BAD_VALUE; + } + + if (!strcasecmp(cmd_str, "always_off")) + { + *arg_val = LED_ALWAYS_OFF; + } + else if (!strcasecmp(cmd_str, "always_blink")) + { + *arg_val = LED_ALWAYS_BLINK; + } + else if (!strcasecmp(cmd_str, "always_on")) + { + *arg_val = LED_ALWAYS_ON; + } + else if (!strcasecmp(cmd_str, "map")) + { + *arg_val = LED_PATTERN_MAP_EN; + } + else + { + return SW_BAD_VALUE; + } + + return SW_OK; +} + +sw_error_t +cmd_data_check_blinkfreq(char *cmd_str, led_blink_freq_t * arg_val, + a_uint32_t size) +{ + if (NULL == cmd_str) + { + return SW_BAD_VALUE; + } + + if (!strcasecmp(cmd_str, "2HZ")) + { + *arg_val = LED_BLINK_2HZ; + } + else if (!strcasecmp(cmd_str, "4HZ")) + { + *arg_val = LED_BLINK_4HZ; + } + else if (!strcasecmp(cmd_str, "8HZ")) + { + *arg_val = LED_BLINK_8HZ; + } + else if (!strcasecmp(cmd_str, "TXRX")) + { + *arg_val = LED_BLINK_TXRX; + } + else + { + return SW_BAD_VALUE; + } + + return SW_OK; +} + +sw_error_t +cmd_data_check_ledpattern(char *info, void * val, a_uint32_t size) +{ + char *cmd; + led_ctrl_pattern_t pattern; + a_uint32_t tmpdata = 0; + + memset(&pattern, 0, sizeof (led_ctrl_pattern_t)); + + dprintf("\n"); + + /* get pattern mode configuration */ + cmd_data_check_element("pattern_mode", NULL, "usage: \n", + cmd_data_check_patternmode, (cmd, &pattern.mode, + sizeof(led_pattern_mode_t))); + + if (LED_PATTERN_MAP_EN == pattern.mode) + { + cmd_data_check_element("full_duplex_light", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (1 == tmpdata) + { + pattern.map |= (1 << FULL_DUPLEX_LIGHT_EN); + } + + cmd_data_check_element("half_duplex_light", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (1 == tmpdata) + { + pattern.map |= (1 << HALF_DUPLEX_LIGHT_EN); + } + + cmd_data_check_element("power_on_light", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (1 == tmpdata) + { + pattern.map |= (1 << POWER_ON_LIGHT_EN); + } + + cmd_data_check_element("active_high", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (1 == tmpdata) + { + pattern.map |= (1 << LED_ACTIVE_HIGH); + } + + cmd_data_check_element("link_2500m_light", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (1 == tmpdata) + { + pattern.map |= (1 << LINK_2500M_LIGHT_EN); + } + + cmd_data_check_element("link_1000m_light", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (1 == tmpdata) + { + pattern.map |= (1 << LINK_1000M_LIGHT_EN); + } + + cmd_data_check_element("link_100m_light", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (1 == tmpdata) + { + pattern.map |= (1 << LINK_100M_LIGHT_EN); + } + + cmd_data_check_element("link_10m_light", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (1 == tmpdata) + { + pattern.map |= (1 << LINK_10M_LIGHT_EN); + } + + cmd_data_check_element("conllision_light", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (1 == tmpdata) + { + pattern.map |= (1 << COLLISION_BLINK_EN); + } + + cmd_data_check_element("rx_traffic_blink", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (1 == tmpdata) + { + pattern.map |= (1 << RX_TRAFFIC_BLINK_EN); + } + + cmd_data_check_element("tx_traffic_blink", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (1 == tmpdata) + { + pattern.map |= (1 << TX_TRAFFIC_BLINK_EN); + } + + cmd_data_check_element("linkup_override_light", "no", "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &tmpdata, + sizeof (a_bool_t))); + if (1 == tmpdata) + { + pattern.map |= (1 << LINKUP_OVERRIDE_EN); + } + + cmd_data_check_element("blink freq", NULL, "usage: <2HZ/4HZ/8HZ/TXRX> \n", + cmd_data_check_blinkfreq, (cmd, &pattern.freq, + sizeof(led_blink_freq_t))); + } + + *(led_ctrl_pattern_t *)val = pattern; + + return SW_OK; +} + +void +cmd_data_print_ledpattern(a_uint8_t * param_name, a_uint32_t * buf, + a_uint32_t size) +{ + led_ctrl_pattern_t *pattern; + + pattern = (led_ctrl_pattern_t *) buf; + + if (LED_ALWAYS_OFF == pattern->mode) + { + dprintf("[pattern_mode]:always_off"); + } + else if (LED_ALWAYS_BLINK == pattern->mode) + { + dprintf("[pattern_mode]:always_blink"); + } + else if (LED_ALWAYS_ON == pattern->mode) + { + dprintf("[pattern_mode]:always_on"); + } + else + { + dprintf("[pattern_mode]:map"); + } + dprintf("\n"); + + if (LED_PATTERN_MAP_EN == pattern->mode) + { + if (pattern->map & (1 << FULL_DUPLEX_LIGHT_EN)) + { + cmd_data_print_confirm("[full_duplex_light]:", A_TRUE, sizeof (a_bool_t)); + dprintf("\n"); + } + + if (pattern->map & (1 << HALF_DUPLEX_LIGHT_EN)) + { + cmd_data_print_confirm("[half_duplex_light]:", A_TRUE, sizeof (a_bool_t)); + dprintf("\n"); + } + + if (pattern->map & (1 << POWER_ON_LIGHT_EN)) + { + cmd_data_print_confirm("[power_on_light]:", A_TRUE, sizeof (a_bool_t)); + dprintf("\n"); + } + + if (pattern->map & (1 << LED_ACTIVE_HIGH)) + { + cmd_data_print_confirm("[active_high]:", A_TRUE, sizeof (a_bool_t)); + dprintf("\n"); + } + + if (pattern->map & (1 << LINK_2500M_LIGHT_EN)) + { + cmd_data_print_confirm("[link_2500m_light]:", A_TRUE, sizeof (a_bool_t)); + dprintf("\n"); + } + + if (pattern->map & (1 << LINK_1000M_LIGHT_EN)) + { + cmd_data_print_confirm("[link_1000m_light]:", A_TRUE, sizeof (a_bool_t)); + dprintf("\n"); + } + + if (pattern->map & (1 << LINK_100M_LIGHT_EN)) + { + cmd_data_print_confirm("[link_100m_light]:", A_TRUE, sizeof (a_bool_t)); + dprintf("\n"); + } + + if (pattern->map & (1 << LINK_10M_LIGHT_EN)) + { + cmd_data_print_confirm("[link_10m_light]:", A_TRUE, sizeof (a_bool_t)); + dprintf("\n"); + } + + if (pattern->map & (1 << COLLISION_BLINK_EN)) + { + cmd_data_print_confirm("[conllision_blink]:", A_TRUE, sizeof (a_bool_t)); + dprintf("\n"); + } + + if (pattern->map & (1 << RX_TRAFFIC_BLINK_EN)) + { + cmd_data_print_confirm("[rx_traffic_blink]:", A_TRUE, sizeof (a_bool_t)); + dprintf("\n"); + } + + if (pattern->map & (1 << TX_TRAFFIC_BLINK_EN)) + { + cmd_data_print_confirm("[tx_traffic_blink]:", A_TRUE, sizeof (a_bool_t)); + dprintf("\n"); + } + + if (pattern->map & (1 << LINKUP_OVERRIDE_EN)) + { + cmd_data_print_confirm("[linkup_override]:", A_TRUE, sizeof (a_bool_t)); + dprintf("\n"); + } + + if (LED_BLINK_2HZ == pattern->freq) + { + dprintf("[blink_frequency]:2HZ\n"); + } + else if (LED_BLINK_4HZ == pattern->freq) + { + dprintf("[blink_frequency]:4HZ\n"); + } + else if (LED_BLINK_8HZ == pattern->freq) + { + dprintf("[blink_frequency]:8HZ\n"); + } + else + { + dprintf("[blink_frequency]:TXRX\n"); + } + } +} + +sw_error_t +cmd_data_check_mirr_analy_cfg(char *info, void *val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_mirr_analysis_config_t *pEntry = (fal_mirr_analysis_config_t *)val; + + memset(pEntry, 0, sizeof(fal_mirr_analysis_config_t)); + + do + { + cmd = get_sub_cmd("analysis_port", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: port id\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(pEntry->port_id), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: port id\n"); + } + }while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("analysis_priority", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: priority range 0x0-0xf\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(pEntry->priority), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: priority range 0x0-0xf\n"); + } + }while (talk_mode && (SW_OK != rv)); + + return SW_OK; +} + +void +cmd_data_print_mirr_analy_cfg(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_mirr_analysis_config_t *entry; + + entry = (fal_mirr_analysis_config_t *) buf; + dprintf("\n"); + dprintf("[analysis_port]:0x%x\n", entry->port_id); + dprintf("[analysis_priority]:0x%x\n", entry->priority); +} + +sw_error_t +cmd_data_check_mirr_direction(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + + if (!strcasecmp(cmd_str, "both")) + { + *arg_val = FAL_MIRR_BOTH; + } + else if (!strcasecmp(cmd_str, "ingress")) + { + *arg_val = FAL_MIRR_INGRESS; + } + else if (!strcasecmp(cmd_str, "egress")) + { + *arg_val = FAL_MIRR_EGRESS; + } + else + { + //dprintf("input error \n"); + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_mirr_direction(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:", param_name); + if (*(a_uint32_t *) buf == FAL_MIRR_BOTH) + { + dprintf("BOTH"); + } + else if (*(a_uint32_t *) buf == FAL_MIRR_INGRESS) + { + dprintf("INGRESS"); + } + else if (*(a_uint32_t *) buf == FAL_MIRR_EGRESS) + { + dprintf("EGRESS"); + } + else + { + dprintf("UNKNOWN VALUE"); + } +} + +/*Shiva*/ +sw_error_t +cmd_data_check_invlan_mode(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + + if (!strcasecmp(cmd_str, "admit_all")) + { + *arg_val = FAL_INVLAN_ADMIT_ALL; + } + else if (!strcasecmp(cmd_str, "admit_tagged")) + { + *arg_val = FAL_INVLAN_ADMIT_TAGGED; + } + else if (!strcasecmp(cmd_str, "admit_untagged")) + { + *arg_val = FAL_INVLAN_ADMIT_UNTAGGED; + } + else + { + //dprintf("input error \n"); + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_invlan_mode(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:", param_name); + + if (*(a_uint32_t *) buf == FAL_INVLAN_ADMIT_ALL) + { + dprintf("ADMIT_ALL"); + } + else if (*(a_uint32_t *) buf == FAL_INVLAN_ADMIT_TAGGED) + { + dprintf("ADMIT_TAGGED"); + } + else if (*(a_uint32_t *) buf == FAL_INVLAN_ADMIT_UNTAGGED) + { + dprintf("ADMIT_UNTAGGED"); + } + else + { + dprintf("UNKNOWN VALUE"); + } +} + +sw_error_t +cmd_data_check_vlan_propagation(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + + if (!strcasecmp(cmd_str, "disable")) + { + *arg_val = FAL_VLAN_PROPAGATION_DISABLE; + } + else if (!strcasecmp(cmd_str, "clone")) + { + *arg_val = FAL_VLAN_PROPAGATION_CLONE; + } + else if (!strcasecmp(cmd_str, "replace")) + { + *arg_val = FAL_VLAN_PROPAGATION_REPLACE; + } + else + { + //dprintf("input error \n"); + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_vlan_propagation(a_char_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:", param_name); + + if (*(a_uint32_t *) buf == FAL_VLAN_PROPAGATION_DISABLE) + { + dprintf("DISABLE"); + } + else if (*(a_uint32_t *) buf == FAL_VLAN_PROPAGATION_CLONE) + { + dprintf("CLONE"); + } + else if (*(a_uint32_t *) buf == FAL_VLAN_PROPAGATION_REPLACE) + { + dprintf("REPLACE"); + } + else + { + dprintf("UNKNOWN VALUE"); + } +} + +sw_error_t +cmd_data_check_vlan_translation(char *info, fal_vlan_trans_entry_t *val, a_uint32_t size) +{ + char *cmd = NULL; + a_uint32_t tmp; + sw_error_t rv; + fal_vlan_trans_entry_t entry; + + memset(&entry, 0, sizeof (fal_vlan_trans_entry_t)); + + if (ssdk_cfg.init_cfg.chip_type != CHIP_HPPE) { + do + { + cmd = get_sub_cmd("ovid", "1"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 4095\n"); + rv = SW_BAD_VALUE; + + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.o_vid, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: the range is 0 -- 4095\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("bi direction", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.bi_dir, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("forward direction", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.forward_dir, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("reverse direction", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.reverse_dir, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("svid", "1"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 4095\n"); + rv = SW_BAD_VALUE; + + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.s_vid, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: the range is 0 -- 4095\n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cvid", "1"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 4095\n"); + rv = SW_BAD_VALUE; + + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.c_vid, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: the range is 0 -- 4095\n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ovid_is_cvid", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.o_vid_is_cvid, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("svid_enable", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.s_vid_enable, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cvid_enable", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.c_vid_enable, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("one_2_one_vlan", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.one_2_one_vlan, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + } + + if (ssdk_cfg.init_cfg.chip_type == CHIP_HPPE) { + do + { + cmd = get_sub_cmd("direction", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0 for ingress, 1 for egress\n"); + rv = SW_BAD_VALUE; + + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.trans_direction, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: value should be 0/1, 0=ingress, 1=egress\n"); + else if (entry.trans_direction !=0 && entry.trans_direction != 1) + { + dprintf("usage: value should be 0/1, 0=ingress, 1=egress\n"); + rv = SW_BAD_VALUE; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("port_bitmap", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0 for port 0, 1 for port 1,...\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.port_bitmap, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: 0 for port 0, 1 for port 1,...\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("svid_enable", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.s_vid_enable, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("svid", "1"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 4095\n"); + rv = SW_BAD_VALUE; + + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.s_vid, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: the range is 0 -- 4095\n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cvid_enable", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.c_vid_enable, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cvid", "1"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 4095\n"); + rv = SW_BAD_VALUE; + + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.c_vid, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: the range is 0 -- 4095\n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + if (entry.trans_direction == 1) { + do + { + cmd = get_sub_cmd("vsi_valid", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.vsi_valid, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("vsi_enable", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.vsi_enable, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("vsi", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 31\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.vsi, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: the range is 0 -- 31\n"); + } + } + while (talk_mode && (SW_OK != rv)); + } + + if (entry.trans_direction == 0) { + do + { + cmd = get_sub_cmd("protocol_enable", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.protocol_enable, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("protocol", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: for example:0x0800 \n"); + rv = SW_BAD_VALUE; + + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: for example:0x0800 \n"); + } + else + { + entry.protocol = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("frmtype_enable", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.frmtype_enable, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("frmtype", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0 for ethernet, 1 for rfc1024, 2 for llc and 3 for ethernet or rfc1024\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.frmtype, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: 0 for ethernet, 1 for rfc1024, 2 for llc and 3 for ethernet or rfc1024\n"); + } + } + while (talk_mode && (SW_OK != rv)); + } + + do + { + cmd = get_sub_cmd("stag_format", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: bit 0 for untagged, bit 1 for priority tagged and " + "bit 2 for tagged\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: bit 0 for untagged, bit 1 for priority " + "tagged and bit 2 for tagged\n"); + } + else + { + entry.s_tagged = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ctag_format", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: bit 0 for untagged, bit 1 for priority tagged and " + "bit 2 for tagged\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: bit 0 for untagged, bit 1 for priority " + "tagged and bit 2 for tagged\n"); + } + else + { + entry.c_tagged = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("s_pcp_enable", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.s_pcp_enable, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("s_pcp", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 7\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: the range is 0 -- 7\n"); + } + else + { + entry.s_pcp = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("c_pcp_enable", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.c_pcp_enable, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("c_pcp", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 7\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: the range is 0 -- 7\n"); + } + else + { + entry.c_pcp = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("s_dei_enable", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.s_dei_enable, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("s_dei", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 1\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: the range is 0 -- 1\n"); + } + else + { + entry.s_dei = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("c_dei_enable", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.c_dei_enable, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("c_dei", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 1\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: the range is 0 -- 1\n"); + } + else + { + entry.c_dei = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("counter_enable", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.counter_enable, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("counter_id", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 63\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: the range is 0 -- 53\n"); + } + else + { + entry.counter_id = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + if (entry.trans_direction == 0) { + do + { + cmd = get_sub_cmd("vsi_action_enable", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.vsi_action_enable, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("vsi_action", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 32\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: the range is 0 -- 32\n"); + } + else + { + entry.vsi_action = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + } + + do + { + cmd = get_sub_cmd("svid_xlt_cmd", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0 for unchanged, 1 for add and replace and 2 for delete tag\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.svid_xlt_cmd, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: 0 for unchanged, 1 for add and replace and 2 for delete tag\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("svid_xlt", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 4095\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: the range is 0 -- 4095\n"); + } + else + { + entry.svid_xlt = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cvid_xlt_cmd", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0 for unchanged, 1 for add and replace and 2 for delete tag\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.cvid_xlt_cmd, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: 0 for unchanged, 1 for add and replace and 2 for delete tag\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cvid_xlt", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 4095\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: the range is 0 -- 4095\n"); + } + else + { + entry.cvid_xlt = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("swap_svid_cvid", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.swap_svid_cvid, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("spcp_xlt_enable", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.spcp_xlt_enable, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("spcp_xlt", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 7\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: the range is 0 -- 7\n"); + } + else + { + entry.spcp_xlt = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cpcp_xlt_enable", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.cpcp_xlt_enable, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cpcp_xlt", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 7\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: the range is 0 -- 7\n"); + } + else + { + entry.cpcp_xlt = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("swap_spcp_cpcp", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.swap_spcp_cpcp, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("sdei_xlt_enable", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.sdei_xlt_enable, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("sdei_xlt", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 1\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: the range is 0 -- 1\n"); + } + else + { + entry.sdei_xlt = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cdei_xlt_enable", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.cdei_xlt_enable, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cdei_xlt", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 7\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: the range is 0 -- 7\n"); + } + else + { + entry.cdei_xlt = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("swap_sdei_cdei", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.swap_sdei_cdei, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + + } + + *val = entry; + return SW_OK; +} + +void +cmd_data_print_vlan_translation(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_vlan_trans_entry_t *entry; + + entry = (fal_vlan_trans_entry_t *) buf; + + if (ssdk_cfg.init_cfg.chip_type != CHIP_HPPE) { + dprintf("[Ovid]:0x%x [Svid]:0x%x [Cvid]:0x%x [BiDirect]:%s [ForwardDirect]:%s [ReverseDirect]:%s", + entry->o_vid, entry->s_vid, entry->c_vid, + entry->bi_dir?"ENABLE":"DISABLE", + entry->forward_dir?"ENABLE":"DISABLE", + entry->reverse_dir?"ENABLE":"DISABLE"); + + dprintf("\n[OvidIsCvid]:%s [SvidEnable]:%s [CvidEnable]:%s [One2OneVlan]:%s\n", + entry->o_vid_is_cvid?"YES":"NO", + entry->s_vid_enable?"YES":"NO", + entry->c_vid_enable?"YES":"NO", + entry->one_2_one_vlan?"YES":"NO"); + } + + if (ssdk_cfg.init_cfg.chip_type == CHIP_HPPE) { + dprintf("\n\n rule field: "); + dprintf("\n[TranslateDirect]:%d", entry->trans_direction); + dprintf("\n[port_bitmap]:0x%x", + entry->port_bitmap); + dprintf("\n[SvidEnable]:%s [Svid]:0x%x [CvidEnable]:%s [Cvid]:0x%x", + entry->s_vid_enable?"YES":"NO", entry->s_vid, + entry->c_vid_enable?"YES":"NO", entry->c_vid); + if (entry->trans_direction == 1) { + dprintf("\n[vsi_valid]:%s [vsi_enable]:%s [vsi]:%d ", + entry->vsi_valid?"ENABLE":"DISABLE", + entry->vsi_enable?"ENABLE":"DISABLE", + entry->vsi); + } + if (entry->trans_direction == 0) { + dprintf("\n[protocol_enable]:%s [protocol]:0x%x [frmtype_enable]:%s [frmtype]:%d ", + entry->protocol_enable?"ENABLE":"DISABLE", + entry->protocol, + entry->frmtype_enable?"ENABLE":"DISABLE", + entry->frmtype); + } + dprintf("\n[stag_format]:0x%x [ctag_format]:0x%x", + entry->s_tagged, + entry->c_tagged); + dprintf("\n[s_pcp_enable]:%s [s_pcp]:%d [c_pcp_enable]:%s [c_pcp]:%d", + entry->s_pcp_enable?"ENABLE":"DISABLE", entry->s_pcp, + entry->c_pcp_enable?"ENABLE":"DISABLE", entry->c_pcp); + dprintf("\n[s_dei_enable]:%s [s_dei]:%d [c_dei_enable]:%s [c_dei]:%d", + entry->s_dei_enable?"ENABLE":"DISABLE", entry->s_dei, + entry->c_dei_enable?"ENABLE":"DISABLE", entry->c_dei); + dprintf("\n\n action field: "); + dprintf("\n[counter_enable]:%s [counter_id]:%d", + entry->counter_enable?"ENABLE":"DISABLE", + entry->counter_id); + if (entry->trans_direction == 0) { + dprintf("\n[vsi_action_enable]:%s [vsi_action]:%d", + entry->vsi_action_enable?"ENABLE":"DISABLE", + entry->vsi_action); + } + dprintf("\n[svid_xlt_cmd]:%d [svid_xlt]:%d [cvid_xlt_cmd]:%d [cvid_xlt]:%d ", + entry->svid_xlt_cmd, + entry->svid_xlt, + entry->cvid_xlt_cmd, + entry->cvid_xlt); + dprintf("\n[swap_svid_cvid]:%s ", + entry->swap_svid_cvid?"ENABLE":"DISABLE"); + dprintf("\n[spcp_xlt_enable]:%s [spcp_xlt]:%d [cpcp_xlt_enable]:%s [cpcp_xlt]:%d ", + entry->spcp_xlt_enable?"ENABLE":"DISABLE", + entry->spcp_xlt, + entry->cpcp_xlt_enable?"ENABLE":"DISABLE", + entry->cpcp_xlt); + dprintf("\n[swap_spcp_cpcp]:%s ", + entry->swap_spcp_cpcp?"ENABLE":"DISABLE"); + dprintf("\n[sdei_xlt_enable]:%s [sdei_xlt]:%d [cdei_xlt_enable]:%s [cdei_xlt]:%d ", + entry->sdei_xlt_enable?"ENABLE":"DISABLE", + entry->sdei_xlt, + entry->cdei_xlt_enable?"ENABLE":"DISABLE", + entry->cdei_xlt); + dprintf("\n[swap_sdei_cdei]:%s\n", + entry->swap_sdei_cdei?"ENABLE":"DISABLE"); + } +} + +sw_error_t +cmd_data_check_qinq_mode(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + + if (!strcasecmp(cmd_str, "ctag")) + { + *arg_val = FAL_QINQ_CTAG_MODE; + } + else if (!strcasecmp(cmd_str, "stag")) + { + *arg_val = FAL_QINQ_STAG_MODE; + } + else + { + //dprintf("input error \n"); + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_qinq_mode(a_char_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:", param_name); + + if (*(a_uint32_t *) buf == FAL_QINQ_CTAG_MODE) + { + dprintf("CTAG"); + } + else if (*(a_uint32_t *) buf == FAL_QINQ_STAG_MODE) + { + dprintf("STAG"); + } + else + { + dprintf("UNKNOWN VALUE"); + } +} + +sw_error_t +cmd_data_check_qinq_role(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + + if (!strcasecmp(cmd_str, "edge")) + { + *arg_val = FAL_QINQ_EDGE_PORT; + } + else if (!strcasecmp(cmd_str, "core")) + { + *arg_val = FAL_QINQ_CORE_PORT; + } + else + { + //dprintf("input error \n"); + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_qinq_role(a_char_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:", param_name); + + if (*(a_uint32_t *) buf == FAL_QINQ_EDGE_PORT) + { + dprintf("EDGE"); + } + else if (*(a_uint32_t *) buf == FAL_QINQ_CORE_PORT) + { + dprintf("CORE"); + } + else + { + dprintf("UNKNOWN VALUE"); + } +} +sw_error_t +cmd_data_check_port_eee_config(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_port_eee_cfg_t cfg; + + aos_mem_zero(&cfg, sizeof (fal_port_eee_cfg_t)); + + do + { + cmd = get_sub_cmd("eee_enable", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(cfg.enable), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + do + { + cmd = get_sub_cmd("eee_capability", "0-0xffff"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(cfg.capability), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("lpi_sleep_timer", "0-0xffff"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(cfg.lpi_sleep_timer), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("advertisement", "0-0xffff"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(cfg.advertisement), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("lpi_tx_enable", "0x1"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(cfg.lpi_tx_enable), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("eee_status", "0-0xffff"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(cfg.eee_status), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("lpi_wakeup_timer", "0-0xffff"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(cfg.lpi_wakeup_timer), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("link_partner_advertisement", "0-0xffff"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(cfg.link_partner_advertisement), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + *(fal_port_eee_cfg_t *)val = cfg; + return SW_OK; +} +void +cmd_data_print_port_eee_config(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_port_eee_cfg_t *cfg; + + cfg = (fal_port_eee_cfg_t *) buf; + + if (A_TRUE == cfg->enable) + { + dprintf("\n[eee_enable]:yes "); + } + else + { + dprintf("\n[eee_enable]:no "); + } + dprintf("\n[eee_capability]:0x%x", cfg->capability); + dprintf("\n[eee_lpi_sleep_timer]:0x%x", cfg->lpi_sleep_timer); + dprintf("\n[eee_advertisement]:0x%x", cfg->advertisement); + dprintf("\n[eee_lpi_tx_enable]:0x%x", cfg->lpi_tx_enable); + dprintf("\n[eee_status]:0x%x ", cfg->eee_status); + dprintf("\n[eee_lpi_wakeup_timer]:0x%x ", cfg->lpi_wakeup_timer); + dprintf("\n[eee_link_partner_advertisement]:0x%x ", cfg->link_partner_advertisement); + + return; +} + +sw_error_t +cmd_data_check_switch_port_loopback_config(char *cmd_str, void * val, + a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_loopback_config_t cfg; + + aos_mem_zero(&cfg, sizeof (fal_loopback_config_t)); + + do + { + cmd = get_sub_cmd("loopback_enable", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(cfg.enable), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("crc_stripped_enable", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(cfg.crc_stripped), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("loopback_rate", "1-0x12c"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer [unit is Mpps]\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(cfg.loopback_rate), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer [unit is Mpps]\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + *(fal_loopback_config_t *)val = cfg; + return SW_OK; +} +void +cmd_data_print_switch_port_loopback_config(a_uint8_t * param_name, + a_uint32_t * buf, a_uint32_t size) +{ + fal_loopback_config_t *cfg; + + cfg = (fal_loopback_config_t *) buf; + + if (A_TRUE == cfg->enable) + { + dprintf("\n[loopback_enable]:yes "); + } + else + { + dprintf("\n[loopback_enable]:no "); + } + if (A_TRUE == cfg->crc_stripped) + { + dprintf("\n[crc_stripped_enable]:yes "); + } + else + { + dprintf("\n[crc_stripped_enable]:no "); + } + + dprintf("\n[loopback_rate]:%d[Mpps]", cfg->loopback_rate); + + return; +} + +/*qca808x_start*/ +void +cmd_data_print_cable_status(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:", param_name); + + if (*(a_uint32_t *) buf == FAL_CABLE_STATUS_NORMAL) + { + dprintf("NORMAL"); + } + else if (*(a_uint32_t *) buf == FAL_CABLE_STATUS_SHORT) + { + dprintf("SHORT"); + } + else if (*(a_uint32_t *) buf == FAL_CABLE_STATUS_OPENED) + { + dprintf("OPENED"); + } + else if (*(a_uint32_t *) buf == FAL_CABLE_STATUS_INVALID) + { + dprintf("INVALID"); + } + else if (*(a_uint32_t *) buf == FAL_CABLE_STATUS_CROSSOVERA) + { + dprintf("CROSSOVERA"); + } + else if (*(a_uint32_t *) buf == FAL_CABLE_STATUS_CROSSOVERB) + { + dprintf("CROSSOVERB"); + } + else if (*(a_uint32_t *) buf == FAL_CABLE_STATUS_CROSSOVERC) + { + dprintf("CROSSOVERC"); + } + else if (*(a_uint32_t *) buf == FAL_CABLE_STATUS_CROSSOVERD) + { + dprintf("CROSSOVERD"); + } + else if (*(a_uint32_t *) buf == FAL_CABLE_STATUS_LOW_MISMATCH) + { + dprintf("LOW_MISMATCH"); + } + else if (*(a_uint32_t *) buf == FAL_CABLE_STATUS_HIGH_MISMATCH) + { + dprintf("HIGH_MISMATCH"); + } + else + { + dprintf("UNKNOWN VALUE"); + } +} + +void +cmd_data_print_cable_len(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:%d", param_name, *(a_uint32_t *) buf); +} + +char* +cmd_cpu_mode(hsl_init_mode mode) +{ + switch (mode) + { + case HSL_NO_CPU: + return "no_cpu"; + case HSL_CPU_1: + return "cpu_1"; + case HSL_CPU_2: + return "cpu_2"; + case HSL_CPU_1_PLUS: + return "cpu_1_plus"; + } + + return "unknow"; +} + +char* +cmd_access_mode(hsl_access_mode mode) +{ + switch (mode) + { + case HSL_MDIO: + return "mdio"; + case HSL_HEADER: + return "header"; + } + + return "unknow"; +} + +static void +_cmd_collect_shell_cfg(ssdk_cfg_t *shell_cfg) +{ + memset(shell_cfg, 0, sizeof(ssdk_cfg_t)); + shell_cfg->init_cfg = init_cfg; + +#ifdef VERSION + aos_mem_copy(shell_cfg->build_ver, VERSION, sizeof(VERSION)); +#endif + +#ifdef BUILD_DATE + aos_mem_copy(shell_cfg->build_date, BUILD_DATE, sizeof(BUILD_DATE)); +#endif + + if (ssdk_cfg.init_cfg.chip_type == CHIP_ATHENA) + aos_mem_copy(shell_cfg->chip_type, "athena", sizeof("athena")); + else if (ssdk_cfg.init_cfg.chip_type == CHIP_GARUDA) + aos_mem_copy(shell_cfg->chip_type, "garuda", sizeof("garuda")); + else if (ssdk_cfg.init_cfg.chip_type == CHIP_SHIVA) + aos_mem_copy(shell_cfg->chip_type, "shiva", sizeof("shiva")); + else if (ssdk_cfg.init_cfg.chip_type == CHIP_HORUS) + aos_mem_copy(shell_cfg->chip_type, "horus", sizeof("horus")); + else if (ssdk_cfg.init_cfg.chip_type == CHIP_ISIS) + aos_mem_copy(shell_cfg->chip_type, "isis", sizeof("isis")); + else if (ssdk_cfg.init_cfg.chip_type == CHIP_ISISC) + aos_mem_copy(shell_cfg->chip_type, "isisc", sizeof("isisc")); + +#ifdef CPU + aos_mem_copy(shell_cfg->cpu_type, CPU, sizeof(CPU)); +#endif + +#ifdef OS + aos_mem_copy(shell_cfg->os_info, OS, sizeof(OS)); +#if defined KVER26 + aos_mem_copy(shell_cfg->os_info+sizeof(OS)-1, " version 2.6", sizeof(" version 2.6")); +#elif defined KVER24 + aos_mem_copy(shell_cfg->os_info+sizeof(OS)-1, " version 2.4", sizeof(" version 2.4")); +#else + aos_mem_copy(shell_cfg->os_info+sizeof(OS)-1, " version unknown", sizeof(" version unknown")); +#endif +#endif + +#ifdef HSL_STANDALONG + shell_cfg->fal_mod = A_FALSE; +#else + shell_cfg->fal_mod = A_TRUE; +#endif + +#ifdef USER_MODE + shell_cfg->kernel_mode = A_FALSE; +#else + shell_cfg->kernel_mode = A_TRUE; +#endif + +#ifdef UK_IF + shell_cfg->uk_if = A_TRUE; +#else + shell_cfg->uk_if = A_FALSE; +#endif + + return; +} + +#define BOOL2STR(val_bool) (((val_bool)==A_TRUE)?"true":"false" ) +/*qca808x_end*/ +#define BOOL2NAME(val_bool) (((feature->in_##val_bool)==A_TRUE)?(#val_bool):"" ) +#define DEFINED2STR(name) (((init->reg_func.name))?"y":"n" ) +/*qca808x_start*/ +static void +_cmd_data_print_cfg(ssdk_cfg_t *entry) +{ + ssdk_init_cfg *init = &(entry->init_cfg); + + dprintf("[build verison]:%-10s [build date]:%s\n", entry->build_ver, entry->build_date); + dprintf("[chip type]:%-14s [arch]:%-12s [os]:%s\n", entry->chip_type, entry->cpu_type, entry->os_info); + dprintf("[fal]:%-20s [kernel mode]:%-5s [uk if]:%s\n", + BOOL2STR(entry->fal_mod), BOOL2STR(entry->kernel_mode), BOOL2STR(entry->uk_if)); + + dprintf("[cpu mode]:%-15s [reg access]:%-6s [ioctl minor]:%d\n", + cmd_cpu_mode(init->cpu_mode), cmd_access_mode(init->reg_mode), + init->nl_prot); +/*qca808x_end*/ + dprintf("[inf defined]:mdio_set(%s) mdio_get(%s) header_reg_set(%s) header_reg_get(%s)\n", + DEFINED2STR(mdio_set), DEFINED2STR(mdio_get), DEFINED2STR(header_reg_set), DEFINED2STR(header_reg_get)); +/*qca808x_start*/ +} + +void +cmd_data_print_ssdk_cfg(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + ssdk_cfg_t *ssdk_cfg = (ssdk_cfg_t *) buf; + dprintf("1.SSDK CONFIGURATION:\n"); + _cmd_data_print_cfg(ssdk_cfg); + + dprintf("\n2.DEMO SHELL CONFIGURATION:\n"); + ssdk_cfg_t shell_cfg; + _cmd_collect_shell_cfg(&shell_cfg); + _cmd_data_print_cfg(&shell_cfg); + + dprintf("\n3.SSDK FEATURES LIST:\n"); +/*qca808x_end*/ + ssdk_features *feature = &(ssdk_cfg->features); + dprintf("%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s\n", + BOOL2NAME(acl), BOOL2NAME(fdb), BOOL2NAME(igmp), BOOL2NAME(leaky), + BOOL2NAME(led), BOOL2NAME(mib), BOOL2NAME(mirror), BOOL2NAME(misc), + BOOL2NAME(portcontrol), BOOL2NAME(portvlan), BOOL2NAME(qos), BOOL2NAME(rate), + BOOL2NAME(stp), BOOL2NAME(vlan), BOOL2NAME(reduced_acl), + BOOL2NAME(cosmap), BOOL2NAME(ip), BOOL2NAME(nat), BOOL2NAME(sec), BOOL2NAME(trunk), BOOL2NAME(interfacectrl)); +/*qca808x_start*/ + +} +/*qca808x_end*/ +sw_error_t +cmd_data_check_hdrmode(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + + if (!strcasecmp(cmd_str, "noheader")) + { + *arg_val = FAL_NO_HEADER_EN; + } + else if (!strcasecmp(cmd_str, "onlymanagement")) + { + *arg_val = FAL_ONLY_MANAGE_FRAME_EN; + } + else if (!strcasecmp(cmd_str, "allframe")) + { + *arg_val = FAL_ALL_TYPE_FRAME_EN; + } + else + { + //dprintf("input error \n"); + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_hdrmode(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:", param_name); + if (*(a_uint32_t *) buf == FAL_NO_HEADER_EN) + { + dprintf("NOHEADER"); + } + else if (*(a_uint32_t *) buf == FAL_ONLY_MANAGE_FRAME_EN) + { + dprintf("ONLYMANAGEMENT"); + } + else if (*(a_uint32_t *) buf == FAL_ALL_TYPE_FRAME_EN) + { + dprintf("ALLFRAME"); + } + else + { + dprintf("UNKNOWN VALUE"); + } +} + +sw_error_t +cmd_data_check_fdboperation(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_fdb_op_t entry; + + memset(&entry, 0, sizeof (fal_fdb_op_t)); + + do + { + cmd = get_sub_cmd("port_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.port_en, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("fid_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.fid_en, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("multi_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.multicast_en, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + *(fal_fdb_op_t *) val = entry; + return SW_OK; +} + +sw_error_t +cmd_data_check_pppoe(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_pppoe_session_t entry; + + aos_mem_zero(&entry, sizeof (fal_pppoe_session_t)); + + do + { + cmd = get_sub_cmd("entryid", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.entry_id), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("sessionid", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 65535\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.session_id, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: the range is 0 -- 65535\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("multi_session", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.multi_session, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("uni_session", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.uni_session, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("vrf_id", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 7\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.vrf_id, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: the range is 0 -- 7\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + if (ssdk_cfg.init_cfg.chip_type == CHIP_HPPE) + { + do + { + cmd = get_sub_cmd("port", "null"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: input port number such as 1,3\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_portmap(cmd, &entry.port_bitmap, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: input port number such as 1,3\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("l3if_index", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 255\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.l3_if_index, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: the range is 0 -- 255\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("l3if_index_valid", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.l3_if_valid, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("smacaddr", NULL); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the format is xx-xx-xx-xx-xx-xx \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_macaddr(cmd, &entry.smac_addr, + sizeof (fal_mac_addr_t)); + if (SW_OK != rv) + dprintf("usage: the format is xx-xx-xx-xx-xx-xx \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("smacaddr_valid", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.smac_valid, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + } + + *(fal_pppoe_session_t*)val = entry; + return SW_OK; +} + +void +cmd_data_print_pppoe(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_pppoe_session_t *entry; + + entry = (fal_pppoe_session_t *) buf; + dprintf("[EntryID]:0x%x [SessionID]:0x%x [MultiSession]:%s [UniSession]:%s [Vrf_ID]:0x%x\n", + entry->entry_id, + entry->session_id, + entry->multi_session ? "YES":"NO", + entry->uni_session ? "YES":"NO", + entry->vrf_id); + cmd_data_print_portmap("[Port]:", entry->port_bitmap, sizeof (fal_pbmp_t)); + dprintf(" [l3if_index]:0x%x [l3if_index_valid]:%s\n", + entry->l3_if_index, entry->l3_if_valid ? "YES":"NO"); + cmd_data_print_macaddr("[smacaddr]:", (a_uint32_t *) & (entry->smac_addr), sizeof (fal_mac_addr_t)); + dprintf(" [smacaddr_valid]:%s", entry->smac_valid ? "YES":"NO"); +} + +sw_error_t +cmd_data_check_pppoe_less(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_pppoe_session_t entry; + + aos_mem_zero(&entry, sizeof (fal_pppoe_session_t)); + + do + { + cmd = get_sub_cmd("sessionid", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 65535\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.session_id, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: the range is 0 -- 65535\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + *(fal_pppoe_session_t*)val = entry; + return SW_OK; +} + +sw_error_t +cmd_data_check_host_entry(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + a_uint32_t tmp; + sw_error_t rv; + fal_host_entry_t entry; + + aos_mem_zero(&entry, sizeof (fal_host_entry_t)); + + do + { + cmd = get_sub_cmd("entryid", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.entry_id), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("entryflags", "0x1"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: bitmap for host entry\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.flags), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: bitmap for host entry\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("entrystatus", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.status), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + if ((FAL_IP_IP4_ADDR & (entry.flags)) == FAL_IP_IP4_ADDR || + (FAL_IP_IP4_ADDR_MCAST& (entry.flags)) == FAL_IP_IP4_ADDR_MCAST) + { + cmd_data_check_element("ip4 addr", NULL, + "usage: the format is xx.xx.xx.xx \n", + cmd_data_check_ip4addr, (cmd, &(entry.ip4_addr), 4)); + } + else if ((FAL_IP_IP6_ADDR & (entry.flags)) == FAL_IP_IP6_ADDR || + (FAL_IP_IP6_ADDR_MCAST& (entry.flags)) == FAL_IP_IP6_ADDR_MCAST) + { + cmd_data_check_element("ip6 addr", NULL, + "usage: the format is xxxx::xxxx \n", + cmd_data_check_ip6addr, (cmd, &(entry.ip6_addr), 16)); + } + + cmd_data_check_element("mac addr", NULL, + "usage: the format is xx-xx-xx-xx-xx-xx \n", + cmd_data_check_macaddr, (cmd, + &(entry.mac_addr), + sizeof (fal_mac_addr_t))); + + do + { + cmd = get_sub_cmd("interface id", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.intf_id), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("load_balance num", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.lb_num), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("vrf id", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.vrf_id), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("port id", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.port_id), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("action", "forward"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_maccmd(cmd, &(entry.action), + sizeof (fal_fwd_cmd_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("mirror", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.mirror_en, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("counter", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.counter_en, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + if (A_TRUE == entry.counter_en) + { + do + { + cmd = get_sub_cmd("counter id", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.counter_id), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + } + + do + { + cmd = get_sub_cmd("dst info", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: dst info\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.dst_info), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: dst info\n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("sync toggle", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: toglle\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: toggle\n"); + } + else + { + entry.syn_toggle = tmp; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("lan wan", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: lan wan\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: lan wan\n"); + } + else + { + entry.lan_wan = tmp; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + if ((FAL_IP_IP4_ADDR_MCAST & (entry.flags)) == FAL_IP_IP4_ADDR_MCAST || + (FAL_IP_IP6_ADDR_MCAST& (entry.flags)) == FAL_IP_IP6_ADDR_MCAST) + { + do + { + cmd = get_sub_cmd("vsi", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: vsi\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: integer\n"); + } + else + { + entry.mcast_info.vsi = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + if ((FAL_IP_IP4_ADDR_MCAST & (entry.flags)) == FAL_IP_IP4_ADDR_MCAST) { + cmd_data_check_element("ip4 addr", NULL, + "usage: the format is xx.xx.xx.xx \n", + cmd_data_check_ip4addr, (cmd, &(entry.mcast_info.sip4_addr), 4)); + } else { + cmd_data_check_element("ip6 addr", NULL, + "usage: the format is xxxx::xxxx \n", + cmd_data_check_ip6addr, (cmd, &(entry.mcast_info.sip6_addr), 16)); + } + } + + *(fal_host_entry_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_host_entry(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_host_entry_t *entry; + + entry = (fal_host_entry_t *) buf; + dprintf("\n[entryid]:0x%x [entryflags]:0x%x [entrystatus]:0x%x", + entry->entry_id, entry->flags, entry->status); + + if ((FAL_IP_IP4_ADDR & entry->flags) == FAL_IP_IP4_ADDR || + (FAL_IP_IP4_ADDR_MCAST & entry->flags) == FAL_IP_IP4_ADDR_MCAST) + { + cmd_data_print_ip4addr("\n[ip_addr]:", + (a_uint32_t *) & (entry->ip4_addr), + sizeof (fal_ip4_addr_t)); + } + else if ((FAL_IP_IP6_ADDR & entry->flags) == FAL_IP_IP6_ADDR || + (FAL_IP_IP6_ADDR_MCAST & entry->flags) == FAL_IP_IP6_ADDR_MCAST) + { + cmd_data_print_ip6addr("\n[ip_addr]:", + (a_uint32_t *) & (entry->ip6_addr), + sizeof (fal_ip6_addr_t)); + } + + cmd_data_print_macaddr(" [mac_addr]:", + (a_uint32_t *) & (entry->mac_addr), + sizeof (fal_mac_addr_t)); + + dprintf("\n[interfaceid]:0x%x [portid]:0x%x ", entry->intf_id, entry->port_id); + dprintf("\n[load_balance num]:0x%x [vrfid]:0x%x ", entry->lb_num, entry->vrf_id); + + cmd_data_print_maccmd("action", (a_uint32_t *) & (entry->action), + sizeof (fal_fwd_cmd_t)); + + if (A_TRUE == entry->mirror_en) + { + dprintf("\n[mirror]:Enable "); + } + else + { + dprintf("\n[mirror]:Disable "); + } + + if (A_TRUE == entry->counter_en) + { + dprintf("\n[counter]:Enable [counter_id]:%d [pkt]%d [byte]%d", + entry->counter_id, entry->packet, entry->byte); + } + else + { + dprintf("\n[couter]:Disable "); + } + + if (A_TRUE == entry->pppoe_en) + { + dprintf("\n[pppoe]:Enable [pppoe_id]:%d", entry->pppoe_id); + } + else + { + dprintf("\n[pppoe]:Disable "); + } + dprintf("\n[lan_wan]:0x%x [sync_toggle]:0x%x [dst_info]:0x%x ", entry->lan_wan, entry->syn_toggle, entry->dst_info); + dprintf("\n[vsi]:0x%x ", entry->mcast_info.vsi); + + if ((FAL_IP_IP4_ADDR_MCAST & entry->flags) == FAL_IP_IP4_ADDR_MCAST) + { + cmd_data_print_ip4addr("\n[ip_addr]:", + (a_uint32_t *) & (entry->mcast_info.sip4_addr), + sizeof (fal_ip4_addr_t)); + } + else if ((FAL_IP_IP6_ADDR_MCAST & entry->flags) == FAL_IP_IP6_ADDR_MCAST) + { + cmd_data_print_ip6addr("\n[ip_addr]:", + (a_uint32_t *) & (entry->mcast_info.sip6_addr), + sizeof (fal_ip6_addr_t)); + } + +} + +sw_error_t +cmd_data_check_arp_learn_mode(char *cmd_str, fal_arp_learn_mode_t * arg_val, + a_uint32_t size) +{ + if (NULL == cmd_str) + { + return SW_BAD_VALUE; + } + + if (!strcasecmp(cmd_str, "learnlocal")) + { + *arg_val = FAL_ARP_LEARN_LOCAL; + } + else if (!strcasecmp(cmd_str, "learnall")) + { + *arg_val = FAL_ARP_LEARN_ALL; + } + else + { + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_arp_learn_mode(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:", param_name); + if (*(a_uint32_t *) buf == FAL_ARP_LEARN_LOCAL) + { + dprintf("LearnLocal"); + } + else if (*(a_uint32_t *) buf == FAL_ARP_LEARN_ALL) + { + dprintf("LearnAll"); + } + else + { + dprintf("UNKNOWN VALUE"); + } +} + +sw_error_t +cmd_data_check_ip_guard_mode(char *cmd_str, fal_source_guard_mode_t * arg_val, a_uint32_t size) +{ + if (NULL == cmd_str) + { + return SW_BAD_VALUE; + } + + if (!strcasecmp(cmd_str, "mac_ip")) + { + *arg_val = FAL_MAC_IP_GUARD; + } + else if (!strcasecmp(cmd_str, "mac_ip_port")) + { + *arg_val = FAL_MAC_IP_PORT_GUARD; + } + else if (!strcasecmp(cmd_str, "mac_ip_vlan")) + { + *arg_val = FAL_MAC_IP_VLAN_GUARD; + } + else if (!strcasecmp(cmd_str, "mac_ip_port_vlan")) + { + *arg_val = FAL_MAC_IP_PORT_VLAN_GUARD; + } + else if (!strcasecmp(cmd_str, "no_guard")) + { + *arg_val = FAL_NO_SOURCE_GUARD; + } + else + { + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_ip_guard_mode(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:", param_name); + if (*(a_uint32_t *) buf == FAL_MAC_IP_GUARD) + { + dprintf("MAC_IP_GUARD"); + } + else if (*(a_uint32_t *) buf == FAL_MAC_IP_PORT_GUARD) + { + dprintf("MAC_IP_PORT_GUARD"); + } + else if (*(a_uint32_t *) buf == FAL_MAC_IP_VLAN_GUARD) + { + dprintf("MAC_IP_VLAN_GUARD"); + } + else if (*(a_uint32_t *) buf == FAL_MAC_IP_PORT_VLAN_GUARD) + { + dprintf("MAC_IP_PORT_VLAN_GUARD"); + } + else if (*(a_uint32_t *) buf == FAL_NO_SOURCE_GUARD) + { + dprintf("NO_GUARD"); + } + else + { + dprintf("UNKNOWN VALUE"); + } +} + +sw_error_t +cmd_data_check_nat_entry(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + a_uint32_t tmp = 0; + fal_nat_entry_t entry; + + aos_mem_zero(&entry, sizeof (fal_nat_entry_t)); + + do + { + cmd = get_sub_cmd("entryid", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.entry_id), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("entryflags", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: bitmap for host entry\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.flags), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: bitmap for host entry\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("entrystatus", "0xf"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.status), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("select_idx", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.slct_idx), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("vrf_id", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.vrf_id), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + cmd_data_check_element("src addr", "0.0.0.0", + "usage: the format is xx.xx.xx.xx \n", + cmd_data_check_ip4addr, (cmd, &(entry.src_addr), 4)); + + cmd_data_check_element("trans addr", "0.0.0.0", + "usage: the format is xx.xx.xx.xx \n", + cmd_data_check_ip4addr, (cmd, &(entry.trans_addr), 4)); + + do + { + cmd = get_sub_cmd("port num", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0- 65535\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: 0- 65535\n"); + } + } + while (talk_mode && (SW_OK != rv)); + entry.port_num = tmp & 0xffff; + + do + { + cmd = get_sub_cmd("port range", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0- 65535\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: 0- 65535\n"); + } + } + while (talk_mode && (SW_OK != rv)); + entry.port_range = tmp & 0xffff; + + do + { + cmd = get_sub_cmd("action", "forward"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_maccmd(cmd, &entry.action, + sizeof (fal_fwd_cmd_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("mirror", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.mirror_en, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("counter", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.counter_en, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + if (A_TRUE == entry.counter_en) + { + do + { + cmd = get_sub_cmd("counter id", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.counter_id), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + } + + *(fal_nat_entry_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_nat_entry(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_nat_entry_t *entry; + + entry = (fal_nat_entry_t *) buf; + dprintf("\n[entryid]:0x%x [entryflags]:0x%x [entrystatus]:0x%x [select_idx]:0x%x", + entry->entry_id, entry->flags, entry->status, entry->slct_idx); + + dprintf("\n[vrf_id]:0x%x ", entry->vrf_id); + + cmd_data_print_ip4addr("\n[src_addr]:", + (a_uint32_t *) & (entry->src_addr), + sizeof (fal_ip4_addr_t)); + + cmd_data_print_ip4addr("\n[trans_addr]:", + (a_uint32_t *) & (entry->trans_addr), + sizeof (fal_ip4_addr_t)); + + dprintf("\n[port_num]:0x%x [port_range]:0x%x ", entry->port_num, entry->port_range); + + cmd_data_print_maccmd("action", (a_uint32_t *) & (entry->action), + sizeof (fal_fwd_cmd_t)); + + if (A_TRUE == entry->mirror_en) + { + dprintf("\n[mirror]:Enable "); + } + else + { + dprintf("\n[mirror]:Disable "); + } + + if (A_TRUE == entry->counter_en) + { + dprintf("\n[counter]:Enable [counter_id]:%d [in_pkt]%d [in_byte]%d [eg_pkt]%d [eg_byte]%d ", + entry->counter_id, entry->ingress_packet, entry->ingress_byte, + entry->egress_packet, entry->egress_byte); + } + else + { + dprintf("\n[couter]:Disable "); + } +} + +sw_error_t +cmd_data_check_napt_entry(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + a_uint32_t tmp = 0; + fal_napt_entry_t entry; + + aos_mem_zero(&entry, sizeof (fal_napt_entry_t)); + + do + { + cmd = get_sub_cmd("entryid", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.entry_id), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("entryflags", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: bitmap for host entry\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.flags), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: bitmap for host entry\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("entrystatus", "0xf"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.status), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("vrf_id", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.vrf_id), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("flow_cookie", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.flow_cookie), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("load_balance", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.load_balance), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + cmd_data_check_element("src addr", "0.0.0.0", + "usage: the format is xx.xx.xx.xx \n", + cmd_data_check_ip4addr, (cmd, &(entry.src_addr), 4)); + + cmd_data_check_element("dst addr", "0.0.0.0", + "usage: the format is xx.xx.xx.xx \n", + cmd_data_check_ip4addr, (cmd, &(entry.dst_addr), 4)); + + if (FAL_NAT_ENTRY_TRANS_IPADDR_INDEX & (entry.flags)) + { + do + { + cmd = get_sub_cmd("trans addr index", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.trans_addr), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + } + else + { + cmd_data_check_element("trans addr", "0.0.0.0", + "usage: the format is xx.xx.xx.xx \n", + cmd_data_check_ip4addr, (cmd, &(entry.trans_addr), 4)); + } + + do + { + cmd = get_sub_cmd("src port", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0- 65535\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: 0- 65535\n"); + } + } + while (talk_mode && (SW_OK != rv)); + entry.src_port = tmp & 0xffff; + + do + { + cmd = get_sub_cmd("dst port", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0- 65535\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: 0- 65535\n"); + } + } + while (talk_mode && (SW_OK != rv)); + entry.dst_port = tmp & 0xffff; + + do + { + cmd = get_sub_cmd("trans port", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0- 65535\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: 0- 65535\n"); + } + } + while (talk_mode && (SW_OK != rv)); + entry.trans_port = tmp & 0xffff; + + do + { + cmd = get_sub_cmd("action", "forward"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_maccmd(cmd, &(entry.action), + sizeof (fal_fwd_cmd_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("mirror", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.mirror_en, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("counter", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.counter_en, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + if (A_TRUE == entry.counter_en) + { + do + { + cmd = get_sub_cmd("counter id", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.counter_id), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + } + + do + { + cmd = get_sub_cmd("priority", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.priority_en, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + + if (A_TRUE == entry.priority_en) + { + do + { + cmd = get_sub_cmd("priority value", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.priority_val), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + } + + *(fal_napt_entry_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_napt_entry(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_napt_entry_t *entry; + + entry = (fal_napt_entry_t *) buf; + dprintf("\n[entryid]:0x%x [entryflags]:0x%x [entrystatus]:0x%x", + entry->entry_id, entry->flags, entry->status); + + dprintf("\n[vrf_id]:0x%x [flow_cookie]:0x%x [load_balance]:0x%x", + entry->vrf_id, entry->flow_cookie, entry->load_balance); + + cmd_data_print_ip4addr("\n[src_addr]:", + (a_uint32_t *) & (entry->src_addr), + sizeof (fal_ip4_addr_t)); + + cmd_data_print_ip4addr("\n[dst_addr]:", + (a_uint32_t *) & (entry->dst_addr), + sizeof (fal_ip4_addr_t)); + + if (FAL_NAT_ENTRY_TRANS_IPADDR_INDEX & entry->flags) + { + dprintf("\n[trans_addr_index]:0x%x", entry->trans_addr); + } + else + { + cmd_data_print_ip4addr("\n[trans_addr]:", + (a_uint32_t *) & (entry->trans_addr), + sizeof (fal_ip4_addr_t)); + } + + dprintf("\n[src_port]:0x%x [dst_port]:0x%x [trans_port]:0x%x ", entry->src_port, entry->dst_port, entry->trans_port); + + cmd_data_print_maccmd("action", (a_uint32_t *) & (entry->action), + sizeof (fal_fwd_cmd_t)); + + if (A_TRUE == entry->mirror_en) + { + dprintf("\n[mirror]:Enable "); + } + else + { + dprintf("\n[mirror]:Disable "); + } + + if (A_TRUE == entry->counter_en) + { + dprintf("\n[counter]:Enable [counter_id]:%d [in_pkt]%d [in_byte]%d [eg_pkt]%d [eg_byte]%d ", + entry->counter_id, entry->ingress_packet, entry->ingress_byte, + entry->egress_packet, entry->egress_byte); + } + else + { + dprintf("\n[couter]:Disable "); + } + + if (A_TRUE == entry->priority_en) + { + dprintf("\n[priority]:Enable [priority_val]:%d ", + entry->priority_val); + } + else + { + dprintf("\n[priority]:Disable "); + } +} + +sw_error_t +cmd_data_check_flow_entry(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + a_uint32_t tmp = 0; + fal_napt_entry_t entry; + + aos_mem_zero(&entry, sizeof (fal_napt_entry_t)); + + do + { + cmd = get_sub_cmd("entryid", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.entry_id), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("entryflags", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: bitmap for host entry\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.flags), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: bitmap for host entry\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("entrystatus", "0xf"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.status), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("vrf_id", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.vrf_id), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("flow_cookie", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.flow_cookie), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("load_balance", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.load_balance), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + cmd_data_check_element("src addr", "0.0.0.0", + "usage: the format is xx.xx.xx.xx \n", + cmd_data_check_ip4addr, (cmd, &(entry.src_addr), 4)); + + cmd_data_check_element("dst addr", "0.0.0.0", + "usage: the format is xx.xx.xx.xx \n", + cmd_data_check_ip4addr, (cmd, &(entry.dst_addr), 4)); + + do + { + cmd = get_sub_cmd("src port", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0- 65535\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: 0- 65535\n"); + } + } + while (talk_mode && (SW_OK != rv)); + entry.src_port = tmp & 0xffff; + + do + { + cmd = get_sub_cmd("dst port", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0- 65535\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: 0- 65535\n"); + } + } + while (talk_mode && (SW_OK != rv)); + entry.dst_port = tmp & 0xffff; + + do + { + cmd = get_sub_cmd("action", "forward"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_maccmd(cmd, &(entry.action), + sizeof (fal_fwd_cmd_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("mirror", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.mirror_en, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("counter", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.counter_en, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + if (A_TRUE == entry.counter_en) + { + do + { + cmd = get_sub_cmd("counter id", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.counter_id), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + } + + do + { + cmd = get_sub_cmd("priority", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.priority_en, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + + if (A_TRUE == entry.priority_en) + { + do + { + cmd = get_sub_cmd("priority value", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.priority_val), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + } + + *(fal_napt_entry_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_flow_entry(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_napt_entry_t *entry; + + entry = (fal_napt_entry_t *) buf; + dprintf("\n[entryid]:0x%x [entryflags]:0x%x [entrystatus]:0x%x", + entry->entry_id, entry->flags, entry->status); + + dprintf("\n[vrf_id]:0x%x [flow_cookie]:0x%x [load_balance]:0x%x", + entry->vrf_id, entry->flow_cookie, entry->load_balance); + + cmd_data_print_ip4addr("\n[src_addr]:", + (a_uint32_t *) & (entry->src_addr), + sizeof (fal_ip4_addr_t)); + + cmd_data_print_ip4addr("\n[dst_addr]:", + (a_uint32_t *) & (entry->dst_addr), + sizeof (fal_ip4_addr_t)); + + dprintf("\n[src_port]:0x%x [dst_port]:0x%x ", entry->src_port, entry->dst_port); + + cmd_data_print_maccmd("action", (a_uint32_t *) & (entry->action), + sizeof (fal_fwd_cmd_t)); + + if (A_TRUE == entry->mirror_en) + { + dprintf("\n[mirror]:Enable "); + } + else + { + dprintf("\n[mirror]:Disable "); + } + + if (A_TRUE == entry->counter_en) + { + dprintf("\n[counter]:Enable [counter_id]:%d [in_pkt]%d [in_byte]%d [eg_pkt]%d [eg_byte]%d ", + entry->counter_id, entry->ingress_packet, entry->ingress_byte, + entry->egress_packet, entry->egress_byte); + } + else + { + dprintf("\n[couter]:Disable "); + } + + if (A_TRUE == entry->priority_en) + { + dprintf("\n[priority]:Enable [priority_val]:%d ", + entry->priority_val); + } + else + { + dprintf("\n[priority]:Disable "); + } +} + +sw_error_t +cmd_data_check_napt_mode(char *cmd_str, fal_napt_mode_t * arg_val, + a_uint32_t size) +{ + if (NULL == cmd_str) + { + return SW_BAD_VALUE; + } + + if (!strcasecmp(cmd_str, "fullcone")) + { + *arg_val = FAL_NAPT_FULL_CONE; + } + else if (!strcasecmp(cmd_str, "strictcone")) + { + *arg_val = FAL_NAPT_STRICT_CONE; + } + else if (!strcasecmp(cmd_str, "portstrict")) + { + *arg_val = FAL_NAPT_PORT_STRICT; + } + else if (!strcasecmp(cmd_str, "synmatric")) + { + *arg_val = FAL_NAPT_SYNMETRIC; + } + else + { + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_napt_mode(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:", param_name); + if (*(a_uint32_t *) buf == FAL_NAPT_FULL_CONE) + { + dprintf("FullCone"); + } + else if (*(a_uint32_t *) buf == FAL_NAPT_STRICT_CONE) + { + dprintf("StrictCone"); + } + else if (*(a_uint32_t *) buf == FAL_NAPT_PORT_STRICT) + { + dprintf("PortStrict"); + } + else if (*(a_uint32_t *) buf == FAL_NAPT_SYNMETRIC) + { + dprintf("Synmatric"); + } + else + { + dprintf("UNKNOWN VALUE"); + } +} + +sw_error_t +cmd_data_check_intf_mac_entry(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + a_uint32_t tmp = 0; + sw_error_t rv; + fal_intf_mac_entry_t entry; + + aos_mem_zero(&entry, sizeof (fal_intf_mac_entry_t)); + + do + { + cmd = get_sub_cmd("entryid", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.entry_id), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("vrfid", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.vrf_id), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("vid low", NULL); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: low vlan id\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: low vlan id\n"); + } + } + while (talk_mode && (SW_OK != rv)); + entry.vid_low = tmp & 0xffff; + + do + { + cmd = get_sub_cmd("vid high", NULL); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: high vlan id\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: high vlan id\n"); + } + } + while (talk_mode && (SW_OK != rv)); + entry.vid_high = tmp & 0xffff; + + cmd_data_check_element("mac addr", NULL, + "usage: the format is xx-xx-xx-xx-xx-xx \n", + cmd_data_check_macaddr, (cmd, &(entry.mac_addr), + sizeof (fal_mac_addr_t))); + + do + { + cmd = get_sub_cmd("ip4_route", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.ip4_route, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ip6_route", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.ip6_route, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + *(fal_intf_mac_entry_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_intf_mac_entry(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_intf_mac_entry_t *entry; + + entry = (fal_intf_mac_entry_t *) buf; + dprintf("\n[entryid]:0x%x [vrf_id]:0x%x [vid_low]:0x%x [vid_high]:0x%x", + entry->entry_id, entry->vrf_id, entry->vid_low, entry->vid_high); + + cmd_data_print_macaddr("\n[mac_addr]:", + (a_uint32_t *) & (entry->mac_addr), + sizeof (fal_mac_addr_t)); + + if (A_TRUE == entry->ip4_route) + { + dprintf("\n[ip4_route]:TRUE"); + } + else + { + dprintf("\n[ip4_route]:FALSE"); + } + + if (A_TRUE == entry->ip6_route) + { + dprintf(" [ip6_route]:TRUE"); + } + else + { + dprintf(" [ip6_route]:FALSE"); + } +} + +sw_error_t +cmd_data_check_pub_addr_entry(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_nat_pub_addr_t entry; + + aos_mem_zero(&entry, sizeof (fal_nat_pub_addr_t)); + + do + { + cmd = get_sub_cmd("entryid", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.entry_id), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + cmd_data_check_element("pub addr", NULL, + "usage: the format is xx.xx.xx.xx \n", + cmd_data_check_ip4addr, (cmd, &(entry.pub_addr), 4)); + + *(fal_nat_pub_addr_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_pub_addr_entry(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_nat_pub_addr_t *entry; + + entry = (fal_nat_pub_addr_t *) buf; + dprintf("[entryid]:0x%x ", entry->entry_id); + cmd_data_print_ip4addr("[pub_addr]:", + (a_uint32_t *) & (entry->pub_addr), + sizeof (fal_ip4_addr_t)); + +} + +sw_error_t +cmd_data_check_egress_shaper(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + a_bool_t bool = A_FALSE; + fal_egress_shaper_t entry; + + aos_mem_zero(&entry, sizeof (fal_egress_shaper_t)); + + do + { + cmd = get_sub_cmd("bytebased", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &bool, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + if (A_TRUE == bool) + { + entry.meter_unit = FAL_BYTE_BASED; + } + else + { + entry.meter_unit = FAL_FRAME_BASED; + } + + do + { + cmd = get_sub_cmd("cir", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.cir), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cbs", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.cbs), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("eir", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.eir), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ebs", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.ebs), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + *(fal_egress_shaper_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_egress_shaper(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_egress_shaper_t *entry; + + entry = (fal_egress_shaper_t *) buf; + + if (FAL_BYTE_BASED == entry->meter_unit) + { + dprintf("\n[byte_based]:yes "); + } + else + { + dprintf("\n[byte_based]:no "); + } + + dprintf("[cir]:0x%08x [cbs]:0x%08x [eir]:0x%08x [ebs]:0x%08x", + entry->cir, entry->cbs, entry->eir, entry->ebs); +} + +sw_error_t +cmd_data_check_policer_timesslot(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + + if (!strncasecmp(cmd_str, "100us", 5)) + *arg_val = FAL_RATE_MI_100US; + else if (!strncasecmp(cmd_str, "1ms", 3)) + *arg_val = FAL_RATE_MI_1MS; + else if (!strncasecmp(cmd_str, "10ms", 4)) + *arg_val = FAL_RATE_MI_10MS; + else if (!strncasecmp(cmd_str, "100ms", 5)) + *arg_val = FAL_RATE_MI_100MS; + else + { + //dprintf("input error \n"); + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_policer_timesslot(char * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:", param_name); + if (*(a_uint32_t *) buf == FAL_RATE_MI_100US) + { + dprintf("100us"); + } + else if (*(a_uint32_t *) buf == FAL_RATE_MI_1MS) + { + dprintf("1ms"); + } + else if (*(a_uint32_t *) buf == FAL_RATE_MI_10MS) + { + dprintf("10ms"); + } + else if (*(a_uint32_t *) buf == FAL_RATE_MI_100MS) + { + dprintf("100ms"); + } + else + { + dprintf("UNKNOWN VALUE"); + } +} + + +sw_error_t +cmd_data_check_acl_policer(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + a_bool_t bool = A_FALSE; + fal_acl_policer_t entry; + + aos_mem_zero(&entry, sizeof (fal_acl_policer_t)); + + do + { + cmd = get_sub_cmd("counter_mode", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.counter_mode), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("bytebased", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &bool, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + if (A_TRUE == bool) + { + entry.meter_unit = FAL_BYTE_BASED; + } + else + { + entry.meter_unit = FAL_FRAME_BASED; + } + + if (A_TRUE == entry.counter_mode) + { + *(fal_acl_policer_t *)val = entry; + return SW_OK; + } + + do + { + cmd = get_sub_cmd("couple_flag", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.couple_flag), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("color_aware", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.color_mode), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("deficit_flag", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.deficit_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cir", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.cir), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cbs", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.cbs), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("eir", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.eir), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ebs", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.ebs), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("meter_interval", "1ms"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the format <100us/1ms/10ms/100ms>\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_policer_timesslot(cmd, &(entry.meter_interval), + sizeof (fal_rate_mt_t)); + if (SW_OK != rv) + dprintf("usage: the format <100us/1ms/10ms/100ms>\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + *(fal_acl_policer_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_acl_policer(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_acl_policer_t *entry; + + entry = (fal_acl_policer_t *) buf; + + if (A_TRUE == entry->counter_mode) + { + dprintf("[counter_mode]:yes "); + } + else + { + dprintf("[counter_mode]:no "); + } + + if (FAL_BYTE_BASED == entry->meter_unit) + { + dprintf("[meter_unit]:byte_based "); + } + else + { + dprintf("[meter_unit]:frame_based "); + } + + if (A_TRUE == entry->counter_mode) + { + dprintf("[counter_lo]:0x%x [counter_hi]", entry->counter_low, entry->counter_high); + } + else + { + if (A_TRUE == entry->color_mode) + { + dprintf("[color_aware]:yes "); + } + else + { + dprintf("[color_aware]:no "); + } + + if (A_TRUE == entry->couple_flag) + { + dprintf("[couple_falg]:yes "); + } + else + { + dprintf("[couple_falg]:no "); + } + + if (A_TRUE == entry->deficit_en) + { + dprintf("[deficit_falg]:yes "); + } + else + { + dprintf("[deficit_falg]:no "); + } + + cmd_data_print_policer_timesslot("meter_interval", + (a_uint32_t *) & (entry->meter_interval), + sizeof (fal_rate_mt_t)); + + dprintf("\n[cir]:0x%08x [cbs]:0x%08x [eir]:0x%08x [ebs]:0x%08x", + entry->cir, entry->cbs, entry->eir, entry->ebs); + } + + return; +} + +sw_error_t +cmd_data_check_port_policer(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + a_bool_t bool = A_FALSE; + fal_port_policer_t entry; + + aos_mem_zero(&entry, sizeof (fal_port_policer_t)); + + do + { + cmd = get_sub_cmd("combine_enable", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.combine_mode), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("bytebased", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &bool, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + if (A_TRUE == bool) + { + entry.meter_unit = FAL_BYTE_BASED; + } + else + { + entry.meter_unit = FAL_FRAME_BASED; + } + + do + { + cmd = get_sub_cmd("couple_flag", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.couple_flag), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("color_aware", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.color_mode), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("deficit_flag", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.deficit_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("c_enable", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.c_enable), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cir", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.cir), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cbs", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.cbs), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("c_rate_flag", "0xfe"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.c_rate_flag), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("c_meter_interval", "1ms"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the format <100us/1ms/10ms/100ms>\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_policer_timesslot(cmd, &(entry.c_meter_interval), + sizeof (fal_rate_mt_t)); + if (SW_OK != rv) + dprintf("usage: the format <100us/1ms/10ms/100ms>\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("e_enable", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.e_enable), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("eir", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.eir), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ebs", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.ebs), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("e_rate_flag", "0xfe"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.e_rate_flag), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("e_meter_interval", "1ms"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the format <100us/1ms/10ms/100ms>\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_policer_timesslot(cmd, &(entry.e_meter_interval), + sizeof (fal_rate_mt_t)); + if (SW_OK != rv) + dprintf("usage: the format <100us/1ms/10ms/100ms>\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + *(fal_port_policer_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_port_policer(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_port_policer_t *entry; + + entry = (fal_port_policer_t *) buf; + + if (A_TRUE == entry->combine_mode) + { + dprintf("[combine_mode]:yes "); + } + else + { + dprintf("[combine_mode]:no "); + } + + if (FAL_BYTE_BASED == entry->meter_unit) + { + dprintf("[meter_unit]:byte_based "); + } + else + { + dprintf("[meter_unit]:frame_based "); + } + + if (A_TRUE == entry->color_mode) + { + dprintf("[color_aware]:yes "); + } + else + { + dprintf("[color_aware]:no "); + } + + if (A_TRUE == entry->couple_flag) + { + dprintf("[couple_falg]:yes "); + } + else + { + dprintf("[couple_falg]:no "); + } + + if (A_TRUE == entry->deficit_en) + { + dprintf("[deficit_falg]:yes "); + } + else + { + dprintf("[deficit_falg]:no "); + } + + if (A_TRUE == entry->c_enable) + { + dprintf("\n[c_enable]:yes "); + } + else + { + dprintf("\n[c_enable]:no "); + } + + dprintf("[cir]:0x%08x [cbs]:0x%08x ", entry->cir,entry->cbs); + + + + dprintf("[c_rate_flag]:0x%08x ", entry->c_rate_flag); + + cmd_data_print_policer_timesslot("c_meter_interval", + (a_uint32_t *) & (entry->c_meter_interval), + sizeof (fal_rate_mt_t)); + + if (A_TRUE == entry->e_enable) + { + dprintf("\n[e_enable]:yes "); + } + else + { + dprintf("\n[e_enable]:no "); + } + + dprintf("[eir]:0x%08x [ebs]:0x%08x ", entry->eir, entry->ebs); + + dprintf("[e_rate_flag]:0x%08x ", entry->e_rate_flag); + + cmd_data_print_policer_timesslot("e_meter_interval", + (a_uint32_t *) & (entry->e_meter_interval), + sizeof (fal_rate_mt_t)); + return; +} + +sw_error_t +cmd_data_check_mac_mode(char *cmd_str, fal_interface_mac_mode_t * arg_val, + a_uint32_t size) +{ + if (NULL == cmd_str) + { + return SW_BAD_VALUE; + } + + if (0 == cmd_str[0]) + { + *arg_val = FAL_MAC_MODE_RGMII; + } + else if (!strcasecmp(cmd_str, "rgmii")) + { + *arg_val = FAL_MAC_MODE_RGMII; + } + else if (!strcasecmp(cmd_str, "rmii")) + { + *arg_val = FAL_MAC_MODE_RMII; + } + else if (!strcasecmp(cmd_str, "gmii")) + { + *arg_val = FAL_MAC_MODE_GMII; + } + else if (!strcasecmp(cmd_str, "mii")) + { + *arg_val = FAL_MAC_MODE_MII; + } + else if (!strcasecmp(cmd_str, "sgmii")) + { + *arg_val = FAL_MAC_MODE_SGMII; + } + else if (!strcasecmp(cmd_str, "fiber")) + { + *arg_val = FAL_MAC_MODE_FIBER; + } + else if (!strcasecmp(cmd_str, "default")) + { + *arg_val = FAL_MAC_MODE_DEFAULT; + } + else + { + return SW_BAD_VALUE; + } + + return SW_OK; +} + +sw_error_t +cmd_data_check_clock_mode(char *cmd_str, fal_interface_clock_mode_t * arg_val, + a_uint32_t size) +{ + if (NULL == cmd_str) + { + return SW_BAD_VALUE; + } + + if (0 == cmd_str[0]) + { + *arg_val = FAL_INTERFACE_CLOCK_MAC_MODE; + } + if (!strcasecmp(cmd_str, "mac")) + { + *arg_val = FAL_INTERFACE_CLOCK_MAC_MODE; + } + else if (!strcasecmp(cmd_str, "phy")) + { + *arg_val = FAL_INTERFACE_CLOCK_PHY_MODE; + } + else + { + return SW_BAD_VALUE; + } + + return SW_OK; +} + + +sw_error_t +cmd_data_check_mac_config(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + fal_mac_config_t entry; + + aos_mem_zero(&entry, sizeof (fal_mac_config_t)); + + cmd_data_check_element("mac_mode", "rgmii", + "usage: port0 \nport6 \n", + cmd_data_check_mac_mode, (cmd, &(entry.mac_mode), 4)); + + if (FAL_MAC_MODE_RGMII == entry.mac_mode) + { + cmd_data_check_element("txclk_delay_cmd", "no", + "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &(entry.config.rgmii.txclk_delay_cmd), 4)); + + cmd_data_check_element("txclk_delay_select", "0", + "usage: <0-3>\n", + cmd_data_check_uint32, (cmd, &(entry.config.rgmii.txclk_delay_sel), 4)); + + cmd_data_check_element("rxclk_delay_cmd", "no", + "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &(entry.config.rgmii.rxclk_delay_cmd), 4)); + + cmd_data_check_element("rxclk_delay_select", "0", + "usage: <0-3>\n", + cmd_data_check_uint32, (cmd, &(entry.config.rgmii.rxclk_delay_sel), 4)); + } + + if (FAL_MAC_MODE_RMII == entry.mac_mode) + { + cmd_data_check_element("master_mode", "no", + "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &(entry.config.rmii.master_mode), 4)); + + cmd_data_check_element("slave_mode", "no", + "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &(entry.config.rmii.slave_mode), 4)); + + cmd_data_check_element("clock_inverse", "no", + "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &(entry.config.rmii.clock_inverse), 4)); + cmd_data_check_element("pipe_rxclk_sel", "no", + "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &(entry.config.rmii.pipe_rxclk_sel), 4)); + + } + + if ((FAL_MAC_MODE_GMII == entry.mac_mode) + || (FAL_MAC_MODE_MII == entry.mac_mode)) + { + cmd_data_check_element("clock_mode", "mac", + "usage: \n", + cmd_data_check_clock_mode, (cmd, &(entry.config.gmii.clock_mode), 4)); + + cmd_data_check_element("txclk_select", "0", + "usage: <0-1>\n", + cmd_data_check_uint32, (cmd, &(entry.config.gmii.txclk_select), 4)); + + cmd_data_check_element("rxclk_select", "0", + "usage: <0-1>\n", + cmd_data_check_uint32, (cmd, &(entry.config.gmii.rxclk_select), 4)); + } + + if (FAL_MAC_MODE_SGMII == entry.mac_mode) + { + cmd_data_check_element("clock_mode", "mac", + "usage: \n", + cmd_data_check_clock_mode, (cmd, &(entry.config.sgmii.clock_mode), 4)); + + cmd_data_check_element("auto_neg", "no", + "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &(entry.config.sgmii.auto_neg), 4)); + + cmd_data_check_element("force_speed", "no", + "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &(entry.config.sgmii.force_speed), 4)); + + cmd_data_check_element("prbs_enable", "no", + "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &(entry.config.sgmii.prbs_enable), 4)); + + cmd_data_check_element("rem_phy_lpbk", "no", + "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &(entry.config.sgmii.rem_phy_lpbk), 4)); + } + + if (FAL_MAC_MODE_FIBER == entry.mac_mode) + { + cmd_data_check_element("auto_neg", "no", + "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &(entry.config.fiber.auto_neg), 4)); + + cmd_data_check_element("fx100_enable", "no", + "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &(entry.config.fiber.fx100_enable), 4)); + } + + *(fal_mac_config_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_mac_config(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_mac_config_t *entry; + + entry = (fal_mac_config_t *) buf; + + if (FAL_MAC_MODE_RGMII == entry->mac_mode) + { + dprintf("[mac_mode]:rgmii"); + } + else if (FAL_MAC_MODE_RMII == entry->mac_mode) + { + dprintf("[mac_mode]:rmii"); + } + else if (FAL_MAC_MODE_GMII == entry->mac_mode) + { + dprintf("[mac_mode]:gmii"); + } + else if (FAL_MAC_MODE_MII == entry->mac_mode) + { + dprintf("[mac_mode]:mii"); + } + else if (FAL_MAC_MODE_SGMII == entry->mac_mode) + { + dprintf("[mac_mode]:sgmii"); + } + else if (FAL_MAC_MODE_FIBER == entry->mac_mode) + { + dprintf("[mac_mode]:fiber"); + } + else + { + dprintf("[mac_mode]:default"); + } + + if (FAL_MAC_MODE_RGMII == entry->mac_mode) + { + if (A_TRUE == entry->config.rgmii.txclk_delay_cmd) + { + dprintf("\n[txclk_delay_cmd]:yes [txclk_delay_select]:%d", entry->config.rgmii.txclk_delay_sel); + } + else + { + dprintf("\n[txclk_delay_cmd]:no"); + } + + if (A_TRUE == entry->config.rgmii.rxclk_delay_cmd) + { + dprintf("\n[rxclk_delay_cmd]:yes [rxclk_delay_select]:%d", entry->config.rgmii.rxclk_delay_sel); + } + else + { + dprintf("\n[rxclk_delay_cmd]:no"); + } + + } + else if (FAL_MAC_MODE_RMII == entry->mac_mode) + { + if (A_TRUE == entry->config.rmii.master_mode) + { + dprintf("\n[master_mode]:yes"); + } + else + { + dprintf("\n[master_mode]:no"); + } + + if (A_TRUE == entry->config.rmii.slave_mode) + { + dprintf("\n[slave_mode]:yes"); + } + else + { + dprintf("\n[slave_mode]:no"); + } + + if (A_TRUE == entry->config.rmii.clock_inverse) + { + dprintf("\n[clock_inverse]:yes"); + } + else + { + dprintf("\n[clock_inverse]:no"); + } + + if (A_TRUE == entry->config.rmii.pipe_rxclk_sel) + { + dprintf("\n[pipe_rxclk_sel]:yes"); + } + else + { + dprintf("\n[pipe_rxclk_sel]:no"); + } + + + } + else if ((FAL_MAC_MODE_GMII == entry->mac_mode) + || (FAL_MAC_MODE_MII == entry->mac_mode)) + { + + if (FAL_INTERFACE_CLOCK_PHY_MODE == entry->config.gmii.clock_mode) + { + dprintf("\n[clock_mode]:phy [txclk_select]:%d [rxclk_select]:%d", entry->config.gmii.txclk_select, entry->config.gmii.rxclk_select); + } + else + { + dprintf("\n[clock_mode]:mac [txclk_select]:%d [rxclk_select]:%d", entry->config.gmii.txclk_select, entry->config.gmii.rxclk_select); + } + } + else if (FAL_MAC_MODE_SGMII == entry->mac_mode) + { + if (FAL_INTERFACE_CLOCK_PHY_MODE == entry->config.sgmii.clock_mode) + { + dprintf("\n[clock_mode]:phy"); + } + else + { + dprintf("\n[clock_mode]:mac"); + } + + if (A_TRUE == entry->config.sgmii.auto_neg) + { + dprintf("\n[auto_neg]:yes"); + } + else + { + dprintf("\n[auto_neg]:no"); + } + if (A_TRUE == entry->config.sgmii.force_speed) + { + dprintf("\n[force_speed]:yes"); + } + else + { + dprintf("\n[force_speed]:no"); + } + if (A_TRUE == entry->config.sgmii.prbs_enable) + { + dprintf("\n[prbs_enable]:yes"); + } + else + { + dprintf("\n[prbs_enable]:no"); + } + if (A_TRUE == entry->config.sgmii.rem_phy_lpbk) + { + dprintf("\n[rem_phy_lpbk]:yes"); + } + else + { + dprintf("\n[rem_phy_lpbk]:no"); + } + } + else if (FAL_MAC_MODE_FIBER == entry->mac_mode) + { + if (A_TRUE == entry->config.fiber.auto_neg) + { + dprintf("\n[auto_neg]:yes"); + } + else + { + dprintf("\n[auto_neg]:no"); + } + if (A_TRUE == entry->config.fiber.fx100_enable) + { + dprintf("\n[fx100_enable]:yes"); + } + else + { + dprintf("\n[fx100_enable]:no"); + } + } + + return; +} + +sw_error_t +cmd_data_check_phy_config(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + fal_phy_config_t entry; + + aos_mem_zero(&entry, sizeof (fal_phy_config_t)); + + cmd_data_check_element("mac_mode", "rgmii", + "usage: \n", + cmd_data_check_mac_mode, (cmd, &(entry.mac_mode), 4)); + + if (FAL_MAC_MODE_RGMII == entry.mac_mode) + { + + cmd_data_check_element("txclk_delay_cmd", "no", + "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &(entry.txclk_delay_cmd), 4)); + + cmd_data_check_element("txclk_delay_select", "0", + "usage: <0-3>\n", + cmd_data_check_uint32, (cmd, &(entry.txclk_delay_sel), 4)); + + cmd_data_check_element("rxclk_delay_cmd", "no", + "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &(entry.rxclk_delay_cmd), 4)); + + cmd_data_check_element("rxclk_delay_select", "0", + "usage: <0-3>\n", + cmd_data_check_uint32, (cmd, &(entry.rxclk_delay_sel), 4)); + } + else + { + return SW_BAD_VALUE; + } + + *(fal_phy_config_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_phy_config(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_phy_config_t *entry; + + entry = (fal_phy_config_t *) buf; + + if (FAL_MAC_MODE_RGMII == entry->mac_mode) + { + dprintf("[mac_mode]:rgmii"); + } + else + { + dprintf("[mac_mode]:default"); + } + + if (FAL_MAC_MODE_RGMII == entry->mac_mode) + { + if (A_TRUE == entry->txclk_delay_cmd) + { + dprintf("\n[txclk_delay_cmd]:yes [txclk_delay_select]:%d", entry->txclk_delay_sel); + } + else + { + dprintf("\n[txclk_delay_cmd]:no"); + } + + if (A_TRUE == entry->rxclk_delay_cmd) + { + dprintf("\n[rxclk_delay_cmd]:yes [rxclk_delay_select]:%d", entry->rxclk_delay_sel); + } + else + { + dprintf("\n[rxclk_delay_cmd]:no"); + } + } + return; +} + +sw_error_t +cmd_data_check_fdb_smode(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + + if (!strcasecmp(cmd_str, "ivl")) + *arg_val = INVALID_VLAN_IVL; + else if (!strcasecmp(cmd_str, "svl")) + *arg_val = INVALID_VLAN_SVL; + else + { + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_fdb_smode(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:", param_name); + if (*(a_uint32_t *) buf == 1) + { + dprintf("IVL"); + } + else if (*(a_uint32_t *) buf == 0) + { + dprintf("SVL"); + } + else + { + dprintf("UNKNOWN VALUE"); + } +} + +void +cmd_data_print_fdb_ctrl_mode(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:", param_name); + if (*(a_uint32_t *) buf == 0) + { + dprintf("auto mode"); + } + else if (*(a_uint32_t *) buf == 1) + { + dprintf("control mode"); + } + else + { + dprintf("UNKNOWN VALUE"); + } +} + +sw_error_t +cmd_data_check_fx100_link_mode(char* cmd_str, fx100_ctrl_link_mode_t* arg_val) +{ + if (0 == cmd_str[0]) + { + *arg_val = Fx100BASE_MODE; + } + else if (!strcasecmp(cmd_str, "fx100base")) + { + *arg_val = Fx100BASE_MODE; + } + else + { + dprintf("UNKNOWN VALUE"); + return SW_BAD_VALUE; + } + + return SW_OK; +} + +sw_error_t +cmd_data_check_fx100_fd_mode(char *cmd_str, a_uint32_t * arg_val) +{ + if (0 == cmd_str[0]) + { + *arg_val = FX100_FULL_DUPLEX; + } + else if (!strcasecmp(cmd_str, "fullduplex")) + { + *arg_val = FX100_FULL_DUPLEX; + } + else if (!strcasecmp(cmd_str, "halfduplex")) + { + *arg_val = FX100_HALF_DUPLEX; + } + else + { + dprintf("UNKNOWN VALUE"); + return SW_BAD_VALUE; + } + + return SW_OK; +} + +sw_error_t +cmd_data_check_sgmii_fiber_mode(char *cmd_str, a_uint32_t * arg_val) +{ + if (0 == cmd_str[0]) + { + *arg_val = FX100_SERDS_MODE; + } + else if (!strcasecmp(cmd_str, "fx100serds")) + { + *arg_val = FX100_SERDS_MODE; + } + else + { + dprintf("UNKNOWN VALUE"); + return SW_BAD_VALUE; + } + return SW_OK; +} + +sw_error_t +cmd_data_check_fx100_config(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + fal_fx100_ctrl_config_t entry; + + aos_mem_zero(&entry, sizeof (fal_fx100_ctrl_config_t)); + + cmd_data_check_element("link_mode", "fx100base", + "usage: \n", + cmd_data_check_fx100_link_mode, (cmd, &(entry.link_mode))); + + cmd_data_check_element("overshoot", "no", + "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &(entry.overshoot), 4)); + + cmd_data_check_element("loopback_mode", "no", + "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &(entry.loopback), 4)); + + cmd_data_check_element("fd_mode", "fullduplex", + "usage: \n", + cmd_data_check_fx100_fd_mode, (cmd, &(entry.fd_mode))); + + cmd_data_check_element("col_test", "no", + "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &(entry.col_test), 4)); + + cmd_data_check_element("sgmii_fiber", "fx100serds", + "usage: \n", + cmd_data_check_sgmii_fiber_mode, (cmd, &(entry.sgmii_fiber_mode))); + + cmd_data_check_element("crs_ctrl", "yes", + "usage: \n", + cmd_data_check_confirm, (cmd, A_TRUE, &(entry.crs_ctrl), 4)); + + cmd_data_check_element("loopback_ctrl", "no", + "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &(entry.loopback_ctrl), 4)); + + cmd_data_check_element("crs_col_100_ctrl", "yes", + "usage: \n", + cmd_data_check_confirm, (cmd, A_TRUE, &(entry.crs_col_100_ctrl), 4)); + + cmd_data_check_element("loop_en", "no", + "usage: \n", + cmd_data_check_confirm, (cmd, A_FALSE, &(entry.loop_en), 4)); + + + + *(fal_fx100_ctrl_config_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_fx100_config(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_fx100_ctrl_config_t* entry; + + entry = (fal_fx100_ctrl_config_t*)buf; + + if (Fx100BASE_MODE == entry->link_mode) + { + dprintf("[link_mode]: fx100base\n"); + } + + if (A_TRUE == entry->overshoot) + { + dprintf("[overshoot]: yes\n"); + } + else + { + dprintf("[overshoot]: no\n"); + } + + if (A_TRUE == entry->loopback) + { + dprintf("[loopback_mode]: yes\n"); + } + else + { + dprintf("[loopback_mode]: no\n"); + } + + if (FX100_FULL_DUPLEX == entry->fd_mode) + { + dprintf("[fd_mode]: fullduplex\n"); + } + else + { + dprintf("[fd_mode]: halfduplex\n"); + } + + if (A_TRUE == entry->col_test) + { + dprintf("[col_test]: yes\n"); + } + else + { + dprintf("[col_test]: no\n"); + } + + if (FX100_SERDS_MODE == entry->sgmii_fiber_mode) + { + dprintf("[sgmii_fiber]: fx100_serds\n"); + } + + if (A_TRUE == entry->crs_ctrl) + { + dprintf("[crs_ctrl]: yes\n"); + } + else + { + dprintf("[crs_ctrl]: no\n"); + } + + if (A_TRUE == entry->loopback_ctrl) + { + dprintf("[loopback_ctrl]: yes\n"); + } + else + { + dprintf("[loopback_ctrl]: no\n"); + } + + if (A_TRUE == entry->crs_col_100_ctrl) + { + dprintf("[crs_col_100_ctrl]: yes\n"); + } + else + { + dprintf("[crs_col_100_ctrl]: no\n"); + } + + if (A_TRUE == entry->loop_en) + { + dprintf("[loop_en]: yes\n"); + } + else + { + dprintf("[loop_en]: no\n"); + } + +} + +sw_error_t +cmd_data_check_sec_mac(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + + if (!strcasecmp(cmd_str, "resv_vid")) + *arg_val = FAL_NORM_MAC_RESV_VID_CMD; + else if (!strcasecmp(cmd_str, "invalid_src_addr")) + *arg_val = FAL_NORM_MAC_INVALID_SRC_ADDR_CMD; + else + { + dprintf("UNKNOWN VALUE"); + return SW_BAD_VALUE; + } + + return SW_OK; +} + +sw_error_t +cmd_data_check_sec_ip(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + + if (!strcasecmp(cmd_str, "invalid_ver")) + *arg_val = FAL_NORM_IP_INVALID_VER_CMD; + else if (!strcasecmp(cmd_str, "same_addr")) + *arg_val = FAL_NROM_IP_SAME_ADDR_CMD; + else if (!strcasecmp(cmd_str, "ttl_change_status")) + *arg_val = FAL_NROM_IP_TTL_CHANGE_STATUS; + else if (!strcasecmp(cmd_str, "ttl_val")) + *arg_val = FAL_NROM_IP_TTL_VALUE; + else + { + dprintf("UNKNOWN VALUE"); + return SW_BAD_VALUE; + } + + return SW_OK; +} + + +sw_error_t +cmd_data_check_sec_ip4(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + + if (!strcasecmp(cmd_str, "invalid_hl")) + *arg_val = FAL_NROM_IP4_INVALID_HL_CMD; + else if (!strcasecmp(cmd_str, "hdr_opts")) + *arg_val = FAL_NROM_IP4_HDR_OPTIONS_CMD; + else if (!strcasecmp(cmd_str, "invalid_df")) + *arg_val = FAL_NROM_IP4_INVALID_DF_CMD; + else if (!strcasecmp(cmd_str, "frag_offset_min_len")) + *arg_val = FAL_NROM_IP4_FRAG_OFFSET_MIN_LEN_CMD; + else if (!strcasecmp(cmd_str, "frag_offset_min_size")) + *arg_val = FAL_NROM_IP4_FRAG_OFFSET_MIN_SIZE; + else if (!strcasecmp(cmd_str, "frag_offset_max_len")) + *arg_val = FAL_NROM_IP4_FRAG_OFFSET_MAX_LEN_CMD; + else if (!strcasecmp(cmd_str, "invalid_frag_offset")) + *arg_val = FAL_NROM_IP4_INVALID_FRAG_OFFSET_CMD; + else if (!strcasecmp(cmd_str, "invalid_sip")) + *arg_val = FAL_NROM_IP4_INVALID_SIP_CMD; + else if (!strcasecmp(cmd_str, "invalid_dip")) + *arg_val = FAL_NROM_IP4_INVALID_DIP_CMD; + else if (!strcasecmp(cmd_str, "invalid_chksum")) + *arg_val = FAL_NROM_IP4_INVALID_CHKSUM_CMD; + else if (!strcasecmp(cmd_str, "invalid_pl")) + *arg_val = FAL_NROM_IP4_INVALID_PL_CMD; + else if (!strcasecmp(cmd_str, "df_clear_status")) + *arg_val = FAL_NROM_IP4_DF_CLEAR_STATUS; + else if (!strcasecmp(cmd_str, "ipid_random_status")) + *arg_val = FAL_NROM_IP4_IPID_RANDOM_STATUS; + else + { + dprintf("UNKNOWN VALUE"); + return SW_BAD_VALUE; + } + + return SW_OK; +} + +sw_error_t +cmd_data_check_sec_ip6(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + + if (!strcasecmp(cmd_str, "invalid_dip")) + *arg_val = FAL_NROM_IP6_INVALID_DIP_CMD; + else if (!strcasecmp(cmd_str, "invalid_sip")) + *arg_val = FAL_NROM_IP6_INVALID_SIP_CMD; + else if (!strcasecmp(cmd_str, "invalid_pl")) + *arg_val = FAL_NROM_IP6_INVALID_PL_CMD; + else + { + dprintf("UNKNOWN VALUE"); + return SW_BAD_VALUE; + } + + return SW_OK; +} + + +sw_error_t +cmd_data_check_sec_tcp(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + + if (!strcasecmp(cmd_str, "blat")) + *arg_val = FAL_NROM_TCP_BLAT_CMD; + else if (!strcasecmp(cmd_str, "invalid_hl")) + *arg_val = FAL_NROM_TCP_INVALID_HL_CMD; + else if (!strcasecmp(cmd_str, "min_hdr_size")) + *arg_val = FAL_NROM_TCP_MIN_HDR_SIZE; + else if (!strcasecmp(cmd_str, "invalid_syn")) + *arg_val = FAL_NROM_TCP_INVALID_SYN_CMD; + else if (!strcasecmp(cmd_str, "su_block")) + *arg_val = FAL_NROM_TCP_SU_BLOCK_CMD; + else if (!strcasecmp(cmd_str, "sp_block")) + *arg_val = FAL_NROM_TCP_SP_BLOCK_CMD; + else if (!strcasecmp(cmd_str, "sap_block")) + *arg_val = FAL_NROM_TCP_SAP_BLOCK_CMD; + else if (!strcasecmp(cmd_str, "xmas_scan")) + *arg_val = FAL_NROM_TCP_XMAS_SCAN_CMD; + else if (!strcasecmp(cmd_str, "null_scan")) + *arg_val = FAL_NROM_TCP_NULL_SCAN_CMD; + else if (!strcasecmp(cmd_str, "sr_block")) + *arg_val = FAL_NROM_TCP_SR_BLOCK_CMD; + else if (!strcasecmp(cmd_str, "sf_block")) + *arg_val = FAL_NROM_TCP_SF_BLOCK_CMD; + else if (!strcasecmp(cmd_str, "sar_block")) + *arg_val = FAL_NROM_TCP_SAR_BLOCK_CMD; + else if (!strcasecmp(cmd_str, "rst_scan")) + *arg_val = FAL_NROM_TCP_RST_SCAN_CMD; + else if (!strcasecmp(cmd_str, "rst_with_data")) + *arg_val = FAL_NROM_TCP_RST_WITH_DATA_CMD; + else if (!strcasecmp(cmd_str, "fa_block")) + *arg_val = FAL_NROM_TCP_FA_BLOCK_CMD; + else if (!strcasecmp(cmd_str, "pa_block")) + *arg_val = FAL_NROM_TCP_PA_BLOCK_CMD; + else if (!strcasecmp(cmd_str, "ua_block")) + *arg_val = FAL_NROM_TCP_UA_BLOCK_CMD; + else if (!strcasecmp(cmd_str, "invalid_chksum")) + *arg_val = FAL_NROM_TCP_INVALID_CHKSUM_CMD; + else if (!strcasecmp(cmd_str, "invalid_urgptr")) + *arg_val = FAL_NROM_TCP_INVALID_URGPTR_CMD; + else if (!strcasecmp(cmd_str, "invalid_opts")) + *arg_val = FAL_NROM_TCP_INVALID_OPTIONS_CMD; + else + { + dprintf("UNKNOWN VALUE"); + return SW_BAD_VALUE; + } + + return SW_OK; +} + + +sw_error_t +cmd_data_check_sec_udp(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + + if (!strcasecmp(cmd_str, "blat")) + *arg_val = FAL_NROM_UDP_BLAT_CMD; + else if (!strcasecmp(cmd_str, "invalid_len")) + *arg_val = FAL_NROM_UDP_INVALID_LEN_CMD; + else if (!strcasecmp(cmd_str, "invalid_chksum")) + *arg_val = FAL_NROM_UDP_INVALID_CHKSUM_CMD; + else + { + dprintf("UNKNOWN VALUE"); + return SW_BAD_VALUE; + } + + return SW_OK; +} + +sw_error_t +cmd_data_check_sec_icmp4(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + + if (!strcasecmp(cmd_str, "ping_pl_exceed")) + *arg_val = FAL_NROM_ICMP4_PING_PL_EXCEED_CMD; + else if (!strcasecmp(cmd_str, "ping_frag")) + *arg_val = FAL_NROM_ICMP4_PING_FRAG_CMD; + else if (!strcasecmp(cmd_str, "ping_max_pl")) + *arg_val = FAL_NROM_ICMP4_PING_MAX_PL_VALUE; + else + { + //dprintf("input error"); + return SW_BAD_VALUE; + } + + return SW_OK; +} + +sw_error_t +cmd_data_check_sec_icmp6(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + + if (!strcasecmp(cmd_str, "ping_pl_exceed")) + *arg_val = FAL_NROM_ICMP6_PING_PL_EXCEED_CMD; + else if (!strcasecmp(cmd_str, "ping_frag")) + *arg_val = FAL_NROM_ICMP6_PING_FRAG_CMD; + else if (!strcasecmp(cmd_str, "ping_max_pl")) + *arg_val = FAL_NROM_ICMP6_PING_MAX_PL_VALUE; + else + { + //dprintf("input error"); + return SW_BAD_VALUE; + } + + return SW_OK; +} + +sw_error_t +cmd_data_check_remark_entry(char *info, void *val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_egress_remark_table_t *pEntry = (fal_egress_remark_table_t *)val; + a_uint32_t tmp = 0; + + memset(pEntry, 0, sizeof(fal_egress_remark_table_t)); + + /* get remark_dscp */ + do + { + cmd = get_sub_cmd("remark dscp", "enable"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_enable(cmd, &(pEntry->remark_dscp), sizeof(a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + /* get remark_up */ + do + { + cmd = get_sub_cmd("remark up", "enable"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_enable(cmd, &(pEntry->remark_up), sizeof(a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + /* get remark_dei */ + do + { + cmd = get_sub_cmd("remark dei", "enable"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_enable(cmd, &(pEntry->remark_dei), sizeof(a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + /* get g_dscp */ + do + { + cmd = get_sub_cmd("green dscp", NULL); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 63\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: the range is 0 -- 63\n"); + } + + if (tmp > 63) + { + dprintf("usage: the range is 0 -- 63\n"); + rv = SW_OUT_OF_RANGE; + } + } + } + while (talk_mode && (SW_OK != rv)); + pEntry->g_dscp = tmp; + + /* get y_dscp */ + do + { + cmd = get_sub_cmd("yellow dscp", NULL); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 63\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: the range is 0 -- 63\n"); + } + + if (tmp > 63) + { + dprintf("usage: the range is 0 -- 63\n"); + rv = SW_OUT_OF_RANGE; + } + } + } + while (talk_mode && (SW_OK != rv)); + pEntry->y_dscp = tmp; + + /* get g_up */ + do + { + cmd = get_sub_cmd("green up", NULL); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 63\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: the range is 0 -- 7\n"); + } + + if (tmp > 63) + { + dprintf("usage: the range is 0 -- 7\n"); + rv = SW_OUT_OF_RANGE; + } + } + } + while (talk_mode && (SW_OK != rv)); + pEntry->g_up = tmp; + + /* get y_up */ + do + { + cmd = get_sub_cmd("yellow up", NULL); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 63\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: the range is 0 -- 7\n"); + } + + if (tmp > 63) + { + dprintf("usage: the range is 0 -- 7\n"); + rv = SW_OUT_OF_RANGE; + } + } + } + while (talk_mode && (SW_OK != rv)); + pEntry->y_up = tmp; + + /* get g_dei */ + do + { + cmd = get_sub_cmd("green dei", NULL); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 1\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: the range is 0 -- 1\n"); + } + + if (tmp > 1) + { + dprintf("usage: the range is 0 -- 1\n"); + rv = SW_OUT_OF_RANGE; + } + } + } + while (talk_mode && (SW_OK != rv)); + pEntry->g_dei = tmp; + + /* get y_dei */ + do + { + cmd = get_sub_cmd("yellow dei", NULL); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 1\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: the range is 0 -- 1\n"); + } + + if (tmp > 1) + { + dprintf("usage: the range is 0 -- 1\n"); + rv = SW_OUT_OF_RANGE; + } + } + } + while (talk_mode && (SW_OK != rv)); + pEntry->y_dei = tmp; + + +/* + dprintf("remark_dscp=%d, remark_up=%d, g_dscp=%d, y_dscp=%d\n", + pEntry->remark_dscp, + pEntry->remark_up, + pEntry->g_dscp, + pEntry->y_dscp); + + *(fal_egress_remark_table_t *) val = entry; +*/ + return SW_OK; +} + +void +cmd_data_print_remark_entry(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_egress_remark_table_t *entry; + + entry = (fal_egress_remark_table_t *) buf; + dprintf("\n"); + dprintf("[remark dscp]:%s\n", entry->remark_dscp?"enabled":"disabled"); + dprintf("[remark up]:%s\n", entry->remark_up?"enabled":"disabled"); + dprintf("[remark dei]:%s\n", entry->remark_dei?"enabled":"disabled"); + dprintf("[green dscp]:%d\n", entry->g_dscp); + dprintf("[yellow dscp]:%d\n", entry->y_dscp); + dprintf("[green up]:%d\n", entry->g_up); + dprintf("[yellow up]:%d\n", entry->y_up); + dprintf("[green dei]:%d\n", entry->g_dei); + dprintf("[yellow dei]:%d\n", entry->y_dei); + + return; +} + +sw_error_t +cmd_data_check_default_route_entry(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_default_route_t entry; + + aos_mem_zero(&entry, sizeof (fal_default_route_t)); + + do + { + cmd = get_sub_cmd("entry valid", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0 for invalid and 1 for valid \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.valid), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: 0 for invalid and 1 for valid \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("vrf id", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: VRF id\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.vrf_id), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: VRF id\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ip version", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0 for ipv4 and 1 for ipv6 \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &(entry.ip_version), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: 0 for ipv4 and 1 for ipv6 \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("route type", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0 for arp and 1 for wcmp \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.droute_type), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: 0 for arp and 1 for wcmp \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("index", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: index for arp entry or wcmp entry \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.index), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: index for arp entry or wcmp entry \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + *(fal_default_route_t *)val = entry; + return SW_OK; +} + +sw_error_t +cmd_data_check_u_qmap(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + a_uint32_t tmp; + sw_error_t rv; + fal_ucast_queue_dest_t entry; + + aos_mem_zero(&entry, sizeof (fal_ucast_queue_dest_t)); + + do + { + cmd = get_sub_cmd("src_profile", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: src profile \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: src profile \n"); + } + else + { + entry.src_profile = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("service_code_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.service_code_en), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("service_code", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: service code \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: service code \n"); + } + else + { + entry.service_code = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cpu_code_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.cpu_code_en), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cpu_code", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: cpu code \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: cpu code \n"); + } + else + { + entry.cpu_code = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("dst_port", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: dest port\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.dst_port), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: dst port \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + *(fal_ucast_queue_dest_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_default_route_entry(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_default_route_t *entry; + + entry = (fal_default_route_t *) buf; + dprintf("\n[valid]:0x%x [vrf_id]:0x%x [ip_version]:0x%x [host_type]:0x%x [index]:0x%x \n", + entry->valid, entry->vrf_id, entry->ip_version, entry->droute_type, entry->index); +} + +sw_error_t +cmd_data_check_host_route_entry(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_host_route_t entry; + + aos_mem_zero(&entry, sizeof (fal_intf_mac_entry_t)); + + do + { + cmd = get_sub_cmd("entry valid", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0 for invalid and 1 for valid \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.valid), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: 0 for invalid and 1 for valid \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("vrf id", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: VRF id\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.vrf_id), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: VRF id\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ip version", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0 for ipv4 and 1 for ipv6 \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.ip_version), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: 0 for ipv4 and 1 for ipv6 \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + if (entry.ip_version == 0) /*IPv4*/ + { + cmd_data_check_element("ip4 addr", NULL, + "usage: the format is xx.xx.xx.xx \n", + cmd_data_check_ip4addr, (cmd, &(entry.route_addr.ip4_addr), 4)); + } + else if (entry.ip_version == 1) /*IPv6*/ + { + cmd_data_check_element("ip6 addr", NULL, + "usage: the format is xx.xx.xx.xx \n", + cmd_data_check_ip4addr, (cmd, &(entry.route_addr.ip6_addr), 16)); + } + else + { + return SW_BAD_VALUE; + } + + do + { + cmd = get_sub_cmd("prefix_length", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: prefix length for this host route, 0~31 for " + "ipv4 and 0~127 for ipv6 \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.prefix_length), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: prefix length for this host route, 0~31 for ipv4 " + "and 0~127 for ipv6 \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + *(fal_host_route_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_host_route_entry(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_host_route_t *entry; + + entry = (fal_host_route_t *) buf; + dprintf("\n[valid]:0x%x [vrf_id]:0x%x [prefix_length]:0x%x", + entry->valid, entry->vrf_id, entry->prefix_length); + + if (0 == entry->ip_version) + { + cmd_data_print_ip4addr("\n[ip_addr]:", + (a_uint32_t *) & (entry->route_addr.ip4_addr), + sizeof (fal_ip4_addr_t)); + } + else if (1 == entry->ip_version) + { + cmd_data_print_ip6addr("\n[ip_addr]:", + (a_uint32_t *) & (entry->route_addr.ip6_addr), + sizeof (fal_ip6_addr_t)); + } +} + +sw_error_t +cmd_data_check_array(char *cmdstr, void *val, a_uint32_t size) +{ + char *tmp = NULL, *str_save; + a_uint32_t i = 0, j; + a_uint32_t addr; + int *dst = (int*)val; + + if (NULL == cmdstr) + { + return SW_BAD_VALUE; /*was: SW_OK;*/ + } + + if (0 == cmdstr[0]) + { + return SW_OK; + } + + tmp = (void *) strtok_r(cmdstr, "-", &str_save); + while (tmp) + { + if (size <= i) + { + return SW_BAD_VALUE; + } + + if ((2 < strlen(tmp)) || (0 == strlen(tmp))) + { + return SW_BAD_VALUE; + } + + for (j = 0; j < strlen(tmp); j++) + { + if (A_FALSE == is_hex(tmp[j])) + return SW_BAD_VALUE; + } + + sscanf(tmp, "%x", &addr); + if (0xff < addr) + { + return SW_BAD_VALUE; + } + + dst[i++] = addr; + tmp = (void *) strtok_r(NULL, "-", &str_save); + } + + if (size != i) + { + return SW_BAD_VALUE; + } + + return SW_OK; +} + + +sw_error_t +cmd_data_check_ip_wcmp_entry(char *cmd_str, void * val, a_uint32_t size) +{ + + char *cmd; + sw_error_t rv; + fal_ip_wcmp_t entry; + + aos_mem_zero(&entry, sizeof (fal_ip_wcmp_t)); + + do + { + cmd = get_sub_cmd("nh_nr", "16"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.nh_nr), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + else { + if(entry.nh_nr > 16) { + dprintf("usage: integer <= 16\n"); + rv = SW_BAD_VALUE; + } + } + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("nh_id", NULL); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the format is xx-xx-xx-xx-xx-xx \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_array(cmd, entry.nh_id, entry.nh_nr); + if (SW_OK != rv) + dprintf("usage: the format is xx-xx-xx-xx-xx-xx \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + *(fal_ip_wcmp_t *)val = entry; + return SW_OK; +} + + +void +cmd_data_print_ip_wcmp_entry(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_ip_wcmp_t *entry; + int i = 0; + + entry = (fal_ip_wcmp_t *) buf; + dprintf("\n[nh_nr]:0x%x", + entry->nh_nr); + dprintf("\n"); + for(i = 0; i < entry->nh_nr; i++) { + dprintf("[nh_id[%d]]:0x%x ", i, entry->nh_id[i]); + if(((i+1) % 4) == 0) + dprintf("\n"); + } +} + +sw_error_t +cmd_data_check_ip4_rfs_entry(char *cmd_str, void * val, a_uint32_t size) +{ + a_uint32_t tmp; + sw_error_t rv; + fal_ip4_rfs_t entry; + + aos_mem_zero(&entry, sizeof (fal_ip4_rfs_t)); + + rv = __cmd_data_check_complex("mac addr", NULL, + "usage: the format is xx-xx-xx-xx-xx-xx \n", + cmd_data_check_macaddr, &(entry.mac_addr), + sizeof (fal_mac_addr_t)); + if (rv) + { + return rv; + } + + rv = __cmd_data_check_complex("ip4 addr", NULL, + "usage: the format is xx.xx.xx.xx \n", + cmd_data_check_ip4addr, &(entry.ip4_addr), + 4); + if (rv) + { + return rv; + } + + rv = __cmd_data_check_complex("vid", "0", + "usage: the format is xx \n", + cmd_data_check_uint32, &(entry.vid), + sizeof (a_uint32_t)); + if (rv) + { + return rv; + } + + rv = __cmd_data_check_complex("loadbalance", "0", + "usage: the format is xx \n", + cmd_data_check_uint32, &tmp, + sizeof (a_uint32_t)); + if (rv) + { + return rv; + } + + entry.load_balance = tmp; + *(fal_ip4_rfs_t *)val = entry; + return SW_OK; +} + +sw_error_t +cmd_data_check_fdb_rfs(char *cmd_str, void * val, a_uint32_t size) +{ + a_uint32_t tmp; + sw_error_t rv; + fal_fdb_rfs_t entry; + + aos_mem_zero(&entry, sizeof (fal_fdb_rfs_t)); + + rv = __cmd_data_check_complex("mac addr", NULL, + "usage: the format is xx-xx-xx-xx-xx-xx \n", + cmd_data_check_macaddr, &(entry.addr), + sizeof (fal_mac_addr_t)); + if (rv) + { + return rv; + } + + rv = __cmd_data_check_complex("fid", NULL, + "usage: the format is xx\n", + cmd_data_check_uint32, &tmp, + sizeof (a_uint32_t)); + if (rv) + { + return rv; + } + + entry.fid = tmp; + + rv = __cmd_data_check_complex("loadbalance", "0", + "usage: the format is xx \n", + cmd_data_check_uint32, &tmp, + sizeof (a_uint32_t)); + if (rv) + { + return rv; + } + + entry.load_balance = tmp; + + *(fal_fdb_rfs_t *)val = entry; + return SW_OK; +} + + +sw_error_t +cmd_data_check_flow_cookie(char *cmd_str, void * val, a_uint32_t size) +{ + sw_error_t rv; + fal_flow_cookie_t entry; + + aos_mem_zero(&entry, sizeof (fal_flow_cookie_t)); + + rv = __cmd_data_check_complex("proto", "0", + "usage: the format is xx \n", + cmd_data_check_uint32, &(entry.proto), + sizeof (a_uint32_t)); + if (rv) + { + return rv; + } + + rv = __cmd_data_check_complex("src addr", NULL, + "usage: the format is xx.xx.xx.xx \n", + cmd_data_check_ip4addr, &(entry.src_addr), + 4); + if (rv) + { + return rv; + } + + rv = __cmd_data_check_complex("dst addr", NULL, + "usage: the format is xx.xx.xx.xx \n", + cmd_data_check_ip4addr, &(entry.dst_addr), + 4); + if (rv) + { + return rv; + } + + rv = __cmd_data_check_complex("src port", "0", + "usage: the format is xx \n", + cmd_data_check_uint32, &(entry.src_port), + sizeof (a_uint32_t)); + if (rv) + { + return rv; + } + + rv = __cmd_data_check_complex("dst port", "0", + "usage: the format is xx \n", + cmd_data_check_uint32, &(entry.dst_port), + sizeof (a_uint32_t)); + if (rv) + { + return rv; + } + + rv = __cmd_data_check_complex("flow cookie", "0", + "usage: the format is xx \n", + cmd_data_check_uint32, &(entry.flow_cookie), + sizeof (a_uint32_t)); + if (rv) + { + return rv; + } + + *(fal_flow_cookie_t *)val = entry; + return SW_OK; +} + +sw_error_t +cmd_data_check_flow_rfs(char *cmd_str, void * val, a_uint32_t size) +{ + a_uint32_t tmp; + sw_error_t rv; + fal_flow_rfs_t entry; + + aos_mem_zero(&entry, sizeof (fal_flow_cookie_t)); + + rv = __cmd_data_check_complex("proto", "0", + "usage: the format is xx \n", + cmd_data_check_uint32, &(entry.proto), + sizeof (a_uint32_t)); + if (rv) + { + return rv; + } + + rv = __cmd_data_check_complex("src addr", NULL, + "usage: the format is xx.xx.xx.xx \n", + cmd_data_check_ip4addr, &(entry.src_addr), + 4); + if (rv) + { + return rv; + } + + rv = __cmd_data_check_complex("dst addr", NULL, + "usage: the format is xx.xx.xx.xx \n", + cmd_data_check_ip4addr, &(entry.dst_addr), + 4); + if (rv) + { + return rv; + } + + rv = __cmd_data_check_complex("src port", "0", + "usage: the format is xx \n", + cmd_data_check_uint32, &(entry.src_port), + sizeof (a_uint32_t)); + if (rv) + { + return rv; + } + + rv = __cmd_data_check_complex("dst port", "0", + "usage: the format is xx \n", + cmd_data_check_uint32, &(entry.dst_port), + sizeof (a_uint32_t)); + if (rv) + { + return rv; + } + + rv = __cmd_data_check_complex("flow rfs", "0", + "usage: the format is xx \n", + cmd_data_check_uint32, &tmp, + sizeof (a_uint32_t)); + if (rv) + { + return rv; + } + + entry.load_balance = tmp; + + + *(fal_flow_rfs_t *)val = entry; + return SW_OK; +} + +sw_error_t +cmd_data_check_ip6_rfs_entry(char *cmd_str, void * val, a_uint32_t size) +{ + a_uint32_t tmp; + sw_error_t rv; + fal_ip6_rfs_t entry; + + aos_mem_zero(&entry, sizeof (fal_ip4_rfs_t)); + + rv = __cmd_data_check_complex("mac addr", NULL, + "usage: the format is xx-xx-xx-xx-xx-xx \n", + cmd_data_check_macaddr, &(entry.mac_addr), + sizeof (fal_mac_addr_t)); + if (rv) + { + return rv; + } + + rv = __cmd_data_check_complex("ip6 addr", NULL, + "usage: the format is xxxx::xxxx \n", + cmd_data_check_ip6addr, &(entry.ip6_addr), + 16); + if (rv) + { + return rv; + } + + rv = __cmd_data_check_complex("vid", "0", + "usage: the format is xx \n", + cmd_data_check_uint32, &(entry.vid), + sizeof (a_uint32_t)); + if (rv) + { + return rv; + } + + rv = __cmd_data_check_complex("loadbalance", "0", + "usage: the format is xx \n", + cmd_data_check_uint32, &tmp, + sizeof (a_uint32_t)); + if (rv) + { + return rv; + } + entry.load_balance = tmp; + + *(fal_ip6_rfs_t *)val = entry; + return SW_OK; +} + + +sw_error_t +cmd_data_check_newadr_lrn(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + fal_vsi_newaddr_lrn_t entry; + + aos_mem_zero(&entry, sizeof (fal_vsi_newaddr_lrn_t)); + + cmd_data_check_element("learnstatus_en", "enable", "usage: enable/disable\n", + cmd_data_check_enable, (cmd, &(entry.lrn_en), sizeof(entry.lrn_en))); + + cmd_data_check_element("learnaction", "forward", "usage: forward/drop/cpycpu/rdtcpu\n", + cmd_data_check_maccmd, (cmd, &(entry.action), sizeof(entry.action))); + + *(fal_vsi_newaddr_lrn_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_newaddr_lrn_entry(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_vsi_newaddr_lrn_t *entry; + + entry = (fal_vsi_newaddr_lrn_t *) buf; + cmd_data_print_enable("learnstatus_en", &entry->lrn_en, sizeof(entry->lrn_en)); + dprintf("\n"); + cmd_data_print_maccmd("learnaction", &entry->action, sizeof(entry->action)); + + return; +} + +sw_error_t +cmd_data_check_stamove(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + fal_vsi_stamove_t entry; + + aos_mem_zero(&entry, sizeof (fal_vsi_stamove_t)); + + cmd_data_check_element("stationmove_en", "enable", "usage: enable/disable\n", + cmd_data_check_enable, (cmd, &(entry.stamove_en), sizeof(entry.stamove_en))); + + cmd_data_check_element("stationmove_action", "forward", "usage: forward/drop/cpycpu/rdtcpu\n", + cmd_data_check_maccmd, (cmd, &(entry.action), sizeof(entry.action))); + + *(fal_vsi_stamove_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_stamove_entry(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_vsi_stamove_t *entry; + + entry = (fal_vsi_stamove_t *) buf; + cmd_data_print_enable("stationmove_en", &entry->stamove_en, sizeof(entry->stamove_en)); + dprintf("\n"); + cmd_data_print_maccmd("stationmove_action", &entry->action, sizeof(entry->action)); + + return; +} + +sw_error_t +cmd_data_check_vsi_member(char *cmd_str, void * val, a_uint32_t size) +{ + sw_error_t rv; + fal_vsi_member_t entry; + + aos_mem_zero(&entry, sizeof (fal_vsi_member_t)); + + rv = __cmd_data_check_complex("membership", 0, + "usage: Bit0-port0 Bit1-port1 ....\n", + cmd_data_check_pbmp, &(entry.member_ports), + sizeof (a_uint32_t)); + if (rv) + return rv; + + rv = __cmd_data_check_complex("unknown_unicast_membership", 0, + "usage: Bit0-port0 Bit1-port1 ....\n", + cmd_data_check_pbmp, &(entry.uuc_ports), + sizeof (a_uint32_t)); + if (rv) + return rv; + + rv = __cmd_data_check_complex("unknown_multicast_membership", 0, + "usage: Bit0-port0 Bit1-port1 ....\n", + cmd_data_check_pbmp, &(entry.umc_ports), + sizeof (a_uint32_t)); + if (rv) + return rv; + + rv = __cmd_data_check_complex("broadcast_membership", 0, + "usage: Bit0-port0 Bit1-port1 ....\n", + cmd_data_check_pbmp, &(entry.bc_ports), + sizeof (a_uint32_t)); + if (rv) + return rv; + + *(fal_vsi_member_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_vsi_member_entry(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_vsi_member_t *entry; + + entry = (fal_vsi_member_t *) buf; + dprintf("\n"); + dprintf("[membership]:0x%x\n", entry->member_ports); + dprintf("[unknown_unicast_membership]:0x%x\n", entry->uuc_ports); + dprintf("[unknown_multicast_membership]:0x%x\n", entry->umc_ports); + dprintf("[broadcast_membership]:0x%x\n", entry->bc_ports); + return; +} + +void +cmd_data_print_vsi_counter(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_vsi_counter_t *entry; + + entry = (fal_vsi_counter_t *) buf; + dprintf("\n"); + dprintf("[rx_bytes]:%lld\n", entry->rx_byte_counter); + dprintf("[rx_packets]:%d\n", entry->rx_packet_counter); + dprintf("[tx_bytes]:%lld\n", entry->tx_byte_counter); + dprintf("[tx_packets]:%d\n", entry->tx_packet_counter); + dprintf("[fwd_bytes]:%lld\n", entry->fwd_byte_counter); + dprintf("[fwd_packets]:%d\n", entry->fwd_packet_counter); + dprintf("[drop_bytes]:%lld\n", entry->drop_byte_counter); + dprintf("[drop_packets]:%d\n", entry->drop_packet_counter); + + return; +} + +sw_error_t +cmd_data_check_intf(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + a_uint32_t tmp; + sw_error_t rv; + fal_intf_entry_t entry; + + aos_mem_zero(&entry, sizeof (fal_intf_entry_t)); + + do + { + cmd = get_sub_cmd("mru", "0x5dc"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: mru \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: mru \n"); + } + else + { + entry.mru = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("mtu", "0x5dc"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: mtu \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: mtu \n"); + } + else + { + entry.mtu = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ttl_dec_bypass_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.ttl_dec_bypass_en), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ipv4_uc_route_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &(entry.ipv4_uc_route_en), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ipv6_uc_route_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &(entry.ipv6_uc_route_en), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("icmp_trigger_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.icmp_trigger_en), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ttl_exceed_action", "forward"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_maccmd(cmd, &(entry.ttl_exceed_action), + sizeof (fal_fwd_cmd_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ttl_exceed_deacclr_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.ttl_exceed_deacclr_en), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("mac_addr_bitmap", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: mac bitmap \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: mac bitmap \n"); + } + else + { + entry.mac_addr_bitmap = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + cmd_data_check_element("mac_addr", NULL, + "usage: the format is xx-xx-xx-xx-xx-xx \n", + cmd_data_check_macaddr, (cmd, &(entry.mac_addr), + sizeof (fal_mac_addr_t))); + + *(fal_intf_entry_t *)val = entry; + return SW_OK; +} + +sw_error_t +cmd_data_check_flow_age(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + a_uint32_t tmp; + sw_error_t rv; + fal_flow_age_timer_t entry; + + aos_mem_zero(&entry, sizeof (fal_flow_age_timer_t)); + + do + { + cmd = get_sub_cmd("age_time", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: age time \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: age time \n"); + } + else + { + entry.age_time = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("age_unit", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: age unit \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: age unit \n"); + } + else + { + entry.unit = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + *(fal_flow_age_timer_t *)val = entry; + return SW_OK; +} + + +sw_error_t +cmd_data_check_ac_dynamic_thresh(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + a_uint32_t tmp; + sw_error_t rv; + fal_ac_dynamic_threshold_t entry; + + aos_mem_zero(&entry, sizeof (fal_ac_dynamic_threshold_t)); + + do + { + cmd = get_sub_cmd("color_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.color_enable), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + + do + { + cmd = get_sub_cmd("wred_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.wred_enable), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("shared_weight", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: weight \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: weight\n"); + } + else + { + entry.shared_weight = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("green_min_off", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: green min offset \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: green min offset \n"); + } + else + { + entry.green_min_off = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("yel_max_off", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: yel max offset \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: green max offset \n"); + } + else + { + entry.yel_max_off = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("yel_min_off", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: yel min offset \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: green min offset \n"); + } + else + { + entry.yel_min_off = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("red_max_off", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: red max offset \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: red max offset \n"); + } + else + { + entry.red_max_off = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("red_min_off", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: red min offset \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: red min offset \n"); + } + else + { + entry.red_min_off = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("green_resume_off", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: green resume offset \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: green resume offset \n"); + } + else + { + entry.green_resume_off = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("yel_resume_off", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: yellow resume offset \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: yellow resume offset \n"); + } + else + { + entry.yel_resume_off = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("red_resume_off", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: red resume offset \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: red resume offset \n"); + } + else + { + entry.red_resume_off = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ceiling", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: shared ceiling \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: shared ceiling \n"); + } + else + { + entry.ceiling = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + *(fal_ac_dynamic_threshold_t *)val = entry; + return SW_OK; +} + +sw_error_t +cmd_data_check_ac_group_buff(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + a_uint32_t tmp; + sw_error_t rv; + fal_ac_group_buffer_t entry; + + do + { + cmd = get_sub_cmd("prealloc_buffer", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: prealloc buffer \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: prealloc buffer \n"); + } + else + { + entry.prealloc_buffer = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("total_buffer", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: total buffer \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: total buffer \n"); + } + else + { + entry.total_buffer = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + *(fal_ac_group_buffer_t *)val = entry; + return SW_OK; +} + +sw_error_t +cmd_data_check_ac_ctrl(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_ac_ctrl_t entry; + + do + { + cmd = get_sub_cmd("ac_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &(entry.ac_en), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ac_fc-en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &(entry.ac_fc_en), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + *(fal_ac_ctrl_t *)val = entry; + return SW_OK; +} + +sw_error_t +cmd_data_check_ac_obj(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_ac_obj_t entry; + + do + { + cmd = get_sub_cmd("obj_type", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0 for queue and 1 for group \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.type), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: 0 for queue and 1 for group \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("obj_id", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: obj id \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.obj_id), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: obj id \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + *(fal_ac_obj_t *)val = entry; + return SW_OK; +} + +sw_error_t +cmd_data_check_ac_static_thresh(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + a_uint32_t tmp; + sw_error_t rv; + fal_ac_static_threshold_t entry; + + aos_mem_zero(&entry, sizeof (fal_ac_static_threshold_t)); + + do + { + cmd = get_sub_cmd("color_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.color_enable), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + + do + { + cmd = get_sub_cmd("wred_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.wred_enable), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("green_max", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: green max \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: group id\n"); + } + else + { + entry.green_max = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("green_min_off", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: green min offset \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: green min offset \n"); + } + else + { + entry.green_min_off = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("yel_max_off", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: yel max offset \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: yel max offset \n"); + } + else + { + entry.yel_max_off = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("yel_min_off", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: yel min offset \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: yel min offset \n"); + } + else + { + entry.yel_min_off = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("red_max_off", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: red max offset \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: red max offset \n"); + } + else + { + entry.red_max_off = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("red_min_off", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: red min offset \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: red min offset \n"); + } + else + { + entry.red_min_off = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("green_resume_off", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: green resume offset \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: green resume offset \n"); + } + else + { + entry.green_resume_off = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("yel_resume_off", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: yellow resume offset \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: yellow resume offset \n"); + } + else + { + entry.yel_resume_off = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("red_resume_off", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: red resume offset \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: red resume offset \n"); + } + else + { + entry.red_resume_off = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + *(fal_ac_static_threshold_t *)val = entry; + return SW_OK; +} + + +sw_error_t +cmd_data_check_ip_global(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + a_uint32_t tmp; + sw_error_t rv; + fal_ip_global_cfg_t entry; + + aos_mem_zero(&entry, sizeof (fal_ip_global_cfg_t)); + + do + { + cmd = get_sub_cmd("mru_fail_action", "forward"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_maccmd(cmd, &(entry.mru_fail_action), + sizeof (fal_fwd_cmd_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("mru_deacclr_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.mru_deacclr_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("mtu_fail_action", "forward"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_maccmd(cmd, &(entry.mtu_fail_action), + sizeof (fal_fwd_cmd_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("mtu_deacclr_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.mtu_deacclr_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("mtu_nonfrag_fail_action", "forward"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_maccmd(cmd, &(entry.mtu_nonfrag_fail_action), + sizeof (fal_fwd_cmd_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("mtu_nonfrag_deacclr", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.mtu_df_deacclr_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("prefix_bc_action", "forward"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_maccmd(cmd, &(entry.prefix_bc_action), + sizeof (fal_fwd_cmd_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("prefix_bc_deacclr", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.prefix_deacclr_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("icmp_rdt_action", "forward"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_maccmd(cmd, &(entry.icmp_rdt_action), + sizeof (fal_fwd_cmd_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("icmp_rdt_deacclr_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.icmp_rdt_deacclr_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("hash_mode_0", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: hash mode\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: hash mode\n"); + } + else + { + entry.hash_mode_0 = tmp; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("hash_mode_1", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: hash mode\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: hash mode\n"); + else + entry.hash_mode_1 = tmp; + } + + } + while (talk_mode && (SW_OK != rv)); + + *(fal_ip_global_cfg_t *)val = entry; + return SW_OK; + +} + +void +cmd_data_print_ip_global(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_ip_global_cfg_t *entry; + + entry = (fal_ip_global_cfg_t *) buf; + + dprintf("\n[mru_fail_action]:0x%x [mru_deacclr_en]:0x%x [mtu_fail_action]:0x%x [mtu_deacclr_en]:0x%x [mtu_nonfrag_fail_action]:0x%x ", + entry->mru_fail_action, entry->mru_deacclr_en, entry->mtu_fail_action, entry->mtu_deacclr_en, entry->mtu_nonfrag_fail_action); + dprintf("\n[mtu_df_deacclr_en]:0x%x [prefix_bc_action]:0x%x [prefix_bc_deacclr_en]:0x%x [icmp_rdt_action]:0x%x [icmp_rdt_deacclr]:0x%x ", + entry->mtu_df_deacclr_en, entry->prefix_bc_action, entry->prefix_deacclr_en, entry->icmp_rdt_action, entry->icmp_rdt_deacclr_en); + dprintf("\n[hash_mode_0]:0x%x [hash_mode_1]:0x%x ", + entry->hash_mode_0, entry->hash_mode_1); + +} + +sw_error_t +cmd_data_check_l3_parser(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + a_uint32_t tmp; + sw_error_t rv; + fal_l3_excep_parser_ctrl entry; + + aos_mem_zero(&entry, sizeof (fal_l3_excep_parser_ctrl)); + + do + { + cmd = get_sub_cmd("small_ip4ttl", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: small ttl value\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: small ttl value\n"); + else + entry.small_ip4ttl = tmp; + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("small_ip6hoplimit", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: small hop limit value\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: small hop limit value\n"); + else + entry.small_ip6hoplimit = tmp; + } + + } + while (talk_mode && (SW_OK != rv)); + + *(fal_l3_excep_parser_ctrl *)val = entry; + return SW_OK; + +} + +void +cmd_data_print_l3_parser(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_l3_excep_parser_ctrl *entry; + + entry = (fal_l3_excep_parser_ctrl *) buf; + + dprintf("\n[small_ip4ttl]:0x%x [small_ip6hoplimit]:0x%x ", + entry->small_ip4ttl, entry->small_ip6hoplimit); +} + +sw_error_t +cmd_data_check_l4_parser(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + a_uint32_t tmp; + sw_error_t rv; + fal_l4_excep_parser_ctrl entry; + + aos_mem_zero(&entry, sizeof (fal_l4_excep_parser_ctrl)); + + do + { + cmd = get_sub_cmd("tcp_flags0", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: tcp flags value\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (tmp)); + if (SW_OK != rv) + dprintf("usage: tcp flags value\n"); + entry.tcp_flags[0] = tmp; + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("tcp_flags_mask0", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: tcp flags mask value\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (tmp)); + if (SW_OK != rv) + dprintf("usage: tcp flags maskvalue\n"); + entry.tcp_flags_mask[0] = tmp; + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("tcp_flags1", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: tcp flags value\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (tmp)); + if (SW_OK != rv) + dprintf("usage: tcp flags value\n"); + entry.tcp_flags[1] = tmp; + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("tcp_flags_mask1", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: tcp flags mask value\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (tmp)); + if (SW_OK != rv) + dprintf("usage: tcp flags maskvalue\n"); + entry.tcp_flags_mask[1] = tmp; + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("tcp_flags2", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: tcp flags value\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (tmp)); + if (SW_OK != rv) + dprintf("usage: tcp flags value\n"); + entry.tcp_flags[2] = tmp; + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("tcp_flags_mask2", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: tcp flags mask value\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (tmp)); + if (SW_OK != rv) + dprintf("usage: tcp flags maskvalue\n"); + entry.tcp_flags_mask[2] = tmp; + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("tcp_flags3", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: tcp flags value\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (tmp)); + if (SW_OK != rv) + dprintf("usage: tcp flags value\n"); + entry.tcp_flags[3] = tmp; + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("tcp_flags_mask3", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: tcp flags mask value\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (tmp)); + if (SW_OK != rv) + dprintf("usage: tcp flags maskvalue\n"); + entry.tcp_flags_mask[3] = tmp; + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("tcp_flags4", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: tcp flags value\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (tmp)); + if (SW_OK != rv) + dprintf("usage: tcp flags value\n"); + entry.tcp_flags[4] = tmp; + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("tcp_flags_mask4", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: tcp flags mask value\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (tmp)); + if (SW_OK != rv) + dprintf("usage: tcp flags maskvalue\n"); + entry.tcp_flags_mask[4] = tmp; + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("tcp_flags5", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: tcp flags value\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (tmp)); + if (SW_OK != rv) + dprintf("usage: tcp flags value\n"); + entry.tcp_flags[5] = tmp; + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("tcp_flags_mask5", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: tcp flags mask value\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (tmp)); + if (SW_OK != rv) + dprintf("usage: tcp flags maskvalue\n"); + entry.tcp_flags_mask[5]= tmp; + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("tcp_flags6", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: tcp flags value\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (tmp)); + if (SW_OK != rv) + dprintf("usage: tcp flags value\n"); + entry.tcp_flags[6] = tmp; + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("tcp_flags_mask6", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: tcp flags mask value\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (tmp)); + if (SW_OK != rv) + dprintf("usage: tcp flags maskvalue\n"); + entry.tcp_flags_mask[6] = tmp; + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("tcp_flags7", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: tcp flags value\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (tmp)); + if (SW_OK != rv) + dprintf("usage: tcp flags value\n"); + entry.tcp_flags[7] = tmp; + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("tcp_flags_mask7", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: tcp flags mask value\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (tmp)); + if (SW_OK != rv) + dprintf("usage: tcp flags maskvalue\n"); + entry.tcp_flags_mask[7] = tmp; + } + + } + while (talk_mode && (SW_OK != rv)); + + + *(fal_l4_excep_parser_ctrl *)val = entry; + return SW_OK; + +} + +void +cmd_data_print_l4_parser(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_l4_excep_parser_ctrl *entry; + a_uint8_t i = 0; + + entry = (fal_l4_excep_parser_ctrl *) buf; + for (i = 0; i < 8; i++) + dprintf("\n[tcp_flags%d]:0x%x [tcp_flags_mask%d]:0x%x ", + i, entry->tcp_flags[i], i, entry->tcp_flags_mask[i]); +} + +sw_error_t +cmd_data_check_exp_ctrl(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_l3_excep_ctrl_t entry; + + aos_mem_zero(&entry, sizeof (fal_l3_excep_ctrl_t)); + + do + { + cmd = get_sub_cmd("excep_cmd", "forward"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_maccmd(cmd, &(entry.cmd), + sizeof (fal_fwd_cmd_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("deacclr_en", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0 for disable and 1 for enable\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &(entry.deacclr_en), + sizeof (a_uint8_t)); + if (SW_OK != rv) + dprintf("usage: 0 for disable and 1 for enable\n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("l3route_only_en", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0 for disable and 1 for enable\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &(entry.l3route_only_en), + sizeof (a_uint8_t)); + if (SW_OK != rv) + dprintf("usage: 0 for disable and 1 for enable\n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("l2fwd_onl_en", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0 for disable and 1 for enable\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &(entry.l2fwd_only_en), + sizeof (a_uint8_t)); + if (SW_OK != rv) + dprintf("usage: 0 for disable and 1 for enable\n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("l2flow_en", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0 for disable and 1 for enable\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &(entry.l2flow_en), + sizeof (a_uint8_t)); + if (SW_OK != rv) + dprintf("usage: 0 for disable and 1 for enable\n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("l3flow_en", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0 for disable and 1 for enable\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &(entry.l3flow_en), + sizeof (a_uint8_t)); + if (SW_OK != rv) + dprintf("usage: 0 for disable and 1 for enable\n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("multicast_en", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0 for disable and 1 for enable\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &(entry.multicast_en), + sizeof (a_uint8_t)); + if (SW_OK != rv) + dprintf("usage: 0 for disable and 1 for enable\n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + *(fal_l3_excep_ctrl_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_exp_ctrl(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_l3_excep_ctrl_t *entry; + + entry = (fal_l3_excep_ctrl_t *) buf; + + dprintf("\n[except_cmd]:0x%x [deacclr_en]:0x%x [l3route_only_en]:0x%x [l2fwd_only_en]:0x%x ", + entry->cmd, entry->deacclr_en, entry->l3route_only_en, entry->l2fwd_only_en); + dprintf("\n[l3flow_en]:0x%x [l2flow_en]:0x%x [multicast_en]:0x%x ", + entry->l3flow_en, entry->l2flow_en, entry->multicast_en); +} + +sw_error_t +cmd_data_check_port_group(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + a_uint32_t tmp; + sw_error_t rv; + fal_qos_group_t entry; + + aos_mem_zero(&entry, sizeof (fal_qos_group_t)); + + do + { + cmd = get_sub_cmd("pcp_group", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: group\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: group\n"); + } + else + { + entry.pcp_group = tmp; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("dscp_group", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: group\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: group\n"); + } + else + { + entry.dscp_group = tmp; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("flow_group", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: group\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: group\n"); + } + else + { + entry.flow_group = tmp; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + *(fal_qos_group_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_port_group(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_qos_group_t *entry; + + entry = (fal_qos_group_t *) buf; + + dprintf("\n[pcp_group]:0x%x [dscp_group]:0x%x [flow_group]:0x%x ", + entry->pcp_group, entry->dscp_group, entry->flow_group); +} + +sw_error_t +cmd_data_check_port_pri(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + a_uint32_t tmp; + sw_error_t rv; + fal_qos_pri_precedence_t entry; + + aos_mem_zero(&entry, sizeof (fal_qos_pri_precedence_t)); + + do + { + cmd = get_sub_cmd("pcp_pri_prece", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: priority\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: priority\n"); + } + else + { + entry.pcp_pri = tmp; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("dscp_pri_prece", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: priority\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: priority\n"); + } + else + { + entry.dscp_pri = tmp; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("preheader_pri_prece", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: priority\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: priority\n"); + } + else + { + entry.preheader_pri = tmp; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("flow_pri_prece", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: priority\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: priority\n"); + } + else + { + entry.flow_pri = tmp; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("acl_pri_prece", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: priority\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: priority\n"); + } + else + { + entry.acl_pri = tmp; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("post_acl_pri_prece", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: priority\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: priority\n"); + } + else + { + entry.post_acl_pri = tmp; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("pcp_pri_force", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.pcp_pri_force), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("dscp_pri_force", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.dscp_pri_force), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + *(fal_qos_pri_precedence_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_port_pri(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_qos_pri_precedence_t *entry; + + entry = (fal_qos_pri_precedence_t *) buf; + + dprintf("\n[pcp_pri_prece]:0x%x [dscp_pri_prece]:0x%x [preheader_pri_prece]:0x%x ", + entry->pcp_pri, entry->dscp_pri, entry->preheader_pri); + dprintf("\n[flow_pri_prece]:0x%x [acl_pri_prece]:0x%x [post_acl_pri_prece]:0x%x ", + entry->flow_pri, entry->acl_pri, entry->post_acl_pri); + dprintf("\n[pcp_pri_force]:0x%x [dscp_pri_force]:0x%x ", + entry->pcp_pri_force, entry->dscp_pri_force); +} + +sw_error_t +cmd_data_check_port_remark(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_qos_remark_enable_t entry; + + aos_mem_zero(&entry, sizeof (fal_qos_remark_enable_t)); + + do + { + cmd = get_sub_cmd("pcp_change_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.pcp_change_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("dei_change_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.dei_chage_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("dscp_change_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.dscp_change_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + *(fal_qos_remark_enable_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_port_remark(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_qos_remark_enable_t *entry; + + entry = (fal_qos_remark_enable_t *) buf; + + dprintf("\n[pcp_change_en]:0x%x [dei_chage_en]:0x%x [dscp_change_en]:0x%x ", + entry->pcp_change_en, entry->dei_chage_en, entry->dscp_change_en); +} + +sw_error_t +cmd_data_check_cosmap(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + a_uint32_t tmp; + sw_error_t rv; + fal_qos_cosmap_t entry; + + aos_mem_zero(&entry, sizeof (fal_qos_cosmap_t)); + + do + { + cmd = get_sub_cmd("internal_pcp", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: internal pcp\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: internal pcp\n"); + } + else + { + entry.internal_pcp = tmp; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("internal_dei", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: internal dei\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: internal dei\n"); + } + else + { + entry.internal_dei = tmp; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("internal_pri", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: internal pri\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: internal pri\n"); + } + else + { + entry.internal_pri = tmp; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("internal_dscp", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: internal dscp\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: internal dscp\n"); + } + else + { + entry.internal_dscp = tmp; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("internal_dp", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: internal dp\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: internal dp\n"); + } + else + { + entry.internal_dp = tmp; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("dscp_mask", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: dscp mask\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: dscp mask\n"); + } + else + { + entry.dscp_mask = tmp; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("dscp_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.dscp_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("pcp_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.pcp_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("dei_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.dei_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("pri_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.pri_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("dp_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.dp_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("qos_prec", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: dscp mask\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: qos prec\n"); + } + else + { + entry.qos_prec = tmp; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + *(fal_qos_cosmap_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_cosmap(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_qos_cosmap_t *entry; + + entry = (fal_qos_cosmap_t *) buf; + + dprintf("\n[internal_pcp]:0x%x [internal_dei]:0x%x [internal_pri]:0x%x ", + entry->internal_pcp, entry->internal_dei, entry->internal_pri); + dprintf("\n[internal_dscp]:0x%x [internal_dp]:0x%x [dscp_mask]:0x%x ", + entry->internal_dscp, entry->internal_dp, entry->dscp_mask); + dprintf("\n[dscp_en]:0x%x [pcp_en]:0x%x [dei_en]:0x%x ", + entry->dscp_en, entry->pcp_en, entry->dei_en); + dprintf("\n[pri_en]:0x%x [dp_en]:0x%x [qos_prec]:0x%x ", + entry->pri_en, entry->dp_en, entry->qos_prec); +} + +void +cmd_data_print_port_scheduler_resource(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_portscheduler_resource_t *entry; + + entry = (fal_portscheduler_resource_t *) buf; + + dprintf("\n[ucastq_start]:0x%x [ucastq_num]:0x%x [mcastq_start]:0x%x [mcastq_num]:0x%x ", + entry->ucastq_start, entry->ucastq_num, entry->mcastq_start, entry->mcastq_num); + dprintf("\n[l0sp_start]:0x%x [l0sp_num]:0x%x [l0cdrr_start]:0x%x [l0cdrr_num]:0x%x ", + entry->l0sp_start, entry->l0sp_num, entry->l0cdrr_start, entry->l0cdrr_num); + dprintf("\n[l0edrr_start]:0x%x [l0edrr_num]:0x%x [l1sp_start]:0x%x [l1sp_num]:0x%x ", + entry->l0edrr_start, entry->l0edrr_num, entry->l1sp_start, entry->l1sp_num); + dprintf("\n[l1cdrr_start]:0x%x [l1cdrr_num]:0x%x [l1edrr_start]:0x%x [l1edrr_num]:0x%x ", + entry->l1cdrr_start, entry->l1cdrr_num, entry->l1edrr_start, entry->l1edrr_num); +} + +sw_error_t +cmd_data_check_queue_scheduler(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + a_uint32_t tmp; + sw_error_t rv; + fal_qos_scheduler_cfg_t entry; + + aos_mem_zero(&entry, sizeof (fal_qos_scheduler_cfg_t)); + + do + { + cmd = get_sub_cmd("sp_id", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: sp id\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: spi id\n"); + } + else + { + entry.sp_id = tmp; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("e_pri", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: e pri\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: e pri\n"); + } + else + { + entry.e_pri = tmp; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("c_pri", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: c pri\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: c pri\n"); + } + else + { + entry.c_pri = tmp; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("c_drr_id", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: c drr id\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: c drr id\n"); + } + else + { + entry.c_drr_id = tmp; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("e_drr_id", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: e drr id\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: e drr id\n"); + } + else + { + entry.e_drr_id = tmp; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("e_drr_wt", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: e drr wt\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: e drr wt\n"); + } + else + { + entry.e_drr_wt = tmp; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("c_drr_wt", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: c drr wt\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: c drr wt\n"); + } + else + { + entry.c_drr_wt = tmp; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("c_drr_ut", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: c drr unit\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: c drr unit\n"); + } + else + { + entry.c_drr_unit = tmp; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("e_drr_ut", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: e drr unit\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: e drr unit\n"); + } + else + { + entry.e_drr_unit = tmp; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("drr_frame_mode", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: drr frame mode\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.drr_frame_mode), + sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: drr frame mode\n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + *(fal_qos_scheduler_cfg_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_queue_scheduler(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_qos_scheduler_cfg_t *entry; + + entry = (fal_qos_scheduler_cfg_t *) buf; + + dprintf("\n[sp_id]:0x%x [e_pri]:0x%x [c_pri]:0x%x [c_drr_id]:0x%x [e_drr_id]:0x%x ", + entry->sp_id, entry->e_pri, entry->c_pri, entry->c_drr_id, entry->e_drr_id); + dprintf("\n[e_drr_wt]:0x%x [c_drr_wt]:0x%x [c_drr_unit]:0x%x [e_drr_unit]:0x%x [drr_frame_mode]:0x%x ", + entry->e_drr_wt, entry->c_drr_wt, entry->c_drr_unit, entry->e_drr_unit, entry->drr_frame_mode); +} + +sw_error_t +cmd_data_check_bm_static_thresh(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + a_uint32_t tmp; + sw_error_t rv; + fal_bm_static_cfg_t entry; + + aos_mem_zero(&entry, sizeof (fal_bm_static_cfg_t)); + + do + { + cmd = get_sub_cmd("max_thresh", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: max thresh\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: max thresh\n"); + } + else + { + entry.max_thresh = tmp; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("resume_off", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: resume offset\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: resume offset\n"); + } + else + { + entry.resume_off = tmp; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + *(fal_bm_static_cfg_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_bm_static_thresh(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_bm_static_cfg_t *entry; + + entry = (fal_bm_static_cfg_t *) buf; + + dprintf("\n[max_thresh]:0x%x [resume_off]:0x%x ", + entry->max_thresh, entry->resume_off); +} + +void +cmd_data_print_queue_cnt(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_queue_stats_t *entry; + + entry = (fal_queue_stats_t *) buf; + + dprintf("\n[tx_packets]:0x%x [tx_bytes]:0x%llx [pending_buff_num]:0x%x ", + entry->tx_packets, entry->tx_bytes, entry->pending_buff_num); + dprintf("\n[green_probability_drop_packets]:0x%x ", entry->drop_packets[0]); + dprintf("\n[green_probability_drop_bytes]:0x%llx ", entry->drop_bytes[0]); + dprintf("\n[yellow_probability_drop_packets]:0x%x ", entry->drop_packets[1]); + dprintf("\n[yellow_probability_drop_bytes]:0x%llx ", entry->drop_bytes[1]); + dprintf("\n[red_probability_drop_packets]:0x%x ", entry->drop_packets[2]); + dprintf("\n[red_probability_drop_bytes]:0x%llx ", entry->drop_bytes[2]); + dprintf("\n[green_force_drop_packets]:0x%x ", entry->drop_packets[3]); + dprintf("\n[green_force_drop_bytes]:0x%llx ", entry->drop_bytes[3]); + dprintf("\n[yellow_force_drop_packets]:0x%x ", entry->drop_packets[4]); + dprintf("\n[yellow_force_drop_bytes]:0x%llx ", entry->drop_bytes[4]); + dprintf("\n[red_force_drop_packets]:0x%x ", entry->drop_packets[5]); + dprintf("\n[red_force_drop_bytes]:0x%llx ", entry->drop_bytes[5]); + +} + +void +cmd_data_print_bm_port_counter(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_bm_port_counter_t *entry; + + entry = (fal_bm_port_counter_t *) buf; + + dprintf("\n[drop_byte_counter]:0x%llx [drop_packet_counter]:0x%x [fc_drop_byte_counter]:0x%llx [fc_drop_packet_counter]:0x%x ", + entry->drop_byte_counter, entry->drop_packet_counter, entry->fc_drop_byte_counter, entry->fc_drop_packet_counter); + dprintf("\n[used_counter]:0x%x [react_counter]:0x%x ", + entry->used_counter, entry->react_counter); +} + +sw_error_t +cmd_data_check_bm_dynamic_thresh(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + a_uint32_t tmp; + sw_error_t rv; + fal_bm_dynamic_cfg_t entry; + + aos_mem_zero(&entry, sizeof (fal_bm_dynamic_cfg_t)); + + do + { + cmd = get_sub_cmd("weight", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: weight\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: weight\n"); + } + else + { + entry.weight = tmp; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("shared_ceiling", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: shared ceiling\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: shared ceiling\n"); + } + else + { + entry.shared_ceiling = tmp; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("resume_off", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: resume offset\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: resume offset\n"); + } + else + { + entry.resume_off = tmp; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("resume_min_thresh", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: resmue min thresh\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: resume min thresh\n"); + } + else + { + entry.resume_min_thresh = tmp; + } + } + + } + while (talk_mode && (SW_OK != rv)); + + *(fal_bm_dynamic_cfg_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_bm_dynamic_thresh(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_bm_dynamic_cfg_t *entry; + + entry = (fal_bm_dynamic_cfg_t *) buf; + + dprintf("\n[weight]:0x%x [shared_ceiling]:0x%x [resume_off]:0x%x [resume_min_thresh]:0x%x ", + entry->weight, entry->shared_ceiling, entry->resume_off, entry->resume_min_thresh); +} + +sw_error_t +cmd_data_check_ring_queue(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + a_uint32_t i = 0; + sw_error_t rv; + fal_queue_bmp_t entry; + + aos_mem_zero(&entry, sizeof (fal_queue_bmp_t)); + + do + { + cmd = get_sub_cmd("bmp", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: bmp\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.bmp[i]), + sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: bmp\n"); + } + + } + while ((talk_mode && (SW_OK != rv)) || (++i < 10)); + + *(fal_queue_bmp_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_ring_queue(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_queue_bmp_t *entry; + int i; + + entry = (fal_queue_bmp_t *) buf; + + for (i = 0; i < 10; i++) + + dprintf("\n[bmp%d]:0x%x ", i, entry->bmp[i]); + +} + +sw_error_t +cmd_data_check_flow_global(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + a_uint32_t tmp; + sw_error_t rv; + fal_flow_global_cfg_t entry; + + aos_mem_zero(&entry, sizeof (fal_flow_global_cfg_t)); + + do + { + cmd = get_sub_cmd("src_intf_check_action", "forward"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_maccmd(cmd, &(entry.src_if_check_action), + sizeof (fal_fwd_cmd_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("src_intf_deacclr_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.src_if_check_deacclr_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("service_loop_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.service_loop_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("servcie_loop_action", "forward"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_maccmd(cmd, &(entry.service_loop_action), + sizeof (fal_fwd_cmd_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("service_loop_deacclr_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.service_loop_deacclr_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("flow_deacclr_action", "forward"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_maccmd(cmd, &(entry.flow_deacclr_action), + sizeof (fal_fwd_cmd_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("sync_mismatch_action", "forward"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_maccmd(cmd, &(entry.sync_mismatch_action), + sizeof (fal_fwd_cmd_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("sync_mismatch_deacclr_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.sync_mismatch_deacclr_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("hash_mode)0", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: hash mode\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: hash mode\n"); + else + entry.hash_mode_0 = tmp; + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("hash_mode_1", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: hash mode\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, + sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: hash mode\n"); + else + entry.hash_mode_1 = tmp; + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("flow_mismatch_copy_escape_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.flow_mismatch_copy_escape_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + { + dprintf("usage: \n"); + } + } + + } + while (talk_mode && (SW_OK != rv)); + + *(fal_flow_global_cfg_t *)val = entry; + return SW_OK; + +} + +void +cmd_data_print_flow_global(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_flow_global_cfg_t *entry; + + entry = (fal_flow_global_cfg_t *) buf; + + dprintf("\n[src_intf_check_action]:0x%x [src_intf_check_deacclr_en]:0x%x " + "[service_loop_en]:0x%x [service_loop_action]:0x%x " + "[service_loop_deacclr_en]:0x%x ", + entry->src_if_check_action, entry->src_if_check_deacclr_en, + entry->service_loop_en, entry->service_loop_action, + entry->service_loop_deacclr_en); + dprintf("\n[flow_deacclr_action]:0x%x [sync_mismatch_action]:0x%x " + "[sync_mismatch_deacclr_en]:0x%x [hash_mode_0]:0x%x " + "[hash_mode_1]:0x%x [flow_mismatch_copy_escape_en]:0x%x", + entry->flow_deacclr_action, entry->sync_mismatch_action, + entry->sync_mismatch_deacclr_en, entry->hash_mode_0, + entry->hash_mode_1, entry->flow_mismatch_copy_escape_en); + +} + + +sw_error_t +cmd_data_check_flow(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + a_uint32_t tmp; + sw_error_t rv; + fal_flow_entry_t entry; + + aos_mem_zero(&entry, sizeof (fal_flow_entry_t)); + + do + { + cmd = get_sub_cmd("entry id", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: entry id \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.entry_id), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: entry id \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("entry type", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: entry type \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: entry type \n"); + } + else + { + entry.entry_type = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("host addr type", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: host addr type \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: host addr type \n"); + } + else + { + entry.host_addr_type = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("host addr index", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: host addr index \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: host addr index \n"); + } + else + { + entry.host_addr_index = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("protocol", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: protocol \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: protocol \n"); + } + else + { + entry.protocol = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("age", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: age \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: age \n"); + } + else + { + entry.age = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("src intf valid", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: src intf valid \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &(entry.src_intf_valid), sizeof (a_uint8_t)); + if (SW_OK != rv) + dprintf("usage: src intf valid \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("src intf index", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: src intf index \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: src intf index \n"); + } + else + { + entry.src_intf_index = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("fwd type", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: fwd type \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: fwd type \n"); + } + else + { + entry.fwd_type = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + + do + { + cmd = get_sub_cmd("snat nexthop", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: snat nexthop \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: snat nexthop \n"); + } + else + { + entry.snat_nexthop = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("snat srcport", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: snat srcport \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: snat srcport \n"); + } + else + { + entry.snat_srcport = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("dnat nexthop", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: dnat nexthop \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: dnat nexthop \n"); + } + else + { + entry.dnat_nexthop = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("dnat dstport", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: dnat dstport \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: dnat dstport \n"); + } + else + { + entry.dnat_dstport = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("route nexthop", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: route nexthop \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: route nexthop \n"); + } + else + { + entry.route_nexthop = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("port valid", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: port valid \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &(entry.port_valid), sizeof (a_uint8_t)); + if (SW_OK != rv) + dprintf("usage: port valid \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("route port", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: route port \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.route_port), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: route port \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("bridge port", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: bridge port \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.bridge_port), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: bridge port \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("deacclr", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &(entry.deacclr_en), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("copy tocpu", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &(entry.copy_tocpu_en), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("syn toggle", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: sync toggle \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: sync toggle \n"); + } + else + { + entry.syn_toggle = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("pri profile", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: pri profile \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: pri profile \n"); + } + else + { + entry.pri_profile = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("service code", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: service code \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: service code \n"); + } + else + { + entry.sevice_code = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ip type", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: ip type \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: ip type \n"); + } + else + { + entry.ip_type = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("src port", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: src port \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: src port \n"); + } + else + { + entry.src_port = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("dst port", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: dst port \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: dst port \n"); + } + else + { + entry.dst_port = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + if (entry.entry_type & FAL_FLOW_IP4_5TUPLE_ADDR || entry.entry_type & FAL_FLOW_IP4_3TUPLE_ADDR) { + cmd_data_check_element("ip addr", NULL, + "usage: the format is xx.xx.xx.xx \n", + cmd_data_check_ip4addr, (cmd, &(entry.flow_ip.ipv4), 4)); + + } else if (entry.entry_type & FAL_FLOW_IP6_5TUPLE_ADDR || entry.entry_type & + FAL_FLOW_IP6_3TUPLE_ADDR) { + cmd_data_check_element("ip addr", NULL, + "usage: the format is xxxx::xx.xx \n", + cmd_data_check_ip6addr, (cmd, &(entry.flow_ip.ipv6), 16)); + } + + do + { + cmd = get_sub_cmd("tree id", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: tree id \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.tree_id), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: tree id \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + *(fal_flow_entry_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_flow(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_flow_entry_t *entry; + + entry = (fal_flow_entry_t *) buf; + + dprintf("\n[entry_id]:0x%x [entry_type]:0x%x [host_addr_type]:0x%x [host_addr_index]:0x%x ", + entry->entry_id, entry->entry_type, entry->host_addr_type, entry->host_addr_index); + dprintf("\n[protocol]:0x%x [agetime]:0x%x [src_intf_valid]:0x%x [src_intf_index]:0x%x [fwd_type]:0x%x ", + entry->protocol, entry->age, entry->src_intf_valid, entry->src_intf_index, entry->fwd_type); + dprintf("\n[snat_nexthop]:0x%x [snat_srcport]:0x%x [dnat_nexthop]:0x%x [dnat_dstport]:0x%x [route_nexthop]:0x%x ", + entry->snat_nexthop, entry->snat_srcport, entry->dnat_nexthop, entry->dnat_dstport, entry->route_nexthop); + dprintf("\n[port_valid]:0x%x [route_port]:0x%x [bridge_port]:0x%x [de_acclr]:0x%x [copy_tocpu]:0x%x ", + entry->port_valid, entry->route_port, entry->bridge_port, entry->deacclr_en, entry->copy_tocpu_en); + dprintf("\n[syn_toggle]:0x%x [pri_profile]:0x%x [sevice_code]:0x%x [ip_type]:0x%x [src_port]:0x%x [dst_port]:0x%x [tree_id]:0x%x ", + entry->syn_toggle, entry->pri_profile, entry->sevice_code, entry->ip_type, entry->src_port, entry->dst_port, entry->tree_id); + if (entry->entry_type & FAL_FLOW_IP4_5TUPLE_ADDR || entry->entry_type & FAL_FLOW_IP4_3TUPLE_ADDR) { + cmd_data_print_ip4addr("\n[ip_addr]:", + (a_uint32_t *) & (entry->flow_ip.ipv4), + sizeof (fal_ip4_addr_t)); + } else { + cmd_data_print_ip6addr("\n[ip_addr]:", + (a_uint32_t *) & (entry->flow_ip.ipv6), + sizeof (fal_ip6_addr_t)); + } + dprintf("\n[pkt]:0x%x [byte]:0x%x ", entry->pkt_counter, entry->byte_counter); +} + + +void +cmd_data_print_ac_static_thresh(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_ac_static_threshold_t *entry; + + entry = (fal_ac_static_threshold_t *) buf; + + dprintf("\n[color_en]:0x%x [wred_en]:0x%x [green_max]:0x%x ", + entry->color_enable, entry->wred_enable, entry->green_max); + dprintf("\n[green_min_off]:0x%x [yel_max_off]:0x%x [yel_min_off]:0x%x [red_max_off]:0x%x [red_min_off]:0x%x ", + entry->green_min_off, entry->yel_max_off, entry->yel_min_off, entry->red_max_off, entry->red_min_off); + dprintf("\n[green_resume_off]:0x%x [yel_resume_off]:0x%x [red_resume_off]:0x%x ", + entry->green_resume_off, entry->yel_resume_off, entry->red_resume_off); +} + +void +cmd_data_print_ac_dynamic_thresh(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_ac_dynamic_threshold_t *entry; + + entry = (fal_ac_dynamic_threshold_t *) buf; + + dprintf("\n[color_en]:0x%x [wred_en]:0x%x [shared_weight]:0x%x ", + entry->color_enable, entry->wred_enable, entry->shared_weight); + dprintf("\n[green_min_off]:0x%x [yel_max_off]:0x%x [yel_min_off]:0x%x [red_max_off]:0x%x [red_min_off]:0x%x ", + entry->green_min_off, entry->yel_max_off, entry->yel_min_off, entry->red_max_off, entry->red_min_off); + dprintf("\n[green_resume_off]:0x%x [yel_resume_off]:0x%x [red_resume_off]:0x%x [ceiling]:0x%x ", + entry->green_resume_off, entry->yel_resume_off, entry->red_resume_off, entry->ceiling); +} + +void +cmd_data_print_ac_group_buff(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_ac_group_buffer_t *entry; + + entry = (fal_ac_group_buffer_t *) buf; + + dprintf("\n[prealloc_buffer]:0x%x [total_buffer]:0x%x ", + entry->prealloc_buffer, entry->total_buffer); +} + +void +cmd_data_print_ac_ctrl(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_ac_ctrl_t *entry; + + entry = (fal_ac_ctrl_t *) buf; + + dprintf("\n[ac_en]:0x%x [ac_fc_en]:0x%x ", + entry->ac_en, entry->ac_fc_en); +} + +void +cmd_data_print_ac_obj(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_ac_obj_t *entry; + + entry = (fal_ac_obj_t *) buf; + + dprintf("\n[obj_type]:0x%x [obj_id]:0x%x ", + entry->type, entry->obj_id); +} + +sw_error_t +cmd_data_check_flow_ctrl(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + a_uint32_t tmp; + sw_error_t rv; + fal_flow_mgmt_t entry; + + aos_mem_zero(&entry, sizeof (fal_flow_mgmt_t)); + + do + { + cmd = get_sub_cmd("miss_action", "forward"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_maccmd(cmd, &(entry.miss_action), + sizeof (fal_fwd_cmd_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("frag_bypass_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &(entry.frag_bypass_en), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("tcpspec_bypass_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &(entry.tcp_spec_bypass_en), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("all_bypass_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &(entry.all_bypass_en), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("key_sel", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: key sel \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: key sel \n"); + else + entry.key_sel = tmp; + } + } + while (talk_mode && (SW_OK != rv)); + + *(fal_flow_mgmt_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_flow_age(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_flow_age_timer_t *entry; + + entry = (fal_flow_age_timer_t *) buf; + + dprintf("\n[age_time]:0x%x [age_unit]:0x%x ", + entry->age_time, entry->unit); +} + +void +cmd_data_print_flow_ctrl(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_flow_mgmt_t *entry; + + entry = (fal_flow_mgmt_t *) buf; + + dprintf("\n[frag_bypass_en]:0x%x [tcp_spec_bypass_en]:0x%x [all_bypass_en]:0x%x " + "[key_sel]:0x%x [miss_action]:0x%x ", + entry->frag_bypass_en, entry->tcp_spec_bypass_en, + entry->all_bypass_en, entry->key_sel, entry->miss_action); +} + +sw_error_t +cmd_data_check_ip_mcmode(char *cmd_str, void * val, a_uint32_t size) +{ + a_char_t *cmd; + sw_error_t rv; + fal_mc_mode_cfg_t entry; + + aos_mem_zero(&entry, sizeof (fal_mc_mode_cfg_t)); + + do + { + cmd = get_sub_cmd("ipv4_mc_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &(entry.l2_ipv4_mc_en), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ipv4_igmpv3_mode", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: mc mode \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &(entry.l2_ipv4_mc_mode), sizeof (a_uint8_t)); + if (SW_OK != rv) + dprintf("usage: mc mode \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ipv6_mc_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &(entry.l2_ipv6_mc_en), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ipv6_mldv2_mode", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: mc mode \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &(entry.l2_ipv6_mc_mode), sizeof (a_uint8_t)); + if (SW_OK != rv) + dprintf("usage: mc mode \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + *(fal_mc_mode_cfg_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_ip_mcmode(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_mc_mode_cfg_t *entry; + + entry = (fal_mc_mode_cfg_t *) buf; + + dprintf("\n[ipv4_mc_en]:0x%x [ipv4_igmpv3_mode]:0x%x [ipv6_mc_en]:0x%x [ipv6_mldv2_mode]:0x%x ", + entry->l2_ipv4_mc_en, entry->l2_ipv4_mc_mode, + entry->l2_ipv6_mc_en, entry->l2_ipv6_mc_mode); +} + + +sw_error_t +cmd_data_check_ip_portmac(char *cmd_str, void * val, a_uint32_t size) +{ + a_char_t *cmd; + sw_error_t rv; + fal_macaddr_entry_t entry; + + aos_mem_zero(&entry, sizeof (fal_macaddr_entry_t)); + + do + { + cmd = get_sub_cmd("entry_valid", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 1 for invalid and 1 for valid \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &(entry.valid), sizeof (a_uint8_t)); + if (SW_OK != rv) + dprintf("usage: 1 for invalid and 1 for valid \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + cmd_data_check_element("mac_addr", NULL, + "usage: the format is xx-xx-xx-xx-xx-xx \n", + cmd_data_check_macaddr, (cmd, &(entry.mac_addr), + sizeof (fal_mac_addr_t))); + + *(fal_macaddr_entry_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_ip_portmac(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_macaddr_entry_t *entry; + + entry = (fal_macaddr_entry_t *) buf; + + dprintf("\n[entry_valid]:0x%x", entry->valid); + cmd_data_print_macaddr("\n[mac_addr]:", + (a_uint32_t *) & (entry->mac_addr), + sizeof (fal_mac_addr_t)); +} + +sw_error_t +cmd_data_check_ip_pub(char *cmd_str, void * val, a_uint32_t size) +{ + a_char_t *cmd; + fal_ip_pub_addr_t entry; + + aos_mem_zero(&entry, sizeof (fal_ip_pub_addr_t)); + + cmd_data_check_element("pub_ip_addr", NULL, + "usage: the format is xx.xx.xx.xx \n", + cmd_data_check_ip4addr, (cmd, &(entry.pub_ip_addr), 4)); + + *(fal_ip_pub_addr_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_ip_pub(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_ip_pub_addr_t *entry; + + entry = (fal_ip_pub_addr_t *) buf; + + cmd_data_print_ip4addr("\n[pub_ip_addr]:", + (a_uint32_t *) & (entry->pub_ip_addr), + sizeof (fal_ip4_addr_t)); +} + +sw_error_t +cmd_data_check_ip_sg(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_sg_cfg_t entry; + + aos_mem_zero(&entry, sizeof (fal_sg_cfg_t)); + + do + { + cmd = get_sub_cmd("ipv4_sg_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &(entry.ipv4_sg_en), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ipv4_sg_violation_action", "forward"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_maccmd(cmd, &(entry.ipv4_sg_vio_action), + sizeof (fal_fwd_cmd_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ipv4_sg_port_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &(entry.ipv4_sg_port_en), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ipv4_sg_svlan_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &(entry.ipv4_sg_svlan_en), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ipv4_sg_cvlan_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &(entry.ipv4_sg_cvlan_en), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ipv4_src_unk_action", "forward"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_maccmd(cmd, &(entry.ipv4_src_unk_action), + sizeof (fal_fwd_cmd_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ipv6_sg_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &(entry.ipv6_sg_en), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ipv6_sg_violation_action", "forward"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_maccmd(cmd, &(entry.ipv6_sg_vio_action), + sizeof (fal_fwd_cmd_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ipv6_sg_port_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &(entry.ipv6_sg_port_en), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ipv6_sg_svlan_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &(entry.ipv6_sg_svlan_en), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ipv6_sg_cvlan_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &(entry.ipv6_sg_cvlan_en), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ipv6_src_unk_action", "forward"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_maccmd(cmd, &(entry.ipv6_src_unk_action), + sizeof (fal_fwd_cmd_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + *(fal_sg_cfg_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_ip_sg(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_sg_cfg_t *entry; + + entry = (fal_sg_cfg_t *) buf; + + dprintf("\n[ipv4_sg_en]:0x%x [ipv4_sg_violation_action]:0x%x [ipv4_sg_port_en]:0x%x ", + entry->ipv4_sg_en, entry->ipv4_sg_vio_action, entry->ipv4_sg_port_en); + dprintf("\n[ipv4_sg_svlan_en]:0x%x [ipv4_sg_cvlan_en]:0x%x [ipv4_src_unk_action]:0x%x ", + entry->ipv4_sg_svlan_en, entry->ipv4_sg_cvlan_en, entry->ipv4_src_unk_action); + dprintf("\n[ipv6_sg_en]:0x%x [ipv6_sg_violation_action]:0x%x [ipv6_sg_port_en]:0x%x ", + entry->ipv6_sg_en, entry->ipv6_sg_vio_action, entry->ipv6_sg_port_en); + dprintf("\n[ipv6_sg_svlan_en]:0x%x [ipv6_sg_cvlan_en]:0x%x [ipv6_src_unk_action]:0x%x ", + entry->ipv6_sg_svlan_en, entry->ipv6_sg_cvlan_en, entry->ipv6_src_unk_action); +} + +sw_error_t +cmd_data_check_vsi_intf(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_intf_id_t entry; + + aos_mem_zero(&entry, sizeof (fal_intf_id_t)); + + do + { + cmd = get_sub_cmd("l3_if_valid", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0 for invalid and 1 for valid \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &(entry.l3_if_valid), sizeof (a_uint8_t)); + if (SW_OK != rv) + dprintf("usage: 0 for invalid and 1 for valid\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("l3_if_index", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: l3 if index \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.l3_if_index), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: l3 if index\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + *(fal_intf_id_t *)val = entry; + return SW_OK; +} + +sw_error_t +cmd_data_check_nexthop(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + a_uint32_t tmp; + sw_error_t rv; + fal_ip_nexthop_t entry; + + aos_mem_zero(&entry, sizeof (fal_ip_nexthop_t)); + + do + { + cmd = get_sub_cmd("type", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0 l3 and 1 for vp \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &(entry.type), sizeof (a_uint8_t)); + if (SW_OK != rv) + dprintf("usage: 0 for invalid and 1 for valid\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + if (entry.type == 0) { + do + { + cmd = get_sub_cmd("vsi", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: vsi \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: vsi\n"); + } + else + { + entry.vsi = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + } else { + do + { + cmd = get_sub_cmd("port", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: port \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &(entry.port), sizeof (a_uint8_t)); + if (SW_OK != rv) + dprintf("usage: port\n"); + } + } + while (talk_mode && (SW_OK != rv)); + } + + do + { + cmd = get_sub_cmd("if_index", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: post l3 if \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.if_index), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: post l3 if index\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ip_to_me_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.ip_to_me_en), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("pub_ip_index", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: pubip index \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: pubip index\n"); + } + else + { + entry.pub_ip_index = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("stag_fmt", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: stag fmt \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: stag fmt\n"); + } + else + { + entry.stag_fmt = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("svid", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: svid \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: svid\n"); + } + else + { + entry.svid = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ctag_fmt", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: ctag fmt \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: ctag fmt\n"); + } + else + { + entry.ctag_fmt = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cvid", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: cvid \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: cvid\n"); + } + else + { + entry.cvid = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + cmd_data_check_element("mac_addr", NULL, + "usage: the format is xx-xx-xx-xx-xx-xx \n", + cmd_data_check_macaddr, (cmd, &(entry.mac_addr), + sizeof (fal_mac_addr_t))); + + rv = __cmd_data_check_complex("dnat_ip", NULL, + "usage: the format is xx.xx.xx.xx \n", + cmd_data_check_ip4addr, &(entry.dnat_ip), + 4); + if (rv) + return rv; + + + *(fal_ip_nexthop_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_nexthop(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_ip_nexthop_t *entry; + + entry = (fal_ip_nexthop_t *) buf; + + dprintf("\n[type]:0x%x", + entry->type); + if (entry->type == 0) + dprintf(" [vsi]:0x%x", entry->vsi); + else + dprintf("[port]:0x%x", entry->port); + dprintf(" [if index]:0x%x", + entry->if_index); + + dprintf("\n[ip_to_me_en]:0x%x [pub_ip_index]:0x%x [stag_fmt]:0x%x", + entry->ip_to_me_en, entry->pub_ip_index, entry->stag_fmt); + dprintf("\n[svid]:0x%x [ctag_fmt]:0x%x [cvid]:0x%x", + entry->svid, entry->ctag_fmt, entry->cvid); + cmd_data_print_macaddr("\n[mac_addr]:", + (a_uint32_t *) & (entry->mac_addr), + sizeof (fal_mac_addr_t)); + cmd_data_print_ip4addr("\n[dnat_ip]:", + (a_uint32_t *) & (entry->dnat_ip), + sizeof (fal_ip4_addr_t)); +} + +void +cmd_data_print_vsi_intf(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_intf_id_t *entry; + + entry = (fal_intf_id_t *) buf; + + dprintf("\n[l3_if_valid]:0x%x [l3_if_index]:0x%x", + entry->l3_if_valid, entry->l3_if_index); +} + + +void +cmd_data_print_intf(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_intf_entry_t *entry; + + entry = (fal_intf_entry_t *) buf; + + dprintf("\n[mru]:0x%x [mtu]:0x%x [ttl_dec_bypass_en]:0x%x", + entry->mru, entry->mtu, entry->ttl_dec_bypass_en); + dprintf("\n[ipv4_route_en]:0x%x [ipv6_route_en]:0x%x [icmp_trigger_en]:0x%x", + entry->ipv4_uc_route_en, entry->ipv6_uc_route_en, entry->icmp_trigger_en); + dprintf("\n[ttl_exceed_action]:0x%x [ttl_exceed_de_acclr_en]:0x%x " + "[mac_addr_bitmap]:0x%x", + entry->ttl_exceed_action, entry->ttl_exceed_deacclr_en, + entry->mac_addr_bitmap); + cmd_data_print_macaddr("\n[mac_addr]:", + (a_uint32_t *) & (entry->mac_addr), + sizeof (fal_mac_addr_t)); + dprintf("\n[rx_pkt]:0x%x [rx_byte]:0x%x [rx_drop_pkt]:0x%x " + "[rx_drop_byte]:0x%x ", + entry->counter.rx_pkt_counter, entry->counter.rx_byte_counter, + entry->counter.rx_drop_pkt_counter, + entry->counter.rx_drop_byte_counter); + dprintf("\n[tx_pkt]:0x%x [tx_byte]:0x%x [tx_drop_pkt]:0x%x " + "[tx_drop_byte]:0x%x ", + entry->counter.tx_pkt_counter, entry->counter.tx_byte_counter, + entry->counter.tx_drop_pkt_counter, + entry->counter.tx_drop_byte_counter); +} + +sw_error_t +cmd_data_check_arp_sg(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_arp_sg_cfg_t entry; + + aos_mem_zero(&entry, sizeof (fal_arp_sg_cfg_t)); + + do + { + cmd = get_sub_cmd("arp_sg_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &(entry.ipv4_arp_sg_en), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("arp_sg_violation_action", "forward"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_maccmd(cmd, &(entry.ipv4_arp_sg_vio_action), + sizeof (fal_fwd_cmd_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("arp_sg_port_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &(entry.ipv4_arp_sg_port_en), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("arp_sg_svlan_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &(entry.ipv4_arp_sg_svlan_en), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("arp_sg_cvlan_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &(entry.ipv4_arp_sg_cvlan_en), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("arp_sg_unk_action", "forward"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_maccmd(cmd, &(entry.ipv4_arp_src_unk_action), + sizeof (fal_fwd_cmd_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("nd_sg_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &(entry.ip_nd_sg_en), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("nd_sg_violation_action", "forward"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_maccmd(cmd, &(entry.ip_nd_sg_vio_action), + sizeof (fal_fwd_cmd_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("nd_sg_port_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &(entry.ip_nd_sg_port_en), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("nd_sg_svlan_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &(entry.ip_nd_sg_svlan_en), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("nd_sg_cvlan_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &(entry.ip_nd_sg_cvlan_en), sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("nd_sg_unk_action", "forward"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_maccmd(cmd, &(entry.ip_nd_src_unk_action), + sizeof (fal_fwd_cmd_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + *(fal_arp_sg_cfg_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_arp_sg(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_arp_sg_cfg_t *entry; + + entry = (fal_arp_sg_cfg_t *) buf; + dprintf("\n[arp_sg_en]:0x%x [arp_sg_violation_action]:0x%x [arp_sg_port_en]:0x%x", + entry->ipv4_arp_sg_en, entry->ipv4_arp_sg_vio_action, entry->ipv4_arp_sg_port_en); + dprintf("\n[arp_sg_svlan_en]:0x%x [arp_sg_cvlan_en]:0x%x [arp_src_unk_action]:0x%x", + entry->ipv4_arp_sg_svlan_en, entry->ipv4_arp_sg_cvlan_en, entry->ipv4_arp_src_unk_action); + + dprintf("\n[nd_sg_en]:0x%x [nd_sg_violation_action]:0x%x [nd_sg_port_en]:0x%x", + entry->ip_nd_sg_en, entry->ip_nd_sg_vio_action, entry->ip_nd_sg_port_en); + dprintf("\n[nd_sg_svlan_en]:0x%x [nd_sg_cvlan_en]:0x%x [nd_src_unk_action]:0x%x", + entry->ip_nd_sg_svlan_en, entry->ip_nd_sg_cvlan_en, entry->ip_nd_src_unk_action); +} + +sw_error_t +cmd_data_check_network_route(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + a_uint32_t tmp; + sw_error_t rv; + fal_network_route_entry_t entry; + + aos_mem_zero(&entry, sizeof (fal_network_route_entry_t)); + + do + { + cmd = get_sub_cmd("type", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0 for ipv4 and 1 for ipv6 \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: 0 for ipv4 and 1 for ipv6 \n"); + } + else + { + entry.type = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + if (entry.type == 0) /*IPv4*/ + { + cmd_data_check_element("ip4 _addr", NULL, + "usage: the format is xx.xx.xx.xx \n", + cmd_data_check_ip4addr, (cmd, &(entry.route_addr.ip4_addr), 4)); + } + else if (entry.type == 1) /*IPv6*/ + { + cmd_data_check_element("ip6_addr", NULL, + "usage: the format is xxxx::xx.xx \n", + cmd_data_check_ip6addr, (cmd, &(entry.route_addr.ip6_addr), 16)); + } + else + { + return SW_BAD_VALUE; + } + + if (entry.type == 0) /*IPv4*/ + { + cmd_data_check_element("ip4_addr_mask", NULL, + "usage: the format is xx.xx.xx.xx \n", + cmd_data_check_ip4addr, (cmd, &(entry.route_addr_mask.ip4_addr_mask), 4)); + } + else if (entry.type == 1) /*IPv6*/ + { + cmd_data_check_element("ip6_addr_mask", NULL, + "usage: the format is xxxx::xxxx \n", + cmd_data_check_ip6addr, (cmd, &(entry.route_addr_mask.ip6_addr_mask), 16)); + } + else + { + return SW_BAD_VALUE; + } + + do + { + cmd = get_sub_cmd("action", "forward"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_maccmd(cmd, &(entry.action), + sizeof (fal_fwd_cmd_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("dst_info", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: Dst info \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.dst_info), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: dst info \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("lan_wan", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0 for lan and 1 for wan \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: 0 for lan and 1 for wan \n"); + } + else + { + entry.lan_wan = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + *(fal_network_route_entry_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_network_route(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_network_route_entry_t *entry; + + entry = (fal_network_route_entry_t *) buf; + dprintf("\n[type]:0x%x ", + entry->type); + + dprintf("\n[dst_info]:0x%x [lan_wan]:0x%x [action]:0x%x", + entry->dst_info, entry->lan_wan, entry->action); + + if (entry->type == 0) { + cmd_data_print_ip4addr("\n[ip4_addr]:", + (a_uint32_t *) & (entry->route_addr.ip4_addr), + sizeof (fal_ip4_addr_t)); + cmd_data_print_ip4addr("\n[ip4_addr_mask]:", + (a_uint32_t *) & (entry->route_addr_mask.ip4_addr_mask), + sizeof (fal_ip4_addr_t)); + } else { + cmd_data_print_ip6addr("\n[ip6_addr]:", + (a_uint32_t *) & (entry->route_addr.ip6_addr), + sizeof (fal_ip6_addr_t)); + cmd_data_print_ip6addr("\n[ip6_addr_mask]:", + (a_uint32_t *) & (entry->route_addr_mask.ip6_addr_mask), + sizeof (fal_ip6_addr_t)); + } +} + +sw_error_t +cmd_data_check_global_qinqmode(char *info, void *val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_global_qinq_mode_t *pEntry = (fal_global_qinq_mode_t *)val; + + memset(pEntry, 0, sizeof(fal_global_qinq_mode_t)); + + /* get mask */ + do + { + cmd = get_sub_cmd("mask", "0x0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(pEntry->mask), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* get ingress mode */ + do + { + cmd = get_sub_cmd("ingress_qinq_mode", "ctag"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_qinq_mode(cmd, &(pEntry->ingress_mode), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* get egress mode */ + do + { + cmd = get_sub_cmd("egress_qinq_mode", "ctag"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_qinq_mode(cmd, &(pEntry->egress_mode), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + }while (talk_mode && (SW_OK != rv)); + + return SW_OK; +} + +void +cmd_data_print_global_qinqmode(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_global_qinq_mode_t *entry; + + entry = (fal_global_qinq_mode_t *) buf; + dprintf("\n"); + dprintf("[mask]:%d\n", entry->mask); + + cmd_data_print_qinq_mode("ingress_qinq_mode", + (a_uint32_t *) & (entry->ingress_mode), + sizeof(a_uint32_t)); + + cmd_data_print_qinq_mode("egress_qinq_mode", + (a_uint32_t *) & (entry->egress_mode), + sizeof(a_uint32_t)); + +} + +sw_error_t +cmd_data_check_port_qinqmode(char *info, void *val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_port_qinq_role_t *pEntry = (fal_port_qinq_role_t *)val; + + memset(pEntry, 0, sizeof(fal_port_qinq_role_t)); + + /* get mask */ + do + { + cmd = get_sub_cmd("mask", "0x0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(pEntry->mask), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* get ingress mode */ + do + { + cmd = get_sub_cmd("ingress_qinq_role", "edge"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_qinq_role(cmd, &(pEntry->ingress_port_role), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* get egress mode */ + do + { + cmd = get_sub_cmd("egress_qinq_role", "edge"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_qinq_role(cmd, &(pEntry->egress_port_role), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + }while (talk_mode && (SW_OK != rv)); + + return SW_OK; +} + +void +cmd_data_print_port_qinqmode(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_port_qinq_role_t *entry; + + entry = (fal_port_qinq_role_t *) buf; + dprintf("\n"); + dprintf("[mask]:%d\n", entry->mask); + + cmd_data_print_qinq_role("ingress_qinq_role", + (a_uint32_t *) & (entry->ingress_port_role), + sizeof(a_uint32_t)); + + cmd_data_print_qinq_role("egress_qinq_role", + (a_uint32_t *) & (entry->egress_port_role), + sizeof(a_uint32_t)); + +} + +sw_error_t +cmd_data_check_tpid(char *info, void *val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_tpid_t *pEntry = (fal_tpid_t *)val; + a_uint32_t tmp = 0; + + memset(pEntry, 0, sizeof(fal_tpid_t)); + + /* get mask */ + do + { + cmd = get_sub_cmd("mask", "0x0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(pEntry->mask), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* get ctpid */ + do + { + cmd = get_sub_cmd("ctagtpid", "0x8100"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: <0x8100>\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: <0x8100>\n"); + + pEntry->ctpid = (a_uint16_t)tmp; + } + }while (talk_mode && (SW_OK != rv)); + + /* get stpid */ + do + { + cmd = get_sub_cmd("stagtpid", "0x88a8"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: <0x88a8>\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: <0x88a8>\n"); + + pEntry->stpid = (a_uint16_t)tmp; + } + }while (talk_mode && (SW_OK != rv)); + + return SW_OK; +} + +void +cmd_data_print_tpid(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_tpid_t *entry; + + entry = (fal_tpid_t *) buf; + dprintf("\n"); + dprintf("[mask]:%d\n", entry->mask); + dprintf("[ctagtpid]:0x%x\n", entry->ctpid); + dprintf("[stagtpid]:0x%x\n", entry->stpid); + +} + +sw_error_t +cmd_data_check_ingress_filter(char *info, void *val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_ingress_vlan_filter_t *pEntry = (fal_ingress_vlan_filter_t *)val; + + memset(pEntry, 0, sizeof(fal_ingress_vlan_filter_t)); + + /* get in vlan filter */ + do + { + cmd = get_sub_cmd("membership_filter_en", "disable"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_enable(cmd, &(pEntry->membership_filter), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* get tag filter */ + do + { + cmd = get_sub_cmd("tagged_filter_en", "disable"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_enable(cmd, &(pEntry->tagged_filter), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* get untag filter */ + do + { + cmd = get_sub_cmd("untagged_filter_en", "disable"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_enable(cmd, &(pEntry->untagged_filter), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* get priority tag filter */ + do + { + cmd = get_sub_cmd("priority_tagged_filter_en", "disable"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_enable(cmd, &(pEntry->priority_filter), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + }while (talk_mode && (SW_OK != rv)); + + return SW_OK; +} + +void +cmd_data_print_ingress_filter(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_ingress_vlan_filter_t *entry; + + entry = (fal_ingress_vlan_filter_t *) buf; + dprintf("\n"); + + cmd_data_print_enable("membership_filter_en", (a_uint32_t *) & (entry->membership_filter), 4); + dprintf("\n"); + cmd_data_print_enable("tagged_filter_en", (a_uint32_t *) & (entry->tagged_filter), 4); + dprintf("\n"); + cmd_data_print_enable("untagged_filter_en", (a_uint32_t *) & (entry->untagged_filter), 4); + dprintf("\n"); + cmd_data_print_enable("priority_tagged_filter_en", (a_uint32_t *) & + (entry->priority_filter), 4); + dprintf("\n"); + +} + +sw_error_t +cmd_data_check_port_default_vid_en(char *info, void *val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_port_default_vid_enable_t *pEntry = (fal_port_default_vid_enable_t *)val; + + memset(pEntry, 0, sizeof(fal_port_default_vid_enable_t)); + + do + { + cmd = get_sub_cmd("default_ctag_vid_en", "disable"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_enable(cmd, &(pEntry->default_cvid_en), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + }while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("default_stag_vid_en", "disable"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_enable(cmd, &(pEntry->default_svid_en), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + }while (talk_mode && (SW_OK != rv)); + + return SW_OK; +} + +void +cmd_data_print_port_default_vid_en(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_port_default_vid_enable_t *entry; + + entry = (fal_port_default_vid_enable_t *) buf; + dprintf("\n"); + + cmd_data_print_enable("default_ctag_vid_en", (a_uint32_t *) & (entry->default_cvid_en), 4); + dprintf("\n"); + cmd_data_print_enable("default_stag_vid_en", (a_uint32_t *) & (entry->default_svid_en), 4); + dprintf("\n"); + +} + +sw_error_t +cmd_data_check_port_vlan_tag(char *info, void *val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_port_vlan_tag_t *pEntry = (fal_port_vlan_tag_t *)val; + a_uint32_t tmp = 0; + + memset(pEntry, 0, sizeof(fal_port_vlan_tag_t)); + + /* get mask */ + do + { + cmd = get_sub_cmd("mask", "0x0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(pEntry->mask), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* get cvid */ + do + { + cmd = get_sub_cmd("default_ctag_vid", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: <0-4095>\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: <0-4095>\n"); + + pEntry->cvid = (a_uint16_t)tmp; + } + }while (talk_mode && (SW_OK != rv)); + + /* get svid */ + do + { + cmd = get_sub_cmd("default_stag_vid", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: <0-4095>\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: <0-4095>\n"); + + pEntry->svid = (a_uint16_t)tmp; + } + }while (talk_mode && (SW_OK != rv)); + + /* get cpri */ + do + { + cmd = get_sub_cmd("default_ctag_pri", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: <0-7>\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: <0-7>\n"); + + pEntry->cpri = (a_uint16_t)tmp; + } + }while (talk_mode && (SW_OK != rv)); + + /* get spri */ + do + { + cmd = get_sub_cmd("default_stag_pri", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: <0-7>\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: <0-7>\n"); + + pEntry->spri = (a_uint16_t)tmp; + } + }while (talk_mode && (SW_OK != rv)); + + /* get cdei */ + do + { + cmd = get_sub_cmd("default_ctag_dei", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: <0-1>\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: <0-1>\n"); + + pEntry->cdei = (a_uint16_t)tmp; + } + }while (talk_mode && (SW_OK != rv)); + + /* get sdei */ + do + { + cmd = get_sub_cmd("default_stag_dei", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: <0-1>\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: <0-1>\n"); + + pEntry->sdei = (a_uint16_t)tmp; + } + }while (talk_mode && (SW_OK != rv)); + + return SW_OK; +} + +void +cmd_data_print_port_vlan_tag(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_port_vlan_tag_t *entry; + + entry = (fal_port_vlan_tag_t *) buf; + dprintf("\n"); + + cmd_data_print_uint32("mask", (a_uint32_t *) & (entry->mask), 4); + dprintf("\n"); + cmd_data_print_uint16("default_ctag_vid", (a_uint32_t *) & (entry->cvid), 4); + dprintf("\n"); + cmd_data_print_uint16("default_stag_vid", (a_uint32_t *) & (entry->svid), 4); + dprintf("\n"); + cmd_data_print_uint16("default_ctag_pri", (a_uint32_t *) & (entry->cpri), 4); + dprintf("\n"); + cmd_data_print_uint16("default_stag_pri", (a_uint32_t *) & (entry->spri), 4); + dprintf("\n"); + cmd_data_print_uint16("default_ctag_dei", (a_uint32_t *) & (entry->cdei), 4); + dprintf("\n"); + cmd_data_print_uint16("default_stag_dei", (a_uint32_t *) & (entry->sdei), 4); + dprintf("\n"); + +} + +sw_error_t +cmd_data_check_port_vlan_direction(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + + if (!strcasecmp(cmd_str, "all")) + { + *arg_val = FAL_PORT_VLAN_ALL; + } + else if (!strcasecmp(cmd_str, "ingress")) + { + *arg_val = FAL_PORT_VLAN_INGRESS; + } + else if (!strcasecmp(cmd_str, "egress")) + { + *arg_val = FAL_PORT_VLAN_EGRESS; + } + else + { + //dprintf("input error \n"); + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_port_vlan_direction(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:", param_name); + if (*(a_uint32_t *) buf == FAL_PORT_VLAN_ALL) + { + dprintf("ALL"); + } + else if (*(a_uint32_t *) buf == FAL_PORT_VLAN_INGRESS) + { + dprintf("INGRESS"); + } + else if (*(a_uint32_t *) buf == FAL_PORT_VLAN_EGRESS) + { + dprintf("EGRESS"); + } + else + { + dprintf("UNKNOWN VALUE"); + } + +} + +sw_error_t +cmd_data_check_port_vlan_translation_adv_rule(char *info, fal_vlan_trans_adv_rule_t *val, a_uint32_t size) +{ + char *cmd = NULL; + a_uint32_t tmp; + sw_error_t rv; + fal_vlan_trans_adv_rule_t entry; + + memset(&entry, 0, sizeof (fal_vlan_trans_adv_rule_t)); + + do + { + cmd = get_sub_cmd("stagformat", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: bit 0 for untagged, bit 1 for priority tagged and bit 2 " + "for tagged\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: bit 0 for untagged, bit 1 for priority tagged and " + "bit 2 for tagged\n"); + } + else + { + entry.s_tagged = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("svid_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.s_vid_enable, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("svid", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 4095\n"); + rv = SW_BAD_VALUE; + + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.s_vid, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: the range is 0 -- 4095\n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("spcp_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.s_pcp_enable, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("spcp", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 7\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: the range is 0 -- 7\n"); + } + else + { + entry.s_pcp = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("sdei_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.s_dei_enable, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("sdei", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 1\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: the range is 0 -- 1\n"); + } + else + { + entry.s_dei = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ctagformat", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: bit 0 for untagged, bit 1 for priority tagged and " + "bit 2 for tagged\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: bit 0 for untagged, bit 1 for priority tagged " + "and bit 2 for tagged\n"); + } + else + { + entry.c_tagged = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cvid_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.c_vid_enable, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cvid", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 4095\n"); + rv = SW_BAD_VALUE; + + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.c_vid, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: the range is 0 -- 4095\n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cpcp_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.c_pcp_enable, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cpcp", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 7\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: the range is 0 -- 7\n"); + } + else + { + entry.c_pcp = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cdei_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.c_dei_enable, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cdei", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 1\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: the range is 0 -- 1\n"); + } + else + { + entry.c_dei = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("frame_type_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.frmtype_enable, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("frametype", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0 for ethernet, 1 for rfc1024, 2 for llc and 3 for ethernet or rfc1024\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.frmtype, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: 0 for ethernet, 1 for rfc1024, 2 for llc and 3 for ethernet or rfc1024\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("protocol_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.protocol_enable, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("protocol", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: for example:0x0800 \n"); + rv = SW_BAD_VALUE; + + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: for example:0x0800 \n"); + } + else + { + entry.protocol = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("vsivalid", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.vsi_valid, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("vsi_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.vsi_enable, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("vsi", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 31\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.vsi, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: the range is 0 -- 31\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + *val = entry; + return SW_OK; +} + +void +cmd_data_print_port_vlan_translation_adv_rule(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_vlan_trans_adv_rule_t *entry; + + entry = (fal_vlan_trans_adv_rule_t *) buf; + + dprintf("\n\n rule field: "); + dprintf("\n[port_bitmap]:0x%x", entry->port_bitmap); + dprintf("\n[stagformat]:0x%x", entry->s_tagged); + dprintf("\n[svid_en]:%s [svid]:%d", entry->s_vid_enable?"ENABLE":"DISABLE", entry->s_vid); + dprintf("\n[spcp_en]:%s [spcp]:%d", entry->s_pcp_enable?"ENABLE":"DISABLE", entry->s_pcp); + dprintf("\n[sdei_en]:%s [sdei]:%d", entry->s_dei_enable?"ENABLE":"DISABLE", entry->s_dei); + + dprintf("\n[ctagformat]:0x%x", entry->c_tagged); + dprintf("\n[cvid_en]:%s [cvid]:%d", entry->c_vid_enable?"ENABLE":"DISABLE", entry->c_vid); + dprintf("\n[cpcp_en]:%s [cpcp]:%d", entry->c_pcp_enable?"ENABLE":"DISABLE", entry->c_pcp); + dprintf("\n[cdei_en]:%s [cdei]:%d", entry->c_dei_enable?"ENABLE":"DISABLE", entry->c_dei); + + dprintf("\n[frame_type_en]:%s [frametype]:0x%x", entry->frmtype_enable?"ENABLE":"DISABLE", + entry->frmtype); + dprintf("\n[protocol_en]:%s [protocol]:0x%x", entry->protocol_enable?"ENABLE":"DISABLE", + entry->protocol); + + dprintf("\n[vsivalid]:%s [vsi_en]:%s [vsi]:%d\n\n", entry->vsi_valid?"ENABLE":"DISABLE", + entry->vsi_enable?"ENABLE":"DISABLE", entry->vsi); +} + +sw_error_t +cmd_data_check_port_vlan_translation_adv_action(char *info, + fal_vlan_trans_adv_action_t *val, a_uint32_t size) +{ + char *cmd = NULL; + a_uint32_t tmp; + sw_error_t rv; + fal_vlan_trans_adv_action_t entry; + + memset(&entry, 0, sizeof (fal_vlan_trans_adv_action_t)); + + do + { + cmd = get_sub_cmd("swap_svid_cvid", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.swap_svid_cvid, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("svid_translation_cmd", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0 for unchanged, 1 for add and replace and 2 for delete tag\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.svid_xlt_cmd, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: 0 for unchanged, 1 for add and replace and 2 for delete tag\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("svidtranslation", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 4095\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: the range is 0 -- 4095\n"); + } + else + { + entry.svid_xlt = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cvid_translation_cmd", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0 for unchanged, 1 for add and replace and 2 for delete tag\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.cvid_xlt_cmd, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: 0 for unchanged, 1 for add and replace and 2 for delete tag\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cvidtranslation", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 4095\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: the range is 0 -- 4095\n"); + } + else + { + entry.cvid_xlt = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("swap_spcp_cpcp", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.swap_spcp_cpcp, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("spcp_translation_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.spcp_xlt_enable, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("spcptranslation", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 7\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: the range is 0 -- 7\n"); + } + else + { + entry.spcp_xlt = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cpcp_translation_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.cpcp_xlt_enable, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cpcptranslation", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 7\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: the range is 0 -- 7\n"); + } + else + { + entry.cpcp_xlt = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("swap_sdei_cdei", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.swap_sdei_cdei, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("sdei_translation_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.sdei_xlt_enable, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("sdeitranslation", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 1\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: the range is 0 -- 1\n"); + } + else + { + entry.sdei_xlt = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cdei_translation_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.cdei_xlt_enable, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cdeitranslation", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 7\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: the range is 0 -- 7\n"); + } + else + { + entry.cdei_xlt = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("counter_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.counter_enable, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("counter_id", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 63\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: the range is 0 -- 53\n"); + } + else + { + entry.counter_id = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("vsi_translation_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.vsi_xlt_enable, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("vsitranslation", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the range is 0 -- 32\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: the range is 0 -- 32\n"); + } + else + { + entry.vsi_xlt = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + *val = entry; + return SW_OK; +} + +void +cmd_data_print_port_vlan_translation_adv_action(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_vlan_trans_adv_action_t *entry; + + entry = (fal_vlan_trans_adv_action_t *) buf; + + dprintf("\n\n action field: "); + dprintf("\n[swap_svid_cvid]:%s ", + entry->swap_svid_cvid?"ENABLE":"DISABLE"); + dprintf("\n[svid_translation_cmd]:%d [svidtranslation]:%d [cvid_translation_cmd]:%d [cvidtranslation]:%d ", + entry->svid_xlt_cmd, + entry->svid_xlt, + entry->cvid_xlt_cmd, + entry->cvid_xlt); + dprintf("\n[swap_spcp_cpcp]:%s ", + entry->swap_spcp_cpcp?"ENABLE":"DISABLE"); + dprintf("\n[spcp_translation_en]:%s [spcptranslation]:%d [cpcp_translation_en]:%s [cpcptranslation]:%d ", + entry->spcp_xlt_enable?"ENABLE":"DISABLE", + entry->spcp_xlt, + entry->cpcp_xlt_enable?"ENABLE":"DISABLE", + entry->cpcp_xlt); + dprintf("\n[swap_sdei_cdei]:%s", + entry->swap_sdei_cdei?"ENABLE":"DISABLE"); + dprintf("\n[sdei_translation_en]:%s [sdeitranslation]:%d [cdei_translation_en]:%s [cdeitranslation]:%d ", + entry->sdei_xlt_enable?"ENABLE":"DISABLE", + entry->sdei_xlt, + entry->cdei_xlt_enable?"ENABLE":"DISABLE", + entry->cdei_xlt); + dprintf("\n[counter_en]:%s [counter_id]:%d", + entry->counter_enable?"ENABLE":"DISABLE", + entry->counter_id); + dprintf("\n[vsi_translation_en]:%s [vsitranslation]:%d \n\n", + entry->vsi_xlt_enable?"ENABLE":"DISABLE", + entry->vsi_xlt); +} + +sw_error_t +cmd_data_check_debug_port_counter_status(char *info, fal_counter_en_t *val, a_uint32_t size) +{ + char *cmd = NULL; + sw_error_t rv; + fal_counter_en_t entry; + + memset(&entry, 0, sizeof (fal_counter_en_t)); + + do + { + cmd = get_sub_cmd("rx_counter_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.rx_counter_en, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("vp_uni_tx_counter_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.vp_uni_tx_counter_en, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("port_mc_tx_counter_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.port_mc_tx_counter_en, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("port_tx_counter_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.port_tx_counter_en, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + + } + while (talk_mode && (SW_OK != rv)); + + *val = entry; + return SW_OK; +} + +void +cmd_data_print_debug_port_counter_status(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_counter_en_t *entry; + + entry = (fal_counter_en_t*) buf; + + dprintf("rx_counter_en:%s\n", entry->rx_counter_en?"ENABLE":"DISABLE"); + dprintf("vp_uni_tx_counter_en:%s\n", entry->vp_uni_tx_counter_en?"ENABLE":"DISABLE"); + dprintf("port_mc_tx_counter_en:%s\n", entry->port_mc_tx_counter_en?"ENABLE":"DISABLE"); + dprintf("port_tx_counter_en:%s\n", entry->port_tx_counter_en?"ENABLE":"DISABLE"); +} + +void +cmd_data_print_port_vlan_counter(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_port_vlan_counter_t *entry; + + entry = (fal_port_vlan_counter_t *) buf; + + dprintf("rx_packet_counter:0x%x, rx_byte_counter:0x%llx\n", entry->rx_packet_counter, entry->rx_byte_counter); + dprintf("tx_packet_counter:0x%x, tx_byte_counter:0x%llx\n", entry->tx_packet_counter, entry->tx_byte_counter); +} + +sw_error_t +cmd_data_check_tag_propagation(char *info, void *val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_vlantag_propagation_t *pEntry = (fal_vlantag_propagation_t *)val; + + memset(pEntry, 0, sizeof(fal_vlantag_propagation_t)); + + /* get mask */ + do + { + cmd = get_sub_cmd("mask", "0x0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(pEntry->mask), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* get vid propagation */ + do + { + cmd = get_sub_cmd("vid_propagation_en", "disable"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_vlan_propagation(cmd, (a_uint32_t *) & (pEntry->vid_propagation), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* get pri propagation */ + do + { + cmd = get_sub_cmd("pri_propagation_en", "disable"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_vlan_propagation(cmd, (a_uint32_t *) & (pEntry->pri_propagation), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* get dei propagation */ + do + { + cmd = get_sub_cmd("dei_propagation_en", "disable"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_vlan_propagation(cmd, (a_uint32_t *) & (pEntry->dei_propagation), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + }while (talk_mode && (SW_OK != rv)); + + return SW_OK; +} + +void +cmd_data_print_tag_propagation(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_vlantag_propagation_t *entry; + + entry = (fal_vlantag_propagation_t *) buf; + dprintf("\n"); + + cmd_data_print_uint32("mask", (a_uint32_t *) & (entry->mask), 4); + dprintf("\n"); + cmd_data_print_vlan_propagation("vid_propagation_en", (a_uint32_t *) & + (entry->vid_propagation), 4); + dprintf("\n"); + cmd_data_print_vlan_propagation("pri_propagation_en", (a_uint32_t *) & + (entry->pri_propagation), 4); + dprintf("\n"); + cmd_data_print_vlan_propagation("dei_propagation_en", (a_uint32_t *) & + (entry->dei_propagation), 4); + dprintf("\n"); + +} + +sw_error_t +cmd_data_check_egress_mode(char *info, void *val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_vlantag_egress_mode_t *pEntry = (fal_vlantag_egress_mode_t *)val; + + memset(pEntry, 0, sizeof(fal_vlantag_egress_mode_t)); + + /* get mask */ + do + { + cmd = get_sub_cmd("mask", "0x0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(pEntry->mask), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* get ctag mode */ + do + { + cmd = get_sub_cmd("ctag_egress_vlan_mode", "unmodified"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_egmode(cmd, (a_uint32_t *) & (pEntry->ctag_mode), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* get stag mode */ + do + { + cmd = get_sub_cmd("stag_egress_vlan_mode", "unmodified"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_egmode(cmd, (a_uint32_t *) & (pEntry->stag_mode), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + }while (talk_mode && (SW_OK != rv)); + + return SW_OK; +} + +void +cmd_data_print_egress_mode(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_vlantag_egress_mode_t *entry; + + entry = (fal_vlantag_egress_mode_t *) buf; + dprintf("\n"); + + cmd_data_print_uint32("mask", (a_uint32_t *) & (entry->mask), 4); + dprintf("\n"); + cmd_data_print_egmode("ctag_egress_vlan_mode", (a_uint32_t *) & (entry->ctag_mode), 4); + dprintf("\n"); + cmd_data_print_egmode("stag_egress_vlan_mode", (a_uint32_t *) & (entry->stag_mode), 4); + dprintf("\n"); + +} + +sw_error_t +cmd_data_check_ctrlpkt_profile(char *info, void *val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_ctrlpkt_profile_t *pEntry = (fal_ctrlpkt_profile_t *)val; + a_uint32_t tmp = 0; + + memset(pEntry, 0, sizeof(fal_ctrlpkt_profile_t)); + + /* get port bitmap */ + do + { + cmd = get_sub_cmd("port_bitmap", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: toal 8 bits for 8 ports\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &tmp, sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: toal 8 bits for 8 ports\n"); + + pEntry->port_map = tmp; + } + }while (talk_mode && (SW_OK != rv)); + + /* get ethernet type profile */ + do + { + cmd = get_sub_cmd("ethtype_profile_bitmap", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: toal 4 bits for 4 ethernet types\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &tmp, sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: toal 4 bits for 4 ethernet types\n"); + + pEntry->ethtype_profile_bitmap = tmp; + } + }while (talk_mode && (SW_OK != rv)); + + /* get rfdb profile */ + do + { + cmd = get_sub_cmd("rfdb_profile_bitmap", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: toal 32 bits for 32 rfdbs\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &tmp, sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: toal 4 bits for 4 ethernet type\n"); + + pEntry->rfdb_profile_bitmap= tmp; + } + }while (talk_mode && (SW_OK != rv)); + + /* get mgt_eapol */ + do + { + cmd = get_sub_cmd("eapol_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(pEntry->protocol_types.mgt_eapol), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + /* get mgt_eapol */ + do + { + cmd = get_sub_cmd("pppoe_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(pEntry->protocol_types.mgt_pppoe), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + /* get mgt_igmp */ + do + { + cmd = get_sub_cmd("igmp_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(pEntry->protocol_types.mgt_igmp), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + /* get mgt_arp_req */ + do + { + cmd = get_sub_cmd("arp_request_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(pEntry->protocol_types.mgt_arp_req), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + /* get mgt_arp_rep */ + do + { + cmd = get_sub_cmd("arp_response_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(pEntry->protocol_types.mgt_arp_rep), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + /* get mgt_dhcp4 */ + do + { + cmd = get_sub_cmd("dhcp4_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(pEntry->protocol_types.mgt_dhcp4), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + /* get mgt_dhcp6 */ + do + { + cmd = get_sub_cmd("dhcp6_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(pEntry->protocol_types.mgt_dhcp6), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + /* get mgt_mld */ + do + { + cmd = get_sub_cmd("mld_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(pEntry->protocol_types.mgt_mld), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + + /* get mgt_ns */ + do + { + cmd = get_sub_cmd("ip6ns_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(pEntry->protocol_types.mgt_ns), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + /* get mgt_na */ + do + { + cmd = get_sub_cmd("ip6na_en", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(pEntry->protocol_types.mgt_na), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + /* get forward command */ + do + { + cmd = get_sub_cmd("ctrlpkt_profile_action", "forward"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: forward/drop/rdtcpu/cpycpu\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_maccmd(cmd, &(pEntry->action.action), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: forward/drop/rdtcpu/cpycpu\n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* get sg_byp */ + do + { + cmd = get_sub_cmd("sourceguard_bypass", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(pEntry->action.sg_bypass), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + /* get l2_filter_byp */ + do + { + cmd = get_sub_cmd("l2filter_bypass", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(pEntry->action.l2_filter_bypass), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + /* get in_stp_byp */ + do + { + cmd = get_sub_cmd("ingress_stp_bypass", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(pEntry->action.in_stp_bypass), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + /* get in_vlan_fltr_byp */ + do + { + cmd = get_sub_cmd("ingress_vlan_filter_bypass", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(pEntry->action.in_vlan_fltr_bypass), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + return SW_OK; +} + +void +cmd_data_print_ctrlpkt_profile(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_ctrlpkt_profile_t *entry; + + entry = (fal_ctrlpkt_profile_t *) buf; + dprintf("\n"); + + cmd_data_print_uint32("port_bitmap", (a_uint32_t *) & (entry->port_map), 4); + dprintf(" "); + cmd_data_print_uint32("ethtype_profile_bitmap", (a_uint32_t *) & + (entry->ethtype_profile_bitmap), 4); + dprintf(" "); + cmd_data_print_uint32("rfdb_profile_bitmap", (a_uint32_t *) & (entry->rfdb_profile_bitmap), + 4); + dprintf("\n"); + cmd_data_print_enable("eapol_en", (a_uint32_t *) & (entry->protocol_types.mgt_eapol), 4); + dprintf(" "); + cmd_data_print_enable("pppoe_en", (a_uint32_t *) & (entry->protocol_types.mgt_pppoe), 4); + dprintf(" "); + cmd_data_print_enable("igmp_en", (a_uint32_t *) & (entry->protocol_types.mgt_igmp), 4); + dprintf(" "); + cmd_data_print_enable("arp_request_en", (a_uint32_t *) & (entry->protocol_types.mgt_arp_req), + 4); + dprintf(" "); + cmd_data_print_enable("arp_response_en", (a_uint32_t *) & (entry->protocol_types.mgt_arp_rep), + 4); + dprintf("\n"); + cmd_data_print_enable("dhcp4_en", (a_uint32_t *) & (entry->protocol_types.mgt_dhcp4), 4); + dprintf(" "); + cmd_data_print_enable("dhcp6_en", (a_uint32_t *) & (entry->protocol_types.mgt_dhcp6), 4); + dprintf(" "); + cmd_data_print_enable("mld_en", (a_uint32_t *) & (entry->protocol_types.mgt_mld), 4); + dprintf(" "); + cmd_data_print_enable("ip6ns_en", (a_uint32_t *) & (entry->protocol_types.mgt_ns), 4); + dprintf(" "); + cmd_data_print_enable("ip6na_en", (a_uint32_t *) & (entry->protocol_types.mgt_na), 4); + dprintf("\n"); + cmd_data_print_maccmd("ctrlpkt_profile_action", (a_uint32_t *) & (entry->action.action), 4); + dprintf(" "); + cmd_data_print_enable("sourceguard_bypass", (a_uint32_t *) & (entry->action.sg_bypass), 4); + dprintf("\n"); + cmd_data_print_enable("l2filter_bypass", (a_uint32_t *) & (entry->action.l2_filter_bypass), + 4); + dprintf(" "); + cmd_data_print_enable("ingress_stp_bypass", (a_uint32_t *) & (entry->action.in_stp_bypass), + 4); + dprintf(" "); + cmd_data_print_enable("ingress_vlan_filter_bypass", (a_uint32_t *) & + (entry->action.in_vlan_fltr_bypass), 4); + dprintf("\n"); + +} + +sw_error_t +cmd_data_check_servcode_config(char *info, fal_servcode_config_t *val, a_uint32_t size) +{ + char *cmd = NULL; + sw_error_t rv; + fal_servcode_config_t entry; + + memset(&entry, 0, sizeof (fal_servcode_config_t)); + + do + { + cmd = get_sub_cmd("destport_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_TRUE, &entry.dest_port_valid, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("destport_id", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("physical port id: 0 - 7\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.dest_port_id, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("physical port id: 0 - 7\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("bypass_bitmap_0", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: refer to service spec\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.bypass_bitmap[0], + sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: refer to service spec\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("bypass_bitmap_1", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: refer to service spec\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.bypass_bitmap[1], + sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: refer to service spec\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("bypass_bitmap_2", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: refer to service spec\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.bypass_bitmap[2], + sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: refer to service spec\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("direction", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0:dest, 1:src \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.direction, + sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: 0:dest, 1:src \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("field_update_bitmap", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: refer to service spec\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.field_update_bitmap, + sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: refer to service spec\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("next_servicecode", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: refer to service spec\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.next_service_code, + sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: refer to service spec\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("hardwareservices", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: refer to service spec\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.hw_services, + sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: refer to service spec\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("offsetselection", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: refer to service spec\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.offset_sel, + sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: refer to service spec\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + *val = entry; + return SW_OK; +} + +void +cmd_data_print_servcode_config(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_servcode_config_t *entry; + + entry = (fal_servcode_config_t *) buf; + + dprintf("\ndestport_en:%s destport_id:%d\n", + entry->dest_port_valid? "ENABLE" : "DISABLE", + entry->dest_port_id); + dprintf("bypass_bitmap_0:0x%x bypass_bitmap_1:0x%x bypass_bitmap_2:0x%x\n", + entry->bypass_bitmap[0], entry->bypass_bitmap[1], entry->bypass_bitmap[2]); + dprintf("direction:%d\n", entry->direction); + dprintf("field_update_bitmap:0x%x next_servicecode:%d\n", + entry->field_update_bitmap, entry->next_service_code); + dprintf("hardwareservices:%d offsetselection:%d\n", + entry->hw_services, entry->offset_sel); +} + +sw_error_t +cmd_data_check_rss_hash_mode(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + + if (!strcasecmp(cmd_str, "ipv4v6")) + { + *arg_val = FAL_RSS_HASH_IPV4V6; + } + else if (!strcasecmp(cmd_str, "ipv4")) + { + *arg_val = FAL_RSS_HASH_IPV4ONLY; + } + else if (!strcasecmp(cmd_str, "ipv6")) + { + *arg_val = FAL_RSS_HASH_IPV6ONLY; + } + else + { + //dprintf("input error \n"); + return SW_BAD_VALUE; + } + + return SW_OK; +} + +sw_error_t +cmd_data_check_rss_hash_config(char *info, fal_rss_hash_config_t *val, a_uint32_t size) +{ + char *cmd = NULL; + a_uint32_t tmp; + sw_error_t rv; + fal_rss_hash_config_t entry; + + memset(&entry, 0, sizeof (fal_rss_hash_config_t)); + + do + { + cmd = get_sub_cmd("hash_mask", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("hash_mask: 0 - 0x1fffff\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.hash_mask, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("hash_mask: 0 - 0x1fffff\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("hash_fragment_mode", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &entry.hash_fragment_mode, + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("hash_seed", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("hash_mask: 0 - 0xffffffff\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.hash_seed, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("hash_mask: 0 - ffffffff\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("hash_sip_mix", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("hash_mask: 0 - 0xfffff\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.hash_sip_mix, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("hash_mask: 0 - 0xfffff\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("hash_dip_mix", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("hash_mask: 0 - 0xfffff\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.hash_dip_mix, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("hash_mask: 0 - 0xfffff\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("hash_protocol_mix", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("hash_mask: 0 - 0x1f\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("hash_mask: 0 - 0x1f\n"); + } + else + { + entry.hash_protocol_mix = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("hash_sport_mix", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("hash_mask: 0 - 0x1f\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("hash_mask: 0 - 0x1f\n"); + } + else + { + entry.hash_sport_mix = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("hash_dport_mix", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("hash_mask: 0 - 0x1f\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &tmp, sizeof (a_uint32_t)); + if (SW_OK != rv) + { + dprintf("hash_mask: 0 - 0x1f\n"); + } + else + { + entry.hash_dport_mix = tmp; + } + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("hash_fin_inner", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("hash_mask: 0 - 0x1ffffff\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.hash_fin_inner, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("hash_mask: 0 - 0x1ffffff\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("hash_fin_outer", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("hash_mask: 0 - 0x1ffffff\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &entry.hash_fin_outer, sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("hash_mask: 0 - 0x1ffffff\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + *val = entry; + return SW_OK; +} + +void +cmd_data_print_rss_hash_config(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_rss_hash_config_t *entry; + + entry = (fal_rss_hash_config_t *) buf; + + dprintf("\nhash_mask:0x%x hash_fragment_mode:%s\n", + entry->hash_mask, + entry->hash_fragment_mode? "ENABLE" : "DISABLE"); + dprintf("hash_seed:0x%x hash_sip_mix:0x%x\n", + entry->hash_seed, + entry->hash_sip_mix); + dprintf("hash_dip_mix:0x%x hash_protocol_mix:0x%x\n", + entry->hash_dip_mix, + entry->hash_protocol_mix); + dprintf("hash_sport_mix:0x%x hash_dport_mix:0x%x\n", + entry->hash_sport_mix, + entry->hash_dport_mix); + dprintf("hash_fin_inner:0x%x hash_fin_outer:0x%x\n", + entry->hash_fin_inner, + entry->hash_fin_outer); +} + +sw_error_t +cmd_data_check_flow_host(char *cmd_str, void * val, a_uint32_t size) +{ + fal_flow_host_entry_t *flow_host = (fal_flow_host_entry_t *)val; + fal_flow_entry_t *flow_entry = &(flow_host->flow_entry); + fal_host_entry_t *host_entry = &(flow_host->host_entry); + + cmd_data_check_flow(cmd_str, flow_entry, size); + cmd_data_check_host_entry(cmd_str, host_entry, size); + + return SW_OK; +} + +void +cmd_data_print_flow_host(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_flow_host_entry_t *flow_host = (fal_flow_host_entry_t *) buf; + fal_flow_entry_t *flow_entry = &(flow_host->flow_entry); + fal_host_entry_t *host_entry = &(flow_host->host_entry); + + cmd_data_print_flow(param_name, (a_uint32_t *)flow_entry, size); + cmd_data_print_host_entry(param_name, (a_uint32_t *)host_entry, size); +} + +sw_error_t +cmd_data_check_port_shaper_token_config(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_shaper_token_number_t entry; + + aos_mem_zero(&entry, sizeof (fal_shaper_token_number_t)); + + do + { + cmd = get_sub_cmd("ctoken_negative_enable", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.c_token_number_negative_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ctoken_number", "0-0x3FFFFFFF"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.c_token_number), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + *(fal_shaper_token_number_t *)val = entry; + return SW_OK; +} + + +sw_error_t +cmd_data_check_shaper_token_config(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_shaper_token_number_t entry; + + aos_mem_zero(&entry, sizeof (fal_shaper_token_number_t)); + + do + { + cmd = get_sub_cmd("ctoken_negative_enable", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.c_token_number_negative_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ctoken_number", "0-0x3FFFFFFF"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.c_token_number), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("etoken_negative_enable", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.e_token_number_negative_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + + do + { + cmd = get_sub_cmd("etoken_number", "0-0x3FFFFFFF"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.e_token_number), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + *(fal_shaper_token_number_t *)val = entry; + return SW_OK; +} + + +sw_error_t +cmd_data_check_port_shaper_config(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_shaper_config_t entry; + + aos_mem_zero(&entry, sizeof (fal_shaper_config_t)); + + do + { + cmd = get_sub_cmd("meter_unit", "0-1"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.meter_unit), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cshaper_enable", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.c_shaper_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cir", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.cir), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cbs", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.cbs), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("shaper_frame_mode", "0-2"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.shaper_frame_mode), sizeof (fal_shaper_frame_mode_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + *(fal_shaper_config_t *)val = entry; + return SW_OK; +} + + +sw_error_t +cmd_data_check_shaper_config(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_shaper_config_t entry; + + aos_mem_zero(&entry, sizeof (fal_shaper_config_t)); + + do + { + cmd = get_sub_cmd("couple_enable", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.couple_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("meter_unit", "0-1"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.meter_unit), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cshaper_enable", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.c_shaper_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cir", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.cir), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cbs", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.cbs), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("eshaper_enable", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.e_shaper_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("eir", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.eir), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ebs", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.ebs), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("shaper_frame_mode", "0-2"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.shaper_frame_mode), sizeof (fal_shaper_frame_mode_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + *(fal_shaper_config_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_shaper_token_config(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_shaper_token_number_t *entry; + entry = (fal_shaper_token_number_t *) buf; + + if (A_TRUE == entry->c_token_number_negative_en) + { + dprintf("\n[shaper_ctoken_negative_enable]:yes "); + } + else + { + dprintf("\n[shaper_ctoken_negative_enable]:no "); + } + dprintf("\n[shaper_ctoken_number]:0x%x", entry->c_token_number); + + if (A_TRUE == entry->e_token_number_negative_en) + { + dprintf("\n[shaper_etoken_negative_enable]:yes "); + } + else + { + dprintf("\n[shaper_etoken_negative_enable]:no "); + } + + dprintf("\n[shaper_etoken_number]:0x%x", entry->e_token_number); + + return; +} + +void +cmd_data_print_port_shaper_token_config(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_shaper_token_number_t *entry; + entry = (fal_shaper_token_number_t *) buf; + + if (A_TRUE == entry->c_token_number_negative_en) + { + dprintf("\n[shaper_ctoken_negative_enable]:yes "); + } + else + { + dprintf("\n[shaper_ctoken_negative_enable]:no "); + } + dprintf("\n[shaper_ctoken_number]:0x%x", entry->c_token_number); + + return; +} + +void +cmd_data_print_shaper_config(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_shaper_config_t *entry; + + entry = (fal_shaper_config_t *) buf; + + if (A_TRUE == entry->couple_en) + { + dprintf("\n[shaper_couple_enable]:yes "); + } + else + { + dprintf("\n[shaper_couple_enable]:no "); + } + + dprintf("\n[shaper_meter_unit]:0x%x", entry->meter_unit); + + if (A_TRUE == entry->c_shaper_en) + { + dprintf("\n[shaper_cshaper_enable]:yes "); + } + else + { + dprintf("\n[shaper_cshaper_enable]:no "); + } + + dprintf("\n[shaper_cir]:0x%x", entry->cir); + dprintf("\n[shaper_cbs]:0x%x", entry->cbs); + + if (A_TRUE == entry->e_shaper_en) + { + dprintf("\n[shaper_eshaper_enable]:yes "); + } + else + { + dprintf("\n[shaper_eshaper_enable]:no "); + } + + dprintf("\n[shaper_eir]:0x%x", entry->eir); + dprintf("\n[shaper_ebs]:0x%x", entry->ebs); + + dprintf("\n[shaper_frame_mode]:0x%x", entry->shaper_frame_mode); + + return; +} + +void +cmd_data_print_port_shaper_config(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_shaper_config_t *entry; + + entry = (fal_shaper_config_t *) buf; + + dprintf("\n[shaper_meter_unit]:0x%x", entry->meter_unit); + + if (A_TRUE == entry->c_shaper_en) + { + dprintf("\n[shaper_cshaper_enable]:yes "); + } + else + { + dprintf("\n[shaper_cshaper_enable]:no "); + } + + dprintf("\n[shaper_cir]:0x%x", entry->cir); + dprintf("\n[shaper_cbs]:0x%x", entry->cbs); + + dprintf("\n[shaper_frame_mode]:0x%x", entry->shaper_frame_mode); + + return; +} + +sw_error_t +cmd_data_check_port_policer_config(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_policer_config_t entry; + + aos_mem_zero(&entry, sizeof (fal_policer_config_t)); + + do + { + cmd = get_sub_cmd("meter_enable", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.meter_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("couple_enable", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.couple_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("color_mode", "0-1"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.color_mode), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("frame_type", "0-0x1f"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.frame_type), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("meter_mode", "0-1"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.meter_mode), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + + do + { + cmd = get_sub_cmd("meter_unit", "0-1"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.meter_unit), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cir", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.cir), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cbs", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.cbs), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("eir", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.eir), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ebs", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.ebs), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + *(fal_policer_config_t *)val = entry; + return SW_OK; +} + +sw_error_t +cmd_data_check_acl_policer_config(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_policer_config_t entry; + + aos_mem_zero(&entry, sizeof (fal_policer_config_t)); + + do + { + cmd = get_sub_cmd("meter_enable", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.meter_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("couple_enable", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.couple_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("color_mode", "0-1"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.color_mode), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("meter_mode", "0-1"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.meter_mode), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + + do + { + cmd = get_sub_cmd("meter_unit", "0-1"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.meter_unit), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cir", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.cir), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("cbs", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.cbs), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("eir", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.eir), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("ebs", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.ebs), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + *(fal_policer_config_t *)val = entry; + return SW_OK; +} + + +sw_error_t +cmd_data_check_policer_cmd_config(char *cmd_str, void * val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_policer_action_t entry; + + aos_mem_zero(&entry, sizeof (fal_policer_action_t)); + + do + { + cmd = get_sub_cmd("yellow_priority_remark", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.yellow_priority_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("yellow_drop_priority_remark", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.yellow_drop_priority_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + + do + { + cmd = get_sub_cmd("yellow_pcp_remark", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.yellow_pcp_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("yellow_dei_remark", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.yellow_dei_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("yellow_priority", "0-15"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.yellow_priority), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("yellow_drop_priority", "0-3"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.yellow_drop_priority), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("yellow_pcp", "0-7"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.yellow_pcp), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("yellow_dei", "0-1"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.yellow_dei), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("red_action", "drop"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: forward/drop\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_maccmd(cmd, &(entry.red_action), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: forward/drop\n"); + } + }while (talk_mode && (SW_OK != rv)); + + + do + { + cmd = get_sub_cmd("red_priority_remark", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.red_priority_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("red_drop_priority_remark", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.red_drop_priority_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("red_pcp_remark", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.red_pcp_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("red_dei_remark", "no"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.red_dei_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("red_priority", "0-15"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.red_priority), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("red_drop_priority", "0-3"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.red_drop_priority), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("red_pcp", "0-7"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.red_pcp), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("red_dei", "0-1"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: integer\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(entry.red_dei), sizeof (a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: integer\n"); + } + } + while (talk_mode && (SW_OK != rv)); + + *(fal_policer_action_t *)val = entry; + return SW_OK; +} + + +void +cmd_data_print_port_policer_config(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_policer_config_t *entry; + + entry = (fal_policer_config_t *) buf; + + if (A_TRUE == entry->meter_en) + { + dprintf("\n[meter_enable]:yes "); + } + else + { + dprintf("\n[meter_enable]:no "); + } + + if (A_TRUE == entry->couple_en) + { + dprintf("\n[couple_enable]:yes "); + } + else + { + dprintf("\n[coupler_enable]:no "); + } + + dprintf("\n[color_mode]:0x%x", entry->color_mode); + dprintf("\n[frame_type]:0x%x", entry->frame_type); + dprintf("\n[meter_mode]:0x%x", entry->meter_mode); + + if (FAL_BYTE_BASED == entry->meter_unit) + { + dprintf("\n[meter_unit]:byte_based "); + } + else + { + dprintf("\n[meter_unit]:frame_based "); + } + + dprintf("\n[cir]:0x%08x [cbs]:0x%08x ", entry->cir,entry->cbs); + dprintf("\n[eir]:0x%08x [ebs]:0x%08x ", entry->eir,entry->ebs); + + return; +} + + +void +cmd_data_print_policer_cmd_config(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_policer_action_t *entry; + + entry = (fal_policer_action_t *) buf; + + if (A_TRUE == entry->yellow_priority_en) + { + dprintf("\n[yellow_priority_remark]:yes "); + } + else + { + dprintf("\n[yellow_priority_remark]:no "); + } + + if (A_TRUE == entry->yellow_drop_priority_en) + { + dprintf("\n[yellow_drop_priority_remark]:yes "); + } + else + { + dprintf("\n[yellow_drop_priority_remark]:no "); + } + + if (A_TRUE == entry->yellow_pcp_en) + { + dprintf("\n[yellow_pcp_remark]:yes "); + } + else + { + dprintf("\n[yellow_pcp_remark]:no "); + } + + if (A_TRUE == entry->yellow_dei_en) + { + dprintf("\n[yellow_dei_remark]:yes "); + } + else + { + dprintf("\n[yellow_dei_remark]:no "); + } + + dprintf("\n[yellow_priority]:0x%x", entry->yellow_priority); + dprintf("\n[yellow_drop_priority]:0x%x", entry->yellow_drop_priority); + dprintf("\n[yellow_pcp]:0x%x", entry->yellow_pcp); + dprintf("\n[yellow_dei]:0x%x", entry->yellow_dei); + + if (FAL_MAC_DROP == entry->red_action) + { + dprintf("\n[red_action]:drop"); + } + else + { + dprintf("\n[red_action]:forward"); + } + + if (A_TRUE == entry->red_priority_en) + { + dprintf("\n[red_priority_remark]:yes "); + } + else + { + dprintf("\n[red_priority_remark]:no "); + } + + if (A_TRUE == entry->red_drop_priority_en) + { + dprintf("\n[red_drop_priority_remark]:yes "); + } + else + { + dprintf("\n[red_drop_priority_remark]:no "); + } + + if (A_TRUE == entry->red_pcp_en) + { + dprintf("\n[red_pcp_remark]:yes "); + } + else + { + dprintf("\n[red_pcp_remark]:no "); + } + + if (A_TRUE == entry->red_dei_en) + { + dprintf("\n[red_dei_remark]:yes "); + } + else + { + dprintf("\n[red_dei_remark]:no "); + } + + dprintf("\n[red_priority]:0x%x", entry->red_priority); + dprintf("\n[red_drop_priority]:0x%x", entry->red_drop_priority); + dprintf("\n[red_pcp]:0x%x", entry->red_pcp); + dprintf("\n[red_dei]:0x%x", entry->red_dei); + + return; +} + +void +cmd_data_print_acl_policer_config(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_policer_config_t *entry; + + entry = (fal_policer_config_t *) buf; + + if (A_TRUE == entry->meter_en) + { + dprintf("[meter_enable]:yes "); + } + else + { + dprintf("\n[meter_enable]:no "); + } + + if (A_TRUE == entry->couple_en) + { + dprintf("\n[couple_enable]:yes "); + } + else + { + dprintf("\n[coupler_enable]:no "); + } + + dprintf("\n[color_mode]:0x%x", entry->color_mode); + + dprintf("\n[meter_mode]:0x%x", entry->meter_mode); + + if (FAL_BYTE_BASED == entry->meter_unit) + { + dprintf("\n[meter_unit]:byte_based "); + } + else + { + dprintf("\n[meter_unit]:frame_based "); + } + + dprintf("\n[cir]:0x%08x [cbs]:0x%08x ", entry->cir,entry->cbs); + dprintf("\n[eir]:0x%08x [ebs]:0x%08x ", entry->eir,entry->ebs); + + return; +} + +void +cmd_data_print_policer_counter_infor(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_policer_counter_t *entry; + entry = (fal_policer_counter_t *) buf; + + dprintf("\n[green_packet_counter]:0x%x", entry->green_packet_counter); + dprintf("\n[green_byte_counter]:0x%llx", entry->green_byte_counter); + + dprintf("\n[yellow_packet_counter]:0x%x", entry->yellow_packet_counter); + dprintf("\n[yellow_byte_counter]:0x%llx", entry->yellow_byte_counter); + + dprintf("\n[red_packet_counter]:0x%x", entry->red_packet_counter); + dprintf("\n[red_byte_counter]:0x%llx", entry->red_byte_counter); + + return; +} + +void +cmd_data_print_policer_global_counter_infor(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_policer_global_counter_t *entry; + entry = (fal_policer_global_counter_t *) buf; + + dprintf("\n[policer_drop_packet_counter]:0x%x", entry->policer_drop_packet_counter); + dprintf("\n[policer_drop_byte_counter]:0x%llx", entry->policer_drop_byte_counter); + + dprintf("\n[policer_forward_packet_counter]:0x%x", entry->policer_forward_packet_counter); + dprintf("\n[policer_forward_byte_counter]:0x%llx", entry->policer_forward_byte_counter); + + dprintf("\n[policer_bypass_packet_counter]:0x%x", entry->policer_bypass_packet_counter); + dprintf("\n[policer_bypass_byte_counter]:0x%llx", entry->policer_bypass_byte_counter); + + return; +} + +sw_error_t +cmd_data_check_ptp_config(char *info, void *val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_ptp_config_t entry; + + aos_mem_zero(&entry, sizeof (fal_ptp_config_t)); + + /* ptp en */ + do + { + cmd = get_sub_cmd("ptp_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(entry.ptp_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + /* clock mode */ + do + { + cmd = get_sub_cmd("clock_mode", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0 for OC, 1 for BC, 2 for E2ETC and 3 for P2PTC\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &(entry.clock_mode), sizeof(a_uint8_t)); + if (SW_OK != rv) + dprintf("usage: 0 for OC, 1 for BC, 2 for E2ETC and 3 for P2PTC\n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* step mode */ + do + { + cmd = get_sub_cmd("step_mode", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0 for one step, 1 for two step and 2 for auto mode\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &(entry.step_mode), sizeof(a_uint8_t)); + if (SW_OK != rv) + dprintf("usage: 0 for one step, 1 for two step, 2 for auto mode\n"); + } + }while (talk_mode && (SW_OK != rv)); + + *(fal_ptp_config_t *)val = entry; + return SW_OK; +} + +void +cmd_data_print_ptp_config(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_ptp_config_t *entry; + + entry = (fal_ptp_config_t *) buf; + dprintf("[ptp_en]:%s\n", entry->ptp_en ? "YES" : "NO"); + dprintf("[clock_mode]:%d [step_mode]:%d\n", entry->clock_mode, entry->step_mode); + dprintf("\n"); + +} + +sw_error_t +cmd_data_check_ptp_reference_clock(char *info, void *val, a_uint32_t size) +{ + a_uint32_t *pValue = (a_uint32_t *)val; + + if (info == NULL) + return SW_BAD_PARAM; + + if (!strcasecmp(info, "local")) + { + *pValue = FAL_REF_CLOCK_LOCAL; + } + else if (!strcasecmp(info, "synce")) + { + *pValue = FAL_REF_CLOCK_SYNCE; + } + else if (!strcasecmp(info, "external")) + { + *pValue = FAL_REF_CLOCK_EXTERNAL; + } + else + { + //dprintf("input error \n"); + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_ptp_reference_clock(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + if (*(a_uint32_t *) buf == FAL_REF_CLOCK_LOCAL) + { + dprintf("local"); + } + else if (*(a_uint32_t *) buf == FAL_REF_CLOCK_SYNCE) + { + dprintf("synce"); + } + else if (*(a_uint32_t *) buf == FAL_REF_CLOCK_EXTERNAL) + { + dprintf("external"); + } + else + { + dprintf("UNKNOWN VALUE"); + } + +} + +sw_error_t +cmd_data_check_ptp_rx_timestamp_mode(char *info, void *val, a_uint32_t size) +{ + a_uint32_t *pValue = (a_uint32_t *)val; + + if (info == NULL) + return SW_BAD_PARAM; + + if (!strcasecmp(info, "mdio")) + { + *pValue = FAL_RX_TS_MDIO; + } + else if (!strcasecmp(info, "embed")) + { + *pValue = FAL_RX_TS_EMBED; + } + else + { + //dprintf("input error \n"); + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_ptp_rx_timestamp_mode(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + if (*(a_uint32_t *) buf == FAL_RX_TS_MDIO) + { + dprintf("mdio"); + } + else if (*(a_uint32_t *) buf == FAL_RX_TS_EMBED) + { + dprintf("embed"); + } + else + { + dprintf("UNKNOWN VALUE"); + } + +} + +sw_error_t +cmd_data_check_ptp_direction(char *info, void *val, a_uint32_t size) +{ + a_uint32_t *pValue = (a_uint32_t *)val; + + if (info == NULL) + return SW_BAD_PARAM; + + if (!strcasecmp(info, "rx")) + { + *pValue = FAL_RX_DIRECTION; + } + else if (!strcasecmp(info, "tx")) + { + *pValue = FAL_TX_DIRECTION; + } + else + { + //dprintf("input error \n"); + return SW_BAD_VALUE; + } + + return SW_OK; +} + +sw_error_t +cmd_data_check_ptp_pkt_info(char *info, void *val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_ptp_pkt_info_t *pEntry = (fal_ptp_pkt_info_t *)val; + + memset(pEntry, 0, sizeof(fal_ptp_pkt_info_t)); + + /* sequence id */ + do + { + cmd = get_sub_cmd("sequence_id", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: sequence id, 16bits \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(pEntry->sequence_id), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: sequence id, 16bits \n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* clock identify */ + do + { + cmd = get_sub_cmd("clock_identify", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: clock identify, 64bits\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint64(cmd, &(pEntry->clock_identify), + sizeof(a_uint64_t)); + if (SW_OK != rv) + dprintf("usage: clock identify, 64bits\n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* port number */ + do + { + cmd = get_sub_cmd("port_number", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: source port id, 16bits\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(pEntry->port_number), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: source port id, 16bits\n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* message type */ + do + { + cmd = get_sub_cmd("msg_type", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: message, 4bits\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(pEntry->msg_type), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: message type, 4bits\n"); + } + }while (talk_mode && (SW_OK != rv)); + + return SW_OK; +} + +void +cmd_data_print_ptp_pkt_info(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_ptp_pkt_info_t *entry; + + entry = (fal_ptp_pkt_info_t *) buf; + dprintf("[sequence_id]:%s\n", entry->sequence_id); + dprintf("[clock_identify]:0x%llx\n", entry->clock_identify); + dprintf("[port_number]:%d [msg_type]:%d\n", entry->port_number, entry->msg_type); + dprintf("\n"); + +} + +sw_error_t +cmd_data_check_ptp_time(char *info, void *val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_ptp_time_t *pEntry = (fal_ptp_time_t *)val; + + memset(pEntry, 0, sizeof(fal_ptp_time_t)); + + /* seconds */ + do + { + cmd = get_sub_cmd("seconds", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: seconds 48bits \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint64(cmd, (a_uint64_t *) (&(pEntry->seconds)), + sizeof(a_uint64_t)); + if (SW_OK != rv) + dprintf("usage: seconds 48bits \n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* nanoseconds */ + do + { + cmd = get_sub_cmd("nanoseconds", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: nanoseconds 32bits\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, (a_uint32_t *) (&(pEntry->nanoseconds)), + sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: nanoseconds 32bits\n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* fracnanoseconds */ + do + { + cmd = get_sub_cmd("fracnanoseconds", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: fracnanoseconds 32bits \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, (a_uint32_t *) (&(pEntry->fracnanoseconds)), + sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: fracnanoseconds 32bits\n"); + } + }while (talk_mode && (SW_OK != rv)); + + return SW_OK; +} + +void +cmd_data_print_ptp_time(a_char_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_ptp_time_t *entry; + + entry = (fal_ptp_time_t *) buf; + dprintf("[seconds]:0x%llx\n", entry->seconds); + dprintf("[nanoseconds]:0x%x\n", entry->nanoseconds); + dprintf("[fracnanoseconds]:0x%x\n", entry->fracnanoseconds); + dprintf("\n"); + +} + +sw_error_t +cmd_data_check_ptp_grandmaster_mode(char *info, void *val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_ptp_grandmaster_mode_t *pEntry = (fal_ptp_grandmaster_mode_t *)val; + + memset(pEntry, 0, sizeof(fal_ptp_grandmaster_mode_t)); + + /* grandmaster mode en */ + do + { + cmd = get_sub_cmd("grandmaster_mode_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(pEntry->grandmaster_mode_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + /* grandmaster second sync en */ + do + { + cmd = get_sub_cmd("grandmaster_second_sync_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, + &(pEntry->grandmaster_second_sync_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + /* frequency offset */ + do + { + cmd = get_sub_cmd("freq_offset", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: enum maxfrequency offset\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &(pEntry->freq_offset), sizeof(a_uint8_t)); + if (SW_OK != rv) + dprintf("usage: enum maxfrequency offset\n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* right shift in kp */ + do + { + cmd = get_sub_cmd("right_shift_in_kp", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(pEntry->right_shift_in_kp), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* kp value */ + do + { + cmd = get_sub_cmd("kp_value", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: kp value\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(pEntry->kp_value), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: kp value\n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* right shift in ki */ + do + { + cmd = get_sub_cmd("right_shift_in_ki", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(pEntry->right_shift_in_ki), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* ki value */ + do + { + cmd = get_sub_cmd("ki_value", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: ki value\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(pEntry->ki_value), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: ki value\n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* ns sync mode */ + do + { + cmd = get_sub_cmd("ns_sync_mode", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0 for PPSIN, 1 for HWPLL, 2 for SWPLL\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &(pEntry->ns_sync_mode), sizeof(a_uint8_t)); + if (SW_OK != rv) + dprintf("usage: 0 for PPSIN, 1 for HWPLL, 2 for SWPLL\n"); + } + }while (talk_mode && (SW_OK != rv)); + + return SW_OK; +} + +void +cmd_data_print_ptp_grandmaster_mode(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_ptp_grandmaster_mode_t *entry; + + entry = (fal_ptp_grandmaster_mode_t *) buf; + dprintf("[grandmaster_mode_en]:%s\n", + entry->grandmaster_mode_en ? "YES" : "NO"); + dprintf("[grandmaster_second_sync_en]:%s\n", + entry->grandmaster_second_sync_en ? "YES" : "NO"); + dprintf("[freq_offset]:%d\n", entry->freq_offset); + dprintf("[right_shift_in_kp]:%s [kp_value]:%d\n", + entry->right_shift_in_kp ? "YES" : "NO", entry->kp_value); + dprintf("[right_shift_in_ki]:%s [ki_value]:%d\n", + entry->right_shift_in_ki ? "YES" : "NO", entry->ki_value); + dprintf("[ns_sync_mode]:%d\n", entry->ns_sync_mode); + dprintf("\n"); + +} + +sw_error_t +cmd_data_check_ptp_security(char *info, void *val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_ptp_security_t *pEntry = (fal_ptp_security_t *)val; + + memset(pEntry, 0, sizeof(fal_ptp_security_t)); + + /* address_check_en */ + do + { + cmd = get_sub_cmd("address_check_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(pEntry->address_check_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + /* ipv6_udp_checksum_recal_en */ + do + { + cmd = get_sub_cmd("ipv6_udp_checksum_recal_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, + &(pEntry->ipv6_udp_checksum_recal_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + /* version_check_en */ + do + { + cmd = get_sub_cmd("version_check_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, + &(pEntry->version_check_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + + /* ptp_version */ + do + { + cmd = get_sub_cmd("ptp_version", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: version, 8bits\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(pEntry->ptp_version), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: version, 8bits\n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* ipv4_udp_checksum_force_zero_en */ + do + { + cmd = get_sub_cmd("ipv4_udp_checksum_force_zero_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, + &(pEntry->ipv4_udp_checksum_force_zero_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + /* ipv6_embed_udp_checksum_force_zero_en */ + do + { + cmd = get_sub_cmd("ipv6_embed_udp_checksum_force_zero_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, + &(pEntry->ipv6_embed_udp_checksum_force_zero_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + + return SW_OK; +} + +void +cmd_data_print_ptp_security(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_ptp_security_t *entry; + + entry = (fal_ptp_security_t *) buf; + dprintf("[address_check_en]:%s\n", + entry->address_check_en ? "YES" : "NO"); + dprintf("[ipv6_udp_checksum_recal_en]:%s\n", + entry->ipv6_udp_checksum_recal_en ? "YES" : "NO"); + dprintf("[version_check_en]:%s\n", + entry->version_check_en ? "YES" : "NO"); + dprintf("[ptp_version]:%d\n", entry->ptp_version); + dprintf("[ipv4_udp_checksum_force_zero_en]:%s\n", + entry->ipv4_udp_checksum_force_zero_en ? "YES" : "NO"); + dprintf("[ipv6_embed_udp_checksum_force_zero_en]:%s\n", + entry->ipv6_embed_udp_checksum_force_zero_en ? "YES" : "NO"); + dprintf("\n"); + +} + +sw_error_t +cmd_data_check_ptp_pps_sig_ctrl(char *info, void *val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_ptp_pps_signal_control_t *pEntry = (fal_ptp_pps_signal_control_t *)val; + + memset(pEntry, 0, sizeof(fal_ptp_pps_signal_control_t)); + + /* negative_in_latency */ + do + { + cmd = get_sub_cmd("negative_in_latency", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(pEntry->negative_in_latency), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + /* in_latency */ + do + { + cmd = get_sub_cmd("in_latency", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: input latency\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(pEntry->in_latency), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: input latency\n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* out_phase */ + do + { + cmd = get_sub_cmd("out_phase", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: output phase\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(pEntry->out_phase), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: output phase\n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* out_pulse_width */ + do + { + cmd = get_sub_cmd("out_pulse_width", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: output pulse width\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(pEntry->out_pulse_width), + sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: output pulse width\n"); + } + }while (talk_mode && (SW_OK != rv)); + + return SW_OK; +} + +void +cmd_data_print_ptp_pps_sig_ctrl(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_ptp_pps_signal_control_t *entry; + + entry = (fal_ptp_pps_signal_control_t *) buf; + dprintf("[negative_in_latency]:%s\n", entry->negative_in_latency ? "YES" : "NO"); + dprintf("[in_latency]:0x%x\n", entry->in_latency); + dprintf("[out_phase]:0x%x\n", entry->out_phase); + dprintf("[out_pulse_width]:0x%x\n", entry->out_pulse_width); + dprintf("\n"); + +} + +sw_error_t +cmd_data_check_ptp_asym_correction(char *info, void *val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_ptp_asym_correction_t *pEntry = (fal_ptp_asym_correction_t *)val; + + memset(pEntry, 0, sizeof(fal_ptp_asym_correction_t)); + + /* eg_asym_en */ + do + { + cmd = get_sub_cmd("eg_asym_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(pEntry->eg_asym_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + /* in_asym_en */ + do + { + cmd = get_sub_cmd("in_asym_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(pEntry->in_asym_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + /* eg_asym_value */ + do + { + cmd = get_sub_cmd("eg_asym_value", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: egress asymmetry value\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(pEntry->eg_asym_value), + sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: egress asymmetry value\n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* in_asym_value */ + do + { + cmd = get_sub_cmd("in_asym_value", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: ingress asymmetry value\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(pEntry->in_asym_value), + sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: ingress asymmetry value\n"); + } + }while (talk_mode && (SW_OK != rv)); + + return SW_OK; +} + +void +cmd_data_print_ptp_asym_correction(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_ptp_asym_correction_t *entry; + + entry = (fal_ptp_asym_correction_t *) buf; + dprintf("[eg_asym_en]:%s\n", entry->eg_asym_en ? "YES" : "NO"); + dprintf("[in_asym_en]:%s\n", entry->in_asym_en ? "YES" : "NO"); + dprintf("[eg_asym_value]:0x%x\n", entry->eg_asym_value); + dprintf("[in_asym_value]:0x%x\n", entry->in_asym_value); + dprintf("\n"); + +} + +sw_error_t +cmd_data_check_ptp_waveform(char *info, void *val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_ptp_output_waveform_t *pEntry = (fal_ptp_output_waveform_t *)val; + + memset(pEntry, 0, sizeof(fal_ptp_output_waveform_t)); + + /* waveform_type */ + do + { + cmd = get_sub_cmd("waveform_type", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: 0 for waveform frequency, 1 for pulse 10ms, " + "2 for trigger0 and 3 for ptp rx state\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint8(cmd, &(pEntry->waveform_type), sizeof(a_uint8_t)); + if (SW_OK != rv) + dprintf("usage: 0 for waveform frequency, 1 for pulse 10ms, " + "2 for trigger0 and 3 for ptp rx state\n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* wave_align_pps_out_en */ + do + { + cmd = get_sub_cmd("wave_align_pps_out_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(pEntry->wave_align_pps_out_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + /* wave_period */ + do + { + cmd = get_sub_cmd("wave_period", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: waveform frequency period\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint64(cmd, &(pEntry->wave_period), sizeof(a_uint64_t)); + if (SW_OK != rv) + dprintf("usage: waveform frequency period\n"); + } + }while (talk_mode && (SW_OK != rv)); + + return SW_OK; +} + +void +cmd_data_print_ptp_waveform(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_ptp_output_waveform_t *entry; + + entry = (fal_ptp_output_waveform_t *) buf; + dprintf("[waveform_type]:%d\n", entry->waveform_type); + dprintf("[wave_align_pps_out_en]:%s\n", entry->wave_align_pps_out_en ? "YES" : "NO"); + dprintf("[wave_period]:0x%llx\n", entry->wave_period); + dprintf("\n"); + +} + +sw_error_t +cmd_data_check_ptp_tod_uart(char *info, void *val, a_uint32_t size) +{ + char *cmd; + a_uint32_t tmp; + sw_error_t rv; + fal_ptp_tod_uart_t *pEntry = (fal_ptp_tod_uart_t *)val; + + memset(pEntry, 0, sizeof(fal_ptp_tod_uart_t)); + + /* baud_config */ + do + { + cmd = get_sub_cmd("baud_config", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: baud config value \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, sizeof(a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: baud config value \n"); + } + else + { + pEntry->baud_config = tmp; + } + } + }while (talk_mode && (SW_OK != rv)); + + /* uart_config_bmp */ + do + { + cmd = get_sub_cmd("uart_config_bmp", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: UART config bitmap \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(pEntry->uart_config_bmp), + sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: UART config bitmap \n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* reset_buf_en */ + do + { + cmd = get_sub_cmd("reset_buf_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(pEntry->reset_buf_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + /* tx_buf_value */ + do + { + cmd = get_sub_cmd("tx_buf_value", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: tx buffer value \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &tmp, + sizeof(a_uint32_t)); + if (SW_OK != rv) + { + dprintf("usage: tx buffer value \n"); + } + else + { + pEntry->tx_buf_value = tmp; + } + } + }while (talk_mode && (SW_OK != rv)); + + return SW_OK; +} + +void +cmd_data_print_ptp_tod_uart(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_ptp_tod_uart_t *entry; + + entry = (fal_ptp_tod_uart_t *) buf; + dprintf("[baud_config]:0x%x\n", entry->baud_config); + dprintf("[uart_config_bmp]:0x%x\n", entry->uart_config_bmp); + dprintf("[reset_buf_en]:%s\n", entry->reset_buf_en ? "YES" : "NO"); + dprintf("[buf_status_bmp]:0x%x\n", entry->buf_status_bmp); + dprintf("[tx_buf_value]:0x%x\n", entry->tx_buf_value); + dprintf("[rx_buf_value]:0x%x\n", entry->rx_buf_value); + dprintf("\n"); + +} + +sw_error_t +cmd_data_check_ptp_enhanced_timestamp_engine(char *info, void *val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_ptp_enhanced_ts_engine_t *pEntry = (fal_ptp_enhanced_ts_engine_t *)val; + + memset(pEntry, 0, sizeof(fal_ptp_enhanced_ts_engine_t)); + + /* filt_en */ + do + { + cmd = get_sub_cmd("filt_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, &(pEntry->filt_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + /* enhance_ts_conf_bmp */ + do + { + cmd = get_sub_cmd("enhance_ts_conf_bmp", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: enhanced timestamp config bitmap \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint16(cmd, &(pEntry->enhance_ts_conf_bmp), + sizeof(a_uint16_t)); + if (SW_OK != rv) + dprintf("usage: enhanced timestamp config bitmap \n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* eth_type */ + do + { + cmd = get_sub_cmd("eth_type", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: ethernet type \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(pEntry->eth_type), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: ethernet type \n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* dmac_addr */ + do + { + cmd = get_sub_cmd("dmac_addr", NULL); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the format is xx-xx-xx-xx-xx-xx \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_macaddr(cmd, &(pEntry->dmac_addr), + sizeof (fal_mac_addr_t)); + if (SW_OK != rv) + dprintf("usage: the format is xx-xx-xx-xx-xx-xx \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + /* ipv4_l4_proto */ + do + { + cmd = get_sub_cmd("ipv4_l4_proto", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: ipv4 l4 protocol, 32bits\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(pEntry->ipv4_l4_proto), + sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: ipv4 l4 protocol, 32bits\n"); + } + }while (talk_mode && (SW_OK != rv)); + + cmd_data_check_element("ipv4_dip", "0.0.0.0", + "usage: the format is xx.xx.xx.xx \n", + cmd_data_check_ip4addr, (cmd, &(pEntry->ipv4_dip), 4)); + cmd_data_check_element("ipv6_dip", NULL, + "usage: the format is xxxx::xxxx \n", + cmd_data_check_ip6addr, (cmd, &(pEntry->ipv6_dip), 16)); + + /* udp_dport */ + do + { + cmd = get_sub_cmd("udp_dport", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: udp dest port\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(pEntry->udp_dport), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: udp dest port\n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* y1731_mac_addr */ + do + { + cmd = get_sub_cmd("y1731_mac_addr", NULL); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: the format is xx-xx-xx-xx-xx-xx \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_macaddr(cmd, &(pEntry->y1731_mac_addr), + sizeof (fal_mac_addr_t)); + if (SW_OK != rv) + dprintf("usage: the format is xx-xx-xx-xx-xx-xx \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + return SW_OK; +} + +void +cmd_data_print_ptp_enhanced_timestamp_engine(a_uint8_t * param_name, + a_uint32_t * buf, a_uint32_t size) +{ + fal_ptp_enhanced_ts_engine_t *entry; + entry = (fal_ptp_enhanced_ts_engine_t *) buf; + + dprintf("[filt_en]:%s\n", entry->filt_en ? "YES" : "NO"); + + dprintf("[enhance_ts_conf_bmp]:0x%x\n", entry->enhance_ts_conf_bmp); + dprintf("[eth_type]:0x%x\n", entry->eth_type); + cmd_data_print_macaddr("[dmac_addr]:", (a_uint32_t *) & (entry->dmac_addr), + sizeof (fal_mac_addr_t)); + dprintf("\n"); + dprintf("[ipv4_l4_proto]:0x%x\n", entry->ipv4_l4_proto); + cmd_data_print_ip4addr("[ipv4_dip]:", + (a_uint32_t *) & (entry->ipv4_dip), + sizeof (fal_ip4_addr_t)); + cmd_data_print_ip6addr("\n[ipv6_dip]:", + (a_uint32_t *) & (entry->ipv6_dip), + sizeof (fal_ip6_addr_t)); + dprintf("\n"); + dprintf("[udp_dport]:0x%x\n", entry->udp_dport); + cmd_data_print_macaddr("[y1731_mac_addr]:", (a_uint32_t *) & (entry->y1731_mac_addr), + sizeof (fal_mac_addr_t)); + dprintf("\n"); + dprintf("[enhance_ts_status_bmp]:0x%x\n", entry->enhance_ts_status_bmp); + dprintf("[enhance_ts_status_pre_bmp]:0x%x\n", entry->enhance_ts_status_pre_bmp); + dprintf("[y1731_identity]:0x%x\n", entry->y1731_identity); + dprintf("[y1731_identity_pre]:0x%x\n", entry->y1731_identity_pre); + dprintf("timestamp:\n"); + dprintf("[seconds]:0x%llx\n", entry->timestamp.seconds); + dprintf("[nanoseconds]:0x%x\n", entry->timestamp.nanoseconds); + dprintf("[fracnanoseconds]:0x%x\n", entry->timestamp.fracnanoseconds); + dprintf("timestamp pre:\n"); + dprintf("[seconds]:0x%llx\n", entry->timestamp_pre.seconds); + dprintf("[nanoseconds]:0x%x\n", entry->timestamp_pre.nanoseconds); + dprintf("[fracnanoseconds]:0x%x\n", entry->timestamp_pre.fracnanoseconds); + printf("\n"); + +} + +sw_error_t +cmd_data_check_ptp_trigger(char *info, void *val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_ptp_trigger_t *pEntry = (fal_ptp_trigger_t *)val; + + memset(pEntry, 0, sizeof(fal_ptp_trigger_t)); + + /* trigger_en */ + do + { + cmd = get_sub_cmd("trigger_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, + &(pEntry->trigger_conf.trigger_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + /* output_force_en */ + do + { + cmd = get_sub_cmd("output_force_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, + &(pEntry->trigger_conf.output_force_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + /* output_force_value */ + do + { + cmd = get_sub_cmd("output_force_value", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: output force value \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, + (a_uint32_t *) (&(pEntry->trigger_conf.output_force_value)), + sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: output force value \n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* patten_select */ + do + { + cmd = get_sub_cmd("patten_select", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: patten select \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, + (a_uint32_t *) (&(pEntry->trigger_conf.patten_select)), + sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: patten select \n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* late_operation */ + do + { + cmd = get_sub_cmd("late_operation", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: late operation\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, + (a_uint32_t *) (&(pEntry->trigger_conf.late_operation)), + sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: late operation\n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* notify */ + do + { + cmd = get_sub_cmd("notify", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: notify\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, + (a_uint32_t *) (&(pEntry->trigger_conf.notify)), + sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: notify\n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* trigger_effect */ + do + { + cmd = get_sub_cmd("trigger_effect", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: trigger effect\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, + (a_uint32_t *) (&(pEntry->trigger_conf.trigger_effect)), + sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: trigger effect\n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* seconds */ + do + { + cmd = get_sub_cmd("seconds", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: seconds 48bits \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint64(cmd, + (a_uint64_t *) (&(pEntry->trigger_conf.tim.seconds)), + sizeof(a_uint64_t)); + if (SW_OK != rv) + dprintf("usage: seconds 48bits \n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* nanoseconds */ + do + { + cmd = get_sub_cmd("nanoseconds", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: nanoseconds 32bits\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, + (a_uint32_t *) (&(pEntry->trigger_conf.tim.nanoseconds)), + sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: nanoseconds 32bits\n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* fracnanoseconds */ + do + { + cmd = get_sub_cmd("fracnanoseconds", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: fracnanoseconds 32bits \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, + (a_uint32_t *) (&(pEntry->trigger_conf.tim.fracnanoseconds)), + sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: fracnanoseconds 32bits\n"); + } + }while (talk_mode && (SW_OK != rv)); + + return SW_OK; +} + +void +cmd_data_print_ptp_trigger(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_ptp_trigger_t *entry; + entry = (fal_ptp_trigger_t *) buf; + + dprintf("[trigger_en]:%s\n", entry->trigger_conf.trigger_en ? "YES" : "NO"); + dprintf("[output_force_en]:%s\n", entry->trigger_conf.output_force_en ? "YES" : "NO"); + dprintf("[output_force_value]:0x%x\n", entry->trigger_conf.output_force_value); + dprintf("[patten_select]:0x%x\n", entry->trigger_conf.patten_select); + dprintf("[late_operation]:0x%x\n", entry->trigger_conf.late_operation); + dprintf("[notify]:0x%x\n", entry->trigger_conf.notify); + dprintf("[trigger_effect]:0x%x\n", entry->trigger_conf.trigger_effect); + dprintf("[trigger_finished]:0x%x\n", entry->trigger_status.trigger_finished); + dprintf("[trigger_active]:0x%x\n", entry->trigger_status.trigger_active); + dprintf("[trigger_error]:0x%x\n", entry->trigger_status.trigger_error); + cmd_data_print_ptp_time("[time]:", + (a_uint32_t *) & (entry->trigger_conf.tim), + sizeof (fal_ptp_time_t)); + +} + +sw_error_t +cmd_data_check_ptp_capture(char *info, void *val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_ptp_capture_t *pEntry = (fal_ptp_capture_t *)val; + + memset(pEntry, 0, sizeof(fal_ptp_capture_t)); + + /* status_clear */ + do + { + cmd = get_sub_cmd("status_clear", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: status clear \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, + (a_uint32_t *) (&(pEntry->capture_conf.status_clear)), + sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: status clear \n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* notify_event */ + do + { + cmd = get_sub_cmd("notify_event", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: notify event \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, + (a_uint32_t *) (&(pEntry->capture_conf.notify_event)), + sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: notify event \n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* single_multi_select */ + do + { + cmd = get_sub_cmd("single_multi_select", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: single multiple select\n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, + (a_uint32_t *) (&(pEntry->capture_conf.single_multi_select)), + sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: single multiple select\n"); + } + }while (talk_mode && (SW_OK != rv)); + + /* fall_edge_en */ + do + { + cmd = get_sub_cmd("fall_edge_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, + &(pEntry->capture_conf.fall_edge_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + /* rise_edge_en */ + do + { + cmd = get_sub_cmd("rise_edge_en", "yes"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_confirm(cmd, A_FALSE, + &(pEntry->capture_conf.rise_edge_en), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + return SW_OK; +} + +void +cmd_data_print_ptp_capture(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_ptp_capture_t *entry; + entry = (fal_ptp_capture_t *) buf; + + dprintf("[status_clear]:0x%x\n", entry->capture_conf.status_clear); + dprintf("[notify_event]:0x%x\n", entry->capture_conf.notify_event); + dprintf("[single_multi_select]:0x%x\n", entry->capture_conf.single_multi_select); + dprintf("[fall_edge_en]:%s\n", entry->capture_conf.fall_edge_en ? "YES" : "NO"); + dprintf("[rise_edge_en]:%s\n", entry->capture_conf.rise_edge_en ? "YES" : "NO"); + + dprintf("[event_detected]:0x%x\n", entry->capture_status.event_detected); + dprintf("[fall_rise_edge_detected]:0x%x\n", entry->capture_status.fall_rise_edge_detected); + dprintf("[single_multi_detected]:0x%x\n", entry->capture_status.single_multi_detected); + dprintf("[event_missed_cnt]:0x%x\n", entry->capture_status.event_missed_cnt); + cmd_data_print_ptp_time("\n[time]:", + (a_uint32_t *) & (entry->capture_status.tim), + sizeof (fal_ptp_time_t)); + +} + +sw_error_t +cmd_data_check_ptp_interrupt(char *info, void *val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_ptp_interrupt_t *pEntry = (fal_ptp_interrupt_t *)val; + + memset(pEntry, 0, sizeof(fal_ptp_interrupt_t)); + + /* intr_mask */ + do + { + cmd = get_sub_cmd("intr_mask", "0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: interrupt mask \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_uint32(cmd, &(pEntry->intr_mask), sizeof(a_uint32_t)); + if (SW_OK != rv) + dprintf("usage: interrupt mask \n"); + } + }while (talk_mode && (SW_OK != rv)); + + return SW_OK; +} + +void +cmd_data_print_ptp_interrupt(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_ptp_interrupt_t *entry; + entry = (fal_ptp_interrupt_t *) buf; + + dprintf("[intr_mask]:0x%x\n", entry->intr_mask); + dprintf("[intr_status]:0x%x\n", entry->intr_status); + +} + +sw_error_t +cmd_data_check_source_filter_mode(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + { + return SW_BAD_PARAM; + } + + if (!strncasecmp(cmd_str, "virtual_port", 15)) + { + *arg_val = FAL_SRC_FILTER_MODE_VP; + } + else if (!strncasecmp(cmd_str, "physical_port", 15)) + { + *arg_val = FAL_SRC_FILTER_MODE_PHYSICAL; + } + else + { + return SW_BAD_VALUE; + } + + return SW_OK; +} + +sw_error_t +cmd_data_check_src_filter_config(char *cmd_str, a_uint32_t *arg_val, a_uint32_t size) +{ + char *cmd; + sw_error_t rv; + fal_src_filter_config_t src_filter_config; + + aos_mem_zero(&src_filter_config, sizeof (fal_src_filter_config_t)); + + do + { + cmd = get_sub_cmd("srcfilter_enable", "enable"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: enable/disable \n"); + rv = SW_BAD_VALUE; + } + else + { + rv = cmd_data_check_enable(cmd, &(src_filter_config.src_filter_enable), + sizeof (a_bool_t)); + if (SW_OK != rv) + dprintf("usage: enable/disable \n"); + } + } + while (talk_mode && (SW_OK != rv)); + + do + { + cmd = get_sub_cmd("srcfilter_mode", "virtual_port"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) + { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) + { + dprintf("usage: usage: virtual_port physical_port\n"); + rv = SW_BAD_VALUE; + } + else + { + cmd_data_check_source_filter_mode(cmd, &(src_filter_config.src_filter_mode), + sizeof(a_uint32_t)); + } + } + while (talk_mode && (SW_OK != rv)); + + *(fal_src_filter_config_t *)arg_val = src_filter_config; + + return SW_OK; +} + +void +cmd_data_print_src_filter_config(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + fal_src_filter_config_t *src_filter_config; + src_filter_config = (fal_src_filter_config_t *) buf; + + dprintf("\n[%s] \n", param_name); + + if(src_filter_config->src_filter_enable) + { + dprintf("src_filter_enable:ENABLE\n"); + } + else + { + dprintf("src_filter_enable:DISABLE\n"); + } + if(src_filter_config->src_filter_mode == FAL_SRC_FILTER_MODE_VP) + { + dprintf("src_filter_mode:virtual_port mode\n"); + } + else if(src_filter_config->src_filter_mode == FAL_SRC_FILTER_MODE_PHYSICAL) + { + dprintf("src_filter_mode:physical_port mode\n"); + } + else + { + dprintf("src_filter_mode:unknown\n"); + } +} + +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 rv = SW_OK; + + if (cmdstr == NULL) { + return SW_BAD_PARAM; + } else if (0 == cmdstr[0]) { + return SW_BAD_VALUE; + } + + if (!strcasecmp(cmdstr, "base")) { + *arg_val = FAL_SFP_CC_BASE; + } + else if (!strcasecmp(cmdstr, "ext")) { + *arg_val = FAL_SFP_CC_EXT; + } + else if (!strcasecmp(cmdstr, "dmi")) { + *arg_val = FAL_SFP_CC_DMI; + } + else { + dprintf("usage: \n"); + rv = SW_BAD_VALUE; + } + + return rv; +} + +sw_error_t +cmd_data_check_sfp_data(char *cmd_str, void *arg_val, a_uint32_t size) +{ + fal_sfp_data_t entry; + sw_error_t rv; + char *cmd, cmd_byte[3]; + char fmt[3] = "%x"; + a_uint8_t bytes; + + aos_mem_zero(&entry, sizeof(fal_sfp_data_t)); + + do { + cmd = get_sub_cmd("addr", "0x50"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) { + dprintf("usage: input valid i2c slave addr(0x0~0x7f) \n"); + rv = SW_BAD_VALUE; + } + else { + rv = cmd_data_check_uint8(cmd, &(entry.addr), sizeof(a_uint8_t)); + if (SW_OK != rv) { + rv = SW_BAD_VALUE; + } + } + } while (talk_mode && (SW_OK != rv)); + + do { + cmd = get_sub_cmd("offset", "0x0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) { + dprintf("usage: 0x0~0xff \n"); + rv = SW_BAD_VALUE; + } + else { + rv = cmd_data_check_uint8(cmd, &(entry.offset), sizeof(a_uint8_t)); + if (SW_OK != rv) { + rv = SW_BAD_VALUE; + } + } + } while (talk_mode && (SW_OK != rv)); + + do { + cmd = get_sub_cmd("count", "0x0"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncasecmp(cmd, "quit", 4)) { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) { + dprintf("usage: 0x0~0xff \n"); + rv = SW_BAD_VALUE; + } + else { + rv = cmd_data_check_uint8(cmd, &(entry.count), sizeof(a_uint8_t)); + if (SW_OK != rv) { + rv = SW_BAD_VALUE; + } else if (entry.offset + entry.count > 255) { + dprintf("error: offset + count more than 255\n"); + rv = SW_BAD_VALUE; + } + } + } while (talk_mode && (SW_OK != rv)); + + do { + cmd = get_sub_cmd("data", "null"); + SW_RTN_ON_NULL_PARAM(cmd); + + if (!strncmp(cmd, "null", strlen(cmd))) { + /* the default value "null" of data is for getting operation */ + rv = SW_OK; + break; + } + + if (!strncasecmp(cmd, "quit", 4)) { + return SW_BAD_VALUE; + } + else if (!strncasecmp(cmd, "help", 4)) { + dprintf("input the matched hex data count: 0x%x \n", entry.count); + rv = SW_BAD_VALUE; + } + else if (strspn(cmd, "1234567890abcdefABCDEFXx") != strlen(cmd) || + strlen(cmd) != (entry.count * 2 + 2)) { + dprintf("the input data is invalid\n"); + rv = SW_BAD_VALUE; + } + else { + if (cmd[0] == '0' && (cmd[1] == 'x' || cmd[1] == 'X')) { + cmd += 2; + for (bytes = 0; bytes < entry.count; bytes++) { + if (strlen(cmd) == 0) { + break; + } + /* copy 2 chars from cmd */ + strlcpy(cmd_byte, cmd, sizeof(cmd_byte)); + sscanf(cmd_byte, fmt, &(entry.data[bytes])); + cmd += 2; + } + + if (bytes < entry.count) { + dprintf("the byte length of input data is less than %d\n", + entry.count); + rv = SW_BAD_VALUE; + } else { + rv = SW_OK; + } + } else { + dprintf("need to input hex data\n"); + rv = SW_BAD_VALUE; + } + } + } while (talk_mode && (SW_OK != rv)); + + *(fal_sfp_data_t *)arg_val = entry; + + return SW_OK; +} + +void +cmd_data_print_sfp_data(a_uint8_t *param_name, a_ulong_t *buf, a_uint32_t size) +{ + a_uint8_t data_cnt; + fal_sfp_data_t *sfp_data = (fal_sfp_data_t *)buf; + + dprintf("\n[%s] \n", param_name); + + dprintf("eeprom addr: 0x%02x\n", sfp_data->addr); + dprintf("eeprom data:"); + for (data_cnt = 0; data_cnt < sfp_data->count; data_cnt++) { + if (!(data_cnt % 16)) { + dprintf("\n%02x:", sfp_data->offset + data_cnt); + } + + dprintf("%02x", sfp_data->data[data_cnt]); + } + + dprintf("\n\n"); +} + +void +cmd_data_print_sfp_dev_type(a_uint8_t *param_name, a_ulong_t *buf, a_uint32_t size) +{ + fal_sfp_dev_type_t *entry; + + dprintf("\n[%s] \n", param_name); + + entry = (fal_sfp_dev_type_t *)buf; + dprintf("[id]:0x%x [ext_id]:0x%x\n", entry->identifier, entry->ext_indentifier); + dprintf("[connector_type]:0x%x\n", entry->connector_type); + dprintf("\n"); +} + +void +cmd_data_print_sfp_transc_code(a_uint8_t *param_name, a_ulong_t *buf, a_uint32_t size) +{ + fal_sfp_transc_code_t *entry; + + dprintf("\n[%s] \n", param_name); + + entry = (fal_sfp_transc_code_t *)buf; + dprintf("[eth_10g_ccode]:0x%x [infiniband_ccode]:0x%x [escon_ccode]:0x%x " + "[sonet_ccode]:0x%x [eth_ccode]:0x%x [fibre_chan_link_length]:0x%x " + "[fibre_chan_tech]: 0x%x [sfp_cable_tech]:0x%x [fibre_chan_trans_md]:0x%x " + "[fibre_chan_speed]:0x%x\n", + entry->eth_10g_ccode, entry->infiniband_ccode, entry->escon_ccode, + entry->sonet_ccode, entry->eth_ccode, entry->fibre_chan_link_length, + entry->fibre_chan_tech, entry->sfp_cable_tech, entry->fibre_chan_trans_md, + entry->fibre_chan_speed); + dprintf("\n"); +} + +void +cmd_data_print_sfp_rate_encode(a_uint8_t *param_name, a_ulong_t *buf, a_uint32_t size) +{ + fal_sfp_rate_encode_t *entry; + + dprintf("\n[%s] \n", param_name); + + entry = (fal_sfp_rate_encode_t *)buf; + dprintf("[encode]:0x%x [nominal_bit_rate]:0x%x\n", entry->encode, entry->nominal_bit_rate); + dprintf("[rate_id]:0x%x\n", entry->rate_id); + dprintf("\n"); +} + +void +cmd_data_print_sfp_link_length(a_uint8_t *param_name, a_ulong_t *buf, a_uint32_t size) +{ + fal_sfp_link_length_t *entry; + + dprintf("\n[%s] \n", param_name); + + entry = (fal_sfp_link_length_t *)buf; + dprintf("[single_mode_length_km]:0x%x [single_mode_length_100m]:0x%x\n", + entry->single_mode_length_km, entry->single_mode_length_100m); + dprintf("[om2_mode_length_10m]:0x%x [om1_mode_length_10m]:0x%x\n", + entry->om2_mode_length_10m, entry->om1_mode_length_10m); + dprintf("[copper_mode_length_1m]:0x%x [om3_mode_length_1m]:0x%x\n", + entry->copper_mode_length_1m, entry->om3_mode_length_1m); + dprintf("\n"); +} + +void +cmd_data_print_sfp_vendor_info(a_uint8_t *param_name, a_ulong_t *buf, a_uint32_t size) +{ + fal_sfp_vendor_info_t *entry; + a_uint8_t index; + + dprintf("\n[%s] \n", param_name); + + entry = (fal_sfp_vendor_info_t *)buf; + dprintf("[vendor_name]:"); + index = 0; + while (index < sizeof(entry->vendor_name)) { + dprintf("%c", entry->vendor_name[index]); + index++; + } + dprintf("\n"); + + dprintf("[vendor_oui]:"); + index = 0; + while (index < sizeof(entry->vendor_oui)) { + dprintf("%02x", entry->vendor_oui[index]); + index++; + } + dprintf("\n"); + + dprintf("[vendor_pn]:"); + index = 0; + while (index < sizeof(entry->vendor_pn)) { + dprintf("%c", entry->vendor_pn[index]); + index++; + } + dprintf("\n"); + + dprintf("[vendor_rev]:"); + index = 0; + while (index < sizeof(entry->vendor_rev)) { + dprintf("%c", entry->vendor_rev[index]); + index++; + } + dprintf("\n"); + + dprintf("[vendor_sn]:"); + index = 0; + while (index < sizeof(entry->vendor_sn)) { + dprintf("%c", entry->vendor_sn[index]); + index++; + } + dprintf("\n"); + + dprintf("[vendor_date_code]:"); + index = 0; + while (index < sizeof(entry->vendor_date_code)) { + dprintf("%c", entry->vendor_date_code[index]); + index++; + } + + dprintf("\n\n"); +} + +void +cmd_data_print_sfp_laser_wavelength(a_uint8_t *param_name, a_ulong_t *buf, a_uint32_t size) +{ + fal_sfp_laser_wavelength_t *entry; + + dprintf("\n[%s] \n", param_name); + + entry = (fal_sfp_laser_wavelength_t *)buf; + dprintf("[laser_wavelength]:0x%x\n", entry->laser_wavelength); + dprintf("\n"); +} + +void +cmd_data_print_sfp_option(a_uint8_t *param_name, a_ulong_t *buf, a_uint32_t size) +{ + fal_sfp_option_t *entry; + + dprintf("\n[%s] \n", param_name); + + entry = (fal_sfp_option_t *)buf; + dprintf("[linear_recv_output]:0x%x [pwr_level_declar]:0x%x " + "[cool_transc_declar]:0x%x [loss_signal]:0x%x " + "[loss_invert_signal]:0x%x [tx_fault_signal]:0x%x " + "[tx_disable]:0x%x [rate_sel]:0x%x\n", + entry->linear_recv_output, entry->pwr_level_declar, + entry->cool_transc_declar, entry->loss_signal, + entry->loss_invert_signal, entry->tx_fault_signal, + entry->tx_disable, entry->rate_sel); + dprintf("\n"); +} + +void +cmd_data_print_sfp_ctrl_rate(a_uint8_t *param_name, a_ulong_t *buf, a_uint32_t size) +{ + fal_sfp_rate_t *entry; + + dprintf("\n[%s] \n", param_name); + + entry = (fal_sfp_rate_t *)buf; + dprintf("[upper_rate_limit]:0x%x [lower_rate_limit]:0x%x\n", + entry->upper_rate_limit, entry->lower_rate_limit); + dprintf("\n"); +} + +void +cmd_data_print_sfp_enhanced_cfg(a_uint8_t *param_name, a_ulong_t *buf, a_uint32_t size) +{ + fal_sfp_enhanced_cfg_t *entry; + + dprintf("\n[%s] \n", param_name); + + entry = (fal_sfp_enhanced_cfg_t *)buf; + dprintf("[addr_mode]:0x%x [rec_pwr_type]:0x%x [external_cal]:0x%x " + "[internal_cal]:0x%x [diag_mon_flag]:0x%x [legacy_type]:0x%x\n", + entry->addr_mode, entry->rec_pwr_type, entry->external_cal, + entry->internal_cal, entry->diag_mon_flag, entry->legacy_type); + + dprintf("[soft_rate_sel_op]:0x%x [app_sel_op]:0x%x, [soft_rate_ctrl_op]:0x%x " + "[rx_los_op]:0x%x [tx_fault_op]:0x%x [tx_disable_ctrl_op]:0x%x " + "[alarm_warning_flag_op]:0x%x\n", + entry->soft_rate_sel_op, entry->app_sel_op, entry->soft_rate_ctrl_op, + entry->rx_los_op, entry->tx_fault_op, entry->tx_disable_ctrl_op, + entry->alarm_warning_flag_op); + + dprintf("[compliance_feature]:0x%x\n", entry->compliance_feature); + dprintf("\n"); +} + +void +cmd_data_print_sfp_diag_threshold(a_uint8_t *param_name, a_ulong_t *buf, a_uint32_t size) +{ + fal_sfp_internal_threshold_t *entry; + + dprintf("\n[%s] \n", param_name); + + entry = (fal_sfp_internal_threshold_t *)buf; + dprintf("[temp_high_alarm]:0x%x [temp_low_alarm]:0x%x " + "[temp_high_warning]:0x%x [temp_low_warning]:0x%x\n", + entry->temp_high_alarm, entry->temp_low_alarm, + entry->temp_high_warning, entry->temp_low_warning); + dprintf("[vol_high_alarm]:0x%x [vol_low_alarm]:0x%x " + "[vol_high_warning]:0x%x [vol_low_warning]:0x%x\n", + entry->vol_high_alarm, entry->vol_low_alarm, + entry->vol_high_warning, entry->vol_low_warning); + dprintf("[bias_high_alarm]:0x%x [bias_low_alarm]:0x%x " + "[bias_high_warning]:0x%x [bias_low_warning]:0x%x\n", + entry->bias_high_alarm, entry->bias_low_alarm, + entry->bias_high_warning, entry->bias_low_warning); + dprintf("[tx_power_high_alarm]:0x%x [tx_power_low_alarm]:0x%x " + "[tx_power_high_warning]:0x%x [tx_power_low_warning]:0x%x\n", + entry->tx_power_high_alarm, entry->tx_power_low_alarm, + entry->tx_power_high_warning, entry->tx_power_low_warning); + dprintf("[rx_power_high_alarm]:0x%x [rx_power_low_alarm]:0x%x " + "[rx_power_high_warning]:0x%x [rx_power_low_warning]:0x%x\n", + entry->rx_power_high_alarm, entry->rx_power_low_alarm, + entry->rx_power_high_warning, entry->rx_power_low_warning); + dprintf("\n"); +} + +void +cmd_data_print_sfp_diag_cal_const(a_uint8_t *param_name, a_ulong_t *buf, a_uint32_t size) +{ + fal_sfp_cal_const_t *entry; + + dprintf("\n[%s] \n", param_name); + + entry = (fal_sfp_cal_const_t *)buf; + dprintf("[rx_power4]:0x%x [rx_power3]:0x%x [rx_power2]:0x%x " + "[rx_power1]:0x%x [rx_power0]:0x%x\n", + entry->rx_power4, entry->rx_power3, entry->rx_power2, + entry->rx_power1, entry->rx_power0); + dprintf("[tx_bias_slope]:0x%x [tx_bias_offset]:0x%x\n", + entry->tx_bias_slope, entry->tx_bias_offset); + dprintf("[tx_power_slope]:0x%x [tx_power_offset]:0x%x\n", + entry->tx_power_slope, entry->tx_power_offset); + dprintf("[temp_slope]:0x%x [temp_offset]:0x%x\n", + entry->temp_slope, entry->temp_offset); + dprintf("[vol_slope]:0x%x [vol_offset]:0x%x\n", + entry->vol_slope, entry->vol_offset); + dprintf("\n"); +} + +void +cmd_data_print_sfp_diag_realtime(a_uint8_t *param_name, a_ulong_t *buf, a_uint32_t size) +{ + fal_sfp_realtime_diag_t *entry; + + dprintf("\n[%s] \n", param_name); + + entry = (fal_sfp_realtime_diag_t *)buf; + dprintf("[cur_temp]:0x%x [cur_vol]:0x%x [tx_cur_bias]:0x%x\n", + entry->cur_temp, entry->cur_vol, entry->tx_cur_bias); + dprintf("[tx_cur_power]:0x%x [rx_cur_power]:0x%x\n", + entry->tx_cur_power, entry->rx_cur_power); + dprintf("\n"); +} + +void +cmd_data_print_sfp_ctrl_status(a_uint8_t *param_name, a_ulong_t *buf, a_uint32_t size) +{ + fal_sfp_ctrl_status_t *entry; + + dprintf("\n[%s] \n", param_name); + + entry = (fal_sfp_ctrl_status_t *)buf; + dprintf("[data_ready]:0x%x [rx_los]:0x%x [tx_fault]:0x%x [soft_rate_sel]:0x%x " + "[rate_sel]:0x%x [rs_state]:0x%x [soft_tx_disable]:0x%x " + "[tx_disable]:0x%x\n", + entry->data_ready, entry->rx_los, entry->tx_fault, entry->soft_rate_sel, + entry->rate_sel, entry->rs_state, entry->soft_tx_disable, + entry->tx_disable); + + dprintf("[pwr_level_sel]:0x%x [pwr_level_op_state]:0x%x [soft_rs_sel]:0x%x\n", + entry->pwr_level_sel, entry->pwr_level_op_state, entry->soft_rs_sel); + + dprintf("\n"); +} + +void +cmd_data_print_sfp_alarm_warn_flag(a_uint8_t *param_name, a_ulong_t *buf, a_uint32_t size) +{ + fal_sfp_alarm_warn_flag_t *entry; + + dprintf("\n[%s] \n", param_name); + + entry = (fal_sfp_alarm_warn_flag_t *)buf; + dprintf("[tx_pwr_low_alarm]:0x%x [tx_pwr_high_alarm]:0x%x " + "[tx_bias_low_alarm]:0x%x [tx_bias_high_alarm]:0x%x " + "[vcc_low_alarm]:0x%x [vcc_high_alarm]:0x%x " + "[tmp_low_alarm]:0x%x [tmp_high_alarm]:0x%x " + "[rx_pwr_low_alarm]:0x%x [rx_pwr_high_alarm]:0x%x\n", + entry->tx_pwr_low_alarm, entry->tx_pwr_high_alarm, + entry->tx_bias_low_alarm, entry->tx_bias_high_alarm, + entry->vcc_low_alarm, entry->vcc_high_alarm, + entry->tmp_low_alarm, entry->tmp_high_alarm, + entry->rx_pwr_low_alarm, entry->rx_pwr_high_alarm); + + dprintf("[tx_pwr_low_warning]:0x%x [tx_pwr_high_warning]:0x%x " + "[tx_bias_low_warning]:0x%x [tx_bias_high_warning]:0x%x " + "[vcc_low_warning]:0x%x [vcc_high_warning]:0x%x " + "[tmp_low_warning]:0x%x [tmp_high_warning]:0x%x " + "[rx_pwr_low_warning]:0x%x [rx_pwr_high_warning]:0x%x\n", + entry->tx_pwr_low_warning, entry->tx_pwr_high_warning, + entry->tx_bias_low_warning, entry->tx_bias_high_warning, + entry->vcc_low_warning, entry->vcc_high_warning, + entry->tmp_low_warning, entry->tmp_high_warning, + entry->rx_pwr_low_warning, entry->rx_pwr_high_warning); + dprintf("\n"); +} diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/shell/shell_lib.c b/feeds/ipq807x/qca-ssdk-shell/src/src/shell/shell_lib.c new file mode 100755 index 000000000..db4e362f6 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/shell/shell_lib.c @@ -0,0 +1,917 @@ +/* + * 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 +#include +#include "shell_config.h" +#include "shell.h" + +#define printc(isPrint, fmt, args...) if(isPrint == 1) printf(fmt, ##args) +#ifndef PROMPT_STR +#define PROMPT_STR "dev0@qca>" +#endif +static char *cmd_promptp = PROMPT_STR; /*command prompt pointer */ +static struct termios term_save; /* terminal setting saved */ +static int term_cursor; /*terminal position */ +static int cmd_cursor; /*command position */ +static char *cmd_strp; /*command string pointer */ +static int cmd_strlen; /*command string length */ + +#define HISTORY_MAX_SIZE 20 +static char *history_buf[HISTORY_MAX_SIZE + 1]; /* history buffer */ +static int history_nr; /* saved history lines */ +static int history_cur; /* current pointer to history line */ + +static void term_config(void); +static void term_restore(void); +static void term_sig_handler(int sig); +static void term_init(char *out_cmd); +static void term_echo(void); +static void cursor_backward(void); +static void cursor_forward(void); +static void handle_backward(void); +static void handle_delete(void); +static void handle_tab(void); +static void handle_up(void); +static void handle_down(void); +static void handle_left(void); +static void handle_right(void); +static void handle_normal(char *out_cmd, char c); +static void handle_help(void); +static void prompt_print(void); +static void out_cmd_print(void); +static int history_prev(void); +static int history_next(void); +static void history_record(char *out_cmd); + + +struct key_bind_t +{ + int is_eseq; /*is escape sequence */ + int key_last; /*relative key or escape sequence last character */ + void (*func) (); +}; + +struct key_bind_t key_bind[] = +{ + {0, '\b', handle_backward}, + {0, 127, handle_delete}, + {0, '\t', handle_tab}, + {0, '?', handle_help}, + {1, 'A', handle_up}, + {1, 'B', handle_down}, + {1, 'C', handle_right}, + {1, 'D', handle_left}, +}; + +/* saving orignal setting and set new attrib to terminal*/ +static void +term_config(void) +{ + struct termios term_tmp; + tcgetattr(0, (void *) &term_save); + memcpy(&term_tmp, &term_save, sizeof (struct termios)); + + /*unbuffered input and turn off echo */ + term_tmp.c_lflag &= ~(ICANON | ECHO | ECHONL); + + tcsetattr(0, TCSANOW, (void *) &term_tmp); +} + +/*restore termial setting*/ +static void +term_restore(void) +{ + tcsetattr(0, TCSANOW, (void *) &term_save); +} + +/*termial signal handler*/ +static void +term_sig_handler(int sig) +{ + switch (sig) + { + case SIGINT: + if (cmd_promptp) + printf("\n%s", cmd_promptp); + + while (cmd_strlen-- > 0) + cmd_strp[cmd_strlen] = '\0'; + + cmd_strp[0] = '\0'; + cmd_strlen = 0; + if (cmd_promptp) + term_cursor = strlen(cmd_promptp); + cmd_cursor = 0; + + fflush(stdout); + + break; + + case SIGUSR1: + case SIGKILL: + case SIGABRT: + case SIGTERM: + case SIGHUP: + printf("exit.\n"); + term_restore(); + exit(0); + default: + break; + } +} + +/*termial initial*/ +static void +term_init(char *out_cmd) +{ + term_cursor = 0; + cmd_cursor = 0; + + cmd_strp = out_cmd; + cmd_strlen = strlen(out_cmd); + + // Initialize signal + signal(SIGINT, term_sig_handler); + signal(SIGUSR1, term_sig_handler); + signal(SIGKILL, term_sig_handler); + signal(SIGABRT, term_sig_handler); + signal(SIGTERM, term_sig_handler); + signal(SIGHUP, term_sig_handler); + //signal(SIGQUIT, SIG_IGN); + + prompt_print(); +} + +/* printf current char*/ +static void +term_echo(void) +{ + + if (cmd_strp[cmd_cursor]) + { + putchar(cmd_strp[cmd_cursor]); + } + else + { + putchar(' '); + } + + fflush(stdout); + term_cursor++; + cmd_cursor++; +} + +/* cursor move back one character */ +static void +cursor_backward(void) +{ + if (cmd_cursor > 0 && term_cursor > 0) + { + cmd_cursor--; + term_cursor--; + putchar('\b'); + fflush(stdout); + } +} + +/* cursor move forward one character */ +static void +cursor_forward(void) +{ + if (cmd_cursor < cmd_strlen) + term_echo(); +} + +/* move backward one characters. */ +static void +handle_backward(void) +{ + if (cmd_cursor > 0) + { + cursor_backward(); + handle_delete(); + } +} + +/*delete one character in front of cursor */ +static void +handle_delete(void) +{ + int cur_tmp = cmd_cursor; + + /*when cursour at the end of string */ + if (cmd_cursor >= cmd_strlen) + return; + + /*delete one character from string */ + strlcpy(cmd_strp + cur_tmp, cmd_strp + cur_tmp + 1, CMDSTR_BUF_SIZE - cur_tmp); + cmd_strlen--; + + /*clear characters after cursor */ + printf("\033[J"); + + /*re-print from delete position */ + while (cmd_cursor <= cmd_strlen) + term_echo(); + + /*move cursor back to delete position */ + cur_tmp = cmd_cursor - cur_tmp; + while (cur_tmp--) + cursor_backward(); +} + +/* deal with up arrow*/ +static void +handle_up(void) +{ + /*get previous history */ + if (history_prev() < 0) + return; + + /*copy current history cmd to out_cmd */ + strlcpy(cmd_strp, history_buf[history_cur], CMDSTR_BUF_SIZE); + + /*print out_cmd */ + out_cmd_print(); +} + +/* deal with down arrow*/ +static void +handle_down(void) +{ + /*get previous history */ + if (history_next() < 0) + return; + + /*copy current history cmd to out_cmd */ + strlcpy(cmd_strp, history_buf[history_cur], CMDSTR_BUF_SIZE); + + /*print out_cmd */ + out_cmd_print(); +} + +/* deal with left arrow*/ +static void +handle_left(void) +{ + cursor_backward(); +} + +/* deal with right arrow*/ +static void +handle_right(void) +{ + cursor_forward(); +} + +static void +print_cmd_all (void) +{ + int cmd_no = 0; + for (cmd_no = 0; GCMD_DESC_VALID(cmd_no); cmd_no++) + { + if (!GCMD_NAME(cmd_no)) + continue; + + printf("%-10s%s\n", GCMD_NAME(cmd_no), GCMD_MEMO(cmd_no)); + } +} + + +static void +print_sub_all (int cmd_id) +{ + int cmd_sub_no = 0, cmd_sub_nr = 0; + for (cmd_sub_no = 0; GCMD_SUB_DESC_VALID(cmd_id, cmd_sub_no); cmd_sub_no++) + { + + if (!GCMD_SUB_NAME(cmd_id, cmd_sub_no)) + continue; + if(cmd_sub_no == 0 || strcasecmp(GCMD_SUB_NAME(cmd_id, cmd_sub_no), + GCMD_SUB_NAME(cmd_id, cmd_sub_no-1))) + { + printf("%-10s\t", GCMD_SUB_NAME(cmd_id, cmd_sub_no)); + if(cmd_sub_nr && !((cmd_sub_nr+1) %5)) + { + printf("\n"); + } + cmd_sub_nr++; + } + } + printf("\n"); +} + +/* +1. partly_cmd_nr = 0 && index = no match: none +2. partly_cmd_nr = 0 && index = matched: full matched +3. partly_cmd_nr = 1 && index = matched: partly matched & to be completed +4. partly_cmd_nr > 1 && index = matched: partly matched & to be list them +*/ +#define NONE_MATCHED(pmatch_nr, pmatch_id) ( (pmatch_nr == 0) && (pmatch_id == GCMD_DESC_NO_MATCH) ) +#define FULL_MATCHED(pmatch_nr, pmatch_id) ( (pmatch_nr == 0) && (pmatch_id != GCMD_DESC_NO_MATCH) ) +#define ONE_PART_MATCHED(pmatch_nr, pmatch_id) ( (pmatch_nr == 1) && (pmatch_id != GCMD_DESC_NO_MATCH) ) +#define MULTI_PART_MATCHED(pmatch_nr, pmatch_id) ( (pmatch_nr > 1 ) && (pmatch_id != GCMD_DESC_NO_MATCH) ) + + +static int +search_cmd_type(char *name, int *pmatch_id, int is_print) +{ + int cmd_no = 0, pmatch_nr = 0; + + *pmatch_id = GCMD_DESC_NO_MATCH; + + /*search type in glb_num_types print matched */ + for (cmd_no = 0; GCMD_DESC_VALID(cmd_no); cmd_no++) + { + + if (!GCMD_NAME(cmd_no)) + continue; + + if (!strcasecmp(name, GCMD_NAME(cmd_no))) + { + /*full matched */ + *pmatch_id = cmd_no; + break; + } + else if (!strncasecmp(name, GCMD_NAME(cmd_no), strlen(name))) + { + /*partly matched */ + printc(is_print, "%-10s%s\n", GCMD_NAME(cmd_no), GCMD_MEMO(cmd_no)); + pmatch_nr++; + *pmatch_id = cmd_no; + } + } + + return pmatch_nr; +} + +static int +search_cmd_sub(int cmd_id, int *pmatch_sub_id, char *sub_name, int is_print) +{ + + int cmd_sub_no, pmatch_sub_nr = 0, fmatch_sub_save = GCMD_DESC_NO_MATCH; + + *pmatch_sub_id = GCMD_DESC_NO_MATCH; + + /*search for full matched */ + for (cmd_sub_no = 0; GCMD_SUB_DESC_VALID(cmd_id, cmd_sub_no); cmd_sub_no++) + { + if (!GCMD_SUB_NAME(cmd_id, cmd_sub_no)) + continue; + + if (!strcasecmp(sub_name, GCMD_SUB_NAME(cmd_id, cmd_sub_no))) + { + /*full matched */ + printc(is_print, "%-10s\t%s\n", GCMD_SUB_ACT(cmd_id, cmd_sub_no), GCMD_SUB_MEMO(cmd_id, cmd_sub_no)); + //*pmatch_sub_id = cmd_sub_no; + if(fmatch_sub_save == GCMD_DESC_NO_MATCH) + { + *pmatch_sub_id = fmatch_sub_save = cmd_sub_no; + } + + } + else if (!strncasecmp(sub_name, GCMD_SUB_NAME(cmd_id, cmd_sub_no), strlen(sub_name))) + { + if(fmatch_sub_save != GCMD_DESC_NO_MATCH) + continue; + + /*partly matched */ + if (*pmatch_sub_id == GCMD_DESC_NO_MATCH || (GCMD_SUB_NAME(cmd_id, cmd_sub_no-1) && + strcasecmp(GCMD_SUB_NAME(cmd_id, cmd_sub_no), GCMD_SUB_NAME(cmd_id, cmd_sub_no-1)))) + { + printc(is_print, "%-10s\t", GCMD_SUB_NAME(cmd_id, cmd_sub_no)); + pmatch_sub_nr++; + *pmatch_sub_id = cmd_sub_no; + } + } + } + + if (pmatch_sub_nr > 1) + printc(is_print, "\n"); + + return pmatch_sub_nr; +} + +static int +search_cmd_action(int cmd_id, int *pmatch_act_id, char *sub_name, char *action, int is_print) +{ + int cmd_act_no = 0, pmatch_act_nr = 0; + + *pmatch_act_id = GCMD_DESC_NO_MATCH; + + /*search for full matched */ + for (cmd_act_no = 0; GCMD_SUB_DESC_VALID(cmd_id, cmd_act_no); cmd_act_no++) + { + + if (strcasecmp(sub_name, GCMD_SUB_NAME(cmd_id, cmd_act_no))) + continue; + + if (!GCMD_SUB_ACT(cmd_id, cmd_act_no)) + continue; + + if (!strcasecmp(action, GCMD_SUB_ACT(cmd_id, cmd_act_no))) + { + /*full matched */ + if (*pmatch_act_id == GCMD_DESC_NO_MATCH) + { + printc(is_print, "%-10s\n", GCMD_SUB_USAGE(cmd_id, cmd_act_no)); + } + + *pmatch_act_id = cmd_act_no; + break; + } + else if (!strncasecmp(action, GCMD_SUB_ACT(cmd_id, cmd_act_no), strlen(action))) + { + /*partly matched */ + if (*pmatch_act_id == GCMD_DESC_NO_MATCH ||( GCMD_SUB_ACT(cmd_id, cmd_act_no-1) && + strcasecmp(GCMD_SUB_ACT(cmd_id, cmd_act_no), GCMD_SUB_ACT(cmd_id, cmd_act_no-1)))) + { + printc(is_print, "%-10s\t%s\n", GCMD_SUB_ACT(cmd_id, cmd_act_no), GCMD_SUB_MEMO(cmd_id, cmd_act_no)); + pmatch_act_nr++; + *pmatch_act_id = cmd_act_no; + } + } + } + + return pmatch_act_nr; +} + +/*print help info*/ +static void +handle_help(void) +{ + int pmatch_id = GCMD_DESC_NO_MATCH, pmatch_sub_id = GCMD_DESC_NO_MATCH, pmatch_act_id = GCMD_DESC_NO_MATCH; + int cmd_nr = 0, pmatch_nr = 0, pmatch_sub_nr = 0; + char *tmp_str[3], *cmd_strp_cp = strdup(cmd_strp), *str_save; + + if (!cmd_strp_cp) + return; + + cmd_strp_cp[strlen(cmd_strp) - 1] = '\0'; + + /* split command string into temp array */ + tmp_str[cmd_nr] = (void *) strtok_r(cmd_strp_cp, " ", &str_save); + + while (tmp_str[cmd_nr]) + { + if (++cmd_nr == 3) + break; + tmp_str[cmd_nr] = (void *) strtok_r(NULL, " ", &str_save); + } + + /*echo input ? */ + printf("?\n"); + + int is_print = 0; + + /* print matched command */ + switch (cmd_nr) + { + case 3: + pmatch_nr = search_cmd_type(tmp_str[0], &pmatch_id, is_print); + if(FULL_MATCHED(pmatch_nr, pmatch_id)) + pmatch_sub_nr = search_cmd_sub(pmatch_id, &pmatch_sub_id, tmp_str[1], is_print); + + if(FULL_MATCHED(pmatch_sub_nr, pmatch_sub_id)) + { + is_print = 1; + search_cmd_action(pmatch_id, &pmatch_act_id, tmp_str[1], tmp_str[2], is_print); + } + break; + + case 2: + pmatch_nr = search_cmd_type(tmp_str[0], &pmatch_id, is_print); + if(FULL_MATCHED(pmatch_nr, pmatch_id)) + { + is_print = 1; + search_cmd_sub(pmatch_id, &pmatch_sub_id, tmp_str[1], is_print); + } + break; + + case 1: + is_print = 1; + pmatch_nr = search_cmd_type(tmp_str[0], &pmatch_id, is_print); + + if(NONE_MATCHED(pmatch_nr, pmatch_id)) + { + print_cmd_all(); + } + else if(FULL_MATCHED(pmatch_nr, pmatch_id)) + { + print_sub_all(pmatch_id); + } + break; + + case 0: + print_cmd_all(); + break; + + default: + break; + } + + printf("\n"); + + /* re-print prompt */ + prompt_print(); + + /* re-print from cursor */ + while (cmd_cursor < cmd_strlen) + term_echo(); + + if(cmd_strp_cp) + free(cmd_strp_cp); +} + +static void +_cmd_complete(char *matchBuf, char *fullName) +{ + //printf ("***%s-%s****", matchBuf, fullName); + int offset = cmd_strlen - cmd_cursor; + int diff = strlen(fullName) - strlen(matchBuf);; + + /*print prompt */ + if (cmd_promptp) + printf("\n%s", cmd_promptp); + + /*give position to new char */ + memmove(cmd_strp + cmd_cursor + diff, cmd_strp + cmd_cursor, offset); + /*insert new char */ + if (cmd_promptp) + memcpy(cmd_strp + cmd_cursor, fullName + strlen(matchBuf), diff); + else + memcpy(cmd_strp + cmd_cursor, fullName, diff); + /*caculate new cursor */ + cmd_cursor += diff; + + /*set new cursor and len */ + cmd_strlen = strlen(cmd_strp); + if (cmd_promptp) + term_cursor = cmd_strlen + strlen(cmd_promptp); + else + term_cursor = cmd_strlen; + + /*re-print command */ + printf("%s", cmd_strp); + + /*set terminal cursor */ + if (cmd_strlen - cmd_cursor) + printf("\033[%dD", cmd_strlen - cmd_cursor); /*move cursor left */ +} + +void _cursor_recover(void) +{ + if(strlen(cmd_strp) != cmd_cursor) + { + int clear = strlen(cmd_strp) - cmd_cursor; + while(clear--) + { + printf("\b"); + } + } +} + +/* deal with tab completion*/ +#define MATCH_BUF_MAX 100 +static void +handle_tab(void) +{ + + int cmd_nr = 0; + char matchBuf[MATCH_BUF_MAX]; + char *tmp_str[3], *str_save; + + memset(matchBuf, 0, MATCH_BUF_MAX); + + if(cmd_cursor < MATCH_BUF_MAX) + strlcpy(matchBuf, cmd_strp, cmd_cursor+1); + else + strlcpy(matchBuf, cmd_strp, MATCH_BUF_MAX); + + printf("\n"); + + /* split command string into temp array */ + tmp_str[cmd_nr] = (void *) strtok_r(matchBuf, " ", &str_save); + + if(!tmp_str[cmd_nr]) + { + print_cmd_all(); + if (cmd_promptp) + printf("\n%s%s", cmd_promptp, cmd_strp); + fflush(stdout); + _cursor_recover(); + return; + } + + while (tmp_str[cmd_nr]) + { + if (++cmd_nr == 3) + break; + tmp_str[cmd_nr] = (void *) strtok_r(NULL, " ", &str_save); + } + + int is_print = 1, is_completed = 0; + int pmatch_nr = 0, pmatch_id = GCMD_DESC_NO_MATCH; + + pmatch_nr = search_cmd_type(tmp_str[0], &pmatch_id, is_print); + + if (cmd_nr == 1) + { + if (ONE_PART_MATCHED(pmatch_nr, pmatch_id)) + { + _cmd_complete(tmp_str[0], GCMD_NAME(pmatch_id)); + is_completed = 1; + } + + if(NONE_MATCHED(pmatch_nr, pmatch_id)) + { + print_cmd_all(); + + } + else if(FULL_MATCHED(pmatch_nr, pmatch_id)) + { + print_sub_all(pmatch_id); + } + + } + else + { + if (FULL_MATCHED(pmatch_nr, pmatch_id)) + { + + int pmatch_sub_nr = 0, pmatch_sub_id = GCMD_DESC_NO_MATCH; + + if(cmd_nr == 3) is_print = 0; + pmatch_sub_nr = search_cmd_sub(pmatch_id, &pmatch_sub_id, tmp_str[1], is_print); + + if(cmd_nr == 2) + { + if (ONE_PART_MATCHED(pmatch_sub_nr, pmatch_sub_id)) + { + _cmd_complete(tmp_str[1], GCMD_SUB_NAME(pmatch_id, pmatch_sub_id)); + is_completed = 1; + } + + } + else + { + int pmatch_act_nr = 0, pmatch_act_id = GCMD_DESC_NO_MATCH; + pmatch_act_nr = search_cmd_action(pmatch_id, &pmatch_act_id, tmp_str[1], tmp_str[2], is_print); + + if (ONE_PART_MATCHED(pmatch_act_nr, pmatch_act_id)) + { + _cmd_complete(tmp_str[2], GCMD_SUB_ACT(pmatch_id, pmatch_act_id)); + is_completed = 1; + + } + else if (FULL_MATCHED(pmatch_act_nr, pmatch_act_id)) + { + is_print = 1; + printc(is_print, "%-10s\n", GCMD_SUB_USAGE(pmatch_id, pmatch_act_id)); + } + } + } + } + + if (is_completed == 0) + { + /*re-echo */ + if (cmd_promptp) + printf("\n%s%s", cmd_promptp, cmd_strp); + fflush(stdout); + _cursor_recover(); + } + //_cursor_recover(); +} + +/*deal with normal character*/ +static void +handle_normal(char *out_cmd, char c) +{ + int tmp_cursor = cmd_cursor; + + /*buffer full */ + if (++cmd_strlen > (MATCH_BUF_MAX - 2)) + return; + + /*append operation */ + if (cmd_cursor == (cmd_strlen - 1)) + { + *(out_cmd + cmd_cursor) = c; + *(out_cmd + cmd_cursor + 1) = 0; + term_echo(); + } + else + { + /* Insert operation */ + /*give position to new char */ + memmove(out_cmd + tmp_cursor + 1, out_cmd + tmp_cursor, + cmd_strlen - tmp_cursor); + *(out_cmd + tmp_cursor) = c; + + /* re-print from cursor */ + while (cmd_cursor < cmd_strlen) + term_echo(); + + /* restore curor to insert position */ + tmp_cursor = cmd_cursor - tmp_cursor - 1; + while (tmp_cursor--) + cursor_backward(); + } +} + +/*print prompt info*/ +static void +prompt_print(void) +{ + if (cmd_promptp) + { + printf("%s", cmd_promptp); + } + + if (cmd_promptp) + { + term_cursor = strlen(cmd_promptp); + } + cmd_cursor = 0; + fflush(stdout); +} + +/*print current output command*/ +static void +out_cmd_print(void) +{ + cmd_strlen = strlen(history_buf[history_cur]); + + putchar('\r'); + prompt_print(); + + while (cmd_cursor < cmd_strlen) + term_echo(); + + /*clear characters after cursor */ + printf("\033[J"); + +} + +/* get previous history command*/ +static int +history_prev(void) +{ + if (history_cur > 0) + { + /*record current*/ + if (cmd_strp[0] != 0 || history_buf[history_cur] == 0) + { + if(history_buf[history_cur]) + free(history_buf[history_cur]); + history_buf[history_cur] = strdup(cmd_strp); + } + history_cur--; + return 0; + } + + return -1; +} + +/* get next history command*/ +static int +history_next(void) +{ + if ((history_cur >= 0) && (history_cur < history_nr)) + { + history_cur++; + return 0; + } + + return -1; +} + +/*record history command*/ +static void +history_record(char *out_cmd) +{ + int i; + + /* cleanup may be saved current command line */ + if (cmd_strlen > 0) /* no put empty line */ + { + i = history_nr; + + free(history_buf[HISTORY_MAX_SIZE]); + history_buf[HISTORY_MAX_SIZE] = 0; + /* After max history, remove the oldest command */ + if (i >= HISTORY_MAX_SIZE) + { + free(history_buf[0]); + for (i = 0; i < (HISTORY_MAX_SIZE - 1); i++) + history_buf[i] = history_buf[i + 1]; + } + history_buf[i++] = strdup(out_cmd); + history_cur = i; + history_nr = i; + } +} + +int +_isspace(int ch) +{ + return (unsigned int) (ch - 9) < 5u || ch == ' '; +} + +/*call by main*/ +int +next_cmd(char *out_cmd) +{ + unsigned char c = 0; + int key_no = 0; + int seq_char = 0; + int str_valid = 0; + + /*set terminal new attrib */ + term_config(); + + /*termial initial */ + term_init(out_cmd); + + /*main loop */ + while ((c = getc(stdin)) != '\n') + { + key_no = 0; + seq_char = 0; + + if (!_isspace(c)) + { + str_valid = 1; + } + + if (c == 27) /*escape sequence */ + { + if ((c = getc(stdin)) == '[' || c == 'O') + { + c = getc(stdin); + seq_char = 1; + } + } + + /*search for bind key handle function */ + while (key_no < sizeof (key_bind) / sizeof (key_bind[0])) + { + if ((seq_char == key_bind[key_no].is_eseq) + && (c == key_bind[key_no].key_last)) + { + key_bind[key_no].func(); + break; + } + key_no++; + } + + if (key_no == sizeof (key_bind) / sizeof (key_bind[0])) + handle_normal(out_cmd, c); + + } + + /*handle enter when at the end of a line */ + if (term_cursor) + putchar('\n'); + + /* record command history without '\n' */ + history_record(out_cmd); +#if 0 + /* add '\n' to out_cmd */ + if (str_valid) + { + out_cmd[cmd_strlen++] = '\n'; + } + else + { + cmd_strlen = 0; + out_cmd[cmd_strlen++] = '\n'; + } + + if (cmd_strlen > 1 && out_cmd[cmd_strlen - 1] == '\n') + out_cmd[cmd_strlen - 1] = 0; +#else + if (!str_valid) + cmd_strlen = 0; +#endif + /*retore terminal to orginal status */ + term_restore(); + + fflush(stdout); + + return cmd_strlen; +} diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/shell/shell_module_ctrl.c b/feeds/ipq807x/qca-ssdk-shell/src/src/shell/shell_module_ctrl.c new file mode 100755 index 000000000..e96f62432 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/shell/shell_module_ctrl.c @@ -0,0 +1,1069 @@ +/* + * 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. + */ +#include +#include "shell_io.h" +#include "shell.h" + +sw_error_t +cmd_data_check_func_ctrl(char *cmd_str, void * val, a_uint32_t size) +{ + sw_error_t rv; + fal_func_ctrl_t entry; + + aos_mem_zero(&entry, sizeof (fal_func_ctrl_t)); + + rv = __cmd_data_check_complex("bitmap0", "0", + "usage: the format is HEX \n", cmd_data_check_uint32, + &(entry.bitmap[0]), sizeof (a_uint32_t)); + if (rv) + return rv; + + rv = __cmd_data_check_complex("bitmap1", "0", + "usage: the format is HEX \n", cmd_data_check_uint32, + &(entry.bitmap[1]), sizeof (a_uint32_t)); + if (rv) + return rv; + + rv = __cmd_data_check_complex("bitmap2", "0", + "usage: the format is HEX \n", cmd_data_check_uint32, + &(entry.bitmap[2]), sizeof (a_uint32_t)); + if (rv) + return rv; + + *(fal_func_ctrl_t *)val = entry; + + return SW_OK; +} + + + +void +cmd_data_print_func_ctrl(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:", param_name); + + fal_func_ctrl_t *p = (fal_func_ctrl_t *) buf; + + dprintf("%08x %08x %08x\n", p->bitmap[0], p->bitmap[1], p->bitmap[2]); +} + + +sw_error_t +cmd_data_check_module(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size) +{ + if (cmd_str == NULL) + return SW_BAD_PARAM; + + if (!strcasecmp(cmd_str, "acl")){ + *arg_val = FAL_MODULE_ACL; + } else if (!strcasecmp(cmd_str, "vsi")) { + *arg_val = FAL_MODULE_VSI; + } else if (!strcasecmp(cmd_str, "ip")) { + *arg_val = FAL_MODULE_IP; + } else if (!strcasecmp(cmd_str, "flow")) { + *arg_val = FAL_MODULE_FLOW; + } else if (!strcasecmp(cmd_str, "qm")) { + *arg_val = FAL_MODULE_QM; + } else if (!strcasecmp(cmd_str, "qos")) { + *arg_val = FAL_MODULE_QOS; + } else if (!strcasecmp(cmd_str, "bm")) { + *arg_val = FAL_MODULE_BM; + } else if (!strcasecmp(cmd_str, "servcode")) { + *arg_val = FAL_MODULE_SERVCODE; + } else if (!strcasecmp(cmd_str, "rsshash")) { + *arg_val = FAL_MODULE_RSS_HASH; + } else if (!strcasecmp(cmd_str, "pppoe")) { + *arg_val = FAL_MODULE_PPPOE; + } else if (!strcasecmp(cmd_str, "portctrl")) { + *arg_val = FAL_MODULE_PORTCTRL; + } else if (!strcasecmp(cmd_str, "shaper")) { + *arg_val = FAL_MODULE_SHAPER; + } else if (!strcasecmp(cmd_str, "mib")){ + *arg_val = FAL_MODULE_MIB; + } else if (!strcasecmp(cmd_str, "mirror")){ + *arg_val = FAL_MODULE_MIRROR; + } else if (!strcasecmp(cmd_str, "fdb")){ + *arg_val = FAL_MODULE_FDB; + } else if (!strcasecmp(cmd_str, "stp")){ + *arg_val = FAL_MODULE_STP; + } else if (!strcasecmp(cmd_str, "sec")){ + *arg_val = FAL_MODULE_SEC; + } else if (!strcasecmp(cmd_str, "trunk")){ + *arg_val = FAL_MODULE_TRUNK; + } else if (!strcasecmp(cmd_str, "portvlan")){ + *arg_val = FAL_MODULE_PORTVLAN; + } else if (!strcasecmp(cmd_str, "ctrlpkt")){ + *arg_val = FAL_MODULE_CTRLPKT; + } else if (!strcasecmp(cmd_str, "policer")){ + *arg_val = FAL_MODULE_POLICER; + } + else + { + return SW_BAD_VALUE; + } + + return SW_OK; +} + +void +cmd_data_print_module(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size) +{ + dprintf("[%s]:", param_name); + + if (*(a_uint32_t *) buf == FAL_MODULE_ACL){ + dprintf("acl"); + } else if (*(a_uint32_t *) buf == FAL_MODULE_VSI) { + dprintf("vsi"); + }else if (*(a_uint32_t *) buf == FAL_MODULE_IP) { + dprintf("ip"); + } else if (*(a_uint32_t *) buf == FAL_MODULE_FLOW) { + dprintf("flow"); + } else if (*(a_uint32_t *) buf == FAL_MODULE_QM) { + dprintf("qm"); + } else if (*(a_uint32_t *) buf == FAL_MODULE_QOS) { + dprintf("qos"); + } else if (*(a_uint32_t *) buf == FAL_MODULE_BM) { + dprintf("bm"); + } else if (*(a_uint32_t *) buf == FAL_MODULE_SERVCODE) { + dprintf("servcode"); + } else if (*(a_uint32_t *) buf == FAL_MODULE_RSS_HASH) { + dprintf("rsshash"); + } else if (*(a_uint32_t *) buf == FAL_MODULE_PPPOE) { + dprintf("pppoe"); + } else if (*(a_uint32_t *) buf == FAL_MODULE_PORTCTRL) { + dprintf("portctrl"); + } else if (*(a_uint32_t *) buf == FAL_MODULE_SHAPER) { + dprintf("shaper"); + } else if (*(a_uint32_t *) buf == FAL_MODULE_MIB) { + dprintf("mib"); + } else if (*(a_uint32_t *) buf == FAL_MODULE_MIRROR) { + dprintf("mirror"); + } else if (*(a_uint32_t *) buf == FAL_MODULE_FDB) { + dprintf("fdb"); + } else if (*(a_uint32_t *) buf == FAL_MODULE_STP) { + dprintf("stp"); + } else if (*(a_uint32_t *) buf == FAL_MODULE_SEC) { + dprintf("sec"); + } else if (*(a_uint32_t *) buf == FAL_MODULE_TRUNK) { + dprintf("trunk"); + } else if (*(a_uint32_t *) buf == FAL_MODULE_PORTVLAN) { + dprintf("portvlan"); + } else if (*(a_uint32_t *) buf == FAL_MODULE_CTRLPKT) { + dprintf("ctrlpkt"); + } else if (*(a_uint32_t *) buf == FAL_MODULE_POLICER) { + dprintf("policer"); + } +} + +static void cmd_data_print_acl_func_ctrl(fal_func_ctrl_t *p) +{ + a_uint32_t func = 0; + char *func_name[FUNC_ACL_UDF_PROFILE_GET+1] ={ + "FUNC_ACL_LIST_CREAT", + "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" + }; + + for(func = FUNC_ACL_LIST_CREAT; func <= FUNC_ACL_UDF_PROFILE_GET; func++) + { + if(p->bitmap[0] & (1<bitmap[0] & (1<bitmap[0] & (1<bitmap[1] & (1 << (func % 32))) + dprintf("%d %s registered\n", func, func_name[func]); + else + dprintf("%d %s unregistered\n", func, func_name[func]); + return; +} + +static void cmd_data_print_flow_func_ctrl(fal_func_ctrl_t *p) +{ + a_uint32_t func = 0; + char *func_name[FUNC_FLOW_ENTRY_NEXT+1] ={ + "FUNC_FLOW_HOST_ADD", + "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" + }; + + for(func = FUNC_FLOW_HOST_ADD; func <= FUNC_FLOW_ENTRY_NEXT; func++) + { + if(p->bitmap[0] & (1 << func)) + { + dprintf("%d %s registered\n", func, func_name[func]); + } + else + { + dprintf("%d %s unregistered\n", func, func_name[func]); + } + } + return; +} + +static void cmd_data_print_mib_func_ctrl(fal_func_ctrl_t *p) +{ + a_uint32_t func = 0; + char *func_name[FUNC_MIB_CPUKEEP_GET+1] ={ + "FUNC_GET_MIB_INFO", + "FUNC_GET_RX_MIB_INFO", + "FUNC_GET_TX_MIB_INFO", + "FUNC_GET_XG_MIB_INFO", + "FUNC_GET_TX_XG_MIB_NFO", + "FUNC_GET_RX_XG_MIB_NFO", + "FUNC_MIB_STATUS_SET", + "FUNC_MIB_STATUS_GET", + "FUNC_MIB_PORT_FLUSH_COUNTERS", + "FUNC_MIB_CPUKEEP_SET", + "FUNC_MIB_CPUKEEP_GET", + }; + + for(func = FUNC_GET_MIB_INFO; func <= FUNC_MIB_CPUKEEP_GET; func++) + { + if(p->bitmap[0] & (1<bitmap[0] & (1 << func)) + { + dprintf("%d %s registered\n", func, func_name[func]); + } + else + { + dprintf("%d %s unregistered\n", func, func_name[func]); + } + } + return; +} + +static void cmd_data_print_qos_func_ctrl(fal_func_ctrl_t *p) +{ + a_uint32_t func = 0; + char *func_name[FUNC_QOS_PORT_SCHEDULER_RESOURCE_GET+1] ={ + "FUNC_QOS_PORT_PRI_SET", + "FUNC_QOS_PORT_PRI_GET", + "FUNC_QOS_COSMAP_PCP_GET", + "FUNC_QUEUE_SCHEDULER_SET", + "FUNC_QUEUE_SCHEDULER_GET", + "FUNC_PORT_QUEUES_GET", + "FUNC_QOS_COSMAP_PCP_SET", + "FUNC_QOS_PORT_REMARK_GET", + "FUNC_QOS_COSMAP_DSCP_GET", + "FUNC_QOS_COSMAP_FLOW_SET", + "FUNC_QOS_PORT_GROUP_SET", + "FUNC_RING_QUEUE_MAP_SET", + "FUNC_QOS_COSMAP_DSCP_SET", + "FUNC_QOS_PORT_REMARK_SET", + "FUNC_QOS_COSMAP_FLOW_GET", + "FUNC_QOS_PORT_GROUP_GET", + "FUNC_RING_QUEUE_MAP_GET", + "FUNC_TDM_TICK_NUM_SET", + "FUNC_TDM_TICK_NUM_GET", + "FUNC_PORT_SCHEDULER_CFG_SET", + "FUNC_PORT_SCHEDULER_CFG_GET", + "FUNC_SCHEDULER_DEQUEUE_CTRL_GET", + "FUNC_SCHEDULER_DEQUEUE_CTRL_SET", + "FUNC_QOS_PORT_MODE_PRI_GET", + "FUNC_QOS_PORT_MODE_PRI_SET", + "FUNC_QOS_PORT_SCHEDULER_CFG_RESET", + "FUNC_QOS_PORT_SCHEDULER_RESOURCE_GET" + }; + + for(func = FUNC_QOS_PORT_PRI_SET; func <= FUNC_QOS_PORT_SCHEDULER_CFG_RESET; func++) + { + if(p->bitmap[0] & (1 << func)) + { + dprintf("%d %s registered\n", func, func_name[func]); + } + else + { + dprintf("%d %s unregistered\n", func, func_name[func]); + } + } + return; +} + +static void cmd_data_print_bm_func_ctrl(fal_func_ctrl_t *p) +{ + a_uint32_t func = 0; + char *func_name[FUNC_BM_PORT_COUNTER_GET+1] ={ + "FUNC_PORT_BUFGROUP_MAP_GET", + "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" + }; + + for(func = FUNC_PORT_BUFGROUP_MAP_GET; func <= FUNC_BM_PORT_COUNTER_GET; func++) + { + if(p->bitmap[0] & (1 << func)) + { + dprintf("%d %s registered\n", func, func_name[func]); + } + else + { + dprintf("%d %s unregistered\n", func, func_name[func]); + } + } + return; +} + +static void cmd_data_print_servcode_func_ctrl(fal_func_ctrl_t *p) +{ + a_uint32_t func = 0; + char *func_name[FUNC_SERVCODE_LOOPCHECK_STATUS_GET+1] ={ + "FUNC_SERVCODE_CONFIG_SET", + "FUNC_SERVCODE_CONFIG_GET", + "FUNC_SERVCODE_LOOPCHECK_EN", + "FUNC_SERVCODE_LOOPCHECK_STATUS_GET", + }; + + for(func = FUNC_SERVCODE_CONFIG_SET; func <= FUNC_SERVCODE_LOOPCHECK_STATUS_GET; func++) + { + if(p->bitmap[0] & (1<bitmap[0] & (1<bitmap[0] & (1 << func)) + { + dprintf("%d %s registered\n", func, func_name[func]); + } + else + { + dprintf("%d %s unregistered\n", func, func_name[func]); + } + } + return; +} + +static void cmd_data_print_port_ctrl_func_ctrl(fal_func_ctrl_t *p) +{ + a_uint32_t func = 0; + char *func_name[FUNC_ADPT_PORT_FLOWCTRL_FORCEMODE_GET+1] ={ + "FUNC_ADPT_PORT_LOCAL_LOOPBACK_GET", + "FUNC_ADPT_PORT_AUTONEG_RESTART", + "FUNC_ADPT_PORT_DUPLEX_SET", + "FUNC_ADPT_PORT_RXMAC_STATUS_GET", + "FUNC_ADPT_PORT_CDT", + "FUNC_ADPT_PORT_TXMAC_STATUS_SET", + "FUNC_ADPT_PORT_COMBO_FIBER_MODE_SET", + "FUNC_ADPT_PORT_COMBO_MEDIUM_STATUS_GET", + "FUNC_ADPT_PORT_MAGIC_FRAME_MAC_SET", + "FUNC_ADPT_PORT_POWERSAVE_SET", + "FUNC_ADPT_PORT_HIBERNATE_SET", + "FUNC_ADPT_PORT_8023AZ_GET", + "FUNC_ADPT_PORT_RXFC_STATUS_GET", + "FUNC_ADPT_PORT_TXFC_STATUS_GET", + "FUNC_ADPT_PORT_REMOTE_LOOPBACK_SET", + "FUNC_ADPT_PORT_FLOWCTRL_SET", + "FUNC_ADPT_PORT_MRU_SET", + "FUNC_ADPT_PORT_AUTONEG_STATUS_GET", + "FUNC_ADPT_PORT_TXMAC_STATUS_GET", + "FUNC_ADPT_PORT_MDIX_GET", + "FUNC_ADPT_PORTS_LINK_STATUS_GET", + "FUNC_ADPT_PORT_MAC_LOOPBACK_SET", + "FUNC_ADPT_PORT_PHY_ID_GET", + "FUNC_ADPT_PORT_MRU_GET", + "FUNC_ADPT_PORT_POWER_ON", + "FUNC_ADPT_PORT_SPEED_SET", + "FUNC_ADPT_PORT_INTERFACE_MODE_GET", + "FUNC_ADPT_PORT_DUPLEX_GET", + "FUNC_ADPT_PORT_AUTONEG_ADV_GET", + "FUNC_ADPT_PORT_MDIX_STATUS_GET", + "FUNC_ADPT_PORT_MTU_SET", + "FUNC_ADPT_PORT_LINK_STATUS_GET", + + "FUNC_ADPT_PORT_8023AZ_SET", + "FUNC_ADPT_PORT_POWERSAVE_GET", + "FUNC_ADPT_PORT_COMBO_PREFER_MEDIUM_GET", + "FUNC_ADPT_PORT_COMBO_PREFER_MEDIUM_SET", + "FUNC_ADPT_PORT_POWER_OFF", + "FUNC_ADPT_PORT_TXFC_STATUS_SET", + "FUNC_ADPT_PORT_COUNTER_SET", + "FUNC_ADPT_PORT_COMBO_FIBER_MODE_GET", + "FUNC_ADPT_PORT_LOCAL_LOOPBACK_SET", + "FUNC_ADPT_PORT_WOL_STATUS_SET", + "FUNC_ADPT_PORT_MAGIC_FRAME_MAC_GET", + "FUNC_ADPT_PORT_FLOWCTRL_GET", + "FUNC_ADPT_PORT_RXMAC_STATUS_SET", + "FUNC_ADPT_PORT_COUNTER_GET", + "FUNC_ADPT_PORT_INTERFACE_MODE_SET", + "FUNC_ADPT_PORT_MAC_LOOPBACK_GET", + "FUNC_ADPT_PORT_HIBERNATE_GET", + "FUNC_ADPT_PORT_AUTONEG_ADV_SET", + "FUNC_ADPT_PORT_REMOTE_LOOPBACK_GET", + "FUNC_ADPT_PORT_COUNTER_SHOW", + "FUNC_ADPT_PORT_AUTONEG_ENABLE", + "FUNC_ADPT_PORT_MTU_GET", + "FUNC_ADPT_PORT_INTERFACE_MODE_STATUS_GET", + "FUNC_ADPT_PORT_RESET", + "FUNC_ADPT_PORT_RXFC_STATUS_SET", + "FUNC_ADPT_PORT_SPEED_GET", + "FUNC_ADPT_PORT_MDIX_SET", + "FUNC_ADPT_PORT_WOL_STATUS_GET", + "FUNC_ADPT_PORT_MAX_FRAME_SIZE_SET", + "FUNC_ADPT_PORT_MAX_FRAME_SIZE_GET", + "FUNC_ADPT_PORT_SOURCE_FILTER_GET", + "FUNC_ADPT_PORT_SOURCE_FILTER_SET", + + "FUNC_ADPT_PORT_INTERFACE_MODE_APPLY", + "FUNC_ADPT_PORT_INTERFACE_3AZ_STATUS_SET", + "FUNC_ADPT_PORT_INTERFACE_3AZ_STATUS_GET", + "FUNC_ADPT_PORT_PROMISC_MODE_SET", + "FUNC_ADPT_PORT_PROMISC_MODE_GET", + "FUNC_ADPT_PORT_FLOWCTRL_FORCEMODE_SET", + "FUNC_ADPT_PORT_FLOWCTRL_FORCEMODE_GET", + }; + + for(func = FUNC_ADPT_PORT_LOCAL_LOOPBACK_GET; func <= FUNC_ADPT_PORT_LINK_STATUS_GET; func++) + { + if(p->bitmap[0] & (1<bitmap[1] & (1<< (func % 32))) + { + dprintf("%d %s registered\n", func, func_name[func]); + } + else + { + dprintf("%d %s unregistered\n", func, func_name[func]); + } + } + + for(func = FUNC_ADPT_PORT_INTERFACE_MODE_APPLY; func <= FUNC_ADPT_PORT_FLOWCTRL_FORCEMODE_GET; func++) + { + if(p->bitmap[2] & (1<<(func % 32))) + { + dprintf("%d %s registered\n", func, func_name[func]); + } + else + { + dprintf("%d %s unregistered\n", func, func_name[func]); + } + } + + return; +} + +static void cmd_data_print_shaper_func_ctrl(fal_func_ctrl_t *p) +{ + a_uint32_t func = 0; + char *func_name[FUNC_ADPT_SHAPER_IPG_PREAMBLE_LENGTH_GET+1] ={ + "FUNC_ADPT_FLOW_SHAPER_SET", + "FUNC_ADPT_QUEUE_SHAPER_GET", + "FUNC_ADPT_QUEUE_SHAPER_TOKEN_NUMBER_SET", + "FUNC_ADPT_PORT_SHAPER_GET", + "FUNC_ADPT_FLOW_SHAPER_TIME_SLOT_GET", + "FUNC_ADPT_PORT_SHAPER_TIME_SLOT_GET", + "FUNC_ADPT_FLOW_SHAPER_TIME_SLOT_SET", + "FUNC_ADPT_PORT_SHAPER_TOKEN_NUMBER_SET", + "FUNC_ADPT_QUEUE_SHAPER_TOKEN_NUMBER_GET", + "FUNC_ADPT_QUEUE_SHAPER_TIME_SLOT_GET", + "FUNC_ADPT_PORT_SHAPER_TOKEN_NUMBER_GET", + "FUNC_ADPT_FLOW_SHAPER_TOKEN_NUMBER_SET", + "FUNC_ADPT_FLOW_SHAPER_TOKEN_NUMBER_GET", + "FUNC_ADPT_PORT_SHAPER_SET", + "FUNC_ADPT_PORT_SHAPER_TIME_SLOT_SET", + "FUNC_ADPT_FLOW_SHAPER_GET", + "FUNC_ADPT_QUEUE_SHAPER_SET", + "FUNC_ADPT_QUEUE_SHAPER_TIME_SLOT_SET", + "FUNC_ADPT_SHAPER_IPG_PREAMBLE_LENGTH_SET", + "FUNC_ADPT_SHAPER_IPG_PREAMBLE_LENGTH_GET", + + }; + + for(func = FUNC_ADPT_FLOW_SHAPER_SET; func <= FUNC_ADPT_SHAPER_IPG_PREAMBLE_LENGTH_GET; func++) + { + if(p->bitmap[0] & (1<bitmap[0] & (1<bitmap[0] & (1<bitmap[1] & (1<<(func % 32))) + { + dprintf("%d %s registered\n", func, func_name[func]); + } + else + { + dprintf("%d %s unregistered\n", func, func_name[func]); + } + } + + return; +} + +static void cmd_data_print_stp_func_ctrl(fal_func_ctrl_t *p) +{ + a_uint32_t func = 0; + char *func_name[FUNC_STP_PORT_STATE_GET+1] ={ + "FUNC_STP_PORT_STATE_SET", + "FUNC_STP_PORT_STATE_GET" + }; + + for(func = FUNC_STP_PORT_STATE_SET; func <= FUNC_STP_PORT_STATE_GET; func++) + { + if (p->bitmap[0] & (1<bitmap[0] & (1<bitmap[0] & (1<bitmap[0] & (1<bitmap[1] & (1<<(func % 32))) + { + dprintf("%d %s registered\n", func, func_name[func]); + } + else + { + dprintf("%d %s unregistered\n", func, func_name[func]); + } + } + return; +} + +static void cmd_data_print_ctrlpkt_func_ctrl(fal_func_ctrl_t *p) +{ + a_uint32_t func = 0; + char *func_name[FUNC_MGMTCTRL_CTRLPKT_PROFILE_GETNEXT+1] ={ + "FUNC_MGMTCTRL_ETHTYPE_PROFILE_SET", + "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" + }; + + for(func = FUNC_MGMTCTRL_ETHTYPE_PROFILE_SET; func <= FUNC_MGMTCTRL_CTRLPKT_PROFILE_GETNEXT; func++) + { + if (p->bitmap[0] & (1<bitmap[0] & (1< +#include "shell.h" +#include "fal.h" + +static int sw_devid = 0; + +sw_error_t +cmd_set_devid(a_ulong_t *arg_val) +{ + sw_error_t rtn; + ssdk_cfg_t ssdk_cfg_new; + + if (arg_val[1] >= SW_MAX_NR_DEV) + { + dprintf("dev_id should be less than <%d>\n", SW_MAX_NR_DEV); + return SW_FAIL; + } + sw_devid = arg_val[1]; + + rtn = fal_ssdk_cfg(sw_devid, &ssdk_cfg_new); + if (rtn == SW_OK) + { + ssdk_cfg = ssdk_cfg_new; + } + + return rtn; +} + +int +get_devid(void) +{ + return sw_devid; +} + +int +set_devid(int dev_id) +{ + sw_devid = dev_id; + return SW_OK; +} +/*qca808x_end*/ +sw_error_t +cmd_show_fdb(a_ulong_t *arg_val) +{ + if (ssdk_cfg.init_cfg.chip_type == CHIP_ISIS) { + sw_error_t rtn; + a_uint32_t cnt = 0; + fal_fdb_op_t *fdb_op = (fal_fdb_op_t *) (ioctl_buf + sizeof(sw_error_t) / 4); + fal_fdb_entry_t *fdb_entry = (fal_fdb_entry_t *) (ioctl_buf + sizeof(sw_error_t) / 4 + sizeof(fal_fdb_op_t) / 4); + + aos_mem_zero(fdb_op, sizeof (fal_fdb_op_t)); + aos_mem_zero(fdb_entry, sizeof (fal_fdb_entry_t)); + arg_val[0] = SW_API_FDB_EXTEND_FIRST; + + while (1) + { + arg_val[1] = (a_ulong_t) ioctl_buf; + arg_val[2] = get_devid(); + arg_val[3] = (a_ulong_t) fdb_op; + arg_val[4] = (a_ulong_t) fdb_entry; + + rtn = cmd_exec_api(arg_val); + if ((SW_OK != rtn) || (SW_OK != (sw_error_t) (*ioctl_buf))) + { + break; + } + arg_val[0] = SW_API_FDB_EXTEND_NEXT; + cnt++; + } + + if((rtn != SW_OK) && (rtn != SW_NO_MORE)) + cmd_print_error(rtn); + else + dprintf("\ntotal %d entries\n", cnt); + }else if ((ssdk_cfg.init_cfg.chip_type == CHIP_ISISC) || + (ssdk_cfg.init_cfg.chip_type == CHIP_DESS) || + (ssdk_cfg.init_cfg.chip_type == CHIP_HPPE)) { + sw_error_t rtn; + a_uint32_t cnt = 0; + fal_fdb_op_t *fdb_op = (fal_fdb_op_t *) (ioctl_buf + sizeof(sw_error_t) / 4); + fal_fdb_entry_t *fdb_entry = (fal_fdb_entry_t *) (ioctl_buf + sizeof(sw_error_t) / 4 + sizeof(fal_fdb_op_t) / 4); + + aos_mem_zero(fdb_op, sizeof (fal_fdb_op_t)); + aos_mem_zero(fdb_entry, sizeof (fal_fdb_entry_t)); + arg_val[0] = SW_API_FDB_EXTEND_FIRST; + + while (1) + { + arg_val[1] = (a_ulong_t) ioctl_buf; + arg_val[2] = get_devid(); + arg_val[3] = (a_ulong_t) fdb_op; + arg_val[4] = (a_ulong_t) fdb_entry; + + rtn = cmd_exec_api(arg_val); + if ((SW_OK != rtn) || (SW_OK != (sw_error_t) (*ioctl_buf))) + { + break; + } + arg_val[0] = SW_API_FDB_EXTEND_NEXT; + cnt++; + } + + if((rtn != SW_OK) && (rtn != SW_NO_MORE)) + cmd_print_error(rtn); + else + dprintf("\ntotal %d entries\n", cnt); + }else if (ssdk_cfg.init_cfg.chip_type == CHIP_SHIVA) { + sw_error_t rtn; + a_uint32_t cnt = 0; + fal_fdb_entry_t *fdb_entry = (fal_fdb_entry_t *) (ioctl_buf + 2); + + memset(fdb_entry, 0, sizeof (fal_fdb_entry_t)); + arg_val[0] = SW_API_FDB_ITERATE; + *(ioctl_buf + 1) = 0; + + while (1) + { + arg_val[1] = (a_ulong_t) ioctl_buf; + arg_val[2] = get_devid(); + arg_val[3] = (a_ulong_t) (ioctl_buf + 1); + arg_val[4] = (a_ulong_t) fdb_entry; + + rtn = cmd_exec_api(arg_val); + if ((SW_OK != rtn) || (SW_OK != (sw_error_t) (*ioctl_buf))) + { + break; + } + cnt++; + } + + if((rtn != SW_OK) && (rtn != SW_NO_MORE)) + cmd_print_error(rtn); + else + dprintf("\ntotal %d entries\n", cnt); + }else { + sw_error_t rtn; + a_uint32_t rtn_size = 1, cnt = 0; + fal_fdb_entry_t *fdb_entry = (fal_fdb_entry_t *) (ioctl_buf + rtn_size); + + memset(fdb_entry, 0, sizeof (fal_fdb_entry_t)); + arg_val[0] = SW_API_FDB_FIRST; + + while (1) + { + arg_val[1] = (a_ulong_t) ioctl_buf; + arg_val[2] = get_devid(); + arg_val[3] = (a_ulong_t) fdb_entry; + + rtn = cmd_exec_api(arg_val); + if ((SW_OK != rtn) || (SW_OK != (sw_error_t) (*ioctl_buf))) + { + break; + } + arg_val[0] = SW_API_FDB_NEXT; + cnt++; + } + + if((rtn != SW_OK) && (rtn != SW_NO_MORE)) + cmd_print_error(rtn); + else + dprintf("\ntotal %d entries\n", cnt); + } + + return SW_OK; +} + +sw_error_t +cmd_show_ctrlpkt(a_ulong_t *arg_val) +{ + sw_error_t rtn; + a_uint32_t cnt = 0; + fal_ctrlpkt_profile_t *ctrlpkt = (fal_ctrlpkt_profile_t *) (ioctl_buf + sizeof(sw_error_t) / 4); + + aos_mem_zero(ctrlpkt, sizeof (fal_ctrlpkt_profile_t)); + arg_val[0] = SW_API_MGMTCTRL_CTRLPKT_PROFILE_GETFIRST; + + while (1) + { + arg_val[1] = (a_ulong_t) ioctl_buf; + arg_val[2] = get_devid(); + arg_val[3] = (a_ulong_t) ctrlpkt; + + rtn = cmd_exec_api(arg_val); + if ((SW_OK != rtn) || (SW_OK != (sw_error_t) (*ioctl_buf))) + { + break; + } + arg_val[0] = SW_API_MGMTCTRL_CTRLPKT_PROFILE_GETNEXT; + cnt++; + } + + if((rtn != SW_OK) && (rtn != SW_NO_MORE)) + cmd_print_error(rtn); + else + dprintf("\ntotal %d entries\n", cnt); + + return SW_OK; +} + +sw_error_t +cmd_show_vlan(a_ulong_t *arg_val) +{ + sw_error_t rtn = SW_OK; + a_uint32_t rtn_size = 1 ,tmp_vid = FAL_NEXT_ENTRY_FIRST_ID, cnt = 0; + fal_vlan_t *vlan_entry = (fal_vlan_t *) (ioctl_buf + rtn_size); + + switch (ssdk_cfg.init_cfg.chip_type) { + case CHIP_ISIS: + case CHIP_ISISC: + case CHIP_DESS: + tmp_vid = FAL_NEXT_ENTRY_FIRST_ID; + break; + case CHIP_ATHENA: + case CHIP_GARUDA: + case CHIP_SHIVA: + case CHIP_HORUS: + tmp_vid = 0; + break; + default: + return SW_NOT_SUPPORTED; + } + + while (1) + { + arg_val[0] = SW_API_VLAN_NEXT; + arg_val[1] = (a_ulong_t) ioctl_buf; + arg_val[2] = get_devid(); + arg_val[3] = tmp_vid; + arg_val[4] = (a_ulong_t) vlan_entry; + + rtn = cmd_exec_api(arg_val); + if ((SW_OK != rtn) || (SW_OK != (sw_error_t) (*ioctl_buf))) + { + break; + } + + tmp_vid = vlan_entry->vid; + cnt++; + } + + if((rtn != SW_OK) && (rtn != SW_NO_MORE)) { + cmd_print_error(rtn); + } else { + dprintf("\ntotal %d entries\n", cnt); + } + + return rtn; +} + +sw_error_t +cmd_show_resv_fdb(a_ulong_t *arg_val) +{ + sw_error_t rtn; + a_uint32_t cnt = 0; + a_ulong_t *iterator = ioctl_buf + 1; + fal_fdb_entry_t *entry = (fal_fdb_entry_t *) (ioctl_buf + 2); + + *iterator = 0; + while (1) + { + arg_val[0] = SW_API_FDB_RESV_ITERATE; + arg_val[1] = (a_ulong_t) ioctl_buf; + arg_val[2] = get_devid(); + arg_val[3] = (a_ulong_t) iterator; + arg_val[4] = (a_ulong_t) entry; + + rtn = cmd_exec_api(arg_val); + if ((SW_OK != rtn) || (SW_OK != (sw_error_t) (*ioctl_buf))) + { + break; + } + cnt++; + dprintf("\n"); + } + + if((rtn != SW_OK) && (rtn != SW_NO_MORE)) + cmd_print_error(rtn); + else + dprintf("\ntotal %d entries\n", cnt); + + return SW_OK; +} + + +sw_error_t +cmd_show_host(a_ulong_t *arg_val) +{ + sw_error_t rtn; + a_uint32_t cnt = 0; + fal_host_entry_t *host_entry = (fal_host_entry_t *) (ioctl_buf + sizeof(sw_error_t) / 4); + + aos_mem_zero(host_entry, sizeof (fal_host_entry_t)); + host_entry->entry_id = FAL_NEXT_ENTRY_FIRST_ID; + arg_val[0] = SW_API_IP_HOST_NEXT; + + while (1) + { + arg_val[1] = (a_ulong_t) ioctl_buf; + arg_val[2] = get_devid(); + arg_val[3] = 0; + arg_val[4] = (a_ulong_t) host_entry; + + rtn = cmd_exec_api(arg_val); + if ((SW_OK != rtn) || (SW_OK != (sw_error_t) (*ioctl_buf))) + { + break; + } + cnt++; + } + + if((rtn != SW_OK) && (rtn != SW_NO_MORE)) + cmd_print_error(rtn); + else + dprintf("\ntotal %d entries\n", cnt); + + return SW_OK; +} + +sw_error_t +cmd_show_host_ipv4(a_ulong_t *arg_val) +{ + sw_error_t rtn; + a_uint32_t cnt = 0; + fal_host_entry_t *host_entry = (fal_host_entry_t *) (ioctl_buf + sizeof(sw_error_t) / 4); + + aos_mem_zero(host_entry, sizeof (fal_host_entry_t)); + host_entry->entry_id = FAL_NEXT_ENTRY_FIRST_ID; + arg_val[0] = SW_API_IP_HOST_NEXT; + + while (1) + { + arg_val[1] = (a_ulong_t) ioctl_buf; + arg_val[2] = get_devid(); + arg_val[3] = FAL_IP_IP4_ADDR; + arg_val[4] = (a_ulong_t) host_entry; + + rtn = cmd_exec_api(arg_val); + if ((SW_OK != rtn) || (SW_OK != (sw_error_t) (*ioctl_buf))) + { + break; + } + cnt++; + } + + + dprintf("\nipv4 total %d entries\n", cnt); + + return SW_OK; +} + +sw_error_t +cmd_show_host_ipv6(a_ulong_t *arg_val) +{ + sw_error_t rtn; + a_uint32_t cnt = 0; + fal_host_entry_t *host_entry = (fal_host_entry_t *) (ioctl_buf + sizeof(sw_error_t) / 4); + + aos_mem_zero(host_entry, sizeof (fal_host_entry_t)); + host_entry->entry_id = FAL_NEXT_ENTRY_FIRST_ID; + arg_val[0] = SW_API_IP_HOST_NEXT; + + while (1) + { + arg_val[1] = (a_ulong_t) ioctl_buf; + arg_val[2] = get_devid(); + arg_val[3] = FAL_IP_IP6_ADDR; + arg_val[4] = (a_ulong_t) host_entry; + + rtn = cmd_exec_api(arg_val); + if ((SW_OK != rtn) || (SW_OK != (sw_error_t) (*ioctl_buf))) + { + break; + } + cnt++; + } + + + dprintf("\nipv6 total %d entries\n", cnt); + + return SW_OK; +} + +sw_error_t +cmd_show_host_ipv4M(a_ulong_t *arg_val) +{ + sw_error_t rtn; + a_uint32_t cnt = 0; + fal_host_entry_t *host_entry = (fal_host_entry_t *) (ioctl_buf + sizeof(sw_error_t) / 4); + + aos_mem_zero(host_entry, sizeof (fal_host_entry_t)); + host_entry->entry_id = FAL_NEXT_ENTRY_FIRST_ID; + arg_val[0] = SW_API_IP_HOST_NEXT; + + while (1) + { + arg_val[1] = (a_ulong_t) ioctl_buf; + arg_val[2] = get_devid(); + arg_val[3] = FAL_IP_IP4_ADDR_MCAST; + arg_val[4] = (a_ulong_t) host_entry; + + rtn = cmd_exec_api(arg_val); + if ((SW_OK != rtn) || (SW_OK != (sw_error_t) (*ioctl_buf))) + { + break; + } + cnt++; + } + + + dprintf("\nipv4 multicast total %d entries\n", cnt); + + return SW_OK; +} + +sw_error_t +cmd_show_host_ipv6M(a_ulong_t *arg_val) +{ + sw_error_t rtn; + a_uint32_t cnt = 0; + fal_host_entry_t *host_entry = (fal_host_entry_t *) (ioctl_buf + sizeof(sw_error_t) / 4); + + aos_mem_zero(host_entry, sizeof (fal_host_entry_t)); + host_entry->entry_id = FAL_NEXT_ENTRY_FIRST_ID; + arg_val[0] = SW_API_IP_HOST_NEXT; + + while (1) + { + arg_val[1] = (a_ulong_t) ioctl_buf; + arg_val[2] = get_devid(); + arg_val[3] = FAL_IP_IP6_ADDR_MCAST; + arg_val[4] = (a_ulong_t) host_entry; + + rtn = cmd_exec_api(arg_val); + if ((SW_OK != rtn) || (SW_OK != (sw_error_t) (*ioctl_buf))) + { + break; + } + cnt++; + } + + + dprintf("\nipv6 multicast total %d entries\n", cnt); + + return SW_OK; +} + +sw_error_t +cmd_show_flow_entry(a_ulong_t *arg_val, a_uint32_t type) +{ + sw_error_t rtn; + a_uint32_t cnt = 0; + fal_flow_entry_t *flow_entry = (fal_flow_entry_t *) (ioctl_buf + sizeof(sw_error_t) / 4); + + aos_mem_zero(flow_entry, sizeof (fal_flow_entry_t)); + flow_entry->entry_id = FAL_NEXT_ENTRY_FIRST_ID; + arg_val[0] = SW_API_FLOWENTRY_NEXT; + + while (1) + { + arg_val[1] = (a_ulong_t) ioctl_buf; + arg_val[2] = get_devid(); + arg_val[3] = type; + arg_val[4] = (a_ulong_t) flow_entry; + + rtn = cmd_exec_api(arg_val); + if ((SW_OK != rtn) || (SW_OK != (sw_error_t) (*ioctl_buf))) + { + break; + } + cnt++; + } + + dprintf("\nflow total %d entries\n", cnt); + + return SW_OK; +} + +sw_error_t +cmd_show_flow_ipv4_3tuple(a_ulong_t *arg_val) +{ + return cmd_show_flow_entry(arg_val, FAL_FLOW_IP4_3TUPLE_ADDR); +} + +sw_error_t +cmd_show_flow_ipv4_5tuple(a_ulong_t *arg_val) +{ + return cmd_show_flow_entry(arg_val, FAL_FLOW_IP4_5TUPLE_ADDR); +} + +sw_error_t +cmd_show_flow_ipv6_3tuple(a_ulong_t *arg_val) +{ + return cmd_show_flow_entry(arg_val, FAL_FLOW_IP6_3TUPLE_ADDR); +} + +sw_error_t +cmd_show_flow_ipv6_5tuple(a_ulong_t *arg_val) +{ + return cmd_show_flow_entry(arg_val, FAL_FLOW_IP6_5TUPLE_ADDR); +} + + +sw_error_t +cmd_show_intfmac(a_ulong_t *arg_val) +{ + sw_error_t rtn; + a_uint32_t cnt = 0; + fal_intf_mac_entry_t *intfmac_entry = (fal_intf_mac_entry_t *) (ioctl_buf + sizeof(sw_error_t) / 4); + + aos_mem_zero(intfmac_entry, sizeof (fal_intf_mac_entry_t)); + intfmac_entry->entry_id = FAL_NEXT_ENTRY_FIRST_ID; + arg_val[0] = SW_API_IP_INTF_ENTRY_NEXT; + + while (1) + { + arg_val[1] = (a_ulong_t) ioctl_buf; + arg_val[2] = get_devid(); + arg_val[3] = 0; + arg_val[4] = (a_ulong_t) intfmac_entry; + + rtn = cmd_exec_api(arg_val); + if ((SW_OK != rtn) || (SW_OK != (sw_error_t) (*ioctl_buf))) + { + break; + } + cnt++; + } + + if((rtn != SW_OK) && (rtn != SW_NO_MORE)) + cmd_print_error(rtn); + else + dprintf("\ntotal %d entries\n", cnt); + + return SW_OK; +} + +sw_error_t +cmd_show_pubaddr(a_ulong_t *arg_val) +{ + sw_error_t rtn; + a_uint32_t cnt = 0; + fal_nat_pub_addr_t *pubaddr_entry = (fal_nat_pub_addr_t *) (ioctl_buf + sizeof(sw_error_t) / 4); + + aos_mem_zero(pubaddr_entry, sizeof (fal_nat_pub_addr_t)); + pubaddr_entry->entry_id = FAL_NEXT_ENTRY_FIRST_ID; + arg_val[0] = SW_API_PUB_ADDR_ENTRY_NEXT; + + while (1) + { + arg_val[1] = (a_ulong_t) ioctl_buf; + arg_val[2] = get_devid(); + arg_val[3] = 0; + arg_val[4] = (a_ulong_t) pubaddr_entry; + + rtn = cmd_exec_api(arg_val); + if ((SW_OK != rtn) || (SW_OK != (sw_error_t) (*ioctl_buf))) + { + break; + } + cnt++; + } + + if((rtn != SW_OK) && (rtn != SW_NO_MORE)) + cmd_print_error(rtn); + else + dprintf("\ntotal %d entries\n", cnt); + + return SW_OK; +} + + +sw_error_t +cmd_show_nat(a_ulong_t *arg_val) +{ + sw_error_t rtn; + a_uint32_t cnt = 0; + fal_nat_entry_t *nat_entry = (fal_nat_entry_t *) (ioctl_buf + sizeof(sw_error_t) / 4); + + aos_mem_zero(nat_entry, sizeof (fal_nat_entry_t)); + nat_entry->entry_id = FAL_NEXT_ENTRY_FIRST_ID; + arg_val[0] = SW_API_NAT_NEXT; + + while (1) + { + arg_val[1] = (a_ulong_t) ioctl_buf; + arg_val[2] = get_devid(); + arg_val[3] = 0; + arg_val[4] = (a_ulong_t) nat_entry; + + rtn = cmd_exec_api(arg_val); + if ((SW_OK != rtn) || (SW_OK != (sw_error_t) (*ioctl_buf))) + { + break; + } + cnt++; + } + + if((rtn != SW_OK) && (rtn != SW_NO_MORE)) + cmd_print_error(rtn); + else + dprintf("\ntotal %d entries\n", cnt); + + return SW_OK; +} + + +sw_error_t +cmd_show_napt(a_ulong_t *arg_val) +{ + sw_error_t rtn; + a_uint32_t cnt = 0; + fal_napt_entry_t *napt_entry = (fal_napt_entry_t *) (ioctl_buf + sizeof(sw_error_t) / 4); + + aos_mem_zero(napt_entry, sizeof (fal_napt_entry_t)); + napt_entry->entry_id = FAL_NEXT_ENTRY_FIRST_ID; + arg_val[0] = SW_API_NAPT_NEXT; + + while (1) + { + arg_val[1] = (a_ulong_t) ioctl_buf; + arg_val[2] = get_devid(); + arg_val[3] = 0; + arg_val[4] = (a_ulong_t) napt_entry; + + rtn = cmd_exec_api(arg_val); + if ((SW_OK != rtn) || (SW_OK != (sw_error_t) (*ioctl_buf))) + { + break; + } + cnt++; + } + + if((rtn != SW_OK) && (rtn != SW_NO_MORE)) + cmd_print_error(rtn); + else + dprintf("\ntotal %d entries\n", cnt); + + return SW_OK; +} + +sw_error_t +cmd_show_flow(a_ulong_t *arg_val) +{ + sw_error_t rtn; + a_uint32_t cnt = 0; + fal_napt_entry_t *napt_entry = (fal_napt_entry_t *) (ioctl_buf + sizeof(sw_error_t) / 4); + + aos_mem_zero(napt_entry, sizeof (fal_napt_entry_t)); + napt_entry->entry_id = FAL_NEXT_ENTRY_FIRST_ID; + arg_val[0] = SW_API_FLOW_NEXT; + + while (1) + { + arg_val[1] = (a_ulong_t ) ioctl_buf; + arg_val[2] = get_devid(); + arg_val[3] = 0; + arg_val[4] = (a_ulong_t ) napt_entry; + + rtn = cmd_exec_api(arg_val); + if ((SW_OK != rtn) || (SW_OK != (sw_error_t) (*ioctl_buf))) + { + break; + } + cnt++; + } + + if((rtn != SW_OK) && (rtn != SW_NO_MORE)) + cmd_print_error(rtn); + else + dprintf("\ntotal %d entries\n", cnt); + + return SW_OK; +} + +sw_error_t +cmd_show_ptvlan_entry(a_ulong_t *arg_val) +{ + sw_error_t rtn; + a_uint32_t port_id, direction, cnt; + a_uint32_t p_size = sizeof(a_ulong_t); + + fal_vlan_trans_adv_rule_t *vlan_rule = (fal_vlan_trans_adv_rule_t *)(ioctl_buf + + (sizeof(sw_error_t) + p_size - 1) / p_size); + fal_vlan_trans_adv_action_t *vlan_action = (fal_vlan_trans_adv_action_t *)(ioctl_buf + + (sizeof(sw_error_t) + p_size - 1) / p_size + + (sizeof(fal_vlan_trans_adv_rule_t) + p_size - 1) / p_size); + + aos_mem_zero(vlan_rule, sizeof(fal_vlan_trans_adv_rule_t)); + aos_mem_zero(vlan_action, sizeof(fal_vlan_trans_adv_action_t)); + + port_id = arg_val[1]; + direction = arg_val[2]; + cnt = 0; + + if (direction != FAL_PORT_VLAN_INGRESS && + direction != FAL_PORT_VLAN_EGRESS) { + return SW_BAD_PARAM; + } + + arg_val[0] = SW_API_PT_VLAN_TRANS_ADV_GETFIRST; + + while (1) { + arg_val[1] = (a_ulong_t)ioctl_buf; + arg_val[2] = get_devid(); + arg_val[3] = port_id; + arg_val[4] = direction; + arg_val[5] = (a_ulong_t)vlan_rule; + arg_val[6] = (a_ulong_t)vlan_action; + + rtn = cmd_exec_api(arg_val); + if ((SW_OK != rtn) || (SW_OK != (sw_error_t)(*ioctl_buf))) { + break; + } + arg_val[0] = SW_API_PT_VLAN_TRANS_ADV_GETNEXT; + cnt++; + } + + if((rtn != SW_OK) && (rtn != SW_NOT_FOUND)) { + cmd_print_error(rtn); + } else { + dprintf("\nvlan total %d entries\n", cnt); + } + + return SW_OK; +} diff --git a/feeds/ipq807x/qca-ssdk/Makefile b/feeds/ipq807x/qca-ssdk/Makefile new file mode 100755 index 000000000..a160f25df --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/Makefile @@ -0,0 +1,85 @@ + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=qca-ssdk +PKG_SOURCE_DATE:=2020-07-10 + +include $(INCLUDE_DIR)/package.mk + +define KernelPackage/qca-ssdk + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + TITLE:=Kernel driver for QCA SSDK + FILES:=$(PKG_BUILD_DIR)/build/bin/qca-ssdk.ko + AUTOLOAD:=$(call AutoLoad,30,qca-ssdk) + PROVIDES:=qca-ssdk +endef + +define KernelPackage/qca-ssdk/Description +This package contains a qca-ssdk driver for QCA chipset +endef + +GCC_VERSION=$(shell echo "$(CONFIG_GCC_VERSION)" | sed 's/[^0-9.]*\([0-9.]*\).*/\1/') + +TOOLCHAIN_BIN_PATH=$(TOOLCHAIN_DIR)/bin + +QCASSDK_CONFIG_OPTS+= TOOL_PATH=$(TOOLCHAIN_BIN_PATH) \ + SYS_PATH=$(LINUX_DIR) \ + TOOLPREFIX=$(TARGET_CROSS) \ + KVER=$(LINUX_VERSION) \ + ARCH=$(LINUX_KARCH) \ + TARGET_SUFFIX=$(CONFIG_TARGET_SUFFIX) \ + GCC_VERSION=$(GCC_VERSION) \ + CFLAGS=-I$(STAGING_DIR)/usr/include + +QCASSDK_CONFIG_OPTS+= PTP_FEATURE=enable + +ifeq ($(SUBTARGET),ipq807x)) + QCASSDK_CONFIG_OPTS+= CHIP_TYPE=HPPE +else ifeq ($(SUBTARGET),ipq60xx)) + QCASSDK_CONFIG_OPTS+= CHIP_TYPE=CPPE +endif +QCASSDK_CONFIG_OPTS+= MINI_SSDK=enable +QCASSDK_CONFIG_OPTS+= PTP_FEATURE=disable + +QCASSDK_CONFIG_OPTS+= HK_CHIP=enable + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include/qca-ssdk + $(INSTALL_DIR) $(1)/usr/include/qca-ssdk/api + $(INSTALL_DIR) $(1)/usr/include/qca-ssdk/ref + $(INSTALL_DIR) $(1)/usr/include/qca-ssdk/fal + $(INSTALL_DIR) $(1)/usr/include/qca-ssdk/sal + $(INSTALL_DIR) $(1)/usr/include/qca-ssdk/init + $(CP) -rf $(PKG_BUILD_DIR)/include/api/sw_ioctl.h $(1)/usr/include/qca-ssdk/api + if [ -f $(PKG_BUILD_DIR)/include/ref/ref_vsi.h ]; then \ + $(CP) -rf $(PKG_BUILD_DIR)/include/ref/ref_vsi.h $(1)/usr/include/qca-ssdk/ref/; \ + fi + if [ -f $(PKG_BUILD_DIR)/include/ref/ref_fdb.h ]; then \ + $(CP) -rf $(PKG_BUILD_DIR)/include/ref/ref_fdb.h $(1)/usr/include/qca-ssdk/ref/; \ + fi + if [ -f $(PKG_BUILD_DIR)/include/ref/ref_port_ctrl.h ]; then \ + $(CP) -rf $(PKG_BUILD_DIR)/include/ref/ref_port_ctrl.h $(1)/usr/include/qca-ssdk/ref/; \ + fi + if [ -f $(PKG_BUILD_DIR)/include/init/ssdk_init.h ]; then \ + $(CP) -rf $(PKG_BUILD_DIR)/include/init/ssdk_init.h $(1)/usr/include/qca-ssdk/init/; \ + fi + $(CP) -rf $(PKG_BUILD_DIR)/include/fal $(1)/usr/include/qca-ssdk + $(CP) -rf $(PKG_BUILD_DIR)/include/common/*.h $(1)/usr/include/qca-ssdk + $(CP) -rf $(PKG_BUILD_DIR)/include/sal/os/linux/*.h $(1)/usr/include/qca-ssdk + $(CP) -rf $(PKG_BUILD_DIR)/include/sal/os/*.h $(1)/usr/include/qca-ssdk + +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) $(strip $(QCASSDK_CONFIG_OPTS)) +endef + +define KernelPackage/qca-ssdk/install + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/qca-ssdk $(1)/etc/init.d/qca-ssdk +endef + +$(eval $(call KernelPackage,qca-ssdk)) diff --git a/feeds/ipq807x/qca-ssdk/files/qca-ssdk b/feeds/ipq807x/qca-ssdk/files/qca-ssdk new file mode 100755 index 000000000..389279c0c --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/files/qca-ssdk @@ -0,0 +1,206 @@ +#!/bin/sh /etc/rc.common +# 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. +# + +START=16 + +#!/bin/sh +ruletype="ip4 ip6" +side="wan lan" +qwan="1 3 2 0 5 7 6 4" +qlan="0 1 2 3 4 5 6 7" + +function create_war_acl_rules(){ + for lw in $side + do + #echo $lw + if [ "$lw" == "wan" ];then + listid=254 + queue=$qwan + portmap=0x20 + else + listid=255 + queue=$qlan + portmap=0x1e + fi + #echo $queue + #echo "creating list $listid" + ssdk_sh acl list create $listid 255 + ruleid=0 + for rt in $ruletype + do + for qid in $queue + do + cmd="ssdk_sh acl rule add $listid $ruleid 1 n 0 0" + #echo $cmd + if [ "$rt" == "ip4" ];then + cmd="$cmd ip4 n n n n n n n n n n n n n n n n n n n n n n n n n n n n n" + #echo $cmd + else + cmd="$cmd ip6 n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n" + #echo $cmd + fi + if [ $ruleid -le 3 ];then + #non-zero dscp + cmd="$cmd y 0x0 0xff" + elif [ $ruleid -le 7 ];then + #zero dscp + cmd="$cmd n" + elif [ $ruleid -le 11 ];then + #non-zero dscp + cmd="$cmd y 0x0 0xff" + else + #zero dscp + cmd="$cmd n" + fi + p=$((ruleid/2)) + cmd="$cmd y mask $((ruleid%2)) 0x1 y mask $((p%2)) 0x1 n n n n n n n n n n n n n n n y n n n n n n n y $qid n n 0 0 n n n n n n n n n n n n n n n n n n n n 0" + #echo $cmd + $cmd + ruleid=`expr $ruleid + 1` + done + done + ssdk_sh acl list bind $listid 0 1 $portmap + done +} + +function create_war_cosmap(){ + ssdk_sh cosmap pri2q set 0 0 + ssdk_sh cosmap pri2q set 1 0 + ssdk_sh cosmap pri2q set 2 0 + ssdk_sh cosmap pri2q set 3 0 + ssdk_sh cosmap pri2q set 4 1 + ssdk_sh cosmap pri2q set 5 1 + ssdk_sh cosmap pri2q set 6 1 + ssdk_sh cosmap pri2q set 7 1 + ssdk_sh cosmap pri2ehq set 0 0 + ssdk_sh cosmap pri2ehq set 1 0 + ssdk_sh cosmap pri2ehq set 2 0 + ssdk_sh cosmap pri2ehq set 3 0 + ssdk_sh cosmap pri2ehq set 4 1 + ssdk_sh cosmap pri2ehq set 5 1 + ssdk_sh cosmap pri2ehq set 6 1 + ssdk_sh cosmap pri2ehq set 7 1 +} + +function create_acl_byp_egstp_rules(){ + ssdk_sh debug module_func set servcode 0xf 0x0 0x0 + ssdk_sh servcode config set 1 n 0 0xfffefc7f 0xffbdff 0 0 0 0 0 0 + ssdk_sh debug module_func set servcode 0x0 0x0 0x0 + ssdk_sh acl list create 56 48 + ssdk_sh acl rule add 56 0 1 n 0 0 mac n n n n n y 01-80-c2-00-00-00 ff-ff-ff-ff-ff-ff n n n n n n n n n n n n n n n n n n n n n n n y n n n n n n n n n n 0 0 n n n n n n n n n n n n n y n n n n n n n n n n n n y n n n n n n n n n n n n 0 + ssdk_sh acl rule add 56 1 1 n 0 0 mac n n n n n n n yes 0x8809 0xffff n n n n n n n n n n n n n n n n n n n n n y n n n n n n n n n n 0 0 n n n n n n n n n n n n n y n n n n n n n n n n n n y n n n n n n n n n n n n 0 + ssdk_sh acl rule add 56 2 1 n 0 0 mac n n n n n n n yes 0x888e 0xffff n n n n n n n n n n n n n n n n n n n n n y n n n n n n n n n n 0 0 n n n n n n n n n n n n n y n n n n n n n n n n n n y n n n n n n n n n n n n 0 + ssdk_sh acl list bind 56 0 2 1 +} + +function delete_war_acl_rules(){ + for lw in $side + do + #echo $lw + if [ "$lw" == "wan" ];then + listid=254 + queue=$qwan + portmap=0x20 + else + listid=255 + queue=$qlan + portmap=0x1e + fi + ssdk_sh acl list unbind $listid 0 1 $portmap + for rt in $ruletype + do + for qid in $queue + do + cmd="ssdk_sh acl rule del $listid 0 1" + echo $cmd + $cmd + done + done + #echo "deleting list $listid" + ssdk_sh acl list destroy $listid + done +} + +function delete_war_cosmap(){ + ssdk_sh cosmap pri2q set 0 0 + ssdk_sh cosmap pri2q set 1 0 + ssdk_sh cosmap pri2q set 2 1 + ssdk_sh cosmap pri2q set 3 1 + ssdk_sh cosmap pri2q set 4 2 + ssdk_sh cosmap pri2q set 5 2 + ssdk_sh cosmap pri2q set 6 3 + ssdk_sh cosmap pri2q set 7 3 + ssdk_sh cosmap pri2ehq set 0 1 + ssdk_sh cosmap pri2ehq set 1 0 + ssdk_sh cosmap pri2ehq set 2 2 + ssdk_sh cosmap pri2ehq set 3 2 + ssdk_sh cosmap pri2ehq set 4 3 + ssdk_sh cosmap pri2ehq set 5 3 + ssdk_sh cosmap pri2ehq set 6 4 + ssdk_sh cosmap pri2ehq set 7 5 +} + +function delete_acl_byp_egstp_rules(){ + ssdk_sh debug module_func set servcode 0xf 0x0 0x0 + ssdk_sh servcode config set 1 n 0 0xfffefcff 0xffbfff 0 0 0 0 0 0 + ssdk_sh debug module_func set servcode 0x0 0x0 0x0 + ssdk_sh acl list unbind 56 0 2 1 + ssdk_sh acl rule del 56 0 1 + ssdk_sh acl rule del 56 1 1 + ssdk_sh acl rule del 56 2 1 + ssdk_sh acl list destroy 56 +} + +function edma_war_config_add(){ + create_war_cosmap + ssdk_sh acl status set enable + create_war_acl_rules +} + +function edma_war_config_del(){ + delete_war_acl_rules + delete_war_cosmap +} + +start() { + chip_ver=`ssdk_sh debug reg get 0 4 | grep Data | tr -d 'SSDK Init OK![Data]:'` + #The following commands should be uncommented to enable EDMA WAR + if [ "$chip_ver" = "0x1401" ]; then + #edma_war_config_add + echo '' + fi + #The following commands should be uncommented to add acl egress stp bypass rules + if [ "$chip_ver" = "0x1500" ] || [ "$chip_ver" = "0x1501" ]; then + #create_acl_byp_egstp_rules + echo '' + fi + echo starting +} + +stop() { + chip_ver=`ssdk_sh debug reg get 0 4 | grep Data | tr -d 'SSDK Init OK![Data]:'` + #The following commands should be uncommented to disable EDMA WAR + if [ "$chip_ver" = "0x1401" ]; then + #edma_war_config_del + echo '' + fi + #The following commands should be uncommented to delete acl egress stp bypass rules + if [ "$chip_ver" = "0x1500" ] || [ "$chip_ver" = "0x1501" ]; then + #delete_acl_byp_egstp_rules + echo '' + fi + echo stoping +} diff --git a/feeds/ipq807x/qca-ssdk/patches/100-aq.patch b/feeds/ipq807x/qca-ssdk/patches/100-aq.patch new file mode 100644 index 000000000..45a3c0cb6 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/patches/100-aq.patch @@ -0,0 +1,47 @@ +Index: qca-ssdk/include/hsl/phy/hsl_phy.h +=================================================================== +--- qca-ssdk.orig/include/hsl/phy/hsl_phy.h ++++ qca-ssdk/include/hsl/phy/hsl_phy.h +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2015, 2017-2020, The Linux Foundation. All rights reserved. ++ * Copyright (c) 2015, 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. +@@ -541,6 +541,7 @@ typedef struct { + #define QCA8033_PHY 0x004DD074 + #define QCA8035_PHY 0x004DD072 + /*qca808x_start*/ ++#define QCA8081_PHY 0x004DD100 + #define QCA8081_PHY_V1_1 0x004DD101 + #define INVALID_PHY_ID 0 + +@@ -559,6 +560,7 @@ typedef struct { + #define AQUANTIA_PHY_113C_A0 0x31c31C10 + #define AQUANTIA_PHY_113C_A1 0x31c31C11 + #define AQUANTIA_PHY_112C 0x03a1b792 ++#define AQUANTIA_PHY_114C 0x31c31C22 + + #define PHY_805XV2 0x004DD082 + #define PHY_805XV1 0x004DD081 +Index: qca-ssdk/src/hsl/phy/hsl_phy.c +=================================================================== +--- qca-ssdk.orig/src/hsl/phy/hsl_phy.c ++++ qca-ssdk/src/hsl/phy/hsl_phy.c +@@ -231,6 +231,7 @@ phy_type_t hsl_phytype_get_by_phyid(a_ui + case AQUANTIA_PHY_108: + case AQUANTIA_PHY_109: + case AQUANTIA_PHY_111: ++ case AQUANTIA_PHY_114C: + case AQUANTIA_PHY_111B0: + case AQUANTIA_PHY_112: + case AQUANTIA_PHY_113C_A0: +@@ -250,6 +251,7 @@ phy_type_t hsl_phytype_get_by_phyid(a_ui + phytype = MPGE_PHY_CHIP; + break; + /*qca808x_start*/ ++ case QCA8081_PHY: + case QCA8081_PHY_V1_1: + phytype = QCA808X_PHY_CHIP; + break; diff --git a/feeds/ipq807x/qca-ssdk/src/ChangeLog b/feeds/ipq807x/qca-ssdk/src/ChangeLog new file mode 100644 index 000000000..547dba45d --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/ChangeLog @@ -0,0 +1,129 @@ +============================================================ +Changes for SSDK 1.0.3: +============================================================ + +* Support HORUS: + - Add chip type HORUS and related source code. + + + + +============================================================ +Changes for SSDK 1.0.4: +============================================================ + +* Support ISIS: + - Add chip type ISIS and related source code. + + + + +============================================================ +Changes for SSDK 1.0.5: +============================================================ + +* Speed up FDB entry next operation. +* Support linux 2.6.31 version. + + + + +============================================================ +Changes for SSDK 1.0.6: +============================================================ + +* New APIs pppoe_session_id_set/get are supported for ISIS chip. +* Fix parameter speed check bug in API isis_port_speed_set. + + + + +============================================================ +Changes for SSDK 1.0.7: +============================================================ +* Fix address bytes order bug in API _isis_ip6_base_addr_set/get. +* Change the socket call for user space and kernel communication to nonblocking way. +* Remove force routing function for ISIS acl action. +* Add configuration for ISIS register accessing speed up feature in ./config file. +* Add configuration for ISIS NAT helper feature in ./config.file. + + + + +============================================================ +Changes for SSDK 1.0.8: +============================================================ +* Offer ioctl based method for linux kernel&user space communication +* Remove some port property logic limitation for ISIS. +* Remove FDB CRC mode setting in ISIS init. +* Add some operation mode flag for ISIS NAPT entry next operation. +* Add some operation mode flag for ISIS NAPT del opertion. +* Fix one bug for fdb entry extendnext command parsing when shell works at slient mode. +* Fix one bug in ISIS ACL rule delete operation(isis_acl_rule_delete). +* Fix one bug in ISIS queue shapper get operation(isis_rate_queue_shaper_get). +* Add new API for ISIS MAC based VLAN translation.(isis_port_mac_vlan_xlt_set/isis_port_mac_vlan_xlt_get). +* Add new API for ISIS add/delete port to/from an exist FDB entry.(isis_fdb_port_add/isis_fdb_port_del). +* Add new API for ISIS ACL rules active/deactive. (isis_acl_rule_active/isis_acl_rule_deactive). +* Add new API for ISIS wcmp hash mode setting. (isis_ip_wcmp_hash_mode_set/isis_ip_wcmp_hash_mode_get). +* Add new API for ISIS host entry aging time setting. (isis_ip_age_time_set/isis_ip_age_time_get). +* Add new API for ISIS interrupt operation. (isis_intr_mask_set/isis_intr_mask_get/isis_intr_status_get/ + isis_intr_status_clear/isis_intr_port_link_mask_set/isis_intr_port_link_mask_get/isis_intr_port_link_status_get). +* Add new API for ISIS port MAC mode setting. (isis_interface_mac_mode_set/isis_interface_mac_mode_get). +* Add new API for ISIS port PHY mode setting. (isis_interface_phy_mode_set/isis_interface_phy_mode_get). +* Add new API for ISIS 802.3az setting. (isis_port_3az_status_set/isis_port_3az_status_get). +* Add new API for ISIS link status getting. (isis_port_link_status_get). +* Add new API for ISIS MAC TX status setting. (isis_port_txmac_status_set/isis_port_txmac_status_get). +* Add new API for ISIS MAC RX status setting. (isis_port_rxmac_status_set/isis_port_rxmac_status_get). +* Add new API for ISIS MAC TX flow control setting. (isis_port_txfc_status_set/isis_port_txfc_status_get). +* Add new API for ISIS MAC RX flow control setting. (isis_port_rxfc_status_set/isis_port_rxfc_status_get). +* Add new API for ISIS MAC back pressure setting. (isis_port_bp_status_set/isis_port_bp_status_get). +* Add new API for ISIS link force mode setting. (isis_port_link_forcemode_set/isis_port_link_forcemode_get). +* Fix one bug in Giga PHY device autoneg ability setting operation. +* Makefile change for ISIS NAT helper refactoring. + +============================================================ +Changes for SSDK 1.1.x: +============================================================ +* Add support for QCA833x family (ISISC, S17c). +* Add support for out-of-band register access through ethernet packets with Atheros header. (S17/S17c) +* Add IPV6 Hardware Routing (ISISC, S17c). +* Add new API for set/get status of one ACL rule source filter. (S17c only) +* Add new API for set/get arl search mode as ivl or svl when vlan invalid. (S17c only) +* Add new API for interface control: +fal_interface_fx100_ctrl_set/fal_interface_fx100_ctrl_get/fal_interface_fx100_status_get/fal_interface_fx100_status_set/fal_interface_mac06_exch_get/fal_interface_mac06_exch_set. (S17c only) +* Add new API for MIB counter: +fal_mib_port_flush_counters/fal_mib_cpukeep_set/fal_mib_cpukeep_get. (S17c only) +*Add new API for Misc: +fal_intr_mask_mac_linkchg_set/fal_intr_mask_mac_linkchg_get/fal_intr_status_mac_linkchg_get/fal_cpu_vid_en_set/fal_cpu_vid_en_get/fal_rtd_pppoe_en_set/fal_rtd_pppoe_en_get/fal_intr_status_mac_linkchg_clear (S17c only) +* Add new API for nat: nat_prv_base_mask_set/nat_prv_base_mask_get. (S17c only) +* Add new API for port ctrl: +fal_port_mac_loopback_set/fal_port_mac_loopback_set. (S17c only) +* Add new API for port vlan: +fal_netisolate_set/fal_netisolate_get/fal_eg_trans_filter_bypass_en_set/fal_eg_trans_filter_bypass_en_get. (S17c only) +* Add new API for QoS: +fal_qos_port_force_spri_status_set/fal_qos_port_force_spri_status_get/fal_qos_port_force_cpri_status_set/fal_qos_port_force_cpri_status_get. (S17c only) +* Add new API for Rate limit: +fal_rate_port_add_rate_byte_set/fal_rate_port_add_rate_byte_get/fal_rate_port_gol_flow_en_set/fal_rate_port_gol_flow_en_get. + +============================================================ +Changes for SSDK 1.1.1: +============================================================ +* Add IGMP mldv2 support + +============================================================ +Changes for SSDK 1.1.2: +============================================================ +* Add API for Trunk support +* Add API for MAC loopback support + +============================================================ +Changes for SSDK 1.1.3: +============================================================ +* Support CHIP_TYPE=ALL_CHIP +============================================================ +Changes for SSDK 1.1.3.2: +============================================================ +* Add hsl_shared_api.h (sync from Perforce server) +* Add support for Linux Kernel 3.2.0 +* Add support for LITTLE ENDIAN (especially for HNAT) +* Add support for ARM CPU diff --git a/feeds/ipq807x/qca-ssdk/src/Makefile b/feeds/ipq807x/qca-ssdk/src/Makefile new file mode 100755 index 000000000..779365171 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/Makefile @@ -0,0 +1,52 @@ +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) kslib + mkdir -p ./temp/;cd ./temp;cp ../build/bin/ssdk_ks_km.a ./;ar -x ssdk_ks_km.a; cp ../ko_Makefile ./Makefile; + make -C $(SYS_PATH) M=$(PRJ_PATH)/temp/ CROSS_COMPILE=$(TOOLPREFIX) modules + cp $(PRJ_PATH)/temp/Module.symvers $(PRJ_PATH)/Module.symvers; + cp temp/*.ko build/bin; + rm -Rf ./temp/*.o ./temp/*.ko ./temp/*.a + @echo "---Build [SSDK-$(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/src/app/nathelper/linux/host_helper.c b/feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/host_helper.c new file mode 100755 index 000000000..8140233a8 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/host_helper.c @@ -0,0 +1,2253 @@ +/* + * Copyright (c) 2012, 2015, 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. + */ + + +#ifdef KVER32 +#include +#include +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef KVER32 +#include +#endif +#include +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) +#include +#endif +#if defined (CONFIG_BRIDGE) +#include <../net/bridge/br_private.h> +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hsl_api.h" +#include "fal_nat.h" +#include "fal_ip.h" +#include "fal_fdb.h" +#include "hsl.h" +#include "nat_helper.h" +#include "napt_acl.h" +#include "lib/nat_helper_hsl.h" +#include "lib/nat_helper_dt.h" +#include "hsl_shared_api.h" +#include + + +#undef CONFIG_IPV6_HWACCEL + + +#ifdef CONFIG_IPV6_HWACCEL +#include +#include +#include +#include +#include +#include +#include +#endif + +//#define AP136_QCA_HEADER_EN 1 +#define MAC_LEN 6 +#define IP_LEN 4 +#define ARP_HEADER_LEN 8 + +#define ARP_ENTRY_MAX 128 + +#define DESS_CHIP_VER 0x14 +#define HOST_PREFIX_MAX 31 + +/* P6 is used by loop dev. */ +#define S17_P6PAD_MODE_REG_VALUE 0x01000000 + +#define MULTIROUTE_WR + +extern struct net init_net; + +//char *nat_lan_dev_list = "eth0.1"; +char nat_lan_dev_list[IFNAMSIZ*4] = "br-lan eth0.1"; +char nat_wan_dev_list[IFNAMSIZ*5] = "eth0.2"; + +char nat_wan_port = 0x20; +int setup_wan_if = 0; +int setup_lan_if=0; + +#define NAT_LAN_DEV_VID 1 +#define NAT_WAN_DEV_VID 2 + +uint32_t nat_lan_vid = NAT_LAN_DEV_VID; +uint32_t nat_wan_vid = NAT_WAN_DEV_VID; + + +static int wan_fid = 0xffff; +static fal_pppoe_session_t pppoetbl = {0}; +static uint32_t pppoe_gwid = 0; +static char nat_bridge_dev[IFNAMSIZ*4] = "br-lan"; +static uint8_t lanip[4] = {0}, lanipmask[4] = {0}, wanip[4] = {0}; +#ifdef CONFIG_IPV6_HWACCEL +static struct in6_addr wan6ip = IN6ADDR_ANY_INIT; +static struct in6_addr lan6ip = IN6ADDR_ANY_INIT; +#endif + +extern int nat_chip_ver; + + +#ifdef ISISC +struct ipv6_default_route_binding +{ + struct in6_addr next_hop; + uint32_t nh_entry_id; +}; +#endif + +#ifdef MULTIROUTE_WR +#define MAX_HOST 8 +struct wan_next_hop +{ + u_int32_t host_ip; + u_int32_t entry_id; + u_int32_t in_acl; + u_int32_t in_use; + u_int8_t host_mac[6]; +}; +static struct net_device *multi_route_indev = NULL; +static struct wan_next_hop wan_nh_ent[MAX_HOST] = {{0}}; + +#define NAT_BACKGROUND_TASK + +#ifdef NAT_BACKGROUND_TASK +#define NAT_HELPER_MSG_MAX 512 + +struct bg_ring_buf_cb { + unsigned int read_idx; + unsigned int write_idx; + unsigned int num; + unsigned int full_flag; + struct nat_helper_bg_msg *buf; +}; + +struct bg_task_cb { + /*struct semaphore bg_sem; */ /*trigger thread work*/ + spinlock_t bg_lock; /*ring buf access protect*/ + /*struct task_struct *bg_task;*/ + struct workqueue_struct *nat_wq; + struct bg_ring_buf_cb ring; +}; + +enum{ + NAT_HELPER_ARP_ADD_MSG = 0, + NAT_HELPER_ARP_DEL_MSG, + NAT_HELPER_IPV6_MSG +}; + +struct arp_in_msg { + uint8_t mac[ETH_ALEN]; + char name[IFNAMSIZ]; /* device name */ + uint32_t ip; + struct net_device *in; +}; + +struct ipv6_msg { + struct sk_buff *skb; + struct net_device *in; +}; + + +struct nat_helper_bg_msg { + struct work_struct work; + uint32_t msg_type; + uint16_t sub_type; + uint16_t reservd; + union { + struct arp_in_msg arp_in; + struct ipv6_msg ipv6; + }; +}; + + +struct bg_task_cb task_cb; + +int bg_ring_buf_write(struct nat_helper_bg_msg msg) +{ + unsigned int idx = 0; + + spin_lock_bh(&task_cb.bg_lock); + + if((task_cb.ring).full_flag && + ((task_cb.ring).read_idx == (task_cb.ring).write_idx)) { + HNAT_PRINTK("ring buf is full!\n"); + spin_unlock_bh(&task_cb.bg_lock); + return -1; + } + msg.work = (task_cb.ring).buf[(task_cb.ring).write_idx].work; + (task_cb.ring).buf[(task_cb.ring).write_idx] = msg; + idx = (task_cb.ring).write_idx; + + (task_cb.ring).write_idx = ((task_cb.ring).write_idx+1)%NAT_HELPER_MSG_MAX; + if(task_cb.ring.read_idx == task_cb.ring.write_idx) + task_cb.ring.full_flag = 1; + + spin_unlock_bh(&task_cb.bg_lock); + queue_work(task_cb.nat_wq, &(task_cb.ring).buf[idx].work); + + return 0; +} + +int bg_ring_buf_read(struct nat_helper_bg_msg *msg) +{ + spin_lock_bh(&task_cb.bg_lock); + task_cb.ring.read_idx = (task_cb.ring.read_idx+1)%NAT_HELPER_MSG_MAX; + task_cb.ring.full_flag = 0; + spin_unlock_bh(&task_cb.bg_lock); + + return 0; +} + + + +#endif + +a_uint32_t nat_helper_wan_port_get(void) +{ + a_uint32_t i = 0; + + for (i = 0; i < 6; i ++) { + if ((nat_wan_port >> i) & 1) + break; + } + + return i; +} + +static int wan_nh_get(u_int32_t host_ip) +{ + int i; + + host_ip = htonl(host_ip); + + for (i=0; iifindex, + .flowi4_mark = 0, + .flowi4_tos = 0, + .flowi4_scope = RT_SCOPE_UNIVERSE, + .daddr = htonl(daddr), + .saddr = htonl(saddr), + }; +#else + struct flowi fl = { .nl_u = { .ip4_u = + { + .daddr = daddr, + .saddr = saddr, + .tos = 0, + .scope = RT_SCOPE_UNIVERSE, + } + }, + .mark = 0, + .iif = multi_route_indev->ifindex + }; +#endif + struct net * net = dev_net(multi_route_indev); + struct fib_nh *mrnh = NULL; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,4,0)) + if (fib_lookup(net, &fl, &res) != 0) +#else + if (fib_lookup(net, &fl, &res,0) != 0) +#endif + { + return 0; + } + else + { + mrnh = res.fi->fib_nh; + if (NULL == mrnh) + { + return 0; + } + } + + return ntohl(mrnh->nh_gw); +} + +uint32_t napt_set_default_route(fal_ip4_addr_t dst_addr, fal_ip4_addr_t src_addr) +{ + sw_error_t rv; + + /* search for the next hop (s) */ + if (!(get_aclrulemask() & (1 << S17_ACL_LIST_DROUTE))) + { + if (multi_route_indev && \ + (nf_athrs17_hnat_wan_type != NF_S17_WAN_TYPE_PPPOE) && + (nf_athrs17_hnat_wan_type != NF_S17_WAN_TYPE_PPPOES0)) + { + uint32_t next_hop = get_next_hop(dst_addr, src_addr); + + HNAT_PRINTK("Next hop: %08x\n", next_hop); + if (next_hop != 0) + { + fal_host_entry_t arp_entry; + + memset(&arp_entry, 0, sizeof(arp_entry)); + arp_entry.ip4_addr = next_hop; + arp_entry.flags = FAL_IP_IP4_ADDR; + rv = IP_HOST_GET(0, FAL_IP_ENTRY_IPADDR_EN, &arp_entry); + if (rv != SW_OK) + { + printk("%s: IP_HOST_GET error... (non-existed host: %08x?) \n", __func__, next_hop); + /* add into the nh_ent */ + wan_nh_add((u_int8_t *)&next_hop, (u_int8_t *)NULL, 0); + } + else + { + if (wan_nh_get(next_hop) != -1) + droute_add_acl_rules(*(uint32_t *)&lanip, *(uint32_t *)&lanipmask, arp_entry.entry_id); + else + printk("%s %d\n", __FUNCTION__, __LINE__); + } + } + else + { + HNAT_PRINTK("no need to set the default route... \n"); + // set_aclrulemask (S17_ACL_LIST_DROUTE); + } + } + else + { + printk("multi_route_indev %pK nf_athrs17_hnat_wan_type %d\n", multi_route_indev, nf_athrs17_hnat_wan_type); + } + } + /* end next hop (s) */ + + return SW_OK; +} +#endif /* MULTIROUTE_WR */ + +void qcaswitch_hostentry_flush(void) +{ + fal_host_entry_t hostentry; + sw_error_t ret; + + do + { + memset(&hostentry, 0, sizeof(fal_host_entry_t)); + hostentry.entry_id = FAL_NEXT_ENTRY_FIRST_ID; + ret = IP_HOST_NEXT (0, FAL_IP_ENTRY_ID_EN, &hostentry); + if (SW_OK == ret) + { + IP_HOST_DEL(0, FAL_IP_ENTRY_IPADDR_EN, &hostentry); + } + }while (SW_OK == ret); + + return; +} + +#ifdef CONFIG_IPV6_HWACCEL /* only for S17c */ +static struct in6_addr* get_ipv6_default_gateway(void) +{ + /* ip_route_output_key can't return correct default nexhop + * routes are less than 4 and it only searches in route + * hash, not in fib, so use fib_lookup. + */ + struct in6_addr *ip6addr = NULL; + struct in6_addr des_addr = IN6ADDR_ANY_INIT; + struct rt6_info *rt = rt6_lookup(&init_net, &des_addr, NULL, 0, 0); + + if (rt) + { + ip6addr = &rt->rt6i_gateway; + } + + return ip6addr; +} + +static int add_pppoev6_host_entry(void) +{ + struct in6_addr local_lan6ip = IN6ADDR_ANY_INIT; + unsigned long flags; + int ppp_sid, ppp_sid2; + unsigned char ppp_peer_mac[ETH_ALEN]; + unsigned char ppp_peer_mac2[ETH_ALEN]; + a_uint32_t ppp_peer_ip = 0; + int wvid; + fal_host_entry_t nh_arp_entry; + sw_error_t rv; + a_uint32_t droute_entry_id = 0; + a_bool_t ena; + static fal_pppoe_session_t pppoev6_sid_table = {0}; + struct in6_addr *next_hop; + + local_irq_save(flags); + memcpy(&local_lan6ip, &lan6ip, sizeof(struct in6_addr)); + ppp_sid2 = nf_athrs17_hnat_ppp_id2; + ppp_sid = nf_athrs17_hnat_ppp_id; + ppp_peer_ip = nf_athrs17_hnat_ppp_peer_ip; + memcpy(ppp_peer_mac, nf_athrs17_hnat_ppp_peer_mac, ETH_ALEN); + memcpy(ppp_peer_mac2, nf_athrs17_hnat_ppp_peer_mac2, ETH_ALEN); + wvid = wan_fid; + local_irq_restore(flags); + + if (NF_S17_WAN_TYPE_PPPOE != nf_athrs17_hnat_wan_type) + { + return SW_BAD_STATE; + } + + if (__ipv6_addr_type(&local_lan6ip) == IPV6_ADDR_ANY) + { + /* Cannot get lanip6 successfully. */ + return SW_BAD_STATE; + } + if (0xffff == wvid) + { + printk("%s: Cannot get WAN vid!\n", __FUNCTION__); + return SW_FAIL; + } + + if (0 == nf_athrs17_hnat_ppp_peer_ip) + { + return SW_FAIL; + } + + next_hop = get_ipv6_default_gateway(); + if (NULL == next_hop) + { + printk("No IPv6 Gateway!\n"); + return SW_BAD_STATE; + } + + if (0 != ppp_sid) + { + if ((ppp_sid == ppp_sid2)||(0 == ppp_sid2)) /* v4 and v6 have the same session id */ + { + memset(&nh_arp_entry, 0, sizeof(nh_arp_entry)); + nh_arp_entry.ip4_addr = ppp_peer_ip; + nh_arp_entry.flags = FAL_IP_IP4_ADDR; + rv = IP_HOST_GET(0, FAL_IP_ENTRY_IPADDR_EN, &nh_arp_entry); + if (rv != SW_OK) + { + printk("%s: IP_HOST_GET error (0x%08x)\n", __func__, ppp_peer_ip); + if (PPPOE_STATUS_GET(0, &ena) != SW_OK) + { + if (!ena) + { + if (PPPOE_STATUS_SET(0, A_TRUE) != SW_OK) + { + aos_printk("Cannot enable the PPPoE mode\n"); + return SW_FAIL; + } + } + } + pppoev6_sid_table.session_id = ppp_sid; + pppoev6_sid_table.multi_session = 1; + pppoev6_sid_table.uni_session = 1; + pppoev6_sid_table.entry_id = 0; + /* set the PPPoE edit reg (0x2200), and PPPoE session reg (0x5f000) */ + rv = PPPOE_SESSION_TABLE_ADD(0, &pppoev6_sid_table); + if (rv == SW_OK) + { + a_int32_t a_entry_id = -1; + + PPPOE_SESSION_ID_SET(0, pppoev6_sid_table.entry_id, pppoev6_sid_table.session_id); + aos_printk("pppoe session: %d, entry_id: %d\n", + pppoev6_sid_table.session_id, pppoev6_sid_table.entry_id); + /* create the peer host ARP entry */ + a_entry_id = arp_hw_add(S17_WAN_PORT, wan_fid, (void *)&ppp_peer_ip, (void *)ppp_peer_mac, 0); + if (a_entry_id >= 0) /* hostentry creation okay */ + { + rv = IP_HOST_PPPOE_BIND(0, a_entry_id, pppoev6_sid_table.entry_id, A_TRUE); + if ( rv != SW_OK) + { + aos_printk("IP_HOST_PPPOE_BIND failed (entry: %d, rv: %d)... \n", + a_entry_id, rv); + PPPOE_SESSION_TABLE_DEL(0, &pppoev6_sid_table); + return SW_FAIL; + } + droute_entry_id = a_entry_id; + } + else + { + PPPOE_SESSION_TABLE_DEL(0, &pppoev6_sid_table); + return SW_FAIL; + } + } + else + { + aos_printk("PPPoE session add failed.. (id: %d)\n", + pppoev6_sid_table.session_id); + aos_printk("rv: %d\n", rv); + return SW_FAIL; + } + } + else + { + droute_entry_id = nh_arp_entry.entry_id; + } + ipv6_droute_add_acl_rules(&local_lan6ip, droute_entry_id); + } + else /* Not the same session id */ + { + if (PPPOE_STATUS_GET(0, &ena) != SW_OK) + { + if (!ena) + { + if (PPPOE_STATUS_SET(0, A_TRUE) != SW_OK) + { + aos_printk("Cannot enable the PPPoE mode\n"); + return SW_FAIL; + } + } + } + memset(&nh_arp_entry, 0, sizeof(nh_arp_entry)); + memcpy((void *)&nh_arp_entry.ip6_addr, (void *)next_hop, sizeof(nh_arp_entry.ip6_addr)); + nh_arp_entry.flags = FAL_IP_IP6_ADDR; + rv = IP_HOST_GET(0, FAL_IP_ENTRY_IPADDR_EN, &nh_arp_entry); + if (rv != SW_OK) + { + /* ARP alread setup. */ + return SW_OK; + } + pppoev6_sid_table.session_id = ppp_sid2; + pppoev6_sid_table.multi_session = 1; + pppoev6_sid_table.uni_session = 1; + pppoev6_sid_table.entry_id = 0; + /* set the PPPoE edit reg (0x2200), and PPPoE session reg (0x5f000) */ + rv = PPPOE_SESSION_TABLE_ADD(0, &pppoev6_sid_table); + if (rv == SW_OK) + { + a_int32_t a_entry_id = -1; + + PPPOE_SESSION_ID_SET(0, pppoev6_sid_table.entry_id, pppoev6_sid_table.session_id); + aos_printk("pppoe session: %d, entry_id: %d\n", + pppoev6_sid_table.session_id, pppoev6_sid_table.entry_id); + /* create the peer host ARP entry */ + a_entry_id = arp_hw_add(S17_WAN_PORT, wan_fid, (void *)next_hop, ppp_peer_mac2, 1); + if (a_entry_id >= 0) /* hostentry creation okay */ + { + rv = IP_HOST_PPPOE_BIND(0, a_entry_id, pppoev6_sid_table.entry_id, A_TRUE); + if ( rv != SW_OK) + { + aos_printk("IP_HOST_PPPOE_BIND failed (entry: %d, rv: %d)... \n", + a_entry_id, rv); + PPPOE_SESSION_TABLE_DEL(0, &pppoev6_sid_table); + return SW_FAIL; + } + droute_entry_id = a_entry_id; + } + else + { + PPPOE_SESSION_TABLE_DEL(0, &pppoev6_sid_table); + return SW_FAIL; + } + } + else + { + aos_printk("PPPoE session add failed.. (id: %d)\n", + pppoev6_sid_table.session_id); + aos_printk("rv: %d\n", rv); + return SW_FAIL; + } + ipv6_droute_add_acl_rules(&local_lan6ip, droute_entry_id); + } + } + + return SW_OK; +} + +uint32_t napt_set_ipv6_default_route(void) +{ + sw_error_t rv; + static a_bool_t ipv6_droute_setup = A_FALSE; + static struct ipv6_default_route_binding ipv6_droute_bind = {IN6ADDR_ANY_INIT,0}; + struct in6_addr local_lan6ip = IN6ADDR_ANY_INIT; + unsigned long flags; + + if (((nat_chip_ver&0xffff)>>8) == DESS_CHIP_VER) + return SW_OK; + + /* search for the next hop (s)*/ + if (NF_S17_WAN_TYPE_IP == nf_athrs17_hnat_wan_type) + { + struct in6_addr *next_hop = get_ipv6_default_gateway(); + + // printk("IPv6 next hop: %pI6\n", next_hop); + + if (next_hop != NULL) + { + fal_host_entry_t ipv6_neigh_entry; + + if (__ipv6_addr_type(next_hop) == IPV6_ADDR_LINKLOCAL) + return SW_OK; + + local_irq_save(flags); + memcpy(&local_lan6ip, &lan6ip, sizeof(struct in6_addr)); + local_irq_restore(flags); + + memset(&ipv6_neigh_entry, 0, sizeof(ipv6_neigh_entry)); + memcpy(&ipv6_neigh_entry.ip6_addr, next_hop, 16); + ipv6_neigh_entry.flags = FAL_IP_IP6_ADDR; + rv = IP_HOST_GET(0, FAL_IP_ENTRY_IPADDR_EN, &ipv6_neigh_entry); + if ((rv != SW_OK)||(__ipv6_addr_type(&local_lan6ip) == IPV6_ADDR_ANY)) + { + if (ipv6_droute_setup) + { + ipv6_droute_del_acl_rules(); + memset(&ipv6_droute_bind, 0, sizeof(ipv6_droute_bind)); + ipv6_droute_setup = A_FALSE; + } + } + else + { + if (ipv6_droute_setup) + { + if (!ipv6_addr_equal(&ipv6_droute_bind.next_hop, next_hop) || + ipv6_droute_bind.nh_entry_id != ipv6_neigh_entry.entry_id) + { + ipv6_droute_del_acl_rules(); + } + } + ipv6_droute_bind.next_hop = *next_hop; + ipv6_droute_bind.nh_entry_id = ipv6_neigh_entry.entry_id; + + ipv6_droute_add_acl_rules(&local_lan6ip, ipv6_neigh_entry.entry_id); + ipv6_droute_setup = A_TRUE; + } + } + else + { + if (ipv6_droute_setup) + { + ipv6_droute_del_acl_rules(); + memset(&ipv6_droute_bind, 0, sizeof(ipv6_droute_bind)); + ipv6_droute_setup = A_FALSE; + } + } + } + else if (NF_S17_WAN_TYPE_IP == nf_athrs17_hnat_wan_type) + { + add_pppoev6_host_entry(); + } + + return SW_OK; +} +#endif /* ifdef CONFIG_IPV6_HWACCEL */ + +static sw_error_t hnat_add_host_route( + fal_ip4_addr_t ip_addr, + uint32_t prefix_len) +{ + fal_host_route_t host_route; + + memset(&host_route, 0, sizeof(fal_host_route_t)); + + fal_ip_host_route_get(0, 0, &host_route); + if ((host_route.route_addr.ip4_addr == ip_addr) && + (host_route.prefix_length == prefix_len) && + host_route.valid) + return SW_OK; + + host_route.valid = A_TRUE; + host_route.vrf_id = 0; + host_route.ip_version = 0; + host_route.route_addr.ip4_addr = ip_addr; + host_route.prefix_length = prefix_len; + + return fal_ip_host_route_set(0, 0, &host_route); +} +static sw_error_t setup_interface_entry(char *list_if, int is_wan) +{ + char temp[IFNAMSIZ*4]; /* Max 4 interface entries right now. */ + char *dev_name, *list_all; + struct net_device *nat_dev; + struct in_device *in_device_lan = NULL, *in_device_wan = NULL; + uint8_t *devmac, if_mac_addr[MAC_LEN]; + char *br_name; + uint32_t vid = 0; + sw_error_t setup_error; + uint32_t ipv6 = 0; + + memcpy(temp, list_if, strlen(list_if)+1); + list_all = temp; + + setup_error = SW_FAIL; + rcu_read_lock(); + while ((dev_name = strsep(&list_all, " ")) != NULL) + { + nat_dev = dev_get_by_name(&init_net, dev_name); + if (NULL == nat_dev) + { + // printk("%s: Cannot get device %s by name!\n", __FUNCTION__, dev_name); + setup_error = SW_FAIL; + continue; + } +#if defined (CONFIG_BRIDGE) +#ifdef KVER32 + if (NULL != br_port_get_rcu(nat_dev)) /* under bridge interface. */ + { + /* Get bridge interface name */ + br_name = (char *)(br_port_get_rcu(nat_dev)->br->dev->name); + if (!is_wan) { + strlcat (nat_lan_dev_list, " ", sizeof(nat_lan_dev_list)); + strlcat (nat_lan_dev_list, br_name, sizeof(nat_lan_dev_list)); + } + /* Get dmac */ + devmac = (uint8_t *)(br_port_get_rcu(nat_dev)->br->dev->dev_addr); + } +#else + if (NULL != nat_dev->br_port) /* under bridge interface. */ + { + /* Get bridge interface name */ + br_name = (char *)nat_dev->br_port->br->dev->name; + //memcpy (nat_bridge_dev, br_name, sizeof(br_name)); + strcat (nat_lan_dev_list, " "); + strcat (nat_lan_dev_list, br_name); + /* Get dmac */ + devmac = (uint8_t *)nat_dev->br_port->br->dev->dev_addr; + } +#endif + else +#endif /* CONFIG_BRIDGE */ + { + devmac = (uint8_t *)nat_dev->dev_addr; + } + /* get vid */ +#if 0 +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) + vid = vlan_dev_vlan_id(nat_dev); +#else + vid = 0; +#endif +#endif + if(is_wan) + vid = nat_wan_vid; + else + vid = nat_lan_vid; +#ifdef CONFIG_IPV6_HWACCEL + ipv6 = 1; + if (is_wan) + { + wan_fid = vid; + } +#else + ipv6 = 0; + if (is_wan) + { + if (NF_S17_WAN_TYPE_PPPOEV6 == nf_athrs17_hnat_wan_type) + ipv6 = 1; + wan_fid = vid; + } +#endif +#ifdef ISISC + if (0 == is_wan) /* Not WAN -> LAN */ + { + /* Setup private and netmask as soon as possible */ + if (br_port_get_rcu(nat_dev)) /* under bridge interface. */ + { + in_device_lan = (struct in_device *) (br_port_get_rcu(nat_dev)->br->dev->ip_ptr); + } + else + { + in_device_lan = (struct in_device *) nat_dev->ip_ptr; + } + + if ((in_device_lan) && (in_device_lan->ifa_list)) + { + nat_hw_prv_mask_set((a_uint32_t)(in_device_lan->ifa_list->ifa_mask)); + nat_hw_prv_base_set((a_uint32_t)(in_device_lan->ifa_list->ifa_address)); +#ifndef KVER32 + printk("Set private base 0x%08x for %s\n", (a_uint32_t)(in_device_lan->ifa_list->ifa_address), nat_dev->br_port->br->dev->name); +#endif + memcpy(&lanip, (void *)&(in_device_lan->ifa_list->ifa_address), 4); /* copy Lan port IP. */ + memcpy(&lanipmask, (void *)&(in_device_lan->ifa_list->ifa_mask), 4); +#ifndef ISISC + redirect_internal_ip_packets_to_cpu_on_wan_add_acl_rules((a_uint32_t)(in_device_lan->ifa_list->ifa_address), + (a_uint32_t)(in_device_lan->ifa_list->ifa_mask)); +#endif + } + + if(setup_lan_if) { + dev_put(nat_dev); + rcu_read_unlock(); + return SW_OK; + } else { + setup_lan_if = 1; + } + } +#endif + if (1 == is_wan) { + if (br_port_get_rcu(nat_dev)) { + in_device_wan = (struct in_device *) (br_port_get_rcu(nat_dev)->br->dev->ip_ptr); + } else { + in_device_wan = (struct in_device *) nat_dev->ip_ptr; + } + if((nf_athrs17_hnat_wan_type == NF_S17_WAN_TYPE_IP) && + (in_device_wan) && (in_device_wan->ifa_list)) + { + a_uint32_t index; + + if (((nat_chip_ver&0xffff) >> 8) == DESS_CHIP_VER) { + a_uint32_t ip, len; + + ip = in_device_wan->ifa_list->ifa_address & in_device_wan->ifa_list->ifa_mask; + ip = ntohl(ip); + len = 32 - ffs(ntohl(in_device_wan->ifa_list->ifa_mask)); + hnat_add_host_route(ip, len); + } + nat_hw_pub_ip_add(ntohl((a_uint32_t)(in_device_wan->ifa_list->ifa_address)), + &index); + HNAT_PRINTK("pubip add 0x%x\n", (a_uint32_t)(in_device_wan->ifa_list->ifa_address)); + } + } + memcpy(if_mac_addr, devmac, MAC_LEN); + devmac = if_mac_addr; + dev_put(nat_dev); + + if(if_mac_add(devmac, vid, ipv6) != 0) + { + setup_error = SW_FAIL; + continue; + } + else + { + setup_error = SW_OK; + break; + } + } + + rcu_read_unlock(); + return setup_error; +} + +static void setup_dev_list(void) +{ + fal_vlan_t entry; + uint32_t tmp_vid = 0xffffffff; + + /*get the vlan entry*/ + while(1) { + if(SW_OK != VLAN_NEXT(0, tmp_vid, &entry)) + break; + tmp_vid = entry.vid; + if(tmp_vid != 0) { + if(entry.mem_ports & nat_wan_port) { + /*wan port*/ + HNAT_PRINTK("wan port vid:%d\n", tmp_vid); + nat_wan_vid = tmp_vid; + snprintf(nat_wan_dev_list, IFNAMSIZ*5, + "eth0.%d eth0 pppoe-wan erouter0 br-wan", + tmp_vid); + } else { + /*lan port*/ + HNAT_PRINTK("lan port vid:%d\n", tmp_vid); + nat_lan_vid = tmp_vid; + snprintf(nat_lan_dev_list, IFNAMSIZ*4, "eth0.%d eth1 eth1.%d br-lan", + tmp_vid, tmp_vid); + } + } + } +} + +static int setup_all_interface_entry(void) +{ + //static int setup_lan_if=0; + static int setup_default_vid = 0; + int i = 0; + + setup_dev_list(); + + if (0 == setup_default_vid) + { + for (i=0; i<7; i++) /* For AR8327/AR8337, only 7 port */ + { +#ifdef NAT_TODO /* need to implement here */ + PORTVLAN_ROUTE_DEFV_SET(0, i); +#endif + } + setup_default_vid = 1; + } + + //if (0 == setup_lan_if) + { +#ifdef ISISC + //MISC_ARP_CMD_SET(0, FAL_MAC_FRWRD); /* Should be put in init function. */ +#if 0 + MISC_ARP_SP_NOT_FOUND_SET(0, FAL_MAC_RDT_TO_CPU); +#endif +#endif + if (SW_OK == setup_interface_entry(nat_lan_dev_list, 0)) + { + //setup_lan_if = 1; /* setup LAN interface entry success */ + //printk("Setup LAN interface entry done!\n"); + } + } + + if (0 == setup_wan_if) + { + if (SW_OK == setup_interface_entry(nat_wan_dev_list, 1)) + { + setup_wan_if = 1; /* setup WAN interface entry success */ + } + } + if (((nat_chip_ver&0xffff)>>8) == NAT_CHIP_VER_8327) { + if ((nf_athrs17_hnat_wan_type == NF_S17_WAN_TYPE_PPPOE) || + (nf_athrs17_hnat_wan_type == NF_S17_WAN_TYPE_PPPOEV6)) + { + uint8_t buf[6]; + + memcpy(buf, nf_athrs17_hnat_ppp_peer_mac, ETH_ALEN); + HNAT_PRINTK("Peer MAC: %s ", buf); + /* add the peer interface with VID */ + if_mac_add(buf, wan_fid, 0); + HNAT_PRINTK(" --> (%.2x-%.2x-%.2x-%.2x-%.2x-%.2x)\n", \ + buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); + memcpy(&wanip, (void *)&nf_athrs17_hnat_wan_ip, 4); + } + } + + return 1; +} + +/* check for pppoe session change */ +static void isis_pppoe_check_for_redial(void) +{ + if (nf_athrs17_hnat_wan_type == NF_S17_WAN_TYPE_IP) + return; + + if(((nf_athrs17_hnat_wan_type == NF_S17_WAN_TYPE_PPPOE) \ + || (nf_athrs17_hnat_wan_type == NF_S17_WAN_TYPE_PPPOEV6)) \ + && (pppoetbl.session_id != 0)) + { + if(pppoetbl.session_id != nf_athrs17_hnat_ppp_id) + { + aos_printk("%s: PPPoE session ID changed... \n", __func__); + if (nf_athrs17_hnat_wan_type != NF_S17_WAN_TYPE_PPPOEV6) + { + if (PPPOE_SESSION_TABLE_DEL(0, &pppoetbl) != SW_OK) + { + aos_printk("delete old pppoe session %d entry_id %d failed.. \n", pppoetbl.session_id, pppoetbl.entry_id); + return; + } + + /* force PPPoE parser for multi- and uni-cast packets; for v1.0.7+ */ + pppoetbl.session_id = nf_athrs17_hnat_ppp_id; + pppoetbl.multi_session = 1; + if (((nat_chip_ver & 0xffff)>>8) == NAT_CHIP_VER_8327) + pppoetbl.uni_session = 1; + else + pppoetbl.uni_session = 0; + pppoetbl.entry_id = 0; + /* set the PPPoE edit reg (0x2200), and PPPoE session reg (0x5f000) */ + if (PPPOE_SESSION_TABLE_ADD(0, &pppoetbl) == SW_OK) + { + PPPOE_SESSION_ID_SET(0, pppoetbl.entry_id, pppoetbl.session_id); + printk("%s: new pppoe session id: %x, entry_id: %x\n", __func__, pppoetbl.session_id, pppoetbl.entry_id); + } + } + else /* nf_athrs17_hnat_wan_type == NF_S17_WAN_TYPE_PPPOEV6 */ + { + /* reset the session Id only */ + aos_printk("IPV6 PPPOE mode... \n"); + pppoetbl.session_id = nf_athrs17_hnat_ppp_id; + PPPOE_SESSION_ID_SET(0, pppoetbl.entry_id, pppoetbl.session_id); + printk("%s: new pppoe session id: %x, entry_id: %x\n", __func__, pppoetbl.session_id, pppoetbl.entry_id); + } + /* read back the WAN IP */ + memcpy(&wanip, (void *)&nf_athrs17_hnat_wan_ip, 4); + aos_printk("Read the WAN IP back... %.8x\n", *(uint32_t *)&wanip); + /* change the PPPoE ACL to ensure the packet is correctly forwarded by the HNAT engine */ + pppoe_add_acl_rules(*(uint32_t *)&wanip, *(uint32_t *)&lanip, + *(uint32_t *)&lanipmask, pppoe_gwid); + } + } +} + +#ifdef ISIS /* only for S17 */ +static void pppoev6_mac6_loop_dev(void) +{ +#define PPPOEV6_SESSION_ID 0xfffe + fal_pppoe_session_t ptbl; + sw_error_t rv; + a_uint32_t entry; + + memset(&ptbl, 0, sizeof(fal_pppoe_session_t)); + + aos_printk("%s: set MAC6 as loopback device\n", __func__); + + ptbl.session_id = PPPOEV6_SESSION_ID; + ptbl.multi_session = 1; + ptbl.uni_session = 1; + ptbl.entry_id = 0xe; + + /* set the PPPoE edit reg (0x2200), and PPPoE session reg (0x5f000) */ + if (PPPOE_SESSION_TABLE_ADD(0, &ptbl) == SW_OK) + { + PPPOE_SESSION_ID_SET(0, ptbl.entry_id, ptbl.session_id); + aos_printk("%s: pppoe session id: %d added into entry: %d \n", __func__, ptbl.session_id, ptbl.entry_id); + } + else + { + aos_printk("%s: failed on adding pppoe session id: %d\n", __func__, ptbl.session_id); + } + + /* PPPoE entry 0 */ + entry = PPPOEV6_SESSION_ID; + HSL_REG_ENTRY_SET(rv, 0, PPPOE_EDIT, 0, (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + + aos_printk("%s: end of function... \n", __func__); +} + +static void pppoev6_remove_parser(uint32_t entry_id) +{ + sw_error_t rv; + a_uint32_t entry; + + aos_printk("%s: clear entry id: %d\n", __func__, entry_id); + /* clear the session id in the PPPoE parser engine */ + entry = 0; + HSL_REG_ENTRY_SET(rv, 0, PPPOE_SESSION, + entry_id, (a_uint8_t *) (&entry), sizeof (a_uint32_t)); +} + +#if 0 +static void pppoev6_mac6_stop_learning(void) +{ + /* do not disable this port if some other registers are already filled in + to prevent setting conflict */ + int val = S17_P6PAD_MODE_REG_VALUE; + sw_error_t rv; + a_uint32_t entry; + + if ( val != (1<<24)) + { + aos_printk("%s: MAC 6 already being used!\n", __FUNCTION__); + return; + } + + + /* clear the MAC6 learning bit */ + HSL_REG_ENTRY_GET(rv, 0, PORT_LOOKUP_CTL, 6, (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + entry = entry & ~(1<<20); + HSL_REG_ENTRY_SET(rv, 0, PORT_LOOKUP_CTL, 6, (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + + /* force loopback mode */ + entry = 0x7e; + HSL_REG_ENTRY_SET(rv, 0, PORT_STATUS, 6, (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + entry = 0x10; + HSL_REG_ENTRY_SET(rv, 0, PORT_HDR_CTL, 6, (a_uint8_t *) (&entry), sizeof (a_uint32_t)); +} +#endif +#endif // ifdef ISIS + +static int add_pppoe_host_entry(uint32_t sport, a_int32_t arp_entry_id) +{ + a_bool_t ena; + int rv = SW_OK; + fal_host_entry_t nh_arp_entry; + + if (0xffff == wan_fid) + { + printk("%s: Cannot get WAN vid!\n", __FUNCTION__); + return SW_FAIL; + } + + if (PPPOE_STATUS_GET(0, &ena) != SW_OK) + { + aos_printk("Cannot get the PPPoE mode\n"); + ena = 0; + } + + memset(&nh_arp_entry, 0, sizeof(nh_arp_entry)); + nh_arp_entry.ip4_addr = ntohl(nf_athrs17_hnat_ppp_peer_ip); + nh_arp_entry.flags = FAL_IP_IP4_ADDR; + rv = IP_HOST_GET(0, FAL_IP_ENTRY_IPADDR_EN, &nh_arp_entry); + if (SW_OK != rv || pppoetbl.session_id != nf_athrs17_hnat_ppp_id) + { + if ((!ena) && (PPPOE_STATUS_SET(0, A_TRUE) != SW_OK)) + aos_printk("Cannot enable the PPPoE mode\n"); + + aos_printk("PPPoE enable mode: %d\n", ena); + + pppoetbl.session_id = nf_athrs17_hnat_ppp_id; + pppoetbl.multi_session = 1; + if (((nat_chip_ver & 0xffff)>>8) == NAT_CHIP_VER_8327) + pppoetbl.uni_session = 1; + else + pppoetbl.uni_session = 0; + pppoetbl.entry_id = 0; + + /* set the PPPoE edit reg (0x2200), and PPPoE session reg (0x5f000) */ + rv = PPPOE_SESSION_TABLE_ADD(0, &pppoetbl); + if (rv == SW_OK) + { + uint8_t mbuf[6], ibuf[4]; + a_int32_t a_entry_id = -1; + a_uint32_t index; + + PPPOE_SESSION_ID_SET(0, pppoetbl.entry_id, pppoetbl.session_id); + aos_printk("pppoe session: %d, entry_id: %d\n", pppoetbl.session_id, pppoetbl.entry_id); + + if (((nat_chip_ver&0xffff)>>8) == DESS_CHIP_VER) { + hnat_add_host_route(ntohl(nf_athrs17_hnat_wan_ip), + HOST_PREFIX_MAX); + } + + /* create the peer host ARP entry */ + memcpy(ibuf, (void *)&nf_athrs17_hnat_ppp_peer_ip, 4); + memcpy(mbuf, nf_athrs17_hnat_ppp_peer_mac, ETH_ALEN); + + a_entry_id = arp_hw_add(S17_WAN_PORT, wan_fid, ibuf, mbuf, 0); + if (a_entry_id >= 0) /* hostentry creation okay */ + { + aos_printk("(1)Bind PPPoE session ID: %d, entry_id: %d to host entry: %d\n", \ + pppoetbl.session_id, pppoetbl.entry_id, a_entry_id); + + rv = IP_HOST_PPPOE_BIND(0, a_entry_id, pppoetbl.entry_id, A_TRUE); + if ( rv != SW_OK) + { + aos_printk("IP_HOST_PPPOE_BIND failed (entry: %d, rv: %d)... \n", a_entry_id, rv); + } + + aos_printk("adding ACLs \n"); + pppoe_gwid = a_entry_id; + pppoe_add_acl_rules(nf_athrs17_hnat_wan_ip, *(uint32_t *)&lanip, + *(uint32_t *)&lanipmask, a_entry_id); + nat_hw_pub_ip_add(ntohl(nf_athrs17_hnat_wan_ip), &index); + aos_printk("ACL creation okay... \n"); + } else { + HNAT_PRINTK("pppoe arp add fail!\n"); + } + } + else + { + aos_printk("PPPoE session add failed.. (id: %d)\n", pppoetbl.session_id); + aos_printk("rv: %d\n", rv); + } + +#ifdef ISIS + if (nf_athrs17_hnat_wan_type == NF_S17_WAN_TYPE_PPPOEV6) + { + aos_printk("IPV6 PPPOE mode... (share the same ID with IPV4's)\n"); + pppoev6_mac6_loop_dev(); + pppoev6_remove_parser(pppoetbl.entry_id); + + /* bind the first LAN host to the pseudo PPPoE ID */ + rv = IP_HOST_PPPOE_BIND(0, arp_entry_id, 0, A_TRUE); + if ( rv != SW_OK) + { + aos_printk("IP_HOST_PPPOE_BIND failed (entry: %d, rv: %d)... \n", arp_entry_id, rv); + } + } +#endif // ifdef ISIS + } +#ifdef ISIS + else /* ena */ + { + if ((nf_athrs17_hnat_wan_type == NF_S17_WAN_TYPE_PPPOEV6) && + (sport != S17_WAN_PORT)&& (arp_entry_id != 0)) + { + aos_printk("IPV6 PPPoE mode\n"); + /* bind LAN hosts to the pseudo PPPoE ID */ + rv = IP_HOST_PPPOE_BIND(0, arp_entry_id, 0, A_TRUE); + if ( rv != SW_OK) + { + aos_printk("IP_HOST_PPPOE_BIND failed (entry: %d, rv: %d)... \n", arp_entry_id, rv); + } + } + } +#endif // ifdef ISIS + + return SW_OK; +} + +static int +dev_check(char *in_dev, char *dev_list) +{ + char *list_dev; + char temp[100] = {0}; + char *list; + + if(!in_dev || !dev_list) + { + return 0; + } + + strlcpy(temp, dev_list, sizeof(temp)); + list = temp; + + while ((list_dev = strsep(&list, " ")) != NULL) + { + HNAT_PRINTK("%s: strlen:%d list_dev:%s in_dev:%s\n", + __func__, strlen(list_dev), list_dev, in_dev); + + if (!strncmp(list_dev, in_dev, strlen(list_dev))) + { + HNAT_PRINTK("%s: %s\n", __FUNCTION__, list_dev); + return 1; + } + } + + return 0; +} + +#ifndef ISISC +static uint32_t get_netmask_from_netdevice(const struct net_device *in_net_dev) +{ + struct in_device *my_in_device = NULL; + uint32_t result = 0xffffff00; + + if((in_net_dev) && (in_net_dev->ip_ptr != NULL)) + { + my_in_device = (struct in_device *)(in_net_dev->ip_ptr); + if(my_in_device->ifa_list != NULL) + { + result = my_in_device->ifa_list->ifa_mask; + } + } + + return result; +} +#endif + + +static void hnat_add_neigh(struct neighbour *neigh) +{ + struct nat_helper_bg_msg msg; + struct net_device *dev = NULL; + + memset(&msg, 0, sizeof(msg)); + msg.arp_in.ip = *((uint32_t *)neigh->primary_key); + memcpy(msg.arp_in.mac, neigh->ha, ETH_ALEN); + strlcpy(msg.arp_in.name, neigh->dev->name, IFNAMSIZ); + msg.arp_in.in = neigh->dev; + + if (neigh->dev->priv_flags & IFF_EBRIDGE) { + if (!(dev = br_port_dev_get(neigh->dev, neigh->ha, NULL, 0))) { + HNAT_ERR_PRINTK("Failed to find bridge port by [%pM]\n", + neigh->ha); + return ; + } + } else { + dev = neigh->dev; + dev_hold(dev); + } + + if (strncmp(dev->name, "eth", strlen("eth")) && + strncmp(dev->name, "erouter", strlen("erouter"))) { + dev_put(dev); + return ; + } + + dev_put(dev); + + msg.msg_type = NAT_HELPER_ARP_ADD_MSG; + bg_ring_buf_write(msg); +} + +static void hnat_del_neigh(struct neighbour *neigh) +{ + struct nat_helper_bg_msg msg; + + memset(&msg, 0, sizeof(msg)); + msg.arp_in.ip = ntohl(*((uint32_t *)neigh->primary_key)); + + msg.msg_type = NAT_HELPER_ARP_DEL_MSG; + bg_ring_buf_write(msg); +} + +static int hnat_netevent_event(struct notifier_block *unused, unsigned long event, void *ptr) +{ + struct neigh_table *tbl; + struct neighbour *neigh; + + if (event != NETEVENT_NEIGH_UPDATE) + return NOTIFY_DONE; + + neigh = ptr; + tbl = neigh->tbl; + + if (tbl->family != AF_INET) + return NOTIFY_DONE; + + HNAT_PRINTK("netevent state %d for ip[%pI4]\n", + neigh->nud_state, (uint32_t *)neigh->primary_key); + + if (neigh->nud_state & NUD_VALID) { + if (neigh->nud_state & NUD_NOARP) { + return NOTIFY_DONE; + } + + HNAT_PRINTK("New ARP entry ip[%pI4] mac[%pM]\n", + (uint32_t *)neigh->primary_key, neigh->ha); + hnat_add_neigh(neigh); + } else { + HNAT_PRINTK("Del ARP entry ip[%pI4] mac[%pM] with status[%d]\n", + (uint32_t *)neigh->primary_key, neigh->ha, neigh->nud_state); + hnat_del_neigh(neigh); + } + + return NOTIFY_DONE; +} + +#ifdef NAT_BACKGROUND_TASK +static unsigned int +arp_del(struct nat_helper_bg_msg *msg) +{ + fal_host_entry_t host; + + memset(&host, 0, sizeof(host)); + + if (!nat_hw_prv_base_is_match(msg->arp_in.ip)) + return 0; + + if (napt_hw_get_by_sip(msg->arp_in.ip)) { + host.flags |= FAL_IP_IP4_ADDR; + host.ip4_addr = msg->arp_in.ip; + IP_HOST_DEL(0, FAL_IP_ENTRY_IPADDR_EN, &host); + } + + return 0; +} + +static unsigned int +arp_add(struct nat_helper_bg_msg *msg) +{ + uint8_t *smac; + uint8_t dev_is_lan = 0; + uint32_t sport = 0, vid = 0; + a_bool_t prvbasemode = 1; + sw_error_t rv = SW_OK; + struct arp_in_msg *arp_info = &msg->arp_in; + a_int32_t arp_entry_id = -1; + fal_fdb_entry_t entry; + + + /* check for PPPoE redial here, to reduce overheads */ + isis_pppoe_check_for_redial(); + + /* do not write out host table if HNAT is disabled */ + if (!nf_athrs17_hnat) + return 0; + + setup_all_interface_entry(); + + if(dev_check((char *)arp_info->name, (char *)nat_wan_dev_list)) + { + + } + else if (dev_check((char *)arp_info->name, (char *)nat_lan_dev_list)) + { + dev_is_lan = 1; + } + else + { + HNAT_INFO_PRINTK("Not Support device: %s\n", (char *)arp_info->name); + return 0; + } + + if(dev_is_lan) { + vid = nat_lan_vid; + } else { + vid = nat_wan_vid; + } + + memset(&entry, 0, sizeof(entry)); + + entry.fid = vid; + + smac = arp_info->mac; + aos_mem_copy(&(entry.addr), smac, sizeof(fal_mac_addr_t)); + if(fal_fdb_entry_search(0, &entry) == SW_OK) { + vid = entry.fid; + sport = 0; + while (sport < 32) { + if(entry.port.map & (1 << sport)) { + break; + } + sport++; + } + } else { + HNAT_PRINTK("not find the FDB entry\n"); + } + + + if (sport == 0) { + HNAT_PRINTK("Not the expected arp, ignore it!\n"); + return 0; + } + + arp_entry_id = arp_hw_add(sport, vid, (a_uint8_t *)&arp_info->ip, smac, 0); + if(arp_entry_id < 0) + { + HNAT_ERR_PRINTK("ARP entry error!!\n"); + return 0; + } + + if (0 == dev_is_lan) + { + struct in_device *in_dev; + + in_dev = __in_dev_get_rtnl(arp_info->in); + if (in_dev) { + if (in_dev->ifa_list) { + *(uint32_t *)&wanip = ntohl(in_dev->ifa_list->ifa_local); + } + } +#ifdef MULTIROUTE_WR + wan_nh_add((u_int8_t *)&arp_info->ip, smac, arp_entry_id); +#endif + } + + if(dev_is_lan && nat_hw_prv_base_can_update()) + { + nat_hw_flush(); + nat_hw_prv_base_update_disable(); +#ifdef MULTIROUTE_WR + //multi_route_indev = in; +#endif + } + multi_route_indev = arp_info->in; + + if ((nf_athrs17_hnat_wan_type == NF_S17_WAN_TYPE_PPPOE) || + (nf_athrs17_hnat_wan_type == NF_S17_WAN_TYPE_PPPOEV6)) + { + add_pppoe_host_entry(sport, arp_entry_id); + } + + if (((nat_chip_ver & 0xffff)>>8) != NAT_CHIP_VER_8327) + return 1; + + /* check for SIP and DIP range */ + if ((lanip[0] != 0) && (wanip[0] != 0)) + { + rv = NAT_PRV_ADDR_MODE_GET(0, &prvbasemode); + if (rv == SW_NOT_SUPPORTED || rv == SW_NOT_INITIALIZED) { + return 1; + } + else if (rv != SW_OK) { + aos_printk("Private IP base mode check failed: %d\n", prvbasemode); + } + + if (!prvbasemode) /* mode 0 */ + { + if ((lanip[0] == wanip[0]) && (lanip[1] == wanip[1])) + { + if ((lanip[2] & 0xf0) == (wanip[2] & 0xf0)) + { + if (get_aclrulemask()& (1 << S17_ACL_LIST_IPCONF)) + return 0; + + aos_printk("LAN IP and WAN IP conflict... \n"); + /* set h/w acl to filter out this case */ +#ifdef MULTIROUTE_WR + // if ( (wan_nh_ent[0].host_ip != 0) && (wan_nh_ent[0].entry_id != 0)) + if ( (wan_nh_ent[0].host_ip != 0)) + ip_conflict_add_acl_rules(*(uint32_t *)&wanip, *(uint32_t *)&lanip, wan_nh_ent[0].entry_id); +#endif + return 0; + } + } + } + else /* mode 1*/ + { + ;; /* do nothing */ + } + } + + return 1; +} +#endif + +static struct notifier_block hnat_netevent_notifier = { + .notifier_call = hnat_netevent_event, +}; + +#ifdef AUTO_UPDATE_PPPOE_INFO +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0)) +struct prv_ppp_file { + int k; + struct sk_buff_head xmitq; + struct sk_buff_head recvq; + wait_queue_head_t wait; + atomic_t cnt; + int hlen; + int idx; + int d; +}; +struct prv_ppp { + struct prv_ppp_file file; + char *o; + struct list_head channels; + int n_channels; + spinlock_t rlock; + spinlock_t wlock; + int m; + unsigned int flags; + unsigned int xmitstate; + unsigned int recvstate; + int d; + char *vj; + int mode[6]; + struct sk_buff *xpending; + char *xcmp; + void *xstate; + char *rcmp; + void *rstate; + unsigned long l_xmit; + unsigned long l_recv; + struct net_device *dev; + int resv1; +#ifdef CONFIG_PPP_MULTILINK + int resv2; + u32 resv3; + int resv4; + u32 resv5; + u32 resv6; + struct sk_buff_head rq; +#endif /* CONFIG_PPP_MULTILINK */ +#ifdef CONFIG_PPP_FILTER + char *p_filter; + char *a_filter; + unsigned p_len, a_len; +#endif /* CONFIG_PPP_FILTER */ + char *pnet; +}; + +struct prv_channel { + struct prv_ppp_file file; + struct list_head list; + struct ppp_channel *chan; + struct rw_semaphore sem; + spinlock_t downlock; + struct prv_ppp *ppp; + char *cnet; + struct list_head clist; + rwlock_t uplock; +#ifdef CONFIG_PPP_MULTILINK + u8 resv1; + u8 resv2; + u32 resv3; + int resv4; +#endif +}; +#endif + +static int qcaswitch_pppoe_ip_event(struct notifier_block *this, + unsigned long event, void *ptr) +{ + struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; + struct net_device *dev = (struct net_device *)ifa->ifa_dev->dev; + #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0)) + struct list_head *list; + struct prv_channel *pch; + struct prv_ppp *ppp = netdev_priv(dev); + #endif + struct sock *sk; + struct pppox_sock *po; + static int connection_count = 0; + fal_pppoe_session_t del_pppoetbl; + int channel_count; + struct ppp_channel *ppp_chan[1]; + int channel_protocol; + + if (!((dev->type == ARPHRD_PPP) && (dev->flags & IFF_POINTOPOINT))) + return NOTIFY_DONE; + + if (dev_net(dev) != &init_net) + return NOTIFY_DONE; + + setup_all_interface_entry(); + + switch (event) + { + case NETDEV_UP: + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) + if (ppp_is_multilink(dev) == 0) { + /* not doing multilink: send it down the first channel */ + channel_count = ppp_hold_channels(dev, ppp_chan, 1); + if (channel_count != 1) + return NOTIFY_DONE; + + channel_protocol = ppp_channel_get_protocol(ppp_chan[0]); + if (channel_protocol == PX_PROTO_OE) + { + if (ppp_chan[0]->private) + { + /* the NETDEV_UP event will be sent many times + * because of ifa operation ifa->ifa_local != ifa->ifa_address + * means that remote ip is really added. + */ + if (ifa->ifa_local == ifa->ifa_address) + { + ppp_release_channels(ppp_chan, 1); + return NOTIFY_DONE; + } + sk = (struct sock *)(ppp_chan[0]->private); + po = (struct pppox_sock*)sk; + connection_count++; + if (((NF_S17_WAN_TYPE_PPPOE == nf_athrs17_hnat_wan_type) && + (0 != nf_athrs17_hnat_ppp_id))) /* another session for IPv6 */ + { + nf_athrs17_hnat_ppp_id2 = ntohs(po->proto.pppoe.pa.sid); + memcpy(nf_athrs17_hnat_ppp_peer_mac2, + po->proto.pppoe.pa.remote, ETH_ALEN); + } else { + nf_athrs17_hnat_wan_type = NF_S17_WAN_TYPE_PPPOE; + nf_athrs17_hnat_wan_ip = ifa->ifa_local; + nf_athrs17_hnat_ppp_peer_ip = ifa->ifa_address; + memcpy(nf_athrs17_hnat_ppp_peer_mac, + po->pppoe_pa.remote, ETH_ALEN); + nf_athrs17_hnat_ppp_id = ntohs(po->pppoe_pa.sid); + } + ppp_release_channels(ppp_chan, 1); + } else { + ppp_release_channels(ppp_chan, 1); + /* channel got unregistered */ + return NOTIFY_DONE; + } + } else { + ppp_release_channels(ppp_chan, 1); + /* channel got unregistered */ + return NOTIFY_DONE; + } + } + #else + //struct prv_ppp *ppp = netdev_priv(dev); + //struct prv_channel *pch; + list = &ppp->channels; + if (list_empty(list)) + return NOTIFY_DONE; + if ((ppp->flags & SC_MULTILINK) == 0) { + list = list->next; + pch = list_entry(list, struct prv_channel, clist); + if (pch->chan) + { + if (pch->chan->private) { + if (ifa->ifa_local == ifa->ifa_address) + return NOTIFY_DONE; + sk = (struct sock *)pch->chan->private; + po = (struct pppox_sock*)sk; + connection_count++; + if (((NF_S17_WAN_TYPE_PPPOE == nf_athrs17_hnat_wan_type) && + (0 != nf_athrs17_hnat_ppp_id))) + { + nf_athrs17_hnat_ppp_id2 = po->num; + memcpy(nf_athrs17_hnat_ppp_peer_mac2, po->pppoe_pa.remote, ETH_ALEN); + } + else + { + nf_athrs17_hnat_wan_type = NF_S17_WAN_TYPE_PPPOE; + nf_athrs17_hnat_wan_ip = ifa->ifa_local; + nf_athrs17_hnat_ppp_peer_ip = ifa->ifa_address; + memcpy(nf_athrs17_hnat_ppp_peer_mac, po->pppoe_pa.remote, ETH_ALEN); + nf_athrs17_hnat_ppp_id = ntohs(po->pppoe_pa.sid); + } + } + } + else + { + return NOTIFY_DONE; + } + } + #endif + break; + + case NETDEV_DOWN: + if (NF_S17_WAN_TYPE_PPPOE != nf_athrs17_hnat_wan_type) + { + return NOTIFY_DONE; + } + connection_count--; + if (ifa->ifa_local == nf_athrs17_hnat_wan_ip) + { + /* PPPoE Interface really down */ + ipv6_droute_del_acl_rules(); + del_pppoetbl.session_id = nf_athrs17_hnat_ppp_id; + del_pppoetbl.multi_session = 1; + if (((nat_chip_ver & 0xffff)>>8) == NAT_CHIP_VER_8327) + del_pppoetbl.uni_session = 1; + else + del_pppoetbl.uni_session = 0; + del_pppoetbl.entry_id = 0; + PPPOE_SESSION_TABLE_DEL(0, &del_pppoetbl); + memset(&pppoetbl, 0, sizeof(pppoetbl)); + nf_athrs17_hnat_wan_type = NF_S17_WAN_TYPE_IP; + nf_athrs17_hnat_wan_ip = 0; + nf_athrs17_hnat_ppp_peer_ip = 0; + nf_athrs17_hnat_ppp_id = 0; + memset(&nf_athrs17_hnat_ppp_peer_mac, 0, ETH_ALEN); + } + else + { + if (0 != nf_athrs17_hnat_ppp_id2) + { + del_pppoetbl.session_id = nf_athrs17_hnat_ppp_id2; + del_pppoetbl.multi_session = 1; + if (((nat_chip_ver & 0xffff)>>8) == NAT_CHIP_VER_8327) + del_pppoetbl.uni_session = 1; + else + del_pppoetbl.uni_session = 0; + del_pppoetbl.entry_id = 0; + PPPOE_SESSION_TABLE_DEL(0, &del_pppoetbl); + memset(&pppoetbl, 0, sizeof(pppoetbl)); + } + nf_athrs17_hnat_ppp_id2 = 0; + memset(&nf_athrs17_hnat_ppp_peer_mac2, 0, ETH_ALEN); + } + qcaswitch_hostentry_flush(); + break; + + default: + break; + } + return NOTIFY_DONE; +} + +/* a linux interface is configured with ipaddr, then + * it becomes a L3 routing interface + * add the router mac of this interface to the table + */ +/* FIXME: only hande pppoe event right now. */ +static int qcaswitch_ip_event(struct notifier_block *this, + unsigned long event, void *ptr) +{ + struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; + struct net_device *dev = (struct net_device *)ifa->ifa_dev->dev; + + if ((dev->type == ARPHRD_PPP) && (dev->flags & IFF_POINTOPOINT)) + { + return qcaswitch_pppoe_ip_event(this, event, ptr); + } + + return NOTIFY_DONE; +} + + +static struct notifier_block qcaswitch_ip_notifier = +{ + .notifier_call = qcaswitch_ip_event, + .priority = 100, +}; +#endif // ifdef AUTO_UPDATE_PPPOE_INFO + +#define HOST_AGEOUT_STATUS 1 +void host_check_aging(void) +{ + fal_host_entry_t *host_entry_p, host_entry= {0}; + sw_error_t rv; + int cnt = 0; + unsigned long flags; + fal_napt_entry_t src_napt = {0}, pub_napt = {0}; + + host_entry_p = &host_entry; + host_entry_p->entry_id = FAL_NEXT_ENTRY_FIRST_ID; + + /*check host is not neccessary, check napt is enough*/ + return; + + local_irq_save(flags); + while (1) + { + host_entry_p->status = HOST_AGEOUT_STATUS; + /* FIXME: now device id is set to 0. */ + rv = IP_HOST_NEXT (0, FAL_IP_ENTRY_STATUS_EN, host_entry_p); + // rv = IP_HOST_NEXT (0, 0, host_entry_p); + if (SW_OK != rv) + break; + if (cnt >= ARP_ENTRY_MAX) // arp entry number + break; + + if (ARP_AGE_NEVER == host_entry_p->status) + continue; + + if ((S17_WAN_PORT == host_entry_p->port_id) && + (host_entry_p->counter_en)) + { + if (0 != host_entry_p->packet) + { + // arp entry is using, update it. + host_entry.status = ARP_AGE; + printk("Update WAN port hostentry!\n"); + IP_HOST_ADD(0, host_entry_p); + } + else + { + printk("Del WAN port hostentry!\n"); + IP_HOST_DEL(0, FAL_IP_ENTRY_IPADDR_EN, host_entry_p); + } + continue; + } + + src_napt.entry_id = FAL_NEXT_ENTRY_FIRST_ID; + memcpy(&src_napt.src_addr, &host_entry_p->ip4_addr, sizeof(fal_ip4_addr_t)); + pub_napt.entry_id = FAL_NEXT_ENTRY_FIRST_ID; + memcpy(&pub_napt.trans_addr, &host_entry_p->ip4_addr, sizeof(fal_ip4_addr_t)); + if((NAPT_NEXT(0, FAL_NAT_ENTRY_SOURCE_IP_EN ,&src_napt) !=0) && \ + (NAPT_NEXT(0, FAL_NAT_ENTRY_PUBLIC_IP_EN ,&pub_napt) != 0)) + { + /* Cannot find naptentry */ + printk("ARP id 0x%x: Cannot find NAPT entry!\n", host_entry_p->entry_id); + IP_HOST_DEL(0, FAL_IP_ENTRY_IPADDR_EN, host_entry_p); + continue; + } + // arp entry is using, update it. + host_entry_p->status = ARP_AGE; + IP_HOST_ADD(0, host_entry_p); + printk("update entry 0x%x port %d\n", host_entry_p->entry_id, host_entry_p->port_id); + cnt++; + } + local_irq_restore(flags); +} + +#ifdef CONFIG_IPV6_HWACCEL +#define IPV6_LEN 16 +#define MAC_LEN 6 +#define PROTO_ICMPV6 0x3a +#define NEIGHBOUR_SOL 135 +#define NEIGHBOUR_AD 136 + +struct icmpv6_option +{ + __u8 type; + __u8 len; + __u8 mac[MAC_LEN]; +}; +#if 0 +static unsigned int ipv6_handle(unsigned int hooknum, + struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + struct sk_buff *new_skb = NULL; + struct nat_helper_bg_msg msg; + /*unsigned long flags = 0;*/ + + if (!nf_athrs17_hnat) + return NF_ACCEPT; + + new_skb = skb_clone(skb, GFP_ATOMIC); + if(new_skb) { + memset(&msg, 0, sizeof(msg)); + msg.msg_type = NAT_HELPER_IPV6_MSG; + msg.ipv6.skb = new_skb; + msg.ipv6.in = (struct net_device *)in; + + /*send msgto background task*/ + /*spin_lock_irqsave(&task_cb.bg_lock, flags);*/ + if(bg_ring_buf_write(msg)) + kfree_skb(new_skb); + /*spin_unlock_irqrestore(&task_cb.bg_lock, flags);*/ + } + + return NF_ACCEPT; + +} +#endif + +#ifdef NAT_BACKGROUND_TASK + +static unsigned int ipv6_bg_handle(struct nat_helper_bg_msg *msg) +{ + struct net_device *in = msg->arp_in.in; + struct sk_buff *skb = msg->arp_in.skb; + + struct ipv6hdr *iph6 = ipv6_hdr(skb); + struct icmp6hdr *icmp6 = icmp6_hdr(skb); + __u8 *sip = ((__u8 *)icmp6)+sizeof(struct icmp6hdr); + struct icmpv6_option *icmpv6_opt = (struct icmpv6_option *)(sip+IPV6_LEN); + __u8 *sa = icmpv6_opt->mac; + + uint32_t sport = 0, vid = 0; + struct inet6_ifaddr *in_device_addr = NULL; + uint8_t dev_is_lan = 0; + uint8_t *smac; + + + /* do not write out host table if HNAT is disabled */ + if (!nf_athrs17_hnat) + return 0; + + setup_all_interface_entry(); + + if(dev_check((char *)in->name, (char *)nat_wan_dev_list)) + { + dev_is_lan = 0; + } + else if (dev_check((char *)in->name, (char *)nat_lan_dev_list)) + { + dev_is_lan = 1; + } + else + { + HNAT_PRINTK("Not Support device: %s\n", (char *)in->name); + return 0; + } + + if(PROTO_ICMPV6 == iph6->nexthdr) + { + if(NEIGHBOUR_AD == icmp6->icmp6_type) + { + fal_fdb_entry_t entry; + if (__ipv6_addr_type((struct in6_addr*)sip) & IPV6_ADDR_LINKLOCAL) + return 0; + +#ifdef AP136_QCA_HEADER_EN + if(arp_if_info_get((void *)(skb->head), &sport, &vid) != 0) + { + return 0; + } + + if ((0 == vid)||(0 == sport)) + { + printk("Error: Null sport or vid!!\n"); + return 0; + } +#else + if(dev_is_lan) { + vid = NAT_LAN_DEV_VID; + } else { + vid = NAT_WAN_DEV_VID; + } + + memset(&entry, 0, sizeof(entry)); + + entry.fid = vid; + smac = skb_mac_header(skb) + MAC_LEN; + aos_mem_copy(&(entry.addr), smac, sizeof(fal_mac_addr_t)); + + if(fal_fdb_entry_search(0, &entry) == SW_OK) { + vid = entry.fid; + sport = 0; + while (sport < 32) { + if(entry.port.map & (1 << sport)) { + break; + } + sport++; + } + } else { + printk("not find the FDB entry\n"); + } +#endif + if ((0 == dev_is_lan) && (S17_WAN_PORT != sport)) + { + printk("Error: WAN port %d\n", sport); + return 0; + } + + HNAT_PRINTK("ND Reply %x %x\n",icmpv6_opt->type,icmpv6_opt->len); + HNAT_PRINTK("isis_v6: incoming packet, sip = %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n" + ,sip[0],sip[1],sip[2],sip[3],sip[4],sip[5],sip[6],sip[7] + ,sip[8],sip[9],sip[10],sip[11],sip[12],sip[13],sip[14],sip[15] + ); + HNAT_PRINTK("isis_v6: incoming packet, sa = %.2x-%.2x-%.2x-%.2x-%.2x-%.2x\n", sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]); + HNAT_PRINTK("isis_v6: vid = %d sport = %d\n", vid, sport); + + //add nd entry + if((2 == icmpv6_opt->type) && (1 == icmpv6_opt->len)) + { + arp_hw_add(sport, vid, sip, sa, 1); + } + else /* ND AD packets without option filed? Fix Me!! */ + { + sa = skb_mac_header(skb) + MAC_LEN; + HNAT_PRINTK("isis_v6 Changed sa = %.2x-%.2x-%.2x-%.2x-%.2x-%.2x\n", sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]); + arp_hw_add(sport, vid, sip, sa, 1); + } + +#ifdef NAT_TODO /* should be ok */ + if ((NULL != in->ip6_ptr) && (NULL != ((struct inet6_dev *)in->ip6_ptr)->addr_list)) +#else + if (NULL != in->ip6_ptr) +#endif + { + //list_for_each_entry(in_device_addr, &(in->ip6_ptr)->addr_list, if_list); + struct inet6_dev *idev = __in6_dev_get(in); + list_for_each_entry(in_device_addr, &idev->addr_list, if_list) { + if (in_device_addr->scope == 0 && + !(in_device_addr->flags & IFA_F_TENTATIVE)) { + break; + } + } + + if (0 == dev_is_lan) + { + /* WAN ipv6 address*/ + memcpy(&wan6ip, (__u8 *)&in_device_addr->addr, sizeof(struct in6_addr)); + HNAT_PRINTK("%s: ipv6 wanip %pI6\n", in->name, &wan6ip); + } + else + { + /* LAN ipv6 address*/ + memcpy(&lan6ip, (__u8 *)&in_device_addr->addr, sizeof(struct in6_addr)); + HNAT_PRINTK("%s: ipv6 lanip %pI6\n", in->name, &lan6ip); + } + } + } + } + + return 1; +} +#endif + +#if 0 +static struct nf_hook_ops ipv6_inhook = +{ + .hook = ipv6_handle, + #if (LINUX_VERSION_CODE < KERNEL_VERSION(4,4,0)) + .owner = THIS_MODULE, + #endif + .pf = PF_INET6, + .hooknum = NF_INET_PRE_ROUTING, + .priority = NF_IP6_PRI_CONNTRACK, +}; +#endif +#endif /* CONFIG_IPV6_HWACCEL */ + +#ifdef NAT_BACKGROUND_TASK + +static void nat_task_entry(struct work_struct *wq) +{ + struct nat_helper_bg_msg msg; + /*unsigned long flags = 0;*/ + unsigned int result = 0; + + msg = *(struct nat_helper_bg_msg *)wq; + + /*spin_lock_irqsave(&task_cb.bg_lock, flags);*/ + bg_ring_buf_read(NULL); + /*spin_unlock_irqrestore(&task_cb.bg_lock, flags);*/ + + if(msg.msg_type == NAT_HELPER_ARP_ADD_MSG) { + result = arp_add(&msg); + } else if (msg.msg_type == NAT_HELPER_ARP_DEL_MSG) { + result = arp_del(&msg); + } + #ifdef CONFIG_IPV6_HWACCEL + else if(msg.msg_type == NAT_HELPER_IPV6_MSG) { + result = ipv6_bg_handle(&msg); + } + #endif + + HNAT_PRINTK("handle msg: %d, result: %d\n", msg.msg_type, result); + +} + +void nat_helper_bg_task_init() +{ + unsigned int i = 0; + struct nat_helper_bg_msg *msg; + /*create the thread and alloc ring buffer*/ + + memset(&task_cb, 0, sizeof(task_cb)); + + task_cb.nat_wq = create_singlethread_workqueue("nat_wq"); + + if(!task_cb.nat_wq) + { + aos_printk("create nat workqueuefail\n"); + return; + } + + /*init lock and alloc the ring buffer*/ + + /*sema_init(&task_cb.bg_sem, 0);*/ + spin_lock_init(&task_cb.bg_lock); + + task_cb.ring.num = NAT_HELPER_MSG_MAX; + task_cb.ring.buf = kzalloc(NAT_HELPER_MSG_MAX * sizeof(struct nat_helper_bg_msg), GFP_ATOMIC); + if(!task_cb.ring.buf) { + aos_printk("ring buf alloc fail!\n"); + return; + } + msg = (struct nat_helper_bg_msg*)task_cb.ring.buf; + for(i = 0; i < task_cb.ring.num; i++) + { + INIT_WORK(&msg[i].work, nat_task_entry); + } + + aos_printk("bg task init successfull!\n"); + +} + +void nat_helper_bg_task_exit() +{ + /*stop the workqueue and release the ring buffer*/ + if(task_cb.nat_wq) + destroy_workqueue(task_cb.nat_wq); + if(task_cb.ring.buf) + kfree(task_cb.ring.buf); +} +#endif + + +extern int napt_procfs_init(void); +extern void napt_procfs_exit(void); + +void host_helper_init(a_uint32_t portbmp) +{ + REG_GET(0, 0, (a_uint8_t *)&nat_chip_ver, 4); + + /* header len 4 with type 0xaaaa */ + HEADER_TYPE_SET(0, A_TRUE, 0xaaaa); + if (((nat_chip_ver & 0xffff)>>8) == NAT_CHIP_VER_8337 || + ((nat_chip_ver & 0xffff)>>8) == NAT_CHIP_VER_DESS) { + /* For S17c (ISISC), it is not necessary to make all frame with header */ + printk("host_helper_init start\n"); + //PORT_TXHDR_MODE_SET(0, 0, FAL_ONLY_MANAGE_FRAME_EN); + /* Fix tag disappear problem, set TO_CPU_VID_CHG_EN, 0xc00 bit1 */ + CPU_VID_EN_SET(0, A_TRUE); + /* set RM_RTD_PPPOE_EN, 0xc00 bit0 */ + RTD_PPPOE_EN_SET(0, A_TRUE); + /* Avoid ARP response storm for HUB, now this fix only apply on PORT5 */ + #if 0 + MISC_ARP_SP_NOT_FOUND_SET(0, FAL_MAC_RDT_TO_CPU); + MISC_ARP_GUARD_SET(0, S17_WAN_PORT, FAL_MAC_IP_PORT_GUARD); + #endif + /* set VLAN_TRANS_TEST register bit, to block packets from WAN port has private dip */ + NETISOLATE_SET(0, A_TRUE); + } else { + PORT_TXHDR_MODE_SET(0, 0, FAL_ALL_TYPE_FRAME_EN); + } + CPU_PORT_STATUS_SET(0, A_TRUE); + IP_ROUTE_STATUS_SET(0, A_TRUE); + + napt_procfs_init(); + memcpy(nat_bridge_dev, nat_lan_dev_list, strlen(nat_lan_dev_list)+1); + + register_netevent_notifier(&hnat_netevent_notifier); +/*hnat not upport ipv6*/ +#if 0 +#ifdef CONFIG_IPV6_HWACCEL + aos_printk("Registering IPv6 hooks... \n"); + nf_register_hook(&ipv6_inhook); +#endif +#endif + +#ifdef AUTO_UPDATE_PPPOE_INFO + register_inetaddr_notifier(&qcaswitch_ip_notifier); +#endif // ifdef AUTO_UPDATE_PPPOE_INFO + + nat_wan_port = portbmp; + + /* Enable ACLs to handle MLD packets */ + upnp_ssdp_add_acl_rules(); + ipv6_snooping_solicted_node_add_acl_rules(); + ipv6_snooping_sextuple0_group_add_acl_rules(); + ipv6_snooping_quintruple0_1_group_add_acl_rules(); + + napt_helper_hsl_init(); +} + +void host_helper_exit(void) +{ + napt_procfs_exit(); + + unregister_netevent_notifier(&hnat_netevent_notifier); +#if 0 +#ifdef CONFIG_IPV6_HWACCEL + nf_unregister_hook(&ipv6_inhook); +#endif +#endif + + #ifdef AUTO_UPDATE_PPPOE_INFO + unregister_inetaddr_notifier(&qcaswitch_ip_notifier); + #endif +} + diff --git a/feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/lib/nat_helper_dt.c b/feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/lib/nat_helper_dt.c new file mode 100755 index 000000000..a76f0a8b9 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/lib/nat_helper_dt.c @@ -0,0 +1,1352 @@ +/* + * Copyright (c) 2012, 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. + */ + + +#ifdef KVER32 +#include +#include +#else +#include +#endif +#include +#include +#include +#include + +#include "../nat_helper.h" +#include "../napt_helper.h" +#include "../napt_acl.h" + +#include "fal_type.h" +#include "fal_nat.h" + +#include "nat_helper_dt.h" +#include "nat_helper_hsl.h" + +#define NAPT_CT_POLLING_SEC 5 +#define NPAT_CT_POLLING_QUOTA 256 + +extern int nat_sockopts_init; +extern uint32_t napt_set_default_route(fal_ip4_addr_t dst_addr, fal_ip4_addr_t src_addr); +#ifdef CONFIG_IPV6_HWACCEL +extern uint32_t napt_set_ipv6_default_route(void); +#endif +extern void nat_ipt_sockopts_replace(void); +extern void qcaswitch_hostentry_flush(void); + +#define NAPT_BUFFER_HASH_SIZE (NAPT_TABLE_SIZE) +#define NAPT_BUFFER_SIZE ((NAPT_BUFFER_HASH_SIZE)*8) + +static a_uint32_t napt_buffer_hash_size = NAPT_TABLE_SIZE; +static a_uint32_t napt_buffer_size = (NAPT_BUFFER_HASH_SIZE)*8; +static a_uint32_t napt_ct_hw_cnt = 0; +static a_uint8_t napt_thread_pending = 0; + +a_uint32_t polling_quota = NPAT_CT_POLLING_QUOTA; + +extern int nat_chip_ver; + +struct napt_ct +{ + struct napt_ct *next; + a_uint32_t ct_addr; + a_uint64_t ct_packets; + a_uint8_t in_hw; + a_uint16_t hw_index; + a_uint8_t deny; + a_uint64_t last_jiffies; +}; + +struct napt_debug_counter +{ + a_uint32_t interate_cnt; + a_uint32_t care_cnt; + a_uint32_t thresh_low_cnt; +}; + +struct nhlist_head +{ + struct napt_ct *next; +}; + +static struct nhlist_head *ct_buf_hash_head = NULL; +static struct napt_ct *ct_buf = NULL; +static a_uint32_t ct_buf_ct_cnt = 0; +static struct napt_debug_counter napt_ct_debug_info; + +int scan_period = NAPT_CT_POLLING_SEC; +int scan_enable = 1; +int napt_need_clean = 0; +/*pppoe dhcp siwtch pre-handle*/ +int wan_switch = 0; + + +static a_int32_t +napt_hash_buf_init(struct napt_ct **hash, struct nhlist_head **hash_head) +{ + a_uint32_t hash_size = NAPT_BUFFER_HASH_SIZE; + a_uint32_t buffer_size = NAPT_BUFFER_SIZE; + + *hash = (struct napt_ct *)kmalloc(sizeof(struct napt_ct)*buffer_size, GFP_ATOMIC); + if(!(*hash)) + { + HNAT_PRINTK("NAPT INIT ERROR! No Sufficient Memory!"); + return -1; + } + + *hash_head = (struct nhlist_head *)kmalloc(sizeof(struct nhlist_head)*hash_size, GFP_ATOMIC); + if(!(*hash_head)) + { + HNAT_PRINTK("NAPT INIT ERROR! No Sufficient Memory!"); + kfree(*hash); + return -1; + } + + memset(*hash,0,sizeof(struct napt_ct)*buffer_size); + memset(*hash_head,0,sizeof(struct nhlist_head)*hash_size); + + return 0; +} + +static a_uint32_t +napt_ct_hash(a_uint32_t ct_addr) +{ + if(nf_athrs17_hnat_sync_counter_en == 0) + return (((ct_addr) * (0x9e370001UL)) >> 22); + else + return (((ct_addr) * (0x9e370001UL)) >> 29); +} + +static struct napt_ct * +napt_hash_add(a_uint32_t ct_addr, a_uint32_t *hash_cnt, + struct napt_ct *hash, struct nhlist_head *hash_head) +{ + struct napt_ct *entry = 0,*last = 0,*node = 0; + struct nhlist_head *head = 0; + a_uint32_t hash_index = napt_ct_hash(ct_addr); + a_uint32_t i = 0, j = 0, index = 0xffffffff; + + if(*hash_cnt >= napt_buffer_size) + { + return NULL; + } + head = &(hash_head[hash_index]); + entry = head->next; + + while(entry) + { + if(ct_addr == entry->ct_addr) + { + return entry; + } + else + { + last = entry; + entry = entry->next; + } + } + /*find a valid position*/ + for (i = *hash_cnt; i < napt_buffer_size; i++) { + if (hash[i].ct_addr == 0) + break; + } + if (i >= napt_buffer_size) { + for (j = 0; j < *hash_cnt; j++) { + if (hash[j].ct_addr == 0) + break; + } + if (j >= *hash_cnt) + return NULL; + index = j; + } else { + index = i; + } + + node = &(hash[index]); + node->ct_addr = ct_addr; + node->ct_packets = 0; + node->in_hw = 0; + node->hw_index = 0; + node->deny = 0; + + if(head->next == 0) + { + head->next = node; + } + else + { + last->next = node; + } + (*hash_cnt)++; + + return node; +} + +static struct napt_ct * +napt_hash_find(a_uint32_t ct_addr, a_uint32_t *hash_cnt, + struct napt_ct *hash, struct nhlist_head *hash_head) +{ + struct napt_ct *entry = 0; + struct nhlist_head *head = 0; + a_uint32_t hash_index = napt_ct_hash(ct_addr); + + if(*hash_cnt == 0) + { + return NULL; + } +#if 0 /* prevent empty entries. */ + if(*hash_cnt >= NAPT_BUFFER_SIZE) + { + return NULL; + } +#endif + + head = &(hash_head[hash_index]); + + if(head->next == 0) + { + return NULL; + } + entry = head->next; + do + { + if(ct_addr == entry->ct_addr) + { + return entry; + } + + entry = entry->next; + } + while(entry); + + return NULL; +} + +static a_int32_t +napt_ct_buf_init(void) +{ + return napt_hash_buf_init(&ct_buf, &ct_buf_hash_head); +} + +static void +napt_ct_buf_exit(void) +{ + if(ct_buf_hash_head) + kfree(ct_buf_hash_head); + + if(ct_buf) + kfree(ct_buf); +} + +static void +napt_ct_buf_flush(void) +{ + ct_buf_ct_cnt = 0; + memset(ct_buf,0,sizeof(struct napt_ct)*NAPT_BUFFER_SIZE); + memset(ct_buf_hash_head,0,sizeof(struct nhlist_head)*NAPT_BUFFER_HASH_SIZE); +} + +static a_uint32_t +napt_ct_cnt_get(void) +{ + return ct_buf_ct_cnt; +} + +static struct napt_ct * +napt_ct_buf_ct_find(a_uint32_t ct_addr) +{ + return napt_hash_find(ct_addr, &ct_buf_ct_cnt, + ct_buf, ct_buf_hash_head); +} + +static a_uint64_t +napt_ct_buf_pkts_get(struct napt_ct *napt_ct) +{ + return napt_ct->ct_packets; +} + +static void +napt_ct_buf_pkts_update(struct napt_ct *napt_ct, a_uint64_t packets) +{ + napt_ct->ct_packets = packets; +} + +static a_uint8_t +napt_ct_buf_deny_get(struct napt_ct *napt_ct) +{ + return napt_ct->deny; +} + +static void +napt_ct_buf_deny_set(struct napt_ct *napt_ct, a_uint8_t deny) +{ + napt_ct->deny = deny; +} + +static void +napt_ct_buf_deny_clear(struct napt_ct *napt_ct) +{ + napt_ct->deny = 0; +} + +static a_uint8_t +napt_ct_buf_in_hw_get(struct napt_ct *napt_ct, a_uint16_t *hw_index) +{ + *hw_index = napt_ct->hw_index; + return napt_ct->in_hw; +} + +static void +napt_ct_buf_in_hw_set(struct napt_ct *napt_ct, a_uint16_t hw_index) +{ + napt_ct->in_hw = 1; + napt_ct->hw_index = hw_index; +} + +static void +napt_ct_buf_in_hw_clear(struct napt_ct *napt_ct) +{ + napt_ct->in_hw = 0; + napt_ct->hw_index = 0; +} + +static void +napt_ct_buf_ct_info_clear(struct napt_ct *napt_ct) +{ + a_uint32_t hash_index = napt_ct_hash(napt_ct->ct_addr); + struct nhlist_head *head = 0; + struct napt_ct *entry = 0, *last = 0; + + head = &ct_buf_hash_head[hash_index]; + entry = head->next; + while (entry && entry != napt_ct) { + last = entry; + entry = entry->next; + } + if (last == 0) + head->next = napt_ct->next; + else + last->next = napt_ct->next; + napt_ct->ct_addr = 0; + napt_ct->ct_packets = 0; + napt_ct->deny = 0; + napt_ct->next = NULL; +} + +static struct napt_ct * +napt_ct_buf_ct_add(a_uint32_t ct_addr) +{ + struct napt_ct *napt_ct; + napt_ct = napt_hash_add(ct_addr, &ct_buf_ct_cnt, + ct_buf, ct_buf_hash_head); + + if(napt_ct) + { + /*ct pkts initial*/ + napt_ct_buf_pkts_update(napt_ct, NAPT_CT_PKTS_GET(ct_addr)); + } + + return napt_ct; +} + +#define NAPT_CT_PERMANENT_DENY 5 +static a_uint32_t napt_ct_addr[NAPT_TABLE_SIZE] = {0}; +a_uint32_t napt_cookie[NAPT_TABLE_SIZE*2] = {0}; + +a_uint32_t packet_thres_base = 50; +static a_uint64_t packets_bdir_total = 0; +static a_uint64_t packets_bdir_thres = 0; + +static inline a_int32_t +before(a_uint64_t seq1, a_uint64_t seq2) +{ + return ((int64_t)(seq1-seq2) < 0); +} + +static a_uint8_t +napt_ct_pkts_reach_thres(a_uint32_t ct_addr, struct napt_ct *napt_ct, + a_uint8_t pkts_sum) +{ + a_uint64_t packets_bdir_old = napt_ct_buf_pkts_get(napt_ct); + a_uint64_t packets_bdir_new = NAPT_CT_PKTS_GET(ct_addr); + + if(pkts_sum) + { + if(packets_bdir_new > packets_bdir_old) + { + packets_bdir_total += (packets_bdir_new - packets_bdir_old); + } + } + + napt_ct_buf_pkts_update(napt_ct, packets_bdir_new); + + HNAT_PRINTK("<%s> ct:%x packets_bdir_old:%lld ==> packets_bdir_new:%lld, thresh:%lld\n", + __func__, ct_addr, packets_bdir_old, packets_bdir_new, packets_bdir_thres); + + if(before((packets_bdir_old+packets_bdir_thres), packets_bdir_new)) + { + return 1; + } + + return 0; +} + +a_uint8_t napt_dnat_flow_find_del( + napt_entry_t *napt, + fal_napt_entry_t *entry) +{ + fal_napt_entry_t tmp_entry; + napt_entry_t tmp_napt; + a_int32_t ret; + + memset(&tmp_entry, 0, sizeof(tmp_entry)); + memset(&tmp_napt, 0, sizeof(tmp_napt)); + tmp_napt = *napt; + tmp_napt.src_addr = 0; + ret = napt_hw_get(&tmp_napt, &tmp_entry); + if(!ret) { + napt_hw_del(&tmp_napt); + *entry = tmp_entry; + return 0; + } + return 1; +} + +a_uint8_t napt_snat_flow_find_del( + napt_entry_t *napt, + fal_napt_entry_t *entry) +{ + fal_napt_entry_t tmp_entry; + napt_entry_t tmp_napt; + a_int32_t ret; + + memset(&tmp_entry, 0, sizeof(tmp_entry)); + memset(&tmp_napt, 0, sizeof(tmp_napt)); + tmp_napt = *napt; + tmp_napt.trans_addr = 0; + ret = napt_hw_get(&tmp_napt, &tmp_entry); + if(!ret) { + napt_hw_del(&tmp_napt); + *entry = tmp_entry; + return 0; + } + return 1; +} + + + + +static a_int32_t +napt_ct_hw_add(a_uint32_t ct_addr, a_uint16_t *hw_index) +{ + napt_entry_t napt = {0}; + a_uint32_t index, i, dcookie = 0, scookie = 0; + fal_napt_entry_t entry; + a_uint8_t ret = 0; + sw_error_t rv = SW_OK; + + if (!ct_addr) + return -1; + + NAPT_CT_TO_HW_ENTRY(ct_addr, &napt); + + if(nat_hw_pub_ip_add(napt.trans_addr, &index) == 0) + { + napt.trans_addr = index; + + } + else + { + HNAT_ERR_PRINTK("####%s##nat_hw_pub_ip_add fail!\n", __func__); + return -1; + } + if (((nat_chip_ver & 0xffff)>>8) == NAT_CHIP_VER_DESS) { + ret = napt_dnat_flow_find_del(&napt, &entry); + if(!ret) { + dcookie = entry.flow_cookie; + } + ret = napt_snat_flow_find_del(&napt, &entry); + if(!ret) { + scookie = entry.flow_cookie; + } + } + rv = napt_hw_add(&napt); + + if(rv == 0) + { + HNAT_PRINTK("%s: success entry_id:0x%x ct 0x%x\n", __func__, napt.entry_id, ct_addr); + + if(napt_ct_addr[napt.entry_id]) + { + HNAT_ERR_PRINTK("fault: napt HW:%x can not be overwrited!\n", + napt.entry_id); + + } + else + { + napt_ct_addr[napt.entry_id] = ct_addr; + *hw_index = napt.entry_id; + // Added from 1.0.7 for default route. + napt_set_default_route(napt.dst_addr, napt.src_addr); + if (((nat_chip_ver & 0xffff)>>8) == NAT_CHIP_VER_DESS) { + i = napt.entry_id; + napt_cookie[i*2] = dcookie; + napt_cookie[i*2+1] = scookie; + } + napt_ct_hw_cnt++; + + return 0; + } + } + else + { + HNAT_PRINTK("%s:fail rv:%d entry_id:%x(maybe full)\n", + __func__,rv, napt.entry_id); + nat_hw_pub_ip_del(napt.trans_addr); + } + + return -1; +} + +static a_int32_t +napt_ct_hw_del (napt_entry_t *napt) +{ + if(napt_hw_del(napt)!= 0) + { + HNAT_ERR_PRINTK("%s: isis_napt_del fail\n", __func__); + return -1; + } + napt_ct_hw_cnt--; + if(nat_hw_pub_ip_del(napt->trans_addr) != 0) + { + HNAT_ERR_PRINTK("%s: public_ip_del fail\n", __func__); + //return -1; + } + return 0; +} + +void nat_helper_cookie_del(a_uint32_t hw_index) +{ + struct napt_ct *napt_ct = NULL; + a_uint32_t ct_addr; + ct_addr = napt_ct_addr[hw_index]; + if(ct_addr) { + napt_ct = napt_ct_buf_ct_find(ct_addr); + } + if(napt_ct) + { + napt_ct_buf_in_hw_clear(napt_ct); + + if(napt_ct_buf_deny_get(napt_ct) != NAPT_CT_PERMANENT_DENY) + { + napt_ct_buf_ct_info_clear(napt_ct); + } + NAPT_CT_AGING_ENABLE(napt_ct_addr[hw_index]); + } + napt_ct_addr[hw_index] = 0; + napt_cookie[hw_index*2] = 0; + napt_cookie[hw_index*2+1] = 0; + HNAT_INFO_PRINTK("nat_helper_cookie_del for index 0x%x\n", hw_index); +} + + +static a_int32_t +napt_ct_del(struct napt_ct *napt_ct, napt_entry_t *napt) +{ + a_uint16_t hw_index = napt->entry_id; + + HNAT_PRINTK("%s: 0x%x ct 0x%x\n", __FUNCTION__, hw_index, napt_ct_addr[hw_index]); + + if(napt_ct_hw_del(napt) != 0) + { + return -1; + } + + NAPT_CT_AGING_ENABLE(napt_ct_addr[hw_index]); + napt_ct_addr[hw_index] = 0; + if(napt_cookie[hw_index*2]) { + napt_hw_dnat_cookie_add(napt, napt_cookie[hw_index*2]); + napt_cookie[hw_index*2] = 0; + } + if(napt_cookie[hw_index*2+1]) { + napt_hw_snat_cookie_add(napt, napt_cookie[hw_index*2+1]); + napt_cookie[hw_index*2+1] = 0; + } + + if(napt_ct) + { + napt_ct_buf_in_hw_clear(napt_ct); + + if(napt_ct_buf_deny_get(napt_ct) != NAPT_CT_PERMANENT_DENY) + { + napt_ct_buf_ct_info_clear(napt_ct); + } + } + + return 0; +} + +static a_int32_t +napt_ct_del_by_index (struct napt_ct *napt_ct, a_uint16_t hw_index) +{ + napt_entry_t napt = {0}; + + if(napt_hw_get_by_index(&napt, hw_index) != 0) + { + return -1; + } + + return napt_ct_del(napt_ct, &napt); +} + +static a_int32_t +napt_ct_in_hw_sanity_check(struct napt_ct *napt_ct, a_uint16_t hw_index) +{ + a_uint16_t ct_hw_index = 0; + if(!napt_ct) + { + HNAT_ERR_PRINTK("<%s>hw_index:%d error napt_ct can't find\n", + __func__, hw_index); + return -1; + } + + if(napt_ct_buf_in_hw_get(napt_ct, &ct_hw_index) == 0) + { + HNAT_ERR_PRINTK("<%s>hw_index:%d in_hw:0 error\n", + __func__, hw_index); + return -1; + } + + if(hw_index != ct_hw_index) + { + HNAT_ERR_PRINTK("<%s>hw_index:%d buf_hw_index:%d\n", + __func__, hw_index, ct_hw_index); + return -1; + } + + return 0; +} + +void +napt_ct_hw_aging(void) +{ +#define NAPT_AGEOUT_STATUS 1 + + a_uint32_t ct_addr, cnt= 0; + napt_entry_t napt = {0}; + + + if(napt_hw_first_by_age(&napt, NAPT_AGEOUT_STATUS) != 0) + { + return; + } + + do + { + a_uint16_t hw_index = napt.entry_id; + struct napt_ct *napt_ct = NULL; + ct_addr = napt_ct_addr[hw_index]; + + if(ct_addr) + { + napt_ct = napt_ct_buf_ct_find(ct_addr); + if(napt_ct_in_hw_sanity_check(napt_ct, hw_index) != 0) + { + HNAT_ERR_PRINTK("<%s> napt_ct_in_hw_sanity_check fail\n", __func__); + continue; + } + + if((nf_athrs17_hnat_sync_counter_en == 0) && (napt_ct_pkts_reach_thres(ct_addr, napt_ct, 0))) + { + printk("set PERMANENT deny ct:%x\n", ct_addr); + napt_ct_buf_deny_set(napt_ct, NAPT_CT_PERMANENT_DENY); + } + } + else + { + HNAT_ERR_PRINTK(" error: in_hw but ct = NULL hw_index:%x\n", hw_index); + } + + napt_ct_del(napt_ct, &napt); + HNAT_INFO_PRINTK("ct:%x aged!\n", ct_addr); + cnt++; + if ((cnt % polling_quota) == 0) { + NAPT_CT_TASK_SLEEP(1); + } + + } + while(napt_hw_next_by_age(&napt, NAPT_AGEOUT_STATUS) != -1); + +#if 0 + if(napt_hw_used_count_get() == 0) + { + nat_hw_prv_base_update_enable(); + } +#endif + + return; +} + +static a_uint32_t +napt_ct_counter_sync(a_uint32_t hw_index) +{ + napt_entry_t napt = {0}; + struct nf_conn *ct = NULL; + struct nf_conn_counter *cct = NULL; + a_uint64_t delta_jiffies = 0, now_jiffies; + a_uint32_t ct_addr = napt_ct_addr[hw_index]; + struct napt_ct *napt_ct; + + if((nf_athrs17_hnat_sync_counter_en == 0) || (napt_ct_addr[hw_index] == 0) || (hw_index >= NAPT_TABLE_SIZE)) + return -1; + + ct = (struct nf_conn *)napt_ct_addr[hw_index]; + cct = (struct nf_conn_counter *)nf_conn_acct_find(ct); + napt_ct = napt_ct_buf_ct_find(ct_addr); + if (napt_ct) { + now_jiffies = (a_uint64_t)get_jiffies_64(); + delta_jiffies = now_jiffies - napt_ct->last_jiffies; + napt_ct->last_jiffies = now_jiffies; + } + + if (!test_bit(IPS_FIXED_TIMEOUT_BIT, &ct->status)) { + ct->timeout.expires += delta_jiffies; + } + + if((cct != NULL) && (napt_hw_get_by_index(&napt, hw_index) == 0)) + { + spin_lock_bh(&ct->lock); + if ((ct->status & IPS_NAT_MASK) == IPS_SRC_NAT) { + atomic64_add(napt.egress_packet, &cct[IP_CT_DIR_ORIGINAL].packets); + atomic64_add(napt.egress_byte, &cct[IP_CT_DIR_ORIGINAL].bytes); + atomic64_add(napt.ingress_packet, &cct[IP_CT_DIR_REPLY].packets); + atomic64_add(napt.ingress_byte, &cct[IP_CT_DIR_REPLY].bytes); + } else { + atomic64_add(napt.ingress_packet, &cct[IP_CT_DIR_ORIGINAL].packets); + atomic64_add(napt.ingress_byte, &cct[IP_CT_DIR_ORIGINAL].bytes); + atomic64_add(napt.egress_packet, &cct[IP_CT_DIR_REPLY].packets); + atomic64_add(napt.egress_byte, &cct[IP_CT_DIR_REPLY].bytes); + } + spin_unlock_bh(&ct->lock); + HNAT_PRINTK("original packets:0x%llx bytes:0x%llx\n", + cct[IP_CT_DIR_ORIGINAL].packets, cct[IP_CT_DIR_ORIGINAL].bytes); + HNAT_PRINTK("reply packets:0x%llx bytes:0x%llx\n", + cct[IP_CT_DIR_REPLY].packets, cct[IP_CT_DIR_REPLY].bytes); + } + + return 0; +} + +static a_int32_t +napt_ct_timer_update(a_uint32_t hw_index) +{ + struct nf_conn *ct = NULL; + struct nf_conn_counter *cct = NULL; + a_uint64_t delta_jiffies = 0, now_jiffies; + a_uint32_t ct_addr = napt_ct_addr[hw_index]; + struct napt_ct *napt_ct; + + if((napt_ct_addr[hw_index] == 0) || (hw_index >= NAPT_TABLE_SIZE)) + return -1; + + ct = (struct nf_conn *)napt_ct_addr[hw_index]; + cct = (struct nf_conn_counter *)nf_conn_acct_find(ct); + napt_ct = napt_ct_buf_ct_find(ct_addr); + if (napt_ct) { + now_jiffies = (a_uint64_t)get_jiffies_64(); + delta_jiffies = now_jiffies - napt_ct->last_jiffies; + napt_ct->last_jiffies = now_jiffies; + } + + if (!test_bit(IPS_FIXED_TIMEOUT_BIT, &ct->status)) { + ct->timeout.expires += delta_jiffies; + } + + return 0; +} + +void napt_ct_counter_decrease(void) +{ + ct_buf_ct_cnt--; +} + +#define NAPT_INVALID_CT_NEED_HW_CLEAR(hw_index) \ + ((napt_ct_valid[hw_index] == 0) && \ + (napt_ct_addr[hw_index] != 0)) +static a_uint32_t +napt_ct_hw_sync(a_uint8_t napt_ct_valid[]) +{ + a_uint16_t hw_index; + a_uint32_t napt_ct_offload_cnt = 0; + + for(hw_index = 0; hw_index < NAPT_TABLE_SIZE; hw_index++) + { + #if 0 + napt_ct_counter_sync(hw_index); + #endif + + if(NAPT_INVALID_CT_NEED_HW_CLEAR(hw_index)) + { + + a_uint32_t ct_addr = napt_ct_addr[hw_index]; + struct napt_ct *napt_ct = napt_ct_buf_ct_find(ct_addr); + + HNAT_INFO_PRINTK("should hw clear for %d\n", hw_index); + + if(napt_ct_in_hw_sanity_check(napt_ct, hw_index) != 0) + { + HNAT_ERR_PRINTK("<%s> napt_ct_in_hw_sanity_check fail\n", __func__); + continue; + } + + if(napt_ct_del_by_index(napt_ct, hw_index) == 0) + { + napt_ct_buf_deny_clear(napt_ct); + } + else + { + HNAT_ERR_PRINTK("hw_index:%d napt_hw_del_by_index fail\n", + hw_index); + } + } + + if(napt_ct_valid[hw_index]) + { + napt_ct_offload_cnt++; + } + } + + return napt_ct_offload_cnt; +} + +static void +napt_ct_frag_hw_yield(struct napt_ct *napt_ct, a_uint16_t hw_index) +{ + napt_entry_t napt = {0}; + + /*os and hw are both traffic; hw offload giveup*/ + if(napt_hw_get_by_index(&napt, hw_index) == 0) + { + if(napt.status == 0xe) + { + a_uint8_t deny = napt_ct_buf_deny_get(napt_ct); + napt_ct_buf_deny_set(napt_ct, (++deny)); + + if(deny >= NAPT_CT_PERMANENT_DENY) + { + /*os service only*/ + HNAT_ERR_PRINTK(" hw service deny\n"); + napt_ct_del(napt_ct, &napt); + } + + //printk(" deny:%d\n", deny); + } + } +} + +#define NAPT_CT_IS_REUSED_BY_OS(in_hw, ct_addr) ((in_hw) && \ + NAPT_CT_AGING_IS_ENABLE(ct_addr)) +static a_int32_t +napt_ct_check_add_one(a_uint32_t ct_addr, a_uint8_t *napt_ct_valid) +{ + struct napt_ct *napt_ct = NULL; + a_uint16_t hw_index; + a_uint8_t in_hw; + + if((napt_ct = napt_ct_buf_ct_find(ct_addr)) == NULL) + { + if((napt_ct = napt_ct_buf_ct_add(ct_addr)) == NULL) + { + HNAT_ERR_PRINTK(" error hash full\n"); + return -1; + } + } + + if(napt_ct_buf_deny_get(napt_ct) >= NAPT_CT_PERMANENT_DENY) + { + HNAT_INFO_PRINTK(" ct:%x is PERMANENT deny\n", + ct_addr); + return -1; + + } + else + { + if (napt_ct_pkts_reach_thres(ct_addr, napt_ct, 1)) + { + if(napt_ct_buf_in_hw_get(napt_ct, &hw_index)) + { + //printk(" ct:%x* is exist\n", ct_addr); + if(nf_athrs17_hnat_sync_counter_en == 0) + { + HNAT_ERR_PRINTK(" ct:%x* is exist\n", ct_addr); + napt_ct_frag_hw_yield(napt_ct, hw_index); + } + } + else + { + if(napt_ct_hw_add(ct_addr, &hw_index) == 0) + { + NAPT_CT_AGING_DISABLE(ct_addr); + napt_ct->last_jiffies = get_jiffies_64(); + + napt_ct_buf_in_hw_set(napt_ct, hw_index); +#ifdef NAT_TODO + ct->in_hnat = 1; /* contrack in HNAT now. */ +#endif + } + } + } else { + HNAT_INFO_PRINTK("can not reach thres for napt_ct=%pK\n", napt_ct); + } + + in_hw = napt_ct_buf_in_hw_get(napt_ct, &hw_index); + if(in_hw) + { + if(!NAPT_CT_IS_REUSED_BY_OS(in_hw, ct_addr)) + { + napt_ct_valid[hw_index] = 1; + } + } + } + + return 0; +} + +static void +napt_ct_pkts_thres_calc_init(void) +{ + packets_bdir_total = 0; + packets_bdir_thres = packet_thres_base; + +} + +a_uint64_t +uint64_div_uint32(a_uint64_t div, a_uint32_t base) +{ + register a_uint32_t i; + a_uint64_t result; + + union + { + a_uint64_t n64[2]; + struct + { + a_uint32_t l0;// 0 + a_uint32_t h0;// 1 + a_uint32_t l1;// 2 + a_uint32_t h1;// 3 + } n32; + } n; + + if(base == 0) + { + return 0; + } + + if(div < base) + { + return 0; + } + + n.n64[0] = div; + n.n64[1] = 0; + result = 0; + i = 0; + + //if div is 32bits, set start from 32 + if(n.n32.h0 == 0) + { + n.n32.h0 = n.n32.l0; + n.n32.l0 = 0; + i = 32; + } + + //left shift until highest bit + for(; i<64; ++i) + { + if((n.n32.h0 & 0x80000000) == 0x80000000) + { + break; + } + else + { + n.n64[0] = n.n64[0] << 1; + } + } + + for (; i<64; ++i) + { + n.n64[1] = (n.n64[1] << 1) + (n.n64[0] >> 63); + n.n64[0] = (n.n64[0] << 1); + result = result << 1 ; + + if(n.n64[1] >= base) + { + n.n64[1] = n.n64[1]- base; + ++result; + } + } + + return result; +} + +static void +napt_ct_pkts_thres_calc(a_uint32_t cnt, a_uint32_t napt_ct_offload_cnt) +{ + a_uint64_t packets_bdir_avg = 0; + a_uint64_t packets_bdir_thres_temp = 0; + + /*ct_avg_pkts* (1+ (ct_offload_cnt/ct_hw_max) )*/ + packets_bdir_avg = uint64_div_uint32(packets_bdir_total, cnt); + packets_bdir_thres_temp = packets_bdir_avg + + uint64_div_uint32((packets_bdir_avg *(a_uint64_t)napt_ct_offload_cnt), + NAPT_TABLE_SIZE); + + if(packets_bdir_thres_temp > packet_thres_base) + { + packets_bdir_thres = packets_bdir_thres_temp; + } + + //HNAT_ERR_PRINTK("###<%s> total:%lld cnt:%d avg:%lld threshold:%lld###\n", __func__, + // packets_bdir_total, cnt, packets_bdir_avg, packets_bdir_thres); + HNAT_INFO_PRINTK("calc pkts avg:%lld offload_cnt:%d threshold:%lld\n", + packets_bdir_avg, napt_ct_offload_cnt, packets_bdir_thres); +} + +#define NAPT_CT_SHOULD_CARE(ct) ((ct) && \ + NAPT_CT_TYPE_IS_NAT(ct) && \ + !NAPT_CT_TYPE_IS_NAT_ALG(ct) && \ + NAPT_CT_INTF_EXPECTED(ct) && \ + NAPT_CT_STATUS_IS_ESTAB(ct) &&\ + nat_hw_prv_base_is_match( \ + NAPT_CT_PRIV_IP_GET(ct))) +a_uint8_t napt_ct_valid_tbl[NAPT_TABLE_SIZE] = {0}; +static a_int32_t +napt_ct_check_add(void) +{ + a_uint32_t ct_addr = 0; + a_uint32_t ct_buf_valid_cnt = 0, care_cnt = 0, ct_cnt = 0; + static a_uint32_t hash = 0; + a_uint32_t iterate = 0; + a_uint32_t napt_ct_offload_cnt = 0; + a_uint16_t hw_index; + + napt_ct_pkts_thres_calc_init(); + + NAPT_CT_LIST_LOCK(); + while((ct_addr = NAPT_CT_LIST_ITERATE(&hash, &iterate))) + { + ct_cnt++; + if (NAPT_CT_SHOULD_CARE(ct_addr)) + { + if(napt_ct_check_add_one(ct_addr, napt_ct_valid_tbl) != -1) + { + ct_buf_valid_cnt++; + } + care_cnt++; + if (care_cnt >= polling_quota) { + break; + } + } + } + + NAPT_CT_LIST_UNLOCK(); + HNAT_INFO_PRINTK("ct_cnt=0x%x, care_cnt=0x%x\n", ct_cnt, care_cnt); + + + if (!ct_addr) { + napt_ct_offload_cnt = napt_ct_hw_sync(napt_ct_valid_tbl); + napt_ct_pkts_thres_calc(ct_buf_valid_cnt, napt_ct_offload_cnt); + memset(napt_ct_valid_tbl, 0, NAPT_TABLE_SIZE); + } + + for(hw_index = 0; hw_index < NAPT_TABLE_SIZE; hw_index++) { + if (nf_athrs17_hnat_sync_counter_en) + napt_ct_counter_sync(hw_index); + else + napt_ct_timer_update(hw_index); + } + + return ct_buf_valid_cnt; +} + +static a_int32_t +napt_ct_add(a_uint32_t ct_addr, a_uint8_t *napt_ct_valid) +{ + struct napt_ct *napt_ct; + + if((napt_ct = napt_ct_buf_ct_add(ct_addr)) == NULL) + { + HNAT_ERR_PRINTK(" error hash full\n"); + return -1; + } + + return 0; +} + +static a_int32_t +napt_ct_buffer_ct_status_update(void) +{ + a_uint32_t ct_addr = 0; + a_uint32_t hash = 0; + a_uint32_t iterate = 0; + + NAPT_CT_LIST_LOCK(); + + while((ct_addr = NAPT_CT_LIST_ITERATE(&hash, &iterate))) + { + if (NAPT_CT_SHOULD_CARE(ct_addr)) + { + napt_ct_add(ct_addr, NULL); + } + } + + NAPT_CT_LIST_UNLOCK(); + + return 0; +} + +static void +napt_ct_buffer_hw_status_update(void) +{ + a_uint16_t hw_index; + + for(hw_index = 0; hw_index < NAPT_TABLE_SIZE; hw_index++) + { + a_uint32_t ct_addr = napt_ct_addr[hw_index]; + if(ct_addr) + { + struct napt_ct *napt_ct = napt_ct_buf_ct_find(ct_addr); + if(napt_ct) + { + napt_ct_buf_in_hw_set(napt_ct, hw_index); + + } + else + { + if(napt_ct_del_by_index(napt_ct, hw_index) != 0) + { + HNAT_ERR_PRINTK("<%s>hw_index:%d napt_ct_del_by_index fail\n", + __func__, hw_index); + } + } + } + } + + return; +} + +static void +napt_ct_buffer_refresh(void) +{ + HNAT_INFO_PRINTK("napt_ct_buffer_refresh\n"); + + napt_ct_buf_flush(); + + napt_ct_buffer_ct_status_update(); + napt_ct_buffer_hw_status_update(); +} + +static void +napt_ct_buffer_refresh_check(a_uint32_t ct_buf_valid_cnt) +{ +#define NAPT_CT_BUF_REFRESH_THRES 1000 + HNAT_INFO_PRINTK("ct_buffer_hash_cnt:%d cnt:%d max:%d\n", + napt_ct_cnt_get(), ct_buf_valid_cnt/2, NAPT_CT_BUF_REFRESH_THRES); + + if((napt_ct_cnt_get() - ct_buf_valid_cnt/2) > NAPT_CT_BUF_REFRESH_THRES) + { + napt_ct_buffer_refresh(); + } +} + +static void +napt_ct_hw_exit(void) +{ + a_uint8_t napt_ct_valid[NAPT_TABLE_SIZE]; + + /*set all ct invalid to cleanup*/ + memset(napt_ct_valid, 0, sizeof(napt_ct_valid)); + + napt_ct_hw_sync(napt_ct_valid); +} + +void +napt_ct_scan(void) +{ + a_uint32_t ct_buf_valid_cnt = 0; + + ct_buf_valid_cnt = napt_ct_check_add(); + + napt_ct_buffer_refresh_check(ct_buf_valid_cnt); +} + +void napt_wan_switch_prehandle(void) +{ + if (wan_switch) { + napt_thread_pending = 1; + napt_l3_status_set(0, A_FALSE); + napt_ct_hw_exit(); + napt_hw_flush(); + qcaswitch_hostentry_flush(); + droute_del_acl_rules(); + ipv6_droute_del_acl_rules(); + if (nf_athrs17_hnat_wan_type == NF_S17_WAN_TYPE_PPPOE) + pppoe_del_acl_rules(); + #ifdef MULTIROUTE_WR + ip_conflict_del_acl_rules(); + #endif + if_mac_cleanup(); + napt_l3_status_set(0, A_TRUE); + napt_thread_pending = 0; + } +} + +static a_int32_t +napt_ct_init(void) +{ + if(nf_athrs17_hnat_sync_counter_en == 0) + { + napt_buffer_hash_size = NAPT_TABLE_SIZE; + napt_buffer_size = NAPT_TABLE_SIZE*8; + } + else + { + napt_buffer_hash_size = 8; + napt_buffer_size = napt_buffer_hash_size; + } + + napt_hw_mode_init(); + + if(napt_ct_buf_init() != 0) + { + HNAT_ERR_PRINTK("*****napt_ct_buf_init fail*******\n"); + return -1; + } + + return 0; +} + +static a_int32_t +napt_ct_exit(void) +{ + napt_hw_mode_cleanup(); + + napt_ct_hw_exit(); + napt_ct_buf_exit(); + + return 0; +} + +static a_int32_t +napt_ct_scan_thread(void *param) +{ +#define NAPT_CT_AGING_SEC 20 +#define ARP_CHECK_AGING_SEC 40 + + a_uint32_t times = (NAPT_CT_AGING_SEC/scan_period); + a_uint32_t arp_check_time = (ARP_CHECK_AGING_SEC/scan_period); + // a_bool_t l3_enable; + + if(napt_ct_init() != 0) + { + return 0; + } + + while(1) + { + if(!nat_sockopts_init) { + nat_ipt_sockopts_replace(); + } + if (napt_thread_pending) { + NAPT_CT_TASK_SLEEP(scan_period); + continue; + } + + if (scan_enable) { + if((--times) == 0) + { + HNAT_PRINTK("[ct hw aging start]\n"); + napt_ct_hw_aging(); + HNAT_PRINTK("[ct hw aging end]\n"); + times = (NAPT_CT_AGING_SEC/scan_period); + } + + if((--arp_check_time) == 0) + { + host_check_aging(); + arp_check_time = (ARP_CHECK_AGING_SEC/scan_period); + } + + if (times != NAPT_CT_AGING_SEC/scan_period) { + HNAT_PRINTK("[ct scan start]\n"); + napt_ct_scan(); + HNAT_PRINTK("[ct scan end]\n"); + } + } else { + if (napt_need_clean) { + napt_need_clean = 0; + napt_ct_hw_exit(); + } + } + +#ifdef ISISC /* only for S17c */ +#ifdef CONFIG_IPV6_HWACCEL + napt_set_ipv6_default_route(); +#endif +#endif + + if (NAPT_CT_TASK_SHOULD_STOP()) { + printk("should stop!\n"); + break; + } + + NAPT_CT_TASK_SLEEP(scan_period); + } + + napt_ct_exit(); + + return 0; +} + +void napt_helper_show(void) +{ + a_uint16_t hw_index; + for(hw_index = 0; hw_index < NAPT_TABLE_SIZE; hw_index++) { + if (napt_ct_addr[hw_index]) { + printk("index[%d] exist: 0x%x\n", hw_index, napt_ct_addr[hw_index]); + } + } + printk("current hardware offload count: 0x%x\n", napt_ct_hw_cnt); + printk("interate:0x%x, care:0x%x, low_thresh=0x%x\n", + napt_ct_debug_info.interate_cnt, + napt_ct_debug_info.care_cnt, + napt_ct_debug_info.thresh_low_cnt); +} + +void +napt_helper_init(void) +{ + const char napt_thread_name[] = "napt_ct_scan"; + + NAPT_CT_TASK_START(napt_ct_scan_thread, napt_thread_name); +} + + +void +napt_helper_exit(void) +{ + NAPT_CT_TASK_STOP(); +} + diff --git a/feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/lib/nat_helper_dt.h b/feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/lib/nat_helper_dt.h new file mode 100755 index 000000000..bd3550b9c --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/lib/nat_helper_dt.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _NAT_HELPER_DT_H +#define _NAT_HELPER_DT_H + +extern void host_check_aging(void); +void napt_ct_counter_decrease(void); + +#endif /*_NAT_HELPER_DT_H*/ diff --git a/feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/lib/nat_helper_hsl.c b/feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/lib/nat_helper_hsl.c new file mode 100755 index 000000000..ba7bad121 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/lib/nat_helper_hsl.c @@ -0,0 +1,879 @@ +/* + * Copyright (c) 2012, 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. + */ + + +#ifdef KVER32 +#include +#include +#else +#include +#endif +#include +#include +#include +#include +#include + +#include "fal_nat.h" +#include "fal_ip.h" + +#include "hsl_api.h" +#include "hsl.h" +#include "hsl_shared_api.h" +#include "../nat_helper.h" +#include "nat_helper_dt.h" +#include "nat_helper_hsl.h" +#include "../napt_acl.h" + +int nat_chip_ver = 0; +a_bool_t napt_add_bypass_check = A_TRUE; + +/* support 4 different interfaces (or 4 VLANs) */ +static fal_intf_mac_entry_t global_if_mac_entry[MAX_INTF_NUM] = {{0}}; +static a_uint8_t if_mac_count = 0; + +extern int setup_wan_if; +extern int setup_lan_if; + +#define DESS_CHIP(ver) ((((ver)&0xffff)>>8) == NAT_CHIP_VER_DESS) + +#define ARP_HW_COUNTER_OFFSET 8 + +static a_uint8_t +nat_hw_debug_counter_get(void) +{ + static a_uint32_t nat_debug_counter = 0; + + return ((nat_debug_counter++) & 0x7); +} + +static a_uint8_t +arp_hw_debug_counter_get(void) +{ + static a_uint32_t ip_debug_counter = 0; + + return ((ip_debug_counter++) & 0x7) + ARP_HW_COUNTER_OFFSET; +} + + +a_int32_t +nat_hw_add(nat_entry_t *nat) +{ + fal_nat_entry_t hw_nat = {0}; + + hw_nat.flags = nat->flags; + hw_nat.src_addr = nat->src_addr; + hw_nat.trans_addr = nat->trans_addr; + hw_nat.port_num = nat->port_num; + hw_nat.port_range = nat->port_range; + hw_nat.counter_en = 1; + hw_nat.counter_id = nat_hw_debug_counter_get(); + + if(NAT_ADD(0, &hw_nat) != 0) + { + return -1; + } + nat->entry_id = hw_nat.entry_id; + + return 0; +} + +a_int32_t +nat_hw_del_by_index(a_uint32_t index) +{ + fal_nat_entry_t nat_entry = {0}; + + HNAT_PRINTK("NAT_DEL(1) index=%d########\n", index); + + nat_entry.entry_id = index; + if(NAT_DEL(0, FAL_NAT_ENTRY_ID_EN, &nat_entry)!= 0) + { + return -1; + } + + return 0; +} + +a_int32_t +nat_hw_flush(void) +{ + if(NAT_DEL(0, 0, 0)!= 0) + { + return -1; + } + + return 0; +} + +a_int32_t +napt_hw_flush(void) +{ + if(NAPT_DEL(0, 0, 0)!= 0) + { + return -1; + } + + return 0; +} + +static a_uint32_t private_ip_can_update = 1; +a_int32_t +nat_hw_prv_base_can_update(void) +{ + return private_ip_can_update; +} + +void +nat_hw_prv_base_update_enable(void) +{ + private_ip_can_update = 1; +} + +void +nat_hw_prv_base_update_disable(void) +{ + private_ip_can_update = 0; +} + +static a_uint32_t private_ip_base = 0xc0a80000; +static a_uint32_t private_net_mask = 0xffffff00; +a_int32_t +nat_hw_prv_base_set(a_uint32_t ip) +{ +#define PRIVATE_IP_MASK 0xffffff00 + + ip = ntohl(ip); + + if (((nat_chip_ver & 0xffff) >> 8) == NAT_CHIP_VER_8327) + private_ip_base = ip & PRIVATE_IP_MASK; + else + private_ip_base = ip & nat_hw_prv_mask_get(); + + + if(DESS_CHIP(nat_chip_ver)) { + if (IP_PRV_BASE_ADDR_SET(0, 0, (fal_ip4_addr_t)ip) != 0) + { + return -1; + } + } else { + if (NAT_PRV_BASE_ADDR_SET(0, (fal_ip4_addr_t)ip) != 0) + { + return -1; + } + } + + HNAT_PRINTK("%s: private_ip_base:%x private_ip_can_update:%d\n", + __func__, private_ip_base, private_ip_can_update); + + return 0; +} + +a_uint32_t +nat_hw_prv_base_get(void) +{ + return private_ip_base; +} + + +a_int32_t +nat_hw_prv_mask_set(a_uint32_t ipmask) +{ + ipmask = ntohl(ipmask); + + if(DESS_CHIP(nat_chip_ver)) { + if (IP_PRV_BASE_MASK_SET(0, 0, (fal_ip4_addr_t)ipmask) != 0) + { + return -1; + } + } else if (((nat_chip_ver & 0xffff)>>8) == NAT_CHIP_VER_8337) { + if (NAT_PRV_BASE_MASK_SET(0, (fal_ip4_addr_t)ipmask) != 0) + { + return -1; + } + } + private_net_mask = ipmask; + + HNAT_PRINTK("%s: 0x%08x\n", __FUNCTION__, private_net_mask); + + return 0; +} + +a_uint32_t +nat_hw_prv_mask_get(void) +{ + return private_net_mask; +} + + +a_int32_t +nat_hw_prv_base_is_match(a_uint32_t ip) +{ +#define PRIVATE_IP_MASK 0xffffff00 + + a_uint32_t prv_base = private_ip_base; + a_uint32_t prv_mask; + + if (((nat_chip_ver & 0xffff)>>8) == NAT_CHIP_VER_8327) { + if((prv_base & PRIVATE_IP_MASK) == (ip & PRIVATE_IP_MASK)) + return 1; + } else { + prv_mask = nat_hw_prv_mask_get(); + if((prv_base & prv_mask) == (ip & prv_mask)) + return 1; + } + + HNAT_PRINTK("%s: private_ip_base:%x usaddr:%x mismatch\n", + __func__, prv_base, ip); + + return 0; +} + +static a_int32_t +_arp_hw_if_mac_add(fal_intf_mac_entry_t *if_mac_entry) +{ + return IP_INTF_ENTRY_ADD(0, if_mac_entry); +} + +static a_int32_t +_arp_hw_if_mac_del(fal_intf_mac_entry_t *if_mac_entry) +{ + return IP_INTF_ENTRY_DEL(0, FAL_IP_ENTRY_ID_EN, if_mac_entry); +} + +a_int32_t +if_mac_cleanup(void) +{ + a_uint8_t i = 0; + + if_mac_count = 0; + for(i = 0; i < MAX_INTF_NUM; i++) + { + if(_arp_hw_if_mac_del(&global_if_mac_entry[i]) != 0) { + printk("mac del fail!\n"); + return -1; + } + memset(&global_if_mac_entry[i], 0, sizeof(fal_intf_mac_entry_t)); + } + + setup_wan_if = 0; + setup_lan_if = 0; + + return 0; +} + +#define MACADDR_LEN 6 +a_int32_t +if_mac_add(a_uint8_t *mac, a_uint32_t vid, uint32_t ipv6) +{ + a_uint8_t i = 0; + a_uint8_t zero_mac[MACADDR_LEN] = {0}; + + if (!memcmp(mac, zero_mac, MACADDR_LEN)) + return 0; + + if(if_mac_count > MAX_INTF_NUM) + return -1; + + for(i = 0; i < if_mac_count; i++) + { + if((!memcmp(global_if_mac_entry[i].mac_addr.uc, mac, 6)) && + (global_if_mac_entry[i].vid_low == vid)) + { + HNAT_PRINTK("%s: mac exist id:%d\n", __func__, + global_if_mac_entry[i].entry_id); + return 0; + } + } + + if(if_mac_count == MAX_INTF_NUM) + { + HNAT_ERR_PRINTK("%s: reach mac count max\n", __func__); + return -1; + } + + memset(&global_if_mac_entry[if_mac_count], 0, sizeof(fal_intf_mac_entry_t)); + memcpy(global_if_mac_entry[if_mac_count].mac_addr.uc, mac, 6); + + global_if_mac_entry[if_mac_count].entry_id = if_mac_count; + if (1 == ipv6) + { + global_if_mac_entry[if_mac_count].ip6_route = 1; + } + else + { + global_if_mac_entry[if_mac_count].ip6_route = 0; + } + global_if_mac_entry[if_mac_count].ip4_route = 1; + + if (vid == 0) + { + global_if_mac_entry[if_mac_count].vid_low = 0; + global_if_mac_entry[if_mac_count].vid_high = 511; + } + else + { + global_if_mac_entry[if_mac_count].vid_low = vid; + global_if_mac_entry[if_mac_count].vid_high = vid; + } + + if(_arp_hw_if_mac_add(&global_if_mac_entry[if_mac_count])!= 0) + { + return -1; + } + + HNAT_PRINTK("%s: count:%d index:%d vid:%d mac:%02x-%02x-%02x-%02x-%02x-%02x\n", + __func__, if_mac_count, global_if_mac_entry[if_mac_count].entry_id, vid, + mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]); + if_mac_count ++; + + return 0; +} + +static a_int32_t +_arp_hw_add(fal_host_entry_t *arp_entry) +{ + return IP_HOST_ADD(0, arp_entry); +} + +a_int32_t +arp_hw_add(a_uint32_t port, a_uint32_t intf_id, a_uint8_t *ip, a_uint8_t *mac, int is_ipv6_entry) +{ + fal_host_entry_t arp_entry; + + +#ifdef ISIS /* Only for AR8337(S17) */ + if (NF_S17_WAN_TYPE_PPPOEV6 == nf_athrs17_hnat_wan_type) + { + memset(&arp_entry,0,sizeof(arp_entry)); + memcpy(&arp_entry.ip4_addr, ip, 4); + memcpy(arp_entry.mac_addr.uc, mac, 6); + arp_entry.status = ARP_AGE_NEVER; + if (port == S17_WAN_PORT) + { + arp_entry.port_id = port; + } + else + { + arp_entry.port_id = 6; /* always assigned to MAC 6 */ + } + arp_entry.flags = FAL_IP_IP4_ADDR; + } + else +#endif /* not ISIS */ + { + memset(&arp_entry,0,sizeof(arp_entry)); + if (0 == is_ipv6_entry) + { + memcpy(&arp_entry.ip4_addr, ip, 4); + arp_entry.ip4_addr = ntohl(arp_entry.ip4_addr); + arp_entry.flags = FAL_IP_IP4_ADDR; + } + else + { + memcpy(&arp_entry.ip6_addr, ip, 16); + arp_entry.flags = FAL_IP_IP6_ADDR; + } + memcpy(arp_entry.mac_addr.uc, mac, 6); + if ((NF_S17_WAN_TYPE_PPPOE == nf_athrs17_hnat_wan_type) && \ + (S17_WAN_PORT == port)) + { + arp_entry.status = ARP_AGE_NEVER; + } + else + { + arp_entry.status = ARP_AGE; + } + arp_entry.port_id = port; + } + + arp_entry.intf_id = intf_id; + + arp_entry.counter_en = 1; + if (S17_WAN_PORT == port) + { + arp_entry.counter_id = 0xf; + } + else + { + arp_entry.counter_id = arp_hw_debug_counter_get(); + } + + if (IP_HOST_GET(0, 0x10, &arp_entry)) { + HNAT_PRINTK("new arp for 0x%x\n", arp_entry.ip4_addr); + if(_arp_hw_add(&arp_entry) != 0) + { + HNAT_ERR_PRINTK("%s: fail\n", __func__); + return -1; + } + } + + if (0 == is_ipv6_entry) + { + HNAT_PRINTK("%s: index:%x port:%d ip:%d.%d.%d.%d\n", + __func__, arp_entry.entry_id, port, + *(ip), *(ip+1), *(ip+2), *(ip+3)); + } + + if (0 != (arp_entry.entry_id & 0xFFFFFC00)) + { + printk("Warning: arp_entry id should be only 10 bits!\n"); + } + + return arp_entry.entry_id; +} + +#define AOS_HEADER_MAGIC 0xC0DE + +a_int32_t +arp_if_info_get(void *data, a_uint32_t *sport, a_uint32_t *vid) +{ + aos_header_t *athr_header = NULL; + if((data==0) || (sport==0) || (vid==0)) + { + return -1; + } + + athr_header = (aos_header_t *)data; + +#if 0 + /*atheros header magic check*/ + if(athr_header->magic != AOS_HEADER_MAGIC) + { + return -1; + } +#endif + + *sport = athr_header->sport; + *vid = athr_header->vid; + + return 0; +} + +#define MAX_PUBLIC_IP_CNT 16 +struct public_ip_shadow +{ + a_uint32_t ip; + a_uint32_t use_cnt; +}; + +static struct public_ip_shadow public_ip_shadow[MAX_PUBLIC_IP_CNT]= {{0}}; +static a_uint32_t public_ip_cnt = 0; + +a_int32_t +nat_hw_pub_ip_add(a_uint32_t ip, a_uint32_t *index) +{ + sw_error_t rv; + a_uint32_t hw_index; + a_uint32_t i; + fal_nat_pub_addr_t ip_entry; + + for(i=0; i= MAX_PUBLIC_IP_CNT) + { + return -1; + } + + memset(&ip_entry, 0, sizeof(ip_entry)); + ip_entry.pub_addr = ip; + rv = NAT_PUB_ADDR_ADD(0,&ip_entry); + if(rv != 0) + { + return -1; + } + + public_ip_cnt++; + hw_index = ip_entry.entry_id; + public_ip_shadow[hw_index].ip = ip; + public_ip_shadow[hw_index].use_cnt++; + *index = hw_index; + + HNAT_PRINTK("%s: public_ip_cnt:%d index:%d ip:0x%x\n", + __func__, public_ip_cnt, hw_index, public_ip_shadow[hw_index].ip); + return 0; +} + + +void +napt_hw_mode_init(void) +{ + sw_error_t rv; + /* age_speedup+age_thres_1/4+age_step_4+age_timer_28s*1+ + stop_age_when1+overwrite_disable */ + /* Also set NAT mode Port strict mode/symmetric mode */ + a_uint32_t entry = 0x15F01CB; + + HSL_REG_ENTRY_SET(rv, 0, NAT_CTRL, 0, (a_uint8_t *) (&entry), + sizeof (a_uint32_t)); + + HSL_REG_ENTRY_GET(rv, 0, ROUTER_CTRL, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + + /*set locktime 100us*/ + SW_SET_REG_BY_FIELD(ROUTER_CTRL, GLB_LOCKTIME, 1, entry); + SW_SET_REG_BY_FIELD(ROUTER_CTRL, ARP_AGE_MODE, 1, entry); + + HSL_REG_ENTRY_SET(rv, 0, ROUTER_CTRL, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + HSL_REG_ENTRY_GET(rv, 0, MOD_ENABLE, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_SET_REG_BY_FIELD(MOD_ENABLE, L3_EN, 1, entry); + HSL_REG_ENTRY_SET(rv, 0, MOD_ENABLE, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + + ACL_STATUS_SET(0, A_TRUE); +} + +void +napt_hw_mode_cleanup(void) +{ + a_uint32_t entry; + sw_error_t rv; + if (!DESS_CHIP(nat_chip_ver)) { + IP_ROUTE_STATUS_SET(0, A_FALSE); + entry = 0; + } else { + HSL_REG_ENTRY_GET(rv, 0, NAT_CTRL, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_SET_REG_BY_FIELD(NAT_CTRL, NAT_EN, 0, entry); + } + HSL_REG_ENTRY_SET(rv, 0, NAT_CTRL, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + ACL_STATUS_SET(0, A_FALSE); +} + +a_int32_t +nat_hw_pub_ip_del(a_uint32_t index) +{ + sw_error_t rv; + + if(public_ip_shadow[index].use_cnt>0) + { + public_ip_shadow[index].use_cnt--; + if(public_ip_shadow[index].use_cnt == 0) + { + fal_nat_pub_addr_t ip_entry; + HNAT_PRINTK("%s: public_ip_cnt:%d index:%d ip:0x%x\n", + __func__, public_ip_cnt, index, public_ip_shadow[index].ip); + memset(&ip_entry,0,sizeof(ip_entry)); + ip_entry.pub_addr = public_ip_shadow[index].ip; + rv = NAT_PUB_ADDR_DEL(0, 1, &ip_entry); + if(rv != 0) + { + return -1; + } + + public_ip_cnt--; + } + return 0; + } + + return -1; +} + +#define napt_entry_cp(to, from) \ +{ \ + (to)->entry_id = (from)->entry_id; \ + (to)->status = (from)->status; \ + (to)->flags = (from)->flags; \ + (to)->src_addr = (from)->src_addr; \ + (to)->src_port = (from)->src_port; \ + (to)->dst_addr = (from)->dst_addr; \ + (to)->dst_port = (from)->dst_port; \ + (to)->trans_addr = (from)->trans_addr; \ + (to)->trans_port = (from)->trans_port; \ + (to)->ingress_packet = (from)->ingress_packet; \ + (to)->ingress_byte = (from)->ingress_byte; \ + (to)->egress_packet = (from)->egress_packet; \ + (to)->egress_byte = (from)->egress_byte; \ +} + +a_int32_t +napt_hw_add(napt_entry_t *napt) +{ + a_int32_t ret = 0; + fal_napt_entry_t fal_napt = {0}; + fal_host_entry_t host_entry = {0}; + a_uint32_t next_hop = 0; + + napt_entry_cp(&fal_napt, napt); + + fal_napt.flags |= FAL_NAT_ENTRY_TRANS_IPADDR_INDEX; + fal_napt.counter_en = 1; + fal_napt.counter_id = nat_hw_debug_counter_get(); + fal_napt.action = FAL_MAC_FRWRD; + + if (!napt_add_bypass_check) { + /*check arp entry*/ + host_entry.flags = FAL_IP_IP4_ADDR; + host_entry.ip4_addr = fal_napt.src_addr; + ret = IP_HOST_GET(0, FAL_IP_ENTRY_IPADDR_EN, &host_entry); + if (ret) { + HNAT_ERR_PRINTK("can not find src host entry!\n"); + return ret; + } + if (nf_athrs17_hnat_wan_type != NF_S17_WAN_TYPE_PPPOE) { + next_hop = get_next_hop(fal_napt.dst_addr, fal_napt.src_addr); + host_entry.ip4_addr = next_hop ? next_hop : fal_napt.dst_addr; + ret = IP_HOST_GET(0, FAL_IP_ENTRY_IPADDR_EN, &host_entry); + if (ret) { + HNAT_ERR_PRINTK("can not find dst host entry!\n"); + return ret; + } + } + } + + ret = NAPT_ADD(0, &fal_napt); + + napt->entry_id = fal_napt.entry_id; + return ret; +} + +a_int32_t +napt_hw_get(napt_entry_t *napt, fal_napt_entry_t *entry) +{ + a_int32_t ret = 0; + fal_napt_entry_t fal_napt = {0}; + + napt_entry_cp(&fal_napt, napt); + + ret = NAPT_GET(0, 0, &fal_napt); + + if(!ret) + *entry = fal_napt; + return ret; +} + +a_int32_t +napt_hw_dnat_cookie_add(napt_entry_t *napt, a_uint32_t cookie) +{ + a_int32_t ret = 0; + fal_napt_entry_t fal_napt = {0}; + fal_napt.flags = napt->flags | 0x10; + fal_napt.status = 0xf; + fal_napt.dst_addr = napt->dst_addr; + fal_napt.dst_port = napt->dst_port; + fal_napt.trans_addr = napt->trans_addr; + fal_napt.trans_port = napt->trans_port; + fal_napt.src_port = napt->src_port; + fal_napt.action = FAL_MAC_RDT_TO_CPU; + fal_napt.flow_cookie = cookie; + ret = NAPT_ADD(0, &fal_napt); + return ret; +} + +a_int32_t +napt_hw_snat_cookie_add(napt_entry_t *napt, a_uint32_t cookie) +{ + a_int32_t ret = 0; + fal_napt_entry_t fal_napt = {0}; + fal_napt.flags = napt->flags | 0x10; + fal_napt.status = 0xf; + fal_napt.dst_addr = napt->dst_addr; + fal_napt.dst_port = napt->dst_port; + fal_napt.src_addr = napt->src_addr; + fal_napt.src_port = napt->src_port; + fal_napt.trans_port = napt->trans_port; + fal_napt.action = FAL_MAC_RDT_TO_CPU; + fal_napt.flow_cookie = cookie; + ret = NAPT_ADD(0, &fal_napt); + return ret; +} + + + + +a_int32_t +napt_hw_del(napt_entry_t *napt) +{ + a_int32_t ret = 0; + + fal_napt_entry_t fal_napt = {0}; + + napt_entry_cp(&fal_napt, napt); + napt_ct_counter_decrease(); + + ret = NAPT_DEL(0, FAL_NAT_ENTRY_KEY_EN, &fal_napt); + + if(ret != 0) + { + return -1; + } + else + { + return 0; + } +} + +a_int32_t +napt_hw_first_by_age(napt_entry_t *napt, a_uint32_t age) +{ + a_int32_t ret = 0; + fal_napt_entry_t fal_napt = {0}; + + fal_napt.entry_id = FAL_NEXT_ENTRY_FIRST_ID; + fal_napt.status = age; + + if(NAPT_NEXT(0, FAL_NAT_ENTRY_AGE_EN ,&fal_napt) !=0) + { + ret = -1; + } + + napt_entry_cp(napt, &fal_napt); + + return ret; +} + +a_int32_t +napt_hw_next_by_age(napt_entry_t *napt, a_uint32_t age) +{ + a_int32_t ret = 0; + fal_napt_entry_t fal_napt = {0}; + + fal_napt.entry_id = napt->entry_id; + fal_napt.status = age; + + if(NAPT_NEXT(0, FAL_NAT_ENTRY_AGE_EN ,&fal_napt) !=0) + { + ret = -1; + } + + napt_entry_cp(napt, &fal_napt); + + return ret; +} + +a_int32_t +napt_hw_get_by_index(napt_entry_t *napt, a_uint16_t hw_index) +{ + fal_napt_entry_t fal_napt = {0}; + sw_error_t rv; + + if(hw_index == 0) + { + fal_napt.entry_id = FAL_NEXT_ENTRY_FIRST_ID; + } + else + { + fal_napt.entry_id = hw_index - 1; + } + + if((rv = NAPT_NEXT(0, 0, &fal_napt)) != 0) + { + HNAT_ERR_PRINTK("[rv:%d] error hw:%x sw:%x\n", + rv, napt->entry_id, hw_index); + return -1; + } + + napt_entry_cp(napt, &fal_napt); + + if(napt->entry_id != hw_index) + { + HNAT_ERR_PRINTK("hw_index error hw:%x sw:%x\n", + napt->entry_id, hw_index); + return -1; + } + + return 0; +} + +a_int32_t napt_hw_get_by_sip(a_uint32_t sip) +{ + fal_napt_entry_t napt; + + memset(&napt, 0, sizeof(fal_napt_entry_t)); + napt.entry_id = FAL_NEXT_ENTRY_FIRST_ID; + napt.src_addr = sip; + if (fal_napt_next(0, FAL_NAT_ENTRY_SOURCE_IP_EN, &napt) == SW_OK) { + return 0; + } + + return -1; +} + +a_uint32_t +napt_hw_used_count_get(void) +{ +#define NAPT_USED_COUNT +#define NAPT_USED_COUNT_OFFSET 0x0e44 /*was:0x0e38*/ +#define NAPT_USED_COUNT_E_LENGTH 11 +#define NAPT_USED_COUNT_E_OFFSET 0x0 +#define NAPT_USED_COUNT_NR_E 1 + sw_error_t rv; + + a_uint32_t count = 0; + HSL_REG_ENTRY_GET(rv, 0, NAPT_USED_COUNT, 0, (a_uint8_t *) (&count), + sizeof (a_uint32_t)); + + return count; +} + +sw_error_t napt_l3_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, MOD_ENABLE, 0, L3_EN, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + return rv; +} + +sw_error_t napt_l3_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_REG_FIELD_GET(rv, dev_id, MOD_ENABLE, 0, L3_EN, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +sw_error_t napt_helper_hsl_init() +{ + return SW_OK; +} + + diff --git a/feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/lib/nat_helper_hsl.h b/feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/lib/nat_helper_hsl.h new file mode 100755 index 000000000..bb7a778d7 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/lib/nat_helper_hsl.h @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2012, 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. + */ + + +#ifndef _NAT_HELPER_HSL_H +#define _NAT_HELPER_HSL_H + +#ifdef KVER32 +#include +#include +#else +#include +#endif + +#include +#include "fal_nat.h" + +#define NAT_HW_NUM 32 +#define NAT_HW_PORT_RANGE_MAX 255 + +#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_PORT_CHECK 0x20 + +#define MAX_INTF_NUM 4 + +/* WAN connection types */ +#define NF_S17_WAN_TYPE_IP 0 /* DHCP, static IP connection */ +#define NF_S17_WAN_TYPE_PPPOE 1 /* PPPoE connection */ +#define NF_S17_WAN_TYPE_GRE 2 /* GRE connections, ex: PPTP */ +#define NF_S17_WAN_TYPE_PPPOEV6 3 /* IPv6 PPPoE connection using the same session as IPv4 connection */ +#define NF_S17_WAN_TYPE_PPPOES0 4 /* PPPoE connection but not yet connected */ +/* define the H/W Age mode for NAPT entries */ +#define ARP_AGE_NEVER 7 +#define ARP_AGE 6 + +#if !defined (HSL_STANDALONG) +/*NAT API*/ +#define NAPT_ADD fal_napt_add +#define NAPT_GET fal_napt_get +#define NAT_PUB_ADDR_ADD fal_nat_pub_addr_add +#define NAPT_NEXT fal_napt_next +#define NAT_PRV_BASE_ADDR_SET fal_nat_prv_base_addr_set +#define NAT_PRV_BASE_MASK_SET fal_nat_prv_base_mask_set +#define NAPT_DEL fal_napt_del +#define NAT_DEL fal_nat_del +#define NAT_PUB_ADDR_DEL fal_nat_pub_addr_del +#define NAT_ADD fal_nat_add +#define NAT_PRV_ADDR_MODE_GET fal_nat_prv_addr_mode_get + +/*IP API*/ +#define IP_INTF_ENTRY_ADD fal_ip_intf_entry_add +#define IP_HOST_ADD fal_ip_host_add +#define IP_HOST_DEL fal_ip_host_del +#define IP_HOST_GET fal_ip_host_get +#define IP_HOST_NEXT fal_ip_host_next +#define IP_INTF_ENTRY_DEL fal_ip_intf_entry_del +#define IP_HOST_PPPOE_BIND fal_ip_host_pppoe_bind +#define IP_ROUTE_STATUS_SET fal_ip_route_status_set +#define IP_HOST_ROUTE_ADD fal_ip_host_route_set +#define IP_PRV_BASE_ADDR_SET fal_ip_vrf_base_addr_set +#define IP_PRV_BASE_MASK_SET fal_ip_vrf_base_mask_set + +/* PPPOE */ +#define PPPOE_STATUS_GET fal_pppoe_status_get +#define PPPOE_STATUS_SET fal_pppoe_status_set +#define PPPOE_SESSION_ID_SET fal_pppoe_session_id_set +#define PPPOE_SESSION_TABLE_ADD fal_pppoe_session_table_add +#define PPPOE_SESSION_TABLE_DEL fal_pppoe_session_table_del +#define RTD_PPPOE_EN_SET fal_rtd_pppoe_en_set + +/*MISC API*/ +#define MISC_ARP_CMD_SET fal_arp_cmd_set +#define CPU_VID_EN_SET fal_cpu_vid_en_set +#define PORT_ARP_ACK_STATUS_SET fal_port_arp_ack_status_set +#define CPU_PORT_STATUS_SET fal_cpu_port_status_set + +/*ACL API*/ +#define ACL_RULE_ADD fal_acl_rule_add +#define ACL_RULE_DEL fal_acl_rule_delete +#define ACL_LIST_CREATE fal_acl_list_creat +#define ACL_LIST_DESTROY fal_acl_list_destroy +#define ACL_LIST_BIND fal_acl_list_bind +#define ACL_LIST_UNBIND fal_acl_list_unbind +#define ACL_STATUS_GET fal_acl_status_get +#define ACL_STATUS_SET fal_acl_status_set +#define ACL_PORT_UDF_PROFILE_SET fal_acl_port_udf_profile_set + +/*VLAN API */ +#define VLAN_NEXT fal_vlan_next + +/* PORTVLAN API */ +#define PORTVLAN_ROUTE_DEFV_SET(dev_id, port_id) +#define NETISOLATE_SET fal_netisolate_set + +/* PORT_CTRL API */ +#define HEADER_TYPE_SET fal_header_type_set +#define PORT_TXHDR_MODE_SET fal_port_txhdr_mode_set + +/* REG ACCESS API */ +#define REG_GET fal_reg_get +#endif + +extern int nf_athrs17_hnat; +extern int nf_athrs17_hnat_wan_type; +extern int nf_athrs17_hnat_ppp_id; +extern int nf_athrs17_hnat_udp_thresh; +extern a_uint32_t nf_athrs17_hnat_wan_ip; +extern a_uint32_t nf_athrs17_hnat_ppp_peer_ip; +extern unsigned char nf_athrs17_hnat_ppp_peer_mac[ETH_ALEN]; +extern unsigned char nf_athrs17_hnat_wan_mac[ETH_ALEN]; +extern int nf_athrs17_hnat_sync_counter_en; + +extern int nf_athrs17_hnat_ppp_id2; +extern unsigned char nf_athrs17_hnat_ppp_peer_mac2[ETH_ALEN]; + +enum { + NAT_CHIP_VER_8327 = 0x12, + NAT_CHIP_VER_8337 = 0x13, + NAT_CHIP_VER_DESS = 0x14, +}; + +typedef struct +{ + a_uint32_t entry_id; + a_uint32_t flags; + a_uint32_t src_addr; + a_uint32_t trans_addr; + a_uint16_t port_num; + a_uint16_t port_range; +} nat_entry_t; + +typedef struct +{ + a_uint32_t entry_id; + a_uint32_t flags; + a_uint32_t status; + a_uint32_t src_addr; + a_uint32_t dst_addr; + a_uint16_t src_port; + a_uint16_t dst_port; + a_uint32_t trans_addr; + a_uint16_t trans_port; + a_uint32_t ingress_packet; + a_uint32_t ingress_byte; + a_uint32_t egress_packet; + a_uint32_t egress_byte; +} napt_entry_t; + +#if defined (__BIG_ENDIAN) +typedef struct +{ + a_uint16_t ver:2; + a_uint16_t pri:3; + a_uint16_t type:5; + a_uint16_t rev:2; + a_uint16_t with_tag:1; + a_uint16_t sport:3; + a_uint16_t vid; + a_uint16_t magic; +} aos_header_t; +#elif defined (__LITTLE_ENDIAN) +typedef struct +{ + a_uint16_t vid; + a_uint16_t sport:3; + a_uint16_t with_tag:1; + a_uint16_t rev:2; + a_uint16_t type:5; + a_uint16_t pri:3; + a_uint16_t ver:2; +} aos_header_t; +#else +#error "no ENDIAN" +#endif + +a_int32_t +nat_hw_add(nat_entry_t *nat); +a_int32_t +nat_hw_del_by_index(a_uint32_t index); +a_int32_t +nat_hw_flush(void); +a_int32_t +napt_hw_flush(void); +a_int32_t +nat_hw_prv_base_can_update(void); +void +nat_hw_prv_base_update_enable(void); +void +nat_hw_prv_base_update_disable(void); +a_int32_t +nat_hw_prv_base_set(a_uint32_t ip); +a_uint32_t +nat_hw_prv_base_get(void); +a_int32_t +nat_hw_prv_mask_set(a_uint32_t ipmask); +a_uint32_t +nat_hw_prv_mask_get(void); +a_int32_t +nat_hw_prv_base_is_match(a_uint32_t ip); +a_int32_t +if_mac_add(uint8_t *mac, uint32_t vid, uint32_t ipv6); +a_int32_t +if_mac_cleanup(void); +a_int32_t +arp_hw_add(a_uint32_t port, a_uint32_t intf_id, a_uint8_t *ip, a_uint8_t *mac, int is_ipv6_entry); +a_int32_t +arp_if_info_get(void *data, a_uint32_t *sport, a_uint32_t *vid); +a_int32_t +nat_hw_pub_ip_add(a_uint32_t ip, a_uint32_t *index); +void +napt_hw_mode_init(void); +void +napt_hw_mode_cleanup(void); +a_int32_t +nat_hw_pub_ip_del(a_uint32_t index); +a_int32_t +napt_hw_add(napt_entry_t *napt_entry); +a_int32_t +napt_hw_get(napt_entry_t *napt, fal_napt_entry_t *entry); +a_int32_t +napt_hw_dnat_cookie_add(napt_entry_t *napt, a_uint32_t cookie); +a_int32_t +napt_hw_snat_cookie_add(napt_entry_t *napt, a_uint32_t cookie); +a_int32_t +napt_hw_del(napt_entry_t *napt_entry); +a_int32_t +napt_hw_first_by_age(napt_entry_t *napt, a_uint32_t age); +a_int32_t +napt_hw_next_by_age(napt_entry_t *napt, a_uint32_t age); +a_int32_t +napt_hw_get_by_index(napt_entry_t *napt, a_uint16_t hw_index); +a_int32_t napt_hw_get_by_sip(a_uint32_t sip); +a_uint32_t +napt_hw_used_count_get(void); + +sw_error_t napt_l3_status_set(a_uint32_t dev_id, a_bool_t enable); +sw_error_t napt_l3_status_get(a_uint32_t dev_id, a_bool_t * enable); + +sw_error_t napt_helper_hsl_init(void); + + +#endif /*_NAT_HELPER_HSL_H*/ + diff --git a/feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/napt_acl.c b/feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/napt_acl.c new file mode 100755 index 000000000..2d0de4f9a --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/napt_acl.c @@ -0,0 +1,1622 @@ +/* + * Copyright (c) 2012, 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. + */ + + +#ifdef KVER32 +#include +#include +#else +#include +#endif +#include +#include + +#include "napt_acl.h" +#include "nat_helper.h" +#include "lib/nat_helper_hsl.h" +#include "hsl_shared_api.h" + +static uint32_t aclrulemask = 0; +extern int nat_chip_ver; + +uint32_t +get_aclrulemask(void) +{ + uint32_t ret; + unsigned long flags; + + local_irq_save(flags); + ret = aclrulemask; + local_irq_restore(flags); + + return ret; +} + +void +set_aclrulemask(uint32_t acl_list) +{ + unsigned long flags; + + local_irq_save(flags); + aclrulemask |= 1<s6_addr32[0]; /* FF02::1:FF00:0000/104 */ + myacl.dest_ip6_val.ul[1] = local_ip->s6_addr32[1]; + myacl.dest_ip6_val.ul[2] = local_ip->s6_addr32[2]; + myacl.dest_ip6_val.ul[3] = local_ip->s6_addr32[3]; + myacl.dest_ip6_mask.ul[0] = 0xffffffff; + myacl.dest_ip6_mask.ul[1] = 0xffffffff; + myacl.dest_ip6_mask.ul[2] = 0xffffffff; + myacl.dest_ip6_mask.ul[3] = 0xff000000; + + FAL_FIELD_FLG_SET ( myacl.field_flg, FAL_ACL_FIELD_INVERSE_ALL ); + FAL_FIELD_FLG_SET ( myacl.field_flg, FAL_ACL_FIELD_IP6_DIP ); + FAL_ACTION_FLG_SET ( myacl.action_flg, FAL_ACL_ACTION_ARP_EN ); + + myacl.arp_ptr = gw_entry_id; + + rtnval = ACL_LIST_CREATE(0, S17_ACL_LIST_IPV6DROUTE, S17_ACL_LIST_PRIO_HIGH); + if ( rtnval != SW_OK ) + { + printk("qcaswitch_acl_list_creat ERROR...\n" ); + printk("already created!? \n"); + return ; + } + + rtnval = ACL_RULE_ADD (0, S17_ACL_LIST_IPV6DROUTE, 0, 1, &myacl ); + if ( rtnval != SW_OK ) + { + printk ( "qcaswitch_acl_rule_add ERROR...\n" ); + return ; + } + + for (i = S17_LAN_PORT0; i <= S17_LAN_PORT4; i++) { + if (i != S17_WAN_PORT) + ACL_LIST_BIND (0, S17_ACL_LIST_IPV6DROUTE, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, i); + } + + /* check for the ACL enable bit */ + if (ACL_STATUS_GET(0, &val) == SW_OK) + { + if (val != A_TRUE) + { + printk("ACL is not yet enabled. Enabling... \n"); + ACL_STATUS_SET(0, A_TRUE); + } + } + + set_aclrulemask(S17_ACL_LIST_IPV6DROUTE); +} + +/* + * Del Default Route ACL rules + */ +void ipv6_droute_del_acl_rules(void) +{ + int i; + + HNAT_PRINTK("IPv6 default route del rule #%d\n", S17_ACL_LIST_IPV6DROUTE); + + if (!(get_aclrulemask() & (1 << S17_ACL_LIST_IPV6DROUTE))) + return; + + for (i = S17_LAN_PORT0; i <= S17_LAN_PORT4; i++) { + if (i != S17_WAN_PORT) + ACL_LIST_UNBIND(0, S17_ACL_LIST_IPV6DROUTE, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, i); + } + + ACL_RULE_DEL(0, S17_ACL_LIST_IPV6DROUTE, 0, 1); + + + ACL_LIST_DESTROY(0, S17_ACL_LIST_IPV6DROUTE); + + unset_aclrulemask(S17_ACL_LIST_IPV6DROUTE); +} + + +static int isis_pppoe_del_rule0(void) +{ + int rtnval; + + rtnval = ACL_LIST_UNBIND(0, S17_ACL_LIST_PPPOE, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, S17_CPU_PORT); + if (rtnval != SW_OK) + aos_printk("unbind error... \n"); + + rtnval = ACL_RULE_DEL(0, S17_ACL_LIST_PPPOE, 0, 1); + if (rtnval != SW_OK) + aos_printk("delete error... \n"); + + rtnval = ACL_LIST_DESTROY(0, S17_ACL_LIST_PPPOE); + if (rtnval != SW_OK) + aos_printk("destroy error... \n"); + + return rtnval; +} + + +/* + * PPPoE ACL rules + * Force ARP_INDEX_EN to the next hop for CPU port + * Force SNAT and ARP_INDEX_EN to the next hop for LAN ports + */ +void pppoe_add_acl_rules( + uint32_t wan_ip, uint32_t local_ip, + uint32_t local_ip_mask, uint32_t gw_entry_id) +{ + fal_acl_rule_t myacl; + uint32_t rtnval, cnt; + a_bool_t val; + int i; + + /* do the 1st, 2nd and 3rd rules */ + for (cnt = 0; cnt < 3; cnt++) + { + memset(&myacl, 0, sizeof(fal_acl_rule_t)); + + switch (cnt) + { + case 0: + if (((nat_chip_ver & 0xffff)>>8) != NAT_CHIP_VER_8327) + break; + + aos_printk("PPPoE adding rule #%d\n", S17_ACL_LIST_PPPOE); + myacl.rule_type = FAL_ACL_RULE_IP4; + myacl.src_ip4_val = wan_ip; + myacl.src_ip4_mask = 0xffffffff; + aos_printk("WAN IP: %.8x\n", wan_ip); + /* + IPv4 rule, with SIP field + IF SIP == WAN IP, FORCE the ARP_INDEX_EN to the PPPoE ARP INDEX + enable packet forwarding & forward only. i.e. no FORCE_L3_MODE + ARP_INDEX_EN, to the PPPoE peer ARP index, + Change the CVID to WAN_VID (2) + Bind to CPU port + */ + FAL_FIELD_FLG_SET(myacl.field_flg, FAL_ACL_FIELD_IP4_SIP); + FAL_FIELD_FLG_SET(myacl.field_flg, FAL_ACL_FIELD_MAC_CTAG_VID); + + FAL_ACTION_FLG_SET(myacl.action_flg, FAL_ACL_ACTION_ARP_EN); + FAL_ACTION_FLG_SET(myacl.action_flg, FAL_ACL_ACTION_REMARK_CTAG_VID); + + myacl.arp_ptr = gw_entry_id; + /* fixed with CVID = 2 */ + myacl.ctag_vid = 2; + + rtnval = ACL_LIST_CREATE(0, S17_ACL_LIST_PPPOE, S17_ACL_LIST_PRIO_HIGH); + if (rtnval != SW_OK) + { + aos_printk("ACL_LIST_CREATE ERROR...\n"); + aos_printk("PPPoE Session ID changed !? \n"); + /* delete the old ACL list */ + rtnval = isis_pppoe_del_rule0(); + if (rtnval != SW_OK) + aos_printk("pppoe_del_rule0: %d \n", rtnval); + + /* create the ACL list again */ + rtnval = ACL_LIST_CREATE(0, S17_ACL_LIST_PPPOE, S17_ACL_LIST_PRIO_HIGH); + if (rtnval != SW_OK) + { + aos_printk("ACL_LIST_CREATE ERROR...\n"); + break; + } + } + + rtnval = ACL_RULE_ADD(0, S17_ACL_LIST_PPPOE, 0, 1, &myacl); + if (rtnval != SW_OK) + { + aos_printk("ACL_RULE_ADD ERROR...\n"); + break; + } + + ACL_LIST_BIND(0, S17_ACL_LIST_PPPOE, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, S17_CPU_PORT_W); + + break; + + case 1: + aos_printk("PPPoE adding rule #%d\n", S17_ACL_LIST_PPPOE+1); + myacl.rule_type = FAL_ACL_RULE_IP4; + myacl.dest_ip4_val = ntohl(local_ip); + myacl.dest_ip4_mask = ntohl(local_ip_mask); + + /* + IPv4 rule, with DIP field + IF DIP != LAN IP, FORCE the ARP_INDEX_EN to the PPPoE ARP INDEX + AND FORCE L3 SNAT + ARP_INDEX_EN, to the PPPoE peer ARP index + Bind to LAN ports + */ + + FAL_FIELD_FLG_SET(myacl.field_flg, FAL_ACL_FIELD_INVERSE_ALL); + FAL_FIELD_FLG_SET(myacl.field_flg, FAL_ACL_FIELD_IP4_DIP); + + FAL_ACTION_FLG_SET(myacl.action_flg, FAL_ACL_ACTION_POLICY_FORWARD_EN); + FAL_ACTION_FLG_SET(myacl.action_flg, FAL_ACL_ACTION_ARP_EN); + + myacl.arp_ptr = gw_entry_id; + myacl.policy_fwd = FAL_ACL_POLICY_SNAT; + + rtnval = ACL_LIST_CREATE(0, S17_ACL_LIST_PPPOE+1, S17_ACL_LIST_PRIO_HIGH); + if (rtnval != SW_OK) + { + aos_printk("ACL_LIST_CREATE ERROR...\n"); + break; + } + + rtnval = ACL_RULE_ADD(0, S17_ACL_LIST_PPPOE+1, 0, 1, &myacl); + if (rtnval != SW_OK) + { + aos_printk("ACL_RULE_ADD ERROR...\n"); + break; + } + /* bind to LAN ports (1-4) */ + for (i = S17_LAN_PORT0; i <= S17_LAN_PORT4; i++) { + if (i != S17_WAN_PORT) + ACL_LIST_BIND(0, S17_ACL_LIST_PPPOE+1, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, i); + } + + break; + + case 2: + /* + User defined filter ACL + filter out 0x8100000288641100 packets and set the CVID to + a predefined VID (100 in this case) + ARP_INDEX_EN, to the PPPoE peer ARP index + Bind to CPU port + */ + aos_printk("PPPoE adding rule #%d\n", S17_ACL_LIST_PPPOE+2); + myacl.rule_type = FAL_ACL_RULE_UDF; + /* set the UDP ACL type as L2, with length 8, offset 12 */ + ACL_PORT_UDF_PROFILE_SET(0, S17_CPU_PORT, FAL_ACL_UDF_TYPE_L2, 12, 8); + myacl.udf_len = 8; + myacl.udf_offset = 12; + myacl.udf_type = FAL_ACL_UDF_TYPE_L2; + memset(&myacl.udf_val, 0, sizeof(myacl.udf_val)); + memset(&myacl.udf_mask, 0, sizeof(myacl.udf_mask)); + /* UDF filter to check for 0x8100000288641100 packets */ + myacl.udf_val[0] = 0x81; + myacl.udf_val[1] = 0x00; + myacl.udf_val[2] = 0x00; + myacl.udf_val[3] = 0x02; + myacl.udf_val[4] = 0x88; + myacl.udf_val[5] = 0x64; + myacl.udf_val[6] = 0x11; + myacl.udf_val[7] = 0x00; + + myacl.udf_mask[0] = 0xff; + myacl.udf_mask[1] = 0xff; + myacl.udf_mask[2] = 0xff; + myacl.udf_mask[3] = 0xff; + myacl.udf_mask[4] = 0xff; + myacl.udf_mask[5] = 0xff; + myacl.udf_mask[6] = 0xff; + myacl.udf_mask[7] = 0xff; + + FAL_FIELD_FLG_SET(myacl.field_flg, FAL_ACL_FIELD_UDF); + FAL_FIELD_FLG_SET(myacl.field_flg, FAL_ACL_FIELD_MAC_CTAG_VID); + + FAL_ACTION_FLG_SET(myacl.action_flg, FAL_ACL_ACTION_ARP_EN); + FAL_ACTION_FLG_SET(myacl.action_flg, FAL_ACL_ACTION_REMARK_CTAG_VID); + + myacl.arp_ptr = gw_entry_id; + /* fixed with CVID = 100 */ + myacl.ctag_vid = 100; + + rtnval = ACL_LIST_CREATE(0, S17_ACL_LIST_PPPOE + 2, S17_ACL_LIST_PRIO_HIGH); + if (rtnval != SW_OK) + { + aos_printk("ACL_LIST_CREATE ERROR...\n"); + break; + } + + rtnval = ACL_RULE_ADD(0, S17_ACL_LIST_PPPOE + 2, 0, 1, &myacl); + if (rtnval != SW_OK) + { + aos_printk("ACL_RULE_ADD ERROR...\n"); + break; + } + + ACL_LIST_BIND(0, S17_ACL_LIST_PPPOE + 2, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, S17_CPU_PORT); + break; + } + } + + if (ACL_STATUS_GET(0, &val) == SW_OK) + { + if (val != A_TRUE) + { + aos_printk("ACL is not yet enabled. Enabling... \n"); + ACL_STATUS_SET(0, A_TRUE); + } + } +} + +static void pppoe_del_acl_rule1(void) +{ + int i; + for (i = S17_LAN_PORT0; i <= S17_LAN_PORT4; i++) { + if (i != S17_WAN_PORT) + ACL_LIST_UNBIND(0, S17_ACL_LIST_PPPOE+1, + FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, i); + } + + ACL_RULE_DEL(0, S17_ACL_LIST_PPPOE+1, 0, 1); + + ACL_LIST_DESTROY(0, S17_ACL_LIST_PPPOE+1); +} + +static void pppoe_del_acl_rule2(void) +{ + ACL_LIST_UNBIND(0, S17_ACL_LIST_PPPOE+2, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, S17_CPU_PORT); + ACL_LIST_UNBIND(0, S17_ACL_LIST_PPPOE+2, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, S17_LAN_PORT1); + ACL_LIST_UNBIND(0, S17_ACL_LIST_PPPOE+2, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, S17_LAN_PORT2); + ACL_LIST_UNBIND(0, S17_ACL_LIST_PPPOE+2, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, S17_LAN_PORT3); + + ACL_RULE_DEL(0, S17_ACL_LIST_PPPOE+2, 0, 1); + + ACL_LIST_DESTROY(0, S17_ACL_LIST_PPPOE+2); +} +void pppoe_del_acl_rules(void) +{ + if (((nat_chip_ver & 0xffff)>>8) == NAT_CHIP_VER_8327) + isis_pppoe_del_rule0(); + pppoe_del_acl_rule1(); + pppoe_del_acl_rule2(); +} +/* + * When LAN & WAN IPs are too close, apply this ACL + * ex: WAN 192.168.1.x, LAN 192.168.0.x + */ +void +ip_conflict_add_acl_rules(uint32_t wan_ip, uint32_t lan_ip, uint32_t gw_entry_id) +{ + fal_acl_rule_t myacl; + uint32_t rtnval, cnt; + a_bool_t val; + int i; + + if (get_aclrulemask() & (1 << S17_ACL_LIST_IPCONF)) return; + + for (cnt = 0; cnt < 2; cnt++) + { + memset(&myacl, 0, sizeof(fal_acl_rule_t)); + + aos_printk("IP conflict adding rule #%d\n", cnt); + + switch (cnt) + { + case 0: + myacl.rule_type = FAL_ACL_RULE_IP4; + myacl.dest_ip4_val = lan_ip; + myacl.dest_ip4_mask = 0xffffff00; + myacl.src_ip4_val = lan_ip; + myacl.src_ip4_mask = 0xffffff00; + + /* + IPv4 rule, with DIP & SIP field + for DIP and SIP = LAN IP, do the next step + */ + FAL_FIELD_FLG_SET(myacl.field_flg, FAL_ACL_FIELD_IP4_DIP); + FAL_FIELD_FLG_SET(myacl.field_flg, FAL_ACL_FIELD_IP4_SIP); + + rtnval = ACL_LIST_CREATE(0, S17_ACL_LIST_IPCONF, S17_ACL_LIST_PRIO_HIGH); + if (rtnval != SW_OK) + { + aos_printk("ACL_LIST_CREATE ERROR...\n"); + break; + } + + rtnval = ACL_RULE_ADD(0, S17_ACL_LIST_IPCONF, 0, 1, &myacl); + if (rtnval != SW_OK) + { + aos_printk("ACL_RULE_ADD ERROR...\n"); + break; + } + + /* bind to LAN ports */ + for (i = S17_LAN_PORT0; i <= S17_LAN_PORT4; i++) { + if (i != S17_WAN_PORT) + ACL_LIST_BIND(0, S17_ACL_LIST_IPCONF, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, i); + } + + aclrulemask |= (1 << S17_ACL_LIST_IPCONF); + set_aclrulemask(S17_ACL_LIST_IPCONF); + + break; + + case 1: + aos_printk("ARP index entry_id: %d\n", gw_entry_id); + + myacl.rule_type = FAL_ACL_RULE_IP4; + myacl.src_ip4_val = lan_ip; + myacl.src_ip4_mask = 0xffffff00; + + /* + IPv4 rule, with SIP field + enable packet forwarding & forward only. i.e. no FORCE_L3_MODE + ARP_INDEX_EN, to the PPPoE peer ARP index + */ + + FAL_FIELD_FLG_SET(myacl.field_flg, FAL_ACL_FIELD_IP4_SIP); + + FAL_ACTION_FLG_SET(myacl.action_flg, FAL_ACL_ACTION_POLICY_FORWARD_EN); + FAL_ACTION_FLG_SET(myacl.action_flg, FAL_ACL_ACTION_ARP_EN); + + myacl.arp_ptr = gw_entry_id; + myacl.policy_fwd = FAL_ACL_POLICY_SNAT; + + /* rule no. 4 */ + rtnval = ACL_LIST_CREATE(0, S17_ACL_LIST_IPCONF+1, S17_ACL_LIST_PRIO_HIGH); + if (rtnval != SW_OK) + { + aos_printk("ACL_LIST_CREATE ERROR...\n"); + break; + } + + rtnval = ACL_RULE_ADD(0, S17_ACL_LIST_IPCONF+1, 0, 1, &myacl); + if (rtnval != SW_OK) + { + aos_printk("ACL_RULE_ADD ERROR...\n"); + break; + } + /* bind to LAN ports (1-4) */ + for (i = S17_LAN_PORT0; i <= S17_LAN_PORT4; i++) { + if (i != S17_WAN_PORT) + ACL_LIST_BIND(0, S17_ACL_LIST_IPCONF+1, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, i); + } + + break; + + default: + break; + } + } + + if (ACL_STATUS_GET(0, &val) == SW_OK) + { + if (val != A_TRUE) + { + aos_printk("ACL is not yet enabled. Enabling... \n"); + ACL_STATUS_SET(0, A_TRUE); + } + } +} + +void ip_conflict_del_acl_rules(void) +{ + int i; + + if (!(get_aclrulemask() & (1 << S17_ACL_LIST_IPCONF))) + return; + + for (i = S17_LAN_PORT0; i <= S17_LAN_PORT4; i++) { + if (i != S17_WAN_PORT) { + ACL_LIST_UNBIND(0, S17_ACL_LIST_IPCONF, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, i); + ACL_LIST_UNBIND(0, S17_ACL_LIST_IPCONF+1, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, i); + } + } + + ACL_RULE_DEL(0, S17_ACL_LIST_IPCONF, 0, 1); + + ACL_LIST_DESTROY(0, S17_ACL_LIST_IPCONF); + + ACL_RULE_DEL(0, S17_ACL_LIST_IPCONF+1, 0, 1); + + ACL_LIST_DESTROY(0, S17_ACL_LIST_IPCONF+1); + + unset_aclrulemask(S17_ACL_LIST_IPCONF); +} + + +/* +solicted_node address + FF02::1:FF00:0000/104 => Solicited-Node Address +*/ +void +ipv6_snooping_solicted_node_add_acl_rules ( void ) +{ + fal_acl_rule_t myacl; + uint32_t rtnval; + a_bool_t val; + int i; + + memset ( &myacl, 0, sizeof ( fal_acl_rule_t ) ); + + aos_printk("Adding ACL rules %d - %s\n", S17_ACL_LIST_IPV6_SOLICITED_NODE, __func__); + myacl.rule_type = FAL_ACL_RULE_IP6; + myacl.dest_ip6_val.ul[0] = 0xff020000; /* FF02::1:FF00:0000/104 */ + myacl.dest_ip6_val.ul[1] = 0x00000000; + myacl.dest_ip6_val.ul[2] = 0x00000001; + myacl.dest_ip6_val.ul[3] = 0xff000000; + + myacl.dest_ip6_mask.ul[0] = 0xffffffff; + myacl.dest_ip6_mask.ul[1] = 0xffffffff; + myacl.dest_ip6_mask.ul[2] = 0xffffffff; + myacl.dest_ip6_mask.ul[3] = 0xff000000; + +#ifdef CONFIG_ATH_8327_ACL_IPV6_PASSTHROUGH + /* ACL action destination port, WAN, LAN and CPU ports */ + myacl.ports = (1 << S17_WAN_PORT) | (1 << S17_CPU_PORT) | (1 << S17_LAN_PORT0) | + (1 << S17_LAN_PORT1) | (1 << S17_LAN_PORT2) | (1 << S17_LAN_PORT3); + + FAL_FIELD_FLG_SET ( myacl.field_flg, FAL_ACL_FIELD_IP6_DIP ); +#else + /* ACL action destination port, LAN and CPU ports */ + myacl.ports = (1 << S17_CPU_PORT) | (1 << S17_LAN_PORT0) | + (1 << S17_LAN_PORT1) | (1 << S17_LAN_PORT2) | (1 << S17_LAN_PORT3); + myacl.vid_val = 0x1; + myacl.vid_mask = 0xfff; + + FAL_FIELD_FLG_SET ( myacl.field_flg, FAL_ACL_FIELD_IP6_DIP ); + FAL_FIELD_FLG_SET ( myacl.field_flg, FAL_ACL_FIELD_MAC_VID ); +#endif + + FAL_ACTION_FLG_SET ( myacl.action_flg, FAL_ACL_ACTION_REDPT ); + + rtnval = ACL_LIST_CREATE ( 0, S17_ACL_LIST_IPV6_SOLICITED_NODE, S17_ACL_LIST_PRIO_MID); + if ( rtnval != SW_OK ) + { + if(rtnval == SW_ALREADY_EXIST) + { + //aos_printk ( "ipv6_snooping_solicted rules acl list already exists.\n"); + + } else { + aos_printk ( "%s: ACL_LIST_CREATE ERROR (%d)...\n", __func__, rtnval ); + } + return; + } + + rtnval = ACL_RULE_ADD ( 0, S17_ACL_LIST_IPV6_SOLICITED_NODE, 0, 1, &myacl ); + if ( rtnval != SW_OK ) + { + aos_printk ( "%s: ACL_RULE_ADD ERROR...(%d)\n", __func__, rtnval ); + return; + } + + // ACL pattern source port +#ifdef CONFIG_ATH_8327_ACL_IPV6_PASSTHROUGH + ACL_LIST_BIND ( 0, S17_ACL_LIST_IPV6_SOLICITED_NODE, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, S17_WAN_PORT ); +#endif + ACL_LIST_BIND ( 0, S17_ACL_LIST_IPV6_SOLICITED_NODE, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, S17_CPU_PORT ); + for (i = S17_LAN_PORT0; i <= S17_LAN_PORT4; i++) { + if (i != S17_WAN_PORT) + ACL_LIST_BIND ( 0, S17_ACL_LIST_IPV6_SOLICITED_NODE, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, i); + } + + if ( ACL_STATUS_GET ( 0, &val ) == SW_OK ) + { + if ( val != A_TRUE ) + { + aos_printk ( "ACL is not yet enabled. Enabling... \n" ); + ACL_STATUS_SET(0, A_TRUE); + } + } +} + + +/* +Node Information Queries (RFC 4620 is experimental) + FF02:0:0:0:0:2:FF00::/104 => Node Information Queries +*/ +void +ipv6_snooping_nodeinfo_query_add_acl_rules ( void ) +{ + fal_acl_rule_t myacl; + uint32_t rtnval; + a_bool_t val; + int i; + + memset ( &myacl, 0, sizeof ( fal_acl_rule_t ) ); + + aos_printk("Adding ACL rules %d - %s\n", S17_ACL_LIST_IPV6_NODEINFO_QUERY, __func__); + myacl.rule_type = FAL_ACL_RULE_IP6; + myacl.dest_ip6_val.ul[0] = 0xff020000; /* FF02:0:0:0:0:2:FF00::/104 */ + myacl.dest_ip6_val.ul[1] = 0x00000000; + myacl.dest_ip6_val.ul[2] = 0x00000002; + myacl.dest_ip6_val.ul[3] = 0xff000000; + + myacl.dest_ip6_mask.ul[0] = 0xffffffff; + myacl.dest_ip6_mask.ul[1] = 0xffffffff; + myacl.dest_ip6_mask.ul[2] = 0xffffffff; + myacl.dest_ip6_mask.ul[3] = 0xff000000; + +#ifdef CONFIG_ATH_8327_ACL_IPV6_PASSTHROUGH + /* ACL action destination port, WAN, LAN and CPU ports */ + myacl.ports = (1 << S17_WAN_PORT) | (1 << S17_CPU_PORT) | (1 << S17_LAN_PORT0) | + (1 << S17_LAN_PORT1) | (1 << S17_LAN_PORT2) | (1 << S17_LAN_PORT3); + + FAL_FIELD_FLG_SET ( myacl.field_flg, FAL_ACL_FIELD_IP6_DIP ); +#else + /* ACL action destination port, LAN and CPU ports */ + myacl.ports = (1 << S17_CPU_PORT) | (1 << S17_LAN_PORT0) | + (1 << S17_LAN_PORT1) | (1 << S17_LAN_PORT2) | (1 << S17_LAN_PORT3); + myacl.vid_val = 0x1; + myacl.vid_mask = 0xfff; + + FAL_FIELD_FLG_SET ( myacl.field_flg, FAL_ACL_FIELD_IP6_DIP ); + FAL_FIELD_FLG_SET ( myacl.field_flg, FAL_ACL_FIELD_MAC_VID ); +#endif + + FAL_ACTION_FLG_SET ( myacl.action_flg, FAL_ACL_ACTION_REDPT ); + + rtnval = ACL_LIST_CREATE ( 0, S17_ACL_LIST_IPV6_NODEINFO_QUERY, S17_ACL_LIST_PRIO_MID); + if ( rtnval != SW_OK ) + { + aos_printk ( "%s: ACL_LIST_CREATE ERROR (%d)...\n", __func__, rtnval ); + return; + } + + rtnval = ACL_RULE_ADD ( 0, S17_ACL_LIST_IPV6_NODEINFO_QUERY, 0, 1, &myacl ); + if ( rtnval != SW_OK ) + { + aos_printk ( "%s: ACL_RULE_ADD ERROR...(%d)\n", __func__, rtnval ); + return; + } + + // ACL pattern source port +#ifdef CONFIG_ATH_8327_ACL_IPV6_PASSTHROUGH + ACL_LIST_BIND ( 0, S17_ACL_LIST_IPV6_NODEINFO_QUERY, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, S17_WAN_PORT ); +#endif + ACL_LIST_BIND ( 0, S17_ACL_LIST_IPV6_NODEINFO_QUERY, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, S17_CPU_PORT ); + for (i = S17_LAN_PORT0; i <= S17_LAN_PORT4; i++) { + if (i != S17_WAN_PORT) + ACL_LIST_BIND ( 0, S17_ACL_LIST_IPV6_NODEINFO_QUERY, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, i); + } + + if ( ACL_STATUS_GET ( 0, &val ) == SW_OK ) + { + if ( val != A_TRUE ) + { + aos_printk ( "ACL is not yet enabled. Enabling... \n" ); + ACL_STATUS_SET(0, A_TRUE); + } + } +} + + +/* +sextuple0_group_acl_rules contains following addresses: + FF02:0:0:0:0:0:0:1 => All Nodes Address + FF02:0:0:0:0:0:0:2 => All Routers Address + FF02:0:0:0:0:0:0:9 => RIP Routers + FF02:0:0:0:0:0:0:C => SSDP + FF02:0:0:0:0:0:0:16 => All MLDv2-capable routers + FF02:0:0:0:0:0:0:FB => mDNSv6 +*/ +void +ipv6_snooping_sextuple0_group_add_acl_rules ( void ) +{ + fal_acl_rule_t myacl; + uint32_t rtnval; + a_bool_t val; + int i; + + memset ( &myacl, 0, sizeof ( fal_acl_rule_t ) ); + + aos_printk("Adding ACL rules %d - %s\n", S17_ACL_LIST_IPV6_SEXTUPLE0_GROUP, __func__); + myacl.rule_type = FAL_ACL_RULE_IP6; + myacl.dest_ip6_val.ul[0] = 0xff020000; /* FF02::/120 */ + myacl.dest_ip6_val.ul[1] = 0x00000000; + myacl.dest_ip6_val.ul[2] = 0x00000000; + myacl.dest_ip6_val.ul[3] = 0x00000000; + + myacl.dest_ip6_mask.ul[0] = 0xffffffff; + myacl.dest_ip6_mask.ul[1] = 0xffffffff; + myacl.dest_ip6_mask.ul[2] = 0xffffffff; + myacl.dest_ip6_mask.ul[3] = 0xffffff00; + +#ifdef CONFIG_ATH_8327_ACL_IPV6_PASSTHROUGH + /* ACL action destination port, WAN, LAN and CPU ports */ + myacl.ports = (1 << S17_WAN_PORT) | (1 << S17_CPU_PORT) | (1 << S17_LAN_PORT0) | + (1 << S17_LAN_PORT1) | (1 << S17_LAN_PORT2) | (1 << S17_LAN_PORT3); + + FAL_FIELD_FLG_SET ( myacl.field_flg, FAL_ACL_FIELD_IP6_DIP ); +#else + /* ACL action destination port, LAN and CPU ports */ + myacl.ports = (1 << S17_CPU_PORT) | (1 << S17_LAN_PORT0) | + (1 << S17_LAN_PORT1) | (1 << S17_LAN_PORT2) | (1 << S17_LAN_PORT3); + myacl.vid_val = 0x1; + myacl.vid_mask = 0xfff; + + FAL_FIELD_FLG_SET ( myacl.field_flg, FAL_ACL_FIELD_IP6_DIP ); + FAL_FIELD_FLG_SET ( myacl.field_flg, FAL_ACL_FIELD_MAC_VID ); +#endif + + FAL_ACTION_FLG_SET ( myacl.action_flg, FAL_ACL_ACTION_REDPT ); + + rtnval = ACL_LIST_CREATE ( 0, S17_ACL_LIST_IPV6_SEXTUPLE0_GROUP, S17_ACL_LIST_PRIO_MID); + if ( rtnval != SW_OK ) + { + if(rtnval == SW_ALREADY_EXIST) + { + //aos_printk ( "ipv6_snooping_sextuple0 rules acl list already exists.\n"); + } else { + aos_printk ( "%s: ACL_LIST_CREATE ERROR (%d)...\n", __func__, rtnval ); + } + return; + } + rtnval = ACL_RULE_ADD ( 0, S17_ACL_LIST_IPV6_SEXTUPLE0_GROUP, 0, 1, &myacl ); + if ( rtnval != SW_OK ) + { + aos_printk ( "%s: ACL_RULE_ADD ERROR...(%d)\n", __func__, rtnval ); + return; + } + + // ACL pattern source port +#ifdef CONFIG_ATH_8327_ACL_IPV6_PASSTHROUGH + ACL_LIST_BIND ( 0, S17_ACL_LIST_IPV6_SEXTUPLE0_GROUP, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, S17_WAN_PORT ); +#endif + ACL_LIST_BIND ( 0, S17_ACL_LIST_IPV6_SEXTUPLE0_GROUP, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, S17_CPU_PORT ); + for (i = S17_LAN_PORT0; i <= S17_LAN_PORT4; i++) { + if (i != S17_WAN_PORT) + ACL_LIST_BIND ( 0, S17_ACL_LIST_IPV6_SEXTUPLE0_GROUP, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, i ); + } + + if ( ACL_STATUS_GET ( 0, &val ) == SW_OK ) + { + if ( val != A_TRUE ) + { + aos_printk ( "ACL is not yet enabled. Enabling... \n" ); + ACL_STATUS_SET(0, A_TRUE); + } + } +} + + +/* +quintruple0_1_group_acl_rules contains following addresses: + FF02:0:0:0:0:0:1:2 => All-dhcp-agents + FF02:0:0:0:0:0:1:3 => LLMNR +*/ +void +ipv6_snooping_quintruple0_1_group_add_acl_rules ( void ) +{ + fal_acl_rule_t myacl; + uint32_t rtnval; + a_bool_t val; + int i; + + memset ( &myacl, 0, sizeof ( fal_acl_rule_t ) ); + + aos_printk("Adding ACL rules %d - %s\n", S17_ACL_LIST_IPV6_QUINTRUPLE0_1_GROUP, __func__); + myacl.rule_type = FAL_ACL_RULE_IP6; + myacl.dest_ip6_val.ul[0] = 0xff020000; /* FF02:0:0:0:0:0:1::/125 */ + myacl.dest_ip6_val.ul[1] = 0x00000000; + myacl.dest_ip6_val.ul[2] = 0x00000000; + myacl.dest_ip6_val.ul[3] = 0x00010000; + + myacl.dest_ip6_mask.ul[0] = 0xffffffff; + myacl.dest_ip6_mask.ul[1] = 0xffffffff; + myacl.dest_ip6_mask.ul[2] = 0xffffffff; + myacl.dest_ip6_mask.ul[3] = 0xfffffff8; + +#ifdef CONFIG_ATH_8327_ACL_IPV6_PASSTHROUGH + myacl.ports = (1 << S17_WAN_PORT) | (1 << S17_CPU_PORT) | (1 << S17_LAN_PORT0) | + (1 << S17_LAN_PORT1) | (1 << S17_LAN_PORT2) | (1 << S17_LAN_PORT3); + + FAL_FIELD_FLG_SET ( myacl.field_flg, FAL_ACL_FIELD_IP6_DIP ); +#else + /* ACL action destination port, LAN and CPU ports */ + myacl.ports = (1 << S17_CPU_PORT) | (1 << S17_LAN_PORT0) | + (1 << S17_LAN_PORT1) | (1 << S17_LAN_PORT2) | (1 << S17_LAN_PORT3); + myacl.vid_val = 0x1; + myacl.vid_mask = 0xfff; + + FAL_FIELD_FLG_SET ( myacl.field_flg, FAL_ACL_FIELD_IP6_DIP ); + FAL_FIELD_FLG_SET ( myacl.field_flg, FAL_ACL_FIELD_MAC_VID ); +#endif + + FAL_ACTION_FLG_SET ( myacl.action_flg, FAL_ACL_ACTION_REDPT ); + + rtnval = ACL_LIST_CREATE ( 0, S17_ACL_LIST_IPV6_QUINTRUPLE0_1_GROUP, S17_ACL_LIST_PRIO_MID); + if ( rtnval != SW_OK ) + { + if(rtnval == SW_ALREADY_EXIST) + { + //aos_printk ( "ipv6_snooping_quintruple0 rules acl list already exists.\n"); + } else { + aos_printk ( "%s: ACL_LIST_CREATE ERROR (%d)...\n", __func__, rtnval ); + } + return; + } + rtnval = ACL_RULE_ADD ( 0, S17_ACL_LIST_IPV6_QUINTRUPLE0_1_GROUP, 0, 1, &myacl ); + if ( rtnval != SW_OK ) + { + aos_printk ( "%s: ACL_RULE_ADD ERROR...(%d)\n", __func__, rtnval ); + return; + } + + /* ACL pattern soruce port */ +#ifdef CONFIG_ATH_8327_ACL_IPV6_PASSTHROUGH + ACL_LIST_BIND ( 0, S17_ACL_LIST_IPV6_QUINTRUPLE0_1_GROUP, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, S17_WAN_PORT ); +#endif + ACL_LIST_BIND ( 0, S17_ACL_LIST_IPV6_QUINTRUPLE0_1_GROUP, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, S17_CPU_PORT ); + for (i = S17_LAN_PORT0; i <= S17_LAN_PORT4; i++) { + if (i != S17_WAN_PORT) + ACL_LIST_BIND ( 0, S17_ACL_LIST_IPV6_QUINTRUPLE0_1_GROUP, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, i ); + } + + if ( ACL_STATUS_GET ( 0, &val ) == SW_OK ) + { + if ( val != A_TRUE ) + { + aos_printk ( "ACL is not yet enabled. Enabling... \n" ); + ACL_STATUS_SET(0, A_TRUE); + } + } +} + +/* +When HW IGMPSNOOPING Enabled, we need to let UPnP SSDP Multicast packets send to lan +*/ +void upnp_ssdp_add_acl_rules(void) +{ + fal_acl_rule_t myacl; + uint32_t rtnval; + a_bool_t val; + int i; + + aos_printk("Adding ACL rules %d - %s\n", S17_ACL_LIST_UPNP_SSDP, __func__); + memset ( &myacl, 0, sizeof ( fal_acl_rule_t ) ); + + myacl.rule_type = FAL_ACL_RULE_IP4; + myacl.dest_ip4_val = 0xeffffffa; // 239.255.255.250 + myacl.dest_ip4_mask = 0xffffffff; + /* ACL action destination port, LAN and CPU ports */ + myacl.ports = (1 << S17_CPU_PORT) | (1 << S17_LAN_PORT0) | + (1 << S17_LAN_PORT1) | (1 << S17_LAN_PORT2) | (1 << S17_LAN_PORT3); + + FAL_FIELD_FLG_SET ( myacl.field_flg, FAL_ACL_FIELD_IP4_DIP ); + FAL_ACTION_FLG_SET ( myacl.action_flg, FAL_ACL_ACTION_REDPT ); + + rtnval = ACL_LIST_CREATE ( 0, S17_ACL_LIST_UPNP_SSDP, S17_ACL_LIST_PRIO_MID); + if ( rtnval != SW_OK ) + { + if(rtnval == SW_ALREADY_EXIST) + { + //aos_printk ( "upnp_ssdp rules acl list already exists.\n"); + } else { + aos_printk ( "upnp_ssdp_acl_rules: ACL_LIST_CREATE ERROR (%d)...\n",rtnval ); + } + return ; + } + + rtnval = ACL_RULE_ADD ( 0, S17_ACL_LIST_UPNP_SSDP, 0, 1, &myacl ); + if ( rtnval != SW_OK ) + { + aos_printk ( "upnp_ssdp_acl_rules: ACL_RULE_ADD ERROR...(%d)\n" ,rtnval ); + return ; + } + + // Pattern source port + ACL_LIST_BIND ( 0, S17_ACL_LIST_UPNP_SSDP, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, S17_CPU_PORT ); + for (i = S17_LAN_PORT0; i <= S17_LAN_PORT4; i++) { + if (i != S17_WAN_PORT) + ACL_LIST_BIND ( 0, S17_ACL_LIST_UPNP_SSDP, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, i ); + } + + if (ACL_STATUS_GET(0, &val) == SW_OK) + { + if (val != A_TRUE) + { + aos_printk("ACL is not yet enabled. Enabling... \n"); + ACL_STATUS_SET(0, A_TRUE); + } + } +} + +void filter_power_cord_acl_rules(void) +{ + fal_acl_rule_t myacl; + uint32_t rtnval; + a_bool_t val; + + aos_printk("Adding ACL rules %d - %s\n", S17_ACL_LIST_PLC_FILTER, __func__); + + memset ( &myacl, 0, sizeof ( fal_acl_rule_t ) ); + myacl.rule_type = FAL_ACL_RULE_MAC; + + myacl.ethtype_val = 0x88e1; + myacl.ethtype_mask = 0xffff; + + /* ACL action destination port PLC port */ + myacl.ports = (1 << S17_CPU_PORT) | (1 << 6); + + /* Set pattern type*/ + memset ( &myacl.field_flg, 0, sizeof ( myacl.field_flg ) ); + FAL_FIELD_FLG_SET ( myacl.field_flg, FAL_ACL_FIELD_MAC_ETHTYPE ); // set ethtype as pattern + + /* Set action type*/ + memset ( &myacl.action_flg, 0, sizeof ( myacl.action_flg ) ); + FAL_ACTION_FLG_SET ( myacl.action_flg, FAL_ACL_ACTION_REDPT); // set action as DENY, FAL_ACL_ACTION_DENY + + /* + memcpy ( myacl.dest_mac_val.uc, mac, 6 ); + memcpy ( myacl.dest_mac_mask.uc, mac_mask, 6 ); + FAL_FIELD_FLG_SET ( myacl.field_flg, FAL_ACL_FIELD_MAC_DA ); + */ + + rtnval = ACL_LIST_CREATE (0, S17_ACL_LIST_PLC_FILTER, S17_ACL_LIST_PRIO_HIGH); + if(rtnval != SW_OK) + { + aos_printk ( "filter_power_cord_acl_rules: ACL_LIST_CREATE ERROR (%d)\n",rtnval ); + return; + } + + rtnval = ACL_RULE_ADD ( 0, S17_ACL_LIST_PLC_FILTER, 0, 1, &myacl ); + if ( rtnval != SW_OK ) + { + aos_printk ( "filter_power_cord_acl_rules: ACL_RULE_ADD ERROR...(%d)\n", rtnval ); + return; + } + + // ACL pattern source port + ACL_LIST_BIND ( 0, S17_ACL_LIST_PLC_FILTER, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, S17_CPU_PORT); + ACL_LIST_BIND ( 0, S17_ACL_LIST_PLC_FILTER, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, 6); + + if ( ACL_STATUS_GET ( 0, &val ) == SW_OK ) + { + if ( val != A_TRUE ) + { + aos_printk ( "ACL is not yet enabled. Enabling... \n" ); + ACL_STATUS_SET ( 0, A_TRUE ); + } + } +} + +/* enable pppoe_passthrough by default */ +static int isis_pppoe_passthrough = 0; + +unsigned int isis_pppoe_passthrough_process(struct sk_buff *skb, aos_header_t *athr_header) +{ + unsigned char *smac = &skb->data[6]; + + if ( isis_pppoe_passthrough == 0 ) + return -1; + + if ( ( ( skb->data[20] == 0x88 && ( skb->data[21] == 0x63 ) ) || ( skb->data[16] == 0x88 && ( skb->data[17] == 0x63 ) ) ) + && ( athr_header->sport != S17_WAN_PORT ) ) + { + pppoe_passthrough_acl_rules ( 0, smac ); + } + + return 0; +} + +unsigned int isis_set_pppoe_passthrough ( int enable ) +{ + if ( enable ) + isis_pppoe_passthrough = 1; + else + isis_pppoe_passthrough = 0; + + printk ( "## isis_set_pppoe_passthrough %s !\n", enable != 0 ? "enabled" : "disabled" ); + + return 0; +} + +unsigned int isis_enable_pppoe_discovery_acl(void) +{ +#if 0 + printk ( "## isis_enable_pppoe_discovery_acl !\n"); + + athrs17_reg_write ( MOD_ENABLE_OFFSET, athrs17_reg_read ( MOD_ENABLE_OFFSET ) | ( 1 << MOD_ENABLE_ACL_EN_BOFFSET ) ); + printk ( "athrs17_reg_write(MOD_ENABLE_OFFSET) = 0x%08x\n", athrs17_reg_read ( MOD_ENABLE_OFFSET ) ); +#endif + return 0; +} + + +int pppoe_passthrough_acl_rules(uint32_t gw_entry_id, unsigned char *mac) +{ + fal_acl_rule_t myacl; + uint32_t rtnval; + a_bool_t val; + uint32_t rule_list_id; + unsigned char mac_mask[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + int i; + + if (isis_pppoe_passthrough > MAX_PPPOE_PASSTHROUGH_NUM) + { + aos_printk("Support %d PPPoE passthrough hosts only... \n", MAX_PPPOE_PASSTHROUGH_NUM); + return -1; + } + + { + /* lan -> wan, pppoe discovery */ + rule_list_id = S17_ACL_LIST_PPPOE_PASSTHROUGH_LAN_TO_WAN + (isis_pppoe_passthrough - 1) * 2; + printk ( "creating ACL list_id: %d \n", rule_list_id ); + + memset ( &myacl, 0, sizeof ( fal_acl_rule_t ) ); + myacl.rule_type = FAL_ACL_RULE_MAC; + memcpy ( myacl.src_mac_val.uc, mac, 6 ); + memcpy ( myacl.src_mac_mask.uc, mac_mask, 6 ); + myacl.ethtype_val = 0x8863; + myacl.ethtype_mask = 0xffff; + + myacl.ports = (1 << S17_WAN_PORT); + + memset ( &myacl.field_flg, 0, sizeof ( myacl.field_flg ) ); + + FAL_FIELD_FLG_SET ( myacl.field_flg, FAL_ACL_FIELD_MAC_SA ); + FAL_FIELD_FLG_SET ( myacl.field_flg, FAL_ACL_FIELD_MAC_ETHTYPE ); + + memset ( &myacl.action_flg, 0, sizeof ( myacl.action_flg ) ); + + FAL_ACTION_FLG_SET ( myacl.action_flg, FAL_ACL_ACTION_REDPT ); + + rtnval = ACL_LIST_CREATE (0, rule_list_id, S17_ACL_LIST_PRIO_MID); + if ( rtnval != SW_OK ) + { + aos_printk ( "pppoe_passthrough_acl_rules: ACL_LIST_CREATE ERROR (%d)\n",rtnval ); + return -1; + } + + rtnval = ACL_RULE_ADD ( 0, rule_list_id, 0, 1, &myacl ); + if ( rtnval != SW_OK ) + { + aos_printk ( "pppoe_passthrough_acl_rules: ACL_RULE_ADD ERROR...(%d)\n", rtnval ); + return -1; + } + + for (i = S17_LAN_PORT0; i <= S17_LAN_PORT4; i++) { + if (i != S17_WAN_PORT) + ACL_LIST_BIND ( 0, rule_list_id, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, i); + } + + } + + { + /* lan -> wan, pppoe session */ + rule_list_id = S17_ACL_LIST_PPPOE_PASSTHROUGH_LAN_TO_WAN + (isis_pppoe_passthrough - 1) * 2 + 1; + + printk ( "creating ACL list_id: %d \n", rule_list_id ); + + memset ( &myacl, 0, sizeof ( fal_acl_rule_t ) ); + myacl.rule_type = FAL_ACL_RULE_MAC; + memcpy ( myacl.src_mac_val.uc, mac, 6 ); + memcpy ( myacl.src_mac_mask.uc, mac_mask, 6 ); + + myacl.ethtype_val = 0x8864; + myacl.ethtype_mask = 0xffff; + + myacl.ports = ( 1< +#include +#else +#include +#endif +#include +#include +#include +#ifdef KVER32 +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include "nat_helper.h" +#include "napt_acl.h" + +#include "lib/nat_helper_hsl.h" + +extern struct net init_net; +static struct task_struct *ct_task; + +/*#undef HNAT_PRINTK +#define HNAT_PRINTK(x...) aos_printk(x)*/ + +#ifdef KVER32 +extern void __rcu_read_lock(void); +extern void __rcu_read_unlock(void); +extern unsigned int nf_conntrack_htable_size; +#endif + +a_bool_t napt_aging_ctrl_en = 0; + +void +napt_ct_aging_disable(uint32_t ct_addr) +{ + struct nf_conn *ct = NULL; + if(nf_athrs17_hnat_sync_counter_en || !napt_aging_ctrl_en) + return; + + if(!ct_addr) + { + return; + } + + ct = (struct nf_conn *)ct_addr; + + if (timer_pending(&ct->timeout)) + { + del_timer(&ct->timeout); + } +} + +int +napt_ct_aging_is_enable(uint32_t ct_addr) +{ + struct nf_conn *ct = NULL; + if(!ct_addr) + { + return 0; + } + + if(nf_athrs17_hnat_sync_counter_en || !napt_aging_ctrl_en) + return 0; + + ct = (struct nf_conn *)ct_addr; + + return timer_pending(&(((struct nf_conn *)ct)->timeout)); +} + +void +napt_ct_aging_enable(uint32_t ct_addr) +{ + struct nf_conn *ct = NULL; + uint16_t l3num = 0; + uint8_t protonum = 0; + if(nf_athrs17_hnat_sync_counter_en || !napt_aging_ctrl_en) + return; + + if(!ct_addr) + { + return; + } + + if(napt_ct_aging_is_enable(ct_addr)) + { + return; + } + + ct = (struct nf_conn *)ct_addr; + l3num = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num; + protonum = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum; + + ct->timeout.expires = jiffies+10*HZ; + + if ((l3num == AF_INET) && (protonum == IPPROTO_TCP)) + { + if (ct->proto.tcp.state == TCP_CONNTRACK_ESTABLISHED) + { + ct->timeout.expires = jiffies+(5*24*60*60*HZ); + } + } + + HNAT_PRINTK(" ct:[%x] add timeout again\n", ct_addr); + add_timer(&ct->timeout); +} + +void +napt_ct_to_hw_entry(uint32_t ct_addr, napt_entry_t *napt) +{ + struct nf_conn *ct = NULL; + struct nf_conntrack_tuple *org_tuple, *rep_tuple; + uint8_t protonum = 0; + + if(!ct_addr) + { + return; + } + +#define NAPT_AGE 0xe + + ct = (struct nf_conn *)ct_addr; + + if ((ct->status & IPS_NAT_MASK) == IPS_SRC_NAT) //snat + { + org_tuple = &(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); + rep_tuple = &(ct->tuplehash[IP_CT_DIR_REPLY].tuple); + + } + else //dnat + { + org_tuple = &(ct->tuplehash[IP_CT_DIR_REPLY].tuple); + rep_tuple = &(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); + } + + protonum = org_tuple->dst.protonum; + + if(org_tuple->src.l3num == AF_INET) + { + if(protonum == IPPROTO_TCP) + { + napt->flags = FAL_NAT_ENTRY_PROTOCOL_TCP; + + } + else if(protonum == IPPROTO_UDP) + { + napt->flags = FAL_NAT_ENTRY_PROTOCOL_UDP; + + } + } + + napt->src_addr = ntohl(org_tuple->src.u3.ip); + napt->src_port = ntohs(org_tuple->src.u.all); + napt->dst_addr = ntohl(org_tuple->dst.u3.ip); + napt->dst_port = ntohs(org_tuple->dst.u.all); + napt->trans_addr = ntohl(rep_tuple->dst.u3.ip); + napt->trans_port = ntohs(rep_tuple->dst.u.all); + napt->status = NAPT_AGE; + + return; +} + +uint64_t +napt_ct_pkts_get(uint32_t ct_addr) +{ + struct nf_conn *ct = NULL; + struct nf_conn_counter *cct = NULL; + if(!ct_addr) + { + return 0; + } + + ct = (struct nf_conn *)ct_addr; + cct = (struct nf_conn_counter *)nf_conn_acct_find(ct); + + if(cct) + { + return (atomic64_read(&cct[IP_CT_DIR_ORIGINAL].packets) + + atomic64_read(&cct[IP_CT_DIR_REPLY].packets)); + } + else + { + return 0; + } +} + +int +napt_ct_type_is_nat(uint32_t ct_addr) +{ + struct nf_conn *ct = NULL; + if(!ct_addr) + { + return 0; + } + + ct = (struct nf_conn *)ct_addr; + + return ((IPS_NAT_MASK & (ct)->status)?1:0); +} + +int +napt_ct_type_is_nat_alg(uint32_t ct_addr) +{ + struct nf_conn *ct = NULL; + if(!ct_addr) + { + return 0; + } + ct = (struct nf_conn *)ct_addr; + return ((nfct_help(ct))?1:0); +} + +int +napt_ct_intf_is_expected(uint32_t ct_addr) +{ + struct nf_conn *ct = (struct nf_conn *)ct_addr; + struct nf_conntrack_tuple *rep_tuple; + uint32_t dst_ip; + struct net_device *dev = NULL; + + if(!ct_addr) + { + return 0; + } + + if ((ct->status & IPS_NAT_MASK) == IPS_SRC_NAT) + rep_tuple = &(ct->tuplehash[IP_CT_DIR_REPLY].tuple); + else + rep_tuple = &(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); + dst_ip = rep_tuple->dst.u3.ip; + dev = ip_dev_find(&init_net, dst_ip); + if(dev) { + if(dev->type == ARPHRD_ETHER) { + if(strstr(dev->name, "eth0") || strstr(dev->name, "erouter0") || + strstr(dev->name, "br-wan")) { + dev_put(dev); + return 1; + } + } else if (dev->type == ARPHRD_PPP) { + dev_put(dev); + return 1; + } + dev_put(dev); + } + + return 0; +} + +int +napt_ct_status_is_estab(uint32_t ct_addr) +{ + struct nf_conn *ct = NULL; + uint16_t l3num = 0; + uint8_t protonum = 0; + + if(!ct_addr) + { + return 0; + } + + ct = (struct nf_conn *)ct_addr; + l3num = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num; + protonum = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum; + + if ((l3num == AF_INET) && (protonum == IPPROTO_TCP)) + { + if (ct->proto.tcp.state == TCP_CONNTRACK_ESTABLISHED) + { + return 1; + } + } + else if ((l3num == AF_INET) && (protonum == IPPROTO_UDP)) + { + return 1; + } + + return 0; +} + +uint32_t +napt_ct_priv_ip_get(uint32_t ct_addr) +{ + struct nf_conn *ct = NULL; + uint32_t usaddr = 0; + + if(!ct_addr) + { + return 0; + } + + ct = (struct nf_conn *)ct_addr; + + if ((ct->status & IPS_NAT_MASK) == IPS_SRC_NAT) //snat + { + usaddr = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip; + } + else + { + usaddr = ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip; + } + + usaddr = ntohl(usaddr); + + return usaddr; +} + +void +napt_ct_list_lock(void) +{ + rcu_read_lock(); +} + +void +napt_ct_list_unlock(void) +{ + rcu_read_unlock(); +} + +uint32_t +napt_ct_list_iterate(uint32_t *hash, uint32_t *iterate) +{ + struct net *net = &init_net; + struct nf_conntrack_tuple_hash *h = NULL; + struct nf_conn *ct = NULL; + struct hlist_nulls_node *pos = (struct hlist_nulls_node *) (*iterate); + + while(*hash < nf_conntrack_htable_size) + { + if(pos == 0) + { + /*get head for list*/ + pos = rcu_dereference((&net->ct.hash[*hash])->first); + } + + hlist_nulls_for_each_entry_from(h, pos, hnnode) + { + (*iterate) = (uint32_t)(pos->next); + ct = nf_ct_tuplehash_to_ctrack(h); + return (uint32_t) ct; + } + + ++(*hash); + pos = 0; + } + + *hash = 0; + return 0; +} + +int +napt_ct_task_should_stop(void) +{ + return kthread_should_stop(); +} + +void +napt_ct_task_start(int (*task)(void*), const char *task_name) +{ + ct_task = kthread_create(task, NULL, task_name); + + if(IS_ERR(ct_task)) + { + aos_printk("thread: %s create fail\n", task_name); + return; + } + + wake_up_process(ct_task); + + HNAT_PRINTK("thread: %s create success pid:%d\n", + task_name, ct_task->pid); +} + +void +napt_ct_task_stop(void) +{ + if(ct_task) + { + kthread_stop(ct_task); + } +} + +void +napt_ct_task_sleep(int secs) +{ + msleep_interruptible(secs*1000); +} diff --git a/feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/napt_helper.h b/feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/napt_helper.h new file mode 100755 index 000000000..4cd21a90b --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/napt_helper.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2012, 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. + */ + + +#ifndef _NAPT_HELPER_H +#define _NAPT_HELPER_H + + + +#define USING_LINUX2631 1 + +#ifdef USING_LINUX2631 + +void +napt_ct_task_start(int (*task)(void*), const char *task_name); +void +napt_ct_task_stop(void); +int +napt_ct_task_should_stop(void); +void +napt_ct_task_sleep(int secs); +void +napt_ct_list_lock(void); +void +napt_ct_list_unlock(void); +uint32_t +napt_ct_list_iterate(uint32_t *hash, uint32_t *pos) ; +void +napt_ct_to_hw_entry(uint32_t ct_addr, void *napt); +void +napt_ct_aging_enable(uint32_t ct_addr); +void +napt_ct_aging_disable(uint32_t ct_addr); +int +napt_ct_aging_is_enable(uint32_t ct_addr); +uint64_t +napt_ct_pkts_get(uint32_t ct_addr); +int +napt_ct_type_is_nat(uint32_t ct_addr); +int +napt_ct_type_is_nat_alg(uint32_t ct_addr); +int +napt_ct_status_is_estab(uint32_t ct_addr); +uint32_t +napt_ct_priv_ip_get(uint32_t ct_addr); +int +napt_ct_intf_is_expected(uint32_t ct_addr); + + + +#define NAPT_CT_TASK_START napt_ct_task_start +#define NAPT_CT_TASK_STOP napt_ct_task_stop +#define NAPT_CT_TASK_SHOULD_STOP napt_ct_task_should_stop +#define NAPT_CT_TASK_SLEEP napt_ct_task_sleep + +#define NAPT_CT_LIST_LOCK napt_ct_list_lock +#define NAPT_CT_LIST_UNLOCK napt_ct_list_unlock +#define NAPT_CT_LIST_ITERATE napt_ct_list_iterate + +#define NAPT_CT_AGING_IS_ENABLE napt_ct_aging_is_enable +#define NAPT_CT_AGING_ENABLE napt_ct_aging_enable +#define NAPT_CT_AGING_DISABLE napt_ct_aging_disable + +#define NAPT_CT_TYPE_IS_NAT napt_ct_type_is_nat +#define NAPT_CT_STATUS_IS_ESTAB napt_ct_status_is_estab +#define NAPT_CT_PRIV_IP_GET napt_ct_priv_ip_get +#define NAPT_CT_PKTS_GET napt_ct_pkts_get +#define NAPT_CT_TO_HW_ENTRY napt_ct_to_hw_entry +#define NAPT_CT_TYPE_IS_NAT_ALG napt_ct_type_is_nat_alg +#define NAPT_CT_INTF_EXPECTED napt_ct_intf_is_expected + + +#else + + + +#endif + + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/napt_procfs.c b/feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/napt_procfs.c new file mode 100755 index 000000000..4f5a66482 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/napt_procfs.c @@ -0,0 +1,1316 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * napt_procfs.c - create files in /proc + * + */ +#include +#ifdef KVER32 +#include +#else +#include +#include +#endif +#include +#include +#include +#include +#include /* for copy_from_user */ +#include "aos_types.h" + +#ifdef AUTO_UPDATE_PPPOE_INFO +#define NF_PROCFS_PERM 0444 +#else +#define NF_PROCFS_PERM 0644 +#endif + +#define ATHRS17_MAC_LEN 13 // 12+1 +#define ATHRS17_IP_LEN 9 // 8+1 +#define ATHRS17_CHAR_MAX_LEN ATHRS17_MAC_LEN + +#define NF_PROCFS_DIR "qca_switch" + +#define NF_ATHRS17_HNAT_NAME "nf_athrs17_hnat" +#define NF_ATHRS17_HNAT_WAN_TYPE_NAME "nf_athrs17_hnat_wan_type" +#define NF_ATHRS17_HNAT_PPP_ID_NAME "nf_athrs17_hnat_ppp_id" +#define NF_ATHRS17_HNAT_UDP_THRESH_NAME "nf_athrs17_hnat_udp_thresh" +#define NF_ATHRS17_HNAT_WAN_IP_NAME "nf_athrs17_hnat_wan_ip" +#define NF_ATHRS17_HNAT_PPP_PEER_IP_NAME "nf_athrs17_hnat_ppp_peer_ip" +#define NF_ATHRS17_HNAT_PPP_PEER_MAC_NAME "nf_athrs17_hnat_ppp_peer_mac" +#define NF_ATHRS17_HNAT_WAN_MAC_NAME "nf_athrs17_hnat_wan_mac" + +#define NF_ATHRS17_HNAT_PPP_ID2_NAME "nf_athrs17_hnat_ppp_id2" +#define NF_ATHRS17_HNAT_PPP_PEER_MAC2_NAME "nf_athrs17_hnat_ppp_peer_mac2" + +/* for PPPoE */ +int nf_athrs17_hnat = 1; +int nf_athrs17_hnat_wan_type = 0; +int nf_athrs17_hnat_ppp_id = 0; +int nf_athrs17_hnat_udp_thresh = 0; +a_uint32_t nf_athrs17_hnat_wan_ip = 0; +a_uint32_t nf_athrs17_hnat_ppp_peer_ip = 0; +unsigned char nf_athrs17_hnat_ppp_peer_mac[ETH_ALEN] = {0}; +unsigned char nf_athrs17_hnat_wan_mac[ETH_ALEN] = {0}; +extern int nf_athrs17_hnat_sync_counter_en; +extern char hnat_log_en; +extern int scan_period; +extern int scan_enable; +extern int napt_need_clean; +extern int wan_switch; +extern char nat_wan_port; +extern a_uint32_t packet_thres_base; +extern a_uint32_t polling_quota; +extern a_bool_t napt_add_bypass_check; +extern void napt_wan_switch_prehandle(void); +/* for IPv6 over PPPoE (only for S17c)*/ +int nf_athrs17_hnat_ppp_id2 = 0; +unsigned char nf_athrs17_hnat_ppp_peer_mac2[ETH_ALEN] = {0}; + +#if 0 +static void setup_proc_entry(void) +{ + nf_athrs17_hnat = 1; + nf_athrs17_hnat_wan_type = 0; + nf_athrs17_hnat_ppp_id = 0; + memset(&nf_athrs17_hnat_ppp_peer_mac, 0, ETH_ALEN); + memset(&nf_athrs17_hnat_wan_mac, 0, ETH_ALEN); + nf_athrs17_hnat_ppp_peer_ip = 0; + nf_athrs17_hnat_wan_ip = 0; + + nf_athrs17_hnat_ppp_id2 = 0; + memset(&nf_athrs17_hnat_ppp_peer_mac2, 0, ETH_ALEN); + nf_athrs17_hnat_sync_counter_en = 0; +} + +/** + * This structure hold information about the /proc file + * + */ +static struct proc_dir_entry *qca_switch_dir; + +static struct proc_dir_entry *nf_athrs17_hnat_file; +static struct proc_dir_entry *nf_athrs17_hnat_wan_type_file; +static struct proc_dir_entry *nf_athrs17_hnat_ppp_id_file; +static struct proc_dir_entry *nf_athrs17_hnat_udp_thresh_file; +static struct proc_dir_entry *nf_athrs17_hnat_wan_ip_file; +static struct proc_dir_entry *nf_athrs17_hnat_ppp_peer_ip_file; +static struct proc_dir_entry *nf_athrs17_hnat_ppp_peer_mac_file; +static struct proc_dir_entry *nf_athrs17_hnat_wan_mac_file; + +static struct proc_dir_entry *nf_athrs17_hnat_ppp_id2_file; +static struct proc_dir_entry *nf_athrs17_hnat_ppp_peer_mac2_file; + +/** + * This function is called then the /proc file is read + * + */ +static int procfile_read_int(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int ret; + int *prv_data = (int *)data; + + ret = snprintf(page, sizeof(int), "%d\n", *prv_data); + + return ret; +} + +static int procfile_read_ip(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int ret; + unsigned char *prv_data = (unsigned char *)data; + + ret = snprintf(page, sizeof(a_uint32_t), "%d.%d.%d.%d\n", prv_data[0], prv_data[1], prv_data[2], prv_data[3]); + + return ret; +} + +static int procfile_read_mac(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int ret; + unsigned char *prv_data = (unsigned char *)data; + unsigned long long *ptr_ull; + + ret = snprintf(page, sizeof(unsigned char)*ETH_ALEN, "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x\n", + prv_data[0], prv_data[1], prv_data[2], prv_data[3], prv_data[4], prv_data[5]); + + ptr_ull = (unsigned long long *)prv_data; + + return ret; +} + +/** + * This function is called with the /proc file is written + * + */ +#ifdef AUTO_UPDATE_PPPOE_INFO +#define procfile_write_int NULL +#define procfile_write_ip NULL +#define procfile_write_mac NULL +#else +static int procfile_write_int(struct file *file, const char *buffer, unsigned long count, void *data) +{ + int len; + uint8_t tmp_buf[9] = {'0', '0', '0', '0', '0', '0', '0', '0', '0'}; + unsigned int *prv_data = (unsigned int *)data; + int res = 0; + + if(count > sizeof(tmp_buf)) + len = sizeof(tmp_buf); + else + len = count; + + if(copy_from_user(tmp_buf, buffer, len)) + return -EFAULT; + + tmp_buf[len-1] = '\0'; + res = kstrtol((const char *)tmp_buf, 10, prv_data); + if(res < 0) + return res; + + // printk("[write] prv_data 0x%p -> 0x%08x\n", prv_data, *prv_data); + + return len; +} + +static int procfile_write_ip(struct file *file, const char *buffer, unsigned long count, void *data) +{ + int ret; + int len; + unsigned char tmp_buf[ATHRS17_IP_LEN]; + unsigned long *prv_data = (unsigned long *)data; + int res = 0; + + if(count > ATHRS17_IP_LEN) + len = ATHRS17_IP_LEN; + else + len = count; + + if(copy_from_user(tmp_buf, buffer, len)) + return -EFAULT; + + tmp_buf[len-1] = '\0'; + + res = kstrtol((const char *)tmp_buf, 16, prv_data); + if(res < 0) + return res; + + return ret; +} + +static int procfile_write_mac(struct file *file, const char *buffer, unsigned long count, void *data) +{ + int ret; + int len; + unsigned char tmp_buf[ATHRS17_MAC_LEN]; + unsigned char *ptr_char; + unsigned long long *prv_data = (unsigned long long *)data; + int res = 0; + + if(count > ATHRS17_MAC_LEN) + len = ATHRS17_MAC_LEN; + else + len = count; + + if(copy_from_user((void *)tmp_buf, buffer, len)) + return -EFAULT; + + tmp_buf[len-1] = 't'; + + res = kstrtoll((const char *)tmp_buf, 16, prv_data); + if(res < 0) + return res; + *prv_data = cpu_to_be64p(prv_data); + ptr_char = (unsigned char *)prv_data; + ptr_char[0] = ptr_char[2]; + ptr_char[1] = ptr_char[3]; + ptr_char[2] = ptr_char[4]; + ptr_char[3] = ptr_char[5]; + ptr_char[4] = ptr_char[6]; + ptr_char[5] = ptr_char[7]; + + return ret; +} +#endif // ifdef AUTO_UPDATE_PPPOE_INFO + + +int napt_procfs_init(void) +{ + int ret = 0; + + setup_proc_entry(); + + /* create directory */ + qca_switch_dir = proc_mkdir(NF_PROCFS_DIR, NULL); + if(qca_switch_dir == NULL) + { + ret = -ENOMEM; + goto err_out; + } + + /* create the /proc file */ + nf_athrs17_hnat_file = create_proc_entry(NF_ATHRS17_HNAT_NAME, 0644, qca_switch_dir); + if (NULL == nf_athrs17_hnat_file) + { + printk("Error: Can not create /proc/%s/%s\n", NF_PROCFS_DIR, NF_ATHRS17_HNAT_NAME); + goto no_athrs17_hnat; + } + nf_athrs17_hnat_file->data = &nf_athrs17_hnat; + nf_athrs17_hnat_file->read_proc = procfile_read_int; + nf_athrs17_hnat_file->write_proc = procfile_write_int; + printk("/proc/%s/%s is created\n", NF_PROCFS_DIR, NF_ATHRS17_HNAT_NAME); + + nf_athrs17_hnat_wan_type_file = create_proc_entry(NF_ATHRS17_HNAT_WAN_TYPE_NAME, NF_PROCFS_PERM, qca_switch_dir); + if (NULL == nf_athrs17_hnat_wan_type_file) + { + printk("Error: Can not create /proc/%s/%s\n", NF_PROCFS_DIR, NF_ATHRS17_HNAT_WAN_TYPE_NAME); + goto no_athrs17_hnat_wan_type; + } + nf_athrs17_hnat_wan_type_file->data = &nf_athrs17_hnat_wan_type; + nf_athrs17_hnat_wan_type_file->read_proc = procfile_read_int; + nf_athrs17_hnat_wan_type_file->write_proc = procfile_write_int; + printk("/proc/%s/%s is created\n", NF_PROCFS_DIR, NF_ATHRS17_HNAT_WAN_TYPE_NAME); + + nf_athrs17_hnat_ppp_id_file = create_proc_entry(NF_ATHRS17_HNAT_PPP_ID_NAME, NF_PROCFS_PERM, qca_switch_dir); + if (NULL == nf_athrs17_hnat_ppp_id_file) + { + printk("Error: Can not create /proc/%s/%s\n", NF_PROCFS_DIR, NF_ATHRS17_HNAT_PPP_ID_NAME); + goto no_athrs17_hnat_ppp_id; + } + nf_athrs17_hnat_ppp_id_file->data = &nf_athrs17_hnat_ppp_id; + nf_athrs17_hnat_ppp_id_file->read_proc = procfile_read_int; + nf_athrs17_hnat_ppp_id_file->write_proc = procfile_write_int; + printk("/proc/%s/%s is created\n", NF_PROCFS_DIR, NF_ATHRS17_HNAT_PPP_ID_NAME); + + nf_athrs17_hnat_udp_thresh_file = create_proc_entry(NF_ATHRS17_HNAT_UDP_THRESH_NAME, NF_PROCFS_PERM, qca_switch_dir); + if (NULL == nf_athrs17_hnat_udp_thresh_file) + { + printk("Error: Can not create /proc/%s/%s\n", NF_PROCFS_DIR, NF_ATHRS17_HNAT_UDP_THRESH_NAME); + goto no_athrs17_hnat_udp_thresh; + } + nf_athrs17_hnat_udp_thresh_file->data = &nf_athrs17_hnat_udp_thresh; + nf_athrs17_hnat_udp_thresh_file->read_proc = procfile_read_int; + nf_athrs17_hnat_udp_thresh_file->write_proc = procfile_write_int; + printk("/proc/%s/%s is created\n", NF_PROCFS_DIR, NF_ATHRS17_HNAT_UDP_THRESH_NAME); + + nf_athrs17_hnat_wan_ip_file = create_proc_entry(NF_ATHRS17_HNAT_WAN_IP_NAME, NF_PROCFS_PERM, qca_switch_dir); + if (NULL == nf_athrs17_hnat_wan_ip_file) + { + printk("Error: Can not create /proc/%s/%s\n", NF_PROCFS_DIR, NF_ATHRS17_HNAT_WAN_IP_NAME); + goto no_athrs17_hnat_wan_ip; + } + nf_athrs17_hnat_wan_ip_file->data = &nf_athrs17_hnat_wan_ip; + nf_athrs17_hnat_wan_ip_file->read_proc = procfile_read_ip; + nf_athrs17_hnat_wan_ip_file->write_proc = procfile_write_ip; + printk("/proc/%s/%s is created\n", NF_PROCFS_DIR, NF_ATHRS17_HNAT_WAN_IP_NAME); + + nf_athrs17_hnat_ppp_peer_ip_file = create_proc_entry(NF_ATHRS17_HNAT_PPP_PEER_IP_NAME, NF_PROCFS_PERM, qca_switch_dir); + if (NULL == nf_athrs17_hnat_ppp_peer_ip_file) + { + printk("Error: Can not create /proc/%s/%s\n", NF_PROCFS_DIR, NF_ATHRS17_HNAT_PPP_PEER_IP_NAME); + goto no_athrs17_hnat_ppp_peer_ip; + } + nf_athrs17_hnat_ppp_peer_ip_file->data = &nf_athrs17_hnat_ppp_peer_ip; + nf_athrs17_hnat_ppp_peer_ip_file->read_proc = procfile_read_ip; + nf_athrs17_hnat_ppp_peer_ip_file->write_proc = procfile_write_ip; + printk("/proc/%s/%s is created\n", NF_PROCFS_DIR, NF_ATHRS17_HNAT_PPP_PEER_IP_NAME); + + nf_athrs17_hnat_ppp_peer_mac_file = create_proc_entry(NF_ATHRS17_HNAT_PPP_PEER_MAC_NAME, NF_PROCFS_PERM, qca_switch_dir); + if (NULL == nf_athrs17_hnat_ppp_peer_mac_file) + { + printk("Error: Can not create /proc/%s/%s\n", NF_PROCFS_DIR, NF_ATHRS17_HNAT_PPP_PEER_MAC_NAME); + goto no_athrs17_hnat_ppp_peer_mac; + } + nf_athrs17_hnat_ppp_peer_mac_file->data = &nf_athrs17_hnat_ppp_peer_mac; + nf_athrs17_hnat_ppp_peer_mac_file->read_proc = procfile_read_mac; + nf_athrs17_hnat_ppp_peer_mac_file->write_proc = procfile_write_mac; + printk("/proc/%s/%s is created\n", NF_PROCFS_DIR, NF_ATHRS17_HNAT_PPP_PEER_MAC_NAME); + + nf_athrs17_hnat_wan_mac_file = create_proc_entry(NF_ATHRS17_HNAT_WAN_MAC_NAME, NF_PROCFS_PERM, qca_switch_dir); + if (NULL == nf_athrs17_hnat_wan_mac_file) + { + printk("Error: Can not create /proc/%s/%s\n", NF_PROCFS_DIR, NF_ATHRS17_HNAT_WAN_MAC_NAME); + goto no_athrs17_hnat_wan_mac; + } + nf_athrs17_hnat_wan_mac_file->data = &nf_athrs17_hnat_wan_mac; + nf_athrs17_hnat_wan_mac_file->read_proc = procfile_read_mac; + nf_athrs17_hnat_wan_mac_file->write_proc = procfile_write_mac; + printk("/proc/%s/%s is created\n", NF_PROCFS_DIR, NF_ATHRS17_HNAT_WAN_MAC_NAME); + + nf_athrs17_hnat_ppp_id2_file = create_proc_entry(NF_ATHRS17_HNAT_PPP_ID2_NAME, NF_PROCFS_PERM, qca_switch_dir); + if (NULL == nf_athrs17_hnat_ppp_id2_file) + { + printk("Error: Can not create /proc/%s/%s\n", NF_PROCFS_DIR, NF_ATHRS17_HNAT_PPP_ID2_NAME); + goto no_athrs17_hnat_ppp_id; + } + nf_athrs17_hnat_ppp_id2_file->data = &nf_athrs17_hnat_ppp_id2; + nf_athrs17_hnat_ppp_id2_file->read_proc = procfile_read_int; + nf_athrs17_hnat_ppp_id2_file->write_proc = procfile_write_int; + printk("/proc/%s/%s is created\n", NF_PROCFS_DIR, NF_ATHRS17_HNAT_PPP_ID2_NAME); + + nf_athrs17_hnat_ppp_peer_mac2_file = create_proc_entry(NF_ATHRS17_HNAT_PPP_PEER_MAC2_NAME, NF_PROCFS_PERM, qca_switch_dir); + if (NULL == nf_athrs17_hnat_ppp_peer_mac2_file) + { + printk("Error: Can not create /proc/%s/%s\n", NF_PROCFS_DIR, NF_ATHRS17_HNAT_PPP_PEER_MAC2_NAME); + goto no_athrs17_hnat_ppp_peer_mac; + } + nf_athrs17_hnat_ppp_peer_mac2_file->data = &nf_athrs17_hnat_ppp_peer_mac2; + nf_athrs17_hnat_ppp_peer_mac2_file->read_proc = procfile_read_mac; + nf_athrs17_hnat_ppp_peer_mac2_file->write_proc = procfile_write_mac; + printk("/proc/%s/%s is created\n", NF_PROCFS_DIR, NF_ATHRS17_HNAT_PPP_PEER_MAC_NAME); + + return 0; + +no_athrs17_hnat_wan_mac: + remove_proc_entry(NF_ATHRS17_HNAT_PPP_PEER_MAC_NAME, qca_switch_dir); +no_athrs17_hnat_ppp_peer_mac: + remove_proc_entry(NF_ATHRS17_HNAT_PPP_PEER_IP_NAME, qca_switch_dir); +no_athrs17_hnat_ppp_peer_ip: + remove_proc_entry(NF_ATHRS17_HNAT_WAN_IP_NAME, qca_switch_dir); +no_athrs17_hnat_wan_ip: + remove_proc_entry(NF_ATHRS17_HNAT_UDP_THRESH_NAME, qca_switch_dir); +no_athrs17_hnat_udp_thresh: + remove_proc_entry(NF_ATHRS17_HNAT_PPP_ID_NAME, qca_switch_dir); +no_athrs17_hnat_ppp_id: + remove_proc_entry(NF_ATHRS17_HNAT_WAN_TYPE_NAME, qca_switch_dir); +no_athrs17_hnat_wan_type: + remove_proc_entry(NF_ATHRS17_HNAT_NAME, qca_switch_dir); +no_athrs17_hnat: + remove_proc_entry(NF_PROCFS_DIR, NULL); +err_out: + return ret; +} + +void napt_procfs_exit(void) +{ + remove_proc_entry(NF_ATHRS17_HNAT_NAME, qca_switch_dir); + remove_proc_entry(NF_ATHRS17_HNAT_WAN_TYPE_NAME, qca_switch_dir); + remove_proc_entry(NF_ATHRS17_HNAT_PPP_ID_NAME, qca_switch_dir); + remove_proc_entry(NF_ATHRS17_HNAT_UDP_THRESH_NAME, qca_switch_dir); + remove_proc_entry(NF_ATHRS17_HNAT_WAN_IP_NAME, qca_switch_dir); + remove_proc_entry(NF_ATHRS17_HNAT_PPP_PEER_IP_NAME, qca_switch_dir); + remove_proc_entry(NF_ATHRS17_HNAT_PPP_PEER_MAC_NAME, qca_switch_dir); + remove_proc_entry(NF_ATHRS17_HNAT_WAN_MAC_NAME, qca_switch_dir); + remove_proc_entry(NF_ATHRS17_HNAT_PPP_ID2_NAME, qca_switch_dir); + remove_proc_entry(NF_ATHRS17_HNAT_PPP_PEER_MAC2_NAME, qca_switch_dir); + remove_proc_entry(NF_PROCFS_DIR, NULL); + printk(KERN_INFO "/proc/%s/%s removed\n", NF_PROCFS_DIR, NF_ATHRS17_HNAT_NAME); +} +#else +static ssize_t napt_hnat_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t count; + a_uint32_t num; + + num = (a_uint32_t)nf_athrs17_hnat; + + count = snprintf(buf, (ssize_t)PAGE_SIZE, "%u", num); + return count; +} + +static ssize_t napt_hnat_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char num_buf[12]; + a_uint32_t num; + + + if (count >= sizeof(num_buf)) return 0; + memcpy(num_buf, buf, count); + num_buf[count] = '\0'; + sscanf(num_buf, "%u", &num); + + nf_athrs17_hnat = num; + + return count; +} + +static ssize_t napt_wan_type_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t count; + a_uint32_t num; + + num = (a_uint32_t)nf_athrs17_hnat_wan_type; + + count = snprintf(buf, (ssize_t)PAGE_SIZE, "%u", num); + return count; +} + +static ssize_t napt_wan_type_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char num_buf[12]; + a_uint32_t num; + + + if (count >= sizeof(num_buf)) return 0; + memcpy(num_buf, buf, count); + num_buf[count] = '\0'; + sscanf(num_buf, "%u", &num); + + nf_athrs17_hnat_wan_type = num; + + return count; +} + +static ssize_t napt_ppp_id_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t count; + a_uint32_t num; + + num = (a_uint32_t)nf_athrs17_hnat_ppp_id; + + count = snprintf(buf, (ssize_t)PAGE_SIZE, "%u", num); + return count; +} + +static ssize_t napt_ppp_id_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char num_buf[12]; + a_uint32_t num; + + + if (count >= sizeof(num_buf)) return 0; + memcpy(num_buf, buf, count); + num_buf[count] = '\0'; + sscanf(num_buf, "%u", &num); + + nf_athrs17_hnat_ppp_id = num; + + return count; +} + +static ssize_t napt_udp_thresh_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t count; + a_uint32_t num; + + num = (a_uint32_t)nf_athrs17_hnat_udp_thresh; + + count = snprintf(buf, (ssize_t)PAGE_SIZE, "%u", num); + return count; +} + +static ssize_t napt_udp_thresh_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char num_buf[12]; + a_uint32_t num; + + + if (count >= sizeof(num_buf)) return 0; + memcpy(num_buf, buf, count); + num_buf[count] = '\0'; + sscanf(num_buf, "%u", &num); + + nf_athrs17_hnat_udp_thresh = num; + + return count; +} + +static ssize_t napt_wan_ip_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t count; + unsigned char* data; + + data = (unsigned char*)&nf_athrs17_hnat_wan_ip; + + count = snprintf(buf, (ssize_t)PAGE_SIZE, "%d.%d.%d.%d", + data[0], data[1], data[2], data[3]); + return count; +} + +static ssize_t napt_wan_ip_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char num_buf[12]; + a_uint32_t num; + + + if (count >= sizeof(num_buf)) return 0; + memcpy(num_buf, buf, count); + num_buf[count] = '\0'; + sscanf(num_buf, "%u", &num); + + nf_athrs17_hnat_wan_ip = num; + + return count; +} + +static ssize_t napt_ppp_peer_ip_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t count; + unsigned char* data; + + data = (unsigned char*)&nf_athrs17_hnat_ppp_peer_ip; + + count = snprintf(buf, (ssize_t)PAGE_SIZE, "%d.%d.%d.%d", + data[0], data[1], data[2], data[3]); + return count; +} + +static ssize_t napt_ppp_peer_ip_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char num_buf[12]; + a_uint32_t num; + + + if (count >= sizeof(num_buf)) return 0; + memcpy(num_buf, buf, count); + num_buf[count] = '\0'; + sscanf(num_buf, "%u", &num); + + nf_athrs17_hnat_ppp_peer_ip = num; + + return count; +} + +static ssize_t napt_peer_mac_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t count; + unsigned char* data; + + data = (unsigned char*)&nf_athrs17_hnat_ppp_peer_mac; + + count = snprintf(buf, (ssize_t)PAGE_SIZE, "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x", + data[0], data[1], data[2], data[3], data[4], data[5]); + return count; +} + +static ssize_t napt_peer_mac_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char num_buf[32]; + unsigned long long prv_data; + unsigned char *ptr_char; + int res = 0; + + if (count >= sizeof(num_buf)) return 0; + memcpy(num_buf, buf, count); + num_buf[count] = '\0'; + res = kstrtoll((const char *)num_buf, 16, &prv_data); + if(res < 0) + return res; + + prv_data = cpu_to_be64p(&prv_data); + ptr_char = (unsigned char *)&prv_data; + nf_athrs17_hnat_ppp_peer_mac[0] = ptr_char[2]; + nf_athrs17_hnat_ppp_peer_mac[1] = ptr_char[3]; + nf_athrs17_hnat_ppp_peer_mac[2] = ptr_char[4]; + nf_athrs17_hnat_ppp_peer_mac[3] = ptr_char[5]; + nf_athrs17_hnat_ppp_peer_mac[4] = ptr_char[6]; + nf_athrs17_hnat_ppp_peer_mac[5] = ptr_char[7]; + + return count; +} + +static ssize_t napt_wan_mac_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t count; + unsigned char* data; + + data = (unsigned char*)&nf_athrs17_hnat_wan_mac; + + count = snprintf(buf, (ssize_t)PAGE_SIZE, "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x", + data[0], data[1], data[2], data[3], data[4], data[5]); + return count; +} + +static ssize_t napt_wan_mac_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char num_buf[32]; + unsigned long long prv_data; + unsigned char *ptr_char; + int res = 0; + + if (count >= sizeof(num_buf)) return 0; + memcpy(num_buf, buf, count); + num_buf[count] = '\0'; + res = kstrtoll((const char *)num_buf, 16, &prv_data); + if(res < 0) + return res; + + prv_data = cpu_to_be64p(&prv_data); + ptr_char = (unsigned char *)&prv_data; + nf_athrs17_hnat_wan_mac[0] = ptr_char[2]; + nf_athrs17_hnat_wan_mac[1] = ptr_char[3]; + nf_athrs17_hnat_wan_mac[2] = ptr_char[4]; + nf_athrs17_hnat_wan_mac[3] = ptr_char[5]; + nf_athrs17_hnat_wan_mac[4] = ptr_char[6]; + nf_athrs17_hnat_wan_mac[5] = ptr_char[7]; + + return count; +} + +static ssize_t napt_peer_mac2_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t count; + unsigned char* data; + + data = (unsigned char*)&nf_athrs17_hnat_ppp_peer_mac2; + + count = snprintf(buf, (ssize_t)PAGE_SIZE, "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x", + data[0], data[1], data[2], data[3], data[4], data[5]); + return count; +} + +static ssize_t napt_peer_mac2_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char num_buf[32]; + unsigned long long prv_data; + unsigned char *ptr_char; + int res = 0; + + if (count >= sizeof(num_buf)) return 0; + memcpy(num_buf, buf, count); + num_buf[count] = '\0'; + res = kstrtoll((const char *)num_buf, 16, &prv_data); + if(res < 0) + return res; + + prv_data = cpu_to_be64p(&prv_data); + ptr_char = (unsigned char *)&prv_data; + nf_athrs17_hnat_ppp_peer_mac2[0] = ptr_char[2]; + nf_athrs17_hnat_ppp_peer_mac2[1] = ptr_char[3]; + nf_athrs17_hnat_ppp_peer_mac2[2] = ptr_char[4]; + nf_athrs17_hnat_ppp_peer_mac2[3] = ptr_char[5]; + nf_athrs17_hnat_ppp_peer_mac2[4] = ptr_char[6]; + nf_athrs17_hnat_ppp_peer_mac2[5] = ptr_char[7]; + + return count; +} + +static ssize_t napt_ppp_id2_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t count; + a_uint32_t num; + + num = (a_uint32_t)nf_athrs17_hnat_ppp_id2; + + count = snprintf(buf, (ssize_t)PAGE_SIZE, "%u", num); + return count; +} + +static ssize_t napt_ppp_id2_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char num_buf[12]; + a_uint32_t num; + + + if (count >= sizeof(num_buf)) return 0; + memcpy(num_buf, buf, count); + num_buf[count] = '\0'; + sscanf(num_buf, "%u", &num); + + nf_athrs17_hnat_ppp_id2 = num; + + return count; +} + +static ssize_t napt_sync_counter_en_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t count; + a_uint32_t num; + + num = (a_uint32_t)nf_athrs17_hnat_sync_counter_en; + + count = snprintf(buf, (ssize_t)PAGE_SIZE, "%u", num); + return count; +} + +static ssize_t napt_sync_counter_en_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char num_buf[12]; + a_uint32_t num; + + + if (count >= sizeof(num_buf)) return 0; + memcpy(num_buf, buf, count); + num_buf[count] = '\0'; + sscanf(num_buf, "%u", &num); + + nf_athrs17_hnat_sync_counter_en = num; + + return count; +} + +static ssize_t napt_log_en_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t count; + a_uint32_t num; + + num = (a_uint32_t)hnat_log_en; + + count = snprintf(buf, (ssize_t)PAGE_SIZE, "%u", num); + return count; +} + +static ssize_t napt_log_en_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char num_buf[12]; + a_uint32_t num; + + + if (count >= sizeof(num_buf)) return 0; + memcpy(num_buf, buf, count); + num_buf[count] = '\0'; + sscanf(num_buf, "%u", &num); + + hnat_log_en = num; + + return count; +} + +static ssize_t napt_scan_period_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t count; + a_uint32_t num; + + num = (a_uint32_t)scan_period; + + count = snprintf(buf, (ssize_t)PAGE_SIZE, "%u", num); + return count; +} + +static ssize_t napt_scan_period_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char num_buf[12]; + a_uint32_t num; + + + if (count >= sizeof(num_buf)) return 0; + memcpy(num_buf, buf, count); + num_buf[count] = '\0'; + sscanf(num_buf, "%u", &num); + + scan_period = num; + + return count; +} + +static ssize_t napt_scan_enable_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t count; + a_uint32_t num; + + num = (a_uint32_t)scan_enable; + + count = snprintf(buf, (ssize_t)PAGE_SIZE, "%u", num); + return count; +} + +static ssize_t napt_scan_enable_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char num_buf[12]; + a_uint32_t num; + + + if (count >= sizeof(num_buf)) return 0; + memcpy(num_buf, buf, count); + num_buf[count] = '\0'; + sscanf(num_buf, "%u", &num); + + scan_enable = num; + + return count; +} + +static ssize_t napt_need_clean_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t count; + a_uint32_t num; + + num = (a_uint32_t)napt_need_clean; + + count = snprintf(buf, (ssize_t)PAGE_SIZE, "%u", num); + return count; +} + +static ssize_t napt_need_clean_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char num_buf[12]; + a_uint32_t num; + + + if (count >= sizeof(num_buf)) return 0; + memcpy(num_buf, buf, count); + num_buf[count] = '\0'; + sscanf(num_buf, "%u", &num); + + napt_need_clean = num; + + return count; +} + +static ssize_t napt_wan_switch_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t count; + a_uint32_t num; + + num = (a_uint32_t)wan_switch; + + count = snprintf(buf, (ssize_t)PAGE_SIZE, "%u", num); + return count; +} + +static ssize_t napt_wan_switch_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char num_buf[12]; + a_uint32_t num; + + + if (count >= sizeof(num_buf)) return 0; + memcpy(num_buf, buf, count); + num_buf[count] = '\0'; + sscanf(num_buf, "%u", &num); + + wan_switch = num; + napt_wan_switch_prehandle(); + + return count; +} + +static ssize_t napt_wan_port_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t count; + a_uint32_t num; + + num = (a_uint32_t)nat_wan_port; + + count = snprintf(buf, (ssize_t)PAGE_SIZE, "%u", num); + return count; +} + +static ssize_t napt_wan_port_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char num_buf[12]; + a_uint32_t num; + + + if (count >= sizeof(num_buf)) return 0; + memcpy(num_buf, buf, count); + num_buf[count] = '\0'; + sscanf(num_buf, "%u", &num); + + nat_wan_port = num; + + return count; +} + +static ssize_t napt_thresh_base_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t count; + a_uint32_t num; + + num = packet_thres_base; + + count = snprintf(buf, (ssize_t)PAGE_SIZE, "%u", num); + return count; +} + +static ssize_t napt_thresh_base_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char num_buf[12]; + a_uint32_t num; + + + if (count >= sizeof(num_buf)) return 0; + memcpy(num_buf, buf, count); + num_buf[count] = '\0'; + sscanf(num_buf, "%u", &num); + + packet_thres_base = num; + + return count; +} + +static ssize_t napt_polling_quota_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t count; + a_uint32_t num; + + num = polling_quota; + + count = snprintf(buf, (ssize_t)PAGE_SIZE, "%u", num); + return count; +} + +static ssize_t napt_polling_quota_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char num_buf[12]; + a_uint32_t num; + + + if (count >= sizeof(num_buf)) return 0; + memcpy(num_buf, buf, count); + num_buf[count] = '\0'; + sscanf(num_buf, "%u", &num); + + polling_quota = num; + + return count; +} + +static ssize_t napt_bypass_check_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t count; + a_uint32_t num; + + num = napt_add_bypass_check; + + count = snprintf(buf, (ssize_t)PAGE_SIZE, "%u", num); + return count; +} + +static ssize_t napt_bypass_check_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char num_buf[12]; + a_uint32_t num; + + + if (count >= sizeof(num_buf)) return 0; + memcpy(num_buf, buf, count); + num_buf[count] = '\0'; + sscanf(num_buf, "%u", &num); + + napt_add_bypass_check = num; + + return count; +} + +extern void napt_helper_show(void); +static ssize_t napt_log_show_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + napt_helper_show(); + return 0; +} + +struct kobject *napt_sys = NULL; +static const struct device_attribute napt_hnat_attr = + __ATTR(hnat, 0660, napt_hnat_get, napt_hnat_set); +static const struct device_attribute napt_wan_type_attr = + __ATTR(wan_type, 0660, napt_wan_type_get, napt_wan_type_set); +static const struct device_attribute napt_ppp_id_attr = + __ATTR(ppp_id, 0660, napt_ppp_id_get, napt_ppp_id_set); +static const struct device_attribute napt_udp_thresh_attr = + __ATTR(udp_thresh, 0660, napt_udp_thresh_get, napt_udp_thresh_set); +static const struct device_attribute napt_wan_ip_attr = + __ATTR(wan_ip, 0660, napt_wan_ip_get, napt_wan_ip_set); +static const struct device_attribute napt_ppp_peer_ip_attr = + __ATTR(peer_ip, 0660, napt_ppp_peer_ip_get, napt_ppp_peer_ip_set); +static const struct device_attribute napt_ppp_peer_mac_attr = + __ATTR(peer_mac, 0660, napt_peer_mac_get, napt_peer_mac_set); +static const struct device_attribute napt_wan_mac_attr = + __ATTR(wan_mac, 0660, napt_wan_mac_get, napt_wan_mac_set); +static const struct device_attribute napt_ppp_id2_attr = + __ATTR(ppp_id2, 0660, napt_ppp_id2_get, napt_ppp_id2_set); +static const struct device_attribute napt_ppp_peer_mac2_attr = + __ATTR(peer_mac2, 0660, napt_peer_mac2_get, napt_peer_mac2_set); +static const struct device_attribute napt_sync_counter_en_attr = + __ATTR(sync_counter_en, 0660, napt_sync_counter_en_get, napt_sync_counter_en_set); +static const struct device_attribute napt_log_en_attr = + __ATTR(log_en, 0660, napt_log_en_get, napt_log_en_set); +static const struct device_attribute napt_log_show_attr = + __ATTR(log_show, 0660, napt_log_show_get, NULL); +static const struct device_attribute napt_scan_period_attr = + __ATTR(speriod, 0660, napt_scan_period_get, napt_scan_period_set); +static const struct device_attribute napt_scan_enable_attr = + __ATTR(scan_en, 0660, napt_scan_enable_get, napt_scan_enable_set); +static const struct device_attribute napt_need_clean_attr = + __ATTR(napt_clean, 0660, napt_need_clean_get, napt_need_clean_set); +static const struct device_attribute napt_wan_switch_attr = + __ATTR(napt_switch, 0660, napt_wan_switch_get, napt_wan_switch_set); +static const struct device_attribute napt_wan_port_attr = + __ATTR(wan_port, 0660, napt_wan_port_get, napt_wan_port_set); +static const struct device_attribute napt_thresh_base_attr = + __ATTR(thresh_base, 0660, napt_thresh_base_get, napt_thresh_base_set); +static const struct device_attribute napt_polling_quota_attr = + __ATTR(ct_quota, 0660, napt_polling_quota_get, napt_polling_quota_set); +static const struct device_attribute napt_bypass_check_attr = + __ATTR(bypass_check, 0660, napt_bypass_check_get, napt_bypass_check_set); + +int napt_procfs_init(void) +{ + int ret = 0; + + napt_sys = kobject_create_and_add("ssdk_napt", NULL); + if (!napt_sys) { + printk("napt failed to register sysfs\n "); + return ret; + } + + + + ret = sysfs_create_file(napt_sys, &napt_hnat_attr.attr); + if (ret) { + printk("Failed to register hnat SysFS file\n"); + goto CLEANUP_1; + } + ret = sysfs_create_file(napt_sys, &napt_wan_type_attr.attr); + if (ret) { + printk("Failed to register wan type SysFS file\n"); + goto CLEANUP_2; + } + ret = sysfs_create_file(napt_sys, &napt_ppp_id_attr.attr); + if (ret) { + printk("Failed to register ppp id SysFS file\n"); + goto CLEANUP_3; + } + ret = sysfs_create_file(napt_sys, &napt_udp_thresh_attr.attr); + if (ret) { + printk("Failed to register udp thresh SysFS file\n"); + goto CLEANUP_4; + } + ret = sysfs_create_file(napt_sys, &napt_wan_ip_attr.attr); + if (ret) { + printk("Failed to register wan ip SysFS file\n"); + goto CLEANUP_5; + } + ret = sysfs_create_file(napt_sys, &napt_ppp_peer_ip_attr.attr); + if (ret) { + printk("Failed to register ppp peer ip SysFS file\n"); + goto CLEANUP_6; + } + ret = sysfs_create_file(napt_sys, &napt_ppp_peer_mac_attr.attr); + if (ret) { + printk("Failed to register ppp peer mac SysFS file\n"); + goto CLEANUP_7; + } + ret = sysfs_create_file(napt_sys, &napt_wan_mac_attr.attr); + if (ret) { + printk("Failed to register wan mac SysFS file\n"); + goto CLEANUP_8; + } + ret = sysfs_create_file(napt_sys, &napt_ppp_id2_attr.attr); + if (ret) { + printk("Failed to register ppp id2 SysFS file\n"); + goto CLEANUP_9; + } + ret = sysfs_create_file(napt_sys, &napt_ppp_peer_mac2_attr.attr); + if (ret) { + printk("Failed to register ppp peer mac2 SysFS file\n"); + goto CLEANUP_10; + } + ret = sysfs_create_file(napt_sys, &napt_sync_counter_en_attr.attr); + if (ret) { + printk("Failed to register sync counter en SysFS file\n"); + goto CLEANUP_11; + } + ret = sysfs_create_file(napt_sys, &napt_log_en_attr.attr); + if (ret) { + printk("Failed to register log en SysFS file\n"); + goto CLEANUP_12; + } + ret = sysfs_create_file(napt_sys, &napt_log_show_attr.attr); + if (ret) { + printk("Failed to register log show SysFS file\n"); + goto CLEANUP_13; + } + ret = sysfs_create_file(napt_sys, &napt_scan_period_attr.attr); + if (ret) { + printk("Failed to register scan period SysFS file\n"); + goto CLEANUP_14; + } + ret = sysfs_create_file(napt_sys, &napt_scan_enable_attr.attr); + if (ret) { + printk("Failed to register scan enable SysFS file\n"); + goto CLEANUP_15; + } + ret = sysfs_create_file(napt_sys, &napt_need_clean_attr.attr); + if (ret) { + printk("Failed to register napt clean SysFS file\n"); + goto CLEANUP_16; + } + ret = sysfs_create_file(napt_sys, &napt_wan_switch_attr.attr); + if (ret) { + printk("Failed to register napt wan switch SysFS file\n"); + goto CLEANUP_17; + } + ret = sysfs_create_file(napt_sys, &napt_wan_port_attr.attr); + if (ret) { + printk("Failed to register napt wan port SysFS file\n"); + goto CLEANUP_18; + } + ret = sysfs_create_file(napt_sys, &napt_thresh_base_attr.attr); + if (ret) { + printk("Failed to register napt thresh base SysFS file\n"); + goto CLEANUP_19; + } + ret = sysfs_create_file(napt_sys, &napt_polling_quota_attr.attr); + if (ret) { + printk("Failed to register napt polling quota SysFS file\n"); + goto CLEANUP_20; + } + ret = sysfs_create_file(napt_sys, &napt_bypass_check_attr.attr); + if (ret) { + printk("Failed to register napt add check bypass SysFS file\n"); + goto CLEANUP_21; + } + return 0; +CLEANUP_21: + sysfs_remove_file(napt_sys, &napt_polling_quota_attr.attr); +CLEANUP_20: + sysfs_remove_file(napt_sys, &napt_thresh_base_attr.attr); +CLEANUP_19: + sysfs_remove_file(napt_sys, &napt_wan_port_attr.attr); +CLEANUP_18: + sysfs_remove_file(napt_sys, &napt_wan_switch_attr.attr); +CLEANUP_17: + sysfs_remove_file(napt_sys, &napt_need_clean_attr.attr); +CLEANUP_16: + sysfs_remove_file(napt_sys, &napt_scan_enable_attr.attr); +CLEANUP_15: + sysfs_remove_file(napt_sys, &napt_scan_period_attr.attr); +CLEANUP_14: + sysfs_remove_file(napt_sys, &napt_log_show_attr.attr); +CLEANUP_13: + sysfs_remove_file(napt_sys, &napt_log_en_attr.attr); +CLEANUP_12: + sysfs_remove_file(napt_sys, &napt_sync_counter_en_attr.attr); +CLEANUP_11: + sysfs_remove_file(napt_sys, &napt_ppp_peer_mac2_attr.attr); +CLEANUP_10: + sysfs_remove_file(napt_sys, &napt_ppp_id2_attr.attr); +CLEANUP_9: + sysfs_remove_file(napt_sys, &napt_wan_mac_attr.attr); +CLEANUP_8: + sysfs_remove_file(napt_sys, &napt_ppp_peer_mac_attr.attr); +CLEANUP_7: + sysfs_remove_file(napt_sys, &napt_ppp_peer_ip_attr.attr); +CLEANUP_6: + sysfs_remove_file(napt_sys, &napt_wan_ip_attr.attr); +CLEANUP_5: + sysfs_remove_file(napt_sys, &napt_udp_thresh_attr.attr); +CLEANUP_4: + sysfs_remove_file(napt_sys, &napt_ppp_id_attr.attr); +CLEANUP_3: + sysfs_remove_file(napt_sys, &napt_wan_type_attr.attr); +CLEANUP_2: + sysfs_remove_file(napt_sys, &napt_hnat_attr.attr); +CLEANUP_1: + kobject_put(napt_sys); + + return ret; +} + +void napt_procfs_exit(void) +{ + printk("napt procfs exit\n"); + + sysfs_remove_file(napt_sys, &napt_bypass_check_attr.attr); + sysfs_remove_file(napt_sys, &napt_polling_quota_attr.attr); + sysfs_remove_file(napt_sys, &napt_thresh_base_attr.attr); + sysfs_remove_file(napt_sys, &napt_wan_port_attr.attr); + sysfs_remove_file(napt_sys, &napt_wan_switch_attr.attr); + sysfs_remove_file(napt_sys, &napt_need_clean_attr.attr); + sysfs_remove_file(napt_sys, &napt_scan_enable_attr.attr); + sysfs_remove_file(napt_sys, &napt_scan_period_attr.attr); + sysfs_remove_file(napt_sys, &napt_log_show_attr.attr); + sysfs_remove_file(napt_sys, &napt_log_en_attr.attr); + sysfs_remove_file(napt_sys, &napt_sync_counter_en_attr.attr); + sysfs_remove_file(napt_sys, &napt_ppp_peer_mac2_attr.attr); + sysfs_remove_file(napt_sys, &napt_ppp_id2_attr.attr); + sysfs_remove_file(napt_sys, &napt_wan_mac_attr.attr); + sysfs_remove_file(napt_sys, &napt_ppp_peer_mac_attr.attr); + sysfs_remove_file(napt_sys, &napt_ppp_peer_ip_attr.attr); + sysfs_remove_file(napt_sys, &napt_wan_ip_attr.attr); + sysfs_remove_file(napt_sys, &napt_udp_thresh_attr.attr); + sysfs_remove_file(napt_sys, &napt_ppp_id_attr.attr); + sysfs_remove_file(napt_sys, &napt_wan_type_attr.attr); + sysfs_remove_file(napt_sys, &napt_hnat_attr.attr); + + kobject_put(napt_sys); +} + + +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/nat_helper.c b/feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/nat_helper.c new file mode 100755 index 000000000..441eeab5e --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/nat_helper.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef KVER32 +#include +#include +#else +#include +#endif +#include + + +#include "nat_helper.h" + +char hnat_log_en = HNAT_LOG_LEVEL_DISABLE; +char hnat_log_buffer[NAT_LOG_MAX_SIZE]; + +void hnat_log_msg(int level, char *string, ...) +{ + + va_list ptr; + + if(level < hnat_log_en) + return; + memset(hnat_log_buffer, 0, sizeof(hnat_log_buffer)); + va_start(ptr,string); + vsnprintf(hnat_log_buffer,sizeof(hnat_log_buffer), string, ptr); + va_end(ptr); + aos_printk("%s\n", hnat_log_buffer); +} + + +sw_error_t +nat_helper_init(uint32_t dev_id, uint32_t portbmp) +{ + nat_helper_bg_task_init(); + host_helper_init(portbmp); + napt_helper_init(); + nat_ipt_helper_init(); + + aos_printk("Hello, nat helper module for 1.1!\n"); + + return SW_OK; +} + +sw_error_t +nat_helper_cleanup(uint32_t dev_id) +{ + host_helper_exit(); + napt_helper_exit(); + nat_ipt_helper_exit(); + nat_helper_bg_task_exit(); + + aos_printk("Goodbye, nat helper module!\n"); + + return SW_OK; +} + diff --git a/feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/nat_helper.h b/feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/nat_helper.h new file mode 100755 index 000000000..6fad83e8f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/nat_helper.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2012, 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. + */ + + +#ifndef _NAT_HELPER_H +#define _NAT_HELPER_H + +#include "sw.h" + +#define NAPT_TABLE_SIZE 1024 + +#define S17_WAN_PORT nat_helper_wan_port_get() + +void host_helper_init(a_uint32_t portbmp); +void host_helper_exit(void); +void napt_helper_init(void); +void napt_helper_exit(void); +void nat_ipt_helper_init(void); +void nat_ipt_helper_exit(void); + +void nat_helper_bg_task_init(void); +void nat_helper_bg_task_exit(void); + +a_uint32_t nat_helper_wan_port_get(void); +uint32_t get_next_hop(uint32_t daddr, uint32_t saddr); + +void hnat_log_msg(int level, char *string, ...); +#define NAT_LOG_MAX_SIZE 1024 +enum { + HNAT_LOG_LEVEL_DEBUG = 0, + HNAT_LOG_LEVEL_INFO, + HNAT_LOG_LEVEL_ERR, + HNAT_LOG_LEVEL_DISABLE +}; +#define HNAT_PRINTK(arg...) \ + hnat_log_msg(HNAT_LOG_LEVEL_DEBUG, arg) +#define HNAT_INFO_PRINTK(arg...) \ + hnat_log_msg(HNAT_LOG_LEVEL_INFO, arg) +#define HNAT_ERR_PRINTK(arg...) \ + hnat_log_msg(HNAT_LOG_LEVEL_ERR, arg) + + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/nat_ipt_helper.c b/feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/nat_ipt_helper.c new file mode 100755 index 000000000..c5918c66f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/app/nathelper/linux/nat_ipt_helper.c @@ -0,0 +1,761 @@ +/* + * Copyright (c) 2012, 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. + */ + + +#ifdef KVER32 +#include +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#include "nat_helper.h" + +#include "lib/nat_helper_hsl.h" +#include "lib/nat_helper_dt.h" + + +#define nf_nat_ipv4_multi_range_compat \ + nf_nat_ipv4_multi_range_compat +#define nf_nat_range nf_nat_ipv4_range +#define ipt_entry_target xt_entry_target +#define ipt_entry_match xt_entry_match + +#define IPT_MATCH_ITERATE(e, fun, args...) \ +({ \ + unsigned int i; \ + int ret = 0; \ + struct xt_entry_match *m; \ + \ + for (i = sizeof(struct ipt_entry); \ + i < (e)->target_offset; \ + i += m->u.match_size) { \ + m = (void *)e + i; \ + ret = fun(m , ##args); \ + if (ret != 0) \ + break; \ + } \ + ret; \ +}) + +#define IPT_ENTRY_ITERATE(entries, size, fun, args...) \ +({ \ + unsigned int k, j; \ + int ret = 0; \ + struct ipt_entry *e; \ + \ + for (k = 0, j = 0; k < (size); \ + k += (e)->next_offset, j++) { \ + e = (void *)(entries) + k; \ + if (j < 0) \ + continue; \ + \ + ret = fun(e , ##args); \ + if (ret != 0) \ + break; \ + } \ + ret; \ +}) + + +#define IPT_BUFFER_INIT_LEN 1000 +#define NF_NAT_INIT_ENTRIES_NUM 5 + +static int +nat_ipt_set_ctl(struct sock *sk, int cmd, void __user * user, unsigned int len); +static int +nat_ipt_get_ctl(struct sock *sk, int cmd, void __user * user, int *len); + +int nat_sockopts_init = 0; + +/*those initial value will be overwrited by orignal iptables sockopts*/ +static struct nf_sockopt_ops orgi_ipt_sockopts; +static struct nf_sockopt_ops tmp_ipt_sockopts = +{ + /*pls check linux/in.h*/ +#define IPT_TEMP_BASE_CTL 60 +#define IPT_TEMP_SET_MAX (IPT_TEMP_BASE_CTL+1) +#define IPT_TEMP_GET_MAX (IPT_TEMP_BASE_CTL+2) + .pf = PF_INET, + .set_optmin = IPT_TEMP_BASE_CTL, + .set_optmax = IPT_TEMP_SET_MAX, + .set = nat_ipt_set_ctl, + .get_optmin = IPT_TEMP_BASE_CTL, + .get_optmax = IPT_TEMP_GET_MAX, + .get = nat_ipt_get_ctl +}; + +static struct nf_sockopt_ops *ipt_sockopts = NULL; +static uint32_t snat_seq = 0; +static uint32_t hw_nat_ipt_seq[NAT_HW_NUM] = {0}; +static uint32_t hw_nat_pip_idx[NAT_HW_NUM] = {0}; +static uint8_t *gbuffer, *sbuffer; +static unsigned int glen, slen; +static struct ipt_replace old_replace; + +static void +nat_ipt_del(struct ipt_replace ireplace) +{ + int i, j; + struct ipt_entry *gentry = NULL; + struct ipt_entry *sentry = NULL; + struct xt_entry_target *gtarget = NULL; + struct xt_entry_target *starget = NULL; + struct nf_nat_ipv4_multi_range_compat *grange = NULL; + struct nf_nat_ipv4_multi_range_compat *srange = NULL; + uint8_t *gptr, *sptr; + unsigned int oldnum = ireplace.num_counters; + unsigned int seq = 1; + gptr = gbuffer; + sptr = sbuffer; + + HNAT_PRINTK("into nat_ipt_del\n"); + for (i = oldnum; i >= 0; i--)//NF_NAT_INIT_ENTRIES_NUM; i--) + { + gentry = (struct ipt_entry *)gptr; + sentry = (struct ipt_entry *)sptr; + gtarget = (struct xt_entry_target *)((uint8_t *) gentry + gentry->target_offset); + starget = (struct xt_entry_target *)((uint8_t *) sentry + sentry->target_offset); + grange = (struct nf_nat_ipv4_multi_range_compat *)((uint8_t *) gtarget + sizeof (*gtarget)); + srange = (struct nf_nat_ipv4_multi_range_compat *)((uint8_t *) starget + sizeof (*starget)); + + HNAT_PRINTK("(%d)isis_nat_del name %s:%s#####(%x:%x %x)###\n", + i, gtarget->u.user.name, starget->u.user.name, + gentry->ip.src.s_addr, gentry->ip.dst.s_addr, + grange->range[0].min.all); + + if (strcmp(gtarget->u.user.name, starget->u.user.name)) + { + /*if (!strcmp(gtarget->u.user.name, "DNAT")) { + if (gentry->ip.src.s_addr || !gentry->ip.dst.s_addr + || grange->range[0].min.all) + return; + goto delete; + } else */ + if (!strcmp(gtarget->u.user.name, "SNAT")) + { + if (!gentry->ip.src.s_addr || gentry->ip.dst.s_addr + || grange->range[0].min.all) + return; + goto delete; + } + return; + } /*else if (!strcmp(gtarget->u.user.name, "DNAT")) { + if (memcmp(gentry, sentry, gentry->next_offset)) { + if (gentry->ip.src.s_addr || !gentry->ip.dst.s_addr + || grange->range[0].min.all) + return; + goto delete; + } + } */else if (!strcmp(gtarget->u.user.name, "SNAT")) + { + if (memcmp(gentry, sentry, gentry->next_offset)) + { + if (!gentry->ip.src.s_addr || gentry->ip.dst.s_addr + || grange->range[0].min.all) + return; + goto delete; + } + } + gptr += gentry->next_offset; + sptr += gentry->next_offset; + if(!strcmp(gtarget->u.user.name, "SNAT")) + { + seq++; + } + } + HNAT_PRINTK("NONE to delete\n"); + return; + +delete: + HNAT_PRINTK("READY to delete one\n"); + for (j = 0; j < NAT_HW_NUM; j++) + { + HNAT_PRINTK("ready [%d] (hw)%x:(sw)%x######\n", + j, hw_nat_ipt_seq[j], seq); + if (hw_nat_ipt_seq[j] == seq) + { + if(nat_hw_del_by_index(j) != 0) + { + return; + } + //public_ip_del(hw_nat_pip_idx[j]); + } + } + + for(i = 0; i < NAT_HW_NUM; i++) + { + if(hw_nat_ipt_seq[i] > seq) + { + hw_nat_ipt_seq[i]--; + } + else if(hw_nat_ipt_seq[i] == seq) + { + hw_nat_ipt_seq[i]=0; + } + } + + return; +} + +static void +nat_ipt_to_hw_entry(struct ipt_entry *e, + nat_entry_t *nat) +{ +#define P_ANY 0 +#define P_TCP 6 +#define P_UDP 17 + + struct ipt_entry_target *t = (struct ipt_entry_target *)ipt_get_target(e); + + const struct nf_nat_ipv4_multi_range_compat *mr = + (struct nf_nat_ipv4_multi_range_compat *)(t->data); + const struct nf_nat_range *range = &mr->range[0]; + + uint32_t sip = ntohl(e->ip.src.s_addr); + uint32_t pip = ntohl(range->min_ip); + uint16_t proto = e->ip.proto; + + memset((void *) nat, 0, sizeof (nat_entry_t)); + + nat->src_addr = sip; + nat->trans_addr = pip; + + if (proto == P_TCP) + { + nat->flags = FAL_NAT_ENTRY_PROTOCOL_TCP; + } + else if (proto == P_UDP) + { + nat->flags = FAL_NAT_ENTRY_PROTOCOL_UDP; + } + else if (proto == P_ANY) + { + nat->flags = FAL_NAT_ENTRY_PROTOCOL_ANY; + } +} + +static int +nat_ipt_hw_add(nat_entry_t *nat) +{ + uint32_t index = 0; + if(nat_hw_add(nat) != 0) + { + return -1; + } + + hw_nat_ipt_seq[nat->entry_id] = snat_seq; + HNAT_PRINTK("###nat_ipt_hw_add hw_nat_ipt_seq[%d]:%d###\n", + nat->entry_id, snat_seq); + + hw_nat_pip_idx[nat->entry_id] = nat->trans_addr; + + if(nat_hw_prv_base_can_update()) + { + nat_hw_prv_base_set(nat->src_addr); + nat_hw_prv_base_update_disable(); + } + + if(nat_hw_pub_ip_add(nat->trans_addr, &index)!= 0) + { + return -1; + } + + return 0; +} + +static int +nat_ipt_hw_port_range_add(nat_entry_t *nat, + uint16_t port_start, uint16_t port_end, + struct xt_multiport *xport) +{ + unsigned int i; + + nat->flags |= FAL_NAT_ENTRY_PORT_CHECK; + + if(xport) + { + //some discontinuous ports + for (i = 0; i < xport->count; i++) + { + + nat->port_num = xport->ports[i]; + nat->port_range = 1; + + if(nat_ipt_hw_add(nat)) + { + HNAT_PRINTK("isis_nat_add(xport:%d) fail!\n", nat->port_num); + return -1; + } + + HNAT_PRINTK("(1)isis_nat_add(xport:%d) success\n", nat->port_num); + } + } + else + { + //one port or port range + uint16_t port_min, port_max; + + for (i = port_start; i <= port_end; i+= NAT_HW_PORT_RANGE_MAX) + { + port_min = i; + if((port_end-port_min)>(NAT_HW_PORT_RANGE_MAX-1)) + { + port_max = port_min+(NAT_HW_PORT_RANGE_MAX-1); + } + else + { + port_max = port_end; + } + + nat->port_num = port_min; + nat->port_range = (port_max - port_min + 1); + + if(nat_ipt_hw_add(nat)) + { + HNAT_PRINTK("isis_nat_add(range port:%d~%d) fail!\n", + port_min, port_max); + return -1; + } + + HNAT_PRINTK("(2)isis_nat_add(range port:%d~%d) success\n", port_min, port_max); + } + } + + return 0; +} + +static int +nat_ipt_check_none_matches(struct ipt_entry *e) +{ + nat_entry_t nat = {0}; + + nat_ipt_to_hw_entry(e, &nat); + + if(nat_ipt_hw_add(&nat) != 0) + { + HNAT_PRINTK("(1)isis_nat_add(none port)fail!\n"); + return -1; + } + + HNAT_PRINTK("(1)isis_nat_add(none port) success\n"); + + return 0; +} +static int +nat_ipt_check_matches(struct ipt_entry_match *m, + struct ipt_entry *e, + unsigned int *j) +{ + int ret = 0; + + nat_entry_t nat = {0}; + uint16_t port_start = 0, port_end = 0; + struct xt_multiport *xport = NULL; + + if(strcmp(m->u.user.name, "udp") == 0) + { + struct xt_udp *udpinfo = (struct xt_udp *)m->data; + port_start = udpinfo->spts[0]; + port_end = udpinfo->spts[1]; + + } + else if(strcmp(m->u.user.name, "tcp") == 0) + { + struct xt_tcp *tcpinfo = (struct xt_tcp *)m->data; + port_start = tcpinfo->spts[0]; + port_end = tcpinfo->spts[1]; + + } + else if(strcmp(m->u.user.name, "multiport") == 0) + { + struct xt_multiport xport_data = {0}; + struct ipt_entry_target *t = ipt_get_target(e); + xport = &xport_data; + + if(t->u.user.revision == 0) + { + xport = (struct xt_multiport *)m->data; + + } + else if(t->u.user.revision == 1) + { + const struct xt_multiport_v1 *xportv1 = + (struct xt_multiport_v1 *)m->data; + memcpy(xport->ports, xportv1->ports, sizeof(xportv1->ports)); + xport->count = xportv1->count; + } + + if(xport->flags != XT_MULTIPORT_SOURCE) + { + memset(xport->ports, 0, sizeof(xport->ports)); + } + + } + else + { + (*j)++ ; + HNAT_PRINTK("###no support matches m->u.user.name:%s\n", + m->u.user.name); + return -1; + } + + nat_ipt_to_hw_entry(e, &nat); + ret = nat_ipt_hw_port_range_add(&nat, port_start, port_end, xport); + + (*j)++ ; + + return ret; +} + +//check netmask !=32 +#define NAT_IPT_RULE_IS_FOR_NAPT(e) (((e)->ip.smsk.s_addr) != 0xffffffff) +#define NAT_IPT_RULE_IS_NONE_MATCHES(e) (((e)->target_offset) == \ + (sizeof(struct ipt_entry))) + +static int +nat_ipt_find_check_entry(struct ipt_entry *e, unsigned int underflow, + unsigned int *i) +{ + int ret = 0; + static uint16_t next_offset = 0; + struct ipt_entry_target *t = ipt_get_target(e); + + if(*i == 0) + { + snat_seq = 0; + next_offset = e->next_offset; + } + else + { + next_offset += e->next_offset; + } + + if (!strcmp(t->u.user.name, "SNAT")) + { + ++snat_seq; + + if(NAT_IPT_RULE_IS_FOR_NAPT(e)) + { + HNAT_PRINTK("this ipt rule only for HW napt offload\n"); + + } + else + { + /*for basic nat offload*/ + HNAT_PRINTK("[%d]next_offset:%d underflow:%d\n", + *i, next_offset, underflow); + + if(next_offset == underflow) //new one + { + + if(NAT_IPT_RULE_IS_NONE_MATCHES(e)) + { + /*none matches*/ + ret = nat_ipt_check_none_matches(e); + + } + else + { + unsigned int j = 0; + /*iterate matches*/ + ret = IPT_MATCH_ITERATE(e, nat_ipt_check_matches, e, &j); + } + } + } + } + + (*i)++ ; + + return ret; +} + +static void +nat_ipt_data_cleanup(void) +{ + if (gbuffer) + kfree(gbuffer); + + gbuffer = NULL; + + if (sbuffer) + kfree(sbuffer); + + sbuffer = NULL; +} + +static void +nat_ipt_data_init(void) +{ + /*alloc initial set buffer*/ + sbuffer = kmalloc(IPT_BUFFER_INIT_LEN, GFP_ATOMIC); + + if(sbuffer) + { + memset(sbuffer, 0, IPT_BUFFER_INIT_LEN); + slen = IPT_BUFFER_INIT_LEN; + } + else + { + HNAT_PRINTK("%s sbuffer memory allocate fail\n", __func__); + } + + /*alloc initial get buffer*/ + gbuffer = kmalloc(IPT_BUFFER_INIT_LEN, GFP_ATOMIC); + + if(gbuffer) + { + memset(gbuffer, 0, IPT_BUFFER_INIT_LEN); + glen = IPT_BUFFER_INIT_LEN; + } + else + { + HNAT_PRINTK("%s gbuffer memory allocate fail\n", __func__); + } + + + /*set initial underflow: nf_nat_rule.c*/ + memset(&old_replace, 0, sizeof (old_replace)); + + /*record ipt rule(SNAT) sequence for hw nat*/ + memset(hw_nat_ipt_seq, 0, NAT_HW_NUM); + + /*record ipt rule(SNAT) pubip index for hw nat*/ + memset(hw_nat_pip_idx, 0, NAT_HW_NUM); +} + +static void +nat_ipt_flush(void) +{ + napt_hw_flush(); + + nat_hw_flush(); + + nat_ipt_data_cleanup(); + nat_ipt_data_init(); + + HNAT_PRINTK("------(nat flush done)------\n"); +} + +static void +nat_ipt_add(struct ipt_replace ireplace) +{ + unsigned int i = 0; + + IPT_ENTRY_ITERATE(sbuffer, + ireplace.size, + nat_ipt_find_check_entry, + ireplace.underflow[NF_INET_POST_ROUTING], + &i); +} + +static int +nat_ipt_hook_type_check(struct ipt_replace ireplace) +{ + int ret = -1; + + HNAT_PRINTK("------we only support SNAT-----\n"); + + if((old_replace.underflow[NF_INET_POST_ROUTING]- + old_replace.hook_entry[NF_INET_POST_ROUTING]) != + (ireplace.underflow[NF_INET_POST_ROUTING]- + ireplace.hook_entry[NF_INET_POST_ROUTING])) + { + HNAT_PRINTK("------this is POSTROUTING(SNAT):yes!------\n"); + ret = 0; + + } + else if ((old_replace.underflow[NF_INET_PRE_ROUTING]- + old_replace.hook_entry[NF_INET_PRE_ROUTING]) != + (ireplace.underflow[NF_INET_PRE_ROUTING]- + ireplace.hook_entry[NF_INET_PRE_ROUTING])) + { + HNAT_PRINTK("------this is PREROUTING(DNAT):no!------\n"); + + } + else if((old_replace.underflow[NF_INET_LOCAL_OUT]- + old_replace.hook_entry[NF_INET_LOCAL_OUT]) != + (ireplace.underflow[NF_INET_LOCAL_OUT]- + ireplace.hook_entry[NF_INET_LOCAL_OUT])) + { + HNAT_PRINTK("------this is OUTPUT:no!------\n"); + + } + else + { + HNAT_PRINTK("------this is UNKNOW:no!------\n"); + + } + + return ret; +} + +static void +nat_ipt_rules_cp_from_user(void **buf, unsigned int *buf_len, + void __user *user, unsigned int user_len) +{ + if((*buf == 0) || (user == 0)) + { + return; + } + + if (*buf_len < user_len) + { + if(*buf) + { + kfree(*buf); + *buf = kmalloc(user_len, GFP_ATOMIC); + if(*buf == NULL) + { + HNAT_PRINTK("%s memory allocate fail\n", __func__); + return; + } + *buf_len = user_len; + } + } + HNAT_PRINTK("(2)nat_ipt_rules_cp_from_user *buf:%x user:%x user_len:%d\n", + (unsigned int)*buf, (unsigned int)user, user_len); + copy_from_user(*buf, user, user_len); + + return; +} + +static int +nat_ipt_set_ctl(struct sock *sk, int cmd, void __user * user, unsigned int len) +{ + struct ipt_replace ireplace; + + memset(&ireplace, 0, sizeof(ireplace)); + + HNAT_PRINTK("NAT set hook\n"); + + if (cmd != IPT_SO_SET_REPLACE) + goto normal; + + copy_from_user(&ireplace, user, sizeof (ireplace)); + + if (strcmp(ireplace.name, "nat") + || (ireplace.num_entries == ireplace.num_counters)) + { + HNAT_PRINTK("none NAT or no new entry %d", ireplace.num_entries); + goto normal; + } + + + if (ireplace.num_entries == NF_NAT_INIT_ENTRIES_NUM) + { + nat_ipt_flush(); + goto normal; + } + + if (nat_ipt_hook_type_check(ireplace) != 0) + { + goto normal; + } + + nat_ipt_rules_cp_from_user((void **)&sbuffer, &slen, + (user + sizeof (ireplace)), + ireplace.size); + + if (ireplace.num_entries > ireplace.num_counters) + { + nat_ipt_add(ireplace); + } + else + { + nat_ipt_del(ireplace); + } + +normal: + /*save old_replace for next hook type check*/ + old_replace = ireplace; + + return orgi_ipt_sockopts.set(sk, cmd, user, len); +} + +static int +nat_ipt_get_ctl(struct sock *sk, int cmd, void __user * user, int *len) +{ + int k = orgi_ipt_sockopts.get(sk, cmd, user, len); + + if (cmd == IPT_SO_GET_ENTRIES) + { + + struct ipt_get_entries entries; + + copy_from_user(&entries, user, sizeof (entries)); + + nat_ipt_rules_cp_from_user((void **)&gbuffer, &glen, + (user + sizeof (struct ipt_get_entries)), + (*len - sizeof (entries))); + } + return k; +} + + +void +nat_ipt_sockopts_replace(void) +{ + int ret = 0; + /*register an temp sockopts to find ipt_sockopts*/ + if((ret = nf_register_sockopt(&tmp_ipt_sockopts)) < 0) { + return; + } + list_for_each_entry(ipt_sockopts, tmp_ipt_sockopts.list.next, list) + { + if (ipt_sockopts->set_optmin == IPT_BASE_CTL) + { + nat_sockopts_init = 1; + break; + } + } + nf_unregister_sockopt(&tmp_ipt_sockopts); + if(!nat_sockopts_init) + return; + + /*save orginal ipt_sockopts*/ + orgi_ipt_sockopts = *ipt_sockopts; + + /*replace ipt_sockopts with our opts*/ + ipt_sockopts->set = nat_ipt_set_ctl; + ipt_sockopts->get = nat_ipt_get_ctl; +} + +static void +nat_ipt_sockopts_restore(void) +{ + ipt_sockopts->set = orgi_ipt_sockopts.set; + ipt_sockopts->get = orgi_ipt_sockopts.get; +} + +void +nat_ipt_helper_init(void) +{ + nat_ipt_sockopts_replace(); + nat_ipt_data_init(); +} + +void +nat_ipt_helper_exit(void) +{ + nat_ipt_sockopts_restore(); + nat_ipt_data_cleanup(); + nat_hw_flush(); +} + diff --git a/feeds/ipq807x/qca-ssdk/src/config b/feeds/ipq807x/qca-ssdk/src/config new file mode 100644 index 000000000..a7076f11c --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/config @@ -0,0 +1,345 @@ +#CPU=mips + +OS=linux + +ifeq ($(KVER),$(filter 3.14%,$(KVER))) +OS_VER=3_14 +endif + +ifeq ($(KVER),$(filter 4.4%,$(KVER))) +OS_VER=4_4 +endif + +ifeq ($(KVER),$(filter 4.1%,$(KVER))) +OS_VER=4_1 +endif + +ifeq ($(KVER),$(filter 4.9%,$(KVER))) +OS_VER=4_9 +endif + +ifeq ($(KVER),$(filter 5.4%,$(KVER))) +OS_VER=5_4 +endif + +ifeq ($(KVER), 3.4.0) +OS_VER=3_4 +endif + +ifeq ($(KVER), 3.18) +OS_VER=3_18 +endif + +ifeq ($(KVER), 3.18.21) +OS_VER=3_18 +endif + +ifeq ($(KVER), 3.4.103) +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 + +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-common -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) +ifeq ($(KVER), 3.4.0) + CPU_CFLAG=-D__LINUX_ARM_ARCH__=7 -DMODULE -fno-common -DCONFIG_MMU -D$(BOARD_NAME) +endif +ifeq ($(KVER), 3.4.103) + CPU_CFLAG=-D__LINUX_ARM_ARCH__=7 -DMODULE -fno-common -DCONFIG_MMU -D$(BOARD_NAME) +endif +ifeq ($(KVER), 3.18.21) + CPU_CFLAG=-D__LINUX_ARM_ARCH__=7 -DMODULE -fno-common -DCONFIG_MMU -D$(BOARD_NAME) +endif +ifeq ($(KVER),$(filter 4.4% 5.4%,$(KVER))) + CPU_CFLAG=-D__LINUX_ARM_ARCH__=7 -DMODULE -fno-common -DCONFIG_MMU -D$(BOARD_NAME) +endif + +ifeq ($(KVER),$(filter 3.14%,$(KVER))) + CPU_CFLAG= -DMODULE -nostdinc -D$(BOARD_NAME) -mlittle-endian -Wundef -Wstrict-prototypes -Wno-trigraphs -Werror -fno-strict-aliasing -fno-common -Wno-format-security -fno-delete-null-pointer-checks -O2 -fno-dwarf2-cfi-asm -mabi=aapcs-linux -mno-thumb-interwork -mfpu=vfp -funwind-tables -marm -D__LINUX_ARM_ARCH__=7 -march=armv7-a -msoft-float -Uarm -Wframe-larger-than=1024 -fno-stack-protector -Wno-unused-but-set-variable -fomit-frame-pointer -g -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -fconserve-stack -Werror=implicit-int -DCC_HAVE_ASM_GOTO -D"KBUILD_STR(s)=\#s" -D"KBUILD_BASENAME=KBUILD_STR(mem)" +endif + +ifeq ($(KVER),$(filter 4.9% 4.4% 5.4%,$(KVER))) + CPU_CFLAG= -DMODULE -nostdinc -D$(BOARD_NAME) -mlittle-endian -Wundef -Wstrict-prototypes -Wno-trigraphs -Werror -fno-strict-aliasing -fno-common -Wno-format-security -fno-delete-null-pointer-checks -O2 -fno-dwarf2-cfi-asm -mabi=aapcs-linux -mno-thumb-interwork -mfpu=vfp -funwind-tables -marm -D__LINUX_ARM_ARCH__=7 -march=armv7-a -msoft-float -Uarm -Wframe-larger-than=2048 -fno-stack-protector -Wno-unused-but-set-variable -fomit-frame-pointer -g -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -fconserve-stack -Werror=implicit-int -DCC_HAVE_ASM_GOTO -D"KBUILD_STR(s)=\#s" -D"KBUILD_BASENAME=KBUILD_STR(mem)" +endif + +ifeq ($(KVER),$(filter 3.18%,$(KVER))) + CPU_CFLAG= -DMODULE -nostdinc -D$(BOARD_NAME) -mlittle-endian -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Wno-format-security -fno-delete-null-pointer-checks -O2 -fno-dwarf2-cfi-asm -mabi=aapcs-linux -mno-thumb-interwork -mfpu=vfp -funwind-tables -marm -D__LINUX_ARM_ARCH__=7 -march=armv7-a -msoft-float -Uarm -Wframe-larger-than=1024 -fno-stack-protector -Wno-unused-but-set-variable -fomit-frame-pointer -g -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -fconserve-stack -Werror=implicit-int -DCC_HAVE_ASM_GOTO -D"KBUILD_STR(s)=\#s" -D"KBUILD_BASENAME=KBUILD_STR(mem)" +endif +endif + +ifeq ($(ARCH), arm64) +ifeq ($(KVER),$(filter 4.1% 4.4% 4.9% 5.4%,$(KVER))) + CPU_CFLAG= -DMODULE -Os -pipe -march=armv8-a -mcpu=cortex-a53+crypto -fno-caller-saves -fno-strict-aliasing -Werror -fno-common -Wno-format-security -Wno-pointer-sign -Wno-unused-but-set-variable -Wno-error=unused-result -mcmodel=large +endif +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 + +ifeq ($(SWCONFIG_FEATURE), disable) +SWCONFIG=FALSE +else +SWCONFIG=TRUE +endif + +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, DESS, HPPE, CPPE, MP and ALL_CHIP(ALL_CHIP means GARUDA, SHIVA, HORUS, ISIS, ISISC, DESS and HPPE CPPE MP) +ifndef CHIP_TYPE +CHIP_TYPE=ALL_CHIP +endif + +#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_SEC=TRUE +IN_PPPOE=TRUE +ifeq ($(HNAT_FEATURE), enable) +IN_NAT_HELPER=TRUE +else +IN_NAT_HELPER=FALSE +endif +ifeq ($(RFS_FEATURE), enable) +IN_RFS=TRUE +else +IN_RFS=FALSE +endif +IN_INTERFACECONTROL=TRUE +IN_MACBLOCK=FALSE +#The PHY CHIP defined according to the switch CHIP +ifeq (ALL_CHIP, $(CHIP_TYPE)) +IN_AQUANTIA_PHY=TRUE +IN_QCA803X_PHY=TRUE +IN_QCA808X_PHY=TRUE +IN_PHY_I2C_MODE=TRUE +IN_MALIBU_PHY=TRUE +IN_SFP_PHY=TRUE +IN_SFP=TRUE +else ifeq (HPPE, $(CHIP_TYPE)) +IN_AQUANTIA_PHY=TRUE +IN_QCA803X_PHY=TRUE +IN_QCA808X_PHY=TRUE +IN_PHY_I2C_MODE=TRUE +IN_SFP_PHY=TRUE +IN_MALIBU_PHY=TRUE +else ifeq (CPPE, $(CHIP_TYPE)) +IN_QCA808X_PHY=TRUE +IN_PHY_I2C_MODE=TRUE +IN_MALIBU_PHY=TRUE +else ifeq (DESS, $(CHIP_TYPE)) +IN_MALIBU_PHY=TRUE +else ifeq (MP, $(CHIP_TYPE)) +IN_QCA803X_PHY=TRUE +IN_QCA808X_PHY=TRUE +else +IN_QCA803X_PHY=FALSE +IN_QCA808X_PHY=FALSE +IN_AQUANTIA_PHY=FALSE +IN_MALIBU_PHY=FALSE +IN_SFP_PHY=FALSE +IN_SFP=FALSE +endif +ifeq ($(SFE_FEATURE), enable) +IN_SFE=TRUE +else +IN_SFE=FALSE +endif +#QCA808X PHY features +ifeq ($(IN_QCA808X_PHY), TRUE) +ifeq ($(PTP_FEATURE), enable) +IN_PTP=TRUE +else +IN_PTP=FALSE +endif +endif +#IN_PHY_I2C_MODE depends on IN_SFP_PHY +ifeq ($(IN_PHY_I2C_MODE), TRUE) +IN_SFP_PHY=TRUE +endif +ifneq (, $(filter HPPE CPPE ALL_CHIP, $(CHIP_TYPE))) +IN_FLOW=TRUE +IN_RSS_HASH=TRUE +IN_QM=TRUE +IN_VSI=TRUE +IN_CTRLPKT=TRUE +IN_SERVCODE=TRUE +IN_BM=TRUE +IN_SHAPER=TRUE +IN_POLICER=TRUE +endif +ifneq (, $(filter HPPE CPPE MP ALL_CHIP, $(CHIP_TYPE))) +IN_UNIPHY=TRUE +endif +#MINI SSDK enabled +ifeq ($(MINI_SSDK), enable) +IN_FDB_MINI=TRUE +IN_MISC_MINI=TRUE +IN_PORTCONTROL_MINI=TRUE +IN_QOS_MINI=TRUE +IN_COSMAP_MINI=TRUE +IN_PORTVLAN_MINI=TRUE +IN_VLAN_MINI=TRUE +IN_VSI_MINI=TRUE +IN_BM_MINI=TRUE +IN_SHAPER_MINI=TRUE +IN_POLICER_MINI=TRUE +IN_FLOW_MINI=TRUE +IN_QM_MINI=TRUE +IN_UNIPHY_MINI=TRUE +IN_IP_MINI=TRUE +IN_SFP=FALSE +#disable modules for MINI HPPE/CPPE +ifneq (, $(filter HPPE CPPE, $(CHIP_TYPE))) +IN_SERVCODE=FALSE +IN_PPPOE=FALSE +IN_NAT=FALSE +IN_COSMAP=FALSE +IN_RATE=FALSE +IN_IGMP=FALSE +IN_LEAKY=FALSE +IN_LED=FALSE +IN_INTERFACECONTROL=FALSE +endif +endif +ifneq ($(HK_CHIP), enable) +CHIP_TYPE=NONHK_CHIP +endif + +ifeq (MP, $(CHIP_TYPE)) +ifeq (disable, $(ISISC_ENABLE)) +IN_ACL=FALSE +IN_FDB=FALSE +IN_IGMP=FALSE +IN_LEAKY=FALSE +IN_LED=FALSE +IN_MIRROR=FALSE +IN_MISC=FALSE +IN_PORTVLAN=FALSE +IN_QOS=FALSE +IN_RATE=FALSE +IN_STP=FALSE +IN_VLAN=FALSE +IN_REDUCED_ACL=FALSE +IN_COSMAP=FALSE +IN_IP=FALSE +IN_NAT=FALSE +IN_FLOW=FALSE +IN_TRUNK=FALSE +IN_RSS_HASH=FALSE +IN_SEC=FALSE +IN_QM=FALSE +IN_PPPOE=FALSE +IN_VSI=FALSE +IN_CTRLPKT=FALSE +IN_SERVCODE=FALSE +IN_BM=FALSE +IN_SHAPER=FALSE +IN_POLICER=FALSE +endif +endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/adpt/adpt.h b/feeds/ipq807x/qca-ssdk/src/include/adpt/adpt.h new file mode 100644 index 000000000..28978270a --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/adpt/adpt.h @@ -0,0 +1,1598 @@ +/* + * 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. + */ + + +/** + * @defgroup + * @{ + */ +#ifndef _ADPT_H_ +#define _ADPT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "sw.h" +#include "fal_fdb.h" +#include "fal_portvlan.h" +#include "fal_ctrlpkt.h" +#include "fal_servcode.h" +#include "fal_rss_hash.h" +#include "fal_mib.h" +#include "fal_port_ctrl.h" +#include "fal_mirror.h" +#include "fal_trunk.h" +#include "fal_ip.h" +#include "fal_qm.h" +#include "fal_flow.h" +#include "ssdk_init.h" +#include "fal_type.h" +#include "fal_stp.h" +#include "fal_vsi.h" +#include "fal_pppoe.h" +#include "fal_sec.h" +#include "fal_acl.h" +#include "fal_qos.h" +#include "fal_shaper.h" +#include "fal_bm.h" +#include "fal_init.h" +#include "fal_policer.h" +#include "fal_misc.h" +#include "fal_ptp.h" +#include "fal_sfp.h" +#include "ssdk_plat.h" + +#define ADPT_DEV_ID_CHECK(dev_id) \ +do { \ + if (dev_id >= SW_MAX_NR_DEV) \ + return SW_OUT_OF_RANGE; \ +} while (0) + +#define ADPT_PORT_ID_CHECK(port_id) \ +do { \ + if (port_id >= SW_MAX_NR_PORT) \ + return SW_OUT_OF_RANGE; \ +} while (0) + +#define ADPT_NULL_POINT_CHECK(point) \ +do { \ + if (point == NULL) \ + return SW_BAD_PTR; \ +} while (0) + +typedef sw_error_t (*adpt_fdb_first_func)(a_uint32_t dev_id, fal_fdb_entry_t * entry); +typedef sw_error_t (*adpt_fdb_next_func)(a_uint32_t dev_id, fal_fdb_entry_t * entry); +typedef sw_error_t (*adpt_fdb_add_func)(a_uint32_t dev_id, const fal_fdb_entry_t * entry); +typedef sw_error_t (*adpt_fdb_age_time_set_func)(a_uint32_t dev_id, a_uint32_t * time); +typedef sw_error_t (*adpt_fdb_extend_next_func)(a_uint32_t dev_id, fal_fdb_op_t * option, + fal_fdb_entry_t * entry); +typedef sw_error_t (*adpt_fdb_learn_ctrl_get_func)(a_uint32_t dev_id, a_bool_t * enable); +typedef sw_error_t (*adpt_fdb_age_time_get_func)(a_uint32_t dev_id, a_uint32_t * time); +typedef sw_error_t (*adpt_port_fdb_learn_limit_set_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable, a_uint32_t cnt); +typedef sw_error_t (*adpt_fdb_port_add_func)(a_uint32_t dev_id, a_uint32_t fid, fal_mac_addr_t * addr, fal_port_t port_id); +typedef sw_error_t (*adpt_fdb_port_learn_set_func)(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); +typedef sw_error_t (*adpt_fdb_port_learn_get_func)(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable); +typedef sw_error_t (*adpt_fdb_port_newaddr_lrn_set_func)(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable, fal_fwd_cmd_t cmd); +typedef sw_error_t (*adpt_fdb_port_newaddr_lrn_get_func)(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable, fal_fwd_cmd_t *cmd); +typedef sw_error_t (*adpt_fdb_port_stamove_set_func)(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable, fal_fwd_cmd_t cmd); +typedef sw_error_t (*adpt_fdb_port_stamove_get_func)(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable, fal_fwd_cmd_t *cmd); +typedef sw_error_t (*adpt_port_fdb_learn_counter_get_func)(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * cnt); +typedef sw_error_t (*adpt_fdb_extend_first_func)(a_uint32_t dev_id, fal_fdb_op_t * option, + fal_fdb_entry_t * entry); +typedef sw_error_t (*adpt_fdb_transfer_func)(a_uint32_t dev_id, fal_port_t old_port, fal_port_t new_port, + a_uint32_t fid, fal_fdb_op_t * option); +typedef sw_error_t (*adpt_fdb_port_del_func)(a_uint32_t dev_id, a_uint32_t fid, fal_mac_addr_t * addr, fal_port_t port_id); +typedef sw_error_t (*adpt_fdb_find_func)(a_uint32_t dev_id, fal_fdb_entry_t * entry); +typedef sw_error_t (*adpt_fdb_learn_ctrl_set_func)(a_uint32_t dev_id, a_bool_t enable); +typedef sw_error_t (*adpt_port_fdb_learn_exceed_cmd_get_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t * cmd); +typedef sw_error_t (*adpt_fdb_del_by_port_func)(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t flag); +typedef sw_error_t (*adpt_port_fdb_learn_limit_get_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable, a_uint32_t * cnt); +typedef sw_error_t (*adpt_fdb_age_ctrl_set_func)(a_uint32_t dev_id, a_bool_t enable); +typedef sw_error_t (*adpt_fdb_del_by_mac_func)(a_uint32_t dev_id, const fal_fdb_entry_t *entry); +typedef sw_error_t (*adpt_fdb_iterate_func)(a_uint32_t dev_id, a_uint32_t * iterator, fal_fdb_entry_t * entry); +typedef sw_error_t (*adpt_port_fdb_learn_exceed_cmd_set_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t cmd); +typedef sw_error_t (*adpt_fdb_del_all_func)(a_uint32_t dev_id, a_uint32_t flag); +typedef sw_error_t (*adpt_fdb_age_ctrl_get_func)(a_uint32_t dev_id, a_bool_t * enable); +typedef sw_error_t (*adpt_fdb_port_maclimit_ctrl_set_func)(a_uint32_t dev_id, fal_port_t port_id, fal_maclimit_ctrl_t * maclimit_ctrl); +typedef sw_error_t (*adpt_fdb_port_maclimit_ctrl_get_func)(a_uint32_t dev_id, fal_port_t port_id, fal_maclimit_ctrl_t * maclimit_ctrl); +typedef sw_error_t (*adpt_fdb_del_by_fid_func)(a_uint32_t dev_id, a_uint16_t fid, a_uint32_t flag); + +typedef sw_error_t (*adpt_mib_cpukeep_get_func)(a_uint32_t dev_id, a_bool_t * enable); +typedef sw_error_t (*adpt_mib_cpukeep_set_func)(a_uint32_t dev_id, a_bool_t enable); +typedef sw_error_t (*adpt_get_mib_info_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info ); +typedef sw_error_t (*adpt_get_tx_mib_info_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info ); +typedef sw_error_t (*adpt_mib_status_set_func)(a_uint32_t dev_id, a_bool_t enable); +typedef sw_error_t (*adpt_mib_port_flush_counters_func)(a_uint32_t dev_id, fal_port_t port_id); +typedef sw_error_t (*adpt_mib_status_get_func)(a_uint32_t dev_id, a_bool_t * enable); +typedef sw_error_t (*adpt_get_rx_mib_info_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info ); +typedef sw_error_t (*adpt_get_xgmib_info_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_xgmib_info_t * mib_info ); +typedef sw_error_t (*adpt_get_tx_xgmib_info_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_xgmib_info_t * mib_info ); +typedef sw_error_t (*adpt_get_rx_xgmib_info_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_xgmib_info_t * mib_info ); + +typedef sw_error_t (*adpt_stp_port_state_get_func)(a_uint32_t dev_id, a_uint32_t st_id, + fal_port_t port_id, fal_stp_state_t * state); +typedef sw_error_t (*adpt_stp_port_state_set_func)(a_uint32_t dev_id, a_uint32_t st_id, + fal_port_t port_id, fal_stp_state_t state); + +typedef sw_error_t (*adpt_port_vlan_vsi_set_func)(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); +typedef sw_error_t (*adpt_port_vlan_vsi_get_func)(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); +typedef sw_error_t (*adpt_port_vsi_set_func)(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t vsi_id); +typedef sw_error_t (*adpt_port_vsi_get_func)(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t *vsi_id); +typedef sw_error_t (*adpt_vsi_stamove_set_func)(a_uint32_t dev_id, a_uint32_t vsi_id, fal_vsi_stamove_t *stamove); +typedef sw_error_t (*adpt_vsi_stamove_get_func)(a_uint32_t dev_id, a_uint32_t vsi_id, fal_vsi_stamove_t *stamove); +typedef sw_error_t (*adpt_vsi_newaddr_lrn_set_func)(a_uint32_t dev_id, a_uint32_t vsi_id, fal_vsi_newaddr_lrn_t *newaddr_lrn); +typedef sw_error_t (*adpt_vsi_newaddr_lrn_get_func)(a_uint32_t dev_id, a_uint32_t vsi_id, fal_vsi_newaddr_lrn_t *newaddr_lrn); +typedef sw_error_t (*adpt_vsi_member_set_func)(a_uint32_t dev_id, a_uint32_t vsi_id, fal_vsi_member_t *vsi_member); +typedef sw_error_t (*adpt_vsi_member_get_func)(a_uint32_t dev_id, a_uint32_t vsi_id, fal_vsi_member_t *vsi_member); +typedef sw_error_t (*adpt_vsi_counter_get_func)(a_uint32_t dev_id, a_uint32_t vsi_id, fal_vsi_counter_t *counter); +typedef sw_error_t (*adpt_vsi_counter_cleanup_func)(a_uint32_t dev_id, a_uint32_t vsi_id); + +// portctrl function. + +typedef sw_error_t (*adpt_port_local_loopback_get_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); +typedef sw_error_t (*adpt_port_autoneg_restart_func)(a_uint32_t dev_id, fal_port_t port_id); +typedef sw_error_t (*adpt_port_duplex_set_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t duplex); +typedef sw_error_t (*adpt_port_rxmac_status_get_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); +typedef sw_error_t (*adpt_port_cdt_func)(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mdi_pair, fal_cable_status_t * cable_status, + a_uint32_t * cable_len); +typedef sw_error_t (*adpt_port_txmac_status_set_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); +typedef sw_error_t (*adpt_port_combo_fiber_mode_set_func)(a_uint32_t dev_id, + a_uint32_t port_id, + fal_port_fiber_mode_t mode); +typedef sw_error_t (*adpt_port_combo_medium_status_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, + fal_port_medium_t * + medium); +typedef sw_error_t (*adpt_port_magic_frame_mac_set_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_mac_addr_t * mac); +typedef sw_error_t (*adpt_port_powersave_set_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); +typedef sw_error_t (*adpt_port_hibernate_set_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); +typedef sw_error_t (*adpt_port_max_frame_size_set_func)(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t max_frame); +typedef sw_error_t (*adpt_port_8023az_get_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); +typedef sw_error_t (*adpt_port_rxfc_status_get_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); +typedef sw_error_t (*adpt_port_txfc_status_get_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); +typedef sw_error_t (*adpt_port_remote_loopback_set_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); +typedef sw_error_t (*adpt_port_flowctrl_set_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); +typedef sw_error_t (*adpt_port_mru_set_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_mru_ctrl_t *ctrl); +typedef sw_error_t (*adpt_port_autoneg_status_get_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status); +typedef sw_error_t (*adpt_port_txmac_status_get_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); +typedef sw_error_t (*adpt_port_mdix_get_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_port_mdix_mode_t * mode); +typedef sw_error_t (*adpt_ports_link_status_get_func)(a_uint32_t dev_id, a_uint32_t * status); +typedef sw_error_t (*adpt_port_mac_loopback_set_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); +typedef sw_error_t (*adpt_port_phy_id_get_func)(a_uint32_t dev_id, fal_port_t port_id, + a_uint16_t * org_id, a_uint16_t * rev_id); +typedef sw_error_t (*adpt_port_mru_get_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_mru_ctrl_t *ctrl); +typedef sw_error_t (*adpt_port_power_on_func)(a_uint32_t dev_id, fal_port_t port_id); +typedef sw_error_t (*adpt_port_speed_set_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t speed); +typedef sw_error_t (*adpt_port_interface_mode_get_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_port_interface_mode_t * mode); +typedef sw_error_t (*adpt_port_duplex_get_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t * pduplex); +typedef sw_error_t (*adpt_port_autoneg_adv_get_func)(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * autoadv); +typedef sw_error_t (*adpt_port_mdix_status_get_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_port_mdix_status_t * mode); +typedef sw_error_t (*adpt_port_mtu_set_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_mtu_ctrl_t *ctrl); +typedef sw_error_t (*adpt_port_link_status_get_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status); +typedef sw_error_t (*adpt_port_8023az_set_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); +typedef sw_error_t (*adpt_port_powersave_get_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); +typedef sw_error_t (*adpt_port_combo_prefer_medium_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, + fal_port_medium_t * + medium); +typedef sw_error_t (*adpt_port_max_frame_size_get_func)(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t *max_frame); +typedef sw_error_t (*adpt_port_combo_prefer_medium_set_func)(a_uint32_t dev_id, + a_uint32_t port_id, + fal_port_medium_t medium); +typedef sw_error_t (*adpt_port_power_off_func)(a_uint32_t dev_id, fal_port_t port_id); +typedef sw_error_t (*adpt_port_txfc_status_set_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); +typedef sw_error_t (*adpt_port_counter_set_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); +typedef sw_error_t (*adpt_port_combo_fiber_mode_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, + fal_port_fiber_mode_t * mode); +typedef sw_error_t (*adpt_port_local_loopback_set_func)(a_uint32_t dev_id, + fal_port_t port_id, + a_bool_t enable); +typedef sw_error_t (*adpt_port_wol_status_set_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); +typedef sw_error_t (*adpt_port_magic_frame_mac_get_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_mac_addr_t * mac); +typedef sw_error_t (*adpt_port_flowctrl_get_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); +typedef sw_error_t (*adpt_port_rxmac_status_set_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); +typedef sw_error_t (*adpt_port_counter_get_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); +typedef sw_error_t (*adpt_port_interface_mode_set_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_port_interface_mode_t mode); +typedef sw_error_t (*adpt_port_mac_loopback_get_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); +typedef sw_error_t (*adpt_port_hibernate_get_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); +typedef sw_error_t (*adpt_port_autoneg_adv_set_func)(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t autoadv); +typedef sw_error_t (*adpt_port_remote_loopback_get_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); +typedef sw_error_t (*adpt_port_counter_show_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_port_counter_info_t * counter_info); +typedef sw_error_t (*adpt_port_autoneg_enable_func)(a_uint32_t dev_id, fal_port_t port_id); +typedef sw_error_t (*adpt_port_mtu_get_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_mtu_ctrl_t *ctrl); +typedef sw_error_t (*adpt_port_interface_mode_status_get_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_port_interface_mode_t * mode); +typedef sw_error_t (*adpt_port_reset_func)(a_uint32_t dev_id, fal_port_t port_id); +typedef sw_error_t (*adpt_port_rxfc_status_set_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); +typedef sw_error_t (*adpt_port_speed_get_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t * pspeed); +typedef sw_error_t (*adpt_port_mdix_set_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_port_mdix_mode_t mode); +typedef sw_error_t (*adpt_port_wol_status_get_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); +typedef sw_error_t (*adpt_port_source_filter_get_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); +typedef sw_error_t (*adpt_port_source_filter_set_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); +typedef sw_error_t (*adpt_port_mux_mac_type_set_func)(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mode0, a_uint32_t mode1, a_uint32_t mode2); +typedef sw_error_t (*adpt_port_mac_speed_set_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t speed); +typedef sw_error_t (*adpt_port_mac_duplex_set_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t duplex); +typedef sw_error_t (*adpt_port_polling_sw_sync_func)(struct qca_phy_priv *priv); + +typedef sw_error_t (*adpt_port_bridge_txmac_set_func)(a_uint32_t dev_id, + fal_port_t port_id, a_bool_t enable); + +typedef sw_error_t (*adpt_port_interface_mode_apply_func)(a_uint32_t dev_id); + +typedef sw_error_t (*adpt_port_interface_3az_status_set_func)(a_uint32_t dev_id, + a_uint32_t port_id, a_bool_t enable); +typedef sw_error_t (*adpt_port_interface_3az_status_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, a_bool_t * enable); +typedef sw_error_t (*adpt_port_flowctrl_forcemode_set_func) (a_uint32_t dev_id, + fal_port_t port_id, a_bool_t enable); +typedef sw_error_t (*adpt_port_flowctrl_forcemode_get_func) (a_uint32_t dev_id, + fal_port_t port_id, a_bool_t * enable); +typedef sw_error_t (*adpt_port_promisc_mode_set_func)(a_uint32_t dev_id, + fal_port_t port_id, a_bool_t enable); +typedef sw_error_t (*adpt_port_promisc_mode_get_func)(a_uint32_t dev_id, + fal_port_t port_id, a_bool_t *enable); +typedef sw_error_t (*adpt_port_interface_eee_cfg_set_func)(a_uint32_t dev_id, + fal_port_t port_id, fal_port_eee_cfg_t *port_eee_cfg); +typedef sw_error_t (*adpt_port_interface_eee_cfg_get_func)(a_uint32_t dev_id, + fal_port_t port_id, fal_port_eee_cfg_t *port_eee_cfg); +typedef sw_error_t (*adpt_port_source_filter_config_set_func)(a_uint32_t dev_id, + fal_port_t port_id, fal_src_filter_config_t *src_filter_config); +typedef sw_error_t (*adpt_port_source_filter_config_get_func)(a_uint32_t dev_id, + fal_port_t port_id, fal_src_filter_config_t *src_filter_config); +typedef sw_error_t (*adpt_switch_port_loopback_set_func)(a_uint32_t dev_id, + fal_port_t port_id, fal_loopback_config_t *loopback_cfg); +typedef sw_error_t (*adpt_switch_port_loopback_get_func)(a_uint32_t dev_id, + fal_port_t port_id, fal_loopback_config_t *loopback_cfg); +typedef sw_error_t (*adpt_port_netdev_notify_func)(struct qca_phy_priv *priv, + a_uint32_t port_id); +typedef sw_error_t (*adpt_port_phy_status_get_func)(a_uint32_t dev_id, + fal_port_t port_id, struct port_phy_status *phy_status); +// mirror +typedef sw_error_t (*adpt_mirr_port_in_set_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); +typedef sw_error_t (*adpt_mirr_port_in_get_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); +typedef sw_error_t (*adpt_mirr_port_eg_set_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); +typedef sw_error_t (*adpt_mirr_port_eg_get_func)(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); +typedef sw_error_t (*adpt_mirr_analysis_port_set_func)(a_uint32_t dev_id, fal_port_t port_id); +typedef sw_error_t (*adpt_mirr_analysis_port_get_func)(a_uint32_t dev_id, fal_port_t * port_id); +typedef sw_error_t (*adpt_mirr_analysis_config_set_func)(a_uint32_t dev_id, fal_mirr_direction_t direction, + fal_mirr_analysis_config_t * config); +typedef sw_error_t (*adpt_mirr_analysis_config_get_func)(a_uint32_t dev_id, fal_mirr_direction_t direction, + fal_mirr_analysis_config_t * config); + +//rss hash +typedef sw_error_t (*adpt_rss_hash_config_set_func)(a_uint32_t dev_id, fal_rss_hash_mode_t mode, fal_rss_hash_config_t * config); +typedef sw_error_t (*adpt_rss_hash_config_get_func)(a_uint32_t dev_id, fal_rss_hash_mode_t mode, fal_rss_hash_config_t * config); + +//trunk +typedef sw_error_t (*adpt_trunk_fail_over_en_get_func)(a_uint32_t dev_id, a_bool_t * fail_over); +typedef sw_error_t (*adpt_trunk_hash_mode_get_func)(a_uint32_t dev_id, a_uint32_t * hash_mode); +typedef sw_error_t (*adpt_trunk_group_get_func)(a_uint32_t dev_id, a_uint32_t trunk_id, + a_bool_t * enable, fal_pbmp_t * member); +typedef sw_error_t (*adpt_trunk_group_set_func)(a_uint32_t dev_id, a_uint32_t trunk_id, + a_bool_t enable, fal_pbmp_t member); +typedef sw_error_t (*adpt_trunk_fail_over_en_set_func)(a_uint32_t dev_id, a_bool_t fail_over); +typedef sw_error_t (*adpt_trunk_hash_mode_set_func)(a_uint32_t dev_id, a_uint32_t hash_mode); + +typedef sw_error_t (*adpt_ip_network_route_get_func)(a_uint32_t dev_id, + a_uint32_t index, a_uint8_t type, + fal_network_route_entry_t *entry); +typedef sw_error_t (*adpt_ip_network_route_add_func)(a_uint32_t dev_id, + a_uint32_t index, + fal_network_route_entry_t *entry); +typedef sw_error_t (*adpt_ip_network_route_del_func)(a_uint32_t dev_id, + a_uint32_t index, + a_uint8_t type); +typedef sw_error_t (*adpt_ip_host_add_func)( + a_uint32_t dev_id, fal_host_entry_t * host_entry); +typedef sw_error_t (*adpt_ip_vsi_sg_cfg_get_func)( + a_uint32_t dev_id, a_uint32_t vsi, + fal_sg_cfg_t *sg_cfg); +typedef sw_error_t (*adpt_ip_pub_addr_set_func)( + a_uint32_t dev_id, a_uint32_t index, + fal_ip_pub_addr_t *entry); +typedef sw_error_t (*adpt_ip_pub_addr_get_func)( + a_uint32_t dev_id, a_uint32_t index, + fal_ip_pub_addr_t *entry); +typedef sw_error_t (*adpt_ip_port_sg_cfg_set_func)( + a_uint32_t dev_id, fal_port_t port_id, + fal_sg_cfg_t *sg_cfg); +typedef sw_error_t (*adpt_ip_port_intf_get_func)( + a_uint32_t dev_id, fal_port_t port_id, fal_intf_id_t *id); +typedef sw_error_t (*adpt_ip_vsi_arp_sg_cfg_set_func)( + a_uint32_t dev_id, a_uint32_t vsi, + fal_arp_sg_cfg_t *arp_sg_cfg); +typedef sw_error_t (*adpt_ip_port_intf_set_func)( + a_uint32_t dev_id, fal_port_t port_id, fal_intf_id_t *id); +typedef sw_error_t (*adpt_ip_vsi_sg_cfg_set_func)( + a_uint32_t dev_id, a_uint32_t vsi, + fal_sg_cfg_t *sg_cfg); +typedef sw_error_t (*adpt_ip_host_next_func)( + a_uint32_t dev_id, a_uint32_t next_mode, + fal_host_entry_t * host_entry); +typedef sw_error_t (*adpt_ip_port_macaddr_set_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_macaddr_entry_t *macaddr); +typedef sw_error_t (*adpt_ip_vsi_intf_get_func)( + a_uint32_t dev_id, a_uint32_t vsi, fal_intf_id_t *id); +typedef sw_error_t (*adpt_ip_port_sg_cfg_get_func)( + a_uint32_t dev_id, fal_port_t port_id, + fal_sg_cfg_t *sg_cfg); +typedef sw_error_t (*adpt_ip_intf_get_func)( + a_uint32_t dev_id, + a_uint32_t index, + fal_intf_entry_t *entry); +typedef sw_error_t (*adpt_ip_host_del_func)( + a_uint32_t dev_id, a_uint32_t del_mode, + fal_host_entry_t * host_entry); +typedef sw_error_t (*adpt_ip_route_mismatch_get_func)( + a_uint32_t dev_id, fal_fwd_cmd_t *cmd); +typedef sw_error_t (*adpt_ip_vsi_arp_sg_cfg_get_func)( + a_uint32_t dev_id, a_uint32_t vsi, + fal_arp_sg_cfg_t *arp_sg_cfg); +typedef sw_error_t (*adpt_ip_port_arp_sg_cfg_set_func)( + a_uint32_t dev_id, fal_port_t port_id, + fal_arp_sg_cfg_t *arp_sg_cfg); +typedef sw_error_t (*adpt_ip_vsi_mc_mode_set_func)( + a_uint32_t dev_id, a_uint32_t vsi, + fal_mc_mode_cfg_t *cfg); +typedef sw_error_t (*adpt_ip_vsi_intf_set_func)( + a_uint32_t dev_id, a_uint32_t vsi, fal_intf_id_t *id); +typedef sw_error_t (*adpt_ip_nexthop_get_func)(a_uint32_t dev_id, + a_uint32_t index, fal_ip_nexthop_t *entry); +typedef sw_error_t (*adpt_ip_route_mismatch_set_func)( + a_uint32_t dev_id, fal_fwd_cmd_t cmd); +typedef sw_error_t (*adpt_ip_host_get_func)( + a_uint32_t dev_id, a_uint32_t get_mode, + fal_host_entry_t * host_entry); +typedef sw_error_t (*adpt_ip_intf_set_func)( + a_uint32_t dev_id, + a_uint32_t index, + fal_intf_entry_t *entry); +typedef sw_error_t (*adpt_ip_vsi_mc_mode_get_func)( + a_uint32_t dev_id, + a_uint32_t vsi, + fal_mc_mode_cfg_t *cfg); +typedef sw_error_t (*adpt_ip_port_macaddr_get_func)( + a_uint32_t dev_id, fal_port_t port_id, + fal_macaddr_entry_t *macaddr); +typedef sw_error_t (*adpt_ip_port_arp_sg_cfg_get_func)( + a_uint32_t dev_id, fal_port_t port_id, + fal_arp_sg_cfg_t *arp_sg_cfg); +typedef sw_error_t (*adpt_ip_nexthop_set_func)(a_uint32_t dev_id, + a_uint32_t index, fal_ip_nexthop_t *entry); +typedef sw_error_t (*adpt_ip_global_ctrl_get_func)(a_uint32_t dev_id, + fal_ip_global_cfg_t *cfg); +typedef sw_error_t (*adpt_ip_global_ctrl_set_func)(a_uint32_t dev_id, + fal_ip_global_cfg_t *cfg); + +typedef sw_error_t (*adpt_flow_global_cfg_get_func)( + a_uint32_t dev_id, + fal_flow_global_cfg_t *cfg); +typedef sw_error_t (*adpt_flow_global_cfg_set_func)( + a_uint32_t dev_id, + fal_flow_global_cfg_t *cfg); +typedef sw_error_t (*adpt_flow_host_add_func)( + a_uint32_t dev_id, + a_uint32_t add_mode, + fal_flow_host_entry_t *flow_host_entry); +typedef sw_error_t (*adpt_flow_entry_get_func)( + a_uint32_t dev_id, + a_uint32_t get_mode, + fal_flow_entry_t *flow_entry); +typedef sw_error_t (*adpt_flow_entry_del_func)( + a_uint32_t dev_id, + a_uint32_t del_mode, + fal_flow_entry_t *flow_entry); +typedef sw_error_t (*adpt_flow_entry_next_func)( + a_uint32_t dev_id, + a_uint32_t next_mode, + fal_flow_entry_t *flow_entry); +typedef sw_error_t (*adpt_flow_status_get_func)( + a_uint32_t dev_id, a_bool_t *enable); +typedef sw_error_t (*adpt_flow_ctrl_set_func)( + a_uint32_t dev_id, + fal_flow_pkt_type_t type, + fal_flow_direction_t dir, + fal_flow_mgmt_t *ctrl); +typedef sw_error_t (*adpt_flow_age_timer_get_func)( + a_uint32_t dev_id, fal_flow_age_timer_t *age_timer); +typedef sw_error_t (*adpt_flow_status_set_func)( + a_uint32_t dev_id, a_bool_t enable); +typedef sw_error_t (*adpt_flow_host_get_func)( + a_uint32_t dev_id, + a_uint32_t get_mode, + fal_flow_host_entry_t *flow_host_entry); +typedef sw_error_t (*adpt_flow_host_del_func)( + a_uint32_t dev_id, + a_uint32_t del_mode, + fal_flow_host_entry_t *flow_host_entry); +typedef sw_error_t (*adpt_flow_ctrl_get_func)( + a_uint32_t dev_id, + fal_flow_pkt_type_t type, + fal_flow_direction_t dir, + fal_flow_mgmt_t *ctrl); +typedef sw_error_t (*adpt_flow_age_timer_set_func)( + a_uint32_t dev_id, fal_flow_age_timer_t *age_timer); +typedef sw_error_t (*adpt_flow_entry_add_func)( + a_uint32_t dev_id, + a_uint32_t add_mode, /*index or hash*/ + fal_flow_entry_t *flow_entry); +typedef sw_error_t (*adpt_ucast_hash_map_set_func)( + a_uint32_t dev_id, + a_uint8_t profile, + a_uint8_t rss_hash, + a_int8_t queue_hash); +typedef sw_error_t (*adpt_ac_dynamic_threshold_get_func)( + a_uint32_t dev_id, + a_uint32_t queue_id, + fal_ac_dynamic_threshold_t *cfg); +typedef sw_error_t (*adpt_ucast_queue_base_profile_get_func)( + a_uint32_t dev_id, + fal_ucast_queue_dest_t *queue_dest, + a_uint32_t *queue_base, a_uint8_t *profile); +typedef sw_error_t (*adpt_port_mcast_priority_class_get_func)( + a_uint32_t dev_id, + fal_port_t port, + a_uint8_t priority, + a_uint8_t *queue_class); +typedef sw_error_t (*adpt_ac_dynamic_threshold_set_func)( + a_uint32_t dev_id, + a_uint32_t queue_id, + fal_ac_dynamic_threshold_t *cfg); +typedef sw_error_t (*adpt_ac_prealloc_buffer_set_func)( + a_uint32_t dev_id, + fal_ac_obj_t *obj, + a_uint16_t num); +typedef sw_error_t (*adpt_ucast_default_hash_get_func)( + a_uint32_t dev_id, + a_uint8_t *hash_value); +typedef sw_error_t (*adpt_ucast_default_hash_set_func)( + a_uint32_t dev_id, + a_uint8_t hash_value); +typedef sw_error_t (*adpt_ac_queue_group_get_func)( + a_uint32_t dev_id, + a_uint32_t queue_id, + a_uint8_t *group_id); +typedef sw_error_t (*adpt_ac_ctrl_get_func)( + a_uint32_t dev_id, + fal_ac_obj_t *obj, + fal_ac_ctrl_t *cfg); +typedef sw_error_t (*adpt_ac_prealloc_buffer_get_func)( + a_uint32_t dev_id, + fal_ac_obj_t *obj, + a_uint16_t *num); +typedef sw_error_t (*adpt_port_mcast_priority_class_set_func)( + a_uint32_t dev_id, + fal_port_t port, + a_uint8_t priority, + a_uint8_t queue_class); +typedef sw_error_t (*adpt_ucast_hash_map_get_func)( + a_uint32_t dev_id, + a_uint8_t profile, + a_uint8_t rss_hash, + a_int8_t *queue_hash); +typedef sw_error_t (*adpt_ac_static_threshold_set_func)( + a_uint32_t dev_id, + fal_ac_obj_t *obj, + fal_ac_static_threshold_t *cfg); +typedef sw_error_t (*adpt_ac_queue_group_set_func)( + a_uint32_t dev_id, + a_uint32_t queue_id, + a_uint8_t group_id); +typedef sw_error_t (*adpt_ac_group_buffer_get_func)( + a_uint32_t dev_id, + a_uint8_t group_id, + fal_ac_group_buffer_t *cfg); +typedef sw_error_t (*adpt_mcast_cpu_code_class_get_func)( + a_uint32_t dev_id, + a_uint8_t cpu_code, + a_uint8_t *queue_class); +typedef sw_error_t (*adpt_ac_ctrl_set_func)( + a_uint32_t dev_id, + fal_ac_obj_t *obj, + fal_ac_ctrl_t *cfg); +typedef sw_error_t (*adpt_ucast_priority_class_get_func)( + a_uint32_t dev_id, + a_uint8_t profile, + a_uint8_t priority, + a_uint8_t *class); +typedef sw_error_t (*adpt_queue_flush_func)( + a_uint32_t dev_id, + fal_port_t port, + a_uint16_t queue_id); +typedef sw_error_t (*adpt_mcast_cpu_code_class_set_func)( + a_uint32_t dev_id, + a_uint8_t cpu_code, + a_uint8_t queue_class); +typedef sw_error_t (*adpt_ucast_priority_class_set_func)( + a_uint32_t dev_id, + a_uint8_t profile, + a_uint8_t priority, + a_uint8_t class); +typedef sw_error_t (*adpt_ac_static_threshold_get_func)( + a_uint32_t dev_id, + fal_ac_obj_t *obj, + fal_ac_static_threshold_t *cfg); +typedef sw_error_t (*adpt_ucast_queue_base_profile_set_func)( + a_uint32_t dev_id, + fal_ucast_queue_dest_t *queue_dest, + a_uint32_t queue_base, a_uint8_t profile); +typedef sw_error_t (*adpt_ac_group_buffer_set_func)( + a_uint32_t dev_id, + a_uint8_t group_id, + fal_ac_group_buffer_t *cfg); +typedef sw_error_t (*adpt_queue_counter_cleanup_func)( + a_uint32_t dev_id, a_uint32_t queue_id); +typedef sw_error_t (*adpt_queue_counter_get_func)( + a_uint32_t dev_id, a_uint32_t queue_id, + fal_queue_stats_t *info); +typedef sw_error_t (*adpt_queue_counter_ctrl_get_func)( + a_uint32_t dev_id, a_bool_t *cnt_en); +typedef sw_error_t (*adpt_queue_counter_ctrl_set_func)( + a_uint32_t dev_id, a_bool_t cnt_en); +typedef sw_error_t (*adpt_qm_enqueue_ctrl_set_func)( + a_uint32_t dev_id, a_uint32_t queue_id, a_bool_t enable); +typedef sw_error_t (*adpt_qm_enqueue_ctrl_get_func)( + a_uint32_t dev_id, a_uint32_t queue_id, a_bool_t *enable); +typedef sw_error_t (*adpt_qm_port_source_profile_set_func)( + a_uint32_t dev_id, fal_port_t port, a_uint32_t src_profile); +typedef sw_error_t (*adpt_qm_port_source_profile_get_func)( + a_uint32_t dev_id, fal_port_t port, a_uint32_t *src_profile); + + +/*portvlan module begin*/ +typedef sw_error_t (*adpt_global_qinq_mode_set_func)(a_uint32_t dev_id, fal_global_qinq_mode_t *mode); +typedef sw_error_t (*adpt_global_qinq_mode_get_func)(a_uint32_t dev_id, fal_global_qinq_mode_t *mode); +typedef sw_error_t (*adpt_tpid_set_func)(a_uint32_t dev_id, fal_tpid_t *tpid); +typedef sw_error_t (*adpt_tpid_get_func)(a_uint32_t dev_id, fal_tpid_t *tpid); +typedef sw_error_t (*adpt_egress_tpid_set_func)(a_uint32_t dev_id, fal_tpid_t *tpid); +typedef sw_error_t (*adpt_egress_tpid_get_func)(a_uint32_t dev_id, fal_tpid_t *tpid); +typedef sw_error_t (*adpt_port_qinq_mode_set_func)(a_uint32_t dev_id, fal_port_t port_id, fal_port_qinq_role_t *mode); +typedef sw_error_t (*adpt_port_qinq_mode_get_func)(a_uint32_t dev_id, fal_port_t port_id, fal_port_qinq_role_t *mode); +typedef sw_error_t (*adpt_port_ingress_vlan_filter_set_func)(a_uint32_t dev_id, fal_port_t port_id, fal_ingress_vlan_filter_t *filter); +typedef sw_error_t (*adpt_port_ingress_vlan_filter_get_func)(a_uint32_t dev_id, fal_port_t port_id, fal_ingress_vlan_filter_t *filter); +typedef sw_error_t (*adpt_port_default_vlantag_set_func)(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); +typedef sw_error_t (*adpt_port_default_vlantag_get_func)(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); +typedef sw_error_t (*adpt_port_tag_propagation_set_func)(a_uint32_t dev_id, fal_port_t port_id, fal_port_vlan_direction_t direction, + fal_vlantag_propagation_t *prop); +typedef sw_error_t (*adpt_port_tag_propagation_get_func)(a_uint32_t dev_id, fal_port_t port_id, fal_port_vlan_direction_t direction, + fal_vlantag_propagation_t *prop); +typedef sw_error_t (*adpt_port_vlantag_egmode_set_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_vlantag_egress_mode_t *port_egvlanmode); +typedef sw_error_t (*adpt_port_vlantag_egmode_get_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_vlantag_egress_mode_t *port_egvlanmode); +typedef sw_error_t (*adpt_port_vlan_xlt_miss_cmd_get_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t *cmd); +typedef sw_error_t (*adpt_port_vlan_xlt_miss_cmd_set_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t cmd); +typedef sw_error_t (*adpt_port_vlan_trans_add_func)(a_uint32_t dev_id, fal_port_t port_id, fal_vlan_trans_entry_t *entry); +typedef sw_error_t (*adpt_port_vlan_trans_get_func)(a_uint32_t dev_id, fal_port_t port_id, fal_vlan_trans_entry_t *entry); +typedef sw_error_t (*adpt_port_vlan_trans_del_func)(a_uint32_t dev_id, fal_port_t port_id, fal_vlan_trans_entry_t *entry); +typedef sw_error_t (*adpt_port_vlan_trans_iterate_func)(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * iterator, fal_vlan_trans_entry_t *entry); +typedef sw_error_t (*adpt_port_vsi_egmode_set_func)(a_uint32_t dev_id, a_uint32_t vsi, a_uint32_t port_id, fal_pt_1q_egmode_t egmode); +typedef sw_error_t (*adpt_port_vsi_egmode_get_func)(a_uint32_t dev_id, a_uint32_t vsi, a_uint32_t port_id, fal_pt_1q_egmode_t * egmode); +typedef sw_error_t (*adpt_port_vlantag_vsi_egmode_enable_set_func)(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); +typedef sw_error_t (*adpt_port_vlantag_vsi_egmode_enable_get_func)(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); +typedef sw_error_t (*adpt_qinq_mode_set_func)(a_uint32_t dev_id, fal_qinq_mode_t mode); +typedef sw_error_t (*adpt_qinq_mode_get_func)(a_uint32_t dev_id, fal_qinq_mode_t * mode); +typedef sw_error_t (*adpt_port_qinq_role_set_func)(a_uint32_t dev_id, fal_port_t port_id, fal_qinq_port_role_t role); +typedef sw_error_t (*adpt_port_qinq_role_get_func)(a_uint32_t dev_id, fal_port_t port_id, fal_qinq_port_role_t * role); +typedef sw_error_t (*adpt_port_invlan_mode_set_func)(a_uint32_t dev_id, fal_port_t port_id, fal_pt_invlan_mode_t mode); +typedef sw_error_t (*adpt_port_invlan_mode_get_func)(a_uint32_t dev_id, fal_port_t port_id, fal_pt_invlan_mode_t * mode); +typedef sw_error_t (*adpt_port_vlan_trans_adv_add_func)(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); +typedef sw_error_t (*adpt_port_vlan_trans_adv_del_func)(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); +typedef sw_error_t (*adpt_port_vlan_trans_adv_getfirst_func)(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); +typedef sw_error_t (*adpt_port_vlan_trans_adv_getnext_func)(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); +typedef sw_error_t (*adpt_port_vlan_counter_get_func)(a_uint32_t dev_id, a_uint32_t cnt_index, fal_port_vlan_counter_t * counter); +typedef sw_error_t (*adpt_port_vlan_counter_cleanup_func)(a_uint32_t dev_id, a_uint32_t cnt_index); +typedef sw_error_t (*adpt_portvlan_member_add_func)(a_uint32_t dev_id, fal_port_t port_id, fal_port_t mem_port_id); +typedef sw_error_t (*adpt_portvlan_member_del_func)(a_uint32_t dev_id, fal_port_t port_id, fal_port_t mem_port_id); +typedef sw_error_t (*adpt_portvlan_member_update_func)(a_uint32_t dev_id, fal_port_t port_id, fal_pbmp_t mem_port_map); +typedef sw_error_t (*adpt_portvlan_member_get_func)(a_uint32_t dev_id, fal_port_t port_id, fal_pbmp_t * mem_port_map); +/*portvlan module end*/ + +/*ctrlpkt module end*/ +typedef sw_error_t (*adpt_mgmtctrl_ethtype_profile_set_func)(a_uint32_t dev_id, a_uint32_t profile_id, a_uint32_t ethtype); +typedef sw_error_t (*adpt_mgmtctrl_ethtype_profile_get_func)(a_uint32_t dev_id, a_uint32_t profile_id, a_uint32_t * ethtype); +typedef sw_error_t (*adpt_mgmtctrl_rfdb_profile_set_func)(a_uint32_t dev_id, a_uint32_t profile_id, fal_mac_addr_t *addr); +typedef sw_error_t (*adpt_mgmtctrl_rfdb_profile_get_func)(a_uint32_t dev_id, a_uint32_t profile_id, fal_mac_addr_t *addr); +typedef sw_error_t (*adpt_mgmtctrl_ctrlpkt_profile_add_func)(a_uint32_t dev_id, fal_ctrlpkt_profile_t *ctrlpkt); +typedef sw_error_t (*adpt_mgmtctrl_ctrlpkt_profile_del_func)(a_uint32_t dev_id, fal_ctrlpkt_profile_t *ctrlpkt); +typedef sw_error_t (*adpt_mgmtctrl_ctrlpkt_profile_getfirst_func)(a_uint32_t dev_id, fal_ctrlpkt_profile_t *ctrlpkt); +typedef sw_error_t (*adpt_mgmtctrl_ctrlpkt_profile_getnext_func)(a_uint32_t dev_id, fal_ctrlpkt_profile_t *ctrlpkt); +/*ctrlpkt module end*/ + +/*service module end*/ +typedef sw_error_t (*adpt_servcode_config_set_func)(a_uint32_t dev_id, + a_uint32_t servcode_index, fal_servcode_config_t *entry); +typedef sw_error_t (*adpt_servcode_config_get_func)(a_uint32_t dev_id, + a_uint32_t servcode_index, fal_servcode_config_t *entry); +typedef sw_error_t (*adpt_servcode_loopcheck_en_func)(a_uint32_t dev_id, a_bool_t enable); +typedef sw_error_t (*adpt_servcode_loopcheck_status_get_func)(a_uint32_t dev_id, a_bool_t *enable); +/*service module end*/ + +//pppoe +typedef sw_error_t (*adpt_pppoe_session_table_add_func)( + a_uint32_t dev_id, + fal_pppoe_session_t * session_tbl); +typedef sw_error_t (*adpt_pppoe_session_table_del_func)( + a_uint32_t dev_id, + fal_pppoe_session_t * session_tbl); +typedef sw_error_t (*adpt_pppoe_session_table_get_func)( + a_uint32_t dev_id, + fal_pppoe_session_t * session_tbl); +typedef sw_error_t (*adpt_pppoe_en_set_func)( + a_uint32_t dev_id, + a_uint32_t l3_if, + a_uint32_t enable); +typedef sw_error_t (*adpt_pppoe_en_get_func)( + a_uint32_t dev_id, + a_uint32_t l3_if, + a_uint32_t *enable); + +typedef sw_error_t (*adpt_sec_l3_excep_parser_ctrl_set_func)( + a_uint32_t dev_id, + fal_l3_excep_parser_ctrl *ctrl); +typedef sw_error_t (*adpt_sec_l3_excep_ctrl_get_func)( + a_uint32_t dev_id, a_uint32_t excep_type, fal_l3_excep_ctrl_t *ctrl); +typedef sw_error_t (*adpt_sec_l3_excep_parser_ctrl_get_func)( + a_uint32_t dev_id, fal_l3_excep_parser_ctrl *ctrl); +typedef sw_error_t (*adpt_sec_l4_excep_parser_ctrl_set_func)( + a_uint32_t dev_id, fal_l4_excep_parser_ctrl *ctrl); +typedef sw_error_t (*adpt_sec_l3_excep_ctrl_set_func)( + a_uint32_t dev_id, a_uint32_t excep_type, fal_l3_excep_ctrl_t *ctrl); +typedef sw_error_t (*adpt_sec_l4_excep_parser_ctrl_get_func)( + a_uint32_t dev_id, fal_l4_excep_parser_ctrl *ctrl); + +typedef sw_error_t (*adpt_acl_list_bind_func)(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); +typedef sw_error_t (*adpt_acl_list_dump_func)(a_uint32_t dev_id); +typedef sw_error_t (*adpt_acl_udf_profile_set_func)(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); +typedef sw_error_t (*adpt_acl_rule_query_func)(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t rule_id, fal_acl_rule_t * rule); +typedef sw_error_t (*adpt_acl_list_unbind_func)(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); +typedef sw_error_t (*adpt_acl_rule_add_func)(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); +typedef sw_error_t (*adpt_acl_rule_delete_func)(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t rule_id, a_uint32_t rule_nr); +typedef sw_error_t (*adpt_acl_rule_dump_func)(a_uint32_t dev_id); +typedef sw_error_t (*adpt_acl_udf_profile_get_func)(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); +typedef sw_error_t (*adpt_acl_list_creat_func)(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t list_pri); +typedef sw_error_t (*adpt_acl_list_destroy_func)(a_uint32_t dev_id, a_uint32_t list_id); + +typedef sw_error_t (*adpt_qos_port_pri_set_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_pri_precedence_t *pri); +typedef sw_error_t (*adpt_qos_port_pri_get_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_pri_precedence_t *pri); +typedef sw_error_t (*adpt_qos_cosmap_pcp_get_func)(a_uint32_t dev_id, a_uint8_t group_id, + a_uint8_t pcp, fal_qos_cosmap_t *cosmap); +typedef sw_error_t (*adpt_queue_scheduler_set_func)(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); +typedef sw_error_t (*adpt_queue_scheduler_get_func)(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); +typedef sw_error_t (*adpt_port_queues_get_func)(a_uint32_t dev_id, + fal_port_t port_id, + fal_queue_bmp_t *queue_bmp); +typedef sw_error_t (*adpt_qos_cosmap_pcp_set_func)(a_uint32_t dev_id, a_uint8_t group_id, + a_uint8_t pcp, fal_qos_cosmap_t *cosmap); +typedef sw_error_t (*adpt_qos_port_remark_get_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_remark_enable_t *remark); +typedef sw_error_t (*adpt_qos_cosmap_dscp_get_func)(a_uint32_t dev_id, a_uint8_t group_id, + a_uint8_t dscp, fal_qos_cosmap_t *cosmap); +typedef sw_error_t (*adpt_qos_cosmap_flow_set_func)(a_uint32_t dev_id, a_uint8_t group_id, + a_uint16_t flow, fal_qos_cosmap_t *cosmap); +typedef sw_error_t (*adpt_qos_port_group_set_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_group_t *group); +typedef sw_error_t (*adpt_ring_queue_map_set_func)(a_uint32_t dev_id, + a_uint32_t ring_id, fal_queue_bmp_t *queue_bmp); +typedef sw_error_t (*adpt_qos_cosmap_dscp_set_func)(a_uint32_t dev_id, a_uint8_t group_id, + a_uint8_t dscp, fal_qos_cosmap_t *cosmap); +typedef sw_error_t (*adpt_qos_port_remark_set_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_remark_enable_t *remark); +typedef sw_error_t (*adpt_qos_cosmap_flow_get_func)(a_uint32_t dev_id, a_uint8_t group_id, + a_uint16_t flow, fal_qos_cosmap_t *cosmap); +typedef sw_error_t (*adpt_qos_port_group_get_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_group_t *group); +typedef sw_error_t (*adpt_ring_queue_map_get_func)(a_uint32_t dev_id, + a_uint32_t ring_id, fal_queue_bmp_t *queue_bmp); + +//shaper + +typedef sw_error_t (*adpt_flow_shaper_set_func)(a_uint32_t dev_id, a_uint32_t flow_id, + fal_shaper_config_t * shaper); +typedef sw_error_t (*adpt_queue_shaper_get_func)(a_uint32_t dev_id, a_uint32_t queue_id, + fal_shaper_config_t * shaper); +typedef sw_error_t (*adpt_queue_shaper_token_number_set_func)(a_uint32_t dev_id,a_uint32_t queue_id, + fal_shaper_token_number_t *token_number); +typedef sw_error_t (*adpt_port_shaper_get_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_shaper_config_t * shaper); +typedef sw_error_t (*adpt_flow_shaper_time_slot_get_func)(a_uint32_t dev_id, a_uint32_t *time_slot); +typedef sw_error_t (*adpt_port_shaper_time_slot_get_func)(a_uint32_t dev_id, a_uint32_t *time_slot); +typedef sw_error_t (*adpt_flow_shaper_time_slot_set_func)(a_uint32_t dev_id, a_uint32_t time_slot); +typedef sw_error_t (*adpt_port_shaper_token_number_set_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_shaper_token_number_t *token_number); +typedef sw_error_t (*adpt_queue_shaper_token_number_get_func)(a_uint32_t dev_id, a_uint32_t queue_id, + fal_shaper_token_number_t *token_number); +typedef sw_error_t (*adpt_queue_shaper_time_slot_get_func)(a_uint32_t dev_id, a_uint32_t *time_slot); +typedef sw_error_t (*adpt_port_shaper_token_number_get_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_shaper_token_number_t *token_number); +typedef sw_error_t (*adpt_flow_shaper_token_number_set_func)(a_uint32_t dev_id, a_uint32_t flow_id, + fal_shaper_token_number_t *token_number); +typedef sw_error_t (*adpt_flow_shaper_token_number_get_func)(a_uint32_t dev_id, a_uint32_t flow_id, + fal_shaper_token_number_t *token_number); +typedef sw_error_t (*adpt_port_shaper_set_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_shaper_config_t * shaper); +typedef sw_error_t (*adpt_port_shaper_time_slot_set_func)(a_uint32_t dev_id, a_uint32_t time_slot); +typedef sw_error_t (*adpt_flow_shaper_get_func)(a_uint32_t dev_id, a_uint32_t flow_id, + fal_shaper_config_t * shaper); +typedef sw_error_t (*adpt_queue_shaper_set_func)(a_uint32_t dev_id,a_uint32_t queue_id, + fal_shaper_config_t * shaper); +typedef sw_error_t (*adpt_queue_shaper_time_slot_set_func)(a_uint32_t dev_id, a_uint32_t time_slot); +typedef sw_error_t (*adpt_shaper_ipg_preamble_length_get_func)(a_uint32_t dev_id, a_uint32_t *ipg_pre_length); +typedef sw_error_t (*adpt_shaper_ipg_preamble_length_set_func)(a_uint32_t dev_id, a_uint32_t ipg_pre_length); + +typedef sw_error_t (*adpt_tdm_tick_num_set_func)(a_uint32_t dev_id, a_uint32_t tick_num); +typedef sw_error_t (*adpt_tdm_tick_num_get_func)(a_uint32_t dev_id, a_uint32_t *tick_num); +typedef sw_error_t (*adpt_port_scheduler_cfg_set_func)(a_uint32_t dev_id, a_uint32_t tick_index, + fal_port_scheduler_cfg_t *cfg); +typedef sw_error_t (*adpt_port_scheduler_cfg_reset_func)(a_uint32_t dev_id, fal_port_t port_id); +typedef sw_error_t (*adpt_port_scheduler_cfg_get_func)(a_uint32_t dev_id, a_uint32_t tick_index, + fal_port_scheduler_cfg_t *cfg); +typedef sw_error_t (*adpt_scheduler_dequeue_ctrl_get_func)(a_uint32_t dev_id, a_uint32_t queue_id, + a_bool_t *enable); +typedef sw_error_t (*adpt_scheduler_dequeue_ctrl_set_func)(a_uint32_t dev_id, a_uint32_t queue_id, + a_bool_t enable); +typedef sw_error_t (*adpt_qos_port_mode_pri_get_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_uint32_t *pri); +typedef sw_error_t (*adpt_qos_port_mode_pri_set_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_uint32_t pri); +typedef sw_error_t (*adpt_port_scheduler_resource_get_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_portscheduler_resource_t *cfg); +typedef sw_error_t (*adpt_port_bufgroup_map_get_func)(a_uint32_t dev_id, fal_port_t port, + a_uint8_t *group); +typedef sw_error_t (*adpt_bm_port_reserved_buffer_get_func)(a_uint32_t dev_id, fal_port_t port, + a_uint16_t *prealloc_buff, a_uint16_t *react_buff); +typedef sw_error_t (*adpt_bm_bufgroup_buffer_get_func)(a_uint32_t dev_id, a_uint8_t group, + a_uint16_t *buff_num); +typedef sw_error_t (*adpt_bm_port_dynamic_thresh_get_func)(a_uint32_t dev_id, fal_port_t port, + fal_bm_dynamic_cfg_t *cfg); +typedef sw_error_t (*adpt_port_bm_ctrl_get_func)(a_uint32_t dev_id, fal_port_t port, a_bool_t *enable); +typedef sw_error_t (*adpt_bm_bufgroup_buffer_set_func)(a_uint32_t dev_id, a_uint8_t group, + a_uint16_t buff_num); +typedef sw_error_t (*adpt_port_bufgroup_map_set_func)(a_uint32_t dev_id, fal_port_t port, + a_uint8_t group); +typedef sw_error_t (*adpt_bm_port_static_thresh_get_func)(a_uint32_t dev_id, fal_port_t port, + fal_bm_static_cfg_t *cfg); +typedef sw_error_t (*adpt_bm_port_reserved_buffer_set_func)(a_uint32_t dev_id, fal_port_t port, + a_uint16_t prealloc_buff, a_uint16_t react_buff); +typedef sw_error_t (*adpt_bm_port_static_thresh_set_func)(a_uint32_t dev_id, fal_port_t port, + fal_bm_static_cfg_t *cfg); +typedef sw_error_t (*adpt_bm_port_dynamic_thresh_set_func)(a_uint32_t dev_id, fal_port_t port, + fal_bm_dynamic_cfg_t *cfg); +typedef sw_error_t (*adpt_port_bm_ctrl_set_func)(a_uint32_t dev_id, fal_port_t port, a_bool_t enable); +typedef sw_error_t (*adpt_port_tdm_ctrl_set_func)(a_uint32_t dev_id, fal_port_tdm_ctrl_t *ctrl); +typedef sw_error_t (*adpt_port_tdm_tick_cfg_set_func)(a_uint32_t dev_id, a_uint32_t tick_index, + fal_port_tdm_tick_cfg_t *cfg); +typedef sw_error_t (*adpt_bm_port_counter_get_func)(a_uint32_t dev_id, fal_port_t port, + fal_bm_port_counter_t *counter); + +//policer +typedef sw_error_t (*adpt_acl_policer_counter_get_func)(a_uint32_t dev_id, a_uint32_t index, + fal_policer_counter_t *counter); +typedef sw_error_t (*adpt_port_policer_counter_get_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_policer_counter_t *counter); +typedef sw_error_t (*adpt_port_compensation_byte_get_func)(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t *length); +typedef sw_error_t (*adpt_port_policer_entry_get_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_policer_config_t *policer, fal_policer_action_t *ation); +typedef sw_error_t (*adpt_port_policer_entry_set_func)(a_uint32_t dev_id, fal_port_t port_id, + fal_policer_config_t *policer, fal_policer_action_t *ation); +typedef sw_error_t (*adpt_acl_policer_entry_get_func)(a_uint32_t dev_id, a_uint32_t index, + fal_policer_config_t *policer, fal_policer_action_t *ation); +typedef sw_error_t (*adpt_acl_policer_entry_set_func)(a_uint32_t dev_id, a_uint32_t index, + fal_policer_config_t *policer, fal_policer_action_t *ation); +typedef sw_error_t (*adpt_policer_time_slot_get_func)(a_uint32_t dev_id, a_uint32_t *time_slot); +typedef sw_error_t (*adpt_port_compensation_byte_set_func)(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t length); +typedef sw_error_t (*adpt_policer_time_slot_set_func)(a_uint32_t dev_id, a_uint32_t time_slot); + +typedef sw_error_t (*adpt_policer_global_counter_get_func)(a_uint32_t dev_id, + fal_policer_global_counter_t *counter); + +/* misc */ +typedef sw_error_t (*adpt_debug_port_counter_enable_func)(a_uint32_t dev_id, + fal_port_t port_id, fal_counter_en_t * cnt_en); +typedef sw_error_t (*adpt_debug_port_counter_status_get_func)(a_uint32_t dev_id, + fal_port_t port_id, fal_counter_en_t * cnt_en); +typedef sw_error_t (*adpt_debug_counter_get_func)(a_bool_t show_type); +typedef sw_error_t (*adpt_debug_counter_set_func)(void); +typedef sw_error_t (*adpt_intr_port_link_mask_set_func) (a_uint32_t dev_id, + fal_port_t port_id, a_uint32_t intr_mask); +typedef sw_error_t (*adpt_intr_port_link_mask_get_func) (a_uint32_t dev_id, + fal_port_t port_id, a_uint32_t * intr_mask); +typedef sw_error_t (*adpt_intr_port_link_status_get_func)(a_uint32_t dev_id, + fal_port_t port_id, a_uint32_t * intr_status); + +/* uniphy */ +typedef sw_error_t (*adpt_uniphy_mode_set_func)(a_uint32_t dev_id, a_uint32_t index, a_uint32_t mode); + +/* ptp */ +typedef sw_error_t (*adpt_ptp_config_set_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_config_t *config); +typedef sw_error_t (*adpt_ptp_config_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_config_t *config); +typedef sw_error_t (*adpt_ptp_reference_clock_set_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_reference_clock_t ref_clock); +typedef sw_error_t (*adpt_ptp_reference_clock_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_reference_clock_t *ref_clock); +typedef sw_error_t (*adpt_ptp_rx_timestamp_mode_set_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_rx_timestamp_mode_t ts_mode); +typedef sw_error_t (*adpt_ptp_rx_timestamp_mode_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_rx_timestamp_mode_t *ts_mode); +typedef sw_error_t (*adpt_ptp_timestamp_get_func)(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); +typedef sw_error_t (*adpt_ptp_pkt_timestamp_set_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_time_t *time); +typedef sw_error_t (*adpt_ptp_pkt_timestamp_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_time_t *time); +typedef sw_error_t (*adpt_ptp_grandmaster_mode_set_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_grandmaster_mode_t *gm_mode); +typedef sw_error_t (*adpt_ptp_grandmaster_mode_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_grandmaster_mode_t *gm_mode); +typedef sw_error_t (*adpt_ptp_rtc_time_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_time_t *time); +typedef sw_error_t (*adpt_ptp_rtc_time_set_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_time_t *time); +typedef sw_error_t (*adpt_ptp_rtc_time_clear_func)(a_uint32_t dev_id, + a_uint32_t port_id); +typedef sw_error_t (*adpt_ptp_rtc_adjtime_set_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_time_t *time); +typedef sw_error_t (*adpt_ptp_rtc_adjfreq_set_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_time_t *time); +typedef sw_error_t (*adpt_ptp_rtc_adjfreq_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_time_t *time); +typedef sw_error_t (*adpt_ptp_link_delay_set_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_time_t *time); +typedef sw_error_t (*adpt_ptp_link_delay_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_time_t *time); +typedef sw_error_t (*adpt_ptp_security_set_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_security_t *sec); +typedef sw_error_t (*adpt_ptp_security_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_security_t *sec); +typedef sw_error_t (*adpt_ptp_pps_signal_control_set_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_pps_signal_control_t *sig_control); +typedef sw_error_t (*adpt_ptp_pps_signal_control_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_pps_signal_control_t *sig_control); +typedef sw_error_t (*adpt_ptp_rx_crc_recalc_enable_func)(a_uint32_t dev_id, + a_uint32_t port_id, a_bool_t status); +typedef sw_error_t (*adpt_ptp_rx_crc_recalc_status_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, a_bool_t *status); +typedef sw_error_t (*adpt_ptp_asym_correction_set_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_asym_correction_t *asym_cf); +typedef sw_error_t (*adpt_ptp_asym_correction_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_asym_correction_t *asym_cf); +typedef sw_error_t (*adpt_ptp_output_waveform_set_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_output_waveform_t *waveform); +typedef sw_error_t (*adpt_ptp_output_waveform_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_output_waveform_t *waveform); +typedef sw_error_t (*adpt_ptp_rtc_time_snapshot_enable_func)(a_uint32_t dev_id, + a_uint32_t port_id, a_bool_t status); +typedef sw_error_t (*adpt_ptp_rtc_time_snapshot_status_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, a_bool_t *status); +typedef sw_error_t (*adpt_ptp_increment_sync_from_clock_enable_func)(a_uint32_t dev_id, + a_uint32_t port_id, a_bool_t status); +typedef sw_error_t (*adpt_ptp_increment_sync_from_clock_status_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, a_bool_t *status); +typedef sw_error_t (*adpt_ptp_tod_uart_set_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_tod_uart_t *tod_uart); +typedef sw_error_t (*adpt_ptp_tod_uart_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_tod_uart_t *tod_uart); +typedef sw_error_t (*adpt_ptp_enhanced_timestamp_engine_set_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_direction_t direction, + fal_ptp_enhanced_ts_engine_t *ts_engine); +typedef sw_error_t (*adpt_ptp_enhanced_timestamp_engine_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_direction_t direction, + fal_ptp_enhanced_ts_engine_t *ts_engine); +typedef sw_error_t (*adpt_ptp_trigger_set_func)(a_uint32_t dev_id, a_uint32_t port_id, + a_uint32_t trigger_id, fal_ptp_trigger_t *triger); +typedef sw_error_t (*adpt_ptp_trigger_get_func)(a_uint32_t dev_id, a_uint32_t port_id, + a_uint32_t trigger_id, fal_ptp_trigger_t *triger); +typedef sw_error_t (*adpt_ptp_capture_set_func)(a_uint32_t dev_id, a_uint32_t port_id, + a_uint32_t capture_id, fal_ptp_capture_t *capture); +typedef sw_error_t (*adpt_ptp_capture_get_func)(a_uint32_t dev_id, a_uint32_t port_id, + a_uint32_t capture_id, fal_ptp_capture_t *capture); +typedef sw_error_t (*adpt_ptp_interrupt_set_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_interrupt_t *interrupt); +typedef sw_error_t (*adpt_ptp_interrupt_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_interrupt_t *interrupt); + +/* sfp */ +typedef sw_error_t (*adpt_sfp_eeprom_data_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_sfp_data_t *entry); +typedef sw_error_t (*adpt_sfp_eeprom_data_set_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_sfp_data_t *entry); +typedef sw_error_t (*adpt_sfp_diag_ctrl_status_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_sfp_ctrl_status_t *ctrl_status); +typedef sw_error_t (*adpt_sfp_diag_extenal_calibration_const_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_sfp_cal_const_t *cal_const); +typedef sw_error_t (*adpt_sfp_link_length_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_sfp_link_length_t *link_len); +typedef sw_error_t (*adpt_sfp_diag_internal_threshold_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_sfp_internal_threshold_t *threshold); +typedef sw_error_t (*adpt_sfp_diag_realtime_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_sfp_realtime_diag_t *real_diag); +typedef sw_error_t (*adpt_sfp_laser_wavelength_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_sfp_laser_wavelength_t *laser_wavelen); +typedef sw_error_t (*adpt_sfp_option_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_sfp_option_t *option); +typedef sw_error_t (*adpt_sfp_checkcode_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_sfp_cc_type_t cc_type, a_uint8_t *ccode); +typedef sw_error_t (*adpt_sfp_diag_alarm_warning_flag_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_sfp_alarm_warn_flag_t *alarm_warn_flag); +typedef sw_error_t (*adpt_sfp_device_type_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_sfp_dev_type_t *sfp_id); +typedef sw_error_t (*adpt_sfp_vendor_info_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_sfp_vendor_info_t *vender_info); +typedef sw_error_t (*adpt_sfp_transceiver_code_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_sfp_transc_code_t *transc_code); +typedef sw_error_t (*adpt_sfp_ctrl_rate_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_sfp_rate_t *rate_limit); +typedef sw_error_t (*adpt_sfp_enhanced_cfg_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_sfp_enhanced_cfg_t *enhanced_feature); +typedef sw_error_t (*adpt_sfp_rate_encode_get_func)(a_uint32_t dev_id, + a_uint32_t port_id, fal_sfp_rate_encode_t *encode); + +/*led*/ +typedef sw_error_t (*adpt_led_ctrl_pattern_set_func)(a_uint32_t dev_id, + led_pattern_group_t group, led_pattern_id_t led_pattern_id, + led_ctrl_pattern_t * pattern); +typedef sw_error_t (*adpt_led_ctrl_pattern_get_func)(a_uint32_t dev_id, + led_pattern_group_t group, led_pattern_id_t led_pattern_id, + led_ctrl_pattern_t * pattern); +typedef sw_error_t (*adpt_led_ctrl_source_set_func)(a_uint32_t dev_id, + a_uint32_t source_id, led_ctrl_pattern_t *pattern); + +typedef struct +{ + ssdk_chip_type chip_type; + a_uint32_t chip_revision; +}adpt_chip_ver_t; +typedef struct +{ + a_uint32_t adpt_fdb_func_bitmap[2]; + adpt_fdb_first_func adpt_fdb_first; + adpt_fdb_next_func adpt_fdb_next; + adpt_fdb_add_func adpt_fdb_add; + adpt_fdb_age_time_set_func adpt_fdb_age_time_set; + adpt_fdb_extend_next_func adpt_fdb_extend_next; + adpt_fdb_learn_ctrl_get_func adpt_fdb_learn_ctrl_get; + adpt_fdb_age_time_get_func adpt_fdb_age_time_get; + adpt_port_fdb_learn_limit_set_func adpt_port_fdb_learn_limit_set; + adpt_fdb_port_add_func adpt_fdb_port_add; + adpt_fdb_port_learn_set_func adpt_fdb_port_learn_set; + adpt_fdb_port_learn_get_func adpt_fdb_port_learn_get; + adpt_fdb_port_newaddr_lrn_set_func adpt_fdb_port_newaddr_lrn_set; + adpt_fdb_port_newaddr_lrn_get_func adpt_fdb_port_newaddr_lrn_get; + adpt_fdb_port_stamove_set_func adpt_fdb_port_stamove_set; + adpt_fdb_port_stamove_get_func adpt_fdb_port_stamove_get; + adpt_port_fdb_learn_counter_get_func adpt_port_fdb_learn_counter_get; + adpt_fdb_extend_first_func adpt_fdb_extend_first; + adpt_fdb_transfer_func adpt_fdb_transfer; + adpt_fdb_port_del_func adpt_fdb_port_del; + adpt_fdb_find_func adpt_fdb_find; + adpt_fdb_learn_ctrl_set_func adpt_fdb_learn_ctrl_set; + adpt_port_fdb_learn_exceed_cmd_get_func adpt_port_fdb_learn_exceed_cmd_get; + adpt_fdb_del_by_port_func adpt_fdb_del_by_port; + adpt_port_fdb_learn_limit_get_func adpt_port_fdb_learn_limit_get; + adpt_fdb_age_ctrl_set_func adpt_fdb_age_ctrl_set; + adpt_fdb_del_by_mac_func adpt_fdb_del_by_mac; + adpt_fdb_iterate_func adpt_fdb_iterate; + adpt_port_fdb_learn_exceed_cmd_set_func adpt_port_fdb_learn_exceed_cmd_set; + adpt_fdb_del_all_func adpt_fdb_del_all; + adpt_fdb_age_ctrl_get_func adpt_fdb_age_ctrl_get; + adpt_fdb_port_maclimit_ctrl_set_func adpt_fdb_port_maclimit_ctrl_set; + adpt_fdb_port_maclimit_ctrl_get_func adpt_fdb_port_maclimit_ctrl_get; + adpt_fdb_del_by_fid_func adpt_fdb_del_by_fid; + /*mib*/ + a_uint32_t adpt_mib_func_bitmap; + adpt_mib_cpukeep_get_func adpt_mib_cpukeep_get; + adpt_mib_cpukeep_set_func adpt_mib_cpukeep_set; + adpt_get_mib_info_func adpt_get_mib_info; + adpt_get_tx_mib_info_func adpt_get_tx_mib_info; + adpt_mib_status_set_func adpt_mib_status_set; + adpt_mib_port_flush_counters_func adpt_mib_port_flush_counters; + adpt_mib_status_get_func adpt_mib_status_get; + adpt_get_rx_mib_info_func adpt_get_rx_mib_info; + adpt_get_xgmib_info_func adpt_get_xgmib_info; + adpt_get_tx_xgmib_info_func adpt_get_tx_xgmib_info; + adpt_get_rx_xgmib_info_func adpt_get_rx_xgmib_info; + + a_uint32_t adpt_stp_func_bitmap; + adpt_stp_port_state_get_func adpt_stp_port_state_get; + adpt_stp_port_state_set_func adpt_stp_port_state_set; + + /*vsi*/ + a_uint32_t adpt_vsi_func_bitmap; + adpt_port_vlan_vsi_set_func adpt_port_vlan_vsi_set; + adpt_port_vlan_vsi_get_func adpt_port_vlan_vsi_get; + adpt_port_vsi_set_func adpt_port_vsi_set; + adpt_port_vsi_get_func adpt_port_vsi_get; + adpt_vsi_stamove_set_func adpt_vsi_stamove_set; + adpt_vsi_stamove_get_func adpt_vsi_stamove_get; + adpt_vsi_newaddr_lrn_set_func adpt_vsi_newaddr_lrn_set; + adpt_vsi_newaddr_lrn_get_func adpt_vsi_newaddr_lrn_get; + adpt_vsi_member_set_func adpt_vsi_member_set; + adpt_vsi_member_get_func adpt_vsi_member_get; + adpt_vsi_counter_get_func adpt_vsi_counter_get; + adpt_vsi_counter_cleanup_func adpt_vsi_counter_cleanup; + + // port_ctrl + a_uint32_t adpt_port_ctrl_func_bitmap[3]; + adpt_port_local_loopback_get_func adpt_port_local_loopback_get; + adpt_port_autoneg_restart_func adpt_port_autoneg_restart; + adpt_port_duplex_set_func adpt_port_duplex_set; + adpt_port_rxmac_status_get_func adpt_port_rxmac_status_get; + adpt_port_cdt_func adpt_port_cdt; + adpt_port_txmac_status_set_func adpt_port_txmac_status_set; + adpt_port_combo_fiber_mode_set_func adpt_port_combo_fiber_mode_set; + adpt_port_combo_medium_status_get_func adpt_port_combo_medium_status_get; + adpt_port_magic_frame_mac_set_func adpt_port_magic_frame_mac_set; + adpt_port_powersave_set_func adpt_port_powersave_set; + adpt_port_hibernate_set_func adpt_port_hibernate_set; + adpt_port_max_frame_size_get_func adpt_port_max_frame_size_get; + adpt_port_8023az_get_func adpt_port_8023az_get; + adpt_port_rxfc_status_get_func adpt_port_rxfc_status_get; + adpt_port_txfc_status_get_func adpt_port_txfc_status_get; + adpt_port_remote_loopback_set_func adpt_port_remote_loopback_set; + adpt_port_flowctrl_set_func adpt_port_flowctrl_set; + adpt_port_mru_set_func adpt_port_mru_set; + adpt_port_autoneg_status_get_func adpt_port_autoneg_status_get; + adpt_port_txmac_status_get_func adpt_port_txmac_status_get; + adpt_port_mdix_get_func adpt_port_mdix_get; + adpt_ports_link_status_get_func adpt_ports_link_status_get; + adpt_port_mac_loopback_set_func adpt_port_mac_loopback_set; + adpt_port_phy_id_get_func adpt_port_phy_id_get; + adpt_port_mru_get_func adpt_port_mru_get; + adpt_port_power_on_func adpt_port_power_on; + adpt_port_speed_set_func adpt_port_speed_set; + adpt_port_interface_mode_get_func adpt_port_interface_mode_get; + adpt_port_duplex_get_func adpt_port_duplex_get; + adpt_port_autoneg_adv_get_func adpt_port_autoneg_adv_get; + adpt_port_mdix_status_get_func adpt_port_mdix_status_get; + adpt_port_mtu_set_func adpt_port_mtu_set; + adpt_port_link_status_get_func adpt_port_link_status_get; + adpt_port_8023az_set_func adpt_port_8023az_set; + adpt_port_powersave_get_func adpt_port_powersave_get; + adpt_port_combo_prefer_medium_get_func adpt_port_combo_prefer_medium_get; + adpt_port_max_frame_size_set_func adpt_port_max_frame_size_set; + adpt_port_combo_prefer_medium_set_func adpt_port_combo_prefer_medium_set; + adpt_port_power_off_func adpt_port_power_off; + adpt_port_txfc_status_set_func adpt_port_txfc_status_set; + adpt_port_counter_set_func adpt_port_counter_set; + adpt_port_combo_fiber_mode_get_func adpt_port_combo_fiber_mode_get; + adpt_port_local_loopback_set_func adpt_port_local_loopback_set; + adpt_port_wol_status_set_func adpt_port_wol_status_set; + adpt_port_magic_frame_mac_get_func adpt_port_magic_frame_mac_get; + adpt_port_flowctrl_get_func adpt_port_flowctrl_get; + adpt_port_rxmac_status_set_func adpt_port_rxmac_status_set; + adpt_port_counter_get_func adpt_port_counter_get; + adpt_port_interface_mode_set_func adpt_port_interface_mode_set; + adpt_port_mac_loopback_get_func adpt_port_mac_loopback_get; + adpt_port_hibernate_get_func adpt_port_hibernate_get; + adpt_port_autoneg_adv_set_func adpt_port_autoneg_adv_set; + adpt_port_remote_loopback_get_func adpt_port_remote_loopback_get; + adpt_port_counter_show_func adpt_port_counter_show; + adpt_port_autoneg_enable_func adpt_port_autoneg_enable; + adpt_port_mtu_get_func adpt_port_mtu_get; + adpt_port_interface_mode_status_get_func adpt_port_interface_mode_status_get; + adpt_port_reset_func adpt_port_reset; + adpt_port_rxfc_status_set_func adpt_port_rxfc_status_set; + adpt_port_speed_get_func adpt_port_speed_get; + adpt_port_mdix_set_func adpt_port_mdix_set; + adpt_port_wol_status_get_func adpt_port_wol_status_get; + adpt_port_source_filter_set_func adpt_port_source_filter_set; + adpt_port_source_filter_get_func adpt_port_source_filter_get; + adpt_port_mux_mac_type_set_func adpt_port_mux_mac_type_set; + adpt_port_mac_speed_set_func adpt_port_mac_speed_set; + adpt_port_mac_duplex_set_func adpt_port_mac_duplex_set; + adpt_port_netdev_notify_func adpt_port_netdev_notify_set; + adpt_port_polling_sw_sync_func adpt_port_polling_sw_sync_set; + + adpt_port_bridge_txmac_set_func adpt_port_bridge_txmac_set; + + adpt_port_interface_mode_apply_func adpt_port_interface_mode_apply; + adpt_port_interface_3az_status_set_func adpt_port_interface_3az_status_set; + adpt_port_interface_3az_status_get_func adpt_port_interface_3az_status_get; + adpt_port_flowctrl_forcemode_set_func adpt_port_flowctrl_forcemode_set; + adpt_port_flowctrl_forcemode_get_func adpt_port_flowctrl_forcemode_get; + adpt_port_promisc_mode_set_func adpt_port_promisc_mode_set; + adpt_port_promisc_mode_get_func adpt_port_promisc_mode_get; + adpt_port_interface_eee_cfg_set_func adpt_port_interface_eee_cfg_set; + adpt_port_interface_eee_cfg_get_func adpt_port_interface_eee_cfg_get; + adpt_port_source_filter_config_set_func adpt_port_source_filter_config_set; + adpt_port_source_filter_config_get_func adpt_port_source_filter_config_get; + adpt_switch_port_loopback_set_func adpt_switch_port_loopback_set; + adpt_switch_port_loopback_get_func adpt_switch_port_loopback_get; + adpt_port_phy_status_get_func adpt_port_phy_status_get; +// mirror + a_uint32_t adpt_mirror_func_bitmap; + adpt_mirr_port_in_set_func adpt_mirr_port_in_set; + adpt_mirr_port_in_get_func adpt_mirr_port_in_get; + adpt_mirr_port_eg_set_func adpt_mirr_port_eg_set; + adpt_mirr_port_eg_get_func adpt_mirr_port_eg_get; + adpt_mirr_analysis_port_set_func adpt_mirr_analysis_port_set; + adpt_mirr_analysis_port_get_func adpt_mirr_analysis_port_get; + adpt_mirr_analysis_config_set_func adpt_mirr_analysis_config_set; + adpt_mirr_analysis_config_get_func adpt_mirr_analysis_config_get; +//rss hash + a_uint32_t adpt_rss_hash_func_bitmap; + adpt_rss_hash_config_set_func adpt_rss_hash_config_set; + adpt_rss_hash_config_get_func adpt_rss_hash_config_get; +//trunk + a_uint32_t adpt_trunk_func_bitmap; + adpt_trunk_fail_over_en_get_func adpt_trunk_fail_over_en_get; + adpt_trunk_hash_mode_get_func adpt_trunk_hash_mode_get; + adpt_trunk_group_get_func adpt_trunk_group_get; + adpt_trunk_group_set_func adpt_trunk_group_set; + adpt_trunk_fail_over_en_set_func adpt_trunk_fail_over_en_set; + adpt_trunk_hash_mode_set_func adpt_trunk_hash_mode_set; + + /* ip */ + a_uint32_t adpt_ip_func_bitmap[2]; + adpt_ip_network_route_get_func adpt_ip_network_route_get; + adpt_ip_network_route_add_func adpt_ip_network_route_add; + adpt_ip_network_route_del_func adpt_ip_network_route_del; + adpt_ip_host_add_func adpt_ip_host_add; + adpt_ip_vsi_sg_cfg_get_func adpt_ip_vsi_sg_cfg_get; + adpt_ip_pub_addr_set_func adpt_ip_pub_addr_set; + adpt_ip_pub_addr_get_func adpt_ip_pub_addr_get; + adpt_ip_port_sg_cfg_set_func adpt_ip_port_sg_cfg_set; + adpt_ip_port_intf_get_func adpt_ip_port_intf_get; + adpt_ip_vsi_arp_sg_cfg_set_func adpt_ip_vsi_arp_sg_cfg_set; + adpt_ip_port_intf_set_func adpt_ip_port_intf_set; + adpt_ip_vsi_sg_cfg_set_func adpt_ip_vsi_sg_cfg_set; + adpt_ip_host_next_func adpt_ip_host_next; + adpt_ip_port_macaddr_set_func adpt_ip_port_macaddr_set; + adpt_ip_vsi_intf_get_func adpt_ip_vsi_intf_get; + adpt_ip_port_sg_cfg_get_func adpt_ip_port_sg_cfg_get; + adpt_ip_intf_get_func adpt_ip_intf_get; + adpt_ip_host_del_func adpt_ip_host_del; + adpt_ip_route_mismatch_get_func adpt_ip_route_mismatch_get; + adpt_ip_vsi_arp_sg_cfg_get_func adpt_ip_vsi_arp_sg_cfg_get; + adpt_ip_port_arp_sg_cfg_set_func adpt_ip_port_arp_sg_cfg_set; + adpt_ip_vsi_mc_mode_set_func adpt_ip_vsi_mc_mode_set; + adpt_ip_vsi_intf_set_func adpt_ip_vsi_intf_set; + adpt_ip_nexthop_get_func adpt_ip_nexthop_get; + adpt_ip_route_mismatch_set_func adpt_ip_route_mismatch_set; + adpt_ip_host_get_func adpt_ip_host_get; + adpt_ip_intf_set_func adpt_ip_intf_set; + adpt_ip_vsi_mc_mode_get_func adpt_ip_vsi_mc_mode_get; + adpt_ip_port_macaddr_get_func adpt_ip_port_macaddr_get; + adpt_ip_port_arp_sg_cfg_get_func adpt_ip_port_arp_sg_cfg_get; + adpt_ip_nexthop_set_func adpt_ip_nexthop_set; + adpt_ip_global_ctrl_get_func adpt_ip_global_ctrl_get; + adpt_ip_global_ctrl_set_func adpt_ip_global_ctrl_set; + /* flow */ + a_uint32_t adpt_flow_func_bitmap; + adpt_flow_host_add_func adpt_flow_host_add; + adpt_flow_entry_get_func adpt_flow_entry_get; + adpt_flow_entry_del_func adpt_flow_entry_del; + adpt_flow_entry_next_func adpt_flow_entry_next; + adpt_flow_status_get_func adpt_flow_status_get; + adpt_flow_ctrl_set_func adpt_flow_ctrl_set; + adpt_flow_age_timer_get_func adpt_flow_age_timer_get; + adpt_flow_status_set_func adpt_flow_status_set; + adpt_flow_host_get_func adpt_flow_host_get; + adpt_flow_host_del_func adpt_flow_host_del; + adpt_flow_ctrl_get_func adpt_flow_ctrl_get; + adpt_flow_age_timer_set_func adpt_flow_age_timer_set; + adpt_flow_entry_add_func adpt_flow_entry_add; + adpt_flow_global_cfg_get_func adpt_flow_global_cfg_get; + adpt_flow_global_cfg_set_func adpt_flow_global_cfg_set; + + /* qm */ + a_uint32_t adpt_qm_func_bitmap[2]; + adpt_ucast_hash_map_set_func adpt_ucast_hash_map_set; + adpt_ac_dynamic_threshold_get_func adpt_ac_dynamic_threshold_get; + adpt_ucast_queue_base_profile_get_func adpt_ucast_queue_base_profile_get; + adpt_port_mcast_priority_class_get_func adpt_port_mcast_priority_class_get; + adpt_ac_dynamic_threshold_set_func adpt_ac_dynamic_threshold_set; + adpt_ac_prealloc_buffer_set_func adpt_ac_prealloc_buffer_set; + adpt_ucast_default_hash_get_func adpt_ucast_default_hash_get; + adpt_ucast_default_hash_set_func adpt_ucast_default_hash_set; + adpt_ac_queue_group_get_func adpt_ac_queue_group_get; + adpt_ac_ctrl_get_func adpt_ac_ctrl_get; + adpt_ac_prealloc_buffer_get_func adpt_ac_prealloc_buffer_get; + adpt_port_mcast_priority_class_set_func adpt_port_mcast_priority_class_set; + adpt_ucast_hash_map_get_func adpt_ucast_hash_map_get; + adpt_ac_static_threshold_set_func adpt_ac_static_threshold_set; + adpt_ac_queue_group_set_func adpt_ac_queue_group_set; + adpt_ac_group_buffer_get_func adpt_ac_group_buffer_get; + adpt_mcast_cpu_code_class_get_func adpt_mcast_cpu_code_class_get; + adpt_ac_ctrl_set_func adpt_ac_ctrl_set; + adpt_ucast_priority_class_get_func adpt_ucast_priority_class_get; + adpt_queue_flush_func adpt_queue_flush; + adpt_mcast_cpu_code_class_set_func adpt_mcast_cpu_code_class_set; + adpt_ucast_priority_class_set_func adpt_ucast_priority_class_set; + adpt_ac_static_threshold_get_func adpt_ac_static_threshold_get; + adpt_ucast_queue_base_profile_set_func adpt_ucast_queue_base_profile_set; + adpt_ac_group_buffer_set_func adpt_ac_group_buffer_set; + adpt_queue_counter_cleanup_func adpt_queue_counter_cleanup; + adpt_queue_counter_get_func adpt_queue_counter_get; + adpt_queue_counter_ctrl_get_func adpt_queue_counter_ctrl_get; + adpt_queue_counter_ctrl_set_func adpt_queue_counter_ctrl_set; + adpt_qm_enqueue_ctrl_set_func adpt_qm_enqueue_ctrl_set; + adpt_qm_enqueue_ctrl_get_func adpt_qm_enqueue_ctrl_get; + adpt_qm_port_source_profile_set_func adpt_qm_port_source_profile_set; + adpt_qm_port_source_profile_get_func adpt_qm_port_source_profile_get; + + /*portvlan module begin*/ + a_uint32_t adpt_portvlan_func_bitmap[2]; + adpt_global_qinq_mode_set_func adpt_global_qinq_mode_set; + adpt_global_qinq_mode_get_func adpt_global_qinq_mode_get; + adpt_tpid_set_func adpt_tpid_set; + adpt_tpid_get_func adpt_tpid_get; + adpt_egress_tpid_set_func adpt_egress_tpid_set; + adpt_egress_tpid_get_func adpt_egress_tpid_get; + adpt_port_qinq_mode_set_func adpt_port_qinq_mode_set; + adpt_port_qinq_mode_get_func adpt_port_qinq_mode_get; + adpt_port_ingress_vlan_filter_set_func adpt_port_ingress_vlan_filter_set; + adpt_port_ingress_vlan_filter_get_func adpt_port_ingress_vlan_filter_get; + adpt_port_default_vlantag_set_func adpt_port_default_vlantag_set; + adpt_port_default_vlantag_get_func adpt_port_default_vlantag_get; + adpt_port_tag_propagation_set_func adpt_port_tag_propagation_set; + adpt_port_tag_propagation_get_func adpt_port_tag_propagation_get; + adpt_port_vlantag_egmode_set_func adpt_port_vlantag_egmode_set; + adpt_port_vlantag_egmode_get_func adpt_port_vlantag_egmode_get; + adpt_port_vlan_xlt_miss_cmd_set_func adpt_port_vlan_xlt_miss_cmd_set; + adpt_port_vlan_xlt_miss_cmd_get_func adpt_port_vlan_xlt_miss_cmd_get; + adpt_port_vlan_trans_add_func adpt_port_vlan_trans_add; + adpt_port_vlan_trans_get_func adpt_port_vlan_trans_get; + adpt_port_vlan_trans_del_func adpt_port_vlan_trans_del; + adpt_port_vlan_trans_iterate_func adpt_port_vlan_trans_iterate; + adpt_port_vsi_egmode_set_func adpt_port_vsi_egmode_set; + adpt_port_vsi_egmode_get_func adpt_port_vsi_egmode_get; + adpt_port_vlantag_vsi_egmode_enable_set_func adpt_port_vlantag_vsi_egmode_enable_set; + adpt_port_vlantag_vsi_egmode_enable_get_func adpt_port_vlantag_vsi_egmode_enable_get; + adpt_qinq_mode_set_func adpt_qinq_mode_set; + adpt_qinq_mode_get_func adpt_qinq_mode_get; + adpt_port_qinq_role_set_func adpt_port_qinq_role_set; + adpt_port_qinq_role_get_func adpt_port_qinq_role_get; + adpt_port_invlan_mode_set_func adpt_port_invlan_mode_set; + adpt_port_invlan_mode_get_func adpt_port_invlan_mode_get; + adpt_port_vlan_trans_adv_add_func adpt_port_vlan_trans_adv_add; + adpt_port_vlan_trans_adv_del_func adpt_port_vlan_trans_adv_del; + adpt_port_vlan_trans_adv_getfirst_func adpt_port_vlan_trans_adv_getfirst; + adpt_port_vlan_trans_adv_getnext_func adpt_port_vlan_trans_adv_getnext; + adpt_port_vlan_counter_get_func adpt_port_vlan_counter_get; + adpt_port_vlan_counter_cleanup_func adpt_port_vlan_counter_cleanup; + adpt_portvlan_member_add_func adpt_portvlan_member_add; + adpt_portvlan_member_del_func adpt_portvlan_member_del; + adpt_portvlan_member_update_func adpt_portvlan_member_update; + adpt_portvlan_member_get_func adpt_portvlan_member_get; + /*portvlan module end*/ + + /*ctrlpkt module begin*/ + a_uint32_t adpt_ctrlpkt_func_bitmap; + adpt_mgmtctrl_ethtype_profile_set_func adpt_mgmtctrl_ethtype_profile_set; + adpt_mgmtctrl_ethtype_profile_get_func adpt_mgmtctrl_ethtype_profile_get; + adpt_mgmtctrl_rfdb_profile_set_func adpt_mgmtctrl_rfdb_profile_set; + adpt_mgmtctrl_rfdb_profile_get_func adpt_mgmtctrl_rfdb_profile_get; + adpt_mgmtctrl_ctrlpkt_profile_add_func adpt_mgmtctrl_ctrlpkt_profile_add; + adpt_mgmtctrl_ctrlpkt_profile_del_func adpt_mgmtctrl_ctrlpkt_profile_del; + adpt_mgmtctrl_ctrlpkt_profile_getfirst_func adpt_mgmtctrl_ctrlpkt_profile_getfirst; + adpt_mgmtctrl_ctrlpkt_profile_getnext_func adpt_mgmtctrl_ctrlpkt_profile_getnext; + /*ctrlpkt module end*/ + + /*servcode module begin*/ + a_uint32_t adpt_servcode_func_bitmap; + adpt_servcode_config_set_func adpt_servcode_config_set; + adpt_servcode_config_get_func adpt_servcode_config_get; + adpt_servcode_loopcheck_en_func adpt_servcode_loopcheck_en; + adpt_servcode_loopcheck_status_get_func adpt_servcode_loopcheck_status_get; + /*servcode module end*/ + + /* pppoe */ + a_uint32_t adpt_pppoe_func_bitmap; + adpt_pppoe_session_table_add_func adpt_pppoe_session_table_add; + adpt_pppoe_session_table_del_func adpt_pppoe_session_table_del; + adpt_pppoe_session_table_get_func adpt_pppoe_session_table_get; + adpt_pppoe_en_set_func adpt_pppoe_en_set; + adpt_pppoe_en_get_func adpt_pppoe_en_get; + + /*sec */ + a_uint32_t adpt_sec_func_bitmap; + adpt_sec_l3_excep_parser_ctrl_set_func adpt_sec_l3_excep_parser_ctrl_set; + adpt_sec_l3_excep_ctrl_get_func adpt_sec_l3_excep_ctrl_get; + adpt_sec_l3_excep_parser_ctrl_get_func adpt_sec_l3_excep_parser_ctrl_get; + adpt_sec_l4_excep_parser_ctrl_set_func adpt_sec_l4_excep_parser_ctrl_set; + adpt_sec_l3_excep_ctrl_set_func adpt_sec_l3_excep_ctrl_set; + adpt_sec_l4_excep_parser_ctrl_get_func adpt_sec_l4_excep_parser_ctrl_get; + + /*acl*/ + a_uint32_t adpt_acl_func_bitmap; + adpt_acl_list_bind_func adpt_acl_list_bind; + adpt_acl_list_dump_func adpt_acl_list_dump; + adpt_acl_udf_profile_set_func adpt_acl_udf_profile_set; + adpt_acl_rule_query_func adpt_acl_rule_query; + adpt_acl_list_unbind_func adpt_acl_list_unbind; + adpt_acl_rule_add_func adpt_acl_rule_add; + adpt_acl_rule_delete_func adpt_acl_rule_delete; + adpt_acl_rule_dump_func adpt_acl_rule_dump; + adpt_acl_udf_profile_get_func adpt_acl_udf_profile_get; + adpt_acl_list_creat_func adpt_acl_list_creat; + adpt_acl_list_destroy_func adpt_acl_list_destroy; + + /* qos */ + a_uint32_t adpt_qos_func_bitmap; + adpt_qos_port_pri_set_func adpt_qos_port_pri_set; + adpt_qos_port_pri_get_func adpt_qos_port_pri_get; + adpt_qos_cosmap_pcp_get_func adpt_qos_cosmap_pcp_get; + adpt_queue_scheduler_set_func adpt_queue_scheduler_set; + adpt_queue_scheduler_get_func adpt_queue_scheduler_get; + adpt_port_queues_get_func adpt_port_queues_get; + adpt_qos_cosmap_pcp_set_func adpt_qos_cosmap_pcp_set; + adpt_qos_port_remark_get_func adpt_qos_port_remark_get; + adpt_qos_cosmap_dscp_get_func adpt_qos_cosmap_dscp_get; + adpt_qos_cosmap_flow_set_func adpt_qos_cosmap_flow_set; + adpt_qos_port_group_set_func adpt_qos_port_group_set; + adpt_ring_queue_map_set_func adpt_ring_queue_map_set; + adpt_qos_cosmap_dscp_set_func adpt_qos_cosmap_dscp_set; + adpt_qos_port_remark_set_func adpt_qos_port_remark_set; + adpt_qos_cosmap_flow_get_func adpt_qos_cosmap_flow_get; + adpt_qos_port_group_get_func adpt_qos_port_group_get; + adpt_ring_queue_map_get_func adpt_ring_queue_map_get; + adpt_tdm_tick_num_set_func adpt_tdm_tick_num_set; + adpt_tdm_tick_num_get_func adpt_tdm_tick_num_get; + adpt_port_scheduler_cfg_set_func adpt_port_scheduler_cfg_set; + adpt_port_scheduler_cfg_get_func adpt_port_scheduler_cfg_get; + adpt_scheduler_dequeue_ctrl_get_func adpt_scheduler_dequeue_ctrl_get; + adpt_scheduler_dequeue_ctrl_set_func adpt_scheduler_dequeue_ctrl_set; + adpt_qos_port_mode_pri_get_func adpt_qos_port_mode_pri_get; + adpt_qos_port_mode_pri_set_func adpt_qos_port_mode_pri_set; + adpt_port_scheduler_cfg_reset_func adpt_port_scheduler_cfg_reset; + adpt_port_scheduler_resource_get_func adpt_port_scheduler_resource_get; + + /* bm */ + a_uint32_t adpt_bm_func_bitmap; + adpt_port_bufgroup_map_get_func adpt_port_bufgroup_map_get; + adpt_bm_port_reserved_buffer_get_func adpt_bm_port_reserved_buffer_get; + adpt_bm_bufgroup_buffer_get_func adpt_bm_bufgroup_buffer_get; + adpt_bm_port_dynamic_thresh_get_func adpt_bm_port_dynamic_thresh_get; + adpt_port_bm_ctrl_get_func adpt_port_bm_ctrl_get; + adpt_bm_bufgroup_buffer_set_func adpt_bm_bufgroup_buffer_set; + adpt_port_bufgroup_map_set_func adpt_port_bufgroup_map_set; + adpt_bm_port_static_thresh_get_func adpt_bm_port_static_thresh_get; + adpt_bm_port_reserved_buffer_set_func adpt_bm_port_reserved_buffer_set; + adpt_bm_port_static_thresh_set_func adpt_bm_port_static_thresh_set; + adpt_bm_port_dynamic_thresh_set_func adpt_bm_port_dynamic_thresh_set; + adpt_port_bm_ctrl_set_func adpt_port_bm_ctrl_set; + adpt_port_tdm_ctrl_set_func adpt_port_tdm_ctrl_set; + adpt_port_tdm_tick_cfg_set_func adpt_port_tdm_tick_cfg_set; + adpt_bm_port_counter_get_func adpt_bm_port_counter_get; + + //shaper + a_uint32_t adpt_shaper_func_bitmap; + adpt_flow_shaper_set_func adpt_flow_shaper_set; + adpt_queue_shaper_get_func adpt_queue_shaper_get; + adpt_queue_shaper_token_number_set_func adpt_queue_shaper_token_number_set; + adpt_port_shaper_get_func adpt_port_shaper_get; + adpt_flow_shaper_time_slot_get_func adpt_flow_shaper_time_slot_get; + adpt_port_shaper_time_slot_get_func adpt_port_shaper_time_slot_get; + adpt_flow_shaper_time_slot_set_func adpt_flow_shaper_time_slot_set; + adpt_shaper_ipg_preamble_length_set_func adpt_shaper_ipg_preamble_length_set; + adpt_port_shaper_token_number_set_func adpt_port_shaper_token_number_set; + adpt_queue_shaper_token_number_get_func adpt_queue_shaper_token_number_get; + adpt_queue_shaper_time_slot_get_func adpt_queue_shaper_time_slot_get; + adpt_port_shaper_token_number_get_func adpt_port_shaper_token_number_get; + adpt_flow_shaper_token_number_set_func adpt_flow_shaper_token_number_set; + adpt_flow_shaper_token_number_get_func adpt_flow_shaper_token_number_get; + adpt_shaper_ipg_preamble_length_get_func adpt_shaper_ipg_preamble_length_get; + adpt_port_shaper_set_func adpt_port_shaper_set; + adpt_port_shaper_time_slot_set_func adpt_port_shaper_time_slot_set; + adpt_flow_shaper_get_func adpt_flow_shaper_get; + adpt_queue_shaper_set_func adpt_queue_shaper_set; + adpt_queue_shaper_time_slot_set_func adpt_queue_shaper_time_slot_set; + +//policer + a_uint32_t adpt_policer_func_bitmap; + adpt_acl_policer_counter_get_func adpt_acl_policer_counter_get; + adpt_port_policer_counter_get_func adpt_port_policer_counter_get; + adpt_port_compensation_byte_get_func adpt_port_compensation_byte_get; + adpt_port_policer_entry_get_func adpt_port_policer_entry_get; + adpt_port_policer_entry_set_func adpt_port_policer_entry_set; + adpt_acl_policer_entry_get_func adpt_acl_policer_entry_get; + adpt_acl_policer_entry_set_func adpt_acl_policer_entry_set; + adpt_policer_time_slot_get_func adpt_policer_time_slot_get; + adpt_port_compensation_byte_set_func adpt_port_compensation_byte_set; + adpt_policer_time_slot_set_func adpt_policer_time_slot_set; + adpt_policer_global_counter_get_func adpt_policer_global_counter_get; + + /* misc */ + adpt_debug_port_counter_enable_func adpt_debug_port_counter_enable; + adpt_debug_port_counter_status_get_func adpt_debug_port_counter_status_get; + adpt_debug_counter_set_func adpt_debug_counter_set; + adpt_debug_counter_get_func adpt_debug_counter_get; + adpt_intr_port_link_mask_set_func adpt_intr_port_link_mask_set; + adpt_intr_port_link_mask_get_func adpt_intr_port_link_mask_get; + adpt_intr_port_link_status_get_func adpt_intr_port_link_status_get; + + /* uniphy */ + adpt_uniphy_mode_set_func adpt_uniphy_mode_set; + + /* ptp */ + adpt_ptp_config_set_func adpt_ptp_config_set; + adpt_ptp_config_get_func adpt_ptp_config_get; + adpt_ptp_reference_clock_set_func adpt_ptp_reference_clock_set; + adpt_ptp_reference_clock_get_func adpt_ptp_reference_clock_get; + adpt_ptp_rx_timestamp_mode_set_func adpt_ptp_rx_timestamp_mode_set; + adpt_ptp_rx_timestamp_mode_get_func adpt_ptp_rx_timestamp_mode_get; + adpt_ptp_timestamp_get_func adpt_ptp_timestamp_get; + adpt_ptp_pkt_timestamp_set_func adpt_ptp_pkt_timestamp_set; + adpt_ptp_pkt_timestamp_get_func adpt_ptp_pkt_timestamp_get; + adpt_ptp_grandmaster_mode_set_func adpt_ptp_grandmaster_mode_set; + adpt_ptp_grandmaster_mode_get_func adpt_ptp_grandmaster_mode_get; + adpt_ptp_rtc_time_get_func adpt_ptp_rtc_time_get; + adpt_ptp_rtc_time_set_func adpt_ptp_rtc_time_set; + adpt_ptp_rtc_time_clear_func adpt_ptp_rtc_time_clear; + adpt_ptp_rtc_adjtime_set_func adpt_ptp_rtc_adjtime_set; + adpt_ptp_rtc_adjfreq_set_func adpt_ptp_rtc_adjfreq_set; + adpt_ptp_rtc_adjfreq_get_func adpt_ptp_rtc_adjfreq_get; + adpt_ptp_link_delay_set_func adpt_ptp_link_delay_set; + adpt_ptp_link_delay_get_func adpt_ptp_link_delay_get; + adpt_ptp_security_set_func adpt_ptp_security_set; + adpt_ptp_security_get_func adpt_ptp_security_get; + adpt_ptp_pps_signal_control_set_func adpt_ptp_pps_signal_control_set; + adpt_ptp_pps_signal_control_get_func adpt_ptp_pps_signal_control_get; + adpt_ptp_rx_crc_recalc_enable_func adpt_ptp_rx_crc_recalc_enable; + adpt_ptp_rx_crc_recalc_status_get_func adpt_ptp_rx_crc_recalc_status_get; + adpt_ptp_asym_correction_set_func adpt_ptp_asym_correction_set; + adpt_ptp_asym_correction_get_func adpt_ptp_asym_correction_get; + adpt_ptp_output_waveform_set_func adpt_ptp_output_waveform_set; + adpt_ptp_output_waveform_get_func adpt_ptp_output_waveform_get; + adpt_ptp_rtc_time_snapshot_enable_func adpt_ptp_rtc_time_snapshot_enable; + adpt_ptp_rtc_time_snapshot_status_get_func adpt_ptp_rtc_time_snapshot_status_get; + adpt_ptp_increment_sync_from_clock_enable_func adpt_ptp_increment_sync_from_clock_enable; + adpt_ptp_increment_sync_from_clock_status_get_func \ + adpt_ptp_increment_sync_from_clock_status_get; + adpt_ptp_tod_uart_set_func adpt_ptp_tod_uart_set; + adpt_ptp_tod_uart_get_func adpt_ptp_tod_uart_get; + adpt_ptp_enhanced_timestamp_engine_set_func adpt_ptp_enhanced_timestamp_engine_set; + adpt_ptp_enhanced_timestamp_engine_get_func adpt_ptp_enhanced_timestamp_engine_get; + adpt_ptp_trigger_set_func adpt_ptp_trigger_set; + adpt_ptp_trigger_get_func adpt_ptp_trigger_get; + adpt_ptp_capture_set_func adpt_ptp_capture_set; + adpt_ptp_capture_get_func adpt_ptp_capture_get; + adpt_ptp_interrupt_set_func adpt_ptp_interrupt_set; + adpt_ptp_interrupt_get_func adpt_ptp_interrupt_get; + + /* sfp */ + adpt_sfp_eeprom_data_get_func adpt_sfp_eeprom_data_get; + adpt_sfp_eeprom_data_set_func adpt_sfp_eeprom_data_set; + adpt_sfp_diag_ctrl_status_get_func adpt_sfp_diag_ctrl_status_get; + adpt_sfp_diag_extenal_calibration_const_get_func + adpt_sfp_diag_extenal_calibration_const_get; + adpt_sfp_link_length_get_func adpt_sfp_link_length_get; + adpt_sfp_diag_internal_threshold_get_func adpt_sfp_diag_internal_threshold_get; + adpt_sfp_diag_realtime_get_func adpt_sfp_diag_realtime_get; + adpt_sfp_laser_wavelength_get_func adpt_sfp_laser_wavelength_get; + adpt_sfp_option_get_func adpt_sfp_option_get; + adpt_sfp_checkcode_get_func adpt_sfp_checkcode_get; + adpt_sfp_diag_alarm_warning_flag_get_func adpt_sfp_diag_alarm_warning_flag_get; + adpt_sfp_device_type_get_func adpt_sfp_device_type_get; + adpt_sfp_vendor_info_get_func adpt_sfp_vendor_info_get; + adpt_sfp_transceiver_code_get_func adpt_sfp_transceiver_code_get; + adpt_sfp_ctrl_rate_get_func adpt_sfp_ctrl_rate_get; + adpt_sfp_enhanced_cfg_get_func adpt_sfp_enhanced_cfg_get; + adpt_sfp_rate_encode_get_func adpt_sfp_rate_encode_get; + /*led*/ + adpt_led_ctrl_pattern_set_func adpt_led_ctrl_pattern_set; + adpt_led_ctrl_pattern_get_func adpt_led_ctrl_pattern_get; + adpt_led_ctrl_source_set_func adpt_led_ctrl_source_set; +}adpt_api_t; + + +adpt_api_t *adpt_api_ptr_get(a_uint32_t dev_id); +sw_error_t adpt_init(a_uint32_t dev_id, ssdk_init_cfg *cfg); +sw_error_t adpt_module_func_ctrl_set(a_uint32_t dev_id, + a_uint32_t module, fal_func_ctrl_t *func_ctrl); +sw_error_t adpt_module_func_ctrl_get(a_uint32_t dev_id, + a_uint32_t module, fal_func_ctrl_t *func_ctrl); +sw_error_t adpt_module_func_init(a_uint32_t dev_id, ssdk_init_cfg *cfg); +#ifdef SCOMPHY +a_uint32_t adapt_scomphy_revision_get(a_uint32_t dev_id); +#endif +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/adpt/cppe/adpt_cppe_flow.h b/feeds/ipq807x/qca-ssdk/src/include/adpt/cppe/adpt_cppe_flow.h new file mode 100755 index 000000000..72480e511 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/adpt/cppe/adpt_cppe_flow.h @@ -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. + */ + + +/** + * @defgroup + * @{ + */ +#ifndef _ADPT_CPPE_FLOW_ +#define _ADPT_CPPE_FLOW_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef IN_FLOW_MINI +sw_error_t +adpt_cppe_flow_copy_escape_set(a_uint32_t dev_id, a_bool_t enable); + +sw_error_t +adpt_cppe_flow_copy_escape_get(a_uint32_t dev_id, a_bool_t *enable); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/adpt/cppe/adpt_cppe_mib.h b/feeds/ipq807x/qca-ssdk/src/include/adpt/cppe/adpt_cppe_mib.h new file mode 100755 index 000000000..3b1302e8d --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/adpt/cppe/adpt_cppe_mib.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. + */ +/** + * @defgroup + * @{ + */ +#ifndef _ADPT_CPPE_MIB_H_ +#define _ADPT_CPPE_MIB_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +sw_error_t +adpt_cppe_lpbk_mib_cpukeep_get(a_uint32_t dev_id, a_uint32_t port_id, + a_bool_t *enable); + +sw_error_t +adpt_cppe_lpbk_mib_cpukeep_set(a_uint32_t dev_id, a_uint32_t port_id, + a_bool_t enable); + +sw_error_t +adpt_hppe_lpbk_mib_status_get(a_uint32_t dev_id, a_uint32_t port_id, + a_bool_t *enable); + +sw_error_t +adpt_cppe_lpbk_mib_status_set(a_uint32_t dev_id, a_uint32_t port_id, + a_bool_t enable); + +sw_error_t +adpt_cppe_lpbk_mib_flush_counters(a_uint32_t dev_id, + fal_port_t port_id); + +sw_error_t +adpt_cppe_lpbk_get_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info ); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/adpt/cppe/adpt_cppe_misc.h b/feeds/ipq807x/qca-ssdk/src/include/adpt/cppe/adpt_cppe_misc.h new file mode 100755 index 000000000..db2d7d989 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/adpt/cppe/adpt_cppe_misc.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. + */ + + +/** + * @defgroup + * @{ + */ +#ifndef _ADPT_CPPE_MISC_ +#define _ADPT_CPPE_MISC_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +sw_error_t +adpt_cppe_debug_port_counter_enable(a_uint32_t dev_id, fal_port_t port_id, + fal_counter_en_t *cnt_en); +sw_error_t +adpt_cppe_debug_port_counter_status_get(a_uint32_t dev_id, fal_port_t port_id, + fal_counter_en_t *cnt_en); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/adpt/cppe/adpt_cppe_portctrl.h b/feeds/ipq807x/qca-ssdk/src/include/adpt/cppe/adpt_cppe_portctrl.h new file mode 100755 index 000000000..9e38ed3cb --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/adpt/cppe/adpt_cppe_portctrl.h @@ -0,0 +1,103 @@ +/* + * 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. + */ + + +/** + * @defgroup + * @{ + */ +#ifndef _ADPT_CPPE_PORTCTRLH_ +#define _ADPT_CPPE_PORTCTRLH_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define CPPE_PORT3_PCS_SEL_PCS0_CHANNEL2 0x0 +#define CPPE_PORT3_PCS_SEL_PCS0_CHANNEL4 0x1 +#define CPPE_PORT4_PCS_SEL_PCS0_CHANNEL3 0x0 +#define CPPE_PORT4_PCS_SEL_PCS0_SGMIIPLUS 0x1 +#define CPPE_PORT5_PCS_SEL_PCS0_CHANNEL4 0x0 +#define CPPE_PORT5_PCS_SEL_PCS1_CHANNEL0 0x1 +#define CPPE_PORT5_GMAC_SEL_GMAC 0x0 +#define CPPE_PORT5_GMAC_SEL_XGMAC 0x1 +#define CPPE_PCS0_CHANNEL4_SEL_PORT5_CLOCK 0x0 +#define CPPE_PCS0_CHANNEL4_SEL_PORT3_CLOCK 0x1 +#define CPPE_PCS0_CHANNEL0_SEL_PSGMII 0x0 +#define CPPE_PCS0_CHANNEL0_SEL_SGMIIPLUS 0x1 +#define CPPE_DETECTION_PHY_FAILURE 0xFFFF +#define CPPE_LOOPBACK_PORT_RATE_FREQUENCY 300 /* 300MHZ*/ +#define CPPE_LOOPBACK_PORT_NUM 0x1 + +sw_error_t +_adpt_cppe_port_mux_mac_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t port_type); +sw_error_t +adpt_cppe_port_mru_set(a_uint32_t dev_id, fal_port_t port_id, + fal_mru_ctrl_t *ctrl); +sw_error_t +adpt_cppe_port_mru_get(a_uint32_t dev_id, fal_port_t port_id, + fal_mru_ctrl_t *ctrl); +#ifndef IN_PORTCONTROL_MINI +sw_error_t +adpt_cppe_port_mtu_set(a_uint32_t dev_id, fal_port_t port_id, + fal_mtu_ctrl_t *ctrl); +sw_error_t +adpt_cppe_port_mtu_get(a_uint32_t dev_id, fal_port_t port_id, + fal_mtu_ctrl_t *ctrl); +sw_error_t +adpt_cppe_port_source_filter_set(a_uint32_t dev_id, + fal_port_t port_id, a_bool_t enable); +sw_error_t +adpt_cppe_port_source_filter_get(a_uint32_t dev_id, + fal_port_t port_id, a_bool_t * enable); +sw_error_t +adpt_cppe_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 +adpt_cppe_port_source_filter_config_get + (a_uint32_t dev_id, fal_port_t port_id, + fal_src_filter_config_t* src_filter_config); +#endif +sw_error_t +adpt_cppe_port_to_channel_convert(a_uint32_t dev_id, + a_uint32_t port_id, a_uint32_t *channel_id); +sw_error_t +adpt_cppe_switch_port_loopback_set(a_uint32_t dev_id, + fal_port_t port_id, fal_loopback_config_t *loopback_cfg); + +sw_error_t +adpt_cppe_switch_port_loopback_get(a_uint32_t dev_id, + fal_port_t port_id, fal_loopback_config_t *loopback_cfg); + +sw_error_t +adpt_cppe_switch_port_loopback_flowctrl_set(a_uint32_t dev_id, + fal_port_t port_id, a_bool_t enable); + +sw_error_t +adpt_cppe_switch_port_loopback_flowctrl_get(a_uint32_t dev_id, + fal_port_t port_id, a_bool_t *enable); + +sw_error_t +adpt_cppe_lpbk_max_frame_size_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t *max_frame); + +sw_error_t +adpt_cppe_lpbk_max_frame_size_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t max_frame); +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/adpt/cppe/adpt_cppe_qm.h b/feeds/ipq807x/qca-ssdk/src/include/adpt/cppe/adpt_cppe_qm.h new file mode 100755 index 000000000..a38b475de --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/adpt/cppe/adpt_cppe_qm.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. + */ + + +/** + * @defgroup + * @{ + */ +#ifndef _ADPT_CPPE_QM_H_ +#define _ADPT_CPPE_QM_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef IN_QM_MINI +sw_error_t +adpt_cppe_qm_port_source_profile_set( + a_uint32_t dev_id, fal_port_t port, a_uint32_t src_profile); +sw_error_t +adpt_cppe_qm_port_source_profile_get( + a_uint32_t dev_id, fal_port_t port, a_uint32_t *src_profile); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif + + diff --git a/feeds/ipq807x/qca-ssdk/src/include/adpt/cppe/adpt_cppe_qos.h b/feeds/ipq807x/qca-ssdk/src/include/adpt/cppe/adpt_cppe_qos.h new file mode 100644 index 000000000..867e73346 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/adpt/cppe/adpt_cppe_qos.h @@ -0,0 +1,68 @@ +/* + * 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. + */ + + +/** + * @defgroup + * @{ + */ +#ifndef _ADPT_CPPE_QOS_H_ +#define _ADPT_CPPE_QOS_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +sw_error_t +adpt_cppe_qos_port_pri_set(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_pri_precedence_t *pri); +sw_error_t +adpt_cppe_qos_port_pri_get(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_pri_precedence_t *pri); +sw_error_t +adpt_cppe_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 +adpt_cppe_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 +adpt_cppe_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 +adpt_cppe_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 +adpt_cppe_qos_port_group_set(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_group_t *group); +sw_error_t +adpt_cppe_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 +adpt_cppe_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 +adpt_cppe_qos_port_group_get(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_group_t *group); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/include/adpt/cppe/adpt_cppe_uniphy.h b/feeds/ipq807x/qca-ssdk/src/include/adpt/cppe/adpt_cppe_uniphy.h new file mode 100755 index 000000000..635fdbf61 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/adpt/cppe/adpt_cppe_uniphy.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. + */ + + +/** + * @defgroup + * @{ + */ +#ifndef _ADPT_CPPE_UNIPHYH_ +#define _ADPT_CPPE_UNIPHYH_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +sw_error_t +__adpt_cppe_uniphy_channel_selection_set(a_uint32_t dev_id, + a_uint32_t ch0_selection, a_uint32_t ch4_selection); + +void +__adpt_hppe_gcc_uniphy_xpcs_reset(a_uint32_t dev_id, a_uint32_t uniphy_index, + a_bool_t enable); +sw_error_t +__adpt_hppe_uniphy_calibrate(a_uint32_t dev_id, a_uint32_t uniphy_index); + +void +__adpt_cppe_gcc_uniphy_software_reset(a_uint32_t dev_id, + a_uint32_t uniphy_index); +sw_error_t +__adpt_cppe_uniphy_mode_set(a_uint32_t dev_id, + a_uint32_t uniphy_index, a_uint32_t mode); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/adpt/hppe/adpt_hppe.h b/feeds/ipq807x/qca-ssdk/src/include/adpt/hppe/adpt_hppe.h new file mode 100755 index 000000000..d8c5be46f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/adpt/hppe/adpt_hppe.h @@ -0,0 +1,112 @@ +/* + * 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. + */ + + +/** + * @defgroup + * @{ + */ +#ifndef _ADPT_HPPE_H_ +#define _ADPT_HPPE_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +void adpt_hppe_fdb_func_bitmap_init(a_uint32_t dev_id); +sw_error_t adpt_hppe_fdb_init(a_uint32_t dev_id); +void adpt_hppe_portvlan_func_bitmap_init(a_uint32_t dev_id); +sw_error_t adpt_hppe_portvlan_init(a_uint32_t dev_id); +void adpt_hppe_ctrlpkt_func_bitmap_init(a_uint32_t dev_id); +sw_error_t adpt_hppe_ctrlpkt_init(a_uint32_t dev_id); +void adpt_hppe_servcode_func_bitmap_init(a_uint32_t dev_id); +sw_error_t adpt_hppe_servcode_init(a_uint32_t dev_id); +void adpt_hppe_rss_hash_func_bitmap_init(a_uint32_t dev_id); +sw_error_t adpt_hppe_rss_hash_init(a_uint32_t dev_id); +void adpt_hppe_mib_func_bitmap_init(a_uint32_t dev_id); +sw_error_t adpt_hppe_mib_init(a_uint32_t dev_id); +void adpt_hppe_stp_func_bitmap_init(a_uint32_t dev_id); +sw_error_t adpt_hppe_stp_init(a_uint32_t dev_id); +void adpt_hppe_vsi_func_bitmap_init(a_uint32_t dev_id); +sw_error_t adpt_hppe_vsi_init(a_uint32_t dev_id); +sw_error_t adpt_hppe_port_ctrl_init(a_uint32_t dev_id); +sw_error_t adpt_hppe_misc_init(a_uint32_t dev_id); + +void adpt_hppe_mirror_func_bitmap_init(a_uint32_t dev_id); +sw_error_t adpt_hppe_mirror_init(a_uint32_t dev_id); +void adpt_hppe_trunk_func_bitmap_init(a_uint32_t dev_id); +sw_error_t adpt_hppe_trunk_init(a_uint32_t dev_id); +void adpt_hppe_ip_func_bitmap_init(a_uint32_t dev_id); +sw_error_t adpt_hppe_ip_init(a_uint32_t dev_id); +void adpt_hppe_qm_func_bitmap_init(a_uint32_t dev_id); +sw_error_t adpt_hppe_qm_init(a_uint32_t dev_id); +void adpt_hppe_flow_func_bitmap_init(a_uint32_t dev_id); +sw_error_t adpt_hppe_flow_init(a_uint32_t dev_id); + +void adpt_hppe_pppoe_func_bitmap_init(a_uint32_t dev_id); +sw_error_t adpt_hppe_pppoe_init(a_uint32_t dev_id); +void adpt_hppe_sec_func_bitmap_init(a_uint32_t dev_id); +sw_error_t adpt_hppe_sec_init(a_uint32_t dev_id); + +void adpt_hppe_acl_func_bitmap_init(a_uint32_t dev_id); +sw_error_t adpt_hppe_acl_init(a_uint32_t dev_id); +void adpt_hppe_qos_func_bitmap_init(a_uint32_t dev_id); +sw_error_t adpt_hppe_qos_init(a_uint32_t dev_id); +void adpt_hppe_bm_func_bitmap_init(a_uint32_t dev_id); +sw_error_t adpt_hppe_bm_init(a_uint32_t dev_id); + +sw_error_t adpt_hppe_shaper_init(a_uint32_t dev_id); + +void adpt_hppe_port_ctrl_func_bitmap_init(a_uint32_t dev_id); + +void adpt_hppe_shaper_func_bitmap_init(a_uint32_t dev_id); + +sw_error_t adpt_hppe_policer_init(a_uint32_t dev_id); + +void adpt_hppe_policer_func_bitmap_init(a_uint32_t dev_id); + +sw_error_t adpt_hppe_uniphy_init(a_uint32_t dev_id); + +/*shaper*/ +#define HPPE_MAX_C_TOKEN_NUM 0x3fffffff +#define HPPE_MAX_E_TOKEN_NUM 0x3fffffff + +#define HPPE_POLICER_TIMESLOT_DFT 600 +#define HPPE_PORT_SHAPER_TIMESLOT_DFT 8 +#define HPPE_FLOW_SHAPER_TIMESLOT_DFT 64 +#define HPPE_QUEUE_SHAPER_TIMESLOT_DFT 300 +#define HPPE_SHAPER_IPG_PREAMBLE_LEN_DFT 20 + +/*BM*/ +#define HPPE_BM_PORT_NUM 15 +#define HPPE_BM_PHY_PORT_OFFSET 8 + +void adpt_hppe_ptp_func_bitmap_init(a_uint32_t dev_id); +sw_error_t adpt_hppe_ptp_init(a_uint32_t dev_id); + +#define HPPE_REVISION 0x0 +#define CPPE_REVISION 0x1 +#define UNKNOWN_REVISION 0xff + +a_uint32_t adpt_hppe_chip_revision_get(a_uint32_t dev_id); + +#ifdef IN_FDB +sw_error_t +adpt_hppe_fdb_del_by_port(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t flag); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/adpt/mp/adpt_mp.h b/feeds/ipq807x/qca-ssdk/src/include/adpt/mp/adpt_mp.h new file mode 100644 index 000000000..47ba498c4 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/adpt/mp/adpt_mp.h @@ -0,0 +1,43 @@ +/* + * 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 _ADPT_MP_H_ +#define _ADPT_MP_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define MP_PORT_TO_GMAC_ID(port_id) (port_id -1) +#define MP_MAX_PORT 2 +#define MP_GMAC0 0 +#define MP_GMAC1 1 +#define MP_PORT_ID_CHECK(port_id) \ +do { \ + if (port_id > MP_MAX_PORT) \ + return SW_OUT_OF_RANGE; \ +} while (0) + +sw_error_t adpt_mp_intr_init(a_uint32_t dev_id); +sw_error_t adpt_mp_mib_init(a_uint32_t dev_id); +sw_error_t adpt_mp_portctrl_init(a_uint32_t dev_id); +sw_error_t adpt_mp_uniphy_init(a_uint32_t dev_id); +sw_error_t adpt_mp_led_init(a_uint32_t dev_id); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/adpt/mp/adpt_mp_portctrl.h b/feeds/ipq807x/qca-ssdk/src/include/adpt/mp/adpt_mp_portctrl.h new file mode 100755 index 000000000..8eb35ad8d --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/adpt/mp/adpt_mp_portctrl.h @@ -0,0 +1,45 @@ +/* + * 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 _ADPT_PORTCTRL_H_ +#define _ADPT_PORTCTRL_H_ + + +#define GMAC_SPEED_10M 0x0 +#define GMAC_SPEED_100M 0x1 +#define GMAC_SPEED_1000M 0x0 +#define GMAC_FULL_DUPLEX 0x1 +#define GMAC_HALF_DUPLEX 0x0 +#define GMAC_PAUSE_TIME 0xffff +#define GMAC_PAUSE_ZERO_QUANTA_ENABLE 0x0 +#define GMAC_JD_ENABLE 0x1 +#define GMAC_WD_DISABLE 0x0 +#define GMAC_FRAME_BURST_ENABLE 0x1 +#define GMAC_JUMBO_FRAME_ENABLE 0x1 +#define GMAC_MAX_FRAME_CTRL_ENABLE 0x1 +#define GMAC_LPI_LINK_UP 0x1 +#define GMAC_LPI_AUTO_MODE 0x1 +#define GMAC_TX_STORE_FORWAD_ENABLE 0x1 +#define GMAC_RX_STORE_FORWAD_ENABLE 0x1 +#define GMAC_FORWARD_ERROR_FRAME_DISABLE 0x0 +#define GMAC_DROP_GAINT_FRAME_DISABLE 0x0 +#define GMAC_HW_FLOWCTRL_ENABLE 0x1 +#define GMAC_HW_FLOWCTRL_DISABLE 0x0 +#define PORT_LPI_ENABLE_STATUS 0x3 +#define PORT_LPI_TASK_RUNNING 0x10000 +#define PORT_LPI_TASK_START 0x20000 + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/adpt/mp/adpt_mp_uniphy.h b/feeds/ipq807x/qca-ssdk/src/include/adpt/mp/adpt_mp_uniphy.h new file mode 100755 index 000000000..1e20b712c --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/adpt/mp/adpt_mp_uniphy.h @@ -0,0 +1,45 @@ +/* + * 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. + */ + + +/** + * @defgroup + * @{ + */ +#ifndef _ADPT_MP_UNIPHY_H_ +#define _ADPT_MP_UNIPHY_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +void +adpt_mp_gcc_uniphy_port_reset(a_uint32_t dev_id, a_uint32_t port_id); + +sw_error_t +adpt_mp_gcc_uniphy_port_clock_set(a_uint32_t dev_id, a_uint32_t port_id, + a_bool_t enable); + +sw_error_t +adpt_mp_uniphy_adapter_port_reset(a_uint32_t dev_id, a_uint32_t port_id); + +sw_error_t +adpt_mp_uniphy_mode_configure(a_uint32_t dev_id, a_uint32_t index, a_uint32_t mode); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/adpt/sfp/adpt_sfp.h b/feeds/ipq807x/qca-ssdk/src/include/adpt/sfp/adpt_sfp.h new file mode 100755 index 000000000..81cdf38a2 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/adpt/sfp/adpt_sfp.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. + */ + + +/** + * @defgroup + * @{ + */ +#ifndef _ADPT_SFP_H_ +#define _ADPT_SFP_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +sw_error_t adpt_sfp_init(a_uint32_t dev_id); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/api/api_access.h b/feeds/ipq807x/qca-ssdk/src/include/api/api_access.h new file mode 100755 index 000000000..78e9eb07b --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/api/api_access.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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/src/include/api/api_desc.h b/feeds/ipq807x/qca-ssdk/src/include/api/api_desc.h new file mode 100755 index 000000000..078728f06 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/api/api_desc.h @@ -0,0 +1,4762 @@ +/* + * Copyright (c) 2012, 2015-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_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_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Status"), + +#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"), +/*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, "miss xlt cmd"), + +#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, "miss xlt cmd"), + +#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, "Egress 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, "Egress 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, "Enable"), + +#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, "Enable"), + +#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_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_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_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_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_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_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_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_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_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_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_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_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, \ + sizeof(a_bool_t), 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_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_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_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 Status"), + +#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 Status"), + +#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_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 buff"), \ + SW_PARAM_DEF(SW_API_BM_PORT_RSVBUFFER_GET, SW_UINT16, 2, \ + SW_PARAM_PTR|SW_PARAM_OUT, "react buff"), + +#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_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_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_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(SW_PTP_INTERRUPT), \ + 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(SW_PTP_INTERRUPT), \ + 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/src/include/api/sw_api.h b/feeds/ipq807x/qca-ssdk/src/include/api/sw_api.h new file mode 100755 index 000000000..127fb59ef --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/api/sw_api.h @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2012, 2015-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} + +#define SW_PARAM_DEF(ioctl, data, size, type, name) {ioctl, size, data, type} + +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_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_FRAME_MAX_SIZE, + SW_SOURCE_FILTER, + 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_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_BMSTHRESH, + SW_BMDTHRESH, + SW_BMPORTCNT, + SW_PORT_SHAPER_TOKEN_CONFIG, + SW_SHAPER_TOKEN_CONFIG, + SW_PORT_SHAPER_CONFIG, + SW_SHAPER_CONFIG, + 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_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_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; + } 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/src/include/api/sw_ioctl.h b/feeds/ipq807x/qca-ssdk/src/include/api/sw_ioctl.h new file mode 100755 index 000000000..fd26b5dea --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/api/sw_ioctl.h @@ -0,0 +1,987 @@ +/* + * Copyright (c) 2012, 2015-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) + + /* 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) + +/* 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) +/*qca808x_start*/ +#define SW_API_PHY_I2C_GET (22 + SW_API_DEBUG_OFFSET) +#define SW_API_PHY_I2C_SET (23 + SW_API_DEBUG_OFFSET) + +#define SW_API_MAX 0xffff + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _SW_IOCTL_H_ */ +/*qca808x_end*/ diff --git a/feeds/ipq807x/qca-ssdk/src/include/common/aos_head.h b/feeds/ipq807x/qca-ssdk/src/include/common/aos_head.h new file mode 100755 index 000000000..b4962118b --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/common/aos_head.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2012,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 "aos_mem.h" +#include "aos_timer.h" +#include "aos_lock.h" +#include "aos_types.h" + diff --git a/feeds/ipq807x/qca-ssdk/src/include/common/shared_func.h b/feeds/ipq807x/qca-ssdk/src/include/common/shared_func.h new file mode 100755 index 000000000..729938c32 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/common/shared_func.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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_CNTU_ON_ERROR_AND_COND1_OR_GOTO_OUT(rtn, cond1) \ + { \ + if ((rtn != SW_OK)) { \ + if (rtn == cond1) \ + continue; \ + else \ + goto out; \ + } \ + } + +#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/src/include/common/sw.h b/feeds/ipq807x/qca-ssdk/src/include/common/sw.h new file mode 100755 index 000000000..fa82d561a --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/common/sw.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2012,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/src/include/common/sw_config.h b/feeds/ipq807x/qca-ssdk/src/include/common/sw_config.h new file mode 100755 index 000000000..d1c4f6956 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/common/sw_config.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2012, 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/src/include/common/sw_error.h b/feeds/ipq807x/qca-ssdk/src/include/common/sw_error.h new file mode 100755 index 000000000..7a175173f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/common/sw_error.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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/src/include/common/util.h b/feeds/ipq807x/qca-ssdk/src/include/common/util.h new file mode 100755 index 000000000..9baa22e9f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/common/util.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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_ulong_t *iterator); + + void *sll_nd_next(const sll_head_t *sll, a_ulong_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/src/include/fal/fal.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal.h new file mode 100755 index 000000000..09d21ffd6 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2012, 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_flow.h" +#include "fal_qm.h" +#include "fal_sec.h" +#include "fal_trunk.h" +#include "fal_interface_ctrl.h" +#include "fal_fdb.h" +#include "fal_multi.h" +#include "fal_ctrlpkt.h" +#include "fal_servcode.h" +#include "fal_rss_hash.h" +#include "fal_vsi.h" +#include "fal_pppoe.h" +#include "fal_bm.h" +#include "fal_shaper.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/src/include/fal/fal_acl.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_acl.h new file mode 100755 index 000000000..e9c9f9cf8 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_acl.h @@ -0,0 +1,616 @@ +/* + * 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. + */ + + +/** + * @defgroup fal_acl FAL_ACL + * @{ + */ +#ifndef _FAL_ACL_H_ +#define _FAL_ACL_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "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 than equal*/ + FAL_ACL_FIELD_GE, /**< match operation is greater than 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, /*start from L2 */ + FAL_ACL_UDF_TYPE_L3, /*start from L3 */ + FAL_ACL_UDF_TYPE_L4, /*start from L4 */ + FAL_ACL_UDF_TYPE_L2_SNAP, /*start from SNAP L2 */ + FAL_ACL_UDF_TYPE_L3_PLUS, /*start from SNAP L3 */ + 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, /*UDF for non-ip packets*/ + FAL_ACL_UDF_IP4, /*UDF for IPv4 packets*/ + FAL_ACL_UDF_IP6, /*UDF for IPv6 packets*/ + 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;/*mac, IP4, IP6 and UDF*/ + fal_acl_field_map_t field_flg;/*Indicate which fields are selected*/ + + /* fields of mac rule */ + fal_mac_addr_t src_mac_val;/*source mac*/ + fal_mac_addr_t src_mac_mask;/*source mac mask*/ + fal_mac_addr_t dest_mac_val;/*destination mac*/ + fal_mac_addr_t dest_mac_mask;/*destionation mac mask*/ + a_uint16_t ethtype_val;/*ethernet type*/ + a_uint16_t ethtype_mask;/*ethernet type mask*/ + a_uint16_t vid_val;/*vlan id, IPQ807x not support*/ + a_uint16_t vid_mask;/*vlan id mask*/ + fal_acl_field_op_t vid_op;/*vlan id operation, larger than or smaller than or range or mask*/ + a_uint8_t tagged_val;/*tagged or not, IPQ807x not support*/ + a_uint8_t tagged_mask;/*tagged or not mask*/ + a_uint8_t up_val;/*cos priority, IPQ807x not support*/ + a_uint8_t up_mask;/*cos priority mask*/ + a_uint8_t cfi_val;/*CFI value, IPQ807x not support*/ + a_uint8_t cfi_mask;/*CFI value mask*/ + a_uint16_t resv0;/*reserved*/ + + /* 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;/*same as stagged define*/ + a_uint8_t ctagged_mask; + a_uint16_t stag_vid_val;/*stag vlan id*/ + a_uint16_t stag_vid_mask;/*stag vlan id mask*/ + fal_acl_field_op_t stag_vid_op;/*vlan id operation, larger than or smaller than or range or mask*/ + 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;/*stag priority*/ + a_uint8_t stag_pri_mask;/*stag priority mask*/ + a_uint8_t ctag_pri_val; + a_uint8_t ctag_pri_mask; + a_uint8_t stag_dei_val;/*stag dei*/ + a_uint8_t stag_dei_mask;/*stag dei mask*/ + a_uint8_t ctag_cfi_val;/*ctag cfi*/ + a_uint8_t ctag_cfi_mask;/*ctag cfi mask*/ + + /* fields of ip4 rule */ + fal_ip4_addr_t src_ip4_val;/*source ipv4 address*/ + fal_ip4_addr_t src_ip4_mask;/*source ipv4 address mask*/ + fal_ip4_addr_t dest_ip4_val;/*destination ipv4 address*/ + fal_ip4_addr_t dest_ip4_mask;/*destination ipv4 address mask*/ + + /* fields of ip6 rule */ + a_uint32_t ip6_lable_val;/*ipv6 flow lable, IPQ807x not support*/ + a_uint32_t ip6_lable_mask;/*ipv6 flow lable mask*/ + fal_ip6_addr_t src_ip6_val;/*source ipv6 address*/ + fal_ip6_addr_t src_ip6_mask;/*source ipv6 address mask*/ + fal_ip6_addr_t dest_ip6_val;/*destination ipv6 address*/ + fal_ip6_addr_t dest_ip6_mask;/*destination ipv6 address mask*/ + + /* fields of ip rule */ + a_uint8_t ip_proto_val;/*IP protocal*/ + a_uint8_t ip_proto_mask;/*IP protocal mask*/ + a_uint8_t ip_dscp_val;/*IP DSCP*/ + a_uint8_t ip_dscp_mask;/*IP DSCP mask*/ + + /* fields of layer four */ + a_uint16_t src_l4port_val;/*source L4 port*/ + a_uint16_t src_l4port_mask;/*source L4 port mask*/ + fal_acl_field_op_t src_l4port_op;/*source L4 port operation*/ + a_uint16_t dest_l4port_val;/*destination L4 port*/ + a_uint16_t dest_l4port_mask;/*destination L4 mask*/ + fal_acl_field_op_t dest_l4port_op;/*destination L4 operation*/ + a_uint8_t icmp_type_val;/*ICMP type*/ + a_uint8_t icmp_type_mask;/*ICMP type mask*/ + a_uint8_t icmp_code_val;/*ICMP code*/ + a_uint8_t icmp_code_mask;/*ICMP code mask*/ + a_uint8_t tcp_flag_val;/*tcp flags value*/ + a_uint8_t tcp_flag_mask;/*tcp flags mask*/ + a_uint8_t ripv1_val;/*Is RIPv1 or not, IPQ807x not support*/ + a_uint8_t ripv1_mask;/*RIPv1 mask*/ + a_uint8_t dhcpv4_val;/*Is DHCPv4 or not, IPQ807x not support*/ + a_uint8_t dhcpv4_mask; + a_uint8_t dhcpv6_val;/*Is DHCPv6 or not, IPQ807x not support*/ + a_uint8_t dhcpv6_mask; + + /* user defined fields */ + fal_acl_udf_type_t udf_type;/*UDF type, IPQ807x not support*/ + a_uint8_t udf_offset;/*UDF offset, IPQ807x not support*/ + a_uint8_t udf_len;/*UDF length, IPQ807x not support*/ + a_uint8_t udf_val[FAL_ACL_UDF_MAX_LENGTH];/*UDF field value*/ + a_uint8_t udf_mask[FAL_ACL_UDF_MAX_LENGTH];/*UDF field mask*/ + + /* fields of action */ + fal_acl_action_map_t action_flg;/*Indicate which action apply*/ + fal_pbmp_t ports; /*high 8bits, 00-port bitmap, 01-nexthop, 10-vp*/ + a_uint32_t match_cnt;/*rule match frame counter*/ + a_uint16_t vid;/*modify vlan id, IPQ807x not support*/ + a_uint8_t up;/*modify COS priority, IPQ807x not support*/ + a_uint8_t queue;/*modify queue*/ + a_uint16_t stag_vid;/*modify stag vlan id*/ + a_uint8_t stag_pri;/*modify stag priority*/ + a_uint8_t stag_dei;/*modify stag dei*/ + a_uint16_t ctag_vid;/*modify ctag vlan id*/ + a_uint8_t ctag_pri;/*modify ctag priority*/ + a_uint8_t ctag_cfi;/*modify ctag dei*/ + a_uint16_t policer_ptr;/*specify policer index*/ + a_uint16_t arp_ptr;/*specify arp table index, IPQ807x not support*/ + a_uint16_t wcmp_ptr;/*specify wcmp table index, IPQ807x not support*/ + a_uint8_t dscp;/*modify dscp*/ + a_uint8_t rsv; + fal_policy_forward_t policy_fwd;/*SNAT or DNAT or ROUTE, IPQ807x not support*/ + fal_combined_t combined; + + /*Only IPQ807x support start*/ + a_uint8_t pri; /*rule priority 0-7*/ + a_bool_t post_routing;/*post routing or not*/ + a_uint8_t acl_pool;/*acl pool*/ + + a_bool_t is_ip_val;/*is ip or not*/ + a_uint8_t is_ip_mask; + a_bool_t is_ipv6_val;/*is ipv6 or ipv4*/ + a_uint8_t is_ipv6_mask; + a_bool_t is_fake_mac_header_val;/*is fake mac header or not*/ + a_uint8_t is_fake_mac_header_mask; + a_bool_t is_snap_val;/*is snap or not*/ + a_uint8_t is_snap_mask; + a_bool_t is_ethernet_val;/*is ethernet or not*/ + a_uint8_t is_ethernet_mask; + + a_bool_t is_fragement_val;/*is fragment or not*/ + a_uint8_t is_fragement_mask; + + a_bool_t is_ah_header_val;/*is ah header or not*/ + a_uint8_t is_ah_header_mask; + + a_bool_t is_esp_header_val;/*is esp header or not*/ + a_uint8_t is_esp_header_mask; + + a_bool_t is_mobility_header_val;/*is mobility header or not*/ + a_uint8_t is_mobility_header_mask; + + a_bool_t is_fragment_header_val;/*is fragment header or not*/ + a_uint8_t is_fragment_header_mask; + + a_bool_t is_other_header_val;/*is other header or not*/ + a_uint8_t is_other_header_mask; + + a_bool_t is_ipv4_option_val;/*is ipv4 option or not*/ + a_uint8_t is_ipv4_option_mask; + + a_bool_t is_first_frag_val;/*is first fragment or not*/ + a_uint8_t is_first_frag_mask; + + /*fields of VLAN rule*/ + a_bool_t vsi_valid;/*vsi valid or not*/ + a_uint8_t vsi_valid_mask; + a_uint8_t vsi; /*vsi value 0-31*/ + a_uint8_t vsi_mask; /*vsi mask 0-31*/ + /*fields of L2 MISC rule*/ + a_uint16_t pppoe_sessionid;/*pppoe session id*/ + a_uint16_t pppoe_sessionid_mask;/*pppoe session mask*/ + fal_acl_field_op_t icmp_type_code_op;/*icmp type operation*/ + /*fields of IP MISC rule*/ + a_uint8_t l3_ttl;/*L3 TTL,0-ttl 0, 1-ttl 1, 2-ttl 255, 3- ttl other*/ + a_uint8_t l3_ttl_mask;/*L3 TTL mask*/ + fal_acl_field_op_t l3_length_op;/*L3 TTL operation*/ + a_uint16_t l3_length;/*L3 length*/ + a_uint16_t l3_length_mask;/*L3 length mask*/ + a_uint16_t l3_pkt_type;/*l3 packet type, 0-tcp, 1-udp, 3-udp_lite, 5-arp, 7-icmp*/ + a_uint16_t l3_pkt_type_mask; + /*field of udf*/ + fal_acl_field_op_t udf0_op;/*udf operation*/ + a_uint16_t udf0_val;/*udf value, 2bytes*/ + a_uint16_t udf0_mask;/*udf mask, 2bytes*/ + 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;/*bypass bitmap*/ + a_uint8_t enqueue_pri;/*enqueue priority*/ + a_uint8_t stag_fmt;/*stag format*/ + a_uint8_t ctag_fmt;/*ctag format*/ + a_uint8_t int_dp;/*internal dp*/ + a_uint8_t service_code;/*service code*/ + a_uint8_t cpu_code;/*cpu code*/ + a_uint64_t match_bytes;/*rule match bytes counter*/ + /*Only IPQ807x support End*/ + + /*new add acl action for IPQ60xx*/ + a_uint8_t dscp_mask;/*modify dscp mask,IPQ60xx support*/ + a_uint8_t qos_res_prec;/*qos res prec,IPQ60xx support*/ +} 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/src/include/fal/fal_api.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_api.h new file mode 100755 index 000000000..dcd6f0af3 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_api.h @@ -0,0 +1,2419 @@ +/* + * Copyright (c) 2012, 2015-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 +#ifndef IN_PORTCONTROL_MINI +/*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_SET, fal_port_interface_mode_set), \ + SW_API_DEF(SW_API_PT_INTERFACE_MODE_APPLY, fal_port_interface_mode_apply), \ + 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 \ + SW_API_DEF(SW_API_PT_DUPLEX_SET, fal_port_duplex_set), \ + SW_API_DEF(SW_API_PT_SPEED_SET, fal_port_speed_set), \ + 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_SET, fal_port_autoneg_adv_set), \ + SW_API_DEF(SW_API_PT_LINK_MODE_SET, fal_port_link_forcemode_set), \ + SW_API_DEF(SW_API_PT_TXHDR_SET, fal_port_txhdr_mode_set), \ + SW_API_DEF(SW_API_PT_RXHDR_SET, fal_port_rxhdr_mode_set), \ + SW_API_DEF(SW_API_HEADER_TYPE_SET, fal_header_type_set), \ + SW_API_DEF(SW_API_TXMAC_STATUS_SET, fal_port_txmac_status_set), \ + SW_API_DEF(SW_API_RXMAC_STATUS_SET, fal_port_rxmac_status_set), \ + 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_TXFC_STATUS_SET, fal_port_txfc_status_set), \ + SW_API_DEF(SW_API_RXFC_STATUS_SET, fal_port_rxfc_status_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), +/*end of PORTCONTROL_API*/ +#define PORTCONTROL_API_PARAM \ + SW_API_DESC(SW_API_PT_DUPLEX_SET) \ + SW_API_DESC(SW_API_PT_SPEED_SET) \ + SW_API_DESC(SW_API_PT_AN_ENABLE) \ + SW_API_DESC(SW_API_PT_AN_RESTART) \ + SW_API_DESC(SW_API_PT_AN_ADV_SET) \ + SW_API_DESC(SW_API_PT_LINK_MODE_SET) \ + SW_API_DESC(SW_API_PT_TXHDR_SET) \ + SW_API_DESC(SW_API_PT_RXHDR_SET) \ + SW_API_DESC(SW_API_HEADER_TYPE_SET) \ + SW_API_DESC(SW_API_TXMAC_STATUS_SET) \ + SW_API_DESC(SW_API_RXMAC_STATUS_SET) \ + SW_API_DESC(SW_API_PT_POWER_OFF) \ + SW_API_DESC(SW_API_PT_POWER_ON) \ + SW_API_DESC(SW_API_TXFC_STATUS_SET) \ + SW_API_DESC(SW_API_RXFC_STATUS_SET) \ + SW_API_DESC(SW_API_PT_SWITCH_PORT_LOOPBACK_SET) \ + SW_API_DESC(SW_API_PT_SWITCH_PORT_LOOPBACK_GET) +/*end of PORTCONTROL_API_PARAM*/ +#endif + +#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 +#ifndef IN_PORTVLAN_MINI +#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 \ + 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), \ + SW_API_DEF(SW_API_PT_ING_MODE_SET, fal_port_1qmode_set), \ + 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_DEF_VID_SET, fal_port_default_vid_set), \ + SW_API_DEF(SW_API_PT_FORCE_DEF_VID_SET, fal_port_force_default_vid_set), \ + SW_API_DEF(SW_API_PT_FORCE_PORTVLAN_SET, fal_port_force_portvlan_set), \ + SW_API_DEF(SW_API_PT_NESTVLAN_SET, fal_port_nestvlan_set), \ + SW_API_DEF(SW_API_NESTVLAN_TPID_SET, fal_nestvlan_tpid_set), \ + SW_API_DEF(SW_API_PT_IN_VLAN_MODE_SET, fal_port_invlan_mode_set), \ + SW_API_DEF(SW_API_PT_DEF_SVID_SET, fal_port_default_svid_set), \ + SW_API_DEF(SW_API_PT_DEF_CVID_SET, fal_port_default_cvid_set), + +#define PORTVLAN_API_PARAM \ + 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) \ + SW_API_DESC(SW_API_PT_ING_MODE_SET) \ + 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_DEF_VID_SET) \ + SW_API_DESC(SW_API_PT_FORCE_DEF_VID_SET) \ + SW_API_DESC(SW_API_PT_FORCE_PORTVLAN_SET) \ + SW_API_DESC(SW_API_PT_NESTVLAN_SET) \ + SW_API_DESC(SW_API_NESTVLAN_TPID_SET) \ + SW_API_DESC(SW_API_PT_IN_VLAN_MODE_SET) \ + SW_API_DESC(SW_API_PT_DEF_SVID_SET) \ + SW_API_DESC(SW_API_PT_DEF_CVID_SET) + +#endif + +#else +#define PORTVLAN_API +#define PORTVLAN_API_PARAM +#endif + +#ifdef IN_FDB +#ifndef IN_FDB_MINI +#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 \ + SW_API_DEF(SW_API_FDB_PT_LEARN_SET, fal_fdb_port_learn_set), \ + SW_API_DEF(SW_API_FDB_EXTEND_FIRST, fal_fdb_entry_extend_getfirst), \ + SW_API_DEF(SW_API_FDB_EXTEND_NEXT, fal_fdb_entry_extend_getnext), + +#define FDB_API_PARAM \ + SW_API_DESC(SW_API_FDB_PT_LEARN_SET) \ + SW_API_DESC(SW_API_FDB_EXTEND_FIRST) \ + SW_API_DESC(SW_API_FDB_EXTEND_NEXT) +#endif +#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 +#ifndef IN_QOS_MINI +#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 \ + SW_API_DEF(SW_API_QOS_PT_MODE_SET, fal_qos_port_mode_set), + + +#define QOS_API_PARAM \ + SW_API_DESC(SW_API_QOS_PT_MODE_SET) + +#endif +#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 +#ifndef IN_MISC_MINI +#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 \ + SW_API_DEF(SW_API_PT_UNK_SA_CMD_SET, fal_port_unk_sa_cmd_set), \ + SW_API_DEF(SW_API_PT_UNK_UC_FILTER_SET, fal_port_unk_uc_filter_set), \ + SW_API_DEF(SW_API_PT_UNK_MC_FILTER_SET, fal_port_unk_mc_filter_set), \ + SW_API_DEF(SW_API_PT_BC_FILTER_SET, fal_port_bc_filter_set), \ + SW_API_DEF(SW_API_EAPOL_STATUS_SET, fal_eapol_status_set), \ + SW_API_DEF(SW_API_EAPOL_CMD_SET, fal_eapol_cmd_set), \ + SW_API_DEF(SW_API_CPU_PORT_STATUS_SET, fal_cpu_port_status_set), + +#define MISC_API_PARAM \ + SW_API_DESC(SW_API_PT_UNK_SA_CMD_SET) \ + SW_API_DESC(SW_API_PT_UNK_UC_FILTER_SET) \ + SW_API_DESC(SW_API_PT_UNK_MC_FILTER_SET) \ + SW_API_DESC(SW_API_PT_BC_FILTER_SET) \ + SW_API_DESC(SW_API_EAPOL_CMD_SET) \ + SW_API_DESC(SW_API_EAPOL_STATUS_SET) \ + SW_API_DESC(SW_API_CPU_PORT_STATUS_SET) + +#endif + +#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 +#ifndef IN_COSMAP_MINI +#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 \ + SW_API_DEF(SW_API_COSMAP_PRI_TO_QU_SET, fal_cosmap_pri_to_queue_set), \ + SW_API_DEF(SW_API_COSMAP_PRI_TO_EHQU_SET, fal_cosmap_pri_to_ehqueue_set), + +#define COSMAP_API_PARAM \ + SW_API_DESC(SW_API_COSMAP_PRI_TO_QU_SET) \ + SW_API_DESC(SW_API_COSMAP_PRI_TO_EHQU_SET) +#endif +#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 +#ifndef IN_IP_MINI +#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 +#else +#define IP_API +#define IP_API_PARAM +#endif + +#ifdef IN_FLOW +#ifndef IN_FLOW_MINI +#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 \ + SW_API_DEF(SW_API_FLOW_CTRL_SET, fal_flow_mgmt_set), \ + SW_API_DEF(SW_API_FLOW_CTRL_GET, fal_flow_mgmt_get), + +#define FLOW_API_PARAM \ + SW_API_DESC(SW_API_FLOW_CTRL_SET) \ + SW_API_DESC(SW_API_FLOW_CTRL_GET) +#endif +#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 +#ifndef IN_VSI_MINI +#define VSI_API \ + SW_API_DEF(SW_API_VSI_ALLOC, ppe_vsi_alloc), \ + SW_API_DEF(SW_API_VSI_FREE, ppe_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, ppe_port_vlan_vsi_set), \ + SW_API_DEF(SW_API_PORT_VLAN_VSI_GET, ppe_port_vlan_vsi_get), \ + SW_API_DEF(SW_API_VSI_TBL_DUMP, ppe_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 \ + SW_API_DEF(SW_API_VSI_ALLOC, ppe_vsi_alloc), \ + SW_API_DEF(SW_API_VSI_FREE, ppe_vsi_free), \ + SW_API_DEF(SW_API_PORT_VSI_SET, fal_port_vsi_set), \ + SW_API_DEF(SW_API_PORT_VLAN_VSI_SET, ppe_port_vlan_vsi_set), \ + SW_API_DEF(SW_API_PORT_VLAN_VSI_GET, ppe_port_vlan_vsi_get), \ + SW_API_DEF(SW_API_VSI_TBL_DUMP, ppe_vsi_tbl_dump), \ + 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_MEMBER_SET, fal_vsi_member_set), \ + SW_API_DEF(SW_API_VSI_MEMBER_GET, fal_vsi_member_get), + + +#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_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_SET) \ + SW_API_DESC(SW_API_VSI_STAMOVE_SET) \ + SW_API_DESC(SW_API_VSI_MEMBER_SET) \ + SW_API_DESC(SW_API_VSI_MEMBER_GET) +#endif +#else +#define VSI_API +#define VSI_API_PARAM +#endif + +#ifdef IN_QM +#ifndef IN_QM_MINI +#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 \ + SW_API_DEF(SW_API_UCAST_QUEUE_BASE_PROFILE_SET, fal_ucast_queue_base_profile_set), \ + SW_API_DEF(SW_API_QUEUE_FLUSH, fal_queue_flush), \ + SW_API_DEF(SW_API_AC_CTRL_SET, fal_ac_ctrl_set), \ + SW_API_DEF(SW_API_AC_PRE_BUFFER_SET, fal_ac_prealloc_buffer_set), \ + SW_API_DEF(SW_API_QUEUE_GROUP_SET, fal_ac_queue_group_set), \ + SW_API_DEF(SW_API_STATIC_THRESH_SET, fal_ac_static_threshold_set), \ + SW_API_DEF(SW_API_DYNAMIC_THRESH_SET, fal_ac_dynamic_threshold_set), \ + SW_API_DEF(SW_API_GOURP_BUFFER_SET, fal_ac_group_buffer_set), \ + SW_API_DEF(SW_API_QM_ENQUEUE_CTRL_SET, fal_qm_enqueue_ctrl_set), + +#define QM_API_PARAM \ + SW_API_DESC(SW_API_UCAST_QUEUE_BASE_PROFILE_SET) \ + SW_API_DESC(SW_API_QUEUE_FLUSH) \ + SW_API_DESC(SW_API_AC_CTRL_SET) \ + SW_API_DESC(SW_API_AC_PRE_BUFFER_SET) \ + SW_API_DESC(SW_API_QUEUE_GROUP_SET) \ + SW_API_DESC(SW_API_STATIC_THRESH_SET) \ + SW_API_DESC(SW_API_DYNAMIC_THRESH_SET) \ + SW_API_DESC(SW_API_GOURP_BUFFER_SET) \ + SW_API_DESC(SW_API_QM_ENQUEUE_CTRL_SET) +#endif +#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 +#ifndef IN_BM_MINI +#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 \ + SW_API_DEF(SW_API_BM_CTRL_SET, fal_port_bm_ctrl_set), \ + SW_API_DEF(SW_API_BM_PORTGROUP_MAP_SET, fal_port_bufgroup_map_set), \ + SW_API_DEF(SW_API_BM_GROUP_BUFFER_SET, fal_bm_bufgroup_buffer_set), \ + SW_API_DEF(SW_API_BM_PORT_RSVBUFFER_SET, fal_bm_port_reserved_buffer_set), \ + SW_API_DEF(SW_API_BM_DYNAMIC_THRESH_SET, fal_bm_port_dynamic_thresh_set), + +#define BM_API_PARAM \ + SW_API_DESC(SW_API_BM_CTRL_SET) \ + SW_API_DESC(SW_API_BM_PORTGROUP_MAP_SET) \ + SW_API_DESC(SW_API_BM_GROUP_BUFFER_SET) \ + SW_API_DESC(SW_API_BM_PORT_RSVBUFFER_SET) \ + SW_API_DESC(SW_API_BM_DYNAMIC_THRESH_SET) +#endif +#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_debug_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 +#ifndef IN_SHAPER_MINI +#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 \ + SW_API_DEF(SW_API_PORT_SHAPER_TIMESLOT_SET, fal_port_shaper_timeslot_set), \ + SW_API_DEF(SW_API_FLOW_SHAPER_TIMESLOT_SET, fal_flow_shaper_timeslot_set), \ + SW_API_DEF(SW_API_QUEUE_SHAPER_TIMESLOT_SET, fal_queue_shaper_timeslot_set), \ + SW_API_DEF(SW_API_PORT_SHAPER_TOKEN_NUMBER_SET, fal_port_shaper_token_number_set), \ + SW_API_DEF(SW_API_FLOW_SHAPER_TOKEN_NUMBER_SET, fal_flow_shaper_token_number_set), \ + SW_API_DEF(SW_API_QUEUE_SHAPER_TOKEN_NUMBER_SET, fal_queue_shaper_token_number_set), \ + SW_API_DEF(SW_API_PORT_SHAPER_SET, fal_port_shaper_set), \ + SW_API_DEF(SW_API_FLOW_SHAPER_SET, fal_flow_shaper_set), \ + 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), + + +#define SHAPER_API_PARAM \ + SW_API_DESC(SW_API_PORT_SHAPER_TIMESLOT_SET) \ + SW_API_DESC(SW_API_FLOW_SHAPER_TIMESLOT_SET) \ + SW_API_DESC(SW_API_QUEUE_SHAPER_TIMESLOT_SET) \ + SW_API_DESC(SW_API_PORT_SHAPER_TOKEN_NUMBER_SET) \ + SW_API_DESC(SW_API_FLOW_SHAPER_TOKEN_NUMBER_SET) \ + SW_API_DESC(SW_API_QUEUE_SHAPER_TOKEN_NUMBER_SET) \ + SW_API_DESC(SW_API_PORT_SHAPER_SET) \ + SW_API_DESC(SW_API_FLOW_SHAPER_SET) \ + 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) +#endif +#else +#define SHAPER_API +#define SHAPER_API_PARAM +#endif + +#ifdef IN_POLICER +#ifndef IN_POLICER_MINI +#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 \ + SW_API_DEF(SW_API_POLICER_TIMESLOT_SET, fal_policer_timeslot_set), \ + SW_API_DEF(SW_API_POLICER_COMPENSATION_SET, fal_port_policer_compensation_byte_set), + + +#define POLICER_API_PARAM \ + SW_API_DESC(SW_API_POLICER_TIMESLOT_SET) \ + SW_API_DESC(SW_API_POLICER_COMPENSATION_SET) +#endif +#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/src/include/fal/fal_bm.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_bm.h new file mode 100755 index 000000000..0f75c3b5a --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_bm.h @@ -0,0 +1,144 @@ +/* + * 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. + */ + + +/** + * @defgroup fal_qos FAL_QM + * @{ + */ +#ifndef _FAL_BM_H_ +#define _FAL_BM_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "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; + +typedef struct +{ + a_bool_t enable; + a_uint32_t offset; + a_uint32_t depth; +} fal_port_tdm_ctrl_t; + +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; + +#define FAL_PORT_TDB_DIR_INGRESS 0 +#define FAL_PORT_TDB_DIR_EGRESS 1 +typedef struct +{ + a_uint8_t valid; /* 0 for invalid and 1 for valid*/ + a_uint8_t direction; /* 0 for ingreee and 1 for egress */ + fal_port_t port; +} fal_port_tdm_tick_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, +}; + +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_bufgroup_map_set(a_uint32_t dev_id, fal_port_t port, + a_uint8_t group); + +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_bufgroup_buffer_set(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); + +#ifndef IN_BM_MINI +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_get(a_uint32_t dev_id, fal_port_t port, + a_uint8_t *group); +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_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_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); +#endif + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _PORT_BM_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/fal/fal_cosmap.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_cosmap.h new file mode 100755 index 000000000..707ce29ad --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_cosmap.h @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2012,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_cosmap FAL_COSMAP + * @{ + */ +#ifndef _FAL_COSMAP_H_ +#define _FAL_COSMAP_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "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; + +#ifndef IN_COSMAP_MINI + 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); +#endif + 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_ehqueue_set(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t queue); +#ifndef IN_COSMAP_MINI + 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_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); +#endif +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_COSMAP_H_ */ + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/fal/fal_ctrlpkt.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_ctrlpkt.h new file mode 100755 index 000000000..0903a2e64 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_ctrlpkt.h @@ -0,0 +1,100 @@ +/* + * 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. + */ + + +/** + * @defgroup fal_gen FAL_CTRLPKT + * @{ + */ +#ifndef _FAL_CTRLPKT_H_ +#define _FAL_CTRLPKT_H_ + +#ifdef __cplusplus +extern "C" { +#endif +/* __cplusplus */ + +#include "sw.h" +#include "fal/fal_type.h" + + +#if defined(SW_API_LOCK) && (!defined(HSL_STANDALONG)) +#define FAL_CTRLPKT_API_LOCK +#define FAL_CTRLPKT_API_UNLOCK +#else +#define FAL_CTRLPKT_API_LOCK +#define FAL_CTRLPKT_API_UNLOCK +#endif + + +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/src/include/fal/fal_fdb.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_fdb.h new file mode 100755 index 000000000..791dba9eb --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_fdb.h @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup fal_fdb FAL_FDB + * @{ + */ +#ifndef _FAL_FDB_H_ +#define _FAL_FDB_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "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; + + 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; + +#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, +}; + +#ifndef IN_FDB_MINI + sw_error_t + fal_fdb_entry_add(a_uint32_t dev_id, const fal_fdb_entry_t * entry); + + sw_error_t + fal_fdb_rfs_set(a_uint32_t dev_id, const fal_fdb_rfs_t * entry); + + sw_error_t + fal_fdb_rfs_del(a_uint32_t dev_id, const fal_fdb_rfs_t * entry); +#endif + + 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); + + +#ifndef IN_FDB_MINI + sw_error_t + fal_fdb_entry_getnext(a_uint32_t dev_id, fal_fdb_entry_t * entry); +#endif + + 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); + + +#ifndef IN_FDB_MINI + sw_error_t + fal_fdb_port_learn_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable); +#endif + 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); +#ifndef IN_FDB_MINI + 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); +#endif + + 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); + +#ifndef IN_FDB_MINI + 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); +#endif + + sw_error_t + fal_fdb_aging_ctrl_set(a_uint32_t dev_id, a_bool_t enable); + +#ifndef IN_FDB_MINI + sw_error_t + fal_fdb_aging_ctrl_get(a_uint32_t dev_id, a_bool_t * enable); +#endif + + sw_error_t + fal_fdb_learning_ctrl_set(a_uint32_t dev_id, a_bool_t enable); + +#ifndef IN_FDB_MINI + 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); +#endif + 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); + +#ifndef IN_FDB_MINI + 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_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_port_learned_mac_counter_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * cnt); + + 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); +#endif + + 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/src/include/fal/fal_flow.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_flow.h new file mode 100755 index 000000000..f8598682d --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_flow.h @@ -0,0 +1,244 @@ +/* + * 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. + */ + + +/** + * @defgroup fal_flow + * @{ + */ +#ifndef _FAL_FLOW_H_ +#define _FAL_FLOW_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "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 + +#define FAL_FLOW_PROTOCOL_OTHER 0 +#define FAL_FLOW_PROTOCOL_TCP 1 +#define FAL_FLOW_PROTOCOL_UDP 2 +#define FAL_FLOW_PROTOCOL_UDPLITE 3 + + +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 +}; + +#ifndef IN_FLOW_MINI +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); +#endif + +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); + +#ifndef IN_FLOW_MINI +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); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_FLOW_H_ */ + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/fal/fal_flowcookie.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_flowcookie.h new file mode 100755 index 000000000..857c5aa4f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_flowcookie.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 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 + * @{ + */ +#ifndef _FAL_FLOWCOOKIE_H_ +#define _FAL_FLOWCOOKIE_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +int ssdk_flow_cookie_set( + u32 protocol, __be32 src_ip, + __be16 src_port, __be32 dst_ip, + __be16 dst_port, u16 flowcookie); + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_FLOWCOOKIE_H_ */ + +/** + * @} + */ + + diff --git a/feeds/ipq807x/qca-ssdk/src/include/fal/fal_igmp.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_igmp.h new file mode 100755 index 000000000..36cee4e15 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_igmp.h @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2012,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_igmp FAL_IGMP + * @{ + */ +#ifndef _FAL_IGMP_H_ +#define _FAL_IGMP_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "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/src/include/fal/fal_init.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_init.h new file mode 100755 index 000000000..2d372c56a --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_init.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2012, 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_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_MISC, + FAL_MODULE_PTP, + FAL_MODULE_SFP, + FAL_MODULE_MAX, +}; + +typedef struct +{ + a_uint32_t bitmap[3]; +}fal_func_ctrl_t; +/*qca808x_start*/ +sw_error_t fal_init(a_uint32_t dev_id, ssdk_init_cfg * cfg); +/*qca808x_end*/ +sw_error_t fal_reset(a_uint32_t dev_id); +sw_error_t fal_ssdk_cfg(a_uint32_t dev_id, ssdk_cfg_t *ssdk_cfg); +/*qca808x_start*/ +sw_error_t fal_cleanup(void); +/*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 fal_module_func_ctrl_get(a_uint32_t dev_id, + a_uint32_t module, fal_func_ctrl_t *func_ctrl); +sw_error_t fal_module_func_init(a_uint32_t dev_id, ssdk_init_cfg *cfg); +sw_error_t fal_switch_devid_get(ssdk_chip_type chip_type, a_uint32_t *pdev_id); + +/*qca808x_start*/ +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_INIT_H_ */ +/** + * @} + */ +/*qca808x_end*/ diff --git a/feeds/ipq807x/qca-ssdk/src/include/fal/fal_interface_ctrl.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_interface_ctrl.h new file mode 100755 index 000000000..f4383eed0 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_interface_ctrl.h @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2012,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_interface_ctrl FAL_INTERFACE_CONTROL + * @{ + */ +#ifndef _FAL_INTERFACECTRL_H_ +#define _FAL_INTERFACECTRL_H_ + +#ifdef __cplusplus +extern "c" { +#endif + +#include "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, + } fx100_ctrl_link_mode_t; + + typedef enum + { + FX100_SERDS_MODE = 1, + } 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/src/include/fal/fal_ip.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_ip.h new file mode 100755 index 000000000..54eed8953 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_ip.h @@ -0,0 +1,646 @@ +/* + * Copyright (c) 2012, 2015, 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. + */ + + +/** + * @defgroup fal_ip FAL_IP + * @{ + */ +#ifndef _FAL_IP_H_ +#define _FAL_IP_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "sw.h" +#include "fal/fal_type.h" +#include "fal_multi.h" + + +#define FAL_MIN_VRF_ID 0 +#define FAL_MAX_VRF_ID 7 + /* 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_GLB_LOCK_TIME_DISABLE = 0, + FAL_GLB_LOCK_TIME_100US, + FAL_GLB_LOCK_TIME_1MS, + FAL_GLB_LOCK_TIME_10MS, + } fal_glb_lock_time_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, +}; + +#ifndef IN_IP_MINI +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); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_IP_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/fal/fal_leaky.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_leaky.h new file mode 100755 index 000000000..01ad94e14 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_leaky.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2012,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_leaky FAL_LEAKY + * @{ + */ +#ifndef _FAL_LEAKY_H_ +#define _FAL_LEAKY_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "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/src/include/fal/fal_led.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_led.h new file mode 100644 index 000000000..45d59dfd9 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_led.h @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2012,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. + */ + + +/** + * @defgroup fal_led FAL_LED + * @{ + */ +#ifndef _FAL_LED_H_ +#define _FAL_LED_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "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 +#define LED_MAP_10M_SPEED \ + (BIT(POWER_ON_LIGHT_EN) | BIT(LINK_10M_LIGHT_EN) | BIT(COLLISION_BLINK_EN) |\ + BIT(RX_TRAFFIC_BLINK_EN) | BIT(TX_TRAFFIC_BLINK_EN) | BIT(LINKUP_OVERRIDE_EN)) +#define LED_MAP_100M_SPEED \ + (BIT(POWER_ON_LIGHT_EN) | BIT(LINK_100M_LIGHT_EN) | BIT(COLLISION_BLINK_EN) |\ + BIT(RX_TRAFFIC_BLINK_EN) | BIT(TX_TRAFFIC_BLINK_EN) | BIT(LINKUP_OVERRIDE_EN)) +#define LED_MAP_1000M_SPEED \ + (BIT(POWER_ON_LIGHT_EN) | BIT(LINK_1000M_LIGHT_EN) | BIT(COLLISION_BLINK_EN) |\ + BIT(RX_TRAFFIC_BLINK_EN) | BIT(TX_TRAFFIC_BLINK_EN) | BIT(LINKUP_OVERRIDE_EN)) +#define LED_MAP_2500M_SPEED \ + (BIT(POWER_ON_LIGHT_EN) | BIT(LINK_2500M_LIGHT_EN) | BIT(COLLISION_BLINK_EN) |\ + BIT(RX_TRAFFIC_BLINK_EN) | BIT(TX_TRAFFIC_BLINK_EN) | BIT(LINKUP_OVERRIDE_EN)) +#define LED_MAP_ALL_SPEED \ + (LED_MAP_10M_SPEED | LED_MAP_100M_SPEED | LED_MAP_1000M_SPEED |\ + LED_MAP_2500M_SPEED) + +#define PORT_LED_SOURCE_MAX 0x3 + + /** + @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); + + sw_error_t + fal_led_source_pattern_set(a_uint32_t dev_id, a_uint32_t source_id, + led_ctrl_pattern_t * pattern); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_LED_H_ */ +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/fal/fal_mib.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_mib.h new file mode 100755 index 000000000..b4b59ffd2 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_mib.h @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup fal_mib FAL_MIB + * @{ + */ +#ifndef _FAL_MIB_H +#define _FAL_MIB_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "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; /* no this counter for Hawkeye*/ + a_uint32_t Filtered; /*no this counter for Hawkeye*/ + 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; /*no this counter for Hawkeye*/ + 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; + +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 +}; + +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; + +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_get_rx_xgmib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_xgmib_info_t * mib_info ); + +sw_error_t +fal_get_tx_xgmib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_xgmib_info_t * mib_info ); + +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_rx_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info ); + +sw_error_t +fal_get_tx_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_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_alloc(a_uint32_t dev_id, a_uint64_t **p_mibcounter); + +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/src/include/fal/fal_mirror.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_mirror.h new file mode 100755 index 000000000..51158d784 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_mirror.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup fal_mirror FAL_MIRROR + * @{ + */ +#ifndef _FAL_MIRROR_H_ +#define _FAL_MIRROR_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "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/src/include/fal/fal_misc.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_misc.h new file mode 100755 index 000000000..c25d744a0 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_misc.h @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup fal_gen FAL_MISC + * @{ + */ +#ifndef _FAL_MISC_H_ +#define _FAL_MISC_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "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 */ +#ifndef IN_MISC_MINI + 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); +#endif + + + 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_uc_filter_set(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_bc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + 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_get(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_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); + + +#ifndef IN_MISC_MINI + 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); +#endif + + sw_error_t + fal_eapol_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + +#ifndef IN_MISC_MINI + sw_error_t + fal_eapol_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); +#endif + sw_error_t + fal_eapol_status_set(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t enable); +#ifndef IN_MISC_MINI + 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); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_MISC_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/fal/fal_multi.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_multi.h new file mode 100755 index 000000000..30b727fd6 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_multi.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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/src/include/fal/fal_nat.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_nat.h new file mode 100755 index 000000000..643919cde --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_nat.h @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup fal_nat FAL_NAT + * @{ + */ +#ifndef _FAL_NAT_H_ +#define _FAL_NAT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "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_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); + + 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); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_NAT_H_ */ + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/fal/fal_policer.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_policer.h new file mode 100755 index 000000000..6a2c42bf0 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_policer.h @@ -0,0 +1,152 @@ +/* + * 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. + */ + + +/** + * @defgroup fal_policer FAL_POLICER + * @{ + */ +#ifndef _FAL_POLICER_H_ +#define _FAL_POLICER_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "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, +}; + + +#ifndef IN_POLICER_MINI +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_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t *length); + +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); + +#endif + +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_policer_timeslot_set(a_uint32_t dev_id, a_uint32_t timeslot); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_POLICER_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/fal/fal_port_ctrl.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_port_ctrl.h new file mode 100755 index 000000000..ab7e38259 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_port_ctrl.h @@ -0,0 +1,801 @@ +/* + * Copyright (c) 2012, 2015-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/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; + +struct port_phy_status +{ + a_uint32_t link_status; + fal_port_speed_t speed; + fal_port_duplex_t duplex; + a_bool_t tx_flowctrl; + a_bool_t rx_flowctrl; +}; + +#define FAL_ENABLE 1 +#define FAL_DISABLE 0 +#define FAL_MAX_PORT_NUMBER 8 +#define FAL_DEFAULT_LOOPBACK_RATE 14 + +//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_DEFAULT_MAX_FRAME_SIZE 0x5ee + +#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 +#define FAL_PHY_PART_2500T_FD 0x40 +#define FAL_PHY_PART_5000T_FD 0x80 +#define FAL_PHY_PART_10000T_FD 0x100 + +//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 + +/* phy eee */ +#define FAL_PHY_EEE_10BASE_T 0x1 +#define FAL_PHY_EEE_100BASE_T 0x2 +#define FAL_PHY_EEE_1000BASE_T 0x4 +#define FAL_PHY_EEE_2500BASE_T 0x8 +#define FAL_PHY_EEE_5000BASE_T 0x10 +#define FAL_PHY_EEE_10000BASE_T 0x20 + 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; + +/** 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, + } 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; + + +/** 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, + /**= 2.5 G */ + a_uint32_t uart_config_bmp; /* refer to FAL_UART_START_POLARITY_HIGH_EN */ + a_bool_t reset_buf_en; /* reset TOD UART RX/TX buffer, self clearing */ + a_uint32_t buf_status_bmp; /* refer to FAL_UART_RX_BUFFER_DATA_PRESENT */ + a_uint16_t tx_buf_value; /* the uart data to transport */ + a_uint16_t rx_buf_value; /* the uart data received */ +} fal_ptp_tod_uart_t; + +enum { + FAL_ENHANCED_TS_ETH_TYPE_EN = 0, /* timestamp the matched ethernet type */ + FAL_ENHANCED_TS_DMAC_EN, /* timestamp the matched dst mac */ + FAL_ENHANCED_TS_RESV_DMAC_EN, /* timestamp the matched ptp dst mac */ + FAL_ENHANCED_TS_IPV4_L4_PROTO_EN, /* timestamp the matched layer 4 protocol id */ + FAL_ENHANCED_TS_IPV4_DIP_EN, /* timestamp the matched ipv4 dst addr */ + FAL_ENHANCED_TS_RESV_IPV4_DIP_EN, /* timestamp the matched ptp ipv4 dst addr */ + FAL_ENHANCED_TS_IPV6_NEXT_HEADER_EN, /* timestamp the matched ipv6 next header field */ + FAL_ENHANCED_TS_IPV6_DIP_EN, /* timestamp the matched ipv6 dst addr */ + FAL_ENHANCED_TS_RESV_IPV6_DIP_EN, /* timestamp the matched ptp ipv6 dst addr */ + FAL_ENHANCED_TS_UDP_DPORT_EN, /* timestamp the matched udp dport number */ + FAL_ENHANCED_TS_RESV_UDP_DPORT_EN, /* timestamp the matched udp dport number */ + FAL_ENHANCED_TS_Y1731_EN, /* timestamp the received Y1731 frame */ + FAL_ENHANCED_TS_Y1731_TIMESTAMP_INSERT_EN, /* enable inserting RX Y1731 timestamp */ + FAL_ENHANCED_TS_Y1731_MAC_EN /* TX direction check smac, RX direction check dmac */ +}; + +enum { + FAL_ENHANCED_TS_ETH_TYPE_STATUS = 0, /* the MAC type of received packet matches + the filter setting */ + FAL_ENHANCED_TS_DMAC_STATUS, /* the dest MAC of received packet matches + the filter setting */ + FAL_ENHANCED_TS_RESV_PRIM_DMAC_STATUS, /* the dest MAC of received packet matches + PTP primary multicast MAC address */ + FAL_ENHANCED_TS_RESV_PDELAY_DMAC_STATUS, /* the dest MAC of received packet matches + PTP peer delay multicast MAC address */ + FAL_ENHANCED_TS_IPV4_L4_PROTO_STATUS, /* the L4 layer protocol of received packet + matched the filter setting */ + FAL_ENHANCED_TS_IPV4_DIP_STATUS, /* the IPv4 dest address of received packet + matched the filter setting */ + FAL_ENHANCED_TS_RESV_IPV4_PRIM_DIP_STATUS, /* the IPv4 dest address of received packet + matches PTP primary multicast ipv4 addr */ + FAL_ENHANCED_TS_RESV_IPV4_PDELAY_DIP_STATUS,/* the IPv4 dest address of received packet + matches PTP peer delay multicast addr */ + FAL_ENHANCED_TS_IPV6_NEXT_HEADER_STATUS, /* the next header fielf of receviced packet + matches the filter setting */ + FAL_ENHANCED_TS_IPV6_DIP_STATUS, /* the ipv6 dest addr of received packet + matches the filter setting */ + FAL_ENHANCED_TS_RESV_IPV6_PRIM_DIP_STATUS, /* the ipv6 dest address of received packet + matches PTP primary multicast ipv6 addr */ + FAL_ENHANCED_TS_RESV_IPV6_PDELAY_DIP_STATUS,/* the ipv6 dest address of received packet + matches PTP peer delay multicast addr */ + FAL_ENHANCED_TS_UDP_DPORT_STATUS, /* the UDP dest port of received packet + matches the filter setting */ + FAL_ENHANCED_TS_RESV_UDP_DPORT_STATUS, /* the UDP dest port of received packet + matches udp dport of ptp event packet */ + FAL_ENHANCED_TS_Y1731_MATCH_STATUS /* the received frame is Y.1731 OAM frame */ +}; + +typedef struct { + a_bool_t filt_en; /* enable/disable filter feature */ + a_uint32_t enhance_ts_conf_bmp; /* refer to FAL_ENHANCED_TS_ETH_TYPE_EN */ + a_uint32_t eth_type; /* ethernet type value */ + fal_mac_addr_t dmac_addr; /* dest mac address */ + a_uint32_t ipv4_l4_proto; /* ipv4 layer 4 protocol field */ + fal_ip4_addr_t ipv4_dip; /* ipv4 dest ip addr */ + fal_ip6_addr_t ipv6_dip; /* ipv6 dest ip addr */ + a_uint32_t udp_dport; /* udp dest port */ + fal_mac_addr_t y1731_mac_addr; /* TX check smac, RX check dmac */ + a_uint32_t enhance_ts_status_bmp; /* refer to FAL_ENHANCED_TS_ETH_TYPE_STATUS */ + a_uint32_t enhance_ts_status_pre_bmp; /* TX NOT SUPPORT */ + a_uint32_t y1731_identity; /* save Y1731 identify value */ + a_uint32_t y1731_identity_pre; /* TX NOT SUPPORT */ + fal_ptp_time_t timestamp; /* save packet timestamp when matched */ + fal_ptp_time_t timestamp_pre; /* TX NOT SUPPORT */ +} fal_ptp_enhanced_ts_engine_t; + +typedef struct { + a_bool_t trigger_en; /* enable trigger or not */ + a_bool_t output_force_en; /* force trigger output a force value */ + int output_force_value; /* the forced value */ + int patten_select; /* trigger pattern: + 0 single rising edge; + 1 single falling edge; + 2 trigger pulse; + 3 trigger periodic waveform; + 4 toggle mode; + */ + int late_operation; /* if later, trigger immediately */ + int notify; /* report the completion of trigger */ + int trigger_effect; /* write 1 to generate a high pulse when trigger happen */ + fal_ptp_time_t tim; /* the trigger timestamp */ +} fal_ptp_trigger_conf_t; + +typedef struct { + int trigger_finished; /* trigger finished or not */ + int trigger_active; /* trigger is active or not */ + int trigger_error; /* trigger error status + 0 no error + 1 trigger time prior to current time + 2 initial value error for edge trigger + */ +} fal_ptp_trigger_status_t; + +typedef struct { + fal_ptp_trigger_conf_t trigger_conf; + fal_ptp_trigger_status_t trigger_status; +} fal_ptp_trigger_t; + +typedef struct { + int status_clear; /* clear event status register */ + int notify_event; /* notify event through interrupt */ + int single_multi_select; /* 1 for single or 0 for multi event capture */ + a_bool_t fall_edge_en; /* enable falling edge detection */ + a_bool_t rise_edge_en; /* enable rising edge detection */ +} fal_ptp_capture_conf_t; + +typedef struct { + int event_detected; /* event detected or not */ + int fall_rise_edge_detected; /* 0 for rising edge, 1 for falling edge detected */ + int single_multi_detected; /* 0 for single event, 1 for multi event detected */ + int event_missed_cnt; /* the number of events missed */ + fal_ptp_time_t tim; /* event timestamp */ +} fal_ptp_capture_status_t; + +typedef struct { + fal_ptp_capture_conf_t capture_conf; + fal_ptp_capture_status_t capture_status; +} fal_ptp_capture_t; + +enum { + FAL_PTP_INTR_EXPAND = 0,/* expand interrupt, FAL_PTP_INTR_TX_GTSE ~ FAL_PTP_INTR_CAP1 */ + FAL_PTP_INTR_RX, /* ptp pkt rx interrupt */ + FAL_PTP_INTR_TX, /* ptp pkt tx interrupt */ + FAL_PTP_INTR_TX_GTSE, /* gtse pkt tx interrupt */ + FAL_PTP_INTR_RX_GTSE, /* gtse pkt rx interrupt */ + FAL_PTP_INTR_TX_BUF, /* uart tod tx buffer half full interrupt */ + FAL_PTP_INTR_RX_BUF, /* uart tod rx buffer half full interrupt */ + FAL_PTP_INTR_PPS_OUT, /* PPS output interrupt */ + FAL_PTP_INTR_PPS_IN, /* PPS input interrupt */ + FAL_PTP_INTR_10MS, /* each 10ms interrupt */ + FAL_PTP_INTR_TRIG0, /* trigger0 interrupt */ + FAL_PTP_INTR_TRIG1, /* trigger1 interrupt */ + FAL_PTP_INTR_CAP0, /* capture0 interrupt */ + FAL_PTP_INTR_CAP1 /* capture1 interrupt */ +}; + +typedef struct { + a_uint32_t intr_mask; + a_uint32_t intr_status; +} fal_ptp_interrupt_t; + +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 +fal_ptp_config_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_config_t *config); + +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 +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 +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 +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 +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 +fal_ptp_pkt_timestamp_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_time_t *time); + +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 +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 +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 +fal_ptp_rtc_time_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_time_t *time); + +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 +fal_ptp_rtc_time_clear(a_uint32_t dev_id, a_uint32_t port_id); + +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 +fal_ptp_rtc_adjfreq_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_time_t *time); + +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 +fal_ptp_link_delay_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_time_t *time); + +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 +fal_ptp_security_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_security_t *sec); + +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 +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 +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 +fal_ptp_rx_crc_recalc_enable(a_uint32_t dev_id, a_uint32_t port_id, + a_bool_t status); + +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 +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 +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 +fal_ptp_output_waveform_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_output_waveform_t *waveform); + +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 +fal_ptp_rtc_time_snapshot_enable(a_uint32_t dev_id, a_uint32_t port_id, + a_bool_t status); + +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 +fal_ptp_increment_sync_from_clock_enable(a_uint32_t dev_id, + a_uint32_t port_id, a_bool_t status); + +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 +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 +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 +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 +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 +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 +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 +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 +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 +fal_ptp_interrupt_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_interrupt_t *interrupt); + +sw_error_t +fal_ptp_interrupt_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_interrupt_t *interrupt); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_PTP_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/fal/fal_qm.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_qm.h new file mode 100755 index 000000000..a15f0b5f8 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_qm.h @@ -0,0 +1,344 @@ +/* + * 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. + */ + + +/** + * @defgroup fal_qos FAL_QM + * @{ + */ +#ifndef _FAL_QM_H_ +#define _FAL_QM_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "sw.h" +#include "fal/fal_type.h" + +typedef enum { + FAL_AC_QUEUE = 0, + FAL_AC_GROUP +} fal_ac_type_t; + +typedef struct { + fal_ac_type_t type; + a_uint32_t obj_id; +} fal_ac_obj_t; + +typedef struct { + a_bool_t ac_en; /* 0 for disable and 1 for enable*/ + a_bool_t ac_fc_en; /* ac for flow control packets */ +} fal_ac_ctrl_t; + +typedef struct { + a_uint16_t prealloc_buffer; /* guareented buffer number */ + a_uint16_t total_buffer; /* total buffer number */ +} fal_ac_group_buffer_t; + +typedef struct { + a_bool_t color_enable; /* 1 for color aware and 0 for color-blind */ + a_bool_t wred_enable; /* 1 for wred and 0 for tail drop */ + a_uint16_t green_max; + a_uint16_t green_min_off; /*gap between green max and green min*/ + a_uint16_t yel_max_off; /*gap between green max and yel max*/ + a_uint16_t yel_min_off; /*gap between green max and yel min*/ + a_uint16_t red_max_off; /*gap between green max and red max*/ + a_uint16_t red_min_off; /*gap between green max and red min*/ + a_uint16_t green_resume_off; /* green resume offset */ + a_uint16_t yel_resume_off; /* yellow resume offset */ + a_uint16_t red_resume_off; /* red resume offset */ +} fal_ac_static_threshold_t; + +typedef struct { + a_bool_t color_enable; /* 1 for color aware and 0 for color-blind */ + a_bool_t wred_enable; /* 1 for wred and 0 for tail drop */ + a_uint8_t shared_weight; /* weight in the shared group */ + a_uint16_t green_min_off; /*gap between green max and green min*/ + a_uint16_t yel_max_off; /*gap between green max and yel max*/ + a_uint16_t yel_min_off; /*gap between green max and yel min*/ + a_uint16_t red_max_off; /*gap between green max and red max*/ + a_uint16_t red_min_off; /*gap between green max and red min*/ + a_uint16_t green_resume_off; /* green resume offset */ + a_uint16_t yel_resume_off; /* yellow resume offset */ + a_uint16_t red_resume_off; /* red resume offset */ + a_uint16_t ceiling; /*shared ceiling*/ +} fal_ac_dynamic_threshold_t; + +typedef struct { + a_uint8_t src_profile; /* queue source profile */ + a_bool_t service_code_en; + a_uint16_t service_code; + a_bool_t cpu_code_en; + a_uint16_t cpu_code; + fal_port_t dst_port; /* destination physical or VP port */ +} fal_ucast_queue_dest_t; + +#define FAL_QM_DROP_ITEMS 6 +typedef struct { + a_uint32_t tx_packets; + a_uint64_t tx_bytes; + a_uint32_t pending_buff_num; + a_uint32_t drop_packets[FAL_QM_DROP_ITEMS]; + a_uint64_t drop_bytes[FAL_QM_DROP_ITEMS]; +} fal_queue_stats_t; + +enum { + FUNC_UCAST_HASH_MAP_SET = 0, + FUNC_AC_DYNAMIC_THRESHOLD_GET, + FUNC_UCAST_QUEUE_BASE_PROFILE_GET, + FUNC_PORT_MCAST_PRIORITY_CLASS_GET, + FUNC_AC_DYNAMIC_THRESHOLD_SET, + FUNC_AC_PREALLOC_BUFFER_SET, + FUNC_UCAST_DEFAULT_HASH_GET, + FUNC_UCAST_DEFAULT_HASH_SET, + FUNC_AC_QUEUE_GROUP_GET, + FUNC_AC_CTRL_GET, + FUNC_AC_PREALLOC_BUFFER_GET, + FUNC_PORT_MCAST_PRIORITY_CLASS_SET, + FUNC_UCAST_HASH_MAP_GET, + FUNC_AC_STATIC_THRESHOLD_SET, + FUNC_AC_QUEUE_GROUP_SET, + FUNC_AC_GROUP_BUFFER_GET, + FUNC_MCAST_CPU_CODE_CLASS_GET, + FUNC_AC_CTRL_SET, + FUNC_UCAST_PRIORITY_CLASS_GET, + FUNC_QUEUE_FLUSH, + FUNC_MCAST_CPU_CODE_CLASS_SET, + FUNC_UCAST_PRIORITY_CLASS_SET, + FUNC_AC_STATIC_THRESHOLD_GET, + FUNC_UCAST_QUEUE_BASE_PROFILE_SET, + FUNC_AC_GROUP_BUFFER_SET, + FUNC_QUEUE_COUNTER_CLEANUP, + FUNC_QUEUE_COUNTER_GET, + FUNC_QUEUE_COUNTER_CTRL_GET, + FUNC_QUEUE_COUNTER_CTRL_SET, + FUNC_QM_ENQUEUE_CTRL_GET, + FUNC_QM_ENQUEUE_CTRL_SET, + FUNC_QM_PORT_SRCPROFILE_GET, + FUNC_QM_PORT_SRCPROFILE_SET, +}; + +sw_error_t +fal_ac_ctrl_set( + a_uint32_t dev_id, + fal_ac_obj_t *obj, + fal_ac_ctrl_t *cfg); + +#ifndef IN_QM_MINI +sw_error_t +fal_ac_ctrl_get( + a_uint32_t dev_id, + fal_ac_obj_t *obj, + fal_ac_ctrl_t *cfg); +#endif + +sw_error_t +fal_ac_prealloc_buffer_set( + a_uint32_t dev_id, + fal_ac_obj_t *obj, + a_uint16_t num); + +#ifndef IN_QM_MINI +sw_error_t +fal_ac_prealloc_buffer_get( + a_uint32_t dev_id, + fal_ac_obj_t *obj, + a_uint16_t *num); +#endif + +sw_error_t +fal_ac_queue_group_set( + a_uint32_t dev_id, + a_uint32_t queue_id, + a_uint8_t group_id); + +#ifndef IN_QM_MINI +sw_error_t +fal_ac_queue_group_get( + a_uint32_t dev_id, + a_uint32_t queue_id, + a_uint8_t *group_id); +#endif + +sw_error_t +fal_ac_static_threshold_set( + a_uint32_t dev_id, + fal_ac_obj_t *obj, + fal_ac_static_threshold_t *cfg); + +#ifndef IN_QM_MINI +sw_error_t +fal_ac_static_threshold_get( + a_uint32_t dev_id, + fal_ac_obj_t *obj, + fal_ac_static_threshold_t *cfg); +#endif + +sw_error_t +fal_ac_dynamic_threshold_set( + a_uint32_t dev_id, + a_uint32_t queue_id, + fal_ac_dynamic_threshold_t *cfg); + +#ifndef IN_QM_MINI +sw_error_t +fal_ac_dynamic_threshold_get( + a_uint32_t dev_id, + a_uint32_t queue_id, + fal_ac_dynamic_threshold_t *cfg); +#endif + +sw_error_t +fal_ac_group_buffer_set( + a_uint32_t dev_id, + a_uint8_t group_id, + fal_ac_group_buffer_t *cfg); + +#ifndef IN_QM_MINI +sw_error_t +fal_ac_group_buffer_get( + a_uint32_t dev_id, + a_uint8_t group_id, + fal_ac_group_buffer_t *cfg); +#endif + +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); + +#ifndef IN_QM_MINI +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 +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 +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 +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 +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 +fal_mcast_cpu_code_class_set( + a_uint32_t dev_id, + a_uint8_t cpu_code, + a_uint8_t queue_class); + +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 +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 +fal_port_mcast_priority_class_get( + a_uint32_t dev_id, + fal_port_t port, + a_uint8_t priority, + a_uint8_t *queue_class); + +#endif +sw_error_t +fal_queue_flush( + a_uint32_t dev_id, + fal_port_t port, + a_uint16_t queue_id); + +#ifndef IN_QM_MINI +sw_error_t +fal_ucast_default_hash_set( + a_uint32_t dev_id, + a_uint8_t hash_value); + +sw_error_t +fal_ucast_default_hash_get( + a_uint32_t dev_id, + a_uint8_t *hash_value); + +sw_error_t +fal_queue_counter_ctrl_set(a_uint32_t dev_id, a_bool_t cnt_en); + +sw_error_t +fal_queue_counter_ctrl_get(a_uint32_t dev_id, a_bool_t *cnt_en); + +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 +fal_queue_counter_cleanup(a_uint32_t dev_id, a_uint32_t queue_id); +#endif + +sw_error_t +fal_qm_enqueue_ctrl_set(a_uint32_t dev_id, a_uint32_t queue_id, a_bool_t enable); + +#ifndef IN_QM_MINI +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 +fal_qm_port_source_profile_set( + a_uint32_t dev_id, + fal_port_t port, + a_uint32_t src_profile); + +sw_error_t +fal_qm_port_source_profile_get( + a_uint32_t dev_id, + fal_port_t port, + a_uint32_t *src_profile); + +#endif + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _PORT_QM_H_ */ +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/fal/fal_qos.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_qos.h new file mode 100644 index 000000000..30c894e1b --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_qos.h @@ -0,0 +1,442 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup fal_qos FAL_QOS + * @{ + */ +#ifndef _FAL_QOS_H_ +#define _FAL_QOS_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "sw.h" +#include "fal/fal_type.h" + + /** + @brief This enum defines traffic scheduling mode. + */ + typedef enum { + FAL_SCH_SP_MODE = 0, /**< strict priority scheduling mode */ + FAL_SCH_WRR_MODE, /**< weight round robin scheduling mode*/ + FAL_SCH_MIX_MODE, /**< sp and wrr mixed scheduling mode */ + FAL_SCH_MIX_PLUS_MODE, /**< sp and wrr mixed plus scheduling mode */ + FAL_SCH_MODE_BUTT + } + fal_sch_mode_t; + + /** + @brief This enum defines qos assignment mode. + */ + typedef enum + { + FAL_QOS_DA_MODE = 0, /**< qos assignment based on destination mac address*/ + FAL_QOS_UP_MODE, /**< qos assignment based on 802.1p field in vlan tag*/ + FAL_QOS_DSCP_MODE, /**< qos assignment based on dscp field in ip header */ + FAL_QOS_PORT_MODE, /**< qos assignment based on port */ + FAL_QOS_FLOW_MODE, /**< qos assignment based on flow */ + FAL_QOS_MODE_BUTT + } fal_qos_mode_t; + +typedef struct { + a_uint8_t pcp_group; /* 0: group 0 1: group 1 */ + a_uint8_t dscp_group; + a_uint8_t flow_group; +} fal_qos_group_t; + +typedef struct { + a_uint8_t pcp_pri; + a_uint8_t dscp_pri; + a_int8_t preheader_pri; + a_uint8_t flow_pri; + a_uint8_t acl_pri; + a_uint8_t post_acl_pri; + a_bool_t pcp_pri_force; + a_bool_t dscp_pri_force; +} fal_qos_pri_precedence_t; + +typedef struct { + a_bool_t pcp_change_en; + a_bool_t dei_chage_en; + a_bool_t dscp_change_en; +} fal_qos_remark_enable_t; + +typedef struct { + a_uint8_t internal_pcp; + a_uint8_t internal_dei; + a_uint8_t internal_pri; + a_uint8_t internal_dscp; + a_uint8_t internal_dp; + a_uint8_t dscp_mask; + a_bool_t dscp_en; + a_bool_t pcp_en; + a_bool_t dei_en; + a_bool_t pri_en; + a_bool_t dp_en; + a_uint8_t qos_prec; /* resolution precedence */ +} fal_qos_cosmap_t; + +typedef enum { + FAL_DRR_IPG_PREAMBLE_FRAME_CRC = 0, /* IPG + Preamble + Frame + CRC */ + FAL_DRR_FRAME_CRC, /* Frame + CRC */ + FAL_DRR_L3_EXCLUDE_CRC /* after Ethernet type excude CRC*/ +} fal_qos_drr_frame_mode_t; + +typedef struct { + a_uint8_t sp_id; /* SP id L0:0~63 L1:0~7 */ + a_uint8_t e_pri; /*SP priority for E path:0~7 low to high */ + a_uint8_t c_pri; /* SP priority for C path: 0~7 low to high */ + a_uint8_t c_drr_id; /*C DRR ID L0:0~159 L1:0~35*/ + a_uint8_t e_drr_id; /*E DRR ID L0:0~159 L1:0~35*/ + a_uint16_t e_drr_wt; /* DRR weight in E DRR: 0~1023 */ + a_uint16_t c_drr_wt; /* DRR weight in C DRR: 0~1023 */ + a_uint8_t c_drr_unit; /* 0:byte based; 1:packet based */ + a_uint8_t e_drr_unit; /* 0:byte based; 1:packet based */ + fal_qos_drr_frame_mode_t drr_frame_mode; +} fal_qos_scheduler_cfg_t; + +typedef struct { + a_uint32_t en_scheduler_port_bmp; /* port bitmap of en-scheduler */ + a_uint32_t en_scheduler_port; /* port of en-scheduler */ + a_uint32_t de_scheduler_port; /* port of de-shceduler */ +} fal_port_scheduler_cfg_t; + +typedef enum { + FAL_QUEUE_SCHEDULER_LEVEL0 = 0, + FAL_QUEUE_SCHEDULER_LEVEL1, +} fal_queue_scheduler_level_t; + + +typedef struct { + a_uint32_t bmp[10]; +} fal_queue_bmp_t; + +enum { + FUNC_QOS_PORT_PRI_SET = 0, + FUNC_QOS_PORT_PRI_GET, + FUNC_QOS_COSMAP_PCP_GET, + FUNC_QUEUE_SCHEDULER_SET, + FUNC_QUEUE_SCHEDULER_GET, + FUNC_PORT_QUEUES_GET, + FUNC_QOS_COSMAP_PCP_SET, + FUNC_QOS_PORT_REMARK_GET, + FUNC_QOS_COSMAP_DSCP_GET, + FUNC_QOS_COSMAP_FLOW_SET, + FUNC_QOS_PORT_GROUP_SET, + FUNC_RING_QUEUE_MAP_SET, + FUNC_QOS_COSMAP_DSCP_SET, + FUNC_QOS_PORT_REMARK_SET, + FUNC_QOS_COSMAP_FLOW_GET, + FUNC_QOS_PORT_GROUP_GET, + FUNC_RING_QUEUE_MAP_GET, + FUNC_TDM_TICK_NUM_SET, + FUNC_TDM_TICK_NUM_GET, + FUNC_PORT_SCHEDULER_CFG_SET, + FUNC_PORT_SCHEDULER_CFG_GET, + FUNC_SCHEDULER_DEQUEUE_CTRL_GET, + FUNC_SCHEDULER_DEQUEUE_CTRL_SET, + FUNC_QOS_PORT_MODE_PRI_GET, + FUNC_QOS_PORT_MODE_PRI_SET, + FUNC_QOS_PORT_SCHEDULER_CFG_RESET, + FUNC_QOS_PORT_SCHEDULER_RESOURCE_GET, +}; + +typedef struct { + a_uint16_t ucastq_start; + a_uint16_t ucastq_num; + a_uint16_t mcastq_start; + a_uint16_t mcastq_num; + a_uint16_t l0sp_start; + a_uint16_t l0sp_num; + a_uint16_t l0cdrr_start; + a_uint16_t l0cdrr_num; + a_uint16_t l0edrr_start; + a_uint16_t l0edrr_num; + a_uint16_t l1sp_start; + a_uint16_t l1sp_num; + a_uint16_t l1cdrr_start; + a_uint16_t l1cdrr_num; + a_uint16_t l1edrr_start; + a_uint16_t l1edrr_num; +} fal_portscheduler_resource_t; + +#define FAL_DOT1P_MIN 0 +#define FAL_DOT1P_MAX 7 + +#define FAL_DSCP_MIN 0 +#define FAL_DSCP_MAX 63 + +#ifndef IN_QOS_MINI + 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 + fal_qos_sch_mode_get(a_uint32_t dev_id, + fal_sch_mode_t * mode, a_uint32_t weight[]); + + + 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 + fal_qos_queue_tx_buf_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + 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 + fal_qos_port_tx_buf_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + 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 + fal_qos_port_red_en_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + + + + 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 + fal_qos_port_rx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number); + + sw_error_t + fal_cosmap_up_queue_set(a_uint32_t dev_id, a_uint32_t up, + fal_queue_t queue); + + + sw_error_t + fal_cosmap_up_queue_get(a_uint32_t dev_id, a_uint32_t up, + fal_queue_t * queue); + + + sw_error_t + fal_cosmap_dscp_queue_set(a_uint32_t dev_id, a_uint32_t dscp, + fal_queue_t queue); + + + sw_error_t + fal_cosmap_dscp_queue_get(a_uint32_t dev_id, a_uint32_t dscp, + fal_queue_t * queue); +#endif + 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 + fal_qos_port_red_en_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + 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 + fal_qos_port_tx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number); + + + 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); + +#ifndef IN_QOS_MINI +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 + 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 + 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 + fal_qos_port_default_up_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t up); + + + 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 + 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 + 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 + fal_qos_port_default_spri_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t spri); + + 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 + fal_qos_port_default_cpri_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t cpri); + + 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 + fal_qos_port_force_spri_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + 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 + fal_qos_port_force_cpri_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + 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 + 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 + 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); +#endif + +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 +fal_qos_port_group_get(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_group_t *group); + +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 +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 +fal_qos_port_remark_set(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_remark_enable_t *remark); + +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +fal_port_queues_get(a_uint32_t dev_id, + fal_port_t port_id, fal_queue_bmp_t *queue_bmp); + +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 +fal_scheduler_dequeue_ctrl_get(a_uint32_t dev_id, a_uint32_t queue_id, a_bool_t *enable); + +sw_error_t +fal_port_scheduler_cfg_reset( + a_uint32_t dev_id, + fal_port_t port_id); + +sw_error_t +fal_port_scheduler_resource_get( + a_uint32_t dev_id, + fal_port_t port_id, + fal_portscheduler_resource_t *cfg); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _PORT_QOS_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/fal/fal_rate.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_rate.h new file mode 100755 index 000000000..99c737798 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_rate.h @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2012,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_rate FAL_RATE + * @{ + */ +#ifndef _FAL_RATE_H_ +#define _FAL_RATE_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "sw.h" +#include "fal/fal_type.h" + + /** + @brief This enum defines storm type + */ + typedef enum { + FAL_UNICAST_STORM = 0, /**< storm caused by unknown unicast packets */ + FAL_MULTICAST_STORM, /**< storm caused by unknown multicast packets */ + FAL_BROADCAST_STORM, /**< storm caused by broadcast packets */ + FAL_STORM_TYPE_BUTT + } + fal_storm_type_t; + + + + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + fal_storm_ctrl_rate_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * rate); + + + + sw_error_t + fal_storm_ctrl_rate_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * rate); + + + typedef enum + { + FAL_RATE_MI_100US = 0, + FAL_RATE_MI_1MS, + FAL_RATE_MI_10MS, + FAL_RATE_MI_100MS, + } fal_rate_mt_t; + + + typedef struct + { + fal_traffic_unit_t meter_unit; + a_uint32_t cir; + a_uint32_t eir; + a_uint32_t cbs; + a_uint32_t ebs; + } fal_egress_shaper_t; + + +#define FAL_INGRESS_POLICING_TCP_CTRL 0x2 +#define FAL_INGRESS_POLICING_MANAGEMENT 0x4 +#define FAL_INGRESS_POLICING_BROAD 0x8 +#define FAL_INGRESS_POLICING_UNK_UNI 0x10 +#define FAL_INGRESS_POLICING_UNK_MUL 0x20 +#define FAL_INGRESS_POLICING_UNI 0x40 +#define FAL_INGRESS_POLICING_MUL 0x80 + + + typedef struct + { + a_bool_t c_enable; + a_bool_t e_enable; + a_bool_t combine_mode; + fal_traffic_unit_t meter_unit; + a_bool_t color_mode; + a_bool_t couple_flag; + a_bool_t deficit_en; + a_uint32_t cir; + a_uint32_t eir; + a_uint32_t cbs; + a_uint32_t ebs; + a_uint32_t c_rate_flag; + a_uint32_t e_rate_flag; + fal_rate_mt_t c_meter_interval; + fal_rate_mt_t e_meter_interval; + } fal_port_policer_t; + + + typedef struct + { + a_bool_t counter_mode; + fal_traffic_unit_t meter_unit; + fal_rate_mt_t meter_interval; + a_bool_t color_mode; + a_bool_t couple_flag; + a_bool_t deficit_en; + a_uint32_t cir; + a_uint32_t eir; + a_uint32_t cbs; + a_uint32_t ebs; + a_uint32_t counter_high; + a_uint32_t counter_low; + } fal_acl_policer_t; + + + 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 + fal_rate_port_policer_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_policer_t * policer); + + + 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 + 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 + 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 + 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 + fal_rate_acl_policer_set(a_uint32_t dev_id, a_uint32_t policer_id, + fal_acl_policer_t * policer); + + + 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 + fal_rate_port_add_rate_byte_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t number); + + 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 + fal_rate_port_gol_flow_en_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + sw_error_t + fal_rate_port_gol_flow_en_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t* enable); + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_RATE_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/fal/fal_reg_access.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_reg_access.h new file mode 100755 index 000000000..c5389a5e9 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_reg_access.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2012, 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*/ +/** + * @defgroup fal_reg_access FAL_REG_ACCESS + * @{ + */ +#ifndef _FAL_REG_ACCESS_H_ +#define _FAL_REG_ACCESS_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "sw.h" +#include "fal/fal_type.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 + fal_phy_set(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t value); +/*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 + 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 + 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 + 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 + 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 + 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 + fal_debug_reg_dump(a_uint32_t dev_id, fal_debug_reg_dump_t *reg_dump); + + 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 + 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 + fal_phy_dump(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t idx, fal_phy_dump_t * phy_dump); + + 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 + 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); + +/*qca808x_start*/ +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_REG_ACCESS_H_ */ + +/** + * @} + */ +/*qca808x_end*/ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/fal/fal_rfs.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_rfs.h new file mode 100755 index 000000000..08c64d6db --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_rfs.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 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_rfs FAL_RFS + * @{ + */ +#ifndef _FAL_RFS_H_ +#define _FAL_RFS_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +#if 0 +typedef struct +{ + u8 addr[6]; + u16 fid; + u8 load_balance; +} ssdk_fdb_rfs_t; + +typedef struct +{ + u8 mac_addr[6]; + u32 ip4_addr; + u32 vid; + u8 load_balance; +} ssdk_ip4_rfs_t; + +typedef struct +{ + u8 mac_addr[6]; + u32 ip6_addr[4]; + u32 vid; + u8 load_balance; +} ssdk_ip6_rfs_t; + + + +int ssdk_rfs_ipct_rule_set( + __be32 ip_src, __be32 ip_dst, + __be16 sport, __be16 dport, uint8_t proto, + u16 loadbalance, bool action); + +int ssdk_rfs_mac_rule_set(ssdk_fdb_rfs_t *rfs); +int ssdk_rfs_mac_rule_del(ssdk_fdb_rfs_t *rfs); + +int +ssdk_ip_rfs_ip4_rule_set(ssdk_ip4_rfs_t * rfs); + +int +ssdk_ip_rfs_ip6_rule_set(ssdk_ip6_rfs_t * rfs); + +int +ssdk_ip_rfs_ip4_rule_del(ssdk_ip4_rfs_t * rfs); + +int +ssdk_ip_rfs_ip6_rule_del(ssdk_ip6_rfs_t * rfs); +#endif +int ssdk_rfs_mac_rule_set(u16 vid, u8* mac, u8 ldb, int is_set); +int ssdk_rfs_ip4_rule_set(u16 vid, u32 ip, u8* mac, u8 ldb, int is_set); +int ssdk_rfs_ip6_rule_set(u16 vid, u8* ip, u8* mac, u8 ldb, int is_set); +int ssdk_rfs_ipct_rule_set( + __be32 ip_src, __be32 ip_dst, + __be16 sport, __be16 dport, uint8_t proto, + u16 loadbalance, bool action); + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_RFS_H_ */ + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/fal/fal_rss_hash.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_rss_hash.h new file mode 100755 index 000000000..e11b9b013 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_rss_hash.h @@ -0,0 +1,77 @@ +/* + * 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. + */ + + +/** + * @defgroup fal_gen FAL_RSS_HASH + * @{ + */ +#ifndef _FAL_RSS_HASH_H_ +#define _FAL_RSS_HASH_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "sw.h" +#include "fal/fal_type.h" + +#if defined(SW_API_LOCK) && (!defined(HSL_STANDALONG)) +#define FAL_RSS_HASH_API_LOCK +#define FAL_RSS_HASH_API_UNLOCK +#else +#define FAL_RSS_HASH_API_LOCK +#define FAL_RSS_HASH_API_UNLOCK +#endif + +typedef enum +{ + FAL_RSS_HASH_IPV4V6 = 0, + FAL_RSS_HASH_IPV4ONLY = 1, + FAL_RSS_HASH_IPV6ONLY = 2, +} fal_rss_hash_mode_t; + +typedef struct +{ + a_uint32_t hash_mask; /* final hash value bits */ + a_bool_t hash_fragment_mode; /* enable fragment mode or not */ + a_uint32_t hash_seed; /* rss hash seed value */ + a_uint32_t hash_sip_mix; /* source ip hash mix */ + a_uint32_t hash_dip_mix; /* dest ip hash mix */ + a_uint8_t hash_protocol_mix; /* L4 protocol hash mix */ + a_uint8_t hash_sport_mix; /* L4 source port hash mix */ + a_uint8_t hash_dport_mix; /* L4 dest port hash mix */ + a_uint32_t hash_fin_inner; /* hash fin inner mix */ + a_uint32_t hash_fin_outer; /* hash fin outer mix */ +} fal_rss_hash_config_t; + +enum { + FUNC_RSS_HASH_CONFIG_SET = 0, + FUNC_RSS_HASH_CONFIG_GET, +}; + +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 +fal_rss_hash_config_get(a_uint32_t dev_id, fal_rss_hash_mode_t mode, fal_rss_hash_config_t * config); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_RSS_HASH_H_ */ +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/fal/fal_sec.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_sec.h new file mode 100755 index 000000000..eff27fee0 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_sec.h @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup fal_sec FAL_SEC + * @{ + */ +#ifndef _FAL_SEC_H_ +#define _FAL_SEC_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "sw.h" +#include "fal/fal_type.h" + +/* Exception: L2 */ +#define FAL_SEC_EXP_UNKNOWN_L2_PROT 1 +#define FAL_SEC_EXP_PPPOE_WRONG_VER_TYPE 2 +#define FAL_SEC_EXP_PPPOE_WRONG_CODE 3 +#define FAL_SEC_EXP_PPPOE_UNSUPPORTED_PPP_PROT 4 +/* Exception: IPv4 */ +#define FAL_SEC_EXP_IPV4_WRONG_VER 5 +#define FAL_SEC_EXP_IPV4_SMALL_IHL 6 +#define FAL_SEC_EXP_IPV4_WITH_OPTION 7 + +#define FAL_SEC_EXP_IPV4_HDR_INCOMPLETE 8 + +#define FAL_SEC_EXP_IPV4_BAD_TOTAL_LEN 9 +#define FAL_SEC_EXP_IPV4_DATA_INCOMPLETE 10 + +#define FAL_SEC_EXP_IPV4_FRAG 11 +#define FAL_SEC_EXP_IPV4_PING_OF_DEATH 12 + +#define FAL_SEC_EXP_IPV4_SNALL_TTL 13 +#define FAL_SEC_EXP_IPV4_UNK_IP_PROT 14 +#define FAL_SEC_EXP_IPV4_CHECKSUM_ERR 15 +#define FAL_SEC_EXP_IPV4_INV_SIP 16 +#define FAL_SEC_EXP_IPV4_INV_DIP 17 +#define FAL_SEC_EXP_IPV4_LAND_ATTACK 18 +#define FAL_SEC_EXP_IPV4_AH_HDR_INCOMPLETE 19 +#define FAL_SEC_EXP_IPV4_AH_HDR_CROSS_BORDER 20 +#define FAL_SEC_EXP_IPV4_ESP_HDR_INCOMPLETE 21 +/* Exception: IPv6 */ +#define FAL_SEC_EXP_IPV6_WRONG_VER 22 +#define FAL_SEC_EXP_IPV6_HDR_INCOMPLETE 23 +#define FAL_SEC_EXP_IPV6_BAD_PAYLOAD_LEN 24 +#define FAL_SEC_EXP_IPV6_DATA_INCOMPLETE 25 +#define FAL_SEC_EXP_IPV6_WITH_EXT_HDR 26 +#define FAL_SEC_EXP_IPV6_SMALL_HOP_LIMIT 27 +#define FAL_SEC_EXP_IPV6_INV_SIP 28 +#define FAL_SEC_EXP_IPV6_INV_DIP 29 +#define FAL_SEC_EXP_IPV6_LAND_ATTACK 30 +#define FAL_SEC_EXP_IPV6_FRAG 31 +#define FAL_SEC_EXP_IPV6_PING_OF_DEATH 32 +#define FAL_SEC_EXP_IPV6_WITH_MORE_EXT_HDR 33 +#define FAL_SEC_EXP_IPV6_UNK_LAST_NEXT_HDR 34 +#define FAL_SEC_EXP_IPV6_MOBILITY_HDR_INCOMPLETE 35 +#define FAL_SEC_EXP_IPV6_MOBILITY_HDR_CROSS_BORDER 36 +#define FAL_SEC_EXP_IPV6_AH_HDR_INCOMPLETE 37 +#define FAL_SEC_EXP_IPV6_AH_HDR_CROSS_BORDER 38 +#define FAL_SEC_EXP_IPV6_ESP_HDR_INCOMPLETE 39 +#define FAL_SEC_EXP_IPV6_ESP_HDR_CROSS_BORDER 40 + +#define FAL_SEC_EXP_IPV6_OTHER_EXT_HDR_INCOMPLETE 41 +#define FAL_SEC_EXP_IPV6_OTHER_EXT_HDR_CROSS_BORDER 42 + +/* Exception: L4 */ +#define FAL_SEC_EXP_TCP_HDR_INCOMPLETE 43 +#define FAL_SEC_EXP_TCP_HDR_CROSS_BORDER 44 +#define FAL_SEC_EXP_TCP_SMAE_SP_DP 45 +#define FAL_SEC_EXP_TCP_SMALL_DATA_OFFSET 46 +#define FAL_SEC_EXP_TCP_FLAGS_0 47 +#define FAL_SEC_EXP_TCP_FLAGS_1 48 +#define FAL_SEC_EXP_TCP_FLAGS_2 49 +#define FAL_SEC_EXP_TCP_FLAGS_3 50 +#define FAL_SEC_EXP_TCP_FLAGS_4 51 +#define FAL_SEC_EXP_TCP_FLAGS_5 52 +#define FAL_SEC_EXP_TCP_FLAGS_6 53 +#define FAL_SEC_EXP_TCP_FLAGS_7 54 +#define FAL_SEC_EXP_TCP_CHECKSUM_ERR 55 +#define FAL_SEC_EXP_UDP_HDR_INCOMPLETE 56 +#define FAL_SEC_EXP_UDP_HDR_CROSS_BORDER 57 + +#define FAL_SEC_EXP_UDP_SMAE_SP_DP 58 +#define FAL_SEC_EXP_UDP_BAD_LEN 59 +#define FAL_SEC_EXP_UDP_DATA_INCOMPLETE 60 + + +#define FAL_SEC_EXP_UDP_CHECKSUM_ERR 61 +#define FAL_SEC_EXP_UDP_LITE_HDR_INCOMPLETE 62 +#define FAL_SEC_EXP_UDP_LITE_HDR_CROSS_BORDER 63 +#define FAL_SEC_EXP_UDP_LITE_SMAE_SP_DP 64 +/* Other exception */ +#define FAL_SEC_EXP_UDP_LITE_CSM_COV_1_TO_7 65 +#define FAL_SEC_EXP_UDP_LITE_CSM_COV_TOO_LONG 66 +#define FAL_SEC_EXP_UDP_LITE_CSM_COV_CROSS_BORDER 67 +#define FAL_SEC_EXP_UDP_LITE_CHECKSUM_ERR 68 + +/**/ + +#define FAL_SEC_EXP_FAKE_L2_PROT_ERR 69 +#define FAL_SEC_EXP_FAKE_MAC_HEADER_ERR 70 + + + typedef enum { + /* define MAC layer related normalization items */ + FAL_NORM_MAC_RESV_VID_CMD = 0, + FAL_NORM_MAC_INVALID_SRC_ADDR_CMD, + + /* define IP layer related normalization items */ + FAL_NORM_IP_INVALID_VER_CMD, + FAL_NROM_IP_SAME_ADDR_CMD, + FAL_NROM_IP_TTL_CHANGE_STATUS, + FAL_NROM_IP_TTL_VALUE, + + /* define IP4 related normalization items */ + FAL_NROM_IP4_INVALID_HL_CMD, + FAL_NROM_IP4_HDR_OPTIONS_CMD, + FAL_NROM_IP4_INVALID_DF_CMD, + FAL_NROM_IP4_FRAG_OFFSET_MIN_LEN_CMD, + FAL_NROM_IP4_FRAG_OFFSET_MAX_LEN_CMD, + FAL_NROM_IP4_INVALID_FRAG_OFFSET_CMD, + FAL_NROM_IP4_INVALID_SIP_CMD, + FAL_NROM_IP4_INVALID_DIP_CMD, + FAL_NROM_IP4_INVALID_CHKSUM_CMD, + FAL_NROM_IP4_INVALID_PL_CMD, + FAL_NROM_IP4_DF_CLEAR_STATUS, + FAL_NROM_IP4_IPID_RANDOM_STATUS, + FAL_NROM_IP4_FRAG_OFFSET_MIN_SIZE, + + /* define IP4 related normalization items */ + FAL_NROM_IP6_INVALID_PL_CMD, + FAL_NROM_IP6_INVALID_SIP_CMD, + FAL_NROM_IP6_INVALID_DIP_CMD, + + /* define TCP related normalization items */ + FAL_NROM_TCP_BLAT_CMD, + FAL_NROM_TCP_INVALID_HL_CMD, + FAL_NROM_TCP_INVALID_SYN_CMD, + FAL_NROM_TCP_SU_BLOCK_CMD, + FAL_NROM_TCP_SP_BLOCK_CMD, + FAL_NROM_TCP_SAP_BLOCK_CMD, + FAL_NROM_TCP_XMAS_SCAN_CMD, + FAL_NROM_TCP_NULL_SCAN_CMD, + FAL_NROM_TCP_SR_BLOCK_CMD, + FAL_NROM_TCP_SF_BLOCK_CMD, + FAL_NROM_TCP_SAR_BLOCK_CMD, + FAL_NROM_TCP_RST_SCAN_CMD, + FAL_NROM_TCP_SYN_WITH_DATA_CMD, + FAL_NROM_TCP_RST_WITH_DATA_CMD, + FAL_NROM_TCP_FA_BLOCK_CMD, + FAL_NROM_TCP_PA_BLOCK_CMD, + FAL_NROM_TCP_UA_BLOCK_CMD, + FAL_NROM_TCP_INVALID_CHKSUM_CMD, + FAL_NROM_TCP_INVALID_URGPTR_CMD, + FAL_NROM_TCP_INVALID_OPTIONS_CMD, + FAL_NROM_TCP_MIN_HDR_SIZE, + + /* define UDP related normalization items */ + FAL_NROM_UDP_BLAT_CMD, + FAL_NROM_UDP_INVALID_LEN_CMD, + FAL_NROM_UDP_INVALID_CHKSUM_CMD, + + /* define ICMP related normalization items */ + FAL_NROM_ICMP4_PING_PL_EXCEED_CMD, + FAL_NROM_ICMP6_PING_PL_EXCEED_CMD, + FAL_NROM_ICMP4_PING_FRAG_CMD, + FAL_NROM_ICMP6_PING_FRAG_CMD, + FAL_NROM_ICMP4_PING_MAX_PL_VALUE, + FAL_NROM_ICMP6_PING_MAX_PL_VALUE, + } + fal_norm_item_t; + + typedef struct { + fal_fwd_cmd_t cmd; /* action for the exception */ + a_bool_t deacclr_en; /* 0 for disable and 1 for disable */ + a_bool_t l3route_only_en; /*host/network route 0: disable and 1: enable*/ + a_bool_t l2fwd_only_en; /*l2 forward 0: disable and 1: enable*/ + a_bool_t l3flow_en; /* 0 for disable and 1 for disable */ + a_bool_t l2flow_en; /* 0 for disable and 1 for disable */ + a_bool_t multicast_en; /* 0 for disable and 1 for disable */ + } fal_l3_excep_ctrl_t; + + typedef struct { + a_uint8_t small_ip4ttl; /* small ttl value checking */ + a_uint8_t small_ip6hoplimit; /*small hoplimit value for check*/ + } fal_l3_excep_parser_ctrl; + +#define TCP_FLAGS_MAX 8 + typedef struct { + a_uint8_t tcp_flags[TCP_FLAGS_MAX]; /*flag for exception*/ + a_uint8_t tcp_flags_mask[TCP_FLAGS_MAX]; /*flag mask*/ + } fal_l4_excep_parser_ctrl; + +enum { + FUNC_SEC_L3_EXCEP_CTRL_SET = 0, + FUNC_SEC_L3_EXCEP_CTRL_GET, + FUNC_SEC_L3_EXCEP_PARSER_CTRL_SET, + FUNC_SEC_L3_EXCEP_PARSER_CTRL_GET, + FUNC_SEC_L4_EXCEP_PARSER_CTRL_SET, + FUNC_SEC_L4_EXCEP_PARSER_CTRL_GET, +}; + + sw_error_t + fal_sec_norm_item_set(a_uint32_t dev_id, fal_norm_item_t item, void *value); + + sw_error_t + fal_sec_norm_item_get(a_uint32_t dev_id, fal_norm_item_t item, void *value); + + 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 + 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 + fal_sec_l3_excep_parser_ctrl_set(a_uint32_t dev_id, fal_l3_excep_parser_ctrl *ctrl); + + sw_error_t + fal_sec_l3_excep_parser_ctrl_get(a_uint32_t dev_id, fal_l3_excep_parser_ctrl *ctrl); + + sw_error_t + fal_sec_l4_excep_parser_ctrl_set(a_uint32_t dev_id, fal_l4_excep_parser_ctrl *ctrl); + + sw_error_t + fal_sec_l4_excep_parser_ctrl_get(a_uint32_t dev_id, fal_l4_excep_parser_ctrl *ctrl); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_SEC_H_ */ + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/fal/fal_servcode.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_servcode.h new file mode 100755 index 000000000..cf8705bbb --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_servcode.h @@ -0,0 +1,137 @@ +/* + * 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. + */ + + +/** + * @defgroup fal_gen FAL_SERVCODE + * @{ + */ +#ifndef _FAL_SERVCODE_H_ +#define _FAL_SERVCODE_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "sw.h" +#include "fal/fal_type.h" + +#if defined(SW_API_LOCK) && (!defined(HSL_STANDALONG)) +#define FAL_SERVCODE_API_LOCK +#define FAL_SERVCODE_API_UNLOCK +#else +#define FAL_SERVCODE_API_LOCK +#define FAL_SERVCODE_API_UNLOCK +#endif + +enum { + FLD_UPDATE_CAPWAP_EN = 0, /*only for IP197*/ + FLD_UPDATE_DIRECTION, /*only for IP197*/ + FLD_UPDATE_DEST_INFO, + FLD_UPDATE_SRC_INFO, + FLD_UPDATE_INT_PRI, + FLD_UPDATE_SERVICE_CODE, + FLD_UPDATE_HASH_FLOW_INDEX, + FLD_UPDATE_FAKE_L2_PROT_EN, /*only for IP197*/ +}; + +enum { + IN_VLAN_TAG_FMT_CHECK_BYP = 0, + IN_VLAN_MEMBER_CHECK_BYP, + IN_VLAN_XLT_BYP, + MY_MAC_CHECK_BYP, + DIP_LOOKUP_BYP, + FLOW_LOOKUP_BYP = 5, + FLOW_ACTION_BYP, + ACL_BYP, + FAKE_MAC_HEADER_BYP, + SERVICE_CODE_BYP, + WRONG_PKT_FMT_L2_BYP = 10, + WRONG_PKT_FMT_L3_IPV4_BYP, + WRONG_PKT_FMT_L3_IPV6_BYP, + WRONG_PKT_FMT_L4_BYP, + FLOW_SERVICE_CODE_BYP, + ACL_SERVICE_CODE_BYP = 15, + FAKE_L2_PROTO_BYP, + PPPOE_TERMINATION_BYP, + DEFAULT_VLAN_BYP, + IN_VLAN_ASSIGN_FAIL_BYP = 24, + SOURCE_GUARD_BYP, + MRU_MTU_CHECK_BYP, + FLOW_SRC_CHECK_BYP, + FLOW_QOS_BYP, + + EG_VLAN_MEMBER_CHECK_BYP = 32, + EG_VLAN_XLT_BYP, + EG_VLAN_TAG_FMT_CTRL_BYP, + FDB_LEARN_BYP = 35, + FDB_REFRESH_BYP, + L2_SOURCE_SEC_BYP, + MANAGEMENT_FWD_BYP, + BRIDGING_FWD_BYP, + IN_STP_FLTR_BYP = 40, + EG_STP_FLTR_BYP, + SOURCE_FLTR_BYP, + POLICER_BYP, + L2_PKT_EDIT_BYP, + L3_PKT_EDIT_BYP = 45, + ACL_POST_ROUTING_CHECK_BYP, + PORT_ISOLATION_BYP, + /* for cypress Qos bypass */ + PRE_ACL_QOS_BYP, + POST_ACL_QOS_BYP, + DSCP_QOS_BYP, + PCP_QOS_BYP, + PREHEADER_QOS_BYP, + + RX_VLAN_COUNTER_BYP = 64, + RX_COUNTER_BYP, + TX_VLAN_COUNTER_BYP, + TX_COUNTER_BYP, +}; + +typedef struct { + a_bool_t dest_port_valid; /* dest_port_id valid or not */ + fal_port_t dest_port_id; /* destination physical port id:0-7 */ + a_uint32_t bypass_bitmap[3]; /* refer to enum IN_VLAN_TAG_FMT_CHECK_BYP... */ + a_uint32_t direction; /* if dest is vp, fill it in dest_info or src_info, 0:dest, 1:src */ + + a_uint32_t field_update_bitmap; /* refer to enum FLD_UPDATE_CAPWAP_EN... */ + a_uint32_t next_service_code; /* next service code */ + a_uint32_t hw_services; /* HW_SERVICES to IP-197 */ + a_uint32_t offset_sel; /* Select the offset value to IP-197:0: l3_offset, 1:l4_offset */ +} fal_servcode_config_t; + +enum +{ + /*servcode*/ + FUNC_SERVCODE_CONFIG_SET = 0, + FUNC_SERVCODE_CONFIG_GET, + FUNC_SERVCODE_LOOPCHECK_EN, + FUNC_SERVCODE_LOOPCHECK_STATUS_GET, +}; + +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 fal_servcode_config_get(a_uint32_t dev_id, a_uint32_t servcode_index, fal_servcode_config_t *entry); +sw_error_t fal_servcode_loopcheck_en(a_uint32_t dev_id, a_bool_t enable); +sw_error_t fal_servcode_loopcheck_status_get(a_uint32_t dev_id, a_bool_t *enable); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_SERVCODE_H_ */ +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/fal/fal_sfp.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_sfp.h new file mode 100755 index 000000000..973245c21 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_sfp.h @@ -0,0 +1,578 @@ +/* + * 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 fal_sfp FAL_SFP + * @{ + */ +#ifndef _FAL_SFP_H_ +#define _FAL_SFP_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "sw.h" +#include "fal/fal_type.h" + +typedef enum { + FAL_SFP_CC_BASE = 0, /* Check code for Base ID Fields (addresses 0 to 62) */ + FAL_SFP_CC_EXT, /* Check code for the Extended ID Fields (addresses 64 to 94) */ + FAL_SFP_CC_DMI, /* Check code for Base Diagnostic Fields (addresses 0 to 94) */ +} fal_sfp_cc_type_t; + +typedef struct { + a_uint32_t addr; /* Addr A0h or A2h */ + a_uint32_t offset; /* offset in eeprom */ + a_uint32_t count; /* data bytes */ + a_uint8_t data[256]; /* data value */ +} fal_sfp_data_t; + +/* A0h offset: 0-2 bytes */ +typedef struct { + a_uint8_t identifier; /* type of transceiver */ + /* + * 00h: Unknown or unspecified + * 01h: GBIC + * 02h: Module soldered to motherboard (ex: SFF) + * 03h: SFP or SFP “Plus†+ * 04h: Reserved for “300 pin XBI†devices* + * 05h: Reserved for “Xenpak†devices* + * 06h: Reserved for “XFP†devices* + * 07h: Reserved for “XFF†devices* + * 08h: Reserved for “XFP-E†devices* + * 09h: Reserved for “XPak†devices* + * 0Ah: Reserved for “X2†devices* + * 0Bh: Reserved for “DWDM-SFP†devices* + * 0Ch: Reserved for “QSFP†devices* + * 0D-7Fh: Reserved, unallocated + * 80-FFh: Vendor specific + */ + a_uint8_t ext_indentifier; /* Extended identifier of type of transceiver */ + /* + * 00h: GBIC definition is not specified or not compliant with a defined MOD_DEF. + * 01h: GBIC is compliant with MOD_DEF 1 + * 02h: GBIC is compliant with MOD_DEF 2 + * 03h: GBIC is compliant with MOD_DEF 3 + * 04h: GBIC/SFP function is defined by two-wire interface ID only + * 05h: GBIC is compliant with MOD_DEF 5 + * 06h: GBIC is compliant with MOD_DEF 6 + * 07h: GBIC is compliant with MOD_DEF 7 + * 08-FFh: Unallocated + */ + a_uint8_t connector_type; /* Code for connector type */ + /* + * 00h: Unknown or unspecified + * 01h: SC + * 02h: Fibre Channel Style 1 copper connector + * 03h: Fibre Channel Style 2 copper connector + * 04h: BNC/TNC + * 05h: Fibre Channel coaxial headers + * 06h: FiberJack + * 07h: LC + * 08h: MT-RJ + * 09h: MU + * 0AH: SG + * 0Bh: Optical pigtail + * 0Ch: MPO Parallel Optic + * 0D-1Fh: Unallocated + * 20h: HSSDC II + * 21h: Copper pigtail + * 22h: RJ45 + * 23h-7Fh: Unallocated + * 80h-FFh: Vendor specific + */ +} fal_sfp_dev_type_t; + +/* A0h offset: 3-10 bytes */ +typedef struct { + a_uint8_t eth_10g_ccode; /* 10G Ethernet Compliance Codes */ + /* + * offset 3 bit7: 10G Base-ER + * offset 3 bit6: 10G Base-LRM + * offset 3 bit5: 10G Base-LR + * offset 3 bit4: 10G Base-SR + */ + a_uint8_t infiniband_ccode; /* Infiniband Compliance Codes */ + /* + * offset 3 bit3: 1X SX + * offset 3 bit2: 1X LX + * offset 3 bit1: 1X Copper Active + * offset 3 bit0: 1X Copper Passive + */ + a_uint8_t escon_ccode; /* ESCON Compliance Codes */ + /* + * offset 4 bit7: ESCON MMF, 1310nm LED + * offset 4 bit6: ESCON SMF, 1310nm Laser + */ + a_uint16_t sonet_ccode; /* SONET Compliance Codes */ + /* + * offset 4 bit5: OC-192, short reach + * offset 4 bit4: SONET reach specifier bit 1 + * offset 4 bit3: SONET reach specifier bit 2 + * offset 4 bit2: OC-48, long reach + * offset 4 bit1: OC-48, intermediate reach + * offset 4 bit0: OC-48, short reach + * offset 5 bit7: Unallocated + * offset 5 bit6: OC-12, single mode, long reach + * offset 5 bit5: OC-12, single mode, inter. reach + * offset 5 bit4: OC-12, short reach + * offset 5 bit3: Unallocated + * offset 5 bit2: OC-3, single mode, long reach + * offset 5 bit1: OC-3, single mode, inter. reach + * offset 5 bit0: OC-3, short reach + */ + a_uint8_t eth_ccode; /* Ethernet Compliance Codes */ + /* + * offset 6 bit7: BASE-PX + * offset 6 bit6: BASE-BX10 + * offset 6 bit5: 100BASE-FX + * offset 6 bit4: 100BASE-LX/LX10 + * offset 6 bit3: 1000BASE-T + * offset 6 bit2: 1000BASE-CX + * offset 6 bit1: 1000BASE-LX + * offset 6 bit0: 1000BASE-SX + */ + a_uint8_t fibre_chan_link_length; /* Fibre Channel Link Length */ + /* + * offset 7 bit7: very long distance (V) + * offset 7 bit6: short distance (S) + * offset 7 bit5: intermediate distance (I) + * offset 7 bit4: long distance (L) + * offset 7 bit3: medium distance (M) + */ + a_uint8_t fibre_chan_tech; /* Fibre Channel Technology */ + /* + * offset 7 bit2: Shortwave laser, linear Rx (SA) + * offset 7 bit1: Longwave laser (LC) + * offset 7 bit0: Electrical inter-enclosure (EL) + * offset 8 bit7: Electrical intra-enclosure (EL) + * offset 8 bit6: Shortwave laser w/o OFC (SN) + * offset 8 bit5: Shortwave laser with OFC4 (SL) + * offset 8 bit4: Longwave laser (LL) + */ + a_uint8_t sfp_cable_tech; /* SFP+ Cable Technology */ + /* + * offset 8 bit3: Active Cable + * offset 8 bit2: passive Cable + * offset 8 bit1: unallocated + * offset 8 bit0: unallocated + */ + a_uint8_t fibre_chan_trans_md; /* Fibre Channel Transmission Media */ + /* + * offset 9 bit7: twin axial pair(TW) + * offset 9 bit6: twisted pair(TP) + * offset 9 bit5: miniature coax(MI) + * offset 9 bit4: video coax(TV) + * offset 9 bit3: multimode, 62.5um(M6) + * offset 9 bit2: multimode, 50um(M5,M5E) + * offset 9 bit1: unallocated + * offset 9 bit0: sigle mode(SM) + */ + a_uint8_t fibre_chan_speed; /* Fibre Channel Speed */ + /* + * offset 10 bit7: 1200 MBytes/sec + * offset 10 bit6: 800 MBytes/sec + * offset 10 bit5: 1600 MBytes/sec + * offset 10 bit4: 400 MBytes/sec + * offset 10 bit3: unallocated + * offset 10 bit2: 200 MBytes/sec + * offset 10 bit1: unallocated + * offset 10 bit0: 100 MBytes/sec + */ +} fal_sfp_transc_code_t; + +/* A0h offset: 11-13 bytes */ +typedef struct { + a_uint8_t encode; /* the serial encoding mechanism */ + /* + * 0h: Unspecified + * 1h: 8B/10B + * 2h: 4B/5B + * 3h: NRZ + * 4h: Manchester + * 5h: SONET Scrambled + * 6h: 64B/66B + * 7h-FFh: Unallocated + */ + a_uint8_t nominal_bit_rate; /* the nomial bit rate */ + /* + * these bits necessary to encode and delimit the signal + * as well as those bits carrying data information, + * the actual transfer rate will depend on the encoding + * of the data definded by the encode value above. + */ + a_uint8_t rate_id; /* the selected rate */ + /* + * 0h: Unspecified + * 1h: Defined for SFF-8079 (4/2/1G Rate_Select & AS0/AS1) + * 2h: Defined for SFF-8431 (8/4/2G Rx Rate_Select only) + * 3h: Unspecified * + * 4h: Defined for SFF-8431 (8/4/2G Tx Rate_Select only) + * 5h: Unspecified * + * 6h: Defined for SFF-8431 (8/4/2G Independent Rx & Tx Rate_select) + * 7h-FFh: Unallocated + */ +} fal_sfp_rate_encode_t; + + +/* A0h offset: 14-19 bytes */ +typedef struct { + a_uint8_t single_mode_length_km; /* the link length of km in single mode */ + a_uint8_t single_mode_length_100m; /* the link length of 100m in single mode */ + a_uint8_t om2_mode_length_10m; /* the link length of 10m micron multimode OM2 */ + a_uint8_t om1_mode_length_10m; /* the link length of 10m micron multimode OM1 */ + a_uint8_t copper_mode_length_1m; /* the link length of 1m copper mode */ + a_uint8_t om3_mode_length_1m; /* the link length of 10m micron multimode OM3 */ +} fal_sfp_link_length_t; + +/* A0h offset: 20-35 bytes vendor name*/ +/* A0h offset: 36th byte transceiver code */ +/* A0h offset: 37-39 bytes vendor oui */ +/* A0h offset: 40-55 bytes vendor pn */ +/* A0h offset: 56-59 bytes vendor rev */ +/* A0h offset: 68-83 bytes for the vendor serial number */ +/* A0h offset: 84-91 bytes for the vendor's date code in ascii charaters */ +typedef struct { + a_uint8_t vendor_name[16]; /* vendor name */ + a_uint8_t vendor_oui[3]; /* vendor OUI */ + a_uint8_t vendor_pn[16]; /* vendor PN */ + a_uint8_t vendor_rev[4]; /* vendor Rev */ + a_uint8_t vendor_sn[16]; /* the vendor serial number */ + a_uint8_t vendor_date_code[8]; /* the vendor's date code in ascii charaters */ +} fal_sfp_vendor_info_t; + +/* A0h offset: 60-61 bytes */ +typedef struct { + a_uint16_t laser_wavelength; /* the output laser wave length in nm */ +} fal_sfp_laser_wavelength_t; + +/* A0h offset: 62 byte unallocated */ +/* A0h offset: 63 byte for checksum base */ + +/* A0h offset: 64-65 bytes */ +typedef struct { + /* the implemented options */ + a_uint8_t linear_recv_output:1; + a_uint8_t pwr_level_declar:1; + a_uint8_t cool_transc_declar:1; + a_uint8_t reversed_1:5; + + a_uint8_t reversed_2:1; + a_uint8_t loss_signal:1; + a_uint8_t loss_invert_signal:1; + a_uint8_t tx_fault_signal:1; + a_uint8_t tx_disable:1; + a_uint8_t rate_sel:1; + a_uint8_t reversed_3:2; + /* + * offset 64 bit7-3: Unallocated + * offset 64 bit2: Cooled Transceiver Declaration (see SFF-8431) + * offset 64 bit1: Power Level Declaration (see SFF-8431) + * offset 64 bit0: Linear Receiver Output Implemented (see SFF-8431) + * offset 65 bit7-6: Unallocated + * offset 65 bit5: RATE_SELECT functionality is implemented + * offset 65 bit4: TX_DISABLE is implemented and disables the high speed serial output + * offset 65 bit3: TX_FAULT signal implemented. (See SFP MSA) + * offset 65 bit2: Loss of Signal implemented, signal inverted from standard definition + * offset 65 bit1: Loss of Signal implemented, signal as defined in SFP MSA + * offset 65 bit0: Unallocated + */ +} fal_sfp_option_t; + +/* A0h offset: 66-67 bytes */ +typedef struct { + a_uint8_t upper_rate_limit; /* the upper rate limit */ + a_uint8_t lower_rate_limit; /* the lower rate limit */ +} fal_sfp_rate_t; + +/* A0h offset: 68-83 bytes for the vendor serial number */ +/* A0h offset: 84-91 bytes for the vendor's date code in ascii charaters */ + +/* A0h offset: 92-94 bytes */ +typedef struct { + /* digital diagnostic monitoring type */ + a_uint8_t reserved_type:2; + a_uint8_t addr_mode:1; + a_uint8_t rec_pwr_type:1; + a_uint8_t external_cal:1; + a_uint8_t internal_cal:1; + a_uint8_t diag_mon_flag:1; + a_uint8_t legacy_type:1; + /* + * bit 7: Reserved for legacy diagnostic + * bit 6: Digital diagnostic monitoring implemented + * bit 5: Internally calibrated + * bit 4: Externally calibrated + * bit 3: Received power measurement type + * 0 = OMA, 1 = average power + * bit 2: Address change required “addressing modes†+ * bit1~0: unallocated + */ + /* optional digital diagnostic features implemented */ + a_uint8_t reserved_op:1; + a_uint8_t soft_rate_sel_op:1; + a_uint8_t app_sel_op:1; + a_uint8_t soft_rate_ctrl_op:1; + a_uint8_t rx_los_op:1; + a_uint8_t tx_fault_op:1; + a_uint8_t tx_disable_ctrl_op:1; + a_uint8_t alarm_warning_flag_op:1; + /* + * bit 7: Optional Alarm/warning flags implemented for all monitored quantities + * bit 6: Optional soft TX_DISABLE control and monitoring implemented + * bit 5: Optional soft TX_FAULT monitoring implemented + * bit 4: Optional soft RX_LOS monitoring implemented + * bit 3: Optional soft RATE_SELECT control and monitoring implemented + * bit 2: Optional Application Select control implemented per SFF-8079 + * bit 1: Optional soft Rate Select control implemented per SFF-8431 + * bit 0: Unallocated + */ + a_uint8_t compliance_feature; /* the implemented features */ + /* + * 00h: Digital diagnostic functionality not included or undefined + * 01h: Includes functionality described in Rev 9.3 of SFF-8472. + * 02h: Includes functionality described in Rev 9.5 of SFF-8472. + * 03h: Includes functionality described in Rev 10.2 of SFF-8472. + * 04h: Includes functionality described in Rev 10.4 of SFF-8472. + * 05h~FFh: Unallocated + */ +} fal_sfp_enhanced_cfg_t; + +/* A0h offset: 95th byte for checksum extended id field */ + +/* A0h offset: 96-127 bytes Vendor Specific */ +/* A0h offset: 128-255 bytes Reserved */ + +/* A2h offset: 0-39 bytes */ +typedef struct { + a_uint16_t temp_high_alarm; /* the temperature alarm high value */ + a_uint16_t temp_low_alarm; /* the temperature alarm low value */ + a_uint16_t temp_high_warning; /* the temperature warning high value */ + a_uint16_t temp_low_warning; /* the temperature warning low value */ + a_uint16_t vol_high_alarm; /* the voltage alarm high value */ + a_uint16_t vol_low_alarm; /* the voltage alarm low value */ + a_uint16_t vol_high_warning; /* the voltage warning high value */ + a_uint16_t vol_low_warning; /* the voltage warning low value */ + a_uint16_t bias_high_alarm; /* the bias alarm high value */ + a_uint16_t bias_low_alarm; /* the bias alarm low value */ + a_uint16_t bias_high_warning; /* the bias warning high value */ + a_uint16_t bias_low_warning; /* the bias warning low value */ + a_uint16_t tx_power_high_alarm; /* the tx power alarm high value */ + a_uint16_t tx_power_low_alarm; /* the tx power alarm low value */ + a_uint16_t tx_power_high_warning;/* the tx power warning high value */ + a_uint16_t tx_power_low_warning; /* the tx power warning low value */ + a_uint16_t rx_power_high_alarm; /* the rx power alarm high value */ + a_uint16_t rx_power_low_alarm; /* the rx power alarm low value */ + a_uint16_t rx_power_high_warning;/* the rx power warning high value */ + a_uint16_t rx_power_low_warning; /* the rx power warning low value */ +} fal_sfp_internal_threshold_t; + +/* A2h offset: 40-55 bytes Reserved for future monitored quantities */ + +/* A2h offset: 56-91 bytes */ +typedef struct { + a_uint32_t rx_power4; /* Single precision floating point Rx optical power4 */ + a_uint32_t rx_power3; /* Single precision floating point Rx optical power3 */ + a_uint32_t rx_power2; /* Single precision floating point Rx optical power2 */ + a_uint32_t rx_power1; /* Single precision floating point Rx optical power1 */ + a_uint32_t rx_power0; /* Single precision floating point Rx optical power0 */ + a_uint16_t tx_bias_slope; /* Fixed decimal for laser bias current */ + a_uint16_t tx_bias_offset; /* Fixed decimal for laser bias current */ + a_uint16_t tx_power_slope; /* Fixed decimal for transmitter coupled output power */ + a_uint16_t tx_power_offset;/* Fixed decimal for transmitter coupled output power */ + a_uint16_t temp_slope; /* Fixed decimal for internal module temperature */ + a_uint16_t temp_offset; /* Fixed decimal for internal module temperature */ + a_uint16_t vol_slope; /* Fixed decimal for internal module supply voltage */ + a_uint16_t vol_offset; /* Fixed decimal for internal module supply voltage */ +} fal_sfp_cal_const_t; + +/* A2h offset: 92-94 bytes Unallocated */ + +/* A2h offset: 95th byte checsum for Base Diagnostic Fields*/ + +/* A2h offset: 96-105 bytes */ +typedef struct { + a_uint16_t cur_temp; /* Internally measured module temperature */ + a_uint16_t cur_vol; /* Internally measured supply voltage in transceiver */ + a_uint16_t tx_cur_bias; /* Internally measured TX Bias Current */ + a_uint16_t tx_cur_power; /* Measured TX output power */ + a_uint16_t rx_cur_power; /* Measured RX input power */ +} fal_sfp_realtime_diag_t; + +/* A2h offset: 106-109 bytes Unallocated */ + +/* A2h offset: 110th byte for base control/status */ +/* A2h offset: 111th byte Reserved */ +/* A2h offset: 118th byte for extend control/status */ +typedef struct { + /* Optional Status/Control Bits */ + a_uint8_t data_ready:1; + a_uint8_t rx_los:1; + a_uint8_t tx_fault:1; + a_uint8_t soft_rate_sel:1; + a_uint8_t rate_sel:1; + a_uint8_t rs_state:1; + a_uint8_t soft_tx_disable:1; + a_uint8_t tx_disable:1; + + /* + * bit7: tx disable state + * bit6: soft tx disable select + * bit5: rs state + * bit4: rate_select state + * bit3: soft rate_select select + * bit2: tx fault state + * bit1: rx_los state + * bit0: data_ready_bar state + */ + + /* Extended Control/Status Bits */ + a_uint8_t pwr_level_sel:1; + a_uint8_t pwr_level_op_state:1; + a_uint8_t reserved_1:1; + a_uint8_t soft_rs_sel:1; + a_uint8_t reserved_2:4; + /* + * bit7-4: Reserved + * bit3: soft RS select + * bit2: Reserved + * bit1: Power level operation state + * bit0: Power level select + */ +} fal_sfp_ctrl_status_t; + +/* A2h offset: 112-113 byte Alarm flag bits */ +/* A2h offset: 114-115 byte Alarm Reserved */ +/* A2h offset: 116-117 byte Warning flag bits */ +typedef struct { + /* internal diagnose exceeds high alarm level */ + a_uint8_t tx_pwr_low_alarm:1; + a_uint8_t tx_pwr_high_alarm:1; + a_uint8_t tx_bias_low_alarm:1; + a_uint8_t tx_bias_high_alarm:1; + a_uint8_t vcc_low_alarm:1; + a_uint8_t vcc_high_alarm:1; + a_uint8_t tmp_low_alarm:1; + a_uint8_t tmp_high_alarm:1; + a_uint8_t reserved_alarm:6; + a_uint8_t rx_pwr_low_alarm:1; + a_uint8_t rx_pwr_high_alarm:1; + + /* internal diagnose exceeds high warn level */ + a_uint8_t tx_pwr_low_warning:1; + a_uint8_t tx_pwr_high_warning:1; + a_uint8_t tx_bias_low_warning:1; + a_uint8_t tx_bias_high_warning:1; + a_uint8_t vcc_low_warning:1; + a_uint8_t vcc_high_warning:1; + a_uint8_t tmp_low_warning:1; + a_uint8_t tmp_high_warning:1; + a_uint8_t reserved_warning:6; + a_uint8_t rx_pwr_low_warning:1; + a_uint8_t rx_pwr_high_warning:1; + /* + * bit 15: internal temperature exceeds high alarm/warning level + * bit 14: internal temperature is below low alarm/warning level + * bit 13: internal supply voltage exceeds high alarm/warning level + * bit 12: internal supply voltage is below low alarm/warning level + * bit 11: TX Bias current exceeds high alarm/warning level + * bit 10: TX Bias current is below low alarm/warning level + * bit 09: TX output power exceeds high alarm/warning level + * bit 08: TX output power is below low alarm/warning level + * bit 07: Received Power exceeds high alarm/warning level + * bit 06: Received Power is below low alarm/warning level + * bit 05~00: reserved alarm/warning + */ +} fal_sfp_alarm_warn_flag_t; + +/* A2h offset: 119th byte Reserved */ +/* A2h offset: 120-127 byte Vendor Specific locations */ +/* A2h offset: 128-247 byte User EEPROM */ +/* A2h offset: 248-255 byte Vendor Specific locations */ + +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 +fal_sfp_eeprom_data_set(a_uint32_t dev_id, a_uint32_t port_id, fal_sfp_data_t *entry); + +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 +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 +fal_sfp_rate_encode_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_sfp_rate_encode_t *encode); + +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 +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 +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 +fal_sfp_option_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_sfp_option_t *option); + +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 +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 +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 +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 +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 +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 +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 +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); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_SFP_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/fal/fal_shaper.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_shaper.h new file mode 100755 index 000000000..e266eeb02 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_shaper.h @@ -0,0 +1,163 @@ +/* + * 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. + */ + + +/** + * @defgroup fal_shaper FAL_SHAPER + * @{ + */ +#ifndef _FAL_SHAPER_H_ +#define _FAL_SHAPER_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "sw.h" +#include "fal/fal_type.h" + +typedef enum +{ + FAL_IPG_PREAMBLE_FRAME_CRC = 0, /* IPG + Preamble + Frame + CRC */ + FAL_FRAME_CRC, /* Frame + CRC */ + FAL_L3_EXCLUDE_CRC /* after Ethernet type excude CRC*/ +} fal_shaper_frame_mode_t; + +typedef struct +{ + a_bool_t couple_en; /* two buckets coupled enable or disable*/ + a_uint32_t meter_unit; /* 0 byte based, 1 frame based */ + a_bool_t c_shaper_en; /* egress shaer C bucket enable or disable */ + a_uint32_t cbs; /* committed burst size */ + a_uint32_t cir; /* committed information rate */ + a_bool_t e_shaper_en; /* egress shaper E bucket enable or disable */ + a_uint32_t ebs; /* excess burst size */ + a_uint32_t eir; /* excess information rate */ + fal_shaper_frame_mode_t shaper_frame_mode; /* shaper frame mode */ +} fal_shaper_config_t; + +typedef struct +{ + a_bool_t c_token_number_negative_en; /* C token is negative or not */ + a_uint32_t c_token_number; /* C token value */ + a_bool_t e_token_number_negative_en; /* E token is negative or not */ + a_uint32_t e_token_number; /* E token value */ +} fal_shaper_token_number_t; + +enum +{ + FUNC_ADPT_FLOW_SHAPER_SET = 0, + FUNC_ADPT_QUEUE_SHAPER_GET, + FUNC_ADPT_QUEUE_SHAPER_TOKEN_NUMBER_SET, + FUNC_ADPT_PORT_SHAPER_GET, + FUNC_ADPT_FLOW_SHAPER_TIME_SLOT_GET, + FUNC_ADPT_PORT_SHAPER_TIME_SLOT_GET, + FUNC_ADPT_FLOW_SHAPER_TIME_SLOT_SET, + FUNC_ADPT_PORT_SHAPER_TOKEN_NUMBER_SET, + FUNC_ADPT_QUEUE_SHAPER_TOKEN_NUMBER_GET, + FUNC_ADPT_QUEUE_SHAPER_TIME_SLOT_GET, + FUNC_ADPT_PORT_SHAPER_TOKEN_NUMBER_GET, + FUNC_ADPT_FLOW_SHAPER_TOKEN_NUMBER_SET, + FUNC_ADPT_FLOW_SHAPER_TOKEN_NUMBER_GET, + FUNC_ADPT_PORT_SHAPER_SET, + FUNC_ADPT_PORT_SHAPER_TIME_SLOT_SET, + FUNC_ADPT_FLOW_SHAPER_GET, + FUNC_ADPT_QUEUE_SHAPER_SET, + FUNC_ADPT_QUEUE_SHAPER_TIME_SLOT_SET, + FUNC_ADPT_SHAPER_IPG_PREAMBLE_LENGTH_SET, + FUNC_ADPT_SHAPER_IPG_PREAMBLE_LENGTH_GET, +}; + +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 +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 +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 +fal_port_shaper_timeslot_set(a_uint32_t dev_id, a_uint32_t timeslot); + +sw_error_t +fal_queue_shaper_timeslot_set(a_uint32_t dev_id, a_uint32_t timeslot); + +sw_error_t +fal_flow_shaper_timeslot_set(a_uint32_t dev_id, a_uint32_t timeslot); + +sw_error_t +fal_shaper_ipg_preamble_length_set(a_uint32_t dev_id, a_uint32_t ipg_pre_length); + +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 +fal_queue_shaper_set(a_uint32_t dev_id,a_uint32_t queue_id, + fal_shaper_config_t * shaper); + +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 +fal_flow_shaper_set(a_uint32_t dev_id, a_uint32_t flow_id, + fal_shaper_config_t * shaper); + +#ifndef IN_SHAPER_MINI +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 +fal_flow_shaper_get(a_uint32_t dev_id, a_uint32_t flow_id, + fal_shaper_config_t * shaper); + +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 +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 +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 +fal_port_shaper_timeslot_get(a_uint32_t dev_id, a_uint32_t *timeslot); + +sw_error_t +fal_queue_shaper_timeslot_get(a_uint32_t dev_id, a_uint32_t *timeslot); + +sw_error_t +fal_flow_shaper_timeslot_get(a_uint32_t dev_id, a_uint32_t *timeslot); + +sw_error_t +fal_shaper_ipg_preamble_length_get(a_uint32_t dev_id, a_uint32_t *ipg_pre_length); +#endif + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_SHAPER_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/fal/fal_stp.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_stp.h new file mode 100755 index 000000000..9d87a9bdc --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_stp.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup fal_stp FAL_STP + * @{ + */ +#ifndef _FAL_STP_H_ +#define _FAL_STP_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "sw.h" +#include "fal/fal_type.h" + +#define FAL_SINGLE_STP_ID 0 + + /** + @brief This enum defines port state for spanning tree. + */ + typedef enum { + FAL_STP_DISABLED = 0, /**< disable state*/ + FAL_STP_BLOCKING, /**< blocking state*/ + FAL_STP_LISTENING, /**< listening state*/ + FAL_STP_LEARNING, /**< learning state*/ + FAL_STP_FORWARDING, /**< forwarding state*/ + FAL_STP_STATE_BUTT + } + fal_stp_state_t; + +/* + * These two #define lines are used to keep them for the + * compatibility of previous project. + */ +#define FAL_STP_BLOKING FAL_STP_BLOCKING +#define FAL_STP_FARWARDING FAL_STP_FORWARDING + +enum { + FUNC_STP_PORT_STATE_SET = 0, + FUNC_STP_PORT_STATE_GET, +}; + + 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 + 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); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_STP_H_ */ + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/fal/fal_trunk.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_trunk.h new file mode 100755 index 000000000..0b5bb5429 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_trunk.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup fal_trunk FAL_TRUNK + * @{ + */ +#ifndef _FAL_TRUNK_H_ +#define _FAL_TRUNK_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "sw.h" +#include "fal/fal_type.h" + + +#define FAL_TRUNK_HASH_KEY_DA 0x1 +#define FAL_TRUNK_HASH_KEY_SA 0x2 +#define FAL_TRUNK_HASH_KEY_DIP 0x4 +#define FAL_TRUNK_HASH_KEY_SIP 0x8 +#define FAL_TRUNK_HASH_KEY_SRC_PORT 0x10 +#define FAL_TRUNK_HASH_KEY_L4_SRC_PORT 0x20 +#define FAL_TRUNK_HASH_KEY_L4_DST_PORT 0x40 +#define FAL_TRUNK_HASH_KEY_UDF0 0x80 +#define FAL_TRUNK_HASH_KEY_UDF1 0x100 +#define FAL_TRUNK_HASH_KEY_UDF2 0x200 +#define FAL_TRUNK_HASH_KEY_UDF3 0x400 +#define FAL_TRUNK_GROUP_MAX_MEMEBER 4 + +enum { + FUNC_TRUNK_GROUP_SET = 0, + FUNC_TRUNK_GROUP_GET, + FUNC_TRUNK_HASH_MODE_SET, + FUNC_TRUNK_HASH_MODE_GET, + FUNC_TRUNK_FAILOVER_ENABLE, + FUNC_TRUNK_FAILOVER_STATUS_GET, +}; + +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 +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 +fal_trunk_hash_mode_set(a_uint32_t dev_id, a_uint32_t hash_mode); + +sw_error_t +fal_trunk_hash_mode_get(a_uint32_t dev_id, a_uint32_t * hash_mode); + +sw_error_t +fal_trunk_manipulate_sa_set(a_uint32_t dev_id, fal_mac_addr_t * addr); + +sw_error_t +fal_trunk_manipulate_sa_get(a_uint32_t dev_id, fal_mac_addr_t * addr); + +sw_error_t +fal_trunk_failover_enable(a_uint32_t dev_id, a_bool_t failover); + +sw_error_t +fal_trunk_failover_status_get(a_uint32_t dev_id, a_bool_t * failover); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_TRUNK_H_ */ + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/fal/fal_type.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_type.h new file mode 100755 index 000000000..0f680a47b --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_type.h @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2012, 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_type FAL_TYPE + * @{ + */ +#ifndef _FAL_TYPE_H_ +#define _FAL_TYPE_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + typedef a_uint32_t fal_port_t; + +/*fal_port_t definition, + bit31-bit24: port_type, 0-physical port, 1-trunk port, 2-virtual port + bit23-bit0: physical port id or trunk id or virtual port id*/ +#define FAL_PORT_TYPE_PPORT 0 +#define FAL_PORT_TYPE_TRUNK 1 +#define FAL_PORT_TYPE_VPORT 2 + +#define FAL_PORT_ID_TYPE(port_id) (((port_id)>>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/src/include/fal/fal_uk_if.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_uk_if.h new file mode 100755 index 000000000..faad2f2b1 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_uk_if.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2012,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/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/src/include/fal/fal_vlan.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_vlan.h new file mode 100755 index 000000000..6386e05e3 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_vlan.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2012,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_vlan FAL_VLAN + * @{ + */ +#ifndef _FAL_VLAN_H +#define _FAL_VLAN_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "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/src/include/fal/fal_vsi.h b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_vsi.h new file mode 100755 index 000000000..2e4a42e59 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/fal/fal_vsi.h @@ -0,0 +1,137 @@ +/* + * 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. + */ + + +/** + * @defgroup fal_stp FAL_VSI + * @{ + */ +#ifndef _FAL_VSI_H_ +#define _FAL_VSI_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "sw.h" +#include "fal/fal_type.h" + +#define FAL_VSI_INVALID 0xffff +#define FAL_VLAN_INVALID 0xffff +#define FAL_VSI_MAX 31 +#define FAL_VLAN_MAX 4095 + +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 all packets*/ + 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); + +#ifndef IN_VSI_MINI +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_vsi_stamove_get(a_uint32_t dev_id, a_uint32_t vsi_id, fal_vsi_stamove_t *stamove); + +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_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); +#endif + +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_stamove_set(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); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_VSI_H_ */ + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_api.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_api.h new file mode 100755 index 000000000..543cab60d --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_api.h @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ATHENA_API_H_ +#define _ATHENA_API_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifdef IN_PORTCONTROL +#define PORTCONTROL_API \ + SW_API_DEF(SW_API_PT_DUPLEX_GET, athena_port_duplex_get), \ + SW_API_DEF(SW_API_PT_DUPLEX_SET, athena_port_duplex_set), \ + SW_API_DEF(SW_API_PT_SPEED_GET, athena_port_speed_get), \ + SW_API_DEF(SW_API_PT_SPEED_SET, athena_port_speed_set), \ + SW_API_DEF(SW_API_PT_AN_GET, athena_port_autoneg_status_get), \ + SW_API_DEF(SW_API_PT_AN_ENABLE, athena_port_autoneg_enable), \ + SW_API_DEF(SW_API_PT_AN_RESTART, athena_port_autoneg_restart), \ + SW_API_DEF(SW_API_PT_AN_ADV_GET, athena_port_autoneg_adv_get), \ + SW_API_DEF(SW_API_PT_AN_ADV_SET, athena_port_autoneg_adv_set), \ + SW_API_DEF(SW_API_PT_IGMPS_MODE_SET, athena_port_igmps_status_set), \ + SW_API_DEF(SW_API_PT_IGMPS_MODE_GET, athena_port_igmps_status_get), \ + SW_API_DEF(SW_API_PT_POWERSAVE_SET, athena_port_powersave_set), \ + SW_API_DEF(SW_API_PT_POWERSAVE_GET, athena_port_powersave_get), \ + SW_API_DEF(SW_API_PT_HIBERNATE_SET, athena_port_hibernate_set), \ + SW_API_DEF(SW_API_PT_HIBERNATE_GET, athena_port_hibernate_get), + + +#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) \ + SW_API_DESC(SW_API_PT_IGMPS_MODE_SET) \ + SW_API_DESC(SW_API_PT_IGMPS_MODE_GET) \ + SW_API_DESC(SW_API_PT_POWERSAVE_SET) \ + SW_API_DESC(SW_API_PT_POWERSAVE_GET) \ + SW_API_DESC(SW_API_PT_HIBERNATE_SET) \ + SW_API_DESC(SW_API_PT_HIBERNATE_GET) +#else +#define PORTCONTROL_API +#define PORTCONTROL_API_PARAM +#endif + +#ifdef IN_VLAN +#define VLAN_API \ + SW_API_DEF(SW_API_VLAN_ADD, athena_vlan_create), \ + SW_API_DEF(SW_API_VLAN_DEL, athena_vlan_delete), \ + SW_API_DEF(SW_API_VLAN_MEM_UPDATE, athena_vlan_member_update), \ + SW_API_DEF(SW_API_VLAN_FIND, athena_vlan_find), \ + SW_API_DEF(SW_API_VLAN_NEXT, athena_vlan_next), \ + SW_API_DEF(SW_API_VLAN_APPEND, athena_vlan_entry_append), + +#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) +#else +#define VLAN_API +#define VLAN_API_PARAM +#endif + +#ifdef IN_PORTVLAN +#define PORTVLAN_API \ + SW_API_DEF(SW_API_PT_ING_MODE_GET, athena_port_1qmode_get), \ + SW_API_DEF(SW_API_PT_ING_MODE_SET, athena_port_1qmode_set), \ + SW_API_DEF(SW_API_PT_EG_MODE_GET, athena_port_egvlanmode_get), \ + SW_API_DEF(SW_API_PT_EG_MODE_SET, athena_port_egvlanmode_set), \ + SW_API_DEF(SW_API_PT_VLAN_MEM_ADD, athena_portvlan_member_add), \ + SW_API_DEF(SW_API_PT_VLAN_MEM_DEL, athena_portvlan_member_del), \ + SW_API_DEF(SW_API_PT_VLAN_MEM_UPDATE, athena_portvlan_member_update), \ + SW_API_DEF(SW_API_PT_VLAN_MEM_GET, athena_portvlan_member_get), \ + +#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) +#else +#define PORTVLAN_API +#define PORTVLAN_API_PARAM +#endif + +#ifdef IN_FDB +#define FDB_API \ + SW_API_DEF(SW_API_FDB_ADD, athena_fdb_add), \ + SW_API_DEF(SW_API_FDB_DELALL, athena_fdb_del_all), \ + SW_API_DEF(SW_API_FDB_DELPORT,athena_fdb_del_by_port), \ + SW_API_DEF(SW_API_FDB_DELMAC, athena_fdb_del_by_mac), \ + SW_API_DEF(SW_API_FDB_FIRST, athena_fdb_first), \ + SW_API_DEF(SW_API_FDB_NEXT, athena_fdb_next), + +#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) +#else +#define FDB_API +#define FDB_API_PARAM +#endif + +#ifdef IN_MIB +#define MIB_API \ + SW_API_DEF(SW_API_PT_MIB_GET, athena_get_mib_info), + +#define MIB_API_PARAM \ + SW_API_DESC(SW_API_PT_MIB_GET) +#else +#define MIB_API +#define MIB_API_PARAM +#endif + +#define REG_API \ + SW_API_DEF(SW_API_PHY_GET, athena_phy_get), \ + SW_API_DEF(SW_API_PHY_SET, athena_phy_set), \ + SW_API_DEF(SW_API_REG_GET, athena_reg_get), \ + SW_API_DEF(SW_API_REG_SET, athena_reg_set), \ + SW_API_DEF(SW_API_REG_FIELD_GET, athena_reg_field_get), \ + SW_API_DEF(SW_API_REG_FIELD_SET, athena_reg_field_set), + +#define REG_API_PARAM \ + SW_API_DESC(SW_API_PHY_GET) \ + SW_API_DESC(SW_API_PHY_SET) \ + SW_API_DESC(SW_API_REG_GET) \ + SW_API_DESC(SW_API_REG_SET) \ + SW_API_DESC(SW_API_REG_FIELD_GET) \ + SW_API_DESC(SW_API_REG_FIELD_SET) + +#define SSDK_API \ + SW_API_DEF(SW_API_SWITCH_RESET, athena_reset), \ + SW_API_DEF(SW_API_SSDK_CFG, hsl_ssdk_cfg), \ + MIB_API \ + PORTCONTROL_API \ + PORTVLAN_API \ + VLAN_API \ + FDB_API \ + REG_API \ + SW_API_DEF(SW_API_MAX, NULL) + +#define SSDK_PARAM \ + 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"), \ + MIB_API_PARAM \ + PORTCONTROL_API_PARAM \ + PORTVLAN_API_PARAM \ + VLAN_API_PARAM \ + FDB_API_PARAM \ + REG_API_PARAM \ + SW_PARAM_DEF(SW_API_MAX, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), + +#if (defined(USER_MODE) && defined(KERNEL_MODULE)) +#undef SSDK_API +#undef SSDK_PARAM + +#define SSDK_API \ + REG_API \ + SW_API_DEF(SW_API_MAX, NULL), + +#define SSDK_PARAM \ + REG_API_PARAM \ + SW_PARAM_DEF(SW_API_MAX, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _ATHENA_API_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_fdb.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_fdb.h new file mode 100755 index 000000000..7a4cb85d1 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_fdb.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ATHENA_FDB_H +#define _ATHENA_FDB_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_fdb.h" + + sw_error_t athena_fdb_init(a_uint32_t dev_id); + +#ifdef IN_FDB +#define ATHENA_FDB_INIT(rv, dev_id) \ + { \ + rv = athena_fdb_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ATHENA_FDB_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + athena_fdb_add(a_uint32_t dev_id, const fal_fdb_entry_t * entry); + + + + HSL_LOCAL sw_error_t + athena_fdb_del_all(a_uint32_t dev_id, a_uint32_t flag); + + + + HSL_LOCAL sw_error_t + athena_fdb_del_by_port(a_uint32_t dev_id, a_uint32_t port_id, + a_uint32_t flag); + + + + HSL_LOCAL sw_error_t + athena_fdb_del_by_mac(a_uint32_t dev_id, const fal_fdb_entry_t * addr); + + + + HSL_LOCAL sw_error_t + athena_fdb_first(a_uint32_t dev_id, fal_fdb_entry_t * entry); + + + + HSL_LOCAL sw_error_t + athena_fdb_next(a_uint32_t dev_id, fal_fdb_entry_t * entry); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ATHENA_FDB_H */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_init.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_init.h new file mode 100755 index 000000000..2720961ce --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_init.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ATHENA_INIT_H_ +#define _ATHENA_INIT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "init/ssdk_init.h" + + sw_error_t + athena_init(a_uint32_t dev_id, ssdk_init_cfg * cfg); + + sw_error_t + athena_cleanup(a_uint32_t dev_id); + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + athena_reset(a_uint32_t dev_id); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _ATHENA_INIT_H_ */ + + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_mib.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_mib.h new file mode 100755 index 000000000..0e1bc1b22 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_mib.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ATHENA_MIB_H +#define _ATHENA_MIB_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_mib.h" + + sw_error_t + athena_mib_init(a_uint32_t dev_id); + +#ifdef IN_MIB +#define ATHENA_MIB_INIT(rv, dev_id) \ + { \ + rv = athena_mib_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ATHENA_MIB_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + athena_get_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info ); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _ATHENA_MIB_H */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_port_ctrl.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_port_ctrl.h new file mode 100755 index 000000000..73f677097 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_port_ctrl.h @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ATHENA_PORT_CTRL_H +#define _ATHENA_PORT_CTRL_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_port_ctrl.h" + + sw_error_t athena_port_ctrl_init(a_uint32_t dev_id); + +#ifdef IN_PORTCONTROL +#define ATHENA_PORT_CTRL_INIT(rv, dev_id) \ + { \ + rv = athena_port_ctrl_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ATHENA_PORT_CTRL_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + athena_port_duplex_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t duplex); + + + + HSL_LOCAL sw_error_t + athena_port_duplex_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t * pduplex); + + + + HSL_LOCAL sw_error_t + athena_port_speed_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t speed); + + + + HSL_LOCAL sw_error_t + athena_port_speed_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t * pspeed); + + + + HSL_LOCAL sw_error_t + athena_port_autoneg_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status); + + + + HSL_LOCAL sw_error_t + athena_port_autoneg_enable(a_uint32_t dev_id, fal_port_t port_id); + + + + HSL_LOCAL sw_error_t + athena_port_autoneg_restart(a_uint32_t dev_id, fal_port_t port_id); + + + + HSL_LOCAL sw_error_t + athena_port_autoneg_adv_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t autoadv); + + + + HSL_LOCAL sw_error_t + athena_port_autoneg_adv_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * autoadv); + + + + HSL_LOCAL sw_error_t + athena_port_igmps_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + + HSL_LOCAL sw_error_t + athena_port_igmps_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + athena_port_powersave_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + + HSL_LOCAL sw_error_t + athena_port_powersave_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable); + + + + HSL_LOCAL sw_error_t + athena_port_hibernate_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + + HSL_LOCAL sw_error_t + athena_port_hibernate_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable); + + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ATHENA_PORT_CTRL_H */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_portvlan.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_portvlan.h new file mode 100755 index 000000000..00385d970 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_portvlan.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ATHENA_PORTVLAN_H +#define _ATHENA_PORTVLAN_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_portvlan.h" + + sw_error_t + athena_portvlan_init(a_uint32_t dev_id); + +#ifdef IN_PORTVLAN +#define ATHENA_PORTVLAN_INIT(rv, dev_id) \ + { \ + rv = athena_portvlan_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ATHENA_PORTVLAN_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + athena_port_1qmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t port_1qmode); + + + + HSL_LOCAL sw_error_t + athena_port_1qmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t * pport_1qmode); + + + + HSL_LOCAL sw_error_t + athena_port_egvlanmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t port_egvlanmode); + + + + HSL_LOCAL sw_error_t + athena_port_egvlanmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t * pport_egvlanmode); + + + + HSL_LOCAL sw_error_t + athena_portvlan_member_add(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id); + + + + HSL_LOCAL sw_error_t + athena_portvlan_member_del(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id); + + + + HSL_LOCAL sw_error_t + athena_portvlan_member_update(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t mem_port_map); + + + + HSL_LOCAL sw_error_t + athena_portvlan_member_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t *mem_port_map); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _ATHENA_PORTVLAN_H */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_reg.h new file mode 100755 index 000000000..3553ce7b6 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_reg.h @@ -0,0 +1,2157 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ATHENA_REG_H +#define _ATHENA_REG_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define MAX_ENTRY_LEN 128 + +#define HSL_RW 1 +#define HSL_RO 0 + + /** + * Athena Mask Control Register + */ +#define MASK_CTL "mask" +#define MASK_CTL_ID 0 +#define MASK_CTL_OFFSET 0x0000 +#define MASK_CTL_E_LENGTH 4 +#define MASK_CTL_E_OFFSET 0 +#define MASK_CTL_NR_E 0 + +#define SOFT_RST "mask_rst" +#define MASK_CTL_SOFT_RST_BOFFSET 31 +#define MASK_CTL_SOFT_RST_BLEN 1 +#define MASK_CTL_SOFT_RST_FLAG HSL_RW + +#define MII_CLK_SEL "mask_clks" +#define MASK_CTL_MII_CLK_SEL_BOFFSET 24 +#define MASK_CTL_MII_CLK_SEL_BLEN 1 +#define MASK_CTL_MII_CLK_SEL_FLAG HSL_RW + +#define RMII_PHY_RX_SEL "mask_prxs" +#define MASK_CTL_RMII_PHY_RX_SEL_BOFFSET 23 +#define MASK_CTL_RMII_PHY_RX_SEL_BLEN 1 +#define MASK_CTL_RMII_PHY_RX_SEL_FLAG HSL_RW + +#define RMII_PHY_TX_SEL "mask_ptxs" +#define MASK_CTL_RMII_PHY_TX_SEL_BOFFSET 22 +#define MASK_CTL_RMII_PHY_TX_SEL_BLEN 1 +#define MASK_CTL_RMII_PHY_TX_SEL_FLAG HSL_RW + +#define RMII_MAC_RX_SEL "mask_mrxs" +#define MASK_CTL_RMII_MAC_RX_SEL_BOFFSET 21 +#define MASK_CTL_RMII_MAC_RX_SEL_BLEN 1 +#define MASK_CTL_RMII_MAC_RX_SEL_FLAG HSL_RW + +#define RMII_MAC_TX_SEL "mask_mtxs" +#define MASK_CTL_RMII_MAC_TX_SEL_BOFFSET 20 +#define MASK_CTL_RMII_MAC_TX_SEL_BLEN 1 +#define MASK_CTL_RMII_MAC_TX_SEL_FLAG HSL_RW + +#define LOAD_EEPROM "mask_ldro" +#define MASK_CTL_LOAD_EEPROM_BOFFSET 16 +#define MASK_CTL_LOAD_EEPROM_BLEN 1 +#define MASK_CTL_LOAD_EEPROM_FLAG HSL_RW + +#define DEVICE_ID "mask_did" +#define MASK_CTL_DEVICE_ID_BOFFSET 8 +#define MASK_CTL_DEVICE_ID_BLEN 8 +#define MASK_CTL_DEVICE_ID_FLAG HSL_RO + +#define REV_ID "mask_rid" +#define MASK_CTL_REV_ID_BOFFSET 0 +#define MASK_CTL_REV_ID_BLEN 8 +#define MASK_CTL_REV_ID_FLAG HSL_RO + + /** + * Global Interrupt Register + */ +#define GLOBAL_INT "gint" +#define GLOBAL_INT_ID 1 +#define GLOBAL_INT_OFFSET 0x0010 +#define GLOBAL_INT_E_LENGTH 4 +#define GLOBAL_INT_E_OFFSET 0 +#define GLOBAL_INT_NR_E 0 + +#define GLB_QM_ERR_CNT "gint_qmen" +#define GLOBAL_INT_GLB_QM_ERR_CNT_BOFFSET 24 +#define GLOBAL_INT_GLB_QM_ERR_CNT_BLEN 8 +#define GLOBAL_INT_GLB_QM_ERR_CNT_FLAG HSL_RO + +#define GLB_LOOKUP_ERR "gint_glblper" +#define GLOBAL_INT_GLB_LOOKUP_ERR_BOFFSET 17 +#define GLOBAL_INT_GLB_LOOKUP_ERR_BLEN 1 +#define GLOBAL_INT_GLB_LOOKUP_ERR_FLAG HSL_RW + +#define GLB_QM_ERR "gint_glbqmer" +#define GLOBAL_INT_GLB_QM_ERR_BOFFSET 16 +#define GLOBAL_INT_GLB_QM_ERR_BLEN 1 +#define GLOBAL_INT_GLB_QM_ERR_FLAG HSL_RW + +#define GLB_HW_INI_DONE "gint_hwid" +#define GLOBAL_INT_GLB_HW_INI_DONE_BOFFSET 14 +#define GLOBAL_INT_GLB_HW_INI_DONE_BLEN 1 +#define GLOBAL_INT_GLB_HW_INI_DONE_FLAG HSL_RW + +#define GLB_MIB_INI "gint_mibi" +#define GLOBAL_INT_GLB_MIB_INI_BOFFSET 13 +#define GLOBAL_INT_GLB_MIB_INI_BLEN 1 +#define GLOBAL_INT_GLB_MIB_INI_FLAG HSL_RW + +#define GLB_MIB_DONE "gint_mibd" +#define GLOBAL_INT_GLB_MIB_DONE_BOFFSET 12 +#define GLOBAL_INT_GLB_MIB_DONE_BLEN 1 +#define GLOBAL_INT_GLB_MIB_DONE_FLAG HSL_RW + +#define GLB_BIST_DONE "gint_bisd" +#define GLOBAL_INT_GLB_BIST_DONE_BOFFSET 11 +#define GLOBAL_INT_GLB_BIST_DONE_BLEN 1 +#define GLOBAL_INT_GLB_BIST_DONE_FLAG HSL_RW + +#define GLB_VT_MISS_VIO "gint_vtms" +#define GLOBAL_INT_GLB_VT_MISS_VIO_BOFFSET 10 +#define GLOBAL_INT_GLB_VT_MISS_VIO_BLEN 1 +#define GLOBAL_INT_GLB_VT_MISS_VIO_FLAG HSL_RW + +#define GLB_VT_MEM_VIO "gint_vtme" +#define GLOBAL_INT_GLB_VT_MEM_VIO_BOFFSET 9 +#define GLOBAL_INT_GLB_VT_MEM_VIO_BLEN 1 +#define GLOBAL_INT_GLB_VT_MEM_VIO_FLAG HSL_RW + +#define GLB_VT_DONE "gint_vtd" +#define GLOBAL_INT_GLB_VT_DONE_BOFFSET 8 +#define GLOBAL_INT_GLB_VT_DONE_BLEN 1 +#define GLOBAL_INT_GLB_VT_DONE_FLAG HSL_RW + +#define GLB_QM_INI "gint_qmin" +#define GLOBAL_INT_GLB_QM_INI_BOFFSET 7 +#define GLOBAL_INT_GLB_QM_INI_BLEN 1 +#define GLOBAL_INT_GLB_QM_INI_FLAG HSL_RW + +#define GLB_AT_INI "gint_atin" +#define GLOBAL_INT_GLB_AT_INI_BOFFSET 6 +#define GLOBAL_INT_GLB_AT_INI_BLEN 1 +#define GLOBAL_INT_GLB_AT_INI_FLAG HSL_RW + +#define GLB_ARL_FULL "gint_arlf" +#define GLOBAL_INT_GLB_ARL_FULL_BOFFSET 5 +#define GLOBAL_INT_GLB_ARL_FULL_BLEN 1 +#define GLOBAL_INT_GLB_ARL_FULL_FLAG HSL_RW + +#define GLB_ARL_DONE "gint_arld" +#define GLOBAL_INT_GLB_ARL_DONE_BOFFSET 4 +#define GLOBAL_INT_GLB_ARL_DONE_BLEN 1 +#define GLOBAL_INT_GLB_ARL_DONE_FLAG HSL_RW + +#define GLB_MDIO_DONE "gint_mdid" +#define GLOBAL_INT_GLB_MDIO_DONE_BOFFSET 3 +#define GLOBAL_INT_GLB_MDIO_DONE_BLEN 1 +#define GLOBAL_INT_GLB_MDIO_DONE_FLAG HSL_RW + +#define GLB_PHY_INT "gint_phyi" +#define GLOBAL_INT_GLB_PHY_INT_BOFFSET 2 +#define GLOBAL_INT_GLB_PHY_INT_BLEN 1 +#define GLOBAL_INT_GLB_PHY_INT_FLAG HSL_RW + +#define GLB_EEPROM_ERR "gint_epei" +#define GLOBAL_INT_GLB_EEPROM_ERR_BOFFSET 1 +#define GLOBAL_INT_GLB_EEPROM_ERR_BLEN 1 +#define GLOBAL_INT_GLB_EEPROM_ERR_FLAG HSL_RW + +#define GLB_EEPROM_INT "gint_epi" +#define GLOBAL_INT_GLB_EEPROM_INT_BOFFSET 0 +#define GLOBAL_INT_GLB_EEPROM_INT_BLEN 1 +#define GLOBAL_INT_GLB_EEPROM_INT_FLAG HSL_RW + + /** + * Global Interrupt Mask Register + */ +#define GLOBAL_INT_MASK "gintm" +#define GLOBAL_INT_MASK_ID 2 +#define GLOBAL_INT_MASK_OFFSET 0x0014 +#define GLOBAL_INT_MASK_E_LENGTH 4 +#define GLOBAL_INT_MASK_E_OFFSET 0 +#define GLOBAL_INT_MASK_NR_E 0 + +#define GLBM_LOOKUP_ERR "gintm_lpe" +#define GLOBAL_INT_MASK_GLBM_LOOKUP_ERR_BOFFSET 17 +#define GLOBAL_INT_MASK_GLBM_LOOKUP_ERR_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_LOOKUP_ERR_FLAG HSL_RW + +#define GLBM_QM_ERR "gintm_qme" +#define GLOBAL_INT_MASK_GLBM_QM_ERR_BOFFSET 16 +#define GLOBAL_INT_MASK_GLBM_QM_ERR_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_QM_ERR_FLAG HSL_RW + +#define GLBM_HW_INI_DONE "gintm_hwid" +#define GLOBAL_INT_MASK_GLBM_HW_INI_DONE_BOFFSET 14 +#define GLOBAL_INT_MASK_GLBM_HW_INI_DONE_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_HW_INI_DONE_FLAG HSL_RW + +#define GLBM_MIB_INI "gintm_mibi" +#define GLOBAL_INT_MASK_GLBM_MIB_INI_BOFFSET 13 +#define GLOBAL_INT_MASK_GLBM_MIB_INI_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_MIB_INI_FLAG HSL_RW + +#define GLBM_MIB_DONE "gintm_mibd" +#define GLOBAL_INT_MASK_GLBM_MIB_DONE_BOFFSET 12 +#define GLOBAL_INT_MASK_GLBM_MIB_DONE_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_MIB_DONE_FLAG HSL_RW + +#define GLBM_BIST_DONE "gintm_bisd" +#define GLOBAL_INT_MASK_GLBM_BIST_DONE_BOFFSET 11 +#define GLOBAL_INT_MASK_GLBM_BIST_DONE_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_BIST_DONE_FLAG HSL_RW + +#define GLBM_VT_MISS_VIO "gintm_vtms" +#define GLOBAL_INT_MASK_GLBM_VT_MISS_VIO_BOFFSET 10 +#define GLOBAL_INT_MASK_GLBM_VT_MISS_VIO_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_VT_MISS_VIO_FLAG HSL_RW + +#define GLBM_VT_MEM_VIO "gintm_vtme" +#define GLOBAL_INT_MASK_GLBM_VT_MEM_VIO_BOFFSET 9 +#define GLOBAL_INT_MASK_GLBM_VT_MEM_VIO_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_VT_MEM_VIO_FLAG HSL_RW + +#define GLBM_VT_DONE "gintm_vtd" +#define GLOBAL_INT_MASK_GLBM_VT_DONE_BOFFSET 8 +#define GLOBAL_INT_MASK_GLBM_VT_DONE_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_VT_DONE_FLAG HSL_RW + +#define GLBM_QM_INI "gintm_qmin" +#define GLOBAL_INT_MASK_GLBM_QM_INI_BOFFSET 7 +#define GLOBAL_INT_MASK_GLBM_QM_INI_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_QM_INI_FLAG HSL_RW + +#define GLBM_AT_INI "gintm_atin" +#define GLOBAL_INT_MASK_GLBM_AT_INI_BOFFSET 6 +#define GLOBAL_INT_MASK_GLBM_AT_INI_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_AT_INI_FLAG HSL_RW + +#define GLBM_ARL_FULL "gintm_arlf" +#define GLOBAL_INT_MASK_GLBM_ARL_FULL_BOFFSET 5 +#define GLOBAL_INT_MASK_GLBM_ARL_FULL_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_ARL_FULL_FLAG HSL_RW + +#define GLBM_ARL_DONE "gintm_arld" +#define GLOBAL_INT_MASK_GLBM_ARL_DONE_BOFFSET 4 +#define GLOBAL_INT_MASK_GLBM_ARL_DONE_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_ARL_DONE_FLAG HSL_RW + +#define GLBM_MDIO_DONE "gintm_mdid" +#define GLOBAL_INT_MASK_GLBM_MDIO_DONE_BOFFSET 3 +#define GLOBAL_INT_MASK_GLBM_MDIO_DONE_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_MDIO_DONE_FLAG HSL_RW + +#define GLBM_PHY_INT "gintm_phy" +#define GLOBAL_INT_MASK_GLBM_PHY_INT_BOFFSET 2 +#define GLOBAL_INT_MASK_GLBM_PHY_INT_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_PHY_INT_FLAG HSL_RW + +#define GLBM_EEPROM_ERR "gintm_epe" +#define GLOBAL_INT_MASK_GLBM_EEPROM_ERR_BOFFSET 1 +#define GLOBAL_INT_MASK_GLBM_EEPROM_ERR_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_EEPROM_ERR_FLAG HSL_RW + +#define GLBM_EEPROM_INT "gintm_ep" +#define GLOBAL_INT_MASK_GLBM_EEPROM_INT_BOFFSET 0 +#define GLOBAL_INT_MASK_GLBM_EEPROM_INT_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_EEPROM_INT_FLAG HSL_RW + + + /** + * Global MAC Address Register + */ +//high +#define GLOBAL_MAC_ADDR0 "gmac0" +#define GLOBAL_MAC_ADDR0_ID 3 +#define GLOBAL_MAC_ADDR0_OFFSET 0x0020 +#define GLOBAL_MAC_ADDR0_E_LENGTH 4 +#define GLOBAL_MAC_ADDR0_E_OFFSET 0 +#define GLOBAL_MAC_ADDR0_NR_E 0 + +#define GLB_BYTE4 "gmac_b4" +#define GLOBAL_MAC_ADDR0_GLB_BYTE4_BOFFSET 8 +#define GLOBAL_MAC_ADDR0_GLB_BYTE4_BLEN 8 +#define GLOBAL_MAC_ADDR0_GLB_BYTE4_FLAG HSL_RW + +#define GLB_BYTE5 "gmac_b5" +#define GLOBAL_MAC_ADDR0_GLB_BYTE5_BOFFSET 0 +#define GLOBAL_MAC_ADDR0_GLB_BYTE5_BLEN 8 +#define GLOBAL_MAC_ADDR0_GLB_BYTE5_FLAG HSL_RW + + +//low +#define GLOBAL_MAC_ADDR1 "gmac1" +#define GLOBAL_MAC_ADDR1_ID 4 +#define GLOBAL_MAC_ADDR1_OFFSET 0x0024 +#define GLOBAL_MAC_ADDR1_E_LENGTH 4 +#define GLOBAL_MAC_ADDR1_E_OFFSET 0 +#define GLOBAL_MAC_ADDR1_NR_E 0 + +#define GLB_BYTE0 "gmac_b0" +#define GLOBAL_MAC_ADDR1_GLB_BYTE0_BOFFSET 24 +#define GLOBAL_MAC_ADDR1_GLB_BYTE0_BLEN 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE0_FLAG HSL_RW + +#define GLB_BYTE1 "gmac_b1" +#define GLOBAL_MAC_ADDR1_GLB_BYTE1_BOFFSET 16 +#define GLOBAL_MAC_ADDR1_GLB_BYTE1_BLEN 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE1_FLAG HSL_RW + +#define GLB_BYTE2 "gmac_b2" +#define GLOBAL_MAC_ADDR1_GLB_BYTE2_BOFFSET 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE2_BLEN 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE2_FLAG HSL_RW + +#define GLB_BYTE3 "gmac_b3" +#define GLOBAL_MAC_ADDR1_GLB_BYTE3_BOFFSET 0 +#define GLOBAL_MAC_ADDR1_GLB_BYTE3_BLEN 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE3_FLAG HSL_RW + + /** + * Global Control Register + */ +#define GLOBAL_CTL "gctl" +#define GLOBAL_CTL_ID 5 +#define GLOBAL_CTL_OFFSET 0x0030 +#define GLOBAL_CTL_E_LENGTH 4 +#define GLOBAL_CTL_E_OFFSET 0 +#define GLOBAL_CTL_NR_E 0 + +#define WEIGHT_PRIORITY "gctl_wpri" +#define GLOBAL_CTL_WEIGHT_PRIORITY_BOFFSET 31 +#define GLOBAL_CTL_WEIGHT_PRIORITY_BLEN 1 +#define GLOBAL_CTL_WEIGHT_PRIORITY_FLAG HSL_RW + +#define RATE_DROP_EN "gctl_rden" +#define GLOBAL_CTL_RATE_DROP_EN_BOFFSET 30 +#define GLOBAL_CTL_RATE_DROP_EN_BLEN 1 +#define GLOBAL_CTL_RATE_DROP_EN_FLAG HSL_RW + +#define QM_PRI_MODE "gctl_qmpm" +#define GLOBAL_CTL_QM_PRI_MODE_BOFFSET 29 +#define GLOBAL_CTL_QM_PRI_MODE_BLEN 1 +#define GLOBAL_CTL_QM_PRI_MODE_FLAG HSL_RW + +#define MIX_PRIORITY "gctl_mpri" +#define GLOBAL_CTL_MIX_PRIORITY_BOFFSET 28 +#define GLOBAL_CTL_MIX_PRIORITY_BLEN 1 +#define GLOBAL_CTL_MIX_PRIORITY_FLAG HSL_RW + +#define RATE_CRE_LIMIT "gctl_rcrl" +#define GLOBAL_CTL_RATE_CRE_LIMIT_BOFFSET 26 +#define GLOBAL_CTL_RATE_CRE_LIMIT_BLEN 2 +#define GLOBAL_CTL_RATE_CRE_LIMIT_FLAG HSL_RW + +#define RATE_TIME_SLOT "gctl_rtms" +#define GLOBAL_CTL_RATE_TIME_SLOT_BOFFSET 24 +#define GLOBAL_CTL_RATE_TIME_SLOT_BLEN 2 +#define GLOBAL_CTL_RATE_TIME_SLOT_FLAG HSL_RW + +#define RELOAD_TIMER "gctl_rdtm" +#define GLOBAL_CTL_RELOAD_TIMER_BOFFSET 20 +#define GLOBAL_CTL_RELOAD_TIMER_BLEN 4 +#define GLOBAL_CTL_RELOAD_TIMER_FLAG HSL_RW + +#define QM_CNT_LOCK "gctl_qmcl" +#define GLOBAL_CTL_QM_CNT_LOCK_BOFFSET 19 +#define GLOBAL_CTL_QM_CNT_LOCK_BLEN 1 +#define GLOBAL_CTL_QM_CNT_LOCK_FLAG HSL_RO + +#define BROAD_DROP_EN "gctl_bden" +#define GLOBAL_CTL_BROAD_DROP_EN_BOFFSET 18 +#define GLOBAL_CTL_BROAD_DROP_EN_BLEN 1 +#define GLOBAL_CTL_BROAD_DROP_EN_FLAG HSL_RW + +#define BROAD_STORM_CTRL "gctl_bsct" +#define GLOBAL_CTL_BROAD_STORM_CTRL_BOFFSET 16 +#define GLOBAL_CTL_BROAD_STORM_CTRL_BLEN 2 +#define GLOBAL_CTL_BROAD_STORM_CTRL_FLAG HSL_RW + +#define BROAD_STORM_EN "gctl_bsen" +#define GLOBAL_CTL_BROAD_STORM_EN_BOFFSET 11 +#define GLOBAL_CTL_BROAD_STORM_EN_BLEN 1 +#define GLOBAL_CTL_BROAD_STORM_EN_FLAG HSL_RW + +#define MAX_FRAME_SIZE "gctl_mfsz" +#define GLOBAL_CTL_MAX_FRAME_SIZE_BOFFSET 0 +#define GLOBAL_CTL_MAX_FRAME_SIZE_BLEN 11 +#define GLOBAL_CTL_MAX_FRAME_SIZE_FLAG HSL_RW + + /** + * Flow Control Register + */ +#define FLOW_CTL "fctl" +#define FLOW_CTL_ID 6 +#define FLOW_CTL_OFFSET 0x0034 +#define FLOW_CTL_E_LENGTH 4 +#define FLOW_CTL_E_OFFSET 0 +#define FLOW_CTL_NR_E 0 + +#define TEST_PAUSE "fctl_tps" +#define FLOW_CTL_TEST_PAUSE_BOFFSET 31 +#define FLOW_CTL_TEST_PAUSE_BLEN 1 +#define FLOW_CTL_TEST_PAUSE_FLAG HSL_RW + +#define PORT_PAUSE_OFF_THRES "fctl_pofft" +#define FLOW_CTL_PORT_PAUSE_OFF_THRES_BOFFSET 24 +#define FLOW_CTL_PORT_PAUSE_OFF_THRES_BLEN 7 +#define FLOW_CTL_PORT_PAUSE_OFF_THRES_FLAG HSL_RW + +#define PORT_PAUSE_ON_THRES "fctl_pont" +#define FLOW_CTL_PORT_PAUSE_ON_THRES_BOFFSET 16 +#define FLOW_CTL_PORT_PAUSE_ON_THRES_BLEN 7 +#define FLOW_CTL_PORT_PAUSE_ON_THRES_FLAG HSL_RW + +#define GOL_PAUSE_OFF_THRES "fctl_gofft" +#define FLOW_CTL_GOL_PAUSE_OFF_THRES_BOFFSET 8 +#define FLOW_CTL_GOL_PAUSE_OFF_THRES_BLEN 8 +#define FLOW_CTL_GOL_PAUSE_OFF_THRES_FLAG HSL_RW + +#define GOL_PAUSE_ON_THRES "fctl_gont" +#define FLOW_CTL_GOL_PAUSE_ON_THRES_BOFFSET 0 +#define FLOW_CTL_GOL_PAUSE_ON_THRES_BLEN 8 +#define FLOW_CTL_GOL_PAUSE_ON_THRES_FLAG HSL_RW + + /** + * QM Control Register + */ +#define QM_CTL "qmct" +#define QM_CTL_ID 7 +#define QM_CTL_OFFSET 0x0038 +#define QM_CTL_E_LENGTH 4 +#define QM_CTL_E_OFFSET 0 +#define QM_CTL_NR_E 0 + +#define QM_ERR_RST_EN "qmct_qeren" +#define QM_CTL_QM_ERR_RST_EN_BOFFSET 31 +#define QM_CTL_QM_ERR_RST_EN_BLEN 1 +#define QM_CTL_QM_ERR_RST_EN_FLAG HSL_RW + +#define LOOKUP_ERR_RST_EN "qmct_lpesen" +#define QM_CTL_LOOKUP_ERR_RST_EN_BOFFSET 30 +#define QM_CTL_LOOKUP_ERR_RST_EN_BLEN 1 +#define QM_CTL_LOOKUP_ERR_RST_EN_FLAG HSL_RW + +#define FLOOD_TO_CPU_EN "qmct_fdcpuen" +#define QM_CTL_FLOOD_TO_CPU_EN_BOFFSET 10 +#define QM_CTL_FLOOD_TO_CPU_EN_BLEN 1 +#define QM_CTL_FLOOD_TO_CPU_EN_FLAG HSL_RW + +#define QM_FUNC_TEST "qmct_qmft" +#define QM_CTL_QM_FUNC_TEST_BOFFSET 9 +#define QM_CTL_QM_FUNC_TEST_BLEN 1 +#define QM_CTL_QM_FUNC_TEST_FLAG HSL_RW + +#define MS_FC_EN "qmct_msfe" +#define QM_CTL_MS_FC_EN_BOFFSET 8 +#define QM_CTL_MS_FC_EN_BLEN 1 +#define QM_CTL_MS_FC_EN_FLAG HSL_RW + +#define FLOW_DROP_EN "qmct_fden" +#define QM_CTL_FLOW_DROP_EN_BOFFSET 7 +#define QM_CTL_FLOW_DROP_EN_BLEN 1 +#define QM_CTL_FLOW_DROP_EN_FLAG HSL_RW + +#define FLOW_DROP_CNT "qmct_fdcn" +#define QM_CTL_FLOW_DROP_CNT_BOFFSET 0 +#define QM_CTL_FLOW_DROP_CNT_BLEN 5 +#define QM_CTL_FLOW_DROP_CNT_FLAG HSL_RW + + /** + * QM Error Register + */ +#define QM_ERR "qmer" +#define QM_ERR_ID 8 +#define QM_ERR_OFFSET 0x003C +#define QM_ERR_E_LENGTH 4 +#define QM_ERR_E_OFFSET 0 +#define QM_ERR_NR_E 0 + +#define QM_ERR_DATA "qmer_data" +#define QM_ERR_QM_ERR_DATA_BOFFSET 0 +#define QM_ERR_QM_ERR_DATA_BLEN 32 +#define QM_ERR_QM_ERR_DATA_FLAG HSL_RO + + /** + * Vlan Table Function Register + */ +//high +#define VLAN_TABLE_FUNC0 "vtbf0" +#define VLAN_TABLE_FUNC0_ID 9 +#define VLAN_TABLE_FUNC0_OFFSET 0x0040 +#define VLAN_TABLE_FUNC0_E_LENGTH 4 +#define VLAN_TABLE_FUNC0_E_OFFSET 0 +#define VLAN_TABLE_FUNC0_NR_E 0 + +#define VT_PRI_EN "vtbf_vtpen" +#define VLAN_TABLE_FUNC0_VT_PRI_EN_BOFFSET 31 +#define VLAN_TABLE_FUNC0_VT_PRI_EN_BLEN 1 +#define VLAN_TABLE_FUNC0_VT_PRI_EN_FLAG HSL_RW + +#define VT_PRI "vtbf_vtpri" +#define VLAN_TABLE_FUNC0_VT_PRI_BOFFSET 28 +#define VLAN_TABLE_FUNC0_VT_PRI_BLEN 3 +#define VLAN_TABLE_FUNC0_VT_PRI_FLAG HSL_RW + +#define VLAN_ID "vtbf_vid" +#define VLAN_TABLE_FUNC0_VLAN_ID_BOFFSET 16 +#define VLAN_TABLE_FUNC0_VLAN_ID_BLEN 12 +#define VLAN_TABLE_FUNC0_VLAN_ID_FLAG HSL_RW + +#define VT_PORT_NUM "vtbf_vtpn" +#define VLAN_TABLE_FUNC0_VT_PORT_NUM_BOFFSET 8 +#define VLAN_TABLE_FUNC0_VT_PORT_NUM_BLEN 4 +#define VLAN_TABLE_FUNC0_VT_PORT_NUM_FLAG HSL_RW + +#define VT_FULL_VIO "vtbf_vtflv" +#define VLAN_TABLE_FUNC0_VT_FULL_VIO_BOFFSET 4 +#define VLAN_TABLE_FUNC0_VT_FULL_VIO_BLEN 1 +#define VLAN_TABLE_FUNC0_VT_FULL_VIO_FLAG HSL_RW + +#define VT_BUSY "vtbf_vtbs" +#define VLAN_TABLE_FUNC0_VT_BUSY_BOFFSET 3 +#define VLAN_TABLE_FUNC0_VT_BUSY_BLEN 1 +#define VLAN_TABLE_FUNC0_VT_BUSY_FLAG HSL_RW + +#define VT_FUNC "vtbf_vtfc" +#define VLAN_TABLE_FUNC0_VT_FUNC_BOFFSET 0 +#define VLAN_TABLE_FUNC0_VT_FUNC_BLEN 3 +#define VLAN_TABLE_FUNC0_VT_FUNC_FLAG HSL_RW + +//low +#define VLAN_TABLE_FUNC1 "vtbf1" +#define VLAN_TABLE_FUNC1_ID 10 +#define VLAN_TABLE_FUNC1_OFFSET 0x0044 +#define VLAN_TABLE_FUNC1_E_LENGTH 4 +#define VLAN_TABLE_FUNC1_E_OFFSET 0 +#define VLAN_TABLE_FUNC1_NR_E 0 + +#define PORT_TAG_EN "vtbf_pgen" +#define VLAN_TABLE_FUNC1_PORT_TAG_EN_BOFFSET 12 +#define VLAN_TABLE_FUNC1_PORT_TAG_EN_BLEN 20 +#define VLAN_TABLE_FUNC1_PORT_TAG_EN_FLAG HSL_RW + +#define VT_VALID "vtbf_vtvd" +#define VLAN_TABLE_FUNC1_VT_VALID_BOFFSET 11 +#define VLAN_TABLE_FUNC1_VT_VALID_BLEN 1 +#define VLAN_TABLE_FUNC1_VT_VALID_FLAG HSL_RW + +#define VID_MEM "vtbf_vidm" +#define VLAN_TABLE_FUNC1_VID_MEM_BOFFSET 0 +#define VLAN_TABLE_FUNC1_VID_MEM_BLEN 10 +#define VLAN_TABLE_FUNC1_VID_MEM_FLAG HSL_RW + + /** + * Address Table Function Register + */ +#define ADDR_TABLE_FUNC0 "atbf0" +#define ADDR_TABLE_FUNC0_ID 11 +#define ADDR_TABLE_FUNC0_OFFSET 0x0050 +#define ADDR_TABLE_FUNC0_E_LENGTH 4 +#define ADDR_TABLE_FUNC0_E_OFFSET 0 +#define ADDR_TABLE_FUNC0_NR_E 0 + +#define AT_ADDR_BYTE4 "atbf_adb4" +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE4_BOFFSET 24 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE4_BLEN 8 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE4_FLAG HSL_RW + +#define AT_ADDR_BYTE5 "atbf_adb5" +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE5_BOFFSET 16 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE5_BLEN 8 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE5_FLAG HSL_RW + +#define AT_FULL_VIO "atbf_atfv" +#define ADDR_TABLE_FUNC0_AT_FULL_VIO_BOFFSET 12 +#define ADDR_TABLE_FUNC0_AT_FULL_VIO_BLEN 1 +#define ADDR_TABLE_FUNC0_AT_FULL_VIO_FLAG HSL_RW + +#define AT_PORT_NUM "atbf_atpn" +#define ADDR_TABLE_FUNC0_AT_PORT_NUM_BOFFSET 8 +#define ADDR_TABLE_FUNC0_AT_PORT_NUM_BLEN 4 +#define ADDR_TABLE_FUNC0_AT_PORT_NUM_FLAG HSL_RW + +#define AT_BUSY "atbf_atbs" +#define ADDR_TABLE_FUNC0_AT_BUSY_BOFFSET 3 +#define ADDR_TABLE_FUNC0_AT_BUSY_BLEN 1 +#define ADDR_TABLE_FUNC0_AT_BUSY_FLAG HSL_RW + +#define AT_FUNC "atbf_atfc" +#define ADDR_TABLE_FUNC0_AT_FUNC_BOFFSET 0 +#define ADDR_TABLE_FUNC0_AT_FUNC_BLEN 3 +#define ADDR_TABLE_FUNC0_AT_FUNC_FLAG HSL_RW + + +#define ADDR_TABLE_FUNC1 "atbf1" +#define ADDR_TABLE_FUNC1_ID 12 +#define ADDR_TABLE_FUNC1_OFFSET 0x0054 +#define ADDR_TABLE_FUNC1_E_LENGTH 4 +#define ADDR_TABLE_FUNC1_E_OFFSET 0 +#define ADDR_TABLE_FUNC1_NR_E 0 + +#define AT_ADDR_BYTE0 "atbf_adb0" +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE0_BOFFSET 24 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE0_BLEN 8 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE0_FLAG HSL_RW + +#define AT_ADDR_BYTE1 "atbf_adb1" +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE1_BOFFSET 16 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE1_BLEN 8 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE1_FLAG HSL_RW + +#define AT_ADDR_BYTE2 "atbf_adb2" +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE2_BOFFSET 8 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE2_BLEN 8 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE2_FLAG HSL_RW + +#define AT_ADDR_BYTE3 "atbf_adb3" +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE3_BOFFSET 0 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE3_BLEN 8 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE3_FLAG HSL_RW + + +#define ADDR_TABLE_FUNC2 "atbf2" +#define ADDR_TABLE_FUNC2_ID 13 +#define ADDR_TABLE_FUNC2_OFFSET 0x0058 +#define ADDR_TABLE_FUNC2_E_LENGTH 4 +#define ADDR_TABLE_FUNC2_E_OFFSET 0 +#define ADDR_TABLE_FUNC2_NR_E 0 + +#define COPY_TO_CPU "atbf_cpcpu" +#define ADDR_TABLE_FUNC2_COPY_TO_CPU_BOFFSET 26 +#define ADDR_TABLE_FUNC2_COPY_TO_CPU_BLEN 1 +#define ADDR_TABLE_FUNC2_COPY_TO_CPU_FLAG HSL_RW + +#define REDRCT_TO_CPU "atbf_rdcpu" +#define ADDR_TABLE_FUNC2_REDRCT_TO_CPU_BOFFSET 25 +#define ADDR_TABLE_FUNC2_REDRCT_TO_CPU_BLEN 1 +#define ADDR_TABLE_FUNC2_REDRCT_TO_CPU_FLAG HSL_RW + +#define SA_DROP_EN "atbf_saden" +#define ADDR_TABLE_FUNC2_SA_DROP_EN_BOFFSET 16 +#define ADDR_TABLE_FUNC2_SA_DROP_EN_BLEN 1 +#define ADDR_TABLE_FUNC2_SA_DROP_EN_FLAG HSL_RW + +#define AT_STATUS "atbf_atsts" +#define ADDR_TABLE_FUNC2_AT_STATUS_BOFFSET 14 +#define ADDR_TABLE_FUNC2_AT_STATUS_BLEN 2 +#define ADDR_TABLE_FUNC2_AT_STATUS_FLAG HSL_RW + +#define MIRROR_EN "atbf_miren" +#define ADDR_TABLE_FUNC2_MIRROR_EN_BOFFSET 13 +#define ADDR_TABLE_FUNC2_MIRROR_EN_BLEN 1 +#define ADDR_TABLE_FUNC2_MIRROR_EN_FLAG HSL_RW + +#define AT_PRI_EN "atbf_atpen" +#define ADDR_TABLE_FUNC2_AT_PRI_EN_BOFFSET 12 +#define ADDR_TABLE_FUNC2_AT_PRI_EN_BLEN 1 +#define ADDR_TABLE_FUNC2_AT_PRI_EN_FLAG HSL_RW + +#define AT_PRI "atbf_atpri" +#define ADDR_TABLE_FUNC2_AT_PRI_BOFFSET 10 +#define ADDR_TABLE_FUNC2_AT_PRI_BLEN 2 +#define ADDR_TABLE_FUNC2_AT_PRI_FLAG HSL_RW + +#define DES_PORT "atbf_desp" +#define ADDR_TABLE_FUNC2_DES_PORT_BOFFSET 0 +#define ADDR_TABLE_FUNC2_DES_PORT_BLEN 10 +#define ADDR_TABLE_FUNC2_DES_PORT_FLAG HSL_RW + + /** + * Address Table Control Register + */ +#define ADDR_TABLE_CTL "atbc" +#define ADDR_TABLE_CTL_ID 14 +#define ADDR_TABLE_CTL_OFFSET 0x005C +#define ADDR_TABLE_CTL_E_LENGTH 4 +#define ADDR_TABLE_CTL_E_OFFSET 0 +#define ADDR_TABLE_CTL_NR_E 0 + +#define ARP_EN "atbc_arpe" +#define ADDR_TABLE_CTL_ARP_EN_BOFFSET 20 +#define ADDR_TABLE_CTL_ARP_EN_BLEN 1 +#define ADDR_TABLE_CTL_ARP_EN_FLAG HSL_RW + +#define ARL_INI_EN "atbc_arlie" +#define ADDR_TABLE_CTL_ARL_INI_EN_BOFFSET 19 +#define ADDR_TABLE_CTL_ARL_INI_EN_BLEN 1 +#define ADDR_TABLE_CTL_ARL_INI_EN_FLAG HSL_RW + +#define BPDU_EN "atbc_bpdue" +#define ADDR_TABLE_CTL_BPDU_EN_BOFFSET 18 +#define ADDR_TABLE_CTL_BPDU_EN_BLEN 1 +#define ADDR_TABLE_CTL_BPDU_EN_FLAG HSL_RW + +#define AGE_EN "atbc_agee" +#define ADDR_TABLE_CTL_AGE_EN_BOFFSET 17 +#define ADDR_TABLE_CTL_AGE_EN_BLEN 1 +#define ADDR_TABLE_CTL_AGE_EN_FLAG HSL_RW + +#define AGE_TIME "atbc_aget" +#define ADDR_TABLE_CTL_AGE_TIME_BOFFSET 0 +#define ADDR_TABLE_CTL_AGE_TIME_BLEN 16 +#define ADDR_TABLE_CTL_AGE_TIME_FLAG HSL_RW + + /** + * IP Priority Mapping Register + */ +#define IP_PRI_MAPPING0 "imap0" +#define IP_PRI_MAPPING0_ID 15 +#define IP_PRI_MAPPING0_OFFSET 0x0060 +#define IP_PRI_MAPPING0_E_LENGTH 4 +#define IP_PRI_MAPPING0_E_OFFSET 0 +#define IP_PRI_MAPPING0_NR_E 0 + +#define IP_0X3C "imap_ip3c" +#define IP_PRI_MAPPING0_IP_0X3C_BOFFSET 30 +#define IP_PRI_MAPPING0_IP_0X3C_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X3C_FLAG HSL_RW + +#define IP_0X38 "imap_ip38" +#define IP_PRI_MAPPING0_IP_0X38_BOFFSET 28 +#define IP_PRI_MAPPING0_IP_0X38_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X38_FLAG HSL_RW + +#define IP_0X34 "imap_ip34" +#define IP_PRI_MAPPING0_IP_0X34_BOFFSET 26 +#define IP_PRI_MAPPING0_IP_0X34_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X34_FLAG HSL_RW + +#define IP_0X30 "imap_ip30" +#define IP_PRI_MAPPING0_IP_0X30_BOFFSET 24 +#define IP_PRI_MAPPING0_IP_0X30_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X30_FLAG HSL_RW + +#define IP_0X2C "imap_ip2c" +#define IP_PRI_MAPPING0_IP_0X2C_BOFFSET 22 +#define IP_PRI_MAPPING0_IP_0X2C_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X2C_FLAG HSL_RW + +#define IP_0X28 "imap_ip28" +#define IP_PRI_MAPPING0_IP_0X28_BOFFSET 20 +#define IP_PRI_MAPPING0_IP_0X28_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X28_FLAG HSL_RW + +#define IP_0X24 "imap_ip24" +#define IP_PRI_MAPPING0_IP_0X24_BOFFSET 18 +#define IP_PRI_MAPPING0_IP_0X24_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X24_FLAG HSL_RW + +#define IP_0X20 "imap_ip20" +#define IP_PRI_MAPPING0_IP_0X20_BOFFSET 16 +#define IP_PRI_MAPPING0_IP_0X20_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X20_FLAG HSL_RW + +#define IP_0X1C "imap_ip1c" +#define IP_PRI_MAPPING0_IP_0X1C_BOFFSET 14 +#define IP_PRI_MAPPING0_IP_0X1C_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X1C_FLAG HSL_RW + +#define IP_0X18 "imap_ip18" +#define IP_PRI_MAPPING0_IP_0X18_BOFFSET 12 +#define IP_PRI_MAPPING0_IP_0X18_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X18_FLAG HSL_RW + +#define IP_0X14 "imap_ip14" +#define IP_PRI_MAPPING0_IP_0X14_BOFFSET 10 +#define IP_PRI_MAPPING0_IP_0X14_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X14_FLAG HSL_RW + +#define IP_0X10 "imap_ip10" +#define IP_PRI_MAPPING0_IP_0X10_BOFFSET 8 +#define IP_PRI_MAPPING0_IP_0X10_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X10_FLAG HSL_RW + +#define IP_0X0C "imap_ip0c" +#define IP_PRI_MAPPING0_IP_0X0C_BOFFSET 6 +#define IP_PRI_MAPPING0_IP_0X0C_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X0C_FLAG HSL_RW + +#define IP_0X08 "imap_ip08" +#define IP_PRI_MAPPING0_IP_0X08_BOFFSET 4 +#define IP_PRI_MAPPING0_IP_0X08_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X08_FLAG HSL_RW + +#define IP_0X04 "imap_ip04" +#define IP_PRI_MAPPING0_IP_0X04_BOFFSET 2 +#define IP_PRI_MAPPING0_IP_0X04_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X04_FLAG HSL_RW + +#define IP_0X00 "imap_ip00" +#define IP_PRI_MAPPING0_IP_0X00_BOFFSET 0 +#define IP_PRI_MAPPING0_IP_0X00_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X00_FLAG HSL_RW + +#define IP_PRI_MAPPING1 "imap1" +#define IP_PRI_MAPPING1_ID 16 +#define IP_PRI_MAPPING1_OFFSET 0x0064 +#define IP_PRI_MAPPING1_E_LENGTH 4 +#define IP_PRI_MAPPING1_E_OFFSET 0 +#define IP_PRI_MAPPING1_NR_E 0 + +#define IP_0X7C "imap_ip7c" +#define IP_PRI_MAPPING1_IP_0X7C_BOFFSET 30 +#define IP_PRI_MAPPING1_IP_0X7C_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X7C_FLAG HSL_RW + +#define IP_0X78 "imap_ip78" +#define IP_PRI_MAPPING1_IP_0X78_BOFFSET 28 +#define IP_PRI_MAPPING1_IP_0X78_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X78_FLAG HSL_RW + +#define IP_0X74 "imap_ip74" +#define IP_PRI_MAPPING1_IP_0X74_BOFFSET 26 +#define IP_PRI_MAPPING1_IP_0X74_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X74_FLAG HSL_RW + +#define IP_0X70 "imap_ip70" +#define IP_PRI_MAPPING1_IP_0X70_BOFFSET 24 +#define IP_PRI_MAPPING1_IP_0X70_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X70_FLAG HSL_RW + +#define IP_0X6C "imap_ip6c" +#define IP_PRI_MAPPING1_IP_0X6C_BOFFSET 22 +#define IP_PRI_MAPPING1_IP_0X6C_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X6C_FLAG HSL_RW + +#define IP_0X68 "imap_ip68" +#define IP_PRI_MAPPING1_IP_0X68_BOFFSET 20 +#define IP_PRI_MAPPING1_IP_0X68_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X68_FLAG HSL_RW + +#define IP_0X64 "imap_ip64" +#define IP_PRI_MAPPING1_IP_0X64_BOFFSET 18 +#define IP_PRI_MAPPING1_IP_0X64_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X64_FLAG HSL_RW + +#define IP_0X60 "imap_ip60" +#define IP_PRI_MAPPING1_IP_0X60_BOFFSET 16 +#define IP_PRI_MAPPING1_IP_0X60_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X60_FLAG HSL_RW + +#define IP_0X5C "imap_ip5c" +#define IP_PRI_MAPPING1_IP_0X5C_BOFFSET 14 +#define IP_PRI_MAPPING1_IP_0X5C_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X5C_FLAG HSL_RW + +#define IP_0X58 "imap_ip58" +#define IP_PRI_MAPPING1_IP_0X58_BOFFSET 12 +#define IP_PRI_MAPPING1_IP_0X58_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X58_FLAG HSL_RW + +#define IP_0X54 "imap_ip54" +#define IP_PRI_MAPPING1_IP_0X54_BOFFSET 10 +#define IP_PRI_MAPPING1_IP_0X54_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X54_FLAG HSL_RW + +#define IP_0X50 "imap_ip50" +#define IP_PRI_MAPPING1_IP_0X50_BOFFSET 8 +#define IP_PRI_MAPPING1_IP_0X50_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X50_FLAG HSL_RW + +#define IP_0X4C "imap_ip4c" +#define IP_PRI_MAPPING1_IP_0X4C_BOFFSET 6 +#define IP_PRI_MAPPING1_IP_0X4C_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X4C_FLAG HSL_RW + +#define IP_0X48 "imap_ip48" +#define IP_PRI_MAPPING1_IP_0X48_BOFFSET 4 +#define IP_PRI_MAPPING1_IP_0X48_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X48_FLAG HSL_RW + +#define IP_0X44 "imap_ip44" +#define IP_PRI_MAPPING1_IP_0X44_BOFFSET 2 +#define IP_PRI_MAPPING1_IP_0X44_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X44_FLAG HSL_RW + +#define IP_0X40 "imap_ip40" +#define IP_PRI_MAPPING1_IP_0X40_BOFFSET 0 +#define IP_PRI_MAPPING1_IP_0X40_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X40_FLAG HSL_RW + + +#define IP_PRI_MAPPING2 "imap2" +#define IP_PRI_MAPPING2_ID 17 +#define IP_PRI_MAPPING2_OFFSET 0x0068 +#define IP_PRI_MAPPING2_E_LENGTH 4 +#define IP_PRI_MAPPING2_E_OFFSET 0 +#define IP_PRI_MAPPING2_NR_E 0 + +#define IP_0XBC "imap_ipbc" +#define IP_PRI_MAPPING2_IP_0XBC_BOFFSET 30 +#define IP_PRI_MAPPING2_IP_0XBC_BLEN 2 +#define IP_PRI_MAPPING2_IP_0XBC_FLAG HSL_RW + +#define IP_0XB8 "imap_ipb8" +#define IP_PRI_MAPPING2_IP_0XB8_BOFFSET 28 +#define IP_PRI_MAPPING2_IP_0XB8_BLEN 2 +#define IP_PRI_MAPPING2_IP_0XB8_FLAG HSL_RW + +#define IP_0XB4 "imap_ipb4" +#define IP_PRI_MAPPING2_IP_0XB4_BOFFSET 26 +#define IP_PRI_MAPPING2_IP_0XB4_BLEN 2 +#define IP_PRI_MAPPING2_IP_0XB4_FLAG HSL_RW + +#define IP_0XB0 "imap_ipb0" +#define IP_PRI_MAPPING2_IP_0XB0_BOFFSET 24 +#define IP_PRI_MAPPING2_IP_0XB0_BLEN 2 +#define IP_PRI_MAPPING2_IP_0XB0_FLAG HSL_RW + +#define IP_0XAC "imap_ipac" +#define IP_PRI_MAPPING2_IP_0XAC_BOFFSET 22 +#define IP_PRI_MAPPING2_IP_0XAC_BLEN 2 +#define IP_PRI_MAPPING2_IP_0XAC_FLAG HSL_RW + +#define IP_0XA8 "imap_ipa8" +#define IP_PRI_MAPPING2_IP_0XA8_BOFFSET 20 +#define IP_PRI_MAPPING2_IP_0XA8_BLEN 2 +#define IP_PRI_MAPPING2_IP_0XA8_FLAG HSL_RW + +#define IP_0XA4 "imap_ipa4" +#define IP_PRI_MAPPING2_IP_0XA4_BOFFSET 18 +#define IP_PRI_MAPPING2_IP_0XA4_BLEN 2 +#define IP_PRI_MAPPING2_IP_0XA4_FLAG HSL_RW + +#define IP_0XA0 "imap_ipa0" +#define IP_PRI_MAPPING2_IP_0XA0_BOFFSET 16 +#define IP_PRI_MAPPING2_IP_0XA0_BLEN 2 +#define IP_PRI_MAPPING2_IP_0XA0_FLAG HSL_RW + +#define IP_0X9C "imap_ip9c" +#define IP_PRI_MAPPING2_IP_0X9C_BOFFSET 14 +#define IP_PRI_MAPPING2_IP_0X9C_BLEN 2 +#define IP_PRI_MAPPING2_IP_0X9C_FLAG HSL_RW + +#define IP_0X98 "imap_ip98" +#define IP_PRI_MAPPING2_IP_0X98_BOFFSET 12 +#define IP_PRI_MAPPING2_IP_0X98_BLEN 2 +#define IP_PRI_MAPPING2_IP_0X98_FLAG HSL_RW + +#define IP_0X94 "imap_ip94" +#define IP_PRI_MAPPING2_IP_0X94_BOFFSET 10 +#define IP_PRI_MAPPING2_IP_0X94_BLEN 2 +#define IP_PRI_MAPPING2_IP_0X94_FLAG HSL_RW + +#define IP_0X90 "imap_ip90" +#define IP_PRI_MAPPING2_IP_0X90_BOFFSET 8 +#define IP_PRI_MAPPING2_IP_0X90_BLEN 2 +#define IP_PRI_MAPPING2_IP_0X90_FLAG HSL_RW + +#define IP_0X8C "imap_ip8c" +#define IP_PRI_MAPPING2_IP_0X8C_BOFFSET 6 +#define IP_PRI_MAPPING2_IP_0X8C_BLEN 2 +#define IP_PRI_MAPPING2_IP_0X8C_FLAG HSL_RW + +#define IP_0X88 "imap_ip88" +#define IP_PRI_MAPPING2_IP_0X88_BOFFSET 4 +#define IP_PRI_MAPPING2_IP_0X88_BLEN 2 +#define IP_PRI_MAPPING2_IP_0X88_FLAG HSL_RW + +#define IP_0X84 "imap_ip84" +#define IP_PRI_MAPPING2_IP_0X84_BOFFSET 2 +#define IP_PRI_MAPPING2_IP_0X84_BLEN 2 +#define IP_PRI_MAPPING2_IP_0X84_FLAG HSL_RW + +#define IP_0X80 "imap_ip80" +#define IP_PRI_MAPPING2_IP_0X80_BOFFSET 0 +#define IP_PRI_MAPPING2_IP_0X80_BLEN 2 +#define IP_PRI_MAPPING2_IP_0X80_FLAG HSL_RW + +#define IP_PRI_MAPPING3 "imap3" +#define IP_PRI_MAPPING3_ID 18 +#define IP_PRI_MAPPING3_OFFSET 0x006C +#define IP_PRI_MAPPING3_E_LENGTH 4 +#define IP_PRI_MAPPING3_E_OFFSET 0 +#define IP_PRI_MAPPING3_NR_E 0 + +#define IP_0XFC "imap_ipfc" +#define IP_PRI_MAPPING3_IP_0XFC_BOFFSET 30 +#define IP_PRI_MAPPING3_IP_0XFC_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XFC_FLAG HSL_RW + +#define IP_0XF8 "imap_ipf8" +#define IP_PRI_MAPPING3_IP_0XF8_BOFFSET 28 +#define IP_PRI_MAPPING3_IP_0XF8_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XF8_FLAG HSL_RW + +#define IP_0XF4 "imap_ipf4" +#define IP_PRI_MAPPING3_IP_0XF4_BOFFSET 26 +#define IP_PRI_MAPPING3_IP_0XF4_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XF4_FLAG HSL_RW + +#define IP_0XF0 "imap_ipf0" +#define IP_PRI_MAPPING3_IP_0XF0_BOFFSET 24 +#define IP_PRI_MAPPING3_IP_0XF0_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XF0_FLAG HSL_RW + +#define IP_0XEC "imap_ipec" +#define IP_PRI_MAPPING3_IP_0XEC_BOFFSET 22 +#define IP_PRI_MAPPING3_IP_0XEC_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XEC_FLAG HSL_RW + +#define IP_0XE8 "imap_ipe8" +#define IP_PRI_MAPPING3_IP_0XE8_BOFFSET 20 +#define IP_PRI_MAPPING3_IP_0XE8_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XE8_FLAG HSL_RW + +#define IP_0XE4 "imap_ipe4" +#define IP_PRI_MAPPING3_IP_0XE4_BOFFSET 18 +#define IP_PRI_MAPPING3_IP_0XE4_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XE4_FLAG HSL_RW + +#define IP_0XE0 "imap_ipe0" +#define IP_PRI_MAPPING3_IP_0XE0_BOFFSET 16 +#define IP_PRI_MAPPING3_IP_0XE0_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XE0_FLAG HSL_RW + +#define IP_0XDC "imap_ipdc" +#define IP_PRI_MAPPING3_IP_0XDC_BOFFSET 14 +#define IP_PRI_MAPPING3_IP_0XDC_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XDC_FLAG HSL_RW + +#define IP_0XD8 "imap_ipd8" +#define IP_PRI_MAPPING3_IP_0XD8_BOFFSET 12 +#define IP_PRI_MAPPING3_IP_0XD8_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XD8_FLAG HSL_RW + +#define IP_0XD4 "imap_ipd4" +#define IP_PRI_MAPPING3_IP_0XD4_BOFFSET 10 +#define IP_PRI_MAPPING3_IP_0XD4_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XD4_FLAG HSL_RW + +#define IP_0XD0 "imap_ipd0" +#define IP_PRI_MAPPING3_IP_0XD0_BOFFSET 8 +#define IP_PRI_MAPPING3_IP_0XD0_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XD0_FLAG HSL_RW + +#define IP_0XCC "imap_ipcc" +#define IP_PRI_MAPPING3_IP_0XCC_BOFFSET 6 +#define IP_PRI_MAPPING3_IP_0XCC_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XCC_FLAG HSL_RW + +#define IP_0XC8 "imap_ipc8" +#define IP_PRI_MAPPING3_IP_0XC8_BOFFSET 4 +#define IP_PRI_MAPPING3_IP_0XC8_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XC8_FLAG HSL_RW + +#define IP_0XC4 "imap_ipc4" +#define IP_PRI_MAPPING3_IP_0XC4_BOFFSET 2 +#define IP_PRI_MAPPING3_IP_0XC4_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XC4_FLAG HSL_RW + +#define IP_0XC0 "imap_ipc0" +#define IP_PRI_MAPPING3_IP_0XC0_BOFFSET 0 +#define IP_PRI_MAPPING3_IP_0XC0_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XC0_FLAG HSL_RW + + /** + * Tag Priority Mapping Register + */ +#define TAG_PRI_MAPPING "tpmap" +#define TAG_PRI_MAPPING_ID 19 +#define TAG_PRI_MAPPING_OFFSET 0x0070 +#define TAG_PRI_MAPPING_E_LENGTH 4 +#define TAG_PRI_MAPPING_E_OFFSET 0 +#define TAG_PRI_MAPPING_NR_E 0 + +#define TAG_0X07 "tpmap_tg07" +#define TAG_PRI_MAPPING_TAG_0X07_BOFFSET 14 +#define TAG_PRI_MAPPING_TAG_0X07_BLEN 2 +#define TAG_PRI_MAPPING_TAG_0X07_FLAG HSL_RW + +#define TAG_0X06 "tpmap_tg06" +#define TAG_PRI_MAPPING_TAG_0X06_BOFFSET 12 +#define TAG_PRI_MAPPING_TAG_0X06_BLEN 2 +#define TAG_PRI_MAPPING_TAG_0X06_FLAG HSL_RW + +#define TAG_0X05 "tpmap_tg05" +#define TAG_PRI_MAPPING_TAG_0X05_BOFFSET 10 +#define TAG_PRI_MAPPING_TAG_0X05_BLEN 2 +#define TAG_PRI_MAPPING_TAG_0X05_FLAG HSL_RW + +#define TAG_0X04 "tpmap_tg04" +#define TAG_PRI_MAPPING_TAG_0X04_BOFFSET 8 +#define TAG_PRI_MAPPING_TAG_0X04_BLEN 2 +#define TAG_PRI_MAPPING_TAG_0X04_FLAG HSL_RW + +#define TAG_0X03 "tpmap_tg03" +#define TAG_PRI_MAPPING_TAG_0X03_BOFFSET 6 +#define TAG_PRI_MAPPING_TAG_0X03_BLEN 2 +#define TAG_PRI_MAPPING_TAG_0X03_FLAG HSL_RW + +#define TAG_0X02 "tpmap_tg02" +#define TAG_PRI_MAPPING_TAG_0X02_BOFFSET 4 +#define TAG_PRI_MAPPING_TAG_0X02_BLEN 2 +#define TAG_PRI_MAPPING_TAG_0X02_FLAG HSL_RW + +#define TAG_0X01 "tpmap_tg01" +#define TAG_PRI_MAPPING_TAG_0X01_BOFFSET 2 +#define TAG_PRI_MAPPING_TAG_0X01_BLEN 2 +#define TAG_PRI_MAPPING_TAG_0X01_FLAG HSL_RW + +#define TAG_0X00 "tpmap_tg00" +#define TAG_PRI_MAPPING_TAG_0X00_BOFFSET 0 +#define TAG_PRI_MAPPING_TAG_0X00_BLEN 2 +#define TAG_PRI_MAPPING_TAG_0X00_FLAG HSL_RW + + /** + * Cpu Port Register + */ +#define CPU_PORT "cpup" +#define CPU_PORT_ID 20 +#define CPU_PORT_OFFSET 0x0078 +#define CPU_PORT_E_LENGTH 4 +#define CPU_PORT_E_OFFSET 0 +#define CPU_PORT_NR_E 0 + +#define CPU_PORT_EN "cpup_cpupe" +#define CPU_PORT_CPU_PORT_EN_BOFFSET 8 +#define CPU_PORT_CPU_PORT_EN_BLEN 1 +#define CPU_PORT_CPU_PORT_EN_FLAG HSL_RW + +#define MIRROR_PORT_NUM "cpup_mirpn" +#define CPU_PORT_MIRROR_PORT_NUM_BOFFSET 4 +#define CPU_PORT_MIRROR_PORT_NUM_BLEN 4 +#define CPU_PORT_MIRROR_PORT_NUM_FLAG HSL_RW + +#define RMII_CUT "cpup_rmcut" +#define CPU_PORT_RMII_CUT_BOFFSET 0 +#define CPU_PORT_RMII_CUT_BLEN 1 +#define CPU_PORT_RMII_CUT_FLAG HSL_RW + + /** + * MIB Function Register + */ +#define MIB_CNT "mibcnt" +#define MIB_CNT_ID 21 +#define MIB_CNT_OFFSET 0x0080 +#define MIB_CNT_E_LENGTH 4 +#define MIB_CNT_E_OFFSET 0 +#define MIB_CNT_NR_E 0 + +#define MIB_FUNC "mibcnt_mibf" +#define MIB_CNT_MIB_FUNC_BOFFSET 24 +#define MIB_CNT_MIB_FUNC_BLEN 3 +#define MIB_CNT_MIB_FUNC_FLAG HSL_RW + +#define MIB_BUSY "mibcnt_mibb" +#define MIB_CNT_MIB_BUSY_BOFFSET 17 +#define MIB_CNT_MIB_BUSY_BLEN 1 +#define MIB_CNT_MIB_BUSY_FLAG HSL_RW + +#define MIB_AT_HALF_EN "mibcnt_mibhe" +#define MIB_CNT_MIB_AT_HALF_EN_BOFFSET 16 +#define MIB_CNT_MIB_AT_HALF_EN_BLEN 1 +#define MIB_CNT_MIB_AT_HALF_EN_FLAG HSL_RW + +#define MIB_TIMER "mibcnt_mibt" +#define MIB_CNT_MIB_TIMER_BOFFSET 0 +#define MIB_CNT_MIB_TIMER_BLEN 16 +#define MIB_CNT_MIB_TIMER_FLAG HSL_RW + + /** + * SPI Interface Register + */ +#define SPI_INTERFACE "spi" +#define SPI_INTERFACE_ID 22 +#define SPI_INTERFACE_OFFSET 0x0090 +#define SPI_INTERFACE_E_LENGTH 4 +#define SPI_INTERFACE_E_OFFSET 0 +#define SPI_INTERFACE_NR_E 0 + +#define DEBUG_OEN "spi_dben" +#define SPI_INTERFACE_DEBUG_OEN_BOFFSET 7 +#define SPI_INTERFACE_DEBUG_OEN_BLEN 25 +#define SPI_INTERFACE_DEBUG_OEN_FLAG HSL_RO + +#define SPI_EN "spi_spien" +#define SPI_INTERFACE_SPI_EN_BOFFSET 5 +#define SPI_INTERFACE_SPI_EN_BLEN 1 +#define SPI_INTERFACE_SPI_EN_FLAG HSL_RO + +#define SPI_SPEED "spi_spisp" +#define SPI_INTERFACE_SPI_SPEED_BOFFSET 4 +#define SPI_INTERFACE_SPI_SPEED_BLEN 1 +#define SPI_INTERFACE_SPI_SPEED_FLAG HSL_RO + +#define UART_SPEED "spi_utsp" +#define SPI_INTERFACE_UART_SPEED_BOFFSET 3 +#define SPI_INTERFACE_UART_SPEED_BLEN 1 +#define SPI_INTERFACE_UART_SPEED_FLAG HSL_RO + +#define RMII_EN "spi_rmen" +#define SPI_INTERFACE_RMII_EN_BOFFSET 2 +#define SPI_INTERFACE_RMII_EN_BLEN 1 +#define SPI_INTERFACE_RMII_EN_FLAG HSL_RO + +#define MII_EN "spi_miien" +#define SPI_INTERFACE_MII_EN_BOFFSET 1 +#define SPI_INTERFACE_MII_EN_BLEN 1 +#define SPI_INTERFACE_MII_EN_FLAG HSL_RO + +#define SPI_SIZE "spi_spisz" +#define SPI_INTERFACE_SPI_SIZE_BOFFSET 0 +#define SPI_INTERFACE_SPI_SIZE_BLEN 1 +#define SPI_INTERFACE_SPI_SIZE_FLAG HSL_RO + + /** + * MDIO High Address Register + */ +#define MDIO_HIGH_ADDR "mdiohd" +#define MDIO_HIGH_ADDR_ID 23 +#define MDIO_HIGH_ADDR_OFFSET 0x0094 +#define MDIO_HIGH_ADDR_E_LENGTH 4 +#define MDIO_HIGH_ADDR_E_OFFSET 0 +#define MDIO_HIGH_ADDR_NR_E 0 + +#define MDIO_HA "mdiohd_ha" +#define MDIO_HIGH_ADDR_MDIO_HA_BOFFSET 0 +#define MDIO_HIGH_ADDR_MDIO_HA_BLEN 9 +#define MDIO_HIGH_ADDR_MDIO_HA_FLAG HSL_RW + + /** + * Destination IP Address Register + */ +#define DIP_ADDR "dip" +#define DIP_ADDR_ID 24 +#define DIP_ADDR_OFFSET 0x0098 +#define DIP_ADDR_E_LENGTH 4 +#define DIP_ADDR_E_OFFSET 0 +#define DIP_ADDR_NR_E 0 + +#define DES_IP_ADDR "dip_addr" +#define DIP_ADDR_DES_IP_ADDR_BOFFSET 0 +#define DIP_ADDR_DES_IP_ADDR_BLEN 32 +#define DIP_ADDR_DES_IP_ADDR_FLAG HSL_RW + + /** + * BIST Control Register + */ +#define BIST_CTL "bctl" +#define BIST_CTL_ID 25 +#define BIST_CTL_OFFSET 0x00A0 +#define BIST_CTL_E_LENGTH 4 +#define BIST_CTL_E_OFFSET 0 +#define BIST_CTL_NR_E 0 + +#define BIST_BUSY "bctl_busy" +#define BIST_CTL_BIST_BUSY_BOFFSET 31 +#define BIST_CTL_BIST_BUSY_BLEN 1 +#define BIST_CTL_BIST_BUSY_FLAG HSL_RW + +#define BIST_ERR_MEM "bctl_errmem" +#define BIST_CTL_BIST_ERR_MEM_BOFFSET 24 +#define BIST_CTL_BIST_ERR_MEM_BLEN 4 +#define BIST_CTL_BIST_ERR_MEM_FLAG HSL_RO + +#define BIST_PTN_EN_2 "bctl_ptnen2" +#define BIST_CTL_BIST_PTN_EN_2_BOFFSET 22 +#define BIST_CTL_BIST_PTN_EN_2_BLEN 1 +#define BIST_CTL_BIST_PTN_EN_2_FLAG HSL_RW + +#define BIST_PTN_EN_1 "bctl_ptnen1" +#define BIST_CTL_BIST_PTN_EN_1_BOFFSET 21 +#define BIST_CTL_BIST_PTN_EN_1_BLEN 1 +#define BIST_CTL_BIST_PTN_EN_1_FLAG HSL_RW + +#define BIST_PTN_EN_0 "bctl_ptnen0" +#define BIST_CTL_BIST_PTN_EN_0_BOFFSET 20 +#define BIST_CTL_BIST_PTN_EN_0_BLEN 1 +#define BIST_CTL_BIST_PTN_EN_0_FLAG HSL_RW + +#define BIST_ERR_PTN "bctl_errptn" +#define BIST_CTL_BIST_ERR_PTN_BOFFSET 16 +#define BIST_CTL_BIST_ERR_PTN_BLEN 2 +#define BIST_CTL_BIST_ERR_PTN_FLAG HSL_RO + +#define BIST_ERR_CNT "bctl_errcnt" +#define BIST_CTL_BIST_ERR_CNT_BOFFSET 13 +#define BIST_CTL_BIST_ERR_CNT_BLEN 3 +#define BIST_CTL_BIST_ERR_CNT_FLAG HSL_RO + +#define BIST_ERR_ADDR "bctl_errad" +#define BIST_CTL_BIST_ERR_ADDR_BOFFSET 0 +#define BIST_CTL_BIST_ERR_ADDR_BLEN 13 +#define BIST_CTL_BIST_ERR_ADDR_FLAG HSL_RO + + /** + * Debug Control Register + */ +#define DEBUG_CTL0 "dctl0" +#define DEBUG_CTL0_ID 26 +#define DEBUG_CTL0_OFFSET 0x00F0 +#define DEBUG_CTL0_E_LENGTH 4 +#define DEBUG_CTL0_E_OFFSET 0 +#define DEBUG_CTL0_NR_E 0 + +#define DEBUG_SEL "dctl_sel" +#define DEBUG_CTL0_DEBUG_SEL_BOFFSET 16 +#define DEBUG_CTL0_DEBUG_SEL_BLEN 8 +#define DEBUG_CTL0_DEBUG_SEL_FLAG HSL_RW + +#define DEBUG_PORT_NUM "dctl_ptnum" +#define DEBUG_CTL0_DEBUG_PORT_NUM_BOFFSET 8 +#define DEBUG_CTL0_DEBUG_PORT_NUM_BLEN 4 +#define DEBUG_CTL0_DEBUG_PORT_NUM_FLAG HSL_RW + +#define DEBUG_ADDR "dctl_addr" +#define DEBUG_CTL0_DEBUG_ADDR_BOFFSET 0 +#define DEBUG_CTL0_DEBUG_ADDR_BLEN 8 +#define DEBUG_CTL0_DEBUG_ADDR_FLAG HSL_RW + + +#define DEBUG_CTL1 "dctl1" +#define DEBUG_CTL1_ID 27 +#define DEBUG_CTL1_OFFSET 0x00F4 +#define DEBUG_CTL1_E_LENGTH 4 +#define DEBUG_CTL1_E_OFFSET 0 +#define DEBUG_CTL1_NR_E 0 + +#define DEBUG_DATA "dctl_data" +#define DEBUG_CTL1_DEBUG_DATA_BOFFSET 0 +#define DEBUG_CTL1_DEBUG_DATA_BLEN 32 +#define DEBUG_CTL1_DEBUG_DATA_FLAG HSL_RO + + /** + * QM Debug Control Register + */ +#define QM_DEBUG_CTL "qmdctl" +#define QM_DEBUG_CTL_ID 28 +#define QM_DEBUG_CTL_OFFSET 0x00F8 +#define QM_DEBUG_CTL_E_LENGTH 4 +#define QM_DEBUG_CTL_E_OFFSET 0 +#define QM_DEBUG_CTL_NR_E 0 + +#define QM_DBG_CTRL "qmdctl_dbgctl" +#define QM_DEBUG_CTL_QM_DBG_CTRL_BOFFSET 0 +#define QM_DEBUG_CTL_QM_DBG_CTRL_BLEN 32 +#define QM_DEBUG_CTL_QM_DBG_CTRL_FLAG HSL_RW + + /** + * Port Status Register + */ +#define PORT_STATUS "ptsts" +#define PORT_STATUS_ID 29 +#define PORT_STATUS_OFFSET 0x0100 +#define PORT_STATUS_E_LENGTH 4 +#define PORT_STATUS_E_OFFSET 0x0100 +#define PORT_STATUS_NR_E 6 + +#define LINK_ASYN_PAUSE "ptsts_lasynp" +#define PORT_STATUS_LINK_ASYN_PAUSE_BOFFSET 11 +#define PORT_STATUS_LINK_ASYN_PAUSE_BLEN 1 +#define PORT_STATUS_LINK_ASYN_PAUSE_FLAG HSL_RO + +#define LINK_PAUSE "ptsts_lpause" +#define PORT_STATUS_LINK_PAUSE_BOFFSET 10 +#define PORT_STATUS_LINK_PAUSE_BLEN 1 +#define PORT_STATUS_LINK_PAUSE_FLAG HSL_RO + +#define LINK_EN "ptsts_linken" +#define PORT_STATUS_LINK_EN_BOFFSET 9 +#define PORT_STATUS_LINK_EN_BLEN 1 +#define PORT_STATUS_LINK_EN_FLAG HSL_RW + +#define LINK "ptsts_ptlink" +#define PORT_STATUS_LINK_BOFFSET 8 +#define PORT_STATUS_LINK_BLEN 1 +#define PORT_STATUS_LINK_FLAG HSL_RO + +#define DUPLEX_MODE "ptsts_dupmod" +#define PORT_STATUS_DUPLEX_MODE_BOFFSET 6 +#define PORT_STATUS_DUPLEX_MODE_BLEN 1 +#define PORT_STATUS_DUPLEX_MODE_FLAG HSL_RW + +#define RX_FLOW_EN "ptsts_rxfwen" +#define PORT_STATUS_RX_FLOW_EN_BOFFSET 5 +#define PORT_STATUS_RX_FLOW_EN_BLEN 1 +#define PORT_STATUS_RX_FLOW_EN_FLAG HSL_RW + +#define TX_FLOW_EN "ptsts_txfwen" +#define PORT_STATUS_TX_FLOW_EN_BOFFSET 4 +#define PORT_STATUS_TX_FLOW_EN_BLEN 1 +#define PORT_STATUS_TX_FLOW_EN_FLAG HSL_RW + +#define RXMAC_EN "ptsts_rxmacen" +#define PORT_STATUS_RXMAC_EN_BOFFSET 3 +#define PORT_STATUS_RXMAC_EN_BLEN 1 +#define PORT_STATUS_RXMAC_EN_FLAG HSL_RW + +#define TXMAC_EN "ptsts_txmacen" +#define PORT_STATUS_TXMAC_EN_BOFFSET 2 +#define PORT_STATUS_TXMAC_EN_BLEN 1 +#define PORT_STATUS_TXMAC_EN_FLAG HSL_RW + +#define SPEED_MODE "ptsts_speed" +#define PORT_STATUS_SPEED_MODE_BOFFSET 0 +#define PORT_STATUS_SPEED_MODE_BLEN 2 +#define PORT_STATUS_SPEED_MODE_FLAG HSL_RW + + /** + * Port Control Register + */ +#define PORT_CTL "pctl" +#define PORT_CTL_ID 30 +#define PORT_CTL_OFFSET 0x0104 +#define PORT_CTL_E_LENGTH 4 +#define PORT_CTL_E_OFFSET 0x0100 +#define PORT_CTL_NR_E 6 + +#define ING_MIRROR_EN "pctl_ingmiren" +#define PORT_CTL_ING_MIRROR_EN_BOFFSET 17 +#define PORT_CTL_ING_MIRROR_EN_BLEN 1 +#define PORT_CTL_ING_MIRROR_EN_FLAG HSL_RW + +#define EG_MIRROR_EN "pctl_egmiren" +#define PORT_CTL_EG_MIRROR_EN_BOFFSET 16 +#define PORT_CTL_EG_MIRROR_EN_BLEN 1 +#define PORT_CTL_EG_MIRROR_EN_FLAG HSL_RW + +#define LEARN_EN "pctl_learnen" +#define PORT_CTL_LEARN_EN_BOFFSET 14 +#define PORT_CTL_LEARN_EN_BLEN 1 +#define PORT_CTL_LEARN_EN_FLAG HSL_RW + +#define SINGLE_VLAN_EN "pctl_svlanen" +#define PORT_CTL_SINGLE_VLAN_EN_BOFFSET 13 +#define PORT_CTL_SINGLE_VLAN_EN_BLEN 1 +#define PORT_CTL_SINGLE_VLAN_EN_FLAG HSL_RW + +#define MAC_LOOP_BACK "pctl_maclp" +#define PORT_CTL_MAC_LOOP_BACK_BOFFSET 12 +#define PORT_CTL_MAC_LOOP_BACK_BLEN 1 +#define PORT_CTL_MAC_LOOP_BACK_FLAG HSL_RW + +#define HEAD_EN "pctl_headen" +#define PORT_CTL_HEAD_EN_BOFFSET 11 +#define PORT_CTL_HEAD_EN_BLEN 1 +#define PORT_CTL_HEAD_EN_FLAG HSL_RW + +#define IGMP_MLD_EN "pctl_imlden" +#define PORT_CTL_IGMP_MLD_EN_BOFFSET 10 +#define PORT_CTL_IGMP_MLD_EN_BLEN 1 +#define PORT_CTL_IGMP_MLD_EN_FLAG HSL_RW + +#define EG_VLAN_MODE "pctl_egvmode" +#define PORT_CTL_EG_VLAN_MODE_BOFFSET 8 +#define PORT_CTL_EG_VLAN_MODE_BLEN 2 +#define PORT_CTL_EG_VLAN_MODE_FLAG HSL_RW + +#define LEARN_ONE_LOCK "pctl_lonelck" +#define PORT_CTL_LEARN_ONE_LOCK_BOFFSET 7 +#define PORT_CTL_LEARN_ONE_LOCK_BLEN 1 +#define PORT_CTL_LEARN_ONE_LOCK_FLAG HSL_RW + +#define PORT_STATE "pctl_pstate" +#define PORT_CTL_PORT_STATE_BOFFSET 0 +#define PORT_CTL_PORT_STATE_BLEN 3 +#define PORT_CTL_PORT_STATE_FLAG HSL_RW + + /** + * Port Based Vlan Register + */ +#define PORT_BASE_VLAN "pbvlan" +#define PORT_BASE_VLAN_ID 31 +#define PORT_BASE_VLAN_OFFSET 0x0108 +#define PORT_BASE_VLAN_E_LENGTH 4 +#define PORT_BASE_VLAN_E_OFFSET 0x0100 +#define PORT_BASE_VLAN_NR_E 6 + +#define DOT1Q_MODE "pbvlan_8021q" +#define PORT_BASE_VLAN_DOT1Q_MODE_BOFFSET 30 +#define PORT_BASE_VLAN_DOT1Q_MODE_BLEN 2 +#define PORT_BASE_VLAN_DOT1Q_MODE_FLAG HSL_RW + +#define ING_PRI "pbvlan_ingpri" +#define PORT_BASE_VLAN_ING_PRI_BOFFSET 28 +#define PORT_BASE_VLAN_ING_PRI_BLEN 2 +#define PORT_BASE_VLAN_ING_PRI_FLAG HSL_RW + +#define EG_TAG_PRI0 "pbvlan_egtpri" +#define PORT_BASE_VLAN_EG_TAG_PRI0_BOFFSET 27 +#define PORT_BASE_VLAN_EG_TAG_PRI0_BLEN 1 +#define PORT_BASE_VLAN_EG_TAG_PRI0_FLAG HSL_RW + +#define PORT_VID_MEM "pbvlan_pvidm" +#define PORT_BASE_VLAN_PORT_VID_MEM_BOFFSET 16 +#define PORT_BASE_VLAN_PORT_VID_MEM_BLEN 6 +#define PORT_BASE_VLAN_PORT_VID_MEM_FLAG HSL_RW + +#define PORT_VID "pbvlan_ptvid" +#define PORT_BASE_VLAN_PORT_VID_BOFFSET 0 +#define PORT_BASE_VLAN_PORT_VID_BLEN 12 +#define PORT_BASE_VLAN_PORT_VID_FLAG HSL_RW + + /** + * Port Rate Limit Register + */ +#define RATE_LIMIT "rlmt" +#define RATE_LIMIT_ID 32 +#define RATE_LIMIT_OFFSET 0x010C +#define RATE_LIMIT_E_LENGTH 4 +#define RATE_LIMIT_E_OFFSET 0x0100 +#define RATE_LIMIT_NR_E 6 + +#define EGRESS_RATE_EN "rlmt_egrateen" +#define RATE_LIMIT_EGRESS_RATE_EN_BOFFSET 25 +#define RATE_LIMIT_EGRESS_RATE_EN_BLEN 1 +#define RATE_LIMIT_EGRESS_RATE_EN_FLAG HSL_RW + +#define INGRESS_RATE_EN "rlmt_ingrateen" +#define RATE_LIMIT_INGRESS_RATE_EN_BOFFSET 24 +#define RATE_LIMIT_INGRESS_RATE_EN_BLEN 1 +#define RATE_LIMIT_INGRESS_RATE_EN_FLAG HSL_RW + +#define EG_RATE "rlmt_egrate" +#define RATE_LIMIT_EG_RATE_BOFFSET 16 +#define RATE_LIMIT_EG_RATE_BLEN 4 +#define RATE_LIMIT_EG_RATE_FLAG HSL_RW + +#define ING_RATE "rlmt_ingrate" +#define RATE_LIMIT_ING_RATE_BOFFSET 0 +#define RATE_LIMIT_ING_RATE_BLEN 4 +#define RATE_LIMIT_ING_RATE_FLAG HSL_RW + + /** + * Priority Control Register + */ +#define PRI_CTL "prctl" +#define PRI_CTL_ID 33 +#define PRI_CTL_OFFSET 0x0110 +#define PRI_CTL_E_LENGTH 4 +#define PRI_CTL_E_OFFSET 0x0100 +#define PRI_CTL_NR_E 6 + +#define PORT_PRI_EN "prctl_ptprien" +#define PRI_CTL_PORT_PRI_EN_BOFFSET 19 +#define PRI_CTL_PORT_PRI_EN_BLEN 1 +#define PRI_CTL_PORT_PRI_EN_FLAG HSL_RW + +#define DA_PRI_EN "prctl_daprien" +#define PRI_CTL_DA_PRI_EN_BOFFSET 18 +#define PRI_CTL_DA_PRI_EN_BLEN 1 +#define PRI_CTL_DA_PRI_EN_FLAG HSL_RW + +#define VLAN_PRI_EN "prctl_vprien" +#define PRI_CTL_VLAN_PRI_EN_BOFFSET 17 +#define PRI_CTL_VLAN_PRI_EN_BLEN 1 +#define PRI_CTL_VLAN_PRI_EN_FLAG HSL_RW + +#define IP_PRI_EN "prctl_ipprien" +#define PRI_CTL_IP_PRI_EN_BOFFSET 16 +#define PRI_CTL_IP_PRI_EN_BLEN 1 +#define PRI_CTL_IP_PRI_EN_FLAG HSL_RW + +#define DA_PRI_SEL "prctl_dapris" +#define PRI_CTL_DA_PRI_SEL_BOFFSET 6 +#define PRI_CTL_DA_PRI_SEL_BLEN 2 +#define PRI_CTL_DA_PRI_SEL_FLAG HSL_RW + +#define VLAN_PRI_SEL "prctl_vpris" +#define PRI_CTL_VLAN_PRI_SEL_BOFFSET 4 +#define PRI_CTL_VLAN_PRI_SEL_BLEN 2 +#define PRI_CTL_VLAN_PRI_SEL_FLAG HSL_RW + +#define IP_PRI_SEL "prctl_ippris" +#define PRI_CTL_IP_PRI_SEL_BOFFSET 2 +#define PRI_CTL_IP_PRI_SEL_BLEN 2 +#define PRI_CTL_IP_PRI_SEL_FLAG HSL_RW + +#define PORT_PRI_SEL "prctl_ptpris" +#define PRI_CTL_PORT_PRI_SEL_BOFFSET 0 +#define PRI_CTL_PORT_PRI_SEL_BLEN 2 +#define PRI_CTL_PORT_PRI_SEL_FLAG HSL_RW + + +//mib memory info +#define MIB_RXBROAD "RxBroad" +#define MIB_RXBROAD_ID 34 +#define MIB_RXBROAD_OFFSET 0x19000 +#define MIB_RXBROAD_E_LENGTH 4 +#define MIB_RXBROAD_E_OFFSET 0xa0 +#define MIB_RXBROAD_NR_E 6 + +#define MIB_RXPAUSE "RxPause" +#define MIB_RXPAUSE_ID 35 +#define MIB_RXPAUSE_OFFSET 0x19004 +#define MIB_RXPAUSE_E_LENGTH 4 +#define MIB_RXPAUSE_E_OFFSET 0xa0 +#define MIB_RXPAUSE_NR_E 6 + +#define MIB_RXMULTI "RxMulti" +#define MIB_RXMULTI_ID 36 +#define MIB_RXMULTI_OFFSET 0x19008 +#define MIB_RXMULTI_E_LENGTH 4 +#define MIB_RXMULTI_E_OFFSET 0xa0 +#define MIB_RXMULTI_NR_E 6 + +#define MIB_RXFCSERR "RxFcsErr" +#define MIB_RXFCSERR_ID 37 +#define MIB_RXFCSERR_OFFSET 0x1900C +#define MIB_RXFCSERR_E_LENGTH 4 +#define MIB_RXFCSERR_E_OFFSET 0xa0 +#define MIB_RXFCSERR_NR_E 6 + +#define MIB_RXALLIGNERR "RxAllignErr" +#define MIB_RXALLIGNERR_ID 38 +#define MIB_RXALLIGNERR_OFFSET 0x19010 +#define MIB_RXALLIGNERR_E_LENGTH 4 +#define MIB_RXALLIGNERR_E_OFFSET 0xa0 +#define MIB_RXALLIGNERR_NR_E 6 + +#define MIB_RXRUNT "RxRunt" +#define MIB_RXRUNT_ID 39 +#define MIB_RXRUNT_OFFSET 0x19014 +#define MIB_RXRUNT_E_LENGTH 4 +#define MIB_RXRUNT_E_OFFSET 0xa0 +#define MIB_RXRUNT_NR_E 6 + +#define MIB_RXFRAGMENT "RxFragment" +#define MIB_RXFRAGMENT_ID 40 +#define MIB_RXFRAGMENT_OFFSET 0x19018 +#define MIB_RXFRAGMENT_E_LENGTH 4 +#define MIB_RXFRAGMENT_E_OFFSET 0xa0 +#define MIB_RXFRAGMENT_NR_E 6 + +#define MIB_RX64BYTE "Rx64Byte" +#define MIB_RX64BYTE_ID 41 +#define MIB_RX64BYTE_OFFSET 0x1901C +#define MIB_RX64BYTE_E_LENGTH 4 +#define MIB_RX64BYTE_E_OFFSET 0xa0 +#define MIB_RX64BYTE_NR_E 6 + +#define MIB_RX128BYTE "Rx128Byte" +#define MIB_RX128BYTE_ID 42 +#define MIB_RX128BYTE_OFFSET 0x19020 +#define MIB_RX128BYTE_E_LENGTH 4 +#define MIB_RX128BYTE_E_OFFSET 0xa0 +#define MIB_RX128BYTE_NR_E 6 + +#define MIB_RX256BYTE "Rx256Byte" +#define MIB_RX256BYTE_ID 43 +#define MIB_RX256BYTE_OFFSET 0x19024 +#define MIB_RX256BYTE_E_LENGTH 4 +#define MIB_RX256BYTE_E_OFFSET 0xa0 +#define MIB_RX256BYTE_NR_E 6 + +#define MIB_RX512BYTE "Rx512Byte" +#define MIB_RX512BYTE_ID 44 +#define MIB_RX512BYTE_OFFSET 0x19028 +#define MIB_RX512BYTE_E_LENGTH 4 +#define MIB_RX512BYTE_E_OFFSET 0xa0 +#define MIB_RX512BYTE_NR_E 6 + +#define MIB_RX1024BYTE "Rx1024Byte" +#define MIB_RX1024BYTE_ID 45 +#define MIB_RX1024BYTE_OFFSET 0x1902C +#define MIB_RX1024BYTE_E_LENGTH 4 +#define MIB_RX1024BYTE_E_OFFSET 0xa0 +#define MIB_RX1024BYTE_NR_E 6 + +#define MIB_RX1518BYTE "Rx1518Byte" //reserved for s16 + +#define MIB_RXMAXBYTE "RxMaxByte" +#define MIB_RXMAXBYTE_ID 46 +#define MIB_RXMAXBYTE_OFFSET 0x19030 +#define MIB_RXMAXBYTE_E_LENGTH 4 +#define MIB_RXMAXBYTE_E_OFFSET 0xa0 +#define MIB_RXMAXBYTE_NR_E 6 + +#define MIB_RXTOOLONG "RxTooLong" +#define MIB_RXTOOLONG_ID 47 +#define MIB_RXTOOLONG_OFFSET 0x19034 +#define MIB_RXTOOLONG_E_LENGTH 4 +#define MIB_RXTOOLONG_E_OFFSET 0xa0 +#define MIB_RXTOOLONG_NR_E 6 + +#define MIB_RXGOODBYTE_LO "RxGoodByteLo" +#define MIB_RXGOODBYTE_LO_ID 48 +#define MIB_RXGOODBYTE_LO_OFFSET 0x19038 +#define MIB_RXGOODBYTE_LO_E_LENGTH 4 +#define MIB_RXGOODBYTE_LO_E_OFFSET 0xa0 +#define MIB_RXGOODBYTE_LO_NR_E 6 + +#define MIB_RXGOODBYTE_HI "RxGoodByteHi" +#define MIB_RXGOODBYTE_HI_ID 49 +#define MIB_RXGOODBYTE_HI_OFFSET 0x1903C +#define MIB_RXGOODBYTE_HI_E_LENGTH 4 +#define MIB_RXGOODBYTE_HI_E_OFFSET 0xa0 +#define MIB_RXGOODBYTE_HI_NR_E 6 + +#define MIB_RXBADBYTE_LO "RxBadByteLo" +#define MIB_RXBADBYTE_LO_ID 50 +#define MIB_RXBADBYTE_LO_OFFSET 0x19040 +#define MIB_RXBADBYTE_LO_E_LENGTH 4 +#define MIB_RXBADBYTE_LO_E_OFFSET 0xa0 +#define MIB_RXBADBYTE_LO_NR_E 6 + +#define MIB_RXBADBYTE_HI "RxBadByteHi" +#define MIB_RXBADBYTE_HI_ID 51 +#define MIB_RXBADBYTE_HI_OFFSET 0x19044 +#define MIB_RXBADBYTE_HI_E_LENGTH 4 +#define MIB_RXBADBYTE_HI_E_OFFSET 0xa0 +#define MIB_RXBADBYTE_HI_NR_E 6 + +#define MIB_RXOVERFLOW "RxOverFlow" +#define MIB_RXOVERFLOW_ID 52 +#define MIB_RXOVERFLOW_OFFSET 0x19048 +#define MIB_RXOVERFLOW_E_LENGTH 4 +#define MIB_RXOVERFLOW_E_OFFSET 0xa0 +#define MIB_RXOVERFLOW_NR_E 6 + +#define MIB_FILTERED "Filtered" +#define MIB_FILTERED_ID 53 +#define MIB_FILTERED_OFFSET 0x1904C +#define MIB_FILTERED_E_LENGTH 4 +#define MIB_FILTERED_E_OFFSET 0xa0 +#define MIB_FILTERED_NR_E 6 + +#define MIB_TXBROAD "TxBroad" +#define MIB_TXBROAD_ID 54 +#define MIB_TXBROAD_OFFSET 0x19050 +#define MIB_TXBROAD_E_LENGTH 4 +#define MIB_TXBROAD_E_OFFSET 0xa0 +#define MIB_TXBROAD_NR_E 6 + +#define MIB_TXPAUSE "TxPause" +#define MIB_TXPAUSE_ID 55 +#define MIB_TXPAUSE_OFFSET 0x19054 +#define MIB_TXPAUSE_E_LENGTH 4 +#define MIB_TXPAUSE_E_OFFSET 0xa0 +#define MIB_TXPAUSE_NR_E 6 + +#define MIB_TXMULTI "TxMulti" +#define MIB_TXMULTI_ID 56 +#define MIB_TXMULTI_OFFSET 0x19058 +#define MIB_TXMULTI_E_LENGTH 4 +#define MIB_TXMULTI_E_OFFSET 0xa0 +#define MIB_TXMULTI_NR_E 6 + +#define MIB_TXUNDERRUN "TxUnderRun" +#define MIB_TXUNDERRUN_ID 57 +#define MIB_TXUNDERRUN_OFFSET 0x1905C +#define MIB_TXUNDERRUN_E_LENGTH 4 +#define MIB_TXUNDERRUN_E_OFFSET 0xa0 +#define MIB_TXUNDERRUN_NR_E 6 + +#define MIB_TX64BYTE "Tx64Byte" +#define MIB_TX64BYTE_ID 58 +#define MIB_TX64BYTE_OFFSET 0x19060 +#define MIB_TX64BYTE_E_LENGTH 4 +#define MIB_TX64BYTE_E_OFFSET 0xa0 +#define MIB_TX64BYTE_NR_E 6 + +#define MIB_TX128BYTE "Tx128Byte" +#define MIB_TX128BYTE_ID 59 +#define MIB_TX128BYTE_OFFSET 0x19064 +#define MIB_TX128BYTE_E_LENGTH 4 +#define MIB_TX128BYTE_E_OFFSET 0xa0 +#define MIB_TX128BYTE_NR_E 6 + +#define MIB_TX256BYTE "Tx256Byte" +#define MIB_TX256BYTE_ID 60 +#define MIB_TX256BYTE_OFFSET 0x19068 +#define MIB_TX256BYTE_E_LENGTH 4 +#define MIB_TX256BYTE_E_OFFSET 0xa0 +#define MIB_TX256BYTE_NR_E 6 + +#define MIB_TX512BYTE "Tx512Byte" +#define MIB_TX512BYTE_ID 61 +#define MIB_TX512BYTE_OFFSET 0x1906C +#define MIB_TX512BYTE_E_LENGTH 4 +#define MIB_TX512BYTE_E_OFFSET 0xa0 +#define MIB_TX512BYTE_NR_E 6 + +#define MIB_TX1024BYTE "Tx1024Byte" +#define MIB_TX1024BYTE_ID 62 +#define MIB_TX1024BYTE_OFFSET 0x19070 +#define MIB_TX1024BYTE_E_LENGTH 4 +#define MIB_TX1024BYTE_E_OFFSET 0xa0 +#define MIB_TX1024BYTE_NR_E 6 + +#define MIB_TX1518BYTE "Tx1518Byte" //reserved for s16 + +#define MIB_TXMAXBYTE "TxMaxByte" +#define MIB_TXMAXBYTE_ID 63 +#define MIB_TXMAXBYTE_OFFSET 0x19074 +#define MIB_TXMAXBYTE_E_LENGTH 4 +#define MIB_TXMAXBYTE_E_OFFSET 0xa0 +#define MIB_TXMAXBYTE_NR_E 6 + +#define MIB_TXOVERSIZE "TxOverSize" +#define MIB_TXOVERSIZE_ID 64 +#define MIB_TXOVERSIZE_OFFSET 0x19078 +#define MIB_TXOVERSIZE_E_LENGTH 4 +#define MIB_TXOVERSIZE_E_OFFSET 0xa0 +#define MIB_TXOVERSIZE_NR_E 6 + +#define MIB_TXBYTE_LO "TxByteLo" +#define MIB_TXBYTE_LO_ID 65 +#define MIB_TXBYTE_LO_OFFSET 0x1907C +#define MIB_TXBYTE_LO_E_LENGTH 4 +#define MIB_TXBYTE_LO_E_OFFSET 0xa0 +#define MIB_TXBYTE_LO_NR_E 6 + +#define MIB_TXBYTE_HI "TxByteHi" +#define MIB_TXBYTE_HI_ID 66 +#define MIB_TXBYTE_HI_OFFSET 0x19080 +#define MIB_TXBYTE_HI_E_LENGTH 4 +#define MIB_TXBYTE_HI_E_OFFSET 0xa0 +#define MIB_TXBYTE_HI_NR_E 6 + +#define MIB_TXCOLLISION "TxCollision" +#define MIB_TXCOLLISION_ID 67 +#define MIB_TXCOLLISION_OFFSET 0x19084 +#define MIB_TXCOLLISION_E_LENGTH 4 +#define MIB_TXCOLLISION_E_OFFSET 0xa0 +#define MIB_TXCOLLISION_NR_E 6 + +#define MIB_TXABORTCOL "TxAbortCol" +#define MIB_TXABORTCOL_ID 68 +#define MIB_TXABORTCOL_OFFSET 0x19088 +#define MIB_TXABORTCOL_E_LENGTH 4 +#define MIB_TXABORTCOL_E_OFFSET 0xa0 +#define MIB_TXABORTCOL_NR_E 6 + +#define MIB_TXMULTICOL "TxMultiCol" +#define MIB_TXMULTICOL_ID 69 +#define MIB_TXMULTICOL_OFFSET 0x1908C +#define MIB_TXMULTICOL_E_LENGTH 4 +#define MIB_TXMULTICOL_E_OFFSET 0xa0 +#define MIB_TXMULTICOL_NR_E 6 + +#define MIB_TXSINGALCOL "TxSingalCol" +#define MIB_TXSINGALCOL_ID 70 +#define MIB_TXSINGALCOL_OFFSET 0x19090 +#define MIB_TXSINGALCOL_E_LENGTH 4 +#define MIB_TXSINGALCOL_E_OFFSET 0xa0 +#define MIB_TXSINGALCOL_NR_E 6 + +#define MIB_TXEXCDEFER "TxExcDefer" +#define MIB_TXEXCDEFER_ID 71 +#define MIB_TXEXCDEFER_OFFSET 0x19094 +#define MIB_TXEXCDEFER_E_LENGTH 4 +#define MIB_TXEXCDEFER_E_OFFSET 0xa0 +#define MIB_TXEXCDEFER_NR_E 6 + +#define MIB_TXDEFER "TxDefer" +#define MIB_TXDEFER_ID 72 +#define MIB_TXDEFER_OFFSET 0x19098 +#define MIB_TXDEFER_E_LENGTH 4 +#define MIB_TXDEFER_E_OFFSET 0xa0 +#define MIB_TXDEFER_NR_E 6 + +#define MIB_TXLATECOL "TxLateCol" +#define MIB_TXLATECOL_ID 73 +#define MIB_TXLATECOL_OFFSET 0x1909C +#define MIB_TXLATECOL_E_LENGTH 4 +#define MIB_TXLATECOL_E_OFFSET 0xa0 +#define MIB_TXLATECOL_NR_E 6 + +//second mem block +#define MIB_RXBROAD_2 "RxBroad_2" +#define MIB_RXBROAD_2_ID 34 +#define MIB_RXBROAD_2_OFFSET (MIB_RXBROAD_OFFSET + 0x400) +#define MIB_RXBROAD_2_E_LENGTH 4 +#define MIB_RXBROAD_2_E_OFFSET 0xa0 +#define MIB_RXBROAD_2_NR_E 6 + +#define MIB_RXPAUSE_2 "RxPause_2" +#define MIB_RXPAUSE_2_ID 35 +#define MIB_RXPAUSE_2_OFFSET (MIB_RXPAUSE_OFFSET + 0x400) +#define MIB_RXPAUSE_2_E_LENGTH 4 +#define MIB_RXPAUSE_2_E_OFFSET 0xa0 +#define MIB_RXPAUSE_2_NR_E 6 + +#define MIB_RXMULTI_2 "RxMulti_2" +#define MIB_RXMULTI_2_ID 36 +#define MIB_RXMULTI_2_OFFSET (MIB_RXMULTI_OFFSET + 0x400) +#define MIB_RXMULTI_2_E_LENGTH 4 +#define MIB_RXMULTI_2_E_OFFSET 0xa0 +#define MIB_RXMULTI_2_NR_E 6 + +#define MIB_RXFCSERR_2 "RxFcsErr_2" +#define MIB_RXFCSERR_2_ID 37 +#define MIB_RXFCSERR_2_OFFSET (MIB_RXFCSERR_OFFSET + 0x400) +#define MIB_RXFCSERR_2_E_LENGTH 4 +#define MIB_RXFCSERR_2_E_OFFSET 0xa0 +#define MIB_RXFCSERR_2_NR_E 6 + +#define MIB_RXALLIGNERR_2 "RxAllignErr_2" +#define MIB_RXALLIGNERR_2_ID 38 +#define MIB_RXALLIGNERR_2_OFFSET (MIB_RXALLIGNERR_OFFSET + 0x400) +#define MIB_RXALLIGNERR_2_E_LENGTH 4 +#define MIB_RXALLIGNERR_2_E_OFFSET 0xa0 +#define MIB_RXALLIGNERR_2_NR_E 6 + +#define MIB_RXRUNT_2 "RxRunt_2" +#define MIB_RXRUNT_2_ID 39 +#define MIB_RXRUNT_2_OFFSET (MIB_RXRUNT_OFFSET + 0x400) +#define MIB_RXRUNT_2_E_LENGTH 4 +#define MIB_RXRUNT_2_E_OFFSET 0xa0 +#define MIB_RXRUNT_2_NR_E 6 + +#define MIB_RXFRAGMENT_2 "RxFragment_2" +#define MIB_RXFRAGMENT_2_ID 40 +#define MIB_RXFRAGMENT_2_OFFSET (MIB_RXFRAGMENT_OFFSET + 0x400) +#define MIB_RXFRAGMENT_2_E_LENGTH 4 +#define MIB_RXFRAGMENT_2_E_OFFSET 0xa0 +#define MIB_RXFRAGMENT_2_NR_E 6 + +#define MIB_RX64BYTE_2 "Rx64Byte_2" +#define MIB_RX64BYTE_2_ID 41 +#define MIB_RX64BYTE_2_OFFSET (MIB_RX64BYTE_OFFSET + 0x400) +#define MIB_RX64BYTE_2_E_LENGTH 4 +#define MIB_RX64BYTE_2_E_OFFSET 0xa0 +#define MIB_RX64BYTE_2_NR_E 6 + +#define MIB_RX128BYTE_2 "Rx128Byte_2" +#define MIB_RX128BYTE_2_ID 42 +#define MIB_RX128BYTE_2_OFFSET (MIB_RX128BYTE_OFFSET + 0x400) +#define MIB_RX128BYTE_2_E_LENGTH 4 +#define MIB_RX128BYTE_2_E_OFFSET 0xa0 +#define MIB_RX128BYTE_2_NR_E 6 + +#define MIB_RX256BYTE_2 "Rx256Byte_2" +#define MIB_RX256BYTE_2_ID 43 +#define MIB_RX256BYTE_2_OFFSET (MIB_RX256BYTE_OFFSET + 0x400) +#define MIB_RX256BYTE_2_E_LENGTH 4 +#define MIB_RX256BYTE_2_E_OFFSET 0xa0 +#define MIB_RX256BYTE_2_NR_E 6 + +#define MIB_RX512BYTE_2 "Rx512Byte_2" +#define MIB_RX512BYTE_2_ID 44 +#define MIB_RX512BYTE_2_OFFSET (MIB_RX512BYTE_OFFSET + 0x400) +#define MIB_RX512BYTE_2_E_LENGTH 4 +#define MIB_RX512BYTE_2_E_OFFSET 0xa0 +#define MIB_RX512BYTE_2_NR_E 6 + +#define MIB_RX1024BYTE_2 "Rx1024Byte_2" +#define MIB_RX1024BYTE_2_ID 45 +#define MIB_RX1024BYTE_2_OFFSET (MIB_RX1024BYTE_OFFSET + 0x400) +#define MIB_RX1024BYTE_2_E_LENGTH 4 +#define MIB_RX1024BYTE_2_E_OFFSET 0xa0 +#define MIB_RX1024BYTE_2_NR_E 6 + +#define MIB_RXMAXBYTE_2 "RxMaxByte_2" +#define MIB_RXMAXBYTE_2_ID 46 +#define MIB_RXMAXBYTE_2_OFFSET (MIB_RXMAXBYTE_OFFSET + 0x400) +#define MIB_RXMAXBYTE_2_E_LENGTH 4 +#define MIB_RXMAXBYTE_2_E_OFFSET 0xa0 +#define MIB_RXMAXBYTE_2_NR_E 6 + +#define MIB_RXTOOLONG_2 "RxTooLong_2" +#define MIB_RXTOOLONG_2_ID 47 +#define MIB_RXTOOLONG_2_OFFSET (MIB_RXTOOLONG_OFFSET + 0x400) +#define MIB_RXTOOLONG_2_E_LENGTH 4 +#define MIB_RXTOOLONG_2_E_OFFSET 0xa0 +#define MIB_RXTOOLONG_2_NR_E 6 + +#define MIB_RXGOODBYTE_LO_2 "RxGoodByteLo_2" +#define MIB_RXGOODBYTE_LO_2_ID 48 +#define MIB_RXGOODBYTE_LO_2_OFFSET (MIB_RXGOODBYTE_LO_OFFSET + 0x400) +#define MIB_RXGOODBYTE_LO_2_E_LENGTH 4 +#define MIB_RXGOODBYTE_LO_2_E_OFFSET 0xa0 +#define MIB_RXGOODBYTE_LO_2_NR_E 6 + +#define MIB_RXGOODBYTE_HI_2 "RxGoodByteHi_2" +#define MIB_RXGOODBYTE_HI_2_ID 49 +#define MIB_RXGOODBYTE_HI_2_OFFSET (MIB_RXGOODBYTE_HI_OFFSET + 0x400) +#define MIB_RXGOODBYTE_HI_2_E_LENGTH 4 +#define MIB_RXGOODBYTE_HI_2_E_OFFSET 0xa0 +#define MIB_RXGOODBYTE_HI_2_NR_E 6 + +#define MIB_RXBADBYTE_LO_2 "RxBadByteLo_2" +#define MIB_RXBADBYTE_LO_2_ID 50 +#define MIB_RXBADBYTE_LO_2_OFFSET (MIB_RXBADBYTE_LO_OFFSET + 0x400) +#define MIB_RXBADBYTE_LO_2_E_LENGTH 4 +#define MIB_RXBADBYTE_LO_2_E_OFFSET 0xa0 +#define MIB_RXBADBYTE_LO_2_NR_E 6 + +#define MIB_RXBADBYTE_HI_2 "RxBadByteHi_2" +#define MIB_RXBADBYTE_HI_2_ID 51 +#define MIB_RXBADBYTE_HI_2_OFFSET (MIB_RXBADBYTE_HI_OFFSET + 0x400) +#define MIB_RXBADBYTE_HI_2_E_LENGTH 4 +#define MIB_RXBADBYTE_HI_2_E_OFFSET 0xa0 +#define MIB_RXBADBYTE_HI_2_NR_E 6 + +#define MIB_RXOVERFLOW_2 "RxOverFlow_2" +#define MIB_RXOVERFLOW_2_ID 52 +#define MIB_RXOVERFLOW_2_OFFSET (MIB_RXOVERFLOW_OFFSET + 0x400) +#define MIB_RXOVERFLOW_2_E_LENGTH 4 +#define MIB_RXOVERFLOW_2_E_OFFSET 0xa0 +#define MIB_RXOVERFLOW_2_NR_E 6 + +#define MIB_FILTERED_2 "Filtered_2" +#define MIB_FILTERED_2_ID 53 +#define MIB_FILTERED_2_OFFSET (MIB_FILTERED_OFFSET + 0x400) +#define MIB_FILTERED_2_E_LENGTH 4 +#define MIB_FILTERED_2_E_OFFSET 0xa0 +#define MIB_FILTERED_2_NR_E 6 + +#define MIB_TXBROAD_2 "TxBroad_2" +#define MIB_TXBROAD_2_ID 54 +#define MIB_TXBROAD_2_OFFSET (MIB_TXBROAD_OFFSET + 0x400) +#define MIB_TXBROAD_2_E_LENGTH 4 +#define MIB_TXBROAD_2_E_OFFSET 0xa0 +#define MIB_TXBROAD_2_NR_E 6 + +#define MIB_TXPAUSE_2 "TxPause_2" +#define MIB_TXPAUSE_2_ID 55 +#define MIB_TXPAUSE_2_OFFSET (MIB_TXPAUSE_OFFSET + 0x400) +#define MIB_TXPAUSE_2_E_LENGTH 4 +#define MIB_TXPAUSE_2_E_OFFSET 0xa0 +#define MIB_TXPAUSE_2_NR_E 6 + +#define MIB_TXMULTI_2 "TxMulti_2" +#define MIB_TXMULTI_2_ID 56 +#define MIB_TXMULTI_2_OFFSET (MIB_TXMULTI_OFFSET + 0x400) +#define MIB_TXMULTI_2_E_LENGTH 4 +#define MIB_TXMULTI_2_E_OFFSET 0xa0 +#define MIB_TXMULTI_2_NR_E 6 + +#define MIB_TXUNDERRUN_2 "TxUnderRun_2" +#define MIB_TXUNDERRUN_2_ID 57 +#define MIB_TXUNDERRUN_2_OFFSET (MIB_TXUNDERRUN_OFFSET + 0x400) +#define MIB_TXUNDERRUN_2_E_LENGTH 4 +#define MIB_TXUNDERRUN_2_E_OFFSET 0xa0 +#define MIB_TXUNDERRUN_2_NR_E 6 + +#define MIB_TX64BYTE_2 "Tx64Byte_2" +#define MIB_TX64BYTE_2_ID 58 +#define MIB_TX64BYTE_2_OFFSET (MIB_TX64BYTE_OFFSET + 0x400) +#define MIB_TX64BYTE_2_E_LENGTH 4 +#define MIB_TX64BYTE_2_E_OFFSET 0xa0 +#define MIB_TX64BYTE_2_NR_E 6 + +#define MIB_TX128BYTE_2 "Tx128Byte_2" +#define MIB_TX128BYTE_2_ID 59 +#define MIB_TX128BYTE_2_OFFSET (MIB_TX128BYTE_OFFSET + 0x400) +#define MIB_TX128BYTE_2_E_LENGTH 4 +#define MIB_TX128BYTE_2_E_OFFSET 0xa0 +#define MIB_TX128BYTE_2_NR_E 6 + +#define MIB_TX256BYTE_2 "Tx256Byte_2" +#define MIB_TX256BYTE_2_ID 60 +#define MIB_TX256BYTE_2_OFFSET (MIB_TX256BYTE_OFFSET + 0x400) +#define MIB_TX256BYTE_2_E_LENGTH 4 +#define MIB_TX256BYTE_2_E_OFFSET 0xa0 +#define MIB_TX256BYTE_2_NR_E 6 + +#define MIB_TX512BYTE_2 "Tx512Byte_2" +#define MIB_TX512BYTE_2_ID 61 +#define MIB_TX512BYTE_2_OFFSET (MIB_TX512BYTE_OFFSET + 0x400) +#define MIB_TX512BYTE_2_E_LENGTH 4 +#define MIB_TX512BYTE_2_E_OFFSET 0xa0 +#define MIB_TX512BYTE_2_NR_E 6 + +#define MIB_TX1024BYTE_2 "Tx1024Byte_2" +#define MIB_TX1024BYTE_2_ID 62 +#define MIB_TX1024BYTE_2_OFFSET (MIB_TX1024BYTE_OFFSET + 0x400) +#define MIB_TX1024BYTE_2_E_LENGTH 4 +#define MIB_TX1024BYTE_2_E_OFFSET 0xa0 +#define MIB_TX1024BYTE_2_NR_E 6 + +#define MIB_TXMAXBYTE_2 "TxMaxByte_2" +#define MIB_TXMAXBYTE_2_ID 63 +#define MIB_TXMAXBYTE_2_OFFSET (MIB_TXMAXBYTE_OFFSET + 0x400) +#define MIB_TXMAXBYTE_2_E_LENGTH 4 +#define MIB_TXMAXBYTE_2_E_OFFSET 0xa0 +#define MIB_TXMAXBYTE_2_NR_E 6 + +#define MIB_TXOVERSIZE_2 "TxOverSize_2" +#define MIB_TXOVERSIZE_2_ID 64 +#define MIB_TXOVERSIZE_2_OFFSET (MIB_TXOVERSIZE_OFFSET + 0x400) +#define MIB_TXOVERSIZE_2_E_LENGTH 4 +#define MIB_TXOVERSIZE_2_E_OFFSET 0xa0 +#define MIB_TXOVERSIZE_2_NR_E 6 + +#define MIB_TXBYTE_LO_2 "TxByteLo_2" +#define MIB_TXBYTE_LO_2_ID 65 +#define MIB_TXBYTE_LO_2_OFFSET (MIB_TXBYTE_LO_OFFSET + 0x400) +#define MIB_TXBYTE_LO_2_E_LENGTH 4 +#define MIB_TXBYTE_LO_2_E_OFFSET 0xa0 +#define MIB_TXBYTE_LO_2_NR_E 6 + +#define MIB_TXBYTE_HI_2 "TxByteHi_2" +#define MIB_TXBYTE_HI_2_ID 66 +#define MIB_TXBYTE_HI_2_OFFSET (MIB_TXBYTE_HI_OFFSET + 0x400) +#define MIB_TXBYTE_HI_2_E_LENGTH 4 +#define MIB_TXBYTE_HI_2_E_OFFSET 0xa0 +#define MIB_TXBYTE_HI_2_NR_E 6 + +#define MIB_TXCOLLISION_2 "TxCollision_2" +#define MIB_TXCOLLISION_2_ID 67 +#define MIB_TXCOLLISION_2_OFFSET (MIB_TXCOLLISION_OFFSET + 0x400) +#define MIB_TXCOLLISION_2_E_LENGTH 4 +#define MIB_TXCOLLISION_2_E_OFFSET 0xa0 +#define MIB_TXCOLLISION_2_NR_E 6 + +#define MIB_TXABORTCOL_2 "TxAbortCol_2" +#define MIB_TXABORTCOL_2_ID 68 +#define MIB_TXABORTCOL_2_OFFSET (MIB_TXABORTCOL_OFFSET + 0x400) +#define MIB_TXABORTCOL_2_E_LENGTH 4 +#define MIB_TXABORTCOL_2_E_OFFSET 0xa0 +#define MIB_TXABORTCOL_2_NR_E 6 + +#define MIB_TXMULTICOL_2 "TxMultiCol_2" +#define MIB_TXMULTICOL_2_ID 69 +#define MIB_TXMULTICOL_2_OFFSET (MIB_TXMULTICOL_OFFSET + 0x400) +#define MIB_TXMULTICOL_2_E_LENGTH 4 +#define MIB_TXMULTICOL_2_E_OFFSET 0xa0 +#define MIB_TXMULTICOL_2_NR_E 6 + +#define MIB_TXSINGALCOL_2 "TxSingalCol_2" +#define MIB_TXSINGALCOL_2_ID 70 +#define MIB_TXSINGALCOL_2_OFFSET (MIB_TXSINGALCOL_OFFSET + 0x400) +#define MIB_TXSINGALCOL_2_E_LENGTH 4 +#define MIB_TXSINGALCOL_2_E_OFFSET 0xa0 +#define MIB_TXSINGALCOL_2_NR_E 6 + +#define MIB_TXEXCDEFER_2 "TxExcDefer_2" +#define MIB_TXEXCDEFER_2_ID 71 +#define MIB_TXEXCDEFER_2_OFFSET (MIB_TXEXCDEFER_OFFSET + 0x400) +#define MIB_TXEXCDEFER_2_E_LENGTH 4 +#define MIB_TXEXCDEFER_2_E_OFFSET 0xa0 +#define MIB_TXEXCDEFER_2_NR_E 6 + +#define MIB_TXDEFER_2 "TxDefer_2" +#define MIB_TXDEFER_2_ID 72 +#define MIB_TXDEFER_2_OFFSET (MIB_TXDEFER_OFFSET + 0x400) +#define MIB_TXDEFER_2_E_LENGTH 4 +#define MIB_TXDEFER_2_E_OFFSET 0xa0 +#define MIB_TXDEFER_2_NR_E 6 + +#define MIB_TXLATECOL_2 "TxLateCol_2" +#define MIB_TXLATECOL_2_ID 73 +#define MIB_TXLATECOL_2_OFFSET (MIB_TXLATECOL_OFFSET + 0x400) +#define MIB_TXLATECOL_2_E_LENGTH 4 +#define MIB_TXLATECOL_2_E_OFFSET 0xa0 +#define MIB_TXLATECOL_2_NR_E 6 + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _ATHENA_REG_H */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_reg_access.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_reg_access.h new file mode 100755 index 000000000..60f4b2822 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_reg_access.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2012,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 _ATHENA_REG_ACCESS_H_ +#define _ATHENA_REG_ACCESS_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "sw.h" + + sw_error_t + athena_phy_get(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t * value); + + sw_error_t + athena_phy_set(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t value); + + sw_error_t + athena_reg_get(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t value[], + a_uint32_t value_len); + + sw_error_t + athena_reg_set(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t value[], + a_uint32_t value_len); + + sw_error_t + athena_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 + athena_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 + athena_reg_access_init(a_uint32_t dev_id, hsl_access_mode mode); + + sw_error_t + athena_access_mode_set(a_uint32_t dev_id, hsl_access_mode mode); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _ATHENA_REG_ACCESS_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_vlan.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_vlan.h new file mode 100755 index 000000000..5e97c72ce --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/athena/athena_vlan.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ATHENA_VLAN_H +#define _ATHENA_VLAN_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_vlan.h" + + sw_error_t + athena_vlan_reset(a_uint32_t dev_id); + + sw_error_t + athena_vlan_init(a_uint32_t dev_id); + + sw_error_t + athena_vlan_cleanup(a_uint32_t dev_id); + +#ifdef IN_VLAN +#define ATHENA_VLAN_RESET(rv, dev_id) \ + { \ + rv = athena_vlan_reset(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } + +#define ATHENA_VLAN_INIT(rv, dev_id) \ + { \ + rv = athena_vlan_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } + +#define ATHENA_VLAN_CLEANUP(rv, dev_id) \ + { \ + rv = athena_vlan_cleanup(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ATHENA_VLAN_RESET(rv, dev_id) +#define ATHENA_VLAN_INIT(rv, dev_id) +#define ATHENA_VLAN_CLEANUP(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + athena_vlan_entry_append(a_uint32_t dev_id, const fal_vlan_t * vlan_entry); + + + + HSL_LOCAL sw_error_t + athena_vlan_create(a_uint32_t dev_id, a_uint32_t vlan_id); + + + + HSL_LOCAL sw_error_t + athena_vlan_next(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan); + + + + HSL_LOCAL sw_error_t + athena_vlan_find(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan); + + + + HSL_LOCAL sw_error_t + athena_vlan_member_update(a_uint32_t dev_id, a_uint32_t vlan_id, + fal_pbmp_t member, fal_pbmp_t u_member); + + + HSL_LOCAL sw_error_t + athena_vlan_delete(a_uint32_t dev_id, a_uint32_t vlan_id); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _ATHENA_VLAN_H */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/cppe/cppe_loopback.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/cppe/cppe_loopback.h new file mode 100755 index 000000000..ed9ff8c2f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/cppe/cppe_loopback.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. + */ +/** + * @defgroup + * @{ + */ +#ifndef _CPPE_LOOPBACK_H_ +#define _CPPE_LOOPBACK_H_ + +sw_error_t +cppe_lpbk_enable_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbk_enable_u *value); + +sw_error_t +cppe_lpbk_enable_set( + a_uint32_t dev_id, + a_uint32_t index, + union lpbk_enable_u *value); + +sw_error_t +cppe_lpbk_fifo_1_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbk_fifo_1_ctrl_u *value); + +sw_error_t +cppe_lpbk_fifo_1_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union lpbk_fifo_1_ctrl_u *value); + +sw_error_t +cppe_lpbk_fifo_2_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbk_fifo_2_ctrl_u *value); + +sw_error_t +cppe_lpbk_fifo_2_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union lpbk_fifo_2_ctrl_u *value); + +sw_error_t +cppe_lpbk_pps_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbk_pps_ctrl_u *value); + +sw_error_t +cppe_lpbk_pps_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union lpbk_pps_ctrl_u *value); + +sw_error_t +cppe_lpbk_mac_junmo_size_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbk_mac_junmo_size_u *value); + +sw_error_t +cppe_lpbk_mac_junmo_size_set( + a_uint32_t dev_id, + a_uint32_t index, + union lpbk_mac_junmo_size_u *value); + +sw_error_t +cppe_lpbk_mib_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbk_mib_ctrl_u *value); + +sw_error_t +cppe_lpbk_mib_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union lpbk_mib_ctrl_u *value); + +sw_error_t +cppe_lpbk_mib_uni_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbkuni_u *value); + +sw_error_t +cppe_lpbk_mib_multi_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbkmulti_u *value); + +sw_error_t +cppe_lpbk_mib_broad_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbkbroad_u *value); + +sw_error_t +cppe_lpbk_mib_pkt64_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbkpkt64_u *value); + +sw_error_t +cppe_lpbk_mib_pkt65to127_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbkpkt65to127_u *value); + +sw_error_t +cppe_lpbk_mib_pkt128to255_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbkpkt128to255_u *value); + +sw_error_t +cppe_lpbk_mib_pkt256to511_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbkpkt256to511_u *value); + +sw_error_t +cppe_lpbk_mib_pkt512to1023_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbkpkt512to1023_u *value); + +sw_error_t +cppe_lpbk_mib_pkt1024to1518_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbkpkt1024to1518_u *value); + +sw_error_t +cppe_lpbk_mib_pkt1519tox_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbkpkt1519tox_u *value); + +sw_error_t +cppe_lpbk_mib_toolong_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbkpkttoolong_u *value); + +sw_error_t +cppe_lpbk_mib_byte_l_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbkbyte_l_u *value); + +sw_error_t +cppe_lpbk_mib_byte_h_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbkbyte_h_u *value); + +sw_error_t +cppe_lpbk_mib_drop_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbkdropcounter_u *value); + +sw_error_t +cppe_lpbk_mib_tooshort_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbkpkttooshort_u *value); + +sw_error_t +cppe_lpbk_mib_pkt14to63_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbkpkt14to63_u *value); + +sw_error_t +cppe_lpbk_mib_toolongbyte_l_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbktoolongbyte_l_u *value); + +sw_error_t +cppe_lpbk_mib_toolongbyte_h_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbktoolongbyte_h_u *value); + + +sw_error_t +cppe_lpbk_mib_tooshortbyte_l_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbktooshortbyte_l_u *value); + +sw_error_t +cppe_lpbk_mib_tooshortbyte_h_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbktooshortbyte_h_u *value); +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/cppe/cppe_loopback_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/cppe/cppe_loopback_reg.h new file mode 100755 index 000000000..899e8cf67 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/cppe/cppe_loopback_reg.h @@ -0,0 +1,578 @@ +/* + * 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 + * @{ + */ +#ifndef CPPE_LOOPBACK_REG_H +#define CPPE_LOOPBACK_REG_H + +/*[register] LPBK_ENABLE*/ +#define LPBK_ENABLE +#define LPBK_ENABLE_ADDRESS 0x00 +#define LPBK_ENABLE_NUM 6 +#define LPBK_ENABLEL_INC 0x200 +#define LPBK_ENABLE_TYPE REG_TYPE_RW +#define LPBK_ENABLE_DEFAULT 0x0 + /*[field] LPBK_EN*/ + #define LPBK_EN_LPBK_EN + #define LPBK_EN_LPBK_EN_OFFSET 0 + #define LPBK_EN_LPBK_EN_LEN 1 + #define LLPBK_EN_LPBK_EN_DEFAULT 0x0 + /*[field] FLOWCTRL_EN*/ + #define LPBK_ENABLE_FLOWCTRL_EN + #define LPBK_ENABLE_FLOWCTRL_EN_OFFSET 1 + #define LPBK_ENABLE_FLOWCTRL_EN_LEN 1 + #define LPBK_ENABLE_FLOWCTRL_EN_DEFAULT 0x1 + /*[field] FLOWCTRL_MODE*/ + #define LPBK_EN_FLOWCTRL_MODE + #define LPBK_EN_FLOWCTRL_MODE_OFFSET 2 + #define LPBK_EN_FLOWCTRL_MODE_LEN 1 + #define LPBK_EN_FLOWCTRL_MODE_DEFAULT 0x0 + /*[field] CRC_STRIP_EN*/ + #define LPBK_EN_CRC_STRIP_EN + #define LPBK_EN_CRC_STRIP_EN_OFFSET 2 + #define LPBK_EN_CRC_STRIP_EN_LEN 1 + #define LPBK_EN_CRC_STRIP_EN_DEFAULT 0x1 +struct lpbk_enable { + a_uint32_t lpbk_en:1; + a_uint32_t flowctrl_en :1; + a_uint32_t flowctrl_mode:1; + a_uint32_t crc_strip_en:1; + a_uint32_t _reserved0:28; +}; +union lpbk_enable_u { + a_uint32_t val; + struct lpbk_enable bf; +}; + +/*[register] LPBK_FIFO_1_CTRL*/ +#define LPBK_FIFO_1_CTRL +#define LPBK_FIFO_1_CTRL_ADDRESS 0x04 +#define LPBK_FIFO_1_CTRL_NUM 6 +#define LPBK_FIFO_1_CTRL_INC 0x200 +#define LPBK_FIFO_1_CTRL_TYPE REG_TYPE_RW +#define LPBK_FIFO_1_CTRL_DEFAULT 0x3 + /*[field] LPBK_FIFO_1_THRESHOLD*/ + #define LPBK_FIFO_1_CTRL_LPBK_FIFO_1_THRESHOLD + #define LPBK_FIFO_1_CTRL_LPBK_FIFO_1_THRESHOLD_OFFSET 0 + #define LPBK_FIFO_1_CTRL_LPBK_FIFO_1_THRESHOLD_LEN 3 + #define LPBK_FIFO_1_CTRL_LPBK_FIFO_1_THRESHOLD_DEFAULT 0x0 +struct lpbk_fifo_1_ctrl { + a_uint32_t lpbk_fifo_1_threshold:3; + a_uint32_t _reserved0:29; +}; +union lpbk_fifo_1_ctrl_u { + a_uint32_t val; + struct lpbk_fifo_1_ctrl bf; +}; + +/*[register] LPBK_FIFO_2_CTRL*/ +#define LPBK_FIFO_2_CTRL +#define LPBK_FIFO_2_CTRL_ADDRESS 0x08 +#define LPBK_FIFO_2_CTRL_NUM 6 +#define LPBK_FIFO_2_CTRL_INC 0x200 +#define LPBK_FIFO_2_CTRL_TYPE REG_TYPE_RW +#define LPBK_FIFO_2_CTRL_DEFAULT 0x1 + /*[field] LPBK_FIFO_2_THRESHOLD*/ + #define LPBK_FIFO_2_CTRL_LPBK_FIFO_2_THRESHOLD + #define LPBK_FIFO_2_CTRL_LPBK_FIFO_2_THRESHOLD_OFFSET 0 + #define LPBK_FIFO_2_CTRL_LPBK_FIFO_2_THRESHOLD_LEN 3 + #define LPBK_FIFO_2_CTRL_LPBK_FIFO_2_THRESHOLD_DEFAULT 0x0 +struct lpbk_fifo_2_ctrl { + a_uint32_t lpbk_fifo_2_threshold:3; + a_uint32_t _reserved0:29; +}; +union lpbk_fifo_2_ctrl_u { + a_uint32_t val; + struct lpbk_fifo_2_ctrl bf; +}; + +/*[register] LPBK_PPS_CTRL*/ +#define LPBK_PPS_CTRL +#define LPBK_PPS_CTRL_ADDRESS 0x0c +#define LPBK_PPS_CTRL_NUM 6 +#define LPBK_PPS_CTRL_INC 0x200 +#define LPBK_PPS_CTRL_TYPE REG_TYPE_RW +#define LPBK_PPS_CTRL_DEFAULT 0x0 + /*[field] LPBK_PPS_THRESHOLD*/ + #define LPBK_PPS_CTRL_LPBK_PPS_THRESHOLD + #define LPBK_PPS_CTRL_LPBK_PPS_THRESHOLD_OFFSET 0 + #define LPBK_PPS_CTRL_LPBK_PPS_THRESHOLD_LEN 9 + #define LPBK_PPS_CTRL_LPBK_PPS_THRESHOLD_DEFAULT 0x16 +struct lpbk_pps_ctrl { + a_uint32_t lpbk_pps_threshold:9; + a_uint32_t _reserved0:13; +}; +union lpbk_pps_ctrl_u { + a_uint32_t val; + struct lpbk_pps_ctrl bf; +}; + +/*[register] LPBK_MAC_JUNMO_SIZE*/ +#define LPBK_MAC_JUNMO_SIZE +#define LPBK_MAC_JUNMO_SIZE_ADDRESS 0x10 +#define LPBK_MAC_JUNMO_SIZE_NUM 6 +#define LPBK_MAC_JUNMO_SIZE_INC 0x200 +#define LPBK_MAC_JUNMO_SIZE_TYPE REG_TYPE_RW +#define LPBK_MAC_JUNMO_SIZE_DEFAULT 0x0 + /*[field] LPBK_MAC_JUMBO_SIZE*/ + #define LPBK_MAC_JUNMO_SIZE_LPBK_MAC_JUMBO_SIZE + #define LPBK_MAC_JUNMO_SIZE_LPBK_MAC_JUMBO_SIZE_OFFSET 0 + #define LPBK_MAC_JUNMO_SIZE_LPBK_MAC_JUMBO_SIZE_LEN 14 + #define LPBK_MAC_JUNMO_SIZE_LPBK_MAC_JUMBO_SIZE_DEFAULT 0x5EA +struct lpbk_mac_junmo_size { + a_uint32_t lpbk_mac_jumbo_size:14; + a_uint32_t _reserved0:18; +}; +union lpbk_mac_junmo_size_u { + a_uint32_t val; + struct lpbk_mac_junmo_size bf; +}; + +/*[register] LPBK_MIB_CTRL*/ +#define LPBK_MIB_CTRL +#define LPBK_MIB_CTRL_ADDRESS 0x14 +#define LPBK_MIB_CTRL_NUM 6 +#define LPBK_MIB_CTRL_INC 0x200 +#define LPBK_MIB_CTRL_TYPE REG_TYPE_RW +#define LPBK_MIB_CTRL_DEFAULT 0x0 + /*[field] MIB_EN*/ + #define LPBK_MIB_CTRL_MIB_EN + #define LPBK_MIB_CTRL_MIB_EN_OFFSET 0 + #define LPBK_MIB_CTRL_MIB_EN_LEN 1 + #define LPBK_MIB_CTRL_MIB_EN_DEFAULT 0x1 + /*[field] MIB_RESET*/ + #define LPBK_MIB_CTRL_MIB_RESET + #define LPBK_MIB_CTRL_MIB_RESET_OFFSET 1 + #define LPBK_MIB_CTRL_MIB_RESET_LEN 1 + #define LPBK_MIB_CTRL_MIB_RESET_DEFAULT 0x0 + /*[field] MIB_RD_CLR*/ + #define LPBK_MIB_CTRL_MIB_RD_CLR + #define LPBK_MIB_CTRL_MIB_RD_CLR_OFFSET 2 + #define LPBK_MIB_CTRL_MIB_RD_CLR_LEN 1 + #define LPBK_MIB_CTRL_MIB_RD_CLR_DEFAULT 0x0 +struct lpbk_mib_ctrl { + a_uint32_t mib_en:1; + a_uint32_t mib_reset:1; + a_uint32_t mib_rd_clr:1; + a_uint32_t _reserved0:29; +}; +union lpbk_mib_ctrl_u { + a_uint32_t val; + struct lpbk_mib_ctrl bf; +}; + +/*[register] LPBKUNI*/ +#define LPBKUNI +#define LPBKUNI_ADDRESS 0x20 +#define LPBKUNI_NUM 6 +#define LPBKUNI_INC 0x200 +#define LPBKUNI_TYPE REG_TYPE_RO +#define LPBKUNI_DEFAULT 0x0 + /*[field] LPBKUNI*/ + #define LPBKUNI_LPBKUNI + #define LPBKUNI_LPBKUNI_OFFSET 0 + #define LPBKUNI_LPBKUNI_LEN 32 + #define LPBKUNI_LPBKUNI_DEFAULT 0x0 +struct lpbkuni { + a_uint32_t lpbkuni:32; +}; +union lpbkuni_u { + a_uint32_t val; + struct lpbkuni bf; +}; + +/*[register] LPBKMULTI*/ +#define LPBKMULTI +#define LPBKMULTI_ADDRESS 0x24 +#define LPBKMULTI_NUM 6 +#define LPBKMULTI_INC 0x200 +#define LPBKMULTI_TYPE REG_TYPE_RO +#define LPBKMULTI_DEFAULT 0x0 + /*[field] LPBKMULTI*/ + #define LPBKMULTI_LPBKMULTI + #define LPBKMULTI_LPBKMULTI_OFFSET 0 + #define LPBKMULTI_LPBKMULTI_LEN 32 + #define LPBKMULTI_LPBKMULTI_DEFAULT 0x0 +struct lpbkmulti { + a_uint32_t lpbkmulti:32; +}; +union lpbkmulti_u { + a_uint32_t val; + struct lpbkmulti bf; +}; + +/*[register] LPBKBROAD*/ +#define LPBKBROAD +#define LPBKBROAD_ADDRESS 0x28 +#define LPBKBROAD_NUM 6 +#define LPBKBROAD_INC 0x200 +#define LPBKBROAD_TYPE REG_TYPE_RO +#define LPBKBROAD_DEFAULT 0x0 + /*[field] LPBK_BROAD*/ + #define LPBKBROAD_LPBKBROAD + #define LPBKBROAD_LPBKBROAD_OFFSET 0 + #define LPBKBROAD_LPBKBROAD_LEN 32 + #define LPBKBROAD_LPBKBROAD_DEFAULT 0x0 +struct lpbkbroad { + a_uint32_t lpbkbroad:32; +}; +union lpbkbroad_u { + a_uint32_t val; + struct lpbkbroad bf; +}; + +/*[register] LPBKPKT64*/ +#define LPBKPKT64 +#define LPBKPKT64_ADDRESS 0x2c +#define LPBKPKT64_NUM 6 +#define LPBKPKT64_INC 0x200 +#define LPBKPKT64_TYPE REG_TYPE_RO +#define LPBKPKT64_DEFAULT 0x0 + /*[field] LPBKPKT64*/ + #define LPBKPKT64_LPBKPKT64 + #define LPBKPKT64_LPBKPKT64_OFFSET 0 + #define LPBKPKT64_LPBKPKT64_LEN 32 + #define LPBKPKT64_LPBKPKT64_DEFAULT 0x0 +struct lpbkpkt64 { + a_uint32_t lpbkpkt64:32; +}; +union lpbkpkt64_u { + a_uint32_t val; + struct lpbkpkt64 bf; +}; + +/*[register] LPBKPKT65TO127*/ +#define LPBKPKT65TO127 +#define LPBKPKT65TO127_ADDRESS 0x30 +#define LPBKPKT65TO127_NUM 6 +#define LPBKPKT65TO127_INC 0x200 +#define LPBKPKT65TO127_TYPE REG_TYPE_RO +#define LPBKPKT65TO1277_DEFAULT 0x0 + /*[field] LPBKPKT65TO127*/ + #define LPBKPKT65TO127_LPBKPKT65TO127 + #define LPBKPKT65TO127_LPBKPKT65TO127_OFFSET 0 + #define LPBKPKT65TO127_LPBKPKT65TO127_LEN 32 + #define LPBKPKT65TO127_LPBKPKT65TO127_DEFAULT 0x0 +struct lpbkpkt65to127 { + a_uint32_t lpbkpkt65to127:32; +}; +union lpbkpkt65to127_u { + a_uint32_t val; + struct lpbkpkt65to127 bf; +}; + +/*[register] LPBKPKT128TO255*/ +#define LPBKPKT128TO255 +#define LPBKPKT128TO255_ADDRESS 0x34 +#define LPBKPKT128TO255_NUM 6 +#define LPBKPKT128TO255_INC 0x200 +#define LPBKPKT128TO255_TYPE REG_TYPE_RO +#define LPBKPKT128TO255_DEFAULT 0x0 + /*[field] LPBKPKT128TO255*/ + #define LPBKPKT128TO255_LPBKPKT128TO255 + #define LPBKPKT128TO255_LPBKPKT128TO255_OFFSET 0 + #define LPBKPKT128TO255_LPBKPKT128TO255_LEN 32 + #define LPBKPKT128TO255_LPBKPKT128TO255_DEFAULT 0x0 +struct lpbkpkt128to255 { + a_uint32_t lpbkpkt128to255:32; +}; +union lpbkpkt128to255_u { + a_uint32_t val; + struct lpbkpkt128to255 bf; +}; + +/*[register] LPBKPKT256TO511*/ +#define LPBKPKT256TO511 +#define LPBKPKT256TO511_ADDRESS 0x38 +#define LPBKPKT256TO511_NUM 6 +#define LPBKPKT256TO511_INC 0x200 +#define LPBKPKT256TO511_TYPE REG_TYPE_RO +#define LPBKPKT256TO511_DEFAULT 0x0 + /*[field] LPBKPKT256TO511*/ + #define LPBKPKT256TO511_LPBKPKT256TO511 + #define LPBKPKT256TO511_LPBKPKT256TO511_OFFSET 0 + #define LPBKPKT256TO511_LPBKPKT256TO511_LEN 32 + #define LPBKPKT256TO511_LPBKPKT256TO511_DEFAULT 0x0 +struct lpbkpkt256to511 { + a_uint32_t lpbkpkt256to511:32; +}; +union lpbkpkt256to511_u { + a_uint32_t val; + struct lpbkpkt256to511 bf; +}; + +/*[register] LPBKPKT512TO1023*/ +#define LPBKPKT512TO1023 +#define LPBKPKT512TO1023_ADDRESS 0x3c +#define LPBKPKT512TO1023_NUM 6 +#define LPBKPKT512TO1023_INC 0x200 +#define LPBKPKT512TO1023_TYPE REG_TYPE_RO +#define LPBKPKT512TO1023_DEFAULT 0x0 + /*[field] LPBKPKT512TO1023*/ + #define LPBKPKT512TO1023_LPBKPKT512TO1023 + #define LPBKPKT512TO1023_LPBKPKT512TO1023_OFFSET 0 + #define LPBKPKT512TO1023_LPBKPKT512TO1023_LEN 32 + #define LPBKPKT512TO1023_LPBKPKT512TO1023_DEFAULT 0x0 +struct lpbkpkt512to1023 { + a_uint32_t lpbkpkt512to1023:32; +}; +union lpbkpkt512to1023_u { + a_uint32_t val; + struct lpbkpkt512to1023 bf; +}; + +/*[register] LPBKPKT1024TO1518*/ +#define LPBKPKT1024TO1518 +#define LPBKPKT1024TO1518_ADDRESS 0x40 +#define LPBKPKT1024TO1518_NUM 6 +#define LPBKPKT1024TO1518_INC 0x200 +#define LPBKPKT1024TO1518_TYPE REG_TYPE_RO +#define LPBKPKT1024TO1518_DEFAULT 0x0 + /*[field] RXPKT1024TO1518*/ + #define LPBKPKT1024TO1518_LPBKPKT1024TO1518 + #define LPBKPKT1024TO1518_OFFSET 0 + #define LPBKPKT1024TO1518_LEN 32 + #define LPBKPKT1024TO1518_DEFAULT 0x0 + +struct lpbkpkt1024to1518 { + a_uint32_t lpbkpkt1024to1518:32; +}; +union lpbkpkt1024to1518_u { + a_uint32_t val; + struct lpbkpkt1024to1518 bf; +}; + +/*[register] LPBKPKT1519TOX*/ +#define LPBKPKT1519TOX +#define LPBKPKT1519TOX_ADDRESS 0x44 +#define LPBKPKT1519TOX_NUM 6 +#define LPBKPKT1519TOX_INC 0x200 +#define LPBKPKT1519TOX_TYPE REG_TYPE_RO +#define LPBKPKT1519TOX_DEFAULT 0x0 + /*[field] RXPKT1519TOX*/ + #define LPBKPKT1519TOX_LPBKPKT1519TOX + #define LPBKPKT1519TOX_LPBKPKT1519TOX_OFFSET 0 + #define LPBKPKT1519TOX_LPBKPKT1519TOX_LEN 32 + #define LPBKPKT1519TOX_LPBKPKT1519TOX_DEFAULT 0x0 +struct lpbkpkt1519tox { + a_uint32_t lpbkpkt1519tox:32; +}; +union lpbkpkt1519tox_u { + a_uint32_t val; + struct lpbkpkt1519tox bf; +}; + +/*[register] LPBKPKTTOOLONG*/ +#define LPBKPKTTOOLONG +#define LPBKPKTTOOLONG_ADDRESS 0x48 +#define LPBKPKTTOOLONG_NUM 6 +#define LPBKPKTTOOLONG_INC 0x200 +#define LPBKPKTTOOLONG_TYPE REG_TYPE_RO +#define LPBKPKTTOOLONG_DEFAULT 0x0 + /*[field] RXTOOLONG*/ + #define LPBKPKTTOOLONG_LPBKPKTTOOLONG + #define LPBKPKTTOOLONG_LPBKPKTTOOLONG_OFFSET 0 + #define LPBKPKTTOOLONG_LPBKPKTTOOLONG_LEN 32 + #define LPBKPKTTOOLONG_LPBKPKTTOOLONG_DEFAULT 0x0 +struct lpbkpkttoolong { + a_uint32_t lpbkpkttoolong:32; +}; +union lpbkpkttoolong_u { + a_uint32_t val; + struct lpbkpkttoolong bf; +}; + +/*[register] LPBKBYTE_L*/ +#define LPBKBYTE_L +#define LPBKBYTE_L_ADDRESS 0x4c +#define LPBKBYTE_L_NUM 6 +#define LPBKBYTE_L_INC 0x200 +#define LPBKBYTE_L_TYPE REG_TYPE_RO +#define LPBKBYTE_L_DEFAULT 0x0 + /*[field] LPBKBYTE_L*/ + #define LPBKBYTE_L_LPBKBYTE_L + #define LPBKBYTE_L_LPBKBYTE_L_OFFSET 0 + #define LPBKBYTE_L_LPBKBYTE_L_LEN 32 + #define LPBKBYTE_L_LPBKBYTE_L_DEFAULT 0x0 +struct lpbkbyte_l { + a_uint32_t lpbkbyte_l:32; +}; +union lpbkbyte_l_u { + a_uint32_t val; + struct lpbkbyte_l bf; +}; + +/*[register] LPBKBYTE_H*/ +#define LPBKBYTE_H +#define LPBKBYTE_H_ADDRESS 0x50 +#define LPBKBYTE_H_NUM 6 +#define LPBKBYTE_H_INC 0x200 +#define LPBKBYTE_H_TYPE REG_TYPE_RO +#define LPBKBYTE_H_DEFAULT 0x0 + /*[field] LPBKBYTE_H*/ + #define LPBKBYTE_H_LPBKBYTE_H + #define LPBKBYTE_H_LPBKBYTE_H_OFFSET 0 + #define LPBKBYTE_H_LPBKBYTE_H_LEN 32 + #define LPBKBYTE_H_LPBKBYTE_H_DEFAULT 0x0 + +struct lpbkbyte_h { + a_uint32_t lpbkbyte_h:32; +}; +union lpbkbyte_h_u { + a_uint32_t val; + struct lpbkbyte_h bf; +}; + +/*[register] LPBKDROPCOUNTER*/ +#define LPBKDROPCOUNTER +#define LPBKDROPCOUNTER_ADDRESS 0x54 +#define LPBKDROPCOUNTER_NUM 6 +#define LPBKDROPCOUNTER_INC 0x200 +#define LPBKDROPCOUNTER_TYPE REG_TYPE_RO +#define LPBKDROPCOUNTER_DEFAULT 0x0 + /*[field] LPBKDROPCOUNTER*/ + #define LPBKDROPCOUNTER_LPBKDROPCOUNTER + #define LPBKDROPCOUNTER_OFFSET 0 + #define LPBKDROPCOUNTER_LEN 32 + #define LPBKDROPCOUNTER_DEFAULT 0x0 +struct lpbkdropcounter { + a_uint32_t lpbkdropcounter:32; +}; +union lpbkdropcounter_u { + a_uint32_t val; + struct lpbkdropcounter bf; +}; + +/*[register] LPBKTOOSHORT*/ +#define LPBKPKTTOOSHORT +#define LPBKPKTTOOSHORT_ADDRESS 0x68 +#define LPBKPKTTOOSHORT_NUM 6 +#define LPBKPKTTOOSHORT_INC 0x200 +#define LPBKPKTTOOSHORT_TYPE REG_TYPE_RO +#define LPBKPKTTOOSHORT_DEFAULT 0x0 + /*[field] LPBKPKTTOOSHORT*/ + #define LPBKPKTTOOSHORT_LPBKPKTTOOSHORT + #define LPBKPKTTOOSHORT_OFFSET 0 + #define LPBKPKTTOOSHORT_LEN 32 + #define LPBKPKTTOOSHORT_DEFAULT 0x0 +struct lpbkpkttooshort { + a_uint32_t lpbkpkttooshort:32; +}; +union lpbkpkttooshort_u { + a_uint32_t val; + struct lpbkpkttooshort bf; +}; + +/*[register] LPBKPKT14TO63*/ +#define LPBKPKT14TO63 +#define LPBKPKT14TO63_ADDRESS 0x6c +#define LPBKPKT14TO63_NUM 6 +#define LPBKPKT14TO63_INC 0x200 +#define LPBKPKT14TO63_TYPE REG_TYPE_RO +#define LPBKPKT14TO63_DEFAULT 0x0 + /*[field] LPBKPKT14TO63*/ + #define LPBKPKT14TO63_LPBKPKT14TO63 + #define LPBKPKT14TO63_OFFSET 0 + #define LPBKPKT14TO63_LEN 32 + #define LPBKPKT14TO63_DEFAULT 0x0 +struct lpbkpkt14to63 { + a_uint32_t lpbkpkt14to63:32; +}; +union lpbkpkt14to63_u { + a_uint32_t val; + struct lpbkpkt14to63 bf; +}; + +/*[register] LPBKTOOLONGBYTE_L*/ +#define LPBKTOOLONGBYTE_L +#define LPBKTOOLONGBYTE_L_ADDRESS 0x70 +#define LPBKTOOLONGBYTE_L_NUM 6 +#define LPBKTOOLONGBYTE_L_INC 0x200 +#define LPBKTOOLONGBYTE_L_TYPE REG_TYPE_RO +#define LPBKTOOLONGBYTE_L_DEFAULT 0x0 + /*[field] LPBKTOOLONGBYTE_L*/ + #define LPBKTOOLONGBYTE_L_LPBKTOOLONGBYTE_L + #define LPBKTOOLONGBYTE_L_LPBKTOOLONGBYTE_L_OFFSET 0 + #define LPBKTOOLONGBYTE_L_LPBKTOOLONGBYTE_L_LEN 32 + #define LPBKTOOLONGBYTE_L_LPBKTOOLONGBYTE_L_DEFAULT 0x0 +struct lpbktoolongbyte_l { + a_uint32_t lpbktoolongbyte_l:32; +}; +union lpbktoolongbyte_l_u { + a_uint32_t val; + struct lpbktoolongbyte_l bf; +}; + +/*[register] LPBKTOOLONGBYTE_H*/ +#define LPBKTOOLONGBYTE_H +#define LPBKTOOLONGBYTE_H_ADDRESS 0x74 +#define LPBKTOOLONGBYTE_H_NUM 6 +#define LPBKTOOLONGBYTE_H_INC 0x200 +#define LPBKTOOLONGBYTE_H_TYPE REG_TYPE_RO +#define LPBKTOOLONGBYTE_H_DEFAULT 0x0 + /*[field] LPBKTOOLONGBYTE_L*/ + #define LPBKTOOLONGBYTE_H_LPBKTOOLONGBYTE_H + #define LPBKTOOLONGBYTE_H_LPBKTOOLONGBYTE_H_OFFSET 0 + #define LPBKTOOLONGBYTE_H_LPBKTOOLONGBYTE_H_LEN 32 + #define LPBKTOOLONGBYTE_H_LPBKTOOLONGBYTE_H_DEFAULT 0x0 +struct lpbktoolongbyte_h { + a_uint32_t lpbktoolongbyte_h:32; +}; +union lpbktoolongbyte_h_u { + a_uint32_t val; + struct lpbktoolongbyte_h bf; +}; + +/*[register] LPBKTOOSHORTBYTE_L*/ +#define LPBKTOOSHORTBYTE_L +#define LPBKTOOSHORTBYTE_L_ADDRESS 0x78 +#define LPBKTOOSHORTBYTE_L_NUM 6 +#define LPBKTOOSHORTBYTE_L_INC 0x200 +#define LPBKTOOLONGBYTE_L_TYPE REG_TYPE_RO +#define LPBKTOOLONGBYTE_L_DEFAULT 0x0 + /*[field] LPBKTOOLONGBYTE_L*/ + #define LPBKTOOSHORTBYTE_L_LPBKTOOSHORTBYTE_L + #define LPBKTOOSHORTBYTE_L_LPBKTOOSHORTBYTE_L_OFFSET 0 + #define LPBKTOOSHORTBYTE_L_LPBKTOOSHORTBYTE_L_LEN 32 + #define LPBKTOOSHORTBYTE_L_LPBKTOOSHORTBYTE_L_DEFAULT 0x0 +struct lpbktooshortbyte_l { + a_uint32_t lpbktooshortbyte_l:32; +}; +union lpbktooshortbyte_l_u { + a_uint32_t val; + struct lpbktooshortbyte_l bf; +}; + +/*[register] LPBKTOOSHORTBYTE_H*/ +#define LPBKTOOSHORTBYTE_H +#define LPBKTOOSHORTBYTE_H_ADDRESS 0x7c +#define LPBKTOOSHORTBYTE_H_NUM 6 +#define LPBKTOOSHORTBYTE_H_INC 0x200 +#define LPBKTOOSHORTBYTE_H_TYPE REG_TYPE_RO +#define LPBKTOOSHORTBYTE_H_DEFAULT 0x0 + /*[field] LPBKTOOLONGBYTE_L*/ + #define LPBKTOOSHORTBYTE_H_LPBKTOOSHORTBYTE_H + #define LPBKTOOSHORTBYTE_H_OFFSET 0 + #define LPBKTOOSHORTBYTE_H_LEN 32 + #define LPBKTOOSHORTBYTE_H_DEFAULT 0x0 +struct lpbktooshortbyte_h { + a_uint32_t lpbktooshortbyte_h:32; +}; +union lpbktooshortbyte_h_u { + a_uint32_t val; + struct lpbktooshortbyte_h bf; +}; +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/cppe/cppe_portctrl.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/cppe/cppe_portctrl.h new file mode 100755 index 000000000..b211c8c41 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/cppe/cppe_portctrl.h @@ -0,0 +1,204 @@ +/* + * 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. + */ + + +/** + * @defgroup + * @{ + */ +#ifndef _CPPE_PORTCTRL_H_ +#define _CPPE_PORTCTRL_H_ +#include "cppe_portctrl_reg.h" + +#define CPPE_MRU_MTU_CTRL_TBL_MAX_ENTRY 256 + +sw_error_t +cppe_mru_mtu_ctrl_tbl_dscp_res_prec_force_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +cppe_mru_mtu_ctrl_tbl_dscp_res_prec_force_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +cppe_mru_mtu_ctrl_tbl_pcp_res_prec_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +cppe_mru_mtu_ctrl_tbl_pcp_res_prec_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +cppe_mru_mtu_ctrl_tbl_pcp_qos_group_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +cppe_mru_mtu_ctrl_tbl_pcp_qos_group_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +cppe_mru_mtu_ctrl_tbl_pcp_res_prec_force_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +cppe_mru_mtu_ctrl_tbl_pcp_res_prec_force_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +cppe_mru_mtu_ctrl_tbl_post_acl_res_prec_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +cppe_mru_mtu_ctrl_tbl_post_acl_res_prec_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +cppe_mru_mtu_ctrl_tbl_preheader_res_prec_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +cppe_mru_mtu_ctrl_tbl_preheader_res_prec_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +cppe_mru_mtu_ctrl_tbl_dscp_res_prec_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +cppe_mru_mtu_ctrl_tbl_dscp_res_prec_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +cppe_mru_mtu_ctrl_tbl_pre_acl_res_prec_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +cppe_mru_mtu_ctrl_tbl_pre_acl_res_prec_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +cppe_mru_mtu_ctrl_tbl_flow_res_prec_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +cppe_mru_mtu_ctrl_tbl_flow_res_prec_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +cppe_mru_mtu_ctrl_tbl_dscp_qos_group_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +cppe_mru_mtu_ctrl_tbl_dscp_qos_group_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +cppe_mru_mtu_ctrl_tbl_src_profile_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +cppe_mru_mtu_ctrl_tbl_src_profile_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +cppe_mru_mtu_ctrl_tbl_source_filter_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +cppe_mru_mtu_ctrl_tbl_source_filter_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +cppe_mru_mtu_ctrl_tbl_source_filter_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +cppe_mru_mtu_ctrl_tbl_source_filter_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +cppe_mru_mtu_ctrl_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union cppe_mru_mtu_ctrl_tbl_u *value); + +sw_error_t +cppe_mru_mtu_ctrl_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union cppe_mru_mtu_ctrl_tbl_u *value); + +sw_error_t +cppe_port_phy_status_1_get( + a_uint32_t dev_id, + union cppe_port_phy_status_1_u *value); + +sw_error_t +cppe_port5_pcs1_phy_status_get( + a_uint32_t dev_id, + unsigned int *value); + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/cppe/cppe_portctrl_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/cppe/cppe_portctrl_reg.h new file mode 100755 index 000000000..d12d8d0b8 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/cppe/cppe_portctrl_reg.h @@ -0,0 +1,166 @@ +/* + * 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. + */ + + +/** + * @defgroup + * @{ + */ +#ifndef _CPPE_PORTCTRL_REG_H_ +#define _CPPE_PORTCTRL_REG_H_ + +/*[table] CPPE_MRU_MTU_CTRL_TBL*/ +#define CPPE_MRU_MTU_CTRL_TBL +#define CPPE_MRU_MTU_CTRL_TBL_ADDRESS 0x3000 +#define CPPE_MRU_MTU_CTRL_TBL_NUM 256 +#define CPPE_MRU_MTU_CTRL_TBL_INC 0x10 +#define CPPE_MRU_MTU_CTRL_TBL_TYPE REG_TYPE_RW +#define CPPE_MRU_MTU_CTRL_TBL_DEFAULT 0x0 + /*[field] MRU*/ + #define CPPE_MRU_MTU_CTRL_TBL_MRU + #define CPPE_MRU_MTU_CTRL_TBL_MRU_OFFSET 0 + #define CPPE_MRU_MTU_CTRL_TBL_MRU_LEN 14 + #define CPPE_MRU_MTU_CTRL_TBL_MRU_DEFAULT 0x0 + /*[field] MRU_CMD*/ + #define CPPE_MRU_MTU_CTRL_TBL_MRU_CMD + #define CPPE_MRU_MTU_CTRL_TBL_MRU_CMD_OFFSET 14 + #define CPPE_MRU_MTU_CTRL_TBL_MRU_CMD_LEN 2 + #define CPPE_MRU_MTU_CTRL_TBL_MRU_CMD_DEFAULT 0x0 + /*[field] MTU*/ + #define CPPE_MRU_MTU_CTRL_TBL_MTU + #define CPPE_MRU_MTU_CTRL_TBL_MTU_OFFSET 16 + #define CPPE_MRU_MTU_CTRL_TBL_MTU_LEN 14 + #define CPPE_MRU_MTU_CTRL_TBL_MTU_DEFAULT 0x0 + /*[field] MTU_CMD*/ + #define CPPE_MRU_MTU_CTRL_TBL_MTU_CMD + #define CPPE_MRU_MTU_CTRL_TBL_MTU_CMD_OFFSET 30 + #define CPPE_MRU_MTU_CTRL_TBL_MTU_CMD_LEN 2 + #define CPPE_MRU_MTU_CTRL_TBL_MTU_CMD_DEFAULT 0x0 + /*[field] RX_CNT_EN*/ + #define CPPE_MRU_MTU_CTRL_TBL_RX_CNT_EN + #define CPPE_MRU_MTU_CTRL_TBL_RX_CNT_EN_OFFSET 32 + #define CPPE_MRU_MTU_CTRL_TBL_RX_CNT_EN_LEN 1 + #define CPPE_MRU_MTU_CTRL_TBL_RX_CNT_EN_DEFAULT 0x0 + /*[field] TX_CNT_EN*/ + #define CPPE_MRU_MTU_CTRL_TBL_TX_CNT_EN + #define CPPE_MRU_MTU_CTRL_TBL_TX_CNT_EN_OFFSET 33 + #define CPPE_MRU_MTU_CTRL_TBL_TX_CNT_EN_LEN 1 + #define CPPE_MRU_MTU_CTRL_TBL_TX_CNT_EN_DEFAULT 0x0 + /*[field] SRC_PROFILE*/ + #define CPPE_MRU_MTU_CTRL_TBL_SRC_PROFILE + #define CPPE_MRU_MTU_CTRL_TBL_SRC_PROFILE_OFFSET 34 + #define CPPE_MRU_MTU_CTRL_TBL_SRC_PROFILE_LEN 2 + #define CPPE_MRU_MTU_CTRL_TBL_SRC_PROFILE_DEFAULT 0x0 + /*[field] PCP_QOS_GROUP_ID*/ + #define CPPE_MRU_MTU_CTRL_TBL_PCP_QOS_GROUP_ID + #define CPPE_MRU_MTU_CTRL_TBL_PCP_QOS_GROUP_ID_OFFSET 36 + #define CPPE_MRU_MTU_CTRL_TBL_PCP_QOS_GROUP_ID_LEN 1 + #define CPPE_MRU_MTU_CTRL_TBL_PCP_QOS_GROUP_ID_DEFAULT 0x0 + /*[field] DSCP_QOS_GROUP_ID*/ + #define CPPE_MRU_MTU_CTRL_TBL_DSCP_QOS_GROUP_ID + #define CPPE_MRU_MTU_CTRL_TBL_DSCP_QOS_GROUP_ID_OFFSET 37 + #define CPPE_MRU_MTU_CTRL_TBL_DSCP_QOS_GROUP_ID_LEN 1 + #define CPPE_MRU_MTU_CTRL_TBL_DSCP_QOS_GROUP_ID_DEFAULT 0x0 + /*[field] PCP_RES_PREC_FORCE*/ + #define CPPE_MRU_MTU_CTRL_TBL_PCP_RES_PREC_FORCE + #define CPPE_MRU_MTU_CTRL_TBL_PCP_RES_PREC_FORCE_OFFSET 38 + #define CPPE_MRU_MTU_CTRL_TBL_PCP_RES_PREC_FORCE_LEN 1 + #define CPPE_MRU_MTU_CTRL_TBL_PCP_RES_PREC_FORCE_DEFAULT 0x0 + /*[field] DSCP_RES_PREC_FORCE*/ + #define CPPE_MRU_MTU_CTRL_TBL_DSCP_RES_PREC_FORCE + #define CPPE_MRU_MTU_CTRL_TBL_DSCP_RES_PREC_FORCE_OFFSET 39 + #define CPPE_MRU_MTU_CTRL_TBL_DSCP_RES_PREC_FORCE_LEN 1 + #define CPPE_MRU_MTU_CTRL_TBL_DSCP_RES_PREC_FORCE_DEFAULT 0x0 + /*[field] PREHEADER_RES_PREC*/ + #define CPPE_MRU_MTU_CTRL_TBL_PREHEADER_RES_PREC + #define CPPE_MRU_MTU_CTRL_TBL_PREHEADER_RES_PREC_OFFSET 40 + #define CPPE_MRU_MTU_CTRL_TBL_PREHEADER_RES_PREC_LEN 3 + #define CPPE_MRU_MTU_CTRL_TBL_PREHEADER_RES_PREC_DEFAULT 0x0 + /*[field] PCP_RES_PREC*/ + #define CPPE_MRU_MTU_CTRL_TBL_PCP_RES_PREC + #define CPPE_MRU_MTU_CTRL_TBL_PCP_RES_PREC_OFFSET 43 + #define CPPE_MRU_MTU_CTRL_TBL_PCP_RES_PREC_LEN 3 + #define CPPE_MRU_MTU_CTRL_TBL_PCP_RES_PREC_DEFAULT 0x0 + /*[field] DSCP_RES_PREC*/ + #define CPPE_MRU_MTU_CTRL_TBL_DSCP_RES_PREC + #define CPPE_MRU_MTU_CTRL_TBL_DSCP_RES_PREC_OFFSET 46 + #define CPPE_MRU_MTU_CTRL_TBL_DSCP_RES_PREC_LEN 3 + #define CPPE_MRU_MTU_CTRL_TBL_DSCP_RES_PREC_DEFAULT 0x0 + /*[field] FLOW_RES_PREC*/ + #define CPPE_MRU_MTU_CTRL_TBL_FLOW_RES_PREC + #define CPPE_MRU_MTU_CTRL_TBL_FLOW_RES_PREC_OFFSET 49 + #define CPPE_MRU_MTU_CTRL_TBL_FLOW_RES_PREC_LEN 3 + #define CPPE_MRU_MTU_CTRL_TBL_FLOW_RES_PREC_DEFAULT 0x0 + /*[field] PRE_ACL_RES_PREC*/ + #define CPPE_MRU_MTU_CTRL_TBL_PRE_ACL_RES_PREC + #define CPPE_MRU_MTU_CTRL_TBL_PRE_ACL_RES_PREC_OFFSET 52 + #define CPPE_MRU_MTU_CTRL_TBL_PRE_ACL_RES_PREC_LEN 3 + #define CPPE_MRU_MTU_CTRL_TBL_PRE_ACL_RES_PREC_DEFAULT 0x0 + /*[field] POST_ACL_RES_PREC*/ + #define CPPE_MRU_MTU_CTRL_TBL_POST_ACL_RES_PREC + #define CPPE_MRU_MTU_CTRL_TBL_POST_ACL_RES_PREC_OFFSET 55 + #define CPPE_MRU_MTU_CTRL_TBL_POST_ACL_RES_PREC_LEN 3 + #define CPPE_MRU_MTU_CTRL_TBL_POST_ACL_RES_PREC_DEFAULT 0x0 + /*[field] SOURCE_FILTERING_BYPASS*/ + #define CPPE_MRU_MTU_CTRL_TBL_SOURCE_FILTERING_BYPASS + #define CPPE_MRU_MTU_CTRL_TBL_SOURCE_FILTERING_BYPASS_OFFSET 58 + #define CPPE_MRU_MTU_CTRL_TBL_SOURCE_FILTERING_BYPASS_LEN 1 + #define CPPE_MRU_MTU_CTRL_TBL_SOURCE_FILTERING_BYPASS_DEFAULT 0x0 + /*[field] SOURCE_FILTERING_MODE*/ + #define CPPE_MRU_MTU_CTRL_TBL_SOURCE_FILTERING_MODE + #define CPPE_MRU_MTU_CTRL_TBL_SOURCE_FILTERING_MODE_OFFSET 59 + #define CPPE_MRU_MTU_CTRL_TBL_SOURCE_FILTERING_MODE_LEN 1 + #define CPPE_MRU_MTU_CTRL_TBL_SOURCE_FILTERING_MODE_DEFAULT 0x0 + +struct cppe_mru_mtu_ctrl_tbl { + a_uint32_t mru:14; + a_uint32_t mru_cmd:2; + a_uint32_t mtu:14; + a_uint32_t mtu_cmd:2; + a_uint32_t rx_cnt_en:1; + a_uint32_t tx_cnt_en:1; + a_uint32_t src_profile:2; + a_uint32_t pcp_qos_group_id:1; + a_uint32_t dscp_qos_group_id:1; + a_uint32_t pcp_res_prec_force:1; + a_uint32_t dscp_res_prec_force:1; + a_uint32_t preheader_res_prec:3; + a_uint32_t pcp_res_prec:3; + a_uint32_t dscp_res_prec:3; + a_uint32_t flow_res_prec:3; + a_uint32_t pre_acl_res_prec:3; + a_uint32_t post_acl_res_prec:3; + a_uint32_t source_filtering_bypass:1; + a_uint32_t source_filtering_mode:1; + a_uint32_t _reserved0:4; +}; + +union cppe_mru_mtu_ctrl_tbl_u { + a_uint32_t val[2]; + struct cppe_mru_mtu_ctrl_tbl bf; +}; + +struct cppe_port_phy_status_1 { + a_uint32_t port5_pcs0_phy_status:8; + a_uint32_t port4_pcs0_phy_status:8; + a_uint32_t port5_pcs1_phy_status:8; + a_uint32_t _reserved0:8; +}; + +union cppe_port_phy_status_1_u { + a_uint32_t val; + struct cppe_port_phy_status_1 bf; +}; + +#endif \ No newline at end of file diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/cppe/cppe_qos.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/cppe/cppe_qos.h new file mode 100755 index 000000000..ae583960f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/cppe/cppe_qos.h @@ -0,0 +1,186 @@ +/* + * 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. + */ + + +/** + * @defgroup + * @{ + */ +#ifndef _CPPE_QOS_H_ +#define _CPPE_QOS_H_ + +#define QOS_MAPPING_TBL_MAX_ENTRY 2592 +#define QOS_MAPPING_FLOW_TBL_MAX_ENTRY 2048 +#define QOS_MAPPING_DSCP_TBL_MAX_ENTRY 256 +#define QOS_MAPPING_PCP_TBL_MAX_ENTRY 16 +#define QOS_MAPPING_TBL_MAX_GROUP 2 + + +sw_error_t +cppe_qos_mapping_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union qos_mapping_tbl_u *value); + +sw_error_t +cppe_qos_mapping_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union qos_mapping_tbl_u *value); + +sw_error_t +cppe_qos_mapping_tbl_int_pcp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +cppe_qos_mapping_tbl_int_pcp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +cppe_qos_mapping_tbl_int_dei_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +cppe_qos_mapping_tbl_int_dei_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +cppe_qos_mapping_tbl_int_dei_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +cppe_qos_mapping_tbl_int_dei_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +cppe_qos_mapping_tbl_dscp_tc_mask_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +cppe_qos_mapping_tbl_dscp_tc_mask_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +cppe_qos_mapping_tbl_int_dscp_tc_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +cppe_qos_mapping_tbl_int_dscp_tc_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +cppe_qos_mapping_tbl_int_dp_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +cppe_qos_mapping_tbl_int_dp_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +cppe_qos_mapping_tbl_int_dp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +cppe_qos_mapping_tbl_int_dp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +cppe_qos_mapping_tbl_int_pri_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +cppe_qos_mapping_tbl_int_pri_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +cppe_qos_mapping_tbl_qos_res_prec_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +cppe_qos_mapping_tbl_qos_res_prec_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +cppe_qos_mapping_tbl_int_pcp_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +cppe_qos_mapping_tbl_int_pcp_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +cppe_qos_mapping_tbl_int_pri_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +cppe_qos_mapping_tbl_int_pri_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +cppe_qos_mapping_tbl_int_dscp_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +cppe_qos_mapping_tbl_int_dscp_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +#endif \ No newline at end of file diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/cppe/cppe_qos_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/cppe/cppe_qos_reg.h new file mode 100755 index 000000000..92e473bc3 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/cppe/cppe_qos_reg.h @@ -0,0 +1,113 @@ +/* + * 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. + */ + + +/** + * @defgroup + * @{ + */ +#ifndef _CPPE_QOS_REG_H_ +#define _CPPE_QOS_REG_H_ + +/*[table] QOS_MAPPING_TBL*/ +#define QOS_MAPPING_TBL +#define QOS_MAPPING_TBL_ADDRESS 0x20000 +#define QOS_MAPPING_TBL_NUM 2592 +#define QOS_MAPPING_TBL_INC 0x10 +#define QOS_MAPPING_TBL_TYPE REG_TYPE_RW +#define QOS_MAPPING_TBL_DEFAULT 0x0 + /*[field] INT_DSCP_TC*/ + #define QOS_MAPPING_TBL_INT_DSCP_TC + #define QOS_MAPPING_TBL_INT_DSCP_TC_OFFSET 0 + #define QOS_MAPPING_TBL_INT_DSCP_TC_LEN 8 + #define QOS_MAPPING_TBL_INT_DSCP_TC_DEFAULT 0x0 + /*[field] DSCP_TC_MASK*/ + #define QOS_MAPPING_TBL_DSCP_TC_MASK + #define QOS_MAPPING_TBL_DSCP_TC_MASK_OFFSET 8 + #define QOS_MAPPING_TBL_DSCP_TC_MASK_LEN 8 + #define QOS_MAPPING_TBL_DSCP_TC_MASK_DEFAULT 0x0 + /*[field] INT_DSCP_EN*/ + #define QOS_MAPPING_TBL_INT_DSCP_EN + #define QOS_MAPPING_TBL_INT_DSCP_EN_OFFSET 16 + #define QOS_MAPPING_TBL_INT_DSCP_EN_LEN 1 + #define QOS_MAPPING_TBL_INT_DSCP_EN_DEFAULT 0x0 + /*[field] INT_PCP_EN*/ + #define QOS_MAPPING_TBL_INT_PCP_EN + #define QOS_MAPPING_TBL_INT_PCP_EN_OFFSET 17 + #define QOS_MAPPING_TBL_INT_PCP_EN_LEN 1 + #define QOS_MAPPING_TBL_INT_PCP_EN_DEFAULT 0x0 + /*[field] INT_PCP*/ + #define QOS_MAPPING_TBL_INT_PCP + #define QOS_MAPPING_TBL_INT_PCP_OFFSET 18 + #define QOS_MAPPING_TBL_INT_PCP_LEN 3 + #define QOS_MAPPING_TBL_INT_PCP_DEFAULT 0x0 + /*[field] INT_DEI_EN*/ + #define QOS_MAPPING_TBL_INT_DEI_EN + #define QOS_MAPPING_TBL_INT_DEI_EN_OFFSET 21 + #define QOS_MAPPING_TBL_INT_DEI_EN_LEN 1 + #define QOS_MAPPING_TBL_INT_DEI_EN_DEFAULT 0x0 + /*[field] INT_DEI*/ + #define QOS_MAPPING_TBL_INT_DEI + #define QOS_MAPPING_TBL_INT_DEI_OFFSET 22 + #define QOS_MAPPING_TBL_INT_DEI_LEN 1 + #define QOS_MAPPING_TBL_INT_DEI_DEFAULT 0x0 + /*[field] INT_PRI_EN*/ + #define QOS_MAPPING_TBL_INT_PRI_EN + #define QOS_MAPPING_TBL_INT_PRI_EN_OFFSET 23 + #define QOS_MAPPING_TBL_INT_PRI_EN_LEN 1 + #define QOS_MAPPING_TBL_INT_PRI_EN_DEFAULT 0x0 + /*[field] INT_PRI*/ + #define QOS_MAPPING_TBL_INT_PRI + #define QOS_MAPPING_TBL_INT_PRI_OFFSET 24 + #define QOS_MAPPING_TBL_INT_PRI_LEN 4 + #define QOS_MAPPING_TBL_INT_PRI_DEFAULT 0x0 + /*[field] INT_DP_EN*/ + #define QOS_MAPPING_TBL_INT_DP_EN + #define QOS_MAPPING_TBL_INT_DP_EN_OFFSET 28 + #define QOS_MAPPING_TBL_INT_DP_EN_LEN 1 + #define QOS_MAPPING_TBL_INT_DP_EN_DEFAULT 0x0 + /*[field] INT_DP*/ + #define QOS_MAPPING_TBL_INT_DP + #define QOS_MAPPING_TBL_INT_DP_OFFSET 29 + #define QOS_MAPPING_TBL_INT_DP_LEN 2 + #define QOS_MAPPING_TBL_INT_DP_DEFAULT 0x0 + /*[field] QOS_RES_PREC*/ + #define QOS_MAPPING_TBL_QOS_RES_PREC + #define QOS_MAPPING_TBL_QOS_RES_PREC_OFFSET 31 + #define QOS_MAPPING_TBL_QOS_RES_PREC_LEN 3 + #define QOS_MAPPING_TBL_QOS_RES_PREC_DEFAULT 0x0 + +struct qos_mapping_tbl { + a_uint32_t int_dscp_tc:8; + a_uint32_t dscp_tc_mask:8; + a_uint32_t int_dscp_en:1; + a_uint32_t int_pcp_en:1; + a_uint32_t int_pcp:3; + a_uint32_t int_dei_en:1; + a_uint32_t int_dei:1; + a_uint32_t int_pri_en:1; + a_uint32_t int_pri:4; + a_uint32_t int_dp_en:1; + a_uint32_t int_dp:2; + a_uint32_t qos_res_prec_0:1; + a_uint32_t qos_res_prec_1:2; + a_uint32_t _reserved0:30; +}; + +union qos_mapping_tbl_u { + a_uint32_t val[2]; + struct qos_mapping_tbl bf; +}; + +#endif \ No newline at end of file diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_acl.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_acl.h new file mode 100755 index 000000000..76e8fee9f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_acl.h @@ -0,0 +1,144 @@ +/* + * 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 dess_acl DESS_ACL + * @{ + */ +#ifndef _DESS_ACL_H_ +#define _DESS_ACL_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_acl.h" + + sw_error_t dess_acl_init(a_uint32_t dev_id); + + sw_error_t dess_acl_reset(a_uint32_t dev_id); + + sw_error_t dess_acl_cleanup(a_uint32_t dev_id); + + +#ifdef IN_ACL +#define DESS_ACL_INIT(rv, dev_id) \ + { \ + rv = dess_acl_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } + +#define DESS_ACL_RESET(rv, dev_id) \ + { \ + rv = dess_acl_reset(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } + +#define DESS_ACL_CLEANUP(rv, dev_id) \ + { \ + rv = dess_acl_cleanup(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define DESS_ACL_INIT(rv, dev_id) +#define DESS_ACL_RESET(rv, dev_id) +#define DESS_ACL_CLEANUP(rv, dev_id) +#endif + + sw_error_t + dess_acl_list_creat(a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t list_pri); + + sw_error_t + dess_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 + dess_acl_rule_delete(a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t rule_id, a_uint32_t rule_nr); + + a_uint32_t + dess_acl_rule_get_offset(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t rule_id); + + sw_error_t + dess_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 + dess_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 + dess_acl_status_set(a_uint32_t dev_id, a_bool_t enable); + + sw_error_t + dess_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 + dess_acl_rule_sync_multi_portmap(a_uint32_t dev_id, a_uint32_t pos, a_uint32_t *act); + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + dess_acl_list_destroy(a_uint32_t dev_id, a_uint32_t list_id); + + HSL_LOCAL sw_error_t + dess_acl_status_get(a_uint32_t dev_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + dess_acl_list_dump(a_uint32_t dev_id); + + HSL_LOCAL sw_error_t + dess_acl_rule_dump(a_uint32_t dev_id); + + HSL_LOCAL sw_error_t + dess_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); + + HSL_LOCAL sw_error_t + dess_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); + + HSL_LOCAL sw_error_t + dess_acl_rule_active(a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t rule_id, a_uint32_t rule_nr); + + HSL_LOCAL sw_error_t + dess_acl_rule_deactive(a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t rule_id, a_uint32_t rule_nr); + HSL_LOCAL sw_error_t + dess_acl_rule_src_filter_sts_set(a_uint32_t dev_id, + a_uint32_t rule_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + dess_acl_rule_src_filter_sts_get(a_uint32_t dev_id, + a_uint32_t rule_id, a_bool_t* enable); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _DESS_ACL_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_api.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_api.h new file mode 100755 index 000000000..7b92fbd34 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_api.h @@ -0,0 +1,1174 @@ +/* + * 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 _DESS_API_H_ +#define _DESS_API_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifdef IN_PORTCONTROL +#define PORTCONTROL_API \ + SW_API_DEF(SW_API_PT_DUPLEX_GET, dess_port_duplex_get), \ + SW_API_DEF(SW_API_PT_DUPLEX_SET, dess_port_duplex_set), \ + SW_API_DEF(SW_API_PT_SPEED_GET, dess_port_speed_get), \ + SW_API_DEF(SW_API_PT_SPEED_SET, dess_port_speed_set), \ + SW_API_DEF(SW_API_PT_AN_GET, dess_port_autoneg_status_get), \ + SW_API_DEF(SW_API_PT_AN_ENABLE, dess_port_autoneg_enable), \ + SW_API_DEF(SW_API_PT_AN_RESTART, dess_port_autoneg_restart), \ + SW_API_DEF(SW_API_PT_AN_ADV_GET, dess_port_autoneg_adv_get), \ + SW_API_DEF(SW_API_PT_AN_ADV_SET, dess_port_autoneg_adv_set), \ + SW_API_DEF(SW_API_PT_FLOWCTRL_SET, dess_port_flowctrl_set), \ + SW_API_DEF(SW_API_PT_FLOWCTRL_GET, dess_port_flowctrl_get), \ + SW_API_DEF(SW_API_PT_FLOWCTRL_MODE_SET, dess_port_flowctrl_forcemode_set), \ + SW_API_DEF(SW_API_PT_FLOWCTRL_MODE_GET, dess_port_flowctrl_forcemode_get), \ + SW_API_DEF(SW_API_PT_POWERSAVE_SET, dess_port_powersave_set), \ + SW_API_DEF(SW_API_PT_POWERSAVE_GET, dess_port_powersave_get), \ + SW_API_DEF(SW_API_PT_HIBERNATE_SET, dess_port_hibernate_set), \ + SW_API_DEF(SW_API_PT_HIBERNATE_GET, dess_port_hibernate_get), \ + SW_API_DEF(SW_API_PT_CDT, dess_port_cdt), \ + SW_API_DEF(SW_API_PT_TXHDR_SET, dess_port_txhdr_mode_set), \ + SW_API_DEF(SW_API_PT_TXHDR_GET, dess_port_txhdr_mode_get), \ + SW_API_DEF(SW_API_PT_RXHDR_SET, dess_port_rxhdr_mode_set), \ + SW_API_DEF(SW_API_PT_RXHDR_GET, dess_port_rxhdr_mode_get), \ + SW_API_DEF(SW_API_HEADER_TYPE_SET, dess_header_type_set), \ + SW_API_DEF(SW_API_HEADER_TYPE_GET, dess_header_type_get), \ + SW_API_DEF(SW_API_TXMAC_STATUS_SET, dess_port_txmac_status_set), \ + SW_API_DEF(SW_API_TXMAC_STATUS_GET, dess_port_txmac_status_get), \ + SW_API_DEF(SW_API_RXMAC_STATUS_SET, dess_port_rxmac_status_set), \ + SW_API_DEF(SW_API_RXMAC_STATUS_GET, dess_port_rxmac_status_get), \ + SW_API_DEF(SW_API_TXFC_STATUS_SET, dess_port_txfc_status_set), \ + SW_API_DEF(SW_API_TXFC_STATUS_GET, dess_port_txfc_status_get), \ + SW_API_DEF(SW_API_RXFC_STATUS_SET, dess_port_rxfc_status_set), \ + SW_API_DEF(SW_API_RXFC_STATUS_GET, dess_port_rxfc_status_get), \ + SW_API_DEF(SW_API_BP_STATUS_SET, dess_port_bp_status_set), \ + SW_API_DEF(SW_API_BP_STATUS_GET, dess_port_bp_status_get), \ + SW_API_DEF(SW_API_PT_LINK_MODE_SET, dess_port_link_forcemode_set), \ + SW_API_DEF(SW_API_PT_LINK_MODE_GET, dess_port_link_forcemode_get), \ + SW_API_DEF(SW_API_PT_LINK_STATUS_GET, dess_port_link_status_get), \ + SW_API_DEF(SW_API_PT_MAC_LOOPBACK_SET, dess_port_mac_loopback_set), \ + SW_API_DEF(SW_API_PT_MAC_LOOPBACK_GET, dess_port_mac_loopback_get), \ + SW_API_DEF(SW_API_PT_CONGESTION_DROP_SET, dess_port_congestion_drop_set), \ + SW_API_DEF(SW_API_PT_CONGESTION_DROP_GET, dess_port_congestion_drop_get), \ + SW_API_DEF(SW_API_PT_RING_FLOW_CTRL_THRES_SET, dess_ring_flow_ctrl_thres_set), \ + SW_API_DEF(SW_API_PT_RING_FLOW_CTRL_THRES_GET, dess_ring_flow_ctrl_thres_get),\ + SW_API_DEF(SW_API_PT_8023AZ_SET, dess_port_8023az_set), \ + SW_API_DEF(SW_API_PT_8023AZ_GET, dess_port_8023az_get), \ + SW_API_DEF(SW_API_PT_MDIX_SET, dess_port_mdix_set), \ + SW_API_DEF(SW_API_PT_MDIX_GET, dess_port_mdix_get), \ + SW_API_DEF(SW_API_PT_MDIX_STATUS_GET, dess_port_mdix_status_get), \ + SW_API_DEF(SW_API_PT_COMBO_PREFER_MEDIUM_SET, dess_port_combo_prefer_medium_set), \ + SW_API_DEF(SW_API_PT_COMBO_PREFER_MEDIUM_GET, dess_port_combo_prefer_medium_get), \ + SW_API_DEF(SW_API_PT_COMBO_MEDIUM_STATUS_GET, dess_port_combo_medium_status_get), \ + SW_API_DEF(SW_API_PT_COMBO_FIBER_MODE_SET, dess_port_combo_fiber_mode_set), \ + SW_API_DEF(SW_API_PT_COMBO_FIBER_MODE_GET, dess_port_combo_fiber_mode_get), \ + SW_API_DEF(SW_API_PT_LOCAL_LOOPBACK_SET, dess_port_local_loopback_set), \ + SW_API_DEF(SW_API_PT_LOCAL_LOOPBACK_GET, dess_port_local_loopback_get), \ + SW_API_DEF(SW_API_PT_REMOTE_LOOPBACK_SET, dess_port_remote_loopback_set), \ + SW_API_DEF(SW_API_PT_REMOTE_LOOPBACK_GET, dess_port_remote_loopback_get), \ + SW_API_DEF(SW_API_PT_RESET, dess_port_reset), \ + SW_API_DEF(SW_API_PT_POWER_OFF, dess_port_power_off), \ + SW_API_DEF(SW_API_PT_POWER_ON, dess_port_power_on), + +#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) \ + 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) \ + SW_API_DESC(SW_API_PT_HIBERNATE_SET) \ + SW_API_DESC(SW_API_PT_HIBERNATE_GET) \ + SW_API_DESC(SW_API_PT_CDT) \ + 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) \ + SW_API_DESC(SW_API_PT_LINK_STATUS_GET) \ + SW_API_DESC(SW_API_PT_MAC_LOOPBACK_SET) \ + SW_API_DESC(SW_API_PT_MAC_LOOPBACK_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)\ + 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) \ + 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) \ + 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) + +#else +#define PORTCONTROL_API +#define PORTCONTROL_API_PARAM +#endif + +#ifdef IN_VLAN +#define VLAN_API \ + SW_API_DEF(SW_API_VLAN_ADD, dess_vlan_create), \ + SW_API_DEF(SW_API_VLAN_DEL, dess_vlan_delete), \ + SW_API_DEF(SW_API_VLAN_FIND, dess_vlan_find), \ + SW_API_DEF(SW_API_VLAN_NEXT, dess_vlan_next), \ + SW_API_DEF(SW_API_VLAN_APPEND, dess_vlan_entry_append), \ + SW_API_DEF(SW_API_VLAN_FLUSH, dess_vlan_flush), \ + SW_API_DEF(SW_API_VLAN_FID_SET, dess_vlan_fid_set), \ + SW_API_DEF(SW_API_VLAN_FID_GET, dess_vlan_fid_get), \ + SW_API_DEF(SW_API_VLAN_MEMBER_ADD, dess_vlan_member_add), \ + SW_API_DEF(SW_API_VLAN_MEMBER_DEL, dess_vlan_member_del), \ + SW_API_DEF(SW_API_VLAN_LEARN_STATE_SET, dess_vlan_learning_state_set), \ + SW_API_DEF(SW_API_VLAN_LEARN_STATE_GET, dess_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_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, dess_port_1qmode_get), \ + SW_API_DEF(SW_API_PT_ING_MODE_SET, dess_port_1qmode_set), \ + SW_API_DEF(SW_API_PT_EG_MODE_GET, dess_port_egvlanmode_get), \ + SW_API_DEF(SW_API_PT_EG_MODE_SET, dess_port_egvlanmode_set), \ + SW_API_DEF(SW_API_PT_VLAN_MEM_ADD, dess_portvlan_member_add), \ + SW_API_DEF(SW_API_PT_VLAN_MEM_DEL, dess_portvlan_member_del), \ + SW_API_DEF(SW_API_PT_VLAN_MEM_UPDATE, dess_portvlan_member_update), \ + SW_API_DEF(SW_API_PT_VLAN_MEM_GET, dess_portvlan_member_get), \ + SW_API_DEF(SW_API_PT_FORCE_DEF_VID_SET, dess_port_force_default_vid_set), \ + SW_API_DEF(SW_API_PT_FORCE_DEF_VID_GET, dess_port_force_default_vid_get), \ + SW_API_DEF(SW_API_PT_FORCE_PORTVLAN_SET, dess_port_force_portvlan_set), \ + SW_API_DEF(SW_API_PT_FORCE_PORTVLAN_GET, dess_port_force_portvlan_get), \ + SW_API_DEF(SW_API_NESTVLAN_TPID_SET, dess_nestvlan_tpid_set), \ + SW_API_DEF(SW_API_NESTVLAN_TPID_GET, dess_nestvlan_tpid_get), \ + SW_API_DEF(SW_API_PT_IN_VLAN_MODE_SET, dess_port_invlan_mode_set), \ + SW_API_DEF(SW_API_PT_IN_VLAN_MODE_GET, dess_port_invlan_mode_get), \ + SW_API_DEF(SW_API_PT_TLS_SET, dess_port_tls_set), \ + SW_API_DEF(SW_API_PT_TLS_GET, dess_port_tls_get), \ + SW_API_DEF(SW_API_PT_PRI_PROPAGATION_SET, dess_port_pri_propagation_set), \ + SW_API_DEF(SW_API_PT_PRI_PROPAGATION_GET, dess_port_pri_propagation_get), \ + SW_API_DEF(SW_API_PT_DEF_SVID_SET, dess_port_default_svid_set), \ + SW_API_DEF(SW_API_PT_DEF_SVID_GET, dess_port_default_svid_get), \ + SW_API_DEF(SW_API_PT_DEF_CVID_SET, dess_port_default_cvid_set), \ + SW_API_DEF(SW_API_PT_DEF_CVID_GET, dess_port_default_cvid_get), \ + SW_API_DEF(SW_API_PT_VLAN_PROPAGATION_SET, dess_port_vlan_propagation_set), \ + SW_API_DEF(SW_API_PT_VLAN_PROPAGATION_GET, dess_port_vlan_propagation_get), \ + SW_API_DEF(SW_API_PT_VLAN_TRANS_ADD, dess_port_vlan_trans_add), \ + SW_API_DEF(SW_API_PT_VLAN_TRANS_DEL, dess_port_vlan_trans_del), \ + SW_API_DEF(SW_API_PT_VLAN_TRANS_GET, dess_port_vlan_trans_get), \ + SW_API_DEF(SW_API_QINQ_MODE_SET, dess_qinq_mode_set), \ + SW_API_DEF(SW_API_QINQ_MODE_GET, dess_qinq_mode_get), \ + SW_API_DEF(SW_API_PT_QINQ_ROLE_SET, dess_port_qinq_role_set), \ + SW_API_DEF(SW_API_PT_QINQ_ROLE_GET, dess_port_qinq_role_get), \ + SW_API_DEF(SW_API_PT_VLAN_TRANS_ITERATE, dess_port_vlan_trans_iterate), \ + SW_API_DEF(SW_API_PT_MAC_VLAN_XLT_SET, dess_port_mac_vlan_xlt_set), \ + SW_API_DEF(SW_API_PT_MAC_VLAN_XLT_GET, dess_port_mac_vlan_xlt_get), \ + SW_API_DEF(SW_API_NETISOLATE_SET, dess_netisolate_set), \ + SW_API_DEF(SW_API_NETISOLATE_GET, dess_netisolate_get),\ + SW_API_DEF(SW_API_EG_FLTR_BYPASS_EN_SET, dess_eg_trans_filter_bypass_en_set), \ + SW_API_DEF(SW_API_EG_FLTR_BYPASS_EN_GET, dess_eg_trans_filter_bypass_en_get), + + +#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_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_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) + +#else +#define PORTVLAN_API +#define PORTVLAN_API_PARAM +#endif + +#ifdef IN_FDB +#define FDB_API \ + SW_API_DEF(SW_API_FDB_ADD, dess_fdb_add), \ + SW_API_DEF(SW_API_FDB_DELALL, dess_fdb_del_all), \ + SW_API_DEF(SW_API_FDB_DELPORT,dess_fdb_del_by_port), \ + SW_API_DEF(SW_API_FDB_DELMAC, dess_fdb_del_by_mac), \ + SW_API_DEF(SW_API_FDB_FIND, dess_fdb_find), \ + SW_API_DEF(SW_API_FDB_EXTEND_NEXT, dess_fdb_extend_next), \ + SW_API_DEF(SW_API_FDB_EXTEND_FIRST, dess_fdb_extend_first), \ + SW_API_DEF(SW_API_FDB_TRANSFER, dess_fdb_transfer), \ + SW_API_DEF(SW_API_FDB_PT_LEARN_SET, dess_fdb_port_learn_set), \ + SW_API_DEF(SW_API_FDB_PT_LEARN_GET, dess_fdb_port_learn_get), \ + SW_API_DEF(SW_API_FDB_AGE_CTRL_SET, dess_fdb_age_ctrl_set), \ + SW_API_DEF(SW_API_FDB_AGE_CTRL_GET, dess_fdb_age_ctrl_get), \ + SW_API_DEF(SW_API_FDB_VLAN_IVL_SVL_SET, dess_fdb_vlan_ivl_svl_set),\ + SW_API_DEF(SW_API_FDB_VLAN_IVL_SVL_GET, dess_fdb_vlan_ivl_svl_get),\ + SW_API_DEF(SW_API_FDB_AGE_TIME_SET, dess_fdb_age_time_set), \ + SW_API_DEF(SW_API_FDB_AGE_TIME_GET, dess_fdb_age_time_get), \ + SW_API_DEF(SW_API_PT_FDB_LEARN_LIMIT_SET, dess_port_fdb_learn_limit_set), \ + SW_API_DEF(SW_API_PT_FDB_LEARN_LIMIT_GET, dess_port_fdb_learn_limit_get), \ + SW_API_DEF(SW_API_PT_FDB_LEARN_EXCEED_CMD_SET, dess_port_fdb_learn_exceed_cmd_set), \ + SW_API_DEF(SW_API_PT_FDB_LEARN_EXCEED_CMD_GET, dess_port_fdb_learn_exceed_cmd_get), \ + SW_API_DEF(SW_API_FDB_LEARN_LIMIT_SET, dess_fdb_learn_limit_set), \ + SW_API_DEF(SW_API_FDB_LEARN_LIMIT_GET, dess_fdb_learn_limit_get), \ + SW_API_DEF(SW_API_FDB_LEARN_EXCEED_CMD_SET, dess_fdb_learn_exceed_cmd_set), \ + SW_API_DEF(SW_API_FDB_LEARN_EXCEED_CMD_GET, dess_fdb_learn_exceed_cmd_get), \ + SW_API_DEF(SW_API_FDB_RESV_ADD, dess_fdb_resv_add), \ + SW_API_DEF(SW_API_FDB_RESV_DEL, dess_fdb_resv_del), \ + SW_API_DEF(SW_API_FDB_RESV_FIND, dess_fdb_resv_find), \ + SW_API_DEF(SW_API_FDB_RESV_ITERATE, dess_fdb_resv_iterate), \ + SW_API_DEF(SW_API_FDB_PT_LEARN_STATIC_SET, dess_fdb_port_learn_static_set), \ + SW_API_DEF(SW_API_FDB_PT_LEARN_STATIC_GET, dess_fdb_port_learn_static_get), \ + SW_API_DEF(SW_API_FDB_PORT_ADD, dess_fdb_port_add), \ + SW_API_DEF(SW_API_FDB_PORT_DEL, dess_fdb_port_del), + +#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_FIND) \ + 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_FDB_PT_LEARN_SET) \ + SW_API_DESC(SW_API_FDB_PT_LEARN_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_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_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) + +#else +#define FDB_API +#define FDB_API_PARAM +#endif + + +#ifdef IN_ACL +#define ACL_API \ + SW_API_DEF(SW_API_ACL_LIST_CREAT, dess_acl_list_creat), \ + SW_API_DEF(SW_API_ACL_LIST_DESTROY, dess_acl_list_destroy), \ + SW_API_DEF(SW_API_ACL_RULE_ADD, dess_acl_rule_add), \ + SW_API_DEF(SW_API_ACL_RULE_DELETE, dess_acl_rule_delete), \ + SW_API_DEF(SW_API_ACL_RULE_QUERY, dess_acl_rule_query), \ + SW_API_DEF(SW_API_ACL_LIST_BIND, dess_acl_list_bind), \ + SW_API_DEF(SW_API_ACL_LIST_UNBIND, dess_acl_list_unbind), \ + SW_API_DEF(SW_API_ACL_STATUS_SET, dess_acl_status_set), \ + SW_API_DEF(SW_API_ACL_STATUS_GET, dess_acl_status_get), \ + SW_API_DEF(SW_API_ACL_LIST_DUMP, dess_acl_list_dump), \ + SW_API_DEF(SW_API_ACL_RULE_DUMP, dess_acl_rule_dump), \ + SW_API_DEF(SW_API_ACL_PT_UDF_PROFILE_SET, dessort_udf_profile_set), \ + SW_API_DEF(SW_API_ACL_PT_UDF_PROFILE_GET, dess_acl_port_udf_profile_get), \ + SW_API_DEF(SW_API_ACL_RULE_ACTIVE, dess_acl_rule_active), \ + SW_API_DEF(SW_API_ACL_RULE_DEACTIVE, dess_acl_rule_deactive),\ + SW_API_DEF(SW_API_ACL_RULE_SRC_FILTER_STS_SET, dess_acl_rule_src_filter_sts_set),\ + SW_API_DEF(SW_API_ACL_RULE_SRC_FILTER_STS_GET, dess_acl_rule_src_filter_sts_get), \ + SW_API_DEF(SW_API_ACL_RULE_GET_OFFSET, dess_acl_rule_get_offset), + +#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) +#else +#define ACL_API +#define ACL_API_PARAM +#endif + + +#ifdef IN_QOS +#define QOS_API \ + SW_API_DEF(SW_API_QOS_QU_TX_BUF_ST_SET, dess_qos_queue_tx_buf_status_set), \ + SW_API_DEF(SW_API_QOS_QU_TX_BUF_ST_GET, dess_qos_queue_tx_buf_status_get), \ + SW_API_DEF(SW_API_QOS_QU_TX_BUF_NR_SET, dess_qos_queue_tx_buf_nr_set), \ + SW_API_DEF(SW_API_QOS_QU_TX_BUF_NR_GET, dess_qos_queue_tx_buf_nr_get), \ + SW_API_DEF(SW_API_QOS_PT_TX_BUF_ST_SET, dess_qos_port_tx_buf_status_set), \ + SW_API_DEF(SW_API_QOS_PT_TX_BUF_ST_GET, dess_qos_port_tx_buf_status_get), \ + SW_API_DEF(SW_API_QOS_PT_RED_EN_SET, dess_qos_port_red_en_set),\ + SW_API_DEF(SW_API_QOS_PT_RED_EN_GET, dess_qos_port_red_en_get),\ + SW_API_DEF(SW_API_QOS_PT_TX_BUF_NR_SET, dess_qos_port_tx_buf_nr_set), \ + SW_API_DEF(SW_API_QOS_PT_TX_BUF_NR_GET, dess_qos_port_tx_buf_nr_get), \ + SW_API_DEF(SW_API_QOS_PT_RX_BUF_NR_SET, dess_qos_port_rx_buf_nr_set), \ + SW_API_DEF(SW_API_QOS_PT_RX_BUF_NR_GET, dess_qos_port_rx_buf_nr_get), \ + SW_API_DEF(SW_API_QOS_PT_MODE_SET, dess_qos_port_mode_set), \ + SW_API_DEF(SW_API_QOS_PT_MODE_GET, dess_qos_port_mode_get), \ + SW_API_DEF(SW_API_QOS_PT_MODE_PRI_SET, dess_qos_port_mode_pri_set), \ + SW_API_DEF(SW_API_QOS_PT_MODE_PRI_GET, dess_qos_port_mode_pri_get), \ + SW_API_DEF(SW_API_QOS_PORT_SCH_MODE_SET, dess_qos_port_sch_mode_set), \ + SW_API_DEF(SW_API_QOS_PORT_SCH_MODE_GET, dess_qos_port_sch_mode_get), \ + SW_API_DEF(SW_API_QOS_PT_DEF_SPRI_SET, dess_qos_port_default_spri_set), \ + SW_API_DEF(SW_API_QOS_PT_DEF_SPRI_GET, dess_qos_port_default_spri_get), \ + SW_API_DEF(SW_API_QOS_PT_DEF_CPRI_SET, dess_qos_port_default_cpri_set), \ + SW_API_DEF(SW_API_QOS_PT_DEF_CPRI_GET, dess_qos_port_default_cpri_get), \ + SW_API_DEF(SW_API_QOS_PT_FORCE_SPRI_ST_SET, dess_qos_port_force_spri_status_set), \ + SW_API_DEF(SW_API_QOS_PT_FORCE_SPRI_ST_GET, dess_qos_port_force_spri_status_get), \ + SW_API_DEF(SW_API_QOS_PT_FORCE_CPRI_ST_SET, dess_qos_port_force_cpri_status_set), \ + SW_API_DEF(SW_API_QOS_PT_FORCE_CPRI_ST_GET, dess_qos_port_force_cpri_status_get), \ + SW_API_DEF(SW_API_QOS_QUEUE_REMARK_SET, dess_qos_queue_remark_table_set), \ + SW_API_DEF(SW_API_QOS_QUEUE_REMARK_GET, dess_qos_queue_remark_table_get), + + +#define QOS_API_PARAM \ + 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_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) +#else +#define QOS_API +#define QOS_API_PARAM +#endif + + +#ifdef IN_IGMP +#define IGMP_API \ + SW_API_DEF(SW_API_PT_IGMPS_MODE_SET, dess_port_igmps_status_set), \ + SW_API_DEF(SW_API_PT_IGMPS_MODE_GET, dess_port_igmps_status_get), \ + SW_API_DEF(SW_API_IGMP_MLD_CMD_SET, dess_igmp_mld_cmd_set), \ + SW_API_DEF(SW_API_IGMP_MLD_CMD_GET, dess_igmp_mld_cmd_get), \ + SW_API_DEF(SW_API_IGMP_PT_JOIN_SET, dess_port_igmp_mld_join_set), \ + SW_API_DEF(SW_API_IGMP_PT_JOIN_GET, dess_port_igmp_mld_join_get), \ + SW_API_DEF(SW_API_IGMP_PT_LEAVE_SET, dess_port_igmp_mld_leave_set), \ + SW_API_DEF(SW_API_IGMP_PT_LEAVE_GET, dess_port_igmp_mld_leave_get), \ + SW_API_DEF(SW_API_IGMP_RP_SET, dess_igmp_mld_rp_set), \ + SW_API_DEF(SW_API_IGMP_RP_GET, dess_igmp_mld_rp_get), \ + SW_API_DEF(SW_API_IGMP_ENTRY_CREAT_SET, dess_igmp_mld_entry_creat_set), \ + SW_API_DEF(SW_API_IGMP_ENTRY_CREAT_GET, dess_igmp_mld_entry_creat_get), \ + SW_API_DEF(SW_API_IGMP_ENTRY_STATIC_SET, dess_igmp_mld_entry_static_set), \ + SW_API_DEF(SW_API_IGMP_ENTRY_STATIC_GET, dess_igmp_mld_entry_static_get), \ + SW_API_DEF(SW_API_IGMP_ENTRY_LEAKY_SET, dess_igmp_mld_entry_leaky_set), \ + SW_API_DEF(SW_API_IGMP_ENTRY_LEAKY_GET, dess_igmp_mld_entry_leaky_get), \ + SW_API_DEF(SW_API_IGMP_ENTRY_V3_SET, dess_igmp_mld_entry_v3_set), \ + SW_API_DEF(SW_API_IGMP_ENTRY_V3_GET, dess_igmp_mld_entry_v3_get), \ + SW_API_DEF(SW_API_IGMP_ENTRY_QUEUE_SET, dess_igmp_mld_entry_queue_set), \ + SW_API_DEF(SW_API_IGMP_ENTRY_QUEUE_GET, dess_igmp_mld_entry_queue_get), \ + SW_API_DEF(SW_API_PT_IGMP_LEARN_LIMIT_SET, dess_port_igmp_mld_learn_limit_set), \ + SW_API_DEF(SW_API_PT_IGMP_LEARN_LIMIT_GET, dess_port_igmp_mld_learn_limit_get), \ + SW_API_DEF(SW_API_PT_IGMP_LEARN_EXCEED_CMD_SET, dess_port_igmp_mld_learn_exceed_cmd_set), \ + SW_API_DEF(SW_API_PT_IGMP_LEARN_EXCEED_CMD_GET, dess_port_igmp_mld_learn_exceed_cmd_get), \ + SW_API_DEF(SW_API_IGMP_SG_ENTRY_SET, dess_igmp_sg_entry_set), \ + SW_API_DEF(SW_API_IGMP_SG_ENTRY_CLEAR, dess_igmp_sg_entry_clear), \ + SW_API_DEF(SW_API_IGMP_SG_ENTRY_SHOW, dess_igmp_sg_entry_show), + +#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) +#else +#define IGMP_API +#define IGMP_API_PARAM +#endif + + +#ifdef IN_LEAKY +#define LEAKY_API \ + SW_API_DEF(SW_API_UC_LEAKY_MODE_SET, dess_uc_leaky_mode_set), \ + SW_API_DEF(SW_API_UC_LEAKY_MODE_GET, dess_uc_leaky_mode_get), \ + SW_API_DEF(SW_API_MC_LEAKY_MODE_SET, dess_mc_leaky_mode_set), \ + SW_API_DEF(SW_API_MC_LEAKY_MODE_GET, dess_mc_leaky_mode_get), \ + SW_API_DEF(SW_API_ARP_LEAKY_MODE_SET, dess_port_arp_leaky_set), \ + SW_API_DEF(SW_API_ARP_LEAKY_MODE_GET, dess_port_arp_leaky_get), \ + SW_API_DEF(SW_API_PT_UC_LEAKY_MODE_SET, dess_port_uc_leaky_set), \ + SW_API_DEF(SW_API_PT_UC_LEAKY_MODE_GET, dess_port_uc_leaky_get), \ + SW_API_DEF(SW_API_PT_MC_LEAKY_MODE_SET, dess_port_mc_leaky_set), \ + SW_API_DEF(SW_API_PT_MC_LEAKY_MODE_GET, dess_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, dess_mirr_analysis_port_set), \ + SW_API_DEF(SW_API_MIRROR_ANALY_PT_GET, dess_mirr_analysis_port_get), \ + SW_API_DEF(SW_API_MIRROR_IN_PT_SET, dess_mirr_port_in_set), \ + SW_API_DEF(SW_API_MIRROR_IN_PT_GET, dess_mirr_port_in_get), \ + SW_API_DEF(SW_API_MIRROR_EG_PT_SET, dess_mirr_port_eg_set), \ + SW_API_DEF(SW_API_MIRROR_EG_PT_GET, dess_mirr_port_eg_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) +#else +#define MIRROR_API +#define MIRROR_API_PARAM +#endif + + +#ifdef IN_RATE +#define RATE_API \ + SW_API_DEF(SW_API_RATE_PORT_POLICER_SET, dess_rate_port_policer_set), \ + SW_API_DEF(SW_API_RATE_PORT_POLICER_GET, dess_rate_port_policer_get), \ + SW_API_DEF(SW_API_RATE_PORT_SHAPER_SET, dess_rate_port_shaper_set), \ + SW_API_DEF(SW_API_RATE_PORT_SHAPER_GET, dess_rate_port_shaper_get), \ + SW_API_DEF(SW_API_RATE_QUEUE_SHAPER_SET, dess_rate_queue_shaper_set), \ + SW_API_DEF(SW_API_RATE_QUEUE_SHAPER_GET, dess_rate_queue_shaper_get), \ + SW_API_DEF(SW_API_RATE_ACL_POLICER_SET, dess_rate_acl_policer_set), \ + SW_API_DEF(SW_API_RATE_ACL_POLICER_GET, dess_rate_acl_policer_get), \ + SW_API_DEF(SW_API_RATE_PT_ADDRATEBYTE_SET, dess_rate_port_add_rate_byte_set), \ + SW_API_DEF(SW_API_RATE_PT_ADDRATEBYTE_GET, dess_rate_port_add_rate_byte_get), \ + SW_API_DEF(SW_API_RATE_PT_GOL_FLOW_EN_SET, dess_rate_port_gol_flow_en_set), \ + SW_API_DEF(SW_API_RATE_PT_GOL_FLOW_EN_GET, dess_rate_port_gol_flow_en_get), + +#define RATE_API_PARAM \ + 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, dess_stp_port_state_set), \ + SW_API_DEF(SW_API_STP_PT_STATE_GET, dess_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, dess_get_mib_info), \ + SW_API_DEF(SW_API_MIB_STATUS_SET, dess_mib_status_set), \ + SW_API_DEF(SW_API_MIB_STATUS_GET, dess_mib_status_get), \ + SW_API_DEF(SW_API_PT_MIB_FLUSH_COUNTERS, dess_mib_port_flush_counters), \ + SW_API_DEF(SW_API_MIB_CPU_KEEP_SET, dess_mib_cpukeep_set), \ + SW_API_DEF(SW_API_MIB_CPU_KEEP_GET, dess_mib_cpukeep_get), + + +#define MIB_API_PARAM \ + SW_API_DESC(SW_API_PT_MIB_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) +#else +#define MIB_API +#define MIB_API_PARAM +#endif + + +#ifdef IN_MISC +#define MISC_API \ + SW_API_DEF(SW_API_FRAME_MAX_SIZE_SET, dess_frame_max_size_set), \ + SW_API_DEF(SW_API_FRAME_MAX_SIZE_GET, dess_frame_max_size_get), \ + SW_API_DEF(SW_API_PT_UNK_UC_FILTER_SET, dess_port_unk_uc_filter_set), \ + SW_API_DEF(SW_API_PT_UNK_UC_FILTER_GET, dess_port_unk_uc_filter_get), \ + SW_API_DEF(SW_API_PT_UNK_MC_FILTER_SET, dess_port_unk_mc_filter_set), \ + SW_API_DEF(SW_API_PT_UNK_MC_FILTER_GET, dess_port_unk_mc_filter_get), \ + SW_API_DEF(SW_API_PT_BC_FILTER_SET, dess_port_bc_filter_set), \ + SW_API_DEF(SW_API_PT_BC_FILTER_GET, dess_port_bc_filter_get), \ + SW_API_DEF(SW_API_CPU_PORT_STATUS_SET, dess_cpu_port_status_set), \ + SW_API_DEF(SW_API_CPU_PORT_STATUS_GET, dess_cpu_port_status_get), \ + SW_API_DEF(SW_API_PPPOE_CMD_SET, dess_pppoe_cmd_set), \ + SW_API_DEF(SW_API_PPPOE_CMD_GET, dess_pppoe_cmd_get), \ + SW_API_DEF(SW_API_PPPOE_STATUS_SET, dess_pppoe_status_set), \ + SW_API_DEF(SW_API_PPPOE_STATUS_GET, dess_pppoe_status_get), \ + SW_API_DEF(SW_API_PT_DHCP_SET, dess_port_dhcp_set), \ + SW_API_DEF(SW_API_PT_DHCP_GET, dess_port_dhcp_get), \ + SW_API_DEF(SW_API_ARP_CMD_SET, dess_arp_cmd_set), \ + SW_API_DEF(SW_API_ARP_CMD_GET, dess_arp_cmd_get), \ + SW_API_DEF(SW_API_EAPOL_CMD_SET, dess_eapol_cmd_set), \ + SW_API_DEF(SW_API_EAPOL_CMD_GET, dess_eapol_cmd_get), \ + SW_API_DEF(SW_API_EAPOL_STATUS_SET, dess_eapol_status_set), \ + SW_API_DEF(SW_API_EAPOL_STATUS_GET, dess_eapol_status_get), \ + SW_API_DEF(SW_API_RIPV1_STATUS_SET, dess_ripv1_status_set), \ + SW_API_DEF(SW_API_RIPV1_STATUS_GET, dess_ripv1_status_get), \ + SW_API_DEF(SW_API_PT_ARP_REQ_STATUS_SET, dess_port_arp_req_status_set), \ + SW_API_DEF(SW_API_PT_ARP_REQ_STATUS_GET, dess_port_arp_req_status_get), \ + SW_API_DEF(SW_API_PT_ARP_ACK_STATUS_SET, dess_port_arp_ack_status_set), \ + SW_API_DEF(SW_API_PT_ARP_ACK_STATUS_GET, dess_port_arp_ack_status_get), \ + SW_API_DEF(SW_API_PPPOE_SESSION_TABLE_ADD, dess_pppoe_session_table_add), \ + SW_API_DEF(SW_API_PPPOE_SESSION_TABLE_DEL, dess_pppoe_session_table_del), \ + SW_API_DEF(SW_API_PPPOE_SESSION_TABLE_GET, dess_pppoe_session_table_get), \ + SW_API_DEF(SW_API_PPPOE_SESSION_ID_SET, dess_pppoe_session_id_set), \ + SW_API_DEF(SW_API_PPPOE_SESSION_ID_GET, dess_pppoe_session_id_get), \ + SW_API_DEF(SW_API_INTR_MASK_SET, dess_intr_mask_set), \ + SW_API_DEF(SW_API_INTR_MASK_GET, dess_intr_mask_get), \ + SW_API_DEF(SW_API_INTR_STATUS_GET, dess_intr_status_get), \ + SW_API_DEF(SW_API_INTR_STATUS_CLEAR, dess_intr_status_clear), \ + SW_API_DEF(SW_API_INTR_PORT_LINK_MASK_SET, dess_intr_port_link_mask_set), \ + SW_API_DEF(SW_API_INTR_PORT_LINK_MASK_GET, dess_intr_port_link_mask_get), \ + SW_API_DEF(SW_API_INTR_PORT_LINK_STATUS_GET, dess_intr_port_link_status_get),\ + SW_API_DEF(SW_API_INTR_MASK_MAC_LINKCHG_SET, dess_intr_mask_mac_linkchg_set), \ + SW_API_DEF(SW_API_INTR_MASK_MAC_LINKCHG_GET, dess_intr_mask_mac_linkchg_get), \ + SW_API_DEF(SW_API_INTR_STATUS_MAC_LINKCHG_GET, dess_intr_status_mac_linkchg_get), \ + SW_API_DEF(SW_API_INTR_STATUS_MAC_LINKCHG_CLEAR, dess_intr_status_mac_linkchg_clear), \ + SW_API_DEF(SW_API_CPU_VID_EN_SET, dess_cpu_vid_en_set), \ + SW_API_DEF(SW_API_CPU_VID_EN_GET, dess_cpu_vid_en_get), \ + SW_API_DEF(SW_API_RTD_PPPOE_EN_SET, dess_rtd_pppoe_en_set), \ + SW_API_DEF(SW_API_RTD_PPPOE_EN_GET, dess_rtd_pppoe_en_get), \ + SW_API_DEF(SW_API_GLOBAL_MACADDR_SET, dess_global_macaddr_set), \ + SW_API_DEF(SW_API_GLOBAL_MACADDR_GET, dess_global_macaddr_get), \ + SW_API_DEF(SW_API_LLDP_STATUS_SET, dess_lldp_status_set), \ + SW_API_DEF(SW_API_LLDP_STATUS_GET, dess_lldp_status_get), \ + SW_API_DEF(SW_API_FRAME_CRC_RESERVE_SET, dess_frame_crc_reserve_set), \ + SW_API_DEF(SW_API_FRAME_CRC_RESERVE_GET, dess_frame_crc_reserve_get), + +#define MISC_API_PARAM \ + 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_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_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_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_PPPOE_SESSION_ADD) \ + SW_API_DESC(SW_API_PPPOE_SESSION_DEL) \ + SW_API_DESC(SW_API_PPPOE_SESSION_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_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_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_RTD_PPPOE_EN_SET) \ + SW_API_DESC(SW_API_RTD_PPPOE_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) + +#else +#define MISC_API +#define MISC_API_PARAM +#endif + + +#ifdef IN_LED +#define LED_API \ + SW_API_DEF(SW_API_LED_PATTERN_SET, dess_led_ctrl_pattern_set), \ + SW_API_DEF(SW_API_LED_PATTERN_GET, dess_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, dess_cosmap_dscp_to_pri_set), \ + SW_API_DEF(SW_API_COSMAP_DSCP_TO_PRI_GET, dess_cosmap_dscp_to_pri_get), \ + SW_API_DEF(SW_API_COSMAP_DSCP_TO_DP_SET, dess_cosmap_dscp_to_dp_set), \ + SW_API_DEF(SW_API_COSMAP_DSCP_TO_DP_GET, dess_cosmap_dscp_to_dp_get), \ + SW_API_DEF(SW_API_COSMAP_UP_TO_PRI_SET, dess_cosmap_up_to_pri_set), \ + SW_API_DEF(SW_API_COSMAP_UP_TO_PRI_GET, dess_cosmap_up_to_pri_get), \ + SW_API_DEF(SW_API_COSMAP_UP_TO_DP_SET, dess_cosmap_up_to_dp_set), \ + SW_API_DEF(SW_API_COSMAP_UP_TO_DP_GET, dess_cosmap_up_to_dp_get), \ + SW_API_DEF(SW_API_COSMAP_PRI_TO_QU_SET, dess_cosmap_pri_to_queue_set), \ + SW_API_DEF(SW_API_COSMAP_PRI_TO_QU_GET, dess_cosmap_pri_to_queue_get), \ + SW_API_DEF(SW_API_COSMAP_PRI_TO_EHQU_SET, dess_cosmap_pri_to_ehqueue_set), \ + SW_API_DEF(SW_API_COSMAP_PRI_TO_EHQU_GET, dess_cosmap_pri_to_ehqueue_get), \ + SW_API_DEF(SW_API_COSMAP_EG_REMARK_SET, dess_cosmap_egress_remark_set), \ + SW_API_DEF(SW_API_COSMAP_EG_REMARK_GET, dess_cosmap_egress_remark_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) +#else +#define COSMAP_API +#define COSMAP_API_PARAM +#endif + +#ifdef IN_SEC +#define SEC_API \ + SW_API_DEF(SW_API_SEC_NORM_SET, dess_sec_norm_item_set), \ + SW_API_DEF(SW_API_SEC_NORM_GET, dess_sec_norm_item_get), \ + SW_API_DEF(SW_API_SEC_MAC_SET, dess_sec_norm_item_set), \ + SW_API_DEF(SW_API_SEC_MAC_GET, dess_sec_norm_item_get), \ + SW_API_DEF(SW_API_SEC_IP_SET, dess_sec_norm_item_set), \ + SW_API_DEF(SW_API_SEC_IP_GET, dess_sec_norm_item_get), \ + SW_API_DEF(SW_API_SEC_IP4_SET, dess_sec_norm_item_set), \ + SW_API_DEF(SW_API_SEC_IP4_GET, dess_sec_norm_item_get), \ + SW_API_DEF(SW_API_SEC_IP6_SET, dess_sec_norm_item_set), \ + SW_API_DEF(SW_API_SEC_IP6_GET, dess_sec_norm_item_get), \ + SW_API_DEF(SW_API_SEC_TCP_SET, dess_sec_norm_item_set), \ + SW_API_DEF(SW_API_SEC_TCP_GET, dess_sec_norm_item_get), \ + SW_API_DEF(SW_API_SEC_UDP_SET, dess_sec_norm_item_set), \ + SW_API_DEF(SW_API_SEC_UDP_GET, dess_sec_norm_item_get), \ + SW_API_DEF(SW_API_SEC_ICMP4_SET, dess_sec_norm_item_set), \ + SW_API_DEF(SW_API_SEC_ICMP4_GET, dess_sec_norm_item_get), \ + SW_API_DEF(SW_API_SEC_ICMP6_SET, dess_sec_norm_item_set), \ + SW_API_DEF(SW_API_SEC_ICMP6_GET, dess_sec_norm_item_get), + +#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) +#else +#define SEC_API +#define SEC_API_PARAM +#endif + +#ifdef IN_IP +#define IP_API \ + SW_API_DEF(SW_API_IP_HOST_ADD, dess_ip_host_add), \ + SW_API_DEF(SW_API_IP_HOST_DEL, dess_ip_host_del), \ + SW_API_DEF(SW_API_IP_HOST_GET, dess_ip_host_get), \ + SW_API_DEF(SW_API_IP_HOST_NEXT, dess_ip_host_next), \ + SW_API_DEF(SW_API_IP_HOST_COUNTER_BIND, dess_ip_host_counter_bind), \ + SW_API_DEF(SW_API_IP_HOST_PPPOE_BIND, dess_ip_host_pppoe_bind), \ + SW_API_DEF(SW_API_IP_PT_ARP_LEARN_SET, dess_ip_pt_arp_learn_set), \ + SW_API_DEF(SW_API_IP_PT_ARP_LEARN_GET, dess_ip_pt_arp_learn_get), \ + SW_API_DEF(SW_API_IP_ARP_LEARN_SET, dess_ip_arp_learn_set), \ + SW_API_DEF(SW_API_IP_ARP_LEARN_GET, dess_ip_arp_learn_get), \ + SW_API_DEF(SW_API_IP_SOURCE_GUARD_SET, dess_ip_source_guard_set), \ + SW_API_DEF(SW_API_IP_SOURCE_GUARD_GET, dess_ip_source_guard_get), \ + SW_API_DEF(SW_API_IP_ARP_GUARD_SET, dess_ip_arp_guard_set), \ + SW_API_DEF(SW_API_IP_ARP_GUARD_GET, dess_ip_arp_guard_get), \ + SW_API_DEF(SW_API_IP_ROUTE_STATUS_SET, dess_ip_route_status_set), \ + SW_API_DEF(SW_API_IP_ROUTE_STATUS_GET, dess_ip_route_status_get), \ + SW_API_DEF(SW_API_IP_INTF_ENTRY_ADD, dess_ip_intf_entry_add), \ + SW_API_DEF(SW_API_IP_INTF_ENTRY_DEL, dess_ip_intf_entry_del), \ + SW_API_DEF(SW_API_IP_INTF_ENTRY_NEXT, dess_ip_intf_entry_next), \ + SW_API_DEF(SW_API_IP_UNK_SOURCE_CMD_SET, dess_ip_unk_source_cmd_set), \ + SW_API_DEF(SW_API_IP_UNK_SOURCE_CMD_GET, dess_ip_unk_source_cmd_get), \ + SW_API_DEF(SW_API_ARP_UNK_SOURCE_CMD_SET, dess_arp_unk_source_cmd_set), \ + SW_API_DEF(SW_API_ARP_UNK_SOURCE_CMD_GET, dess_arp_unk_source_cmd_get), \ + SW_API_DEF(SW_API_IP_AGE_TIME_SET, dess_ip_age_time_set), \ + SW_API_DEF(SW_API_IP_AGE_TIME_GET, dess_ip_age_time_get), \ + SW_API_DEF(SW_API_WCMP_HASH_MODE_SET, dess_ip_wcmp_hash_mode_set), \ + SW_API_DEF(SW_API_WCMP_HASH_MODE_GET, dess_ip_wcmp_hash_mode_get), \ + SW_API_DEF(SW_API_IP_DEFAULT_FLOW_CMD_SET, dess_default_flow_cmd_set), \ + SW_API_DEF(SW_API_IP_DEFAULT_FLOW_CMD_GET, dess_default_flow_cmd_get), \ + SW_API_DEF(SW_API_IP_DEFAULT_RT_FLOW_CMD_SET, dess_default_rt_flow_cmd_set), \ + SW_API_DEF(SW_API_IP_DEFAULT_RT_FLOW_CMD_GET, dess_default_rt_flow_cmd_get), + +#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_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) + +#else +#define IP_API +#define IP_API_PARAM +#endif + +#ifdef IN_NAT +#define NAT_API \ + SW_API_DEF(SW_API_NAT_ADD, dess_nat_add), \ + SW_API_DEF(SW_API_NAT_DEL, dess_nat_del), \ + SW_API_DEF(SW_API_NAT_GET, dess_nat_get), \ + SW_API_DEF(SW_API_NAT_NEXT, dess_nat_next), \ + SW_API_DEF(SW_API_NAT_COUNTER_BIND, dess_nat_counter_bind), \ + SW_API_DEF(SW_API_NAPT_ADD, dess_napt_add), \ + SW_API_DEF(SW_API_NAPT_DEL, dess_napt_del), \ + SW_API_DEF(SW_API_NAPT_GET, dess_napt_get), \ + SW_API_DEF(SW_API_NAPT_NEXT, dess_napt_next), \ + SW_API_DEF(SW_API_NAPT_COUNTER_BIND, dess_napt_counter_bind), \ + SW_API_DEF(SW_API_FLOW_ADD, dess_flow_add), \ + SW_API_DEF(SW_API_FLOW_DEL, dess_flow_del), \ + SW_API_DEF(SW_API_FLOW_GET, dess_flow_get), \ + SW_API_DEF(SW_API_FLOW_NEXT, dess_flow_next), \ + SW_API_DEF(SW_API_FLOW_COUNTER_BIND, dess_flow_counter_bind), \ + SW_API_DEF(SW_API_NAT_STATUS_SET, dess_nat_status_set), \ + SW_API_DEF(SW_API_NAT_STATUS_GET, dess_nat_status_get), \ + SW_API_DEF(SW_API_NAT_HASH_MODE_SET, dess_nat_hash_mode_set), \ + SW_API_DEF(SW_API_NAT_HASH_MODE_GET, dess_nat_hash_mode_get), \ + SW_API_DEF(SW_API_NAPT_STATUS_SET, dess_napt_status_set), \ + SW_API_DEF(SW_API_NAPT_STATUS_GET, dess_napt_status_get), \ + SW_API_DEF(SW_API_NAPT_MODE_SET, dess_napt_mode_set), \ + SW_API_DEF(SW_API_NAPT_MODE_GET, dess_napt_mode_get), \ + SW_API_DEF(SW_API_PRV_BASE_ADDR_SET, dess_nat_prv_base_addr_set), \ + SW_API_DEF(SW_API_PRV_BASE_ADDR_GET, dess_nat_prv_base_addr_get), \ + SW_API_DEF(SW_API_PUB_ADDR_ENTRY_ADD, dess_nat_pub_addr_add), \ + SW_API_DEF(SW_API_PUB_ADDR_ENTRY_DEL, dess_nat_pub_addr_del), \ + SW_API_DEF(SW_API_PUB_ADDR_ENTRY_NEXT, dess_nat_pub_addr_next), \ + SW_API_DEF(SW_API_NAT_UNK_SESSION_CMD_SET, dess_nat_unk_session_cmd_set), \ + SW_API_DEF(SW_API_NAT_UNK_SESSION_CMD_GET, dess_nat_unk_session_cmd_get), \ + SW_API_DEF(SW_API_PRV_BASE_MASK_SET, dess_nat_prv_base_mask_set), \ + SW_API_DEF(SW_API_PRV_BASE_MASK_GET, dess_nat_prv_base_mask_get), \ + SW_API_DEF(SW_API_NAT_GLOBAL_SET, dess_nat_global_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_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) +#else +#define NAT_API +#define NAT_API_PARAM +#endif + +#ifdef IN_TRUNK +#define TRUNK_API \ + SW_API_DEF(SW_API_TRUNK_GROUP_SET, dess_trunk_group_set), \ + SW_API_DEF(SW_API_TRUNK_GROUP_GET, dess_trunk_group_get), \ + SW_API_DEF(SW_API_TRUNK_HASH_SET, dess_trunk_hash_mode_set), \ + SW_API_DEF(SW_API_TRUNK_HASH_GET, dess_trunk_hash_mode_get), \ + SW_API_DEF(SW_API_TRUNK_MAN_SA_SET, dess_trunk_manipulate_sa_set), \ + SW_API_DEF(SW_API_TRUNK_MAN_SA_GET, dess_trunk_manipulate_sa_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) +#else +#define TRUNK_API +#define TRUNK_API_PARAM +#endif + +#ifdef IN_INTERFACECONTROL +#define INTERFACECTRL_API \ + SW_API_DEF(SW_API_MAC_MODE_SET, dess_interface_mac_mode_set), \ + SW_API_DEF(SW_API_MAC_MODE_GET, dess_interface_mac_mode_get), \ + SW_API_DEF(SW_API_PORT_3AZ_STATUS_SET, dess_port_3az_status_set), \ + SW_API_DEF(SW_API_PORT_3AZ_STATUS_GET, dess_port_3az_status_get), \ + SW_API_DEF(SW_API_PHY_MODE_SET, dess_interface_phy_mode_set), \ + SW_API_DEF(SW_API_PHY_MODE_GET, dess_interface_phy_mode_get), \ + SW_API_DEF(SW_API_FX100_CTRL_SET, dess_interface_fx100_ctrl_set), \ + SW_API_DEF(SW_API_FX100_CTRL_GET, dess_interface_fx100_ctrl_get), \ + SW_API_DEF(SW_API_FX100_STATUS_GET, dess_interface_fx100_status_get), \ + SW_API_DEF(SW_API_MAC06_EXCH_SET, dess_interface_mac06_exch_set), \ + SW_API_DEF(SW_API_MAC06_EXCH_GET, dess_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 + +#define REG_API \ + SW_API_DEF(SW_API_PHY_GET, dess_phy_get), \ + SW_API_DEF(SW_API_PHY_SET, dess_phy_set), \ + SW_API_DEF(SW_API_REG_GET, dess_reg_get), \ + SW_API_DEF(SW_API_PSGMII_REG_SET, dess_psgmii_reg_set), \ + SW_API_DEF(SW_API_PSGMII_REG_GET, dess_psgmii_reg_get), \ + SW_API_DEF(SW_API_REG_SET, dess_reg_set), \ + SW_API_DEF(SW_API_REG_FIELD_GET, dess_reg_field_get), \ + SW_API_DEF(SW_API_REG_FIELD_SET, dess_reg_field_set), \ + SW_API_DEF(SW_API_REG_DUMP, dess_regsiter_dump), \ + SW_API_DEF(SW_API_DBG_REG_DUMP, dess_debug_regsiter_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), + + +#define REG_API_PARAM \ + SW_API_DESC(SW_API_PHY_GET) \ + SW_API_DESC(SW_API_PHY_SET) \ + 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) + + + +#define SSDK_API \ + SW_API_DEF(SW_API_SWITCH_RESET, dess_reset), \ + SW_API_DEF(SW_API_SSDK_CFG, hsl_ssdk_cfg), \ + PORTCONTROL_API \ + 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 \ + TRUNK_API \ + INTERFACECTRL_API \ + REG_API \ + SW_API_DEF(SW_API_MAX, NULL), + + +#define SSDK_PARAM \ + 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"), \ + MIB_API_PARAM \ + LEAKY_API_PARAM \ + MISC_API_PARAM \ + IGMP_API_PARAM \ + MIRROR_API_PARAM \ + PORTCONTROL_API_PARAM \ + 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 \ + TRUNK_API_PARAM \ + INTERFACECTRL_API_PARAM \ + REG_API_PARAM \ + SW_PARAM_DEF(SW_API_MAX, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), + +#if (defined(USER_MODE) && defined(KERNEL_MODULE)) +#undef SSDK_API +#undef SSDK_PARAM + +#define SSDK_API \ + REG_API \ + SW_API_DEF(SW_API_MAX, NULL), + +#define SSDK_PARAM \ + REG_API_PARAM \ + SW_PARAM_DEF(SW_API_MAX, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _DESS_API_H_ */ +_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_cosmap.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_cosmap.h new file mode 100755 index 000000000..5ab114121 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_cosmap.h @@ -0,0 +1,141 @@ +/* + * 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 dess_cosmap DESS_COSMAP + * @{ + */ +#ifndef _DESS_COSMAP_H_ +#define _DESS_COSMAP_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_cosmap.h" + + sw_error_t dess_cosmap_init(a_uint32_t dev_id); + +#ifdef IN_COSMAP +#define DESS_COSMAP_INIT(rv, dev_id) \ + { \ + rv = dess_cosmap_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define DESS_COSMAP_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + dess_cosmap_dscp_to_pri_set(a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t pri); + + HSL_LOCAL sw_error_t + dess_cosmap_dscp_to_pri_get(a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t * pri); + + HSL_LOCAL sw_error_t + dess_cosmap_dscp_to_dp_set(a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t dp); + + HSL_LOCAL sw_error_t + dess_cosmap_dscp_to_dp_get(a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t * dp); + + HSL_LOCAL sw_error_t + dess_cosmap_up_to_pri_set(a_uint32_t dev_id, a_uint32_t up, + a_uint32_t pri); + + HSL_LOCAL sw_error_t + dess_cosmap_up_to_pri_get(a_uint32_t dev_id, a_uint32_t up, + a_uint32_t * pri); + + HSL_LOCAL sw_error_t + dess_cosmap_up_to_dp_set(a_uint32_t dev_id, a_uint32_t up, + a_uint32_t dp); + + HSL_LOCAL sw_error_t + dess_cosmap_up_to_dp_get(a_uint32_t dev_id, a_uint32_t up, + a_uint32_t * dp); + + HSL_LOCAL sw_error_t + dess_cosmap_dscp_to_ehpri_set(a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t pri); + + HSL_LOCAL sw_error_t + dess_cosmap_dscp_to_ehpri_get(a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t * pri); + + HSL_LOCAL sw_error_t + dess_cosmap_dscp_to_ehdp_set(a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t dp); + + HSL_LOCAL sw_error_t + dess_cosmap_dscp_to_ehdp_get(a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t * dp); + + HSL_LOCAL sw_error_t + dess_cosmap_up_to_ehpri_set(a_uint32_t dev_id, a_uint32_t up, + a_uint32_t pri); + + HSL_LOCAL sw_error_t + dess_cosmap_up_to_ehpri_get(a_uint32_t dev_id, a_uint32_t up, + a_uint32_t * pri); + + HSL_LOCAL sw_error_t + dess_cosmap_up_to_ehdp_set(a_uint32_t dev_id, a_uint32_t up, + a_uint32_t dp); + + HSL_LOCAL sw_error_t + dess_cosmap_up_to_ehdp_get(a_uint32_t dev_id, a_uint32_t up, + a_uint32_t * dp); + + HSL_LOCAL sw_error_t + dess_cosmap_pri_to_queue_set(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t queue); + + HSL_LOCAL sw_error_t + dess_cosmap_pri_to_queue_get(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t * queue); + + HSL_LOCAL sw_error_t + dess_cosmap_pri_to_ehqueue_set(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t queue); + + HSL_LOCAL sw_error_t + dess_cosmap_pri_to_ehqueue_get(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t * queue); + + HSL_LOCAL sw_error_t + dess_cosmap_egress_remark_set(a_uint32_t dev_id, a_uint32_t tbl_id, + fal_egress_remark_table_t * tbl); + + HSL_LOCAL sw_error_t + dess_cosmap_egress_remark_get(a_uint32_t dev_id, a_uint32_t tbl_id, + fal_egress_remark_table_t * tbl); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _DESS_COSMAP_H_ */ + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_fdb.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_fdb.h new file mode 100755 index 000000000..801c9c363 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_fdb.h @@ -0,0 +1,168 @@ +/* + * 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 dess_fdb DESS_FDB + * @{ + */ +#ifndef _DESS_FDB_H_ +#define _DESS_FDB_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_fdb.h" + + sw_error_t dess_fdb_init(a_uint32_t dev_id); + +#ifdef IN_FDB +#define DESS_FDB_INIT(rv, dev_id) \ + { \ + rv = dess_fdb_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define DESS_FDB_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + dess_fdb_add(a_uint32_t dev_id, const fal_fdb_entry_t * entry); + + HSL_LOCAL sw_error_t + dess_fdb_find(a_uint32_t dev_id, fal_fdb_entry_t * entry); + + HSL_LOCAL sw_error_t + dess_fdb_del_all(a_uint32_t dev_id, a_uint32_t flag); + + HSL_LOCAL sw_error_t + dess_fdb_del_by_port(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t flag); + + HSL_LOCAL sw_error_t + dess_fdb_del_by_mac(a_uint32_t dev_id, const fal_fdb_entry_t * entry); + + HSL_LOCAL sw_error_t + dess_fdb_extend_next(a_uint32_t dev_id, fal_fdb_op_t * op, + fal_fdb_entry_t * entry); + + HSL_LOCAL sw_error_t + dess_fdb_extend_first(a_uint32_t dev_id, fal_fdb_op_t * option, + fal_fdb_entry_t * entry); + + HSL_LOCAL sw_error_t + dess_fdb_transfer(a_uint32_t dev_id, fal_port_t old_port, + fal_port_t new_port, a_uint32_t fid, + fal_fdb_op_t * option); + + HSL_LOCAL sw_error_t + dess_fdb_port_learn_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + HSL_LOCAL sw_error_t + dess_fdb_port_learn_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + HSL_LOCAL sw_error_t + dess_fdb_age_ctrl_set(a_uint32_t dev_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + dess_fdb_age_ctrl_get(a_uint32_t dev_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + dess_fdb_vlan_ivl_svl_set(a_uint32_t dev_id, fal_fdb_smode smode); + + HSL_LOCAL sw_error_t + dess_fdb_vlan_ivl_svl_get(a_uint32_t dev_id, fal_fdb_smode * smode); + + HSL_LOCAL sw_error_t + dess_fdb_age_time_set(a_uint32_t dev_id, a_uint32_t * time); + + HSL_LOCAL sw_error_t + dess_fdb_age_time_get(a_uint32_t dev_id, a_uint32_t * time); + + HSL_LOCAL sw_error_t + dess_port_fdb_learn_limit_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable, a_uint32_t cnt); + + HSL_LOCAL sw_error_t + dess_port_fdb_learn_limit_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable, a_uint32_t * cnt); + + HSL_LOCAL sw_error_t + dess_port_fdb_learn_exceed_cmd_set(a_uint32_t dev_id, + fal_port_t port_id, + fal_fwd_cmd_t cmd); + + HSL_LOCAL sw_error_t + dess_port_fdb_learn_exceed_cmd_get(a_uint32_t dev_id, + fal_port_t port_id, + fal_fwd_cmd_t * cmd); + + HSL_LOCAL sw_error_t + dess_fdb_learn_limit_set(a_uint32_t dev_id, a_bool_t enable, + a_uint32_t cnt); + + HSL_LOCAL sw_error_t + dess_fdb_learn_limit_get(a_uint32_t dev_id, a_bool_t * enable, + a_uint32_t * cnt); + + HSL_LOCAL sw_error_t + dess_fdb_learn_exceed_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + HSL_LOCAL sw_error_t + dess_fdb_learn_exceed_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + HSL_LOCAL sw_error_t + dess_fdb_resv_add(a_uint32_t dev_id, fal_fdb_entry_t * entry); + + HSL_LOCAL sw_error_t + dess_fdb_resv_del(a_uint32_t dev_id, fal_fdb_entry_t * entry); + + HSL_LOCAL sw_error_t + dess_fdb_resv_find(a_uint32_t dev_id, fal_fdb_entry_t * entry); + + HSL_LOCAL sw_error_t + dess_fdb_resv_iterate(a_uint32_t dev_id, a_uint32_t * iterator, + fal_fdb_entry_t * entry); + + HSL_LOCAL sw_error_t + dess_fdb_port_learn_static_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + HSL_LOCAL sw_error_t + dess_fdb_port_learn_static_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + HSL_LOCAL sw_error_t + dess_fdb_port_add(a_uint32_t dev_id, a_uint32_t fid, fal_mac_addr_t * addr, fal_port_t port_id); + + HSL_LOCAL sw_error_t + dess_fdb_port_del(a_uint32_t dev_id, a_uint32_t fid, fal_mac_addr_t * addr, fal_port_t port_id); + + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _DESS_FDB_H_ */ + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_fdb_prv.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_fdb_prv.h new file mode 100755 index 000000000..e0f4f0a83 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_fdb_prv.h @@ -0,0 +1,49 @@ +/* + * 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 _DESS_FDB_PRV_H_ +#define _DESS_FDB_PRV_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +#define ARL_FLUSH_ALL 1 +#define ARL_LOAD_ENTRY 2 +#define ARL_PURGE_ENTRY 3 +#define ARL_FLUSH_ALL_UNLOCK 4 +#define ARL_FLUSH_PORT_UNICAST 5 +#define ARL_NEXT_ENTRY 6 +#define ARL_FIND_ENTRY 7 +#define ARL_TRANSFER_ENTRY 8 + +#define ARL_FIRST_ENTRY 1001 +#define ARL_FLUSH_PORT_NO_STATIC 1002 +#define ARL_FLUSH_PORT_AND_STATIC 1003 + +#define DESS_MAX_FID 4095 +#define DESS_MAX_LEARN_LIMIT_CNT 2048 +#define DESS_MAX_PORT_LEARN_LIMIT_CNT 1024 + + sw_error_t + inter_dess_fdb_flush(a_uint32_t dev_id, a_uint32_t flag); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _DESS_FDB_PRV_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_igmp.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_igmp.h new file mode 100755 index 000000000..bc808814e --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_igmp.h @@ -0,0 +1,165 @@ +/* + * 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 dess_igmp DESS_IGMP + * @{ + */ +#ifndef _DESS_IGMP_H_ +#define _DESS_IGMP_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_igmp.h" +#include "fal/fal_multi.h" + + sw_error_t + dess_igmp_init(a_uint32_t dev_id); + +#ifdef IN_IGMP +#define DESS_IGMP_INIT(rv, dev_id) \ + { \ + rv = dess_igmp_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define DESS_IGMP_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + dess_port_igmps_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_port_igmps_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable); + + + HSL_LOCAL sw_error_t + dess_igmp_mld_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + + HSL_LOCAL sw_error_t + dess_igmp_mld_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + + HSL_LOCAL sw_error_t + dess_port_igmp_mld_join_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_port_igmp_mld_join_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + dess_port_igmp_mld_leave_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_port_igmp_mld_leave_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + dess_igmp_mld_rp_set(a_uint32_t dev_id, fal_pbmp_t pts); + + + HSL_LOCAL sw_error_t + dess_igmp_mld_rp_get(a_uint32_t dev_id, fal_pbmp_t * pts); + + + HSL_LOCAL sw_error_t + dess_igmp_mld_entry_creat_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_igmp_mld_entry_creat_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + dess_igmp_mld_entry_static_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_igmp_mld_entry_static_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + dess_igmp_mld_entry_leaky_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_igmp_mld_entry_leaky_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + dess_igmp_mld_entry_v3_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_igmp_mld_entry_v3_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + dess_igmp_mld_entry_queue_set(a_uint32_t dev_id, a_bool_t enable, a_uint32_t queue); + + + HSL_LOCAL sw_error_t + dess_igmp_mld_entry_queue_get(a_uint32_t dev_id, a_bool_t * enable, a_uint32_t * queue); + + + HSL_LOCAL sw_error_t + dess_port_igmp_mld_learn_limit_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable, a_uint32_t cnt); + + + HSL_LOCAL sw_error_t + dess_port_igmp_mld_learn_limit_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable, a_uint32_t * cnt); + + + HSL_LOCAL sw_error_t + dess_port_igmp_mld_learn_exceed_cmd_set(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t cmd); + + + HSL_LOCAL sw_error_t + dess_port_igmp_mld_learn_exceed_cmd_get(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t * cmd); + + HSL_LOCAL sw_error_t + dess_igmp_sg_entry_set(a_uint32_t dev_id, fal_igmp_sg_entry_t * entry); + + HSL_LOCAL sw_error_t + dess_igmp_sg_entry_clear(a_uint32_t dev_id, fal_igmp_sg_entry_t * entry); + + HSL_LOCAL sw_error_t + dess_igmp_sg_entry_show(a_uint32_t dev_id); + + HSL_LOCAL sw_error_t + dess_igmp_sg_entry_query(a_uint32_t dev_id, fal_igmp_sg_info_t * info); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _DESS_IGMP_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_init.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_init.h new file mode 100755 index 000000000..77671512a --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_init.h @@ -0,0 +1,44 @@ +/* + * 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 dess_init DESS_INIT + * @{ + */ +#ifndef _DESS_INIT_H_ +#define _DESS_INIT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "init/ssdk_init.h" + + + sw_error_t + dess_init(a_uint32_t dev_id, ssdk_init_cfg *cfg); + + + sw_error_t + dess_cleanup(a_uint32_t dev_id); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _DESS_INIT_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_interface_ctrl.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_interface_ctrl.h new file mode 100755 index 000000000..08f313434 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_interface_ctrl.h @@ -0,0 +1,58 @@ +/* + * 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 _DESS_INTERFACE_CTRL_H_ +#define _DESS_INTERFACE_CTRL_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_interface_ctrl.h" + + sw_error_t dess_interface_ctrl_init(a_uint32_t dev_id); + +#ifdef IN_INTERFACECONTROL +#define DESS_INTERFACE_CTRL_INIT(rv, dev_id) \ + { \ + rv = dess_interface_ctrl_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define DESS_INTERFACE_CTRL_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + dess_port_3az_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + dess_port_3az_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + dess_interface_mac_mode_get(a_uint32_t dev_id, fal_port_t port_id, fal_mac_config_t * config); + + HSL_LOCAL sw_error_t + dess_interface_mac_mode_set(a_uint32_t dev_id, fal_port_t port_id, fal_mac_config_t * config); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _DESS_INTERFACE_CTRL_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_ip.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_ip.h new file mode 100755 index 000000000..339bd83c6 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_ip.h @@ -0,0 +1,201 @@ +/* + * 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. + */ + + +#ifndef _DESS_IP_H_ +#define _DESS_IP_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_ip.h" + + sw_error_t dess_ip_init(a_uint32_t dev_id); + + sw_error_t dess_ip_reset(a_uint32_t dev_id); + +#ifdef IN_IP +#define DESS_IP_INIT(rv, dev_id) \ + { \ + rv = dess_ip_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } + +#define DESS_IP_RESET(rv, dev_id) \ + { \ + rv = dess_ip_reset(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define DESS_IP_INIT(rv, dev_id) +#define DESS_IP_RESET(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + dess_ip_host_add(a_uint32_t dev_id, fal_host_entry_t * host_entry); + + HSL_LOCAL sw_error_t + dess_ip_intf_entry_add(a_uint32_t dev_id, fal_intf_mac_entry_t * entry); + + HSL_LOCAL sw_error_t + dess_ip_host_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_host_entry_t * host_entry); + + HSL_LOCAL sw_error_t + dess_ip_host_get(a_uint32_t dev_id, a_uint32_t get_mode, + fal_host_entry_t * host_entry); + + HSL_LOCAL sw_error_t + dess_ip_host_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_host_entry_t * host_entry); + + HSL_LOCAL sw_error_t + dess_ip_host_counter_bind(a_uint32_t dev_id, a_uint32_t entry_id, + a_uint32_t cnt_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + dess_ip_host_pppoe_bind(a_uint32_t dev_id, a_uint32_t entry_id, + a_uint32_t pppoe_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + dess_ip_pt_arp_learn_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t flags); + + HSL_LOCAL sw_error_t + dess_ip_pt_arp_learn_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * flags); + + HSL_LOCAL sw_error_t + dess_ip_arp_learn_set(a_uint32_t dev_id, fal_arp_learn_mode_t mode); + + HSL_LOCAL sw_error_t + dess_ip_arp_learn_get(a_uint32_t dev_id, fal_arp_learn_mode_t * mode); + + HSL_LOCAL sw_error_t + dess_ip_source_guard_set(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t mode); + + HSL_LOCAL sw_error_t + dess_ip_source_guard_get(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t * mode); + + HSL_LOCAL sw_error_t + dess_ip_unk_source_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + HSL_LOCAL sw_error_t + dess_ip_unk_source_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + HSL_LOCAL sw_error_t + dess_ip_arp_guard_set(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t mode); + + HSL_LOCAL sw_error_t + dess_ip_arp_guard_get(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t * mode); + + HSL_LOCAL sw_error_t + dess_arp_unk_source_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + HSL_LOCAL sw_error_t + dess_arp_unk_source_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + HSL_LOCAL sw_error_t + dess_ip_route_status_set(a_uint32_t dev_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + dess_ip_route_status_get(a_uint32_t dev_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + dess_ip_intf_entry_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_intf_mac_entry_t * entry); + + HSL_LOCAL sw_error_t + dess_ip_intf_entry_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_intf_mac_entry_t * entry); + + HSL_LOCAL sw_error_t + dess_ip_age_time_set(a_uint32_t dev_id, a_uint32_t * time); + + HSL_LOCAL sw_error_t + dess_ip_age_time_get(a_uint32_t dev_id, a_uint32_t * time); + + HSL_LOCAL sw_error_t + dess_ip_wcmp_entry_set(a_uint32_t dev_id, a_uint32_t wcmp_id, fal_ip_wcmp_t * wcmp); + + HSL_LOCAL sw_error_t + dess_ip_wcmp_entry_get(a_uint32_t dev_id, a_uint32_t wcmp_id, fal_ip_wcmp_t * wcmp); + + HSL_LOCAL sw_error_t + dess_ip_rfs_ip4_set(a_uint32_t dev_id, fal_ip4_rfs_t * rfs); + + HSL_LOCAL sw_error_t + dess_ip_rfs_ip6_set(a_uint32_t dev_id, fal_ip6_rfs_t * rfs); + + HSL_LOCAL sw_error_t + dess_ip_rfs_ip4_del(a_uint32_t dev_id, fal_ip4_rfs_t * rfs); + + HSL_LOCAL sw_error_t + dess_ip_rfs_ip6_del(a_uint32_t dev_id, fal_ip6_rfs_t * rfs); + + HSL_LOCAL sw_error_t + dess_ip_wcmp_hash_mode_set(a_uint32_t dev_id, a_uint32_t hash_mode); + + HSL_LOCAL sw_error_t + dess_ip_wcmp_hash_mode_get(a_uint32_t dev_id, a_uint32_t * hash_mode); + + HSL_LOCAL sw_error_t + dess_ip_vrf_base_addr_set(a_uint32_t dev_id, a_uint32_t vrf_id, fal_ip4_addr_t addr); + + HSL_LOCAL sw_error_t + dess_ip_vrf_base_addr_get(a_uint32_t dev_id, a_uint32_t vrf_id, fal_ip4_addr_t * addr); + + HSL_LOCAL sw_error_t + dess_ip_vrf_base_mask_set(a_uint32_t dev_id, a_uint32_t vrf_id, fal_ip4_addr_t addr); + + HSL_LOCAL sw_error_t + dess_ip_vrf_base_mask_get(a_uint32_t dev_id, a_uint32_t vrf_id, fal_ip4_addr_t * addr); + + HSL_LOCAL sw_error_t + dess_ip_default_route_set(a_uint32_t dev_id, a_uint32_t droute_id, fal_default_route_t * entry); + + HSL_LOCAL sw_error_t + dess_ip_default_route_get(a_uint32_t dev_id, a_uint32_t droute_id, fal_default_route_t * entry); + + HSL_LOCAL sw_error_t + dess_ip_host_route_set(a_uint32_t dev_id, a_uint32_t hroute_id, fal_host_route_t * entry); + + HSL_LOCAL sw_error_t + dess_ip_host_route_get(a_uint32_t dev_id, a_uint32_t hroute_id, fal_host_route_t * entry); + + HSL_LOCAL sw_error_t + dess_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); + + HSL_LOCAL sw_error_t + dess_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); + + HSL_LOCAL sw_error_t + dess_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); + + HSL_LOCAL sw_error_t + dess_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); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _DESS_IP_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_leaky.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_leaky.h new file mode 100755 index 000000000..a4d3fdaed --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_leaky.h @@ -0,0 +1,94 @@ +/* + * 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 _DESS_LEAKY_H_ +#define _DESS_LEAKY_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_leaky.h" + + sw_error_t dess_leaky_init(a_uint32_t dev_id); + +#ifdef IN_LEAKY +#define DESS_LEAKY_INIT(rv, dev_id) \ + { \ + rv = dess_leaky_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define DESS_LEAKY_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + dess_uc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode); + + + HSL_LOCAL sw_error_t + dess_uc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t * ctrl_mode); + + + HSL_LOCAL sw_error_t + dess_mc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode); + + + HSL_LOCAL sw_error_t + dess_mc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t * ctrl_mode); + + + HSL_LOCAL sw_error_t + dess_port_arp_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_port_arp_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + dess_port_uc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_port_uc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + dess_port_mc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_port_mc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _DESS_LEAKY_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_led.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_led.h new file mode 100755 index 000000000..77da266a8 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_led.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 _DESS_LED_H_ +#define _DESS_LED_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_led.h" + + sw_error_t + dess_led_init(a_uint32_t dev_id); + +#ifdef IN_LED +#define DESS_LED_INIT(rv, dev_id) \ + { \ + rv = dess_led_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define DESS_LED_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + dess_led_ctrl_pattern_set(a_uint32_t dev_id, led_pattern_group_t group, + led_pattern_id_t id, led_ctrl_pattern_t * pattern); + + + HSL_LOCAL sw_error_t + dess_led_ctrl_pattern_get(a_uint32_t dev_id, led_pattern_group_t group, + led_pattern_id_t id, led_ctrl_pattern_t * pattern); + + HSL_LOCAL sw_error_t + dess_led_source_pattern_set(a_uint32_t dev_id, a_uint32_t source_id, led_ctrl_pattern_t * pattern); + + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _DESS_LED_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_mib.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_mib.h new file mode 100755 index 000000000..12dfb299f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_mib.h @@ -0,0 +1,69 @@ +/* + * 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 _DESS_MIB_H_ +#define _DESS_MIB_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_mib.h" + + sw_error_t + dess_mib_init(a_uint32_t dev_id); + +#ifdef IN_MIB +#define DESS_MIB_INIT(rv, dev_id) \ + { \ + rv = dess_mib_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define DESS_MIB_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + dess_get_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info ); + + + HSL_LOCAL sw_error_t + dess_mib_status_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_mib_status_get(a_uint32_t dev_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + dess_mib_port_flush_counters(a_uint32_t dev_id, fal_port_t port_id); + + HSL_LOCAL sw_error_t + dess_mib_cpukeep_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_mib_cpukeep_get(a_uint32_t dev_id, a_bool_t * enable); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _DESS_MIB_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_mirror.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_mirror.h new file mode 100755 index 000000000..88c1e4fdf --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_mirror.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 _DESS_MIRROR_H_ +#define _DESS_MIRROR_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_mirror.h" +#define MIRROR_ANALYZER_NONE 0xf + + sw_error_t dess_mirr_init(a_uint32_t dev_id); + +#ifdef IN_MIRROR +#define DESS_MIRR_INIT(rv, dev_id) \ + { \ + rv = dess_mirr_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define DESS_MIRR_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + dess_mirr_analysis_port_set(a_uint32_t dev_id, fal_port_t port_id); + + + HSL_LOCAL sw_error_t + dess_mirr_analysis_port_get(a_uint32_t dev_id, fal_port_t * port_id); + + + HSL_LOCAL sw_error_t + dess_mirr_port_in_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_mirr_port_in_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + dess_mirr_port_eg_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_mirr_port_eg_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _DESS_MIRROR_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_misc.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_misc.h new file mode 100755 index 000000000..961e812b2 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_misc.h @@ -0,0 +1,258 @@ +/* + * 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 _DESS_MISC_H_ +#define _DESS_MISC_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_misc.h" + + sw_error_t dess_misc_init(a_uint32_t dev_id); + +#ifdef IN_MISC +#define DESS_MISC_INIT(rv, dev_id) \ + { \ + rv = dess_misc_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define DESS_MISC_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + dess_frame_max_size_set(a_uint32_t dev_id, a_uint32_t size); + + + HSL_LOCAL sw_error_t + dess_frame_max_size_get(a_uint32_t dev_id, a_uint32_t * size); + + + HSL_LOCAL sw_error_t + dess_port_unk_uc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_port_unk_uc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + dess_port_unk_mc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_port_unk_mc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + dess_port_bc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_port_bc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + dess_cpu_port_status_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_cpu_port_status_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + dess_pppoe_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + + HSL_LOCAL sw_error_t + dess_pppoe_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + + HSL_LOCAL sw_error_t + dess_pppoe_status_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_pppoe_status_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + dess_port_dhcp_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_port_dhcp_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + dess_arp_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + + HSL_LOCAL sw_error_t + dess_arp_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + + HSL_LOCAL sw_error_t + dess_eapol_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + + HSL_LOCAL sw_error_t + dess_eapol_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + + HSL_LOCAL sw_error_t + dess_pppoe_session_table_add(a_uint32_t dev_id, fal_pppoe_session_t * session_tbl); + + + HSL_LOCAL sw_error_t + dess_pppoe_session_table_del(a_uint32_t dev_id, fal_pppoe_session_t * session_tbl); + + + HSL_LOCAL sw_error_t + dess_pppoe_session_table_get(a_uint32_t dev_id, fal_pppoe_session_t * session_tbl); + + + HSL_LOCAL sw_error_t + dess_pppoe_session_id_set(a_uint32_t dev_id, a_uint32_t index, + a_uint32_t id); + + + HSL_LOCAL sw_error_t + dess_pppoe_session_id_get(a_uint32_t dev_id, a_uint32_t index, + a_uint32_t * id); + + + HSL_LOCAL sw_error_t + dess_eapol_status_set(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + dess_eapol_status_get(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + dess_ripv1_status_set(a_uint32_t dev_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + dess_ripv1_status_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + dess_port_arp_req_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_port_arp_req_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable); + + + HSL_LOCAL sw_error_t + dess_port_arp_ack_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_port_arp_ack_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable); + + + HSL_LOCAL sw_error_t + dess_intr_mask_set(a_uint32_t dev_id, a_uint32_t intr_mask); + + + HSL_LOCAL sw_error_t + dess_intr_mask_get(a_uint32_t dev_id, a_uint32_t * intr_mask); + + + HSL_LOCAL sw_error_t + dess_intr_status_get(a_uint32_t dev_id, a_uint32_t * intr_status); + + + HSL_LOCAL sw_error_t + dess_intr_status_clear(a_uint32_t dev_id, a_uint32_t intr_status); + + + HSL_LOCAL sw_error_t + dess_intr_port_link_mask_set(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t intr_mask_flag); + + + HSL_LOCAL sw_error_t + dess_intr_port_link_mask_get(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t * intr_mask_flag); + + + HSL_LOCAL sw_error_t + dess_intr_port_link_status_get(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t * intr_mask_flag); + + HSL_LOCAL sw_error_t + dess_intr_mask_mac_linkchg_set(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_intr_mask_mac_linkchg_get(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + dess_intr_status_mac_linkchg_get(a_uint32_t dev_id, fal_pbmp_t *port_bitmap); + + HSL_LOCAL sw_error_t + dess_cpu_vid_en_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_cpu_vid_en_get(a_uint32_t dev_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + dess_rtd_pppoe_en_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_rtd_pppoe_en_get(a_uint32_t dev_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + dess_intr_status_mac_linkchg_clear(a_uint32_t dev_id); + + HSL_LOCAL sw_error_t + dess_global_macaddr_set(a_uint32_t dev_id, fal_mac_addr_t * addr); + + HSL_LOCAL sw_error_t + dess_global_macaddr_get(a_uint32_t dev_id, fal_mac_addr_t * addr); + + HSL_LOCAL sw_error_t + dess_lldp_status_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_lldp_status_get(a_uint32_t dev_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + dess_frame_crc_reserve_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_frame_crc_reserve_get(a_uint32_t dev_id, a_bool_t * enable); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_nat.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_nat.h new file mode 100755 index 000000000..57156fca6 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_nat.h @@ -0,0 +1,147 @@ +/* + * 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 _DESS_NAT_H_ +#define _DESS_NAT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_nat.h" + + sw_error_t dess_nat_init(a_uint32_t dev_id); + + sw_error_t dess_nat_reset(a_uint32_t dev_id); + +#ifdef IN_NAT +#define DESS_NAT_INIT(rv, dev_id) \ + { \ + rv = dess_nat_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } + +#define DESS_NAT_RESET(rv, dev_id) \ + { \ + rv = dess_nat_reset(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define DESS_NAT_INIT(rv, dev_id) +#define DESS_NAT_RESET(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + dess_napt_add(a_uint32_t dev_id, fal_napt_entry_t * napt_entry); + + HSL_LOCAL sw_error_t + dess_nat_pub_addr_add(a_uint32_t dev_id, fal_nat_pub_addr_t * entry); + + HSL_LOCAL sw_error_t + dess_napt_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_napt_entry_t * napt_entry); + + HSL_LOCAL sw_error_t + dess_nat_prv_base_addr_set(a_uint32_t dev_id, fal_ip4_addr_t addr); + + HSL_LOCAL sw_error_t + dess_napt_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_napt_entry_t * napt_entry); + + HSL_LOCAL sw_error_t + dess_nat_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_nat_entry_t * nat_entry); + + HSL_LOCAL sw_error_t + dess_nat_pub_addr_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_nat_pub_addr_t * entry); + + HSL_LOCAL sw_error_t + dess_nat_add(a_uint32_t dev_id, fal_nat_entry_t * nat_entry); + + HSL_LOCAL sw_error_t + dess_nat_get(a_uint32_t dev_id, a_uint32_t get_mode, + fal_nat_entry_t * nat_entry); + + HSL_LOCAL sw_error_t + dess_nat_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_nat_entry_t * nat_entry); + + HSL_LOCAL sw_error_t + dess_nat_counter_bind(a_uint32_t dev_id, a_uint32_t entry_id, + a_uint32_t cnt_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + dess_napt_get(a_uint32_t dev_id, a_uint32_t get_mode, + fal_napt_entry_t * napt_entry); + + HSL_LOCAL sw_error_t + dess_napt_counter_bind(a_uint32_t dev_id, a_uint32_t entry_id, + a_uint32_t cnt_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + dess_nat_status_set(a_uint32_t dev_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + dess_nat_status_get(a_uint32_t dev_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + dess_nat_hash_mode_set(a_uint32_t dev_id, a_uint32_t mode); + + HSL_LOCAL sw_error_t + dess_nat_hash_mode_get(a_uint32_t dev_id, a_uint32_t * mode); + + HSL_LOCAL sw_error_t + dess_napt_status_set(a_uint32_t dev_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + dess_napt_status_get(a_uint32_t dev_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + dess_napt_mode_set(a_uint32_t dev_id, fal_napt_mode_t mode); + + HSL_LOCAL sw_error_t + dess_napt_mode_get(a_uint32_t dev_id, fal_napt_mode_t * mode); + + HSL_LOCAL sw_error_t + dess_nat_prv_base_addr_get(a_uint32_t dev_id, fal_ip4_addr_t * addr); + + HSL_LOCAL sw_error_t + dess_nat_prv_base_mask_set(a_uint32_t dev_id, fal_ip4_addr_t addr); + + HSL_LOCAL sw_error_t + dess_nat_prv_base_mask_get(a_uint32_t dev_id, fal_ip4_addr_t * addr); + + HSL_LOCAL sw_error_t + dess_nat_pub_addr_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_nat_pub_addr_t * entry); + + HSL_LOCAL sw_error_t + dess_nat_unk_session_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + HSL_LOCAL sw_error_t + dess_nat_unk_session_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + HSL_LOCAL sw_error_t + dess_nat_global_set(a_uint32_t dev_id, a_bool_t enable); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _DESS_NAT_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_nat_helper.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_nat_helper.h new file mode 100755 index 000000000..13c0fb18e --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_nat_helper.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 _DESS_NAT_HELPER_H_ +#define _DESS_NAT_HELPER_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_nat.h" + + sw_error_t nat_helper_init(a_uint32_t dev_id, a_uint32_t portbmp); + + sw_error_t nat_helper_cleanup(a_uint32_t dev_id); + +#ifdef IN_NAT_HELPER +#define DESS_NAT_HELPER_INIT(rv, dev_id, portbmp) \ + { \ + rv = nat_helper_init(dev_id, portbmp); \ + SW_RTN_ON_ERROR(rv); \ + } + +#define DESS_NAT_HELPER_CLEANUP(rv, dev_id) \ + { \ + rv = nat_helper_cleanup(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define DESS_NAT_HELPER_INIT(rv, dev_id, portbmp) +#define DESS_NAT_HELPER_CLEANUP(rv, dev_id) +#endif + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _DESS_NAT_HELPER_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_port_ctrl.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_port_ctrl.h new file mode 100755 index 000000000..b08b0b59d --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_port_ctrl.h @@ -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. + */ + + +#ifndef _DESS_PORT_CTRL_H_ +#define _DESS_PORT_CTRL_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include "fal/fal_port_ctrl.h" + + sw_error_t dess_port_ctrl_init (a_uint32_t dev_id); + +#ifdef IN_PORTCONTROL +#define DESS_PORT_CTRL_INIT(rv, dev_id) \ + { \ + rv = dess_port_ctrl_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define DESS_PORT_CTRL_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + dess_port_duplex_set (a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t duplex); + + + HSL_LOCAL sw_error_t + dess_port_duplex_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t * pduplex); + + + HSL_LOCAL sw_error_t + dess_port_speed_set (a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t speed); + + + HSL_LOCAL sw_error_t + dess_port_speed_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t * pspeed); + + + HSL_LOCAL sw_error_t + dess_port_autoneg_status_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status); + + + HSL_LOCAL sw_error_t + dess_port_autoneg_enable (a_uint32_t dev_id, fal_port_t port_id); + + + HSL_LOCAL sw_error_t + dess_port_autoneg_restart (a_uint32_t dev_id, fal_port_t port_id); + + + HSL_LOCAL sw_error_t + dess_port_autoneg_adv_set (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t autoadv); + + + HSL_LOCAL sw_error_t + dess_port_autoneg_adv_get (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * autoadv); + + + HSL_LOCAL sw_error_t + dess_port_flowctrl_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_port_flowctrl_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + dess_port_flowctrl_forcemode_set (a_uint32_t dev_id, + fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_port_flowctrl_forcemode_get (a_uint32_t dev_id, + fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + dess_port_powersave_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_port_powersave_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + dess_port_hibernate_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_port_hibernate_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + dess_port_cdt (a_uint32_t dev_id, fal_port_t port_id, a_uint32_t mdi_pair, + fal_cable_status_t * cable_status, a_uint32_t * cable_len); + + + HSL_LOCAL sw_error_t + dess_port_rxhdr_mode_set (a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t mode); + + + HSL_LOCAL sw_error_t + dess_port_rxhdr_mode_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t * mode); + + + HSL_LOCAL sw_error_t + dess_port_txhdr_mode_set (a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t mode); + + + HSL_LOCAL sw_error_t + dess_port_txhdr_mode_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t * mode); + + + HSL_LOCAL sw_error_t + dess_header_type_set (a_uint32_t dev_id, a_bool_t enable, + a_uint32_t type); + + + HSL_LOCAL sw_error_t + dess_header_type_get (a_uint32_t dev_id, a_bool_t * enable, + a_uint32_t * type); + + + HSL_LOCAL sw_error_t + dess_port_txmac_status_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_port_txmac_status_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + dess_port_rxmac_status_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_port_rxmac_status_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + dess_port_txfc_status_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_port_txfc_status_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + dess_port_rxfc_status_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_port_rxfc_status_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + dess_port_bp_status_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_port_bp_status_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + dess_port_link_forcemode_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_port_link_forcemode_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + dess_port_link_status_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status); + + HSL_LOCAL sw_error_t + dess_port_mac_loopback_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_port_mac_loopback_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + HSL_LOCAL sw_error_t + dess_port_congestion_drop_set (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t queue_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + dess_port_congestion_drop_get (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t queue_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + dess_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); + + HSL_LOCAL sw_error_t + dess_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); + + HSL_LOCAL sw_error_t + dess_port_8023az_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + HSL_LOCAL sw_error_t + dess_port_8023az_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + HSL_LOCAL sw_error_t + dess_port_mdix_set (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_mdix_mode_t mode); + + HSL_LOCAL sw_error_t + dess_port_mdix_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_mdix_mode_t * mode); + + HSL_LOCAL sw_error_t + dess_port_mdix_status_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_mdix_status_t * mode); + + HSL_LOCAL sw_error_t + dess_port_combo_prefer_medium_set (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_medium_t phy_medium); + + HSL_LOCAL sw_error_t + dess_port_combo_prefer_medium_get (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_medium_t * phy_medium); + + HSL_LOCAL sw_error_t + dess_port_combo_medium_status_get (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_medium_t * phy_medium); + + HSL_LOCAL sw_error_t + dess_port_combo_fiber_mode_set (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_fiber_mode_t fiber_mode); + + HSL_LOCAL sw_error_t + dess_port_combo_fiber_mode_get (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_fiber_mode_t * fiber_mode); + + HSL_LOCAL sw_error_t + dess_port_local_loopback_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + HSL_LOCAL sw_error_t + dess_port_local_loopback_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + HSL_LOCAL sw_error_t + dess_port_remote_loopback_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + HSL_LOCAL sw_error_t + dess_port_remote_loopback_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + HSL_LOCAL sw_error_t + dess_port_magic_frame_mac_set (a_uint32_t dev_id, fal_port_t port_id, + fal_mac_addr_t * mac); + + HSL_LOCAL sw_error_t + dess_port_magic_frame_mac_get (a_uint32_t dev_id, fal_port_t port_id, + fal_mac_addr_t * mac); + + HSL_LOCAL sw_error_t + dess_port_phy_id_get (a_uint32_t dev_id, fal_port_t port_id, + a_uint16_t * org_id, a_uint16_t * rev_id); + + HSL_LOCAL sw_error_t + dess_port_wol_status_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + HSL_LOCAL sw_error_t + dess_port_wol_status_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + HSL_LOCAL sw_error_t + dess_port_reset (a_uint32_t dev_id, fal_port_t port_id); + + HSL_LOCAL sw_error_t + dess_port_power_off (a_uint32_t dev_id, fal_port_t port_id); + + HSL_LOCAL sw_error_t + dess_port_power_on (a_uint32_t dev_id, fal_port_t port_id); + + HSL_LOCAL sw_error_t + dess_port_interface_mode_set (a_uint32_t dev_id, fal_port_t port_id, + fal_port_interface_mode_t mode); + + HSL_LOCAL sw_error_t + dess_port_interface_mode_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_interface_mode_t * mode); + + HSL_LOCAL sw_error_t + dess_port_interface_mode_status_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_interface_mode_t * mode); + HSL_LOCAL sw_error_t + dess_port_counter_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + HSL_LOCAL sw_error_t + dess_port_counter_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + HSL_LOCAL sw_error_t + dess_port_counter_show (a_uint32_t dev_id, fal_port_t port_id, + fal_port_counter_info_t * counter_info); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _DESS_PORT_CTRL_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_portvlan.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_portvlan.h new file mode 100755 index 000000000..e68e12724 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_portvlan.h @@ -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. + */ + + +#ifndef _DESS_PORTVLAN_H_ +#define _DESS_PORTVLAN_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_portvlan.h" + + sw_error_t dess_portvlan_init(a_uint32_t dev_id); + +#ifdef IN_PORTVLAN +#define DESS_PORTVLAN_INIT(rv, dev_id) \ + { \ + rv = dess_portvlan_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define DESS_PORTVLAN_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + dess_port_1qmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t port_1qmode); + + + HSL_LOCAL sw_error_t + dess_port_1qmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t * pport_1qmode); + + + HSL_LOCAL sw_error_t + dess_port_egvlanmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t port_egvlanmode); + + + HSL_LOCAL sw_error_t + dess_port_egvlanmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t * pport_egvlanmode); + + + HSL_LOCAL sw_error_t + dess_portvlan_member_add(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id); + + + HSL_LOCAL sw_error_t + dess_portvlan_member_del(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id); + + + HSL_LOCAL sw_error_t + dess_portvlan_member_update(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t mem_port_map); + + + HSL_LOCAL sw_error_t + dess_portvlan_member_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t * mem_port_map); + + + HSL_LOCAL sw_error_t + dess_port_force_default_vid_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_port_force_default_vid_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + dess_port_force_portvlan_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_port_force_portvlan_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + dess_nestvlan_tpid_set(a_uint32_t dev_id, a_uint32_t tpid); + + + HSL_LOCAL sw_error_t + dess_nestvlan_tpid_get(a_uint32_t dev_id, a_uint32_t * tpid); + + + HSL_LOCAL sw_error_t + dess_port_invlan_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_invlan_mode_t mode); + + + HSL_LOCAL sw_error_t + dess_port_invlan_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_invlan_mode_t * mode); + + + HSL_LOCAL sw_error_t + dess_port_tls_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_port_tls_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + dess_port_pri_propagation_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_port_pri_propagation_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + dess_port_default_svid_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vid); + + + HSL_LOCAL sw_error_t + dess_port_default_svid_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vid); + + HSL_LOCAL sw_error_t + dess_port_default_cvid_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vid); + + + HSL_LOCAL sw_error_t + dess_port_default_cvid_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vid); + + + HSL_LOCAL sw_error_t + dess_port_vlan_propagation_set(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_propagation_mode_t mode); + + + HSL_LOCAL sw_error_t + dess_port_vlan_propagation_get(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_propagation_mode_t * mode); + + + HSL_LOCAL sw_error_t + dess_port_vlan_trans_add(a_uint32_t dev_id, fal_port_t port_id, fal_vlan_trans_entry_t *entry); + + + HSL_LOCAL sw_error_t + dess_port_vlan_trans_del(a_uint32_t dev_id, fal_port_t port_id, fal_vlan_trans_entry_t *entry); + + + HSL_LOCAL sw_error_t + dess_port_vlan_trans_get(a_uint32_t dev_id, fal_port_t port_id, fal_vlan_trans_entry_t *entry); + + + HSL_LOCAL sw_error_t + dess_qinq_mode_set(a_uint32_t dev_id, fal_qinq_mode_t mode); + + + HSL_LOCAL sw_error_t + dess_qinq_mode_get(a_uint32_t dev_id, fal_qinq_mode_t * mode); + + + HSL_LOCAL sw_error_t + dess_port_qinq_role_set(a_uint32_t dev_id, fal_port_t port_id, fal_qinq_port_role_t role); + + + HSL_LOCAL sw_error_t + dess_port_qinq_role_get(a_uint32_t dev_id, fal_port_t port_id, fal_qinq_port_role_t * role); + + + HSL_LOCAL sw_error_t + dess_port_vlan_trans_iterate(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * iterator, fal_vlan_trans_entry_t * entry); + + + HSL_LOCAL sw_error_t + dess_port_mac_vlan_xlt_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_port_mac_vlan_xlt_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + HSL_LOCAL sw_error_t + dess_netisolate_set(a_uint32_t dev_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + dess_netisolate_get(a_uint32_t dev_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + dess_eg_trans_filter_bypass_en_set(a_uint32_t dev_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + dess_eg_trans_filter_bypass_en_get(a_uint32_t dev_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + dess_port_route_defv_set(a_uint32_t dev_id, fal_port_t port_id); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _DESS_PORTVLAN_H */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_psgmii.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_psgmii.h new file mode 100755 index 000000000..7c9b580c3 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_psgmii.h @@ -0,0 +1,310 @@ +/* + * Copyright (c) 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. + */ + + + +#ifndef _DESS_PSGMII_H_ +#define _DESS_PSGMII_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*PSGMII Registers*/ +#define PSGMIIPHY_MODECFG_1 0xcc +#define PSGMIIPHY_PHY_INTERFACE 0x10C +#define PSGMIIPHY_EEE_CH0_1 0x168 +#define PSGMIIPHY_EEE_CH0_2 0x16C +#define PSGMIIPHY_EEE_CH0_3 0x170 +#define PSGMIIPHY_EEE_CH0_4 0x174 +#define PSGMIIPHY_EEE_CH0_5 0x178 +#define PSGMIIPHY_EEE_CH0_6 0x17C +#define PSGMIIPHY_EEE_CH0_7 0x180 +#define PSGMIIPHY_EEE_CH1_1 0x184 +#define PSGMIIPHY_EEE_CH1_2 0x188 +#define PSGMIIPHY_EEE_CH1_3 0x18C +#define PSGMIIPHY_EEE_CH2_1 0x190 +#define PSGMIIPHY_EEE_CH2_2 0x194 +#define PSGMIIPHY_EEE_CH2_3 0x198 +#define PSGMIIPHY_EEE_CH3_1 0x19C +#define PSGMIIPHY_EEE_CH3_2 0x1A0 +#define PSGMIIPHY_EEE_CH3_3 0x1A4 +#define PSGMIIPHY_EEE_CH4_1 0x1A8 +#define PSGMIIPHY_EEE_CH4_2 0x1AC +#define PSGMIIPHY_EEE_CH4_3 0x1B0 + +#define PSGMIIPHY_MODE_CONTROL 0x1b4 +#define PSGMIIPHY_FIFO 0x1b8 + +#define PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_1 0x1BC +#define PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4 0x1C8 +#define PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_5 0x1CC +#define PSGMIIPHY_CHANNEL_1_INPUT_OUTPUT_4 0x1e0 +#define PSGMIIPHY_CHANNEL_1_INPUT_OUTPUT_5 0x1e4 +#define PSGMIIPHY_CHANNEL_2_INPUT_OUTPUT_4 0x1f8 +#define PSGMIIPHY_CHANNEL_2_INPUT_OUTPUT_5 0x1fC +#define PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_4 0x210 +#define PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_5 0x214 +#define PSGMIIPHY_CHANNEL_4_INPUT_OUTPUT_4 0x228 +#define PSGMIIPHY_CHANNEL_4_INPUT_OUTPUT_5 0x22C + +#define PSGMIIPHY_CHANNEL0TXSTATE 0x248 +#define PSGMIIPHY_CHANNEL0RXSTATES 0x24c +#define PSGMIIPHY_CHANNEL1TXSTATE 0x250 +#define PSGMIIPHY_CHANNEL1RXSTATES 0x254 +#define PSGMIIPHY_CHANNEL2TXSTATE 0x258 +#define PSGMIIPHY_CHANNEL2RXSTATES 0x25c +#define PSGMIIPHY_CHANNEL3TXSTATE 0x260 +#define PSGMIIPHY_CHANNEL3RXSTATES 0x264 +#define PSGMIIPHY_CHANNEL4TXSTATE 0x268 +#define PSGMIIPHY_CHANNEL4RXSTATES 0x26c + +/* PSGMII Registers Field*/ + +/*PSGMIIPHY_EEE_CH0_1 register field*/ +#define PSGMIIPHY_EEE_DIS_LPI 0x2 +#define PSGMIIPHY_EEE_EN_LPI 0x1 + +/*PSGMIIPHY_MODE_CONTROL register field*/ +#define PSGMIIPHY_MODE_SW_V17_V18 0x8000 +/* Interface Mode, bits 12:14 */ +#define PSGMIIPHY_MODE_CH0_MODE_1000BASEX 0x0000 +#define PSGMIIPHY_MODE_CH0_MODE_PSGMII_PHY 0x1000 +#define PSGMIIPHY_MODE_CH0_MODE_PSGMII_MAC 0x2000 +#define PSGMIIPHY_MODE_CH0_PSGMII_QSGMII 0x200 +#define PSGMIIPHY_MODE_CH0_QSGMII_SGMII 0x100 +#define PSGMIIPHY_MODE_SGMII_EVEN_LOW 0x0008 +#define PSGMIIPHY_MODE_CH4_CH1_0_SGMII 0x0004 +#define PSGMIIPHY_MODE_CH1_CH0_SGMII 0x0002 +#define PSGMIIPHY_MODE_CH0_ATHR_CSCO_MODE_25M 0x0001 + +/*CHANNEL_0_INPUT_OUTPUT_1 register field*/ +#define PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_1_MR_AN_COMPLETE 0x800 + +/*CHANNEL_0_INPUT_OUTPUT_4 register field*/ +#define PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4_POWER_ON_25M 0x400 +#define PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4_MR_MAIN_RESET_25M 0x200 +#define PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4_MR_MR_LOOPBACK_25M 0x100 +#define PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4_MR_RESTART_AN_25M 0x80 +#define PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4_MR_AN_ENABLE_25M 0x40 +#define PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4_MR_MR_REG4_CH_25M 0x20 +#define PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4_MR_MR_NP_LOADED_25M 0x10 +#define PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4_FORCE_SPEED_25M 0x08 +#define PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4_SPEED_25M_10M 0x02 +#define PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4_SPEED_25M_100M 0x04 +#define PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4_SPEED_25M_1000M 0x06 +#define PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4_REM_PHY_LPBK 0x00 + +/*CHANNEL_0_INPUT_OUTPUT_5 register field*/ +#define PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_5_FULL_DUPLEX_25M 0x800 +#define PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_5_HALF_DUPLEX_25M 0x400 +#define PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_5_REMOTE_FAULT_25M 0x300 +#define PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_5_LINK_25M 0x80 +#define PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_5_DUPLEX_MODE_25M 0x40 +#define PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_5_SPEED_MODE_25M 0x30 +#define PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_5_PAUSE_SG_TX_EN_25M 0x08 +#define PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_5_NEXT_PAGE_25M 0x04 +#define PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_5_PAUSE_25M 0x02 +#define PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_5_ASYM_PAUSE_25M 0x01 + +/*CHANNEL_1_INPUT_OUTPUT_4 register field*/ +#define PSGMIIPHY_CHANNEL_1_INPUT_OUTPUT_4_POWER_ON_25M 0x400 +#define PSGMIIPHY_CHANNEL_1_INPUT_OUTPUT_4_MR_MAIN_RESET_25M 0x200 +#define PSGMIIPHY_CHANNEL_1_INPUT_OUTPUT_4_MR_MR_LOOPBACK_25M 0x100 +#define PSGMIIPHY_CHANNEL_1_INPUT_OUTPUT_4_MR_RESTART_AN_25M 0x80 +#define PSGMIIPHY_CHANNEL_1_INPUT_OUTPUT_4_MR_AN_ENABLE_25M 0x40 +#define PSGMIIPHY_CHANNEL_1_INPUT_OUTPUT_4_MR_MR_REG4_CH_25M 0x20 +#define PSGMIIPHY_CHANNEL_1_INPUT_OUTPUT_4_MR_MR_NP_LOADED_25M 0x10 +#define PSGMIIPHY_CHANNEL_1_INPUT_OUTPUT_4_FORCE_SPEED_25M 0x08 +#define PSGMIIPHY_CHANNEL_1_INPUT_OUTPUT_4_SPEED_25M_10M 0x02 +#define PSGMIIPHY_CHANNEL_1_INPUT_OUTPUT_4_SPEED_25M_100M 0x04 +#define PSGMIIPHY_CHANNEL_1_INPUT_OUTPUT_4_SPEED_25M_1000M 0x06 +#define PSGMIIPHY_CHANNEL_1_INPUT_OUTPUT_4_REM_PHY_LPBK 0x00 + +/*CHANNEL_1_INPUT_OUTPUT_5 register field*/ +#define PSGMIIPHY_CHANNEL_1_INPUT_OUTPUT_5_FULL_DUPLEX_25M 0x800 +#define PSGMIIPHY_CHANNEL_1_INPUT_OUTPUT_5_HALF_DUPLEX_25M 0x400 +#define PSGMIIPHY_CHANNEL_1_INPUT_OUTPUT_5_REMOTE_FAULT_25M 0x300 +#define PSGMIIPHY_CHANNEL_1_INPUT_OUTPUT_5_LINK_25M 0x80 +#define PSGMIIPHY_CHANNEL_1_INPUT_OUTPUT_5_DUPLEX_MODE_25M 0x40 +#define PSGMIIPHY_CHANNEL_1_INPUT_OUTPUT_5_SPEED_MODE_25M 0x30 +#define PSGMIIPHY_CHANNEL_1_INPUT_OUTPUT_5_PAUSE_SG_TX_EN_25M 0x08 +#define PSGMIIPHY_CHANNEL_1_INPUT_OUTPUT_5_NEXT_PAGE_25M 0x04 +#define PSGMIIPHY_CHANNEL_1_INPUT_OUTPUT_5_PAUSE_25M 0x02 +#define PSGMIIPHY_CHANNEL_1_INPUT_OUTPUT_5_ASYM_PAUSE_25M 0x01 + +/*CHANNEL_2_INPUT_OUTPUT_4 register field*/ +#define PSGMIIPHY_CHANNEL_2_INPUT_OUTPUT_4_POWER_ON_25M 0x400 +#define PSGMIIPHY_CHANNEL_2_INPUT_OUTPUT_4_MR_MAIN_RESET_25M 0x200 +#define PSGMIIPHY_CHANNEL_2_INPUT_OUTPUT_4_MR_MR_LOOPBACK_25M 0x100 +#define PSGMIIPHY_CHANNEL_2_INPUT_OUTPUT_4_MR_RESTART_AN_25M 0x80 +#define PSGMIIPHY_CHANNEL_2_INPUT_OUTPUT_4_MR_AN_ENABLE_25M 0x40 +#define PSGMIIPHY_CHANNEL_2_INPUT_OUTPUT_4_MR_MR_REG4_CH_25M 0x20 +#define PSGMIIPHY_CHANNEL_2_INPUT_OUTPUT_4_MR_MR_NP_LOADED_25M 0x10 +#define PSGMIIPHY_CHANNEL_2_INPUT_OUTPUT_4_FORCE_SPEED_25M 0x08 +#define PSGMIIPHY_CHANNEL_2_INPUT_OUTPUT_4_SPEED_25M_10M 0x02 +#define PSGMIIPHY_CHANNEL_2_INPUT_OUTPUT_4_SPEED_25M_100M 0x04 +#define PSGMIIPHY_CHANNEL_2_INPUT_OUTPUT_4_SPEED_25M_1000M 0x06 +#define PSGMIIPHY_CHANNEL_2_INPUT_OUTPUT_4_REM_PHY_LPBK 0x00 + +/*CHANNEL_2_INPUT_OUTPUT_5 register field*/ +#define PSGMIIPHY_CHANNEL_2_INPUT_OUTPUT_5_FULL_DUPLEX_25M 0x800 +#define PSGMIIPHY_CHANNEL_2_INPUT_OUTPUT_5_HALF_DUPLEX_25M 0x400 +#define PSGMIIPHY_CHANNEL_2_INPUT_OUTPUT_5_REMOTE_FAULT_25M 0x300 +#define PSGMIIPHY_CHANNEL_2_INPUT_OUTPUT_5_LINK_25M 0x80 +#define PSGMIIPHY_CHANNEL_2_INPUT_OUTPUT_5_DUPLEX_MODE_25M 0x40 +#define PSGMIIPHY_CHANNEL_2_INPUT_OUTPUT_5_SPEED_MODE_25M 0x30 +#define PSGMIIPHY_CHANNEL_2_INPUT_OUTPUT_5_PAUSE_SG_TX_EN_25M 0x08 +#define PSGMIIPHY_CHANNEL_2_INPUT_OUTPUT_5_NEXT_PAGE_25M 0x04 +#define PSGMIIPHY_CHANNEL_2_INPUT_OUTPUT_5_PAUSE_25M 0x02 +#define PSGMIIPHY_CHANNEL_2_INPUT_OUTPUT_5_ASYM_PAUSE_25M 0x01 + +/*CHANNEL_3_INPUT_OUTPUT_4 register field*/ +#define PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_4_POWER_ON_25M 0x400 +#define PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_4_MR_MAIN_RESET_25M 0x200 +#define PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_4_MR_MR_LOOPBACK_25M 0x100 +#define PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_4_MR_RESTART_AN_25M 0x80 +#define PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_4_MR_AN_ENABLE_25M 0x40 +#define PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_4_MR_MR_REG4_CH_25M 0x20 +#define PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_4_MR_MR_NP_LOADED_25M 0x10 +#define PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_4_FORCE_SPEED_25M 0x08 + +#define PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_4_SPEED_25M_MASK 0x06 +#define PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_4_SPEED_25M_10M 0x0 +#define PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_4_SPEED_25M_100M 0x02 +#define PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_4_SPEED_25M_1000M 0x04 +#define PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_4_REM_PHY_LPBK 0x00 + +/*CHANNEL_3_INPUT_OUTPUT_5 register field*/ +#define PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_5_FULL_DUPLEX_25M 0x800 +#define PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_5_HALF_DUPLEX_25M 0x400 +#define PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_5_REMOTE_FAULT_25M 0x300 +#define PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_5_LINK_25M 0x80 +#define PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_5_DUPLEX_MODE_25M 0x40 +#define PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_5_SPEED_MODE_25M 0x30 +#define PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_5_SPEED_25M_10M 0x00 +#define PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_5_SPEED_25M_100M 0x10 +#define PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_5_SPEED_25M_1000M 0x20 +#define PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_5_PAUSE_SG_TX_EN_25M 0x08 +#define PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_5_NEXT_PAGE_25M 0x04 +#define PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_5_PAUSE_25M 0x02 +#define PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_5_ASYM_PAUSE_25M 0x01 + +/*CHANNEL_4_INPUT_OUTPUT_4 register field*/ +#define PSGMIIPHY_CHANNEL_4_INPUT_OUTPUT_4_POWER_ON_25M 0x400 +#define PSGMIIPHY_CHANNEL_4_INPUT_OUTPUT_4_MR_MAIN_RESET_25M 0x200 +#define PSGMIIPHY_CHANNEL_4_INPUT_OUTPUT_4_MR_MR_LOOPBACK_25M 0x100 +#define PSGMIIPHY_CHANNEL_4_INPUT_OUTPUT_4_MR_RESTART_AN_25M 0x80 +#define PSGMIIPHY_CHANNEL_4_INPUT_OUTPUT_4_MR_AN_ENABLE_25M 0x40 +#define PSGMIIPHY_CHANNEL_4_INPUT_OUTPUT_4_MR_MR_REG4_CH_25M 0x20 +#define PSGMIIPHY_CHANNEL_4_INPUT_OUTPUT_4_MR_MR_NP_LOADED_25M 0x10 +#define PSGMIIPHY_CHANNEL_4_INPUT_OUTPUT_4_FORCE_SPEED_25M 0x08 +#define PSGMIIPHY_CHANNEL_4_INPUT_OUTPUT_4_SPEED_25M_10M 0x02 +#define PSGMIIPHY_CHANNEL_4_INPUT_OUTPUT_4_SPEED_25M_100M 0x04 +#define PSGMIIPHY_CHANNEL_4_INPUT_OUTPUT_4_SPEED_25M_1000M 0x06 +#define PSGMIIPHY_CHANNEL_4_INPUT_OUTPUT_4_REM_PHY_LPBK 0x00 + +/*CHANNEL_4_INPUT_OUTPUT_5 register field*/ +#define PSGMIIPHY_CHANNEL_4_INPUT_OUTPUT_5_FULL_DUPLEX_25M 0x800 +#define PSGMIIPHY_CHANNEL_4_INPUT_OUTPUT_5_HALF_DUPLEX_25M 0x400 +#define PSGMIIPHY_CHANNEL_4_INPUT_OUTPUT_5_REMOTE_FAULT_25M 0x300 +#define PSGMIIPHY_CHANNEL_4_INPUT_OUTPUT_5_LINK_25M 0x80 +#define PSGMIIPHY_CHANNEL_4_INPUT_OUTPUT_5_DUPLEX_MODE_25M 0x40 +#define PSGMIIPHY_CHANNEL_4_INPUT_OUTPUT_5_SPEED_MODE_25M 0x30 +#define PSGMIIPHY_CHANNEL_4_INPUT_OUTPUT_5_PAUSE_SG_TX_EN_25M 0x08 +#define PSGMIIPHY_CHANNEL_4_INPUT_OUTPUT_5_NEXT_PAGE_25M 0x04 +#define PSGMIIPHY_CHANNEL_4_INPUT_OUTPUT_5_PAUSE_25M 0x02 +#define PSGMIIPHY_CHANNEL_4_INPUT_OUTPUT_5_ASYM_PAUSE_25M 0x01 + +typedef enum { + PSGMII_MAC_MODE_PSGMII = 0, + PSGMII_MAC_MODE_QSGMII, + PSGMII_MAC_MODE_SGMII, + PSGMII_MAC_MODE_DEFAULT +}psgmii_interface_mac_mode_t; + + sw_error_t + dess_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 + dess_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 + dess_psgmii_set_lpi(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable); + + sw_error_t + dess_psgmii_get_lpi(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t *enable); + + sw_error_t + dess_psgmii_set_interface_type(a_uint32_t dev_id, a_uint32_t phy_id, + psgmii_interface_mac_mode_t mode); + + sw_error_t + dess_psgmii_get_interface_type(a_uint32_t dev_id, a_uint32_t * phy_id, + psgmii_interface_mac_mode_t * mode); + + a_bool_t + dess_psgmii_autoneg_done(a_uint32_t dev_id, a_uint32_t phy_id); + + sw_error_t + dess_psgmii_reset(a_uint32_t dev_id, a_uint32_t phy_id); + + sw_error_t + dess_psgmii_poweroff(a_uint32_t dev_id, a_uint32_t phy_id); + + sw_error_t + dess_psgmii_poweron(a_uint32_t dev_id, a_uint32_t phy_id); + + a_bool_t + dess_psgmii_get_link_status(a_uint32_t dev_id, a_uint32_t phy_id); + + sw_error_t + dess_psgmii_set_loopback(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t enable); + + sw_error_t + dess_psgmii_get_loopback(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t * enable); + + a_bool_t dess_psgmii_autoneg_status(a_uint32_t dev_id, a_uint32_t phy_id); + + sw_error_t + dess_psgmii_restart_autoneg(a_uint32_t dev_id, a_uint32_t phy_id); + + sw_error_t + dess_psgmii_enable_autoneg(a_uint32_t dev_id, a_uint32_t phy_id); + + sw_error_t + dess_psgmii_set_duplex(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_duplex_t duplex); + + sw_error_t + dess_psgmii_get_duplex(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_duplex_t * duplex); + + sw_error_t + dess_psgmii_set_speed(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_speed_t speed); + + sw_error_t + dess_psgmii_get_speed(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_speed_t * speed); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _DESS_PSGMII_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_qos.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_qos.h new file mode 100755 index 000000000..083e3a874 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_qos.h @@ -0,0 +1,180 @@ +/* + * 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 _DESS_QOS_H_ +#define _DESS_QOS_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_qos.h" + + sw_error_t dess_qos_init(a_uint32_t dev_id); + +#ifdef IN_QOS +#define DESS_QOS_INIT(rv, dev_id) \ + { \ + rv = dess_qos_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define DESS_QOS_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + dess_qos_queue_tx_buf_status_set(a_uint32_t dev_id, + fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_qos_queue_tx_buf_status_get(a_uint32_t dev_id, + fal_port_t port_id, + a_bool_t * enable); + + HSL_LOCAL sw_error_t + dess_qos_port_tx_buf_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_qos_port_tx_buf_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + HSL_LOCAL sw_error_t + dess_qos_port_red_en_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + HSL_LOCAL sw_error_t + dess_qos_port_red_en_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t* enable); + + + HSL_LOCAL sw_error_t + dess_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); + + + HSL_LOCAL sw_error_t + dess_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); + + + HSL_LOCAL sw_error_t + dess_qos_port_tx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number); + + + HSL_LOCAL sw_error_t + dess_qos_port_tx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number); + + + HSL_LOCAL sw_error_t + dess_qos_port_rx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number); + + + HSL_LOCAL sw_error_t + dess_qos_port_rx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number); + + + HSL_LOCAL sw_error_t + dess_qos_port_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_qos_port_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + dess_qos_port_mode_pri_set(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_uint32_t pri); + + + HSL_LOCAL sw_error_t + dess_qos_port_mode_pri_get(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_uint32_t * pri); + + + HSL_LOCAL sw_error_t + dess_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[]); + + + HSL_LOCAL sw_error_t + dess_qos_port_sch_mode_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_sch_mode_t * mode, a_uint32_t weight[]); + + HSL_LOCAL sw_error_t + dess_qos_port_default_spri_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t spri); + + + HSL_LOCAL sw_error_t + dess_qos_port_default_spri_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * spri); + + + HSL_LOCAL sw_error_t + dess_qos_port_default_cpri_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t cpri); + + + HSL_LOCAL sw_error_t + dess_qos_port_default_cpri_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * cpri); + + sw_error_t + dess_qos_port_force_spri_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + sw_error_t + dess_qos_port_force_spri_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t* enable); + + sw_error_t + dess_qos_port_force_cpri_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + sw_error_t + dess_qos_port_force_cpri_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t* enable); + + HSL_LOCAL sw_error_t + dess_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); + + + HSL_LOCAL sw_error_t + dess_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); + + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _DESS_QOS_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_rate.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_rate.h new file mode 100755 index 000000000..d5316f989 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_rate.h @@ -0,0 +1,96 @@ +/* + * 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 _DESS_RATE_H_ +#define _DESS_RATE_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_rate.h" + + sw_error_t dess_rate_init(a_uint32_t dev_id); + +#ifdef IN_RATE +#define DESS_RATE_INIT(rv, dev_id) \ + { \ + rv = dess_rate_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define DESS_RATE_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + dess_rate_port_policer_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_policer_t * policer); + + HSL_LOCAL sw_error_t + dess_rate_port_policer_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_policer_t * policer); + + HSL_LOCAL sw_error_t + dess_rate_port_shaper_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable, + fal_egress_shaper_t * shaper); + + HSL_LOCAL sw_error_t + dess_rate_port_shaper_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable, + fal_egress_shaper_t * shaper); + + HSL_LOCAL sw_error_t + dess_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); + + HSL_LOCAL sw_error_t + dess_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); + + HSL_LOCAL sw_error_t + dess_rate_acl_policer_set(a_uint32_t dev_id, a_uint32_t policer_id, + fal_acl_policer_t * policer); + + HSL_LOCAL sw_error_t + dess_rate_acl_policer_get(a_uint32_t dev_id, a_uint32_t policer_id, + fal_acl_policer_t * policer); + + HSL_LOCAL sw_error_t + dess_rate_port_add_rate_byte_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t number); + + HSL_LOCAL sw_error_t + dess_rate_port_add_rate_byte_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t *number); + + HSL_LOCAL sw_error_t + dess_rate_port_gol_flow_en_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + HSL_LOCAL sw_error_t + dess_rate_port_gol_flow_en_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t* enable); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _DESS_RATE_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_reg.h new file mode 100755 index 000000000..89b67d144 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_reg.h @@ -0,0 +1,5011 @@ +/* + * 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 _DESS_REG_H_ +#define _DESS_REG_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define DESS_DEVICE_ID 0x14 /* TBD */ + +#define MAX_ENTRY_LEN 128 + +#define HSL_RW 1 +#define HSL_RO 0 + + + /* DESS Mask Control Register */ +#define MASK_CTL +#define MASK_CTL_ID 0 +#define MASK_CTL_OFFSET 0x0000 +#define MASK_CTL_E_LENGTH 4 +#define MASK_CTL_E_OFFSET 0 +#define MASK_CTL_NR_E 1 + +#define DEVICE_ID +#define MASK_CTL_DEVICE_ID_BOFFSET 8 +#define MASK_CTL_DEVICE_ID_BLEN 8 +#define MASK_CTL_DEVICE_ID_FLAG HSL_RO + +#define REV_ID +#define MASK_CTL_REV_ID_BOFFSET 0 +#define MASK_CTL_REV_ID_BLEN 8 +#define MASK_CTL_REV_ID_FLAG HSL_RO + + +/* RGMII Control Register */ +#define RGMII_CTRL +#define RGMII_CTRL_ID 0 +#define RGMII_CTRL_OFFSET 0x0004 +#define RGMII_CTRL_E_LENGTH 4 +#define RGMII_CTRL_E_OFFSET 0 +#define RGMII_CTRL_NR_E 1 + +#define RMII1_MASTER_EN +#define RGMII_CTRL_RMII1_MASTER_EN_BOFFSET 25 +#define RGMII_CTRL_RMII1_MASTER_EN_BLEN 1 +#define RGMII_CTRL_RMII1_MASTER_EN_FLAG HSL_RW + +#define RMII0_MASTER_EN +#define RGMII_CTRL_RMII0_MASTER_EN_BOFFSET 24 +#define RGMII_CTRL_RMII0_MASTER_EN_BLEN 1 +#define RGMII_CTRL_RMII0_MASTER_EN_FLAG HSL_RW + + +/* Global Interrupt Status Register1 */ +#define GBL_INT_STATUS1 +#define GBL_INT_STATUS1_ID 1 +#define GBL_INT_STATUS1_OFFSET 0x0024 +#define GBL_INT_STATUS1_E_LENGTH 4 +#define GBL_INT_STATUS1_E_OFFSET 0 +#define GBL_INT_STATUS1_NR_E 1 + +#define LINK_CHG_INT_S +#define GBL_INT_STATUS1_LINK_CHG_INT_S_BOFFSET 1 +#define GBL_INT_STATUS1_LINK_CHG_INT_S_BLEN 7 +#define GBL_INT_STATUS1_LINK_CHG_INT_S_FLAG HSL_RW + +#define PHY_INT_S +#define GBL_INT_STATUS1_PHY_INT_S_BOFFSET 15 +#define GBL_INT_STATUS1_PHY_INT_S_BLEN 1 +#define GBL_INT_STATUS1_PHY_INT_S_FLAG HSL_RO + + + /* Global Interrupt Mask Register1 */ +#define GBL_INT_MASK1 +#define GBL_INT_MASK1_ID 1 +#define GBL_INT_MASK1_OFFSET 0x002c +#define GBL_INT_MASK1_E_LENGTH 4 +#define GBL_INT_MASK1_E_OFFSET 0 +#define GBL_INT_MASK1_NR_E 1 + +#define LINK_CHG_INT_M +#define GBL_INT_MASK1_LINK_CHG_INT_M_BOFFSET 1 +#define GBL_INT_MASK1_LINK_CHG_INT_M_BLEN 7 +#define GBL_INT_MASK1_LINK_CHG_INT_M_FLAG HSL_RW + +#define PHY_INT_M +#define GBL_INT_MASK1_PHY_INT_M_BOFFSET 15 +#define GBL_INT_MASK1_PHY_INT_M_BLEN 1 +#define GBL_INT_MASK1_PHY_INT_M_FLAG HSL_RO + + + + + /* Module Enable Register */ +#define MOD_ENABLE +#define MOD_ENABLE_OFFSET 0x0030 +#define MOD_ENABLE_E_LENGTH 4 +#define MOD_ENABLE_E_OFFSET 0 +#define MOD_ENABLE_NR_E 1 + +#define L3_EN +#define MOD_ENABLE_L3_EN_BOFFSET 2 +#define MOD_ENABLE_L3_EN_BLEN 1 +#define MOD_ENABLE_L3_EN_FLAG HSL_RW + +#define ACL_EN +#define MOD_ENABLE_ACL_EN_BOFFSET 1 +#define MOD_ENABLE_ACL_EN_BLEN 1 +#define MOD_ENABLE_ACL_EN_FLAG HSL_RW + +#define MIB_EN +#define MOD_ENABLE_MIB_EN_BOFFSET 0 +#define MOD_ENABLE_MIB_EN_BLEN 1 +#define MOD_ENABLE_MIB_EN_FLAG HSL_RW + + + + + /* MIB Function Register */ +#define MIB_FUNC +#define MIB_FUNC_OFFSET 0x0034 +#define MIB_FUNC_E_LENGTH 4 +#define MIB_FUNC_E_OFFSET 0 +#define MIB_FUNC_NR_E 1 + +#define MIB_FUN +#define MIB_FUNC_MIB_FUN_BOFFSET 24 +#define MIB_FUNC_MIB_FUN_BLEN 3 +#define MIB_FUNC_MIB_FUN_FLAG HSL_RW + +#define MIB_FLUSH_PORT +#define MIB_FUNC_MIB_FLUSH_PORT_BOFFSET 21 +#define MIB_FUNC_MIB_FLUSH_PORT_BLEN 3 +#define MIB_FUNC_MIB_FLUSH_PORT_FLAG HSL_RW + +#define MIB_CPU_KEEP +#define MIB_FUNC_MIB_CPU_KEEP_BOFFSET 20 +#define MIB_FUNC_MIB_CPU_KEEP_BLEN 1 +#define MIB_FUNC_MIB_CPU_KEEP_FLAG HSL_RW + +#define MIB_BUSY +#define MIB_FUNC_MIB_BUSY_BOFFSET 17 +#define MIB_FUNC_MIB_BUSY_BLEN 1 +#define MIB_FUNC_MIB_BUSY_FLAG HSL_RW + +#define MIB_AT_HALF_EN +#define MIB_FUNC_MIB_AT_HALF_EN_BOFFSET 16 +#define MIB_FUNC_MIB_AT_HALF_EN_BLEN 1 +#define MIB_FUNC_MIB_AT_HALF_EN_FLAG HSL_RW + +#define MIB_TIMER +#define MIB_FUNC_MIB_TIMER_BOFFSET 0 +#define MIB_FUNC_MIB_TIMER_BLEN 16 +#define MIB_FUNC_MIB_TIMER_FLAG HSL_RW + + + + + /* Service tag Register */ +#define SERVICE_TAG +#define SERVICE_TAG_OFFSET 0x0048 +#define SERVICE_TAG_E_LENGTH 4 +#define SERVICE_TAG_E_OFFSET 0 +#define SERVICE_TAG_NR_E 1 + +#define STAG_MODE +#define SERVICE_TAG_STAG_MODE_BOFFSET 17 +#define SERVICE_TAG_STAG_MODE_BLEN 1 +#define SERVICE_TAG_STAG_MODE_FLAG HSL_RW + +#define TAG_VALUE +#define SERVICE_TAG_TAG_VALUE_BOFFSET 0 +#define SERVICE_TAG_TAG_VALUE_BLEN 16 +#define SERVICE_TAG_TAG_VALUE_FLAG HSL_RW + + + + + /* Global MAC Address Register */ +#define GLOBAL_MAC_ADDR0 +#define GLOBAL_MAC_ADDR0_OFFSET 0x0060 +#define GLOBAL_MAC_ADDR0_E_LENGTH 4 +#define GLOBAL_MAC_ADDR0_E_OFFSET 0 +#define GLOBAL_MAC_ADDR0_NR_E 1 + +#define GLB_BYTE4 +#define GLOBAL_MAC_ADDR0_GLB_BYTE4_BOFFSET 8 +#define GLOBAL_MAC_ADDR0_GLB_BYTE4_BLEN 8 +#define GLOBAL_MAC_ADDR0_GLB_BYTE4_FLAG HSL_RW + +#define GLB_BYTE5 +#define GLOBAL_MAC_ADDR0_GLB_BYTE5_BOFFSET 0 +#define GLOBAL_MAC_ADDR0_GLB_BYTE5_BLEN 8 +#define GLOBAL_MAC_ADDR0_GLB_BYTE5_FLAG HSL_RW + +#define GLOBAL_MAC_ADDR1 +#define GLOBAL_MAC_ADDR1_ID 4 +#define GLOBAL_MAC_ADDR1_OFFSET 0x0064 +#define GLOBAL_MAC_ADDR1_E_LENGTH 4 +#define GLOBAL_MAC_ADDR1_E_OFFSET 0 +#define GLOBAL_MAC_ADDR1_NR_E 1 + +#define GLB_BYTE0 +#define GLOBAL_MAC_ADDR1_GLB_BYTE0_BOFFSET 24 +#define GLOBAL_MAC_ADDR1_GLB_BYTE0_BLEN 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE0_FLAG HSL_RW + +#define GLB_BYTE1 +#define GLOBAL_MAC_ADDR1_GLB_BYTE1_BOFFSET 16 +#define GLOBAL_MAC_ADDR1_GLB_BYTE1_BLEN 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE1_FLAG HSL_RW + +#define GLB_BYTE2 +#define GLOBAL_MAC_ADDR1_GLB_BYTE2_BOFFSET 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE2_BLEN 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE2_FLAG HSL_RW + +#define GLB_BYTE3 +#define GLOBAL_MAC_ADDR1_GLB_BYTE3_BOFFSET 0 +#define GLOBAL_MAC_ADDR1_GLB_BYTE3_BLEN 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE3_FLAG HSL_RW + + + + + /* Max Size Register */ +#define MAX_SIZE +#define MAX_SIZE_OFFSET 0x0078 +#define MAX_SIZE_E_LENGTH 4 +#define MAX_SIZE_E_OFFSET 0 +#define MAX_SIZE_NR_E 1 + +#define CRC_RESERVE +#define MAX_SIZE_CRC_RESERVE_BOFFSET 16 +#define MAX_SIZE_CRC_RESERVE_BLEN 1 +#define MAX_SIZE_CRC_RESERVE_FLAG HSL_RW + +#define MAX_FRAME_SIZE +#define MAX_SIZE_MAX_FRAME_SIZE_BOFFSET 0 +#define MAX_SIZE_MAX_FRAME_SIZE_BLEN 14 +#define MAX_SIZE_MAX_FRAME_SIZE_FLAG HSL_RW + + + + + + + + + + + + + /* Port Status Register */ +#define PORT_STATUS +#define PORT_STATUS_OFFSET 0x007c +#define PORT_STATUS_E_LENGTH 4 +#define PORT_STATUS_E_OFFSET 0x0004 +#define PORT_STATUS_NR_E 7 + +#define FLOW_LINK_EN +#define PORT_STATUS_FLOW_LINK_EN_BOFFSET 12 +#define PORT_STATUS_FLOW_LINK_EN_BLEN 1 +#define PORT_STATUS_FLOW_LINK_EN_FLAG HSL_RW + +#define AUTO_RX_FLOW +#define PORT_STATUS_AUTO_RX_FLOW_BOFFSET 11 +#define PORT_STATUS_AUTO_RX_FLOW_BLEN 1 +#define PORT_STATUS_AUTO_RX_FLOW_FLAG HSL_RO + +#define AUTO_TX_FLOW +#define PORT_STATUS_AUTO_TX_FLOW_BOFFSET 10 +#define PORT_STATUS_AUTO_TX_FLOW_BLEN 1 +#define PORT_STATUS_AUTO_TX_FLOW_FLAG HSL_RO + +#define LINK_EN +#define PORT_STATUS_LINK_EN_BOFFSET 9 +#define PORT_STATUS_LINK_EN_BLEN 1 +#define PORT_STATUS_LINK_EN_FLAG HSL_RW + +#define LINK +#define PORT_STATUS_LINK_BOFFSET 8 +#define PORT_STATUS_LINK_BLEN 1 +#define PORT_STATUS_LINK_FLAG HSL_RO + +#define TX_HALF_FLOW_EN +#define PORT_STATUS_TX_HALF_FLOW_EN_BOFFSET 7 +#define PORT_STATUS_TX_HALF_FLOW_EN_BLEN 1 +#define PORT_STATUS_TX_HALF_FLOW_EN_FLAG HSL_RW + +#define DUPLEX_MODE +#define PORT_STATUS_DUPLEX_MODE_BOFFSET 6 +#define PORT_STATUS_DUPLEX_MODE_BLEN 1 +#define PORT_STATUS_DUPLEX_MODE_FLAG HSL_RW + +#define RX_FLOW_EN +#define PORT_STATUS_RX_FLOW_EN_BOFFSET 5 +#define PORT_STATUS_RX_FLOW_EN_BLEN 1 +#define PORT_STATUS_RX_FLOW_EN_FLAG HSL_RW + +#define TX_FLOW_EN +#define PORT_STATUS_TX_FLOW_EN_BOFFSET 4 +#define PORT_STATUS_TX_FLOW_EN_BLEN 1 +#define PORT_STATUS_TX_FLOW_EN_FLAG HSL_RW + +#define RXMAC_EN +#define PORT_STATUS_RXMAC_EN_BOFFSET 3 +#define PORT_STATUS_RXMAC_EN_BLEN 1 +#define PORT_STATUS_RXMAC_EN_FLAG HSL_RW + +#define TXMAC_EN +#define PORT_STATUS_TXMAC_EN_BOFFSET 2 +#define PORT_STATUS_TXMAC_EN_BLEN 1 +#define PORT_STATUS_TXMAC_EN_FLAG HSL_RW + +#define SPEED_MODE +#define PORT_STATUS_SPEED_MODE_BOFFSET 0 +#define PORT_STATUS_SPEED_MODE_BLEN 2 +#define PORT_STATUS_SPEED_MODE_FLAG HSL_RW + + + + + /* Header Ctl Register */ +#define HEADER_CTL +#define HEADER_CTL_OFFSET 0x0098 +#define HEADER_CTL_E_LENGTH 4 +#define HEADER_CTL_E_OFFSET 0x0004 +#define HEADER_CTL_NR_E 1 + +#define TYPE_LEN +#define HEADER_CTL_TYPE_LEN_BOFFSET 16 +#define HEADER_CTL_TYPE_LEN_BLEN 1 +#define HEADER_CTL_TYPE_LEN_FLAG HSL_RW + +#define TYPE_VAL +#define HEADER_CTL_TYPE_VAL_BOFFSET 0 +#define HEADER_CTL_TYPE_VAL_BLEN 16 +#define HEADER_CTL_TYPE_VAL_FLAG HSL_RW + + + + + /* Port Header Ctl Register */ +#define PORT_HDR_CTL +#define PORT_HDR_CTL_OFFSET 0x009c +#define PORT_HDR_CTL_E_LENGTH 4 +#define PORT_HDR_CTL_E_OFFSET 0x0004 +#define PORT_HDR_CTL_NR_E 7 + +#define IPG_DEC_EN +#define PORT_HDR_CTL_IPG_DEC_EN_BOFFSET 5 +#define PORT_HDR_CTL_IPG_DEC_EN_BLEN 1 +#define PORT_HDR_CTL_IPG_DEC_EN_FLAG HSL_RW + +#define LOOPBACK_EN +#define PORT_HDR_CTL_LOOPBACK_EN_BOFFSET 4 +#define PORT_HDR_CTL_LOOPBACK_EN_BLEN 1 +#define PORT_HDR_CTL_LOOPBACK_EN_FLAG HSL_RW + +#define RXHDR_MODE +#define PORT_HDR_CTL_RXHDR_MODE_BOFFSET 2 +#define PORT_HDR_CTL_RXHDR_MODE_BLEN 2 +#define PORT_HDR_CTL_RXHDR_MODE_FLAG HSL_RW + +#define TXHDR_MODE +#define PORT_HDR_CTL_TXHDR_MODE_BOFFSET 0 +#define PORT_HDR_CTL_TXHDR_MODE_BLEN 2 +#define PORT_HDR_CTL_TXHDR_MODE_FLAG HSL_RW + + + + + /* EEE control Register */ +#define EEE_CTL +#define EEE_CTL_OFFSET 0x0100 +#define EEE_CTL_E_LENGTH 4 +#define EEE_CTL_E_OFFSET 0 +#define EEE_CTL_NR_E 1 + +#define LPI_STATE_REMAP_EN_5 +#define EEE_CTL_LPI_STATE_REMAP_EN_5_BOFFSET 13 +#define EEE_CTL_LPI_STATE_REMAP_EN_5_BLEN 1 +#define EEE_CTL_LPI_STATE_REMAP_EN_5_FLAG HSL_RW + +#define LPI_EN_5 +#define EEE_CTL_LPI_EN_5_BOFFSET 12 +#define EEE_CTL_LPI_EN_5_BLEN 1 +#define EEE_CTL_LPI_EN_5_FLAG HSL_RW + +#define LPI_STATE_REMAP_EN_4 +#define EEE_CTL_LPI_STATE_REMAP_EN_4_BOFFSET 11 +#define EEE_CTL_LPI_STATE_REMAP_EN_4_BLEN 1 +#define EEE_CTL_LPI_STATE_REMAP_EN_4_FLAG HSL_RW + +#define LPI_EN_4 +#define EEE_CTL_LPI_EN_4_BOFFSET 10 +#define EEE_CTL_LPI_EN_4_BLEN 1 +#define EEE_CTL_LPI_EN_4_FLAG HSL_RW + +#define LPI_STATE_REMAP_EN_3 +#define EEE_CTL_LPI_STATE_REMAP_EN_3_BOFFSET 9 +#define EEE_CTL_LPI_STATE_REMAP_EN_3_BLEN 1 +#define EEE_CTL_LPI_STATE_REMAP_EN_3_FLAG HSL_RW + +#define LPI_EN_3 +#define EEE_CTL_LPI_EN_3_BOFFSET 8 +#define EEE_CTL_LPI_EN_3_BLEN 1 +#define EEE_CTL_LPI_EN_3_FLAG HSL_RW + +#define LPI_STATE_REMAP_EN_2 +#define EEE_CTL_LPI_STATE_REMAP_EN_2_BOFFSET 7 +#define EEE_CTL_LPI_STATE_REMAP_EN_2_BLEN 1 +#define EEE_CTL_LPI_STATE_REMAP_EN_2_FLAG HSL_RW + +#define LPI_EN_2 +#define EEE_CTL_LPI_EN_2_BOFFSET 6 +#define EEE_CTL_LPI_EN_2_BLEN 1 +#define EEE_CTL_LPI_EN_2_FLAG HSL_RW + +#define LPI_STATE_REMAP_EN_1 +#define EEE_CTL_LPI_STATE_REMAP_EN_1_BOFFSET 5 +#define EEE_CTL_LPI_STATE_REMAP_EN_1_BLEN 1 +#define EEE_CTL_LPI_STATE_REMAP_EN_1_FLAG HSL_RW + +#define LPI_EN_1 +#define EEE_CTL_LPI_EN_1_BOFFSET 4 +#define EEE_CTL_LPI_EN_1_BLEN 1 +#define EEE_CTL_LPI_EN_1_FLAG HSL_RW + + + + + /* Frame Ack Ctl0 Register */ +#define FRAME_ACK_CTL0 +#define FRAME_ACK_CTL0_OFFSET 0x0210 +#define FRAME_ACK_CTL0_E_LENGTH 4 +#define FRAME_ACK_CTL0_E_OFFSET 0 +#define FRAME_ACK_CTL0_NR_E 1 + +#define ARP_REQ_EN +#define FRAME_ACK_CTL0_ARP_REQ_EN_BOFFSET 6 +#define FRAME_ACK_CTL0_ARP_REQ_EN_BLEN 1 +#define FRAME_ACK_CTL0_ARP_REQ_EN_FLAG HSL_RW + +#define ARP_REP_EN +#define FRAME_ACK_CTL0_ARP_REP_EN_BOFFSET 5 +#define FRAME_ACK_CTL0_ARP_REP_EN_BLEN 1 +#define FRAME_ACK_CTL0_ARP_REP_EN_FLAG HSL_RW + +#define DHCP_EN +#define FRAME_ACK_CTL0_DHCP_EN_BOFFSET 4 +#define FRAME_ACK_CTL0_DHCP_EN_BLEN 1 +#define FRAME_ACK_CTL0_DHCP_EN_FLAG HSL_RW + +#define EAPOL_EN +#define FRAME_ACK_CTL0_EAPOL_EN_BOFFSET 3 +#define FRAME_ACK_CTL0_EAPOL_EN_BLEN 1 +#define FRAME_ACK_CTL0_EAPOL_EN_FLAG HSL_RW + +#define LEAVE_EN +#define FRAME_ACK_CTL0_LEAVE_EN_BOFFSET 2 +#define FRAME_ACK_CTL0_LEAVE_EN_BLEN 1 +#define FRAME_ACK_CTL0_LEAVE_EN_FLAG HSL_RW + +#define JOIN_EN +#define FRAME_ACK_CTL0_JOIN_EN_BOFFSET 1 +#define FRAME_ACK_CTL0_JOIN_EN_BLEN 1 +#define FRAME_ACK_CTL0_JOIN_EN_FLAG HSL_RW + +#define IGMP_MLD_EN +#define FRAME_ACK_CTL0_IGMP_MLD_EN_BOFFSET 0 +#define FRAME_ACK_CTL0_IGMP_MLD_EN_BLEN 1 +#define FRAME_ACK_CTL0_IGMP_MLD_EN_FLAG HSL_RW + + + + + /* Frame Ack Ctl1 Register */ +#define FRAME_ACK_CTL1 +#define FRAME_ACK_CTL1_OFFSET 0x0214 +#define FRAME_ACK_CTL1_E_LENGTH 4 +#define FRAME_ACK_CTL1_E_OFFSET 0 +#define FRAME_ACK_CTL1_NR_E 1 + +#define LLDP_EN +#define FRAME_ACK_CTL1_LLDP_EN_BOFFSET 26 +#define FRAME_ACK_CTL1_LLDP_EN_BLEN 1 +#define FRAME_ACK_CTL1_LLDP_EN_FLAG HSL_RW + + +#define PPPOE_EN +#define FRAME_ACK_CTL1_PPPOE_EN_BOFFSET 25 +#define FRAME_ACK_CTL1_PPPOE_EN_BLEN 1 +#define FRAME_ACK_CTL1_PPPOE_EN_FLAG HSL_RW + +#define IGMP_V3_EN +#define FRAME_ACK_CTL1_IGMP_V3_EN_BOFFSET 24 +#define FRAME_ACK_CTL1_IGMP_V3_EN_BLEN 1 +#define FRAME_ACK_CTL1_IGMP_V3_EN_FLAG HSL_RW + + + + + /* Window Rule Ctl0 Register */ +#define WIN_RULE_CTL0 +#define WIN_RULE_CTL0_OFFSET 0x0218 +#define WIN_RULE_CTL0_E_LENGTH 4 +#define WIN_RULE_CTL0_E_OFFSET 0x4 +#define WIN_RULE_CTL0_NR_E 7 + +#define L4_LENGTH +#define WIN_RULE_CTL0_L4_LENGTH_BOFFSET 24 +#define WIN_RULE_CTL0_L4_LENGTH_BLEN 4 +#define WIN_RULE_CTL0_L4_LENGTH_FLAG HSL_RW + +#define L3_LENGTH +#define WIN_RULE_CTL0_L3_LENGTH_BOFFSET 20 +#define WIN_RULE_CTL0_L3_LENGTH_BLEN 4 +#define WIN_RULE_CTL0_L3_LENGTH_FLAG HSL_RW + +#define L2_LENGTH +#define WIN_RULE_CTL0_L2_LENGTH_BOFFSET 16 +#define WIN_RULE_CTL0_L2_LENGTH_BLEN 4 +#define WIN_RULE_CTL0_L2_LENGTH_FLAG HSL_RW + +#define L4_OFFSET +#define WIN_RULE_CTL0_L4_OFFSET_BOFFSET 10 +#define WIN_RULE_CTL0_L4_OFFSET_BLEN 5 +#define WIN_RULE_CTL0_L4_OFFSET_FLAG HSL_RW + +#define L3_OFFSET +#define WIN_RULE_CTL0_L3_OFFSET_BOFFSET 5 +#define WIN_RULE_CTL0_L3_OFFSET_BLEN 5 +#define WIN_RULE_CTL0_L3_OFFSET_FLAG HSL_RW + +#define L2_OFFSET +#define WIN_RULE_CTL0_L2_OFFSET_BOFFSET 0 +#define WIN_RULE_CTL0_L2_OFFSET_BLEN 5 +#define WIN_RULE_CTL0_L2_OFFSET_FLAG HSL_RW + + + + + /* Window Rule Ctl1 Register */ +#define WIN_RULE_CTL1 +#define WIN_RULE_CTL1_OFFSET 0x0234 +#define WIN_RULE_CTL1_E_LENGTH 4 +#define WIN_RULE_CTL1_E_OFFSET 0x4 +#define WIN_RULE_CTL1_NR_E 7 + +#define L3P_LENGTH +#define WIN_RULE_CTL1_L3P_LENGTH_BOFFSET 20 +#define WIN_RULE_CTL1_L3P_LENGTH_BLEN 4 +#define WIN_RULE_CTL1_L3P_LENGTH_FLAG HSL_RW + +#define L2S_LENGTH +#define WIN_RULE_CTL1_L2S_LENGTH_BOFFSET 16 +#define WIN_RULE_CTL1_L2S_LENGTH_BLEN 4 +#define WIN_RULE_CTL1_L2S_LENGTH_FLAG HSL_RW + +#define L3P_OFFSET +#define WIN_RULE_CTL1_L3P_OFFSET_BOFFSET 5 +#define WIN_RULE_CTL1_L3P_OFFSET_BLEN 5 +#define WIN_RULE_CTL1_L3P_OFFSET_FLAG HSL_RW + +#define L2S_OFFSET +#define WIN_RULE_CTL1_L2S_OFFSET_BOFFSET 0 +#define WIN_RULE_CTL1_L2S_OFFSET_BLEN 5 +#define WIN_RULE_CTL1_L2S_OFFSET_FLAG HSL_RW + + + + + /* Trunk Hash Mode Register */ +#define TRUNK_HASH_MODE +#define TRUNK_HASH_MODE_OFFSET 0x0270 +#define TRUNK_HASH_MODE_E_LENGTH 4 +#define TRUNK_HASH_MODE_E_OFFSET 0x4 +#define TRUNK_HASH_MODE_NR_E 1 + +#define DIP_EN +#define TRUNK_HASH_MODE_DIP_EN_BOFFSET 3 +#define TRUNK_HASH_MODE_DIP_EN_BLEN 1 +#define TRUNK_HASH_MODE_DIP_EN_FLAG HSL_RW + +#define SIP_EN +#define TRUNK_HASH_MODE_SIP_EN_BOFFSET 2 +#define TRUNK_HASH_MODE_SIP_EN_BLEN 1 +#define TRUNK_HASH_MODE_SIP_EN_FLAG HSL_RW + +#define SA_EN +#define TRUNK_HASH_MODE_SA_EN_BOFFSET 1 +#define TRUNK_HASH_MODE_SA_EN_BLEN 1 +#define TRUNK_HASH_MODE_SA_EN_FLAG HSL_RW + +#define DA_EN +#define TRUNK_HASH_MODE_DA_EN_BOFFSET 0 +#define TRUNK_HASH_MODE_DA_EN_BLEN 1 +#define TRUNK_HASH_MODE_DA_EN_FLAG HSL_RW + + + + + /* Vlan Table Function0 Register */ +#define VLAN_TABLE_FUNC0 +#define VLAN_TABLE_FUNC0_OFFSET 0x0610 +#define VLAN_TABLE_FUNC0_E_LENGTH 4 +#define VLAN_TABLE_FUNC0_E_OFFSET 0 +#define VLAN_TABLE_FUNC0_NR_E 1 + +#define VT_VALID +#define VLAN_TABLE_FUNC0_VT_VALID_BOFFSET 20 +#define VLAN_TABLE_FUNC0_VT_VALID_BLEN 1 +#define VLAN_TABLE_FUNC0_VT_VALID_FLAG HSL_RW + +#define IVL_EN +#define VLAN_TABLE_FUNC0_IVL_EN_BOFFSET 19 +#define VLAN_TABLE_FUNC0_IVL_EN_BLEN 1 +#define VLAN_TABLE_FUNC0_IVL_EN_FLAG HSL_RW + +#define LEARN_DIS +#define VLAN_TABLE_FUNC0_LEARN_DIS_BOFFSET 18 +#define VLAN_TABLE_FUNC0_LEARN_DIS_BLEN 1 +#define VLAN_TABLE_FUNC0_LEARN_DIS_FLAG HSL_RW + +#define VID_MEM +#define VLAN_TABLE_FUNC0_VID_MEM_BOFFSET 4 +#define VLAN_TABLE_FUNC0_VID_MEM_BLEN 14 +#define VLAN_TABLE_FUNC0_VID_MEM_FLAG HSL_RW + +#define VT_PRI_EN +#define VLAN_TABLE_FUNC0_VT_PRI_EN_BOFFSET 3 +#define VLAN_TABLE_FUNC0_VT_PRI_EN_BLEN 1 +#define VLAN_TABLE_FUNC0_VT_PRI_EN_FLAG HSL_RW + +#define VT_PRI +#define VLAN_TABLE_FUNC0_VT_PRI_BOFFSET 0 +#define VLAN_TABLE_FUNC0_VT_PRI_BLEN 3 +#define VLAN_TABLE_FUNC0_VT_PRI_FLAG HSL_RW + + /* Vlan Table Function1 Register */ +#define VLAN_TABLE_FUNC1 +#define VLAN_TABLE_FUNC1_OFFSET 0x0614 +#define VLAN_TABLE_FUNC1_E_LENGTH 4 +#define VLAN_TABLE_FUNC1_E_OFFSET 0 +#define VLAN_TABLE_FUNC1_NR_E 1 + +#define VT_BUSY +#define VLAN_TABLE_FUNC1_VT_BUSY_BOFFSET 31 +#define VLAN_TABLE_FUNC1_VT_BUSY_BLEN 1 +#define VLAN_TABLE_FUNC1_VT_BUSY_FLAG HSL_RW + +#define VLAN_ID +#define VLAN_TABLE_FUNC1_VLAN_ID_BOFFSET 16 +#define VLAN_TABLE_FUNC1_VLAN_ID_BLEN 12 +#define VLAN_TABLE_FUNC1_VLAN_ID_FLAG HSL_RW + +#define VT_PORT_NUM +#define VLAN_TABLE_FUNC1_VT_PORT_NUM_BOFFSET 8 +#define VLAN_TABLE_FUNC1_VT_PORT_NUM_BLEN 4 +#define VLAN_TABLE_FUNC1_VT_PORT_NUM_FLAG HSL_RW + +#define VT_FULL_VIO +#define VLAN_TABLE_FUNC1_VT_FULL_VIO_BOFFSET 4 +#define VLAN_TABLE_FUNC1_VT_FULL_VIO_BLEN 1 +#define VLAN_TABLE_FUNC1_VT_FULL_VIO_FLAG HSL_RW + +#define VT_FUNC +#define VLAN_TABLE_FUNC1_VT_FUNC_BOFFSET 0 +#define VLAN_TABLE_FUNC1_VT_FUNC_BLEN 3 +#define VLAN_TABLE_FUNC1_VT_FUNC_FLAG HSL_RW + + + + + /* Address Table Function0 Register */ +#define ADDR_TABLE_FUNC0 +#define ADDR_TABLE_FUNC0_OFFSET 0x0600 +#define ADDR_TABLE_FUNC0_E_LENGTH 4 +#define ADDR_TABLE_FUNC0_E_OFFSET 0 +#define ADDR_TABLE_FUNC0_NR_E 1 + + +#define AT_ADDR_BYTE2 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE2_BOFFSET 24 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE2_BLEN 8 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE2_FLAG HSL_RW + +#define AT_ADDR_BYTE3 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE3_BOFFSET 16 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE3_BLEN 8 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE3_FLAG HSL_RW + +#define AT_ADDR_BYTE4 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE4_BOFFSET 8 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE4_BLEN 8 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE4_FLAG HSL_RW + +#define AT_ADDR_BYTE5 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE5_BOFFSET 0 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE5_BLEN 8 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE5_FLAG HSL_RW + + /* Address Table Function1 Register */ +#define ADDR_TABLE_FUNC1 +#define ADDR_TABLE_FUNC1_OFFSET 0x0604 +#define ADDR_TABLE_FUNC1_E_LENGTH 4 +#define ADDR_TABLE_FUNC1_E_OFFSET 0 +#define ADDR_TABLE_FUNC1_NR_E 1 + +#define SA_DROP_EN +#define ADDR_TABLE_FUNC1_SA_DROP_EN_BOFFSET 30 +#define ADDR_TABLE_FUNC1_SA_DROP_EN_BLEN 1 +#define ADDR_TABLE_FUNC1_SA_DROP_EN_FLAG HSL_RW + +#define MIRROR_EN +#define ADDR_TABLE_FUNC1_MIRROR_EN_BOFFSET 29 +#define ADDR_TABLE_FUNC1_MIRROR_EN_BLEN 1 +#define ADDR_TABLE_FUNC1_MIRROR_EN_FLAG HSL_RW + +#define AT_PRI_EN +#define ADDR_TABLE_FUNC1_AT_PRI_EN_BOFFSET 28 +#define ADDR_TABLE_FUNC1_AT_PRI_EN_BLEN 1 +#define ADDR_TABLE_FUNC1_AT_PRI_EN_FLAG HSL_RW + +#define AT_SVL_EN +#define ADDR_TABLE_FUNC1_AT_SVL_EN_BOFFSET 27 +#define ADDR_TABLE_FUNC1_AT_SVL_EN_BLEN 1 +#define ADDR_TABLE_FUNC1_AT_SVL_EN_FLAG HSL_RW + +#define AT_PRI +#define ADDR_TABLE_FUNC1_AT_PRI_BOFFSET 24 +#define ADDR_TABLE_FUNC1_AT_PRI_BLEN 3 +#define ADDR_TABLE_FUNC1_AT_PRI_FLAG HSL_RW + +#define CROSS_PT +#define ADDR_TABLE_FUNC1_CROSS_PT_BOFFSET 23 +#define ADDR_TABLE_FUNC1_CROSS_PT_BLEN 1 +#define ADDR_TABLE_FUNC1_CROSS_PT_FLAG HSL_RW + +#define DES_PORT +#define ADDR_TABLE_FUNC1_DES_PORT_BOFFSET 16 +#define ADDR_TABLE_FUNC1_DES_PORT_BLEN 7 +#define ADDR_TABLE_FUNC1_DES_PORT_FLAG HSL_RW + +#define AT_ADDR_BYTE0 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE0_BOFFSET 8 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE0_BLEN 8 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE0_FLAG HSL_RW + +#define AT_ADDR_BYTE1 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE1_BOFFSET 0 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE1_BLEN 8 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE1_FLAG HSL_RW + + /* Address Table Function2 Register */ +#define ADDR_TABLE_FUNC2 +#define ADDR_TABLE_FUNC2_OFFSET 0x0608 +#define ADDR_TABLE_FUNC2_E_LENGTH 4 +#define ADDR_TABLE_FUNC2_E_OFFSET 0 +#define ADDR_TABLE_FUNC2_NR_E 1 + + +#define LOAD_BALANCE_EN +#define ADDR_TABLE_FUNC2_LOAD_BALANCE_EN_BOFFSET 23 +#define ADDR_TABLE_FUNC2_LOAD_BALANCE_EN_BLEN 1 +#define ADDR_TABLE_FUNC2_LOAD_BALANCE_EN_FLAG HSL_RW + +#define LOAD_BALANCE +#define ADDR_TABLE_FUNC2_LOAD_BALANCE_BOFFSET 21 +#define ADDR_TABLE_FUNC2_LOAD_BALANCE_BLEN 2 +#define ADDR_TABLE_FUNC2_LOAD_BALANCE_FLAG HSL_RW + +#define WL_EN +#define ADDR_TABLE_FUNC2_WL_EN_BOFFSET 20 +#define ADDR_TABLE_FUNC2_WL_EN_BLEN 1 +#define ADDR_TABLE_FUNC2_WL_EN_FLAG HSL_RW + +#define AT_VID +#define ADDR_TABLE_FUNC2_AT_VID_BOFFSET 8 +#define ADDR_TABLE_FUNC2_AT_VID_BLEN 12 +#define ADDR_TABLE_FUNC2_AT_VID_FLAG HSL_RW + +#define SHORT_LOOP +#define ADDR_TABLE_FUNC2_SHORT_LOOP_BOFFSET 7 +#define ADDR_TABLE_FUNC2_SHORT_LOOP_BLEN 1 +#define ADDR_TABLE_FUNC2_SHORT_LOOP_FLAG HSL_RW + +#define COPY_TO_CPU +#define ADDR_TABLE_FUNC2_COPY_TO_CPU_BOFFSET 6 +#define ADDR_TABLE_FUNC2_COPY_TO_CPU_BLEN 1 +#define ADDR_TABLE_FUNC2_COPY_TO_CPU_FLAG HSL_RW + +#define REDRCT_TO_CPU +#define ADDR_TABLE_FUNC2_REDRCT_TO_CPU_BOFFSET 5 +#define ADDR_TABLE_FUNC2_REDRCT_TO_CPU_BLEN 1 +#define ADDR_TABLE_FUNC2_REDRCT_TO_CPU_FLAG HSL_RW + +#define LEAKY_EN +#define ADDR_TABLE_FUNC2_LEAKY_EN_BOFFSET 4 +#define ADDR_TABLE_FUNC2_LEAKY_EN_BLEN 1 +#define ADDR_TABLE_FUNC2_LEAKY_EN_FLAG HSL_RW + +#define AT_STATUS +#define ADDR_TABLE_FUNC2_AT_STATUS_BOFFSET 0 +#define ADDR_TABLE_FUNC2_AT_STATUS_BLEN 4 +#define ADDR_TABLE_FUNC2_AT_STATUS_FLAG HSL_RW + + /* Address Table Function3 Register */ +#define ADDR_TABLE_FUNC3 +#define ADDR_TABLE_FUNC3_OFFSET 0x060c +#define ADDR_TABLE_FUNC3_E_LENGTH 4 +#define ADDR_TABLE_FUNC3_E_OFFSET 0 +#define ADDR_TABLE_FUNC3_NR_E 1 + +#define AT_BUSY +#define ADDR_TABLE_FUNC3_AT_BUSY_BOFFSET 31 +#define ADDR_TABLE_FUNC3_AT_BUSY_BLEN 1 +#define ADDR_TABLE_FUNC3_AT_BUSY_FLAG HSL_RW + +#define NEW_PORT_NUM +#define ADDR_TABLE_FUNC3_NEW_PORT_NUM_BOFFSET 22 +#define ADDR_TABLE_FUNC3_NEW_PORT_NUM_BLEN 3 +#define ADDR_TABLE_FUNC3_NEW_PORT_NUM_FLAG HSL_RW + +#define AT_INDEX +#define ADDR_TABLE_FUNC3_AT_INDEX_BOFFSET 16 +#define ADDR_TABLE_FUNC3_AT_INDEX_BLEN 5 +#define ADDR_TABLE_FUNC3_AT_INDEX_FLAG HSL_RW + +#define AT_VID_EN +#define ADDR_TABLE_FUNC3_AT_VID_EN_BOFFSET 15 +#define ADDR_TABLE_FUNC3_AT_VID_EN_BLEN 1 +#define ADDR_TABLE_FUNC3_AT_VID_EN_FLAG HSL_RW + +#define AT_PORT_EN +#define ADDR_TABLE_FUNC3_AT_PORT_EN_BOFFSET 14 +#define ADDR_TABLE_FUNC3_AT_PORT_EN_BLEN 1 +#define ADDR_TABLE_FUNC3_AT_PORT_EN_FLAG HSL_RW + +#define AT_MULTI_EN +#define ADDR_TABLE_FUNC3_AT_MULTI_EN_BOFFSET 13 +#define ADDR_TABLE_FUNC3_AT_MULTI_EN_BLEN 1 +#define ADDR_TABLE_FUNC3_AT_MULTI_EN_FLAG HSL_RW + +#define AT_FULL_VIO +#define ADDR_TABLE_FUNC3_AT_FULL_VIO_BOFFSET 12 +#define ADDR_TABLE_FUNC3_AT_FULL_VIO_BLEN 1 +#define ADDR_TABLE_FUNC3_AT_FULL_VIO_FLAG HSL_RW + +#define AT_PORT_NUM +#define ADDR_TABLE_FUNC3_AT_PORT_NUM_BOFFSET 8 +#define ADDR_TABLE_FUNC3_AT_PORT_NUM_BLEN 4 +#define ADDR_TABLE_FUNC3_AT_PORT_NUM_FLAG HSL_RW + +#define FLUSH_ST_EN +#define ADDR_TABLE_FUNC3_FLUSH_ST_EN_BOFFSET 4 +#define ADDR_TABLE_FUNC3_FLUSH_ST_EN_BLEN 1 +#define ADDR_TABLE_FUNC3_FLUSH_ST_EN_FLAG HSL_RW + +#define AT_FUNC +#define ADDR_TABLE_FUNC3_AT_FUNC_BOFFSET 0 +#define ADDR_TABLE_FUNC3_AT_FUNC_BLEN 4 +#define ADDR_TABLE_FUNC3_AT_FUNC_FLAG HSL_RW + + + + + /* Reserve Address Table0 Register */ +#define RESV_ADDR_TBL0 +#define RESV_ADDR_TBL0_OFFSET 0x3c000 +#define RESV_ADDR_TBL0_E_LENGTH 4 +#define RESV_ADDR_TBL0_E_OFFSET 0 +#define RESV_ADDR_TBL0_NR_E 1 + +#define RESV_ADDR_BYTE2 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE2_BOFFSET 24 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE2_BLEN 8 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE2_FLAG HSL_RW + +#define RESV_ADDR_BYTE3 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE3_BOFFSET 16 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE3_BLEN 8 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE3_FLAG HSL_RW + +#define RESV_ADDR_BYTE4 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE4_BOFFSET 8 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE4_BLEN 8 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE4_FLAG HSL_RW + +#define RESV_ADDR_BYTE5 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE5_BOFFSET 0 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE5_BLEN 8 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE5_FLAG HSL_RW + + /* Reserve Address Table1 Register */ +#define RESV_ADDR_TBL1 +#define RESV_ADDR_TBL1_OFFSET 0x3c004 +#define RESV_ADDR_TBL1_E_LENGTH 4 +#define RESV_ADDR_TBL1_E_OFFSET 0 +#define RESV_ADDR_TBL1_NR_E 1 + +#define RESV_COPY_TO_CPU +#define RESV_ADDR_TBL1_RESV_COPY_TO_CPU_BOFFSET 31 +#define RESV_ADDR_TBL1_RESV_COPY_TO_CPU_BLEN 1 +#define RESV_ADDR_TBL1_RESV_COPY_TO_CPU_FLAG HSL_RW + +#define RESV_REDRCT_TO_CPU +#define RESV_ADDR_TBL1_RESV_REDRCT_TO_CPU_BOFFSET 30 +#define RESV_ADDR_TBL1_RESV_REDRCT_TO_CPU_BLEN 1 +#define RESV_ADDR_TBL1_RESV_REDRCT_TO_CPU_FLAG HSL_RW + +#define RESV_LEAKY_EN +#define RESV_ADDR_TBL1_RESV_LEAKY_EN_BOFFSET 29 +#define RESV_ADDR_TBL1_RESV_LEAKY_EN_BLEN 1 +#define RESV_ADDR_TBL1_RESV_LEAKY_EN_FLAG HSL_RW + +#define RESV_MIRROR_EN +#define RESV_ADDR_TBL1_RESV_MIRROR_EN_BOFFSET 28 +#define RESV_ADDR_TBL1_RESV_MIRROR_EN_BLEN 1 +#define RESV_ADDR_TBL1_RESV_MIRROR_EN_FLAG HSL_RW + +#define RESV_PRI_EN +#define RESV_ADDR_TBL1_RESV_PRI_EN_BOFFSET 27 +#define RESV_ADDR_TBL1_RESV_PRI_EN_BLEN 1 +#define RESV_ADDR_TBL1_RESV_PRI_EN_FLAG HSL_RW + +#define RESV_PRI +#define RESV_ADDR_TBL1_RESV_PRI_BOFFSET 24 +#define RESV_ADDR_TBL1_RESV_PRI_BLEN 3 +#define RESV_ADDR_TBL1_RESV_PRI_FLAG HSL_RW + +#define RESV_CROSS_PT +#define RESV_ADDR_TBL1_RESV_CROSS_PT_BOFFSET 23 +#define RESV_ADDR_TBL1_RESV_CROSS_PT_BLEN 1 +#define RESV_ADDR_TBL1_RESV_CROSS_PT_FLAG HSL_RW + +#define RESV_DES_PORT +#define RESV_ADDR_TBL1_RESV_DES_PORT_BOFFSET 16 +#define RESV_ADDR_TBL1_RESV_DES_PORT_BLEN 7 +#define RESV_ADDR_TBL1_RESV_DES_PORT_FLAG HSL_RW + +#define RESV_ADDR_BYTE0 +#define RESV_ADDR_TBL1_RESV_ADDR_BYTE0_BOFFSET 8 +#define RESV_ADDR_TBL1_RESV_ADDR_BYTE0_BLEN 8 +#define RESV_ADDR_TBL1_RESV_ADDR_BYTE0_FLAG HSL_RW + +#define RESV_ADDR_BYTE1 +#define RESV_ADDR_TBL1_RESV_ADDR_BYTE1_BOFFSET 0 +#define RESV_ADDR_TBL1_RESV_ADDR_BYTE1_BLEN 8 +#define RESV_ADDR_TBL1_RESV_ADDR_BYTE1_FLAG HSL_RW + + /* Reserve Address Table2 Register */ +#define RESV_ADDR_TBL2 +#define RESV_ADDR_TBL2_OFFSET 0x3c008 +#define RESV_ADDR_TBL2_E_LENGTH 4 +#define RESV_ADDR_TBL2_E_OFFSET 0 +#define RESV_ADDR_TBL2_NR_E 1 + +#define RESV_STATUS +#define RESV_ADDR_TBL2_RESV_STATUS_BOFFSET 0 +#define RESV_ADDR_TBL2_RESV_STATUS_BLEN 1 +#define RESV_ADDR_TBL2_RESV_STATUS_FLAG HSL_RW + + + + + /* Address Table Control Register */ +#define ADDR_TABLE_CTL +#define ADDR_TABLE_CTL_OFFSET 0x0618 +#define ADDR_TABLE_CTL_E_LENGTH 4 +#define ADDR_TABLE_CTL_E_OFFSET 0 +#define ADDR_TABLE_CTL_NR_E 1 + +#define ARL_INI_EN +#define ADDR_TABLE_CTL_ARL_INI_EN_BOFFSET 31 +#define ADDR_TABLE_CTL_ARL_INI_EN_BLEN 1 +#define ADDR_TABLE_CTL_ARL_INI_EN_FLAG HSL_RW + +#define LEARN_CHANGE_EN +#define ADDR_TABLE_CTL_LEARN_CHANGE_EN_BOFFSET 30 +#define ADDR_TABLE_CTL_LEARN_CHANGE_EN_BLEN 1 +#define ADDR_TABLE_CTL_LEARN_CHANGE_EN_FLAG HSL_RW + +#define IGMP_JOIN_LEAKY +#define ADDR_TABLE_CTL_IGMP_JOIN_LEAKY_BOFFSET 29 +#define ADDR_TABLE_CTL_IGMP_JOIN_LEAKY_BLEN 1 +#define ADDR_TABLE_CTL_IGMP_JOIN_LEAKY_FLAG HSL_RW + +#define IGMP_CREAT_EN +#define ADDR_TABLE_CTL_IGMP_CREAT_EN_BOFFSET 28 +#define ADDR_TABLE_CTL_IGMP_CREAT_EN_BLEN 1 +#define ADDR_TABLE_CTL_IGMP_CREAT_EN_FLAG HSL_RW + +#define IGMP_PRI_EN +#define ADDR_TABLE_CTL_IGMP_PRI_EN_BOFFSET 27 +#define ADDR_TABLE_CTL_IGMP_PRI_EN_BLEN 1 +#define ADDR_TABLE_CTL_IGMP_PRI_EN_FLAG HSL_RW + +#define IGMP_PRI +#define ADDR_TABLE_CTL_IGMP_PRI_BOFFSET 24 +#define ADDR_TABLE_CTL_IGMP_PRI_BLEN 3 +#define ADDR_TABLE_CTL_IGMP_PRI_FLAG HSL_RW + +#define IGMP_JOIN_STATIC +#define ADDR_TABLE_CTL_IGMP_JOIN_STATIC_BOFFSET 20 +#define ADDR_TABLE_CTL_IGMP_JOIN_STATIC_BLEN 4 +#define ADDR_TABLE_CTL_IGMP_JOIN_STATIC_FLAG HSL_RW + +#define AGE_EN +#define ADDR_TABLE_CTL_AGE_EN_BOFFSET 19 +#define ADDR_TABLE_CTL_AGE_EN_BLEN 1 +#define ADDR_TABLE_CTL_AGE_EN_FLAG HSL_RW + +#define LOOP_CHECK_TIMER +#define ADDR_TABLE_CTL_LOOP_CHECK_TIMER_BOFFSET 16 +#define ADDR_TABLE_CTL_LOOP_CHECK_TIMER_BLEN 3 +#define ADDR_TABLE_CTL_LOOP_CHECK_TIMER_FLAG HSL_RW + +#define AGE_TIME +#define ADDR_TABLE_CTL_AGE_TIME_BOFFSET 0 +#define ADDR_TABLE_CTL_AGE_TIME_BLEN 16 +#define ADDR_TABLE_CTL_AGE_TIME_FLAG HSL_RW + + + + + /* Global Forward Control0 Register */ +#define FORWARD_CTL0 +#define FORWARD_CTL0_OFFSET 0x0620 +#define FORWARD_CTL0_E_LENGTH 4 +#define FORWARD_CTL0_E_OFFSET 0 +#define FORWARD_CTL0_NR_E 1 + +#define ARP_CMD +#define FORWARD_CTL0_ARP_CMD_BOFFSET 26 +#define FORWARD_CTL0_ARP_CMD_BLEN 2 +#define FORWARD_CTL0_ARP_CMD_FLAG HSL_RW + +#define IP_NOT_FOUND +#define FORWARD_CTL0_IP_NOT_FOUND_BOFFSET 24 +#define FORWARD_CTL0_IP_NOT_FOUND_BLEN 2 +#define FORWARD_CTL0_IP_NOT_FOUND_FLAG HSL_RW + +#define ARP_NOT_FOUND +#define FORWARD_CTL0_ARP_NOT_FOUND_BOFFSET 22 +#define FORWARD_CTL0_ARP_NOT_FOUND_BLEN 2 +#define FORWARD_CTL0_ARP_NOT_FOUND_FLAG HSL_RW + +#define HASH_MODE +#define FORWARD_CTL0_HASH_MODE_BOFFSET 20 +#define FORWARD_CTL0_HASH_MODE_BLEN 2 +#define FORWARD_CTL0_HASH_MODE_FLAG HSL_RW + +#define NAT_NOT_FOUND_DROP +#define FORWARD_CTL0_NAT_NOT_FOUND_DROP_BOFFSET 17 +#define FORWARD_CTL0_NAT_NOT_FOUND_DROP_BLEN 1 +#define FORWARD_CTL0_NAT_NOT_FOUND_DROP_FLAG HSL_RW + +#define SP_NOT_FOUND_DROP +#define FORWARD_CTL0_SP_NOT_FOUND_DROP_BOFFSET 16 +#define FORWARD_CTL0_SP_NOT_FOUND_DROP_BLEN 1 +#define FORWARD_CTL0_SP_NOT_FOUND_DROP_FLAG HSL_RW + +#define IGMP_LEAVE_DROP +#define FORWARD_CTL0_IGMP_LEAVE_DROP_BOFFSET 14 +#define FORWARD_CTL0_IGMP_LEAVE_DROP_BLEN 1 +#define FORWARD_CTL0_IGMP_LEAVE_DROP_FLAG HSL_RW + +#define ARL_UNI_LEAKY +#define FORWARD_CTL0_ARL_UNI_LEAKY_BOFFSET 13 +#define FORWARD_CTL0_ARL_UNI_LEAKY_BLEN 1 +#define FORWARD_CTL0_ARL_UNI_LEAKY_FLAG HSL_RW + +#define ARL_MUL_LEAKY +#define FORWARD_CTL0_ARL_MUL_LEAKY_BOFFSET 12 +#define FORWARD_CTL0_ARL_MUL_LEAKY_BLEN 1 +#define FORWARD_CTL0_ARL_MUL_LEAKY_FLAG HSL_RW + +#define MANAGE_VID_VIO_DROP_EN +#define FORWARD_CTL0_MANAGE_VID_VIO_DROP_EN_BOFFSET 11 +#define FORWARD_CTL0_MANAGE_VID_VIO_DROP_EN_BLEN 1 +#define FORWARD_CTL0_MANAGE_VID_VIO_DROP_EN_FLAG HSL_RW + +#define CPU_PORT_EN +#define FORWARD_CTL0_CPU_PORT_EN_BOFFSET 10 +#define FORWARD_CTL0_CPU_PORT_EN_BLEN 1 +#define FORWARD_CTL0_CPU_PORT_EN_FLAG HSL_RW + +#define PPPOE_RDT_EN +#define FORWARD_CTL0_PPPOE_RDT_EN_BOFFSET 8 +#define FORWARD_CTL0_PPPOE_RDT_EN_BLEN 1 +#define FORWARD_CTL0_PPPOE_RDT_EN_FLAG HSL_RW + +#define MIRROR_PORT_NUM +#define FORWARD_CTL0_MIRROR_PORT_NUM_BOFFSET 4 +#define FORWARD_CTL0_MIRROR_PORT_NUM_BLEN 4 +#define FORWARD_CTL0_MIRROR_PORT_NUM_FLAG HSL_RW + +#define IGMP_COPY_EN +#define FORWARD_CTL0_IGMP_COPY_EN_BOFFSET 3 +#define FORWARD_CTL0_IGMP_COPY_EN_BLEN 1 +#define FORWARD_CTL0_IGMP_COPY_EN_FLAG HSL_RW + +#define RIP_CPY_EN +#define FORWARD_CTL0_RIP_CPY_EN_BOFFSET 2 +#define FORWARD_CTL0_RIP_CPY_EN_BLEN 1 +#define FORWARD_CTL0_RIP_CPY_EN_FLAG HSL_RW + +#define EAPOL_CMD +#define FORWARD_CTL0_EAPOL_CMD_BOFFSET 0 +#define FORWARD_CTL0_EAPOL_CMD_BLEN 1 +#define FORWARD_CTL0_EAPOL_CMD_FLAG HSL_RW + + /* Global Forward Control1 Register */ +#define FORWARD_CTL1 +#define FORWARD_CTL1_OFFSET 0x0624 +#define FORWARD_CTL1_E_LENGTH 4 +#define FORWARD_CTL1_E_OFFSET 0 +#define FORWARD_CTL1_NR_E 1 + +#define IGMP_DP +#define FORWARD_CTL1_IGMP_DP_BOFFSET 24 +#define FORWARD_CTL1_IGMP_DP_BLEN 7 +#define FORWARD_CTL1_IGMP_DP_FLAG HSL_RW + +#define BC_FLOOD_DP +#define FORWARD_CTL1_BC_FLOOD_DP_BOFFSET 16 +#define FORWARD_CTL1_BC_FLOOD_DP_BLEN 7 +#define FORWARD_CTL1_BC_FLOOD_DP_FLAG HSL_RW + +#define MUL_FLOOD_DP +#define FORWARD_CTL1_MUL_FLOOD_DP_BOFFSET 8 +#define FORWARD_CTL1_MUL_FLOOD_DP_BLEN 7 +#define FORWARD_CTL1_MUL_FLOOD_DP_FLAG HSL_RW + +#define UNI_FLOOD_DP +#define FORWARD_CTL1_UNI_FLOOD_DP_BOFFSET 0 +#define FORWARD_CTL1_UNI_FLOOD_DP_BLEN 7 +#define FORWARD_CTL1_UNI_FLOOD_DP_FLAG HSL_RW + + + + + /* Global Learn Limit Ctl Register */ +#define GLOBAL_LEARN_LIMIT_CTL +#define GLOBAL_LEARN_LIMIT_CTL_OFFSET 0x0628 +#define GLOBAL_LEARN_LIMIT_CTL_E_LENGTH 4 +#define GLOBAL_LEARN_LIMIT_CTL_E_OFFSET 0 +#define GLOBAL_LEARN_LIMIT_CTL_NR_E 1 + +#define GOL_SA_LEARN_LIMIT_EN +#define GLOBAL_LEARN_LIMIT_CTL_GOL_SA_LEARN_LIMIT_EN_BOFFSET 12 +#define GLOBAL_LEARN_LIMIT_CTL_GOL_SA_LEARN_LIMIT_EN_BLEN 1 +#define GLOBAL_LEARN_LIMIT_CTL_GOL_SA_LEARN_LIMIT_EN_FLAG HSL_RW + +#define GOL_SA_LEARN_LIMIT_DROP_EN +#define GLOBAL_LEARN_LIMIT_CTL_GOL_SA_LEARN_LIMIT_DROP_EN_BOFFSET 13 +#define GLOBAL_LEARN_LIMIT_CTL_GOL_SA_LEARN_LIMIT_DROP_EN_BLEN 1 +#define GLOBAL_LEARN_LIMIT_CTL_GOL_SA_LEARN_LIMIT_DROP_EN_FLAG HSL_RW + +#define GOL_SA_LEARN_CNT +#define GLOBAL_LEARN_LIMIT_CTL_GOL_SA_LEARN_CNT_BOFFSET 0 +#define GLOBAL_LEARN_LIMIT_CTL_GOL_SA_LEARN_CNT_BLEN 12 +#define GLOBAL_LEARN_LIMIT_CTL_GOL_SA_LEARN_CNT_FLAG HSL_RW + + + + + /* DSCP To Priority Register */ +#define DSCP_TO_PRI +#define DSCP_TO_PRI_OFFSET 0x0630 +#define DSCP_TO_PRI_E_LENGTH 4 +#define DSCP_TO_PRI_E_OFFSET 0x0004 +#define DSCP_TO_PRI_NR_E 8 + + + + + /* UP To Priority Register */ +#define UP_TO_PRI +#define UP_TO_PRI_OFFSET 0x0650 +#define UP_TO_PRI_E_LENGTH 4 +#define UP_TO_PRI_E_OFFSET 0x0004 +#define UP_TO_PRI_NR_E 1 + + + + + /* WAN DSCP To Priority Register */ +#define DSCP_TO_EHPRI +#define DSCP_TO_EHPRI_OFFSET 0x0730 +#define DSCP_TO_EHPRI_E_LENGTH 4 +#define DSCP_TO_EHPRI_E_OFFSET 0x0004 +#define DSCP_TO_EHPRI_NR_E 8 + + + + + /* WAN UP To Priority Register */ +#define UP_TO_EHPRI +#define UP_TO_EHPRI_OFFSET 0x0750 +#define UP_TO_EHPRI_E_LENGTH 4 +#define UP_TO_EHPRI_E_OFFSET 0x0004 +#define UP_TO_EHPRI_NR_E 1 + + + + + /* Port Lookup control Register */ +#define PORT_LOOKUP_CTL +#define PORT_LOOKUP_CTL_OFFSET 0x0660 +#define PORT_LOOKUP_CTL_E_LENGTH 4 +#define PORT_LOOKUP_CTL_E_OFFSET 0x000c +#define PORT_LOOKUP_CTL_NR_E 7 + +#define MULTI_DROP_EN +#define PORT_LOOKUP_CTL_MULTI_DROP_EN_BOFFSET 31 +#define PORT_LOOKUP_CTL_MULTI_DROP_EN_BLEN 1 +#define PORT_LOOKUP_CTL_MULTI_DROP_EN_FLAG HSL_RW + +#define UNI_LEAKY_EN +#define PORT_LOOKUP_CTL_UNI_LEAKY_EN_BOFFSET 28 +#define PORT_LOOKUP_CTL_UNI_LEAKY_EN_BLEN 1 +#define PORT_LOOKUP_CTL_UNI_LEAKY_EN_FLAG HSL_RW + +#define MUL_LEAKY_EN +#define PORT_LOOKUP_CTL_MUL_LEAKY_EN_BOFFSET 27 +#define PORT_LOOKUP_CTL_MUL_LEAKY_EN_BLEN 1 +#define PORT_LOOKUP_CTL_MUL_LEAKY_EN_FLAG HSL_RW + +#define ARP_LEAKY_EN +#define PORT_LOOKUP_CTL_ARP_LEAKY_EN_BOFFSET 26 +#define PORT_LOOKUP_CTL_ARP_LEAKY_EN_BLEN 1 +#define PORT_LOOKUP_CTL_ARP_LEAKY_EN_FLAG HSL_RW + +#define ING_MIRROR_EN +#define PORT_LOOKUP_CTL_ING_MIRROR_EN_BOFFSET 25 +#define PORT_LOOKUP_CTL_ING_MIRROR_EN_BLEN 1 +#define PORT_LOOKUP_CTL_ING_MIRROR_EN_FLAG HSL_RW + +#define PORT_LOOP_BACK +#define PORT_LOOKUP_CTL_PORT_LOOP_BACK_BOFFSET 21 +#define PORT_LOOKUP_CTL_PORT_LOOP_BACK_BLEN 1 +#define PORT_LOOKUP_CTL_PORT_LOOP_BACK_FLAG HSL_RW + +#define LEARN_EN +#define PORT_LOOKUP_CTL_LEARN_EN_BOFFSET 20 +#define PORT_LOOKUP_CTL_LEARN_EN_BLEN 1 +#define PORT_LOOKUP_CTL_LEARN_EN_FLAG HSL_RW + +#define PORT_STATE +#define PORT_LOOKUP_CTL_PORT_STATE_BOFFSET 16 +#define PORT_LOOKUP_CTL_PORT_STATE_BLEN 3 +#define PORT_LOOKUP_CTL_PORT_STATE_FLAG HSL_RW + +#define FORCE_PVLAN +#define PORT_LOOKUP_CTL_FORCE_PVLAN_BOFFSET 10 +#define PORT_LOOKUP_CTL_FORCE_PVLAN_BLEN 1 +#define PORT_LOOKUP_CTL_FORCE_PVLAN_FLAG HSL_RW + +#define DOT1Q_MODE +#define PORT_LOOKUP_CTL_DOT1Q_MODE_BOFFSET 8 +#define PORT_LOOKUP_CTL_DOT1Q_MODE_BLEN 2 +#define PORT_LOOKUP_CTL_DOT1Q_MODE_FLAG HSL_RW + +#define PORT_VID_MEM +#define PORT_LOOKUP_CTL_PORT_VID_MEM_BOFFSET 0 +#define PORT_LOOKUP_CTL_PORT_VID_MEM_BLEN 7 +#define PORT_LOOKUP_CTL_PORT_VID_MEM_FLAG HSL_RW + + + + + /* Priority Control Register */ +#define PRI_CTL +#define PRI_CTL_OFFSET 0x0664 +#define PRI_CTL_E_LENGTH 4 +#define PRI_CTL_E_OFFSET 0x000c +#define PRI_CTL_NR_E 7 + +#define EG_MAC_BASE_VLAN_EN +#define PRI_CTL_EG_MAC_BASE_VLAN_EN_BOFFSET 20 +#define PRI_CTL_EG_MAC_BASE_VLAN_EN_BLEN 1 +#define PRI_CTL_EG_MAC_BASE_VLAN_EN_FLAG HSL_RW + +#define FLOW_PRI_EN +#define PRI_CTL_FLOW_PRI_EN_BOFFSET 19 +#define PRI_CTL_FLOW_PRI_EN_BLEN 1 +#define PRI_CTL_FLOW_PRI_EN_FLAG HSL_RW + +#define DA_PRI_EN +#define PRI_CTL_DA_PRI_EN_BOFFSET 18 +#define PRI_CTL_DA_PRI_EN_BLEN 1 +#define PRI_CTL_DA_PRI_EN_FLAG HSL_RW + +#define VLAN_PRI_EN +#define PRI_CTL_VLAN_PRI_EN_BOFFSET 17 +#define PRI_CTL_VLAN_PRI_EN_BLEN 1 +#define PRI_CTL_VLAN_PRI_EN_FLAG HSL_RW + +#define IP_PRI_EN +#define PRI_CTL_IP_PRI_EN_BOFFSET 16 +#define PRI_CTL_IP_PRI_EN_BLEN 1 +#define PRI_CTL_IP_PRI_EN_FLAG HSL_RW + +#define FLOW_PRI_SEL +#define PRI_CTL_FLOW_PRI_SEL_BOFFSET 8 +#define PRI_CTL_FLOW_PRI_SEL_BLEN 2 +#define PRI_CTL_FLOW_PRI_SEL_FLAG HSL_RW + +#define DA_PRI_SEL +#define PRI_CTL_DA_PRI_SEL_BOFFSET 6 +#define PRI_CTL_DA_PRI_SEL_BLEN 2 +#define PRI_CTL_DA_PRI_SEL_FLAG HSL_RW + +#define VLAN_PRI_SEL +#define PRI_CTL_VLAN_PRI_SEL_BOFFSET 4 +#define PRI_CTL_VLAN_PRI_SEL_BLEN 2 +#define PRI_CTL_VLAN_PRI_SEL_FLAG HSL_RW + +#define IP_PRI_SEL +#define PRI_CTL_IP_PRI_SEL_BOFFSET 2 +#define PRI_CTL_IP_PRI_SEL_BLEN 2 +#define PRI_CTL_IP_PRI_SEL_FLAG HSL_RW + + + + /* Port Learn Limit Ctl Register */ +#define PORT_LEARN_LIMIT_CTL +#define PORT_LEARN_LIMIT_CTL_OFFSET 0x0668 +#define PORT_LEARN_LIMIT_CTL_E_LENGTH 4 +#define PORT_LEARN_LIMIT_CTL_E_OFFSET 0x000c +#define PORT_LEARN_LIMIT_CTL_NR_E 7 + +#define IGMP_JOIN_LIMIT_DROP_EN +#define PORT_LEARN_LIMIT_CTL_IGMP_JOIN_LIMIT_DROP_EN_BOFFSET 29 +#define PORT_LEARN_LIMIT_CTL_IGMP_JOIN_LIMIT_DROP_EN_BLEN 1 +#define PORT_LEARN_LIMIT_CTL_IGMP_JOIN_LIMIT_DROP_EN_FLAG HSL_RW + +#define SA_LEARN_LIMIT_DROP_EN +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_LIMIT_DROP_EN_BOFFSET 28 +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_LIMIT_DROP_EN_BLEN 1 +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_LIMIT_DROP_EN_FLAG HSL_RW + +#define IGMP_JOIN_LIMIT_EN +#define PORT_LEARN_LIMIT_CTL_IGMP_JOIN_LIMIT_EN_BOFFSET 27 +#define PORT_LEARN_LIMIT_CTL_IGMP_JOIN_LIMIT_EN_BLEN 1 +#define PORT_LEARN_LIMIT_CTL_IGMP_JOIN_LIMIT_EN_FLAG HSL_RW + +#define IGMP_JOIN_CNT +#define PORT_LEARN_LIMIT_CTL_IGMP_JOIN_CNT_BOFFSET 16 +#define PORT_LEARN_LIMIT_CTL_IGMP_JOIN_CNT_BLEN 11 +#define PORT_LEARN_LIMIT_CTL_IGMP_JOIN_CNT_FLAG HSL_RW + +#define SA_LEARN_STATUS +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_STATUS_BOFFSET 12 +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_STATUS_BLEN 4 +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_STATUS_FLAG HSL_RW + +#define SA_LEARN_LIMIT_EN +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_LIMIT_EN_BOFFSET 11 +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_LIMIT_EN_BLEN 1 +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_LIMIT_EN_FLAG HSL_RW + +#define SA_LEARN_CNT +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_CNT_BOFFSET 0 +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_CNT_BLEN 11 +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_CNT_FLAG HSL_RW + + + + /* Global Trunk Ctl0 Register */ +#define GOL_TRUNK_CTL0 +#define GOL_TRUNK_CTL0_OFFSET 0x0700 +#define GOL_TRUNK_CTL0_E_LENGTH 4 +#define GOL_TRUNK_CTL0_E_OFFSET 0x4 +#define GOL_TRUNK_CTL0_NR_E 1 + + + /* Global Trunk Ctl1 Register */ +#define GOL_TRUNK_CTL1 +#define GOL_TRUNK_CTL1_OFFSET 0x0704 +#define GOL_TRUNK_CTL1_E_LENGTH 4 +#define GOL_TRUNK_CTL1_E_OFFSET 0x4 +#define GOL_TRUNK_CTL1_NR_E 2 + + + /* ACL Forward source filter Register */ +#define ACL_FWD_SRC_FILTER_CTL0 +#define ACL_FWD_SRC_FILTER_CTL0_OFFSET 0x0710 +#define ACL_FWD_SRC_FILTER_CTL0_E_LENGTH 4 +#define ACL_FWD_SRC_FILTER_CTL0_E_OFFSET 0x4 +#define ACL_FWD_SRC_FILTER_CTL0_NR_E 3 + + + /* VLAN translation register */ +#define VLAN_TRANS +#define VLAN_TRANS_OFFSET 0x0418 +#define VLAN_TRANS_E_LENGTH 4 +#define VLAN_TRANS_E_OFFSET 0 +#define VLAN_TRANS_NR_E 7 + +#define EG_FLTR_BYPASS_EN +#define VLAN_TRANS_EG_FLTR_BYPASS_EN_BOFFSET 1 +#define VLAN_TRANS_EG_FLTR_BYPASS_EN_BLEN 1 +#define VLAN_TRANS_EG_FLTR_BYPASS_EN_FLAG HSL_RW + +#define NET_ISO +#define VLAN_TRANS_NET_ISO_BOFFSET 0 +#define VLAN_TRANS_NET_ISO_BLEN 1 +#define VLAN_TRANS_NET_ISO_FLAG HSL_RW + + + /* Port vlan0 Register */ +#define PORT_VLAN0 +#define PORT_VLAN0_OFFSET 0x0420 +#define PORT_VLAN0_E_LENGTH 4 +#define PORT_VLAN0_E_OFFSET 0x0008 +#define PORT_VLAN0_NR_E 7 + +#define ING_CPRI +#define PORT_VLAN0_ING_CPRI_BOFFSET 29 +#define PORT_VLAN0_ING_CPRI_BLEN 3 +#define PORT_VLAN0_ING_CPRI_FLAG HSL_RW + +#define ING_FORCE_CPRI +#define PORT_VLAN0_ING_FORCE_CPRI_BOFFSET 28 +#define PORT_VLAN0_ING_FORCE_CPRI_BLEN 1 +#define PORT_VLAN0_ING_FORCE_CPRI_FLAG HSL_RW + +#define DEF_CVID +#define PORT_VLAN0_DEF_CVID_BOFFSET 16 +#define PORT_VLAN0_DEF_CVID_BLEN 12 +#define PORT_VLAN0_DEF_CVID_FLAG HSL_RW + +#define ING_SPRI +#define PORT_VLAN0_ING_SPRI_BOFFSET 13 +#define PORT_VLAN0_ING_SPRI_BLEN 3 +#define PORT_VLAN0_ING_SPRI_FLAG HSL_RW + +#define ING_FORCE_SPRI +#define PORT_VLAN0_ING_FORCE_SPRI_BOFFSET 12 +#define PORT_VLAN0_ING_FORCE_SPRI_BLEN 1 +#define PORT_VLAN0_ING_FORCE_SPRI_FLAG HSL_RW + +#define DEF_SVID +#define PORT_VLAN0_DEF_SVID_BOFFSET 0 +#define PORT_VLAN0_DEF_SVID_BLEN 12 +#define PORT_VLAN0_DEF_SVID_FLAG HSL_RW + + /* Port vlan1 Register */ +#define PORT_VLAN1 +#define PORT_VLAN1_OFFSET 0x0424 +#define PORT_VLAN1_E_LENGTH 4 +#define PORT_VLAN1_E_OFFSET 0x0008 +#define PORT_VLAN1_NR_E 7 + +#define VRF_ID +#define PORT_VLAN1_VRF_ID_BOFFSET 15 +#define PORT_VLAN1_VRF_ID_BLEN 3 +#define PORT_VLAN1_VRF_ID_FLAG HSL_RW + +#define EG_VLAN_MODE +#define PORT_VLAN1_EG_VLAN_MODE_BOFFSET 12 +#define PORT_VLAN1_EG_VLAN_MODE_BLEN 2 +#define PORT_VLAN1_EG_VLAN_MODE_FLAG HSL_RW + +#define VLAN_DIS +#define PORT_VLAN1_VLAN_DIS_BOFFSET 11 +#define PORT_VLAN1_VLAN_DIS_BLEN 1 +#define PORT_VLAN1_VLAN_DIS_FLAG HSL_RW + +#define SP_CHECK_EN +#define PORT_VLAN1_SP_CHECK_EN_BOFFSET 10 +#define PORT_VLAN1_SP_CHECK_EN_BLEN 1 +#define PORT_VLAN1_SP_CHECK_EN_FLAG HSL_RW + +#define COREP_EN +#define PORT_VLAN1_COREP_EN_BOFFSET 9 +#define PORT_VLAN1_COREP_EN_BLEN 1 +#define PORT_VLAN1_COREP_EN_FLAG HSL_RW + +#define FORCE_DEF_VID +#define PORT_VLAN1_FORCE_DEF_VID_BOFFSET 8 +#define PORT_VLAN1_FORCE_DEF_VID_BLEN 1 +#define PORT_VLAN1_FORCE_DEF_VID_FLAG HSL_RW + +#define TLS_EN +#define PORT_VLAN1_TLS_EN_BOFFSET 7 +#define PORT_VLAN1_TLS_EN_BLEN 1 +#define PORT_VLAN1_TLS_EN_FLAG HSL_RW + +#define PROPAGATION_EN +#define PORT_VLAN1_PROPAGATION_EN_BOFFSET 6 +#define PORT_VLAN1_PROPAGATION_EN_BLEN 1 +#define PORT_VLAN1_PROPAGATION_EN_FLAG HSL_RW + +#define CLONE +#define PORT_VLAN1_CLONE_BOFFSET 5 +#define PORT_VLAN1_CLONE_BLEN 1 +#define PORT_VLAN1_CLONE_FLAG HSL_RW + +#define PRI_PROPAGATION +#define PORT_VLAN1_PRI_PROPAGATION_BOFFSET 4 +#define PORT_VLAN1_PRI_PROPAGATION_BLEN 1 +#define PORT_VLAN1_VLAN_PRI_PROPAGATION_FLAG HSL_RW + +#define IN_VLAN_MODE +#define PORT_VLAN1_IN_VLAN_MODE_BOFFSET 2 +#define PORT_VLAN1_IN_VLAN_MODE_BLEN 2 +#define PORT_VLAN1_IN_VLAN_MODE_FLAG HSL_RW + + + /* Route Default VID Register */ +#define ROUTER_DEFV +#define ROUTER_DEFV_OFFSET 0x0c70 +#define ROUTER_DEFV_E_LENGTH 4 +#define ROUTER_DEFV_E_OFFSET 0x0004 +#define ROUTER_DEFV_NR_E 4 + + + /* Route Egress VLAN Mode Register */ +#define ROUTER_EG +#define ROUTER_EG_OFFSET 0x0c80 +#define ROUTER_EG_E_LENGTH 4 +#define ROUTER_EG_E_OFFSET 0x0004 +#define ROUTER_EG_NR_E 1 + +/* port flow control threshold Register */ +#define PORT_FLOC_CTRL_THRESH +#define PORT_FLOC_CTRL_THRESH_OFFSET 0x9b0 +#define PORT_FLOC_CTRL_THRESH_E_LENGTH 4 +#define PORT_FLOC_CTRL_THRESH_E_OFFSET 0x0004 +#define PORT_FLOC_CTRL_THRESH_NR_E 7 + + + /* LED control Register */ +#define LED_CTRL "ledctrl" +#define LED_CTRL_ID 25 +#define LED_CTRL_OFFSET 0x0050 +#define LED_CTRL_E_LENGTH 4 +#define LED_CTRL_E_OFFSET 0 +#define LED_CTRL_NR_E 3 + +#define PATTERN_EN "lctrl_pen" +#define LED_CTRL_PATTERN_EN_BOFFSET 14 +#define LED_CTRL_PATTERN_EN_BLEN 2 +#define LED_CTRL_PATTERN_EN_FLAG HSL_RW + +#define FULL_LIGHT_EN "lctrl_fen" +#define LED_CTRL_FULL_LIGHT_EN_BOFFSET 13 +#define LED_CTRL_FULL_LIGHT_EN_BLEN 1 +#define LED_CTRL_FULL_LIGHT_EN_FLAG HSL_RW + +#define HALF_LIGHT_EN "lctrl_hen" +#define LED_CTRL_HALF_LIGHT_EN_BOFFSET 12 +#define LED_CTRL_HALF_LIGHT_EN_BLEN 1 +#define LED_CTRL_HALF_LIGHT_EN_FLAG HSL_RW + +#define POWERON_LIGHT_EN "lctrl_poen" +#define LED_CTRL_POWERON_LIGHT_EN_BOFFSET 11 +#define LED_CTRL_POWERON_LIGHT_EN_BLEN 1 +#define LED_CTRL_POWERON_LIGHT_EN_FLAG HSL_RW + +#define GE_LIGHT_EN "lctrl_geen" +#define LED_CTRL_GE_LIGHT_EN_BOFFSET 10 +#define LED_CTRL_GE_LIGHT_EN_BLEN 1 +#define LED_CTRL_GE_LIGHT_EN_FLAG HSL_RW + +#define FE_LIGHT_EN "lctrl_feen" +#define LED_CTRL_FE_LIGHT_EN_BOFFSET 9 +#define LED_CTRL_FE_LIGHT_EN_BLEN 1 +#define LED_CTRL_FE_LIGHT_EN_FLAG HSL_RW + +#define ETH_LIGHT_EN "lctrl_ethen" +#define LED_CTRL_ETH_LIGHT_EN_BOFFSET 8 +#define LED_CTRL_ETH_LIGHT_EN_BLEN 1 +#define LED_CTRL_ETH_LIGHT_EN_FLAG HSL_RW + +#define COL_BLINK_EN "lctrl_cen" +#define LED_CTRL_COL_BLINK_EN_BOFFSET 7 +#define LED_CTRL_COL_BLINK_EN_BLEN 1 +#define LED_CTRL_COL_BLINK_EN_FLAG HSL_RW + +#define RX_BLINK_EN "lctrl_rxen" +#define LED_CTRL_RX_BLINK_EN_BOFFSET 5 +#define LED_CTRL_RX_BLINK_EN_BLEN 1 +#define LED_CTRL_RX_BLINK_EN_FLAG HSL_RW + +#define TX_BLINK_EN "lctrl_txen" +#define LED_CTRL_TX_BLINK_EN_BOFFSET 4 +#define LED_CTRL_TX_BLINK_EN_BLEN 1 +#define LED_CTRL_TX_BLINK_EN_FLAG HSL_RW + +#define LINKUP_OVER_EN "lctrl_loen" +#define LED_CTRL_LINKUP_OVER_EN_BOFFSET 2 +#define LED_CTRL_LINKUP_OVER_EN_BLEN 1 +#define LED_CTRL_LINKUP_OVER_EN_FLAG HSL_RW + +#define BLINK_FREQ "lctrl_bfreq" +#define LED_CTRL_BLINK_FREQ_BOFFSET 0 +#define LED_CTRL_BLINK_FREQ_BLEN 2 +#define LED_CTRL_BLINK_FREQ_FLAG HSL_RW + + /* LED control Register */ +#define LED_PATTERN "ledpatten" +#define LED_PATTERN_ID 25 +#define LED_PATTERN_OFFSET 0x005c +#define LED_PATTERN_E_LENGTH 4 +#define LED_PATTERN_E_OFFSET 0 +#define LED_PATTERN_NR_E 1 + + +#define P3L2_MODE +#define LED_PATTERN_P3L2_MODE_BOFFSET 24 +#define LED_PATTERN_P3L2_MODE_BLEN 2 +#define LED_PATTERN_P3L2_MODE_FLAG HSL_RW + +#define P3L1_MODE +#define LED_PATTERN_P3L1_MODE_BOFFSET 22 +#define LED_PATTERN_P3L1_MODE_BLEN 2 +#define LED_PATTERN_P3L1_MODE_FLAG HSL_RW + +#define P3L0_MODE +#define LED_PATTERN_P3L0_MODE_BOFFSET 20 +#define LED_PATTERN_P3L0_MODE_BLEN 2 +#define LED_PATTERN_P3L0_MODE_FLAG HSL_RW + +#define P2L2_MODE +#define LED_PATTERN_P2L2_MODE_BOFFSET 18 +#define LED_PATTERN_P2L2_MODE_BLEN 2 +#define LED_PATTERN_P2L2_MODE_FLAG HSL_RW + +#define P2L1_MODE +#define LED_PATTERN_P2L1_MODE_BOFFSET 16 +#define LED_PATTERN_P2L1_MODE_BLEN 2 +#define LED_PATTERN_P2L1_MODE_FLAG HSL_RW + +#define P2L0_MODE +#define LED_PATTERN_P2L0_MODE_BOFFSET 14 +#define LED_PATTERN_P2L0_MODE_BLEN 2 +#define LED_PATTERN_P2L0_MODE_FLAG HSL_RW + +#define P1L2_MODE +#define LED_PATTERN_P1L2_MODE_BOFFSET 12 +#define LED_PATTERN_P1L2_MODE_BLEN 2 +#define LED_PATTERN_P1L2_MODE_FLAG HSL_RW + +#define P1L1_MODE +#define LED_PATTERN_P1L1_MODE_BOFFSET 10 +#define LED_PATTERN_P1L1_MODE_BLEN 2 +#define LED_PATTERN_P1L1_MODE_FLAG HSL_RW + +#define P1L0_MODE +#define LED_PATTERN_P1L0_MODE_BOFFSET 8 +#define LED_PATTERN_P1L0_MODE_BLEN 2 +#define LED_PATTERN_P1L0_MODE_FLAG HSL_RW + + + + + /* Pri To Queue Register */ +#define PRI_TO_QUEUE +#define PRI_TO_QUEUE_OFFSET 0x0814 +#define PRI_TO_QUEUE_E_LENGTH 4 +#define PRI_TO_QUEUE_E_OFFSET 0x0004 +#define PRI_TO_QUEUE_NR_E 1 + + + + + /* Pri To EhQueue Register */ +#define PRI_TO_EHQUEUE +#define PRI_TO_EHQUEUE_OFFSET 0x0810 +#define PRI_TO_EHQUEUE_E_LENGTH 4 +#define PRI_TO_EHQUEUE_E_OFFSET 0x0004 +#define PRI_TO_EHQUEUE_NR_E 1 + + + + + /*Global Flow Control Register*/ +#define QM_CTRL_REG +#define QM_CTRL_REG_OFFSET 0X0808 +#define QM_CTRL_REG_E_LENGTH 4 +#define QM_CTRL_REG_E_OFFSET 0x0004 +#define QM_CTRL_REG_NR_E 1 + +#define GOL_FLOW_EN +#define QM_CTRL_REG_GOL_FLOW_EN_BOFFSET 16 +#define QM_CTRL_REG_GOL_FLOW_EN_BLEN 7 +#define QM_CTRL_REG_GOL_FLOW_EN_FLAG HSL_RW + +#define QM_FUNC_TEST +#define QM_CTRL_REG_QM_FUNC_TEST_BOFFSET 10 +#define QM_CTRL_REG_QM_FUNC_TEST_BLEN 1 +#define QM_CTRL_REG_QM_FUNC_TEST_FLAG HSL_RW + +#define RATE_DROP_EN +#define QM_CTRL_REG_RATE_DROP_EN_BOFFSET 7 +#define QM_CTRL_REG_RATE_DROP_EN_BLEN 1 +#define QM_CTRL_REG_RATE_DROP_EN_FLAG HSL_RW + +#define FLOW_DROP_EN +#define QM_CTRL_REG_FLOW_DROP_EN_BOFFSET 6 +#define QM_CTRL_REG_FLOW_DROP_EN_BLEN 1 +#define QM_CTRL_REG_FLOW_DROP_EN_FLAG HSL_RW + +#define FLOW_DROP_CNT +#define QM_CTRL_REG_FLOW_DROP_CNT_BOFFSET 0 +#define QM_CTRL_REG_FLOW_DROP_CNT_BLEN 6 +#define QM_CTRL_REG_FLOW_DROP_CNT_FLAG HSL_RW + + + + + /* Port HOL CTL0 Register */ +#define PORT_HOL_CTL0 +#define PORT_HOL_CTL0_OFFSET 0x0970 +#define PORT_HOL_CTL0_E_LENGTH 4 +#define PORT_HOL_CTL0_E_OFFSET 0x0008 +#define PORT_HOL_CTL0_NR_E 7 + +#define PORT_DESC_NR +#define PORT_HOL_CTL0_PORT_DESC_NR_BOFFSET 24 +#define PORT_HOL_CTL0_PORT_DESC_NR_BLEN 6 +#define PORT_HOL_CTL0_PORT_DESC_NR_FLAG HSL_RW + +#define QUEUE5_DESC_NR +#define PORT_HOL_CTL0_QUEUE5_DESC_NR_BOFFSET 20 +#define PORT_HOL_CTL0_QUEUE5_DESC_NR_BLEN 4 +#define PORT_HOL_CTL0_QUEUE5_DESC_NR_FLAG HSL_RW + +#define QUEUE4_DESC_NR +#define PORT_HOL_CTL0_QUEUE4_DESC_NR_BOFFSET 16 +#define PORT_HOL_CTL0_QUEUE4_DESC_NR_BLEN 4 +#define PORT_HOL_CTL0_QUEUE4_DESC_NR_FLAG HSL_RW + +#define QUEUE3_DESC_NR +#define PORT_HOL_CTL0_QUEUE3_DESC_NR_BOFFSET 12 +#define PORT_HOL_CTL0_QUEUE3_DESC_NR_BLEN 4 +#define PORT_HOL_CTL0_QUEUE3_DESC_NR_FLAG HSL_RW + +#define QUEUE2_DESC_NR +#define PORT_HOL_CTL0_QUEUE2_DESC_NR_BOFFSET 8 +#define PORT_HOL_CTL0_QUEUE2_DESC_NR_BLEN 4 +#define PORT_HOL_CTL0_QUEUE2_DESC_NR_FLAG HSL_RW + +#define QUEUE1_DESC_NR +#define PORT_HOL_CTL0_QUEUE1_DESC_NR_BOFFSET 4 +#define PORT_HOL_CTL0_QUEUE1_DESC_NR_BLEN 4 +#define PORT_HOL_CTL0_QUEUE1_DESC_NR_FLAG HSL_RW + +#define QUEUE0_DESC_NR +#define PORT_HOL_CTL0_QUEUE0_DESC_NR_BOFFSET 0 +#define PORT_HOL_CTL0_QUEUE0_DESC_NR_BLEN 4 +#define PORT_HOL_CTL0_QUEUE0_DESC_NR_FLAG HSL_RW + + /* Port HOL CTL1 Register */ +#define PORT_HOL_CTL1 +#define PORT_HOL_CTL1_OFFSET 0x0974 +#define PORT_HOL_CTL1_E_LENGTH 4 +#define PORT_HOL_CTL1_E_OFFSET 0x0008 +#define PORT_HOL_CTL1_NR_E 7 + +#define EG_MIRROR_EN +#define PORT_HOL_CTL1_EG_MIRROR_EN_BOFFSET 16 +#define PORT_HOL_CTL1_EG_MIRROR_EN_BLEN 1 +#define PORT_HOL_CTL1_EG_MIRROR_EN_FLAG HSL_RW + +#define PORT_RED_EN +#define PORT_HOL_CTL1_PORT_RED_EN_BOFFSET 8 +#define PORT_HOL_CTL1_PORT_RED_EN_BLEN 1 +#define PORT_HOL_CTL1_PORT_RED_EN_FLAG HSL_RW + +#define PORT_DESC_EN +#define PORT_HOL_CTL1_PORT_DESC_EN_BOFFSET 7 +#define PORT_HOL_CTL1_PORT_DESC_EN_BLEN 1 +#define PORT_HOL_CTL1_PORT_DESC_EN_FLAG HSL_RW + +#define QUEUE_DESC_EN +#define PORT_HOL_CTL1_QUEUE_DESC_EN_BOFFSET 6 +#define PORT_HOL_CTL1_QUEUE_DESC_EN_BLEN 1 +#define PORT_HOL_CTL1_QUEUE_DESC_EN_FLAG HSL_RW + +#define PORT_IN_DESC_EN +#define PORT_HOL_CTL1_PORT_IN_DESC_EN_BOFFSET 0 +#define PORT_HOL_CTL1_PORT_IN_DESC_EN_BLEN 4 +#define PORT_HOL_CTL1_PORT_IN_DESC_EN_FLAG HSL_RW + + + /* PKT edit control register */ +#define PKT_CTRL +#define PKT_CTRL_OFFSET 0x0c00 +#define PKT_CTRL_E_LENGTH 4 +#define PKT_CTRL_E_OFFSET 0 +#define PKT_CTRL_NR_E 7 + +#define CPU_VID_EN +#define PKT_CTRL_CPU_VID_EN_BOFFSET 1 +#define PKT_CTRL_CPU_VID_EN_BLEN 1 +#define PKT_CTRL_CPU_VID_EN_FLAG HSL_RW + + +#define RTD_PPPOE_EN +#define PKT_CTRL_RTD_PPPOE_EN_BOFFSET 0 +#define PKT_CTRL_RTD_PPPOE_EN_BLEN 1 +#define PKT_CTRL_RTD_PPPOE_EN_FLAG HSL_RW + + + + + /* mib memory info */ +#define MIB_RXBROAD +#define MIB_RXBROAD_OFFSET 0x01000 +#define MIB_RXBROAD_E_LENGTH 4 +#define MIB_RXBROAD_E_OFFSET 0x100 +#define MIB_RXBROAD_NR_E 7 + +#define MIB_RXPAUSE +#define MIB_RXPAUSE_OFFSET 0x01004 +#define MIB_RXPAUSE_E_LENGTH 4 +#define MIB_RXPAUSE_E_OFFSET 0x100 +#define MIB_RXPAUSE_NR_E 7 + +#define MIB_RXMULTI +#define MIB_RXMULTI_OFFSET 0x01008 +#define MIB_RXMULTI_E_LENGTH 4 +#define MIB_RXMULTI_E_OFFSET 0x100 +#define MIB_RXMULTI_NR_E 7 + +#define MIB_RXFCSERR +#define MIB_RXFCSERR_OFFSET 0x0100c +#define MIB_RXFCSERR_E_LENGTH 4 +#define MIB_RXFCSERR_E_OFFSET 0x100 +#define MIB_RXFCSERR_NR_E 7 + +#define MIB_RXALLIGNERR +#define MIB_RXALLIGNERR_OFFSET 0x01010 +#define MIB_RXALLIGNERR_E_LENGTH 4 +#define MIB_RXALLIGNERR_E_OFFSET 0x100 +#define MIB_RXALLIGNERR_NR_E 7 + +#define MIB_RXRUNT +#define MIB_RXRUNT_OFFSET 0x01014 +#define MIB_RXRUNT_E_LENGTH 4 +#define MIB_RXRUNT_E_OFFSET 0x100 +#define MIB_RXRUNT_NR_E 7 + +#define MIB_RXFRAGMENT +#define MIB_RXFRAGMENT_OFFSET 0x01018 +#define MIB_RXFRAGMENT_E_LENGTH 4 +#define MIB_RXFRAGMENT_E_OFFSET 0x100 +#define MIB_RXFRAGMENT_NR_E 7 + +#define MIB_RX64BYTE +#define MIB_RX64BYTE_OFFSET 0x0101c +#define MIB_RX64BYTE_E_LENGTH 4 +#define MIB_RX64BYTE_E_OFFSET 0x100 +#define MIB_RX64BYTE_NR_E 7 + +#define MIB_RX128BYTE +#define MIB_RX128BYTE_OFFSET 0x01020 +#define MIB_RX128BYTE_E_LENGTH 4 +#define MIB_RX128BYTE_E_OFFSET 0x100 +#define MIB_RX128BYTE_NR_E 7 + +#define MIB_RX256BYTE +#define MIB_RX256BYTE_OFFSET 0x01024 +#define MIB_RX256BYTE_E_LENGTH 4 +#define MIB_RX256BYTE_E_OFFSET 0x100 +#define MIB_RX256BYTE_NR_E 7 + +#define MIB_RX512BYTE +#define MIB_RX512BYTE_OFFSET 0x01028 +#define MIB_RX512BYTE_E_LENGTH 4 +#define MIB_RX512BYTE_E_OFFSET 0x100 +#define MIB_RX512BYTE_NR_E 7 + +#define MIB_RX1024BYTE +#define MIB_RX1024BYTE_OFFSET 0x0102c +#define MIB_RX1024BYTE_E_LENGTH 4 +#define MIB_RX1024BYTE_E_OFFSET 0x100 +#define MIB_RX1024BYTE_NR_E 7 + +#define MIB_RX1518BYTE +#define MIB_RX1518BYTE_OFFSET 0x01030 +#define MIB_RX1518BYTE_E_LENGTH 4 +#define MIB_RX1518BYTE_E_OFFSET 0x100 +#define MIB_RX1518BYTE_NR_E 7 + +#define MIB_RXMAXBYTE +#define MIB_RXMAXBYTE_OFFSET 0x01034 +#define MIB_RXMAXBYTE_E_LENGTH 4 +#define MIB_RXMAXBYTE_E_OFFSET 0x100 +#define MIB_RXMAXBYTE_NR_E 7 + +#define MIB_RXTOOLONG +#define MIB_RXTOOLONG_OFFSET 0x01038 +#define MIB_RXTOOLONG_E_LENGTH 4 +#define MIB_RXTOOLONG_E_OFFSET 0x100 +#define MIB_RXTOOLONG_NR_E 7 + +#define MIB_RXGOODBYTE_LO +#define MIB_RXGOODBYTE_LO_OFFSET 0x0103c +#define MIB_RXGOODBYTE_LO_E_LENGTH 4 +#define MIB_RXGOODBYTE_LO_E_OFFSET 0x100 +#define MIB_RXGOODBYTE_LO_NR_E 7 + +#define MIB_RXGOODBYTE_HI +#define MIB_RXGOODBYTE_HI_OFFSET 0x01040 +#define MIB_RXGOODBYTE_HI_E_LENGTH 4 +#define MIB_RXGOODBYTE_HI_E_OFFSET 0x100 +#define MIB_RXGOODBYTE_HI_NR_E 7 + +#define MIB_RXBADBYTE_LO +#define MIB_RXBADBYTE_LO_OFFSET 0x01044 +#define MIB_RXBADBYTE_LO_E_LENGTH 4 +#define MIB_RXBADBYTE_LO_E_OFFSET 0x100 +#define MIB_RXBADBYTE_LO_NR_E 7 + +#define MIB_RXBADBYTE_HI +#define MIB_RXBADBYTE_HI_OFFSET 0x01048 +#define MIB_RXBADBYTE_HI_E_LENGTH 4 +#define MIB_RXBADBYTE_HI_E_OFFSET 0x100 +#define MIB_RXBADBYTE_HI_NR_E 7 + +#define MIB_RXOVERFLOW +#define MIB_RXOVERFLOW_OFFSET 0x0104c +#define MIB_RXOVERFLOW_E_LENGTH 4 +#define MIB_RXOVERFLOW_E_OFFSET 0x100 +#define MIB_RXOVERFLOW_NR_E 7 + +#define MIB_FILTERED +#define MIB_FILTERED_OFFSET 0x01050 +#define MIB_FILTERED_E_LENGTH 4 +#define MIB_FILTERED_E_OFFSET 0x100 +#define MIB_FILTERED_NR_E 7 + +#define MIB_TXBROAD +#define MIB_TXBROAD_OFFSET 0x01054 +#define MIB_TXBROAD_E_LENGTH 4 +#define MIB_TXBROAD_E_OFFSET 0x100 +#define MIB_TXBROAD_NR_E 7 + +#define MIB_TXPAUSE +#define MIB_TXPAUSE_OFFSET 0x01058 +#define MIB_TXPAUSE_E_LENGTH 4 +#define MIB_TXPAUSE_E_OFFSET 0x100 +#define MIB_TXPAUSE_NR_E 7 + +#define MIB_TXMULTI +#define MIB_TXMULTI_OFFSET 0x0105c +#define MIB_TXMULTI_E_LENGTH 4 +#define MIB_TXMULTI_E_OFFSET 0x100 +#define MIB_TXMULTI_NR_E 7 + +#define MIB_TXUNDERRUN +#define MIB_TXUNDERRUN_OFFSET 0x01060 +#define MIB_TXUNDERRUN_E_LENGTH 4 +#define MIB_TXUNDERRUN_E_OFFSET 0x100 +#define MIB_TXUNDERRUN_NR_E 7 + +#define MIB_TX64BYTE +#define MIB_TX64BYTE_OFFSET 0x01064 +#define MIB_TX64BYTE_E_LENGTH 4 +#define MIB_TX64BYTE_E_OFFSET 0x100 +#define MIB_TX64BYTE_NR_E 7 + +#define MIB_TX128BYTE +#define MIB_TX128BYTE_OFFSET 0x01068 +#define MIB_TX128BYTE_E_LENGTH 4 +#define MIB_TX128BYTE_E_OFFSET 0x100 +#define MIB_TX128BYTE_NR_E 7 + +#define MIB_TX256BYTE +#define MIB_TX256BYTE_OFFSET 0x0106c +#define MIB_TX256BYTE_E_LENGTH 4 +#define MIB_TX256BYTE_E_OFFSET 0x100 +#define MIB_TX256BYTE_NR_E 7 + +#define MIB_TX512BYTE +#define MIB_TX512BYTE_OFFSET 0x01070 +#define MIB_TX512BYTE_E_LENGTH 4 +#define MIB_TX512BYTE_E_OFFSET 0x100 +#define MIB_TX512BYTE_NR_E 7 + +#define MIB_TX1024BYTE +#define MIB_TX1024BYTE_OFFSET 0x01074 +#define MIB_TX1024BYTE_E_LENGTH 4 +#define MIB_TX1024BYTE_E_OFFSET 0x100 +#define MIB_TX1024BYTE_NR_E 7 + +#define MIB_TX1518BYTE +#define MIB_TX1518BYTE_OFFSET 0x01078 +#define MIB_TX1518BYTE_E_LENGTH 4 +#define MIB_TX1518BYTE_E_OFFSET 0x100 +#define MIB_TX1518BYTE_NR_E 7 + +#define MIB_TXMAXBYTE +#define MIB_TXMAXBYTE_OFFSET 0x0107c +#define MIB_TXMAXBYTE_E_LENGTH 4 +#define MIB_TXMAXBYTE_E_OFFSET 0x100 +#define MIB_TXMAXBYTE_NR_E 7 + +#define MIB_TXOVERSIZE +#define MIB_TXOVERSIZE_OFFSET 0x01080 +#define MIB_TXOVERSIZE_E_LENGTH 4 +#define MIB_TXOVERSIZE_E_OFFSET 0x100 +#define MIB_TXOVERSIZE_NR_E 7 + +#define MIB_TXBYTE_LO +#define MIB_TXBYTE_LO_OFFSET 0x01084 +#define MIB_TXBYTE_LO_E_LENGTH 4 +#define MIB_TXBYTE_LO_E_OFFSET 0x100 +#define MIB_TXBYTE_LO_NR_E 7 + +#define MIB_TXBYTE_HI +#define MIB_TXBYTE_HI_OFFSET 0x01088 +#define MIB_TXBYTE_HI_E_LENGTH 4 +#define MIB_TXBYTE_HI_E_OFFSET 0x100 +#define MIB_TXBYTE_HI_NR_E 7 + +#define MIB_TXCOLLISION +#define MIB_TXCOLLISION_OFFSET 0x0108c +#define MIB_TXCOLLISION_E_LENGTH 4 +#define MIB_TXCOLLISION_E_OFFSET 0x100 +#define MIB_TXCOLLISION_NR_E 7 + +#define MIB_TXABORTCOL +#define MIB_TXABORTCOL_OFFSET 0x01090 +#define MIB_TXABORTCOL_E_LENGTH 4 +#define MIB_TXABORTCOL_E_OFFSET 0x100 +#define MIB_TXABORTCOL_NR_E 7 + +#define MIB_TXMULTICOL +#define MIB_TXMULTICOL_OFFSET 0x01094 +#define MIB_TXMULTICOL_E_LENGTH 4 +#define MIB_TXMULTICOL_E_OFFSET 0x100 +#define MIB_TXMULTICOL_NR_E 7 + +#define MIB_TXSINGALCOL +#define MIB_TXSINGALCOL_OFFSET 0x01098 +#define MIB_TXSINGALCOL_E_LENGTH 4 +#define MIB_TXSINGALCOL_E_OFFSET 0x100 +#define MIB_TXSINGALCOL_NR_E 7 + +#define MIB_TXEXCDEFER +#define MIB_TXEXCDEFER_OFFSET 0x0109c +#define MIB_TXEXCDEFER_E_LENGTH 4 +#define MIB_TXEXCDEFER_E_OFFSET 0x100 +#define MIB_TXEXCDEFER_NR_E 7 + +#define MIB_TXDEFER +#define MIB_TXDEFER_OFFSET 0x010a0 +#define MIB_TXDEFER_E_LENGTH 4 +#define MIB_TXDEFER_E_OFFSET 0x100 +#define MIB_TXDEFER_NR_E 7 + +#define MIB_TXLATECOL +#define MIB_TXLATECOL_OFFSET 0x010a4 +#define MIB_TXLATECOL_E_LENGTH 4 +#define MIB_TXLATECOL_E_OFFSET 0x100 +#define MIB_TXLATECOL_NR_E 7 + +#define MIB_RXUNICAST +#define MIB_RXUNICAST_OFFSET 0x010a8 +#define MIB_RXUNICAST_E_LENGTH 4 +#define MIB_RXUNICAST_E_OFFSET 0x100 +#define MIB_RXUNICAST_NR_E 7 + +#define MIB_TXUNICAST +#define MIB_TXUNICAST_OFFSET 0x010ac +#define MIB_TXUNICAST_E_LENGTH 4 +#define MIB_TXUNICAST_E_OFFSET 0x100 +#define MIB_TXUNICAST_NR_E 7 + + /* ACL Action Register */ +#define ACL_RSLT0 10 +#define ACL_RSLT0_OFFSET 0x5a000 +#define ACL_RSLT0_E_LENGTH 4 +#define ACL_RSLT0_E_OFFSET 0x10 +#define ACL_RSLT0_NR_E 96 + +#define CTAGPRI +#define ACL_RSLT0_CTAGPRI_BOFFSET 29 +#define ACL_RSLT0_CTAGPRI_BLEN 3 +#define ACL_RSLT0_CTAGPRI_FLAG HSL_RW + +#define CTAGCFI +#define ACL_RSLT0_CTAGCFI_BOFFSET 28 +#define ACL_RSLT0_CTAGCFI_BLEN 1 +#define ACL_RSLT0_CTAGCFI_FLAG HSL_RW + +#define CTAGVID +#define ACL_RSLT0_CTAGVID_BOFFSET 16 +#define ACL_RSLT0_CTAGVID_BLEN 12 +#define ACL_RSLT0_CTAGVID_FLAG HSL_RW + +#define STAGPRI +#define ACL_RSLT0_STAGPRI_BOFFSET 13 +#define ACL_RSLT0_STAGPRI_BLEN 3 +#define ACL_RSLT0_STAGPRI_FLAG HSL_RW + +#define STAGDEI +#define ACL_RSLT0_STAGDEI_BOFFSET 12 +#define ACL_RSLT0_STAGDEI_BLEN 1 +#define ACL_RSLT0_STAGDEI_FLAG HSL_RW + +#define STAGVID +#define ACL_RSLT0_STAGVID_BOFFSET 0 +#define ACL_RSLT0_STAGVID_BLEN 12 +#define ACL_RSLT0_STAGVID_FLAG HSL_RW + + +#define ACL_RSLT1 11 +#define ACL_RSLT1_OFFSET 0x5a004 +#define ACL_RSLT1_E_LENGTH 4 +#define ACL_RSLT1_E_OFFSET 0x10 +#define ACL_RSLT1_NR_E 96 + +#define DES_PORT0 +#define ACL_RSLT1_DES_PORT0_BOFFSET 29 +#define ACL_RSLT1_DES_PORT0_BLEN 3 +#define ACL_RSLT1_DES_PORT0_FLAG HSL_RW + +#define PRI_QU_EN +#define ACL_RSLT1_PRI_QU_EN_BOFFSET 28 +#define ACL_RSLT1_PRI_QU_EN_BLEN 1 +#define ACL_RSLT1_PRI_QU_EN_FLAG HSL_RW + +#define PRI_QU +#define ACL_RSLT1_PRI_QU_BOFFSET 25 +#define ACL_RSLT1_PRI_QU_BLEN 3 +#define ACL_RSLT1_PRI_QU_FLAG HSL_RW + +#define WCMP_EN +#define ACL_RSLT1_WCMP_EN_BOFFSET 24 +#define ACL_RSLT1_WCMP_EN_BLEN 1 +#define ACL_RSLT1_WCMP_EN_FLAG HSL_RW + +#define ARP_PTR +#define ACL_RSLT1_ARP_PTR_BOFFSET 17 +#define ACL_RSLT1_ARP_PTR_BLEN 7 +#define ACL_RSLT1_ARP_PTR_FLAG HSL_RW + +#define ARP_PTR_EN +#define ACL_RSLT1_ARP_PTR_EN_BOFFSET 16 +#define ACL_RSLT1_ARP_PTR_EN_BLEN 1 +#define ACL_RSLT1_ARP_PTR_EN_FLAG HSL_RW + +#define FORCE_L3_MODE +#define ACL_RSLT1_FORCE_L3_MODE_BOFFSET 14 +#define ACL_RSLT1_FORCE_L3_MODE_BLEN 2 +#define ACL_RSLT1_FORCE_L3_MODE_FLAG HSL_RW + +#define LOOK_VID_CHG +#define ACL_RSLT1_LOOK_VID_CHG_BOFFSET 13 +#define ACL_RSLT1_LOOK_VID_CHG_BLEN 1 +#define ACL_RSLT1_LOOK_VID_CHG_FLAG HSL_RW + +#define TRANS_CVID_CHG +#define ACL_RSLT1_TRANS_CVID_CHG_BOFFSET 12 +#define ACL_RSLT1_TRANS_CVID_CHG_BLEN 1 +#define ACL_RSLT1_TRANS_CVID_CHG_FLAG HSL_RW + +#define TRANS_SVID_CHG +#define ACL_RSLT1_TRANS_SVID_CHG_BOFFSET 11 +#define ACL_RSLT1_TRANS_SVID_CHG_BLEN 1 +#define ACL_RSLT1_TRANS_SVID_CHG_FLAG HSL_RW + +#define CTAG_CFI_CHG +#define ACL_RSLT1_CTAG_CFI_CHG_BOFFSET 10 +#define ACL_RSLT1_CTAG_CFI_CHG_BLEN 1 +#define ACL_RSLT1_CTAG_CFI_CHG_FLAG HSL_RW + +#define CTAG_PRI_REMAP +#define ACL_RSLT1_CTAG_PRI_REMAP_BOFFSET 9 +#define ACL_RSLT1_CTAG_PRI_REMAP_BLEN 1 +#define ACL_RSLT1_CTAG_PRI_REMAP_FLAG HSL_RW + +#define STAG_DEI_CHG +#define ACL_RSLT1_STAG_DEI_CHG_BOFFSET 8 +#define ACL_RSLT1_STAG_DEI_CHG_BLEN 1 +#define ACL_RSLT1_STAG_DEI_CHG_FLAG HSL_RW + +#define STAG_PRI_REMAP +#define ACL_RSLT1_STAG_PRI_REMAP_BOFFSET 7 +#define ACL_RSLT1_STAG_PRI_REMAP_BLEN 1 +#define ACL_RSLT1_STAG_PRI_REMAP_FLAG HSL_RW + +#define DSCP_REMAP +#define ACL_RSLT1_DSCP_REMAP_BOFFSET 6 +#define ACL_RSLT1_DSCP_REMAP_BLEN 1 +#define ACL_RSLT1_DSCP_REMAP_FLAG HSL_RW + +#define DSCPV +#define ACL_RSLT1_DSCPV_BOFFSET 0 +#define ACL_RSLT1_DSCPV_BLEN 6 +#define ACL_RSLT1_DSCPV_FLAG HSL_RW + +#define ACL_RSLT2 12 +#define ACL_RSLT2_OFFSET 0x5a008 +#define ACL_RSLT2_E_LENGTH 4 +#define ACL_RSLT2_E_OFFSET 0x10 +#define ACL_RSLT2_NR_E 96 + +#define TRIGGER_INTR +#define ACL_RSLT2_TRIGGER_INTR_BOFFSET 16 +#define ACL_RSLT2_TRIGGER_INTR_BLEN 1 +#define ACL_RSLT2_TRIGGER_INTR_FLAG HSL_RW + +#define EG_BYPASS +#define ACL_RSLT2_EG_BYPASS_BOFFSET 15 +#define ACL_RSLT2_EG_BYPASS_BLEN 1 +#define ACL_RSLT2_EG_BYPASS_FLAG HSL_RW + +#define POLICER_EN +#define ACL_RSLT2_POLICER_EN_BOFFSET 14 +#define ACL_RSLT2_POLICER_EN_BLEN 1 +#define ACL_RSLT2_POLICER_EN_FLAG HSL_RW + +#define POLICER_PTR +#define ACL_RSLT2_POLICER_PTR_BOFFSET 9 +#define ACL_RSLT2_POLICER_PTR_BLEN 5 +#define ACL_RSLT2_POLICER_PTR_FLAG HSL_RW + +#define FWD_CMD +#define ACL_RSLT2_FWD_CMD_BOFFSET 6 +#define ACL_RSLT2_FWD_CMD_BLEN 3 +#define ACL_RSLT2_FWD_CMD_FLAG HSL_RW + +#define MIRR_EN +#define ACL_RSLT2_MIRR_EN_BOFFSET 5 +#define ACL_RSLT2_MIRR_EN_BLEN 1 +#define ACL_RSLT2_MIRR_EN_FLAG HSL_RW + +#define DES_PORT_EN +#define ACL_RSLT2_DES_PORT_EN_BOFFSET 4 +#define ACL_RSLT2_DES_PORT_EN_BLEN 1 +#define ACL_RSLT2_DES_PORT_EN_FLAG HSL_RW + +#define DES_PORT1 +#define ACL_RSLT2_DES_PORT1_BOFFSET 0 +#define ACL_RSLT2_DES_PORT1_BLEN 4 +#define ACL_RSLT2_DES_PORT1_FLAG HSL_RW + + + + + /* MAC Type Rule Field Define */ +#define MAC_RUL_V0 0 +#define MAC_RUL_V0_OFFSET 0x58000 +#define MAC_RUL_V0_E_LENGTH 4 +#define MAC_RUL_V0_E_OFFSET 0x20 +#define MAC_RUL_V0_NR_E 96 + +#define DAV_BYTE2 +#define MAC_RUL_V0_DAV_BYTE2_BOFFSET 24 +#define MAC_RUL_V0_DAV_BYTE2_BLEN 8 +#define MAC_RUL_V0_DAV_BYTE2_FLAG HSL_RW + +#define DAV_BYTE3 +#define MAC_RUL_V0_DAV_BYTE3_BOFFSET 16 +#define MAC_RUL_V0_DAV_BYTE3_BLEN 8 +#define MAC_RUL_V0_DAV_BYTE3_FLAG HSL_RW + +#define DAV_BYTE4 +#define MAC_RUL_V0_DAV_BYTE4_BOFFSET 8 +#define MAC_RUL_V0_DAV_BYTE4_BLEN 8 +#define MAC_RUL_V0_DAV_BYTE4_FLAG HSL_RW + +#define DAV_BYTE5 +#define MAC_RUL_V0_DAV_BYTE5_BOFFSET 0 +#define MAC_RUL_V0_DAV_BYTE5_BLEN 8 +#define MAC_RUL_V0_DAV_BYTE5_FLAG HSL_RW + + +#define MAC_RUL_V1 1 +#define MAC_RUL_V1_OFFSET 0x58004 +#define MAC_RUL_V1_E_LENGTH 4 +#define MAC_RUL_V1_E_OFFSET 0x20 +#define MAC_RUL_V1_NR_E 96 + +#define SAV_BYTE4 +#define MAC_RUL_V1_SAV_BYTE4_BOFFSET 24 +#define MAC_RUL_V1_SAV_BYTE4_BLEN 8 +#define MAC_RUL_V1_SAV_BYTE4_FLAG HSL_RW + +#define SAV_BYTE5 +#define MAC_RUL_V1_SAV_BYTE5_BOFFSET 16 +#define MAC_RUL_V1_SAV_BYTE5_BLEN 8 +#define MAC_RUL_V1_SAV_BYTE5_FLAG HSL_RW + +#define DAV_BYTE0 +#define MAC_RUL_V1_DAV_BYTE0_BOFFSET 8 +#define MAC_RUL_V1_DAV_BYTE0_BLEN 8 +#define MAC_RUL_V1_DAV_BYTE0_FLAG HSL_RW + +#define DAV_BYTE1 +#define MAC_RUL_V1_DAV_BYTE1_BOFFSET 0 +#define MAC_RUL_V1_DAV_BYTE1_BLEN 8 +#define MAC_RUL_V1_DAV_BYTE1_FLAG HSL_RW + + +#define MAC_RUL_V2 2 +#define MAC_RUL_V2_OFFSET 0x58008 +#define MAC_RUL_V2_E_LENGTH 4 +#define MAC_RUL_V2_E_OFFSET 0x20 +#define MAC_RUL_V2_NR_E 96 + +#define SAV_BYTE0 +#define MAC_RUL_V2_SAV_BYTE0_BOFFSET 24 +#define MAC_RUL_V2_SAV_BYTE0_BLEN 8 +#define MAC_RUL_V2_SAV_BYTE0_FLAG HSL_RW + +#define SAV_BYTE1 +#define MAC_RUL_V2_SAV_BYTE1_BOFFSET 16 +#define MAC_RUL_V2_SAV_BYTE1_BLEN 8 +#define MAC_RUL_V2_SAV_BYTE1_FLAG HSL_RW + +#define SAV_BYTE2 +#define MAC_RUL_V2_SAV_BYTE2_BOFFSET 8 +#define MAC_RUL_V2_SAV_BYTE2_BLEN 8 +#define MAC_RUL_V2_SAV_BYTE2_FLAG HSL_RW + +#define SAV_BYTE3 +#define MAC_RUL_V2_SAV_BYTE3_BOFFSET 0 +#define MAC_RUL_V2_SAV_BYTE3_BLEN 8 +#define MAC_RUL_V2_SAV_BYTE3_FLAG HSL_RW + + +#define MAC_RUL_V3 3 +#define MAC_RUL_V3_ID 13 +#define MAC_RUL_V3_OFFSET 0x5800c +#define MAC_RUL_V3_E_LENGTH 4 +#define MAC_RUL_V3_E_OFFSET 0x20 +#define MAC_RUL_V3_NR_E 96 + +#define ETHTYPV +#define MAC_RUL_V3_ETHTYPV_BOFFSET 16 +#define MAC_RUL_V3_ETHTYPV_BLEN 16 +#define MAC_RUL_V3_ETHTYPV_FLAG HSL_RW + +#define VLANPRIV +#define MAC_RUL_V3_VLANPRIV_BOFFSET 13 +#define MAC_RUL_V3_VLANPRIV_BLEN 3 +#define MAC_RUL_V3_VLANPRIV_FLAG HSL_RW + +#define VLANCFIV +#define MAC_RUL_V3_VLANCFIV_BOFFSET 12 +#define MAC_RUL_V3_VLANCFIV_BLEN 1 +#define MAC_RUL_V3_VLANCFIV_FLAG HSL_RW + +#define VLANIDV +#define MAC_RUL_V3_VLANIDV_BOFFSET 0 +#define MAC_RUL_V3_VLANIDV_BLEN 12 +#define MAC_RUL_V3_VLANIDV_FLAG HSL_RW + + +#define MAC_RUL_V4 4 +#define MAC_RUL_V4_OFFSET 0x58010 +#define MAC_RUL_V4_E_LENGTH 4 +#define MAC_RUL_V4_E_OFFSET 0x20 +#define MAC_RUL_V4_NR_E 96 + +#define RULE_INV +#define MAC_RUL_V4_RULE_INV_BOFFSET 7 +#define MAC_RUL_V4_RULE_INV_BLEN 1 +#define MAC_RUL_V4_RULE_INV_FLAG HSL_RW + +#define SRC_PT +#define MAC_RUL_V4_SRC_PT_BOFFSET 0 +#define MAC_RUL_V4_SRC_PT_BLEN 7 +#define MAC_RUL_V4_SRC_PT_FLAG HSL_RW + + +#define MAC_RUL_M0 5 +#define MAC_RUL_M0_OFFSET 0x59000 +#define MAC_RUL_M0_E_LENGTH 4 +#define MAC_RUL_M0_E_OFFSET 0x20 +#define MAC_RUL_M0_NR_E 96 + +#define DAM_BYTE2 +#define MAC_RUL_M0_DAM_BYTE2_BOFFSET 24 +#define MAC_RUL_M0_DAM_BYTE2_BLEN 8 +#define MAC_RUL_M0_DAM_BYTE2_FLAG HSL_RW + +#define DAM_BYTE3 +#define MAC_RUL_M0_DAM_BYTE3_BOFFSET 16 +#define MAC_RUL_M0_DAM_BYTE3_BLEN 8 +#define MAC_RUL_M0_DAM_BYTE3_FLAG HSL_RW + +#define DAM_BYTE4 +#define MAC_RUL_M0_DAM_BYTE4_BOFFSET 8 +#define MAC_RUL_M0_DAM_BYTE4_BLEN 8 +#define MAC_RUL_M0_DAM_BYTE4_FLAG HSL_RW + +#define DAM_BYTE5 +#define MAC_RUL_M0_DAM_BYTE5_BOFFSET 0 +#define MAC_RUL_M0_DAM_BYTE5_BLEN 8 +#define MAC_RUL_M0_DAM_BYTE5_FLAG HSL_RW + + +#define MAC_RUL_M1 6 +#define MAC_RUL_M1_OFFSET 0x59004 +#define MAC_RUL_M1_E_LENGTH 4 +#define MAC_RUL_M1_E_OFFSET 0x20 +#define MAC_RUL_M1_NR_E 96 + +#define SAM_BYTE4 +#define MAC_RUL_M1_SAM_BYTE4_BOFFSET 24 +#define MAC_RUL_M1_SAM_BYTE4_BLEN 8 +#define MAC_RUL_M1_SAM_BYTE4_FLAG HSL_RW + +#define SAM_BYTE5 +#define MAC_RUL_M1_SAM_BYTE5_BOFFSET 16 +#define MAC_RUL_M1_SAM_BYTE5_BLEN 8 +#define MAC_RUL_M1_SAM_BYTE5_FLAG HSL_RW + +#define DAM_BYTE0 +#define MAC_RUL_M1_DAM_BYTE0_BOFFSET 8 +#define MAC_RUL_M1_DAM_BYTE0_BLEN 8 +#define MAC_RUL_M1_DAM_BYTE0_FLAG HSL_RW + +#define DAM_BYTE1 +#define MAC_RUL_M1_DAM_BYTE1_BOFFSET 0 +#define MAC_RUL_M1_DAM_BYTE1_BLEN 8 +#define MAC_RUL_M1_DAM_BYTE1_FLAG HSL_RW + + +#define MAC_RUL_M2 7 +#define MAC_RUL_M2_OFFSET 0x59008 +#define MAC_RUL_M2_E_LENGTH 4 +#define MAC_RUL_M2_E_OFFSET 0x20 +#define MAC_RUL_M2_NR_E 96 + +#define SAM_BYTE0 +#define MAC_RUL_M2_SAM_BYTE0_BOFFSET 24 +#define MAC_RUL_M2_SAM_BYTE0_BLEN 8 +#define MAC_RUL_M2_SAM_BYTE0_FLAG HSL_RW + +#define SAM_BYTE1 +#define MAC_RUL_M2_SAM_BYTE1_BOFFSET 16 +#define MAC_RUL_M2_SAM_BYTE1_BLEN 8 +#define MAC_RUL_M2_SAM_BYTE1_FLAG HSL_RW + +#define SAM_BYTE2 +#define MAC_RUL_M2_SAM_BYTE2_BOFFSET 8 +#define MAC_RUL_M2_SAM_BYTE2_BLEN 8 +#define MAC_RUL_M2_SAM_BYTE2_FLAG HSL_RW + +#define SAM_BYTE3 +#define MAC_RUL_M2_SAM_BYTE3_BOFFSET 0 +#define MAC_RUL_M2_SAM_BYTE3_BLEN 8 +#define MAC_RUL_M2_SAM_BYTE3_FLAG HSL_RW + + +#define MAC_RUL_M3 8 +#define MAC_RUL_M3_OFFSET 0x5900c +#define MAC_RUL_M3_E_LENGTH 4 +#define MAC_RUL_M3_E_OFFSET 0x20 +#define MAC_RUL_M3_NR_E 96 + +#define ETHTYPM +#define MAC_RUL_M3_ETHTYPM_BOFFSET 16 +#define MAC_RUL_M3_ETHTYPM_BLEN 16 +#define MAC_RUL_M3_ETHTYPM_FLAG HSL_RW + +#define VLANPRIM +#define MAC_RUL_M3_VLANPRIM_BOFFSET 13 +#define MAC_RUL_M3_VLANPRIM_BLEN 3 +#define MAC_RUL_M3_VLANPRIM_FLAG HSL_RW + +#define VLANCFIM +#define MAC_RUL_M3_VLANCFIM_BOFFSET 12 +#define MAC_RUL_M3_VLANCFIM_BLEN 1 +#define MAC_RUL_M3_VLANCFIM_FLAG HSL_RW + +#define VLANIDM +#define MAC_RUL_M3_VLANIDM_BOFFSET 0 +#define MAC_RUL_M3_VLANIDM_BLEN 12 +#define MAC_RUL_M3_VLANIDM_FLAG HSL_RW + + +#define MAC_RUL_M4 9 +#define MAC_RUL_M4_OFFSET 0x59010 +#define MAC_RUL_M4_E_LENGTH 4 +#define MAC_RUL_M4_E_OFFSET 0x20 +#define MAC_RUL_M4_NR_E 96 + +#define RULE_VALID +#define MAC_RUL_M4_RULE_VALID_BOFFSET 6 +#define MAC_RUL_M4_RULE_VALID_BLEN 2 +#define MAC_RUL_M4_RULE_VALID_FLAG HSL_RW + +#define TAGGEDM +#define MAC_RUL_M4_TAGGEDM_BOFFSET 5 +#define MAC_RUL_M4_TAGGEDM_BLEN 1 +#define MAC_RUL_M4_TAGGEDM_FLAG HSL_RW + +#define TAGGEDV +#define MAC_RUL_M4_TAGGEDV_BOFFSET 4 +#define MAC_RUL_M4_TAGGEDV_BLEN 1 +#define MAC_RUL_M4_TAGGEDV_FLAG HSL_RW + +#define VIDMSK +#define MAC_RUL_M4_VIDMSK_BOFFSET 3 +#define MAC_RUL_M4_VIDMSK_BLEN 1 +#define MAC_RUL_M4_VIDMSK_FLAG HSL_RW + +#define RULE_TYP +#define MAC_RUL_M4_RULE_TYP_BOFFSET 0 +#define MAC_RUL_M4_RULE_TYP_BLEN 3 +#define MAC_RUL_M4_RULE_TYP_FLAG HSL_RW + + + + + /* IP4 Type Rule Field Define */ +#define IP4_RUL_V0 0 +#define IP4_RUL_V0_OFFSET 0x58000 +#define IP4_RUL_V0_E_LENGTH 4 +#define IP4_RUL_V0_E_OFFSET 0x20 +#define IP4_RUL_V0_NR_E 96 + +#define DIPV +#define IP4_RUL_V0_DIPV_BOFFSET 0 +#define IP4_RUL_V0_DIPV_BLEN 32 +#define IP4_RUL_V0_DIPV_FLAG HSL_RW + + +#define IP4_RUL_V1 1 +#define IP4_RUL_V1_OFFSET 0x58004 +#define IP4_RUL_V1_E_LENGTH 4 +#define IP4_RUL_V1_E_OFFSET 0x20 +#define IP4_RUL_V1_NR_E 96 + +#define SIPV +#define IP4_RUL_V1_SIPV_BOFFSET 0 +#define IP4_RUL_V1_SIPV_BLEN 32 +#define IP4_RUL_V1_SIPV_FLAG HSL_RW + + +#define IP4_RUL_V2 2 +#define IP4_RUL_V2_OFFSET 0x58008 +#define IP4_RUL_V2_E_LENGTH 4 +#define IP4_RUL_V2_E_OFFSET 0x20 +#define IP4_RUL_V2_NR_E 96 + +#define IP4PROTV +#define IP4_RUL_V2_IP4PROTV_BOFFSET 0 +#define IP4_RUL_V2_IP4PROTV_BLEN 8 +#define IP4_RUL_V2_IP4PROTV_FLAG HSL_RW + +#define IP4DSCPV +#define IP4_RUL_V2_IP4DSCPV_BOFFSET 8 +#define IP4_RUL_V2_IP4DSCPV_BLEN 8 +#define IP4_RUL_V2_IP4DSCPV_FLAG HSL_RW + +#define IP4DPORTV +#define IP4_RUL_V2_IP4DPORTV_BOFFSET 16 +#define IP4_RUL_V2_IP4DPORTV_BLEN 16 +#define IP4_RUL_V2_IP4DPORTV_FLAG HSL_RW + + +#define IP4_RUL_V3 3 +#define IP4_RUL_V3_OFFSET 0x5800c +#define IP4_RUL_V3_E_LENGTH 4 +#define IP4_RUL_V3_E_OFFSET 0x20 +#define IP4_RUL_V3_NR_E 96 + +#define IP4TCPFLAGV +#define IP4_RUL_V3_IP4TCPFLAGV_BOFFSET 24 +#define IP4_RUL_V3_IP4TCPFLAGV_BLEN 6 +#define IP4_RUL_V3_IP4TCPFLAGV_FLAG HSL_RW + +#define IP4DHCPV +#define IP4_RUL_V3_IP4DHCPV_BOFFSET 22 +#define IP4_RUL_V3_IP4DHCPV_BLEN 1 +#define IP4_RUL_V3_IP4DHCPV_FLAG HSL_RW + +#define IP4RIPV +#define IP4_RUL_V3_IP4RIPV_BOFFSET 21 +#define IP4_RUL_V3_IP4RIPV_BLEN 1 +#define IP4_RUL_V3_IP4RIPV_FLAG HSL_RW + +#define ICMP_EN +#define IP4_RUL_V3_ICMP_EN_BOFFSET 20 +#define IP4_RUL_V3_ICMP_EN_BLEN 1 +#define IP4_RUL_V3_ICMP_EN_FLAG HSL_RW + +#define IP4SPORTV +#define IP4_RUL_V3_IP4SPORTV_BOFFSET 0 +#define IP4_RUL_V3_IP4SPORTV_BLEN 16 +#define IP4_RUL_V3_IP4SPORTV_FLAG HSL_RW + +#define IP4ICMPTYPV +#define IP4_RUL_V3_IP4ICMPTYPV_BOFFSET 8 +#define IP4_RUL_V3_IP4ICMPTYPV_BLEN 8 +#define IP4_RUL_V3_IP4ICMPTYPV_FLAG HSL_RW + +#define IP4ICMPCODEV +#define IP4_RUL_V3_IP4ICMPCODEV_BOFFSET 0 +#define IP4_RUL_V3_IP4ICMPCODEV_BLEN 8 +#define IP4_RUL_V3_IP4ICMPCODEV_FLAG HSL_RW + + +#define IP4_RUL_V4 4 +#define IP4_RUL_V4_OFFSET 0x58010 +#define IP4_RUL_V4_E_LENGTH 4 +#define IP4_RUL_V4_E_OFFSET 0x20 +#define IP4_RUL_V4_NR_E 96 + + +#define IP4_RUL_M0 5 +#define IP4_RUL_M0_OFFSET 0x59000 +#define IP4_RUL_M0_E_LENGTH 4 +#define IP4_RUL_M0_E_OFFSET 0x20 +#define IP4_RUL_M0_NR_E 96 + +#define DIPM +#define IP4_RUL_M0_DIPM_BOFFSET 0 +#define IP4_RUL_M0_DIPM_BLEN 32 +#define IP4_RUL_M0_DIPM_FLAG HSL_RW + + +#define IP4_RUL_M1 6 +#define IP4_RUL_M1_OFFSET 0x59004 +#define IP4_RUL_M1_E_LENGTH 4 +#define IP4_RUL_M1_E_OFFSET 0x20 +#define IP4_RUL_M1_NR_E 96 + +#define SIPM +#define IP4_RUL_M1_SIPM_BOFFSET 0 +#define IP4_RUL_M1_SIPM_BLEN 32 +#define IP4_RUL_M1_SIPM_FLAG HSL_RW + + +#define IP4_RUL_M2 7 +#define IP4_RUL_M2_OFFSET 0x59008 +#define IP4_RUL_M2_E_LENGTH 4 +#define IP4_RUL_M2_E_OFFSET 0x20 +#define IP4_RUL_M2_NR_E 96 + +#define IP4PROTM +#define IP4_RUL_M2_IP4PROTM_BOFFSET 0 +#define IP4_RUL_M2_IP4PROTM_BLEN 8 +#define IP4_RUL_M2_IP4PROTM_FLAG HSL_RW + +#define IP4DSCPM +#define IP4_RUL_M2_IP4DSCPM_BOFFSET 8 +#define IP4_RUL_M2_IP4DSCPM_BLEN 8 +#define IP4_RUL_M2_IP4DSCPM_FLAG HSL_RW + +#define IP4DPORTM +#define IP4_RUL_M2_IP4DPORTM_BOFFSET 16 +#define IP4_RUL_M2_IP4DPORTM_BLEN 16 +#define IP4_RUL_M2_IP4DPORTM_FLAG HSL_RW + + +#define IP4_RUL_M3 8 +#define IP4_RUL_M3_OFFSET 0x5900c +#define IP4_RUL_M3_E_LENGTH 4 +#define IP4_RUL_M3_E_OFFSET 0x20 +#define IP4_RUL_M3_NR_E 96 + +#define IP4TCPFLAGM +#define IP4_RUL_M3_IP4TCPFLAGM_BOFFSET 24 +#define IP4_RUL_M3_IP4TCPFLAGM_BLEN 6 +#define IP4_RUL_M3_IP4TCPFLAGM_FLAG HSL_RW + +#define IP4DHCPM +#define IP4_RUL_M3_IP4DHCPM_BOFFSET 22 +#define IP4_RUL_M3_IP4DHCPM_BLEN 1 +#define IP4_RUL_M3_IP4DHCPM_FLAG HSL_RW + +#define IP4RIPM +#define IP4_RUL_M3_IP4RIPM_BOFFSET 21 +#define IP4_RUL_M3_IP4RIPM_BLEN 1 +#define IP4_RUL_M3_IP4RIPM_FLAG HSL_RW + +#define IP4DPORTM_EN +#define IP4_RUL_M3_IP4DPORTM_EN_BOFFSET 17 +#define IP4_RUL_M3_IP4DPORTM_EN_BLEN 1 +#define IP4_RUL_M3_IP4DPORTM_EN_FLAG HSL_RW + +#define IP4SPORTM_EN +#define IP4_RUL_M3_IP4SPORTM_EN_BOFFSET 16 +#define IP4_RUL_M3_IP4SPORTM_EN_BLEN 1 +#define IP4_RUL_M3_IP4SPORTM_EN_FLAG HSL_RW + +#define IP4SPORTM +#define IP4_RUL_M3_IP4SPORTM_BOFFSET 0 +#define IP4_RUL_M3_IP4SPORTM_BLEN 16 +#define IP4_RUL_M3_IP4SPORTM_FLAG HSL_RW + +#define IP4ICMPTYPM +#define IP4_RUL_M3_IP4ICMPTYPM_BOFFSET 8 +#define IP4_RUL_M3_IP4ICMPTYPM_BLEN 8 +#define IP4_RUL_M3_IP4ICMPTYPM_FLAG HSL_RW + +#define IP4ICMPCODEM +#define IP4_RUL_M3_IP4ICMPCODEM_BOFFSET 0 +#define IP4_RUL_M3_IP4ICMPCODEM_BLEN 8 +#define IP4_RUL_M3_IP4ICMPCODEM_FLAG HSL_RW + + +#define IP4_RUL_M4 9 +#define IP4_RUL_M4_OFFSET 0x59010 +#define IP4_RUL_M4_E_LENGTH 4 +#define IP4_RUL_M4_E_OFFSET 0x20 +#define IP4_RUL_M4_NR_E 32 + + + + + /* IP6 Type1 Rule Field Define */ +#define IP6_RUL1_V0 0 +#define IP6_RUL1_V0_OFFSET 0x58000 +#define IP6_RUL1_V0_E_LENGTH 4 +#define IP6_RUL1_V0_E_OFFSET 0x20 +#define IP6_RUL1_V0_NR_E 96 + +#define IP6_DIPV0 +#define IP6_RUL1_V0_IP6_DIPV0_BOFFSET 0 +#define IP6_RUL1_V0_IP6_DIPV0_BLEN 32 +#define IP6_RUL1_V0_IP6_DIPV0_FLAG HSL_RW + + +#define IP6_RUL1_V1 1 +#define IP6_RUL1_V1_OFFSET 0x58004 +#define IP6_RUL1_V1_E_LENGTH 4 +#define IP6_RUL1_V1_E_OFFSET 0x20 +#define IP6_RUL1_V1_NR_E 96 + +#define IP6_DIPV1 +#define IP6_RUL1_V1_IP6_DIPV1_BOFFSET 0 +#define IP6_RUL1_V1_IP6_DIPv1_BLEN 32 +#define IP6_RUL1_V1_IP6_DIPV1_FLAG HSL_RW + + +#define IP6_RUL1_V2 2 +#define IP6_RUL1_V2_OFFSET 0x58008 +#define IP6_RUL1_V2_E_LENGTH 4 +#define IP6_RUL1_V2_E_OFFSET 0x20 +#define IP6_RUL1_V2_NR_E 96 + +#define IP6_DIPV2 +#define IP6_RUL1_V2_IP6_DIPV2_BOFFSET 0 +#define IP6_RUL1_V2_IP6_DIPv2_BLEN 32 +#define IP6_RUL1_V2_IP6_DIPV2_FLAG HSL_RW + + +#define IP6_RUL1_V3 3 +#define IP6_RUL1_V3_OFFSET 0x5800c +#define IP6_RUL1_V3_E_LENGTH 4 +#define IP6_RUL1_V3_E_OFFSET 0x20 +#define IP6_RUL1_V3_NR_E 96 + +#define IP6_DIPV3 +#define IP6_RUL1_V3_IP6_DIPV3_BOFFSET 0 +#define IP6_RUL1_V3_IP6_DIPv3_BLEN 32 +#define IP6_RUL1_V3_IP6_DIPV3_FLAG HSL_RW + + +#define IP6_RUL1_V4 4 +#define IP6_RUL1_V4_OFFSET 0x58010 +#define IP6_RUL1_V4_E_LENGTH 4 +#define IP6_RUL1_V4_E_OFFSET 0x20 +#define IP6_RUL1_V4_NR_E 96 + + +#define IP6_RUL1_M0 5 +#define IP6_RUL1_M0_OFFSET 0x59000 +#define IP6_RUL1_M0_E_LENGTH 4 +#define IP6_RUL1_M0_E_OFFSET 0x20 +#define IP6_RUL1_M0_NR_E 96 + +#define IP6_DIPM0 +#define IP6_RUL1_M0_IP6_DIPM0_BOFFSET 0 +#define IP6_RUL1_M0_IP6_DIPM0_BLEN 32 +#define IP6_RUL1_M0_IP6_DIPM0_FLAG HSL_RW + + +#define IP6_RUL1_M1 6 +#define IP6_RUL1_M1_OFFSET 0x59004 +#define IP6_RUL1_M1_E_LENGTH 4 +#define IP6_RUL1_M1_E_OFFSET 0x20 +#define IP6_RUL1_M1_NR_E 96 + +#define IP6_DIPM1 +#define IP6_RUL1_M1_IP6_DIPM1_BOFFSET 0 +#define IP6_RUL1_M1_IP6_DIPM1_BLEN 32 +#define IP6_RUL1_M1_IP6_DIPM1_FLAG HSL_RW + + +#define IP6_RUL1_M2 7 +#define IP6_RUL1_M2_OFFSET 0x59008 +#define IP6_RUL1_M2_E_LENGTH 4 +#define IP6_RUL1_M2_E_OFFSET 0x20 +#define IP6_RUL1_M2_NR_E 96 + +#define IP6_DIPM2 +#define IP6_RUL1_M2_IP6_DIPM2_BOFFSET 0 +#define IP6_RUL1_M2_IP6_DIPM2_BLEN 32 +#define IP6_RUL1_M2_IP6_DIPM2_FLAG HSL_RW + + +#define IP6_RUL1_M3 8 +#define IP6_RUL1_M3_OFFSET 0x5900c +#define IP6_RUL1_M3_E_LENGTH 4 +#define IP6_RUL1_M3_E_OFFSET 0x20 +#define IP6_RUL1_M3_NR_E 96 + +#define IP6_DIPM3 +#define IP6_RUL1_M3_IP6_DIPM3_BOFFSET 0 +#define IP6_RUL1_M3_IP6_DIPM3_BLEN 32 +#define IP6_RUL1_M3_IP6_DIPM3_FLAG HSL_RW + + +#define IP6_RUL1_M4 9 +#define IP6_RUL1_M4_OFFSET 0x59010 +#define IP6_RUL1_M4_E_LENGTH 4 +#define IP6_RUL1_M4_E_OFFSET 0x20 +#define IP6_RUL1_M4_NR_E 96 + + + + + /* IP6 Type2 Rule Field Define */ +#define IP6_RUL2_V0 0 +#define IP6_RUL2_V0_OFFSET 0x58000 +#define IP6_RUL2_V0_E_LENGTH 4 +#define IP6_RUL2_V0_E_OFFSET 0x20 +#define IP6_RUL2_V0_NR_E 96 + +#define IP6_SIPV0 +#define IP6_RUL2_V0_IP6_SIPV0_BOFFSET 0 +#define IP6_RUL2_V0_IP6_SIPv0_BLEN 32 +#define IP6_RUL2_V0_IP6_SIPV0_FLAG HSL_RW + + +#define IP6_RUL2_V1 1 +#define IP6_RUL2_V1_OFFSET 0x58004 +#define IP6_RUL2_V1_E_LENGTH 4 +#define IP6_RUL2_V1_E_OFFSET 0x20 +#define IP6_RUL2_V1_NR_E 96 + +#define IP6_SIPV1 +#define IP6_RUL2_V1_IP6_SIPV1_BOFFSET 0 +#define IP6_RUL2_V1_IP6_SIPv1_BLEN 32 +#define IP6_RUL2_V1_IP6_SIPV1_FLAG HSL_RW + + +#define IP6_RUL2_V2 2 +#define IP6_RUL2_V2_OFFSET 0x58008 +#define IP6_RUL2_V2_E_LENGTH 4 +#define IP6_RUL2_V2_E_OFFSET 0x20 +#define IP6_RUL2_V2_NR_E 96 + +#define IP6_SIPV2 +#define IP6_RUL2_V2_IP6_SIPV2_BOFFSET 0 +#define IP6_RUL2_V2_IP6_SIPv2_BLEN 32 +#define IP6_RUL2_V2_IP6_SIPV2_FLAG HSL_RW + + +#define IP6_RUL2_V3 3 +#define IP6_RUL2_V3_OFFSET 0x5800c +#define IP6_RUL2_V3_E_LENGTH 4 +#define IP6_RUL2_V3_E_OFFSET 0x20 +#define IP6_RUL2_V3_NR_E 96 + +#define IP6_SIPV3 +#define IP6_RUL2_V3_IP6_SIPV3_BOFFSET 0 +#define IP6_RUL2_V3_IP6_SIPv3_BLEN 32 +#define IP6_RUL2_V3_IP6_SIPV3_FLAG HSL_RW + + +#define IP6_RUL2_V4 4 +#define IP6_RUL2_V4_OFFSET 0x58010 +#define IP6_RUL2_V4_E_LENGTH 4 +#define IP6_RUL2_V4_E_OFFSET 0x20 +#define IP6_RUL2_V4_NR_E 96 + + +#define IP6_RUL2_M0 5 +#define IP6_RUL2_M0_OFFSET 0x59000 +#define IP6_RUL2_M0_E_LENGTH 4 +#define IP6_RUL2_M0_E_OFFSET 0x20 +#define IP6_RUL2_M0_NR_E 96 + +#define IP6_SIPM0 +#define IP6_RUL2_M0_IP6_SIPM0_BOFFSET 0 +#define IP6_RUL2_M0_IP6_SIPM0_BLEN 32 +#define IP6_RUL2_M0_IP6_SIPM0_FLAG HSL_RW + + +#define IP6_RUL2_M1 6 +#define IP6_RUL2_M1_OFFSET 0x59004 +#define IP6_RUL2_M1_E_LENGTH 4 +#define IP6_RUL2_M1_E_OFFSET 0x20 +#define IP6_RUL2_M1_NR_E 96 + +#define IP6_SIPM1 +#define IP6_RUL2_M1_IP6_DIPM1_BOFFSET 0 +#define IP6_RUL2_M1_IP6_DIPM1_BLEN 32 +#define IP6_RUL2_M1_IP6_DIPM1_FLAG HSL_RW + + +#define IP6_RUL2_M2 7 +#define IP6_RUL2_M2_OFFSET 0x59008 +#define IP6_RUL2_M2_E_LENGTH 4 +#define IP6_RUL2_M2_E_OFFSET 0x20 +#define IP6_RUL2_M2_NR_E 96 + +#define IP6_SIPM2 +#define IP6_RUL2_M2_IP6_DIPM2_BOFFSET 0 +#define IP6_RUL2_M2_IP6_DIPM2_BLEN 32 +#define IP6_RUL2_M2_IP6_DIPM2_FLAG HSL_RW + + +#define IP6_RUL2_M3 8 +#define IP6_RUL2_M3_OFFSET 0x5900c +#define IP6_RUL2_M3_E_LENGTH 4 +#define IP6_RUL2_M3_E_OFFSET 0x20 +#define IP6_RUL2_M3_NR_E 96 + +#define IP6_SIPM3 +#define IP6_RUL2_M3_IP6_SIPM3_BOFFSET 0 +#define IP6_RUL2_M3_IP6_SIPM3_BLEN 32 +#define IP6_RUL2_M3_IP6_SIPM3_FLAG HSL_RW + + +#define IP6_RUL2_M4 9 +#define IP6_RUL2_M4_OFFSET 0x59010 +#define IP6_RUL2_M4_E_LENGTH 4 +#define IP6_RUL2_M4_E_OFFSET 0x20 +#define IP6_RUL2_M4_NR_E 96 + + + + + /* IP6 Type3 Rule Field Define */ +#define IP6_RUL3_V0 0 +#define IP6_RUL3_V0_OFFSET 0x58000 +#define IP6_RUL3_V0_E_LENGTH 4 +#define IP6_RUL3_V0_E_OFFSET 0x20 +#define IP6_RUL3_V0_NR_E 96 + +#define IP6PROTV +#define IP6_RUL3_V0_IP6PROTV_BOFFSET 0 +#define IP6_RUL3_V0_IP6PROTV_BLEN 8 +#define IP6_RUL3_V0_IP6PROTV_FLAG HSL_RW + +#define IP6DSCPV +#define IP6_RUL3_V0_IP6DSCPV_BOFFSET 8 +#define IP6_RUL3_V0_IP6DSCPV_BLEN 8 +#define IP6_RUL3_V0_IP6DSCPV_FLAG HSL_RW + + +#define IP6_RUL3_V1 1 +#define IP6_RUL3_V1_OFFSET 0x58004 +#define IP6_RUL3_V1_E_LENGTH 4 +#define IP6_RUL3_V1_E_OFFSET 0x20 +#define IP6_RUL3_V1_NR_E 96 + +#define IP6LABEL1V +#define IP6_RUL3_V1_IP6LABEL1V_BOFFSET 16 +#define IP6_RUL3_V1_IP6LABEL1V_BLEN 16 +#define IP6_RUL3_V1_IP6LABEL1V_FLAG HSL_RW + + +#define IP6_RUL3_V2 2 +#define IP6_RUL3_V2_OFFSET 0x58008 +#define IP6_RUL3_V2_E_LENGTH 4 +#define IP6_RUL3_V2_E_OFFSET 0x20 +#define IP6_RUL3_V2_NR_E 96 + +#define IP6LABEL2V +#define IP6_RUL3_V2_IP6LABEL2V_BOFFSET 0 +#define IP6_RUL3_V2_IP6LABEL2V_BLEN 4 +#define IP6_RUL3_V2_IP6LABEL2V_FLAG HSL_RW + +#define IP6DPORTV +#define IP6_RUL3_V2_IP6DPORTV_BOFFSET 16 +#define IP6_RUL3_V2_IP6DPORTV_BLEN 16 +#define IP6_RUL3_V2_IP6DPORTV_FLAG HSL_RW + + +#define IP6_RUL3_V3 3 +#define IP6_RUL3_V3_OFFSET 0x5800c +#define IP6_RUL3_V3_E_LENGTH 4 +#define IP6_RUL3_V3_E_OFFSET 0x20 +#define IP6_RUL3_V3_NR_E 96 + +#define IP6TCPFLAGV +#define IP6_RUL3_V3_IP6TCPFLAGV_BOFFSET 24 +#define IP6_RUL3_V3_IP6TCPFLAGV_BLEN 6 +#define IP6_RUL3_V3_IP6TCPFLAGV_FLAG HSL_RW + +#define IP6FWDTYPV +#define IP6_RUL3_V3_IP6FWDTYPV_BOFFSET 23 +#define IP6_RUL3_V3_IP6FWDTYPV_BLEN 1 +#define IP6_RUL3_V3_IP6FWDTYPV_FLAG HSL_RW + +#define IP6DHCPV +#define IP6_RUL3_V3_IP6DHCPV_BOFFSET 22 +#define IP6_RUL3_V3_IP6DHCPV_BLEN 1 +#define IP6_RUL3_V3_IP6DHCPV_FLAG HSL_RW + +#define ICMP6_EN +#define IP6_RUL3_V3_ICMP6_EN_BOFFSET 20 +#define IP6_RUL3_V3_ICMP6_EN_BLEN 1 +#define IP6_RUL3_V3_ICMP6_EN_FLAG HSL_RW + +#define IP6SPORTV +#define IP6_RUL3_V3_IP6SPORTV_BOFFSET 0 +#define IP6_RUL3_V3_IP6SPORTV_BLEN 16 +#define IP6_RUL3_V3_IP6SPORTV_FLAG HSL_RW + +#define IP6ICMPTYPV +#define IP6_RUL3_V3_IP6ICMPTYPV_BOFFSET 8 +#define IP6_RUL3_V3_IP6ICMPTYPV_BLEN 8 +#define IP6_RUL3_V3_IP6ICMPTYPV_FLAG HSL_RW + +#define IP6ICMPCODEV +#define IP6_RUL3_V3_IP6ICMPCODEV_BOFFSET 0 +#define IP6_RUL3_V3_IP6ICMPCODEV_BLEN 8 +#define IP6_RUL3_V3_IP6ICMPCODEV_FLAG HSL_RW + + +#define IP6_RUL3_V4 4 +#define IP6_RUL3_V4_OFFSET 0x58010 +#define IP6_RUL3_V4_E_LENGTH 4 +#define IP6_RUL3_V4_E_OFFSET 0x20 +#define IP6_RUL3_V4_NR_E 96 + + +#define IP6_RUL3_M0 5 +#define IP6_RUL3_M0_OFFSET 0x59000 +#define IP6_RUL3_M0_E_LENGTH 4 +#define IP6_RUL3_M0_E_OFFSET 0x20 +#define IP6_RUL3_M0_NR_E 96 + +#define IP6PROTM +#define IP6_RUL3_M0_IP6PROTM_BOFFSET 0 +#define IP6_RUL3_M0_IP6PROTM_BLEN 8 +#define IP6_RUL3_M0_IP6PROTM_FLAG HSL_RW + +#define IP6DSCPM +#define IP6_RUL3_M0_IP6DSCPM_BOFFSET 8 +#define IP6_RUL3_M0_IP6DSCPM_BLEN 8 +#define IP6_RUL3_M0_IP6DSCPM_FLAG HSL_RW + + +#define IP6_RUL3_M1 6 +#define IP6_RUL3_M1_OFFSET 0x59004 +#define IP6_RUL3_M1_E_LENGTH 4 +#define IP6_RUL3_M1_E_OFFSET 0x20 +#define IP6_RUL3_M1_NR_E 96 + +#define IP6LABEL1M +#define IP6_RUL3_M1_IP6LABEL1M_BOFFSET 16 +#define IP6_RUL3_M1_IP6LABEL1M_BLEN 16 +#define IP6_RUL3_M1_IP6LABEL1M_FLAG HSL_RW + + +#define IP6_RUL3_M2 7 +#define IP6_RUL3_M2_OFFSET 0x59008 +#define IP6_RUL3_M2_E_LENGTH 4 +#define IP6_RUL3_M2_E_OFFSET 0x20 +#define IP6_RUL3_M2_NR_E 96 + +#define IP6LABEL2M +#define IP6_RUL3_M2_IP6LABEL2M_BOFFSET 0 +#define IP6_RUL3_M2_IP6LABEL2M_BLEN 4 +#define IP6_RUL3_M2_IP6LABEL21M_FLAG HSL_RW + +#define IP6DPORTM +#define IP6_RUL3_M2_IP6DPORTM_BOFFSET 16 +#define IP6_RUL3_M2_IP6DPORTM_BLEN 16 +#define IP6_RUL3_M2_IP6DPORTM_FLAG HSL_RW + + +#define IP6_RUL3_M3 8 +#define IP6_RUL3_M3_OFFSET 0x5900c +#define IP6_RUL3_M3_E_LENGTH 4 +#define IP6_RUL3_M3_E_OFFSET 0x20 +#define IP6_RUL3_M3_NR_E 96 + +#define IP6TCPFLAGM +#define IP6_RUL3_M3_IP6TCPFLAGM_BOFFSET 24 +#define IP6_RUL3_M3_IP6TCPFLAGM_BLEN 6 +#define IP6_RUL3_M3_IP6TCPFLAGM_FLAG HSL_RW + +#define IP6RWDTYPM +#define IP6_RUL3_M3_IP6RWDTYPV_BOFFSET 23 +#define IP6_RUL3_M3_IP6RWDTYPV_BLEN 1 +#define IP6_RUL3_M3_IP6RWDTYPV_FLAG HSL_RW + +#define IP6DHCPM +#define IP6_RUL3_M3_IP6DHCPM_BOFFSET 22 +#define IP6_RUL3_M3_IP6DHCPM_BLEN 1 +#define IP6_RUL3_M3_IP6DHCPM_FLAG HSL_RW + +#define IP6DPORTM_EN +#define IP6_RUL3_M3_IP6DPORTM_EN_BOFFSET 17 +#define IP6_RUL3_M3_IP6DPORTM_EN_BLEN 1 +#define IP6_RUL3_M3_IP6DPORTM_EN_FLAG HSL_RW + +#define IP6SPORTM_EN +#define IP6_RUL3_M3_IP6SPORTM_EN_BOFFSET 16 +#define IP6_RUL3_M3_IP6SPORTM_EN_BLEN 1 +#define IP6_RUL3_M3_IP6SPORTM_EN_FLAG HSL_RW + +#define IP6SPORTM +#define IP6_RUL3_M3_IP6SPORTM_BOFFSET 0 +#define IP6_RUL3_M3_IP6SPORTM_BLEN 16 +#define IP6_RUL3_M3_IP6SPORTM_FLAG HSL_RW + +#define IP6ICMPTYPM +#define IP6_RUL3_M3_IP6ICMPTYPM_BOFFSET 8 +#define IP6_RUL3_M3_IP6ICMPTYPM_BLEN 8 +#define IP6_RUL3_M3_IP6ICMPTYPM_FLAG HSL_RW + +#define IP6ICMPCODEM +#define IP6_RUL3_M3_IP6ICMPCODEM_BOFFSET 0 +#define IP6_RUL3_M3_IP6ICMPCODEM_BLEN 8 +#define IP6_RUL3_M3_IP6ICMPCODEM_FLAG HSL_RW + + +#define IP6_RUL3_M4 9 +#define IP6_RUL3_M4_OFFSET 0x59010 +#define IP6_RUL3_M4_E_LENGTH 4 +#define IP6_RUL3_M4_E_OFFSET 0x20 +#define IP6_RUL3_M4_NR_E 96 + + + + + /* Enhanced MAC Type Rule Field Define */ +#define EHMAC_RUL_V0 0 +#define EHMAC_RUL_V0_OFFSET 0x58000 +#define EHMAC_RUL_V0_E_LENGTH 4 +#define EHMAC_RUL_V0_E_OFFSET 0x20 +#define EHMAC_RUL_V0_NR_E 96 + +#define DAV_BYTE2 +#define EHMAC_RUL_V0_DAV_BYTE2_BOFFSET 24 +#define EHMAC_RUL_V0_DAV_BYTE2_BLEN 8 +#define EHMAC_RUL_V0_DAV_BYTE2_FLAG HSL_RW + +#define DAV_BYTE3 +#define EHMAC_RUL_V0_DAV_BYTE3_BOFFSET 16 +#define EHMAC_RUL_V0_DAV_BYTE3_BLEN 8 +#define EHMAC_RUL_V0_DAV_BYTE3_FLAG HSL_RW + +#define DAV_BYTE4 +#define EHMAC_RUL_V0_DAV_BYTE4_BOFFSET 8 +#define EHMAC_RUL_V0_DAV_BYTE4_BLEN 8 +#define EHMAC_RUL_V0_DAV_BYTE4_FLAG HSL_RW + +#define DAV_BYTE5 +#define EHMAC_RUL_V0_DAV_BYTE5_BOFFSET 0 +#define EHMAC_RUL_V0_DAV_BYTE5_BLEN 8 +#define EHMAC_RUL_V0_DAV_BYTE5_FLAG HSL_RW + + +#define EHMAC_RUL_V1 1 +#define EHMAC_RUL_V1_OFFSET 0x58004 +#define EHMAC_RUL_V1_E_LENGTH 4 +#define EHMAC_RUL_V1_E_OFFSET 0x20 +#define EHMAC_RUL_V1_NR_E 96 + +#define SAV_BYTE4 +#define EHMAC_RUL_V1_SAV_BYTE4_BOFFSET 24 +#define EHMAC_RUL_V1_SAV_BYTE4_BLEN 8 +#define EHMAC_RUL_V1_SAV_BYTE4_FLAG HSL_RW + +#define SAV_BYTE5 +#define EHMAC_RUL_V1_SAV_BYTE5_BOFFSET 16 +#define EHMAC_RUL_V1_SAV_BYTE5_BLEN 8 +#define EHMAC_RUL_V1_SAV_BYTE5_FLAG HSL_RW + +#define DAV_BYTE0 +#define EHMAC_RUL_V1_DAV_BYTE0_BOFFSET 8 +#define EHMAC_RUL_V1_DAV_BYTE0_BLEN 8 +#define EHMAC_RUL_V1_DAV_BYTE0_FLAG HSL_RW + +#define DAV_BYTE1 +#define EHMAC_RUL_V1_DAV_BYTE1_BOFFSET 0 +#define EHMAC_RUL_V1_DAV_BYTE1_BLEN 8 +#define EHMAC_RUL_V1_DAV_BYTE1_FLAG HSL_RW + + +#define EHMAC_RUL_V2 2 +#define EHMAC_RUL_V2_OFFSET 0x58008 +#define EHMAC_RUL_V2_E_LENGTH 4 +#define EHMAC_RUL_V2_E_OFFSET 0x20 +#define EHMAC_RUL_V2_NR_E 96 + +#define CTAG_VIDLV +#define EHMAC_RUL_V2_CTAG_VIDLV_BOFFSET 24 +#define EHMAC_RUL_V2_CTAG_VIDLV_BLEN 8 +#define EHMAC_RUL_V2_CTAG_VIDLV_FLAG HSL_RW + +#define STAG_PRIV +#define EHMAC_RUL_V2_STAG_PRIV_BOFFSET 21 +#define EHMAC_RUL_V2_STAG_PRIV_BLEN 3 +#define EHMAC_RUL_V2_STAG_PRIV_FLAG HSL_RW + +#define STAG_DEIV +#define EHMAC_RUL_V2_STAG_DEIV_BOFFSET 20 +#define EHMAC_RUL_V2_STAG_DEIV_BLEN 1 +#define EHMAC_RUL_V2_STAG_DEIV_FLAG HSL_RW + +#define STAG_VIDV +#define EHMAC_RUL_V2_STAG_VIDV_BOFFSET 8 +#define EHMAC_RUL_V2_STAG_VIDV_BLEN 12 +#define EHMAC_RUL_V2_STAG_VIDV_FLAG HSL_RW + +#define SAV_BYTE3 +#define EHMAC_RUL_V2_SAV_BYTE3_BOFFSET 0 +#define EHMAC_RUL_V2_SAV_BYTE3_BLEN 8 +#define EHMAC_RUL_V2_SAV_BYTE3_FLAG HSL_RW + + +#define EHMAC_RUL_V3 3 +#define EHMAC_RUL_V3_ID 13 +#define EHMAC_RUL_V3_OFFSET 0x5800c +#define EHMAC_RUL_V3_E_LENGTH 4 +#define EHMAC_RUL_V3_E_OFFSET 0x20 +#define EHMAC_RUL_V3_NR_E 96 + +#define STAGGEDM +#define EHMAC_RUL_V3_STAGGEDM_BOFFSET 31 +#define EHMAC_RUL_V3_STAGGEDM_BLEN 1 +#define EHMAC_RUL_V3_STAGGEDM_FLAG HSL_RW + +#define STAGGEDV +#define EHMAC_RUL_V3_STAGGEDV_BOFFSET 30 +#define EHMAC_RUL_V3_STAGGEDV_BLEN 1 +#define EHMAC_RUL_V3_STAGGEDV_FLAG HSL_RW + +#define DA_EN +#define EHMAC_RUL_V3_DA_EN_BOFFSET 25 +#define EHMAC_RUL_V3_DA_EN_BLEN 1 +#define EHMAC_RUL_V3_DA_EN_FLAG HSL_RW + +#define SVIDMSK +#define EHMAC_RUL_V3_SVIDMSK_BOFFSET 24 +#define EHMAC_RUL_V3_SVIDMSK_BLEN 1 +#define EHMAC_RUL_V3_SVIDMSK_FLAG HSL_RW + +#define ETHTYPV +#define EHMAC_RUL_V3_ETHTYPV_BOFFSET 8 +#define EHMAC_RUL_V3_ETHTYPV_BLEN 16 +#define EHMAC_RUL_V3_ETHTYPV_FLAG HSL_RW + +#define CTAG_PRIV +#define EHMAC_RUL_V3_CTAG_PRIV_BOFFSET 5 +#define EHMAC_RUL_V3_CTAG_PRIV_BLEN 3 +#define EHMAC_RUL_V3_CTAG_PRIV_FLAG HSL_RW + +#define CTAG_CFIV +#define EHMAC_RUL_V3_CTAG_CFIV_BOFFSET 4 +#define EHMAC_RUL_V3_CTAG_CFIV_BLEN 1 +#define EHMAC_RUL_V3_CTAG_CFIV_FLAG HSL_RW + +#define CTAG_VIDHV +#define EHMAC_RUL_V3_CTAG_VIDHV_BOFFSET 0 +#define EHMAC_RUL_V3_CTAG_VIDHV_BLEN 4 +#define EHMAC_RUL_V3_CTAG_VIDHV_FLAG HSL_RW + + +#define EHMAC_RUL_V4 4 +#define EHMAC_RUL_V4_OFFSET 0x58010 +#define EHMAC_RUL_V4_E_LENGTH 4 +#define EHMAC_RUL_V4_E_OFFSET 0x20 +#define EHMAC_RUL_V4_NR_E 96 + + +#define EHMAC_RUL_M0 5 +#define EHMAC_RUL_M0_OFFSET 0x59000 +#define EHMAC_RUL_M0_E_LENGTH 4 +#define EHMAC_RUL_M0_E_OFFSET 0x20 +#define EHMAC_RUL_M0_NR_E 96 + +#define DAM_BYTE2 +#define EHMAC_RUL_M0_DAM_BYTE2_BOFFSET 24 +#define EHMAC_RUL_M0_DAM_BYTE2_BLEN 8 +#define EHMAC_RUL_M0_DAM_BYTE2_FLAG HSL_RW + +#define DAM_BYTE3 +#define EHMAC_RUL_M0_DAM_BYTE3_BOFFSET 16 +#define EHMAC_RUL_M0_DAM_BYTE3_BLEN 8 +#define EHMAC_RUL_M0_DAM_BYTE3_FLAG HSL_RW + +#define DAM_BYTE4 +#define EHMAC_RUL_M0_DAM_BYTE4_BOFFSET 8 +#define EHMAC_RUL_M0_DAM_BYTE4_BLEN 8 +#define EHMAC_RUL_M0_DAM_BYTE4_FLAG HSL_RW + +#define DAM_BYTE5 +#define EHMAC_RUL_M0_DAM_BYTE5_BOFFSET 0 +#define EHMAC_RUL_M0_DAM_BYTE5_BLEN 8 +#define EHMAC_RUL_M0_DAM_BYTE5_FLAG HSL_RW + + +#define EHMAC_RUL_M1 6 +#define EHMAC_RUL_M1_OFFSET 0x59004 +#define EHMAC_RUL_M1_E_LENGTH 4 +#define EHMAC_RUL_M1_E_OFFSET 0x20 +#define EHMAC_RUL_M1_NR_E 96 + +#define SAM_BYTE4 +#define EHMAC_RUL_M1_SAM_BYTE4_BOFFSET 24 +#define EHMAC_RUL_M1_SAM_BYTE4_BLEN 8 +#define EHMAC_RUL_M1_SAM_BYTE4_FLAG HSL_RW + +#define SAM_BYTE5 +#define EHMAC_RUL_M1_SAM_BYTE5_BOFFSET 16 +#define EHMAC_RUL_M1_SAM_BYTE5_BLEN 8 +#define EHMAC_RUL_M1_SAM_BYTE5_FLAG HSL_RW + +#define DAM_BYTE0 +#define EHMAC_RUL_M1_DAM_BYTE0_BOFFSET 8 +#define EHMAC_RUL_M1_DAM_BYTE0_BLEN 8 +#define EHMAC_RUL_M1_DAM_BYTE0_FLAG HSL_RW + +#define DAM_BYTE1 +#define EHMAC_RUL_M1_DAM_BYTE1_BOFFSET 0 +#define EHMAC_RUL_M1_DAM_BYTE1_BLEN 8 +#define EHMAC_RUL_M1_DAM_BYTE1_FLAG HSL_RW + + +#define EHMAC_RUL_M2 7 +#define EHMAC_RUL_M2_OFFSET 0x59008 +#define EHMAC_RUL_M2_E_LENGTH 4 +#define EHMAC_RUL_M2_E_OFFSET 0x20 +#define EHMAC_RUL_M2_NR_E 96 + +#define CTAG_VIDLM +#define EHMAC_RUL_M2_CTAG_VIDLM_BOFFSET 24 +#define EHMAC_RUL_M2_CTAG_VIDLM_BLEN 8 +#define EHMAC_RUL_M2_CTAG_VIDLM_FLAG HSL_RW + +#define STAG_PRIM +#define EHMAC_RUL_M2_STAG_PRIM_BOFFSET 21 +#define EHMAC_RUL_M2_STAG_PRIM_BLEN 3 +#define EHMAC_RUL_M2_STAG_PRIM_FLAG HSL_RW + +#define STAG_DEIM +#define EHMAC_RUL_M2_STAG_DEIM_BOFFSET 20 +#define EHMAC_RUL_M2_STAG_DEIM_BLEN 1 +#define EHMAC_RUL_M2_STAG_DEIM_FLAG HSL_RW + +#define STAG_VIDM +#define EHMAC_RUL_M2_STAG_VIDM_BOFFSET 8 +#define EHMAC_RUL_M2_STAG_VIDM_BLEN 12 +#define EHMAC_RUL_M2_STAG_VIDM_FLAG HSL_RW + +#define SAM_BYTE3 +#define EHMAC_RUL_M2_SAM_BYTE3_BOFFSET 0 +#define EHMAC_RUL_M2_SAM_BYTE3_BLEN 8 +#define EHMAC_RUL_M2_SAM_BYTE3_FLAG HSL_RW + + +#define EHMAC_RUL_M3 8 +#define EHMAC_RUL_M3_OFFSET 0x5900c +#define EHMAC_RUL_M3_E_LENGTH 4 +#define EHMAC_RUL_M3_E_OFFSET 0x20 +#define EHMAC_RUL_M3_NR_E 96 + +#define ETHTYPM +#define EHMAC_RUL_M3_ETHTYPM_BOFFSET 8 +#define EHMAC_RUL_M3_ETHTYPM_BLEN 16 +#define EHMAC_RUL_M3_ETHTYPM_FLAG HSL_RW + +#define CTAG_PRIM +#define EHMAC_RUL_M3_CTAG_PRIM_BOFFSET 5 +#define EHMAC_RUL_M3_CTAG_PRIM_BLEN 3 +#define EHMAC_RUL_M3_CTAG_PRIM_FLAG HSL_RW + +#define CTAG_CFIM +#define EHMAC_RUL_M3_CTAG_CFIM_BOFFSET 4 +#define EHMAC_RUL_M3_CTAG_CFIM_BLEN 1 +#define EHMAC_RUL_M3_CTAG_CFIM_FLAG HSL_RW + +#define CTAG_VIDHM +#define EHMAC_RUL_M3_CTAG_VIDHM_BOFFSET 0 +#define EHMAC_RUL_M3_CTAG_VIDHM_BLEN 4 +#define EHMAC_RUL_M3_CTAG_VIDHM_FLAG HSL_RW + + +#define EHMAC_RUL_M4 9 +#define EHMAC_RUL_M4_OFFSET 0x59010 +#define EHMAC_RUL_M4_E_LENGTH 4 +#define EHMAC_RUL_M4_E_OFFSET 0x20 +#define EHMAC_RUL_M4_NR_E 96 + +#define CTAGGEDM +#define EHMAC_RUL_M4_CTAGGEDM_BOFFSET 5 +#define EHMAC_RUL_M4_CTAGGEDM_BLEN 1 +#define EHMAC_RUL_M4_CTAGGEDM_FLAG HSL_RW + +#define CTAGGEDV +#define EHMAC_RUL_M4_CTAGGEDV_BOFFSET 4 +#define EHMAC_RUL_M4_CTAGGEDV_BLEN 1 +#define EHMAC_RUL_M4_CTAGGEDV_FLAG HSL_RW + +#define CVIDMSK +#define EHMAC_RUL_M4_CVIDMSK_BOFFSET 3 +#define EHMAC_RUL_M4_CVIDMSK_BLEN 1 +#define EHMAC_RUL_M4_CVIDMSK_FLAG HSL_RW + + + + + /* PPPoE Session Table Define */ +#define PPPOE_SESSION +#define PPPOE_SESSION_OFFSET 0x5f000 +#define PPPOE_SESSION_E_LENGTH 4 +#define PPPOE_SESSION_E_OFFSET 0x4 +#define PPPOE_SESSION_NR_E 16 + +#define VRF_ID +#define PPPOE_SESSION_VRF_ID_BOFFSET 18 +#define PPPOE_SESSION_VRF_ID_BLEN 3 +#define PPPOE_SESSION_VRF_ID_FLAG HSL_RW + +#define ENTRY_VALID +#define PPPOE_SESSION_ENTRY_VALID_BOFFSET 16 +#define PPPOE_SESSION_ENTRY_VALID_BLEN 2 +#define PPPOE_SESSION_ENTRY_VALID_FLAG HSL_RW + +#define SEESION_ID +#define PPPOE_SESSION_SEESION_ID_BOFFSET 0 +#define PPPOE_SESSION_SEESION_ID_BLEN 16 +#define PPPOE_SESSION_SEESION_ID_FLAG HSL_RW + + + +#define PPPOE_EDIT +#define PPPOE_EDIT_OFFSET 0x02200 +#define PPPOE_EDIT_E_LENGTH 4 +#define PPPOE_EDIT_E_OFFSET 0x10 +#define PPPOE_EDIT_NR_E 16 + +#define EDIT_ID +#define PPPOE_EDIT_EDIT_ID_BOFFSET 0 +#define PPPOE_EDIT_EDIT_ID_BLEN 16 +#define PPPOE_EDIT_EDIT_ID_FLAG HSL_RW + + + + + /* L3 Host Entry Define */ +#define HOST_ENTRY0 +#define HOST_ENTRY0_OFFSET 0x0e80 +#define HOST_ENTRY0_E_LENGTH 4 +#define HOST_ENTRY0_E_OFFSET 0x0 +#define HOST_ENTRY0_NR_E 1 + +#define IP_ADDR +#define HOST_ENTRY0_IP_ADDR_BOFFSET 0 +#define HOST_ENTRY0_IP_ADDR_BLEN 32 +#define HOST_ENTRY0_IP_ADDR_FLAG HSL_RW + + +#define HOST_ENTRY1 +#define HOST_ENTRY1_OFFSET 0x0e84 +#define HOST_ENTRY1_E_LENGTH 4 +#define HOST_ENTRY1_E_OFFSET 0x0 +#define HOST_ENTRY1_NR_E 1 + + +#define HOST_ENTRY2 +#define HOST_ENTRY2_OFFSET 0x0e88 +#define HOST_ENTRY2_E_LENGTH 4 +#define HOST_ENTRY2_E_OFFSET 0x0 +#define HOST_ENTRY2_NR_E 1 + + +#define HOST_ENTRY3 +#define HOST_ENTRY3_OFFSET 0x0e8c +#define HOST_ENTRY3_E_LENGTH 4 +#define HOST_ENTRY3_E_OFFSET 0x0 +#define HOST_ENTRY3_NR_E 1 + + +#define HOST_ENTRY4 +#define HOST_ENTRY4_OFFSET 0x0e90 +#define HOST_ENTRY4_E_LENGTH 4 +#define HOST_ENTRY4_E_OFFSET 0x0 +#define HOST_ENTRY4_NR_E 1 + +#define MAC_ADDR2 +#define HOST_ENTRY4_MAC_ADDR2_BOFFSET 24 +#define HOST_ENTRY4_MAC_ADDR2_BLEN 8 +#define HOST_ENTRY4_MAC_ADDR2_FLAG HSL_RW + +#define MAC_ADDR3 +#define HOST_ENTRY4_MAC_ADDR3_BOFFSET 16 +#define HOST_ENTRY4_MAC_ADDR3_BLEN 8 +#define HOST_ENTRY4_MAC_ADDR3_FLAG HSL_RW + +#define MAC_ADDR4 +#define HOST_ENTRY4_MAC_ADDR4_BOFFSET 8 +#define HOST_ENTRY4_MAC_ADDR4_BLEN 8 +#define HOST_ENTRY4_MAC_ADDR4_FLAG HSL_RW + +#define MAC_ADDR5 +#define HOST_ENTRY4_MAC_ADDR5_BOFFSET 0 +#define HOST_ENTRY4_MAC_ADDR5_BLEN 8 +#define HOST_ENTRY4_MAC_ADDR5_FLAG HSL_RW + +#define HOST_ENTRY5 +#define HOST_ENTRY5_OFFSET 0x0e94 +#define HOST_ENTRY5_E_LENGTH 4 +#define HOST_ENTRY5_E_OFFSET 0x0 +#define HOST_ENTRY5_NR_E 1 + +#define CPU_ADDR +#define HOST_ENTRY5_CPU_ADDR_BOFFSET 31 +#define HOST_ENTRY5_CPU_ADDR_BLEN 1 +#define HOST_ENTRY5_CPU_ADDR_FLAG HSL_RW + +#define SRC_PORT +#define HOST_ENTRY5_SRC_PORT_BOFFSET 28 +#define HOST_ENTRY5_SRC_PORT_BLEN 3 +#define HOST_ENTRY5_SRC_PORT_FLAG HSL_RW + +#define INTF_ID +#define HOST_ENTRY5_INTF_ID_BOFFSET 16 +#define HOST_ENTRY5_INTF_ID_BLEN 12 +#define HOST_ENTRY5_INTF_ID_FLAG HSL_RW + +#define MAC_ADDR0 +#define HOST_ENTRY5_MAC_ADDR0_BOFFSET 8 +#define HOST_ENTRY5_MAC_ADDR0_BLEN 8 +#define HOST_ENTRY5_MAC_ADDR0_FLAG HSL_RW + +#define MAC_ADDR1 +#define HOST_ENTRY5_MAC_ADDR1_BOFFSET 0 +#define HOST_ENTRY5_MAC_ADDR1_BLEN 8 +#define HOST_ENTRY5_MAC_ADDR1_FLAG HSL_RW + + +#define HOST_ENTRY6 +#define HOST_ENTRY6_OFFSET 0x0e98 +#define HOST_ENTRY6_E_LENGTH 4 +#define HOST_ENTRY6_E_OFFSET 0x0 +#define HOST_ENTRY6_NR_E 1 + +#define LB_BIT +#define HOST_ENTRY6_LB_BIT_BOFFSET 19 +#define HOST_ENTRY6_LB_BIT_BLEN 3 +#define HOST_ENTRY6_LB_BIT_FLAG HSL_RW + +#define VRF_ID +#define HOST_ENTRY6_VRF_ID_BOFFSET 16 +#define HOST_ENTRY6_VRF_ID_BLEN 3 +#define HOST_ENTRY6_VRF_ID_FLAG HSL_RW + +#define IP_VER +#define HOST_ENTRY6_IP_VER_BOFFSET 15 +#define HOST_ENTRY6_IP_VER_BLEN 1 +#define HOST_ENTRY6_IP_VER_FLAG HSL_RW + +#define AGE_FLAG +#define HOST_ENTRY6_AGE_FLAG_BOFFSET 12 +#define HOST_ENTRY6_AGE_FLAG_BLEN 3 +#define HOST_ENTRY6_AGE_FLAG_FLAG HSL_RW + +#define PPPOE_EN +#define HOST_ENTRY6_PPPOE_EN_BOFFSET 11 +#define HOST_ENTRY6_PPPOE_EN_BLEN 1 +#define HOST_ENTRY6_PPPOE_EN_FLAG HSL_RW + +#define PPPOE_IDX +#define HOST_ENTRY6_PPPOE_IDX_BOFFSET 7 +#define HOST_ENTRY6_PPPOE_IDX_BLEN 4 +#define HOST_ENTRY6_PPPOE_IDX_FLAG HSL_RW + +#define CNT_EN +#define HOST_ENTRY6_CNT_EN_BOFFSET 6 +#define HOST_ENTRY6_CNT_EN_BLEN 1 +#define HOST_ENTRY6_CNT_EN_FLAG HSL_RW + +#define CNT_IDX +#define HOST_ENTRY6_CNT_IDX_BOFFSET 2 +#define HOST_ENTRY6_CNT_IDX_BLEN 4 +#define HOST_ENTRY6_CNT_IDX_FLAG HSL_RW + +#define ACTION +#define HOST_ENTRY6_ACTION_BOFFSET 0 +#define HOST_ENTRY6_ACTION_BLEN 2 +#define HOST_ENTRY6_ACTION_FLAG HSL_RW + + +#define HOST_ENTRY7 +#define HOST_ENTRY7_OFFSET 0x0e58 +#define HOST_ENTRY7_E_LENGTH 4 +#define HOST_ENTRY7_E_OFFSET 0x0 +#define HOST_ENTRY7_NR_E 1 + +#define TBL_BUSY +#define HOST_ENTRY7_TBL_BUSY_BOFFSET 31 +#define HOST_ENTRY7_TBL_BUSY_BLEN 1 +#define HOST_ENTRY7_TBL_BUSY_FLAG HSL_RW + +#define SPEC_SYNC +#define HOST_ENTRY7_SPEC_SYNC_BOFFSET 23 +#define HOST_ENTRY7_SPEC_SYNC_BLEN 1 +#define HOST_ENTRY7_SPEC_SYNC_FLAG HSL_RW + +#define SPEC_SP +#define HOST_ENTRY7_SPEC_SP_BOFFSET 22 +#define HOST_ENTRY7_SPEC_SP_BLEN 1 +#define HOST_ENTRY7_SPEC_SP_FLAG HSL_RW + +#define SPEC_VID +#define HOST_ENTRY7_SPEC_VID_BOFFSET 21 +#define HOST_ENTRY7_SPEC_VID_BLEN 1 +#define HOST_ENTRY7_SPEC_VID_FLAG HSL_RW + +#define SPEC_PIP +#define HOST_ENTRY7_SPEC_PIP_BOFFSET 20 +#define HOST_ENTRY7_SPEC_PIP_BLEN 1 +#define HOST_ENTRY7_SPEC_PIP_FLAG HSL_RW + +#define SPEC_SIP +#define HOST_ENTRY7_SPEC_SIP_BOFFSET 19 +#define HOST_ENTRY7_SPEC_SIP_BLEN 1 +#define HOST_ENTRY7_SPEC_SIP_FLAG HSL_RW + +#define SPEC_STATUS +#define HOST_ENTRY7_SPEC_STATUS_BOFFSET 18 +#define HOST_ENTRY7_SPEC_STATUS_BLEN 1 +#define HOST_ENTRY7_SPEC_STATUS_FLAG HSL_RW + +#define TBL_IDX +#define HOST_ENTRY7_TBL_IDX_BOFFSET 8 +#define HOST_ENTRY7_TBL_IDX_BLEN 10 +#define HOST_ENTRY7_TBL_IDX_FLAG HSL_RW + +#define TBL_STAUS +#define HOST_ENTRY7_TBL_STAUS_BOFFSET 7 +#define HOST_ENTRY7_TBL_STAUS_BLEN 1 +#define HOST_ENTRY7_TBL_STAUS_FLAG HSL_RW + +#define TBL_SEL +#define HOST_ENTRY7_TBL_SEL_BOFFSET 4 +#define HOST_ENTRY7_TBL_SEL_BLEN 2 +#define HOST_ENTRY7_TBL_SEL_FLAG HSL_RW + +#define ENTRY_FUNC +#define HOST_ENTRY7_ENTRY_FUNC_BOFFSET 0 +#define HOST_ENTRY7_ENTRY_FUNC_BLEN 3 +#define HOST_ENTRY7_ENTRY_FUNC_FLAG HSL_RW + + + + +#define NAT_ENTRY0 +#define NAT_ENTRY0_OFFSET 0x0e80 +#define NAT_ENTRY0_E_LENGTH 4 +#define NAT_ENTRY0_E_OFFSET 0x0 +#define NAT_ENTRY0_NR_E 1 + +#define IP_ADDR +#define NAT_ENTRY0_IP_ADDR_BOFFSET 0 +#define NAT_ENTRY0_IP_ADDR_BLEN 32 +#define NAT_ENTRY0_IP_ADDR_FLAG HSL_RW + + +#define NAT_ENTRY1 +#define NAT_ENTRY1_OFFSET 0x0e84 +#define NAT_ENTRY1_E_LENGTH 4 +#define NAT_ENTRY1_E_OFFSET 0x0 +#define NAT_ENTRY1_NR_E 1 + +#define PRV_IPADDR0 +#define NAT_ENTRY1_PRV_IPADDR0_BOFFSET 24 +#define NAT_ENTRY1_PRV_IPADDR0_BLEN 8 +#define NAT_ENTRY1_PRV_IPADDR0_FLAG HSL_RW + +#define PORT_RANGE +#define NAT_ENTRY1_PORT_RANGE_BOFFSET 16 +#define NAT_ENTRY1_PORT_RANGE_BLEN 8 +#define NAT_ENTRY1_PORT_RANGE_FLAG HSL_RW + +#define PORT_NUM +#define NAT_ENTRY1_PORT_NUM_BOFFSET 0 +#define NAT_ENTRY1_PORT_NUM_BLEN 16 +#define NAT_ENTRY1_PORT_NUM_FLAG HSL_RW + + +#define NAT_ENTRY2 +#define NAT_ENTRY2_OFFSET 0x0e88 +#define NAT_ENTRY2_E_LENGTH 4 +#define NAT_ENTRY2_E_OFFSET 0x0 +#define NAT_ENTRY2_NR_E 1 + +#define HASH_KEY +#define NAT_ENTRY2_HASH_KEY_BOFFSET 30 +#define NAT_ENTRY2_HASH_KEY_BLEN 2 +#define NAT_ENTRY2_HASH_KEY_FLAG HSL_RW + +#define ACTION +#define NAT_ENTRY2_ACTION_BOFFSET 28 +#define NAT_ENTRY2_ACTION_BLEN 2 +#define NAT_ENTRY2_ACTION_FLAG HSL_RW + +#define CNT_EN +#define NAT_ENTRY2_CNT_EN_BOFFSET 27 +#define NAT_ENTRY2_CNT_EN_BLEN 1 +#define NAT_ENTRY2_CNT_EN_FLAG HSL_RW + +#define CNT_IDX +#define NAT_ENTRY2_CNT_IDX_BOFFSET 24 +#define NAT_ENTRY2_CNT_IDX_BLEN 3 +#define NAT_ENTRY2_CNT_IDX_FLAG HSL_RW + +#define PRV_IPADDR1 +#define NAT_ENTRY2_PRV_IPADDR1_BOFFSET 0 +#define NAT_ENTRY2_PRV_IPADDR1_BLEN 24 +#define NAT_ENTRY2_PRV_IPADDR1_FLAG HSL_RW + + +#define NAT_ENTRY3 +#define NAT_ENTRY3_OFFSET 0x0e8c +#define NAT_ENTRY3_E_LENGTH 4 +#define NAT_ENTRY3_E_OFFSET 0x0 +#define NAT_ENTRY3_NR_E 1 + +#define VRF_ID +#define NAT_ENTRY3_VRF_ID_BOFFSET 4 +#define NAT_ENTRY3_VRF_ID_BLEN 3 +#define NAT_ENTRY3_VRF_ID_FLAG HSL_RW + +#define ENTRY_VALID +#define NAT_ENTRY3_ENTRY_VALID_BOFFSET 3 +#define NAT_ENTRY3_ENTRY_VALID_BLEN 1 +#define NAT_ENTRY3_ENTRY_VALID_FLAG HSL_RW + +#define PORT_EN +#define NAT_ENTRY3_PORT_EN_BOFFSET 2 +#define NAT_ENTRY3_PORT_EN_BLEN 1 +#define NAT_ENTRY3_PORT_EN_FLAG HSL_RW + +#define PRO_TYP +#define NAT_ENTRY3_PRO_TYP_BOFFSET 0 +#define NAT_ENTRY3_PRO_TYP_BLEN 2 +#define NAT_ENTRY3_PRO_TYP_FLAG HSL_RW + + +#define NAPT_ENTRY0 +#define NAPT_ENTRY0_OFFSET 0x0e80 +#define NAPT_ENTRY0_E_LENGTH 4 +#define NAPT_ENTRY0_E_OFFSET 0x0 +#define NAPT_ENTRY0_NR_E 1 + +#define DST_IPADDR +#define NAPT_ENTRY0_DST_IPADDR_BOFFSET 0 +#define NAPT_ENTRY0_DST_IPADDR_BLEN 32 +#define NAPT_ENTRY0_DST_IPADDR_FLAG HSL_RW + + +#define NAPT_ENTRY1 +#define NAPT_ENTRY1_OFFSET 0x0e84 +#define NAPT_ENTRY1_E_LENGTH 4 +#define NAPT_ENTRY1_E_OFFSET 0x0 +#define NAPT_ENTRY1_NR_E 1 + +#define SRC_PORT +#define NAPT_ENTRY1_SRC_PORT_BOFFSET 16 +#define NAPT_ENTRY1_SRC_PORT_BLEN 16 +#define NAPT_ENTRY1_SRC_PORT_FLAG HSL_RW + +#define DST_PORT +#define NAPT_ENTRY1_DST_PORT_BOFFSET 0 +#define NAPT_ENTRY1_DST_PORT_BLEN 16 +#define NAPT_ENTRY1_DST_PORT_FLAG HSL_RW + + +#define NAPT_ENTRY2 +#define NAPT_ENTRY2_OFFSET 0x0e88 +#define NAPT_ENTRY2_E_LENGTH 4 +#define NAPT_ENTRY2_E_OFFSET 0x0 +#define NAPT_ENTRY2_NR_E 1 + +#define SRC_IPADDR0 +#define NAPT_ENTRY2_SRC_IPADDR0_BOFFSET 20 +#define NAPT_ENTRY2_SRC_IPADDR0_BLEN 12 +#define NAPT_ENTRY2_SRC_IPADDR0_FLAG HSL_RW + +#define TRANS_IPADDR +#define NAPT_ENTRY2_TRANS_IPADDR_BOFFSET 16 +#define NAPT_ENTRY2_TRANS_IPADDR_BLEN 4 +#define NAPT_ENTRY2_TRANS_IPADDR_FLAG HSL_RW + +#define TRANS_PORT +#define NAPT_ENTRY2_TRANS_PORT_BOFFSET 0 +#define NAPT_ENTRY2_TRANS_PORT_BLEN 16 +#define NAPT_ENTRY2_TRANS_PORT_FLAG HSL_RW + + +#define NAPT_ENTRY3 +#define NAPT_ENTRY3_OFFSET 0x0e8c +#define NAPT_ENTRY3_E_LENGTH 4 +#define NAPT_ENTRY3_E_OFFSET 0x0 +#define NAPT_ENTRY3_NR_E 1 + +#define PRIORITY_EN +#define NAPT_ENTRY3_PRIORITY_EN_BOFFSET 31 +#define NAPT_ENTRY3_PRIORITY_EN_BLEN 1 +#define NAPT_ENTRY3_PRIORITY_EN_FLAG HSL_RW + +#define PRIORITY_VAL +#define NAPT_ENTRY3_PRIORITY_VAL_BOFFSET 28 +#define NAPT_ENTRY3_PRIORITY_VAL_BLEN 3 +#define NAPT_ENTRY3_PRIORITY_VAL_FLAG HSL_RW + +#define CNT_EN +#define NAPT_ENTRY3_CNT_EN_BOFFSET 27 +#define NAPT_ENTRY3_CNT_EN_BLEN 1 +#define NAPT_ENTRY3_CNT_EN_FLAG HSL_RW + +#define CNT_IDX +#define NAPT_ENTRY3_CNT_IDX_BOFFSET 24 +#define NAPT_ENTRY3_CNT_IDX_BLEN 3 +#define NAPT_ENTRY3_CNT_IDX_FLAG HSL_RW + +#define PROT_TYP +#define NAPT_ENTRY3_PROT_TYP_BOFFSET 22 +#define NAPT_ENTRY3_PROT_TYP_BLEN 2 +#define NAPT_ENTRY3_PROT_TYP_FLAG HSL_RW + +#define ACTION +#define NAPT_ENTRY3_ACTION_BOFFSET 20 +#define NAPT_ENTRY3_ACTION_BLEN 2 +#define NAPT_ENTRY3_ACTION_FLAG HSL_RW + +#define SRC_IPADDR1 +#define NAPT_ENTRY3_SRC_IPADDR1_BOFFSET 0 +#define NAPT_ENTRY3_SRC_IPADDR1_BLEN 20 +#define NAPT_ENTRY3_SRC_IPADDR1_FLAG HSL_RW + + +#define NAPT_ENTRY4 +#define NAPT_ENTRY4_OFFSET 0x0e90 +#define NAPT_ENTRY4_E_LENGTH 4 +#define NAPT_ENTRY4_E_OFFSET 0x0 +#define NAPT_ENTRY4_NR_E 1 + +#define LOAD_BALANCE +#define NAPT_ENTRY4_LOAD_BALANCE_BOFFSET 19 +#define NAPT_ENTRY4_LOAD_BALANCE_BLEN 3 +#define NAPT_ENTRY4_LOAD_BALANCE_FLAG HSL_RW + +#define FLOW_COOKIE +#define NAPT_ENTRY4_FLOW_COOKIE_BOFFSET 8 +#define NAPT_ENTRY4_FLOW_COOKIE_BLEN 11 +#define NAPT_ENTRY4_FLOW_COOKIE_FLAG HSL_RW + +#define VRF_ID +#define NAPT_ENTRY4_VRF_ID_BOFFSET 5 +#define NAPT_ENTRY4_VRF_ID_BLEN 3 +#define NAPT_ENTRY4_VRF_ID_FLAG HSL_RW + +#define AGE_SYNC +#define NAPT_ENTRY4_AGE_SYNC_BOFFSET 4 +#define NAPT_ENTRY4_AGE_SYNC_BLEN 1 +#define NAPT_ENTRY4_AGE_SYNC_FLAG HSL_RO + +#define AGE_FLAG +#define NAPT_ENTRY4_AGE_FLAG_BOFFSET 0 +#define NAPT_ENTRY4_AGE_FLAG_BLEN 4 +#define NAPT_ENTRY4_AGE_FLAG_FLAG HSL_RW + + +#define ROUTER_CTRL +#define ROUTER_CTRL_OFFSET 0x0e00 +#define ROUTER_CTRL_E_LENGTH 4 +#define ROUTER_CTRL_E_OFFSET 0x0 +#define ROUTER_CTRL_NR_E 1 + +#define ARP_LEARN_MODE +#define ROUTER_CTRL_ARP_LEARN_MODE_BOFFSET 19 +#define ROUTER_CTRL_ARP_LEARN_MODE_BLEN 1 +#define ROUTER_CTRL_ARP_LEARN_MODE_FLAG HSL_RW + +#define GLB_LOCKTIME +#define ROUTER_CTRL_GLB_LOCKTIME_BOFFSET 16 +#define ROUTER_CTRL_GLB_LOCKTIME_BLEN 2 +#define ROUTER_CTRL_GLB_LOCKTIME_FLAG HSL_RW + +#define ARP_AGE_TIME +#define ROUTER_CTRL_ARP_AGE_TIME_BOFFSET 8 +#define ROUTER_CTRL_ARP_AGE_TIME_BLEN 8 +#define ROUTER_CTRL_ARP_AGE_TIME_FLAG HSL_RW + +#define WCMP_HAHS_DP +#define ROUTER_CTRL_WCMP_HAHS_DP_BOFFSET 7 +#define ROUTER_CTRL_WCMP_HAHS_DP_BLEN 1 +#define ROUTER_CTRL_WCMP_HAHS_DP_FLAG HSL_RW + +#define WCMP_HAHS_DIP +#define ROUTER_CTRL_WCMP_HAHS_DIP_BOFFSET 6 +#define ROUTER_CTRL_WCMP_HAHS_DIP_BLEN 1 +#define ROUTER_CTRL_WCMP_HAHS_DIP_FLAG HSL_RW + +#define WCMP_HAHS_SP +#define ROUTER_CTRL_WCMP_HAHS_SP_BOFFSET 5 +#define ROUTER_CTRL_WCMP_HAHS_SP_BLEN 1 +#define ROUTER_CTRL_WCMP_HAHS_SP_FLAG HSL_RW + +#define WCMP_HAHS_SIP +#define ROUTER_CTRL_WCMP_HAHS_SIP_BOFFSET 4 +#define ROUTER_CTRL_WCMP_HAHS_SIP_BLEN 1 +#define ROUTER_CTRL_WCMP_HAHS_SIP_FLAG HSL_RW + +#define ARP_AGE_MODE +#define ROUTER_CTRL_ARP_AGE_MODE_BOFFSET 1 +#define ROUTER_CTRL_ARP_AGE_MODE_BLEN 1 +#define ROUTER_CTRL_ARP_AGE_MODE_FLAG HSL_RW + +#define ROUTER_EN +#define ROUTER_CTRL_ROUTER_EN_BOFFSET 0 +#define ROUTER_CTRL_ROUTER_EN_BLEN 1 +#define ROUTER_CTRL_ROUTER_EN_FLAG HSL_RW + + + + +#define ROUTER_PTCTRL0 +#define ROUTER_PTCTRL0_OFFSET 0x0e04 +#define ROUTER_PTCTRL0_E_LENGTH 4 +#define ROUTER_PTCTRL0_E_OFFSET 0x0 +#define ROUTER_PTCTRL0_NR_E 1 + + + + +#define ROUTER_PTCTRL1 +#define ROUTER_PTCTRL1_OFFSET 0x0e08 +#define ROUTER_PTCTRL1_E_LENGTH 4 +#define ROUTER_PTCTRL1_E_OFFSET 0x0 +#define ROUTER_PTCTRL1_NR_E 1 + + + +#define ROUTER_PTCTRL2 +#define ROUTER_PTCTRL2_OFFSET 0x0e0c +#define ROUTER_PTCTRL2_E_LENGTH 4 +#define ROUTER_PTCTRL2_E_OFFSET 0x0 +#define ROUTER_PTCTRL2_NR_E 1 + +#define ARP_PT_UP +#define ROUTER_PTCTRL2_ARP_PT_UP_BOFFSET 16 +#define ROUTER_PTCTRL2_ARP_PT_UP_BLEN 7 +#define ROUTER_PTCTRL2_ARP_PT_UP_FLAG HSL_RW + +#define ARP_LEARN_ACK +#define ROUTER_PTCTRL2_ARP_LEARN_ACK_BOFFSET 8 +#define ROUTER_PTCTRL2_ARP_LEARN_ACK_BLEN 7 +#define ROUTER_PTCTRL2_ARP_LEARN_ACK_FLAG HSL_RW + +#define ARP_LEARN_REQ +#define ROUTER_PTCTRL2_ARP_LEARN_REQ_BOFFSET 0 +#define ROUTER_PTCTRL2_ARP_LEARN_REQ_BLEN 7 +#define ROUTER_PTCTRL2_ARP_LEARN_REQ_FLAG HSL_RW + + + + +#define NAT_CTRL +#define NAT_CTRL_OFFSET 0x0e38 +#define NAT_CTRL_E_LENGTH 4 +#define NAT_CTRL_E_OFFSET 0x0 +#define NAT_CTRL_NR_E 1 + +#define NAT_HASH_MODE +#define NAT_CTRL_NAT_HASH_MODE_BOFFSET 5 +#define NAT_CTRL_NAT_HASH_MODE_BLEN 2 +#define NAT_CTRL_NAT_HASH_MODE_FLAG HSL_RW + +#define NAPT_OVERRIDE +#define NAT_CTRL_NAPT_OVERRIDE_BOFFSET 4 +#define NAT_CTRL_NAPT_OVERRIDE_BLEN 1 +#define NAT_CTRL_NAPT_OVERRIDE_FLAG HSL_RW + +#define NAPT_MODE +#define NAT_CTRL_NAPT_MODE_BOFFSET 2 +#define NAT_CTRL_NAPT_MODE_BLEN 2 +#define NAT_CTRL_NAPT_MODE_FLAG HSL_RW + +#define NAT_EN +#define NAT_CTRL_NAT_EN_BOFFSET 1 +#define NAT_CTRL_NAT_EN_BLEN 1 +#define NAT_CTRL_NAT_EN_FLAG HSL_RW + +#define NAPT_EN +#define NAT_CTRL_NAPT_EN_BOFFSET 0 +#define NAT_CTRL_NAPT_EN_BLEN 1 +#define NAT_CTRL_NAPT_EN_FLAG HSL_RW + + + +#define FlOW_CMD_CTL +#define FlOW_CMD_CTL_OFFSET 0x0ea0 +#define FlOW_CMD_CTL_E_LENGTH 4 +#define FlOW_CMD_CTL_E_OFFSET 0x4 +#define FlOW_CMD_CTL_NR_E 8 + +#define LAN_2_LAN_DEFAULT +#define FlOW_CMD_CTL_LAN_2_LAN_DEFAULT_BOFFSET 26 +#define FlOW_CMD_CTL_LAN_2_LAN_DEFAULT_BLEN 2 +#define FlOW_CMD_CTL_LAN_2_LAN_DEFAULT_FLAG HSL_RW + +#define WAN_2_LAN_DEFAULT +#define FlOW_CMD_CTL_WAN_2_LAN_DEFAULT_BOFFSET 24 +#define FlOW_CMD_CTL_WAN_2_LAN_DEFAULT_BLEN 2 +#define FlOW_CMD_CTL_WAN_2_LAN_DEFAULT_FLAG HSL_RW + +#define LAN_2_WAN_DEFAULT +#define FlOW_CMD_CTL_LAN_2_WAN_DEFAULT_BOFFSET 22 +#define FlOW_CMD_CTL_LAN_2_WAN_DEFAULT_BLEN 2 +#define FlOW_CMD_CTL_LAN_2_WAN_DEFAULT_FLAG HSL_RW + +#define WAN_2_WAN_DEFAULT +#define FlOW_CMD_CTL_WAN_2_WAN_DEFAULT_BOFFSET 20 +#define FlOW_CMD_CTL_WAN_2_WAN_DEFAULT_BLEN 2 +#define FlOW_CMD_CTL_WAN_2_WAN_DEFAULT_FLAG HSL_RW + + +#define FlOW_RT_CMD_CTL +#define FlOW_RT_CMD_CTL_OFFSET 0x0ec0 +#define FlOW_RT_CMD_CTL_E_LENGTH 4 +#define FlOW_RT_CMD_CTL_E_OFFSET 0x4 +#define FlOW_RT_CMD_CTL_NR_E 8 + +#define LAN_2_LAN_DEFAULT +#define FlOW_RT_CMD_CTL_LAN_2_LAN_DEFAULT_BOFFSET 26 +#define FlOW_RT_CMD_CTL_LAN_2_LAN_DEFAULT_BLEN 2 +#define FlOW_RT_CMD_CTL_LAN_2_LAN_DEFAULT_FLAG HSL_RW + +#define WAN_2_LAN_DEFAULT +#define FlOW_RT_CMD_CTL_WAN_2_LAN_DEFAULT_BOFFSET 24 +#define FlOW_RT_CMD_CTL_WAN_2_LAN_DEFAULT_BLEN 2 +#define FlOW_RT_CMD_CTL_WAN_2_LAN_DEFAULT_FLAG HSL_RW + +#define LAN_2_WAN_DEFAULT +#define FlOW_RT_CMD_CTL_LAN_2_WAN_DEFAULT_BOFFSET 22 +#define FlOW_RT_CMD_CTL_LAN_2_WAN_DEFAULT_BLEN 2 +#define FlOW_RT_CMD_CTL_LAN_2_WAN_DEFAULT_FLAG HSL_RW + +#define WAN_2_WAN_DEFAULT +#define FlOW_RT_CMD_CTL_WAN_2_WAN_DEFAULT_BOFFSET 20 +#define FlOW_RT_CMD_CTL_WAN_2_WAN_DEFAULT_BLEN 2 +#define FlOW_RT_CMD_CTL_WAN_2_WAN_DEFAULT_FLAG HSL_RW + + + +#define PRV_BASEADDR +#define PRV_BASEADDR_OFFSET 0x0e5c +#define PRV_BASEADDR_E_LENGTH 4 +#define PRV_BASEADDR_E_OFFSET 0x0 +#define PRV_BASEADDR_NR_E 1 + +#define IP4_ADDR +#define PRV_BASEADDR_IP4_ADDR_BOFFSET 0 +#define PRV_BASEADDR_IP4_ADDR_BLEN 20 +#define PRV_BASEADDR_IP4_ADDR_FLAG HSL_RW + + + + +#define PRVIP_ADDR +#define PRVIP_ADDR_OFFSET 0x0470 +#define PRVIP_ADDR_E_LENGTH 4 +#define PRVIP_ADDR_E_OFFSET 0x0 +#define PRVIP_ADDR_NR_E 1 + +#define IP4_BASEADDR +#define PRVIP_ADDR_IP4_BASEADDR_BOFFSET 0 +#define PRVIP_ADDR_IP4_BASEADDR_BLEN 32 +#define PRVIP_ADDR_IP4_BASEADDR_FLAG HSL_RW + + +#define PRVIP_MASK +#define PRVIP_MASK_OFFSET 0x0474 +#define PRVIP_MASK_E_LENGTH 4 +#define PRVIP_MASK_E_OFFSET 0x0 +#define PRVIP_MASK_NR_E 1 + +#define IP4_BASEMASK +#define PRVIP_MASK_IP4_BASEMASK_BOFFSET 0 +#define PRVIP_MASK_IP4_BASEMASK_BLEN 32 +#define PRVIP_MASK_IP4_BASEMASK_FLAG HSL_RW + + + + +#define PUB_ADDR0 +#define PUB_ADDR0_OFFSET 0x5aa00 +#define PUB_ADDR0_E_LENGTH 4 +#define PUB_ADDR0_E_OFFSET 0x0 +#define PUB_ADDR0_NR_E 1 + +#define IP4_ADDR +#define PUB_ADDR0_IP4_ADDR_BOFFSET 0 +#define PUB_ADDR0_IP4_ADDR_BLEN 32 +#define PUB_ADDR0_IP4_ADDR_FLAG HSL_RW + + +#define PUB_ADDR1 +#define PUB_ADDR1_OFFSET 0x5aa04 +#define PUB_ADDR1_E_LENGTH 4 +#define PUB_ADDR1_E_OFFSET 0x0 +#define PUB_ADDR1_NR_E 1 + +#define ADDR_VALID +#define PUB_ADDR1_ADDR_VALID_BOFFSET 0 +#define PUB_ADDR1_ADDR_VALID_BLEN 1 +#define PUB_ADDR1_ADDR_VALID_FLAG HSL_RW + + + + +#define INTF_ADDR_ENTRY0 +#define INTF_ADDR_ENTRY0_OFFSET 0x5aa00 +#define INTF_ADDR_ENTRY0_E_LENGTH 4 +#define INTF_ADDR_ENTRY0_E_OFFSET 0x0 +#define INTF_ADDR_ENTRY0_NR_E 8 + +#define MAC_ADDR2 +#define INTF_ADDR_ENTRY0_MAC_ADDR2_BOFFSET 24 +#define INTF_ADDR_ENTRY0_MAC_ADDR2_BLEN 8 +#define INTF_ADDR_ENTRY0_MAC_ADDR2_FLAG HSL_RW + +#define MAC_ADDR3 +#define INTF_ADDR_ENTRY0_MAC_ADDR3_BOFFSET 16 +#define INTF_ADDR_ENTRY0_MAC_ADDR3_BLEN 8 +#define INTF_ADDR_ENTRY0_MAC_ADDR3_FLAG HSL_RW + +#define MAC_ADDR4 +#define INTF_ADDR_ENTRY0_MAC_ADDR4_BOFFSET 8 +#define INTF_ADDR_ENTRY0_MAC_ADDR4_BLEN 8 +#define INTF_ADDR_ENTRY0_MAC_ADDR4_FLAG HSL_RW + +#define MAC_ADDR5 +#define INTF_ADDR_ENTRY0_MAC_ADDR5_BOFFSET 0 +#define INTF_ADDR_ENTRY0_MAC_ADDR5_BLEN 8 +#define INTF_ADDR_ENTRY0_MAC_ADDR5_FLAG HSL_RW + + +#define INTF_ADDR_ENTRY1 +#define INTF_ADDR_ENTRY1_OFFSET 0x5aa04 +#define INTF_ADDR_ENTRY1_E_LENGTH 4 +#define INTF_ADDR_ENTRY1_E_OFFSET 0x0 +#define INTF_ADDR_ENTRY1_NR_E 8 + +#define VID_HIGH0 +#define INTF_ADDR_ENTRY1_VID_HIGH0_BOFFSET 28 +#define INTF_ADDR_ENTRY1_VID_HIGH0_BLEN 4 +#define INTF_ADDR_ENTRY1_VID_HIGH0_FLAG HSL_RW + +#define VID_LOW +#define INTF_ADDR_ENTRY1_VID_LOW_BOFFSET 16 +#define INTF_ADDR_ENTRY1_VID_LOW_BLEN 12 +#define INTF_ADDR_ENTRY1_VID_LOW_FLAG HSL_RW + +#define MAC_ADDR0 +#define INTF_ADDR_ENTRY1_MAC_ADDR0_BOFFSET 8 +#define INTF_ADDR_ENTRY1_MAC_ADDR0_BLEN 8 +#define INTF_ADDR_ENTRY1_MAC_ADDR0_FLAG HSL_RW + +#define MAC_ADDR1 +#define INTF_ADDR_ENTRY1_MAC_ADDR1_BOFFSET 0 +#define INTF_ADDR_ENTRY1_MAC_ADDR1_BLEN 8 +#define INTF_ADDR_ENTRY1_MAC_ADDR1_FLAG HSL_RW + + +#define INTF_ADDR_ENTRY2 +#define INTF_ADDR_ENTRY2_OFFSET 0x5aa08 +#define INTF_ADDR_ENTRY2_E_LENGTH 4 +#define INTF_ADDR_ENTRY2_E_OFFSET 0x0 +#define INTF_ADDR_ENTRY2_NR_E 8 + +#define VRF_ID +#define INTF_ADDR_ENTRY2_VRF_ID_BOFFSET 10 +#define INTF_ADDR_ENTRY2_VRF_ID_BLEN 3 +#define INTF_ADDR_ENTRY2_VRF_ID_FLAG HSL_RW + +#define IP6_ROUTE +#define INTF_ADDR_ENTRY2_IP6_ROUTE_BOFFSET 9 +#define INTF_ADDR_ENTRY2_IP6_ROUTE_BLEN 1 +#define INTF_ADDR_ENTRY2_IP6_ROUTE_FLAG HSL_RW + +#define IP4_ROUTE +#define INTF_ADDR_ENTRY2_IP4_ROUTE_BOFFSET 8 +#define INTF_ADDR_ENTRY2_IP4_ROUTE_BLEN 1 +#define INTF_ADDR_ENTRY2_IP4_ROUTE_FLAG HSL_RW + +#define VID_HIGH1 +#define INTF_ADDR_ENTRY2_VID_HIGH1_BOFFSET 0 +#define INTF_ADDR_ENTRY2_VID_HIGH1_BLEN 8 +#define INTF_ADDR_ENTRY2_VID_HIGH1_FLAG HSL_RW + + +#define IP4_DEFAULT_ROUTE_ENTRY +#define IP4_DEFAULT_ROUTE_ENTRY_OFFSET 0x004c4 +#define IP4_DEFAULT_ROUTE_ENTRY_E_LENGTH 4 +#define IP4_DEFAULT_ROUTE_ENTRY_E_OFFSET 0x0 +#define IP4_DEFAULT_ROUTE_ENTRY_NR_E 8 + +#define VALID +#define IP4_DEFAULT_ROUTE_ENTRY_VALID_BOFFSET 11 +#define IP4_DEFAULT_ROUTE_ENTRY_VALID_BLEN 1 +#define IP4_DEFAULT_ROUTE_ENTRY_VALID_FLAG HSL_RW + +#define VRF +#define IP4_DEFAULT_ROUTE_ENTRY_VRF_BOFFSET 8 +#define IP4_DEFAULT_ROUTE_ENTRY_VRF_BLEN 3 +#define IP4_DEFAULT_ROUTE_ENTRY_VRF_FLAG HSL_RW + +#define ARP_WCMP_TYPE +#define IP4_DEFAULT_ROUTE_ENTRY_ARP_WCMP_TYPE_BOFFSET 7 +#define IP4_DEFAULT_ROUTE_ENTRY_ARP_WCMP_TYPE_BLEN 1 +#define IP4_DEFAULT_ROUTE_ENTRY_ARP_WCMP_TYPE_FLAG HSL_RW + +#define ARP_WCMP_INDEX +#define IP4_DEFAULT_ROUTE_ENTRY_ARP_WCMP_INDEX_BOFFSET 0 +#define IP4_DEFAULT_ROUTE_ENTRY_ARP_WCMP_INDEX_BLEN 7 +#define IP4_DEFAULT_ROUTE_ENTRY_ARP_WCMP_INDEX_FLAG HSL_RW + +#define IP6_DEFAULT_ROUTE_ENTRY +#define IP6_DEFAULT_ROUTE_ENTRY_OFFSET 0x004c4 +#define IP6_DEFAULT_ROUTE_ENTRY_E_LENGTH 4 +#define IP6_DEFAULT_ROUTE_ENTRY_E_OFFSET 0x0 +#define IP6_DEFAULT_ROUTE_ENTRY_NR_E 8 + +#define VALID +#define IP6_DEFAULT_ROUTE_ENTRY_VALID_BOFFSET 11 +#define IP6_DEFAULT_ROUTE_ENTRY_VALID_BLEN 1 +#define IP6_DEFAULT_ROUTE_ENTRY_VALID_FLAG HSL_RW + +#define VRF +#define IP6_DEFAULT_ROUTE_ENTRY_VRF_BOFFSET 8 +#define IP6_DEFAULT_ROUTE_ENTRY_VRF_BLEN 3 +#define IP6_DEFAULT_ROUTE_ENTRY_VRF_FLAG HSL_RW + +#define ARP_WCMP_TYPE +#define IP6_DEFAULT_ROUTE_ENTRY_ARP_WCMP_TYPE_BOFFSET 7 +#define IP6_DEFAULT_ROUTE_ENTRY_ARP_WCMP_TYPE_BLEN 1 +#define IP6_DEFAULT_ROUTE_ENTRY_ARP_WCMP_TYPE_FLAG HSL_RW + +#define ARP_WCMP_INDEX +#define IP6_DEFAULT_ROUTE_ENTRY_ARP_WCMP_INDEX_BOFFSET 0 +#define IP6_DEFAULT_ROUTE_ENTRY_ARP_WCMP_INDEX_BLEN 7 +#define IP6_DEFAULT_ROUTE_ENTRY_ARP_WCMP_INDEX_FLAG HSL_RW + +#define IP4_HOST_ROUTE_ENTRY0 +#define IP4_HOST_ROUTE_ENTRY0_OFFSET 0x5b000 +#define IP4_HOST_ROUTE_ENTRY0_E_LENGTH 4 +#define IP4_HOST_ROUTE_ENTRY0_E_OFFSET 0x0 +#define IP4_HOST_ROUTE_ENTRY0_NR_E 16 + +#define IP4_ADDRL +#define IP4_HOST_ROUTE_ENTRY0_IP4_ADDRL_BOFFSET 5 +#define IP4_HOST_ROUTE_ENTRY0_IP4_ADDRL_BLEN 27 +#define IP4_HOST_ROUTE_ENTRY0_IP4_ADDRL_FLAG HSL_RW + +#define PREFIX_LENGTH +#define IP4_HOST_ROUTE_ENTRY0_PREFIX_LENGTH_BOFFSET 0 +#define IP4_HOST_ROUTE_ENTRY0_PREFIX_LENGTH_BLEN 5 +#define IP4_HOST_ROUTE_ENTRY0_PREFIX_LENGTH_FLAG HSL_RW + +#define IP4_HOST_ROUTE_ENTRY1 +#define IP4_HOST_ROUTE_ENTRY1_OFFSET 0x5b004 +#define IP4_HOST_ROUTE_ENTRY1_E_LENGTH 4 +#define IP4_HOST_ROUTE_ENTRY1_E_OFFSET 0x0 +#define IP4_HOST_ROUTE_ENTRY1_NR_E 16 + +#define VALID +#define IP4_HOST_ROUTE_ENTRY1_VALID_BOFFSET 8 +#define IP4_HOST_ROUTE_ENTRY1_VALID_BLEN 1 +#define IP4_HOST_ROUTE_ENTRY1_VALID_FLAG HSL_RW + +#define VRF +#define IP4_HOST_ROUTE_ENTRY1_VRF_BOFFSET 5 +#define IP4_HOST_ROUTE_ENTRY1_VRF_BLEN 3 +#define IP4_HOST_ROUTE_ENTRY1_VRF_FLAG HSL_RW + +#define IP4_ADDRH +#define IP4_HOST_ROUTE_ENTRY1_IP4_ADDRH_BOFFSET 0 +#define IP4_HOST_ROUTE_ENTRY1_IP4_ADDRH_BLEN 5 +#define IP4_HOST_ROUTE_ENTRY1_IP4_ADDRH_FLAG HSL_RW + +#define IP6_HOST_ROUTE_ENTRY0 +#define IP6_HOST_ROUTE_ENTRY0_OFFSET 0x5b100 +#define IP6_HOST_ROUTE_ENTRY0_E_LENGTH 4 +#define IP6_HOST_ROUTE_ENTRY0_E_OFFSET 0x0 +#define IP6_HOST_ROUTE_ENTRY0_NR_E 16 + +#define PREFIX_LENGTH +#define IP6_HOST_ROUTE_ENTRY0_PREFIX_LENGTH_BOFFSET 0 +#define IP6_HOST_ROUTE_ENTRY0_PREFIX_LENGTH_BLEN 7 +#define IP6_HOST_ROUTE_ENTRY0_PREFIX_LENGTH_FLAG HSL_RW + +#define IP6_ADDR0L +#define IP6_HOST_ROUTE_ENTRY0_IP6_ADDR0L_BOFFSET 7 +#define IP6_HOST_ROUTE_ENTRY0_IP6_ADDR0L_BLEN 25 +#define IP6_HOST_ROUTE_ENTRY0_IP6_ADDR0L_FLAG HSL_RW + +#define IP6_HOST_ROUTE_ENTRY1 +#define IP6_HOST_ROUTE_ENTRY1_OFFSET 0x5b104 +#define IP6_HOST_ROUTE_ENTRY1_E_LENGTH 4 +#define IP6_HOST_ROUTE_ENTRY1_E_OFFSET 0x0 +#define IP6_HOST_ROUTE_ENTRY1_NR_E 16 + +#define IP6_ADDR0H +#define IP6_HOST_ROUTE_ENTRY1_IP6_ADDR0H_BOFFSET 0 +#define IP6_HOST_ROUTE_ENTRY1_IP6_ADDR0H_BLEN 7 +#define IP6_HOST_ROUTE_ENTRY1_IP6_ADDR0H_FLAG HSL_RW + +#define IP6_ADDR1L +#define IP6_HOST_ROUTE_ENTRY1_IP6_ADDR1L_BOFFSET 7 +#define IP6_HOST_ROUTE_ENTRY1_IP6_ADDR1L_BLEN 25 +#define IP6_HOST_ROUTE_ENTRY1_IP6_ADDR1L_FLAG HSL_RW + +#define IP6_HOST_ROUTE_ENTRY2 +#define IP6_HOST_ROUTE_ENTRY2_OFFSET 0x5b108 +#define IP6_HOST_ROUTE_ENTRY2_E_LENGTH 4 +#define IP6_HOST_ROUTE_ENTRY2_E_OFFSET 0x0 +#define IP6_HOST_ROUTE_ENTRY2_NR_E 16 + +#define IP6_ADDR1H +#define IP6_HOST_ROUTE_ENTRY2_IP6_ADDR1H_BOFFSET 0 +#define IP6_HOST_ROUTE_ENTRY2_IP6_ADDR1H_BLEN 7 +#define IP6_HOST_ROUTE_ENTRY2_IP6_ADDR1H_FLAG HSL_RW + +#define IP6_ADDR2L +#define IP6_HOST_ROUTE_ENTRY2_IP6_ADDR2L_BOFFSET 7 +#define IP6_HOST_ROUTE_ENTRY2_IP6_ADDR2L_BLEN 25 +#define IP6_HOST_ROUTE_ENTRY2_IP6_ADDR2L_FLAG HSL_RW + +#define IP6_HOST_ROUTE_ENTRY3 +#define IP6_HOST_ROUTE_ENTRY3_OFFSET 0x5b10c +#define IP6_HOST_ROUTE_ENTRY3_E_LENGTH 4 +#define IP6_HOST_ROUTE_ENTRY3_E_OFFSET 0x0 +#define IP6_HOST_ROUTE_ENTRY3_NR_E 16 + +#define IP6_ADDR2H +#define IP6_HOST_ROUTE_ENTRY3_IP6_ADDR2H_BOFFSET 0 +#define IP6_HOST_ROUTE_ENTRY3_IP6_ADDR2H_BLEN 7 +#define IP6_HOST_ROUTE_ENTRY3_IP6_ADDR2H_FLAG HSL_RW + +#define IP6_ADDR3L +#define IP6_HOST_ROUTE_ENTRY3_IP6_ADDR3L_BOFFSET 7 +#define IP6_HOST_ROUTE_ENTRY3_IP6_ADDR3L_BLEN 25 +#define IP6_HOST_ROUTE_ENTRY3_IP6_ADDR3L_FLAG HSL_RW + +#define IP6_HOST_ROUTE_ENTRY4 +#define IP6_HOST_ROUTE_ENTRY4_OFFSET 0x5b110 +#define IP6_HOST_ROUTE_ENTRY4_E_LENGTH 4 +#define IP6_HOST_ROUTE_ENTRY4_E_OFFSET 0x0 +#define IP6_HOST_ROUTE_ENTRY4_NR_E 16 + +#define IP6_ADDR3H +#define IP6_HOST_ROUTE_ENTRY4_IP6_ADDR3H_BOFFSET 0 +#define IP6_HOST_ROUTE_ENTRY4_IP6_ADDR3H_BLEN 7 +#define IP6_HOST_ROUTE_ENTRY4_IP6_ADDR3H_FLAG HSL_RW + +#define VRF +#define IP6_HOST_ROUTE_ENTRY4_VRF_BOFFSET 7 +#define IP6_HOST_ROUTE_ENTRY4_VRF_BLEN 3 +#define IP6_HOST_ROUTE_ENTRY4_VRF_FLAG HSL_RW + +#define VALID +#define IP6_HOST_ROUTE_ENTRY4_VALID_BOFFSET 10 +#define IP6_HOST_ROUTE_ENTRY4_VALID_BLEN 1 +#define IP6_HOST_ROUTE_ENTRY4_VALID_FLAG HSL_RW + + + /* Port Shaper Register0 */ +#define EG_SHAPER0 +#define EG_SHAPER0_OFFSET 0x0890 +#define EG_SHAPER0_E_LENGTH 4 +#define EG_SHAPER0_E_OFFSET 0x0020 +#define EG_SHAPER0_NR_E 7 + +#define EG_Q1_CIR +#define EG_SHAPER0_EG_Q1_CIR_BOFFSET 16 +#define EG_SHAPER0_EG_Q1_CIR_BLEN 15 +#define EG_SHAPER0_EG_Q1_CIR_FLAG HSL_RW + +#define EG_Q0_CIR +#define EG_SHAPER0_EG_Q0_CIR_BOFFSET 0 +#define EG_SHAPER0_EG_Q0_CIR_BLEN 15 +#define EG_SHAPER0_EG_Q0_CIR_FLAG HSL_RW + + + /* Port Shaper Register1 */ +#define EG_SHAPER1 +#define EG_SHAPER1_OFFSET 0x0894 +#define EG_SHAPER1_E_LENGTH 4 +#define EG_SHAPER1_E_OFFSET 0x0020 +#define EG_SHAPER1_NR_E 7 + +#define EG_Q3_CIR +#define EG_SHAPER1_EG_Q3_CIR_BOFFSET 16 +#define EG_SHAPER1_EG_Q3_CIR_BLEN 15 +#define EG_SHAPER1_EG_Q3_CIR_FLAG HSL_RW + +#define EG_Q2_CIR +#define EG_SHAPER1_EG_Q2_CIR_BOFFSET 0 +#define EG_SHAPER1_EG_Q2_CIR_BLEN 15 +#define EG_SHAPER1_EG_Q2_CIR_FLAG HSL_RW + + + /* Port Shaper Register2 */ +#define EG_SHAPER2 +#define EG_SHAPER2_OFFSET 0x0898 +#define EG_SHAPER2_E_LENGTH 4 +#define EG_SHAPER2_E_OFFSET 0x0020 +#define EG_SHAPER2_NR_E 7 + +#define EG_Q5_CIR +#define EG_SHAPER2_EG_Q5_CIR_BOFFSET 16 +#define EG_SHAPER2_EG_Q5_CIR_BLEN 15 +#define EG_SHAPER2_EG_Q5_CIR_FLAG HSL_RW + +#define EG_Q4_CIR +#define EG_SHAPER2_EG_Q4_CIR_BOFFSET 0 +#define EG_SHAPER2_EG_Q4_CIR_BLEN 15 +#define EG_SHAPER2_EG_Q4_CIR_FLAG HSL_RW + + + /* Port Shaper Register3 */ +#define EG_SHAPER3 +#define EG_SHAPER3_OFFSET 0x089c +#define EG_SHAPER3_E_LENGTH 4 +#define EG_SHAPER3_E_OFFSET 0x0020 +#define EG_SHAPER3_NR_E 7 + +#define EG_Q1_EIR +#define EG_SHAPER3_EG_Q1_EIR_BOFFSET 16 +#define EG_SHAPER3_EG_Q1_EIR_BLEN 15 +#define EG_SHAPER3_EG_Q1_EIR_FLAG HSL_RW + +#define EG_Q0_EIR +#define EG_SHAPER3_EG_Q0_EIR_BOFFSET 0 +#define EG_SHAPER3_EG_Q0_EIR_BLEN 15 +#define EG_SHAPER3_EG_Q0_EIR_FLAG HSL_RW + + + /* Port Shaper Register4 */ +#define EG_SHAPER4 +#define EG_SHAPER4_OFFSET 0x08a0 +#define EG_SHAPER4_E_LENGTH 4 +#define EG_SHAPER4_E_OFFSET 0x0020 +#define EG_SHAPER4_NR_E 7 + +#define EG_Q3_EIR +#define EG_SHAPER4_EG_Q3_EIR_BOFFSET 16 +#define EG_SHAPER4_EG_Q3_EIR_BLEN 15 +#define EG_SHAPER4_EG_Q3_EIR_FLAG HSL_RW + +#define EG_Q2_EIR +#define EG_SHAPER4_EG_Q2_EIR_BOFFSET 0 +#define EG_SHAPER4_EG_Q2_EIR_BLEN 15 +#define EG_SHAPER4_EG_Q2_EIR_FLAG HSL_RW + + + /* Port Shaper Register5 */ +#define EG_SHAPER5 +#define EG_SHAPER5_OFFSET 0x08a4 +#define EG_SHAPER5_E_LENGTH 4 +#define EG_SHAPER5_E_OFFSET 0x0020 +#define EG_SHAPER5_NR_E 7 + +#define EG_Q5_EIR +#define EG_SHAPER5_EG_Q5_EIR_BOFFSET 16 +#define EG_SHAPER5_EG_Q5_EIR_BLEN 15 +#define EG_SHAPER5_EG_Q5_EIR_FLAG HSL_RW + +#define EG_Q4_EIR +#define EG_SHAPER5_EG_Q4_EIR_BOFFSET 0 +#define EG_SHAPER5_EG_Q4_EIR_BLEN 15 +#define EG_SHAPER5_EG_Q4_EIR_FLAG HSL_RW + + + /* Port Shaper Register6 */ +#define EG_SHAPER6 +#define EG_SHAPER6_OFFSET 0x08a8 +#define EG_SHAPER6_E_LENGTH 4 +#define EG_SHAPER6_E_OFFSET 0x0020 +#define EG_SHAPER6_NR_E 7 + +#define EG_Q3_CBS +#define EG_SHAPER6_EG_Q3_CBS_BOFFSET 28 +#define EG_SHAPER6_EG_Q3_CBS_BLEN 3 +#define EG_SHAPER6_EG_Q3_CBS_FLAG HSL_RW + +#define EG_Q3_EBS +#define EG_SHAPER6_EG_Q3_EBS_BOFFSET 24 +#define EG_SHAPER6_EG_Q3_EBS_BLEN 3 +#define EG_SHAPER6_EG_Q3_EBS_FLAG HSL_RW + +#define EG_Q2_CBS +#define EG_SHAPER6_EG_Q2_CBS_BOFFSET 20 +#define EG_SHAPER6_EG_Q2_CBS_BLEN 3 +#define EG_SHAPER6_EG_Q2_CBS_FLAG HSL_RW + +#define EG_Q2_EBS +#define EG_SHAPER6_EG_Q2_EBS_BOFFSET 16 +#define EG_SHAPER6_EG_Q2_EBS_BLEN 3 +#define EG_SHAPER6_EG_Q2_EBS_FLAG HSL_RW + +#define EG_Q1_CBS +#define EG_SHAPER6_EG_Q1_CBS_BOFFSET 12 +#define EG_SHAPER6_EG_Q1_CBS_BLEN 3 +#define EG_SHAPER6_EG_Q1_CBS_FLAG HSL_RW + +#define EG_Q1_EBS +#define EG_SHAPER6_EG_Q1_EBS_BOFFSET 8 +#define EG_SHAPER6_EG_Q1_EBS_BLEN 3 +#define EG_SHAPER6_EG_Q1_EBS_FLAG HSL_RW + +#define EG_Q0_CBS +#define EG_SHAPER6_EG_Q0_CBS_BOFFSET 4 +#define EG_SHAPER6_EG_Q0_CBS_BLEN 3 +#define EG_SHAPER6_EG_Q0_CBS_FLAG HSL_RW + +#define EG_Q0_EBS +#define EG_SHAPER6_EG_Q0_EBS_BOFFSET 0 +#define EG_SHAPER6_EG_Q0_EBS_BLEN 3 +#define EG_SHAPER6_EG_Q0_EBS_FLAG HSL_RW + + + /* Port Shaper Register7 */ +#define EG_SHAPER7 +#define EG_SHAPER7_OFFSET 0x08ac +#define EG_SHAPER7_E_LENGTH 4 +#define EG_SHAPER7_E_OFFSET 0x0020 +#define EG_SHAPER7_NR_E 7 + +#define EG_Q5_CBS +#define EG_SHAPER7_EG_Q5_CBS_BOFFSET 28 +#define EG_SHAPER7_EG_Q5_CBS_BLEN 3 +#define EG_SHAPER7_EG_Q5_CBS_FLAG HSL_RW + +#define EG_Q5_EBS +#define EG_SHAPER7_EG_Q5_EBS_BOFFSET 24 +#define EG_SHAPER7_EG_Q5_EBS_BLEN 3 +#define EG_SHAPER7_EG_Q5_EBS_FLAG HSL_RW + +#define EG_Q4_CBS +#define EG_SHAPER7_EG_Q4_CBS_BOFFSET 20 +#define EG_SHAPER7_EG_Q4_CBS_BLEN 3 +#define EG_SHAPER7_EG_Q4_CBS_FLAG HSL_RW + +#define EG_Q4_EBS +#define EG_SHAPER7_EG_Q4_EBS_BOFFSET 16 +#define EG_SHAPER7_EG_Q4_EBS_BLEN 3 +#define EG_SHAPER7_EG_Q4_EBS_FLAG HSL_RW + +#define EG_Q5_UNIT +#define EG_SHAPER7_EG_Q5_UNIT_BOFFSET 13 +#define EG_SHAPER7_EG_Q5_UNIT_BLEN 1 +#define EG_SHAPER7_EG_Q5_UNIT_FLAG HSL_RW + +#define EG_Q4_UNIT +#define EG_SHAPER7_EG_Q4_UNIT_BOFFSET 12 +#define EG_SHAPER7_EG_Q4_UNIT_BLEN 1 +#define EG_SHAPER7_EG_Q4_UNIT_FLAG HSL_RW + +#define EG_Q3_UNIT +#define EG_SHAPER7_EG_Q3_UNIT_BOFFSET 11 +#define EG_SHAPER7_EG_Q3_UNIT_BLEN 1 +#define EG_SHAPER7_EG_Q3_UNIT_FLAG HSL_RW + +#define EG_Q2_UNIT +#define EG_SHAPER7_EG_Q2_UNIT_BOFFSET 10 +#define EG_SHAPER7_EG_Q2_UNIT_BLEN 1 +#define EG_SHAPER7_EG_Q2_UNIT_FLAG HSL_RW + +#define EG_Q1_UNIT +#define EG_SHAPER7_EG_Q1_UNIT_BOFFSET 9 +#define EG_SHAPER7_EG_Q1_UNIT_BLEN 1 +#define EG_SHAPER7_EG_Q1_UNIT_FLAG HSL_RW + +#define EG_Q0_UNIT +#define EG_SHAPER7_EG_Q0_UNIT_BOFFSET 8 +#define EG_SHAPER7_EG_Q0_UNIT_BLEN 1 +#define EG_SHAPER7_EG_Q0_UNIT_FLAG HSL_RW + +#define EG_PT +#define EG_SHAPER7_EG_PT_BOFFSET 3 +#define EG_SHAPER7_EG_PT_BLEN 1 +#define EG_SHAPER7_EG_PT_FLAG HSL_RW + +#define EG_TS +#define EG_SHAPER7_EG_TS_BOFFSET 0 +#define EG_SHAPER7_EG_TS_BLEN 3 +#define EG_SHAPER7_EG_TS_FLAG HSL_RW + + + + /* ACL Policer Register0 */ +#define ACL_POLICER0 +#define ACL_POLICER0_OFFSET 0x0a00 +#define ACL_POLICER0_E_LENGTH 4 +#define ACL_POLICER0_E_OFFSET 0x0008 +#define ACL_POLICER0_NR_E 32 + +#define ACL_CBS +#define ACL_POLICER0_ACL_CBS_BOFFSET 15 +#define ACL_POLICER0_ACL_CBS_BLEN 3 +#define ACL_POLICER0_ACL_CBS_FLAG HSL_RW + +#define ACL_CIR +#define ACL_POLICER0_ACL_CIR_BOFFSET 0 +#define ACL_POLICER0_ACL_CIR_BLEN 15 +#define ACL_POLICER0_ACL_CIR_FLAG HSL_RW + + + /* ACL Policer Register1 */ +#define ACL_POLICER1 +#define ACL_POLICER1_OFFSET 0x0a04 +#define ACL_POLICER1_E_LENGTH 4 +#define ACL_POLICER1_E_OFFSET 0x0008 +#define ACL_POLICER1_NR_E 32 + +#define ACL_BORROW +#define ACL_POLICER1_ACL_BORROW_BOFFSET 23 +#define ACL_POLICER1_ACL_BORROW_BLEN 1 +#define ACL_POLICER1_ACL_BORROW_FLAG HSL_RW + +#define ACL_UNIT +#define ACL_POLICER1_ACL_UNIT_BOFFSET 22 +#define ACL_POLICER1_ACL_UNIT_BLEN 1 +#define ACL_POLICER1_ACL_UNIT_FLAG HSL_RW + +#define ACL_CF +#define ACL_POLICER1_ACL_CF_BOFFSET 21 +#define ACL_POLICER1_ACL_CF_BLEN 1 +#define ACL_POLICER1_ACL_CF_FLAG HSL_RW + +#define ACL_CM +#define ACL_POLICER1_ACL_CM_BOFFSET 20 +#define ACL_POLICER1_ACL_CM_BLEN 1 +#define ACL_POLICER1_ACL_CM_FLAG HSL_RW + +#define ACL_TS +#define ACL_POLICER1_ACL_TS_BOFFSET 18 +#define ACL_POLICER1_ACL_TS_BLEN 2 +#define ACL_POLICER1_ACL_TS_FLAG HSL_RW + +#define ACL_EBS +#define ACL_POLICER1_ACL_EBS_BOFFSET 15 +#define ACL_POLICER1_ACL_EBS_BLEN 3 +#define ACL_POLICER1_ACL_EBS_FLAG HSL_RW + +#define ACL_EIR +#define ACL_POLICER1_ACL_EIR_BOFFSET 0 +#define ACL_POLICER1_ACL_EIR_BLEN 15 +#define ACL_POLICER1_ACL_EIR_FLAG HSL_RW + + + /* Flow Congestion Drop CTRL0 */ +#define FLOW_CONGE_DROP_CTRL0 +#define FLOW_CONGE_DROP_CTRL0_OFFSET 0x0b74 +#define FLOW_CONGE_DROP_CTRL0_E_LENGTH 4 +#define FLOW_CONGE_DROP_CTRL0_E_OFFSET 4 +#define FLOW_CONGE_DROP_CTRL0_NR_E 1 + +#define EN5 +#define FLOW_CONGE_DROP_CTRL0_EN5_BOFFSET 22 +#define FLOW_CONGE_DROP_CTRL0_EN5_BLEN 6 +#define FLOW_CONGE_DROP_CTRL0_EN5_FLAG HSL_RW + +#define EN4 +#define FLOW_CONGE_DROP_CTRL0_EN4_BOFFSET 18 +#define FLOW_CONGE_DROP_CTRL0_EN4_BLEN 4 +#define FLOW_CONGE_DROP_CTRL0_EN4_FLAG HSL_RW + +#define EN3 +#define FLOW_CONGE_DROP_CTRL0_EN3_BOFFSET 14 +#define FLOW_CONGE_DROP_CTRL0_EN3_BLEN 4 +#define FLOW_CONGE_DROP_CTRL0_EN3_FLAG HSL_RW + +#define EN2 +#define FLOW_CONGE_DROP_CTRL0_EN2_BOFFSET 10 +#define FLOW_CONGE_DROP_CTRL0_EN2_BLEN 4 +#define FLOW_CONGE_DROP_CTRL0_EN2_FLAG HSL_RW + +#define EN1 +#define FLOW_CONGE_DROP_CTRL0_EN1_BOFFSET 6 +#define FLOW_CONGE_DROP_CTRL0_EN1_BLEN 4 +#define FLOW_CONGE_DROP_CTRL0_EN1_FLAG HSL_RW + +#define EN0 +#define FLOW_CONGE_DROP_CTRL0_EN0_BOFFSET 0 +#define FLOW_CONGE_DROP_CTRL0_EN0_BLEN 6 +#define FLOW_CONGE_DROP_CTRL0_EN0_FLAG HSL_RW + + /* Ring Flow Control Threshold Register*/ +#define RING_FLOW_CTRL_THRES +#define RING_FLOW_CTRL_THRES_OFFSET 0x0b80 +#define RING_FLOW_CTRL_THRES_E_LENGTH 4 +#define RING_FLOW_CTRL_THRES_E_OFFSET 4 +#define RING_FLOW_CTRL_THRES_NR_E 8 + +#define XON +#define RING_FLOW_CTRL_THRES_XON_BOFFSET 16 +#define RING_FLOW_CTRL_THRES_XON_BLEN 8 +#define RING_FLOW_CTRL_THRES_XON_FLAG HSL_RW + +#define XOFF +#define RING_FLOW_CTRL_THRES_XOFF_BOFFSET 0 +#define RING_FLOW_CTRL_THRES_XOFF_BLEN 8 +#define RING_FLOW_CTRL_THRES_XOFF_FLAG HSL_RW + + + + + /* ACL Counter Register0 */ +#define ACL_COUNTER0 +#define ACL_COUNTER0_OFFSET 0x1c000 +#define ACL_COUNTER0_E_LENGTH 4 +#define ACL_COUNTER0_E_OFFSET 0x0008 +#define ACL_COUNTER0_NR_E 32 + + /* ACL Counter Register1 */ +#define ACL_COUNTER1 +#define ACL_COUNTER1_OFFSET 0x1c004 +#define ACL_COUNTER1_E_LENGTH 4 +#define ACL_COUNTER1_E_OFFSET 0x0008 +#define ACL_COUNTER1_NR_E 32 + + + + + /* INGRESS Policer Register0 */ +#define INGRESS_POLICER0 +#define INGRESS_POLICER0_OFFSET 0x0b00 +#define INGRESS_POLICER0_E_LENGTH 4 +#define INGRESS_POLICER0_E_OFFSET 0x0010 +#define INGRESS_POLICER0_NR_E 7 + +#define ADD_RATE_BYTE +#define INGRESS_POLICER0_ADD_RATE_BYTE_BOFFSET 24 +#define INGRESS_POLICER0_ADD_RATE_BYTE_BLEN 8 +#define INGRESS_POLICER0_ADD_RATE_BYTE_FLAG HSL_RW + +#define C_ING_TS +#define INGRESS_POLICER0_C_ING_TS_BOFFSET 22 +#define INGRESS_POLICER0_C_ING_TS_BLEN 2 +#define INGRESS_POLICER0_C_ING_TS_FLAG HSL_RW + +#define RATE_MODE +#define INGRESS_POLICER0_RATE_MODE_BOFFSET 20 +#define INGRESS_POLICER0_RATE_MODE_BLEN 1 +#define INGRESS_POLICER0_RATE_MODE_FLAG HSL_RW + +#define INGRESS_CBS +#define INGRESS_POLICER0_INGRESS_CBS_BOFFSET 15 +#define INGRESS_POLICER0_INGRESS_CBS_BLEN 3 +#define INGRESS_POLICER0_INGRESS_CBS_FLAG HSL_RW + +#define INGRESS_CIR +#define INGRESS_POLICER0_INGRESS_CIR_BOFFSET 0 +#define INGRESS_POLICER0_INGRESS_CIR_BLEN 15 +#define INGRESS_POLICER0_INGRESS_CIR_FLAG HSL_RW + + + /* INGRESS Policer Register1 */ +#define INGRESS_POLICER1 +#define INGRESS_POLICER1_OFFSET 0x0b04 +#define INGRESS_POLICER1_E_LENGTH 4 +#define INGRESS_POLICER1_E_OFFSET 0x0010 +#define INGRESS_POLICER1_NR_E 7 + +#define INGRESS_BORROW +#define INGRESS_POLICER1_INGRESS_BORROW_BOFFSET 23 +#define INGRESS_POLICER1_INGRESS_BORROW_BLEN 1 +#define INGRESS_POLICER1_INGRESS_BORROW_FLAG HSL_RW + +#define INGRESS_UNIT +#define INGRESS_POLICER1_INGRESS_UNIT_BOFFSET 22 +#define INGRESS_POLICER1_INGRESS_UNIT_BLEN 1 +#define INGRESS_POLICER1_INGRESS_UNIT_FLAG HSL_RW + +#define INGRESS_CF +#define INGRESS_POLICER1_INGRESS_CF_BOFFSET 21 +#define INGRESS_POLICER1_INGRESS_CF_BLEN 1 +#define INGRESS_POLICER1_INGRESS_CF_FLAG HSL_RW + +#define INGRESS_CM +#define INGRESS_POLICER1_INGRESS_CM_BOFFSET 20 +#define INGRESS_POLICER1_INGRESS_CM_BLEN 1 +#define INGRESS_POLICER1_INGRESS_CM_FLAG HSL_RW + +#define E_ING_TS +#define INGRESS_POLICER1_E_ING_TS_BOFFSET 18 +#define INGRESS_POLICER1_E_ING_TS_BLEN 2 +#define INGRESS_POLICER1_E_ING_TS_FLAG HSL_RW + +#define INGRESS_EBS +#define INGRESS_POLICER1_INGRESS_EBS_BOFFSET 15 +#define INGRESS_POLICER1_INGRESS_EBS_BLEN 3 +#define INGRESS_POLICER1_INGRESS_EBS_FLAG HSL_RW + +#define INGRESS_EIR +#define INGRESS_POLICER1_INGRESS_EIR_BOFFSET 0 +#define INGRESS_POLICER1_INGRESS_EIR_BLEN 15 +#define INGRESS_POLICER1_INGRESS_EIR_FLAG HSL_RW + + + /* INGRESS Policer Register2 */ +#define INGRESS_POLICER2 +#define INGRESS_POLICER2_OFFSET 0x0b08 +#define INGRESS_POLICER2_E_LENGTH 4 +#define INGRESS_POLICER2_E_OFFSET 0x0010 +#define INGRESS_POLICER2_NR_E 7 + +#define C_MUL +#define INGRESS_POLICER2_C_MUL_BOFFSET 15 +#define INGRESS_POLICER2_C_MUL_BLEN 1 +#define INGRESS_POLICER2_C_UNK_MUL_FLAG HSL_RW + +#define C_UNI +#define INGRESS_POLICER2_C_UNI_BOFFSET 14 +#define INGRESS_POLICER2_C_UNI_BLEN 1 +#define INGRESS_POLICER2_C_UNI_FLAG HSL_RW + +#define C_UNK_MUL +#define INGRESS_POLICER2_C_UNK_MUL_BOFFSET 13 +#define INGRESS_POLICER2_C_UNK_MUL_BLEN 1 +#define INGRESS_POLICER2_C_UNK_MUL_FLAG HSL_RW + +#define C_UNK_UNI +#define INGRESS_POLICER2_C_UNK_UNI_BOFFSET 12 +#define INGRESS_POLICER2_C_UNK_UNI_BLEN 1 +#define INGRESS_POLICER2_C_UNK_UNI_FLAG HSL_RW + +#define C_BROAD +#define INGRESS_POLICER2_C_BROAD_BOFFSET 11 +#define INGRESS_POLICER2_C_BROAD_BLEN 1 +#define INGRESS_POLICER2_C_BROAD_FLAG HSL_RW + +#define C_MANAGE +#define INGRESS_POLICER2_C_MANAGC_BOFFSET 10 +#define INGRESS_POLICER2_C_MANAGC_BLEN 1 +#define INGRESS_POLICER2_C_MANAGC_FLAG HSL_RW + +#define C_TCP +#define INGRESS_POLICER2_C_TCP_BOFFSET 9 +#define INGRESS_POLICER2_C_TCP_BLEN 1 +#define INGRESS_POLICER2_C_TCP_FLAG HSL_RW + +#define C_MIRR +#define INGRESS_POLICER2_C_MIRR_BOFFSET 8 +#define INGRESS_POLICER2_C_MIRR_BLEN 1 +#define INGRESS_POLICER2_C_MIRR_FLAG HSL_RW + +#define E_MUL +#define INGRESS_POLICER2_E_MUL_BOFFSET 7 +#define INGRESS_POLICER2_E_MUL_BLEN 1 +#define INGRESS_POLICER2_E_UNK_MUL_FLAG HSL_RW + +#define E_UNI +#define INGRESS_POLICER2_E_UNI_BOFFSET 6 +#define INGRESS_POLICER2_E_UNI_BLEN 1 +#define INGRESS_POLICER2_E_UNI_FLAG HSL_RW + +#define E_UNK_MUL +#define INGRESS_POLICER2_E_UNK_MUL_BOFFSET 5 +#define INGRESS_POLICER2_E_UNK_MUL_BLEN 1 +#define INGRESS_POLICER2_E_UNK_MUL_FLAG HSL_RW + +#define E_UNK_UNI +#define INGRESS_POLICER2_E_UNK_UNI_BOFFSET 4 +#define INGRESS_POLICER2_E_UNK_UNI_BLEN 1 +#define INGRESS_POLICER2_E_UNK_UNI_FLAG HSL_RW + +#define E_BROAD +#define INGRESS_POLICER2_E_BROAD_BOFFSET 3 +#define INGRESS_POLICER2_E_BROAD_BLEN 1 +#define INGRESS_POLICER2_E_BROAD_FLAG HSL_RW + +#define E_MANAGE +#define INGRESS_POLICER2_E_MANAGE_BOFFSET 2 +#define INGRESS_POLICER2_E_MANAGE_BLEN 1 +#define INGRESS_POLICER2_E_MANAGE_FLAG HSL_RW + +#define E_TCP +#define INGRESS_POLICER2_E_TCP_BOFFSET 1 +#define INGRESS_POLICER2_E_TCP_BLEN 1 +#define INGRESS_POLICER2_E_TCP_FLAG HSL_RW + +#define E_MIRR +#define INGRESS_POLICER2_E_MIRR_BOFFSET 0 +#define INGRESS_POLICER2_E_MIRR_BLEN 1 +#define INGRESS_POLICER2_E_MIRR_FLAG HSL_RW + + + + + /* Port Rate Limit2 Register */ +#define WRR_CTRL +#define WRR_CTRL_OFFSET 0x0830 +#define WRR_CTRL_E_LENGTH 4 +#define WRR_CTRL_E_OFFSET 0x0004 +#define WRR_CTRL_NR_E 7 + +#define SCH_MODE +#define WRR_CTRL_SCH_MODE_BOFFSET 30 +#define WRR_CTRL_SCH_MODE_BLEN 2 +#define WRR_CTRL_SCH_MODE_FLAG HSL_RW + +#define Q5_W +#define WRR_CTRL_Q5_W_BOFFSET 25 +#define WRR_CTRL_Q5_W_BLEN 5 +#define WRR_CTRL_Q5_W_FLAG HSL_RW + +#define Q4_W +#define WRR_CTRL_Q4_W_BOFFSET 20 +#define WRR_CTRL_Q4_W_BLEN 5 +#define WRR_CTRL_Q4_W_FLAG HSL_RW + +#define Q3_W +#define WRR_CTRL_Q3_W_BOFFSET 15 +#define WRR_CTRL_Q3_W_BLEN 5 +#define WRR_CTRL_Q3_W_FLAG HSL_RW + +#define Q2_W +#define WRR_CTRL_Q2_W_BOFFSET 10 +#define WRR_CTRL_Q2_W_BLEN 5 +#define WRR_CTRL_Q2_W_FLAG HSL_RW + +#define Q1_W +#define WRR_CTRL_Q1_W_BOFFSET 5 +#define WRR_CTRL_Q1_W_BLEN 5 +#define WRR_CTRL_Q1_W_FLAG HSL_RW + +#define Q0_W +#define WRR_CTRL_Q0_W_BOFFSET 0 +#define WRR_CTRL_Q0_W_BLEN 5 +#define WRR_CTRL_Q0_W_FLAG HSL_RW + +/* Global Interrupt Register0 */ +#define GLOBAL_INT0 +#define GLOBAL_INT0_OFFSET 0x0020 +#define GLOBAL_INT0_E_LENGTH 4 +#define GLOBAL_INT0_E_OFFSET 0 +#define GLOBAL_INT0_NR_E 1 + +/* Global Interrupt Register1 */ +#define GLOBAL_INT1 +#define GLOBAL_INT1_OFFSET 0x0024 +#define GLOBAL_INT1_E_LENGTH 4 +#define GLOBAL_INT1_E_OFFSET 0 +#define GLOBAL_INT1_NR_E 1 + +/* Global Interrupt Mask Register0 */ +#define GLOBAL_INT0_MASK +#define GLOBAL_INT0_MASK_OFFSET 0x0028 +#define GLOBAL_INT0_MASK_E_LENGTH 4 +#define GLOBAL_INT0_MASK_E_OFFSET 0 +#define GLOBAL_INT0_MASK_NR_E 1 + +/* Global Interrupt Mask Register1 */ +#define GLOBAL_INT1_MASK +#define GLOBAL_INT1_MASK_OFFSET 0x002c +#define GLOBAL_INT1_MASK_E_LENGTH 4 +#define GLOBAL_INT1_MASK_E_OFFSET 0 +#define GLOBAL_INT1_MASK_NR_E 1 + + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _DESS_REG_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_reg_access.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_reg_access.h new file mode 100755 index 000000000..5eb04369a --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_reg_access.h @@ -0,0 +1,78 @@ +/* + * 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 _DESS_REG_ACCESS_H_ +#define _DESS_REG_ACCESS_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "sw.h" + + sw_error_t + dess_phy_get(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t * value); + + sw_error_t + dess_phy_set(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t value); + + sw_error_t + dess_reg_get(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t value[], + a_uint32_t value_len); + + sw_error_t + dess_reg_set(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t value[], + a_uint32_t value_len); + + sw_error_t + dess_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 + dess_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 + dess_regsiter_dump(a_uint32_t dev_id,a_uint32_t register_idx, fal_reg_dump_t * reg_dump); + + sw_error_t + dess_debug_regsiter_dump(a_uint32_t dev_id, fal_debug_reg_dump_t * dbg_reg_dump); + + + sw_error_t + dess_reg_access_init(a_uint32_t dev_id, hsl_access_mode mode); + + sw_error_t + dess_access_mode_set(a_uint32_t dev_id, hsl_access_mode mode); + + sw_error_t + dess_phy_dump(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t idx, fal_phy_dump_t * phy_dump); + + sw_error_t + dess_debug_psgmii_self_test(a_uint32_t dev_id, a_bool_t enable, + a_uint32_t times, a_uint32_t * result); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _DESS_REG_ACCESS_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_sec.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_sec.h new file mode 100755 index 000000000..1ef340a61 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_sec.h @@ -0,0 +1,53 @@ +/* + * 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 _DESS_SEC_H_ +#define _DESS_SEC_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_sec.h" + + sw_error_t dess_sec_init(a_uint32_t dev_id); + +#ifdef IN_SEC +#define DESS_SEC_INIT(rv, dev_id) \ + { \ + rv = dess_sec_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define DESS_SEC_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + dess_sec_norm_item_set(a_uint32_t dev_id, fal_norm_item_t item, + void *value); + + HSL_LOCAL sw_error_t + dess_sec_norm_item_get(a_uint32_t dev_id, fal_norm_item_t item, + void *value); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _DESS_SEC_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_stp.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_stp.h new file mode 100755 index 000000000..c1450cd85 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_stp.h @@ -0,0 +1,55 @@ +/* + * 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 _DESS_STP_H_ +#define _DESS_STP_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_stp.h" + + sw_error_t dess_stp_init(a_uint32_t dev_id); + +#ifdef IN_STP +#define DESS_STP_INIT(rv, dev_id) \ + { \ + rv = dess_stp_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define DESS_STP_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + dess_stp_port_state_set(a_uint32_t dev_id, a_uint32_t st_id, + fal_port_t port_id, fal_stp_state_t state); + + + HSL_LOCAL sw_error_t + dess_stp_port_state_get(a_uint32_t dev_id, a_uint32_t st_id, + fal_port_t port_id, fal_stp_state_t * state); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _DESS_STP_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_trunk.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_trunk.h new file mode 100755 index 000000000..60e751a8d --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_trunk.h @@ -0,0 +1,59 @@ +/* + * 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 _DESS_TRUNK_H_ +#define _DESS_TRUNK_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_trunk.h" + + sw_error_t dess_trunk_init(a_uint32_t dev_id); + +#ifdef IN_TRUNK +#define DESS_TRUNK_INIT(rv, dev_id) \ + { \ + rv = dess_trunk_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define DESS_TRUNK_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + dess_trunk_group_set(a_uint32_t dev_id, a_uint32_t trunk_id, + a_bool_t enable, fal_pbmp_t member); + + HSL_LOCAL sw_error_t + dess_trunk_group_get(a_uint32_t dev_id, a_uint32_t trunk_id, + a_bool_t * enable, fal_pbmp_t * member); + + HSL_LOCAL sw_error_t + dess_trunk_hash_mode_set(a_uint32_t dev_id, a_uint32_t hash_mode); + + HSL_LOCAL sw_error_t + dess_trunk_hash_mode_get(a_uint32_t dev_id, a_uint32_t * hash_mode); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _DESS_TRUNK_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_vlan.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_vlan.h new file mode 100755 index 000000000..efe099219 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/dess/dess_vlan.h @@ -0,0 +1,99 @@ +/* + * 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 _DESS_VLAN_H_ +#define _DESS_VLAN_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_vlan.h" + + sw_error_t + dess_vlan_init(a_uint32_t dev_id); + +#ifdef IN_VLAN +#define DESS_VLAN_INIT(rv, dev_id) \ + { \ + rv = dess_vlan_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define DESS_VLAN_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + dess_vlan_entry_append(a_uint32_t dev_id, const fal_vlan_t * vlan_entry); + + + HSL_LOCAL sw_error_t + dess_vlan_create(a_uint32_t dev_id, a_uint32_t vlan_id); + + + HSL_LOCAL sw_error_t + dess_vlan_next(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan); + + + HSL_LOCAL sw_error_t + dess_vlan_find(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan); + + + HSL_LOCAL sw_error_t + dess_vlan_delete(a_uint32_t dev_id, a_uint32_t vlan_id); + + + HSL_LOCAL sw_error_t + dess_vlan_flush(a_uint32_t dev_id); + + + HSL_LOCAL sw_error_t + dess_vlan_fid_set(a_uint32_t dev_id, a_uint32_t vlan_id, a_uint32_t fid); + + + HSL_LOCAL sw_error_t + dess_vlan_fid_get(a_uint32_t dev_id, a_uint32_t vlan_id, a_uint32_t * fid); + + + HSL_LOCAL sw_error_t + dess_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); + + + HSL_LOCAL sw_error_t + dess_vlan_member_del(a_uint32_t dev_id, a_uint32_t vlan_id, fal_port_t port_id); + + + HSL_LOCAL sw_error_t + dess_vlan_learning_state_set(a_uint32_t dev_id, a_uint32_t vlan_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + dess_vlan_learning_state_get(a_uint32_t dev_id, a_uint32_t vlan_id, + a_bool_t * enable); + + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _DESS_VLAN_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_acl.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_acl.h new file mode 100755 index 000000000..2e6794a7a --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_acl.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 garuda_acl GARUDA_ACL + * @{ + */ +#ifndef _GARUDA_ACL_H_ +#define _GARUDA_ACL_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_acl.h" + + sw_error_t + garuda_acl_init(a_uint32_t dev_id); + + sw_error_t + garuda_acl_reset(a_uint32_t dev_id); + +#ifdef IN_ACL +#define GARUDA_ACL_INIT(rv, dev_id) \ + { \ + rv = garuda_acl_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } + +#define GARUDA_ACL_RESET(rv, dev_id) \ + { \ + rv = garuda_acl_reset(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define GARUDA_ACL_INIT(rv, dev_id) +#define GARUDA_ACL_RESET(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + garuda_acl_list_creat(a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t list_pri); + + + + HSL_LOCAL sw_error_t + garuda_acl_list_destroy(a_uint32_t dev_id, a_uint32_t list_id); + + + + HSL_LOCAL sw_error_t + garuda_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); + + + + HSL_LOCAL sw_error_t + garuda_acl_rule_delete(a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t rule_id, a_uint32_t rule_nr); + + + + HSL_LOCAL sw_error_t + garuda_acl_rule_query(a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t rule_id, fal_acl_rule_t * rule); + + + + HSL_LOCAL sw_error_t + garuda_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); + + + HSL_LOCAL sw_error_t + garuda_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); + + + + HSL_LOCAL sw_error_t + garuda_acl_status_set(a_uint32_t dev_id, a_bool_t enable); + + + + HSL_LOCAL sw_error_t + garuda_acl_status_get(a_uint32_t dev_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + garuda_acl_list_dump(a_uint32_t dev_id); + + HSL_LOCAL sw_error_t + garuda_acl_rule_dump(a_uint32_t dev_id); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _GARUDA_ACL_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_api.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_api.h new file mode 100755 index 000000000..d5cd0cab8 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_api.h @@ -0,0 +1,531 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _GARUDA_API_H_ +#define _GARUDA_API_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifdef IN_PORTCONTROL +#define PORTCONTROL_API \ + SW_API_DEF(SW_API_PT_DUPLEX_GET, garuda_port_duplex_get), \ + SW_API_DEF(SW_API_PT_DUPLEX_SET, garuda_port_duplex_set), \ + SW_API_DEF(SW_API_PT_SPEED_GET, garuda_port_speed_get), \ + SW_API_DEF(SW_API_PT_SPEED_SET, garuda_port_speed_set), \ + SW_API_DEF(SW_API_PT_AN_GET, garuda_port_autoneg_status_get), \ + SW_API_DEF(SW_API_PT_AN_ENABLE, garuda_port_autoneg_enable), \ + SW_API_DEF(SW_API_PT_AN_RESTART, garuda_port_autoneg_restart), \ + SW_API_DEF(SW_API_PT_AN_ADV_GET, garuda_port_autoneg_adv_get), \ + SW_API_DEF(SW_API_PT_AN_ADV_SET, garuda_port_autoneg_adv_set), \ + SW_API_DEF(SW_API_PT_HDR_SET, garuda_port_hdr_status_set), \ + SW_API_DEF(SW_API_PT_HDR_GET, garuda_port_hdr_status_get), \ + SW_API_DEF(SW_API_PT_FLOWCTRL_SET, garuda_port_flowctrl_set), \ + SW_API_DEF(SW_API_PT_FLOWCTRL_GET, garuda_port_flowctrl_get), \ + SW_API_DEF(SW_API_PT_FLOWCTRL_MODE_SET, garuda_port_flowctrl_forcemode_set), \ + SW_API_DEF(SW_API_PT_FLOWCTRL_MODE_GET, garuda_port_flowctrl_forcemode_get),\ + SW_API_DEF(SW_API_PT_POWERSAVE_SET, garuda_port_powersave_set), \ + SW_API_DEF(SW_API_PT_POWERSAVE_GET, garuda_port_powersave_get), \ + SW_API_DEF(SW_API_PT_HIBERNATE_SET, garuda_port_hibernate_set), \ + SW_API_DEF(SW_API_PT_HIBERNATE_GET, garuda_port_hibernate_get), \ + SW_API_DEF(SW_API_PT_CDT, garuda_port_cdt), + +#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) \ + 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) \ + SW_API_DESC(SW_API_PT_HIBERNATE_SET) \ + SW_API_DESC(SW_API_PT_HIBERNATE_GET) \ + SW_API_DESC(SW_API_PT_CDT) + +#else +#define PORTCONTROL_API +#define PORTCONTROL_API_PARAM +#endif + +#ifdef IN_VLAN +#define VLAN_API \ + SW_API_DEF(SW_API_VLAN_ADD, garuda_vlan_create), \ + SW_API_DEF(SW_API_VLAN_DEL, garuda_vlan_delete), \ + SW_API_DEF(SW_API_VLAN_MEM_UPDATE, garuda_vlan_member_update), \ + SW_API_DEF(SW_API_VLAN_FIND, garuda_vlan_find), \ + SW_API_DEF(SW_API_VLAN_NEXT, garuda_vlan_next), \ + SW_API_DEF(SW_API_VLAN_APPEND, garuda_vlan_entry_append), + +#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) +#else +#define VLAN_API +#define VLAN_API_PARAM +#endif + +#ifdef IN_PORTVLAN +#define PORTVLAN_API \ + SW_API_DEF(SW_API_PT_ING_MODE_GET, garuda_port_1qmode_get), \ + SW_API_DEF(SW_API_PT_ING_MODE_SET, garuda_port_1qmode_set), \ + SW_API_DEF(SW_API_PT_EG_MODE_GET, garuda_port_egvlanmode_get), \ + SW_API_DEF(SW_API_PT_EG_MODE_SET, garuda_port_egvlanmode_set), \ + SW_API_DEF(SW_API_PT_VLAN_MEM_ADD, garuda_portvlan_member_add), \ + SW_API_DEF(SW_API_PT_VLAN_MEM_DEL, garuda_portvlan_member_del), \ + SW_API_DEF(SW_API_PT_VLAN_MEM_UPDATE, garuda_portvlan_member_update), \ + SW_API_DEF(SW_API_PT_VLAN_MEM_GET, garuda_portvlan_member_get), \ + SW_API_DEF(SW_API_PT_DEF_VID_SET, garuda_port_default_vid_set), \ + SW_API_DEF(SW_API_PT_DEF_VID_GET, garuda_port_default_vid_get), \ + SW_API_DEF(SW_API_PT_FORCE_DEF_VID_SET, garuda_port_force_default_vid_set), \ + SW_API_DEF(SW_API_PT_FORCE_DEF_VID_GET, garuda_port_force_default_vid_get), \ + SW_API_DEF(SW_API_PT_FORCE_PORTVLAN_SET, garuda_port_force_portvlan_set), \ + SW_API_DEF(SW_API_PT_FORCE_PORTVLAN_GET, garuda_port_force_portvlan_get), \ + SW_API_DEF(SW_API_PT_NESTVLAN_SET, garuda_port_nestvlan_set), \ + SW_API_DEF(SW_API_PT_NESTVLAN_GET, garuda_port_nestvlan_get), \ + SW_API_DEF(SW_API_NESTVLAN_TPID_SET, garuda_nestvlan_tpid_set), \ + SW_API_DEF(SW_API_NESTVLAN_TPID_GET, garuda_nestvlan_tpid_get), + +#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) +#else +#define PORTVLAN_API +#define PORTVLAN_API_PARAM +#endif + +#ifdef IN_FDB +#define FDB_API \ + SW_API_DEF(SW_API_FDB_ADD, garuda_fdb_add), \ + SW_API_DEF(SW_API_FDB_DELALL, garuda_fdb_del_all), \ + SW_API_DEF(SW_API_FDB_DELPORT,garuda_fdb_del_by_port), \ + SW_API_DEF(SW_API_FDB_DELMAC, garuda_fdb_del_by_mac), \ + SW_API_DEF(SW_API_FDB_FIRST, garuda_fdb_first), \ + SW_API_DEF(SW_API_FDB_NEXT, garuda_fdb_next), \ + SW_API_DEF(SW_API_FDB_FIND, garuda_fdb_find), \ + SW_API_DEF(SW_API_FDB_PT_LEARN_SET, garuda_fdb_port_learn_set), \ + SW_API_DEF(SW_API_FDB_PT_LEARN_GET, garuda_fdb_port_learn_get), \ + SW_API_DEF(SW_API_FDB_AGE_CTRL_SET, garuda_fdb_age_ctrl_set), \ + SW_API_DEF(SW_API_FDB_AGE_CTRL_GET, garuda_fdb_age_ctrl_get), \ + SW_API_DEF(SW_API_FDB_AGE_TIME_SET, garuda_fdb_age_time_set), \ + SW_API_DEF(SW_API_FDB_AGE_TIME_GET, garuda_fdb_age_time_get), + +#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_AGE_CTRL_SET) \ + SW_API_DESC(SW_API_FDB_AGE_CTRL_GET) \ + SW_API_DESC(SW_API_FDB_AGE_TIME_SET) \ + SW_API_DESC(SW_API_FDB_AGE_TIME_GET) +#else +#define FDB_API +#define FDB_API_PARAM +#endif + +#ifdef IN_ACL +#define ACL_API \ + SW_API_DEF(SW_API_ACL_LIST_CREAT, garuda_acl_list_creat), \ + SW_API_DEF(SW_API_ACL_LIST_DESTROY, garuda_acl_list_destroy), \ + SW_API_DEF(SW_API_ACL_RULE_ADD, garuda_acl_rule_add), \ + SW_API_DEF(SW_API_ACL_RULE_DELETE, garuda_acl_rule_delete), \ + SW_API_DEF(SW_API_ACL_RULE_QUERY, garuda_acl_rule_query), \ + SW_API_DEF(SW_API_ACL_LIST_BIND, garuda_acl_list_bind), \ + SW_API_DEF(SW_API_ACL_LIST_UNBIND, garuda_acl_list_unbind), \ + SW_API_DEF(SW_API_ACL_STATUS_SET, garuda_acl_status_set), \ + SW_API_DEF(SW_API_ACL_STATUS_GET, garuda_acl_status_get), \ + SW_API_DEF(SW_API_ACL_LIST_DUMP, garuda_acl_list_dump), \ + SW_API_DEF(SW_API_ACL_RULE_DUMP, garuda_acl_rule_dump), + +#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) +#else +#define ACL_API +#define ACL_API_PARAM +#endif + +#ifdef IN_QOS +#define QOS_API \ + SW_API_DEF(SW_API_QOS_SCH_MODE_SET, garuda_qos_sch_mode_set), \ + SW_API_DEF(SW_API_QOS_SCH_MODE_GET, garuda_qos_sch_mode_get), \ + SW_API_DEF(SW_API_QOS_QU_TX_BUF_ST_SET, garuda_qos_queue_tx_buf_status_set), \ + SW_API_DEF(SW_API_QOS_QU_TX_BUF_ST_GET, garuda_qos_queue_tx_buf_status_get), \ + SW_API_DEF(SW_API_QOS_QU_TX_BUF_NR_SET, garuda_qos_queue_tx_buf_nr_set), \ + SW_API_DEF(SW_API_QOS_QU_TX_BUF_NR_GET, garuda_qos_queue_tx_buf_nr_get), \ + SW_API_DEF(SW_API_QOS_PT_TX_BUF_ST_SET, garuda_qos_port_tx_buf_status_set), \ + SW_API_DEF(SW_API_QOS_PT_TX_BUF_ST_GET, garuda_qos_port_tx_buf_status_get), \ + SW_API_DEF(SW_API_QOS_PT_TX_BUF_NR_SET, garuda_qos_port_tx_buf_nr_set), \ + SW_API_DEF(SW_API_QOS_PT_TX_BUF_NR_GET, garuda_qos_port_tx_buf_nr_get), \ + SW_API_DEF(SW_API_COSMAP_UP_QU_SET, garuda_cosmap_up_queue_set), \ + SW_API_DEF(SW_API_COSMAP_UP_QU_GET, garuda_cosmap_up_queue_get), \ + SW_API_DEF(SW_API_COSMAP_DSCP_QU_SET, garuda_cosmap_dscp_queue_set), \ + SW_API_DEF(SW_API_COSMAP_DSCP_QU_GET, garuda_cosmap_dscp_queue_get), \ + SW_API_DEF(SW_API_QOS_PT_MODE_SET, garuda_qos_port_mode_set), \ + SW_API_DEF(SW_API_QOS_PT_MODE_GET, garuda_qos_port_mode_get), \ + SW_API_DEF(SW_API_QOS_PT_MODE_PRI_SET, garuda_qos_port_mode_pri_set), \ + SW_API_DEF(SW_API_QOS_PT_MODE_PRI_GET, garuda_qos_port_mode_pri_get), \ + SW_API_DEF(SW_API_QOS_PORT_DEF_UP_SET, garuda_qos_port_default_up_set), \ + SW_API_DEF(SW_API_QOS_PORT_DEF_UP_GET, garuda_qos_port_default_up_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_TX_BUF_NR_SET) \ + SW_API_DESC(SW_API_QOS_PT_TX_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) +#else +#define QOS_API +#define QOS_API_PARAM +#endif + +#ifdef IN_IGMP +#define IGMP_API \ + SW_API_DEF(SW_API_PT_IGMPS_MODE_SET, garuda_port_igmps_status_set), \ + SW_API_DEF(SW_API_PT_IGMPS_MODE_GET, garuda_port_igmps_status_get), \ + SW_API_DEF(SW_API_IGMP_MLD_CMD_SET, garuda_igmp_mld_cmd_set), \ + SW_API_DEF(SW_API_IGMP_MLD_CMD_GET, garuda_igmp_mld_cmd_get), \ + SW_API_DEF(SW_API_IGMP_PT_JOIN_SET, garuda_port_igmp_mld_join_set), \ + SW_API_DEF(SW_API_IGMP_PT_JOIN_GET, garuda_port_igmp_mld_join_get), \ + SW_API_DEF(SW_API_IGMP_PT_LEAVE_SET, garuda_port_igmp_mld_leave_set), \ + SW_API_DEF(SW_API_IGMP_PT_LEAVE_GET, garuda_port_igmp_mld_leave_get), \ + SW_API_DEF(SW_API_IGMP_RP_SET, garuda_igmp_mld_rp_set), \ + SW_API_DEF(SW_API_IGMP_RP_GET, garuda_igmp_mld_rp_get), \ + SW_API_DEF(SW_API_IGMP_ENTRY_CREAT_SET, garuda_igmp_mld_entry_creat_set), \ + SW_API_DEF(SW_API_IGMP_ENTRY_CREAT_GET, garuda_igmp_mld_entry_creat_get), + +#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) +#else +#define IGMP_API +#define IGMP_API_PARAM +#endif + +#ifdef IN_LEAKY +#define LEAKY_API \ + SW_API_DEF(SW_API_UC_LEAKY_MODE_SET, garuda_uc_leaky_mode_set), \ + SW_API_DEF(SW_API_UC_LEAKY_MODE_GET, garuda_uc_leaky_mode_get), \ + SW_API_DEF(SW_API_MC_LEAKY_MODE_SET, garuda_mc_leaky_mode_set), \ + SW_API_DEF(SW_API_MC_LEAKY_MODE_GET, garuda_mc_leaky_mode_get), \ + SW_API_DEF(SW_API_ARP_LEAKY_MODE_SET, garuda_port_arp_leaky_set), \ + SW_API_DEF(SW_API_ARP_LEAKY_MODE_GET, garuda_port_arp_leaky_get), \ + SW_API_DEF(SW_API_PT_UC_LEAKY_MODE_SET, garuda_port_uc_leaky_set), \ + SW_API_DEF(SW_API_PT_UC_LEAKY_MODE_GET, garuda_port_uc_leaky_get), \ + SW_API_DEF(SW_API_PT_MC_LEAKY_MODE_SET, garuda_port_mc_leaky_set), \ + SW_API_DEF(SW_API_PT_MC_LEAKY_MODE_GET, garuda_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, garuda_mirr_analysis_port_set), \ + SW_API_DEF(SW_API_MIRROR_ANALY_PT_GET, garuda_mirr_analysis_port_get), \ + SW_API_DEF(SW_API_MIRROR_IN_PT_SET, garuda_mirr_port_in_set), \ + SW_API_DEF(SW_API_MIRROR_IN_PT_GET, garuda_mirr_port_in_get), \ + SW_API_DEF(SW_API_MIRROR_EG_PT_SET, garuda_mirr_port_eg_set), \ + SW_API_DEF(SW_API_MIRROR_EG_PT_GET, garuda_mirr_port_eg_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) +#else +#define MIRROR_API +#define MIRROR_API_PARAM +#endif + +#ifdef IN_RATE +#define RATE_API \ + SW_API_DEF(SW_API_RATE_QU_EGRL_SET, garuda_rate_queue_egrl_set), \ + SW_API_DEF(SW_API_RATE_QU_EGRL_GET, garuda_rate_queue_egrl_get), \ + SW_API_DEF(SW_API_RATE_PT_EGRL_SET, garuda_rate_port_egrl_set), \ + SW_API_DEF(SW_API_RATE_PT_EGRL_GET, garuda_rate_port_egrl_get), \ + SW_API_DEF(SW_API_RATE_PT_INRL_SET, garuda_rate_port_inrl_set), \ + SW_API_DEF(SW_API_RATE_PT_INRL_GET, garuda_rate_port_inrl_get), \ + SW_API_DEF(SW_API_STORM_CTRL_FRAME_SET, garuda_storm_ctrl_frame_set), \ + SW_API_DEF(SW_API_STORM_CTRL_FRAME_GET, garuda_storm_ctrl_frame_get), \ + SW_API_DEF(SW_API_STORM_CTRL_RATE_SET, garuda_storm_ctrl_rate_set), \ + SW_API_DEF(SW_API_STORM_CTRL_RATE_GET, garuda_storm_ctrl_rate_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) +#else +#define RATE_API +#define RATE_API_PARAM +#endif + +#ifdef IN_STP +#define STP_API \ + SW_API_DEF(SW_API_STP_PT_STATE_SET, garuda_stp_port_state_set), \ + SW_API_DEF(SW_API_STP_PT_STATE_GET, garuda_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, garuda_get_mib_info), \ + SW_API_DEF(SW_API_MIB_STATUS_SET, garuda_mib_status_set), \ + SW_API_DEF(SW_API_MIB_STATUS_GET, garuda_mib_status_get), + +#define MIB_API_PARAM \ + SW_API_DESC(SW_API_PT_MIB_GET) \ + SW_API_DESC(SW_API_MIB_STATUS_SET) \ + SW_API_DESC(SW_API_MIB_STATUS_GET) +#else +#define MIB_API +#define MIB_API_PARAM +#endif + +#ifdef IN_MISC +#define MISC_API \ + SW_API_DEF(SW_API_ARP_STATUS_SET, garuda_arp_status_set), \ + SW_API_DEF(SW_API_ARP_STATUS_GET, garuda_arp_status_get), \ + SW_API_DEF(SW_API_FRAME_MAX_SIZE_SET, garuda_frame_max_size_set), \ + SW_API_DEF(SW_API_FRAME_MAX_SIZE_GET, garuda_frame_max_size_get), \ + SW_API_DEF(SW_API_PT_UNK_SA_CMD_SET, garuda_port_unk_sa_cmd_set), \ + SW_API_DEF(SW_API_PT_UNK_SA_CMD_GET, garuda_port_unk_sa_cmd_get), \ + SW_API_DEF(SW_API_PT_UNK_UC_FILTER_SET, garuda_port_unk_uc_filter_set), \ + SW_API_DEF(SW_API_PT_UNK_UC_FILTER_GET, garuda_port_unk_uc_filter_get), \ + SW_API_DEF(SW_API_PT_UNK_MC_FILTER_SET, garuda_port_unk_mc_filter_set), \ + SW_API_DEF(SW_API_PT_UNK_MC_FILTER_GET, garuda_port_unk_mc_filter_get), \ + SW_API_DEF(SW_API_CPU_PORT_STATUS_SET, garuda_cpu_port_status_set), \ + SW_API_DEF(SW_API_CPU_PORT_STATUS_GET, garuda_cpu_port_status_get), \ + SW_API_DEF(SW_API_BC_TO_CPU_PORT_SET, garuda_bc_to_cpu_port_set), \ + SW_API_DEF(SW_API_BC_TO_CPU_PORT_GET, garuda_bc_to_cpu_port_get), \ + SW_API_DEF(SW_API_PPPOE_CMD_SET, garuda_pppoe_cmd_set), \ + SW_API_DEF(SW_API_PPPOE_CMD_GET, garuda_pppoe_cmd_get), \ + SW_API_DEF(SW_API_PPPOE_STATUS_SET, garuda_pppoe_status_set), \ + SW_API_DEF(SW_API_PPPOE_STATUS_GET, garuda_pppoe_status_get), \ + SW_API_DEF(SW_API_PT_DHCP_SET, garuda_port_dhcp_set), \ + SW_API_DEF(SW_API_PT_DHCP_GET, garuda_port_dhcp_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_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_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_PT_DHCP_SET) \ + SW_API_DESC(SW_API_PT_DHCP_GET) +#else +#define MISC_API +#define MISC_API_PARAM +#endif + +#ifdef IN_LED +#define LED_API \ + SW_API_DEF(SW_API_LED_PATTERN_SET, garuda_led_ctrl_pattern_set), \ + SW_API_DEF(SW_API_LED_PATTERN_GET, garuda_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 + +#define REG_API \ + SW_API_DEF(SW_API_PHY_GET, garuda_phy_get), \ + SW_API_DEF(SW_API_PHY_SET, garuda_phy_set), \ + SW_API_DEF(SW_API_REG_GET, garuda_reg_get), \ + SW_API_DEF(SW_API_REG_SET, garuda_reg_set), \ + SW_API_DEF(SW_API_REG_FIELD_GET, garuda_reg_field_get), \ + SW_API_DEF(SW_API_REG_FIELD_SET, garuda_reg_field_set), + +#define REG_API_PARAM \ + SW_API_DESC(SW_API_PHY_GET) \ + SW_API_DESC(SW_API_PHY_SET) \ + SW_API_DESC(SW_API_REG_GET) \ + SW_API_DESC(SW_API_REG_SET) \ + SW_API_DESC(SW_API_REG_FIELD_GET) \ + SW_API_DESC(SW_API_REG_FIELD_SET) + +#define SSDK_API \ + SW_API_DEF(SW_API_SWITCH_RESET, garuda_reset), \ + SW_API_DEF(SW_API_SSDK_CFG, hsl_ssdk_cfg), \ + PORTCONTROL_API \ + 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 \ + REG_API \ + SW_API_DEF(SW_API_MAX, NULL), + +#define SSDK_PARAM \ + 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"), \ + MIB_API_PARAM \ + LEAKY_API_PARAM \ + MISC_API_PARAM \ + IGMP_API_PARAM \ + MIRROR_API_PARAM \ + PORTCONTROL_API_PARAM \ + PORTVLAN_API_PARAM \ + VLAN_API_PARAM \ + FDB_API_PARAM \ + QOS_API_PARAM \ + RATE_API_PARAM \ + STP_API_PARAM \ + ACL_API_PARAM \ + LED_API_PARAM \ + REG_API_PARAM \ + SW_PARAM_DEF(SW_API_MAX, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), + +#if (defined(USER_MODE) && defined(KERNEL_MODULE)) +#undef SSDK_API +#undef SSDK_PARAM + +#define SSDK_API \ + REG_API \ + SW_API_DEF(SW_API_MAX, NULL), + +#define SSDK_PARAM \ + REG_API_PARAM \ + SW_PARAM_DEF(SW_API_MAX, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _GARUDA_API_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_fdb.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_fdb.h new file mode 100755 index 000000000..b50d2fc67 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_fdb.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 garuda_fdb GARUDA_FDB + * @{ + */ +#ifndef _GARUDA_FDB_H_ +#define _GARUDA_FDB_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_fdb.h" + + sw_error_t + garuda_fdb_init(a_uint32_t dev_id); + +#ifdef IN_FDB +#define GARUDA_FDB_INIT(rv, dev_id) \ + { \ + rv = garuda_fdb_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define GARUDA_FDB_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + garuda_fdb_add(a_uint32_t dev_id, const fal_fdb_entry_t * entry); + + + + HSL_LOCAL sw_error_t + garuda_fdb_del_all(a_uint32_t dev_id, a_uint32_t flag); + + + + HSL_LOCAL sw_error_t + garuda_fdb_del_by_port(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t flag); + + + + HSL_LOCAL sw_error_t + garuda_fdb_del_by_mac(a_uint32_t dev_id, + const fal_fdb_entry_t *entry); + + + + HSL_LOCAL sw_error_t + garuda_fdb_first(a_uint32_t dev_id, fal_fdb_entry_t * entry); + + + + HSL_LOCAL sw_error_t + garuda_fdb_next(a_uint32_t dev_id, fal_fdb_entry_t * entry); + + + + HSL_LOCAL sw_error_t + garuda_fdb_find(a_uint32_t dev_id, fal_fdb_entry_t * entry); + + + + HSL_LOCAL sw_error_t + garuda_fdb_port_learn_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + + HSL_LOCAL sw_error_t + garuda_fdb_port_learn_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable); + + + + HSL_LOCAL sw_error_t + garuda_fdb_age_ctrl_set(a_uint32_t dev_id, a_bool_t enable); + + + + HSL_LOCAL sw_error_t + garuda_fdb_age_ctrl_get(a_uint32_t dev_id, a_bool_t *enable); + + + + HSL_LOCAL sw_error_t + garuda_fdb_age_time_set(a_uint32_t dev_id, a_uint32_t * time); + + + + HSL_LOCAL sw_error_t + garuda_fdb_age_time_get(a_uint32_t dev_id, a_uint32_t * time); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _GARUDA_FDB_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_igmp.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_igmp.h new file mode 100755 index 000000000..487230418 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_igmp.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 garuda_igmp GARUDA_IGMP + * @{ + */ +#ifndef _GARUDA_IGMP_H_ +#define _GARUDA_IGMP_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_igmp.h" + + sw_error_t + garuda_igmp_init(a_uint32_t dev_id); + +#ifdef IN_IGMP +#define GARUDA_IGMP_INIT(rv, dev_id) \ + { \ + rv = garuda_igmp_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define GARUDA_IGMP_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + garuda_port_igmps_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + + HSL_LOCAL sw_error_t + garuda_port_igmps_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable); + + + + HSL_LOCAL sw_error_t + garuda_igmp_mld_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + + + HSL_LOCAL sw_error_t + garuda_igmp_mld_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + + + HSL_LOCAL sw_error_t + garuda_port_igmp_mld_join_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + + HSL_LOCAL sw_error_t + garuda_port_igmp_mld_join_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + + HSL_LOCAL sw_error_t + garuda_port_igmp_mld_leave_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + + HSL_LOCAL sw_error_t + garuda_port_igmp_mld_leave_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + + HSL_LOCAL sw_error_t + garuda_igmp_mld_rp_set(a_uint32_t dev_id, fal_pbmp_t pts); + + + + HSL_LOCAL sw_error_t + garuda_igmp_mld_rp_get(a_uint32_t dev_id, fal_pbmp_t * pts); + + + + HSL_LOCAL sw_error_t + garuda_igmp_mld_entry_creat_set(a_uint32_t dev_id, a_bool_t enable); + + + + HSL_LOCAL sw_error_t + garuda_igmp_mld_entry_creat_get(a_uint32_t dev_id, a_bool_t * enable); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _GARUDA_IGMP_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_init.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_init.h new file mode 100755 index 000000000..b72450115 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_init.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 garuda_init GARUDA_INIT + * @{ + */ +#ifndef _GARUDA_INIT_H_ +#define _GARUDA_INIT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "init/ssdk_init.h" + + sw_error_t + garuda_init(a_uint32_t dev_id, ssdk_init_cfg *cfg); + + sw_error_t + garuda_cleanup(a_uint32_t dev_id); + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + garuda_reset(a_uint32_t dev_id); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _GARUDA_INIT_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_leaky.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_leaky.h new file mode 100755 index 000000000..dfd95ec7f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_leaky.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 garuda_leaky GARUDA_LEAKY + * @{ + */ +#ifndef _GARUDA_LEAKY_H_ +#define _GARUDA_LEAKY_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_leaky.h" + + sw_error_t garuda_leaky_init(a_uint32_t dev_id); + +#ifdef IN_LEAKY +#define GARUDA_LEAKY_INIT(rv, dev_id) \ + { \ + rv = garuda_leaky_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define GARUDA_LEAKY_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + garuda_uc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode); + + + + HSL_LOCAL sw_error_t + garuda_uc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t * ctrl_mode); + + + + HSL_LOCAL sw_error_t + garuda_mc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode); + + + HSL_LOCAL sw_error_t + garuda_mc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t * ctrl_mode); + + + + HSL_LOCAL sw_error_t + garuda_port_arp_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + + HSL_LOCAL sw_error_t + garuda_port_arp_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + + HSL_LOCAL sw_error_t + garuda_port_uc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + + HSL_LOCAL sw_error_t + garuda_port_uc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + garuda_port_mc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + + HSL_LOCAL sw_error_t + garuda_port_mc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _GARUDA_LEAKY_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_led.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_led.h new file mode 100755 index 000000000..16340bf96 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_led.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _GARUDA_LED_H_ +#define _GARUDA_LED_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_led.h" + + sw_error_t + garuda_led_init(a_uint32_t dev_id); + +#ifdef IN_LED +#define GARUDA_LED_INIT(rv, dev_id) \ + { \ + rv = garuda_led_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define GARUDA_LED_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + garuda_led_ctrl_pattern_set(a_uint32_t dev_id, led_pattern_group_t group, + led_pattern_id_t id, led_ctrl_pattern_t * pattern); + + + + HSL_LOCAL sw_error_t + garuda_led_ctrl_pattern_get(a_uint32_t dev_id, led_pattern_group_t group, + led_pattern_id_t id, led_ctrl_pattern_t * pattern); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _GARUDA_LED_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_mib.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_mib.h new file mode 100755 index 000000000..3fc578a90 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_mib.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 garuda_mib GARUDA_MIB + * @{ + */ +#ifndef _GARUDA_MIB_H_ +#define _GARUDA_MIB_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_mib.h" + + sw_error_t + garuda_mib_init(a_uint32_t dev_id); + +#ifdef IN_MIB +#define GARUDA_MIB_INIT(rv, dev_id) \ + { \ + rv = garuda_mib_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define GARUDA_MIB_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + garuda_get_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info ); + + + + HSL_LOCAL sw_error_t + garuda_mib_status_set(a_uint32_t dev_id, a_bool_t enable); + + + + HSL_LOCAL sw_error_t + garuda_mib_status_get(a_uint32_t dev_id, a_bool_t * enable); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _GARUDA_MIB_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_mirror.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_mirror.h new file mode 100755 index 000000000..00f390165 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_mirror.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 garuda_mirror GARUDA_MIRROR + * @{ + */ +#ifndef _GARUDA_MIRROR_H_ +#define _GARUDA_MIRROR_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_mirror.h" + + sw_error_t garuda_mirr_init(a_uint32_t dev_id); + +#ifdef IN_MIRROR +#define GARUDA_MIRR_INIT(rv, dev_id) \ + { \ + rv = garuda_mirr_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define GARUDA_MIRR_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + garuda_mirr_analysis_port_set(a_uint32_t dev_id, fal_port_t port_id); + + + + HSL_LOCAL sw_error_t + garuda_mirr_analysis_port_get(a_uint32_t dev_id, fal_port_t * port_id); + + + + HSL_LOCAL sw_error_t + garuda_mirr_port_in_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + + HSL_LOCAL sw_error_t + garuda_mirr_port_in_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + + HSL_LOCAL sw_error_t + garuda_mirr_port_eg_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + + HSL_LOCAL sw_error_t + garuda_mirr_port_eg_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _GARUDA_MIRROR_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_misc.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_misc.h new file mode 100755 index 000000000..26ee61936 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_misc.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _GARUDA_MISC_H_ +#define _GARUDA_MISC_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_misc.h" + + sw_error_t garuda_misc_init(a_uint32_t dev_id); + +#ifdef IN_MISC +#define GARUDA_MISC_INIT(rv, dev_id) \ + { \ + rv = garuda_misc_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define GARUDA_MISC_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + garuda_arp_status_set(a_uint32_t dev_id, a_bool_t enable); + + + + HSL_LOCAL sw_error_t + garuda_arp_status_get(a_uint32_t dev_id, a_bool_t * enable); + + + + HSL_LOCAL sw_error_t + garuda_frame_max_size_set(a_uint32_t dev_id, a_uint32_t size); + + + + HSL_LOCAL sw_error_t + garuda_frame_max_size_get(a_uint32_t dev_id, a_uint32_t * size); + + + + HSL_LOCAL sw_error_t + garuda_port_unk_sa_cmd_set(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t cmd); + + + + HSL_LOCAL sw_error_t + garuda_port_unk_sa_cmd_get(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t * cmd); + + + + HSL_LOCAL sw_error_t + garuda_port_unk_uc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + + HSL_LOCAL sw_error_t + garuda_port_unk_uc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + + HSL_LOCAL sw_error_t + garuda_port_unk_mc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + + HSL_LOCAL sw_error_t + garuda_port_unk_mc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + + HSL_LOCAL sw_error_t + garuda_cpu_port_status_set(a_uint32_t dev_id, a_bool_t enable); + + + + HSL_LOCAL sw_error_t + garuda_cpu_port_status_get(a_uint32_t dev_id, a_bool_t * enable); + + + + HSL_LOCAL sw_error_t + garuda_bc_to_cpu_port_set(a_uint32_t dev_id, a_bool_t enable); + + + + HSL_LOCAL sw_error_t + garuda_bc_to_cpu_port_get(a_uint32_t dev_id, a_bool_t * enable); + + + + HSL_LOCAL sw_error_t + garuda_pppoe_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + + + HSL_LOCAL sw_error_t + garuda_pppoe_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + + HSL_LOCAL sw_error_t + garuda_pppoe_status_set(a_uint32_t dev_id, a_bool_t enable); + + + + HSL_LOCAL sw_error_t + garuda_pppoe_status_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + garuda_port_dhcp_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + + HSL_LOCAL sw_error_t + garuda_port_dhcp_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _GARUDA_MISC_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_port_ctrl.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_port_ctrl.h new file mode 100755 index 000000000..ebfec946e --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_port_ctrl.h @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 garuda_port_ctrl GARUDA_PORT_CONTROL + * @{ + */ +#ifndef _GARUDA_PORT_CTRL_H_ +#define _GARUDA_PORT_CTRL_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_port_ctrl.h" + + sw_error_t garuda_port_ctrl_init(a_uint32_t dev_id); + +#ifdef IN_PORTCONTROL +#define GARUDA_PORT_CTRL_INIT(rv, dev_id) \ + { \ + rv = garuda_port_ctrl_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define GARUDA_PORT_CTRL_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + garuda_port_duplex_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t duplex); + + + HSL_LOCAL sw_error_t + garuda_port_duplex_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t * pduplex); + + + HSL_LOCAL sw_error_t + garuda_port_speed_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t speed); + + + HSL_LOCAL sw_error_t + garuda_port_speed_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t * pspeed); + + + HSL_LOCAL sw_error_t + garuda_port_autoneg_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status); + + + HSL_LOCAL sw_error_t + garuda_port_autoneg_enable(a_uint32_t dev_id, fal_port_t port_id); + + + HSL_LOCAL sw_error_t + garuda_port_autoneg_restart(a_uint32_t dev_id, fal_port_t port_id); + + HSL_LOCAL sw_error_t + garuda_port_autoneg_adv_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t autoadv); + + + HSL_LOCAL sw_error_t + garuda_port_autoneg_adv_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * autoadv); + + + HSL_LOCAL sw_error_t + garuda_port_hdr_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + garuda_port_hdr_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + garuda_port_flowctrl_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + garuda_port_flowctrl_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + garuda_port_flowctrl_forcemode_set(a_uint32_t dev_id, + fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + garuda_port_flowctrl_forcemode_get(a_uint32_t dev_id, + fal_port_t port_id, + a_bool_t * enable); + + HSL_LOCAL sw_error_t + garuda_port_powersave_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + garuda_port_powersave_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable); + + + HSL_LOCAL sw_error_t + garuda_port_hibernate_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + garuda_port_hibernate_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable); + + + HSL_LOCAL sw_error_t + garuda_port_cdt(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t mdi_pair, + fal_cable_status_t *cable_status, a_uint32_t *cable_len); + + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _GARUDA_PORT_CTRL_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_portvlan.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_portvlan.h new file mode 100755 index 000000000..9fa278b3c --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_portvlan.h @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 garuda_port_vlan GARUDA_PORT_VLAN + * @{ + */ +#ifndef _GARUDA_PORTVLAN_H_ +#define _GARUDA_PORTVLAN_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_portvlan.h" + + sw_error_t garuda_portvlan_init(a_uint32_t dev_id); + +#ifdef IN_PORTVLAN +#define GARUDA_PORTVLAN_INIT(rv, dev_id) \ + { \ + rv = garuda_portvlan_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define GARUDA_PORTVLAN_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + garuda_port_1qmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t port_1qmode); + + + + HSL_LOCAL sw_error_t + garuda_port_1qmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t * pport_1qmode); + + + + HSL_LOCAL sw_error_t + garuda_port_egvlanmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t port_egvlanmode); + + + + HSL_LOCAL sw_error_t + garuda_port_egvlanmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t * pport_egvlanmode); + + + + HSL_LOCAL sw_error_t + garuda_portvlan_member_add(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id); + + + + HSL_LOCAL sw_error_t + garuda_portvlan_member_del(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id); + + + + HSL_LOCAL sw_error_t + garuda_portvlan_member_update(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t mem_port_map); + + + + HSL_LOCAL sw_error_t + garuda_portvlan_member_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t * mem_port_map); + + + + HSL_LOCAL sw_error_t + garuda_port_default_vid_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vid); + + + + HSL_LOCAL sw_error_t + garuda_port_default_vid_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vid); + + + + HSL_LOCAL sw_error_t + garuda_port_force_default_vid_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + + HSL_LOCAL sw_error_t + garuda_port_force_default_vid_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + + HSL_LOCAL sw_error_t + garuda_port_force_portvlan_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + garuda_port_force_portvlan_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + + HSL_LOCAL sw_error_t + garuda_port_nestvlan_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + + HSL_LOCAL sw_error_t + garuda_port_nestvlan_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + HSL_LOCAL sw_error_t + garuda_nestvlan_tpid_set(a_uint32_t dev_id, a_uint32_t tpid); + + + HSL_LOCAL sw_error_t + garuda_nestvlan_tpid_get(a_uint32_t dev_id, a_uint32_t * tpid); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ATHENA_PORTVLAN_H */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_qos.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_qos.h new file mode 100755 index 000000000..2b60f50a3 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_qos.h @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 garuda_qos GARUDA_QOS + * @{ + */ +#ifndef _GARUDA_QOS_H_ +#define _GARUDA_QOS_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_qos.h" + + sw_error_t garuda_qos_init(a_uint32_t dev_id); + +#ifdef IN_QOS +#define GARUDA_QOS_INIT(rv, dev_id) \ + { \ + rv = garuda_qos_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define GARUDA_QOS_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + garuda_qos_sch_mode_set(a_uint32_t dev_id, + fal_sch_mode_t mode, const a_uint32_t weight[]); + + + + HSL_LOCAL sw_error_t + garuda_qos_sch_mode_get(a_uint32_t dev_id, + fal_sch_mode_t * mode, a_uint32_t weight[]); + + + + HSL_LOCAL sw_error_t + garuda_qos_queue_tx_buf_status_set(a_uint32_t dev_id, + fal_port_t port_id, a_bool_t enable); + + + + HSL_LOCAL sw_error_t + garuda_qos_queue_tx_buf_status_get(a_uint32_t dev_id, + fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + garuda_qos_port_tx_buf_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + + HSL_LOCAL sw_error_t + garuda_qos_port_tx_buf_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + + HSL_LOCAL sw_error_t + garuda_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); + + + + HSL_LOCAL sw_error_t + garuda_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); + + + + HSL_LOCAL sw_error_t + garuda_qos_port_tx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number); + + + + HSL_LOCAL sw_error_t + garuda_qos_port_tx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number); + + + + HSL_LOCAL sw_error_t + garuda_cosmap_up_queue_set(a_uint32_t dev_id, a_uint32_t up, + fal_queue_t queue); + + + HSL_LOCAL sw_error_t + garuda_cosmap_up_queue_get(a_uint32_t dev_id, a_uint32_t up, + fal_queue_t * queue); + + + + HSL_LOCAL sw_error_t + garuda_cosmap_dscp_queue_set(a_uint32_t dev_id, a_uint32_t dscp, + fal_queue_t queue); + + + + HSL_LOCAL sw_error_t + garuda_cosmap_dscp_queue_get(a_uint32_t dev_id, a_uint32_t dscp, + fal_queue_t * queue); + + + + HSL_LOCAL sw_error_t + garuda_qos_port_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_bool_t enable); + + + + HSL_LOCAL sw_error_t + garuda_qos_port_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_bool_t * enable); + + + + HSL_LOCAL sw_error_t + garuda_qos_port_mode_pri_set(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_uint32_t pri); + + + HSL_LOCAL sw_error_t + garuda_qos_port_mode_pri_get(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_uint32_t * pri); + + + + HSL_LOCAL sw_error_t + garuda_qos_port_default_up_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t up); + + + + HSL_LOCAL sw_error_t + garuda_qos_port_default_up_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * up); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _GARUDA_QOS_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_rate.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_rate.h new file mode 100755 index 000000000..eb76efa50 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_rate.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 garuda_rate GARUDA_RATE + * @{ + */ +#ifndef _GARUDA_RATE_H_ +#define _GARUDA_RATE_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_rate.h" + + sw_error_t garuda_rate_init(a_uint32_t dev_id); + +#ifdef IN_RATE +#define GARUDA_RATE_INIT(rv, dev_id) \ + { \ + rv = garuda_rate_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define GARUDA_RATE_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + garuda_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); + + + + HSL_LOCAL sw_error_t + garuda_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); + + + + HSL_LOCAL sw_error_t + garuda_rate_port_egrl_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * speed, a_bool_t enable); + + + + HSL_LOCAL sw_error_t + garuda_rate_port_egrl_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * speed, a_bool_t * enable); + + + + HSL_LOCAL sw_error_t + garuda_rate_port_inrl_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * speed, a_bool_t enable); + + + + HSL_LOCAL sw_error_t + garuda_rate_port_inrl_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * speed, a_bool_t * enable); + + + + HSL_LOCAL sw_error_t + garuda_storm_ctrl_frame_set(a_uint32_t dev_id, fal_port_t port_id, + fal_storm_type_t storm_type, a_bool_t enable); + + + + HSL_LOCAL sw_error_t + garuda_storm_ctrl_frame_get(a_uint32_t dev_id, fal_port_t port_id, + fal_storm_type_t storm_type, a_bool_t * enable); + + + + HSL_LOCAL sw_error_t + garuda_storm_ctrl_rate_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * rate_in_pps); + + + + HSL_LOCAL sw_error_t + garuda_storm_ctrl_rate_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * rate_in_pps); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _GARUDA_RATE_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_reduced_acl.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_reduced_acl.h new file mode 100755 index 000000000..08be79484 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_reduced_acl.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2012,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 _GARUDA_REDUCED_ACL_H_ +#define _GARUDA_REDUCED_ACL_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "sw.h" + + sw_error_t + garuda_acl_rule_write(a_uint32_t dev_id, a_uint32_t rule_idx, a_uint32_t vlu[8], + a_uint32_t msk[8]); + + sw_error_t + garuda_acl_action_write(a_uint32_t dev_id, a_uint32_t act_idx, + a_uint32_t act); + + sw_error_t + garuda_acl_slct_write(a_uint32_t dev_id, a_uint32_t slct_idx, + a_uint32_t slct[8]); + + sw_error_t + garuda_acl_rule_read(a_uint32_t dev_id, a_uint32_t rule_idx, a_uint32_t vlu[8], + a_uint32_t msk[8]); + + sw_error_t + garuda_acl_action_read(a_uint32_t dev_id, a_uint32_t act_idx, + a_uint32_t * act); + + sw_error_t + garuda_acl_slct_read(a_uint32_t dev_id, a_uint32_t slct_idx, + a_uint32_t slct[8]); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _GARUDA_REDUCED_ACL_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_reg.h new file mode 100755 index 000000000..32169706c --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_reg.h @@ -0,0 +1,3614 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _GARUDA_REG_H_ +#define _GARUDA_REG_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define MAX_ENTRY_LEN 128 + +#define HSL_RW 1 +#define HSL_RO 0 + + + /* GARUDA Mask Control Register */ +#define MASK_CTL "mask" +#define MASK_CTL_ID 0 +#define MASK_CTL_OFFSET 0x0000 +#define MASK_CTL_E_LENGTH 4 +#define MASK_CTL_E_OFFSET 0 +#define MASK_CTL_NR_E 1 + +#define SOFT_RST "mask_rst" +#define MASK_CTL_SOFT_RST_BOFFSET 31 +#define MASK_CTL_SOFT_RST_BLEN 1 +#define MASK_CTL_SOFT_RST_FLAG HSL_RW + +#define MII_CLK5_SEL "mask_clk5s" +#define MASK_CTL_MII_CLK5_SEL_BOFFSET 21 +#define MASK_CTL_MII_CLK5_SEL_BLEN 1 +#define MASK_CTL_MII_CLK5_SEL_FLAG HSL_RW + +#define MII_CLK0_SEL "mask_clk0s" +#define MASK_CTL_MII_CLK0_SEL_BOFFSET 20 +#define MASK_CTL_MII_CLK0_SEL_BLEN 1 +#define MASK_CTL_MII_CLK0_SEL_FLAG HSL_RW + +#define LOAD_EEPROM "mask_ldro" +#define MASK_CTL_LOAD_EEPROM_BOFFSET 16 +#define MASK_CTL_LOAD_EEPROM_BLEN 1 +#define MASK_CTL_LOAD_EEPROM_FLAG HSL_RW + +#define DEVICE_ID "mask_did" +#define MASK_CTL_DEVICE_ID_BOFFSET 8 +#define MASK_CTL_DEVICE_ID_BLEN 8 +#define MASK_CTL_DEVICE_ID_FLAG HSL_RO + +#define REV_ID "mask_rid" +#define MASK_CTL_REV_ID_BOFFSET 0 +#define MASK_CTL_REV_ID_BLEN 8 +#define MASK_CTL_REV_ID_FLAG HSL_RO + + + /* GARUDA Mask Control Register */ +#define POSTRIP "postrip" +#define POSTRIP_ID 0 +#define POSTRIP_OFFSET 0x0008 +#define POSTRIP_E_LENGTH 4 +#define POSTRIP_E_OFFSET 0 +#define POSTRIP_NR_E 1 + +#define POWER_ON_SEL "postrip_sel" +#define POSTRIP_POWER_ON_SEL_BOFFSET 31 +#define POSTRIP_POWER_ON_SEL_BLEN 1 +#define POSTRIP_POWER_ON_SEL_FLAG HSL_RW + +#define RXDELAY_S1 "postrip_rx_s1" +#define POSTRIP_RXDELAY_S1_BOFFSET 26 +#define POSTRIP_RXDELAY_S1_BLEN 1 +#define POSTRIP_RXDELAY_S1_FLAG HSL_RW + +#define SPI_EN "postrip_spi" +#define POSTRIP_SPI_EN_BOFFSET 25 +#define POSTRIP_SPI_EN_BLEN 1 +#define POSTRIP_SPI_EN_FLAG HSL_RW + +#define LED_OPEN_EN "postrip_led" +#define POSTRIP_LED_OPEN_EN_BOFFSET 24 +#define POSTRIP_LED_OPEN_EN_BLEN 1 +#define POSTRIP_LED_OPEN_EN_FLAG HSL_RW + +#define RXDELAY_S0 "postrip_rx_s0" +#define POSTRIP_RXDELAY_S0_BOFFSET 23 +#define POSTRIP_RXDELAY_S0_BLEN 1 +#define POSTRIP_RXDELAY_S0_FLAG HSL_RW + +#define TXDELAY_S1 "postrip_tx_s1" +#define POSTRIP_TXDELAY_S1_BOFFSET 22 +#define POSTRIP_TXDELAY_S1_BLEN 1 +#define POSTRIP_TXDELAY_S1_FLAG HSL_RW + +#define TXDELAY_S0 "postrip_tx_s0" +#define POSTRIP_TXDELAY_S0_BOFFSET 21 +#define POSTRIP_TXDELAY_S0_BLEN 1 +#define POSTRIP_TXDELAY_S0_FLAG HSL_RW + +#define LPW_EXIT "postrip_lpw_exit" +#define POSTRIP_LPW_EXIT_BOFFSET 20 +#define POSTRIP_LPW_EXIT_BLEN 1 +#define POSTRIP_LPW_EXIT_FLAG HSL_RW + +#define PHY_PLL_ON "postrip_phy_pll" +#define POSTRIP_PHY_PLL_ON_BOFFSET 19 +#define POSTRIP_PHY_PLL_ON_BLEN 1 +#define POSTRIP_PHY_PLL_ON_FLAG HSL_RW + +#define MAN_ENABLE "postrip_man_en" +#define POSTRIP_MAN_ENABLE_BOFFSET 18 +#define POSTRIP_MAN_ENABLE_BLEN 1 +#define POSTRIP_MAN_ENABLE_FLAG HSL_RW + +#define LPW_STATE_EN "postrip_lpw_state" +#define POSTRIP_LPW_STATE_EN_BOFFSET 17 +#define POSTRIP_LPW_STATE_EN_BLEN 1 +#define POSTRIP_LPW_STATE_EN_FLAG HSL_RW + +#define POWER_DOWN_HW "postrip_power_down" +#define POSTRIP_POWER_DOWN_HW_BOFFSET 16 +#define POSTRIP_POWER_DOWN_HW_BLEN 1 +#define POSTRIP_POWER_DOWN_HW_FLAG HSL_RW + +#define MAC5_PHY_MODE "postrip_mac5_phy" +#define POSTRIP_MAC5_PHY_MODE_BOFFSET 15 +#define POSTRIP_MAC5_PHY_MODE_BLEN 1 +#define POSTRIP_MAC5_PHY_MODE_FLAG HSL_RW + +#define MAC5_MAC_MODE "postrip_mac5_mac" +#define POSTRIP_MAC5_MAC_MODE_BOFFSET 14 +#define POSTRIP_MAC5_MAC_MODE_BLEN 1 +#define POSTRIP_MAC5_MAC_MODE_FLAG HSL_RW + +#define DBG_MODE_I "postrip_dbg" +#define POSTRIP_DBG_MODE_I_BOFFSET 13 +#define POSTRIP_DBG_MODE_I_BLEN 1 +#define POSTRIP_DBG_MODE_I_FLAG HSL_RW + +#define HIB_PULSE_HW "postrip_hib" +#define POSTRIP_HIB_PULSE_HW_BOFFSET 12 +#define POSTRIP_HIB_PULSE_HW_BLEN 1 +#define POSTRIP_HIB_PULSE_HW_FLAG HSL_RW + +#define SEL_CLK25M "postrip_clk25" +#define POSTRIP_SEL_CLK25M_BOFFSET 11 +#define POSTRIP_SEL_CLK25M_BLEN 1 +#define POSTRIP_SEL_CLK25M_FLAG HSL_RW + +#define GATE_25M_EN "postrip_gate25" +#define POSTRIP_GATE_25M_EN_BOFFSET 10 +#define POSTRIP_GATE_25M_EN_BLEN 1 +#define POSTRIP_GATE_25M_EN_FLAG HSL_RW + +#define SEL_ANA_RST "postrip_sel_ana" +#define POSTRIP_SEL_ANA_RST_BOFFSET 9 +#define POSTRIP_SEL_ANA_RST_BLEN 1 +#define POSTRIP_SEL_ANA_RST_FLAG HSL_RW + +#define SERDES_EN "postrip_serdes_en" +#define POSTRIP_SERDES_EN_BOFFSET 8 +#define POSTRIP_SERDES_EN_BLEN 1 +#define POSTRIP_SERDES_EN_FLAG HSL_RW + +#define RGMII_TXCLK_DELAY_EN "postrip_tx_delay" +#define POSTRIP_RGMII_TXCLK_DELAY_EN_BOFFSET 7 +#define POSTRIP_RGMII_TXCLK_DELAY_EN_BLEN 1 +#define POSTRIP_RGMII_TXCLK_DELAY_EN_FLAG HSL_RW + +#define RGMII_RXCLK_DELAY_EN "postrip_rx_delay" +#define POSTRIP_RGMII_RXCLK_DELAY_EN_BOFFSET 6 +#define POSTRIP_RGMII_RXCLK_DELAY_EN_BLEN 1 +#define POSTRIP_RGMII_RXCLK_DELAY_EN_FLAG HSL_RW + +#define RTL_MODE "postrip_rtl" +#define POSTRIP_RTL_MODE_BOFFSET 5 +#define POSTRIP_RTL_MODE_BLEN 1 +#define POSTRIP_RTL_MODE_FLAG HSL_RW + +#define MAC0_MAC_MODE "postrip_mac0_mac" +#define POSTRIP_MAC0_MAC_MODE_BOFFSET 4 +#define POSTRIP_MAC0_MAC_MODE_BLEN 1 +#define POSTRIP_MAC0_MAC_MODE_FLAG HSL_RW + +#define PHY4_RGMII_EN "postrip_phy4_rgmii" +#define POSTRIP_PHY4_RGMII_EN_BOFFSET 3 +#define POSTRIP_PHY4_RGMII_EN_BLEN 1 +#define POSTRIP_PHY4_RGMII_EN_FLAG HSL_RW + +#define PHY4_GMII_EN "postrip_phy4_gmii" +#define POSTRIP_PHY4_GMII_EN_BOFFSET 2 +#define POSTRIP_PHY4_GMII_EN_BLEN 1 +#define POSTRIP_PHY4_GMII_EN_FLAG HSL_RW + +#define MAC0_RGMII_EN "postrip_mac0_rgmii" +#define POSTRIP_MAC0_RGMII_EN_BOFFSET 1 +#define POSTRIP_MAC0_RGMII_EN_BLEN 1 +#define POSTRIP_MAC0_RGMII_EN_FLAG HSL_RW + +#define MAC0_GMII_EN "postrip_mac0_gmii" +#define POSTRIP_MAC0_GMII_EN_BOFFSET 0 +#define POSTRIP_MAC0_GMII_EN_BLEN 1 +#define POSTRIP_MAC0_GMII_EN_FLAG HSL_RW + + + + /* Global Interrupt Register */ +#define GLOBAL_INT "gint" +#define GLOBAL_INT_ID 1 +#define GLOBAL_INT_OFFSET 0x0010 +#define GLOBAL_INT_E_LENGTH 4 +#define GLOBAL_INT_E_OFFSET 0 +#define GLOBAL_INT_NR_E 1 + +#define GLB_QM_ERR_CNT "gint_qmen" +#define GLOBAL_INT_GLB_QM_ERR_CNT_BOFFSET 24 +#define GLOBAL_INT_GLB_QM_ERR_CNT_BLEN 8 +#define GLOBAL_INT_GLB_QM_ERR_CNT_FLAG HSL_RO + +#define GLB_LOOKUP_ERR "gint_glblper" +#define GLOBAL_INT_GLB_LOOKUP_ERR_BOFFSET 17 +#define GLOBAL_INT_GLB_LOOKUP_ERR_BLEN 1 +#define GLOBAL_INT_GLB_LOOKUP_ERR_FLAG HSL_RW + +#define GLB_QM_ERR "gint_glbqmer" +#define GLOBAL_INT_GLB_QM_ERR_BOFFSET 16 +#define GLOBAL_INT_GLB_QM_ERR_BLEN 1 +#define GLOBAL_INT_GLB_QM_ERR_FLAG HSL_RW + +#define GLB_HW_INI_DONE "gint_hwid" +#define GLOBAL_INT_GLB_HW_INI_DONE_BOFFSET 14 +#define GLOBAL_INT_GLB_HW_INI_DONE_BLEN 1 +#define GLOBAL_INT_GLB_HW_INI_DONE_FLAG HSL_RW + +#define GLB_MIB_INI "gint_mibi" +#define GLOBAL_INT_GLB_MIB_INI_BOFFSET 13 +#define GLOBAL_INT_GLB_MIB_INI_BLEN 1 +#define GLOBAL_INT_GLB_MIB_INI_FLAG HSL_RW + +#define GLB_MIB_DONE "gint_mibd" +#define GLOBAL_INT_GLB_MIB_DONE_BOFFSET 12 +#define GLOBAL_INT_GLB_MIB_DONE_BLEN 1 +#define GLOBAL_INT_GLB_MIB_DONE_FLAG HSL_RW + +#define GLB_BIST_DONE "gint_bisd" +#define GLOBAL_INT_GLB_BIST_DONE_BOFFSET 11 +#define GLOBAL_INT_GLB_BIST_DONE_BLEN 1 +#define GLOBAL_INT_GLB_BIST_DONE_FLAG HSL_RW + +#define GLB_VT_MISS_VIO "gint_vtms" +#define GLOBAL_INT_GLB_VT_MISS_VIO_BOFFSET 10 +#define GLOBAL_INT_GLB_VT_MISS_VIO_BLEN 1 +#define GLOBAL_INT_GLB_VT_MISS_VIO_FLAG HSL_RW + +#define GLB_VT_MEM_VIO "gint_vtme" +#define GLOBAL_INT_GLB_VT_MEM_VIO_BOFFSET 9 +#define GLOBAL_INT_GLB_VT_MEM_VIO_BLEN 1 +#define GLOBAL_INT_GLB_VT_MEM_VIO_FLAG HSL_RW + +#define GLB_VT_DONE "gint_vtd" +#define GLOBAL_INT_GLB_VT_DONE_BOFFSET 8 +#define GLOBAL_INT_GLB_VT_DONE_BLEN 1 +#define GLOBAL_INT_GLB_VT_DONE_FLAG HSL_RW + +#define GLB_QM_INI "gint_qmin" +#define GLOBAL_INT_GLB_QM_INI_BOFFSET 7 +#define GLOBAL_INT_GLB_QM_INI_BLEN 1 +#define GLOBAL_INT_GLB_QM_INI_FLAG HSL_RW + +#define GLB_AT_INI "gint_atin" +#define GLOBAL_INT_GLB_AT_INI_BOFFSET 6 +#define GLOBAL_INT_GLB_AT_INI_BLEN 1 +#define GLOBAL_INT_GLB_AT_INI_FLAG HSL_RW + +#define GLB_ARL_FULL "gint_arlf" +#define GLOBAL_INT_GLB_ARL_FULL_BOFFSET 5 +#define GLOBAL_INT_GLB_ARL_FULL_BLEN 1 +#define GLOBAL_INT_GLB_ARL_FULL_FLAG HSL_RW + +#define GLB_ARL_DONE "gint_arld" +#define GLOBAL_INT_GLB_ARL_DONE_BOFFSET 4 +#define GLOBAL_INT_GLB_ARL_DONE_BLEN 1 +#define GLOBAL_INT_GLB_ARL_DONE_FLAG HSL_RW + +#define GLB_MDIO_DONE "gint_mdid" +#define GLOBAL_INT_GLB_MDIO_DONE_BOFFSET 3 +#define GLOBAL_INT_GLB_MDIO_DONE_BLEN 1 +#define GLOBAL_INT_GLB_MDIO_DONE_FLAG HSL_RW + +#define GLB_PHY_INT "gint_phyi" +#define GLOBAL_INT_GLB_PHY_INT_BOFFSET 2 +#define GLOBAL_INT_GLB_PHY_INT_BLEN 1 +#define GLOBAL_INT_GLB_PHY_INT_FLAG HSL_RW + +#define GLB_EEPROM_ERR "gint_epei" +#define GLOBAL_INT_GLB_EEPROM_ERR_BOFFSET 1 +#define GLOBAL_INT_GLB_EEPROM_ERR_BLEN 1 +#define GLOBAL_INT_GLB_EEPROM_ERR_FLAG HSL_RW + +#define GLB_EEPROM_INT "gint_epi" +#define GLOBAL_INT_GLB_EEPROM_INT_BOFFSET 0 +#define GLOBAL_INT_GLB_EEPROM_INT_BLEN 1 +#define GLOBAL_INT_GLB_EEPROM_INT_FLAG HSL_RW + + + /* Global Interrupt Mask Register */ +#define GLOBAL_INT_MASK "gintm" +#define GLOBAL_INT_MASK_ID 2 +#define GLOBAL_INT_MASK_OFFSET 0x0014 +#define GLOBAL_INT_MASK_E_LENGTH 4 +#define GLOBAL_INT_MASK_E_OFFSET 0 +#define GLOBAL_INT_MASK_NR_E 1 + +#define GLBM_LOOKUP_ERR "gintm_lpe" +#define GLOBAL_INT_MASK_GLBM_LOOKUP_ERR_BOFFSET 17 +#define GLOBAL_INT_MASK_GLBM_LOOKUP_ERR_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_LOOKUP_ERR_FLAG HSL_RW + +#define GLBM_QM_ERR "gintm_qme" +#define GLOBAL_INT_MASK_GLBM_QM_ERR_BOFFSET 16 +#define GLOBAL_INT_MASK_GLBM_QM_ERR_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_QM_ERR_FLAG HSL_RW + +#define GLBM_HW_INI_DONE "gintm_hwid" +#define GLOBAL_INT_MASK_GLBM_HW_INI_DONE_BOFFSET 14 +#define GLOBAL_INT_MASK_GLBM_HW_INI_DONE_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_HW_INI_DONE_FLAG HSL_RW + +#define GLBM_MIB_INI "gintm_mibi" +#define GLOBAL_INT_MASK_GLBM_MIB_INI_BOFFSET 13 +#define GLOBAL_INT_MASK_GLBM_MIB_INI_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_MIB_INI_FLAG HSL_RW + +#define GLBM_MIB_DONE "gintm_mibd" +#define GLOBAL_INT_MASK_GLBM_MIB_DONE_BOFFSET 12 +#define GLOBAL_INT_MASK_GLBM_MIB_DONE_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_MIB_DONE_FLAG HSL_RW + +#define GLBM_BIST_DONE "gintm_bisd" +#define GLOBAL_INT_MASK_GLBM_BIST_DONE_BOFFSET 11 +#define GLOBAL_INT_MASK_GLBM_BIST_DONE_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_BIST_DONE_FLAG HSL_RW + +#define GLBM_VT_MISS_VIO "gintm_vtms" +#define GLOBAL_INT_MASK_GLBM_VT_MISS_VIO_BOFFSET 10 +#define GLOBAL_INT_MASK_GLBM_VT_MISS_VIO_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_VT_MISS_VIO_FLAG HSL_RW + +#define GLBM_VT_MEM_VIO "gintm_vtme" +#define GLOBAL_INT_MASK_GLBM_VT_MEM_VIO_BOFFSET 9 +#define GLOBAL_INT_MASK_GLBM_VT_MEM_VIO_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_VT_MEM_VIO_FLAG HSL_RW + +#define GLBM_VT_DONE "gintm_vtd" +#define GLOBAL_INT_MASK_GLBM_VT_DONE_BOFFSET 8 +#define GLOBAL_INT_MASK_GLBM_VT_DONE_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_VT_DONE_FLAG HSL_RW + +#define GLBM_QM_INI "gintm_qmin" +#define GLOBAL_INT_MASK_GLBM_QM_INI_BOFFSET 7 +#define GLOBAL_INT_MASK_GLBM_QM_INI_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_QM_INI_FLAG HSL_RW + +#define GLBM_AT_INI "gintm_atin" +#define GLOBAL_INT_MASK_GLBM_AT_INI_BOFFSET 6 +#define GLOBAL_INT_MASK_GLBM_AT_INI_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_AT_INI_FLAG HSL_RW + +#define GLBM_ARL_FULL "gintm_arlf" +#define GLOBAL_INT_MASK_GLBM_ARL_FULL_BOFFSET 5 +#define GLOBAL_INT_MASK_GLBM_ARL_FULL_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_ARL_FULL_FLAG HSL_RW + +#define GLBM_ARL_DONE "gintm_arld" +#define GLOBAL_INT_MASK_GLBM_ARL_DONE_BOFFSET 4 +#define GLOBAL_INT_MASK_GLBM_ARL_DONE_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_ARL_DONE_FLAG HSL_RW + +#define GLBM_MDIO_DONE "gintm_mdid" +#define GLOBAL_INT_MASK_GLBM_MDIO_DONE_BOFFSET 3 +#define GLOBAL_INT_MASK_GLBM_MDIO_DONE_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_MDIO_DONE_FLAG HSL_RW + +#define GLBM_PHY_INT "gintm_phy" +#define GLOBAL_INT_MASK_GLBM_PHY_INT_BOFFSET 2 +#define GLOBAL_INT_MASK_GLBM_PHY_INT_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_PHY_INT_FLAG HSL_RW + +#define GLBM_EEPROM_ERR "gintm_epe" +#define GLOBAL_INT_MASK_GLBM_EEPROM_ERR_BOFFSET 1 +#define GLOBAL_INT_MASK_GLBM_EEPROM_ERR_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_EEPROM_ERR_FLAG HSL_RW + +#define GLBM_EEPROM_INT "gintm_ep" +#define GLOBAL_INT_MASK_GLBM_EEPROM_INT_BOFFSET 0 +#define GLOBAL_INT_MASK_GLBM_EEPROM_INT_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_EEPROM_INT_FLAG HSL_RW + + + /* Global MAC Address Register */ +#define GLOBAL_MAC_ADDR0 "gmac0" +#define GLOBAL_MAC_ADDR0_ID 3 +#define GLOBAL_MAC_ADDR0_OFFSET 0x0020 +#define GLOBAL_MAC_ADDR0_E_LENGTH 4 +#define GLOBAL_MAC_ADDR0_E_OFFSET 0 +#define GLOBAL_MAC_ADDR0_NR_E 1 + +#define GLB_BYTE4 "gmac_b4" +#define GLOBAL_MAC_ADDR0_GLB_BYTE4_BOFFSET 8 +#define GLOBAL_MAC_ADDR0_GLB_BYTE4_BLEN 8 +#define GLOBAL_MAC_ADDR0_GLB_BYTE4_FLAG HSL_RW + +#define GLB_BYTE5 "gmac_b5" +#define GLOBAL_MAC_ADDR0_GLB_BYTE5_BOFFSET 0 +#define GLOBAL_MAC_ADDR0_GLB_BYTE5_BLEN 8 +#define GLOBAL_MAC_ADDR0_GLB_BYTE5_FLAG HSL_RW + +#define GLOBAL_MAC_ADDR1 "gmac1" +#define GLOBAL_MAC_ADDR1_ID 4 +#define GLOBAL_MAC_ADDR1_OFFSET 0x0024 +#define GLOBAL_MAC_ADDR1_E_LENGTH 4 +#define GLOBAL_MAC_ADDR1_E_OFFSET 0 +#define GLOBAL_MAC_ADDR1_NR_E 1 + +#define GLB_BYTE0 "gmac_b0" +#define GLOBAL_MAC_ADDR1_GLB_BYTE0_BOFFSET 24 +#define GLOBAL_MAC_ADDR1_GLB_BYTE0_BLEN 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE0_FLAG HSL_RW + +#define GLB_BYTE1 "gmac_b1" +#define GLOBAL_MAC_ADDR1_GLB_BYTE1_BOFFSET 16 +#define GLOBAL_MAC_ADDR1_GLB_BYTE1_BLEN 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE1_FLAG HSL_RW + +#define GLB_BYTE2 "gmac_b2" +#define GLOBAL_MAC_ADDR1_GLB_BYTE2_BOFFSET 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE2_BLEN 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE2_FLAG HSL_RW + +#define GLB_BYTE3 "gmac_b3" +#define GLOBAL_MAC_ADDR1_GLB_BYTE3_BOFFSET 0 +#define GLOBAL_MAC_ADDR1_GLB_BYTE3_BLEN 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE3_FLAG HSL_RW + + + /* Flood Mask Register */ +#define FLOOD_MASK "fmask" +#define FLOOD_MASK_ID 5 +#define FLOOD_MASK_OFFSET 0x002c +#define FLOOD_MASK_E_LENGTH 4 +#define FLOOD_MASK_E_OFFSET 0 +#define FLOOD_MASK_NR_E 1 + +#define BROAD_TO_CPU "fmask_btocpu" +#define FLOOD_MASK_BROAD_TO_CPU_BOFFSET 26 +#define FLOOD_MASK_BROAD_TO_CPU_BLEN 1 +#define FLOOD_MASK_BROAD_TO_CPU_FLAG HSL_RW + +#define ARL_MUL_LEAKY "fmask_amlky" +#define FLOOD_MASK_ARL_MUL_LEAKY_BOFFSET 25 +#define FLOOD_MASK_ARL_MUL_LEAKY_BLEN 1 +#define FLOOD_MASK_ARL_MUL_LEAKY_FLAG HSL_RW + +#define ARL_UNI_LEAKY "fmask_aulky" +#define FLOOD_MASK_ARL_UNI_LEAKY_BOFFSET 24 +#define FLOOD_MASK_ARL_UNI_LEAKY_BLEN 1 +#define FLOOD_MASK_ARL_UNI_LEAKY_FLAG HSL_RW + +#define MUL_FLOOD_DP "fmask_mfdp" +#define FLOOD_MASK_MUL_FLOOD_DP_BOFFSET 16 +#define FLOOD_MASK_MUL_FLOOD_DP_BLEN 6 +#define FLOOD_MASK_MUL_FLOOD_DP_FLAG HSL_RW + +#define IGMP_DP "fmask_igmpdp" +#define FLOOD_MASK_IGMP_DP_BOFFSET 8 +#define FLOOD_MASK_IGMP_DP_BLEN 6 +#define FLOOD_MASK_IGMP_DP_FLAG HSL_RW + +#define UNI_FLOOD_DP "fmask_ufdp" +#define FLOOD_MASK_UNI_FLOOD_DP_BOFFSET 0 +#define FLOOD_MASK_UNI_FLOOD_DP_BLEN 6 +#define FLOOD_MASK_UNI_FLOOD_DP_FLAG HSL_RW + + + /* Global Control Register */ +#define GLOBAL_CTL "gctl" +#define GLOBAL_CTL_ID 5 +#define GLOBAL_CTL_OFFSET 0x0030 +#define GLOBAL_CTL_E_LENGTH 4 +#define GLOBAL_CTL_E_OFFSET 0 +#define GLOBAL_CTL_NR_E 1 + +#define WEIGHT_PRIORITY "gctl_wpri" +#define GLOBAL_CTL_WEIGHT_PRIORITY_BOFFSET 31 +#define GLOBAL_CTL_WEIGHT_PRIORITY_BLEN 1 +#define GLOBAL_CTL_WEIGHT_PRIORITY_FLAG HSL_RW + +#define RATE_DROP_EN "gctl_rden" +#define GLOBAL_CTL_RATE_DROP_EN_BOFFSET 30 +#define GLOBAL_CTL_RATE_DROP_EN_BLEN 1 +#define GLOBAL_CTL_RATE_DROP_EN_FLAG HSL_RW + +#define QM_PRI_MODE "gctl_qmpm" +#define GLOBAL_CTL_QM_PRI_MODE_BOFFSET 29 +#define GLOBAL_CTL_QM_PRI_MODE_BLEN 1 +#define GLOBAL_CTL_QM_PRI_MODE_FLAG HSL_RW + +#define MIX_PRIORITY "gctl_mpri" +#define GLOBAL_CTL_MIX_PRIORITY_BOFFSET 28 +#define GLOBAL_CTL_MIX_PRIORITY_BLEN 1 +#define GLOBAL_CTL_MIX_PRIORITY_FLAG HSL_RW + +#define RATE_CRE_LIMIT "gctl_rcrl" +#define GLOBAL_CTL_RATE_CRE_LIMIT_BOFFSET 26 +#define GLOBAL_CTL_RATE_CRE_LIMIT_BLEN 2 +#define GLOBAL_CTL_RATE_CRE_LIMIT_FLAG HSL_RW + +#define RATE_TIME_SLOT "gctl_rtms" +#define GLOBAL_CTL_RATE_TIME_SLOT_BOFFSET 24 +#define GLOBAL_CTL_RATE_TIME_SLOT_BLEN 2 +#define GLOBAL_CTL_RATE_TIME_SLOT_FLAG HSL_RW + +#define RELOAD_TIMER "gctl_rdtm" +#define GLOBAL_CTL_RELOAD_TIMER_BOFFSET 20 +#define GLOBAL_CTL_RELOAD_TIMER_BLEN 4 +#define GLOBAL_CTL_RELOAD_TIMER_FLAG HSL_RW + +#define QM_CNT_LOCK "gctl_qmcl" +#define GLOBAL_CTL_QM_CNT_LOCK_BOFFSET 19 +#define GLOBAL_CTL_QM_CNT_LOCK_BLEN 1 +#define GLOBAL_CTL_QM_CNT_LOCK_FLAG HSL_RO + +#define BROAD_DROP_EN "gctl_bden" +#define GLOBAL_CTL_BROAD_DROP_EN_BOFFSET 18 +#define GLOBAL_CTL_BROAD_DROP_EN_BLEN 1 +#define GLOBAL_CTL_BROAD_DROP_EN_FLAG HSL_RW + +#define MAX_FRAME_SIZE "gctl_mfsz" +#define GLOBAL_CTL_MAX_FRAME_SIZE_BOFFSET 0 +#define GLOBAL_CTL_MAX_FRAME_SIZE_BLEN 14 +#define GLOBAL_CTL_MAX_FRAME_SIZE_FLAG HSL_RW + + + /* Flow Control Register */ +#define FLOW_CTL "fctl" +#define FLOW_CTL_ID 6 +#define FLOW_CTL_OFFSET 0x0034 +#define FLOW_CTL_E_LENGTH 4 +#define FLOW_CTL_E_OFFSET 0 +#define FLOW_CTL_NR_E 1 + +#define TEST_PAUSE "fctl_tps" +#define FLOW_CTL_TEST_PAUSE_BOFFSET 31 +#define FLOW_CTL_TEST_PAUSE_BLEN 1 +#define FLOW_CTL_TEST_PAUSE_FLAG HSL_RW + +#define PORT_PAUSE_OFF_THRES "fctl_pofft" +#define FLOW_CTL_PORT_PAUSE_OFF_THRES_BOFFSET 24 +#define FLOW_CTL_PORT_PAUSE_OFF_THRES_BLEN 7 +#define FLOW_CTL_PORT_PAUSE_OFF_THRES_FLAG HSL_RW + +#define PORT_PAUSE_ON_THRES "fctl_pont" +#define FLOW_CTL_PORT_PAUSE_ON_THRES_BOFFSET 16 +#define FLOW_CTL_PORT_PAUSE_ON_THRES_BLEN 7 +#define FLOW_CTL_PORT_PAUSE_ON_THRES_FLAG HSL_RW + +#define GOL_PAUSE_OFF_THRES "fctl_gofft" +#define FLOW_CTL_GOL_PAUSE_OFF_THRES_BOFFSET 8 +#define FLOW_CTL_GOL_PAUSE_OFF_THRES_BLEN 8 +#define FLOW_CTL_GOL_PAUSE_OFF_THRES_FLAG HSL_RW + +#define GOL_PAUSE_ON_THRES "fctl_gont" +#define FLOW_CTL_GOL_PAUSE_ON_THRES_BOFFSET 0 +#define FLOW_CTL_GOL_PAUSE_ON_THRES_BLEN 8 +#define FLOW_CTL_GOL_PAUSE_ON_THRES_FLAG HSL_RW + + + /* QM Control Register */ +#define QM_CTL "qmct" +#define QM_CTL_ID 7 +#define QM_CTL_OFFSET 0x003c +#define QM_CTL_E_LENGTH 4 +#define QM_CTL_E_OFFSET 0 +#define QM_CTL_NR_E 1 + +#define QM_ERR_RST_EN "qmct_qeren" +#define QM_CTL_QM_ERR_RST_EN_BOFFSET 31 +#define QM_CTL_QM_ERR_RST_EN_BLEN 1 +#define QM_CTL_QM_ERR_RST_EN_FLAG HSL_RW + +#define LOOKUP_ERR_RST_EN "qmct_lpesen" +#define QM_CTL_LOOKUP_ERR_RST_EN_BOFFSET 30 +#define QM_CTL_LOOKUP_ERR_RST_EN_BLEN 1 +#define QM_CTL_LOOKUP_ERR_RST_EN_FLAG HSL_RW + +#define IGMP_CREAT_EN "qmct_igmpcrt" +#define QM_CTL_IGMP_CREAT_EN_BOFFSET 22 +#define QM_CTL_IGMP_CREAT_EN_BLEN 1 +#define QM_CTL_IGMP_CREAT_EN_FLAG HSL_RW + +#define ACL_EN "qmct_aclen" +#define QM_CTL_ACL_EN_BOFFSET 21 +#define QM_CTL_ACL_EN_BLEN 1 +#define QM_CTL_ACL_EN_FLAG HSL_RW + +#define PPPOE_RDT_EN "qmct_pppoerdten" +#define QM_CTL_PPPOE_RDT_EN_BOFFSET 20 +#define QM_CTL_PPPOE_RDT_EN_BLEN 1 +#define QM_CTL_PPPOE_RDT_EN_FLAG HSL_RW + +#define IGMP_COPY_EN "qmct_igmpcpy" +#define QM_CTL_IGMP_COPY_EN_BOFFSET 11 +#define QM_CTL_IGMP_COPY_EN_BLEN 1 +#define QM_CTL_IGMP_COPY_EN_FLAG HSL_RW + +#define PPPOE_EN "qmct_pppoeen" +#define QM_CTL_PPPOE_EN_BOFFSET 10 +#define QM_CTL_PPPOE_EN_BLEN 1 +#define QM_CTL_PPPOE_EN_FLAG HSL_RW + +#define QM_FUNC_TEST "qmct_qmft" +#define QM_CTL_QM_FUNC_TEST_BOFFSET 9 +#define QM_CTL_QM_FUNC_TEST_BLEN 1 +#define QM_CTL_QM_FUNC_TEST_FLAG HSL_RW + +#define MS_FC_EN "qmct_msfe" +#define QM_CTL_MS_FC_EN_BOFFSET 8 +#define QM_CTL_MS_FC_EN_BLEN 1 +#define QM_CTL_MS_FC_EN_FLAG HSL_RW + +#define FLOW_DROP_EN "qmct_fden" +#define QM_CTL_FLOW_DROP_EN_BOFFSET 7 +#define QM_CTL_FLOW_DROP_EN_BLEN 1 +#define QM_CTL_FLOW_DROP_EN_FLAG HSL_RW + +#define MANAGE_VID_VIO_DROP_EN "qmct_mden" +#define QM_CTL_MANAGE_VID_VIO_DROP_EN_BOFFSET 6 +#define QM_CTL_MANAGE_VID_VIO_DROP_EN_BLEN 1 +#define QM_CTL_MANAGE_VID_VIO_DROP_EN_FLAG HSL_RW + +#define FLOW_DROP_CNT "qmct_fdcn" +#define QM_CTL_FLOW_DROP_CNT_BOFFSET 0 +#define QM_CTL_FLOW_DROP_CNT_BLEN 6 +#define QM_CTL_FLOW_DROP_CNT_FLAG HSL_RW + + + /* Vlan Table Function Register */ +#define VLAN_TABLE_FUNC0 "vtbf0" +#define VLAN_TABLE_FUNC0_ID 9 +#define VLAN_TABLE_FUNC0_OFFSET 0x0040 +#define VLAN_TABLE_FUNC0_E_LENGTH 4 +#define VLAN_TABLE_FUNC0_E_OFFSET 0 +#define VLAN_TABLE_FUNC0_NR_E 1 + +#define VT_PRI_EN "vtbf_vtpen" +#define VLAN_TABLE_FUNC0_VT_PRI_EN_BOFFSET 31 +#define VLAN_TABLE_FUNC0_VT_PRI_EN_BLEN 1 +#define VLAN_TABLE_FUNC0_VT_PRI_EN_FLAG HSL_RW + +#define VT_PRI "vtbf_vtpri" +#define VLAN_TABLE_FUNC0_VT_PRI_BOFFSET 28 +#define VLAN_TABLE_FUNC0_VT_PRI_BLEN 3 +#define VLAN_TABLE_FUNC0_VT_PRI_FLAG HSL_RW + +#define VLAN_ID "vtbf_vid" +#define VLAN_TABLE_FUNC0_VLAN_ID_BOFFSET 16 +#define VLAN_TABLE_FUNC0_VLAN_ID_BLEN 12 +#define VLAN_TABLE_FUNC0_VLAN_ID_FLAG HSL_RW + +#define VT_PORT_NUM "vtbf_vtpn" +#define VLAN_TABLE_FUNC0_VT_PORT_NUM_BOFFSET 8 +#define VLAN_TABLE_FUNC0_VT_PORT_NUM_BLEN 4 +#define VLAN_TABLE_FUNC0_VT_PORT_NUM_FLAG HSL_RW + +#define VT_FULL_VIO "vtbf_vtflv" +#define VLAN_TABLE_FUNC0_VT_FULL_VIO_BOFFSET 4 +#define VLAN_TABLE_FUNC0_VT_FULL_VIO_BLEN 1 +#define VLAN_TABLE_FUNC0_VT_FULL_VIO_FLAG HSL_RW + +#define VT_BUSY "vtbf_vtbs" +#define VLAN_TABLE_FUNC0_VT_BUSY_BOFFSET 3 +#define VLAN_TABLE_FUNC0_VT_BUSY_BLEN 1 +#define VLAN_TABLE_FUNC0_VT_BUSY_FLAG HSL_RW + +#define VT_FUNC "vtbf_vtfc" +#define VLAN_TABLE_FUNC0_VT_FUNC_BOFFSET 0 +#define VLAN_TABLE_FUNC0_VT_FUNC_BLEN 3 +#define VLAN_TABLE_FUNC0_VT_FUNC_FLAG HSL_RW + +#define VLAN_TABLE_FUNC1 "vtbf1" +#define VLAN_TABLE_FUNC1_ID 10 +#define VLAN_TABLE_FUNC1_OFFSET 0x0044 +#define VLAN_TABLE_FUNC1_E_LENGTH 4 +#define VLAN_TABLE_FUNC1_E_OFFSET 0 +#define VLAN_TABLE_FUNC1_NR_E 1 + +#define VT_VALID "vtbf_vtvd" +#define VLAN_TABLE_FUNC1_VT_VALID_BOFFSET 11 +#define VLAN_TABLE_FUNC1_VT_VALID_BLEN 1 +#define VLAN_TABLE_FUNC1_VT_VALID_FLAG HSL_RW + +#define VID_MEM "vtbf_vidm" +#define VLAN_TABLE_FUNC1_VID_MEM_BOFFSET 0 +#define VLAN_TABLE_FUNC1_VID_MEM_BLEN 10 +#define VLAN_TABLE_FUNC1_VID_MEM_FLAG HSL_RW + + + /* Address Table Function Register */ +#define ADDR_TABLE_FUNC0 "atbf0" +#define ADDR_TABLE_FUNC0_ID 11 +#define ADDR_TABLE_FUNC0_OFFSET 0x0050 +#define ADDR_TABLE_FUNC0_E_LENGTH 4 +#define ADDR_TABLE_FUNC0_E_OFFSET 0 +#define ADDR_TABLE_FUNC0_NR_E 1 + +#define AT_ADDR_BYTE4 "atbf_adb4" +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE4_BOFFSET 24 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE4_BLEN 8 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE4_FLAG HSL_RW + +#define AT_ADDR_BYTE5 "atbf_adb5" +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE5_BOFFSET 16 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE5_BLEN 8 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE5_FLAG HSL_RW + +#define AT_FULL_VIO "atbf_atfv" +#define ADDR_TABLE_FUNC0_AT_FULL_VIO_BOFFSET 12 +#define ADDR_TABLE_FUNC0_AT_FULL_VIO_BLEN 1 +#define ADDR_TABLE_FUNC0_AT_FULL_VIO_FLAG HSL_RW + +#define AT_PORT_NUM "atbf_atpn" +#define ADDR_TABLE_FUNC0_AT_PORT_NUM_BOFFSET 8 +#define ADDR_TABLE_FUNC0_AT_PORT_NUM_BLEN 4 +#define ADDR_TABLE_FUNC0_AT_PORT_NUM_FLAG HSL_RW + +#define FLUSH_ST_EN "atbf_fsen" +#define ADDR_TABLE_FUNC0_FLUSH_ST_EN_BOFFSET 4 +#define ADDR_TABLE_FUNC0_FLUSH_ST_EN_BLEN 1 +#define ADDR_TABLE_FUNC0_FLUSH_ST_EN_FLAG HSL_RW + +#define AT_BUSY "atbf_atbs" +#define ADDR_TABLE_FUNC0_AT_BUSY_BOFFSET 3 +#define ADDR_TABLE_FUNC0_AT_BUSY_BLEN 1 +#define ADDR_TABLE_FUNC0_AT_BUSY_FLAG HSL_RW + +#define AT_FUNC "atbf_atfc" +#define ADDR_TABLE_FUNC0_AT_FUNC_BOFFSET 0 +#define ADDR_TABLE_FUNC0_AT_FUNC_BLEN 3 +#define ADDR_TABLE_FUNC0_AT_FUNC_FLAG HSL_RW + +#define ADDR_TABLE_FUNC1 "atbf1" +#define ADDR_TABLE_FUNC1_ID 12 +#define ADDR_TABLE_FUNC1_OFFSET 0x0054 +#define ADDR_TABLE_FUNC1_E_LENGTH 4 +#define ADDR_TABLE_FUNC1_E_OFFSET 0 +#define ADDR_TABLE_FUNC1_NR_E 0 + +#define AT_ADDR_BYTE0 "atbf_adb0" +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE0_BOFFSET 24 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE0_BLEN 8 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE0_FLAG HSL_RW + +#define AT_ADDR_BYTE1 "atbf_adb1" +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE1_BOFFSET 16 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE1_BLEN 8 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE1_FLAG HSL_RW + +#define AT_ADDR_BYTE2 "atbf_adb2" +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE2_BOFFSET 8 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE2_BLEN 8 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE2_FLAG HSL_RW + +#define AT_ADDR_BYTE3 "atbf_adb3" +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE3_BOFFSET 0 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE3_BLEN 8 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE3_FLAG HSL_RW + +#define ADDR_TABLE_FUNC2 "atbf2" +#define ADDR_TABLE_FUNC2_ID 13 +#define ADDR_TABLE_FUNC2_OFFSET 0x0058 +#define ADDR_TABLE_FUNC2_E_LENGTH 4 +#define ADDR_TABLE_FUNC2_E_OFFSET 0 +#define ADDR_TABLE_FUNC2_NR_E 0 + +#define COPY_TO_CPU "atbf_cpcpu" +#define ADDR_TABLE_FUNC2_COPY_TO_CPU_BOFFSET 26 +#define ADDR_TABLE_FUNC2_COPY_TO_CPU_BLEN 1 +#define ADDR_TABLE_FUNC2_COPY_TO_CPU_FLAG HSL_RW + +#define REDRCT_TO_CPU "atbf_rdcpu" +#define ADDR_TABLE_FUNC2_REDRCT_TO_CPU_BOFFSET 25 +#define ADDR_TABLE_FUNC2_REDRCT_TO_CPU_BLEN 1 +#define ADDR_TABLE_FUNC2_REDRCT_TO_CPU_FLAG HSL_RW + +#define LEAKY_EN "atbf_lkyen" +#define ADDR_TABLE_FUNC2_LEAKY_EN_BOFFSET 24 +#define ADDR_TABLE_FUNC2_LEAKY_EN_BLEN 1 +#define ADDR_TABLE_FUNC2_LEAKY_EN_FLAG HSL_RW + +#define AT_STATUS "atbf_atsts" +#define ADDR_TABLE_FUNC2_AT_STATUS_BOFFSET 16 +#define ADDR_TABLE_FUNC2_AT_STATUS_BLEN 4 +#define ADDR_TABLE_FUNC2_AT_STATUS_FLAG HSL_RW + +#define CLONE_EN "atbf_clone" +#define ADDR_TABLE_FUNC2_CLONE_EN_BOFFSET 15 +#define ADDR_TABLE_FUNC2_CLONE_EN_BLEN 1 +#define ADDR_TABLE_FUNC2_CLONE_EN_FLAG HSL_RW + +#define SA_DROP_EN "atbf_saden" +#define ADDR_TABLE_FUNC2_SA_DROP_EN_BOFFSET 14 +#define ADDR_TABLE_FUNC2_SA_DROP_EN_BLEN 1 +#define ADDR_TABLE_FUNC2_SA_DROP_EN_FLAG HSL_RW + +#define MIRROR_EN "atbf_miren" +#define ADDR_TABLE_FUNC2_MIRROR_EN_BOFFSET 13 +#define ADDR_TABLE_FUNC2_MIRROR_EN_BLEN 1 +#define ADDR_TABLE_FUNC2_MIRROR_EN_FLAG HSL_RW + +#define AT_PRI_EN "atbf_atpen" +#define ADDR_TABLE_FUNC2_AT_PRI_EN_BOFFSET 12 +#define ADDR_TABLE_FUNC2_AT_PRI_EN_BLEN 1 +#define ADDR_TABLE_FUNC2_AT_PRI_EN_FLAG HSL_RW + +#define AT_PRI "atbf_atpri" +#define ADDR_TABLE_FUNC2_AT_PRI_BOFFSET 10 +#define ADDR_TABLE_FUNC2_AT_PRI_BLEN 2 +#define ADDR_TABLE_FUNC2_AT_PRI_FLAG HSL_RW + +#define DES_PORT "atbf_desp" +#define ADDR_TABLE_FUNC2_DES_PORT_BOFFSET 0 +#define ADDR_TABLE_FUNC2_DES_PORT_BLEN 6 +#define ADDR_TABLE_FUNC2_DES_PORT_FLAG HSL_RW + + + /* Address Table Control Register */ +#define ADDR_TABLE_CTL "atbc" +#define ADDR_TABLE_CTL_ID 14 +#define ADDR_TABLE_CTL_OFFSET 0x005C +#define ADDR_TABLE_CTL_E_LENGTH 4 +#define ADDR_TABLE_CTL_E_OFFSET 0 +#define ADDR_TABLE_CTL_NR_E 1 + +#define ARP_EN "atbc_arpe" +#define ADDR_TABLE_CTL_ARP_EN_BOFFSET 20 +#define ADDR_TABLE_CTL_ARP_EN_BLEN 1 +#define ADDR_TABLE_CTL_ARP_EN_FLAG HSL_RW + +#define ARL_INI_EN "atbc_arlie" +#define ADDR_TABLE_CTL_ARL_INI_EN_BOFFSET 19 +#define ADDR_TABLE_CTL_ARL_INI_EN_BLEN 1 +#define ADDR_TABLE_CTL_ARL_INI_EN_FLAG HSL_RW + +#define LEARN_CHANGE_EN "atbc_lcen" +#define ADDR_TABLE_CTL_LEARN_CHANGE_EN_BOFFSET 18 +#define ADDR_TABLE_CTL_LEARN_CHANGE_EN_BLEN 1 +#define ADDR_TABLE_CTL_LEARN_CHANGE_EN_FLAG HSL_RW + +#define AGE_EN "atbc_agee" +#define ADDR_TABLE_CTL_AGE_EN_BOFFSET 17 +#define ADDR_TABLE_CTL_AGE_EN_BLEN 1 +#define ADDR_TABLE_CTL_AGE_EN_FLAG HSL_RW + +#define AGE_TIME "atbc_aget" +#define ADDR_TABLE_CTL_AGE_TIME_BOFFSET 0 +#define ADDR_TABLE_CTL_AGE_TIME_BLEN 16 +#define ADDR_TABLE_CTL_AGE_TIME_FLAG HSL_RW + + + /* IP Priority Mapping Register */ +#define IP_PRI_MAPPING "imap" +#define IP_PRI_MAPPING_ID 15 +#define IP_PRI_MAPPING_OFFSET 0x0060 +#define IP_PRI_MAPPING_E_LENGTH 4 +#define IP_PRI_MAPPING_E_OFFSET 0 +#define IP_PRI_MAPPING_NR_E 1 + + + /* IP Priority Mapping Register */ +#define IP_PRI_MAPPING0 "imap0" +#define IP_PRI_MAPPING0_ID 15 +#define IP_PRI_MAPPING0_OFFSET 0x0060 +#define IP_PRI_MAPPING0_E_LENGTH 4 +#define IP_PRI_MAPPING0_E_OFFSET 0 +#define IP_PRI_MAPPING0_NR_E 0 + +#define IP_0X3C "imap_ip3c" +#define IP_PRI_MAPPING0_IP_0X3C_BOFFSET 30 +#define IP_PRI_MAPPING0_IP_0X3C_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X3C_FLAG HSL_RW + +#define IP_0X38 "imap_ip38" +#define IP_PRI_MAPPING0_IP_0X38_BOFFSET 28 +#define IP_PRI_MAPPING0_IP_0X38_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X38_FLAG HSL_RW + +#define IP_0X34 "imap_ip34" +#define IP_PRI_MAPPING0_IP_0X34_BOFFSET 26 +#define IP_PRI_MAPPING0_IP_0X34_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X34_FLAG HSL_RW + +#define IP_0X30 "imap_ip30" +#define IP_PRI_MAPPING0_IP_0X30_BOFFSET 24 +#define IP_PRI_MAPPING0_IP_0X30_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X30_FLAG HSL_RW + +#define IP_0X2C "imap_ip2c" +#define IP_PRI_MAPPING0_IP_0X2C_BOFFSET 22 +#define IP_PRI_MAPPING0_IP_0X2C_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X2C_FLAG HSL_RW + +#define IP_0X28 "imap_ip28" +#define IP_PRI_MAPPING0_IP_0X28_BOFFSET 20 +#define IP_PRI_MAPPING0_IP_0X28_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X28_FLAG HSL_RW + +#define IP_0X24 "imap_ip24" +#define IP_PRI_MAPPING0_IP_0X24_BOFFSET 18 +#define IP_PRI_MAPPING0_IP_0X24_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X24_FLAG HSL_RW + +#define IP_0X20 "imap_ip20" +#define IP_PRI_MAPPING0_IP_0X20_BOFFSET 16 +#define IP_PRI_MAPPING0_IP_0X20_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X20_FLAG HSL_RW + +#define IP_0X1C "imap_ip1c" +#define IP_PRI_MAPPING0_IP_0X1C_BOFFSET 14 +#define IP_PRI_MAPPING0_IP_0X1C_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X1C_FLAG HSL_RW + +#define IP_0X18 "imap_ip18" +#define IP_PRI_MAPPING0_IP_0X18_BOFFSET 12 +#define IP_PRI_MAPPING0_IP_0X18_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X18_FLAG HSL_RW + +#define IP_0X14 "imap_ip14" +#define IP_PRI_MAPPING0_IP_0X14_BOFFSET 10 +#define IP_PRI_MAPPING0_IP_0X14_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X14_FLAG HSL_RW + +#define IP_0X10 "imap_ip10" +#define IP_PRI_MAPPING0_IP_0X10_BOFFSET 8 +#define IP_PRI_MAPPING0_IP_0X10_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X10_FLAG HSL_RW + +#define IP_0X0C "imap_ip0c" +#define IP_PRI_MAPPING0_IP_0X0C_BOFFSET 6 +#define IP_PRI_MAPPING0_IP_0X0C_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X0C_FLAG HSL_RW + +#define IP_0X08 "imap_ip08" +#define IP_PRI_MAPPING0_IP_0X08_BOFFSET 4 +#define IP_PRI_MAPPING0_IP_0X08_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X08_FLAG HSL_RW + +#define IP_0X04 "imap_ip04" +#define IP_PRI_MAPPING0_IP_0X04_BOFFSET 2 +#define IP_PRI_MAPPING0_IP_0X04_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X04_FLAG HSL_RW + +#define IP_0X00 "imap_ip00" +#define IP_PRI_MAPPING0_IP_0X00_BOFFSET 0 +#define IP_PRI_MAPPING0_IP_0X00_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X00_FLAG HSL_RW + +#define IP_PRI_MAPPING1 "imap1" +#define IP_PRI_MAPPING1_ID 16 +#define IP_PRI_MAPPING1_OFFSET 0x0064 +#define IP_PRI_MAPPING1_E_LENGTH 4 +#define IP_PRI_MAPPING1_E_OFFSET 0 +#define IP_PRI_MAPPING1_NR_E 0 + +#define IP_0X7C "imap_ip7c" +#define IP_PRI_MAPPING1_IP_0X7C_BOFFSET 30 +#define IP_PRI_MAPPING1_IP_0X7C_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X7C_FLAG HSL_RW + +#define IP_0X78 "imap_ip78" +#define IP_PRI_MAPPING1_IP_0X78_BOFFSET 28 +#define IP_PRI_MAPPING1_IP_0X78_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X78_FLAG HSL_RW + +#define IP_0X74 "imap_ip74" +#define IP_PRI_MAPPING1_IP_0X74_BOFFSET 26 +#define IP_PRI_MAPPING1_IP_0X74_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X74_FLAG HSL_RW + +#define IP_0X70 "imap_ip70" +#define IP_PRI_MAPPING1_IP_0X70_BOFFSET 24 +#define IP_PRI_MAPPING1_IP_0X70_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X70_FLAG HSL_RW + +#define IP_0X6C "imap_ip6c" +#define IP_PRI_MAPPING1_IP_0X6C_BOFFSET 22 +#define IP_PRI_MAPPING1_IP_0X6C_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X6C_FLAG HSL_RW + +#define IP_0X68 "imap_ip68" +#define IP_PRI_MAPPING1_IP_0X68_BOFFSET 20 +#define IP_PRI_MAPPING1_IP_0X68_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X68_FLAG HSL_RW + +#define IP_0X64 "imap_ip64" +#define IP_PRI_MAPPING1_IP_0X64_BOFFSET 18 +#define IP_PRI_MAPPING1_IP_0X64_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X64_FLAG HSL_RW + +#define IP_0X60 "imap_ip60" +#define IP_PRI_MAPPING1_IP_0X60_BOFFSET 16 +#define IP_PRI_MAPPING1_IP_0X60_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X60_FLAG HSL_RW + +#define IP_0X5C "imap_ip5c" +#define IP_PRI_MAPPING1_IP_0X5C_BOFFSET 14 +#define IP_PRI_MAPPING1_IP_0X5C_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X5C_FLAG HSL_RW + +#define IP_0X58 "imap_ip58" +#define IP_PRI_MAPPING1_IP_0X58_BOFFSET 12 +#define IP_PRI_MAPPING1_IP_0X58_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X58_FLAG HSL_RW + +#define IP_0X54 "imap_ip54" +#define IP_PRI_MAPPING1_IP_0X54_BOFFSET 10 +#define IP_PRI_MAPPING1_IP_0X54_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X54_FLAG HSL_RW + +#define IP_0X50 "imap_ip50" +#define IP_PRI_MAPPING1_IP_0X50_BOFFSET 8 +#define IP_PRI_MAPPING1_IP_0X50_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X50_FLAG HSL_RW + +#define IP_0X4C "imap_ip4c" +#define IP_PRI_MAPPING1_IP_0X4C_BOFFSET 6 +#define IP_PRI_MAPPING1_IP_0X4C_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X4C_FLAG HSL_RW + +#define IP_0X48 "imap_ip48" +#define IP_PRI_MAPPING1_IP_0X48_BOFFSET 4 +#define IP_PRI_MAPPING1_IP_0X48_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X48_FLAG HSL_RW + +#define IP_0X44 "imap_ip44" +#define IP_PRI_MAPPING1_IP_0X44_BOFFSET 2 +#define IP_PRI_MAPPING1_IP_0X44_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X44_FLAG HSL_RW + +#define IP_0X40 "imap_ip40" +#define IP_PRI_MAPPING1_IP_0X40_BOFFSET 0 +#define IP_PRI_MAPPING1_IP_0X40_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X40_FLAG HSL_RW + + +#define IP_PRI_MAPPING2 "imap2" +#define IP_PRI_MAPPING2_ID 17 +#define IP_PRI_MAPPING2_OFFSET 0x0068 +#define IP_PRI_MAPPING2_E_LENGTH 4 +#define IP_PRI_MAPPING2_E_OFFSET 0 +#define IP_PRI_MAPPING2_NR_E 0 + +#define IP_0XBC "imap_ipbc" +#define IP_PRI_MAPPING2_IP_0XBC_BOFFSET 30 +#define IP_PRI_MAPPING2_IP_0XBC_BLEN 2 +#define IP_PRI_MAPPING2_IP_0XBC_FLAG HSL_RW + +#define IP_0XB8 "imap_ipb8" +#define IP_PRI_MAPPING2_IP_0XB8_BOFFSET 28 +#define IP_PRI_MAPPING2_IP_0XB8_BLEN 2 +#define IP_PRI_MAPPING2_IP_0XB8_FLAG HSL_RW + +#define IP_0XB4 "imap_ipb4" +#define IP_PRI_MAPPING2_IP_0XB4_BOFFSET 26 +#define IP_PRI_MAPPING2_IP_0XB4_BLEN 2 +#define IP_PRI_MAPPING2_IP_0XB4_FLAG HSL_RW + +#define IP_0XB0 "imap_ipb0" +#define IP_PRI_MAPPING2_IP_0XB0_BOFFSET 24 +#define IP_PRI_MAPPING2_IP_0XB0_BLEN 2 +#define IP_PRI_MAPPING2_IP_0XB0_FLAG HSL_RW + +#define IP_0XAC "imap_ipac" +#define IP_PRI_MAPPING2_IP_0XAC_BOFFSET 22 +#define IP_PRI_MAPPING2_IP_0XAC_BLEN 2 +#define IP_PRI_MAPPING2_IP_0XAC_FLAG HSL_RW + +#define IP_0XA8 "imap_ipa8" +#define IP_PRI_MAPPING2_IP_0XA8_BOFFSET 20 +#define IP_PRI_MAPPING2_IP_0XA8_BLEN 2 +#define IP_PRI_MAPPING2_IP_0XA8_FLAG HSL_RW + +#define IP_0XA4 "imap_ipa4" +#define IP_PRI_MAPPING2_IP_0XA4_BOFFSET 18 +#define IP_PRI_MAPPING2_IP_0XA4_BLEN 2 +#define IP_PRI_MAPPING2_IP_0XA4_FLAG HSL_RW + +#define IP_0XA0 "imap_ipa0" +#define IP_PRI_MAPPING2_IP_0XA0_BOFFSET 16 +#define IP_PRI_MAPPING2_IP_0XA0_BLEN 2 +#define IP_PRI_MAPPING2_IP_0XA0_FLAG HSL_RW + +#define IP_0X9C "imap_ip9c" +#define IP_PRI_MAPPING2_IP_0X9C_BOFFSET 14 +#define IP_PRI_MAPPING2_IP_0X9C_BLEN 2 +#define IP_PRI_MAPPING2_IP_0X9C_FLAG HSL_RW + +#define IP_0X98 "imap_ip98" +#define IP_PRI_MAPPING2_IP_0X98_BOFFSET 12 +#define IP_PRI_MAPPING2_IP_0X98_BLEN 2 +#define IP_PRI_MAPPING2_IP_0X98_FLAG HSL_RW + +#define IP_0X94 "imap_ip94" +#define IP_PRI_MAPPING2_IP_0X94_BOFFSET 10 +#define IP_PRI_MAPPING2_IP_0X94_BLEN 2 +#define IP_PRI_MAPPING2_IP_0X94_FLAG HSL_RW + +#define IP_0X90 "imap_ip90" +#define IP_PRI_MAPPING2_IP_0X90_BOFFSET 8 +#define IP_PRI_MAPPING2_IP_0X90_BLEN 2 +#define IP_PRI_MAPPING2_IP_0X90_FLAG HSL_RW + +#define IP_0X8C "imap_ip8c" +#define IP_PRI_MAPPING2_IP_0X8C_BOFFSET 6 +#define IP_PRI_MAPPING2_IP_0X8C_BLEN 2 +#define IP_PRI_MAPPING2_IP_0X8C_FLAG HSL_RW + +#define IP_0X88 "imap_ip88" +#define IP_PRI_MAPPING2_IP_0X88_BOFFSET 4 +#define IP_PRI_MAPPING2_IP_0X88_BLEN 2 +#define IP_PRI_MAPPING2_IP_0X88_FLAG HSL_RW + +#define IP_0X84 "imap_ip84" +#define IP_PRI_MAPPING2_IP_0X84_BOFFSET 2 +#define IP_PRI_MAPPING2_IP_0X84_BLEN 2 +#define IP_PRI_MAPPING2_IP_0X84_FLAG HSL_RW + +#define IP_0X80 "imap_ip80" +#define IP_PRI_MAPPING2_IP_0X80_BOFFSET 0 +#define IP_PRI_MAPPING2_IP_0X80_BLEN 2 +#define IP_PRI_MAPPING2_IP_0X80_FLAG HSL_RW + +#define IP_PRI_MAPPING3 "imap3" +#define IP_PRI_MAPPING3_ID 18 +#define IP_PRI_MAPPING3_OFFSET 0x006C +#define IP_PRI_MAPPING3_E_LENGTH 4 +#define IP_PRI_MAPPING3_E_OFFSET 0 +#define IP_PRI_MAPPING3_NR_E 0 + +#define IP_0XFC "imap_ipfc" +#define IP_PRI_MAPPING3_IP_0XFC_BOFFSET 30 +#define IP_PRI_MAPPING3_IP_0XFC_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XFC_FLAG HSL_RW + +#define IP_0XF8 "imap_ipf8" +#define IP_PRI_MAPPING3_IP_0XF8_BOFFSET 28 +#define IP_PRI_MAPPING3_IP_0XF8_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XF8_FLAG HSL_RW + +#define IP_0XF4 "imap_ipf4" +#define IP_PRI_MAPPING3_IP_0XF4_BOFFSET 26 +#define IP_PRI_MAPPING3_IP_0XF4_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XF4_FLAG HSL_RW + +#define IP_0XF0 "imap_ipf0" +#define IP_PRI_MAPPING3_IP_0XF0_BOFFSET 24 +#define IP_PRI_MAPPING3_IP_0XF0_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XF0_FLAG HSL_RW + +#define IP_0XEC "imap_ipec" +#define IP_PRI_MAPPING3_IP_0XEC_BOFFSET 22 +#define IP_PRI_MAPPING3_IP_0XEC_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XEC_FLAG HSL_RW + +#define IP_0XE8 "imap_ipe8" +#define IP_PRI_MAPPING3_IP_0XE8_BOFFSET 20 +#define IP_PRI_MAPPING3_IP_0XE8_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XE8_FLAG HSL_RW + +#define IP_0XE4 "imap_ipe4" +#define IP_PRI_MAPPING3_IP_0XE4_BOFFSET 18 +#define IP_PRI_MAPPING3_IP_0XE4_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XE4_FLAG HSL_RW + +#define IP_0XE0 "imap_ipe0" +#define IP_PRI_MAPPING3_IP_0XE0_BOFFSET 16 +#define IP_PRI_MAPPING3_IP_0XE0_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XE0_FLAG HSL_RW + +#define IP_0XDC "imap_ipdc" +#define IP_PRI_MAPPING3_IP_0XDC_BOFFSET 14 +#define IP_PRI_MAPPING3_IP_0XDC_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XDC_FLAG HSL_RW + +#define IP_0XD8 "imap_ipd8" +#define IP_PRI_MAPPING3_IP_0XD8_BOFFSET 12 +#define IP_PRI_MAPPING3_IP_0XD8_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XD8_FLAG HSL_RW + +#define IP_0XD4 "imap_ipd4" +#define IP_PRI_MAPPING3_IP_0XD4_BOFFSET 10 +#define IP_PRI_MAPPING3_IP_0XD4_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XD4_FLAG HSL_RW + +#define IP_0XD0 "imap_ipd0" +#define IP_PRI_MAPPING3_IP_0XD0_BOFFSET 8 +#define IP_PRI_MAPPING3_IP_0XD0_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XD0_FLAG HSL_RW + +#define IP_0XCC "imap_ipcc" +#define IP_PRI_MAPPING3_IP_0XCC_BOFFSET 6 +#define IP_PRI_MAPPING3_IP_0XCC_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XCC_FLAG HSL_RW + +#define IP_0XC8 "imap_ipc8" +#define IP_PRI_MAPPING3_IP_0XC8_BOFFSET 4 +#define IP_PRI_MAPPING3_IP_0XC8_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XC8_FLAG HSL_RW + +#define IP_0XC4 "imap_ipc4" +#define IP_PRI_MAPPING3_IP_0XC4_BOFFSET 2 +#define IP_PRI_MAPPING3_IP_0XC4_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XC4_FLAG HSL_RW + +#define IP_0XC0 "imap_ipc0" +#define IP_PRI_MAPPING3_IP_0XC0_BOFFSET 0 +#define IP_PRI_MAPPING3_IP_0XC0_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XC0_FLAG HSL_RW + + + /* Tag Priority Mapping Register */ +#define TAG_PRI_MAPPING "tpmap" +#define TAG_PRI_MAPPING_ID 19 +#define TAG_PRI_MAPPING_OFFSET 0x0070 +#define TAG_PRI_MAPPING_E_LENGTH 4 +#define TAG_PRI_MAPPING_E_OFFSET 0 +#define TAG_PRI_MAPPING_NR_E 1 + +#define TAG_0X07 "tpmap_tg07" +#define TAG_PRI_MAPPING_TAG_0X07_BOFFSET 14 +#define TAG_PRI_MAPPING_TAG_0X07_BLEN 2 +#define TAG_PRI_MAPPING_TAG_0X07_FLAG HSL_RW + +#define TAG_0X06 "tpmap_tg06" +#define TAG_PRI_MAPPING_TAG_0X06_BOFFSET 12 +#define TAG_PRI_MAPPING_TAG_0X06_BLEN 2 +#define TAG_PRI_MAPPING_TAG_0X06_FLAG HSL_RW + +#define TAG_0X05 "tpmap_tg05" +#define TAG_PRI_MAPPING_TAG_0X05_BOFFSET 10 +#define TAG_PRI_MAPPING_TAG_0X05_BLEN 2 +#define TAG_PRI_MAPPING_TAG_0X05_FLAG HSL_RW + +#define TAG_0X04 "tpmap_tg04" +#define TAG_PRI_MAPPING_TAG_0X04_BOFFSET 8 +#define TAG_PRI_MAPPING_TAG_0X04_BLEN 2 +#define TAG_PRI_MAPPING_TAG_0X04_FLAG HSL_RW + +#define TAG_0X03 "tpmap_tg03" +#define TAG_PRI_MAPPING_TAG_0X03_BOFFSET 6 +#define TAG_PRI_MAPPING_TAG_0X03_BLEN 2 +#define TAG_PRI_MAPPING_TAG_0X03_FLAG HSL_RW + +#define TAG_0X02 "tpmap_tg02" +#define TAG_PRI_MAPPING_TAG_0X02_BOFFSET 4 +#define TAG_PRI_MAPPING_TAG_0X02_BLEN 2 +#define TAG_PRI_MAPPING_TAG_0X02_FLAG HSL_RW + +#define TAG_0X01 "tpmap_tg01" +#define TAG_PRI_MAPPING_TAG_0X01_BOFFSET 2 +#define TAG_PRI_MAPPING_TAG_0X01_BLEN 2 +#define TAG_PRI_MAPPING_TAG_0X01_FLAG HSL_RW + +#define TAG_0X00 "tpmap_tg00" +#define TAG_PRI_MAPPING_TAG_0X00_BOFFSET 0 +#define TAG_PRI_MAPPING_TAG_0X00_BLEN 2 +#define TAG_PRI_MAPPING_TAG_0X00_FLAG HSL_RW + + + /* Service tag Register */ +#define SERVICE_TAG "servicetag" +#define SERVICE_TAG_ID 20 +#define SERVICE_TAG_OFFSET 0x0074 +#define SERVICE_TAG_E_LENGTH 4 +#define SERVICE_TAG_E_OFFSET 0 +#define SERVICE_TAG_NR_E 1 + +#define TAG_VALUE "servicetag_val" +#define SERVICE_TAG_TAG_VALUE_BOFFSET 0 +#define SERVICE_TAG_TAG_VALUE_BLEN 16 +#define SERVICE_TAG_TAG_VALUE_FLAG HSL_RW + + + /* Cpu Port Register */ +#define CPU_PORT "cpup" +#define CPU_PORT_ID 20 +#define CPU_PORT_OFFSET 0x0078 +#define CPU_PORT_E_LENGTH 4 +#define CPU_PORT_E_OFFSET 0 +#define CPU_PORT_NR_E 0 + +#define CPU_PORT_EN "cpup_cpupe" +#define CPU_PORT_CPU_PORT_EN_BOFFSET 8 +#define CPU_PORT_CPU_PORT_EN_BLEN 1 +#define CPU_PORT_CPU_PORT_EN_FLAG HSL_RW + +#define MIRROR_PORT_NUM "cpup_mirpn" +#define CPU_PORT_MIRROR_PORT_NUM_BOFFSET 4 +#define CPU_PORT_MIRROR_PORT_NUM_BLEN 4 +#define CPU_PORT_MIRROR_PORT_NUM_FLAG HSL_RW + + + /* MIB Function Register */ +#define MIB_FUNC "mibfunc" +#define MIB_FUNC_ID 21 +#define MIB_FUNC_OFFSET 0x0080 +#define MIB_FUNC_E_LENGTH 4 +#define MIB_FUNC_E_OFFSET 0 +#define MIB_FUNC_NR_E 1 + +#define MAC_CRC_EN "mibfunc_crcen" +#define MIB_FUNC_MAC_CRC_EN_BOFFSET 31 +#define MIB_FUNC_MAC_CRC_EN_BLEN 1 +#define MIB_FUNC_MAC_CRC_EN_FLAG HSL_RW + +#define MIB_EN "mib_en" +#define MIB_FUNC_MIB_EN_BOFFSET 30 +#define MIB_FUNC_MIB_EN_BLEN 1 +#define MIB_FUNC_MIB_EN_FLAG HSL_RW + +#define MIB_FUN "mibfunc_mibf" +#define MIB_FUNC_MIB_FUN_BOFFSET 24 +#define MIB_FUNC_MIB_FUN_BLEN 3 +#define MIB_FUNC_MIB_FUN_FLAG HSL_RW + +#define MIB_BUSY "mibfunc_mibb" +#define MIB_FUNC_MIB_BUSY_BOFFSET 17 +#define MIB_FUNC_MIB_BUSY_BLEN 1 +#define MIB_FUNC_MIB_BUSY_FLAG HSL_RW + +#define MIB_AT_HALF_EN "mibfunc_mibhe" +#define MIB_FUNC_MIB_AT_HALF_EN_BOFFSET 16 +#define MIB_FUNC_MIB_AT_HALF_EN_BLEN 1 +#define MIB_FUNC_MIB_AT_HALF_EN_FLAG HSL_RW + +#define MIB_TIMER "mibfunc_mibt" +#define MIB_FUNC_MIB_TIMER_BOFFSET 0 +#define MIB_FUNC_MIB_TIMER_BLEN 16 +#define MIB_FUNC_MIB_TIMER_FLAG HSL_RW + + + /* Mdio control Register */ +#define MDIO_CTRL "mctrl" +#define MDIO_CTRL_ID 24 +#define MDIO_CTRL_OFFSET 0x0098 +#define MDIO_CTRL_E_LENGTH 4 +#define MDIO_CTRL_E_OFFSET 0 +#define MDIO_CTRL_NR_E 1 + +#define MSTER_EN "mctrl_msteren" +#define MDIO_CTRL_MSTER_EN_BOFFSET 30 +#define MDIO_CTRL_MSTER_EN_BLEN 1 +#define MDIO_CTRL_MSTER_EN_FLAG HSL_RW + +#define MSTER_EN "mctrl_msteren" +#define MDIO_CTRL_MSTER_EN_BOFFSET 30 +#define MDIO_CTRL_MSTER_EN_BLEN 1 +#define MDIO_CTRL_MSTER_EN_FLAG HSL_RW + +#define CMD "mctrl_cmd" +#define MDIO_CTRL_CMD_BOFFSET 27 +#define MDIO_CTRL_CMD_BLEN 1 +#define MDIO_CTRL_CMD_FLAG HSL_RW + +#define SUP_PRE "mctrl_spre" +#define MDIO_CTRL_SUP_PRE_BOFFSET 26 +#define MDIO_CTRL_SUP_PRE_BLEN 1 +#define MDIO_CTRL_SUP_PRE_FLAG HSL_RW + +#define PHY_ADDR "mctrl_phyaddr" +#define MDIO_CTRL_PHY_ADDR_BOFFSET 21 +#define MDIO_CTRL_PHY_ADDR_BLEN 5 +#define MDIO_CTRL_PHY_ADDR_FLAG HSL_RW + +#define REG_ADDR "mctrl_regaddr" +#define MDIO_CTRL_REG_ADDR_BOFFSET 16 +#define MDIO_CTRL_REG_ADDR_BLEN 5 +#define MDIO_CTRL_REG_ADDR_FLAG HSL_RW + +#define DATA "mctrl_data" +#define MDIO_CTRL_DATA_BOFFSET 0 +#define MDIO_CTRL_DATA_BLEN 16 +#define MDIO_CTRL_DATA_FLAG HSL_RW + + + + + /* BIST control Register */ +#define BIST_CTRL "bctrl" +#define BIST_CTRL_ID 24 +#define BIST_CTRL_OFFSET 0x00a0 +#define BIST_CTRL_E_LENGTH 4 +#define BIST_CTRL_E_OFFSET 0 +#define BIST_CTRL_NR_E 1 + +#define BIST_BUSY "bctrl_bb" +#define BIST_CTRL_BIST_BUSY_BOFFSET 31 +#define BIST_CTRL_BIST_BUSY_BLEN 1 +#define BIST_CTRL_BIST_BUSY_FLAG HSL_RW + +#define ONE_ERR "bctrl_oe" +#define BIST_CTRL_ONE_ERR_BOFFSET 30 +#define BIST_CTRL_ONE_ERR_BLEN 1 +#define BIST_CTRL_ONE_ERR_FLAG HSL_RO + +#define ERR_MEM "bctrl_em" +#define BIST_CTRL_ERR_MEM_BOFFSET 24 +#define BIST_CTRL_ERR_MEM_BLEN 4 +#define BIST_CTRL_ERR_MEM_FLAG HSL_RO + +#define PTN_EN2 "bctrl_pe2" +#define BIST_CTRL_PTN_EN2_BOFFSET 22 +#define BIST_CTRL_PTN_EN2_BLEN 1 +#define BIST_CTRL_PTN_EN2_FLAG HSL_RW + +#define PTN_EN1 "bctrl_pe1" +#define BIST_CTRL_PTN_EN1_BOFFSET 21 +#define BIST_CTRL_PTN_EN1_BLEN 1 +#define BIST_CTRL_PTN_EN1_FLAG HSL_RW + +#define PTN_EN0 "bctrl_pe0" +#define BIST_CTRL_PTN_EN0_BOFFSET 20 +#define BIST_CTRL_PTN_EN0_BLEN 1 +#define BIST_CTRL_PTN_EN0_FLAG HSL_RW + +#define ERR_PTN "bctrl_ep" +#define BIST_CTRL_ERR_PTN_BOFFSET 16 +#define BIST_CTRL_ERR_PTN_BLEN 2 +#define BIST_CTRL_ERR_PTN_FLAG HSL_RO + +#define ERR_CNT "bctrl_ec" +#define BIST_CTRL_ERR_CNT_BOFFSET 13 +#define BIST_CTRL_ERR_CNT_BLEN 3 +#define BIST_CTRL_ERR_CNT_FLAG HSL_RO + +#define ERR_ADDR "bctrl_ea" +#define BIST_CTRL_ERR_ADDR_BOFFSET 0 +#define BIST_CTRL_ERR_ADDR_BLEN 13 +#define BIST_CTRL_ERR_ADDR_FLAG HSL_RO + + + + + /* BIST recover Register */ +#define BIST_RCV "brcv" +#define BIST_RCV_ID 24 +#define BIST_RCV_OFFSET 0x00a4 +#define BIST_RCV_E_LENGTH 4 +#define BIST_RCV_E_OFFSET 0 +#define BIST_RCV_NR_E 1 + +#define RCV_EN "brcv_en" +#define BIST_RCV_RCV_EN_BOFFSET 31 +#define BIST_RCV_RCV_EN_BLEN 1 +#define BIST_RCV_RCV_EN_FLAG HSL_RW + +#define RCV_ADDR "brcv_addr" +#define BIST_RCV_RCV_ADDR_BOFFSET 0 +#define BIST_RCV_RCV_ADDR_BLEN 13 +#define BIST_RCV_RCV_ADDR_FLAG HSL_RW + + + + + /* LED control Register */ +#define LED_CTRL "ledctrl" +#define LED_CTRL_ID 25 +#define LED_CTRL_OFFSET 0x00b0 +#define LED_CTRL_E_LENGTH 4 +#define LED_CTRL_E_OFFSET 0 +#define LED_CTRL_NR_E 1 + +#define PATTERN_EN "lctrl_pen" +#define LED_CTRL_PATTERN_EN_BOFFSET 14 +#define LED_CTRL_PATTERN_EN_BLEN 2 +#define LED_CTRL_PATTERN_EN_FLAG HSL_RW + +#define FULL_LIGHT_EN "lctrl_fen" +#define LED_CTRL_FULL_LIGHT_EN_BOFFSET 13 +#define LED_CTRL_FULL_LIGHT_EN_BLEN 1 +#define LED_CTRL_FULL_LIGHT_EN_FLAG HSL_RW + +#define HALF_LIGHT_EN "lctrl_hen" +#define LED_CTRL_HALF_LIGHT_EN_BOFFSET 12 +#define LED_CTRL_HALF_LIGHT_EN_BLEN 1 +#define LED_CTRL_HALF_LIGHT_EN_FLAG HSL_RW + +#define POWERON_LIGHT_EN "lctrl_poen" +#define LED_CTRL_POWERON_LIGHT_EN_BOFFSET 11 +#define LED_CTRL_POWERON_LIGHT_EN_BLEN 1 +#define LED_CTRL_POWERON_LIGHT_EN_FLAG HSL_RW + +#define GE_LIGHT_EN "lctrl_geen" +#define LED_CTRL_GE_LIGHT_EN_BOFFSET 10 +#define LED_CTRL_GE_LIGHT_EN_BLEN 1 +#define LED_CTRL_GE_LIGHT_EN_FLAG HSL_RW + +#define FE_LIGHT_EN "lctrl_feen" +#define LED_CTRL_FE_LIGHT_EN_BOFFSET 9 +#define LED_CTRL_FE_LIGHT_EN_BLEN 1 +#define LED_CTRL_FE_LIGHT_EN_FLAG HSL_RW + +#define ETH_LIGHT_EN "lctrl_ethen" +#define LED_CTRL_ETH_LIGHT_EN_BOFFSET 8 +#define LED_CTRL_ETH_LIGHT_EN_BLEN 1 +#define LED_CTRL_ETH_LIGHT_EN_FLAG HSL_RW + +#define COL_BLINK_EN "lctrl_cen" +#define LED_CTRL_COL_BLINK_EN_BOFFSET 7 +#define LED_CTRL_COL_BLINK_EN_BLEN 1 +#define LED_CTRL_COL_BLINK_EN_FLAG HSL_RW + +#define RX_BLINK_EN "lctrl_rxen" +#define LED_CTRL_RX_BLINK_EN_BOFFSET 5 +#define LED_CTRL_RX_BLINK_EN_BLEN 1 +#define LED_CTRL_RX_BLINK_EN_FLAG HSL_RW + +#define TX_BLINK_EN "lctrl_txen" +#define LED_CTRL_TX_BLINK_EN_BOFFSET 4 +#define LED_CTRL_TX_BLINK_EN_BLEN 1 +#define LED_CTRL_TX_BLINK_EN_FLAG HSL_RW + +#define LINKUP_OVER_EN "lctrl_loen" +#define LED_CTRL_LINKUP_OVER_EN_BOFFSET 2 +#define LED_CTRL_LINKUP_OVER_EN_BLEN 1 +#define LED_CTRL_LINKUP_OVER_EN_FLAG HSL_RW + +#define BLINK_FREQ "lctrl_bfreq" +#define LED_CTRL_BLINK_FREQ_BOFFSET 0 +#define LED_CTRL_BLINK_FREQ_BLEN 2 +#define LED_CTRL_BLINK_FREQ_FLAG HSL_RW + + + /* Port Status Register */ +#define PORT_STATUS "ptsts" +#define PORT_STATUS_ID 29 +#define PORT_STATUS_OFFSET 0x0100 +#define PORT_STATUS_E_LENGTH 4 +#define PORT_STATUS_E_OFFSET 0x0100 +#define PORT_STATUS_NR_E 6 + +#define FLOW_LINK_EN "ptsts_flen" +#define PORT_STATUS_FLOW_LINK_EN_BOFFSET 12 +#define PORT_STATUS_FLOW_LINK_EN_BLEN 1 +#define PORT_STATUS_FLOW_LINK_EN_FLAG HSL_RW + + +#define LINK_ASYN_PAUSE "ptsts_lasynp" +#define PORT_STATUS_LINK_ASYN_PAUSE_BOFFSET 11 +#define PORT_STATUS_LINK_ASYN_PAUSE_BLEN 1 +#define PORT_STATUS_LINK_ASYN_PAUSE_FLAG HSL_RO + +#define LINK_PAUSE "ptsts_lpause" +#define PORT_STATUS_LINK_PAUSE_BOFFSET 10 +#define PORT_STATUS_LINK_PAUSE_BLEN 1 +#define PORT_STATUS_LINK_PAUSE_FLAG HSL_RO + +#define LINK_EN "ptsts_linken" +#define PORT_STATUS_LINK_EN_BOFFSET 9 +#define PORT_STATUS_LINK_EN_BLEN 1 +#define PORT_STATUS_LINK_EN_FLAG HSL_RW + +#define LINK "ptsts_ptlink" +#define PORT_STATUS_LINK_BOFFSET 8 +#define PORT_STATUS_LINK_BLEN 1 +#define PORT_STATUS_LINK_FLAG HSL_RO + +#define TX_HALF_FLOW_EN +#define PORT_STATUS_TX_HALF_FLOW_EN_BOFFSET 7 +#define PORT_STATUS_TX_HALF_FLOW_EN_BLEN 1 +#define PORT_STATUS_TX_HALF_FLOW_EN_FLAG HSL_RW + +#define DUPLEX_MODE "ptsts_dupmod" +#define PORT_STATUS_DUPLEX_MODE_BOFFSET 6 +#define PORT_STATUS_DUPLEX_MODE_BLEN 1 +#define PORT_STATUS_DUPLEX_MODE_FLAG HSL_RW + +#define RX_FLOW_EN "ptsts_rxfwen" +#define PORT_STATUS_RX_FLOW_EN_BOFFSET 5 +#define PORT_STATUS_RX_FLOW_EN_BLEN 1 +#define PORT_STATUS_RX_FLOW_EN_FLAG HSL_RW + +#define TX_FLOW_EN "ptsts_txfwen" +#define PORT_STATUS_TX_FLOW_EN_BOFFSET 4 +#define PORT_STATUS_TX_FLOW_EN_BLEN 1 +#define PORT_STATUS_TX_FLOW_EN_FLAG HSL_RW + +#define RXMAC_EN "ptsts_rxmacen" +#define PORT_STATUS_RXMAC_EN_BOFFSET 3 +#define PORT_STATUS_RXMAC_EN_BLEN 1 +#define PORT_STATUS_RXMAC_EN_FLAG HSL_RW + +#define TXMAC_EN "ptsts_txmacen" +#define PORT_STATUS_TXMAC_EN_BOFFSET 2 +#define PORT_STATUS_TXMAC_EN_BLEN 1 +#define PORT_STATUS_TXMAC_EN_FLAG HSL_RW + +#define SPEED_MODE "ptsts_speed" +#define PORT_STATUS_SPEED_MODE_BOFFSET 0 +#define PORT_STATUS_SPEED_MODE_BLEN 2 +#define PORT_STATUS_SPEED_MODE_FLAG HSL_RW + + + /* Port Control Register */ +#define PORT_CTL "pctl" +#define PORT_CTL_ID 30 +#define PORT_CTL_OFFSET 0x0104 +#define PORT_CTL_E_LENGTH 4 +#define PORT_CTL_E_OFFSET 0x0100 +#define PORT_CTL_NR_E 6 + +#define LEAVE_EN "pctl_leaveen" +#define PORT_CTL_LEAVE_EN_BOFFSET 21 +#define PORT_CTL_LEAVE_EN_BLEN 1 +#define PORT_CTL_LEAVE_EN_FLAG HSL_RW + +#define JOIN_EN "pctl_joinen" +#define PORT_CTL_JOIN_EN_BOFFSET 20 +#define PORT_CTL_JOIN_EN_BLEN 1 +#define PORT_CTL_JOIN_EN_FLAG HSL_RW + +#define DHCP_EN "pctl_dhcpen" +#define PORT_CTL_DHCP_EN_BOFFSET 19 +#define PORT_CTL_DHCP_EN_BLEN 1 +#define PORT_CTL_DHCP_EN_FLAG HSL_RW + +#define ING_MIRROR_EN "pctl_ingmiren" +#define PORT_CTL_ING_MIRROR_EN_BOFFSET 17 +#define PORT_CTL_ING_MIRROR_EN_BLEN 1 +#define PORT_CTL_ING_MIRROR_EN_FLAG HSL_RW + +#define EG_MIRROR_EN "pctl_egmiren" +#define PORT_CTL_EG_MIRROR_EN_BOFFSET 16 +#define PORT_CTL_EG_MIRROR_EN_BLEN 1 +#define PORT_CTL_EG_MIRROR_EN_FLAG HSL_RW + +#define DTAG_EN "pctl_dtagen" +#define PORT_CTL_DTAG_EN_BOFFSET 15 +#define PORT_CTL_DTAG_EN_BLEN 1 +#define PORT_CTL_DTAG_EN_FLAG HSL_RW + +#define LEARN_EN "pctl_learnen" +#define PORT_CTL_LEARN_EN_BOFFSET 14 +#define PORT_CTL_LEARN_EN_BLEN 1 +#define PORT_CTL_LEARN_EN_FLAG HSL_RW + +#define SINGLE_VLAN_EN "pctl_svlanen" +#define PORT_CTL_SINGLE_VLAN_EN_BOFFSET 13 +#define PORT_CTL_SINGLE_VLAN_EN_BLEN 1 +#define PORT_CTL_SINGLE_VLAN_EN_FLAG HSL_RW + +#define MAC_LOOP_BACK "pctl_maclp" +#define PORT_CTL_MAC_LOOP_BACK_BOFFSET 12 +#define PORT_CTL_MAC_LOOP_BACK_BLEN 1 +#define PORT_CTL_MAC_LOOP_BACK_FLAG HSL_RW + +#define HEAD_EN "pctl_headen" +#define PORT_CTL_HEAD_EN_BOFFSET 11 +#define PORT_CTL_HEAD_EN_BLEN 1 +#define PORT_CTL_HEAD_EN_FLAG HSL_RW + +#define IGMP_MLD_EN "pctl_imlden" +#define PORT_CTL_IGMP_MLD_EN_BOFFSET 10 +#define PORT_CTL_IGMP_MLD_EN_BLEN 1 +#define PORT_CTL_IGMP_MLD_EN_FLAG HSL_RW + +#define EG_VLAN_MODE "pctl_egvmode" +#define PORT_CTL_EG_VLAN_MODE_BOFFSET 8 +#define PORT_CTL_EG_VLAN_MODE_BLEN 2 +#define PORT_CTL_EG_VLAN_MODE_FLAG HSL_RW + +#define LEARN_ONE_LOCK "pctl_lonelck" +#define PORT_CTL_LEARN_ONE_LOCK_BOFFSET 7 +#define PORT_CTL_LEARN_ONE_LOCK_BLEN 1 +#define PORT_CTL_LEARN_ONE_LOCK_FLAG HSL_RW + +#define PORT_LOCK_EN "pctl_locken" +#define PORT_CTL_PORT_LOCK_EN_BOFFSET 6 +#define PORT_CTL_PORT_LOCK_EN_BLEN 1 +#define PORT_CTL_PORT_LOCK_EN_FLAG HSL_RW + +#define LOCK_DROP_EN "pctl_dropen" +#define PORT_CTL_LOCK_DROP_EN_BOFFSET 5 +#define PORT_CTL_LOCK_DROP_EN_BLEN 1 +#define PORT_CTL_LOCK_DROP_EN_FLAG HSL_RW + +#define PORT_STATE "pctl_pstate" +#define PORT_CTL_PORT_STATE_BOFFSET 0 +#define PORT_CTL_PORT_STATE_BLEN 3 +#define PORT_CTL_PORT_STATE_FLAG HSL_RW + + + /* Port Based Vlan Register */ +#define PORT_BASE_VLAN "pbvlan" +#define PORT_BASE_VLAN_ID 31 +#define PORT_BASE_VLAN_OFFSET 0x0108 +#define PORT_BASE_VLAN_E_LENGTH 4 +#define PORT_BASE_VLAN_E_OFFSET 0x0100 +#define PORT_BASE_VLAN_NR_E 6 + +#define DOT1Q_MODE "pbvlan_8021q" +#define PORT_BASE_VLAN_DOT1Q_MODE_BOFFSET 30 +#define PORT_BASE_VLAN_DOT1Q_MODE_BLEN 2 +#define PORT_BASE_VLAN_DOT1Q_MODE_FLAG HSL_RW + +#define ING_PRI "pbvlan_ingpri" +#define PORT_BASE_VLAN_ING_PRI_BOFFSET 27 +#define PORT_BASE_VLAN_ING_PRI_BLEN 3 +#define PORT_BASE_VLAN_ING_PRI_FLAG HSL_RW + +#define FORCE_PVLAN "pbvlan_fpvlan" +#define PORT_BASE_VLAN_FORCE_PVLAN_BOFFSET 26 +#define PORT_BASE_VLAN_FORCE_PVLAN_BLEN 1 +#define PORT_BASE_VLAN_FORCE_PVLAN_FLAG HSL_RW + +#define PORT_VID_MEM "pbvlan_pvidm" +#define PORT_BASE_VLAN_PORT_VID_MEM_BOFFSET 16 +#define PORT_BASE_VLAN_PORT_VID_MEM_BLEN 6 +#define PORT_BASE_VLAN_PORT_VID_MEM_FLAG HSL_RW + +#define ARP_LEAKY_EN "pbvlan_alen" +#define PORT_BASE_VLAN_ARP_LEAKY_EN_BOFFSET 15 +#define PORT_BASE_VLAN_ARP_LEAKY_EN_BLEN 1 +#define PORT_BASE_VLAN_ARP_LEAKY_EN_FLAG HSL_RW + +#define UNI_LEAKY_EN "pbvlan_ulen" +#define PORT_BASE_VLAN_UNI_LEAKY_EN_BOFFSET 14 +#define PORT_BASE_VLAN_UNI_LEAKY_EN_BLEN 1 +#define PORT_BASE_VLAN_UNI_LEAKY_EN_FLAG HSL_RW + +#define MUL_LEAKY_EN "pbvlan_mlen" +#define PORT_BASE_VLAN_MUL_LEAKY_EN_BOFFSET 13 +#define PORT_BASE_VLAN_MUL_LEAKY_EN_BLEN 1 +#define PORT_BASE_VLAN_MUL_LEAKY_EN_FLAG HSL_RW + +#define FORCE_DEF_VID "pbvlan_fdvid" +#define PORT_BASE_VLAN_FORCE_DEF_VID_BOFFSET 12 +#define PORT_BASE_VLAN_FORCE_DEF_VID_BLEN 1 +#define PORT_BASE_VLAN_FORCE_DEF_VID_FLAG HSL_RW + +#define PORT_VID "pbvlan_ptvid" +#define PORT_BASE_VLAN_PORT_VID_BOFFSET 0 +#define PORT_BASE_VLAN_PORT_VID_BLEN 12 +#define PORT_BASE_VLAN_PORT_VID_FLAG HSL_RW + + + /* Port Rate Limit0 Register */ +#define RATE_LIMIT0 "rlmt0" +#define RATE_LIMIT0_ID 32 +#define RATE_LIMIT0_OFFSET 0x010C +#define RATE_LIMIT0_E_LENGTH 4 +#define RATE_LIMIT0_E_OFFSET 0x0100 +#define RATE_LIMIT0_NR_E 6 + +#define ADD_RATE_BYTE "rlmt_addbyte" +#define RATE_LIMIT0_ADD_RATE_BYTE_BOFFSET 24 +#define RATE_LIMIT0_ADD_RATE_BYTE_BLEN 8 +#define RATE_LIMIT0_ADD_RATE_BYTE_FLAG HSL_RW + +#define EG_RATE_EN "rlmt_egen" +#define RATE_LIMIT0_EG_RATE_EN_BOFFSET 23 +#define RATE_LIMIT0_EG_RATE_EN_BLEN 1 +#define RATE_LIMIT0_EG_RATE_EN_FLAG HSL_RW + +#define EG_MNG_RATE_EN "rlmt_egmngen" +#define RATE_LIMIT0_EG_MNG_RATE_EN_BOFFSET 22 +#define RATE_LIMIT0_EG_MNG_RATE_EN_BLEN 1 +#define RATE_LIMIT0_EG_MNG_RATE_EN_FLAG HSL_RW + +#define IN_MNG_RATE_EN "rlmt_inmngen" +#define RATE_LIMIT0_IN_MNG_RATE_EN_BOFFSET 21 +#define RATE_LIMIT0_IN_MNG_RATE_EN_BLEN 1 +#define RATE_LIMIT0_IN_MNG_RATE_EN_FLAG HSL_RW + +#define IN_MUL_RATE_EN "rlmt_inmulen" +#define RATE_LIMIT0_IN_MUL_RATE_EN_BOFFSET 20 +#define RATE_LIMIT0_IN_MUL_RATE_EN_BLEN 1 +#define RATE_LIMIT0_IN_MUL_RATE_EN_FLAG HSL_RW + +#define ING_RATE "rlmt_ingrate" +#define RATE_LIMIT0_ING_RATE_BOFFSET 0 +#define RATE_LIMIT0_ING_RATE_BLEN 15 +#define RATE_LIMIT0_ING_RATE_FLAG HSL_RW + + + /* Priority Control Register */ +#define PRI_CTL "prctl" +#define PRI_CTL_ID 33 +#define PRI_CTL_OFFSET 0x0110 +#define PRI_CTL_E_LENGTH 4 +#define PRI_CTL_E_OFFSET 0x0100 +#define PRI_CTL_NR_E 6 + +#define PORT_PRI_EN "prctl_ptprien" +#define PRI_CTL_PORT_PRI_EN_BOFFSET 19 +#define PRI_CTL_PORT_PRI_EN_BLEN 1 +#define PRI_CTL_PORT_PRI_EN_FLAG HSL_RW + +#define DA_PRI_EN "prctl_daprien" +#define PRI_CTL_DA_PRI_EN_BOFFSET 18 +#define PRI_CTL_DA_PRI_EN_BLEN 1 +#define PRI_CTL_DA_PRI_EN_FLAG HSL_RW + +#define VLAN_PRI_EN "prctl_vprien" +#define PRI_CTL_VLAN_PRI_EN_BOFFSET 17 +#define PRI_CTL_VLAN_PRI_EN_BLEN 1 +#define PRI_CTL_VLAN_PRI_EN_FLAG HSL_RW + +#define IP_PRI_EN "prctl_ipprien" +#define PRI_CTL_IP_PRI_EN_BOFFSET 16 +#define PRI_CTL_IP_PRI_EN_BLEN 1 +#define PRI_CTL_IP_PRI_EN_FLAG HSL_RW + +#define DA_PRI_SEL "prctl_dapris" +#define PRI_CTL_DA_PRI_SEL_BOFFSET 6 +#define PRI_CTL_DA_PRI_SEL_BLEN 2 +#define PRI_CTL_DA_PRI_SEL_FLAG HSL_RW + +#define VLAN_PRI_SEL "prctl_vpris" +#define PRI_CTL_VLAN_PRI_SEL_BOFFSET 4 +#define PRI_CTL_VLAN_PRI_SEL_BLEN 2 +#define PRI_CTL_VLAN_PRI_SEL_FLAG HSL_RW + +#define IP_PRI_SEL "prctl_ippris" +#define PRI_CTL_IP_PRI_SEL_BOFFSET 2 +#define PRI_CTL_IP_PRI_SEL_BLEN 2 +#define PRI_CTL_IP_PRI_SEL_FLAG HSL_RW + +#define PORT_PRI_SEL "prctl_ptpris" +#define PRI_CTL_PORT_PRI_SEL_BOFFSET 0 +#define PRI_CTL_PORT_PRI_SEL_BLEN 2 +#define PRI_CTL_PORT_PRI_SEL_FLAG HSL_RW + + + /* Storm Control Register */ +#define STORM_CTL "sctrl" +#define STORM_CTL_ID 33 +#define STORM_CTL_OFFSET 0x0114 +#define STORM_CTL_E_LENGTH 4 +#define STORM_CTL_E_OFFSET 0x0100 +#define STORM_CTL_NR_E 6 + +#define UNIT "sctrl_unit" +#define STORM_CTL_UNIT_BOFFSET 24 +#define STORM_CTL_UNIT_BLEN 2 +#define STORM_CTL_UNIT_FLAG HSL_RW + +#define MUL_EN "sctrl_mulen" +#define STORM_CTL_MUL_EN_BOFFSET 10 +#define STORM_CTL_MUL_EN_BLEN 1 +#define STORM_CTL_MUL_EN_FLAG HSL_RW + +#define UNI_EN "sctrl_unien" +#define STORM_CTL_UNI_EN_BOFFSET 9 +#define STORM_CTL_UNI_EN_BLEN 1 +#define STORM_CTL_UNI_EN_FLAG HSL_RW + +#define BRO_EN "sctrl_broen" +#define STORM_CTL_BRO_EN_BOFFSET 8 +#define STORM_CTL_BRO_EN_BLEN 1 +#define STORM_CTL_BRO_EN_FLAG HSL_RW + +#define RATE "sctrl_rate" +#define STORM_CTL_RATE_BOFFSET 0 +#define STORM_CTL_RATE_BLEN 4 +#define STORM_CTL_RATE_FLAG HSL_RW + + + /* Queue Control Register */ +#define QUEUE_CTL "qctl" +#define QUEUE_CTL_ID 34 +#define QUEUE_CTL_OFFSET 0x0118 +#define QUEUE_CTL_E_LENGTH 4 +#define QUEUE_CTL_E_OFFSET 0x0100 +#define QUEUE_CTL_NR_E 6 + +#define PORT_DESC_EN "qctl_pdescen" +#define QUEUE_CTL_PORT_DESC_EN_BOFFSET 25 +#define QUEUE_CTL_PORT_DESC_EN_BLEN 1 +#define QUEUE_CTL_PORT_DESC_EN_FLAG HSL_RW + +#define QUEUE_DESC_EN "qctl_qdescen" +#define QUEUE_CTL_QUEUE_DESC_EN_BOFFSET 24 +#define QUEUE_CTL_QUEUE_DESC_EN_BLEN 1 +#define QUEUE_CTL_QUEUE_DESC_EN_FLAG HSL_RW + +#define PORT_DESC_NR "qctl_pdscpnr" +#define QUEUE_CTL_PORT_DESC_NR_BOFFSET 16 +#define QUEUE_CTL_PORT_DESC_NR_BLEN 6 +#define QUEUE_CTL_PORT_DESC_NR_FLAG HSL_RW + +#define QUEUE3_DESC_NR "qctl_q3dscpnr" +#define QUEUE_CTL_QUEUE3_DESC_NR_BOFFSET 12 +#define QUEUE_CTL_QUEUE3_DESC_NR_BLEN 4 +#define QUEUE_CTL_QUEUE3_DESC_NR_FLAG HSL_RW + +#define QUEUE2_DESC_NR "qctl_q2dscpnr" +#define QUEUE_CTL_QUEUE2_DESC_NR_BOFFSET 8 +#define QUEUE_CTL_QUEUE2_DESC_NR_BLEN 4 +#define QUEUE_CTL_QUEUE2_DESC_NR_FLAG HSL_RW + +#define QUEUE1_DESC_NR "qctl_q1dscpnr" +#define QUEUE_CTL_QUEUE1_DESC_NR_BOFFSET 4 +#define QUEUE_CTL_QUEUE1_DESC_NR_BLEN 4 +#define QUEUE_CTL_QUEUE1_DESC_NR_FLAG HSL_RW + +#define QUEUE0_DESC_NR "qctl_q0dscpnr" +#define QUEUE_CTL_QUEUE0_DESC_NR_BOFFSET 0 +#define QUEUE_CTL_QUEUE0_DESC_NR_BLEN 4 +#define QUEUE_CTL_QUEUE0_DESC_NR_FLAG HSL_RW + + + /* Port Rate Limit1 Register */ +#define RATE_LIMIT1 "rlmt1" +#define RATE_LIMIT1_ID 32 +#define RATE_LIMIT1_OFFSET 0x011C +#define RATE_LIMIT1_E_LENGTH 4 +#define RATE_LIMIT1_E_OFFSET 0x0100 +#define RATE_LIMIT1_NR_E 6 + +#define EG_Q1_RATE "rlmt_egq1rate" +#define RATE_LIMIT1_EG_Q1_RATE_BOFFSET 16 +#define RATE_LIMIT1_EG_Q1_RATE_BLEN 15 +#define RATE_LIMIT1_EG_Q1_RATE_FLAG HSL_RW + +#define EG_Q0_RATE "rlmt_egq0rate" +#define RATE_LIMIT1_EG_Q0_RATE_BOFFSET 0 +#define RATE_LIMIT1_EG_Q0_RATE_BLEN 15 +#define RATE_LIMIT1_EG_Q0_RATE_FLAG HSL_RW + + + /* Port Rate Limit2 Register */ +#define RATE_LIMIT2 "rlmt2" +#define RATE_LIMIT2_ID 32 +#define RATE_LIMIT2_OFFSET 0x0120 +#define RATE_LIMIT2_E_LENGTH 4 +#define RATE_LIMIT2_E_OFFSET 0x0100 +#define RATE_LIMIT2_NR_E 6 + +#define EG_Q3_RATE "rlmt_egq3rate" +#define RATE_LIMIT2_EG_Q3_RATE_BOFFSET 16 +#define RATE_LIMIT2_EG_Q3_RATE_BLEN 15 +#define RATE_LIMIT2_EG_Q3_RATE_FLAG HSL_RW + +#define EG_Q2_RATE "rlmt_egq2rate" +#define RATE_LIMIT2_EG_Q2_RATE_BOFFSET 0 +#define RATE_LIMIT2_EG_Q2_RATE_BLEN 15 +#define RATE_LIMIT2_EG_Q2_RATE_FLAG HSL_RW + + + /* mib memory info */ +#define MIB_RXBROAD "RxBroad" +#define MIB_RXBROAD_ID 34 +#define MIB_RXBROAD_OFFSET 0x20000 +#define MIB_RXBROAD_E_LENGTH 4 +#define MIB_RXBROAD_E_OFFSET 0x100 +#define MIB_RXBROAD_NR_E 6 + +#define MIB_RXPAUSE "RxPause" +#define MIB_RXPAUSE_ID 35 +#define MIB_RXPAUSE_OFFSET 0x20004 +#define MIB_RXPAUSE_E_LENGTH 4 +#define MIB_RXPAUSE_E_OFFSET 0x100 +#define MIB_RXPAUSE_NR_E 6 + +#define MIB_RXMULTI "RxMulti" +#define MIB_RXMULTI_ID 36 +#define MIB_RXMULTI_OFFSET 0x20008 +#define MIB_RXMULTI_E_LENGTH 4 +#define MIB_RXMULTI_E_OFFSET 0x100 +#define MIB_RXMULTI_NR_E 6 + +#define MIB_RXFCSERR "RxFcsErr" +#define MIB_RXFCSERR_ID 37 +#define MIB_RXFCSERR_OFFSET 0x2000c +#define MIB_RXFCSERR_E_LENGTH 4 +#define MIB_RXFCSERR_E_OFFSET 0x100 +#define MIB_RXFCSERR_NR_E 6 + +#define MIB_RXALLIGNERR "RxAllignErr" +#define MIB_RXALLIGNERR_ID 38 +#define MIB_RXALLIGNERR_OFFSET 0x20010 +#define MIB_RXALLIGNERR_E_LENGTH 4 +#define MIB_RXALLIGNERR_E_OFFSET 0x100 +#define MIB_RXALLIGNERR_NR_E 6 + +#define MIB_RXRUNT "RxRunt" +#define MIB_RXRUNT_ID 39 +#define MIB_RXRUNT_OFFSET 0x20014 +#define MIB_RXRUNT_E_LENGTH 4 +#define MIB_RXRUNT_E_OFFSET 0x100 +#define MIB_RXRUNT_NR_E 6 + +#define MIB_RXFRAGMENT "RxFragment" +#define MIB_RXFRAGMENT_ID 40 +#define MIB_RXFRAGMENT_OFFSET 0x20018 +#define MIB_RXFRAGMENT_E_LENGTH 4 +#define MIB_RXFRAGMENT_E_OFFSET 0x100 +#define MIB_RXFRAGMENT_NR_E 6 + +#define MIB_RX64BYTE "Rx64Byte" +#define MIB_RX64BYTE_ID 41 +#define MIB_RX64BYTE_OFFSET 0x2001c +#define MIB_RX64BYTE_E_LENGTH 4 +#define MIB_RX64BYTE_E_OFFSET 0x100 +#define MIB_RX64BYTE_NR_E 6 + +#define MIB_RX128BYTE "Rx128Byte" +#define MIB_RX128BYTE_ID 42 +#define MIB_RX128BYTE_OFFSET 0x20020 +#define MIB_RX128BYTE_E_LENGTH 4 +#define MIB_RX128BYTE_E_OFFSET 0x100 +#define MIB_RX128BYTE_NR_E 6 + +#define MIB_RX256BYTE "Rx256Byte" +#define MIB_RX256BYTE_ID 43 +#define MIB_RX256BYTE_OFFSET 0x20024 +#define MIB_RX256BYTE_E_LENGTH 4 +#define MIB_RX256BYTE_E_OFFSET 0x100 +#define MIB_RX256BYTE_NR_E 6 + +#define MIB_RX512BYTE "Rx512Byte" +#define MIB_RX512BYTE_ID 44 +#define MIB_RX512BYTE_OFFSET 0x20028 +#define MIB_RX512BYTE_E_LENGTH 4 +#define MIB_RX512BYTE_E_OFFSET 0x100 +#define MIB_RX512BYTE_NR_E 6 + +#define MIB_RX1024BYTE "Rx1024Byte" +#define MIB_RX1024BYTE_ID 45 +#define MIB_RX1024BYTE_OFFSET 0x2002c +#define MIB_RX1024BYTE_E_LENGTH 4 +#define MIB_RX1024BYTE_E_OFFSET 0x100 +#define MIB_RX1024BYTE_NR_E 6 + +#define MIB_RX1518BYTE "Rx1518Byte" +#define MIB_RX1518BYTE_ID 45 +#define MIB_RX1518BYTE_OFFSET 0x20030 +#define MIB_RX1518BYTE_E_LENGTH 4 +#define MIB_RX1518BYTE_E_OFFSET 0x100 +#define MIB_RX1518BYTE_NR_E 6 + +#define MIB_RXMAXBYTE "RxMaxByte" +#define MIB_RXMAXBYTE_ID 46 +#define MIB_RXMAXBYTE_OFFSET 0x20034 +#define MIB_RXMAXBYTE_E_LENGTH 4 +#define MIB_RXMAXBYTE_E_OFFSET 0x100 +#define MIB_RXMAXBYTE_NR_E 6 + +#define MIB_RXTOOLONG "RxTooLong" +#define MIB_RXTOOLONG_ID 47 +#define MIB_RXTOOLONG_OFFSET 0x20038 +#define MIB_RXTOOLONG_E_LENGTH 4 +#define MIB_RXTOOLONG_E_OFFSET 0x100 +#define MIB_RXTOOLONG_NR_E 6 + +#define MIB_RXGOODBYTE_LO "RxGoodByteLo" +#define MIB_RXGOODBYTE_LO_ID 48 +#define MIB_RXGOODBYTE_LO_OFFSET 0x2003c +#define MIB_RXGOODBYTE_LO_E_LENGTH 4 +#define MIB_RXGOODBYTE_LO_E_OFFSET 0x100 +#define MIB_RXGOODBYTE_LO_NR_E 6 + +#define MIB_RXGOODBYTE_HI "RxGoodByteHi" +#define MIB_RXGOODBYTE_HI_ID 49 +#define MIB_RXGOODBYTE_HI_OFFSET 0x20040 +#define MIB_RXGOODBYTE_HI_E_LENGTH 4 +#define MIB_RXGOODBYTE_HI_E_OFFSET 0x100 +#define MIB_RXGOODBYTE_HI_NR_E 6 + +#define MIB_RXBADBYTE_LO "RxBadByteLo" +#define MIB_RXBADBYTE_LO_ID 50 +#define MIB_RXBADBYTE_LO_OFFSET 0x20044 +#define MIB_RXBADBYTE_LO_E_LENGTH 4 +#define MIB_RXBADBYTE_LO_E_OFFSET 0x100 +#define MIB_RXBADBYTE_LO_NR_E 6 + +#define MIB_RXBADBYTE_HI "RxBadByteHi" +#define MIB_RXBADBYTE_HI_ID 51 +#define MIB_RXBADBYTE_HI_OFFSET 0x20048 +#define MIB_RXBADBYTE_HI_E_LENGTH 4 +#define MIB_RXBADBYTE_HI_E_OFFSET 0x100 +#define MIB_RXBADBYTE_HI_NR_E 6 + +#define MIB_RXOVERFLOW "RxOverFlow" +#define MIB_RXOVERFLOW_ID 52 +#define MIB_RXOVERFLOW_OFFSET 0x2004c +#define MIB_RXOVERFLOW_E_LENGTH 4 +#define MIB_RXOVERFLOW_E_OFFSET 0x100 +#define MIB_RXOVERFLOW_NR_E 6 + +#define MIB_FILTERED "Filtered" +#define MIB_FILTERED_ID 53 +#define MIB_FILTERED_OFFSET 0x20050 +#define MIB_FILTERED_E_LENGTH 4 +#define MIB_FILTERED_E_OFFSET 0x100 +#define MIB_FILTERED_NR_E 6 + +#define MIB_TXBROAD "TxBroad" +#define MIB_TXBROAD_ID 54 +#define MIB_TXBROAD_OFFSET 0x20054 +#define MIB_TXBROAD_E_LENGTH 4 +#define MIB_TXBROAD_E_OFFSET 0x100 +#define MIB_TXBROAD_NR_E 6 + +#define MIB_TXPAUSE "TxPause" +#define MIB_TXPAUSE_ID 55 +#define MIB_TXPAUSE_OFFSET 0x20058 +#define MIB_TXPAUSE_E_LENGTH 4 +#define MIB_TXPAUSE_E_OFFSET 0x100 +#define MIB_TXPAUSE_NR_E 6 + +#define MIB_TXMULTI "TxMulti" +#define MIB_TXMULTI_ID 56 +#define MIB_TXMULTI_OFFSET 0x2005c +#define MIB_TXMULTI_E_LENGTH 4 +#define MIB_TXMULTI_E_OFFSET 0x100 +#define MIB_TXMULTI_NR_E 6 + +#define MIB_TXUNDERRUN "TxUnderRun" +#define MIB_TXUNDERRUN_ID 57 +#define MIB_TXUNDERRUN_OFFSET 0x20060 +#define MIB_TXUNDERRUN_E_LENGTH 4 +#define MIB_TXUNDERRUN_E_OFFSET 0x100 +#define MIB_TXUNDERRUN_NR_E 6 + +#define MIB_TX64BYTE "Tx64Byte" +#define MIB_TX64BYTE_ID 58 +#define MIB_TX64BYTE_OFFSET 0x20064 +#define MIB_TX64BYTE_E_LENGTH 4 +#define MIB_TX64BYTE_E_OFFSET 0x100 +#define MIB_TX64BYTE_NR_E 6 + +#define MIB_TX128BYTE "Tx128Byte" +#define MIB_TX128BYTE_ID 59 +#define MIB_TX128BYTE_OFFSET 0x20068 +#define MIB_TX128BYTE_E_LENGTH 4 +#define MIB_TX128BYTE_E_OFFSET 0x100 +#define MIB_TX128BYTE_NR_E 6 + +#define MIB_TX256BYTE "Tx256Byte" +#define MIB_TX256BYTE_ID 60 +#define MIB_TX256BYTE_OFFSET 0x2006c +#define MIB_TX256BYTE_E_LENGTH 4 +#define MIB_TX256BYTE_E_OFFSET 0x100 +#define MIB_TX256BYTE_NR_E 6 + +#define MIB_TX512BYTE "Tx512Byte" +#define MIB_TX512BYTE_ID 61 +#define MIB_TX512BYTE_OFFSET 0x20070 +#define MIB_TX512BYTE_E_LENGTH 4 +#define MIB_TX512BYTE_E_OFFSET 0x100 +#define MIB_TX512BYTE_NR_E 6 + +#define MIB_TX1024BYTE "Tx1024Byte" +#define MIB_TX1024BYTE_ID 62 +#define MIB_TX1024BYTE_OFFSET 0x20074 +#define MIB_TX1024BYTE_E_LENGTH 4 +#define MIB_TX1024BYTE_E_OFFSET 0x100 +#define MIB_TX1024BYTE_NR_E 6 + +#define MIB_TX1518BYTE "Tx1518Byte" +#define MIB_TX1518BYTE_ID 62 +#define MIB_TX1518BYTE_OFFSET 0x20078 +#define MIB_TX1518BYTE_E_LENGTH 4 +#define MIB_TX1518BYTE_E_OFFSET 0x100 +#define MIB_TX1518BYTE_NR_E 6 + +#define MIB_TXMAXBYTE "TxMaxByte" +#define MIB_TXMAXBYTE_ID 63 +#define MIB_TXMAXBYTE_OFFSET 0x2007c +#define MIB_TXMAXBYTE_E_LENGTH 4 +#define MIB_TXMAXBYTE_E_OFFSET 0x100 +#define MIB_TXMAXBYTE_NR_E 6 + +#define MIB_TXOVERSIZE "TxOverSize" +#define MIB_TXOVERSIZE_ID 64 +#define MIB_TXOVERSIZE_OFFSET 0x20080 +#define MIB_TXOVERSIZE_E_LENGTH 4 +#define MIB_TXOVERSIZE_E_OFFSET 0x100 +#define MIB_TXOVERSIZE_NR_E 6 + +#define MIB_TXBYTE_LO "TxByteLo" +#define MIB_TXBYTE_LO_ID 65 +#define MIB_TXBYTE_LO_OFFSET 0x20084 +#define MIB_TXBYTE_LO_E_LENGTH 4 +#define MIB_TXBYTE_LO_E_OFFSET 0x100 +#define MIB_TXBYTE_LO_NR_E 6 + +#define MIB_TXBYTE_HI "TxByteHi" +#define MIB_TXBYTE_HI_ID 66 +#define MIB_TXBYTE_HI_OFFSET 0x20088 +#define MIB_TXBYTE_HI_E_LENGTH 4 +#define MIB_TXBYTE_HI_E_OFFSET 0x100 +#define MIB_TXBYTE_HI_NR_E 6 + +#define MIB_TXCOLLISION "TxCollision" +#define MIB_TXCOLLISION_ID 67 +#define MIB_TXCOLLISION_OFFSET 0x2008c +#define MIB_TXCOLLISION_E_LENGTH 4 +#define MIB_TXCOLLISION_E_OFFSET 0x100 +#define MIB_TXCOLLISION_NR_E 6 + +#define MIB_TXABORTCOL "TxAbortCol" +#define MIB_TXABORTCOL_ID 68 +#define MIB_TXABORTCOL_OFFSET 0x20090 +#define MIB_TXABORTCOL_E_LENGTH 4 +#define MIB_TXABORTCOL_E_OFFSET 0x100 +#define MIB_TXABORTCOL_NR_E 6 + +#define MIB_TXMULTICOL "TxMultiCol" +#define MIB_TXMULTICOL_ID 69 +#define MIB_TXMULTICOL_OFFSET 0x20094 +#define MIB_TXMULTICOL_E_LENGTH 4 +#define MIB_TXMULTICOL_E_OFFSET 0x100 +#define MIB_TXMULTICOL_NR_E 6 + +#define MIB_TXSINGALCOL "TxSingalCol" +#define MIB_TXSINGALCOL_ID 70 +#define MIB_TXSINGALCOL_OFFSET 0x20098 +#define MIB_TXSINGALCOL_E_LENGTH 4 +#define MIB_TXSINGALCOL_E_OFFSET 0x100 +#define MIB_TXSINGALCOL_NR_E 6 + +#define MIB_TXEXCDEFER "TxExcDefer" +#define MIB_TXEXCDEFER_ID 71 +#define MIB_TXEXCDEFER_OFFSET 0x2009c +#define MIB_TXEXCDEFER_E_LENGTH 4 +#define MIB_TXEXCDEFER_E_OFFSET 0x100 +#define MIB_TXEXCDEFER_NR_E 6 + +#define MIB_TXDEFER "TxDefer" +#define MIB_TXDEFER_ID 72 +#define MIB_TXDEFER_OFFSET 0x200a0 +#define MIB_TXDEFER_E_LENGTH 4 +#define MIB_TXDEFER_E_OFFSET 0x100 +#define MIB_TXDEFER_NR_E 6 + +#define MIB_TXLATECOL "TxLateCol" +#define MIB_TXLATECOL_ID 73 +#define MIB_TXLATECOL_OFFSET 0x200a4 +#define MIB_TXLATECOL_E_LENGTH 4 +#define MIB_TXLATECOL_E_OFFSET 0x100 +#define MIB_TXLATECOL_NR_E 6 + +#if 0 + /* mib info second mem block */ +#define MIB_RXBROAD_2 "RxBroad_2" +#define MIB_RXBROAD_2_ID 34 +#define MIB_RXBROAD_2_OFFSET (MIB_RXBROAD_OFFSET + 0x400) +#define MIB_RXBROAD_2_E_LENGTH 4 +#define MIB_RXBROAD_2_E_OFFSET 0xa8 +#define MIB_RXBROAD_2_NR_E 6 + +#define MIB_RXPAUSE_2 "RxPause_2" +#define MIB_RXPAUSE_2_ID 35 +#define MIB_RXPAUSE_2_OFFSET (MIB_RXPAUSE_OFFSET + 0x400) +#define MIB_RXPAUSE_2_E_LENGTH 4 +#define MIB_RXPAUSE_2_E_OFFSET 0xa8 +#define MIB_RXPAUSE_2_NR_E 6 + +#define MIB_RXMULTI_2 "RxMulti_2" +#define MIB_RXMULTI_2_ID 36 +#define MIB_RXMULTI_2_OFFSET (MIB_RXMULTI_OFFSET + 0x400) +#define MIB_RXMULTI_2_E_LENGTH 4 +#define MIB_RXMULTI_2_E_OFFSET 0xa8 +#define MIB_RXMULTI_2_NR_E 6 + +#define MIB_RXFCSERR_2 "RxFcsErr_2" +#define MIB_RXFCSERR_2_ID 37 +#define MIB_RXFCSERR_2_OFFSET (MIB_RXFCSERR_OFFSET + 0x400) +#define MIB_RXFCSERR_2_E_LENGTH 4 +#define MIB_RXFCSERR_2_E_OFFSET 0xa8 +#define MIB_RXFCSERR_2_NR_E 6 + +#define MIB_RXALLIGNERR_2 "RxAllignErr_2" +#define MIB_RXALLIGNERR_2_ID 38 +#define MIB_RXALLIGNERR_2_OFFSET (MIB_RXALLIGNERR_OFFSET + 0x400) +#define MIB_RXALLIGNERR_2_E_LENGTH 4 +#define MIB_RXALLIGNERR_2_E_OFFSET 0xa8 +#define MIB_RXALLIGNERR_2_NR_E 6 + +#define MIB_RXRUNT_2 "RxRunt_2" +#define MIB_RXRUNT_2_ID 39 +#define MIB_RXRUNT_2_OFFSET (MIB_RXRUNT_OFFSET + 0x400) +#define MIB_RXRUNT_2_E_LENGTH 4 +#define MIB_RXRUNT_2_E_OFFSET 0xa8 +#define MIB_RXRUNT_2_NR_E 6 + +#define MIB_RXFRAGMENT_2 "RxFragment_2" +#define MIB_RXFRAGMENT_2_ID 40 +#define MIB_RXFRAGMENT_2_OFFSET (MIB_RXFRAGMENT_OFFSET + 0x400) +#define MIB_RXFRAGMENT_2_E_LENGTH 4 +#define MIB_RXFRAGMENT_2_E_OFFSET 0xa8 +#define MIB_RXFRAGMENT_2_NR_E 6 + +#define MIB_RX64BYTE_2 "Rx64Byte_2" +#define MIB_RX64BYTE_2_ID 41 +#define MIB_RX64BYTE_2_OFFSET (MIB_RX64BYTE_OFFSET + 0x400) +#define MIB_RX64BYTE_2_E_LENGTH 4 +#define MIB_RX64BYTE_2_E_OFFSET 0xa8 +#define MIB_RX64BYTE_2_NR_E 6 + +#define MIB_RX128BYTE_2 "Rx128Byte_2" +#define MIB_RX128BYTE_2_ID 42 +#define MIB_RX128BYTE_2_OFFSET (MIB_RX128BYTE_OFFSET + 0x400) +#define MIB_RX128BYTE_2_E_LENGTH 4 +#define MIB_RX128BYTE_2_E_OFFSET 0xa8 +#define MIB_RX128BYTE_2_NR_E 6 + +#define MIB_RX256BYTE_2 "Rx256Byte_2" +#define MIB_RX256BYTE_2_ID 43 +#define MIB_RX256BYTE_2_OFFSET (MIB_RX256BYTE_OFFSET + 0x400) +#define MIB_RX256BYTE_2_E_LENGTH 4 +#define MIB_RX256BYTE_2_E_OFFSET 0xa8 +#define MIB_RX256BYTE_2_NR_E 6 + +#define MIB_RX512BYTE_2 "Rx512Byte_2" +#define MIB_RX512BYTE_2_ID 44 +#define MIB_RX512BYTE_2_OFFSET (MIB_RX512BYTE_OFFSET + 0x400) +#define MIB_RX512BYTE_2_E_LENGTH 4 +#define MIB_RX512BYTE_2_E_OFFSET 0xa8 +#define MIB_RX512BYTE_2_NR_E 6 + +#define MIB_RX1024BYTE_2 "Rx1024Byte_2" +#define MIB_RX1024BYTE_2_ID 45 +#define MIB_RX1024BYTE_2_OFFSET (MIB_RX1024BYTE_OFFSET + 0x400) +#define MIB_RX1024BYTE_2_E_LENGTH 4 +#define MIB_RX1024BYTE_2_E_OFFSET 0xa8 +#define MIB_RX1024BYTE_2_NR_E 6 + +#define MIB_RX1518BYTE_2 "Rx1518Byte_2" +#define MIB_RX1518BYTE_2_ID 45 +#define MIB_RX1518BYTE_2_OFFSET (MIB_RX1518BYTE_OFFSET + 0x400) +#define MIB_RX1518BYTE_2_E_LENGTH 4 +#define MIB_RX1518BYTE_2_E_OFFSET 0xa8 +#define MIB_RX1518BYTE_2_NR_E 6 + +#define MIB_RXMAXBYTE_2 "RxMaxByte_2" +#define MIB_RXMAXBYTE_2_ID 46 +#define MIB_RXMAXBYTE_2_OFFSET (MIB_RXMAXBYTE_OFFSET + 0x400) +#define MIB_RXMAXBYTE_2_E_LENGTH 4 +#define MIB_RXMAXBYTE_2_E_OFFSET 0xa8 +#define MIB_RXMAXBYTE_2_NR_E 6 + +#define MIB_RXTOOLONG_2 "RxTooLong_2" +#define MIB_RXTOOLONG_2_ID 47 +#define MIB_RXTOOLONG_2_OFFSET (MIB_RXTOOLONG_OFFSET + 0x400) +#define MIB_RXTOOLONG_2_E_LENGTH 4 +#define MIB_RXTOOLONG_2_E_OFFSET 0xa8 +#define MIB_RXTOOLONG_2_NR_E 6 + +#define MIB_RXGOODBYTE_LO_2 "RxGoodByteLo_2" +#define MIB_RXGOODBYTE_LO_2_ID 48 +#define MIB_RXGOODBYTE_LO_2_OFFSET (MIB_RXGOODBYTE_LO_OFFSET + 0x400) +#define MIB_RXGOODBYTE_LO_2_E_LENGTH 4 +#define MIB_RXGOODBYTE_LO_2_E_OFFSET 0xa8 +#define MIB_RXGOODBYTE_LO_2_NR_E 6 + +#define MIB_RXGOODBYTE_HI_2 "RxGoodByteHi_2" +#define MIB_RXGOODBYTE_HI_2_ID 49 +#define MIB_RXGOODBYTE_HI_2_OFFSET (MIB_RXGOODBYTE_HI_OFFSET + 0x400) +#define MIB_RXGOODBYTE_HI_2_E_LENGTH 4 +#define MIB_RXGOODBYTE_HI_2_E_OFFSET 0xa8 +#define MIB_RXGOODBYTE_HI_2_NR_E 6 + +#define MIB_RXBADBYTE_LO_2 "RxBadByteLo_2" +#define MIB_RXBADBYTE_LO_2_ID 50 +#define MIB_RXBADBYTE_LO_2_OFFSET (MIB_RXBADBYTE_LO_OFFSET + 0x400) +#define MIB_RXBADBYTE_LO_2_E_LENGTH 4 +#define MIB_RXBADBYTE_LO_2_E_OFFSET 0xa8 +#define MIB_RXBADBYTE_LO_2_NR_E 6 + +#define MIB_RXBADBYTE_HI_2 "RxBadByteHi_2" +#define MIB_RXBADBYTE_HI_2_ID 51 +#define MIB_RXBADBYTE_HI_2_OFFSET (MIB_RXBADBYTE_HI_OFFSET + 0x400) +#define MIB_RXBADBYTE_HI_2_E_LENGTH 4 +#define MIB_RXBADBYTE_HI_2_E_OFFSET 0xa8 +#define MIB_RXBADBYTE_HI_2_NR_E 6 + +#define MIB_RXOVERFLOW_2 "RxOverFlow_2" +#define MIB_RXOVERFLOW_2_ID 52 +#define MIB_RXOVERFLOW_2_OFFSET (MIB_RXOVERFLOW_OFFSET + 0x400) +#define MIB_RXOVERFLOW_2_E_LENGTH 4 +#define MIB_RXOVERFLOW_2_E_OFFSET 0xa8 +#define MIB_RXOVERFLOW_2_NR_E 6 + +#define MIB_FILTERED_2 "Filtered_2" +#define MIB_FILTERED_2_ID 53 +#define MIB_FILTERED_2_OFFSET (MIB_FILTERED_OFFSET + 0x400) +#define MIB_FILTERED_2_E_LENGTH 4 +#define MIB_FILTERED_2_E_OFFSET 0xa8 +#define MIB_FILTERED_2_NR_E 6 + +#define MIB_TXBROAD_2 "TxBroad_2" +#define MIB_TXBROAD_2_ID 54 +#define MIB_TXBROAD_2_OFFSET (MIB_TXBROAD_OFFSET + 0x400) +#define MIB_TXBROAD_2_E_LENGTH 4 +#define MIB_TXBROAD_2_E_OFFSET 0xa8 +#define MIB_TXBROAD_2_NR_E 6 + +#define MIB_TXPAUSE_2 "TxPause_2" +#define MIB_TXPAUSE_2_ID 55 +#define MIB_TXPAUSE_2_OFFSET (MIB_TXPAUSE_OFFSET + 0x400) +#define MIB_TXPAUSE_2_E_LENGTH 4 +#define MIB_TXPAUSE_2_E_OFFSET 0xa8 +#define MIB_TXPAUSE_2_NR_E 6 + +#define MIB_TXMULTI_2 "TxMulti_2" +#define MIB_TXMULTI_2_ID 56 +#define MIB_TXMULTI_2_OFFSET (MIB_TXMULTI_OFFSET + 0x400) +#define MIB_TXMULTI_2_E_LENGTH 4 +#define MIB_TXMULTI_2_E_OFFSET 0xa8 +#define MIB_TXMULTI_2_NR_E 6 + +#define MIB_TXUNDERRUN_2 "TxUnderRun_2" +#define MIB_TXUNDERRUN_2_ID 57 +#define MIB_TXUNDERRUN_2_OFFSET (MIB_TXUNDERRUN_OFFSET + 0x400) +#define MIB_TXUNDERRUN_2_E_LENGTH 4 +#define MIB_TXUNDERRUN_2_E_OFFSET 0xa8 +#define MIB_TXUNDERRUN_2_NR_E 6 + +#define MIB_TX64BYTE_2 "Tx64Byte_2" +#define MIB_TX64BYTE_2_ID 58 +#define MIB_TX64BYTE_2_OFFSET (MIB_TX64BYTE_OFFSET + 0x400) +#define MIB_TX64BYTE_2_E_LENGTH 4 +#define MIB_TX64BYTE_2_E_OFFSET 0xa8 +#define MIB_TX64BYTE_2_NR_E 6 + +#define MIB_TX128BYTE_2 "Tx128Byte_2" +#define MIB_TX128BYTE_2_ID 59 +#define MIB_TX128BYTE_2_OFFSET (MIB_TX128BYTE_OFFSET + 0x400) +#define MIB_TX128BYTE_2_E_LENGTH 4 +#define MIB_TX128BYTE_2_E_OFFSET 0xa8 +#define MIB_TX128BYTE_2_NR_E 6 + +#define MIB_TX256BYTE_2 "Tx256Byte_2" +#define MIB_TX256BYTE_2_ID 60 +#define MIB_TX256BYTE_2_OFFSET (MIB_TX256BYTE_OFFSET + 0x400) +#define MIB_TX256BYTE_2_E_LENGTH 4 +#define MIB_TX256BYTE_2_E_OFFSET 0xa8 +#define MIB_TX256BYTE_2_NR_E 6 + +#define MIB_TX512BYTE_2 "Tx512Byte_2" +#define MIB_TX512BYTE_2_ID 61 +#define MIB_TX512BYTE_2_OFFSET (MIB_TX512BYTE_OFFSET + 0x400) +#define MIB_TX512BYTE_2_E_LENGTH 4 +#define MIB_TX512BYTE_2_E_OFFSET 0xa8 +#define MIB_TX512BYTE_2_NR_E 6 + +#define MIB_TX1024BYTE_2 "Tx1024Byte_2" +#define MIB_TX1024BYTE_2_ID 62 +#define MIB_TX1024BYTE_2_OFFSET (MIB_TX1024BYTE_OFFSET + 0x400) +#define MIB_TX1024BYTE_2_E_LENGTH 4 +#define MIB_TX1024BYTE_2_E_OFFSET 0xa8 +#define MIB_TX1024BYTE_2_NR_E 6 + +#define MIB_TX1518BYTE_2 "Tx1518Byte_2" +#define MIB_TX1518BYTE_2_ID 62 +#define MIB_TX1518BYTE_2_OFFSET (MIB_TX1518BYTE_OFFSET + 0x400) +#define MIB_TX1518BYTE_2_E_LENGTH 4 +#define MIB_TX1518BYTE_2_E_OFFSET 0xa8 +#define MIB_TX1518BYTE_2_NR_E 6 + +#define MIB_TXMAXBYTE_2 "TxMaxByte_2" +#define MIB_TXMAXBYTE_2_ID 63 +#define MIB_TXMAXBYTE_2_OFFSET (MIB_TXMAXBYTE_OFFSET + 0x400) +#define MIB_TXMAXBYTE_2_E_LENGTH 4 +#define MIB_TXMAXBYTE_2_E_OFFSET 0xa8 +#define MIB_TXMAXBYTE_2_NR_E 6 + +#define MIB_TXOVERSIZE_2 "TxOverSize_2" +#define MIB_TXOVERSIZE_2_ID 64 +#define MIB_TXOVERSIZE_2_OFFSET (MIB_TXOVERSIZE_OFFSET + 0x400) +#define MIB_TXOVERSIZE_2_E_LENGTH 4 +#define MIB_TXOVERSIZE_2_E_OFFSET 0xa8 +#define MIB_TXOVERSIZE_2_NR_E 6 + +#define MIB_TXBYTE_LO_2 "TxByteLo_2" +#define MIB_TXBYTE_LO_2_ID 65 +#define MIB_TXBYTE_LO_2_OFFSET (MIB_TXBYTE_LO_OFFSET + 0x400) +#define MIB_TXBYTE_LO_2_E_LENGTH 4 +#define MIB_TXBYTE_LO_2_E_OFFSET 0xa8 +#define MIB_TXBYTE_LO_2_NR_E 6 + +#define MIB_TXBYTE_HI_2 "TxByteHi_2" +#define MIB_TXBYTE_HI_2_ID 66 +#define MIB_TXBYTE_HI_2_OFFSET (MIB_TXBYTE_HI_OFFSET + 0x400) +#define MIB_TXBYTE_HI_2_E_LENGTH 4 +#define MIB_TXBYTE_HI_2_E_OFFSET 0xa8 +#define MIB_TXBYTE_HI_2_NR_E 6 + +#define MIB_TXCOLLISION_2 "TxCollision_2" +#define MIB_TXCOLLISION_2_ID 67 +#define MIB_TXCOLLISION_2_OFFSET (MIB_TXCOLLISION_OFFSET + 0x400) +#define MIB_TXCOLLISION_2_E_LENGTH 4 +#define MIB_TXCOLLISION_2_E_OFFSET 0xa8 +#define MIB_TXCOLLISION_2_NR_E 6 + +#define MIB_TXABORTCOL_2 "TxAbortCol_2" +#define MIB_TXABORTCOL_2_ID 68 +#define MIB_TXABORTCOL_2_OFFSET (MIB_TXABORTCOL_OFFSET + 0x400) +#define MIB_TXABORTCOL_2_E_LENGTH 4 +#define MIB_TXABORTCOL_2_E_OFFSET 0xa8 +#define MIB_TXABORTCOL_2_NR_E 6 + +#define MIB_TXMULTICOL_2 "TxMultiCol_2" +#define MIB_TXMULTICOL_2_ID 69 +#define MIB_TXMULTICOL_2_OFFSET (MIB_TXMULTICOL_OFFSET + 0x400) +#define MIB_TXMULTICOL_2_E_LENGTH 4 +#define MIB_TXMULTICOL_2_E_OFFSET 0xa8 +#define MIB_TXMULTICOL_2_NR_E 6 + +#define MIB_TXSINGALCOL_2 "TxSingalCol_2" +#define MIB_TXSINGALCOL_2_ID 70 +#define MIB_TXSINGALCOL_2_OFFSET (MIB_TXSINGALCOL_OFFSET + 0x400) +#define MIB_TXSINGALCOL_2_E_LENGTH 4 +#define MIB_TXSINGALCOL_2_E_OFFSET 0xa8 +#define MIB_TXSINGALCOL_2_NR_E 6 + +#define MIB_TXEXCDEFER_2 "TxExcDefer_2" +#define MIB_TXEXCDEFER_2_ID 71 +#define MIB_TXEXCDEFER_2_OFFSET (MIB_TXEXCDEFER_OFFSET + 0x400) +#define MIB_TXEXCDEFER_2_E_LENGTH 4 +#define MIB_TXEXCDEFER_2_E_OFFSET 0xa8 +#define MIB_TXEXCDEFER_2_NR_E 6 + +#define MIB_TXDEFER_2 "TxDefer_2" +#define MIB_TXDEFER_2_ID 72 +#define MIB_TXDEFER_2_OFFSET (MIB_TXDEFER_OFFSET + 0x400) +#define MIB_TXDEFER_2_E_LENGTH 4 +#define MIB_TXDEFER_2_E_OFFSET 0xa8 +#define MIB_TXDEFER_2_NR_E 6 + +#define MIB_TXLATECOL_2 "TxLateCol_2" +#define MIB_TXLATECOL_2_ID 73 +#define MIB_TXLATECOL_2_OFFSET (MIB_TXLATECOL_OFFSET + 0x400) +#define MIB_TXLATECOL_2_E_LENGTH 4 +#define MIB_TXLATECOL_2_E_OFFSET 0xa8 +#define MIB_TXLATECOL_2_NR_E 6 +#endif + +#define ACL_RSLT "aclact" +#define ACL_RSLT_ID 13 +#define ACL_RSLT_OFFSET 0x58000 +#define ACL_RSLT_E_LENGTH 4 +#define ACL_RSLT_E_OFFSET 0x20 +#define ACL_RSLT_NR_E 32 + +#define RDTCPU "aclact_rdtpu" +#define ACL_RSLT_RDTCPU_BOFFSET 31 +#define ACL_RSLT_RDTCPU_BLEN 1 +#define ACL_RSLT_RDTCPU_FLAG HSL_RW + +#define CPYCPU "aclact_cpcpu" +#define ACL_RSLT_CPYCPU_BOFFSET 30 +#define ACL_RSLT_CPYCPU_BLEN 1 +#define ACL_RSLT_CPYCPU_FLAG HSL_RW + +#define MIRR_EN "aclact_mirr" +#define ACL_RSLT_MIRR_EN_BOFFSET 29 +#define ACL_RSLT_MIRR_EN_BLEN 1 +#define ACL_RSLT_MIRR_EN_FLAG HSL_RW + +#define STAG_CHG_EN "aclact_rdcpu" +#define ACL_RSLT_STAG_CHG_EN_BOFFSET 28 +#define ACL_RSLT_STAG_CHG_EN_BLEN 1 +#define ACL_RSLT_STAG_CHG_EN_FLAG HSL_RW + +#define VID_MEM_EN "aclact_rdcpu" +#define ACL_RSLT_VID_MEM_EN_BOFFSET 27 +#define ACL_RSLT_VID_MEM_EN_BLEN 1 +#define ACL_RSLT_VID_MEM_EN_FLAG HSL_RW + +#define DES_PORT_EN "aclact_rdcpu" +#define ACL_RSLT_DES_PORT_EN_BOFFSET 26 +#define ACL_RSLT_DES_PORT_EN_BLEN 1 +#define ACL_RSLT_DES_PORT_EN_FLAG HSL_RW + +#define PORT_MEM "aclact_rdcpu" +#define ACL_RSLT_PORT_MEM_BOFFSET 20 +#define ACL_RSLT_PORT_MEM_BLEN 6 +#define ACL_RSLT_PORT_MEM_FLAG HSL_RW + +#define REMARK_PRI_QU "aclact_rdcpu" +#define ACL_RSLT_REMARK_PRI_QU_BOFFSET 19 +#define ACL_RSLT_REMARK_PRI_QU_BLEN 1 +#define ACL_RSLT_REMARK_PRI_QU_FLAG HSL_RW + +#define DOT1P "aclact_rdcpu" +#define ACL_RSLT_DOT1P_BOFFSET 16 +#define ACL_RSLT_DOT1P_BLEN 3 +#define ACL_RSLT_DOT1P_FLAG HSL_RW + +#define PRI_QU "aclact_rdcpu" +#define ACL_RSLT_PRI_QU_BOFFSET 14 +#define ACL_RSLT_PRI_QU_BLEN 2 +#define ACL_RSLT_PRI_QU_FLAG HSL_RW + +#define REMARK_DOT1P "aclact_rdcpu" +#define ACL_RSLT_REMARK_DOT1P_BOFFSET 13 +#define ACL_RSLT_REMARK_DOT1P_BLEN 1 +#define ACL_RSLT_REMARK_DOT1P_FLAG HSL_RW + +#define CHG_VID_EN "aclact_rdcpu" +#define ACL_RSLT_CHG_VID_EN_BOFFSET 12 +#define ACL_RSLT_CHG_VID_EN_BLEN 1 +#define ACL_RSLT_CHG_VID_EN_FLAG HSL_RW + +#define VID "aclact_rdcpu" +#define ACL_RSLT_VID_BOFFSET 0 +#define ACL_RSLT_VID_BLEN 12 +#define ACL_RSLT_VID_FLAG HSL_RW + + + + +#define RUL_SLCT0 "rulslct0" +#define RUL_SLCT0_ID 13 +#define RUL_SLCT0_OFFSET 0x58800 +#define RUL_SLCT0_E_LENGTH 4 +#define RUL_SLCT0_E_OFFSET 0x20 +#define RUL_SLCT0_NR_E 32 + +#define ADDR3_EN "rulslct_addr3en" +#define RUL_SLCT0_ADDR3_EN_BOFFSET 3 +#define RUL_SLCT0_ADDR3_EN_BLEN 1 +#define RUL_SLCT0_ADDR3_EN_FLAG HSL_RW + +#define ADDR2_EN "rulslct_addr2en" +#define RUL_SLCT0_ADDR2_EN_BOFFSET 2 +#define RUL_SLCT0_ADDR2_EN_BLEN 1 +#define RUL_SLCT0_ADDR2_EN_FLAG HSL_RW + +#define ADDR1_EN "rulslct_addr1en" +#define RUL_SLCT0_ADDR1_EN_BOFFSET 1 +#define RUL_SLCT0_ADDR1_EN_BLEN 1 +#define RUL_SLCT0_ADDR1_EN_FLAG HSL_RW + +#define ADDR0_EN "rulslct_addr0en" +#define RUL_SLCT0_ADDR0_EN_BOFFSET 0 +#define RUL_SLCT0_ADDR0_EN_BLEN 1 +#define RUL_SLCT0_ADDR0_EN_FLAG HSL_RW + + + + +#define RUL_SLCT1 "rulslct1" +#define RUL_SLCT1_ID 13 +#define RUL_SLCT1_OFFSET 0x58804 +#define RUL_SLCT1_E_LENGTH 4 +#define RUL_SLCT1_E_OFFSET 0x20 +#define RUL_SLCT1_NR_E 32 + +#define ADDR0 "rulslct1_addr0" +#define RUL_SLCT1_ADDR0_BOFFSET 0 +#define RUL_SLCT1_ADDR0_BLEN 5 +#define RUL_SLCT1_ADDR0_FLAG HSL_RW + + + + +#define RUL_SLCT2 "rulslct2" +#define RUL_SLCT2_ID 13 +#define RUL_SLCT2_OFFSET 0x58808 +#define RUL_SLCT2_E_LENGTH 4 +#define RUL_SLCT2_E_OFFSET 0x20 +#define RUL_SLCT2_NR_E 32 + +#define ADDR1 "rulslct2_addr1" +#define RUL_SLCT2_ADDR1_BOFFSET 0 +#define RUL_SLCT2_ADDR1_BLEN 5 +#define RUL_SLCT2_ADDR1_FLAG HSL_RW + + + + +#define RUL_SLCT3 "rulslct3" +#define RUL_SLCT3_ID 13 +#define RUL_SLCT3_OFFSET 0x5880c +#define RUL_SLCT3_E_LENGTH 4 +#define RUL_SLCT3_E_OFFSET 0x20 +#define RUL_SLCT3_NR_E 32 + +#define ADDR2 "rulslct3_addr2" +#define RUL_SLCT3_ADDR2_BOFFSET 0 +#define RUL_SLCT3_ADDR2_BLEN 5 +#define RUL_SLCT3_ADDR2_FLAG HSL_RW + + + + +#define RUL_SLCT4 "rulslct4" +#define RUL_SLCT4_ID 13 +#define RUL_SLCT4_OFFSET 0x58810 +#define RUL_SLCT4_E_LENGTH 4 +#define RUL_SLCT4_E_OFFSET 0x20 +#define RUL_SLCT4_NR_E 32 + +#define ADDR3 "rulslct4_addr3" +#define RUL_SLCT4_ADDR3_BOFFSET 0 +#define RUL_SLCT4_ADDR3_BLEN 5 +#define RUL_SLCT4_ADDR3_FLAG HSL_RW + + + + +#define RUL_SLCT6 "rulslct6" +#define RUL_SLCT6_ID 13 +#define RUL_SLCT6_OFFSET 0x58818 +#define RUL_SLCT6_E_LENGTH 4 +#define RUL_SLCT6_E_OFFSET 0x20 +#define RUL_SLCT6_NR_E 32 + +#define RULE_LEN "rulslct6_rulelen" +#define RUL_SLCT6_RULE_LEN_BOFFSET 0 +#define RUL_SLCT6_RULE_LEN_BLEN 6 +#define RUL_SLCT6_RULE_LEN_FLAG HSL_RW + + + + +#define RUL_TYPE "ruletype" +#define RUL_TYPE_ID 13 +#define RUL_TYPE_OFFSET 0x5881c +#define RUL_TYPE_E_LENGTH 4 +#define RUL_TYPE_E_OFFSET 0x20 +#define RUL_TYPE_NR_E 32 + +#define TYP "ruletype_typ" +#define RUL_TYPE_TYP_BOFFSET 0 +#define RUL_TYPE_TYP_BLEN 3 +#define RUL_TYPE_TYP_FLAG HSL_RW + + + + +#define MAC_RUL_V0 "macrv0" +#define MAC_RUL_V0_ID 13 +#define MAC_RUL_V0_OFFSET 0x58400 +#define MAC_RUL_V0_E_LENGTH 4 +#define MAC_RUL_V0_E_OFFSET 0x20 +#define MAC_RUL_V0_NR_E 32 + +#define DAV_BYTE2 "macrv0_dav2" +#define MAC_RUL_V0_DAV_BYTE2_BOFFSET 24 +#define MAC_RUL_V0_DAV_BYTE2_BLEN 8 +#define MAC_RUL_V0_DAV_BYTE2_FLAG HSL_RW + +#define DAV_BYTE3 "macrv0_dav3" +#define MAC_RUL_V0_DAV_BYTE3_BOFFSET 16 +#define MAC_RUL_V0_DAV_BYTE3_BLEN 8 +#define MAC_RUL_V0_DAV_BYTE3_FLAG HSL_RW + +#define DAV_BYTE4 "macrv0_dav4" +#define MAC_RUL_V0_DAV_BYTE4_BOFFSET 8 +#define MAC_RUL_V0_DAV_BYTE4_BLEN 8 +#define MAC_RUL_V0_DAV_BYTE4_FLAG HSL_RW + +#define DAV_BYTE5 "macrv0_dav5" +#define MAC_RUL_V0_DAV_BYTE5_BOFFSET 0 +#define MAC_RUL_V0_DAV_BYTE5_BLEN 8 +#define MAC_RUL_V0_DAV_BYTE5_FLAG HSL_RW + + + + +#define MAC_RUL_V1 "macrv1" +#define MAC_RUL_V1_ID 13 +#define MAC_RUL_V1_OFFSET 0x58404 +#define MAC_RUL_V1_E_LENGTH 4 +#define MAC_RUL_V1_E_OFFSET 0x20 +#define MAC_RUL_V1_NR_E 32 + +#define SAV_BYTE4 "macrv1_sav4" +#define MAC_RUL_V1_SAV_BYTE4_BOFFSET 24 +#define MAC_RUL_V1_SAV_BYTE4_BLEN 8 +#define MAC_RUL_V1_SAV_BYTE4_FLAG HSL_RW + +#define SAV_BYTE5 "macrv1_sav5" +#define MAC_RUL_V1_SAV_BYTE5_BOFFSET 16 +#define MAC_RUL_V1_SAV_BYTE5_BLEN 8 +#define MAC_RUL_V1_SAV_BYTE5_FLAG HSL_RW + +#define DAV_BYTE0 "macrv1_dav0" +#define MAC_RUL_V1_DAV_BYTE0_BOFFSET 8 +#define MAC_RUL_V1_DAV_BYTE0_BLEN 8 +#define MAC_RUL_V1_DAV_BYTE0_FLAG HSL_RW + +#define DAV_BYTE1 "macrv1_dav1" +#define MAC_RUL_V1_DAV_BYTE1_BOFFSET 0 +#define MAC_RUL_V1_DAV_BYTE1_BLEN 8 +#define MAC_RUL_V1_DAV_BYTE1_FLAG HSL_RW + + + + +#define MAC_RUL_V2 "macrv2" +#define MAC_RUL_V2_ID 13 +#define MAC_RUL_V2_OFFSET 0x58408 +#define MAC_RUL_V2_E_LENGTH 4 +#define MAC_RUL_V2_E_OFFSET 0x20 +#define MAC_RUL_V2_NR_E 32 + +#define SAV_BYTE0 "macrv2_sav0" +#define MAC_RUL_V2_SAV_BYTE0_BOFFSET 24 +#define MAC_RUL_V2_SAV_BYTE0_BLEN 8 +#define MAC_RUL_V2_SAV_BYTE0_FLAG HSL_RW + +#define SAV_BYTE1 "macrv2_sav1" +#define MAC_RUL_V2_SAV_BYTE1_BOFFSET 16 +#define MAC_RUL_V2_SAV_BYTE1_BLEN 8 +#define MAC_RUL_V2_SAV_BYTE1_FLAG HSL_RW + +#define SAV_BYTE2 "macrv2_sav2" +#define MAC_RUL_V2_SAV_BYTE2_BOFFSET 8 +#define MAC_RUL_V2_SAV_BYTE2_BLEN 8 +#define MAC_RUL_V2_SAV_BYTE2_FLAG HSL_RW + +#define SAV_BYTE3 "macrv2_sav3" +#define MAC_RUL_V2_SAV_BYTE3_BOFFSET 0 +#define MAC_RUL_V2_SAV_BYTE3_BLEN 8 +#define MAC_RUL_V2_SAV_BYTE3_FLAG HSL_RW + + + + +#define MAC_RUL_V3 "macrv3" +#define MAC_RUL_V3_ID 13 +#define MAC_RUL_V3_OFFSET 0x5840c +#define MAC_RUL_V3_E_LENGTH 4 +#define MAC_RUL_V3_E_OFFSET 0x20 +#define MAC_RUL_V3_NR_E 32 + +#define ETHTYPV "macrv3_ethtypv" +#define MAC_RUL_V3_ETHTYPV_BOFFSET 16 +#define MAC_RUL_V3_ETHTYPV_BLEN 16 +#define MAC_RUL_V3_ETHTYPV_FLAG HSL_RW + +#define VLANPRIV "macrv3_vlanpriv" +#define MAC_RUL_V3_VLANPRIV_BOFFSET 13 +#define MAC_RUL_V3_VLANPRIV_BLEN 3 +#define MAC_RUL_V3_VLANPRIV_FLAG HSL_RW + +#define VLANIDV "macrv3_vlanidv" +#define MAC_RUL_V3_VLANIDV_BOFFSET 0 +#define MAC_RUL_V3_VLANIDV_BLEN 12 +#define MAC_RUL_V3_VLANIDV_FLAG HSL_RW + + + + +#define MAC_RUL_V4 "macrv4" +#define MAC_RUL_V4_ID 13 +#define MAC_RUL_V4_OFFSET 0x58410 +#define MAC_RUL_V4_E_LENGTH 4 +#define MAC_RUL_V4_E_OFFSET 0x20 +#define MAC_RUL_V4_NR_E 32 + +#define TAGGEDM "macrv4_vlanid" +#define MAC_RUL_V4_TAGGEDM_BOFFSET 7 +#define MAC_RUL_V4_TAGGEDM_BLEN 1 +#define MAC_RUL_V4_TAGGEDM_FLAG HSL_RW + +#define TAGGEDV "macrv4_vlanid" +#define MAC_RUL_V4_TAGGEDV_BOFFSET 6 +#define MAC_RUL_V4_TAGGEDV_BLEN 1 +#define MAC_RUL_V4_TAGGEDV_FLAG HSL_RW + +#define MAC_INPT "macrv4_vlanid" +#define MAC_RUL_V4_MAC_INPT_BOFFSET 0 +#define MAC_RUL_V4_MAC_INPT_BLEN 6 +#define MAC_RUL_V4_MAC_INPT_FLAG HSL_RW + + + + + +#define MAC_RUL_M0 "macrv0" +#define MAC_RUL_M0_ID 13 +#define MAC_RUL_M0_OFFSET 0x58c00 +#define MAC_RUL_M0_E_LENGTH 4 +#define MAC_RUL_M0_E_OFFSET 0x20 +#define MAC_RUL_M0_NR_E 32 + +#define DAM_BYTE2 "macrv0_dam2" +#define MAC_RUL_M0_DAM_BYTE2_BOFFSET 24 +#define MAC_RUL_M0_DAM_BYTE2_BLEN 8 +#define MAC_RUL_M0_DAM_BYTE2_FLAG HSL_RW + +#define DAM_BYTE3 "macrv0_dam3" +#define MAC_RUL_M0_DAM_BYTE3_BOFFSET 16 +#define MAC_RUL_M0_DAM_BYTE3_BLEN 8 +#define MAC_RUL_M0_DAM_BYTE3_FLAG HSL_RW + +#define DAM_BYTE4 "macrv0_dam4" +#define MAC_RUL_M0_DAM_BYTE4_BOFFSET 8 +#define MAC_RUL_M0_DAM_BYTE4_BLEN 8 +#define MAC_RUL_M0_DAM_BYTE4_FLAG HSL_RW + +#define DAM_BYTE5 "macrv0_dam5" +#define MAC_RUL_M0_DAM_BYTE5_BOFFSET 0 +#define MAC_RUL_M0_DAM_BYTE5_BLEN 8 +#define MAC_RUL_M0_DAM_BYTE5_FLAG HSL_RW + + + + +#define MAC_RUL_M1 "macrm1" +#define MAC_RUL_M1_ID 13 +#define MAC_RUL_M1_OFFSET 0x58c04 +#define MAC_RUL_M1_E_LENGTH 4 +#define MAC_RUL_M1_E_OFFSET 0x20 +#define MAC_RUL_M1_NR_E 32 + +#define SAM_BYTE4 "macrm1_sam4" +#define MAC_RUL_M1_SAM_BYTE4_BOFFSET 24 +#define MAC_RUL_M1_SAM_BYTE4_BLEN 8 +#define MAC_RUL_M1_SAM_BYTE4_FLAG HSL_RW + +#define SAM_BYTE5 "macrm1_sam5" +#define MAC_RUL_M1_SAM_BYTE5_BOFFSET 16 +#define MAC_RUL_M1_SAM_BYTE5_BLEN 8 +#define MAC_RUL_M1_SAM_BYTE5_FLAG HSL_RW + +#define DAM_BYTE0 "macrm1_dam0" +#define MAC_RUL_M1_DAM_BYTE0_BOFFSET 8 +#define MAC_RUL_M1_DAM_BYTE0_BLEN 8 +#define MAC_RUL_M1_DAM_BYTE0_FLAG HSL_RW + +#define DAM_BYTE1 "macrm1_dam1" +#define MAC_RUL_M1_DAM_BYTE1_BOFFSET 0 +#define MAC_RUL_M1_DAM_BYTE1_BLEN 8 +#define MAC_RUL_M1_DAM_BYTE1_FLAG HSL_RW + + + + +#define MAC_RUL_M2 "macrm2" +#define MAC_RUL_M2_ID 13 +#define MAC_RUL_M2_OFFSET 0x58c08 +#define MAC_RUL_M2_E_LENGTH 4 +#define MAC_RUL_M2_E_OFFSET 0x20 +#define MAC_RUL_M2_NR_E 32 + +#define SAM_BYTE0 "macrm2_sam0" +#define MAC_RUL_M2_SAM_BYTE0_BOFFSET 24 +#define MAC_RUL_M2_SAM_BYTE0_BLEN 8 +#define MAC_RUL_M2_SAM_BYTE0_FLAG HSL_RW + +#define SAM_BYTE1 "macrm2_samv1" +#define MAC_RUL_M2_SAM_BYTE1_BOFFSET 16 +#define MAC_RUL_M2_SAM_BYTE1_BLEN 8 +#define MAC_RUL_M2_SAM_BYTE1_FLAG HSL_RW + +#define SAM_BYTE2 "macrm2_sam2" +#define MAC_RUL_M2_SAM_BYTE2_BOFFSET 8 +#define MAC_RUL_M2_SAM_BYTE2_BLEN 8 +#define MAC_RUL_M2_SAM_BYTE2_FLAG HSL_RW + +#define SAM_BYTE3 "macrm2_sam3" +#define MAC_RUL_M2_SAM_BYTE3_BOFFSET 0 +#define MAC_RUL_M2_SAM_BYTE3_BLEN 8 +#define MAC_RUL_M2_SAM_BYTE3_FLAG HSL_RW + + + + +#define MAC_RUL_M3 "macrv3" +#define MAC_RUL_M3_ID 13 +#define MAC_RUL_M3_OFFSET 0x58c0c +#define MAC_RUL_M3_E_LENGTH 4 +#define MAC_RUL_M3_E_OFFSET 0x20 +#define MAC_RUL_M3_NR_E 32 + +#define ETHTYPM "macrm3_ethtypm" +#define MAC_RUL_M3_ETHTYPM_BOFFSET 16 +#define MAC_RUL_M3_ETHTYPM_BLEN 16 +#define MAC_RUL_M3_ETHTYPM_FLAG HSL_RW + +#define VLANPRIM "macrm3_vlanprim" +#define MAC_RUL_M3_VLANPRIM_BOFFSET 13 +#define MAC_RUL_M3_VLANPRIM_BLEN 3 +#define MAC_RUL_M3_VLANPRIM_FLAG HSL_RW + +#define VIDMSK "macrm3_vidmsk" +#define MAC_RUL_M3_VIDMSK_BOFFSET 12 +#define MAC_RUL_M3_VIDMSK_BLEN 1 +#define MAC_RUL_M3_VIDMSK_FLAG HSL_RW + +#define VLANIDM "macrm3_vlanidm" +#define MAC_RUL_M3_VLANIDM_BOFFSET 0 +#define MAC_RUL_M3_VLANIDM_BLEN 12 +#define MAC_RUL_M3_VLANIDM_FLAG HSL_RW + + + + +#define IP4_RUL_V0 "ip4v0" +#define IP4_RUL_V0_ID 13 +#define IP4_RUL_V0_OFFSET 0x58400 +#define IP4_RUL_V0_E_LENGTH 4 +#define IP4_RUL_V0_E_OFFSET 0x20 +#define IP4_RUL_V0_NR_E 32 + +#define DIPV "ip4v0_dipv" +#define IP4_RUL_V0_DIPV_BOFFSET 0 +#define IP4_RUL_V0_DIPV_BLEN 32 +#define IP4_RUL_V0_DIPV_FLAG HSL_RW + + + + +#define IP4_RUL_V1 "ip4v1" +#define IP4_RUL_V1_ID 13 +#define IP4_RUL_V1_OFFSET 0x58404 +#define IP4_RUL_V1_E_LENGTH 4 +#define IP4_RUL_V1_E_OFFSET 0x20 +#define IP4_RUL_V1_NR_E 32 + +#define SIPV "ip4v1_sipv" +#define IP4_RUL_V1_SIPV_BOFFSET 0 +#define IP4_RUL_V1_SIPV_BLEN 32 +#define IP4_RUL_V1_SIPV_FLAG HSL_RW + + + + +#define IP4_RUL_V2 "ip4v2" +#define IP4_RUL_V2_ID 13 +#define IP4_RUL_V2_OFFSET 0x58408 +#define IP4_RUL_V2_E_LENGTH 4 +#define IP4_RUL_V2_E_OFFSET 0x20 +#define IP4_RUL_V2_NR_E 32 + +#define IP4PROTV "ip4v2_protv" +#define IP4_RUL_V2_IP4PROTV_BOFFSET 0 +#define IP4_RUL_V2_IP4PROTV_BLEN 8 +#define IP4_RUL_V2_IP4PROTV_FLAG HSL_RW + +#define IP4DSCPV "ip4v2_dscpv" +#define IP4_RUL_V2_IP4DSCPV_BOFFSET 8 +#define IP4_RUL_V2_IP4DSCPV_BLEN 8 +#define IP4_RUL_V2_IP4DSCPV_FLAG HSL_RW + +#define IP4DPORTV "ip4v2_dportv" +#define IP4_RUL_V2_IP4DPORTV_BOFFSET 16 +#define IP4_RUL_V2_IP4DPORTV_BLEN 16 +#define IP4_RUL_V2_IP4DPORTV_FLAG HSL_RW + + + + +#define IP4_RUL_V3 "ip4v3" +#define IP4_RUL_V3_ID 13 +#define IP4_RUL_V3_OFFSET 0x5840c +#define IP4_RUL_V3_E_LENGTH 4 +#define IP4_RUL_V3_E_OFFSET 0x20 +#define IP4_RUL_V3_NR_E 32 + +#define IP4SPORTV "ip4v3_sportv" +#define IP4_RUL_V3_IP4SPORTV_BOFFSET 0 +#define IP4_RUL_V3_IP4SPORTV_BLEN 16 +#define IP4_RUL_V3_IP4SPORTV_FLAG HSL_RW + + +#define IP4_RUL_V4 "ip4v2" +#define IP4_RUL_V4_ID 13 +#define IP4_RUL_V4_OFFSET 0x58410 +#define IP4_RUL_V4_E_LENGTH 4 +#define IP4_RUL_V4_E_OFFSET 0x20 +#define IP4_RUL_V4_NR_E 32 + +#define IP4_INPT "ip4rv4_inpt" +#define IP4_RUL_V4_IP4_INPT_BOFFSET 0 +#define IP4_RUL_V4_IP4_INPT_BLEN 6 +#define IP4_RUL_V4_IP4_INPT_FLAG HSL_RW + + + + + + +#define IP4_RUL_M0 "ip4m0" +#define IP4_RUL_M0_ID 13 +#define IP4_RUL_M0_OFFSET 0x58c00 +#define IP4_RUL_M0_E_LENGTH 4 +#define IP4_RUL_M0_E_OFFSET 0x20 +#define IP4_RUL_M0_NR_E 32 + +#define DIPM "ip4m0_dipm" +#define IP4_RUL_M0_DIPM_BOFFSET 0 +#define IP4_RUL_M0_DIPM_BLEN 32 +#define IP4_RUL_M0_DIPM_FLAG HSL_RW + + + + +#define IP4_RUL_M1 "ip4m1" +#define IP4_RUL_M1_ID 13 +#define IP4_RUL_M1_OFFSET 0x58c04 +#define IP4_RUL_M1_E_LENGTH 4 +#define IP4_RUL_M1_E_OFFSET 0x20 +#define IP4_RUL_M1_NR_E 32 + +#define SIPM "ip4m1_sipm" +#define IP4_RUL_M1_SIPM_BOFFSET 0 +#define IP4_RUL_M1_SIPM_BLEN 32 +#define IP4_RUL_M1_SIPM_FLAG HSL_RW + + + + +#define IP4_RUL_M2 "ip4m2" +#define IP4_RUL_M2_ID 13 +#define IP4_RUL_M2_OFFSET 0x58c08 +#define IP4_RUL_M2_E_LENGTH 4 +#define IP4_RUL_M2_E_OFFSET 0x20 +#define IP4_RUL_M2_NR_E 32 + +#define IP4PROTM "ip4m2_protm" +#define IP4_RUL_M2_IP4PROTM_BOFFSET 0 +#define IP4_RUL_M2_IP4PROTM_BLEN 8 +#define IP4_RUL_M2_IP4PROTM_FLAG HSL_RW + +#define IP4DSCPM "ip4m2_dscpm" +#define IP4_RUL_M2_IP4DSCPM_BOFFSET 8 +#define IP4_RUL_M2_IP4DSCPM_BLEN 8 +#define IP4_RUL_M2_IP4DSCPM_FLAG HSL_RW + +#define IP4DPORTM "ip4m2_dportm" +#define IP4_RUL_M2_IP4DPORTM_BOFFSET 16 +#define IP4_RUL_M2_IP4DPORTM_BLEN 16 +#define IP4_RUL_M2_IP4DPORTM_FLAG HSL_RW + + + + +#define IP4_RUL_M3 "ip4m3" +#define IP4_RUL_M3_ID 13 +#define IP4_RUL_M3_OFFSET 0x58c0c +#define IP4_RUL_M3_E_LENGTH 4 +#define IP4_RUL_M3_E_OFFSET 0x20 +#define IP4_RUL_M3_NR_E 32 + +#define IP4SPORTM "ip4m3_sportm" +#define IP4_RUL_M3_IP4SPORTM_BOFFSET 0 +#define IP4_RUL_M3_IP4SPORTM_BLEN 16 +#define IP4_RUL_M3_IP4SPORTM_FLAG HSL_RW + +#define IP4SPORTM_EN "ip4m3_sportmen" +#define IP4_RUL_M3_IP4SPORTM_EN_BOFFSET 16 +#define IP4_RUL_M3_IP4SPORTM_EN_BLEN 1 +#define IP4_RUL_M3_IP4SPORTM_EN_FLAG HSL_RW + +#define IP4DPORTM_EN "ip4m3_dportmen" +#define IP4_RUL_M3_IP4DPORTM_EN_BOFFSET 17 +#define IP4_RUL_M3_IP4DPORTM_EN_BLEN 1 +#define IP4_RUL_M3_IP4DPORTM_EN_FLAG HSL_RW + + + + +#define IP6_RUL1_V0 "ip6r1v0" +#define IP6_RUL1_V0_ID 13 +#define IP6_RUL1_V0_OFFSET 0x58400 +#define IP6_RUL1_V0_E_LENGTH 4 +#define IP6_RUL1_V0_E_OFFSET 0x20 +#define IP6_RUL1_V0_NR_E 32 + +#define IP6_DIPV0 "ip6r1v0_dipv0" +#define IP6_RUL1_V0_IP6_DIPV0_BOFFSET 0 +#define IP6_RUL1_V0_IP6_DIPV0_BLEN 32 +#define IP6_RUL1_V0_IP6_DIPV0_FLAG HSL_RW + + + + +#define IP6_RUL1_V1 "ip6r1v1" +#define IP6_RUL1_V1_ID 13 +#define IP6_RUL1_V1_OFFSET 0x58404 +#define IP6_RUL1_V1_E_LENGTH 4 +#define IP6_RUL1_V1_E_OFFSET 0x20 +#define IP6_RUL1_V1_NR_E 32 + +#define IP6_DIPV1 "ip6r1v1_dipv1" +#define IP6_RUL1_V1_IP6_DIPV1_BOFFSET 0 +#define IP6_RUL1_V1_IP6_DIPv1_BLEN 32 +#define IP6_RUL1_V1_IP6_DIPV1_FLAG HSL_RW + + + +#define IP6_RUL1_V2 "ip6r1v2" +#define IP6_RUL1_V2_ID 13 +#define IP6_RUL1_V2_OFFSET 0x58408 +#define IP6_RUL1_V2_E_LENGTH 4 +#define IP6_RUL1_V2_E_OFFSET 0x20 +#define IP6_RUL1_V2_NR_E 32 + +#define IP6_DIPV2 "ip6r1v2_dipv2" +#define IP6_RUL1_V2_IP6_DIPV2_BOFFSET 0 +#define IP6_RUL1_V2_IP6_DIPv2_BLEN 32 +#define IP6_RUL1_V2_IP6_DIPV2_FLAG HSL_RW + + + + +#define IP6_RUL1_V3 "ip6r1v3" +#define IP6_RUL1_V3_ID 13 +#define IP6_RUL1_V3_OFFSET 0x5840c +#define IP6_RUL1_V3_E_LENGTH 4 +#define IP6_RUL1_V3_E_OFFSET 0x20 +#define IP6_RUL1_V3_NR_E 32 + +#define IP6_DIPV3 "ip6r1v3_dipv3" +#define IP6_RUL1_V3_IP6_DIPV3_BOFFSET 0 +#define IP6_RUL1_V3_IP6_DIPv3_BLEN 32 +#define IP6_RUL1_V3_IP6_DIPV3_FLAG HSL_RW + + + + +#define IP6_RUL1_V4 "ip6r1v4" +#define IP6_RUL1_V4_ID 13 +#define IP6_RUL1_V4_OFFSET 0x58410 +#define IP6_RUL1_V4_E_LENGTH 4 +#define IP6_RUL1_V4_E_OFFSET 0x20 +#define IP6_RUL1_V4_NR_E 32 + +#define IP6_RUL1_INPT "ip6r1v4_inpt" +#define IP6_RUL1_V4_IP6_RUL1_INPT_BOFFSET 0 +#define IP6_RUL1_V4_IP6_RUL1_INPT_BLEN 6 +#define IP6_RUL1_V4_IP6_RUL1_INPT_FLAG HSL_RW + + + + + +#define IP6_RUL1_M0 "ip6r1m0" +#define IP6_RUL1_M0_ID 13 +#define IP6_RUL1_M0_OFFSET 0x58c00 +#define IP6_RUL1_M0_E_LENGTH 4 +#define IP6_RUL1_M0_E_OFFSET 0x20 +#define IP6_RUL1_M0_NR_E 32 + +#define IP6_DIPM0 "ip6r1m0_dipm0" +#define IP6_RUL1_M0_IP6_DIPM0_BOFFSET 0 +#define IP6_RUL1_M0_IP6_DIPM0_BLEN 32 +#define IP6_RUL1_M0_IP6_DIPM0_FLAG HSL_RW + + + + +#define IP6_RUL1_M1 "ip6r1m1" +#define IP6_RUL1_M1_ID 13 +#define IP6_RUL1_M1_OFFSET 0x58c04 +#define IP6_RUL1_M1_E_LENGTH 4 +#define IP6_RUL1_M1_E_OFFSET 0x20 +#define IP6_RUL1_M1_NR_E 32 + +#define IP6_DIPM1 "ip6r1m1_dipm1" +#define IP6_RUL1_M1_IP6_DIPM1_BOFFSET 0 +#define IP6_RUL1_M1_IP6_DIPM1_BLEN 32 +#define IP6_RUL1_M1_IP6_DIPM1_FLAG HSL_RW + + + +#define IP6_RUL1_M2 "ip6r1m2" +#define IP6_RUL1_M2_ID 13 +#define IP6_RUL1_M2_OFFSET 0x58c08 +#define IP6_RUL1_M2_E_LENGTH 4 +#define IP6_RUL1_M2_E_OFFSET 0x20 +#define IP6_RUL1_M2_NR_E 32 + +#define IP6_DIPM2 "ip6r1m2_dipm2" +#define IP6_RUL1_M2_IP6_DIPM2_BOFFSET 0 +#define IP6_RUL1_M2_IP6_DIPM2_BLEN 32 +#define IP6_RUL1_M2_IP6_DIPM2_FLAG HSL_RW + + + + +#define IP6_RUL1_M3 "ip6r1m3" +#define IP6_RUL1_M3_ID 13 +#define IP6_RUL1_M3_OFFSET 0x58c0c +#define IP6_RUL1_M3_E_LENGTH 4 +#define IP6_RUL1_M3_E_OFFSET 0x20 +#define IP6_RUL1_M3_NR_E 32 + +#define IP6_DIPM3 "ip6r1m3_dipm3" +#define IP6_RUL1_M3_IP6_DIPM3_BOFFSET 0 +#define IP6_RUL1_M3_IP6_DIPM3_BLEN 32 +#define IP6_RUL1_M3_IP6_DIPM3_FLAG HSL_RW + + + + + +#define IP6_RUL2_V0 "ip6r2v0" +#define IP6_RUL2_V0_ID 13 +#define IP6_RUL2_V0_OFFSET 0x58400 +#define IP6_RUL2_V0_E_LENGTH 4 +#define IP6_RUL2_V0_E_OFFSET 0x20 +#define IP6_RUL2_V0_NR_E 32 + +#define IP6_SIPV0 "ip6r2v0_sipv0" +#define IP6_RUL2_V0_IP6_SIPV0_BOFFSET 0 +#define IP6_RUL2_V0_IP6_SIPv0_BLEN 32 +#define IP6_RUL2_V0_IP6_SIPV0_FLAG HSL_RW + + + + +#define IP6_RUL2_V1 "ip6r2v1" +#define IP6_RUL2_V1_ID 13 +#define IP6_RUL2_V1_OFFSET 0x58404 +#define IP6_RUL2_V1_E_LENGTH 4 +#define IP6_RUL2_V1_E_OFFSET 0x20 +#define IP6_RUL2_V1_NR_E 32 + +#define IP6_SIPV1 "ip6r2v1_sipv1" +#define IP6_RUL2_V1_IP6_SIPV1_BOFFSET 0 +#define IP6_RUL2_V1_IP6_SIPv1_BLEN 32 +#define IP6_RUL2_V1_IP6_SIPV1_FLAG HSL_RW + + + +#define IP6_RUL2_V2 "ip6r2v2" +#define IP6_RUL2_V2_ID 13 +#define IP6_RUL2_V2_OFFSET 0x58408 +#define IP6_RUL2_V2_E_LENGTH 4 +#define IP6_RUL2_V2_E_OFFSET 0x20 +#define IP6_RUL2_V2_NR_E 32 + +#define IP6_SIPV2 "ip6r2v2_sipv2" +#define IP6_RUL2_V2_IP6_SIPV2_BOFFSET 0 +#define IP6_RUL2_V2_IP6_SIPv2_BLEN 32 +#define IP6_RUL2_V2_IP6_SIPV2_FLAG HSL_RW + + + + +#define IP6_RUL2_V3 "ip6r2v3" +#define IP6_RUL2_V3_ID 13 +#define IP6_RUL2_V3_OFFSET 0x5840c +#define IP6_RUL2_V3_E_LENGTH 4 +#define IP6_RUL2_V3_E_OFFSET 0x20 +#define IP6_RUL2_V3_NR_E 32 + +#define IP6_SIPV3 "ip6r2v3_sipv3" +#define IP6_RUL2_V3_IP6_SIPV3_BOFFSET 0 +#define IP6_RUL2_V3_IP6_SIPv3_BLEN 32 +#define IP6_RUL2_V3_IP6_SIPV3_FLAG HSL_RW + + + + +#define IP6_RUL2_V4 "ip6r2v4" +#define IP6_RUL2_V4_ID 13 +#define IP6_RUL2_V4_OFFSET 0x58410 +#define IP6_RUL2_V4_E_LENGTH 4 +#define IP6_RUL2_V4_E_OFFSET 0x20 +#define IP6_RUL2_V4_NR_E 32 + +#define IP6_RUL2_INPT "ip6r2v4_inptm" +#define IP6_RUL2_V4_IP6_RUL2_INPT_BOFFSET 0 +#define IP6_RUL2_V4_IP6_RUL2_INPT_BLEN 6 +#define IP6_RUL2_V4_IP6_RUL2_INPT_FLAG HSL_RW + + + + +#define IP6_RUL2_M0 "ip6r2m0" +#define IP6_RUL2_M0_ID 13 +#define IP6_RUL2_M0_OFFSET 0x58c00 +#define IP6_RUL2_M0_E_LENGTH 4 +#define IP6_RUL2_M0_E_OFFSET 0x20 +#define IP6_RUL2_M0_NR_E 32 + +#define IP6_SIPM0 "ip6r2m0_sipm0" +#define IP6_RUL2_M0_IP6_SIPM0_BOFFSET 0 +#define IP6_RUL2_M0_IP6_SIPM0_BLEN 32 +#define IP6_RUL2_M0_IP6_SIPM0_FLAG HSL_RW + + + + +#define IP6_RUL2_M1 "ip6r2m1" +#define IP6_RUL2_M1_ID 13 +#define IP6_RUL2_M1_OFFSET 0x58c04 +#define IP6_RUL2_M1_E_LENGTH 4 +#define IP6_RUL2_M1_E_OFFSET 0x20 +#define IP6_RUL2_M1_NR_E 32 + +#define IP6_SIPM1 "ip6r2m1_sipm1" +#define IP6_RUL2_M1_IP6_DIPM1_BOFFSET 0 +#define IP6_RUL2_M1_IP6_DIPM1_BLEN 32 +#define IP6_RUL2_M1_IP6_DIPM1_FLAG HSL_RW + + + +#define IP6_RUL2_M2 "ip6r2m2" +#define IP6_RUL2_M2_ID 13 +#define IP6_RUL2_M2_OFFSET 0x58c08 +#define IP6_RUL2_M2_E_LENGTH 4 +#define IP6_RUL2_M2_E_OFFSET 0x20 +#define IP6_RUL2_M2_NR_E 32 + +#define IP6_SIPM2 "ip6r2m2_sipm2" +#define IP6_RUL2_M2_IP6_DIPM2_BOFFSET 0 +#define IP6_RUL2_M2_IP6_DIPM2_BLEN 32 +#define IP6_RUL2_M2_IP6_DIPM2_FLAG HSL_RW + + + + +#define IP6_RUL2_M3 "ip6r2m3" +#define IP6_RUL2_M3_ID 13 +#define IP6_RUL2_M3_OFFSET 0x58c0c +#define IP6_RUL2_M3_E_LENGTH 4 +#define IP6_RUL2_M3_E_OFFSET 0x20 +#define IP6_RUL2_M3_NR_E 32 + +#define IP6_SIPM3 "ip6r2m3_sipm3" +#define IP6_RUL2_M3_IP6_SIPM3_BOFFSET 0 +#define IP6_RUL2_M3_IP6_SIPM3_BLEN 32 +#define IP6_RUL2_M3_IP6_SIPM3_FLAG HSL_RW + + + + + +#define IP6_RUL3_V0 "ip6r3v0" +#define IP6_RUL3_V0_ID 13 +#define IP6_RUL3_V0_OFFSET 0x58400 +#define IP6_RUL3_V0_E_LENGTH 4 +#define IP6_RUL3_V0_E_OFFSET 0x20 +#define IP6_RUL3_V0_NR_E 32 + +#define IP6PROTV "ip6r3v0_protv" +#define IP6_RUL3_V0_IP6PROTV_BOFFSET 0 +#define IP6_RUL3_V0_IP6PROTV_BLEN 8 +#define IP6_RUL3_V0_IP6PROTV_FLAG HSL_RW + +#define IP6DSCPV "ip6r3v0_dscpv" +#define IP6_RUL3_V0_IP6DSCPV_BOFFSET 8 +#define IP6_RUL3_V0_IP6DSCPV_BLEN 8 +#define IP6_RUL3_V0_IP6DSCPV_FLAG HSL_RW + +#define IP6DPORTV "ip6r3v0_dportv" +#define IP6_RUL3_V0_IP6DPORTV_BOFFSET 16 +#define IP6_RUL3_V0_IP6DPORTV_BLEN 16 +#define IP6_RUL3_V0_IP6DPORTV_FLAG HSL_RW + + + + +#define IP6_RUL3_V1 "ip6r3v1" +#define IP6_RUL3_V1_ID 13 +#define IP6_RUL3_V1_OFFSET 0x58404 +#define IP6_RUL3_V1_E_LENGTH 4 +#define IP6_RUL3_V1_E_OFFSET 0x20 +#define IP6_RUL3_V1_NR_E 32 + +#define IP6SPORTV "ip6r3v1_sportv" +#define IP6_RUL3_V1_IP6SPORTV_BOFFSET 0 +#define IP6_RUL3_V1_IP6SPORTV_BLEN 16 +#define IP6_RUL3_V1_IP6SPORTV_FLAG HSL_RW + +#define IP6LABEL1V "ip6r3v1_label1v" +#define IP6_RUL3_V1_IP6LABEL1V_BOFFSET 16 +#define IP6_RUL3_V1_IP6LABEL1V_BLEN 16 +#define IP6_RUL3_V1_IP6LABEL1V_FLAG HSL_RW + + + + +#define IP6_RUL3_V2 "ip6r3v2" +#define IP6_RUL3_V2_ID 13 +#define IP6_RUL3_V2_OFFSET 0x58408 +#define IP6_RUL3_V2_E_LENGTH 4 +#define IP6_RUL3_V2_E_OFFSET 0x20 +#define IP6_RUL3_V2_NR_E 32 + +#define IP6LABEL2V "ip6r3v2_label2v" +#define IP6_RUL3_V2_IP6LABEL2V_BOFFSET 0 +#define IP6_RUL3_V2_IP6LABEL2V_BLEN 4 +#define IP6_RUL3_V2_IP6LABEL2V_FLAG HSL_RW + + + + +#define IP6_RUL3_V4 "ip6r3v4" +#define IP6_RUL3_V4_ID 13 +#define IP6_RUL3_V4_OFFSET 0x58410 +#define IP6_RUL3_V4_E_LENGTH 4 +#define IP6_RUL3_V4_E_OFFSET 0x20 +#define IP6_RUL3_V4_NR_E 32 + +#define IP6_RUL3_INPT "ip6r3v4_inpt" +#define IP6_RUL3_V4_IP6_RUL3_INPT_BOFFSET 0 +#define IP6_RUL3_V4_IP6_RUL3_INPT_BLEN 6 +#define IP6_RUL3_V4_IP6_RUL3_INPT_FLAG HSL_RW + + + + +#define IP6_RUL3_M0 "ip6r3m0" +#define IP6_RUL3_M0_ID 13 +#define IP6_RUL3_M0_OFFSET 0x58c00 +#define IP6_RUL3_M0_E_LENGTH 4 +#define IP6_RUL3_M0_E_OFFSET 0x20 +#define IP6_RUL3_M0_NR_E 32 + +#define IP6PROTM "ip6r3m0_protm" +#define IP6_RUL3_M0_IP6PROTM_BOFFSET 0 +#define IP6_RUL3_M0_IP6PROTM_BLEN 8 +#define IP6_RUL3_M0_IP6PROTM_FLAG HSL_RW + +#define IP6DSCPM "ip6r3m0_dscpm" +#define IP6_RUL3_M0_IP6DSCPM_BOFFSET 8 +#define IP6_RUL3_M0_IP6DSCPM_BLEN 8 +#define IP6_RUL3_M0_IP6DSCPM_FLAG HSL_RW + +#define IP6DPORTM "ip6r3m0_dportm" +#define IP6_RUL3_M0_IP6DPORTM_BOFFSET 16 +#define IP6_RUL3_M0_IP6DPORTM_BLEN 16 +#define IP6_RUL3_M0_IP6DPORTM_FLAG HSL_RW + + + + +#define IP6_RUL3_M1 "ip6r3m1" +#define IP6_RUL3_M1_ID 13 +#define IP6_RUL3_M1_OFFSET 0x58c04 +#define IP6_RUL3_M1_E_LENGTH 4 +#define IP6_RUL3_M1_E_OFFSET 0x20 +#define IP6_RUL3_M1_NR_E 32 + +#define IP6SPORTM "ip6r3m1_sportm" +#define IP6_RUL3_M1_IP6SPORTM_BOFFSET 0 +#define IP6_RUL3_M1_IP6SPORTM_BLEN 16 +#define IP6_RUL3_M1_IP6SPORTM_FLAG HSL_RW + +#define IP6LABEL1M "ip6r3m1_label1m" +#define IP6_RUL3_M1_IP6LABEL1M_BOFFSET 16 +#define IP6_RUL3_M1_IP6LABEL1M_BLEN 16 +#define IP6_RUL3_M1_IP6LABEL1M_FLAG HSL_RW + + + + +#define IP6_RUL3_M2 "ip6r3m2" +#define IP6_RUL3_M2_ID 13 +#define IP6_RUL3_M2_OFFSET 0x58c08 +#define IP6_RUL3_M2_E_LENGTH 4 +#define IP6_RUL3_M2_E_OFFSET 0x20 +#define IP6_RUL3_M2_NR_E 32 + +#define IP6LABEL2M "ip6r3m2_label2m" +#define IP6_RUL3_M2_IP6LABEL2M_BOFFSET 0 +#define IP6_RUL3_M2_IP6LABEL2M_BLEN 4 +#define IP6_RUL3_M2_IP6LABEL21M_FLAG HSL_RW + + + + +#define IP6_RUL3_M3 "ip6r3m3" +#define IP6_RUL3_M3_ID 13 +#define IP6_RUL3_M3_OFFSET 0x58c0c +#define IP6_RUL3_M3_E_LENGTH 4 +#define IP6_RUL3_M3_E_OFFSET 0x20 +#define IP6_RUL3_M3_NR_E 32 + + +#define IP6DPORTM_EN "ip6r3m3_dportmen" +#define IP6_RUL3_M3_IP6DPORTM_EN_BOFFSET 25 +#define IP6_RUL3_M3_IP6DPORTM_EN_BLEN 1 +#define IP6_RUL3_M3_IP6DPORTM_EN_FLAG HSL_RW + +#define IP6SPORTM_EN "ip6r3m3_sportmen" +#define IP6_RUL3_M3_IP6SPORTM_EN_BOFFSET 24 +#define IP6_RUL3_M3_IP6SPORTM_EN_BLEN 1 +#define IP6_RUL3_M3_IP6SPORTM_EN_FLAG HSL_RW + + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _GARUDA_REG_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_reg_access.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_reg_access.h new file mode 100755 index 000000000..3325e9fd2 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_reg_access.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2012,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 _GARUDA_REG_ACCESS_H_ +#define _GARUDA_REG_ACCESS_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "sw.h" + + sw_error_t + garuda_phy_get(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t * value); + + sw_error_t + garuda_phy_set(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t value); + + sw_error_t + garuda_reg_get(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t value[], + a_uint32_t value_len); + + sw_error_t + garuda_reg_set(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t value[], + a_uint32_t value_len); + + sw_error_t + garuda_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 + garuda_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 + garuda_reg_access_init(a_uint32_t dev_id, hsl_access_mode mode); + + sw_error_t + garuda_access_mode_set(a_uint32_t dev_id, hsl_access_mode mode); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _GARUDA_REG_ACCESS_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_stp.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_stp.h new file mode 100755 index 000000000..c81129182 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_stp.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 garuda_stp GARUDA_STP + * @{ + */ +#ifndef _GARUDA_STP_H_ +#define _GARUDA_STP_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_stp.h" + + sw_error_t garuda_stp_init(a_uint32_t dev_id); + +#ifdef IN_STP +#define GARUDA_STP_INIT(rv, dev_id) \ + { \ + rv = garuda_stp_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define GARUDA_STP_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + garuda_stp_port_state_set(a_uint32_t dev_id, a_uint32_t st_id, + fal_port_t port_id, fal_stp_state_t state); + + + + HSL_LOCAL sw_error_t + garuda_stp_port_state_get(a_uint32_t dev_id, a_uint32_t st_id, + fal_port_t port_id, fal_stp_state_t * state); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _GARUDA_STP_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_vlan.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_vlan.h new file mode 100755 index 000000000..9eff4331b --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/garuda/garuda_vlan.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 garuda_vlan GARUDA_VLAN + * @{ + */ +#ifndef _GARUDA_VLAN_H_ +#define _GARUDA_VLAN_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_vlan.h" + + sw_error_t + garuda_vlan_init(a_uint32_t dev_id); + +#ifdef IN_VLAN +#define GARUDA_VLAN_INIT(rv, dev_id) \ + { \ + rv = garuda_vlan_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define GARUDA_VLAN_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + garuda_vlan_entry_append(a_uint32_t dev_id, const fal_vlan_t * vlan_entry); + + + + HSL_LOCAL sw_error_t + garuda_vlan_create(a_uint32_t dev_id, a_uint32_t vlan_id); + + + + HSL_LOCAL sw_error_t + garuda_vlan_next(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan); + + + + HSL_LOCAL sw_error_t + garuda_vlan_find(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan); + + + + HSL_LOCAL sw_error_t + garuda_vlan_member_update(a_uint32_t dev_id, a_uint32_t vlan_id, + fal_pbmp_t member, fal_pbmp_t u_member); + + + + HSL_LOCAL sw_error_t + garuda_vlan_delete(a_uint32_t dev_id, a_uint32_t vlan_id); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _GARUDA_VLAN_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_api.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_api.h new file mode 100755 index 000000000..aed76d285 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_api.h @@ -0,0 +1,559 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _HORUS_API_H_ +#define _HORUS_API_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifdef IN_PORTCONTROL +#define PORTCONTROL_API \ + SW_API_DEF(SW_API_PT_DUPLEX_GET, horus_port_duplex_get), \ + SW_API_DEF(SW_API_PT_DUPLEX_SET, horus_port_duplex_set), \ + SW_API_DEF(SW_API_PT_SPEED_GET, horus_port_speed_get), \ + SW_API_DEF(SW_API_PT_SPEED_SET, horus_port_speed_set), \ + SW_API_DEF(SW_API_PT_AN_GET, horus_port_autoneg_status_get), \ + SW_API_DEF(SW_API_PT_AN_ENABLE, horus_port_autoneg_enable), \ + SW_API_DEF(SW_API_PT_AN_RESTART, horus_port_autoneg_restart), \ + SW_API_DEF(SW_API_PT_AN_ADV_GET, horus_port_autoneg_adv_get), \ + SW_API_DEF(SW_API_PT_AN_ADV_SET, horus_port_autoneg_adv_set), \ + SW_API_DEF(SW_API_PT_HDR_SET, horus_port_hdr_status_set), \ + SW_API_DEF(SW_API_PT_HDR_GET, horus_port_hdr_status_get), \ + SW_API_DEF(SW_API_PT_FLOWCTRL_SET, horus_port_flowctrl_set), \ + SW_API_DEF(SW_API_PT_FLOWCTRL_GET, horus_port_flowctrl_get), \ + SW_API_DEF(SW_API_PT_FLOWCTRL_MODE_SET, horus_port_flowctrl_forcemode_set), \ + SW_API_DEF(SW_API_PT_FLOWCTRL_MODE_GET, horus_port_flowctrl_forcemode_get), \ + SW_API_DEF(SW_API_PT_POWERSAVE_SET, horus_port_powersave_set), \ + SW_API_DEF(SW_API_PT_POWERSAVE_GET, horus_port_powersave_get), \ + SW_API_DEF(SW_API_PT_HIBERNATE_SET, horus_port_hibernate_set), \ + SW_API_DEF(SW_API_PT_HIBERNATE_GET, horus_port_hibernate_get), \ + SW_API_DEF(SW_API_PT_CDT, horus_port_cdt), + +#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) \ + 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) \ + SW_API_DESC(SW_API_PT_HIBERNATE_SET) \ + SW_API_DESC(SW_API_PT_HIBERNATE_GET) \ + SW_API_DESC(SW_API_PT_CDT) +#else +#define PORTCONTROL_API +#define PORTCONTROL_API_PARAM +#endif + + +#ifdef IN_VLAN +#define VLAN_API \ + SW_API_DEF(SW_API_VLAN_ADD, horus_vlan_create), \ + SW_API_DEF(SW_API_VLAN_DEL, horus_vlan_delete), \ + SW_API_DEF(SW_API_VLAN_MEM_UPDATE, horus_vlan_member_update), \ + SW_API_DEF(SW_API_VLAN_FIND, horus_vlan_find), \ + SW_API_DEF(SW_API_VLAN_NEXT, horus_vlan_next), \ + SW_API_DEF(SW_API_VLAN_APPEND, horus_vlan_entry_append), + +#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) +#else +#define VLAN_API +#define VLAN_API_PARAM +#endif + + +#ifdef IN_PORTVLAN +#define PORTVLAN_API \ + SW_API_DEF(SW_API_PT_ING_MODE_GET, horus_port_1qmode_get), \ + SW_API_DEF(SW_API_PT_ING_MODE_SET, horus_port_1qmode_set), \ + SW_API_DEF(SW_API_PT_EG_MODE_GET, horus_port_egvlanmode_get), \ + SW_API_DEF(SW_API_PT_EG_MODE_SET, horus_port_egvlanmode_set), \ + SW_API_DEF(SW_API_PT_VLAN_MEM_ADD, horus_portvlan_member_add), \ + SW_API_DEF(SW_API_PT_VLAN_MEM_DEL, horus_portvlan_member_del), \ + SW_API_DEF(SW_API_PT_VLAN_MEM_UPDATE, horus_portvlan_member_update), \ + SW_API_DEF(SW_API_PT_VLAN_MEM_GET, horus_portvlan_member_get), \ + SW_API_DEF(SW_API_PT_DEF_VID_SET, horus_port_default_vid_set), \ + SW_API_DEF(SW_API_PT_DEF_VID_GET, horus_port_default_vid_get), \ + SW_API_DEF(SW_API_PT_FORCE_DEF_VID_SET, horus_port_force_default_vid_set), \ + SW_API_DEF(SW_API_PT_FORCE_DEF_VID_GET, horus_port_force_default_vid_get), \ + SW_API_DEF(SW_API_PT_FORCE_PORTVLAN_SET, horus_port_force_portvlan_set), \ + SW_API_DEF(SW_API_PT_FORCE_PORTVLAN_GET, horus_port_force_portvlan_get), \ + SW_API_DEF(SW_API_NESTVLAN_TPID_SET, horus_nestvlan_tpid_set), \ + SW_API_DEF(SW_API_NESTVLAN_TPID_GET, horus_nestvlan_tpid_get), \ + SW_API_DEF(SW_API_PT_IN_VLAN_MODE_SET, horus_port_invlan_mode_set), \ + SW_API_DEF(SW_API_PT_IN_VLAN_MODE_GET, horus_port_invlan_mode_get), \ + SW_API_DEF(SW_API_PT_PRI_PROPAGATION_SET, horus_port_pri_propagation_set), \ + SW_API_DEF(SW_API_PT_PRI_PROPAGATION_GET, horus_port_pri_propagation_get), \ + SW_API_DEF(SW_API_QINQ_MODE_SET, horus_qinq_mode_set), \ + SW_API_DEF(SW_API_QINQ_MODE_GET, horus_qinq_mode_get), \ + SW_API_DEF(SW_API_PT_QINQ_ROLE_SET, horus_port_qinq_role_set), \ + SW_API_DEF(SW_API_PT_QINQ_ROLE_GET, horus_port_qinq_role_get), + +#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_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_PRI_PROPAGATION_SET) \ + SW_API_DESC(SW_API_PT_PRI_PROPAGATION_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) +#else +#define PORTVLAN_API +#define PORTVLAN_API_PARAM +#endif + + +#ifdef IN_FDB +#define FDB_API \ + SW_API_DEF(SW_API_FDB_ADD, horus_fdb_add), \ + SW_API_DEF(SW_API_FDB_DELALL, horus_fdb_del_all), \ + SW_API_DEF(SW_API_FDB_DELPORT,horus_fdb_del_by_port), \ + SW_API_DEF(SW_API_FDB_DELMAC, horus_fdb_del_by_mac), \ + SW_API_DEF(SW_API_FDB_FIRST, horus_fdb_first), \ + SW_API_DEF(SW_API_FDB_NEXT, horus_fdb_next), \ + SW_API_DEF(SW_API_FDB_FIND, horus_fdb_find), \ + SW_API_DEF(SW_API_FDB_PT_LEARN_SET, horus_fdb_port_learn_set), \ + SW_API_DEF(SW_API_FDB_PT_LEARN_GET, horus_fdb_port_learn_get), \ + SW_API_DEF(SW_API_FDB_AGE_CTRL_SET, horus_fdb_age_ctrl_set), \ + SW_API_DEF(SW_API_FDB_AGE_CTRL_GET, horus_fdb_age_ctrl_get), \ + SW_API_DEF(SW_API_FDB_AGE_TIME_SET, horus_fdb_age_time_set), \ + SW_API_DEF(SW_API_FDB_AGE_TIME_GET, horus_fdb_age_time_get), + +#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_AGE_CTRL_SET) \ + SW_API_DESC(SW_API_FDB_AGE_CTRL_GET) \ + SW_API_DESC(SW_API_FDB_AGE_TIME_SET) \ + SW_API_DESC(SW_API_FDB_AGE_TIME_GET) +#else +#define FDB_API +#define FDB_API_PARAM +#endif + + +#ifdef IN_QOS +#define QOS_API \ + SW_API_DEF(SW_API_QOS_QU_TX_BUF_ST_SET, horus_qos_queue_tx_buf_status_set), \ + SW_API_DEF(SW_API_QOS_QU_TX_BUF_ST_GET, horus_qos_queue_tx_buf_status_get), \ + SW_API_DEF(SW_API_QOS_QU_TX_BUF_NR_SET, horus_qos_queue_tx_buf_nr_set), \ + SW_API_DEF(SW_API_QOS_QU_TX_BUF_NR_GET, horus_qos_queue_tx_buf_nr_get), \ + SW_API_DEF(SW_API_QOS_PT_TX_BUF_ST_SET, horus_qos_port_tx_buf_status_set), \ + SW_API_DEF(SW_API_QOS_PT_TX_BUF_ST_GET, horus_qos_port_tx_buf_status_get), \ + SW_API_DEF(SW_API_QOS_PT_TX_BUF_NR_SET, horus_qos_port_tx_buf_nr_set), \ + SW_API_DEF(SW_API_QOS_PT_TX_BUF_NR_GET, horus_qos_port_tx_buf_nr_get), \ + SW_API_DEF(SW_API_QOS_PT_RX_BUF_NR_SET, horus_qos_port_rx_buf_nr_set), \ + SW_API_DEF(SW_API_QOS_PT_RX_BUF_NR_GET, horus_qos_port_rx_buf_nr_get), \ + SW_API_DEF(SW_API_COSMAP_UP_QU_SET, horus_cosmap_up_queue_set), \ + SW_API_DEF(SW_API_COSMAP_UP_QU_GET, horus_cosmap_up_queue_get), \ + SW_API_DEF(SW_API_COSMAP_DSCP_QU_SET, horus_cosmap_dscp_queue_set), \ + SW_API_DEF(SW_API_COSMAP_DSCP_QU_GET, horus_cosmap_dscp_queue_get), \ + SW_API_DEF(SW_API_QOS_PT_MODE_SET, horus_qos_port_mode_set), \ + SW_API_DEF(SW_API_QOS_PT_MODE_GET, horus_qos_port_mode_get), \ + SW_API_DEF(SW_API_QOS_PT_MODE_PRI_SET, horus_qos_port_mode_pri_set), \ + SW_API_DEF(SW_API_QOS_PT_MODE_PRI_GET, horus_qos_port_mode_pri_get), \ + SW_API_DEF(SW_API_QOS_PORT_DEF_UP_SET, horus_qos_port_default_up_set), \ + SW_API_DEF(SW_API_QOS_PORT_DEF_UP_GET, horus_qos_port_default_up_get), \ + SW_API_DEF(SW_API_QOS_PORT_SCH_MODE_SET, horus_qos_port_sch_mode_set), \ + SW_API_DEF(SW_API_QOS_PORT_SCH_MODE_GET, horus_qos_port_sch_mode_get), + +#define QOS_API_PARAM \ + 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_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) +#else +#define QOS_API +#define QOS_API_PARAM +#endif + + +#ifdef IN_IGMP +#define IGMP_API \ + SW_API_DEF(SW_API_PT_IGMPS_MODE_SET, horus_port_igmps_status_set), \ + SW_API_DEF(SW_API_PT_IGMPS_MODE_GET, horus_port_igmps_status_get), \ + SW_API_DEF(SW_API_IGMP_MLD_CMD_SET, horus_igmp_mld_cmd_set), \ + SW_API_DEF(SW_API_IGMP_MLD_CMD_GET, horus_igmp_mld_cmd_get), \ + SW_API_DEF(SW_API_IGMP_PT_JOIN_SET, horus_port_igmp_mld_join_set), \ + SW_API_DEF(SW_API_IGMP_PT_JOIN_GET, horus_port_igmp_mld_join_get), \ + SW_API_DEF(SW_API_IGMP_PT_LEAVE_SET, horus_port_igmp_mld_leave_set), \ + SW_API_DEF(SW_API_IGMP_PT_LEAVE_GET, horus_port_igmp_mld_leave_get), \ + SW_API_DEF(SW_API_IGMP_RP_SET, horus_igmp_mld_rp_set), \ + SW_API_DEF(SW_API_IGMP_RP_GET, horus_igmp_mld_rp_get), \ + SW_API_DEF(SW_API_IGMP_ENTRY_CREAT_SET, horus_igmp_mld_entry_creat_set), \ + SW_API_DEF(SW_API_IGMP_ENTRY_CREAT_GET, horus_igmp_mld_entry_creat_get), \ + SW_API_DEF(SW_API_IGMP_ENTRY_STATIC_SET, horus_igmp_mld_entry_static_set), \ + SW_API_DEF(SW_API_IGMP_ENTRY_STATIC_GET, horus_igmp_mld_entry_static_get), \ + SW_API_DEF(SW_API_IGMP_ENTRY_LEAKY_SET, horus_igmp_mld_entry_leaky_set), \ + SW_API_DEF(SW_API_IGMP_ENTRY_LEAKY_GET, horus_igmp_mld_entry_leaky_get), \ + SW_API_DEF(SW_API_IGMP_ENTRY_V3_SET, horus_igmp_mld_entry_v3_set), \ + SW_API_DEF(SW_API_IGMP_ENTRY_V3_GET, horus_igmp_mld_entry_v3_get), \ + SW_API_DEF(SW_API_IGMP_ENTRY_QUEUE_SET, horus_igmp_mld_entry_queue_set), \ + SW_API_DEF(SW_API_IGMP_ENTRY_QUEUE_GET, horus_igmp_mld_entry_queue_get), \ + +#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) +#else +#define IGMP_API +#define IGMP_API_PARAM +#endif + + +#ifdef IN_LEAKY +#define LEAKY_API \ + SW_API_DEF(SW_API_UC_LEAKY_MODE_SET, horus_uc_leaky_mode_set), \ + SW_API_DEF(SW_API_UC_LEAKY_MODE_GET, horus_uc_leaky_mode_get), \ + SW_API_DEF(SW_API_MC_LEAKY_MODE_SET, horus_mc_leaky_mode_set), \ + SW_API_DEF(SW_API_MC_LEAKY_MODE_GET, horus_mc_leaky_mode_get), \ + SW_API_DEF(SW_API_ARP_LEAKY_MODE_SET, horus_port_arp_leaky_set), \ + SW_API_DEF(SW_API_ARP_LEAKY_MODE_GET, horus_port_arp_leaky_get), \ + SW_API_DEF(SW_API_PT_UC_LEAKY_MODE_SET, horus_port_uc_leaky_set), \ + SW_API_DEF(SW_API_PT_UC_LEAKY_MODE_GET, horus_port_uc_leaky_get), \ + SW_API_DEF(SW_API_PT_MC_LEAKY_MODE_SET, horus_port_mc_leaky_set), \ + SW_API_DEF(SW_API_PT_MC_LEAKY_MODE_GET, horus_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, horus_mirr_analysis_port_set), \ + SW_API_DEF(SW_API_MIRROR_ANALY_PT_GET, horus_mirr_analysis_port_get), \ + SW_API_DEF(SW_API_MIRROR_IN_PT_SET, horus_mirr_port_in_set), \ + SW_API_DEF(SW_API_MIRROR_IN_PT_GET, horus_mirr_port_in_get), \ + SW_API_DEF(SW_API_MIRROR_EG_PT_SET, horus_mirr_port_eg_set), \ + SW_API_DEF(SW_API_MIRROR_EG_PT_GET, horus_mirr_port_eg_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) +#else +#define MIRROR_API +#define MIRROR_API_PARAM +#endif + + + +#ifdef IN_RATE +#define RATE_API \ + SW_API_DEF(SW_API_RATE_PT_EGRL_SET, horus_rate_port_egrl_set), \ + SW_API_DEF(SW_API_RATE_PT_EGRL_GET, horus_rate_port_egrl_get), \ + SW_API_DEF(SW_API_RATE_PT_INRL_SET, horus_rate_port_inrl_set), \ + SW_API_DEF(SW_API_RATE_PT_INRL_GET, horus_rate_port_inrl_get), \ + SW_API_DEF(SW_API_STORM_CTRL_FRAME_SET, horus_storm_ctrl_frame_set), \ + SW_API_DEF(SW_API_STORM_CTRL_FRAME_GET, horus_storm_ctrl_frame_get), \ + SW_API_DEF(SW_API_STORM_CTRL_RATE_SET, horus_storm_ctrl_rate_set), \ + SW_API_DEF(SW_API_STORM_CTRL_RATE_GET, horus_storm_ctrl_rate_get), + +#define RATE_API_PARAM \ + 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) +#else +#define RATE_API +#define RATE_API_PARAM +#endif + + +#ifdef IN_STP +#define STP_API \ + SW_API_DEF(SW_API_STP_PT_STATE_SET, horus_stp_port_state_set), \ + SW_API_DEF(SW_API_STP_PT_STATE_GET, horus_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, horus_get_mib_info), \ + SW_API_DEF(SW_API_MIB_STATUS_SET, horus_mib_status_set), \ + SW_API_DEF(SW_API_MIB_STATUS_GET, horus_mib_status_get), + +#define MIB_API_PARAM \ + SW_API_DESC(SW_API_PT_MIB_GET) \ + SW_API_DESC(SW_API_MIB_STATUS_SET) \ + SW_API_DESC(SW_API_MIB_STATUS_GET) +#else +#define MIB_API +#define MIB_API_PARAM +#endif + + +#ifdef IN_MISC +#define MISC_API \ + SW_API_DEF(SW_API_ARP_STATUS_SET, horus_arp_status_set), \ + SW_API_DEF(SW_API_ARP_STATUS_GET, horus_arp_status_get), \ + SW_API_DEF(SW_API_FRAME_MAX_SIZE_SET, horus_frame_max_size_set), \ + SW_API_DEF(SW_API_FRAME_MAX_SIZE_GET, horus_frame_max_size_get), \ + SW_API_DEF(SW_API_PT_UNK_SA_CMD_SET, horus_port_unk_sa_cmd_set), \ + SW_API_DEF(SW_API_PT_UNK_SA_CMD_GET, horus_port_unk_sa_cmd_get), \ + SW_API_DEF(SW_API_PT_UNK_UC_FILTER_SET, horus_port_unk_uc_filter_set), \ + SW_API_DEF(SW_API_PT_UNK_UC_FILTER_GET, horus_port_unk_uc_filter_get), \ + SW_API_DEF(SW_API_PT_UNK_MC_FILTER_SET, horus_port_unk_mc_filter_set), \ + SW_API_DEF(SW_API_PT_UNK_MC_FILTER_GET, horus_port_unk_mc_filter_get), \ + SW_API_DEF(SW_API_PT_BC_FILTER_SET, horus_port_bc_filter_set), \ + SW_API_DEF(SW_API_PT_BC_FILTER_GET, horus_port_bc_filter_get), \ + SW_API_DEF(SW_API_CPU_PORT_STATUS_SET, horus_cpu_port_status_set), \ + SW_API_DEF(SW_API_CPU_PORT_STATUS_GET, horus_cpu_port_status_get), \ + SW_API_DEF(SW_API_PPPOE_CMD_SET, horus_pppoe_cmd_set), \ + SW_API_DEF(SW_API_PPPOE_CMD_GET, horus_pppoe_cmd_get), \ + SW_API_DEF(SW_API_PPPOE_STATUS_SET, horus_pppoe_status_set), \ + SW_API_DEF(SW_API_PPPOE_STATUS_GET, horus_pppoe_status_get), \ + SW_API_DEF(SW_API_PT_DHCP_SET, horus_port_dhcp_set), \ + SW_API_DEF(SW_API_PT_DHCP_GET, horus_port_dhcp_get), \ + SW_API_DEF(SW_API_ARP_CMD_SET, horus_arp_cmd_set), \ + SW_API_DEF(SW_API_ARP_CMD_GET, horus_arp_cmd_get), \ + SW_API_DEF(SW_API_EAPOL_CMD_SET, horus_eapol_cmd_set), \ + SW_API_DEF(SW_API_EAPOL_CMD_GET, horus_eapol_cmd_get), \ + SW_API_DEF(SW_API_EAPOL_STATUS_SET, horus_eapol_status_set), \ + SW_API_DEF(SW_API_EAPOL_STATUS_GET, horus_eapol_status_get), \ + SW_API_DEF(SW_API_RIPV1_STATUS_SET, horus_ripv1_status_set), \ + SW_API_DEF(SW_API_RIPV1_STATUS_GET, horus_ripv1_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_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_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) +#else +#define MISC_API +#define MISC_API_PARAM +#endif + + +#ifdef IN_LED +#define LED_API \ + SW_API_DEF(SW_API_LED_PATTERN_SET, horus_led_ctrl_pattern_set), \ + SW_API_DEF(SW_API_LED_PATTERN_GET, horus_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 + + +#define REG_API \ + SW_API_DEF(SW_API_PHY_GET, horus_phy_get), \ + SW_API_DEF(SW_API_PHY_SET, horus_phy_set), \ + SW_API_DEF(SW_API_REG_GET, horus_reg_get), \ + SW_API_DEF(SW_API_REG_SET, horus_reg_set), \ + SW_API_DEF(SW_API_REG_FIELD_GET, horus_reg_field_get), \ + SW_API_DEF(SW_API_REG_FIELD_SET, horus_reg_field_set), + +#define REG_API_PARAM \ + SW_API_DESC(SW_API_PHY_GET) \ + SW_API_DESC(SW_API_PHY_SET) \ + SW_API_DESC(SW_API_REG_GET) \ + SW_API_DESC(SW_API_REG_SET) \ + SW_API_DESC(SW_API_REG_FIELD_GET) \ + SW_API_DESC(SW_API_REG_FIELD_SET) + + +#define SSDK_API \ + SW_API_DEF(SW_API_SWITCH_RESET, horus_reset), \ + SW_API_DEF(SW_API_SSDK_CFG, hsl_ssdk_cfg), \ + PORTCONTROL_API \ + VLAN_API \ + PORTVLAN_API \ + FDB_API \ + QOS_API \ + IGMP_API \ + LEAKY_API \ + MIRROR_API \ + RATE_API \ + STP_API \ + MIB_API \ + MISC_API \ + LED_API \ + REG_API \ + SW_API_DEF(SW_API_MAX, NULL), + + +#define SSDK_PARAM \ + 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"), \ + MIB_API_PARAM \ + LEAKY_API_PARAM \ + MISC_API_PARAM \ + IGMP_API_PARAM \ + MIRROR_API_PARAM \ + PORTCONTROL_API_PARAM \ + PORTVLAN_API_PARAM \ + VLAN_API_PARAM \ + FDB_API_PARAM \ + QOS_API_PARAM \ + RATE_API_PARAM \ + STP_API_PARAM \ + LED_API_PARAM \ + REG_API_PARAM \ + SW_PARAM_DEF(SW_API_MAX, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), + + +#if (defined(USER_MODE) && defined(KERNEL_MODULE)) +#undef SSDK_API +#undef SSDK_PARAM + +#define SSDK_API \ + REG_API \ + SW_API_DEF(SW_API_MAX, NULL), + +#define SSDK_PARAM \ + REG_API_PARAM \ + SW_PARAM_DEF(SW_API_MAX, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), +#endif + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _HORUS_API_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_fdb.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_fdb.h new file mode 100755 index 000000000..3097bab00 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_fdb.h @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 horus_fdb HORUS_FDB + * @{ + */ +#ifndef _HORUS_FDB_H_ +#define _HORUS_FDB_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_fdb.h" + + sw_error_t + horus_fdb_init(a_uint32_t dev_id); + +#ifdef IN_FDB +#define HORUS_FDB_INIT(rv, dev_id) \ + { \ + rv = horus_fdb_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define HORUS_FDB_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + horus_fdb_add(a_uint32_t dev_id, const fal_fdb_entry_t * entry); + + + HSL_LOCAL sw_error_t + horus_fdb_del_all(a_uint32_t dev_id, a_uint32_t flag); + + + HSL_LOCAL sw_error_t + horus_fdb_del_by_port(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t flag); + + + HSL_LOCAL sw_error_t + horus_fdb_del_by_mac(a_uint32_t dev_id, + const fal_fdb_entry_t *entry); + + + HSL_LOCAL sw_error_t + horus_fdb_first(a_uint32_t dev_id, fal_fdb_entry_t * entry); + + + HSL_LOCAL sw_error_t + horus_fdb_next(a_uint32_t dev_id, fal_fdb_entry_t * entry); + + + HSL_LOCAL sw_error_t + horus_fdb_find(a_uint32_t dev_id, fal_fdb_entry_t * entry); + + + HSL_LOCAL sw_error_t + horus_fdb_port_learn_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_fdb_port_learn_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable); + + + HSL_LOCAL sw_error_t + horus_fdb_age_ctrl_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_fdb_age_ctrl_get(a_uint32_t dev_id, a_bool_t *enable); + + + HSL_LOCAL sw_error_t + horus_fdb_age_time_set(a_uint32_t dev_id, a_uint32_t * time); + + + HSL_LOCAL sw_error_t + horus_fdb_age_time_get(a_uint32_t dev_id, a_uint32_t * time); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _HORUS_FDB_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_igmp.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_igmp.h new file mode 100755 index 000000000..e17b67a08 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_igmp.h @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 horus_igmp HORUS_IGMP + * @{ + */ +#ifndef _HORUS_IGMP_H_ +#define _HORUS_IGMP_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_igmp.h" + + sw_error_t + horus_igmp_init(a_uint32_t dev_id); + +#ifdef IN_IGMP +#define HORUS_IGMP_INIT(rv, dev_id) \ + { \ + rv = horus_igmp_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define HORUS_IGMP_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + horus_port_igmps_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_port_igmps_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable); + + + HSL_LOCAL sw_error_t + horus_igmp_mld_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + + HSL_LOCAL sw_error_t + horus_igmp_mld_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + + HSL_LOCAL sw_error_t + horus_port_igmp_mld_join_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_port_igmp_mld_join_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + horus_port_igmp_mld_leave_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_port_igmp_mld_leave_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + horus_igmp_mld_rp_set(a_uint32_t dev_id, fal_pbmp_t pts); + + + HSL_LOCAL sw_error_t + horus_igmp_mld_rp_get(a_uint32_t dev_id, fal_pbmp_t * pts); + + + HSL_LOCAL sw_error_t + horus_igmp_mld_entry_creat_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_igmp_mld_entry_creat_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + horus_igmp_mld_entry_static_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_igmp_mld_entry_static_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + horus_igmp_mld_entry_leaky_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_igmp_mld_entry_leaky_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + horus_igmp_mld_entry_v3_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_igmp_mld_entry_v3_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + horus_igmp_mld_entry_queue_set(a_uint32_t dev_id, a_bool_t enable, a_uint32_t queue); + + + HSL_LOCAL sw_error_t + horus_igmp_mld_entry_queue_get(a_uint32_t dev_id, a_bool_t * enable, a_uint32_t * queue); + + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _HORUS_IGMP_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_init.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_init.h new file mode 100755 index 000000000..388876480 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_init.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 horus_init HORUS_INIT + * @{ + */ +#ifndef _HORUS_INIT_H_ +#define _HORUS_INIT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "init/ssdk_init.h" + + + sw_error_t + horus_init(a_uint32_t dev_id, ssdk_init_cfg *cfg); + + + sw_error_t + horus_reset(a_uint32_t dev_id); + + + sw_error_t + horus_cleanup(a_uint32_t dev_id); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _HORUS_INIT_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_leaky.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_leaky.h new file mode 100755 index 000000000..eb669995d --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_leaky.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 horus_leaky HORUS_LEAKY + * @{ + */ +#ifndef _HORUS_LEAKY_H_ +#define _HORUS_LEAKY_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_leaky.h" + + sw_error_t horus_leaky_init(a_uint32_t dev_id); + +#ifdef IN_LEAKY +#define HORUS_LEAKY_INIT(rv, dev_id) \ + { \ + rv = horus_leaky_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define HORUS_LEAKY_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + horus_uc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode); + + + HSL_LOCAL sw_error_t + horus_uc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t * ctrl_mode); + + + HSL_LOCAL sw_error_t + horus_mc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode); + + + HSL_LOCAL sw_error_t + horus_mc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t * ctrl_mode); + + + HSL_LOCAL sw_error_t + horus_port_arp_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_port_arp_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + horus_port_uc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_port_uc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + horus_port_mc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_port_mc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _HORUS_LEAKY_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_led.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_led.h new file mode 100755 index 000000000..c7d8a92cf --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_led.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _HORUS_LED_H_ +#define _HORUS_LED_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_led.h" + + sw_error_t + horus_led_init(a_uint32_t dev_id); + +#ifdef IN_LED +#define HORUS_LED_INIT(rv, dev_id) \ + { \ + rv = horus_led_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define HORUS_LED_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + horus_led_ctrl_pattern_set(a_uint32_t dev_id, led_pattern_group_t group, + led_pattern_id_t id, led_ctrl_pattern_t * pattern); + + + HSL_LOCAL sw_error_t + horus_led_ctrl_pattern_get(a_uint32_t dev_id, led_pattern_group_t group, + led_pattern_id_t id, led_ctrl_pattern_t * pattern); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _HORUS_LED_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_mib.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_mib.h new file mode 100755 index 000000000..6f1963e16 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_mib.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 horus_mib HORUS_MIB + * @{ + */ +#ifndef _HORUS_MIB_H_ +#define _HORUS_MIB_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_mib.h" + + sw_error_t + horus_mib_init(a_uint32_t dev_id); + +#ifdef IN_MIB +#define HORUS_MIB_INIT(rv, dev_id) \ + { \ + rv = horus_mib_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define HORUS_MIB_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + horus_get_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info ); + + + HSL_LOCAL sw_error_t + horus_mib_status_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_mib_status_get(a_uint32_t dev_id, a_bool_t * enable); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _HORUS_MIB_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_mirror.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_mirror.h new file mode 100755 index 000000000..ae51f7e21 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_mirror.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 horus_mirror HORUS_MIRROR + * @{ + */ +#ifndef _HORUS_MIRROR_H_ +#define _HORUS_MIRROR_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_mirror.h" + + sw_error_t horus_mirr_init(a_uint32_t dev_id); + +#ifdef IN_MIRROR +#define HORUS_MIRR_INIT(rv, dev_id) \ + { \ + rv = horus_mirr_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define HORUS_MIRR_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + horus_mirr_analysis_port_set(a_uint32_t dev_id, fal_port_t port_id); + + + HSL_LOCAL sw_error_t + horus_mirr_analysis_port_get(a_uint32_t dev_id, fal_port_t * port_id); + + + HSL_LOCAL sw_error_t + horus_mirr_port_in_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_mirr_port_in_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + horus_mirr_port_eg_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_mirr_port_eg_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _HORUS_MIRROR_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_misc.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_misc.h new file mode 100755 index 000000000..557244412 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_misc.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 horus_misc HORUS_MISC + * @{ + */ +#ifndef _HORUS_MISC_H_ +#define _HORUS_MISC_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_misc.h" + + sw_error_t horus_misc_init(a_uint32_t dev_id); + +#ifdef IN_MISC +#define HORUS_MISC_INIT(rv, dev_id) \ + { \ + rv = horus_misc_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define HORUS_MISC_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + horus_arp_status_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_arp_status_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + horus_frame_max_size_set(a_uint32_t dev_id, a_uint32_t size); + + + HSL_LOCAL sw_error_t + horus_frame_max_size_get(a_uint32_t dev_id, a_uint32_t * size); + + + HSL_LOCAL sw_error_t + horus_port_unk_sa_cmd_set(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t cmd); + + + HSL_LOCAL sw_error_t + horus_port_unk_sa_cmd_get(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t * cmd); + + + HSL_LOCAL sw_error_t + horus_port_unk_uc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_port_unk_uc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + horus_port_unk_mc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_port_unk_mc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + horus_port_bc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_port_bc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + horus_cpu_port_status_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_cpu_port_status_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + horus_pppoe_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + + HSL_LOCAL sw_error_t + horus_pppoe_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + + HSL_LOCAL sw_error_t + horus_pppoe_status_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_pppoe_status_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + horus_port_dhcp_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_port_dhcp_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + horus_arp_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + + HSL_LOCAL sw_error_t + horus_arp_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + + HSL_LOCAL sw_error_t + horus_eapol_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + + HSL_LOCAL sw_error_t + horus_eapol_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + HSL_LOCAL sw_error_t + horus_eapol_status_set(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + horus_eapol_status_get(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + horus_ripv1_status_set(a_uint32_t dev_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + horus_ripv1_status_get(a_uint32_t dev_id, a_bool_t * enable); + + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _HORUS_GEN_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_port_ctrl.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_port_ctrl.h new file mode 100755 index 000000000..580f49e61 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_port_ctrl.h @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 horus_port_ctrl HORUS_PORT_CONTROL + * @{ + */ +#ifndef _HORUS_PORT_CTRL_H_ +#define _HORUS_PORT_CTRL_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_port_ctrl.h" + + sw_error_t horus_port_ctrl_init(a_uint32_t dev_id); + +#ifdef IN_PORTCONTROL +#define HORUS_PORT_CTRL_INIT(rv, dev_id) \ + { \ + rv = horus_port_ctrl_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define HORUS_PORT_CTRL_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + horus_port_duplex_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t duplex); + + + HSL_LOCAL sw_error_t + horus_port_duplex_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t * pduplex); + + + HSL_LOCAL sw_error_t + horus_port_speed_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t speed); + + + HSL_LOCAL sw_error_t + horus_port_speed_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t * pspeed); + + + HSL_LOCAL sw_error_t + horus_port_autoneg_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status); + + + HSL_LOCAL sw_error_t + horus_port_autoneg_enable(a_uint32_t dev_id, fal_port_t port_id); + + + HSL_LOCAL sw_error_t + horus_port_autoneg_restart(a_uint32_t dev_id, fal_port_t port_id); + + + HSL_LOCAL sw_error_t + horus_port_autoneg_adv_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t autoadv); + + + HSL_LOCAL sw_error_t + horus_port_autoneg_adv_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * autoadv); + + + HSL_LOCAL sw_error_t + horus_port_hdr_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_port_hdr_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + horus_port_flowctrl_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_port_flowctrl_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + horus_port_flowctrl_forcemode_set(a_uint32_t dev_id, + fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_port_flowctrl_forcemode_get(a_uint32_t dev_id, + fal_port_t port_id, + a_bool_t * enable); + + HSL_LOCAL sw_error_t + horus_port_powersave_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_port_powersave_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable); + + + HSL_LOCAL sw_error_t + horus_port_hibernate_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_port_hibernate_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable); + + + HSL_LOCAL sw_error_t + horus_port_cdt(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t mdi_pair, + fal_cable_status_t *cable_status, a_uint32_t *cable_len); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _HORUS_PORT_CTRL_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_portvlan.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_portvlan.h new file mode 100755 index 000000000..d1237f99c --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_portvlan.h @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 horus_port_vlan HORUS_PORT_VLAN + * @{ + */ +#ifndef _HORUS_PORTVLAN_H_ +#define _HORUS_PORTVLAN_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_portvlan.h" + + sw_error_t horus_portvlan_init(a_uint32_t dev_id); + +#ifdef IN_PORTVLAN +#define HORUS_PORTVLAN_INIT(rv, dev_id) \ + { \ + rv = horus_portvlan_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define HORUS_PORTVLAN_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + horus_port_1qmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t port_1qmode); + + + HSL_LOCAL sw_error_t + horus_port_1qmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t * pport_1qmode); + + + HSL_LOCAL sw_error_t + horus_port_egvlanmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t port_egvlanmode); + + + HSL_LOCAL sw_error_t + horus_port_egvlanmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t * pport_egvlanmode); + + + HSL_LOCAL sw_error_t + horus_portvlan_member_add(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id); + + + HSL_LOCAL sw_error_t + horus_portvlan_member_del(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id); + + + HSL_LOCAL sw_error_t + horus_portvlan_member_update(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t mem_port_map); + + + HSL_LOCAL sw_error_t + horus_portvlan_member_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t * mem_port_map); + + HSL_LOCAL sw_error_t + horus_port_default_vid_set(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t vid); + + HSL_LOCAL sw_error_t + horus_port_default_vid_get(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t *vid); + + HSL_LOCAL sw_error_t + horus_port_force_default_vid_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_port_force_default_vid_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + horus_port_force_portvlan_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_port_force_portvlan_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + horus_nestvlan_tpid_set(a_uint32_t dev_id, a_uint32_t tpid); + + + HSL_LOCAL sw_error_t + horus_nestvlan_tpid_get(a_uint32_t dev_id, a_uint32_t * tpid); + + + HSL_LOCAL sw_error_t + horus_port_invlan_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_invlan_mode_t mode); + + + HSL_LOCAL sw_error_t + horus_port_invlan_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_invlan_mode_t * mode); + + HSL_LOCAL sw_error_t + horus_port_pri_propagation_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_port_pri_propagation_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + HSL_LOCAL sw_error_t + horus_qinq_mode_set(a_uint32_t dev_id, fal_qinq_mode_t mode); + + + HSL_LOCAL sw_error_t + horus_qinq_mode_get(a_uint32_t dev_id, fal_qinq_mode_t * mode); + + + HSL_LOCAL sw_error_t + horus_port_qinq_role_set(a_uint32_t dev_id, fal_port_t port_id, fal_qinq_port_role_t role); + + + HSL_LOCAL sw_error_t + horus_port_qinq_role_get(a_uint32_t dev_id, fal_port_t port_id, fal_qinq_port_role_t * role); + + + + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ATHENA_PORTVLAN_H */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_qos.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_qos.h new file mode 100755 index 000000000..f3cf75d0e --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_qos.h @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 horus_qos HORUS_QOS + * @{ + */ +#ifndef _HORUS_QOS_H_ +#define _HORUS_QOS_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_qos.h" + + sw_error_t horus_qos_init(a_uint32_t dev_id); + +#ifdef IN_QOS +#define HORUS_QOS_INIT(rv, dev_id) \ + { \ + rv = horus_qos_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define HORUS_QOS_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + horus_qos_queue_tx_buf_status_set(a_uint32_t dev_id, + fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_qos_queue_tx_buf_status_get(a_uint32_t dev_id, + fal_port_t port_id, + a_bool_t * enable); + + HSL_LOCAL sw_error_t + horus_qos_port_tx_buf_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_qos_port_tx_buf_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + horus_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); + + + HSL_LOCAL sw_error_t + horus_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); + + + HSL_LOCAL sw_error_t + horus_qos_port_tx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number); + + + HSL_LOCAL sw_error_t + horus_qos_port_tx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number); + + + HSL_LOCAL sw_error_t + horus_qos_port_rx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number); + + + HSL_LOCAL sw_error_t + horus_qos_port_rx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number); + + + HSL_LOCAL sw_error_t + horus_cosmap_up_queue_set(a_uint32_t dev_id, a_uint32_t up, + fal_queue_t queue); + + + HSL_LOCAL sw_error_t + horus_cosmap_up_queue_get(a_uint32_t dev_id, a_uint32_t up, + fal_queue_t * queue); + + + HSL_LOCAL sw_error_t + horus_cosmap_dscp_queue_set(a_uint32_t dev_id, a_uint32_t dscp, + fal_queue_t queue); + + + HSL_LOCAL sw_error_t + horus_cosmap_dscp_queue_get(a_uint32_t dev_id, a_uint32_t dscp, + fal_queue_t * queue); + + + HSL_LOCAL sw_error_t + horus_qos_port_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_qos_port_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + horus_qos_port_mode_pri_set(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_uint32_t pri); + + + HSL_LOCAL sw_error_t + horus_qos_port_mode_pri_get(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_uint32_t * pri); + + + HSL_LOCAL sw_error_t + horus_qos_port_default_up_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t up); + + + HSL_LOCAL sw_error_t + horus_qos_port_default_up_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * up); + + + HSL_LOCAL sw_error_t + horus_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[]); + + + HSL_LOCAL sw_error_t + horus_qos_port_sch_mode_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_sch_mode_t * mode, a_uint32_t weight[]); + + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _HORUS_QOS_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_rate.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_rate.h new file mode 100755 index 000000000..84b04d73f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_rate.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 horus_rate HORUS_RATE + * @{ + */ +#ifndef _HORUS_RATE_H_ +#define _HORUS_RATE_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_rate.h" + + sw_error_t horus_rate_init(a_uint32_t dev_id); + +#ifdef IN_RATE +#define HORUS_RATE_INIT(rv, dev_id) \ + { \ + rv = horus_rate_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define HORUS_RATE_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + horus_rate_port_egrl_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * speed, a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_rate_port_egrl_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * speed, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + horus_rate_port_inrl_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * speed, a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_rate_port_inrl_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * speed, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + horus_storm_ctrl_frame_set(a_uint32_t dev_id, fal_port_t port_id, + fal_storm_type_t storm_type, a_bool_t enable); + + + HSL_LOCAL sw_error_t + horus_storm_ctrl_frame_get(a_uint32_t dev_id, fal_port_t port_id, + fal_storm_type_t storm_type, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + horus_storm_ctrl_rate_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * rate_in_pps); + + + HSL_LOCAL sw_error_t + horus_storm_ctrl_rate_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * rate_in_pps); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _HORUS_RATE_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_reg.h new file mode 100755 index 000000000..891e2c46b --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_reg.h @@ -0,0 +1,2431 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _HORUS_REG_H_ +#define _HORUS_REG_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define MAX_ENTRY_LEN 128 + +#define HSL_RW 1 +#define HSL_RO 0 + + + /* Garuda Mask Control Register */ +#define MASK_CTL "mask" +#define MASK_CTL_ID 0 +#define MASK_CTL_OFFSET 0x0000 +#define MASK_CTL_E_LENGTH 4 +#define MASK_CTL_E_OFFSET 0 +#define MASK_CTL_NR_E 1 + +#define SOFT_RST "mask_rst" +#define MASK_CTL_SOFT_RST_BOFFSET 31 +#define MASK_CTL_SOFT_RST_BLEN 1 +#define MASK_CTL_SOFT_RST_FLAG HSL_RW + +#define MII_CLK5_SEL "mask_clk5s" +#define MASK_CTL_MII_CLK5_SEL_BOFFSET 21 +#define MASK_CTL_MII_CLK5_SEL_BLEN 1 +#define MASK_CTL_MII_CLK5_SEL_FLAG HSL_RW + +#define MII_CLK0_SEL "mask_clk0s" +#define MASK_CTL_MII_CLK0_SEL_BOFFSET 20 +#define MASK_CTL_MII_CLK0_SEL_BLEN 1 +#define MASK_CTL_MII_CLK0_SEL_FLAG HSL_RW + +#define LOAD_EEPROM "mask_ldro" +#define MASK_CTL_LOAD_EEPROM_BOFFSET 16 +#define MASK_CTL_LOAD_EEPROM_BLEN 1 +#define MASK_CTL_LOAD_EEPROM_FLAG HSL_RW + +#define DEVICE_ID "mask_did" +#define MASK_CTL_DEVICE_ID_BOFFSET 8 +#define MASK_CTL_DEVICE_ID_BLEN 8 +#define MASK_CTL_DEVICE_ID_FLAG HSL_RO + +#define REV_ID "mask_rid" +#define MASK_CTL_REV_ID_BOFFSET 0 +#define MASK_CTL_REV_ID_BLEN 8 +#define MASK_CTL_REV_ID_FLAG HSL_RO + + + /* Garuda Mask Control Register */ +#define POSTRIP "postrip" +#define POSTRIP_ID 0 +#define POSTRIP_OFFSET 0x0008 +#define POSTRIP_E_LENGTH 4 +#define POSTRIP_E_OFFSET 0 +#define POSTRIP_NR_E 1 + +#define POWER_ON_SEL "postrip_sel" +#define POSTRIP_POWER_ON_SEL_BOFFSET 31 +#define POSTRIP_POWER_ON_SEL_BLEN 1 +#define POSTRIP_POWER_ON_SEL_FLAG HSL_RW + +#define RXDELAY_S1 "postrip_rx_s1" +#define POSTRIP_RXDELAY_S1_BOFFSET 26 +#define POSTRIP_RXDELAY_S1_BLEN 1 +#define POSTRIP_RXDELAY_S1_FLAG HSL_RW + +#define SPI_EN "postrip_spi" +#define POSTRIP_SPI_EN_BOFFSET 25 +#define POSTRIP_SPI_EN_BLEN 1 +#define POSTRIP_SPI_EN_FLAG HSL_RW + +#define LED_OPEN_EN "postrip_led" +#define POSTRIP_LED_OPEN_EN_BOFFSET 24 +#define POSTRIP_LED_OPEN_EN_BLEN 1 +#define POSTRIP_LED_OPEN_EN_FLAG HSL_RW + +#define RXDELAY_S0 "postrip_rx_s0" +#define POSTRIP_RXDELAY_S0_BOFFSET 23 +#define POSTRIP_RXDELAY_S0_BLEN 1 +#define POSTRIP_RXDELAY_S0_FLAG HSL_RW + +#define TXDELAY_S1 "postrip_tx_s1" +#define POSTRIP_TXDELAY_S1_BOFFSET 22 +#define POSTRIP_TXDELAY_S1_BLEN 1 +#define POSTRIP_TXDELAY_S1_FLAG HSL_RW + +#define TXDELAY_S0 "postrip_tx_s0" +#define POSTRIP_TXDELAY_S0_BOFFSET 21 +#define POSTRIP_TXDELAY_S0_BLEN 1 +#define POSTRIP_TXDELAY_S0_FLAG HSL_RW + +#define LPW_EXIT "postrip_lpw_exit" +#define POSTRIP_LPW_EXIT_BOFFSET 20 +#define POSTRIP_LPW_EXIT_BLEN 1 +#define POSTRIP_LPW_EXIT_FLAG HSL_RW + +#define PHY_PLL_ON "postrip_phy_pll" +#define POSTRIP_PHY_PLL_ON_BOFFSET 19 +#define POSTRIP_PHY_PLL_ON_BLEN 1 +#define POSTRIP_PHY_PLL_ON_FLAG HSL_RW + +#define MAN_ENABLE "postrip_man_en" +#define POSTRIP_MAN_ENABLE_BOFFSET 18 +#define POSTRIP_MAN_ENABLE_BLEN 1 +#define POSTRIP_MAN_ENABLE_FLAG HSL_RW + +#define LPW_STATE_EN "postrip_lpw_state" +#define POSTRIP_LPW_STATE_EN_BOFFSET 17 +#define POSTRIP_LPW_STATE_EN_BLEN 1 +#define POSTRIP_LPW_STATE_EN_FLAG HSL_RW + +#define POWER_DOWN_HW "postrip_power_down" +#define POSTRIP_POWER_DOWN_HW_BOFFSET 16 +#define POSTRIP_POWER_DOWN_HW_BLEN 1 +#define POSTRIP_POWER_DOWN_HW_FLAG HSL_RW + +#define MAC5_PHY_MODE "postrip_mac5_phy" +#define POSTRIP_MAC5_PHY_MODE_BOFFSET 15 +#define POSTRIP_MAC5_PHY_MODE_BLEN 1 +#define POSTRIP_MAC5_PHY_MODE_FLAG HSL_RW + +#define MAC5_MAC_MODE "postrip_mac5_mac" +#define POSTRIP_MAC5_MAC_MODE_BOFFSET 14 +#define POSTRIP_MAC5_MAC_MODE_BLEN 1 +#define POSTRIP_MAC5_MAC_MODE_FLAG HSL_RW + +#define DBG_MODE_I "postrip_dbg" +#define POSTRIP_DBG_MODE_I_BOFFSET 13 +#define POSTRIP_DBG_MODE_I_BLEN 1 +#define POSTRIP_DBG_MODE_I_FLAG HSL_RW + +#define HIB_PULSE_HW "postrip_hib" +#define POSTRIP_HIB_PULSE_HW_BOFFSET 12 +#define POSTRIP_HIB_PULSE_HW_BLEN 1 +#define POSTRIP_HIB_PULSE_HW_FLAG HSL_RW + +#define SEL_CLK25M "postrip_clk25" +#define POSTRIP_SEL_CLK25M_BOFFSET 11 +#define POSTRIP_SEL_CLK25M_BLEN 1 +#define POSTRIP_SEL_CLK25M_FLAG HSL_RW + +#define GATE_25M_EN "postrip_gate25" +#define POSTRIP_GATE_25M_EN_BOFFSET 10 +#define POSTRIP_GATE_25M_EN_BLEN 1 +#define POSTRIP_GATE_25M_EN_FLAG HSL_RW + +#define SEL_ANA_RST "postrip_sel_ana" +#define POSTRIP_SEL_ANA_RST_BOFFSET 9 +#define POSTRIP_SEL_ANA_RST_BLEN 1 +#define POSTRIP_SEL_ANA_RST_FLAG HSL_RW + +#define SERDES_EN "postrip_serdes_en" +#define POSTRIP_SERDES_EN_BOFFSET 8 +#define POSTRIP_SERDES_EN_BLEN 1 +#define POSTRIP_SERDES_EN_FLAG HSL_RW + +#define RGMII_TXCLK_DELAY_EN "postrip_tx_delay" +#define POSTRIP_RGMII_TXCLK_DELAY_EN_BOFFSET 7 +#define POSTRIP_RGMII_TXCLK_DELAY_EN_BLEN 1 +#define POSTRIP_RGMII_TXCLK_DELAY_EN_FLAG HSL_RW + +#define RGMII_RXCLK_DELAY_EN "postrip_rx_delay" +#define POSTRIP_RGMII_RXCLK_DELAY_EN_BOFFSET 6 +#define POSTRIP_RGMII_RXCLK_DELAY_EN_BLEN 1 +#define POSTRIP_RGMII_RXCLK_DELAY_EN_FLAG HSL_RW + +#define RTL_MODE "postrip_rtl" +#define POSTRIP_RTL_MODE_BOFFSET 5 +#define POSTRIP_RTL_MODE_BLEN 1 +#define POSTRIP_RTL_MODE_FLAG HSL_RW + +#define MAC0_MAC_MODE "postrip_mac0_mac" +#define POSTRIP_MAC0_MAC_MODE_BOFFSET 4 +#define POSTRIP_MAC0_MAC_MODE_BLEN 1 +#define POSTRIP_MAC0_MAC_MODE_FLAG HSL_RW + +#define PHY4_RGMII_EN "postrip_phy4_rgmii" +#define POSTRIP_PHY4_RGMII_EN_BOFFSET 3 +#define POSTRIP_PHY4_RGMII_EN_BLEN 1 +#define POSTRIP_PHY4_RGMII_EN_FLAG HSL_RW + +#define PHY4_GMII_EN "postrip_phy4_gmii" +#define POSTRIP_PHY4_GMII_EN_BOFFSET 2 +#define POSTRIP_PHY4_GMII_EN_BLEN 1 +#define POSTRIP_PHY4_GMII_EN_FLAG HSL_RW + +#define MAC0_RGMII_EN "postrip_mac0_rgmii" +#define POSTRIP_MAC0_RGMII_EN_BOFFSET 1 +#define POSTRIP_MAC0_RGMII_EN_BLEN 1 +#define POSTRIP_MAC0_RGMII_EN_FLAG HSL_RW + +#define MAC0_GMII_EN "postrip_mac0_gmii" +#define POSTRIP_MAC0_GMII_EN_BOFFSET 0 +#define POSTRIP_MAC0_GMII_EN_BLEN 1 +#define POSTRIP_MAC0_GMII_EN_FLAG HSL_RW + + + + /* Global Interrupt Register */ +#define GLOBAL_INT "gint" +#define GLOBAL_INT_ID 1 +#define GLOBAL_INT_OFFSET 0x0014 +#define GLOBAL_INT_E_LENGTH 4 +#define GLOBAL_INT_E_OFFSET 0 +#define GLOBAL_INT_NR_E 1 + +#define GLB_QM_ERR_CNT "gint_qmen" +#define GLOBAL_INT_GLB_QM_ERR_CNT_BOFFSET 24 +#define GLOBAL_INT_GLB_QM_ERR_CNT_BLEN 8 +#define GLOBAL_INT_GLB_QM_ERR_CNT_FLAG HSL_RO + +#define GLB_LOOKUP_ERR "gint_glblper" +#define GLOBAL_INT_GLB_LOOKUP_ERR_BOFFSET 17 +#define GLOBAL_INT_GLB_LOOKUP_ERR_BLEN 1 +#define GLOBAL_INT_GLB_LOOKUP_ERR_FLAG HSL_RW + +#define GLB_QM_ERR "gint_glbqmer" +#define GLOBAL_INT_GLB_QM_ERR_BOFFSET 16 +#define GLOBAL_INT_GLB_QM_ERR_BLEN 1 +#define GLOBAL_INT_GLB_QM_ERR_FLAG HSL_RW + +#define GLB_HW_INI_DONE "gint_hwid" +#define GLOBAL_INT_GLB_HW_INI_DONE_BOFFSET 14 +#define GLOBAL_INT_GLB_HW_INI_DONE_BLEN 1 +#define GLOBAL_INT_GLB_HW_INI_DONE_FLAG HSL_RW + +#define GLB_MIB_INI "gint_mibi" +#define GLOBAL_INT_GLB_MIB_INI_BOFFSET 13 +#define GLOBAL_INT_GLB_MIB_INI_BLEN 1 +#define GLOBAL_INT_GLB_MIB_INI_FLAG HSL_RW + +#define GLB_MIB_DONE "gint_mibd" +#define GLOBAL_INT_GLB_MIB_DONE_BOFFSET 12 +#define GLOBAL_INT_GLB_MIB_DONE_BLEN 1 +#define GLOBAL_INT_GLB_MIB_DONE_FLAG HSL_RW + +#define GLB_BIST_DONE "gint_bisd" +#define GLOBAL_INT_GLB_BIST_DONE_BOFFSET 11 +#define GLOBAL_INT_GLB_BIST_DONE_BLEN 1 +#define GLOBAL_INT_GLB_BIST_DONE_FLAG HSL_RW + +#define GLB_VT_MISS_VIO "gint_vtms" +#define GLOBAL_INT_GLB_VT_MISS_VIO_BOFFSET 10 +#define GLOBAL_INT_GLB_VT_MISS_VIO_BLEN 1 +#define GLOBAL_INT_GLB_VT_MISS_VIO_FLAG HSL_RW + +#define GLB_VT_MEM_VIO "gint_vtme" +#define GLOBAL_INT_GLB_VT_MEM_VIO_BOFFSET 9 +#define GLOBAL_INT_GLB_VT_MEM_VIO_BLEN 1 +#define GLOBAL_INT_GLB_VT_MEM_VIO_FLAG HSL_RW + +#define GLB_VT_DONE "gint_vtd" +#define GLOBAL_INT_GLB_VT_DONE_BOFFSET 8 +#define GLOBAL_INT_GLB_VT_DONE_BLEN 1 +#define GLOBAL_INT_GLB_VT_DONE_FLAG HSL_RW + +#define GLB_QM_INI "gint_qmin" +#define GLOBAL_INT_GLB_QM_INI_BOFFSET 7 +#define GLOBAL_INT_GLB_QM_INI_BLEN 1 +#define GLOBAL_INT_GLB_QM_INI_FLAG HSL_RW + +#define GLB_AT_INI "gint_atin" +#define GLOBAL_INT_GLB_AT_INI_BOFFSET 6 +#define GLOBAL_INT_GLB_AT_INI_BLEN 1 +#define GLOBAL_INT_GLB_AT_INI_FLAG HSL_RW + +#define GLB_ARL_FULL "gint_arlf" +#define GLOBAL_INT_GLB_ARL_FULL_BOFFSET 5 +#define GLOBAL_INT_GLB_ARL_FULL_BLEN 1 +#define GLOBAL_INT_GLB_ARL_FULL_FLAG HSL_RW + +#define GLB_ARL_DONE "gint_arld" +#define GLOBAL_INT_GLB_ARL_DONE_BOFFSET 4 +#define GLOBAL_INT_GLB_ARL_DONE_BLEN 1 +#define GLOBAL_INT_GLB_ARL_DONE_FLAG HSL_RW + +#define GLB_MDIO_DONE "gint_mdid" +#define GLOBAL_INT_GLB_MDIO_DONE_BOFFSET 3 +#define GLOBAL_INT_GLB_MDIO_DONE_BLEN 1 +#define GLOBAL_INT_GLB_MDIO_DONE_FLAG HSL_RW + +#define GLB_PHY_INT "gint_phyi" +#define GLOBAL_INT_GLB_PHY_INT_BOFFSET 2 +#define GLOBAL_INT_GLB_PHY_INT_BLEN 1 +#define GLOBAL_INT_GLB_PHY_INT_FLAG HSL_RW + +#define GLB_EEPROM_ERR "gint_epei" +#define GLOBAL_INT_GLB_EEPROM_ERR_BOFFSET 1 +#define GLOBAL_INT_GLB_EEPROM_ERR_BLEN 1 +#define GLOBAL_INT_GLB_EEPROM_ERR_FLAG HSL_RW + +#define GLB_EEPROM_INT "gint_epi" +#define GLOBAL_INT_GLB_EEPROM_INT_BOFFSET 0 +#define GLOBAL_INT_GLB_EEPROM_INT_BLEN 1 +#define GLOBAL_INT_GLB_EEPROM_INT_FLAG HSL_RW + + + /* Global Interrupt Mask Register */ +#define GLOBAL_INT_MASK "gintm" +#define GLOBAL_INT_MASK_ID 2 +#define GLOBAL_INT_MASK_OFFSET 0x0018 +#define GLOBAL_INT_MASK_E_LENGTH 4 +#define GLOBAL_INT_MASK_E_OFFSET 0 +#define GLOBAL_INT_MASK_NR_E 1 + +#define GLBM_LOOKUP_ERR "gintm_lpe" +#define GLOBAL_INT_MASK_GLBM_LOOKUP_ERR_BOFFSET 17 +#define GLOBAL_INT_MASK_GLBM_LOOKUP_ERR_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_LOOKUP_ERR_FLAG HSL_RW + +#define GLBM_QM_ERR "gintm_qme" +#define GLOBAL_INT_MASK_GLBM_QM_ERR_BOFFSET 16 +#define GLOBAL_INT_MASK_GLBM_QM_ERR_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_QM_ERR_FLAG HSL_RW + +#define GLBM_HW_INI_DONE "gintm_hwid" +#define GLOBAL_INT_MASK_GLBM_HW_INI_DONE_BOFFSET 14 +#define GLOBAL_INT_MASK_GLBM_HW_INI_DONE_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_HW_INI_DONE_FLAG HSL_RW + +#define GLBM_MIB_INI "gintm_mibi" +#define GLOBAL_INT_MASK_GLBM_MIB_INI_BOFFSET 13 +#define GLOBAL_INT_MASK_GLBM_MIB_INI_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_MIB_INI_FLAG HSL_RW + +#define GLBM_MIB_DONE "gintm_mibd" +#define GLOBAL_INT_MASK_GLBM_MIB_DONE_BOFFSET 12 +#define GLOBAL_INT_MASK_GLBM_MIB_DONE_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_MIB_DONE_FLAG HSL_RW + +#define GLBM_BIST_DONE "gintm_bisd" +#define GLOBAL_INT_MASK_GLBM_BIST_DONE_BOFFSET 11 +#define GLOBAL_INT_MASK_GLBM_BIST_DONE_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_BIST_DONE_FLAG HSL_RW + +#define GLBM_VT_MISS_VIO "gintm_vtms" +#define GLOBAL_INT_MASK_GLBM_VT_MISS_VIO_BOFFSET 10 +#define GLOBAL_INT_MASK_GLBM_VT_MISS_VIO_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_VT_MISS_VIO_FLAG HSL_RW + +#define GLBM_VT_MEM_VIO "gintm_vtme" +#define GLOBAL_INT_MASK_GLBM_VT_MEM_VIO_BOFFSET 9 +#define GLOBAL_INT_MASK_GLBM_VT_MEM_VIO_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_VT_MEM_VIO_FLAG HSL_RW + +#define GLBM_VT_DONE "gintm_vtd" +#define GLOBAL_INT_MASK_GLBM_VT_DONE_BOFFSET 8 +#define GLOBAL_INT_MASK_GLBM_VT_DONE_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_VT_DONE_FLAG HSL_RW + +#define GLBM_QM_INI "gintm_qmin" +#define GLOBAL_INT_MASK_GLBM_QM_INI_BOFFSET 7 +#define GLOBAL_INT_MASK_GLBM_QM_INI_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_QM_INI_FLAG HSL_RW + +#define GLBM_AT_INI "gintm_atin" +#define GLOBAL_INT_MASK_GLBM_AT_INI_BOFFSET 6 +#define GLOBAL_INT_MASK_GLBM_AT_INI_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_AT_INI_FLAG HSL_RW + +#define GLBM_ARL_FULL "gintm_arlf" +#define GLOBAL_INT_MASK_GLBM_ARL_FULL_BOFFSET 5 +#define GLOBAL_INT_MASK_GLBM_ARL_FULL_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_ARL_FULL_FLAG HSL_RW + +#define GLBM_ARL_DONE "gintm_arld" +#define GLOBAL_INT_MASK_GLBM_ARL_DONE_BOFFSET 4 +#define GLOBAL_INT_MASK_GLBM_ARL_DONE_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_ARL_DONE_FLAG HSL_RW + +#define GLBM_MDIO_DONE "gintm_mdid" +#define GLOBAL_INT_MASK_GLBM_MDIO_DONE_BOFFSET 3 +#define GLOBAL_INT_MASK_GLBM_MDIO_DONE_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_MDIO_DONE_FLAG HSL_RW + +#define GLBM_PHY_INT "gintm_phy" +#define GLOBAL_INT_MASK_GLBM_PHY_INT_BOFFSET 2 +#define GLOBAL_INT_MASK_GLBM_PHY_INT_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_PHY_INT_FLAG HSL_RW + +#define GLBM_EEPROM_ERR "gintm_epe" +#define GLOBAL_INT_MASK_GLBM_EEPROM_ERR_BOFFSET 1 +#define GLOBAL_INT_MASK_GLBM_EEPROM_ERR_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_EEPROM_ERR_FLAG HSL_RW + +#define GLBM_EEPROM_INT "gintm_ep" +#define GLOBAL_INT_MASK_GLBM_EEPROM_INT_BOFFSET 0 +#define GLOBAL_INT_MASK_GLBM_EEPROM_INT_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_EEPROM_INT_FLAG HSL_RW + + + /* Global MAC Address Register */ +#define GLOBAL_MAC_ADDR0 "gmac0" +#define GLOBAL_MAC_ADDR0_ID 3 +#define GLOBAL_MAC_ADDR0_OFFSET 0x0020 +#define GLOBAL_MAC_ADDR0_E_LENGTH 4 +#define GLOBAL_MAC_ADDR0_E_OFFSET 0 +#define GLOBAL_MAC_ADDR0_NR_E 1 + +#define GLB_BYTE4 "gmac_b4" +#define GLOBAL_MAC_ADDR0_GLB_BYTE4_BOFFSET 8 +#define GLOBAL_MAC_ADDR0_GLB_BYTE4_BLEN 8 +#define GLOBAL_MAC_ADDR0_GLB_BYTE4_FLAG HSL_RW + +#define GLB_BYTE5 "gmac_b5" +#define GLOBAL_MAC_ADDR0_GLB_BYTE5_BOFFSET 0 +#define GLOBAL_MAC_ADDR0_GLB_BYTE5_BLEN 8 +#define GLOBAL_MAC_ADDR0_GLB_BYTE5_FLAG HSL_RW + +#define GLOBAL_MAC_ADDR1 "gmac1" +#define GLOBAL_MAC_ADDR1_ID 4 +#define GLOBAL_MAC_ADDR1_OFFSET 0x0024 +#define GLOBAL_MAC_ADDR1_E_LENGTH 4 +#define GLOBAL_MAC_ADDR1_E_OFFSET 0 +#define GLOBAL_MAC_ADDR1_NR_E 1 + +#define GLB_BYTE0 "gmac_b0" +#define GLOBAL_MAC_ADDR1_GLB_BYTE0_BOFFSET 24 +#define GLOBAL_MAC_ADDR1_GLB_BYTE0_BLEN 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE0_FLAG HSL_RW + +#define GLB_BYTE1 "gmac_b1" +#define GLOBAL_MAC_ADDR1_GLB_BYTE1_BOFFSET 16 +#define GLOBAL_MAC_ADDR1_GLB_BYTE1_BLEN 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE1_FLAG HSL_RW + +#define GLB_BYTE2 "gmac_b2" +#define GLOBAL_MAC_ADDR1_GLB_BYTE2_BOFFSET 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE2_BLEN 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE2_FLAG HSL_RW + +#define GLB_BYTE3 "gmac_b3" +#define GLOBAL_MAC_ADDR1_GLB_BYTE3_BOFFSET 0 +#define GLOBAL_MAC_ADDR1_GLB_BYTE3_BLEN 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE3_FLAG HSL_RW + + + /* Flood Mask Register */ +#define FLOOD_MASK "fmask" +#define FLOOD_MASK_ID 5 +#define FLOOD_MASK_OFFSET 0x002c +#define FLOOD_MASK_E_LENGTH 4 +#define FLOOD_MASK_E_OFFSET 0 +#define FLOOD_MASK_NR_E 1 + +#define BC_FLOOD_DP "fmask_bfdp" +#define FLOOD_MASK_BC_FLOOD_DP_BOFFSET 25 +#define FLOOD_MASK_BC_FLOOD_DP_BLEN 6 +#define FLOOD_MASK_BC_FLOOD_DP_FLAG HSL_RW + +#define ARL_UNI_LEAKY "fmask_aulky" +#define FLOOD_MASK_ARL_UNI_LEAKY_BOFFSET 24 +#define FLOOD_MASK_ARL_UNI_LEAKY_BLEN 1 +#define FLOOD_MASK_ARL_UNI_LEAKY_FLAG HSL_RW + +#define ARL_MUL_LEAKY "fmask_amlky" +#define FLOOD_MASK_ARL_MUL_LEAKY_BOFFSET 23 +#define FLOOD_MASK_ARL_MUL_LEAKY_BLEN 1 +#define FLOOD_MASK_ARL_MUL_LEAKY_FLAG HSL_RW + +#define MUL_FLOOD_DP "fmask_mfdp" +#define FLOOD_MASK_MUL_FLOOD_DP_BOFFSET 16 +#define FLOOD_MASK_MUL_FLOOD_DP_BLEN 6 +#define FLOOD_MASK_MUL_FLOOD_DP_FLAG HSL_RW + +#define IGMP_DP "fmask_igmpdp" +#define FLOOD_MASK_IGMP_DP_BOFFSET 8 +#define FLOOD_MASK_IGMP_DP_BLEN 6 +#define FLOOD_MASK_IGMP_DP_FLAG HSL_RW + +#define UNI_FLOOD_DP "fmask_ufdp" +#define FLOOD_MASK_UNI_FLOOD_DP_BOFFSET 0 +#define FLOOD_MASK_UNI_FLOOD_DP_BLEN 6 +#define FLOOD_MASK_UNI_FLOOD_DP_FLAG HSL_RW + + + /* Global Control Register */ +#define GLOBAL_CTL "gctl" +#define GLOBAL_CTL_ID 5 +#define GLOBAL_CTL_OFFSET 0x0030 +#define GLOBAL_CTL_E_LENGTH 4 +#define GLOBAL_CTL_E_OFFSET 0 +#define GLOBAL_CTL_NR_E 1 + +#define RATE_DROP_EN "gctl_rden" +#define GLOBAL_CTL_RATE_DROP_EN_BOFFSET 29 +#define GLOBAL_CTL_RATE_DROP_EN_BLEN 1 +#define GLOBAL_CTL_RATE_DROP_EN_FLAG HSL_RW + +#define QM_PRI_MODE "gctl_qmpm" +#define GLOBAL_CTL_QM_PRI_MODE_BOFFSET 28 +#define GLOBAL_CTL_QM_PRI_MODE_BLEN 1 +#define GLOBAL_CTL_QM_PRI_MODE_FLAG HSL_RW + +#define RATE_CRE_LIMIT "gctl_rcrl" +#define GLOBAL_CTL_RATE_CRE_LIMIT_BOFFSET 26 +#define GLOBAL_CTL_RATE_CRE_LIMIT_BLEN 2 +#define GLOBAL_CTL_RATE_CRE_LIMIT_FLAG HSL_RW + +#define RATE_TIME_SLOT "gctl_rtms" +#define GLOBAL_CTL_RATE_TIME_SLOT_BOFFSET 24 +#define GLOBAL_CTL_RATE_TIME_SLOT_BLEN 2 +#define GLOBAL_CTL_RATE_TIME_SLOT_FLAG HSL_RW + +#define RELOAD_TIMER "gctl_rdtm" +#define GLOBAL_CTL_RELOAD_TIMER_BOFFSET 20 +#define GLOBAL_CTL_RELOAD_TIMER_BLEN 4 +#define GLOBAL_CTL_RELOAD_TIMER_FLAG HSL_RW + +#define QM_CNT_LOCK "gctl_qmcl" +#define GLOBAL_CTL_QM_CNT_LOCK_BOFFSET 19 +#define GLOBAL_CTL_QM_CNT_LOCK_BLEN 1 +#define GLOBAL_CTL_QM_CNT_LOCK_FLAG HSL_RO + +#define BROAD_DROP_EN "gctl_bden" +#define GLOBAL_CTL_BROAD_DROP_EN_BOFFSET 18 +#define GLOBAL_CTL_BROAD_DROP_EN_BLEN 1 +#define GLOBAL_CTL_BROAD_DROP_EN_FLAG HSL_RW + +#define MAX_FRAME_SIZE "gctl_mfsz" +#define GLOBAL_CTL_MAX_FRAME_SIZE_BOFFSET 0 +#define GLOBAL_CTL_MAX_FRAME_SIZE_BLEN 14 +#define GLOBAL_CTL_MAX_FRAME_SIZE_FLAG HSL_RW + + + /* Flow Control Register */ +#define FLOW_CTL0 "fctl" +#define FLOW_CTL0_ID 6 +#define FLOW_CTL0_OFFSET 0x0034 +#define FLOW_CTL0_E_LENGTH 4 +#define FLOW_CTL0_E_OFFSET 0 +#define FLOW_CTL0_NR_E 1 + +#define TEST_PAUSE "fctl_tps" +#define FLOW_CTL0_TEST_PAUSE_BOFFSET 31 +#define FLOW_CTL0_TEST_PAUSE_BLEN 1 +#define FLOW_CTL0_TEST_PAUSE_FLAG HSL_RW + + +#define GOL_PAUSE_ON_THRES "fctl_gont" +#define FLOW_CTL0_GOL_PAUSE_ON_THRES_BOFFSET 16 +#define FLOW_CTL0_GOL_PAUSE_ON_THRES_BLEN 8 +#define FLOW_CTL0_GOL_PAUSE_ON_THRES_FLAG HSL_RW + +#define GOL_PAUSE_OFF_THRES "fctl_gofft" +#define FLOW_CTL0_GOL_PAUSE_OFF_THRES_BOFFSET 0 +#define FLOW_CTL0_GOL_PAUSE_OFF_THRES_BLEN 8 +#define FLOW_CTL0_GOL_PAUSE_OFF_THRES_FLAG HSL_RW + + + + + /* Flow Control1 Register */ +#define FLOW_CTL1 "fctl1" +#define FLOW_CTL1_ID 6 +#define FLOW_CTL1_OFFSET 0x0038 +#define FLOW_CTL1_E_LENGTH 4 +#define FLOW_CTL1_E_OFFSET 0 +#define FLOW_CTL1_NR_E 1 + +#define PORT_PAUSE_ON_THRES "fctl1_pont" +#define FLOW_CTL1_PORT_PAUSE_ON_THRES_BOFFSET 16 +#define FLOW_CTL1_PORT_PAUSE_ON_THRES_BLEN 8 +#define FLOW_CTL1_PORT_PAUSE_ON_THRES_FLAG HSL_RW + +#define PORT_PAUSE_OFF_THRES "fctl1_pofft" +#define FLOW_CTL1_PORT_PAUSE_OFF_THRES_BOFFSET 0 +#define FLOW_CTL1_PORT_PAUSE_OFF_THRES_BLEN 8 +#define FLOW_CTL1_PORT_PAUSE_OFF_THRES_FLAG HSL_RW + + + + + /* QM Control Register */ +#define QM_CTL "qmct" +#define QM_CTL_ID 7 +#define QM_CTL_OFFSET 0x003c +#define QM_CTL_E_LENGTH 4 +#define QM_CTL_E_OFFSET 0 +#define QM_CTL_NR_E 1 + +#define QM_ERR_RST_EN "qmct_qeren" +#define QM_CTL_QM_ERR_RST_EN_BOFFSET 31 +#define QM_CTL_QM_ERR_RST_EN_BLEN 1 +#define QM_CTL_QM_ERR_RST_EN_FLAG HSL_RW + +#define LOOKUP_ERR_RST_EN "qmct_lpesen" +#define QM_CTL_LOOKUP_ERR_RST_EN_BOFFSET 30 +#define QM_CTL_LOOKUP_ERR_RST_EN_BLEN 1 +#define QM_CTL_LOOKUP_ERR_RST_EN_FLAG HSL_RW + +#define IGMP_JOIN_STATIC "qmct_igmpjs" +#define QM_CTL_IGMP_JOIN_STATIC_BOFFSET 24 +#define QM_CTL_IGMP_JOIN_STATIC_BLEN 4 +#define QM_CTL_IGMP_JOIN_STATIC_FLAG HSL_RW + +#define IGMP_JOIN_LEAKY "qmct_igmpjl" +#define QM_CTL_IGMP_JOIN_LEAKY_BOFFSET 23 +#define QM_CTL_IGMP_JOIN_LEAKY_BLEN 1 +#define QM_CTL_IGMP_JOIN_LEAKY_FLAG HSL_RW + +#define IGMP_CREAT_EN "qmct_igmpcrt" +#define QM_CTL_IGMP_CREAT_EN_BOFFSET 22 +#define QM_CTL_IGMP_CREAT_EN_BLEN 1 +#define QM_CTL_IGMP_CREAT_EN_FLAG HSL_RW + +#define PPPOE_RDT_EN "qmct_pppoerdten" +#define QM_CTL_PPPOE_RDT_EN_BOFFSET 20 +#define QM_CTL_PPPOE_RDT_EN_BLEN 1 +#define QM_CTL_PPPOE_RDT_EN_FLAG HSL_RW + +#define IGMP_V3_EN "qmct_igmpv3e" +#define QM_CTL_IGMP_V3_EN_BOFFSET 19 +#define QM_CTL_IGMP_V3_EN_BLEN 1 +#define QM_CTL_IGMP_V3_EN_FLAG HSL_RW + +#define IGMP_PRI_EN "qmct_igmpprie" +#define QM_CTL_IGMP_PRI_EN_BOFFSET 18 +#define QM_CTL_IGMP_PRI_EN_BLEN 1 +#define QM_CTL_IGMP_PRI_EN_FLAG HSL_RW + +#define IGMP_PRI "qmct_igmppri" +#define QM_CTL_IGMP_PRI_BOFFSET 16 +#define QM_CTL_IGMP_PRI_BLEN 2 +#define QM_CTL_IGMP_PRI_FLAG HSL_RW + +#define ARP_EN "qmct_arpe" +#define QM_CTL_ARP_EN_BOFFSET 15 +#define QM_CTL_ARP_EN_BLEN 1 +#define QM_CTL_ARP_EN_FLAG HSL_RW + +#define ARP_CMD "qmct_arpc" +#define QM_CTL_ARP_CMD_BOFFSET 14 +#define QM_CTL_ARP_CMD_BLEN 1 +#define QM_CTL_ARP_CMD_FLAG HSL_RW + +#define RIP_CPY_EN "qmct_ripcpyen" +#define QM_CTL_RIP_CPY_EN_BOFFSET 13 +#define QM_CTL_RIP_CPY_EN_BLEN 1 +#define QM_CTL_RIP_CPY_EN_FLAG HSL_RW + +#define EAPOL_CMD "qmct_eapolc" +#define QM_CTL_EAPOL_CMD_BOFFSET 12 +#define QM_CTL_EAPOL_CMD_BLEN 1 +#define QM_CTL_EAPOL_CMD_FLAG HSL_RW + +#define IGMP_COPY_EN "qmct_igmpcpy" +#define QM_CTL_IGMP_COPY_EN_BOFFSET 11 +#define QM_CTL_IGMP_COPY_EN_BLEN 1 +#define QM_CTL_IGMP_COPY_EN_FLAG HSL_RW + +#define PPPOE_EN "qmct_pppoeen" +#define QM_CTL_PPPOE_EN_BOFFSET 10 +#define QM_CTL_PPPOE_EN_BLEN 1 +#define QM_CTL_PPPOE_EN_FLAG HSL_RW + +#define QM_FUNC_TEST "qmct_qmft" +#define QM_CTL_QM_FUNC_TEST_BOFFSET 9 +#define QM_CTL_QM_FUNC_TEST_BLEN 1 +#define QM_CTL_QM_FUNC_TEST_FLAG HSL_RW + +#define MS_FC_EN "qmct_msfe" +#define QM_CTL_MS_FC_EN_BOFFSET 8 +#define QM_CTL_MS_FC_EN_BLEN 1 +#define QM_CTL_MS_FC_EN_FLAG HSL_RW + +#define FLOW_DROP_EN "qmct_fden" +#define QM_CTL_FLOW_DROP_EN_BOFFSET 7 +#define QM_CTL_FLOW_DROP_EN_BLEN 1 +#define QM_CTL_FLOW_DROP_EN_FLAG HSL_RW + +#define MANAGE_VID_VIO_DROP_EN "qmct_mden" +#define QM_CTL_MANAGE_VID_VIO_DROP_EN_BOFFSET 6 +#define QM_CTL_MANAGE_VID_VIO_DROP_EN_BLEN 1 +#define QM_CTL_MANAGE_VID_VIO_DROP_EN_FLAG HSL_RW + +#define FLOW_DROP_CNT "qmct_fdcn" +#define QM_CTL_FLOW_DROP_CNT_BOFFSET 0 +#define QM_CTL_FLOW_DROP_CNT_BLEN 6 +#define QM_CTL_FLOW_DROP_CNT_FLAG HSL_RW + + + /* Vlan Table Function Register */ +#define VLAN_TABLE_FUNC0 "vtbf0" +#define VLAN_TABLE_FUNC0_ID 9 +#define VLAN_TABLE_FUNC0_OFFSET 0x0040 +#define VLAN_TABLE_FUNC0_E_LENGTH 4 +#define VLAN_TABLE_FUNC0_E_OFFSET 0 +#define VLAN_TABLE_FUNC0_NR_E 1 + +#define VT_PRI_EN "vtbf_vtpen" +#define VLAN_TABLE_FUNC0_VT_PRI_EN_BOFFSET 31 +#define VLAN_TABLE_FUNC0_VT_PRI_EN_BLEN 1 +#define VLAN_TABLE_FUNC0_VT_PRI_EN_FLAG HSL_RW + +#define VT_PRI "vtbf_vtpri" +#define VLAN_TABLE_FUNC0_VT_PRI_BOFFSET 28 +#define VLAN_TABLE_FUNC0_VT_PRI_BLEN 3 +#define VLAN_TABLE_FUNC0_VT_PRI_FLAG HSL_RW + +#define VLAN_ID "vtbf_vid" +#define VLAN_TABLE_FUNC0_VLAN_ID_BOFFSET 16 +#define VLAN_TABLE_FUNC0_VLAN_ID_BLEN 12 +#define VLAN_TABLE_FUNC0_VLAN_ID_FLAG HSL_RW + +#define VT_PORT_NUM "vtbf_vtpn" +#define VLAN_TABLE_FUNC0_VT_PORT_NUM_BOFFSET 8 +#define VLAN_TABLE_FUNC0_VT_PORT_NUM_BLEN 4 +#define VLAN_TABLE_FUNC0_VT_PORT_NUM_FLAG HSL_RW + +#define VT_FULL_VIO "vtbf_vtflv" +#define VLAN_TABLE_FUNC0_VT_FULL_VIO_BOFFSET 4 +#define VLAN_TABLE_FUNC0_VT_FULL_VIO_BLEN 1 +#define VLAN_TABLE_FUNC0_VT_FULL_VIO_FLAG HSL_RW + +#define VT_BUSY "vtbf_vtbs" +#define VLAN_TABLE_FUNC0_VT_BUSY_BOFFSET 3 +#define VLAN_TABLE_FUNC0_VT_BUSY_BLEN 1 +#define VLAN_TABLE_FUNC0_VT_BUSY_FLAG HSL_RW + +#define VT_FUNC "vtbf_vtfc" +#define VLAN_TABLE_FUNC0_VT_FUNC_BOFFSET 0 +#define VLAN_TABLE_FUNC0_VT_FUNC_BLEN 3 +#define VLAN_TABLE_FUNC0_VT_FUNC_FLAG HSL_RW + +#define VLAN_TABLE_FUNC1 "vtbf1" +#define VLAN_TABLE_FUNC1_ID 10 +#define VLAN_TABLE_FUNC1_OFFSET 0x0044 +#define VLAN_TABLE_FUNC1_E_LENGTH 4 +#define VLAN_TABLE_FUNC1_E_OFFSET 0 +#define VLAN_TABLE_FUNC1_NR_E 1 + +#define VT_VALID "vtbf_vtvd" +#define VLAN_TABLE_FUNC1_VT_VALID_BOFFSET 11 +#define VLAN_TABLE_FUNC1_VT_VALID_BLEN 1 +#define VLAN_TABLE_FUNC1_VT_VALID_FLAG HSL_RW + +#define LEARN_DIS "vtbf_ldis" +#define VLAN_TABLE_FUNC1_LEARN_DIS_BOFFSET 10 +#define VLAN_TABLE_FUNC1_LEARN_DIS_BLEN 1 +#define VLAN_TABLE_FUNC1_LEARN_DIS_FLAG HSL_RW + +#define VID_MEM "vtbf_vidm" +#define VLAN_TABLE_FUNC1_VID_MEM_BOFFSET 0 +#define VLAN_TABLE_FUNC1_VID_MEM_BLEN 6 +#define VLAN_TABLE_FUNC1_VID_MEM_FLAG HSL_RW + + + /* Address Table Function Register */ +#define ADDR_TABLE_FUNC0 "atbf0" +#define ADDR_TABLE_FUNC0_ID 11 +#define ADDR_TABLE_FUNC0_OFFSET 0x0050 +#define ADDR_TABLE_FUNC0_E_LENGTH 4 +#define ADDR_TABLE_FUNC0_E_OFFSET 0 +#define ADDR_TABLE_FUNC0_NR_E 1 + +#define AT_ADDR_BYTE4 "atbf_adb4" +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE4_BOFFSET 24 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE4_BLEN 8 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE4_FLAG HSL_RW + +#define AT_ADDR_BYTE5 "atbf_adb5" +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE5_BOFFSET 16 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE5_BLEN 8 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE5_FLAG HSL_RW + +#define AT_FULL_VIO "atbf_atfv" +#define ADDR_TABLE_FUNC0_AT_FULL_VIO_BOFFSET 12 +#define ADDR_TABLE_FUNC0_AT_FULL_VIO_BLEN 1 +#define ADDR_TABLE_FUNC0_AT_FULL_VIO_FLAG HSL_RW + +#define AT_PORT_NUM "atbf_atpn" +#define ADDR_TABLE_FUNC0_AT_PORT_NUM_BOFFSET 8 +#define ADDR_TABLE_FUNC0_AT_PORT_NUM_BLEN 4 +#define ADDR_TABLE_FUNC0_AT_PORT_NUM_FLAG HSL_RW + +#define FLUSH_ST_EN "atbf_fsen" +#define ADDR_TABLE_FUNC0_FLUSH_ST_EN_BOFFSET 4 +#define ADDR_TABLE_FUNC0_FLUSH_ST_EN_BLEN 1 +#define ADDR_TABLE_FUNC0_FLUSH_ST_EN_FLAG HSL_RW + +#define AT_BUSY "atbf_atbs" +#define ADDR_TABLE_FUNC0_AT_BUSY_BOFFSET 3 +#define ADDR_TABLE_FUNC0_AT_BUSY_BLEN 1 +#define ADDR_TABLE_FUNC0_AT_BUSY_FLAG HSL_RW + +#define AT_FUNC "atbf_atfc" +#define ADDR_TABLE_FUNC0_AT_FUNC_BOFFSET 0 +#define ADDR_TABLE_FUNC0_AT_FUNC_BLEN 3 +#define ADDR_TABLE_FUNC0_AT_FUNC_FLAG HSL_RW + +#define ADDR_TABLE_FUNC1 "atbf1" +#define ADDR_TABLE_FUNC1_ID 12 +#define ADDR_TABLE_FUNC1_OFFSET 0x0054 +#define ADDR_TABLE_FUNC1_E_LENGTH 4 +#define ADDR_TABLE_FUNC1_E_OFFSET 0 +#define ADDR_TABLE_FUNC1_NR_E 0 + +#define AT_ADDR_BYTE0 "atbf_adb0" +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE0_BOFFSET 24 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE0_BLEN 8 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE0_FLAG HSL_RW + +#define AT_ADDR_BYTE1 "atbf_adb1" +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE1_BOFFSET 16 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE1_BLEN 8 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE1_FLAG HSL_RW + +#define AT_ADDR_BYTE2 "atbf_adb2" +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE2_BOFFSET 8 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE2_BLEN 8 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE2_FLAG HSL_RW + +#define AT_ADDR_BYTE3 "atbf_adb3" +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE3_BOFFSET 0 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE3_BLEN 8 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE3_FLAG HSL_RW + +#define ADDR_TABLE_FUNC2 "atbf2" +#define ADDR_TABLE_FUNC2_ID 13 +#define ADDR_TABLE_FUNC2_OFFSET 0x0058 +#define ADDR_TABLE_FUNC2_E_LENGTH 4 +#define ADDR_TABLE_FUNC2_E_OFFSET 0 +#define ADDR_TABLE_FUNC2_NR_E 0 + +#define COPY_TO_CPU "atbf_cpcpu" +#define ADDR_TABLE_FUNC2_COPY_TO_CPU_BOFFSET 26 +#define ADDR_TABLE_FUNC2_COPY_TO_CPU_BLEN 1 +#define ADDR_TABLE_FUNC2_COPY_TO_CPU_FLAG HSL_RW + +#define REDRCT_TO_CPU "atbf_rdcpu" +#define ADDR_TABLE_FUNC2_REDRCT_TO_CPU_BOFFSET 25 +#define ADDR_TABLE_FUNC2_REDRCT_TO_CPU_BLEN 1 +#define ADDR_TABLE_FUNC2_REDRCT_TO_CPU_FLAG HSL_RW + +#define LEAKY_EN "atbf_lkyen" +#define ADDR_TABLE_FUNC2_LEAKY_EN_BOFFSET 24 +#define ADDR_TABLE_FUNC2_LEAKY_EN_BLEN 1 +#define ADDR_TABLE_FUNC2_LEAKY_EN_FLAG HSL_RW + +#define AT_STATUS "atbf_atsts" +#define ADDR_TABLE_FUNC2_AT_STATUS_BOFFSET 16 +#define ADDR_TABLE_FUNC2_AT_STATUS_BLEN 4 +#define ADDR_TABLE_FUNC2_AT_STATUS_FLAG HSL_RW + +#define CLONE_EN "atbf_clone" +#define ADDR_TABLE_FUNC2_CLONE_EN_BOFFSET 15 +#define ADDR_TABLE_FUNC2_CLONE_EN_BLEN 1 +#define ADDR_TABLE_FUNC2_CLONE_EN_FLAG HSL_RW + +#define SA_DROP_EN "atbf_saden" +#define ADDR_TABLE_FUNC2_SA_DROP_EN_BOFFSET 14 +#define ADDR_TABLE_FUNC2_SA_DROP_EN_BLEN 1 +#define ADDR_TABLE_FUNC2_SA_DROP_EN_FLAG HSL_RW + +#define MIRROR_EN "atbf_miren" +#define ADDR_TABLE_FUNC2_MIRROR_EN_BOFFSET 13 +#define ADDR_TABLE_FUNC2_MIRROR_EN_BLEN 1 +#define ADDR_TABLE_FUNC2_MIRROR_EN_FLAG HSL_RW + +#define AT_PRI_EN "atbf_atpen" +#define ADDR_TABLE_FUNC2_AT_PRI_EN_BOFFSET 12 +#define ADDR_TABLE_FUNC2_AT_PRI_EN_BLEN 1 +#define ADDR_TABLE_FUNC2_AT_PRI_EN_FLAG HSL_RW + +#define AT_PRI "atbf_atpri" +#define ADDR_TABLE_FUNC2_AT_PRI_BOFFSET 10 +#define ADDR_TABLE_FUNC2_AT_PRI_BLEN 2 +#define ADDR_TABLE_FUNC2_AT_PRI_FLAG HSL_RW + +#define CROSS_PT "atbf_cpt" +#define ADDR_TABLE_FUNC2_CROSS_PT_BOFFSET 8 +#define ADDR_TABLE_FUNC2_CROSS_PT_BLEN 1 +#define ADDR_TABLE_FUNC2_CROSS_PT_FLAG HSL_RW + +#define DES_PORT "atbf_desp" +#define ADDR_TABLE_FUNC2_DES_PORT_BOFFSET 0 +#define ADDR_TABLE_FUNC2_DES_PORT_BLEN 6 +#define ADDR_TABLE_FUNC2_DES_PORT_FLAG HSL_RW + + + /* Address Table Control Register */ +#define ADDR_TABLE_CTL "atbc" +#define ADDR_TABLE_CTL_ID 14 +#define ADDR_TABLE_CTL_OFFSET 0x005C +#define ADDR_TABLE_CTL_E_LENGTH 4 +#define ADDR_TABLE_CTL_E_OFFSET 0 +#define ADDR_TABLE_CTL_NR_E 1 + +#define LOOP_CH_TIME "atbc_lct" +#define ADDR_TABLE_CTL_LOOP_CH_TIME_BOFFSET 24 +#define ADDR_TABLE_CTL_LOOP_CH_TIMEP_BLEN 3 +#define ADDR_TABLE_CTL_LOOP_CH_TIME_FLAG HSL_RW + +#define RESVID_DROP "atbc_rviddrop" +#define ADDR_TABLE_CTL_RESVID_DROP_BOFFSET 22 +#define ADDR_TABLE_CTL_RESVID_DROP_BLEN 1 +#define ADDR_TABLE_CTL_RESVID_DROP_FLAG HSL_RW + +#define STAG_MODE "atbc_stag" +#define ADDR_TABLE_CTL_STAG_MODE_BOFFSET 21 +#define ADDR_TABLE_CTL_STAG_MODE_BLEN 1 +#define ADDR_TABLE_CTL_STAG_MODE_FLAG HSL_RW + +#define ARL_INI_EN "atbc_arlie" +#define ADDR_TABLE_CTL_ARL_INI_EN_BOFFSET 19 +#define ADDR_TABLE_CTL_ARL_INI_EN_BLEN 1 +#define ADDR_TABLE_CTL_ARL_INI_EN_FLAG HSL_RW + +#define LEARN_CHANGE_EN "atbc_lcen" +#define ADDR_TABLE_CTL_LEARN_CHANGE_EN_BOFFSET 18 +#define ADDR_TABLE_CTL_LEARN_CHANGE_EN_BLEN 1 +#define ADDR_TABLE_CTL_LEARN_CHANGE_EN_FLAG HSL_RW + +#define AGE_EN "atbc_agee" +#define ADDR_TABLE_CTL_AGE_EN_BOFFSET 17 +#define ADDR_TABLE_CTL_AGE_EN_BLEN 1 +#define ADDR_TABLE_CTL_AGE_EN_FLAG HSL_RW + +#define AGE_TIME "atbc_aget" +#define ADDR_TABLE_CTL_AGE_TIME_BOFFSET 0 +#define ADDR_TABLE_CTL_AGE_TIME_BLEN 16 +#define ADDR_TABLE_CTL_AGE_TIME_FLAG HSL_RW + + + /* IP Priority Mapping Register */ +#define IP_PRI_MAPPING "imap" +#define IP_PRI_MAPPING_ID 15 +#define IP_PRI_MAPPING_OFFSET 0x0060 +#define IP_PRI_MAPPING_E_LENGTH 4 +#define IP_PRI_MAPPING_E_OFFSET 0 +#define IP_PRI_MAPPING_NR_E 1 + + + /* IP Priority Mapping Register */ +#define IP_PRI_MAPPING0 "imap0" +#define IP_PRI_MAPPING0_ID 15 +#define IP_PRI_MAPPING0_OFFSET 0x0060 +#define IP_PRI_MAPPING0_E_LENGTH 4 +#define IP_PRI_MAPPING0_E_OFFSET 0 +#define IP_PRI_MAPPING0_NR_E 0 + +#define IP_0X3C "imap_ip3c" +#define IP_PRI_MAPPING0_IP_0X3C_BOFFSET 30 +#define IP_PRI_MAPPING0_IP_0X3C_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X3C_FLAG HSL_RW + +#define IP_0X38 "imap_ip38" +#define IP_PRI_MAPPING0_IP_0X38_BOFFSET 28 +#define IP_PRI_MAPPING0_IP_0X38_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X38_FLAG HSL_RW + +#define IP_0X34 "imap_ip34" +#define IP_PRI_MAPPING0_IP_0X34_BOFFSET 26 +#define IP_PRI_MAPPING0_IP_0X34_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X34_FLAG HSL_RW + +#define IP_0X30 "imap_ip30" +#define IP_PRI_MAPPING0_IP_0X30_BOFFSET 24 +#define IP_PRI_MAPPING0_IP_0X30_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X30_FLAG HSL_RW + +#define IP_0X2C "imap_ip2c" +#define IP_PRI_MAPPING0_IP_0X2C_BOFFSET 22 +#define IP_PRI_MAPPING0_IP_0X2C_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X2C_FLAG HSL_RW + +#define IP_0X28 "imap_ip28" +#define IP_PRI_MAPPING0_IP_0X28_BOFFSET 20 +#define IP_PRI_MAPPING0_IP_0X28_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X28_FLAG HSL_RW + +#define IP_0X24 "imap_ip24" +#define IP_PRI_MAPPING0_IP_0X24_BOFFSET 18 +#define IP_PRI_MAPPING0_IP_0X24_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X24_FLAG HSL_RW + +#define IP_0X20 "imap_ip20" +#define IP_PRI_MAPPING0_IP_0X20_BOFFSET 16 +#define IP_PRI_MAPPING0_IP_0X20_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X20_FLAG HSL_RW + +#define IP_0X1C "imap_ip1c" +#define IP_PRI_MAPPING0_IP_0X1C_BOFFSET 14 +#define IP_PRI_MAPPING0_IP_0X1C_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X1C_FLAG HSL_RW + +#define IP_0X18 "imap_ip18" +#define IP_PRI_MAPPING0_IP_0X18_BOFFSET 12 +#define IP_PRI_MAPPING0_IP_0X18_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X18_FLAG HSL_RW + +#define IP_0X14 "imap_ip14" +#define IP_PRI_MAPPING0_IP_0X14_BOFFSET 10 +#define IP_PRI_MAPPING0_IP_0X14_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X14_FLAG HSL_RW + +#define IP_0X10 "imap_ip10" +#define IP_PRI_MAPPING0_IP_0X10_BOFFSET 8 +#define IP_PRI_MAPPING0_IP_0X10_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X10_FLAG HSL_RW + +#define IP_0X0C "imap_ip0c" +#define IP_PRI_MAPPING0_IP_0X0C_BOFFSET 6 +#define IP_PRI_MAPPING0_IP_0X0C_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X0C_FLAG HSL_RW + +#define IP_0X08 "imap_ip08" +#define IP_PRI_MAPPING0_IP_0X08_BOFFSET 4 +#define IP_PRI_MAPPING0_IP_0X08_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X08_FLAG HSL_RW + +#define IP_0X04 "imap_ip04" +#define IP_PRI_MAPPING0_IP_0X04_BOFFSET 2 +#define IP_PRI_MAPPING0_IP_0X04_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X04_FLAG HSL_RW + +#define IP_0X00 "imap_ip00" +#define IP_PRI_MAPPING0_IP_0X00_BOFFSET 0 +#define IP_PRI_MAPPING0_IP_0X00_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X00_FLAG HSL_RW + +#define IP_PRI_MAPPING1 "imap1" +#define IP_PRI_MAPPING1_ID 16 +#define IP_PRI_MAPPING1_OFFSET 0x0064 +#define IP_PRI_MAPPING1_E_LENGTH 4 +#define IP_PRI_MAPPING1_E_OFFSET 0 +#define IP_PRI_MAPPING1_NR_E 0 + +#define IP_0X7C "imap_ip7c" +#define IP_PRI_MAPPING1_IP_0X7C_BOFFSET 30 +#define IP_PRI_MAPPING1_IP_0X7C_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X7C_FLAG HSL_RW + +#define IP_0X78 "imap_ip78" +#define IP_PRI_MAPPING1_IP_0X78_BOFFSET 28 +#define IP_PRI_MAPPING1_IP_0X78_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X78_FLAG HSL_RW + +#define IP_0X74 "imap_ip74" +#define IP_PRI_MAPPING1_IP_0X74_BOFFSET 26 +#define IP_PRI_MAPPING1_IP_0X74_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X74_FLAG HSL_RW + +#define IP_0X70 "imap_ip70" +#define IP_PRI_MAPPING1_IP_0X70_BOFFSET 24 +#define IP_PRI_MAPPING1_IP_0X70_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X70_FLAG HSL_RW + +#define IP_0X6C "imap_ip6c" +#define IP_PRI_MAPPING1_IP_0X6C_BOFFSET 22 +#define IP_PRI_MAPPING1_IP_0X6C_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X6C_FLAG HSL_RW + +#define IP_0X68 "imap_ip68" +#define IP_PRI_MAPPING1_IP_0X68_BOFFSET 20 +#define IP_PRI_MAPPING1_IP_0X68_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X68_FLAG HSL_RW + +#define IP_0X64 "imap_ip64" +#define IP_PRI_MAPPING1_IP_0X64_BOFFSET 18 +#define IP_PRI_MAPPING1_IP_0X64_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X64_FLAG HSL_RW + +#define IP_0X60 "imap_ip60" +#define IP_PRI_MAPPING1_IP_0X60_BOFFSET 16 +#define IP_PRI_MAPPING1_IP_0X60_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X60_FLAG HSL_RW + +#define IP_0X5C "imap_ip5c" +#define IP_PRI_MAPPING1_IP_0X5C_BOFFSET 14 +#define IP_PRI_MAPPING1_IP_0X5C_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X5C_FLAG HSL_RW + +#define IP_0X58 "imap_ip58" +#define IP_PRI_MAPPING1_IP_0X58_BOFFSET 12 +#define IP_PRI_MAPPING1_IP_0X58_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X58_FLAG HSL_RW + +#define IP_0X54 "imap_ip54" +#define IP_PRI_MAPPING1_IP_0X54_BOFFSET 10 +#define IP_PRI_MAPPING1_IP_0X54_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X54_FLAG HSL_RW + +#define IP_0X50 "imap_ip50" +#define IP_PRI_MAPPING1_IP_0X50_BOFFSET 8 +#define IP_PRI_MAPPING1_IP_0X50_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X50_FLAG HSL_RW + +#define IP_0X4C "imap_ip4c" +#define IP_PRI_MAPPING1_IP_0X4C_BOFFSET 6 +#define IP_PRI_MAPPING1_IP_0X4C_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X4C_FLAG HSL_RW + +#define IP_0X48 "imap_ip48" +#define IP_PRI_MAPPING1_IP_0X48_BOFFSET 4 +#define IP_PRI_MAPPING1_IP_0X48_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X48_FLAG HSL_RW + +#define IP_0X44 "imap_ip44" +#define IP_PRI_MAPPING1_IP_0X44_BOFFSET 2 +#define IP_PRI_MAPPING1_IP_0X44_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X44_FLAG HSL_RW + +#define IP_0X40 "imap_ip40" +#define IP_PRI_MAPPING1_IP_0X40_BOFFSET 0 +#define IP_PRI_MAPPING1_IP_0X40_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X40_FLAG HSL_RW + + +#define IP_PRI_MAPPING2 "imap2" +#define IP_PRI_MAPPING2_ID 17 +#define IP_PRI_MAPPING2_OFFSET 0x0068 +#define IP_PRI_MAPPING2_E_LENGTH 4 +#define IP_PRI_MAPPING2_E_OFFSET 0 +#define IP_PRI_MAPPING2_NR_E 0 + +#define IP_0XBC "imap_ipbc" +#define IP_PRI_MAPPING2_IP_0XBC_BOFFSET 30 +#define IP_PRI_MAPPING2_IP_0XBC_BLEN 2 +#define IP_PRI_MAPPING2_IP_0XBC_FLAG HSL_RW + +#define IP_0XB8 "imap_ipb8" +#define IP_PRI_MAPPING2_IP_0XB8_BOFFSET 28 +#define IP_PRI_MAPPING2_IP_0XB8_BLEN 2 +#define IP_PRI_MAPPING2_IP_0XB8_FLAG HSL_RW + +#define IP_0XB4 "imap_ipb4" +#define IP_PRI_MAPPING2_IP_0XB4_BOFFSET 26 +#define IP_PRI_MAPPING2_IP_0XB4_BLEN 2 +#define IP_PRI_MAPPING2_IP_0XB4_FLAG HSL_RW + +#define IP_0XB0 "imap_ipb0" +#define IP_PRI_MAPPING2_IP_0XB0_BOFFSET 24 +#define IP_PRI_MAPPING2_IP_0XB0_BLEN 2 +#define IP_PRI_MAPPING2_IP_0XB0_FLAG HSL_RW + +#define IP_0XAC "imap_ipac" +#define IP_PRI_MAPPING2_IP_0XAC_BOFFSET 22 +#define IP_PRI_MAPPING2_IP_0XAC_BLEN 2 +#define IP_PRI_MAPPING2_IP_0XAC_FLAG HSL_RW + +#define IP_0XA8 "imap_ipa8" +#define IP_PRI_MAPPING2_IP_0XA8_BOFFSET 20 +#define IP_PRI_MAPPING2_IP_0XA8_BLEN 2 +#define IP_PRI_MAPPING2_IP_0XA8_FLAG HSL_RW + +#define IP_0XA4 "imap_ipa4" +#define IP_PRI_MAPPING2_IP_0XA4_BOFFSET 18 +#define IP_PRI_MAPPING2_IP_0XA4_BLEN 2 +#define IP_PRI_MAPPING2_IP_0XA4_FLAG HSL_RW + +#define IP_0XA0 "imap_ipa0" +#define IP_PRI_MAPPING2_IP_0XA0_BOFFSET 16 +#define IP_PRI_MAPPING2_IP_0XA0_BLEN 2 +#define IP_PRI_MAPPING2_IP_0XA0_FLAG HSL_RW + +#define IP_0X9C "imap_ip9c" +#define IP_PRI_MAPPING2_IP_0X9C_BOFFSET 14 +#define IP_PRI_MAPPING2_IP_0X9C_BLEN 2 +#define IP_PRI_MAPPING2_IP_0X9C_FLAG HSL_RW + +#define IP_0X98 "imap_ip98" +#define IP_PRI_MAPPING2_IP_0X98_BOFFSET 12 +#define IP_PRI_MAPPING2_IP_0X98_BLEN 2 +#define IP_PRI_MAPPING2_IP_0X98_FLAG HSL_RW + +#define IP_0X94 "imap_ip94" +#define IP_PRI_MAPPING2_IP_0X94_BOFFSET 10 +#define IP_PRI_MAPPING2_IP_0X94_BLEN 2 +#define IP_PRI_MAPPING2_IP_0X94_FLAG HSL_RW + +#define IP_0X90 "imap_ip90" +#define IP_PRI_MAPPING2_IP_0X90_BOFFSET 8 +#define IP_PRI_MAPPING2_IP_0X90_BLEN 2 +#define IP_PRI_MAPPING2_IP_0X90_FLAG HSL_RW + +#define IP_0X8C "imap_ip8c" +#define IP_PRI_MAPPING2_IP_0X8C_BOFFSET 6 +#define IP_PRI_MAPPING2_IP_0X8C_BLEN 2 +#define IP_PRI_MAPPING2_IP_0X8C_FLAG HSL_RW + +#define IP_0X88 "imap_ip88" +#define IP_PRI_MAPPING2_IP_0X88_BOFFSET 4 +#define IP_PRI_MAPPING2_IP_0X88_BLEN 2 +#define IP_PRI_MAPPING2_IP_0X88_FLAG HSL_RW + +#define IP_0X84 "imap_ip84" +#define IP_PRI_MAPPING2_IP_0X84_BOFFSET 2 +#define IP_PRI_MAPPING2_IP_0X84_BLEN 2 +#define IP_PRI_MAPPING2_IP_0X84_FLAG HSL_RW + +#define IP_0X80 "imap_ip80" +#define IP_PRI_MAPPING2_IP_0X80_BOFFSET 0 +#define IP_PRI_MAPPING2_IP_0X80_BLEN 2 +#define IP_PRI_MAPPING2_IP_0X80_FLAG HSL_RW + +#define IP_PRI_MAPPING3 "imap3" +#define IP_PRI_MAPPING3_ID 18 +#define IP_PRI_MAPPING3_OFFSET 0x006C +#define IP_PRI_MAPPING3_E_LENGTH 4 +#define IP_PRI_MAPPING3_E_OFFSET 0 +#define IP_PRI_MAPPING3_NR_E 0 + +#define IP_0XFC "imap_ipfc" +#define IP_PRI_MAPPING3_IP_0XFC_BOFFSET 30 +#define IP_PRI_MAPPING3_IP_0XFC_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XFC_FLAG HSL_RW + +#define IP_0XF8 "imap_ipf8" +#define IP_PRI_MAPPING3_IP_0XF8_BOFFSET 28 +#define IP_PRI_MAPPING3_IP_0XF8_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XF8_FLAG HSL_RW + +#define IP_0XF4 "imap_ipf4" +#define IP_PRI_MAPPING3_IP_0XF4_BOFFSET 26 +#define IP_PRI_MAPPING3_IP_0XF4_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XF4_FLAG HSL_RW + +#define IP_0XF0 "imap_ipf0" +#define IP_PRI_MAPPING3_IP_0XF0_BOFFSET 24 +#define IP_PRI_MAPPING3_IP_0XF0_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XF0_FLAG HSL_RW + +#define IP_0XEC "imap_ipec" +#define IP_PRI_MAPPING3_IP_0XEC_BOFFSET 22 +#define IP_PRI_MAPPING3_IP_0XEC_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XEC_FLAG HSL_RW + +#define IP_0XE8 "imap_ipe8" +#define IP_PRI_MAPPING3_IP_0XE8_BOFFSET 20 +#define IP_PRI_MAPPING3_IP_0XE8_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XE8_FLAG HSL_RW + +#define IP_0XE4 "imap_ipe4" +#define IP_PRI_MAPPING3_IP_0XE4_BOFFSET 18 +#define IP_PRI_MAPPING3_IP_0XE4_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XE4_FLAG HSL_RW + +#define IP_0XE0 "imap_ipe0" +#define IP_PRI_MAPPING3_IP_0XE0_BOFFSET 16 +#define IP_PRI_MAPPING3_IP_0XE0_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XE0_FLAG HSL_RW + +#define IP_0XDC "imap_ipdc" +#define IP_PRI_MAPPING3_IP_0XDC_BOFFSET 14 +#define IP_PRI_MAPPING3_IP_0XDC_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XDC_FLAG HSL_RW + +#define IP_0XD8 "imap_ipd8" +#define IP_PRI_MAPPING3_IP_0XD8_BOFFSET 12 +#define IP_PRI_MAPPING3_IP_0XD8_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XD8_FLAG HSL_RW + +#define IP_0XD4 "imap_ipd4" +#define IP_PRI_MAPPING3_IP_0XD4_BOFFSET 10 +#define IP_PRI_MAPPING3_IP_0XD4_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XD4_FLAG HSL_RW + +#define IP_0XD0 "imap_ipd0" +#define IP_PRI_MAPPING3_IP_0XD0_BOFFSET 8 +#define IP_PRI_MAPPING3_IP_0XD0_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XD0_FLAG HSL_RW + +#define IP_0XCC "imap_ipcc" +#define IP_PRI_MAPPING3_IP_0XCC_BOFFSET 6 +#define IP_PRI_MAPPING3_IP_0XCC_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XCC_FLAG HSL_RW + +#define IP_0XC8 "imap_ipc8" +#define IP_PRI_MAPPING3_IP_0XC8_BOFFSET 4 +#define IP_PRI_MAPPING3_IP_0XC8_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XC8_FLAG HSL_RW + +#define IP_0XC4 "imap_ipc4" +#define IP_PRI_MAPPING3_IP_0XC4_BOFFSET 2 +#define IP_PRI_MAPPING3_IP_0XC4_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XC4_FLAG HSL_RW + +#define IP_0XC0 "imap_ipc0" +#define IP_PRI_MAPPING3_IP_0XC0_BOFFSET 0 +#define IP_PRI_MAPPING3_IP_0XC0_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XC0_FLAG HSL_RW + + + /* Tag Priority Mapping Register */ +#define TAG_PRI_MAPPING "tpmap" +#define TAG_PRI_MAPPING_ID 19 +#define TAG_PRI_MAPPING_OFFSET 0x0070 +#define TAG_PRI_MAPPING_E_LENGTH 4 +#define TAG_PRI_MAPPING_E_OFFSET 0 +#define TAG_PRI_MAPPING_NR_E 1 + +#define TAG_0X07 "tpmap_tg07" +#define TAG_PRI_MAPPING_TAG_0X07_BOFFSET 14 +#define TAG_PRI_MAPPING_TAG_0X07_BLEN 2 +#define TAG_PRI_MAPPING_TAG_0X07_FLAG HSL_RW + +#define TAG_0X06 "tpmap_tg06" +#define TAG_PRI_MAPPING_TAG_0X06_BOFFSET 12 +#define TAG_PRI_MAPPING_TAG_0X06_BLEN 2 +#define TAG_PRI_MAPPING_TAG_0X06_FLAG HSL_RW + +#define TAG_0X05 "tpmap_tg05" +#define TAG_PRI_MAPPING_TAG_0X05_BOFFSET 10 +#define TAG_PRI_MAPPING_TAG_0X05_BLEN 2 +#define TAG_PRI_MAPPING_TAG_0X05_FLAG HSL_RW + +#define TAG_0X04 "tpmap_tg04" +#define TAG_PRI_MAPPING_TAG_0X04_BOFFSET 8 +#define TAG_PRI_MAPPING_TAG_0X04_BLEN 2 +#define TAG_PRI_MAPPING_TAG_0X04_FLAG HSL_RW + +#define TAG_0X03 "tpmap_tg03" +#define TAG_PRI_MAPPING_TAG_0X03_BOFFSET 6 +#define TAG_PRI_MAPPING_TAG_0X03_BLEN 2 +#define TAG_PRI_MAPPING_TAG_0X03_FLAG HSL_RW + +#define TAG_0X02 "tpmap_tg02" +#define TAG_PRI_MAPPING_TAG_0X02_BOFFSET 4 +#define TAG_PRI_MAPPING_TAG_0X02_BLEN 2 +#define TAG_PRI_MAPPING_TAG_0X02_FLAG HSL_RW + +#define TAG_0X01 "tpmap_tg01" +#define TAG_PRI_MAPPING_TAG_0X01_BOFFSET 2 +#define TAG_PRI_MAPPING_TAG_0X01_BLEN 2 +#define TAG_PRI_MAPPING_TAG_0X01_FLAG HSL_RW + +#define TAG_0X00 "tpmap_tg00" +#define TAG_PRI_MAPPING_TAG_0X00_BOFFSET 0 +#define TAG_PRI_MAPPING_TAG_0X00_BLEN 2 +#define TAG_PRI_MAPPING_TAG_0X00_FLAG HSL_RW + + + /* Service tag Register */ +#define SERVICE_TAG "servicetag" +#define SERVICE_TAG_ID 20 +#define SERVICE_TAG_OFFSET 0x0074 +#define SERVICE_TAG_E_LENGTH 4 +#define SERVICE_TAG_E_OFFSET 0 +#define SERVICE_TAG_NR_E 1 + +#define TAG_VALUE "servicetag_val" +#define SERVICE_TAG_TAG_VALUE_BOFFSET 0 +#define SERVICE_TAG_TAG_VALUE_BLEN 16 +#define SERVICE_TAG_TAG_VALUE_FLAG HSL_RW + + + /* Cpu Port Register */ +#define CPU_PORT "cpup" +#define CPU_PORT_ID 20 +#define CPU_PORT_OFFSET 0x0078 +#define CPU_PORT_E_LENGTH 4 +#define CPU_PORT_E_OFFSET 0 +#define CPU_PORT_NR_E 0 + +#define CPU_PORT_EN "cpup_cpupe" +#define CPU_PORT_CPU_PORT_EN_BOFFSET 8 +#define CPU_PORT_CPU_PORT_EN_BLEN 1 +#define CPU_PORT_CPU_PORT_EN_FLAG HSL_RW + +#define MIRROR_PORT_NUM "cpup_mirpn" +#define CPU_PORT_MIRROR_PORT_NUM_BOFFSET 4 +#define CPU_PORT_MIRROR_PORT_NUM_BLEN 4 +#define CPU_PORT_MIRROR_PORT_NUM_FLAG HSL_RW + + + /* MIB Function Register */ +#define MIB_FUNC "mibfunc" +#define MIB_FUNC_ID 21 +#define MIB_FUNC_OFFSET 0x0080 +#define MIB_FUNC_E_LENGTH 4 +#define MIB_FUNC_E_OFFSET 0 +#define MIB_FUNC_NR_E 1 + +#define MAC_CRC_EN "mibfunc_crcen" +#define MIB_FUNC_MAC_CRC_EN_BOFFSET 31 +#define MIB_FUNC_MAC_CRC_EN_BLEN 1 +#define MIB_FUNC_MAC_CRC_EN_FLAG HSL_RW + +#define MIB_EN "mib_en" +#define MIB_FUNC_MIB_EN_BOFFSET 30 +#define MIB_FUNC_MIB_EN_BLEN 1 +#define MIB_FUNC_MIB_EN_FLAG HSL_RW + +#define MIB_FUN "mibfunc_mibf" +#define MIB_FUNC_MIB_FUN_BOFFSET 24 +#define MIB_FUNC_MIB_FUN_BLEN 3 +#define MIB_FUNC_MIB_FUN_FLAG HSL_RW + +#define MIB_BUSY "mibfunc_mibb" +#define MIB_FUNC_MIB_BUSY_BOFFSET 17 +#define MIB_FUNC_MIB_BUSY_BLEN 1 +#define MIB_FUNC_MIB_BUSY_FLAG HSL_RW + +#define MIB_AT_HALF_EN "mibfunc_mibhe" +#define MIB_FUNC_MIB_AT_HALF_EN_BOFFSET 16 +#define MIB_FUNC_MIB_AT_HALF_EN_BLEN 1 +#define MIB_FUNC_MIB_AT_HALF_EN_FLAG HSL_RW + +#define MIB_TIMER "mibfunc_mibt" +#define MIB_FUNC_MIB_TIMER_BOFFSET 0 +#define MIB_FUNC_MIB_TIMER_BLEN 16 +#define MIB_FUNC_MIB_TIMER_FLAG HSL_RW + + + /* Mdio control Register */ +#define MDIO_CTRL "mctrl" +#define MDIO_CTRL_ID 24 +#define MDIO_CTRL_OFFSET 0x0098 +#define MDIO_CTRL_E_LENGTH 4 +#define MDIO_CTRL_E_OFFSET 0 +#define MDIO_CTRL_NR_E 1 + +#define MSTER_EN "mctrl_msteren" +#define MDIO_CTRL_MSTER_EN_BOFFSET 30 +#define MDIO_CTRL_MSTER_EN_BLEN 1 +#define MDIO_CTRL_MSTER_EN_FLAG HSL_RW + +#define MSTER_EN "mctrl_msteren" +#define MDIO_CTRL_MSTER_EN_BOFFSET 30 +#define MDIO_CTRL_MSTER_EN_BLEN 1 +#define MDIO_CTRL_MSTER_EN_FLAG HSL_RW + +#define CMD "mctrl_cmd" +#define MDIO_CTRL_CMD_BOFFSET 27 +#define MDIO_CTRL_CMD_BLEN 1 +#define MDIO_CTRL_CMD_FLAG HSL_RW + +#define SUP_PRE "mctrl_spre" +#define MDIO_CTRL_SUP_PRE_BOFFSET 26 +#define MDIO_CTRL_SUP_PRE_BLEN 1 +#define MDIO_CTRL_SUP_PRE_FLAG HSL_RW + +#define PHY_ADDR "mctrl_phyaddr" +#define MDIO_CTRL_PHY_ADDR_BOFFSET 21 +#define MDIO_CTRL_PHY_ADDR_BLEN 5 +#define MDIO_CTRL_PHY_ADDR_FLAG HSL_RW + +#define REG_ADDR "mctrl_regaddr" +#define MDIO_CTRL_REG_ADDR_BOFFSET 16 +#define MDIO_CTRL_REG_ADDR_BLEN 5 +#define MDIO_CTRL_REG_ADDR_FLAG HSL_RW + +#define DATA "mctrl_data" +#define MDIO_CTRL_DATA_BOFFSET 0 +#define MDIO_CTRL_DATA_BLEN 16 +#define MDIO_CTRL_DATA_FLAG HSL_RW + + + + + /* BIST control Register */ +#define BIST_CTRL "bctrl" +#define BIST_CTRL_ID 24 +#define BIST_CTRL_OFFSET 0x00a0 +#define BIST_CTRL_E_LENGTH 4 +#define BIST_CTRL_E_OFFSET 0 +#define BIST_CTRL_NR_E 1 + +#define BIST_BUSY "bctrl_bb" +#define BIST_CTRL_BIST_BUSY_BOFFSET 31 +#define BIST_CTRL_BIST_BUSY_BLEN 1 +#define BIST_CTRL_BIST_BUSY_FLAG HSL_RW + +#define ONE_ERR "bctrl_oe" +#define BIST_CTRL_ONE_ERR_BOFFSET 30 +#define BIST_CTRL_ONE_ERR_BLEN 1 +#define BIST_CTRL_ONE_ERR_FLAG HSL_RO + +#define ERR_MEM "bctrl_em" +#define BIST_CTRL_ERR_MEM_BOFFSET 24 +#define BIST_CTRL_ERR_MEM_BLEN 4 +#define BIST_CTRL_ERR_MEM_FLAG HSL_RO + +#define PTN_EN2 "bctrl_pe2" +#define BIST_CTRL_PTN_EN2_BOFFSET 22 +#define BIST_CTRL_PTN_EN2_BLEN 1 +#define BIST_CTRL_PTN_EN2_FLAG HSL_RW + +#define PTN_EN1 "bctrl_pe1" +#define BIST_CTRL_PTN_EN1_BOFFSET 21 +#define BIST_CTRL_PTN_EN1_BLEN 1 +#define BIST_CTRL_PTN_EN1_FLAG HSL_RW + +#define PTN_EN0 "bctrl_pe0" +#define BIST_CTRL_PTN_EN0_BOFFSET 20 +#define BIST_CTRL_PTN_EN0_BLEN 1 +#define BIST_CTRL_PTN_EN0_FLAG HSL_RW + +#define ERR_PTN "bctrl_ep" +#define BIST_CTRL_ERR_PTN_BOFFSET 16 +#define BIST_CTRL_ERR_PTN_BLEN 2 +#define BIST_CTRL_ERR_PTN_FLAG HSL_RO + +#define ERR_CNT "bctrl_ec" +#define BIST_CTRL_ERR_CNT_BOFFSET 13 +#define BIST_CTRL_ERR_CNT_BLEN 2 +#define BIST_CTRL_ERR_CNT_FLAG HSL_RO + +#define ERR_ADDR "bctrl_ea" +#define BIST_CTRL_ERR_ADDR_BOFFSET 0 +#define BIST_CTRL_ERR_ADDR_BLEN 12 +#define BIST_CTRL_ERR_ADDR_FLAG HSL_RO + + + + + /* BIST recover Register */ +#define BIST_RCV "brcv" +#define BIST_RCV_ID 24 +#define BIST_RCV_OFFSET 0x00a4 +#define BIST_RCV_E_LENGTH 4 +#define BIST_RCV_E_OFFSET 0 +#define BIST_RCV_NR_E 1 + +#define RCV_EN "brcv_en" +#define BIST_RCV_RCV_EN_BOFFSET 31 +#define BIST_RCV_RCV_EN_BLEN 1 +#define BIST_RCV_RCV_EN_FLAG HSL_RW + +#define RCV_ADDR "brcv_addr" +#define BIST_RCV_RCV_ADDR_BOFFSET 0 +#define BIST_RCV_RCV_ADDR_BLEN 12 +#define BIST_RCV_RCV_ADDR_FLAG HSL_RW + + + + + /* LED control Register */ +#define LED_CTRL "ledctrl" +#define LED_CTRL_ID 25 +#define LED_CTRL_OFFSET 0x00b0 +#define LED_CTRL_E_LENGTH 4 +#define LED_CTRL_E_OFFSET 0 +#define LED_CTRL_NR_E 1 + +#define PATTERN_EN "lctrl_pen" +#define LED_CTRL_PATTERN_EN_BOFFSET 14 +#define LED_CTRL_PATTERN_EN_BLEN 2 +#define LED_CTRL_PATTERN_EN_FLAG HSL_RW + +#define FULL_LIGHT_EN "lctrl_fen" +#define LED_CTRL_FULL_LIGHT_EN_BOFFSET 13 +#define LED_CTRL_FULL_LIGHT_EN_BLEN 1 +#define LED_CTRL_FULL_LIGHT_EN_FLAG HSL_RW + +#define HALF_LIGHT_EN "lctrl_hen" +#define LED_CTRL_HALF_LIGHT_EN_BOFFSET 12 +#define LED_CTRL_HALF_LIGHT_EN_BLEN 1 +#define LED_CTRL_HALF_LIGHT_EN_FLAG HSL_RW + +#define POWERON_LIGHT_EN "lctrl_poen" +#define LED_CTRL_POWERON_LIGHT_EN_BOFFSET 11 +#define LED_CTRL_POWERON_LIGHT_EN_BLEN 1 +#define LED_CTRL_POWERON_LIGHT_EN_FLAG HSL_RW + +#define GE_LIGHT_EN "lctrl_geen" +#define LED_CTRL_GE_LIGHT_EN_BOFFSET 10 +#define LED_CTRL_GE_LIGHT_EN_BLEN 1 +#define LED_CTRL_GE_LIGHT_EN_FLAG HSL_RW + +#define FE_LIGHT_EN "lctrl_feen" +#define LED_CTRL_FE_LIGHT_EN_BOFFSET 9 +#define LED_CTRL_FE_LIGHT_EN_BLEN 1 +#define LED_CTRL_FE_LIGHT_EN_FLAG HSL_RW + +#define ETH_LIGHT_EN "lctrl_ethen" +#define LED_CTRL_ETH_LIGHT_EN_BOFFSET 8 +#define LED_CTRL_ETH_LIGHT_EN_BLEN 1 +#define LED_CTRL_ETH_LIGHT_EN_FLAG HSL_RW + +#define COL_BLINK_EN "lctrl_cen" +#define LED_CTRL_COL_BLINK_EN_BOFFSET 7 +#define LED_CTRL_COL_BLINK_EN_BLEN 1 +#define LED_CTRL_COL_BLINK_EN_FLAG HSL_RW + +#define RX_BLINK_EN "lctrl_rxen" +#define LED_CTRL_RX_BLINK_EN_BOFFSET 5 +#define LED_CTRL_RX_BLINK_EN_BLEN 1 +#define LED_CTRL_RX_BLINK_EN_FLAG HSL_RW + +#define TX_BLINK_EN "lctrl_txen" +#define LED_CTRL_TX_BLINK_EN_BOFFSET 4 +#define LED_CTRL_TX_BLINK_EN_BLEN 1 +#define LED_CTRL_TX_BLINK_EN_FLAG HSL_RW + +#define LINKUP_OVER_EN "lctrl_loen" +#define LED_CTRL_LINKUP_OVER_EN_BOFFSET 2 +#define LED_CTRL_LINKUP_OVER_EN_BLEN 1 +#define LED_CTRL_LINKUP_OVER_EN_FLAG HSL_RW + +#define BLINK_FREQ "lctrl_bfreq" +#define LED_CTRL_BLINK_FREQ_BOFFSET 0 +#define LED_CTRL_BLINK_FREQ_BLEN 2 +#define LED_CTRL_BLINK_FREQ_FLAG HSL_RW + + /* LED control Register */ +#define LED_PATTERN "ledpatten" +#define LED_PATTERN_ID 25 +#define LED_PATTERN_OFFSET 0x00bc +#define LED_PATTERN_E_LENGTH 4 +#define LED_PATTERN_E_OFFSET 0 +#define LED_PATTERN_NR_E 1 + +#define P3L1_MODE "p3l1_mode" +#define LED_PATTERN_P3L1_MODE_BOFFSET 24 +#define LED_PATTERN_P3L1_MODE_BLEN 2 +#define LED_PATTERN_P3L1_MODE_FLAG HSL_RW + +#define P3L0_MODE "p3l0_mode" +#define LED_PATTERN_P3L0_MODE_BOFFSET 22 +#define LED_PATTERN_P3L0_MODE_BLEN 2 +#define LED_PATTERN_P3L0_MODE_FLAG HSL_RW + +#define P2L1_MODE "p2l1_mode" +#define LED_PATTERN_P2L1_MODE_BOFFSET 20 +#define LED_PATTERN_P2L1_MODE_BLEN 2 +#define LED_PATTERN_P2L1_MODE_FLAG HSL_RW + +#define P2L0_MODE "p2l0_mode" +#define LED_PATTERN_P2L0_MODE_BOFFSET 18 +#define LED_PATTERN_P2L0_MODE_BLEN 2 +#define LED_PATTERN_P2L0_MODE_FLAG HSL_RW + +#define P1L1_MODE "p1l1_mode" +#define LED_PATTERN_P1L1_MODE_BOFFSET 16 +#define LED_PATTERN_P1L1_MODE_BLEN 2 +#define LED_PATTERN_P1L1_MODE_FLAG HSL_RW + +#define P1L0_MODE "p1l0_mode" +#define LED_PATTERN_P1L0_MODE_BOFFSET 14 +#define LED_PATTERN_P1L0_MODE_BLEN 2 +#define LED_PATTERN_P1L0_MODE_FLAG HSL_RW + +#define M5_MODE "m5_mode" +#define LED_PATTERN_M5_MODE_BOFFSET 10 +#define LED_PATTERN_M5_MODE_BLEN 2 +#define LED_PATTERN_M5_MODE_FLAG HSL_RW + + + /* Port Status Register */ +#define PORT_STATUS "ptsts" +#define PORT_STATUS_ID 29 +#define PORT_STATUS_OFFSET 0x0100 +#define PORT_STATUS_E_LENGTH 4 +#define PORT_STATUS_E_OFFSET 0x0100 +#define PORT_STATUS_NR_E 6 + +#define FLOW_LINK_EN "ptsts_flen" +#define PORT_STATUS_FLOW_LINK_EN_BOFFSET 12 +#define PORT_STATUS_FLOW_LINK_EN_BLEN 1 +#define PORT_STATUS_FLOW_LINK_EN_FLAG HSL_RW + + +#define LINK_ASYN_PAUSE "ptsts_lasynp" +#define PORT_STATUS_LINK_ASYN_PAUSE_BOFFSET 11 +#define PORT_STATUS_LINK_ASYN_PAUSE_BLEN 1 +#define PORT_STATUS_LINK_ASYN_PAUSE_FLAG HSL_RO + +#define LINK_PAUSE "ptsts_lpause" +#define PORT_STATUS_LINK_PAUSE_BOFFSET 10 +#define PORT_STATUS_LINK_PAUSE_BLEN 1 +#define PORT_STATUS_LINK_PAUSE_FLAG HSL_RO + +#define LINK_EN "ptsts_linken" +#define PORT_STATUS_LINK_EN_BOFFSET 9 +#define PORT_STATUS_LINK_EN_BLEN 1 +#define PORT_STATUS_LINK_EN_FLAG HSL_RW + +#define LINK "ptsts_ptlink" +#define PORT_STATUS_LINK_BOFFSET 8 +#define PORT_STATUS_LINK_BLEN 1 +#define PORT_STATUS_LINK_FLAG HSL_RO + +#define TX_HALF_FLOW_EN +#define PORT_STATUS_TX_HALF_FLOW_EN_BOFFSET 7 +#define PORT_STATUS_TX_HALF_FLOW_EN_BLEN 1 +#define PORT_STATUS_TX_HALF_FLOW_EN_FLAG HSL_RW + +#define DUPLEX_MODE "ptsts_dupmod" +#define PORT_STATUS_DUPLEX_MODE_BOFFSET 6 +#define PORT_STATUS_DUPLEX_MODE_BLEN 1 +#define PORT_STATUS_DUPLEX_MODE_FLAG HSL_RW + +#define RX_FLOW_EN "ptsts_rxfwen" +#define PORT_STATUS_RX_FLOW_EN_BOFFSET 5 +#define PORT_STATUS_RX_FLOW_EN_BLEN 1 +#define PORT_STATUS_RX_FLOW_EN_FLAG HSL_RW + +#define TX_FLOW_EN "ptsts_txfwen" +#define PORT_STATUS_TX_FLOW_EN_BOFFSET 4 +#define PORT_STATUS_TX_FLOW_EN_BLEN 1 +#define PORT_STATUS_TX_FLOW_EN_FLAG HSL_RW + +#define RXMAC_EN "ptsts_rxmacen" +#define PORT_STATUS_RXMAC_EN_BOFFSET 3 +#define PORT_STATUS_RXMAC_EN_BLEN 1 +#define PORT_STATUS_RXMAC_EN_FLAG HSL_RW + +#define TXMAC_EN "ptsts_txmacen" +#define PORT_STATUS_TXMAC_EN_BOFFSET 2 +#define PORT_STATUS_TXMAC_EN_BLEN 1 +#define PORT_STATUS_TXMAC_EN_FLAG HSL_RW + +#define SPEED_MODE "ptsts_speed" +#define PORT_STATUS_SPEED_MODE_BOFFSET 0 +#define PORT_STATUS_SPEED_MODE_BLEN 2 +#define PORT_STATUS_SPEED_MODE_FLAG HSL_RW + + + /* Port Control Register */ +#define PORT_CTL "pctl" +#define PORT_CTL_ID 30 +#define PORT_CTL_OFFSET 0x0104 +#define PORT_CTL_E_LENGTH 4 +#define PORT_CTL_E_OFFSET 0x0100 +#define PORT_CTL_NR_E 6 + +#define EAPOL_EN "pctl_eapolen" +#define PORT_CTL_EAPOL_EN_BOFFSET 23 +#define PORT_CTL_EAPOL_EN_BLEN 1 +#define PORT_CTL_EAPOL_EN_FLAG HSL_RW + +#define ARP_LEAKY_EN "pbvlan_alen" +#define PORT_CTL_ARP_LEAKY_EN_BOFFSET 22 +#define PORT_CTL_ARP_LEAKY_EN_BLEN 1 +#define PORT_CTL_ARP_LEAKY_EN_FLAG HSL_RW + +#define LEAVE_EN "pctl_leaveen" +#define PORT_CTL_LEAVE_EN_BOFFSET 21 +#define PORT_CTL_LEAVE_EN_BLEN 1 +#define PORT_CTL_LEAVE_EN_FLAG HSL_RW + +#define JOIN_EN "pctl_joinen" +#define PORT_CTL_JOIN_EN_BOFFSET 20 +#define PORT_CTL_JOIN_EN_BLEN 1 +#define PORT_CTL_JOIN_EN_FLAG HSL_RW + +#define DHCP_EN "pctl_dhcpen" +#define PORT_CTL_DHCP_EN_BOFFSET 19 +#define PORT_CTL_DHCP_EN_BLEN 1 +#define PORT_CTL_DHCP_EN_FLAG HSL_RW + +#define ING_MIRROR_EN "pctl_ingmiren" +#define PORT_CTL_ING_MIRROR_EN_BOFFSET 17 +#define PORT_CTL_ING_MIRROR_EN_BLEN 1 +#define PORT_CTL_ING_MIRROR_EN_FLAG HSL_RW + +#define EG_MIRROR_EN "pctl_egmiren" +#define PORT_CTL_EG_MIRROR_EN_BOFFSET 16 +#define PORT_CTL_EG_MIRROR_EN_BLEN 1 +#define PORT_CTL_EG_MIRROR_EN_FLAG HSL_RW + +#define LEARN_EN "pctl_learnen" +#define PORT_CTL_LEARN_EN_BOFFSET 14 +#define PORT_CTL_LEARN_EN_BLEN 1 +#define PORT_CTL_LEARN_EN_FLAG HSL_RW + +#define MAC_LOOP_BACK "pctl_maclp" +#define PORT_CTL_MAC_LOOP_BACK_BOFFSET 12 +#define PORT_CTL_MAC_LOOP_BACK_BLEN 1 +#define PORT_CTL_MAC_LOOP_BACK_FLAG HSL_RW + +#define HEAD_EN "pctl_headen" +#define PORT_CTL_HEAD_EN_BOFFSET 11 +#define PORT_CTL_HEAD_EN_BLEN 1 +#define PORT_CTL_HEAD_EN_FLAG HSL_RW + +#define IGMP_MLD_EN "pctl_imlden" +#define PORT_CTL_IGMP_MLD_EN_BOFFSET 10 +#define PORT_CTL_IGMP_MLD_EN_BLEN 1 +#define PORT_CTL_IGMP_MLD_EN_FLAG HSL_RW + +#define EG_VLAN_MODE "pctl_egvmode" +#define PORT_CTL_EG_VLAN_MODE_BOFFSET 8 +#define PORT_CTL_EG_VLAN_MODE_BLEN 2 +#define PORT_CTL_EG_VLAN_MODE_FLAG HSL_RW + +#define LEARN_ONE_LOCK "pctl_lonelck" +#define PORT_CTL_LEARN_ONE_LOCK_BOFFSET 7 +#define PORT_CTL_LEARN_ONE_LOCK_BLEN 1 +#define PORT_CTL_LEARN_ONE_LOCK_FLAG HSL_RW + +#define PORT_LOCK_EN "pctl_locken" +#define PORT_CTL_PORT_LOCK_EN_BOFFSET 6 +#define PORT_CTL_PORT_LOCK_EN_BLEN 1 +#define PORT_CTL_PORT_LOCK_EN_FLAG HSL_RW + +#define LOCK_DROP_EN "pctl_dropen" +#define PORT_CTL_LOCK_DROP_EN_BOFFSET 5 +#define PORT_CTL_LOCK_DROP_EN_BLEN 1 +#define PORT_CTL_LOCK_DROP_EN_FLAG HSL_RW + +#define PORT_STATE "pctl_pstate" +#define PORT_CTL_PORT_STATE_BOFFSET 0 +#define PORT_CTL_PORT_STATE_BLEN 3 +#define PORT_CTL_PORT_STATE_FLAG HSL_RW + + + /* Port dot1q Register */ +#define PORT_DOT1Q "pdot1Q" +#define PORT_DOT1Q_ID 31 +#define PORT_DOT1Q_OFFSET 0x0108 +#define PORT_DOT1Q_E_LENGTH 4 +#define PORT_DOT1Q_E_OFFSET 0x0100 +#define PORT_DOT1Q_NR_E 6 + +#define ING_PRI "pdot1q_ingpri" +#define PORT_DOT1Q_ING_PRI_BOFFSET 29 +#define PORT_DOT1Q_ING_PRI_BLEN 3 +#define PORT_DOT1Q_ING_PRI_FLAG HSL_RW + +#define FORCE_PVLAN "pdot1q_fpvlan" +#define PORT_DOT1Q_FORCE_PVLAN_BOFFSET 28 +#define PORT_DOT1Q_FORCE_PVLAN_BLEN 1 +#define PORT_DOT1Q_FORCE_PVLAN_FLAG HSL_RW + +#define DEF_VID "pdot1q_dcvid" +#define PORT_DOT1Q_DEF_VID_BOFFSET 16 +#define PORT_DOT1Q_DEF_VID_BLEN 12 +#define PORT_DOT1Q_DEF_VID_FLAG HSL_RW + +#define FORCE_DEF_VID "pbot1q_fdvid" +#define PORT_DOT1Q_FORCE_DEF_VID_BOFFSET 12 +#define PORT_DOT1Q_FORCE_DEF_VID_BLEN 1 +#define PORT_DOT1Q_FORCE_DEF_VID_FLAG HSL_RW + + + /* Port Based Vlan Register */ +#define PORT_BASE_VLAN "pbvlan" +#define PORT_BASE_VLAN_ID 31 +#define PORT_BASE_VLAN_OFFSET 0x010c +#define PORT_BASE_VLAN_E_LENGTH 4 +#define PORT_BASE_VLAN_E_OFFSET 0x0100 +#define PORT_BASE_VLAN_NR_E 6 + +#define DOT1Q_MODE "pbvlan_8021q" +#define PORT_BASE_VLAN_DOT1Q_MODE_BOFFSET 30 +#define PORT_BASE_VLAN_DOT1Q_MODE_BLEN 2 +#define PORT_BASE_VLAN_DOT1Q_MODE_FLAG HSL_RW + +#define COREP_EN "pbvlan_corepen" +#define PORT_BASE_VLAN_COREP_EN_BOFFSET 29 +#define PORT_BASE_VLAN_COREP_EN_BLEN 1 +#define PORT_BASE_VLAN_COREP_EN_FLAG HSL_RW + +#define IN_VLAN_MODE "pbvlan_imode" +#define PORT_BASE_VLAN_IN_VLAN_MODE_BOFFSET 27 +#define PORT_BASE_VLAN_IN_VLAN_MODE_BLEN 2 +#define PORT_BASE_VLAN_IN_VLAN_MODE_FLAG HSL_RW + +#define PRI_PROPAGATION "pbvlan_prip" +#define PORT_BASE_VLAN_PRI_PROPAGATION_BOFFSET 23 +#define PORT_BASE_VLAN_PRI_PROPAGATION_BLEN 1 +#define PORT_BASE_VLAN_PRI_PROPAGATION_FLAG HSL_RW + +#define PORT_VID_MEM "pbvlan_pvidm" +#define PORT_BASE_VLAN_PORT_VID_MEM_BOFFSET 16 +#define PORT_BASE_VLAN_PORT_VID_MEM_BLEN 6 +#define PORT_BASE_VLAN_PORT_VID_MEM_FLAG HSL_RW + +#define UNI_LEAKY_EN "pbvlan_ulen" +#define PORT_BASE_VLAN_UNI_LEAKY_EN_BOFFSET 14 +#define PORT_BASE_VLAN_UNI_LEAKY_EN_BLEN 1 +#define PORT_BASE_VLAN_UNI_LEAKY_EN_FLAG HSL_RW + +#define MUL_LEAKY_EN "pbvlan_mlen" +#define PORT_BASE_VLAN_MUL_LEAKY_EN_BOFFSET 13 +#define PORT_BASE_VLAN_MUL_LEAKY_EN_BLEN 1 +#define PORT_BASE_VLAN_MUL_LEAKY_EN_FLAG HSL_RW + + + /* Port Rate Limit0 Register */ +#define RATE_LIMIT0 "rlmt0" +#define RATE_LIMIT0_ID 32 +#define RATE_LIMIT0_OFFSET 0x0110 +#define RATE_LIMIT0_E_LENGTH 4 +#define RATE_LIMIT0_E_OFFSET 0x0100 +#define RATE_LIMIT0_NR_E 6 + +#define ADD_RATE_BYTE "rlmt_addbyte" +#define RATE_LIMIT0_ADD_RATE_BYTE_BOFFSET 24 +#define RATE_LIMIT0_ADD_RATE_BYTE_BLEN 8 +#define RATE_LIMIT0_ADD_RATE_BYTE_FLAG HSL_RW + +#define EG_MNG_RATE_EN "rlmt_egmngen" +#define RATE_LIMIT0_EG_MNG_RATE_EN_BOFFSET 22 +#define RATE_LIMIT0_EG_MNG_RATE_EN_BLEN 1 +#define RATE_LIMIT0_EG_MNG_RATE_EN_FLAG HSL_RW + +#define IN_MNG_RATE_EN "rlmt_inmngen" +#define RATE_LIMIT0_IN_MNG_RATE_EN_BOFFSET 21 +#define RATE_LIMIT0_IN_MNG_RATE_EN_BLEN 1 +#define RATE_LIMIT0_IN_MNG_RATE_EN_FLAG HSL_RW + +#define IN_MUL_RATE_EN "rlmt_inmulen" +#define RATE_LIMIT0_IN_MUL_RATE_EN_BOFFSET 20 +#define RATE_LIMIT0_IN_MUL_RATE_EN_BLEN 1 +#define RATE_LIMIT0_IN_MUL_RATE_EN_FLAG HSL_RW + +#define ING_RATE "rlmt_ingrate" +#define RATE_LIMIT0_ING_RATE_BOFFSET 0 +#define RATE_LIMIT0_ING_RATE_BLEN 13 +#define RATE_LIMIT0_ING_RATE_FLAG HSL_RW + + + /* Priority Control Register */ +#define PRI_CTL "prctl" +#define PRI_CTL_ID 33 +#define PRI_CTL_OFFSET 0x0114 +#define PRI_CTL_E_LENGTH 4 +#define PRI_CTL_E_OFFSET 0x0100 +#define PRI_CTL_NR_E 6 + +#define PORT_PRI_EN "prctl_ptprien" +#define PRI_CTL_PORT_PRI_EN_BOFFSET 19 +#define PRI_CTL_PORT_PRI_EN_BLEN 1 +#define PRI_CTL_PORT_PRI_EN_FLAG HSL_RW + +#define DA_PRI_EN "prctl_daprien" +#define PRI_CTL_DA_PRI_EN_BOFFSET 18 +#define PRI_CTL_DA_PRI_EN_BLEN 1 +#define PRI_CTL_DA_PRI_EN_FLAG HSL_RW + +#define VLAN_PRI_EN "prctl_vprien" +#define PRI_CTL_VLAN_PRI_EN_BOFFSET 17 +#define PRI_CTL_VLAN_PRI_EN_BLEN 1 +#define PRI_CTL_VLAN_PRI_EN_FLAG HSL_RW + +#define IP_PRI_EN "prctl_ipprien" +#define PRI_CTL_IP_PRI_EN_BOFFSET 16 +#define PRI_CTL_IP_PRI_EN_BLEN 1 +#define PRI_CTL_IP_PRI_EN_FLAG HSL_RW + +#define DA_PRI_SEL "prctl_dapris" +#define PRI_CTL_DA_PRI_SEL_BOFFSET 6 +#define PRI_CTL_DA_PRI_SEL_BLEN 2 +#define PRI_CTL_DA_PRI_SEL_FLAG HSL_RW + +#define VLAN_PRI_SEL "prctl_vpris" +#define PRI_CTL_VLAN_PRI_SEL_BOFFSET 4 +#define PRI_CTL_VLAN_PRI_SEL_BLEN 2 +#define PRI_CTL_VLAN_PRI_SEL_FLAG HSL_RW + +#define IP_PRI_SEL "prctl_ippris" +#define PRI_CTL_IP_PRI_SEL_BOFFSET 2 +#define PRI_CTL_IP_PRI_SEL_BLEN 2 +#define PRI_CTL_IP_PRI_SEL_FLAG HSL_RW + +#define PORT_PRI_SEL "prctl_ptpris" +#define PRI_CTL_PORT_PRI_SEL_BOFFSET 0 +#define PRI_CTL_PORT_PRI_SEL_BLEN 2 +#define PRI_CTL_PORT_PRI_SEL_FLAG HSL_RW + + + /* Storm Control Register */ +#define STORM_CTL "sctrl" +#define STORM_CTL_ID 33 +#define STORM_CTL_OFFSET 0x0118 +#define STORM_CTL_E_LENGTH 4 +#define STORM_CTL_E_OFFSET 0x0100 +#define STORM_CTL_NR_E 6 + +#define UNIT "sctrl_unit" +#define STORM_CTL_UNIT_BOFFSET 24 +#define STORM_CTL_UNIT_BLEN 2 +#define STORM_CTL_UNIT_FLAG HSL_RW + +#define MUL_EN "sctrl_mulen" +#define STORM_CTL_MUL_EN_BOFFSET 10 +#define STORM_CTL_MUL_EN_BLEN 1 +#define STORM_CTL_MUL_EN_FLAG HSL_RW + +#define UNI_EN "sctrl_unien" +#define STORM_CTL_UNI_EN_BOFFSET 9 +#define STORM_CTL_UNI_EN_BLEN 1 +#define STORM_CTL_UNI_EN_FLAG HSL_RW + +#define BRO_EN "sctrl_broen" +#define STORM_CTL_BRO_EN_BOFFSET 8 +#define STORM_CTL_BRO_EN_BLEN 1 +#define STORM_CTL_BRO_EN_FLAG HSL_RW + +#define RATE "sctrl_rate" +#define STORM_CTL_RATE_BOFFSET 0 +#define STORM_CTL_RATE_BLEN 4 +#define STORM_CTL_RATE_FLAG HSL_RW + + + /* Queue Control Register */ +#define QUEUE_CTL "qctl" +#define QUEUE_CTL_ID 34 +#define QUEUE_CTL_OFFSET 0x011c +#define QUEUE_CTL_E_LENGTH 4 +#define QUEUE_CTL_E_OFFSET 0x0100 +#define QUEUE_CTL_NR_E 6 + +#define PORT_IN_DESC_EN "qctl_pdescen" +#define QUEUE_CTL_PORT_IN_DESC_EN_BOFFSET 28 +#define QUEUE_CTL_PORT_IN_DESC_EN_BLEN 4 +#define QUEUE_CTL_PORT_IN_DESC_EN_FLAG HSL_RW + +#define PORT_DESC_EN "qctl_pdescen" +#define QUEUE_CTL_PORT_DESC_EN_BOFFSET 25 +#define QUEUE_CTL_PORT_DESC_EN_BLEN 1 +#define QUEUE_CTL_PORT_DESC_EN_FLAG HSL_RW + +#define QUEUE_DESC_EN "qctl_qdescen" +#define QUEUE_CTL_QUEUE_DESC_EN_BOFFSET 24 +#define QUEUE_CTL_QUEUE_DESC_EN_BLEN 1 +#define QUEUE_CTL_QUEUE_DESC_EN_FLAG HSL_RW + +#define PORT_DESC_NR "qctl_pdscpnr" +#define QUEUE_CTL_PORT_DESC_NR_BOFFSET 16 +#define QUEUE_CTL_PORT_DESC_NR_BLEN 6 +#define QUEUE_CTL_PORT_DESC_NR_FLAG HSL_RW + +#define QUEUE3_DESC_NR "qctl_q3dscpnr" +#define QUEUE_CTL_QUEUE3_DESC_NR_BOFFSET 12 +#define QUEUE_CTL_QUEUE3_DESC_NR_BLEN 4 +#define QUEUE_CTL_QUEUE3_DESC_NR_FLAG HSL_RW + +#define QUEUE2_DESC_NR "qctl_q2dscpnr" +#define QUEUE_CTL_QUEUE2_DESC_NR_BOFFSET 8 +#define QUEUE_CTL_QUEUE2_DESC_NR_BLEN 4 +#define QUEUE_CTL_QUEUE2_DESC_NR_FLAG HSL_RW + +#define QUEUE1_DESC_NR "qctl_q1dscpnr" +#define QUEUE_CTL_QUEUE1_DESC_NR_BOFFSET 4 +#define QUEUE_CTL_QUEUE1_DESC_NR_BLEN 4 +#define QUEUE_CTL_QUEUE1_DESC_NR_FLAG HSL_RW + +#define QUEUE0_DESC_NR "qctl_q0dscpnr" +#define QUEUE_CTL_QUEUE0_DESC_NR_BOFFSET 0 +#define QUEUE_CTL_QUEUE0_DESC_NR_BLEN 4 +#define QUEUE_CTL_QUEUE0_DESC_NR_FLAG HSL_RW + + + /* Port Rate Limit1 Register */ +#define RATE_LIMIT1 "rlmt1" +#define RATE_LIMIT1_ID 32 +#define RATE_LIMIT1_OFFSET 0x0120 +#define RATE_LIMIT1_E_LENGTH 4 +#define RATE_LIMIT1_E_OFFSET 0x0100 +#define RATE_LIMIT1_NR_E 6 + +#define EG_RATE "rlmt_egrate" +#define RATE_LIMIT1_EG_RATE_BOFFSET 0 +#define RATE_LIMIT1_EG_RATE_BLEN 13 +#define RATE_LIMIT1_EG_RATE_FLAG HSL_RW + + + /* Port Rate Limit3 Register */ +#define RATE_LIMIT3 "rlmt3" +#define RATE_LIMIT3_ID 32 +#define RATE_LIMIT3_OFFSET 0x0128 +#define RATE_LIMIT3_E_LENGTH 4 +#define RATE_LIMIT3_E_OFFSET 0x0100 +#define RATE_LIMIT3_NR_E 6 + +#define EG_CBS "rlmt_egcbs" +#define RATE_LIMIT3_EG_CBS_BOFFSET 16 +#define RATE_LIMIT3_EG_CBS_BLEN 2 +#define RATE_LIMIT3_EG_CBS_FLAG HSL_RW + +#define EG_TS "rlmt_egts" +#define RATE_LIMIT3_EG_TS_BOFFSET 0 +#define RATE_LIMIT3_EG_TS_BLEN 3 +#define RATE_LIMIT3_EG_TS_FLAG HSL_RW + + + /* Weight Round Robin Register */ +#define WRR_CTRL "wrrc" +#define WRR_CTRL_ID 32 +#define WRR_CTRL_OFFSET 0x012c +#define WRR_CTRL_E_LENGTH 4 +#define WRR_CTRL_E_OFFSET 0x0100 +#define WRR_CTRL_NR_E 6 + +#define SCH_MODE "wrrc_mode" +#define WRR_CTRL_SCH_MODE_BOFFSET 29 +#define WRR_CTRL_SCH_MODE_BLEN 2 +#define WRR_CTRL_SCH_MODE_FLAG HSL_RW + + + /* mib memory info */ +#define MIB_RXBROAD "RxBroad" +#define MIB_RXBROAD_ID 34 +#define MIB_RXBROAD_OFFSET 0x20000 +#define MIB_RXBROAD_E_LENGTH 4 +#define MIB_RXBROAD_E_OFFSET 0x100 +#define MIB_RXBROAD_NR_E 6 + +#define MIB_RXPAUSE "RxPause" +#define MIB_RXPAUSE_ID 35 +#define MIB_RXPAUSE_OFFSET 0x20004 +#define MIB_RXPAUSE_E_LENGTH 4 +#define MIB_RXPAUSE_E_OFFSET 0x100 +#define MIB_RXPAUSE_NR_E 6 + +#define MIB_RXMULTI "RxMulti" +#define MIB_RXMULTI_ID 36 +#define MIB_RXMULTI_OFFSET 0x20008 +#define MIB_RXMULTI_E_LENGTH 4 +#define MIB_RXMULTI_E_OFFSET 0x100 +#define MIB_RXMULTI_NR_E 6 + +#define MIB_RXFCSERR "RxFcsErr" +#define MIB_RXFCSERR_ID 37 +#define MIB_RXFCSERR_OFFSET 0x2000c +#define MIB_RXFCSERR_E_LENGTH 4 +#define MIB_RXFCSERR_E_OFFSET 0x100 +#define MIB_RXFCSERR_NR_E 6 + +#define MIB_RXALLIGNERR "RxAllignErr" +#define MIB_RXALLIGNERR_ID 38 +#define MIB_RXALLIGNERR_OFFSET 0x20010 +#define MIB_RXALLIGNERR_E_LENGTH 4 +#define MIB_RXALLIGNERR_E_OFFSET 0x100 +#define MIB_RXALLIGNERR_NR_E 6 + +#define MIB_RXRUNT "RxRunt" +#define MIB_RXRUNT_ID 39 +#define MIB_RXRUNT_OFFSET 0x20014 +#define MIB_RXRUNT_E_LENGTH 4 +#define MIB_RXRUNT_E_OFFSET 0x100 +#define MIB_RXRUNT_NR_E 6 + +#define MIB_RXFRAGMENT "RxFragment" +#define MIB_RXFRAGMENT_ID 40 +#define MIB_RXFRAGMENT_OFFSET 0x20018 +#define MIB_RXFRAGMENT_E_LENGTH 4 +#define MIB_RXFRAGMENT_E_OFFSET 0x100 +#define MIB_RXFRAGMENT_NR_E 6 + +#define MIB_RX64BYTE "Rx64Byte" +#define MIB_RX64BYTE_ID 41 +#define MIB_RX64BYTE_OFFSET 0x2001c +#define MIB_RX64BYTE_E_LENGTH 4 +#define MIB_RX64BYTE_E_OFFSET 0x100 +#define MIB_RX64BYTE_NR_E 6 + +#define MIB_RX128BYTE "Rx128Byte" +#define MIB_RX128BYTE_ID 42 +#define MIB_RX128BYTE_OFFSET 0x20020 +#define MIB_RX128BYTE_E_LENGTH 4 +#define MIB_RX128BYTE_E_OFFSET 0x100 +#define MIB_RX128BYTE_NR_E 6 + +#define MIB_RX256BYTE "Rx256Byte" +#define MIB_RX256BYTE_ID 43 +#define MIB_RX256BYTE_OFFSET 0x20024 +#define MIB_RX256BYTE_E_LENGTH 4 +#define MIB_RX256BYTE_E_OFFSET 0x100 +#define MIB_RX256BYTE_NR_E 6 + +#define MIB_RX512BYTE "Rx512Byte" +#define MIB_RX512BYTE_ID 44 +#define MIB_RX512BYTE_OFFSET 0x20028 +#define MIB_RX512BYTE_E_LENGTH 4 +#define MIB_RX512BYTE_E_OFFSET 0x100 +#define MIB_RX512BYTE_NR_E 6 + +#define MIB_RX1024BYTE "Rx1024Byte" +#define MIB_RX1024BYTE_ID 45 +#define MIB_RX1024BYTE_OFFSET 0x2002c +#define MIB_RX1024BYTE_E_LENGTH 4 +#define MIB_RX1024BYTE_E_OFFSET 0x100 +#define MIB_RX1024BYTE_NR_E 6 + +#define MIB_RX1518BYTE "Rx1518Byte" +#define MIB_RX1518BYTE_ID 45 +#define MIB_RX1518BYTE_OFFSET 0x20030 +#define MIB_RX1518BYTE_E_LENGTH 4 +#define MIB_RX1518BYTE_E_OFFSET 0x100 +#define MIB_RX1518BYTE_NR_E 6 + +#define MIB_RXMAXBYTE "RxMaxByte" +#define MIB_RXMAXBYTE_ID 46 +#define MIB_RXMAXBYTE_OFFSET 0x20034 +#define MIB_RXMAXBYTE_E_LENGTH 4 +#define MIB_RXMAXBYTE_E_OFFSET 0x100 +#define MIB_RXMAXBYTE_NR_E 6 + +#define MIB_RXTOOLONG "RxTooLong" +#define MIB_RXTOOLONG_ID 47 +#define MIB_RXTOOLONG_OFFSET 0x20038 +#define MIB_RXTOOLONG_E_LENGTH 4 +#define MIB_RXTOOLONG_E_OFFSET 0x100 +#define MIB_RXTOOLONG_NR_E 6 + +#define MIB_RXGOODBYTE_LO "RxGoodByteLo" +#define MIB_RXGOODBYTE_LO_ID 48 +#define MIB_RXGOODBYTE_LO_OFFSET 0x2003c +#define MIB_RXGOODBYTE_LO_E_LENGTH 4 +#define MIB_RXGOODBYTE_LO_E_OFFSET 0x100 +#define MIB_RXGOODBYTE_LO_NR_E 6 + +#define MIB_RXGOODBYTE_HI "RxGoodByteHi" +#define MIB_RXGOODBYTE_HI_ID 49 +#define MIB_RXGOODBYTE_HI_OFFSET 0x20040 +#define MIB_RXGOODBYTE_HI_E_LENGTH 4 +#define MIB_RXGOODBYTE_HI_E_OFFSET 0x100 +#define MIB_RXGOODBYTE_HI_NR_E 6 + +#define MIB_RXBADBYTE_LO "RxBadByteLo" +#define MIB_RXBADBYTE_LO_ID 50 +#define MIB_RXBADBYTE_LO_OFFSET 0x20044 +#define MIB_RXBADBYTE_LO_E_LENGTH 4 +#define MIB_RXBADBYTE_LO_E_OFFSET 0x100 +#define MIB_RXBADBYTE_LO_NR_E 6 + +#define MIB_RXBADBYTE_HI "RxBadByteHi" +#define MIB_RXBADBYTE_HI_ID 51 +#define MIB_RXBADBYTE_HI_OFFSET 0x20048 +#define MIB_RXBADBYTE_HI_E_LENGTH 4 +#define MIB_RXBADBYTE_HI_E_OFFSET 0x100 +#define MIB_RXBADBYTE_HI_NR_E 6 + +#define MIB_RXOVERFLOW "RxOverFlow" +#define MIB_RXOVERFLOW_ID 52 +#define MIB_RXOVERFLOW_OFFSET 0x2004c +#define MIB_RXOVERFLOW_E_LENGTH 4 +#define MIB_RXOVERFLOW_E_OFFSET 0x100 +#define MIB_RXOVERFLOW_NR_E 6 + +#define MIB_FILTERED "Filtered" +#define MIB_FILTERED_ID 53 +#define MIB_FILTERED_OFFSET 0x20050 +#define MIB_FILTERED_E_LENGTH 4 +#define MIB_FILTERED_E_OFFSET 0x100 +#define MIB_FILTERED_NR_E 6 + +#define MIB_TXBROAD "TxBroad" +#define MIB_TXBROAD_ID 54 +#define MIB_TXBROAD_OFFSET 0x20054 +#define MIB_TXBROAD_E_LENGTH 4 +#define MIB_TXBROAD_E_OFFSET 0x100 +#define MIB_TXBROAD_NR_E 6 + +#define MIB_TXPAUSE "TxPause" +#define MIB_TXPAUSE_ID 55 +#define MIB_TXPAUSE_OFFSET 0x20058 +#define MIB_TXPAUSE_E_LENGTH 4 +#define MIB_TXPAUSE_E_OFFSET 0x100 +#define MIB_TXPAUSE_NR_E 6 + +#define MIB_TXMULTI "TxMulti" +#define MIB_TXMULTI_ID 56 +#define MIB_TXMULTI_OFFSET 0x2005c +#define MIB_TXMULTI_E_LENGTH 4 +#define MIB_TXMULTI_E_OFFSET 0x100 +#define MIB_TXMULTI_NR_E 6 + +#define MIB_TXUNDERRUN "TxUnderRun" +#define MIB_TXUNDERRUN_ID 57 +#define MIB_TXUNDERRUN_OFFSET 0x20060 +#define MIB_TXUNDERRUN_E_LENGTH 4 +#define MIB_TXUNDERRUN_E_OFFSET 0x100 +#define MIB_TXUNDERRUN_NR_E 6 + +#define MIB_TX64BYTE "Tx64Byte" +#define MIB_TX64BYTE_ID 58 +#define MIB_TX64BYTE_OFFSET 0x20064 +#define MIB_TX64BYTE_E_LENGTH 4 +#define MIB_TX64BYTE_E_OFFSET 0x100 +#define MIB_TX64BYTE_NR_E 6 + +#define MIB_TX128BYTE "Tx128Byte" +#define MIB_TX128BYTE_ID 59 +#define MIB_TX128BYTE_OFFSET 0x20068 +#define MIB_TX128BYTE_E_LENGTH 4 +#define MIB_TX128BYTE_E_OFFSET 0x100 +#define MIB_TX128BYTE_NR_E 6 + +#define MIB_TX256BYTE "Tx256Byte" +#define MIB_TX256BYTE_ID 60 +#define MIB_TX256BYTE_OFFSET 0x2006c +#define MIB_TX256BYTE_E_LENGTH 4 +#define MIB_TX256BYTE_E_OFFSET 0x100 +#define MIB_TX256BYTE_NR_E 6 + +#define MIB_TX512BYTE "Tx512Byte" +#define MIB_TX512BYTE_ID 61 +#define MIB_TX512BYTE_OFFSET 0x20070 +#define MIB_TX512BYTE_E_LENGTH 4 +#define MIB_TX512BYTE_E_OFFSET 0x100 +#define MIB_TX512BYTE_NR_E 6 + +#define MIB_TX1024BYTE "Tx1024Byte" +#define MIB_TX1024BYTE_ID 62 +#define MIB_TX1024BYTE_OFFSET 0x20074 +#define MIB_TX1024BYTE_E_LENGTH 4 +#define MIB_TX1024BYTE_E_OFFSET 0x100 +#define MIB_TX1024BYTE_NR_E 6 + +#define MIB_TX1518BYTE "Tx1518Byte" +#define MIB_TX1518BYTE_ID 62 +#define MIB_TX1518BYTE_OFFSET 0x20078 +#define MIB_TX1518BYTE_E_LENGTH 4 +#define MIB_TX1518BYTE_E_OFFSET 0x100 +#define MIB_TX1518BYTE_NR_E 6 + +#define MIB_TXMAXBYTE "TxMaxByte" +#define MIB_TXMAXBYTE_ID 63 +#define MIB_TXMAXBYTE_OFFSET 0x2007c +#define MIB_TXMAXBYTE_E_LENGTH 4 +#define MIB_TXMAXBYTE_E_OFFSET 0x100 +#define MIB_TXMAXBYTE_NR_E 6 + +#define MIB_TXOVERSIZE "TxOverSize" +#define MIB_TXOVERSIZE_ID 64 +#define MIB_TXOVERSIZE_OFFSET 0x20080 +#define MIB_TXOVERSIZE_E_LENGTH 4 +#define MIB_TXOVERSIZE_E_OFFSET 0x100 +#define MIB_TXOVERSIZE_NR_E 6 + +#define MIB_TXBYTE_LO "TxByteLo" +#define MIB_TXBYTE_LO_ID 65 +#define MIB_TXBYTE_LO_OFFSET 0x20084 +#define MIB_TXBYTE_LO_E_LENGTH 4 +#define MIB_TXBYTE_LO_E_OFFSET 0x100 +#define MIB_TXBYTE_LO_NR_E 6 + +#define MIB_TXBYTE_HI "TxByteHi" +#define MIB_TXBYTE_HI_ID 66 +#define MIB_TXBYTE_HI_OFFSET 0x20088 +#define MIB_TXBYTE_HI_E_LENGTH 4 +#define MIB_TXBYTE_HI_E_OFFSET 0x100 +#define MIB_TXBYTE_HI_NR_E 6 + +#define MIB_TXCOLLISION "TxCollision" +#define MIB_TXCOLLISION_ID 67 +#define MIB_TXCOLLISION_OFFSET 0x2008c +#define MIB_TXCOLLISION_E_LENGTH 4 +#define MIB_TXCOLLISION_E_OFFSET 0x100 +#define MIB_TXCOLLISION_NR_E 6 + +#define MIB_TXABORTCOL "TxAbortCol" +#define MIB_TXABORTCOL_ID 68 +#define MIB_TXABORTCOL_OFFSET 0x20090 +#define MIB_TXABORTCOL_E_LENGTH 4 +#define MIB_TXABORTCOL_E_OFFSET 0x100 +#define MIB_TXABORTCOL_NR_E 6 + +#define MIB_TXMULTICOL "TxMultiCol" +#define MIB_TXMULTICOL_ID 69 +#define MIB_TXMULTICOL_OFFSET 0x20094 +#define MIB_TXMULTICOL_E_LENGTH 4 +#define MIB_TXMULTICOL_E_OFFSET 0x100 +#define MIB_TXMULTICOL_NR_E 6 + +#define MIB_TXSINGALCOL "TxSingalCol" +#define MIB_TXSINGALCOL_ID 70 +#define MIB_TXSINGALCOL_OFFSET 0x20098 +#define MIB_TXSINGALCOL_E_LENGTH 4 +#define MIB_TXSINGALCOL_E_OFFSET 0x100 +#define MIB_TXSINGALCOL_NR_E 6 + +#define MIB_TXEXCDEFER "TxExcDefer" +#define MIB_TXEXCDEFER_ID 71 +#define MIB_TXEXCDEFER_OFFSET 0x2009c +#define MIB_TXEXCDEFER_E_LENGTH 4 +#define MIB_TXEXCDEFER_E_OFFSET 0x100 +#define MIB_TXEXCDEFER_NR_E 6 + +#define MIB_TXDEFER "TxDefer" +#define MIB_TXDEFER_ID 72 +#define MIB_TXDEFER_OFFSET 0x200a0 +#define MIB_TXDEFER_E_LENGTH 4 +#define MIB_TXDEFER_E_OFFSET 0x100 +#define MIB_TXDEFER_NR_E 6 + +#define MIB_TXLATECOL "TxLateCol" +#define MIB_TXLATECOL_ID 73 +#define MIB_TXLATECOL_OFFSET 0x200a4 +#define MIB_TXLATECOL_E_LENGTH 4 +#define MIB_TXLATECOL_E_OFFSET 0x100 +#define MIB_TXLATECOL_NR_E 6 + + +#define PPPOE_SESSION "pppoes" +#define PPPOE_SESSION_ID 13 +#define PPPOE_SESSION_OFFSET 0x59100 +#define PPPOE_SESSION_E_LENGTH 4 +#define PPPOE_SESSION_E_OFFSET 0x4 +#define PPPOE_SESSION_NR_E 16 + +#define ENTRY_VALID "pppoes_v" +#define PPPOE_SESSION_ENTRY_VALID_BOFFSET 19 +#define PPPOE_SESSION_ENTRY_VALID_BLEN 1 +#define PPPOE_SESSION_ENTRY_VALID_FLAG HSL_RW + +#define STRIP_EN "pppoes_s" +#define PPPOE_SESSION_STRIP_EN_BOFFSET 16 +#define PPPOE_SESSION_STRIP_EN_BLEN 1 +#define PPPOE_SESSION_STRIP_EN_FLAG HSL_RW + +#define SEESION_ID "pppoes_id" +#define PPPOE_SESSION_SEESION_ID_BOFFSET 0 +#define PPPOE_SESSION_SEESION_ID_BLEN 16 +#define PPPOE_SESSION_SEESION_ID_FLAG HSL_RW + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _HORUS_REG_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_reg_access.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_reg_access.h new file mode 100755 index 000000000..a41ef6c03 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_reg_access.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2012,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 _HORUS_REG_ACCESS_H_ +#define _HORUS_REG_ACCESS_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "sw.h" + + sw_error_t + horus_phy_get(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t * value); + + sw_error_t + horus_phy_set(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t value); + + sw_error_t + horus_reg_get(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t value[], + a_uint32_t value_len); + + sw_error_t + horus_reg_set(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t value[], + a_uint32_t value_len); + + sw_error_t + horus_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 + horus_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 + horus_reg_access_init(a_uint32_t dev_id, hsl_access_mode mode); + + sw_error_t + horus_access_mode_set(a_uint32_t dev_id, hsl_access_mode mode); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _HORUS_REG_ACCESS_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_stp.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_stp.h new file mode 100755 index 000000000..ed228147e --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_stp.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 horus_stp HORUS_STP + * @{ + */ +#ifndef _HORUS_STP_H_ +#define _HORUS_STP_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_stp.h" + + sw_error_t horus_stp_init(a_uint32_t dev_id); + +#ifdef IN_STP +#define HORUS_STP_INIT(rv, dev_id) \ + { \ + rv = horus_stp_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define HORUS_STP_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + horus_stp_port_state_set(a_uint32_t dev_id, a_uint32_t st_id, + fal_port_t port_id, fal_stp_state_t state); + + + HSL_LOCAL sw_error_t + horus_stp_port_state_get(a_uint32_t dev_id, a_uint32_t st_id, + fal_port_t port_id, fal_stp_state_t * state); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _HORUS_STP_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_vlan.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_vlan.h new file mode 100755 index 000000000..9429131b0 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/horus/horus_vlan.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 horus_vlan HORUS_VLAN + * @{ + */ +#ifndef _HORUS_VLAN_H_ +#define _HORUS_VLAN_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_vlan.h" + + sw_error_t + horus_vlan_init(a_uint32_t dev_id); + +#ifdef IN_VLAN +#define HORUS_VLAN_INIT(rv, dev_id) \ + { \ + rv = horus_vlan_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define HORUS_VLAN_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + horus_vlan_entry_append(a_uint32_t dev_id, const fal_vlan_t * vlan_entry); + + + HSL_LOCAL sw_error_t + horus_vlan_create(a_uint32_t dev_id, a_uint32_t vlan_id); + + + HSL_LOCAL sw_error_t + horus_vlan_next(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan); + + + HSL_LOCAL sw_error_t + horus_vlan_find(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan); + + + HSL_LOCAL sw_error_t + horus_vlan_member_update(a_uint32_t dev_id, a_uint32_t vlan_id, + fal_pbmp_t member, fal_pbmp_t u_member); + + + HSL_LOCAL sw_error_t + horus_vlan_delete(a_uint32_t dev_id, a_uint32_t vlan_id); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _HORUS_VLAN_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_acl.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_acl.h new file mode 100755 index 000000000..ec2bb1332 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_acl.h @@ -0,0 +1,1256 @@ +/* + * 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 + * @{ + */ +#ifndef _HPPE_ACL_H_ +#define _HPPE_ACL_H_ + +#define IPO_RULE_REG_MAX_ENTRY 512 +#define IPO_MASK_REG_MAX_ENTRY 512 +#define RULE_EXT_1_REG_MAX_ENTRY 64 +#define RULE_EXT_2_REG_MAX_ENTRY 64 +#define RULE_EXT_4_REG_MAX_ENTRY 64 +#define IPO_ACTION_MAX_ENTRY 512 +#define IPO_CNT_TBL_MAX_ENTRY 512 + +sw_error_t +hppe_non_ip_udf0_ctrl_reg_get( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value); + +sw_error_t +hppe_non_ip_udf0_ctrl_reg_set( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value); + +sw_error_t +hppe_non_ip_udf1_ctrl_reg_get( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value); + +sw_error_t +hppe_non_ip_udf1_ctrl_reg_set( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value); + +sw_error_t +hppe_non_ip_udf2_ctrl_reg_get( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value); + +sw_error_t +hppe_non_ip_udf2_ctrl_reg_set( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value); + +sw_error_t +hppe_non_ip_udf3_ctrl_reg_get( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value); + +sw_error_t +hppe_non_ip_udf3_ctrl_reg_set( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value); + +sw_error_t +hppe_ipv4_udf0_ctrl_reg_get( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value); + +sw_error_t +hppe_ipv4_udf0_ctrl_reg_set( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value); + +sw_error_t +hppe_ipv4_udf1_ctrl_reg_get( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value); + +sw_error_t +hppe_ipv4_udf1_ctrl_reg_set( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value); + +sw_error_t +hppe_ipv4_udf2_ctrl_reg_get( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value); + +sw_error_t +hppe_ipv4_udf2_ctrl_reg_set( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value); + +sw_error_t +hppe_ipv4_udf3_ctrl_reg_get( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value); + +sw_error_t +hppe_ipv4_udf3_ctrl_reg_set( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value); + +sw_error_t +hppe_ipv6_udf0_ctrl_reg_get( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value); + +sw_error_t +hppe_ipv6_udf0_ctrl_reg_set( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value); + +sw_error_t +hppe_ipv6_udf1_ctrl_reg_get( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value); + +sw_error_t +hppe_ipv6_udf1_ctrl_reg_set( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value); + +sw_error_t +hppe_ipv6_udf2_ctrl_reg_get( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value); + +sw_error_t +hppe_ipv6_udf2_ctrl_reg_set( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value); + +sw_error_t +hppe_ipv6_udf3_ctrl_reg_get( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value); + +sw_error_t +hppe_ipv6_udf3_ctrl_reg_set( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value); + +sw_error_t +hppe_non_ip_udf0_ctrl_reg_udf0_base_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_non_ip_udf0_ctrl_reg_udf0_base_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_non_ip_udf0_ctrl_reg_udf0_offset_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_non_ip_udf0_ctrl_reg_udf0_offset_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_non_ip_udf1_ctrl_reg_udf1_base_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_non_ip_udf1_ctrl_reg_udf1_base_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_non_ip_udf1_ctrl_reg_udf1_offset_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_non_ip_udf1_ctrl_reg_udf1_offset_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_non_ip_udf2_ctrl_reg_udf2_offset_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_non_ip_udf2_ctrl_reg_udf2_offset_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_non_ip_udf2_ctrl_reg_udf2_base_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_non_ip_udf2_ctrl_reg_udf2_base_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_non_ip_udf3_ctrl_reg_udf3_base_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_non_ip_udf3_ctrl_reg_udf3_base_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_non_ip_udf3_ctrl_reg_udf3_offset_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_non_ip_udf3_ctrl_reg_udf3_offset_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_ipv4_udf0_ctrl_reg_udf0_base_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_ipv4_udf0_ctrl_reg_udf0_base_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_ipv4_udf0_ctrl_reg_udf0_offset_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_ipv4_udf0_ctrl_reg_udf0_offset_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_ipv4_udf1_ctrl_reg_udf1_base_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_ipv4_udf1_ctrl_reg_udf1_base_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_ipv4_udf1_ctrl_reg_udf1_offset_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_ipv4_udf1_ctrl_reg_udf1_offset_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_ipv4_udf2_ctrl_reg_udf2_offset_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_ipv4_udf2_ctrl_reg_udf2_offset_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_ipv4_udf2_ctrl_reg_udf2_base_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_ipv4_udf2_ctrl_reg_udf2_base_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_ipv4_udf3_ctrl_reg_udf3_base_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_ipv4_udf3_ctrl_reg_udf3_base_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_ipv4_udf3_ctrl_reg_udf3_offset_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_ipv4_udf3_ctrl_reg_udf3_offset_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_ipv6_udf0_ctrl_reg_udf0_base_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_ipv6_udf0_ctrl_reg_udf0_base_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_ipv6_udf0_ctrl_reg_udf0_offset_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_ipv6_udf0_ctrl_reg_udf0_offset_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_ipv6_udf1_ctrl_reg_udf1_base_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_ipv6_udf1_ctrl_reg_udf1_base_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_ipv6_udf1_ctrl_reg_udf1_offset_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_ipv6_udf1_ctrl_reg_udf1_offset_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_ipv6_udf2_ctrl_reg_udf2_offset_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_ipv6_udf2_ctrl_reg_udf2_offset_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_ipv6_udf2_ctrl_reg_udf2_base_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_ipv6_udf2_ctrl_reg_udf2_base_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_ipv6_udf3_ctrl_reg_udf3_base_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_ipv6_udf3_ctrl_reg_udf3_base_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_ipv6_udf3_ctrl_reg_udf3_offset_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_ipv6_udf3_ctrl_reg_udf3_offset_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_ipo_rule_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + union ipo_rule_reg_u *value); + +sw_error_t +hppe_ipo_rule_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + union ipo_rule_reg_u *value); + +sw_error_t +hppe_ipo_mask_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + union ipo_mask_reg_u *value); + +sw_error_t +hppe_ipo_mask_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + union ipo_mask_reg_u *value); + +sw_error_t +hppe_rule_ext_1_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + union rule_ext_1_reg_u *value); + +sw_error_t +hppe_rule_ext_1_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + union rule_ext_1_reg_u *value); + +sw_error_t +hppe_rule_ext_2_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + union rule_ext_2_reg_u *value); + +sw_error_t +hppe_rule_ext_2_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + union rule_ext_2_reg_u *value); + +sw_error_t +hppe_rule_ext_4_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + union rule_ext_4_reg_u *value); + +sw_error_t +hppe_rule_ext_4_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + union rule_ext_4_reg_u *value); + +sw_error_t +hppe_ipo_dbg_addr_reg_get( + a_uint32_t dev_id, + union ipo_dbg_addr_reg_u *value); + +sw_error_t +hppe_ipo_dbg_addr_reg_set( + a_uint32_t dev_id, + union ipo_dbg_addr_reg_u *value); + +sw_error_t +hppe_ipo_dbg_data_reg_get( + a_uint32_t dev_id, + union ipo_dbg_data_reg_u *value); + +sw_error_t +hppe_ipo_dbg_data_reg_set( + a_uint32_t dev_id, + union ipo_dbg_data_reg_u *value); + +sw_error_t +hppe_ipo_spare_reg_reg_get( + a_uint32_t dev_id, + union ipo_spare_reg_reg_u *value); + +sw_error_t +hppe_ipo_spare_reg_reg_set( + a_uint32_t dev_id, + union ipo_spare_reg_reg_u *value); + +sw_error_t +hppe_ipo_glb_hit_counter_reg_get( + a_uint32_t dev_id, + union ipo_glb_hit_counter_reg_u *value); + +sw_error_t +hppe_ipo_glb_hit_counter_reg_set( + a_uint32_t dev_id, + union ipo_glb_hit_counter_reg_u *value); + +sw_error_t +hppe_ipo_glb_miss_counter_reg_get( + a_uint32_t dev_id, + union ipo_glb_miss_counter_reg_u *value); + +sw_error_t +hppe_ipo_glb_miss_counter_reg_set( + a_uint32_t dev_id, + union ipo_glb_miss_counter_reg_u *value); + +sw_error_t +hppe_ipo_glb_bypass_counter_reg_get( + a_uint32_t dev_id, + union ipo_glb_bypass_counter_reg_u *value); + +sw_error_t +hppe_ipo_glb_bypass_counter_reg_set( + a_uint32_t dev_id, + union ipo_glb_bypass_counter_reg_u *value); + +sw_error_t +hppe_ipo_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union ipo_cnt_tbl_u *value); + +sw_error_t +hppe_ipo_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union ipo_cnt_tbl_u *value); + +sw_error_t +hppe_ipo_cnt_tbl_hit_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_ipo_cnt_tbl_hit_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_ipo_cnt_tbl_hit_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_cnt_tbl_hit_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); +sw_error_t +hppe_ipo_rule_reg_src_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_rule_reg_src_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_rule_reg_inverse_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_rule_reg_inverse_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_rule_reg_rule_type_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_rule_reg_rule_type_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_rule_reg_src_type_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_rule_reg_src_type_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_rule_reg_range_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_rule_reg_range_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_rule_reg_post_routing_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_rule_reg_post_routing_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_rule_reg_fake_mac_header_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_rule_reg_fake_mac_header_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_rule_reg_res_chain_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_rule_reg_res_chain_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_rule_reg_pri_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_rule_reg_pri_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_rule_reg_rule_field_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_ipo_rule_reg_rule_field_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_ipo_mask_reg_maskfield_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_ipo_mask_reg_maskfield_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_rule_ext_1_reg_ext2_2_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rule_ext_1_reg_ext2_2_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rule_ext_1_reg_ext2_0_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rule_ext_1_reg_ext2_0_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rule_ext_1_reg_ext2_3_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rule_ext_1_reg_ext2_3_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rule_ext_1_reg_ext2_1_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rule_ext_1_reg_ext2_1_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rule_ext_2_reg_ext4_0_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rule_ext_2_reg_ext4_0_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rule_ext_2_reg_ext4_1_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rule_ext_2_reg_ext4_1_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rule_ext_4_reg_ext8_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rule_ext_4_reg_ext8_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_dbg_addr_reg_ipo_dbg_addr_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_ipo_dbg_addr_reg_ipo_dbg_addr_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_ipo_dbg_data_reg_ipo_dbg_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_ipo_dbg_data_reg_ipo_dbg_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_ipo_spare_reg_reg_spare_reg_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_ipo_spare_reg_reg_spare_reg_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_ipo_glb_hit_counter_reg_hit_count_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_ipo_glb_hit_counter_reg_hit_count_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_ipo_glb_miss_counter_reg_miss_count_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_ipo_glb_miss_counter_reg_miss_count_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_ipo_glb_bypass_counter_reg_bypass_count_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_ipo_glb_bypass_counter_reg_bypass_count_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_ipo_action_get( + a_uint32_t dev_id, + a_uint32_t index, + union ipo_action_u *value); + +sw_error_t +hppe_ipo_action_set( + a_uint32_t dev_id, + a_uint32_t index, + union ipo_action_u *value); + +sw_error_t +hppe_ipo_action_mirror_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_mirror_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_action_ctag_pcp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_ctag_pcp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_action_int_dp_change_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_int_dp_change_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_action_enqueue_pri_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_enqueue_pri_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_action_stag_pcp_change_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_stag_pcp_change_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_action_dscp_tc_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_dscp_tc_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_action_cpu_code_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_cpu_code_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_action_stag_dei_change_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_stag_dei_change_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_action_ctag_fmt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_ctag_fmt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_action_dest_info_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_dest_info_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_action_svid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_svid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_action_dest_info_change_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_dest_info_change_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_action_policer_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_policer_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_action_int_dp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_int_dp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_action_ctag_pcp_change_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_ctag_pcp_change_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_action_metadata_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_metadata_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_action_enqueue_pri_change_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_enqueue_pri_change_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_action_stag_dei_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_stag_dei_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_action_fwd_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_fwd_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_action_bypass_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_bypass_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_action_ctag_dei_change_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_ctag_dei_change_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_action_policer_index_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_policer_index_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_action_ctag_dei_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_ctag_dei_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_action_stag_pcp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_stag_pcp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_action_syn_toggle_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_syn_toggle_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_action_service_code_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_service_code_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_action_qid_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_qid_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_action_service_code_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_service_code_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_action_cvid_change_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_cvid_change_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_action_cvid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_cvid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_action_svid_change_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_svid_change_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_action_cpu_code_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_cpu_code_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_action_dscp_tc_change_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_dscp_tc_change_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_action_qid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_qid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipo_action_stag_fmt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipo_action_stag_fmt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + + +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_acl_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_acl_reg.h new file mode 100755 index 000000000..db18ea4e7 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_acl_reg.h @@ -0,0 +1,842 @@ +/* + * 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 + * @{ + */ +#ifndef HPPE_ACL_REG_H +#define HPPE_ACL_REG_H + +/*[register] NON_IP_UDF0_CTRL_REG*/ +#define NON_IP_UDF0_CTRL_REG +#define NON_IP_UDF0_CTRL_REG_ADDRESS 0x38 +#define NON_IP_UDF0_CTRL_REG_NUM 1 +#define NON_IP_UDF0_CTRL_REG_INC 0x4 +#define NON_IP_UDF0_CTRL_REG_TYPE REG_TYPE_RW +#define NON_IP_UDF0_CTRL_REG_DEFAULT 0x0 + /*[field] UDF0_BASE*/ + #define NON_IP_UDF0_CTRL_REG_UDF0_BASE + #define NON_IP_UDF0_CTRL_REG_UDF0_BASE_OFFSET 0 + #define NON_IP_UDF0_CTRL_REG_UDF0_BASE_LEN 2 + #define NON_IP_UDF0_CTRL_REG_UDF0_BASE_DEFAULT 0x0 + /*[field] UDF0_OFFSET*/ + #define NON_IP_UDF0_CTRL_REG_UDF0_OFFSET + #define NON_IP_UDF0_CTRL_REG_UDF0_OFFSET_OFFSET 8 + #define NON_IP_UDF0_CTRL_REG_UDF0_OFFSET_LEN 6 + #define NON_IP_UDF0_CTRL_REG_UDF0_OFFSET_DEFAULT 0x0 + +struct udf_ctrl_reg { + a_uint32_t udf_base:2; + a_uint32_t _reserved0:6; + a_uint32_t udf_offset:6; + a_uint32_t _reserved1:18; +}; + +union udf_ctrl_reg_u { + a_uint32_t val; + struct udf_ctrl_reg bf; +}; + +/*[register] NON_IP_UDF1_CTRL_REG*/ +#define NON_IP_UDF1_CTRL_REG +#define NON_IP_UDF1_CTRL_REG_ADDRESS 0x3c +#define NON_IP_UDF1_CTRL_REG_NUM 1 +#define NON_IP_UDF1_CTRL_REG_INC 0x4 +#define NON_IP_UDF1_CTRL_REG_TYPE REG_TYPE_RW +#define NON_IP_UDF1_CTRL_REG_DEFAULT 0x0 + /*[field] UDF1_BASE*/ + #define NON_IP_UDF1_CTRL_REG_UDF1_BASE + #define NON_IP_UDF1_CTRL_REG_UDF1_BASE_OFFSET 0 + #define NON_IP_UDF1_CTRL_REG_UDF1_BASE_LEN 2 + #define NON_IP_UDF1_CTRL_REG_UDF1_BASE_DEFAULT 0x0 + /*[field] UDF1_OFFSET*/ + #define NON_IP_UDF1_CTRL_REG_UDF1_OFFSET + #define NON_IP_UDF1_CTRL_REG_UDF1_OFFSET_OFFSET 8 + #define NON_IP_UDF1_CTRL_REG_UDF1_OFFSET_LEN 6 + #define NON_IP_UDF1_CTRL_REG_UDF1_OFFSET_DEFAULT 0x0 + +/*[register] NON_IP_UDF2_CTRL_REG*/ +#define NON_IP_UDF2_CTRL_REG +#define NON_IP_UDF2_CTRL_REG_ADDRESS 0x40 +#define NON_IP_UDF2_CTRL_REG_NUM 1 +#define NON_IP_UDF2_CTRL_REG_INC 0x4 +#define NON_IP_UDF2_CTRL_REG_TYPE REG_TYPE_RW +#define NON_IP_UDF2_CTRL_REG_DEFAULT 0x0 + /*[field] UDF2_BASE*/ + #define NON_IP_UDF2_CTRL_REG_UDF2_BASE + #define NON_IP_UDF2_CTRL_REG_UDF2_BASE_OFFSET 0 + #define NON_IP_UDF2_CTRL_REG_UDF2_BASE_LEN 2 + #define NON_IP_UDF2_CTRL_REG_UDF2_BASE_DEFAULT 0x0 + /*[field] UDF2_OFFSET*/ + #define NON_IP_UDF2_CTRL_REG_UDF2_OFFSET + #define NON_IP_UDF2_CTRL_REG_UDF2_OFFSET_OFFSET 8 + #define NON_IP_UDF2_CTRL_REG_UDF2_OFFSET_LEN 6 + #define NON_IP_UDF2_CTRL_REG_UDF2_OFFSET_DEFAULT 0x0 + +/*[register] NON_IP_UDF3_CTRL_REG*/ +#define NON_IP_UDF3_CTRL_REG +#define NON_IP_UDF3_CTRL_REG_ADDRESS 0x44 +#define NON_IP_UDF3_CTRL_REG_NUM 1 +#define NON_IP_UDF3_CTRL_REG_INC 0x4 +#define NON_IP_UDF3_CTRL_REG_TYPE REG_TYPE_RW +#define NON_IP_UDF3_CTRL_REG_DEFAULT 0x0 + /*[field] UDF3_BASE*/ + #define NON_IP_UDF3_CTRL_REG_UDF3_BASE + #define NON_IP_UDF3_CTRL_REG_UDF3_BASE_OFFSET 0 + #define NON_IP_UDF3_CTRL_REG_UDF3_BASE_LEN 2 + #define NON_IP_UDF3_CTRL_REG_UDF3_BASE_DEFAULT 0x0 + /*[field] UDF3_OFFSET*/ + #define NON_IP_UDF3_CTRL_REG_UDF3_OFFSET + #define NON_IP_UDF3_CTRL_REG_UDF3_OFFSET_OFFSET 8 + #define NON_IP_UDF3_CTRL_REG_UDF3_OFFSET_LEN 6 + #define NON_IP_UDF3_CTRL_REG_UDF3_OFFSET_DEFAULT 0x0 + +/*[register] IPV4_UDF0_CTRL_REG*/ +#define IPV4_UDF0_CTRL_REG +#define IPV4_UDF0_CTRL_REG_ADDRESS 0x48 +#define IPV4_UDF0_CTRL_REG_NUM 1 +#define IPV4_UDF0_CTRL_REG_INC 0x4 +#define IPV4_UDF0_CTRL_REG_TYPE REG_TYPE_RW +#define IPV4_UDF0_CTRL_REG_DEFAULT 0x0 + /*[field] UDF0_BASE*/ + #define IPV4_UDF0_CTRL_REG_UDF0_BASE + #define IPV4_UDF0_CTRL_REG_UDF0_BASE_OFFSET 0 + #define IPV4_UDF0_CTRL_REG_UDF0_BASE_LEN 2 + #define IPV4_UDF0_CTRL_REG_UDF0_BASE_DEFAULT 0x0 + /*[field] UDF0_OFFSET*/ + #define IPV4_UDF0_CTRL_REG_UDF0_OFFSET + #define IPV4_UDF0_CTRL_REG_UDF0_OFFSET_OFFSET 8 + #define IPV4_UDF0_CTRL_REG_UDF0_OFFSET_LEN 6 + #define IPV4_UDF0_CTRL_REG_UDF0_OFFSET_DEFAULT 0x0 + +/*[register] IPV4_UDF1_CTRL_REG*/ +#define IPV4_UDF1_CTRL_REG +#define IPV4_UDF1_CTRL_REG_ADDRESS 0x4c +#define IPV4_UDF1_CTRL_REG_NUM 1 +#define IPV4_UDF1_CTRL_REG_INC 0x4 +#define IPV4_UDF1_CTRL_REG_TYPE REG_TYPE_RW +#define IPV4_UDF1_CTRL_REG_DEFAULT 0x0 + /*[field] UDF1_BASE*/ + #define IPV4_UDF1_CTRL_REG_UDF1_BASE + #define IPV4_UDF1_CTRL_REG_UDF1_BASE_OFFSET 0 + #define IPV4_UDF1_CTRL_REG_UDF1_BASE_LEN 2 + #define IPV4_UDF1_CTRL_REG_UDF1_BASE_DEFAULT 0x0 + /*[field] UDF1_OFFSET*/ + #define IPV4_UDF1_CTRL_REG_UDF1_OFFSET + #define IPV4_UDF1_CTRL_REG_UDF1_OFFSET_OFFSET 8 + #define IPV4_UDF1_CTRL_REG_UDF1_OFFSET_LEN 6 + #define IPV4_UDF1_CTRL_REG_UDF1_OFFSET_DEFAULT 0x0 + +/*[register] IPV4_UDF2_CTRL_REG*/ +#define IPV4_UDF2_CTRL_REG +#define IPV4_UDF2_CTRL_REG_ADDRESS 0x50 +#define IPV4_UDF2_CTRL_REG_NUM 1 +#define IPV4_UDF2_CTRL_REG_INC 0x4 +#define IPV4_UDF2_CTRL_REG_TYPE REG_TYPE_RW +#define IPV4_UDF2_CTRL_REG_DEFAULT 0x0 + /*[field] UDF2_BASE*/ + #define IPV4_UDF2_CTRL_REG_UDF2_BASE + #define IPV4_UDF2_CTRL_REG_UDF2_BASE_OFFSET 0 + #define IPV4_UDF2_CTRL_REG_UDF2_BASE_LEN 2 + #define IPV4_UDF2_CTRL_REG_UDF2_BASE_DEFAULT 0x0 + /*[field] UDF2_OFFSET*/ + #define IPV4_UDF2_CTRL_REG_UDF2_OFFSET + #define IPV4_UDF2_CTRL_REG_UDF2_OFFSET_OFFSET 8 + #define IPV4_UDF2_CTRL_REG_UDF2_OFFSET_LEN 6 + #define IPV4_UDF2_CTRL_REG_UDF2_OFFSET_DEFAULT 0x0 + +/*[register] IPV4_UDF3_CTRL_REG*/ +#define IPV4_UDF3_CTRL_REG +#define IPV4_UDF3_CTRL_REG_ADDRESS 0x54 +#define IPV4_UDF3_CTRL_REG_NUM 1 +#define IPV4_UDF3_CTRL_REG_INC 0x4 +#define IPV4_UDF3_CTRL_REG_TYPE REG_TYPE_RW +#define IPV4_UDF3_CTRL_REG_DEFAULT 0x0 + /*[field] UDF3_BASE*/ + #define IPV4_UDF3_CTRL_REG_UDF3_BASE + #define IPV4_UDF3_CTRL_REG_UDF3_BASE_OFFSET 0 + #define IPV4_UDF3_CTRL_REG_UDF3_BASE_LEN 2 + #define IPV4_UDF3_CTRL_REG_UDF3_BASE_DEFAULT 0x0 + /*[field] UDF3_OFFSET*/ + #define IPV4_UDF3_CTRL_REG_UDF3_OFFSET + #define IPV4_UDF3_CTRL_REG_UDF3_OFFSET_OFFSET 8 + #define IPV4_UDF3_CTRL_REG_UDF3_OFFSET_LEN 6 + #define IPV4_UDF3_CTRL_REG_UDF3_OFFSET_DEFAULT 0x0 + +/*[register] IPV6_UDF0_CTRL_REG*/ +#define IPV6_UDF0_CTRL_REG +#define IPV6_UDF0_CTRL_REG_ADDRESS 0x58 +#define IPV6_UDF0_CTRL_REG_NUM 1 +#define IPV6_UDF0_CTRL_REG_INC 0x4 +#define IPV6_UDF0_CTRL_REG_TYPE REG_TYPE_RW +#define IPV6_UDF0_CTRL_REG_DEFAULT 0x0 + /*[field] UDF0_BASE*/ + #define IPV6_UDF0_CTRL_REG_UDF0_BASE + #define IPV6_UDF0_CTRL_REG_UDF0_BASE_OFFSET 0 + #define IPV6_UDF0_CTRL_REG_UDF0_BASE_LEN 2 + #define IPV6_UDF0_CTRL_REG_UDF0_BASE_DEFAULT 0x0 + /*[field] UDF0_OFFSET*/ + #define IPV6_UDF0_CTRL_REG_UDF0_OFFSET + #define IPV6_UDF0_CTRL_REG_UDF0_OFFSET_OFFSET 8 + #define IPV6_UDF0_CTRL_REG_UDF0_OFFSET_LEN 6 + #define IPV6_UDF0_CTRL_REG_UDF0_OFFSET_DEFAULT 0x0 + +/*[register] IPV6_UDF1_CTRL_REG*/ +#define IPV6_UDF1_CTRL_REG +#define IPV6_UDF1_CTRL_REG_ADDRESS 0x5c +#define IPV6_UDF1_CTRL_REG_NUM 1 +#define IPV6_UDF1_CTRL_REG_INC 0x4 +#define IPV6_UDF1_CTRL_REG_TYPE REG_TYPE_RW +#define IPV6_UDF1_CTRL_REG_DEFAULT 0x0 + /*[field] UDF1_BASE*/ + #define IPV6_UDF1_CTRL_REG_UDF1_BASE + #define IPV6_UDF1_CTRL_REG_UDF1_BASE_OFFSET 0 + #define IPV6_UDF1_CTRL_REG_UDF1_BASE_LEN 2 + #define IPV6_UDF1_CTRL_REG_UDF1_BASE_DEFAULT 0x0 + /*[field] UDF1_OFFSET*/ + #define IPV6_UDF1_CTRL_REG_UDF1_OFFSET + #define IPV6_UDF1_CTRL_REG_UDF1_OFFSET_OFFSET 8 + #define IPV6_UDF1_CTRL_REG_UDF1_OFFSET_LEN 6 + #define IPV6_UDF1_CTRL_REG_UDF1_OFFSET_DEFAULT 0x0 + +/*[register] IPV6_UDF2_CTRL_REG*/ +#define IPV6_UDF2_CTRL_REG +#define IPV6_UDF2_CTRL_REG_ADDRESS 0x60 +#define IPV6_UDF2_CTRL_REG_NUM 1 +#define IPV6_UDF2_CTRL_REG_INC 0x4 +#define IPV6_UDF2_CTRL_REG_TYPE REG_TYPE_RW +#define IPV6_UDF2_CTRL_REG_DEFAULT 0x0 + /*[field] UDF2_BASE*/ + #define IPV6_UDF2_CTRL_REG_UDF2_BASE + #define IPV6_UDF2_CTRL_REG_UDF2_BASE_OFFSET 0 + #define IPV6_UDF2_CTRL_REG_UDF2_BASE_LEN 2 + #define IPV6_UDF2_CTRL_REG_UDF2_BASE_DEFAULT 0x0 + /*[field] UDF2_OFFSET*/ + #define IPV6_UDF2_CTRL_REG_UDF2_OFFSET + #define IPV6_UDF2_CTRL_REG_UDF2_OFFSET_OFFSET 8 + #define IPV6_UDF2_CTRL_REG_UDF2_OFFSET_LEN 6 + #define IPV6_UDF2_CTRL_REG_UDF2_OFFSET_DEFAULT 0x0 + +/*[register] IPV6_UDF3_CTRL_REG*/ +#define IPV6_UDF3_CTRL_REG +#define IPV6_UDF3_CTRL_REG_ADDRESS 0x64 +#define IPV6_UDF3_CTRL_REG_NUM 1 +#define IPV6_UDF3_CTRL_REG_INC 0x4 +#define IPV6_UDF3_CTRL_REG_TYPE REG_TYPE_RW +#define IPV6_UDF3_CTRL_REG_DEFAULT 0x0 + /*[field] UDF3_BASE*/ + #define IPV6_UDF3_CTRL_REG_UDF3_BASE + #define IPV6_UDF3_CTRL_REG_UDF3_BASE_OFFSET 0 + #define IPV6_UDF3_CTRL_REG_UDF3_BASE_LEN 2 + #define IPV6_UDF3_CTRL_REG_UDF3_BASE_DEFAULT 0x0 + /*[field] UDF3_OFFSET*/ + #define IPV6_UDF3_CTRL_REG_UDF3_OFFSET + #define IPV6_UDF3_CTRL_REG_UDF3_OFFSET_OFFSET 8 + #define IPV6_UDF3_CTRL_REG_UDF3_OFFSET_LEN 6 + #define IPV6_UDF3_CTRL_REG_UDF3_OFFSET_DEFAULT 0x0 + +/*[table] IPO_RULE_REG*/ +#define IPO_RULE_REG +#define IPO_RULE_REG_ADDRESS 0x0 +#define IPO_RULE_REG_NUM 512 +#define IPO_RULE_REG_INC 0x10 +#define IPO_RULE_REG_TYPE REG_TYPE_RW +#define IPO_RULE_REG_DEFAULT 0x0 + /*[field] RULE_FIELD*/ + #define IPO_RULE_REG_RULE_FIELD + #define IPO_RULE_REG_RULE_FIELD_OFFSET 0 + #define IPO_RULE_REG_RULE_FIELD_LEN 52 + #define IPO_RULE_REG_RULE_FIELD_DEFAULT 0x0 + /*[field] FAKE_MAC_HEADER*/ + #define IPO_RULE_REG_FAKE_MAC_HEADER + #define IPO_RULE_REG_FAKE_MAC_HEADER_OFFSET 52 + #define IPO_RULE_REG_FAKE_MAC_HEADER_LEN 1 + #define IPO_RULE_REG_FAKE_MAC_HEADER_DEFAULT 0x0 + /*[field] RANGE_EN*/ + #define IPO_RULE_REG_RANGE_EN + #define IPO_RULE_REG_RANGE_EN_OFFSET 53 + #define IPO_RULE_REG_RANGE_EN_LEN 1 + #define IPO_RULE_REG_RANGE_EN_DEFAULT 0x0 + /*[field] INVERSE_EN*/ + #define IPO_RULE_REG_INVERSE_EN + #define IPO_RULE_REG_INVERSE_EN_OFFSET 54 + #define IPO_RULE_REG_INVERSE_EN_LEN 1 + #define IPO_RULE_REG_INVERSE_EN_DEFAULT 0x0 + /*[field] RULE_TYPE*/ + #define IPO_RULE_REG_RULE_TYPE + #define IPO_RULE_REG_RULE_TYPE_OFFSET 55 + #define IPO_RULE_REG_RULE_TYPE_LEN 4 + #define IPO_RULE_REG_RULE_TYPE_DEFAULT 0x0 + /*[field] SRC_TYPE*/ + #define IPO_RULE_REG_SRC_TYPE + #define IPO_RULE_REG_SRC_TYPE_OFFSET 59 + #define IPO_RULE_REG_SRC_TYPE_LEN 2 + #define IPO_RULE_REG_SRC_TYPE_DEFAULT 0x0 + /*[field] SRC*/ + #define IPO_RULE_REG_SRC + #define IPO_RULE_REG_SRC_OFFSET 61 + #define IPO_RULE_REG_SRC_LEN 8 + #define IPO_RULE_REG_SRC_DEFAULT 0x0 + /*[field] PRI*/ + #define IPO_RULE_REG_PRI + #define IPO_RULE_REG_PRI_OFFSET 69 + #define IPO_RULE_REG_PRI_LEN 9 + #define IPO_RULE_REG_PRI_DEFAULT 0x0 + /*[field] RES_CHAIN*/ + #define IPO_RULE_REG_RES_CHAIN + #define IPO_RULE_REG_RES_CHAIN_OFFSET 78 + #define IPO_RULE_REG_RES_CHAIN_LEN 1 + #define IPO_RULE_REG_RES_CHAIN_DEFAULT 0x0 + /*[field] POST_ROUTING_EN*/ + #define IPO_RULE_REG_POST_ROUTING_EN + #define IPO_RULE_REG_POST_ROUTING_EN_OFFSET 79 + #define IPO_RULE_REG_POST_ROUTING_EN_LEN 1 + #define IPO_RULE_REG_POST_ROUTING_EN_DEFAULT 0x0 + +struct ipo_rule_reg { + a_uint32_t rule_field_0:32; + a_uint32_t rule_field_1:20; + a_uint32_t fake_mac_header:1; + a_uint32_t range_en:1; + a_uint32_t inverse_en:1; + a_uint32_t rule_type:4; + a_uint32_t src_type:2; + a_uint32_t src_0:3; + a_uint32_t src_1:5; + a_uint32_t pri:9; + a_uint32_t res_chain:1; + a_uint32_t post_routing_en:1; + a_uint32_t _reserved0:16; +}; + +union ipo_rule_reg_u { + a_uint32_t val[3]; + struct ipo_rule_reg bf; +}; + +/*[table] IPO_MASK_REG*/ +#define IPO_MASK_REG +#define IPO_MASK_REG_ADDRESS 0x2000 +#define IPO_MASK_REG_NUM 512 +#define IPO_MASK_REG_INC 0x10 +#define IPO_MASK_REG_TYPE REG_TYPE_RW +#define IPO_MASK_REG_DEFAULT 0x0 + /*[field] MASKFIELD*/ + #define IPO_MASK_REG_MASKFIELD + #define IPO_MASK_REG_MASKFIELD_OFFSET 0 + #define IPO_MASK_REG_MASKFIELD_LEN 53 + #define IPO_MASK_REG_MASKFIELD_DEFAULT 0x0 + +struct ipo_mask_reg { + a_uint32_t maskfield_0:32; + a_uint32_t maskfield_1:21; + a_uint32_t _reserved0:11; +}; + +union ipo_mask_reg_u { + a_uint32_t val[2]; + struct ipo_mask_reg bf; +}; + +/*[register] RULE_EXT_1_REG*/ +#define RULE_EXT_1_REG +#define RULE_EXT_1_REG_ADDRESS 0x4000 +#define RULE_EXT_1_REG_NUM 64 +#define RULE_EXT_1_REG_INC 0x4 +#define RULE_EXT_1_REG_TYPE REG_TYPE_RW +#define RULE_EXT_1_REG_DEFAULT 0x0 + /*[field] EXT2_0*/ + #define RULE_EXT_1_REG_EXT2_0 + #define RULE_EXT_1_REG_EXT2_0_OFFSET 0 + #define RULE_EXT_1_REG_EXT2_0_LEN 1 + #define RULE_EXT_1_REG_EXT2_0_DEFAULT 0x0 + /*[field] EXT2_1*/ + #define RULE_EXT_1_REG_EXT2_1 + #define RULE_EXT_1_REG_EXT2_1_OFFSET 1 + #define RULE_EXT_1_REG_EXT2_1_LEN 1 + #define RULE_EXT_1_REG_EXT2_1_DEFAULT 0x0 + /*[field] EXT2_2*/ + #define RULE_EXT_1_REG_EXT2_2 + #define RULE_EXT_1_REG_EXT2_2_OFFSET 2 + #define RULE_EXT_1_REG_EXT2_2_LEN 1 + #define RULE_EXT_1_REG_EXT2_2_DEFAULT 0x0 + /*[field] EXT2_3*/ + #define RULE_EXT_1_REG_EXT2_3 + #define RULE_EXT_1_REG_EXT2_3_OFFSET 3 + #define RULE_EXT_1_REG_EXT2_3_LEN 1 + #define RULE_EXT_1_REG_EXT2_3_DEFAULT 0x0 + +struct rule_ext_1_reg { + a_uint32_t ext2_0:1; + a_uint32_t ext2_1:1; + a_uint32_t ext2_2:1; + a_uint32_t ext2_3:1; + a_uint32_t _reserved0:28; +}; + +union rule_ext_1_reg_u { + a_uint32_t val; + struct rule_ext_1_reg bf; +}; + +/*[register] RULE_EXT_2_REG*/ +#define RULE_EXT_2_REG +#define RULE_EXT_2_REG_ADDRESS 0x4100 +#define RULE_EXT_2_REG_NUM 64 +#define RULE_EXT_2_REG_INC 0x4 +#define RULE_EXT_2_REG_TYPE REG_TYPE_RW +#define RULE_EXT_2_REG_DEFAULT 0x0 + /*[field] EXT4_0*/ + #define RULE_EXT_2_REG_EXT4_0 + #define RULE_EXT_2_REG_EXT4_0_OFFSET 0 + #define RULE_EXT_2_REG_EXT4_0_LEN 1 + #define RULE_EXT_2_REG_EXT4_0_DEFAULT 0x0 + /*[field] EXT4_1*/ + #define RULE_EXT_2_REG_EXT4_1 + #define RULE_EXT_2_REG_EXT4_1_OFFSET 1 + #define RULE_EXT_2_REG_EXT4_1_LEN 1 + #define RULE_EXT_2_REG_EXT4_1_DEFAULT 0x0 + +struct rule_ext_2_reg { + a_uint32_t ext4_0:1; + a_uint32_t ext4_1:1; + a_uint32_t _reserved0:30; +}; + +union rule_ext_2_reg_u { + a_uint32_t val; + struct rule_ext_2_reg bf; +}; + +/*[register] RULE_EXT_4_REG*/ +#define RULE_EXT_4_REG +#define RULE_EXT_4_REG_ADDRESS 0x4200 +#define RULE_EXT_4_REG_NUM 64 +#define RULE_EXT_4_REG_INC 0x4 +#define RULE_EXT_4_REG_TYPE REG_TYPE_RW +#define RULE_EXT_4_REG_DEFAULT 0x0 + /*[field] EXT8*/ + #define RULE_EXT_4_REG_EXT8 + #define RULE_EXT_4_REG_EXT8_OFFSET 0 + #define RULE_EXT_4_REG_EXT8_LEN 1 + #define RULE_EXT_4_REG_EXT8_DEFAULT 0x0 + +struct rule_ext_4_reg { + a_uint32_t ext8:1; + a_uint32_t _reserved0:31; +}; + +union rule_ext_4_reg_u { + a_uint32_t val; + struct rule_ext_4_reg bf; +}; + +/*[register] IPO_DBG_ADDR_REG*/ +#define IPO_DBG_ADDR_REG +#define IPO_DBG_ADDR_REG_ADDRESS 0x4300 +#define IPO_DBG_ADDR_REG_NUM 1 +#define IPO_DBG_ADDR_REG_INC 0x4 +#define IPO_DBG_ADDR_REG_TYPE REG_TYPE_RW +#define IPO_DBG_ADDR_REG_DEFAULT 0x0 + /*[field] IPO_DBG_ADDR*/ + #define IPO_DBG_ADDR_REG_IPO_DBG_ADDR + #define IPO_DBG_ADDR_REG_IPO_DBG_ADDR_OFFSET 0 + #define IPO_DBG_ADDR_REG_IPO_DBG_ADDR_LEN 32 + #define IPO_DBG_ADDR_REG_IPO_DBG_ADDR_DEFAULT 0x0 + +struct ipo_dbg_addr_reg { + a_uint32_t ipo_dbg_addr:32; +}; + +union ipo_dbg_addr_reg_u { + a_uint32_t val; + struct ipo_dbg_addr_reg bf; +}; + +/*[register] IPO_DBG_DATA_REG*/ +#define IPO_DBG_DATA_REG +#define IPO_DBG_DATA_REG_ADDRESS 0x4304 +#define IPO_DBG_DATA_REG_NUM 1 +#define IPO_DBG_DATA_REG_INC 0x4 +#define IPO_DBG_DATA_REG_TYPE REG_TYPE_RO +#define IPO_DBG_DATA_REG_DEFAULT 0x0 + /*[field] IPO_DBG_DATA*/ + #define IPO_DBG_DATA_REG_IPO_DBG_DATA + #define IPO_DBG_DATA_REG_IPO_DBG_DATA_OFFSET 0 + #define IPO_DBG_DATA_REG_IPO_DBG_DATA_LEN 32 + #define IPO_DBG_DATA_REG_IPO_DBG_DATA_DEFAULT 0x0 + +struct ipo_dbg_data_reg { + a_uint32_t ipo_dbg_data:32; +}; + +union ipo_dbg_data_reg_u { + a_uint32_t val; + struct ipo_dbg_data_reg bf; +}; + +/*[register] IPO_SPARE_REG_REG*/ +#define IPO_SPARE_REG_REG +#define IPO_SPARE_REG_REG_ADDRESS 0x4308 +#define IPO_SPARE_REG_REG_NUM 1 +#define IPO_SPARE_REG_REG_INC 0x4 +#define IPO_SPARE_REG_REG_TYPE REG_TYPE_RW +#define IPO_SPARE_REG_REG_DEFAULT 0x0 + /*[field] SPARE_REG*/ + #define IPO_SPARE_REG_REG_SPARE_REG + #define IPO_SPARE_REG_REG_SPARE_REG_OFFSET 0 + #define IPO_SPARE_REG_REG_SPARE_REG_LEN 32 + #define IPO_SPARE_REG_REG_SPARE_REG_DEFAULT 0x0 + +struct ipo_spare_reg_reg { + a_uint32_t spare_reg:32; +}; + +union ipo_spare_reg_reg_u { + a_uint32_t val; + struct ipo_spare_reg_reg bf; +}; + +/*[register] IPO_GLB_HIT_COUNTER_REG*/ +#define IPO_GLB_HIT_COUNTER_REG +#define IPO_GLB_HIT_COUNTER_REG_ADDRESS 0x430c +#define IPO_GLB_HIT_COUNTER_REG_NUM 1 +#define IPO_GLB_HIT_COUNTER_REG_INC 0x4 +#define IPO_GLB_HIT_COUNTER_REG_TYPE REG_TYPE_RO +#define IPO_GLB_HIT_COUNTER_REG_DEFAULT 0x0 + /*[field] HIT_COUNT*/ + #define IPO_GLB_HIT_COUNTER_REG_HIT_COUNT + #define IPO_GLB_HIT_COUNTER_REG_HIT_COUNT_OFFSET 0 + #define IPO_GLB_HIT_COUNTER_REG_HIT_COUNT_LEN 32 + #define IPO_GLB_HIT_COUNTER_REG_HIT_COUNT_DEFAULT 0x0 + +struct ipo_glb_hit_counter_reg { + a_uint32_t hit_count:32; +}; + +union ipo_glb_hit_counter_reg_u { + a_uint32_t val; + struct ipo_glb_hit_counter_reg bf; +}; + +/*[register] IPO_GLB_MISS_COUNTER_REG*/ +#define IPO_GLB_MISS_COUNTER_REG +#define IPO_GLB_MISS_COUNTER_REG_ADDRESS 0x4310 +#define IPO_GLB_MISS_COUNTER_REG_NUM 1 +#define IPO_GLB_MISS_COUNTER_REG_INC 0x4 +#define IPO_GLB_MISS_COUNTER_REG_TYPE REG_TYPE_RO +#define IPO_GLB_MISS_COUNTER_REG_DEFAULT 0x0 + /*[field] MISS_COUNT*/ + #define IPO_GLB_MISS_COUNTER_REG_MISS_COUNT + #define IPO_GLB_MISS_COUNTER_REG_MISS_COUNT_OFFSET 0 + #define IPO_GLB_MISS_COUNTER_REG_MISS_COUNT_LEN 32 + #define IPO_GLB_MISS_COUNTER_REG_MISS_COUNT_DEFAULT 0x0 + +struct ipo_glb_miss_counter_reg { + a_uint32_t miss_count:32; +}; + +union ipo_glb_miss_counter_reg_u { + a_uint32_t val; + struct ipo_glb_miss_counter_reg bf; +}; + +/*[register] IPO_GLB_BYPASS_COUNTER_REG*/ +#define IPO_GLB_BYPASS_COUNTER_REG +#define IPO_GLB_BYPASS_COUNTER_REG_ADDRESS 0x4314 +#define IPO_GLB_BYPASS_COUNTER_REG_NUM 1 +#define IPO_GLB_BYPASS_COUNTER_REG_INC 0x4 +#define IPO_GLB_BYPASS_COUNTER_REG_TYPE REG_TYPE_RO +#define IPO_GLB_BYPASS_COUNTER_REG_DEFAULT 0x0 + /*[field] BYPASS_COUNT*/ + #define IPO_GLB_BYPASS_COUNTER_REG_BYPASS_COUNT + #define IPO_GLB_BYPASS_COUNTER_REG_BYPASS_COUNT_OFFSET 0 + #define IPO_GLB_BYPASS_COUNTER_REG_BYPASS_COUNT_LEN 32 + #define IPO_GLB_BYPASS_COUNTER_REG_BYPASS_COUNT_DEFAULT 0x0 + +struct ipo_glb_bypass_counter_reg { + a_uint32_t bypass_count:32; +}; + +union ipo_glb_bypass_counter_reg_u { + a_uint32_t val; + struct ipo_glb_bypass_counter_reg bf; +}; + +/*[table] IPO_CNT_TBL*/ +#define IPO_CNT_TBL +#define IPO_CNT_TBL_ADDRESS 0x74000 +#define IPO_CNT_TBL_NUM 512 +#define IPO_CNT_TBL_INC 0x10 +#define IPO_CNT_TBL_TYPE REG_TYPE_RW +#define IPO_CNT_TBL_DEFAULT 0x0 + /*[field] HIT_PKT_CNT*/ + #define IPO_CNT_TBL_HIT_PKT_CNT + #define IPO_CNT_TBL_HIT_PKT_CNT_OFFSET 0 + #define IPO_CNT_TBL_HIT_PKT_CNT_LEN 32 + #define IPO_CNT_TBL_HIT_PKT_CNT_DEFAULT 0x0 + /*[field] HIT_BYTE_CNT*/ + #define IPO_CNT_TBL_HIT_BYTE_CNT + #define IPO_CNT_TBL_HIT_BYTE_CNT_OFFSET 32 + #define IPO_CNT_TBL_HIT_BYTE_CNT_LEN 40 + #define IPO_CNT_TBL_HIT_BYTE_CNT_DEFAULT 0x0 + +struct ipo_cnt_tbl { + a_uint32_t hit_pkt_cnt:32; + a_uint32_t hit_byte_cnt_0:32; + a_uint32_t hit_byte_cnt_1:8; + a_uint32_t _reserved0:24; +}; + +union ipo_cnt_tbl_u { + a_uint32_t val[3]; + struct ipo_cnt_tbl bf; +}; + +/*[table] IPO_ACTION*/ +#define IPO_ACTION +#define IPO_ACTION_ADDRESS 0x8000 +#define IPO_ACTION_NUM 512 +#define IPO_ACTION_INC 0x20 +#define IPO_ACTION_TYPE REG_TYPE_RW +#define IPO_ACTION_DEFAULT 0x0 + /*[field] DEST_INFO_CHANGE_EN*/ + #define IPO_ACTION_DEST_INFO_CHANGE_EN + #define IPO_ACTION_DEST_INFO_CHANGE_EN_OFFSET 0 + #define IPO_ACTION_DEST_INFO_CHANGE_EN_LEN 1 + #define IPO_ACTION_DEST_INFO_CHANGE_EN_DEFAULT 0x0 + /*[field] FWD_CMD*/ + #define IPO_ACTION_FWD_CMD + #define IPO_ACTION_FWD_CMD_OFFSET 1 + #define IPO_ACTION_FWD_CMD_LEN 2 + #define IPO_ACTION_FWD_CMD_DEFAULT 0x0 + /*[field] DEST_INFO*/ + #define IPO_ACTION_DEST_INFO + #define IPO_ACTION_DEST_INFO_OFFSET 3 + #define IPO_ACTION_DEST_INFO_LEN 14 + #define IPO_ACTION_DEST_INFO_DEFAULT 0x0 + /*[field] MIRROR_EN*/ + #define IPO_ACTION_MIRROR_EN + #define IPO_ACTION_MIRROR_EN_OFFSET 17 + #define IPO_ACTION_MIRROR_EN_LEN 1 + #define IPO_ACTION_MIRROR_EN_DEFAULT 0x0 + /*[field] BYPASS_BITMAP*/ + #define IPO_ACTION_BYPASS_BITMAP + #define IPO_ACTION_BYPASS_BITMAP_OFFSET 18 + #define IPO_ACTION_BYPASS_BITMAP_LEN 32 + #define IPO_ACTION_BYPASS_BITMAP_DEFAULT 0x0 + /*[field] SVID_CHANGE_EN*/ + #define IPO_ACTION_SVID_CHANGE_EN + #define IPO_ACTION_SVID_CHANGE_EN_OFFSET 50 + #define IPO_ACTION_SVID_CHANGE_EN_LEN 1 + #define IPO_ACTION_SVID_CHANGE_EN_DEFAULT 0x0 + /*[field] STAG_FMT*/ + #define IPO_ACTION_STAG_FMT + #define IPO_ACTION_STAG_FMT_OFFSET 51 + #define IPO_ACTION_STAG_FMT_LEN 1 + #define IPO_ACTION_STAG_FMT_DEFAULT 0x0 + /*[field] SVID*/ + #define IPO_ACTION_SVID + #define IPO_ACTION_SVID_OFFSET 52 + #define IPO_ACTION_SVID_LEN 12 + #define IPO_ACTION_SVID_DEFAULT 0x0 + /*[field] CVID_CHANGE_EN*/ + #define IPO_ACTION_CVID_CHANGE_EN + #define IPO_ACTION_CVID_CHANGE_EN_OFFSET 64 + #define IPO_ACTION_CVID_CHANGE_EN_LEN 1 + #define IPO_ACTION_CVID_CHANGE_EN_DEFAULT 0x0 + /*[field] CTAG_FMT*/ + #define IPO_ACTION_CTAG_FMT + #define IPO_ACTION_CTAG_FMT_OFFSET 65 + #define IPO_ACTION_CTAG_FMT_LEN 1 + #define IPO_ACTION_CTAG_FMT_DEFAULT 0x0 + /*[field] CVID*/ + #define IPO_ACTION_CVID + #define IPO_ACTION_CVID_OFFSET 66 + #define IPO_ACTION_CVID_LEN 12 + #define IPO_ACTION_CVID_DEFAULT 0x0 + /*[field] DSCP_TC_CHANGE_EN*/ + #define IPO_ACTION_DSCP_TC_CHANGE_EN + #define IPO_ACTION_DSCP_TC_CHANGE_EN_OFFSET 78 + #define IPO_ACTION_DSCP_TC_CHANGE_EN_LEN 1 + #define IPO_ACTION_DSCP_TC_CHANGE_EN_DEFAULT 0x0 + /*[field] DSCP_TC*/ + #define IPO_ACTION_DSCP_TC + #define IPO_ACTION_DSCP_TC_OFFSET 79 + #define IPO_ACTION_DSCP_TC_LEN 8 + #define IPO_ACTION_DSCP_TC_DEFAULT 0x0 + /*[field] STAG_PCP_CHANGE_EN*/ + #define IPO_ACTION_STAG_PCP_CHANGE_EN + #define IPO_ACTION_STAG_PCP_CHANGE_EN_OFFSET 87 + #define IPO_ACTION_STAG_PCP_CHANGE_EN_LEN 1 + #define IPO_ACTION_STAG_PCP_CHANGE_EN_DEFAULT 0x0 + /*[field] STAG_PCP*/ + #define IPO_ACTION_STAG_PCP + #define IPO_ACTION_STAG_PCP_OFFSET 88 + #define IPO_ACTION_STAG_PCP_LEN 3 + #define IPO_ACTION_STAG_PCP_DEFAULT 0x0 + /*[field] STAG_DEI_CHANGE_EN*/ + #define IPO_ACTION_STAG_DEI_CHANGE_EN + #define IPO_ACTION_STAG_DEI_CHANGE_EN_OFFSET 91 + #define IPO_ACTION_STAG_DEI_CHANGE_EN_LEN 1 + #define IPO_ACTION_STAG_DEI_CHANGE_EN_DEFAULT 0x0 + /*[field] STAG_DEI*/ + #define IPO_ACTION_STAG_DEI + #define IPO_ACTION_STAG_DEI_OFFSET 92 + #define IPO_ACTION_STAG_DEI_LEN 1 + #define IPO_ACTION_STAG_DEI_DEFAULT 0x0 + /*[field] CTAG_PCP_CHANGE_EN*/ + #define IPO_ACTION_CTAG_PCP_CHANGE_EN + #define IPO_ACTION_CTAG_PCP_CHANGE_EN_OFFSET 93 + #define IPO_ACTION_CTAG_PCP_CHANGE_EN_LEN 1 + #define IPO_ACTION_CTAG_PCP_CHANGE_EN_DEFAULT 0x0 + /*[field] CTAG_PCP*/ + #define IPO_ACTION_CTAG_PCP + #define IPO_ACTION_CTAG_PCP_OFFSET 94 + #define IPO_ACTION_CTAG_PCP_LEN 3 + #define IPO_ACTION_CTAG_PCP_DEFAULT 0x0 + /*[field] CTAG_DEI_CHANGE_EN*/ + #define IPO_ACTION_CTAG_DEI_CHANGE_EN + #define IPO_ACTION_CTAG_DEI_CHANGE_EN_OFFSET 97 + #define IPO_ACTION_CTAG_DEI_CHANGE_EN_LEN 1 + #define IPO_ACTION_CTAG_DEI_CHANGE_EN_DEFAULT 0x0 + /*[field] CTAG_DEI*/ + #define IPO_ACTION_CTAG_DEI + #define IPO_ACTION_CTAG_DEI_OFFSET 98 + #define IPO_ACTION_CTAG_DEI_LEN 1 + #define IPO_ACTION_CTAG_DEI_DEFAULT 0x0 + /*[field] ENQUEUE_PRI_CHANGE_EN*/ + #define IPO_ACTION_ENQUEUE_PRI_CHANGE_EN + #define IPO_ACTION_ENQUEUE_PRI_CHANGE_EN_OFFSET 99 + #define IPO_ACTION_ENQUEUE_PRI_CHANGE_EN_LEN 1 + #define IPO_ACTION_ENQUEUE_PRI_CHANGE_EN_DEFAULT 0x0 + /*[field] ENQUEUE_PRI*/ + #define IPO_ACTION_ENQUEUE_PRI + #define IPO_ACTION_ENQUEUE_PRI_OFFSET 100 + #define IPO_ACTION_ENQUEUE_PRI_LEN 4 + #define IPO_ACTION_ENQUEUE_PRI_DEFAULT 0x0 + /*[field] INT_DP_CHANGE_EN*/ + #define IPO_ACTION_INT_DP_CHANGE_EN + #define IPO_ACTION_INT_DP_CHANGE_EN_OFFSET 104 + #define IPO_ACTION_INT_DP_CHANGE_EN_LEN 1 + #define IPO_ACTION_INT_DP_CHANGE_EN_DEFAULT 0x0 + /*[field] INT_DP*/ + #define IPO_ACTION_INT_DP + #define IPO_ACTION_INT_DP_OFFSET 105 + #define IPO_ACTION_INT_DP_LEN 2 + #define IPO_ACTION_INT_DP_DEFAULT 0x0 + /*[field] POLICER_EN*/ + #define IPO_ACTION_POLICER_EN + #define IPO_ACTION_POLICER_EN_OFFSET 107 + #define IPO_ACTION_POLICER_EN_LEN 1 + #define IPO_ACTION_POLICER_EN_DEFAULT 0x0 + /*[field] POLICER_INDEX*/ + #define IPO_ACTION_POLICER_INDEX + #define IPO_ACTION_POLICER_INDEX_OFFSET 108 + #define IPO_ACTION_POLICER_INDEX_LEN 9 + #define IPO_ACTION_POLICER_INDEX_DEFAULT 0x0 + /*[field] QID_EN*/ + #define IPO_ACTION_QID_EN + #define IPO_ACTION_QID_EN_OFFSET 117 + #define IPO_ACTION_QID_EN_LEN 1 + #define IPO_ACTION_QID_EN_DEFAULT 0x0 + /*[field] QID*/ + #define IPO_ACTION_QID + #define IPO_ACTION_QID_OFFSET 118 + #define IPO_ACTION_QID_LEN 8 + #define IPO_ACTION_QID_DEFAULT 0x0 + /*[field] SERVICE_CODE_EN*/ + #define IPO_ACTION_SERVICE_CODE_EN + #define IPO_ACTION_SERVICE_CODE_EN_OFFSET 126 + #define IPO_ACTION_SERVICE_CODE_EN_LEN 1 + #define IPO_ACTION_SERVICE_CODE_EN_DEFAULT 0x0 + /*[field] SERVICE_CODE*/ + #define IPO_ACTION_SERVICE_CODE + #define IPO_ACTION_SERVICE_CODE_OFFSET 127 + #define IPO_ACTION_SERVICE_CODE_LEN 8 + #define IPO_ACTION_SERVICE_CODE_DEFAULT 0x0 + /*[field] SYN_TOGGLE*/ + #define IPO_ACTION_SYN_TOGGLE + #define IPO_ACTION_SYN_TOGGLE_OFFSET 135 + #define IPO_ACTION_SYN_TOGGLE_LEN 1 + #define IPO_ACTION_SYN_TOGGLE_DEFAULT 0x0 + /*[field] CPU_CODE_EN*/ + #define IPO_ACTION_CPU_CODE_EN + #define IPO_ACTION_CPU_CODE_EN_OFFSET 136 + #define IPO_ACTION_CPU_CODE_EN_LEN 1 + #define IPO_ACTION_CPU_CODE_EN_DEFAULT 0x0 + /*[field] CPU_CODE*/ + #define IPO_ACTION_CPU_CODE + #define IPO_ACTION_CPU_CODE_OFFSET 137 + #define IPO_ACTION_CPU_CODE_LEN 8 + #define IPO_ACTION_CPU_CODE_DEFAULT 0x0 + /*[field] METADATA_EN*/ + #define IPO_ACTION_METADATA_EN + #define IPO_ACTION_METADATA_EN_OFFSET 145 + #define IPO_ACTION_METADATA_EN_LEN 1 + #define IPO_ACTION_METADATA_EN_DEFAULT 0x0 + +struct ipo_action { + a_uint32_t dest_info_change_en:1; + a_uint32_t fwd_cmd:2; + a_uint32_t dest_info:14; + a_uint32_t mirror_en:1; + a_uint32_t bypass_bitmap_0:14; + a_uint32_t bypass_bitmap_1:18; + a_uint32_t svid_change_en:1; + a_uint32_t stag_fmt:1; + a_uint32_t svid:12; + a_uint32_t cvid_change_en:1; + a_uint32_t ctag_fmt:1; + a_uint32_t cvid:12; + a_uint32_t dscp_tc_change_en:1; + a_uint32_t dscp_tc:8; + a_uint32_t stag_pcp_change_en:1; + a_uint32_t stag_pcp:3; + a_uint32_t stag_dei_change_en:1; + a_uint32_t stag_dei:1; + a_uint32_t ctag_pcp_change_en:1; + a_uint32_t ctag_pcp_0:2; + a_uint32_t ctag_pcp_1:1; + a_uint32_t ctag_dei_change_en:1; + a_uint32_t ctag_dei:1; + a_uint32_t enqueue_pri_change_en:1; + a_uint32_t enqueue_pri:4; + a_uint32_t int_dp_change_en:1; + a_uint32_t int_dp:2; + a_uint32_t policer_en:1; + a_uint32_t policer_index:9; + a_uint32_t qid_en:1; + a_uint32_t qid:8; + a_uint32_t service_code_en:1; + a_uint32_t service_code_0:1; + a_uint32_t service_code_1:7; + a_uint32_t syn_toggle:1; + a_uint32_t cpu_code_en:1; + a_uint32_t cpu_code:8; + a_uint32_t metadata_en:1; + a_uint32_t dscp_tc_mask:8; + a_uint32_t qos_res_prec:3; + a_uint32_t _reserved0:3; +}; + +union ipo_action_u { + a_uint32_t val[5]; + struct ipo_action bf; +}; + + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_bm.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_bm.h new file mode 100755 index 000000000..d48f44187 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_bm.h @@ -0,0 +1,1218 @@ +/* + * 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 + * @{ + */ +#ifndef _HPPE_BM_H_ +#define _HPPE_BM_H_ + +#define DEQ_FIFO_CFG_MAX_ENTRY 9 +#define PORT_FC_MODE_MAX_ENTRY 15 +#define PORT_FC_STATUS_MAX_ENTRY 15 +#define PORT_GROUP_ID_MAX_ENTRY 15 +#define PORT_CNT_MAX_ENTRY 15 +#define PORT_REACTED_CNT_MAX_ENTRY 15 +#define SHARED_GROUP_CNT_MAX_ENTRY 4 +#define SHARED_GROUP_CFG_MAX_ENTRY 4 +#define PORT_PROFILE_TH_CFG_MAX_ENTRY 15 +#define REACT_PROFILE_TH_CFG_MAX_ENTRY 15 +#define GRP_PROFILE_TH_CFG_MAX_ENTRY 4 +#define PORT_OUT_PROFILE_CNT_MAX_ENTRY 15 +#define PORT_IN_PROFILE_CNT_MAX_ENTRY 15 +#define REACT_OUT_PROFILE_CNT_MAX_ENTRY 15 +#define REACT_IN_PROFILE_CNT_MAX_ENTRY 15 +#define GRP_OUT_PROFILE_CNT_MAX_ENTRY 4 +#define GRP_IN_PROFILE_CNT_MAX_ENTRY 4 +#define PORT_FC_CFG_MAX_ENTRY 15 +#define LLM_MAX_ENTRY 2048 +#define RCM_MAX_ENTRY 2048 +#define DM_MAX_ENTRY 8192 + + +sw_error_t +hppe_fb_fifo_cfg_get( + a_uint32_t dev_id, + union fb_fifo_cfg_u *value); + +sw_error_t +hppe_fb_fifo_cfg_set( + a_uint32_t dev_id, + union fb_fifo_cfg_u *value); + +sw_error_t +hppe_fp_fifo_cfg_get( + a_uint32_t dev_id, + union fp_fifo_cfg_u *value); + +sw_error_t +hppe_fp_fifo_cfg_set( + a_uint32_t dev_id, + union fp_fifo_cfg_u *value); + +sw_error_t +hppe_deq_fifo_cfg_get( + a_uint32_t dev_id, + a_uint32_t index, + union deq_fifo_cfg_u *value); + +sw_error_t +hppe_deq_fifo_cfg_set( + a_uint32_t dev_id, + a_uint32_t index, + union deq_fifo_cfg_u *value); + +sw_error_t +hppe_tick_dly_cfg_get( + a_uint32_t dev_id, + union tick_dly_cfg_u *value); + +sw_error_t +hppe_tick_dly_cfg_set( + a_uint32_t dev_id, + union tick_dly_cfg_u *value); + +sw_error_t +hppe_bm_rsv_0_get( + a_uint32_t dev_id, + union bm_rsv_0_u *value); + +sw_error_t +hppe_bm_rsv_0_set( + a_uint32_t dev_id, + union bm_rsv_0_u *value); + +sw_error_t +hppe_bm_rsv_1_get( + a_uint32_t dev_id, + union bm_rsv_1_u *value); + +sw_error_t +hppe_bm_rsv_1_set( + a_uint32_t dev_id, + union bm_rsv_1_u *value); + +sw_error_t +hppe_bm_dbg_addr_get( + a_uint32_t dev_id, + union bm_dbg_addr_u *value); + +sw_error_t +hppe_bm_dbg_addr_set( + a_uint32_t dev_id, + union bm_dbg_addr_u *value); + +sw_error_t +hppe_bm_dbg_data_get( + a_uint32_t dev_id, + union bm_dbg_data_u *value); + +sw_error_t +hppe_bm_dbg_data_set( + a_uint32_t dev_id, + union bm_dbg_data_u *value); + +sw_error_t +hppe_port_fc_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_fc_mode_u *value); + +sw_error_t +hppe_port_fc_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_fc_mode_u *value); + +sw_error_t +hppe_port_fc_status_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_fc_status_u *value); + +sw_error_t +hppe_port_fc_status_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_fc_status_u *value); + +sw_error_t +hppe_port_group_id_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_group_id_u *value); + +sw_error_t +hppe_port_group_id_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_group_id_u *value); + +sw_error_t +hppe_port_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_cnt_u *value); + +sw_error_t +hppe_port_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_cnt_u *value); + +sw_error_t +hppe_port_reacted_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_reacted_cnt_u *value); + +sw_error_t +hppe_port_reacted_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_reacted_cnt_u *value); + +sw_error_t +hppe_shared_group_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + union shared_group_cnt_u *value); + +sw_error_t +hppe_shared_group_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + union shared_group_cnt_u *value); + +sw_error_t +hppe_shared_group_cfg_get( + a_uint32_t dev_id, + a_uint32_t index, + union shared_group_cfg_u *value); + +sw_error_t +hppe_shared_group_cfg_set( + a_uint32_t dev_id, + a_uint32_t index, + union shared_group_cfg_u *value); + +sw_error_t +hppe_port_profile_cnt_en_get( + a_uint32_t dev_id, + union port_profile_cnt_en_u *value); + +sw_error_t +hppe_port_profile_cnt_en_set( + a_uint32_t dev_id, + union port_profile_cnt_en_u *value); + +sw_error_t +hppe_grp_profile_cnt_en_get( + a_uint32_t dev_id, + union grp_profile_cnt_en_u *value); + +sw_error_t +hppe_grp_profile_cnt_en_set( + a_uint32_t dev_id, + union grp_profile_cnt_en_u *value); + +sw_error_t +hppe_port_profile_th_cfg_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_profile_th_cfg_u *value); + +sw_error_t +hppe_port_profile_th_cfg_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_profile_th_cfg_u *value); + +sw_error_t +hppe_react_profile_th_cfg_get( + a_uint32_t dev_id, + a_uint32_t index, + union react_profile_th_cfg_u *value); + +sw_error_t +hppe_react_profile_th_cfg_set( + a_uint32_t dev_id, + a_uint32_t index, + union react_profile_th_cfg_u *value); + +sw_error_t +hppe_grp_profile_th_cfg_get( + a_uint32_t dev_id, + a_uint32_t index, + union grp_profile_th_cfg_u *value); + +sw_error_t +hppe_grp_profile_th_cfg_set( + a_uint32_t dev_id, + a_uint32_t index, + union grp_profile_th_cfg_u *value); + +sw_error_t +hppe_tot_react_profile_th_cfg_get( + a_uint32_t dev_id, + union tot_react_profile_th_cfg_u *value); + +sw_error_t +hppe_tot_react_profile_th_cfg_set( + a_uint32_t dev_id, + union tot_react_profile_th_cfg_u *value); + +sw_error_t +hppe_port_out_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_out_profile_cnt_u *value); + +sw_error_t +hppe_port_out_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_out_profile_cnt_u *value); + +sw_error_t +hppe_port_in_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_in_profile_cnt_u *value); + +sw_error_t +hppe_port_in_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_in_profile_cnt_u *value); + +sw_error_t +hppe_react_out_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + union react_out_profile_cnt_u *value); + +sw_error_t +hppe_react_out_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + union react_out_profile_cnt_u *value); + +sw_error_t +hppe_react_in_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + union react_in_profile_cnt_u *value); + +sw_error_t +hppe_react_in_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + union react_in_profile_cnt_u *value); + +sw_error_t +hppe_grp_out_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + union grp_out_profile_cnt_u *value); + +sw_error_t +hppe_grp_out_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + union grp_out_profile_cnt_u *value); + +sw_error_t +hppe_grp_in_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + union grp_in_profile_cnt_u *value); + +sw_error_t +hppe_grp_in_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + union grp_in_profile_cnt_u *value); + +sw_error_t +hppe_tot_react_out_profile_cnt_get( + a_uint32_t dev_id, + union tot_react_out_profile_cnt_u *value); + +sw_error_t +hppe_tot_react_out_profile_cnt_set( + a_uint32_t dev_id, + union tot_react_out_profile_cnt_u *value); + +sw_error_t +hppe_tot_react_in_profile_cnt_get( + a_uint32_t dev_id, + union tot_react_in_profile_cnt_u *value); + +sw_error_t +hppe_tot_react_in_profile_cnt_set( + a_uint32_t dev_id, + union tot_react_in_profile_cnt_u *value); + +sw_error_t +hppe_port_fc_cfg_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_fc_cfg_u *value); + +sw_error_t +hppe_port_fc_cfg_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_fc_cfg_u *value); + +sw_error_t +hppe_llm_get( + a_uint32_t dev_id, + a_uint32_t index, + union llm_u *value); + +sw_error_t +hppe_llm_set( + a_uint32_t dev_id, + a_uint32_t index, + union llm_u *value); + +sw_error_t +hppe_rcm_get( + a_uint32_t dev_id, + a_uint32_t index, + union rcm_u *value); + +sw_error_t +hppe_rcm_set( + a_uint32_t dev_id, + a_uint32_t index, + union rcm_u *value); + +sw_error_t +hppe_dm_get( + a_uint32_t dev_id, + a_uint32_t index, + union dm_u *value); + +sw_error_t +hppe_dm_set( + a_uint32_t dev_id, + a_uint32_t index, + union dm_u *value); + +sw_error_t +hppe_fb_fifo_cfg_fb_fifo_thres_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_fb_fifo_cfg_fb_fifo_thres_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_fp_fifo_cfg_fp_fifo_thres_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_fp_fifo_cfg_fp_fifo_thres_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_deq_fifo_cfg_deq_fifo_thres_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_deq_fifo_cfg_deq_fifo_thres_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tick_dly_cfg_tick_dly_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_tick_dly_cfg_tick_dly_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_bm_rsv_0_rsv_0_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_bm_rsv_0_rsv_0_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_bm_rsv_1_rsv_1_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_bm_rsv_1_rsv_1_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_bm_dbg_addr_dbg_addr_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_bm_dbg_addr_dbg_addr_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_bm_dbg_data_dbg_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_bm_dbg_data_dbg_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_fc_mode_fc_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_fc_mode_fc_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_fc_status_port_fc_status_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_fc_status_port_fc_status_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_fc_status_port_xon_th_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_fc_status_port_xon_th_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_group_id_port_shared_group_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_group_id_port_shared_group_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_cnt_port_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_cnt_port_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_reacted_cnt_port_reacted_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_reacted_cnt_port_reacted_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_shared_group_cnt_shared_group_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_shared_group_cnt_shared_group_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_shared_group_cfg_shared_group_limit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_shared_group_cfg_shared_group_limit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_8_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_8_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_7_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_7_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_6_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_6_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_2_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_2_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_8_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_8_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_5_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_5_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_12_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_12_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_4_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_4_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_3_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_3_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_10_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_10_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_4_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_4_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_5_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_5_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_14_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_14_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_14_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_14_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_3_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_3_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_1_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_1_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_0_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_0_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_7_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_7_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_13_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_13_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_6_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_6_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_0_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_0_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_13_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_13_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_11_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_11_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_1_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_1_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_12_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_12_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_11_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_11_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_10_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_10_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_9_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_9_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_2_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_2_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_9_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_9_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_grp_profile_cnt_en_grp_cnt_en_3_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_grp_profile_cnt_en_grp_cnt_en_3_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_grp_profile_cnt_en_tot_rect_cnt_en_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_grp_profile_cnt_en_tot_rect_cnt_en_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_grp_profile_cnt_en_grp_cnt_en_1_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_grp_profile_cnt_en_grp_cnt_en_1_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_grp_profile_cnt_en_grp_cnt_en_0_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_grp_profile_cnt_en_grp_cnt_en_0_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_grp_profile_cnt_en_grp_cnt_en_2_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_grp_profile_cnt_en_grp_cnt_en_2_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_profile_th_cfg_port_profile_th_cfg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_profile_th_cfg_port_profile_th_cfg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_react_profile_th_cfg_react_profile_th_cfg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_react_profile_th_cfg_react_profile_th_cfg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_grp_profile_th_cfg_grp_profile_th_cfg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_grp_profile_th_cfg_grp_profile_th_cfg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tot_react_profile_th_cfg_tot_react_profile_th_cfg_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_tot_react_profile_th_cfg_tot_react_profile_th_cfg_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_out_profile_cnt_port_out_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_out_profile_cnt_port_out_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_in_profile_cnt_port_in_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_in_profile_cnt_port_in_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_react_out_profile_cnt_react_out_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_react_out_profile_cnt_react_out_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_react_in_profile_cnt_react_in_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_react_in_profile_cnt_react_in_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_grp_out_profile_cnt_grp_out_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_grp_out_profile_cnt_grp_out_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_grp_in_profile_cnt_grp_in_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_grp_in_profile_cnt_grp_in_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tot_react_out_profile_cnt_tot_react_out_profile_cnt_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_tot_react_out_profile_cnt_tot_react_out_profile_cnt_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_tot_react_in_profile_cnt_tot_react_in_profile_cnt_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_tot_react_in_profile_cnt_tot_react_in_profile_cnt_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_fc_cfg_port_pre_alloc_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_fc_cfg_port_pre_alloc_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_fc_cfg_port_resume_offset_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_fc_cfg_port_resume_offset_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_fc_cfg_port_shared_dynamic_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_fc_cfg_port_shared_dynamic_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_fc_cfg_port_shared_weight_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_fc_cfg_port_shared_weight_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_fc_cfg_port_resume_floor_th_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_fc_cfg_port_resume_floor_th_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_fc_cfg_port_react_limit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_fc_cfg_port_react_limit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_fc_cfg_port_shared_ceiling_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_fc_cfg_port_shared_ceiling_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_llm_eop_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_llm_eop_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_llm_nxt_ptr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_llm_nxt_ptr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rcm_ref_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rcm_ref_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_dm_pkt_data_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_dm_pkt_data_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +#endif + + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_bm_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_bm_reg.h new file mode 100755 index 000000000..8b4d98f75 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_bm_reg.h @@ -0,0 +1,1036 @@ +/* + * 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 + * @{ + */ +#ifndef HPPE_BM_REG_H +#define HPPE_BM_REG_H + +/*[register] FB_FIFO_CFG*/ +#define FB_FIFO_CFG +#define FB_FIFO_CFG_ADDRESS 0x0 +#define FB_FIFO_CFG_NUM 1 +#define FB_FIFO_CFG_INC 0x4 +#define FB_FIFO_CFG_TYPE REG_TYPE_RW +#define FB_FIFO_CFG_DEFAULT 0x10 + /*[field] FB_FIFO_THRES*/ + #define FB_FIFO_CFG_FB_FIFO_THRES + #define FB_FIFO_CFG_FB_FIFO_THRES_OFFSET 0 + #define FB_FIFO_CFG_FB_FIFO_THRES_LEN 5 + #define FB_FIFO_CFG_FB_FIFO_THRES_DEFAULT 0x10 + +struct fb_fifo_cfg { + a_uint32_t fb_fifo_thres:5; + a_uint32_t _reserved0:27; +}; + +union fb_fifo_cfg_u { + a_uint32_t val; + struct fb_fifo_cfg bf; +}; + +/*[register] FP_FIFO_CFG*/ +#define FP_FIFO_CFG +#define FP_FIFO_CFG_ADDRESS 0x4 +#define FP_FIFO_CFG_NUM 1 +#define FP_FIFO_CFG_INC 0x4 +#define FP_FIFO_CFG_TYPE REG_TYPE_RW +#define FP_FIFO_CFG_DEFAULT 0x10 + /*[field] FP_FIFO_THRES*/ + #define FP_FIFO_CFG_FP_FIFO_THRES + #define FP_FIFO_CFG_FP_FIFO_THRES_OFFSET 0 + #define FP_FIFO_CFG_FP_FIFO_THRES_LEN 5 + #define FP_FIFO_CFG_FP_FIFO_THRES_DEFAULT 0x10 + +struct fp_fifo_cfg { + a_uint32_t fp_fifo_thres:5; + a_uint32_t _reserved0:27; +}; + +union fp_fifo_cfg_u { + a_uint32_t val; + struct fp_fifo_cfg bf; +}; + +/*[register] DEQ_FIFO_CFG*/ +#define DEQ_FIFO_CFG +#define DEQ_FIFO_CFG_ADDRESS 0x8 +#define DEQ_FIFO_CFG_NUM 9 +#define DEQ_FIFO_CFG_INC 0x4 +#define DEQ_FIFO_CFG_TYPE REG_TYPE_RW +#define DEQ_FIFO_CFG_DEFAULT 0x2 + /*[field] DEQ_FIFO_THRES*/ + #define DEQ_FIFO_CFG_DEQ_FIFO_THRES + #define DEQ_FIFO_CFG_DEQ_FIFO_THRES_OFFSET 0 + #define DEQ_FIFO_CFG_DEQ_FIFO_THRES_LEN 3 + #define DEQ_FIFO_CFG_DEQ_FIFO_THRES_DEFAULT 0x2 + +struct deq_fifo_cfg { + a_uint32_t deq_fifo_thres:3; + a_uint32_t _reserved0:29; +}; + +union deq_fifo_cfg_u { + a_uint32_t val; + struct deq_fifo_cfg bf; +}; + +/*[register] TICK_DLY_CFG*/ +#define TICK_DLY_CFG +#define TICK_DLY_CFG_ADDRESS 0x2c +#define TICK_DLY_CFG_NUM 1 +#define TICK_DLY_CFG_INC 0x4 +#define TICK_DLY_CFG_TYPE REG_TYPE_RW +#define TICK_DLY_CFG_DEFAULT 0x0 + /*[field] TICK_DLY*/ + #define TICK_DLY_CFG_TICK_DLY + #define TICK_DLY_CFG_TICK_DLY_OFFSET 0 + #define TICK_DLY_CFG_TICK_DLY_LEN 1 + #define TICK_DLY_CFG_TICK_DLY_DEFAULT 0x0 + +struct tick_dly_cfg { + a_uint32_t tick_dly:1; + a_uint32_t _reserved0:31; +}; + +union tick_dly_cfg_u { + a_uint32_t val; + struct tick_dly_cfg bf; +}; + +/*[register] BM_RSV_0*/ +#define BM_RSV_0 +#define BM_RSV_0_ADDRESS 0x30 +#define BM_RSV_0_NUM 1 +#define BM_RSV_0_INC 0x4 +#define BM_RSV_0_TYPE REG_TYPE_RW +#define BM_RSV_0_DEFAULT 0x0 + /*[field] RSV_0*/ + #define BM_RSV_0_RSV_0 + #define BM_RSV_0_RSV_0_OFFSET 0 + #define BM_RSV_0_RSV_0_LEN 32 + #define BM_RSV_0_RSV_0_DEFAULT 0x0 + +struct bm_rsv_0 { + a_uint32_t rsv_0:32; +}; + +union bm_rsv_0_u { + a_uint32_t val; + struct bm_rsv_0 bf; +}; + +/*[register] BM_RSV_1*/ +#define BM_RSV_1 +#define BM_RSV_1_ADDRESS 0x34 +#define BM_RSV_1_NUM 1 +#define BM_RSV_1_INC 0x4 +#define BM_RSV_1_TYPE REG_TYPE_RW +#define BM_RSV_1_DEFAULT 0x0 + /*[field] RSV_1*/ + #define BM_RSV_1_RSV_1 + #define BM_RSV_1_RSV_1_OFFSET 0 + #define BM_RSV_1_RSV_1_LEN 32 + #define BM_RSV_1_RSV_1_DEFAULT 0x0 + +struct bm_rsv_1 { + a_uint32_t rsv_1:32; +}; + +union bm_rsv_1_u { + a_uint32_t val; + struct bm_rsv_1 bf; +}; + +/*[register] BM_DBG_ADDR*/ +#define BM_DBG_ADDR +#define BM_DBG_ADDR_ADDRESS 0x80 +#define BM_DBG_ADDR_NUM 1 +#define BM_DBG_ADDR_INC 0x4 +#define BM_DBG_ADDR_TYPE REG_TYPE_RW +#define BM_DBG_ADDR_DEFAULT 0x0 + /*[field] DBG_ADDR*/ + #define BM_DBG_ADDR_DBG_ADDR + #define BM_DBG_ADDR_DBG_ADDR_OFFSET 0 + #define BM_DBG_ADDR_DBG_ADDR_LEN 8 + #define BM_DBG_ADDR_DBG_ADDR_DEFAULT 0x0 + +struct bm_dbg_addr { + a_uint32_t dbg_addr:8; + a_uint32_t _reserved0:24; +}; + +union bm_dbg_addr_u { + a_uint32_t val; + struct bm_dbg_addr bf; +}; + +/*[register] BM_DBG_DATA*/ +#define BM_DBG_DATA +#define BM_DBG_DATA_ADDRESS 0x84 +#define BM_DBG_DATA_NUM 1 +#define BM_DBG_DATA_INC 0x4 +#define BM_DBG_DATA_TYPE REG_TYPE_RO +#define BM_DBG_DATA_DEFAULT 0x0 + /*[field] DBG_DATA*/ + #define BM_DBG_DATA_DBG_DATA + #define BM_DBG_DATA_DBG_DATA_OFFSET 0 + #define BM_DBG_DATA_DBG_DATA_LEN 32 + #define BM_DBG_DATA_DBG_DATA_DEFAULT 0x0 + +struct bm_dbg_data { + a_uint32_t dbg_data:32; +}; + +union bm_dbg_data_u { + a_uint32_t val; + struct bm_dbg_data bf; +}; + +/*[register] PORT_FC_MODE*/ +#define PORT_FC_MODE +#define PORT_FC_MODE_ADDRESS 0x100 +#define PORT_FC_MODE_NUM 15 +#define PORT_FC_MODE_INC 0x4 +#define PORT_FC_MODE_TYPE REG_TYPE_RW +#define PORT_FC_MODE_DEFAULT 0x0 + /*[field] FC_EN*/ + #define PORT_FC_MODE_FC_EN + #define PORT_FC_MODE_FC_EN_OFFSET 0 + #define PORT_FC_MODE_FC_EN_LEN 1 + #define PORT_FC_MODE_FC_EN_DEFAULT 0x0 + +struct port_fc_mode { + a_uint32_t fc_en:1; + a_uint32_t _reserved0:31; +}; + +union port_fc_mode_u { + a_uint32_t val; + struct port_fc_mode bf; +}; + +/*[register] PORT_FC_STATUS*/ +#define PORT_FC_STATUS +#define PORT_FC_STATUS_ADDRESS 0x140 +#define PORT_FC_STATUS_NUM 15 +#define PORT_FC_STATUS_INC 0x4 +#define PORT_FC_STATUS_TYPE REG_TYPE_RO +#define PORT_FC_STATUS_DEFAULT 0x0 + /*[field] PORT_XON_TH*/ + #define PORT_FC_STATUS_PORT_XON_TH + #define PORT_FC_STATUS_PORT_XON_TH_OFFSET 0 + #define PORT_FC_STATUS_PORT_XON_TH_LEN 11 + #define PORT_FC_STATUS_PORT_XON_TH_DEFAULT 0x0 + /*[field] PORT_FC_STATUS*/ + #define PORT_FC_STATUS_PORT_FC_STATUS + #define PORT_FC_STATUS_PORT_FC_STATUS_OFFSET 16 + #define PORT_FC_STATUS_PORT_FC_STATUS_LEN 2 + #define PORT_FC_STATUS_PORT_FC_STATUS_DEFAULT 0x0 + +struct port_fc_status { + a_uint32_t port_xon_th:11; + a_uint32_t _reserved0:5; + a_uint32_t port_fc_status:2; + a_uint32_t _reserved1:14; +}; + +union port_fc_status_u { + a_uint32_t val; + struct port_fc_status bf; +}; + +/*[register] PORT_GROUP_ID*/ +#define PORT_GROUP_ID +#define PORT_GROUP_ID_ADDRESS 0x180 +#define PORT_GROUP_ID_NUM 15 +#define PORT_GROUP_ID_INC 0x4 +#define PORT_GROUP_ID_TYPE REG_TYPE_RW +#define PORT_GROUP_ID_DEFAULT 0x0 + /*[field] PORT_SHARED_GROUP_ID*/ + #define PORT_GROUP_ID_PORT_SHARED_GROUP_ID + #define PORT_GROUP_ID_PORT_SHARED_GROUP_ID_OFFSET 0 + #define PORT_GROUP_ID_PORT_SHARED_GROUP_ID_LEN 2 + #define PORT_GROUP_ID_PORT_SHARED_GROUP_ID_DEFAULT 0x0 + +struct port_group_id { + a_uint32_t port_shared_group_id:2; + a_uint32_t _reserved0:30; +}; + +union port_group_id_u { + a_uint32_t val; + struct port_group_id bf; +}; + +/*[register] PORT_CNT*/ +#define PORT_CNT +#define PORT_CNT_ADDRESS 0x1c0 +#define PORT_CNT_NUM 15 +#define PORT_CNT_INC 0x4 +#define PORT_CNT_TYPE REG_TYPE_RO +#define PORT_CNT_DEFAULT 0x0 + /*[field] PORT_CNT*/ + #define PORT_CNT_PORT_CNT + #define PORT_CNT_PORT_CNT_OFFSET 0 + #define PORT_CNT_PORT_CNT_LEN 11 + #define PORT_CNT_PORT_CNT_DEFAULT 0x0 + +struct port_cnt { + a_uint32_t port_cnt:11; + a_uint32_t _reserved0:21; +}; + +union port_cnt_u { + a_uint32_t val; + struct port_cnt bf; +}; + +/*[register] PORT_REACTED_CNT*/ +#define PORT_REACTED_CNT +#define PORT_REACTED_CNT_ADDRESS 0x240 +#define PORT_REACTED_CNT_NUM 15 +#define PORT_REACTED_CNT_INC 0x4 +#define PORT_REACTED_CNT_TYPE REG_TYPE_RO +#define PORT_REACTED_CNT_DEFAULT 0x0 + /*[field] PORT_REACTED_CNT*/ + #define PORT_REACTED_CNT_PORT_REACTED_CNT + #define PORT_REACTED_CNT_PORT_REACTED_CNT_OFFSET 0 + #define PORT_REACTED_CNT_PORT_REACTED_CNT_LEN 9 + #define PORT_REACTED_CNT_PORT_REACTED_CNT_DEFAULT 0x0 + +struct port_reacted_cnt { + a_uint32_t port_reacted_cnt:9; + a_uint32_t _reserved0:23; +}; + +union port_reacted_cnt_u { + a_uint32_t val; + struct port_reacted_cnt bf; +}; + +/*[register] SHARED_GROUP_CNT*/ +#define SHARED_GROUP_CNT +#define SHARED_GROUP_CNT_ADDRESS 0x280 +#define SHARED_GROUP_CNT_NUM 4 +#define SHARED_GROUP_CNT_INC 0x4 +#define SHARED_GROUP_CNT_TYPE REG_TYPE_RO +#define SHARED_GROUP_CNT_DEFAULT 0x0 + /*[field] SHARED_GROUP_CNT*/ + #define SHARED_GROUP_CNT_SHARED_GROUP_CNT + #define SHARED_GROUP_CNT_SHARED_GROUP_CNT_OFFSET 0 + #define SHARED_GROUP_CNT_SHARED_GROUP_CNT_LEN 11 + #define SHARED_GROUP_CNT_SHARED_GROUP_CNT_DEFAULT 0x0 + +struct shared_group_cnt { + a_uint32_t shared_group_cnt:11; + a_uint32_t _reserved0:21; +}; + +union shared_group_cnt_u { + a_uint32_t val; + struct shared_group_cnt bf; +}; + +/*[register] SHARED_GROUP_CFG*/ +#define SHARED_GROUP_CFG +#define SHARED_GROUP_CFG_ADDRESS 0x290 +#define SHARED_GROUP_CFG_NUM 4 +#define SHARED_GROUP_CFG_INC 0x4 +#define SHARED_GROUP_CFG_TYPE REG_TYPE_RW +#define SHARED_GROUP_CFG_DEFAULT 0x0 + /*[field] SHARED_GROUP_LIMIT*/ + #define SHARED_GROUP_CFG_SHARED_GROUP_LIMIT + #define SHARED_GROUP_CFG_SHARED_GROUP_LIMIT_OFFSET 0 + #define SHARED_GROUP_CFG_SHARED_GROUP_LIMIT_LEN 11 + #define SHARED_GROUP_CFG_SHARED_GROUP_LIMIT_DEFAULT 0x0 + +struct shared_group_cfg { + a_uint32_t shared_group_limit:11; + a_uint32_t _reserved0:21; +}; + +union shared_group_cfg_u { + a_uint32_t val; + struct shared_group_cfg bf; +}; + +/*[register] PORT_PROFILE_CNT_EN*/ +#define PORT_PROFILE_CNT_EN +#define PORT_PROFILE_CNT_EN_ADDRESS 0x300 +#define PORT_PROFILE_CNT_EN_NUM 1 +#define PORT_PROFILE_CNT_EN_INC 0x4 +#define PORT_PROFILE_CNT_EN_TYPE REG_TYPE_RW +#define PORT_PROFILE_CNT_EN_DEFAULT 0x0 + /*[field] PORT_CNT_EN_0*/ + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_0 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_0_OFFSET 0 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_0_LEN 1 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_0_DEFAULT 0x0 + /*[field] PORT_CNT_EN_1*/ + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_1 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_1_OFFSET 1 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_1_LEN 1 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_1_DEFAULT 0x0 + /*[field] PORT_CNT_EN_2*/ + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_2 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_2_OFFSET 2 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_2_LEN 1 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_2_DEFAULT 0x0 + /*[field] PORT_CNT_EN_3*/ + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_3 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_3_OFFSET 3 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_3_LEN 1 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_3_DEFAULT 0x0 + /*[field] PORT_CNT_EN_4*/ + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_4 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_4_OFFSET 4 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_4_LEN 1 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_4_DEFAULT 0x0 + /*[field] PORT_CNT_EN_5*/ + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_5 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_5_OFFSET 5 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_5_LEN 1 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_5_DEFAULT 0x0 + /*[field] PORT_CNT_EN_6*/ + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_6 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_6_OFFSET 6 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_6_LEN 1 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_6_DEFAULT 0x0 + /*[field] PORT_CNT_EN_7*/ + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_7 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_7_OFFSET 7 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_7_LEN 1 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_7_DEFAULT 0x0 + /*[field] PORT_CNT_EN_8*/ + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_8 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_8_OFFSET 8 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_8_LEN 1 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_8_DEFAULT 0x0 + /*[field] PORT_CNT_EN_9*/ + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_9 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_9_OFFSET 9 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_9_LEN 1 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_9_DEFAULT 0x0 + /*[field] PORT_CNT_EN_10*/ + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_10 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_10_OFFSET 10 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_10_LEN 1 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_10_DEFAULT 0x0 + /*[field] PORT_CNT_EN_11*/ + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_11 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_11_OFFSET 11 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_11_LEN 1 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_11_DEFAULT 0x0 + /*[field] PORT_CNT_EN_12*/ + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_12 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_12_OFFSET 12 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_12_LEN 1 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_12_DEFAULT 0x0 + /*[field] PORT_CNT_EN_13*/ + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_13 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_13_OFFSET 13 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_13_LEN 1 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_13_DEFAULT 0x0 + /*[field] PORT_CNT_EN_14*/ + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_14 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_14_OFFSET 14 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_14_LEN 1 + #define PORT_PROFILE_CNT_EN_PORT_CNT_EN_14_DEFAULT 0x0 + /*[field] REACT_CNT_EN_0*/ + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_0 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_0_OFFSET 16 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_0_LEN 1 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_0_DEFAULT 0x0 + /*[field] REACT_CNT_EN_1*/ + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_1 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_1_OFFSET 17 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_1_LEN 1 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_1_DEFAULT 0x0 + /*[field] REACT_CNT_EN_2*/ + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_2 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_2_OFFSET 18 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_2_LEN 1 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_2_DEFAULT 0x0 + /*[field] REACT_CNT_EN_3*/ + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_3 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_3_OFFSET 19 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_3_LEN 1 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_3_DEFAULT 0x0 + /*[field] REACT_CNT_EN_4*/ + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_4 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_4_OFFSET 20 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_4_LEN 1 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_4_DEFAULT 0x0 + /*[field] REACT_CNT_EN_5*/ + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_5 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_5_OFFSET 21 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_5_LEN 1 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_5_DEFAULT 0x0 + /*[field] REACT_CNT_EN_6*/ + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_6 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_6_OFFSET 22 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_6_LEN 1 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_6_DEFAULT 0x0 + /*[field] REACT_CNT_EN_7*/ + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_7 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_7_OFFSET 23 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_7_LEN 1 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_7_DEFAULT 0x0 + /*[field] REACT_CNT_EN_8*/ + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_8 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_8_OFFSET 24 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_8_LEN 1 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_8_DEFAULT 0x0 + /*[field] REACT_CNT_EN_9*/ + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_9 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_9_OFFSET 25 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_9_LEN 1 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_9_DEFAULT 0x0 + /*[field] REACT_CNT_EN_10*/ + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_10 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_10_OFFSET 26 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_10_LEN 1 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_10_DEFAULT 0x0 + /*[field] REACT_CNT_EN_11*/ + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_11 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_11_OFFSET 27 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_11_LEN 1 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_11_DEFAULT 0x0 + /*[field] REACT_CNT_EN_12*/ + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_12 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_12_OFFSET 28 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_12_LEN 1 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_12_DEFAULT 0x0 + /*[field] REACT_CNT_EN_13*/ + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_13 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_13_OFFSET 29 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_13_LEN 1 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_13_DEFAULT 0x0 + /*[field] REACT_CNT_EN_14*/ + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_14 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_14_OFFSET 30 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_14_LEN 1 + #define PORT_PROFILE_CNT_EN_REACT_CNT_EN_14_DEFAULT 0x0 + +struct port_profile_cnt_en { + a_uint32_t port_cnt_en_0:1; + a_uint32_t port_cnt_en_1:1; + a_uint32_t port_cnt_en_2:1; + a_uint32_t port_cnt_en_3:1; + a_uint32_t port_cnt_en_4:1; + a_uint32_t port_cnt_en_5:1; + a_uint32_t port_cnt_en_6:1; + a_uint32_t port_cnt_en_7:1; + a_uint32_t port_cnt_en_8:1; + a_uint32_t port_cnt_en_9:1; + a_uint32_t port_cnt_en_10:1; + a_uint32_t port_cnt_en_11:1; + a_uint32_t port_cnt_en_12:1; + a_uint32_t port_cnt_en_13:1; + a_uint32_t port_cnt_en_14:1; + a_uint32_t _reserved0:1; + a_uint32_t react_cnt_en_0:1; + a_uint32_t react_cnt_en_1:1; + a_uint32_t react_cnt_en_2:1; + a_uint32_t react_cnt_en_3:1; + a_uint32_t react_cnt_en_4:1; + a_uint32_t react_cnt_en_5:1; + a_uint32_t react_cnt_en_6:1; + a_uint32_t react_cnt_en_7:1; + a_uint32_t react_cnt_en_8:1; + a_uint32_t react_cnt_en_9:1; + a_uint32_t react_cnt_en_10:1; + a_uint32_t react_cnt_en_11:1; + a_uint32_t react_cnt_en_12:1; + a_uint32_t react_cnt_en_13:1; + a_uint32_t react_cnt_en_14:1; + a_uint32_t _reserved1:1; +}; + +union port_profile_cnt_en_u { + a_uint32_t val; + struct port_profile_cnt_en bf; +}; + +/*[register] GRP_PROFILE_CNT_EN*/ +#define GRP_PROFILE_CNT_EN +#define GRP_PROFILE_CNT_EN_ADDRESS 0x304 +#define GRP_PROFILE_CNT_EN_NUM 1 +#define GRP_PROFILE_CNT_EN_INC 0x4 +#define GRP_PROFILE_CNT_EN_TYPE REG_TYPE_RW +#define GRP_PROFILE_CNT_EN_DEFAULT 0x0 + /*[field] GRP_CNT_EN_0*/ + #define GRP_PROFILE_CNT_EN_GRP_CNT_EN_0 + #define GRP_PROFILE_CNT_EN_GRP_CNT_EN_0_OFFSET 0 + #define GRP_PROFILE_CNT_EN_GRP_CNT_EN_0_LEN 1 + #define GRP_PROFILE_CNT_EN_GRP_CNT_EN_0_DEFAULT 0x0 + /*[field] GRP_CNT_EN_1*/ + #define GRP_PROFILE_CNT_EN_GRP_CNT_EN_1 + #define GRP_PROFILE_CNT_EN_GRP_CNT_EN_1_OFFSET 1 + #define GRP_PROFILE_CNT_EN_GRP_CNT_EN_1_LEN 1 + #define GRP_PROFILE_CNT_EN_GRP_CNT_EN_1_DEFAULT 0x0 + /*[field] GRP_CNT_EN_2*/ + #define GRP_PROFILE_CNT_EN_GRP_CNT_EN_2 + #define GRP_PROFILE_CNT_EN_GRP_CNT_EN_2_OFFSET 2 + #define GRP_PROFILE_CNT_EN_GRP_CNT_EN_2_LEN 1 + #define GRP_PROFILE_CNT_EN_GRP_CNT_EN_2_DEFAULT 0x0 + /*[field] GRP_CNT_EN_3*/ + #define GRP_PROFILE_CNT_EN_GRP_CNT_EN_3 + #define GRP_PROFILE_CNT_EN_GRP_CNT_EN_3_OFFSET 3 + #define GRP_PROFILE_CNT_EN_GRP_CNT_EN_3_LEN 1 + #define GRP_PROFILE_CNT_EN_GRP_CNT_EN_3_DEFAULT 0x0 + /*[field] TOT_RECT_CNT_EN*/ + #define GRP_PROFILE_CNT_EN_TOT_RECT_CNT_EN + #define GRP_PROFILE_CNT_EN_TOT_RECT_CNT_EN_OFFSET 4 + #define GRP_PROFILE_CNT_EN_TOT_RECT_CNT_EN_LEN 1 + #define GRP_PROFILE_CNT_EN_TOT_RECT_CNT_EN_DEFAULT 0x0 + +struct grp_profile_cnt_en { + a_uint32_t grp_cnt_en_0:1; + a_uint32_t grp_cnt_en_1:1; + a_uint32_t grp_cnt_en_2:1; + a_uint32_t grp_cnt_en_3:1; + a_uint32_t tot_rect_cnt_en:1; + a_uint32_t _reserved0:27; +}; + +union grp_profile_cnt_en_u { + a_uint32_t val; + struct grp_profile_cnt_en bf; +}; + +/*[register] PORT_PROFILE_TH_CFG*/ +#define PORT_PROFILE_TH_CFG +#define PORT_PROFILE_TH_CFG_ADDRESS 0x308 +#define PORT_PROFILE_TH_CFG_NUM 15 +#define PORT_PROFILE_TH_CFG_INC 0x4 +#define PORT_PROFILE_TH_CFG_TYPE REG_TYPE_RW +#define PORT_PROFILE_TH_CFG_DEFAULT 0x0 + /*[field] PORT_PROFILE_TH_CFG*/ + #define PORT_PROFILE_TH_CFG_PORT_PROFILE_TH_CFG + #define PORT_PROFILE_TH_CFG_PORT_PROFILE_TH_CFG_OFFSET 0 + #define PORT_PROFILE_TH_CFG_PORT_PROFILE_TH_CFG_LEN 11 + #define PORT_PROFILE_TH_CFG_PORT_PROFILE_TH_CFG_DEFAULT 0x0 + +struct port_profile_th_cfg { + a_uint32_t port_profile_th_cfg:11; + a_uint32_t _reserved0:21; +}; + +union port_profile_th_cfg_u { + a_uint32_t val; + struct port_profile_th_cfg bf; +}; + +/*[register] REACT_PROFILE_TH_CFG*/ +#define REACT_PROFILE_TH_CFG +#define REACT_PROFILE_TH_CFG_ADDRESS 0x348 +#define REACT_PROFILE_TH_CFG_NUM 15 +#define REACT_PROFILE_TH_CFG_INC 0x4 +#define REACT_PROFILE_TH_CFG_TYPE REG_TYPE_RW +#define REACT_PROFILE_TH_CFG_DEFAULT 0x0 + /*[field] REACT_PROFILE_TH_CFG*/ + #define REACT_PROFILE_TH_CFG_REACT_PROFILE_TH_CFG + #define REACT_PROFILE_TH_CFG_REACT_PROFILE_TH_CFG_OFFSET 0 + #define REACT_PROFILE_TH_CFG_REACT_PROFILE_TH_CFG_LEN 9 + #define REACT_PROFILE_TH_CFG_REACT_PROFILE_TH_CFG_DEFAULT 0x0 + +struct react_profile_th_cfg { + a_uint32_t react_profile_th_cfg:9; + a_uint32_t _reserved0:23; +}; + +union react_profile_th_cfg_u { + a_uint32_t val; + struct react_profile_th_cfg bf; +}; + +/*[register] GRP_PROFILE_TH_CFG*/ +#define GRP_PROFILE_TH_CFG +#define GRP_PROFILE_TH_CFG_ADDRESS 0x388 +#define GRP_PROFILE_TH_CFG_NUM 4 +#define GRP_PROFILE_TH_CFG_INC 0x4 +#define GRP_PROFILE_TH_CFG_TYPE REG_TYPE_RW +#define GRP_PROFILE_TH_CFG_DEFAULT 0x0 + /*[field] GRP_PROFILE_TH_CFG*/ + #define GRP_PROFILE_TH_CFG_GRP_PROFILE_TH_CFG + #define GRP_PROFILE_TH_CFG_GRP_PROFILE_TH_CFG_OFFSET 0 + #define GRP_PROFILE_TH_CFG_GRP_PROFILE_TH_CFG_LEN 11 + #define GRP_PROFILE_TH_CFG_GRP_PROFILE_TH_CFG_DEFAULT 0x0 + +struct grp_profile_th_cfg { + a_uint32_t grp_profile_th_cfg:11; + a_uint32_t _reserved0:21; +}; + +union grp_profile_th_cfg_u { + a_uint32_t val; + struct grp_profile_th_cfg bf; +}; + +/*[register] TOT_REACT_PROFILE_TH_CFG*/ +#define TOT_REACT_PROFILE_TH_CFG +#define TOT_REACT_PROFILE_TH_CFG_ADDRESS 0x398 +#define TOT_REACT_PROFILE_TH_CFG_NUM 1 +#define TOT_REACT_PROFILE_TH_CFG_INC 0x4 +#define TOT_REACT_PROFILE_TH_CFG_TYPE REG_TYPE_RW +#define TOT_REACT_PROFILE_TH_CFG_DEFAULT 0x0 + /*[field] TOT_REACT_PROFILE_TH_CFG*/ + #define TOT_REACT_PROFILE_TH_CFG_TOT_REACT_PROFILE_TH_CFG + #define TOT_REACT_PROFILE_TH_CFG_TOT_REACT_PROFILE_TH_CFG_OFFSET 0 + #define TOT_REACT_PROFILE_TH_CFG_TOT_REACT_PROFILE_TH_CFG_LEN 11 + #define TOT_REACT_PROFILE_TH_CFG_TOT_REACT_PROFILE_TH_CFG_DEFAULT 0x0 + +struct tot_react_profile_th_cfg { + a_uint32_t tot_react_profile_th_cfg:11; + a_uint32_t _reserved0:21; +}; + +union tot_react_profile_th_cfg_u { + a_uint32_t val; + struct tot_react_profile_th_cfg bf; +}; + +/*[register] PORT_OUT_PROFILE_CNT*/ +#define PORT_OUT_PROFILE_CNT +#define PORT_OUT_PROFILE_CNT_ADDRESS 0x3a0 +#define PORT_OUT_PROFILE_CNT_NUM 15 +#define PORT_OUT_PROFILE_CNT_INC 0x4 +#define PORT_OUT_PROFILE_CNT_TYPE REG_TYPE_RW +#define PORT_OUT_PROFILE_CNT_DEFAULT 0x0 + /*[field] PORT_OUT_PROFILE_CNT*/ + #define PORT_OUT_PROFILE_CNT_PORT_OUT_PROFILE_CNT + #define PORT_OUT_PROFILE_CNT_PORT_OUT_PROFILE_CNT_OFFSET 0 + #define PORT_OUT_PROFILE_CNT_PORT_OUT_PROFILE_CNT_LEN 32 + #define PORT_OUT_PROFILE_CNT_PORT_OUT_PROFILE_CNT_DEFAULT 0x0 + +struct port_out_profile_cnt { + a_uint32_t port_out_profile_cnt:32; +}; + +union port_out_profile_cnt_u { + a_uint32_t val; + struct port_out_profile_cnt bf; +}; + +/*[register] PORT_IN_PROFILE_CNT*/ +#define PORT_IN_PROFILE_CNT +#define PORT_IN_PROFILE_CNT_ADDRESS 0x3e0 +#define PORT_IN_PROFILE_CNT_NUM 15 +#define PORT_IN_PROFILE_CNT_INC 0x4 +#define PORT_IN_PROFILE_CNT_TYPE REG_TYPE_RW +#define PORT_IN_PROFILE_CNT_DEFAULT 0x0 + /*[field] PORT_IN_PROFILE_CNT*/ + #define PORT_IN_PROFILE_CNT_PORT_IN_PROFILE_CNT + #define PORT_IN_PROFILE_CNT_PORT_IN_PROFILE_CNT_OFFSET 0 + #define PORT_IN_PROFILE_CNT_PORT_IN_PROFILE_CNT_LEN 32 + #define PORT_IN_PROFILE_CNT_PORT_IN_PROFILE_CNT_DEFAULT 0x0 + +struct port_in_profile_cnt { + a_uint32_t port_in_profile_cnt:32; +}; + +union port_in_profile_cnt_u { + a_uint32_t val; + struct port_in_profile_cnt bf; +}; + +/*[register] REACT_OUT_PROFILE_CNT*/ +#define REACT_OUT_PROFILE_CNT +#define REACT_OUT_PROFILE_CNT_ADDRESS 0x420 +#define REACT_OUT_PROFILE_CNT_NUM 15 +#define REACT_OUT_PROFILE_CNT_INC 0x4 +#define REACT_OUT_PROFILE_CNT_TYPE REG_TYPE_RW +#define REACT_OUT_PROFILE_CNT_DEFAULT 0x0 + /*[field] REACT_OUT_PROFILE_CNT*/ + #define REACT_OUT_PROFILE_CNT_REACT_OUT_PROFILE_CNT + #define REACT_OUT_PROFILE_CNT_REACT_OUT_PROFILE_CNT_OFFSET 0 + #define REACT_OUT_PROFILE_CNT_REACT_OUT_PROFILE_CNT_LEN 32 + #define REACT_OUT_PROFILE_CNT_REACT_OUT_PROFILE_CNT_DEFAULT 0x0 + +struct react_out_profile_cnt { + a_uint32_t react_out_profile_cnt:32; +}; + +union react_out_profile_cnt_u { + a_uint32_t val; + struct react_out_profile_cnt bf; +}; + +/*[register] REACT_IN_PROFILE_CNT*/ +#define REACT_IN_PROFILE_CNT +#define REACT_IN_PROFILE_CNT_ADDRESS 0x460 +#define REACT_IN_PROFILE_CNT_NUM 15 +#define REACT_IN_PROFILE_CNT_INC 0x4 +#define REACT_IN_PROFILE_CNT_TYPE REG_TYPE_RW +#define REACT_IN_PROFILE_CNT_DEFAULT 0x0 + /*[field] REACT_IN_PROFILE_CNT*/ + #define REACT_IN_PROFILE_CNT_REACT_IN_PROFILE_CNT + #define REACT_IN_PROFILE_CNT_REACT_IN_PROFILE_CNT_OFFSET 0 + #define REACT_IN_PROFILE_CNT_REACT_IN_PROFILE_CNT_LEN 32 + #define REACT_IN_PROFILE_CNT_REACT_IN_PROFILE_CNT_DEFAULT 0x0 + +struct react_in_profile_cnt { + a_uint32_t react_in_profile_cnt:32; +}; + +union react_in_profile_cnt_u { + a_uint32_t val; + struct react_in_profile_cnt bf; +}; + +/*[register] GRP_OUT_PROFILE_CNT*/ +#define GRP_OUT_PROFILE_CNT +#define GRP_OUT_PROFILE_CNT_ADDRESS 0x4a0 +#define GRP_OUT_PROFILE_CNT_NUM 4 +#define GRP_OUT_PROFILE_CNT_INC 0x4 +#define GRP_OUT_PROFILE_CNT_TYPE REG_TYPE_RW +#define GRP_OUT_PROFILE_CNT_DEFAULT 0x0 + /*[field] GRP_OUT_PROFILE_CNT*/ + #define GRP_OUT_PROFILE_CNT_GRP_OUT_PROFILE_CNT + #define GRP_OUT_PROFILE_CNT_GRP_OUT_PROFILE_CNT_OFFSET 0 + #define GRP_OUT_PROFILE_CNT_GRP_OUT_PROFILE_CNT_LEN 32 + #define GRP_OUT_PROFILE_CNT_GRP_OUT_PROFILE_CNT_DEFAULT 0x0 + +struct grp_out_profile_cnt { + a_uint32_t grp_out_profile_cnt:32; +}; + +union grp_out_profile_cnt_u { + a_uint32_t val; + struct grp_out_profile_cnt bf; +}; + +/*[register] GRP_IN_PROFILE_CNT*/ +#define GRP_IN_PROFILE_CNT +#define GRP_IN_PROFILE_CNT_ADDRESS 0x4b0 +#define GRP_IN_PROFILE_CNT_NUM 4 +#define GRP_IN_PROFILE_CNT_INC 0x4 +#define GRP_IN_PROFILE_CNT_TYPE REG_TYPE_RW +#define GRP_IN_PROFILE_CNT_DEFAULT 0x0 + /*[field] GRP_IN_PROFILE_CNT*/ + #define GRP_IN_PROFILE_CNT_GRP_IN_PROFILE_CNT + #define GRP_IN_PROFILE_CNT_GRP_IN_PROFILE_CNT_OFFSET 0 + #define GRP_IN_PROFILE_CNT_GRP_IN_PROFILE_CNT_LEN 32 + #define GRP_IN_PROFILE_CNT_GRP_IN_PROFILE_CNT_DEFAULT 0x0 + +struct grp_in_profile_cnt { + a_uint32_t grp_in_profile_cnt:32; +}; + +union grp_in_profile_cnt_u { + a_uint32_t val; + struct grp_in_profile_cnt bf; +}; + +/*[register] TOT_REACT_OUT_PROFILE_CNT*/ +#define TOT_REACT_OUT_PROFILE_CNT +#define TOT_REACT_OUT_PROFILE_CNT_ADDRESS 0x4c0 +#define TOT_REACT_OUT_PROFILE_CNT_NUM 1 +#define TOT_REACT_OUT_PROFILE_CNT_INC 0x4 +#define TOT_REACT_OUT_PROFILE_CNT_TYPE REG_TYPE_RW +#define TOT_REACT_OUT_PROFILE_CNT_DEFAULT 0x0 + /*[field] TOT_REACT_OUT_PROFILE_CNT*/ + #define TOT_REACT_OUT_PROFILE_CNT_TOT_REACT_OUT_PROFILE_CNT + #define TOT_REACT_OUT_PROFILE_CNT_TOT_REACT_OUT_PROFILE_CNT_OFFSET 0 + #define TOT_REACT_OUT_PROFILE_CNT_TOT_REACT_OUT_PROFILE_CNT_LEN 32 + #define TOT_REACT_OUT_PROFILE_CNT_TOT_REACT_OUT_PROFILE_CNT_DEFAULT 0x0 + +struct tot_react_out_profile_cnt { + a_uint32_t tot_react_out_profile_cnt:32; +}; + +union tot_react_out_profile_cnt_u { + a_uint32_t val; + struct tot_react_out_profile_cnt bf; +}; + +/*[register] TOT_REACT_IN_PROFILE_CNT*/ +#define TOT_REACT_IN_PROFILE_CNT +#define TOT_REACT_IN_PROFILE_CNT_ADDRESS 0x4c4 +#define TOT_REACT_IN_PROFILE_CNT_NUM 1 +#define TOT_REACT_IN_PROFILE_CNT_INC 0x4 +#define TOT_REACT_IN_PROFILE_CNT_TYPE REG_TYPE_RW +#define TOT_REACT_IN_PROFILE_CNT_DEFAULT 0x0 + /*[field] TOT_REACT_IN_PROFILE_CNT*/ + #define TOT_REACT_IN_PROFILE_CNT_TOT_REACT_IN_PROFILE_CNT + #define TOT_REACT_IN_PROFILE_CNT_TOT_REACT_IN_PROFILE_CNT_OFFSET 0 + #define TOT_REACT_IN_PROFILE_CNT_TOT_REACT_IN_PROFILE_CNT_LEN 32 + #define TOT_REACT_IN_PROFILE_CNT_TOT_REACT_IN_PROFILE_CNT_DEFAULT 0x0 + +struct tot_react_in_profile_cnt { + a_uint32_t tot_react_in_profile_cnt:32; +}; + +union tot_react_in_profile_cnt_u { + a_uint32_t val; + struct tot_react_in_profile_cnt bf; +}; + +/*[table] PORT_FC_CFG*/ +#define PORT_FC_CFG +#define PORT_FC_CFG_ADDRESS 0x1000 +#define PORT_FC_CFG_NUM 15 +#define PORT_FC_CFG_INC 0x10 +#define PORT_FC_CFG_TYPE REG_TYPE_RW +#define PORT_FC_CFG_DEFAULT 0x0 + /*[field] PORT_REACT_LIMIT*/ + #define PORT_FC_CFG_PORT_REACT_LIMIT + #define PORT_FC_CFG_PORT_REACT_LIMIT_OFFSET 0 + #define PORT_FC_CFG_PORT_REACT_LIMIT_LEN 9 + #define PORT_FC_CFG_PORT_REACT_LIMIT_DEFAULT 0x0 + /*[field] PORT_RESUME_FLOOR_TH*/ + #define PORT_FC_CFG_PORT_RESUME_FLOOR_TH + #define PORT_FC_CFG_PORT_RESUME_FLOOR_TH_OFFSET 9 + #define PORT_FC_CFG_PORT_RESUME_FLOOR_TH_LEN 9 + #define PORT_FC_CFG_PORT_RESUME_FLOOR_TH_DEFAULT 0x0 + /*[field] PORT_RESUME_OFFSET*/ + #define PORT_FC_CFG_PORT_RESUME_OFFSET + #define PORT_FC_CFG_PORT_RESUME_OFFSET_OFFSET 18 + #define PORT_FC_CFG_PORT_RESUME_OFFSET_LEN 11 + #define PORT_FC_CFG_PORT_RESUME_OFFSET_DEFAULT 0x0 + /*[field] PORT_SHARED_CEILING*/ + #define PORT_FC_CFG_PORT_SHARED_CEILING + #define PORT_FC_CFG_PORT_SHARED_CEILING_OFFSET 29 + #define PORT_FC_CFG_PORT_SHARED_CEILING_LEN 11 + #define PORT_FC_CFG_PORT_SHARED_CEILING_DEFAULT 0x0 + /*[field] PORT_SHARED_WEIGHT*/ + #define PORT_FC_CFG_PORT_SHARED_WEIGHT + #define PORT_FC_CFG_PORT_SHARED_WEIGHT_OFFSET 40 + #define PORT_FC_CFG_PORT_SHARED_WEIGHT_LEN 3 + #define PORT_FC_CFG_PORT_SHARED_WEIGHT_DEFAULT 0x0 + /*[field] PORT_SHARED_DYNAMIC*/ + #define PORT_FC_CFG_PORT_SHARED_DYNAMIC + #define PORT_FC_CFG_PORT_SHARED_DYNAMIC_OFFSET 43 + #define PORT_FC_CFG_PORT_SHARED_DYNAMIC_LEN 1 + #define PORT_FC_CFG_PORT_SHARED_DYNAMIC_DEFAULT 0x0 + /*[field] PORT_PRE_ALLOC*/ + #define PORT_FC_CFG_PORT_PRE_ALLOC + #define PORT_FC_CFG_PORT_PRE_ALLOC_OFFSET 44 + #define PORT_FC_CFG_PORT_PRE_ALLOC_LEN 11 + #define PORT_FC_CFG_PORT_PRE_ALLOC_DEFAULT 0x0 + +struct port_fc_cfg { + a_uint32_t port_react_limit:9; + a_uint32_t port_resume_floor_th:9; + a_uint32_t port_resume_offset:11; + a_uint32_t port_shared_ceiling_0:3; + a_uint32_t port_shared_ceiling_1:8; + a_uint32_t port_shared_weight:3; + a_uint32_t port_shared_dynamic:1; + a_uint32_t port_pre_alloc:11; + a_uint32_t _reserved0:9; +}; + +union port_fc_cfg_u { + a_uint32_t val[2]; + struct port_fc_cfg bf; +}; + +/*[table] LLM*/ +#define LLM +#define LLM_ADDRESS 0x10000 +#define LLM_NUM 2048 +#define LLM_INC 0x10 +#define LLM_TYPE REG_TYPE_RW +#define LLM_DEFAULT 0x0 + /*[field] NXT_PTR*/ + #define LLM_NXT_PTR + #define LLM_NXT_PTR_OFFSET 0 + #define LLM_NXT_PTR_LEN 11 + #define LLM_NXT_PTR_DEFAULT 0x0 + /*[field] EOP*/ + #define LLM_EOP + #define LLM_EOP_OFFSET 11 + #define LLM_EOP_LEN 1 + #define LLM_EOP_DEFAULT 0x0 + +struct llm { + a_uint32_t nxt_ptr:11; + a_uint32_t eop:1; + a_uint32_t _reserved0:20; +}; + +union llm_u { + a_uint32_t val; + struct llm bf; +}; + +/*[table] RCM*/ +#define RCM +#define RCM_ADDRESS 0x20000 +#define RCM_NUM 2048 +#define RCM_INC 0x10 +#define RCM_TYPE REG_TYPE_RW +#define RCM_DEFAULT 0x0 + /*[field] REF_CNT*/ + #define RCM_REF_CNT + #define RCM_REF_CNT_OFFSET 0 + #define RCM_REF_CNT_LEN 4 + #define RCM_REF_CNT_DEFAULT 0x0 + +struct rcm { + a_uint32_t ref_cnt:4; + a_uint32_t _reserved0:28; +}; + +union rcm_u { + a_uint32_t val; + struct rcm bf; +}; + +/*[table] DM*/ +#define DM +#define DM_ADDRESS 0x80000 +#define DM_NUM 8192 +#define DM_INC 0x40 +#define DM_TYPE REG_TYPE_RW +#define DM_DEFAULT 0x0 + /*[field] PKT_DATA*/ + #define DM_PKT_DATA + #define DM_PKT_DATA_OFFSET 0 + #define DM_PKT_DATA_LEN 512 + #define DM_PKT_DATA_DEFAULT 0x0 + +struct dm { + a_uint32_t pkt_data_0:32; + a_uint32_t pkt_data_1:32; + a_uint32_t pkt_data_2:32; + a_uint32_t pkt_data_3:32; + a_uint32_t pkt_data_4:32; + a_uint32_t pkt_data_5:32; + a_uint32_t pkt_data_6:32; + a_uint32_t pkt_data_7:32; + a_uint32_t pkt_data_8:32; + a_uint32_t pkt_data_9:32; + a_uint32_t pkt_data_10:32; + a_uint32_t pkt_data_11:32; + a_uint32_t pkt_data_12:32; + a_uint32_t pkt_data_13:32; + a_uint32_t pkt_data_14:32; + a_uint32_t pkt_data_15:32; +}; + +union dm_u { + a_uint32_t val[16]; + struct dm bf; +}; + + +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_ctrlpkt.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_ctrlpkt.h new file mode 100755 index 000000000..83503a3e6 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_ctrlpkt.h @@ -0,0 +1,245 @@ +/* + * 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 + * @{ + */ +#ifndef _HPPE_CTRLPKT_H_ +#define _HPPE_CTRLPKT_H_ + +#define ETHERTYPE_CTRL_MAX_ENTRY 4 +#define RFDB_TBL_MAX_ENTRY 32 +#define APP_CTRL_MAX_ENTRY 32 + + +sw_error_t +hppe_ethertype_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union ethertype_ctrl_u *value); + +sw_error_t +hppe_ethertype_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union ethertype_ctrl_u *value); + +sw_error_t +hppe_app_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union app_ctrl_u *value); + +sw_error_t +hppe_app_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union app_ctrl_u *value); + +sw_error_t +hppe_ethertype_ctrl_ethertype_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ethertype_ctrl_ethertype_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ethertype_ctrl_ethertype_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ethertype_ctrl_ethertype_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_app_ctrl_portbitmap_include_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_app_ctrl_portbitmap_include_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_app_ctrl_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_app_ctrl_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_app_ctrl_portbitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_app_ctrl_portbitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_app_ctrl_rfdb_index_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_app_ctrl_rfdb_index_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_app_ctrl_protocol_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_app_ctrl_protocol_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_app_ctrl_in_stg_byp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_app_ctrl_in_stg_byp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_app_ctrl_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_app_ctrl_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_app_ctrl_l2_sec_byp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_app_ctrl_l2_sec_byp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_app_ctrl_protocol_include_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_app_ctrl_protocol_include_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_app_ctrl_ethertype_include_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_app_ctrl_ethertype_include_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_app_ctrl_sg_byp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_app_ctrl_sg_byp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_app_ctrl_rfdb_include_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_app_ctrl_rfdb_include_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_app_ctrl_ethertype_index_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_app_ctrl_ethertype_index_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_app_ctrl_in_vlan_fltr_byp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_app_ctrl_in_vlan_fltr_byp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_ctrlpkt_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_ctrlpkt_reg.h new file mode 100755 index 000000000..943157f06 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_ctrlpkt_reg.h @@ -0,0 +1,154 @@ +/* + * 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 HPPE_CTRLPKT_REG_H +#define HPPE_CTRLPKT_REG_H + +/** + * @defgroup + * @{ + */ +/*[register] ETHERTYPE_CTRL*/ +#define ETHERTYPE_CTRL +#define ETHERTYPE_CTRL_ADDRESS 0x80 +#define ETHERTYPE_CTRL_NUM 4 +#define ETHERTYPE_CTRL_INC 0x4 +#define ETHERTYPE_CTRL_TYPE REG_TYPE_RW +#define ETHERTYPE_CTRL_DEFAULT 0x0 + /*[field] ETHERTYPE_EN*/ + #define ETHERTYPE_CTRL_ETHERTYPE_EN + #define ETHERTYPE_CTRL_ETHERTYPE_EN_OFFSET 0 + #define ETHERTYPE_CTRL_ETHERTYPE_EN_LEN 1 + #define ETHERTYPE_CTRL_ETHERTYPE_EN_DEFAULT 0x0 + /*[field] ETHERTYPE*/ + #define ETHERTYPE_CTRL_ETHERTYPE + #define ETHERTYPE_CTRL_ETHERTYPE_OFFSET 16 + #define ETHERTYPE_CTRL_ETHERTYPE_LEN 16 + #define ETHERTYPE_CTRL_ETHERTYPE_DEFAULT 0x0 + +struct ethertype_ctrl { + a_uint32_t ethertype_en:1; + a_uint32_t _reserved0:15; + a_uint32_t ethertype:16; +}; + +union ethertype_ctrl_u { + a_uint32_t val; + struct ethertype_ctrl bf; +}; + +/*[table] APP_CTRL*/ +#define APP_CTRL +#define APP_CTRL_ADDRESS 0x1400 +#define APP_CTRL_NUM 32 +#define APP_CTRL_INC 0x10 +#define APP_CTRL_TYPE REG_TYPE_RW +#define APP_CTRL_DEFAULT 0x0 + /*[field] VALID*/ + #define APP_CTRL_VALID + #define APP_CTRL_VALID_OFFSET 0 + #define APP_CTRL_VALID_LEN 1 + #define APP_CTRL_VALID_DEFAULT 0x0 + /*[field] RFDB_INCLUDE*/ + #define APP_CTRL_RFDB_INCLUDE + #define APP_CTRL_RFDB_INCLUDE_OFFSET 1 + #define APP_CTRL_RFDB_INCLUDE_LEN 1 + #define APP_CTRL_RFDB_INCLUDE_DEFAULT 0x0 + /*[field] RFDB_INDEX_BITMAP*/ + #define APP_CTRL_RFDB_INDEX_BITMAP + #define APP_CTRL_RFDB_INDEX_BITMAP_OFFSET 2 + #define APP_CTRL_RFDB_INDEX_BITMAP_LEN 32 + #define APP_CTRL_RFDB_INDEX_BITMAP_DEFAULT 0x0 + /*[field] PROTOCOL_INCLUDE*/ + #define APP_CTRL_PROTOCOL_INCLUDE + #define APP_CTRL_PROTOCOL_INCLUDE_OFFSET 34 + #define APP_CTRL_PROTOCOL_INCLUDE_LEN 1 + #define APP_CTRL_PROTOCOL_INCLUDE_DEFAULT 0x0 + /*[field] PROTOCOL_BITMAP*/ + #define APP_CTRL_PROTOCOL_BITMAP + #define APP_CTRL_PROTOCOL_BITMAP_OFFSET 35 + #define APP_CTRL_PROTOCOL_BITMAP_LEN 26 + #define APP_CTRL_PROTOCOL_BITMAP_DEFAULT 0x0 + /*[field] ETHERTYPE_INCLUDE*/ + #define APP_CTRL_ETHERTYPE_INCLUDE + #define APP_CTRL_ETHERTYPE_INCLUDE_OFFSET 61 + #define APP_CTRL_ETHERTYPE_INCLUDE_LEN 1 + #define APP_CTRL_ETHERTYPE_INCLUDE_DEFAULT 0x0 + /*[field] ETHERTYPE_INDEX_BITMAP*/ + #define APP_CTRL_ETHERTYPE_INDEX_BITMAP + #define APP_CTRL_ETHERTYPE_INDEX_BITMAP_OFFSET 62 + #define APP_CTRL_ETHERTYPE_INDEX_BITMAP_LEN 4 + #define APP_CTRL_ETHERTYPE_INDEX_BITMAP_DEFAULT 0x0 + /*[field] PORTBITMAP_INCLUDE*/ + #define APP_CTRL_PORTBITMAP_INCLUDE + #define APP_CTRL_PORTBITMAP_INCLUDE_OFFSET 66 + #define APP_CTRL_PORTBITMAP_INCLUDE_LEN 1 + #define APP_CTRL_PORTBITMAP_INCLUDE_DEFAULT 0x0 + /*[field] PORTBITMAP*/ + #define APP_CTRL_PORTBITMAP + #define APP_CTRL_PORTBITMAP_OFFSET 67 + #define APP_CTRL_PORTBITMAP_LEN 8 + #define APP_CTRL_PORTBITMAP_DEFAULT 0x0 + /*[field] IN_VLAN_FLTR_BYP*/ + #define APP_CTRL_IN_VLAN_FLTR_BYP + #define APP_CTRL_IN_VLAN_FLTR_BYP_OFFSET 75 + #define APP_CTRL_IN_VLAN_FLTR_BYP_LEN 1 + #define APP_CTRL_IN_VLAN_FLTR_BYP_DEFAULT 0x0 + /*[field] IN_STG_BYP*/ + #define APP_CTRL_IN_STG_BYP + #define APP_CTRL_IN_STG_BYP_OFFSET 76 + #define APP_CTRL_IN_STG_BYP_LEN 1 + #define APP_CTRL_IN_STG_BYP_DEFAULT 0x0 + /*[field] L2_SEC_BYP*/ + #define APP_CTRL_L2_SEC_BYP + #define APP_CTRL_L2_SEC_BYP_OFFSET 77 + #define APP_CTRL_L2_SEC_BYP_LEN 1 + #define APP_CTRL_L2_SEC_BYP_DEFAULT 0x0 + /*[field] SG_BYP*/ + #define APP_CTRL_SG_BYP + #define APP_CTRL_SG_BYP_OFFSET 78 + #define APP_CTRL_SG_BYP_LEN 1 + #define APP_CTRL_SG_BYP_DEFAULT 0x0 + /*[field] CMD*/ + #define APP_CTRL_CMD + #define APP_CTRL_CMD_OFFSET 79 + #define APP_CTRL_CMD_LEN 2 + #define APP_CTRL_CMD_DEFAULT 0x0 + +struct app_ctrl { + a_uint32_t valid:1; + a_uint32_t rfdb_include:1; + a_uint32_t rfdb_index_bitmap_0:30; + a_uint32_t rfdb_index_bitmap_1:2; + a_uint32_t protocol_include:1; + a_uint32_t protocol_bitmap:26; + a_uint32_t ethertype_include:1; + a_uint32_t ethertype_index_bitmap_0:2; + a_uint32_t ethertype_index_bitmap_1:2; + a_uint32_t portbitmap_include:1; + a_uint32_t portbitmap:8; + a_uint32_t in_vlan_fltr_byp:1; + a_uint32_t in_stg_byp:1; + a_uint32_t l2_sec_byp:1; + a_uint32_t sg_byp:1; + a_uint32_t cmd:2; + a_uint32_t _reserved0:15; +}; + +union app_ctrl_u { + a_uint32_t val[3]; + struct app_ctrl bf; +}; + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_fdb.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_fdb.h new file mode 100755 index 000000000..d99bfd6ba --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_fdb.h @@ -0,0 +1,900 @@ +/* + * 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 + * @{ + */ +#ifndef _HPPE_FDB_H_ +#define _HPPE_FDB_H_ + +#define PRE_L2_CNT_TBL_MAX_ENTRY 32 +#define PORT_BRIDGE_CTRL_MAX_ENTRY 8 +#define PORT_LRN_LIMIT_CTRL_MAX_ENTRY 8 +#define PORT_LRN_LIMIT_COUNTER_MAX_ENTRY 8 +#define RFDB_TBL_MAX_ENTRY 32 +#define FDB_TBL_MAX_ENTRY 2048 + + +sw_error_t +hppe_l2_dbg_addr_get( + a_uint32_t dev_id, + union l2_dbg_addr_u *value); + +sw_error_t +hppe_l2_dbg_addr_set( + a_uint32_t dev_id, + union l2_dbg_addr_u *value); + +sw_error_t +hppe_l2_dbg_data_get( + a_uint32_t dev_id, + union l2_dbg_data_u *value); + +sw_error_t +hppe_l2_dbg_data_set( + a_uint32_t dev_id, + union l2_dbg_data_u *value); + +sw_error_t +hppe_fdb_tbl_op_get( + a_uint32_t dev_id, + union fdb_tbl_op_u *value); + +sw_error_t +hppe_fdb_tbl_op_set( + a_uint32_t dev_id, + union fdb_tbl_op_u *value); + +sw_error_t +hppe_fdb_tbl_rd_op_get( + a_uint32_t dev_id, + union fdb_tbl_rd_op_u *value); + +sw_error_t +hppe_fdb_tbl_rd_op_set( + a_uint32_t dev_id, + union fdb_tbl_rd_op_u *value); + +sw_error_t +hppe_fdb_tbl_op_rslt_get( + a_uint32_t dev_id, + union fdb_tbl_op_rslt_u *value); + +sw_error_t +hppe_fdb_tbl_op_rslt_set( + a_uint32_t dev_id, + union fdb_tbl_op_rslt_u *value); + +sw_error_t +hppe_fdb_tbl_rd_op_rslt_get( + a_uint32_t dev_id, + union fdb_tbl_rd_op_rslt_u *value); + +sw_error_t +hppe_fdb_tbl_rd_op_rslt_set( + a_uint32_t dev_id, + union fdb_tbl_rd_op_rslt_u *value); + +sw_error_t +hppe_age_timer_get( + a_uint32_t dev_id, + union age_timer_u *value); + +sw_error_t +hppe_age_timer_set( + a_uint32_t dev_id, + union age_timer_u *value); + +sw_error_t +hppe_l2_global_conf_get( + a_uint32_t dev_id, + union l2_global_conf_u *value); + +sw_error_t +hppe_l2_global_conf_set( + a_uint32_t dev_id, + union l2_global_conf_u *value); + +sw_error_t +hppe_l2_dbgcnt_cmd_get( + a_uint32_t dev_id, + union l2_dbgcnt_cmd_u *value); + +sw_error_t +hppe_l2_dbgcnt_cmd_set( + a_uint32_t dev_id, + union l2_dbgcnt_cmd_u *value); + +sw_error_t +hppe_l2_dbgcnt_rdata_get( + a_uint32_t dev_id, + union l2_dbgcnt_rdata_u *value); + +sw_error_t +hppe_l2_dbgcnt_rdata_set( + a_uint32_t dev_id, + union l2_dbgcnt_rdata_u *value); + +sw_error_t +hppe_l2_dbgcnt_wdata_get( + a_uint32_t dev_id, + union l2_dbgcnt_wdata_u *value); + +sw_error_t +hppe_l2_dbgcnt_wdata_set( + a_uint32_t dev_id, + union l2_dbgcnt_wdata_u *value); + +sw_error_t +hppe_fdb_tbl_rd_op_rslt_data0_get( + a_uint32_t dev_id, + union fdb_tbl_rd_op_rslt_data0_u *value); + +sw_error_t +hppe_fdb_tbl_rd_op_rslt_data0_set( + a_uint32_t dev_id, + union fdb_tbl_rd_op_rslt_data0_u *value); + +sw_error_t +hppe_fdb_tbl_rd_op_rslt_data1_get( + a_uint32_t dev_id, + union fdb_tbl_rd_op_rslt_data1_u *value); + +sw_error_t +hppe_fdb_tbl_rd_op_rslt_data1_set( + a_uint32_t dev_id, + union fdb_tbl_rd_op_rslt_data1_u *value); + +sw_error_t +hppe_fdb_tbl_rd_op_rslt_data2_get( + a_uint32_t dev_id, + union fdb_tbl_rd_op_rslt_data2_u *value); + +sw_error_t +hppe_fdb_tbl_rd_op_rslt_data2_set( + a_uint32_t dev_id, + union fdb_tbl_rd_op_rslt_data2_u *value); + +sw_error_t +hppe_fdb_tbl_op_data0_get( + a_uint32_t dev_id, + union fdb_tbl_op_data0_u *value); + +sw_error_t +hppe_fdb_tbl_op_data0_set( + a_uint32_t dev_id, + union fdb_tbl_op_data0_u *value); + +sw_error_t +hppe_fdb_tbl_op_data1_get( + a_uint32_t dev_id, + union fdb_tbl_op_data1_u *value); + +sw_error_t +hppe_fdb_tbl_op_data1_set( + a_uint32_t dev_id, + union fdb_tbl_op_data1_u *value); + +sw_error_t +hppe_fdb_tbl_op_data2_get( + a_uint32_t dev_id, + union fdb_tbl_op_data2_u *value); + +sw_error_t +hppe_fdb_tbl_op_data2_set( + a_uint32_t dev_id, + union fdb_tbl_op_data2_u *value); + +sw_error_t +hppe_fdb_tbl_rd_op_data0_get( + a_uint32_t dev_id, + union fdb_tbl_rd_op_data0_u *value); + +sw_error_t +hppe_fdb_tbl_rd_op_data0_set( + a_uint32_t dev_id, + union fdb_tbl_rd_op_data0_u *value); + +sw_error_t +hppe_fdb_tbl_rd_op_data1_get( + a_uint32_t dev_id, + union fdb_tbl_rd_op_data1_u *value); + +sw_error_t +hppe_fdb_tbl_rd_op_data1_set( + a_uint32_t dev_id, + union fdb_tbl_rd_op_data1_u *value); + +sw_error_t +hppe_fdb_tbl_rd_op_data2_get( + a_uint32_t dev_id, + union fdb_tbl_rd_op_data2_u *value); + +sw_error_t +hppe_fdb_tbl_rd_op_data2_set( + a_uint32_t dev_id, + union fdb_tbl_rd_op_data2_u *value); + +sw_error_t +hppe_port_bridge_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_bridge_ctrl_u *value); + +sw_error_t +hppe_port_bridge_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_bridge_ctrl_u *value); + +sw_error_t +hppe_port_lrn_limit_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_lrn_limit_ctrl_u *value); + +sw_error_t +hppe_port_lrn_limit_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_lrn_limit_ctrl_u *value); + +sw_error_t +hppe_port_lrn_limit_counter_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_lrn_limit_counter_u *value); + +sw_error_t +hppe_port_lrn_limit_counter_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_lrn_limit_counter_u *value); + +sw_error_t +hppe_rfdb_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union rfdb_tbl_u *value); + +sw_error_t +hppe_rfdb_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union rfdb_tbl_u *value); + +sw_error_t +hppe_fdb_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union fdb_tbl_u *value); + +sw_error_t +hppe_fdb_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union fdb_tbl_u *value); + +sw_error_t +hppe_l2_dbg_addr_l2_dbg_addr_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l2_dbg_addr_l2_dbg_addr_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l2_dbg_data_l2_dbg_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l2_dbg_data_l2_dbg_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_fdb_tbl_op_op_mode_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_fdb_tbl_op_op_mode_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_fdb_tbl_op_op_type_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_fdb_tbl_op_op_type_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_fdb_tbl_op_entry_index_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_fdb_tbl_op_entry_index_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_fdb_tbl_op_cmd_id_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_fdb_tbl_op_cmd_id_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_fdb_tbl_op_hash_block_bitmap_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_fdb_tbl_op_hash_block_bitmap_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_fdb_tbl_op_byp_rslt_en_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_fdb_tbl_op_byp_rslt_en_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_fdb_tbl_rd_op_op_mode_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_fdb_tbl_rd_op_op_mode_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_fdb_tbl_rd_op_op_type_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_fdb_tbl_rd_op_op_type_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_fdb_tbl_rd_op_entry_index_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_fdb_tbl_rd_op_entry_index_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_fdb_tbl_rd_op_cmd_id_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_fdb_tbl_rd_op_cmd_id_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_fdb_tbl_rd_op_hash_block_bitmap_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_fdb_tbl_rd_op_hash_block_bitmap_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_fdb_tbl_rd_op_byp_rslt_en_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_fdb_tbl_rd_op_byp_rslt_en_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_fdb_tbl_op_rslt_op_rslt_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_fdb_tbl_op_rslt_op_rslt_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_fdb_tbl_op_rslt_valid_cnt_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_fdb_tbl_op_rslt_valid_cnt_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_fdb_tbl_op_rslt_entry_index_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_fdb_tbl_op_rslt_entry_index_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_fdb_tbl_op_rslt_cmd_id_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_fdb_tbl_op_rslt_cmd_id_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_fdb_tbl_rd_op_rslt_op_rslt_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_fdb_tbl_rd_op_rslt_op_rslt_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_fdb_tbl_rd_op_rslt_valid_cnt_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_fdb_tbl_rd_op_rslt_valid_cnt_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_fdb_tbl_rd_op_rslt_entry_index_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_fdb_tbl_rd_op_rslt_entry_index_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_fdb_tbl_rd_op_rslt_cmd_id_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_fdb_tbl_rd_op_rslt_cmd_id_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_age_timer_age_val_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_age_timer_age_val_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l2_global_conf_fdb_hash_full_fwd_cmd_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l2_global_conf_fdb_hash_full_fwd_cmd_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l2_global_conf_failover_en_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l2_global_conf_failover_en_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l2_global_conf_lrn_ctrl_mode_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l2_global_conf_lrn_ctrl_mode_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l2_global_conf_age_en_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l2_global_conf_age_en_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l2_global_conf_fdb_hash_mode_1_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l2_global_conf_fdb_hash_mode_1_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l2_global_conf_lrn_en_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l2_global_conf_lrn_en_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l2_global_conf_fdb_hash_mode_0_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l2_global_conf_fdb_hash_mode_0_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l2_global_conf_age_ctrl_mode_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l2_global_conf_age_ctrl_mode_set( + a_uint32_t dev_id, + unsigned int value); + +#ifndef IN_FDB_MINI +sw_error_t +hppe_l2_global_conf_service_code_loop_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l2_global_conf_service_code_loop_set( + a_uint32_t dev_id, + unsigned int value); +#endif + +sw_error_t +hppe_l2_dbgcnt_cmd_type_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l2_dbgcnt_cmd_type_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l2_dbgcnt_cmd_addr_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l2_dbgcnt_cmd_addr_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l2_dbgcnt_rdata_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l2_dbgcnt_rdata_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l2_dbgcnt_wdata_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l2_dbgcnt_wdata_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_fdb_tbl_rd_op_rslt_data0_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_fdb_tbl_rd_op_rslt_data0_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_fdb_tbl_rd_op_rslt_data1_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_fdb_tbl_rd_op_rslt_data1_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_fdb_tbl_rd_op_rslt_data2_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_fdb_tbl_rd_op_rslt_data2_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_fdb_tbl_op_data0_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_fdb_tbl_op_data0_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_fdb_tbl_op_data1_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_fdb_tbl_op_data1_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_fdb_tbl_op_data2_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_fdb_tbl_op_data2_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_fdb_tbl_rd_op_data0_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_fdb_tbl_rd_op_data0_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_fdb_tbl_rd_op_data1_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_fdb_tbl_rd_op_data1_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_fdb_tbl_rd_op_data2_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_fdb_tbl_rd_op_data2_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_bridge_ctrl_txmac_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_bridge_ctrl_txmac_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_bridge_ctrl_port_isolation_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_bridge_ctrl_port_isolation_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_bridge_ctrl_station_move_lrn_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_bridge_ctrl_station_move_lrn_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_bridge_ctrl_new_addr_fwd_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_bridge_ctrl_new_addr_fwd_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_bridge_ctrl_promisc_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_bridge_ctrl_promisc_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_bridge_ctrl_new_addr_lrn_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_bridge_ctrl_new_addr_lrn_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_bridge_ctrl_station_move_fwd_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_bridge_ctrl_station_move_fwd_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_lrn_limit_ctrl_lrn_lmt_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_lrn_limit_ctrl_lrn_lmt_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_lrn_limit_ctrl_lrn_lmt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_lrn_limit_ctrl_lrn_lmt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_lrn_limit_ctrl_lrn_lmt_exceed_fwd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_lrn_limit_ctrl_lrn_lmt_exceed_fwd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_lrn_limit_counter_lrn_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_lrn_limit_counter_lrn_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rfdb_tbl_mac_addr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_rfdb_tbl_mac_addr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_rfdb_tbl_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rfdb_tbl_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_fdb_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_fdb_reg.h new file mode 100755 index 000000000..1bbc37f15 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_fdb_reg.h @@ -0,0 +1,838 @@ +/* + * 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. + */ + + +/** + * @defgroup + * @{ + */ +#ifndef HPPE_FDB_REG_H +#define HPPE_FDB_REG_H + +/*[register] L2_DBG_ADDR*/ +#define L2_DBG_ADDR +#define L2_DBG_ADDR_ADDRESS 0x0 +#define L2_DBG_ADDR_NUM 1 +#define L2_DBG_ADDR_INC 0x4 +#define L2_DBG_ADDR_TYPE REG_TYPE_RW +#define L2_DBG_ADDR_DEFAULT 0x0 + /*[field] L2_DBG_ADDR*/ + #define L2_DBG_ADDR_L2_DBG_ADDR + #define L2_DBG_ADDR_L2_DBG_ADDR_OFFSET 0 + #define L2_DBG_ADDR_L2_DBG_ADDR_LEN 32 + #define L2_DBG_ADDR_L2_DBG_ADDR_DEFAULT 0x0 + +struct l2_dbg_addr { + a_uint32_t l2_dbg_addr:32; +}; + +union l2_dbg_addr_u { + a_uint32_t val; + struct l2_dbg_addr bf; +}; + +/*[register] L2_DBG_DATA*/ +#define L2_DBG_DATA +#define L2_DBG_DATA_ADDRESS 0x4 +#define L2_DBG_DATA_NUM 1 +#define L2_DBG_DATA_INC 0x4 +#define L2_DBG_DATA_TYPE REG_TYPE_RO +#define L2_DBG_DATA_DEFAULT 0x0 + /*[field] L2_DBG_DATA*/ + #define L2_DBG_DATA_L2_DBG_DATA + #define L2_DBG_DATA_L2_DBG_DATA_OFFSET 0 + #define L2_DBG_DATA_L2_DBG_DATA_LEN 32 + #define L2_DBG_DATA_L2_DBG_DATA_DEFAULT 0x0 + +struct l2_dbg_data { + a_uint32_t l2_dbg_data:32; +}; + +union l2_dbg_data_u { + a_uint32_t val; + struct l2_dbg_data bf; +}; + +/*[register] FDB_TBL_OP*/ +#define FDB_TBL_OP +#define FDB_TBL_OP_ADDRESS 0x8 +#define FDB_TBL_OP_NUM 1 +#define FDB_TBL_OP_INC 0x4 +#define FDB_TBL_OP_TYPE REG_TYPE_RW +#define FDB_TBL_OP_DEFAULT 0x0 + /*[field] CMD_ID*/ + #define FDB_TBL_OP_CMD_ID + #define FDB_TBL_OP_CMD_ID_OFFSET 0 + #define FDB_TBL_OP_CMD_ID_LEN 4 + #define FDB_TBL_OP_CMD_ID_DEFAULT 0x0 + /*[field] BYP_RSLT_EN*/ + #define FDB_TBL_OP_BYP_RSLT_EN + #define FDB_TBL_OP_BYP_RSLT_EN_OFFSET 4 + #define FDB_TBL_OP_BYP_RSLT_EN_LEN 1 + #define FDB_TBL_OP_BYP_RSLT_EN_DEFAULT 0x0 + /*[field] OP_TYPE*/ + #define FDB_TBL_OP_OP_TYPE + #define FDB_TBL_OP_OP_TYPE_OFFSET 5 + #define FDB_TBL_OP_OP_TYPE_LEN 3 + #define FDB_TBL_OP_OP_TYPE_DEFAULT 0x0 + /*[field] HASH_BLOCK_BITMAP*/ + #define FDB_TBL_OP_HASH_BLOCK_BITMAP + #define FDB_TBL_OP_HASH_BLOCK_BITMAP_OFFSET 8 + #define FDB_TBL_OP_HASH_BLOCK_BITMAP_LEN 2 + #define FDB_TBL_OP_HASH_BLOCK_BITMAP_DEFAULT 0x0 + /*[field] OP_MODE*/ + #define FDB_TBL_OP_OP_MODE + #define FDB_TBL_OP_OP_MODE_OFFSET 10 + #define FDB_TBL_OP_OP_MODE_LEN 1 + #define FDB_TBL_OP_OP_MODE_DEFAULT 0x0 + /*[field] ENTRY_INDEX*/ + #define FDB_TBL_OP_ENTRY_INDEX + #define FDB_TBL_OP_ENTRY_INDEX_OFFSET 11 + #define FDB_TBL_OP_ENTRY_INDEX_LEN 11 + #define FDB_TBL_OP_ENTRY_INDEX_DEFAULT 0x0 + +struct fdb_tbl_op { + a_uint32_t cmd_id:4; + a_uint32_t byp_rslt_en:1; + a_uint32_t op_type:3; + a_uint32_t hash_block_bitmap:2; + a_uint32_t op_mode:1; + a_uint32_t entry_index:11; + a_uint32_t _reserved0:10; +}; + +union fdb_tbl_op_u { + a_uint32_t val; + struct fdb_tbl_op bf; +}; + +/*[register] FDB_TBL_RD_OP*/ +#define FDB_TBL_RD_OP +#define FDB_TBL_RD_OP_ADDRESS 0x10 +#define FDB_TBL_RD_OP_NUM 1 +#define FDB_TBL_RD_OP_INC 0x4 +#define FDB_TBL_RD_OP_TYPE REG_TYPE_RW +#define FDB_TBL_RD_OP_DEFAULT 0x0 + /*[field] CMD_ID*/ + #define FDB_TBL_RD_OP_CMD_ID + #define FDB_TBL_RD_OP_CMD_ID_OFFSET 0 + #define FDB_TBL_RD_OP_CMD_ID_LEN 4 + #define FDB_TBL_RD_OP_CMD_ID_DEFAULT 0x0 + /*[field] BYP_RSLT_EN*/ + #define FDB_TBL_RD_OP_BYP_RSLT_EN + #define FDB_TBL_RD_OP_BYP_RSLT_EN_OFFSET 4 + #define FDB_TBL_RD_OP_BYP_RSLT_EN_LEN 1 + #define FDB_TBL_RD_OP_BYP_RSLT_EN_DEFAULT 0x0 + /*[field] OP_TYPE*/ + #define FDB_TBL_RD_OP_OP_TYPE + #define FDB_TBL_RD_OP_OP_TYPE_OFFSET 5 + #define FDB_TBL_RD_OP_OP_TYPE_LEN 3 + #define FDB_TBL_RD_OP_OP_TYPE_DEFAULT 0x0 + /*[field] HASH_BLOCK_BITMAP*/ + #define FDB_TBL_RD_OP_HASH_BLOCK_BITMAP + #define FDB_TBL_RD_OP_HASH_BLOCK_BITMAP_OFFSET 8 + #define FDB_TBL_RD_OP_HASH_BLOCK_BITMAP_LEN 2 + #define FDB_TBL_RD_OP_HASH_BLOCK_BITMAP_DEFAULT 0x0 + /*[field] OP_MODE*/ + #define FDB_TBL_RD_OP_OP_MODE + #define FDB_TBL_RD_OP_OP_MODE_OFFSET 10 + #define FDB_TBL_RD_OP_OP_MODE_LEN 1 + #define FDB_TBL_RD_OP_OP_MODE_DEFAULT 0x0 + /*[field] ENTRY_INDEX*/ + #define FDB_TBL_RD_OP_ENTRY_INDEX + #define FDB_TBL_RD_OP_ENTRY_INDEX_OFFSET 11 + #define FDB_TBL_RD_OP_ENTRY_INDEX_LEN 11 + #define FDB_TBL_RD_OP_ENTRY_INDEX_DEFAULT 0x0 + +struct fdb_tbl_rd_op { + a_uint32_t cmd_id:4; + a_uint32_t byp_rslt_en:1; + a_uint32_t op_type:3; + a_uint32_t hash_block_bitmap:2; + a_uint32_t op_mode:1; + a_uint32_t entry_index:11; + a_uint32_t _reserved0:10; +}; + +union fdb_tbl_rd_op_u { + a_uint32_t val; + struct fdb_tbl_rd_op bf; +}; + +/*[register] FDB_TBL_OP_RSLT*/ +#define FDB_TBL_OP_RSLT +#define FDB_TBL_OP_RSLT_ADDRESS 0x20 +#define FDB_TBL_OP_RSLT_NUM 1 +#define FDB_TBL_OP_RSLT_INC 0x4 +#define FDB_TBL_OP_RSLT_TYPE REG_TYPE_RO +#define FDB_TBL_OP_RSLT_DEFAULT 0x0 + /*[field] CMD_ID*/ + #define FDB_TBL_OP_RSLT_CMD_ID + #define FDB_TBL_OP_RSLT_CMD_ID_OFFSET 0 + #define FDB_TBL_OP_RSLT_CMD_ID_LEN 4 + #define FDB_TBL_OP_RSLT_CMD_ID_DEFAULT 0x0 + /*[field] OP_RSLT*/ + #define FDB_TBL_OP_RSLT_OP_RSLT + #define FDB_TBL_OP_RSLT_OP_RSLT_OFFSET 4 + #define FDB_TBL_OP_RSLT_OP_RSLT_LEN 1 + #define FDB_TBL_OP_RSLT_OP_RSLT_DEFAULT 0x0 + /*[field] VALID_CNT*/ + #define FDB_TBL_OP_RSLT_VALID_CNT + #define FDB_TBL_OP_RSLT_VALID_CNT_OFFSET 5 + #define FDB_TBL_OP_RSLT_VALID_CNT_LEN 4 + #define FDB_TBL_OP_RSLT_VALID_CNT_DEFAULT 0x0 + /*[field] ENTRY_INDEX*/ + #define FDB_TBL_OP_RSLT_ENTRY_INDEX + #define FDB_TBL_OP_RSLT_ENTRY_INDEX_OFFSET 9 + #define FDB_TBL_OP_RSLT_ENTRY_INDEX_LEN 11 + #define FDB_TBL_OP_RSLT_ENTRY_INDEX_DEFAULT 0x0 + +struct fdb_tbl_op_rslt { + a_uint32_t cmd_id:4; + a_uint32_t op_rslt:1; + a_uint32_t valid_cnt:4; + a_uint32_t entry_index:11; + a_uint32_t _reserved0:12; +}; + +union fdb_tbl_op_rslt_u { + a_uint32_t val; + struct fdb_tbl_op_rslt bf; +}; + +/*[register] FDB_TBL_RD_OP_RSLT*/ +#define FDB_TBL_RD_OP_RSLT +#define FDB_TBL_RD_OP_RSLT_ADDRESS 0x30 +#define FDB_TBL_RD_OP_RSLT_NUM 1 +#define FDB_TBL_RD_OP_RSLT_INC 0x4 +#define FDB_TBL_RD_OP_RSLT_TYPE REG_TYPE_RO +#define FDB_TBL_RD_OP_RSLT_DEFAULT 0x0 + /*[field] CMD_ID*/ + #define FDB_TBL_RD_OP_RSLT_CMD_ID + #define FDB_TBL_RD_OP_RSLT_CMD_ID_OFFSET 0 + #define FDB_TBL_RD_OP_RSLT_CMD_ID_LEN 4 + #define FDB_TBL_RD_OP_RSLT_CMD_ID_DEFAULT 0x0 + /*[field] OP_RSLT*/ + #define FDB_TBL_RD_OP_RSLT_OP_RSLT + #define FDB_TBL_RD_OP_RSLT_OP_RSLT_OFFSET 4 + #define FDB_TBL_RD_OP_RSLT_OP_RSLT_LEN 1 + #define FDB_TBL_RD_OP_RSLT_OP_RSLT_DEFAULT 0x0 + /*[field] VALID_CNT*/ + #define FDB_TBL_RD_OP_RSLT_VALID_CNT + #define FDB_TBL_RD_OP_RSLT_VALID_CNT_OFFSET 5 + #define FDB_TBL_RD_OP_RSLT_VALID_CNT_LEN 4 + #define FDB_TBL_RD_OP_RSLT_VALID_CNT_DEFAULT 0x0 + /*[field] ENTRY_INDEX*/ + #define FDB_TBL_RD_OP_RSLT_ENTRY_INDEX + #define FDB_TBL_RD_OP_RSLT_ENTRY_INDEX_OFFSET 9 + #define FDB_TBL_RD_OP_RSLT_ENTRY_INDEX_LEN 11 + #define FDB_TBL_RD_OP_RSLT_ENTRY_INDEX_DEFAULT 0x0 + +struct fdb_tbl_rd_op_rslt { + a_uint32_t cmd_id:4; + a_uint32_t op_rslt:1; + a_uint32_t valid_cnt:4; + a_uint32_t entry_index:11; + a_uint32_t _reserved0:12; +}; + +union fdb_tbl_rd_op_rslt_u { + a_uint32_t val; + struct fdb_tbl_rd_op_rslt bf; +}; + +/*[register] AGE_TIMER*/ +#define AGE_TIMER +#define AGE_TIMER_ADDRESS 0x34 +#define AGE_TIMER_NUM 1 +#define AGE_TIMER_INC 0x4 +#define AGE_TIMER_TYPE REG_TYPE_RW +#define AGE_TIMER_DEFAULT 0x0 + /*[field] AGE_VAL*/ + #define AGE_TIMER_AGE_VAL + #define AGE_TIMER_AGE_VAL_OFFSET 0 + #define AGE_TIMER_AGE_VAL_LEN 20 + #define AGE_TIMER_AGE_VAL_DEFAULT 0x0 + +struct age_timer { + a_uint32_t age_val:20; + a_uint32_t _reserved0:12; +}; + +union age_timer_u { + a_uint32_t val; + struct age_timer bf; +}; + +/*[register] L2_GLOBAL_CONF*/ +#define L2_GLOBAL_CONF +#define L2_GLOBAL_CONF_ADDRESS 0x38 +#define L2_GLOBAL_CONF_NUM 1 +#define L2_GLOBAL_CONF_INC 0x4 +#define L2_GLOBAL_CONF_TYPE REG_TYPE_RW +#define L2_GLOBAL_CONF_DEFAULT 0xc0 + /*[field] FDB_HASH_MODE_0*/ + #define L2_GLOBAL_CONF_FDB_HASH_MODE_0 + #define L2_GLOBAL_CONF_FDB_HASH_MODE_0_OFFSET 0 + #define L2_GLOBAL_CONF_FDB_HASH_MODE_0_LEN 2 + #define L2_GLOBAL_CONF_FDB_HASH_MODE_0_DEFAULT 0x0 + /*[field] FDB_HASH_MODE_1*/ + #define L2_GLOBAL_CONF_FDB_HASH_MODE_1 + #define L2_GLOBAL_CONF_FDB_HASH_MODE_1_OFFSET 2 + #define L2_GLOBAL_CONF_FDB_HASH_MODE_1_LEN 2 + #define L2_GLOBAL_CONF_FDB_HASH_MODE_1_DEFAULT 0x0 + /*[field] FDB_HASH_FULL_FWD_CMD*/ + #define L2_GLOBAL_CONF_FDB_HASH_FULL_FWD_CMD + #define L2_GLOBAL_CONF_FDB_HASH_FULL_FWD_CMD_OFFSET 4 + #define L2_GLOBAL_CONF_FDB_HASH_FULL_FWD_CMD_LEN 2 + #define L2_GLOBAL_CONF_FDB_HASH_FULL_FWD_CMD_DEFAULT 0x0 + /*[field] LRN_EN*/ + #define L2_GLOBAL_CONF_LRN_EN + #define L2_GLOBAL_CONF_LRN_EN_OFFSET 6 + #define L2_GLOBAL_CONF_LRN_EN_LEN 1 + #define L2_GLOBAL_CONF_LRN_EN_DEFAULT 0x1 + /*[field] AGE_EN*/ + #define L2_GLOBAL_CONF_AGE_EN + #define L2_GLOBAL_CONF_AGE_EN_OFFSET 7 + #define L2_GLOBAL_CONF_AGE_EN_LEN 1 + #define L2_GLOBAL_CONF_AGE_EN_DEFAULT 0x1 + /*[field] LRN_CTRL_MODE*/ + #define L2_GLOBAL_CONF_LRN_CTRL_MODE + #define L2_GLOBAL_CONF_LRN_CTRL_MODE_OFFSET 8 + #define L2_GLOBAL_CONF_LRN_CTRL_MODE_LEN 1 + #define L2_GLOBAL_CONF_LRN_CTRL_MODE_DEFAULT 0x0 + /*[field] AGE_CTRL_MODE*/ + #define L2_GLOBAL_CONF_AGE_CTRL_MODE + #define L2_GLOBAL_CONF_AGE_CTRL_MODE_OFFSET 9 + #define L2_GLOBAL_CONF_AGE_CTRL_MODE_LEN 1 + #define L2_GLOBAL_CONF_AGE_CTRL_MODE_DEFAULT 0x0 + /*[field] FAILOVER_EN*/ + #define L2_GLOBAL_CONF_FAILOVER_EN + #define L2_GLOBAL_CONF_FAILOVER_EN_OFFSET 10 + #define L2_GLOBAL_CONF_FAILOVER_EN_LEN 1 + #define L2_GLOBAL_CONF_FAILOVER_EN_DEFAULT 0x0 + /*[field] SERVICE_CODE_LOOP*/ + #define L2_GLOBAL_CONF_SERVICE_CODE_LOOP + #define L2_GLOBAL_CONF_SERVICE_CODE_LOOP_OFFSET 11 + #define L2_GLOBAL_CONF_SERVICE_CODE_LOOP_LEN 1 + #define L2_GLOBAL_CONF_SERVICE_CODE_LOOP_DEFAULT 0x0 + +struct l2_global_conf { + a_uint32_t fdb_hash_mode_0:2; + a_uint32_t fdb_hash_mode_1:2; + a_uint32_t fdb_hash_full_fwd_cmd:2; + a_uint32_t lrn_en:1; + a_uint32_t age_en:1; + a_uint32_t lrn_ctrl_mode:1; + a_uint32_t age_ctrl_mode:1; + a_uint32_t failover_en:1; + a_uint32_t service_code_loop:1; + a_uint32_t l2_flow_copy_escape:1; + a_uint32_t _reserved0:19; +}; + +union l2_global_conf_u { + a_uint32_t val; + struct l2_global_conf bf; +}; + +/*[register] L2_DBGCNT_CMD*/ +#define L2_DBGCNT_CMD +#define L2_DBGCNT_CMD_ADDRESS 0x44 +#define L2_DBGCNT_CMD_NUM 1 +#define L2_DBGCNT_CMD_INC 0x4 +#define L2_DBGCNT_CMD_TYPE REG_TYPE_RW +#define L2_DBGCNT_CMD_DEFAULT 0x0 + /*[field] ADDR*/ + #define L2_DBGCNT_CMD_ADDR + #define L2_DBGCNT_CMD_ADDR_OFFSET 0 + #define L2_DBGCNT_CMD_ADDR_LEN 8 + #define L2_DBGCNT_CMD_ADDR_DEFAULT 0x0 + /*[field] TYPE*/ + #define L2_DBGCNT_CMD_TYPE_F + #define L2_DBGCNT_CMD_TYPE_F_OFFSET 8 + #define L2_DBGCNT_CMD_TYPE_F_LEN 2 + #define L2_DBGCNT_CMD_TYPE_F_DEFAULT 0x0 + +struct l2_dbgcnt_cmd { + a_uint32_t addr:8; + a_uint32_t type:2; + a_uint32_t _reserved0:22; +}; + +union l2_dbgcnt_cmd_u { + a_uint32_t val; + struct l2_dbgcnt_cmd bf; +}; + +/*[register] L2_DBGCNT_RDATA*/ +#define L2_DBGCNT_RDATA +#define L2_DBGCNT_RDATA_ADDRESS 0x48 +#define L2_DBGCNT_RDATA_NUM 1 +#define L2_DBGCNT_RDATA_INC 0x4 +#define L2_DBGCNT_RDATA_TYPE REG_TYPE_RO +#define L2_DBGCNT_RDATA_DEFAULT 0x0 + /*[field] DATA*/ + #define L2_DBGCNT_RDATA_DATA + #define L2_DBGCNT_RDATA_DATA_OFFSET 0 + #define L2_DBGCNT_RDATA_DATA_LEN 32 + #define L2_DBGCNT_RDATA_DATA_DEFAULT 0x0 + +struct l2_dbgcnt_rdata { + a_uint32_t data:32; +}; + +union l2_dbgcnt_rdata_u { + a_uint32_t val; + struct l2_dbgcnt_rdata bf; +}; + +/*[register] L2_DBGCNT_WDATA*/ +#define L2_DBGCNT_WDATA +#define L2_DBGCNT_WDATA_ADDRESS 0x4c +#define L2_DBGCNT_WDATA_NUM 1 +#define L2_DBGCNT_WDATA_INC 0x4 +#define L2_DBGCNT_WDATA_TYPE REG_TYPE_RW +#define L2_DBGCNT_WDATA_DEFAULT 0x0 + /*[field] DATA*/ + #define L2_DBGCNT_WDATA_DATA + #define L2_DBGCNT_WDATA_DATA_OFFSET 0 + #define L2_DBGCNT_WDATA_DATA_LEN 32 + #define L2_DBGCNT_WDATA_DATA_DEFAULT 0x0 + +struct l2_dbgcnt_wdata { + a_uint32_t data:32; +}; + +union l2_dbgcnt_wdata_u { + a_uint32_t val; + struct l2_dbgcnt_wdata bf; +}; + +/*[register] FDB_TBL_RD_OP_RSLT_DATA0*/ +#define FDB_TBL_RD_OP_RSLT_DATA0 +#define FDB_TBL_RD_OP_RSLT_DATA0_ADDRESS 0x200 +#define FDB_TBL_RD_OP_RSLT_DATA0_NUM 1 +#define FDB_TBL_RD_OP_RSLT_DATA0_INC 0x10 +#define FDB_TBL_RD_OP_RSLT_DATA0_TYPE REG_TYPE_RO +#define FDB_TBL_RD_OP_RSLT_DATA0_DEFAULT 0x0 + /*[field] DATA*/ + #define FDB_TBL_RD_OP_RSLT_DATA0_DATA + #define FDB_TBL_RD_OP_RSLT_DATA0_DATA_OFFSET 0 + #define FDB_TBL_RD_OP_RSLT_DATA0_DATA_LEN 32 + #define FDB_TBL_RD_OP_RSLT_DATA0_DATA_DEFAULT 0x0 + +struct fdb_tbl_rd_op_rslt_data0 { + a_uint32_t data:32; +}; + +union fdb_tbl_rd_op_rslt_data0_u { + a_uint32_t val; + struct fdb_tbl_rd_op_rslt_data0 bf; +}; + +/*[register] FDB_TBL_RD_OP_RSLT_DATA1*/ +#define FDB_TBL_RD_OP_RSLT_DATA1 +#define FDB_TBL_RD_OP_RSLT_DATA1_ADDRESS 0x204 +#define FDB_TBL_RD_OP_RSLT_DATA1_NUM 1 +#define FDB_TBL_RD_OP_RSLT_DATA1_INC 0x10 +#define FDB_TBL_RD_OP_RSLT_DATA1_TYPE REG_TYPE_RO +#define FDB_TBL_RD_OP_RSLT_DATA1_DEFAULT 0x0 + /*[field] DATA*/ + #define FDB_TBL_RD_OP_RSLT_DATA1_DATA + #define FDB_TBL_RD_OP_RSLT_DATA1_DATA_OFFSET 0 + #define FDB_TBL_RD_OP_RSLT_DATA1_DATA_LEN 32 + #define FDB_TBL_RD_OP_RSLT_DATA1_DATA_DEFAULT 0x0 + +struct fdb_tbl_rd_op_rslt_data1 { + a_uint32_t data:32; +}; + +union fdb_tbl_rd_op_rslt_data1_u { + a_uint32_t val; + struct fdb_tbl_rd_op_rslt_data1 bf; +}; + +/*[register] FDB_TBL_RD_OP_RSLT_DATA2*/ +#define FDB_TBL_RD_OP_RSLT_DATA2 +#define FDB_TBL_RD_OP_RSLT_DATA2_ADDRESS 0x208 +#define FDB_TBL_RD_OP_RSLT_DATA2_NUM 1 +#define FDB_TBL_RD_OP_RSLT_DATA2_INC 0x10 +#define FDB_TBL_RD_OP_RSLT_DATA2_TYPE REG_TYPE_RO +#define FDB_TBL_RD_OP_RSLT_DATA2_DEFAULT 0x0 + /*[field] DATA*/ + #define FDB_TBL_RD_OP_RSLT_DATA2_DATA + #define FDB_TBL_RD_OP_RSLT_DATA2_DATA_OFFSET 0 + #define FDB_TBL_RD_OP_RSLT_DATA2_DATA_LEN 32 + #define FDB_TBL_RD_OP_RSLT_DATA2_DATA_DEFAULT 0x0 + +struct fdb_tbl_rd_op_rslt_data2 { + a_uint32_t data:32; +}; + +union fdb_tbl_rd_op_rslt_data2_u { + a_uint32_t val; + struct fdb_tbl_rd_op_rslt_data2 bf; +}; + +/*[register] FDB_TBL_OP_DATA0*/ +#define FDB_TBL_OP_DATA0 +#define FDB_TBL_OP_DATA0_ADDRESS 0x230 +#define FDB_TBL_OP_DATA0_NUM 1 +#define FDB_TBL_OP_DATA0_INC 0x10 +#define FDB_TBL_OP_DATA0_TYPE REG_TYPE_RW +#define FDB_TBL_OP_DATA0_DEFAULT 0x0 + /*[field] DATA*/ + #define FDB_TBL_OP_DATA0_DATA + #define FDB_TBL_OP_DATA0_DATA_OFFSET 0 + #define FDB_TBL_OP_DATA0_DATA_LEN 32 + #define FDB_TBL_OP_DATA0_DATA_DEFAULT 0x0 + +struct fdb_tbl_op_data0 { + a_uint32_t data:32; +}; + +union fdb_tbl_op_data0_u { + a_uint32_t val; + struct fdb_tbl_op_data0 bf; +}; + +/*[register] FDB_TBL_OP_DATA1*/ +#define FDB_TBL_OP_DATA1 +#define FDB_TBL_OP_DATA1_ADDRESS 0x234 +#define FDB_TBL_OP_DATA1_NUM 1 +#define FDB_TBL_OP_DATA1_INC 0x10 +#define FDB_TBL_OP_DATA1_TYPE REG_TYPE_RW +#define FDB_TBL_OP_DATA1_DEFAULT 0x0 + /*[field] DATA*/ + #define FDB_TBL_OP_DATA1_DATA + #define FDB_TBL_OP_DATA1_DATA_OFFSET 0 + #define FDB_TBL_OP_DATA1_DATA_LEN 32 + #define FDB_TBL_OP_DATA1_DATA_DEFAULT 0x0 + +struct fdb_tbl_op_data1 { + a_uint32_t data:32; +}; + +union fdb_tbl_op_data1_u { + a_uint32_t val; + struct fdb_tbl_op_data1 bf; +}; + +/*[register] FDB_TBL_OP_DATA2*/ +#define FDB_TBL_OP_DATA2 +#define FDB_TBL_OP_DATA2_ADDRESS 0x238 +#define FDB_TBL_OP_DATA2_NUM 1 +#define FDB_TBL_OP_DATA2_INC 0x10 +#define FDB_TBL_OP_DATA2_TYPE REG_TYPE_RW +#define FDB_TBL_OP_DATA2_DEFAULT 0x0 + /*[field] DATA*/ + #define FDB_TBL_OP_DATA2_DATA + #define FDB_TBL_OP_DATA2_DATA_OFFSET 0 + #define FDB_TBL_OP_DATA2_DATA_LEN 32 + #define FDB_TBL_OP_DATA2_DATA_DEFAULT 0x0 + +struct fdb_tbl_op_data2 { + a_uint32_t data:32; +}; + +union fdb_tbl_op_data2_u { + a_uint32_t val; + struct fdb_tbl_op_data2 bf; +}; + +/*[register] FDB_TBL_RD_OP_DATA0*/ +#define FDB_TBL_RD_OP_DATA0 +#define FDB_TBL_RD_OP_DATA0_ADDRESS 0x260 +#define FDB_TBL_RD_OP_DATA0_NUM 1 +#define FDB_TBL_RD_OP_DATA0_INC 0x10 +#define FDB_TBL_RD_OP_DATA0_TYPE REG_TYPE_RW +#define FDB_TBL_RD_OP_DATA0_DEFAULT 0x0 + /*[field] DATA*/ + #define FDB_TBL_RD_OP_DATA0_DATA + #define FDB_TBL_RD_OP_DATA0_DATA_OFFSET 0 + #define FDB_TBL_RD_OP_DATA0_DATA_LEN 32 + #define FDB_TBL_RD_OP_DATA0_DATA_DEFAULT 0x0 + +struct fdb_tbl_rd_op_data0 { + a_uint32_t data:32; +}; + +union fdb_tbl_rd_op_data0_u { + a_uint32_t val; + struct fdb_tbl_rd_op_data0 bf; +}; + +/*[register] FDB_TBL_RD_OP_DATA1*/ +#define FDB_TBL_RD_OP_DATA1 +#define FDB_TBL_RD_OP_DATA1_ADDRESS 0x264 +#define FDB_TBL_RD_OP_DATA1_NUM 1 +#define FDB_TBL_RD_OP_DATA1_INC 0x10 +#define FDB_TBL_RD_OP_DATA1_TYPE REG_TYPE_RW +#define FDB_TBL_RD_OP_DATA1_DEFAULT 0x0 + /*[field] DATA*/ + #define FDB_TBL_RD_OP_DATA1_DATA + #define FDB_TBL_RD_OP_DATA1_DATA_OFFSET 0 + #define FDB_TBL_RD_OP_DATA1_DATA_LEN 32 + #define FDB_TBL_RD_OP_DATA1_DATA_DEFAULT 0x0 + +struct fdb_tbl_rd_op_data1 { + a_uint32_t data:32; +}; + +union fdb_tbl_rd_op_data1_u { + a_uint32_t val; + struct fdb_tbl_rd_op_data1 bf; +}; + +/*[register] FDB_TBL_RD_OP_DATA2*/ +#define FDB_TBL_RD_OP_DATA2 +#define FDB_TBL_RD_OP_DATA2_ADDRESS 0x268 +#define FDB_TBL_RD_OP_DATA2_NUM 1 +#define FDB_TBL_RD_OP_DATA2_INC 0x10 +#define FDB_TBL_RD_OP_DATA2_TYPE REG_TYPE_RW +#define FDB_TBL_RD_OP_DATA2_DEFAULT 0x0 + /*[field] DATA*/ + #define FDB_TBL_RD_OP_DATA2_DATA + #define FDB_TBL_RD_OP_DATA2_DATA_OFFSET 0 + #define FDB_TBL_RD_OP_DATA2_DATA_LEN 32 + #define FDB_TBL_RD_OP_DATA2_DATA_DEFAULT 0x0 + +struct fdb_tbl_rd_op_data2 { + a_uint32_t data:32; +}; + +union fdb_tbl_rd_op_data2_u { + a_uint32_t val; + struct fdb_tbl_rd_op_data2 bf; +}; + +/*[register] PORT_BRIDGE_CTRL*/ +#define PORT_BRIDGE_CTRL +#define PORT_BRIDGE_CTRL_ADDRESS 0x300 +#define PORT_BRIDGE_CTRL_NUM 8 +#define PORT_BRIDGE_CTRL_INC 0x4 +#define PORT_BRIDGE_CTRL_TYPE REG_TYPE_RW +#define PORT_BRIDGE_CTRL_DEFAULT 0x2ff09 + /*[field] NEW_ADDR_LRN_EN*/ + #define PORT_BRIDGE_CTRL_NEW_ADDR_LRN_EN + #define PORT_BRIDGE_CTRL_NEW_ADDR_LRN_EN_OFFSET 0 + #define PORT_BRIDGE_CTRL_NEW_ADDR_LRN_EN_LEN 1 + #define PORT_BRIDGE_CTRL_NEW_ADDR_LRN_EN_DEFAULT 0x1 + /*[field] NEW_ADDR_FWD_CMD*/ + #define PORT_BRIDGE_CTRL_NEW_ADDR_FWD_CMD + #define PORT_BRIDGE_CTRL_NEW_ADDR_FWD_CMD_OFFSET 1 + #define PORT_BRIDGE_CTRL_NEW_ADDR_FWD_CMD_LEN 2 + #define PORT_BRIDGE_CTRL_NEW_ADDR_FWD_CMD_DEFAULT 0x0 + /*[field] STATION_MOVE_LRN_EN*/ + #define PORT_BRIDGE_CTRL_STATION_MOVE_LRN_EN + #define PORT_BRIDGE_CTRL_STATION_MOVE_LRN_EN_OFFSET 3 + #define PORT_BRIDGE_CTRL_STATION_MOVE_LRN_EN_LEN 1 + #define PORT_BRIDGE_CTRL_STATION_MOVE_LRN_EN_DEFAULT 0x1 + /*[field] STATION_MOVE_FWD_CMD*/ + #define PORT_BRIDGE_CTRL_STATION_MOVE_FWD_CMD + #define PORT_BRIDGE_CTRL_STATION_MOVE_FWD_CMD_OFFSET 4 + #define PORT_BRIDGE_CTRL_STATION_MOVE_FWD_CMD_LEN 2 + #define PORT_BRIDGE_CTRL_STATION_MOVE_FWD_CMD_DEFAULT 0x0 + /*[field] PORT_ISOLATION_BITMAP*/ + #define PORT_BRIDGE_CTRL_PORT_ISOLATION_BITMAP + #define PORT_BRIDGE_CTRL_PORT_ISOLATION_BITMAP_OFFSET 8 + #define PORT_BRIDGE_CTRL_PORT_ISOLATION_BITMAP_LEN 8 + #define PORT_BRIDGE_CTRL_PORT_ISOLATION_BITMAP_DEFAULT 0xff + /*[field] TXMAC_EN*/ + #define PORT_BRIDGE_CTRL_TXMAC_EN + #define PORT_BRIDGE_CTRL_TXMAC_EN_OFFSET 16 + #define PORT_BRIDGE_CTRL_TXMAC_EN_LEN 1 + #define PORT_BRIDGE_CTRL_TXMAC_EN_DEFAULT 0x0 + /*[field] PROMISC_EN*/ + #define PORT_BRIDGE_CTRL_PROMISC_EN + #define PORT_BRIDGE_CTRL_PROMISC_EN_OFFSET 17 + #define PORT_BRIDGE_CTRL_PROMISC_EN_LEN 1 + #define PORT_BRIDGE_CTRL_PROMISC_EN_DEFAULT 0x1 + +struct port_bridge_ctrl { + a_uint32_t new_addr_lrn_en:1; + a_uint32_t new_addr_fwd_cmd:2; + a_uint32_t station_move_lrn_en:1; + a_uint32_t station_move_fwd_cmd:2; + a_uint32_t _reserved0:2; + a_uint32_t port_isolation_bitmap:8; + a_uint32_t txmac_en:1; + a_uint32_t promisc_en:1; + a_uint32_t _reserved1:14; +}; + +union port_bridge_ctrl_u { + a_uint32_t val; + struct port_bridge_ctrl bf; +}; + +/*[register] PORT_LRN_LIMIT_CTRL*/ +#define PORT_LRN_LIMIT_CTRL +#define PORT_LRN_LIMIT_CTRL_ADDRESS 0x400 +#define PORT_LRN_LIMIT_CTRL_NUM 8 +#define PORT_LRN_LIMIT_CTRL_INC 0x4 +#define PORT_LRN_LIMIT_CTRL_TYPE REG_TYPE_RW +#define PORT_LRN_LIMIT_CTRL_DEFAULT 0x1800 + /*[field] LRN_LMT_CNT*/ + #define PORT_LRN_LIMIT_CTRL_LRN_LMT_CNT + #define PORT_LRN_LIMIT_CTRL_LRN_LMT_CNT_OFFSET 0 + #define PORT_LRN_LIMIT_CTRL_LRN_LMT_CNT_LEN 12 + #define PORT_LRN_LIMIT_CTRL_LRN_LMT_CNT_DEFAULT 0x800 + /*[field] LRN_LMT_EN*/ + #define PORT_LRN_LIMIT_CTRL_LRN_LMT_EN + #define PORT_LRN_LIMIT_CTRL_LRN_LMT_EN_OFFSET 12 + #define PORT_LRN_LIMIT_CTRL_LRN_LMT_EN_LEN 1 + #define PORT_LRN_LIMIT_CTRL_LRN_LMT_EN_DEFAULT 0x1 + /*[field] LRN_LMT_EXCEED_FWD*/ + #define PORT_LRN_LIMIT_CTRL_LRN_LMT_EXCEED_FWD + #define PORT_LRN_LIMIT_CTRL_LRN_LMT_EXCEED_FWD_OFFSET 13 + #define PORT_LRN_LIMIT_CTRL_LRN_LMT_EXCEED_FWD_LEN 2 + #define PORT_LRN_LIMIT_CTRL_LRN_LMT_EXCEED_FWD_DEFAULT 0x0 + +struct port_lrn_limit_ctrl { + a_uint32_t lrn_lmt_cnt:12; + a_uint32_t lrn_lmt_en:1; + a_uint32_t lrn_lmt_exceed_fwd:2; + a_uint32_t _reserved0:17; +}; + +union port_lrn_limit_ctrl_u { + a_uint32_t val; + struct port_lrn_limit_ctrl bf; +}; + +/*[register] PORT_LRN_LIMIT_COUNTER*/ +#define PORT_LRN_LIMIT_COUNTER +#define PORT_LRN_LIMIT_COUNTER_ADDRESS 0x500 +#define PORT_LRN_LIMIT_COUNTER_NUM 8 +#define PORT_LRN_LIMIT_COUNTER_INC 0x4 +#define PORT_LRN_LIMIT_COUNTER_TYPE REG_TYPE_RO +#define PORT_LRN_LIMIT_COUNTER_DEFAULT 0x0 + /*[field] LRN_CNT*/ + #define PORT_LRN_LIMIT_COUNTER_LRN_CNT + #define PORT_LRN_LIMIT_COUNTER_LRN_CNT_OFFSET 0 + #define PORT_LRN_LIMIT_COUNTER_LRN_CNT_LEN 12 + #define PORT_LRN_LIMIT_COUNTER_LRN_CNT_DEFAULT 0x0 + +struct port_lrn_limit_counter { + a_uint32_t lrn_cnt:12; + a_uint32_t _reserved0:20; +}; + +union port_lrn_limit_counter_u { + a_uint32_t val; + struct port_lrn_limit_counter bf; +}; + +/*[table] RFDB_TBL*/ +#define RFDB_TBL +#define RFDB_TBL_ADDRESS 0x1000 +#define RFDB_TBL_NUM 32 +#define RFDB_TBL_INC 0x8 +#define RFDB_TBL_TYPE REG_TYPE_RW +#define RFDB_TBL_DEFAULT 0x0 + /*[field] MAC_ADDR*/ + #define RFDB_TBL_MAC_ADDR + #define RFDB_TBL_MAC_ADDR_OFFSET 0 + #define RFDB_TBL_MAC_ADDR_LEN 48 + #define RFDB_TBL_MAC_ADDR_DEFAULT 0x0 + /*[field] VALID*/ + #define RFDB_TBL_VALID + #define RFDB_TBL_VALID_OFFSET 48 + #define RFDB_TBL_VALID_LEN 1 + #define RFDB_TBL_VALID_DEFAULT 0x0 + +struct rfdb_tbl { + a_uint32_t mac_addr_0:32; + a_uint32_t mac_addr_1:16; + a_uint32_t valid:1; + a_uint32_t _reserved0:15; +}; + +union rfdb_tbl_u { + a_uint32_t val[2]; + struct rfdb_tbl bf; +}; + +/*[table] FDB_TBL*/ +#define FDB_TBL +#define FDB_TBL_ADDRESS 0x10000 +#define FDB_TBL_NUM 2048 +#define FDB_TBL_INC 0x10 +#define FDB_TBL_TYPE REG_TYPE_RW +#define FDB_TBL_DEFAULT 0x0 + /*[field] MAC_ADDR*/ + #define FDB_TBL_MAC_ADDR + #define FDB_TBL_MAC_ADDR_OFFSET 0 + #define FDB_TBL_MAC_ADDR_LEN 48 + #define FDB_TBL_MAC_ADDR_DEFAULT 0x0 + /*[field] ENTRY_VALID*/ + #define FDB_TBL_ENTRY_VALID + #define FDB_TBL_ENTRY_VALID_OFFSET 48 + #define FDB_TBL_ENTRY_VALID_LEN 1 + #define FDB_TBL_ENTRY_VALID_DEFAULT 0x0 + /*[field] LOOKUP_VALID*/ + #define FDB_TBL_LOOKUP_VALID + #define FDB_TBL_LOOKUP_VALID_OFFSET 49 + #define FDB_TBL_LOOKUP_VALID_LEN 1 + #define FDB_TBL_LOOKUP_VALID_DEFAULT 0x0 + /*[field] VSI*/ + #define FDB_TBL_VSI + #define FDB_TBL_VSI_OFFSET 50 + #define FDB_TBL_VSI_LEN 5 + #define FDB_TBL_VSI_DEFAULT 0x0 + /*[field] DST_INFO*/ + #define FDB_TBL_DST_INFO + #define FDB_TBL_DST_INFO_OFFSET 55 + #define FDB_TBL_DST_INFO_LEN 14 + #define FDB_TBL_DST_INFO_DEFAULT 0x0 + /*[field] SA_CMD*/ + #define FDB_TBL_SA_CMD + #define FDB_TBL_SA_CMD_OFFSET 69 + #define FDB_TBL_SA_CMD_LEN 2 + #define FDB_TBL_SA_CMD_DEFAULT 0x0 + /*[field] DA_CMD*/ + #define FDB_TBL_DA_CMD + #define FDB_TBL_DA_CMD_OFFSET 71 + #define FDB_TBL_DA_CMD_LEN 2 + #define FDB_TBL_DA_CMD_DEFAULT 0x0 + /*[field] HIT_AGE*/ + #define FDB_TBL_HIT_AGE + #define FDB_TBL_HIT_AGE_OFFSET 73 + #define FDB_TBL_HIT_AGE_LEN 2 + #define FDB_TBL_HIT_AGE_DEFAULT 0x0 + +struct fdb_tbl { + a_uint32_t mac_addr_0:32; + a_uint32_t mac_addr_1:16; + a_uint32_t entry_valid:1; + a_uint32_t lookup_valid:1; + a_uint32_t vsi:5; + a_uint32_t dst_info_0:9; + a_uint32_t dst_info_1:5; + a_uint32_t sa_cmd:2; + a_uint32_t da_cmd:2; + a_uint32_t hit_age:2; + a_uint32_t _reserved0:21; +}; + +union fdb_tbl_u { + a_uint32_t val[3]; + struct fdb_tbl bf; +}; + + + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_flow.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_flow.h new file mode 100755 index 000000000..437b7200c --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_flow.h @@ -0,0 +1,2264 @@ +/* + * 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 + * @{ + */ +#ifndef _HPPE_FLOW_H_ +#define _HPPE_FLOW_H_ + +#define FLOW_CTRL1_MAX_ENTRY 3 +#define IN_FLOW_3TUPLE_TBL_MAX_ENTRY 4096 +#define IN_FLOW_IPV6_3TUPLE_TBL_MAX_ENTRY 2048 +#define IN_FLOW_IPV6_5TUPLE_TBL_MAX_ENTRY 2048 +#define IN_FLOW_TBL_MAX_ENTRY 4096 +#define EG_FLOW_TREE_MAP_TBL_MAX_ENTRY 4096 +#define IN_FLOW_CNT_TBL_MAX_ENTRY 4096 + +sw_error_t +hppe_in_flow_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union in_flow_cnt_tbl_u *value); + +sw_error_t +hppe_in_flow_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union in_flow_cnt_tbl_u *value); + +sw_error_t +hppe_flow_ctrl0_get( + a_uint32_t dev_id, + union flow_ctrl0_u *value); + +sw_error_t +hppe_flow_ctrl0_set( + a_uint32_t dev_id, + union flow_ctrl0_u *value); + +sw_error_t +hppe_flow_ctrl1_get( + a_uint32_t dev_id, + a_uint32_t index, + union flow_ctrl1_u *value); + +sw_error_t +hppe_flow_ctrl1_set( + a_uint32_t dev_id, + a_uint32_t index, + union flow_ctrl1_u *value); + + +sw_error_t +hppe_in_flow_tbl_op_get( + a_uint32_t dev_id, + union in_flow_tbl_op_u *value); + +sw_error_t +hppe_in_flow_tbl_op_set( + a_uint32_t dev_id, + union in_flow_tbl_op_u *value); + +sw_error_t +hppe_in_flow_host_tbl_op_get( + a_uint32_t dev_id, + union in_flow_host_tbl_op_u *value); + +sw_error_t +hppe_in_flow_host_tbl_op_set( + a_uint32_t dev_id, + union in_flow_host_tbl_op_u *value); + +sw_error_t +hppe_in_flow_tbl_op_data0_get( + a_uint32_t dev_id, + union in_flow_tbl_op_data0_u *value); + +sw_error_t +hppe_in_flow_tbl_op_data0_set( + a_uint32_t dev_id, + union in_flow_tbl_op_data0_u *value); + +sw_error_t +hppe_in_flow_tbl_op_data1_get( + a_uint32_t dev_id, + union in_flow_tbl_op_data1_u *value); + +sw_error_t +hppe_in_flow_tbl_op_data1_set( + a_uint32_t dev_id, + union in_flow_tbl_op_data1_u *value); + +sw_error_t +hppe_in_flow_tbl_op_data2_get( + a_uint32_t dev_id, + union in_flow_tbl_op_data2_u *value); + +sw_error_t +hppe_in_flow_tbl_op_data2_set( + a_uint32_t dev_id, + union in_flow_tbl_op_data2_u *value); + +sw_error_t +hppe_in_flow_tbl_op_data3_get( + a_uint32_t dev_id, + union in_flow_tbl_op_data3_u *value); + +sw_error_t +hppe_in_flow_tbl_op_data3_set( + a_uint32_t dev_id, + union in_flow_tbl_op_data3_u *value); + +sw_error_t +hppe_in_flow_tbl_op_data4_get( + a_uint32_t dev_id, + union in_flow_tbl_op_data4_u *value); + +sw_error_t +hppe_in_flow_tbl_op_data4_set( + a_uint32_t dev_id, + union in_flow_tbl_op_data4_u *value); + +sw_error_t +hppe_in_flow_tbl_op_data5_get( + a_uint32_t dev_id, + union in_flow_tbl_op_data5_u *value); + +sw_error_t +hppe_in_flow_tbl_op_data5_set( + a_uint32_t dev_id, + union in_flow_tbl_op_data5_u *value); + +sw_error_t +hppe_in_flow_tbl_op_data6_get( + a_uint32_t dev_id, + union in_flow_tbl_op_data6_u *value); + +sw_error_t +hppe_in_flow_tbl_op_data6_set( + a_uint32_t dev_id, + union in_flow_tbl_op_data6_u *value); + +sw_error_t +hppe_in_flow_tbl_op_data7_get( + a_uint32_t dev_id, + union in_flow_tbl_op_data7_u *value); + +sw_error_t +hppe_in_flow_tbl_op_data7_set( + a_uint32_t dev_id, + union in_flow_tbl_op_data7_u *value); + +sw_error_t +hppe_in_flow_tbl_op_data8_get( + a_uint32_t dev_id, + union in_flow_tbl_op_data8_u *value); + +sw_error_t +hppe_in_flow_tbl_op_data8_set( + a_uint32_t dev_id, + union in_flow_tbl_op_data8_u *value); + +sw_error_t +hppe_flow_host_tbl_op_data0_get( + a_uint32_t dev_id, + union flow_host_tbl_op_data0_u *value); + +sw_error_t +hppe_flow_host_tbl_op_data0_set( + a_uint32_t dev_id, + union flow_host_tbl_op_data0_u *value); + +sw_error_t +hppe_flow_host_tbl_op_data1_get( + a_uint32_t dev_id, + union flow_host_tbl_op_data1_u *value); + +sw_error_t +hppe_flow_host_tbl_op_data1_set( + a_uint32_t dev_id, + union flow_host_tbl_op_data1_u *value); + +sw_error_t +hppe_flow_host_tbl_op_data2_get( + a_uint32_t dev_id, + union flow_host_tbl_op_data2_u *value); + +sw_error_t +hppe_flow_host_tbl_op_data2_set( + a_uint32_t dev_id, + union flow_host_tbl_op_data2_u *value); + +sw_error_t +hppe_flow_host_tbl_op_data3_get( + a_uint32_t dev_id, + union flow_host_tbl_op_data3_u *value); + +sw_error_t +hppe_flow_host_tbl_op_data3_set( + a_uint32_t dev_id, + union flow_host_tbl_op_data3_u *value); + +sw_error_t +hppe_flow_host_tbl_op_data4_get( + a_uint32_t dev_id, + union flow_host_tbl_op_data4_u *value); + +sw_error_t +hppe_flow_host_tbl_op_data4_set( + a_uint32_t dev_id, + union flow_host_tbl_op_data4_u *value); + +sw_error_t +hppe_flow_host_tbl_op_data5_get( + a_uint32_t dev_id, + union flow_host_tbl_op_data5_u *value); + +sw_error_t +hppe_flow_host_tbl_op_data5_set( + a_uint32_t dev_id, + union flow_host_tbl_op_data5_u *value); + +sw_error_t +hppe_flow_host_tbl_op_data6_get( + a_uint32_t dev_id, + union flow_host_tbl_op_data6_u *value); + +sw_error_t +hppe_flow_host_tbl_op_data6_set( + a_uint32_t dev_id, + union flow_host_tbl_op_data6_u *value); + +sw_error_t +hppe_flow_host_tbl_op_data7_get( + a_uint32_t dev_id, + union flow_host_tbl_op_data7_u *value); + +sw_error_t +hppe_flow_host_tbl_op_data7_set( + a_uint32_t dev_id, + union flow_host_tbl_op_data7_u *value); + +sw_error_t +hppe_flow_host_tbl_op_data8_get( + a_uint32_t dev_id, + union flow_host_tbl_op_data8_u *value); + +sw_error_t +hppe_flow_host_tbl_op_data8_set( + a_uint32_t dev_id, + union flow_host_tbl_op_data8_u *value); + +sw_error_t +hppe_flow_host_tbl_op_data9_get( + a_uint32_t dev_id, + union flow_host_tbl_op_data9_u *value); + +sw_error_t +hppe_flow_host_tbl_op_data9_set( + a_uint32_t dev_id, + union flow_host_tbl_op_data9_u *value); + +sw_error_t +hppe_in_flow_tbl_op_rslt_get( + a_uint32_t dev_id, + union in_flow_tbl_op_rslt_u *value); + +sw_error_t +hppe_in_flow_tbl_op_rslt_set( + a_uint32_t dev_id, + union in_flow_tbl_op_rslt_u *value); + +sw_error_t +hppe_flow_host_tbl_op_rslt_get( + a_uint32_t dev_id, + union flow_host_tbl_op_rslt_u *value); + +sw_error_t +hppe_flow_host_tbl_op_rslt_set( + a_uint32_t dev_id, + union flow_host_tbl_op_rslt_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_u *value); + +sw_error_t +hppe_in_flow_host_tbl_rd_op_get( + a_uint32_t dev_id, + union in_flow_host_tbl_rd_op_u *value); + +sw_error_t +hppe_in_flow_host_tbl_rd_op_set( + a_uint32_t dev_id, + union in_flow_host_tbl_rd_op_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data0_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data0_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data0_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data0_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data1_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data1_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data1_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data1_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data2_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data2_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data2_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data2_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data3_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data3_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data3_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data3_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data4_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data4_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data4_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data4_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data5_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data5_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data5_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data5_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data6_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data6_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data6_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data6_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data7_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data7_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data7_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data7_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data8_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data8_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data8_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data8_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data0_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data0_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data0_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data0_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data1_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data1_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data1_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data1_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data2_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data2_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data2_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data2_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data3_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data3_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data3_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data3_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data4_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data4_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data4_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data4_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data5_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data5_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data5_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data5_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data6_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data6_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data6_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data6_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data7_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data7_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data7_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data7_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data8_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data8_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data8_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data8_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data9_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data9_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data9_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data9_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_rslt_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_rslt_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_rslt_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_rslt_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_op_rslt_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_rslt_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_op_rslt_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_rslt_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data0_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data0_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data0_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data0_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data1_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data1_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data1_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data1_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data2_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data2_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data2_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data2_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data3_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data3_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data3_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data3_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data4_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data4_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data4_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data4_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data5_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data5_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data5_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data5_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data6_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data6_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data6_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data6_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data7_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data7_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data7_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data7_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data8_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data8_u *value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data8_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data8_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data0_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data0_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data0_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data0_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data1_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data1_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data1_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data1_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data2_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data2_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data2_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data2_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data3_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data3_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data3_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data3_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data4_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data4_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data4_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data4_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data5_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data5_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data5_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data5_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data6_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data6_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data6_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data6_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data7_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data7_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data7_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data7_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data8_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data8_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data8_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data8_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data9_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data9_u *value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data9_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data9_u *value); + +sw_error_t +hppe_in_flow_3tuple_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union in_flow_3tuple_tbl_u *value); + +sw_error_t +hppe_in_flow_3tuple_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union in_flow_3tuple_tbl_u *value); + +sw_error_t +hppe_in_flow_ipv6_3tuple_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union in_flow_ipv6_3tuple_tbl_u *value); + +sw_error_t +hppe_in_flow_ipv6_3tuple_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union in_flow_ipv6_3tuple_tbl_u *value); + +sw_error_t +hppe_in_flow_ipv6_5tuple_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union in_flow_ipv6_5tuple_tbl_u *value); + +sw_error_t +hppe_in_flow_ipv6_5tuple_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union in_flow_ipv6_5tuple_tbl_u *value); + +sw_error_t +hppe_in_flow_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union in_flow_tbl_u *value); + +sw_error_t +hppe_in_flow_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union in_flow_tbl_u *value); + +sw_error_t +hppe_eg_flow_tree_map_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union eg_flow_tree_map_tbl_u *value); + +sw_error_t +hppe_eg_flow_tree_map_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union eg_flow_tree_map_tbl_u *value); + +sw_error_t +hppe_flow_ctrl0_flow_hash_mode_0_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_ctrl0_flow_hash_mode_0_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_ctrl0_flow_age_timer_unit_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_ctrl0_flow_age_timer_unit_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_ctrl0_flow_hash_mode_1_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_ctrl0_flow_hash_mode_1_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_ctrl0_flow_age_timer_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_ctrl0_flow_age_timer_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_ctrl0_flow_en_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_ctrl0_flow_en_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl1_frag_bypass_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl1_frag_bypass_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl4_key_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl4_key_sel_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl1_key_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl1_key_sel_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl0_frag_bypass_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl0_frag_bypass_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl0_miss_action_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl0_miss_action_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl0_key_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl0_key_sel_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl1_bypass_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl1_bypass_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl0_bypass_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl0_bypass_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl2_tcp_special_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl2_tcp_special_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl4_tcp_special_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl4_tcp_special_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl3_frag_bypass_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl3_frag_bypass_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl3_bypass_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl3_bypass_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl3_tcp_special_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl3_tcp_special_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl1_miss_action_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl1_miss_action_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl4_frag_bypass_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl4_frag_bypass_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl1_tcp_special_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl1_tcp_special_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl2_key_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl2_key_sel_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl2_miss_action_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl2_miss_action_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl2_bypass_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl2_bypass_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl4_bypass_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl4_bypass_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl3_key_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl3_key_sel_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl0_tcp_special_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl0_tcp_special_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl2_frag_bypass_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl2_frag_bypass_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl3_miss_action_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl3_miss_action_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl4_miss_action_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_flow_ctrl1_flow_ctl4_miss_action_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_flow_tbl_op_entry_index_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_op_entry_index_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_op_cmd_id_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_op_cmd_id_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_op_byp_rslt_en_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_op_byp_rslt_en_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_op_op_mode_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_op_op_mode_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_op_op_type_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_op_op_type_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_op_op_host_en_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_op_op_host_en_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_op_op_result_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_op_op_result_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_op_busy_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_op_busy_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_op_hash_block_bitmap_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_op_hash_block_bitmap_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_host_tbl_op_host_entry_index_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_host_tbl_op_host_entry_index_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_host_tbl_op_hash_block_bitmap_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_host_tbl_op_hash_block_bitmap_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_op_data0_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_op_data0_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_op_data1_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_op_data1_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_op_data2_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_op_data2_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_op_data3_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_op_data3_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_op_data4_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_op_data4_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_op_data5_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_op_data5_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_op_data6_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_op_data6_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_op_data7_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_op_data7_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_op_data8_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_op_data8_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_host_tbl_op_data0_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_host_tbl_op_data0_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_host_tbl_op_data1_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_host_tbl_op_data1_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_host_tbl_op_data2_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_host_tbl_op_data2_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_host_tbl_op_data3_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_host_tbl_op_data3_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_host_tbl_op_data4_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_host_tbl_op_data4_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_host_tbl_op_data5_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_host_tbl_op_data5_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_host_tbl_op_data6_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_host_tbl_op_data6_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_host_tbl_op_data7_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_host_tbl_op_data7_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_host_tbl_op_data8_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_host_tbl_op_data8_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_host_tbl_op_data9_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_host_tbl_op_data9_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_op_rslt_op_rslt_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_op_rslt_op_rslt_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_op_rslt_valid_cnt_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_op_rslt_valid_cnt_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_op_rslt_flow_entry_index_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_op_rslt_flow_entry_index_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_op_rslt_cmd_id_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_op_rslt_cmd_id_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_host_tbl_op_rslt_host_entry_index_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_host_tbl_op_rslt_host_entry_index_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_rd_op_entry_index_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_entry_index_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_rd_op_cmd_id_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_cmd_id_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_rd_op_byp_rslt_en_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_byp_rslt_en_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_rd_op_op_mode_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_op_mode_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_rd_op_op_type_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_op_type_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_rd_op_op_host_en_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_op_host_en_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_rd_op_op_result_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_op_result_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_rd_op_busy_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_busy_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_rd_op_hash_block_bitmap_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_hash_block_bitmap_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_host_tbl_rd_op_host_entry_index_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_host_tbl_rd_op_host_entry_index_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_host_tbl_rd_op_hash_block_bitmap_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_host_tbl_rd_op_hash_block_bitmap_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data0_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data0_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data1_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data1_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data2_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data2_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data3_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data3_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data4_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data4_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data5_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data5_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data6_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data6_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data7_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data7_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data8_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_data8_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data0_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data0_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data1_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data1_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data2_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data2_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data3_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data3_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data4_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data4_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data5_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data5_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data6_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data6_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data7_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data7_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data8_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data8_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data9_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_host_tbl_rd_op_data9_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_rd_op_rslt_op_rslt_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_rslt_op_rslt_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_rd_op_rslt_valid_cnt_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_rslt_valid_cnt_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_rd_op_rslt_flow_entry_index_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_rslt_flow_entry_index_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_rd_op_rslt_cmd_id_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_rd_op_rslt_cmd_id_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_host_tbl_rd_op_rslt_host_entry_index_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_host_tbl_rd_op_rslt_host_entry_index_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data0_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data0_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data1_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data1_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data2_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data2_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data3_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data3_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data4_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data4_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data5_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data5_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data6_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data6_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data7_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data7_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data8_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data8_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data0_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data0_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data1_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data1_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data2_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data2_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data3_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data3_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data4_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data4_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data5_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data5_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data6_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data6_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data7_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data7_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data8_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data8_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data9_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data9_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_eg_flow_tree_map_tbl_tree_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_flow_tree_map_tbl_tree_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_flow_cnt_tbl_hit_byte_counter_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_in_flow_cnt_tbl_hit_byte_counter_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_in_flow_cnt_tbl_hit_pkt_counter_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_flow_cnt_tbl_hit_pkt_counter_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_flow_ipv4_5tuple_add( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_tbl_u *entry); + +sw_error_t +hppe_flow_ipv4_3tuple_add( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_3tuple_tbl_u *entry); + +sw_error_t +hppe_flow_ipv6_5tuple_add( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_ipv6_5tuple_tbl_u *entry); + +sw_error_t +hppe_flow_ipv6_3tuple_add( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_ipv6_3tuple_tbl_u *entry); + +sw_error_t +hppe_flow_flush_common(a_uint32_t dev_id); + +sw_error_t +hppe_flow_ipv4_5tuple_del( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_tbl_u *entry); + +sw_error_t +hppe_flow_ipv4_3tuple_del( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_3tuple_tbl_u *entry); + +sw_error_t +hppe_flow_ipv6_5tuple_del( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_ipv6_5tuple_tbl_u *entry); + +sw_error_t +hppe_flow_ipv6_3tuple_del( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_ipv6_3tuple_tbl_u *entry); + +sw_error_t +hppe_flow_ipv4_5tuple_get( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_tbl_u *entry); + +sw_error_t +hppe_flow_ipv4_3tuple_get( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_3tuple_tbl_u *entry); + +sw_error_t +hppe_flow_ipv6_5tuple_get( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_ipv6_5tuple_tbl_u *entry); + +sw_error_t +hppe_flow_ipv6_3tuple_get( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_ipv6_3tuple_tbl_u *entry); + + +#include "hppe_ip_reg.h" + +sw_error_t +hppe_flow_host_get_common( + a_uint32_t dev_id, + a_uint32_t op_mode, + a_uint32_t *index, + a_uint32_t *data, + a_uint32_t num); + + +sw_error_t +hppe_flow_host_flush_common(a_uint32_t dev_id); + + +sw_error_t +hppe_flow_host_op_both_common( + a_uint32_t dev_id, + a_uint32_t op_type, + a_uint32_t op_mode, + a_uint32_t *index); + + +sw_error_t +hppe_flow_entry_host_op_ipv4_5tuple_add( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_tbl_u *entry); + + +sw_error_t +hppe_flow_entry_host_op_ipv4_3tuple_add( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_3tuple_tbl_u *entry); + + +sw_error_t +hppe_flow_entry_host_op_ipv6_5tuple_add( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_ipv6_5tuple_tbl_u *entry); + + +sw_error_t +hppe_flow_entry_host_op_ipv6_3tuple_add( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_ipv6_3tuple_tbl_u *entry); + + +sw_error_t +hppe_flow_entry_host_op_ipv4_5tuple_del( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_tbl_u *entry); + + +sw_error_t +hppe_flow_entry_host_op_ipv4_3tuple_del( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_3tuple_tbl_u *entry); + + +sw_error_t +hppe_flow_entry_host_op_ipv6_5tuple_del( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_ipv6_5tuple_tbl_u *entry); + + +sw_error_t +hppe_flow_entry_host_op_ipv6_3tuple_del( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_ipv6_3tuple_tbl_u *entry); + + +sw_error_t +hppe_flow_entry_host_op_ipv4_5tuple_get( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_tbl_u *entry); + + +sw_error_t +hppe_flow_entry_host_op_ipv4_3tuple_get( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_3tuple_tbl_u *entry); + + +sw_error_t +hppe_flow_entry_host_op_ipv6_5tuple_get( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_ipv6_5tuple_tbl_u *entry); + + +sw_error_t +hppe_flow_entry_host_op_ipv6_3tuple_get( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_ipv6_3tuple_tbl_u *entry); + + +sw_error_t +hppe_flow_host_data_op_common( + a_uint32_t dev_id, + a_uint32_t op_type, + a_uint32_t op_mode, + a_uint32_t *index); + + +sw_error_t +hppe_flow_host_ipv4_data_add( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_tbl_u *entry); + + +sw_error_t +hppe_flow_host_ipv6_data_add( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_ipv6_tbl_u *entry); + + +sw_error_t +hppe_flow_host_ipv4_data_get( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_tbl_u *entry); + + +sw_error_t +hppe_flow_host_ipv6_data_get( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_ipv6_tbl_u *entry); + + +sw_error_t +hppe_flow_host_ipv4_data_del( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_tbl_u *entry); + + +sw_error_t +hppe_flow_host_ipv6_data_del( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_ipv6_tbl_u *entry); + +sw_error_t +hppe_flow_host_ipv4_data_rd_add( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_tbl_u *entry); + +sw_error_t +hppe_flow_host_ipv6_data_rd_add( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_ipv6_tbl_u *entry); + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_flow_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_flow_reg.h new file mode 100755 index 000000000..41b9c445b --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_flow_reg.h @@ -0,0 +1,2856 @@ +/* + * 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 + * @{ + */ +#ifndef _HPPE_FLOW_REG_H_ +#define _HPPE_FLOW_REG_H_ + +/*[register] FLOW_CTRL0*/ +#define FLOW_CTRL0 +#define FLOW_CTRL0_ADDRESS 0x368 +#define FLOW_CTRL0_NUM 1 +#define FLOW_CTRL0_INC 0x4 +#define FLOW_CTRL0_TYPE REG_TYPE_RW +#define FLOW_CTRL0_DEFAULT 0xc89 + /*[field] FLOW_EN*/ + #define FLOW_CTRL0_FLOW_EN + #define FLOW_CTRL0_FLOW_EN_OFFSET 0 + #define FLOW_CTRL0_FLOW_EN_LEN 1 + #define FLOW_CTRL0_FLOW_EN_DEFAULT 0x1 + /*[field] FLOW_HASH_MODE_0*/ + #define FLOW_CTRL0_FLOW_HASH_MODE_0 + #define FLOW_CTRL0_FLOW_HASH_MODE_0_OFFSET 1 + #define FLOW_CTRL0_FLOW_HASH_MODE_0_LEN 2 + #define FLOW_CTRL0_FLOW_HASH_MODE_0_DEFAULT 0x0 + /*[field] FLOW_HASH_MODE_1*/ + #define FLOW_CTRL0_FLOW_HASH_MODE_1 + #define FLOW_CTRL0_FLOW_HASH_MODE_1_OFFSET 3 + #define FLOW_CTRL0_FLOW_HASH_MODE_1_LEN 2 + #define FLOW_CTRL0_FLOW_HASH_MODE_1_DEFAULT 0x1 + /*[field] FLOW_AGE_TIMER*/ + #define FLOW_CTRL0_FLOW_AGE_TIMER + #define FLOW_CTRL0_FLOW_AGE_TIMER_OFFSET 5 + #define FLOW_CTRL0_FLOW_AGE_TIMER_LEN 16 + #define FLOW_CTRL0_FLOW_AGE_TIMER_DEFAULT 0x64 + /*[field] FLOW_AGE_TIMER_UNIT*/ + #define FLOW_CTRL0_FLOW_AGE_TIMER_UNIT + #define FLOW_CTRL0_FLOW_AGE_TIMER_UNIT_OFFSET 21 + #define FLOW_CTRL0_FLOW_AGE_TIMER_UNIT_LEN 2 + #define FLOW_CTRL0_FLOW_AGE_TIMER_UNIT_DEFAULT 0x0 + +struct flow_ctrl0 { + a_uint32_t flow_en:1; + a_uint32_t flow_hash_mode_0:2; + a_uint32_t flow_hash_mode_1:2; + a_uint32_t flow_age_timer:16; + a_uint32_t flow_age_timer_unit:2; + a_uint32_t _reserved0:9; +}; + +union flow_ctrl0_u { + a_uint32_t val; + struct flow_ctrl0 bf; +}; + +/*[register] FLOW_CTRL1*/ +#define FLOW_CTRL1 +#define FLOW_CTRL1_ADDRESS 0x36c +#define FLOW_CTRL1_NUM 3 +#define FLOW_CTRL1_INC 0x4 +#define FLOW_CTRL1_TYPE REG_TYPE_RW +#define FLOW_CTRL1_DEFAULT 0x20000 + /*[field] FLOW_CTL0_MISS_ACTION*/ + #define FLOW_CTRL1_FLOW_CTL0_MISS_ACTION + #define FLOW_CTRL1_FLOW_CTL0_MISS_ACTION_OFFSET 0 + #define FLOW_CTRL1_FLOW_CTL0_MISS_ACTION_LEN 2 + #define FLOW_CTRL1_FLOW_CTL0_MISS_ACTION_DEFAULT 0x0 + /*[field] FLOW_CTL0_FRAG_BYPASS*/ + #define FLOW_CTRL1_FLOW_CTL0_FRAG_BYPASS + #define FLOW_CTRL1_FLOW_CTL0_FRAG_BYPASS_OFFSET 2 + #define FLOW_CTRL1_FLOW_CTL0_FRAG_BYPASS_LEN 1 + #define FLOW_CTRL1_FLOW_CTL0_FRAG_BYPASS_DEFAULT 0x0 + /*[field] FLOW_CTL0_TCP_SPECIAL*/ + #define FLOW_CTRL1_FLOW_CTL0_TCP_SPECIAL + #define FLOW_CTRL1_FLOW_CTL0_TCP_SPECIAL_OFFSET 3 + #define FLOW_CTRL1_FLOW_CTL0_TCP_SPECIAL_LEN 1 + #define FLOW_CTRL1_FLOW_CTL0_TCP_SPECIAL_DEFAULT 0x0 + /*[field] FLOW_CTL0_BYPASS*/ + #define FLOW_CTRL1_FLOW_CTL0_BYPASS + #define FLOW_CTRL1_FLOW_CTL0_BYPASS_OFFSET 4 + #define FLOW_CTRL1_FLOW_CTL0_BYPASS_LEN 1 + #define FLOW_CTRL1_FLOW_CTL0_BYPASS_DEFAULT 0x0 + /*[field] FLOW_CTL0_KEY_SEL*/ + #define FLOW_CTRL1_FLOW_CTL0_KEY_SEL + #define FLOW_CTRL1_FLOW_CTL0_KEY_SEL_OFFSET 5 + #define FLOW_CTRL1_FLOW_CTL0_KEY_SEL_LEN 1 + #define FLOW_CTRL1_FLOW_CTL0_KEY_SEL_DEFAULT 0x0 + /*[field] FLOW_CTL1_MISS_ACTION*/ + #define FLOW_CTRL1_FLOW_CTL1_MISS_ACTION + #define FLOW_CTRL1_FLOW_CTL1_MISS_ACTION_OFFSET 6 + #define FLOW_CTRL1_FLOW_CTL1_MISS_ACTION_LEN 2 + #define FLOW_CTRL1_FLOW_CTL1_MISS_ACTION_DEFAULT 0x0 + /*[field] FLOW_CTL1_FRAG_BYPASS*/ + #define FLOW_CTRL1_FLOW_CTL1_FRAG_BYPASS + #define FLOW_CTRL1_FLOW_CTL1_FRAG_BYPASS_OFFSET 8 + #define FLOW_CTRL1_FLOW_CTL1_FRAG_BYPASS_LEN 1 + #define FLOW_CTRL1_FLOW_CTL1_FRAG_BYPASS_DEFAULT 0x0 + /*[field] FLOW_CTL1_TCP_SPECIAL*/ + #define FLOW_CTRL1_FLOW_CTL1_TCP_SPECIAL + #define FLOW_CTRL1_FLOW_CTL1_TCP_SPECIAL_OFFSET 9 + #define FLOW_CTRL1_FLOW_CTL1_TCP_SPECIAL_LEN 1 + #define FLOW_CTRL1_FLOW_CTL1_TCP_SPECIAL_DEFAULT 0x0 + /*[field] FLOW_CTL1_BYPASS*/ + #define FLOW_CTRL1_FLOW_CTL1_BYPASS + #define FLOW_CTRL1_FLOW_CTL1_BYPASS_OFFSET 10 + #define FLOW_CTRL1_FLOW_CTL1_BYPASS_LEN 1 + #define FLOW_CTRL1_FLOW_CTL1_BYPASS_DEFAULT 0x0 + /*[field] FLOW_CTL1_KEY_SEL*/ + #define FLOW_CTRL1_FLOW_CTL1_KEY_SEL + #define FLOW_CTRL1_FLOW_CTL1_KEY_SEL_OFFSET 11 + #define FLOW_CTRL1_FLOW_CTL1_KEY_SEL_LEN 1 + #define FLOW_CTRL1_FLOW_CTL1_KEY_SEL_DEFAULT 0x0 + /*[field] FLOW_CTL2_MISS_ACTION*/ + #define FLOW_CTRL1_FLOW_CTL2_MISS_ACTION + #define FLOW_CTRL1_FLOW_CTL2_MISS_ACTION_OFFSET 12 + #define FLOW_CTRL1_FLOW_CTL2_MISS_ACTION_LEN 2 + #define FLOW_CTRL1_FLOW_CTL2_MISS_ACTION_DEFAULT 0x0 + /*[field] FLOW_CTL2_FRAG_BYPASS*/ + #define FLOW_CTRL1_FLOW_CTL2_FRAG_BYPASS + #define FLOW_CTRL1_FLOW_CTL2_FRAG_BYPASS_OFFSET 14 + #define FLOW_CTRL1_FLOW_CTL2_FRAG_BYPASS_LEN 1 + #define FLOW_CTRL1_FLOW_CTL2_FRAG_BYPASS_DEFAULT 0x0 + /*[field] FLOW_CTL2_TCP_SPECIAL*/ + #define FLOW_CTRL1_FLOW_CTL2_TCP_SPECIAL + #define FLOW_CTRL1_FLOW_CTL2_TCP_SPECIAL_OFFSET 15 + #define FLOW_CTRL1_FLOW_CTL2_TCP_SPECIAL_LEN 1 + #define FLOW_CTRL1_FLOW_CTL2_TCP_SPECIAL_DEFAULT 0x0 + /*[field] FLOW_CTL2_BYPASS*/ + #define FLOW_CTRL1_FLOW_CTL2_BYPASS + #define FLOW_CTRL1_FLOW_CTL2_BYPASS_OFFSET 16 + #define FLOW_CTRL1_FLOW_CTL2_BYPASS_LEN 1 + #define FLOW_CTRL1_FLOW_CTL2_BYPASS_DEFAULT 0x0 + /*[field] FLOW_CTL2_KEY_SEL*/ + #define FLOW_CTRL1_FLOW_CTL2_KEY_SEL + #define FLOW_CTRL1_FLOW_CTL2_KEY_SEL_OFFSET 17 + #define FLOW_CTRL1_FLOW_CTL2_KEY_SEL_LEN 1 + #define FLOW_CTRL1_FLOW_CTL2_KEY_SEL_DEFAULT 0x1 + /*[field] FLOW_CTL3_MISS_ACTION*/ + #define FLOW_CTRL1_FLOW_CTL3_MISS_ACTION + #define FLOW_CTRL1_FLOW_CTL3_MISS_ACTION_OFFSET 18 + #define FLOW_CTRL1_FLOW_CTL3_MISS_ACTION_LEN 2 + #define FLOW_CTRL1_FLOW_CTL3_MISS_ACTION_DEFAULT 0x0 + /*[field] FLOW_CTL3_FRAG_BYPASS*/ + #define FLOW_CTRL1_FLOW_CTL3_FRAG_BYPASS + #define FLOW_CTRL1_FLOW_CTL3_FRAG_BYPASS_OFFSET 20 + #define FLOW_CTRL1_FLOW_CTL3_FRAG_BYPASS_LEN 1 + #define FLOW_CTRL1_FLOW_CTL3_FRAG_BYPASS_DEFAULT 0x0 + /*[field] FLOW_CTL3_TCP_SPECIAL*/ + #define FLOW_CTRL1_FLOW_CTL3_TCP_SPECIAL + #define FLOW_CTRL1_FLOW_CTL3_TCP_SPECIAL_OFFSET 21 + #define FLOW_CTRL1_FLOW_CTL3_TCP_SPECIAL_LEN 1 + #define FLOW_CTRL1_FLOW_CTL3_TCP_SPECIAL_DEFAULT 0x0 + /*[field] FLOW_CTL3_BYPASS*/ + #define FLOW_CTRL1_FLOW_CTL3_BYPASS + #define FLOW_CTRL1_FLOW_CTL3_BYPASS_OFFSET 22 + #define FLOW_CTRL1_FLOW_CTL3_BYPASS_LEN 1 + #define FLOW_CTRL1_FLOW_CTL3_BYPASS_DEFAULT 0x0 + /*[field] FLOW_CTL3_KEY_SEL*/ + #define FLOW_CTRL1_FLOW_CTL3_KEY_SEL + #define FLOW_CTRL1_FLOW_CTL3_KEY_SEL_OFFSET 23 + #define FLOW_CTRL1_FLOW_CTL3_KEY_SEL_LEN 1 + #define FLOW_CTRL1_FLOW_CTL3_KEY_SEL_DEFAULT 0x0 + /*[field] FLOW_CTL4_MISS_ACTION*/ + #define FLOW_CTRL1_FLOW_CTL4_MISS_ACTION + #define FLOW_CTRL1_FLOW_CTL4_MISS_ACTION_OFFSET 24 + #define FLOW_CTRL1_FLOW_CTL4_MISS_ACTION_LEN 2 + #define FLOW_CTRL1_FLOW_CTL4_MISS_ACTION_DEFAULT 0x0 + /*[field] FLOW_CTL4_FRAG_BYPASS*/ + #define FLOW_CTRL1_FLOW_CTL4_FRAG_BYPASS + #define FLOW_CTRL1_FLOW_CTL4_FRAG_BYPASS_OFFSET 26 + #define FLOW_CTRL1_FLOW_CTL4_FRAG_BYPASS_LEN 1 + #define FLOW_CTRL1_FLOW_CTL4_FRAG_BYPASS_DEFAULT 0x0 + /*[field] FLOW_CTL4_TCP_SPECIAL*/ + #define FLOW_CTRL1_FLOW_CTL4_TCP_SPECIAL + #define FLOW_CTRL1_FLOW_CTL4_TCP_SPECIAL_OFFSET 27 + #define FLOW_CTRL1_FLOW_CTL4_TCP_SPECIAL_LEN 1 + #define FLOW_CTRL1_FLOW_CTL4_TCP_SPECIAL_DEFAULT 0x0 + /*[field] FLOW_CTL4_BYPASS*/ + #define FLOW_CTRL1_FLOW_CTL4_BYPASS + #define FLOW_CTRL1_FLOW_CTL4_BYPASS_OFFSET 28 + #define FLOW_CTRL1_FLOW_CTL4_BYPASS_LEN 1 + #define FLOW_CTRL1_FLOW_CTL4_BYPASS_DEFAULT 0x0 + /*[field] FLOW_CTL4_KEY_SEL*/ + #define FLOW_CTRL1_FLOW_CTL4_KEY_SEL + #define FLOW_CTRL1_FLOW_CTL4_KEY_SEL_OFFSET 29 + #define FLOW_CTRL1_FLOW_CTL4_KEY_SEL_LEN 1 + #define FLOW_CTRL1_FLOW_CTL4_KEY_SEL_DEFAULT 0x0 + +struct flow_ctrl1 { + a_uint32_t flow_ctl0_miss_action:2; + a_uint32_t flow_ctl0_frag_bypass:1; + a_uint32_t flow_ctl0_tcp_special:1; + a_uint32_t flow_ctl0_bypass:1; + a_uint32_t flow_ctl0_key_sel:1; + a_uint32_t flow_ctl1_miss_action:2; + a_uint32_t flow_ctl1_frag_bypass:1; + a_uint32_t flow_ctl1_tcp_special:1; + a_uint32_t flow_ctl1_bypass:1; + a_uint32_t flow_ctl1_key_sel:1; + a_uint32_t flow_ctl2_miss_action:2; + a_uint32_t flow_ctl2_frag_bypass:1; + a_uint32_t flow_ctl2_tcp_special:1; + a_uint32_t flow_ctl2_bypass:1; + a_uint32_t flow_ctl2_key_sel:1; + a_uint32_t flow_ctl3_miss_action:2; + a_uint32_t flow_ctl3_frag_bypass:1; + a_uint32_t flow_ctl3_tcp_special:1; + a_uint32_t flow_ctl3_bypass:1; + a_uint32_t flow_ctl3_key_sel:1; + a_uint32_t flow_ctl4_miss_action:2; + a_uint32_t flow_ctl4_frag_bypass:1; + a_uint32_t flow_ctl4_tcp_special:1; + a_uint32_t flow_ctl4_bypass:1; + a_uint32_t flow_ctl4_key_sel:1; + a_uint32_t _reserved0:2; +}; + +union flow_ctrl1_u { + a_uint32_t val; + struct flow_ctrl1 bf; +}; + +/*[register] IN_FLOW_TBL_OP*/ +#define IN_FLOW_TBL_OP +#define IN_FLOW_TBL_OP_ADDRESS 0x3b8 +#define IN_FLOW_TBL_OP_NUM 1 +#define IN_FLOW_TBL_OP_INC 0x4 +#define IN_FLOW_TBL_OP_TYPE REG_TYPE_RW +#define IN_FLOW_TBL_OP_DEFAULT 0x0 + /*[field] CMD_ID*/ + #define IN_FLOW_TBL_OP_CMD_ID + #define IN_FLOW_TBL_OP_CMD_ID_OFFSET 0 + #define IN_FLOW_TBL_OP_CMD_ID_LEN 4 + #define IN_FLOW_TBL_OP_CMD_ID_DEFAULT 0x0 + /*[field] BYP_RSLT_EN*/ + #define IN_FLOW_TBL_OP_BYP_RSLT_EN + #define IN_FLOW_TBL_OP_BYP_RSLT_EN_OFFSET 4 + #define IN_FLOW_TBL_OP_BYP_RSLT_EN_LEN 1 + #define IN_FLOW_TBL_OP_BYP_RSLT_EN_DEFAULT 0x0 + /*[field] OP_TYPE*/ + #define IN_FLOW_TBL_OP_OP_TYPE + #define IN_FLOW_TBL_OP_OP_TYPE_OFFSET 5 + #define IN_FLOW_TBL_OP_OP_TYPE_LEN 3 + #define IN_FLOW_TBL_OP_OP_TYPE_DEFAULT 0x0 + /*[field] HASH_BLOCK_BITMAP*/ + #define IN_FLOW_TBL_OP_HASH_BLOCK_BITMAP + #define IN_FLOW_TBL_OP_HASH_BLOCK_BITMAP_OFFSET 8 + #define IN_FLOW_TBL_OP_HASH_BLOCK_BITMAP_LEN 2 + #define IN_FLOW_TBL_OP_HASH_BLOCK_BITMAP_DEFAULT 0x0 + /*[field] OP_MODE*/ + #define IN_FLOW_TBL_OP_OP_MODE + #define IN_FLOW_TBL_OP_OP_MODE_OFFSET 10 + #define IN_FLOW_TBL_OP_OP_MODE_LEN 1 + #define IN_FLOW_TBL_OP_OP_MODE_DEFAULT 0x0 + /*[field] OP_HOST_EN*/ + #define IN_FLOW_TBL_OP_OP_HOST_EN + #define IN_FLOW_TBL_OP_OP_HOST_EN_OFFSET 11 + #define IN_FLOW_TBL_OP_OP_HOST_EN_LEN 1 + #define IN_FLOW_TBL_OP_OP_HOST_EN_DEFAULT 0x0 + /*[field] ENTRY_INDEX*/ + #define IN_FLOW_TBL_OP_ENTRY_INDEX + #define IN_FLOW_TBL_OP_ENTRY_INDEX_OFFSET 12 + #define IN_FLOW_TBL_OP_ENTRY_INDEX_LEN 12 + #define IN_FLOW_TBL_OP_ENTRY_INDEX_DEFAULT 0x0 + /*[field] OP_RESULT*/ + #define IN_FLOW_TBL_OP_OP_RESULT + #define IN_FLOW_TBL_OP_OP_RESULT_OFFSET 24 + #define IN_FLOW_TBL_OP_OP_RESULT_LEN 1 + #define IN_FLOW_TBL_OP_OP_RESULT_DEFAULT 0x0 + /*[field] BUSY*/ + #define IN_FLOW_TBL_OP_BUSY + #define IN_FLOW_TBL_OP_BUSY_OFFSET 25 + #define IN_FLOW_TBL_OP_BUSY_LEN 1 + #define IN_FLOW_TBL_OP_BUSY_DEFAULT 0x0 + +struct in_flow_tbl_op { + a_uint32_t cmd_id:4; + a_uint32_t byp_rslt_en:1; + a_uint32_t op_type:3; + a_uint32_t hash_block_bitmap:2; + a_uint32_t op_mode:1; + a_uint32_t op_host_en:1; + a_uint32_t entry_index:12; + a_uint32_t op_result:1; + a_uint32_t busy:1; + a_uint32_t _reserved0:6; +}; + +union in_flow_tbl_op_u { + a_uint32_t val; + struct in_flow_tbl_op bf; +}; + +/*[register] IN_FLOW_HOST_TBL_OP*/ +#define IN_FLOW_HOST_TBL_OP +#define IN_FLOW_HOST_TBL_OP_ADDRESS 0x3bc +#define IN_FLOW_HOST_TBL_OP_NUM 1 +#define IN_FLOW_HOST_TBL_OP_INC 0x4 +#define IN_FLOW_HOST_TBL_OP_TYPE REG_TYPE_RW +#define IN_FLOW_HOST_TBL_OP_DEFAULT 0x0 + /*[field] HASH_BLOCK_BITMAP*/ + #define IN_FLOW_HOST_TBL_OP_HASH_BLOCK_BITMAP + #define IN_FLOW_HOST_TBL_OP_HASH_BLOCK_BITMAP_OFFSET 0 + #define IN_FLOW_HOST_TBL_OP_HASH_BLOCK_BITMAP_LEN 2 + #define IN_FLOW_HOST_TBL_OP_HASH_BLOCK_BITMAP_DEFAULT 0x0 + /*[field] HOST_ENTRY_INDEX*/ + #define IN_FLOW_HOST_TBL_OP_HOST_ENTRY_INDEX + #define IN_FLOW_HOST_TBL_OP_HOST_ENTRY_INDEX_OFFSET 2 + #define IN_FLOW_HOST_TBL_OP_HOST_ENTRY_INDEX_LEN 13 + #define IN_FLOW_HOST_TBL_OP_HOST_ENTRY_INDEX_DEFAULT 0x0 + +struct in_flow_host_tbl_op { + a_uint32_t hash_block_bitmap:2; + a_uint32_t host_entry_index:13; + a_uint32_t _reserved0:17; +}; + +union in_flow_host_tbl_op_u { + a_uint32_t val; + struct in_flow_host_tbl_op bf; +}; + +/*[register] IN_FLOW_TBL_OP_DATA0*/ +#define IN_FLOW_TBL_OP_DATA0 +#define IN_FLOW_TBL_OP_DATA0_ADDRESS 0x3c0 +#define IN_FLOW_TBL_OP_DATA0_NUM 1 +#define IN_FLOW_TBL_OP_DATA0_INC 0x4 +#define IN_FLOW_TBL_OP_DATA0_TYPE REG_TYPE_RW +#define IN_FLOW_TBL_OP_DATA0_DEFAULT 0x0 + /*[field] DATA*/ + #define IN_FLOW_TBL_OP_DATA0_DATA + #define IN_FLOW_TBL_OP_DATA0_DATA_OFFSET 0 + #define IN_FLOW_TBL_OP_DATA0_DATA_LEN 32 + #define IN_FLOW_TBL_OP_DATA0_DATA_DEFAULT 0x0 + +struct in_flow_tbl_op_data0 { + a_uint32_t data:32; +}; + +union in_flow_tbl_op_data0_u { + a_uint32_t val; + struct in_flow_tbl_op_data0 bf; +}; + +/*[register] IN_FLOW_TBL_OP_DATA1*/ +#define IN_FLOW_TBL_OP_DATA1 +#define IN_FLOW_TBL_OP_DATA1_ADDRESS 0x3c4 +#define IN_FLOW_TBL_OP_DATA1_NUM 1 +#define IN_FLOW_TBL_OP_DATA1_INC 0x4 +#define IN_FLOW_TBL_OP_DATA1_TYPE REG_TYPE_RW +#define IN_FLOW_TBL_OP_DATA1_DEFAULT 0x0 + /*[field] DATA*/ + #define IN_FLOW_TBL_OP_DATA1_DATA + #define IN_FLOW_TBL_OP_DATA1_DATA_OFFSET 0 + #define IN_FLOW_TBL_OP_DATA1_DATA_LEN 32 + #define IN_FLOW_TBL_OP_DATA1_DATA_DEFAULT 0x0 + +struct in_flow_tbl_op_data1 { + a_uint32_t data:32; +}; + +union in_flow_tbl_op_data1_u { + a_uint32_t val; + struct in_flow_tbl_op_data1 bf; +}; + +/*[register] IN_FLOW_TBL_OP_DATA2*/ +#define IN_FLOW_TBL_OP_DATA2 +#define IN_FLOW_TBL_OP_DATA2_ADDRESS 0x3c8 +#define IN_FLOW_TBL_OP_DATA2_NUM 1 +#define IN_FLOW_TBL_OP_DATA2_INC 0x4 +#define IN_FLOW_TBL_OP_DATA2_TYPE REG_TYPE_RW +#define IN_FLOW_TBL_OP_DATA2_DEFAULT 0x0 + /*[field] DATA*/ + #define IN_FLOW_TBL_OP_DATA2_DATA + #define IN_FLOW_TBL_OP_DATA2_DATA_OFFSET 0 + #define IN_FLOW_TBL_OP_DATA2_DATA_LEN 32 + #define IN_FLOW_TBL_OP_DATA2_DATA_DEFAULT 0x0 + +struct in_flow_tbl_op_data2 { + a_uint32_t data:32; +}; + +union in_flow_tbl_op_data2_u { + a_uint32_t val; + struct in_flow_tbl_op_data2 bf; +}; + +/*[register] IN_FLOW_TBL_OP_DATA3*/ +#define IN_FLOW_TBL_OP_DATA3 +#define IN_FLOW_TBL_OP_DATA3_ADDRESS 0x3cc +#define IN_FLOW_TBL_OP_DATA3_NUM 1 +#define IN_FLOW_TBL_OP_DATA3_INC 0x4 +#define IN_FLOW_TBL_OP_DATA3_TYPE REG_TYPE_RW +#define IN_FLOW_TBL_OP_DATA3_DEFAULT 0x0 + /*[field] DATA*/ + #define IN_FLOW_TBL_OP_DATA3_DATA + #define IN_FLOW_TBL_OP_DATA3_DATA_OFFSET 0 + #define IN_FLOW_TBL_OP_DATA3_DATA_LEN 32 + #define IN_FLOW_TBL_OP_DATA3_DATA_DEFAULT 0x0 + +struct in_flow_tbl_op_data3 { + a_uint32_t data:32; +}; + +union in_flow_tbl_op_data3_u { + a_uint32_t val; + struct in_flow_tbl_op_data3 bf; +}; + +/*[register] IN_FLOW_TBL_OP_DATA4*/ +#define IN_FLOW_TBL_OP_DATA4 +#define IN_FLOW_TBL_OP_DATA4_ADDRESS 0x3d0 +#define IN_FLOW_TBL_OP_DATA4_NUM 1 +#define IN_FLOW_TBL_OP_DATA4_INC 0x4 +#define IN_FLOW_TBL_OP_DATA4_TYPE REG_TYPE_RW +#define IN_FLOW_TBL_OP_DATA4_DEFAULT 0x0 + /*[field] DATA*/ + #define IN_FLOW_TBL_OP_DATA4_DATA + #define IN_FLOW_TBL_OP_DATA4_DATA_OFFSET 0 + #define IN_FLOW_TBL_OP_DATA4_DATA_LEN 32 + #define IN_FLOW_TBL_OP_DATA4_DATA_DEFAULT 0x0 + +struct in_flow_tbl_op_data4 { + a_uint32_t data:32; +}; + +union in_flow_tbl_op_data4_u { + a_uint32_t val; + struct in_flow_tbl_op_data4 bf; +}; + +/*[register] IN_FLOW_TBL_OP_DATA5*/ +#define IN_FLOW_TBL_OP_DATA5 +#define IN_FLOW_TBL_OP_DATA5_ADDRESS 0x3d4 +#define IN_FLOW_TBL_OP_DATA5_NUM 1 +#define IN_FLOW_TBL_OP_DATA5_INC 0x4 +#define IN_FLOW_TBL_OP_DATA5_TYPE REG_TYPE_RW +#define IN_FLOW_TBL_OP_DATA5_DEFAULT 0x0 + /*[field] DATA*/ + #define IN_FLOW_TBL_OP_DATA5_DATA + #define IN_FLOW_TBL_OP_DATA5_DATA_OFFSET 0 + #define IN_FLOW_TBL_OP_DATA5_DATA_LEN 32 + #define IN_FLOW_TBL_OP_DATA5_DATA_DEFAULT 0x0 + +struct in_flow_tbl_op_data5 { + a_uint32_t data:32; +}; + +union in_flow_tbl_op_data5_u { + a_uint32_t val; + struct in_flow_tbl_op_data5 bf; +}; + +/*[register] IN_FLOW_TBL_OP_DATA6*/ +#define IN_FLOW_TBL_OP_DATA6 +#define IN_FLOW_TBL_OP_DATA6_ADDRESS 0x3d8 +#define IN_FLOW_TBL_OP_DATA6_NUM 1 +#define IN_FLOW_TBL_OP_DATA6_INC 0x4 +#define IN_FLOW_TBL_OP_DATA6_TYPE REG_TYPE_RW +#define IN_FLOW_TBL_OP_DATA6_DEFAULT 0x0 + /*[field] DATA*/ + #define IN_FLOW_TBL_OP_DATA6_DATA + #define IN_FLOW_TBL_OP_DATA6_DATA_OFFSET 0 + #define IN_FLOW_TBL_OP_DATA6_DATA_LEN 32 + #define IN_FLOW_TBL_OP_DATA6_DATA_DEFAULT 0x0 + +struct in_flow_tbl_op_data6 { + a_uint32_t data:32; +}; + +union in_flow_tbl_op_data6_u { + a_uint32_t val; + struct in_flow_tbl_op_data6 bf; +}; + +/*[register] IN_FLOW_TBL_OP_DATA7*/ +#define IN_FLOW_TBL_OP_DATA7 +#define IN_FLOW_TBL_OP_DATA7_ADDRESS 0x3dc +#define IN_FLOW_TBL_OP_DATA7_NUM 1 +#define IN_FLOW_TBL_OP_DATA7_INC 0x4 +#define IN_FLOW_TBL_OP_DATA7_TYPE REG_TYPE_RW +#define IN_FLOW_TBL_OP_DATA7_DEFAULT 0x0 + /*[field] DATA*/ + #define IN_FLOW_TBL_OP_DATA7_DATA + #define IN_FLOW_TBL_OP_DATA7_DATA_OFFSET 0 + #define IN_FLOW_TBL_OP_DATA7_DATA_LEN 32 + #define IN_FLOW_TBL_OP_DATA7_DATA_DEFAULT 0x0 + +struct in_flow_tbl_op_data7 { + a_uint32_t data:32; +}; + +union in_flow_tbl_op_data7_u { + a_uint32_t val; + struct in_flow_tbl_op_data7 bf; +}; + +/*[register] IN_FLOW_TBL_OP_DATA8*/ +#define IN_FLOW_TBL_OP_DATA8 +#define IN_FLOW_TBL_OP_DATA8_ADDRESS 0x3e0 +#define IN_FLOW_TBL_OP_DATA8_NUM 1 +#define IN_FLOW_TBL_OP_DATA8_INC 0x4 +#define IN_FLOW_TBL_OP_DATA8_TYPE REG_TYPE_RW +#define IN_FLOW_TBL_OP_DATA8_DEFAULT 0x0 + /*[field] DATA*/ + #define IN_FLOW_TBL_OP_DATA8_DATA + #define IN_FLOW_TBL_OP_DATA8_DATA_OFFSET 0 + #define IN_FLOW_TBL_OP_DATA8_DATA_LEN 32 + #define IN_FLOW_TBL_OP_DATA8_DATA_DEFAULT 0x0 + +struct in_flow_tbl_op_data8 { + a_uint32_t data:32; +}; + +union in_flow_tbl_op_data8_u { + a_uint32_t val; + struct in_flow_tbl_op_data8 bf; +}; + +/*[register] FLOW_HOST_TBL_OP_DATA0*/ +#define FLOW_HOST_TBL_OP_DATA0 +#define FLOW_HOST_TBL_OP_DATA0_ADDRESS 0x3e4 +#define FLOW_HOST_TBL_OP_DATA0_NUM 1 +#define FLOW_HOST_TBL_OP_DATA0_INC 0x4 +#define FLOW_HOST_TBL_OP_DATA0_TYPE REG_TYPE_RW +#define FLOW_HOST_TBL_OP_DATA0_DEFAULT 0x0 + /*[field] DATA*/ + #define FLOW_HOST_TBL_OP_DATA0_DATA + #define FLOW_HOST_TBL_OP_DATA0_DATA_OFFSET 0 + #define FLOW_HOST_TBL_OP_DATA0_DATA_LEN 32 + #define FLOW_HOST_TBL_OP_DATA0_DATA_DEFAULT 0x0 + +struct flow_host_tbl_op_data0 { + a_uint32_t data:32; +}; + +union flow_host_tbl_op_data0_u { + a_uint32_t val; + struct flow_host_tbl_op_data0 bf; +}; + +/*[register] FLOW_HOST_TBL_OP_DATA1*/ +#define FLOW_HOST_TBL_OP_DATA1 +#define FLOW_HOST_TBL_OP_DATA1_ADDRESS 0x3e8 +#define FLOW_HOST_TBL_OP_DATA1_NUM 1 +#define FLOW_HOST_TBL_OP_DATA1_INC 0x4 +#define FLOW_HOST_TBL_OP_DATA1_TYPE REG_TYPE_RW +#define FLOW_HOST_TBL_OP_DATA1_DEFAULT 0x0 + /*[field] DATA*/ + #define FLOW_HOST_TBL_OP_DATA1_DATA + #define FLOW_HOST_TBL_OP_DATA1_DATA_OFFSET 0 + #define FLOW_HOST_TBL_OP_DATA1_DATA_LEN 32 + #define FLOW_HOST_TBL_OP_DATA1_DATA_DEFAULT 0x0 + +struct flow_host_tbl_op_data1 { + a_uint32_t data:32; +}; + +union flow_host_tbl_op_data1_u { + a_uint32_t val; + struct flow_host_tbl_op_data1 bf; +}; + +/*[register] FLOW_HOST_TBL_OP_DATA2*/ +#define FLOW_HOST_TBL_OP_DATA2 +#define FLOW_HOST_TBL_OP_DATA2_ADDRESS 0x3ec +#define FLOW_HOST_TBL_OP_DATA2_NUM 1 +#define FLOW_HOST_TBL_OP_DATA2_INC 0x4 +#define FLOW_HOST_TBL_OP_DATA2_TYPE REG_TYPE_RW +#define FLOW_HOST_TBL_OP_DATA2_DEFAULT 0x0 + /*[field] DATA*/ + #define FLOW_HOST_TBL_OP_DATA2_DATA + #define FLOW_HOST_TBL_OP_DATA2_DATA_OFFSET 0 + #define FLOW_HOST_TBL_OP_DATA2_DATA_LEN 32 + #define FLOW_HOST_TBL_OP_DATA2_DATA_DEFAULT 0x0 + +struct flow_host_tbl_op_data2 { + a_uint32_t data:32; +}; + +union flow_host_tbl_op_data2_u { + a_uint32_t val; + struct flow_host_tbl_op_data2 bf; +}; + +/*[register] FLOW_HOST_TBL_OP_DATA3*/ +#define FLOW_HOST_TBL_OP_DATA3 +#define FLOW_HOST_TBL_OP_DATA3_ADDRESS 0x3f0 +#define FLOW_HOST_TBL_OP_DATA3_NUM 1 +#define FLOW_HOST_TBL_OP_DATA3_INC 0x4 +#define FLOW_HOST_TBL_OP_DATA3_TYPE REG_TYPE_RW +#define FLOW_HOST_TBL_OP_DATA3_DEFAULT 0x0 + /*[field] DATA*/ + #define FLOW_HOST_TBL_OP_DATA3_DATA + #define FLOW_HOST_TBL_OP_DATA3_DATA_OFFSET 0 + #define FLOW_HOST_TBL_OP_DATA3_DATA_LEN 32 + #define FLOW_HOST_TBL_OP_DATA3_DATA_DEFAULT 0x0 + +struct flow_host_tbl_op_data3 { + a_uint32_t data:32; +}; + +union flow_host_tbl_op_data3_u { + a_uint32_t val; + struct flow_host_tbl_op_data3 bf; +}; + +/*[register] FLOW_HOST_TBL_OP_DATA4*/ +#define FLOW_HOST_TBL_OP_DATA4 +#define FLOW_HOST_TBL_OP_DATA4_ADDRESS 0x3f4 +#define FLOW_HOST_TBL_OP_DATA4_NUM 1 +#define FLOW_HOST_TBL_OP_DATA4_INC 0x4 +#define FLOW_HOST_TBL_OP_DATA4_TYPE REG_TYPE_RW +#define FLOW_HOST_TBL_OP_DATA4_DEFAULT 0x0 + /*[field] DATA*/ + #define FLOW_HOST_TBL_OP_DATA4_DATA + #define FLOW_HOST_TBL_OP_DATA4_DATA_OFFSET 0 + #define FLOW_HOST_TBL_OP_DATA4_DATA_LEN 32 + #define FLOW_HOST_TBL_OP_DATA4_DATA_DEFAULT 0x0 + +struct flow_host_tbl_op_data4 { + a_uint32_t data:32; +}; + +union flow_host_tbl_op_data4_u { + a_uint32_t val; + struct flow_host_tbl_op_data4 bf; +}; + +/*[register] FLOW_HOST_TBL_OP_DATA5*/ +#define FLOW_HOST_TBL_OP_DATA5 +#define FLOW_HOST_TBL_OP_DATA5_ADDRESS 0x3f8 +#define FLOW_HOST_TBL_OP_DATA5_NUM 1 +#define FLOW_HOST_TBL_OP_DATA5_INC 0x4 +#define FLOW_HOST_TBL_OP_DATA5_TYPE REG_TYPE_RW +#define FLOW_HOST_TBL_OP_DATA5_DEFAULT 0x0 + /*[field] DATA*/ + #define FLOW_HOST_TBL_OP_DATA5_DATA + #define FLOW_HOST_TBL_OP_DATA5_DATA_OFFSET 0 + #define FLOW_HOST_TBL_OP_DATA5_DATA_LEN 32 + #define FLOW_HOST_TBL_OP_DATA5_DATA_DEFAULT 0x0 + +struct flow_host_tbl_op_data5 { + a_uint32_t data:32; +}; + +union flow_host_tbl_op_data5_u { + a_uint32_t val; + struct flow_host_tbl_op_data5 bf; +}; + +/*[register] FLOW_HOST_TBL_OP_DATA6*/ +#define FLOW_HOST_TBL_OP_DATA6 +#define FLOW_HOST_TBL_OP_DATA6_ADDRESS 0x3fc +#define FLOW_HOST_TBL_OP_DATA6_NUM 1 +#define FLOW_HOST_TBL_OP_DATA6_INC 0x4 +#define FLOW_HOST_TBL_OP_DATA6_TYPE REG_TYPE_RW +#define FLOW_HOST_TBL_OP_DATA6_DEFAULT 0x0 + /*[field] DATA*/ + #define FLOW_HOST_TBL_OP_DATA6_DATA + #define FLOW_HOST_TBL_OP_DATA6_DATA_OFFSET 0 + #define FLOW_HOST_TBL_OP_DATA6_DATA_LEN 32 + #define FLOW_HOST_TBL_OP_DATA6_DATA_DEFAULT 0x0 + +struct flow_host_tbl_op_data6 { + a_uint32_t data:32; +}; + +union flow_host_tbl_op_data6_u { + a_uint32_t val; + struct flow_host_tbl_op_data6 bf; +}; + +/*[register] FLOW_HOST_TBL_OP_DATA7*/ +#define FLOW_HOST_TBL_OP_DATA7 +#define FLOW_HOST_TBL_OP_DATA7_ADDRESS 0x400 +#define FLOW_HOST_TBL_OP_DATA7_NUM 1 +#define FLOW_HOST_TBL_OP_DATA7_INC 0x4 +#define FLOW_HOST_TBL_OP_DATA7_TYPE REG_TYPE_RW +#define FLOW_HOST_TBL_OP_DATA7_DEFAULT 0x0 + /*[field] DATA*/ + #define FLOW_HOST_TBL_OP_DATA7_DATA + #define FLOW_HOST_TBL_OP_DATA7_DATA_OFFSET 0 + #define FLOW_HOST_TBL_OP_DATA7_DATA_LEN 32 + #define FLOW_HOST_TBL_OP_DATA7_DATA_DEFAULT 0x0 + +struct flow_host_tbl_op_data7 { + a_uint32_t data:32; +}; + +union flow_host_tbl_op_data7_u { + a_uint32_t val; + struct flow_host_tbl_op_data7 bf; +}; + +/*[register] FLOW_HOST_TBL_OP_DATA8*/ +#define FLOW_HOST_TBL_OP_DATA8 +#define FLOW_HOST_TBL_OP_DATA8_ADDRESS 0x404 +#define FLOW_HOST_TBL_OP_DATA8_NUM 1 +#define FLOW_HOST_TBL_OP_DATA8_INC 0x4 +#define FLOW_HOST_TBL_OP_DATA8_TYPE REG_TYPE_RW +#define FLOW_HOST_TBL_OP_DATA8_DEFAULT 0x0 + /*[field] DATA*/ + #define FLOW_HOST_TBL_OP_DATA8_DATA + #define FLOW_HOST_TBL_OP_DATA8_DATA_OFFSET 0 + #define FLOW_HOST_TBL_OP_DATA8_DATA_LEN 32 + #define FLOW_HOST_TBL_OP_DATA8_DATA_DEFAULT 0x0 + +struct flow_host_tbl_op_data8 { + a_uint32_t data:32; +}; + +union flow_host_tbl_op_data8_u { + a_uint32_t val; + struct flow_host_tbl_op_data8 bf; +}; + +/*[register] FLOW_HOST_TBL_OP_DATA9*/ +#define FLOW_HOST_TBL_OP_DATA9 +#define FLOW_HOST_TBL_OP_DATA9_ADDRESS 0x408 +#define FLOW_HOST_TBL_OP_DATA9_NUM 1 +#define FLOW_HOST_TBL_OP_DATA9_INC 0x4 +#define FLOW_HOST_TBL_OP_DATA9_TYPE REG_TYPE_RW +#define FLOW_HOST_TBL_OP_DATA9_DEFAULT 0x0 + /*[field] DATA*/ + #define FLOW_HOST_TBL_OP_DATA9_DATA + #define FLOW_HOST_TBL_OP_DATA9_DATA_OFFSET 0 + #define FLOW_HOST_TBL_OP_DATA9_DATA_LEN 32 + #define FLOW_HOST_TBL_OP_DATA9_DATA_DEFAULT 0x0 + +struct flow_host_tbl_op_data9 { + a_uint32_t data:32; +}; + +union flow_host_tbl_op_data9_u { + a_uint32_t val; + struct flow_host_tbl_op_data9 bf; +}; + +/*[register] IN_FLOW_TBL_OP_RSLT*/ +#define IN_FLOW_TBL_OP_RSLT +#define IN_FLOW_TBL_OP_RSLT_ADDRESS 0x40c +#define IN_FLOW_TBL_OP_RSLT_NUM 1 +#define IN_FLOW_TBL_OP_RSLT_INC 0x4 +#define IN_FLOW_TBL_OP_RSLT_TYPE REG_TYPE_RO +#define IN_FLOW_TBL_OP_RSLT_DEFAULT 0x0 + /*[field] CMD_ID*/ + #define IN_FLOW_TBL_OP_RSLT_CMD_ID + #define IN_FLOW_TBL_OP_RSLT_CMD_ID_OFFSET 0 + #define IN_FLOW_TBL_OP_RSLT_CMD_ID_LEN 4 + #define IN_FLOW_TBL_OP_RSLT_CMD_ID_DEFAULT 0x0 + /*[field] OP_RSLT*/ + #define IN_FLOW_TBL_OP_RSLT_OP_RSLT + #define IN_FLOW_TBL_OP_RSLT_OP_RSLT_OFFSET 4 + #define IN_FLOW_TBL_OP_RSLT_OP_RSLT_LEN 1 + #define IN_FLOW_TBL_OP_RSLT_OP_RSLT_DEFAULT 0x0 + /*[field] FLOW_ENTRY_INDEX*/ + #define IN_FLOW_TBL_OP_RSLT_FLOW_ENTRY_INDEX + #define IN_FLOW_TBL_OP_RSLT_FLOW_ENTRY_INDEX_OFFSET 5 + #define IN_FLOW_TBL_OP_RSLT_FLOW_ENTRY_INDEX_LEN 12 + #define IN_FLOW_TBL_OP_RSLT_FLOW_ENTRY_INDEX_DEFAULT 0x0 + /*[field] VALID_CNT*/ + #define IN_FLOW_TBL_OP_RSLT_VALID_CNT + #define IN_FLOW_TBL_OP_RSLT_VALID_CNT_OFFSET 17 + #define IN_FLOW_TBL_OP_RSLT_VALID_CNT_LEN 4 + #define IN_FLOW_TBL_OP_RSLT_VALID_CNT_DEFAULT 0x0 + +struct in_flow_tbl_op_rslt { + a_uint32_t cmd_id:4; + a_uint32_t op_rslt:1; + a_uint32_t flow_entry_index:12; + a_uint32_t valid_cnt:4; + a_uint32_t _reserved0:11; +}; + +union in_flow_tbl_op_rslt_u { + a_uint32_t val; + struct in_flow_tbl_op_rslt bf; +}; + +/*[register] FLOW_HOST_TBL_OP_RSLT*/ +#define FLOW_HOST_TBL_OP_RSLT +#define FLOW_HOST_TBL_OP_RSLT_ADDRESS 0x410 +#define FLOW_HOST_TBL_OP_RSLT_NUM 1 +#define FLOW_HOST_TBL_OP_RSLT_INC 0x4 +#define FLOW_HOST_TBL_OP_RSLT_TYPE REG_TYPE_RO +#define FLOW_HOST_TBL_OP_RSLT_DEFAULT 0x0 + /*[field] HOST_ENTRY_INDEX*/ + #define FLOW_HOST_TBL_OP_RSLT_HOST_ENTRY_INDEX + #define FLOW_HOST_TBL_OP_RSLT_HOST_ENTRY_INDEX_OFFSET 0 + #define FLOW_HOST_TBL_OP_RSLT_HOST_ENTRY_INDEX_LEN 13 + #define FLOW_HOST_TBL_OP_RSLT_HOST_ENTRY_INDEX_DEFAULT 0x0 + +struct flow_host_tbl_op_rslt { + a_uint32_t host_entry_index:13; + a_uint32_t _reserved0:19; +}; + +union flow_host_tbl_op_rslt_u { + a_uint32_t val; + struct flow_host_tbl_op_rslt bf; +}; + +/*[register] IN_FLOW_TBL_RD_OP*/ +#define IN_FLOW_TBL_RD_OP +#define IN_FLOW_TBL_RD_OP_ADDRESS 0x414 +#define IN_FLOW_TBL_RD_OP_NUM 1 +#define IN_FLOW_TBL_RD_OP_INC 0x4 +#define IN_FLOW_TBL_RD_OP_TYPE REG_TYPE_RW +#define IN_FLOW_TBL_RD_OP_DEFAULT 0x0 + /*[field] CMD_ID*/ + #define IN_FLOW_TBL_RD_OP_CMD_ID + #define IN_FLOW_TBL_RD_OP_CMD_ID_OFFSET 0 + #define IN_FLOW_TBL_RD_OP_CMD_ID_LEN 4 + #define IN_FLOW_TBL_RD_OP_CMD_ID_DEFAULT 0x0 + /*[field] BYP_RSLT_EN*/ + #define IN_FLOW_TBL_RD_OP_BYP_RSLT_EN + #define IN_FLOW_TBL_RD_OP_BYP_RSLT_EN_OFFSET 4 + #define IN_FLOW_TBL_RD_OP_BYP_RSLT_EN_LEN 1 + #define IN_FLOW_TBL_RD_OP_BYP_RSLT_EN_DEFAULT 0x0 + /*[field] OP_TYPE*/ + #define IN_FLOW_TBL_RD_OP_OP_TYPE + #define IN_FLOW_TBL_RD_OP_OP_TYPE_OFFSET 5 + #define IN_FLOW_TBL_RD_OP_OP_TYPE_LEN 3 + #define IN_FLOW_TBL_RD_OP_OP_TYPE_DEFAULT 0x0 + /*[field] HASH_BLOCK_BITMAP*/ + #define IN_FLOW_TBL_RD_OP_HASH_BLOCK_BITMAP + #define IN_FLOW_TBL_RD_OP_HASH_BLOCK_BITMAP_OFFSET 8 + #define IN_FLOW_TBL_RD_OP_HASH_BLOCK_BITMAP_LEN 2 + #define IN_FLOW_TBL_RD_OP_HASH_BLOCK_BITMAP_DEFAULT 0x0 + /*[field] OP_MODE*/ + #define IN_FLOW_TBL_RD_OP_OP_MODE + #define IN_FLOW_TBL_RD_OP_OP_MODE_OFFSET 10 + #define IN_FLOW_TBL_RD_OP_OP_MODE_LEN 1 + #define IN_FLOW_TBL_RD_OP_OP_MODE_DEFAULT 0x0 + /*[field] OP_HOST_EN*/ + #define IN_FLOW_TBL_RD_OP_OP_HOST_EN + #define IN_FLOW_TBL_RD_OP_OP_HOST_EN_OFFSET 11 + #define IN_FLOW_TBL_RD_OP_OP_HOST_EN_LEN 1 + #define IN_FLOW_TBL_RD_OP_OP_HOST_EN_DEFAULT 0x0 + /*[field] ENTRY_INDEX*/ + #define IN_FLOW_TBL_RD_OP_ENTRY_INDEX + #define IN_FLOW_TBL_RD_OP_ENTRY_INDEX_OFFSET 12 + #define IN_FLOW_TBL_RD_OP_ENTRY_INDEX_LEN 12 + #define IN_FLOW_TBL_RD_OP_ENTRY_INDEX_DEFAULT 0x0 + /*[field] OP_RESULT*/ + #define IN_FLOW_TBL_RD_OP_OP_RESULT + #define IN_FLOW_TBL_RD_OP_OP_RESULT_OFFSET 24 + #define IN_FLOW_TBL_RD_OP_OP_RESULT_LEN 1 + #define IN_FLOW_TBL_RD_OP_OP_RESULT_DEFAULT 0x0 + /*[field] BUSY*/ + #define IN_FLOW_TBL_RD_OP_BUSY + #define IN_FLOW_TBL_RD_OP_BUSY_OFFSET 25 + #define IN_FLOW_TBL_RD_OP_BUSY_LEN 1 + #define IN_FLOW_TBL_RD_OP_BUSY_DEFAULT 0x0 + +struct in_flow_tbl_rd_op { + a_uint32_t cmd_id:4; + a_uint32_t byp_rslt_en:1; + a_uint32_t op_type:3; + a_uint32_t hash_block_bitmap:2; + a_uint32_t op_mode:1; + a_uint32_t op_host_en:1; + a_uint32_t entry_index:12; + a_uint32_t op_result:1; + a_uint32_t busy:1; + a_uint32_t _reserved0:6; +}; + +union in_flow_tbl_rd_op_u { + a_uint32_t val; + struct in_flow_tbl_rd_op bf; +}; + +/*[register] IN_FLOW_HOST_TBL_RD_OP*/ +#define IN_FLOW_HOST_TBL_RD_OP +#define IN_FLOW_HOST_TBL_RD_OP_ADDRESS 0x418 +#define IN_FLOW_HOST_TBL_RD_OP_NUM 1 +#define IN_FLOW_HOST_TBL_RD_OP_INC 0x4 +#define IN_FLOW_HOST_TBL_RD_OP_TYPE REG_TYPE_RW +#define IN_FLOW_HOST_TBL_RD_OP_DEFAULT 0x0 + /*[field] HASH_BLOCK_BITMAP*/ + #define IN_FLOW_HOST_TBL_RD_OP_HASH_BLOCK_BITMAP + #define IN_FLOW_HOST_TBL_RD_OP_HASH_BLOCK_BITMAP_OFFSET 0 + #define IN_FLOW_HOST_TBL_RD_OP_HASH_BLOCK_BITMAP_LEN 2 + #define IN_FLOW_HOST_TBL_RD_OP_HASH_BLOCK_BITMAP_DEFAULT 0x0 + /*[field] HOST_ENTRY_INDEX*/ + #define IN_FLOW_HOST_TBL_RD_OP_HOST_ENTRY_INDEX + #define IN_FLOW_HOST_TBL_RD_OP_HOST_ENTRY_INDEX_OFFSET 2 + #define IN_FLOW_HOST_TBL_RD_OP_HOST_ENTRY_INDEX_LEN 13 + #define IN_FLOW_HOST_TBL_RD_OP_HOST_ENTRY_INDEX_DEFAULT 0x0 + +struct in_flow_host_tbl_rd_op { + a_uint32_t hash_block_bitmap:2; + a_uint32_t host_entry_index:13; + a_uint32_t _reserved0:17; +}; + +union in_flow_host_tbl_rd_op_u { + a_uint32_t val; + struct in_flow_host_tbl_rd_op bf; +}; + +/*[register] IN_FLOW_TBL_RD_OP_DATA0*/ +#define IN_FLOW_TBL_RD_OP_DATA0 +#define IN_FLOW_TBL_RD_OP_DATA0_ADDRESS 0x41c +#define IN_FLOW_TBL_RD_OP_DATA0_NUM 1 +#define IN_FLOW_TBL_RD_OP_DATA0_INC 0x4 +#define IN_FLOW_TBL_RD_OP_DATA0_TYPE REG_TYPE_RW +#define IN_FLOW_TBL_RD_OP_DATA0_DEFAULT 0x0 + /*[field] DATA*/ + #define IN_FLOW_TBL_RD_OP_DATA0_DATA + #define IN_FLOW_TBL_RD_OP_DATA0_DATA_OFFSET 0 + #define IN_FLOW_TBL_RD_OP_DATA0_DATA_LEN 32 + #define IN_FLOW_TBL_RD_OP_DATA0_DATA_DEFAULT 0x0 + +struct in_flow_tbl_rd_op_data0 { + a_uint32_t data:32; +}; + +union in_flow_tbl_rd_op_data0_u { + a_uint32_t val; + struct in_flow_tbl_rd_op_data0 bf; +}; + +/*[register] IN_FLOW_TBL_RD_OP_DATA1*/ +#define IN_FLOW_TBL_RD_OP_DATA1 +#define IN_FLOW_TBL_RD_OP_DATA1_ADDRESS 0x420 +#define IN_FLOW_TBL_RD_OP_DATA1_NUM 1 +#define IN_FLOW_TBL_RD_OP_DATA1_INC 0x4 +#define IN_FLOW_TBL_RD_OP_DATA1_TYPE REG_TYPE_RW +#define IN_FLOW_TBL_RD_OP_DATA1_DEFAULT 0x0 + /*[field] DATA*/ + #define IN_FLOW_TBL_RD_OP_DATA1_DATA + #define IN_FLOW_TBL_RD_OP_DATA1_DATA_OFFSET 0 + #define IN_FLOW_TBL_RD_OP_DATA1_DATA_LEN 32 + #define IN_FLOW_TBL_RD_OP_DATA1_DATA_DEFAULT 0x0 + +struct in_flow_tbl_rd_op_data1 { + a_uint32_t data:32; +}; + +union in_flow_tbl_rd_op_data1_u { + a_uint32_t val; + struct in_flow_tbl_rd_op_data1 bf; +}; + +/*[register] IN_FLOW_TBL_RD_OP_DATA2*/ +#define IN_FLOW_TBL_RD_OP_DATA2 +#define IN_FLOW_TBL_RD_OP_DATA2_ADDRESS 0x424 +#define IN_FLOW_TBL_RD_OP_DATA2_NUM 1 +#define IN_FLOW_TBL_RD_OP_DATA2_INC 0x4 +#define IN_FLOW_TBL_RD_OP_DATA2_TYPE REG_TYPE_RW +#define IN_FLOW_TBL_RD_OP_DATA2_DEFAULT 0x0 + /*[field] DATA*/ + #define IN_FLOW_TBL_RD_OP_DATA2_DATA + #define IN_FLOW_TBL_RD_OP_DATA2_DATA_OFFSET 0 + #define IN_FLOW_TBL_RD_OP_DATA2_DATA_LEN 32 + #define IN_FLOW_TBL_RD_OP_DATA2_DATA_DEFAULT 0x0 + +struct in_flow_tbl_rd_op_data2 { + a_uint32_t data:32; +}; + +union in_flow_tbl_rd_op_data2_u { + a_uint32_t val; + struct in_flow_tbl_rd_op_data2 bf; +}; + +/*[register] IN_FLOW_TBL_RD_OP_DATA3*/ +#define IN_FLOW_TBL_RD_OP_DATA3 +#define IN_FLOW_TBL_RD_OP_DATA3_ADDRESS 0x428 +#define IN_FLOW_TBL_RD_OP_DATA3_NUM 1 +#define IN_FLOW_TBL_RD_OP_DATA3_INC 0x4 +#define IN_FLOW_TBL_RD_OP_DATA3_TYPE REG_TYPE_RW +#define IN_FLOW_TBL_RD_OP_DATA3_DEFAULT 0x0 + /*[field] DATA*/ + #define IN_FLOW_TBL_RD_OP_DATA3_DATA + #define IN_FLOW_TBL_RD_OP_DATA3_DATA_OFFSET 0 + #define IN_FLOW_TBL_RD_OP_DATA3_DATA_LEN 32 + #define IN_FLOW_TBL_RD_OP_DATA3_DATA_DEFAULT 0x0 + +struct in_flow_tbl_rd_op_data3 { + a_uint32_t data:32; +}; + +union in_flow_tbl_rd_op_data3_u { + a_uint32_t val; + struct in_flow_tbl_rd_op_data3 bf; +}; + +/*[register] IN_FLOW_TBL_RD_OP_DATA4*/ +#define IN_FLOW_TBL_RD_OP_DATA4 +#define IN_FLOW_TBL_RD_OP_DATA4_ADDRESS 0x42c +#define IN_FLOW_TBL_RD_OP_DATA4_NUM 1 +#define IN_FLOW_TBL_RD_OP_DATA4_INC 0x4 +#define IN_FLOW_TBL_RD_OP_DATA4_TYPE REG_TYPE_RW +#define IN_FLOW_TBL_RD_OP_DATA4_DEFAULT 0x0 + /*[field] DATA*/ + #define IN_FLOW_TBL_RD_OP_DATA4_DATA + #define IN_FLOW_TBL_RD_OP_DATA4_DATA_OFFSET 0 + #define IN_FLOW_TBL_RD_OP_DATA4_DATA_LEN 32 + #define IN_FLOW_TBL_RD_OP_DATA4_DATA_DEFAULT 0x0 + +struct in_flow_tbl_rd_op_data4 { + a_uint32_t data:32; +}; + +union in_flow_tbl_rd_op_data4_u { + a_uint32_t val; + struct in_flow_tbl_rd_op_data4 bf; +}; + +/*[register] IN_FLOW_TBL_RD_OP_DATA5*/ +#define IN_FLOW_TBL_RD_OP_DATA5 +#define IN_FLOW_TBL_RD_OP_DATA5_ADDRESS 0x430 +#define IN_FLOW_TBL_RD_OP_DATA5_NUM 1 +#define IN_FLOW_TBL_RD_OP_DATA5_INC 0x4 +#define IN_FLOW_TBL_RD_OP_DATA5_TYPE REG_TYPE_RW +#define IN_FLOW_TBL_RD_OP_DATA5_DEFAULT 0x0 + /*[field] DATA*/ + #define IN_FLOW_TBL_RD_OP_DATA5_DATA + #define IN_FLOW_TBL_RD_OP_DATA5_DATA_OFFSET 0 + #define IN_FLOW_TBL_RD_OP_DATA5_DATA_LEN 32 + #define IN_FLOW_TBL_RD_OP_DATA5_DATA_DEFAULT 0x0 + +struct in_flow_tbl_rd_op_data5 { + a_uint32_t data:32; +}; + +union in_flow_tbl_rd_op_data5_u { + a_uint32_t val; + struct in_flow_tbl_rd_op_data5 bf; +}; + +/*[register] IN_FLOW_TBL_RD_OP_DATA6*/ +#define IN_FLOW_TBL_RD_OP_DATA6 +#define IN_FLOW_TBL_RD_OP_DATA6_ADDRESS 0x434 +#define IN_FLOW_TBL_RD_OP_DATA6_NUM 1 +#define IN_FLOW_TBL_RD_OP_DATA6_INC 0x4 +#define IN_FLOW_TBL_RD_OP_DATA6_TYPE REG_TYPE_RW +#define IN_FLOW_TBL_RD_OP_DATA6_DEFAULT 0x0 + /*[field] DATA*/ + #define IN_FLOW_TBL_RD_OP_DATA6_DATA + #define IN_FLOW_TBL_RD_OP_DATA6_DATA_OFFSET 0 + #define IN_FLOW_TBL_RD_OP_DATA6_DATA_LEN 32 + #define IN_FLOW_TBL_RD_OP_DATA6_DATA_DEFAULT 0x0 + +struct in_flow_tbl_rd_op_data6 { + a_uint32_t data:32; +}; + +union in_flow_tbl_rd_op_data6_u { + a_uint32_t val; + struct in_flow_tbl_rd_op_data6 bf; +}; + +/*[register] IN_FLOW_TBL_RD_OP_DATA7*/ +#define IN_FLOW_TBL_RD_OP_DATA7 +#define IN_FLOW_TBL_RD_OP_DATA7_ADDRESS 0x438 +#define IN_FLOW_TBL_RD_OP_DATA7_NUM 1 +#define IN_FLOW_TBL_RD_OP_DATA7_INC 0x4 +#define IN_FLOW_TBL_RD_OP_DATA7_TYPE REG_TYPE_RW +#define IN_FLOW_TBL_RD_OP_DATA7_DEFAULT 0x0 + /*[field] DATA*/ + #define IN_FLOW_TBL_RD_OP_DATA7_DATA + #define IN_FLOW_TBL_RD_OP_DATA7_DATA_OFFSET 0 + #define IN_FLOW_TBL_RD_OP_DATA7_DATA_LEN 32 + #define IN_FLOW_TBL_RD_OP_DATA7_DATA_DEFAULT 0x0 + +struct in_flow_tbl_rd_op_data7 { + a_uint32_t data:32; +}; + +union in_flow_tbl_rd_op_data7_u { + a_uint32_t val; + struct in_flow_tbl_rd_op_data7 bf; +}; + +/*[register] IN_FLOW_TBL_RD_OP_DATA8*/ +#define IN_FLOW_TBL_RD_OP_DATA8 +#define IN_FLOW_TBL_RD_OP_DATA8_ADDRESS 0x43c +#define IN_FLOW_TBL_RD_OP_DATA8_NUM 1 +#define IN_FLOW_TBL_RD_OP_DATA8_INC 0x4 +#define IN_FLOW_TBL_RD_OP_DATA8_TYPE REG_TYPE_RW +#define IN_FLOW_TBL_RD_OP_DATA8_DEFAULT 0x0 + /*[field] DATA*/ + #define IN_FLOW_TBL_RD_OP_DATA8_DATA + #define IN_FLOW_TBL_RD_OP_DATA8_DATA_OFFSET 0 + #define IN_FLOW_TBL_RD_OP_DATA8_DATA_LEN 32 + #define IN_FLOW_TBL_RD_OP_DATA8_DATA_DEFAULT 0x0 + +struct in_flow_tbl_rd_op_data8 { + a_uint32_t data:32; +}; + +union in_flow_tbl_rd_op_data8_u { + a_uint32_t val; + struct in_flow_tbl_rd_op_data8 bf; +}; + +/*[register] FLOW_HOST_TBL_RD_OP_DATA0*/ +#define FLOW_HOST_TBL_RD_OP_DATA0 +#define FLOW_HOST_TBL_RD_OP_DATA0_ADDRESS 0x440 +#define FLOW_HOST_TBL_RD_OP_DATA0_NUM 1 +#define FLOW_HOST_TBL_RD_OP_DATA0_INC 0x4 +#define FLOW_HOST_TBL_RD_OP_DATA0_TYPE REG_TYPE_RW +#define FLOW_HOST_TBL_RD_OP_DATA0_DEFAULT 0x0 + /*[field] DATA*/ + #define FLOW_HOST_TBL_RD_OP_DATA0_DATA + #define FLOW_HOST_TBL_RD_OP_DATA0_DATA_OFFSET 0 + #define FLOW_HOST_TBL_RD_OP_DATA0_DATA_LEN 32 + #define FLOW_HOST_TBL_RD_OP_DATA0_DATA_DEFAULT 0x0 + +struct flow_host_tbl_rd_op_data0 { + a_uint32_t data:32; +}; + +union flow_host_tbl_rd_op_data0_u { + a_uint32_t val; + struct flow_host_tbl_rd_op_data0 bf; +}; + +/*[register] FLOW_HOST_TBL_RD_OP_DATA1*/ +#define FLOW_HOST_TBL_RD_OP_DATA1 +#define FLOW_HOST_TBL_RD_OP_DATA1_ADDRESS 0x444 +#define FLOW_HOST_TBL_RD_OP_DATA1_NUM 1 +#define FLOW_HOST_TBL_RD_OP_DATA1_INC 0x4 +#define FLOW_HOST_TBL_RD_OP_DATA1_TYPE REG_TYPE_RW +#define FLOW_HOST_TBL_RD_OP_DATA1_DEFAULT 0x0 + /*[field] DATA*/ + #define FLOW_HOST_TBL_RD_OP_DATA1_DATA + #define FLOW_HOST_TBL_RD_OP_DATA1_DATA_OFFSET 0 + #define FLOW_HOST_TBL_RD_OP_DATA1_DATA_LEN 32 + #define FLOW_HOST_TBL_RD_OP_DATA1_DATA_DEFAULT 0x0 + +struct flow_host_tbl_rd_op_data1 { + a_uint32_t data:32; +}; + +union flow_host_tbl_rd_op_data1_u { + a_uint32_t val; + struct flow_host_tbl_rd_op_data1 bf; +}; + +/*[register] FLOW_HOST_TBL_RD_OP_DATA2*/ +#define FLOW_HOST_TBL_RD_OP_DATA2 +#define FLOW_HOST_TBL_RD_OP_DATA2_ADDRESS 0x448 +#define FLOW_HOST_TBL_RD_OP_DATA2_NUM 1 +#define FLOW_HOST_TBL_RD_OP_DATA2_INC 0x4 +#define FLOW_HOST_TBL_RD_OP_DATA2_TYPE REG_TYPE_RW +#define FLOW_HOST_TBL_RD_OP_DATA2_DEFAULT 0x0 + /*[field] DATA*/ + #define FLOW_HOST_TBL_RD_OP_DATA2_DATA + #define FLOW_HOST_TBL_RD_OP_DATA2_DATA_OFFSET 0 + #define FLOW_HOST_TBL_RD_OP_DATA2_DATA_LEN 32 + #define FLOW_HOST_TBL_RD_OP_DATA2_DATA_DEFAULT 0x0 + +struct flow_host_tbl_rd_op_data2 { + a_uint32_t data:32; +}; + +union flow_host_tbl_rd_op_data2_u { + a_uint32_t val; + struct flow_host_tbl_rd_op_data2 bf; +}; + +/*[register] FLOW_HOST_TBL_RD_OP_DATA3*/ +#define FLOW_HOST_TBL_RD_OP_DATA3 +#define FLOW_HOST_TBL_RD_OP_DATA3_ADDRESS 0x44c +#define FLOW_HOST_TBL_RD_OP_DATA3_NUM 1 +#define FLOW_HOST_TBL_RD_OP_DATA3_INC 0x4 +#define FLOW_HOST_TBL_RD_OP_DATA3_TYPE REG_TYPE_RW +#define FLOW_HOST_TBL_RD_OP_DATA3_DEFAULT 0x0 + /*[field] DATA*/ + #define FLOW_HOST_TBL_RD_OP_DATA3_DATA + #define FLOW_HOST_TBL_RD_OP_DATA3_DATA_OFFSET 0 + #define FLOW_HOST_TBL_RD_OP_DATA3_DATA_LEN 32 + #define FLOW_HOST_TBL_RD_OP_DATA3_DATA_DEFAULT 0x0 + +struct flow_host_tbl_rd_op_data3 { + a_uint32_t data:32; +}; + +union flow_host_tbl_rd_op_data3_u { + a_uint32_t val; + struct flow_host_tbl_rd_op_data3 bf; +}; + +/*[register] FLOW_HOST_TBL_RD_OP_DATA4*/ +#define FLOW_HOST_TBL_RD_OP_DATA4 +#define FLOW_HOST_TBL_RD_OP_DATA4_ADDRESS 0x450 +#define FLOW_HOST_TBL_RD_OP_DATA4_NUM 1 +#define FLOW_HOST_TBL_RD_OP_DATA4_INC 0x4 +#define FLOW_HOST_TBL_RD_OP_DATA4_TYPE REG_TYPE_RW +#define FLOW_HOST_TBL_RD_OP_DATA4_DEFAULT 0x0 + /*[field] DATA*/ + #define FLOW_HOST_TBL_RD_OP_DATA4_DATA + #define FLOW_HOST_TBL_RD_OP_DATA4_DATA_OFFSET 0 + #define FLOW_HOST_TBL_RD_OP_DATA4_DATA_LEN 32 + #define FLOW_HOST_TBL_RD_OP_DATA4_DATA_DEFAULT 0x0 + +struct flow_host_tbl_rd_op_data4 { + a_uint32_t data:32; +}; + +union flow_host_tbl_rd_op_data4_u { + a_uint32_t val; + struct flow_host_tbl_rd_op_data4 bf; +}; + +/*[register] FLOW_HOST_TBL_RD_OP_DATA5*/ +#define FLOW_HOST_TBL_RD_OP_DATA5 +#define FLOW_HOST_TBL_RD_OP_DATA5_ADDRESS 0x454 +#define FLOW_HOST_TBL_RD_OP_DATA5_NUM 1 +#define FLOW_HOST_TBL_RD_OP_DATA5_INC 0x4 +#define FLOW_HOST_TBL_RD_OP_DATA5_TYPE REG_TYPE_RW +#define FLOW_HOST_TBL_RD_OP_DATA5_DEFAULT 0x0 + /*[field] DATA*/ + #define FLOW_HOST_TBL_RD_OP_DATA5_DATA + #define FLOW_HOST_TBL_RD_OP_DATA5_DATA_OFFSET 0 + #define FLOW_HOST_TBL_RD_OP_DATA5_DATA_LEN 32 + #define FLOW_HOST_TBL_RD_OP_DATA5_DATA_DEFAULT 0x0 + +struct flow_host_tbl_rd_op_data5 { + a_uint32_t data:32; +}; + +union flow_host_tbl_rd_op_data5_u { + a_uint32_t val; + struct flow_host_tbl_rd_op_data5 bf; +}; + +/*[register] FLOW_HOST_TBL_RD_OP_DATA6*/ +#define FLOW_HOST_TBL_RD_OP_DATA6 +#define FLOW_HOST_TBL_RD_OP_DATA6_ADDRESS 0x458 +#define FLOW_HOST_TBL_RD_OP_DATA6_NUM 1 +#define FLOW_HOST_TBL_RD_OP_DATA6_INC 0x4 +#define FLOW_HOST_TBL_RD_OP_DATA6_TYPE REG_TYPE_RW +#define FLOW_HOST_TBL_RD_OP_DATA6_DEFAULT 0x0 + /*[field] DATA*/ + #define FLOW_HOST_TBL_RD_OP_DATA6_DATA + #define FLOW_HOST_TBL_RD_OP_DATA6_DATA_OFFSET 0 + #define FLOW_HOST_TBL_RD_OP_DATA6_DATA_LEN 32 + #define FLOW_HOST_TBL_RD_OP_DATA6_DATA_DEFAULT 0x0 + +struct flow_host_tbl_rd_op_data6 { + a_uint32_t data:32; +}; + +union flow_host_tbl_rd_op_data6_u { + a_uint32_t val; + struct flow_host_tbl_rd_op_data6 bf; +}; + +/*[register] FLOW_HOST_TBL_RD_OP_DATA7*/ +#define FLOW_HOST_TBL_RD_OP_DATA7 +#define FLOW_HOST_TBL_RD_OP_DATA7_ADDRESS 0x45c +#define FLOW_HOST_TBL_RD_OP_DATA7_NUM 1 +#define FLOW_HOST_TBL_RD_OP_DATA7_INC 0x4 +#define FLOW_HOST_TBL_RD_OP_DATA7_TYPE REG_TYPE_RW +#define FLOW_HOST_TBL_RD_OP_DATA7_DEFAULT 0x0 + /*[field] DATA*/ + #define FLOW_HOST_TBL_RD_OP_DATA7_DATA + #define FLOW_HOST_TBL_RD_OP_DATA7_DATA_OFFSET 0 + #define FLOW_HOST_TBL_RD_OP_DATA7_DATA_LEN 32 + #define FLOW_HOST_TBL_RD_OP_DATA7_DATA_DEFAULT 0x0 + +struct flow_host_tbl_rd_op_data7 { + a_uint32_t data:32; +}; + +union flow_host_tbl_rd_op_data7_u { + a_uint32_t val; + struct flow_host_tbl_rd_op_data7 bf; +}; + +/*[register] FLOW_HOST_TBL_RD_OP_DATA8*/ +#define FLOW_HOST_TBL_RD_OP_DATA8 +#define FLOW_HOST_TBL_RD_OP_DATA8_ADDRESS 0x460 +#define FLOW_HOST_TBL_RD_OP_DATA8_NUM 1 +#define FLOW_HOST_TBL_RD_OP_DATA8_INC 0x4 +#define FLOW_HOST_TBL_RD_OP_DATA8_TYPE REG_TYPE_RW +#define FLOW_HOST_TBL_RD_OP_DATA8_DEFAULT 0x0 + /*[field] DATA*/ + #define FLOW_HOST_TBL_RD_OP_DATA8_DATA + #define FLOW_HOST_TBL_RD_OP_DATA8_DATA_OFFSET 0 + #define FLOW_HOST_TBL_RD_OP_DATA8_DATA_LEN 32 + #define FLOW_HOST_TBL_RD_OP_DATA8_DATA_DEFAULT 0x0 + +struct flow_host_tbl_rd_op_data8 { + a_uint32_t data:32; +}; + +union flow_host_tbl_rd_op_data8_u { + a_uint32_t val; + struct flow_host_tbl_rd_op_data8 bf; +}; + +/*[register] FLOW_HOST_TBL_RD_OP_DATA9*/ +#define FLOW_HOST_TBL_RD_OP_DATA9 +#define FLOW_HOST_TBL_RD_OP_DATA9_ADDRESS 0x464 +#define FLOW_HOST_TBL_RD_OP_DATA9_NUM 1 +#define FLOW_HOST_TBL_RD_OP_DATA9_INC 0x4 +#define FLOW_HOST_TBL_RD_OP_DATA9_TYPE REG_TYPE_RW +#define FLOW_HOST_TBL_RD_OP_DATA9_DEFAULT 0x0 + /*[field] DATA*/ + #define FLOW_HOST_TBL_RD_OP_DATA9_DATA + #define FLOW_HOST_TBL_RD_OP_DATA9_DATA_OFFSET 0 + #define FLOW_HOST_TBL_RD_OP_DATA9_DATA_LEN 32 + #define FLOW_HOST_TBL_RD_OP_DATA9_DATA_DEFAULT 0x0 + +struct flow_host_tbl_rd_op_data9 { + a_uint32_t data:32; +}; + +union flow_host_tbl_rd_op_data9_u { + a_uint32_t val; + struct flow_host_tbl_rd_op_data9 bf; +}; + +/*[register] IN_FLOW_TBL_RD_OP_RSLT*/ +#define IN_FLOW_TBL_RD_OP_RSLT +#define IN_FLOW_TBL_RD_OP_RSLT_ADDRESS 0x468 +#define IN_FLOW_TBL_RD_OP_RSLT_NUM 1 +#define IN_FLOW_TBL_RD_OP_RSLT_INC 0x4 +#define IN_FLOW_TBL_RD_OP_RSLT_TYPE REG_TYPE_RO +#define IN_FLOW_TBL_RD_OP_RSLT_DEFAULT 0x0 + /*[field] CMD_ID*/ + #define IN_FLOW_TBL_RD_OP_RSLT_CMD_ID + #define IN_FLOW_TBL_RD_OP_RSLT_CMD_ID_OFFSET 0 + #define IN_FLOW_TBL_RD_OP_RSLT_CMD_ID_LEN 4 + #define IN_FLOW_TBL_RD_OP_RSLT_CMD_ID_DEFAULT 0x0 + /*[field] OP_RSLT*/ + #define IN_FLOW_TBL_RD_OP_RSLT_OP_RSLT + #define IN_FLOW_TBL_RD_OP_RSLT_OP_RSLT_OFFSET 4 + #define IN_FLOW_TBL_RD_OP_RSLT_OP_RSLT_LEN 1 + #define IN_FLOW_TBL_RD_OP_RSLT_OP_RSLT_DEFAULT 0x0 + /*[field] FLOW_ENTRY_INDEX*/ + #define IN_FLOW_TBL_RD_OP_RSLT_FLOW_ENTRY_INDEX + #define IN_FLOW_TBL_RD_OP_RSLT_FLOW_ENTRY_INDEX_OFFSET 5 + #define IN_FLOW_TBL_RD_OP_RSLT_FLOW_ENTRY_INDEX_LEN 12 + #define IN_FLOW_TBL_RD_OP_RSLT_FLOW_ENTRY_INDEX_DEFAULT 0x0 + /*[field] VALID_CNT*/ + #define IN_FLOW_TBL_RD_OP_RSLT_VALID_CNT + #define IN_FLOW_TBL_RD_OP_RSLT_VALID_CNT_OFFSET 17 + #define IN_FLOW_TBL_RD_OP_RSLT_VALID_CNT_LEN 4 + #define IN_FLOW_TBL_RD_OP_RSLT_VALID_CNT_DEFAULT 0x0 + +struct in_flow_tbl_rd_op_rslt { + a_uint32_t cmd_id:4; + a_uint32_t op_rslt:1; + a_uint32_t flow_entry_index:12; + a_uint32_t valid_cnt:4; + a_uint32_t _reserved0:11; +}; + +union in_flow_tbl_rd_op_rslt_u { + a_uint32_t val; + struct in_flow_tbl_rd_op_rslt bf; +}; + +/*[register] FLOW_HOST_TBL_RD_OP_RSLT*/ +#define FLOW_HOST_TBL_RD_OP_RSLT +#define FLOW_HOST_TBL_RD_OP_RSLT_ADDRESS 0x46c +#define FLOW_HOST_TBL_RD_OP_RSLT_NUM 1 +#define FLOW_HOST_TBL_RD_OP_RSLT_INC 0x4 +#define FLOW_HOST_TBL_RD_OP_RSLT_TYPE REG_TYPE_RO +#define FLOW_HOST_TBL_RD_OP_RSLT_DEFAULT 0x0 + /*[field] HOST_ENTRY_INDEX*/ + #define FLOW_HOST_TBL_RD_OP_RSLT_HOST_ENTRY_INDEX + #define FLOW_HOST_TBL_RD_OP_RSLT_HOST_ENTRY_INDEX_OFFSET 0 + #define FLOW_HOST_TBL_RD_OP_RSLT_HOST_ENTRY_INDEX_LEN 13 + #define FLOW_HOST_TBL_RD_OP_RSLT_HOST_ENTRY_INDEX_DEFAULT 0x0 + +struct flow_host_tbl_rd_op_rslt { + a_uint32_t host_entry_index:13; + a_uint32_t _reserved0:19; +}; + +union flow_host_tbl_rd_op_rslt_u { + a_uint32_t val; + struct flow_host_tbl_rd_op_rslt bf; +}; + +/*[register] IN_FLOW_TBL_RD_RSLT_DATA0*/ +#define IN_FLOW_TBL_RD_RSLT_DATA0 +#define IN_FLOW_TBL_RD_RSLT_DATA0_ADDRESS 0x470 +#define IN_FLOW_TBL_RD_RSLT_DATA0_NUM 1 +#define IN_FLOW_TBL_RD_RSLT_DATA0_INC 0x4 +#define IN_FLOW_TBL_RD_RSLT_DATA0_TYPE REG_TYPE_RO +#define IN_FLOW_TBL_RD_RSLT_DATA0_DEFAULT 0x0 + /*[field] DATA*/ + #define IN_FLOW_TBL_RD_RSLT_DATA0_DATA + #define IN_FLOW_TBL_RD_RSLT_DATA0_DATA_OFFSET 0 + #define IN_FLOW_TBL_RD_RSLT_DATA0_DATA_LEN 32 + #define IN_FLOW_TBL_RD_RSLT_DATA0_DATA_DEFAULT 0x0 + +struct in_flow_tbl_rd_rslt_data0 { + a_uint32_t data:32; +}; + +union in_flow_tbl_rd_rslt_data0_u { + a_uint32_t val; + struct in_flow_tbl_rd_rslt_data0 bf; +}; + +/*[register] IN_FLOW_TBL_RD_RSLT_DATA1*/ +#define IN_FLOW_TBL_RD_RSLT_DATA1 +#define IN_FLOW_TBL_RD_RSLT_DATA1_ADDRESS 0x474 +#define IN_FLOW_TBL_RD_RSLT_DATA1_NUM 1 +#define IN_FLOW_TBL_RD_RSLT_DATA1_INC 0x4 +#define IN_FLOW_TBL_RD_RSLT_DATA1_TYPE REG_TYPE_RO +#define IN_FLOW_TBL_RD_RSLT_DATA1_DEFAULT 0x0 + /*[field] DATA*/ + #define IN_FLOW_TBL_RD_RSLT_DATA1_DATA + #define IN_FLOW_TBL_RD_RSLT_DATA1_DATA_OFFSET 0 + #define IN_FLOW_TBL_RD_RSLT_DATA1_DATA_LEN 32 + #define IN_FLOW_TBL_RD_RSLT_DATA1_DATA_DEFAULT 0x0 + +struct in_flow_tbl_rd_rslt_data1 { + a_uint32_t data:32; +}; + +union in_flow_tbl_rd_rslt_data1_u { + a_uint32_t val; + struct in_flow_tbl_rd_rslt_data1 bf; +}; + +/*[register] IN_FLOW_TBL_RD_RSLT_DATA2*/ +#define IN_FLOW_TBL_RD_RSLT_DATA2 +#define IN_FLOW_TBL_RD_RSLT_DATA2_ADDRESS 0x478 +#define IN_FLOW_TBL_RD_RSLT_DATA2_NUM 1 +#define IN_FLOW_TBL_RD_RSLT_DATA2_INC 0x4 +#define IN_FLOW_TBL_RD_RSLT_DATA2_TYPE REG_TYPE_RO +#define IN_FLOW_TBL_RD_RSLT_DATA2_DEFAULT 0x0 + /*[field] DATA*/ + #define IN_FLOW_TBL_RD_RSLT_DATA2_DATA + #define IN_FLOW_TBL_RD_RSLT_DATA2_DATA_OFFSET 0 + #define IN_FLOW_TBL_RD_RSLT_DATA2_DATA_LEN 32 + #define IN_FLOW_TBL_RD_RSLT_DATA2_DATA_DEFAULT 0x0 + +struct in_flow_tbl_rd_rslt_data2 { + a_uint32_t data:32; +}; + +union in_flow_tbl_rd_rslt_data2_u { + a_uint32_t val; + struct in_flow_tbl_rd_rslt_data2 bf; +}; + +/*[register] IN_FLOW_TBL_RD_RSLT_DATA3*/ +#define IN_FLOW_TBL_RD_RSLT_DATA3 +#define IN_FLOW_TBL_RD_RSLT_DATA3_ADDRESS 0x47c +#define IN_FLOW_TBL_RD_RSLT_DATA3_NUM 1 +#define IN_FLOW_TBL_RD_RSLT_DATA3_INC 0x4 +#define IN_FLOW_TBL_RD_RSLT_DATA3_TYPE REG_TYPE_RO +#define IN_FLOW_TBL_RD_RSLT_DATA3_DEFAULT 0x0 + /*[field] DATA*/ + #define IN_FLOW_TBL_RD_RSLT_DATA3_DATA + #define IN_FLOW_TBL_RD_RSLT_DATA3_DATA_OFFSET 0 + #define IN_FLOW_TBL_RD_RSLT_DATA3_DATA_LEN 32 + #define IN_FLOW_TBL_RD_RSLT_DATA3_DATA_DEFAULT 0x0 + +struct in_flow_tbl_rd_rslt_data3 { + a_uint32_t data:32; +}; + +union in_flow_tbl_rd_rslt_data3_u { + a_uint32_t val; + struct in_flow_tbl_rd_rslt_data3 bf; +}; + +/*[register] IN_FLOW_TBL_RD_RSLT_DATA4*/ +#define IN_FLOW_TBL_RD_RSLT_DATA4 +#define IN_FLOW_TBL_RD_RSLT_DATA4_ADDRESS 0x480 +#define IN_FLOW_TBL_RD_RSLT_DATA4_NUM 1 +#define IN_FLOW_TBL_RD_RSLT_DATA4_INC 0x4 +#define IN_FLOW_TBL_RD_RSLT_DATA4_TYPE REG_TYPE_RO +#define IN_FLOW_TBL_RD_RSLT_DATA4_DEFAULT 0x0 + /*[field] DATA*/ + #define IN_FLOW_TBL_RD_RSLT_DATA4_DATA + #define IN_FLOW_TBL_RD_RSLT_DATA4_DATA_OFFSET 0 + #define IN_FLOW_TBL_RD_RSLT_DATA4_DATA_LEN 32 + #define IN_FLOW_TBL_RD_RSLT_DATA4_DATA_DEFAULT 0x0 + +struct in_flow_tbl_rd_rslt_data4 { + a_uint32_t data:32; +}; + +union in_flow_tbl_rd_rslt_data4_u { + a_uint32_t val; + struct in_flow_tbl_rd_rslt_data4 bf; +}; + +/*[register] IN_FLOW_TBL_RD_RSLT_DATA5*/ +#define IN_FLOW_TBL_RD_RSLT_DATA5 +#define IN_FLOW_TBL_RD_RSLT_DATA5_ADDRESS 0x484 +#define IN_FLOW_TBL_RD_RSLT_DATA5_NUM 1 +#define IN_FLOW_TBL_RD_RSLT_DATA5_INC 0x4 +#define IN_FLOW_TBL_RD_RSLT_DATA5_TYPE REG_TYPE_RO +#define IN_FLOW_TBL_RD_RSLT_DATA5_DEFAULT 0x0 + /*[field] DATA*/ + #define IN_FLOW_TBL_RD_RSLT_DATA5_DATA + #define IN_FLOW_TBL_RD_RSLT_DATA5_DATA_OFFSET 0 + #define IN_FLOW_TBL_RD_RSLT_DATA5_DATA_LEN 32 + #define IN_FLOW_TBL_RD_RSLT_DATA5_DATA_DEFAULT 0x0 + +struct in_flow_tbl_rd_rslt_data5 { + a_uint32_t data:32; +}; + +union in_flow_tbl_rd_rslt_data5_u { + a_uint32_t val; + struct in_flow_tbl_rd_rslt_data5 bf; +}; + +/*[register] IN_FLOW_TBL_RD_RSLT_DATA6*/ +#define IN_FLOW_TBL_RD_RSLT_DATA6 +#define IN_FLOW_TBL_RD_RSLT_DATA6_ADDRESS 0x488 +#define IN_FLOW_TBL_RD_RSLT_DATA6_NUM 1 +#define IN_FLOW_TBL_RD_RSLT_DATA6_INC 0x4 +#define IN_FLOW_TBL_RD_RSLT_DATA6_TYPE REG_TYPE_RO +#define IN_FLOW_TBL_RD_RSLT_DATA6_DEFAULT 0x0 + /*[field] DATA*/ + #define IN_FLOW_TBL_RD_RSLT_DATA6_DATA + #define IN_FLOW_TBL_RD_RSLT_DATA6_DATA_OFFSET 0 + #define IN_FLOW_TBL_RD_RSLT_DATA6_DATA_LEN 32 + #define IN_FLOW_TBL_RD_RSLT_DATA6_DATA_DEFAULT 0x0 + +struct in_flow_tbl_rd_rslt_data6 { + a_uint32_t data:32; +}; + +union in_flow_tbl_rd_rslt_data6_u { + a_uint32_t val; + struct in_flow_tbl_rd_rslt_data6 bf; +}; + +/*[register] IN_FLOW_TBL_RD_RSLT_DATA7*/ +#define IN_FLOW_TBL_RD_RSLT_DATA7 +#define IN_FLOW_TBL_RD_RSLT_DATA7_ADDRESS 0x48c +#define IN_FLOW_TBL_RD_RSLT_DATA7_NUM 1 +#define IN_FLOW_TBL_RD_RSLT_DATA7_INC 0x4 +#define IN_FLOW_TBL_RD_RSLT_DATA7_TYPE REG_TYPE_RO +#define IN_FLOW_TBL_RD_RSLT_DATA7_DEFAULT 0x0 + /*[field] DATA*/ + #define IN_FLOW_TBL_RD_RSLT_DATA7_DATA + #define IN_FLOW_TBL_RD_RSLT_DATA7_DATA_OFFSET 0 + #define IN_FLOW_TBL_RD_RSLT_DATA7_DATA_LEN 32 + #define IN_FLOW_TBL_RD_RSLT_DATA7_DATA_DEFAULT 0x0 + +struct in_flow_tbl_rd_rslt_data7 { + a_uint32_t data:32; +}; + +union in_flow_tbl_rd_rslt_data7_u { + a_uint32_t val; + struct in_flow_tbl_rd_rslt_data7 bf; +}; + +/*[register] IN_FLOW_TBL_RD_RSLT_DATA8*/ +#define IN_FLOW_TBL_RD_RSLT_DATA8 +#define IN_FLOW_TBL_RD_RSLT_DATA8_ADDRESS 0x490 +#define IN_FLOW_TBL_RD_RSLT_DATA8_NUM 1 +#define IN_FLOW_TBL_RD_RSLT_DATA8_INC 0x4 +#define IN_FLOW_TBL_RD_RSLT_DATA8_TYPE REG_TYPE_RO +#define IN_FLOW_TBL_RD_RSLT_DATA8_DEFAULT 0x0 + /*[field] DATA*/ + #define IN_FLOW_TBL_RD_RSLT_DATA8_DATA + #define IN_FLOW_TBL_RD_RSLT_DATA8_DATA_OFFSET 0 + #define IN_FLOW_TBL_RD_RSLT_DATA8_DATA_LEN 32 + #define IN_FLOW_TBL_RD_RSLT_DATA8_DATA_DEFAULT 0x0 + +struct in_flow_tbl_rd_rslt_data8 { + a_uint32_t data:32; +}; + +union in_flow_tbl_rd_rslt_data8_u { + a_uint32_t val; + struct in_flow_tbl_rd_rslt_data8 bf; +}; + +/*[register] FLOW_HOST_TBL_RD_RSLT_DATA0*/ +#define FLOW_HOST_TBL_RD_RSLT_DATA0 +#define FLOW_HOST_TBL_RD_RSLT_DATA0_ADDRESS 0x494 +#define FLOW_HOST_TBL_RD_RSLT_DATA0_NUM 1 +#define FLOW_HOST_TBL_RD_RSLT_DATA0_INC 0x4 +#define FLOW_HOST_TBL_RD_RSLT_DATA0_TYPE REG_TYPE_RO +#define FLOW_HOST_TBL_RD_RSLT_DATA0_DEFAULT 0x0 + /*[field] DATA*/ + #define FLOW_HOST_TBL_RD_RSLT_DATA0_DATA + #define FLOW_HOST_TBL_RD_RSLT_DATA0_DATA_OFFSET 0 + #define FLOW_HOST_TBL_RD_RSLT_DATA0_DATA_LEN 32 + #define FLOW_HOST_TBL_RD_RSLT_DATA0_DATA_DEFAULT 0x0 + +struct flow_host_tbl_rd_rslt_data0 { + a_uint32_t data:32; +}; + +union flow_host_tbl_rd_rslt_data0_u { + a_uint32_t val; + struct flow_host_tbl_rd_rslt_data0 bf; +}; + +/*[register] FLOW_HOST_TBL_RD_RSLT_DATA1*/ +#define FLOW_HOST_TBL_RD_RSLT_DATA1 +#define FLOW_HOST_TBL_RD_RSLT_DATA1_ADDRESS 0x498 +#define FLOW_HOST_TBL_RD_RSLT_DATA1_NUM 1 +#define FLOW_HOST_TBL_RD_RSLT_DATA1_INC 0x4 +#define FLOW_HOST_TBL_RD_RSLT_DATA1_TYPE REG_TYPE_RO +#define FLOW_HOST_TBL_RD_RSLT_DATA1_DEFAULT 0x0 + /*[field] DATA*/ + #define FLOW_HOST_TBL_RD_RSLT_DATA1_DATA + #define FLOW_HOST_TBL_RD_RSLT_DATA1_DATA_OFFSET 0 + #define FLOW_HOST_TBL_RD_RSLT_DATA1_DATA_LEN 32 + #define FLOW_HOST_TBL_RD_RSLT_DATA1_DATA_DEFAULT 0x0 + +struct flow_host_tbl_rd_rslt_data1 { + a_uint32_t data:32; +}; + +union flow_host_tbl_rd_rslt_data1_u { + a_uint32_t val; + struct flow_host_tbl_rd_rslt_data1 bf; +}; + +/*[register] FLOW_HOST_TBL_RD_RSLT_DATA2*/ +#define FLOW_HOST_TBL_RD_RSLT_DATA2 +#define FLOW_HOST_TBL_RD_RSLT_DATA2_ADDRESS 0x49c +#define FLOW_HOST_TBL_RD_RSLT_DATA2_NUM 1 +#define FLOW_HOST_TBL_RD_RSLT_DATA2_INC 0x4 +#define FLOW_HOST_TBL_RD_RSLT_DATA2_TYPE REG_TYPE_RO +#define FLOW_HOST_TBL_RD_RSLT_DATA2_DEFAULT 0x0 + /*[field] DATA*/ + #define FLOW_HOST_TBL_RD_RSLT_DATA2_DATA + #define FLOW_HOST_TBL_RD_RSLT_DATA2_DATA_OFFSET 0 + #define FLOW_HOST_TBL_RD_RSLT_DATA2_DATA_LEN 32 + #define FLOW_HOST_TBL_RD_RSLT_DATA2_DATA_DEFAULT 0x0 + +struct flow_host_tbl_rd_rslt_data2 { + a_uint32_t data:32; +}; + +union flow_host_tbl_rd_rslt_data2_u { + a_uint32_t val; + struct flow_host_tbl_rd_rslt_data2 bf; +}; + +/*[register] FLOW_HOST_TBL_RD_RSLT_DATA3*/ +#define FLOW_HOST_TBL_RD_RSLT_DATA3 +#define FLOW_HOST_TBL_RD_RSLT_DATA3_ADDRESS 0x4a0 +#define FLOW_HOST_TBL_RD_RSLT_DATA3_NUM 1 +#define FLOW_HOST_TBL_RD_RSLT_DATA3_INC 0x4 +#define FLOW_HOST_TBL_RD_RSLT_DATA3_TYPE REG_TYPE_RO +#define FLOW_HOST_TBL_RD_RSLT_DATA3_DEFAULT 0x0 + /*[field] DATA*/ + #define FLOW_HOST_TBL_RD_RSLT_DATA3_DATA + #define FLOW_HOST_TBL_RD_RSLT_DATA3_DATA_OFFSET 0 + #define FLOW_HOST_TBL_RD_RSLT_DATA3_DATA_LEN 32 + #define FLOW_HOST_TBL_RD_RSLT_DATA3_DATA_DEFAULT 0x0 + +struct flow_host_tbl_rd_rslt_data3 { + a_uint32_t data:32; +}; + +union flow_host_tbl_rd_rslt_data3_u { + a_uint32_t val; + struct flow_host_tbl_rd_rslt_data3 bf; +}; + +/*[register] FLOW_HOST_TBL_RD_RSLT_DATA4*/ +#define FLOW_HOST_TBL_RD_RSLT_DATA4 +#define FLOW_HOST_TBL_RD_RSLT_DATA4_ADDRESS 0x4a4 +#define FLOW_HOST_TBL_RD_RSLT_DATA4_NUM 1 +#define FLOW_HOST_TBL_RD_RSLT_DATA4_INC 0x4 +#define FLOW_HOST_TBL_RD_RSLT_DATA4_TYPE REG_TYPE_RO +#define FLOW_HOST_TBL_RD_RSLT_DATA4_DEFAULT 0x0 + /*[field] DATA*/ + #define FLOW_HOST_TBL_RD_RSLT_DATA4_DATA + #define FLOW_HOST_TBL_RD_RSLT_DATA4_DATA_OFFSET 0 + #define FLOW_HOST_TBL_RD_RSLT_DATA4_DATA_LEN 32 + #define FLOW_HOST_TBL_RD_RSLT_DATA4_DATA_DEFAULT 0x0 + +struct flow_host_tbl_rd_rslt_data4 { + a_uint32_t data:32; +}; + +union flow_host_tbl_rd_rslt_data4_u { + a_uint32_t val; + struct flow_host_tbl_rd_rslt_data4 bf; +}; + +/*[register] FLOW_HOST_TBL_RD_RSLT_DATA5*/ +#define FLOW_HOST_TBL_RD_RSLT_DATA5 +#define FLOW_HOST_TBL_RD_RSLT_DATA5_ADDRESS 0x4a8 +#define FLOW_HOST_TBL_RD_RSLT_DATA5_NUM 1 +#define FLOW_HOST_TBL_RD_RSLT_DATA5_INC 0x4 +#define FLOW_HOST_TBL_RD_RSLT_DATA5_TYPE REG_TYPE_RO +#define FLOW_HOST_TBL_RD_RSLT_DATA5_DEFAULT 0x0 + /*[field] DATA*/ + #define FLOW_HOST_TBL_RD_RSLT_DATA5_DATA + #define FLOW_HOST_TBL_RD_RSLT_DATA5_DATA_OFFSET 0 + #define FLOW_HOST_TBL_RD_RSLT_DATA5_DATA_LEN 32 + #define FLOW_HOST_TBL_RD_RSLT_DATA5_DATA_DEFAULT 0x0 + +struct flow_host_tbl_rd_rslt_data5 { + a_uint32_t data:32; +}; + +union flow_host_tbl_rd_rslt_data5_u { + a_uint32_t val; + struct flow_host_tbl_rd_rslt_data5 bf; +}; + +/*[register] FLOW_HOST_TBL_RD_RSLT_DATA6*/ +#define FLOW_HOST_TBL_RD_RSLT_DATA6 +#define FLOW_HOST_TBL_RD_RSLT_DATA6_ADDRESS 0x4ac +#define FLOW_HOST_TBL_RD_RSLT_DATA6_NUM 1 +#define FLOW_HOST_TBL_RD_RSLT_DATA6_INC 0x4 +#define FLOW_HOST_TBL_RD_RSLT_DATA6_TYPE REG_TYPE_RO +#define FLOW_HOST_TBL_RD_RSLT_DATA6_DEFAULT 0x0 + /*[field] DATA*/ + #define FLOW_HOST_TBL_RD_RSLT_DATA6_DATA + #define FLOW_HOST_TBL_RD_RSLT_DATA6_DATA_OFFSET 0 + #define FLOW_HOST_TBL_RD_RSLT_DATA6_DATA_LEN 32 + #define FLOW_HOST_TBL_RD_RSLT_DATA6_DATA_DEFAULT 0x0 + +struct flow_host_tbl_rd_rslt_data6 { + a_uint32_t data:32; +}; + +union flow_host_tbl_rd_rslt_data6_u { + a_uint32_t val; + struct flow_host_tbl_rd_rslt_data6 bf; +}; + +/*[register] FLOW_HOST_TBL_RD_RSLT_DATA7*/ +#define FLOW_HOST_TBL_RD_RSLT_DATA7 +#define FLOW_HOST_TBL_RD_RSLT_DATA7_ADDRESS 0x4b0 +#define FLOW_HOST_TBL_RD_RSLT_DATA7_NUM 1 +#define FLOW_HOST_TBL_RD_RSLT_DATA7_INC 0x4 +#define FLOW_HOST_TBL_RD_RSLT_DATA7_TYPE REG_TYPE_RO +#define FLOW_HOST_TBL_RD_RSLT_DATA7_DEFAULT 0x0 + /*[field] DATA*/ + #define FLOW_HOST_TBL_RD_RSLT_DATA7_DATA + #define FLOW_HOST_TBL_RD_RSLT_DATA7_DATA_OFFSET 0 + #define FLOW_HOST_TBL_RD_RSLT_DATA7_DATA_LEN 32 + #define FLOW_HOST_TBL_RD_RSLT_DATA7_DATA_DEFAULT 0x0 + +struct flow_host_tbl_rd_rslt_data7 { + a_uint32_t data:32; +}; + +union flow_host_tbl_rd_rslt_data7_u { + a_uint32_t val; + struct flow_host_tbl_rd_rslt_data7 bf; +}; + +/*[register] FLOW_HOST_TBL_RD_RSLT_DATA8*/ +#define FLOW_HOST_TBL_RD_RSLT_DATA8 +#define FLOW_HOST_TBL_RD_RSLT_DATA8_ADDRESS 0x4b4 +#define FLOW_HOST_TBL_RD_RSLT_DATA8_NUM 1 +#define FLOW_HOST_TBL_RD_RSLT_DATA8_INC 0x4 +#define FLOW_HOST_TBL_RD_RSLT_DATA8_TYPE REG_TYPE_RO +#define FLOW_HOST_TBL_RD_RSLT_DATA8_DEFAULT 0x0 + /*[field] DATA*/ + #define FLOW_HOST_TBL_RD_RSLT_DATA8_DATA + #define FLOW_HOST_TBL_RD_RSLT_DATA8_DATA_OFFSET 0 + #define FLOW_HOST_TBL_RD_RSLT_DATA8_DATA_LEN 32 + #define FLOW_HOST_TBL_RD_RSLT_DATA8_DATA_DEFAULT 0x0 + +struct flow_host_tbl_rd_rslt_data8 { + a_uint32_t data:32; +}; + +union flow_host_tbl_rd_rslt_data8_u { + a_uint32_t val; + struct flow_host_tbl_rd_rslt_data8 bf; +}; + +/*[register] FLOW_HOST_TBL_RD_RSLT_DATA9*/ +#define FLOW_HOST_TBL_RD_RSLT_DATA9 +#define FLOW_HOST_TBL_RD_RSLT_DATA9_ADDRESS 0x4b8 +#define FLOW_HOST_TBL_RD_RSLT_DATA9_NUM 1 +#define FLOW_HOST_TBL_RD_RSLT_DATA9_INC 0x4 +#define FLOW_HOST_TBL_RD_RSLT_DATA9_TYPE REG_TYPE_RO +#define FLOW_HOST_TBL_RD_RSLT_DATA9_DEFAULT 0x0 + /*[field] DATA*/ + #define FLOW_HOST_TBL_RD_RSLT_DATA9_DATA + #define FLOW_HOST_TBL_RD_RSLT_DATA9_DATA_OFFSET 0 + #define FLOW_HOST_TBL_RD_RSLT_DATA9_DATA_LEN 32 + #define FLOW_HOST_TBL_RD_RSLT_DATA9_DATA_DEFAULT 0x0 + +struct flow_host_tbl_rd_rslt_data9 { + a_uint32_t data:32; +}; + +union flow_host_tbl_rd_rslt_data9_u { + a_uint32_t val; + struct flow_host_tbl_rd_rslt_data9 bf; +}; + +/*[table] IN_FLOW_3TUPLE_TBL*/ +#define IN_FLOW_3TUPLE_TBL +#define IN_FLOW_3TUPLE_TBL_ADDRESS 0x40000 +#define IN_FLOW_3TUPLE_TBL_NUM 4096 +#define IN_FLOW_3TUPLE_TBL_INC 0x20 +#define IN_FLOW_3TUPLE_TBL_TYPE REG_TYPE_RW +#define IN_FLOW_3TUPLE_TBL_DEFAULT 0x0 + /*[field] VALID*/ + #define IN_FLOW_3TUPLE_TBL_VALID + #define IN_FLOW_3TUPLE_TBL_VALID_OFFSET 0 + #define IN_FLOW_3TUPLE_TBL_VALID_LEN 1 + #define IN_FLOW_3TUPLE_TBL_VALID_DEFAULT 0x0 + /*[field] ENTRY_TYPE*/ + #define IN_FLOW_3TUPLE_TBL_ENTRY_TYPE + #define IN_FLOW_3TUPLE_TBL_ENTRY_TYPE_OFFSET 1 + #define IN_FLOW_3TUPLE_TBL_ENTRY_TYPE_LEN 1 + #define IN_FLOW_3TUPLE_TBL_ENTRY_TYPE_DEFAULT 0x0 + /*[field] HOST_ADDR_INDEX_TYPE*/ + #define IN_FLOW_3TUPLE_TBL_HOST_ADDR_INDEX_TYPE + #define IN_FLOW_3TUPLE_TBL_HOST_ADDR_INDEX_TYPE_OFFSET 2 + #define IN_FLOW_3TUPLE_TBL_HOST_ADDR_INDEX_TYPE_LEN 1 + #define IN_FLOW_3TUPLE_TBL_HOST_ADDR_INDEX_TYPE_DEFAULT 0x0 + /*[field] HOST_ADDR_INDEX*/ + #define IN_FLOW_3TUPLE_TBL_HOST_ADDR_INDEX + #define IN_FLOW_3TUPLE_TBL_HOST_ADDR_INDEX_OFFSET 3 + #define IN_FLOW_3TUPLE_TBL_HOST_ADDR_INDEX_LEN 13 + #define IN_FLOW_3TUPLE_TBL_HOST_ADDR_INDEX_DEFAULT 0x0 + /*[field] PROTOCOL_TYPE*/ + #define IN_FLOW_3TUPLE_TBL_PROTOCOL_TYPE + #define IN_FLOW_3TUPLE_TBL_PROTOCOL_TYPE_OFFSET 16 + #define IN_FLOW_3TUPLE_TBL_PROTOCOL_TYPE_LEN 2 + #define IN_FLOW_3TUPLE_TBL_PROTOCOL_TYPE_DEFAULT 0x0 + /*[field] AGE*/ + #define IN_FLOW_3TUPLE_TBL_AGE + #define IN_FLOW_3TUPLE_TBL_AGE_OFFSET 18 + #define IN_FLOW_3TUPLE_TBL_AGE_LEN 2 + #define IN_FLOW_3TUPLE_TBL_AGE_DEFAULT 0x0 + /*[field] SRC_L3_IF_VALID*/ + #define IN_FLOW_3TUPLE_TBL_SRC_L3_IF_VALID + #define IN_FLOW_3TUPLE_TBL_SRC_L3_IF_VALID_OFFSET 20 + #define IN_FLOW_3TUPLE_TBL_SRC_L3_IF_VALID_LEN 1 + #define IN_FLOW_3TUPLE_TBL_SRC_L3_IF_VALID_DEFAULT 0x0 + /*[field] SRC_L3_IF*/ + #define IN_FLOW_3TUPLE_TBL_SRC_L3_IF + #define IN_FLOW_3TUPLE_TBL_SRC_L3_IF_OFFSET 21 + #define IN_FLOW_3TUPLE_TBL_SRC_L3_IF_LEN 8 + #define IN_FLOW_3TUPLE_TBL_SRC_L3_IF_DEFAULT 0x0 + /*[field] FWD_TYPE*/ + #define IN_FLOW_3TUPLE_TBL_FWD_TYPE + #define IN_FLOW_3TUPLE_TBL_FWD_TYPE_OFFSET 29 + #define IN_FLOW_3TUPLE_TBL_FWD_TYPE_LEN 3 + #define IN_FLOW_3TUPLE_TBL_FWD_TYPE_DEFAULT 0x0 + /*[field] PORT_VP2 reuse FWD_TYPE[1]*/ + #define IN_FLOW_3TUPLE_TBL_PORT_VP2 + #define IN_FLOW_3TUPLE_TBL_PORT_VP2_OFFSET 32 + #define IN_FLOW_3TUPLE_TBL_PORT_VP2_LEN 8 + #define IN_FLOW_3TUPLE_TBL_PORT_VP2_DEFAULT 0x0 + /*[field] NEXT_HOP3 reuse FWD_TYPE[2]*/ + #define IN_FLOW_3TUPLE_TBL_NEXT_HOP3 + #define IN_FLOW_3TUPLE_TBL_NEXT_HOP3_OFFSET 32 + #define IN_FLOW_3TUPLE_TBL_NEXT_HOP3_LEN 12 + #define IN_FLOW_3TUPLE_TBL_NEXT_HOP3_DEFAULT 0x0 + /*[field] NEXT_HOP1 reuse FWD_TYPE[0]*/ + #define IN_FLOW_3TUPLE_TBL_NEXT_HOP1 + #define IN_FLOW_3TUPLE_TBL_NEXT_HOP1_OFFSET 32 + #define IN_FLOW_3TUPLE_TBL_NEXT_HOP1_LEN 12 + #define IN_FLOW_3TUPLE_TBL_NEXT_HOP1_DEFAULT 0x0 + /*[field] NEXT_HOP2 reuse FWD_TYPE[3]*/ + #define IN_FLOW_3TUPLE_TBL_NEXT_HOP2 + #define IN_FLOW_3TUPLE_TBL_NEXT_HOP2_OFFSET 32 + #define IN_FLOW_3TUPLE_TBL_NEXT_HOP2_LEN 12 + #define IN_FLOW_3TUPLE_TBL_NEXT_HOP2_DEFAULT 0x0 + /*[field] PORT_VP_VALID1 reuse FWD_TYPE[2]*/ + #define IN_FLOW_3TUPLE_TBL_PORT_VP_VALID1 + #define IN_FLOW_3TUPLE_TBL_PORT_VP_VALID1_OFFSET 44 + #define IN_FLOW_3TUPLE_TBL_PORT_VP_VALID1_LEN 1 + #define IN_FLOW_3TUPLE_TBL_PORT_VP_VALID1_DEFAULT 0x0 + /*[field] PORT_VP1 reuse FWD_TYPE[2]*/ + #define IN_FLOW_3TUPLE_TBL_PORT_VP1 + #define IN_FLOW_3TUPLE_TBL_PORT_VP1_OFFSET 45 + #define IN_FLOW_3TUPLE_TBL_PORT_VP1_LEN 8 + #define IN_FLOW_3TUPLE_TBL_PORT_VP1_DEFAULT 0x0 + /*[field] DE_ACCE*/ + #define IN_FLOW_3TUPLE_TBL_DE_ACCE + #define IN_FLOW_3TUPLE_TBL_DE_ACCE_OFFSET 60 + #define IN_FLOW_3TUPLE_TBL_DE_ACCE_LEN 1 + #define IN_FLOW_3TUPLE_TBL_DE_ACCE_DEFAULT 0x0 + /*[field] COPY_TO_CPU_EN*/ + #define IN_FLOW_3TUPLE_TBL_COPY_TO_CPU_EN + #define IN_FLOW_3TUPLE_TBL_COPY_TO_CPU_EN_OFFSET 61 + #define IN_FLOW_3TUPLE_TBL_COPY_TO_CPU_EN_LEN 1 + #define IN_FLOW_3TUPLE_TBL_COPY_TO_CPU_EN_DEFAULT 0x0 + /*[field] SYN_TOGGLE*/ + #define IN_FLOW_3TUPLE_TBL_SYN_TOGGLE + #define IN_FLOW_3TUPLE_TBL_SYN_TOGGLE_OFFSET 62 + #define IN_FLOW_3TUPLE_TBL_SYN_TOGGLE_LEN 1 + #define IN_FLOW_3TUPLE_TBL_SYN_TOGGLE_DEFAULT 0x0 + /*[field] PRI_PROFILE*/ + #define IN_FLOW_3TUPLE_TBL_PRI_PROFILE + #define IN_FLOW_3TUPLE_TBL_PRI_PROFILE_OFFSET 63 + #define IN_FLOW_3TUPLE_TBL_PRI_PROFILE_LEN 5 + #define IN_FLOW_3TUPLE_TBL_PRI_PROFILE_DEFAULT 0x0 + /*[field] SERVICE_CODE*/ + #define IN_FLOW_3TUPLE_TBL_SERVICE_CODE + #define IN_FLOW_3TUPLE_TBL_SERVICE_CODE_OFFSET 68 + #define IN_FLOW_3TUPLE_TBL_SERVICE_CODE_LEN 8 + #define IN_FLOW_3TUPLE_TBL_SERVICE_CODE_DEFAULT 0x0 + /*[field] IP_ADDR*/ + #define IN_FLOW_3TUPLE_TBL_IP_ADDR + #define IN_FLOW_3TUPLE_TBL_IP_ADDR_OFFSET 76 + #define IN_FLOW_3TUPLE_TBL_IP_ADDR_LEN 32 + #define IN_FLOW_3TUPLE_TBL_IP_ADDR_DEFAULT 0x0 + /*[field] IP_PROTOCOL*/ + #define IN_FLOW_3TUPLE_TBL_IP_PROTOCOL + #define IN_FLOW_3TUPLE_TBL_IP_PROTOCOL_OFFSET 108 + #define IN_FLOW_3TUPLE_TBL_IP_PROTOCOL_LEN 8 + #define IN_FLOW_3TUPLE_TBL_IP_PROTOCOL_DEFAULT 0x0 + +struct in_flow_tbl_1 { + a_uint32_t valid:1; + a_uint32_t entry_type:1; + a_uint32_t host_addr_index_type:1; + a_uint32_t host_addr_index:13; + a_uint32_t protocol_type:2; + a_uint32_t age:2; + a_uint32_t src_l3_if_valid:1; + a_uint32_t src_l3_if:8; + a_uint32_t fwd_type:3; + a_uint32_t port_vp2:8; + a_uint32_t _reserved0:20; + a_uint32_t de_acce:1; + a_uint32_t copy_to_cpu_en:1; + a_uint32_t syn_toggle:1; + a_uint32_t pri_profile_0:1; + a_uint32_t pri_profile_1:4; + a_uint32_t service_code:8; + a_uint32_t ip_addr_0:20; + a_uint32_t ip_addr_1:12; + a_uint32_t l4_sport:16; + a_uint32_t l4_dport_0:4; + a_uint32_t l4_dport_1:12; + a_uint32_t _reserved1:20; +}; + +struct in_flow_tbl_3 { + a_uint32_t valid:1; + a_uint32_t entry_type:1; + a_uint32_t host_addr_index_type:1; + a_uint32_t host_addr_index:13; + a_uint32_t protocol_type:2; + a_uint32_t age:2; + a_uint32_t src_l3_if_valid:1; + a_uint32_t src_l3_if:8; + a_uint32_t fwd_type:3; + a_uint32_t next_hop2:12; + a_uint32_t l4_port2:16; + a_uint32_t de_acce:1; + a_uint32_t copy_to_cpu_en:1; + a_uint32_t syn_toggle:1; + a_uint32_t pri_profile_0:1; + a_uint32_t pri_profile_1:4; + a_uint32_t service_code:8; + a_uint32_t ip_addr_0:20; + a_uint32_t ip_addr_1:12; + a_uint32_t l4_sport:16; + a_uint32_t l4_dport_0:4; + a_uint32_t l4_dport_1:12; + a_uint32_t _reserved0:20; +}; + +struct in_flow_tbl_0 { + a_uint32_t valid:1; + a_uint32_t entry_type:1; + a_uint32_t host_addr_index_type:1; + a_uint32_t host_addr_index:13; + a_uint32_t protocol_type:2; + a_uint32_t age:2; + a_uint32_t src_l3_if_valid:1; + a_uint32_t src_l3_if:8; + a_uint32_t fwd_type:3; + a_uint32_t next_hop1:12; + a_uint32_t l4_port1:16; + a_uint32_t de_acce:1; + a_uint32_t copy_to_cpu_en:1; + a_uint32_t syn_toggle:1; + a_uint32_t pri_profile_0:1; + a_uint32_t pri_profile_1:4; + a_uint32_t service_code:8; + a_uint32_t ip_addr_0:20; + a_uint32_t ip_addr_1:12; + a_uint32_t l4_sport:16; + a_uint32_t l4_dport_0:4; + a_uint32_t l4_dport_1:12; + a_uint32_t _reserved0:20; +}; + +struct in_flow_tbl_2 { + a_uint32_t valid:1; + a_uint32_t entry_type:1; + a_uint32_t host_addr_index_type:1; + a_uint32_t host_addr_index:13; + a_uint32_t protocol_type:2; + a_uint32_t age:2; + a_uint32_t src_l3_if_valid:1; + a_uint32_t src_l3_if:8; + a_uint32_t fwd_type:3; + a_uint32_t next_hop3:12; + a_uint32_t port_vp_valid1:1; + a_uint32_t port_vp1:8; + a_uint32_t _reserved0:7; + a_uint32_t de_acce:1; + a_uint32_t copy_to_cpu_en:1; + a_uint32_t syn_toggle:1; + a_uint32_t pri_profile_0:1; + a_uint32_t pri_profile_1:4; + a_uint32_t service_code:8; + a_uint32_t ip_addr_0:20; + a_uint32_t ip_addr_1:12; + a_uint32_t l4_sport:16; + a_uint32_t l4_dport_0:4; + a_uint32_t l4_dport_1:12; + a_uint32_t _reserved1:20; +}; + +union in_flow_tbl_u { + a_uint32_t val[5]; + struct in_flow_tbl_0 bf0; + struct in_flow_tbl_1 bf1; + struct in_flow_tbl_2 bf2; + struct in_flow_tbl_3 bf3; +}; + +/*[table] IN_FLOW_IPV6_3TUPLE_TBL*/ +#define IN_FLOW_IPV6_3TUPLE_TBL +#define IN_FLOW_IPV6_3TUPLE_TBL_ADDRESS 0x40000 +#define IN_FLOW_IPV6_3TUPLE_TBL_NUM 2048 +#define IN_FLOW_IPV6_3TUPLE_TBL_INC 0x40 +#define IN_FLOW_IPV6_3TUPLE_TBL_TYPE REG_TYPE_RW +#define IN_FLOW_IPV6_3TUPLE_TBL_DEFAULT 0x0 + /*[field] VALID*/ + #define IN_FLOW_IPV6_3TUPLE_TBL_VALID + #define IN_FLOW_IPV6_3TUPLE_TBL_VALID_OFFSET 0 + #define IN_FLOW_IPV6_3TUPLE_TBL_VALID_LEN 1 + #define IN_FLOW_IPV6_3TUPLE_TBL_VALID_DEFAULT 0x0 + /*[field] ENTRY_TYPE*/ + #define IN_FLOW_IPV6_3TUPLE_TBL_ENTRY_TYPE + #define IN_FLOW_IPV6_3TUPLE_TBL_ENTRY_TYPE_OFFSET 1 + #define IN_FLOW_IPV6_3TUPLE_TBL_ENTRY_TYPE_LEN 1 + #define IN_FLOW_IPV6_3TUPLE_TBL_ENTRY_TYPE_DEFAULT 0x0 + /*[field] HOST_ADDR_INDEX_TYPE*/ + #define IN_FLOW_IPV6_3TUPLE_TBL_HOST_ADDR_INDEX_TYPE + #define IN_FLOW_IPV6_3TUPLE_TBL_HOST_ADDR_INDEX_TYPE_OFFSET 2 + #define IN_FLOW_IPV6_3TUPLE_TBL_HOST_ADDR_INDEX_TYPE_LEN 1 + #define IN_FLOW_IPV6_3TUPLE_TBL_HOST_ADDR_INDEX_TYPE_DEFAULT 0x0 + /*[field] HOST_ADDR_INDEX*/ + #define IN_FLOW_IPV6_3TUPLE_TBL_HOST_ADDR_INDEX + #define IN_FLOW_IPV6_3TUPLE_TBL_HOST_ADDR_INDEX_OFFSET 3 + #define IN_FLOW_IPV6_3TUPLE_TBL_HOST_ADDR_INDEX_LEN 13 + #define IN_FLOW_IPV6_3TUPLE_TBL_HOST_ADDR_INDEX_DEFAULT 0x0 + /*[field] PROTOCOL_TYPE*/ + #define IN_FLOW_IPV6_3TUPLE_TBL_PROTOCOL_TYPE + #define IN_FLOW_IPV6_3TUPLE_TBL_PROTOCOL_TYPE_OFFSET 16 + #define IN_FLOW_IPV6_3TUPLE_TBL_PROTOCOL_TYPE_LEN 2 + #define IN_FLOW_IPV6_3TUPLE_TBL_PROTOCOL_TYPE_DEFAULT 0x0 + /*[field] AGE*/ + #define IN_FLOW_IPV6_3TUPLE_TBL_AGE + #define IN_FLOW_IPV6_3TUPLE_TBL_AGE_OFFSET 18 + #define IN_FLOW_IPV6_3TUPLE_TBL_AGE_LEN 2 + #define IN_FLOW_IPV6_3TUPLE_TBL_AGE_DEFAULT 0x0 + /*[field] SRC_L3_IF_VALID*/ + #define IN_FLOW_IPV6_3TUPLE_TBL_SRC_L3_IF_VALID + #define IN_FLOW_IPV6_3TUPLE_TBL_SRC_L3_IF_VALID_OFFSET 20 + #define IN_FLOW_IPV6_3TUPLE_TBL_SRC_L3_IF_VALID_LEN 1 + #define IN_FLOW_IPV6_3TUPLE_TBL_SRC_L3_IF_VALID_DEFAULT 0x0 + /*[field] SRC_L3_IF*/ + #define IN_FLOW_IPV6_3TUPLE_TBL_SRC_L3_IF + #define IN_FLOW_IPV6_3TUPLE_TBL_SRC_L3_IF_OFFSET 21 + #define IN_FLOW_IPV6_3TUPLE_TBL_SRC_L3_IF_LEN 8 + #define IN_FLOW_IPV6_3TUPLE_TBL_SRC_L3_IF_DEFAULT 0x0 + /*[field] FWD_TYPE*/ + #define IN_FLOW_IPV6_3TUPLE_TBL_FWD_TYPE + #define IN_FLOW_IPV6_3TUPLE_TBL_FWD_TYPE_OFFSET 29 + #define IN_FLOW_IPV6_3TUPLE_TBL_FWD_TYPE_LEN 3 + #define IN_FLOW_IPV6_3TUPLE_TBL_FWD_TYPE_DEFAULT 0x0 + /*[field] NEXT_HOP3 reuse FWD_TYPE[2]*/ + #define IN_FLOW_IPV6_3TUPLE_TBL_NEXT_HOP3 + #define IN_FLOW_IPV6_3TUPLE_TBL_NEXT_HOP3_OFFSET 32 + #define IN_FLOW_IPV6_3TUPLE_TBL_NEXT_HOP3_LEN 12 + #define IN_FLOW_IPV6_3TUPLE_TBL_NEXT_HOP3_DEFAULT 0x0 + /*[field] NEXT_HOP1 reuse FWD_TYPE[1]*/ + #define IN_FLOW_IPV6_3TUPLE_TBL_NEXT_HOP1 + #define IN_FLOW_IPV6_3TUPLE_TBL_NEXT_HOP1_OFFSET 32 + #define IN_FLOW_IPV6_3TUPLE_TBL_NEXT_HOP1_LEN 12 + #define IN_FLOW_IPV6_3TUPLE_TBL_NEXT_HOP1_DEFAULT 0x0 + /*[field] NEXT_HOP2 reuse FWD_TYPE[3]*/ + #define IN_FLOW_IPV6_3TUPLE_TBL_NEXT_HOP2 + #define IN_FLOW_IPV6_3TUPLE_TBL_NEXT_HOP2_OFFSET 32 + #define IN_FLOW_IPV6_3TUPLE_TBL_NEXT_HOP2_LEN 12 + #define IN_FLOW_IPV6_3TUPLE_TBL_NEXT_HOP2_DEFAULT 0x0 + /*[field] PORT_VP2 reuse FWD_TYPE[0]*/ + #define IN_FLOW_IPV6_3TUPLE_TBL_PORT_VP2 + #define IN_FLOW_IPV6_3TUPLE_TBL_PORT_VP2_OFFSET 32 + #define IN_FLOW_IPV6_3TUPLE_TBL_PORT_VP2_LEN 8 + #define IN_FLOW_IPV6_3TUPLE_TBL_PORT_VP2_DEFAULT 0x0 + /*[field] PORT_VP_VALID1 reuse FWD_TYPE[2]*/ + #define IN_FLOW_IPV6_3TUPLE_TBL_PORT_VP_VALID1 + #define IN_FLOW_IPV6_3TUPLE_TBL_PORT_VP_VALID1_OFFSET 44 + #define IN_FLOW_IPV6_3TUPLE_TBL_PORT_VP_VALID1_LEN 1 + #define IN_FLOW_IPV6_3TUPLE_TBL_PORT_VP_VALID1_DEFAULT 0x0 + /*[field] PORT_VP1 reuse FWD_TYPE[2]*/ + #define IN_FLOW_IPV6_3TUPLE_TBL_PORT_VP1 + #define IN_FLOW_IPV6_3TUPLE_TBL_PORT_VP1_OFFSET 45 + #define IN_FLOW_IPV6_3TUPLE_TBL_PORT_VP1_LEN 8 + #define IN_FLOW_IPV6_3TUPLE_TBL_PORT_VP1_DEFAULT 0x0 + /*[field] DE_ACCE*/ + #define IN_FLOW_IPV6_3TUPLE_TBL_DE_ACCE + #define IN_FLOW_IPV6_3TUPLE_TBL_DE_ACCE_OFFSET 60 + #define IN_FLOW_IPV6_3TUPLE_TBL_DE_ACCE_LEN 1 + #define IN_FLOW_IPV6_3TUPLE_TBL_DE_ACCE_DEFAULT 0x0 + /*[field] COPY_TO_CPU_EN*/ + #define IN_FLOW_IPV6_3TUPLE_TBL_COPY_TO_CPU_EN + #define IN_FLOW_IPV6_3TUPLE_TBL_COPY_TO_CPU_EN_OFFSET 61 + #define IN_FLOW_IPV6_3TUPLE_TBL_COPY_TO_CPU_EN_LEN 1 + #define IN_FLOW_IPV6_3TUPLE_TBL_COPY_TO_CPU_EN_DEFAULT 0x0 + /*[field] SYN_TOGGLE*/ + #define IN_FLOW_IPV6_3TUPLE_TBL_SYN_TOGGLE + #define IN_FLOW_IPV6_3TUPLE_TBL_SYN_TOGGLE_OFFSET 62 + #define IN_FLOW_IPV6_3TUPLE_TBL_SYN_TOGGLE_LEN 1 + #define IN_FLOW_IPV6_3TUPLE_TBL_SYN_TOGGLE_DEFAULT 0x0 + /*[field] PRI_PROFILE*/ + #define IN_FLOW_IPV6_3TUPLE_TBL_PRI_PROFILE + #define IN_FLOW_IPV6_3TUPLE_TBL_PRI_PROFILE_OFFSET 63 + #define IN_FLOW_IPV6_3TUPLE_TBL_PRI_PROFILE_LEN 5 + #define IN_FLOW_IPV6_3TUPLE_TBL_PRI_PROFILE_DEFAULT 0x0 + /*[field] SERVICE_CODE*/ + #define IN_FLOW_IPV6_3TUPLE_TBL_SERVICE_CODE + #define IN_FLOW_IPV6_3TUPLE_TBL_SERVICE_CODE_OFFSET 68 + #define IN_FLOW_IPV6_3TUPLE_TBL_SERVICE_CODE_LEN 8 + #define IN_FLOW_IPV6_3TUPLE_TBL_SERVICE_CODE_DEFAULT 0x0 + /*[field] IP_PROTOCOL*/ + #define IN_FLOW_IPV6_3TUPLE_TBL_IP_PROTOCOL + #define IN_FLOW_IPV6_3TUPLE_TBL_IP_PROTOCOL_OFFSET 108 + #define IN_FLOW_IPV6_3TUPLE_TBL_IP_PROTOCOL_LEN 8 + #define IN_FLOW_IPV6_3TUPLE_TBL_IP_PROTOCOL_DEFAULT 0x0 + /*[field] IP_ADDR*/ + #define IN_FLOW_IPV6_3TUPLE_TBL_IP_ADDR + #define IN_FLOW_IPV6_3TUPLE_TBL_IP_ADDR_OFFSET 140 + #define IN_FLOW_IPV6_3TUPLE_TBL_IP_ADDR_LEN 128 + #define IN_FLOW_IPV6_3TUPLE_TBL_IP_ADDR_DEFAULT 0x0 + +struct in_flow_3tuple_tbl_3 { + a_uint32_t valid:1; + a_uint32_t entry_type:1; + a_uint32_t host_addr_index_type:1; + a_uint32_t host_addr_index:13; + a_uint32_t protocol_type:2; + a_uint32_t age:2; + a_uint32_t src_l3_if_valid:1; + a_uint32_t src_l3_if:8; + a_uint32_t fwd_type:3; + a_uint32_t next_hop2:12; + a_uint32_t _reserved0:16; + a_uint32_t de_acce:1; + a_uint32_t copy_to_cpu_en:1; + a_uint32_t syn_toggle:1; + a_uint32_t pri_profile_0:1; + a_uint32_t pri_profile_1:4; + a_uint32_t service_code:8; + a_uint32_t ip_addr_0:20; + a_uint32_t ip_addr_1:12; + a_uint32_t ip_protocol:8; + a_uint32_t _reserved1_0:12; + a_uint32_t _reserved1_1:32; +}; + +struct in_flow_3tuple_tbl_1 { + a_uint32_t valid:1; + a_uint32_t entry_type:1; + a_uint32_t host_addr_index_type:1; + a_uint32_t host_addr_index:13; + a_uint32_t protocol_type:2; + a_uint32_t age:2; + a_uint32_t src_l3_if_valid:1; + a_uint32_t src_l3_if:8; + a_uint32_t fwd_type:3; + a_uint32_t port_vp2:8; + a_uint32_t _reserved0:20; + a_uint32_t de_acce:1; + a_uint32_t copy_to_cpu_en:1; + a_uint32_t syn_toggle:1; + a_uint32_t pri_profile_0:1; + a_uint32_t pri_profile_1:4; + a_uint32_t service_code:8; + a_uint32_t ip_addr_0:20; + a_uint32_t ip_addr_1:12; + a_uint32_t ip_protocol:8; + a_uint32_t _reserved1_0:12; + a_uint32_t _reserved1_1:32; +}; + +struct in_flow_3tuple_tbl_2 { + a_uint32_t valid:1; + a_uint32_t entry_type:1; + a_uint32_t host_addr_index_type:1; + a_uint32_t host_addr_index:13; + a_uint32_t protocol_type:2; + a_uint32_t age:2; + a_uint32_t src_l3_if_valid:1; + a_uint32_t src_l3_if:8; + a_uint32_t fwd_type:3; + a_uint32_t next_hop3:12; + a_uint32_t port_vp_valid1:1; + a_uint32_t port_vp1:8; + a_uint32_t _reserved0:7; + a_uint32_t de_acce:1; + a_uint32_t copy_to_cpu_en:1; + a_uint32_t syn_toggle:1; + a_uint32_t pri_profile_0:1; + a_uint32_t pri_profile_1:4; + a_uint32_t service_code:8; + a_uint32_t ip_addr_0:20; + a_uint32_t ip_addr_1:12; + a_uint32_t ip_protocol:8; + a_uint32_t _reserved1_0:12; + a_uint32_t _reserved1_1:32; +}; + +struct in_flow_3tuple_tbl_0 { + a_uint32_t valid:1; + a_uint32_t entry_type:1; + a_uint32_t host_addr_index_type:1; + a_uint32_t host_addr_index:13; + a_uint32_t protocol_type:2; + a_uint32_t age:2; + a_uint32_t src_l3_if_valid:1; + a_uint32_t src_l3_if:8; + a_uint32_t fwd_type:3; + a_uint32_t next_hop1:12; + a_uint32_t _reserved0:16; + a_uint32_t de_acce:1; + a_uint32_t copy_to_cpu_en:1; + a_uint32_t syn_toggle:1; + a_uint32_t pri_profile_0:1; + a_uint32_t pri_profile_1:4; + a_uint32_t service_code:8; + a_uint32_t ip_addr_0:20; + a_uint32_t ip_addr_1:12; + a_uint32_t ip_protocol:8; + a_uint32_t _reserved1_0:12; + a_uint32_t _reserved1_1:32; +}; + +union in_flow_3tuple_tbl_u { + a_uint32_t val[5]; + struct in_flow_3tuple_tbl_0 bf0; + struct in_flow_3tuple_tbl_1 bf1; + struct in_flow_3tuple_tbl_2 bf2; + struct in_flow_3tuple_tbl_3 bf3; +}; + +/*[table] IN_FLOW_IPV6_5TUPLE_TBL*/ +#define IN_FLOW_IPV6_5TUPLE_TBL +#define IN_FLOW_IPV6_5TUPLE_TBL_ADDRESS 0x40000 +#define IN_FLOW_IPV6_5TUPLE_TBL_NUM 2048 +#define IN_FLOW_IPV6_5TUPLE_TBL_INC 0x40 +#define IN_FLOW_IPV6_5TUPLE_TBL_TYPE REG_TYPE_RW +#define IN_FLOW_IPV6_5TUPLE_TBL_DEFAULT 0x0 + /*[field] VALID*/ + #define IN_FLOW_IPV6_5TUPLE_TBL_VALID + #define IN_FLOW_IPV6_5TUPLE_TBL_VALID_OFFSET 0 + #define IN_FLOW_IPV6_5TUPLE_TBL_VALID_LEN 1 + #define IN_FLOW_IPV6_5TUPLE_TBL_VALID_DEFAULT 0x0 + /*[field] ENTRY_TYPE*/ + #define IN_FLOW_IPV6_5TUPLE_TBL_ENTRY_TYPE + #define IN_FLOW_IPV6_5TUPLE_TBL_ENTRY_TYPE_OFFSET 1 + #define IN_FLOW_IPV6_5TUPLE_TBL_ENTRY_TYPE_LEN 1 + #define IN_FLOW_IPV6_5TUPLE_TBL_ENTRY_TYPE_DEFAULT 0x0 + /*[field] HOST_ADDR_INDEX_TYPE*/ + #define IN_FLOW_IPV6_5TUPLE_TBL_HOST_ADDR_INDEX_TYPE + #define IN_FLOW_IPV6_5TUPLE_TBL_HOST_ADDR_INDEX_TYPE_OFFSET 2 + #define IN_FLOW_IPV6_5TUPLE_TBL_HOST_ADDR_INDEX_TYPE_LEN 1 + #define IN_FLOW_IPV6_5TUPLE_TBL_HOST_ADDR_INDEX_TYPE_DEFAULT 0x0 + /*[field] HOST_ADDR_INDEX*/ + #define IN_FLOW_IPV6_5TUPLE_TBL_HOST_ADDR_INDEX + #define IN_FLOW_IPV6_5TUPLE_TBL_HOST_ADDR_INDEX_OFFSET 3 + #define IN_FLOW_IPV6_5TUPLE_TBL_HOST_ADDR_INDEX_LEN 13 + #define IN_FLOW_IPV6_5TUPLE_TBL_HOST_ADDR_INDEX_DEFAULT 0x0 + /*[field] PROTOCOL_TYPE*/ + #define IN_FLOW_IPV6_5TUPLE_TBL_PROTOCOL_TYPE + #define IN_FLOW_IPV6_5TUPLE_TBL_PROTOCOL_TYPE_OFFSET 16 + #define IN_FLOW_IPV6_5TUPLE_TBL_PROTOCOL_TYPE_LEN 2 + #define IN_FLOW_IPV6_5TUPLE_TBL_PROTOCOL_TYPE_DEFAULT 0x0 + /*[field] AGE*/ + #define IN_FLOW_IPV6_5TUPLE_TBL_AGE + #define IN_FLOW_IPV6_5TUPLE_TBL_AGE_OFFSET 18 + #define IN_FLOW_IPV6_5TUPLE_TBL_AGE_LEN 2 + #define IN_FLOW_IPV6_5TUPLE_TBL_AGE_DEFAULT 0x0 + /*[field] SRC_L3_IF_VALID*/ + #define IN_FLOW_IPV6_5TUPLE_TBL_SRC_L3_IF_VALID + #define IN_FLOW_IPV6_5TUPLE_TBL_SRC_L3_IF_VALID_OFFSET 20 + #define IN_FLOW_IPV6_5TUPLE_TBL_SRC_L3_IF_VALID_LEN 1 + #define IN_FLOW_IPV6_5TUPLE_TBL_SRC_L3_IF_VALID_DEFAULT 0x0 + /*[field] SRC_L3_IF*/ + #define IN_FLOW_IPV6_5TUPLE_TBL_SRC_L3_IF + #define IN_FLOW_IPV6_5TUPLE_TBL_SRC_L3_IF_OFFSET 21 + #define IN_FLOW_IPV6_5TUPLE_TBL_SRC_L3_IF_LEN 8 + #define IN_FLOW_IPV6_5TUPLE_TBL_SRC_L3_IF_DEFAULT 0x0 + /*[field] FWD_TYPE*/ + #define IN_FLOW_IPV6_5TUPLE_TBL_FWD_TYPE + #define IN_FLOW_IPV6_5TUPLE_TBL_FWD_TYPE_OFFSET 29 + #define IN_FLOW_IPV6_5TUPLE_TBL_FWD_TYPE_LEN 3 + #define IN_FLOW_IPV6_5TUPLE_TBL_FWD_TYPE_DEFAULT 0x0 + /*[field] NEXT_HOP2 reuse FWD_TYPE[3]*/ + #define IN_FLOW_IPV6_5TUPLE_TBL_NEXT_HOP2 + #define IN_FLOW_IPV6_5TUPLE_TBL_NEXT_HOP2_OFFSET 32 + #define IN_FLOW_IPV6_5TUPLE_TBL_NEXT_HOP2_LEN 12 + #define IN_FLOW_IPV6_5TUPLE_TBL_NEXT_HOP2_DEFAULT 0x0 + /*[field] PORT_VP2 reuse FWD_TYPE[1]*/ + #define IN_FLOW_IPV6_5TUPLE_TBL_PORT_VP2 + #define IN_FLOW_IPV6_5TUPLE_TBL_PORT_VP2_OFFSET 32 + #define IN_FLOW_IPV6_5TUPLE_TBL_PORT_VP2_LEN 8 + #define IN_FLOW_IPV6_5TUPLE_TBL_PORT_VP2_DEFAULT 0x0 + /*[field] NEXT_HOP3 reuse FWD_TYPE[2]*/ + #define IN_FLOW_IPV6_5TUPLE_TBL_NEXT_HOP3 + #define IN_FLOW_IPV6_5TUPLE_TBL_NEXT_HOP3_OFFSET 32 + #define IN_FLOW_IPV6_5TUPLE_TBL_NEXT_HOP3_LEN 12 + #define IN_FLOW_IPV6_5TUPLE_TBL_NEXT_HOP3_DEFAULT 0x0 + /*[field] NEXT_HOP1 reuse FWD_TYPE[0]*/ + #define IN_FLOW_IPV6_5TUPLE_TBL_NEXT_HOP1 + #define IN_FLOW_IPV6_5TUPLE_TBL_NEXT_HOP1_OFFSET 32 + #define IN_FLOW_IPV6_5TUPLE_TBL_NEXT_HOP1_LEN 12 + #define IN_FLOW_IPV6_5TUPLE_TBL_NEXT_HOP1_DEFAULT 0x0 + /*[field] PORT_VP_VALID1 reuse FWD_TYPE[2]*/ + #define IN_FLOW_IPV6_5TUPLE_TBL_PORT_VP_VALID1 + #define IN_FLOW_IPV6_5TUPLE_TBL_PORT_VP_VALID1_OFFSET 44 + #define IN_FLOW_IPV6_5TUPLE_TBL_PORT_VP_VALID1_LEN 1 + #define IN_FLOW_IPV6_5TUPLE_TBL_PORT_VP_VALID1_DEFAULT 0x0 + /*[field] PORT_VP1 reuse FWD_TYPE[2]*/ + #define IN_FLOW_IPV6_5TUPLE_TBL_PORT_VP1 + #define IN_FLOW_IPV6_5TUPLE_TBL_PORT_VP1_OFFSET 45 + #define IN_FLOW_IPV6_5TUPLE_TBL_PORT_VP1_LEN 8 + #define IN_FLOW_IPV6_5TUPLE_TBL_PORT_VP1_DEFAULT 0x0 + /*[field] DE_ACCE*/ + #define IN_FLOW_IPV6_5TUPLE_TBL_DE_ACCE + #define IN_FLOW_IPV6_5TUPLE_TBL_DE_ACCE_OFFSET 60 + #define IN_FLOW_IPV6_5TUPLE_TBL_DE_ACCE_LEN 1 + #define IN_FLOW_IPV6_5TUPLE_TBL_DE_ACCE_DEFAULT 0x0 + /*[field] COPY_TO_CPU_EN*/ + #define IN_FLOW_IPV6_5TUPLE_TBL_COPY_TO_CPU_EN + #define IN_FLOW_IPV6_5TUPLE_TBL_COPY_TO_CPU_EN_OFFSET 61 + #define IN_FLOW_IPV6_5TUPLE_TBL_COPY_TO_CPU_EN_LEN 1 + #define IN_FLOW_IPV6_5TUPLE_TBL_COPY_TO_CPU_EN_DEFAULT 0x0 + /*[field] SYN_TOGGLE*/ + #define IN_FLOW_IPV6_5TUPLE_TBL_SYN_TOGGLE + #define IN_FLOW_IPV6_5TUPLE_TBL_SYN_TOGGLE_OFFSET 62 + #define IN_FLOW_IPV6_5TUPLE_TBL_SYN_TOGGLE_LEN 1 + #define IN_FLOW_IPV6_5TUPLE_TBL_SYN_TOGGLE_DEFAULT 0x0 + /*[field] PRI_PROFILE*/ + #define IN_FLOW_IPV6_5TUPLE_TBL_PRI_PROFILE + #define IN_FLOW_IPV6_5TUPLE_TBL_PRI_PROFILE_OFFSET 63 + #define IN_FLOW_IPV6_5TUPLE_TBL_PRI_PROFILE_LEN 5 + #define IN_FLOW_IPV6_5TUPLE_TBL_PRI_PROFILE_DEFAULT 0x0 + /*[field] SERVICE_CODE*/ + #define IN_FLOW_IPV6_5TUPLE_TBL_SERVICE_CODE + #define IN_FLOW_IPV6_5TUPLE_TBL_SERVICE_CODE_OFFSET 68 + #define IN_FLOW_IPV6_5TUPLE_TBL_SERVICE_CODE_LEN 8 + #define IN_FLOW_IPV6_5TUPLE_TBL_SERVICE_CODE_DEFAULT 0x0 + /*[field] L4_SPORT*/ + #define IN_FLOW_IPV6_5TUPLE_TBL_L4_SPORT + #define IN_FLOW_IPV6_5TUPLE_TBL_L4_SPORT_OFFSET 108 + #define IN_FLOW_IPV6_5TUPLE_TBL_L4_SPORT_LEN 16 + #define IN_FLOW_IPV6_5TUPLE_TBL_L4_SPORT_DEFAULT 0x0 + /*[field] L4_DPORT*/ + #define IN_FLOW_IPV6_5TUPLE_TBL_L4_DPORT + #define IN_FLOW_IPV6_5TUPLE_TBL_L4_DPORT_OFFSET 124 + #define IN_FLOW_IPV6_5TUPLE_TBL_L4_DPORT_LEN 16 + #define IN_FLOW_IPV6_5TUPLE_TBL_L4_DPORT_DEFAULT 0x0 + /*[field] IP_ADDR*/ + #define IN_FLOW_IPV6_5TUPLE_TBL_IP_ADDR + #define IN_FLOW_IPV6_5TUPLE_TBL_IP_ADDR_OFFSET 140 + #define IN_FLOW_IPV6_5TUPLE_TBL_IP_ADDR_LEN 128 + #define IN_FLOW_IPV6_5TUPLE_TBL_IP_ADDR_DEFAULT 0x0 + +struct in_flow_ipv6_5tuple_tbl_1 { + a_uint32_t valid:1; + a_uint32_t entry_type:1; + a_uint32_t host_addr_index_type:1; + a_uint32_t host_addr_index:13; + a_uint32_t protocol_type:2; + a_uint32_t age:2; + a_uint32_t src_l3_if_valid:1; + a_uint32_t src_l3_if:8; + a_uint32_t fwd_type:3; + a_uint32_t port_vp2:8; + a_uint32_t _reserved0:20; + a_uint32_t de_acce:1; + a_uint32_t copy_to_cpu_en:1; + a_uint32_t syn_toggle:1; + a_uint32_t pri_profile_0:1; + a_uint32_t pri_profile_1:4; + a_uint32_t service_code:8; + a_uint32_t _reserved1_0:20; + a_uint32_t _reserved1_1:12; + a_uint32_t l4_sport:16; + a_uint32_t l4_dport_0:4; + a_uint32_t l4_dport_1:12; + a_uint32_t ip_addr_0:20; + a_uint32_t ip_addr_1:32; + a_uint32_t ip_addr_2:32; + a_uint32_t ip_addr_3:32; + a_uint32_t ip_addr_4:12; + a_uint32_t _reserved2:20; +}; + +struct in_flow_ipv6_5tuple_tbl_0 { + a_uint32_t valid:1; + a_uint32_t entry_type:1; + a_uint32_t host_addr_index_type:1; + a_uint32_t host_addr_index:13; + a_uint32_t protocol_type:2; + a_uint32_t age:2; + a_uint32_t src_l3_if_valid:1; + a_uint32_t src_l3_if:8; + a_uint32_t fwd_type:3; + a_uint32_t next_hop1:12; + a_uint32_t _reserved0:16; + a_uint32_t de_acce:1; + a_uint32_t copy_to_cpu_en:1; + a_uint32_t syn_toggle:1; + a_uint32_t pri_profile_0:1; + a_uint32_t pri_profile_1:4; + a_uint32_t service_code:8; + a_uint32_t _reserved1_0:20; + a_uint32_t _reserved1_1:12; + a_uint32_t l4_sport:16; + a_uint32_t l4_dport_0:4; + a_uint32_t l4_dport_1:12; + a_uint32_t ip_addr_0:20; + a_uint32_t ip_addr_1:32; + a_uint32_t ip_addr_2:32; + a_uint32_t ip_addr_3:32; + a_uint32_t ip_addr_4:12; + a_uint32_t _reserved2:20; +}; + +struct in_flow_ipv6_5tuple_tbl_2 { + a_uint32_t valid:1; + a_uint32_t entry_type:1; + a_uint32_t host_addr_index_type:1; + a_uint32_t host_addr_index:13; + a_uint32_t protocol_type:2; + a_uint32_t age:2; + a_uint32_t src_l3_if_valid:1; + a_uint32_t src_l3_if:8; + a_uint32_t fwd_type:3; + a_uint32_t next_hop3:12; + a_uint32_t port_vp_valid1:1; + a_uint32_t port_vp1:8; + a_uint32_t _reserved0:7; + a_uint32_t de_acce:1; + a_uint32_t copy_to_cpu_en:1; + a_uint32_t syn_toggle:1; + a_uint32_t pri_profile_0:1; + a_uint32_t pri_profile_1:4; + a_uint32_t service_code:8; + a_uint32_t _reserved1_0:20; + a_uint32_t _reserved1_1:12; + a_uint32_t l4_sport:16; + a_uint32_t l4_dport_0:4; + a_uint32_t l4_dport_1:12; + a_uint32_t ip_addr_0:20; + a_uint32_t ip_addr_1:32; + a_uint32_t ip_addr_2:32; + a_uint32_t ip_addr_3:32; + a_uint32_t ip_addr_4:12; + a_uint32_t _reserved2:20; +}; + +struct in_flow_ipv6_5tuple_tbl_3 { + a_uint32_t valid:1; + a_uint32_t entry_type:1; + a_uint32_t host_addr_index_type:1; + a_uint32_t host_addr_index:13; + a_uint32_t protocol_type:2; + a_uint32_t age:2; + a_uint32_t src_l3_if_valid:1; + a_uint32_t src_l3_if:8; + a_uint32_t fwd_type:3; + a_uint32_t next_hop2:12; + a_uint32_t _reserved0:16; + a_uint32_t de_acce:1; + a_uint32_t copy_to_cpu_en:1; + a_uint32_t syn_toggle:1; + a_uint32_t pri_profile_0:1; + a_uint32_t pri_profile_1:4; + a_uint32_t service_code:8; + a_uint32_t _reserved1_0:20; + a_uint32_t _reserved1_1:12; + a_uint32_t l4_sport:16; + a_uint32_t l4_dport_0:4; + a_uint32_t l4_dport_1:12; + a_uint32_t ip_addr_0:20; + a_uint32_t ip_addr_1:32; + a_uint32_t ip_addr_2:32; + a_uint32_t ip_addr_3:32; + a_uint32_t ip_addr_4:12; + a_uint32_t _reserved2:20; +}; + +union in_flow_ipv6_5tuple_tbl_u { + a_uint32_t val[9]; + struct in_flow_ipv6_5tuple_tbl_0 bf0; + struct in_flow_ipv6_5tuple_tbl_1 bf1; + struct in_flow_ipv6_5tuple_tbl_2 bf2; + struct in_flow_ipv6_5tuple_tbl_3 bf3; +}; + +/*[table] IN_FLOW_TBL*/ +#define IN_FLOW_TBL +#define IN_FLOW_TBL_ADDRESS 0x40000 +#define IN_FLOW_TBL_NUM 4096 +#define IN_FLOW_TBL_INC 0x20 +#define IN_FLOW_TBL_TYPE REG_TYPE_RW +#define IN_FLOW_TBL_DEFAULT 0x0 + /*[field] VALID*/ + #define IN_FLOW_TBL_VALID + #define IN_FLOW_TBL_VALID_OFFSET 0 + #define IN_FLOW_TBL_VALID_LEN 1 + #define IN_FLOW_TBL_VALID_DEFAULT 0x0 + /*[field] ENTRY_TYPE*/ + #define IN_FLOW_TBL_ENTRY_TYPE + #define IN_FLOW_TBL_ENTRY_TYPE_OFFSET 1 + #define IN_FLOW_TBL_ENTRY_TYPE_LEN 1 + #define IN_FLOW_TBL_ENTRY_TYPE_DEFAULT 0x0 + /*[field] HOST_ADDR_INDEX_TYPE*/ + #define IN_FLOW_TBL_HOST_ADDR_INDEX_TYPE + #define IN_FLOW_TBL_HOST_ADDR_INDEX_TYPE_OFFSET 2 + #define IN_FLOW_TBL_HOST_ADDR_INDEX_TYPE_LEN 1 + #define IN_FLOW_TBL_HOST_ADDR_INDEX_TYPE_DEFAULT 0x0 + /*[field] HOST_ADDR_INDEX*/ + #define IN_FLOW_TBL_HOST_ADDR_INDEX + #define IN_FLOW_TBL_HOST_ADDR_INDEX_OFFSET 3 + #define IN_FLOW_TBL_HOST_ADDR_INDEX_LEN 13 + #define IN_FLOW_TBL_HOST_ADDR_INDEX_DEFAULT 0x0 + /*[field] PROTOCOL_TYPE*/ + #define IN_FLOW_TBL_PROTOCOL_TYPE + #define IN_FLOW_TBL_PROTOCOL_TYPE_OFFSET 16 + #define IN_FLOW_TBL_PROTOCOL_TYPE_LEN 2 + #define IN_FLOW_TBL_PROTOCOL_TYPE_DEFAULT 0x0 + /*[field] AGE*/ + #define IN_FLOW_TBL_AGE + #define IN_FLOW_TBL_AGE_OFFSET 18 + #define IN_FLOW_TBL_AGE_LEN 2 + #define IN_FLOW_TBL_AGE_DEFAULT 0x0 + /*[field] SRC_L3_IF_VALID*/ + #define IN_FLOW_TBL_SRC_L3_IF_VALID + #define IN_FLOW_TBL_SRC_L3_IF_VALID_OFFSET 20 + #define IN_FLOW_TBL_SRC_L3_IF_VALID_LEN 1 + #define IN_FLOW_TBL_SRC_L3_IF_VALID_DEFAULT 0x0 + /*[field] SRC_L3_IF*/ + #define IN_FLOW_TBL_SRC_L3_IF + #define IN_FLOW_TBL_SRC_L3_IF_OFFSET 21 + #define IN_FLOW_TBL_SRC_L3_IF_LEN 8 + #define IN_FLOW_TBL_SRC_L3_IF_DEFAULT 0x0 + /*[field] FWD_TYPE*/ + #define IN_FLOW_TBL_FWD_TYPE + #define IN_FLOW_TBL_FWD_TYPE_OFFSET 29 + #define IN_FLOW_TBL_FWD_TYPE_LEN 3 + #define IN_FLOW_TBL_FWD_TYPE_DEFAULT 0x0 + /*[field] PORT_VP2 reuse FWD_TYPE[1]*/ + #define IN_FLOW_TBL_PORT_VP2 + #define IN_FLOW_TBL_PORT_VP2_OFFSET 32 + #define IN_FLOW_TBL_PORT_VP2_LEN 8 + #define IN_FLOW_TBL_PORT_VP2_DEFAULT 0x0 + /*[field] NEXT_HOP2 reuse FWD_TYPE[3]*/ + #define IN_FLOW_TBL_NEXT_HOP2 + #define IN_FLOW_TBL_NEXT_HOP2_OFFSET 32 + #define IN_FLOW_TBL_NEXT_HOP2_LEN 12 + #define IN_FLOW_TBL_NEXT_HOP2_DEFAULT 0x0 + /*[field] NEXT_HOP3 reuse FWD_TYPE[2]*/ + #define IN_FLOW_TBL_NEXT_HOP3 + #define IN_FLOW_TBL_NEXT_HOP3_OFFSET 32 + #define IN_FLOW_TBL_NEXT_HOP3_LEN 12 + #define IN_FLOW_TBL_NEXT_HOP3_DEFAULT 0x0 + /*[field] NEXT_HOP1 reuse FWD_TYPE[0]*/ + #define IN_FLOW_TBL_NEXT_HOP1 + #define IN_FLOW_TBL_NEXT_HOP1_OFFSET 32 + #define IN_FLOW_TBL_NEXT_HOP1_LEN 12 + #define IN_FLOW_TBL_NEXT_HOP1_DEFAULT 0x0 + /*[field] L4_PORT2 reuse FWD_TYPE[3]*/ + #define IN_FLOW_TBL_L4_PORT2 + #define IN_FLOW_TBL_L4_PORT2_OFFSET 44 + #define IN_FLOW_TBL_L4_PORT2_LEN 16 + #define IN_FLOW_TBL_L4_PORT2_DEFAULT 0x0 + /*[field] PORT_VP_VALID1 reuse FWD_TYPE[2]*/ + #define IN_FLOW_TBL_PORT_VP_VALID1 + #define IN_FLOW_TBL_PORT_VP_VALID1_OFFSET 44 + #define IN_FLOW_TBL_PORT_VP_VALID1_LEN 1 + #define IN_FLOW_TBL_PORT_VP_VALID1_DEFAULT 0x0 + /*[field] L4_PORT1 reuse FWD_TYPE[0]*/ + #define IN_FLOW_TBL_L4_PORT1 + #define IN_FLOW_TBL_L4_PORT1_OFFSET 44 + #define IN_FLOW_TBL_L4_PORT1_LEN 16 + #define IN_FLOW_TBL_L4_PORT1_DEFAULT 0x0 + /*[field] PORT_VP1 reuse FWD_TYPE[2]*/ + #define IN_FLOW_TBL_PORT_VP1 + #define IN_FLOW_TBL_PORT_VP1_OFFSET 45 + #define IN_FLOW_TBL_PORT_VP1_LEN 8 + #define IN_FLOW_TBL_PORT_VP1_DEFAULT 0x0 + /*[field] DE_ACCE*/ + #define IN_FLOW_TBL_DE_ACCE + #define IN_FLOW_TBL_DE_ACCE_OFFSET 60 + #define IN_FLOW_TBL_DE_ACCE_LEN 1 + #define IN_FLOW_TBL_DE_ACCE_DEFAULT 0x0 + /*[field] COPY_TO_CPU_EN*/ + #define IN_FLOW_TBL_COPY_TO_CPU_EN + #define IN_FLOW_TBL_COPY_TO_CPU_EN_OFFSET 61 + #define IN_FLOW_TBL_COPY_TO_CPU_EN_LEN 1 + #define IN_FLOW_TBL_COPY_TO_CPU_EN_DEFAULT 0x0 + /*[field] SYN_TOGGLE*/ + #define IN_FLOW_TBL_SYN_TOGGLE + #define IN_FLOW_TBL_SYN_TOGGLE_OFFSET 62 + #define IN_FLOW_TBL_SYN_TOGGLE_LEN 1 + #define IN_FLOW_TBL_SYN_TOGGLE_DEFAULT 0x0 + /*[field] PRI_PROFILE*/ + #define IN_FLOW_TBL_PRI_PROFILE + #define IN_FLOW_TBL_PRI_PROFILE_OFFSET 63 + #define IN_FLOW_TBL_PRI_PROFILE_LEN 5 + #define IN_FLOW_TBL_PRI_PROFILE_DEFAULT 0x0 + /*[field] SERVICE_CODE*/ + #define IN_FLOW_TBL_SERVICE_CODE + #define IN_FLOW_TBL_SERVICE_CODE_OFFSET 68 + #define IN_FLOW_TBL_SERVICE_CODE_LEN 8 + #define IN_FLOW_TBL_SERVICE_CODE_DEFAULT 0x0 + /*[field] IP_ADDR*/ + #define IN_FLOW_TBL_IP_ADDR + #define IN_FLOW_TBL_IP_ADDR_OFFSET 76 + #define IN_FLOW_TBL_IP_ADDR_LEN 32 + #define IN_FLOW_TBL_IP_ADDR_DEFAULT 0x0 + /*[field] L4_SPORT*/ + #define IN_FLOW_TBL_L4_SPORT + #define IN_FLOW_TBL_L4_SPORT_OFFSET 108 + #define IN_FLOW_TBL_L4_SPORT_LEN 16 + #define IN_FLOW_TBL_L4_SPORT_DEFAULT 0x0 + /*[field] L4_DPORT*/ + #define IN_FLOW_TBL_L4_DPORT + #define IN_FLOW_TBL_L4_DPORT_OFFSET 124 + #define IN_FLOW_TBL_L4_DPORT_LEN 16 + #define IN_FLOW_TBL_L4_DPORT_DEFAULT 0x0 + +struct in_flow_ipv6_3tuple_tbl_3 { + a_uint32_t valid:1; + a_uint32_t entry_type:1; + a_uint32_t host_addr_index_type:1; + a_uint32_t host_addr_index:13; + a_uint32_t protocol_type:2; + a_uint32_t age:2; + a_uint32_t src_l3_if_valid:1; + a_uint32_t src_l3_if:8; + a_uint32_t fwd_type:3; + a_uint32_t next_hop2:12; + a_uint32_t _reserved0:16; + a_uint32_t de_acce:1; + a_uint32_t copy_to_cpu_en:1; + a_uint32_t syn_toggle:1; + a_uint32_t pri_profile_0:1; + a_uint32_t pri_profile_1:4; + a_uint32_t service_code:8; + a_uint32_t _reserved1_0:20; + a_uint32_t _reserved1_1:12; + a_uint32_t ip_protocol:8; + a_uint32_t _reserved2_0:12; + a_uint32_t _reserved2_1:12; + a_uint32_t ip_addr_0:20; + a_uint32_t ip_addr_1:32; + a_uint32_t ip_addr_2:32; + a_uint32_t ip_addr_3:32; + a_uint32_t ip_addr_4:12; + a_uint32_t _reserved3:20; +}; + +struct in_flow_ipv6_3tuple_tbl_1 { + a_uint32_t valid:1; + a_uint32_t entry_type:1; + a_uint32_t host_addr_index_type:1; + a_uint32_t host_addr_index:13; + a_uint32_t protocol_type:2; + a_uint32_t age:2; + a_uint32_t src_l3_if_valid:1; + a_uint32_t src_l3_if:8; + a_uint32_t fwd_type:3; + a_uint32_t next_hop1:12; + a_uint32_t _reserved0:16; + a_uint32_t de_acce:1; + a_uint32_t copy_to_cpu_en:1; + a_uint32_t syn_toggle:1; + a_uint32_t pri_profile_0:1; + a_uint32_t pri_profile_1:4; + a_uint32_t service_code:8; + a_uint32_t _reserved1_0:20; + a_uint32_t _reserved1_1:12; + a_uint32_t ip_protocol:8; + a_uint32_t _reserved2_0:12; + a_uint32_t _reserved2_1:12; + a_uint32_t ip_addr_0:20; + a_uint32_t ip_addr_1:32; + a_uint32_t ip_addr_2:32; + a_uint32_t ip_addr_3:32; + a_uint32_t ip_addr_4:12; + a_uint32_t _reserved3:20; +}; + +struct in_flow_ipv6_3tuple_tbl_0 { + a_uint32_t valid:1; + a_uint32_t entry_type:1; + a_uint32_t host_addr_index_type:1; + a_uint32_t host_addr_index:13; + a_uint32_t protocol_type:2; + a_uint32_t age:2; + a_uint32_t src_l3_if_valid:1; + a_uint32_t src_l3_if:8; + a_uint32_t fwd_type:3; + a_uint32_t port_vp2:8; + a_uint32_t _reserved0:20; + a_uint32_t de_acce:1; + a_uint32_t copy_to_cpu_en:1; + a_uint32_t syn_toggle:1; + a_uint32_t pri_profile_0:1; + a_uint32_t pri_profile_1:4; + a_uint32_t service_code:8; + a_uint32_t _reserved1_0:20; + a_uint32_t _reserved1_1:12; + a_uint32_t ip_protocol:8; + a_uint32_t _reserved2_0:12; + a_uint32_t _reserved2_1:12; + a_uint32_t ip_addr_0:20; + a_uint32_t ip_addr_1:32; + a_uint32_t ip_addr_2:32; + a_uint32_t ip_addr_3:32; + a_uint32_t ip_addr_4:12; + a_uint32_t _reserved3:20; +}; + +struct in_flow_ipv6_3tuple_tbl_2 { + a_uint32_t valid:1; + a_uint32_t entry_type:1; + a_uint32_t host_addr_index_type:1; + a_uint32_t host_addr_index:13; + a_uint32_t protocol_type:2; + a_uint32_t age:2; + a_uint32_t src_l3_if_valid:1; + a_uint32_t src_l3_if:8; + a_uint32_t fwd_type:3; + a_uint32_t next_hop3:12; + a_uint32_t port_vp_valid1:1; + a_uint32_t port_vp1:8; + a_uint32_t _reserved0:7; + a_uint32_t de_acce:1; + a_uint32_t copy_to_cpu_en:1; + a_uint32_t syn_toggle:1; + a_uint32_t pri_profile_0:1; + a_uint32_t pri_profile_1:4; + a_uint32_t service_code:8; + a_uint32_t _reserved1_0:20; + a_uint32_t _reserved1_1:12; + a_uint32_t ip_protocol:8; + a_uint32_t _reserved2_0:12; + a_uint32_t _reserved2_1:12; + a_uint32_t ip_addr_0:20; + a_uint32_t ip_addr_1:32; + a_uint32_t ip_addr_2:32; + a_uint32_t ip_addr_3:32; + a_uint32_t ip_addr_4:12; + a_uint32_t _reserved3:20; +}; + +union in_flow_ipv6_3tuple_tbl_u { + a_uint32_t val[9]; + struct in_flow_ipv6_3tuple_tbl_0 bf0; + struct in_flow_ipv6_3tuple_tbl_1 bf1; + struct in_flow_ipv6_3tuple_tbl_2 bf2; + struct in_flow_ipv6_3tuple_tbl_3 bf3; +}; + +/*[table] EG_FLOW_TREE_MAP_TBL*/ +#define EG_FLOW_TREE_MAP_TBL +#define EG_FLOW_TREE_MAP_TBL_ADDRESS 0x8000 +#define EG_FLOW_TREE_MAP_TBL_NUM 4096 +#define EG_FLOW_TREE_MAP_TBL_INC 0x4 +#define EG_FLOW_TREE_MAP_TBL_TYPE REG_TYPE_RW +#define EG_FLOW_TREE_MAP_TBL_DEFAULT 0x0 + /*[field] TREE_ID*/ + #define EG_FLOW_TREE_MAP_TBL_TREE_ID + #define EG_FLOW_TREE_MAP_TBL_TREE_ID_OFFSET 0 + #define EG_FLOW_TREE_MAP_TBL_TREE_ID_LEN 24 + #define EG_FLOW_TREE_MAP_TBL_TREE_ID_DEFAULT 0x0 + +struct eg_flow_tree_map_tbl { + a_uint32_t tree_id:24; + a_uint32_t _reserved0:8; +}; + +union eg_flow_tree_map_tbl_u { + a_uint32_t val; + struct eg_flow_tree_map_tbl bf; +}; + +/*[table] IN_FLOW_CNT_TBL*/ +#define IN_FLOW_CNT_TBL +#define IN_FLOW_CNT_TBL_ADDRESS 0x20000 +#define IN_FLOW_CNT_TBL_NUM 4096 +#define IN_FLOW_CNT_TBL_INC 0x10 +#define IN_FLOW_CNT_TBL_TYPE REG_TYPE_RW +#define IN_FLOW_CNT_TBL_DEFAULT 0x0 + /*[field] HIT_PKT_COUNTER*/ + #define IN_FLOW_CNT_TBL_HIT_PKT_COUNTER + #define IN_FLOW_CNT_TBL_HIT_PKT_COUNTER_OFFSET 0 + #define IN_FLOW_CNT_TBL_HIT_PKT_COUNTER_LEN 32 + #define IN_FLOW_CNT_TBL_HIT_PKT_COUNTER_DEFAULT 0x0 + /*[field] HIT_BYTE_COUNTER*/ + #define IN_FLOW_CNT_TBL_HIT_BYTE_COUNTER + #define IN_FLOW_CNT_TBL_HIT_BYTE_COUNTER_OFFSET 32 + #define IN_FLOW_CNT_TBL_HIT_BYTE_COUNTER_LEN 40 + #define IN_FLOW_CNT_TBL_HIT_BYTE_COUNTER_DEFAULT 0x0 + +struct in_flow_cnt_tbl { + a_uint32_t hit_pkt_counter:32; + a_uint32_t hit_byte_counter_0:32; + a_uint32_t hit_byte_counter_1:8; + a_uint32_t _reserved0:24; +}; + +union in_flow_cnt_tbl_u { + a_uint32_t val[3]; + struct in_flow_cnt_tbl bf; +}; + +#endif \ No newline at end of file diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_global.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_global.h new file mode 100755 index 000000000..def29f93e --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_global.h @@ -0,0 +1,1204 @@ +/* + * 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 + * @{ + */ +#ifndef _HPPE_GLOBAL_H_ +#define _HPPE_GLOBAL_H_ + +sw_error_t +hppe_switch_id_get( + a_uint32_t dev_id, + union switch_id_u *value); + +sw_error_t +hppe_switch_id_set( + a_uint32_t dev_id, + union switch_id_u *value); + +sw_error_t +hppe_rgmii_ctrl_get( + a_uint32_t dev_id, + union rgmii_ctrl_u *value); + +sw_error_t +hppe_rgmii_ctrl_set( + a_uint32_t dev_id, + union rgmii_ctrl_u *value); + +sw_error_t +hppe_clk_gating_ctrl_get( + a_uint32_t dev_id, + union clk_gating_ctrl_u *value); + +sw_error_t +hppe_clk_gating_ctrl_set( + a_uint32_t dev_id, + union clk_gating_ctrl_u *value); + +sw_error_t +hppe_port_mux_ctrl_get( + a_uint32_t dev_id, + union port_mux_ctrl_u *value); + +sw_error_t +hppe_port_mux_ctrl_set( + a_uint32_t dev_id, + union port_mux_ctrl_u *value); + +sw_error_t +cppe_port_mux_ctrl_get( + a_uint32_t dev_id, + union cppe_port_mux_ctrl_u *value); + +sw_error_t +cppe_port_mux_ctrl_set( + a_uint32_t dev_id, + union cppe_port_mux_ctrl_u *value); + +sw_error_t +hppe_module_ini_done_int_get( + a_uint32_t dev_id, + union module_ini_done_int_u *value); + +sw_error_t +hppe_module_ini_done_int_set( + a_uint32_t dev_id, + union module_ini_done_int_u *value); + +sw_error_t +hppe_module_cpu_done_int_get( + a_uint32_t dev_id, + union module_cpu_done_int_u *value); + +sw_error_t +hppe_module_cpu_done_int_set( + a_uint32_t dev_id, + union module_cpu_done_int_u *value); + +sw_error_t +hppe_port_link_int_get( + a_uint32_t dev_id, + union port_link_int_u *value); + +sw_error_t +hppe_port_link_int_set( + a_uint32_t dev_id, + union port_link_int_u *value); + +sw_error_t +hppe_module_ini_done_int_mask_get( + a_uint32_t dev_id, + union module_ini_done_int_mask_u *value); + +sw_error_t +hppe_module_ini_done_int_mask_set( + a_uint32_t dev_id, + union module_ini_done_int_mask_u *value); + +sw_error_t +hppe_module_cpu_done_int_mask_get( + a_uint32_t dev_id, + union module_cpu_done_int_mask_u *value); + +sw_error_t +hppe_module_cpu_done_int_mask_set( + a_uint32_t dev_id, + union module_cpu_done_int_mask_u *value); + +sw_error_t +hppe_port_link_int_mask_get( + a_uint32_t dev_id, + union port_link_int_mask_u *value); + +sw_error_t +hppe_port_link_int_mask_set( + a_uint32_t dev_id, + union port_link_int_mask_u *value); + +sw_error_t +hppe_port_phy_status_0_get( + a_uint32_t dev_id, + union port_phy_status_0_u *value); + +sw_error_t +hppe_port_phy_status_0_set( + a_uint32_t dev_id, + union port_phy_status_0_u *value); + +sw_error_t +hppe_port_phy_status_1_get( + a_uint32_t dev_id, + union port_phy_status_1_u *value); + +sw_error_t +hppe_port_phy_status_1_set( + a_uint32_t dev_id, + union port_phy_status_1_u *value); + +sw_error_t +hppe_port1_status_get( + a_uint32_t dev_id, + union port1_status_u *value); + +sw_error_t +hppe_port1_status_set( + a_uint32_t dev_id, + union port1_status_u *value); + +sw_error_t +hppe_port2_status_get( + a_uint32_t dev_id, + union port2_status_u *value); + +sw_error_t +hppe_port2_status_set( + a_uint32_t dev_id, + union port2_status_u *value); + +sw_error_t +hppe_port3_status_get( + a_uint32_t dev_id, + union port3_status_u *value); + +sw_error_t +hppe_port3_status_set( + a_uint32_t dev_id, + union port3_status_u *value); + +sw_error_t +hppe_port4_status_get( + a_uint32_t dev_id, + union port4_status_u *value); + +sw_error_t +hppe_port4_status_set( + a_uint32_t dev_id, + union port4_status_u *value); + +sw_error_t +hppe_port5_status_get( + a_uint32_t dev_id, + union port5_status_u *value); + +sw_error_t +hppe_port5_status_set( + a_uint32_t dev_id, + union port5_status_u *value); + +sw_error_t +hppe_port6_status_get( + a_uint32_t dev_id, + union port6_status_u *value); + +sw_error_t +hppe_port6_status_set( + a_uint32_t dev_id, + union port6_status_u *value); + +sw_error_t +hppe_reserved_regs_0_get( + a_uint32_t dev_id, + union reserved_regs_0_u *value); + +sw_error_t +hppe_reserved_regs_0_set( + a_uint32_t dev_id, + union reserved_regs_0_u *value); + +sw_error_t +hppe_reserved_regs_1_get( + a_uint32_t dev_id, + union reserved_regs_1_u *value); + +sw_error_t +hppe_reserved_regs_1_set( + a_uint32_t dev_id, + union reserved_regs_1_u *value); + +sw_error_t +hppe_reserved_regs_2_get( + a_uint32_t dev_id, + union reserved_regs_2_u *value); + +sw_error_t +hppe_reserved_regs_2_set( + a_uint32_t dev_id, + union reserved_regs_2_u *value); + +sw_error_t +hppe_reserved_regs_3_get( + a_uint32_t dev_id, + union reserved_regs_3_u *value); + +sw_error_t +hppe_reserved_regs_3_set( + a_uint32_t dev_id, + union reserved_regs_3_u *value); + +sw_error_t +hppe_dbg_data_sel_get( + a_uint32_t dev_id, + union dbg_data_sel_u *value); + +sw_error_t +hppe_dbg_data_sel_set( + a_uint32_t dev_id, + union dbg_data_sel_u *value); + +sw_error_t +hppe_switch_id_dev_id_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_switch_id_dev_id_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_switch_id_rev_id_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_switch_id_rev_id_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_rgmii_ctrl_rgmii_ctrl_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_rgmii_ctrl_rgmii_ctrl_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_clk_gating_ctrl_clk_gating_ctrl_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_clk_gating_ctrl_clk_gating_ctrl_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_mux_ctrl_port6_pcs_sel_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_mux_ctrl_port6_pcs_sel_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_mux_ctrl_port5_gmac_sel_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_mux_ctrl_port5_gmac_sel_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_mux_ctrl_port5_pcs_sel_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_mux_ctrl_port5_pcs_sel_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_mux_ctrl_port4_pcs_sel_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_mux_ctrl_port4_pcs_sel_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_mux_ctrl_port6_gmac_sel_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_mux_ctrl_port6_gmac_sel_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_ini_done_int_iv_ini_done_int_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_ini_done_int_iv_ini_done_int_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_ini_done_int_qm_ini_done_int_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_ini_done_int_qm_ini_done_int_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_ini_done_int_l3_ini_done_int_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_ini_done_int_l3_ini_done_int_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_ini_done_int_bm_ini_done_int_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_ini_done_int_bm_ini_done_int_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_ini_done_int_ptx_ini_done_int_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_ini_done_int_ptx_ini_done_int_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_ini_done_int_tm_ini_done_int_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_ini_done_int_tm_ini_done_int_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_ini_done_int_l2_ini_done_int_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_ini_done_int_l2_ini_done_int_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_ini_done_int_acl_ini_done_int_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_ini_done_int_acl_ini_done_int_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_ini_done_int_ing_rate_ini_done_int_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_ini_done_int_ing_rate_ini_done_int_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_cpu_done_int_l3_flow_wr_cmd_overflow_int_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_cpu_done_int_l3_flow_wr_cmd_overflow_int_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_cpu_done_int_l2_fdb_rd_cmd_overflow_int_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_cpu_done_int_l2_fdb_rd_cmd_overflow_int_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_cpu_done_int_qm_cpu_op_done_int_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_cpu_done_int_qm_cpu_op_done_int_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_cpu_done_int_l3_flow_rd_cmd_overflow_int_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_cpu_done_int_l3_flow_rd_cmd_overflow_int_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_cpu_done_int_l2_fdb_wr_result_vld_int_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_cpu_done_int_l2_fdb_wr_result_vld_int_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_cpu_done_int_l2_fdb_rd_result_vld_int_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_cpu_done_int_l2_fdb_rd_result_vld_int_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_cpu_done_int_l2_fdb_wr_cmd_overflow_int_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_cpu_done_int_l2_fdb_wr_cmd_overflow_int_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_cpu_done_int_l3_flow_rd_result_vld_int_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_cpu_done_int_l3_flow_rd_result_vld_int_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_cpu_done_int_l3_host_wr_cmd_overflow_int_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_cpu_done_int_l3_host_wr_cmd_overflow_int_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_cpu_done_int_l3_host_rd_cmd_overflow_int_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_cpu_done_int_l3_host_rd_cmd_overflow_int_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_cpu_done_int_l3_host_rd_result_vld_int_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_cpu_done_int_l3_host_rd_result_vld_int_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_cpu_done_int_l3_host_wr_result_vld_int_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_cpu_done_int_l3_host_wr_result_vld_int_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_cpu_done_int_l3_flow_wr_result_vld_int_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_cpu_done_int_l3_flow_wr_result_vld_int_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_link_int_port6_link_chg_int_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_link_int_port6_link_chg_int_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_link_int_xgmac0_an_done_int_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_link_int_xgmac0_an_done_int_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_link_int_port5_1_link_chg_int_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_link_int_port5_1_link_chg_int_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_link_int_port5_0_link_chg_int_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_link_int_port5_0_link_chg_int_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_link_int_port4_link_chg_int_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_link_int_port4_link_chg_int_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_link_int_port3_link_chg_int_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_link_int_port3_link_chg_int_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_link_int_port2_link_chg_int_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_link_int_port2_link_chg_int_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_link_int_xgmac1_an_done_int_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_link_int_xgmac1_an_done_int_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_link_int_port1_link_chg_int_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_link_int_port1_link_chg_int_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_ini_done_int_mask_tm_ini_done_int_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_ini_done_int_mask_tm_ini_done_int_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_ini_done_int_mask_bm_ini_done_int_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_ini_done_int_mask_bm_ini_done_int_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_ini_done_int_mask_iv_ini_done_int_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_ini_done_int_mask_iv_ini_done_int_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_ini_done_int_mask_acl_ini_done_int_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_ini_done_int_mask_acl_ini_done_int_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_ini_done_int_mask_qm_ini_done_int_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_ini_done_int_mask_qm_ini_done_int_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_ini_done_int_mask_l2_ini_done_int_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_ini_done_int_mask_l2_ini_done_int_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_ini_done_int_mask_ptx_ini_done_int_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_ini_done_int_mask_ptx_ini_done_int_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_ini_done_int_mask_ing_rate_ini_done_int_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_ini_done_int_mask_ing_rate_ini_done_int_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_ini_done_int_mask_l3_ini_done_int_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_ini_done_int_mask_l3_ini_done_int_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_cpu_done_int_mask_l3_host_wr_result_vld_int_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_cpu_done_int_mask_l3_host_wr_result_vld_int_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_cpu_done_int_mask_l3_flow_wr_result_vld_int_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_cpu_done_int_mask_l3_flow_wr_result_vld_int_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_cpu_done_int_mask_l3_host_rd_cmd_overflow_int_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_cpu_done_int_mask_l3_host_rd_cmd_overflow_int_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_cpu_done_int_mask_l3_flow_wr_cmd_overflow_int_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_cpu_done_int_mask_l3_flow_wr_cmd_overflow_int_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_cpu_done_int_mask_l3_host_rd_result_vld_int_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_cpu_done_int_mask_l3_host_rd_result_vld_int_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_cpu_done_int_mask_l2_fdb_rd_cmd_overflow_int_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_cpu_done_int_mask_l2_fdb_rd_cmd_overflow_int_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_cpu_done_int_mask_l2_fdb_wr_cmd_overflow_int_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_cpu_done_int_mask_l2_fdb_wr_cmd_overflow_int_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_cpu_done_int_mask_l3_host_wr_cmd_overflow_int_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_cpu_done_int_mask_l3_host_wr_cmd_overflow_int_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_cpu_done_int_mask_l2_fdb_rd_result_vld_int_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_cpu_done_int_mask_l2_fdb_rd_result_vld_int_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_cpu_done_int_mask_l2_fdb_wr_result_vld_int_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_cpu_done_int_mask_l2_fdb_wr_result_vld_int_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_cpu_done_int_mask_qm_cpu_op_done_int_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_cpu_done_int_mask_qm_cpu_op_done_int_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_cpu_done_int_mask_l3_flow_rd_result_vld_int_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_cpu_done_int_mask_l3_flow_rd_result_vld_int_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_module_cpu_done_int_mask_l3_flow_rd_cmd_overflow_int_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_module_cpu_done_int_mask_l3_flow_rd_cmd_overflow_int_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_link_int_mask_xgmac0_an_done_int_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_link_int_mask_xgmac0_an_done_int_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_link_int_mask_port2_link_chg_int_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_link_int_mask_port2_link_chg_int_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_link_int_mask_port4_link_chg_int_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_link_int_mask_port4_link_chg_int_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_link_int_mask_port3_link_chg_int_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_link_int_mask_port3_link_chg_int_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_link_int_mask_port5_1_link_chg_int_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_link_int_mask_port5_1_link_chg_int_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_link_int_mask_xgmac1_an_done_int_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_link_int_mask_xgmac1_an_done_int_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_link_int_mask_port1_link_chg_int_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_link_int_mask_port1_link_chg_int_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_link_int_mask_port5_0_link_chg_int_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_link_int_mask_port5_0_link_chg_int_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_link_int_mask_port6_link_chg_int_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_link_int_mask_port6_link_chg_int_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_phy_status_0_port3_phy_status_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_phy_status_0_port3_phy_status_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_phy_status_0_port4_phy_status_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_phy_status_0_port4_phy_status_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_phy_status_0_port2_phy_status_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_phy_status_0_port2_phy_status_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_phy_status_0_port1_phy_status_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_phy_status_0_port1_phy_status_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_phy_status_1_port6_phy_status_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_phy_status_1_port6_phy_status_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_phy_status_1_port5_0_phy_status_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_phy_status_1_port5_0_phy_status_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_phy_status_1_port5_1_phy_status_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port_phy_status_1_port5_1_phy_status_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port1_status_port1_status_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port1_status_port1_status_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port2_status_port2_status_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port2_status_port2_status_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port3_status_port3_status_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port3_status_port3_status_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port4_status_port4_status_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port4_status_port4_status_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port5_status_port3_mac_speed_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port5_status_port3_mac_speed_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port5_status_port2_mac_speed_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port5_status_port2_mac_speed_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port5_status_port1_mac_speed_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port5_status_port1_mac_speed_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port5_status_port5_status_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port5_status_port5_status_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port5_status_port4_mac_speed_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port5_status_port4_mac_speed_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port6_status_port6_status_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_port6_status_port6_status_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_reserved_regs_0_spare_regs_0_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_reserved_regs_0_spare_regs_0_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_reserved_regs_1_spare_regs_1_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_reserved_regs_1_spare_regs_1_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_reserved_regs_2_spare_regs_2_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_reserved_regs_2_spare_regs_2_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_reserved_regs_3_spare_regs_3_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_reserved_regs_3_spare_regs_3_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_dbg_data_sel_dbg_data_sel_desp_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_dbg_data_sel_dbg_data_sel_desp_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_dbg_data_sel_dbg_data_sel_switch_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_dbg_data_sel_dbg_data_sel_switch_set( + a_uint32_t dev_id, + unsigned int value); + +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_global_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_global_reg.h new file mode 100755 index 000000000..904f4f15a --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_global_reg.h @@ -0,0 +1,988 @@ +/* + * 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. + */ + + +/** + * @defgroup + * @{ + */ +#ifndef HPPE_GLOBAL_REG_H +#define HPPE_GLOBAL_REG_H + +/*[register] SWITCH_ID*/ +#define SWITCH_ID +#define SWITCH_ID_ADDRESS 0x0 +#define SWITCH_ID_NUM 1 +#define SWITCH_ID_INC 0x4 +#define SWITCH_ID_TYPE REG_TYPE_RW +#define SWITCH_ID_DEFAULT 0x1500 + /*[field] REV_ID*/ + #define SWITCH_ID_REV_ID + #define SWITCH_ID_REV_ID_OFFSET 0 + #define SWITCH_ID_REV_ID_LEN 8 + #define SWITCH_ID_REV_ID_DEFAULT 0x0 + /*[field] DEV_ID*/ + #define SWITCH_ID_DEV_ID + #define SWITCH_ID_DEV_ID_OFFSET 8 + #define SWITCH_ID_DEV_ID_LEN 8 + #define SWITCH_ID_DEV_ID_DEFAULT 0x15 + +struct switch_id { + a_uint32_t rev_id:8; + a_uint32_t dev_id:8; + a_uint32_t _reserved0:16; +}; + +union switch_id_u { + a_uint32_t val; + struct switch_id bf; +}; + +/*[register] RGMII_CTRL*/ +#define RGMII_CTRL +#define RGMII_CTRL_ADDRESS 0x4 +#define RGMII_CTRL_NUM 1 +#define RGMII_CTRL_INC 0x4 +#define RGMII_CTRL_TYPE REG_TYPE_RW +#define RGMII_CTRL_DEFAULT 0x0 + /*[field] RGMII_CTRL*/ + #define RGMII_CTRL_RGMII_CTRL + #define RGMII_CTRL_RGMII_CTRL_OFFSET 0 + #define RGMII_CTRL_RGMII_CTRL_LEN 32 + #define RGMII_CTRL_RGMII_CTRL_DEFAULT 0x0 + +struct rgmii_ctrl { + a_uint32_t rgmii_ctrl:32; +}; + +union rgmii_ctrl_u { + a_uint32_t val; + struct rgmii_ctrl bf; +}; + +/*[register] CLK_GATING_CTRL*/ +#define CLK_GATING_CTRL +#define CLK_GATING_CTRL_ADDRESS 0x8 +#define CLK_GATING_CTRL_NUM 1 +#define CLK_GATING_CTRL_INC 0x4 +#define CLK_GATING_CTRL_TYPE REG_TYPE_RW +#define CLK_GATING_CTRL_DEFAULT 0xffffffff + /*[field] CLK_GATING_CTRL*/ + #define CLK_GATING_CTRL_CLK_GATING_CTRL + #define CLK_GATING_CTRL_CLK_GATING_CTRL_OFFSET 0 + #define CLK_GATING_CTRL_CLK_GATING_CTRL_LEN 32 + #define CLK_GATING_CTRL_CLK_GATING_CTRL_DEFAULT 0xffffffff + +struct clk_gating_ctrl { + a_uint32_t clk_gating_ctrl:32; +}; + +union clk_gating_ctrl_u { + a_uint32_t val; + struct clk_gating_ctrl bf; +}; + +/*[register] PORT_MUX_CTRL*/ +#define PORT_MUX_CTRL +#define PORT_MUX_CTRL_ADDRESS 0x10 +#define PORT_MUX_CTRL_NUM 1 +#define PORT_MUX_CTRL_INC 0x4 +#define PORT_MUX_CTRL_TYPE REG_TYPE_RW +#define PORT_MUX_CTRL_DEFAULT 0x0 + /*[field] PORT4_PCS_SEL*/ + #define PORT_MUX_CTRL_PORT4_PCS_SEL + #define PORT_MUX_CTRL_PORT4_PCS_SEL_OFFSET 0 + #define PORT_MUX_CTRL_PORT4_PCS_SEL_LEN 1 + #define PORT_MUX_CTRL_PORT4_PCS_SEL_DEFAULT 0x0 + /*[field] PORT5_PCS_SEL*/ + #define PORT_MUX_CTRL_PORT5_PCS_SEL + #define PORT_MUX_CTRL_PORT5_PCS_SEL_OFFSET 1 + #define PORT_MUX_CTRL_PORT5_PCS_SEL_LEN 2 + #define PORT_MUX_CTRL_PORT5_PCS_SEL_DEFAULT 0x0 + /*[field] PORT5_GMAC_SEL*/ + #define PORT_MUX_CTRL_PORT5_GMAC_SEL + #define PORT_MUX_CTRL_PORT5_GMAC_SEL_OFFSET 3 + #define PORT_MUX_CTRL_PORT5_GMAC_SEL_LEN 1 + #define PORT_MUX_CTRL_PORT5_GMAC_SEL_DEFAULT 0x0 + /*[field] PORT6_PCS_SEL*/ + #define PORT_MUX_CTRL_PORT6_PCS_SEL + #define PORT_MUX_CTRL_PORT6_PCS_SEL_OFFSET 4 + #define PORT_MUX_CTRL_PORT6_PCS_SEL_LEN 1 + #define PORT_MUX_CTRL_PORT6_PCS_SEL_DEFAULT 0x0 + /*[field] PORT6_GMAC_SEL*/ + #define PORT_MUX_CTRL_PORT6_GMAC_SEL + #define PORT_MUX_CTRL_PORT6_GMAC_SEL_OFFSET 5 + #define PORT_MUX_CTRL_PORT6_GMAC_SEL_LEN 1 + #define PORT_MUX_CTRL_PORT6_GMAC_SEL_DEFAULT 0x0 + +struct port_mux_ctrl { + a_uint32_t port4_pcs_sel:1; + a_uint32_t port5_pcs_sel:2; + a_uint32_t port5_gmac_sel:1; + a_uint32_t port6_pcs_sel:1; + a_uint32_t port6_gmac_sel:1; + a_uint32_t _reserved0:26; +}; + +union port_mux_ctrl_u { + a_uint32_t val; + struct port_mux_ctrl bf; +}; +struct cppe_port_mux_ctrl { + a_uint32_t port3_pcs_sel:2; + a_uint32_t port4_pcs_sel:2; + a_uint32_t port5_pcs_sel:2; + a_uint32_t port5_gmac_sel:1; + a_uint32_t pcs0_ch4_sel:1; + a_uint32_t pcs0_ch0_sel:1; + a_uint32_t _reserved0:23; +}; + +union cppe_port_mux_ctrl_u { + a_uint32_t val; + struct cppe_port_mux_ctrl bf; +}; + +/*[register] MODULE_INI_DONE_INT*/ +#define MODULE_INI_DONE_INT +#define MODULE_INI_DONE_INT_ADDRESS 0x20 +#define MODULE_INI_DONE_INT_NUM 1 +#define MODULE_INI_DONE_INT_INC 0x4 +#define MODULE_INI_DONE_INT_TYPE REG_TYPE_RW +#define MODULE_INI_DONE_INT_DEFAULT 0x0 + /*[field] L3_INI_DONE_INT*/ + #define MODULE_INI_DONE_INT_L3_INI_DONE_INT + #define MODULE_INI_DONE_INT_L3_INI_DONE_INT_OFFSET 0 + #define MODULE_INI_DONE_INT_L3_INI_DONE_INT_LEN 1 + #define MODULE_INI_DONE_INT_L3_INI_DONE_INT_DEFAULT 0x0 + /*[field] ACL_INI_DONE_INT*/ + #define MODULE_INI_DONE_INT_ACL_INI_DONE_INT + #define MODULE_INI_DONE_INT_ACL_INI_DONE_INT_OFFSET 1 + #define MODULE_INI_DONE_INT_ACL_INI_DONE_INT_LEN 1 + #define MODULE_INI_DONE_INT_ACL_INI_DONE_INT_DEFAULT 0x0 + /*[field] L2_INI_DONE_INT*/ + #define MODULE_INI_DONE_INT_L2_INI_DONE_INT + #define MODULE_INI_DONE_INT_L2_INI_DONE_INT_OFFSET 2 + #define MODULE_INI_DONE_INT_L2_INI_DONE_INT_LEN 1 + #define MODULE_INI_DONE_INT_L2_INI_DONE_INT_DEFAULT 0x0 + /*[field] ING_RATE_INI_DONE_INT*/ + #define MODULE_INI_DONE_INT_ING_RATE_INI_DONE_INT + #define MODULE_INI_DONE_INT_ING_RATE_INI_DONE_INT_OFFSET 3 + #define MODULE_INI_DONE_INT_ING_RATE_INI_DONE_INT_LEN 1 + #define MODULE_INI_DONE_INT_ING_RATE_INI_DONE_INT_DEFAULT 0x0 + /*[field] BM_INI_DONE_INT*/ + #define MODULE_INI_DONE_INT_BM_INI_DONE_INT + #define MODULE_INI_DONE_INT_BM_INI_DONE_INT_OFFSET 4 + #define MODULE_INI_DONE_INT_BM_INI_DONE_INT_LEN 1 + #define MODULE_INI_DONE_INT_BM_INI_DONE_INT_DEFAULT 0x0 + /*[field] TM_INI_DONE_INT*/ + #define MODULE_INI_DONE_INT_TM_INI_DONE_INT + #define MODULE_INI_DONE_INT_TM_INI_DONE_INT_OFFSET 5 + #define MODULE_INI_DONE_INT_TM_INI_DONE_INT_LEN 1 + #define MODULE_INI_DONE_INT_TM_INI_DONE_INT_DEFAULT 0x0 + /*[field] QM_INI_DONE_INT*/ + #define MODULE_INI_DONE_INT_QM_INI_DONE_INT + #define MODULE_INI_DONE_INT_QM_INI_DONE_INT_OFFSET 6 + #define MODULE_INI_DONE_INT_QM_INI_DONE_INT_LEN 1 + #define MODULE_INI_DONE_INT_QM_INI_DONE_INT_DEFAULT 0x0 + /*[field] IV_INI_DONE_INT*/ + #define MODULE_INI_DONE_INT_IV_INI_DONE_INT + #define MODULE_INI_DONE_INT_IV_INI_DONE_INT_OFFSET 7 + #define MODULE_INI_DONE_INT_IV_INI_DONE_INT_LEN 1 + #define MODULE_INI_DONE_INT_IV_INI_DONE_INT_DEFAULT 0x0 + /*[field] PTX_INI_DONE_INT*/ + #define MODULE_INI_DONE_INT_PTX_INI_DONE_INT + #define MODULE_INI_DONE_INT_PTX_INI_DONE_INT_OFFSET 8 + #define MODULE_INI_DONE_INT_PTX_INI_DONE_INT_LEN 1 + #define MODULE_INI_DONE_INT_PTX_INI_DONE_INT_DEFAULT 0x0 + +struct module_ini_done_int { + a_uint32_t l3_ini_done_int:1; + a_uint32_t acl_ini_done_int:1; + a_uint32_t l2_ini_done_int:1; + a_uint32_t ing_rate_ini_done_int:1; + a_uint32_t bm_ini_done_int:1; + a_uint32_t tm_ini_done_int:1; + a_uint32_t qm_ini_done_int:1; + a_uint32_t iv_ini_done_int:1; + a_uint32_t ptx_ini_done_int:1; + a_uint32_t _reserved0:23; +}; + +union module_ini_done_int_u { + a_uint32_t val; + struct module_ini_done_int bf; +}; + +/*[register] MODULE_CPU_DONE_INT*/ +#define MODULE_CPU_DONE_INT +#define MODULE_CPU_DONE_INT_ADDRESS 0x24 +#define MODULE_CPU_DONE_INT_NUM 1 +#define MODULE_CPU_DONE_INT_INC 0x4 +#define MODULE_CPU_DONE_INT_TYPE REG_TYPE_RW +#define MODULE_CPU_DONE_INT_DEFAULT 0x0 + /*[field] QM_CPU_OP_DONE_INT*/ + #define MODULE_CPU_DONE_INT_QM_CPU_OP_DONE_INT + #define MODULE_CPU_DONE_INT_QM_CPU_OP_DONE_INT_OFFSET 0 + #define MODULE_CPU_DONE_INT_QM_CPU_OP_DONE_INT_LEN 1 + #define MODULE_CPU_DONE_INT_QM_CPU_OP_DONE_INT_DEFAULT 0x0 + /*[field] L2_FDB_RD_RESULT_VLD_INT*/ + #define MODULE_CPU_DONE_INT_L2_FDB_RD_RESULT_VLD_INT + #define MODULE_CPU_DONE_INT_L2_FDB_RD_RESULT_VLD_INT_OFFSET 1 + #define MODULE_CPU_DONE_INT_L2_FDB_RD_RESULT_VLD_INT_LEN 1 + #define MODULE_CPU_DONE_INT_L2_FDB_RD_RESULT_VLD_INT_DEFAULT 0x0 + /*[field] L2_FDB_WR_RESULT_VLD_INT*/ + #define MODULE_CPU_DONE_INT_L2_FDB_WR_RESULT_VLD_INT + #define MODULE_CPU_DONE_INT_L2_FDB_WR_RESULT_VLD_INT_OFFSET 2 + #define MODULE_CPU_DONE_INT_L2_FDB_WR_RESULT_VLD_INT_LEN 1 + #define MODULE_CPU_DONE_INT_L2_FDB_WR_RESULT_VLD_INT_DEFAULT 0x0 + /*[field] L2_FDB_RD_CMD_OVERFLOW_INT*/ + #define MODULE_CPU_DONE_INT_L2_FDB_RD_CMD_OVERFLOW_INT + #define MODULE_CPU_DONE_INT_L2_FDB_RD_CMD_OVERFLOW_INT_OFFSET 3 + #define MODULE_CPU_DONE_INT_L2_FDB_RD_CMD_OVERFLOW_INT_LEN 1 + #define MODULE_CPU_DONE_INT_L2_FDB_RD_CMD_OVERFLOW_INT_DEFAULT 0x0 + /*[field] L2_FDB_WR_CMD_OVERFLOW_INT*/ + #define MODULE_CPU_DONE_INT_L2_FDB_WR_CMD_OVERFLOW_INT + #define MODULE_CPU_DONE_INT_L2_FDB_WR_CMD_OVERFLOW_INT_OFFSET 4 + #define MODULE_CPU_DONE_INT_L2_FDB_WR_CMD_OVERFLOW_INT_LEN 1 + #define MODULE_CPU_DONE_INT_L2_FDB_WR_CMD_OVERFLOW_INT_DEFAULT 0x0 + /*[field] L3_HOST_WR_CMD_OVERFLOW_INT*/ + #define MODULE_CPU_DONE_INT_L3_HOST_WR_CMD_OVERFLOW_INT + #define MODULE_CPU_DONE_INT_L3_HOST_WR_CMD_OVERFLOW_INT_OFFSET 8 + #define MODULE_CPU_DONE_INT_L3_HOST_WR_CMD_OVERFLOW_INT_LEN 1 + #define MODULE_CPU_DONE_INT_L3_HOST_WR_CMD_OVERFLOW_INT_DEFAULT 0x0 + /*[field] L3_HOST_RD_CMD_OVERFLOW_INT*/ + #define MODULE_CPU_DONE_INT_L3_HOST_RD_CMD_OVERFLOW_INT + #define MODULE_CPU_DONE_INT_L3_HOST_RD_CMD_OVERFLOW_INT_OFFSET 9 + #define MODULE_CPU_DONE_INT_L3_HOST_RD_CMD_OVERFLOW_INT_LEN 1 + #define MODULE_CPU_DONE_INT_L3_HOST_RD_CMD_OVERFLOW_INT_DEFAULT 0x0 + /*[field] L3_HOST_WR_RESULT_VLD_INT*/ + #define MODULE_CPU_DONE_INT_L3_HOST_WR_RESULT_VLD_INT + #define MODULE_CPU_DONE_INT_L3_HOST_WR_RESULT_VLD_INT_OFFSET 10 + #define MODULE_CPU_DONE_INT_L3_HOST_WR_RESULT_VLD_INT_LEN 1 + #define MODULE_CPU_DONE_INT_L3_HOST_WR_RESULT_VLD_INT_DEFAULT 0x0 + /*[field] L3_HOST_RD_RESULT_VLD_INT*/ + #define MODULE_CPU_DONE_INT_L3_HOST_RD_RESULT_VLD_INT + #define MODULE_CPU_DONE_INT_L3_HOST_RD_RESULT_VLD_INT_OFFSET 11 + #define MODULE_CPU_DONE_INT_L3_HOST_RD_RESULT_VLD_INT_LEN 1 + #define MODULE_CPU_DONE_INT_L3_HOST_RD_RESULT_VLD_INT_DEFAULT 0x0 + /*[field] L3_FLOW_WR_CMD_OVERFLOW_INT*/ + #define MODULE_CPU_DONE_INT_L3_FLOW_WR_CMD_OVERFLOW_INT + #define MODULE_CPU_DONE_INT_L3_FLOW_WR_CMD_OVERFLOW_INT_OFFSET 12 + #define MODULE_CPU_DONE_INT_L3_FLOW_WR_CMD_OVERFLOW_INT_LEN 1 + #define MODULE_CPU_DONE_INT_L3_FLOW_WR_CMD_OVERFLOW_INT_DEFAULT 0x0 + /*[field] L3_FLOW_RD_CMD_OVERFLOW_INT*/ + #define MODULE_CPU_DONE_INT_L3_FLOW_RD_CMD_OVERFLOW_INT + #define MODULE_CPU_DONE_INT_L3_FLOW_RD_CMD_OVERFLOW_INT_OFFSET 13 + #define MODULE_CPU_DONE_INT_L3_FLOW_RD_CMD_OVERFLOW_INT_LEN 1 + #define MODULE_CPU_DONE_INT_L3_FLOW_RD_CMD_OVERFLOW_INT_DEFAULT 0x0 + /*[field] L3_FLOW_WR_RESULT_VLD_INT*/ + #define MODULE_CPU_DONE_INT_L3_FLOW_WR_RESULT_VLD_INT + #define MODULE_CPU_DONE_INT_L3_FLOW_WR_RESULT_VLD_INT_OFFSET 14 + #define MODULE_CPU_DONE_INT_L3_FLOW_WR_RESULT_VLD_INT_LEN 1 + #define MODULE_CPU_DONE_INT_L3_FLOW_WR_RESULT_VLD_INT_DEFAULT 0x0 + /*[field] L3_FLOW_RD_RESULT_VLD_INT*/ + #define MODULE_CPU_DONE_INT_L3_FLOW_RD_RESULT_VLD_INT + #define MODULE_CPU_DONE_INT_L3_FLOW_RD_RESULT_VLD_INT_OFFSET 15 + #define MODULE_CPU_DONE_INT_L3_FLOW_RD_RESULT_VLD_INT_LEN 1 + #define MODULE_CPU_DONE_INT_L3_FLOW_RD_RESULT_VLD_INT_DEFAULT 0x0 + +struct module_cpu_done_int { + a_uint32_t qm_cpu_op_done_int:1; + a_uint32_t l2_fdb_rd_result_vld_int:1; + a_uint32_t l2_fdb_wr_result_vld_int:1; + a_uint32_t l2_fdb_rd_cmd_overflow_int:1; + a_uint32_t l2_fdb_wr_cmd_overflow_int:1; + a_uint32_t _reserved0:3; + a_uint32_t l3_host_wr_cmd_overflow_int:1; + a_uint32_t l3_host_rd_cmd_overflow_int:1; + a_uint32_t l3_host_wr_result_vld_int:1; + a_uint32_t l3_host_rd_result_vld_int:1; + a_uint32_t l3_flow_wr_cmd_overflow_int:1; + a_uint32_t l3_flow_rd_cmd_overflow_int:1; + a_uint32_t l3_flow_wr_result_vld_int:1; + a_uint32_t l3_flow_rd_result_vld_int:1; + a_uint32_t _reserved1:16; +}; + +union module_cpu_done_int_u { + a_uint32_t val; + struct module_cpu_done_int bf; +}; + +/*[register] PORT_LINK_INT*/ +#define PORT_LINK_INT +#define PORT_LINK_INT_ADDRESS 0x28 +#define PORT_LINK_INT_NUM 1 +#define PORT_LINK_INT_INC 0x4 +#define PORT_LINK_INT_TYPE REG_TYPE_RW +#define PORT_LINK_INT_DEFAULT 0x0 + /*[field] PORT1_LINK_CHG_INT*/ + #define PORT_LINK_INT_PORT1_LINK_CHG_INT + #define PORT_LINK_INT_PORT1_LINK_CHG_INT_OFFSET 0 + #define PORT_LINK_INT_PORT1_LINK_CHG_INT_LEN 1 + #define PORT_LINK_INT_PORT1_LINK_CHG_INT_DEFAULT 0x0 + /*[field] PORT2_LINK_CHG_INT*/ + #define PORT_LINK_INT_PORT2_LINK_CHG_INT + #define PORT_LINK_INT_PORT2_LINK_CHG_INT_OFFSET 1 + #define PORT_LINK_INT_PORT2_LINK_CHG_INT_LEN 1 + #define PORT_LINK_INT_PORT2_LINK_CHG_INT_DEFAULT 0x0 + /*[field] PORT3_LINK_CHG_INT*/ + #define PORT_LINK_INT_PORT3_LINK_CHG_INT + #define PORT_LINK_INT_PORT3_LINK_CHG_INT_OFFSET 2 + #define PORT_LINK_INT_PORT3_LINK_CHG_INT_LEN 1 + #define PORT_LINK_INT_PORT3_LINK_CHG_INT_DEFAULT 0x0 + /*[field] PORT4_LINK_CHG_INT*/ + #define PORT_LINK_INT_PORT4_LINK_CHG_INT + #define PORT_LINK_INT_PORT4_LINK_CHG_INT_OFFSET 3 + #define PORT_LINK_INT_PORT4_LINK_CHG_INT_LEN 1 + #define PORT_LINK_INT_PORT4_LINK_CHG_INT_DEFAULT 0x0 + /*[field] PORT5_0_LINK_CHG_INT*/ + #define PORT_LINK_INT_PORT5_0_LINK_CHG_INT + #define PORT_LINK_INT_PORT5_0_LINK_CHG_INT_OFFSET 4 + #define PORT_LINK_INT_PORT5_0_LINK_CHG_INT_LEN 1 + #define PORT_LINK_INT_PORT5_0_LINK_CHG_INT_DEFAULT 0x0 + /*[field] PORT5_1_LINK_CHG_INT*/ + #define PORT_LINK_INT_PORT5_1_LINK_CHG_INT + #define PORT_LINK_INT_PORT5_1_LINK_CHG_INT_OFFSET 5 + #define PORT_LINK_INT_PORT5_1_LINK_CHG_INT_LEN 1 + #define PORT_LINK_INT_PORT5_1_LINK_CHG_INT_DEFAULT 0x0 + /*[field] PORT6_LINK_CHG_INT*/ + #define PORT_LINK_INT_PORT6_LINK_CHG_INT + #define PORT_LINK_INT_PORT6_LINK_CHG_INT_OFFSET 6 + #define PORT_LINK_INT_PORT6_LINK_CHG_INT_LEN 1 + #define PORT_LINK_INT_PORT6_LINK_CHG_INT_DEFAULT 0x0 + /*[field] XGMAC0_AN_DONE_INT*/ + #define PORT_LINK_INT_XGMAC0_AN_DONE_INT + #define PORT_LINK_INT_XGMAC0_AN_DONE_INT_OFFSET 8 + #define PORT_LINK_INT_XGMAC0_AN_DONE_INT_LEN 1 + #define PORT_LINK_INT_XGMAC0_AN_DONE_INT_DEFAULT 0x0 + /*[field] XGMAC1_AN_DONE_INT*/ + #define PORT_LINK_INT_XGMAC1_AN_DONE_INT + #define PORT_LINK_INT_XGMAC1_AN_DONE_INT_OFFSET 9 + #define PORT_LINK_INT_XGMAC1_AN_DONE_INT_LEN 1 + #define PORT_LINK_INT_XGMAC1_AN_DONE_INT_DEFAULT 0x0 + +struct port_link_int { + a_uint32_t port1_link_chg_int:1; + a_uint32_t port2_link_chg_int:1; + a_uint32_t port3_link_chg_int:1; + a_uint32_t port4_link_chg_int:1; + a_uint32_t port5_0_link_chg_int:1; + a_uint32_t port5_1_link_chg_int:1; + a_uint32_t port6_link_chg_int:1; + a_uint32_t _reserved0:1; + a_uint32_t xgmac0_an_done_int:1; + a_uint32_t xgmac1_an_done_int:1; + a_uint32_t _reserved1:22; +}; + +union port_link_int_u { + a_uint32_t val; + struct port_link_int bf; +}; + +/*[register] MODULE_INI_DONE_INT_MASK*/ +#define MODULE_INI_DONE_INT_MASK +#define MODULE_INI_DONE_INT_MASK_ADDRESS 0x30 +#define MODULE_INI_DONE_INT_MASK_NUM 1 +#define MODULE_INI_DONE_INT_MASK_INC 0x4 +#define MODULE_INI_DONE_INT_MASK_TYPE REG_TYPE_RW +#define MODULE_INI_DONE_INT_MASK_DEFAULT 0x1ff + /*[field] L3_INI_DONE_INT_MASK*/ + #define MODULE_INI_DONE_INT_MASK_L3_INI_DONE_INT_MASK + #define MODULE_INI_DONE_INT_MASK_L3_INI_DONE_INT_MASK_OFFSET 0 + #define MODULE_INI_DONE_INT_MASK_L3_INI_DONE_INT_MASK_LEN 1 + #define MODULE_INI_DONE_INT_MASK_L3_INI_DONE_INT_MASK_DEFAULT 0x1 + /*[field] ACL_INI_DONE_INT_MASK*/ + #define MODULE_INI_DONE_INT_MASK_ACL_INI_DONE_INT_MASK + #define MODULE_INI_DONE_INT_MASK_ACL_INI_DONE_INT_MASK_OFFSET 1 + #define MODULE_INI_DONE_INT_MASK_ACL_INI_DONE_INT_MASK_LEN 1 + #define MODULE_INI_DONE_INT_MASK_ACL_INI_DONE_INT_MASK_DEFAULT 0x1 + /*[field] L2_INI_DONE_INT_MASK*/ + #define MODULE_INI_DONE_INT_MASK_L2_INI_DONE_INT_MASK + #define MODULE_INI_DONE_INT_MASK_L2_INI_DONE_INT_MASK_OFFSET 2 + #define MODULE_INI_DONE_INT_MASK_L2_INI_DONE_INT_MASK_LEN 1 + #define MODULE_INI_DONE_INT_MASK_L2_INI_DONE_INT_MASK_DEFAULT 0x1 + /*[field] ING_RATE_INI_DONE_INT_MASK*/ + #define MODULE_INI_DONE_INT_MASK_ING_RATE_INI_DONE_INT_MASK + #define MODULE_INI_DONE_INT_MASK_ING_RATE_INI_DONE_INT_MASK_OFFSET 3 + #define MODULE_INI_DONE_INT_MASK_ING_RATE_INI_DONE_INT_MASK_LEN 1 + #define MODULE_INI_DONE_INT_MASK_ING_RATE_INI_DONE_INT_MASK_DEFAULT 0x1 + /*[field] BM_INI_DONE_INT_MASK*/ + #define MODULE_INI_DONE_INT_MASK_BM_INI_DONE_INT_MASK + #define MODULE_INI_DONE_INT_MASK_BM_INI_DONE_INT_MASK_OFFSET 4 + #define MODULE_INI_DONE_INT_MASK_BM_INI_DONE_INT_MASK_LEN 1 + #define MODULE_INI_DONE_INT_MASK_BM_INI_DONE_INT_MASK_DEFAULT 0x1 + /*[field] TM_INI_DONE_INT_MASK*/ + #define MODULE_INI_DONE_INT_MASK_TM_INI_DONE_INT_MASK + #define MODULE_INI_DONE_INT_MASK_TM_INI_DONE_INT_MASK_OFFSET 5 + #define MODULE_INI_DONE_INT_MASK_TM_INI_DONE_INT_MASK_LEN 1 + #define MODULE_INI_DONE_INT_MASK_TM_INI_DONE_INT_MASK_DEFAULT 0x1 + /*[field] QM_INI_DONE_INT_MASK*/ + #define MODULE_INI_DONE_INT_MASK_QM_INI_DONE_INT_MASK + #define MODULE_INI_DONE_INT_MASK_QM_INI_DONE_INT_MASK_OFFSET 6 + #define MODULE_INI_DONE_INT_MASK_QM_INI_DONE_INT_MASK_LEN 1 + #define MODULE_INI_DONE_INT_MASK_QM_INI_DONE_INT_MASK_DEFAULT 0x1 + /*[field] IV_INI_DONE_INT_MASK*/ + #define MODULE_INI_DONE_INT_MASK_IV_INI_DONE_INT_MASK + #define MODULE_INI_DONE_INT_MASK_IV_INI_DONE_INT_MASK_OFFSET 7 + #define MODULE_INI_DONE_INT_MASK_IV_INI_DONE_INT_MASK_LEN 1 + #define MODULE_INI_DONE_INT_MASK_IV_INI_DONE_INT_MASK_DEFAULT 0x1 + /*[field] PTX_INI_DONE_INT_MASK*/ + #define MODULE_INI_DONE_INT_MASK_PTX_INI_DONE_INT_MASK + #define MODULE_INI_DONE_INT_MASK_PTX_INI_DONE_INT_MASK_OFFSET 8 + #define MODULE_INI_DONE_INT_MASK_PTX_INI_DONE_INT_MASK_LEN 1 + #define MODULE_INI_DONE_INT_MASK_PTX_INI_DONE_INT_MASK_DEFAULT 0x1 + +struct module_ini_done_int_mask { + a_uint32_t l3_ini_done_int_mask:1; + a_uint32_t acl_ini_done_int_mask:1; + a_uint32_t l2_ini_done_int_mask:1; + a_uint32_t ing_rate_ini_done_int_mask:1; + a_uint32_t bm_ini_done_int_mask:1; + a_uint32_t tm_ini_done_int_mask:1; + a_uint32_t qm_ini_done_int_mask:1; + a_uint32_t iv_ini_done_int_mask:1; + a_uint32_t ptx_ini_done_int_mask:1; + a_uint32_t _reserved0:23; +}; + +union module_ini_done_int_mask_u { + a_uint32_t val; + struct module_ini_done_int_mask bf; +}; + +/*[register] MODULE_CPU_DONE_INT_MASK*/ +#define MODULE_CPU_DONE_INT_MASK +#define MODULE_CPU_DONE_INT_MASK_ADDRESS 0x34 +#define MODULE_CPU_DONE_INT_MASK_NUM 1 +#define MODULE_CPU_DONE_INT_MASK_INC 0x4 +#define MODULE_CPU_DONE_INT_MASK_TYPE REG_TYPE_RW +#define MODULE_CPU_DONE_INT_MASK_DEFAULT 0xff1f + /*[field] QM_CPU_OP_DONE_INT_MASK*/ + #define MODULE_CPU_DONE_INT_MASK_QM_CPU_OP_DONE_INT_MASK + #define MODULE_CPU_DONE_INT_MASK_QM_CPU_OP_DONE_INT_MASK_OFFSET 0 + #define MODULE_CPU_DONE_INT_MASK_QM_CPU_OP_DONE_INT_MASK_LEN 1 + #define MODULE_CPU_DONE_INT_MASK_QM_CPU_OP_DONE_INT_MASK_DEFAULT 0x1 + /*[field] L2_FDB_RD_RESULT_VLD_INT_MASK*/ + #define MODULE_CPU_DONE_INT_MASK_L2_FDB_RD_RESULT_VLD_INT_MASK + #define MODULE_CPU_DONE_INT_MASK_L2_FDB_RD_RESULT_VLD_INT_MASK_OFFSET 1 + #define MODULE_CPU_DONE_INT_MASK_L2_FDB_RD_RESULT_VLD_INT_MASK_LEN 1 + #define MODULE_CPU_DONE_INT_MASK_L2_FDB_RD_RESULT_VLD_INT_MASK_DEFAULT 0x1 + /*[field] L2_FDB_WR_RESULT_VLD_INT_MASK*/ + #define MODULE_CPU_DONE_INT_MASK_L2_FDB_WR_RESULT_VLD_INT_MASK + #define MODULE_CPU_DONE_INT_MASK_L2_FDB_WR_RESULT_VLD_INT_MASK_OFFSET 2 + #define MODULE_CPU_DONE_INT_MASK_L2_FDB_WR_RESULT_VLD_INT_MASK_LEN 1 + #define MODULE_CPU_DONE_INT_MASK_L2_FDB_WR_RESULT_VLD_INT_MASK_DEFAULT 0x1 + /*[field] L2_FDB_RD_CMD_OVERFLOW_INT_MASK*/ + #define MODULE_CPU_DONE_INT_MASK_L2_FDB_RD_CMD_OVERFLOW_INT_MASK + #define MODULE_CPU_DONE_INT_MASK_L2_FDB_RD_CMD_OVERFLOW_INT_MASK_OFFSET 3 + #define MODULE_CPU_DONE_INT_MASK_L2_FDB_RD_CMD_OVERFLOW_INT_MASK_LEN 1 + #define MODULE_CPU_DONE_INT_MASK_L2_FDB_RD_CMD_OVERFLOW_INT_MASK_DEFAULT 0x1 + /*[field] L2_FDB_WR_CMD_OVERFLOW_INT_MASK*/ + #define MODULE_CPU_DONE_INT_MASK_L2_FDB_WR_CMD_OVERFLOW_INT_MASK + #define MODULE_CPU_DONE_INT_MASK_L2_FDB_WR_CMD_OVERFLOW_INT_MASK_OFFSET 4 + #define MODULE_CPU_DONE_INT_MASK_L2_FDB_WR_CMD_OVERFLOW_INT_MASK_LEN 1 + #define MODULE_CPU_DONE_INT_MASK_L2_FDB_WR_CMD_OVERFLOW_INT_MASK_DEFAULT 0x1 + /*[field] L3_HOST_WR_CMD_OVERFLOW_INT_MASK*/ + #define MODULE_CPU_DONE_INT_MASK_L3_HOST_WR_CMD_OVERFLOW_INT_MASK + #define MODULE_CPU_DONE_INT_MASK_L3_HOST_WR_CMD_OVERFLOW_INT_MASK_OFFSET 8 + #define MODULE_CPU_DONE_INT_MASK_L3_HOST_WR_CMD_OVERFLOW_INT_MASK_LEN 1 + #define MODULE_CPU_DONE_INT_MASK_L3_HOST_WR_CMD_OVERFLOW_INT_MASK_DEFAULT 0x1 + /*[field] L3_HOST_RD_CMD_OVERFLOW_INT_MASK*/ + #define MODULE_CPU_DONE_INT_MASK_L3_HOST_RD_CMD_OVERFLOW_INT_MASK + #define MODULE_CPU_DONE_INT_MASK_L3_HOST_RD_CMD_OVERFLOW_INT_MASK_OFFSET 9 + #define MODULE_CPU_DONE_INT_MASK_L3_HOST_RD_CMD_OVERFLOW_INT_MASK_LEN 1 + #define MODULE_CPU_DONE_INT_MASK_L3_HOST_RD_CMD_OVERFLOW_INT_MASK_DEFAULT 0x1 + /*[field] L3_HOST_WR_RESULT_VLD_INT_MASK*/ + #define MODULE_CPU_DONE_INT_MASK_L3_HOST_WR_RESULT_VLD_INT_MASK + #define MODULE_CPU_DONE_INT_MASK_L3_HOST_WR_RESULT_VLD_INT_MASK_OFFSET 10 + #define MODULE_CPU_DONE_INT_MASK_L3_HOST_WR_RESULT_VLD_INT_MASK_LEN 1 + #define MODULE_CPU_DONE_INT_MASK_L3_HOST_WR_RESULT_VLD_INT_MASK_DEFAULT 0x1 + /*[field] L3_HOST_RD_RESULT_VLD_INT_MASK*/ + #define MODULE_CPU_DONE_INT_MASK_L3_HOST_RD_RESULT_VLD_INT_MASK + #define MODULE_CPU_DONE_INT_MASK_L3_HOST_RD_RESULT_VLD_INT_MASK_OFFSET 11 + #define MODULE_CPU_DONE_INT_MASK_L3_HOST_RD_RESULT_VLD_INT_MASK_LEN 1 + #define MODULE_CPU_DONE_INT_MASK_L3_HOST_RD_RESULT_VLD_INT_MASK_DEFAULT 0x1 + /*[field] L3_FLOW_WR_CMD_OVERFLOW_INT_MASK*/ + #define MODULE_CPU_DONE_INT_MASK_L3_FLOW_WR_CMD_OVERFLOW_INT_MASK + #define MODULE_CPU_DONE_INT_MASK_L3_FLOW_WR_CMD_OVERFLOW_INT_MASK_OFFSET 12 + #define MODULE_CPU_DONE_INT_MASK_L3_FLOW_WR_CMD_OVERFLOW_INT_MASK_LEN 1 + #define MODULE_CPU_DONE_INT_MASK_L3_FLOW_WR_CMD_OVERFLOW_INT_MASK_DEFAULT 0x1 + /*[field] L3_FLOW_RD_CMD_OVERFLOW_INT_MASK*/ + #define MODULE_CPU_DONE_INT_MASK_L3_FLOW_RD_CMD_OVERFLOW_INT_MASK + #define MODULE_CPU_DONE_INT_MASK_L3_FLOW_RD_CMD_OVERFLOW_INT_MASK_OFFSET 13 + #define MODULE_CPU_DONE_INT_MASK_L3_FLOW_RD_CMD_OVERFLOW_INT_MASK_LEN 1 + #define MODULE_CPU_DONE_INT_MASK_L3_FLOW_RD_CMD_OVERFLOW_INT_MASK_DEFAULT 0x1 + /*[field] L3_FLOW_WR_RESULT_VLD_INT_MASK*/ + #define MODULE_CPU_DONE_INT_MASK_L3_FLOW_WR_RESULT_VLD_INT_MASK + #define MODULE_CPU_DONE_INT_MASK_L3_FLOW_WR_RESULT_VLD_INT_MASK_OFFSET 14 + #define MODULE_CPU_DONE_INT_MASK_L3_FLOW_WR_RESULT_VLD_INT_MASK_LEN 1 + #define MODULE_CPU_DONE_INT_MASK_L3_FLOW_WR_RESULT_VLD_INT_MASK_DEFAULT 0x1 + /*[field] L3_FLOW_RD_RESULT_VLD_INT_MASK*/ + #define MODULE_CPU_DONE_INT_MASK_L3_FLOW_RD_RESULT_VLD_INT_MASK + #define MODULE_CPU_DONE_INT_MASK_L3_FLOW_RD_RESULT_VLD_INT_MASK_OFFSET 15 + #define MODULE_CPU_DONE_INT_MASK_L3_FLOW_RD_RESULT_VLD_INT_MASK_LEN 1 + #define MODULE_CPU_DONE_INT_MASK_L3_FLOW_RD_RESULT_VLD_INT_MASK_DEFAULT 0x1 + +struct module_cpu_done_int_mask { + a_uint32_t qm_cpu_op_done_int_mask:1; + a_uint32_t l2_fdb_rd_result_vld_int_mask:1; + a_uint32_t l2_fdb_wr_result_vld_int_mask:1; + a_uint32_t l2_fdb_rd_cmd_overflow_int_mask:1; + a_uint32_t l2_fdb_wr_cmd_overflow_int_mask:1; + a_uint32_t _reserved0:3; + a_uint32_t l3_host_wr_cmd_overflow_int_mask:1; + a_uint32_t l3_host_rd_cmd_overflow_int_mask:1; + a_uint32_t l3_host_wr_result_vld_int_mask:1; + a_uint32_t l3_host_rd_result_vld_int_mask:1; + a_uint32_t l3_flow_wr_cmd_overflow_int_mask:1; + a_uint32_t l3_flow_rd_cmd_overflow_int_mask:1; + a_uint32_t l3_flow_wr_result_vld_int_mask:1; + a_uint32_t l3_flow_rd_result_vld_int_mask:1; + a_uint32_t _reserved1:16; +}; + +union module_cpu_done_int_mask_u { + a_uint32_t val; + struct module_cpu_done_int_mask bf; +}; + +/*[register] PORT_LINK_INT_MASK*/ +#define PORT_LINK_INT_MASK +#define PORT_LINK_INT_MASK_ADDRESS 0x38 +#define PORT_LINK_INT_MASK_NUM 1 +#define PORT_LINK_INT_MASK_INC 0x4 +#define PORT_LINK_INT_MASK_TYPE REG_TYPE_RW +#define PORT_LINK_INT_MASK_DEFAULT 0x37f + /*[field] PORT1_LINK_CHG_INT_MASK*/ + #define PORT_LINK_INT_MASK_PORT1_LINK_CHG_INT_MASK + #define PORT_LINK_INT_MASK_PORT1_LINK_CHG_INT_MASK_OFFSET 0 + #define PORT_LINK_INT_MASK_PORT1_LINK_CHG_INT_MASK_LEN 1 + #define PORT_LINK_INT_MASK_PORT1_LINK_CHG_INT_MASK_DEFAULT 0x1 + /*[field] PORT2_LINK_CHG_INT_MASK*/ + #define PORT_LINK_INT_MASK_PORT2_LINK_CHG_INT_MASK + #define PORT_LINK_INT_MASK_PORT2_LINK_CHG_INT_MASK_OFFSET 1 + #define PORT_LINK_INT_MASK_PORT2_LINK_CHG_INT_MASK_LEN 1 + #define PORT_LINK_INT_MASK_PORT2_LINK_CHG_INT_MASK_DEFAULT 0x1 + /*[field] PORT3_LINK_CHG_INT_MASK*/ + #define PORT_LINK_INT_MASK_PORT3_LINK_CHG_INT_MASK + #define PORT_LINK_INT_MASK_PORT3_LINK_CHG_INT_MASK_OFFSET 2 + #define PORT_LINK_INT_MASK_PORT3_LINK_CHG_INT_MASK_LEN 1 + #define PORT_LINK_INT_MASK_PORT3_LINK_CHG_INT_MASK_DEFAULT 0x1 + /*[field] PORT4_LINK_CHG_INT_MASK*/ + #define PORT_LINK_INT_MASK_PORT4_LINK_CHG_INT_MASK + #define PORT_LINK_INT_MASK_PORT4_LINK_CHG_INT_MASK_OFFSET 3 + #define PORT_LINK_INT_MASK_PORT4_LINK_CHG_INT_MASK_LEN 1 + #define PORT_LINK_INT_MASK_PORT4_LINK_CHG_INT_MASK_DEFAULT 0x1 + /*[field] PORT5_0_LINK_CHG_INT_MASK*/ + #define PORT_LINK_INT_MASK_PORT5_0_LINK_CHG_INT_MASK + #define PORT_LINK_INT_MASK_PORT5_0_LINK_CHG_INT_MASK_OFFSET 4 + #define PORT_LINK_INT_MASK_PORT5_0_LINK_CHG_INT_MASK_LEN 1 + #define PORT_LINK_INT_MASK_PORT5_0_LINK_CHG_INT_MASK_DEFAULT 0x1 + /*[field] PORT5_1_LINK_CHG_INT_MASK*/ + #define PORT_LINK_INT_MASK_PORT5_1_LINK_CHG_INT_MASK + #define PORT_LINK_INT_MASK_PORT5_1_LINK_CHG_INT_MASK_OFFSET 5 + #define PORT_LINK_INT_MASK_PORT5_1_LINK_CHG_INT_MASK_LEN 1 + #define PORT_LINK_INT_MASK_PORT5_1_LINK_CHG_INT_MASK_DEFAULT 0x1 + /*[field] PORT6_LINK_CHG_INT_MASK*/ + #define PORT_LINK_INT_MASK_PORT6_LINK_CHG_INT_MASK + #define PORT_LINK_INT_MASK_PORT6_LINK_CHG_INT_MASK_OFFSET 6 + #define PORT_LINK_INT_MASK_PORT6_LINK_CHG_INT_MASK_LEN 1 + #define PORT_LINK_INT_MASK_PORT6_LINK_CHG_INT_MASK_DEFAULT 0x1 + /*[field] XGMAC0_AN_DONE_INT_MASK*/ + #define PORT_LINK_INT_MASK_XGMAC0_AN_DONE_INT_MASK + #define PORT_LINK_INT_MASK_XGMAC0_AN_DONE_INT_MASK_OFFSET 8 + #define PORT_LINK_INT_MASK_XGMAC0_AN_DONE_INT_MASK_LEN 1 + #define PORT_LINK_INT_MASK_XGMAC0_AN_DONE_INT_MASK_DEFAULT 0x1 + /*[field] XGMAC1_AN_DONE_INT_MASK*/ + #define PORT_LINK_INT_MASK_XGMAC1_AN_DONE_INT_MASK + #define PORT_LINK_INT_MASK_XGMAC1_AN_DONE_INT_MASK_OFFSET 9 + #define PORT_LINK_INT_MASK_XGMAC1_AN_DONE_INT_MASK_LEN 1 + #define PORT_LINK_INT_MASK_XGMAC1_AN_DONE_INT_MASK_DEFAULT 0x1 + +struct port_link_int_mask { + a_uint32_t port1_link_chg_int_mask:1; + a_uint32_t port2_link_chg_int_mask:1; + a_uint32_t port3_link_chg_int_mask:1; + a_uint32_t port4_link_chg_int_mask:1; + a_uint32_t port5_0_link_chg_int_mask:1; + a_uint32_t port5_1_link_chg_int_mask:1; + a_uint32_t port6_link_chg_int_mask:1; + a_uint32_t _reserved0:1; + a_uint32_t xgmac0_an_done_int_mask:1; + a_uint32_t xgmac1_an_done_int_mask:1; + a_uint32_t _reserved1:22; +}; + +union port_link_int_mask_u { + a_uint32_t val; + struct port_link_int_mask bf; +}; + +/*[register] PORT_PHY_STATUS_0*/ +#define PORT_PHY_STATUS_0 +#define PORT_PHY_STATUS_0_ADDRESS 0x40 +#define PORT_PHY_STATUS_0_NUM 1 +#define PORT_PHY_STATUS_0_INC 0x4 +#define PORT_PHY_STATUS_0_TYPE REG_TYPE_RO +#define PORT_PHY_STATUS_0_DEFAULT 0x0 + /*[field] PORT1_PHY_STATUS*/ + #define PORT_PHY_STATUS_0_PORT1_PHY_STATUS + #define PORT_PHY_STATUS_0_PORT1_PHY_STATUS_OFFSET 0 + #define PORT_PHY_STATUS_0_PORT1_PHY_STATUS_LEN 8 + #define PORT_PHY_STATUS_0_PORT1_PHY_STATUS_DEFAULT 0x0 + /*[field] PORT2_PHY_STATUS*/ + #define PORT_PHY_STATUS_0_PORT2_PHY_STATUS + #define PORT_PHY_STATUS_0_PORT2_PHY_STATUS_OFFSET 8 + #define PORT_PHY_STATUS_0_PORT2_PHY_STATUS_LEN 8 + #define PORT_PHY_STATUS_0_PORT2_PHY_STATUS_DEFAULT 0x0 + /*[field] PORT3_PHY_STATUS*/ + #define PORT_PHY_STATUS_0_PORT3_PHY_STATUS + #define PORT_PHY_STATUS_0_PORT3_PHY_STATUS_OFFSET 16 + #define PORT_PHY_STATUS_0_PORT3_PHY_STATUS_LEN 8 + #define PORT_PHY_STATUS_0_PORT3_PHY_STATUS_DEFAULT 0x0 + /*[field] PORT4_PHY_STATUS*/ + #define PORT_PHY_STATUS_0_PORT4_PHY_STATUS + #define PORT_PHY_STATUS_0_PORT4_PHY_STATUS_OFFSET 24 + #define PORT_PHY_STATUS_0_PORT4_PHY_STATUS_LEN 8 + #define PORT_PHY_STATUS_0_PORT4_PHY_STATUS_DEFAULT 0x0 + +struct port_phy_status_0 { + a_uint32_t port1_phy_status:8; + a_uint32_t port2_phy_status:8; + a_uint32_t port3_phy_status:8; + a_uint32_t port4_phy_status:8; +}; + +union port_phy_status_0_u { + a_uint32_t val; + struct port_phy_status_0 bf; +}; + +/*[register] PORT_PHY_STATUS_1*/ +#define PORT_PHY_STATUS_1 +#define PORT_PHY_STATUS_1_ADDRESS 0x44 +#define PORT_PHY_STATUS_1_NUM 1 +#define PORT_PHY_STATUS_1_INC 0x4 +#define PORT_PHY_STATUS_1_TYPE REG_TYPE_RO +#define PORT_PHY_STATUS_1_DEFAULT 0x0 + /*[field] PORT5_0_PHY_STATUS*/ + #define PORT_PHY_STATUS_1_PORT5_0_PHY_STATUS + #define PORT_PHY_STATUS_1_PORT5_0_PHY_STATUS_OFFSET 0 + #define PORT_PHY_STATUS_1_PORT5_0_PHY_STATUS_LEN 8 + #define PORT_PHY_STATUS_1_PORT5_0_PHY_STATUS_DEFAULT 0x0 + /*[field] PORT5_1_PHY_STATUS*/ + #define PORT_PHY_STATUS_1_PORT5_1_PHY_STATUS + #define PORT_PHY_STATUS_1_PORT5_1_PHY_STATUS_OFFSET 8 + #define PORT_PHY_STATUS_1_PORT5_1_PHY_STATUS_LEN 8 + #define PORT_PHY_STATUS_1_PORT5_1_PHY_STATUS_DEFAULT 0x0 + /*[field] PORT6_PHY_STATUS*/ + #define PORT_PHY_STATUS_1_PORT6_PHY_STATUS + #define PORT_PHY_STATUS_1_PORT6_PHY_STATUS_OFFSET 16 + #define PORT_PHY_STATUS_1_PORT6_PHY_STATUS_LEN 8 + #define PORT_PHY_STATUS_1_PORT6_PHY_STATUS_DEFAULT 0x0 + +struct port_phy_status_1 { + a_uint32_t port5_0_phy_status:8; + a_uint32_t port5_1_phy_status:8; + a_uint32_t port6_phy_status:8; + a_uint32_t _reserved0:8; +}; + +union port_phy_status_1_u { + a_uint32_t val; + struct port_phy_status_1 bf; +}; + +/*[register] PORT1_STATUS*/ +#define PORT1_STATUS +#define PORT1_STATUS_ADDRESS 0x50 +#define PORT1_STATUS_NUM 1 +#define PORT1_STATUS_INC 0x4 +#define PORT1_STATUS_TYPE REG_TYPE_RO +#define PORT1_STATUS_DEFAULT 0x0 + /*[field] PORT1_STATUS*/ + #define PORT1_STATUS_PORT1_STATUS + #define PORT1_STATUS_PORT1_STATUS_OFFSET 0 + #define PORT1_STATUS_PORT1_STATUS_LEN 32 + #define PORT1_STATUS_PORT1_STATUS_DEFAULT 0x0 + +struct port1_status { + a_uint32_t port1_status:32; +}; + +union port1_status_u { + a_uint32_t val; + struct port1_status bf; +}; + +/*[register] PORT2_STATUS*/ +#define PORT2_STATUS +#define PORT2_STATUS_ADDRESS 0x54 +#define PORT2_STATUS_NUM 1 +#define PORT2_STATUS_INC 0x4 +#define PORT2_STATUS_TYPE REG_TYPE_RO +#define PORT2_STATUS_DEFAULT 0x0 + /*[field] PORT2_STATUS*/ + #define PORT2_STATUS_PORT2_STATUS + #define PORT2_STATUS_PORT2_STATUS_OFFSET 0 + #define PORT2_STATUS_PORT2_STATUS_LEN 32 + #define PORT2_STATUS_PORT2_STATUS_DEFAULT 0x0 + +struct port2_status { + a_uint32_t port2_status:32; +}; + +union port2_status_u { + a_uint32_t val; + struct port2_status bf; +}; + +/*[register] PORT3_STATUS*/ +#define PORT3_STATUS +#define PORT3_STATUS_ADDRESS 0x58 +#define PORT3_STATUS_NUM 1 +#define PORT3_STATUS_INC 0x4 +#define PORT3_STATUS_TYPE REG_TYPE_RO +#define PORT3_STATUS_DEFAULT 0x0 + /*[field] PORT3_STATUS*/ + #define PORT3_STATUS_PORT3_STATUS + #define PORT3_STATUS_PORT3_STATUS_OFFSET 0 + #define PORT3_STATUS_PORT3_STATUS_LEN 32 + #define PORT3_STATUS_PORT3_STATUS_DEFAULT 0x0 + +struct port3_status { + a_uint32_t port3_status:32; +}; + +union port3_status_u { + a_uint32_t val; + struct port3_status bf; +}; + +/*[register] PORT4_STATUS*/ +#define PORT4_STATUS +#define PORT4_STATUS_ADDRESS 0x5c +#define PORT4_STATUS_NUM 1 +#define PORT4_STATUS_INC 0x4 +#define PORT4_STATUS_TYPE REG_TYPE_RO +#define PORT4_STATUS_DEFAULT 0x0 + /*[field] PORT4_STATUS*/ + #define PORT4_STATUS_PORT4_STATUS + #define PORT4_STATUS_PORT4_STATUS_OFFSET 0 + #define PORT4_STATUS_PORT4_STATUS_LEN 32 + #define PORT4_STATUS_PORT4_STATUS_DEFAULT 0x0 + +struct port4_status { + a_uint32_t port4_status:32; +}; + +union port4_status_u { + a_uint32_t val; + struct port4_status bf; +}; + +/*[register] PORT5_STATUS*/ +#define PORT5_STATUS +#define PORT5_STATUS_ADDRESS 0x60 +#define PORT5_STATUS_NUM 1 +#define PORT5_STATUS_INC 0x4 +#define PORT5_STATUS_TYPE REG_TYPE_RO +#define PORT5_STATUS_DEFAULT 0x0 + /*[field] PORT5_STATUS*/ + #define PORT5_STATUS_PORT5_STATUS + #define PORT5_STATUS_PORT5_STATUS_OFFSET 0 + #define PORT5_STATUS_PORT5_STATUS_LEN 8 + #define PORT5_STATUS_PORT5_STATUS_DEFAULT 0x0 + /*[field] PORT1_MAC_SPEED*/ + #define PORT5_STATUS_PORT1_MAC_SPEED + #define PORT5_STATUS_PORT1_MAC_SPEED_OFFSET 16 + #define PORT5_STATUS_PORT1_MAC_SPEED_LEN 2 + #define PORT5_STATUS_PORT1_MAC_SPEED_DEFAULT 0x0 + /*[field] PORT2_MAC_SPEED*/ + #define PORT5_STATUS_PORT2_MAC_SPEED + #define PORT5_STATUS_PORT2_MAC_SPEED_OFFSET 18 + #define PORT5_STATUS_PORT2_MAC_SPEED_LEN 2 + #define PORT5_STATUS_PORT2_MAC_SPEED_DEFAULT 0x0 + /*[field] PORT3_MAC_SPEED*/ + #define PORT5_STATUS_PORT3_MAC_SPEED + #define PORT5_STATUS_PORT3_MAC_SPEED_OFFSET 20 + #define PORT5_STATUS_PORT3_MAC_SPEED_LEN 2 + #define PORT5_STATUS_PORT3_MAC_SPEED_DEFAULT 0x0 + /*[field] PORT4_MAC_SPEED*/ + #define PORT5_STATUS_PORT4_MAC_SPEED + #define PORT5_STATUS_PORT4_MAC_SPEED_OFFSET 22 + #define PORT5_STATUS_PORT4_MAC_SPEED_LEN 2 + #define PORT5_STATUS_PORT4_MAC_SPEED_DEFAULT 0x0 + +struct port5_status { + a_uint32_t port5_status:8; + a_uint32_t _reserved0:8; + a_uint32_t port1_mac_speed:2; + a_uint32_t port2_mac_speed:2; + a_uint32_t port3_mac_speed:2; + a_uint32_t port4_mac_speed:2; + a_uint32_t _reserved1:8; +}; + +union port5_status_u { + a_uint32_t val; + struct port5_status bf; +}; + +/*[register] PORT6_STATUS*/ +#define PORT6_STATUS +#define PORT6_STATUS_ADDRESS 0x64 +#define PORT6_STATUS_NUM 1 +#define PORT6_STATUS_INC 0x4 +#define PORT6_STATUS_TYPE REG_TYPE_RO +#define PORT6_STATUS_DEFAULT 0x0 + /*[field] PORT6_STATUS*/ + #define PORT6_STATUS_PORT6_STATUS + #define PORT6_STATUS_PORT6_STATUS_OFFSET 0 + #define PORT6_STATUS_PORT6_STATUS_LEN 8 + #define PORT6_STATUS_PORT6_STATUS_DEFAULT 0x0 + +struct port6_status { + a_uint32_t port6_status:8; + a_uint32_t _reserved0:24; +}; + +union port6_status_u { + a_uint32_t val; + struct port6_status bf; +}; + +/*[register] RESERVED_REGS_0*/ +#define RESERVED_REGS_0 +#define RESERVED_REGS_0_ADDRESS 0x70 +#define RESERVED_REGS_0_NUM 1 +#define RESERVED_REGS_0_INC 0x4 +#define RESERVED_REGS_0_TYPE REG_TYPE_RW +#define RESERVED_REGS_0_DEFAULT 0x0 + /*[field] SPARE_REGS_0*/ + #define RESERVED_REGS_0_SPARE_REGS_0 + #define RESERVED_REGS_0_SPARE_REGS_0_OFFSET 0 + #define RESERVED_REGS_0_SPARE_REGS_0_LEN 32 + #define RESERVED_REGS_0_SPARE_REGS_0_DEFAULT 0x0 + +struct reserved_regs_0 { + a_uint32_t spare_regs_0:32; +}; + +union reserved_regs_0_u { + a_uint32_t val; + struct reserved_regs_0 bf; +}; + +/*[register] RESERVED_REGS_1*/ +#define RESERVED_REGS_1 +#define RESERVED_REGS_1_ADDRESS 0x74 +#define RESERVED_REGS_1_NUM 1 +#define RESERVED_REGS_1_INC 0x4 +#define RESERVED_REGS_1_TYPE REG_TYPE_RW +#define RESERVED_REGS_1_DEFAULT 0x0 + /*[field] SPARE_REGS_1*/ + #define RESERVED_REGS_1_SPARE_REGS_1 + #define RESERVED_REGS_1_SPARE_REGS_1_OFFSET 0 + #define RESERVED_REGS_1_SPARE_REGS_1_LEN 32 + #define RESERVED_REGS_1_SPARE_REGS_1_DEFAULT 0x0 + +struct reserved_regs_1 { + a_uint32_t spare_regs_1:32; +}; + +union reserved_regs_1_u { + a_uint32_t val; + struct reserved_regs_1 bf; +}; + +/*[register] RESERVED_REGS_2*/ +#define RESERVED_REGS_2 +#define RESERVED_REGS_2_ADDRESS 0x78 +#define RESERVED_REGS_2_NUM 1 +#define RESERVED_REGS_2_INC 0x4 +#define RESERVED_REGS_2_TYPE REG_TYPE_RW +#define RESERVED_REGS_2_DEFAULT 0x0 + /*[field] SPARE_REGS_2*/ + #define RESERVED_REGS_2_SPARE_REGS_2 + #define RESERVED_REGS_2_SPARE_REGS_2_OFFSET 0 + #define RESERVED_REGS_2_SPARE_REGS_2_LEN 32 + #define RESERVED_REGS_2_SPARE_REGS_2_DEFAULT 0x0 + +struct reserved_regs_2 { + a_uint32_t spare_regs_2:32; +}; + +union reserved_regs_2_u { + a_uint32_t val; + struct reserved_regs_2 bf; +}; + +/*[register] RESERVED_REGS_3*/ +#define RESERVED_REGS_3 +#define RESERVED_REGS_3_ADDRESS 0x7c +#define RESERVED_REGS_3_NUM 1 +#define RESERVED_REGS_3_INC 0x4 +#define RESERVED_REGS_3_TYPE REG_TYPE_RW +#define RESERVED_REGS_3_DEFAULT 0x0 + /*[field] SPARE_REGS_3*/ + #define RESERVED_REGS_3_SPARE_REGS_3 + #define RESERVED_REGS_3_SPARE_REGS_3_OFFSET 0 + #define RESERVED_REGS_3_SPARE_REGS_3_LEN 32 + #define RESERVED_REGS_3_SPARE_REGS_3_DEFAULT 0x0 + +struct reserved_regs_3 { + a_uint32_t spare_regs_3:32; +}; + +union reserved_regs_3_u { + a_uint32_t val; + struct reserved_regs_3 bf; +}; + +/*[register] DBG_DATA_SEL*/ +#define DBG_DATA_SEL +#define DBG_DATA_SEL_ADDRESS 0x80 +#define DBG_DATA_SEL_NUM 1 +#define DBG_DATA_SEL_INC 0x4 +#define DBG_DATA_SEL_TYPE REG_TYPE_RW +#define DBG_DATA_SEL_DEFAULT 0x0 + /*[field] DBG_DATA_SEL_DESP*/ + #define DBG_DATA_SEL_DBG_DATA_SEL_DESP + #define DBG_DATA_SEL_DBG_DATA_SEL_DESP_OFFSET 0 + #define DBG_DATA_SEL_DBG_DATA_SEL_DESP_LEN 5 + #define DBG_DATA_SEL_DBG_DATA_SEL_DESP_DEFAULT 0x0 + /*[field] DBG_DATA_SEL_SWITCH*/ + #define DBG_DATA_SEL_DBG_DATA_SEL_SWITCH + #define DBG_DATA_SEL_DBG_DATA_SEL_SWITCH_OFFSET 5 + #define DBG_DATA_SEL_DBG_DATA_SEL_SWITCH_LEN 1 + #define DBG_DATA_SEL_DBG_DATA_SEL_SWITCH_DEFAULT 0x0 + +struct dbg_data_sel { + a_uint32_t dbg_data_sel_desp:5; + a_uint32_t dbg_data_sel_switch:1; + a_uint32_t _reserved0:26; +}; + +union dbg_data_sel_u { + a_uint32_t val; + struct dbg_data_sel bf; +}; + + + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_init.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_init.h new file mode 100755 index 000000000..0ec05ff5e --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_init.h @@ -0,0 +1,117 @@ +/* + * 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. + */ + + +/** + * @defgroup hppe_init _HPPE_INIT_H_ + * @{ + */ +#ifndef _HPPE_INIT_H_ +#define _HPPE_INIT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "init/ssdk_init.h" + +#define HPPE_GCC_UNIPHY_REG_INC 0x100 +#define HPPE_TO_XGMAC_PORT_ID(port_id) (port_id - 5) +#define HPPE_TO_GMAC_PORT_ID(port_id) (port_id -1) +#define HPPE_FCS_LEN 4 + +#define HPPE_MUX_PORT1 5 +#define HPPE_MUX_PORT2 6 + +#define HPPE_GCC_UNIPHY_PSGMII_SOFT_RESET 0x3ff2 +#define HPPE_GCC_UNIPHY_USXGMII_SOFT_RESET 0x36 +#define HPPE_MAX_PORT_NUM 6 +#define HPPE_GCC_UNIPHY_USXGMII_XPCS_RESET 0x4 +#define HPPE_GCC_UNIPHY_USXGMII_XPCS_RELEASE_RESET 0x0 + + +#define HPPE_UNIPHY_BASE1 0x10000 +#define HPPE_UNIPHY_BASE2 0x20000 +#define HPPE_UNIPHY_MAX_DIRECT_ACCESS_REG 0x7fff +#define HPPE_UNIPHY_INDIRECT_REG_ADDR 0x83fc +#define HPPE_UNIPHY_INDIRECT_HIGH_ADDR 0x1fff00 +#define HPPE_UNIPHY_INDIRECT_LOW_ADDR 0xff +#define HPPE_UNIPHY_INDIRECT_DATA 0x20 +#define UNIPHY_CALIBRATION_DONE 0x1 +#define UNIPHY_10GR_LINKUP 0x1 +#define UNIPHY_10GR_LINK_LOSS 0x7 +#define UNIPHY_ATHEROS_NEGOTIATION 0x0 +#define UNIPHY_STANDARD_NEGOTIATION 0x1 +#define UNIPHY_CH0_QSGMII_SGMII_MODE 0x0 +#define UNIPHY_CH0_PSGMII_MODE 0x1 +#define UNIPHY_CH0_SGMII_MODE 0x0 +#define UNIPHY_CH0_QSGMII_MODE 0x1 +#define UNIPHY_SGMII_MODE_ENABLE 0x1 +#define UNIPHY_SGMII_MODE_DISABLE 0x0 +#define UNIPHY_SGMIIPLUS_MODE_ENABLE 0x1 +#define UNIPHY_SGMIIPLUS_MODE_DISABLE 0x0 +#define UNIPHY_XPCS_MODE_ENABLE 0x1 +#define UNIPHY_XPCS_MODE_DISABLE 0x0 +#define UNIPHY_PHY_SGMII_MODE 0x3 +#define UNIPHY_PHY_SGMIIPLUS_MODE 0x5 +#define UNIPHY_SGMII_CHANNEL1_DISABLE 0x0 +#define UNIPHY_SGMII_CHANNEL1_ENABLE 0x1 +#define UNIPHY_SGMII_CHANNEL4_DISABLE 0x0 +#define UNIPHY_SGMII_CHANNEL4_ENABLE 0x1 +#define UNIPHY_FORCE_SPEED_ENABLE 0x1 + +#define SGMII_1000M_SOURCE1_CLOCK1 0x101 +#define SGMII_100M_SOURCE1_CLOCK1 0x109 +#define SGMII_10M_SOURCE1_CLOCK1 0x109 +#define SGMII_1000M_SOURCE2_CLOCK1 0x301 +#define SGMII_100M_SOURCE2_CLOCK1 0x309 +#define SGMII_10M_SOURCE2_CLOCK1 0x309 +#define SGMII_1000M_CLOCK2 0x0 +#define SGMII_100M_CLOCK2 0x0 +#define SGMII_10M_CLOCK2 0x9 +#define UNIPHY_MISC2_REG_OFFSET 0x218 +#define UNIPHY_PLL_RESET_REG_OFFSET 0x780 +#define UNIPHY_MISC2_REG_VALUE 0x70 +#define UNIPHY_MISC2_REG_SGMII_PLUS_MODE 0x50 +#define UNIPHY_PLL_RESET_REG_VALUE 0x02bf +#define UNIPHY_PLL_RESET_REG_DEFAULT_VALUE 0x02ff +#define UNIPHY_MISC2_REG_SGMII_MODE 0x30 +#define UNIPHY_FORCE_SPEED_MODE_ENABLE 0x1 + +#define AQ_PHY_AUTO_STATUS_REG 0x70001 +#define AQ_PHY_LINK_STATUS_REG 0x7c800 +#define AQ_PHY_FLOWCTRL_STATUS_REG 0x7c810 +#define PHY_MII_STATUS_REG 0x11 + + +#define MALIBU_PHY_QSGMII 0x8504 +#define MALIBU_PHY_MODE_REG 0x1f +#define MALIBU_PSGMII_PHY_ADDR 0x5 +#define MALIBU_MODE_CHANAGE_RESET 0x0 +#define MALIBU_MODE_RESET_DEFAULT_VALUE 0x5f +#define MALIBU_MODE_RESET_REG 0x0 + +sw_error_t hppe_init(a_uint32_t dev_id, ssdk_init_cfg *cfg); +a_bool_t hppe_mac_port_valid_check(a_uint32_t dev_id, fal_port_t port_id); +a_bool_t hppe_xgmac_port_check(fal_port_t port_id); +sw_error_t hppe_cleanup(a_uint32_t dev_id); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _HPPE_INIT_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_ip.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_ip.h new file mode 100755 index 000000000..e3f17fba8 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_ip.h @@ -0,0 +1,2696 @@ +/* + * 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 + * @{ + */ +#ifndef _HPPE_IP_H_ +#define _HPPE_IP_H_ + +#define MY_MAC_TBL_MAX_ENTRY 8 +#define L3_VSI_MAX_ENTRY 32 +#define L3_VSI_EXT_MAX_ENTRY 32 +#define NETWORK_ROUTE_IP_MAX_ENTRY 32 +#define NETWORK_ROUTE_IP_EXT_MAX_ENTRY 32 +#define NETWORK_ROUTE_ACTION_MAX_ENTRY 32 +#define L3_VP_PORT_TBL_MAX_ENTRY 256 +#define IN_L3_IF_TBL_MAX_ENTRY 256 +#define HOST_IPV6_MCAST_TBL_MAX_ENTRY 1536 +#define HOST_IPV4_MCAST_TBL_MAX_ENTRY 3072 +#define HOST_TBL_MAX_ENTRY 6144 +#define HOST_IPV6_TBL_MAX_ENTRY 3072 +#define IN_NEXTHOP_TBL_MAX_ENTRY 2560 +#define EG_L3_IF_TBL_MAX_ENTRY 256 +#define IN_PUB_IP_ADDR_TBL_MAX_ENTRY 16 +#define RT_INTERFACE_CNT_TBL_MAX_ENTRY 512 + +#ifndef IP_MINI +sw_error_t +hppe_rt_interface_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union rt_interface_cnt_tbl_u *value); + +sw_error_t +hppe_rt_interface_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union rt_interface_cnt_tbl_u *value); + +sw_error_t +hppe_my_mac_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union my_mac_tbl_u *value); + +sw_error_t +hppe_my_mac_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union my_mac_tbl_u *value); + +sw_error_t +hppe_l3_vsi_get( + a_uint32_t dev_id, + a_uint32_t index, + union l3_vsi_u *value); + +sw_error_t +hppe_l3_vsi_set( + a_uint32_t dev_id, + a_uint32_t index, + union l3_vsi_u *value); + +sw_error_t +hppe_l3_vsi_ext_get( + a_uint32_t dev_id, + a_uint32_t index, + union l3_vsi_ext_u *value); + +sw_error_t +hppe_l3_vsi_ext_set( + a_uint32_t dev_id, + a_uint32_t index, + union l3_vsi_ext_u *value); + +sw_error_t +hppe_in_pub_ip_addr_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union in_pub_ip_addr_tbl_u *value); + +sw_error_t +hppe_in_pub_ip_addr_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union in_pub_ip_addr_tbl_u *value); + +sw_error_t +hppe_network_route_ip_get( + a_uint32_t dev_id, + a_uint32_t index, + union network_route_ip_u *value); + +sw_error_t +hppe_network_route_ip_set( + a_uint32_t dev_id, + a_uint32_t index, + union network_route_ip_u *value); + +sw_error_t +hppe_network_route_ip_ext_get( + a_uint32_t dev_id, + a_uint32_t index, + union network_route_ip_ext_u *value); + +sw_error_t +hppe_network_route_ip_ext_set( + a_uint32_t dev_id, + a_uint32_t index, + union network_route_ip_ext_u *value); + +sw_error_t +hppe_network_route_action_get( + a_uint32_t dev_id, + a_uint32_t index, + union network_route_action_u *value); + +sw_error_t +hppe_network_route_action_set( + a_uint32_t dev_id, + a_uint32_t index, + union network_route_action_u *value); +#endif +#if ((!defined IN_IP_MINI) || (!defined IN_FLOW_MINI)) +sw_error_t +hppe_l3_route_ctrl_get( + a_uint32_t dev_id, + union l3_route_ctrl_u *value); + +sw_error_t +hppe_l3_route_ctrl_set( + a_uint32_t dev_id, + union l3_route_ctrl_u *value); + +sw_error_t +hppe_l3_route_ctrl_ext_get( + a_uint32_t dev_id, + union l3_route_ctrl_ext_u *value); + +sw_error_t +hppe_l3_route_ctrl_ext_set( + a_uint32_t dev_id, + union l3_route_ctrl_ext_u *value); +#endif +#ifndef IN_IP_MINI +sw_error_t +hppe_host_tbl_op_get( + a_uint32_t dev_id, + union host_tbl_op_u *value); + +sw_error_t +hppe_host_tbl_op_set( + a_uint32_t dev_id, + union host_tbl_op_u *value); +#endif +#if ((!defined IN_IP_MINI) || (!defined IN_FLOW_MINI)) +sw_error_t +hppe_host_tbl_op_data0_get( + a_uint32_t dev_id, + union host_tbl_op_data0_u *value); + +sw_error_t +hppe_host_tbl_op_data0_set( + a_uint32_t dev_id, + union host_tbl_op_data0_u *value); + +sw_error_t +hppe_host_tbl_op_data1_get( + a_uint32_t dev_id, + union host_tbl_op_data1_u *value); + +sw_error_t +hppe_host_tbl_op_data1_set( + a_uint32_t dev_id, + union host_tbl_op_data1_u *value); + +sw_error_t +hppe_host_tbl_op_data2_get( + a_uint32_t dev_id, + union host_tbl_op_data2_u *value); + +sw_error_t +hppe_host_tbl_op_data2_set( + a_uint32_t dev_id, + union host_tbl_op_data2_u *value); + +sw_error_t +hppe_host_tbl_op_data3_get( + a_uint32_t dev_id, + union host_tbl_op_data3_u *value); + +sw_error_t +hppe_host_tbl_op_data3_set( + a_uint32_t dev_id, + union host_tbl_op_data3_u *value); + +sw_error_t +hppe_host_tbl_op_data4_get( + a_uint32_t dev_id, + union host_tbl_op_data4_u *value); + +sw_error_t +hppe_host_tbl_op_data4_set( + a_uint32_t dev_id, + union host_tbl_op_data4_u *value); +#endif +#ifndef IN_IP_MINI +sw_error_t +hppe_host_tbl_op_data5_get( + a_uint32_t dev_id, + union host_tbl_op_data5_u *value); + +sw_error_t +hppe_host_tbl_op_data5_set( + a_uint32_t dev_id, + union host_tbl_op_data5_u *value); + +sw_error_t +hppe_host_tbl_op_data6_get( + a_uint32_t dev_id, + union host_tbl_op_data6_u *value); + +sw_error_t +hppe_host_tbl_op_data6_set( + a_uint32_t dev_id, + union host_tbl_op_data6_u *value); + +sw_error_t +hppe_host_tbl_op_data7_get( + a_uint32_t dev_id, + union host_tbl_op_data7_u *value); + +sw_error_t +hppe_host_tbl_op_data7_set( + a_uint32_t dev_id, + union host_tbl_op_data7_u *value); + +sw_error_t +hppe_host_tbl_op_data8_get( + a_uint32_t dev_id, + union host_tbl_op_data8_u *value); + +sw_error_t +hppe_host_tbl_op_data8_set( + a_uint32_t dev_id, + union host_tbl_op_data8_u *value); + +sw_error_t +hppe_host_tbl_op_data9_get( + a_uint32_t dev_id, + union host_tbl_op_data9_u *value); + +sw_error_t +hppe_host_tbl_op_data9_set( + a_uint32_t dev_id, + union host_tbl_op_data9_u *value); + +sw_error_t +hppe_host_tbl_op_rslt_get( + a_uint32_t dev_id, + union host_tbl_op_rslt_u *value); + +sw_error_t +hppe_host_tbl_op_rslt_set( + a_uint32_t dev_id, + union host_tbl_op_rslt_u *value); + +sw_error_t +hppe_host_tbl_rd_op_get( + a_uint32_t dev_id, + union host_tbl_rd_op_u *value); + +sw_error_t +hppe_host_tbl_rd_op_set( + a_uint32_t dev_id, + union host_tbl_rd_op_u *value); +#endif +#if ((!defined IN_IP_MINI) || (!defined IN_FLOW_MINI)) +sw_error_t +hppe_host_tbl_rd_op_data0_get( + a_uint32_t dev_id, + union host_tbl_rd_op_data0_u *value); + +sw_error_t +hppe_host_tbl_rd_op_data0_set( + a_uint32_t dev_id, + union host_tbl_rd_op_data0_u *value); + +sw_error_t +hppe_host_tbl_rd_op_data1_get( + a_uint32_t dev_id, + union host_tbl_rd_op_data1_u *value); + +sw_error_t +hppe_host_tbl_rd_op_data1_set( + a_uint32_t dev_id, + union host_tbl_rd_op_data1_u *value); + +sw_error_t +hppe_host_tbl_rd_op_data2_get( + a_uint32_t dev_id, + union host_tbl_rd_op_data2_u *value); + +sw_error_t +hppe_host_tbl_rd_op_data2_set( + a_uint32_t dev_id, + union host_tbl_rd_op_data2_u *value); + +sw_error_t +hppe_host_tbl_rd_op_data3_get( + a_uint32_t dev_id, + union host_tbl_rd_op_data3_u *value); + +sw_error_t +hppe_host_tbl_rd_op_data3_set( + a_uint32_t dev_id, + union host_tbl_rd_op_data3_u *value); + +sw_error_t +hppe_host_tbl_rd_op_data4_get( + a_uint32_t dev_id, + union host_tbl_rd_op_data4_u *value); + +sw_error_t +hppe_host_tbl_rd_op_data4_set( + a_uint32_t dev_id, + union host_tbl_rd_op_data4_u *value); +#endif +#ifndef IN_IP_MINI +sw_error_t +hppe_host_tbl_rd_op_data5_get( + a_uint32_t dev_id, + union host_tbl_rd_op_data5_u *value); + +sw_error_t +hppe_host_tbl_rd_op_data5_set( + a_uint32_t dev_id, + union host_tbl_rd_op_data5_u *value); + +sw_error_t +hppe_host_tbl_rd_op_data6_get( + a_uint32_t dev_id, + union host_tbl_rd_op_data6_u *value); + +sw_error_t +hppe_host_tbl_rd_op_data6_set( + a_uint32_t dev_id, + union host_tbl_rd_op_data6_u *value); + +sw_error_t +hppe_host_tbl_rd_op_data7_get( + a_uint32_t dev_id, + union host_tbl_rd_op_data7_u *value); + +sw_error_t +hppe_host_tbl_rd_op_data7_set( + a_uint32_t dev_id, + union host_tbl_rd_op_data7_u *value); + +sw_error_t +hppe_host_tbl_rd_op_data8_get( + a_uint32_t dev_id, + union host_tbl_rd_op_data8_u *value); + +sw_error_t +hppe_host_tbl_rd_op_data8_set( + a_uint32_t dev_id, + union host_tbl_rd_op_data8_u *value); + +sw_error_t +hppe_host_tbl_rd_op_data9_get( + a_uint32_t dev_id, + union host_tbl_rd_op_data9_u *value); + +sw_error_t +hppe_host_tbl_rd_op_data9_set( + a_uint32_t dev_id, + union host_tbl_rd_op_data9_u *value); + +sw_error_t +hppe_host_tbl_rd_op_rslt_get( + a_uint32_t dev_id, + union host_tbl_rd_op_rslt_u *value); + +sw_error_t +hppe_host_tbl_rd_op_rslt_set( + a_uint32_t dev_id, + union host_tbl_rd_op_rslt_u *value); + +sw_error_t +hppe_host_tbl_rd_rslt_data0_get( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data0_u *value); + +sw_error_t +hppe_host_tbl_rd_rslt_data0_set( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data0_u *value); + +sw_error_t +hppe_host_tbl_rd_rslt_data1_get( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data1_u *value); + +sw_error_t +hppe_host_tbl_rd_rslt_data1_set( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data1_u *value); + +sw_error_t +hppe_host_tbl_rd_rslt_data2_get( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data2_u *value); + +sw_error_t +hppe_host_tbl_rd_rslt_data2_set( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data2_u *value); + +sw_error_t +hppe_host_tbl_rd_rslt_data3_get( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data3_u *value); + +sw_error_t +hppe_host_tbl_rd_rslt_data3_set( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data3_u *value); + +sw_error_t +hppe_host_tbl_rd_rslt_data4_get( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data4_u *value); + +sw_error_t +hppe_host_tbl_rd_rslt_data4_set( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data4_u *value); + +sw_error_t +hppe_host_tbl_rd_rslt_data5_get( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data5_u *value); + +sw_error_t +hppe_host_tbl_rd_rslt_data5_set( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data5_u *value); + +sw_error_t +hppe_host_tbl_rd_rslt_data6_get( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data6_u *value); + +sw_error_t +hppe_host_tbl_rd_rslt_data6_set( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data6_u *value); + +sw_error_t +hppe_host_tbl_rd_rslt_data7_get( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data7_u *value); + +sw_error_t +hppe_host_tbl_rd_rslt_data7_set( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data7_u *value); + +sw_error_t +hppe_host_tbl_rd_rslt_data8_get( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data8_u *value); + +sw_error_t +hppe_host_tbl_rd_rslt_data8_set( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data8_u *value); + +sw_error_t +hppe_host_tbl_rd_rslt_data9_get( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data9_u *value); + +sw_error_t +hppe_host_tbl_rd_rslt_data9_set( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data9_u *value); + +sw_error_t +hppe_l3_dbg_cmd_get( + a_uint32_t dev_id, + union l3_dbg_cmd_u *value); + +sw_error_t +hppe_l3_dbg_cmd_set( + a_uint32_t dev_id, + union l3_dbg_cmd_u *value); + +sw_error_t +hppe_l3_dbg_wr_data_get( + a_uint32_t dev_id, + union l3_dbg_wr_data_u *value); + +sw_error_t +hppe_l3_dbg_wr_data_set( + a_uint32_t dev_id, + union l3_dbg_wr_data_u *value); + +sw_error_t +hppe_l3_dbg_rd_data_get( + a_uint32_t dev_id, + union l3_dbg_rd_data_u *value); + +sw_error_t +hppe_l3_dbg_rd_data_set( + a_uint32_t dev_id, + union l3_dbg_rd_data_u *value); +#endif +sw_error_t +hppe_l3_vp_port_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l3_vp_port_tbl_u *value); + +sw_error_t +hppe_l3_vp_port_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l3_vp_port_tbl_u *value); +#if ((!defined IN_IP_MINI) || (defined IN_PPPOE)) +sw_error_t +hppe_in_l3_if_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union in_l3_if_tbl_u *value); + +sw_error_t +hppe_in_l3_if_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union in_l3_if_tbl_u *value); +#endif +#ifndef IN_IP_MINI +sw_error_t +hppe_host_ipv6_mcast_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union host_ipv6_mcast_tbl_u *value); + +sw_error_t +hppe_host_ipv6_mcast_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union host_ipv6_mcast_tbl_u *value); + +sw_error_t +hppe_host_ipv4_mcast_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union host_ipv4_mcast_tbl_u *value); + +sw_error_t +hppe_host_ipv4_mcast_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union host_ipv4_mcast_tbl_u *value); + +sw_error_t +hppe_host_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union host_tbl_u *value); + +sw_error_t +hppe_host_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union host_tbl_u *value); + +sw_error_t +hppe_host_ipv6_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union host_ipv6_tbl_u *value); + +sw_error_t +hppe_host_ipv6_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union host_ipv6_tbl_u *value); + +sw_error_t +hppe_in_nexthop_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union in_nexthop_tbl_u *value); + +sw_error_t +hppe_in_nexthop_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union in_nexthop_tbl_u *value); +#endif +#if ((!defined IN_IP_MINI) || (defined IN_PPPOE)) +sw_error_t +hppe_eg_l3_if_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union eg_l3_if_tbl_u *value); + +sw_error_t +hppe_eg_l3_if_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union eg_l3_if_tbl_u *value); +#endif +#ifndef IN_IP_MINI +sw_error_t +hppe_my_mac_tbl_mac_da_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_my_mac_tbl_mac_da_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_my_mac_tbl_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_my_mac_tbl_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vsi_l3_if_index_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vsi_l3_if_index_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vsi_l2_ipv6_mc_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vsi_l2_ipv6_mc_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vsi_l3_if_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vsi_l3_if_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vsi_l2_ipv6_mc_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vsi_l2_ipv6_mc_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vsi_l2_ipv4_mc_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vsi_l2_ipv4_mc_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vsi_l2_ipv4_mc_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vsi_l2_ipv4_mc_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vsi_ext_ip_arp_sg_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vsi_ext_ip_arp_sg_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vsi_ext_ipv6_sg_svlan_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vsi_ext_ipv6_sg_svlan_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vsi_ext_ip_nd_sg_cvlan_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vsi_ext_ip_nd_sg_cvlan_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vsi_ext_ip_nd_sg_vio_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vsi_ext_ip_nd_sg_vio_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vsi_ext_ipv4_sg_port_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vsi_ext_ipv4_sg_port_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vsi_ext_ip_nd_sg_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vsi_ext_ip_nd_sg_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vsi_ext_ipv4_sg_svlan_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vsi_ext_ipv4_sg_svlan_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vsi_ext_ipv4_sg_cvlan_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vsi_ext_ipv4_sg_cvlan_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vsi_ext_ip_arp_sg_svlan_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vsi_ext_ip_arp_sg_svlan_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vsi_ext_ip_nd_sg_svlan_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vsi_ext_ip_nd_sg_svlan_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vsi_ext_ipv6_sg_vio_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vsi_ext_ipv6_sg_vio_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vsi_ext_ip_nd_sg_port_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vsi_ext_ip_nd_sg_port_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vsi_ext_ip_arp_src_unk_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vsi_ext_ip_arp_src_unk_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vsi_ext_ipv6_sg_port_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vsi_ext_ipv6_sg_port_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vsi_ext_ipv4_src_unk_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vsi_ext_ipv4_src_unk_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vsi_ext_ip_arp_sg_vio_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vsi_ext_ip_arp_sg_vio_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vsi_ext_ip_arp_sg_port_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vsi_ext_ip_arp_sg_port_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vsi_ext_ipv4_sg_vio_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vsi_ext_ipv4_sg_vio_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vsi_ext_ipv6_src_unk_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vsi_ext_ipv6_src_unk_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vsi_ext_ipv6_sg_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vsi_ext_ipv6_sg_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vsi_ext_ip_arp_sg_cvlan_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vsi_ext_ip_arp_sg_cvlan_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vsi_ext_ip_nd_src_unk_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vsi_ext_ip_nd_src_unk_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vsi_ext_ipv4_sg_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vsi_ext_ipv4_sg_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vsi_ext_ipv6_sg_cvlan_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vsi_ext_ipv6_sg_cvlan_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_network_route_ip_ip_addr_mask_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_network_route_ip_ip_addr_mask_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_network_route_ip_ip_addr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_network_route_ip_ip_addr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_network_route_ip_ext_entry_type_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_network_route_ip_ext_entry_type_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_network_route_ip_ext_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_network_route_ip_ext_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_network_route_action_lan_wan_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_network_route_action_lan_wan_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_network_route_action_fwd_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_network_route_action_fwd_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_network_route_action_dst_info_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_network_route_action_dst_info_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_route_ctrl_flow_src_if_check_de_acce_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l3_route_ctrl_flow_src_if_check_de_acce_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l3_route_ctrl_pppoe_multicast_cmd_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l3_route_ctrl_pppoe_multicast_cmd_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l3_route_ctrl_ip_mtu_fail_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l3_route_ctrl_ip_mtu_fail_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l3_route_ctrl_flow_src_if_check_cmd_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l3_route_ctrl_flow_src_if_check_cmd_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l3_route_ctrl_icmp_rdt_de_acce_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l3_route_ctrl_icmp_rdt_de_acce_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l3_route_ctrl_flow_de_acce_cmd_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l3_route_ctrl_flow_de_acce_cmd_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l3_route_ctrl_ip_mtu_fail_de_acce_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l3_route_ctrl_ip_mtu_fail_de_acce_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l3_route_ctrl_flow_sync_mismatch_cmd_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l3_route_ctrl_flow_sync_mismatch_cmd_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l3_route_ctrl_flow_service_code_loop_de_acce_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l3_route_ctrl_flow_service_code_loop_de_acce_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l3_route_ctrl_flow_sync_mismatch_de_acce_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l3_route_ctrl_flow_sync_mismatch_de_acce_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l3_route_ctrl_ip_mtu_df_fail_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l3_route_ctrl_ip_mtu_df_fail_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l3_route_ctrl_flow_service_code_loop_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l3_route_ctrl_flow_service_code_loop_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l3_route_ctrl_ip_mru_check_fail_de_acce_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l3_route_ctrl_ip_mru_check_fail_de_acce_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l3_route_ctrl_ip_prefix_bc_cmd_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l3_route_ctrl_ip_prefix_bc_cmd_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l3_route_ctrl_ip_mtu_df_fail_de_acce_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l3_route_ctrl_ip_mtu_df_fail_de_acce_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l3_route_ctrl_pppoe_multicast_de_acce_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l3_route_ctrl_pppoe_multicast_de_acce_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l3_route_ctrl_ip_mru_check_fail_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l3_route_ctrl_ip_mru_check_fail_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l3_route_ctrl_icmp_rdt_cmd_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l3_route_ctrl_icmp_rdt_cmd_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l3_route_ctrl_ip_prefix_bc_de_acce_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l3_route_ctrl_ip_prefix_bc_de_acce_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l3_route_ctrl_ext_flow_service_code_loop_en_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l3_route_ctrl_ext_flow_service_code_loop_en_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l3_route_ctrl_ext_host_hash_mode_0_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l3_route_ctrl_ext_host_hash_mode_0_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l3_route_ctrl_ext_host_hash_mode_1_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l3_route_ctrl_ext_host_hash_mode_1_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l3_route_ctrl_ext_ip_route_mismatch_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l3_route_ctrl_ext_ip_route_mismatch_set( + a_uint32_t dev_id, + unsigned int value); + + +sw_error_t +hppe_host_tbl_op_entry_index_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_op_entry_index_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_op_cmd_id_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_op_cmd_id_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_op_byp_rslt_en_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_op_byp_rslt_en_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_op_op_mode_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_op_op_mode_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_op_op_type_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_op_op_type_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_op_op_result_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_op_op_result_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_op_busy_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_op_busy_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_op_hash_block_bitmap_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_op_hash_block_bitmap_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_op_data0_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_op_data0_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_op_data1_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_op_data1_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_op_data2_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_op_data2_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_op_data3_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_op_data3_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_op_data4_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_op_data4_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_op_data5_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_op_data5_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_op_data6_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_op_data6_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_op_data7_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_op_data7_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_op_data8_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_op_data8_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_op_data9_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_op_data9_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_op_rslt_op_rslt_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_op_rslt_op_rslt_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_op_rslt_valid_cnt_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_op_rslt_valid_cnt_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_op_rslt_entry_index_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_op_rslt_entry_index_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_op_rslt_cmd_id_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_op_rslt_cmd_id_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_rd_op_entry_index_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_rd_op_entry_index_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_rd_op_cmd_id_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_rd_op_cmd_id_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_rd_op_byp_rslt_en_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_rd_op_byp_rslt_en_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_rd_op_op_mode_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_rd_op_op_mode_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_rd_op_op_type_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_rd_op_op_type_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_rd_op_op_result_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_rd_op_op_result_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_rd_op_busy_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_rd_op_busy_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_rd_op_hash_block_bitmap_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_rd_op_hash_block_bitmap_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_rd_op_data0_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_rd_op_data0_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_rd_op_data1_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_rd_op_data1_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_rd_op_data2_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_rd_op_data2_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_rd_op_data3_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_rd_op_data3_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_rd_op_data4_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_rd_op_data4_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_rd_op_data5_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_rd_op_data5_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_rd_op_data6_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_rd_op_data6_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_rd_op_data7_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_rd_op_data7_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_rd_op_data8_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_rd_op_data8_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_rd_op_data9_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_rd_op_data9_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_rd_op_rslt_op_rslt_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_rd_op_rslt_op_rslt_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_rd_op_rslt_valid_cnt_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_rd_op_rslt_valid_cnt_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_rd_op_rslt_entry_index_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_rd_op_rslt_entry_index_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_rd_op_rslt_cmd_id_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_rd_op_rslt_cmd_id_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_rd_rslt_data0_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_rd_rslt_data0_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_rd_rslt_data1_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_rd_rslt_data1_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_rd_rslt_data2_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_rd_rslt_data2_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_rd_rslt_data3_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_rd_rslt_data3_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_rd_rslt_data4_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_rd_rslt_data4_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_rd_rslt_data5_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_rd_rslt_data5_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_rd_rslt_data6_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_rd_rslt_data6_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_rd_rslt_data7_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_rd_rslt_data7_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_rd_rslt_data8_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_rd_rslt_data8_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_host_tbl_rd_rslt_data9_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_host_tbl_rd_rslt_data9_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l3_dbg_cmd_type_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l3_dbg_cmd_type_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l3_dbg_cmd_addr_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l3_dbg_cmd_addr_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l3_dbg_wr_data_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l3_dbg_wr_data_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l3_dbg_rd_data_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l3_dbg_rd_data_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l3_vp_port_tbl_ip_arp_sg_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vp_port_tbl_ip_arp_sg_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vp_port_tbl_ipv6_sg_svlan_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vp_port_tbl_ipv6_sg_svlan_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vp_port_tbl_ip_nd_sg_cvlan_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vp_port_tbl_ip_nd_sg_cvlan_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vp_port_tbl_l3_if_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vp_port_tbl_l3_if_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vp_port_tbl_ip_nd_sg_vio_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vp_port_tbl_ip_nd_sg_vio_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vp_port_tbl_ipv4_sg_port_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vp_port_tbl_ipv4_sg_port_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vp_port_tbl_ip_nd_sg_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vp_port_tbl_ip_nd_sg_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vp_port_tbl_l3_if_index_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vp_port_tbl_l3_if_index_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vp_port_tbl_ipv4_sg_svlan_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vp_port_tbl_ipv4_sg_svlan_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vp_port_tbl_ipv4_sg_cvlan_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vp_port_tbl_ipv4_sg_cvlan_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vp_port_tbl_ip_arp_sg_svlan_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vp_port_tbl_ip_arp_sg_svlan_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vp_port_tbl_mac_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vp_port_tbl_mac_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vp_port_tbl_ip_nd_sg_svlan_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vp_port_tbl_ip_nd_sg_svlan_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vp_port_tbl_vsi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vp_port_tbl_vsi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vp_port_tbl_mac_da_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_l3_vp_port_tbl_mac_da_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_l3_vp_port_tbl_ipv6_sg_vio_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vp_port_tbl_ipv6_sg_vio_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vp_port_tbl_ip_nd_sg_port_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vp_port_tbl_ip_nd_sg_port_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vp_port_tbl_ip_arp_src_unk_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vp_port_tbl_ip_arp_src_unk_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vp_port_tbl_ipv6_sg_port_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vp_port_tbl_ipv6_sg_port_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vp_port_tbl_ipv4_src_unk_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vp_port_tbl_ipv4_src_unk_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vp_port_tbl_ip_arp_sg_port_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vp_port_tbl_ip_arp_sg_port_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vp_port_tbl_ip_arp_sg_vio_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vp_port_tbl_ip_arp_sg_vio_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vp_port_tbl_ipv4_sg_vio_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vp_port_tbl_ipv4_sg_vio_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vp_port_tbl_ipv6_src_unk_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vp_port_tbl_ipv6_src_unk_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vp_port_tbl_ip_arp_sg_cvlan_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vp_port_tbl_ip_arp_sg_cvlan_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vp_port_tbl_ipv6_sg_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vp_port_tbl_ipv6_sg_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vp_port_tbl_vsi_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vp_port_tbl_vsi_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vp_port_tbl_ip_nd_src_unk_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vp_port_tbl_ip_nd_src_unk_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vp_port_tbl_ipv4_sg_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vp_port_tbl_ipv4_sg_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_vp_port_tbl_ipv6_sg_cvlan_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_vp_port_tbl_ipv6_sg_cvlan_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_l3_if_tbl_ttl_dec_bypass_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_l3_if_tbl_ttl_dec_bypass_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_l3_if_tbl_ttl_exceed_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_l3_if_tbl_ttl_exceed_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_l3_if_tbl_mru_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_l3_if_tbl_mru_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_l3_if_tbl_ipv4_uc_route_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_l3_if_tbl_ipv4_uc_route_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_l3_if_tbl_ipv6_uc_route_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_l3_if_tbl_ipv6_uc_route_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_l3_if_tbl_ttl_exceed_de_acce_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_l3_if_tbl_ttl_exceed_de_acce_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_l3_if_tbl_icmp_trigger_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_l3_if_tbl_icmp_trigger_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_l3_if_tbl_mac_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_l3_if_tbl_mac_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_l3_if_tbl_pppoe_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_l3_if_tbl_pppoe_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_l3_if_tbl_mtu_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_l3_if_tbl_mtu_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_nexthop_tbl_ip_pub_addr_index_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_nexthop_tbl_ip_pub_addr_index_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_nexthop_tbl_cvid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_nexthop_tbl_cvid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_nexthop_tbl_post_l3_if_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_nexthop_tbl_post_l3_if_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_nexthop_tbl_mac_addr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_in_nexthop_tbl_mac_addr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_in_nexthop_tbl_port_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_nexthop_tbl_port_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_nexthop_tbl_ip_to_me_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_nexthop_tbl_ip_to_me_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_nexthop_tbl_ip_addr_dnat_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_nexthop_tbl_ip_addr_dnat_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_nexthop_tbl_type_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_nexthop_tbl_type_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_nexthop_tbl_stag_fmt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_nexthop_tbl_stag_fmt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_nexthop_tbl_vsi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_nexthop_tbl_vsi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_nexthop_tbl_svid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_nexthop_tbl_svid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_nexthop_tbl_ctag_fmt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_nexthop_tbl_ctag_fmt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_l3_if_tbl_session_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_l3_if_tbl_session_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_l3_if_tbl_mac_addr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_eg_l3_if_tbl_mac_addr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_eg_l3_if_tbl_pppoe_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_l3_if_tbl_pppoe_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_pub_ip_addr_tbl_ip_addr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_pub_ip_addr_tbl_ip_addr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rt_interface_cnt_tbl_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_rt_interface_cnt_tbl_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_rt_interface_cnt_tbl_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rt_interface_cnt_tbl_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rt_interface_cnt_tbl_drop_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_rt_interface_cnt_tbl_drop_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_rt_interface_cnt_tbl_drop_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rt_interface_cnt_tbl_drop_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + + +sw_error_t +hppe_host_ipv4_add( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_tbl_u *entry); + +sw_error_t +hppe_host_ipv6_add( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_ipv6_tbl_u *entry); + +sw_error_t +hppe_host_ipv4_mcast_add( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_ipv4_mcast_tbl_u *entry); + +sw_error_t +hppe_host_ipv6_mcast_add( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_ipv6_mcast_tbl_u *entry); + +sw_error_t +hppe_host_ipv4_del( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_tbl_u *entry); + +sw_error_t +hppe_host_ipv6_del( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_ipv6_tbl_u *entry); + +sw_error_t +hppe_host_ipv4_mcast_del( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_ipv4_mcast_tbl_u *entry); + +sw_error_t +hppe_host_ipv6_mcast_del( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_ipv6_mcast_tbl_u *entry); + +sw_error_t +hppe_host_ipv4_get( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_tbl_u *entry); + +sw_error_t +hppe_host_ipv6_get( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_ipv6_tbl_u *entry); + +sw_error_t +hppe_host_ipv4_mcast_get( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_ipv4_mcast_tbl_u *entry); + +sw_error_t +hppe_host_ipv6_mcast_get( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_ipv6_mcast_tbl_u *entry); + +sw_error_t +hppe_host_flush_common(a_uint32_t dev_id); +#endif + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_ip_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_ip_reg.h new file mode 100755 index 000000000..31be3c355 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_ip_reg.h @@ -0,0 +1,2240 @@ +/* + * 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. + */ + + +/** + * @defgroup + * @{ + */ +#ifndef _HPPE_IP_REG_H_ +#define _HPPE_IP_REG_H_ + +/*[table] MY_MAC_TBL*/ +#define MY_MAC_TBL +#define MY_MAC_TBL_ADDRESS 0x0 +#define MY_MAC_TBL_NUM 8 +#define MY_MAC_TBL_INC 0x8 +#define MY_MAC_TBL_TYPE REG_TYPE_RW +#define MY_MAC_TBL_DEFAULT 0x0 + /*[field] MAC_DA*/ + #define MY_MAC_TBL_MAC_DA + #define MY_MAC_TBL_MAC_DA_OFFSET 0 + #define MY_MAC_TBL_MAC_DA_LEN 48 + #define MY_MAC_TBL_MAC_DA_DEFAULT 0x0 + /*[field] VALID*/ + #define MY_MAC_TBL_VALID + #define MY_MAC_TBL_VALID_OFFSET 48 + #define MY_MAC_TBL_VALID_LEN 1 + #define MY_MAC_TBL_VALID_DEFAULT 0x0 + +struct my_mac_tbl { + a_uint32_t mac_da_0:32; + a_uint32_t mac_da_1:16; + a_uint32_t valid:1; + a_uint32_t _reserved0:15; +}; + +union my_mac_tbl_u { + a_uint32_t val[2]; + struct my_mac_tbl bf; +}; + +/*[register] L3_VSI*/ +#define L3_VSI +#define L3_VSI_ADDRESS 0x40 +#define L3_VSI_NUM 32 +#define L3_VSI_INC 0x4 +#define L3_VSI_TYPE REG_TYPE_RW +#define L3_VSI_DEFAULT 0x0 + /*[field] L3_IF_VALID*/ + #define L3_VSI_L3_IF_VALID + #define L3_VSI_L3_IF_VALID_OFFSET 0 + #define L3_VSI_L3_IF_VALID_LEN 1 + #define L3_VSI_L3_IF_VALID_DEFAULT 0x0 + /*[field] L3_IF_INDEX*/ + #define L3_VSI_L3_IF_INDEX + #define L3_VSI_L3_IF_INDEX_OFFSET 1 + #define L3_VSI_L3_IF_INDEX_LEN 8 + #define L3_VSI_L3_IF_INDEX_DEFAULT 0x0 + /*[field] L2_IPV4_MC_EN*/ + #define L3_VSI_L2_IPV4_MC_EN + #define L3_VSI_L2_IPV4_MC_EN_OFFSET 9 + #define L3_VSI_L2_IPV4_MC_EN_LEN 1 + #define L3_VSI_L2_IPV4_MC_EN_DEFAULT 0x0 + /*[field] L2_IPV4_MC_MODE*/ + #define L3_VSI_L2_IPV4_MC_MODE + #define L3_VSI_L2_IPV4_MC_MODE_OFFSET 10 + #define L3_VSI_L2_IPV4_MC_MODE_LEN 1 + #define L3_VSI_L2_IPV4_MC_MODE_DEFAULT 0x0 + /*[field] L2_IPV6_MC_EN*/ + #define L3_VSI_L2_IPV6_MC_EN + #define L3_VSI_L2_IPV6_MC_EN_OFFSET 11 + #define L3_VSI_L2_IPV6_MC_EN_LEN 1 + #define L3_VSI_L2_IPV6_MC_EN_DEFAULT 0x0 + /*[field] L2_IPV6_MC_MODE*/ + #define L3_VSI_L2_IPV6_MC_MODE + #define L3_VSI_L2_IPV6_MC_MODE_OFFSET 12 + #define L3_VSI_L2_IPV6_MC_MODE_LEN 1 + #define L3_VSI_L2_IPV6_MC_MODE_DEFAULT 0x0 + +struct l3_vsi { + a_uint32_t l3_if_valid:1; + a_uint32_t l3_if_index:8; + a_uint32_t l2_ipv4_mc_en:1; + a_uint32_t l2_ipv4_mc_mode:1; + a_uint32_t l2_ipv6_mc_en:1; + a_uint32_t l2_ipv6_mc_mode:1; + a_uint32_t _reserved0:19; +}; + +union l3_vsi_u { + a_uint32_t val; + struct l3_vsi bf; +}; + +/*[register] L3_VSI_EXT*/ +#define L3_VSI_EXT +#define L3_VSI_EXT_ADDRESS 0xc0 +#define L3_VSI_EXT_NUM 32 +#define L3_VSI_EXT_INC 0x4 +#define L3_VSI_EXT_TYPE REG_TYPE_RW +#define L3_VSI_EXT_DEFAULT 0x0 + /*[field] IPV4_SG_EN*/ + #define L3_VSI_EXT_IPV4_SG_EN + #define L3_VSI_EXT_IPV4_SG_EN_OFFSET 0 + #define L3_VSI_EXT_IPV4_SG_EN_LEN 1 + #define L3_VSI_EXT_IPV4_SG_EN_DEFAULT 0x0 + /*[field] IPV4_SG_VIO_CMD*/ + #define L3_VSI_EXT_IPV4_SG_VIO_CMD + #define L3_VSI_EXT_IPV4_SG_VIO_CMD_OFFSET 1 + #define L3_VSI_EXT_IPV4_SG_VIO_CMD_LEN 2 + #define L3_VSI_EXT_IPV4_SG_VIO_CMD_DEFAULT 0x0 + /*[field] IPV4_SG_PORT_EN*/ + #define L3_VSI_EXT_IPV4_SG_PORT_EN + #define L3_VSI_EXT_IPV4_SG_PORT_EN_OFFSET 3 + #define L3_VSI_EXT_IPV4_SG_PORT_EN_LEN 1 + #define L3_VSI_EXT_IPV4_SG_PORT_EN_DEFAULT 0x0 + /*[field] IPV4_SG_SVLAN_EN*/ + #define L3_VSI_EXT_IPV4_SG_SVLAN_EN + #define L3_VSI_EXT_IPV4_SG_SVLAN_EN_OFFSET 4 + #define L3_VSI_EXT_IPV4_SG_SVLAN_EN_LEN 1 + #define L3_VSI_EXT_IPV4_SG_SVLAN_EN_DEFAULT 0x0 + /*[field] IPV4_SG_CVLAN_EN*/ + #define L3_VSI_EXT_IPV4_SG_CVLAN_EN + #define L3_VSI_EXT_IPV4_SG_CVLAN_EN_OFFSET 5 + #define L3_VSI_EXT_IPV4_SG_CVLAN_EN_LEN 1 + #define L3_VSI_EXT_IPV4_SG_CVLAN_EN_DEFAULT 0x0 + /*[field] IPV4_SRC_UNK_CMD*/ + #define L3_VSI_EXT_IPV4_SRC_UNK_CMD + #define L3_VSI_EXT_IPV4_SRC_UNK_CMD_OFFSET 6 + #define L3_VSI_EXT_IPV4_SRC_UNK_CMD_LEN 2 + #define L3_VSI_EXT_IPV4_SRC_UNK_CMD_DEFAULT 0x0 + /*[field] IPV6_SG_EN*/ + #define L3_VSI_EXT_IPV6_SG_EN + #define L3_VSI_EXT_IPV6_SG_EN_OFFSET 8 + #define L3_VSI_EXT_IPV6_SG_EN_LEN 1 + #define L3_VSI_EXT_IPV6_SG_EN_DEFAULT 0x0 + /*[field] IPV6_SG_VIO_CMD*/ + #define L3_VSI_EXT_IPV6_SG_VIO_CMD + #define L3_VSI_EXT_IPV6_SG_VIO_CMD_OFFSET 9 + #define L3_VSI_EXT_IPV6_SG_VIO_CMD_LEN 2 + #define L3_VSI_EXT_IPV6_SG_VIO_CMD_DEFAULT 0x0 + /*[field] IPV6_SG_PORT_EN*/ + #define L3_VSI_EXT_IPV6_SG_PORT_EN + #define L3_VSI_EXT_IPV6_SG_PORT_EN_OFFSET 11 + #define L3_VSI_EXT_IPV6_SG_PORT_EN_LEN 1 + #define L3_VSI_EXT_IPV6_SG_PORT_EN_DEFAULT 0x0 + /*[field] IPV6_SG_SVLAN_EN*/ + #define L3_VSI_EXT_IPV6_SG_SVLAN_EN + #define L3_VSI_EXT_IPV6_SG_SVLAN_EN_OFFSET 12 + #define L3_VSI_EXT_IPV6_SG_SVLAN_EN_LEN 1 + #define L3_VSI_EXT_IPV6_SG_SVLAN_EN_DEFAULT 0x0 + /*[field] IPV6_SG_CVLAN_EN*/ + #define L3_VSI_EXT_IPV6_SG_CVLAN_EN + #define L3_VSI_EXT_IPV6_SG_CVLAN_EN_OFFSET 13 + #define L3_VSI_EXT_IPV6_SG_CVLAN_EN_LEN 1 + #define L3_VSI_EXT_IPV6_SG_CVLAN_EN_DEFAULT 0x0 + /*[field] IPV6_SRC_UNK_CMD*/ + #define L3_VSI_EXT_IPV6_SRC_UNK_CMD + #define L3_VSI_EXT_IPV6_SRC_UNK_CMD_OFFSET 14 + #define L3_VSI_EXT_IPV6_SRC_UNK_CMD_LEN 2 + #define L3_VSI_EXT_IPV6_SRC_UNK_CMD_DEFAULT 0x0 + /*[field] IP_ARP_SG_EN*/ + #define L3_VSI_EXT_IP_ARP_SG_EN + #define L3_VSI_EXT_IP_ARP_SG_EN_OFFSET 16 + #define L3_VSI_EXT_IP_ARP_SG_EN_LEN 1 + #define L3_VSI_EXT_IP_ARP_SG_EN_DEFAULT 0x0 + /*[field] IP_ARP_SG_VIO_CMD*/ + #define L3_VSI_EXT_IP_ARP_SG_VIO_CMD + #define L3_VSI_EXT_IP_ARP_SG_VIO_CMD_OFFSET 17 + #define L3_VSI_EXT_IP_ARP_SG_VIO_CMD_LEN 2 + #define L3_VSI_EXT_IP_ARP_SG_VIO_CMD_DEFAULT 0x0 + /*[field] IP_ARP_SG_PORT_EN*/ + #define L3_VSI_EXT_IP_ARP_SG_PORT_EN + #define L3_VSI_EXT_IP_ARP_SG_PORT_EN_OFFSET 19 + #define L3_VSI_EXT_IP_ARP_SG_PORT_EN_LEN 1 + #define L3_VSI_EXT_IP_ARP_SG_PORT_EN_DEFAULT 0x0 + /*[field] IP_ARP_SG_SVLAN_EN*/ + #define L3_VSI_EXT_IP_ARP_SG_SVLAN_EN + #define L3_VSI_EXT_IP_ARP_SG_SVLAN_EN_OFFSET 20 + #define L3_VSI_EXT_IP_ARP_SG_SVLAN_EN_LEN 1 + #define L3_VSI_EXT_IP_ARP_SG_SVLAN_EN_DEFAULT 0x0 + /*[field] IP_ARP_SG_CVLAN_EN*/ + #define L3_VSI_EXT_IP_ARP_SG_CVLAN_EN + #define L3_VSI_EXT_IP_ARP_SG_CVLAN_EN_OFFSET 21 + #define L3_VSI_EXT_IP_ARP_SG_CVLAN_EN_LEN 1 + #define L3_VSI_EXT_IP_ARP_SG_CVLAN_EN_DEFAULT 0x0 + /*[field] IP_ARP_SRC_UNK_CMD*/ + #define L3_VSI_EXT_IP_ARP_SRC_UNK_CMD + #define L3_VSI_EXT_IP_ARP_SRC_UNK_CMD_OFFSET 22 + #define L3_VSI_EXT_IP_ARP_SRC_UNK_CMD_LEN 2 + #define L3_VSI_EXT_IP_ARP_SRC_UNK_CMD_DEFAULT 0x0 + /*[field] IP_ND_SG_EN*/ + #define L3_VSI_EXT_IP_ND_SG_EN + #define L3_VSI_EXT_IP_ND_SG_EN_OFFSET 24 + #define L3_VSI_EXT_IP_ND_SG_EN_LEN 1 + #define L3_VSI_EXT_IP_ND_SG_EN_DEFAULT 0x0 + /*[field] IP_ND_SG_VIO_CMD*/ + #define L3_VSI_EXT_IP_ND_SG_VIO_CMD + #define L3_VSI_EXT_IP_ND_SG_VIO_CMD_OFFSET 25 + #define L3_VSI_EXT_IP_ND_SG_VIO_CMD_LEN 2 + #define L3_VSI_EXT_IP_ND_SG_VIO_CMD_DEFAULT 0x0 + /*[field] IP_ND_SG_PORT_EN*/ + #define L3_VSI_EXT_IP_ND_SG_PORT_EN + #define L3_VSI_EXT_IP_ND_SG_PORT_EN_OFFSET 27 + #define L3_VSI_EXT_IP_ND_SG_PORT_EN_LEN 1 + #define L3_VSI_EXT_IP_ND_SG_PORT_EN_DEFAULT 0x0 + /*[field] IP_ND_SG_SVLAN_EN*/ + #define L3_VSI_EXT_IP_ND_SG_SVLAN_EN + #define L3_VSI_EXT_IP_ND_SG_SVLAN_EN_OFFSET 28 + #define L3_VSI_EXT_IP_ND_SG_SVLAN_EN_LEN 1 + #define L3_VSI_EXT_IP_ND_SG_SVLAN_EN_DEFAULT 0x0 + /*[field] IP_ND_SG_CVLAN_EN*/ + #define L3_VSI_EXT_IP_ND_SG_CVLAN_EN + #define L3_VSI_EXT_IP_ND_SG_CVLAN_EN_OFFSET 29 + #define L3_VSI_EXT_IP_ND_SG_CVLAN_EN_LEN 1 + #define L3_VSI_EXT_IP_ND_SG_CVLAN_EN_DEFAULT 0x0 + /*[field] IP_ND_SRC_UNK_CMD*/ + #define L3_VSI_EXT_IP_ND_SRC_UNK_CMD + #define L3_VSI_EXT_IP_ND_SRC_UNK_CMD_OFFSET 30 + #define L3_VSI_EXT_IP_ND_SRC_UNK_CMD_LEN 2 + #define L3_VSI_EXT_IP_ND_SRC_UNK_CMD_DEFAULT 0x0 + +struct l3_vsi_ext { + a_uint32_t ipv4_sg_en:1; + a_uint32_t ipv4_sg_vio_cmd:2; + a_uint32_t ipv4_sg_port_en:1; + a_uint32_t ipv4_sg_svlan_en:1; + a_uint32_t ipv4_sg_cvlan_en:1; + a_uint32_t ipv4_src_unk_cmd:2; + a_uint32_t ipv6_sg_en:1; + a_uint32_t ipv6_sg_vio_cmd:2; + a_uint32_t ipv6_sg_port_en:1; + a_uint32_t ipv6_sg_svlan_en:1; + a_uint32_t ipv6_sg_cvlan_en:1; + a_uint32_t ipv6_src_unk_cmd:2; + a_uint32_t ip_arp_sg_en:1; + a_uint32_t ip_arp_sg_vio_cmd:2; + a_uint32_t ip_arp_sg_port_en:1; + a_uint32_t ip_arp_sg_svlan_en:1; + a_uint32_t ip_arp_sg_cvlan_en:1; + a_uint32_t ip_arp_src_unk_cmd:2; + a_uint32_t ip_nd_sg_en:1; + a_uint32_t ip_nd_sg_vio_cmd:2; + a_uint32_t ip_nd_sg_port_en:1; + a_uint32_t ip_nd_sg_svlan_en:1; + a_uint32_t ip_nd_sg_cvlan_en:1; + a_uint32_t ip_nd_src_unk_cmd:2; +}; + +union l3_vsi_ext_u { + a_uint32_t val; + struct l3_vsi_ext bf; +}; + +/*[register] NETWORK_ROUTE_IP*/ +#define NETWORK_ROUTE_IP +#define NETWORK_ROUTE_IP_ADDRESS 0x140 +#define NETWORK_ROUTE_IP_NUM 32 +#define NETWORK_ROUTE_IP_INC 0x8 +#define NETWORK_ROUTE_IP_TYPE REG_TYPE_RW +#define NETWORK_ROUTE_IP_DEFAULT 0x0 + /*[field] IP_ADDR*/ + #define NETWORK_ROUTE_IP_IP_ADDR + #define NETWORK_ROUTE_IP_IP_ADDR_OFFSET 0 + #define NETWORK_ROUTE_IP_IP_ADDR_LEN 32 + #define NETWORK_ROUTE_IP_IP_ADDR_DEFAULT 0x0 + /*[field] IP_ADDR_MASK*/ + #define NETWORK_ROUTE_IP_IP_ADDR_MASK + #define NETWORK_ROUTE_IP_IP_ADDR_MASK_OFFSET 32 + #define NETWORK_ROUTE_IP_IP_ADDR_MASK_LEN 32 + #define NETWORK_ROUTE_IP_IP_ADDR_MASK_DEFAULT 0x0 + +struct network_route_ip { + a_uint32_t ip_addr:32; + a_uint32_t ip_addr_mask:32; +}; + +union network_route_ip_u { + a_uint32_t val[2]; + struct network_route_ip bf; +}; + +/*[register] NETWORK_ROUTE_IP_EXT*/ +#define NETWORK_ROUTE_IP_EXT +#define NETWORK_ROUTE_IP_EXT_ADDRESS 0x240 +#define NETWORK_ROUTE_IP_EXT_NUM 32 +#define NETWORK_ROUTE_IP_EXT_INC 0x4 +#define NETWORK_ROUTE_IP_EXT_TYPE REG_TYPE_RW +#define NETWORK_ROUTE_IP_EXT_DEFAULT 0x0 + /*[field] VALID*/ + #define NETWORK_ROUTE_IP_EXT_VALID + #define NETWORK_ROUTE_IP_EXT_VALID_OFFSET 0 + #define NETWORK_ROUTE_IP_EXT_VALID_LEN 1 + #define NETWORK_ROUTE_IP_EXT_VALID_DEFAULT 0x0 + /*[field] ENTRY_TYPE*/ + #define NETWORK_ROUTE_IP_EXT_ENTRY_TYPE + #define NETWORK_ROUTE_IP_EXT_ENTRY_TYPE_OFFSET 1 + #define NETWORK_ROUTE_IP_EXT_ENTRY_TYPE_LEN 1 + #define NETWORK_ROUTE_IP_EXT_ENTRY_TYPE_DEFAULT 0x0 + +struct network_route_ip_ext { + a_uint32_t valid:1; + a_uint32_t entry_type:1; + a_uint32_t _reserved0:30; +}; + +union network_route_ip_ext_u { + a_uint32_t val; + struct network_route_ip_ext bf; +}; + +/*[register] NETWORK_ROUTE_ACTION*/ +#define NETWORK_ROUTE_ACTION +#define NETWORK_ROUTE_ACTION_ADDRESS 0x2c0 +#define NETWORK_ROUTE_ACTION_NUM 32 +#define NETWORK_ROUTE_ACTION_INC 0x4 +#define NETWORK_ROUTE_ACTION_TYPE REG_TYPE_RW +#define NETWORK_ROUTE_ACTION_DEFAULT 0x0 + /*[field] FWD_CMD*/ + #define NETWORK_ROUTE_ACTION_FWD_CMD + #define NETWORK_ROUTE_ACTION_FWD_CMD_OFFSET 0 + #define NETWORK_ROUTE_ACTION_FWD_CMD_LEN 2 + #define NETWORK_ROUTE_ACTION_FWD_CMD_DEFAULT 0x0 + /*[field] DST_INFO*/ + #define NETWORK_ROUTE_ACTION_DST_INFO + #define NETWORK_ROUTE_ACTION_DST_INFO_OFFSET 2 + #define NETWORK_ROUTE_ACTION_DST_INFO_LEN 14 + #define NETWORK_ROUTE_ACTION_DST_INFO_DEFAULT 0x0 + /*[field] LAN_WAN*/ + #define NETWORK_ROUTE_ACTION_LAN_WAN + #define NETWORK_ROUTE_ACTION_LAN_WAN_OFFSET 16 + #define NETWORK_ROUTE_ACTION_LAN_WAN_LEN 1 + #define NETWORK_ROUTE_ACTION_LAN_WAN_DEFAULT 0x0 + +struct network_route_action { + a_uint32_t fwd_cmd:2; + a_uint32_t dst_info:14; + a_uint32_t lan_wan:1; + a_uint32_t _reserved0:15; +}; + +union network_route_action_u { + a_uint32_t val; + struct network_route_action bf; +}; + +/*[register] L3_ROUTE_CTRL*/ +#define L3_ROUTE_CTRL +#define L3_ROUTE_CTRL_ADDRESS 0x340 +#define L3_ROUTE_CTRL_NUM 1 +#define L3_ROUTE_CTRL_INC 0x4 +#define L3_ROUTE_CTRL_TYPE REG_TYPE_RW +#define L3_ROUTE_CTRL_DEFAULT 0xdbc36db + /*[field] IP_MRU_CHECK_FAIL*/ + #define L3_ROUTE_CTRL_IP_MRU_CHECK_FAIL + #define L3_ROUTE_CTRL_IP_MRU_CHECK_FAIL_OFFSET 0 + #define L3_ROUTE_CTRL_IP_MRU_CHECK_FAIL_LEN 2 + #define L3_ROUTE_CTRL_IP_MRU_CHECK_FAIL_DEFAULT 0x3 + /*[field] IP_MRU_CHECK_FAIL_DE_ACCE*/ + #define L3_ROUTE_CTRL_IP_MRU_CHECK_FAIL_DE_ACCE + #define L3_ROUTE_CTRL_IP_MRU_CHECK_FAIL_DE_ACCE_OFFSET 2 + #define L3_ROUTE_CTRL_IP_MRU_CHECK_FAIL_DE_ACCE_LEN 1 + #define L3_ROUTE_CTRL_IP_MRU_CHECK_FAIL_DE_ACCE_DEFAULT 0x0 + /*[field] IP_MTU_FAIL*/ + #define L3_ROUTE_CTRL_IP_MTU_FAIL + #define L3_ROUTE_CTRL_IP_MTU_FAIL_OFFSET 3 + #define L3_ROUTE_CTRL_IP_MTU_FAIL_LEN 2 + #define L3_ROUTE_CTRL_IP_MTU_FAIL_DEFAULT 0x3 + /*[field] IP_MTU_FAIL_DE_ACCE*/ + #define L3_ROUTE_CTRL_IP_MTU_FAIL_DE_ACCE + #define L3_ROUTE_CTRL_IP_MTU_FAIL_DE_ACCE_OFFSET 5 + #define L3_ROUTE_CTRL_IP_MTU_FAIL_DE_ACCE_LEN 1 + #define L3_ROUTE_CTRL_IP_MTU_FAIL_DE_ACCE_DEFAULT 0x0 + /*[field] IP_MTU_DF_FAIL*/ + #define L3_ROUTE_CTRL_IP_MTU_DF_FAIL + #define L3_ROUTE_CTRL_IP_MTU_DF_FAIL_OFFSET 6 + #define L3_ROUTE_CTRL_IP_MTU_DF_FAIL_LEN 2 + #define L3_ROUTE_CTRL_IP_MTU_DF_FAIL_DEFAULT 0x3 + /*[field] IP_MTU_DF_FAIL_DE_ACCE*/ + #define L3_ROUTE_CTRL_IP_MTU_DF_FAIL_DE_ACCE + #define L3_ROUTE_CTRL_IP_MTU_DF_FAIL_DE_ACCE_OFFSET 8 + #define L3_ROUTE_CTRL_IP_MTU_DF_FAIL_DE_ACCE_LEN 1 + #define L3_ROUTE_CTRL_IP_MTU_DF_FAIL_DE_ACCE_DEFAULT 0x0 + /*[field] IP_PREFIX_BC_CMD*/ + #define L3_ROUTE_CTRL_IP_PREFIX_BC_CMD + #define L3_ROUTE_CTRL_IP_PREFIX_BC_CMD_OFFSET 9 + #define L3_ROUTE_CTRL_IP_PREFIX_BC_CMD_LEN 2 + #define L3_ROUTE_CTRL_IP_PREFIX_BC_CMD_DEFAULT 0x3 + /*[field] IP_PREFIX_BC_DE_ACCE*/ + #define L3_ROUTE_CTRL_IP_PREFIX_BC_DE_ACCE + #define L3_ROUTE_CTRL_IP_PREFIX_BC_DE_ACCE_OFFSET 11 + #define L3_ROUTE_CTRL_IP_PREFIX_BC_DE_ACCE_LEN 1 + #define L3_ROUTE_CTRL_IP_PREFIX_BC_DE_ACCE_DEFAULT 0x0 + /*[field] FLOW_SRC_IF_CHECK_CMD*/ + #define L3_ROUTE_CTRL_FLOW_SRC_IF_CHECK_CMD + #define L3_ROUTE_CTRL_FLOW_SRC_IF_CHECK_CMD_OFFSET 12 + #define L3_ROUTE_CTRL_FLOW_SRC_IF_CHECK_CMD_LEN 2 + #define L3_ROUTE_CTRL_FLOW_SRC_IF_CHECK_CMD_DEFAULT 0x3 + /*[field] FLOW_SRC_IF_CHECK_DE_ACCE*/ + #define L3_ROUTE_CTRL_FLOW_SRC_IF_CHECK_DE_ACCE + #define L3_ROUTE_CTRL_FLOW_SRC_IF_CHECK_DE_ACCE_OFFSET 14 + #define L3_ROUTE_CTRL_FLOW_SRC_IF_CHECK_DE_ACCE_LEN 1 + #define L3_ROUTE_CTRL_FLOW_SRC_IF_CHECK_DE_ACCE_DEFAULT 0x0 + /*[field] FLOW_SERVICE_CODE_LOOP*/ + #define L3_ROUTE_CTRL_FLOW_SERVICE_CODE_LOOP + #define L3_ROUTE_CTRL_FLOW_SERVICE_CODE_LOOP_OFFSET 15 + #define L3_ROUTE_CTRL_FLOW_SERVICE_CODE_LOOP_LEN 2 + #define L3_ROUTE_CTRL_FLOW_SERVICE_CODE_LOOP_DEFAULT 0x0 + /*[field] FLOW_SERVICE_CODE_LOOP_DE_ACCE*/ + #define L3_ROUTE_CTRL_FLOW_SERVICE_CODE_LOOP_DE_ACCE + #define L3_ROUTE_CTRL_FLOW_SERVICE_CODE_LOOP_DE_ACCE_OFFSET 17 + #define L3_ROUTE_CTRL_FLOW_SERVICE_CODE_LOOP_DE_ACCE_LEN 1 + #define L3_ROUTE_CTRL_FLOW_SERVICE_CODE_LOOP_DE_ACCE_DEFAULT 0x0 + /*[field] FLOW_DE_ACCE_CMD*/ + #define L3_ROUTE_CTRL_FLOW_DE_ACCE_CMD + #define L3_ROUTE_CTRL_FLOW_DE_ACCE_CMD_OFFSET 18 + #define L3_ROUTE_CTRL_FLOW_DE_ACCE_CMD_LEN 2 + #define L3_ROUTE_CTRL_FLOW_DE_ACCE_CMD_DEFAULT 0x3 + /*[field] FLOW_SYNC_MISMATCH_CMD*/ + #define L3_ROUTE_CTRL_FLOW_SYNC_MISMATCH_CMD + #define L3_ROUTE_CTRL_FLOW_SYNC_MISMATCH_CMD_OFFSET 20 + #define L3_ROUTE_CTRL_FLOW_SYNC_MISMATCH_CMD_LEN 2 + #define L3_ROUTE_CTRL_FLOW_SYNC_MISMATCH_CMD_DEFAULT 0x3 + /*[field] FLOW_SYNC_MISMATCH_DE_ACCE*/ + #define L3_ROUTE_CTRL_FLOW_SYNC_MISMATCH_DE_ACCE + #define L3_ROUTE_CTRL_FLOW_SYNC_MISMATCH_DE_ACCE_OFFSET 22 + #define L3_ROUTE_CTRL_FLOW_SYNC_MISMATCH_DE_ACCE_LEN 1 + #define L3_ROUTE_CTRL_FLOW_SYNC_MISMATCH_DE_ACCE_DEFAULT 0x0 + /*[field] ICMP_RDT_CMD*/ + #define L3_ROUTE_CTRL_ICMP_RDT_CMD + #define L3_ROUTE_CTRL_ICMP_RDT_CMD_OFFSET 23 + #define L3_ROUTE_CTRL_ICMP_RDT_CMD_LEN 2 + #define L3_ROUTE_CTRL_ICMP_RDT_CMD_DEFAULT 0x3 + /*[field] ICMP_RDT_DE_ACCE*/ + #define L3_ROUTE_CTRL_ICMP_RDT_DE_ACCE + #define L3_ROUTE_CTRL_ICMP_RDT_DE_ACCE_OFFSET 25 + #define L3_ROUTE_CTRL_ICMP_RDT_DE_ACCE_LEN 1 + #define L3_ROUTE_CTRL_ICMP_RDT_DE_ACCE_DEFAULT 0x0 + /*[field] PPPOE_MULTICAST_CMD*/ + #define L3_ROUTE_CTRL_PPPOE_MULTICAST_CMD + #define L3_ROUTE_CTRL_PPPOE_MULTICAST_CMD_OFFSET 26 + #define L3_ROUTE_CTRL_PPPOE_MULTICAST_CMD_LEN 2 + #define L3_ROUTE_CTRL_PPPOE_MULTICAST_CMD_DEFAULT 0x3 + /*[field] PPPOE_MULTICAST_DE_ACCE*/ + #define L3_ROUTE_CTRL_PPPOE_MULTICAST_DE_ACCE + #define L3_ROUTE_CTRL_PPPOE_MULTICAST_DE_ACCE_OFFSET 28 + #define L3_ROUTE_CTRL_PPPOE_MULTICAST_DE_ACCE_LEN 1 + #define L3_ROUTE_CTRL_PPPOE_MULTICAST_DE_ACCE_DEFAULT 0x0 + +struct l3_route_ctrl { + a_uint32_t ip_mru_check_fail:2; + a_uint32_t ip_mru_check_fail_de_acce:1; + a_uint32_t ip_mtu_fail:2; + a_uint32_t ip_mtu_fail_de_acce:1; + a_uint32_t ip_mtu_df_fail:2; + a_uint32_t ip_mtu_df_fail_de_acce:1; + a_uint32_t ip_prefix_bc_cmd:2; + a_uint32_t ip_prefix_bc_de_acce:1; + a_uint32_t flow_src_if_check_cmd:2; + a_uint32_t flow_src_if_check_de_acce:1; + a_uint32_t flow_service_code_loop:2; + a_uint32_t flow_service_code_loop_de_acce:1; + a_uint32_t flow_de_acce_cmd:2; + a_uint32_t flow_sync_mismatch_cmd:2; + a_uint32_t flow_sync_mismatch_de_acce:1; + a_uint32_t icmp_rdt_cmd:2; + a_uint32_t icmp_rdt_de_acce:1; + a_uint32_t pppoe_multicast_cmd:2; + a_uint32_t pppoe_multicast_de_acce:1; + a_uint32_t _reserved0:3; +}; + +union l3_route_ctrl_u { + a_uint32_t val; + struct l3_route_ctrl bf; +}; + +/*[register] L3_ROUTE_CTRL_EXT*/ +#define L3_ROUTE_CTRL_EXT +#define L3_ROUTE_CTRL_EXT_ADDRESS 0x344 +#define L3_ROUTE_CTRL_EXT_NUM 1 +#define L3_ROUTE_CTRL_EXT_INC 0x4 +#define L3_ROUTE_CTRL_EXT_TYPE REG_TYPE_RW +#define L3_ROUTE_CTRL_EXT_DEFAULT 0x23 + /*[field] IP_ROUTE_MISMATCH*/ + #define L3_ROUTE_CTRL_EXT_IP_ROUTE_MISMATCH + #define L3_ROUTE_CTRL_EXT_IP_ROUTE_MISMATCH_OFFSET 0 + #define L3_ROUTE_CTRL_EXT_IP_ROUTE_MISMATCH_LEN 2 + #define L3_ROUTE_CTRL_EXT_IP_ROUTE_MISMATCH_DEFAULT 0x3 + /*[field] FLOW_SERVICE_CODE_LOOP_EN*/ + #define L3_ROUTE_CTRL_EXT_FLOW_SERVICE_CODE_LOOP_EN + #define L3_ROUTE_CTRL_EXT_FLOW_SERVICE_CODE_LOOP_EN_OFFSET 2 + #define L3_ROUTE_CTRL_EXT_FLOW_SERVICE_CODE_LOOP_EN_LEN 1 + #define L3_ROUTE_CTRL_EXT_FLOW_SERVICE_CODE_LOOP_EN_DEFAULT 0x0 + /*[field] HOST_HASH_MODE_0*/ + #define L3_ROUTE_CTRL_EXT_HOST_HASH_MODE_0 + #define L3_ROUTE_CTRL_EXT_HOST_HASH_MODE_0_OFFSET 3 + #define L3_ROUTE_CTRL_EXT_HOST_HASH_MODE_0_LEN 2 + #define L3_ROUTE_CTRL_EXT_HOST_HASH_MODE_0_DEFAULT 0x0 + /*[field] HOST_HASH_MODE_1*/ + #define L3_ROUTE_CTRL_EXT_HOST_HASH_MODE_1 + #define L3_ROUTE_CTRL_EXT_HOST_HASH_MODE_1_OFFSET 5 + #define L3_ROUTE_CTRL_EXT_HOST_HASH_MODE_1_LEN 2 + #define L3_ROUTE_CTRL_EXT_HOST_HASH_MODE_1_DEFAULT 0x1 + +struct l3_route_ctrl_ext { + a_uint32_t ip_route_mismatch:2; + a_uint32_t flow_service_code_loop_en:1; + a_uint32_t host_hash_mode_0:2; + a_uint32_t host_hash_mode_1:2; + a_uint32_t l3_flow_copy_escape:1; + a_uint32_t _reserved0:24; +}; + +union l3_route_ctrl_ext_u { + a_uint32_t val; + struct l3_route_ctrl_ext bf; +}; + +/*[register] HOST_TBL_OP*/ +#define HOST_TBL_OP +#define HOST_TBL_OP_ADDRESS 0x4bc +#define HOST_TBL_OP_NUM 1 +#define HOST_TBL_OP_INC 0x4 +#define HOST_TBL_OP_TYPE REG_TYPE_RW +#define HOST_TBL_OP_DEFAULT 0x0 + /*[field] CMD_ID*/ + #define HOST_TBL_OP_CMD_ID + #define HOST_TBL_OP_CMD_ID_OFFSET 0 + #define HOST_TBL_OP_CMD_ID_LEN 4 + #define HOST_TBL_OP_CMD_ID_DEFAULT 0x0 + /*[field] BYP_RSLT_EN*/ + #define HOST_TBL_OP_BYP_RSLT_EN + #define HOST_TBL_OP_BYP_RSLT_EN_OFFSET 4 + #define HOST_TBL_OP_BYP_RSLT_EN_LEN 1 + #define HOST_TBL_OP_BYP_RSLT_EN_DEFAULT 0x0 + /*[field] OP_TYPE*/ + #define HOST_TBL_OP_OP_TYPE + #define HOST_TBL_OP_OP_TYPE_OFFSET 5 + #define HOST_TBL_OP_OP_TYPE_LEN 3 + #define HOST_TBL_OP_OP_TYPE_DEFAULT 0x0 + /*[field] HASH_BLOCK_BITMAP*/ + #define HOST_TBL_OP_HASH_BLOCK_BITMAP + #define HOST_TBL_OP_HASH_BLOCK_BITMAP_OFFSET 8 + #define HOST_TBL_OP_HASH_BLOCK_BITMAP_LEN 2 + #define HOST_TBL_OP_HASH_BLOCK_BITMAP_DEFAULT 0x0 + /*[field] OP_MODE*/ + #define HOST_TBL_OP_OP_MODE + #define HOST_TBL_OP_OP_MODE_OFFSET 10 + #define HOST_TBL_OP_OP_MODE_LEN 1 + #define HOST_TBL_OP_OP_MODE_DEFAULT 0x0 + /*[field] ENTRY_INDEX*/ + #define HOST_TBL_OP_ENTRY_INDEX + #define HOST_TBL_OP_ENTRY_INDEX_OFFSET 11 + #define HOST_TBL_OP_ENTRY_INDEX_LEN 13 + #define HOST_TBL_OP_ENTRY_INDEX_DEFAULT 0x0 + /*[field] OP_RESULT*/ + #define HOST_TBL_OP_OP_RESULT + #define HOST_TBL_OP_OP_RESULT_OFFSET 24 + #define HOST_TBL_OP_OP_RESULT_LEN 1 + #define HOST_TBL_OP_OP_RESULT_DEFAULT 0x0 + /*[field] BUSY*/ + #define HOST_TBL_OP_BUSY + #define HOST_TBL_OP_BUSY_OFFSET 25 + #define HOST_TBL_OP_BUSY_LEN 1 + #define HOST_TBL_OP_BUSY_DEFAULT 0x0 + +struct host_tbl_op { + a_uint32_t cmd_id:4; + a_uint32_t byp_rslt_en:1; + a_uint32_t op_type:3; + a_uint32_t hash_block_bitmap:2; + a_uint32_t op_mode:1; + a_uint32_t entry_index:13; + a_uint32_t op_result:1; + a_uint32_t busy:1; + a_uint32_t _reserved0:6; +}; + +union host_tbl_op_u { + a_uint32_t val; + struct host_tbl_op bf; +}; + +/*[register] HOST_TBL_OP_DATA0*/ +#define HOST_TBL_OP_DATA0 +#define HOST_TBL_OP_DATA0_ADDRESS 0x4c0 +#define HOST_TBL_OP_DATA0_NUM 1 +#define HOST_TBL_OP_DATA0_INC 0x4 +#define HOST_TBL_OP_DATA0_TYPE REG_TYPE_RW +#define HOST_TBL_OP_DATA0_DEFAULT 0x0 + /*[field] DATA*/ + #define HOST_TBL_OP_DATA0_DATA + #define HOST_TBL_OP_DATA0_DATA_OFFSET 0 + #define HOST_TBL_OP_DATA0_DATA_LEN 32 + #define HOST_TBL_OP_DATA0_DATA_DEFAULT 0x0 + +struct host_tbl_op_data0 { + a_uint32_t data:32; +}; + +union host_tbl_op_data0_u { + a_uint32_t val; + struct host_tbl_op_data0 bf; +}; + +/*[register] HOST_TBL_OP_DATA1*/ +#define HOST_TBL_OP_DATA1 +#define HOST_TBL_OP_DATA1_ADDRESS 0x4c4 +#define HOST_TBL_OP_DATA1_NUM 1 +#define HOST_TBL_OP_DATA1_INC 0x4 +#define HOST_TBL_OP_DATA1_TYPE REG_TYPE_RW +#define HOST_TBL_OP_DATA1_DEFAULT 0x0 + /*[field] DATA*/ + #define HOST_TBL_OP_DATA1_DATA + #define HOST_TBL_OP_DATA1_DATA_OFFSET 0 + #define HOST_TBL_OP_DATA1_DATA_LEN 32 + #define HOST_TBL_OP_DATA1_DATA_DEFAULT 0x0 + +struct host_tbl_op_data1 { + a_uint32_t data:32; +}; + +union host_tbl_op_data1_u { + a_uint32_t val; + struct host_tbl_op_data1 bf; +}; + +/*[register] HOST_TBL_OP_DATA2*/ +#define HOST_TBL_OP_DATA2 +#define HOST_TBL_OP_DATA2_ADDRESS 0x4c8 +#define HOST_TBL_OP_DATA2_NUM 1 +#define HOST_TBL_OP_DATA2_INC 0x4 +#define HOST_TBL_OP_DATA2_TYPE REG_TYPE_RW +#define HOST_TBL_OP_DATA2_DEFAULT 0x0 + /*[field] DATA*/ + #define HOST_TBL_OP_DATA2_DATA + #define HOST_TBL_OP_DATA2_DATA_OFFSET 0 + #define HOST_TBL_OP_DATA2_DATA_LEN 32 + #define HOST_TBL_OP_DATA2_DATA_DEFAULT 0x0 + +struct host_tbl_op_data2 { + a_uint32_t data:32; +}; + +union host_tbl_op_data2_u { + a_uint32_t val; + struct host_tbl_op_data2 bf; +}; + +/*[register] HOST_TBL_OP_DATA3*/ +#define HOST_TBL_OP_DATA3 +#define HOST_TBL_OP_DATA3_ADDRESS 0x4cc +#define HOST_TBL_OP_DATA3_NUM 1 +#define HOST_TBL_OP_DATA3_INC 0x4 +#define HOST_TBL_OP_DATA3_TYPE REG_TYPE_RW +#define HOST_TBL_OP_DATA3_DEFAULT 0x0 + /*[field] DATA*/ + #define HOST_TBL_OP_DATA3_DATA + #define HOST_TBL_OP_DATA3_DATA_OFFSET 0 + #define HOST_TBL_OP_DATA3_DATA_LEN 32 + #define HOST_TBL_OP_DATA3_DATA_DEFAULT 0x0 + +struct host_tbl_op_data3 { + a_uint32_t data:32; +}; + +union host_tbl_op_data3_u { + a_uint32_t val; + struct host_tbl_op_data3 bf; +}; + +/*[register] HOST_TBL_OP_DATA4*/ +#define HOST_TBL_OP_DATA4 +#define HOST_TBL_OP_DATA4_ADDRESS 0x4d0 +#define HOST_TBL_OP_DATA4_NUM 1 +#define HOST_TBL_OP_DATA4_INC 0x4 +#define HOST_TBL_OP_DATA4_TYPE REG_TYPE_RW +#define HOST_TBL_OP_DATA4_DEFAULT 0x0 + /*[field] DATA*/ + #define HOST_TBL_OP_DATA4_DATA + #define HOST_TBL_OP_DATA4_DATA_OFFSET 0 + #define HOST_TBL_OP_DATA4_DATA_LEN 32 + #define HOST_TBL_OP_DATA4_DATA_DEFAULT 0x0 + +struct host_tbl_op_data4 { + a_uint32_t data:32; +}; + +union host_tbl_op_data4_u { + a_uint32_t val; + struct host_tbl_op_data4 bf; +}; + +/*[register] HOST_TBL_OP_DATA5*/ +#define HOST_TBL_OP_DATA5 +#define HOST_TBL_OP_DATA5_ADDRESS 0x4d4 +#define HOST_TBL_OP_DATA5_NUM 1 +#define HOST_TBL_OP_DATA5_INC 0x4 +#define HOST_TBL_OP_DATA5_TYPE REG_TYPE_RW +#define HOST_TBL_OP_DATA5_DEFAULT 0x0 + /*[field] DATA*/ + #define HOST_TBL_OP_DATA5_DATA + #define HOST_TBL_OP_DATA5_DATA_OFFSET 0 + #define HOST_TBL_OP_DATA5_DATA_LEN 32 + #define HOST_TBL_OP_DATA5_DATA_DEFAULT 0x0 + +struct host_tbl_op_data5 { + a_uint32_t data:32; +}; + +union host_tbl_op_data5_u { + a_uint32_t val; + struct host_tbl_op_data5 bf; +}; + +/*[register] HOST_TBL_OP_DATA6*/ +#define HOST_TBL_OP_DATA6 +#define HOST_TBL_OP_DATA6_ADDRESS 0x4d8 +#define HOST_TBL_OP_DATA6_NUM 1 +#define HOST_TBL_OP_DATA6_INC 0x4 +#define HOST_TBL_OP_DATA6_TYPE REG_TYPE_RW +#define HOST_TBL_OP_DATA6_DEFAULT 0x0 + /*[field] DATA*/ + #define HOST_TBL_OP_DATA6_DATA + #define HOST_TBL_OP_DATA6_DATA_OFFSET 0 + #define HOST_TBL_OP_DATA6_DATA_LEN 32 + #define HOST_TBL_OP_DATA6_DATA_DEFAULT 0x0 + +struct host_tbl_op_data6 { + a_uint32_t data:32; +}; + +union host_tbl_op_data6_u { + a_uint32_t val; + struct host_tbl_op_data6 bf; +}; + +/*[register] HOST_TBL_OP_DATA7*/ +#define HOST_TBL_OP_DATA7 +#define HOST_TBL_OP_DATA7_ADDRESS 0x4dc +#define HOST_TBL_OP_DATA7_NUM 1 +#define HOST_TBL_OP_DATA7_INC 0x4 +#define HOST_TBL_OP_DATA7_TYPE REG_TYPE_RW +#define HOST_TBL_OP_DATA7_DEFAULT 0x0 + /*[field] DATA*/ + #define HOST_TBL_OP_DATA7_DATA + #define HOST_TBL_OP_DATA7_DATA_OFFSET 0 + #define HOST_TBL_OP_DATA7_DATA_LEN 32 + #define HOST_TBL_OP_DATA7_DATA_DEFAULT 0x0 + +struct host_tbl_op_data7 { + a_uint32_t data:32; +}; + +union host_tbl_op_data7_u { + a_uint32_t val; + struct host_tbl_op_data7 bf; +}; + +/*[register] HOST_TBL_OP_DATA8*/ +#define HOST_TBL_OP_DATA8 +#define HOST_TBL_OP_DATA8_ADDRESS 0x4e0 +#define HOST_TBL_OP_DATA8_NUM 1 +#define HOST_TBL_OP_DATA8_INC 0x4 +#define HOST_TBL_OP_DATA8_TYPE REG_TYPE_RW +#define HOST_TBL_OP_DATA8_DEFAULT 0x0 + /*[field] DATA*/ + #define HOST_TBL_OP_DATA8_DATA + #define HOST_TBL_OP_DATA8_DATA_OFFSET 0 + #define HOST_TBL_OP_DATA8_DATA_LEN 32 + #define HOST_TBL_OP_DATA8_DATA_DEFAULT 0x0 + +struct host_tbl_op_data8 { + a_uint32_t data:32; +}; + +union host_tbl_op_data8_u { + a_uint32_t val; + struct host_tbl_op_data8 bf; +}; + +/*[register] HOST_TBL_OP_DATA9*/ +#define HOST_TBL_OP_DATA9 +#define HOST_TBL_OP_DATA9_ADDRESS 0x4e4 +#define HOST_TBL_OP_DATA9_NUM 1 +#define HOST_TBL_OP_DATA9_INC 0x4 +#define HOST_TBL_OP_DATA9_TYPE REG_TYPE_RW +#define HOST_TBL_OP_DATA9_DEFAULT 0x0 + /*[field] DATA*/ + #define HOST_TBL_OP_DATA9_DATA + #define HOST_TBL_OP_DATA9_DATA_OFFSET 0 + #define HOST_TBL_OP_DATA9_DATA_LEN 32 + #define HOST_TBL_OP_DATA9_DATA_DEFAULT 0x0 + +struct host_tbl_op_data9 { + a_uint32_t data:32; +}; + +union host_tbl_op_data9_u { + a_uint32_t val; + struct host_tbl_op_data9 bf; +}; + +/*[register] HOST_TBL_OP_RSLT*/ +#define HOST_TBL_OP_RSLT +#define HOST_TBL_OP_RSLT_ADDRESS 0x4e8 +#define HOST_TBL_OP_RSLT_NUM 1 +#define HOST_TBL_OP_RSLT_INC 0x4 +#define HOST_TBL_OP_RSLT_TYPE REG_TYPE_RO +#define HOST_TBL_OP_RSLT_DEFAULT 0x0 + /*[field] CMD_ID*/ + #define HOST_TBL_OP_RSLT_CMD_ID + #define HOST_TBL_OP_RSLT_CMD_ID_OFFSET 0 + #define HOST_TBL_OP_RSLT_CMD_ID_LEN 4 + #define HOST_TBL_OP_RSLT_CMD_ID_DEFAULT 0x0 + /*[field] OP_RSLT*/ + #define HOST_TBL_OP_RSLT_OP_RSLT + #define HOST_TBL_OP_RSLT_OP_RSLT_OFFSET 4 + #define HOST_TBL_OP_RSLT_OP_RSLT_LEN 1 + #define HOST_TBL_OP_RSLT_OP_RSLT_DEFAULT 0x0 + /*[field] ENTRY_INDEX*/ + #define HOST_TBL_OP_RSLT_ENTRY_INDEX + #define HOST_TBL_OP_RSLT_ENTRY_INDEX_OFFSET 5 + #define HOST_TBL_OP_RSLT_ENTRY_INDEX_LEN 13 + #define HOST_TBL_OP_RSLT_ENTRY_INDEX_DEFAULT 0x0 + /*[field] VALID_CNT*/ + #define HOST_TBL_OP_RSLT_VALID_CNT + #define HOST_TBL_OP_RSLT_VALID_CNT_OFFSET 18 + #define HOST_TBL_OP_RSLT_VALID_CNT_LEN 4 + #define HOST_TBL_OP_RSLT_VALID_CNT_DEFAULT 0x0 + +struct host_tbl_op_rslt { + a_uint32_t cmd_id:4; + a_uint32_t op_rslt:1; + a_uint32_t entry_index:13; + a_uint32_t valid_cnt:4; + a_uint32_t _reserved0:10; +}; + +union host_tbl_op_rslt_u { + a_uint32_t val; + struct host_tbl_op_rslt bf; +}; + +/*[register] HOST_TBL_RD_OP*/ +#define HOST_TBL_RD_OP +#define HOST_TBL_RD_OP_ADDRESS 0x4ec +#define HOST_TBL_RD_OP_NUM 1 +#define HOST_TBL_RD_OP_INC 0x4 +#define HOST_TBL_RD_OP_TYPE REG_TYPE_RW +#define HOST_TBL_RD_OP_DEFAULT 0x0 + /*[field] CMD_ID*/ + #define HOST_TBL_RD_OP_CMD_ID + #define HOST_TBL_RD_OP_CMD_ID_OFFSET 0 + #define HOST_TBL_RD_OP_CMD_ID_LEN 4 + #define HOST_TBL_RD_OP_CMD_ID_DEFAULT 0x0 + /*[field] BYP_RSLT_EN*/ + #define HOST_TBL_RD_OP_BYP_RSLT_EN + #define HOST_TBL_RD_OP_BYP_RSLT_EN_OFFSET 4 + #define HOST_TBL_RD_OP_BYP_RSLT_EN_LEN 1 + #define HOST_TBL_RD_OP_BYP_RSLT_EN_DEFAULT 0x0 + /*[field] OP_TYPE*/ + #define HOST_TBL_RD_OP_OP_TYPE + #define HOST_TBL_RD_OP_OP_TYPE_OFFSET 5 + #define HOST_TBL_RD_OP_OP_TYPE_LEN 3 + #define HOST_TBL_RD_OP_OP_TYPE_DEFAULT 0x0 + /*[field] HASH_BLOCK_BITMAP*/ + #define HOST_TBL_RD_OP_HASH_BLOCK_BITMAP + #define HOST_TBL_RD_OP_HASH_BLOCK_BITMAP_OFFSET 8 + #define HOST_TBL_RD_OP_HASH_BLOCK_BITMAP_LEN 2 + #define HOST_TBL_RD_OP_HASH_BLOCK_BITMAP_DEFAULT 0x0 + /*[field] OP_MODE*/ + #define HOST_TBL_RD_OP_OP_MODE + #define HOST_TBL_RD_OP_OP_MODE_OFFSET 10 + #define HOST_TBL_RD_OP_OP_MODE_LEN 1 + #define HOST_TBL_RD_OP_OP_MODE_DEFAULT 0x0 + /*[field] ENTRY_INDEX*/ + #define HOST_TBL_RD_OP_ENTRY_INDEX + #define HOST_TBL_RD_OP_ENTRY_INDEX_OFFSET 11 + #define HOST_TBL_RD_OP_ENTRY_INDEX_LEN 13 + #define HOST_TBL_RD_OP_ENTRY_INDEX_DEFAULT 0x0 + /*[field] OP_RESULT*/ + #define HOST_TBL_RD_OP_OP_RESULT + #define HOST_TBL_RD_OP_OP_RESULT_OFFSET 24 + #define HOST_TBL_RD_OP_OP_RESULT_LEN 1 + #define HOST_TBL_RD_OP_OP_RESULT_DEFAULT 0x0 + /*[field] BUSY*/ + #define HOST_TBL_RD_OP_BUSY + #define HOST_TBL_RD_OP_BUSY_OFFSET 25 + #define HOST_TBL_RD_OP_BUSY_LEN 1 + #define HOST_TBL_RD_OP_BUSY_DEFAULT 0x0 + +struct host_tbl_rd_op { + a_uint32_t cmd_id:4; + a_uint32_t byp_rslt_en:1; + a_uint32_t op_type:3; + a_uint32_t hash_block_bitmap:2; + a_uint32_t op_mode:1; + a_uint32_t entry_index:13; + a_uint32_t op_result:1; + a_uint32_t busy:1; + a_uint32_t _reserved0:6; +}; + +union host_tbl_rd_op_u { + a_uint32_t val; + struct host_tbl_rd_op bf; +}; + +/*[register] HOST_TBL_RD_OP_DATA0*/ +#define HOST_TBL_RD_OP_DATA0 +#define HOST_TBL_RD_OP_DATA0_ADDRESS 0x4f0 +#define HOST_TBL_RD_OP_DATA0_NUM 1 +#define HOST_TBL_RD_OP_DATA0_INC 0x4 +#define HOST_TBL_RD_OP_DATA0_TYPE REG_TYPE_RW +#define HOST_TBL_RD_OP_DATA0_DEFAULT 0x0 + /*[field] DATA*/ + #define HOST_TBL_RD_OP_DATA0_DATA + #define HOST_TBL_RD_OP_DATA0_DATA_OFFSET 0 + #define HOST_TBL_RD_OP_DATA0_DATA_LEN 32 + #define HOST_TBL_RD_OP_DATA0_DATA_DEFAULT 0x0 + +struct host_tbl_rd_op_data0 { + a_uint32_t data:32; +}; + +union host_tbl_rd_op_data0_u { + a_uint32_t val; + struct host_tbl_rd_op_data0 bf; +}; + +/*[register] HOST_TBL_RD_OP_DATA1*/ +#define HOST_TBL_RD_OP_DATA1 +#define HOST_TBL_RD_OP_DATA1_ADDRESS 0x4f4 +#define HOST_TBL_RD_OP_DATA1_NUM 1 +#define HOST_TBL_RD_OP_DATA1_INC 0x4 +#define HOST_TBL_RD_OP_DATA1_TYPE REG_TYPE_RW +#define HOST_TBL_RD_OP_DATA1_DEFAULT 0x0 + /*[field] DATA*/ + #define HOST_TBL_RD_OP_DATA1_DATA + #define HOST_TBL_RD_OP_DATA1_DATA_OFFSET 0 + #define HOST_TBL_RD_OP_DATA1_DATA_LEN 32 + #define HOST_TBL_RD_OP_DATA1_DATA_DEFAULT 0x0 + +struct host_tbl_rd_op_data1 { + a_uint32_t data:32; +}; + +union host_tbl_rd_op_data1_u { + a_uint32_t val; + struct host_tbl_rd_op_data1 bf; +}; + +/*[register] HOST_TBL_RD_OP_DATA2*/ +#define HOST_TBL_RD_OP_DATA2 +#define HOST_TBL_RD_OP_DATA2_ADDRESS 0x4f8 +#define HOST_TBL_RD_OP_DATA2_NUM 1 +#define HOST_TBL_RD_OP_DATA2_INC 0x4 +#define HOST_TBL_RD_OP_DATA2_TYPE REG_TYPE_RW +#define HOST_TBL_RD_OP_DATA2_DEFAULT 0x0 + /*[field] DATA*/ + #define HOST_TBL_RD_OP_DATA2_DATA + #define HOST_TBL_RD_OP_DATA2_DATA_OFFSET 0 + #define HOST_TBL_RD_OP_DATA2_DATA_LEN 32 + #define HOST_TBL_RD_OP_DATA2_DATA_DEFAULT 0x0 + +struct host_tbl_rd_op_data2 { + a_uint32_t data:32; +}; + +union host_tbl_rd_op_data2_u { + a_uint32_t val; + struct host_tbl_rd_op_data2 bf; +}; + +/*[register] HOST_TBL_RD_OP_DATA3*/ +#define HOST_TBL_RD_OP_DATA3 +#define HOST_TBL_RD_OP_DATA3_ADDRESS 0x4fc +#define HOST_TBL_RD_OP_DATA3_NUM 1 +#define HOST_TBL_RD_OP_DATA3_INC 0x4 +#define HOST_TBL_RD_OP_DATA3_TYPE REG_TYPE_RW +#define HOST_TBL_RD_OP_DATA3_DEFAULT 0x0 + /*[field] DATA*/ + #define HOST_TBL_RD_OP_DATA3_DATA + #define HOST_TBL_RD_OP_DATA3_DATA_OFFSET 0 + #define HOST_TBL_RD_OP_DATA3_DATA_LEN 32 + #define HOST_TBL_RD_OP_DATA3_DATA_DEFAULT 0x0 + +struct host_tbl_rd_op_data3 { + a_uint32_t data:32; +}; + +union host_tbl_rd_op_data3_u { + a_uint32_t val; + struct host_tbl_rd_op_data3 bf; +}; + +/*[register] HOST_TBL_RD_OP_DATA4*/ +#define HOST_TBL_RD_OP_DATA4 +#define HOST_TBL_RD_OP_DATA4_ADDRESS 0x500 +#define HOST_TBL_RD_OP_DATA4_NUM 1 +#define HOST_TBL_RD_OP_DATA4_INC 0x4 +#define HOST_TBL_RD_OP_DATA4_TYPE REG_TYPE_RW +#define HOST_TBL_RD_OP_DATA4_DEFAULT 0x0 + /*[field] DATA*/ + #define HOST_TBL_RD_OP_DATA4_DATA + #define HOST_TBL_RD_OP_DATA4_DATA_OFFSET 0 + #define HOST_TBL_RD_OP_DATA4_DATA_LEN 32 + #define HOST_TBL_RD_OP_DATA4_DATA_DEFAULT 0x0 + +struct host_tbl_rd_op_data4 { + a_uint32_t data:32; +}; + +union host_tbl_rd_op_data4_u { + a_uint32_t val; + struct host_tbl_rd_op_data4 bf; +}; + +/*[register] HOST_TBL_RD_OP_DATA5*/ +#define HOST_TBL_RD_OP_DATA5 +#define HOST_TBL_RD_OP_DATA5_ADDRESS 0x504 +#define HOST_TBL_RD_OP_DATA5_NUM 1 +#define HOST_TBL_RD_OP_DATA5_INC 0x4 +#define HOST_TBL_RD_OP_DATA5_TYPE REG_TYPE_RW +#define HOST_TBL_RD_OP_DATA5_DEFAULT 0x0 + /*[field] DATA*/ + #define HOST_TBL_RD_OP_DATA5_DATA + #define HOST_TBL_RD_OP_DATA5_DATA_OFFSET 0 + #define HOST_TBL_RD_OP_DATA5_DATA_LEN 32 + #define HOST_TBL_RD_OP_DATA5_DATA_DEFAULT 0x0 + +struct host_tbl_rd_op_data5 { + a_uint32_t data:32; +}; + +union host_tbl_rd_op_data5_u { + a_uint32_t val; + struct host_tbl_rd_op_data5 bf; +}; + +/*[register] HOST_TBL_RD_OP_DATA6*/ +#define HOST_TBL_RD_OP_DATA6 +#define HOST_TBL_RD_OP_DATA6_ADDRESS 0x508 +#define HOST_TBL_RD_OP_DATA6_NUM 1 +#define HOST_TBL_RD_OP_DATA6_INC 0x4 +#define HOST_TBL_RD_OP_DATA6_TYPE REG_TYPE_RW +#define HOST_TBL_RD_OP_DATA6_DEFAULT 0x0 + /*[field] DATA*/ + #define HOST_TBL_RD_OP_DATA6_DATA + #define HOST_TBL_RD_OP_DATA6_DATA_OFFSET 0 + #define HOST_TBL_RD_OP_DATA6_DATA_LEN 32 + #define HOST_TBL_RD_OP_DATA6_DATA_DEFAULT 0x0 + +struct host_tbl_rd_op_data6 { + a_uint32_t data:32; +}; + +union host_tbl_rd_op_data6_u { + a_uint32_t val; + struct host_tbl_rd_op_data6 bf; +}; + +/*[register] HOST_TBL_RD_OP_DATA7*/ +#define HOST_TBL_RD_OP_DATA7 +#define HOST_TBL_RD_OP_DATA7_ADDRESS 0x50c +#define HOST_TBL_RD_OP_DATA7_NUM 1 +#define HOST_TBL_RD_OP_DATA7_INC 0x4 +#define HOST_TBL_RD_OP_DATA7_TYPE REG_TYPE_RW +#define HOST_TBL_RD_OP_DATA7_DEFAULT 0x0 + /*[field] DATA*/ + #define HOST_TBL_RD_OP_DATA7_DATA + #define HOST_TBL_RD_OP_DATA7_DATA_OFFSET 0 + #define HOST_TBL_RD_OP_DATA7_DATA_LEN 32 + #define HOST_TBL_RD_OP_DATA7_DATA_DEFAULT 0x0 + +struct host_tbl_rd_op_data7 { + a_uint32_t data:32; +}; + +union host_tbl_rd_op_data7_u { + a_uint32_t val; + struct host_tbl_rd_op_data7 bf; +}; + +/*[register] HOST_TBL_RD_OP_DATA8*/ +#define HOST_TBL_RD_OP_DATA8 +#define HOST_TBL_RD_OP_DATA8_ADDRESS 0x510 +#define HOST_TBL_RD_OP_DATA8_NUM 1 +#define HOST_TBL_RD_OP_DATA8_INC 0x4 +#define HOST_TBL_RD_OP_DATA8_TYPE REG_TYPE_RW +#define HOST_TBL_RD_OP_DATA8_DEFAULT 0x0 + /*[field] DATA*/ + #define HOST_TBL_RD_OP_DATA8_DATA + #define HOST_TBL_RD_OP_DATA8_DATA_OFFSET 0 + #define HOST_TBL_RD_OP_DATA8_DATA_LEN 32 + #define HOST_TBL_RD_OP_DATA8_DATA_DEFAULT 0x0 + +struct host_tbl_rd_op_data8 { + a_uint32_t data:32; +}; + +union host_tbl_rd_op_data8_u { + a_uint32_t val; + struct host_tbl_rd_op_data8 bf; +}; + +/*[register] HOST_TBL_RD_OP_DATA9*/ +#define HOST_TBL_RD_OP_DATA9 +#define HOST_TBL_RD_OP_DATA9_ADDRESS 0x514 +#define HOST_TBL_RD_OP_DATA9_NUM 1 +#define HOST_TBL_RD_OP_DATA9_INC 0x4 +#define HOST_TBL_RD_OP_DATA9_TYPE REG_TYPE_RW +#define HOST_TBL_RD_OP_DATA9_DEFAULT 0x0 + /*[field] DATA*/ + #define HOST_TBL_RD_OP_DATA9_DATA + #define HOST_TBL_RD_OP_DATA9_DATA_OFFSET 0 + #define HOST_TBL_RD_OP_DATA9_DATA_LEN 32 + #define HOST_TBL_RD_OP_DATA9_DATA_DEFAULT 0x0 + +struct host_tbl_rd_op_data9 { + a_uint32_t data:32; +}; + +union host_tbl_rd_op_data9_u { + a_uint32_t val; + struct host_tbl_rd_op_data9 bf; +}; + +/*[register] HOST_TBL_RD_OP_RSLT*/ +#define HOST_TBL_RD_OP_RSLT +#define HOST_TBL_RD_OP_RSLT_ADDRESS 0x518 +#define HOST_TBL_RD_OP_RSLT_NUM 1 +#define HOST_TBL_RD_OP_RSLT_INC 0x4 +#define HOST_TBL_RD_OP_RSLT_TYPE REG_TYPE_RO +#define HOST_TBL_RD_OP_RSLT_DEFAULT 0x0 + /*[field] CMD_ID*/ + #define HOST_TBL_RD_OP_RSLT_CMD_ID + #define HOST_TBL_RD_OP_RSLT_CMD_ID_OFFSET 0 + #define HOST_TBL_RD_OP_RSLT_CMD_ID_LEN 4 + #define HOST_TBL_RD_OP_RSLT_CMD_ID_DEFAULT 0x0 + /*[field] OP_RSLT*/ + #define HOST_TBL_RD_OP_RSLT_OP_RSLT + #define HOST_TBL_RD_OP_RSLT_OP_RSLT_OFFSET 4 + #define HOST_TBL_RD_OP_RSLT_OP_RSLT_LEN 1 + #define HOST_TBL_RD_OP_RSLT_OP_RSLT_DEFAULT 0x0 + /*[field] ENTRY_INDEX*/ + #define HOST_TBL_RD_OP_RSLT_ENTRY_INDEX + #define HOST_TBL_RD_OP_RSLT_ENTRY_INDEX_OFFSET 5 + #define HOST_TBL_RD_OP_RSLT_ENTRY_INDEX_LEN 13 + #define HOST_TBL_RD_OP_RSLT_ENTRY_INDEX_DEFAULT 0x0 + /*[field] VALID_CNT*/ + #define HOST_TBL_RD_OP_RSLT_VALID_CNT + #define HOST_TBL_RD_OP_RSLT_VALID_CNT_OFFSET 18 + #define HOST_TBL_RD_OP_RSLT_VALID_CNT_LEN 4 + #define HOST_TBL_RD_OP_RSLT_VALID_CNT_DEFAULT 0x0 + +struct host_tbl_rd_op_rslt { + a_uint32_t cmd_id:4; + a_uint32_t op_rslt:1; + a_uint32_t entry_index:13; + a_uint32_t valid_cnt:4; + a_uint32_t _reserved0:10; +}; + +union host_tbl_rd_op_rslt_u { + a_uint32_t val; + struct host_tbl_rd_op_rslt bf; +}; + +/*[register] HOST_TBL_RD_RSLT_DATA0*/ +#define HOST_TBL_RD_RSLT_DATA0 +#define HOST_TBL_RD_RSLT_DATA0_ADDRESS 0x51c +#define HOST_TBL_RD_RSLT_DATA0_NUM 1 +#define HOST_TBL_RD_RSLT_DATA0_INC 0x4 +#define HOST_TBL_RD_RSLT_DATA0_TYPE REG_TYPE_RO +#define HOST_TBL_RD_RSLT_DATA0_DEFAULT 0x0 + /*[field] DATA*/ + #define HOST_TBL_RD_RSLT_DATA0_DATA + #define HOST_TBL_RD_RSLT_DATA0_DATA_OFFSET 0 + #define HOST_TBL_RD_RSLT_DATA0_DATA_LEN 32 + #define HOST_TBL_RD_RSLT_DATA0_DATA_DEFAULT 0x0 + +struct host_tbl_rd_rslt_data0 { + a_uint32_t data:32; +}; + +union host_tbl_rd_rslt_data0_u { + a_uint32_t val; + struct host_tbl_rd_rslt_data0 bf; +}; + +/*[register] HOST_TBL_RD_RSLT_DATA1*/ +#define HOST_TBL_RD_RSLT_DATA1 +#define HOST_TBL_RD_RSLT_DATA1_ADDRESS 0x520 +#define HOST_TBL_RD_RSLT_DATA1_NUM 1 +#define HOST_TBL_RD_RSLT_DATA1_INC 0x4 +#define HOST_TBL_RD_RSLT_DATA1_TYPE REG_TYPE_RO +#define HOST_TBL_RD_RSLT_DATA1_DEFAULT 0x0 + /*[field] DATA*/ + #define HOST_TBL_RD_RSLT_DATA1_DATA + #define HOST_TBL_RD_RSLT_DATA1_DATA_OFFSET 0 + #define HOST_TBL_RD_RSLT_DATA1_DATA_LEN 32 + #define HOST_TBL_RD_RSLT_DATA1_DATA_DEFAULT 0x0 + +struct host_tbl_rd_rslt_data1 { + a_uint32_t data:32; +}; + +union host_tbl_rd_rslt_data1_u { + a_uint32_t val; + struct host_tbl_rd_rslt_data1 bf; +}; + +/*[register] HOST_TBL_RD_RSLT_DATA2*/ +#define HOST_TBL_RD_RSLT_DATA2 +#define HOST_TBL_RD_RSLT_DATA2_ADDRESS 0x524 +#define HOST_TBL_RD_RSLT_DATA2_NUM 1 +#define HOST_TBL_RD_RSLT_DATA2_INC 0x4 +#define HOST_TBL_RD_RSLT_DATA2_TYPE REG_TYPE_RO +#define HOST_TBL_RD_RSLT_DATA2_DEFAULT 0x0 + /*[field] DATA*/ + #define HOST_TBL_RD_RSLT_DATA2_DATA + #define HOST_TBL_RD_RSLT_DATA2_DATA_OFFSET 0 + #define HOST_TBL_RD_RSLT_DATA2_DATA_LEN 32 + #define HOST_TBL_RD_RSLT_DATA2_DATA_DEFAULT 0x0 + +struct host_tbl_rd_rslt_data2 { + a_uint32_t data:32; +}; + +union host_tbl_rd_rslt_data2_u { + a_uint32_t val; + struct host_tbl_rd_rslt_data2 bf; +}; + +/*[register] HOST_TBL_RD_RSLT_DATA3*/ +#define HOST_TBL_RD_RSLT_DATA3 +#define HOST_TBL_RD_RSLT_DATA3_ADDRESS 0x528 +#define HOST_TBL_RD_RSLT_DATA3_NUM 1 +#define HOST_TBL_RD_RSLT_DATA3_INC 0x4 +#define HOST_TBL_RD_RSLT_DATA3_TYPE REG_TYPE_RO +#define HOST_TBL_RD_RSLT_DATA3_DEFAULT 0x0 + /*[field] DATA*/ + #define HOST_TBL_RD_RSLT_DATA3_DATA + #define HOST_TBL_RD_RSLT_DATA3_DATA_OFFSET 0 + #define HOST_TBL_RD_RSLT_DATA3_DATA_LEN 32 + #define HOST_TBL_RD_RSLT_DATA3_DATA_DEFAULT 0x0 + +struct host_tbl_rd_rslt_data3 { + a_uint32_t data:32; +}; + +union host_tbl_rd_rslt_data3_u { + a_uint32_t val; + struct host_tbl_rd_rslt_data3 bf; +}; + +/*[register] HOST_TBL_RD_RSLT_DATA4*/ +#define HOST_TBL_RD_RSLT_DATA4 +#define HOST_TBL_RD_RSLT_DATA4_ADDRESS 0x52c +#define HOST_TBL_RD_RSLT_DATA4_NUM 1 +#define HOST_TBL_RD_RSLT_DATA4_INC 0x4 +#define HOST_TBL_RD_RSLT_DATA4_TYPE REG_TYPE_RO +#define HOST_TBL_RD_RSLT_DATA4_DEFAULT 0x0 + /*[field] DATA*/ + #define HOST_TBL_RD_RSLT_DATA4_DATA + #define HOST_TBL_RD_RSLT_DATA4_DATA_OFFSET 0 + #define HOST_TBL_RD_RSLT_DATA4_DATA_LEN 32 + #define HOST_TBL_RD_RSLT_DATA4_DATA_DEFAULT 0x0 + +struct host_tbl_rd_rslt_data4 { + a_uint32_t data:32; +}; + +union host_tbl_rd_rslt_data4_u { + a_uint32_t val; + struct host_tbl_rd_rslt_data4 bf; +}; + +/*[register] HOST_TBL_RD_RSLT_DATA5*/ +#define HOST_TBL_RD_RSLT_DATA5 +#define HOST_TBL_RD_RSLT_DATA5_ADDRESS 0x530 +#define HOST_TBL_RD_RSLT_DATA5_NUM 1 +#define HOST_TBL_RD_RSLT_DATA5_INC 0x4 +#define HOST_TBL_RD_RSLT_DATA5_TYPE REG_TYPE_RO +#define HOST_TBL_RD_RSLT_DATA5_DEFAULT 0x0 + /*[field] DATA*/ + #define HOST_TBL_RD_RSLT_DATA5_DATA + #define HOST_TBL_RD_RSLT_DATA5_DATA_OFFSET 0 + #define HOST_TBL_RD_RSLT_DATA5_DATA_LEN 32 + #define HOST_TBL_RD_RSLT_DATA5_DATA_DEFAULT 0x0 + +struct host_tbl_rd_rslt_data5 { + a_uint32_t data:32; +}; + +union host_tbl_rd_rslt_data5_u { + a_uint32_t val; + struct host_tbl_rd_rslt_data5 bf; +}; + +/*[register] HOST_TBL_RD_RSLT_DATA6*/ +#define HOST_TBL_RD_RSLT_DATA6 +#define HOST_TBL_RD_RSLT_DATA6_ADDRESS 0x534 +#define HOST_TBL_RD_RSLT_DATA6_NUM 1 +#define HOST_TBL_RD_RSLT_DATA6_INC 0x4 +#define HOST_TBL_RD_RSLT_DATA6_TYPE REG_TYPE_RO +#define HOST_TBL_RD_RSLT_DATA6_DEFAULT 0x0 + /*[field] DATA*/ + #define HOST_TBL_RD_RSLT_DATA6_DATA + #define HOST_TBL_RD_RSLT_DATA6_DATA_OFFSET 0 + #define HOST_TBL_RD_RSLT_DATA6_DATA_LEN 32 + #define HOST_TBL_RD_RSLT_DATA6_DATA_DEFAULT 0x0 + +struct host_tbl_rd_rslt_data6 { + a_uint32_t data:32; +}; + +union host_tbl_rd_rslt_data6_u { + a_uint32_t val; + struct host_tbl_rd_rslt_data6 bf; +}; + +/*[register] HOST_TBL_RD_RSLT_DATA7*/ +#define HOST_TBL_RD_RSLT_DATA7 +#define HOST_TBL_RD_RSLT_DATA7_ADDRESS 0x538 +#define HOST_TBL_RD_RSLT_DATA7_NUM 1 +#define HOST_TBL_RD_RSLT_DATA7_INC 0x4 +#define HOST_TBL_RD_RSLT_DATA7_TYPE REG_TYPE_RO +#define HOST_TBL_RD_RSLT_DATA7_DEFAULT 0x0 + /*[field] DATA*/ + #define HOST_TBL_RD_RSLT_DATA7_DATA + #define HOST_TBL_RD_RSLT_DATA7_DATA_OFFSET 0 + #define HOST_TBL_RD_RSLT_DATA7_DATA_LEN 32 + #define HOST_TBL_RD_RSLT_DATA7_DATA_DEFAULT 0x0 + +struct host_tbl_rd_rslt_data7 { + a_uint32_t data:32; +}; + +union host_tbl_rd_rslt_data7_u { + a_uint32_t val; + struct host_tbl_rd_rslt_data7 bf; +}; + +/*[register] HOST_TBL_RD_RSLT_DATA8*/ +#define HOST_TBL_RD_RSLT_DATA8 +#define HOST_TBL_RD_RSLT_DATA8_ADDRESS 0x53c +#define HOST_TBL_RD_RSLT_DATA8_NUM 1 +#define HOST_TBL_RD_RSLT_DATA8_INC 0x4 +#define HOST_TBL_RD_RSLT_DATA8_TYPE REG_TYPE_RO +#define HOST_TBL_RD_RSLT_DATA8_DEFAULT 0x0 + /*[field] DATA*/ + #define HOST_TBL_RD_RSLT_DATA8_DATA + #define HOST_TBL_RD_RSLT_DATA8_DATA_OFFSET 0 + #define HOST_TBL_RD_RSLT_DATA8_DATA_LEN 32 + #define HOST_TBL_RD_RSLT_DATA8_DATA_DEFAULT 0x0 + +struct host_tbl_rd_rslt_data8 { + a_uint32_t data:32; +}; + +union host_tbl_rd_rslt_data8_u { + a_uint32_t val; + struct host_tbl_rd_rslt_data8 bf; +}; + +/*[register] HOST_TBL_RD_RSLT_DATA9*/ +#define HOST_TBL_RD_RSLT_DATA9 +#define HOST_TBL_RD_RSLT_DATA9_ADDRESS 0x540 +#define HOST_TBL_RD_RSLT_DATA9_NUM 1 +#define HOST_TBL_RD_RSLT_DATA9_INC 0x4 +#define HOST_TBL_RD_RSLT_DATA9_TYPE REG_TYPE_RO +#define HOST_TBL_RD_RSLT_DATA9_DEFAULT 0x0 + /*[field] DATA*/ + #define HOST_TBL_RD_RSLT_DATA9_DATA + #define HOST_TBL_RD_RSLT_DATA9_DATA_OFFSET 0 + #define HOST_TBL_RD_RSLT_DATA9_DATA_LEN 32 + #define HOST_TBL_RD_RSLT_DATA9_DATA_DEFAULT 0x0 + +struct host_tbl_rd_rslt_data9 { + a_uint32_t data:32; +}; + +union host_tbl_rd_rslt_data9_u { + a_uint32_t val; + struct host_tbl_rd_rslt_data9 bf; +}; + +/*[register] L3_DBG_CMD*/ +#define L3_DBG_CMD +#define L3_DBG_CMD_ADDRESS 0xc04 +#define L3_DBG_CMD_NUM 1 +#define L3_DBG_CMD_INC 0x4 +#define L3_DBG_CMD_TYPE REG_TYPE_RW +#define L3_DBG_CMD_DEFAULT 0x0 + /*[field] ADDR*/ + #define L3_DBG_CMD_ADDR + #define L3_DBG_CMD_ADDR_OFFSET 0 + #define L3_DBG_CMD_ADDR_LEN 8 + #define L3_DBG_CMD_ADDR_DEFAULT 0x0 + /*[field] TYPE*/ + #define L3_DBG_CMD_TYPE_F + #define L3_DBG_CMD_TYPE_F_OFFSET 8 + #define L3_DBG_CMD_TYPE_F_LEN 2 + #define L3_DBG_CMD_TYPE_F_DEFAULT 0x0 + +struct l3_dbg_cmd { + a_uint32_t addr:8; + a_uint32_t type:2; + a_uint32_t _reserved0:22; +}; + +union l3_dbg_cmd_u { + a_uint32_t val; + struct l3_dbg_cmd bf; +}; + +/*[register] L3_DBG_WR_DATA*/ +#define L3_DBG_WR_DATA +#define L3_DBG_WR_DATA_ADDRESS 0xc08 +#define L3_DBG_WR_DATA_NUM 1 +#define L3_DBG_WR_DATA_INC 0x4 +#define L3_DBG_WR_DATA_TYPE REG_TYPE_RW +#define L3_DBG_WR_DATA_DEFAULT 0x0 + /*[field] DATA*/ + #define L3_DBG_WR_DATA_DATA + #define L3_DBG_WR_DATA_DATA_OFFSET 0 + #define L3_DBG_WR_DATA_DATA_LEN 32 + #define L3_DBG_WR_DATA_DATA_DEFAULT 0x0 + +struct l3_dbg_wr_data { + a_uint32_t data:32; +}; + +union l3_dbg_wr_data_u { + a_uint32_t val; + struct l3_dbg_wr_data bf; +}; + +/*[register] L3_DBG_RD_DATA*/ +#define L3_DBG_RD_DATA +#define L3_DBG_RD_DATA_ADDRESS 0xc0c +#define L3_DBG_RD_DATA_NUM 1 +#define L3_DBG_RD_DATA_INC 0x4 +#define L3_DBG_RD_DATA_TYPE REG_TYPE_RO +#define L3_DBG_RD_DATA_DEFAULT 0x0 + /*[field] DATA*/ + #define L3_DBG_RD_DATA_DATA + #define L3_DBG_RD_DATA_DATA_OFFSET 0 + #define L3_DBG_RD_DATA_DATA_LEN 32 + #define L3_DBG_RD_DATA_DATA_DEFAULT 0x0 + +struct l3_dbg_rd_data { + a_uint32_t data:32; +}; + +union l3_dbg_rd_data_u { + a_uint32_t val; + struct l3_dbg_rd_data bf; +}; + +/*[register] IN_PUB_IP_ADDR_TBL*/ +#define IN_PUB_IP_ADDR_TBL +#define IN_PUB_IP_ADDR_TBL_ADDRESS 0x378 +#define IN_PUB_IP_ADDR_TBL_NUM 16 +#define IN_PUB_IP_ADDR_TBL_INC 0x4 +#define IN_PUB_IP_ADDR_TBL_TYPE REG_TYPE_RW +#define IN_PUB_IP_ADDR_TBL_DEFAULT 0x0 + /*[field] IP_ADDR*/ + #define IN_PUB_IP_ADDR_TBL_IP_ADDR + #define IN_PUB_IP_ADDR_TBL_IP_ADDR_OFFSET 0 + #define IN_PUB_IP_ADDR_TBL_IP_ADDR_LEN 32 + #define IN_PUB_IP_ADDR_TBL_IP_ADDR_DEFAULT 0x0 + +struct in_pub_ip_addr_tbl { + a_uint32_t ip_addr:32; +}; + +union in_pub_ip_addr_tbl_u { + a_uint32_t val; + struct in_pub_ip_addr_tbl bf; +}; + +/*[table] L3_VP_PORT_TBL*/ +#define L3_VP_PORT_TBL +#define L3_VP_PORT_TBL_ADDRESS 0x1000 +#define L3_VP_PORT_TBL_NUM 256 +#define L3_VP_PORT_TBL_INC 0x10 +#define L3_VP_PORT_TBL_TYPE REG_TYPE_RW +#define L3_VP_PORT_TBL_DEFAULT 0x0 + /*[field] L3_IF_VALID*/ + #define L3_VP_PORT_TBL_L3_IF_VALID + #define L3_VP_PORT_TBL_L3_IF_VALID_OFFSET 0 + #define L3_VP_PORT_TBL_L3_IF_VALID_LEN 1 + #define L3_VP_PORT_TBL_L3_IF_VALID_DEFAULT 0x0 + /*[field] L3_IF_INDEX*/ + #define L3_VP_PORT_TBL_L3_IF_INDEX + #define L3_VP_PORT_TBL_L3_IF_INDEX_OFFSET 1 + #define L3_VP_PORT_TBL_L3_IF_INDEX_LEN 8 + #define L3_VP_PORT_TBL_L3_IF_INDEX_DEFAULT 0x0 + /*[field] IPV4_SG_EN*/ + #define L3_VP_PORT_TBL_IPV4_SG_EN + #define L3_VP_PORT_TBL_IPV4_SG_EN_OFFSET 9 + #define L3_VP_PORT_TBL_IPV4_SG_EN_LEN 1 + #define L3_VP_PORT_TBL_IPV4_SG_EN_DEFAULT 0x0 + /*[field] IPV4_SG_VIO_CMD*/ + #define L3_VP_PORT_TBL_IPV4_SG_VIO_CMD + #define L3_VP_PORT_TBL_IPV4_SG_VIO_CMD_OFFSET 10 + #define L3_VP_PORT_TBL_IPV4_SG_VIO_CMD_LEN 2 + #define L3_VP_PORT_TBL_IPV4_SG_VIO_CMD_DEFAULT 0x0 + /*[field] IPV4_SG_PORT_EN*/ + #define L3_VP_PORT_TBL_IPV4_SG_PORT_EN + #define L3_VP_PORT_TBL_IPV4_SG_PORT_EN_OFFSET 12 + #define L3_VP_PORT_TBL_IPV4_SG_PORT_EN_LEN 1 + #define L3_VP_PORT_TBL_IPV4_SG_PORT_EN_DEFAULT 0x0 + /*[field] IPV4_SG_SVLAN_EN*/ + #define L3_VP_PORT_TBL_IPV4_SG_SVLAN_EN + #define L3_VP_PORT_TBL_IPV4_SG_SVLAN_EN_OFFSET 13 + #define L3_VP_PORT_TBL_IPV4_SG_SVLAN_EN_LEN 1 + #define L3_VP_PORT_TBL_IPV4_SG_SVLAN_EN_DEFAULT 0x0 + /*[field] IPV4_SG_CVLAN_EN*/ + #define L3_VP_PORT_TBL_IPV4_SG_CVLAN_EN + #define L3_VP_PORT_TBL_IPV4_SG_CVLAN_EN_OFFSET 14 + #define L3_VP_PORT_TBL_IPV4_SG_CVLAN_EN_LEN 1 + #define L3_VP_PORT_TBL_IPV4_SG_CVLAN_EN_DEFAULT 0x0 + /*[field] IPV4_SRC_UNK_CMD*/ + #define L3_VP_PORT_TBL_IPV4_SRC_UNK_CMD + #define L3_VP_PORT_TBL_IPV4_SRC_UNK_CMD_OFFSET 15 + #define L3_VP_PORT_TBL_IPV4_SRC_UNK_CMD_LEN 2 + #define L3_VP_PORT_TBL_IPV4_SRC_UNK_CMD_DEFAULT 0x0 + /*[field] IPV6_SG_EN*/ + #define L3_VP_PORT_TBL_IPV6_SG_EN + #define L3_VP_PORT_TBL_IPV6_SG_EN_OFFSET 17 + #define L3_VP_PORT_TBL_IPV6_SG_EN_LEN 1 + #define L3_VP_PORT_TBL_IPV6_SG_EN_DEFAULT 0x0 + /*[field] IPV6_SG_VIO_CMD*/ + #define L3_VP_PORT_TBL_IPV6_SG_VIO_CMD + #define L3_VP_PORT_TBL_IPV6_SG_VIO_CMD_OFFSET 18 + #define L3_VP_PORT_TBL_IPV6_SG_VIO_CMD_LEN 2 + #define L3_VP_PORT_TBL_IPV6_SG_VIO_CMD_DEFAULT 0x0 + /*[field] IPV6_SG_PORT_EN*/ + #define L3_VP_PORT_TBL_IPV6_SG_PORT_EN + #define L3_VP_PORT_TBL_IPV6_SG_PORT_EN_OFFSET 20 + #define L3_VP_PORT_TBL_IPV6_SG_PORT_EN_LEN 1 + #define L3_VP_PORT_TBL_IPV6_SG_PORT_EN_DEFAULT 0x0 + /*[field] IPV6_SG_SVLAN_EN*/ + #define L3_VP_PORT_TBL_IPV6_SG_SVLAN_EN + #define L3_VP_PORT_TBL_IPV6_SG_SVLAN_EN_OFFSET 21 + #define L3_VP_PORT_TBL_IPV6_SG_SVLAN_EN_LEN 1 + #define L3_VP_PORT_TBL_IPV6_SG_SVLAN_EN_DEFAULT 0x0 + /*[field] IPV6_SG_CVLAN_EN*/ + #define L3_VP_PORT_TBL_IPV6_SG_CVLAN_EN + #define L3_VP_PORT_TBL_IPV6_SG_CVLAN_EN_OFFSET 22 + #define L3_VP_PORT_TBL_IPV6_SG_CVLAN_EN_LEN 1 + #define L3_VP_PORT_TBL_IPV6_SG_CVLAN_EN_DEFAULT 0x0 + /*[field] IPV6_SRC_UNK_CMD*/ + #define L3_VP_PORT_TBL_IPV6_SRC_UNK_CMD + #define L3_VP_PORT_TBL_IPV6_SRC_UNK_CMD_OFFSET 23 + #define L3_VP_PORT_TBL_IPV6_SRC_UNK_CMD_LEN 2 + #define L3_VP_PORT_TBL_IPV6_SRC_UNK_CMD_DEFAULT 0x0 + /*[field] IP_ARP_SG_EN*/ + #define L3_VP_PORT_TBL_IP_ARP_SG_EN + #define L3_VP_PORT_TBL_IP_ARP_SG_EN_OFFSET 25 + #define L3_VP_PORT_TBL_IP_ARP_SG_EN_LEN 1 + #define L3_VP_PORT_TBL_IP_ARP_SG_EN_DEFAULT 0x0 + /*[field] IP_ARP_SG_VIO_CMD*/ + #define L3_VP_PORT_TBL_IP_ARP_SG_VIO_CMD + #define L3_VP_PORT_TBL_IP_ARP_SG_VIO_CMD_OFFSET 26 + #define L3_VP_PORT_TBL_IP_ARP_SG_VIO_CMD_LEN 2 + #define L3_VP_PORT_TBL_IP_ARP_SG_VIO_CMD_DEFAULT 0x0 + /*[field] IP_ARP_SG_PORT_EN*/ + #define L3_VP_PORT_TBL_IP_ARP_SG_PORT_EN + #define L3_VP_PORT_TBL_IP_ARP_SG_PORT_EN_OFFSET 28 + #define L3_VP_PORT_TBL_IP_ARP_SG_PORT_EN_LEN 1 + #define L3_VP_PORT_TBL_IP_ARP_SG_PORT_EN_DEFAULT 0x0 + /*[field] IP_ARP_SG_SVLAN_EN*/ + #define L3_VP_PORT_TBL_IP_ARP_SG_SVLAN_EN + #define L3_VP_PORT_TBL_IP_ARP_SG_SVLAN_EN_OFFSET 29 + #define L3_VP_PORT_TBL_IP_ARP_SG_SVLAN_EN_LEN 1 + #define L3_VP_PORT_TBL_IP_ARP_SG_SVLAN_EN_DEFAULT 0x0 + /*[field] IP_ARP_SRC_UNK_CMD*/ + #define L3_VP_PORT_TBL_IP_ARP_SRC_UNK_CMD + #define L3_VP_PORT_TBL_IP_ARP_SRC_UNK_CMD_OFFSET 30 + #define L3_VP_PORT_TBL_IP_ARP_SRC_UNK_CMD_LEN 2 + #define L3_VP_PORT_TBL_IP_ARP_SRC_UNK_CMD_DEFAULT 0x0 + /*[field] IP_ARP_SG_CVLAN_EN*/ + #define L3_VP_PORT_TBL_IP_ARP_SG_CVLAN_EN + #define L3_VP_PORT_TBL_IP_ARP_SG_CVLAN_EN_OFFSET 32 + #define L3_VP_PORT_TBL_IP_ARP_SG_CVLAN_EN_LEN 1 + #define L3_VP_PORT_TBL_IP_ARP_SG_CVLAN_EN_DEFAULT 0x0 + /*[field] IP_ND_SG_EN*/ + #define L3_VP_PORT_TBL_IP_ND_SG_EN + #define L3_VP_PORT_TBL_IP_ND_SG_EN_OFFSET 33 + #define L3_VP_PORT_TBL_IP_ND_SG_EN_LEN 1 + #define L3_VP_PORT_TBL_IP_ND_SG_EN_DEFAULT 0x0 + /*[field] IP_ND_SG_VIO_CMD*/ + #define L3_VP_PORT_TBL_IP_ND_SG_VIO_CMD + #define L3_VP_PORT_TBL_IP_ND_SG_VIO_CMD_OFFSET 34 + #define L3_VP_PORT_TBL_IP_ND_SG_VIO_CMD_LEN 2 + #define L3_VP_PORT_TBL_IP_ND_SG_VIO_CMD_DEFAULT 0x0 + /*[field] IP_ND_SG_PORT_EN*/ + #define L3_VP_PORT_TBL_IP_ND_SG_PORT_EN + #define L3_VP_PORT_TBL_IP_ND_SG_PORT_EN_OFFSET 36 + #define L3_VP_PORT_TBL_IP_ND_SG_PORT_EN_LEN 1 + #define L3_VP_PORT_TBL_IP_ND_SG_PORT_EN_DEFAULT 0x0 + /*[field] IP_ND_SG_SVLAN_EN*/ + #define L3_VP_PORT_TBL_IP_ND_SG_SVLAN_EN + #define L3_VP_PORT_TBL_IP_ND_SG_SVLAN_EN_OFFSET 37 + #define L3_VP_PORT_TBL_IP_ND_SG_SVLAN_EN_LEN 1 + #define L3_VP_PORT_TBL_IP_ND_SG_SVLAN_EN_DEFAULT 0x0 + /*[field] IP_ND_SG_CVLAN_EN*/ + #define L3_VP_PORT_TBL_IP_ND_SG_CVLAN_EN + #define L3_VP_PORT_TBL_IP_ND_SG_CVLAN_EN_OFFSET 38 + #define L3_VP_PORT_TBL_IP_ND_SG_CVLAN_EN_LEN 1 + #define L3_VP_PORT_TBL_IP_ND_SG_CVLAN_EN_DEFAULT 0x0 + /*[field] IP_ND_SRC_UNK_CMD*/ + #define L3_VP_PORT_TBL_IP_ND_SRC_UNK_CMD + #define L3_VP_PORT_TBL_IP_ND_SRC_UNK_CMD_OFFSET 39 + #define L3_VP_PORT_TBL_IP_ND_SRC_UNK_CMD_LEN 2 + #define L3_VP_PORT_TBL_IP_ND_SRC_UNK_CMD_DEFAULT 0x0 + /*[field] VSI_VALID*/ + #define L3_VP_PORT_TBL_VSI_VALID + #define L3_VP_PORT_TBL_VSI_VALID_OFFSET 41 + #define L3_VP_PORT_TBL_VSI_VALID_LEN 1 + #define L3_VP_PORT_TBL_VSI_VALID_DEFAULT 0x0 + /*[field] VSI*/ + #define L3_VP_PORT_TBL_VSI + #define L3_VP_PORT_TBL_VSI_OFFSET 42 + #define L3_VP_PORT_TBL_VSI_LEN 5 + #define L3_VP_PORT_TBL_VSI_DEFAULT 0x0 + /*[field] MAC_VALID*/ + #define L3_VP_PORT_TBL_MAC_VALID + #define L3_VP_PORT_TBL_MAC_VALID_OFFSET 47 + #define L3_VP_PORT_TBL_MAC_VALID_LEN 1 + #define L3_VP_PORT_TBL_MAC_VALID_DEFAULT 0x0 + /*[field] MAC_DA*/ + #define L3_VP_PORT_TBL_MAC_DA + #define L3_VP_PORT_TBL_MAC_DA_OFFSET 48 + #define L3_VP_PORT_TBL_MAC_DA_LEN 48 + #define L3_VP_PORT_TBL_MAC_DA_DEFAULT 0x0 + +struct l3_vp_port_tbl { + a_uint32_t l3_if_valid:1; + a_uint32_t l3_if_index:8; + a_uint32_t ipv4_sg_en:1; + a_uint32_t ipv4_sg_vio_cmd:2; + a_uint32_t ipv4_sg_port_en:1; + a_uint32_t ipv4_sg_svlan_en:1; + a_uint32_t ipv4_sg_cvlan_en:1; + a_uint32_t ipv4_src_unk_cmd:2; + a_uint32_t ipv6_sg_en:1; + a_uint32_t ipv6_sg_vio_cmd:2; + a_uint32_t ipv6_sg_port_en:1; + a_uint32_t ipv6_sg_svlan_en:1; + a_uint32_t ipv6_sg_cvlan_en:1; + a_uint32_t ipv6_src_unk_cmd:2; + a_uint32_t ip_arp_sg_en:1; + a_uint32_t ip_arp_sg_vio_cmd:2; + a_uint32_t ip_arp_sg_port_en:1; + a_uint32_t ip_arp_sg_svlan_en:1; + a_uint32_t ip_arp_src_unk_cmd:2; + a_uint32_t ip_arp_sg_cvlan_en:1; + a_uint32_t ip_nd_sg_en:1; + a_uint32_t ip_nd_sg_vio_cmd:2; + a_uint32_t ip_nd_sg_port_en:1; + a_uint32_t ip_nd_sg_svlan_en:1; + a_uint32_t ip_nd_sg_cvlan_en:1; + a_uint32_t ip_nd_src_unk_cmd:2; + a_uint32_t vsi_valid:1; + a_uint32_t vsi:5; + a_uint32_t mac_valid:1; + a_uint32_t mac_da_0:16; + a_uint32_t mac_da_1:32; +}; + +union l3_vp_port_tbl_u { + a_uint32_t val[3]; + struct l3_vp_port_tbl bf; +}; + +/*[table] IN_L3_IF_TBL*/ +#define IN_L3_IF_TBL +#define IN_L3_IF_TBL_ADDRESS 0x2000 +#define IN_L3_IF_TBL_NUM 256 +#define IN_L3_IF_TBL_INC 0x8 +#define IN_L3_IF_TBL_TYPE REG_TYPE_RW +#define IN_L3_IF_TBL_DEFAULT 0x0 + /*[field] MRU*/ + #define IN_L3_IF_TBL_MRU + #define IN_L3_IF_TBL_MRU_OFFSET 0 + #define IN_L3_IF_TBL_MRU_LEN 14 + #define IN_L3_IF_TBL_MRU_DEFAULT 0x0 + /*[field] MTU*/ + #define IN_L3_IF_TBL_MTU + #define IN_L3_IF_TBL_MTU_OFFSET 14 + #define IN_L3_IF_TBL_MTU_LEN 14 + #define IN_L3_IF_TBL_MTU_DEFAULT 0x0 + /*[field] TTL_DEC_BYPASS*/ + #define IN_L3_IF_TBL_TTL_DEC_BYPASS + #define IN_L3_IF_TBL_TTL_DEC_BYPASS_OFFSET 28 + #define IN_L3_IF_TBL_TTL_DEC_BYPASS_LEN 1 + #define IN_L3_IF_TBL_TTL_DEC_BYPASS_DEFAULT 0x0 + /*[field] IPV4_UC_ROUTE_EN*/ + #define IN_L3_IF_TBL_IPV4_UC_ROUTE_EN + #define IN_L3_IF_TBL_IPV4_UC_ROUTE_EN_OFFSET 29 + #define IN_L3_IF_TBL_IPV4_UC_ROUTE_EN_LEN 1 + #define IN_L3_IF_TBL_IPV4_UC_ROUTE_EN_DEFAULT 0x0 + /*[field] IPV6_UC_ROUTE_EN*/ + #define IN_L3_IF_TBL_IPV6_UC_ROUTE_EN + #define IN_L3_IF_TBL_IPV6_UC_ROUTE_EN_OFFSET 30 + #define IN_L3_IF_TBL_IPV6_UC_ROUTE_EN_LEN 1 + #define IN_L3_IF_TBL_IPV6_UC_ROUTE_EN_DEFAULT 0x0 + /*[field] ICMP_TRIGGER_EN*/ + #define IN_L3_IF_TBL_ICMP_TRIGGER_EN + #define IN_L3_IF_TBL_ICMP_TRIGGER_EN_OFFSET 31 + #define IN_L3_IF_TBL_ICMP_TRIGGER_EN_LEN 1 + #define IN_L3_IF_TBL_ICMP_TRIGGER_EN_DEFAULT 0x0 + /*[field] TTL_EXCEED_CMD*/ + #define IN_L3_IF_TBL_TTL_EXCEED_CMD + #define IN_L3_IF_TBL_TTL_EXCEED_CMD_OFFSET 32 + #define IN_L3_IF_TBL_TTL_EXCEED_CMD_LEN 2 + #define IN_L3_IF_TBL_TTL_EXCEED_CMD_DEFAULT 0x0 + /*[field] TTL_EXCEED_DE_ACCE*/ + #define IN_L3_IF_TBL_TTL_EXCEED_DE_ACCE + #define IN_L3_IF_TBL_TTL_EXCEED_DE_ACCE_OFFSET 34 + #define IN_L3_IF_TBL_TTL_EXCEED_DE_ACCE_LEN 1 + #define IN_L3_IF_TBL_TTL_EXCEED_DE_ACCE_DEFAULT 0x0 + /*[field] MAC_BITMAP*/ + #define IN_L3_IF_TBL_MAC_BITMAP + #define IN_L3_IF_TBL_MAC_BITMAP_OFFSET 35 + #define IN_L3_IF_TBL_MAC_BITMAP_LEN 8 + #define IN_L3_IF_TBL_MAC_BITMAP_DEFAULT 0x0 + /*[field] PPPOE_EN*/ + #define IN_L3_IF_TBL_PPPOE_EN + #define IN_L3_IF_TBL_PPPOE_EN_OFFSET 43 + #define IN_L3_IF_TBL_PPPOE_EN_LEN 1 + #define IN_L3_IF_TBL_PPPOE_EN_DEFAULT 0x0 + +struct in_l3_if_tbl { + a_uint32_t mru:14; + a_uint32_t mtu:14; + a_uint32_t ttl_dec_bypass:1; + a_uint32_t ipv4_uc_route_en:1; + a_uint32_t ipv6_uc_route_en:1; + a_uint32_t icmp_trigger_en:1; + a_uint32_t ttl_exceed_cmd:2; + a_uint32_t ttl_exceed_de_acce:1; + a_uint32_t mac_bitmap:8; + a_uint32_t pppoe_en:1; + a_uint32_t _reserved0:20; +}; + +union in_l3_if_tbl_u { + a_uint32_t val[2]; + struct in_l3_if_tbl bf; +}; + +/*[table] HOST_IPV6_MCAST_TBL*/ +#define HOST_IPV6_MCAST_TBL +#define HOST_IPV6_MCAST_TBL_ADDRESS 0x20000 +#define HOST_IPV6_MCAST_TBL_NUM 1536 +#define HOST_IPV6_MCAST_TBL_INC 0x40 +#define HOST_IPV6_MCAST_TBL_TYPE REG_TYPE_RW +#define HOST_IPV6_MCAST_TBL_DEFAULT 0x0 + /*[field] VALID*/ + #define HOST_IPV6_MCAST_TBL_VALID + #define HOST_IPV6_MCAST_TBL_VALID_OFFSET 0 + #define HOST_IPV6_MCAST_TBL_VALID_LEN 1 + #define HOST_IPV6_MCAST_TBL_VALID_DEFAULT 0x0 + /*[field] KEY_TYPE*/ + #define HOST_IPV6_MCAST_TBL_KEY_TYPE + #define HOST_IPV6_MCAST_TBL_KEY_TYPE_OFFSET 1 + #define HOST_IPV6_MCAST_TBL_KEY_TYPE_LEN 2 + #define HOST_IPV6_MCAST_TBL_KEY_TYPE_DEFAULT 0x0 + /*[field] FWD_CMD*/ + #define HOST_IPV6_MCAST_TBL_FWD_CMD + #define HOST_IPV6_MCAST_TBL_FWD_CMD_OFFSET 3 + #define HOST_IPV6_MCAST_TBL_FWD_CMD_LEN 2 + #define HOST_IPV6_MCAST_TBL_FWD_CMD_DEFAULT 0x0 + /*[field] SYN_TOGGLE*/ + #define HOST_IPV6_MCAST_TBL_SYN_TOGGLE + #define HOST_IPV6_MCAST_TBL_SYN_TOGGLE_OFFSET 5 + #define HOST_IPV6_MCAST_TBL_SYN_TOGGLE_LEN 1 + #define HOST_IPV6_MCAST_TBL_SYN_TOGGLE_DEFAULT 0x0 + /*[field] DST_INFO*/ + #define HOST_IPV6_MCAST_TBL_DST_INFO + #define HOST_IPV6_MCAST_TBL_DST_INFO_OFFSET 6 + #define HOST_IPV6_MCAST_TBL_DST_INFO_LEN 14 + #define HOST_IPV6_MCAST_TBL_DST_INFO_DEFAULT 0x0 + /*[field] LAN_WAN*/ + #define HOST_IPV6_MCAST_TBL_LAN_WAN + #define HOST_IPV6_MCAST_TBL_LAN_WAN_OFFSET 20 + #define HOST_IPV6_MCAST_TBL_LAN_WAN_LEN 1 + #define HOST_IPV6_MCAST_TBL_LAN_WAN_DEFAULT 0x0 + /*[field] VSI*/ + #define HOST_IPV6_MCAST_TBL_VSI + #define HOST_IPV6_MCAST_TBL_VSI_OFFSET 21 + #define HOST_IPV6_MCAST_TBL_VSI_LEN 5 + #define HOST_IPV6_MCAST_TBL_VSI_DEFAULT 0x0 + /*[field] SIPV6_ADDR*/ + #define HOST_IPV6_MCAST_TBL_SIPV6_ADDR + #define HOST_IPV6_MCAST_TBL_SIPV6_ADDR_OFFSET 44 + #define HOST_IPV6_MCAST_TBL_SIPV6_ADDR_LEN 128 + #define HOST_IPV6_MCAST_TBL_SIPV6_ADDR_DEFAULT 0x0 + /*[field] GIPV6_ADDR*/ + #define HOST_IPV6_MCAST_TBL_GIPV6_ADDR + #define HOST_IPV6_MCAST_TBL_GIPV6_ADDR_OFFSET 172 + #define HOST_IPV6_MCAST_TBL_GIPV6_ADDR_LEN 128 + #define HOST_IPV6_MCAST_TBL_GIPV6_ADDR_DEFAULT 0x0 + +struct host_tbl { + a_uint32_t valid:1; + a_uint32_t key_type:2; + a_uint32_t fwd_cmd:2; + a_uint32_t syn_toggle:1; + a_uint32_t dst_info:14; + a_uint32_t lan_wan:1; + a_uint32_t _reserved0:11; + a_uint32_t ip_addr:32; + a_uint32_t _reserved1:32; +}; + +union host_tbl_u { + a_uint32_t val[3]; + struct host_tbl bf; +}; + +/*[table] HOST_IPV4_MCAST_TBL*/ +#define HOST_IPV4_MCAST_TBL +#define HOST_IPV4_MCAST_TBL_ADDRESS 0x20000 +#define HOST_IPV4_MCAST_TBL_NUM 3072 +#define HOST_IPV4_MCAST_TBL_INC 0x20 +#define HOST_IPV4_MCAST_TBL_TYPE REG_TYPE_RW +#define HOST_IPV4_MCAST_TBL_DEFAULT 0x0 + /*[field] VALID*/ + #define HOST_IPV4_MCAST_TBL_VALID + #define HOST_IPV4_MCAST_TBL_VALID_OFFSET 0 + #define HOST_IPV4_MCAST_TBL_VALID_LEN 1 + #define HOST_IPV4_MCAST_TBL_VALID_DEFAULT 0x0 + /*[field] KEY_TYPE*/ + #define HOST_IPV4_MCAST_TBL_KEY_TYPE + #define HOST_IPV4_MCAST_TBL_KEY_TYPE_OFFSET 1 + #define HOST_IPV4_MCAST_TBL_KEY_TYPE_LEN 2 + #define HOST_IPV4_MCAST_TBL_KEY_TYPE_DEFAULT 0x0 + /*[field] FWD_CMD*/ + #define HOST_IPV4_MCAST_TBL_FWD_CMD + #define HOST_IPV4_MCAST_TBL_FWD_CMD_OFFSET 3 + #define HOST_IPV4_MCAST_TBL_FWD_CMD_LEN 2 + #define HOST_IPV4_MCAST_TBL_FWD_CMD_DEFAULT 0x0 + /*[field] SYN_TOGGLE*/ + #define HOST_IPV4_MCAST_TBL_SYN_TOGGLE + #define HOST_IPV4_MCAST_TBL_SYN_TOGGLE_OFFSET 5 + #define HOST_IPV4_MCAST_TBL_SYN_TOGGLE_LEN 1 + #define HOST_IPV4_MCAST_TBL_SYN_TOGGLE_DEFAULT 0x0 + /*[field] DST_INFO*/ + #define HOST_IPV4_MCAST_TBL_DST_INFO + #define HOST_IPV4_MCAST_TBL_DST_INFO_OFFSET 6 + #define HOST_IPV4_MCAST_TBL_DST_INFO_LEN 14 + #define HOST_IPV4_MCAST_TBL_DST_INFO_DEFAULT 0x0 + /*[field] LAN_WAN*/ + #define HOST_IPV4_MCAST_TBL_LAN_WAN + #define HOST_IPV4_MCAST_TBL_LAN_WAN_OFFSET 20 + #define HOST_IPV4_MCAST_TBL_LAN_WAN_LEN 1 + #define HOST_IPV4_MCAST_TBL_LAN_WAN_DEFAULT 0x0 + /*[field] VSI*/ + #define HOST_IPV4_MCAST_TBL_VSI + #define HOST_IPV4_MCAST_TBL_VSI_OFFSET 21 + #define HOST_IPV4_MCAST_TBL_VSI_LEN 5 + #define HOST_IPV4_MCAST_TBL_VSI_DEFAULT 0x0 + /*[field] SIP_ADDR*/ + #define HOST_IPV4_MCAST_TBL_SIP_ADDR + #define HOST_IPV4_MCAST_TBL_SIP_ADDR_OFFSET 85 + #define HOST_IPV4_MCAST_TBL_SIP_ADDR_LEN 32 + #define HOST_IPV4_MCAST_TBL_SIP_ADDR_DEFAULT 0x0 + /*[field] GIP_ADDR*/ + #define HOST_IPV4_MCAST_TBL_GIP_ADDR + #define HOST_IPV4_MCAST_TBL_GIP_ADDR_OFFSET 117 + #define HOST_IPV4_MCAST_TBL_GIP_ADDR_LEN 32 + #define HOST_IPV4_MCAST_TBL_GIP_ADDR_DEFAULT 0x0 + +struct host_ipv6_tbl { + a_uint32_t valid:1; + a_uint32_t key_type:2; + a_uint32_t fwd_cmd:2; + a_uint32_t syn_toggle:1; + a_uint32_t dst_info:14; + a_uint32_t lan_wan:1; + a_uint32_t _reserved0:1; + a_uint32_t ipv6_addr_0:10; + a_uint32_t ipv6_addr_1:32; + a_uint32_t ipv6_addr_2:32; + a_uint32_t ipv6_addr_3:32; + a_uint32_t ipv6_addr_4:22; + a_uint32_t _reserved1:10; +}; + +union host_ipv6_tbl_u { + a_uint32_t val[5]; + struct host_ipv6_tbl bf; +}; + +/*[table] HOST_TBL*/ +#define HOST_TBL +#define HOST_TBL_ADDRESS 0x20000 +#define HOST_TBL_NUM 6144 +#define HOST_TBL_INC 0x10 +#define HOST_TBL_TYPE REG_TYPE_RW +#define HOST_TBL_DEFAULT 0x0 + /*[field] VALID*/ + #define HOST_TBL_VALID + #define HOST_TBL_VALID_OFFSET 0 + #define HOST_TBL_VALID_LEN 1 + #define HOST_TBL_VALID_DEFAULT 0x0 + /*[field] KEY_TYPE*/ + #define HOST_TBL_KEY_TYPE + #define HOST_TBL_KEY_TYPE_OFFSET 1 + #define HOST_TBL_KEY_TYPE_LEN 2 + #define HOST_TBL_KEY_TYPE_DEFAULT 0x0 + /*[field] FWD_CMD*/ + #define HOST_TBL_FWD_CMD + #define HOST_TBL_FWD_CMD_OFFSET 3 + #define HOST_TBL_FWD_CMD_LEN 2 + #define HOST_TBL_FWD_CMD_DEFAULT 0x0 + /*[field] SYN_TOGGLE*/ + #define HOST_TBL_SYN_TOGGLE + #define HOST_TBL_SYN_TOGGLE_OFFSET 5 + #define HOST_TBL_SYN_TOGGLE_LEN 1 + #define HOST_TBL_SYN_TOGGLE_DEFAULT 0x0 + /*[field] DST_INFO*/ + #define HOST_TBL_DST_INFO + #define HOST_TBL_DST_INFO_OFFSET 6 + #define HOST_TBL_DST_INFO_LEN 14 + #define HOST_TBL_DST_INFO_DEFAULT 0x0 + /*[field] LAN_WAN*/ + #define HOST_TBL_LAN_WAN + #define HOST_TBL_LAN_WAN_OFFSET 20 + #define HOST_TBL_LAN_WAN_LEN 1 + #define HOST_TBL_LAN_WAN_DEFAULT 0x0 + /*[field] IP_ADDR*/ + #define HOST_TBL_IP_ADDR + #define HOST_TBL_IP_ADDR_OFFSET 32 + #define HOST_TBL_IP_ADDR_LEN 32 + #define HOST_TBL_IP_ADDR_DEFAULT 0x0 + +struct host_ipv4_mcast_tbl { + a_uint32_t valid:1; + a_uint32_t key_type:2; + a_uint32_t fwd_cmd:2; + a_uint32_t syn_toggle:1; + a_uint32_t dst_info:14; + a_uint32_t lan_wan:1; + a_uint32_t vsi:5; + a_uint32_t _reserved0_0:6; + a_uint32_t _reserved0_1:32; + a_uint32_t _reserved0_2:21; + a_uint32_t sip_addr_0:11; + a_uint32_t sip_addr_1:21; + a_uint32_t gip_addr_0:11; + a_uint32_t gip_addr_1:21; + a_uint32_t _reserved1:11; +}; + +union host_ipv4_mcast_tbl_u { + a_uint32_t val[5]; + struct host_ipv4_mcast_tbl bf; +}; + +/*[table] HOST_IPV6_TBL*/ +#define HOST_IPV6_TBL +#define HOST_IPV6_TBL_ADDRESS 0x20000 +#define HOST_IPV6_TBL_NUM 3072 +#define HOST_IPV6_TBL_INC 0x20 +#define HOST_IPV6_TBL_TYPE REG_TYPE_RW +#define HOST_IPV6_TBL_DEFAULT 0x0 + /*[field] VALID*/ + #define HOST_IPV6_TBL_VALID + #define HOST_IPV6_TBL_VALID_OFFSET 0 + #define HOST_IPV6_TBL_VALID_LEN 1 + #define HOST_IPV6_TBL_VALID_DEFAULT 0x0 + /*[field] KEY_TYPE*/ + #define HOST_IPV6_TBL_KEY_TYPE + #define HOST_IPV6_TBL_KEY_TYPE_OFFSET 1 + #define HOST_IPV6_TBL_KEY_TYPE_LEN 2 + #define HOST_IPV6_TBL_KEY_TYPE_DEFAULT 0x0 + /*[field] FWD_CMD*/ + #define HOST_IPV6_TBL_FWD_CMD + #define HOST_IPV6_TBL_FWD_CMD_OFFSET 3 + #define HOST_IPV6_TBL_FWD_CMD_LEN 2 + #define HOST_IPV6_TBL_FWD_CMD_DEFAULT 0x0 + /*[field] SYN_TOGGLE*/ + #define HOST_IPV6_TBL_SYN_TOGGLE + #define HOST_IPV6_TBL_SYN_TOGGLE_OFFSET 5 + #define HOST_IPV6_TBL_SYN_TOGGLE_LEN 1 + #define HOST_IPV6_TBL_SYN_TOGGLE_DEFAULT 0x0 + /*[field] DST_INFO*/ + #define HOST_IPV6_TBL_DST_INFO + #define HOST_IPV6_TBL_DST_INFO_OFFSET 6 + #define HOST_IPV6_TBL_DST_INFO_LEN 14 + #define HOST_IPV6_TBL_DST_INFO_DEFAULT 0x0 + /*[field] LAN_WAN*/ + #define HOST_IPV6_TBL_LAN_WAN + #define HOST_IPV6_TBL_LAN_WAN_OFFSET 20 + #define HOST_IPV6_TBL_LAN_WAN_LEN 1 + #define HOST_IPV6_TBL_LAN_WAN_DEFAULT 0x0 + /*[field] IPV6_ADDR*/ + #define HOST_IPV6_TBL_IPV6_ADDR + #define HOST_IPV6_TBL_IPV6_ADDR_OFFSET 22 + #define HOST_IPV6_TBL_IPV6_ADDR_LEN 128 + #define HOST_IPV6_TBL_IPV6_ADDR_DEFAULT 0x0 + +struct host_ipv6_mcast_tbl { + a_uint32_t valid:1; + a_uint32_t key_type:2; + a_uint32_t fwd_cmd:2; + a_uint32_t syn_toggle:1; + a_uint32_t dst_info:14; + a_uint32_t lan_wan:1; + a_uint32_t vsi:5; + a_uint32_t _reserved0_0:6; + a_uint32_t _reserved0_1:12; + a_uint32_t sipv6_addr_0:20; + a_uint32_t sipv6_addr_1:32; + a_uint32_t sipv6_addr_2:32; + a_uint32_t sipv6_addr_3:32; + a_uint32_t sipv6_addr_4:12; + a_uint32_t gipv6_addr_0:20; + a_uint32_t gipv6_addr_1:32; + a_uint32_t gipv6_addr_2:32; + a_uint32_t gipv6_addr_3:32; + a_uint32_t gipv6_addr_4:12; + a_uint32_t _reserved1:20; +}; + +union host_ipv6_mcast_tbl_u { + a_uint32_t val[10]; + struct host_ipv6_mcast_tbl bf; +}; + +/*[table] IN_NEXTHOP_TBL*/ +#define IN_NEXTHOP_TBL +#define IN_NEXTHOP_TBL_ADDRESS 0x60000 +#define IN_NEXTHOP_TBL_NUM 2560 +#define IN_NEXTHOP_TBL_INC 0x10 +#define IN_NEXTHOP_TBL_TYPE REG_TYPE_RW +#define IN_NEXTHOP_TBL_DEFAULT 0x0 + /*[field] TYPE*/ + #define IN_NEXTHOP_TBL_TYPE_F + #define IN_NEXTHOP_TBL_TYPE_F_OFFSET 0 + #define IN_NEXTHOP_TBL_TYPE_F_LEN 1 + #define IN_NEXTHOP_TBL_TYPE_F_DEFAULT 0x0 + /*[field] PORT reuse TYPE[0]*/ + #define IN_NEXTHOP_TBL_PORT + #define IN_NEXTHOP_TBL_PORT_OFFSET 1 + #define IN_NEXTHOP_TBL_PORT_LEN 8 + #define IN_NEXTHOP_TBL_PORT_DEFAULT 0x0 + /*[field] VSI reuse TYPE[1]*/ + #define IN_NEXTHOP_TBL_VSI + #define IN_NEXTHOP_TBL_VSI_OFFSET 1 + #define IN_NEXTHOP_TBL_VSI_LEN 5 + #define IN_NEXTHOP_TBL_VSI_DEFAULT 0x0 + /*[field] POST_L3_IF*/ + #define IN_NEXTHOP_TBL_POST_L3_IF + #define IN_NEXTHOP_TBL_POST_L3_IF_OFFSET 9 + #define IN_NEXTHOP_TBL_POST_L3_IF_LEN 8 + #define IN_NEXTHOP_TBL_POST_L3_IF_DEFAULT 0x0 + /*[field] IP_TO_ME*/ + #define IN_NEXTHOP_TBL_IP_TO_ME + #define IN_NEXTHOP_TBL_IP_TO_ME_OFFSET 17 + #define IN_NEXTHOP_TBL_IP_TO_ME_LEN 1 + #define IN_NEXTHOP_TBL_IP_TO_ME_DEFAULT 0x0 + /*[field] STAG_FMT*/ + #define IN_NEXTHOP_TBL_STAG_FMT + #define IN_NEXTHOP_TBL_STAG_FMT_OFFSET 18 + #define IN_NEXTHOP_TBL_STAG_FMT_LEN 1 + #define IN_NEXTHOP_TBL_STAG_FMT_DEFAULT 0x0 + /*[field] SVID*/ + #define IN_NEXTHOP_TBL_SVID + #define IN_NEXTHOP_TBL_SVID_OFFSET 19 + #define IN_NEXTHOP_TBL_SVID_LEN 12 + #define IN_NEXTHOP_TBL_SVID_DEFAULT 0x0 + /*[field] CTAG_FMT*/ + #define IN_NEXTHOP_TBL_CTAG_FMT + #define IN_NEXTHOP_TBL_CTAG_FMT_OFFSET 31 + #define IN_NEXTHOP_TBL_CTAG_FMT_LEN 1 + #define IN_NEXTHOP_TBL_CTAG_FMT_DEFAULT 0x0 + /*[field] CVID*/ + #define IN_NEXTHOP_TBL_CVID + #define IN_NEXTHOP_TBL_CVID_OFFSET 32 + #define IN_NEXTHOP_TBL_CVID_LEN 12 + #define IN_NEXTHOP_TBL_CVID_DEFAULT 0x0 + /*[field] IP_PUB_ADDR_INDEX*/ + #define IN_NEXTHOP_TBL_IP_PUB_ADDR_INDEX + #define IN_NEXTHOP_TBL_IP_PUB_ADDR_INDEX_OFFSET 44 + #define IN_NEXTHOP_TBL_IP_PUB_ADDR_INDEX_LEN 4 + #define IN_NEXTHOP_TBL_IP_PUB_ADDR_INDEX_DEFAULT 0x0 + /*[field] MAC_ADDR*/ + #define IN_NEXTHOP_TBL_MAC_ADDR + #define IN_NEXTHOP_TBL_MAC_ADDR_OFFSET 48 + #define IN_NEXTHOP_TBL_MAC_ADDR_LEN 48 + #define IN_NEXTHOP_TBL_MAC_ADDR_DEFAULT 0x0 + /*[field] IP_ADDR_DNAT*/ + #define IN_NEXTHOP_TBL_IP_ADDR_DNAT + #define IN_NEXTHOP_TBL_IP_ADDR_DNAT_OFFSET 96 + #define IN_NEXTHOP_TBL_IP_ADDR_DNAT_LEN 32 + #define IN_NEXTHOP_TBL_IP_ADDR_DNAT_DEFAULT 0x0 + +struct in_nexthop_tbl_1 { + a_uint32_t type:1; + a_uint32_t vsi:5; + a_uint32_t _reserved0:3; + a_uint32_t post_l3_if:8; + a_uint32_t ip_to_me:1; + a_uint32_t stag_fmt:1; + a_uint32_t svid:12; + a_uint32_t ctag_fmt:1; + a_uint32_t cvid:12; + a_uint32_t ip_pub_addr_index:4; + a_uint32_t mac_addr_0:16; + a_uint32_t mac_addr_1:32; + a_uint32_t ip_addr_dnat:32; +}; + +struct in_nexthop_tbl_0 { + a_uint32_t type:1; + a_uint32_t port:8; + a_uint32_t post_l3_if:8; + a_uint32_t ip_to_me:1; + a_uint32_t stag_fmt:1; + a_uint32_t svid:12; + a_uint32_t ctag_fmt:1; + a_uint32_t cvid:12; + a_uint32_t ip_pub_addr_index:4; + a_uint32_t mac_addr_0:16; + a_uint32_t mac_addr_1:32; + a_uint32_t ip_addr_dnat:32; +}; + +union in_nexthop_tbl_u { + a_uint32_t val[4]; + struct in_nexthop_tbl_0 bf0; + struct in_nexthop_tbl_1 bf1; +}; + +/*[table] EG_L3_IF_TBL*/ +#define EG_L3_IF_TBL +#define EG_L3_IF_TBL_ADDRESS 0xe000 +#define EG_L3_IF_TBL_NUM 256 +#define EG_L3_IF_TBL_INC 0x10 +#define EG_L3_IF_TBL_TYPE REG_TYPE_RW +#define EG_L3_IF_TBL_DEFAULT 0x0 + /*[field] MAC_ADDR*/ + #define EG_L3_IF_TBL_MAC_ADDR + #define EG_L3_IF_TBL_MAC_ADDR_OFFSET 0 + #define EG_L3_IF_TBL_MAC_ADDR_LEN 48 + #define EG_L3_IF_TBL_MAC_ADDR_DEFAULT 0x0 + /*[field] SESSION_ID*/ + #define EG_L3_IF_TBL_SESSION_ID + #define EG_L3_IF_TBL_SESSION_ID_OFFSET 48 + #define EG_L3_IF_TBL_SESSION_ID_LEN 16 + #define EG_L3_IF_TBL_SESSION_ID_DEFAULT 0x0 + /*[field] PPPOE_EN*/ + #define EG_L3_IF_TBL_PPPOE_EN + #define EG_L3_IF_TBL_PPPOE_EN_OFFSET 64 + #define EG_L3_IF_TBL_PPPOE_EN_LEN 1 + #define EG_L3_IF_TBL_PPPOE_EN_DEFAULT 0x0 + +struct eg_l3_if_tbl { + a_uint32_t mac_addr_0:32; + a_uint32_t mac_addr_1:16; + a_uint32_t session_id:16; + a_uint32_t pppoe_en:1; + a_uint32_t _reserved0:31; +}; + +union eg_l3_if_tbl_u { + a_uint32_t val[3]; + struct eg_l3_if_tbl bf; +}; + +/*[table] RT_INTERFACE_CNT_TBL*/ +#define RT_INTERFACE_CNT_TBL +#define RT_INTERFACE_CNT_TBL_ADDRESS 0x40000 +#define RT_INTERFACE_CNT_TBL_NUM 512 +#define RT_INTERFACE_CNT_TBL_INC 0x20 +#define RT_INTERFACE_CNT_TBL_TYPE REG_TYPE_RW +#define RT_INTERFACE_CNT_TBL_DEFAULT 0x0 + /*[field] PKT_CNT*/ + #define RT_INTERFACE_CNT_TBL_PKT_CNT + #define RT_INTERFACE_CNT_TBL_PKT_CNT_OFFSET 0 + #define RT_INTERFACE_CNT_TBL_PKT_CNT_LEN 32 + #define RT_INTERFACE_CNT_TBL_PKT_CNT_DEFAULT 0x0 + /*[field] BYTE_CNT*/ + #define RT_INTERFACE_CNT_TBL_BYTE_CNT + #define RT_INTERFACE_CNT_TBL_BYTE_CNT_OFFSET 32 + #define RT_INTERFACE_CNT_TBL_BYTE_CNT_LEN 40 + #define RT_INTERFACE_CNT_TBL_BYTE_CNT_DEFAULT 0x0 + /*[field] DROP_PKT_CNT*/ + #define RT_INTERFACE_CNT_TBL_DROP_PKT_CNT + #define RT_INTERFACE_CNT_TBL_DROP_PKT_CNT_OFFSET 72 + #define RT_INTERFACE_CNT_TBL_DROP_PKT_CNT_LEN 32 + #define RT_INTERFACE_CNT_TBL_DROP_PKT_CNT_DEFAULT 0x0 + /*[field] DROP_BYTE_CNT*/ + #define RT_INTERFACE_CNT_TBL_DROP_BYTE_CNT + #define RT_INTERFACE_CNT_TBL_DROP_BYTE_CNT_OFFSET 104 + #define RT_INTERFACE_CNT_TBL_DROP_BYTE_CNT_LEN 40 + #define RT_INTERFACE_CNT_TBL_DROP_BYTE_CNT_DEFAULT 0x0 + +struct rt_interface_cnt_tbl { + a_uint32_t pkt_cnt:32; + a_uint32_t byte_cnt_0:32; + a_uint32_t byte_cnt_1:8; + a_uint32_t drop_pkt_cnt_0:24; + a_uint32_t drop_pkt_cnt_1:8; + a_uint32_t drop_byte_cnt_0:24; + a_uint32_t drop_byte_cnt_1:16; + a_uint32_t _reserved0:16; +}; + +union rt_interface_cnt_tbl_u { + a_uint32_t val[5]; + struct rt_interface_cnt_tbl bf; +}; + + + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_mib.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_mib.h new file mode 100755 index 000000000..a80dd304d --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_mib.h @@ -0,0 +1,1150 @@ +/* + * 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 + * @{ + */ +#ifndef _HPPE_MIB_H_ +#define _HPPE_MIB_H_ + +#define MAC_MIB_CTRL_MAX_ENTRY 6 +#define RXBROAD_MAX_ENTRY 6 +#define RXPAUSE_MAX_ENTRY 6 +#define RXMULTI_MAX_ENTRY 6 +#define RXFCSERR_MAX_ENTRY 6 +#define RXALIGNERR_MAX_ENTRY 6 +#define RXRUNT_MAX_ENTRY 6 +#define RXFRAG_MAX_ENTRY 6 +#define RXJUMBOFCSERR_MAX_ENTRY 6 +#define RXJUMBOALIGNERR_MAX_ENTRY 6 +#define RXPKT64_MAX_ENTRY 6 +#define RXPKT65TO127_MAX_ENTRY 6 +#define RXPKT128TO255_MAX_ENTRY 6 +#define RXPKT256TO511_MAX_ENTRY 6 +#define RXPKT512TO1023_MAX_ENTRY 6 +#define RXPKT1024TO1518_MAX_ENTRY 6 +#define RXPKT1519TOX_MAX_ENTRY 6 +#define RXTOOLONG_MAX_ENTRY 6 +#define RXGOODBYTE_L_MAX_ENTRY 6 +#define RXGOODBYTE_H_MAX_ENTRY 6 +#define RXBADBYTE_L_MAX_ENTRY 6 +#define RXBADBYTE_H_MAX_ENTRY 6 +#define RXUNI_MAX_ENTRY 6 +#define TXBROAD_MAX_ENTRY 6 +#define TXPAUSE_MAX_ENTRY 6 +#define TXMULTI_MAX_ENTRY 6 +#define TXUNDERRUN_MAX_ENTRY 6 +#define TXPKT64_MAX_ENTRY 6 +#define TXPKT65TO127_MAX_ENTRY 6 +#define TXPKT128TO255_MAX_ENTRY 6 +#define TXPKT256TO511_MAX_ENTRY 6 +#define TXPKT512TO1023_MAX_ENTRY 6 +#define TXPKT1024TO1518_MAX_ENTRY 6 +#define TXPKT1519TOX_MAX_ENTRY 6 +#define TXBYTE_L_MAX_ENTRY 6 +#define TXBYTE_H_MAX_ENTRY 6 +#define TXCOLLISIONS_MAX_ENTRY 6 +#define TXABORTCOL_MAX_ENTRY 6 +#define TXMULTICOL_MAX_ENTRY 6 +#define TXSINGLECOL_MAX_ENTRY 6 +#define TXEXCESSIVEDEFER_MAX_ENTRY 6 +#define TXDEFER_MAX_ENTRY 6 +#define TXLATECOL_MAX_ENTRY 6 +#define TXUNI_MAX_ENTRY 6 + + +sw_error_t +hppe_mac_mib_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_mib_ctrl_u *value); + +sw_error_t +hppe_mac_mib_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_mib_ctrl_u *value); + +sw_error_t +hppe_rxbroad_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxbroad_u *value); + +sw_error_t +hppe_rxbroad_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxbroad_u *value); + +sw_error_t +hppe_rxpause_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxpause_u *value); + +sw_error_t +hppe_rxpause_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxpause_u *value); + +sw_error_t +hppe_rxmulti_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxmulti_u *value); + +sw_error_t +hppe_rxmulti_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxmulti_u *value); + +sw_error_t +hppe_rxfcserr_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxfcserr_u *value); + +sw_error_t +hppe_rxfcserr_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxfcserr_u *value); + +sw_error_t +hppe_rxalignerr_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxalignerr_u *value); + +sw_error_t +hppe_rxalignerr_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxalignerr_u *value); + +sw_error_t +hppe_rxrunt_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxrunt_u *value); + +sw_error_t +hppe_rxrunt_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxrunt_u *value); + +sw_error_t +hppe_rxfrag_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxfrag_u *value); + +sw_error_t +hppe_rxfrag_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxfrag_u *value); + +sw_error_t +hppe_rxjumbofcserr_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxjumbofcserr_u *value); + +sw_error_t +hppe_rxjumbofcserr_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxjumbofcserr_u *value); + +sw_error_t +hppe_rxjumboalignerr_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxjumboalignerr_u *value); + +sw_error_t +hppe_rxjumboalignerr_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxjumboalignerr_u *value); + +sw_error_t +hppe_rxpkt64_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxpkt64_u *value); + +sw_error_t +hppe_rxpkt64_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxpkt64_u *value); + +sw_error_t +hppe_rxpkt65to127_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxpkt65to127_u *value); + +sw_error_t +hppe_rxpkt65to127_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxpkt65to127_u *value); + +sw_error_t +hppe_rxpkt128to255_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxpkt128to255_u *value); + +sw_error_t +hppe_rxpkt128to255_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxpkt128to255_u *value); + +sw_error_t +hppe_rxpkt256to511_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxpkt256to511_u *value); + +sw_error_t +hppe_rxpkt256to511_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxpkt256to511_u *value); + +sw_error_t +hppe_rxpkt512to1023_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxpkt512to1023_u *value); + +sw_error_t +hppe_rxpkt512to1023_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxpkt512to1023_u *value); + +sw_error_t +hppe_rxpkt1024to1518_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxpkt1024to1518_u *value); + +sw_error_t +hppe_rxpkt1024to1518_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxpkt1024to1518_u *value); + +sw_error_t +hppe_rxpkt1519tox_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxpkt1519tox_u *value); + +sw_error_t +hppe_rxpkt1519tox_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxpkt1519tox_u *value); + +sw_error_t +hppe_rxtoolong_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxtoolong_u *value); + +sw_error_t +hppe_rxtoolong_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxtoolong_u *value); + +sw_error_t +hppe_rxgoodbyte_l_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxgoodbyte_l_u *value); + +sw_error_t +hppe_rxgoodbyte_l_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxgoodbyte_l_u *value); + +sw_error_t +hppe_rxgoodbyte_h_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxgoodbyte_h_u *value); + +sw_error_t +hppe_rxgoodbyte_h_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxgoodbyte_h_u *value); + +sw_error_t +hppe_rxbadbyte_l_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxbadbyte_l_u *value); + +sw_error_t +hppe_rxbadbyte_l_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxbadbyte_l_u *value); + +sw_error_t +hppe_rxbadbyte_h_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxbadbyte_h_u *value); + +sw_error_t +hppe_rxbadbyte_h_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxbadbyte_h_u *value); + +sw_error_t +hppe_rxuni_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxuni_u *value); + +sw_error_t +hppe_rxuni_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxuni_u *value); + +sw_error_t +hppe_txbroad_get( + a_uint32_t dev_id, + a_uint32_t index, + union txbroad_u *value); + +sw_error_t +hppe_txbroad_set( + a_uint32_t dev_id, + a_uint32_t index, + union txbroad_u *value); + +sw_error_t +hppe_txpause_get( + a_uint32_t dev_id, + a_uint32_t index, + union txpause_u *value); + +sw_error_t +hppe_txpause_set( + a_uint32_t dev_id, + a_uint32_t index, + union txpause_u *value); + +sw_error_t +hppe_txmulti_get( + a_uint32_t dev_id, + a_uint32_t index, + union txmulti_u *value); + +sw_error_t +hppe_txmulti_set( + a_uint32_t dev_id, + a_uint32_t index, + union txmulti_u *value); + +sw_error_t +hppe_txunderrun_get( + a_uint32_t dev_id, + a_uint32_t index, + union txunderrun_u *value); + +sw_error_t +hppe_txunderrun_set( + a_uint32_t dev_id, + a_uint32_t index, + union txunderrun_u *value); + +sw_error_t +hppe_txpkt64_get( + a_uint32_t dev_id, + a_uint32_t index, + union txpkt64_u *value); + +sw_error_t +hppe_txpkt64_set( + a_uint32_t dev_id, + a_uint32_t index, + union txpkt64_u *value); + +sw_error_t +hppe_txpkt65to127_get( + a_uint32_t dev_id, + a_uint32_t index, + union txpkt65to127_u *value); + +sw_error_t +hppe_txpkt65to127_set( + a_uint32_t dev_id, + a_uint32_t index, + union txpkt65to127_u *value); + +sw_error_t +hppe_txpkt128to255_get( + a_uint32_t dev_id, + a_uint32_t index, + union txpkt128to255_u *value); + +sw_error_t +hppe_txpkt128to255_set( + a_uint32_t dev_id, + a_uint32_t index, + union txpkt128to255_u *value); + +sw_error_t +hppe_txpkt256to511_get( + a_uint32_t dev_id, + a_uint32_t index, + union txpkt256to511_u *value); + +sw_error_t +hppe_txpkt256to511_set( + a_uint32_t dev_id, + a_uint32_t index, + union txpkt256to511_u *value); + +sw_error_t +hppe_txpkt512to1023_get( + a_uint32_t dev_id, + a_uint32_t index, + union txpkt512to1023_u *value); + +sw_error_t +hppe_txpkt512to1023_set( + a_uint32_t dev_id, + a_uint32_t index, + union txpkt512to1023_u *value); + +sw_error_t +hppe_txpkt1024to1518_get( + a_uint32_t dev_id, + a_uint32_t index, + union txpkt1024to1518_u *value); + +sw_error_t +hppe_txpkt1024to1518_set( + a_uint32_t dev_id, + a_uint32_t index, + union txpkt1024to1518_u *value); + +sw_error_t +hppe_txpkt1519tox_get( + a_uint32_t dev_id, + a_uint32_t index, + union txpkt1519tox_u *value); + +sw_error_t +hppe_txpkt1519tox_set( + a_uint32_t dev_id, + a_uint32_t index, + union txpkt1519tox_u *value); + +sw_error_t +hppe_txbyte_l_get( + a_uint32_t dev_id, + a_uint32_t index, + union txbyte_l_u *value); + +sw_error_t +hppe_txbyte_l_set( + a_uint32_t dev_id, + a_uint32_t index, + union txbyte_l_u *value); + +sw_error_t +hppe_txbyte_h_get( + a_uint32_t dev_id, + a_uint32_t index, + union txbyte_h_u *value); + +sw_error_t +hppe_txbyte_h_set( + a_uint32_t dev_id, + a_uint32_t index, + union txbyte_h_u *value); + +sw_error_t +hppe_txcollisions_get( + a_uint32_t dev_id, + a_uint32_t index, + union txcollisions_u *value); + +sw_error_t +hppe_txcollisions_set( + a_uint32_t dev_id, + a_uint32_t index, + union txcollisions_u *value); + +sw_error_t +hppe_txabortcol_get( + a_uint32_t dev_id, + a_uint32_t index, + union txabortcol_u *value); + +sw_error_t +hppe_txabortcol_set( + a_uint32_t dev_id, + a_uint32_t index, + union txabortcol_u *value); + +sw_error_t +hppe_txmulticol_get( + a_uint32_t dev_id, + a_uint32_t index, + union txmulticol_u *value); + +sw_error_t +hppe_txmulticol_set( + a_uint32_t dev_id, + a_uint32_t index, + union txmulticol_u *value); + +sw_error_t +hppe_txsinglecol_get( + a_uint32_t dev_id, + a_uint32_t index, + union txsinglecol_u *value); + +sw_error_t +hppe_txsinglecol_set( + a_uint32_t dev_id, + a_uint32_t index, + union txsinglecol_u *value); + +sw_error_t +hppe_txexcessivedefer_get( + a_uint32_t dev_id, + a_uint32_t index, + union txexcessivedefer_u *value); + +sw_error_t +hppe_txexcessivedefer_set( + a_uint32_t dev_id, + a_uint32_t index, + union txexcessivedefer_u *value); + +sw_error_t +hppe_txdefer_get( + a_uint32_t dev_id, + a_uint32_t index, + union txdefer_u *value); + +sw_error_t +hppe_txdefer_set( + a_uint32_t dev_id, + a_uint32_t index, + union txdefer_u *value); + +sw_error_t +hppe_txlatecol_get( + a_uint32_t dev_id, + a_uint32_t index, + union txlatecol_u *value); + +sw_error_t +hppe_txlatecol_set( + a_uint32_t dev_id, + a_uint32_t index, + union txlatecol_u *value); + +sw_error_t +hppe_txuni_get( + a_uint32_t dev_id, + a_uint32_t index, + union txuni_u *value); + +sw_error_t +hppe_txuni_set( + a_uint32_t dev_id, + a_uint32_t index, + union txuni_u *value); + +sw_error_t +hppe_mac_mib_ctrl_mib_reset_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_mib_ctrl_mib_reset_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_mib_ctrl_mib_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_mib_ctrl_mib_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_mib_ctrl_mib_rd_clr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_mib_ctrl_mib_rd_clr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rxbroad_rxbroad_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rxbroad_rxbroad_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rxpause_rxpause_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rxpause_rxpause_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rxmulti_rxmulti_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rxmulti_rxmulti_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rxfcserr_rxfcserr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rxfcserr_rxfcserr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rxalignerr_rxalignerr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rxalignerr_rxalignerr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rxrunt_rxrunt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rxrunt_rxrunt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rxfrag_rxfrag_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rxfrag_rxfrag_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rxjumbofcserr_rxjumbofcserr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rxjumbofcserr_rxjumbofcserr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rxjumboalignerr_rxjumboalignerr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rxjumboalignerr_rxjumboalignerr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rxpkt64_rxpkt64_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rxpkt64_rxpkt64_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rxpkt65to127_rxpkt65to127_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rxpkt65to127_rxpkt65to127_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rxpkt128to255_rxpkt128to255_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rxpkt128to255_rxpkt128to255_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rxpkt256to511_rxpkt256to511_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rxpkt256to511_rxpkt256to511_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rxpkt512to1023_rxpkt512to1023_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rxpkt512to1023_rxpkt512to1023_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rxpkt1024to1518_rxpkt1024to1518_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rxpkt1024to1518_rxpkt1024to1518_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rxpkt1519tox_rxpkt1519tox_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rxpkt1519tox_rxpkt1519tox_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rxtoolong_rxtoolong_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rxtoolong_rxtoolong_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rxgoodbyte_l_rxgoodbyte_l_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rxgoodbyte_l_rxgoodbyte_l_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rxgoodbyte_h_rxgoodbyte_h_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rxgoodbyte_h_rxgoodbyte_h_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rxbadbyte_l_rxbadbyte_l_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rxbadbyte_l_rxbadbyte_l_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rxbadbyte_h_rxbadbyte_h_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rxbadbyte_h_rxbadbyte_h_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rxuni_rxuni_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rxuni_rxuni_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_txbroad_txbroad_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_txbroad_txbroad_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_txpause_txpause_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_txpause_txpause_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_txmulti_txmulti_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_txmulti_txmulti_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_txunderrun_txunderrun_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_txunderrun_txunderrun_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_txpkt64_txpkt64_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_txpkt64_txpkt64_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_txpkt65to127_txpkt65to127_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_txpkt65to127_txpkt65to127_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_txpkt128to255_txpkt128to255_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_txpkt128to255_txpkt128to255_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_txpkt256to511_txpkt256to511_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_txpkt256to511_txpkt256to511_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_txpkt512to1023_txpkt512to1023_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_txpkt512to1023_txpkt512to1023_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_txpkt1024to1518_txpkt1024to1518_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_txpkt1024to1518_txpkt1024to1518_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_txpkt1519tox_txpkt1519tox_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_txpkt1519tox_txpkt1519tox_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_txbyte_l_txbyte_l_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_txbyte_l_txbyte_l_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_txbyte_h_txbyte_h_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_txbyte_h_txbyte_h_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_txcollisions_txcollisions_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_txcollisions_txcollisions_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_txabortcol_txabortcol_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_txabortcol_txabortcol_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_txmulticol_txmulticol_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_txmulticol_txmulticol_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_txsinglecol_txsinglecol_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_txsinglecol_txsinglecol_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_txexcessivedefer_txexcessivedefer_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_txexcessivedefer_txexcessivedefer_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_txdefer_txdefer_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_txdefer_txdefer_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_txlatecol_txlatecol_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_txlatecol_txlatecol_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_txuni_txuni_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_txuni_txuni_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_mib_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_mib_reg.h new file mode 100755 index 000000000..476d5e805 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_mib_reg.h @@ -0,0 +1,1006 @@ +/* + * 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 + * @{ + */ +#ifndef HPPE_MIB_REG_H +#define HPPE_MIB_REG_H + +/*[register] MAC_MIB_CTRL*/ +#define MAC_MIB_CTRL +#define MAC_MIB_CTRL_ADDRESS 0x34 +#define MAC_MIB_CTRL_NUM 6 +#define MAC_MIB_CTRL_INC 0x200 +#define MAC_MIB_CTRL_TYPE REG_TYPE_RW +#define MAC_MIB_CTRL_DEFAULT 0x0 + /*[field] MIB_EN*/ + #define MAC_MIB_CTRL_MIB_EN + #define MAC_MIB_CTRL_MIB_EN_OFFSET 0 + #define MAC_MIB_CTRL_MIB_EN_LEN 1 + #define MAC_MIB_CTRL_MIB_EN_DEFAULT 0x0 + /*[field] MIB_RESET*/ + #define MAC_MIB_CTRL_MIB_RESET + #define MAC_MIB_CTRL_MIB_RESET_OFFSET 1 + #define MAC_MIB_CTRL_MIB_RESET_LEN 1 + #define MAC_MIB_CTRL_MIB_RESET_DEFAULT 0x0 + /*[field] MIB_RD_CLR*/ + #define MAC_MIB_CTRL_MIB_RD_CLR + #define MAC_MIB_CTRL_MIB_RD_CLR_OFFSET 2 + #define MAC_MIB_CTRL_MIB_RD_CLR_LEN 1 + #define MAC_MIB_CTRL_MIB_RD_CLR_DEFAULT 0x0 + +struct mac_mib_ctrl { + a_uint32_t mib_en:1; + a_uint32_t mib_reset:1; + a_uint32_t mib_rd_clr:1; + a_uint32_t _reserved0:29; +}; + +union mac_mib_ctrl_u { + a_uint32_t val; + struct mac_mib_ctrl bf; +}; + +/*[register] RXBROAD*/ +#define RXBROAD +#define RXBROAD_ADDRESS 0x40 +#define RXBROAD_NUM 6 +#define RXBROAD_INC 0x200 +#define RXBROAD_TYPE REG_TYPE_RO +#define RXBROAD_DEFAULT 0x0 + /*[field] RXBROAD*/ + #define RXBROAD_RXBROAD + #define RXBROAD_RXBROAD_OFFSET 0 + #define RXBROAD_RXBROAD_LEN 32 + #define RXBROAD_RXBROAD_DEFAULT 0x0 + +struct rxbroad { + a_uint32_t rxbroad:32; +}; + +union rxbroad_u { + a_uint32_t val; + struct rxbroad bf; +}; + +/*[register] RXPAUSE*/ +#define RXPAUSE +#define RXPAUSE_ADDRESS 0x44 +#define RXPAUSE_NUM 6 +#define RXPAUSE_INC 0x200 +#define RXPAUSE_TYPE REG_TYPE_RO +#define RXPAUSE_DEFAULT 0x0 + /*[field] RXPAUSE*/ + #define RXPAUSE_RXPAUSE + #define RXPAUSE_RXPAUSE_OFFSET 0 + #define RXPAUSE_RXPAUSE_LEN 32 + #define RXPAUSE_RXPAUSE_DEFAULT 0x0 + +struct rxpause { + a_uint32_t rxpause:32; +}; + +union rxpause_u { + a_uint32_t val; + struct rxpause bf; +}; + +/*[register] RXMULTI*/ +#define RXMULTI +#define RXMULTI_ADDRESS 0x48 +#define RXMULTI_NUM 6 +#define RXMULTI_INC 0x200 +#define RXMULTI_TYPE REG_TYPE_RO +#define RXMULTI_DEFAULT 0x0 + /*[field] RXMULTI*/ + #define RXMULTI_RXMULTI + #define RXMULTI_RXMULTI_OFFSET 0 + #define RXMULTI_RXMULTI_LEN 32 + #define RXMULTI_RXMULTI_DEFAULT 0x0 + +struct rxmulti { + a_uint32_t rxmulti:32; +}; + +union rxmulti_u { + a_uint32_t val; + struct rxmulti bf; +}; + +/*[register] RXFCSERR*/ +#define RXFCSERR +#define RXFCSERR_ADDRESS 0x4c +#define RXFCSERR_NUM 6 +#define RXFCSERR_INC 0x200 +#define RXFCSERR_TYPE REG_TYPE_RO +#define RXFCSERR_DEFAULT 0x0 + /*[field] RXFCSERR*/ + #define RXFCSERR_RXFCSERR + #define RXFCSERR_RXFCSERR_OFFSET 0 + #define RXFCSERR_RXFCSERR_LEN 32 + #define RXFCSERR_RXFCSERR_DEFAULT 0x0 + +struct rxfcserr { + a_uint32_t rxfcserr:32; +}; + +union rxfcserr_u { + a_uint32_t val; + struct rxfcserr bf; +}; + +/*[register] RXALIGNERR*/ +#define RXALIGNERR +#define RXALIGNERR_ADDRESS 0x50 +#define RXALIGNERR_NUM 6 +#define RXALIGNERR_INC 0x200 +#define RXALIGNERR_TYPE REG_TYPE_RO +#define RXALIGNERR_DEFAULT 0x0 + /*[field] RXALIGNERR*/ + #define RXALIGNERR_RXALIGNERR + #define RXALIGNERR_RXALIGNERR_OFFSET 0 + #define RXALIGNERR_RXALIGNERR_LEN 32 + #define RXALIGNERR_RXALIGNERR_DEFAULT 0x0 + +struct rxalignerr { + a_uint32_t rxalignerr:32; +}; + +union rxalignerr_u { + a_uint32_t val; + struct rxalignerr bf; +}; + +/*[register] RXRUNT*/ +#define RXRUNT +#define RXRUNT_ADDRESS 0x54 +#define RXRUNT_NUM 6 +#define RXRUNT_INC 0x200 +#define RXRUNT_TYPE REG_TYPE_RO +#define RXRUNT_DEFAULT 0x0 + /*[field] RXRUNT*/ + #define RXRUNT_RXRUNT + #define RXRUNT_RXRUNT_OFFSET 0 + #define RXRUNT_RXRUNT_LEN 32 + #define RXRUNT_RXRUNT_DEFAULT 0x0 + +struct rxrunt { + a_uint32_t rxrunt:32; +}; + +union rxrunt_u { + a_uint32_t val; + struct rxrunt bf; +}; + +/*[register] RXFRAG*/ +#define RXFRAG +#define RXFRAG_ADDRESS 0x58 +#define RXFRAG_NUM 6 +#define RXFRAG_INC 0x200 +#define RXFRAG_TYPE REG_TYPE_RO +#define RXFRAG_DEFAULT 0x0 + /*[field] RXFRAG*/ + #define RXFRAG_RXFRAG + #define RXFRAG_RXFRAG_OFFSET 0 + #define RXFRAG_RXFRAG_LEN 32 + #define RXFRAG_RXFRAG_DEFAULT 0x0 + +struct rxfrag { + a_uint32_t rxfrag:32; +}; + +union rxfrag_u { + a_uint32_t val; + struct rxfrag bf; +}; + +/*[register] RXJUMBOFCSERR*/ +#define RXJUMBOFCSERR +#define RXJUMBOFCSERR_ADDRESS 0x5c +#define RXJUMBOFCSERR_NUM 6 +#define RXJUMBOFCSERR_INC 0x200 +#define RXJUMBOFCSERR_TYPE REG_TYPE_RO +#define RXJUMBOFCSERR_DEFAULT 0x0 + /*[field] RXJUMBOFCSERR*/ + #define RXJUMBOFCSERR_RXJUMBOFCSERR + #define RXJUMBOFCSERR_RXJUMBOFCSERR_OFFSET 0 + #define RXJUMBOFCSERR_RXJUMBOFCSERR_LEN 32 + #define RXJUMBOFCSERR_RXJUMBOFCSERR_DEFAULT 0x0 + +struct rxjumbofcserr { + a_uint32_t rxjumbofcserr:32; +}; + +union rxjumbofcserr_u { + a_uint32_t val; + struct rxjumbofcserr bf; +}; + +/*[register] RXJUMBOALIGNERR*/ +#define RXJUMBOALIGNERR +#define RXJUMBOALIGNERR_ADDRESS 0x60 +#define RXJUMBOALIGNERR_NUM 6 +#define RXJUMBOALIGNERR_INC 0x200 +#define RXJUMBOALIGNERR_TYPE REG_TYPE_RO +#define RXJUMBOALIGNERR_DEFAULT 0x0 + /*[field] RXJUMBOALIGNERR*/ + #define RXJUMBOALIGNERR_RXJUMBOALIGNERR + #define RXJUMBOALIGNERR_RXJUMBOALIGNERR_OFFSET 0 + #define RXJUMBOALIGNERR_RXJUMBOALIGNERR_LEN 32 + #define RXJUMBOALIGNERR_RXJUMBOALIGNERR_DEFAULT 0x0 + +struct rxjumboalignerr { + a_uint32_t rxjumboalignerr:32; +}; + +union rxjumboalignerr_u { + a_uint32_t val; + struct rxjumboalignerr bf; +}; + +/*[register] RXPKT64*/ +#define RXPKT64 +#define RXPKT64_ADDRESS 0x64 +#define RXPKT64_NUM 6 +#define RXPKT64_INC 0x200 +#define RXPKT64_TYPE REG_TYPE_RO +#define RXPKT64_DEFAULT 0x0 + /*[field] RXPKT64*/ + #define RXPKT64_RXPKT64 + #define RXPKT64_RXPKT64_OFFSET 0 + #define RXPKT64_RXPKT64_LEN 32 + #define RXPKT64_RXPKT64_DEFAULT 0x0 + +struct rxpkt64 { + a_uint32_t rxpkt64:32; +}; + +union rxpkt64_u { + a_uint32_t val; + struct rxpkt64 bf; +}; + +/*[register] RXPKT65TO127*/ +#define RXPKT65TO127 +#define RXPKT65TO127_ADDRESS 0x68 +#define RXPKT65TO127_NUM 6 +#define RXPKT65TO127_INC 0x200 +#define RXPKT65TO127_TYPE REG_TYPE_RO +#define RXPKT65TO127_DEFAULT 0x0 + /*[field] RXPKT65TO127*/ + #define RXPKT65TO127_RXPKT65TO127 + #define RXPKT65TO127_RXPKT65TO127_OFFSET 0 + #define RXPKT65TO127_RXPKT65TO127_LEN 32 + #define RXPKT65TO127_RXPKT65TO127_DEFAULT 0x0 + +struct rxpkt65to127 { + a_uint32_t rxpkt65to127:32; +}; + +union rxpkt65to127_u { + a_uint32_t val; + struct rxpkt65to127 bf; +}; + +/*[register] RXPKT128TO255*/ +#define RXPKT128TO255 +#define RXPKT128TO255_ADDRESS 0x6c +#define RXPKT128TO255_NUM 6 +#define RXPKT128TO255_INC 0x200 +#define RXPKT128TO255_TYPE REG_TYPE_RO +#define RXPKT128TO255_DEFAULT 0x0 + /*[field] RXPKT128TO255*/ + #define RXPKT128TO255_RXPKT128TO255 + #define RXPKT128TO255_RXPKT128TO255_OFFSET 0 + #define RXPKT128TO255_RXPKT128TO255_LEN 32 + #define RXPKT128TO255_RXPKT128TO255_DEFAULT 0x0 + +struct rxpkt128to255 { + a_uint32_t rxpkt128to255:32; +}; + +union rxpkt128to255_u { + a_uint32_t val; + struct rxpkt128to255 bf; +}; + +/*[register] RXPKT256TO511*/ +#define RXPKT256TO511 +#define RXPKT256TO511_ADDRESS 0x70 +#define RXPKT256TO511_NUM 6 +#define RXPKT256TO511_INC 0x200 +#define RXPKT256TO511_TYPE REG_TYPE_RO +#define RXPKT256TO511_DEFAULT 0x0 + /*[field] RXPKT256TO511*/ + #define RXPKT256TO511_RXPKT256TO511 + #define RXPKT256TO511_RXPKT256TO511_OFFSET 0 + #define RXPKT256TO511_RXPKT256TO511_LEN 32 + #define RXPKT256TO511_RXPKT256TO511_DEFAULT 0x0 + +struct rxpkt256to511 { + a_uint32_t rxpkt256to511:32; +}; + +union rxpkt256to511_u { + a_uint32_t val; + struct rxpkt256to511 bf; +}; + +/*[register] RXPKT512TO1023*/ +#define RXPKT512TO1023 +#define RXPKT512TO1023_ADDRESS 0x74 +#define RXPKT512TO1023_NUM 6 +#define RXPKT512TO1023_INC 0x200 +#define RXPKT512TO1023_TYPE REG_TYPE_RO +#define RXPKT512TO1023_DEFAULT 0x0 + /*[field] RXPKT512TO1023*/ + #define RXPKT512TO1023_RXPKT512TO1023 + #define RXPKT512TO1023_RXPKT512TO1023_OFFSET 0 + #define RXPKT512TO1023_RXPKT512TO1023_LEN 32 + #define RXPKT512TO1023_RXPKT512TO1023_DEFAULT 0x0 + +struct rxpkt512to1023 { + a_uint32_t rxpkt512to1023:32; +}; + +union rxpkt512to1023_u { + a_uint32_t val; + struct rxpkt512to1023 bf; +}; + +/*[register] RXPKT1024TO1518*/ +#define RXPKT1024TO1518 +#define RXPKT1024TO1518_ADDRESS 0x78 +#define RXPKT1024TO1518_NUM 6 +#define RXPKT1024TO1518_INC 0x200 +#define RXPKT1024TO1518_TYPE REG_TYPE_RO +#define RXPKT1024TO1518_DEFAULT 0x0 + /*[field] RXPKT1024TO1518*/ + #define RXPKT1024TO1518_RXPKT1024TO1518 + #define RXPKT1024TO1518_RXPKT1024TO1518_OFFSET 0 + #define RXPKT1024TO1518_RXPKT1024TO1518_LEN 32 + #define RXPKT1024TO1518_RXPKT1024TO1518_DEFAULT 0x0 + +struct rxpkt1024to1518 { + a_uint32_t rxpkt1024to1518:32; +}; + +union rxpkt1024to1518_u { + a_uint32_t val; + struct rxpkt1024to1518 bf; +}; + +/*[register] RXPKT1519TOX*/ +#define RXPKT1519TOX +#define RXPKT1519TOX_ADDRESS 0x7c +#define RXPKT1519TOX_NUM 6 +#define RXPKT1519TOX_INC 0x200 +#define RXPKT1519TOX_TYPE REG_TYPE_RO +#define RXPKT1519TOX_DEFAULT 0x0 + /*[field] RXPKT1519TOX*/ + #define RXPKT1519TOX_RXPKT1519TOX + #define RXPKT1519TOX_RXPKT1519TOX_OFFSET 0 + #define RXPKT1519TOX_RXPKT1519TOX_LEN 32 + #define RXPKT1519TOX_RXPKT1519TOX_DEFAULT 0x0 + +struct rxpkt1519tox { + a_uint32_t rxpkt1519tox:32; +}; + +union rxpkt1519tox_u { + a_uint32_t val; + struct rxpkt1519tox bf; +}; + +/*[register] RXTOOLONG*/ +#define RXTOOLONG +#define RXTOOLONG_ADDRESS 0x80 +#define RXTOOLONG_NUM 6 +#define RXTOOLONG_INC 0x200 +#define RXTOOLONG_TYPE REG_TYPE_RO +#define RXTOOLONG_DEFAULT 0x0 + /*[field] RXTOOLONG*/ + #define RXTOOLONG_RXTOOLONG + #define RXTOOLONG_RXTOOLONG_OFFSET 0 + #define RXTOOLONG_RXTOOLONG_LEN 32 + #define RXTOOLONG_RXTOOLONG_DEFAULT 0x0 + +struct rxtoolong { + a_uint32_t rxtoolong:32; +}; + +union rxtoolong_u { + a_uint32_t val; + struct rxtoolong bf; +}; + +/*[register] RXGOODBYTE_L*/ +#define RXGOODBYTE_L +#define RXGOODBYTE_L_ADDRESS 0x84 +#define RXGOODBYTE_L_NUM 6 +#define RXGOODBYTE_L_INC 0x200 +#define RXGOODBYTE_L_TYPE REG_TYPE_RO +#define RXGOODBYTE_L_DEFAULT 0x0 + /*[field] RXGOODBYTE_L*/ + #define RXGOODBYTE_L_RXGOODBYTE_L + #define RXGOODBYTE_L_RXGOODBYTE_L_OFFSET 0 + #define RXGOODBYTE_L_RXGOODBYTE_L_LEN 32 + #define RXGOODBYTE_L_RXGOODBYTE_L_DEFAULT 0x0 + +struct rxgoodbyte_l { + a_uint32_t rxgoodbyte_l:32; +}; + +union rxgoodbyte_l_u { + a_uint32_t val; + struct rxgoodbyte_l bf; +}; + +/*[register] RXGOODBYTE_H*/ +#define RXGOODBYTE_H +#define RXGOODBYTE_H_ADDRESS 0x88 +#define RXGOODBYTE_H_NUM 6 +#define RXGOODBYTE_H_INC 0x200 +#define RXGOODBYTE_H_TYPE REG_TYPE_RO +#define RXGOODBYTE_H_DEFAULT 0x0 + /*[field] RXGOODBYTE_H*/ + #define RXGOODBYTE_H_RXGOODBYTE_H + #define RXGOODBYTE_H_RXGOODBYTE_H_OFFSET 0 + #define RXGOODBYTE_H_RXGOODBYTE_H_LEN 32 + #define RXGOODBYTE_H_RXGOODBYTE_H_DEFAULT 0x0 + +struct rxgoodbyte_h { + a_uint32_t rxgoodbyte_h:32; +}; + +union rxgoodbyte_h_u { + a_uint32_t val; + struct rxgoodbyte_h bf; +}; + +/*[register] RXBADBYTE_L*/ +#define RXBADBYTE_L +#define RXBADBYTE_L_ADDRESS 0x8c +#define RXBADBYTE_L_NUM 6 +#define RXBADBYTE_L_INC 0x200 +#define RXBADBYTE_L_TYPE REG_TYPE_RO +#define RXBADBYTE_L_DEFAULT 0x0 + /*[field] RXBADBYTE_L*/ + #define RXBADBYTE_L_RXBADBYTE_L + #define RXBADBYTE_L_RXBADBYTE_L_OFFSET 0 + #define RXBADBYTE_L_RXBADBYTE_L_LEN 32 + #define RXBADBYTE_L_RXBADBYTE_L_DEFAULT 0x0 + +struct rxbadbyte_l { + a_uint32_t rxbadbyte_l:32; +}; + +union rxbadbyte_l_u { + a_uint32_t val; + struct rxbadbyte_l bf; +}; + +/*[register] RXBADBYTE_H*/ +#define RXBADBYTE_H +#define RXBADBYTE_H_ADDRESS 0x90 +#define RXBADBYTE_H_NUM 6 +#define RXBADBYTE_H_INC 0x200 +#define RXBADBYTE_H_TYPE REG_TYPE_RO +#define RXBADBYTE_H_DEFAULT 0x0 + /*[field] RXBADBYTE_H*/ + #define RXBADBYTE_H_RXBADBYTE_H + #define RXBADBYTE_H_RXBADBYTE_H_OFFSET 0 + #define RXBADBYTE_H_RXBADBYTE_H_LEN 32 + #define RXBADBYTE_H_RXBADBYTE_H_DEFAULT 0x0 + +struct rxbadbyte_h { + a_uint32_t rxbadbyte_h:32; +}; + +union rxbadbyte_h_u { + a_uint32_t val; + struct rxbadbyte_h bf; +}; + +/*[register] RXUNI*/ +#define RXUNI +#define RXUNI_ADDRESS 0x94 +#define RXUNI_NUM 6 +#define RXUNI_INC 0x200 +#define RXUNI_TYPE REG_TYPE_RO +#define RXUNI_DEFAULT 0x0 + /*[field] RXUNI*/ + #define RXUNI_RXUNI + #define RXUNI_RXUNI_OFFSET 0 + #define RXUNI_RXUNI_LEN 32 + #define RXUNI_RXUNI_DEFAULT 0x0 + +struct rxuni { + a_uint32_t rxuni:32; +}; + +union rxuni_u { + a_uint32_t val; + struct rxuni bf; +}; + +/*[register] TXBROAD*/ +#define TXBROAD +#define TXBROAD_ADDRESS 0xa0 +#define TXBROAD_NUM 6 +#define TXBROAD_INC 0x200 +#define TXBROAD_TYPE REG_TYPE_RO +#define TXBROAD_DEFAULT 0x0 + /*[field] TXBROAD*/ + #define TXBROAD_TXBROAD + #define TXBROAD_TXBROAD_OFFSET 0 + #define TXBROAD_TXBROAD_LEN 32 + #define TXBROAD_TXBROAD_DEFAULT 0x0 + +struct txbroad { + a_uint32_t txbroad:32; +}; + +union txbroad_u { + a_uint32_t val; + struct txbroad bf; +}; + +/*[register] TXPAUSE*/ +#define TXPAUSE +#define TXPAUSE_ADDRESS 0xa4 +#define TXPAUSE_NUM 6 +#define TXPAUSE_INC 0x200 +#define TXPAUSE_TYPE REG_TYPE_RO +#define TXPAUSE_DEFAULT 0x0 + /*[field] TXPAUSE*/ + #define TXPAUSE_TXPAUSE + #define TXPAUSE_TXPAUSE_OFFSET 0 + #define TXPAUSE_TXPAUSE_LEN 32 + #define TXPAUSE_TXPAUSE_DEFAULT 0x0 + +struct txpause { + a_uint32_t txpause:32; +}; + +union txpause_u { + a_uint32_t val; + struct txpause bf; +}; + +/*[register] TXMULTI*/ +#define TXMULTI +#define TXMULTI_ADDRESS 0xa8 +#define TXMULTI_NUM 6 +#define TXMULTI_INC 0x200 +#define TXMULTI_TYPE REG_TYPE_RO +#define TXMULTI_DEFAULT 0x0 + /*[field] TXMULTI*/ + #define TXMULTI_TXMULTI + #define TXMULTI_TXMULTI_OFFSET 0 + #define TXMULTI_TXMULTI_LEN 32 + #define TXMULTI_TXMULTI_DEFAULT 0x0 + +struct txmulti { + a_uint32_t txmulti:32; +}; + +union txmulti_u { + a_uint32_t val; + struct txmulti bf; +}; + +/*[register] TXUNDERRUN*/ +#define TXUNDERRUN +#define TXUNDERRUN_ADDRESS 0xac +#define TXUNDERRUN_NUM 6 +#define TXUNDERRUN_INC 0x200 +#define TXUNDERRUN_TYPE REG_TYPE_RO +#define TXUNDERRUN_DEFAULT 0x0 + /*[field] TXUNDERRUN*/ + #define TXUNDERRUN_TXUNDERRUN + #define TXUNDERRUN_TXUNDERRUN_OFFSET 0 + #define TXUNDERRUN_TXUNDERRUN_LEN 32 + #define TXUNDERRUN_TXUNDERRUN_DEFAULT 0x0 + +struct txunderrun { + a_uint32_t txunderrun:32; +}; + +union txunderrun_u { + a_uint32_t val; + struct txunderrun bf; +}; + +/*[register] TXPKT64*/ +#define TXPKT64 +#define TXPKT64_ADDRESS 0xb0 +#define TXPKT64_NUM 6 +#define TXPKT64_INC 0x200 +#define TXPKT64_TYPE REG_TYPE_RO +#define TXPKT64_DEFAULT 0x0 + /*[field] TXPKT64*/ + #define TXPKT64_TXPKT64 + #define TXPKT64_TXPKT64_OFFSET 0 + #define TXPKT64_TXPKT64_LEN 32 + #define TXPKT64_TXPKT64_DEFAULT 0x0 + +struct txpkt64 { + a_uint32_t txpkt64:32; +}; + +union txpkt64_u { + a_uint32_t val; + struct txpkt64 bf; +}; + +/*[register] TXPKT65TO127*/ +#define TXPKT65TO127 +#define TXPKT65TO127_ADDRESS 0xb4 +#define TXPKT65TO127_NUM 6 +#define TXPKT65TO127_INC 0x200 +#define TXPKT65TO127_TYPE REG_TYPE_RO +#define TXPKT65TO127_DEFAULT 0x0 + /*[field] TXPKT65TO127*/ + #define TXPKT65TO127_TXPKT65TO127 + #define TXPKT65TO127_TXPKT65TO127_OFFSET 0 + #define TXPKT65TO127_TXPKT65TO127_LEN 32 + #define TXPKT65TO127_TXPKT65TO127_DEFAULT 0x0 + +struct txpkt65to127 { + a_uint32_t txpkt65to127:32; +}; + +union txpkt65to127_u { + a_uint32_t val; + struct txpkt65to127 bf; +}; + +/*[register] TXPKT128TO255*/ +#define TXPKT128TO255 +#define TXPKT128TO255_ADDRESS 0xb8 +#define TXPKT128TO255_NUM 6 +#define TXPKT128TO255_INC 0x200 +#define TXPKT128TO255_TYPE REG_TYPE_RO +#define TXPKT128TO255_DEFAULT 0x0 + /*[field] TXPKT128TO255*/ + #define TXPKT128TO255_TXPKT128TO255 + #define TXPKT128TO255_TXPKT128TO255_OFFSET 0 + #define TXPKT128TO255_TXPKT128TO255_LEN 32 + #define TXPKT128TO255_TXPKT128TO255_DEFAULT 0x0 + +struct txpkt128to255 { + a_uint32_t txpkt128to255:32; +}; + +union txpkt128to255_u { + a_uint32_t val; + struct txpkt128to255 bf; +}; + +/*[register] TXPKT256TO511*/ +#define TXPKT256TO511 +#define TXPKT256TO511_ADDRESS 0xbc +#define TXPKT256TO511_NUM 6 +#define TXPKT256TO511_INC 0x200 +#define TXPKT256TO511_TYPE REG_TYPE_RO +#define TXPKT256TO511_DEFAULT 0x0 + /*[field] TXPKT256TO511*/ + #define TXPKT256TO511_TXPKT256TO511 + #define TXPKT256TO511_TXPKT256TO511_OFFSET 0 + #define TXPKT256TO511_TXPKT256TO511_LEN 32 + #define TXPKT256TO511_TXPKT256TO511_DEFAULT 0x0 + +struct txpkt256to511 { + a_uint32_t txpkt256to511:32; +}; + +union txpkt256to511_u { + a_uint32_t val; + struct txpkt256to511 bf; +}; + +/*[register] TXPKT512TO1023*/ +#define TXPKT512TO1023 +#define TXPKT512TO1023_ADDRESS 0xc0 +#define TXPKT512TO1023_NUM 6 +#define TXPKT512TO1023_INC 0x200 +#define TXPKT512TO1023_TYPE REG_TYPE_RO +#define TXPKT512TO1023_DEFAULT 0x0 + /*[field] TXPKT512TO1023*/ + #define TXPKT512TO1023_TXPKT512TO1023 + #define TXPKT512TO1023_TXPKT512TO1023_OFFSET 0 + #define TXPKT512TO1023_TXPKT512TO1023_LEN 32 + #define TXPKT512TO1023_TXPKT512TO1023_DEFAULT 0x0 + +struct txpkt512to1023 { + a_uint32_t txpkt512to1023:32; +}; + +union txpkt512to1023_u { + a_uint32_t val; + struct txpkt512to1023 bf; +}; + +/*[register] TXPKT1024TO1518*/ +#define TXPKT1024TO1518 +#define TXPKT1024TO1518_ADDRESS 0xc4 +#define TXPKT1024TO1518_NUM 6 +#define TXPKT1024TO1518_INC 0x200 +#define TXPKT1024TO1518_TYPE REG_TYPE_RO +#define TXPKT1024TO1518_DEFAULT 0x0 + /*[field] TXPKT1024TO1518*/ + #define TXPKT1024TO1518_TXPKT1024TO1518 + #define TXPKT1024TO1518_TXPKT1024TO1518_OFFSET 0 + #define TXPKT1024TO1518_TXPKT1024TO1518_LEN 32 + #define TXPKT1024TO1518_TXPKT1024TO1518_DEFAULT 0x0 + +struct txpkt1024to1518 { + a_uint32_t txpkt1024to1518:32; +}; + +union txpkt1024to1518_u { + a_uint32_t val; + struct txpkt1024to1518 bf; +}; + +/*[register] TXPKT1519TOX*/ +#define TXPKT1519TOX +#define TXPKT1519TOX_ADDRESS 0xc8 +#define TXPKT1519TOX_NUM 6 +#define TXPKT1519TOX_INC 0x200 +#define TXPKT1519TOX_TYPE REG_TYPE_RO +#define TXPKT1519TOX_DEFAULT 0x0 + /*[field] TXPKT1519TOX*/ + #define TXPKT1519TOX_TXPKT1519TOX + #define TXPKT1519TOX_TXPKT1519TOX_OFFSET 0 + #define TXPKT1519TOX_TXPKT1519TOX_LEN 32 + #define TXPKT1519TOX_TXPKT1519TOX_DEFAULT 0x0 + +struct txpkt1519tox { + a_uint32_t txpkt1519tox:32; +}; + +union txpkt1519tox_u { + a_uint32_t val; + struct txpkt1519tox bf; +}; + +/*[register] TXBYTE_L*/ +#define TXBYTE_L +#define TXBYTE_L_ADDRESS 0xcc +#define TXBYTE_L_NUM 6 +#define TXBYTE_L_INC 0x200 +#define TXBYTE_L_TYPE REG_TYPE_RO +#define TXBYTE_L_DEFAULT 0x0 + /*[field] TXBYTE_L*/ + #define TXBYTE_L_TXBYTE_L + #define TXBYTE_L_TXBYTE_L_OFFSET 0 + #define TXBYTE_L_TXBYTE_L_LEN 32 + #define TXBYTE_L_TXBYTE_L_DEFAULT 0x0 + +struct txbyte_l { + a_uint32_t txbyte_l:32; +}; + +union txbyte_l_u { + a_uint32_t val; + struct txbyte_l bf; +}; + +/*[register] TXBYTE_H*/ +#define TXBYTE_H +#define TXBYTE_H_ADDRESS 0xd0 +#define TXBYTE_H_NUM 6 +#define TXBYTE_H_INC 0x200 +#define TXBYTE_H_TYPE REG_TYPE_RO +#define TXBYTE_H_DEFAULT 0x0 + /*[field] TXBYTE_H*/ + #define TXBYTE_H_TXBYTE_H + #define TXBYTE_H_TXBYTE_H_OFFSET 0 + #define TXBYTE_H_TXBYTE_H_LEN 32 + #define TXBYTE_H_TXBYTE_H_DEFAULT 0x0 + +struct txbyte_h { + a_uint32_t txbyte_h:32; +}; + +union txbyte_h_u { + a_uint32_t val; + struct txbyte_h bf; +}; + +/*[register] TXCOLLISIONS*/ +#define TXCOLLISIONS +#define TXCOLLISIONS_ADDRESS 0xd4 +#define TXCOLLISIONS_NUM 6 +#define TXCOLLISIONS_INC 0x200 +#define TXCOLLISIONS_TYPE REG_TYPE_RO +#define TXCOLLISIONS_DEFAULT 0x0 + /*[field] TXCOLLISIONS*/ + #define TXCOLLISIONS_TXCOLLISIONS + #define TXCOLLISIONS_TXCOLLISIONS_OFFSET 0 + #define TXCOLLISIONS_TXCOLLISIONS_LEN 32 + #define TXCOLLISIONS_TXCOLLISIONS_DEFAULT 0x0 + +struct txcollisions { + a_uint32_t txcollisions:32; +}; + +union txcollisions_u { + a_uint32_t val; + struct txcollisions bf; +}; + +/*[register] TXABORTCOL*/ +#define TXABORTCOL +#define TXABORTCOL_ADDRESS 0xd8 +#define TXABORTCOL_NUM 6 +#define TXABORTCOL_INC 0x200 +#define TXABORTCOL_TYPE REG_TYPE_RO +#define TXABORTCOL_DEFAULT 0x0 + /*[field] TXABORTCOL*/ + #define TXABORTCOL_TXABORTCOL + #define TXABORTCOL_TXABORTCOL_OFFSET 0 + #define TXABORTCOL_TXABORTCOL_LEN 32 + #define TXABORTCOL_TXABORTCOL_DEFAULT 0x0 + +struct txabortcol { + a_uint32_t txabortcol:32; +}; + +union txabortcol_u { + a_uint32_t val; + struct txabortcol bf; +}; + +/*[register] TXMULTICOL*/ +#define TXMULTICOL +#define TXMULTICOL_ADDRESS 0xdc +#define TXMULTICOL_NUM 6 +#define TXMULTICOL_INC 0x200 +#define TXMULTICOL_TYPE REG_TYPE_RO +#define TXMULTICOL_DEFAULT 0x0 + /*[field] TXMULTICOL*/ + #define TXMULTICOL_TXMULTICOL + #define TXMULTICOL_TXMULTICOL_OFFSET 0 + #define TXMULTICOL_TXMULTICOL_LEN 32 + #define TXMULTICOL_TXMULTICOL_DEFAULT 0x0 + +struct txmulticol { + a_uint32_t txmulticol:32; +}; + +union txmulticol_u { + a_uint32_t val; + struct txmulticol bf; +}; + +/*[register] TXSINGLECOL*/ +#define TXSINGLECOL +#define TXSINGLECOL_ADDRESS 0xe0 +#define TXSINGLECOL_NUM 6 +#define TXSINGLECOL_INC 0x200 +#define TXSINGLECOL_TYPE REG_TYPE_RO +#define TXSINGLECOL_DEFAULT 0x0 + /*[field] TXSINGLECOL*/ + #define TXSINGLECOL_TXSINGLECOL + #define TXSINGLECOL_TXSINGLECOL_OFFSET 0 + #define TXSINGLECOL_TXSINGLECOL_LEN 32 + #define TXSINGLECOL_TXSINGLECOL_DEFAULT 0x0 + +struct txsinglecol { + a_uint32_t txsinglecol:32; +}; + +union txsinglecol_u { + a_uint32_t val; + struct txsinglecol bf; +}; + +/*[register] TXEXCESSIVEDEFER*/ +#define TXEXCESSIVEDEFER +#define TXEXCESSIVEDEFER_ADDRESS 0xe4 +#define TXEXCESSIVEDEFER_NUM 6 +#define TXEXCESSIVEDEFER_INC 0x200 +#define TXEXCESSIVEDEFER_TYPE REG_TYPE_RO +#define TXEXCESSIVEDEFER_DEFAULT 0x0 + /*[field] TXEXCESSIVEDEFER*/ + #define TXEXCESSIVEDEFER_TXEXCESSIVEDEFER + #define TXEXCESSIVEDEFER_TXEXCESSIVEDEFER_OFFSET 0 + #define TXEXCESSIVEDEFER_TXEXCESSIVEDEFER_LEN 32 + #define TXEXCESSIVEDEFER_TXEXCESSIVEDEFER_DEFAULT 0x0 + +struct txexcessivedefer { + a_uint32_t txexcessivedefer:32; +}; + +union txexcessivedefer_u { + a_uint32_t val; + struct txexcessivedefer bf; +}; + +/*[register] TXDEFER*/ +#define TXDEFER +#define TXDEFER_ADDRESS 0xe8 +#define TXDEFER_NUM 6 +#define TXDEFER_INC 0x200 +#define TXDEFER_TYPE REG_TYPE_RO +#define TXDEFER_DEFAULT 0x0 + /*[field] TXDEFER*/ + #define TXDEFER_TXDEFER + #define TXDEFER_TXDEFER_OFFSET 0 + #define TXDEFER_TXDEFER_LEN 32 + #define TXDEFER_TXDEFER_DEFAULT 0x0 + +struct txdefer { + a_uint32_t txdefer:32; +}; + +union txdefer_u { + a_uint32_t val; + struct txdefer bf; +}; + +/*[register] TXLATECOL*/ +#define TXLATECOL +#define TXLATECOL_ADDRESS 0xec +#define TXLATECOL_NUM 6 +#define TXLATECOL_INC 0x200 +#define TXLATECOL_TYPE REG_TYPE_RO +#define TXLATECOL_DEFAULT 0x0 + /*[field] TXLATECOL*/ + #define TXLATECOL_TXLATECOL + #define TXLATECOL_TXLATECOL_OFFSET 0 + #define TXLATECOL_TXLATECOL_LEN 32 + #define TXLATECOL_TXLATECOL_DEFAULT 0x0 + +struct txlatecol { + a_uint32_t txlatecol:32; +}; + +union txlatecol_u { + a_uint32_t val; + struct txlatecol bf; +}; + +/*[register] TXUNI*/ +#define TXUNI +#define TXUNI_ADDRESS 0xf0 +#define TXUNI_NUM 6 +#define TXUNI_INC 0x200 +#define TXUNI_TYPE REG_TYPE_RO +#define TXUNI_DEFAULT 0x0 + /*[field] TXUNI*/ + #define TXUNI_TXUNI + #define TXUNI_TXUNI_OFFSET 0 + #define TXUNI_TXUNI_LEN 32 + #define TXUNI_TXUNI_DEFAULT 0x0 + +struct txuni { + a_uint32_t txuni:32; +}; + +union txuni_u { + a_uint32_t val; + struct txuni bf; +}; + + + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_mirror.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_mirror.h new file mode 100755 index 000000000..c8f3994f3 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_mirror.h @@ -0,0 +1,92 @@ +/* + * 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 + * @{ + */ +#ifndef _HPPE_MIRROR_H_ +#define _HPPE_MIRROR_H_ + +#define PORT_MIRROR_MAX_ENTRY 8 + +sw_error_t +hppe_mirror_analyzer_get( + a_uint32_t dev_id, + union mirror_analyzer_u *value); + +sw_error_t +hppe_mirror_analyzer_set( + a_uint32_t dev_id, + union mirror_analyzer_u *value); + +sw_error_t +hppe_port_mirror_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_mirror_u *value); + +sw_error_t +hppe_port_mirror_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_mirror_u *value); + +sw_error_t +hppe_mirror_analyzer_in_analyzer_port_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_mirror_analyzer_in_analyzer_port_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_mirror_analyzer_eg_analyzer_port_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_mirror_analyzer_eg_analyzer_port_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_mirror_in_mirr_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_mirror_in_mirr_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_mirror_eg_mirr_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_mirror_eg_mirr_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_mirror_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_mirror_reg.h new file mode 100755 index 000000000..45b69a7ce --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_mirror_reg.h @@ -0,0 +1,83 @@ +/* + * 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 + * @{ + */ +#ifndef HPPE_MIRROR_REG_H +#define HPPE_MIRROR_REG_H + +/*[register] MIRROR_ANALYZER*/ +#define MIRROR_ANALYZER +#define MIRROR_ANALYZER_ADDRESS 0x40 +#define MIRROR_ANALYZER_NUM 1 +#define MIRROR_ANALYZER_INC 0x4 +#define MIRROR_ANALYZER_TYPE REG_TYPE_RW +#define MIRROR_ANALYZER_DEFAULT 0x0 + /*[field] IN_ANALYZER_PORT*/ + #define MIRROR_ANALYZER_IN_ANALYZER_PORT + #define MIRROR_ANALYZER_IN_ANALYZER_PORT_OFFSET 0 + #define MIRROR_ANALYZER_IN_ANALYZER_PORT_LEN 6 + #define MIRROR_ANALYZER_IN_ANALYZER_PORT_DEFAULT 0x0 + /*[field] EG_ANALYZER_PORT*/ + #define MIRROR_ANALYZER_EG_ANALYZER_PORT + #define MIRROR_ANALYZER_EG_ANALYZER_PORT_OFFSET 8 + #define MIRROR_ANALYZER_EG_ANALYZER_PORT_LEN 6 + #define MIRROR_ANALYZER_EG_ANALYZER_PORT_DEFAULT 0x0 + +struct mirror_analyzer { + a_uint32_t in_analyzer_port:6; + a_uint32_t _reserved0:2; + a_uint32_t eg_analyzer_port:6; + a_uint32_t _reserved1:18; +}; + +union mirror_analyzer_u { + a_uint32_t val; + struct mirror_analyzer bf; +}; + +/*[register] PORT_MIRROR*/ +#define PORT_MIRROR +#define PORT_MIRROR_ADDRESS 0x800 +#define PORT_MIRROR_NUM 8 +#define PORT_MIRROR_INC 0x4 +#define PORT_MIRROR_TYPE REG_TYPE_RW +#define PORT_MIRROR_DEFAULT 0x0 + /*[field] IN_MIRR_EN*/ + #define PORT_MIRROR_IN_MIRR_EN + #define PORT_MIRROR_IN_MIRR_EN_OFFSET 0 + #define PORT_MIRROR_IN_MIRR_EN_LEN 1 + #define PORT_MIRROR_IN_MIRR_EN_DEFAULT 0x0 + /*[field] EG_MIRR_EN*/ + #define PORT_MIRROR_EG_MIRR_EN + #define PORT_MIRROR_EG_MIRR_EN_OFFSET 1 + #define PORT_MIRROR_EG_MIRR_EN_LEN 1 + #define PORT_MIRROR_EG_MIRR_EN_DEFAULT 0x0 + +struct port_mirror { + a_uint32_t in_mirr_en:1; + a_uint32_t eg_mirr_en:1; + a_uint32_t _reserved0:30; +}; + +union port_mirror_u { + a_uint32_t val; + struct port_mirror bf; +}; + + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_policer.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_policer.h new file mode 100755 index 000000000..92ca03675 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_policer.h @@ -0,0 +1,1173 @@ +/* + * 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 + * @{ + */ +#ifndef _HPPE_POLICER_H_ +#define _HPPE_POLICER_H_ + +#define METER_CMPST_LENGTH_REG_MAX_ENTRY 8 +#define IN_ACL_METER_CFG_TBL_MAX_ENTRY 512 +#define IN_ACL_METER_CRDT_TBL_MAX_ENTRY 512 +#define IN_PORT_METER_CFG_TBL_MAX_ENTRY 8 +#define IN_PORT_METER_CRDT_TBL_MAX_ENTRY 8 +#define IN_PORT_METER_CNT_TBL_MAX_ENTRY 24 +#define IN_ACL_METER_CNT_TBL_MAX_ENTRY 1536 +#define PC_GLOBAL_CNT_TBL_MAX_ENTRY 3 +#define DROP_CPU_CNT_TBL_MAX_ENTRY 1280 +#define CPU_CODE_CNT_TBL_MAX_ENTRY 256 +#define PORT_TX_DROP_CNT_TBL_MAX_ENTRY 8 +#define VP_TX_DROP_CNT_TBL_MAX_ENTRY 256 +#define VLAN_DEV_CNT_TBL_MAX_ENTRY 64 + + +sw_error_t +hppe_meter_cmpst_length_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + union meter_cmpst_length_reg_u *value); + +sw_error_t +hppe_meter_cmpst_length_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + union meter_cmpst_length_reg_u *value); + +sw_error_t +hppe_pc_drop_bypass_reg_get( + a_uint32_t dev_id, + union pc_drop_bypass_reg_u *value); + +sw_error_t +hppe_pc_drop_bypass_reg_set( + a_uint32_t dev_id, + union pc_drop_bypass_reg_u *value); + +sw_error_t +hppe_pc_spare_reg_get( + a_uint32_t dev_id, + union pc_spare_reg_u *value); + +sw_error_t +hppe_pc_spare_reg_set( + a_uint32_t dev_id, + union pc_spare_reg_u *value); + +sw_error_t +hppe_time_slot_reg_get( + a_uint32_t dev_id, + union time_slot_reg_u *value); + +sw_error_t +hppe_time_slot_reg_set( + a_uint32_t dev_id, + union time_slot_reg_u *value); + +sw_error_t +hppe_pc_dbg_addr_reg_get( + a_uint32_t dev_id, + union pc_dbg_addr_reg_u *value); + +sw_error_t +hppe_pc_dbg_addr_reg_set( + a_uint32_t dev_id, + union pc_dbg_addr_reg_u *value); + +sw_error_t +hppe_pc_dbg_data_reg_get( + a_uint32_t dev_id, + union pc_dbg_data_reg_u *value); + +sw_error_t +hppe_pc_dbg_data_reg_set( + a_uint32_t dev_id, + union pc_dbg_data_reg_u *value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union in_acl_meter_cfg_tbl_u *value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union in_acl_meter_cfg_tbl_u *value); + +sw_error_t +hppe_in_acl_meter_crdt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union in_acl_meter_crdt_tbl_u *value); + +sw_error_t +hppe_in_acl_meter_crdt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union in_acl_meter_crdt_tbl_u *value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union in_port_meter_cfg_tbl_u *value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union in_port_meter_cfg_tbl_u *value); + +sw_error_t +hppe_in_port_meter_crdt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union in_port_meter_crdt_tbl_u *value); + +sw_error_t +hppe_in_port_meter_crdt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union in_port_meter_crdt_tbl_u *value); + +sw_error_t +hppe_in_port_meter_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union in_port_meter_cnt_tbl_u *value); + +sw_error_t +hppe_in_port_meter_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union in_port_meter_cnt_tbl_u *value); + +sw_error_t +hppe_in_acl_meter_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union in_acl_meter_cnt_tbl_u *value); + +sw_error_t +hppe_in_acl_meter_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union in_acl_meter_cnt_tbl_u *value); + + +sw_error_t +hppe_pc_global_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union pc_global_cnt_tbl_u *value); + +sw_error_t +hppe_pc_global_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union pc_global_cnt_tbl_u *value); + +sw_error_t +hppe_drop_cpu_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union drop_cpu_cnt_tbl_u *value); + +sw_error_t +hppe_drop_cpu_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union drop_cpu_cnt_tbl_u *value); + +sw_error_t +hppe_port_tx_drop_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_tx_drop_cnt_tbl_u *value); + +sw_error_t +hppe_port_tx_drop_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_tx_drop_cnt_tbl_u *value); + +sw_error_t +hppe_vp_tx_drop_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union vp_tx_drop_cnt_tbl_u *value); + +sw_error_t +hppe_vp_tx_drop_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union vp_tx_drop_cnt_tbl_u *value); + +sw_error_t +hppe_vlan_dev_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union vlan_dev_cnt_tbl_u *value); + +sw_error_t +hppe_vlan_dev_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union vlan_dev_cnt_tbl_u *value); + +sw_error_t +hppe_meter_cmpst_length_reg_cmpst_length_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_meter_cmpst_length_reg_cmpst_length_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pc_drop_bypass_reg_drop_bypass_en_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_pc_drop_bypass_reg_drop_bypass_en_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_pc_spare_reg_spare_reg_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_pc_spare_reg_spare_reg_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_time_slot_reg_time_slot_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_time_slot_reg_time_slot_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_pc_dbg_addr_reg_dbg_addr_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_pc_dbg_addr_reg_dbg_addr_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_pc_dbg_data_reg_dbg_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_pc_dbg_data_reg_dbg_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_meter_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_meter_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_color_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_color_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_exceed_chg_pcp_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_exceed_chg_pcp_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_exceed_pri_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_exceed_pri_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_exceed_chg_pri_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_exceed_chg_pri_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_exceed_dp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_exceed_dp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_dp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_dp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_exceed_dei_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_exceed_dei_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_pri_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_pri_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_cbs_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_cbs_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_chg_dei_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_chg_dei_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_chg_pcp_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_chg_pcp_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_cir_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_cir_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_dei_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_dei_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_chg_pri_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_chg_pri_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_meter_unit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_meter_unit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_meter_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_meter_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_chg_dp_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_chg_dp_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_eir_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_eir_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_exceed_chg_dp_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_exceed_chg_dp_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_exceed_chg_dei_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_exceed_chg_dei_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_exceed_pcp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_exceed_pcp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_pcp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_pcp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_token_unit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_token_unit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_coupling_flag_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_coupling_flag_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_ebs_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_acl_meter_cfg_tbl_ebs_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_acl_meter_crdt_tbl_c_crdt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_acl_meter_crdt_tbl_c_crdt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_acl_meter_crdt_tbl_e_crdt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_acl_meter_crdt_tbl_e_crdt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_meter_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_meter_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_color_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_color_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_exceed_chg_pcp_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_exceed_chg_pcp_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_exceed_pri_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_exceed_pri_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_exceed_chg_pri_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_exceed_chg_pri_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_exceed_dp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_exceed_dp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_dp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_dp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_exceed_dei_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_exceed_dei_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_pri_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_pri_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_cbs_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_cbs_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_chg_dei_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_chg_dei_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_chg_pcp_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_chg_pcp_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_cir_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_cir_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_dei_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_dei_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_chg_pri_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_chg_pri_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_meter_unit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_meter_unit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_meter_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_meter_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_chg_dp_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_chg_dp_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_eir_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_eir_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_exceed_chg_dp_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_exceed_chg_dp_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_exceed_chg_dei_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_exceed_chg_dei_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_exceed_pcp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_exceed_pcp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_pcp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_pcp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_token_unit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_token_unit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_coupling_flag_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_coupling_flag_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_meter_flag_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_meter_flag_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_ebs_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_port_meter_cfg_tbl_ebs_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_port_meter_crdt_tbl_c_crdt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_port_meter_crdt_tbl_c_crdt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_port_meter_crdt_tbl_e_crdt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_port_meter_crdt_tbl_e_crdt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_port_meter_cnt_tbl_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_in_port_meter_cnt_tbl_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_in_port_meter_cnt_tbl_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_port_meter_cnt_tbl_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_acl_meter_cnt_tbl_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_in_acl_meter_cnt_tbl_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_in_acl_meter_cnt_tbl_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_acl_meter_cnt_tbl_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + + +sw_error_t +hppe_pc_global_cnt_tbl_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_pc_global_cnt_tbl_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_pc_global_cnt_tbl_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pc_global_cnt_tbl_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_drop_cpu_cnt_tbl_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_drop_cpu_cnt_tbl_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_drop_cpu_cnt_tbl_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_drop_cpu_cnt_tbl_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_tx_drop_cnt_tbl_tx_drop_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_port_tx_drop_cnt_tbl_tx_drop_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_port_tx_drop_cnt_tbl_tx_drop_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_tx_drop_cnt_tbl_tx_drop_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vp_tx_drop_cnt_tbl_tx_drop_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_vp_tx_drop_cnt_tbl_tx_drop_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_vp_tx_drop_cnt_tbl_tx_drop_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vp_tx_drop_cnt_tbl_tx_drop_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vlan_dev_cnt_tbl_rx_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_vlan_dev_cnt_tbl_rx_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_vlan_dev_cnt_tbl_rx_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vlan_dev_cnt_tbl_rx_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_policer_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_policer_reg.h new file mode 100755 index 000000000..bcd4ba439 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_policer_reg.h @@ -0,0 +1,795 @@ +/* + * 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 + * @{ + */ +#ifndef HPPE_POLICER_REG_H +#define HPPE_POLICER_REG_H + +/*[register] METER_CMPST_LENGTH_REG*/ +#define METER_CMPST_LENGTH_REG +#define METER_CMPST_LENGTH_REG_ADDRESS 0x0 +#define METER_CMPST_LENGTH_REG_NUM 8 +#define METER_CMPST_LENGTH_REG_INC 0x4 +#define METER_CMPST_LENGTH_REG_TYPE REG_TYPE_RW +#define METER_CMPST_LENGTH_REG_DEFAULT 0x0 + /*[field] CMPST_LENGTH*/ + #define METER_CMPST_LENGTH_REG_CMPST_LENGTH + #define METER_CMPST_LENGTH_REG_CMPST_LENGTH_OFFSET 0 + #define METER_CMPST_LENGTH_REG_CMPST_LENGTH_LEN 5 + #define METER_CMPST_LENGTH_REG_CMPST_LENGTH_DEFAULT 0x0 + +struct meter_cmpst_length_reg { + a_uint32_t cmpst_length:5; + a_uint32_t _reserved0:27; +}; + +union meter_cmpst_length_reg_u { + a_uint32_t val; + struct meter_cmpst_length_reg bf; +}; + +/*[register] PC_DROP_BYPASS_REG*/ +#define PC_DROP_BYPASS_REG +#define PC_DROP_BYPASS_REG_ADDRESS 0x20 +#define PC_DROP_BYPASS_REG_NUM 1 +#define PC_DROP_BYPASS_REG_INC 0x4 +#define PC_DROP_BYPASS_REG_TYPE REG_TYPE_RW +#define PC_DROP_BYPASS_REG_DEFAULT 0x0 + /*[field] DROP_BYPASS_EN*/ + #define PC_DROP_BYPASS_REG_DROP_BYPASS_EN + #define PC_DROP_BYPASS_REG_DROP_BYPASS_EN_OFFSET 0 + #define PC_DROP_BYPASS_REG_DROP_BYPASS_EN_LEN 1 + #define PC_DROP_BYPASS_REG_DROP_BYPASS_EN_DEFAULT 0x0 + +struct pc_drop_bypass_reg { + a_uint32_t drop_bypass_en:1; + a_uint32_t _reserved0:31; +}; + +union pc_drop_bypass_reg_u { + a_uint32_t val; + struct pc_drop_bypass_reg bf; +}; + +/*[register] PC_SPARE_REG*/ +#define PC_SPARE_REG +#define PC_SPARE_REG_ADDRESS 0x30 +#define PC_SPARE_REG_NUM 1 +#define PC_SPARE_REG_INC 0x4 +#define PC_SPARE_REG_TYPE REG_TYPE_RW +#define PC_SPARE_REG_DEFAULT 0x0 + /*[field] SPARE_REG*/ + #define PC_SPARE_REG_SPARE_REG + #define PC_SPARE_REG_SPARE_REG_OFFSET 0 + #define PC_SPARE_REG_SPARE_REG_LEN 32 + #define PC_SPARE_REG_SPARE_REG_DEFAULT 0x0 + +struct pc_spare_reg { + a_uint32_t spare_reg:32; +}; + +union pc_spare_reg_u { + a_uint32_t val; + struct pc_spare_reg bf; +}; + +/*[register] TIME_SLOT_REG*/ +#define TIME_SLOT_REG +#define TIME_SLOT_REG_ADDRESS 0x40 +#define TIME_SLOT_REG_NUM 1 +#define TIME_SLOT_REG_INC 0x4 +#define TIME_SLOT_REG_TYPE REG_TYPE_RW +#define TIME_SLOT_REG_DEFAULT 0x0 + /*[field] TIME_SLOT*/ + #define TIME_SLOT_REG_TIME_SLOT + #define TIME_SLOT_REG_TIME_SLOT_OFFSET 0 + #define TIME_SLOT_REG_TIME_SLOT_LEN 10 + #define TIME_SLOT_REG_TIME_SLOT_DEFAULT 0x0 + +struct time_slot_reg { + a_uint32_t time_slot:10; + a_uint32_t _reserved0:22; +}; + +union time_slot_reg_u { + a_uint32_t val; + struct time_slot_reg bf; +}; + +/*[register] PC_DBG_ADDR_REG*/ +#define PC_DBG_ADDR_REG +#define PC_DBG_ADDR_REG_ADDRESS 0x80 +#define PC_DBG_ADDR_REG_NUM 1 +#define PC_DBG_ADDR_REG_INC 0x4 +#define PC_DBG_ADDR_REG_TYPE REG_TYPE_RW +#define PC_DBG_ADDR_REG_DEFAULT 0x0 + /*[field] DBG_ADDR*/ + #define PC_DBG_ADDR_REG_DBG_ADDR + #define PC_DBG_ADDR_REG_DBG_ADDR_OFFSET 24 + #define PC_DBG_ADDR_REG_DBG_ADDR_LEN 8 + #define PC_DBG_ADDR_REG_DBG_ADDR_DEFAULT 0x0 + +struct pc_dbg_addr_reg { + a_uint32_t dbg_addr:8; +}; + +union pc_dbg_addr_reg_u { + a_uint32_t val; + struct pc_dbg_addr_reg bf; +}; + +/*[register] PC_DBG_DATA_REG*/ +#define PC_DBG_DATA_REG +#define PC_DBG_DATA_REG_ADDRESS 0x84 +#define PC_DBG_DATA_REG_NUM 1 +#define PC_DBG_DATA_REG_INC 0x4 +#define PC_DBG_DATA_REG_TYPE REG_TYPE_RO +#define PC_DBG_DATA_REG_DEFAULT 0x0 + /*[field] DBG_DATA*/ + #define PC_DBG_DATA_REG_DBG_DATA + #define PC_DBG_DATA_REG_DBG_DATA_OFFSET 0 + #define PC_DBG_DATA_REG_DBG_DATA_LEN 32 + #define PC_DBG_DATA_REG_DBG_DATA_DEFAULT 0x0 + +struct pc_dbg_data_reg { + a_uint32_t dbg_data:32; +}; + +union pc_dbg_data_reg_u { + a_uint32_t val; + struct pc_dbg_data_reg bf; +}; + +/*[table] IN_ACL_METER_CFG_TBL*/ +#define IN_ACL_METER_CFG_TBL +#define IN_ACL_METER_CFG_TBL_ADDRESS 0x4000 +#define IN_ACL_METER_CFG_TBL_NUM 512 +#define IN_ACL_METER_CFG_TBL_INC 0x10 +#define IN_ACL_METER_CFG_TBL_TYPE REG_TYPE_RW +#define IN_ACL_METER_CFG_TBL_DEFAULT 0x0 + /*[field] METER_EN*/ + #define IN_ACL_METER_CFG_TBL_METER_EN + #define IN_ACL_METER_CFG_TBL_METER_EN_OFFSET 0 + #define IN_ACL_METER_CFG_TBL_METER_EN_LEN 1 + #define IN_ACL_METER_CFG_TBL_METER_EN_DEFAULT 0x0 + /*[field] COLOR_MODE*/ + #define IN_ACL_METER_CFG_TBL_COLOR_MODE + #define IN_ACL_METER_CFG_TBL_COLOR_MODE_OFFSET 1 + #define IN_ACL_METER_CFG_TBL_COLOR_MODE_LEN 1 + #define IN_ACL_METER_CFG_TBL_COLOR_MODE_DEFAULT 0x0 + /*[field] COUPLING_FLAG*/ + #define IN_ACL_METER_CFG_TBL_COUPLING_FLAG + #define IN_ACL_METER_CFG_TBL_COUPLING_FLAG_OFFSET 2 + #define IN_ACL_METER_CFG_TBL_COUPLING_FLAG_LEN 1 + #define IN_ACL_METER_CFG_TBL_COUPLING_FLAG_DEFAULT 0x0 + /*[field] METER_MODE*/ + #define IN_ACL_METER_CFG_TBL_METER_MODE + #define IN_ACL_METER_CFG_TBL_METER_MODE_OFFSET 3 + #define IN_ACL_METER_CFG_TBL_METER_MODE_LEN 1 + #define IN_ACL_METER_CFG_TBL_METER_MODE_DEFAULT 0x0 + /*[field] TOKEN_UNIT*/ + #define IN_ACL_METER_CFG_TBL_TOKEN_UNIT + #define IN_ACL_METER_CFG_TBL_TOKEN_UNIT_OFFSET 4 + #define IN_ACL_METER_CFG_TBL_TOKEN_UNIT_LEN 3 + #define IN_ACL_METER_CFG_TBL_TOKEN_UNIT_DEFAULT 0x0 + /*[field] METER_UNIT*/ + #define IN_ACL_METER_CFG_TBL_METER_UNIT + #define IN_ACL_METER_CFG_TBL_METER_UNIT_OFFSET 7 + #define IN_ACL_METER_CFG_TBL_METER_UNIT_LEN 1 + #define IN_ACL_METER_CFG_TBL_METER_UNIT_DEFAULT 0x0 + /*[field] CBS*/ + #define IN_ACL_METER_CFG_TBL_CBS + #define IN_ACL_METER_CFG_TBL_CBS_OFFSET 8 + #define IN_ACL_METER_CFG_TBL_CBS_LEN 16 + #define IN_ACL_METER_CFG_TBL_CBS_DEFAULT 0x0 + /*[field] CIR*/ + #define IN_ACL_METER_CFG_TBL_CIR + #define IN_ACL_METER_CFG_TBL_CIR_OFFSET 24 + #define IN_ACL_METER_CFG_TBL_CIR_LEN 18 + #define IN_ACL_METER_CFG_TBL_CIR_DEFAULT 0x0 + /*[field] EBS*/ + #define IN_ACL_METER_CFG_TBL_EBS + #define IN_ACL_METER_CFG_TBL_EBS_OFFSET 42 + #define IN_ACL_METER_CFG_TBL_EBS_LEN 16 + #define IN_ACL_METER_CFG_TBL_EBS_DEFAULT 0x0 + /*[field] EIR*/ + #define IN_ACL_METER_CFG_TBL_EIR + #define IN_ACL_METER_CFG_TBL_EIR_OFFSET 58 + #define IN_ACL_METER_CFG_TBL_EIR_LEN 18 + #define IN_ACL_METER_CFG_TBL_EIR_DEFAULT 0x0 + /*[field] EXCEED_CHG_PRI_CMD*/ + #define IN_ACL_METER_CFG_TBL_EXCEED_CHG_PRI_CMD + #define IN_ACL_METER_CFG_TBL_EXCEED_CHG_PRI_CMD_OFFSET 76 + #define IN_ACL_METER_CFG_TBL_EXCEED_CHG_PRI_CMD_LEN 1 + #define IN_ACL_METER_CFG_TBL_EXCEED_CHG_PRI_CMD_DEFAULT 0x0 + /*[field] EXCEED_CHG_DP_CMD*/ + #define IN_ACL_METER_CFG_TBL_EXCEED_CHG_DP_CMD + #define IN_ACL_METER_CFG_TBL_EXCEED_CHG_DP_CMD_OFFSET 77 + #define IN_ACL_METER_CFG_TBL_EXCEED_CHG_DP_CMD_LEN 1 + #define IN_ACL_METER_CFG_TBL_EXCEED_CHG_DP_CMD_DEFAULT 0x0 + /*[field] EXCEED_CHG_PCP_CMD*/ + #define IN_ACL_METER_CFG_TBL_EXCEED_CHG_PCP_CMD + #define IN_ACL_METER_CFG_TBL_EXCEED_CHG_PCP_CMD_OFFSET 78 + #define IN_ACL_METER_CFG_TBL_EXCEED_CHG_PCP_CMD_LEN 1 + #define IN_ACL_METER_CFG_TBL_EXCEED_CHG_PCP_CMD_DEFAULT 0x0 + /*[field] EXCEED_CHG_DEI_CMD*/ + #define IN_ACL_METER_CFG_TBL_EXCEED_CHG_DEI_CMD + #define IN_ACL_METER_CFG_TBL_EXCEED_CHG_DEI_CMD_OFFSET 79 + #define IN_ACL_METER_CFG_TBL_EXCEED_CHG_DEI_CMD_LEN 1 + #define IN_ACL_METER_CFG_TBL_EXCEED_CHG_DEI_CMD_DEFAULT 0x0 + /*[field] EXCEED_PRI*/ + #define IN_ACL_METER_CFG_TBL_EXCEED_PRI + #define IN_ACL_METER_CFG_TBL_EXCEED_PRI_OFFSET 80 + #define IN_ACL_METER_CFG_TBL_EXCEED_PRI_LEN 4 + #define IN_ACL_METER_CFG_TBL_EXCEED_PRI_DEFAULT 0x0 + /*[field] EXCEED_DP*/ + #define IN_ACL_METER_CFG_TBL_EXCEED_DP + #define IN_ACL_METER_CFG_TBL_EXCEED_DP_OFFSET 84 + #define IN_ACL_METER_CFG_TBL_EXCEED_DP_LEN 2 + #define IN_ACL_METER_CFG_TBL_EXCEED_DP_DEFAULT 0x0 + /*[field] EXCEED_PCP*/ + #define IN_ACL_METER_CFG_TBL_EXCEED_PCP + #define IN_ACL_METER_CFG_TBL_EXCEED_PCP_OFFSET 86 + #define IN_ACL_METER_CFG_TBL_EXCEED_PCP_LEN 3 + #define IN_ACL_METER_CFG_TBL_EXCEED_PCP_DEFAULT 0x0 + /*[field] EXCEED_DEI*/ + #define IN_ACL_METER_CFG_TBL_EXCEED_DEI + #define IN_ACL_METER_CFG_TBL_EXCEED_DEI_OFFSET 89 + #define IN_ACL_METER_CFG_TBL_EXCEED_DEI_LEN 1 + #define IN_ACL_METER_CFG_TBL_EXCEED_DEI_DEFAULT 0x0 + /*[field] VIOLATE_CMD*/ + #define IN_ACL_METER_CFG_TBL_VIOLATE_CMD + #define IN_ACL_METER_CFG_TBL_VIOLATE_CMD_OFFSET 90 + #define IN_ACL_METER_CFG_TBL_VIOLATE_CMD_LEN 1 + #define IN_ACL_METER_CFG_TBL_VIOLATE_CMD_DEFAULT 0x0 + /*[field] VIOLATE_CHG_PRI_CMD*/ + #define IN_ACL_METER_CFG_TBL_VIOLATE_CHG_PRI_CMD + #define IN_ACL_METER_CFG_TBL_VIOLATE_CHG_PRI_CMD_OFFSET 91 + #define IN_ACL_METER_CFG_TBL_VIOLATE_CHG_PRI_CMD_LEN 1 + #define IN_ACL_METER_CFG_TBL_VIOLATE_CHG_PRI_CMD_DEFAULT 0x0 + /*[field] VIOLATE_CHG_DP_CMD*/ + #define IN_ACL_METER_CFG_TBL_VIOLATE_CHG_DP_CMD + #define IN_ACL_METER_CFG_TBL_VIOLATE_CHG_DP_CMD_OFFSET 92 + #define IN_ACL_METER_CFG_TBL_VIOLATE_CHG_DP_CMD_LEN 1 + #define IN_ACL_METER_CFG_TBL_VIOLATE_CHG_DP_CMD_DEFAULT 0x0 + /*[field] VIOLATE_CHG_PCP_CMD*/ + #define IN_ACL_METER_CFG_TBL_VIOLATE_CHG_PCP_CMD + #define IN_ACL_METER_CFG_TBL_VIOLATE_CHG_PCP_CMD_OFFSET 93 + #define IN_ACL_METER_CFG_TBL_VIOLATE_CHG_PCP_CMD_LEN 1 + #define IN_ACL_METER_CFG_TBL_VIOLATE_CHG_PCP_CMD_DEFAULT 0x0 + /*[field] VIOLATE_CHG_DEI_CMD*/ + #define IN_ACL_METER_CFG_TBL_VIOLATE_CHG_DEI_CMD + #define IN_ACL_METER_CFG_TBL_VIOLATE_CHG_DEI_CMD_OFFSET 94 + #define IN_ACL_METER_CFG_TBL_VIOLATE_CHG_DEI_CMD_LEN 1 + #define IN_ACL_METER_CFG_TBL_VIOLATE_CHG_DEI_CMD_DEFAULT 0x0 + /*[field] VIOLATE_PRI*/ + #define IN_ACL_METER_CFG_TBL_VIOLATE_PRI + #define IN_ACL_METER_CFG_TBL_VIOLATE_PRI_OFFSET 95 + #define IN_ACL_METER_CFG_TBL_VIOLATE_PRI_LEN 4 + #define IN_ACL_METER_CFG_TBL_VIOLATE_PRI_DEFAULT 0x0 + /*[field] VIOLATE_DP*/ + #define IN_ACL_METER_CFG_TBL_VIOLATE_DP + #define IN_ACL_METER_CFG_TBL_VIOLATE_DP_OFFSET 99 + #define IN_ACL_METER_CFG_TBL_VIOLATE_DP_LEN 2 + #define IN_ACL_METER_CFG_TBL_VIOLATE_DP_DEFAULT 0x0 + /*[field] VIOLATE_PCP*/ + #define IN_ACL_METER_CFG_TBL_VIOLATE_PCP + #define IN_ACL_METER_CFG_TBL_VIOLATE_PCP_OFFSET 101 + #define IN_ACL_METER_CFG_TBL_VIOLATE_PCP_LEN 3 + #define IN_ACL_METER_CFG_TBL_VIOLATE_PCP_DEFAULT 0x0 + /*[field] VIOLATE_DEI*/ + #define IN_ACL_METER_CFG_TBL_VIOLATE_DEI + #define IN_ACL_METER_CFG_TBL_VIOLATE_DEI_OFFSET 104 + #define IN_ACL_METER_CFG_TBL_VIOLATE_DEI_LEN 1 + #define IN_ACL_METER_CFG_TBL_VIOLATE_DEI_DEFAULT 0x0 + +struct in_acl_meter_cfg_tbl { + a_uint32_t meter_en:1; + a_uint32_t color_mode:1; + a_uint32_t coupling_flag:1; + a_uint32_t meter_mode:1; + a_uint32_t token_unit:3; + a_uint32_t meter_unit:1; + a_uint32_t cbs:16; + a_uint32_t cir_0:8; + a_uint32_t cir_1:10; + a_uint32_t ebs:16; + a_uint32_t eir_0:6; + a_uint32_t eir_1:12; + a_uint32_t exceed_chg_pri_cmd:1; + a_uint32_t exceed_chg_dp_cmd:1; + a_uint32_t exceed_chg_pcp_cmd:1; + a_uint32_t exceed_chg_dei_cmd:1; + a_uint32_t exceed_pri:4; + a_uint32_t exceed_dp:2; + a_uint32_t exceed_pcp:3; + a_uint32_t exceed_dei:1; + a_uint32_t violate_cmd:1; + a_uint32_t violate_chg_pri_cmd:1; + a_uint32_t violate_chg_dp_cmd:1; + a_uint32_t violate_chg_pcp_cmd:1; + a_uint32_t violate_chg_dei_cmd:1; + a_uint32_t violate_pri_0:1; + a_uint32_t violate_pri_1:3; + a_uint32_t violate_dp:2; + a_uint32_t violate_pcp:3; + a_uint32_t violate_dei:1; + a_uint32_t _reserved0:23; +}; + +union in_acl_meter_cfg_tbl_u { + a_uint32_t val[4]; + struct in_acl_meter_cfg_tbl bf; +}; + +/*[table] IN_ACL_METER_CRDT_TBL*/ +#define IN_ACL_METER_CRDT_TBL +#define IN_ACL_METER_CRDT_TBL_ADDRESS 0x8000 +#define IN_ACL_METER_CRDT_TBL_NUM 512 +#define IN_ACL_METER_CRDT_TBL_INC 0x10 +#define IN_ACL_METER_CRDT_TBL_TYPE REG_TYPE_RW +#define IN_ACL_METER_CRDT_TBL_DEFAULT 0x0 + /*[field] C_CRDT*/ + #define IN_ACL_METER_CRDT_TBL_C_CRDT + #define IN_ACL_METER_CRDT_TBL_C_CRDT_OFFSET 0 + #define IN_ACL_METER_CRDT_TBL_C_CRDT_LEN 32 + #define IN_ACL_METER_CRDT_TBL_C_CRDT_DEFAULT 0x0 + /*[field] E_CRDT*/ + #define IN_ACL_METER_CRDT_TBL_E_CRDT + #define IN_ACL_METER_CRDT_TBL_E_CRDT_OFFSET 32 + #define IN_ACL_METER_CRDT_TBL_E_CRDT_LEN 32 + #define IN_ACL_METER_CRDT_TBL_E_CRDT_DEFAULT 0x0 + +struct in_acl_meter_crdt_tbl { + a_uint32_t c_crdt:32; + a_uint32_t e_crdt:32; +}; + +union in_acl_meter_crdt_tbl_u { + a_uint32_t val[2]; + struct in_acl_meter_crdt_tbl bf; +}; + +/*[table] IN_PORT_METER_CFG_TBL*/ +#define IN_PORT_METER_CFG_TBL +#define IN_PORT_METER_CFG_TBL_ADDRESS 0xc000 +#define IN_PORT_METER_CFG_TBL_NUM 8 +#define IN_PORT_METER_CFG_TBL_INC 0x10 +#define IN_PORT_METER_CFG_TBL_TYPE REG_TYPE_RW +#define IN_PORT_METER_CFG_TBL_DEFAULT 0x0 + /*[field] METER_EN*/ + #define IN_PORT_METER_CFG_TBL_METER_EN + #define IN_PORT_METER_CFG_TBL_METER_EN_OFFSET 0 + #define IN_PORT_METER_CFG_TBL_METER_EN_LEN 1 + #define IN_PORT_METER_CFG_TBL_METER_EN_DEFAULT 0x0 + /*[field] COLOR_MODE*/ + #define IN_PORT_METER_CFG_TBL_COLOR_MODE + #define IN_PORT_METER_CFG_TBL_COLOR_MODE_OFFSET 1 + #define IN_PORT_METER_CFG_TBL_COLOR_MODE_LEN 1 + #define IN_PORT_METER_CFG_TBL_COLOR_MODE_DEFAULT 0x0 + /*[field] METER_FLAG*/ + #define IN_PORT_METER_CFG_TBL_METER_FLAG + #define IN_PORT_METER_CFG_TBL_METER_FLAG_OFFSET 2 + #define IN_PORT_METER_CFG_TBL_METER_FLAG_LEN 5 + #define IN_PORT_METER_CFG_TBL_METER_FLAG_DEFAULT 0x0 + /*[field] COUPLING_FLAG*/ + #define IN_PORT_METER_CFG_TBL_COUPLING_FLAG + #define IN_PORT_METER_CFG_TBL_COUPLING_FLAG_OFFSET 7 + #define IN_PORT_METER_CFG_TBL_COUPLING_FLAG_LEN 1 + #define IN_PORT_METER_CFG_TBL_COUPLING_FLAG_DEFAULT 0x0 + /*[field] METER_MODE*/ + #define IN_PORT_METER_CFG_TBL_METER_MODE + #define IN_PORT_METER_CFG_TBL_METER_MODE_OFFSET 8 + #define IN_PORT_METER_CFG_TBL_METER_MODE_LEN 1 + #define IN_PORT_METER_CFG_TBL_METER_MODE_DEFAULT 0x0 + /*[field] TOKEN_UNIT*/ + #define IN_PORT_METER_CFG_TBL_TOKEN_UNIT + #define IN_PORT_METER_CFG_TBL_TOKEN_UNIT_OFFSET 9 + #define IN_PORT_METER_CFG_TBL_TOKEN_UNIT_LEN 3 + #define IN_PORT_METER_CFG_TBL_TOKEN_UNIT_DEFAULT 0x0 + /*[field] METER_UNIT*/ + #define IN_PORT_METER_CFG_TBL_METER_UNIT + #define IN_PORT_METER_CFG_TBL_METER_UNIT_OFFSET 12 + #define IN_PORT_METER_CFG_TBL_METER_UNIT_LEN 1 + #define IN_PORT_METER_CFG_TBL_METER_UNIT_DEFAULT 0x0 + /*[field] CBS*/ + #define IN_PORT_METER_CFG_TBL_CBS + #define IN_PORT_METER_CFG_TBL_CBS_OFFSET 13 + #define IN_PORT_METER_CFG_TBL_CBS_LEN 16 + #define IN_PORT_METER_CFG_TBL_CBS_DEFAULT 0x0 + /*[field] CIR*/ + #define IN_PORT_METER_CFG_TBL_CIR + #define IN_PORT_METER_CFG_TBL_CIR_OFFSET 29 + #define IN_PORT_METER_CFG_TBL_CIR_LEN 18 + #define IN_PORT_METER_CFG_TBL_CIR_DEFAULT 0x0 + /*[field] EBS*/ + #define IN_PORT_METER_CFG_TBL_EBS + #define IN_PORT_METER_CFG_TBL_EBS_OFFSET 47 + #define IN_PORT_METER_CFG_TBL_EBS_LEN 16 + #define IN_PORT_METER_CFG_TBL_EBS_DEFAULT 0x0 + /*[field] EIR*/ + #define IN_PORT_METER_CFG_TBL_EIR + #define IN_PORT_METER_CFG_TBL_EIR_OFFSET 63 + #define IN_PORT_METER_CFG_TBL_EIR_LEN 18 + #define IN_PORT_METER_CFG_TBL_EIR_DEFAULT 0x0 + /*[field] EXCEED_CHG_PRI_CMD*/ + #define IN_PORT_METER_CFG_TBL_EXCEED_CHG_PRI_CMD + #define IN_PORT_METER_CFG_TBL_EXCEED_CHG_PRI_CMD_OFFSET 81 + #define IN_PORT_METER_CFG_TBL_EXCEED_CHG_PRI_CMD_LEN 1 + #define IN_PORT_METER_CFG_TBL_EXCEED_CHG_PRI_CMD_DEFAULT 0x0 + /*[field] EXCEED_CHG_DP_CMD*/ + #define IN_PORT_METER_CFG_TBL_EXCEED_CHG_DP_CMD + #define IN_PORT_METER_CFG_TBL_EXCEED_CHG_DP_CMD_OFFSET 82 + #define IN_PORT_METER_CFG_TBL_EXCEED_CHG_DP_CMD_LEN 1 + #define IN_PORT_METER_CFG_TBL_EXCEED_CHG_DP_CMD_DEFAULT 0x0 + /*[field] EXCEED_CHG_PCP_CMD*/ + #define IN_PORT_METER_CFG_TBL_EXCEED_CHG_PCP_CMD + #define IN_PORT_METER_CFG_TBL_EXCEED_CHG_PCP_CMD_OFFSET 83 + #define IN_PORT_METER_CFG_TBL_EXCEED_CHG_PCP_CMD_LEN 1 + #define IN_PORT_METER_CFG_TBL_EXCEED_CHG_PCP_CMD_DEFAULT 0x0 + /*[field] EXCEED_CHG_DEI_CMD*/ + #define IN_PORT_METER_CFG_TBL_EXCEED_CHG_DEI_CMD + #define IN_PORT_METER_CFG_TBL_EXCEED_CHG_DEI_CMD_OFFSET 84 + #define IN_PORT_METER_CFG_TBL_EXCEED_CHG_DEI_CMD_LEN 1 + #define IN_PORT_METER_CFG_TBL_EXCEED_CHG_DEI_CMD_DEFAULT 0x0 + /*[field] EXCEED_PRI*/ + #define IN_PORT_METER_CFG_TBL_EXCEED_PRI + #define IN_PORT_METER_CFG_TBL_EXCEED_PRI_OFFSET 85 + #define IN_PORT_METER_CFG_TBL_EXCEED_PRI_LEN 4 + #define IN_PORT_METER_CFG_TBL_EXCEED_PRI_DEFAULT 0x0 + /*[field] EXCEED_DP*/ + #define IN_PORT_METER_CFG_TBL_EXCEED_DP + #define IN_PORT_METER_CFG_TBL_EXCEED_DP_OFFSET 89 + #define IN_PORT_METER_CFG_TBL_EXCEED_DP_LEN 2 + #define IN_PORT_METER_CFG_TBL_EXCEED_DP_DEFAULT 0x0 + /*[field] EXCEED_PCP*/ + #define IN_PORT_METER_CFG_TBL_EXCEED_PCP + #define IN_PORT_METER_CFG_TBL_EXCEED_PCP_OFFSET 91 + #define IN_PORT_METER_CFG_TBL_EXCEED_PCP_LEN 3 + #define IN_PORT_METER_CFG_TBL_EXCEED_PCP_DEFAULT 0x0 + /*[field] EXCEED_DEI*/ + #define IN_PORT_METER_CFG_TBL_EXCEED_DEI + #define IN_PORT_METER_CFG_TBL_EXCEED_DEI_OFFSET 94 + #define IN_PORT_METER_CFG_TBL_EXCEED_DEI_LEN 1 + #define IN_PORT_METER_CFG_TBL_EXCEED_DEI_DEFAULT 0x0 + /*[field] VIOLATE_CMD*/ + #define IN_PORT_METER_CFG_TBL_VIOLATE_CMD + #define IN_PORT_METER_CFG_TBL_VIOLATE_CMD_OFFSET 95 + #define IN_PORT_METER_CFG_TBL_VIOLATE_CMD_LEN 1 + #define IN_PORT_METER_CFG_TBL_VIOLATE_CMD_DEFAULT 0x0 + /*[field] VIOLATE_CHG_PRI_CMD*/ + #define IN_PORT_METER_CFG_TBL_VIOLATE_CHG_PRI_CMD + #define IN_PORT_METER_CFG_TBL_VIOLATE_CHG_PRI_CMD_OFFSET 96 + #define IN_PORT_METER_CFG_TBL_VIOLATE_CHG_PRI_CMD_LEN 1 + #define IN_PORT_METER_CFG_TBL_VIOLATE_CHG_PRI_CMD_DEFAULT 0x0 + /*[field] VIOLATE_CHG_DP_CMD*/ + #define IN_PORT_METER_CFG_TBL_VIOLATE_CHG_DP_CMD + #define IN_PORT_METER_CFG_TBL_VIOLATE_CHG_DP_CMD_OFFSET 97 + #define IN_PORT_METER_CFG_TBL_VIOLATE_CHG_DP_CMD_LEN 1 + #define IN_PORT_METER_CFG_TBL_VIOLATE_CHG_DP_CMD_DEFAULT 0x0 + /*[field] VIOLATE_CHG_PCP_CMD*/ + #define IN_PORT_METER_CFG_TBL_VIOLATE_CHG_PCP_CMD + #define IN_PORT_METER_CFG_TBL_VIOLATE_CHG_PCP_CMD_OFFSET 98 + #define IN_PORT_METER_CFG_TBL_VIOLATE_CHG_PCP_CMD_LEN 1 + #define IN_PORT_METER_CFG_TBL_VIOLATE_CHG_PCP_CMD_DEFAULT 0x0 + /*[field] VIOLATE_CHG_DEI_CMD*/ + #define IN_PORT_METER_CFG_TBL_VIOLATE_CHG_DEI_CMD + #define IN_PORT_METER_CFG_TBL_VIOLATE_CHG_DEI_CMD_OFFSET 99 + #define IN_PORT_METER_CFG_TBL_VIOLATE_CHG_DEI_CMD_LEN 1 + #define IN_PORT_METER_CFG_TBL_VIOLATE_CHG_DEI_CMD_DEFAULT 0x0 + /*[field] VIOLATE_PRI*/ + #define IN_PORT_METER_CFG_TBL_VIOLATE_PRI + #define IN_PORT_METER_CFG_TBL_VIOLATE_PRI_OFFSET 100 + #define IN_PORT_METER_CFG_TBL_VIOLATE_PRI_LEN 4 + #define IN_PORT_METER_CFG_TBL_VIOLATE_PRI_DEFAULT 0x0 + /*[field] VIOLATE_DP*/ + #define IN_PORT_METER_CFG_TBL_VIOLATE_DP + #define IN_PORT_METER_CFG_TBL_VIOLATE_DP_OFFSET 104 + #define IN_PORT_METER_CFG_TBL_VIOLATE_DP_LEN 2 + #define IN_PORT_METER_CFG_TBL_VIOLATE_DP_DEFAULT 0x0 + /*[field] VIOLATE_PCP*/ + #define IN_PORT_METER_CFG_TBL_VIOLATE_PCP + #define IN_PORT_METER_CFG_TBL_VIOLATE_PCP_OFFSET 106 + #define IN_PORT_METER_CFG_TBL_VIOLATE_PCP_LEN 3 + #define IN_PORT_METER_CFG_TBL_VIOLATE_PCP_DEFAULT 0x0 + /*[field] VIOLATE_DEI*/ + #define IN_PORT_METER_CFG_TBL_VIOLATE_DEI + #define IN_PORT_METER_CFG_TBL_VIOLATE_DEI_OFFSET 109 + #define IN_PORT_METER_CFG_TBL_VIOLATE_DEI_LEN 1 + #define IN_PORT_METER_CFG_TBL_VIOLATE_DEI_DEFAULT 0x0 + +struct in_port_meter_cfg_tbl { + a_uint32_t meter_en:1; + a_uint32_t color_mode:1; + a_uint32_t meter_flag:5; + a_uint32_t coupling_flag:1; + a_uint32_t meter_mode:1; + a_uint32_t token_unit:3; + a_uint32_t meter_unit:1; + a_uint32_t cbs:16; + a_uint32_t cir_0:3; + a_uint32_t cir_1:15; + a_uint32_t ebs:16; + a_uint32_t eir_0:1; + a_uint32_t eir_1:17; + a_uint32_t exceed_chg_pri_cmd:1; + a_uint32_t exceed_chg_dp_cmd:1; + a_uint32_t exceed_chg_pcp_cmd:1; + a_uint32_t exceed_chg_dei_cmd:1; + a_uint32_t exceed_pri:4; + a_uint32_t exceed_dp:2; + a_uint32_t exceed_pcp:3; + a_uint32_t exceed_dei:1; + a_uint32_t violate_cmd:1; + a_uint32_t violate_chg_pri_cmd:1; + a_uint32_t violate_chg_dp_cmd:1; + a_uint32_t violate_chg_pcp_cmd:1; + a_uint32_t violate_chg_dei_cmd:1; + a_uint32_t violate_pri:4; + a_uint32_t violate_dp:2; + a_uint32_t violate_pcp:3; + a_uint32_t violate_dei:1; + a_uint32_t _reserved0:18; +}; + +union in_port_meter_cfg_tbl_u { + a_uint32_t val[4]; + struct in_port_meter_cfg_tbl bf; +}; + +/*[table] IN_PORT_METER_CRDT_TBL*/ +#define IN_PORT_METER_CRDT_TBL +#define IN_PORT_METER_CRDT_TBL_ADDRESS 0xd000 +#define IN_PORT_METER_CRDT_TBL_NUM 8 +#define IN_PORT_METER_CRDT_TBL_INC 0x10 +#define IN_PORT_METER_CRDT_TBL_TYPE REG_TYPE_RW +#define IN_PORT_METER_CRDT_TBL_DEFAULT 0x0 + /*[field] C_CRDT*/ + #define IN_PORT_METER_CRDT_TBL_C_CRDT + #define IN_PORT_METER_CRDT_TBL_C_CRDT_OFFSET 0 + #define IN_PORT_METER_CRDT_TBL_C_CRDT_LEN 32 + #define IN_PORT_METER_CRDT_TBL_C_CRDT_DEFAULT 0x0 + /*[field] E_CRDT*/ + #define IN_PORT_METER_CRDT_TBL_E_CRDT + #define IN_PORT_METER_CRDT_TBL_E_CRDT_OFFSET 32 + #define IN_PORT_METER_CRDT_TBL_E_CRDT_LEN 32 + #define IN_PORT_METER_CRDT_TBL_E_CRDT_DEFAULT 0x0 + +struct in_port_meter_crdt_tbl { + a_uint32_t c_crdt:32; + a_uint32_t e_crdt:32; +}; + +union in_port_meter_crdt_tbl_u { + a_uint32_t val[2]; + struct in_port_meter_crdt_tbl bf; +}; + +/*[table] IN_PORT_METER_CNT_TBL*/ +#define IN_PORT_METER_CNT_TBL +#define IN_PORT_METER_CNT_TBL_ADDRESS 0xe000 +#define IN_PORT_METER_CNT_TBL_NUM 24 +#define IN_PORT_METER_CNT_TBL_INC 0x10 +#define IN_PORT_METER_CNT_TBL_TYPE REG_TYPE_RW +#define IN_PORT_METER_CNT_TBL_DEFAULT 0x0 + /*[field] PKT_CNT*/ + #define IN_PORT_METER_CNT_TBL_PKT_CNT + #define IN_PORT_METER_CNT_TBL_PKT_CNT_OFFSET 0 + #define IN_PORT_METER_CNT_TBL_PKT_CNT_LEN 32 + #define IN_PORT_METER_CNT_TBL_PKT_CNT_DEFAULT 0x0 + /*[field] BYTE_CNT*/ + #define IN_PORT_METER_CNT_TBL_BYTE_CNT + #define IN_PORT_METER_CNT_TBL_BYTE_CNT_OFFSET 32 + #define IN_PORT_METER_CNT_TBL_BYTE_CNT_LEN 40 + #define IN_PORT_METER_CNT_TBL_BYTE_CNT_DEFAULT 0x0 + +struct in_port_meter_cnt_tbl { + a_uint32_t pkt_cnt:32; + a_uint32_t byte_cnt_0:32; + a_uint32_t byte_cnt_1:8; + a_uint32_t _reserved0:24; +}; + +union in_port_meter_cnt_tbl_u { + a_uint32_t val[3]; + struct in_port_meter_cnt_tbl bf; +}; + +/*[table] IN_ACL_METER_CNT_TBL*/ +#define IN_ACL_METER_CNT_TBL +#define IN_ACL_METER_CNT_TBL_ADDRESS 0x10000 +#define IN_ACL_METER_CNT_TBL_NUM 1536 +#define IN_ACL_METER_CNT_TBL_INC 0x10 +#define IN_ACL_METER_CNT_TBL_TYPE REG_TYPE_RW +#define IN_ACL_METER_CNT_TBL_DEFAULT 0x0 + /*[field] PKT_CNT*/ + #define IN_ACL_METER_CNT_TBL_PKT_CNT + #define IN_ACL_METER_CNT_TBL_PKT_CNT_OFFSET 0 + #define IN_ACL_METER_CNT_TBL_PKT_CNT_LEN 32 + #define IN_ACL_METER_CNT_TBL_PKT_CNT_DEFAULT 0x0 + /*[field] BYTE_CNT*/ + #define IN_ACL_METER_CNT_TBL_BYTE_CNT + #define IN_ACL_METER_CNT_TBL_BYTE_CNT_OFFSET 32 + #define IN_ACL_METER_CNT_TBL_BYTE_CNT_LEN 40 + #define IN_ACL_METER_CNT_TBL_BYTE_CNT_DEFAULT 0x0 + +struct in_acl_meter_cnt_tbl { + a_uint32_t pkt_cnt:32; + a_uint32_t byte_cnt_0:32; + a_uint32_t byte_cnt_1:8; + a_uint32_t _reserved0:24; +}; + +union in_acl_meter_cnt_tbl_u { + a_uint32_t val[3]; + struct in_acl_meter_cnt_tbl bf; +}; + +/*[table] PC_GLOBAL_CNT_TBL*/ +#define PC_GLOBAL_CNT_TBL +#define PC_GLOBAL_CNT_TBL_ADDRESS 0x58000 +#define PC_GLOBAL_CNT_TBL_NUM 3 +#define PC_GLOBAL_CNT_TBL_INC 0x10 +#define PC_GLOBAL_CNT_TBL_TYPE REG_TYPE_RW +#define PC_GLOBAL_CNT_TBL_DEFAULT 0x0 + /*[field] PKT_CNT*/ + #define PC_GLOBAL_CNT_TBL_PKT_CNT + #define PC_GLOBAL_CNT_TBL_PKT_CNT_OFFSET 0 + #define PC_GLOBAL_CNT_TBL_PKT_CNT_LEN 32 + #define PC_GLOBAL_CNT_TBL_PKT_CNT_DEFAULT 0x0 + /*[field] BYTE_CNT*/ + #define PC_GLOBAL_CNT_TBL_BYTE_CNT + #define PC_GLOBAL_CNT_TBL_BYTE_CNT_OFFSET 32 + #define PC_GLOBAL_CNT_TBL_BYTE_CNT_LEN 40 + #define PC_GLOBAL_CNT_TBL_BYTE_CNT_DEFAULT 0x0 + +struct pc_global_cnt_tbl { + a_uint32_t pkt_cnt:32; + a_uint32_t byte_cnt_0:32; + a_uint32_t byte_cnt_1:8; + a_uint32_t _reserved0:24; +}; + +union pc_global_cnt_tbl_u { + a_uint32_t val[3]; + struct pc_global_cnt_tbl bf; +}; + +/*[table] DROP_CPU_CNT_TBL*/ +#define DROP_CPU_CNT_TBL +#define DROP_CPU_CNT_TBL_ADDRESS 0x60000 +#define DROP_CPU_CNT_TBL_NUM 1280 +#define DROP_CPU_CNT_TBL_INC 0x10 +#define DROP_CPU_CNT_TBL_TYPE REG_TYPE_RW +#define DROP_CPU_CNT_TBL_DEFAULT 0x0 + /*[field] PKT_CNT*/ + #define DROP_CPU_CNT_TBL_PKT_CNT + #define DROP_CPU_CNT_TBL_PKT_CNT_OFFSET 0 + #define DROP_CPU_CNT_TBL_PKT_CNT_LEN 32 + #define DROP_CPU_CNT_TBL_PKT_CNT_DEFAULT 0x0 + /*[field] BYTE_CNT*/ + #define DROP_CPU_CNT_TBL_BYTE_CNT + #define DROP_CPU_CNT_TBL_BYTE_CNT_OFFSET 32 + #define DROP_CPU_CNT_TBL_BYTE_CNT_LEN 40 + #define DROP_CPU_CNT_TBL_BYTE_CNT_DEFAULT 0x0 + +struct drop_cpu_cnt_tbl { + a_uint32_t pkt_cnt:32; + a_uint32_t byte_cnt_0:32; + a_uint32_t byte_cnt_1:8; + a_uint32_t _reserved0:24; +}; + +union drop_cpu_cnt_tbl_u { + a_uint32_t val[3]; + struct drop_cpu_cnt_tbl bf; +}; + +/*[table] PORT_TX_DROP_CNT_TBL*/ +#define PORT_TX_DROP_CNT_TBL +#define PORT_TX_DROP_CNT_TBL_ADDRESS 0x7d000 +#define PORT_TX_DROP_CNT_TBL_NUM 8 +#define PORT_TX_DROP_CNT_TBL_INC 0x10 +#define PORT_TX_DROP_CNT_TBL_TYPE REG_TYPE_RW +#define PORT_TX_DROP_CNT_TBL_DEFAULT 0x0 + /*[field] TX_DROP_PKT_CNT*/ + #define PORT_TX_DROP_CNT_TBL_TX_DROP_PKT_CNT + #define PORT_TX_DROP_CNT_TBL_TX_DROP_PKT_CNT_OFFSET 0 + #define PORT_TX_DROP_CNT_TBL_TX_DROP_PKT_CNT_LEN 32 + #define PORT_TX_DROP_CNT_TBL_TX_DROP_PKT_CNT_DEFAULT 0x0 + /*[field] TX_DROP_BYTE_CNT*/ + #define PORT_TX_DROP_CNT_TBL_TX_DROP_BYTE_CNT + #define PORT_TX_DROP_CNT_TBL_TX_DROP_BYTE_CNT_OFFSET 32 + #define PORT_TX_DROP_CNT_TBL_TX_DROP_BYTE_CNT_LEN 40 + #define PORT_TX_DROP_CNT_TBL_TX_DROP_BYTE_CNT_DEFAULT 0x0 + +struct port_tx_drop_cnt_tbl { + a_uint32_t tx_drop_pkt_cnt:32; + a_uint32_t tx_drop_byte_cnt_0:32; + a_uint32_t tx_drop_byte_cnt_1:8; + a_uint32_t _reserved0:24; +}; + +union port_tx_drop_cnt_tbl_u { + a_uint32_t val[3]; + struct port_tx_drop_cnt_tbl bf; +}; + +/*[table] VP_TX_DROP_CNT_TBL*/ +#define VP_TX_DROP_CNT_TBL +#define VP_TX_DROP_CNT_TBL_ADDRESS 0x7e000 +#define VP_TX_DROP_CNT_TBL_NUM 256 +#define VP_TX_DROP_CNT_TBL_INC 0x10 +#define VP_TX_DROP_CNT_TBL_TYPE REG_TYPE_RW +#define VP_TX_DROP_CNT_TBL_DEFAULT 0x0 + /*[field] TX_DROP_PKT_CNT*/ + #define VP_TX_DROP_CNT_TBL_TX_DROP_PKT_CNT + #define VP_TX_DROP_CNT_TBL_TX_DROP_PKT_CNT_OFFSET 0 + #define VP_TX_DROP_CNT_TBL_TX_DROP_PKT_CNT_LEN 32 + #define VP_TX_DROP_CNT_TBL_TX_DROP_PKT_CNT_DEFAULT 0x0 + /*[field] TX_DROP_BYTE_CNT*/ + #define VP_TX_DROP_CNT_TBL_TX_DROP_BYTE_CNT + #define VP_TX_DROP_CNT_TBL_TX_DROP_BYTE_CNT_OFFSET 32 + #define VP_TX_DROP_CNT_TBL_TX_DROP_BYTE_CNT_LEN 40 + #define VP_TX_DROP_CNT_TBL_TX_DROP_BYTE_CNT_DEFAULT 0x0 + +struct vp_tx_drop_cnt_tbl { + a_uint32_t tx_drop_pkt_cnt:32; + a_uint32_t tx_drop_byte_cnt_0:32; + a_uint32_t tx_drop_byte_cnt_1:8; + a_uint32_t _reserved0:24; +}; + +union vp_tx_drop_cnt_tbl_u { + a_uint32_t val[3]; + struct vp_tx_drop_cnt_tbl bf; +}; + +/*[table] VLAN_DEV_CNT_TBL*/ +#define VLAN_DEV_CNT_TBL +#define VLAN_DEV_CNT_TBL_ADDRESS 0x7f000 +#define VLAN_DEV_CNT_TBL_NUM 64 +#define VLAN_DEV_CNT_TBL_INC 0x10 +#define VLAN_DEV_CNT_TBL_TYPE REG_TYPE_RW +#define VLAN_DEV_CNT_TBL_DEFAULT 0x0 + /*[field] RX_PKT_CNT*/ + #define VLAN_DEV_CNT_TBL_RX_PKT_CNT + #define VLAN_DEV_CNT_TBL_RX_PKT_CNT_OFFSET 0 + #define VLAN_DEV_CNT_TBL_RX_PKT_CNT_LEN 32 + #define VLAN_DEV_CNT_TBL_RX_PKT_CNT_DEFAULT 0x0 + /*[field] RX_BYTE_CNT*/ + #define VLAN_DEV_CNT_TBL_RX_BYTE_CNT + #define VLAN_DEV_CNT_TBL_RX_BYTE_CNT_OFFSET 32 + #define VLAN_DEV_CNT_TBL_RX_BYTE_CNT_LEN 40 + #define VLAN_DEV_CNT_TBL_RX_BYTE_CNT_DEFAULT 0x0 + +struct vlan_dev_cnt_tbl { + a_uint32_t rx_pkt_cnt:32; + a_uint32_t rx_byte_cnt_0:32; + a_uint32_t rx_byte_cnt_1:8; + a_uint32_t _reserved0:24; +}; + +union vlan_dev_cnt_tbl_u { + a_uint32_t val[3]; + struct vlan_dev_cnt_tbl bf; +}; + + + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_portctrl.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_portctrl.h new file mode 100755 index 000000000..e14ed3106 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_portctrl.h @@ -0,0 +1,1413 @@ +/* + * 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 + * @{ + */ +#ifndef _HPPE_PORTCTRL_H_ +#define _HPPE_PORTCTRL_H_ + + +#define MAC_ENABLE_MAX_ENTRY 6 +#define MAC_SPEED_MAX_ENTRY 6 +#define GOL_MAC_ADDR0_MAX_ENTRY 6 +#define GOL_MAC_ADDR1_MAX_ENTRY 6 +#define MAC_CTRL0_MAX_ENTRY 6 +#define MAC_CTRL1_MAX_ENTRY 6 +#define MAC_CTRL2_MAX_ENTRY 6 +#define MAC_DBG_CTRL_MAX_ENTRY 6 +#define MAC_DBG_ADDR_MAX_ENTRY 6 +#define MAC_DBG_DATA_MAX_ENTRY 6 +#define MAC_JUMBO_SIZE_MAX_ENTRY 6 +#define MC_MTU_CTRL_TBL_MAX_ENTRY 8 +#define MRU_MTU_CTRL_TBL_MAX_ENTRY 256 +#define RX_FIFO_CFG_MAX_ENTRY 8 +#define TDM_CFG_MAX_ENTRY 128 +#define PORT_IN_FORWARD_MAX_ENTRY 8 +#define PORT_TX_COUNTER_TBL_REG_MAX_ENTRY 8 +#define VP_TX_COUNTER_TBL_REG_MAX_ENTRY 256 +#define IPR_PKT_NUM_TBL_REG_MAX_ENTRY 8 +#define IPR_BYTE_LOW_REG_REG_MAX_ENTRY 8 +#define IPR_BYTE_HIGH_REG_MAX_ENTRY 8 +#define DROP_CNT_MAX_ENTRY 8 +#define DROP_PKT_STAT_MAX_ENTRY 30 + + +sw_error_t +hppe_mac_enable_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_enable_u *value); + +sw_error_t +hppe_mac_enable_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_enable_u *value); + +sw_error_t +hppe_mac_speed_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_speed_u *value); + +sw_error_t +hppe_mac_speed_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_speed_u *value); + +sw_error_t +hppe_gol_mac_addr0_get( + a_uint32_t dev_id, + a_uint32_t index, + union gol_mac_addr0_u *value); + +sw_error_t +hppe_gol_mac_addr0_set( + a_uint32_t dev_id, + a_uint32_t index, + union gol_mac_addr0_u *value); + +sw_error_t +hppe_gol_mac_addr1_get( + a_uint32_t dev_id, + a_uint32_t index, + union gol_mac_addr1_u *value); + +sw_error_t +hppe_gol_mac_addr1_set( + a_uint32_t dev_id, + a_uint32_t index, + union gol_mac_addr1_u *value); + +sw_error_t +hppe_mac_ctrl0_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_ctrl0_u *value); + +sw_error_t +hppe_mac_ctrl0_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_ctrl0_u *value); + +sw_error_t +hppe_mac_ctrl1_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_ctrl1_u *value); + +sw_error_t +hppe_mac_ctrl1_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_ctrl1_u *value); + +sw_error_t +hppe_mac_ctrl2_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_ctrl2_u *value); + +sw_error_t +hppe_mac_ctrl2_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_ctrl2_u *value); + +sw_error_t +hppe_mac_dbg_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_dbg_ctrl_u *value); + +sw_error_t +hppe_mac_dbg_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_dbg_ctrl_u *value); + +sw_error_t +hppe_mac_dbg_addr_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_dbg_addr_u *value); + +sw_error_t +hppe_mac_dbg_addr_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_dbg_addr_u *value); + +sw_error_t +hppe_mac_dbg_data_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_dbg_data_u *value); + +sw_error_t +hppe_mac_dbg_data_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_dbg_data_u *value); + +sw_error_t +hppe_mac_jumbo_size_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_jumbo_size_u *value); + +sw_error_t +hppe_mac_jumbo_size_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_jumbo_size_u *value); + +sw_error_t +hppe_mru_mtu_ctrl_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mru_mtu_ctrl_tbl_u *value); + +sw_error_t +hppe_mru_mtu_ctrl_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mru_mtu_ctrl_tbl_u *value); + +sw_error_t +hppe_mc_mtu_ctrl_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mc_mtu_ctrl_tbl_u *value); + +sw_error_t +hppe_mc_mtu_ctrl_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mc_mtu_ctrl_tbl_u *value); + +sw_error_t +hppe_tdm_ctrl_get( + a_uint32_t dev_id, + union tdm_ctrl_u *value); + +sw_error_t +hppe_tdm_ctrl_set( + a_uint32_t dev_id, + union tdm_ctrl_u *value); + +sw_error_t +hppe_rx_fifo_cfg_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_fifo_cfg_u *value); + +sw_error_t +hppe_rx_fifo_cfg_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_fifo_cfg_u *value); + +sw_error_t +hppe_tdm_cfg_get( + a_uint32_t dev_id, + a_uint32_t index, + union tdm_cfg_u *value); + +sw_error_t +hppe_tdm_cfg_set( + a_uint32_t dev_id, + a_uint32_t index, + union tdm_cfg_u *value); + +sw_error_t +hppe_drop_stat_get( + a_uint32_t dev_id, + a_uint32_t index, + union drop_stat_u *value); + +sw_error_t +hppe_drop_stat_set( + a_uint32_t dev_id, + a_uint32_t index, + union drop_stat_u *value); + +sw_error_t +hppe_mac_enable_txmac_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_enable_txmac_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_enable_rxmac_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_enable_rxmac_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_enable_tx_flow_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_enable_tx_flow_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_enable_rx_flow_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_enable_rx_flow_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_enable_duplex_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_enable_duplex_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_speed_mac_speed_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_speed_mac_speed_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_gol_mac_addr0_mac_addr_byte4_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_gol_mac_addr0_mac_addr_byte4_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_gol_mac_addr0_mac_addr_byte5_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_gol_mac_addr0_mac_addr_byte5_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_gol_mac_addr1_mac_addr_byte1_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_gol_mac_addr1_mac_addr_byte1_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_gol_mac_addr1_mac_addr_byte2_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_gol_mac_addr1_mac_addr_byte2_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_gol_mac_addr1_mac_addr_byte0_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_gol_mac_addr1_mac_addr_byte0_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_gol_mac_addr1_mac_addr_byte3_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_gol_mac_addr1_mac_addr_byte3_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_ctrl0_amaxc_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_ctrl0_amaxc_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_ctrl0_ipgt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_ctrl0_ipgt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_ctrl0_nobo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_ctrl0_nobo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_ctrl0_half_thdf_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_ctrl0_half_thdf_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_ctrl0_hugen_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_ctrl0_hugen_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_ctrl0_bpnb_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_ctrl0_bpnb_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_ctrl0_flchk_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_ctrl0_flchk_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_ctrl0_ipgr2_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_ctrl0_ipgr2_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_ctrl0_drbnib_rxok_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_ctrl0_drbnib_rxok_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_ctrl0_huge_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_ctrl0_huge_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_ctrl0_abebe_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_ctrl0_abebe_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_ctrl1_povr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_ctrl1_povr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_ctrl1_simr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_ctrl1_simr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_ctrl1_jam_ipg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_ctrl1_jam_ipg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_ctrl1_lcol_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_ctrl1_lcol_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_ctrl1_tctl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_ctrl1_tctl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_ctrl1_retry_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_ctrl1_retry_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_ctrl1_prlen_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_ctrl1_prlen_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_ctrl1_ppad_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_ctrl1_ppad_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_ctrl1_long_jam_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_ctrl1_long_jam_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_ctrl1_phug_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_ctrl1_phug_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_ctrl1_sstct_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_ctrl1_sstct_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_ctrl1_mbof_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_ctrl1_mbof_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_ctrl1_tpause_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_ctrl1_tpause_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_ctrl2_ipg_dec_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_ctrl2_ipg_dec_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_ctrl2_mac_rsv_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_ctrl2_mac_rsv_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_ctrl2_mac_tx_thd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_ctrl2_mac_tx_thd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_ctrl2_crc_rsv_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_ctrl2_crc_rsv_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_ctrl2_crs_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_ctrl2_crs_sel_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_ctrl2_ipg_dec_len_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_ctrl2_ipg_dec_len_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_ctrl2_maxfr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_ctrl2_maxfr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_ctrl2_mac_lpi_tx_idle_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_ctrl2_mac_lpi_tx_idle_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_ctrl2_mac_loop_back_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_ctrl2_mac_loop_back_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_ctrl2_test_pause_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_ctrl2_test_pause_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_dbg_ctrl_edxsdfr_transmit_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_dbg_ctrl_edxsdfr_transmit_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_dbg_ctrl_hihg_ipg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_dbg_ctrl_hihg_ipg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_dbg_ctrl_mac_ipg_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_dbg_ctrl_mac_ipg_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_dbg_ctrl_mac_len_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_dbg_ctrl_mac_len_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_dbg_ctrl_ipgr1_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_dbg_ctrl_ipgr1_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_dbg_addr_mac_debug_addr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_dbg_addr_mac_debug_addr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_dbg_data_mac_debug_data_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_dbg_data_mac_debug_data_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_jumbo_size_mac_jumbo_size_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_jumbo_size_mac_jumbo_size_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mru_mtu_ctrl_tbl_mtu_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mru_mtu_ctrl_tbl_mtu_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mru_mtu_ctrl_tbl_rx_cnt_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mru_mtu_ctrl_tbl_rx_cnt_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mru_mtu_ctrl_tbl_tx_cnt_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mru_mtu_ctrl_tbl_tx_cnt_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mru_mtu_ctrl_tbl_mru_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mru_mtu_ctrl_tbl_mru_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mru_mtu_ctrl_tbl_mru_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mru_mtu_ctrl_tbl_mru_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mru_mtu_ctrl_tbl_src_profile_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mru_mtu_ctrl_tbl_src_profile_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mru_mtu_ctrl_tbl_mtu_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mru_mtu_ctrl_tbl_mtu_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mc_mtu_ctrl_tbl_mtu_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mc_mtu_ctrl_tbl_mtu_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mc_mtu_ctrl_tbl_tx_cnt_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mc_mtu_ctrl_tbl_tx_cnt_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mc_mtu_ctrl_tbl_mtu_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mc_mtu_ctrl_tbl_mtu_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); +sw_error_t +hppe_tdm_ctrl_tdm_en_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_tdm_ctrl_tdm_en_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_tdm_ctrl_tdm_offset_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_tdm_ctrl_tdm_offset_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_tdm_ctrl_tdm_depth_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_tdm_ctrl_tdm_depth_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_rx_fifo_cfg_rx_fifo_thres_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_fifo_cfg_rx_fifo_thres_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tdm_cfg_port_num_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tdm_cfg_port_num_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tdm_cfg_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tdm_cfg_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tdm_cfg_dir_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tdm_cfg_dir_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_in_forward_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_in_forward_u *value); + +sw_error_t +hppe_port_in_forward_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_in_forward_u *value); + +sw_error_t +hppe_port_in_forward_source_filtering_bypass_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_in_forward_source_filtering_bypass_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); +sw_error_t +hppe_port_tx_counter_tbl_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_tx_counter_tbl_reg_u *value); + +sw_error_t +hppe_port_tx_counter_tbl_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_tx_counter_tbl_reg_u *value); + +sw_error_t +hppe_vp_tx_counter_tbl_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + union vp_tx_counter_tbl_reg_u *value); + +sw_error_t +hppe_vp_tx_counter_tbl_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + union vp_tx_counter_tbl_reg_u *value); + +sw_error_t +hppe_epe_dbg_in_cnt_reg_get( + a_uint32_t dev_id, + union epe_dbg_in_cnt_reg_u *value); + +sw_error_t +hppe_epe_dbg_in_cnt_reg_set( + a_uint32_t dev_id, + union epe_dbg_in_cnt_reg_u *value); + +sw_error_t +hppe_epe_dbg_out_cnt_reg_get( + a_uint32_t dev_id, + union epe_dbg_out_cnt_reg_u *value); + +sw_error_t +hppe_epe_dbg_out_cnt_reg_set( + a_uint32_t dev_id, + union epe_dbg_out_cnt_reg_u *value); + +sw_error_t +hppe_port_tx_counter_tbl_reg_tx_bytes_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_port_tx_counter_tbl_reg_tx_bytes_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_port_tx_counter_tbl_reg_tx_packets_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_tx_counter_tbl_reg_tx_packets_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vp_tx_counter_tbl_reg_tx_bytes_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_vp_tx_counter_tbl_reg_tx_bytes_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_vp_tx_counter_tbl_reg_tx_packets_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vp_tx_counter_tbl_reg_tx_packets_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_epe_dbg_in_cnt_reg_counter_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_epe_dbg_in_cnt_reg_counter_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_epe_dbg_out_cnt_reg_counter_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_epe_dbg_out_cnt_reg_counter_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_drop_stat_bytes_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_drop_stat_bytes_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_drop_stat_pkts_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_drop_stat_pkts_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_lpi_enable_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpi_enable_u *value); + +sw_error_t +hppe_lpi_enable_set( + a_uint32_t dev_id, + a_uint32_t index, + union lpi_enable_u *value); + +sw_error_t +hppe_lpi_timer_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpi_port_timer_u *value); + +sw_error_t +hppe_lpi_timer_set( + a_uint32_t dev_id, + a_uint32_t index, + union lpi_port_timer_u *value); + +sw_error_t +hppe_lpi_dbg_addr_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpi_dbg_addr_u *value); + +sw_error_t +hppe_lpi_adb_addr_set( + a_uint32_t dev_id, + a_uint32_t index, + union lpi_dbg_addr_u *value); + +sw_error_t +hppe_lpi_dbg_data_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpi_dbg_data_u *value); + +sw_error_t +hppe_lpi_adb_data_set( + a_uint32_t dev_id, + a_uint32_t index, + union lpi_dbg_data_u *value); + +sw_error_t +hppe_lpi_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpi_cnt_u *value); + +sw_error_t +hppe_lpi_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + union lpi_cnt_u *value); + +sw_error_t +hppe_drop_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + union drop_cnt_u *value); + +sw_error_t +hppe_drop_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + union drop_cnt_u *value); + +sw_error_t +hppe_drop_cnt_drop_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_drop_cnt_drop_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipr_pkt_num_tbl_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + union ipr_pkt_num_tbl_reg_u *value); + +sw_error_t +hppe_ipr_pkt_num_tbl_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + union ipr_pkt_num_tbl_reg_u *value); + +sw_error_t +hppe_ipr_byte_low_reg_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + union ipr_byte_low_reg_reg_u *value); + +sw_error_t +hppe_ipr_byte_low_reg_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + union ipr_byte_low_reg_reg_u *value); + +sw_error_t +hppe_ipr_byte_high_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + union ipr_byte_high_reg_u *value); + +sw_error_t +hppe_ipr_byte_high_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + union ipr_byte_high_reg_u *value); + +sw_error_t +hppe_ipr_pkt_num_tbl_reg_packets_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipr_pkt_num_tbl_reg_packets_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipr_byte_low_reg_reg_bytes_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipr_byte_low_reg_reg_bytes_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ipr_byte_high_reg_bytes_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ipr_byte_high_reg_bytes_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + + +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_portctrl_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_portctrl_reg.h new file mode 100755 index 000000000..ecef92a42 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_portctrl_reg.h @@ -0,0 +1,1119 @@ +/* + * 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 + * @{ + */ +#ifndef HPPE_PORTCTRL_REG_H +#define HPPE_PORTCTRL_REG_H + +/*[register] MAC_ENABLE*/ +#define MAC_ENABLE +#define MAC_ENABLE_ADDRESS 0x0 +#define MAC_ENABLE_NUM 6 +#define MAC_ENABLE_INC 0x200 +#define MAC_ENABLE_TYPE REG_TYPE_RW +#define MAC_ENABLE_DEFAULT 0x10 + /*[field] RXMAC_EN*/ + #define MAC_ENABLE_RXMAC_EN + #define MAC_ENABLE_RXMAC_EN_OFFSET 0 + #define MAC_ENABLE_RXMAC_EN_LEN 1 + #define MAC_ENABLE_RXMAC_EN_DEFAULT 0x0 + /*[field] TXMAC_EN*/ + #define MAC_ENABLE_TXMAC_EN + #define MAC_ENABLE_TXMAC_EN_OFFSET 1 + #define MAC_ENABLE_TXMAC_EN_LEN 1 + #define MAC_ENABLE_TXMAC_EN_DEFAULT 0x0 + /*[field] DUPLEX*/ + #define MAC_ENABLE_DUPLEX + #define MAC_ENABLE_DUPLEX_OFFSET 4 + #define MAC_ENABLE_DUPLEX_LEN 1 + #define MAC_ENABLE_DUPLEX_DEFAULT 0x1 + /*[field] RX_FLOW_EN*/ + #define MAC_ENABLE_RX_FLOW_EN + #define MAC_ENABLE_RX_FLOW_EN_OFFSET 5 + #define MAC_ENABLE_RX_FLOW_EN_LEN 1 + #define MAC_ENABLE_RX_FLOW_EN_DEFAULT 0x0 + /*[field] TX_FLOW_EN*/ + #define MAC_ENABLE_TX_FLOW_EN + #define MAC_ENABLE_TX_FLOW_EN_OFFSET 6 + #define MAC_ENABLE_TX_FLOW_EN_LEN 1 + #define MAC_ENABLE_TX_FLOW_EN_DEFAULT 0x0 + +struct mac_enable { + a_uint32_t rxmac_en:1; + a_uint32_t txmac_en:1; + a_uint32_t _reserved0:2; + a_uint32_t duplex:1; + a_uint32_t rx_flow_en:1; + a_uint32_t tx_flow_en:1; + a_uint32_t _reserved1:25; +}; + +union mac_enable_u { + a_uint32_t val; + struct mac_enable bf; +}; + +/*[register] MAC_SPEED*/ +#define MAC_SPEED +#define MAC_SPEED_ADDRESS 0x4 +#define MAC_SPEED_NUM 6 +#define MAC_SPEED_INC 0x200 +#define MAC_SPEED_TYPE REG_TYPE_RW +#define MAC_SPEED_DEFAULT 0x0 + /*[field] MAC_SPEED*/ + #define MAC_SPEED_MAC_SPEED + #define MAC_SPEED_MAC_SPEED_OFFSET 0 + #define MAC_SPEED_MAC_SPEED_LEN 2 + #define MAC_SPEED_MAC_SPEED_DEFAULT 0x0 + +struct mac_speed { + a_uint32_t mac_speed:2; + a_uint32_t _reserved0:30; +}; + +union mac_speed_u { + a_uint32_t val; + struct mac_speed bf; +}; + +/*[register] GOL_MAC_ADDR0*/ +#define GOL_MAC_ADDR0 +#define GOL_MAC_ADDR0_ADDRESS 0x8 +#define GOL_MAC_ADDR0_NUM 6 +#define GOL_MAC_ADDR0_INC 0x200 +#define GOL_MAC_ADDR0_TYPE REG_TYPE_RW +#define GOL_MAC_ADDR0_DEFAULT 0x1 + /*[field] MAC_ADDR_BYTE4*/ + #define GOL_MAC_ADDR0_MAC_ADDR_BYTE4 + #define GOL_MAC_ADDR0_MAC_ADDR_BYTE4_OFFSET 0 + #define GOL_MAC_ADDR0_MAC_ADDR_BYTE4_LEN 8 + #define GOL_MAC_ADDR0_MAC_ADDR_BYTE4_DEFAULT 0x1 + /*[field] MAC_ADDR_BYTE5*/ + #define GOL_MAC_ADDR0_MAC_ADDR_BYTE5 + #define GOL_MAC_ADDR0_MAC_ADDR_BYTE5_OFFSET 8 + #define GOL_MAC_ADDR0_MAC_ADDR_BYTE5_LEN 8 + #define GOL_MAC_ADDR0_MAC_ADDR_BYTE5_DEFAULT 0x0 + +struct gol_mac_addr0 { + a_uint32_t mac_addr_byte4:8; + a_uint32_t mac_addr_byte5:8; + a_uint32_t _reserved0:16; +}; + +union gol_mac_addr0_u { + a_uint32_t val; + struct gol_mac_addr0 bf; +}; + +/*[register] GOL_MAC_ADDR1*/ +#define GOL_MAC_ADDR1 +#define GOL_MAC_ADDR1_ADDRESS 0xc +#define GOL_MAC_ADDR1_NUM 6 +#define GOL_MAC_ADDR1_INC 0x200 +#define GOL_MAC_ADDR1_TYPE REG_TYPE_RW +#define GOL_MAC_ADDR1_DEFAULT 0x0 + /*[field] MAC_ADDR_BYTE3*/ + #define GOL_MAC_ADDR1_MAC_ADDR_BYTE3 + #define GOL_MAC_ADDR1_MAC_ADDR_BYTE3_OFFSET 0 + #define GOL_MAC_ADDR1_MAC_ADDR_BYTE3_LEN 8 + #define GOL_MAC_ADDR1_MAC_ADDR_BYTE3_DEFAULT 0x0 + /*[field] MAC_ADDR_BYTE2*/ + #define GOL_MAC_ADDR1_MAC_ADDR_BYTE2 + #define GOL_MAC_ADDR1_MAC_ADDR_BYTE2_OFFSET 8 + #define GOL_MAC_ADDR1_MAC_ADDR_BYTE2_LEN 8 + #define GOL_MAC_ADDR1_MAC_ADDR_BYTE2_DEFAULT 0x0 + /*[field] MAC_ADDR_BYTE1*/ + #define GOL_MAC_ADDR1_MAC_ADDR_BYTE1 + #define GOL_MAC_ADDR1_MAC_ADDR_BYTE1_OFFSET 16 + #define GOL_MAC_ADDR1_MAC_ADDR_BYTE1_LEN 8 + #define GOL_MAC_ADDR1_MAC_ADDR_BYTE1_DEFAULT 0x0 + /*[field] MAC_ADDR_BYTE0*/ + #define GOL_MAC_ADDR1_MAC_ADDR_BYTE0 + #define GOL_MAC_ADDR1_MAC_ADDR_BYTE0_OFFSET 24 + #define GOL_MAC_ADDR1_MAC_ADDR_BYTE0_LEN 8 + #define GOL_MAC_ADDR1_MAC_ADDR_BYTE0_DEFAULT 0x0 + +struct gol_mac_addr1 { + a_uint32_t mac_addr_byte3:8; + a_uint32_t mac_addr_byte2:8; + a_uint32_t mac_addr_byte1:8; + a_uint32_t mac_addr_byte0:8; +}; + +union gol_mac_addr1_u { + a_uint32_t val; + struct gol_mac_addr1 bf; +}; + +/*[register] MAC_CTRL0*/ +#define MAC_CTRL0 +#define MAC_CTRL0_ADDRESS 0x10 +#define MAC_CTRL0_NUM 6 +#define MAC_CTRL0_INC 0x200 +#define MAC_CTRL0_TYPE REG_TYPE_RW +#define MAC_CTRL0_DEFAULT 0xb00e6060 + /*[field] IPGT*/ + #define MAC_CTRL0_IPGT + #define MAC_CTRL0_IPGT_OFFSET 0 + #define MAC_CTRL0_IPGT_LEN 7 + #define MAC_CTRL0_IPGT_DEFAULT 0x60 + /*[field] IPGR2*/ + #define MAC_CTRL0_IPGR2 + #define MAC_CTRL0_IPGR2_OFFSET 8 + #define MAC_CTRL0_IPGR2_LEN 7 + #define MAC_CTRL0_IPGR2_DEFAULT 0x60 + /*[field] HALF_THDF_CTRL*/ + #define MAC_CTRL0_HALF_THDF_CTRL + #define MAC_CTRL0_HALF_THDF_CTRL_OFFSET 15 + #define MAC_CTRL0_HALF_THDF_CTRL_LEN 1 + #define MAC_CTRL0_HALF_THDF_CTRL_DEFAULT 0x0 + /*[field] HUGEN*/ + #define MAC_CTRL0_HUGEN + #define MAC_CTRL0_HUGEN_OFFSET 16 + #define MAC_CTRL0_HUGEN_LEN 1 + #define MAC_CTRL0_HUGEN_DEFAULT 0x0 + /*[field] HUGE*/ + #define MAC_CTRL0_HUGE + #define MAC_CTRL0_HUGE_OFFSET 17 + #define MAC_CTRL0_HUGE_LEN 1 + #define MAC_CTRL0_HUGE_DEFAULT 0x1 + /*[field] FLCHK*/ + #define MAC_CTRL0_FLCHK + #define MAC_CTRL0_FLCHK_OFFSET 18 + #define MAC_CTRL0_FLCHK_LEN 1 + #define MAC_CTRL0_FLCHK_DEFAULT 0x1 + /*[field] ABEBE*/ + #define MAC_CTRL0_ABEBE + #define MAC_CTRL0_ABEBE_OFFSET 19 + #define MAC_CTRL0_ABEBE_LEN 1 + #define MAC_CTRL0_ABEBE_DEFAULT 0x1 + /*[field] AMAXC_EN*/ + #define MAC_CTRL0_AMAXC_EN + #define MAC_CTRL0_AMAXC_EN_OFFSET 28 + #define MAC_CTRL0_AMAXC_EN_LEN 1 + #define MAC_CTRL0_AMAXC_EN_DEFAULT 0x1 + /*[field] BPNB*/ + #define MAC_CTRL0_BPNB + #define MAC_CTRL0_BPNB_OFFSET 29 + #define MAC_CTRL0_BPNB_LEN 1 + #define MAC_CTRL0_BPNB_DEFAULT 0x1 + /*[field] NOBO*/ + #define MAC_CTRL0_NOBO + #define MAC_CTRL0_NOBO_OFFSET 30 + #define MAC_CTRL0_NOBO_LEN 1 + #define MAC_CTRL0_NOBO_DEFAULT 0x0 + /*[field] DRBNIB_RXOK_EN*/ + #define MAC_CTRL0_DRBNIB_RXOK_EN + #define MAC_CTRL0_DRBNIB_RXOK_EN_OFFSET 31 + #define MAC_CTRL0_DRBNIB_RXOK_EN_LEN 1 + #define MAC_CTRL0_DRBNIB_RXOK_EN_DEFAULT 0x1 + +struct mac_ctrl0 { + a_uint32_t ipgt:7; + a_uint32_t _reserved0:1; + a_uint32_t ipgr2:7; + a_uint32_t half_thdf_ctrl:1; + a_uint32_t hugen:1; + a_uint32_t huge:1; + a_uint32_t flchk:1; + a_uint32_t abebe:1; + a_uint32_t _reserved1:8; + a_uint32_t amaxc_en:1; + a_uint32_t bpnb:1; + a_uint32_t nobo:1; + a_uint32_t drbnib_rxok_en:1; +}; + +union mac_ctrl0_u { + a_uint32_t val; + struct mac_ctrl0 bf; +}; + +/*[register] MAC_CTRL1*/ +#define MAC_CTRL1 +#define MAC_CTRL1_ADDRESS 0x14 +#define MAC_CTRL1_NUM 6 +#define MAC_CTRL1_INC 0x200 +#define MAC_CTRL1_TYPE REG_TYPE_RW +#define MAC_CTRL1_DEFAULT 0x3707f07 + /*[field] JAM_IPG*/ + #define MAC_CTRL1_JAM_IPG + #define MAC_CTRL1_JAM_IPG_OFFSET 0 + #define MAC_CTRL1_JAM_IPG_LEN 4 + #define MAC_CTRL1_JAM_IPG_DEFAULT 0x7 + /*[field] TPAUSE*/ + #define MAC_CTRL1_TPAUSE + #define MAC_CTRL1_TPAUSE_OFFSET 4 + #define MAC_CTRL1_TPAUSE_LEN 1 + #define MAC_CTRL1_TPAUSE_DEFAULT 0x0 + /*[field] TCTL*/ + #define MAC_CTRL1_TCTL + #define MAC_CTRL1_TCTL_OFFSET 5 + #define MAC_CTRL1_TCTL_LEN 1 + #define MAC_CTRL1_TCTL_DEFAULT 0x0 + /*[field] SSTCT*/ + #define MAC_CTRL1_SSTCT + #define MAC_CTRL1_SSTCT_OFFSET 6 + #define MAC_CTRL1_SSTCT_LEN 1 + #define MAC_CTRL1_SSTCT_DEFAULT 0x0 + /*[field] SIMR*/ + #define MAC_CTRL1_SIMR + #define MAC_CTRL1_SIMR_OFFSET 7 + #define MAC_CTRL1_SIMR_LEN 1 + #define MAC_CTRL1_SIMR_DEFAULT 0x0 + /*[field] RETRY*/ + #define MAC_CTRL1_RETRY + #define MAC_CTRL1_RETRY_OFFSET 8 + #define MAC_CTRL1_RETRY_LEN 4 + #define MAC_CTRL1_RETRY_DEFAULT 0xf + /*[field] PRLEN*/ + #define MAC_CTRL1_PRLEN + #define MAC_CTRL1_PRLEN_OFFSET 12 + #define MAC_CTRL1_PRLEN_LEN 4 + #define MAC_CTRL1_PRLEN_DEFAULT 0x7 + /*[field] PPAD*/ + #define MAC_CTRL1_PPAD + #define MAC_CTRL1_PPAD_OFFSET 16 + #define MAC_CTRL1_PPAD_LEN 1 + #define MAC_CTRL1_PPAD_DEFAULT 0x0 + /*[field] POVR*/ + #define MAC_CTRL1_POVR + #define MAC_CTRL1_POVR_OFFSET 17 + #define MAC_CTRL1_POVR_LEN 1 + #define MAC_CTRL1_POVR_DEFAULT 0x0 + /*[field] PHUG*/ + #define MAC_CTRL1_PHUG + #define MAC_CTRL1_PHUG_OFFSET 18 + #define MAC_CTRL1_PHUG_LEN 1 + #define MAC_CTRL1_PHUG_DEFAULT 0x0 + /*[field] MBOF*/ + #define MAC_CTRL1_MBOF + #define MAC_CTRL1_MBOF_OFFSET 19 + #define MAC_CTRL1_MBOF_LEN 1 + #define MAC_CTRL1_MBOF_DEFAULT 0x0 + /*[field] LCOL*/ + #define MAC_CTRL1_LCOL + #define MAC_CTRL1_LCOL_OFFSET 20 + #define MAC_CTRL1_LCOL_LEN 8 + #define MAC_CTRL1_LCOL_DEFAULT 0x37 + /*[field] LONG_JAM_EN*/ + #define MAC_CTRL1_LONG_JAM_EN + #define MAC_CTRL1_LONG_JAM_EN_OFFSET 28 + #define MAC_CTRL1_LONG_JAM_EN_LEN 1 + #define MAC_CTRL1_LONG_JAM_EN_DEFAULT 0x0 + +struct mac_ctrl1 { + a_uint32_t jam_ipg:4; + a_uint32_t tpause:1; + a_uint32_t tctl:1; + a_uint32_t sstct:1; + a_uint32_t simr:1; + a_uint32_t retry:4; + a_uint32_t prlen:4; + a_uint32_t ppad:1; + a_uint32_t povr:1; + a_uint32_t phug:1; + a_uint32_t mbof:1; + a_uint32_t lcol:8; + a_uint32_t long_jam_en:1; + a_uint32_t _reserved0:3; +}; + +union mac_ctrl1_u { + a_uint32_t val; + struct mac_ctrl1 bf; +}; + +/*[register] MAC_CTRL2*/ +#define MAC_CTRL2 +#define MAC_CTRL2_ADDRESS 0x18 +#define MAC_CTRL2_NUM 6 +#define MAC_CTRL2_INC 0x200 +#define MAC_CTRL2_TYPE REG_TYPE_RW +#define MAC_CTRL2_DEFAULT 0xc271c40 + /*[field] IPG_DEC_LEN*/ + #define MAC_CTRL2_IPG_DEC_LEN + #define MAC_CTRL2_IPG_DEC_LEN_OFFSET 1 + #define MAC_CTRL2_IPG_DEC_LEN_LEN 1 + #define MAC_CTRL2_IPG_DEC_LEN_DEFAULT 0x0 + /*[field] TEST_PAUSE*/ + #define MAC_CTRL2_TEST_PAUSE + #define MAC_CTRL2_TEST_PAUSE_OFFSET 2 + #define MAC_CTRL2_TEST_PAUSE_LEN 1 + #define MAC_CTRL2_TEST_PAUSE_DEFAULT 0x0 + /*[field] MAC_LPI_TX_IDLE*/ + #define MAC_CTRL2_MAC_LPI_TX_IDLE + #define MAC_CTRL2_MAC_LPI_TX_IDLE_OFFSET 3 + #define MAC_CTRL2_MAC_LPI_TX_IDLE_LEN 1 + #define MAC_CTRL2_MAC_LPI_TX_IDLE_DEFAULT 0x0 + /*[field] MAC_LOOP_BACK*/ + #define MAC_CTRL2_MAC_LOOP_BACK + #define MAC_CTRL2_MAC_LOOP_BACK_OFFSET 4 + #define MAC_CTRL2_MAC_LOOP_BACK_LEN 1 + #define MAC_CTRL2_MAC_LOOP_BACK_DEFAULT 0x0 + /*[field] IPG_DEC_EN*/ + #define MAC_CTRL2_IPG_DEC_EN + #define MAC_CTRL2_IPG_DEC_EN_OFFSET 5 + #define MAC_CTRL2_IPG_DEC_EN_LEN 1 + #define MAC_CTRL2_IPG_DEC_EN_DEFAULT 0x0 + /*[field] CRS_SEL*/ + #define MAC_CTRL2_CRS_SEL + #define MAC_CTRL2_CRS_SEL_OFFSET 6 + #define MAC_CTRL2_CRS_SEL_LEN 1 + #define MAC_CTRL2_CRS_SEL_DEFAULT 0x1 + /*[field] CRC_RSV_EN*/ + #define MAC_CTRL2_CRC_RSV_EN + #define MAC_CTRL2_CRC_RSV_EN_OFFSET 7 + #define MAC_CTRL2_CRC_RSV_EN_LEN 1 + #define MAC_CTRL2_CRC_RSV_EN_DEFAULT 0x0 + /*[field] MAXFR*/ + #define MAC_CTRL2_MAXFR + #define MAC_CTRL2_MAXFR_OFFSET 8 + #define MAC_CTRL2_MAXFR_LEN 14 + #define MAC_CTRL2_MAXFR_DEFAULT 0x271c + /*[field] MAC_TX_THD*/ + #define MAC_CTRL2_MAC_TX_THD + #define MAC_CTRL2_MAC_TX_THD_OFFSET 24 + #define MAC_CTRL2_MAC_TX_THD_LEN 4 + #define MAC_CTRL2_MAC_TX_THD_DEFAULT 0xc + /*[field] MAC_RSV*/ + #define MAC_CTRL2_MAC_RSV + #define MAC_CTRL2_MAC_RSV_OFFSET 28 + #define MAC_CTRL2_MAC_RSV_LEN 4 + #define MAC_CTRL2_MAC_RSV_DEFAULT 0x0 + +struct mac_ctrl2 { + a_uint32_t _reserved0:1; + a_uint32_t ipg_dec_len:1; + a_uint32_t test_pause:1; + a_uint32_t mac_lpi_tx_idle:1; + a_uint32_t mac_loop_back:1; + a_uint32_t ipg_dec_en:1; + a_uint32_t crs_sel:1; + a_uint32_t crc_rsv_en:1; + a_uint32_t maxfr:14; + a_uint32_t _reserved1:2; + a_uint32_t mac_tx_thd:4; + a_uint32_t mac_rsv:4; +}; + +union mac_ctrl2_u { + a_uint32_t val; + struct mac_ctrl2 bf; +}; + +/*[register] MAC_DBG_CTRL*/ +#define MAC_DBG_CTRL +#define MAC_DBG_CTRL_ADDRESS 0x1c +#define MAC_DBG_CTRL_NUM 6 +#define MAC_DBG_CTRL_INC 0x200 +#define MAC_DBG_CTRL_TYPE REG_TYPE_RW +#define MAC_DBG_CTRL_DEFAULT 0x80701040 + /*[field] IPGR1*/ + #define MAC_DBG_CTRL_IPGR1 + #define MAC_DBG_CTRL_IPGR1_OFFSET 0 + #define MAC_DBG_CTRL_IPGR1_LEN 7 + #define MAC_DBG_CTRL_IPGR1_DEFAULT 0x40 + /*[field] HIHG_IPG*/ + #define MAC_DBG_CTRL_HIHG_IPG + #define MAC_DBG_CTRL_HIHG_IPG_OFFSET 8 + #define MAC_DBG_CTRL_HIHG_IPG_LEN 8 + #define MAC_DBG_CTRL_HIHG_IPG_DEFAULT 0x10 + /*[field] MAC_IPG_CTRL*/ + #define MAC_DBG_CTRL_MAC_IPG_CTRL + #define MAC_DBG_CTRL_MAC_IPG_CTRL_OFFSET 20 + #define MAC_DBG_CTRL_MAC_IPG_CTRL_LEN 4 + #define MAC_DBG_CTRL_MAC_IPG_CTRL_DEFAULT 0x7 + /*[field] MAC_LEN_CTRL*/ + #define MAC_DBG_CTRL_MAC_LEN_CTRL + #define MAC_DBG_CTRL_MAC_LEN_CTRL_OFFSET 30 + #define MAC_DBG_CTRL_MAC_LEN_CTRL_LEN 1 + #define MAC_DBG_CTRL_MAC_LEN_CTRL_DEFAULT 0x0 + /*[field] EDXSDFR_TRANSMIT_EN*/ + #define MAC_DBG_CTRL_EDXSDFR_TRANSMIT_EN + #define MAC_DBG_CTRL_EDXSDFR_TRANSMIT_EN_OFFSET 31 + #define MAC_DBG_CTRL_EDXSDFR_TRANSMIT_EN_LEN 1 + #define MAC_DBG_CTRL_EDXSDFR_TRANSMIT_EN_DEFAULT 0x1 + +struct mac_dbg_ctrl { + a_uint32_t ipgr1:7; + a_uint32_t _reserved0:1; + a_uint32_t hihg_ipg:8; + a_uint32_t _reserved1:4; + a_uint32_t mac_ipg_ctrl:4; + a_uint32_t _reserved2:6; + a_uint32_t mac_len_ctrl:1; + a_uint32_t edxsdfr_transmit_en:1; +}; + +union mac_dbg_ctrl_u { + a_uint32_t val; + struct mac_dbg_ctrl bf; +}; + +/*[register] MAC_DBG_ADDR*/ +#define MAC_DBG_ADDR +#define MAC_DBG_ADDR_ADDRESS 0x20 +#define MAC_DBG_ADDR_NUM 6 +#define MAC_DBG_ADDR_INC 0x200 +#define MAC_DBG_ADDR_TYPE REG_TYPE_RW +#define MAC_DBG_ADDR_DEFAULT 0x0 + /*[field] MAC_DEBUG_ADDR*/ + #define MAC_DBG_ADDR_MAC_DEBUG_ADDR + #define MAC_DBG_ADDR_MAC_DEBUG_ADDR_OFFSET 0 + #define MAC_DBG_ADDR_MAC_DEBUG_ADDR_LEN 8 + #define MAC_DBG_ADDR_MAC_DEBUG_ADDR_DEFAULT 0x0 + +struct mac_dbg_addr { + a_uint32_t mac_debug_addr:8; + a_uint32_t _reserved0:24; +}; + +union mac_dbg_addr_u { + a_uint32_t val; + struct mac_dbg_addr bf; +}; + +/*[register] MAC_DBG_DATA*/ +#define MAC_DBG_DATA +#define MAC_DBG_DATA_ADDRESS 0x24 +#define MAC_DBG_DATA_NUM 6 +#define MAC_DBG_DATA_INC 0x200 +#define MAC_DBG_DATA_TYPE REG_TYPE_RO +#define MAC_DBG_DATA_DEFAULT 0x0 + /*[field] MAC_DEBUG_DATA*/ + #define MAC_DBG_DATA_MAC_DEBUG_DATA + #define MAC_DBG_DATA_MAC_DEBUG_DATA_OFFSET 0 + #define MAC_DBG_DATA_MAC_DEBUG_DATA_LEN 32 + #define MAC_DBG_DATA_MAC_DEBUG_DATA_DEFAULT 0x0 + +struct mac_dbg_data { + a_uint32_t mac_debug_data:32; +}; + +union mac_dbg_data_u { + a_uint32_t val; + struct mac_dbg_data bf; +}; + +/*[register] MAC_JUMBO_SIZE*/ +#define MAC_JUMBO_SIZE +#define MAC_JUMBO_SIZE_ADDRESS 0x30 +#define MAC_JUMBO_SIZE_NUM 6 +#define MAC_JUMBO_SIZE_INC 0x200 +#define MAC_JUMBO_SIZE_TYPE REG_TYPE_RW +#define MAC_JUMBO_SIZE_DEFAULT 0x271c + /*[field] MAC_JUMBO_SIZE*/ + #define MAC_JUMBO_SIZE_MAC_JUMBO_SIZE + #define MAC_JUMBO_SIZE_MAC_JUMBO_SIZE_OFFSET 0 + #define MAC_JUMBO_SIZE_MAC_JUMBO_SIZE_LEN 14 + #define MAC_JUMBO_SIZE_MAC_JUMBO_SIZE_DEFAULT 0x271c + +struct mac_jumbo_size { + a_uint32_t mac_jumbo_size:14; + a_uint32_t _reserved0:18; +}; + +union mac_jumbo_size_u { + a_uint32_t val; + struct mac_jumbo_size bf; +}; + +/*[register] PORT_IN_FORWARD*/ +#define PORT_IN_FORWARD +#define PORT_IN_FORWARD_ADDRESS 0x700 +#define PORT_IN_FORWARD_NUM 8 +#define PORT_IN_FORWARD_INC 0x4 +#define PORT_IN_FORWARD_TYPE REG_TYPE_RW +#define PORT_IN_FORWARD_DEFAULT 0x0 + /*[field] SOURCE_FILTERING_BYPASS*/ + #define PORT_IN_FORWARD_SOURCE_FILTERING_BYPASS + #define PORT_IN_FORWARD_SOURCE_FILTERING_BYPASS_OFFSET 0 + #define PORT_IN_FORWARD_SOURCE_FILTERING_BYPASS_LEN 1 + #define PORT_IN_FORWARD_SOURCE_FILTERING_BYPASS_DEFAULT 0x0 + +struct port_in_forward { + a_uint32_t source_filtering_bypass:1; + a_uint32_t _reserved0:31; +}; + +union port_in_forward_u { + a_uint32_t val; + struct port_in_forward bf; +}; + +/*[table] MRU_MTU_CTRL_TBL*/ +#define MRU_MTU_CTRL_TBL +#define MRU_MTU_CTRL_TBL_ADDRESS 0x3000 +#define MRU_MTU_CTRL_TBL_NUM 256 +#define MRU_MTU_CTRL_TBL_INC 0x8 +#define MRU_MTU_CTRL_TBL_TYPE REG_TYPE_RW +#define MRU_MTU_CTRL_TBL_DEFAULT 0x0 + /*[field] MRU*/ + #define MRU_MTU_CTRL_TBL_MRU + #define MRU_MTU_CTRL_TBL_MRU_OFFSET 0 + #define MRU_MTU_CTRL_TBL_MRU_LEN 14 + #define MRU_MTU_CTRL_TBL_MRU_DEFAULT 0x0 + /*[field] MRU_CMD*/ + #define MRU_MTU_CTRL_TBL_MRU_CMD + #define MRU_MTU_CTRL_TBL_MRU_CMD_OFFSET 14 + #define MRU_MTU_CTRL_TBL_MRU_CMD_LEN 2 + #define MRU_MTU_CTRL_TBL_MRU_CMD_DEFAULT 0x0 + /*[field] MTU*/ + #define MRU_MTU_CTRL_TBL_MTU + #define MRU_MTU_CTRL_TBL_MTU_OFFSET 16 + #define MRU_MTU_CTRL_TBL_MTU_LEN 14 + #define MRU_MTU_CTRL_TBL_MTU_DEFAULT 0x0 + /*[field] MTU_CMD*/ + #define MRU_MTU_CTRL_TBL_MTU_CMD + #define MRU_MTU_CTRL_TBL_MTU_CMD_OFFSET 30 + #define MRU_MTU_CTRL_TBL_MTU_CMD_LEN 2 + #define MRU_MTU_CTRL_TBL_MTU_CMD_DEFAULT 0x0 + /*[field] RX_CNT_EN*/ + #define MRU_MTU_CTRL_TBL_RX_CNT_EN + #define MRU_MTU_CTRL_TBL_RX_CNT_EN_OFFSET 32 + #define MRU_MTU_CTRL_TBL_RX_CNT_EN_LEN 1 + #define MRU_MTU_CTRL_TBL_RX_CNT_EN_DEFAULT 0x0 + /*[field] TX_CNT_EN*/ + #define MRU_MTU_CTRL_TBL_TX_CNT_EN + #define MRU_MTU_CTRL_TBL_TX_CNT_EN_OFFSET 33 + #define MRU_MTU_CTRL_TBL_TX_CNT_EN_LEN 1 + #define MRU_MTU_CTRL_TBL_TX_CNT_EN_DEFAULT 0x0 + /*[field] SRC_PROFILE*/ + #define MRU_MTU_CTRL_TBL_SRC_PROFILE + #define MRU_MTU_CTRL_TBL_SRC_PROFILE_OFFSET 34 + #define MRU_MTU_CTRL_TBL_SRC_PROFILE_LEN 2 + #define MRU_MTU_CTRL_TBL_SRC_PROFILE_DEFAULT 0x0 + +struct mru_mtu_ctrl_tbl { + a_uint32_t mru:14; + a_uint32_t mru_cmd:2; + a_uint32_t mtu:14; + a_uint32_t mtu_cmd:2; + a_uint32_t rx_cnt_en:1; + a_uint32_t tx_cnt_en:1; + a_uint32_t src_profile:2; + a_uint32_t _reserved0:28; +}; + +union mru_mtu_ctrl_tbl_u { + a_uint32_t val[2]; + struct mru_mtu_ctrl_tbl bf; +}; + +/*[register] MC_MTU_CTRL_TBL*/ +#define MC_MTU_CTRL_TBL +#define MC_MTU_CTRL_TBL_ADDRESS 0xa00 +#define MC_MTU_CTRL_TBL_NUM 8 +#define MC_MTU_CTRL_TBL_INC 0x4 +#define MC_MTU_CTRL_TBL_TYPE REG_TYPE_RW +#define MC_MTU_CTRL_TBL_DEFAULT 0x5ea + /*[field] MTU*/ + #define MC_MTU_CTRL_TBL_MTU + #define MC_MTU_CTRL_TBL_MTU_OFFSET 0 + #define MC_MTU_CTRL_TBL_MTU_LEN 14 + #define MC_MTU_CTRL_TBL_MTU_DEFAULT 0x5ea + /*[field] MTU_CMD*/ + #define MC_MTU_CTRL_TBL_MTU_CMD + #define MC_MTU_CTRL_TBL_MTU_CMD_OFFSET 14 + #define MC_MTU_CTRL_TBL_MTU_CMD_LEN 2 + #define MC_MTU_CTRL_TBL_MTU_CMD_DEFAULT 0x0 + /*[field] TX_CNT_EN*/ + #define MC_MTU_CTRL_TBL_TX_CNT_EN + #define MC_MTU_CTRL_TBL_TX_CNT_EN_OFFSET 16 + #define MC_MTU_CTRL_TBL_TX_CNT_EN_LEN 1 + #define MC_MTU_CTRL_TBL_TX_CNT_EN_DEFAULT 0x0 + +struct mc_mtu_ctrl_tbl { + a_uint32_t mtu:14; + a_uint32_t mtu_cmd:2; + a_uint32_t tx_cnt_en:1; + a_uint32_t _reserved0:15; +}; + +union mc_mtu_ctrl_tbl_u { + a_uint32_t val; + struct mc_mtu_ctrl_tbl bf; +}; + +/*[register] TDM_CTRL*/ +#define TDM_CTRL +#define TDM_CTRL_ADDRESS 0x0 +#define TDM_CTRL_NUM 1 +#define TDM_CTRL_INC 0x4 +#define TDM_CTRL_TYPE REG_TYPE_RW +#define TDM_CTRL_DEFAULT 0x80000050 + /*[field] TDM_DEPTH*/ + #define TDM_CTRL_TDM_DEPTH + #define TDM_CTRL_TDM_DEPTH_OFFSET 0 + #define TDM_CTRL_TDM_DEPTH_LEN 8 + #define TDM_CTRL_TDM_DEPTH_DEFAULT 0x50 + /*[field] TDM_OFFSET*/ + #define TDM_CTRL_TDM_OFFSET + #define TDM_CTRL_TDM_OFFSET_OFFSET 8 + #define TDM_CTRL_TDM_OFFSET_LEN 7 + #define TDM_CTRL_TDM_OFFSET_DEFAULT 0x0 + /*[field] TDM_EN*/ + #define TDM_CTRL_TDM_EN + #define TDM_CTRL_TDM_EN_OFFSET 31 + #define TDM_CTRL_TDM_EN_LEN 1 + #define TDM_CTRL_TDM_EN_DEFAULT 0x1 + +struct tdm_ctrl { + a_uint32_t tdm_depth:8; + a_uint32_t tdm_offset:7; + a_uint32_t _reserved0:16; + a_uint32_t tdm_en:1; +}; + +union tdm_ctrl_u { + a_uint32_t val; + struct tdm_ctrl bf; +}; + +/*[register] RX_FIFO_CFG*/ +#define RX_FIFO_CFG +#define RX_FIFO_CFG_ADDRESS 0x4 +#define RX_FIFO_CFG_NUM 8 +#define RX_FIFO_CFG_INC 0x4 +#define RX_FIFO_CFG_TYPE REG_TYPE_RW +#define RX_FIFO_CFG_DEFAULT 0x4 + /*[field] RX_FIFO_THRES*/ + #define RX_FIFO_CFG_RX_FIFO_THRES + #define RX_FIFO_CFG_RX_FIFO_THRES_OFFSET 0 + #define RX_FIFO_CFG_RX_FIFO_THRES_LEN 3 + #define RX_FIFO_CFG_RX_FIFO_THRES_DEFAULT 0x4 + +struct rx_fifo_cfg { + a_uint32_t rx_fifo_thres:3; + a_uint32_t _reserved0:29; +}; + +union rx_fifo_cfg_u { + a_uint32_t val; + struct rx_fifo_cfg bf; +}; + +/*[table] TDM_CFG*/ +#define TDM_CFG +#define TDM_CFG_ADDRESS 0x1000 +#define TDM_CFG_NUM 128 +#define TDM_CFG_INC 0x10 +#define TDM_CFG_TYPE REG_TYPE_RW +#define TDM_CFG_DEFAULT 0x0 + /*[field] PORT_NUM*/ + #define TDM_CFG_PORT_NUM + #define TDM_CFG_PORT_NUM_OFFSET 0 + #define TDM_CFG_PORT_NUM_LEN 4 + #define TDM_CFG_PORT_NUM_DEFAULT 0x0 + /*[field] DIR*/ + #define TDM_CFG_DIR + #define TDM_CFG_DIR_OFFSET 4 + #define TDM_CFG_DIR_LEN 1 + #define TDM_CFG_DIR_DEFAULT 0x0 + /*[field] VALID*/ + #define TDM_CFG_VALID + #define TDM_CFG_VALID_OFFSET 5 + #define TDM_CFG_VALID_LEN 1 + #define TDM_CFG_VALID_DEFAULT 0x0 + +struct tdm_cfg { + a_uint32_t port_num:4; + a_uint32_t dir:1; + a_uint32_t valid:1; + a_uint32_t _reserved0:26; +}; + +union tdm_cfg_u { + a_uint32_t val; + struct tdm_cfg bf; +}; + +/*[table] DROP_STAT*/ +#define DROP_STAT +#define DROP_STAT_ADDRESS 0x3000 +#define DROP_STAT_NUM 30 +#define DROP_STAT_INC 0x10 +#define DROP_STAT_TYPE REG_TYPE_RW +#define DROP_STAT_DEFAULT 0x0 + /*[field] PKTS*/ + #define DROP_STAT_PKTS + #define DROP_STAT_PKTS_OFFSET 0 + #define DROP_STAT_PKTS_LEN 32 + #define DROP_STAT_PKTS_DEFAULT 0x0 + /*[field] BYTES*/ + #define DROP_STAT_BYTES + #define DROP_STAT_BYTES_OFFSET 32 + #define DROP_STAT_BYTES_LEN 40 + #define DROP_STAT_BYTES_DEFAULT 0x0 + +struct drop_stat { + a_uint32_t pkts:32; + a_uint32_t bytes_0:32; + a_uint32_t bytes_1:8; + a_uint32_t _reserved0:24; +}; + +union drop_stat_u { + a_uint32_t val[3]; + struct drop_stat bf; +}; + +/*[register] PORT_TX_COUNTER_TBL_REG*/ +#define PORT_TX_COUNTER_TBL_REG +#define PORT_TX_COUNTER_TBL_REG_ADDRESS 0x900 +#define PORT_TX_COUNTER_TBL_REG_NUM 8 +#define PORT_TX_COUNTER_TBL_REG_INC 0x10 +#define PORT_TX_COUNTER_TBL_REG_TYPE REG_TYPE_RW +#define PORT_TX_COUNTER_TBL_REG_DEFAULT 0x0 + /*[field] TX_PACKETS*/ + #define PORT_TX_COUNTER_TBL_REG_TX_PACKETS + #define PORT_TX_COUNTER_TBL_REG_TX_PACKETS_OFFSET 0 + #define PORT_TX_COUNTER_TBL_REG_TX_PACKETS_LEN 32 + #define PORT_TX_COUNTER_TBL_REG_TX_PACKETS_DEFAULT 0x0 + /*[field] TX_BYTES*/ + #define PORT_TX_COUNTER_TBL_REG_TX_BYTES + #define PORT_TX_COUNTER_TBL_REG_TX_BYTES_OFFSET 32 + #define PORT_TX_COUNTER_TBL_REG_TX_BYTES_LEN 40 + #define PORT_TX_COUNTER_TBL_REG_TX_BYTES_DEFAULT 0x0 + +struct port_tx_counter_tbl_reg { + a_uint32_t tx_packets:32; + a_uint32_t tx_bytes_0:32; + a_uint32_t tx_bytes_1:8; + a_uint32_t _reserved0:24; +}; + +union port_tx_counter_tbl_reg_u { + a_uint32_t val[3]; + struct port_tx_counter_tbl_reg bf; +}; + +/*[register] VP_TX_COUNTER_TBL_REG*/ +#define VP_TX_COUNTER_TBL_REG +#define VP_TX_COUNTER_TBL_REG_ADDRESS 0x1000 +#define VP_TX_COUNTER_TBL_REG_NUM 256 +#define VP_TX_COUNTER_TBL_REG_INC 0x10 +#define VP_TX_COUNTER_TBL_REG_TYPE REG_TYPE_RW +#define VP_TX_COUNTER_TBL_REG_DEFAULT 0x0 + /*[field] TX_PACKETS*/ + #define VP_TX_COUNTER_TBL_REG_TX_PACKETS + #define VP_TX_COUNTER_TBL_REG_TX_PACKETS_OFFSET 0 + #define VP_TX_COUNTER_TBL_REG_TX_PACKETS_LEN 32 + #define VP_TX_COUNTER_TBL_REG_TX_PACKETS_DEFAULT 0x0 + /*[field] TX_BYTES*/ + #define VP_TX_COUNTER_TBL_REG_TX_BYTES + #define VP_TX_COUNTER_TBL_REG_TX_BYTES_OFFSET 32 + #define VP_TX_COUNTER_TBL_REG_TX_BYTES_LEN 40 + #define VP_TX_COUNTER_TBL_REG_TX_BYTES_DEFAULT 0x0 + +struct vp_tx_counter_tbl_reg { + a_uint32_t tx_packets:32; + a_uint32_t tx_bytes_0:32; + a_uint32_t tx_bytes_1:8; + a_uint32_t _reserved0:24; +}; + +union vp_tx_counter_tbl_reg_u { + a_uint32_t val[3]; + struct vp_tx_counter_tbl_reg bf; +}; + +/*[register] EPE_DBG_IN_CNT_REG*/ +#define EPE_DBG_IN_CNT_REG +#define EPE_DBG_IN_CNT_REG_ADDRESS 0x6054 +#define EPE_DBG_IN_CNT_REG_NUM 1 +#define EPE_DBG_IN_CNT_REG_INC 0x4 +#define EPE_DBG_IN_CNT_REG_TYPE REG_TYPE_RW +#define EPE_DBG_IN_CNT_REG_DEFAULT 0x0 + /*[field] COUNTER*/ + #define EPE_DBG_IN_CNT_REG_COUNTER + #define EPE_DBG_IN_CNT_REG_COUNTER_OFFSET 0 + #define EPE_DBG_IN_CNT_REG_COUNTER_LEN 32 + #define EPE_DBG_IN_CNT_REG_COUNTER_DEFAULT 0x0 + +struct epe_dbg_in_cnt_reg { + a_uint32_t counter:32; +}; + +union epe_dbg_in_cnt_reg_u { + a_uint32_t val; + struct epe_dbg_in_cnt_reg bf; +}; + +/*[register] EPE_DBG_OUT_CNT_REG*/ +#define EPE_DBG_OUT_CNT_REG +#define EPE_DBG_OUT_CNT_REG_ADDRESS 0x6070 +#define EPE_DBG_OUT_CNT_REG_NUM 1 +#define EPE_DBG_OUT_CNT_REG_INC 0x4 +#define EPE_DBG_OUT_CNT_REG_TYPE REG_TYPE_RW +#define EPE_DBG_OUT_CNT_REG_DEFAULT 0x0 + /*[field] COUNTER*/ + #define EPE_DBG_OUT_CNT_REG_COUNTER + #define EPE_DBG_OUT_CNT_REG_COUNTER_OFFSET 0 + #define EPE_DBG_OUT_CNT_REG_COUNTER_LEN 32 + #define EPE_DBG_OUT_CNT_REG_COUNTER_DEFAULT 0x0 + +struct epe_dbg_out_cnt_reg { + a_uint32_t counter:32; +}; + +union epe_dbg_out_cnt_reg_u { + a_uint32_t val; + struct epe_dbg_out_cnt_reg bf; +}; + +/*[register] LPI_ENABLE*/ +#define LPI_ENABLE +#define LPI_ENABLE_ADDRESS 0x0 +#define LPI_ENABLE_NUM 1 +#define LPI_ENABLE_INC 0x0 +#define LPI_ENABLE_TYPE REG_TYPE_RW +#define LPI_ENABLE_DEFAULT 0x0 + /*[field] LPI_PORT1_EN*/ + #define LPI_PORT1_EN + #define LPI_PORT1_EN_OFFSET 0 + #define LPI_PORT1_EN_LEN 1 + #define LPI_PORT1_EN_DEFAULT 0x0 + /*[field] LPI_PORT2_EN*/ + #define LPI_PORT2_EN + #define LPI_PORT2_EN_OFFSET 1 + #define LPI_PORT2_EN_LEN 1 + #define LPI_PORT2_EN_DEFAULT 0x0 + /*[field] LPI_PORT3_EN*/ + #define LPI_PORT3_EN + #define LPI_PORT3_EN_OFFSET 2 + #define LPI_PORT3_EN_LEN 1 + #define LPI_PORT3_EN_DEFAULT 0x0 + /*[field] LPI_PORT4_EN*/ + #define LPI_PORT4_EN + #define LPI_PORT4_EN_OFFSET 3 + #define LPI_PORT4_EN_LEN 1 + #define LPI_PORT4_EN_DEFAULT 0x0 + /*[field] LPI_PORT5_EN*/ + #define LPI_PORT5_EN + #define LPI_PORT5_EN_OFFSET 4 + #define LPI_PORT5_EN_LEN 1 + #define LPI_PORT5_EN_DEFAULT 0x0 + /*[field] LPI_LPI_PORT6_EN*/ + #define LPI_PORT6_EN + #define LPI_PORT6_EN_OFFSET 5 + #define LPI_PORT6_EN_LEN 1 + #define LPI_LPI_PORT6_EN_DEFAULT 0x0 +struct lpi_enable { + a_uint32_t lpi_port1_en:1; + a_uint32_t lpi_port2_en:1; + a_uint32_t lpi_port3_en:1; + a_uint32_t lpi_port4_en:1; + a_uint32_t lpi_port5_en:1; + a_uint32_t lpi_port6_en:1; + a_uint32_t _reserved0:26; +}; + +union lpi_enable_u { + a_uint32_t val; + struct lpi_enable bf; +}; + +/*[register] LPI_PORT_TIMER*/ +#define LPI_PORT_TIMER_ENABLE +#define LPI_PORT_TIMER_ADDRESS 0x0 +#define LPI_PORT_TIMER_NUM 6 +#define LPI_PORT_TIMER_INC 0x4 +#define LPI_PORT_TIMER_TYPE REG_TYPE_RW +#define LPI_PORT_TIMER_DEFAULT 0x0 + /*[field] LPI_PORT_WAKEUP_TIMER*/ + #define LPI_PORT_WAKEUP_TIMER + #define LPI_PORT_WAKEUP_TIMER_OFFSET 0 + #define LPI_PORT_WAKEUP_TIMER_LEN 16 + #define LPI_PORT_WAKEUP_TIMER_DEFAULT 0x0 + /*[field] LPI_PORT_SLEEP_TIMER*/ + #define LPI_PORT_SLEEP_TIMER + #define LPI_PORT_SLEEP_TIMER_OFFSET 16 + #define LPI_PORT_SLEEP_TIMER_LEN 16 + #define LPI_PORT_SLEEP_TIMER_DEFAULT 0x0 + +struct lpi_port_timer { + a_uint32_t lpi_port_wakeup_timer:16; + a_uint32_t lpi_port_sleep_timer:16; +}; + +union lpi_port_timer_u { + a_uint32_t val; + struct lpi_port_timer bf; +}; + +/*[register] LPI_DBG_ADDR*/ +#define LPI_DBG_ADDR +#define LPI_DBG_ADDR_ADDRESS 0x1C +#define LPI_DBG_ADDR_NUM 1 +#define LPI_DBG_ADDR_INC 0x1 +#define LPI_DBG_ADDR_TYPE REG_TYPE_RW +#define LPI_DBG_ADDR_DEFAULT 0x0 + /*[field] LPI_DBG_ADDR*/ + #define LPI_DBG_ADDR + #define IIP_DBG_ADDR_OFFSET 0 + #define LPI_DBG_ADDR_LEN 8 + #define LPI_DBG_ADDR_DEFAULT 0x0 + +struct lpi_dbg_addr { + a_uint32_t lpi_debug_addr:8; + a_uint32_t _reserved0:24; +}; + +union lpi_dbg_addr_u { + a_uint32_t val; + struct lpi_dbg_addr bf; +}; + +/*[register] LPI_DBG_DATA*/ +#define LPI_DBG_DATA +#define LPI_DBG_DATA_ADDRESS 0x20 +#define LPI_DBG_DATA_NUM 1 +#define LPI_DBG_DATA_INC 0x1 +#define LPI_DBG_DATA_TYPE REG_TYPE_RW +#define LPI_DBG_DATA_DEFAULT 0x0 + /*[field] LPI_DBG_DATA*/ + #define LPI_DBG_DATA + #define LPI_DBG_DATA_OFFSET 0 + #define LPI_DBG_DATA_LEN 32 + #define LPI_DBG_DATA_DEFAULT 0x0 + +struct lpi_dbg_data { + a_uint32_t lpi_debug_data:8; + a_uint32_t _reserved0:24; +}; + +union lpi_dbg_data_u { + a_uint32_t val; + struct lpi_dbg_data bf; +}; + +/*[register] LPI_CNT*/ +#define LPI_CNT +#define LPI_CNT_ADDRESS 0x30 +#define LPI_CNT_NUM 1 +#define LPI_CNT_INC 0x1 +#define LPI_CNT_TYPE REG_TYPE_RW +#define LPI_CNT_DEFAULT 0x0 + /*[field] LPI_CNT*/ + #define LPI_CNT + #define LPI_CNT_OFFSET 0 + #define LPI_CNT_LEN 9 + #define LPI_CNT_DEFAULT 0x0 + +struct lpi_cnt { + a_uint32_t lpi_cnt_val:9; + a_uint32_t _reserved0:23; +}; + +union lpi_cnt_u { + a_uint32_t val; + struct lpi_cnt bf; +}; + +/*[register] DROP_CNT*/ +#define DROP_CNT +#define DROP_CNT_ADDRESS 0x24 +#define DROP_CNT_NUM 8 +#define DROP_CNT_INC 0x4 +#define DROP_CNT_TYPE REG_TYPE_RW +#define DROP_CNT_DEFAULT 0x0 + /*[field] DROP_CNT*/ + #define DROP_CNT_DROP_CNT + #define DROP_CNT_DROP_CNT_OFFSET 0 + #define DROP_CNT_DROP_CNT_LEN 32 + #define DROP_CNT_DROP_CNT_DEFAULT 0x0 + +struct drop_cnt { + a_uint32_t drop_cnt:32; +}; + +union drop_cnt_u { + a_uint32_t val; + struct drop_cnt bf; +}; + +/*[register] IPR_PKT_NUM_TBL_REG*/ +#define IPR_PKT_NUM_TBL_REG +#define IPR_PKT_NUM_TBL_REG_ADDRESS 0x80 +#define IPR_PKT_NUM_TBL_REG_NUM 8 +#define IPR_PKT_NUM_TBL_REG_INC 0x4 +#define IPR_PKT_NUM_TBL_REG_TYPE REG_TYPE_RW +#define IPR_PKT_NUM_TBL_REG_DEFAULT 0x0 + /*[field] PACKETS*/ + #define IPR_PKT_NUM_TBL_REG_PACKETS + #define IPR_PKT_NUM_TBL_REG_PACKETS_OFFSET 0 + #define IPR_PKT_NUM_TBL_REG_PACKETS_LEN 32 + #define IPR_PKT_NUM_TBL_REG_PACKETS_DEFAULT 0x0 + +struct ipr_pkt_num_tbl_reg { + a_uint32_t packets:32; +}; + +union ipr_pkt_num_tbl_reg_u { + a_uint32_t val; + struct ipr_pkt_num_tbl_reg bf; +}; + +/*[register] IPR_BYTE_LOW_REG_REG*/ +#define IPR_BYTE_LOW_REG_REG +#define IPR_BYTE_LOW_REG_REG_ADDRESS 0xa0 +#define IPR_BYTE_LOW_REG_REG_NUM 8 +#define IPR_BYTE_LOW_REG_REG_INC 0x4 +#define IPR_BYTE_LOW_REG_REG_TYPE REG_TYPE_RW +#define IPR_BYTE_LOW_REG_REG_DEFAULT 0x0 + /*[field] BYTES*/ + #define IPR_BYTE_LOW_REG_REG_BYTES + #define IPR_BYTE_LOW_REG_REG_BYTES_OFFSET 0 + #define IPR_BYTE_LOW_REG_REG_BYTES_LEN 32 + #define IPR_BYTE_LOW_REG_REG_BYTES_DEFAULT 0x0 + +struct ipr_byte_low_reg_reg { + a_uint32_t bytes:32; +}; + +union ipr_byte_low_reg_reg_u { + a_uint32_t val; + struct ipr_byte_low_reg_reg bf; +}; + +/*[register] IPR_BYTE_HIGH_REG*/ +#define IPR_BYTE_HIGH_REG +#define IPR_BYTE_HIGH_REG_ADDRESS 0xc0 +#define IPR_BYTE_HIGH_REG_NUM 8 +#define IPR_BYTE_HIGH_REG_INC 0x4 +#define IPR_BYTE_HIGH_REG_TYPE REG_TYPE_RW +#define IPR_BYTE_HIGH_REG_DEFAULT 0x0 + /*[field] BYTES*/ + #define IPR_BYTE_HIGH_REG_BYTES + #define IPR_BYTE_HIGH_REG_BYTES_OFFSET 0 + #define IPR_BYTE_HIGH_REG_BYTES_LEN 32 + #define IPR_BYTE_HIGH_REG_BYTES_DEFAULT 0x0 + +struct ipr_byte_high_reg { + a_uint32_t bytes:32; +}; + +union ipr_byte_high_reg_u { + a_uint32_t val; + struct ipr_byte_high_reg bf; +}; + + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_portvlan.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_portvlan.h new file mode 100755 index 000000000..232ca4480 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_portvlan.h @@ -0,0 +1,1609 @@ +/* + * 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 + * @{ + */ +#ifndef _HPPE_PORTVLAN_H_ +#define _HPPE_PORTVLAN_H_ + +#include "hppe_portvlan_reg.h" + +#define XLT_RULE_TBL_MAX_ENTRY 64 +#define XLT_ACTION_TBL_MAX_ENTRY 64 +#define PORT_PARSING_REG_MAX_ENTRY 8 +#define EG_VLAN_XLT_RULE_MAX_ENTRY 64 +#define PORT_EG_DEF_VID_MAX_ENTRY 8 +#define PORT_EG_VLAN_MAX_ENTRY 8 +#define EG_VLAN_XLT_ACTION_MAX_ENTRY 64 + + +sw_error_t +hppe_port_parsing_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_parsing_reg_u *value); + +sw_error_t +hppe_port_parsing_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_parsing_reg_u *value); + +sw_error_t +hppe_vlan_tpid_reg_get( + a_uint32_t dev_id, + union vlan_tpid_reg_u *value); + +sw_error_t +hppe_vlan_tpid_reg_set( + a_uint32_t dev_id, + union vlan_tpid_reg_u *value); + +sw_error_t +hppe_port_parsing_reg_port_role_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_parsing_reg_port_role_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vlan_tpid_reg_stag_tpid_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_vlan_tpid_reg_stag_tpid_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_vlan_tpid_reg_ctag_tpid_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_vlan_tpid_reg_ctag_tpid_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_bridge_config_get( + a_uint32_t dev_id, + union bridge_config_u *value); + +sw_error_t +hppe_bridge_config_set( + a_uint32_t dev_id, + union bridge_config_u *value); + +sw_error_t +hppe_port_def_vid_get( + a_uint32_t dev_id, + a_uint32_t port_id, + union port_def_vid_u *value); + +sw_error_t +hppe_port_def_vid_set( + a_uint32_t dev_id, + a_uint32_t port_id, + union port_def_vid_u *value); + +sw_error_t +hppe_port_def_pcp_get( + a_uint32_t dev_id, + a_uint32_t port_id, + union port_def_pcp_u *value); + +sw_error_t +hppe_port_def_pcp_set( + a_uint32_t dev_id, + a_uint32_t port_id, + union port_def_pcp_u *value); + +sw_error_t +hppe_port_vlan_config_get( + a_uint32_t dev_id, + a_uint32_t port_id, + union port_vlan_config_u *value); + +sw_error_t +hppe_port_vlan_config_set( + a_uint32_t dev_id, + a_uint32_t port_id, + union port_vlan_config_u *value); + +sw_error_t +hppe_iv_dbg_addr_get( + a_uint32_t dev_id, + union iv_dbg_addr_u *value); + +sw_error_t +hppe_iv_dbg_addr_set( + a_uint32_t dev_id, + union iv_dbg_addr_u *value); + +sw_error_t +hppe_iv_dbg_data_get( + a_uint32_t dev_id, + union iv_dbg_data_u *value); + +sw_error_t +hppe_iv_dbg_data_set( + a_uint32_t dev_id, + union iv_dbg_data_u *value); + +sw_error_t +hppe_eco_reserve_get( + a_uint32_t dev_id, + union eco_reserve_u *value); + +sw_error_t +hppe_eco_reserve_set( + a_uint32_t dev_id, + union eco_reserve_u *value); + +sw_error_t +hppe_xlt_rule_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union xlt_rule_tbl_u *value); + +sw_error_t +hppe_xlt_rule_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union xlt_rule_tbl_u *value); + +sw_error_t +hppe_xlt_action_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union xlt_action_tbl_u *value); + +sw_error_t +hppe_xlt_action_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union xlt_action_tbl_u *value); + +sw_error_t +hppe_bridge_config_bridge_type_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_bridge_config_bridge_type_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_port_def_vid_port_def_cvid_en_get( + a_uint32_t dev_id, + a_uint32_t port_id, + unsigned int *value); + +sw_error_t +hppe_port_def_vid_port_def_cvid_en_set( + a_uint32_t dev_id, + a_uint32_t port_id, + unsigned int value); + +sw_error_t +hppe_port_def_vid_port_def_svid_en_get( + a_uint32_t dev_id, + a_uint32_t port_id, + unsigned int *value); + +sw_error_t +hppe_port_def_vid_port_def_svid_en_set( + a_uint32_t dev_id, + a_uint32_t port_id, + unsigned int value); + +sw_error_t +hppe_port_def_vid_port_def_cvid_get( + a_uint32_t dev_id, + a_uint32_t port_id, + unsigned int *value); + +sw_error_t +hppe_port_def_vid_port_def_cvid_set( + a_uint32_t dev_id, + a_uint32_t port_id, + unsigned int value); + +sw_error_t +hppe_port_def_vid_port_def_svid_get( + a_uint32_t dev_id, + a_uint32_t port_id, + unsigned int *value); + +sw_error_t +hppe_port_def_vid_port_def_svid_set( + a_uint32_t dev_id, + a_uint32_t port_id, + unsigned int value); + +sw_error_t +hppe_port_def_pcp_port_def_sdei_get( + a_uint32_t dev_id, + a_uint32_t port_id, + unsigned int *value); + +sw_error_t +hppe_port_def_pcp_port_def_sdei_set( + a_uint32_t dev_id, + a_uint32_t port_id, + unsigned int value); + +sw_error_t +hppe_port_def_pcp_port_def_spcp_get( + a_uint32_t dev_id, + a_uint32_t port_id, + unsigned int *value); + +sw_error_t +hppe_port_def_pcp_port_def_spcp_set( + a_uint32_t dev_id, + a_uint32_t port_id, + unsigned int value); + +sw_error_t +hppe_port_def_pcp_port_def_cdei_get( + a_uint32_t dev_id, + a_uint32_t port_id, + unsigned int *value); + +sw_error_t +hppe_port_def_pcp_port_def_cdei_set( + a_uint32_t dev_id, + a_uint32_t port_id, + unsigned int value); + +sw_error_t +hppe_port_def_pcp_port_def_cpcp_get( + a_uint32_t dev_id, + a_uint32_t port_id, + unsigned int *value); + +sw_error_t +hppe_port_def_pcp_port_def_cpcp_set( + a_uint32_t dev_id, + a_uint32_t port_id, + unsigned int value); + +sw_error_t +hppe_port_vlan_config_port_in_dei_prop_cmd_get( + a_uint32_t dev_id, + a_uint32_t port_id, + unsigned int *value); + +sw_error_t +hppe_port_vlan_config_port_in_dei_prop_cmd_set( + a_uint32_t dev_id, + a_uint32_t port_id, + unsigned int value); + +sw_error_t +hppe_port_vlan_config_port_in_pcp_prop_cmd_get( + a_uint32_t dev_id, + a_uint32_t port_id, + unsigned int *value); + +sw_error_t +hppe_port_vlan_config_port_in_pcp_prop_cmd_set( + a_uint32_t dev_id, + a_uint32_t port_id, + unsigned int value); + +sw_error_t +hppe_port_vlan_config_port_untag_fltr_cmd_get( + a_uint32_t dev_id, + a_uint32_t port_id, + unsigned int *value); + +sw_error_t +hppe_port_vlan_config_port_untag_fltr_cmd_set( + a_uint32_t dev_id, + a_uint32_t port_id, + unsigned int value); + +sw_error_t +hppe_port_vlan_config_port_in_vlan_fltr_cmd_get( + a_uint32_t dev_id, + a_uint32_t port_id, + unsigned int *value); + +sw_error_t +hppe_port_vlan_config_port_in_vlan_fltr_cmd_set( + a_uint32_t dev_id, + a_uint32_t port_id, + unsigned int value); + +sw_error_t +hppe_port_vlan_config_port_pri_tag_fltr_cmd_get( + a_uint32_t dev_id, + a_uint32_t port_id, + unsigned int *value); + +sw_error_t +hppe_port_vlan_config_port_pri_tag_fltr_cmd_set( + a_uint32_t dev_id, + a_uint32_t port_id, + unsigned int value); + +sw_error_t +hppe_port_vlan_config_port_vlan_xlt_miss_fwd_cmd_get( + a_uint32_t dev_id, + a_uint32_t port_id, + unsigned int *value); + +sw_error_t +hppe_port_vlan_config_port_vlan_xlt_miss_fwd_cmd_set( + a_uint32_t dev_id, + a_uint32_t port_id, + unsigned int value); + +sw_error_t +hppe_port_vlan_config_port_tag_fltr_cmd_get( + a_uint32_t dev_id, + a_uint32_t port_id, + unsigned int *value); + +sw_error_t +hppe_port_vlan_config_port_tag_fltr_cmd_set( + a_uint32_t dev_id, + a_uint32_t port_id, + unsigned int value); + +sw_error_t +hppe_iv_dbg_addr_dbg_addr_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_iv_dbg_addr_dbg_addr_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_iv_dbg_data_dbg_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_iv_dbg_data_dbg_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_eco_reserve_eco_res_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_eco_reserve_eco_res_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_xlt_rule_tbl_ckey_vid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_rule_tbl_ckey_vid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_rule_tbl_frm_type_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_rule_tbl_frm_type_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_rule_tbl_prot_value_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_rule_tbl_prot_value_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_rule_tbl_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_rule_tbl_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_rule_tbl_frm_type_incl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_rule_tbl_frm_type_incl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_rule_tbl_ckey_dei_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_rule_tbl_ckey_dei_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_rule_tbl_skey_dei_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_rule_tbl_skey_dei_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_rule_tbl_skey_pcp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_rule_tbl_skey_pcp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_rule_tbl_ckey_pcp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_rule_tbl_ckey_pcp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_rule_tbl_ckey_vid_incl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_rule_tbl_ckey_vid_incl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_rule_tbl_ckey_dei_incl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_rule_tbl_ckey_dei_incl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_rule_tbl_port_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_rule_tbl_port_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_rule_tbl_prot_incl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_rule_tbl_prot_incl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_rule_tbl_skey_pcp_incl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_rule_tbl_skey_pcp_incl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_rule_tbl_ckey_fmt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_rule_tbl_ckey_fmt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_rule_tbl_skey_vid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_rule_tbl_skey_vid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_rule_tbl_skey_fmt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_rule_tbl_skey_fmt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_rule_tbl_ckey_pcp_incl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_rule_tbl_ckey_pcp_incl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_rule_tbl_skey_dei_incl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_rule_tbl_skey_dei_incl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_rule_tbl_skey_vid_incl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_rule_tbl_skey_vid_incl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_action_tbl_dei_swap_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_action_tbl_dei_swap_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_action_tbl_xlt_cvid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_action_tbl_xlt_cvid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_action_tbl_xlt_cpcp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_action_tbl_xlt_cpcp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_action_tbl_xlt_spcp_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_action_tbl_xlt_spcp_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_action_tbl_xlt_sdei_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_action_tbl_xlt_sdei_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_action_tbl_xlt_cvid_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_action_tbl_xlt_cvid_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_action_tbl_vsi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_action_tbl_vsi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_action_tbl_xlt_spcp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_action_tbl_xlt_spcp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_action_tbl_counter_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_action_tbl_counter_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_action_tbl_vid_swap_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_action_tbl_vid_swap_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_action_tbl_xlt_sdei_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_action_tbl_xlt_sdei_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_action_tbl_counter_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_action_tbl_counter_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_action_tbl_xlt_svid_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_action_tbl_xlt_svid_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_action_tbl_xlt_svid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_action_tbl_xlt_svid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_action_tbl_vsi_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_action_tbl_vsi_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_action_tbl_xlt_cpcp_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_action_tbl_xlt_cpcp_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_action_tbl_xlt_cdei_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_action_tbl_xlt_cdei_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_action_tbl_pcp_swap_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_action_tbl_pcp_swap_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_xlt_action_tbl_xlt_cdei_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_xlt_action_tbl_xlt_cdei_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_rule_get( + a_uint32_t dev_id, + a_uint32_t index, + union eg_vlan_xlt_rule_u *value); + +sw_error_t +hppe_eg_vlan_xlt_rule_set( + a_uint32_t dev_id, + a_uint32_t index, + union eg_vlan_xlt_rule_u *value); + +sw_error_t +hppe_eg_vsi_tag_get( + a_uint32_t dev_id, + a_uint32_t index, + union eg_vsi_tag_u *value); + +sw_error_t +hppe_eg_vsi_tag_set( + a_uint32_t dev_id, + a_uint32_t index, + union eg_vsi_tag_u *value); + +sw_error_t +hppe_port_eg_def_vid_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_eg_def_vid_u *value); + +sw_error_t +hppe_port_eg_def_vid_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_eg_def_vid_u *value); + +sw_error_t +hppe_port_eg_vlan_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_eg_vlan_u *value); + +sw_error_t +hppe_port_eg_vlan_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_eg_vlan_u *value); + +sw_error_t +hppe_eg_vlan_tpid_get( + a_uint32_t dev_id, + union eg_vlan_tpid_u *value); + +sw_error_t +hppe_eg_vlan_tpid_set( + a_uint32_t dev_id, + union eg_vlan_tpid_u *value); + +sw_error_t +hppe_eg_bridge_config_get( + a_uint32_t dev_id, + union eg_bridge_config_u *value); + +sw_error_t +hppe_eg_bridge_config_set( + a_uint32_t dev_id, + union eg_bridge_config_u *value); + +sw_error_t +hppe_eg_vlan_xlt_action_get( + a_uint32_t dev_id, + a_uint32_t index, + union eg_vlan_xlt_action_u *value); + +sw_error_t +hppe_eg_vlan_xlt_action_set( + a_uint32_t dev_id, + a_uint32_t index, + union eg_vlan_xlt_action_u *value); + +sw_error_t +hppe_eg_vlan_xlt_rule_ckey_vid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_rule_ckey_vid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_rule_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_rule_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_rule_ckey_dei_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_rule_ckey_dei_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_rule_skey_dei_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_rule_skey_dei_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_rule_skey_pcp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_rule_skey_pcp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_rule_ckey_pcp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_rule_ckey_pcp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_rule_vsi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_rule_vsi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_rule_ckey_vid_incl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_rule_ckey_vid_incl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_rule_ckey_dei_incl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_rule_ckey_dei_incl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_rule_vsi_incl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_rule_vsi_incl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_rule_port_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_rule_port_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_rule_skey_pcp_incl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_rule_skey_pcp_incl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_rule_ckey_fmt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_rule_ckey_fmt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_rule_skey_vid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_rule_skey_vid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_rule_skey_fmt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_rule_skey_fmt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_rule_ckey_pcp_incl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_rule_ckey_pcp_incl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_rule_skey_vid_incl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_rule_skey_vid_incl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_rule_skey_dei_incl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_rule_skey_dei_incl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_rule_vsi_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_rule_vsi_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vsi_tag_tagged_mode_port_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vsi_tag_tagged_mode_port_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_eg_def_vid_port_def_svid_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_eg_def_vid_port_def_svid_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_eg_def_vid_port_def_svid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_eg_def_vid_port_def_svid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_eg_def_vid_port_def_cvid_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_eg_def_vid_port_def_cvid_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_eg_def_vid_port_def_cvid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_eg_def_vid_port_def_cvid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_eg_vlan_tx_counting_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_eg_vlan_tx_counting_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_eg_vlan_port_eg_vlan_ctag_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_eg_vlan_port_eg_vlan_ctag_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_eg_vlan_port_eg_pcp_prop_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_eg_vlan_port_eg_pcp_prop_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_eg_vlan_vsi_tag_mode_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_eg_vlan_vsi_tag_mode_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_eg_vlan_port_eg_vlan_stag_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_eg_vlan_port_eg_vlan_stag_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_eg_vlan_port_eg_dei_prop_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_eg_vlan_port_eg_dei_prop_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_eg_vlan_port_vlan_type_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_eg_vlan_port_vlan_type_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_tpid_ctpid_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_eg_vlan_tpid_ctpid_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_eg_vlan_tpid_stpid_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_eg_vlan_tpid_stpid_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_eg_bridge_config_bridge_type_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_eg_bridge_config_bridge_type_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_eg_bridge_config_queue_cnt_en_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_eg_bridge_config_queue_cnt_en_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_eg_vlan_xlt_action_dei_swap_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_action_dei_swap_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_cvid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_cvid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_cpcp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_cpcp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_spcp_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_spcp_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_sdei_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_sdei_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_cvid_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_cvid_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_spcp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_spcp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_action_counter_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_action_counter_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_action_vid_swap_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_action_vid_swap_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_sdei_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_sdei_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_action_counter_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_action_counter_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_svid_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_svid_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_svid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_svid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_cpcp_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_cpcp_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_cdei_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_cdei_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_action_pcp_swap_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_action_pcp_swap_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_cdei_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_cdei_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vlan_dev_tx_counter_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union vlan_dev_tx_counter_tbl_u *value); + +sw_error_t +hppe_vlan_dev_tx_counter_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union vlan_dev_tx_counter_tbl_u *value); + +sw_error_t +hppe_vlan_dev_tx_counter_tbl_tx_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_vlan_dev_tx_counter_tbl_tx_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_vlan_dev_tx_counter_tbl_tx_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vlan_dev_tx_counter_tbl_tx_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_portvlan_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_portvlan_reg.h new file mode 100755 index 000000000..5a918d9f5 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_portvlan_reg.h @@ -0,0 +1,1045 @@ +/* + * 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 + * @{ + */ +#ifndef HPPE_PORTVLAN_REG_H +#define HPPE_PORTVLAN_REG_H + +/*[register] PORT_PARSING_REG*/ +#define PORT_PARSING_REG +#define PORT_PARSING_REG_ADDRESS 0x0 +#define PORT_PARSING_REG_NUM 8 +#define PORT_PARSING_REG_INC 0x4 +#define PORT_PARSING_REG_TYPE REG_TYPE_RW +#define PORT_PARSING_REG_DEFAULT 0x0 + /*[field] PORT_ROLE*/ + #define PORT_PARSING_REG_PORT_ROLE + #define PORT_PARSING_REG_PORT_ROLE_OFFSET 0 + #define PORT_PARSING_REG_PORT_ROLE_LEN 1 + #define PORT_PARSING_REG_PORT_ROLE_DEFAULT 0x0 + +struct port_parsing_reg { + a_uint32_t port_role:1; + a_uint32_t _reserved0:31; +}; + +union port_parsing_reg_u { + a_uint32_t val; + struct port_parsing_reg bf; +}; + +/*[register] VLAN_TPID_REG*/ +#define VLAN_TPID_REG +#define VLAN_TPID_REG_ADDRESS 0x20 +#define VLAN_TPID_REG_NUM 1 +#define VLAN_TPID_REG_INC 0x4 +#define VLAN_TPID_REG_TYPE REG_TYPE_RW +#define VLAN_TPID_REG_DEFAULT 0x88a88100 + /*[field] CTAG_TPID*/ + #define VLAN_TPID_REG_CTAG_TPID + #define VLAN_TPID_REG_CTAG_TPID_OFFSET 0 + #define VLAN_TPID_REG_CTAG_TPID_LEN 16 + #define VLAN_TPID_REG_CTAG_TPID_DEFAULT 0x8100 + /*[field] STAG_TPID*/ + #define VLAN_TPID_REG_STAG_TPID + #define VLAN_TPID_REG_STAG_TPID_OFFSET 16 + #define VLAN_TPID_REG_STAG_TPID_LEN 16 + #define VLAN_TPID_REG_STAG_TPID_DEFAULT 0x88a8 + +struct vlan_tpid_reg { + a_uint32_t ctag_tpid:16; + a_uint32_t stag_tpid:16; +}; + +union vlan_tpid_reg_u { + a_uint32_t val; + struct vlan_tpid_reg bf; +}; + +/*[register] BRIDGE_CONFIG*/ +#define BRIDGE_CONFIG +#define BRIDGE_CONFIG_ADDRESS 0x0 +#define BRIDGE_CONFIG_NUM 1 +#define BRIDGE_CONFIG_INC 0x4 +#define BRIDGE_CONFIG_TYPE REG_TYPE_RW +#define BRIDGE_CONFIG_DEFAULT 0x0 + /*[field] BRIDGE_TYPE*/ + #define BRIDGE_CONFIG_BRIDGE_TYPE + #define BRIDGE_CONFIG_BRIDGE_TYPE_OFFSET 0 + #define BRIDGE_CONFIG_BRIDGE_TYPE_LEN 1 + #define BRIDGE_CONFIG_BRIDGE_TYPE_DEFAULT 0x0 + +struct bridge_config { + a_uint32_t bridge_type:1; + a_uint32_t _reserved0:31; +}; + +union bridge_config_u { + a_uint32_t val; + struct bridge_config bf; +}; + +/*[register] PORT_DEF_VID*/ +#define PORT_DEF_VID +#define PORT_DEF_VID_ADDRESS 0x10 +#define PORT_DEF_VID_NUM 1 +#define PORT_DEF_VID_INC 0x4 +#define PORT_DEF_VID_TYPE REG_TYPE_RW +#define PORT_DEF_VID_DEFAULT 0x0 + /*[field] PORT_DEF_SVID*/ + #define PORT_DEF_VID_PORT_DEF_SVID + #define PORT_DEF_VID_PORT_DEF_SVID_OFFSET 0 + #define PORT_DEF_VID_PORT_DEF_SVID_LEN 12 + #define PORT_DEF_VID_PORT_DEF_SVID_DEFAULT 0x0 + /*[field] PORT_DEF_SVID_EN*/ + #define PORT_DEF_VID_PORT_DEF_SVID_EN + #define PORT_DEF_VID_PORT_DEF_SVID_EN_OFFSET 12 + #define PORT_DEF_VID_PORT_DEF_SVID_EN_LEN 1 + #define PORT_DEF_VID_PORT_DEF_SVID_EN_DEFAULT 0x0 + /*[field] PORT_DEF_CVID*/ + #define PORT_DEF_VID_PORT_DEF_CVID + #define PORT_DEF_VID_PORT_DEF_CVID_OFFSET 16 + #define PORT_DEF_VID_PORT_DEF_CVID_LEN 12 + #define PORT_DEF_VID_PORT_DEF_CVID_DEFAULT 0x0 + /*[field] PORT_DEF_CVID_EN*/ + #define PORT_DEF_VID_PORT_DEF_CVID_EN + #define PORT_DEF_VID_PORT_DEF_CVID_EN_OFFSET 28 + #define PORT_DEF_VID_PORT_DEF_CVID_EN_LEN 1 + #define PORT_DEF_VID_PORT_DEF_CVID_EN_DEFAULT 0x0 + +struct port_def_vid { + a_uint32_t port_def_svid:12; + a_uint32_t port_def_svid_en:1; + a_uint32_t _reserved0:3; + a_uint32_t port_def_cvid:12; + a_uint32_t port_def_cvid_en:1; + a_uint32_t _reserved1:3; +}; + +union port_def_vid_u { + a_uint32_t val; + struct port_def_vid bf; +}; + +/*[register] PORT_DEF_PCP*/ +#define PORT_DEF_PCP +#define PORT_DEF_PCP_ADDRESS 0x30 +#define PORT_DEF_PCP_NUM 1 +#define PORT_DEF_PCP_INC 0x4 +#define PORT_DEF_PCP_TYPE REG_TYPE_RW +#define PORT_DEF_PCP_DEFAULT 0x0 + /*[field] PORT_DEF_SPCP*/ + #define PORT_DEF_PCP_PORT_DEF_SPCP + #define PORT_DEF_PCP_PORT_DEF_SPCP_OFFSET 0 + #define PORT_DEF_PCP_PORT_DEF_SPCP_LEN 3 + #define PORT_DEF_PCP_PORT_DEF_SPCP_DEFAULT 0x0 + /*[field] PORT_DEF_SDEI*/ + #define PORT_DEF_PCP_PORT_DEF_SDEI + #define PORT_DEF_PCP_PORT_DEF_SDEI_OFFSET 3 + #define PORT_DEF_PCP_PORT_DEF_SDEI_LEN 1 + #define PORT_DEF_PCP_PORT_DEF_SDEI_DEFAULT 0x0 + /*[field] PORT_DEF_CPCP*/ + #define PORT_DEF_PCP_PORT_DEF_CPCP + #define PORT_DEF_PCP_PORT_DEF_CPCP_OFFSET 4 + #define PORT_DEF_PCP_PORT_DEF_CPCP_LEN 3 + #define PORT_DEF_PCP_PORT_DEF_CPCP_DEFAULT 0x0 + /*[field] PORT_DEF_CDEI*/ + #define PORT_DEF_PCP_PORT_DEF_CDEI + #define PORT_DEF_PCP_PORT_DEF_CDEI_OFFSET 7 + #define PORT_DEF_PCP_PORT_DEF_CDEI_LEN 1 + #define PORT_DEF_PCP_PORT_DEF_CDEI_DEFAULT 0x0 + +struct port_def_pcp { + a_uint32_t port_def_spcp:3; + a_uint32_t port_def_sdei:1; + a_uint32_t port_def_cpcp:3; + a_uint32_t port_def_cdei:1; + a_uint32_t _reserved0:24; +}; + +union port_def_pcp_u { + a_uint32_t val; + struct port_def_pcp bf; +}; + +/*[register] PORT_VLAN_CONFIG*/ +#define PORT_VLAN_CONFIG +#define PORT_VLAN_CONFIG_ADDRESS 0x50 +#define PORT_VLAN_CONFIG_NUM 1 +#define PORT_VLAN_CONFIG_INC 0x4 +#define PORT_VLAN_CONFIG_TYPE REG_TYPE_RW +#define PORT_VLAN_CONFIG_DEFAULT 0x0 + /*[field] PORT_IN_PCP_PROP_CMD*/ + #define PORT_VLAN_CONFIG_PORT_IN_PCP_PROP_CMD + #define PORT_VLAN_CONFIG_PORT_IN_PCP_PROP_CMD_OFFSET 0 + #define PORT_VLAN_CONFIG_PORT_IN_PCP_PROP_CMD_LEN 1 + #define PORT_VLAN_CONFIG_PORT_IN_PCP_PROP_CMD_DEFAULT 0x0 + /*[field] PORT_IN_DEI_PROP_CMD*/ + #define PORT_VLAN_CONFIG_PORT_IN_DEI_PROP_CMD + #define PORT_VLAN_CONFIG_PORT_IN_DEI_PROP_CMD_OFFSET 1 + #define PORT_VLAN_CONFIG_PORT_IN_DEI_PROP_CMD_LEN 1 + #define PORT_VLAN_CONFIG_PORT_IN_DEI_PROP_CMD_DEFAULT 0x0 + /*[field] PORT_UNTAG_FLTR_CMD*/ + #define PORT_VLAN_CONFIG_PORT_UNTAG_FLTR_CMD + #define PORT_VLAN_CONFIG_PORT_UNTAG_FLTR_CMD_OFFSET 2 + #define PORT_VLAN_CONFIG_PORT_UNTAG_FLTR_CMD_LEN 1 + #define PORT_VLAN_CONFIG_PORT_UNTAG_FLTR_CMD_DEFAULT 0x0 + /*[field] PORT_PRI_TAG_FLTR_CMD*/ + #define PORT_VLAN_CONFIG_PORT_PRI_TAG_FLTR_CMD + #define PORT_VLAN_CONFIG_PORT_PRI_TAG_FLTR_CMD_OFFSET 3 + #define PORT_VLAN_CONFIG_PORT_PRI_TAG_FLTR_CMD_LEN 1 + #define PORT_VLAN_CONFIG_PORT_PRI_TAG_FLTR_CMD_DEFAULT 0x0 + /*[field] PORT_TAG_FLTR_CMD*/ + #define PORT_VLAN_CONFIG_PORT_TAG_FLTR_CMD + #define PORT_VLAN_CONFIG_PORT_TAG_FLTR_CMD_OFFSET 4 + #define PORT_VLAN_CONFIG_PORT_TAG_FLTR_CMD_LEN 1 + #define PORT_VLAN_CONFIG_PORT_TAG_FLTR_CMD_DEFAULT 0x0 + /*[field] PORT_VLAN_XLT_MISS_FWD_CMD*/ + #define PORT_VLAN_CONFIG_PORT_VLAN_XLT_MISS_FWD_CMD + #define PORT_VLAN_CONFIG_PORT_VLAN_XLT_MISS_FWD_CMD_OFFSET 5 + #define PORT_VLAN_CONFIG_PORT_VLAN_XLT_MISS_FWD_CMD_LEN 2 + #define PORT_VLAN_CONFIG_PORT_VLAN_XLT_MISS_FWD_CMD_DEFAULT 0x0 + /*[field] PORT_IN_VLAN_FLTR_CMD*/ + #define PORT_VLAN_CONFIG_PORT_IN_VLAN_FLTR_CMD + #define PORT_VLAN_CONFIG_PORT_IN_VLAN_FLTR_CMD_OFFSET 7 + #define PORT_VLAN_CONFIG_PORT_IN_VLAN_FLTR_CMD_LEN 1 + #define PORT_VLAN_CONFIG_PORT_IN_VLAN_FLTR_CMD_DEFAULT 0x0 + +struct port_vlan_config { + a_uint32_t port_in_pcp_prop_cmd:1; + a_uint32_t port_in_dei_prop_cmd:1; + a_uint32_t port_untag_fltr_cmd:1; + a_uint32_t port_pri_tag_fltr_cmd:1; + a_uint32_t port_tag_fltr_cmd:1; + a_uint32_t port_vlan_xlt_miss_fwd_cmd:2; + a_uint32_t port_in_vlan_fltr_cmd:1; + a_uint32_t _reserved0:24; +}; + +union port_vlan_config_u { + a_uint32_t val; + struct port_vlan_config bf; +}; + +/*[register] IV_DBG_ADDR*/ +#define IV_DBG_ADDR +#define IV_DBG_ADDR_ADDRESS 0x70 +#define IV_DBG_ADDR_NUM 1 +#define IV_DBG_ADDR_INC 0x4 +#define IV_DBG_ADDR_TYPE REG_TYPE_RW +#define IV_DBG_ADDR_DEFAULT 0x0 + /*[field] DBG_ADDR*/ + #define IV_DBG_ADDR_DBG_ADDR + #define IV_DBG_ADDR_DBG_ADDR_OFFSET 0 + #define IV_DBG_ADDR_DBG_ADDR_LEN 8 + #define IV_DBG_ADDR_DBG_ADDR_DEFAULT 0x0 + +struct iv_dbg_addr { + a_uint32_t dbg_addr:8; + a_uint32_t _reserved0:24; +}; + +union iv_dbg_addr_u { + a_uint32_t val; + struct iv_dbg_addr bf; +}; + +/*[register] IV_DBG_DATA*/ +#define IV_DBG_DATA +#define IV_DBG_DATA_ADDRESS 0x74 +#define IV_DBG_DATA_NUM 1 +#define IV_DBG_DATA_INC 0x4 +#define IV_DBG_DATA_TYPE REG_TYPE_RO +#define IV_DBG_DATA_DEFAULT 0x0 + /*[field] DBG_DATA*/ + #define IV_DBG_DATA_DBG_DATA + #define IV_DBG_DATA_DBG_DATA_OFFSET 0 + #define IV_DBG_DATA_DBG_DATA_LEN 32 + #define IV_DBG_DATA_DBG_DATA_DEFAULT 0x0 + +struct iv_dbg_data { + a_uint32_t dbg_data:32; +}; + +union iv_dbg_data_u { + a_uint32_t val; + struct iv_dbg_data bf; +}; + +/*[register] ECO_RESERVE*/ +#define ECO_RESERVE +#define ECO_RESERVE_ADDRESS 0x78 +#define ECO_RESERVE_NUM 1 +#define ECO_RESERVE_INC 0x4 +#define ECO_RESERVE_TYPE REG_TYPE_RW +#define ECO_RESERVE_DEFAULT 0x0 + /*[field] ECO_RES*/ + #define ECO_RESERVE_ECO_RES + #define ECO_RESERVE_ECO_RES_OFFSET 0 + #define ECO_RESERVE_ECO_RES_LEN 32 + #define ECO_RESERVE_ECO_RES_DEFAULT 0x0 + +struct eco_reserve { + a_uint32_t eco_res:32; +}; + +union eco_reserve_u { + a_uint32_t val; + struct eco_reserve bf; +}; + +/*[table] XLT_RULE_TBL*/ +#define XLT_RULE_TBL +#define XLT_RULE_TBL_ADDRESS 0x2000 +#define XLT_RULE_TBL_NUM 64 +#define XLT_RULE_TBL_INC 0x10 +#define XLT_RULE_TBL_TYPE REG_TYPE_RW +#define XLT_RULE_TBL_DEFAULT 0x0 + /*[field] VALID*/ + #define XLT_RULE_TBL_VALID + #define XLT_RULE_TBL_VALID_OFFSET 0 + #define XLT_RULE_TBL_VALID_LEN 1 + #define XLT_RULE_TBL_VALID_DEFAULT 0x0 + /*[field] PORT_BITMAP*/ + #define XLT_RULE_TBL_PORT_BITMAP + #define XLT_RULE_TBL_PORT_BITMAP_OFFSET 1 + #define XLT_RULE_TBL_PORT_BITMAP_LEN 8 + #define XLT_RULE_TBL_PORT_BITMAP_DEFAULT 0x0 + /*[field] SKEY_FMT*/ + #define XLT_RULE_TBL_SKEY_FMT + #define XLT_RULE_TBL_SKEY_FMT_OFFSET 9 + #define XLT_RULE_TBL_SKEY_FMT_LEN 3 + #define XLT_RULE_TBL_SKEY_FMT_DEFAULT 0x0 + /*[field] SKEY_VID_INCL*/ + #define XLT_RULE_TBL_SKEY_VID_INCL + #define XLT_RULE_TBL_SKEY_VID_INCL_OFFSET 12 + #define XLT_RULE_TBL_SKEY_VID_INCL_LEN 1 + #define XLT_RULE_TBL_SKEY_VID_INCL_DEFAULT 0x0 + /*[field] SKEY_VID*/ + #define XLT_RULE_TBL_SKEY_VID + #define XLT_RULE_TBL_SKEY_VID_OFFSET 13 + #define XLT_RULE_TBL_SKEY_VID_LEN 12 + #define XLT_RULE_TBL_SKEY_VID_DEFAULT 0x0 + /*[field] SKEY_PCP_INCL*/ + #define XLT_RULE_TBL_SKEY_PCP_INCL + #define XLT_RULE_TBL_SKEY_PCP_INCL_OFFSET 25 + #define XLT_RULE_TBL_SKEY_PCP_INCL_LEN 1 + #define XLT_RULE_TBL_SKEY_PCP_INCL_DEFAULT 0x0 + /*[field] SKEY_PCP*/ + #define XLT_RULE_TBL_SKEY_PCP + #define XLT_RULE_TBL_SKEY_PCP_OFFSET 26 + #define XLT_RULE_TBL_SKEY_PCP_LEN 3 + #define XLT_RULE_TBL_SKEY_PCP_DEFAULT 0x0 + /*[field] SKEY_DEI_INCL*/ + #define XLT_RULE_TBL_SKEY_DEI_INCL + #define XLT_RULE_TBL_SKEY_DEI_INCL_OFFSET 29 + #define XLT_RULE_TBL_SKEY_DEI_INCL_LEN 1 + #define XLT_RULE_TBL_SKEY_DEI_INCL_DEFAULT 0x0 + /*[field] SKEY_DEI*/ + #define XLT_RULE_TBL_SKEY_DEI + #define XLT_RULE_TBL_SKEY_DEI_OFFSET 30 + #define XLT_RULE_TBL_SKEY_DEI_LEN 1 + #define XLT_RULE_TBL_SKEY_DEI_DEFAULT 0x0 + /*[field] CKEY_FMT*/ + #define XLT_RULE_TBL_CKEY_FMT + #define XLT_RULE_TBL_CKEY_FMT_OFFSET 31 + #define XLT_RULE_TBL_CKEY_FMT_LEN 3 + #define XLT_RULE_TBL_CKEY_FMT_DEFAULT 0x0 + /*[field] CKEY_VID_INCL*/ + #define XLT_RULE_TBL_CKEY_VID_INCL + #define XLT_RULE_TBL_CKEY_VID_INCL_OFFSET 34 + #define XLT_RULE_TBL_CKEY_VID_INCL_LEN 1 + #define XLT_RULE_TBL_CKEY_VID_INCL_DEFAULT 0x0 + /*[field] CKEY_VID*/ + #define XLT_RULE_TBL_CKEY_VID + #define XLT_RULE_TBL_CKEY_VID_OFFSET 35 + #define XLT_RULE_TBL_CKEY_VID_LEN 12 + #define XLT_RULE_TBL_CKEY_VID_DEFAULT 0x0 + /*[field] CKEY_PCP_INCL*/ + #define XLT_RULE_TBL_CKEY_PCP_INCL + #define XLT_RULE_TBL_CKEY_PCP_INCL_OFFSET 47 + #define XLT_RULE_TBL_CKEY_PCP_INCL_LEN 1 + #define XLT_RULE_TBL_CKEY_PCP_INCL_DEFAULT 0x0 + /*[field] CKEY_PCP*/ + #define XLT_RULE_TBL_CKEY_PCP + #define XLT_RULE_TBL_CKEY_PCP_OFFSET 48 + #define XLT_RULE_TBL_CKEY_PCP_LEN 3 + #define XLT_RULE_TBL_CKEY_PCP_DEFAULT 0x0 + /*[field] CKEY_DEI_INCL*/ + #define XLT_RULE_TBL_CKEY_DEI_INCL + #define XLT_RULE_TBL_CKEY_DEI_INCL_OFFSET 51 + #define XLT_RULE_TBL_CKEY_DEI_INCL_LEN 1 + #define XLT_RULE_TBL_CKEY_DEI_INCL_DEFAULT 0x0 + /*[field] CKEY_DEI*/ + #define XLT_RULE_TBL_CKEY_DEI + #define XLT_RULE_TBL_CKEY_DEI_OFFSET 52 + #define XLT_RULE_TBL_CKEY_DEI_LEN 1 + #define XLT_RULE_TBL_CKEY_DEI_DEFAULT 0x0 + /*[field] FRM_TYPE_INCL*/ + #define XLT_RULE_TBL_FRM_TYPE_INCL + #define XLT_RULE_TBL_FRM_TYPE_INCL_OFFSET 53 + #define XLT_RULE_TBL_FRM_TYPE_INCL_LEN 1 + #define XLT_RULE_TBL_FRM_TYPE_INCL_DEFAULT 0x0 + /*[field] FRM_TYPE*/ + #define XLT_RULE_TBL_FRM_TYPE + #define XLT_RULE_TBL_FRM_TYPE_OFFSET 54 + #define XLT_RULE_TBL_FRM_TYPE_LEN 2 + #define XLT_RULE_TBL_FRM_TYPE_DEFAULT 0x0 + /*[field] PROT_INCL*/ + #define XLT_RULE_TBL_PROT_INCL + #define XLT_RULE_TBL_PROT_INCL_OFFSET 56 + #define XLT_RULE_TBL_PROT_INCL_LEN 1 + #define XLT_RULE_TBL_PROT_INCL_DEFAULT 0x0 + /*[field] PROT_VALUE*/ + #define XLT_RULE_TBL_PROT_VALUE + #define XLT_RULE_TBL_PROT_VALUE_OFFSET 57 + #define XLT_RULE_TBL_PROT_VALUE_LEN 16 + #define XLT_RULE_TBL_PROT_VALUE_DEFAULT 0x0 + +struct xlt_rule_tbl { + a_uint32_t valid:1; + a_uint32_t port_bitmap:8; + a_uint32_t skey_fmt:3; + a_uint32_t skey_vid_incl:1; + a_uint32_t skey_vid:12; + a_uint32_t skey_pcp_incl:1; + a_uint32_t skey_pcp:3; + a_uint32_t skey_dei_incl:1; + a_uint32_t skey_dei:1; + a_uint32_t ckey_fmt_0:1; + a_uint32_t ckey_fmt_1:2; + a_uint32_t ckey_vid_incl:1; + a_uint32_t ckey_vid:12; + a_uint32_t ckey_pcp_incl:1; + a_uint32_t ckey_pcp:3; + a_uint32_t ckey_dei_incl:1; + a_uint32_t ckey_dei:1; + a_uint32_t frm_type_incl:1; + a_uint32_t frm_type:2; + a_uint32_t prot_incl:1; + a_uint32_t prot_value_0:7; + a_uint32_t prot_value_1:9; + a_uint32_t _reserved0:23; +}; + +union xlt_rule_tbl_u { + a_uint32_t val[3]; + struct xlt_rule_tbl bf; +}; + +/*[table] XLT_ACTION_TBL*/ +#define XLT_ACTION_TBL +#define XLT_ACTION_TBL_ADDRESS 0x4000 +#define XLT_ACTION_TBL_NUM 64 +#define XLT_ACTION_TBL_INC 0x10 +#define XLT_ACTION_TBL_TYPE REG_TYPE_RW +#define XLT_ACTION_TBL_DEFAULT 0x0 + /*[field] VID_SWAP_CMD*/ + #define XLT_ACTION_TBL_VID_SWAP_CMD + #define XLT_ACTION_TBL_VID_SWAP_CMD_OFFSET 0 + #define XLT_ACTION_TBL_VID_SWAP_CMD_LEN 1 + #define XLT_ACTION_TBL_VID_SWAP_CMD_DEFAULT 0x0 + /*[field] XLT_SVID_CMD*/ + #define XLT_ACTION_TBL_XLT_SVID_CMD + #define XLT_ACTION_TBL_XLT_SVID_CMD_OFFSET 1 + #define XLT_ACTION_TBL_XLT_SVID_CMD_LEN 2 + #define XLT_ACTION_TBL_XLT_SVID_CMD_DEFAULT 0x0 + /*[field] XLT_SVID*/ + #define XLT_ACTION_TBL_XLT_SVID + #define XLT_ACTION_TBL_XLT_SVID_OFFSET 3 + #define XLT_ACTION_TBL_XLT_SVID_LEN 12 + #define XLT_ACTION_TBL_XLT_SVID_DEFAULT 0x0 + /*[field] XLT_CVID_CMD*/ + #define XLT_ACTION_TBL_XLT_CVID_CMD + #define XLT_ACTION_TBL_XLT_CVID_CMD_OFFSET 15 + #define XLT_ACTION_TBL_XLT_CVID_CMD_LEN 2 + #define XLT_ACTION_TBL_XLT_CVID_CMD_DEFAULT 0x0 + /*[field] XLT_CVID*/ + #define XLT_ACTION_TBL_XLT_CVID + #define XLT_ACTION_TBL_XLT_CVID_OFFSET 17 + #define XLT_ACTION_TBL_XLT_CVID_LEN 12 + #define XLT_ACTION_TBL_XLT_CVID_DEFAULT 0x0 + /*[field] PCP_SWAP_CMD*/ + #define XLT_ACTION_TBL_PCP_SWAP_CMD + #define XLT_ACTION_TBL_PCP_SWAP_CMD_OFFSET 29 + #define XLT_ACTION_TBL_PCP_SWAP_CMD_LEN 1 + #define XLT_ACTION_TBL_PCP_SWAP_CMD_DEFAULT 0x0 + /*[field] XLT_SPCP_CMD*/ + #define XLT_ACTION_TBL_XLT_SPCP_CMD + #define XLT_ACTION_TBL_XLT_SPCP_CMD_OFFSET 30 + #define XLT_ACTION_TBL_XLT_SPCP_CMD_LEN 1 + #define XLT_ACTION_TBL_XLT_SPCP_CMD_DEFAULT 0x0 + /*[field] XLT_SPCP*/ + #define XLT_ACTION_TBL_XLT_SPCP + #define XLT_ACTION_TBL_XLT_SPCP_OFFSET 31 + #define XLT_ACTION_TBL_XLT_SPCP_LEN 3 + #define XLT_ACTION_TBL_XLT_SPCP_DEFAULT 0x0 + /*[field] XLT_CPCP_CMD*/ + #define XLT_ACTION_TBL_XLT_CPCP_CMD + #define XLT_ACTION_TBL_XLT_CPCP_CMD_OFFSET 34 + #define XLT_ACTION_TBL_XLT_CPCP_CMD_LEN 1 + #define XLT_ACTION_TBL_XLT_CPCP_CMD_DEFAULT 0x0 + /*[field] XLT_CPCP*/ + #define XLT_ACTION_TBL_XLT_CPCP + #define XLT_ACTION_TBL_XLT_CPCP_OFFSET 35 + #define XLT_ACTION_TBL_XLT_CPCP_LEN 3 + #define XLT_ACTION_TBL_XLT_CPCP_DEFAULT 0x0 + /*[field] DEI_SWAP_CMD*/ + #define XLT_ACTION_TBL_DEI_SWAP_CMD + #define XLT_ACTION_TBL_DEI_SWAP_CMD_OFFSET 38 + #define XLT_ACTION_TBL_DEI_SWAP_CMD_LEN 1 + #define XLT_ACTION_TBL_DEI_SWAP_CMD_DEFAULT 0x0 + /*[field] XLT_SDEI_CMD*/ + #define XLT_ACTION_TBL_XLT_SDEI_CMD + #define XLT_ACTION_TBL_XLT_SDEI_CMD_OFFSET 39 + #define XLT_ACTION_TBL_XLT_SDEI_CMD_LEN 1 + #define XLT_ACTION_TBL_XLT_SDEI_CMD_DEFAULT 0x0 + /*[field] XLT_SDEI*/ + #define XLT_ACTION_TBL_XLT_SDEI + #define XLT_ACTION_TBL_XLT_SDEI_OFFSET 40 + #define XLT_ACTION_TBL_XLT_SDEI_LEN 1 + #define XLT_ACTION_TBL_XLT_SDEI_DEFAULT 0x0 + /*[field] XLT_CDEI_CMD*/ + #define XLT_ACTION_TBL_XLT_CDEI_CMD + #define XLT_ACTION_TBL_XLT_CDEI_CMD_OFFSET 41 + #define XLT_ACTION_TBL_XLT_CDEI_CMD_LEN 1 + #define XLT_ACTION_TBL_XLT_CDEI_CMD_DEFAULT 0x0 + /*[field] XLT_CDEI*/ + #define XLT_ACTION_TBL_XLT_CDEI + #define XLT_ACTION_TBL_XLT_CDEI_OFFSET 42 + #define XLT_ACTION_TBL_XLT_CDEI_LEN 1 + #define XLT_ACTION_TBL_XLT_CDEI_DEFAULT 0x0 + /*[field] VSI_CMD*/ + #define XLT_ACTION_TBL_VSI_CMD + #define XLT_ACTION_TBL_VSI_CMD_OFFSET 43 + #define XLT_ACTION_TBL_VSI_CMD_LEN 1 + #define XLT_ACTION_TBL_VSI_CMD_DEFAULT 0x0 + /*[field] VSI*/ + #define XLT_ACTION_TBL_VSI + #define XLT_ACTION_TBL_VSI_OFFSET 44 + #define XLT_ACTION_TBL_VSI_LEN 5 + #define XLT_ACTION_TBL_VSI_DEFAULT 0x0 + /*[field] COUNTER_EN*/ + #define XLT_ACTION_TBL_COUNTER_EN + #define XLT_ACTION_TBL_COUNTER_EN_OFFSET 49 + #define XLT_ACTION_TBL_COUNTER_EN_LEN 1 + #define XLT_ACTION_TBL_COUNTER_EN_DEFAULT 0x0 + /*[field] COUNTER_ID*/ + #define XLT_ACTION_TBL_COUNTER_ID + #define XLT_ACTION_TBL_COUNTER_ID_OFFSET 50 + #define XLT_ACTION_TBL_COUNTER_ID_LEN 6 + #define XLT_ACTION_TBL_COUNTER_ID_DEFAULT 0x0 + +struct xlt_action_tbl { + a_uint32_t vid_swap_cmd:1; + a_uint32_t xlt_svid_cmd:2; + a_uint32_t xlt_svid:12; + a_uint32_t xlt_cvid_cmd:2; + a_uint32_t xlt_cvid:12; + a_uint32_t pcp_swap_cmd:1; + a_uint32_t xlt_spcp_cmd:1; + a_uint32_t xlt_spcp_0:1; + a_uint32_t xlt_spcp_1:2; + a_uint32_t xlt_cpcp_cmd:1; + a_uint32_t xlt_cpcp:3; + a_uint32_t dei_swap_cmd:1; + a_uint32_t xlt_sdei_cmd:1; + a_uint32_t xlt_sdei:1; + a_uint32_t xlt_cdei_cmd:1; + a_uint32_t xlt_cdei:1; + a_uint32_t vsi_cmd:1; + a_uint32_t vsi:5; + a_uint32_t counter_en:1; + a_uint32_t counter_id:6; + a_uint32_t _reserved0:8; +}; + +union xlt_action_tbl_u { + a_uint32_t val[2]; + struct xlt_action_tbl bf; +}; + +/*[table] EG_VLAN_XLT_RULE*/ +#define EG_VLAN_XLT_RULE +#define EG_VLAN_XLT_RULE_ADDRESS 0x200 +#define EG_VLAN_XLT_RULE_NUM 64 +#define EG_VLAN_XLT_RULE_INC 0x8 +#define EG_VLAN_XLT_RULE_TYPE REG_TYPE_RW +#define EG_VLAN_XLT_RULE_DEFAULT 0x0 + /*[field] VALID*/ + #define EG_VLAN_XLT_RULE_VALID + #define EG_VLAN_XLT_RULE_VALID_OFFSET 0 + #define EG_VLAN_XLT_RULE_VALID_LEN 1 + #define EG_VLAN_XLT_RULE_VALID_DEFAULT 0x0 + /*[field] PORT_BITMAP*/ + #define EG_VLAN_XLT_RULE_PORT_BITMAP + #define EG_VLAN_XLT_RULE_PORT_BITMAP_OFFSET 1 + #define EG_VLAN_XLT_RULE_PORT_BITMAP_LEN 8 + #define EG_VLAN_XLT_RULE_PORT_BITMAP_DEFAULT 0x0 + /*[field] VSI_INCL*/ + #define EG_VLAN_XLT_RULE_VSI_INCL + #define EG_VLAN_XLT_RULE_VSI_INCL_OFFSET 9 + #define EG_VLAN_XLT_RULE_VSI_INCL_LEN 1 + #define EG_VLAN_XLT_RULE_VSI_INCL_DEFAULT 0x0 + /*[field] VSI*/ + #define EG_VLAN_XLT_RULE_VSI + #define EG_VLAN_XLT_RULE_VSI_OFFSET 10 + #define EG_VLAN_XLT_RULE_VSI_LEN 5 + #define EG_VLAN_XLT_RULE_VSI_DEFAULT 0x0 + /*[field] VSI_VALID*/ + #define EG_VLAN_XLT_RULE_VSI_VALID + #define EG_VLAN_XLT_RULE_VSI_VALID_OFFSET 15 + #define EG_VLAN_XLT_RULE_VSI_VALID_LEN 1 + #define EG_VLAN_XLT_RULE_VSI_VALID_DEFAULT 0x0 + /*[field] SKEY_FMT*/ + #define EG_VLAN_XLT_RULE_SKEY_FMT + #define EG_VLAN_XLT_RULE_SKEY_FMT_OFFSET 16 + #define EG_VLAN_XLT_RULE_SKEY_FMT_LEN 3 + #define EG_VLAN_XLT_RULE_SKEY_FMT_DEFAULT 0x0 + /*[field] SKEY_VID_INCL*/ + #define EG_VLAN_XLT_RULE_SKEY_VID_INCL + #define EG_VLAN_XLT_RULE_SKEY_VID_INCL_OFFSET 19 + #define EG_VLAN_XLT_RULE_SKEY_VID_INCL_LEN 1 + #define EG_VLAN_XLT_RULE_SKEY_VID_INCL_DEFAULT 0x0 + /*[field] SKEY_VID*/ + #define EG_VLAN_XLT_RULE_SKEY_VID + #define EG_VLAN_XLT_RULE_SKEY_VID_OFFSET 20 + #define EG_VLAN_XLT_RULE_SKEY_VID_LEN 12 + #define EG_VLAN_XLT_RULE_SKEY_VID_DEFAULT 0x0 + /*[field] SKEY_PCP_INCL*/ + #define EG_VLAN_XLT_RULE_SKEY_PCP_INCL + #define EG_VLAN_XLT_RULE_SKEY_PCP_INCL_OFFSET 32 + #define EG_VLAN_XLT_RULE_SKEY_PCP_INCL_LEN 1 + #define EG_VLAN_XLT_RULE_SKEY_PCP_INCL_DEFAULT 0x0 + /*[field] SKEY_PCP*/ + #define EG_VLAN_XLT_RULE_SKEY_PCP + #define EG_VLAN_XLT_RULE_SKEY_PCP_OFFSET 33 + #define EG_VLAN_XLT_RULE_SKEY_PCP_LEN 3 + #define EG_VLAN_XLT_RULE_SKEY_PCP_DEFAULT 0x0 + /*[field] SKEY_DEI_INCL*/ + #define EG_VLAN_XLT_RULE_SKEY_DEI_INCL + #define EG_VLAN_XLT_RULE_SKEY_DEI_INCL_OFFSET 36 + #define EG_VLAN_XLT_RULE_SKEY_DEI_INCL_LEN 1 + #define EG_VLAN_XLT_RULE_SKEY_DEI_INCL_DEFAULT 0x0 + /*[field] SKEY_DEI*/ + #define EG_VLAN_XLT_RULE_SKEY_DEI + #define EG_VLAN_XLT_RULE_SKEY_DEI_OFFSET 37 + #define EG_VLAN_XLT_RULE_SKEY_DEI_LEN 1 + #define EG_VLAN_XLT_RULE_SKEY_DEI_DEFAULT 0x0 + /*[field] CKEY_FMT*/ + #define EG_VLAN_XLT_RULE_CKEY_FMT + #define EG_VLAN_XLT_RULE_CKEY_FMT_OFFSET 38 + #define EG_VLAN_XLT_RULE_CKEY_FMT_LEN 3 + #define EG_VLAN_XLT_RULE_CKEY_FMT_DEFAULT 0x0 + /*[field] CKEY_VID_INCL*/ + #define EG_VLAN_XLT_RULE_CKEY_VID_INCL + #define EG_VLAN_XLT_RULE_CKEY_VID_INCL_OFFSET 41 + #define EG_VLAN_XLT_RULE_CKEY_VID_INCL_LEN 1 + #define EG_VLAN_XLT_RULE_CKEY_VID_INCL_DEFAULT 0x0 + /*[field] CKEY_VID*/ + #define EG_VLAN_XLT_RULE_CKEY_VID + #define EG_VLAN_XLT_RULE_CKEY_VID_OFFSET 42 + #define EG_VLAN_XLT_RULE_CKEY_VID_LEN 12 + #define EG_VLAN_XLT_RULE_CKEY_VID_DEFAULT 0x0 + /*[field] CKEY_PCP_INCL*/ + #define EG_VLAN_XLT_RULE_CKEY_PCP_INCL + #define EG_VLAN_XLT_RULE_CKEY_PCP_INCL_OFFSET 54 + #define EG_VLAN_XLT_RULE_CKEY_PCP_INCL_LEN 1 + #define EG_VLAN_XLT_RULE_CKEY_PCP_INCL_DEFAULT 0x0 + /*[field] CKEY_PCP*/ + #define EG_VLAN_XLT_RULE_CKEY_PCP + #define EG_VLAN_XLT_RULE_CKEY_PCP_OFFSET 55 + #define EG_VLAN_XLT_RULE_CKEY_PCP_LEN 3 + #define EG_VLAN_XLT_RULE_CKEY_PCP_DEFAULT 0x0 + /*[field] CKEY_DEI_INCL*/ + #define EG_VLAN_XLT_RULE_CKEY_DEI_INCL + #define EG_VLAN_XLT_RULE_CKEY_DEI_INCL_OFFSET 58 + #define EG_VLAN_XLT_RULE_CKEY_DEI_INCL_LEN 1 + #define EG_VLAN_XLT_RULE_CKEY_DEI_INCL_DEFAULT 0x0 + /*[field] CKEY_DEI*/ + #define EG_VLAN_XLT_RULE_CKEY_DEI + #define EG_VLAN_XLT_RULE_CKEY_DEI_OFFSET 59 + #define EG_VLAN_XLT_RULE_CKEY_DEI_LEN 1 + #define EG_VLAN_XLT_RULE_CKEY_DEI_DEFAULT 0x0 + +struct eg_vlan_xlt_rule { + a_uint32_t valid:1; + a_uint32_t port_bitmap:8; + a_uint32_t vsi_incl:1; + a_uint32_t vsi:5; + a_uint32_t vsi_valid:1; + a_uint32_t skey_fmt:3; + a_uint32_t skey_vid_incl:1; + a_uint32_t skey_vid:12; + a_uint32_t skey_pcp_incl:1; + a_uint32_t skey_pcp:3; + a_uint32_t skey_dei_incl:1; + a_uint32_t skey_dei:1; + a_uint32_t ckey_fmt:3; + a_uint32_t ckey_vid_incl:1; + a_uint32_t ckey_vid:12; + a_uint32_t ckey_pcp_incl:1; + a_uint32_t ckey_pcp:3; + a_uint32_t ckey_dei_incl:1; + a_uint32_t ckey_dei:1; + a_uint32_t _reserved0:4; +}; + +union eg_vlan_xlt_rule_u { + a_uint32_t val[2]; + struct eg_vlan_xlt_rule bf; +}; + +/*[register] EG_VSI_TAG*/ +#define EG_VSI_TAG +#define EG_VSI_TAG_ADDRESS 0x0 +#define EG_VSI_TAG_NUM 32 +#define EG_VSI_TAG_INC 0x4 +#define EG_VSI_TAG_TYPE REG_TYPE_RW +#define EG_VSI_TAG_DEFAULT 0xaaaa + /*[field] TAGGED_MODE_PORT_BITMAP*/ + #define EG_VSI_TAG_TAGGED_MODE_PORT_BITMAP + #define EG_VSI_TAG_TAGGED_MODE_PORT_BITMAP_OFFSET 0 + #define EG_VSI_TAG_TAGGED_MODE_PORT_BITMAP_LEN 16 + #define EG_VSI_TAG_TAGGED_MODE_PORT_BITMAP_DEFAULT 0xaaaa + +struct eg_vsi_tag { + a_uint32_t tagged_mode_port_bitmap:16; + a_uint32_t _reserved0:16; +}; + +union eg_vsi_tag_u { + a_uint32_t val; + struct eg_vsi_tag bf; +}; + +/*[register] PORT_EG_DEF_VID*/ +#define PORT_EG_DEF_VID +#define PORT_EG_DEF_VID_ADDRESS 0x400 +#define PORT_EG_DEF_VID_NUM 8 +#define PORT_EG_DEF_VID_INC 0x4 +#define PORT_EG_DEF_VID_TYPE REG_TYPE_RW +#define PORT_EG_DEF_VID_DEFAULT 0x0 + /*[field] PORT_DEF_SVID*/ + #define PORT_EG_DEF_VID_PORT_DEF_SVID + #define PORT_EG_DEF_VID_PORT_DEF_SVID_OFFSET 0 + #define PORT_EG_DEF_VID_PORT_DEF_SVID_LEN 12 + #define PORT_EG_DEF_VID_PORT_DEF_SVID_DEFAULT 0x0 + /*[field] PORT_DEF_SVID_EN*/ + #define PORT_EG_DEF_VID_PORT_DEF_SVID_EN + #define PORT_EG_DEF_VID_PORT_DEF_SVID_EN_OFFSET 12 + #define PORT_EG_DEF_VID_PORT_DEF_SVID_EN_LEN 1 + #define PORT_EG_DEF_VID_PORT_DEF_SVID_EN_DEFAULT 0x0 + /*[field] PORT_DEF_CVID*/ + #define PORT_EG_DEF_VID_PORT_DEF_CVID + #define PORT_EG_DEF_VID_PORT_DEF_CVID_OFFSET 16 + #define PORT_EG_DEF_VID_PORT_DEF_CVID_LEN 12 + #define PORT_EG_DEF_VID_PORT_DEF_CVID_DEFAULT 0x0 + /*[field] PORT_DEF_CVID_EN*/ + #define PORT_EG_DEF_VID_PORT_DEF_CVID_EN + #define PORT_EG_DEF_VID_PORT_DEF_CVID_EN_OFFSET 28 + #define PORT_EG_DEF_VID_PORT_DEF_CVID_EN_LEN 1 + #define PORT_EG_DEF_VID_PORT_DEF_CVID_EN_DEFAULT 0x0 + +struct port_eg_def_vid { + a_uint32_t port_def_svid:12; + a_uint32_t port_def_svid_en:1; + a_uint32_t _reserved0:3; + a_uint32_t port_def_cvid:12; + a_uint32_t port_def_cvid_en:1; + a_uint32_t _reserved1:3; +}; + +union port_eg_def_vid_u { + a_uint32_t val; + struct port_eg_def_vid bf; +}; + +/*[register] PORT_EG_VLAN*/ +#define PORT_EG_VLAN +#define PORT_EG_VLAN_ADDRESS 0x420 +#define PORT_EG_VLAN_NUM 8 +#define PORT_EG_VLAN_INC 0x4 +#define PORT_EG_VLAN_TYPE REG_TYPE_RW +#define PORT_EG_VLAN_DEFAULT 0x14 + /*[field] PORT_VLAN_TYPE*/ + #define PORT_EG_VLAN_PORT_VLAN_TYPE + #define PORT_EG_VLAN_PORT_VLAN_TYPE_OFFSET 0 + #define PORT_EG_VLAN_PORT_VLAN_TYPE_LEN 1 + #define PORT_EG_VLAN_PORT_VLAN_TYPE_DEFAULT 0x0 + /*[field] PORT_EG_VLAN_CTAG_MODE*/ + #define PORT_EG_VLAN_PORT_EG_VLAN_CTAG_MODE + #define PORT_EG_VLAN_PORT_EG_VLAN_CTAG_MODE_OFFSET 1 + #define PORT_EG_VLAN_PORT_EG_VLAN_CTAG_MODE_LEN 2 + #define PORT_EG_VLAN_PORT_EG_VLAN_CTAG_MODE_DEFAULT 0x2 + /*[field] PORT_EG_VLAN_STAG_MODE*/ + #define PORT_EG_VLAN_PORT_EG_VLAN_STAG_MODE + #define PORT_EG_VLAN_PORT_EG_VLAN_STAG_MODE_OFFSET 3 + #define PORT_EG_VLAN_PORT_EG_VLAN_STAG_MODE_LEN 2 + #define PORT_EG_VLAN_PORT_EG_VLAN_STAG_MODE_DEFAULT 0x2 + /*[field] VSI_TAG_MODE_EN*/ + #define PORT_EG_VLAN_VSI_TAG_MODE_EN + #define PORT_EG_VLAN_VSI_TAG_MODE_EN_OFFSET 5 + #define PORT_EG_VLAN_VSI_TAG_MODE_EN_LEN 1 + #define PORT_EG_VLAN_VSI_TAG_MODE_EN_DEFAULT 0x0 + /*[field] PORT_EG_PCP_PROP_CMD*/ + #define PORT_EG_VLAN_PORT_EG_PCP_PROP_CMD + #define PORT_EG_VLAN_PORT_EG_PCP_PROP_CMD_OFFSET 6 + #define PORT_EG_VLAN_PORT_EG_PCP_PROP_CMD_LEN 1 + #define PORT_EG_VLAN_PORT_EG_PCP_PROP_CMD_DEFAULT 0x0 + /*[field] PORT_EG_DEI_PROP_CMD*/ + #define PORT_EG_VLAN_PORT_EG_DEI_PROP_CMD + #define PORT_EG_VLAN_PORT_EG_DEI_PROP_CMD_OFFSET 7 + #define PORT_EG_VLAN_PORT_EG_DEI_PROP_CMD_LEN 1 + #define PORT_EG_VLAN_PORT_EG_DEI_PROP_CMD_DEFAULT 0x0 + /*[field] TX_COUNTING_EN*/ + #define PORT_EG_VLAN_TX_COUNTING_EN + #define PORT_EG_VLAN_TX_COUNTING_EN_OFFSET 8 + #define PORT_EG_VLAN_TX_COUNTING_EN_LEN 1 + #define PORT_EG_VLAN_TX_COUNTING_EN_DEFAULT 0x0 + +struct port_eg_vlan { + a_uint32_t port_vlan_type:1; + a_uint32_t port_eg_vlan_ctag_mode:2; + a_uint32_t port_eg_vlan_stag_mode:2; + a_uint32_t vsi_tag_mode_en:1; + a_uint32_t port_eg_pcp_prop_cmd:1; + a_uint32_t port_eg_dei_prop_cmd:1; + a_uint32_t tx_counting_en:1; + a_uint32_t _reserved0:23; +}; + +union port_eg_vlan_u { + a_uint32_t val; + struct port_eg_vlan bf; +}; + +/*[register] EG_VLAN_TPID*/ +#define EG_VLAN_TPID +#define EG_VLAN_TPID_ADDRESS 0x440 +#define EG_VLAN_TPID_NUM 1 +#define EG_VLAN_TPID_INC 0x4 +#define EG_VLAN_TPID_TYPE REG_TYPE_RW +#define EG_VLAN_TPID_DEFAULT 0x810088a8 + /*[field] STPID*/ + #define EG_VLAN_TPID_STPID + #define EG_VLAN_TPID_STPID_OFFSET 0 + #define EG_VLAN_TPID_STPID_LEN 16 + #define EG_VLAN_TPID_STPID_DEFAULT 0x88a8 + /*[field] CTPID*/ + #define EG_VLAN_TPID_CTPID + #define EG_VLAN_TPID_CTPID_OFFSET 16 + #define EG_VLAN_TPID_CTPID_LEN 16 + #define EG_VLAN_TPID_CTPID_DEFAULT 0x8100 + +struct eg_vlan_tpid { + a_uint32_t stpid:16; + a_uint32_t ctpid:16; +}; + +union eg_vlan_tpid_u { + a_uint32_t val; + struct eg_vlan_tpid bf; +}; + +/*[register] EG_BRIDGE_CONFIG*/ +#define EG_BRIDGE_CONFIG +#define EG_BRIDGE_CONFIG_ADDRESS 0x6000 +#define EG_BRIDGE_CONFIG_NUM 1 +#define EG_BRIDGE_CONFIG_INC 0x4 +#define EG_BRIDGE_CONFIG_TYPE REG_TYPE_RW +#define EG_BRIDGE_CONFIG_DEFAULT 0x0 + /*[field] BRIDGE_TYPE*/ + #define EG_BRIDGE_CONFIG_BRIDGE_TYPE + #define EG_BRIDGE_CONFIG_BRIDGE_TYPE_OFFSET 0 + #define EG_BRIDGE_CONFIG_BRIDGE_TYPE_LEN 1 + #define EG_BRIDGE_CONFIG_BRIDGE_TYPE_DEFAULT 0x0 + /*[field] PKT_LE_EDIT_BYPASS*/ + #define EG_BRIDGE_CONFIG_PKT_LE_EDIT_BYPASS + #define EG_BRIDGE_CONFIG_PKT_LE_EDIT_BYPASS_OFFSET 1 + #define EG_BRIDGE_CONFIG_PKT_LE_EDIT_BYPASS_LEN 1 + #define EG_BRIDGE_CONFIG_PKT_LE_EDIT_BYPASS_DEFAULT 0x0 + /*[field] QUEUE_CNT_EN*/ + #define EG_BRIDGE_CONFIG_QUEUE_CNT_EN + #define EG_BRIDGE_CONFIG_QUEUE_CNT_EN_OFFSET 2 + #define EG_BRIDGE_CONFIG_QUEUE_CNT_EN_LEN 1 + #define EG_BRIDGE_CONFIG_QUEUE_CNT_EN_DEFAULT 0x0 + +struct eg_bridge_config { + a_uint32_t bridge_type:1; + a_uint32_t pkt_le_edit_bypass:1; + a_uint32_t queue_cnt_en:1; + a_uint32_t _reserved0:29; +}; + +union eg_bridge_config_u { + a_uint32_t val; + struct eg_bridge_config bf; +}; + +/*[table] EG_VLAN_XLT_ACTION*/ +#define EG_VLAN_XLT_ACTION +#define EG_VLAN_XLT_ACTION_ADDRESS 0xd000 +#define EG_VLAN_XLT_ACTION_NUM 64 +#define EG_VLAN_XLT_ACTION_INC 0x8 +#define EG_VLAN_XLT_ACTION_TYPE REG_TYPE_RW +#define EG_VLAN_XLT_ACTION_DEFAULT 0x0 + /*[field] VID_SWAP_CMD*/ + #define EG_VLAN_XLT_ACTION_VID_SWAP_CMD + #define EG_VLAN_XLT_ACTION_VID_SWAP_CMD_OFFSET 0 + #define EG_VLAN_XLT_ACTION_VID_SWAP_CMD_LEN 1 + #define EG_VLAN_XLT_ACTION_VID_SWAP_CMD_DEFAULT 0x0 + /*[field] XLT_SVID_CMD*/ + #define EG_VLAN_XLT_ACTION_XLT_SVID_CMD + #define EG_VLAN_XLT_ACTION_XLT_SVID_CMD_OFFSET 1 + #define EG_VLAN_XLT_ACTION_XLT_SVID_CMD_LEN 2 + #define EG_VLAN_XLT_ACTION_XLT_SVID_CMD_DEFAULT 0x0 + /*[field] XLT_SVID*/ + #define EG_VLAN_XLT_ACTION_XLT_SVID + #define EG_VLAN_XLT_ACTION_XLT_SVID_OFFSET 3 + #define EG_VLAN_XLT_ACTION_XLT_SVID_LEN 12 + #define EG_VLAN_XLT_ACTION_XLT_SVID_DEFAULT 0x0 + /*[field] XLT_CVID_CMD*/ + #define EG_VLAN_XLT_ACTION_XLT_CVID_CMD + #define EG_VLAN_XLT_ACTION_XLT_CVID_CMD_OFFSET 15 + #define EG_VLAN_XLT_ACTION_XLT_CVID_CMD_LEN 2 + #define EG_VLAN_XLT_ACTION_XLT_CVID_CMD_DEFAULT 0x0 + /*[field] XLT_CVID*/ + #define EG_VLAN_XLT_ACTION_XLT_CVID + #define EG_VLAN_XLT_ACTION_XLT_CVID_OFFSET 17 + #define EG_VLAN_XLT_ACTION_XLT_CVID_LEN 12 + #define EG_VLAN_XLT_ACTION_XLT_CVID_DEFAULT 0x0 + /*[field] PCP_SWAP_CMD*/ + #define EG_VLAN_XLT_ACTION_PCP_SWAP_CMD + #define EG_VLAN_XLT_ACTION_PCP_SWAP_CMD_OFFSET 29 + #define EG_VLAN_XLT_ACTION_PCP_SWAP_CMD_LEN 1 + #define EG_VLAN_XLT_ACTION_PCP_SWAP_CMD_DEFAULT 0x0 + /*[field] XLT_SPCP_CMD*/ + #define EG_VLAN_XLT_ACTION_XLT_SPCP_CMD + #define EG_VLAN_XLT_ACTION_XLT_SPCP_CMD_OFFSET 30 + #define EG_VLAN_XLT_ACTION_XLT_SPCP_CMD_LEN 1 + #define EG_VLAN_XLT_ACTION_XLT_SPCP_CMD_DEFAULT 0x0 + /*[field] XLT_SPCP*/ + #define EG_VLAN_XLT_ACTION_XLT_SPCP + #define EG_VLAN_XLT_ACTION_XLT_SPCP_OFFSET 31 + #define EG_VLAN_XLT_ACTION_XLT_SPCP_LEN 3 + #define EG_VLAN_XLT_ACTION_XLT_SPCP_DEFAULT 0x0 + /*[field] XLT_CPCP_CMD*/ + #define EG_VLAN_XLT_ACTION_XLT_CPCP_CMD + #define EG_VLAN_XLT_ACTION_XLT_CPCP_CMD_OFFSET 34 + #define EG_VLAN_XLT_ACTION_XLT_CPCP_CMD_LEN 1 + #define EG_VLAN_XLT_ACTION_XLT_CPCP_CMD_DEFAULT 0x0 + /*[field] XLT_CPCP*/ + #define EG_VLAN_XLT_ACTION_XLT_CPCP + #define EG_VLAN_XLT_ACTION_XLT_CPCP_OFFSET 35 + #define EG_VLAN_XLT_ACTION_XLT_CPCP_LEN 3 + #define EG_VLAN_XLT_ACTION_XLT_CPCP_DEFAULT 0x0 + /*[field] DEI_SWAP_CMD*/ + #define EG_VLAN_XLT_ACTION_DEI_SWAP_CMD + #define EG_VLAN_XLT_ACTION_DEI_SWAP_CMD_OFFSET 38 + #define EG_VLAN_XLT_ACTION_DEI_SWAP_CMD_LEN 1 + #define EG_VLAN_XLT_ACTION_DEI_SWAP_CMD_DEFAULT 0x0 + /*[field] XLT_SDEI_CMD*/ + #define EG_VLAN_XLT_ACTION_XLT_SDEI_CMD + #define EG_VLAN_XLT_ACTION_XLT_SDEI_CMD_OFFSET 39 + #define EG_VLAN_XLT_ACTION_XLT_SDEI_CMD_LEN 1 + #define EG_VLAN_XLT_ACTION_XLT_SDEI_CMD_DEFAULT 0x0 + /*[field] XLT_SDEI*/ + #define EG_VLAN_XLT_ACTION_XLT_SDEI + #define EG_VLAN_XLT_ACTION_XLT_SDEI_OFFSET 40 + #define EG_VLAN_XLT_ACTION_XLT_SDEI_LEN 1 + #define EG_VLAN_XLT_ACTION_XLT_SDEI_DEFAULT 0x0 + /*[field] XLT_CDEI_CMD*/ + #define EG_VLAN_XLT_ACTION_XLT_CDEI_CMD + #define EG_VLAN_XLT_ACTION_XLT_CDEI_CMD_OFFSET 41 + #define EG_VLAN_XLT_ACTION_XLT_CDEI_CMD_LEN 1 + #define EG_VLAN_XLT_ACTION_XLT_CDEI_CMD_DEFAULT 0x0 + /*[field] XLT_CDEI*/ + #define EG_VLAN_XLT_ACTION_XLT_CDEI + #define EG_VLAN_XLT_ACTION_XLT_CDEI_OFFSET 42 + #define EG_VLAN_XLT_ACTION_XLT_CDEI_LEN 1 + #define EG_VLAN_XLT_ACTION_XLT_CDEI_DEFAULT 0x0 + /*[field] COUNTER_EN*/ + #define EG_VLAN_XLT_ACTION_COUNTER_EN + #define EG_VLAN_XLT_ACTION_COUNTER_EN_OFFSET 43 + #define EG_VLAN_XLT_ACTION_COUNTER_EN_LEN 1 + #define EG_VLAN_XLT_ACTION_COUNTER_EN_DEFAULT 0x0 + /*[field] COUNTER_ID*/ + #define EG_VLAN_XLT_ACTION_COUNTER_ID + #define EG_VLAN_XLT_ACTION_COUNTER_ID_OFFSET 44 + #define EG_VLAN_XLT_ACTION_COUNTER_ID_LEN 6 + #define EG_VLAN_XLT_ACTION_COUNTER_ID_DEFAULT 0x0 + +struct eg_vlan_xlt_action { + a_uint32_t vid_swap_cmd:1; + a_uint32_t xlt_svid_cmd:2; + a_uint32_t xlt_svid:12; + a_uint32_t xlt_cvid_cmd:2; + a_uint32_t xlt_cvid:12; + a_uint32_t pcp_swap_cmd:1; + a_uint32_t xlt_spcp_cmd:1; + a_uint32_t xlt_spcp_0:1; + a_uint32_t xlt_spcp_1:2; + a_uint32_t xlt_cpcp_cmd:1; + a_uint32_t xlt_cpcp:3; + a_uint32_t dei_swap_cmd:1; + a_uint32_t xlt_sdei_cmd:1; + a_uint32_t xlt_sdei:1; + a_uint32_t xlt_cdei_cmd:1; + a_uint32_t xlt_cdei:1; + a_uint32_t counter_en:1; + a_uint32_t counter_id:6; + a_uint32_t _reserved0:14; +}; + +union eg_vlan_xlt_action_u { + a_uint32_t val[2]; + struct eg_vlan_xlt_action bf; +}; + +/*[table] VLAN_DEV_TX_COUNTER_TBL*/ +#define VLAN_DEV_TX_COUNTER_TBL +#define VLAN_DEV_TX_COUNTER_TBL_ADDRESS 0x2000 +#define VLAN_DEV_TX_COUNTER_TBL_NUM 64 +#define VLAN_DEV_TX_COUNTER_TBL_INC 0x10 +#define VLAN_DEV_TX_COUNTER_TBL_TYPE REG_TYPE_RW +#define VLAN_DEV_TX_COUNTER_TBL_DEFAULT 0x0 + /*[field] TX_PKT_CNT*/ + #define VLAN_DEV_TX_COUNTER_TBL_TX_PKT_CNT + #define VLAN_DEV_TX_COUNTER_TBL_TX_PKT_CNT_OFFSET 0 + #define VLAN_DEV_TX_COUNTER_TBL_TX_PKT_CNT_LEN 32 + #define VLAN_DEV_TX_COUNTER_TBL_TX_PKT_CNT_DEFAULT 0x0 + /*[field] TX_BYTE_CNT*/ + #define VLAN_DEV_TX_COUNTER_TBL_TX_BYTE_CNT + #define VLAN_DEV_TX_COUNTER_TBL_TX_BYTE_CNT_OFFSET 32 + #define VLAN_DEV_TX_COUNTER_TBL_TX_BYTE_CNT_LEN 40 + #define VLAN_DEV_TX_COUNTER_TBL_TX_BYTE_CNT_DEFAULT 0x0 + +struct vlan_dev_tx_counter_tbl { + a_uint32_t tx_pkt_cnt:32; + a_uint32_t tx_byte_cnt_0:32; + a_uint32_t tx_byte_cnt_1:8; + a_uint32_t _reserved0:24; +}; + +union vlan_dev_tx_counter_tbl_u { + a_uint32_t val[3]; + struct vlan_dev_tx_counter_tbl bf; +}; + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_pppoe.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_pppoe.h new file mode 100755 index 000000000..051e596bc --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_pppoe.h @@ -0,0 +1,173 @@ +/* + * 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 + * @{ + */ +#ifndef _HPPE_PPPOE_H_ +#define _HPPE_PPPOE_H_ + +#define PPPOE_SESSION_MAX_ENTRY 16 +#define PPPOE_SESSION_EXT_MAX_ENTRY 16 +#define PPPOE_SESSION_EXT1_MAX_ENTRY 16 + +sw_error_t +hppe_pppoe_session_get( + a_uint32_t dev_id, + a_uint32_t index, + union pppoe_session_u *value); + +sw_error_t +hppe_pppoe_session_set( + a_uint32_t dev_id, + a_uint32_t index, + union pppoe_session_u *value); + +sw_error_t +hppe_pppoe_session_ext_get( + a_uint32_t dev_id, + a_uint32_t index, + union pppoe_session_ext_u *value); + +sw_error_t +hppe_pppoe_session_ext_set( + a_uint32_t dev_id, + a_uint32_t index, + union pppoe_session_ext_u *value); + +sw_error_t +hppe_pppoe_session_ext1_get( + a_uint32_t dev_id, + a_uint32_t index, + union pppoe_session_ext1_u *value); + +sw_error_t +hppe_pppoe_session_ext1_set( + a_uint32_t dev_id, + a_uint32_t index, + union pppoe_session_ext1_u *value); + +sw_error_t +hppe_pppoe_session_session_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pppoe_session_session_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pppoe_session_l3_if_index_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pppoe_session_l3_if_index_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pppoe_session_port_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pppoe_session_port_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pppoe_session_ext_uc_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pppoe_session_ext_uc_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pppoe_session_ext_mc_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pppoe_session_ext_mc_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pppoe_session_ext_smac_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pppoe_session_ext_smac_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pppoe_session_ext_l3_if_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pppoe_session_ext_l3_if_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pppoe_session_ext_smac_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pppoe_session_ext_smac_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pppoe_session_ext1_smac_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pppoe_session_ext1_smac_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + + +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_pppoe_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_pppoe_reg.h new file mode 100755 index 000000000..715c8287c --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_pppoe_reg.h @@ -0,0 +1,127 @@ +/* + * 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 + * @{ + */ +#ifndef HPPE_PPPOE_REG_H +#define HPPE_PPPOE_REG_H + + +/*[register] PPPOE_SESSION*/ +#define PPPOE_SESSION +#define PPPOE_SESSION_ADDRESS 0xc20 +#define PPPOE_SESSION_NUM 16 +#define PPPOE_SESSION_INC 0x4 +#define PPPOE_SESSION_TYPE REG_TYPE_RW +#define PPPOE_SESSION_DEFAULT 0x0 + /*[field] SESSION_ID*/ + #define PPPOE_SESSION_SESSION_ID + #define PPPOE_SESSION_SESSION_ID_OFFSET 0 + #define PPPOE_SESSION_SESSION_ID_LEN 16 + #define PPPOE_SESSION_SESSION_ID_DEFAULT 0x0 + /*[field] PORT_BITMAP*/ + #define PPPOE_SESSION_PORT_BITMAP + #define PPPOE_SESSION_PORT_BITMAP_OFFSET 16 + #define PPPOE_SESSION_PORT_BITMAP_LEN 8 + #define PPPOE_SESSION_PORT_BITMAP_DEFAULT 0x0 + /*[field] L3_IF_INDEX*/ + #define PPPOE_SESSION_L3_IF_INDEX + #define PPPOE_SESSION_L3_IF_INDEX_OFFSET 24 + #define PPPOE_SESSION_L3_IF_INDEX_LEN 8 + #define PPPOE_SESSION_L3_IF_INDEX_DEFAULT 0x0 + +struct pppoe_session { + a_uint32_t session_id:16; + a_uint32_t port_bitmap:8; + a_uint32_t l3_if_index:8; +}; + +union pppoe_session_u { + a_uint32_t val; + struct pppoe_session bf; +}; + +/*[register] PPPOE_SESSION_EXT*/ +#define PPPOE_SESSION_EXT +#define PPPOE_SESSION_EXT_ADDRESS 0xc60 +#define PPPOE_SESSION_EXT_NUM 16 +#define PPPOE_SESSION_EXT_INC 0x4 +#define PPPOE_SESSION_EXT_TYPE REG_TYPE_RW +#define PPPOE_SESSION_EXT_DEFAULT 0x0 + /*[field] L3_IF_VALID*/ + #define PPPOE_SESSION_EXT_L3_IF_VALID + #define PPPOE_SESSION_EXT_L3_IF_VALID_OFFSET 0 + #define PPPOE_SESSION_EXT_L3_IF_VALID_LEN 1 + #define PPPOE_SESSION_EXT_L3_IF_VALID_DEFAULT 0x0 + /*[field] MC_VALID*/ + #define PPPOE_SESSION_EXT_MC_VALID + #define PPPOE_SESSION_EXT_MC_VALID_OFFSET 1 + #define PPPOE_SESSION_EXT_MC_VALID_LEN 1 + #define PPPOE_SESSION_EXT_MC_VALID_DEFAULT 0x0 + /*[field] UC_VALID*/ + #define PPPOE_SESSION_EXT_UC_VALID + #define PPPOE_SESSION_EXT_UC_VALID_OFFSET 2 + #define PPPOE_SESSION_EXT_UC_VALID_LEN 1 + #define PPPOE_SESSION_EXT_UC_VALID_DEFAULT 0x0 + /*[field] SMAC_VALID*/ + #define PPPOE_SESSION_EXT_SMAC_VALID + #define PPPOE_SESSION_EXT_SMAC_VALID_OFFSET 3 + #define PPPOE_SESSION_EXT_SMAC_VALID_LEN 1 + #define PPPOE_SESSION_EXT_SMAC_VALID_DEFAULT 0x0 + /*[field] SMAC*/ + #define PPPOE_SESSION_EXT_SMAC + #define PPPOE_SESSION_EXT_SMAC_OFFSET 16 + #define PPPOE_SESSION_EXT_SMAC_LEN 16 + #define PPPOE_SESSION_EXT_SMAC_DEFAULT 0x0 + +struct pppoe_session_ext { + a_uint32_t l3_if_valid:1; + a_uint32_t mc_valid:1; + a_uint32_t uc_valid:1; + a_uint32_t smac_valid:1; + a_uint32_t _reserved0:12; + a_uint32_t smac:16; +}; + +union pppoe_session_ext_u { + a_uint32_t val; + struct pppoe_session_ext bf; +}; + +/*[register] PPPOE_SESSION_EXT1*/ +#define PPPOE_SESSION_EXT1 +#define PPPOE_SESSION_EXT1_ADDRESS 0xca0 +#define PPPOE_SESSION_EXT1_NUM 16 +#define PPPOE_SESSION_EXT1_INC 0x4 +#define PPPOE_SESSION_EXT1_TYPE REG_TYPE_RW +#define PPPOE_SESSION_EXT1_DEFAULT 0x0 + /*[field] SMAC*/ + #define PPPOE_SESSION_EXT1_SMAC + #define PPPOE_SESSION_EXT1_SMAC_OFFSET 0 + #define PPPOE_SESSION_EXT1_SMAC_LEN 32 + #define PPPOE_SESSION_EXT1_SMAC_DEFAULT 0x0 + +struct pppoe_session_ext1 { + a_uint32_t smac:32; +}; + +union pppoe_session_ext1_u { + a_uint32_t val; + struct pppoe_session_ext1 bf; +}; + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_qm.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_qm.h new file mode 100755 index 000000000..383a07cc6 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_qm.h @@ -0,0 +1,3811 @@ +/* + * 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 + * @{ + */ +#ifndef _HPPE_QM_H_ +#define _HPPE_QM_H_ + +#define MCAST_PRIORITY_MAP0_MAX_ENTRY 16 +#define MCAST_PRIORITY_MAP1_MAX_ENTRY 16 +#define MCAST_PRIORITY_MAP2_MAX_ENTRY 16 +#define MCAST_PRIORITY_MAP3_MAX_ENTRY 16 +#define MCAST_PRIORITY_MAP4_MAX_ENTRY 16 +#define MCAST_PRIORITY_MAP5_MAX_ENTRY 16 +#define MCAST_PRIORITY_MAP6_MAX_ENTRY 16 +#define MCAST_PRIORITY_MAP7_MAX_ENTRY 16 +#define UQ_AGG_PROFILE_CFG_MAX_ENTRY 8 +#define MQ_AGG_PROFILE_CFG_MAX_ENTRY 8 +#define GRP_AGG_PROFILE_CFG_MAX_ENTRY 4 +#define UQ_AGG_IN_PROFILE_CNT_MAX_ENTRY 8 +#define UQ_AGG_OUT_PROFILE_CNT_MAX_ENTRY 8 +#define MQ_AGG_IN_PROFILE_CNT_MAX_ENTRY 8 +#define MQ_AGG_OUT_PROFILE_CNT_MAX_ENTRY 8 +#define GRP_AGG_IN_PROFILE_CNT_MAX_ENTRY 4 +#define GRP_AGG_OUT_PROFILE_CNT_MAX_ENTRY 4 +#define UCAST_QUEUE_MAP_TBL_MAX_ENTRY 3072 +#define UCAST_HASH_MAP_TBL_MAX_ENTRY 4096 +#define UCAST_PRIORITY_MAP_TBL_MAX_ENTRY 256 +#define MCAST_QUEUE_MAP_TBL_MAX_ENTRY 256 +#define AC_MSEQ_TBL_MAX_ENTRY 256 +#define AC_UNI_QUEUE_CFG_TBL_MAX_ENTRY 256 +#define AC_MUL_QUEUE_CFG_TBL_MAX_ENTRY 44 +#define AC_GRP_CFG_TBL_MAX_ENTRY 4 +#define AC_UNI_QUEUE_CNT_TBL_MAX_ENTRY 256 +#define AC_MUL_QUEUE_CNT_TBL_MAX_ENTRY 44 +#define AC_GRP_CNT_TBL_MAX_ENTRY 4 +#define AC_UNI_QUEUE_DROP_STATE_TBL_MAX_ENTRY 256 +#define AC_MUL_QUEUE_DROP_STATE_TBL_MAX_ENTRY 44 +#define AC_GRP_DROP_STATE_TBL_MAX_ENTRY 4 +#define OQ_ENQ_OPR_TBL_MAX_ENTRY 300 +#define OQ_DEQ_OPR_TBL_MAX_ENTRY 300 +#define OQ_HEAD_UNI_TBL_MAX_ENTRY 256 +#define OQ_HEAD_MUL_TBL_MAX_ENTRY 44 +#define OQ_LL_UNI_TBL_MAX_ENTRY 2048 +#define OQ_LL_MUL_P0_TBL_MAX_ENTRY 2048 +#define OQ_LL_MUL_P1_TBL_MAX_ENTRY 2048 +#define OQ_LL_MUL_P2_TBL_MAX_ENTRY 2048 +#define OQ_LL_MUL_P3_TBL_MAX_ENTRY 2048 +#define OQ_LL_MUL_P4_TBL_MAX_ENTRY 2048 +#define OQ_LL_MUL_P5_TBL_MAX_ENTRY 2048 +#define OQ_LL_MUL_P6_TBL_MAX_ENTRY 2048 +#define OQ_LL_MUL_P7_TBL_MAX_ENTRY 2048 +#define PKT_DESP_TBL_MAX_ENTRY 2048 +#define UNI_DROP_CNT_TBL_MAX_ENTRY 1536 +#define MUL_P0_DROP_CNT_TBL_MAX_ENTRY 48 +#define MUL_P1_DROP_CNT_TBL_MAX_ENTRY 12 +#define MUL_P2_DROP_CNT_TBL_MAX_ENTRY 12 +#define MUL_P3_DROP_CNT_TBL_MAX_ENTRY 12 +#define MUL_P4_DROP_CNT_TBL_MAX_ENTRY 12 +#define MUL_P5_DROP_CNT_TBL_MAX_ENTRY 12 +#define MUL_P6_DROP_CNT_TBL_MAX_ENTRY 12 +#define MUL_P7_DROP_CNT_TBL_MAX_ENTRY 12 +#define UQ_AGG_PROFILE_MAP_MAX_ENTRY 256 +#define QUEUE_TX_COUNTER_TBL_MAX_ENTRY 300 + +sw_error_t +hppe_queue_tx_counter_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union queue_tx_counter_tbl_u *value); + +sw_error_t +hppe_queue_tx_counter_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union queue_tx_counter_tbl_u *value); + +sw_error_t +hppe_flush_cfg_get( + a_uint32_t dev_id, + union flush_cfg_u *value); + +sw_error_t +hppe_flush_cfg_set( + a_uint32_t dev_id, + union flush_cfg_u *value); + +sw_error_t +hppe_in_mirror_priority_ctrl_get( + a_uint32_t dev_id, + union in_mirror_priority_ctrl_u *value); + +sw_error_t +hppe_in_mirror_priority_ctrl_set( + a_uint32_t dev_id, + union in_mirror_priority_ctrl_u *value); + +sw_error_t +hppe_eg_mirror_priority_ctrl_get( + a_uint32_t dev_id, + union eg_mirror_priority_ctrl_u *value); + +sw_error_t +hppe_eg_mirror_priority_ctrl_set( + a_uint32_t dev_id, + union eg_mirror_priority_ctrl_u *value); + +sw_error_t +hppe_ucast_default_hash_get( + a_uint32_t dev_id, + union ucast_default_hash_u *value); + +sw_error_t +hppe_ucast_default_hash_set( + a_uint32_t dev_id, + union ucast_default_hash_u *value); + +sw_error_t +hppe_spare_reg0_get( + a_uint32_t dev_id, + union spare_reg0_u *value); + +sw_error_t +hppe_spare_reg0_set( + a_uint32_t dev_id, + union spare_reg0_u *value); + +sw_error_t +hppe_spare_reg1_get( + a_uint32_t dev_id, + union spare_reg1_u *value); + +sw_error_t +hppe_spare_reg1_set( + a_uint32_t dev_id, + union spare_reg1_u *value); + +sw_error_t +hppe_qm_dbg_addr_get( + a_uint32_t dev_id, + union qm_dbg_addr_u *value); + +sw_error_t +hppe_qm_dbg_addr_set( + a_uint32_t dev_id, + union qm_dbg_addr_u *value); + +sw_error_t +hppe_qm_dbg_data_get( + a_uint32_t dev_id, + union qm_dbg_data_u *value); + +sw_error_t +hppe_qm_dbg_data_set( + a_uint32_t dev_id, + union qm_dbg_data_u *value); + +sw_error_t +hppe_mcast_priority_map0_get( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_priority_map0_u *value); + +sw_error_t +hppe_mcast_priority_map0_set( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_priority_map0_u *value); + +sw_error_t +hppe_mcast_priority_map1_get( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_priority_map1_u *value); + +sw_error_t +hppe_mcast_priority_map1_set( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_priority_map1_u *value); + +sw_error_t +hppe_mcast_priority_map2_get( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_priority_map2_u *value); + +sw_error_t +hppe_mcast_priority_map2_set( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_priority_map2_u *value); + +sw_error_t +hppe_mcast_priority_map3_get( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_priority_map3_u *value); + +sw_error_t +hppe_mcast_priority_map3_set( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_priority_map3_u *value); + +sw_error_t +hppe_mcast_priority_map4_get( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_priority_map4_u *value); + +sw_error_t +hppe_mcast_priority_map4_set( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_priority_map4_u *value); + +sw_error_t +hppe_mcast_priority_map5_get( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_priority_map5_u *value); + +sw_error_t +hppe_mcast_priority_map5_set( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_priority_map5_u *value); + +sw_error_t +hppe_mcast_priority_map6_get( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_priority_map6_u *value); + +sw_error_t +hppe_mcast_priority_map6_set( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_priority_map6_u *value); + +sw_error_t +hppe_mcast_priority_map7_get( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_priority_map7_u *value); + +sw_error_t +hppe_mcast_priority_map7_set( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_priority_map7_u *value); + +sw_error_t +hppe_agg_profile_cnt_en_get( + a_uint32_t dev_id, + union agg_profile_cnt_en_u *value); + +sw_error_t +hppe_agg_profile_cnt_en_set( + a_uint32_t dev_id, + union agg_profile_cnt_en_u *value); + +sw_error_t +hppe_uq_agg_profile_cfg_get( + a_uint32_t dev_id, + a_uint32_t index, + union uq_agg_profile_cfg_u *value); + +sw_error_t +hppe_uq_agg_profile_cfg_set( + a_uint32_t dev_id, + a_uint32_t index, + union uq_agg_profile_cfg_u *value); + +sw_error_t +hppe_mq_agg_profile_cfg_get( + a_uint32_t dev_id, + a_uint32_t index, + union mq_agg_profile_cfg_u *value); + +sw_error_t +hppe_mq_agg_profile_cfg_set( + a_uint32_t dev_id, + a_uint32_t index, + union mq_agg_profile_cfg_u *value); + +sw_error_t +hppe_grp_agg_profile_cfg_get( + a_uint32_t dev_id, + a_uint32_t index, + union grp_agg_profile_cfg_u *value); + +sw_error_t +hppe_grp_agg_profile_cfg_set( + a_uint32_t dev_id, + a_uint32_t index, + union grp_agg_profile_cfg_u *value); + +sw_error_t +hppe_uq_agg_in_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + union uq_agg_in_profile_cnt_u *value); + +sw_error_t +hppe_uq_agg_in_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + union uq_agg_in_profile_cnt_u *value); + +sw_error_t +hppe_uq_agg_out_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + union uq_agg_out_profile_cnt_u *value); + +sw_error_t +hppe_uq_agg_out_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + union uq_agg_out_profile_cnt_u *value); + +sw_error_t +hppe_mq_agg_in_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + union mq_agg_in_profile_cnt_u *value); + +sw_error_t +hppe_mq_agg_in_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + union mq_agg_in_profile_cnt_u *value); + +sw_error_t +hppe_mq_agg_out_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + union mq_agg_out_profile_cnt_u *value); + +sw_error_t +hppe_mq_agg_out_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + union mq_agg_out_profile_cnt_u *value); + +sw_error_t +hppe_grp_agg_in_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + union grp_agg_in_profile_cnt_u *value); + +sw_error_t +hppe_grp_agg_in_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + union grp_agg_in_profile_cnt_u *value); + +sw_error_t +hppe_grp_agg_out_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + union grp_agg_out_profile_cnt_u *value); + +sw_error_t +hppe_grp_agg_out_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + union grp_agg_out_profile_cnt_u *value); + +sw_error_t +hppe_ucast_queue_map_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union ucast_queue_map_tbl_u *value); + +sw_error_t +hppe_ucast_queue_map_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union ucast_queue_map_tbl_u *value); + +sw_error_t +hppe_ucast_hash_map_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union ucast_hash_map_tbl_u *value); + +sw_error_t +hppe_ucast_hash_map_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union ucast_hash_map_tbl_u *value); + +sw_error_t +hppe_ucast_priority_map_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union ucast_priority_map_tbl_u *value); + +sw_error_t +hppe_ucast_priority_map_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union ucast_priority_map_tbl_u *value); + +sw_error_t +hppe_mcast_queue_map_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_queue_map_tbl_u *value); + +sw_error_t +hppe_mcast_queue_map_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_queue_map_tbl_u *value); + +sw_error_t +hppe_ac_mseq_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union ac_mseq_tbl_u *value); + +sw_error_t +hppe_ac_mseq_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union ac_mseq_tbl_u *value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union ac_uni_queue_cfg_tbl_u *value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union ac_uni_queue_cfg_tbl_u *value); + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union ac_mul_queue_cfg_tbl_u *value); + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union ac_mul_queue_cfg_tbl_u *value); + +sw_error_t +hppe_ac_grp_cfg_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union ac_grp_cfg_tbl_u *value); + +sw_error_t +hppe_ac_grp_cfg_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union ac_grp_cfg_tbl_u *value); + +sw_error_t +hppe_ac_uni_queue_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union ac_uni_queue_cnt_tbl_u *value); + +sw_error_t +hppe_ac_uni_queue_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union ac_uni_queue_cnt_tbl_u *value); + +sw_error_t +hppe_ac_mul_queue_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union ac_mul_queue_cnt_tbl_u *value); + +sw_error_t +hppe_ac_mul_queue_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union ac_mul_queue_cnt_tbl_u *value); + +sw_error_t +hppe_ac_grp_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union ac_grp_cnt_tbl_u *value); + +sw_error_t +hppe_ac_grp_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union ac_grp_cnt_tbl_u *value); + +sw_error_t +hppe_ac_uni_queue_drop_state_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union ac_uni_queue_drop_state_tbl_u *value); + +sw_error_t +hppe_ac_uni_queue_drop_state_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union ac_uni_queue_drop_state_tbl_u *value); + +sw_error_t +hppe_ac_mul_queue_drop_state_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union ac_mul_queue_drop_state_tbl_u *value); + +sw_error_t +hppe_ac_mul_queue_drop_state_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union ac_mul_queue_drop_state_tbl_u *value); + +sw_error_t +hppe_ac_grp_drop_state_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union ac_grp_drop_state_tbl_u *value); + +sw_error_t +hppe_ac_grp_drop_state_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union ac_grp_drop_state_tbl_u *value); + +sw_error_t +hppe_oq_enq_opr_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union oq_enq_opr_tbl_u *value); + +sw_error_t +hppe_oq_enq_opr_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union oq_enq_opr_tbl_u *value); + +sw_error_t +hppe_oq_deq_opr_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union oq_deq_opr_tbl_u *value); + +sw_error_t +hppe_oq_deq_opr_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union oq_deq_opr_tbl_u *value); + +sw_error_t +hppe_oq_head_uni_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union oq_head_uni_tbl_u *value); + +sw_error_t +hppe_oq_head_uni_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union oq_head_uni_tbl_u *value); + +sw_error_t +hppe_oq_head_mul_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union oq_head_mul_tbl_u *value); + +sw_error_t +hppe_oq_head_mul_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union oq_head_mul_tbl_u *value); + +sw_error_t +hppe_oq_ll_uni_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_uni_tbl_u *value); + +sw_error_t +hppe_oq_ll_uni_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_uni_tbl_u *value); + +sw_error_t +hppe_oq_ll_mul_p0_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_mul_p0_tbl_u *value); + +sw_error_t +hppe_oq_ll_mul_p0_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_mul_p0_tbl_u *value); + +sw_error_t +hppe_oq_ll_mul_p1_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_mul_p1_tbl_u *value); + +sw_error_t +hppe_oq_ll_mul_p1_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_mul_p1_tbl_u *value); + +sw_error_t +hppe_oq_ll_mul_p2_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_mul_p2_tbl_u *value); + +sw_error_t +hppe_oq_ll_mul_p2_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_mul_p2_tbl_u *value); + +sw_error_t +hppe_oq_ll_mul_p3_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_mul_p3_tbl_u *value); + +sw_error_t +hppe_oq_ll_mul_p3_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_mul_p3_tbl_u *value); + +sw_error_t +hppe_oq_ll_mul_p4_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_mul_p4_tbl_u *value); + +sw_error_t +hppe_oq_ll_mul_p4_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_mul_p4_tbl_u *value); + +sw_error_t +hppe_oq_ll_mul_p5_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_mul_p5_tbl_u *value); + +sw_error_t +hppe_oq_ll_mul_p5_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_mul_p5_tbl_u *value); + +sw_error_t +hppe_oq_ll_mul_p6_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_mul_p6_tbl_u *value); + +sw_error_t +hppe_oq_ll_mul_p6_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_mul_p6_tbl_u *value); + +sw_error_t +hppe_oq_ll_mul_p7_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_mul_p7_tbl_u *value); + +sw_error_t +hppe_oq_ll_mul_p7_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_mul_p7_tbl_u *value); + +sw_error_t +hppe_pkt_desp_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union pkt_desp_tbl_u *value); + +sw_error_t +hppe_pkt_desp_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union pkt_desp_tbl_u *value); + +sw_error_t +hppe_uni_drop_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union uni_drop_cnt_tbl_u *value); + +sw_error_t +hppe_uni_drop_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union uni_drop_cnt_tbl_u *value); + +sw_error_t +hppe_mul_p0_drop_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mul_p0_drop_cnt_tbl_u *value); + +sw_error_t +hppe_mul_p0_drop_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mul_p0_drop_cnt_tbl_u *value); + +sw_error_t +hppe_mul_p1_drop_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mul_p1_drop_cnt_tbl_u *value); + +sw_error_t +hppe_mul_p1_drop_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mul_p1_drop_cnt_tbl_u *value); + +sw_error_t +hppe_mul_p2_drop_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mul_p2_drop_cnt_tbl_u *value); + +sw_error_t +hppe_mul_p2_drop_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mul_p2_drop_cnt_tbl_u *value); + +sw_error_t +hppe_mul_p3_drop_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mul_p3_drop_cnt_tbl_u *value); + +sw_error_t +hppe_mul_p3_drop_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mul_p3_drop_cnt_tbl_u *value); + +sw_error_t +hppe_mul_p4_drop_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mul_p4_drop_cnt_tbl_u *value); + +sw_error_t +hppe_mul_p4_drop_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mul_p4_drop_cnt_tbl_u *value); + +sw_error_t +hppe_mul_p5_drop_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mul_p5_drop_cnt_tbl_u *value); + +sw_error_t +hppe_mul_p5_drop_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mul_p5_drop_cnt_tbl_u *value); + +sw_error_t +hppe_mul_p6_drop_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mul_p6_drop_cnt_tbl_u *value); + +sw_error_t +hppe_mul_p6_drop_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mul_p6_drop_cnt_tbl_u *value); + +sw_error_t +hppe_mul_p7_drop_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mul_p7_drop_cnt_tbl_u *value); + +sw_error_t +hppe_mul_p7_drop_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mul_p7_drop_cnt_tbl_u *value); + +sw_error_t +hppe_uq_agg_profile_map_get( + a_uint32_t dev_id, + a_uint32_t index, + union uq_agg_profile_map_u *value); + +sw_error_t +hppe_uq_agg_profile_map_set( + a_uint32_t dev_id, + a_uint32_t index, + union uq_agg_profile_map_u *value); + +sw_error_t +hppe_flush_cfg_flush_busy_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flush_cfg_flush_busy_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flush_cfg_flush_qid_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flush_cfg_flush_qid_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flush_cfg_flush_dst_port_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flush_cfg_flush_dst_port_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flush_cfg_flush_all_queues_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flush_cfg_flush_all_queues_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flush_cfg_flush_wt_time_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flush_cfg_flush_wt_time_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_flush_cfg_flush_status_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_flush_cfg_flush_status_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_in_mirror_priority_ctrl_priority_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_in_mirror_priority_ctrl_priority_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_eg_mirror_priority_ctrl_priority_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_eg_mirror_priority_ctrl_priority_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_ucast_default_hash_hash_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_ucast_default_hash_hash_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_spare_reg0_spare_reg0_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_spare_reg0_spare_reg0_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_spare_reg1_spare_reg1_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_spare_reg1_spare_reg1_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_qm_dbg_addr_dbg_addr_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_qm_dbg_addr_dbg_addr_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_qm_dbg_data_dbg_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_qm_dbg_data_dbg_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_mcast_priority_map0_class_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mcast_priority_map0_class_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mcast_priority_map1_class_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mcast_priority_map1_class_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mcast_priority_map2_class_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mcast_priority_map2_class_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mcast_priority_map3_class_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mcast_priority_map3_class_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mcast_priority_map4_class_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mcast_priority_map4_class_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mcast_priority_map5_class_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mcast_priority_map5_class_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mcast_priority_map6_class_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mcast_priority_map6_class_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mcast_priority_map7_class_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mcast_priority_map7_class_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_agg_profile_cnt_en_mq_p2_en_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_agg_profile_cnt_en_mq_p2_en_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_agg_profile_cnt_en_uq_en_1_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_agg_profile_cnt_en_uq_en_1_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_agg_profile_cnt_en_mq_p0_en_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_agg_profile_cnt_en_mq_p0_en_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_agg_profile_cnt_en_grp_1_en_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_agg_profile_cnt_en_grp_1_en_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_agg_profile_cnt_en_grp_0_en_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_agg_profile_cnt_en_grp_0_en_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_agg_profile_cnt_en_mq_p6_en_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_agg_profile_cnt_en_mq_p6_en_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_agg_profile_cnt_en_uq_en_3_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_agg_profile_cnt_en_uq_en_3_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_agg_profile_cnt_en_mq_p4_en_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_agg_profile_cnt_en_mq_p4_en_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_agg_profile_cnt_en_uq_en_2_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_agg_profile_cnt_en_uq_en_2_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_agg_profile_cnt_en_uq_en_5_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_agg_profile_cnt_en_uq_en_5_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_agg_profile_cnt_en_uq_en_6_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_agg_profile_cnt_en_uq_en_6_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_agg_profile_cnt_en_grp_3_en_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_agg_profile_cnt_en_grp_3_en_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_agg_profile_cnt_en_grp_2_en_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_agg_profile_cnt_en_grp_2_en_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_agg_profile_cnt_en_uq_en_4_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_agg_profile_cnt_en_uq_en_4_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_agg_profile_cnt_en_mq_p7_en_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_agg_profile_cnt_en_mq_p7_en_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_agg_profile_cnt_en_uq_en_7_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_agg_profile_cnt_en_uq_en_7_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_agg_profile_cnt_en_global_en_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_agg_profile_cnt_en_global_en_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_agg_profile_cnt_en_mq_p5_en_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_agg_profile_cnt_en_mq_p5_en_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_agg_profile_cnt_en_mq_p1_en_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_agg_profile_cnt_en_mq_p1_en_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_agg_profile_cnt_en_uq_en_0_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_agg_profile_cnt_en_uq_en_0_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_agg_profile_cnt_en_mq_p3_en_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_agg_profile_cnt_en_mq_p3_en_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_uq_agg_profile_cfg_th_cfg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uq_agg_profile_cfg_th_cfg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mq_agg_profile_cfg_th_cfg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mq_agg_profile_cfg_th_cfg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_grp_agg_profile_cfg_th_cfg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_grp_agg_profile_cfg_th_cfg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uq_agg_in_profile_cnt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uq_agg_in_profile_cnt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uq_agg_out_profile_cnt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uq_agg_out_profile_cnt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mq_agg_in_profile_cnt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mq_agg_in_profile_cnt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mq_agg_out_profile_cnt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mq_agg_out_profile_cnt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_grp_agg_in_profile_cnt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_grp_agg_in_profile_cnt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_grp_agg_out_profile_cnt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_grp_agg_out_profile_cnt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ucast_queue_map_tbl_profile_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ucast_queue_map_tbl_profile_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ucast_queue_map_tbl_queue_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ucast_queue_map_tbl_queue_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ucast_hash_map_tbl_hash_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ucast_hash_map_tbl_hash_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ucast_priority_map_tbl_class_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ucast_priority_map_tbl_class_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mcast_queue_map_tbl_class_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mcast_queue_map_tbl_class_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_mseq_tbl_ac_mseq_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_mseq_tbl_ac_mseq_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_gap_grn_yel_max_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_gap_grn_yel_max_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_wred_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_wred_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_ac_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_ac_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_red_resume_offset_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_red_resume_offset_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_grp_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_grp_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_color_aware_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_color_aware_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_yel_resume_offset_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_yel_resume_offset_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_gap_grn_yel_min_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_gap_grn_yel_min_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_shared_weight_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_shared_weight_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_shared_dynamic_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_shared_dynamic_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_gap_grn_red_max_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_gap_grn_red_max_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_pre_alloc_limit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_pre_alloc_limit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_force_ac_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_force_ac_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_gap_grn_red_min_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_gap_grn_red_min_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_gap_grn_grn_min_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_gap_grn_grn_min_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_shared_ceiling_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_shared_ceiling_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_grn_resume_offset_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_grn_resume_offset_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_ac_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_ac_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_red_resume_offset_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_red_resume_offset_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_grp_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_grp_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_color_aware_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_color_aware_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_yel_resume_offset_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_yel_resume_offset_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_pre_alloc_limit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_pre_alloc_limit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_force_ac_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_force_ac_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_shared_ceiling_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_shared_ceiling_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_grn_resume_offset_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_grn_resume_offset_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_gap_grn_yel_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_gap_grn_yel_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_gap_grn_red_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_gap_grn_red_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_grp_grn_resume_offset_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_grp_grn_resume_offset_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_grp_dp_thrd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_grp_dp_thrd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_cfg_ac_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_cfg_ac_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_grp_palloc_limit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_grp_palloc_limit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_cfg_color_aware_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_cfg_color_aware_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_grp_red_resume_offset_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_grp_red_resume_offset_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_grp_gap_grn_yel_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_grp_gap_grn_yel_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_cfg_force_ac_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_cfg_force_ac_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_grp_yel_resume_offset_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_grp_yel_resume_offset_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_grp_gap_grn_red_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_grp_gap_grn_red_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_grp_limit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_grp_limit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_uni_queue_cnt_tbl_ac_uni_queue_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_uni_queue_cnt_tbl_ac_uni_queue_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_mul_queue_cnt_tbl_ac_mul_queue_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_mul_queue_cnt_tbl_ac_mul_queue_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_grp_cnt_tbl_ac_grp_alloc_used_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_grp_cnt_tbl_ac_grp_alloc_used_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_grp_cnt_tbl_ac_grp_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_grp_cnt_tbl_ac_grp_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_uni_queue_drop_state_tbl_red_resume_thrd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_uni_queue_drop_state_tbl_red_resume_thrd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_uni_queue_drop_state_tbl_red_drop_state_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_uni_queue_drop_state_tbl_red_drop_state_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_uni_queue_drop_state_tbl_yel_resume_thrd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_uni_queue_drop_state_tbl_yel_resume_thrd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_uni_queue_drop_state_tbl_grn_drop_state_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_uni_queue_drop_state_tbl_grn_drop_state_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_uni_queue_drop_state_tbl_yel_drop_state_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_uni_queue_drop_state_tbl_yel_drop_state_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_uni_queue_drop_state_tbl_grn_resume_thrd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_uni_queue_drop_state_tbl_grn_resume_thrd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_mul_queue_drop_state_tbl_red_resume_thrd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_mul_queue_drop_state_tbl_red_resume_thrd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_mul_queue_drop_state_tbl_red_drop_state_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_mul_queue_drop_state_tbl_red_drop_state_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_mul_queue_drop_state_tbl_yel_resume_thrd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_mul_queue_drop_state_tbl_yel_resume_thrd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_mul_queue_drop_state_tbl_grn_drop_state_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_mul_queue_drop_state_tbl_grn_drop_state_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_mul_queue_drop_state_tbl_yel_drop_state_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_mul_queue_drop_state_tbl_yel_drop_state_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_mul_queue_drop_state_tbl_grn_resume_thrd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_mul_queue_drop_state_tbl_grn_resume_thrd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_grp_drop_state_tbl_red_resume_thrd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_grp_drop_state_tbl_red_resume_thrd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_grp_drop_state_tbl_red_drop_state_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_grp_drop_state_tbl_red_drop_state_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_grp_drop_state_tbl_yel_resume_thrd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_grp_drop_state_tbl_yel_resume_thrd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_grp_drop_state_tbl_grn_drop_state_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_grp_drop_state_tbl_grn_drop_state_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_grp_drop_state_tbl_yel_drop_state_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_grp_drop_state_tbl_yel_drop_state_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ac_grp_drop_state_tbl_grn_resume_thrd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ac_grp_drop_state_tbl_grn_resume_thrd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_enq_opr_tbl_enq_disable_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_enq_opr_tbl_enq_disable_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_deq_opr_tbl_deq_drop_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_deq_opr_tbl_deq_drop_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_head_uni_tbl_head_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_head_uni_tbl_head_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_head_uni_tbl_tail_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_head_uni_tbl_tail_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_head_uni_tbl_empty_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_head_uni_tbl_empty_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_head_mul_tbl_head_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_head_mul_tbl_head_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_head_mul_tbl_tail_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_head_mul_tbl_tail_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_head_mul_tbl_ingress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_head_mul_tbl_ingress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_head_mul_tbl_empty_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_head_mul_tbl_empty_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_head_mul_tbl_egress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_head_mul_tbl_egress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_head_mul_tbl_normal_fwd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_head_mul_tbl_normal_fwd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_ll_uni_tbl_next_pointer_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_ll_uni_tbl_next_pointer_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_ll_mul_p0_tbl_next_pointer_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_ll_mul_p0_tbl_next_pointer_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_ll_mul_p0_tbl_ingress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_ll_mul_p0_tbl_ingress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_ll_mul_p0_tbl_egress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_ll_mul_p0_tbl_egress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_ll_mul_p0_tbl_normal_fwd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_ll_mul_p0_tbl_normal_fwd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_ll_mul_p1_tbl_next_pointer_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_ll_mul_p1_tbl_next_pointer_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_ll_mul_p1_tbl_ingress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_ll_mul_p1_tbl_ingress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_ll_mul_p1_tbl_egress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_ll_mul_p1_tbl_egress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_ll_mul_p1_tbl_normal_fwd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_ll_mul_p1_tbl_normal_fwd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_ll_mul_p2_tbl_next_pointer_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_ll_mul_p2_tbl_next_pointer_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_ll_mul_p2_tbl_ingress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_ll_mul_p2_tbl_ingress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_ll_mul_p2_tbl_egress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_ll_mul_p2_tbl_egress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_ll_mul_p2_tbl_normal_fwd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_ll_mul_p2_tbl_normal_fwd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_ll_mul_p3_tbl_next_pointer_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_ll_mul_p3_tbl_next_pointer_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_ll_mul_p3_tbl_ingress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_ll_mul_p3_tbl_ingress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_ll_mul_p3_tbl_egress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_ll_mul_p3_tbl_egress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_ll_mul_p3_tbl_normal_fwd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_ll_mul_p3_tbl_normal_fwd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_ll_mul_p4_tbl_next_pointer_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_ll_mul_p4_tbl_next_pointer_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_ll_mul_p4_tbl_ingress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_ll_mul_p4_tbl_ingress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_ll_mul_p4_tbl_egress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_ll_mul_p4_tbl_egress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_ll_mul_p4_tbl_normal_fwd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_ll_mul_p4_tbl_normal_fwd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_ll_mul_p5_tbl_next_pointer_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_ll_mul_p5_tbl_next_pointer_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_ll_mul_p5_tbl_ingress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_ll_mul_p5_tbl_ingress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_ll_mul_p5_tbl_egress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_ll_mul_p5_tbl_egress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_ll_mul_p5_tbl_normal_fwd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_ll_mul_p5_tbl_normal_fwd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_ll_mul_p6_tbl_next_pointer_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_ll_mul_p6_tbl_next_pointer_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_ll_mul_p6_tbl_ingress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_ll_mul_p6_tbl_ingress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_ll_mul_p6_tbl_egress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_ll_mul_p6_tbl_egress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_ll_mul_p6_tbl_normal_fwd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_ll_mul_p6_tbl_normal_fwd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_ll_mul_p7_tbl_next_pointer_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_ll_mul_p7_tbl_next_pointer_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_ll_mul_p7_tbl_ingress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_ll_mul_p7_tbl_ingress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_ll_mul_p7_tbl_egress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_ll_mul_p7_tbl_egress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_oq_ll_mul_p7_tbl_normal_fwd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_oq_ll_mul_p7_tbl_normal_fwd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_ip_addr_index_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_ip_addr_index_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_route_flag_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_route_flag_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_int_cpcp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_int_cpcp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_pkt_l3_edit_bypass_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_pkt_l3_edit_bypass_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_int_ctag_fmt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_int_ctag_fmt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_fake_mac_header_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_fake_mac_header_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_acl_index_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_acl_index_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_l4_type_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_l4_type_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_int_svid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_int_svid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_int_sdei_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_int_sdei_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_fc_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_fc_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_packet_length_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_packet_length_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_rx_ts_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_pkt_desp_tbl_rx_ts_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_pkt_desp_tbl_ts_dir_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_ts_dir_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_chg_port_vp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_chg_port_vp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_int_pri_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_int_pri_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_one_enq_flag_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_one_enq_flag_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_fc_grp_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_fc_grp_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_fake_l2_prot_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_fake_l2_prot_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_org_src_port_vp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_org_src_port_vp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_hash_flag_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_hash_flag_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_int_stag_fmt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_int_stag_fmt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_service_code_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_service_code_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_rx_ptp_type_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_rx_ptp_type_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_mac_da_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_pkt_desp_tbl_mac_da_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_pkt_desp_tbl_cpu_code_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_cpu_code_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_eg_vlan_tag_fmt_bypass_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_eg_vlan_tag_fmt_bypass_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_ip_addr_index_type_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_ip_addr_index_type_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_int_cvid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_int_cvid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_eg_vlan_xlt_bypass_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_eg_vlan_xlt_bypass_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_hash_value_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_hash_value_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_stag_flag_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_stag_flag_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_dst_l3_if_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_dst_l3_if_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_int_cdei_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_int_cdei_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_edma_vp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_edma_vp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_ac_group_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_ac_group_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_vp_tx_cnt_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_vp_tx_cnt_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_src_port_vp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_src_port_vp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_nat_action_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_nat_action_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_dscp_update_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_dscp_update_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_pppoe_strip_flag_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_pppoe_strip_flag_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_snap_flag_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_snap_flag_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_vsi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_vsi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_pkt_l2_edit_bypass_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_pkt_l2_edit_bypass_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_tx_ptp_tag_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_tx_ptp_tag_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_ip_addr_index_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_ip_addr_index_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_int_dp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_int_dp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_src_pn_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_src_pn_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_tx_ts_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_tx_ts_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_l4_offset_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_l4_offset_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_ttl_update_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_ttl_update_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_napt_port_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_napt_port_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_napt_addr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_napt_addr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_copy_cpu_flag_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_copy_cpu_flag_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_ttl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_ttl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_l3_offset_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_l3_offset_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_rsv0_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_rsv0_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_next_header_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_next_header_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_acl_index_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_acl_index_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_rx_ts_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_rx_ts_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_dscp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_dscp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_acl_index_toggle_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_acl_index_toggle_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_ctag_flag_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_ctag_flag_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_ip_addr_index_toggle_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_ip_addr_index_toggle_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_tx_os_correction_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_tx_os_correction_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_int_spcp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_int_spcp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_pppoe_flag_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_pppoe_flag_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_l3_type_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_l3_type_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pkt_desp_tbl_vsi_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pkt_desp_tbl_vsi_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uni_drop_cnt_tbl_uni_drop_byte_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_uni_drop_cnt_tbl_uni_drop_byte_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_uni_drop_cnt_tbl_uni_drop_pkt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uni_drop_cnt_tbl_uni_drop_pkt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mul_p0_drop_cnt_tbl_mul_p0_drop_pkt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mul_p0_drop_cnt_tbl_mul_p0_drop_pkt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mul_p0_drop_cnt_tbl_mul_p0_drop_byte_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_mul_p0_drop_cnt_tbl_mul_p0_drop_byte_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_mul_p1_drop_cnt_tbl_mul_p1_drop_byte_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_mul_p1_drop_cnt_tbl_mul_p1_drop_byte_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_mul_p1_drop_cnt_tbl_mul_p1_drop_pkt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mul_p1_drop_cnt_tbl_mul_p1_drop_pkt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mul_p2_drop_cnt_tbl_mul_p2_drop_pkt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mul_p2_drop_cnt_tbl_mul_p2_drop_pkt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mul_p2_drop_cnt_tbl_mul_p2_drop_byte_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_mul_p2_drop_cnt_tbl_mul_p2_drop_byte_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_mul_p3_drop_cnt_tbl_mul_p3_drop_pkt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mul_p3_drop_cnt_tbl_mul_p3_drop_pkt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mul_p3_drop_cnt_tbl_mul_p3_drop_byte_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_mul_p3_drop_cnt_tbl_mul_p3_drop_byte_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_mul_p4_drop_cnt_tbl_mul_p4_drop_pkt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mul_p4_drop_cnt_tbl_mul_p4_drop_pkt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mul_p4_drop_cnt_tbl_mul_p4_drop_byte_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_mul_p4_drop_cnt_tbl_mul_p4_drop_byte_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_mul_p5_drop_cnt_tbl_mul_p5_drop_byte_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_mul_p5_drop_cnt_tbl_mul_p5_drop_byte_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_mul_p5_drop_cnt_tbl_mul_p5_drop_pkt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mul_p5_drop_cnt_tbl_mul_p5_drop_pkt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mul_p6_drop_cnt_tbl_mul_p6_drop_byte_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_mul_p6_drop_cnt_tbl_mul_p6_drop_byte_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_mul_p6_drop_cnt_tbl_mul_p6_drop_pkt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mul_p6_drop_cnt_tbl_mul_p6_drop_pkt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mul_p7_drop_cnt_tbl_mul_p7_drop_pkt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mul_p7_drop_cnt_tbl_mul_p7_drop_pkt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mul_p7_drop_cnt_tbl_mul_p7_drop_byte_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_mul_p7_drop_cnt_tbl_mul_p7_drop_byte_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_uq_agg_profile_map_qid_2_agg_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uq_agg_profile_map_qid_2_agg_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uq_agg_profile_map_enable_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uq_agg_profile_map_enable_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_queue_tx_counter_tbl_tx_bytes_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_queue_tx_counter_tbl_tx_bytes_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_queue_tx_counter_tbl_tx_packets_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_queue_tx_counter_tbl_tx_packets_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_qm_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_qm_reg.h new file mode 100755 index 000000000..504d3c2d0 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_qm_reg.h @@ -0,0 +1,2748 @@ +/* + * 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 + * @{ + */ +#ifndef HPPE_QM_REG_H +#define HPPE_QM_REG_H + +/*[register] FLUSH_CFG*/ +#define FLUSH_CFG +#define FLUSH_CFG_ADDRESS 0x0 +#define FLUSH_CFG_NUM 1 +#define FLUSH_CFG_INC 0x4 +#define FLUSH_CFG_TYPE REG_TYPE_RW +#define FLUSH_CFG_DEFAULT 0x80000 + /*[field] FLUSH_QID*/ + #define FLUSH_CFG_FLUSH_QID + #define FLUSH_CFG_FLUSH_QID_OFFSET 0 + #define FLUSH_CFG_FLUSH_QID_LEN 9 + #define FLUSH_CFG_FLUSH_QID_DEFAULT 0x0 + /*[field] FLUSH_STATUS*/ + #define FLUSH_CFG_FLUSH_STATUS + #define FLUSH_CFG_FLUSH_STATUS_OFFSET 10 + #define FLUSH_CFG_FLUSH_STATUS_LEN 1 + #define FLUSH_CFG_FLUSH_STATUS_DEFAULT 0x0 + /*[field] FLUSH_WT_TIME*/ + #define FLUSH_CFG_FLUSH_WT_TIME + #define FLUSH_CFG_FLUSH_WT_TIME_OFFSET 11 + #define FLUSH_CFG_FLUSH_WT_TIME_LEN 10 + #define FLUSH_CFG_FLUSH_WT_TIME_DEFAULT 0x100 + /*[field] FLUSH_DST_PORT*/ + #define FLUSH_CFG_FLUSH_DST_PORT + #define FLUSH_CFG_FLUSH_DST_PORT_OFFSET 21 + #define FLUSH_CFG_FLUSH_DST_PORT_LEN 3 + #define FLUSH_CFG_FLUSH_DST_PORT_DEFAULT 0x0 + /*[field] FLUSH_ALL_QUEUES*/ + #define FLUSH_CFG_FLUSH_ALL_QUEUES + #define FLUSH_CFG_FLUSH_ALL_QUEUES_OFFSET 24 + #define FLUSH_CFG_FLUSH_ALL_QUEUES_LEN 1 + #define FLUSH_CFG_FLUSH_ALL_QUEUES_DEFAULT 0x0 + /*[field] FLUSH_BUSY*/ + #define FLUSH_CFG_FLUSH_BUSY + #define FLUSH_CFG_FLUSH_BUSY_OFFSET 31 + #define FLUSH_CFG_FLUSH_BUSY_LEN 1 + #define FLUSH_CFG_FLUSH_BUSY_DEFAULT 0x0 + +struct flush_cfg { + a_uint32_t flush_qid:9; + a_uint32_t _reserved0:1; + a_uint32_t flush_status:1; + a_uint32_t flush_wt_time:10; + a_uint32_t flush_dst_port:3; + a_uint32_t flush_all_queues:1; + a_uint32_t _reserved1:6; + a_uint32_t flush_busy:1; +}; + +union flush_cfg_u { + a_uint32_t val; + struct flush_cfg bf; +}; + +/*[register] IN_MIRROR_PRIORITY_CTRL*/ +#define IN_MIRROR_PRIORITY_CTRL +#define IN_MIRROR_PRIORITY_CTRL_ADDRESS 0x4 +#define IN_MIRROR_PRIORITY_CTRL_NUM 1 +#define IN_MIRROR_PRIORITY_CTRL_INC 0x4 +#define IN_MIRROR_PRIORITY_CTRL_TYPE REG_TYPE_RW +#define IN_MIRROR_PRIORITY_CTRL_DEFAULT 0x0 + /*[field] PRIORITY*/ + #define IN_MIRROR_PRIORITY_CTRL_PRIORITY + #define IN_MIRROR_PRIORITY_CTRL_PRIORITY_OFFSET 0 + #define IN_MIRROR_PRIORITY_CTRL_PRIORITY_LEN 4 + #define IN_MIRROR_PRIORITY_CTRL_PRIORITY_DEFAULT 0x0 + +struct in_mirror_priority_ctrl { + a_uint32_t priority:4; + a_uint32_t _reserved0:28; +}; + +union in_mirror_priority_ctrl_u { + a_uint32_t val; + struct in_mirror_priority_ctrl bf; +}; + +/*[register] EG_MIRROR_PRIORITY_CTRL*/ +#define EG_MIRROR_PRIORITY_CTRL +#define EG_MIRROR_PRIORITY_CTRL_ADDRESS 0x8 +#define EG_MIRROR_PRIORITY_CTRL_NUM 1 +#define EG_MIRROR_PRIORITY_CTRL_INC 0x4 +#define EG_MIRROR_PRIORITY_CTRL_TYPE REG_TYPE_RW +#define EG_MIRROR_PRIORITY_CTRL_DEFAULT 0x0 + /*[field] PRIORITY*/ + #define EG_MIRROR_PRIORITY_CTRL_PRIORITY + #define EG_MIRROR_PRIORITY_CTRL_PRIORITY_OFFSET 0 + #define EG_MIRROR_PRIORITY_CTRL_PRIORITY_LEN 4 + #define EG_MIRROR_PRIORITY_CTRL_PRIORITY_DEFAULT 0x0 + +struct eg_mirror_priority_ctrl { + a_uint32_t priority:4; + a_uint32_t _reserved0:28; +}; + +union eg_mirror_priority_ctrl_u { + a_uint32_t val; + struct eg_mirror_priority_ctrl bf; +}; + +/*[register] UCAST_DEFAULT_HASH*/ +#define UCAST_DEFAULT_HASH +#define UCAST_DEFAULT_HASH_ADDRESS 0x60 +#define UCAST_DEFAULT_HASH_NUM 1 +#define UCAST_DEFAULT_HASH_INC 0x4 +#define UCAST_DEFAULT_HASH_TYPE REG_TYPE_RW +#define UCAST_DEFAULT_HASH_DEFAULT 0x0 + /*[field] HASH*/ + #define UCAST_DEFAULT_HASH_HASH + #define UCAST_DEFAULT_HASH_HASH_OFFSET 0 + #define UCAST_DEFAULT_HASH_HASH_LEN 8 + #define UCAST_DEFAULT_HASH_HASH_DEFAULT 0x0 + +struct ucast_default_hash { + a_uint32_t hash:8; + a_uint32_t _reserved0:24; +}; + +union ucast_default_hash_u { + a_uint32_t val; + struct ucast_default_hash bf; +}; + +/*[register] SPARE_REG0*/ +#define SPARE_REG0 +#define SPARE_REG0_ADDRESS 0x70 +#define SPARE_REG0_NUM 1 +#define SPARE_REG0_INC 0x4 +#define SPARE_REG0_TYPE REG_TYPE_RW +#define SPARE_REG0_DEFAULT 0x0 + /*[field] SPARE_REG0*/ + #define SPARE_REG0_SPARE_REG0 + #define SPARE_REG0_SPARE_REG0_OFFSET 0 + #define SPARE_REG0_SPARE_REG0_LEN 32 + #define SPARE_REG0_SPARE_REG0_DEFAULT 0x0 + +struct spare_reg0 { + a_uint32_t spare_reg0:32; +}; + +union spare_reg0_u { + a_uint32_t val; + struct spare_reg0 bf; +}; + +/*[register] SPARE_REG1*/ +#define SPARE_REG1 +#define SPARE_REG1_ADDRESS 0x74 +#define SPARE_REG1_NUM 1 +#define SPARE_REG1_INC 0x4 +#define SPARE_REG1_TYPE REG_TYPE_RW +#define SPARE_REG1_DEFAULT 0x0 + /*[field] SPARE_REG1*/ + #define SPARE_REG1_SPARE_REG1 + #define SPARE_REG1_SPARE_REG1_OFFSET 0 + #define SPARE_REG1_SPARE_REG1_LEN 32 + #define SPARE_REG1_SPARE_REG1_DEFAULT 0x0 + +struct spare_reg1 { + a_uint32_t spare_reg1:32; +}; + +union spare_reg1_u { + a_uint32_t val; + struct spare_reg1 bf; +}; + +/*[register] QM_DBG_ADDR*/ +#define QM_DBG_ADDR +#define QM_DBG_ADDR_ADDRESS 0x80 +#define QM_DBG_ADDR_NUM 1 +#define QM_DBG_ADDR_INC 0x4 +#define QM_DBG_ADDR_TYPE REG_TYPE_RW +#define QM_DBG_ADDR_DEFAULT 0x0 + /*[field] DBG_ADDR*/ + #define QM_DBG_ADDR_DBG_ADDR + #define QM_DBG_ADDR_DBG_ADDR_OFFSET 0 + #define QM_DBG_ADDR_DBG_ADDR_LEN 8 + #define QM_DBG_ADDR_DBG_ADDR_DEFAULT 0x0 + +struct qm_dbg_addr { + a_uint32_t dbg_addr:8; + a_uint32_t _reserved0:24; +}; + +union qm_dbg_addr_u { + a_uint32_t val; + struct qm_dbg_addr bf; +}; + +/*[register] QM_DBG_DATA*/ +#define QM_DBG_DATA +#define QM_DBG_DATA_ADDRESS 0x84 +#define QM_DBG_DATA_NUM 1 +#define QM_DBG_DATA_INC 0x4 +#define QM_DBG_DATA_TYPE REG_TYPE_RO +#define QM_DBG_DATA_DEFAULT 0x0 + /*[field] DBG_DATA*/ + #define QM_DBG_DATA_DBG_DATA + #define QM_DBG_DATA_DBG_DATA_OFFSET 0 + #define QM_DBG_DATA_DBG_DATA_LEN 32 + #define QM_DBG_DATA_DBG_DATA_DEFAULT 0x0 + +struct qm_dbg_data { + a_uint32_t dbg_data:32; +}; + +union qm_dbg_data_u { + a_uint32_t val; + struct qm_dbg_data bf; +}; + +/*[register] MCAST_PRIORITY_MAP0*/ +#define MCAST_PRIORITY_MAP0 +#define MCAST_PRIORITY_MAP0_ADDRESS 0x100 +#define MCAST_PRIORITY_MAP0_NUM 16 +#define MCAST_PRIORITY_MAP0_INC 0x4 +#define MCAST_PRIORITY_MAP0_TYPE REG_TYPE_RW +#define MCAST_PRIORITY_MAP0_DEFAULT 0x0 + /*[field] CLASS*/ + #define MCAST_PRIORITY_MAP0_CLASS + #define MCAST_PRIORITY_MAP0_CLASS_OFFSET 0 + #define MCAST_PRIORITY_MAP0_CLASS_LEN 4 + #define MCAST_PRIORITY_MAP0_CLASS_DEFAULT 0x0 + +struct mcast_priority_map0 { + a_uint32_t class:4; + a_uint32_t _reserved0:28; +}; + +union mcast_priority_map0_u { + a_uint32_t val; + struct mcast_priority_map0 bf; +}; + +/*[register] MCAST_PRIORITY_MAP1*/ +#define MCAST_PRIORITY_MAP1 +#define MCAST_PRIORITY_MAP1_ADDRESS 0x140 +#define MCAST_PRIORITY_MAP1_NUM 16 +#define MCAST_PRIORITY_MAP1_INC 0x4 +#define MCAST_PRIORITY_MAP1_TYPE REG_TYPE_RW +#define MCAST_PRIORITY_MAP1_DEFAULT 0x0 + /*[field] CLASS*/ + #define MCAST_PRIORITY_MAP1_CLASS + #define MCAST_PRIORITY_MAP1_CLASS_OFFSET 0 + #define MCAST_PRIORITY_MAP1_CLASS_LEN 2 + #define MCAST_PRIORITY_MAP1_CLASS_DEFAULT 0x0 + +struct mcast_priority_map1 { + a_uint32_t class:2; + a_uint32_t _reserved0:30; +}; + +union mcast_priority_map1_u { + a_uint32_t val; + struct mcast_priority_map1 bf; +}; + +/*[register] MCAST_PRIORITY_MAP2*/ +#define MCAST_PRIORITY_MAP2 +#define MCAST_PRIORITY_MAP2_ADDRESS 0x180 +#define MCAST_PRIORITY_MAP2_NUM 16 +#define MCAST_PRIORITY_MAP2_INC 0x4 +#define MCAST_PRIORITY_MAP2_TYPE REG_TYPE_RW +#define MCAST_PRIORITY_MAP2_DEFAULT 0x0 + /*[field] CLASS*/ + #define MCAST_PRIORITY_MAP2_CLASS + #define MCAST_PRIORITY_MAP2_CLASS_OFFSET 0 + #define MCAST_PRIORITY_MAP2_CLASS_LEN 2 + #define MCAST_PRIORITY_MAP2_CLASS_DEFAULT 0x0 + +struct mcast_priority_map2 { + a_uint32_t class:2; + a_uint32_t _reserved0:30; +}; + +union mcast_priority_map2_u { + a_uint32_t val; + struct mcast_priority_map2 bf; +}; + +/*[register] MCAST_PRIORITY_MAP3*/ +#define MCAST_PRIORITY_MAP3 +#define MCAST_PRIORITY_MAP3_ADDRESS 0x1c0 +#define MCAST_PRIORITY_MAP3_NUM 16 +#define MCAST_PRIORITY_MAP3_INC 0x4 +#define MCAST_PRIORITY_MAP3_TYPE REG_TYPE_RW +#define MCAST_PRIORITY_MAP3_DEFAULT 0x0 + /*[field] CLASS*/ + #define MCAST_PRIORITY_MAP3_CLASS + #define MCAST_PRIORITY_MAP3_CLASS_OFFSET 0 + #define MCAST_PRIORITY_MAP3_CLASS_LEN 2 + #define MCAST_PRIORITY_MAP3_CLASS_DEFAULT 0x0 + +struct mcast_priority_map3 { + a_uint32_t class:2; + a_uint32_t _reserved0:30; +}; + +union mcast_priority_map3_u { + a_uint32_t val; + struct mcast_priority_map3 bf; +}; + +/*[register] MCAST_PRIORITY_MAP4*/ +#define MCAST_PRIORITY_MAP4 +#define MCAST_PRIORITY_MAP4_ADDRESS 0x200 +#define MCAST_PRIORITY_MAP4_NUM 16 +#define MCAST_PRIORITY_MAP4_INC 0x4 +#define MCAST_PRIORITY_MAP4_TYPE REG_TYPE_RW +#define MCAST_PRIORITY_MAP4_DEFAULT 0x0 + /*[field] CLASS*/ + #define MCAST_PRIORITY_MAP4_CLASS + #define MCAST_PRIORITY_MAP4_CLASS_OFFSET 0 + #define MCAST_PRIORITY_MAP4_CLASS_LEN 2 + #define MCAST_PRIORITY_MAP4_CLASS_DEFAULT 0x0 + +struct mcast_priority_map4 { + a_uint32_t class:2; + a_uint32_t _reserved0:30; +}; + +union mcast_priority_map4_u { + a_uint32_t val; + struct mcast_priority_map4 bf; +}; + +/*[register] MCAST_PRIORITY_MAP5*/ +#define MCAST_PRIORITY_MAP5 +#define MCAST_PRIORITY_MAP5_ADDRESS 0x240 +#define MCAST_PRIORITY_MAP5_NUM 16 +#define MCAST_PRIORITY_MAP5_INC 0x4 +#define MCAST_PRIORITY_MAP5_TYPE REG_TYPE_RW +#define MCAST_PRIORITY_MAP5_DEFAULT 0x0 + /*[field] CLASS*/ + #define MCAST_PRIORITY_MAP5_CLASS + #define MCAST_PRIORITY_MAP5_CLASS_OFFSET 0 + #define MCAST_PRIORITY_MAP5_CLASS_LEN 2 + #define MCAST_PRIORITY_MAP5_CLASS_DEFAULT 0x0 + +struct mcast_priority_map5 { + a_uint32_t class:2; + a_uint32_t _reserved0:30; +}; + +union mcast_priority_map5_u { + a_uint32_t val; + struct mcast_priority_map5 bf; +}; + +/*[register] MCAST_PRIORITY_MAP6*/ +#define MCAST_PRIORITY_MAP6 +#define MCAST_PRIORITY_MAP6_ADDRESS 0x280 +#define MCAST_PRIORITY_MAP6_NUM 16 +#define MCAST_PRIORITY_MAP6_INC 0x4 +#define MCAST_PRIORITY_MAP6_TYPE REG_TYPE_RW +#define MCAST_PRIORITY_MAP6_DEFAULT 0x0 + /*[field] CLASS*/ + #define MCAST_PRIORITY_MAP6_CLASS + #define MCAST_PRIORITY_MAP6_CLASS_OFFSET 0 + #define MCAST_PRIORITY_MAP6_CLASS_LEN 2 + #define MCAST_PRIORITY_MAP6_CLASS_DEFAULT 0x0 + +struct mcast_priority_map6 { + a_uint32_t class:2; + a_uint32_t _reserved0:30; +}; + +union mcast_priority_map6_u { + a_uint32_t val; + struct mcast_priority_map6 bf; +}; + +/*[register] MCAST_PRIORITY_MAP7*/ +#define MCAST_PRIORITY_MAP7 +#define MCAST_PRIORITY_MAP7_ADDRESS 0x2c0 +#define MCAST_PRIORITY_MAP7_NUM 16 +#define MCAST_PRIORITY_MAP7_INC 0x4 +#define MCAST_PRIORITY_MAP7_TYPE REG_TYPE_RW +#define MCAST_PRIORITY_MAP7_DEFAULT 0x0 + /*[field] CLASS*/ + #define MCAST_PRIORITY_MAP7_CLASS + #define MCAST_PRIORITY_MAP7_CLASS_OFFSET 0 + #define MCAST_PRIORITY_MAP7_CLASS_LEN 2 + #define MCAST_PRIORITY_MAP7_CLASS_DEFAULT 0x0 + +struct mcast_priority_map7 { + a_uint32_t class:2; + a_uint32_t _reserved0:30; +}; + +union mcast_priority_map7_u { + a_uint32_t val; + struct mcast_priority_map7 bf; +}; + +/*[register] AGG_PROFILE_CNT_EN*/ +#define AGG_PROFILE_CNT_EN +#define AGG_PROFILE_CNT_EN_ADDRESS 0x300 +#define AGG_PROFILE_CNT_EN_NUM 1 +#define AGG_PROFILE_CNT_EN_INC 0x4 +#define AGG_PROFILE_CNT_EN_TYPE REG_TYPE_RW +#define AGG_PROFILE_CNT_EN_DEFAULT 0xfffff + /*[field] UQ_EN_0*/ + #define AGG_PROFILE_CNT_EN_UQ_EN_0 + #define AGG_PROFILE_CNT_EN_UQ_EN_0_OFFSET 0 + #define AGG_PROFILE_CNT_EN_UQ_EN_0_LEN 1 + #define AGG_PROFILE_CNT_EN_UQ_EN_0_DEFAULT 0x1 + /*[field] UQ_EN_1*/ + #define AGG_PROFILE_CNT_EN_UQ_EN_1 + #define AGG_PROFILE_CNT_EN_UQ_EN_1_OFFSET 1 + #define AGG_PROFILE_CNT_EN_UQ_EN_1_LEN 1 + #define AGG_PROFILE_CNT_EN_UQ_EN_1_DEFAULT 0x1 + /*[field] UQ_EN_2*/ + #define AGG_PROFILE_CNT_EN_UQ_EN_2 + #define AGG_PROFILE_CNT_EN_UQ_EN_2_OFFSET 2 + #define AGG_PROFILE_CNT_EN_UQ_EN_2_LEN 1 + #define AGG_PROFILE_CNT_EN_UQ_EN_2_DEFAULT 0x1 + /*[field] UQ_EN_3*/ + #define AGG_PROFILE_CNT_EN_UQ_EN_3 + #define AGG_PROFILE_CNT_EN_UQ_EN_3_OFFSET 3 + #define AGG_PROFILE_CNT_EN_UQ_EN_3_LEN 1 + #define AGG_PROFILE_CNT_EN_UQ_EN_3_DEFAULT 0x1 + /*[field] UQ_EN_4*/ + #define AGG_PROFILE_CNT_EN_UQ_EN_4 + #define AGG_PROFILE_CNT_EN_UQ_EN_4_OFFSET 4 + #define AGG_PROFILE_CNT_EN_UQ_EN_4_LEN 1 + #define AGG_PROFILE_CNT_EN_UQ_EN_4_DEFAULT 0x1 + /*[field] UQ_EN_5*/ + #define AGG_PROFILE_CNT_EN_UQ_EN_5 + #define AGG_PROFILE_CNT_EN_UQ_EN_5_OFFSET 5 + #define AGG_PROFILE_CNT_EN_UQ_EN_5_LEN 1 + #define AGG_PROFILE_CNT_EN_UQ_EN_5_DEFAULT 0x1 + /*[field] UQ_EN_6*/ + #define AGG_PROFILE_CNT_EN_UQ_EN_6 + #define AGG_PROFILE_CNT_EN_UQ_EN_6_OFFSET 6 + #define AGG_PROFILE_CNT_EN_UQ_EN_6_LEN 1 + #define AGG_PROFILE_CNT_EN_UQ_EN_6_DEFAULT 0x1 + /*[field] UQ_EN_7*/ + #define AGG_PROFILE_CNT_EN_UQ_EN_7 + #define AGG_PROFILE_CNT_EN_UQ_EN_7_OFFSET 7 + #define AGG_PROFILE_CNT_EN_UQ_EN_7_LEN 1 + #define AGG_PROFILE_CNT_EN_UQ_EN_7_DEFAULT 0x1 + /*[field] MQ_P0_EN*/ + #define AGG_PROFILE_CNT_EN_MQ_P0_EN + #define AGG_PROFILE_CNT_EN_MQ_P0_EN_OFFSET 8 + #define AGG_PROFILE_CNT_EN_MQ_P0_EN_LEN 1 + #define AGG_PROFILE_CNT_EN_MQ_P0_EN_DEFAULT 0x1 + /*[field] MQ_P1_EN*/ + #define AGG_PROFILE_CNT_EN_MQ_P1_EN + #define AGG_PROFILE_CNT_EN_MQ_P1_EN_OFFSET 9 + #define AGG_PROFILE_CNT_EN_MQ_P1_EN_LEN 1 + #define AGG_PROFILE_CNT_EN_MQ_P1_EN_DEFAULT 0x1 + /*[field] MQ_P2_EN*/ + #define AGG_PROFILE_CNT_EN_MQ_P2_EN + #define AGG_PROFILE_CNT_EN_MQ_P2_EN_OFFSET 10 + #define AGG_PROFILE_CNT_EN_MQ_P2_EN_LEN 1 + #define AGG_PROFILE_CNT_EN_MQ_P2_EN_DEFAULT 0x1 + /*[field] MQ_P3_EN*/ + #define AGG_PROFILE_CNT_EN_MQ_P3_EN + #define AGG_PROFILE_CNT_EN_MQ_P3_EN_OFFSET 11 + #define AGG_PROFILE_CNT_EN_MQ_P3_EN_LEN 1 + #define AGG_PROFILE_CNT_EN_MQ_P3_EN_DEFAULT 0x1 + /*[field] MQ_P4_EN*/ + #define AGG_PROFILE_CNT_EN_MQ_P4_EN + #define AGG_PROFILE_CNT_EN_MQ_P4_EN_OFFSET 12 + #define AGG_PROFILE_CNT_EN_MQ_P4_EN_LEN 1 + #define AGG_PROFILE_CNT_EN_MQ_P4_EN_DEFAULT 0x1 + /*[field] MQ_P5_EN*/ + #define AGG_PROFILE_CNT_EN_MQ_P5_EN + #define AGG_PROFILE_CNT_EN_MQ_P5_EN_OFFSET 13 + #define AGG_PROFILE_CNT_EN_MQ_P5_EN_LEN 1 + #define AGG_PROFILE_CNT_EN_MQ_P5_EN_DEFAULT 0x1 + /*[field] MQ_P6_EN*/ + #define AGG_PROFILE_CNT_EN_MQ_P6_EN + #define AGG_PROFILE_CNT_EN_MQ_P6_EN_OFFSET 14 + #define AGG_PROFILE_CNT_EN_MQ_P6_EN_LEN 1 + #define AGG_PROFILE_CNT_EN_MQ_P6_EN_DEFAULT 0x1 + /*[field] MQ_P7_EN*/ + #define AGG_PROFILE_CNT_EN_MQ_P7_EN + #define AGG_PROFILE_CNT_EN_MQ_P7_EN_OFFSET 15 + #define AGG_PROFILE_CNT_EN_MQ_P7_EN_LEN 1 + #define AGG_PROFILE_CNT_EN_MQ_P7_EN_DEFAULT 0x1 + /*[field] GRP_0_EN*/ + #define AGG_PROFILE_CNT_EN_GRP_0_EN + #define AGG_PROFILE_CNT_EN_GRP_0_EN_OFFSET 16 + #define AGG_PROFILE_CNT_EN_GRP_0_EN_LEN 1 + #define AGG_PROFILE_CNT_EN_GRP_0_EN_DEFAULT 0x1 + /*[field] GRP_1_EN*/ + #define AGG_PROFILE_CNT_EN_GRP_1_EN + #define AGG_PROFILE_CNT_EN_GRP_1_EN_OFFSET 17 + #define AGG_PROFILE_CNT_EN_GRP_1_EN_LEN 1 + #define AGG_PROFILE_CNT_EN_GRP_1_EN_DEFAULT 0x1 + /*[field] GRP_2_EN*/ + #define AGG_PROFILE_CNT_EN_GRP_2_EN + #define AGG_PROFILE_CNT_EN_GRP_2_EN_OFFSET 18 + #define AGG_PROFILE_CNT_EN_GRP_2_EN_LEN 1 + #define AGG_PROFILE_CNT_EN_GRP_2_EN_DEFAULT 0x1 + /*[field] GRP_3_EN*/ + #define AGG_PROFILE_CNT_EN_GRP_3_EN + #define AGG_PROFILE_CNT_EN_GRP_3_EN_OFFSET 19 + #define AGG_PROFILE_CNT_EN_GRP_3_EN_LEN 1 + #define AGG_PROFILE_CNT_EN_GRP_3_EN_DEFAULT 0x1 + /*[field] GLOBAL_EN*/ + #define AGG_PROFILE_CNT_EN_GLOBAL_EN + #define AGG_PROFILE_CNT_EN_GLOBAL_EN_OFFSET 31 + #define AGG_PROFILE_CNT_EN_GLOBAL_EN_LEN 1 + #define AGG_PROFILE_CNT_EN_GLOBAL_EN_DEFAULT 0x0 + +struct agg_profile_cnt_en { + a_uint32_t uq_en_0:1; + a_uint32_t uq_en_1:1; + a_uint32_t uq_en_2:1; + a_uint32_t uq_en_3:1; + a_uint32_t uq_en_4:1; + a_uint32_t uq_en_5:1; + a_uint32_t uq_en_6:1; + a_uint32_t uq_en_7:1; + a_uint32_t mq_p0_en:1; + a_uint32_t mq_p1_en:1; + a_uint32_t mq_p2_en:1; + a_uint32_t mq_p3_en:1; + a_uint32_t mq_p4_en:1; + a_uint32_t mq_p5_en:1; + a_uint32_t mq_p6_en:1; + a_uint32_t mq_p7_en:1; + a_uint32_t grp_0_en:1; + a_uint32_t grp_1_en:1; + a_uint32_t grp_2_en:1; + a_uint32_t grp_3_en:1; + a_uint32_t _reserved0:11; + a_uint32_t global_en:1; +}; + +union agg_profile_cnt_en_u { + a_uint32_t val; + struct agg_profile_cnt_en bf; +}; + +/*[register] UQ_AGG_PROFILE_CFG*/ +#define UQ_AGG_PROFILE_CFG +#define UQ_AGG_PROFILE_CFG_ADDRESS 0x320 +#define UQ_AGG_PROFILE_CFG_NUM 8 +#define UQ_AGG_PROFILE_CFG_INC 0x4 +#define UQ_AGG_PROFILE_CFG_TYPE REG_TYPE_RW +#define UQ_AGG_PROFILE_CFG_DEFAULT 0x0 + /*[field] TH_CFG*/ + #define UQ_AGG_PROFILE_CFG_TH_CFG + #define UQ_AGG_PROFILE_CFG_TH_CFG_OFFSET 0 + #define UQ_AGG_PROFILE_CFG_TH_CFG_LEN 11 + #define UQ_AGG_PROFILE_CFG_TH_CFG_DEFAULT 0x0 + +struct uq_agg_profile_cfg { + a_uint32_t th_cfg:11; + a_uint32_t _reserved0:21; +}; + +union uq_agg_profile_cfg_u { + a_uint32_t val; + struct uq_agg_profile_cfg bf; +}; + +/*[register] MQ_AGG_PROFILE_CFG*/ +#define MQ_AGG_PROFILE_CFG +#define MQ_AGG_PROFILE_CFG_ADDRESS 0x340 +#define MQ_AGG_PROFILE_CFG_NUM 8 +#define MQ_AGG_PROFILE_CFG_INC 0x4 +#define MQ_AGG_PROFILE_CFG_TYPE REG_TYPE_RW +#define MQ_AGG_PROFILE_CFG_DEFAULT 0x0 + /*[field] TH_CFG*/ + #define MQ_AGG_PROFILE_CFG_TH_CFG + #define MQ_AGG_PROFILE_CFG_TH_CFG_OFFSET 0 + #define MQ_AGG_PROFILE_CFG_TH_CFG_LEN 11 + #define MQ_AGG_PROFILE_CFG_TH_CFG_DEFAULT 0x0 + +struct mq_agg_profile_cfg { + a_uint32_t th_cfg:11; + a_uint32_t _reserved0:21; +}; + +union mq_agg_profile_cfg_u { + a_uint32_t val; + struct mq_agg_profile_cfg bf; +}; + +/*[register] GRP_AGG_PROFILE_CFG*/ +#define GRP_AGG_PROFILE_CFG +#define GRP_AGG_PROFILE_CFG_ADDRESS 0x360 +#define GRP_AGG_PROFILE_CFG_NUM 4 +#define GRP_AGG_PROFILE_CFG_INC 0x4 +#define GRP_AGG_PROFILE_CFG_TYPE REG_TYPE_RW +#define GRP_AGG_PROFILE_CFG_DEFAULT 0x0 + /*[field] TH_CFG*/ + #define GRP_AGG_PROFILE_CFG_TH_CFG + #define GRP_AGG_PROFILE_CFG_TH_CFG_OFFSET 0 + #define GRP_AGG_PROFILE_CFG_TH_CFG_LEN 11 + #define GRP_AGG_PROFILE_CFG_TH_CFG_DEFAULT 0x0 + +struct grp_agg_profile_cfg { + a_uint32_t th_cfg:11; + a_uint32_t _reserved0:21; +}; + +union grp_agg_profile_cfg_u { + a_uint32_t val; + struct grp_agg_profile_cfg bf; +}; + +/*[register] UQ_AGG_IN_PROFILE_CNT*/ +#define UQ_AGG_IN_PROFILE_CNT +#define UQ_AGG_IN_PROFILE_CNT_ADDRESS 0x380 +#define UQ_AGG_IN_PROFILE_CNT_NUM 8 +#define UQ_AGG_IN_PROFILE_CNT_INC 0x4 +#define UQ_AGG_IN_PROFILE_CNT_TYPE REG_TYPE_RW +#define UQ_AGG_IN_PROFILE_CNT_DEFAULT 0x0 + /*[field] CNT*/ + #define UQ_AGG_IN_PROFILE_CNT_CNT + #define UQ_AGG_IN_PROFILE_CNT_CNT_OFFSET 0 + #define UQ_AGG_IN_PROFILE_CNT_CNT_LEN 32 + #define UQ_AGG_IN_PROFILE_CNT_CNT_DEFAULT 0x0 + +struct uq_agg_in_profile_cnt { + a_uint32_t cnt:32; +}; + +union uq_agg_in_profile_cnt_u { + a_uint32_t val; + struct uq_agg_in_profile_cnt bf; +}; + +/*[register] UQ_AGG_OUT_PROFILE_CNT*/ +#define UQ_AGG_OUT_PROFILE_CNT +#define UQ_AGG_OUT_PROFILE_CNT_ADDRESS 0x3a0 +#define UQ_AGG_OUT_PROFILE_CNT_NUM 8 +#define UQ_AGG_OUT_PROFILE_CNT_INC 0x4 +#define UQ_AGG_OUT_PROFILE_CNT_TYPE REG_TYPE_RW +#define UQ_AGG_OUT_PROFILE_CNT_DEFAULT 0x0 + /*[field] CNT*/ + #define UQ_AGG_OUT_PROFILE_CNT_CNT + #define UQ_AGG_OUT_PROFILE_CNT_CNT_OFFSET 0 + #define UQ_AGG_OUT_PROFILE_CNT_CNT_LEN 32 + #define UQ_AGG_OUT_PROFILE_CNT_CNT_DEFAULT 0x0 + +struct uq_agg_out_profile_cnt { + a_uint32_t cnt:32; +}; + +union uq_agg_out_profile_cnt_u { + a_uint32_t val; + struct uq_agg_out_profile_cnt bf; +}; + +/*[register] MQ_AGG_IN_PROFILE_CNT*/ +#define MQ_AGG_IN_PROFILE_CNT +#define MQ_AGG_IN_PROFILE_CNT_ADDRESS 0x3c0 +#define MQ_AGG_IN_PROFILE_CNT_NUM 8 +#define MQ_AGG_IN_PROFILE_CNT_INC 0x4 +#define MQ_AGG_IN_PROFILE_CNT_TYPE REG_TYPE_RW +#define MQ_AGG_IN_PROFILE_CNT_DEFAULT 0x0 + /*[field] CNT*/ + #define MQ_AGG_IN_PROFILE_CNT_CNT + #define MQ_AGG_IN_PROFILE_CNT_CNT_OFFSET 0 + #define MQ_AGG_IN_PROFILE_CNT_CNT_LEN 32 + #define MQ_AGG_IN_PROFILE_CNT_CNT_DEFAULT 0x0 + +struct mq_agg_in_profile_cnt { + a_uint32_t cnt:32; +}; + +union mq_agg_in_profile_cnt_u { + a_uint32_t val; + struct mq_agg_in_profile_cnt bf; +}; + +/*[register] MQ_AGG_OUT_PROFILE_CNT*/ +#define MQ_AGG_OUT_PROFILE_CNT +#define MQ_AGG_OUT_PROFILE_CNT_ADDRESS 0x3e0 +#define MQ_AGG_OUT_PROFILE_CNT_NUM 8 +#define MQ_AGG_OUT_PROFILE_CNT_INC 0x4 +#define MQ_AGG_OUT_PROFILE_CNT_TYPE REG_TYPE_RW +#define MQ_AGG_OUT_PROFILE_CNT_DEFAULT 0x0 + /*[field] CNT*/ + #define MQ_AGG_OUT_PROFILE_CNT_CNT + #define MQ_AGG_OUT_PROFILE_CNT_CNT_OFFSET 0 + #define MQ_AGG_OUT_PROFILE_CNT_CNT_LEN 32 + #define MQ_AGG_OUT_PROFILE_CNT_CNT_DEFAULT 0x0 + +struct mq_agg_out_profile_cnt { + a_uint32_t cnt:32; +}; + +union mq_agg_out_profile_cnt_u { + a_uint32_t val; + struct mq_agg_out_profile_cnt bf; +}; + +/*[register] GRP_AGG_IN_PROFILE_CNT*/ +#define GRP_AGG_IN_PROFILE_CNT +#define GRP_AGG_IN_PROFILE_CNT_ADDRESS 0x400 +#define GRP_AGG_IN_PROFILE_CNT_NUM 4 +#define GRP_AGG_IN_PROFILE_CNT_INC 0x4 +#define GRP_AGG_IN_PROFILE_CNT_TYPE REG_TYPE_RW +#define GRP_AGG_IN_PROFILE_CNT_DEFAULT 0x0 + /*[field] CNT*/ + #define GRP_AGG_IN_PROFILE_CNT_CNT + #define GRP_AGG_IN_PROFILE_CNT_CNT_OFFSET 0 + #define GRP_AGG_IN_PROFILE_CNT_CNT_LEN 32 + #define GRP_AGG_IN_PROFILE_CNT_CNT_DEFAULT 0x0 + +struct grp_agg_in_profile_cnt { + a_uint32_t cnt:32; +}; + +union grp_agg_in_profile_cnt_u { + a_uint32_t val; + struct grp_agg_in_profile_cnt bf; +}; + +/*[register] GRP_AGG_OUT_PROFILE_CNT*/ +#define GRP_AGG_OUT_PROFILE_CNT +#define GRP_AGG_OUT_PROFILE_CNT_ADDRESS 0x410 +#define GRP_AGG_OUT_PROFILE_CNT_NUM 4 +#define GRP_AGG_OUT_PROFILE_CNT_INC 0x4 +#define GRP_AGG_OUT_PROFILE_CNT_TYPE REG_TYPE_RW +#define GRP_AGG_OUT_PROFILE_CNT_DEFAULT 0x0 + /*[field] CNT*/ + #define GRP_AGG_OUT_PROFILE_CNT_CNT + #define GRP_AGG_OUT_PROFILE_CNT_CNT_OFFSET 0 + #define GRP_AGG_OUT_PROFILE_CNT_CNT_LEN 32 + #define GRP_AGG_OUT_PROFILE_CNT_CNT_DEFAULT 0x0 + +struct grp_agg_out_profile_cnt { + a_uint32_t cnt:32; +}; + +union grp_agg_out_profile_cnt_u { + a_uint32_t val; + struct grp_agg_out_profile_cnt bf; +}; + +/*[table] UCAST_QUEUE_MAP_TBL*/ +#define UCAST_QUEUE_MAP_TBL +#define UCAST_QUEUE_MAP_TBL_ADDRESS 0x10000 +#define UCAST_QUEUE_MAP_TBL_NUM 3072 +#define UCAST_QUEUE_MAP_TBL_INC 0x10 +#define UCAST_QUEUE_MAP_TBL_TYPE REG_TYPE_RW +#define UCAST_QUEUE_MAP_TBL_DEFAULT 0x0 + /*[field] PROFILE_ID*/ + #define UCAST_QUEUE_MAP_TBL_PROFILE_ID + #define UCAST_QUEUE_MAP_TBL_PROFILE_ID_OFFSET 0 + #define UCAST_QUEUE_MAP_TBL_PROFILE_ID_LEN 4 + #define UCAST_QUEUE_MAP_TBL_PROFILE_ID_DEFAULT 0x0 + /*[field] QUEUE_ID*/ + #define UCAST_QUEUE_MAP_TBL_QUEUE_ID + #define UCAST_QUEUE_MAP_TBL_QUEUE_ID_OFFSET 4 + #define UCAST_QUEUE_MAP_TBL_QUEUE_ID_LEN 8 + #define UCAST_QUEUE_MAP_TBL_QUEUE_ID_DEFAULT 0x0 + +struct ucast_queue_map_tbl { + a_uint32_t profile_id:4; + a_uint32_t queue_id:8; + a_uint32_t _reserved0:20; +}; + +union ucast_queue_map_tbl_u { + a_uint32_t val; + struct ucast_queue_map_tbl bf; +}; + +/*[table] UCAST_HASH_MAP_TBL*/ +#define UCAST_HASH_MAP_TBL +#define UCAST_HASH_MAP_TBL_ADDRESS 0x30000 +#define UCAST_HASH_MAP_TBL_NUM 4096 +#define UCAST_HASH_MAP_TBL_INC 0x10 +#define UCAST_HASH_MAP_TBL_TYPE REG_TYPE_RW +#define UCAST_HASH_MAP_TBL_DEFAULT 0x0 + /*[field] HASH*/ + #define UCAST_HASH_MAP_TBL_HASH + #define UCAST_HASH_MAP_TBL_HASH_OFFSET 0 + #define UCAST_HASH_MAP_TBL_HASH_LEN 8 + #define UCAST_HASH_MAP_TBL_HASH_DEFAULT 0x0 + +struct ucast_hash_map_tbl { + a_uint32_t hash:8; + a_uint32_t _reserved0:24; +}; + +union ucast_hash_map_tbl_u { + a_uint32_t val; + struct ucast_hash_map_tbl bf; +}; + +/*[table] UCAST_PRIORITY_MAP_TBL*/ +#define UCAST_PRIORITY_MAP_TBL +#define UCAST_PRIORITY_MAP_TBL_ADDRESS 0x42000 +#define UCAST_PRIORITY_MAP_TBL_NUM 256 +#define UCAST_PRIORITY_MAP_TBL_INC 0x10 +#define UCAST_PRIORITY_MAP_TBL_TYPE REG_TYPE_RW +#define UCAST_PRIORITY_MAP_TBL_DEFAULT 0x0 + /*[field] CLASS*/ + #define UCAST_PRIORITY_MAP_TBL_CLASS + #define UCAST_PRIORITY_MAP_TBL_CLASS_OFFSET 0 + #define UCAST_PRIORITY_MAP_TBL_CLASS_LEN 4 + #define UCAST_PRIORITY_MAP_TBL_CLASS_DEFAULT 0x0 + +struct ucast_priority_map_tbl { + a_uint32_t class:4; + a_uint32_t _reserved0:28; +}; + +union ucast_priority_map_tbl_u { + a_uint32_t val; + struct ucast_priority_map_tbl bf; +}; + +/*[table] MCAST_QUEUE_MAP_TBL*/ +#define MCAST_QUEUE_MAP_TBL +#define MCAST_QUEUE_MAP_TBL_ADDRESS 0x44000 +#define MCAST_QUEUE_MAP_TBL_NUM 256 +#define MCAST_QUEUE_MAP_TBL_INC 0x10 +#define MCAST_QUEUE_MAP_TBL_TYPE REG_TYPE_RW +#define MCAST_QUEUE_MAP_TBL_DEFAULT 0x0 + /*[field] CLASS*/ + #define MCAST_QUEUE_MAP_TBL_CLASS + #define MCAST_QUEUE_MAP_TBL_CLASS_OFFSET 0 + #define MCAST_QUEUE_MAP_TBL_CLASS_LEN 4 + #define MCAST_QUEUE_MAP_TBL_CLASS_DEFAULT 0x0 + +struct mcast_queue_map_tbl { + a_uint32_t class:4; + a_uint32_t _reserved0:28; +}; + +union mcast_queue_map_tbl_u { + a_uint32_t val; + struct mcast_queue_map_tbl bf; +}; + +/*[table] AC_MSEQ_TBL*/ +#define AC_MSEQ_TBL +#define AC_MSEQ_TBL_ADDRESS 0x46000 +#define AC_MSEQ_TBL_NUM 256 +#define AC_MSEQ_TBL_INC 0x10 +#define AC_MSEQ_TBL_TYPE REG_TYPE_RW +#define AC_MSEQ_TBL_DEFAULT 0x0 + /*[field] AC_MSEQ*/ + #define AC_MSEQ_TBL_AC_MSEQ + #define AC_MSEQ_TBL_AC_MSEQ_OFFSET 0 + #define AC_MSEQ_TBL_AC_MSEQ_LEN 15 + #define AC_MSEQ_TBL_AC_MSEQ_DEFAULT 0x0 + +struct ac_mseq_tbl { + a_uint32_t ac_mseq:15; + a_uint32_t _reserved0:17; +}; + +union ac_mseq_tbl_u { + a_uint32_t val; + struct ac_mseq_tbl bf; +}; + +/*[table] AC_UNI_QUEUE_CFG_TBL*/ +#define AC_UNI_QUEUE_CFG_TBL +#define AC_UNI_QUEUE_CFG_TBL_ADDRESS 0x48000 +#define AC_UNI_QUEUE_CFG_TBL_NUM 256 +#define AC_UNI_QUEUE_CFG_TBL_INC 0x10 +#define AC_UNI_QUEUE_CFG_TBL_TYPE REG_TYPE_RW +#define AC_UNI_QUEUE_CFG_TBL_DEFAULT 0x0 + /*[field] AC_CFG_AC_EN*/ + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_AC_EN + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_AC_EN_OFFSET 0 + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_AC_EN_LEN 1 + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_AC_EN_DEFAULT 0x0 + /*[field] AC_CFG_WRED_EN*/ + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_WRED_EN + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_WRED_EN_OFFSET 1 + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_WRED_EN_LEN 1 + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_WRED_EN_DEFAULT 0x0 + /*[field] AC_CFG_FORCE_AC_EN*/ + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_FORCE_AC_EN + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_FORCE_AC_EN_OFFSET 2 + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_FORCE_AC_EN_LEN 1 + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_FORCE_AC_EN_DEFAULT 0x0 + /*[field] AC_CFG_COLOR_AWARE*/ + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_COLOR_AWARE + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_COLOR_AWARE_OFFSET 3 + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_COLOR_AWARE_LEN 1 + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_COLOR_AWARE_DEFAULT 0x0 + /*[field] AC_CFG_GRP_ID*/ + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_GRP_ID + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_GRP_ID_OFFSET 4 + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_GRP_ID_LEN 2 + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_GRP_ID_DEFAULT 0x0 + /*[field] AC_CFG_PRE_ALLOC_LIMIT*/ + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_PRE_ALLOC_LIMIT + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_PRE_ALLOC_LIMIT_OFFSET 6 + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_PRE_ALLOC_LIMIT_LEN 11 + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_PRE_ALLOC_LIMIT_DEFAULT 0x0 + /*[field] AC_CFG_SHARED_DYNAMIC*/ + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_SHARED_DYNAMIC + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_SHARED_DYNAMIC_OFFSET 17 + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_SHARED_DYNAMIC_LEN 1 + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_SHARED_DYNAMIC_DEFAULT 0x0 + /*[field] AC_CFG_SHARED_WEIGHT*/ + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_SHARED_WEIGHT + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_SHARED_WEIGHT_OFFSET 18 + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_SHARED_WEIGHT_LEN 3 + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_SHARED_WEIGHT_DEFAULT 0x0 + /*[field] AC_CFG_SHARED_CEILING*/ + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_SHARED_CEILING + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_SHARED_CEILING_OFFSET 21 + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_SHARED_CEILING_LEN 11 + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_SHARED_CEILING_DEFAULT 0x0 + /*[field] AC_CFG_GAP_GRN_GRN_MIN*/ + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_GAP_GRN_GRN_MIN + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_GAP_GRN_GRN_MIN_OFFSET 32 + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_GAP_GRN_GRN_MIN_LEN 11 + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_GAP_GRN_GRN_MIN_DEFAULT 0x0 + /*[field] AC_CFG_GAP_GRN_YEL_MAX*/ + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_GAP_GRN_YEL_MAX + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_GAP_GRN_YEL_MAX_OFFSET 43 + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_GAP_GRN_YEL_MAX_LEN 11 + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_GAP_GRN_YEL_MAX_DEFAULT 0x0 + /*[field] AC_CFG_GAP_GRN_YEL_MIN*/ + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_GAP_GRN_YEL_MIN + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_GAP_GRN_YEL_MIN_OFFSET 54 + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_GAP_GRN_YEL_MIN_LEN 11 + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_GAP_GRN_YEL_MIN_DEFAULT 0x0 + /*[field] AC_CFG_GAP_GRN_RED_MAX*/ + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_GAP_GRN_RED_MAX + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_GAP_GRN_RED_MAX_OFFSET 65 + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_GAP_GRN_RED_MAX_LEN 11 + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_GAP_GRN_RED_MAX_DEFAULT 0x0 + /*[field] AC_CFG_GAP_GRN_RED_MIN*/ + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_GAP_GRN_RED_MIN + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_GAP_GRN_RED_MIN_OFFSET 76 + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_GAP_GRN_RED_MIN_LEN 11 + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_GAP_GRN_RED_MIN_DEFAULT 0x0 + /*[field] AC_CFG_RED_RESUME_OFFSET*/ + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_RED_RESUME_OFFSET + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_RED_RESUME_OFFSET_OFFSET 87 + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_RED_RESUME_OFFSET_LEN 11 + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_RED_RESUME_OFFSET_DEFAULT 0x0 + /*[field] AC_CFG_YEL_RESUME_OFFSET*/ + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_YEL_RESUME_OFFSET + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_YEL_RESUME_OFFSET_OFFSET 98 + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_YEL_RESUME_OFFSET_LEN 11 + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_YEL_RESUME_OFFSET_DEFAULT 0x0 + /*[field] AC_CFG_GRN_RESUME_OFFSET*/ + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_GRN_RESUME_OFFSET + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_GRN_RESUME_OFFSET_OFFSET 109 + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_GRN_RESUME_OFFSET_LEN 11 + #define AC_UNI_QUEUE_CFG_TBL_AC_CFG_GRN_RESUME_OFFSET_DEFAULT 0x0 + +struct ac_uni_queue_cfg_tbl { + a_uint32_t ac_cfg_ac_en:1; + a_uint32_t ac_cfg_wred_en:1; + a_uint32_t ac_cfg_force_ac_en:1; + a_uint32_t ac_cfg_color_aware:1; + a_uint32_t ac_cfg_grp_id:2; + a_uint32_t ac_cfg_pre_alloc_limit:11; + a_uint32_t ac_cfg_shared_dynamic:1; + a_uint32_t ac_cfg_shared_weight:3; + a_uint32_t ac_cfg_shared_ceiling:11; + a_uint32_t ac_cfg_gap_grn_grn_min:11; + a_uint32_t ac_cfg_gap_grn_yel_max:11; + a_uint32_t ac_cfg_gap_grn_yel_min_0:10; + a_uint32_t ac_cfg_gap_grn_yel_min_1:1; + a_uint32_t ac_cfg_gap_grn_red_max:11; + a_uint32_t ac_cfg_gap_grn_red_min:11; + a_uint32_t ac_cfg_red_resume_offset_0:9; + a_uint32_t ac_cfg_red_resume_offset_1:2; + a_uint32_t ac_cfg_yel_resume_offset:11; + a_uint32_t ac_cfg_grn_resume_offset:11; + a_uint32_t _reserved0:8; +}; + +union ac_uni_queue_cfg_tbl_u { + a_uint32_t val[4]; + struct ac_uni_queue_cfg_tbl bf; +}; + +/*[table] AC_MUL_QUEUE_CFG_TBL*/ +#define AC_MUL_QUEUE_CFG_TBL +#define AC_MUL_QUEUE_CFG_TBL_ADDRESS 0x4a000 +#define AC_MUL_QUEUE_CFG_TBL_NUM 44 +#define AC_MUL_QUEUE_CFG_TBL_INC 0x10 +#define AC_MUL_QUEUE_CFG_TBL_TYPE REG_TYPE_RW +#define AC_MUL_QUEUE_CFG_TBL_DEFAULT 0x0 + /*[field] AC_CFG_AC_EN*/ + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_AC_EN + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_AC_EN_OFFSET 0 + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_AC_EN_LEN 1 + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_AC_EN_DEFAULT 0x0 + /*[field] AC_CFG_FORCE_AC_EN*/ + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_FORCE_AC_EN + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_FORCE_AC_EN_OFFSET 1 + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_FORCE_AC_EN_LEN 1 + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_FORCE_AC_EN_DEFAULT 0x0 + /*[field] AC_CFG_COLOR_AWARE*/ + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_COLOR_AWARE + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_COLOR_AWARE_OFFSET 2 + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_COLOR_AWARE_LEN 1 + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_COLOR_AWARE_DEFAULT 0x0 + /*[field] AC_CFG_GRP_ID*/ + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_GRP_ID + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_GRP_ID_OFFSET 3 + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_GRP_ID_LEN 2 + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_GRP_ID_DEFAULT 0x0 + /*[field] AC_CFG_PRE_ALLOC_LIMIT*/ + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_PRE_ALLOC_LIMIT + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_PRE_ALLOC_LIMIT_OFFSET 5 + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_PRE_ALLOC_LIMIT_LEN 11 + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_PRE_ALLOC_LIMIT_DEFAULT 0x0 + /*[field] AC_CFG_SHARED_CEILING*/ + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_SHARED_CEILING + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_SHARED_CEILING_OFFSET 16 + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_SHARED_CEILING_LEN 11 + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_SHARED_CEILING_DEFAULT 0x0 + /*[field] AC_CFG_GAP_GRN_YEL*/ + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_GAP_GRN_YEL + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_GAP_GRN_YEL_OFFSET 27 + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_GAP_GRN_YEL_LEN 11 + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_GAP_GRN_YEL_DEFAULT 0x0 + /*[field] AC_CFG_GAP_GRN_RED*/ + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_GAP_GRN_RED + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_GAP_GRN_RED_OFFSET 38 + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_GAP_GRN_RED_LEN 11 + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_GAP_GRN_RED_DEFAULT 0x0 + /*[field] AC_CFG_RED_RESUME_OFFSET*/ + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_RED_RESUME_OFFSET + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_RED_RESUME_OFFSET_OFFSET 49 + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_RED_RESUME_OFFSET_LEN 11 + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_RED_RESUME_OFFSET_DEFAULT 0x0 + /*[field] AC_CFG_YEL_RESUME_OFFSET*/ + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_YEL_RESUME_OFFSET + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_YEL_RESUME_OFFSET_OFFSET 60 + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_YEL_RESUME_OFFSET_LEN 11 + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_YEL_RESUME_OFFSET_DEFAULT 0x0 + /*[field] AC_CFG_GRN_RESUME_OFFSET*/ + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_GRN_RESUME_OFFSET + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_GRN_RESUME_OFFSET_OFFSET 71 + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_GRN_RESUME_OFFSET_LEN 11 + #define AC_MUL_QUEUE_CFG_TBL_AC_CFG_GRN_RESUME_OFFSET_DEFAULT 0x0 + +struct ac_mul_queue_cfg_tbl { + a_uint32_t ac_cfg_ac_en:1; + a_uint32_t ac_cfg_force_ac_en:1; + a_uint32_t ac_cfg_color_aware:1; + a_uint32_t ac_cfg_grp_id:2; + a_uint32_t ac_cfg_pre_alloc_limit:11; + a_uint32_t ac_cfg_shared_ceiling:11; + a_uint32_t ac_cfg_gap_grn_yel_0:5; + a_uint32_t ac_cfg_gap_grn_yel_1:6; + a_uint32_t ac_cfg_gap_grn_red:11; + a_uint32_t ac_cfg_red_resume_offset:11; + a_uint32_t ac_cfg_yel_resume_offset_0:4; + a_uint32_t ac_cfg_yel_resume_offset_1:7; + a_uint32_t ac_cfg_grn_resume_offset:11; + a_uint32_t _reserved0:14; +}; + +union ac_mul_queue_cfg_tbl_u { + a_uint32_t val[3]; + struct ac_mul_queue_cfg_tbl bf; +}; + +/*[table] AC_GRP_CFG_TBL*/ +#define AC_GRP_CFG_TBL +#define AC_GRP_CFG_TBL_ADDRESS 0x4c000 +#define AC_GRP_CFG_TBL_NUM 4 +#define AC_GRP_CFG_TBL_INC 0x10 +#define AC_GRP_CFG_TBL_TYPE REG_TYPE_RW +#define AC_GRP_CFG_TBL_DEFAULT 0x0 + /*[field] AC_CFG_AC_EN*/ + #define AC_GRP_CFG_TBL_AC_CFG_AC_EN + #define AC_GRP_CFG_TBL_AC_CFG_AC_EN_OFFSET 0 + #define AC_GRP_CFG_TBL_AC_CFG_AC_EN_LEN 1 + #define AC_GRP_CFG_TBL_AC_CFG_AC_EN_DEFAULT 0x0 + /*[field] AC_CFG_FORCE_AC_EN*/ + #define AC_GRP_CFG_TBL_AC_CFG_FORCE_AC_EN + #define AC_GRP_CFG_TBL_AC_CFG_FORCE_AC_EN_OFFSET 1 + #define AC_GRP_CFG_TBL_AC_CFG_FORCE_AC_EN_LEN 1 + #define AC_GRP_CFG_TBL_AC_CFG_FORCE_AC_EN_DEFAULT 0x0 + /*[field] AC_CFG_COLOR_AWARE*/ + #define AC_GRP_CFG_TBL_AC_CFG_COLOR_AWARE + #define AC_GRP_CFG_TBL_AC_CFG_COLOR_AWARE_OFFSET 2 + #define AC_GRP_CFG_TBL_AC_CFG_COLOR_AWARE_LEN 1 + #define AC_GRP_CFG_TBL_AC_CFG_COLOR_AWARE_DEFAULT 0x0 + /*[field] AC_GRP_GAP_GRN_RED*/ + #define AC_GRP_CFG_TBL_AC_GRP_GAP_GRN_RED + #define AC_GRP_CFG_TBL_AC_GRP_GAP_GRN_RED_OFFSET 3 + #define AC_GRP_CFG_TBL_AC_GRP_GAP_GRN_RED_LEN 11 + #define AC_GRP_CFG_TBL_AC_GRP_GAP_GRN_RED_DEFAULT 0x0 + /*[field] AC_GRP_GAP_GRN_YEL*/ + #define AC_GRP_CFG_TBL_AC_GRP_GAP_GRN_YEL + #define AC_GRP_CFG_TBL_AC_GRP_GAP_GRN_YEL_OFFSET 14 + #define AC_GRP_CFG_TBL_AC_GRP_GAP_GRN_YEL_LEN 11 + #define AC_GRP_CFG_TBL_AC_GRP_GAP_GRN_YEL_DEFAULT 0x0 + /*[field] AC_GRP_DP_THRD*/ + #define AC_GRP_CFG_TBL_AC_GRP_DP_THRD + #define AC_GRP_CFG_TBL_AC_GRP_DP_THRD_OFFSET 25 + #define AC_GRP_CFG_TBL_AC_GRP_DP_THRD_LEN 11 + #define AC_GRP_CFG_TBL_AC_GRP_DP_THRD_DEFAULT 0x0 + /*[field] AC_GRP_LIMIT*/ + #define AC_GRP_CFG_TBL_AC_GRP_LIMIT + #define AC_GRP_CFG_TBL_AC_GRP_LIMIT_OFFSET 36 + #define AC_GRP_CFG_TBL_AC_GRP_LIMIT_LEN 11 + #define AC_GRP_CFG_TBL_AC_GRP_LIMIT_DEFAULT 0x0 + /*[field] AC_GRP_RED_RESUME_OFFSET*/ + #define AC_GRP_CFG_TBL_AC_GRP_RED_RESUME_OFFSET + #define AC_GRP_CFG_TBL_AC_GRP_RED_RESUME_OFFSET_OFFSET 47 + #define AC_GRP_CFG_TBL_AC_GRP_RED_RESUME_OFFSET_LEN 11 + #define AC_GRP_CFG_TBL_AC_GRP_RED_RESUME_OFFSET_DEFAULT 0x0 + /*[field] AC_GRP_YEL_RESUME_OFFSET*/ + #define AC_GRP_CFG_TBL_AC_GRP_YEL_RESUME_OFFSET + #define AC_GRP_CFG_TBL_AC_GRP_YEL_RESUME_OFFSET_OFFSET 58 + #define AC_GRP_CFG_TBL_AC_GRP_YEL_RESUME_OFFSET_LEN 11 + #define AC_GRP_CFG_TBL_AC_GRP_YEL_RESUME_OFFSET_DEFAULT 0x0 + /*[field] AC_GRP_GRN_RESUME_OFFSET*/ + #define AC_GRP_CFG_TBL_AC_GRP_GRN_RESUME_OFFSET + #define AC_GRP_CFG_TBL_AC_GRP_GRN_RESUME_OFFSET_OFFSET 69 + #define AC_GRP_CFG_TBL_AC_GRP_GRN_RESUME_OFFSET_LEN 11 + #define AC_GRP_CFG_TBL_AC_GRP_GRN_RESUME_OFFSET_DEFAULT 0x0 + /*[field] AC_GRP_PALLOC_LIMIT*/ + #define AC_GRP_CFG_TBL_AC_GRP_PALLOC_LIMIT + #define AC_GRP_CFG_TBL_AC_GRP_PALLOC_LIMIT_OFFSET 80 + #define AC_GRP_CFG_TBL_AC_GRP_PALLOC_LIMIT_LEN 11 + #define AC_GRP_CFG_TBL_AC_GRP_PALLOC_LIMIT_DEFAULT 0x0 + +struct ac_grp_cfg_tbl { + a_uint32_t ac_cfg_ac_en:1; + a_uint32_t ac_cfg_force_ac_en:1; + a_uint32_t ac_cfg_color_aware:1; + a_uint32_t ac_grp_gap_grn_red:11; + a_uint32_t ac_grp_gap_grn_yel:11; + a_uint32_t ac_grp_dp_thrd_0:7; + a_uint32_t ac_grp_dp_thrd_1:4; + a_uint32_t ac_grp_limit:11; + a_uint32_t ac_grp_red_resume_offset:11; + a_uint32_t ac_grp_yel_resume_offset_0:6; + a_uint32_t ac_grp_yel_resume_offset_1:5; + a_uint32_t ac_grp_grn_resume_offset:11; + a_uint32_t ac_grp_palloc_limit:11; + a_uint32_t _reserved0:5; +}; + +union ac_grp_cfg_tbl_u { + a_uint32_t val[3]; + struct ac_grp_cfg_tbl bf; +}; + +/*[table] AC_UNI_QUEUE_CNT_TBL*/ +#define AC_UNI_QUEUE_CNT_TBL +#define AC_UNI_QUEUE_CNT_TBL_ADDRESS 0x4e000 +#define AC_UNI_QUEUE_CNT_TBL_NUM 256 +#define AC_UNI_QUEUE_CNT_TBL_INC 0x10 +#define AC_UNI_QUEUE_CNT_TBL_TYPE REG_TYPE_RW +#define AC_UNI_QUEUE_CNT_TBL_DEFAULT 0x0 + /*[field] AC_UNI_QUEUE_CNT*/ + #define AC_UNI_QUEUE_CNT_TBL_AC_UNI_QUEUE_CNT + #define AC_UNI_QUEUE_CNT_TBL_AC_UNI_QUEUE_CNT_OFFSET 0 + #define AC_UNI_QUEUE_CNT_TBL_AC_UNI_QUEUE_CNT_LEN 12 + #define AC_UNI_QUEUE_CNT_TBL_AC_UNI_QUEUE_CNT_DEFAULT 0x0 + +struct ac_uni_queue_cnt_tbl { + a_uint32_t ac_uni_queue_cnt:12; + a_uint32_t _reserved0:20; +}; + +union ac_uni_queue_cnt_tbl_u { + a_uint32_t val; + struct ac_uni_queue_cnt_tbl bf; +}; + +/*[table] AC_MUL_QUEUE_CNT_TBL*/ +#define AC_MUL_QUEUE_CNT_TBL +#define AC_MUL_QUEUE_CNT_TBL_ADDRESS 0x52000 +#define AC_MUL_QUEUE_CNT_TBL_NUM 44 +#define AC_MUL_QUEUE_CNT_TBL_INC 0x10 +#define AC_MUL_QUEUE_CNT_TBL_TYPE REG_TYPE_RW +#define AC_MUL_QUEUE_CNT_TBL_DEFAULT 0x0 + /*[field] AC_MUL_QUEUE_CNT*/ + #define AC_MUL_QUEUE_CNT_TBL_AC_MUL_QUEUE_CNT + #define AC_MUL_QUEUE_CNT_TBL_AC_MUL_QUEUE_CNT_OFFSET 0 + #define AC_MUL_QUEUE_CNT_TBL_AC_MUL_QUEUE_CNT_LEN 13 + #define AC_MUL_QUEUE_CNT_TBL_AC_MUL_QUEUE_CNT_DEFAULT 0x0 + +struct ac_mul_queue_cnt_tbl { + a_uint32_t ac_mul_queue_cnt:13; + a_uint32_t _reserved0:19; +}; + +union ac_mul_queue_cnt_tbl_u { + a_uint32_t val; + struct ac_mul_queue_cnt_tbl bf; +}; + +/*[table] AC_GRP_CNT_TBL*/ +#define AC_GRP_CNT_TBL +#define AC_GRP_CNT_TBL_ADDRESS 0x54000 +#define AC_GRP_CNT_TBL_NUM 4 +#define AC_GRP_CNT_TBL_INC 0x10 +#define AC_GRP_CNT_TBL_TYPE REG_TYPE_RW +#define AC_GRP_CNT_TBL_DEFAULT 0x0 + /*[field] AC_GRP_CNT*/ + #define AC_GRP_CNT_TBL_AC_GRP_CNT + #define AC_GRP_CNT_TBL_AC_GRP_CNT_OFFSET 0 + #define AC_GRP_CNT_TBL_AC_GRP_CNT_LEN 16 + #define AC_GRP_CNT_TBL_AC_GRP_CNT_DEFAULT 0x0 + /*[field] AC_GRP_ALLOC_USED*/ + #define AC_GRP_CNT_TBL_AC_GRP_ALLOC_USED + #define AC_GRP_CNT_TBL_AC_GRP_ALLOC_USED_OFFSET 16 + #define AC_GRP_CNT_TBL_AC_GRP_ALLOC_USED_LEN 16 + #define AC_GRP_CNT_TBL_AC_GRP_ALLOC_USED_DEFAULT 0x0 + +struct ac_grp_cnt_tbl { + a_uint32_t ac_grp_cnt:16; + a_uint32_t ac_grp_alloc_used:16; +}; + +union ac_grp_cnt_tbl_u { + a_uint32_t val; + struct ac_grp_cnt_tbl bf; +}; + +/*[table] AC_UNI_QUEUE_DROP_STATE_TBL*/ +#define AC_UNI_QUEUE_DROP_STATE_TBL +#define AC_UNI_QUEUE_DROP_STATE_TBL_ADDRESS 0x56000 +#define AC_UNI_QUEUE_DROP_STATE_TBL_NUM 256 +#define AC_UNI_QUEUE_DROP_STATE_TBL_INC 0x10 +#define AC_UNI_QUEUE_DROP_STATE_TBL_TYPE REG_TYPE_RW +#define AC_UNI_QUEUE_DROP_STATE_TBL_DEFAULT 0x0 + /*[field] RED_RESUME_THRD*/ + #define AC_UNI_QUEUE_DROP_STATE_TBL_RED_RESUME_THRD + #define AC_UNI_QUEUE_DROP_STATE_TBL_RED_RESUME_THRD_OFFSET 0 + #define AC_UNI_QUEUE_DROP_STATE_TBL_RED_RESUME_THRD_LEN 11 + #define AC_UNI_QUEUE_DROP_STATE_TBL_RED_RESUME_THRD_DEFAULT 0x0 + /*[field] YEL_RESUME_THRD*/ + #define AC_UNI_QUEUE_DROP_STATE_TBL_YEL_RESUME_THRD + #define AC_UNI_QUEUE_DROP_STATE_TBL_YEL_RESUME_THRD_OFFSET 11 + #define AC_UNI_QUEUE_DROP_STATE_TBL_YEL_RESUME_THRD_LEN 11 + #define AC_UNI_QUEUE_DROP_STATE_TBL_YEL_RESUME_THRD_DEFAULT 0x0 + /*[field] GRN_RESUME_THRD*/ + #define AC_UNI_QUEUE_DROP_STATE_TBL_GRN_RESUME_THRD + #define AC_UNI_QUEUE_DROP_STATE_TBL_GRN_RESUME_THRD_OFFSET 22 + #define AC_UNI_QUEUE_DROP_STATE_TBL_GRN_RESUME_THRD_LEN 11 + #define AC_UNI_QUEUE_DROP_STATE_TBL_GRN_RESUME_THRD_DEFAULT 0x0 + /*[field] RED_DROP_STATE*/ + #define AC_UNI_QUEUE_DROP_STATE_TBL_RED_DROP_STATE + #define AC_UNI_QUEUE_DROP_STATE_TBL_RED_DROP_STATE_OFFSET 33 + #define AC_UNI_QUEUE_DROP_STATE_TBL_RED_DROP_STATE_LEN 4 + #define AC_UNI_QUEUE_DROP_STATE_TBL_RED_DROP_STATE_DEFAULT 0x0 + /*[field] YEL_DROP_STATE*/ + #define AC_UNI_QUEUE_DROP_STATE_TBL_YEL_DROP_STATE + #define AC_UNI_QUEUE_DROP_STATE_TBL_YEL_DROP_STATE_OFFSET 37 + #define AC_UNI_QUEUE_DROP_STATE_TBL_YEL_DROP_STATE_LEN 4 + #define AC_UNI_QUEUE_DROP_STATE_TBL_YEL_DROP_STATE_DEFAULT 0x0 + /*[field] GRN_DROP_STATE*/ + #define AC_UNI_QUEUE_DROP_STATE_TBL_GRN_DROP_STATE + #define AC_UNI_QUEUE_DROP_STATE_TBL_GRN_DROP_STATE_OFFSET 41 + #define AC_UNI_QUEUE_DROP_STATE_TBL_GRN_DROP_STATE_LEN 4 + #define AC_UNI_QUEUE_DROP_STATE_TBL_GRN_DROP_STATE_DEFAULT 0x0 + +struct ac_uni_queue_drop_state_tbl { + a_uint32_t red_resume_thrd:11; + a_uint32_t yel_resume_thrd:11; + a_uint32_t grn_resume_thrd_0:10; + a_uint32_t grn_resume_thrd_1:1; + a_uint32_t red_drop_state:4; + a_uint32_t yel_drop_state:4; + a_uint32_t grn_drop_state:4; + a_uint32_t _reserved0:19; +}; + +union ac_uni_queue_drop_state_tbl_u { + a_uint32_t val[2]; + struct ac_uni_queue_drop_state_tbl bf; +}; + +/*[table] AC_MUL_QUEUE_DROP_STATE_TBL*/ +#define AC_MUL_QUEUE_DROP_STATE_TBL +#define AC_MUL_QUEUE_DROP_STATE_TBL_ADDRESS 0x58000 +#define AC_MUL_QUEUE_DROP_STATE_TBL_NUM 44 +#define AC_MUL_QUEUE_DROP_STATE_TBL_INC 0x10 +#define AC_MUL_QUEUE_DROP_STATE_TBL_TYPE REG_TYPE_RW +#define AC_MUL_QUEUE_DROP_STATE_TBL_DEFAULT 0x0 + /*[field] RED_RESUME_THRD*/ + #define AC_MUL_QUEUE_DROP_STATE_TBL_RED_RESUME_THRD + #define AC_MUL_QUEUE_DROP_STATE_TBL_RED_RESUME_THRD_OFFSET 0 + #define AC_MUL_QUEUE_DROP_STATE_TBL_RED_RESUME_THRD_LEN 11 + #define AC_MUL_QUEUE_DROP_STATE_TBL_RED_RESUME_THRD_DEFAULT 0x0 + /*[field] YEL_RESUME_THRD*/ + #define AC_MUL_QUEUE_DROP_STATE_TBL_YEL_RESUME_THRD + #define AC_MUL_QUEUE_DROP_STATE_TBL_YEL_RESUME_THRD_OFFSET 11 + #define AC_MUL_QUEUE_DROP_STATE_TBL_YEL_RESUME_THRD_LEN 11 + #define AC_MUL_QUEUE_DROP_STATE_TBL_YEL_RESUME_THRD_DEFAULT 0x0 + /*[field] GRN_RESUME_THRD*/ + #define AC_MUL_QUEUE_DROP_STATE_TBL_GRN_RESUME_THRD + #define AC_MUL_QUEUE_DROP_STATE_TBL_GRN_RESUME_THRD_OFFSET 22 + #define AC_MUL_QUEUE_DROP_STATE_TBL_GRN_RESUME_THRD_LEN 11 + #define AC_MUL_QUEUE_DROP_STATE_TBL_GRN_RESUME_THRD_DEFAULT 0x0 + /*[field] RED_DROP_STATE*/ + #define AC_MUL_QUEUE_DROP_STATE_TBL_RED_DROP_STATE + #define AC_MUL_QUEUE_DROP_STATE_TBL_RED_DROP_STATE_OFFSET 33 + #define AC_MUL_QUEUE_DROP_STATE_TBL_RED_DROP_STATE_LEN 1 + #define AC_MUL_QUEUE_DROP_STATE_TBL_RED_DROP_STATE_DEFAULT 0x0 + /*[field] YEL_DROP_STATE*/ + #define AC_MUL_QUEUE_DROP_STATE_TBL_YEL_DROP_STATE + #define AC_MUL_QUEUE_DROP_STATE_TBL_YEL_DROP_STATE_OFFSET 34 + #define AC_MUL_QUEUE_DROP_STATE_TBL_YEL_DROP_STATE_LEN 1 + #define AC_MUL_QUEUE_DROP_STATE_TBL_YEL_DROP_STATE_DEFAULT 0x0 + /*[field] GRN_DROP_STATE*/ + #define AC_MUL_QUEUE_DROP_STATE_TBL_GRN_DROP_STATE + #define AC_MUL_QUEUE_DROP_STATE_TBL_GRN_DROP_STATE_OFFSET 35 + #define AC_MUL_QUEUE_DROP_STATE_TBL_GRN_DROP_STATE_LEN 1 + #define AC_MUL_QUEUE_DROP_STATE_TBL_GRN_DROP_STATE_DEFAULT 0x0 + +struct ac_mul_queue_drop_state_tbl { + a_uint32_t red_resume_thrd:11; + a_uint32_t yel_resume_thrd:11; + a_uint32_t grn_resume_thrd_0:10; + a_uint32_t grn_resume_thrd_1:1; + a_uint32_t red_drop_state:1; + a_uint32_t yel_drop_state:1; + a_uint32_t grn_drop_state:1; + a_uint32_t _reserved0:28; +}; + +union ac_mul_queue_drop_state_tbl_u { + a_uint32_t val[2]; + struct ac_mul_queue_drop_state_tbl bf; +}; + +/*[table] AC_GRP_DROP_STATE_TBL*/ +#define AC_GRP_DROP_STATE_TBL +#define AC_GRP_DROP_STATE_TBL_ADDRESS 0x5a000 +#define AC_GRP_DROP_STATE_TBL_NUM 4 +#define AC_GRP_DROP_STATE_TBL_INC 0x10 +#define AC_GRP_DROP_STATE_TBL_TYPE REG_TYPE_RW +#define AC_GRP_DROP_STATE_TBL_DEFAULT 0x0 + /*[field] RED_RESUME_THRD*/ + #define AC_GRP_DROP_STATE_TBL_RED_RESUME_THRD + #define AC_GRP_DROP_STATE_TBL_RED_RESUME_THRD_OFFSET 0 + #define AC_GRP_DROP_STATE_TBL_RED_RESUME_THRD_LEN 11 + #define AC_GRP_DROP_STATE_TBL_RED_RESUME_THRD_DEFAULT 0x0 + /*[field] YEL_RESUME_THRD*/ + #define AC_GRP_DROP_STATE_TBL_YEL_RESUME_THRD + #define AC_GRP_DROP_STATE_TBL_YEL_RESUME_THRD_OFFSET 11 + #define AC_GRP_DROP_STATE_TBL_YEL_RESUME_THRD_LEN 11 + #define AC_GRP_DROP_STATE_TBL_YEL_RESUME_THRD_DEFAULT 0x0 + /*[field] GRN_RESUME_THRD*/ + #define AC_GRP_DROP_STATE_TBL_GRN_RESUME_THRD + #define AC_GRP_DROP_STATE_TBL_GRN_RESUME_THRD_OFFSET 22 + #define AC_GRP_DROP_STATE_TBL_GRN_RESUME_THRD_LEN 11 + #define AC_GRP_DROP_STATE_TBL_GRN_RESUME_THRD_DEFAULT 0x0 + /*[field] RED_DROP_STATE*/ + #define AC_GRP_DROP_STATE_TBL_RED_DROP_STATE + #define AC_GRP_DROP_STATE_TBL_RED_DROP_STATE_OFFSET 33 + #define AC_GRP_DROP_STATE_TBL_RED_DROP_STATE_LEN 1 + #define AC_GRP_DROP_STATE_TBL_RED_DROP_STATE_DEFAULT 0x0 + /*[field] YEL_DROP_STATE*/ + #define AC_GRP_DROP_STATE_TBL_YEL_DROP_STATE + #define AC_GRP_DROP_STATE_TBL_YEL_DROP_STATE_OFFSET 34 + #define AC_GRP_DROP_STATE_TBL_YEL_DROP_STATE_LEN 1 + #define AC_GRP_DROP_STATE_TBL_YEL_DROP_STATE_DEFAULT 0x0 + /*[field] GRN_DROP_STATE*/ + #define AC_GRP_DROP_STATE_TBL_GRN_DROP_STATE + #define AC_GRP_DROP_STATE_TBL_GRN_DROP_STATE_OFFSET 35 + #define AC_GRP_DROP_STATE_TBL_GRN_DROP_STATE_LEN 1 + #define AC_GRP_DROP_STATE_TBL_GRN_DROP_STATE_DEFAULT 0x0 + +struct ac_grp_drop_state_tbl { + a_uint32_t red_resume_thrd:11; + a_uint32_t yel_resume_thrd:11; + a_uint32_t grn_resume_thrd_0:10; + a_uint32_t grn_resume_thrd_1:1; + a_uint32_t red_drop_state:1; + a_uint32_t yel_drop_state:1; + a_uint32_t grn_drop_state:1; + a_uint32_t _reserved0:28; +}; + +union ac_grp_drop_state_tbl_u { + a_uint32_t val[2]; + struct ac_grp_drop_state_tbl bf; +}; + +/*[table] OQ_ENQ_OPR_TBL*/ +#define OQ_ENQ_OPR_TBL +#define OQ_ENQ_OPR_TBL_ADDRESS 0x5c000 +#define OQ_ENQ_OPR_TBL_NUM 300 +#define OQ_ENQ_OPR_TBL_INC 0x10 +#define OQ_ENQ_OPR_TBL_TYPE REG_TYPE_RW +#define OQ_ENQ_OPR_TBL_DEFAULT 0x0 + /*[field] ENQ_DISABLE*/ + #define OQ_ENQ_OPR_TBL_ENQ_DISABLE + #define OQ_ENQ_OPR_TBL_ENQ_DISABLE_OFFSET 0 + #define OQ_ENQ_OPR_TBL_ENQ_DISABLE_LEN 1 + #define OQ_ENQ_OPR_TBL_ENQ_DISABLE_DEFAULT 0x0 + +struct oq_enq_opr_tbl { + a_uint32_t enq_disable:1; + a_uint32_t _reserved0:31; +}; + +union oq_enq_opr_tbl_u { + a_uint32_t val; + struct oq_enq_opr_tbl bf; +}; + +/*[table] OQ_DEQ_OPR_TBL*/ +#define OQ_DEQ_OPR_TBL +#define OQ_DEQ_OPR_TBL_ADDRESS 0x64000 +#define OQ_DEQ_OPR_TBL_NUM 300 +#define OQ_DEQ_OPR_TBL_INC 0x10 +#define OQ_DEQ_OPR_TBL_TYPE REG_TYPE_RW +#define OQ_DEQ_OPR_TBL_DEFAULT 0x0 + /*[field] DEQ_DROP*/ + #define OQ_DEQ_OPR_TBL_DEQ_DROP + #define OQ_DEQ_OPR_TBL_DEQ_DROP_OFFSET 0 + #define OQ_DEQ_OPR_TBL_DEQ_DROP_LEN 1 + #define OQ_DEQ_OPR_TBL_DEQ_DROP_DEFAULT 0x0 + +struct oq_deq_opr_tbl { + a_uint32_t deq_drop:1; + a_uint32_t _reserved0:31; +}; + +union oq_deq_opr_tbl_u { + a_uint32_t val; + struct oq_deq_opr_tbl bf; +}; + +/*[table] OQ_HEAD_UNI_TBL*/ +#define OQ_HEAD_UNI_TBL +#define OQ_HEAD_UNI_TBL_ADDRESS 0x6c000 +#define OQ_HEAD_UNI_TBL_NUM 256 +#define OQ_HEAD_UNI_TBL_INC 0x10 +#define OQ_HEAD_UNI_TBL_TYPE REG_TYPE_RW +#define OQ_HEAD_UNI_TBL_DEFAULT 0x0 + /*[field] EMPTY*/ + #define OQ_HEAD_UNI_TBL_EMPTY + #define OQ_HEAD_UNI_TBL_EMPTY_OFFSET 0 + #define OQ_HEAD_UNI_TBL_EMPTY_LEN 1 + #define OQ_HEAD_UNI_TBL_EMPTY_DEFAULT 0x0 + /*[field] TAIL*/ + #define OQ_HEAD_UNI_TBL_TAIL + #define OQ_HEAD_UNI_TBL_TAIL_OFFSET 1 + #define OQ_HEAD_UNI_TBL_TAIL_LEN 11 + #define OQ_HEAD_UNI_TBL_TAIL_DEFAULT 0x0 + /*[field] HEAD*/ + #define OQ_HEAD_UNI_TBL_HEAD + #define OQ_HEAD_UNI_TBL_HEAD_OFFSET 12 + #define OQ_HEAD_UNI_TBL_HEAD_LEN 11 + #define OQ_HEAD_UNI_TBL_HEAD_DEFAULT 0x0 + +struct oq_head_uni_tbl { + a_uint32_t empty:1; + a_uint32_t tail:11; + a_uint32_t head:11; + a_uint32_t _reserved0:9; +}; + +union oq_head_uni_tbl_u { + a_uint32_t val; + struct oq_head_uni_tbl bf; +}; + +/*[table] OQ_HEAD_MUL_TBL*/ +#define OQ_HEAD_MUL_TBL +#define OQ_HEAD_MUL_TBL_ADDRESS 0x74000 +#define OQ_HEAD_MUL_TBL_NUM 44 +#define OQ_HEAD_MUL_TBL_INC 0x10 +#define OQ_HEAD_MUL_TBL_TYPE REG_TYPE_RW +#define OQ_HEAD_MUL_TBL_DEFAULT 0x0 + /*[field] NORMAL_FWD*/ + #define OQ_HEAD_MUL_TBL_NORMAL_FWD + #define OQ_HEAD_MUL_TBL_NORMAL_FWD_OFFSET 0 + #define OQ_HEAD_MUL_TBL_NORMAL_FWD_LEN 1 + #define OQ_HEAD_MUL_TBL_NORMAL_FWD_DEFAULT 0x0 + /*[field] EGRESS_MIRR*/ + #define OQ_HEAD_MUL_TBL_EGRESS_MIRR + #define OQ_HEAD_MUL_TBL_EGRESS_MIRR_OFFSET 1 + #define OQ_HEAD_MUL_TBL_EGRESS_MIRR_LEN 1 + #define OQ_HEAD_MUL_TBL_EGRESS_MIRR_DEFAULT 0x0 + /*[field] INGRESS_MIRR*/ + #define OQ_HEAD_MUL_TBL_INGRESS_MIRR + #define OQ_HEAD_MUL_TBL_INGRESS_MIRR_OFFSET 2 + #define OQ_HEAD_MUL_TBL_INGRESS_MIRR_LEN 1 + #define OQ_HEAD_MUL_TBL_INGRESS_MIRR_DEFAULT 0x0 + /*[field] EMPTY*/ + #define OQ_HEAD_MUL_TBL_EMPTY + #define OQ_HEAD_MUL_TBL_EMPTY_OFFSET 3 + #define OQ_HEAD_MUL_TBL_EMPTY_LEN 1 + #define OQ_HEAD_MUL_TBL_EMPTY_DEFAULT 0x0 + /*[field] TAIL*/ + #define OQ_HEAD_MUL_TBL_TAIL + #define OQ_HEAD_MUL_TBL_TAIL_OFFSET 4 + #define OQ_HEAD_MUL_TBL_TAIL_LEN 11 + #define OQ_HEAD_MUL_TBL_TAIL_DEFAULT 0x0 + /*[field] HEAD*/ + #define OQ_HEAD_MUL_TBL_HEAD + #define OQ_HEAD_MUL_TBL_HEAD_OFFSET 15 + #define OQ_HEAD_MUL_TBL_HEAD_LEN 11 + #define OQ_HEAD_MUL_TBL_HEAD_DEFAULT 0x0 + +struct oq_head_mul_tbl { + a_uint32_t normal_fwd:1; + a_uint32_t egress_mirr:1; + a_uint32_t ingress_mirr:1; + a_uint32_t empty:1; + a_uint32_t tail:11; + a_uint32_t head:11; + a_uint32_t _reserved0:6; +}; + +union oq_head_mul_tbl_u { + a_uint32_t val; + struct oq_head_mul_tbl bf; +}; + +/*[table] OQ_LL_UNI_TBL*/ +#define OQ_LL_UNI_TBL +#define OQ_LL_UNI_TBL_ADDRESS 0x90000 +#define OQ_LL_UNI_TBL_NUM 2048 +#define OQ_LL_UNI_TBL_INC 0x10 +#define OQ_LL_UNI_TBL_TYPE REG_TYPE_RW +#define OQ_LL_UNI_TBL_DEFAULT 0x0 + /*[field] NEXT_POINTER*/ + #define OQ_LL_UNI_TBL_NEXT_POINTER + #define OQ_LL_UNI_TBL_NEXT_POINTER_OFFSET 0 + #define OQ_LL_UNI_TBL_NEXT_POINTER_LEN 11 + #define OQ_LL_UNI_TBL_NEXT_POINTER_DEFAULT 0x0 + +struct oq_ll_uni_tbl { + a_uint32_t next_pointer:11; + a_uint32_t _reserved0:21; +}; + +union oq_ll_uni_tbl_u { + a_uint32_t val; + struct oq_ll_uni_tbl bf; +}; + +/*[table] OQ_LL_MUL_P0_TBL*/ +#define OQ_LL_MUL_P0_TBL +#define OQ_LL_MUL_P0_TBL_ADDRESS 0xb0000 +#define OQ_LL_MUL_P0_TBL_NUM 2048 +#define OQ_LL_MUL_P0_TBL_INC 0x10 +#define OQ_LL_MUL_P0_TBL_TYPE REG_TYPE_RW +#define OQ_LL_MUL_P0_TBL_DEFAULT 0x0 + /*[field] NORMAL_FWD*/ + #define OQ_LL_MUL_P0_TBL_NORMAL_FWD + #define OQ_LL_MUL_P0_TBL_NORMAL_FWD_OFFSET 0 + #define OQ_LL_MUL_P0_TBL_NORMAL_FWD_LEN 1 + #define OQ_LL_MUL_P0_TBL_NORMAL_FWD_DEFAULT 0x0 + /*[field] EGRESS_MIRR*/ + #define OQ_LL_MUL_P0_TBL_EGRESS_MIRR + #define OQ_LL_MUL_P0_TBL_EGRESS_MIRR_OFFSET 1 + #define OQ_LL_MUL_P0_TBL_EGRESS_MIRR_LEN 1 + #define OQ_LL_MUL_P0_TBL_EGRESS_MIRR_DEFAULT 0x0 + /*[field] INGRESS_MIRR*/ + #define OQ_LL_MUL_P0_TBL_INGRESS_MIRR + #define OQ_LL_MUL_P0_TBL_INGRESS_MIRR_OFFSET 2 + #define OQ_LL_MUL_P0_TBL_INGRESS_MIRR_LEN 1 + #define OQ_LL_MUL_P0_TBL_INGRESS_MIRR_DEFAULT 0x0 + /*[field] NEXT_POINTER*/ + #define OQ_LL_MUL_P0_TBL_NEXT_POINTER + #define OQ_LL_MUL_P0_TBL_NEXT_POINTER_OFFSET 3 + #define OQ_LL_MUL_P0_TBL_NEXT_POINTER_LEN 11 + #define OQ_LL_MUL_P0_TBL_NEXT_POINTER_DEFAULT 0x0 + +struct oq_ll_mul_p0_tbl { + a_uint32_t normal_fwd:1; + a_uint32_t egress_mirr:1; + a_uint32_t ingress_mirr:1; + a_uint32_t next_pointer:11; + a_uint32_t _reserved0:18; +}; + +union oq_ll_mul_p0_tbl_u { + a_uint32_t val; + struct oq_ll_mul_p0_tbl bf; +}; + +/*[table] OQ_LL_MUL_P1_TBL*/ +#define OQ_LL_MUL_P1_TBL +#define OQ_LL_MUL_P1_TBL_ADDRESS 0xd0000 +#define OQ_LL_MUL_P1_TBL_NUM 2048 +#define OQ_LL_MUL_P1_TBL_INC 0x10 +#define OQ_LL_MUL_P1_TBL_TYPE REG_TYPE_RW +#define OQ_LL_MUL_P1_TBL_DEFAULT 0x0 + /*[field] NORMAL_FWD*/ + #define OQ_LL_MUL_P1_TBL_NORMAL_FWD + #define OQ_LL_MUL_P1_TBL_NORMAL_FWD_OFFSET 0 + #define OQ_LL_MUL_P1_TBL_NORMAL_FWD_LEN 1 + #define OQ_LL_MUL_P1_TBL_NORMAL_FWD_DEFAULT 0x0 + /*[field] EGRESS_MIRR*/ + #define OQ_LL_MUL_P1_TBL_EGRESS_MIRR + #define OQ_LL_MUL_P1_TBL_EGRESS_MIRR_OFFSET 1 + #define OQ_LL_MUL_P1_TBL_EGRESS_MIRR_LEN 1 + #define OQ_LL_MUL_P1_TBL_EGRESS_MIRR_DEFAULT 0x0 + /*[field] INGRESS_MIRR*/ + #define OQ_LL_MUL_P1_TBL_INGRESS_MIRR + #define OQ_LL_MUL_P1_TBL_INGRESS_MIRR_OFFSET 2 + #define OQ_LL_MUL_P1_TBL_INGRESS_MIRR_LEN 1 + #define OQ_LL_MUL_P1_TBL_INGRESS_MIRR_DEFAULT 0x0 + /*[field] NEXT_POINTER*/ + #define OQ_LL_MUL_P1_TBL_NEXT_POINTER + #define OQ_LL_MUL_P1_TBL_NEXT_POINTER_OFFSET 3 + #define OQ_LL_MUL_P1_TBL_NEXT_POINTER_LEN 11 + #define OQ_LL_MUL_P1_TBL_NEXT_POINTER_DEFAULT 0x0 + +struct oq_ll_mul_p1_tbl { + a_uint32_t normal_fwd:1; + a_uint32_t egress_mirr:1; + a_uint32_t ingress_mirr:1; + a_uint32_t next_pointer:11; + a_uint32_t _reserved0:18; +}; + +union oq_ll_mul_p1_tbl_u { + a_uint32_t val; + struct oq_ll_mul_p1_tbl bf; +}; + +/*[table] OQ_LL_MUL_P2_TBL*/ +#define OQ_LL_MUL_P2_TBL +#define OQ_LL_MUL_P2_TBL_ADDRESS 0x110000 +#define OQ_LL_MUL_P2_TBL_NUM 2048 +#define OQ_LL_MUL_P2_TBL_INC 0x10 +#define OQ_LL_MUL_P2_TBL_TYPE REG_TYPE_RW +#define OQ_LL_MUL_P2_TBL_DEFAULT 0x0 + /*[field] NORMAL_FWD*/ + #define OQ_LL_MUL_P2_TBL_NORMAL_FWD + #define OQ_LL_MUL_P2_TBL_NORMAL_FWD_OFFSET 0 + #define OQ_LL_MUL_P2_TBL_NORMAL_FWD_LEN 1 + #define OQ_LL_MUL_P2_TBL_NORMAL_FWD_DEFAULT 0x0 + /*[field] EGRESS_MIRR*/ + #define OQ_LL_MUL_P2_TBL_EGRESS_MIRR + #define OQ_LL_MUL_P2_TBL_EGRESS_MIRR_OFFSET 1 + #define OQ_LL_MUL_P2_TBL_EGRESS_MIRR_LEN 1 + #define OQ_LL_MUL_P2_TBL_EGRESS_MIRR_DEFAULT 0x0 + /*[field] INGRESS_MIRR*/ + #define OQ_LL_MUL_P2_TBL_INGRESS_MIRR + #define OQ_LL_MUL_P2_TBL_INGRESS_MIRR_OFFSET 2 + #define OQ_LL_MUL_P2_TBL_INGRESS_MIRR_LEN 1 + #define OQ_LL_MUL_P2_TBL_INGRESS_MIRR_DEFAULT 0x0 + /*[field] NEXT_POINTER*/ + #define OQ_LL_MUL_P2_TBL_NEXT_POINTER + #define OQ_LL_MUL_P2_TBL_NEXT_POINTER_OFFSET 3 + #define OQ_LL_MUL_P2_TBL_NEXT_POINTER_LEN 11 + #define OQ_LL_MUL_P2_TBL_NEXT_POINTER_DEFAULT 0x0 + +struct oq_ll_mul_p2_tbl { + a_uint32_t normal_fwd:1; + a_uint32_t egress_mirr:1; + a_uint32_t ingress_mirr:1; + a_uint32_t next_pointer:11; + a_uint32_t _reserved0:18; +}; + +union oq_ll_mul_p2_tbl_u { + a_uint32_t val; + struct oq_ll_mul_p2_tbl bf; +}; + +/*[table] OQ_LL_MUL_P3_TBL*/ +#define OQ_LL_MUL_P3_TBL +#define OQ_LL_MUL_P3_TBL_ADDRESS 0x130000 +#define OQ_LL_MUL_P3_TBL_NUM 2048 +#define OQ_LL_MUL_P3_TBL_INC 0x10 +#define OQ_LL_MUL_P3_TBL_TYPE REG_TYPE_RW +#define OQ_LL_MUL_P3_TBL_DEFAULT 0x0 + /*[field] NORMAL_FWD*/ + #define OQ_LL_MUL_P3_TBL_NORMAL_FWD + #define OQ_LL_MUL_P3_TBL_NORMAL_FWD_OFFSET 0 + #define OQ_LL_MUL_P3_TBL_NORMAL_FWD_LEN 1 + #define OQ_LL_MUL_P3_TBL_NORMAL_FWD_DEFAULT 0x0 + /*[field] EGRESS_MIRR*/ + #define OQ_LL_MUL_P3_TBL_EGRESS_MIRR + #define OQ_LL_MUL_P3_TBL_EGRESS_MIRR_OFFSET 1 + #define OQ_LL_MUL_P3_TBL_EGRESS_MIRR_LEN 1 + #define OQ_LL_MUL_P3_TBL_EGRESS_MIRR_DEFAULT 0x0 + /*[field] INGRESS_MIRR*/ + #define OQ_LL_MUL_P3_TBL_INGRESS_MIRR + #define OQ_LL_MUL_P3_TBL_INGRESS_MIRR_OFFSET 2 + #define OQ_LL_MUL_P3_TBL_INGRESS_MIRR_LEN 1 + #define OQ_LL_MUL_P3_TBL_INGRESS_MIRR_DEFAULT 0x0 + /*[field] NEXT_POINTER*/ + #define OQ_LL_MUL_P3_TBL_NEXT_POINTER + #define OQ_LL_MUL_P3_TBL_NEXT_POINTER_OFFSET 3 + #define OQ_LL_MUL_P3_TBL_NEXT_POINTER_LEN 11 + #define OQ_LL_MUL_P3_TBL_NEXT_POINTER_DEFAULT 0x0 + +struct oq_ll_mul_p3_tbl { + a_uint32_t normal_fwd:1; + a_uint32_t egress_mirr:1; + a_uint32_t ingress_mirr:1; + a_uint32_t next_pointer:11; + a_uint32_t _reserved0:18; +}; + +union oq_ll_mul_p3_tbl_u { + a_uint32_t val; + struct oq_ll_mul_p3_tbl bf; +}; + +/*[table] OQ_LL_MUL_P4_TBL*/ +#define OQ_LL_MUL_P4_TBL +#define OQ_LL_MUL_P4_TBL_ADDRESS 0x150000 +#define OQ_LL_MUL_P4_TBL_NUM 2048 +#define OQ_LL_MUL_P4_TBL_INC 0x10 +#define OQ_LL_MUL_P4_TBL_TYPE REG_TYPE_RW +#define OQ_LL_MUL_P4_TBL_DEFAULT 0x0 + /*[field] NORMAL_FWD*/ + #define OQ_LL_MUL_P4_TBL_NORMAL_FWD + #define OQ_LL_MUL_P4_TBL_NORMAL_FWD_OFFSET 0 + #define OQ_LL_MUL_P4_TBL_NORMAL_FWD_LEN 1 + #define OQ_LL_MUL_P4_TBL_NORMAL_FWD_DEFAULT 0x0 + /*[field] EGRESS_MIRR*/ + #define OQ_LL_MUL_P4_TBL_EGRESS_MIRR + #define OQ_LL_MUL_P4_TBL_EGRESS_MIRR_OFFSET 1 + #define OQ_LL_MUL_P4_TBL_EGRESS_MIRR_LEN 1 + #define OQ_LL_MUL_P4_TBL_EGRESS_MIRR_DEFAULT 0x0 + /*[field] INGRESS_MIRR*/ + #define OQ_LL_MUL_P4_TBL_INGRESS_MIRR + #define OQ_LL_MUL_P4_TBL_INGRESS_MIRR_OFFSET 2 + #define OQ_LL_MUL_P4_TBL_INGRESS_MIRR_LEN 1 + #define OQ_LL_MUL_P4_TBL_INGRESS_MIRR_DEFAULT 0x0 + /*[field] NEXT_POINTER*/ + #define OQ_LL_MUL_P4_TBL_NEXT_POINTER + #define OQ_LL_MUL_P4_TBL_NEXT_POINTER_OFFSET 3 + #define OQ_LL_MUL_P4_TBL_NEXT_POINTER_LEN 11 + #define OQ_LL_MUL_P4_TBL_NEXT_POINTER_DEFAULT 0x0 + +struct oq_ll_mul_p4_tbl { + a_uint32_t normal_fwd:1; + a_uint32_t egress_mirr:1; + a_uint32_t ingress_mirr:1; + a_uint32_t next_pointer:11; + a_uint32_t _reserved0:18; +}; + +union oq_ll_mul_p4_tbl_u { + a_uint32_t val; + struct oq_ll_mul_p4_tbl bf; +}; + +/*[table] OQ_LL_MUL_P5_TBL*/ +#define OQ_LL_MUL_P5_TBL +#define OQ_LL_MUL_P5_TBL_ADDRESS 0x170000 +#define OQ_LL_MUL_P5_TBL_NUM 2048 +#define OQ_LL_MUL_P5_TBL_INC 0x10 +#define OQ_LL_MUL_P5_TBL_TYPE REG_TYPE_RW +#define OQ_LL_MUL_P5_TBL_DEFAULT 0x0 + /*[field] NORMAL_FWD*/ + #define OQ_LL_MUL_P5_TBL_NORMAL_FWD + #define OQ_LL_MUL_P5_TBL_NORMAL_FWD_OFFSET 0 + #define OQ_LL_MUL_P5_TBL_NORMAL_FWD_LEN 1 + #define OQ_LL_MUL_P5_TBL_NORMAL_FWD_DEFAULT 0x0 + /*[field] EGRESS_MIRR*/ + #define OQ_LL_MUL_P5_TBL_EGRESS_MIRR + #define OQ_LL_MUL_P5_TBL_EGRESS_MIRR_OFFSET 1 + #define OQ_LL_MUL_P5_TBL_EGRESS_MIRR_LEN 1 + #define OQ_LL_MUL_P5_TBL_EGRESS_MIRR_DEFAULT 0x0 + /*[field] INGRESS_MIRR*/ + #define OQ_LL_MUL_P5_TBL_INGRESS_MIRR + #define OQ_LL_MUL_P5_TBL_INGRESS_MIRR_OFFSET 2 + #define OQ_LL_MUL_P5_TBL_INGRESS_MIRR_LEN 1 + #define OQ_LL_MUL_P5_TBL_INGRESS_MIRR_DEFAULT 0x0 + /*[field] NEXT_POINTER*/ + #define OQ_LL_MUL_P5_TBL_NEXT_POINTER + #define OQ_LL_MUL_P5_TBL_NEXT_POINTER_OFFSET 3 + #define OQ_LL_MUL_P5_TBL_NEXT_POINTER_LEN 11 + #define OQ_LL_MUL_P5_TBL_NEXT_POINTER_DEFAULT 0x0 + +struct oq_ll_mul_p5_tbl { + a_uint32_t normal_fwd:1; + a_uint32_t egress_mirr:1; + a_uint32_t ingress_mirr:1; + a_uint32_t next_pointer:11; + a_uint32_t _reserved0:18; +}; + +union oq_ll_mul_p5_tbl_u { + a_uint32_t val; + struct oq_ll_mul_p5_tbl bf; +}; + +/*[table] OQ_LL_MUL_P6_TBL*/ +#define OQ_LL_MUL_P6_TBL +#define OQ_LL_MUL_P6_TBL_ADDRESS 0x190000 +#define OQ_LL_MUL_P6_TBL_NUM 2048 +#define OQ_LL_MUL_P6_TBL_INC 0x10 +#define OQ_LL_MUL_P6_TBL_TYPE REG_TYPE_RW +#define OQ_LL_MUL_P6_TBL_DEFAULT 0x0 + /*[field] NORMAL_FWD*/ + #define OQ_LL_MUL_P6_TBL_NORMAL_FWD + #define OQ_LL_MUL_P6_TBL_NORMAL_FWD_OFFSET 0 + #define OQ_LL_MUL_P6_TBL_NORMAL_FWD_LEN 1 + #define OQ_LL_MUL_P6_TBL_NORMAL_FWD_DEFAULT 0x0 + /*[field] EGRESS_MIRR*/ + #define OQ_LL_MUL_P6_TBL_EGRESS_MIRR + #define OQ_LL_MUL_P6_TBL_EGRESS_MIRR_OFFSET 1 + #define OQ_LL_MUL_P6_TBL_EGRESS_MIRR_LEN 1 + #define OQ_LL_MUL_P6_TBL_EGRESS_MIRR_DEFAULT 0x0 + /*[field] INGRESS_MIRR*/ + #define OQ_LL_MUL_P6_TBL_INGRESS_MIRR + #define OQ_LL_MUL_P6_TBL_INGRESS_MIRR_OFFSET 2 + #define OQ_LL_MUL_P6_TBL_INGRESS_MIRR_LEN 1 + #define OQ_LL_MUL_P6_TBL_INGRESS_MIRR_DEFAULT 0x0 + /*[field] NEXT_POINTER*/ + #define OQ_LL_MUL_P6_TBL_NEXT_POINTER + #define OQ_LL_MUL_P6_TBL_NEXT_POINTER_OFFSET 3 + #define OQ_LL_MUL_P6_TBL_NEXT_POINTER_LEN 11 + #define OQ_LL_MUL_P6_TBL_NEXT_POINTER_DEFAULT 0x0 + +struct oq_ll_mul_p6_tbl { + a_uint32_t normal_fwd:1; + a_uint32_t egress_mirr:1; + a_uint32_t ingress_mirr:1; + a_uint32_t next_pointer:11; + a_uint32_t _reserved0:18; +}; + +union oq_ll_mul_p6_tbl_u { + a_uint32_t val; + struct oq_ll_mul_p6_tbl bf; +}; + +/*[table] OQ_LL_MUL_P7_TBL*/ +#define OQ_LL_MUL_P7_TBL +#define OQ_LL_MUL_P7_TBL_ADDRESS 0x1b0000 +#define OQ_LL_MUL_P7_TBL_NUM 2048 +#define OQ_LL_MUL_P7_TBL_INC 0x10 +#define OQ_LL_MUL_P7_TBL_TYPE REG_TYPE_RW +#define OQ_LL_MUL_P7_TBL_DEFAULT 0x0 + /*[field] NORMAL_FWD*/ + #define OQ_LL_MUL_P7_TBL_NORMAL_FWD + #define OQ_LL_MUL_P7_TBL_NORMAL_FWD_OFFSET 0 + #define OQ_LL_MUL_P7_TBL_NORMAL_FWD_LEN 1 + #define OQ_LL_MUL_P7_TBL_NORMAL_FWD_DEFAULT 0x0 + /*[field] EGRESS_MIRR*/ + #define OQ_LL_MUL_P7_TBL_EGRESS_MIRR + #define OQ_LL_MUL_P7_TBL_EGRESS_MIRR_OFFSET 1 + #define OQ_LL_MUL_P7_TBL_EGRESS_MIRR_LEN 1 + #define OQ_LL_MUL_P7_TBL_EGRESS_MIRR_DEFAULT 0x0 + /*[field] INGRESS_MIRR*/ + #define OQ_LL_MUL_P7_TBL_INGRESS_MIRR + #define OQ_LL_MUL_P7_TBL_INGRESS_MIRR_OFFSET 2 + #define OQ_LL_MUL_P7_TBL_INGRESS_MIRR_LEN 1 + #define OQ_LL_MUL_P7_TBL_INGRESS_MIRR_DEFAULT 0x0 + /*[field] NEXT_POINTER*/ + #define OQ_LL_MUL_P7_TBL_NEXT_POINTER + #define OQ_LL_MUL_P7_TBL_NEXT_POINTER_OFFSET 3 + #define OQ_LL_MUL_P7_TBL_NEXT_POINTER_LEN 11 + #define OQ_LL_MUL_P7_TBL_NEXT_POINTER_DEFAULT 0x0 + +struct oq_ll_mul_p7_tbl { + a_uint32_t normal_fwd:1; + a_uint32_t egress_mirr:1; + a_uint32_t ingress_mirr:1; + a_uint32_t next_pointer:11; + a_uint32_t _reserved0:18; +}; + +union oq_ll_mul_p7_tbl_u { + a_uint32_t val; + struct oq_ll_mul_p7_tbl bf; +}; + +/*[table] PKT_DESP_TBL*/ +#define PKT_DESP_TBL +#define PKT_DESP_TBL_ADDRESS 0x1c0000 +#define PKT_DESP_TBL_NUM 2048 +#define PKT_DESP_TBL_INC 0x40 +#define PKT_DESP_TBL_TYPE REG_TYPE_RW +#define PKT_DESP_TBL_DEFAULT 0x0 + /*[field] ORG_SRC_PORT_VP*/ + #define PKT_DESP_TBL_ORG_SRC_PORT_VP + #define PKT_DESP_TBL_ORG_SRC_PORT_VP_OFFSET 0 + #define PKT_DESP_TBL_ORG_SRC_PORT_VP_LEN 12 + #define PKT_DESP_TBL_ORG_SRC_PORT_VP_DEFAULT 0x0 + /*[field] SRC_PORT_VP*/ + #define PKT_DESP_TBL_SRC_PORT_VP + #define PKT_DESP_TBL_SRC_PORT_VP_OFFSET 12 + #define PKT_DESP_TBL_SRC_PORT_VP_LEN 12 + #define PKT_DESP_TBL_SRC_PORT_VP_DEFAULT 0x0 + /*[field] PACKET_LENGTH*/ + #define PKT_DESP_TBL_PACKET_LENGTH + #define PKT_DESP_TBL_PACKET_LENGTH_OFFSET 24 + #define PKT_DESP_TBL_PACKET_LENGTH_LEN 14 + #define PKT_DESP_TBL_PACKET_LENGTH_DEFAULT 0x0 + /*[field] TS_DIR*/ + #define PKT_DESP_TBL_TS_DIR + #define PKT_DESP_TBL_TS_DIR_OFFSET 38 + #define PKT_DESP_TBL_TS_DIR_LEN 1 + #define PKT_DESP_TBL_TS_DIR_DEFAULT 0x0 + /*[field] TX_TS_EN reuse TS_DIR[0]*/ + #define PKT_DESP_TBL_TX_TS_EN + #define PKT_DESP_TBL_TX_TS_EN_OFFSET 39 + #define PKT_DESP_TBL_TX_TS_EN_LEN 1 + #define PKT_DESP_TBL_TX_TS_EN_DEFAULT 0x0 + /*[field] RX_TS_VALID reuse TS_DIR[1]*/ + #define PKT_DESP_TBL_RX_TS_VALID + #define PKT_DESP_TBL_RX_TS_VALID_OFFSET 39 + #define PKT_DESP_TBL_RX_TS_VALID_LEN 1 + #define PKT_DESP_TBL_RX_TS_VALID_DEFAULT 0x0 + /*[field] RX_TS reuse TS_DIR[1]*/ + #define PKT_DESP_TBL_RX_TS + #define PKT_DESP_TBL_RX_TS_OFFSET 40 + #define PKT_DESP_TBL_RX_TS_LEN 40 + #define PKT_DESP_TBL_RX_TS_DEFAULT 0x0 + /*[field] TX_OS_CORRECTION_EN reuse TS_DIR[0]*/ + #define PKT_DESP_TBL_TX_OS_CORRECTION_EN + #define PKT_DESP_TBL_TX_OS_CORRECTION_EN_OFFSET 40 + #define PKT_DESP_TBL_TX_OS_CORRECTION_EN_LEN 1 + #define PKT_DESP_TBL_TX_OS_CORRECTION_EN_DEFAULT 0x0 + /*[field] TX_PTP_TAG reuse TS_DIR[0]*/ + #define PKT_DESP_TBL_TX_PTP_TAG + #define PKT_DESP_TBL_TX_PTP_TAG_OFFSET 41 + #define PKT_DESP_TBL_TX_PTP_TAG_LEN 10 + #define PKT_DESP_TBL_TX_PTP_TAG_DEFAULT 0x0 + /*[field] INT_PRI*/ + #define PKT_DESP_TBL_INT_PRI + #define PKT_DESP_TBL_INT_PRI_OFFSET 80 + #define PKT_DESP_TBL_INT_PRI_LEN 4 + #define PKT_DESP_TBL_INT_PRI_DEFAULT 0x0 + /*[field] INT_DP*/ + #define PKT_DESP_TBL_INT_DP + #define PKT_DESP_TBL_INT_DP_OFFSET 84 + #define PKT_DESP_TBL_INT_DP_LEN 2 + #define PKT_DESP_TBL_INT_DP_DEFAULT 0x0 + /*[field] CPU_CODE*/ + #define PKT_DESP_TBL_CPU_CODE + #define PKT_DESP_TBL_CPU_CODE_OFFSET 86 + #define PKT_DESP_TBL_CPU_CODE_LEN 8 + #define PKT_DESP_TBL_CPU_CODE_DEFAULT 0x0 + /*[field] SERVICE_CODE*/ + #define PKT_DESP_TBL_SERVICE_CODE + #define PKT_DESP_TBL_SERVICE_CODE_OFFSET 94 + #define PKT_DESP_TBL_SERVICE_CODE_LEN 8 + #define PKT_DESP_TBL_SERVICE_CODE_DEFAULT 0x0 + /*[field] DST_L3_IF*/ + #define PKT_DESP_TBL_DST_L3_IF + #define PKT_DESP_TBL_DST_L3_IF_OFFSET 102 + #define PKT_DESP_TBL_DST_L3_IF_LEN 8 + #define PKT_DESP_TBL_DST_L3_IF_DEFAULT 0x0 + /*[field] MAC_DA*/ + #define PKT_DESP_TBL_MAC_DA + #define PKT_DESP_TBL_MAC_DA_OFFSET 110 + #define PKT_DESP_TBL_MAC_DA_LEN 48 + #define PKT_DESP_TBL_MAC_DA_DEFAULT 0x0 + /*[field] ROUTE_FLAG*/ + #define PKT_DESP_TBL_ROUTE_FLAG + #define PKT_DESP_TBL_ROUTE_FLAG_OFFSET 158 + #define PKT_DESP_TBL_ROUTE_FLAG_LEN 1 + #define PKT_DESP_TBL_ROUTE_FLAG_DEFAULT 0x0 + /*[field] PPPOE_STRIP_FLAG*/ + #define PKT_DESP_TBL_PPPOE_STRIP_FLAG + #define PKT_DESP_TBL_PPPOE_STRIP_FLAG_OFFSET 159 + #define PKT_DESP_TBL_PPPOE_STRIP_FLAG_LEN 1 + #define PKT_DESP_TBL_PPPOE_STRIP_FLAG_DEFAULT 0x0 + /*[field] NAT_ACTION*/ + #define PKT_DESP_TBL_NAT_ACTION + #define PKT_DESP_TBL_NAT_ACTION_OFFSET 160 + #define PKT_DESP_TBL_NAT_ACTION_LEN 3 + #define PKT_DESP_TBL_NAT_ACTION_DEFAULT 0x0 + /*[field] NAPT_PORT*/ + #define PKT_DESP_TBL_NAPT_PORT + #define PKT_DESP_TBL_NAPT_PORT_OFFSET 163 + #define PKT_DESP_TBL_NAPT_PORT_LEN 16 + #define PKT_DESP_TBL_NAPT_PORT_DEFAULT 0x0 + /*[field] NAPT_ADDR*/ + #define PKT_DESP_TBL_NAPT_ADDR + #define PKT_DESP_TBL_NAPT_ADDR_OFFSET 179 + #define PKT_DESP_TBL_NAPT_ADDR_LEN 32 + #define PKT_DESP_TBL_NAPT_ADDR_DEFAULT 0x0 + /*[field] DSCP_UPDATE*/ + #define PKT_DESP_TBL_DSCP_UPDATE + #define PKT_DESP_TBL_DSCP_UPDATE_OFFSET 211 + #define PKT_DESP_TBL_DSCP_UPDATE_LEN 1 + #define PKT_DESP_TBL_DSCP_UPDATE_DEFAULT 0x0 + /*[field] DSCP*/ + #define PKT_DESP_TBL_DSCP + #define PKT_DESP_TBL_DSCP_OFFSET 212 + #define PKT_DESP_TBL_DSCP_LEN 8 + #define PKT_DESP_TBL_DSCP_DEFAULT 0x0 + /*[field] TTL_UPDATE*/ + #define PKT_DESP_TBL_TTL_UPDATE + #define PKT_DESP_TBL_TTL_UPDATE_OFFSET 220 + #define PKT_DESP_TBL_TTL_UPDATE_LEN 1 + #define PKT_DESP_TBL_TTL_UPDATE_DEFAULT 0x0 + /*[field] TTL*/ + #define PKT_DESP_TBL_TTL + #define PKT_DESP_TBL_TTL_OFFSET 221 + #define PKT_DESP_TBL_TTL_LEN 8 + #define PKT_DESP_TBL_TTL_DEFAULT 0x0 + /*[field] STAG_FLAG*/ + #define PKT_DESP_TBL_STAG_FLAG + #define PKT_DESP_TBL_STAG_FLAG_OFFSET 229 + #define PKT_DESP_TBL_STAG_FLAG_LEN 1 + #define PKT_DESP_TBL_STAG_FLAG_DEFAULT 0x0 + /*[field] CTAG_FLAG*/ + #define PKT_DESP_TBL_CTAG_FLAG + #define PKT_DESP_TBL_CTAG_FLAG_OFFSET 230 + #define PKT_DESP_TBL_CTAG_FLAG_LEN 1 + #define PKT_DESP_TBL_CTAG_FLAG_DEFAULT 0x0 + /*[field] SNAP_FLAG*/ + #define PKT_DESP_TBL_SNAP_FLAG + #define PKT_DESP_TBL_SNAP_FLAG_OFFSET 231 + #define PKT_DESP_TBL_SNAP_FLAG_LEN 1 + #define PKT_DESP_TBL_SNAP_FLAG_DEFAULT 0x0 + /*[field] PPPOE_FLAG*/ + #define PKT_DESP_TBL_PPPOE_FLAG + #define PKT_DESP_TBL_PPPOE_FLAG_OFFSET 232 + #define PKT_DESP_TBL_PPPOE_FLAG_LEN 1 + #define PKT_DESP_TBL_PPPOE_FLAG_DEFAULT 0x0 + /*[field] INT_STAG_FMT*/ + #define PKT_DESP_TBL_INT_STAG_FMT + #define PKT_DESP_TBL_INT_STAG_FMT_OFFSET 233 + #define PKT_DESP_TBL_INT_STAG_FMT_LEN 1 + #define PKT_DESP_TBL_INT_STAG_FMT_DEFAULT 0x0 + /*[field] INT_CTAG_FMT*/ + #define PKT_DESP_TBL_INT_CTAG_FMT + #define PKT_DESP_TBL_INT_CTAG_FMT_OFFSET 234 + #define PKT_DESP_TBL_INT_CTAG_FMT_LEN 1 + #define PKT_DESP_TBL_INT_CTAG_FMT_DEFAULT 0x0 + /*[field] INT_SVID*/ + #define PKT_DESP_TBL_INT_SVID + #define PKT_DESP_TBL_INT_SVID_OFFSET 235 + #define PKT_DESP_TBL_INT_SVID_LEN 12 + #define PKT_DESP_TBL_INT_SVID_DEFAULT 0x0 + /*[field] INT_CVID*/ + #define PKT_DESP_TBL_INT_CVID + #define PKT_DESP_TBL_INT_CVID_OFFSET 247 + #define PKT_DESP_TBL_INT_CVID_LEN 12 + #define PKT_DESP_TBL_INT_CVID_DEFAULT 0x0 + /*[field] INT_SPCP*/ + #define PKT_DESP_TBL_INT_SPCP + #define PKT_DESP_TBL_INT_SPCP_OFFSET 259 + #define PKT_DESP_TBL_INT_SPCP_LEN 3 + #define PKT_DESP_TBL_INT_SPCP_DEFAULT 0x0 + /*[field] INT_CPCP*/ + #define PKT_DESP_TBL_INT_CPCP + #define PKT_DESP_TBL_INT_CPCP_OFFSET 262 + #define PKT_DESP_TBL_INT_CPCP_LEN 3 + #define PKT_DESP_TBL_INT_CPCP_DEFAULT 0x0 + /*[field] INT_SDEI*/ + #define PKT_DESP_TBL_INT_SDEI + #define PKT_DESP_TBL_INT_SDEI_OFFSET 265 + #define PKT_DESP_TBL_INT_SDEI_LEN 1 + #define PKT_DESP_TBL_INT_SDEI_DEFAULT 0x0 + /*[field] INT_CDEI*/ + #define PKT_DESP_TBL_INT_CDEI + #define PKT_DESP_TBL_INT_CDEI_OFFSET 266 + #define PKT_DESP_TBL_INT_CDEI_LEN 1 + #define PKT_DESP_TBL_INT_CDEI_DEFAULT 0x0 + /*[field] VSI*/ + #define PKT_DESP_TBL_VSI + #define PKT_DESP_TBL_VSI_OFFSET 267 + #define PKT_DESP_TBL_VSI_LEN 5 + #define PKT_DESP_TBL_VSI_DEFAULT 0x0 + /*[field] L3_OFFSET*/ + #define PKT_DESP_TBL_L3_OFFSET + #define PKT_DESP_TBL_L3_OFFSET_OFFSET 272 + #define PKT_DESP_TBL_L3_OFFSET_LEN 8 + #define PKT_DESP_TBL_L3_OFFSET_DEFAULT 0x0 + /*[field] L3_TYPE*/ + #define PKT_DESP_TBL_L3_TYPE + #define PKT_DESP_TBL_L3_TYPE_OFFSET 280 + #define PKT_DESP_TBL_L3_TYPE_LEN 2 + #define PKT_DESP_TBL_L3_TYPE_DEFAULT 0x0 + /*[field] L4_OFFSET*/ + #define PKT_DESP_TBL_L4_OFFSET + #define PKT_DESP_TBL_L4_OFFSET_OFFSET 282 + #define PKT_DESP_TBL_L4_OFFSET_LEN 8 + #define PKT_DESP_TBL_L4_OFFSET_DEFAULT 0x0 + /*[field] L4_TYPE*/ + #define PKT_DESP_TBL_L4_TYPE + #define PKT_DESP_TBL_L4_TYPE_OFFSET 290 + #define PKT_DESP_TBL_L4_TYPE_LEN 3 + #define PKT_DESP_TBL_L4_TYPE_DEFAULT 0x0 + /*[field] NEXT_HEADER*/ + #define PKT_DESP_TBL_NEXT_HEADER + #define PKT_DESP_TBL_NEXT_HEADER_OFFSET 293 + #define PKT_DESP_TBL_NEXT_HEADER_LEN 8 + #define PKT_DESP_TBL_NEXT_HEADER_DEFAULT 0x0 + /*[field] EG_VLAN_TAG_FMT_BYPASS_EN*/ + #define PKT_DESP_TBL_EG_VLAN_TAG_FMT_BYPASS_EN + #define PKT_DESP_TBL_EG_VLAN_TAG_FMT_BYPASS_EN_OFFSET 301 + #define PKT_DESP_TBL_EG_VLAN_TAG_FMT_BYPASS_EN_LEN 1 + #define PKT_DESP_TBL_EG_VLAN_TAG_FMT_BYPASS_EN_DEFAULT 0x0 + /*[field] EG_VLAN_XLT_BYPASS_EN*/ + #define PKT_DESP_TBL_EG_VLAN_XLT_BYPASS_EN + #define PKT_DESP_TBL_EG_VLAN_XLT_BYPASS_EN_OFFSET 302 + #define PKT_DESP_TBL_EG_VLAN_XLT_BYPASS_EN_LEN 1 + #define PKT_DESP_TBL_EG_VLAN_XLT_BYPASS_EN_DEFAULT 0x0 + /*[field] PKT_L2_EDIT_BYPASS*/ + #define PKT_DESP_TBL_PKT_L2_EDIT_BYPASS + #define PKT_DESP_TBL_PKT_L2_EDIT_BYPASS_OFFSET 303 + #define PKT_DESP_TBL_PKT_L2_EDIT_BYPASS_LEN 1 + #define PKT_DESP_TBL_PKT_L2_EDIT_BYPASS_DEFAULT 0x0 + /*[field] PKT_L3_EDIT_BYPASS*/ + #define PKT_DESP_TBL_PKT_L3_EDIT_BYPASS + #define PKT_DESP_TBL_PKT_L3_EDIT_BYPASS_OFFSET 304 + #define PKT_DESP_TBL_PKT_L3_EDIT_BYPASS_LEN 1 + #define PKT_DESP_TBL_PKT_L3_EDIT_BYPASS_DEFAULT 0x0 + /*[field] ACL_INDEX_TOGGLE*/ + #define PKT_DESP_TBL_ACL_INDEX_TOGGLE + #define PKT_DESP_TBL_ACL_INDEX_TOGGLE_OFFSET 305 + #define PKT_DESP_TBL_ACL_INDEX_TOGGLE_LEN 1 + #define PKT_DESP_TBL_ACL_INDEX_TOGGLE_DEFAULT 0x0 + /*[field] ACL_INDEX_VALID*/ + #define PKT_DESP_TBL_ACL_INDEX_VALID + #define PKT_DESP_TBL_ACL_INDEX_VALID_OFFSET 306 + #define PKT_DESP_TBL_ACL_INDEX_VALID_LEN 1 + #define PKT_DESP_TBL_ACL_INDEX_VALID_DEFAULT 0x0 + /*[field] ACL_INDEX*/ + #define PKT_DESP_TBL_ACL_INDEX + #define PKT_DESP_TBL_ACL_INDEX_OFFSET 307 + #define PKT_DESP_TBL_ACL_INDEX_LEN 9 + #define PKT_DESP_TBL_ACL_INDEX_DEFAULT 0x0 + /*[field] IP_ADDR_INDEX_TYPE*/ + #define PKT_DESP_TBL_IP_ADDR_INDEX_TYPE + #define PKT_DESP_TBL_IP_ADDR_INDEX_TYPE_OFFSET 316 + #define PKT_DESP_TBL_IP_ADDR_INDEX_TYPE_LEN 1 + #define PKT_DESP_TBL_IP_ADDR_INDEX_TYPE_DEFAULT 0x0 + /*[field] IP_ADDR_INDEX_TOGGLE*/ + #define PKT_DESP_TBL_IP_ADDR_INDEX_TOGGLE + #define PKT_DESP_TBL_IP_ADDR_INDEX_TOGGLE_OFFSET 317 + #define PKT_DESP_TBL_IP_ADDR_INDEX_TOGGLE_LEN 1 + #define PKT_DESP_TBL_IP_ADDR_INDEX_TOGGLE_DEFAULT 0x0 + /*[field] IP_ADDR_INDEX_VALID*/ + #define PKT_DESP_TBL_IP_ADDR_INDEX_VALID + #define PKT_DESP_TBL_IP_ADDR_INDEX_VALID_OFFSET 318 + #define PKT_DESP_TBL_IP_ADDR_INDEX_VALID_LEN 1 + #define PKT_DESP_TBL_IP_ADDR_INDEX_VALID_DEFAULT 0x0 + /*[field] IP_ADDR_INDEX*/ + #define PKT_DESP_TBL_IP_ADDR_INDEX + #define PKT_DESP_TBL_IP_ADDR_INDEX_OFFSET 319 + #define PKT_DESP_TBL_IP_ADDR_INDEX_LEN 13 + #define PKT_DESP_TBL_IP_ADDR_INDEX_DEFAULT 0x0 + /*[field] CHG_PORT_VP*/ + #define PKT_DESP_TBL_CHG_PORT_VP + #define PKT_DESP_TBL_CHG_PORT_VP_OFFSET 332 + #define PKT_DESP_TBL_CHG_PORT_VP_LEN 12 + #define PKT_DESP_TBL_CHG_PORT_VP_DEFAULT 0x0 + /*[field] HASH_FLAG*/ + #define PKT_DESP_TBL_HASH_FLAG + #define PKT_DESP_TBL_HASH_FLAG_OFFSET 344 + #define PKT_DESP_TBL_HASH_FLAG_LEN 3 + #define PKT_DESP_TBL_HASH_FLAG_DEFAULT 0x0 + /*[field] HASH_VALUE*/ + #define PKT_DESP_TBL_HASH_VALUE + #define PKT_DESP_TBL_HASH_VALUE_OFFSET 347 + #define PKT_DESP_TBL_HASH_VALUE_LEN 21 + #define PKT_DESP_TBL_HASH_VALUE_DEFAULT 0x0 + /*[field] COPY_CPU_FLAG*/ + #define PKT_DESP_TBL_COPY_CPU_FLAG + #define PKT_DESP_TBL_COPY_CPU_FLAG_OFFSET 368 + #define PKT_DESP_TBL_COPY_CPU_FLAG_LEN 1 + #define PKT_DESP_TBL_COPY_CPU_FLAG_DEFAULT 0x0 + /*[field] SRC_PN*/ + #define PKT_DESP_TBL_SRC_PN + #define PKT_DESP_TBL_SRC_PN_OFFSET 369 + #define PKT_DESP_TBL_SRC_PN_LEN 4 + #define PKT_DESP_TBL_SRC_PN_DEFAULT 0x0 + /*[field] RX_PTP_TYPE*/ + #define PKT_DESP_TBL_RX_PTP_TYPE + #define PKT_DESP_TBL_RX_PTP_TYPE_OFFSET 373 + #define PKT_DESP_TBL_RX_PTP_TYPE_LEN 4 + #define PKT_DESP_TBL_RX_PTP_TYPE_DEFAULT 0x0 + /*[field] FAKE_L2_PROT*/ + #define PKT_DESP_TBL_FAKE_L2_PROT + #define PKT_DESP_TBL_FAKE_L2_PROT_OFFSET 377 + #define PKT_DESP_TBL_FAKE_L2_PROT_LEN 1 + #define PKT_DESP_TBL_FAKE_L2_PROT_DEFAULT 0x0 + /*[field] FAKE_MAC_HEADER*/ + #define PKT_DESP_TBL_FAKE_MAC_HEADER + #define PKT_DESP_TBL_FAKE_MAC_HEADER_OFFSET 378 + #define PKT_DESP_TBL_FAKE_MAC_HEADER_LEN 1 + #define PKT_DESP_TBL_FAKE_MAC_HEADER_DEFAULT 0x0 + /*[field] VSI_VALID*/ + #define PKT_DESP_TBL_VSI_VALID + #define PKT_DESP_TBL_VSI_VALID_OFFSET 379 + #define PKT_DESP_TBL_VSI_VALID_LEN 1 + #define PKT_DESP_TBL_VSI_VALID_DEFAULT 0x0 + /*[field] VP_TX_CNT_EN*/ + #define PKT_DESP_TBL_VP_TX_CNT_EN + #define PKT_DESP_TBL_VP_TX_CNT_EN_OFFSET 380 + #define PKT_DESP_TBL_VP_TX_CNT_EN_LEN 1 + #define PKT_DESP_TBL_VP_TX_CNT_EN_DEFAULT 0x0 + /*[field] RSV0*/ + #define PKT_DESP_TBL_RSV0 + #define PKT_DESP_TBL_RSV0_OFFSET 381 + #define PKT_DESP_TBL_RSV0_LEN 7 + #define PKT_DESP_TBL_RSV0_DEFAULT 0x0 + /*[field] AC_GROUP_BITMAP*/ + #define PKT_DESP_TBL_AC_GROUP_BITMAP + #define PKT_DESP_TBL_AC_GROUP_BITMAP_OFFSET 388 + #define PKT_DESP_TBL_AC_GROUP_BITMAP_LEN 4 + #define PKT_DESP_TBL_AC_GROUP_BITMAP_DEFAULT 0x0 + /*[field] ONE_ENQ_FLAG*/ + #define PKT_DESP_TBL_ONE_ENQ_FLAG + #define PKT_DESP_TBL_ONE_ENQ_FLAG_OFFSET 392 + #define PKT_DESP_TBL_ONE_ENQ_FLAG_LEN 1 + #define PKT_DESP_TBL_ONE_ENQ_FLAG_DEFAULT 0x0 + /*[field] EDMA_VP*/ + #define PKT_DESP_TBL_EDMA_VP + #define PKT_DESP_TBL_EDMA_VP_OFFSET 393 + #define PKT_DESP_TBL_EDMA_VP_LEN 3 + #define PKT_DESP_TBL_EDMA_VP_DEFAULT 0x0 + /*[field] FC_GRP_ID*/ + #define PKT_DESP_TBL_FC_GRP_ID + #define PKT_DESP_TBL_FC_GRP_ID_OFFSET 396 + #define PKT_DESP_TBL_FC_GRP_ID_LEN 3 + #define PKT_DESP_TBL_FC_GRP_ID_DEFAULT 0x0 + /*[field] FC_EN*/ + #define PKT_DESP_TBL_FC_EN + #define PKT_DESP_TBL_FC_EN_OFFSET 399 + #define PKT_DESP_TBL_FC_EN_LEN 1 + #define PKT_DESP_TBL_FC_EN_DEFAULT 0x0 + +struct pkt_desp_tbl_0 { + a_uint32_t org_src_port_vp:12; + a_uint32_t src_port_vp:12; + a_uint32_t packet_length_0:8; + a_uint32_t packet_length_1:6; + a_uint32_t ts_dir:1; + a_uint32_t tx_ts_en:1; + a_uint32_t tx_os_correction_en:1; + a_uint32_t tx_ptp_tag:10; + a_uint32_t _reserved0_0:13; + a_uint32_t _reserved0_1:16; + a_uint32_t int_pri:4; + a_uint32_t int_dp:2; + a_uint32_t cpu_code:8; + a_uint32_t service_code_0:2; + a_uint32_t service_code_1:6; + a_uint32_t dst_l3_if:8; + a_uint32_t mac_da_0:18; + a_uint32_t mac_da_1:30; + a_uint32_t route_flag:1; + a_uint32_t pppoe_strip_flag:1; + a_uint32_t nat_action:3; + a_uint32_t napt_port:16; + a_uint32_t napt_addr_0:13; + a_uint32_t napt_addr_1:19; + a_uint32_t dscp_update:1; + a_uint32_t dscp:8; + a_uint32_t ttl_update:1; + a_uint32_t ttl_0:3; + a_uint32_t ttl_1:5; + a_uint32_t stag_flag:1; + a_uint32_t ctag_flag:1; + a_uint32_t snap_flag:1; + a_uint32_t pppoe_flag:1; + a_uint32_t int_stag_fmt:1; + a_uint32_t int_ctag_fmt:1; + a_uint32_t int_svid:12; + a_uint32_t int_cvid_0:9; + a_uint32_t int_cvid_1:3; + a_uint32_t int_spcp:3; + a_uint32_t int_cpcp:3; + a_uint32_t int_sdei:1; + a_uint32_t int_cdei:1; + a_uint32_t vsi:5; + a_uint32_t l3_offset:8; + a_uint32_t l3_type:2; + a_uint32_t l4_offset_0:6; + a_uint32_t l4_offset_1:2; + a_uint32_t l4_type:3; + a_uint32_t next_header:8; + a_uint32_t eg_vlan_tag_fmt_bypass_en:1; + a_uint32_t eg_vlan_xlt_bypass_en:1; + a_uint32_t pkt_l2_edit_bypass:1; + a_uint32_t pkt_l3_edit_bypass:1; + a_uint32_t acl_index_toggle:1; + a_uint32_t acl_index_valid:1; + a_uint32_t acl_index:9; + a_uint32_t ip_addr_index_type:1; + a_uint32_t ip_addr_index_toggle:1; + a_uint32_t ip_addr_index_valid:1; + a_uint32_t ip_addr_index_0:1; + a_uint32_t ip_addr_index_1:12; + a_uint32_t chg_port_vp:12; + a_uint32_t hash_flag:3; + a_uint32_t hash_value_0:5; + a_uint32_t hash_value_1:16; + a_uint32_t copy_cpu_flag:1; + a_uint32_t src_pn:4; + a_uint32_t rx_ptp_type:4; + a_uint32_t fake_l2_prot:1; + a_uint32_t fake_mac_header:1; + a_uint32_t vsi_valid:1; + a_uint32_t vp_tx_cnt_en:1; + a_uint32_t rsv0_0:3; + a_uint32_t rsv0_1:4; + a_uint32_t ac_group_bitmap:4; + a_uint32_t one_enq_flag:1; + a_uint32_t edma_vp:3; + a_uint32_t fc_grp_id:3; + a_uint32_t fc_en:1; + a_uint32_t _reserved1:16; +}; + +struct pkt_desp_tbl_1 { + a_uint32_t org_src_port_vp:12; + a_uint32_t src_port_vp:12; + a_uint32_t packet_length_0:8; + a_uint32_t packet_length_1:6; + a_uint32_t ts_dir:1; + a_uint32_t rx_ts_valid:1; + a_uint32_t rx_ts_0:24; + a_uint32_t rx_ts_1:16; + a_uint32_t int_pri:4; + a_uint32_t int_dp:2; + a_uint32_t cpu_code:8; + a_uint32_t service_code_0:2; + a_uint32_t service_code_1:6; + a_uint32_t dst_l3_if:8; + a_uint32_t mac_da_0:18; + a_uint32_t mac_da_1:30; + a_uint32_t route_flag:1; + a_uint32_t pppoe_strip_flag:1; + a_uint32_t nat_action:3; + a_uint32_t napt_port:16; + a_uint32_t napt_addr_0:13; + a_uint32_t napt_addr_1:19; + a_uint32_t dscp_update:1; + a_uint32_t dscp:8; + a_uint32_t ttl_update:1; + a_uint32_t ttl_0:3; + a_uint32_t ttl_1:5; + a_uint32_t stag_flag:1; + a_uint32_t ctag_flag:1; + a_uint32_t snap_flag:1; + a_uint32_t pppoe_flag:1; + a_uint32_t int_stag_fmt:1; + a_uint32_t int_ctag_fmt:1; + a_uint32_t int_svid:12; + a_uint32_t int_cvid_0:9; + a_uint32_t int_cvid_1:3; + a_uint32_t int_spcp:3; + a_uint32_t int_cpcp:3; + a_uint32_t int_sdei:1; + a_uint32_t int_cdei:1; + a_uint32_t vsi:5; + a_uint32_t l3_offset:8; + a_uint32_t l3_type:2; + a_uint32_t l4_offset_0:6; + a_uint32_t l4_offset_1:2; + a_uint32_t l4_type:3; + a_uint32_t next_header:8; + a_uint32_t eg_vlan_tag_fmt_bypass_en:1; + a_uint32_t eg_vlan_xlt_bypass_en:1; + a_uint32_t pkt_l2_edit_bypass:1; + a_uint32_t pkt_l3_edit_bypass:1; + a_uint32_t acl_index_toggle:1; + a_uint32_t acl_index_valid:1; + a_uint32_t acl_index:9; + a_uint32_t ip_addr_index_type:1; + a_uint32_t ip_addr_index_toggle:1; + a_uint32_t ip_addr_index_valid:1; + a_uint32_t ip_addr_index_0:1; + a_uint32_t ip_addr_index_1:12; + a_uint32_t chg_port_vp:12; + a_uint32_t hash_flag:3; + a_uint32_t hash_value_0:5; + a_uint32_t hash_value_1:16; + a_uint32_t copy_cpu_flag:1; + a_uint32_t src_pn:4; + a_uint32_t rx_ptp_type:4; + a_uint32_t fake_l2_prot:1; + a_uint32_t fake_mac_header:1; + a_uint32_t vsi_valid:1; + a_uint32_t vp_tx_cnt_en:1; + a_uint32_t rsv0_0:3; + a_uint32_t rsv0_1:4; + a_uint32_t ac_group_bitmap:4; + a_uint32_t one_enq_flag:1; + a_uint32_t edma_vp:3; + a_uint32_t fc_grp_id:3; + a_uint32_t fc_en:1; + a_uint32_t _reserved0:16; +}; + +union pkt_desp_tbl_u { + a_uint32_t val[13]; + struct pkt_desp_tbl_0 bf0; + struct pkt_desp_tbl_1 bf1; +}; + +/*[table] UNI_DROP_CNT_TBL*/ +#define UNI_DROP_CNT_TBL +#define UNI_DROP_CNT_TBL_ADDRESS 0x1e0000 +#define UNI_DROP_CNT_TBL_NUM 1536 +#define UNI_DROP_CNT_TBL_INC 0x10 +#define UNI_DROP_CNT_TBL_TYPE REG_TYPE_RW +#define UNI_DROP_CNT_TBL_DEFAULT 0x0 + /*[field] UNI_DROP_PKT*/ + #define UNI_DROP_CNT_TBL_UNI_DROP_PKT + #define UNI_DROP_CNT_TBL_UNI_DROP_PKT_OFFSET 0 + #define UNI_DROP_CNT_TBL_UNI_DROP_PKT_LEN 32 + #define UNI_DROP_CNT_TBL_UNI_DROP_PKT_DEFAULT 0x0 + /*[field] UNI_DROP_BYTE*/ + #define UNI_DROP_CNT_TBL_UNI_DROP_BYTE + #define UNI_DROP_CNT_TBL_UNI_DROP_BYTE_OFFSET 32 + #define UNI_DROP_CNT_TBL_UNI_DROP_BYTE_LEN 40 + #define UNI_DROP_CNT_TBL_UNI_DROP_BYTE_DEFAULT 0x0 + +struct uni_drop_cnt_tbl { + a_uint32_t uni_drop_pkt:32; + a_uint32_t uni_drop_byte_0:32; + a_uint32_t uni_drop_byte_1:8; + a_uint32_t _reserved0:24; +}; + +union uni_drop_cnt_tbl_u { + a_uint32_t val[3]; + struct uni_drop_cnt_tbl bf; +}; + +/*[table] MUL_P0_DROP_CNT_TBL*/ +#define MUL_P0_DROP_CNT_TBL +#define MUL_P0_DROP_CNT_TBL_ADDRESS 0x1f0000 +#define MUL_P0_DROP_CNT_TBL_NUM 48 +#define MUL_P0_DROP_CNT_TBL_INC 0x10 +#define MUL_P0_DROP_CNT_TBL_TYPE REG_TYPE_RW +#define MUL_P0_DROP_CNT_TBL_DEFAULT 0x0 + /*[field] MUL_P0_DROP_PKT*/ + #define MUL_P0_DROP_CNT_TBL_MUL_P0_DROP_PKT + #define MUL_P0_DROP_CNT_TBL_MUL_P0_DROP_PKT_OFFSET 0 + #define MUL_P0_DROP_CNT_TBL_MUL_P0_DROP_PKT_LEN 32 + #define MUL_P0_DROP_CNT_TBL_MUL_P0_DROP_PKT_DEFAULT 0x0 + /*[field] MUL_P0_DROP_BYTE*/ + #define MUL_P0_DROP_CNT_TBL_MUL_P0_DROP_BYTE + #define MUL_P0_DROP_CNT_TBL_MUL_P0_DROP_BYTE_OFFSET 32 + #define MUL_P0_DROP_CNT_TBL_MUL_P0_DROP_BYTE_LEN 40 + #define MUL_P0_DROP_CNT_TBL_MUL_P0_DROP_BYTE_DEFAULT 0x0 + +struct mul_p0_drop_cnt_tbl { + a_uint32_t mul_p0_drop_pkt:32; + a_uint32_t mul_p0_drop_byte_0:32; + a_uint32_t mul_p0_drop_byte_1:8; + a_uint32_t _reserved0:24; +}; + +union mul_p0_drop_cnt_tbl_u { + a_uint32_t val[3]; + struct mul_p0_drop_cnt_tbl bf; +}; + +/*[table] MUL_P1_DROP_CNT_TBL*/ +#define MUL_P1_DROP_CNT_TBL +#define MUL_P1_DROP_CNT_TBL_ADDRESS 0x1f1000 +#define MUL_P1_DROP_CNT_TBL_NUM 12 +#define MUL_P1_DROP_CNT_TBL_INC 0x10 +#define MUL_P1_DROP_CNT_TBL_TYPE REG_TYPE_RW +#define MUL_P1_DROP_CNT_TBL_DEFAULT 0x0 + /*[field] MUL_P1_DROP_PKT*/ + #define MUL_P1_DROP_CNT_TBL_MUL_P1_DROP_PKT + #define MUL_P1_DROP_CNT_TBL_MUL_P1_DROP_PKT_OFFSET 0 + #define MUL_P1_DROP_CNT_TBL_MUL_P1_DROP_PKT_LEN 32 + #define MUL_P1_DROP_CNT_TBL_MUL_P1_DROP_PKT_DEFAULT 0x0 + /*[field] MUL_P1_DROP_BYTE*/ + #define MUL_P1_DROP_CNT_TBL_MUL_P1_DROP_BYTE + #define MUL_P1_DROP_CNT_TBL_MUL_P1_DROP_BYTE_OFFSET 32 + #define MUL_P1_DROP_CNT_TBL_MUL_P1_DROP_BYTE_LEN 40 + #define MUL_P1_DROP_CNT_TBL_MUL_P1_DROP_BYTE_DEFAULT 0x0 + +struct mul_p1_drop_cnt_tbl { + a_uint32_t mul_p1_drop_pkt:32; + a_uint32_t mul_p1_drop_byte_0:32; + a_uint32_t mul_p1_drop_byte_1:8; + a_uint32_t _reserved0:24; +}; + +union mul_p1_drop_cnt_tbl_u { + a_uint32_t val[3]; + struct mul_p1_drop_cnt_tbl bf; +}; + +/*[table] MUL_P2_DROP_CNT_TBL*/ +#define MUL_P2_DROP_CNT_TBL +#define MUL_P2_DROP_CNT_TBL_ADDRESS 0x1f2000 +#define MUL_P2_DROP_CNT_TBL_NUM 12 +#define MUL_P2_DROP_CNT_TBL_INC 0x10 +#define MUL_P2_DROP_CNT_TBL_TYPE REG_TYPE_RW +#define MUL_P2_DROP_CNT_TBL_DEFAULT 0x0 + /*[field] MUL_P2_DROP_PKT*/ + #define MUL_P2_DROP_CNT_TBL_MUL_P2_DROP_PKT + #define MUL_P2_DROP_CNT_TBL_MUL_P2_DROP_PKT_OFFSET 0 + #define MUL_P2_DROP_CNT_TBL_MUL_P2_DROP_PKT_LEN 32 + #define MUL_P2_DROP_CNT_TBL_MUL_P2_DROP_PKT_DEFAULT 0x0 + /*[field] MUL_P2_DROP_BYTE*/ + #define MUL_P2_DROP_CNT_TBL_MUL_P2_DROP_BYTE + #define MUL_P2_DROP_CNT_TBL_MUL_P2_DROP_BYTE_OFFSET 32 + #define MUL_P2_DROP_CNT_TBL_MUL_P2_DROP_BYTE_LEN 40 + #define MUL_P2_DROP_CNT_TBL_MUL_P2_DROP_BYTE_DEFAULT 0x0 + +struct mul_p2_drop_cnt_tbl { + a_uint32_t mul_p2_drop_pkt:32; + a_uint32_t mul_p2_drop_byte_0:32; + a_uint32_t mul_p2_drop_byte_1:8; + a_uint32_t _reserved0:24; +}; + +union mul_p2_drop_cnt_tbl_u { + a_uint32_t val[3]; + struct mul_p2_drop_cnt_tbl bf; +}; + +/*[table] MUL_P3_DROP_CNT_TBL*/ +#define MUL_P3_DROP_CNT_TBL +#define MUL_P3_DROP_CNT_TBL_ADDRESS 0x1f3000 +#define MUL_P3_DROP_CNT_TBL_NUM 12 +#define MUL_P3_DROP_CNT_TBL_INC 0x10 +#define MUL_P3_DROP_CNT_TBL_TYPE REG_TYPE_RW +#define MUL_P3_DROP_CNT_TBL_DEFAULT 0x0 + /*[field] MUL_P3_DROP_PKT*/ + #define MUL_P3_DROP_CNT_TBL_MUL_P3_DROP_PKT + #define MUL_P3_DROP_CNT_TBL_MUL_P3_DROP_PKT_OFFSET 0 + #define MUL_P3_DROP_CNT_TBL_MUL_P3_DROP_PKT_LEN 32 + #define MUL_P3_DROP_CNT_TBL_MUL_P3_DROP_PKT_DEFAULT 0x0 + /*[field] MUL_P3_DROP_BYTE*/ + #define MUL_P3_DROP_CNT_TBL_MUL_P3_DROP_BYTE + #define MUL_P3_DROP_CNT_TBL_MUL_P3_DROP_BYTE_OFFSET 32 + #define MUL_P3_DROP_CNT_TBL_MUL_P3_DROP_BYTE_LEN 40 + #define MUL_P3_DROP_CNT_TBL_MUL_P3_DROP_BYTE_DEFAULT 0x0 + +struct mul_p3_drop_cnt_tbl { + a_uint32_t mul_p3_drop_pkt:32; + a_uint32_t mul_p3_drop_byte_0:32; + a_uint32_t mul_p3_drop_byte_1:8; + a_uint32_t _reserved0:24; +}; + +union mul_p3_drop_cnt_tbl_u { + a_uint32_t val[3]; + struct mul_p3_drop_cnt_tbl bf; +}; + +/*[table] MUL_P4_DROP_CNT_TBL*/ +#define MUL_P4_DROP_CNT_TBL +#define MUL_P4_DROP_CNT_TBL_ADDRESS 0x1f4000 +#define MUL_P4_DROP_CNT_TBL_NUM 12 +#define MUL_P4_DROP_CNT_TBL_INC 0x10 +#define MUL_P4_DROP_CNT_TBL_TYPE REG_TYPE_RW +#define MUL_P4_DROP_CNT_TBL_DEFAULT 0x0 + /*[field] MUL_P4_DROP_PKT*/ + #define MUL_P4_DROP_CNT_TBL_MUL_P4_DROP_PKT + #define MUL_P4_DROP_CNT_TBL_MUL_P4_DROP_PKT_OFFSET 0 + #define MUL_P4_DROP_CNT_TBL_MUL_P4_DROP_PKT_LEN 32 + #define MUL_P4_DROP_CNT_TBL_MUL_P4_DROP_PKT_DEFAULT 0x0 + /*[field] MUL_P4_DROP_BYTE*/ + #define MUL_P4_DROP_CNT_TBL_MUL_P4_DROP_BYTE + #define MUL_P4_DROP_CNT_TBL_MUL_P4_DROP_BYTE_OFFSET 32 + #define MUL_P4_DROP_CNT_TBL_MUL_P4_DROP_BYTE_LEN 40 + #define MUL_P4_DROP_CNT_TBL_MUL_P4_DROP_BYTE_DEFAULT 0x0 + +struct mul_p4_drop_cnt_tbl { + a_uint32_t mul_p4_drop_pkt:32; + a_uint32_t mul_p4_drop_byte_0:32; + a_uint32_t mul_p4_drop_byte_1:8; + a_uint32_t _reserved0:24; +}; + +union mul_p4_drop_cnt_tbl_u { + a_uint32_t val[3]; + struct mul_p4_drop_cnt_tbl bf; +}; + +/*[table] MUL_P5_DROP_CNT_TBL*/ +#define MUL_P5_DROP_CNT_TBL +#define MUL_P5_DROP_CNT_TBL_ADDRESS 0x1f5000 +#define MUL_P5_DROP_CNT_TBL_NUM 12 +#define MUL_P5_DROP_CNT_TBL_INC 0x10 +#define MUL_P5_DROP_CNT_TBL_TYPE REG_TYPE_RW +#define MUL_P5_DROP_CNT_TBL_DEFAULT 0x0 + /*[field] MUL_P5_DROP_PKT*/ + #define MUL_P5_DROP_CNT_TBL_MUL_P5_DROP_PKT + #define MUL_P5_DROP_CNT_TBL_MUL_P5_DROP_PKT_OFFSET 0 + #define MUL_P5_DROP_CNT_TBL_MUL_P5_DROP_PKT_LEN 32 + #define MUL_P5_DROP_CNT_TBL_MUL_P5_DROP_PKT_DEFAULT 0x0 + /*[field] MUL_P5_DROP_BYTE*/ + #define MUL_P5_DROP_CNT_TBL_MUL_P5_DROP_BYTE + #define MUL_P5_DROP_CNT_TBL_MUL_P5_DROP_BYTE_OFFSET 32 + #define MUL_P5_DROP_CNT_TBL_MUL_P5_DROP_BYTE_LEN 40 + #define MUL_P5_DROP_CNT_TBL_MUL_P5_DROP_BYTE_DEFAULT 0x0 + +struct mul_p5_drop_cnt_tbl { + a_uint32_t mul_p5_drop_pkt:32; + a_uint32_t mul_p5_drop_byte_0:32; + a_uint32_t mul_p5_drop_byte_1:8; + a_uint32_t _reserved0:24; +}; + +union mul_p5_drop_cnt_tbl_u { + a_uint32_t val[3]; + struct mul_p5_drop_cnt_tbl bf; +}; + +/*[table] MUL_P6_DROP_CNT_TBL*/ +#define MUL_P6_DROP_CNT_TBL +#define MUL_P6_DROP_CNT_TBL_ADDRESS 0x1f6000 +#define MUL_P6_DROP_CNT_TBL_NUM 12 +#define MUL_P6_DROP_CNT_TBL_INC 0x10 +#define MUL_P6_DROP_CNT_TBL_TYPE REG_TYPE_RW +#define MUL_P6_DROP_CNT_TBL_DEFAULT 0x0 + /*[field] MUL_P6_DROP_PKT*/ + #define MUL_P6_DROP_CNT_TBL_MUL_P6_DROP_PKT + #define MUL_P6_DROP_CNT_TBL_MUL_P6_DROP_PKT_OFFSET 0 + #define MUL_P6_DROP_CNT_TBL_MUL_P6_DROP_PKT_LEN 32 + #define MUL_P6_DROP_CNT_TBL_MUL_P6_DROP_PKT_DEFAULT 0x0 + /*[field] MUL_P6_DROP_BYTE*/ + #define MUL_P6_DROP_CNT_TBL_MUL_P6_DROP_BYTE + #define MUL_P6_DROP_CNT_TBL_MUL_P6_DROP_BYTE_OFFSET 32 + #define MUL_P6_DROP_CNT_TBL_MUL_P6_DROP_BYTE_LEN 40 + #define MUL_P6_DROP_CNT_TBL_MUL_P6_DROP_BYTE_DEFAULT 0x0 + +struct mul_p6_drop_cnt_tbl { + a_uint32_t mul_p6_drop_pkt:32; + a_uint32_t mul_p6_drop_byte_0:32; + a_uint32_t mul_p6_drop_byte_1:8; + a_uint32_t _reserved0:24; +}; + +union mul_p6_drop_cnt_tbl_u { + a_uint32_t val[3]; + struct mul_p6_drop_cnt_tbl bf; +}; + +/*[table] MUL_P7_DROP_CNT_TBL*/ +#define MUL_P7_DROP_CNT_TBL +#define MUL_P7_DROP_CNT_TBL_ADDRESS 0x1f7000 +#define MUL_P7_DROP_CNT_TBL_NUM 12 +#define MUL_P7_DROP_CNT_TBL_INC 0x10 +#define MUL_P7_DROP_CNT_TBL_TYPE REG_TYPE_RW +#define MUL_P7_DROP_CNT_TBL_DEFAULT 0x0 + /*[field] MUL_P7_DROP_PKT*/ + #define MUL_P7_DROP_CNT_TBL_MUL_P7_DROP_PKT + #define MUL_P7_DROP_CNT_TBL_MUL_P7_DROP_PKT_OFFSET 0 + #define MUL_P7_DROP_CNT_TBL_MUL_P7_DROP_PKT_LEN 32 + #define MUL_P7_DROP_CNT_TBL_MUL_P7_DROP_PKT_DEFAULT 0x0 + /*[field] MUL_P7_DROP_BYTE*/ + #define MUL_P7_DROP_CNT_TBL_MUL_P7_DROP_BYTE + #define MUL_P7_DROP_CNT_TBL_MUL_P7_DROP_BYTE_OFFSET 32 + #define MUL_P7_DROP_CNT_TBL_MUL_P7_DROP_BYTE_LEN 40 + #define MUL_P7_DROP_CNT_TBL_MUL_P7_DROP_BYTE_DEFAULT 0x0 + +struct mul_p7_drop_cnt_tbl { + a_uint32_t mul_p7_drop_pkt:32; + a_uint32_t mul_p7_drop_byte_0:32; + a_uint32_t mul_p7_drop_byte_1:8; + a_uint32_t _reserved0:24; +}; + +union mul_p7_drop_cnt_tbl_u { + a_uint32_t val[3]; + struct mul_p7_drop_cnt_tbl bf; +}; + +/*[table] UQ_AGG_PROFILE_MAP*/ +#define UQ_AGG_PROFILE_MAP +#define UQ_AGG_PROFILE_MAP_ADDRESS 0x1f8000 +#define UQ_AGG_PROFILE_MAP_NUM 256 +#define UQ_AGG_PROFILE_MAP_INC 0x10 +#define UQ_AGG_PROFILE_MAP_TYPE REG_TYPE_RW +#define UQ_AGG_PROFILE_MAP_DEFAULT 0x0 + /*[field] QID_2_AGG_ID*/ + #define UQ_AGG_PROFILE_MAP_QID_2_AGG_ID + #define UQ_AGG_PROFILE_MAP_QID_2_AGG_ID_OFFSET 0 + #define UQ_AGG_PROFILE_MAP_QID_2_AGG_ID_LEN 3 + #define UQ_AGG_PROFILE_MAP_QID_2_AGG_ID_DEFAULT 0x0 + /*[field] ENABLE*/ + #define UQ_AGG_PROFILE_MAP_ENABLE + #define UQ_AGG_PROFILE_MAP_ENABLE_OFFSET 3 + #define UQ_AGG_PROFILE_MAP_ENABLE_LEN 1 + #define UQ_AGG_PROFILE_MAP_ENABLE_DEFAULT 0x0 + +struct uq_agg_profile_map { + a_uint32_t qid_2_agg_id:3; + a_uint32_t enable:1; + a_uint32_t _reserved0:28; +}; + +union uq_agg_profile_map_u { + a_uint32_t val; + struct uq_agg_profile_map bf; +}; + +/*[table] QUEUE_TX_COUNTER_TBL*/ +#define QUEUE_TX_COUNTER_TBL +#define QUEUE_TX_COUNTER_TBL_ADDRESS 0x4000 +#define QUEUE_TX_COUNTER_TBL_NUM 300 +#define QUEUE_TX_COUNTER_TBL_INC 0x10 +#define QUEUE_TX_COUNTER_TBL_TYPE REG_TYPE_RW +#define QUEUE_TX_COUNTER_TBL_DEFAULT 0x0 + /*[field] TX_PACKETS*/ + #define QUEUE_TX_COUNTER_TBL_TX_PACKETS + #define QUEUE_TX_COUNTER_TBL_TX_PACKETS_OFFSET 0 + #define QUEUE_TX_COUNTER_TBL_TX_PACKETS_LEN 32 + #define QUEUE_TX_COUNTER_TBL_TX_PACKETS_DEFAULT 0x0 + /*[field] TX_BYTES*/ + #define QUEUE_TX_COUNTER_TBL_TX_BYTES + #define QUEUE_TX_COUNTER_TBL_TX_BYTES_OFFSET 32 + #define QUEUE_TX_COUNTER_TBL_TX_BYTES_LEN 40 + #define QUEUE_TX_COUNTER_TBL_TX_BYTES_DEFAULT 0x0 + +struct queue_tx_counter_tbl { + a_uint32_t tx_packets:32; + a_uint32_t tx_bytes_0:32; + a_uint32_t tx_bytes_1:8; + a_uint32_t _reserved0:24; +}; + +union queue_tx_counter_tbl_u { + a_uint32_t val[3]; + struct queue_tx_counter_tbl bf; +}; + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_qos.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_qos.h new file mode 100755 index 000000000..353290b75 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_qos.h @@ -0,0 +1,2163 @@ +/* + * 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 + * @{ + */ +#ifndef _HPPE_QOS_H_ +#define _HPPE_QOS_H_ + +#define L0_FLOW_MAP_TBL_MAX_ENTRY 300 +#define L0_C_SP_CFG_TBL_MAX_ENTRY 512 +#define L0_E_SP_CFG_TBL_MAX_ENTRY 512 +#define L0_FLOW_PORT_MAP_TBL_MAX_ENTRY 300 +#define L0_C_DRR_HEAD_TBL_MAX_ENTRY 160 +#define L0_E_DRR_HEAD_TBL_MAX_ENTRY 160 +#define L0_DRR_CREDIT_TBL_MAX_ENTRY 300 +#define L0_C_DRR_LL_TBL_MAX_ENTRY 300 +#define L0_C_DRR_REVERSE_LL_TBL_MAX_ENTRY 300 +#define L0_E_DRR_LL_TBL_MAX_ENTRY 300 +#define L0_E_DRR_REVERSE_LL_TBL_MAX_ENTRY 300 +#define L0_SP_ENTRY_TBL_MAX_ENTRY 64 +#define L0_ENS_Q_LL_TBL_MAX_ENTRY 300 +#define L0_ENS_Q_HEAD_TBL_MAX_ENTRY 8 +#define L0_ENS_Q_ENTRY_TBL_MAX_ENTRY 300 +#define L0_FLOW_STATUS_TBL_MAX_ENTRY 300 +#define RING_Q_MAP_TBL_MAX_ENTRY 16 +#define RFC_BLOCK_TBL_MAX_ENTRY 300 +#define RFC_STATUS_TBL_MAX_ENTRY 300 +#define DEQ_DIS_TBL_MAX_ENTRY 300 +#define L1_FLOW_MAP_TBL_MAX_ENTRY 64 +#define L1_C_SP_CFG_TBL_MAX_ENTRY 64 +#define L1_E_SP_CFG_TBL_MAX_ENTRY 64 +#define L1_FLOW_PORT_MAP_TBL_MAX_ENTRY 64 +#define L1_C_DRR_HEAD_TBL_MAX_ENTRY 36 +#define L1_E_DRR_HEAD_TBL_MAX_ENTRY 36 +#define L1_DRR_CREDIT_TBL_MAX_ENTRY 64 +#define L1_C_DRR_LL_TBL_MAX_ENTRY 64 +#define L1_C_DRR_REVERSE_LL_TBL_MAX_ENTRY 64 +#define L1_E_DRR_LL_TBL_MAX_ENTRY 64 +#define L1_E_DRR_REVERSE_LL_TBL_MAX_ENTRY 64 +#define L1_A_FLOW_ENTRY_TBL_MAX_ENTRY 64 +#define L1_B_FLOW_ENTRY_TBL_MAX_ENTRY 64 +#define L1_SP_ENTRY_TBL_MAX_ENTRY 8 + +#define L1_ENS_Q_LL_TBL_MAX_ENTRY 64 +#define L1_ENS_Q_HEAD_TBL_MAX_ENTRY 8 +#define L1_ENS_Q_ENTRY_TBL_MAX_ENTRY 64 +#define L1_FLOW_STATUS_TBL_MAX_ENTRY 64 +#define PSCH_TDM_CFG_TBL_MAX_ENTRY 128 + +#define PORT_QOS_CTRL_MAX_ENTRY 8 +#define PCP_QOS_GROUP_0_MAX_ENTRY 16 +#define PCP_QOS_GROUP_1_MAX_ENTRY 16 +#define FLOW_QOS_GROUP_0_MAX_ENTRY 32 +#define FLOW_QOS_GROUP_1_MAX_ENTRY 32 +#define DSCP_QOS_GROUP_0_MAX_ENTRY 64 +#define DSCP_QOS_GROUP_1_MAX_ENTRY 64 + +sw_error_t +hppe_dscp_qos_group_0_get( + a_uint32_t dev_id, + a_uint32_t index, + union dscp_qos_group_0_u *value); + +sw_error_t +hppe_dscp_qos_group_0_set( + a_uint32_t dev_id, + a_uint32_t index, + union dscp_qos_group_0_u *value); + +sw_error_t +hppe_dscp_qos_group_1_get( + a_uint32_t dev_id, + a_uint32_t index, + union dscp_qos_group_1_u *value); + +sw_error_t +hppe_dscp_qos_group_1_set( + a_uint32_t dev_id, + a_uint32_t index, + union dscp_qos_group_1_u *value); + + +sw_error_t +hppe_pcp_qos_group_0_get( + a_uint32_t dev_id, + a_uint32_t index, + union pcp_qos_group_0_u *value); + +sw_error_t +hppe_pcp_qos_group_0_set( + a_uint32_t dev_id, + a_uint32_t index, + union pcp_qos_group_0_u *value); + +sw_error_t +hppe_pcp_qos_group_1_get( + a_uint32_t dev_id, + a_uint32_t index, + union pcp_qos_group_1_u *value); + +sw_error_t +hppe_pcp_qos_group_1_set( + a_uint32_t dev_id, + a_uint32_t index, + union pcp_qos_group_1_u *value); + +sw_error_t +hppe_flow_qos_group_0_get( + a_uint32_t dev_id, + a_uint32_t index, + union flow_qos_group_0_u *value); + +sw_error_t +hppe_flow_qos_group_0_set( + a_uint32_t dev_id, + a_uint32_t index, + union flow_qos_group_0_u *value); + +sw_error_t +hppe_flow_qos_group_1_get( + a_uint32_t dev_id, + a_uint32_t index, + union flow_qos_group_1_u *value); + +sw_error_t +hppe_flow_qos_group_1_set( + a_uint32_t dev_id, + a_uint32_t index, + union flow_qos_group_1_u *value); + +sw_error_t +hppe_port_qos_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_qos_ctrl_u *value); + +sw_error_t +hppe_port_qos_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_qos_ctrl_u *value); + +sw_error_t +hppe_tdm_depth_cfg_get( + a_uint32_t dev_id, + union tdm_depth_cfg_u *value); + +sw_error_t +hppe_tdm_depth_cfg_set( + a_uint32_t dev_id, + union tdm_depth_cfg_u *value); + +sw_error_t +hppe_min_max_mode_cfg_get( + a_uint32_t dev_id, + union min_max_mode_cfg_u *value); + +sw_error_t +hppe_min_max_mode_cfg_set( + a_uint32_t dev_id, + union min_max_mode_cfg_u *value); + +sw_error_t +hppe_tm_dbg_addr_get( + a_uint32_t dev_id, + union tm_dbg_addr_u *value); + +sw_error_t +hppe_tm_dbg_addr_set( + a_uint32_t dev_id, + union tm_dbg_addr_u *value); + +sw_error_t +hppe_tm_dbg_data_get( + a_uint32_t dev_id, + union tm_dbg_data_u *value); + +sw_error_t +hppe_tm_dbg_data_set( + a_uint32_t dev_id, + union tm_dbg_data_u *value); + +sw_error_t +hppe_eco_reserve_0_get( + a_uint32_t dev_id, + union eco_reserve_0_u *value); + +sw_error_t +hppe_eco_reserve_0_set( + a_uint32_t dev_id, + union eco_reserve_0_u *value); + +sw_error_t +hppe_eco_reserve_1_get( + a_uint32_t dev_id, + union eco_reserve_1_u *value); + +sw_error_t +hppe_eco_reserve_1_set( + a_uint32_t dev_id, + union eco_reserve_1_u *value); + +sw_error_t +hppe_l0_flow_map_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_flow_map_tbl_u *value); + +sw_error_t +hppe_l0_flow_map_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_flow_map_tbl_u *value); + +sw_error_t +hppe_l0_c_sp_cfg_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_c_sp_cfg_tbl_u *value); + +sw_error_t +hppe_l0_c_sp_cfg_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_c_sp_cfg_tbl_u *value); + +sw_error_t +hppe_l0_e_sp_cfg_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_e_sp_cfg_tbl_u *value); + +sw_error_t +hppe_l0_e_sp_cfg_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_e_sp_cfg_tbl_u *value); + +sw_error_t +hppe_l0_flow_port_map_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_flow_port_map_tbl_u *value); + +sw_error_t +hppe_l0_flow_port_map_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_flow_port_map_tbl_u *value); + +sw_error_t +hppe_l0_c_drr_head_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_c_drr_head_tbl_u *value); + +sw_error_t +hppe_l0_c_drr_head_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_c_drr_head_tbl_u *value); + +sw_error_t +hppe_l0_e_drr_head_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_e_drr_head_tbl_u *value); + +sw_error_t +hppe_l0_e_drr_head_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_e_drr_head_tbl_u *value); + +sw_error_t +hppe_l0_drr_credit_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_drr_credit_tbl_u *value); + +sw_error_t +hppe_l0_drr_credit_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_drr_credit_tbl_u *value); + +sw_error_t +hppe_l0_c_drr_ll_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_c_drr_ll_tbl_u *value); + +sw_error_t +hppe_l0_c_drr_ll_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_c_drr_ll_tbl_u *value); + +sw_error_t +hppe_l0_c_drr_reverse_ll_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_c_drr_reverse_ll_tbl_u *value); + +sw_error_t +hppe_l0_c_drr_reverse_ll_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_c_drr_reverse_ll_tbl_u *value); + +sw_error_t +hppe_l0_e_drr_ll_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_e_drr_ll_tbl_u *value); + +sw_error_t +hppe_l0_e_drr_ll_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_e_drr_ll_tbl_u *value); + +sw_error_t +hppe_l0_e_drr_reverse_ll_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_e_drr_reverse_ll_tbl_u *value); + +sw_error_t +hppe_l0_e_drr_reverse_ll_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_e_drr_reverse_ll_tbl_u *value); + +sw_error_t +hppe_l0_sp_entry_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_sp_entry_tbl_u *value); + +sw_error_t +hppe_l0_sp_entry_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_sp_entry_tbl_u *value); + +sw_error_t +hppe_l0_ens_q_ll_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_ens_q_ll_tbl_u *value); + +sw_error_t +hppe_l0_ens_q_ll_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_ens_q_ll_tbl_u *value); + +sw_error_t +hppe_l0_ens_q_head_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_ens_q_head_tbl_u *value); + +sw_error_t +hppe_l0_ens_q_head_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_ens_q_head_tbl_u *value); + +sw_error_t +hppe_l0_ens_q_entry_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_ens_q_entry_tbl_u *value); + +sw_error_t +hppe_l0_ens_q_entry_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_ens_q_entry_tbl_u *value); + +sw_error_t +hppe_l0_flow_status_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_flow_status_tbl_u *value); + +sw_error_t +hppe_l0_flow_status_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_flow_status_tbl_u *value); + +sw_error_t +hppe_ring_q_map_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union ring_q_map_tbl_u *value); + +sw_error_t +hppe_ring_q_map_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union ring_q_map_tbl_u *value); + +sw_error_t +hppe_rfc_block_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union rfc_block_tbl_u *value); + +sw_error_t +hppe_rfc_block_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union rfc_block_tbl_u *value); + +sw_error_t +hppe_rfc_status_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union rfc_status_tbl_u *value); + +sw_error_t +hppe_rfc_status_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union rfc_status_tbl_u *value); + +sw_error_t +hppe_deq_dis_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union deq_dis_tbl_u *value); + +sw_error_t +hppe_deq_dis_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union deq_dis_tbl_u *value); + +sw_error_t +hppe_l1_flow_map_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_flow_map_tbl_u *value); + +sw_error_t +hppe_l1_flow_map_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_flow_map_tbl_u *value); + +sw_error_t +hppe_l1_c_sp_cfg_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_c_sp_cfg_tbl_u *value); + +sw_error_t +hppe_l1_c_sp_cfg_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_c_sp_cfg_tbl_u *value); + +sw_error_t +hppe_l1_e_sp_cfg_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_e_sp_cfg_tbl_u *value); + +sw_error_t +hppe_l1_e_sp_cfg_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_e_sp_cfg_tbl_u *value); + +sw_error_t +hppe_l1_flow_port_map_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_flow_port_map_tbl_u *value); + +sw_error_t +hppe_l1_flow_port_map_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_flow_port_map_tbl_u *value); + +sw_error_t +hppe_l1_c_drr_head_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_c_drr_head_tbl_u *value); + +sw_error_t +hppe_l1_c_drr_head_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_c_drr_head_tbl_u *value); + +sw_error_t +hppe_l1_e_drr_head_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_e_drr_head_tbl_u *value); + +sw_error_t +hppe_l1_e_drr_head_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_e_drr_head_tbl_u *value); + +sw_error_t +hppe_l1_drr_credit_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_drr_credit_tbl_u *value); + +sw_error_t +hppe_l1_drr_credit_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_drr_credit_tbl_u *value); + +sw_error_t +hppe_l1_c_drr_ll_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_c_drr_ll_tbl_u *value); + +sw_error_t +hppe_l1_c_drr_ll_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_c_drr_ll_tbl_u *value); + +sw_error_t +hppe_l1_c_drr_reverse_ll_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_c_drr_reverse_ll_tbl_u *value); + +sw_error_t +hppe_l1_c_drr_reverse_ll_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_c_drr_reverse_ll_tbl_u *value); + +sw_error_t +hppe_l1_e_drr_ll_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_e_drr_ll_tbl_u *value); + +sw_error_t +hppe_l1_e_drr_ll_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_e_drr_ll_tbl_u *value); + +sw_error_t +hppe_l1_e_drr_reverse_ll_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_e_drr_reverse_ll_tbl_u *value); + +sw_error_t +hppe_l1_e_drr_reverse_ll_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_e_drr_reverse_ll_tbl_u *value); + +sw_error_t +hppe_l1_a_flow_entry_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_a_flow_entry_tbl_u *value); + +sw_error_t +hppe_l1_a_flow_entry_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_a_flow_entry_tbl_u *value); + +sw_error_t +hppe_l1_b_flow_entry_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_b_flow_entry_tbl_u *value); + +sw_error_t +hppe_l1_b_flow_entry_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_b_flow_entry_tbl_u *value); + +sw_error_t +hppe_l1_sp_entry_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_sp_entry_tbl_u *value); + +sw_error_t +hppe_l1_sp_entry_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_sp_entry_tbl_u *value); + +sw_error_t +hppe_l1_ens_q_ll_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_ens_q_ll_tbl_u *value); + +sw_error_t +hppe_l1_ens_q_ll_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_ens_q_ll_tbl_u *value); + +sw_error_t +hppe_l1_ens_q_head_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_ens_q_head_tbl_u *value); + +sw_error_t +hppe_l1_ens_q_head_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_ens_q_head_tbl_u *value); + +sw_error_t +hppe_l1_ens_q_entry_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_ens_q_entry_tbl_u *value); + +sw_error_t +hppe_l1_ens_q_entry_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_ens_q_entry_tbl_u *value); + +sw_error_t +hppe_l1_flow_status_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_flow_status_tbl_u *value); + +sw_error_t +hppe_l1_flow_status_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_flow_status_tbl_u *value); + +sw_error_t +hppe_psch_tdm_cfg_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union psch_tdm_cfg_tbl_u *value); + +sw_error_t +hppe_psch_tdm_cfg_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union psch_tdm_cfg_tbl_u *value); + +sw_error_t +hppe_tdm_depth_cfg_tdm_depth_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_tdm_depth_cfg_tdm_depth_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_min_max_mode_cfg_min_max_mode_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_min_max_mode_cfg_min_max_mode_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_tm_dbg_addr_dbg_addr_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_tm_dbg_addr_dbg_addr_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_tm_dbg_data_dbg_data_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_tm_dbg_data_dbg_data_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_eco_reserve_0_eco_res_0_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_eco_reserve_0_eco_res_0_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_eco_reserve_1_eco_res_1_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_eco_reserve_1_eco_res_1_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l0_flow_map_tbl_e_pri_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_flow_map_tbl_e_pri_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_flow_map_tbl_c_pri_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_flow_map_tbl_c_pri_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_flow_map_tbl_e_drr_wt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_flow_map_tbl_e_drr_wt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_flow_map_tbl_c_drr_wt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_flow_map_tbl_c_drr_wt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_flow_map_tbl_sp_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_flow_map_tbl_sp_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_c_sp_cfg_tbl_drr_credit_unit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_c_sp_cfg_tbl_drr_credit_unit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_c_sp_cfg_tbl_drr_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_c_sp_cfg_tbl_drr_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_e_sp_cfg_tbl_drr_credit_unit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_e_sp_cfg_tbl_drr_credit_unit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_e_sp_cfg_tbl_drr_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_e_sp_cfg_tbl_drr_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_flow_port_map_tbl_port_num_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_flow_port_map_tbl_port_num_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_c_drr_head_tbl_backup_head_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_c_drr_head_tbl_backup_head_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_c_drr_head_tbl_active_vld_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_c_drr_head_tbl_active_vld_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_c_drr_head_tbl_backup_max_n_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_c_drr_head_tbl_backup_max_n_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_c_drr_head_tbl_active_tail_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_c_drr_head_tbl_active_tail_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_c_drr_head_tbl_active_head_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_c_drr_head_tbl_active_head_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_c_drr_head_tbl_backup_vld_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_c_drr_head_tbl_backup_vld_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_c_drr_head_tbl_active_max_n_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_c_drr_head_tbl_active_max_n_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_c_drr_head_tbl_backup_tail_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_c_drr_head_tbl_backup_tail_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_e_drr_head_tbl_backup_head_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_e_drr_head_tbl_backup_head_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_e_drr_head_tbl_active_vld_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_e_drr_head_tbl_active_vld_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_e_drr_head_tbl_backup_max_n_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_e_drr_head_tbl_backup_max_n_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_e_drr_head_tbl_active_tail_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_e_drr_head_tbl_active_tail_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_e_drr_head_tbl_active_head_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_e_drr_head_tbl_active_head_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_e_drr_head_tbl_backup_vld_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_e_drr_head_tbl_backup_vld_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_e_drr_head_tbl_active_max_n_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_e_drr_head_tbl_active_max_n_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_e_drr_head_tbl_backup_tail_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_e_drr_head_tbl_backup_tail_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_drr_credit_tbl_e_drr_credit_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_drr_credit_tbl_e_drr_credit_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_drr_credit_tbl_c_drr_credit_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_drr_credit_tbl_c_drr_credit_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_drr_credit_tbl_c_drr_credit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_drr_credit_tbl_c_drr_credit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_drr_credit_tbl_e_drr_credit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_drr_credit_tbl_e_drr_credit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_c_drr_ll_tbl_next_ptr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_c_drr_ll_tbl_next_ptr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_c_drr_reverse_ll_tbl_pre_ptr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_c_drr_reverse_ll_tbl_pre_ptr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_e_drr_ll_tbl_next_ptr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_e_drr_ll_tbl_next_ptr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_e_drr_reverse_ll_tbl_pre_ptr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_e_drr_reverse_ll_tbl_pre_ptr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_sp_entry_tbl_entry_vld_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_sp_entry_tbl_entry_vld_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_sp_entry_tbl_entry_path_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_l0_sp_entry_tbl_entry_path_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_l0_ens_q_ll_tbl_next_ptr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_ens_q_ll_tbl_next_ptr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_ens_q_head_tbl_vld_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_ens_q_head_tbl_vld_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_ens_q_head_tbl_head_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_ens_q_head_tbl_head_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_ens_q_head_tbl_tail_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_ens_q_head_tbl_tail_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_ens_q_entry_tbl_entry_ens_in_q_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_ens_q_entry_tbl_entry_ens_in_q_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_ens_q_entry_tbl_entry_ens_vld_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_ens_q_entry_tbl_entry_ens_vld_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_ens_q_entry_tbl_entry_ens_type_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_ens_q_entry_tbl_entry_ens_type_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_flow_status_tbl_en_cdrr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_flow_status_tbl_en_cdrr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_flow_status_tbl_en_edrr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_flow_status_tbl_en_edrr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_flow_status_tbl_en_level_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_flow_status_tbl_en_level_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ring_q_map_tbl_queue_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_ring_q_map_tbl_queue_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_rfc_block_tbl_rfc_block_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rfc_block_tbl_rfc_block_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rfc_status_tbl_rfc_status_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rfc_status_tbl_rfc_status_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_deq_dis_tbl_deq_dis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_deq_dis_tbl_deq_dis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_flow_map_tbl_e_pri_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_flow_map_tbl_e_pri_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_flow_map_tbl_c_pri_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_flow_map_tbl_c_pri_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_flow_map_tbl_e_drr_wt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_flow_map_tbl_e_drr_wt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_flow_map_tbl_c_drr_wt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_flow_map_tbl_c_drr_wt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_flow_map_tbl_sp_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_flow_map_tbl_sp_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_c_sp_cfg_tbl_drr_credit_unit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_c_sp_cfg_tbl_drr_credit_unit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_c_sp_cfg_tbl_drr_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_c_sp_cfg_tbl_drr_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_e_sp_cfg_tbl_drr_credit_unit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_e_sp_cfg_tbl_drr_credit_unit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_e_sp_cfg_tbl_drr_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_e_sp_cfg_tbl_drr_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_flow_port_map_tbl_port_num_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_flow_port_map_tbl_port_num_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_c_drr_head_tbl_backup_head_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_c_drr_head_tbl_backup_head_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_c_drr_head_tbl_active_vld_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_c_drr_head_tbl_active_vld_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_c_drr_head_tbl_backup_max_n_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_c_drr_head_tbl_backup_max_n_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_c_drr_head_tbl_active_tail_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_c_drr_head_tbl_active_tail_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_c_drr_head_tbl_active_head_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_c_drr_head_tbl_active_head_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_c_drr_head_tbl_backup_vld_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_c_drr_head_tbl_backup_vld_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_c_drr_head_tbl_active_max_n_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_c_drr_head_tbl_active_max_n_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_c_drr_head_tbl_backup_tail_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_c_drr_head_tbl_backup_tail_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_e_drr_head_tbl_backup_head_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_e_drr_head_tbl_backup_head_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_e_drr_head_tbl_active_vld_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_e_drr_head_tbl_active_vld_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_e_drr_head_tbl_backup_max_n_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_e_drr_head_tbl_backup_max_n_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_e_drr_head_tbl_active_tail_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_e_drr_head_tbl_active_tail_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_e_drr_head_tbl_active_head_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_e_drr_head_tbl_active_head_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_e_drr_head_tbl_backup_vld_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_e_drr_head_tbl_backup_vld_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_e_drr_head_tbl_active_max_n_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_e_drr_head_tbl_active_max_n_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_e_drr_head_tbl_backup_tail_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_e_drr_head_tbl_backup_tail_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_drr_credit_tbl_e_drr_credit_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_drr_credit_tbl_e_drr_credit_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_drr_credit_tbl_c_drr_credit_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_drr_credit_tbl_c_drr_credit_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_drr_credit_tbl_c_drr_credit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_drr_credit_tbl_c_drr_credit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_drr_credit_tbl_e_drr_credit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_drr_credit_tbl_e_drr_credit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_c_drr_ll_tbl_next_ptr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_c_drr_ll_tbl_next_ptr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_c_drr_reverse_ll_tbl_pre_ptr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_c_drr_reverse_ll_tbl_pre_ptr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_e_drr_ll_tbl_next_ptr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_e_drr_ll_tbl_next_ptr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_e_drr_reverse_ll_tbl_pre_ptr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_e_drr_reverse_ll_tbl_pre_ptr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_a_flow_entry_tbl_entry_path_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_a_flow_entry_tbl_entry_path_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_b_flow_entry_tbl_entry_path_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_b_flow_entry_tbl_entry_path_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_sp_entry_tbl_entry_vld_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_sp_entry_tbl_entry_vld_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_sp_entry_tbl_entry_path_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_l1_sp_entry_tbl_entry_path_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_l1_ens_q_ll_tbl_next_ptr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_ens_q_ll_tbl_next_ptr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_ens_q_head_tbl_vld_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_ens_q_head_tbl_vld_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_ens_q_head_tbl_head_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_ens_q_head_tbl_head_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_ens_q_head_tbl_tail_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_ens_q_head_tbl_tail_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_ens_q_entry_tbl_entry_ens_in_q_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_ens_q_entry_tbl_entry_ens_in_q_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_ens_q_entry_tbl_entry_ens_vld_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_ens_q_entry_tbl_entry_ens_vld_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_ens_q_entry_tbl_entry_ens_type_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_ens_q_entry_tbl_entry_ens_type_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_flow_status_tbl_en_cdrr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_flow_status_tbl_en_cdrr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_flow_status_tbl_en_edrr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_flow_status_tbl_en_edrr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_flow_status_tbl_en_level_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_flow_status_tbl_en_level_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_psch_tdm_cfg_tbl_ens_port_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_psch_tdm_cfg_tbl_ens_port_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_psch_tdm_cfg_tbl_des_port_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_psch_tdm_cfg_tbl_des_port_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_psch_tdm_cfg_tbl_ens_port_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_psch_tdm_cfg_tbl_ens_port_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_qos_ctrl_port_flow_qos_pri_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_qos_ctrl_port_flow_qos_pri_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_qos_ctrl_port_dscp_qos_pri_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_qos_ctrl_port_dscp_qos_pri_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_qos_ctrl_port_dscp_change_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_qos_ctrl_port_dscp_change_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_qos_ctrl_port_pcp_change_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_qos_ctrl_port_pcp_change_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_qos_ctrl_port_acl_qos_pri_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_qos_ctrl_port_acl_qos_pri_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_qos_ctrl_flow_qos_group_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_qos_ctrl_flow_qos_group_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_qos_ctrl_port_preheader_qos_pri_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_qos_ctrl_port_preheader_qos_pri_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_qos_ctrl_pcp_qos_group_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_qos_ctrl_pcp_qos_group_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_qos_ctrl_dscp_qos_group_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_qos_ctrl_dscp_qos_group_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_qos_ctrl_port_pcp_qos_pri_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_qos_ctrl_port_pcp_qos_pri_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_qos_ctrl_port_dei_change_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_qos_ctrl_port_dei_change_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pcp_qos_group_0_qos_info_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pcp_qos_group_0_qos_info_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pcp_qos_group_1_qos_info_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pcp_qos_group_1_qos_info_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_flow_qos_group_0_qos_info_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_flow_qos_group_0_qos_info_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_flow_qos_group_1_qos_info_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_flow_qos_group_1_qos_info_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_dscp_qos_group_0_qos_info_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_dscp_qos_group_0_qos_info_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_dscp_qos_group_1_qos_info_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_dscp_qos_group_1_qos_info_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + + +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_qos_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_qos_reg.h new file mode 100755 index 000000000..59decb6d5 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_qos_reg.h @@ -0,0 +1,1676 @@ +/* + * 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 + * @{ + */ +#ifndef HPPE_QOS_REG_H +#define HPPE_QOS_REG_H + +/*[register] TDM_DEPTH_CFG*/ +#define TDM_DEPTH_CFG +#define TDM_DEPTH_CFG_ADDRESS 0x0 +#define TDM_DEPTH_CFG_NUM 1 +#define TDM_DEPTH_CFG_INC 0x4 +#define TDM_DEPTH_CFG_TYPE REG_TYPE_RW +#define TDM_DEPTH_CFG_DEFAULT 0x28 + /*[field] TDM_DEPTH*/ + #define TDM_DEPTH_CFG_TDM_DEPTH + #define TDM_DEPTH_CFG_TDM_DEPTH_OFFSET 0 + #define TDM_DEPTH_CFG_TDM_DEPTH_LEN 8 + #define TDM_DEPTH_CFG_TDM_DEPTH_DEFAULT 0x28 + +struct tdm_depth_cfg { + a_uint32_t tdm_depth:8; + a_uint32_t _reserved0:24; +}; + +union tdm_depth_cfg_u { + a_uint32_t val; + struct tdm_depth_cfg bf; +}; + +/*[register] MIN_MAX_MODE_CFG*/ +#define MIN_MAX_MODE_CFG +#define MIN_MAX_MODE_CFG_ADDRESS 0x4 +#define MIN_MAX_MODE_CFG_NUM 1 +#define MIN_MAX_MODE_CFG_INC 0x4 +#define MIN_MAX_MODE_CFG_TYPE REG_TYPE_RW +#define MIN_MAX_MODE_CFG_DEFAULT 0x0 + /*[field] MIN_MAX_MODE*/ + #define MIN_MAX_MODE_CFG_MIN_MAX_MODE + #define MIN_MAX_MODE_CFG_MIN_MAX_MODE_OFFSET 0 + #define MIN_MAX_MODE_CFG_MIN_MAX_MODE_LEN 1 + #define MIN_MAX_MODE_CFG_MIN_MAX_MODE_DEFAULT 0x0 + +struct min_max_mode_cfg { + a_uint32_t min_max_mode:1; + a_uint32_t _reserved0:31; +}; + +union min_max_mode_cfg_u { + a_uint32_t val; + struct min_max_mode_cfg bf; +}; + + +/*[register] TM_DBG_ADDR*/ +#define TM_DBG_ADDR +#define TM_DBG_ADDR_ADDRESS 0x20 +#define TM_DBG_ADDR_NUM 1 +#define TM_DBG_ADDR_INC 0x4 +#define TM_DBG_ADDR_TYPE REG_TYPE_RW +#define TM_DBG_ADDR_DEFAULT 0x0 + /*[field] DBG_ADDR*/ + #define TM_DBG_ADDR_DBG_ADDR + #define TM_DBG_ADDR_DBG_ADDR_OFFSET 0 + #define TM_DBG_ADDR_DBG_ADDR_LEN 8 + #define TM_DBG_ADDR_DBG_ADDR_DEFAULT 0x0 + +struct tm_dbg_addr { + a_uint32_t dbg_addr:8; + a_uint32_t _reserved0:24; +}; + +union tm_dbg_addr_u { + a_uint32_t val; + struct tm_dbg_addr bf; +}; + +/*[register] TM_DBG_DATA*/ +#define TM_DBG_DATA +#define TM_DBG_DATA_ADDRESS 0x24 +#define TM_DBG_DATA_NUM 1 +#define TM_DBG_DATA_INC 0x4 +#define TM_DBG_DATA_TYPE REG_TYPE_RO +#define TM_DBG_DATA_DEFAULT 0x0 + /*[field] DBG_DATA*/ + #define TM_DBG_DATA_DBG_DATA + #define TM_DBG_DATA_DBG_DATA_OFFSET 0 + #define TM_DBG_DATA_DBG_DATA_LEN 32 + #define TM_DBG_DATA_DBG_DATA_DEFAULT 0x0 + +struct tm_dbg_data { + a_uint32_t dbg_data:32; +}; + +union tm_dbg_data_u { + a_uint32_t val; + struct tm_dbg_data bf; +}; + +/*[register] ECO_RESERVE_0*/ +#define ECO_RESERVE_0 +#define ECO_RESERVE_0_ADDRESS 0x28 +#define ECO_RESERVE_0_NUM 1 +#define ECO_RESERVE_0_INC 0x4 +#define ECO_RESERVE_0_TYPE REG_TYPE_RW +#define ECO_RESERVE_0_DEFAULT 0x0 + /*[field] ECO_RES_0*/ + #define ECO_RESERVE_0_ECO_RES_0 + #define ECO_RESERVE_0_ECO_RES_0_OFFSET 0 + #define ECO_RESERVE_0_ECO_RES_0_LEN 32 + #define ECO_RESERVE_0_ECO_RES_0_DEFAULT 0x0 + +struct eco_reserve_0 { + a_uint32_t eco_res_0:32; +}; + +union eco_reserve_0_u { + a_uint32_t val; + struct eco_reserve_0 bf; +}; + +/*[register] ECO_RESERVE_1*/ +#define ECO_RESERVE_1 +#define ECO_RESERVE_1_ADDRESS 0x2c +#define ECO_RESERVE_1_NUM 1 +#define ECO_RESERVE_1_INC 0x4 +#define ECO_RESERVE_1_TYPE REG_TYPE_RW +#define ECO_RESERVE_1_DEFAULT 0x0 + /*[field] ECO_RES_1*/ + #define ECO_RESERVE_1_ECO_RES_1 + #define ECO_RESERVE_1_ECO_RES_1_OFFSET 0 + #define ECO_RESERVE_1_ECO_RES_1_LEN 32 + #define ECO_RESERVE_1_ECO_RES_1_DEFAULT 0x0 + +struct eco_reserve_1 { + a_uint32_t eco_res_1:32; +}; + +union eco_reserve_1_u { + a_uint32_t val; + struct eco_reserve_1 bf; +}; + +/*[table] L0_FLOW_MAP_TBL*/ +#define L0_FLOW_MAP_TBL +#define L0_FLOW_MAP_TBL_ADDRESS 0x2000 +#define L0_FLOW_MAP_TBL_NUM 300 +#define L0_FLOW_MAP_TBL_INC 0x10 +#define L0_FLOW_MAP_TBL_TYPE REG_TYPE_RW +#define L0_FLOW_MAP_TBL_DEFAULT 0x0 + /*[field] SP_ID*/ + #define L0_FLOW_MAP_TBL_SP_ID + #define L0_FLOW_MAP_TBL_SP_ID_OFFSET 0 + #define L0_FLOW_MAP_TBL_SP_ID_LEN 6 + #define L0_FLOW_MAP_TBL_SP_ID_DEFAULT 0x0 + /*[field] C_PRI*/ + #define L0_FLOW_MAP_TBL_C_PRI + #define L0_FLOW_MAP_TBL_C_PRI_OFFSET 6 + #define L0_FLOW_MAP_TBL_C_PRI_LEN 3 + #define L0_FLOW_MAP_TBL_C_PRI_DEFAULT 0x0 + /*[field] E_PRI*/ + #define L0_FLOW_MAP_TBL_E_PRI + #define L0_FLOW_MAP_TBL_E_PRI_OFFSET 9 + #define L0_FLOW_MAP_TBL_E_PRI_LEN 3 + #define L0_FLOW_MAP_TBL_E_PRI_DEFAULT 0x0 + /*[field] C_DRR_WT*/ + #define L0_FLOW_MAP_TBL_C_DRR_WT + #define L0_FLOW_MAP_TBL_C_DRR_WT_OFFSET 12 + #define L0_FLOW_MAP_TBL_C_DRR_WT_LEN 10 + #define L0_FLOW_MAP_TBL_C_DRR_WT_DEFAULT 0x0 + /*[field] E_DRR_WT*/ + #define L0_FLOW_MAP_TBL_E_DRR_WT + #define L0_FLOW_MAP_TBL_E_DRR_WT_OFFSET 22 + #define L0_FLOW_MAP_TBL_E_DRR_WT_LEN 10 + #define L0_FLOW_MAP_TBL_E_DRR_WT_DEFAULT 0x0 + +struct l0_flow_map_tbl { + a_uint32_t sp_id:6; + a_uint32_t c_pri:3; + a_uint32_t e_pri:3; + a_uint32_t c_drr_wt:10; + a_uint32_t e_drr_wt:10; +}; + +union l0_flow_map_tbl_u { + a_uint32_t val; + struct l0_flow_map_tbl bf; +}; + +/*[table] L0_C_SP_CFG_TBL*/ +#define L0_C_SP_CFG_TBL +#define L0_C_SP_CFG_TBL_ADDRESS 0x4000 +#define L0_C_SP_CFG_TBL_NUM 512 +#define L0_C_SP_CFG_TBL_INC 0x10 +#define L0_C_SP_CFG_TBL_TYPE REG_TYPE_RW +#define L0_C_SP_CFG_TBL_DEFAULT 0x0 + /*[field] DRR_ID*/ + #define L0_C_SP_CFG_TBL_DRR_ID + #define L0_C_SP_CFG_TBL_DRR_ID_OFFSET 0 + #define L0_C_SP_CFG_TBL_DRR_ID_LEN 8 + #define L0_C_SP_CFG_TBL_DRR_ID_DEFAULT 0x0 + /*[field] DRR_CREDIT_UNIT*/ + #define L0_C_SP_CFG_TBL_DRR_CREDIT_UNIT + #define L0_C_SP_CFG_TBL_DRR_CREDIT_UNIT_OFFSET 8 + #define L0_C_SP_CFG_TBL_DRR_CREDIT_UNIT_LEN 1 + #define L0_C_SP_CFG_TBL_DRR_CREDIT_UNIT_DEFAULT 0x0 + +struct l0_c_sp_cfg_tbl { + a_uint32_t drr_id:8; + a_uint32_t drr_credit_unit:1; + a_uint32_t _reserved0:23; +}; + +union l0_c_sp_cfg_tbl_u { + a_uint32_t val; + struct l0_c_sp_cfg_tbl bf; +}; + +/*[table] L0_E_SP_CFG_TBL*/ +#define L0_E_SP_CFG_TBL +#define L0_E_SP_CFG_TBL_ADDRESS 0x6000 +#define L0_E_SP_CFG_TBL_NUM 512 +#define L0_E_SP_CFG_TBL_INC 0x10 +#define L0_E_SP_CFG_TBL_TYPE REG_TYPE_RW +#define L0_E_SP_CFG_TBL_DEFAULT 0x0 + /*[field] DRR_ID*/ + #define L0_E_SP_CFG_TBL_DRR_ID + #define L0_E_SP_CFG_TBL_DRR_ID_OFFSET 0 + #define L0_E_SP_CFG_TBL_DRR_ID_LEN 8 + #define L0_E_SP_CFG_TBL_DRR_ID_DEFAULT 0x0 + /*[field] DRR_CREDIT_UNIT*/ + #define L0_E_SP_CFG_TBL_DRR_CREDIT_UNIT + #define L0_E_SP_CFG_TBL_DRR_CREDIT_UNIT_OFFSET 8 + #define L0_E_SP_CFG_TBL_DRR_CREDIT_UNIT_LEN 1 + #define L0_E_SP_CFG_TBL_DRR_CREDIT_UNIT_DEFAULT 0x0 + +struct l0_e_sp_cfg_tbl { + a_uint32_t drr_id:8; + a_uint32_t drr_credit_unit:1; + a_uint32_t _reserved0:23; +}; + +union l0_e_sp_cfg_tbl_u { + a_uint32_t val; + struct l0_e_sp_cfg_tbl bf; +}; + +/*[table] L0_FLOW_PORT_MAP_TBL*/ +#define L0_FLOW_PORT_MAP_TBL +#define L0_FLOW_PORT_MAP_TBL_ADDRESS 0x8000 +#define L0_FLOW_PORT_MAP_TBL_NUM 300 +#define L0_FLOW_PORT_MAP_TBL_INC 0x10 +#define L0_FLOW_PORT_MAP_TBL_TYPE REG_TYPE_RW +#define L0_FLOW_PORT_MAP_TBL_DEFAULT 0x0 + /*[field] PORT_NUM*/ + #define L0_FLOW_PORT_MAP_TBL_PORT_NUM + #define L0_FLOW_PORT_MAP_TBL_PORT_NUM_OFFSET 0 + #define L0_FLOW_PORT_MAP_TBL_PORT_NUM_LEN 4 + #define L0_FLOW_PORT_MAP_TBL_PORT_NUM_DEFAULT 0x0 + +struct l0_flow_port_map_tbl { + a_uint32_t port_num:4; + a_uint32_t _reserved0:28; +}; + +union l0_flow_port_map_tbl_u { + a_uint32_t val; + struct l0_flow_port_map_tbl bf; +}; + +/*[table] L0_C_DRR_HEAD_TBL*/ +#define L0_C_DRR_HEAD_TBL +#define L0_C_DRR_HEAD_TBL_ADDRESS 0xa000 +#define L0_C_DRR_HEAD_TBL_NUM 160 +#define L0_C_DRR_HEAD_TBL_INC 0x10 +#define L0_C_DRR_HEAD_TBL_TYPE REG_TYPE_RO +#define L0_C_DRR_HEAD_TBL_DEFAULT 0x0 + /*[field] BACKUP_TAIL*/ + #define L0_C_DRR_HEAD_TBL_BACKUP_TAIL + #define L0_C_DRR_HEAD_TBL_BACKUP_TAIL_OFFSET 0 + #define L0_C_DRR_HEAD_TBL_BACKUP_TAIL_LEN 9 + #define L0_C_DRR_HEAD_TBL_BACKUP_TAIL_DEFAULT 0x0 + /*[field] BACKUP_HEAD*/ + #define L0_C_DRR_HEAD_TBL_BACKUP_HEAD + #define L0_C_DRR_HEAD_TBL_BACKUP_HEAD_OFFSET 9 + #define L0_C_DRR_HEAD_TBL_BACKUP_HEAD_LEN 9 + #define L0_C_DRR_HEAD_TBL_BACKUP_HEAD_DEFAULT 0x0 + /*[field] BACKUP_VLD*/ + #define L0_C_DRR_HEAD_TBL_BACKUP_VLD + #define L0_C_DRR_HEAD_TBL_BACKUP_VLD_OFFSET 18 + #define L0_C_DRR_HEAD_TBL_BACKUP_VLD_LEN 1 + #define L0_C_DRR_HEAD_TBL_BACKUP_VLD_DEFAULT 0x0 + /*[field] BACKUP_MAX_N*/ + #define L0_C_DRR_HEAD_TBL_BACKUP_MAX_N + #define L0_C_DRR_HEAD_TBL_BACKUP_MAX_N_OFFSET 19 + #define L0_C_DRR_HEAD_TBL_BACKUP_MAX_N_LEN 5 + #define L0_C_DRR_HEAD_TBL_BACKUP_MAX_N_DEFAULT 0x0 + /*[field] ACTIVE_TAIL*/ + #define L0_C_DRR_HEAD_TBL_ACTIVE_TAIL + #define L0_C_DRR_HEAD_TBL_ACTIVE_TAIL_OFFSET 24 + #define L0_C_DRR_HEAD_TBL_ACTIVE_TAIL_LEN 9 + #define L0_C_DRR_HEAD_TBL_ACTIVE_TAIL_DEFAULT 0x0 + /*[field] ACTIVE_HEAD*/ + #define L0_C_DRR_HEAD_TBL_ACTIVE_HEAD + #define L0_C_DRR_HEAD_TBL_ACTIVE_HEAD_OFFSET 33 + #define L0_C_DRR_HEAD_TBL_ACTIVE_HEAD_LEN 9 + #define L0_C_DRR_HEAD_TBL_ACTIVE_HEAD_DEFAULT 0x0 + /*[field] ACTIVE_VLD*/ + #define L0_C_DRR_HEAD_TBL_ACTIVE_VLD + #define L0_C_DRR_HEAD_TBL_ACTIVE_VLD_OFFSET 42 + #define L0_C_DRR_HEAD_TBL_ACTIVE_VLD_LEN 1 + #define L0_C_DRR_HEAD_TBL_ACTIVE_VLD_DEFAULT 0x0 + /*[field] ACTIVE_MAX_N*/ + #define L0_C_DRR_HEAD_TBL_ACTIVE_MAX_N + #define L0_C_DRR_HEAD_TBL_ACTIVE_MAX_N_OFFSET 43 + #define L0_C_DRR_HEAD_TBL_ACTIVE_MAX_N_LEN 5 + #define L0_C_DRR_HEAD_TBL_ACTIVE_MAX_N_DEFAULT 0x0 + +struct l0_c_drr_head_tbl { + a_uint32_t backup_tail:9; + a_uint32_t backup_head:9; + a_uint32_t backup_vld:1; + a_uint32_t backup_max_n:5; + a_uint32_t active_tail_0:8; + a_uint32_t active_tail_1:1; + a_uint32_t active_head:9; + a_uint32_t active_vld:1; + a_uint32_t active_max_n:5; + a_uint32_t _reserved0:16; +}; + +union l0_c_drr_head_tbl_u { + a_uint32_t val[2]; + struct l0_c_drr_head_tbl bf; +}; + +/*[table] L0_E_DRR_HEAD_TBL*/ +#define L0_E_DRR_HEAD_TBL +#define L0_E_DRR_HEAD_TBL_ADDRESS 0xc000 +#define L0_E_DRR_HEAD_TBL_NUM 160 +#define L0_E_DRR_HEAD_TBL_INC 0x10 +#define L0_E_DRR_HEAD_TBL_TYPE REG_TYPE_RO +#define L0_E_DRR_HEAD_TBL_DEFAULT 0x0 + /*[field] BACKUP_TAIL*/ + #define L0_E_DRR_HEAD_TBL_BACKUP_TAIL + #define L0_E_DRR_HEAD_TBL_BACKUP_TAIL_OFFSET 0 + #define L0_E_DRR_HEAD_TBL_BACKUP_TAIL_LEN 9 + #define L0_E_DRR_HEAD_TBL_BACKUP_TAIL_DEFAULT 0x0 + /*[field] BACKUP_HEAD*/ + #define L0_E_DRR_HEAD_TBL_BACKUP_HEAD + #define L0_E_DRR_HEAD_TBL_BACKUP_HEAD_OFFSET 9 + #define L0_E_DRR_HEAD_TBL_BACKUP_HEAD_LEN 9 + #define L0_E_DRR_HEAD_TBL_BACKUP_HEAD_DEFAULT 0x0 + /*[field] BACKUP_VLD*/ + #define L0_E_DRR_HEAD_TBL_BACKUP_VLD + #define L0_E_DRR_HEAD_TBL_BACKUP_VLD_OFFSET 18 + #define L0_E_DRR_HEAD_TBL_BACKUP_VLD_LEN 1 + #define L0_E_DRR_HEAD_TBL_BACKUP_VLD_DEFAULT 0x0 + /*[field] BACKUP_MAX_N*/ + #define L0_E_DRR_HEAD_TBL_BACKUP_MAX_N + #define L0_E_DRR_HEAD_TBL_BACKUP_MAX_N_OFFSET 19 + #define L0_E_DRR_HEAD_TBL_BACKUP_MAX_N_LEN 5 + #define L0_E_DRR_HEAD_TBL_BACKUP_MAX_N_DEFAULT 0x0 + /*[field] ACTIVE_TAIL*/ + #define L0_E_DRR_HEAD_TBL_ACTIVE_TAIL + #define L0_E_DRR_HEAD_TBL_ACTIVE_TAIL_OFFSET 24 + #define L0_E_DRR_HEAD_TBL_ACTIVE_TAIL_LEN 9 + #define L0_E_DRR_HEAD_TBL_ACTIVE_TAIL_DEFAULT 0x0 + /*[field] ACTIVE_HEAD*/ + #define L0_E_DRR_HEAD_TBL_ACTIVE_HEAD + #define L0_E_DRR_HEAD_TBL_ACTIVE_HEAD_OFFSET 33 + #define L0_E_DRR_HEAD_TBL_ACTIVE_HEAD_LEN 9 + #define L0_E_DRR_HEAD_TBL_ACTIVE_HEAD_DEFAULT 0x0 + /*[field] ACTIVE_VLD*/ + #define L0_E_DRR_HEAD_TBL_ACTIVE_VLD + #define L0_E_DRR_HEAD_TBL_ACTIVE_VLD_OFFSET 42 + #define L0_E_DRR_HEAD_TBL_ACTIVE_VLD_LEN 1 + #define L0_E_DRR_HEAD_TBL_ACTIVE_VLD_DEFAULT 0x0 + /*[field] ACTIVE_MAX_N*/ + #define L0_E_DRR_HEAD_TBL_ACTIVE_MAX_N + #define L0_E_DRR_HEAD_TBL_ACTIVE_MAX_N_OFFSET 43 + #define L0_E_DRR_HEAD_TBL_ACTIVE_MAX_N_LEN 5 + #define L0_E_DRR_HEAD_TBL_ACTIVE_MAX_N_DEFAULT 0x0 + +struct l0_e_drr_head_tbl { + a_uint32_t backup_tail:9; + a_uint32_t backup_head:9; + a_uint32_t backup_vld:1; + a_uint32_t backup_max_n:5; + a_uint32_t active_tail_0:8; + a_uint32_t active_tail_1:1; + a_uint32_t active_head:9; + a_uint32_t active_vld:1; + a_uint32_t active_max_n:5; + a_uint32_t _reserved0:16; +}; + +union l0_e_drr_head_tbl_u { + a_uint32_t val[2]; + struct l0_e_drr_head_tbl bf; +}; + +/*[table] L0_DRR_CREDIT_TBL*/ +#define L0_DRR_CREDIT_TBL +#define L0_DRR_CREDIT_TBL_ADDRESS 0xe000 +#define L0_DRR_CREDIT_TBL_NUM 300 +#define L0_DRR_CREDIT_TBL_INC 0x10 +#define L0_DRR_CREDIT_TBL_TYPE REG_TYPE_RO +#define L0_DRR_CREDIT_TBL_DEFAULT 0x0 + /*[field] C_DRR_CREDIT*/ + #define L0_DRR_CREDIT_TBL_C_DRR_CREDIT + #define L0_DRR_CREDIT_TBL_C_DRR_CREDIT_OFFSET 0 + #define L0_DRR_CREDIT_TBL_C_DRR_CREDIT_LEN 24 + #define L0_DRR_CREDIT_TBL_C_DRR_CREDIT_DEFAULT 0x0 + /*[field] C_DRR_CREDIT_NEG*/ + #define L0_DRR_CREDIT_TBL_C_DRR_CREDIT_NEG + #define L0_DRR_CREDIT_TBL_C_DRR_CREDIT_NEG_OFFSET 24 + #define L0_DRR_CREDIT_TBL_C_DRR_CREDIT_NEG_LEN 1 + #define L0_DRR_CREDIT_TBL_C_DRR_CREDIT_NEG_DEFAULT 0x0 + /*[field] E_DRR_CREDIT*/ + #define L0_DRR_CREDIT_TBL_E_DRR_CREDIT + #define L0_DRR_CREDIT_TBL_E_DRR_CREDIT_OFFSET 25 + #define L0_DRR_CREDIT_TBL_E_DRR_CREDIT_LEN 24 + #define L0_DRR_CREDIT_TBL_E_DRR_CREDIT_DEFAULT 0x0 + /*[field] E_DRR_CREDIT_NEG*/ + #define L0_DRR_CREDIT_TBL_E_DRR_CREDIT_NEG + #define L0_DRR_CREDIT_TBL_E_DRR_CREDIT_NEG_OFFSET 49 + #define L0_DRR_CREDIT_TBL_E_DRR_CREDIT_NEG_LEN 1 + #define L0_DRR_CREDIT_TBL_E_DRR_CREDIT_NEG_DEFAULT 0x0 + +struct l0_drr_credit_tbl { + a_uint32_t c_drr_credit:24; + a_uint32_t c_drr_credit_neg:1; + a_uint32_t e_drr_credit_0:7; + a_uint32_t e_drr_credit_1:17; + a_uint32_t e_drr_credit_neg:1; + a_uint32_t _reserved0:14; +}; + +union l0_drr_credit_tbl_u { + a_uint32_t val[2]; + struct l0_drr_credit_tbl bf; +}; + +/*[table] L0_C_DRR_LL_TBL*/ +#define L0_C_DRR_LL_TBL +#define L0_C_DRR_LL_TBL_ADDRESS 0x10000 +#define L0_C_DRR_LL_TBL_NUM 300 +#define L0_C_DRR_LL_TBL_INC 0x10 +#define L0_C_DRR_LL_TBL_TYPE REG_TYPE_RO +#define L0_C_DRR_LL_TBL_DEFAULT 0x0 + /*[field] NEXT_PTR*/ + #define L0_C_DRR_LL_TBL_NEXT_PTR + #define L0_C_DRR_LL_TBL_NEXT_PTR_OFFSET 0 + #define L0_C_DRR_LL_TBL_NEXT_PTR_LEN 9 + #define L0_C_DRR_LL_TBL_NEXT_PTR_DEFAULT 0x0 + +struct l0_c_drr_ll_tbl { + a_uint32_t next_ptr:9; + a_uint32_t _reserved0:23; +}; + +union l0_c_drr_ll_tbl_u { + a_uint32_t val; + struct l0_c_drr_ll_tbl bf; +}; + +/*[table] L0_C_DRR_REVERSE_LL_TBL*/ +#define L0_C_DRR_REVERSE_LL_TBL +#define L0_C_DRR_REVERSE_LL_TBL_ADDRESS 0x12000 +#define L0_C_DRR_REVERSE_LL_TBL_NUM 300 +#define L0_C_DRR_REVERSE_LL_TBL_INC 0x10 +#define L0_C_DRR_REVERSE_LL_TBL_TYPE REG_TYPE_RO +#define L0_C_DRR_REVERSE_LL_TBL_DEFAULT 0x0 + /*[field] PRE_PTR*/ + #define L0_C_DRR_REVERSE_LL_TBL_PRE_PTR + #define L0_C_DRR_REVERSE_LL_TBL_PRE_PTR_OFFSET 0 + #define L0_C_DRR_REVERSE_LL_TBL_PRE_PTR_LEN 9 + #define L0_C_DRR_REVERSE_LL_TBL_PRE_PTR_DEFAULT 0x0 + +struct l0_c_drr_reverse_ll_tbl { + a_uint32_t pre_ptr:9; + a_uint32_t _reserved0:23; +}; + +union l0_c_drr_reverse_ll_tbl_u { + a_uint32_t val; + struct l0_c_drr_reverse_ll_tbl bf; +}; + +/*[table] L0_E_DRR_LL_TBL*/ +#define L0_E_DRR_LL_TBL +#define L0_E_DRR_LL_TBL_ADDRESS 0x14000 +#define L0_E_DRR_LL_TBL_NUM 300 +#define L0_E_DRR_LL_TBL_INC 0x10 +#define L0_E_DRR_LL_TBL_TYPE REG_TYPE_RO +#define L0_E_DRR_LL_TBL_DEFAULT 0x0 + /*[field] NEXT_PTR*/ + #define L0_E_DRR_LL_TBL_NEXT_PTR + #define L0_E_DRR_LL_TBL_NEXT_PTR_OFFSET 0 + #define L0_E_DRR_LL_TBL_NEXT_PTR_LEN 9 + #define L0_E_DRR_LL_TBL_NEXT_PTR_DEFAULT 0x0 + +struct l0_e_drr_ll_tbl { + a_uint32_t next_ptr:9; + a_uint32_t _reserved0:23; +}; + +union l0_e_drr_ll_tbl_u { + a_uint32_t val; + struct l0_e_drr_ll_tbl bf; +}; + +/*[table] L0_E_DRR_REVERSE_LL_TBL*/ +#define L0_E_DRR_REVERSE_LL_TBL +#define L0_E_DRR_REVERSE_LL_TBL_ADDRESS 0x16000 +#define L0_E_DRR_REVERSE_LL_TBL_NUM 300 +#define L0_E_DRR_REVERSE_LL_TBL_INC 0x10 +#define L0_E_DRR_REVERSE_LL_TBL_TYPE REG_TYPE_RO +#define L0_E_DRR_REVERSE_LL_TBL_DEFAULT 0x0 + /*[field] PRE_PTR*/ + #define L0_E_DRR_REVERSE_LL_TBL_PRE_PTR + #define L0_E_DRR_REVERSE_LL_TBL_PRE_PTR_OFFSET 0 + #define L0_E_DRR_REVERSE_LL_TBL_PRE_PTR_LEN 9 + #define L0_E_DRR_REVERSE_LL_TBL_PRE_PTR_DEFAULT 0x0 + +struct l0_e_drr_reverse_ll_tbl { + a_uint32_t pre_ptr:9; + a_uint32_t _reserved0:23; +}; + +union l0_e_drr_reverse_ll_tbl_u { + a_uint32_t val; + struct l0_e_drr_reverse_ll_tbl bf; +}; + +/*[table] L0_SP_ENTRY_TBL*/ +#define L0_SP_ENTRY_TBL +#define L0_SP_ENTRY_TBL_ADDRESS 0x18000 +#define L0_SP_ENTRY_TBL_NUM 64 +#define L0_SP_ENTRY_TBL_INC 0x20 +#define L0_SP_ENTRY_TBL_TYPE REG_TYPE_RO +#define L0_SP_ENTRY_TBL_DEFAULT 0x0 + /*[field] ENTRY_PATH_ID*/ + #define L0_SP_ENTRY_TBL_ENTRY_PATH_ID + #define L0_SP_ENTRY_TBL_ENTRY_PATH_ID_OFFSET 0 + #define L0_SP_ENTRY_TBL_ENTRY_PATH_ID_LEN 144 + #define L0_SP_ENTRY_TBL_ENTRY_PATH_ID_DEFAULT 0x0 + /*[field] ENTRY_VLD*/ + #define L0_SP_ENTRY_TBL_ENTRY_VLD + #define L0_SP_ENTRY_TBL_ENTRY_VLD_OFFSET 144 + #define L0_SP_ENTRY_TBL_ENTRY_VLD_LEN 16 + #define L0_SP_ENTRY_TBL_ENTRY_VLD_DEFAULT 0x0 + +struct l0_sp_entry_tbl { + a_uint32_t entry_path_id_0:32; + a_uint32_t entry_path_id_1:32; + a_uint32_t entry_path_id_2:32; + a_uint32_t entry_path_id_3:32; + a_uint32_t entry_path_id_4:16; + a_uint32_t entry_vld:16; +}; + +union l0_sp_entry_tbl_u { + a_uint32_t val[5]; + struct l0_sp_entry_tbl bf; +}; + + +/*[table] L0_ENS_Q_LL_TBL*/ +#define L0_ENS_Q_LL_TBL +#define L0_ENS_Q_LL_TBL_ADDRESS 0x1e000 +#define L0_ENS_Q_LL_TBL_NUM 300 +#define L0_ENS_Q_LL_TBL_INC 0x10 +#define L0_ENS_Q_LL_TBL_TYPE REG_TYPE_RO +#define L0_ENS_Q_LL_TBL_DEFAULT 0x0 + /*[field] NEXT_PTR*/ + #define L0_ENS_Q_LL_TBL_NEXT_PTR + #define L0_ENS_Q_LL_TBL_NEXT_PTR_OFFSET 0 + #define L0_ENS_Q_LL_TBL_NEXT_PTR_LEN 9 + #define L0_ENS_Q_LL_TBL_NEXT_PTR_DEFAULT 0x0 + +struct l0_ens_q_ll_tbl { + a_uint32_t next_ptr:9; + a_uint32_t _reserved0:23; +}; + +union l0_ens_q_ll_tbl_u { + a_uint32_t val; + struct l0_ens_q_ll_tbl bf; +}; + +/*[table] L0_ENS_Q_HEAD_TBL*/ +#define L0_ENS_Q_HEAD_TBL +#define L0_ENS_Q_HEAD_TBL_ADDRESS 0x20000 +#define L0_ENS_Q_HEAD_TBL_NUM 8 +#define L0_ENS_Q_HEAD_TBL_INC 0x10 +#define L0_ENS_Q_HEAD_TBL_TYPE REG_TYPE_RO +#define L0_ENS_Q_HEAD_TBL_DEFAULT 0x0 + /*[field] TAIL*/ + #define L0_ENS_Q_HEAD_TBL_TAIL + #define L0_ENS_Q_HEAD_TBL_TAIL_OFFSET 0 + #define L0_ENS_Q_HEAD_TBL_TAIL_LEN 9 + #define L0_ENS_Q_HEAD_TBL_TAIL_DEFAULT 0x0 + /*[field] HEAD*/ + #define L0_ENS_Q_HEAD_TBL_HEAD + #define L0_ENS_Q_HEAD_TBL_HEAD_OFFSET 9 + #define L0_ENS_Q_HEAD_TBL_HEAD_LEN 9 + #define L0_ENS_Q_HEAD_TBL_HEAD_DEFAULT 0x0 + /*[field] VLD*/ + #define L0_ENS_Q_HEAD_TBL_VLD + #define L0_ENS_Q_HEAD_TBL_VLD_OFFSET 18 + #define L0_ENS_Q_HEAD_TBL_VLD_LEN 1 + #define L0_ENS_Q_HEAD_TBL_VLD_DEFAULT 0x0 + +struct l0_ens_q_head_tbl { + a_uint32_t tail:9; + a_uint32_t head:9; + a_uint32_t vld:1; + a_uint32_t _reserved0:13; +}; + +union l0_ens_q_head_tbl_u { + a_uint32_t val; + struct l0_ens_q_head_tbl bf; +}; + +/*[table] L0_ENS_Q_ENTRY_TBL*/ +#define L0_ENS_Q_ENTRY_TBL +#define L0_ENS_Q_ENTRY_TBL_ADDRESS 0x22000 +#define L0_ENS_Q_ENTRY_TBL_NUM 300 +#define L0_ENS_Q_ENTRY_TBL_INC 0x10 +#define L0_ENS_Q_ENTRY_TBL_TYPE REG_TYPE_RO +#define L0_ENS_Q_ENTRY_TBL_DEFAULT 0x0 + /*[field] ENTRY_ENS_TYPE*/ + #define L0_ENS_Q_ENTRY_TBL_ENTRY_ENS_TYPE + #define L0_ENS_Q_ENTRY_TBL_ENTRY_ENS_TYPE_OFFSET 0 + #define L0_ENS_Q_ENTRY_TBL_ENTRY_ENS_TYPE_LEN 2 + #define L0_ENS_Q_ENTRY_TBL_ENTRY_ENS_TYPE_DEFAULT 0x0 + /*[field] ENTRY_ENS_VLD*/ + #define L0_ENS_Q_ENTRY_TBL_ENTRY_ENS_VLD + #define L0_ENS_Q_ENTRY_TBL_ENTRY_ENS_VLD_OFFSET 2 + #define L0_ENS_Q_ENTRY_TBL_ENTRY_ENS_VLD_LEN 1 + #define L0_ENS_Q_ENTRY_TBL_ENTRY_ENS_VLD_DEFAULT 0x0 + /*[field] ENTRY_ENS_IN_Q*/ + #define L0_ENS_Q_ENTRY_TBL_ENTRY_ENS_IN_Q + #define L0_ENS_Q_ENTRY_TBL_ENTRY_ENS_IN_Q_OFFSET 3 + #define L0_ENS_Q_ENTRY_TBL_ENTRY_ENS_IN_Q_LEN 1 + #define L0_ENS_Q_ENTRY_TBL_ENTRY_ENS_IN_Q_DEFAULT 0x0 + +struct l0_ens_q_entry_tbl { + a_uint32_t entry_ens_type:2; + a_uint32_t entry_ens_vld:1; + a_uint32_t entry_ens_in_q:1; + a_uint32_t _reserved0:28; +}; + +union l0_ens_q_entry_tbl_u { + a_uint32_t val; + struct l0_ens_q_entry_tbl bf; +}; + +/*[table] L0_FLOW_STATUS_TBL*/ +#define L0_FLOW_STATUS_TBL +#define L0_FLOW_STATUS_TBL_ADDRESS 0x24000 +#define L0_FLOW_STATUS_TBL_NUM 300 +#define L0_FLOW_STATUS_TBL_INC 0x10 +#define L0_FLOW_STATUS_TBL_TYPE REG_TYPE_RO +#define L0_FLOW_STATUS_TBL_DEFAULT 0x0 + /*[field] EN_LEVEL*/ + #define L0_FLOW_STATUS_TBL_EN_LEVEL + #define L0_FLOW_STATUS_TBL_EN_LEVEL_OFFSET 0 + #define L0_FLOW_STATUS_TBL_EN_LEVEL_LEN 1 + #define L0_FLOW_STATUS_TBL_EN_LEVEL_DEFAULT 0x0 + /*[field] EN_CDRR*/ + #define L0_FLOW_STATUS_TBL_EN_CDRR + #define L0_FLOW_STATUS_TBL_EN_CDRR_OFFSET 1 + #define L0_FLOW_STATUS_TBL_EN_CDRR_LEN 1 + #define L0_FLOW_STATUS_TBL_EN_CDRR_DEFAULT 0x0 + /*[field] EN_EDRR*/ + #define L0_FLOW_STATUS_TBL_EN_EDRR + #define L0_FLOW_STATUS_TBL_EN_EDRR_OFFSET 2 + #define L0_FLOW_STATUS_TBL_EN_EDRR_LEN 1 + #define L0_FLOW_STATUS_TBL_EN_EDRR_DEFAULT 0x0 + +struct l0_flow_status_tbl { + a_uint32_t en_level:1; + a_uint32_t en_cdrr:1; + a_uint32_t en_edrr:1; + a_uint32_t _reserved0:29; +}; + +union l0_flow_status_tbl_u { + a_uint32_t val; + struct l0_flow_status_tbl bf; +}; + + +/*[table] RING_Q_MAP_TBL*/ +#define RING_Q_MAP_TBL +#define RING_Q_MAP_TBL_ADDRESS 0x2a000 +#define RING_Q_MAP_TBL_NUM 16 +#define RING_Q_MAP_TBL_INC 0x40 +#define RING_Q_MAP_TBL_TYPE REG_TYPE_RW +#define RING_Q_MAP_TBL_DEFAULT 0x0 + /*[field] QUEUE_BITMAP*/ + #define RING_Q_MAP_TBL_QUEUE_BITMAP + #define RING_Q_MAP_TBL_QUEUE_BITMAP_OFFSET 0 + #define RING_Q_MAP_TBL_QUEUE_BITMAP_LEN 300 + #define RING_Q_MAP_TBL_QUEUE_BITMAP_DEFAULT 0x0 + +struct ring_q_map_tbl { + a_uint32_t queue_bitmap_0:32; + a_uint32_t queue_bitmap_1:32; + a_uint32_t queue_bitmap_2:32; + a_uint32_t queue_bitmap_3:32; + a_uint32_t queue_bitmap_4:32; + a_uint32_t queue_bitmap_5:32; + a_uint32_t queue_bitmap_6:32; + a_uint32_t queue_bitmap_7:32; + a_uint32_t queue_bitmap_8:32; + a_uint32_t queue_bitmap_9:12; + a_uint32_t _reserved0:20; +}; + +union ring_q_map_tbl_u { + a_uint32_t val[10]; + struct ring_q_map_tbl bf; +}; + +/*[table] RFC_BLOCK_TBL*/ +#define RFC_BLOCK_TBL +#define RFC_BLOCK_TBL_ADDRESS 0x2c000 +#define RFC_BLOCK_TBL_NUM 300 +#define RFC_BLOCK_TBL_INC 0x10 +#define RFC_BLOCK_TBL_TYPE REG_TYPE_RO +#define RFC_BLOCK_TBL_DEFAULT 0x0 + /*[field] RFC_BLOCK*/ + #define RFC_BLOCK_TBL_RFC_BLOCK + #define RFC_BLOCK_TBL_RFC_BLOCK_OFFSET 0 + #define RFC_BLOCK_TBL_RFC_BLOCK_LEN 1 + #define RFC_BLOCK_TBL_RFC_BLOCK_DEFAULT 0x0 + +struct rfc_block_tbl { + a_uint32_t rfc_block:1; + a_uint32_t _reserved0:31; +}; + +union rfc_block_tbl_u { + a_uint32_t val; + struct rfc_block_tbl bf; +}; + +/*[table] RFC_STATUS_TBL*/ +#define RFC_STATUS_TBL +#define RFC_STATUS_TBL_ADDRESS 0x2e000 +#define RFC_STATUS_TBL_NUM 300 +#define RFC_STATUS_TBL_INC 0x10 +#define RFC_STATUS_TBL_TYPE REG_TYPE_RO +#define RFC_STATUS_TBL_DEFAULT 0x0 + /*[field] RFC_STATUS*/ + #define RFC_STATUS_TBL_RFC_STATUS + #define RFC_STATUS_TBL_RFC_STATUS_OFFSET 0 + #define RFC_STATUS_TBL_RFC_STATUS_LEN 1 + #define RFC_STATUS_TBL_RFC_STATUS_DEFAULT 0x0 + +struct rfc_status_tbl { + a_uint32_t rfc_status:1; + a_uint32_t _reserved0:31; +}; + +union rfc_status_tbl_u { + a_uint32_t val; + struct rfc_status_tbl bf; +}; + +/*[table] DEQ_DIS_TBL*/ +#define DEQ_DIS_TBL +#define DEQ_DIS_TBL_ADDRESS 0x30000 +#define DEQ_DIS_TBL_NUM 300 +#define DEQ_DIS_TBL_INC 0x10 +#define DEQ_DIS_TBL_TYPE REG_TYPE_RW +#define DEQ_DIS_TBL_DEFAULT 0x0 + /*[field] DEQ_DIS*/ + #define DEQ_DIS_TBL_DEQ_DIS + #define DEQ_DIS_TBL_DEQ_DIS_OFFSET 0 + #define DEQ_DIS_TBL_DEQ_DIS_LEN 1 + #define DEQ_DIS_TBL_DEQ_DIS_DEFAULT 0x0 + +struct deq_dis_tbl { + a_uint32_t deq_dis:1; + a_uint32_t _reserved0:31; +}; + +union deq_dis_tbl_u { + a_uint32_t val; + struct deq_dis_tbl bf; +}; + +/*[table] L1_FLOW_MAP_TBL*/ +#define L1_FLOW_MAP_TBL +#define L1_FLOW_MAP_TBL_ADDRESS 0x40000 +#define L1_FLOW_MAP_TBL_NUM 64 +#define L1_FLOW_MAP_TBL_INC 0x10 +#define L1_FLOW_MAP_TBL_TYPE REG_TYPE_RW +#define L1_FLOW_MAP_TBL_DEFAULT 0x0 + /*[field] SP_ID*/ + #define L1_FLOW_MAP_TBL_SP_ID + #define L1_FLOW_MAP_TBL_SP_ID_OFFSET 0 + #define L1_FLOW_MAP_TBL_SP_ID_LEN 4 + #define L1_FLOW_MAP_TBL_SP_ID_DEFAULT 0x0 + /*[field] C_PRI*/ + #define L1_FLOW_MAP_TBL_C_PRI + #define L1_FLOW_MAP_TBL_C_PRI_OFFSET 4 + #define L1_FLOW_MAP_TBL_C_PRI_LEN 3 + #define L1_FLOW_MAP_TBL_C_PRI_DEFAULT 0x0 + /*[field] E_PRI*/ + #define L1_FLOW_MAP_TBL_E_PRI + #define L1_FLOW_MAP_TBL_E_PRI_OFFSET 7 + #define L1_FLOW_MAP_TBL_E_PRI_LEN 3 + #define L1_FLOW_MAP_TBL_E_PRI_DEFAULT 0x0 + /*[field] C_DRR_WT*/ + #define L1_FLOW_MAP_TBL_C_DRR_WT + #define L1_FLOW_MAP_TBL_C_DRR_WT_OFFSET 10 + #define L1_FLOW_MAP_TBL_C_DRR_WT_LEN 10 + #define L1_FLOW_MAP_TBL_C_DRR_WT_DEFAULT 0x0 + /*[field] E_DRR_WT*/ + #define L1_FLOW_MAP_TBL_E_DRR_WT + #define L1_FLOW_MAP_TBL_E_DRR_WT_OFFSET 20 + #define L1_FLOW_MAP_TBL_E_DRR_WT_LEN 10 + #define L1_FLOW_MAP_TBL_E_DRR_WT_DEFAULT 0x0 + +struct l1_flow_map_tbl { + a_uint32_t sp_id:4; + a_uint32_t c_pri:3; + a_uint32_t e_pri:3; + a_uint32_t c_drr_wt:10; + a_uint32_t e_drr_wt:10; + a_uint32_t _reserved0:2; +}; + +union l1_flow_map_tbl_u { + a_uint32_t val; + struct l1_flow_map_tbl bf; +}; + +/*[table] L1_C_SP_CFG_TBL*/ +#define L1_C_SP_CFG_TBL +#define L1_C_SP_CFG_TBL_ADDRESS 0x42000 +#define L1_C_SP_CFG_TBL_NUM 64 +#define L1_C_SP_CFG_TBL_INC 0x10 +#define L1_C_SP_CFG_TBL_TYPE REG_TYPE_RW +#define L1_C_SP_CFG_TBL_DEFAULT 0x0 + /*[field] DRR_ID*/ + #define L1_C_SP_CFG_TBL_DRR_ID + #define L1_C_SP_CFG_TBL_DRR_ID_OFFSET 0 + #define L1_C_SP_CFG_TBL_DRR_ID_LEN 6 + #define L1_C_SP_CFG_TBL_DRR_ID_DEFAULT 0x0 + /*[field] DRR_CREDIT_UNIT*/ + #define L1_C_SP_CFG_TBL_DRR_CREDIT_UNIT + #define L1_C_SP_CFG_TBL_DRR_CREDIT_UNIT_OFFSET 6 + #define L1_C_SP_CFG_TBL_DRR_CREDIT_UNIT_LEN 1 + #define L1_C_SP_CFG_TBL_DRR_CREDIT_UNIT_DEFAULT 0x0 + +struct l1_c_sp_cfg_tbl { + a_uint32_t drr_id:6; + a_uint32_t drr_credit_unit:1; + a_uint32_t _reserved0:25; +}; + +union l1_c_sp_cfg_tbl_u { + a_uint32_t val; + struct l1_c_sp_cfg_tbl bf; +}; + +/*[table] L1_E_SP_CFG_TBL*/ +#define L1_E_SP_CFG_TBL +#define L1_E_SP_CFG_TBL_ADDRESS 0x44000 +#define L1_E_SP_CFG_TBL_NUM 64 +#define L1_E_SP_CFG_TBL_INC 0x10 +#define L1_E_SP_CFG_TBL_TYPE REG_TYPE_RW +#define L1_E_SP_CFG_TBL_DEFAULT 0x0 + /*[field] DRR_ID*/ + #define L1_E_SP_CFG_TBL_DRR_ID + #define L1_E_SP_CFG_TBL_DRR_ID_OFFSET 0 + #define L1_E_SP_CFG_TBL_DRR_ID_LEN 6 + #define L1_E_SP_CFG_TBL_DRR_ID_DEFAULT 0x0 + /*[field] DRR_CREDIT_UNIT*/ + #define L1_E_SP_CFG_TBL_DRR_CREDIT_UNIT + #define L1_E_SP_CFG_TBL_DRR_CREDIT_UNIT_OFFSET 6 + #define L1_E_SP_CFG_TBL_DRR_CREDIT_UNIT_LEN 1 + #define L1_E_SP_CFG_TBL_DRR_CREDIT_UNIT_DEFAULT 0x0 + +struct l1_e_sp_cfg_tbl { + a_uint32_t drr_id:6; + a_uint32_t drr_credit_unit:1; + a_uint32_t _reserved0:25; +}; + +union l1_e_sp_cfg_tbl_u { + a_uint32_t val; + struct l1_e_sp_cfg_tbl bf; +}; + +/*[table] L1_FLOW_PORT_MAP_TBL*/ +#define L1_FLOW_PORT_MAP_TBL +#define L1_FLOW_PORT_MAP_TBL_ADDRESS 0x46000 +#define L1_FLOW_PORT_MAP_TBL_NUM 64 +#define L1_FLOW_PORT_MAP_TBL_INC 0x10 +#define L1_FLOW_PORT_MAP_TBL_TYPE REG_TYPE_RW +#define L1_FLOW_PORT_MAP_TBL_DEFAULT 0x0 + /*[field] PORT_NUM*/ + #define L1_FLOW_PORT_MAP_TBL_PORT_NUM + #define L1_FLOW_PORT_MAP_TBL_PORT_NUM_OFFSET 0 + #define L1_FLOW_PORT_MAP_TBL_PORT_NUM_LEN 4 + #define L1_FLOW_PORT_MAP_TBL_PORT_NUM_DEFAULT 0x0 + +struct l1_flow_port_map_tbl { + a_uint32_t port_num:4; + a_uint32_t _reserved0:28; +}; + +union l1_flow_port_map_tbl_u { + a_uint32_t val; + struct l1_flow_port_map_tbl bf; +}; + +/*[table] L1_C_DRR_HEAD_TBL*/ +#define L1_C_DRR_HEAD_TBL +#define L1_C_DRR_HEAD_TBL_ADDRESS 0x48000 +#define L1_C_DRR_HEAD_TBL_NUM 36 +#define L1_C_DRR_HEAD_TBL_INC 0x10 +#define L1_C_DRR_HEAD_TBL_TYPE REG_TYPE_RO +#define L1_C_DRR_HEAD_TBL_DEFAULT 0x0 + /*[field] BACKUP_TAIL*/ + #define L1_C_DRR_HEAD_TBL_BACKUP_TAIL + #define L1_C_DRR_HEAD_TBL_BACKUP_TAIL_OFFSET 0 + #define L1_C_DRR_HEAD_TBL_BACKUP_TAIL_LEN 6 + #define L1_C_DRR_HEAD_TBL_BACKUP_TAIL_DEFAULT 0x0 + /*[field] BACKUP_HEAD*/ + #define L1_C_DRR_HEAD_TBL_BACKUP_HEAD + #define L1_C_DRR_HEAD_TBL_BACKUP_HEAD_OFFSET 6 + #define L1_C_DRR_HEAD_TBL_BACKUP_HEAD_LEN 6 + #define L1_C_DRR_HEAD_TBL_BACKUP_HEAD_DEFAULT 0x0 + /*[field] BACKUP_VLD*/ + #define L1_C_DRR_HEAD_TBL_BACKUP_VLD + #define L1_C_DRR_HEAD_TBL_BACKUP_VLD_OFFSET 12 + #define L1_C_DRR_HEAD_TBL_BACKUP_VLD_LEN 1 + #define L1_C_DRR_HEAD_TBL_BACKUP_VLD_DEFAULT 0x0 + /*[field] BACKUP_MAX_N*/ + #define L1_C_DRR_HEAD_TBL_BACKUP_MAX_N + #define L1_C_DRR_HEAD_TBL_BACKUP_MAX_N_OFFSET 13 + #define L1_C_DRR_HEAD_TBL_BACKUP_MAX_N_LEN 5 + #define L1_C_DRR_HEAD_TBL_BACKUP_MAX_N_DEFAULT 0x0 + /*[field] ACTIVE_TAIL*/ + #define L1_C_DRR_HEAD_TBL_ACTIVE_TAIL + #define L1_C_DRR_HEAD_TBL_ACTIVE_TAIL_OFFSET 18 + #define L1_C_DRR_HEAD_TBL_ACTIVE_TAIL_LEN 6 + #define L1_C_DRR_HEAD_TBL_ACTIVE_TAIL_DEFAULT 0x0 + /*[field] ACTIVE_HEAD*/ + #define L1_C_DRR_HEAD_TBL_ACTIVE_HEAD + #define L1_C_DRR_HEAD_TBL_ACTIVE_HEAD_OFFSET 24 + #define L1_C_DRR_HEAD_TBL_ACTIVE_HEAD_LEN 6 + #define L1_C_DRR_HEAD_TBL_ACTIVE_HEAD_DEFAULT 0x0 + /*[field] ACTIVE_VLD*/ + #define L1_C_DRR_HEAD_TBL_ACTIVE_VLD + #define L1_C_DRR_HEAD_TBL_ACTIVE_VLD_OFFSET 30 + #define L1_C_DRR_HEAD_TBL_ACTIVE_VLD_LEN 1 + #define L1_C_DRR_HEAD_TBL_ACTIVE_VLD_DEFAULT 0x0 + /*[field] ACTIVE_MAX_N*/ + #define L1_C_DRR_HEAD_TBL_ACTIVE_MAX_N + #define L1_C_DRR_HEAD_TBL_ACTIVE_MAX_N_OFFSET 31 + #define L1_C_DRR_HEAD_TBL_ACTIVE_MAX_N_LEN 5 + #define L1_C_DRR_HEAD_TBL_ACTIVE_MAX_N_DEFAULT 0x0 + +struct l1_c_drr_head_tbl { + a_uint32_t backup_tail:6; + a_uint32_t backup_head:6; + a_uint32_t backup_vld:1; + a_uint32_t backup_max_n:5; + a_uint32_t active_tail:6; + a_uint32_t active_head:6; + a_uint32_t active_vld:1; + a_uint32_t active_max_n_0:1; + a_uint32_t active_max_n_1:4; + a_uint32_t _reserved0:28; +}; + +union l1_c_drr_head_tbl_u { + a_uint32_t val[2]; + struct l1_c_drr_head_tbl bf; +}; + +/*[table] L1_E_DRR_HEAD_TBL*/ +#define L1_E_DRR_HEAD_TBL +#define L1_E_DRR_HEAD_TBL_ADDRESS 0x4a000 +#define L1_E_DRR_HEAD_TBL_NUM 36 +#define L1_E_DRR_HEAD_TBL_INC 0x10 +#define L1_E_DRR_HEAD_TBL_TYPE REG_TYPE_RO +#define L1_E_DRR_HEAD_TBL_DEFAULT 0x0 + /*[field] BACKUP_TAIL*/ + #define L1_E_DRR_HEAD_TBL_BACKUP_TAIL + #define L1_E_DRR_HEAD_TBL_BACKUP_TAIL_OFFSET 0 + #define L1_E_DRR_HEAD_TBL_BACKUP_TAIL_LEN 6 + #define L1_E_DRR_HEAD_TBL_BACKUP_TAIL_DEFAULT 0x0 + /*[field] BACKUP_HEAD*/ + #define L1_E_DRR_HEAD_TBL_BACKUP_HEAD + #define L1_E_DRR_HEAD_TBL_BACKUP_HEAD_OFFSET 6 + #define L1_E_DRR_HEAD_TBL_BACKUP_HEAD_LEN 6 + #define L1_E_DRR_HEAD_TBL_BACKUP_HEAD_DEFAULT 0x0 + /*[field] BACKUP_VLD*/ + #define L1_E_DRR_HEAD_TBL_BACKUP_VLD + #define L1_E_DRR_HEAD_TBL_BACKUP_VLD_OFFSET 12 + #define L1_E_DRR_HEAD_TBL_BACKUP_VLD_LEN 1 + #define L1_E_DRR_HEAD_TBL_BACKUP_VLD_DEFAULT 0x0 + /*[field] BACKUP_MAX_N*/ + #define L1_E_DRR_HEAD_TBL_BACKUP_MAX_N + #define L1_E_DRR_HEAD_TBL_BACKUP_MAX_N_OFFSET 13 + #define L1_E_DRR_HEAD_TBL_BACKUP_MAX_N_LEN 5 + #define L1_E_DRR_HEAD_TBL_BACKUP_MAX_N_DEFAULT 0x0 + /*[field] ACTIVE_TAIL*/ + #define L1_E_DRR_HEAD_TBL_ACTIVE_TAIL + #define L1_E_DRR_HEAD_TBL_ACTIVE_TAIL_OFFSET 18 + #define L1_E_DRR_HEAD_TBL_ACTIVE_TAIL_LEN 6 + #define L1_E_DRR_HEAD_TBL_ACTIVE_TAIL_DEFAULT 0x0 + /*[field] ACTIVE_HEAD*/ + #define L1_E_DRR_HEAD_TBL_ACTIVE_HEAD + #define L1_E_DRR_HEAD_TBL_ACTIVE_HEAD_OFFSET 24 + #define L1_E_DRR_HEAD_TBL_ACTIVE_HEAD_LEN 6 + #define L1_E_DRR_HEAD_TBL_ACTIVE_HEAD_DEFAULT 0x0 + /*[field] ACTIVE_VLD*/ + #define L1_E_DRR_HEAD_TBL_ACTIVE_VLD + #define L1_E_DRR_HEAD_TBL_ACTIVE_VLD_OFFSET 30 + #define L1_E_DRR_HEAD_TBL_ACTIVE_VLD_LEN 1 + #define L1_E_DRR_HEAD_TBL_ACTIVE_VLD_DEFAULT 0x0 + /*[field] ACTIVE_MAX_N*/ + #define L1_E_DRR_HEAD_TBL_ACTIVE_MAX_N + #define L1_E_DRR_HEAD_TBL_ACTIVE_MAX_N_OFFSET 31 + #define L1_E_DRR_HEAD_TBL_ACTIVE_MAX_N_LEN 5 + #define L1_E_DRR_HEAD_TBL_ACTIVE_MAX_N_DEFAULT 0x0 + +struct l1_e_drr_head_tbl { + a_uint32_t backup_tail:6; + a_uint32_t backup_head:6; + a_uint32_t backup_vld:1; + a_uint32_t backup_max_n:5; + a_uint32_t active_tail:6; + a_uint32_t active_head:6; + a_uint32_t active_vld:1; + a_uint32_t active_max_n_0:1; + a_uint32_t active_max_n_1:4; + a_uint32_t _reserved0:28; +}; + +union l1_e_drr_head_tbl_u { + a_uint32_t val[2]; + struct l1_e_drr_head_tbl bf; +}; + +/*[table] L1_DRR_CREDIT_TBL*/ +#define L1_DRR_CREDIT_TBL +#define L1_DRR_CREDIT_TBL_ADDRESS 0x4c000 +#define L1_DRR_CREDIT_TBL_NUM 64 +#define L1_DRR_CREDIT_TBL_INC 0x10 +#define L1_DRR_CREDIT_TBL_TYPE REG_TYPE_RO +#define L1_DRR_CREDIT_TBL_DEFAULT 0x0 + /*[field] C_DRR_CREDIT*/ + #define L1_DRR_CREDIT_TBL_C_DRR_CREDIT + #define L1_DRR_CREDIT_TBL_C_DRR_CREDIT_OFFSET 0 + #define L1_DRR_CREDIT_TBL_C_DRR_CREDIT_LEN 24 + #define L1_DRR_CREDIT_TBL_C_DRR_CREDIT_DEFAULT 0x0 + /*[field] C_DRR_CREDIT_NEG*/ + #define L1_DRR_CREDIT_TBL_C_DRR_CREDIT_NEG + #define L1_DRR_CREDIT_TBL_C_DRR_CREDIT_NEG_OFFSET 24 + #define L1_DRR_CREDIT_TBL_C_DRR_CREDIT_NEG_LEN 1 + #define L1_DRR_CREDIT_TBL_C_DRR_CREDIT_NEG_DEFAULT 0x0 + /*[field] E_DRR_CREDIT*/ + #define L1_DRR_CREDIT_TBL_E_DRR_CREDIT + #define L1_DRR_CREDIT_TBL_E_DRR_CREDIT_OFFSET 25 + #define L1_DRR_CREDIT_TBL_E_DRR_CREDIT_LEN 24 + #define L1_DRR_CREDIT_TBL_E_DRR_CREDIT_DEFAULT 0x0 + /*[field] E_DRR_CREDIT_NEG*/ + #define L1_DRR_CREDIT_TBL_E_DRR_CREDIT_NEG + #define L1_DRR_CREDIT_TBL_E_DRR_CREDIT_NEG_OFFSET 49 + #define L1_DRR_CREDIT_TBL_E_DRR_CREDIT_NEG_LEN 1 + #define L1_DRR_CREDIT_TBL_E_DRR_CREDIT_NEG_DEFAULT 0x0 + +struct l1_drr_credit_tbl { + a_uint32_t c_drr_credit:24; + a_uint32_t c_drr_credit_neg:1; + a_uint32_t e_drr_credit_0:7; + a_uint32_t e_drr_credit_1:17; + a_uint32_t e_drr_credit_neg:1; + a_uint32_t _reserved0:14; +}; + +union l1_drr_credit_tbl_u { + a_uint32_t val[2]; + struct l1_drr_credit_tbl bf; +}; + +/*[table] L1_C_DRR_LL_TBL*/ +#define L1_C_DRR_LL_TBL +#define L1_C_DRR_LL_TBL_ADDRESS 0x4e000 +#define L1_C_DRR_LL_TBL_NUM 64 +#define L1_C_DRR_LL_TBL_INC 0x10 +#define L1_C_DRR_LL_TBL_TYPE REG_TYPE_RO +#define L1_C_DRR_LL_TBL_DEFAULT 0x0 + /*[field] NEXT_PTR*/ + #define L1_C_DRR_LL_TBL_NEXT_PTR + #define L1_C_DRR_LL_TBL_NEXT_PTR_OFFSET 0 + #define L1_C_DRR_LL_TBL_NEXT_PTR_LEN 6 + #define L1_C_DRR_LL_TBL_NEXT_PTR_DEFAULT 0x0 + +struct l1_c_drr_ll_tbl { + a_uint32_t next_ptr:6; + a_uint32_t _reserved0:26; +}; + +union l1_c_drr_ll_tbl_u { + a_uint32_t val; + struct l1_c_drr_ll_tbl bf; +}; + +/*[table] L1_C_DRR_REVERSE_LL_TBL*/ +#define L1_C_DRR_REVERSE_LL_TBL +#define L1_C_DRR_REVERSE_LL_TBL_ADDRESS 0x50000 +#define L1_C_DRR_REVERSE_LL_TBL_NUM 64 +#define L1_C_DRR_REVERSE_LL_TBL_INC 0x10 +#define L1_C_DRR_REVERSE_LL_TBL_TYPE REG_TYPE_RO +#define L1_C_DRR_REVERSE_LL_TBL_DEFAULT 0x0 + /*[field] PRE_PTR*/ + #define L1_C_DRR_REVERSE_LL_TBL_PRE_PTR + #define L1_C_DRR_REVERSE_LL_TBL_PRE_PTR_OFFSET 0 + #define L1_C_DRR_REVERSE_LL_TBL_PRE_PTR_LEN 6 + #define L1_C_DRR_REVERSE_LL_TBL_PRE_PTR_DEFAULT 0x0 + +struct l1_c_drr_reverse_ll_tbl { + a_uint32_t pre_ptr:6; + a_uint32_t _reserved0:26; +}; + +union l1_c_drr_reverse_ll_tbl_u { + a_uint32_t val; + struct l1_c_drr_reverse_ll_tbl bf; +}; + +/*[table] L1_E_DRR_LL_TBL*/ +#define L1_E_DRR_LL_TBL +#define L1_E_DRR_LL_TBL_ADDRESS 0x52000 +#define L1_E_DRR_LL_TBL_NUM 64 +#define L1_E_DRR_LL_TBL_INC 0x10 +#define L1_E_DRR_LL_TBL_TYPE REG_TYPE_RO +#define L1_E_DRR_LL_TBL_DEFAULT 0x0 + /*[field] NEXT_PTR*/ + #define L1_E_DRR_LL_TBL_NEXT_PTR + #define L1_E_DRR_LL_TBL_NEXT_PTR_OFFSET 0 + #define L1_E_DRR_LL_TBL_NEXT_PTR_LEN 6 + #define L1_E_DRR_LL_TBL_NEXT_PTR_DEFAULT 0x0 + +struct l1_e_drr_ll_tbl { + a_uint32_t next_ptr:6; + a_uint32_t _reserved0:26; +}; + +union l1_e_drr_ll_tbl_u { + a_uint32_t val; + struct l1_e_drr_ll_tbl bf; +}; + +/*[table] L1_E_DRR_REVERSE_LL_TBL*/ +#define L1_E_DRR_REVERSE_LL_TBL +#define L1_E_DRR_REVERSE_LL_TBL_ADDRESS 0x54000 +#define L1_E_DRR_REVERSE_LL_TBL_NUM 64 +#define L1_E_DRR_REVERSE_LL_TBL_INC 0x10 +#define L1_E_DRR_REVERSE_LL_TBL_TYPE REG_TYPE_RO +#define L1_E_DRR_REVERSE_LL_TBL_DEFAULT 0x0 + /*[field] PRE_PTR*/ + #define L1_E_DRR_REVERSE_LL_TBL_PRE_PTR + #define L1_E_DRR_REVERSE_LL_TBL_PRE_PTR_OFFSET 0 + #define L1_E_DRR_REVERSE_LL_TBL_PRE_PTR_LEN 6 + #define L1_E_DRR_REVERSE_LL_TBL_PRE_PTR_DEFAULT 0x0 + +struct l1_e_drr_reverse_ll_tbl { + a_uint32_t pre_ptr:6; + a_uint32_t _reserved0:26; +}; + +union l1_e_drr_reverse_ll_tbl_u { + a_uint32_t val; + struct l1_e_drr_reverse_ll_tbl bf; +}; + +/*[table] L1_A_FLOW_ENTRY_TBL*/ +#define L1_A_FLOW_ENTRY_TBL +#define L1_A_FLOW_ENTRY_TBL_ADDRESS 0x56000 +#define L1_A_FLOW_ENTRY_TBL_NUM 64 +#define L1_A_FLOW_ENTRY_TBL_INC 0x10 +#define L1_A_FLOW_ENTRY_TBL_TYPE REG_TYPE_RO +#define L1_A_FLOW_ENTRY_TBL_DEFAULT 0x0 + /*[field] ENTRY_PATH_ID*/ + #define L1_A_FLOW_ENTRY_TBL_ENTRY_PATH_ID + #define L1_A_FLOW_ENTRY_TBL_ENTRY_PATH_ID_OFFSET 0 + #define L1_A_FLOW_ENTRY_TBL_ENTRY_PATH_ID_LEN 10 + #define L1_A_FLOW_ENTRY_TBL_ENTRY_PATH_ID_DEFAULT 0x0 + +struct l1_a_flow_entry_tbl { + a_uint32_t entry_path_id:10; + a_uint32_t _reserved0:22; +}; + +union l1_a_flow_entry_tbl_u { + a_uint32_t val; + struct l1_a_flow_entry_tbl bf; +}; + +/*[table] L1_B_FLOW_ENTRY_TBL*/ +#define L1_B_FLOW_ENTRY_TBL +#define L1_B_FLOW_ENTRY_TBL_ADDRESS 0x58000 +#define L1_B_FLOW_ENTRY_TBL_NUM 64 +#define L1_B_FLOW_ENTRY_TBL_INC 0x10 +#define L1_B_FLOW_ENTRY_TBL_TYPE REG_TYPE_RO +#define L1_B_FLOW_ENTRY_TBL_DEFAULT 0x0 + /*[field] ENTRY_PATH_ID*/ + #define L1_B_FLOW_ENTRY_TBL_ENTRY_PATH_ID + #define L1_B_FLOW_ENTRY_TBL_ENTRY_PATH_ID_OFFSET 0 + #define L1_B_FLOW_ENTRY_TBL_ENTRY_PATH_ID_LEN 10 + #define L1_B_FLOW_ENTRY_TBL_ENTRY_PATH_ID_DEFAULT 0x0 + +struct l1_b_flow_entry_tbl { + a_uint32_t entry_path_id:10; + a_uint32_t _reserved0:22; +}; + +union l1_b_flow_entry_tbl_u { + a_uint32_t val; + struct l1_b_flow_entry_tbl bf; +}; + +/*[table] L1_SP_ENTRY_TBL*/ +#define L1_SP_ENTRY_TBL +#define L1_SP_ENTRY_TBL_ADDRESS 0x5a000 +#define L1_SP_ENTRY_TBL_NUM 8 +#define L1_SP_ENTRY_TBL_INC 0x40 +#define L1_SP_ENTRY_TBL_TYPE REG_TYPE_RO +#define L1_SP_ENTRY_TBL_DEFAULT 0x0 + /*[field] ENTRY_PATH_ID*/ + #define L1_SP_ENTRY_TBL_ENTRY_PATH_ID + #define L1_SP_ENTRY_TBL_ENTRY_PATH_ID_OFFSET 0 + #define L1_SP_ENTRY_TBL_ENTRY_PATH_ID_LEN 256 + #define L1_SP_ENTRY_TBL_ENTRY_PATH_ID_DEFAULT 0x0 + /*[field] ENTRY_VLD*/ + #define L1_SP_ENTRY_TBL_ENTRY_VLD + #define L1_SP_ENTRY_TBL_ENTRY_VLD_OFFSET 256 + #define L1_SP_ENTRY_TBL_ENTRY_VLD_LEN 16 + #define L1_SP_ENTRY_TBL_ENTRY_VLD_DEFAULT 0x0 + +struct l1_sp_entry_tbl { + a_uint32_t entry_path_id_0:32; + a_uint32_t entry_path_id_1:32; + a_uint32_t entry_path_id_2:32; + a_uint32_t entry_path_id_3:32; + a_uint32_t entry_path_id_4:32; + a_uint32_t entry_path_id_5:32; + a_uint32_t entry_path_id_6:32; + a_uint32_t entry_path_id_7:32; + a_uint32_t entry_vld:16; + a_uint32_t _reserved0:16; +}; + +union l1_sp_entry_tbl_u { + a_uint32_t val[9]; + struct l1_sp_entry_tbl bf; +}; + + +/*[table] L1_ENS_Q_LL_TBL*/ +#define L1_ENS_Q_LL_TBL +#define L1_ENS_Q_LL_TBL_ADDRESS 0x60000 +#define L1_ENS_Q_LL_TBL_NUM 64 +#define L1_ENS_Q_LL_TBL_INC 0x10 +#define L1_ENS_Q_LL_TBL_TYPE REG_TYPE_RO +#define L1_ENS_Q_LL_TBL_DEFAULT 0x0 + /*[field] NEXT_PTR*/ + #define L1_ENS_Q_LL_TBL_NEXT_PTR + #define L1_ENS_Q_LL_TBL_NEXT_PTR_OFFSET 0 + #define L1_ENS_Q_LL_TBL_NEXT_PTR_LEN 6 + #define L1_ENS_Q_LL_TBL_NEXT_PTR_DEFAULT 0x0 + +struct l1_ens_q_ll_tbl { + a_uint32_t next_ptr:6; + a_uint32_t _reserved0:26; +}; + +union l1_ens_q_ll_tbl_u { + a_uint32_t val; + struct l1_ens_q_ll_tbl bf; +}; + +/*[table] L1_ENS_Q_HEAD_TBL*/ +#define L1_ENS_Q_HEAD_TBL +#define L1_ENS_Q_HEAD_TBL_ADDRESS 0x62000 +#define L1_ENS_Q_HEAD_TBL_NUM 8 +#define L1_ENS_Q_HEAD_TBL_INC 0x10 +#define L1_ENS_Q_HEAD_TBL_TYPE REG_TYPE_RO +#define L1_ENS_Q_HEAD_TBL_DEFAULT 0x0 + /*[field] TAIL*/ + #define L1_ENS_Q_HEAD_TBL_TAIL + #define L1_ENS_Q_HEAD_TBL_TAIL_OFFSET 0 + #define L1_ENS_Q_HEAD_TBL_TAIL_LEN 6 + #define L1_ENS_Q_HEAD_TBL_TAIL_DEFAULT 0x0 + /*[field] HEAD*/ + #define L1_ENS_Q_HEAD_TBL_HEAD + #define L1_ENS_Q_HEAD_TBL_HEAD_OFFSET 6 + #define L1_ENS_Q_HEAD_TBL_HEAD_LEN 6 + #define L1_ENS_Q_HEAD_TBL_HEAD_DEFAULT 0x0 + /*[field] VLD*/ + #define L1_ENS_Q_HEAD_TBL_VLD + #define L1_ENS_Q_HEAD_TBL_VLD_OFFSET 12 + #define L1_ENS_Q_HEAD_TBL_VLD_LEN 1 + #define L1_ENS_Q_HEAD_TBL_VLD_DEFAULT 0x0 + +struct l1_ens_q_head_tbl { + a_uint32_t tail:6; + a_uint32_t head:6; + a_uint32_t vld:1; + a_uint32_t _reserved0:19; +}; + +union l1_ens_q_head_tbl_u { + a_uint32_t val; + struct l1_ens_q_head_tbl bf; +}; + +/*[table] L1_ENS_Q_ENTRY_TBL*/ +#define L1_ENS_Q_ENTRY_TBL +#define L1_ENS_Q_ENTRY_TBL_ADDRESS 0x64000 +#define L1_ENS_Q_ENTRY_TBL_NUM 64 +#define L1_ENS_Q_ENTRY_TBL_INC 0x10 +#define L1_ENS_Q_ENTRY_TBL_TYPE REG_TYPE_RO +#define L1_ENS_Q_ENTRY_TBL_DEFAULT 0x0 + /*[field] ENTRY_ENS_TYPE*/ + #define L1_ENS_Q_ENTRY_TBL_ENTRY_ENS_TYPE + #define L1_ENS_Q_ENTRY_TBL_ENTRY_ENS_TYPE_OFFSET 0 + #define L1_ENS_Q_ENTRY_TBL_ENTRY_ENS_TYPE_LEN 2 + #define L1_ENS_Q_ENTRY_TBL_ENTRY_ENS_TYPE_DEFAULT 0x0 + /*[field] ENTRY_ENS_VLD*/ + #define L1_ENS_Q_ENTRY_TBL_ENTRY_ENS_VLD + #define L1_ENS_Q_ENTRY_TBL_ENTRY_ENS_VLD_OFFSET 2 + #define L1_ENS_Q_ENTRY_TBL_ENTRY_ENS_VLD_LEN 1 + #define L1_ENS_Q_ENTRY_TBL_ENTRY_ENS_VLD_DEFAULT 0x0 + /*[field] ENTRY_ENS_IN_Q*/ + #define L1_ENS_Q_ENTRY_TBL_ENTRY_ENS_IN_Q + #define L1_ENS_Q_ENTRY_TBL_ENTRY_ENS_IN_Q_OFFSET 3 + #define L1_ENS_Q_ENTRY_TBL_ENTRY_ENS_IN_Q_LEN 1 + #define L1_ENS_Q_ENTRY_TBL_ENTRY_ENS_IN_Q_DEFAULT 0x0 + +struct l1_ens_q_entry_tbl { + a_uint32_t entry_ens_type:2; + a_uint32_t entry_ens_vld:1; + a_uint32_t entry_ens_in_q:1; + a_uint32_t _reserved0:28; +}; + +union l1_ens_q_entry_tbl_u { + a_uint32_t val; + struct l1_ens_q_entry_tbl bf; +}; + +/*[table] L1_FLOW_STATUS_TBL*/ +#define L1_FLOW_STATUS_TBL +#define L1_FLOW_STATUS_TBL_ADDRESS 0x66000 +#define L1_FLOW_STATUS_TBL_NUM 64 +#define L1_FLOW_STATUS_TBL_INC 0x10 +#define L1_FLOW_STATUS_TBL_TYPE REG_TYPE_RO +#define L1_FLOW_STATUS_TBL_DEFAULT 0x0 + /*[field] EN_LEVEL*/ + #define L1_FLOW_STATUS_TBL_EN_LEVEL + #define L1_FLOW_STATUS_TBL_EN_LEVEL_OFFSET 0 + #define L1_FLOW_STATUS_TBL_EN_LEVEL_LEN 1 + #define L1_FLOW_STATUS_TBL_EN_LEVEL_DEFAULT 0x0 + /*[field] EN_CDRR*/ + #define L1_FLOW_STATUS_TBL_EN_CDRR + #define L1_FLOW_STATUS_TBL_EN_CDRR_OFFSET 1 + #define L1_FLOW_STATUS_TBL_EN_CDRR_LEN 1 + #define L1_FLOW_STATUS_TBL_EN_CDRR_DEFAULT 0x0 + /*[field] EN_EDRR*/ + #define L1_FLOW_STATUS_TBL_EN_EDRR + #define L1_FLOW_STATUS_TBL_EN_EDRR_OFFSET 2 + #define L1_FLOW_STATUS_TBL_EN_EDRR_LEN 1 + #define L1_FLOW_STATUS_TBL_EN_EDRR_DEFAULT 0x0 + +struct l1_flow_status_tbl { + a_uint32_t en_level:1; + a_uint32_t en_cdrr:1; + a_uint32_t en_edrr:1; + a_uint32_t _reserved0:29; +}; + +union l1_flow_status_tbl_u { + a_uint32_t val; + struct l1_flow_status_tbl bf; +}; + +/*[table] PSCH_TDM_CFG_TBL*/ +#define PSCH_TDM_CFG_TBL +#define PSCH_TDM_CFG_TBL_ADDRESS 0x7a000 +#define PSCH_TDM_CFG_TBL_NUM 128 +#define PSCH_TDM_CFG_TBL_INC 0x10 +#define PSCH_TDM_CFG_TBL_TYPE REG_TYPE_RW +#define PSCH_TDM_CFG_TBL_DEFAULT 0x0 + /*[field] DES_PORT*/ + #define PSCH_TDM_CFG_TBL_DES_PORT + #define PSCH_TDM_CFG_TBL_DES_PORT_OFFSET 0 + #define PSCH_TDM_CFG_TBL_DES_PORT_LEN 4 + #define PSCH_TDM_CFG_TBL_DES_PORT_DEFAULT 0x0 + /*[field] ENS_PORT*/ + #define PSCH_TDM_CFG_TBL_ENS_PORT + #define PSCH_TDM_CFG_TBL_ENS_PORT_OFFSET 4 + #define PSCH_TDM_CFG_TBL_ENS_PORT_LEN 4 + #define PSCH_TDM_CFG_TBL_ENS_PORT_DEFAULT 0x0 + /*[field] ENS_PORT_BITMAP*/ + #define PSCH_TDM_CFG_TBL_ENS_PORT_BITMAP + #define PSCH_TDM_CFG_TBL_ENS_PORT_BITMAP_OFFSET 8 + #define PSCH_TDM_CFG_TBL_ENS_PORT_BITMAP_LEN 8 + #define PSCH_TDM_CFG_TBL_ENS_PORT_BITMAP_DEFAULT 0x0 + +struct psch_tdm_cfg_tbl { + a_uint32_t des_port:4; + a_uint32_t ens_port:4; + a_uint32_t ens_port_bitmap:8; + a_uint32_t _reserved0:16; +}; + +union psch_tdm_cfg_tbl_u { + a_uint32_t val; + struct psch_tdm_cfg_tbl bf; +}; + +/*[register] PORT_QOS_CTRL*/ +#define PORT_QOS_CTRL +#define PORT_QOS_CTRL_ADDRESS 0x900 +#define PORT_QOS_CTRL_NUM 8 +#define PORT_QOS_CTRL_INC 0x10 +#define PORT_QOS_CTRL_TYPE REG_TYPE_RW +#define PORT_QOS_CTRL_DEFAULT 0x23440 + /*[field] PCP_QOS_GROUP_ID*/ + #define PORT_QOS_CTRL_PCP_QOS_GROUP_ID + #define PORT_QOS_CTRL_PCP_QOS_GROUP_ID_OFFSET 0 + #define PORT_QOS_CTRL_PCP_QOS_GROUP_ID_LEN 1 + #define PORT_QOS_CTRL_PCP_QOS_GROUP_ID_DEFAULT 0x0 + /*[field] DSCP_QOS_GROUP_ID*/ + #define PORT_QOS_CTRL_DSCP_QOS_GROUP_ID + #define PORT_QOS_CTRL_DSCP_QOS_GROUP_ID_OFFSET 1 + #define PORT_QOS_CTRL_DSCP_QOS_GROUP_ID_LEN 1 + #define PORT_QOS_CTRL_DSCP_QOS_GROUP_ID_DEFAULT 0x0 + /*[field] FLOW_QOS_GROUP_ID*/ + #define PORT_QOS_CTRL_FLOW_QOS_GROUP_ID + #define PORT_QOS_CTRL_FLOW_QOS_GROUP_ID_OFFSET 2 + #define PORT_QOS_CTRL_FLOW_QOS_GROUP_ID_LEN 1 + #define PORT_QOS_CTRL_FLOW_QOS_GROUP_ID_DEFAULT 0x0 + /*[field] PORT_DSCP_QOS_PRI*/ + #define PORT_QOS_CTRL_PORT_DSCP_QOS_PRI + #define PORT_QOS_CTRL_PORT_DSCP_QOS_PRI_OFFSET 3 + #define PORT_QOS_CTRL_PORT_DSCP_QOS_PRI_LEN 3 + #define PORT_QOS_CTRL_PORT_DSCP_QOS_PRI_DEFAULT 0x0 + /*[field] PORT_PCP_QOS_PRI*/ + #define PORT_QOS_CTRL_PORT_PCP_QOS_PRI + #define PORT_QOS_CTRL_PORT_PCP_QOS_PRI_OFFSET 6 + #define PORT_QOS_CTRL_PORT_PCP_QOS_PRI_LEN 3 + #define PORT_QOS_CTRL_PORT_PCP_QOS_PRI_DEFAULT 0x1 + /*[field] PORT_PREHEADER_QOS_PRI*/ + #define PORT_QOS_CTRL_PORT_PREHEADER_QOS_PRI + #define PORT_QOS_CTRL_PORT_PREHEADER_QOS_PRI_OFFSET 9 + #define PORT_QOS_CTRL_PORT_PREHEADER_QOS_PRI_LEN 3 + #define PORT_QOS_CTRL_PORT_PREHEADER_QOS_PRI_DEFAULT 0x2 + /*[field] PORT_FLOW_QOS_PRI*/ + #define PORT_QOS_CTRL_PORT_FLOW_QOS_PRI + #define PORT_QOS_CTRL_PORT_FLOW_QOS_PRI_OFFSET 12 + #define PORT_QOS_CTRL_PORT_FLOW_QOS_PRI_LEN 3 + #define PORT_QOS_CTRL_PORT_FLOW_QOS_PRI_DEFAULT 0x3 + /*[field] PORT_ACL_QOS_PRI*/ + #define PORT_QOS_CTRL_PORT_ACL_QOS_PRI + #define PORT_QOS_CTRL_PORT_ACL_QOS_PRI_OFFSET 15 + #define PORT_QOS_CTRL_PORT_ACL_QOS_PRI_LEN 3 + #define PORT_QOS_CTRL_PORT_ACL_QOS_PRI_DEFAULT 0x4 + /*[field] PORT_PCP_CHANGE_EN*/ + #define PORT_QOS_CTRL_PORT_PCP_CHANGE_EN + #define PORT_QOS_CTRL_PORT_PCP_CHANGE_EN_OFFSET 18 + #define PORT_QOS_CTRL_PORT_PCP_CHANGE_EN_LEN 1 + #define PORT_QOS_CTRL_PORT_PCP_CHANGE_EN_DEFAULT 0x0 + /*[field] PORT_DEI_CHANGE_EN*/ + #define PORT_QOS_CTRL_PORT_DEI_CHANGE_EN + #define PORT_QOS_CTRL_PORT_DEI_CHANGE_EN_OFFSET 19 + #define PORT_QOS_CTRL_PORT_DEI_CHANGE_EN_LEN 1 + #define PORT_QOS_CTRL_PORT_DEI_CHANGE_EN_DEFAULT 0x0 + /*[field] PORT_DSCP_CHANGE_EN*/ + #define PORT_QOS_CTRL_PORT_DSCP_CHANGE_EN + #define PORT_QOS_CTRL_PORT_DSCP_CHANGE_EN_OFFSET 20 + #define PORT_QOS_CTRL_PORT_DSCP_CHANGE_EN_LEN 1 + #define PORT_QOS_CTRL_PORT_DSCP_CHANGE_EN_DEFAULT 0x0 + +struct port_qos_ctrl { + a_uint32_t pcp_qos_group_id:1; + a_uint32_t dscp_qos_group_id:1; + a_uint32_t flow_qos_group_id:1; + a_uint32_t port_dscp_qos_pri:3; + a_uint32_t port_pcp_qos_pri:3; + a_uint32_t port_preheader_qos_pri:3; + a_uint32_t port_flow_qos_pri:3; + a_uint32_t port_acl_qos_pri:3; + a_uint32_t port_pcp_change_en:1; + a_uint32_t port_dei_change_en:1; + a_uint32_t port_dscp_change_en:1; + a_uint32_t _reserved0:11; +}; + +union port_qos_ctrl_u { + a_uint32_t val; + struct port_qos_ctrl bf; +}; + +/*[register] PCP_QOS_GROUP_0*/ +#define PCP_QOS_GROUP_0 +#define PCP_QOS_GROUP_0_ADDRESS 0xb00 +#define PCP_QOS_GROUP_0_NUM 16 +#define PCP_QOS_GROUP_0_INC 0x4 +#define PCP_QOS_GROUP_0_TYPE REG_TYPE_RW +#define PCP_QOS_GROUP_0_DEFAULT 0x0 + /*[field] QOS_INFO*/ + #define PCP_QOS_GROUP_0_QOS_INFO + #define PCP_QOS_GROUP_0_QOS_INFO_OFFSET 0 + #define PCP_QOS_GROUP_0_QOS_INFO_LEN 16 + #define PCP_QOS_GROUP_0_QOS_INFO_DEFAULT 0x0 + +struct pcp_qos_group_0 { + a_uint32_t qos_info:16; + a_uint32_t _reserved0:16; +}; + +union pcp_qos_group_0_u { + a_uint32_t val; + struct pcp_qos_group_0 bf; +}; + +/*[register] PCP_QOS_GROUP_1*/ +#define PCP_QOS_GROUP_1 +#define PCP_QOS_GROUP_1_ADDRESS 0xc00 +#define PCP_QOS_GROUP_1_NUM 16 +#define PCP_QOS_GROUP_1_INC 0x4 +#define PCP_QOS_GROUP_1_TYPE REG_TYPE_RW +#define PCP_QOS_GROUP_1_DEFAULT 0x0 + /*[field] QOS_INFO*/ + #define PCP_QOS_GROUP_1_QOS_INFO + #define PCP_QOS_GROUP_1_QOS_INFO_OFFSET 0 + #define PCP_QOS_GROUP_1_QOS_INFO_LEN 16 + #define PCP_QOS_GROUP_1_QOS_INFO_DEFAULT 0x0 + +struct pcp_qos_group_1 { + a_uint32_t qos_info:16; + a_uint32_t _reserved0:16; +}; + +union pcp_qos_group_1_u { + a_uint32_t val; + struct pcp_qos_group_1 bf; +}; + +/*[register] FLOW_QOS_GROUP_0*/ +#define FLOW_QOS_GROUP_0 +#define FLOW_QOS_GROUP_0_ADDRESS 0xd00 +#define FLOW_QOS_GROUP_0_NUM 32 +#define FLOW_QOS_GROUP_0_INC 0x4 +#define FLOW_QOS_GROUP_0_TYPE REG_TYPE_RW +#define FLOW_QOS_GROUP_0_DEFAULT 0x0 + /*[field] QOS_INFO*/ + #define FLOW_QOS_GROUP_0_QOS_INFO + #define FLOW_QOS_GROUP_0_QOS_INFO_OFFSET 0 + #define FLOW_QOS_GROUP_0_QOS_INFO_LEN 16 + #define FLOW_QOS_GROUP_0_QOS_INFO_DEFAULT 0x0 + +struct flow_qos_group_0 { + a_uint32_t qos_info:16; + a_uint32_t _reserved0:16; +}; + +union flow_qos_group_0_u { + a_uint32_t val; + struct flow_qos_group_0 bf; +}; + +/*[register] FLOW_QOS_GROUP_1*/ +#define FLOW_QOS_GROUP_1 +#define FLOW_QOS_GROUP_1_ADDRESS 0xe00 +#define FLOW_QOS_GROUP_1_NUM 32 +#define FLOW_QOS_GROUP_1_INC 0x4 +#define FLOW_QOS_GROUP_1_TYPE REG_TYPE_RW +#define FLOW_QOS_GROUP_1_DEFAULT 0x0 + /*[field] QOS_INFO*/ + #define FLOW_QOS_GROUP_1_QOS_INFO + #define FLOW_QOS_GROUP_1_QOS_INFO_OFFSET 0 + #define FLOW_QOS_GROUP_1_QOS_INFO_LEN 16 + #define FLOW_QOS_GROUP_1_QOS_INFO_DEFAULT 0x0 + +struct flow_qos_group_1 { + a_uint32_t qos_info:16; + a_uint32_t _reserved0:16; +}; + +union flow_qos_group_1_u { + a_uint32_t val; + struct flow_qos_group_1 bf; +}; + +/*[register] DSCP_QOS_GROUP_0*/ +#define DSCP_QOS_GROUP_0 +#define DSCP_QOS_GROUP_0_ADDRESS 0x2000 +#define DSCP_QOS_GROUP_0_NUM 64 +#define DSCP_QOS_GROUP_0_INC 0x10 +#define DSCP_QOS_GROUP_0_TYPE REG_TYPE_RW +#define DSCP_QOS_GROUP_0_DEFAULT 0x0 + /*[field] QOS_INFO*/ + #define DSCP_QOS_GROUP_0_QOS_INFO + #define DSCP_QOS_GROUP_0_QOS_INFO_OFFSET 0 + #define DSCP_QOS_GROUP_0_QOS_INFO_LEN 16 + #define DSCP_QOS_GROUP_0_QOS_INFO_DEFAULT 0x0 + +struct dscp_qos_group_0 { + a_uint32_t qos_info:16; + a_uint32_t _reserved0:16; +}; + +union dscp_qos_group_0_u { + a_uint32_t val; + struct dscp_qos_group_0 bf; +}; + +/*[register] DSCP_QOS_GROUP_1*/ +#define DSCP_QOS_GROUP_1 +#define DSCP_QOS_GROUP_1_ADDRESS 0x2800 +#define DSCP_QOS_GROUP_1_NUM 64 +#define DSCP_QOS_GROUP_1_INC 0x10 +#define DSCP_QOS_GROUP_1_TYPE REG_TYPE_RW +#define DSCP_QOS_GROUP_1_DEFAULT 0x0 + /*[field] QOS_INFO*/ + #define DSCP_QOS_GROUP_1_QOS_INFO + #define DSCP_QOS_GROUP_1_QOS_INFO_OFFSET 0 + #define DSCP_QOS_GROUP_1_QOS_INFO_LEN 16 + #define DSCP_QOS_GROUP_1_QOS_INFO_DEFAULT 0x0 + +struct dscp_qos_group_1 { + a_uint32_t qos_info:16; + a_uint32_t _reserved0:16; +}; + +union dscp_qos_group_1_u { + a_uint32_t val; + struct dscp_qos_group_1 bf; +}; + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_reg_access.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_reg_access.h new file mode 100755 index 000000000..7b0f56a6f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_reg_access.h @@ -0,0 +1,54 @@ +/* + * 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 _HPPE_REG_ACCESS_H_ +#define _HPPE_REG_ACCESS_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "sw.h" + +#define IPE_L3_BASE_ADDR 0x200000 +#define QUEUE_MANAGER_BASE_ADDR 0x800000 +#define TRAFFIC_MANAGER_BASE_ADDR 0x400000 +#define INGRESS_POLICER_BASE_ADDR 0x100000 +#define INGRESS_VLAN_BASE_ADDR 0x00f000 +#define IPE_L2_BASE_ADDR 0x060000 +#define IPO_CSR_BASE_ADDR 0x0b0000 +#define IPR_CSR_BASE_ADDR 0x002000 +#define NSS_MAC_CSR_BASE_ADDR 0x001000 +#define NSS_PRX_CSR_BASE_ADDR 0x00b000 +#define NSS_PTX_CSR_BASE_ADDR 0x020000 +#define NSS_BM_CSR_BASE_ADDR 0x600000 +#define NSS_XGMAC_CSR_BASE_ADDR 0x003000 +#define NSS_GLOBAL_BASE_ADDR 0x0 +#define NSS_UNIPHY_BASE_ADDR 0x0 +#define NSS_LPI_BASE_ADDR 0x400 + +sw_error_t hppe_reg_get(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint32_t *val); +sw_error_t hppe_reg_set(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint32_t val); +sw_error_t hppe_reg_tbl_get(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint32_t *val, a_uint32_t num); +sw_error_t hppe_reg_tbl_set(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint32_t *val, a_uint32_t num); +sw_error_t hppe_uniphy_reg_get(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint32_t index, a_uint32_t *val); +sw_error_t hppe_uniphy_reg_set(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint32_t index, a_uint32_t val); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _HPPE_REG_ACCESS_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_rss.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_rss.h new file mode 100755 index 000000000..3be8a956a --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_rss.h @@ -0,0 +1,249 @@ +/* + * 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 + * @{ + */ +#ifndef _HPPE_RSS_H_ +#define _HPPE_RSS_H_ + +#define RSS_HASH_MIX_REG_MAX_ENTRY 11 +#define RSS_HASH_FIN_REG_MAX_ENTRY 5 +#define RSS_HASH_MIX_IPV4_REG_MAX_ENTRY 5 +#define RSS_HASH_FIN_IPV4_REG_MAX_ENTRY 5 + +sw_error_t +hppe_rss_hash_mask_reg_get( + a_uint32_t dev_id, + union rss_hash_mask_reg_u *value); + +sw_error_t +hppe_rss_hash_mask_reg_set( + a_uint32_t dev_id, + union rss_hash_mask_reg_u *value); + +sw_error_t +hppe_rss_hash_seed_reg_get( + a_uint32_t dev_id, + union rss_hash_seed_reg_u *value); + +sw_error_t +hppe_rss_hash_seed_reg_set( + a_uint32_t dev_id, + union rss_hash_seed_reg_u *value); + +sw_error_t +hppe_rss_hash_mix_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + union rss_hash_mix_reg_u *value); + +sw_error_t +hppe_rss_hash_mix_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + union rss_hash_mix_reg_u *value); + +sw_error_t +hppe_rss_hash_fin_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + union rss_hash_fin_reg_u *value); + +sw_error_t +hppe_rss_hash_fin_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + union rss_hash_fin_reg_u *value); + +sw_error_t +hppe_rss_hash_mask_ipv4_reg_get( + a_uint32_t dev_id, + union rss_hash_mask_ipv4_reg_u *value); + +sw_error_t +hppe_rss_hash_mask_ipv4_reg_set( + a_uint32_t dev_id, + union rss_hash_mask_ipv4_reg_u *value); + +sw_error_t +hppe_rss_hash_seed_ipv4_reg_get( + a_uint32_t dev_id, + union rss_hash_seed_ipv4_reg_u *value); + +sw_error_t +hppe_rss_hash_seed_ipv4_reg_set( + a_uint32_t dev_id, + union rss_hash_seed_ipv4_reg_u *value); + +sw_error_t +hppe_rss_hash_mix_ipv4_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + union rss_hash_mix_ipv4_reg_u *value); + +sw_error_t +hppe_rss_hash_mix_ipv4_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + union rss_hash_mix_ipv4_reg_u *value); + +sw_error_t +hppe_rss_hash_fin_ipv4_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + union rss_hash_fin_ipv4_reg_u *value); + +sw_error_t +hppe_rss_hash_fin_ipv4_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + union rss_hash_fin_ipv4_reg_u *value); + +sw_error_t +hppe_rss_hash_mask_reg_fragment_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_rss_hash_mask_reg_fragment_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_rss_hash_mask_reg_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_rss_hash_mask_reg_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_rss_hash_seed_reg_seed_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_rss_hash_seed_reg_seed_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_rss_hash_mix_reg_hash_mix_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rss_hash_mix_reg_hash_mix_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rss_hash_fin_reg_fin_outer_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rss_hash_fin_reg_fin_outer_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rss_hash_fin_reg_fin_inner_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rss_hash_fin_reg_fin_inner_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rss_hash_mask_ipv4_reg_fragment_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_rss_hash_mask_ipv4_reg_fragment_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_rss_hash_mask_ipv4_reg_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_rss_hash_mask_ipv4_reg_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_rss_hash_seed_ipv4_reg_seed_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_rss_hash_seed_ipv4_reg_seed_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_rss_hash_mix_ipv4_reg_hash_mix_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rss_hash_mix_ipv4_reg_hash_mix_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rss_hash_fin_ipv4_reg_fin_outer_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rss_hash_fin_ipv4_reg_fin_outer_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rss_hash_fin_ipv4_reg_fin_inner_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rss_hash_fin_ipv4_reg_fin_inner_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_rss_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_rss_reg.h new file mode 100755 index 000000000..189cb7b24 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_rss_reg.h @@ -0,0 +1,231 @@ +/* + * 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 + * @{ + */ +#ifndef HPPE_RSS_REG_H +#define HPPE_RSS_REG_H + +/*[register] RSS_HASH_MASK_REG*/ +#define RSS_HASH_MASK_REG +#define RSS_HASH_MASK_REG_ADDRESS 0x4318 +#define RSS_HASH_MASK_REG_NUM 1 +#define RSS_HASH_MASK_REG_INC 0x4 +#define RSS_HASH_MASK_REG_TYPE REG_TYPE_RW +#define RSS_HASH_MASK_REG_DEFAULT 0x0 + /*[field] MASK*/ + #define RSS_HASH_MASK_REG_MASK + #define RSS_HASH_MASK_REG_MASK_OFFSET 0 + #define RSS_HASH_MASK_REG_MASK_LEN 21 + #define RSS_HASH_MASK_REG_MASK_DEFAULT 0x0 + /*[field] FRAGMENT*/ + #define RSS_HASH_MASK_REG_FRAGMENT + #define RSS_HASH_MASK_REG_FRAGMENT_OFFSET 28 + #define RSS_HASH_MASK_REG_FRAGMENT_LEN 1 + #define RSS_HASH_MASK_REG_FRAGMENT_DEFAULT 0x0 + +struct rss_hash_mask_reg { + a_uint32_t mask:21; + a_uint32_t _reserved0:7; + a_uint32_t fragment:1; + a_uint32_t _reserved1:3; +}; + +union rss_hash_mask_reg_u { + a_uint32_t val; + struct rss_hash_mask_reg bf; +}; + +/*[register] RSS_HASH_SEED_REG*/ +#define RSS_HASH_SEED_REG +#define RSS_HASH_SEED_REG_ADDRESS 0x431c +#define RSS_HASH_SEED_REG_NUM 1 +#define RSS_HASH_SEED_REG_INC 0x4 +#define RSS_HASH_SEED_REG_TYPE REG_TYPE_RW +#define RSS_HASH_SEED_REG_DEFAULT 0x0 + /*[field] SEED*/ + #define RSS_HASH_SEED_REG_SEED + #define RSS_HASH_SEED_REG_SEED_OFFSET 0 + #define RSS_HASH_SEED_REG_SEED_LEN 32 + #define RSS_HASH_SEED_REG_SEED_DEFAULT 0x0 + +struct rss_hash_seed_reg { + a_uint32_t seed:32; +}; + +union rss_hash_seed_reg_u { + a_uint32_t val; + struct rss_hash_seed_reg bf; +}; + +/*[register] RSS_HASH_MIX_REG*/ +#define RSS_HASH_MIX_REG +#define RSS_HASH_MIX_REG_ADDRESS 0x4320 +#define RSS_HASH_MIX_REG_NUM 11 +#define RSS_HASH_MIX_REG_INC 0x4 +#define RSS_HASH_MIX_REG_TYPE REG_TYPE_RW +#define RSS_HASH_MIX_REG_DEFAULT 0x0 + /*[field] HASH_MIX*/ + #define RSS_HASH_MIX_REG_HASH_MIX + #define RSS_HASH_MIX_REG_HASH_MIX_OFFSET 0 + #define RSS_HASH_MIX_REG_HASH_MIX_LEN 5 + #define RSS_HASH_MIX_REG_HASH_MIX_DEFAULT 0x0 + +struct rss_hash_mix_reg { + a_uint32_t hash_mix:5; + a_uint32_t _reserved0:27; +}; + +union rss_hash_mix_reg_u { + a_uint32_t val; + struct rss_hash_mix_reg bf; +}; + +/*[register] RSS_HASH_FIN_REG*/ +#define RSS_HASH_FIN_REG +#define RSS_HASH_FIN_REG_ADDRESS 0x4350 +#define RSS_HASH_FIN_REG_NUM 5 +#define RSS_HASH_FIN_REG_INC 0x4 +#define RSS_HASH_FIN_REG_TYPE REG_TYPE_RW +#define RSS_HASH_FIN_REG_DEFAULT 0x0 + /*[field] FIN_INNER*/ + #define RSS_HASH_FIN_REG_FIN_INNER + #define RSS_HASH_FIN_REG_FIN_INNER_OFFSET 0 + #define RSS_HASH_FIN_REG_FIN_INNER_LEN 5 + #define RSS_HASH_FIN_REG_FIN_INNER_DEFAULT 0x0 + /*[field] FIN_OUTER*/ + #define RSS_HASH_FIN_REG_FIN_OUTER + #define RSS_HASH_FIN_REG_FIN_OUTER_OFFSET 5 + #define RSS_HASH_FIN_REG_FIN_OUTER_LEN 5 + #define RSS_HASH_FIN_REG_FIN_OUTER_DEFAULT 0x0 + +struct rss_hash_fin_reg { + a_uint32_t fin_inner:5; + a_uint32_t fin_outer:5; + a_uint32_t _reserved0:22; +}; + +union rss_hash_fin_reg_u { + a_uint32_t val; + struct rss_hash_fin_reg bf; +}; + +/*[register] RSS_HASH_MASK_IPV4_REG*/ +#define RSS_HASH_MASK_IPV4_REG +#define RSS_HASH_MASK_IPV4_REG_ADDRESS 0x4380 +#define RSS_HASH_MASK_IPV4_REG_NUM 1 +#define RSS_HASH_MASK_IPV4_REG_INC 0x4 +#define RSS_HASH_MASK_IPV4_REG_TYPE REG_TYPE_RW +#define RSS_HASH_MASK_IPV4_REG_DEFAULT 0x0 + /*[field] MASK*/ + #define RSS_HASH_MASK_IPV4_REG_MASK + #define RSS_HASH_MASK_IPV4_REG_MASK_OFFSET 0 + #define RSS_HASH_MASK_IPV4_REG_MASK_LEN 21 + #define RSS_HASH_MASK_IPV4_REG_MASK_DEFAULT 0x0 + /*[field] FRAGMENT*/ + #define RSS_HASH_MASK_IPV4_REG_FRAGMENT + #define RSS_HASH_MASK_IPV4_REG_FRAGMENT_OFFSET 28 + #define RSS_HASH_MASK_IPV4_REG_FRAGMENT_LEN 1 + #define RSS_HASH_MASK_IPV4_REG_FRAGMENT_DEFAULT 0x0 + +struct rss_hash_mask_ipv4_reg { + a_uint32_t mask:21; + a_uint32_t _reserved0:7; + a_uint32_t fragment:1; + a_uint32_t _reserved1:3; +}; + +union rss_hash_mask_ipv4_reg_u { + a_uint32_t val; + struct rss_hash_mask_ipv4_reg bf; +}; + +/*[register] RSS_HASH_SEED_IPV4_REG*/ +#define RSS_HASH_SEED_IPV4_REG +#define RSS_HASH_SEED_IPV4_REG_ADDRESS 0x4384 +#define RSS_HASH_SEED_IPV4_REG_NUM 1 +#define RSS_HASH_SEED_IPV4_REG_INC 0x4 +#define RSS_HASH_SEED_IPV4_REG_TYPE REG_TYPE_RW +#define RSS_HASH_SEED_IPV4_REG_DEFAULT 0x0 + /*[field] SEED*/ + #define RSS_HASH_SEED_IPV4_REG_SEED + #define RSS_HASH_SEED_IPV4_REG_SEED_OFFSET 0 + #define RSS_HASH_SEED_IPV4_REG_SEED_LEN 32 + #define RSS_HASH_SEED_IPV4_REG_SEED_DEFAULT 0x0 + +struct rss_hash_seed_ipv4_reg { + a_uint32_t seed:32; +}; + +union rss_hash_seed_ipv4_reg_u { + a_uint32_t val; + struct rss_hash_seed_ipv4_reg bf; +}; + +/*[register] RSS_HASH_MIX_IPV4_REG*/ +#define RSS_HASH_MIX_IPV4_REG +#define RSS_HASH_MIX_IPV4_REG_ADDRESS 0x4390 +#define RSS_HASH_MIX_IPV4_REG_NUM 5 +#define RSS_HASH_MIX_IPV4_REG_INC 0x4 +#define RSS_HASH_MIX_IPV4_REG_TYPE REG_TYPE_RW +#define RSS_HASH_MIX_IPV4_REG_DEFAULT 0x0 + /*[field] HASH_MIX*/ + #define RSS_HASH_MIX_IPV4_REG_HASH_MIX + #define RSS_HASH_MIX_IPV4_REG_HASH_MIX_OFFSET 0 + #define RSS_HASH_MIX_IPV4_REG_HASH_MIX_LEN 5 + #define RSS_HASH_MIX_IPV4_REG_HASH_MIX_DEFAULT 0x0 + +struct rss_hash_mix_ipv4_reg { + a_uint32_t hash_mix:5; + a_uint32_t _reserved0:27; +}; + +union rss_hash_mix_ipv4_reg_u { + a_uint32_t val; + struct rss_hash_mix_ipv4_reg bf; +}; + +/*[register] RSS_HASH_FIN_IPV4_REG*/ +#define RSS_HASH_FIN_IPV4_REG +#define RSS_HASH_FIN_IPV4_REG_ADDRESS 0x43b0 +#define RSS_HASH_FIN_IPV4_REG_NUM 5 +#define RSS_HASH_FIN_IPV4_REG_INC 0x4 +#define RSS_HASH_FIN_IPV4_REG_TYPE REG_TYPE_RW +#define RSS_HASH_FIN_IPV4_REG_DEFAULT 0x0 + /*[field] FIN_INNER*/ + #define RSS_HASH_FIN_IPV4_REG_FIN_INNER + #define RSS_HASH_FIN_IPV4_REG_FIN_INNER_OFFSET 0 + #define RSS_HASH_FIN_IPV4_REG_FIN_INNER_LEN 5 + #define RSS_HASH_FIN_IPV4_REG_FIN_INNER_DEFAULT 0x0 + /*[field] FIN_OUTER*/ + #define RSS_HASH_FIN_IPV4_REG_FIN_OUTER + #define RSS_HASH_FIN_IPV4_REG_FIN_OUTER_OFFSET 5 + #define RSS_HASH_FIN_IPV4_REG_FIN_OUTER_LEN 5 + #define RSS_HASH_FIN_IPV4_REG_FIN_OUTER_DEFAULT 0x0 + +struct rss_hash_fin_ipv4_reg { + a_uint32_t fin_inner:5; + a_uint32_t fin_outer:5; + a_uint32_t _reserved0:22; +}; + +union rss_hash_fin_ipv4_reg_u { + a_uint32_t val; + struct rss_hash_fin_ipv4_reg bf; +}; + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_sec.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_sec.h new file mode 100755 index 000000000..e54618972 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_sec.h @@ -0,0 +1,416 @@ +/* + * 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 + * @{ + */ +#ifndef _HPPE_SEC_H_ +#define _HPPE_SEC_H_ + +#define L3_EXCEPTION_CMD_MAX_ENTRY 72 +#define L3_EXP_L3_ONLY_CTRL_MAX_ENTRY 72 +#define L3_EXP_L2_ONLY_CTRL_MAX_ENTRY 72 +#define L3_EXP_L2_FLOW_CTRL_MAX_ENTRY 72 +#define L3_EXP_L3_FLOW_CTRL_MAX_ENTRY 72 +#define L3_EXP_MULTICAST_CTRL_MAX_ENTRY 72 + +sw_error_t +hppe_l3_exception_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + union l3_exception_cmd_u *value); + +sw_error_t +hppe_l3_exception_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + union l3_exception_cmd_u *value); + +sw_error_t +hppe_l3_exp_l3_only_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l3_exp_l3_only_ctrl_u *value); + +sw_error_t +hppe_l3_exp_l3_only_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l3_exp_l3_only_ctrl_u *value); + +sw_error_t +hppe_l3_exp_l2_only_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l3_exp_l2_only_ctrl_u *value); + +sw_error_t +hppe_l3_exp_l2_only_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l3_exp_l2_only_ctrl_u *value); + +sw_error_t +hppe_l3_exp_l2_flow_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l3_exp_l2_flow_ctrl_u *value); + +sw_error_t +hppe_l3_exp_l2_flow_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l3_exp_l2_flow_ctrl_u *value); + +sw_error_t +hppe_l3_exp_l3_flow_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l3_exp_l3_flow_ctrl_u *value); + +sw_error_t +hppe_l3_exp_l3_flow_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l3_exp_l3_flow_ctrl_u *value); + +sw_error_t +hppe_l3_exp_multicast_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l3_exp_multicast_ctrl_u *value); + +sw_error_t +hppe_l3_exp_multicast_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l3_exp_multicast_ctrl_u *value); + +sw_error_t +hppe_l3_exception_cmd_l3_excep_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_exception_cmd_l3_excep_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_exception_cmd_de_acce_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_exception_cmd_de_acce_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_exp_l3_only_ctrl_excep_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_exp_l3_only_ctrl_excep_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_exp_l2_only_ctrl_excep_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_exp_l2_only_ctrl_excep_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_exp_l2_flow_ctrl_excep_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_exp_l2_flow_ctrl_excep_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_exp_l3_flow_ctrl_excep_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_exp_l3_flow_ctrl_excep_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_exp_multicast_ctrl_excep_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l3_exp_multicast_ctrl_excep_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l3_exception_parsing_ctrl_reg_get( + a_uint32_t dev_id, + union l3_exception_parsing_ctrl_reg_u *value); + +sw_error_t +hppe_l3_exception_parsing_ctrl_reg_set( + a_uint32_t dev_id, + union l3_exception_parsing_ctrl_reg_u *value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_0_reg_get( + a_uint32_t dev_id, + union l4_exception_parsing_ctrl_0_reg_u *value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_0_reg_set( + a_uint32_t dev_id, + union l4_exception_parsing_ctrl_0_reg_u *value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_1_reg_get( + a_uint32_t dev_id, + union l4_exception_parsing_ctrl_1_reg_u *value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_1_reg_set( + a_uint32_t dev_id, + union l4_exception_parsing_ctrl_1_reg_u *value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_2_reg_get( + a_uint32_t dev_id, + union l4_exception_parsing_ctrl_2_reg_u *value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_2_reg_set( + a_uint32_t dev_id, + union l4_exception_parsing_ctrl_2_reg_u *value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_3_reg_get( + a_uint32_t dev_id, + union l4_exception_parsing_ctrl_3_reg_u *value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_3_reg_set( + a_uint32_t dev_id, + union l4_exception_parsing_ctrl_3_reg_u *value); + +sw_error_t +hppe_l3_exception_parsing_ctrl_reg_small_hop_limit_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l3_exception_parsing_ctrl_reg_small_hop_limit_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l3_exception_parsing_ctrl_reg_small_ttl_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l3_exception_parsing_ctrl_reg_small_ttl_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_0_reg_tcp_flags0_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_0_reg_tcp_flags0_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_0_reg_tcp_flags0_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_0_reg_tcp_flags0_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_0_reg_tcp_flags1_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_0_reg_tcp_flags1_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_0_reg_tcp_flags1_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_0_reg_tcp_flags1_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_1_reg_tcp_flags2_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_1_reg_tcp_flags2_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_1_reg_tcp_flags2_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_1_reg_tcp_flags2_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_1_reg_tcp_flags3_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_1_reg_tcp_flags3_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_1_reg_tcp_flags3_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_1_reg_tcp_flags3_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_2_reg_tcp_flags4_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_2_reg_tcp_flags4_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_2_reg_tcp_flags4_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_2_reg_tcp_flags4_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_2_reg_tcp_flags5_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_2_reg_tcp_flags5_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_2_reg_tcp_flags5_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_2_reg_tcp_flags5_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_3_reg_tcp_flags6_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_3_reg_tcp_flags6_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_3_reg_tcp_flags6_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_3_reg_tcp_flags6_mask_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_3_reg_tcp_flags7_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_3_reg_tcp_flags7_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_3_reg_tcp_flags7_mask_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_l4_exception_parsing_ctrl_3_reg_tcp_flags7_mask_set( + a_uint32_t dev_id, + unsigned int value); + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_sec_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_sec_reg.h new file mode 100755 index 000000000..d2ab84109 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_sec_reg.h @@ -0,0 +1,373 @@ +/* + * 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 + * @{ + */ +#ifndef _HPPE_SEC_REG_H_ +#define _HPPE_SEC_REG_H_ + + +/*[register] L3_EXCEPTION_CMD*/ +#define L3_EXCEPTION_CMD +#define L3_EXCEPTION_CMD_ADDRESS 0x544 +#define L3_EXCEPTION_CMD_NUM 72 +#define L3_EXCEPTION_CMD_INC 0x4 +#define L3_EXCEPTION_CMD_TYPE REG_TYPE_RW +#define L3_EXCEPTION_CMD_DEFAULT 0x0 + /*[field] L3_EXCEP_CMD*/ + #define L3_EXCEPTION_CMD_L3_EXCEP_CMD + #define L3_EXCEPTION_CMD_L3_EXCEP_CMD_OFFSET 0 + #define L3_EXCEPTION_CMD_L3_EXCEP_CMD_LEN 2 + #define L3_EXCEPTION_CMD_L3_EXCEP_CMD_DEFAULT 0x0 + /*[field] DE_ACCE*/ + #define L3_EXCEPTION_CMD_DE_ACCE + #define L3_EXCEPTION_CMD_DE_ACCE_OFFSET 2 + #define L3_EXCEPTION_CMD_DE_ACCE_LEN 1 + #define L3_EXCEPTION_CMD_DE_ACCE_DEFAULT 0x0 + +struct l3_exception_cmd { + a_uint32_t l3_excep_cmd:2; + a_uint32_t de_acce:1; + a_uint32_t _reserved0:29; +}; + +union l3_exception_cmd_u { + a_uint32_t val; + struct l3_exception_cmd bf; +}; + +/*[register] L3_EXP_L3_ONLY_CTRL*/ +#define L3_EXP_L3_ONLY_CTRL +#define L3_EXP_L3_ONLY_CTRL_ADDRESS 0x664 +#define L3_EXP_L3_ONLY_CTRL_NUM 72 +#define L3_EXP_L3_ONLY_CTRL_INC 0x4 +#define L3_EXP_L3_ONLY_CTRL_TYPE REG_TYPE_RW +#define L3_EXP_L3_ONLY_CTRL_DEFAULT 0x0 + /*[field] EXCEP_EN*/ + #define L3_EXP_L3_ONLY_CTRL_EXCEP_EN + #define L3_EXP_L3_ONLY_CTRL_EXCEP_EN_OFFSET 0 + #define L3_EXP_L3_ONLY_CTRL_EXCEP_EN_LEN 1 + #define L3_EXP_L3_ONLY_CTRL_EXCEP_EN_DEFAULT 0x0 + +struct l3_exp_l3_only_ctrl { + a_uint32_t excep_en:1; + a_uint32_t _reserved0:31; +}; + +union l3_exp_l3_only_ctrl_u { + a_uint32_t val; + struct l3_exp_l3_only_ctrl bf; +}; + +/*[register] L3_EXP_L2_ONLY_CTRL*/ +#define L3_EXP_L2_ONLY_CTRL +#define L3_EXP_L2_ONLY_CTRL_ADDRESS 0x784 +#define L3_EXP_L2_ONLY_CTRL_NUM 72 +#define L3_EXP_L2_ONLY_CTRL_INC 0x4 +#define L3_EXP_L2_ONLY_CTRL_TYPE REG_TYPE_RW +#define L3_EXP_L2_ONLY_CTRL_DEFAULT 0x0 + /*[field] EXCEP_EN*/ + #define L3_EXP_L2_ONLY_CTRL_EXCEP_EN + #define L3_EXP_L2_ONLY_CTRL_EXCEP_EN_OFFSET 0 + #define L3_EXP_L2_ONLY_CTRL_EXCEP_EN_LEN 1 + #define L3_EXP_L2_ONLY_CTRL_EXCEP_EN_DEFAULT 0x0 + +struct l3_exp_l2_only_ctrl { + a_uint32_t excep_en:1; + a_uint32_t _reserved0:31; +}; + +union l3_exp_l2_only_ctrl_u { + a_uint32_t val; + struct l3_exp_l2_only_ctrl bf; +}; + +/*[register] L3_EXP_L2_FLOW_CTRL*/ +#define L3_EXP_L2_FLOW_CTRL +#define L3_EXP_L2_FLOW_CTRL_ADDRESS 0x8a4 +#define L3_EXP_L2_FLOW_CTRL_NUM 72 +#define L3_EXP_L2_FLOW_CTRL_INC 0x4 +#define L3_EXP_L2_FLOW_CTRL_TYPE REG_TYPE_RW +#define L3_EXP_L2_FLOW_CTRL_DEFAULT 0x0 + /*[field] EXCEP_EN*/ + #define L3_EXP_L2_FLOW_CTRL_EXCEP_EN + #define L3_EXP_L2_FLOW_CTRL_EXCEP_EN_OFFSET 0 + #define L3_EXP_L2_FLOW_CTRL_EXCEP_EN_LEN 1 + #define L3_EXP_L2_FLOW_CTRL_EXCEP_EN_DEFAULT 0x0 + +struct l3_exp_l2_flow_ctrl { + a_uint32_t excep_en:1; + a_uint32_t _reserved0:31; +}; + +union l3_exp_l2_flow_ctrl_u { + a_uint32_t val; + struct l3_exp_l2_flow_ctrl bf; +}; + +/*[register] L3_EXP_L3_FLOW_CTRL*/ +#define L3_EXP_L3_FLOW_CTRL +#define L3_EXP_L3_FLOW_CTRL_ADDRESS 0x9c4 +#define L3_EXP_L3_FLOW_CTRL_NUM 72 +#define L3_EXP_L3_FLOW_CTRL_INC 0x4 +#define L3_EXP_L3_FLOW_CTRL_TYPE REG_TYPE_RW +#define L3_EXP_L3_FLOW_CTRL_DEFAULT 0x0 + /*[field] EXCEP_EN*/ + #define L3_EXP_L3_FLOW_CTRL_EXCEP_EN + #define L3_EXP_L3_FLOW_CTRL_EXCEP_EN_OFFSET 0 + #define L3_EXP_L3_FLOW_CTRL_EXCEP_EN_LEN 1 + #define L3_EXP_L3_FLOW_CTRL_EXCEP_EN_DEFAULT 0x0 + +struct l3_exp_l3_flow_ctrl { + a_uint32_t excep_en:1; + a_uint32_t _reserved0:31; +}; + +union l3_exp_l3_flow_ctrl_u { + a_uint32_t val; + struct l3_exp_l3_flow_ctrl bf; +}; + +/*[register] L3_EXP_MULTICAST_CTRL*/ +#define L3_EXP_MULTICAST_CTRL +#define L3_EXP_MULTICAST_CTRL_ADDRESS 0xae4 +#define L3_EXP_MULTICAST_CTRL_NUM 72 +#define L3_EXP_MULTICAST_CTRL_INC 0x4 +#define L3_EXP_MULTICAST_CTRL_TYPE REG_TYPE_RW +#define L3_EXP_MULTICAST_CTRL_DEFAULT 0x0 + /*[field] EXCEP_EN*/ + #define L3_EXP_MULTICAST_CTRL_EXCEP_EN + #define L3_EXP_MULTICAST_CTRL_EXCEP_EN_OFFSET 0 + #define L3_EXP_MULTICAST_CTRL_EXCEP_EN_LEN 1 + #define L3_EXP_MULTICAST_CTRL_EXCEP_EN_DEFAULT 0x0 + +struct l3_exp_multicast_ctrl { + a_uint32_t excep_en:1; + a_uint32_t _reserved0:31; +}; + +union l3_exp_multicast_ctrl_u { + a_uint32_t val; + struct l3_exp_multicast_ctrl bf; +}; + +/*[register] L3_EXCEPTION_PARSING_CTRL_REG*/ +#define L3_EXCEPTION_PARSING_CTRL_REG +#define L3_EXCEPTION_PARSING_CTRL_REG_ADDRESS 0x24 +#define L3_EXCEPTION_PARSING_CTRL_REG_NUM 1 +#define L3_EXCEPTION_PARSING_CTRL_REG_INC 0x4 +#define L3_EXCEPTION_PARSING_CTRL_REG_TYPE REG_TYPE_RW +#define L3_EXCEPTION_PARSING_CTRL_REG_DEFAULT 0x0 + /*[field] SMALL_TTL*/ + #define L3_EXCEPTION_PARSING_CTRL_REG_SMALL_TTL + #define L3_EXCEPTION_PARSING_CTRL_REG_SMALL_TTL_OFFSET 0 + #define L3_EXCEPTION_PARSING_CTRL_REG_SMALL_TTL_LEN 8 + #define L3_EXCEPTION_PARSING_CTRL_REG_SMALL_TTL_DEFAULT 0x0 + /*[field] SMALL_HOP_LIMIT*/ + #define L3_EXCEPTION_PARSING_CTRL_REG_SMALL_HOP_LIMIT + #define L3_EXCEPTION_PARSING_CTRL_REG_SMALL_HOP_LIMIT_OFFSET 8 + #define L3_EXCEPTION_PARSING_CTRL_REG_SMALL_HOP_LIMIT_LEN 8 + #define L3_EXCEPTION_PARSING_CTRL_REG_SMALL_HOP_LIMIT_DEFAULT 0x0 + +struct l3_exception_parsing_ctrl_reg { + a_uint32_t small_ttl:8; + a_uint32_t small_hop_limit:8; + a_uint32_t _reserved0:16; +}; + +union l3_exception_parsing_ctrl_reg_u { + a_uint32_t val; + struct l3_exception_parsing_ctrl_reg bf; +}; + +/*[register] L4_EXCEPTION_PARSING_CTRL_0_REG*/ +#define L4_EXCEPTION_PARSING_CTRL_0_REG +#define L4_EXCEPTION_PARSING_CTRL_0_REG_ADDRESS 0x28 +#define L4_EXCEPTION_PARSING_CTRL_0_REG_NUM 1 +#define L4_EXCEPTION_PARSING_CTRL_0_REG_INC 0x4 +#define L4_EXCEPTION_PARSING_CTRL_0_REG_TYPE REG_TYPE_RW +#define L4_EXCEPTION_PARSING_CTRL_0_REG_DEFAULT 0x0 + /*[field] TCP_FLAGS0*/ + #define L4_EXCEPTION_PARSING_CTRL_0_REG_TCP_FLAGS0 + #define L4_EXCEPTION_PARSING_CTRL_0_REG_TCP_FLAGS0_OFFSET 0 + #define L4_EXCEPTION_PARSING_CTRL_0_REG_TCP_FLAGS0_LEN 6 + #define L4_EXCEPTION_PARSING_CTRL_0_REG_TCP_FLAGS0_DEFAULT 0x0 + /*[field] TCP_FLAGS0_MASK*/ + #define L4_EXCEPTION_PARSING_CTRL_0_REG_TCP_FLAGS0_MASK + #define L4_EXCEPTION_PARSING_CTRL_0_REG_TCP_FLAGS0_MASK_OFFSET 8 + #define L4_EXCEPTION_PARSING_CTRL_0_REG_TCP_FLAGS0_MASK_LEN 6 + #define L4_EXCEPTION_PARSING_CTRL_0_REG_TCP_FLAGS0_MASK_DEFAULT 0x0 + /*[field] TCP_FLAGS1*/ + #define L4_EXCEPTION_PARSING_CTRL_0_REG_TCP_FLAGS1 + #define L4_EXCEPTION_PARSING_CTRL_0_REG_TCP_FLAGS1_OFFSET 16 + #define L4_EXCEPTION_PARSING_CTRL_0_REG_TCP_FLAGS1_LEN 6 + #define L4_EXCEPTION_PARSING_CTRL_0_REG_TCP_FLAGS1_DEFAULT 0x0 + /*[field] TCP_FLAGS1_MASK*/ + #define L4_EXCEPTION_PARSING_CTRL_0_REG_TCP_FLAGS1_MASK + #define L4_EXCEPTION_PARSING_CTRL_0_REG_TCP_FLAGS1_MASK_OFFSET 24 + #define L4_EXCEPTION_PARSING_CTRL_0_REG_TCP_FLAGS1_MASK_LEN 6 + #define L4_EXCEPTION_PARSING_CTRL_0_REG_TCP_FLAGS1_MASK_DEFAULT 0x0 + +struct l4_exception_parsing_ctrl_0_reg { + a_uint32_t tcp_flags0:6; + a_uint32_t _reserved0:2; + a_uint32_t tcp_flags0_mask:6; + a_uint32_t _reserved1:2; + a_uint32_t tcp_flags1:6; + a_uint32_t _reserved2:2; + a_uint32_t tcp_flags1_mask:6; + a_uint32_t _reserved3:2; +}; + +union l4_exception_parsing_ctrl_0_reg_u { + a_uint32_t val; + struct l4_exception_parsing_ctrl_0_reg bf; +}; + +/*[register] L4_EXCEPTION_PARSING_CTRL_1_REG*/ +#define L4_EXCEPTION_PARSING_CTRL_1_REG +#define L4_EXCEPTION_PARSING_CTRL_1_REG_ADDRESS 0x2c +#define L4_EXCEPTION_PARSING_CTRL_1_REG_NUM 1 +#define L4_EXCEPTION_PARSING_CTRL_1_REG_INC 0x4 +#define L4_EXCEPTION_PARSING_CTRL_1_REG_TYPE REG_TYPE_RW +#define L4_EXCEPTION_PARSING_CTRL_1_REG_DEFAULT 0x0 + /*[field] TCP_FLAGS2*/ + #define L4_EXCEPTION_PARSING_CTRL_1_REG_TCP_FLAGS2 + #define L4_EXCEPTION_PARSING_CTRL_1_REG_TCP_FLAGS2_OFFSET 0 + #define L4_EXCEPTION_PARSING_CTRL_1_REG_TCP_FLAGS2_LEN 6 + #define L4_EXCEPTION_PARSING_CTRL_1_REG_TCP_FLAGS2_DEFAULT 0x0 + /*[field] TCP_FLAGS2_MASK*/ + #define L4_EXCEPTION_PARSING_CTRL_1_REG_TCP_FLAGS2_MASK + #define L4_EXCEPTION_PARSING_CTRL_1_REG_TCP_FLAGS2_MASK_OFFSET 8 + #define L4_EXCEPTION_PARSING_CTRL_1_REG_TCP_FLAGS2_MASK_LEN 6 + #define L4_EXCEPTION_PARSING_CTRL_1_REG_TCP_FLAGS2_MASK_DEFAULT 0x0 + /*[field] TCP_FLAGS3*/ + #define L4_EXCEPTION_PARSING_CTRL_1_REG_TCP_FLAGS3 + #define L4_EXCEPTION_PARSING_CTRL_1_REG_TCP_FLAGS3_OFFSET 16 + #define L4_EXCEPTION_PARSING_CTRL_1_REG_TCP_FLAGS3_LEN 6 + #define L4_EXCEPTION_PARSING_CTRL_1_REG_TCP_FLAGS3_DEFAULT 0x0 + /*[field] TCP_FLAGS3_MASK*/ + #define L4_EXCEPTION_PARSING_CTRL_1_REG_TCP_FLAGS3_MASK + #define L4_EXCEPTION_PARSING_CTRL_1_REG_TCP_FLAGS3_MASK_OFFSET 24 + #define L4_EXCEPTION_PARSING_CTRL_1_REG_TCP_FLAGS3_MASK_LEN 6 + #define L4_EXCEPTION_PARSING_CTRL_1_REG_TCP_FLAGS3_MASK_DEFAULT 0x0 + +struct l4_exception_parsing_ctrl_1_reg { + a_uint32_t tcp_flags2:6; + a_uint32_t _reserved0:2; + a_uint32_t tcp_flags2_mask:6; + a_uint32_t _reserved1:2; + a_uint32_t tcp_flags3:6; + a_uint32_t _reserved2:2; + a_uint32_t tcp_flags3_mask:6; + a_uint32_t _reserved3:2; +}; + +union l4_exception_parsing_ctrl_1_reg_u { + a_uint32_t val; + struct l4_exception_parsing_ctrl_1_reg bf; +}; + +/*[register] L4_EXCEPTION_PARSING_CTRL_2_REG*/ +#define L4_EXCEPTION_PARSING_CTRL_2_REG +#define L4_EXCEPTION_PARSING_CTRL_2_REG_ADDRESS 0x30 +#define L4_EXCEPTION_PARSING_CTRL_2_REG_NUM 1 +#define L4_EXCEPTION_PARSING_CTRL_2_REG_INC 0x4 +#define L4_EXCEPTION_PARSING_CTRL_2_REG_TYPE REG_TYPE_RW +#define L4_EXCEPTION_PARSING_CTRL_2_REG_DEFAULT 0x0 + /*[field] TCP_FLAGS4*/ + #define L4_EXCEPTION_PARSING_CTRL_2_REG_TCP_FLAGS4 + #define L4_EXCEPTION_PARSING_CTRL_2_REG_TCP_FLAGS4_OFFSET 0 + #define L4_EXCEPTION_PARSING_CTRL_2_REG_TCP_FLAGS4_LEN 6 + #define L4_EXCEPTION_PARSING_CTRL_2_REG_TCP_FLAGS4_DEFAULT 0x0 + /*[field] TCP_FLAGS4_MASK*/ + #define L4_EXCEPTION_PARSING_CTRL_2_REG_TCP_FLAGS4_MASK + #define L4_EXCEPTION_PARSING_CTRL_2_REG_TCP_FLAGS4_MASK_OFFSET 8 + #define L4_EXCEPTION_PARSING_CTRL_2_REG_TCP_FLAGS4_MASK_LEN 6 + #define L4_EXCEPTION_PARSING_CTRL_2_REG_TCP_FLAGS4_MASK_DEFAULT 0x0 + /*[field] TCP_FLAGS5*/ + #define L4_EXCEPTION_PARSING_CTRL_2_REG_TCP_FLAGS5 + #define L4_EXCEPTION_PARSING_CTRL_2_REG_TCP_FLAGS5_OFFSET 16 + #define L4_EXCEPTION_PARSING_CTRL_2_REG_TCP_FLAGS5_LEN 6 + #define L4_EXCEPTION_PARSING_CTRL_2_REG_TCP_FLAGS5_DEFAULT 0x0 + /*[field] TCP_FLAGS5_MASK*/ + #define L4_EXCEPTION_PARSING_CTRL_2_REG_TCP_FLAGS5_MASK + #define L4_EXCEPTION_PARSING_CTRL_2_REG_TCP_FLAGS5_MASK_OFFSET 24 + #define L4_EXCEPTION_PARSING_CTRL_2_REG_TCP_FLAGS5_MASK_LEN 6 + #define L4_EXCEPTION_PARSING_CTRL_2_REG_TCP_FLAGS5_MASK_DEFAULT 0x0 + +struct l4_exception_parsing_ctrl_2_reg { + a_uint32_t tcp_flags4:6; + a_uint32_t _reserved0:2; + a_uint32_t tcp_flags4_mask:6; + a_uint32_t _reserved1:2; + a_uint32_t tcp_flags5:6; + a_uint32_t _reserved2:2; + a_uint32_t tcp_flags5_mask:6; + a_uint32_t _reserved3:2; +}; + +union l4_exception_parsing_ctrl_2_reg_u { + a_uint32_t val; + struct l4_exception_parsing_ctrl_2_reg bf; +}; + +/*[register] L4_EXCEPTION_PARSING_CTRL_3_REG*/ +#define L4_EXCEPTION_PARSING_CTRL_3_REG +#define L4_EXCEPTION_PARSING_CTRL_3_REG_ADDRESS 0x34 +#define L4_EXCEPTION_PARSING_CTRL_3_REG_NUM 1 +#define L4_EXCEPTION_PARSING_CTRL_3_REG_INC 0x4 +#define L4_EXCEPTION_PARSING_CTRL_3_REG_TYPE REG_TYPE_RW +#define L4_EXCEPTION_PARSING_CTRL_3_REG_DEFAULT 0x0 + /*[field] TCP_FLAGS6*/ + #define L4_EXCEPTION_PARSING_CTRL_3_REG_TCP_FLAGS6 + #define L4_EXCEPTION_PARSING_CTRL_3_REG_TCP_FLAGS6_OFFSET 0 + #define L4_EXCEPTION_PARSING_CTRL_3_REG_TCP_FLAGS6_LEN 6 + #define L4_EXCEPTION_PARSING_CTRL_3_REG_TCP_FLAGS6_DEFAULT 0x0 + /*[field] TCP_FLAGS6_MASK*/ + #define L4_EXCEPTION_PARSING_CTRL_3_REG_TCP_FLAGS6_MASK + #define L4_EXCEPTION_PARSING_CTRL_3_REG_TCP_FLAGS6_MASK_OFFSET 8 + #define L4_EXCEPTION_PARSING_CTRL_3_REG_TCP_FLAGS6_MASK_LEN 6 + #define L4_EXCEPTION_PARSING_CTRL_3_REG_TCP_FLAGS6_MASK_DEFAULT 0x0 + /*[field] TCP_FLAGS7*/ + #define L4_EXCEPTION_PARSING_CTRL_3_REG_TCP_FLAGS7 + #define L4_EXCEPTION_PARSING_CTRL_3_REG_TCP_FLAGS7_OFFSET 16 + #define L4_EXCEPTION_PARSING_CTRL_3_REG_TCP_FLAGS7_LEN 6 + #define L4_EXCEPTION_PARSING_CTRL_3_REG_TCP_FLAGS7_DEFAULT 0x0 + /*[field] TCP_FLAGS7_MASK*/ + #define L4_EXCEPTION_PARSING_CTRL_3_REG_TCP_FLAGS7_MASK + #define L4_EXCEPTION_PARSING_CTRL_3_REG_TCP_FLAGS7_MASK_OFFSET 24 + #define L4_EXCEPTION_PARSING_CTRL_3_REG_TCP_FLAGS7_MASK_LEN 6 + #define L4_EXCEPTION_PARSING_CTRL_3_REG_TCP_FLAGS7_MASK_DEFAULT 0x0 + +struct l4_exception_parsing_ctrl_3_reg { + a_uint32_t tcp_flags6:6; + a_uint32_t _reserved0:2; + a_uint32_t tcp_flags6_mask:6; + a_uint32_t _reserved1:2; + a_uint32_t tcp_flags7:6; + a_uint32_t _reserved2:2; + a_uint32_t tcp_flags7_mask:6; + a_uint32_t _reserved3:2; +}; + +union l4_exception_parsing_ctrl_3_reg_u { + a_uint32_t val; + struct l4_exception_parsing_ctrl_3_reg bf; +}; + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_servcode.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_servcode.h new file mode 100755 index 000000000..bbeda36dc --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_servcode.h @@ -0,0 +1,220 @@ +/* + * 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 + * @{ + */ +#ifndef _HPPE_SERVCODE_H_ +#define _HPPE_SERVCODE_H_ + +#define IN_L2_SERVICE_TBL_MAX_ENTRY 256 +#define EG_SERVICE_TBL_MAX_ENTRY 256 + +sw_error_t +hppe_service_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union service_tbl_u *value); + +sw_error_t +hppe_service_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union service_tbl_u *value); + +sw_error_t +hppe_service_tbl_rx_counting_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_service_tbl_rx_counting_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_service_tbl_bypass_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_service_tbl_bypass_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_l2_service_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union in_l2_service_tbl_u *value); + +sw_error_t +hppe_in_l2_service_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union in_l2_service_tbl_u *value); + +sw_error_t +hppe_in_l2_service_tbl_direction_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_l2_service_tbl_direction_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_l2_service_tbl_rx_cnt_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_l2_service_tbl_rx_cnt_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_l2_service_tbl_tx_cnt_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_l2_service_tbl_tx_cnt_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_l2_service_tbl_bypass_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_l2_service_tbl_bypass_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_l2_service_tbl_dst_port_id_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_l2_service_tbl_dst_port_id_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_in_l2_service_tbl_dst_port_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_in_l2_service_tbl_dst_port_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + + sw_error_t +hppe_eg_service_tbl_next_service_code_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_service_tbl_next_service_code_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_service_tbl_tx_counting_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_service_tbl_tx_counting_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_service_tbl_field_update_action_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_service_tbl_field_update_action_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_service_tbl_offset_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_service_tbl_offset_sel_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_service_tbl_hw_services_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_service_tbl_hw_services_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_service_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union eg_service_tbl_u *value); + +sw_error_t +hppe_eg_service_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union eg_service_tbl_u *value); + + +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_servcode_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_servcode_reg.h new file mode 100755 index 000000000..82f794b9f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_servcode_reg.h @@ -0,0 +1,150 @@ +/* + * 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 + * @{ + */ +#ifndef HPPE_SERVCODE_REG_H +#define HPPE_SERVCODE_REG_H + +/*[table] SERVICE_TBL*/ +#define SERVICE_TBL +#define SERVICE_TBL_ADDRESS 0x6000 +#define SERVICE_TBL_NUM 256 +#define SERVICE_TBL_INC 0x10 +#define SERVICE_TBL_TYPE REG_TYPE_RW +#define SERVICE_TBL_DEFAULT 0x0 + /*[field] BYPASS_BITMAP*/ + #define SERVICE_TBL_BYPASS_BITMAP + #define SERVICE_TBL_BYPASS_BITMAP_OFFSET 0 + #define SERVICE_TBL_BYPASS_BITMAP_LEN 32 + #define SERVICE_TBL_BYPASS_BITMAP_DEFAULT 0x0 + /*[field] RX_COUNTING_EN*/ + #define SERVICE_TBL_RX_COUNTING_EN + #define SERVICE_TBL_RX_COUNTING_EN_OFFSET 32 + #define SERVICE_TBL_RX_COUNTING_EN_LEN 1 + #define SERVICE_TBL_RX_COUNTING_EN_DEFAULT 0x0 + +struct service_tbl { + a_uint32_t bypass_bitmap:32; + a_uint32_t rx_counting_en:1; + a_uint32_t _reserved0:31; +}; + +union service_tbl_u { + a_uint32_t val[2]; + struct service_tbl bf; +}; + +/*[table] IN_L2_SERVICE_TBL*/ +#define IN_L2_SERVICE_TBL +#define IN_L2_SERVICE_TBL_ADDRESS 0x4000 +#define IN_L2_SERVICE_TBL_NUM 256 +#define IN_L2_SERVICE_TBL_INC 0x10 +#define IN_L2_SERVICE_TBL_TYPE REG_TYPE_RW +#define IN_L2_SERVICE_TBL_DEFAULT 0x0 + /*[field] DST_PORT_ID_VALID*/ + #define IN_L2_SERVICE_TBL_DST_PORT_ID_VALID + #define IN_L2_SERVICE_TBL_DST_PORT_ID_VALID_OFFSET 0 + #define IN_L2_SERVICE_TBL_DST_PORT_ID_VALID_LEN 1 + #define IN_L2_SERVICE_TBL_DST_PORT_ID_VALID_DEFAULT 0x0 + /*[field] DST_PORT_ID*/ + #define IN_L2_SERVICE_TBL_DST_PORT_ID + #define IN_L2_SERVICE_TBL_DST_PORT_ID_OFFSET 1 + #define IN_L2_SERVICE_TBL_DST_PORT_ID_LEN 4 + #define IN_L2_SERVICE_TBL_DST_PORT_ID_DEFAULT 0x0 + /*[field] DIRECTION*/ + #define IN_L2_SERVICE_TBL_DIRECTION + #define IN_L2_SERVICE_TBL_DIRECTION_OFFSET 5 + #define IN_L2_SERVICE_TBL_DIRECTION_LEN 1 + #define IN_L2_SERVICE_TBL_DIRECTION_DEFAULT 0x0 + /*[field] BYPASS_BITMAP*/ + #define IN_L2_SERVICE_TBL_BYPASS_BITMAP + #define IN_L2_SERVICE_TBL_BYPASS_BITMAP_OFFSET 6 + #define IN_L2_SERVICE_TBL_BYPASS_BITMAP_LEN 24 + #define IN_L2_SERVICE_TBL_BYPASS_BITMAP_DEFAULT 0x0 + /*[field] RX_CNT_EN*/ + #define IN_L2_SERVICE_TBL_RX_CNT_EN + #define IN_L2_SERVICE_TBL_RX_CNT_EN_OFFSET 30 + #define IN_L2_SERVICE_TBL_RX_CNT_EN_LEN 1 + #define IN_L2_SERVICE_TBL_RX_CNT_EN_DEFAULT 0x0 + /*[field] TX_CNT_EN*/ + #define IN_L2_SERVICE_TBL_TX_CNT_EN + #define IN_L2_SERVICE_TBL_TX_CNT_EN_OFFSET 31 + #define IN_L2_SERVICE_TBL_TX_CNT_EN_LEN 1 + #define IN_L2_SERVICE_TBL_TX_CNT_EN_DEFAULT 0x0 + +struct in_l2_service_tbl { + a_uint32_t dst_port_id_valid:1; + a_uint32_t dst_port_id:4; + a_uint32_t direction:1; + a_uint32_t bypass_bitmap:24; + a_uint32_t rx_cnt_en:1; + a_uint32_t tx_cnt_en:1; +}; + +union in_l2_service_tbl_u { + a_uint32_t val; + struct in_l2_service_tbl bf; +}; + +/*[table] EG_SERVICE_TBL*/ +#define EG_SERVICE_TBL +#define EG_SERVICE_TBL_ADDRESS 0xc000 +#define EG_SERVICE_TBL_NUM 256 +#define EG_SERVICE_TBL_INC 0x8 +#define EG_SERVICE_TBL_TYPE REG_TYPE_RW +#define EG_SERVICE_TBL_DEFAULT 0x0 + /*[field] FIELD_UPDATE_ACTION*/ + #define EG_SERVICE_TBL_FIELD_UPDATE_ACTION + #define EG_SERVICE_TBL_FIELD_UPDATE_ACTION_OFFSET 0 + #define EG_SERVICE_TBL_FIELD_UPDATE_ACTION_LEN 32 + #define EG_SERVICE_TBL_FIELD_UPDATE_ACTION_DEFAULT 0x0 + /*[field] NEXT_SERVICE_CODE*/ + #define EG_SERVICE_TBL_NEXT_SERVICE_CODE + #define EG_SERVICE_TBL_NEXT_SERVICE_CODE_OFFSET 32 + #define EG_SERVICE_TBL_NEXT_SERVICE_CODE_LEN 8 + #define EG_SERVICE_TBL_NEXT_SERVICE_CODE_DEFAULT 0x0 + /*[field] HW_SERVICES*/ + #define EG_SERVICE_TBL_HW_SERVICES + #define EG_SERVICE_TBL_HW_SERVICES_OFFSET 40 + #define EG_SERVICE_TBL_HW_SERVICES_LEN 6 + #define EG_SERVICE_TBL_HW_SERVICES_DEFAULT 0x0 + /*[field] OFFSET_SEL*/ + #define EG_SERVICE_TBL_OFFSET_SEL + #define EG_SERVICE_TBL_OFFSET_SEL_OFFSET 46 + #define EG_SERVICE_TBL_OFFSET_SEL_LEN 1 + #define EG_SERVICE_TBL_OFFSET_SEL_DEFAULT 0x0 + /*[field] TX_COUNTING_EN*/ + #define EG_SERVICE_TBL_TX_COUNTING_EN + #define EG_SERVICE_TBL_TX_COUNTING_EN_OFFSET 47 + #define EG_SERVICE_TBL_TX_COUNTING_EN_LEN 1 + #define EG_SERVICE_TBL_TX_COUNTING_EN_DEFAULT 0x0 + +struct eg_service_tbl { + a_uint32_t field_update_action:32; + a_uint32_t next_service_code:8; + a_uint32_t hw_services:6; + a_uint32_t offset_sel:1; + a_uint32_t tx_counting_en:1; + a_uint32_t _reserved0:16; +}; + +union eg_service_tbl_u { + a_uint32_t val[2]; + struct eg_service_tbl bf; +}; +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_shaper.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_shaper.h new file mode 100755 index 000000000..4f8c74fd2 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_shaper.h @@ -0,0 +1,1055 @@ +/* + * 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 + * @{ + */ +#ifndef _HPPE_SHAPER_H_ +#define _HPPE_SHAPER_H_ + +#define L0_SHP_CREDIT_TBL_MAX_ENTRY 300 +#define L0_SHP_CFG_TBL_MAX_ENTRY 300 +#define L0_COMP_TBL_MAX_ENTRY 300 +#define L0_COMP_CFG_TBL_MAX_ENTRY 300 +#define L1_SHP_CREDIT_TBL_MAX_ENTRY 64 +#define L1_SHP_CFG_TBL_MAX_ENTRY 64 +#define L1_COMP_TBL_MAX_ENTRY 64 +#define L1_COMP_CFG_TBL_MAX_ENTRY 64 +#define PSCH_SHP_SIGN_TBL_MAX_ENTRY 8 +#define PSCH_SHP_CREDIT_TBL_MAX_ENTRY 8 +#define PSCH_SHP_CFG_TBL_MAX_ENTRY 8 +#define PSCH_COMP_TBL_MAX_ENTRY 8 +#define PSCH_COMP_CFG_TBL_MAX_ENTRY 8 + +sw_error_t +hppe_shp_slot_cfg_l0_get( + a_uint32_t dev_id, + union shp_slot_cfg_l0_u *value); + +sw_error_t +hppe_shp_slot_cfg_l0_set( + a_uint32_t dev_id, + union shp_slot_cfg_l0_u *value); + +sw_error_t +hppe_shp_slot_cfg_l1_get( + a_uint32_t dev_id, + union shp_slot_cfg_l1_u *value); + +sw_error_t +hppe_shp_slot_cfg_l1_set( + a_uint32_t dev_id, + union shp_slot_cfg_l1_u *value); + +sw_error_t +hppe_shp_slot_cfg_port_get( + a_uint32_t dev_id, + union shp_slot_cfg_port_u *value); + +sw_error_t +hppe_shp_slot_cfg_port_set( + a_uint32_t dev_id, + union shp_slot_cfg_port_u *value); + +sw_error_t +hppe_l0_shp_credit_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_shp_credit_tbl_u *value); + +sw_error_t +hppe_l0_shp_credit_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_shp_credit_tbl_u *value); + +sw_error_t +hppe_l0_shp_cfg_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_shp_cfg_tbl_u *value); + +sw_error_t +hppe_l0_shp_cfg_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_shp_cfg_tbl_u *value); + +sw_error_t +hppe_l0_comp_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_comp_tbl_u *value); + +sw_error_t +hppe_l0_comp_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_comp_tbl_u *value); + +sw_error_t +hppe_l0_comp_cfg_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_comp_cfg_tbl_u *value); + +sw_error_t +hppe_l0_comp_cfg_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_comp_cfg_tbl_u *value); + +sw_error_t +hppe_l1_shp_credit_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_shp_credit_tbl_u *value); + +sw_error_t +hppe_l1_shp_credit_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_shp_credit_tbl_u *value); + +sw_error_t +hppe_l1_shp_cfg_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_shp_cfg_tbl_u *value); + +sw_error_t +hppe_l1_shp_cfg_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_shp_cfg_tbl_u *value); + +sw_error_t +hppe_l1_comp_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_comp_tbl_u *value); + +sw_error_t +hppe_l1_comp_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_comp_tbl_u *value); + +sw_error_t +hppe_l1_comp_cfg_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_comp_cfg_tbl_u *value); + +sw_error_t +hppe_l1_comp_cfg_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_comp_cfg_tbl_u *value); + +sw_error_t +hppe_psch_shp_sign_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union psch_shp_sign_tbl_u *value); + +sw_error_t +hppe_psch_shp_sign_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union psch_shp_sign_tbl_u *value); + +sw_error_t +hppe_psch_shp_credit_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union psch_shp_credit_tbl_u *value); + +sw_error_t +hppe_psch_shp_credit_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union psch_shp_credit_tbl_u *value); + +sw_error_t +hppe_psch_shp_cfg_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union psch_shp_cfg_tbl_u *value); + +sw_error_t +hppe_psch_shp_cfg_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union psch_shp_cfg_tbl_u *value); + +sw_error_t +hppe_psch_comp_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union psch_comp_tbl_u *value); + +sw_error_t +hppe_psch_comp_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union psch_comp_tbl_u *value); + +sw_error_t +hppe_psch_comp_cfg_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union psch_comp_cfg_tbl_u *value); + +sw_error_t +hppe_psch_comp_cfg_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union psch_comp_cfg_tbl_u *value); + +sw_error_t +hppe_ipg_pre_len_cfg_get( + a_uint32_t dev_id, + union ipg_pre_len_cfg_u *value); + +sw_error_t +hppe_ipg_pre_len_cfg_set( + a_uint32_t dev_id, + union ipg_pre_len_cfg_u *value); + +sw_error_t +hppe_ipg_pre_len_cfg_ipg_pre_len_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_ipg_pre_len_cfg_ipg_pre_len_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_shp_slot_cfg_l0_l0_shp_slot_time_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_shp_slot_cfg_l0_l0_shp_slot_time_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_shp_slot_cfg_l1_l1_shp_slot_time_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_shp_slot_cfg_l1_l1_shp_slot_time_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_shp_slot_cfg_port_port_shp_slot_time_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_shp_slot_cfg_port_port_shp_slot_time_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_l0_shp_credit_tbl_e_shaper_credit_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_shp_credit_tbl_e_shaper_credit_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_shp_credit_tbl_e_shaper_credit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_shp_credit_tbl_e_shaper_credit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_shp_credit_tbl_c_shaper_credit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_shp_credit_tbl_c_shaper_credit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_shp_credit_tbl_c_shaper_credit_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_shp_credit_tbl_c_shaper_credit_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_shp_cfg_tbl_cir_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_shp_cfg_tbl_cir_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_shp_cfg_tbl_cf_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_shp_cfg_tbl_cf_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_shp_cfg_tbl_meter_unit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_shp_cfg_tbl_meter_unit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_shp_cfg_tbl_e_shaper_enable_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_shp_cfg_tbl_e_shaper_enable_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_shp_cfg_tbl_c_shaper_enable_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_shp_cfg_tbl_c_shaper_enable_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_shp_cfg_tbl_eir_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_shp_cfg_tbl_eir_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_shp_cfg_tbl_token_unit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_shp_cfg_tbl_token_unit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_shp_cfg_tbl_cbs_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_shp_cfg_tbl_cbs_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_shp_cfg_tbl_ebs_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_shp_cfg_tbl_ebs_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_comp_tbl_c_drr_compensate_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_comp_tbl_c_drr_compensate_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_comp_tbl_e_drr_compensate_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_comp_tbl_e_drr_compensate_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_comp_tbl_c_shaper_compensate_byte_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_comp_tbl_c_shaper_compensate_byte_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_comp_tbl_c_shaper_compensate_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_comp_tbl_c_shaper_compensate_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_comp_tbl_c_shaper_compensate_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_comp_tbl_c_shaper_compensate_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_comp_tbl_e_shaper_compensate_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_comp_tbl_e_shaper_compensate_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_comp_tbl_e_drr_compensate_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_comp_tbl_e_drr_compensate_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_comp_tbl_e_drr_compensate_byte_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_comp_tbl_e_drr_compensate_byte_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_comp_tbl_c_drr_compensate_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_comp_tbl_c_drr_compensate_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_comp_tbl_c_drr_compensate_byte_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_comp_tbl_c_drr_compensate_byte_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_comp_tbl_e_shaper_compensate_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_comp_tbl_e_shaper_compensate_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_comp_tbl_e_shaper_compensate_byte_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_comp_tbl_e_shaper_compensate_byte_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_comp_cfg_tbl_drr_meter_len_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_comp_cfg_tbl_drr_meter_len_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l0_comp_cfg_tbl_shaper_meter_len_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l0_comp_cfg_tbl_shaper_meter_len_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_shp_credit_tbl_e_shaper_credit_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_shp_credit_tbl_e_shaper_credit_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_shp_credit_tbl_e_shaper_credit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_shp_credit_tbl_e_shaper_credit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_shp_credit_tbl_c_shaper_credit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_shp_credit_tbl_c_shaper_credit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_shp_credit_tbl_c_shaper_credit_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_shp_credit_tbl_c_shaper_credit_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_shp_cfg_tbl_cir_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_shp_cfg_tbl_cir_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_shp_cfg_tbl_cf_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_shp_cfg_tbl_cf_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_shp_cfg_tbl_meter_unit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_shp_cfg_tbl_meter_unit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_shp_cfg_tbl_e_shaper_enable_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_shp_cfg_tbl_e_shaper_enable_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_shp_cfg_tbl_c_shaper_enable_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_shp_cfg_tbl_c_shaper_enable_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_shp_cfg_tbl_eir_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_shp_cfg_tbl_eir_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_shp_cfg_tbl_token_unit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_shp_cfg_tbl_token_unit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_shp_cfg_tbl_cbs_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_shp_cfg_tbl_cbs_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_shp_cfg_tbl_ebs_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_shp_cfg_tbl_ebs_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_comp_tbl_c_drr_compensate_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_comp_tbl_c_drr_compensate_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_comp_tbl_e_drr_compensate_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_comp_tbl_e_drr_compensate_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_comp_tbl_c_shaper_compensate_byte_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_comp_tbl_c_shaper_compensate_byte_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_comp_tbl_c_shaper_compensate_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_comp_tbl_c_shaper_compensate_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_comp_tbl_c_shaper_compensate_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_comp_tbl_c_shaper_compensate_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_comp_tbl_e_shaper_compensate_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_comp_tbl_e_shaper_compensate_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_comp_tbl_e_drr_compensate_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_comp_tbl_e_drr_compensate_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_comp_tbl_e_drr_compensate_byte_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_comp_tbl_e_drr_compensate_byte_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_comp_tbl_c_drr_compensate_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_comp_tbl_c_drr_compensate_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_comp_tbl_c_drr_compensate_byte_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_comp_tbl_c_drr_compensate_byte_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_comp_tbl_e_shaper_compensate_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_comp_tbl_e_shaper_compensate_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_comp_tbl_e_shaper_compensate_byte_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_comp_tbl_e_shaper_compensate_byte_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_comp_cfg_tbl_drr_meter_len_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_comp_cfg_tbl_drr_meter_len_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_l1_comp_cfg_tbl_shaper_meter_len_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_l1_comp_cfg_tbl_shaper_meter_len_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + + +sw_error_t +hppe_psch_shp_sign_tbl_shaper_credit_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_psch_shp_sign_tbl_shaper_credit_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_psch_shp_credit_tbl_shaper_credit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_psch_shp_credit_tbl_shaper_credit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_psch_shp_cfg_tbl_cir_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_psch_shp_cfg_tbl_cir_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_psch_shp_cfg_tbl_meter_unit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_psch_shp_cfg_tbl_meter_unit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_psch_shp_cfg_tbl_token_unit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_psch_shp_cfg_tbl_token_unit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_psch_shp_cfg_tbl_cbs_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_psch_shp_cfg_tbl_cbs_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_psch_shp_cfg_tbl_shaper_enable_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_psch_shp_cfg_tbl_shaper_enable_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_psch_comp_tbl_shaper_compensate_byte_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_psch_comp_tbl_shaper_compensate_byte_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_psch_comp_tbl_shaper_compensate_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_psch_comp_tbl_shaper_compensate_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_psch_comp_tbl_shaper_compensate_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_psch_comp_tbl_shaper_compensate_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_psch_comp_cfg_tbl_shaper_meter_len_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_psch_comp_cfg_tbl_shaper_meter_len_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_shaper_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_shaper_reg.h new file mode 100755 index 000000000..fe7b0afdd --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_shaper_reg.h @@ -0,0 +1,730 @@ +/* + * 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 + * @{ + */ +#ifndef HPPE_SHAPER_REG_H +#define HPPE_SHAPER_REG_H + +/*[register] SHP_SLOT_CFG_L0*/ +#define SHP_SLOT_CFG_L0 +#define SHP_SLOT_CFG_L0_ADDRESS 0x10 +#define SHP_SLOT_CFG_L0_NUM 1 +#define SHP_SLOT_CFG_L0_INC 0x4 +#define SHP_SLOT_CFG_L0_TYPE REG_TYPE_RW +#define SHP_SLOT_CFG_L0_DEFAULT 0x12c + /*[field] L0_SHP_SLOT_TIME*/ + #define SHP_SLOT_CFG_L0_L0_SHP_SLOT_TIME + #define SHP_SLOT_CFG_L0_L0_SHP_SLOT_TIME_OFFSET 0 + #define SHP_SLOT_CFG_L0_L0_SHP_SLOT_TIME_LEN 12 + #define SHP_SLOT_CFG_L0_L0_SHP_SLOT_TIME_DEFAULT 0x12c + +struct shp_slot_cfg_l0 { + a_uint32_t l0_shp_slot_time:12; + a_uint32_t _reserved0:20; +}; + +union shp_slot_cfg_l0_u { + a_uint32_t val; + struct shp_slot_cfg_l0 bf; +}; + +/*[register] SHP_SLOT_CFG_L1*/ +#define SHP_SLOT_CFG_L1 +#define SHP_SLOT_CFG_L1_ADDRESS 0x14 +#define SHP_SLOT_CFG_L1_NUM 1 +#define SHP_SLOT_CFG_L1_INC 0x4 +#define SHP_SLOT_CFG_L1_TYPE REG_TYPE_RW +#define SHP_SLOT_CFG_L1_DEFAULT 0x40 + /*[field] L1_SHP_SLOT_TIME*/ + #define SHP_SLOT_CFG_L1_L1_SHP_SLOT_TIME + #define SHP_SLOT_CFG_L1_L1_SHP_SLOT_TIME_OFFSET 0 + #define SHP_SLOT_CFG_L1_L1_SHP_SLOT_TIME_LEN 12 + #define SHP_SLOT_CFG_L1_L1_SHP_SLOT_TIME_DEFAULT 0x40 + +struct shp_slot_cfg_l1 { + a_uint32_t l1_shp_slot_time:12; + a_uint32_t _reserved0:20; +}; + +union shp_slot_cfg_l1_u { + a_uint32_t val; + struct shp_slot_cfg_l1 bf; +}; + +/*[register] SHP_SLOT_CFG_PORT*/ +#define SHP_SLOT_CFG_PORT +#define SHP_SLOT_CFG_PORT_ADDRESS 0x18 +#define SHP_SLOT_CFG_PORT_NUM 1 +#define SHP_SLOT_CFG_PORT_INC 0x4 +#define SHP_SLOT_CFG_PORT_TYPE REG_TYPE_RW +#define SHP_SLOT_CFG_PORT_DEFAULT 0x8 + /*[field] PORT_SHP_SLOT_TIME*/ + #define SHP_SLOT_CFG_PORT_PORT_SHP_SLOT_TIME + #define SHP_SLOT_CFG_PORT_PORT_SHP_SLOT_TIME_OFFSET 0 + #define SHP_SLOT_CFG_PORT_PORT_SHP_SLOT_TIME_LEN 12 + #define SHP_SLOT_CFG_PORT_PORT_SHP_SLOT_TIME_DEFAULT 0x8 + +struct shp_slot_cfg_port { + a_uint32_t port_shp_slot_time:12; + a_uint32_t _reserved0:20; +}; + +union shp_slot_cfg_port_u { + a_uint32_t val; + struct shp_slot_cfg_port bf; +}; + +/*[table] L0_SHP_CREDIT_TBL*/ +#define L0_SHP_CREDIT_TBL +#define L0_SHP_CREDIT_TBL_ADDRESS 0x1a000 +#define L0_SHP_CREDIT_TBL_NUM 300 +#define L0_SHP_CREDIT_TBL_INC 0x10 +#define L0_SHP_CREDIT_TBL_TYPE REG_TYPE_RW +#define L0_SHP_CREDIT_TBL_DEFAULT 0x0 + /*[field] C_SHAPER_CREDIT*/ + #define L0_SHP_CREDIT_TBL_C_SHAPER_CREDIT + #define L0_SHP_CREDIT_TBL_C_SHAPER_CREDIT_OFFSET 0 + #define L0_SHP_CREDIT_TBL_C_SHAPER_CREDIT_LEN 30 + #define L0_SHP_CREDIT_TBL_C_SHAPER_CREDIT_DEFAULT 0x0 + /*[field] C_SHAPER_CREDIT_NEG*/ + #define L0_SHP_CREDIT_TBL_C_SHAPER_CREDIT_NEG + #define L0_SHP_CREDIT_TBL_C_SHAPER_CREDIT_NEG_OFFSET 30 + #define L0_SHP_CREDIT_TBL_C_SHAPER_CREDIT_NEG_LEN 1 + #define L0_SHP_CREDIT_TBL_C_SHAPER_CREDIT_NEG_DEFAULT 0x0 + /*[field] E_SHAPER_CREDIT*/ + #define L0_SHP_CREDIT_TBL_E_SHAPER_CREDIT + #define L0_SHP_CREDIT_TBL_E_SHAPER_CREDIT_OFFSET 31 + #define L0_SHP_CREDIT_TBL_E_SHAPER_CREDIT_LEN 30 + #define L0_SHP_CREDIT_TBL_E_SHAPER_CREDIT_DEFAULT 0x0 + /*[field] E_SHAPER_CREDIT_NEG*/ + #define L0_SHP_CREDIT_TBL_E_SHAPER_CREDIT_NEG + #define L0_SHP_CREDIT_TBL_E_SHAPER_CREDIT_NEG_OFFSET 61 + #define L0_SHP_CREDIT_TBL_E_SHAPER_CREDIT_NEG_LEN 1 + #define L0_SHP_CREDIT_TBL_E_SHAPER_CREDIT_NEG_DEFAULT 0x0 + +struct l0_shp_credit_tbl { + a_uint32_t c_shaper_credit:30; + a_uint32_t c_shaper_credit_neg:1; + a_uint32_t e_shaper_credit_0:1; + a_uint32_t e_shaper_credit_1:29; + a_uint32_t e_shaper_credit_neg:1; + a_uint32_t _reserved0:2; +}; + +union l0_shp_credit_tbl_u { + a_uint32_t val[2]; + struct l0_shp_credit_tbl bf; +}; + +/*[table] L0_SHP_CFG_TBL*/ +#define L0_SHP_CFG_TBL +#define L0_SHP_CFG_TBL_ADDRESS 0x1c000 +#define L0_SHP_CFG_TBL_NUM 300 +#define L0_SHP_CFG_TBL_INC 0x10 +#define L0_SHP_CFG_TBL_TYPE REG_TYPE_RW +#define L0_SHP_CFG_TBL_DEFAULT 0x0 + /*[field] CIR*/ + #define L0_SHP_CFG_TBL_CIR + #define L0_SHP_CFG_TBL_CIR_OFFSET 0 + #define L0_SHP_CFG_TBL_CIR_LEN 18 + #define L0_SHP_CFG_TBL_CIR_DEFAULT 0x0 + /*[field] CBS*/ + #define L0_SHP_CFG_TBL_CBS + #define L0_SHP_CFG_TBL_CBS_OFFSET 18 + #define L0_SHP_CFG_TBL_CBS_LEN 14 + #define L0_SHP_CFG_TBL_CBS_DEFAULT 0x0 + /*[field] EIR*/ + #define L0_SHP_CFG_TBL_EIR + #define L0_SHP_CFG_TBL_EIR_OFFSET 32 + #define L0_SHP_CFG_TBL_EIR_LEN 18 + #define L0_SHP_CFG_TBL_EIR_DEFAULT 0x0 + /*[field] EBS*/ + #define L0_SHP_CFG_TBL_EBS + #define L0_SHP_CFG_TBL_EBS_OFFSET 50 + #define L0_SHP_CFG_TBL_EBS_LEN 14 + #define L0_SHP_CFG_TBL_EBS_DEFAULT 0x0 + /*[field] TOKEN_UNIT*/ + #define L0_SHP_CFG_TBL_TOKEN_UNIT + #define L0_SHP_CFG_TBL_TOKEN_UNIT_OFFSET 64 + #define L0_SHP_CFG_TBL_TOKEN_UNIT_LEN 3 + #define L0_SHP_CFG_TBL_TOKEN_UNIT_DEFAULT 0x0 + /*[field] METER_UNIT*/ + #define L0_SHP_CFG_TBL_METER_UNIT + #define L0_SHP_CFG_TBL_METER_UNIT_OFFSET 67 + #define L0_SHP_CFG_TBL_METER_UNIT_LEN 1 + #define L0_SHP_CFG_TBL_METER_UNIT_DEFAULT 0x0 + /*[field] C_SHAPER_ENABLE*/ + #define L0_SHP_CFG_TBL_C_SHAPER_ENABLE + #define L0_SHP_CFG_TBL_C_SHAPER_ENABLE_OFFSET 68 + #define L0_SHP_CFG_TBL_C_SHAPER_ENABLE_LEN 1 + #define L0_SHP_CFG_TBL_C_SHAPER_ENABLE_DEFAULT 0x0 + /*[field] E_SHAPER_ENABLE*/ + #define L0_SHP_CFG_TBL_E_SHAPER_ENABLE + #define L0_SHP_CFG_TBL_E_SHAPER_ENABLE_OFFSET 69 + #define L0_SHP_CFG_TBL_E_SHAPER_ENABLE_LEN 1 + #define L0_SHP_CFG_TBL_E_SHAPER_ENABLE_DEFAULT 0x0 + /*[field] CF*/ + #define L0_SHP_CFG_TBL_CF + #define L0_SHP_CFG_TBL_CF_OFFSET 70 + #define L0_SHP_CFG_TBL_CF_LEN 1 + #define L0_SHP_CFG_TBL_CF_DEFAULT 0x0 + +struct l0_shp_cfg_tbl { + a_uint32_t cir:18; + a_uint32_t cbs:14; + a_uint32_t eir:18; + a_uint32_t ebs:14; + a_uint32_t token_unit:3; + a_uint32_t meter_unit:1; + a_uint32_t c_shaper_enable:1; + a_uint32_t e_shaper_enable:1; + a_uint32_t cf:1; + a_uint32_t _reserved0:25; +}; + +union l0_shp_cfg_tbl_u { + a_uint32_t val[3]; + struct l0_shp_cfg_tbl bf; +}; + +/*[table] L0_COMP_TBL*/ +#define L0_COMP_TBL +#define L0_COMP_TBL_ADDRESS 0x26000 +#define L0_COMP_TBL_NUM 300 +#define L0_COMP_TBL_INC 0x10 +#define L0_COMP_TBL_TYPE REG_TYPE_RO +#define L0_COMP_TBL_DEFAULT 0x0 + /*[field] C_SHAPER_COMPENSATE_BYTE_CNT*/ + #define L0_COMP_TBL_C_SHAPER_COMPENSATE_BYTE_CNT + #define L0_COMP_TBL_C_SHAPER_COMPENSATE_BYTE_CNT_OFFSET 0 + #define L0_COMP_TBL_C_SHAPER_COMPENSATE_BYTE_CNT_LEN 18 + #define L0_COMP_TBL_C_SHAPER_COMPENSATE_BYTE_CNT_DEFAULT 0x0 + /*[field] C_SHAPER_COMPENSATE_BYTE_NEG*/ + #define L0_COMP_TBL_C_SHAPER_COMPENSATE_BYTE_NEG + #define L0_COMP_TBL_C_SHAPER_COMPENSATE_BYTE_NEG_OFFSET 18 + #define L0_COMP_TBL_C_SHAPER_COMPENSATE_BYTE_NEG_LEN 1 + #define L0_COMP_TBL_C_SHAPER_COMPENSATE_BYTE_NEG_DEFAULT 0x0 + /*[field] C_SHAPER_COMPENSATE_PKT_CNT*/ + #define L0_COMP_TBL_C_SHAPER_COMPENSATE_PKT_CNT + #define L0_COMP_TBL_C_SHAPER_COMPENSATE_PKT_CNT_OFFSET 19 + #define L0_COMP_TBL_C_SHAPER_COMPENSATE_PKT_CNT_LEN 4 + #define L0_COMP_TBL_C_SHAPER_COMPENSATE_PKT_CNT_DEFAULT 0x0 + /*[field] C_DRR_COMPENSATE_BYTE_CNT*/ + #define L0_COMP_TBL_C_DRR_COMPENSATE_BYTE_CNT + #define L0_COMP_TBL_C_DRR_COMPENSATE_BYTE_CNT_OFFSET 23 + #define L0_COMP_TBL_C_DRR_COMPENSATE_BYTE_CNT_LEN 18 + #define L0_COMP_TBL_C_DRR_COMPENSATE_BYTE_CNT_DEFAULT 0x0 + /*[field] C_DRR_COMPENSATE_BYTE_NEG*/ + #define L0_COMP_TBL_C_DRR_COMPENSATE_BYTE_NEG + #define L0_COMP_TBL_C_DRR_COMPENSATE_BYTE_NEG_OFFSET 41 + #define L0_COMP_TBL_C_DRR_COMPENSATE_BYTE_NEG_LEN 1 + #define L0_COMP_TBL_C_DRR_COMPENSATE_BYTE_NEG_DEFAULT 0x0 + /*[field] C_DRR_COMPENSATE_PKT_CNT*/ + #define L0_COMP_TBL_C_DRR_COMPENSATE_PKT_CNT + #define L0_COMP_TBL_C_DRR_COMPENSATE_PKT_CNT_OFFSET 42 + #define L0_COMP_TBL_C_DRR_COMPENSATE_PKT_CNT_LEN 4 + #define L0_COMP_TBL_C_DRR_COMPENSATE_PKT_CNT_DEFAULT 0x0 + /*[field] E_SHAPER_COMPENSATE_BYTE_CNT*/ + #define L0_COMP_TBL_E_SHAPER_COMPENSATE_BYTE_CNT + #define L0_COMP_TBL_E_SHAPER_COMPENSATE_BYTE_CNT_OFFSET 46 + #define L0_COMP_TBL_E_SHAPER_COMPENSATE_BYTE_CNT_LEN 18 + #define L0_COMP_TBL_E_SHAPER_COMPENSATE_BYTE_CNT_DEFAULT 0x0 + /*[field] E_SHAPER_COMPENSATE_BYTE_NEG*/ + #define L0_COMP_TBL_E_SHAPER_COMPENSATE_BYTE_NEG + #define L0_COMP_TBL_E_SHAPER_COMPENSATE_BYTE_NEG_OFFSET 64 + #define L0_COMP_TBL_E_SHAPER_COMPENSATE_BYTE_NEG_LEN 1 + #define L0_COMP_TBL_E_SHAPER_COMPENSATE_BYTE_NEG_DEFAULT 0x0 + /*[field] E_SHAPER_COMPENSATE_PKT_CNT*/ + #define L0_COMP_TBL_E_SHAPER_COMPENSATE_PKT_CNT + #define L0_COMP_TBL_E_SHAPER_COMPENSATE_PKT_CNT_OFFSET 65 + #define L0_COMP_TBL_E_SHAPER_COMPENSATE_PKT_CNT_LEN 4 + #define L0_COMP_TBL_E_SHAPER_COMPENSATE_PKT_CNT_DEFAULT 0x0 + /*[field] E_DRR_COMPENSATE_BYTE_CNT*/ + #define L0_COMP_TBL_E_DRR_COMPENSATE_BYTE_CNT + #define L0_COMP_TBL_E_DRR_COMPENSATE_BYTE_CNT_OFFSET 69 + #define L0_COMP_TBL_E_DRR_COMPENSATE_BYTE_CNT_LEN 18 + #define L0_COMP_TBL_E_DRR_COMPENSATE_BYTE_CNT_DEFAULT 0x0 + /*[field] E_DRR_COMPENSATE_BYTE_NEG*/ + #define L0_COMP_TBL_E_DRR_COMPENSATE_BYTE_NEG + #define L0_COMP_TBL_E_DRR_COMPENSATE_BYTE_NEG_OFFSET 87 + #define L0_COMP_TBL_E_DRR_COMPENSATE_BYTE_NEG_LEN 1 + #define L0_COMP_TBL_E_DRR_COMPENSATE_BYTE_NEG_DEFAULT 0x0 + /*[field] E_DRR_COMPENSATE_PKT_CNT*/ + #define L0_COMP_TBL_E_DRR_COMPENSATE_PKT_CNT + #define L0_COMP_TBL_E_DRR_COMPENSATE_PKT_CNT_OFFSET 88 + #define L0_COMP_TBL_E_DRR_COMPENSATE_PKT_CNT_LEN 4 + #define L0_COMP_TBL_E_DRR_COMPENSATE_PKT_CNT_DEFAULT 0x0 + +struct l0_comp_tbl { + a_uint32_t c_shaper_compensate_byte_cnt:18; + a_uint32_t c_shaper_compensate_byte_neg:1; + a_uint32_t c_shaper_compensate_pkt_cnt:4; + a_uint32_t c_drr_compensate_byte_cnt_0:9; + a_uint32_t c_drr_compensate_byte_cnt_1:9; + a_uint32_t c_drr_compensate_byte_neg:1; + a_uint32_t c_drr_compensate_pkt_cnt:4; + a_uint32_t e_shaper_compensate_byte_cnt:18; + a_uint32_t e_shaper_compensate_byte_neg:1; + a_uint32_t e_shaper_compensate_pkt_cnt:4; + a_uint32_t e_drr_compensate_byte_cnt:18; + a_uint32_t e_drr_compensate_byte_neg:1; + a_uint32_t e_drr_compensate_pkt_cnt:4; + a_uint32_t _reserved0:4; +}; + +union l0_comp_tbl_u { + a_uint32_t val[3]; + struct l0_comp_tbl bf; +}; + +/*[table] L0_COMP_CFG_TBL*/ +#define L0_COMP_CFG_TBL +#define L0_COMP_CFG_TBL_ADDRESS 0x28000 +#define L0_COMP_CFG_TBL_NUM 300 +#define L0_COMP_CFG_TBL_INC 0x10 +#define L0_COMP_CFG_TBL_TYPE REG_TYPE_RW +#define L0_COMP_CFG_TBL_DEFAULT 0x0 + /*[field] SHAPER_METER_LEN*/ + #define L0_COMP_CFG_TBL_SHAPER_METER_LEN + #define L0_COMP_CFG_TBL_SHAPER_METER_LEN_OFFSET 0 + #define L0_COMP_CFG_TBL_SHAPER_METER_LEN_LEN 2 + #define L0_COMP_CFG_TBL_SHAPER_METER_LEN_DEFAULT 0x0 + /*[field] DRR_METER_LEN*/ + #define L0_COMP_CFG_TBL_DRR_METER_LEN + #define L0_COMP_CFG_TBL_DRR_METER_LEN_OFFSET 2 + #define L0_COMP_CFG_TBL_DRR_METER_LEN_LEN 2 + #define L0_COMP_CFG_TBL_DRR_METER_LEN_DEFAULT 0x0 + +struct l0_comp_cfg_tbl { + a_uint32_t shaper_meter_len:2; + a_uint32_t drr_meter_len:2; + a_uint32_t _reserved0:28; +}; + +union l0_comp_cfg_tbl_u { + a_uint32_t val; + struct l0_comp_cfg_tbl bf; +}; + +/*[table] L1_SHP_CREDIT_TBL*/ +#define L1_SHP_CREDIT_TBL +#define L1_SHP_CREDIT_TBL_ADDRESS 0x5c000 +#define L1_SHP_CREDIT_TBL_NUM 64 +#define L1_SHP_CREDIT_TBL_INC 0x10 +#define L1_SHP_CREDIT_TBL_TYPE REG_TYPE_RW +#define L1_SHP_CREDIT_TBL_DEFAULT 0x0 + /*[field] C_SHAPER_CREDIT*/ + #define L1_SHP_CREDIT_TBL_C_SHAPER_CREDIT + #define L1_SHP_CREDIT_TBL_C_SHAPER_CREDIT_OFFSET 0 + #define L1_SHP_CREDIT_TBL_C_SHAPER_CREDIT_LEN 30 + #define L1_SHP_CREDIT_TBL_C_SHAPER_CREDIT_DEFAULT 0x0 + /*[field] C_SHAPER_CREDIT_NEG*/ + #define L1_SHP_CREDIT_TBL_C_SHAPER_CREDIT_NEG + #define L1_SHP_CREDIT_TBL_C_SHAPER_CREDIT_NEG_OFFSET 30 + #define L1_SHP_CREDIT_TBL_C_SHAPER_CREDIT_NEG_LEN 1 + #define L1_SHP_CREDIT_TBL_C_SHAPER_CREDIT_NEG_DEFAULT 0x0 + /*[field] E_SHAPER_CREDIT*/ + #define L1_SHP_CREDIT_TBL_E_SHAPER_CREDIT + #define L1_SHP_CREDIT_TBL_E_SHAPER_CREDIT_OFFSET 31 + #define L1_SHP_CREDIT_TBL_E_SHAPER_CREDIT_LEN 30 + #define L1_SHP_CREDIT_TBL_E_SHAPER_CREDIT_DEFAULT 0x0 + /*[field] E_SHAPER_CREDIT_NEG*/ + #define L1_SHP_CREDIT_TBL_E_SHAPER_CREDIT_NEG + #define L1_SHP_CREDIT_TBL_E_SHAPER_CREDIT_NEG_OFFSET 61 + #define L1_SHP_CREDIT_TBL_E_SHAPER_CREDIT_NEG_LEN 1 + #define L1_SHP_CREDIT_TBL_E_SHAPER_CREDIT_NEG_DEFAULT 0x0 + +struct l1_shp_credit_tbl { + a_uint32_t c_shaper_credit:30; + a_uint32_t c_shaper_credit_neg:1; + a_uint32_t e_shaper_credit_0:1; + a_uint32_t e_shaper_credit_1:29; + a_uint32_t e_shaper_credit_neg:1; + a_uint32_t _reserved0:2; +}; + +union l1_shp_credit_tbl_u { + a_uint32_t val[2]; + struct l1_shp_credit_tbl bf; +}; + +/*[table] L1_SHP_CFG_TBL*/ +#define L1_SHP_CFG_TBL +#define L1_SHP_CFG_TBL_ADDRESS 0x5e000 +#define L1_SHP_CFG_TBL_NUM 64 +#define L1_SHP_CFG_TBL_INC 0x10 +#define L1_SHP_CFG_TBL_TYPE REG_TYPE_RW +#define L1_SHP_CFG_TBL_DEFAULT 0x0 + /*[field] CIR*/ + #define L1_SHP_CFG_TBL_CIR + #define L1_SHP_CFG_TBL_CIR_OFFSET 0 + #define L1_SHP_CFG_TBL_CIR_LEN 18 + #define L1_SHP_CFG_TBL_CIR_DEFAULT 0x0 + /*[field] CBS*/ + #define L1_SHP_CFG_TBL_CBS + #define L1_SHP_CFG_TBL_CBS_OFFSET 18 + #define L1_SHP_CFG_TBL_CBS_LEN 14 + #define L1_SHP_CFG_TBL_CBS_DEFAULT 0x0 + /*[field] EIR*/ + #define L1_SHP_CFG_TBL_EIR + #define L1_SHP_CFG_TBL_EIR_OFFSET 32 + #define L1_SHP_CFG_TBL_EIR_LEN 18 + #define L1_SHP_CFG_TBL_EIR_DEFAULT 0x0 + /*[field] EBS*/ + #define L1_SHP_CFG_TBL_EBS + #define L1_SHP_CFG_TBL_EBS_OFFSET 50 + #define L1_SHP_CFG_TBL_EBS_LEN 14 + #define L1_SHP_CFG_TBL_EBS_DEFAULT 0x0 + /*[field] TOKEN_UNIT*/ + #define L1_SHP_CFG_TBL_TOKEN_UNIT + #define L1_SHP_CFG_TBL_TOKEN_UNIT_OFFSET 64 + #define L1_SHP_CFG_TBL_TOKEN_UNIT_LEN 3 + #define L1_SHP_CFG_TBL_TOKEN_UNIT_DEFAULT 0x0 + /*[field] METER_UNIT*/ + #define L1_SHP_CFG_TBL_METER_UNIT + #define L1_SHP_CFG_TBL_METER_UNIT_OFFSET 67 + #define L1_SHP_CFG_TBL_METER_UNIT_LEN 1 + #define L1_SHP_CFG_TBL_METER_UNIT_DEFAULT 0x0 + /*[field] C_SHAPER_ENABLE*/ + #define L1_SHP_CFG_TBL_C_SHAPER_ENABLE + #define L1_SHP_CFG_TBL_C_SHAPER_ENABLE_OFFSET 68 + #define L1_SHP_CFG_TBL_C_SHAPER_ENABLE_LEN 1 + #define L1_SHP_CFG_TBL_C_SHAPER_ENABLE_DEFAULT 0x0 + /*[field] E_SHAPER_ENABLE*/ + #define L1_SHP_CFG_TBL_E_SHAPER_ENABLE + #define L1_SHP_CFG_TBL_E_SHAPER_ENABLE_OFFSET 69 + #define L1_SHP_CFG_TBL_E_SHAPER_ENABLE_LEN 1 + #define L1_SHP_CFG_TBL_E_SHAPER_ENABLE_DEFAULT 0x0 + /*[field] CF*/ + #define L1_SHP_CFG_TBL_CF + #define L1_SHP_CFG_TBL_CF_OFFSET 70 + #define L1_SHP_CFG_TBL_CF_LEN 1 + #define L1_SHP_CFG_TBL_CF_DEFAULT 0x0 + +struct l1_shp_cfg_tbl { + a_uint32_t cir:18; + a_uint32_t cbs:14; + a_uint32_t eir:18; + a_uint32_t ebs:14; + a_uint32_t token_unit:3; + a_uint32_t meter_unit:1; + a_uint32_t c_shaper_enable:1; + a_uint32_t e_shaper_enable:1; + a_uint32_t cf:1; + a_uint32_t _reserved0:25; +}; + +union l1_shp_cfg_tbl_u { + a_uint32_t val[3]; + struct l1_shp_cfg_tbl bf; +}; + +/*[table] L1_COMP_TBL*/ +#define L1_COMP_TBL +#define L1_COMP_TBL_ADDRESS 0x68000 +#define L1_COMP_TBL_NUM 64 +#define L1_COMP_TBL_INC 0x10 +#define L1_COMP_TBL_TYPE REG_TYPE_RO +#define L1_COMP_TBL_DEFAULT 0x0 + /*[field] C_SHAPER_COMPENSATE_BYTE_CNT*/ + #define L1_COMP_TBL_C_SHAPER_COMPENSATE_BYTE_CNT + #define L1_COMP_TBL_C_SHAPER_COMPENSATE_BYTE_CNT_OFFSET 0 + #define L1_COMP_TBL_C_SHAPER_COMPENSATE_BYTE_CNT_LEN 18 + #define L1_COMP_TBL_C_SHAPER_COMPENSATE_BYTE_CNT_DEFAULT 0x0 + /*[field] C_SHAPER_COMPENSATE_BYTE_NEG*/ + #define L1_COMP_TBL_C_SHAPER_COMPENSATE_BYTE_NEG + #define L1_COMP_TBL_C_SHAPER_COMPENSATE_BYTE_NEG_OFFSET 18 + #define L1_COMP_TBL_C_SHAPER_COMPENSATE_BYTE_NEG_LEN 1 + #define L1_COMP_TBL_C_SHAPER_COMPENSATE_BYTE_NEG_DEFAULT 0x0 + /*[field] C_SHAPER_COMPENSATE_PKT_CNT*/ + #define L1_COMP_TBL_C_SHAPER_COMPENSATE_PKT_CNT + #define L1_COMP_TBL_C_SHAPER_COMPENSATE_PKT_CNT_OFFSET 19 + #define L1_COMP_TBL_C_SHAPER_COMPENSATE_PKT_CNT_LEN 4 + #define L1_COMP_TBL_C_SHAPER_COMPENSATE_PKT_CNT_DEFAULT 0x0 + /*[field] C_DRR_COMPENSATE_BYTE_CNT*/ + #define L1_COMP_TBL_C_DRR_COMPENSATE_BYTE_CNT + #define L1_COMP_TBL_C_DRR_COMPENSATE_BYTE_CNT_OFFSET 23 + #define L1_COMP_TBL_C_DRR_COMPENSATE_BYTE_CNT_LEN 18 + #define L1_COMP_TBL_C_DRR_COMPENSATE_BYTE_CNT_DEFAULT 0x0 + /*[field] C_DRR_COMPENSATE_BYTE_NEG*/ + #define L1_COMP_TBL_C_DRR_COMPENSATE_BYTE_NEG + #define L1_COMP_TBL_C_DRR_COMPENSATE_BYTE_NEG_OFFSET 41 + #define L1_COMP_TBL_C_DRR_COMPENSATE_BYTE_NEG_LEN 1 + #define L1_COMP_TBL_C_DRR_COMPENSATE_BYTE_NEG_DEFAULT 0x0 + /*[field] C_DRR_COMPENSATE_PKT_CNT*/ + #define L1_COMP_TBL_C_DRR_COMPENSATE_PKT_CNT + #define L1_COMP_TBL_C_DRR_COMPENSATE_PKT_CNT_OFFSET 42 + #define L1_COMP_TBL_C_DRR_COMPENSATE_PKT_CNT_LEN 4 + #define L1_COMP_TBL_C_DRR_COMPENSATE_PKT_CNT_DEFAULT 0x0 + /*[field] E_SHAPER_COMPENSATE_BYTE_CNT*/ + #define L1_COMP_TBL_E_SHAPER_COMPENSATE_BYTE_CNT + #define L1_COMP_TBL_E_SHAPER_COMPENSATE_BYTE_CNT_OFFSET 46 + #define L1_COMP_TBL_E_SHAPER_COMPENSATE_BYTE_CNT_LEN 18 + #define L1_COMP_TBL_E_SHAPER_COMPENSATE_BYTE_CNT_DEFAULT 0x0 + /*[field] E_SHAPER_COMPENSATE_BYTE_NEG*/ + #define L1_COMP_TBL_E_SHAPER_COMPENSATE_BYTE_NEG + #define L1_COMP_TBL_E_SHAPER_COMPENSATE_BYTE_NEG_OFFSET 64 + #define L1_COMP_TBL_E_SHAPER_COMPENSATE_BYTE_NEG_LEN 1 + #define L1_COMP_TBL_E_SHAPER_COMPENSATE_BYTE_NEG_DEFAULT 0x0 + /*[field] E_SHAPER_COMPENSATE_PKT_CNT*/ + #define L1_COMP_TBL_E_SHAPER_COMPENSATE_PKT_CNT + #define L1_COMP_TBL_E_SHAPER_COMPENSATE_PKT_CNT_OFFSET 65 + #define L1_COMP_TBL_E_SHAPER_COMPENSATE_PKT_CNT_LEN 4 + #define L1_COMP_TBL_E_SHAPER_COMPENSATE_PKT_CNT_DEFAULT 0x0 + /*[field] E_DRR_COMPENSATE_BYTE_CNT*/ + #define L1_COMP_TBL_E_DRR_COMPENSATE_BYTE_CNT + #define L1_COMP_TBL_E_DRR_COMPENSATE_BYTE_CNT_OFFSET 69 + #define L1_COMP_TBL_E_DRR_COMPENSATE_BYTE_CNT_LEN 18 + #define L1_COMP_TBL_E_DRR_COMPENSATE_BYTE_CNT_DEFAULT 0x0 + /*[field] E_DRR_COMPENSATE_BYTE_NEG*/ + #define L1_COMP_TBL_E_DRR_COMPENSATE_BYTE_NEG + #define L1_COMP_TBL_E_DRR_COMPENSATE_BYTE_NEG_OFFSET 87 + #define L1_COMP_TBL_E_DRR_COMPENSATE_BYTE_NEG_LEN 1 + #define L1_COMP_TBL_E_DRR_COMPENSATE_BYTE_NEG_DEFAULT 0x0 + /*[field] E_DRR_COMPENSATE_PKT_CNT*/ + #define L1_COMP_TBL_E_DRR_COMPENSATE_PKT_CNT + #define L1_COMP_TBL_E_DRR_COMPENSATE_PKT_CNT_OFFSET 88 + #define L1_COMP_TBL_E_DRR_COMPENSATE_PKT_CNT_LEN 4 + #define L1_COMP_TBL_E_DRR_COMPENSATE_PKT_CNT_DEFAULT 0x0 + +struct l1_comp_tbl { + a_uint32_t c_shaper_compensate_byte_cnt:18; + a_uint32_t c_shaper_compensate_byte_neg:1; + a_uint32_t c_shaper_compensate_pkt_cnt:4; + a_uint32_t c_drr_compensate_byte_cnt_0:9; + a_uint32_t c_drr_compensate_byte_cnt_1:9; + a_uint32_t c_drr_compensate_byte_neg:1; + a_uint32_t c_drr_compensate_pkt_cnt:4; + a_uint32_t e_shaper_compensate_byte_cnt:18; + a_uint32_t e_shaper_compensate_byte_neg:1; + a_uint32_t e_shaper_compensate_pkt_cnt:4; + a_uint32_t e_drr_compensate_byte_cnt:18; + a_uint32_t e_drr_compensate_byte_neg:1; + a_uint32_t e_drr_compensate_pkt_cnt:4; + a_uint32_t _reserved0:4; +}; + +union l1_comp_tbl_u { + a_uint32_t val[3]; + struct l1_comp_tbl bf; +}; + +/*[table] L1_COMP_CFG_TBL*/ +#define L1_COMP_CFG_TBL +#define L1_COMP_CFG_TBL_ADDRESS 0x6a000 +#define L1_COMP_CFG_TBL_NUM 64 +#define L1_COMP_CFG_TBL_INC 0x10 +#define L1_COMP_CFG_TBL_TYPE REG_TYPE_RW +#define L1_COMP_CFG_TBL_DEFAULT 0x0 + /*[field] SHAPER_METER_LEN*/ + #define L1_COMP_CFG_TBL_SHAPER_METER_LEN + #define L1_COMP_CFG_TBL_SHAPER_METER_LEN_OFFSET 0 + #define L1_COMP_CFG_TBL_SHAPER_METER_LEN_LEN 2 + #define L1_COMP_CFG_TBL_SHAPER_METER_LEN_DEFAULT 0x0 + /*[field] DRR_METER_LEN*/ + #define L1_COMP_CFG_TBL_DRR_METER_LEN + #define L1_COMP_CFG_TBL_DRR_METER_LEN_OFFSET 2 + #define L1_COMP_CFG_TBL_DRR_METER_LEN_LEN 2 + #define L1_COMP_CFG_TBL_DRR_METER_LEN_DEFAULT 0x0 + +struct l1_comp_cfg_tbl { + a_uint32_t shaper_meter_len:2; + a_uint32_t drr_meter_len:2; + a_uint32_t _reserved0:28; +}; + +union l1_comp_cfg_tbl_u { + a_uint32_t val; + struct l1_comp_cfg_tbl bf; +}; + +/*[table] PSCH_SHP_SIGN_TBL*/ +#define PSCH_SHP_SIGN_TBL +#define PSCH_SHP_SIGN_TBL_ADDRESS 0x70000 +#define PSCH_SHP_SIGN_TBL_NUM 8 +#define PSCH_SHP_SIGN_TBL_INC 0x10 +#define PSCH_SHP_SIGN_TBL_TYPE REG_TYPE_RW +#define PSCH_SHP_SIGN_TBL_DEFAULT 0x0 + /*[field] SHAPER_CREDIT_NEG*/ + #define PSCH_SHP_SIGN_TBL_SHAPER_CREDIT_NEG + #define PSCH_SHP_SIGN_TBL_SHAPER_CREDIT_NEG_OFFSET 0 + #define PSCH_SHP_SIGN_TBL_SHAPER_CREDIT_NEG_LEN 1 + #define PSCH_SHP_SIGN_TBL_SHAPER_CREDIT_NEG_DEFAULT 0x0 + +struct psch_shp_sign_tbl { + a_uint32_t shaper_credit_neg:1; + a_uint32_t _reserved0:31; +}; + +union psch_shp_sign_tbl_u { + a_uint32_t val; + struct psch_shp_sign_tbl bf; +}; + +/*[table] PSCH_SHP_CREDIT_TBL*/ +#define PSCH_SHP_CREDIT_TBL +#define PSCH_SHP_CREDIT_TBL_ADDRESS 0x72000 +#define PSCH_SHP_CREDIT_TBL_NUM 8 +#define PSCH_SHP_CREDIT_TBL_INC 0x10 +#define PSCH_SHP_CREDIT_TBL_TYPE REG_TYPE_RW +#define PSCH_SHP_CREDIT_TBL_DEFAULT 0x0 + /*[field] SHAPER_CREDIT*/ + #define PSCH_SHP_CREDIT_TBL_SHAPER_CREDIT + #define PSCH_SHP_CREDIT_TBL_SHAPER_CREDIT_OFFSET 0 + #define PSCH_SHP_CREDIT_TBL_SHAPER_CREDIT_LEN 30 + #define PSCH_SHP_CREDIT_TBL_SHAPER_CREDIT_DEFAULT 0x0 + +struct psch_shp_credit_tbl { + a_uint32_t shaper_credit:30; + a_uint32_t _reserved0:2; +}; + +union psch_shp_credit_tbl_u { + a_uint32_t val; + struct psch_shp_credit_tbl bf; +}; + +/*[table] PSCH_SHP_CFG_TBL*/ +#define PSCH_SHP_CFG_TBL +#define PSCH_SHP_CFG_TBL_ADDRESS 0x74000 +#define PSCH_SHP_CFG_TBL_NUM 8 +#define PSCH_SHP_CFG_TBL_INC 0x10 +#define PSCH_SHP_CFG_TBL_TYPE REG_TYPE_RW +#define PSCH_SHP_CFG_TBL_DEFAULT 0x0 + /*[field] CIR*/ + #define PSCH_SHP_CFG_TBL_CIR + #define PSCH_SHP_CFG_TBL_CIR_OFFSET 0 + #define PSCH_SHP_CFG_TBL_CIR_LEN 18 + #define PSCH_SHP_CFG_TBL_CIR_DEFAULT 0x0 + /*[field] CBS*/ + #define PSCH_SHP_CFG_TBL_CBS + #define PSCH_SHP_CFG_TBL_CBS_OFFSET 18 + #define PSCH_SHP_CFG_TBL_CBS_LEN 14 + #define PSCH_SHP_CFG_TBL_CBS_DEFAULT 0x0 + /*[field] TOKEN_UNIT*/ + #define PSCH_SHP_CFG_TBL_TOKEN_UNIT + #define PSCH_SHP_CFG_TBL_TOKEN_UNIT_OFFSET 32 + #define PSCH_SHP_CFG_TBL_TOKEN_UNIT_LEN 3 + #define PSCH_SHP_CFG_TBL_TOKEN_UNIT_DEFAULT 0x0 + /*[field] METER_UNIT*/ + #define PSCH_SHP_CFG_TBL_METER_UNIT + #define PSCH_SHP_CFG_TBL_METER_UNIT_OFFSET 35 + #define PSCH_SHP_CFG_TBL_METER_UNIT_LEN 1 + #define PSCH_SHP_CFG_TBL_METER_UNIT_DEFAULT 0x0 + /*[field] SHAPER_ENABLE*/ + #define PSCH_SHP_CFG_TBL_SHAPER_ENABLE + #define PSCH_SHP_CFG_TBL_SHAPER_ENABLE_OFFSET 36 + #define PSCH_SHP_CFG_TBL_SHAPER_ENABLE_LEN 1 + #define PSCH_SHP_CFG_TBL_SHAPER_ENABLE_DEFAULT 0x0 + +struct psch_shp_cfg_tbl { + a_uint32_t cir:18; + a_uint32_t cbs:14; + a_uint32_t token_unit:3; + a_uint32_t meter_unit:1; + a_uint32_t shaper_enable:1; + a_uint32_t _reserved0:27; +}; + +union psch_shp_cfg_tbl_u { + a_uint32_t val[2]; + struct psch_shp_cfg_tbl bf; +}; + +/*[table] PSCH_COMP_TBL*/ +#define PSCH_COMP_TBL +#define PSCH_COMP_TBL_ADDRESS 0x76000 +#define PSCH_COMP_TBL_NUM 8 +#define PSCH_COMP_TBL_INC 0x10 +#define PSCH_COMP_TBL_TYPE REG_TYPE_RO +#define PSCH_COMP_TBL_DEFAULT 0x0 + /*[field] SHAPER_COMPENSATE_BYTE_CNT*/ + #define PSCH_COMP_TBL_SHAPER_COMPENSATE_BYTE_CNT + #define PSCH_COMP_TBL_SHAPER_COMPENSATE_BYTE_CNT_OFFSET 0 + #define PSCH_COMP_TBL_SHAPER_COMPENSATE_BYTE_CNT_LEN 18 + #define PSCH_COMP_TBL_SHAPER_COMPENSATE_BYTE_CNT_DEFAULT 0x0 + /*[field] SHAPER_COMPENSATE_BYTE_NEG*/ + #define PSCH_COMP_TBL_SHAPER_COMPENSATE_BYTE_NEG + #define PSCH_COMP_TBL_SHAPER_COMPENSATE_BYTE_NEG_OFFSET 18 + #define PSCH_COMP_TBL_SHAPER_COMPENSATE_BYTE_NEG_LEN 1 + #define PSCH_COMP_TBL_SHAPER_COMPENSATE_BYTE_NEG_DEFAULT 0x0 + /*[field] SHAPER_COMPENSATE_PKT_CNT*/ + #define PSCH_COMP_TBL_SHAPER_COMPENSATE_PKT_CNT + #define PSCH_COMP_TBL_SHAPER_COMPENSATE_PKT_CNT_OFFSET 19 + #define PSCH_COMP_TBL_SHAPER_COMPENSATE_PKT_CNT_LEN 4 + #define PSCH_COMP_TBL_SHAPER_COMPENSATE_PKT_CNT_DEFAULT 0x0 + +struct psch_comp_tbl { + a_uint32_t shaper_compensate_byte_cnt:18; + a_uint32_t shaper_compensate_byte_neg:1; + a_uint32_t shaper_compensate_pkt_cnt:4; + a_uint32_t _reserved0:9; +}; + +union psch_comp_tbl_u { + a_uint32_t val; + struct psch_comp_tbl bf; +}; + +/*[table] PSCH_COMP_CFG_TBL*/ +#define PSCH_COMP_CFG_TBL +#define PSCH_COMP_CFG_TBL_ADDRESS 0x78000 +#define PSCH_COMP_CFG_TBL_NUM 8 +#define PSCH_COMP_CFG_TBL_INC 0x10 +#define PSCH_COMP_CFG_TBL_TYPE REG_TYPE_RW +#define PSCH_COMP_CFG_TBL_DEFAULT 0x0 + /*[field] SHAPER_METER_LEN*/ + #define PSCH_COMP_CFG_TBL_SHAPER_METER_LEN + #define PSCH_COMP_CFG_TBL_SHAPER_METER_LEN_OFFSET 0 + #define PSCH_COMP_CFG_TBL_SHAPER_METER_LEN_LEN 2 + #define PSCH_COMP_CFG_TBL_SHAPER_METER_LEN_DEFAULT 0x0 + +struct psch_comp_cfg_tbl { + a_uint32_t shaper_meter_len:2; + a_uint32_t _reserved0:30; +}; + +union psch_comp_cfg_tbl_u { + a_uint32_t val; + struct psch_comp_cfg_tbl bf; +}; + +/*[register] IPG_PRE_LEN_CFG*/ +#define IPG_PRE_LEN_CFG +#define IPG_PRE_LEN_CFG_ADDRESS 0x8 +#define IPG_PRE_LEN_CFG_NUM 1 +#define IPG_PRE_LEN_CFG_INC 0x4 +#define IPG_PRE_LEN_CFG_TYPE REG_TYPE_RW +#define IPG_PRE_LEN_CFG_DEFAULT 0x0 + /*[field] IPG_PRE_LEN*/ + #define IPG_PRE_LEN_CFG_IPG_PRE_LEN + #define IPG_PRE_LEN_CFG_IPG_PRE_LEN_OFFSET 0 + #define IPG_PRE_LEN_CFG_IPG_PRE_LEN_LEN 5 + #define IPG_PRE_LEN_CFG_IPG_PRE_LEN_DEFAULT 0x0 + +struct ipg_pre_len_cfg { + a_uint32_t ipg_pre_len:5; + a_uint32_t _reserved0:27; +}; + +union ipg_pre_len_cfg_u { + a_uint32_t val; + struct ipg_pre_len_cfg bf; +}; + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_stp.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_stp.h new file mode 100755 index 000000000..76443dd0d --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_stp.h @@ -0,0 +1,51 @@ +/* + * 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 + * @{ + */ +#ifndef _HPPE_STP_H_ +#define _HPPE_STP_H_ + +#define CST_STATE_MAX_ENTRY 8 + +sw_error_t +hppe_cst_state_get( + a_uint32_t dev_id, + a_uint32_t index, + union cst_state_u *value); + +sw_error_t +hppe_cst_state_set( + a_uint32_t dev_id, + a_uint32_t index, + union cst_state_u *value); + +sw_error_t +hppe_cst_state_port_state_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_cst_state_port_state_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + + +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_stp_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_stp_reg.h new file mode 100755 index 000000000..c472b7ba7 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_stp_reg.h @@ -0,0 +1,46 @@ +/* + * 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 + * @{ + */ +#ifndef HPPE_STP_REG_H +#define HPPE_STP_REG_H + +/*[register] CST_STATE*/ +#define CST_STATE +#define CST_STATE_ADDRESS 0x100 +#define CST_STATE_NUM 8 +#define CST_STATE_INC 0x4 +#define CST_STATE_TYPE REG_TYPE_RW +#define CST_STATE_DEFAULT 0x3 + /*[field] PORT_STATE*/ + #define CST_STATE_PORT_STATE + #define CST_STATE_PORT_STATE_OFFSET 0 + #define CST_STATE_PORT_STATE_LEN 2 + #define CST_STATE_PORT_STATE_DEFAULT 0x3 + +struct cst_state { + a_uint32_t port_state:2; + a_uint32_t _reserved0:30; +}; + +union cst_state_u { + a_uint32_t val; + struct cst_state bf; +}; + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_trunk.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_trunk.h new file mode 100755 index 000000000..279b5d92f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_trunk.h @@ -0,0 +1,320 @@ +/* + * 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 + * @{ + */ +#ifndef _HPPE_TRUNK_H_ +#define _HPPE_TRUNK_H_ + + +#define PORT_PARSING_REG_MAX_ENTRY 8 + +#define PC_GLOBAL_CNT_TBL_MAX_ENTRY 3 +#define TRUNK_FILTER_MAX_ENTRY 2 +#define TRUNK_MEMBER_MAX_ENTRY 2 +#define PORT_TRUNK_ID_MAX_ENTRY 8 + +sw_error_t +hppe_trunk_hash_field_reg_get( + a_uint32_t dev_id, + union trunk_hash_field_reg_u *value); + +sw_error_t +hppe_trunk_hash_field_reg_set( + a_uint32_t dev_id, + union trunk_hash_field_reg_u *value); + +sw_error_t +hppe_trunk_filter_get( + a_uint32_t dev_id, + a_uint32_t index, + union trunk_filter_u *value); + +sw_error_t +hppe_trunk_filter_set( + a_uint32_t dev_id, + a_uint32_t index, + union trunk_filter_u *value); + +sw_error_t +hppe_trunk_member_get( + a_uint32_t dev_id, + a_uint32_t index, + union trunk_member_u *value); + +sw_error_t +hppe_trunk_member_set( + a_uint32_t dev_id, + a_uint32_t index, + union trunk_member_u *value); + +sw_error_t +hppe_port_trunk_id_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_trunk_id_u *value); + +sw_error_t +hppe_port_trunk_id_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_trunk_id_u *value); + +sw_error_t +hppe_trunk_hash_field_reg_udf2_incl_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_trunk_hash_field_reg_udf2_incl_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_trunk_hash_field_reg_mac_da_incl_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_trunk_hash_field_reg_mac_da_incl_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_trunk_hash_field_reg_src_port_incl_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_trunk_hash_field_reg_src_port_incl_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_trunk_hash_field_reg_udf3_incl_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_trunk_hash_field_reg_udf3_incl_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_trunk_hash_field_reg_l4_dst_port_incl_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_trunk_hash_field_reg_l4_dst_port_incl_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_trunk_hash_field_reg_udf0_incl_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_trunk_hash_field_reg_udf0_incl_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_trunk_hash_field_reg_dst_ip_incl_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_trunk_hash_field_reg_dst_ip_incl_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_trunk_hash_field_reg_l4_src_port_incl_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_trunk_hash_field_reg_l4_src_port_incl_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_trunk_hash_field_reg_src_ip_incl_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_trunk_hash_field_reg_src_ip_incl_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_trunk_hash_field_reg_udf1_incl_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_trunk_hash_field_reg_udf1_incl_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_trunk_hash_field_reg_mac_sa_incl_get( + a_uint32_t dev_id, + unsigned int *value); + +sw_error_t +hppe_trunk_hash_field_reg_mac_sa_incl_set( + a_uint32_t dev_id, + unsigned int value); + +sw_error_t +hppe_trunk_filter_mem_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_trunk_filter_mem_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_trunk_member_member_2_port_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_trunk_member_member_2_port_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_trunk_member_member_0_port_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_trunk_member_member_0_port_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_trunk_member_member_1_port_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_trunk_member_member_1_port_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_trunk_member_member_6_port_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_trunk_member_member_6_port_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_trunk_member_member_4_port_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_trunk_member_member_4_port_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_trunk_member_member_3_port_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_trunk_member_member_3_port_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_trunk_member_member_5_port_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_trunk_member_member_5_port_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_trunk_member_member_7_port_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_trunk_member_member_7_port_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_trunk_id_trunk_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_trunk_id_trunk_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_port_trunk_id_trunk_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_port_trunk_id_trunk_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_trunk_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_trunk_reg.h new file mode 100755 index 000000000..7f9af5c61 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_trunk_reg.h @@ -0,0 +1,230 @@ +/* + * 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 + * @{ + */ +#ifndef HPPE_TRUNK_REG_H +#define HPPE_TRUNK_REG_H + +/*[register] TRUNK_HASH_FIELD_REG*/ +#define TRUNK_HASH_FIELD_REG +#define TRUNK_HASH_FIELD_REG_ADDRESS 0x68 +#define TRUNK_HASH_FIELD_REG_NUM 1 +#define TRUNK_HASH_FIELD_REG_INC 0x4 +#define TRUNK_HASH_FIELD_REG_TYPE REG_TYPE_RW +#define TRUNK_HASH_FIELD_REG_DEFAULT 0x0 + /*[field] SRC_PORT_INCL*/ + #define TRUNK_HASH_FIELD_REG_SRC_PORT_INCL + #define TRUNK_HASH_FIELD_REG_SRC_PORT_INCL_OFFSET 0 + #define TRUNK_HASH_FIELD_REG_SRC_PORT_INCL_LEN 1 + #define TRUNK_HASH_FIELD_REG_SRC_PORT_INCL_DEFAULT 0x0 + /*[field] MAC_DA_INCL*/ + #define TRUNK_HASH_FIELD_REG_MAC_DA_INCL + #define TRUNK_HASH_FIELD_REG_MAC_DA_INCL_OFFSET 1 + #define TRUNK_HASH_FIELD_REG_MAC_DA_INCL_LEN 1 + #define TRUNK_HASH_FIELD_REG_MAC_DA_INCL_DEFAULT 0x0 + /*[field] MAC_SA_INCL*/ + #define TRUNK_HASH_FIELD_REG_MAC_SA_INCL + #define TRUNK_HASH_FIELD_REG_MAC_SA_INCL_OFFSET 2 + #define TRUNK_HASH_FIELD_REG_MAC_SA_INCL_LEN 1 + #define TRUNK_HASH_FIELD_REG_MAC_SA_INCL_DEFAULT 0x0 + /*[field] SRC_IP_INCL*/ + #define TRUNK_HASH_FIELD_REG_SRC_IP_INCL + #define TRUNK_HASH_FIELD_REG_SRC_IP_INCL_OFFSET 3 + #define TRUNK_HASH_FIELD_REG_SRC_IP_INCL_LEN 1 + #define TRUNK_HASH_FIELD_REG_SRC_IP_INCL_DEFAULT 0x0 + /*[field] DST_IP_INCL*/ + #define TRUNK_HASH_FIELD_REG_DST_IP_INCL + #define TRUNK_HASH_FIELD_REG_DST_IP_INCL_OFFSET 4 + #define TRUNK_HASH_FIELD_REG_DST_IP_INCL_LEN 1 + #define TRUNK_HASH_FIELD_REG_DST_IP_INCL_DEFAULT 0x0 + /*[field] L4_SRC_PORT_INCL*/ + #define TRUNK_HASH_FIELD_REG_L4_SRC_PORT_INCL + #define TRUNK_HASH_FIELD_REG_L4_SRC_PORT_INCL_OFFSET 5 + #define TRUNK_HASH_FIELD_REG_L4_SRC_PORT_INCL_LEN 1 + #define TRUNK_HASH_FIELD_REG_L4_SRC_PORT_INCL_DEFAULT 0x0 + /*[field] L4_DST_PORT_INCL*/ + #define TRUNK_HASH_FIELD_REG_L4_DST_PORT_INCL + #define TRUNK_HASH_FIELD_REG_L4_DST_PORT_INCL_OFFSET 6 + #define TRUNK_HASH_FIELD_REG_L4_DST_PORT_INCL_LEN 1 + #define TRUNK_HASH_FIELD_REG_L4_DST_PORT_INCL_DEFAULT 0x0 + /*[field] UDF0_INCL*/ + #define TRUNK_HASH_FIELD_REG_UDF0_INCL + #define TRUNK_HASH_FIELD_REG_UDF0_INCL_OFFSET 7 + #define TRUNK_HASH_FIELD_REG_UDF0_INCL_LEN 1 + #define TRUNK_HASH_FIELD_REG_UDF0_INCL_DEFAULT 0x0 + /*[field] UDF1_INCL*/ + #define TRUNK_HASH_FIELD_REG_UDF1_INCL + #define TRUNK_HASH_FIELD_REG_UDF1_INCL_OFFSET 8 + #define TRUNK_HASH_FIELD_REG_UDF1_INCL_LEN 1 + #define TRUNK_HASH_FIELD_REG_UDF1_INCL_DEFAULT 0x0 + /*[field] UDF2_INCL*/ + #define TRUNK_HASH_FIELD_REG_UDF2_INCL + #define TRUNK_HASH_FIELD_REG_UDF2_INCL_OFFSET 9 + #define TRUNK_HASH_FIELD_REG_UDF2_INCL_LEN 1 + #define TRUNK_HASH_FIELD_REG_UDF2_INCL_DEFAULT 0x0 + /*[field] UDF3_INCL*/ + #define TRUNK_HASH_FIELD_REG_UDF3_INCL + #define TRUNK_HASH_FIELD_REG_UDF3_INCL_OFFSET 10 + #define TRUNK_HASH_FIELD_REG_UDF3_INCL_LEN 1 + #define TRUNK_HASH_FIELD_REG_UDF3_INCL_DEFAULT 0x0 + +struct trunk_hash_field_reg { + a_uint32_t src_port_incl:1; + a_uint32_t mac_da_incl:1; + a_uint32_t mac_sa_incl:1; + a_uint32_t src_ip_incl:1; + a_uint32_t dst_ip_incl:1; + a_uint32_t l4_src_port_incl:1; + a_uint32_t l4_dst_port_incl:1; + a_uint32_t udf0_incl:1; + a_uint32_t udf1_incl:1; + a_uint32_t udf2_incl:1; + a_uint32_t udf3_incl:1; + a_uint32_t _reserved0:21; +}; + +union trunk_hash_field_reg_u { + a_uint32_t val; + struct trunk_hash_field_reg bf; +}; + +/*[register] TRUNK_FILTER*/ +#define TRUNK_FILTER +#define TRUNK_FILTER_ADDRESS 0x50 +#define TRUNK_FILTER_NUM 2 +#define TRUNK_FILTER_INC 0x4 +#define TRUNK_FILTER_TYPE REG_TYPE_RW +#define TRUNK_FILTER_DEFAULT 0x0 + /*[field] MEM_BITMAP*/ + #define TRUNK_FILTER_MEM_BITMAP + #define TRUNK_FILTER_MEM_BITMAP_OFFSET 0 + #define TRUNK_FILTER_MEM_BITMAP_LEN 8 + #define TRUNK_FILTER_MEM_BITMAP_DEFAULT 0x0 + +struct trunk_filter { + a_uint32_t mem_bitmap:8; + a_uint32_t _reserved0:24; +}; + +union trunk_filter_u { + a_uint32_t val; + struct trunk_filter bf; +}; + +/*[register] TRUNK_MEMBER*/ +#define TRUNK_MEMBER +#define TRUNK_MEMBER_ADDRESS 0x60 +#define TRUNK_MEMBER_NUM 2 +#define TRUNK_MEMBER_INC 0x4 +#define TRUNK_MEMBER_TYPE REG_TYPE_RW +#define TRUNK_MEMBER_DEFAULT 0x0 + /*[field] MEMBER_0_PORT_ID*/ + #define TRUNK_MEMBER_MEMBER_0_PORT_ID + #define TRUNK_MEMBER_MEMBER_0_PORT_ID_OFFSET 0 + #define TRUNK_MEMBER_MEMBER_0_PORT_ID_LEN 3 + #define TRUNK_MEMBER_MEMBER_0_PORT_ID_DEFAULT 0x0 + /*[field] MEMBER_1_PORT_ID*/ + #define TRUNK_MEMBER_MEMBER_1_PORT_ID + #define TRUNK_MEMBER_MEMBER_1_PORT_ID_OFFSET 4 + #define TRUNK_MEMBER_MEMBER_1_PORT_ID_LEN 3 + #define TRUNK_MEMBER_MEMBER_1_PORT_ID_DEFAULT 0x0 + /*[field] MEMBER_2_PORT_ID*/ + #define TRUNK_MEMBER_MEMBER_2_PORT_ID + #define TRUNK_MEMBER_MEMBER_2_PORT_ID_OFFSET 8 + #define TRUNK_MEMBER_MEMBER_2_PORT_ID_LEN 3 + #define TRUNK_MEMBER_MEMBER_2_PORT_ID_DEFAULT 0x0 + /*[field] MEMBER_3_PORT_ID*/ + #define TRUNK_MEMBER_MEMBER_3_PORT_ID + #define TRUNK_MEMBER_MEMBER_3_PORT_ID_OFFSET 12 + #define TRUNK_MEMBER_MEMBER_3_PORT_ID_LEN 3 + #define TRUNK_MEMBER_MEMBER_3_PORT_ID_DEFAULT 0x0 + /*[field] MEMBER_4_PORT_ID*/ + #define TRUNK_MEMBER_MEMBER_4_PORT_ID + #define TRUNK_MEMBER_MEMBER_4_PORT_ID_OFFSET 16 + #define TRUNK_MEMBER_MEMBER_4_PORT_ID_LEN 3 + #define TRUNK_MEMBER_MEMBER_4_PORT_ID_DEFAULT 0x0 + /*[field] MEMBER_5_PORT_ID*/ + #define TRUNK_MEMBER_MEMBER_5_PORT_ID + #define TRUNK_MEMBER_MEMBER_5_PORT_ID_OFFSET 20 + #define TRUNK_MEMBER_MEMBER_5_PORT_ID_LEN 3 + #define TRUNK_MEMBER_MEMBER_5_PORT_ID_DEFAULT 0x0 + /*[field] MEMBER_6_PORT_ID*/ + #define TRUNK_MEMBER_MEMBER_6_PORT_ID + #define TRUNK_MEMBER_MEMBER_6_PORT_ID_OFFSET 24 + #define TRUNK_MEMBER_MEMBER_6_PORT_ID_LEN 3 + #define TRUNK_MEMBER_MEMBER_6_PORT_ID_DEFAULT 0x0 + /*[field] MEMBER_7_PORT_ID*/ + #define TRUNK_MEMBER_MEMBER_7_PORT_ID + #define TRUNK_MEMBER_MEMBER_7_PORT_ID_OFFSET 28 + #define TRUNK_MEMBER_MEMBER_7_PORT_ID_LEN 3 + #define TRUNK_MEMBER_MEMBER_7_PORT_ID_DEFAULT 0x0 + +struct trunk_member { + a_uint32_t member_0_port_id:3; + a_uint32_t _reserved0:1; + a_uint32_t member_1_port_id:3; + a_uint32_t _reserved1:1; + a_uint32_t member_2_port_id:3; + a_uint32_t _reserved2:1; + a_uint32_t member_3_port_id:3; + a_uint32_t _reserved3:1; + a_uint32_t member_4_port_id:3; + a_uint32_t _reserved4:1; + a_uint32_t member_5_port_id:3; + a_uint32_t _reserved5:1; + a_uint32_t member_6_port_id:3; + a_uint32_t _reserved6:1; + a_uint32_t member_7_port_id:3; + a_uint32_t _reserved7:1; +}; + +union trunk_member_u { + a_uint32_t val; + struct trunk_member bf; +}; + +/*[register] PORT_TRUNK_ID*/ +#define PORT_TRUNK_ID +#define PORT_TRUNK_ID_ADDRESS 0x600 +#define PORT_TRUNK_ID_NUM 8 +#define PORT_TRUNK_ID_INC 0x4 +#define PORT_TRUNK_ID_TYPE REG_TYPE_RW +#define PORT_TRUNK_ID_DEFAULT 0x0 + /*[field] TRUNK_EN*/ + #define PORT_TRUNK_ID_TRUNK_EN + #define PORT_TRUNK_ID_TRUNK_EN_OFFSET 0 + #define PORT_TRUNK_ID_TRUNK_EN_LEN 1 + #define PORT_TRUNK_ID_TRUNK_EN_DEFAULT 0x0 + /*[field] TRUNK_ID*/ + #define PORT_TRUNK_ID_TRUNK_ID + #define PORT_TRUNK_ID_TRUNK_ID_OFFSET 1 + #define PORT_TRUNK_ID_TRUNK_ID_LEN 1 + #define PORT_TRUNK_ID_TRUNK_ID_DEFAULT 0x0 + +struct port_trunk_id { + a_uint32_t trunk_en:1; + a_uint32_t trunk_id:1; + a_uint32_t _reserved0:30; +}; + +union port_trunk_id_u { + a_uint32_t val; + struct port_trunk_id bf; +}; + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_uniphy.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_uniphy.h new file mode 100755 index 000000000..c41c5bb0d --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_uniphy.h @@ -0,0 +1,2440 @@ +/* + * 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. + */ + + +/** + * @defgroup + * @{ + */ +#ifndef _HPPE_UNIPHY_H_ +#define _HPPE_UNIPHY_H_ + +#define UNIPHY_OFFSET_CALIB_4_MAX_ENTRY 3 +#define UNIPHY_MODE_CTRL_MAX_ENTRY 3 +#define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_MAX_ENTRY 3 +#define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_MAX_ENTRY 3 +#define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_MAX_ENTRY 3 +#define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_MAX_ENTRY 3 +#define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_MAX_ENTRY 3 +#define SR_XS_PCS_KR_STS1_MAX_ENTRY 3 +#define VR_XS_PCS_DIG_CTRL1_MAX_ENTRY 3 +#define SR_MII_CTRL_MAX_ENTRY 3 +#define VR_MII_AN_CTRL_MAX_ENTRY 3 +#define VR_MII_AN_INTR_STS_MAX_ENTRY 3 + +#define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_MAX_ENTRY 3 +#define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_MAX_ENTRY 3 +#define UNIPHY_RESISTOR_CALIBRATION_1_MAX_ENTRY 3 +#define UNIPHY_PLL_VCO_RELATED_CONTROL_1_MAX_ENTRY 3 +#define UNIPHY_RX_AFE_2_MAX_ENTRY 3 +#define BANDGAP_IP_MBIAS_2_MAX_ENTRY 4 +#define LDO_0P9V_RELATED_1_MAX_ENTRY 4 +#define OTP_VTT_LDO_RELATED_MAX_ENTRY 4 +#define OTP_TEMPERATURE_COMPENSATE_1_MAX_ENTRY 4 +#define PLL_VCO_RELATED_CONTROL_1_MAX_ENTRY 4 +#define PLL_CONTROL_VCO_RELATED_SELECTION_2_MAX_ENTRY 4 +#define UNIPHY_MISC2_PHY_MODE_MAX_ENTRY 4 +#define UNIPHY_PLL_POWER_ON_AND_RESET_INC_MAX_ENTRY 4 + +sw_error_t +hppe_uniphy_offset_calib_4_get( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_offset_calib_4_u *value); + +sw_error_t +hppe_uniphy_offset_calib_4_set( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_offset_calib_4_u *value); + +sw_error_t +hppe_uniphy_mode_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_mode_ctrl_u *value); + +sw_error_t +hppe_uniphy_mode_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_mode_ctrl_u *value); + +sw_error_t +hppe_uniphy_channel0_input_output_4_get( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_channel0_input_output_4_u *value); + +sw_error_t +hppe_uniphy_channel0_input_output_4_set( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_channel0_input_output_4_u *value); + +sw_error_t +hppe_uniphy_channel1_input_output_4_get( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_channel1_input_output_4_u *value); + +sw_error_t +hppe_uniphy_channel1_input_output_4_set( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_channel1_input_output_4_u *value); + +sw_error_t +hppe_uniphy_channel2_input_output_4_get( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_channel2_input_output_4_u *value); + +sw_error_t +hppe_uniphy_channel2_input_output_4_set( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_channel2_input_output_4_u *value); + +sw_error_t +hppe_uniphy_channel3_input_output_4_get( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_channel3_input_output_4_u *value); + +sw_error_t +hppe_uniphy_channel3_input_output_4_set( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_channel3_input_output_4_u *value); + +sw_error_t +hppe_uniphy_channel4_input_output_4_get( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_channel4_input_output_4_u *value); + +sw_error_t +hppe_uniphy_channel4_input_output_4_set( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_channel4_input_output_4_u *value); + +sw_error_t +hppe_uniphy_instance_link_detect_get( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_instance_link_detect_u *value); + +sw_error_t +hppe_uniphy_instance_link_detect_set( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_instance_link_detect_u *value); + + +sw_error_t +hppe_sr_xs_pcs_kr_sts1_get( + a_uint32_t dev_id, + a_uint32_t index, + union sr_xs_pcs_kr_sts1_u *value); + +sw_error_t +hppe_sr_xs_pcs_kr_sts1_set( + a_uint32_t dev_id, + a_uint32_t index, + union sr_xs_pcs_kr_sts1_u *value); + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_get( + a_uint32_t dev_id, + a_uint32_t index, + union vr_xs_pcs_dig_ctrl1_u *value); + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_set( + a_uint32_t dev_id, + a_uint32_t index, + union vr_xs_pcs_dig_ctrl1_u *value); + +sw_error_t +hppe_sr_mii_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union sr_mii_ctrl_u *value); + +sw_error_t +hppe_sr_mii_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union sr_mii_ctrl_u *value); + +sw_error_t +hppe_vr_mii_an_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union vr_mii_an_ctrl_u *value); + +sw_error_t +hppe_vr_mii_an_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union vr_mii_an_ctrl_u *value); + +sw_error_t +hppe_vr_mii_an_intr_sts_get( + a_uint32_t dev_id, + a_uint32_t index, + union vr_mii_an_intr_sts_u *value); + +sw_error_t +hppe_vr_mii_an_intr_sts_set( + a_uint32_t dev_id, + a_uint32_t index, + union vr_mii_an_intr_sts_u *value); + +sw_error_t +hppe_uniphy_offset_calib_4_mmd1_reg_cal_rep_time_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_offset_calib_4_mmd1_reg_cal_rep_time_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_offset_calib_4_mmd1_reg_pll_locked_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_offset_calib_4_mmd1_reg_pll_locked_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_offset_calib_4_mmd1_reg_clr_sampler_calib_timeout_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_offset_calib_4_mmd1_reg_clr_sampler_calib_timeout_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_offset_calib_4_mmd1_reg_lockdet_lckdt_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_offset_calib_4_mmd1_reg_lockdet_lckdt_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_offset_calib_4_mmd1_reg_cal_detect_time_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_offset_calib_4_mmd1_reg_cal_detect_time_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_offset_calib_4_mmd1_reg_calibration_done_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_offset_calib_4_mmd1_reg_calibration_done_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_offset_calib_4_mmd1_reg_smpl_cal_ready_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_offset_calib_4_mmd1_reg_smpl_cal_ready_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_ch1_ch0_sgmii_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_ch1_ch0_sgmii_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_usxg_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_usxg_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_ch4_ch1_0_sgmii_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_ch4_ch1_0_sgmii_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_sgplus_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_sgplus_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_xpcs_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_xpcs_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_ch0_psgmii_qsgmii_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_ch0_psgmii_qsgmii_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_ch0_autoneg_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_ch0_autoneg_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_sw_v17_v18_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_sw_v17_v18_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_ch0_mode_ctrl_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_ch0_mode_ctrl_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_sgmii_even_low_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_sgmii_even_low_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_ch0_qsgmii_sgmii_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_ch0_qsgmii_sgmii_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_sg_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_sg_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_mr_restart_an_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_mr_restart_an_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_rem_phy_lpbk_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_rem_phy_lpbk_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_mr_reg4_ch_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_mr_reg4_ch_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_power_on_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_power_on_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_mr_main_reset_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_mr_main_reset_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel0_force_speed_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel0_force_speed_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_adp_sw_rstn_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_adp_sw_rstn_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_speed_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_speed_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_mr_an_enable_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_mr_an_enable_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_mr_np_loaded_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_mr_np_loaded_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_mr_loopback_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_mr_loopback_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_adp_sw_rstn_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_adp_sw_rstn_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_power_on_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_power_on_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_mr_main_reset_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_mr_main_reset_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_mr_an_enable_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_mr_an_enable_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_speed_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_speed_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_rem_phy_lpbk_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_rem_phy_lpbk_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_mr_reg4_ch_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_mr_reg4_ch_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_mr_np_loaded_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_mr_np_loaded_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_force_speed_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_force_speed_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_mr_restart_an_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_mr_restart_an_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_mr_loopback_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_mr_loopback_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_rem_phy_lpbk_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_rem_phy_lpbk_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_adp_sw_rstn_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_adp_sw_rstn_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_mr_main_reset_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_mr_main_reset_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_mr_loopback_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_mr_loopback_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_mr_restart_an_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_mr_restart_an_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_speed_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_speed_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_mr_np_loaded_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_mr_np_loaded_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_force_speed_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_force_speed_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_mr_an_enable_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_mr_an_enable_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_power_on_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_power_on_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_mr_reg4_ch_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_mr_reg4_ch_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_mr_main_reset_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_mr_main_reset_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_speed_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_speed_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_mr_np_loaded_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_mr_np_loaded_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_adp_sw_rstn_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_adp_sw_rstn_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_power_on_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_power_on_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_mr_an_enable_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_mr_an_enable_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_mr_reg4_ch_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_mr_reg4_ch_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_mr_restart_an_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_mr_restart_an_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_rem_phy_lpbk_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_rem_phy_lpbk_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_force_speed_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_force_speed_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_mr_loopback_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_mr_loopback_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_mr_loopback_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_mr_loopback_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_mr_reg4_ch_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_mr_reg4_ch_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_mr_restart_an_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_mr_restart_an_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_mr_an_enable_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_mr_an_enable_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_force_speed_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_force_speed_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_mr_main_reset_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_mr_main_reset_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_power_on_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_power_on_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_speed_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_speed_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_rem_phy_lpbk_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_rem_phy_lpbk_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_mr_np_loaded_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_mr_np_loaded_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_adp_sw_rstn_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_adp_sw_rstn_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_sr_xs_pcs_kr_sts1_plu_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_sr_xs_pcs_kr_sts1_plu_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_sr_xs_pcs_kr_sts1_prbs31abl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_sr_xs_pcs_kr_sts1_prbs31abl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_sr_xs_pcs_kr_sts1_rpcs_bklk_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_sr_xs_pcs_kr_sts1_rpcs_bklk_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_sr_xs_pcs_kr_sts1_prcs_hiber_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_sr_xs_pcs_kr_sts1_prcs_hiber_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_sr_xs_pcs_kr_sts1_prbs9abl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_sr_xs_pcs_kr_sts1_prbs9abl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_vr_rst_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_vr_rst_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_usra_rst_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_usra_rst_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_en_2_5g_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_en_2_5g_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_dskbyp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_dskbyp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_en_vsmmd1_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_en_vsmmd1_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_init_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_init_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_cl37_bp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_cl37_bp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_pwrsv_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_pwrsv_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_dtxlaned_3_1_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_dtxlaned_3_1_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_usxg_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_usxg_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_r2tlbe_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_r2tlbe_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_cr_cjn_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_cr_cjn_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_dtxlaned_0_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_dtxlaned_0_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_byp_pwrup_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_byp_pwrup_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_sr_mii_ctrl_lpm_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_sr_mii_ctrl_lpm_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_sr_mii_ctrl_duplex_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_sr_mii_ctrl_duplex_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_sr_mii_ctrl_ss6_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_sr_mii_ctrl_ss6_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_sr_mii_ctrl_ss5_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_sr_mii_ctrl_ss5_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_sr_mii_ctrl_ss13_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_sr_mii_ctrl_ss13_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_sr_mii_ctrl_an_enable_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_sr_mii_ctrl_an_enable_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_sr_mii_ctrl_restart_an_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_sr_mii_ctrl_restart_an_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_sr_mii_ctrl_rst_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_sr_mii_ctrl_rst_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_sr_mii_ctrl_lbe_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_sr_mii_ctrl_lbe_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vr_mii_an_ctrl_pcs_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vr_mii_an_ctrl_pcs_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vr_mii_an_ctrl_mii_an_intr_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vr_mii_an_ctrl_mii_an_intr_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vr_mii_an_ctrl_sgmii_link_sts_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vr_mii_an_ctrl_sgmii_link_sts_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vr_mii_an_ctrl_tx_config_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vr_mii_an_ctrl_tx_config_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vr_mii_an_ctrl_mii_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vr_mii_an_ctrl_mii_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vr_mii_an_intr_sts_usxg_an_sts_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vr_mii_an_intr_sts_usxg_an_sts_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vr_mii_an_intr_sts_cl37_ansgm_sts_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vr_mii_an_intr_sts_cl37_ansgm_sts_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vr_mii_an_intr_sts_cl37_ancmplt_intr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vr_mii_an_intr_sts_cl37_ancmplt_intr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_pll_control_vco_related_selection_get( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_pll_control_vco_related_selection_u *value); + +sw_error_t +hppe_uniphy_pll_control_vco_related_selection_set( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_pll_control_vco_related_selection_u *value); + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_get( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_tx_ac_jtag_mux_driver_selection_u *value); + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_set( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_tx_ac_jtag_mux_driver_selection_u *value); + +sw_error_t +hppe_uniphy_resistor_calibration_1_get( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_resistor_calibration_1_u *value); + +sw_error_t +hppe_uniphy_resistor_calibration_1_set( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_resistor_calibration_1_u *value); + +sw_error_t +hppe_uniphy_pll_vco_related_control_1_get( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_pll_vco_related_control_1_u *value); + +sw_error_t +hppe_uniphy_pll_vco_related_control_1_set( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_pll_vco_related_control_1_u *value); + +sw_error_t +hppe_uniphy_rx_afe_2_get( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_rx_afe_2_u *value); + +sw_error_t +hppe_uniphy_rx_afe_2_set( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_rx_afe_2_u *value); + +sw_error_t +hppe_bandgap_ip_mbias_2_get( + a_uint32_t dev_id, + a_uint32_t index, + union bandgap_ip_mbias_2_u *value); + +sw_error_t +hppe_bandgap_ip_mbias_2_set( + a_uint32_t dev_id, + a_uint32_t index, + union bandgap_ip_mbias_2_u *value); + +sw_error_t +hppe_ldo_0p9v_related_1_get( + a_uint32_t dev_id, + a_uint32_t index, + union ldo_0p9v_related_1_u *value); + +sw_error_t +hppe_ldo_0p9v_related_1_set( + a_uint32_t dev_id, + a_uint32_t index, + union ldo_0p9v_related_1_u *value); + +sw_error_t +hppe_otp_vtt_ldo_related_get( + a_uint32_t dev_id, + a_uint32_t index, + union otp_vtt_ldo_related_u *value); + +sw_error_t +hppe_otp_vtt_ldo_related_set( + a_uint32_t dev_id, + a_uint32_t index, + union otp_vtt_ldo_related_u *value); + +sw_error_t +hppe_otp_temperature_compensate_1_get( + a_uint32_t dev_id, + a_uint32_t index, + union otp_temperature_compensate_1_u *value); + +sw_error_t +hppe_otp_temperature_compensate_1_set( + a_uint32_t dev_id, + a_uint32_t index, + union otp_temperature_compensate_1_u *value); + +sw_error_t +hppe_pll_vco_related_control_1_get( + a_uint32_t dev_id, + a_uint32_t index, + union pll_vco_related_control_1_u *value); + +sw_error_t +hppe_pll_vco_related_control_1_set( + a_uint32_t dev_id, + a_uint32_t index, + union pll_vco_related_control_1_u *value); + +sw_error_t +hppe_pll_control_vco_related_selection_2_get( + a_uint32_t dev_id, + a_uint32_t index, + union pll_control_vco_related_selection_2_u *value); + +sw_error_t +hppe_pll_control_vco_related_selection_2_set( + a_uint32_t dev_id, + a_uint32_t index, + union pll_control_vco_related_selection_2_u *value); + +sw_error_t +hppe_uniphy_pll_control_vco_related_selection_mmd1_reg_src_uphy_pll_vco_gain_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_pll_control_vco_related_selection_mmd1_reg_src_uphy_pll_vco_gain_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_pll_control_vco_related_selection_mmd1_reg_src_uphy_pll_vco_temp_cmp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_pll_control_vco_related_selection_mmd1_reg_src_uphy_pll_vco_temp_cmp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_pll_control_vco_related_selection_mmd1_reg_src_uphy_pll_lpf_c2_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_pll_control_vco_related_selection_mmd1_reg_src_uphy_pll_lpf_c2_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_pll_control_vco_related_selection_mmd1_reg_src_uphy_pll_vco_amp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_pll_control_vco_related_selection_mmd1_reg_src_uphy_pll_vco_amp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_pll_control_vco_related_selection_mmd1_reg_src_uphy_pll_lpf_dc_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_pll_control_vco_related_selection_mmd1_reg_src_uphy_pll_lpf_dc_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_pll_control_vco_related_selection_mmd1_reg_src_uphy_pll_cp_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_pll_control_vco_related_selection_mmd1_reg_src_uphy_pll_cp_sel_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_pll_control_vco_related_selection_mmd1_reg_src_uphy_pll_lpf_res_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_pll_control_vco_related_selection_mmd1_reg_src_uphy_pll_lpf_res_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_mmd1_reg_src_uphy_tx_vcm_delta_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_mmd1_reg_src_uphy_tx_vcm_delta_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_mmd1_reg_src_uphy_tx_emp_lsb_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_mmd1_reg_src_uphy_tx_emp_lsb_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_mmd1_reg_src_uphy_tx_emp_lvl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_mmd1_reg_src_uphy_tx_emp_lvl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_mmd1_reg_src_uphy_tx_acjtag_beacon_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_mmd1_reg_src_uphy_tx_acjtag_beacon_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_mmd1_reg_src_uphy_tx_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_mmd1_reg_src_uphy_tx_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_mmd1_reg_src_uphy_txd_bit_width_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_mmd1_reg_src_uphy_txd_bit_width_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_mmd1_reg_src_uphy_tx_rescal_code_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_mmd1_reg_src_uphy_tx_rescal_code_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_mmd1_reg_src_uphy_tx_amp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_mmd1_reg_src_uphy_tx_amp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_resistor_calibration_1_mmd1_reg_disable_load_res_txrx_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_resistor_calibration_1_mmd1_reg_disable_load_res_txrx_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_resistor_calibration_1_mmd1_reg_calib_tx_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_resistor_calibration_1_mmd1_reg_calib_tx_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_resistor_calibration_1_mmd1_reg_calib_rx_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_resistor_calibration_1_mmd1_reg_calib_rx_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_resistor_calibration_1_mmd1_reg_vref_lvl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_resistor_calibration_1_mmd1_reg_vref_lvl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_pll_vco_related_control_1_miireg_uphy_pll_lckdt_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_pll_vco_related_control_1_miireg_uphy_pll_lckdt_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_pll_vco_related_control_1_miireg_autoload_sel_pll_vco_calib_ready_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_pll_vco_related_control_1_miireg_autoload_sel_pll_vco_calib_ready_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_pll_vco_related_control_1_miireg_reg_uphy_pll_vco_calib_ready_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_pll_vco_related_control_1_miireg_reg_uphy_pll_vco_calib_ready_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_pll_vco_related_control_1_miireg_reg_uphy_pll_vco_temp_cmp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_pll_vco_related_control_1_miireg_reg_uphy_pll_vco_temp_cmp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_pll_vco_related_control_1_miireg_reg_uphy_pll_vco_amp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_pll_vco_related_control_1_miireg_reg_uphy_pll_vco_amp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_pll_vco_related_control_1_miireg_reg_uphy_pll_vco_gain_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_pll_vco_related_control_1_miireg_reg_uphy_pll_vco_gain_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_rx_afe_2_miireg_reg_uphy_rx_afe_res1_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_rx_afe_2_miireg_reg_uphy_rx_afe_res1_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_rx_afe_2_miireg_reg_uphy_rx_afe_cap1_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_rx_afe_2_miireg_reg_uphy_rx_afe_cap1_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_rx_afe_2_miireg_reg_uphy_rx_rescal_code_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_uniphy_rx_afe_2_miireg_reg_uphy_rx_rescal_code_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_bandgap_ip_mbias_2_cmn_mmd1_reg_mbias_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_bandgap_ip_mbias_2_cmn_mmd1_reg_mbias_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_bandgap_ip_mbias_2_cmn_mmd1_reg_cmn_icc_rescode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_bandgap_ip_mbias_2_cmn_mmd1_reg_cmn_icc_rescode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_bandgap_ip_mbias_2_cmn_mmd1_reg_cmn_bg_rsv_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_bandgap_ip_mbias_2_cmn_mmd1_reg_cmn_bg_rsv_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_ldo_ocp_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_ldo_ocp_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_ldo_int_load_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_ldo_int_load_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_ldo_int_res_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_ldo_int_res_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_ldo_vout_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_ldo_vout_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_ldo_ocp_current_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_ldo_ocp_current_sel_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_vtt_ldo_biasgen_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_vtt_ldo_biasgen_sel_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_ldo_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_ldo_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_ldo_comp_current_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_ldo_comp_current_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_ldo_bias_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_ldo_bias_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_otp_vtt_ldo_related_cmn_mmd1_reg_cmn_ana_isolation_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_otp_vtt_ldo_related_cmn_mmd1_reg_cmn_ana_isolation_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_otp_vtt_ldo_related_cmn_mmd1_reg_cmn_vtt_ldo_ocp_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_otp_vtt_ldo_related_cmn_mmd1_reg_cmn_vtt_ldo_ocp_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_otp_vtt_ldo_related_cmn_mmd1_reg_cmn_vtt_ldo_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_otp_vtt_ldo_related_cmn_mmd1_reg_cmn_vtt_ldo_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_otp_vtt_ldo_related_cmn_mmd1_reg_cmn_vtt_ldo_bias_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_otp_vtt_ldo_related_cmn_mmd1_reg_cmn_vtt_ldo_bias_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_otp_vtt_ldo_related_cmn_mmd1_reg_cmn_vtt_ldo_rsv_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_otp_vtt_ldo_related_cmn_mmd1_reg_cmn_vtt_ldo_rsv_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_otp_vtt_ldo_related_cmn_mmd1_reg_cmn_vtt_ldo_ocp_current_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_otp_vtt_ldo_related_cmn_mmd1_reg_cmn_vtt_ldo_ocp_current_sel_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_otp_vtt_ldo_related_cmn_mmd1_reg_cmn_vtt_ldo_int_load_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_otp_vtt_ldo_related_cmn_mmd1_reg_cmn_vtt_ldo_int_load_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_otp_temperature_compensate_1_cmn_mmd1_reg_uphy_ictat100u_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_otp_temperature_compensate_1_cmn_mmd1_reg_uphy_ictat100u_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_otp_temperature_compensate_1_cmn_mmd1_reg_cmn_pll_ictat100u_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_otp_temperature_compensate_1_cmn_mmd1_reg_cmn_pll_ictat100u_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_otp_temperature_compensate_1_cmn_mmd1_reg_uphy_ictat100u_ctrl1_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_otp_temperature_compensate_1_cmn_mmd1_reg_uphy_ictat100u_ctrl1_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_otp_temperature_compensate_1_cmn_mmd1_reg_uphy_ictat100u_ctrl2_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_otp_temperature_compensate_1_cmn_mmd1_reg_uphy_ictat100u_ctrl2_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_otp_temperature_compensate_1_cmn_mmd1_reg_uphy_ictat100u_ctrl0_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_otp_temperature_compensate_1_cmn_mmd1_reg_uphy_ictat100u_ctrl0_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pll_vco_related_control_1_cmn_mii_reg_reg_cmn_pll_vco_calib_ready_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pll_vco_related_control_1_cmn_mii_reg_reg_cmn_pll_vco_calib_ready_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pll_vco_related_control_1_cmn_mii_reg_reg_cmn_pll_vco_temp_cmp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pll_vco_related_control_1_cmn_mii_reg_reg_cmn_pll_vco_temp_cmp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pll_vco_related_control_1_cmn_mii_reg_cmn_pll_lckdt_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pll_vco_related_control_1_cmn_mii_reg_cmn_pll_lckdt_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pll_vco_related_control_1_cmn_mii_reg_reg_cmn_pll_vco_amp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pll_vco_related_control_1_cmn_mii_reg_reg_cmn_pll_vco_amp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pll_vco_related_control_1_cmn_mii_reg_autoload_sel_pll_vco_calib_ready_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pll_vco_related_control_1_cmn_mii_reg_autoload_sel_pll_vco_calib_ready_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pll_control_vco_related_selection_2_cmn_mmd1_reg_src_cmn_pll_vco_calib_ready_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pll_control_vco_related_selection_2_cmn_mmd1_reg_src_cmn_pll_vco_calib_ready_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pll_control_vco_related_selection_2_cmn_mmd1_reg_src_cmn_pll_vco_temp_cmp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pll_control_vco_related_selection_2_cmn_mmd1_reg_src_cmn_pll_vco_temp_cmp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pll_control_vco_related_selection_2_cmn_mmd1_reg_src_cmn_pll_vco_amp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pll_control_vco_related_selection_2_cmn_mmd1_reg_src_cmn_pll_vco_amp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pll_control_vco_related_selection_2_cmn_mmd1_reg_src_cmn_pll_vco_calib_start_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pll_control_vco_related_selection_2_cmn_mmd1_reg_src_cmn_pll_vco_calib_start_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pll_control_vco_related_selection_2_cmn_mmd1_reg_src_cmn_pll_vco_calib_code_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pll_control_vco_related_selection_2_cmn_mmd1_reg_src_cmn_pll_vco_calib_code_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pll_control_vco_related_selection_2_cmn_mmd1_reg_src_cmn_pll_fbclk_div_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pll_control_vco_related_selection_2_cmn_mmd1_reg_src_cmn_pll_fbclk_div_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_uniphy_phy_mode_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_misc2_phy_mode_u *value); + +sw_error_t +hppe_uniphy_phy_mode_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_misc2_phy_mode_u *value); + +sw_error_t +hppe_uniphy_pll_reset_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union pll_power_on_and_reset_u *value); + +sw_error_t +hppe_uniphy_pll_reset_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union pll_power_on_and_reset_u *value); + +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_uniphy_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_uniphy_reg.h new file mode 100755 index 000000000..773a3fe4c --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_uniphy_reg.h @@ -0,0 +1,1594 @@ +/* + * 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. + */ + + +/** + * @defgroup + * @{ + */ +#ifndef HPPE_UNIPHY_REG_H +#define HPPE_UNIPHY_REG_H + +/*[register] UNIPHY_OFFSET_CALIB_4*/ +#define UNIPHY_OFFSET_CALIB_4 +#define UNIPHY_OFFSET_CALIB_4_ADDRESS 0x1e0 +#define UNIPHY_OFFSET_CALIB_4_NUM 3 +#define UNIPHY_OFFSET_CALIB_4_INC 0x1 +#define UNIPHY_OFFSET_CALIB_4_TYPE REG_TYPE_RW +#define UNIPHY_OFFSET_CALIB_4_DEFAULT 0x0 + /*[field] MMD1_REG_SMPL_CAL_READY*/ + #define UNIPHY_OFFSET_CALIB_4_MMD1_REG_SMPL_CAL_READY + #define UNIPHY_OFFSET_CALIB_4_MMD1_REG_SMPL_CAL_READY_OFFSET 0 + #define UNIPHY_OFFSET_CALIB_4_MMD1_REG_SMPL_CAL_READY_LEN 1 + #define UNIPHY_OFFSET_CALIB_4_MMD1_REG_SMPL_CAL_READY_DEFAULT 0x0 + /*[field] MMD1_REG_CLR_SAMPLER_CALIB_TIMEOUT*/ + #define UNIPHY_OFFSET_CALIB_4_MMD1_REG_CLR_SAMPLER_CALIB_TIMEOUT + #define UNIPHY_OFFSET_CALIB_4_MMD1_REG_CLR_SAMPLER_CALIB_TIMEOUT_OFFSET 1 + #define UNIPHY_OFFSET_CALIB_4_MMD1_REG_CLR_SAMPLER_CALIB_TIMEOUT_LEN 1 + #define UNIPHY_OFFSET_CALIB_4_MMD1_REG_CLR_SAMPLER_CALIB_TIMEOUT_DEFAULT 0x0 + /*[field] MMD1_REG_LOCKDET_LCKDT_REG*/ + #define UNIPHY_OFFSET_CALIB_4_MMD1_REG_LOCKDET_LCKDT_REG + #define UNIPHY_OFFSET_CALIB_4_MMD1_REG_LOCKDET_LCKDT_REG_OFFSET 4 + #define UNIPHY_OFFSET_CALIB_4_MMD1_REG_LOCKDET_LCKDT_REG_LEN 1 + #define UNIPHY_OFFSET_CALIB_4_MMD1_REG_LOCKDET_LCKDT_REG_DEFAULT 0x0 + /*[field] MMD1_REG_PLL_LOCKED_REG*/ + #define UNIPHY_OFFSET_CALIB_4_MMD1_REG_PLL_LOCKED_REG + #define UNIPHY_OFFSET_CALIB_4_MMD1_REG_PLL_LOCKED_REG_OFFSET 6 + #define UNIPHY_OFFSET_CALIB_4_MMD1_REG_PLL_LOCKED_REG_LEN 1 + #define UNIPHY_OFFSET_CALIB_4_MMD1_REG_PLL_LOCKED_REG_DEFAULT 0x0 + /*[field] MMD1_REG_CALIBRATION_DONE_REG*/ + #define UNIPHY_OFFSET_CALIB_4_MMD1_REG_CALIBRATION_DONE_REG + #define UNIPHY_OFFSET_CALIB_4_MMD1_REG_CALIBRATION_DONE_REG_OFFSET 7 + #define UNIPHY_OFFSET_CALIB_4_MMD1_REG_CALIBRATION_DONE_REG_LEN 1 + #define UNIPHY_OFFSET_CALIB_4_MMD1_REG_CALIBRATION_DONE_REG_DEFAULT 0x0 + /*[field] MMD1_REG_CAL_DETECT_TIME*/ + #define UNIPHY_OFFSET_CALIB_4_MMD1_REG_CAL_DETECT_TIME + #define UNIPHY_OFFSET_CALIB_4_MMD1_REG_CAL_DETECT_TIME_OFFSET 8 + #define UNIPHY_OFFSET_CALIB_4_MMD1_REG_CAL_DETECT_TIME_LEN 5 + #define UNIPHY_OFFSET_CALIB_4_MMD1_REG_CAL_DETECT_TIME_DEFAULT 0x0 + /*[field] MMD1_REG_CAL_REP_TIME*/ + #define UNIPHY_OFFSET_CALIB_4_MMD1_REG_CAL_REP_TIME + #define UNIPHY_OFFSET_CALIB_4_MMD1_REG_CAL_REP_TIME_OFFSET 13 + #define UNIPHY_OFFSET_CALIB_4_MMD1_REG_CAL_REP_TIME_LEN 3 + #define UNIPHY_OFFSET_CALIB_4_MMD1_REG_CAL_REP_TIME_DEFAULT 0x0 + +struct uniphy_offset_calib_4 { + a_uint32_t mmd1_reg_smpl_cal_ready:1; + a_uint32_t mmd1_reg_clr_sampler_calib_timeout:1; + a_uint32_t _reserved0:2; + a_uint32_t mmd1_reg_lockdet_lckdt_reg:1; + a_uint32_t _reserved1:1; + a_uint32_t mmd1_reg_pll_locked_reg:1; + a_uint32_t mmd1_reg_calibration_done_reg:1; + a_uint32_t mmd1_reg_cal_detect_time:5; + a_uint32_t mmd1_reg_cal_rep_time:3; + a_uint32_t _reserved2:16; +}; + +union uniphy_offset_calib_4_u { + a_uint32_t val; + struct uniphy_offset_calib_4 bf; +}; + +/*[register] UNIPHY_MODE_CTRL*/ +#define UNIPHY_MODE_CTRL +#define UNIPHY_MODE_CTRL_ADDRESS 0x46c +#define UNIPHY_MODE_CTRL_NUM 3 +#define UNIPHY_MODE_CTRL_INC 0x1 +#define UNIPHY_MODE_CTRL_TYPE REG_TYPE_RW +#define UNIPHY_MODE_CTRL_DEFAULT 0x221 + /*[field] NEWADDEDFROMHERE_CH0_AUTONEG_MODE*/ + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_CH0_AUTONEG_MODE + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_CH0_AUTONEG_MODE_OFFSET 0 + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_CH0_AUTONEG_MODE_LEN 1 + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_CH0_AUTONEG_MODE_DEFAULT 0x1 + /*[field] NEWADDEDFROMHERE_CH1_CH0_SGMII*/ + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_CH1_CH0_SGMII + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_CH1_CH0_SGMII_OFFSET 1 + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_CH1_CH0_SGMII_LEN 1 + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_CH1_CH0_SGMII_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH4_CH1_0_SGMII*/ + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_CH4_CH1_0_SGMII + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_CH4_CH1_0_SGMII_OFFSET 2 + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_CH4_CH1_0_SGMII_LEN 1 + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_CH4_CH1_0_SGMII_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_SGMII_EVEN_LOW*/ + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_SGMII_EVEN_LOW + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_SGMII_EVEN_LOW_OFFSET 3 + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_SGMII_EVEN_LOW_LEN 1 + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_SGMII_EVEN_LOW_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH0_MODE_CTRL_25M*/ + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_CH0_MODE_CTRL_25M + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_CH0_MODE_CTRL_25M_OFFSET 4 + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_CH0_MODE_CTRL_25M_LEN 3 + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_CH0_MODE_CTRL_25M_DEFAULT 0x2 + /*[field] NEWADDEDFROMHERE_CH0_QSGMII_SGMII*/ + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_CH0_QSGMII_SGMII + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_CH0_QSGMII_SGMII_OFFSET 8 + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_CH0_QSGMII_SGMII_LEN 1 + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_CH0_QSGMII_SGMII_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH0_PSGMII_QSGMII*/ + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_CH0_PSGMII_QSGMII + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_CH0_PSGMII_QSGMII_OFFSET 9 + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_CH0_PSGMII_QSGMII_LEN 1 + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_CH0_PSGMII_QSGMII_DEFAULT 0x1 + /*[field] NEWADDEDFROMHERE_SG_MODE*/ + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_SG_MODE + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_SG_MODE_OFFSET 10 + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_SG_MODE_LEN 1 + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_SG_MODE_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_SGPLUS_MODE*/ + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_SGPLUS_MODE + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_SGPLUS_MODE_OFFSET 11 + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_SGPLUS_MODE_LEN 1 + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_SGPLUS_MODE_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_XPCS_MODE*/ + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_XPCS_MODE + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_XPCS_MODE_OFFSET 12 + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_XPCS_MODE_LEN 1 + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_XPCS_MODE_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_USXG_EN*/ + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_USXG_EN + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_USXG_EN_OFFSET 13 + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_USXG_EN_LEN 1 + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_USXG_EN_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_SW_V17_V18*/ + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_SW_V17_V18 + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_SW_V17_V18_OFFSET 15 + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_SW_V17_V18_LEN 1 + #define UNIPHY_MODE_CTRL_NEWADDEDFROMHERE_SW_V17_V18_DEFAULT 0x0 + +struct uniphy_mode_ctrl { + a_uint32_t newaddedfromhere_ch0_autoneg_mode:1; + a_uint32_t newaddedfromhere_ch1_ch0_sgmii:1; + a_uint32_t newaddedfromhere_ch4_ch1_0_sgmii:1; + a_uint32_t newaddedfromhere_sgmii_even_low:1; + a_uint32_t newaddedfromhere_ch0_mode_ctrl_25m:3; + a_uint32_t _reserved0:1; + a_uint32_t newaddedfromhere_ch0_qsgmii_sgmii:1; + a_uint32_t newaddedfromhere_ch0_psgmii_qsgmii:1; + a_uint32_t newaddedfromhere_sg_mode:1; + a_uint32_t newaddedfromhere_sgplus_mode:1; + a_uint32_t newaddedfromhere_xpcs_mode:1; + a_uint32_t newaddedfromhere_usxg_en:1; + a_uint32_t _reserved1:1; + a_uint32_t newaddedfromhere_sw_v17_v18:1; + a_uint32_t _reserved2:16; +}; + +union uniphy_mode_ctrl_u { + a_uint32_t val; + struct uniphy_mode_ctrl bf; +}; + +/*[register] UNIPHY_CHANNEL0_INPUT_OUTPUT_4*/ +#define UNIPHY_CHANNEL0_INPUT_OUTPUT_4 +#define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_ADDRESS 0x480 +#define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NUM 3 +#define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_INC 0x1 +#define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_TYPE REG_TYPE_RW +#define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_DEFAULT 0x844 + /*[field] NEWADDEDFROMHERE_CH0_REM_PHY_LPBK*/ + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_REM_PHY_LPBK + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_REM_PHY_LPBK_OFFSET 0 + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_REM_PHY_LPBK_LEN 1 + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_REM_PHY_LPBK_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH0_SPEED_25M*/ + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_SPEED_25M + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_SPEED_25M_OFFSET 1 + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_SPEED_25M_LEN 2 + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_SPEED_25M_DEFAULT 0x2 + /*[field] NEWADDEDFROMHERE_CH0_FORCE_SPEED_25M*/ + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_FORCE_SPEED_25M + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_FORCE_SPEED_25M_OFFSET 3 + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_FORCE_SPEED_25M_LEN 1 + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_FORCE_SPEED_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH0_MR_NP_LOADED_25M*/ + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_MR_NP_LOADED_25M + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_MR_NP_LOADED_25M_OFFSET 4 + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_MR_NP_LOADED_25M_LEN 1 + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_MR_NP_LOADED_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH0_MR_REG4_CH_25M*/ + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_MR_REG4_CH_25M + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_MR_REG4_CH_25M_OFFSET 5 + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_MR_REG4_CH_25M_LEN 1 + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_MR_REG4_CH_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH0_MR_AN_ENABLE_25M*/ + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_MR_AN_ENABLE_25M + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_MR_AN_ENABLE_25M_OFFSET 6 + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_MR_AN_ENABLE_25M_LEN 1 + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_MR_AN_ENABLE_25M_DEFAULT 0x1 + /*[field] NEWADDEDFROMHERE_CH0_MR_RESTART_AN_25M*/ + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_MR_RESTART_AN_25M + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_MR_RESTART_AN_25M_OFFSET 7 + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_MR_RESTART_AN_25M_LEN 1 + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_MR_RESTART_AN_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH0_MR_LOOPBACK_25M*/ + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_MR_LOOPBACK_25M + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_MR_LOOPBACK_25M_OFFSET 8 + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_MR_LOOPBACK_25M_LEN 1 + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_MR_LOOPBACK_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH0_MR_MAIN_RESET_25M*/ + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_MR_MAIN_RESET_25M + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_MR_MAIN_RESET_25M_OFFSET 9 + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_MR_MAIN_RESET_25M_LEN 1 + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_MR_MAIN_RESET_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH0_POWER_ON_25M*/ + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_POWER_ON_25M + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_POWER_ON_25M_OFFSET 10 + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_POWER_ON_25M_LEN 1 + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_POWER_ON_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH0_ADP_SW_RSTN*/ + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_ADP_SW_RSTN + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_ADP_SW_RSTN_OFFSET 11 + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_ADP_SW_RSTN_LEN 1 + #define UNIPHY_CHANNEL0_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH0_ADP_SW_RSTN_DEFAULT 0x1 + +struct uniphy_channel0_input_output_4 { + a_uint32_t newaddedfromhere_ch0_rem_phy_lpbk:1; + a_uint32_t newaddedfromhere_ch0_speed_25m:2; + a_uint32_t newaddedfromhere_ch0_force_speed_25m:1; + a_uint32_t newaddedfromhere_ch0_mr_np_loaded_25m:1; + a_uint32_t newaddedfromhere_ch0_mr_reg4_ch_25m:1; + a_uint32_t newaddedfromhere_ch0_mr_an_enable_25m:1; + a_uint32_t newaddedfromhere_ch0_mr_restart_an_25m:1; + a_uint32_t newaddedfromhere_ch0_mr_loopback_25m:1; + a_uint32_t newaddedfromhere_ch0_mr_main_reset_25m:1; + a_uint32_t newaddedfromhere_ch0_power_on_25m:1; + a_uint32_t newaddedfromhere_ch0_adp_sw_rstn:1; + a_uint32_t _reserved0:20; +}; + +union uniphy_channel0_input_output_4_u { + a_uint32_t val; + struct uniphy_channel0_input_output_4 bf; +}; + +/*[register] UNIPHY_CHANNEL1_INPUT_OUTPUT_4*/ +#define UNIPHY_CHANNEL1_INPUT_OUTPUT_4 +#define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_ADDRESS 0x498 +#define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NUM 3 +#define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_INC 0x1 +#define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_TYPE REG_TYPE_RW +#define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_DEFAULT 0x844 + /*[field] NEWADDEDFROMHERE_CH1_REM_PHY_LPBK*/ + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_REM_PHY_LPBK + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_REM_PHY_LPBK_OFFSET 0 + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_REM_PHY_LPBK_LEN 1 + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_REM_PHY_LPBK_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH1_SPEED_25M*/ + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_SPEED_25M + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_SPEED_25M_OFFSET 1 + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_SPEED_25M_LEN 2 + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_SPEED_25M_DEFAULT 0x2 + /*[field] NEWADDEDFROMHERE_CH1_FORCE_SPEED_25M*/ + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_FORCE_SPEED_25M + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_FORCE_SPEED_25M_OFFSET 3 + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_FORCE_SPEED_25M_LEN 1 + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_FORCE_SPEED_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH1_MR_NP_LOADED_25M*/ + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_MR_NP_LOADED_25M + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_MR_NP_LOADED_25M_OFFSET 4 + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_MR_NP_LOADED_25M_LEN 1 + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_MR_NP_LOADED_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH1_MR_REG4_CH_25M*/ + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_MR_REG4_CH_25M + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_MR_REG4_CH_25M_OFFSET 5 + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_MR_REG4_CH_25M_LEN 1 + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_MR_REG4_CH_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH1_MR_AN_ENABLE_25M*/ + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_MR_AN_ENABLE_25M + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_MR_AN_ENABLE_25M_OFFSET 6 + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_MR_AN_ENABLE_25M_LEN 1 + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_MR_AN_ENABLE_25M_DEFAULT 0x1 + /*[field] NEWADDEDFROMHERE_CH1_MR_RESTART_AN_25M*/ + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_MR_RESTART_AN_25M + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_MR_RESTART_AN_25M_OFFSET 7 + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_MR_RESTART_AN_25M_LEN 1 + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_MR_RESTART_AN_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH1_MR_LOOPBACK_25M*/ + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_MR_LOOPBACK_25M + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_MR_LOOPBACK_25M_OFFSET 8 + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_MR_LOOPBACK_25M_LEN 1 + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_MR_LOOPBACK_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH1_MR_MAIN_RESET_25M*/ + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_MR_MAIN_RESET_25M + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_MR_MAIN_RESET_25M_OFFSET 9 + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_MR_MAIN_RESET_25M_LEN 1 + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_MR_MAIN_RESET_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH1_POWER_ON_25M*/ + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_POWER_ON_25M + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_POWER_ON_25M_OFFSET 10 + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_POWER_ON_25M_LEN 1 + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_POWER_ON_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH1_ADP_SW_RSTN*/ + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_ADP_SW_RSTN + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_ADP_SW_RSTN_OFFSET 11 + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_ADP_SW_RSTN_LEN 1 + #define UNIPHY_CHANNEL1_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH1_ADP_SW_RSTN_DEFAULT 0x1 + +struct uniphy_channel1_input_output_4 { + a_uint32_t newaddedfromhere_ch1_rem_phy_lpbk:1; + a_uint32_t newaddedfromhere_ch1_speed_25m:2; + a_uint32_t newaddedfromhere_ch1_force_speed_25m:1; + a_uint32_t newaddedfromhere_ch1_mr_np_loaded_25m:1; + a_uint32_t newaddedfromhere_ch1_mr_reg4_ch_25m:1; + a_uint32_t newaddedfromhere_ch1_mr_an_enable_25m:1; + a_uint32_t newaddedfromhere_ch1_mr_restart_an_25m:1; + a_uint32_t newaddedfromhere_ch1_mr_loopback_25m:1; + a_uint32_t newaddedfromhere_ch1_mr_main_reset_25m:1; + a_uint32_t newaddedfromhere_ch1_power_on_25m:1; + a_uint32_t newaddedfromhere_ch1_adp_sw_rstn:1; + a_uint32_t _reserved0:20; +}; + +union uniphy_channel1_input_output_4_u { + a_uint32_t val; + struct uniphy_channel1_input_output_4 bf; +}; + +/*[register] UNIPHY_CHANNEL2_INPUT_OUTPUT_4*/ +#define UNIPHY_CHANNEL2_INPUT_OUTPUT_4 +#define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_ADDRESS 0x4b0 +#define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NUM 3 +#define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_INC 0x1 +#define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_TYPE REG_TYPE_RW +#define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_DEFAULT 0x844 + /*[field] NEWADDEDFROMHERE_CH2_REM_PHY_LPBK*/ + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_REM_PHY_LPBK + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_REM_PHY_LPBK_OFFSET 0 + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_REM_PHY_LPBK_LEN 1 + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_REM_PHY_LPBK_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH2_SPEED_25M*/ + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_SPEED_25M + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_SPEED_25M_OFFSET 1 + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_SPEED_25M_LEN 2 + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_SPEED_25M_DEFAULT 0x2 + /*[field] NEWADDEDFROMHERE_CH2_FORCE_SPEED_25M*/ + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_FORCE_SPEED_25M + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_FORCE_SPEED_25M_OFFSET 3 + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_FORCE_SPEED_25M_LEN 1 + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_FORCE_SPEED_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH2_MR_NP_LOADED_25M*/ + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_MR_NP_LOADED_25M + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_MR_NP_LOADED_25M_OFFSET 4 + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_MR_NP_LOADED_25M_LEN 1 + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_MR_NP_LOADED_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH2_MR_REG4_CH_25M*/ + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_MR_REG4_CH_25M + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_MR_REG4_CH_25M_OFFSET 5 + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_MR_REG4_CH_25M_LEN 1 + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_MR_REG4_CH_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH2_MR_AN_ENABLE_25M*/ + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_MR_AN_ENABLE_25M + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_MR_AN_ENABLE_25M_OFFSET 6 + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_MR_AN_ENABLE_25M_LEN 1 + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_MR_AN_ENABLE_25M_DEFAULT 0x1 + /*[field] NEWADDEDFROMHERE_CH2_MR_RESTART_AN_25M*/ + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_MR_RESTART_AN_25M + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_MR_RESTART_AN_25M_OFFSET 7 + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_MR_RESTART_AN_25M_LEN 1 + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_MR_RESTART_AN_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH2_MR_LOOPBACK_25M*/ + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_MR_LOOPBACK_25M + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_MR_LOOPBACK_25M_OFFSET 8 + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_MR_LOOPBACK_25M_LEN 1 + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_MR_LOOPBACK_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH2_MR_MAIN_RESET_25M*/ + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_MR_MAIN_RESET_25M + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_MR_MAIN_RESET_25M_OFFSET 9 + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_MR_MAIN_RESET_25M_LEN 1 + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_MR_MAIN_RESET_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH2_POWER_ON_25M*/ + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_POWER_ON_25M + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_POWER_ON_25M_OFFSET 10 + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_POWER_ON_25M_LEN 1 + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_POWER_ON_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH2_ADP_SW_RSTN*/ + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_ADP_SW_RSTN + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_ADP_SW_RSTN_OFFSET 11 + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_ADP_SW_RSTN_LEN 1 + #define UNIPHY_CHANNEL2_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH2_ADP_SW_RSTN_DEFAULT 0x1 + +struct uniphy_channel2_input_output_4 { + a_uint32_t newaddedfromhere_ch2_rem_phy_lpbk:1; + a_uint32_t newaddedfromhere_ch2_speed_25m:2; + a_uint32_t newaddedfromhere_ch2_force_speed_25m:1; + a_uint32_t newaddedfromhere_ch2_mr_np_loaded_25m:1; + a_uint32_t newaddedfromhere_ch2_mr_reg4_ch_25m:1; + a_uint32_t newaddedfromhere_ch2_mr_an_enable_25m:1; + a_uint32_t newaddedfromhere_ch2_mr_restart_an_25m:1; + a_uint32_t newaddedfromhere_ch2_mr_loopback_25m:1; + a_uint32_t newaddedfromhere_ch2_mr_main_reset_25m:1; + a_uint32_t newaddedfromhere_ch2_power_on_25m:1; + a_uint32_t newaddedfromhere_ch2_adp_sw_rstn:1; + a_uint32_t _reserved0:20; +}; + +union uniphy_channel2_input_output_4_u { + a_uint32_t val; + struct uniphy_channel2_input_output_4 bf; +}; + +/*[register] UNIPHY_CHANNEL3_INPUT_OUTPUT_4*/ +#define UNIPHY_CHANNEL3_INPUT_OUTPUT_4 +#define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_ADDRESS 0x4c8 +#define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NUM 3 +#define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_INC 0x1 +#define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_TYPE REG_TYPE_RW +#define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_DEFAULT 0x844 + /*[field] NEWADDEDFROMHERE_CH3_REM_PHY_LPBK*/ + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_REM_PHY_LPBK + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_REM_PHY_LPBK_OFFSET 0 + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_REM_PHY_LPBK_LEN 1 + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_REM_PHY_LPBK_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH3_SPEED_25M*/ + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_SPEED_25M + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_SPEED_25M_OFFSET 1 + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_SPEED_25M_LEN 2 + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_SPEED_25M_DEFAULT 0x2 + /*[field] NEWADDEDFROMHERE_CH3_FORCE_SPEED_25M*/ + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_FORCE_SPEED_25M + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_FORCE_SPEED_25M_OFFSET 3 + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_FORCE_SPEED_25M_LEN 1 + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_FORCE_SPEED_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH3_MR_NP_LOADED_25M*/ + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_MR_NP_LOADED_25M + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_MR_NP_LOADED_25M_OFFSET 4 + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_MR_NP_LOADED_25M_LEN 1 + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_MR_NP_LOADED_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH3_MR_REG4_CH_25M*/ + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_MR_REG4_CH_25M + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_MR_REG4_CH_25M_OFFSET 5 + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_MR_REG4_CH_25M_LEN 1 + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_MR_REG4_CH_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH3_MR_AN_ENABLE_25M*/ + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_MR_AN_ENABLE_25M + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_MR_AN_ENABLE_25M_OFFSET 6 + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_MR_AN_ENABLE_25M_LEN 1 + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_MR_AN_ENABLE_25M_DEFAULT 0x1 + /*[field] NEWADDEDFROMHERE_CH3_MR_RESTART_AN_25M*/ + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_MR_RESTART_AN_25M + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_MR_RESTART_AN_25M_OFFSET 7 + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_MR_RESTART_AN_25M_LEN 1 + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_MR_RESTART_AN_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH3_MR_LOOPBACK_25M*/ + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_MR_LOOPBACK_25M + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_MR_LOOPBACK_25M_OFFSET 8 + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_MR_LOOPBACK_25M_LEN 1 + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_MR_LOOPBACK_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH3_MR_MAIN_RESET_25M*/ + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_MR_MAIN_RESET_25M + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_MR_MAIN_RESET_25M_OFFSET 9 + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_MR_MAIN_RESET_25M_LEN 1 + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_MR_MAIN_RESET_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH3_POWER_ON_25M*/ + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_POWER_ON_25M + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_POWER_ON_25M_OFFSET 10 + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_POWER_ON_25M_LEN 1 + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_POWER_ON_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH3_ADP_SW_RSTN*/ + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_ADP_SW_RSTN + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_ADP_SW_RSTN_OFFSET 11 + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_ADP_SW_RSTN_LEN 1 + #define UNIPHY_CHANNEL3_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH3_ADP_SW_RSTN_DEFAULT 0x1 + +struct uniphy_channel3_input_output_4 { + a_uint32_t newaddedfromhere_ch3_rem_phy_lpbk:1; + a_uint32_t newaddedfromhere_ch3_speed_25m:2; + a_uint32_t newaddedfromhere_ch3_force_speed_25m:1; + a_uint32_t newaddedfromhere_ch3_mr_np_loaded_25m:1; + a_uint32_t newaddedfromhere_ch3_mr_reg4_ch_25m:1; + a_uint32_t newaddedfromhere_ch3_mr_an_enable_25m:1; + a_uint32_t newaddedfromhere_ch3_mr_restart_an_25m:1; + a_uint32_t newaddedfromhere_ch3_mr_loopback_25m:1; + a_uint32_t newaddedfromhere_ch3_mr_main_reset_25m:1; + a_uint32_t newaddedfromhere_ch3_power_on_25m:1; + a_uint32_t newaddedfromhere_ch3_adp_sw_rstn:1; + a_uint32_t _reserved0:20; +}; + +union uniphy_channel3_input_output_4_u { + a_uint32_t val; + struct uniphy_channel3_input_output_4 bf; +}; + +/*[register] UNIPHY_CHANNEL4_INPUT_OUTPUT_4*/ +#define UNIPHY_CHANNEL4_INPUT_OUTPUT_4 +#define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_ADDRESS 0x4e0 +#define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NUM 3 +#define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_INC 0x1 +#define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_TYPE REG_TYPE_RW +#define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_DEFAULT 0x844 + /*[field] NEWADDEDFROMHERE_CH4_REM_PHY_LPBK*/ + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_REM_PHY_LPBK + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_REM_PHY_LPBK_OFFSET 0 + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_REM_PHY_LPBK_LEN 1 + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_REM_PHY_LPBK_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH4_SPEED_25M*/ + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_SPEED_25M + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_SPEED_25M_OFFSET 1 + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_SPEED_25M_LEN 2 + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_SPEED_25M_DEFAULT 0x2 + /*[field] NEWADDEDFROMHERE_CH4_FORCE_SPEED_25M*/ + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_FORCE_SPEED_25M + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_FORCE_SPEED_25M_OFFSET 3 + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_FORCE_SPEED_25M_LEN 1 + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_FORCE_SPEED_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH4_MR_NP_LOADED_25M*/ + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_MR_NP_LOADED_25M + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_MR_NP_LOADED_25M_OFFSET 4 + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_MR_NP_LOADED_25M_LEN 1 + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_MR_NP_LOADED_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH4_MR_REG4_CH_25M*/ + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_MR_REG4_CH_25M + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_MR_REG4_CH_25M_OFFSET 5 + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_MR_REG4_CH_25M_LEN 1 + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_MR_REG4_CH_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH4_MR_AN_ENABLE_25M*/ + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_MR_AN_ENABLE_25M + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_MR_AN_ENABLE_25M_OFFSET 6 + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_MR_AN_ENABLE_25M_LEN 1 + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_MR_AN_ENABLE_25M_DEFAULT 0x1 + /*[field] NEWADDEDFROMHERE_CH4_MR_RESTART_AN_25M*/ + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_MR_RESTART_AN_25M + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_MR_RESTART_AN_25M_OFFSET 7 + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_MR_RESTART_AN_25M_LEN 1 + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_MR_RESTART_AN_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH4_MR_LOOPBACK_25M*/ + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_MR_LOOPBACK_25M + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_MR_LOOPBACK_25M_OFFSET 8 + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_MR_LOOPBACK_25M_LEN 1 + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_MR_LOOPBACK_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH4_MR_MAIN_RESET_25M*/ + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_MR_MAIN_RESET_25M + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_MR_MAIN_RESET_25M_OFFSET 9 + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_MR_MAIN_RESET_25M_LEN 1 + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_MR_MAIN_RESET_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH4_POWER_ON_25M*/ + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_POWER_ON_25M + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_POWER_ON_25M_OFFSET 10 + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_POWER_ON_25M_LEN 1 + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_POWER_ON_25M_DEFAULT 0x0 + /*[field] NEWADDEDFROMHERE_CH4_ADP_SW_RSTN*/ + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_ADP_SW_RSTN + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_ADP_SW_RSTN_OFFSET 11 + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_ADP_SW_RSTN_LEN 1 + #define UNIPHY_CHANNEL4_INPUT_OUTPUT_4_NEWADDEDFROMHERE_CH4_ADP_SW_RSTN_DEFAULT 0x1 + +struct uniphy_channel4_input_output_4 { + a_uint32_t newaddedfromhere_ch4_rem_phy_lpbk:1; + a_uint32_t newaddedfromhere_ch4_speed_25m:2; + a_uint32_t newaddedfromhere_ch4_force_speed_25m:1; + a_uint32_t newaddedfromhere_ch4_mr_np_loaded_25m:1; + a_uint32_t newaddedfromhere_ch4_mr_reg4_ch_25m:1; + a_uint32_t newaddedfromhere_ch4_mr_an_enable_25m:1; + a_uint32_t newaddedfromhere_ch4_mr_restart_an_25m:1; + a_uint32_t newaddedfromhere_ch4_mr_loopback_25m:1; + a_uint32_t newaddedfromhere_ch4_mr_main_reset_25m:1; + a_uint32_t newaddedfromhere_ch4_power_on_25m:1; + a_uint32_t newaddedfromhere_ch4_adp_sw_rstn:1; + a_uint32_t _reserved0:20; +}; + +union uniphy_channel4_input_output_4_u { + a_uint32_t val; + struct uniphy_channel4_input_output_4 bf; +}; + +/*[register] UNIPHY_INSTANCE_LINK_DETECT*/ +#define UNIPHY_INSTANCE_LINK_DETECT +#define UNIPHY_INSTANCE_LINK_DETECT_ADDRESS 0x570 +#define UNIPHY_INSTANCE_LINK_DETECT_NUM 3 +#define UNIPHY_INSTANCE_LINK_DETECT_INC 0x1 +#define UNIPHY_INSTANCE_LINK_DETECT_TYPE REG_TYPE_RW +#define UNIPHY_INSTANCE_LINK_DETECT_DEFAULT 0x0 + +struct uniphy_instance_link_detect { + a_uint32_t _reserved0:6; + a_uint32_t detect_los_from_sfp:3; + a_uint32_t _reserved1:23; +}; + +union uniphy_instance_link_detect_u { + a_uint32_t val; + struct uniphy_instance_link_detect bf; +}; + +/*[register] SR_XS_PCS_KR_STS1*/ +#define SR_XS_PCS_KR_STS1 +#define SR_XS_PCS_KR_STS1_ADDRESS 0x30020 +#define SR_XS_PCS_KR_STS1_NUM 3 +#define SR_XS_PCS_KR_STS1_INC 0x1 +#define SR_XS_PCS_KR_STS1_TYPE REG_TYPE_RW +#define SR_XS_PCS_KR_STS1_DEFAULT 0x0 + /*[field] RPCS_BKLK*/ + #define SR_XS_PCS_KR_STS1_RPCS_BKLK + #define SR_XS_PCS_KR_STS1_RPCS_BKLK_OFFSET 0 + #define SR_XS_PCS_KR_STS1_RPCS_BKLK_LEN 1 + #define SR_XS_PCS_KR_STS1_RPCS_BKLK_DEFAULT 0x0 + /*[field] PRCS_HIBER*/ + #define SR_XS_PCS_KR_STS1_PRCS_HIBER + #define SR_XS_PCS_KR_STS1_PRCS_HIBER_OFFSET 1 + #define SR_XS_PCS_KR_STS1_PRCS_HIBER_LEN 1 + #define SR_XS_PCS_KR_STS1_PRCS_HIBER_DEFAULT 0x0 + /*[field] PRBS31ABL*/ + #define SR_XS_PCS_KR_STS1_PRBS31ABL + #define SR_XS_PCS_KR_STS1_PRBS31ABL_OFFSET 2 + #define SR_XS_PCS_KR_STS1_PRBS31ABL_LEN 1 + #define SR_XS_PCS_KR_STS1_PRBS31ABL_DEFAULT 0x0 + /*[field] PRBS9ABL*/ + #define SR_XS_PCS_KR_STS1_PRBS9ABL + #define SR_XS_PCS_KR_STS1_PRBS9ABL_OFFSET 3 + #define SR_XS_PCS_KR_STS1_PRBS9ABL_LEN 1 + #define SR_XS_PCS_KR_STS1_PRBS9ABL_DEFAULT 0x0 + /*[field] PLU*/ + #define SR_XS_PCS_KR_STS1_PLU + #define SR_XS_PCS_KR_STS1_PLU_OFFSET 12 + #define SR_XS_PCS_KR_STS1_PLU_LEN 1 + #define SR_XS_PCS_KR_STS1_PLU_DEFAULT 0x0 + +struct sr_xs_pcs_kr_sts1 { + a_uint32_t rpcs_bklk:1; + a_uint32_t prcs_hiber:1; + a_uint32_t prbs31abl:1; + a_uint32_t prbs9abl:1; + a_uint32_t _reserved0:8; + a_uint32_t plu:1; + a_uint32_t _reserved1:19; +}; + +union sr_xs_pcs_kr_sts1_u { + a_uint32_t val; + struct sr_xs_pcs_kr_sts1 bf; +}; + +/*[register] VR_XS_PCS_DIG_CTRL1*/ +#define VR_XS_PCS_DIG_CTRL1 +#define VR_XS_PCS_DIG_CTRL1_ADDRESS 0x38000 +#define VR_XS_PCS_DIG_CTRL1_NUM 3 +#define VR_XS_PCS_DIG_CTRL1_INC 0x1 +#define VR_XS_PCS_DIG_CTRL1_TYPE REG_TYPE_RW +#define VR_XS_PCS_DIG_CTRL1_DEFAULT 0x0 + /*[field] DSKBYP*/ + #define VR_XS_PCS_DIG_CTRL1_DSKBYP + #define VR_XS_PCS_DIG_CTRL1_DSKBYP_OFFSET 0 + #define VR_XS_PCS_DIG_CTRL1_DSKBYP_LEN 1 + #define VR_XS_PCS_DIG_CTRL1_DSKBYP_DEFAULT 0x0 + /*[field] BYP_PWRUP*/ + #define VR_XS_PCS_DIG_CTRL1_BYP_PWRUP + #define VR_XS_PCS_DIG_CTRL1_BYP_PWRUP_OFFSET 1 + #define VR_XS_PCS_DIG_CTRL1_BYP_PWRUP_LEN 1 + #define VR_XS_PCS_DIG_CTRL1_BYP_PWRUP_DEFAULT 0x0 + /*[field] EN_2_5G_MODE*/ + #define VR_XS_PCS_DIG_CTRL1_EN_2_5G_MODE + #define VR_XS_PCS_DIG_CTRL1_EN_2_5G_MODE_OFFSET 2 + #define VR_XS_PCS_DIG_CTRL1_EN_2_5G_MODE_LEN 1 + #define VR_XS_PCS_DIG_CTRL1_EN_2_5G_MODE_DEFAULT 0x0 + /*[field] CR_CJN*/ + #define VR_XS_PCS_DIG_CTRL1_CR_CJN + #define VR_XS_PCS_DIG_CTRL1_CR_CJN_OFFSET 3 + #define VR_XS_PCS_DIG_CTRL1_CR_CJN_LEN 1 + #define VR_XS_PCS_DIG_CTRL1_CR_CJN_DEFAULT 0x0 + /*[field] DTXLANED_0*/ + #define VR_XS_PCS_DIG_CTRL1_DTXLANED_0 + #define VR_XS_PCS_DIG_CTRL1_DTXLANED_0_OFFSET 4 + #define VR_XS_PCS_DIG_CTRL1_DTXLANED_0_LEN 1 + #define VR_XS_PCS_DIG_CTRL1_DTXLANED_0_DEFAULT 0x0 + /*[field] DTXLANED_3_1*/ + #define VR_XS_PCS_DIG_CTRL1_DTXLANED_3_1 + #define VR_XS_PCS_DIG_CTRL1_DTXLANED_3_1_OFFSET 5 + #define VR_XS_PCS_DIG_CTRL1_DTXLANED_3_1_LEN 3 + #define VR_XS_PCS_DIG_CTRL1_DTXLANED_3_1_DEFAULT 0x0 + /*[field] INIT*/ + #define VR_XS_PCS_DIG_CTRL1_INIT + #define VR_XS_PCS_DIG_CTRL1_INIT_OFFSET 8 + #define VR_XS_PCS_DIG_CTRL1_INIT_LEN 1 + #define VR_XS_PCS_DIG_CTRL1_INIT_DEFAULT 0x0 + /*[field] USXG_EN*/ + #define VR_XS_PCS_DIG_CTRL1_USXG_EN + #define VR_XS_PCS_DIG_CTRL1_USXG_EN_OFFSET 9 + #define VR_XS_PCS_DIG_CTRL1_USXG_EN_LEN 1 + #define VR_XS_PCS_DIG_CTRL1_USXG_EN_DEFAULT 0x0 + /*[field] USRA_RST*/ + #define VR_XS_PCS_DIG_CTRL1_USRA_RST + #define VR_XS_PCS_DIG_CTRL1_USRA_RST_OFFSET 10 + #define VR_XS_PCS_DIG_CTRL1_USRA_RST_LEN 1 + #define VR_XS_PCS_DIG_CTRL1_USRA_RST_DEFAULT 0x0 + /*[field] PWRSV*/ + #define VR_XS_PCS_DIG_CTRL1_PWRSV + #define VR_XS_PCS_DIG_CTRL1_PWRSV_OFFSET 11 + #define VR_XS_PCS_DIG_CTRL1_PWRSV_LEN 1 + #define VR_XS_PCS_DIG_CTRL1_PWRSV_DEFAULT 0x0 + /*[field] CL37_BP*/ + #define VR_XS_PCS_DIG_CTRL1_CL37_BP + #define VR_XS_PCS_DIG_CTRL1_CL37_BP_OFFSET 12 + #define VR_XS_PCS_DIG_CTRL1_CL37_BP_LEN 1 + #define VR_XS_PCS_DIG_CTRL1_CL37_BP_DEFAULT 0x0 + /*[field] EN_VSMMD1*/ + #define VR_XS_PCS_DIG_CTRL1_EN_VSMMD1 + #define VR_XS_PCS_DIG_CTRL1_EN_VSMMD1_OFFSET 13 + #define VR_XS_PCS_DIG_CTRL1_EN_VSMMD1_LEN 1 + #define VR_XS_PCS_DIG_CTRL1_EN_VSMMD1_DEFAULT 0x0 + /*[field] R2TLBE*/ + #define VR_XS_PCS_DIG_CTRL1_R2TLBE + #define VR_XS_PCS_DIG_CTRL1_R2TLBE_OFFSET 14 + #define VR_XS_PCS_DIG_CTRL1_R2TLBE_LEN 1 + #define VR_XS_PCS_DIG_CTRL1_R2TLBE_DEFAULT 0x0 + /*[field] VR_RST*/ + #define VR_XS_PCS_DIG_CTRL1_VR_RST + #define VR_XS_PCS_DIG_CTRL1_VR_RST_OFFSET 15 + #define VR_XS_PCS_DIG_CTRL1_VR_RST_LEN 1 + #define VR_XS_PCS_DIG_CTRL1_VR_RST_DEFAULT 0x0 + +struct vr_xs_pcs_dig_ctrl1 { + a_uint32_t dskbyp:1; + a_uint32_t byp_pwrup:1; + a_uint32_t en_2_5g_mode:1; + a_uint32_t cr_cjn:1; + a_uint32_t dtxlaned_0:1; + a_uint32_t dtxlaned_3_1:3; + a_uint32_t init:1; + a_uint32_t usxg_en:1; + a_uint32_t usra_rst:1; + a_uint32_t pwrsv:1; + a_uint32_t cl37_bp:1; + a_uint32_t en_vsmmd1:1; + a_uint32_t r2tlbe:1; + a_uint32_t vr_rst:1; + a_uint32_t _reserved0:16; +}; + +union vr_xs_pcs_dig_ctrl1_u { + a_uint32_t val; + struct vr_xs_pcs_dig_ctrl1 bf; +}; + +/*[register] SR_MII_CTRL*/ +#define SR_MII_CTRL +#define SR_MII_CTRL_ADDRESS 0x1f0000 +#define SR_MII_CTRL_NUM 3 +#define SR_MII_CTRL_INC 0x1 +#define SR_MII_CTRL_TYPE REG_TYPE_RW +#define SR_MII_CTRL_DEFAULT 0x0 + /*[field] SS5*/ + #define SR_MII_CTRL_SS5 + #define SR_MII_CTRL_SS5_OFFSET 5 + #define SR_MII_CTRL_SS5_LEN 1 + #define SR_MII_CTRL_SS5_DEFAULT 0x0 + /*[field] SS6*/ + #define SR_MII_CTRL_SS6 + #define SR_MII_CTRL_SS6_OFFSET 6 + #define SR_MII_CTRL_SS6_LEN 1 + #define SR_MII_CTRL_SS6_DEFAULT 0x0 + /*[field] DUPLEX_MODE*/ + #define SR_MII_CTRL_DUPLEX_MODE + #define SR_MII_CTRL_DUPLEX_MODE_OFFSET 8 + #define SR_MII_CTRL_DUPLEX_MODE_LEN 1 + #define SR_MII_CTRL_DUPLEX_MODE_DEFAULT 0x0 + /*[field] RESTART_AN*/ + #define SR_MII_CTRL_RESTART_AN + #define SR_MII_CTRL_RESTART_AN_OFFSET 9 + #define SR_MII_CTRL_RESTART_AN_LEN 1 + #define SR_MII_CTRL_RESTART_AN_DEFAULT 0x0 + /*[field] LPM*/ + #define SR_MII_CTRL_LPM + #define SR_MII_CTRL_LPM_OFFSET 11 + #define SR_MII_CTRL_LPM_LEN 1 + #define SR_MII_CTRL_LPM_DEFAULT 0x0 + /*[field] AN_ENABLE*/ + #define SR_MII_CTRL_AN_ENABLE + #define SR_MII_CTRL_AN_ENABLE_OFFSET 12 + #define SR_MII_CTRL_AN_ENABLE_LEN 1 + #define SR_MII_CTRL_AN_ENABLE_DEFAULT 0x0 + /*[field] SS13*/ + #define SR_MII_CTRL_SS13 + #define SR_MII_CTRL_SS13_OFFSET 13 + #define SR_MII_CTRL_SS13_LEN 1 + #define SR_MII_CTRL_SS13_DEFAULT 0x0 + /*[field] LBE*/ + #define SR_MII_CTRL_LBE + #define SR_MII_CTRL_LBE_OFFSET 14 + #define SR_MII_CTRL_LBE_LEN 1 + #define SR_MII_CTRL_LBE_DEFAULT 0x0 + /*[field] RST*/ + #define SR_MII_CTRL_RST + #define SR_MII_CTRL_RST_OFFSET 15 + #define SR_MII_CTRL_RST_LEN 1 + #define SR_MII_CTRL_RST_DEFAULT 0x0 + +struct sr_mii_ctrl { + a_uint32_t _reserved0:5; + a_uint32_t ss5:1; + a_uint32_t ss6:1; + a_uint32_t _reserved1:1; + a_uint32_t duplex_mode:1; + a_uint32_t restart_an:1; + a_uint32_t _reserved2:1; + a_uint32_t lpm:1; + a_uint32_t an_enable:1; + a_uint32_t ss13:1; + a_uint32_t lbe:1; + a_uint32_t rst:1; + a_uint32_t _reserved3:16; +}; + +union sr_mii_ctrl_u { + a_uint32_t val; + struct sr_mii_ctrl bf; +}; + +/*[register] VR_MII_AN_CTRL*/ +#define VR_MII_AN_CTRL +#define VR_MII_AN_CTRL_ADDRESS 0x1f8001 +#define VR_MII_AN_CTRL_NUM 3 +#define VR_MII_AN_CTRL_INC 0x1 +#define VR_MII_AN_CTRL_TYPE REG_TYPE_RW +#define VR_MII_AN_CTRL_DEFAULT 0x0 + /*[field] MII_AN_INTR_EN*/ + #define VR_MII_AN_CTRL_MII_AN_INTR_EN + #define VR_MII_AN_CTRL_MII_AN_INTR_EN_OFFSET 0 + #define VR_MII_AN_CTRL_MII_AN_INTR_EN_LEN 1 + #define VR_MII_AN_CTRL_MII_AN_INTR_EN_DEFAULT 0x0 + /*[field] PCS_MODE*/ + #define VR_MII_AN_CTRL_PCS_MODE + #define VR_MII_AN_CTRL_PCS_MODE_OFFSET 1 + #define VR_MII_AN_CTRL_PCS_MODE_LEN 2 + #define VR_MII_AN_CTRL_PCS_MODE_DEFAULT 0x0 + /*[field] TX_CONFIG*/ + #define VR_MII_AN_CTRL_TX_CONFIG + #define VR_MII_AN_CTRL_TX_CONFIG_OFFSET 3 + #define VR_MII_AN_CTRL_TX_CONFIG_LEN 1 + #define VR_MII_AN_CTRL_TX_CONFIG_DEFAULT 0x0 + /*[field] SGMII_LINK_STS*/ + #define VR_MII_AN_CTRL_SGMII_LINK_STS + #define VR_MII_AN_CTRL_SGMII_LINK_STS_OFFSET 4 + #define VR_MII_AN_CTRL_SGMII_LINK_STS_LEN 1 + #define VR_MII_AN_CTRL_SGMII_LINK_STS_DEFAULT 0x0 + /*[field] MII_CTRL*/ + #define VR_MII_AN_CTRL_MII_CTRL + #define VR_MII_AN_CTRL_MII_CTRL_OFFSET 8 + #define VR_MII_AN_CTRL_MII_CTRL_LEN 1 + #define VR_MII_AN_CTRL_MII_CTRL_DEFAULT 0x0 + +struct vr_mii_an_ctrl { + a_uint32_t mii_an_intr_en:1; + a_uint32_t pcs_mode:2; + a_uint32_t tx_config:1; + a_uint32_t sgmii_link_sts:1; + a_uint32_t _reserved0:3; + a_uint32_t mii_ctrl:1; + a_uint32_t _reserved1:23; +}; + +union vr_mii_an_ctrl_u { + a_uint32_t val; + struct vr_mii_an_ctrl bf; +}; + +/*[register] VR_MII_AN_INTR_STS*/ +#define VR_MII_AN_INTR_STS +#define VR_MII_AN_INTR_STS_ADDRESS 0x1f8002 +#define VR_MII_AN_INTR_STS_NUM 3 +#define VR_MII_AN_INTR_STS_INC 0x1 +#define VR_MII_AN_INTR_STS_TYPE REG_TYPE_RW +#define VR_MII_AN_INTR_STS_DEFAULT 0x0 + /*[field] CL37_ANCMPLT_INTR*/ + #define VR_MII_AN_INTR_STS_CL37_ANCMPLT_INTR + #define VR_MII_AN_INTR_STS_CL37_ANCMPLT_INTR_OFFSET 0 + #define VR_MII_AN_INTR_STS_CL37_ANCMPLT_INTR_LEN 1 + #define VR_MII_AN_INTR_STS_CL37_ANCMPLT_INTR_DEFAULT 0x0 + /*[field] CL37_ANSGM_STS*/ + #define VR_MII_AN_INTR_STS_CL37_ANSGM_STS + #define VR_MII_AN_INTR_STS_CL37_ANSGM_STS_OFFSET 1 + #define VR_MII_AN_INTR_STS_CL37_ANSGM_STS_LEN 4 + #define VR_MII_AN_INTR_STS_CL37_ANSGM_STS_DEFAULT 0x0 + /*[field] USXG_AN_STS*/ + #define VR_MII_AN_INTR_STS_USXG_AN_STS + #define VR_MII_AN_INTR_STS_USXG_AN_STS_OFFSET 8 + #define VR_MII_AN_INTR_STS_USXG_AN_STS_LEN 7 + #define VR_MII_AN_INTR_STS_USXG_AN_STS_DEFAULT 0x0 + +struct vr_mii_an_intr_sts { + a_uint32_t cl37_ancmplt_intr:1; + a_uint32_t cl37_ansgm_sts:4; + a_uint32_t _reserved0:3; + a_uint32_t usxg_an_sts:7; + a_uint32_t _reserved1:17; +}; + +union vr_mii_an_intr_sts_u { + a_uint32_t val; + struct vr_mii_an_intr_sts bf; +}; + +/*[register] UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION*/ +#define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION +#define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_ADDRESS 0x14 +#define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_NUM 3 +#define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_INC 0x1 +#define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_TYPE REG_TYPE_RW +#define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_DEFAULT 0x0 + /*[field] MMD1_REG_SRC_UPHY_PLL_VCO_TEMP_CMP*/ + #define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_MMD1_REG_SRC_UPHY_PLL_VCO_TEMP_CMP + #define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_MMD1_REG_SRC_UPHY_PLL_VCO_TEMP_CMP_OFFSET 2 + #define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_MMD1_REG_SRC_UPHY_PLL_VCO_TEMP_CMP_LEN 2 + #define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_MMD1_REG_SRC_UPHY_PLL_VCO_TEMP_CMP_DEFAULT 0x0 + /*[field] MMD1_REG_SRC_UPHY_PLL_VCO_AMP*/ + #define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_MMD1_REG_SRC_UPHY_PLL_VCO_AMP + #define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_MMD1_REG_SRC_UPHY_PLL_VCO_AMP_OFFSET 4 + #define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_MMD1_REG_SRC_UPHY_PLL_VCO_AMP_LEN 2 + #define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_MMD1_REG_SRC_UPHY_PLL_VCO_AMP_DEFAULT 0x0 + /*[field] MMD1_REG_SRC_UPHY_PLL_VCO_GAIN*/ + #define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_MMD1_REG_SRC_UPHY_PLL_VCO_GAIN + #define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_MMD1_REG_SRC_UPHY_PLL_VCO_GAIN_OFFSET 6 + #define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_MMD1_REG_SRC_UPHY_PLL_VCO_GAIN_LEN 2 + #define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_MMD1_REG_SRC_UPHY_PLL_VCO_GAIN_DEFAULT 0x0 + /*[field] MMD1_REG_SRC_UPHY_PLL_LPF_C2*/ + #define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_MMD1_REG_SRC_UPHY_PLL_LPF_C2 + #define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_MMD1_REG_SRC_UPHY_PLL_LPF_C2_OFFSET 8 + #define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_MMD1_REG_SRC_UPHY_PLL_LPF_C2_LEN 2 + #define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_MMD1_REG_SRC_UPHY_PLL_LPF_C2_DEFAULT 0x0 + /*[field] MMD1_REG_SRC_UPHY_PLL_LPF_RES*/ + #define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_MMD1_REG_SRC_UPHY_PLL_LPF_RES + #define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_MMD1_REG_SRC_UPHY_PLL_LPF_RES_OFFSET 10 + #define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_MMD1_REG_SRC_UPHY_PLL_LPF_RES_LEN 2 + #define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_MMD1_REG_SRC_UPHY_PLL_LPF_RES_DEFAULT 0x0 + /*[field] MMD1_REG_SRC_UPHY_PLL_CP_SEL*/ + #define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_MMD1_REG_SRC_UPHY_PLL_CP_SEL + #define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_MMD1_REG_SRC_UPHY_PLL_CP_SEL_OFFSET 12 + #define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_MMD1_REG_SRC_UPHY_PLL_CP_SEL_LEN 2 + #define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_MMD1_REG_SRC_UPHY_PLL_CP_SEL_DEFAULT 0x0 + /*[field] MMD1_REG_SRC_UPHY_PLL_LPF_DC*/ + #define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_MMD1_REG_SRC_UPHY_PLL_LPF_DC + #define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_MMD1_REG_SRC_UPHY_PLL_LPF_DC_OFFSET 14 + #define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_MMD1_REG_SRC_UPHY_PLL_LPF_DC_LEN 2 + #define UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_MMD1_REG_SRC_UPHY_PLL_LPF_DC_DEFAULT 0x0 + +struct uniphy_pll_control_vco_related_selection { + a_uint32_t mmd1_reg_src_uphy_pll_vco_temp_cmp:2; + a_uint32_t mmd1_reg_src_uphy_pll_vco_amp:2; + a_uint32_t mmd1_reg_src_uphy_pll_vco_gain:2; + a_uint32_t mmd1_reg_src_uphy_pll_lpf_c2:2; + a_uint32_t mmd1_reg_src_uphy_pll_lpf_res:2; + a_uint32_t mmd1_reg_src_uphy_pll_cp_sel:2; + a_uint32_t mmd1_reg_src_uphy_pll_lpf_dc:2; + a_uint32_t _reserved0:16; +}; + +union uniphy_pll_control_vco_related_selection_u { + a_uint32_t val; + struct uniphy_pll_control_vco_related_selection bf; +}; + +/*[register] UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION*/ +#define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION +#define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_ADDRESS 0x24 +#define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_NUM 3 +#define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_INC 0x1 +#define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_TYPE REG_TYPE_RW +#define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_DEFAULT 0x0 + /*[field] MMD1_REG_SRC_UPHY_TX_EMP_LSB_EN*/ + #define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_MMD1_REG_SRC_UPHY_TX_EMP_LSB_EN + #define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_MMD1_REG_SRC_UPHY_TX_EMP_LSB_EN_OFFSET 0 + #define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_MMD1_REG_SRC_UPHY_TX_EMP_LSB_EN_LEN 2 + #define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_MMD1_REG_SRC_UPHY_TX_EMP_LSB_EN_DEFAULT 0x0 + /*[field] MMD1_REG_SRC_UPHY_TX_RESCAL_CODE*/ + #define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_MMD1_REG_SRC_UPHY_TX_RESCAL_CODE + #define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_MMD1_REG_SRC_UPHY_TX_RESCAL_CODE_OFFSET 2 + #define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_MMD1_REG_SRC_UPHY_TX_RESCAL_CODE_LEN 2 + #define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_MMD1_REG_SRC_UPHY_TX_RESCAL_CODE_DEFAULT 0x0 + /*[field] MMD1_REG_SRC_UPHY_TX_EMP_LVL*/ + #define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_MMD1_REG_SRC_UPHY_TX_EMP_LVL + #define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_MMD1_REG_SRC_UPHY_TX_EMP_LVL_OFFSET 4 + #define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_MMD1_REG_SRC_UPHY_TX_EMP_LVL_LEN 2 + #define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_MMD1_REG_SRC_UPHY_TX_EMP_LVL_DEFAULT 0x0 + /*[field] MMD1_REG_SRC_UPHY_TX_AMP*/ + #define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_MMD1_REG_SRC_UPHY_TX_AMP + #define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_MMD1_REG_SRC_UPHY_TX_AMP_OFFSET 6 + #define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_MMD1_REG_SRC_UPHY_TX_AMP_LEN 2 + #define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_MMD1_REG_SRC_UPHY_TX_AMP_DEFAULT 0x0 + /*[field] MMD1_REG_SRC_UPHY_TX_VCM_DELTA*/ + #define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_MMD1_REG_SRC_UPHY_TX_VCM_DELTA + #define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_MMD1_REG_SRC_UPHY_TX_VCM_DELTA_OFFSET 8 + #define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_MMD1_REG_SRC_UPHY_TX_VCM_DELTA_LEN 2 + #define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_MMD1_REG_SRC_UPHY_TX_VCM_DELTA_DEFAULT 0x0 + /*[field] MMD1_REG_SRC_UPHY_TX_EN*/ + #define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_MMD1_REG_SRC_UPHY_TX_EN + #define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_MMD1_REG_SRC_UPHY_TX_EN_OFFSET 10 + #define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_MMD1_REG_SRC_UPHY_TX_EN_LEN 2 + #define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_MMD1_REG_SRC_UPHY_TX_EN_DEFAULT 0x0 + /*[field] MMD1_REG_SRC_UPHY_TXD_BIT_WIDTH*/ + #define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_MMD1_REG_SRC_UPHY_TXD_BIT_WIDTH + #define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_MMD1_REG_SRC_UPHY_TXD_BIT_WIDTH_OFFSET 12 + #define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_MMD1_REG_SRC_UPHY_TXD_BIT_WIDTH_LEN 2 + #define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_MMD1_REG_SRC_UPHY_TXD_BIT_WIDTH_DEFAULT 0x0 + /*[field] MMD1_REG_SRC_UPHY_TX_ACJTAG_BEACON_EN*/ + #define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_MMD1_REG_SRC_UPHY_TX_ACJTAG_BEACON_EN + #define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_MMD1_REG_SRC_UPHY_TX_ACJTAG_BEACON_EN_OFFSET 14 + #define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_MMD1_REG_SRC_UPHY_TX_ACJTAG_BEACON_EN_LEN 2 + #define UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_MMD1_REG_SRC_UPHY_TX_ACJTAG_BEACON_EN_DEFAULT 0x0 + +struct uniphy_tx_ac_jtag_mux_driver_selection { + a_uint32_t mmd1_reg_src_uphy_tx_emp_lsb_en:2; + a_uint32_t mmd1_reg_src_uphy_tx_rescal_code:2; + a_uint32_t mmd1_reg_src_uphy_tx_emp_lvl:2; + a_uint32_t mmd1_reg_src_uphy_tx_amp:2; + a_uint32_t mmd1_reg_src_uphy_tx_vcm_delta:2; + a_uint32_t mmd1_reg_src_uphy_tx_en:2; + a_uint32_t mmd1_reg_src_uphy_txd_bit_width:2; + a_uint32_t mmd1_reg_src_uphy_tx_acjtag_beacon_en:2; + a_uint32_t _reserved0:16; +}; + +union uniphy_tx_ac_jtag_mux_driver_selection_u { + a_uint32_t val; + struct uniphy_tx_ac_jtag_mux_driver_selection bf; +}; + +/*[register] UNIPHY_RESISTOR_CALIBRATION_1*/ +#define UNIPHY_RESISTOR_CALIBRATION_1 +#define UNIPHY_RESISTOR_CALIBRATION_1_ADDRESS 0x170 +#define UNIPHY_RESISTOR_CALIBRATION_1_NUM 3 +#define UNIPHY_RESISTOR_CALIBRATION_1_INC 0x1 +#define UNIPHY_RESISTOR_CALIBRATION_1_TYPE REG_TYPE_RW +#define UNIPHY_RESISTOR_CALIBRATION_1_DEFAULT 0x0 + /*[field] MMD1_REG_CALIB_RX_REG*/ + #define UNIPHY_RESISTOR_CALIBRATION_1_MMD1_REG_CALIB_RX_REG + #define UNIPHY_RESISTOR_CALIBRATION_1_MMD1_REG_CALIB_RX_REG_OFFSET 0 + #define UNIPHY_RESISTOR_CALIBRATION_1_MMD1_REG_CALIB_RX_REG_LEN 5 + #define UNIPHY_RESISTOR_CALIBRATION_1_MMD1_REG_CALIB_RX_REG_DEFAULT 0x0 + /*[field] MMD1_REG_CALIB_TX_REG*/ + #define UNIPHY_RESISTOR_CALIBRATION_1_MMD1_REG_CALIB_TX_REG + #define UNIPHY_RESISTOR_CALIBRATION_1_MMD1_REG_CALIB_TX_REG_OFFSET 5 + #define UNIPHY_RESISTOR_CALIBRATION_1_MMD1_REG_CALIB_TX_REG_LEN 5 + #define UNIPHY_RESISTOR_CALIBRATION_1_MMD1_REG_CALIB_TX_REG_DEFAULT 0x0 + /*[field] MMD1_REG_VREF_LVL*/ + #define UNIPHY_RESISTOR_CALIBRATION_1_MMD1_REG_VREF_LVL + #define UNIPHY_RESISTOR_CALIBRATION_1_MMD1_REG_VREF_LVL_OFFSET 10 + #define UNIPHY_RESISTOR_CALIBRATION_1_MMD1_REG_VREF_LVL_LEN 5 + #define UNIPHY_RESISTOR_CALIBRATION_1_MMD1_REG_VREF_LVL_DEFAULT 0x0 + /*[field] MMD1_REG_DISABLE_LOAD_RES_TXRX*/ + #define UNIPHY_RESISTOR_CALIBRATION_1_MMD1_REG_DISABLE_LOAD_RES_TXRX + #define UNIPHY_RESISTOR_CALIBRATION_1_MMD1_REG_DISABLE_LOAD_RES_TXRX_OFFSET 15 + #define UNIPHY_RESISTOR_CALIBRATION_1_MMD1_REG_DISABLE_LOAD_RES_TXRX_LEN 1 + #define UNIPHY_RESISTOR_CALIBRATION_1_MMD1_REG_DISABLE_LOAD_RES_TXRX_DEFAULT 0x0 + +struct uniphy_resistor_calibration_1 { + a_uint32_t mmd1_reg_calib_rx_reg:5; + a_uint32_t mmd1_reg_calib_tx_reg:5; + a_uint32_t mmd1_reg_vref_lvl:5; + a_uint32_t mmd1_reg_disable_load_res_txrx:1; + a_uint32_t _reserved0:16; +}; + +union uniphy_resistor_calibration_1_u { + a_uint32_t val; + struct uniphy_resistor_calibration_1 bf; +}; + +/*[register] UNIPHY_PLL_VCO_RELATED_CONTROL_1*/ +#define UNIPHY_PLL_VCO_RELATED_CONTROL_1 +#define UNIPHY_PLL_VCO_RELATED_CONTROL_1_ADDRESS 0x78c +#define UNIPHY_PLL_VCO_RELATED_CONTROL_1_NUM 3 +#define UNIPHY_PLL_VCO_RELATED_CONTROL_1_INC 0x1 +#define UNIPHY_PLL_VCO_RELATED_CONTROL_1_TYPE REG_TYPE_RW +#define UNIPHY_PLL_VCO_RELATED_CONTROL_1_DEFAULT 0x0 + /*[field] MIIREG_REG_UPHY_PLL_VCO_TEMP_CMP*/ + #define UNIPHY_PLL_VCO_RELATED_CONTROL_1_MIIREG_REG_UPHY_PLL_VCO_TEMP_CMP + #define UNIPHY_PLL_VCO_RELATED_CONTROL_1_MIIREG_REG_UPHY_PLL_VCO_TEMP_CMP_OFFSET 0 + #define UNIPHY_PLL_VCO_RELATED_CONTROL_1_MIIREG_REG_UPHY_PLL_VCO_TEMP_CMP_LEN 6 + #define UNIPHY_PLL_VCO_RELATED_CONTROL_1_MIIREG_REG_UPHY_PLL_VCO_TEMP_CMP_DEFAULT 0x0 + /*[field] MIIREG_REG_UPHY_PLL_VCO_CALIB_READY*/ + #define UNIPHY_PLL_VCO_RELATED_CONTROL_1_MIIREG_REG_UPHY_PLL_VCO_CALIB_READY + #define UNIPHY_PLL_VCO_RELATED_CONTROL_1_MIIREG_REG_UPHY_PLL_VCO_CALIB_READY_OFFSET 6 + #define UNIPHY_PLL_VCO_RELATED_CONTROL_1_MIIREG_REG_UPHY_PLL_VCO_CALIB_READY_LEN 1 + #define UNIPHY_PLL_VCO_RELATED_CONTROL_1_MIIREG_REG_UPHY_PLL_VCO_CALIB_READY_DEFAULT 0x0 + /*[field] MIIREG_AUTOLOAD_SEL_PLL_VCO_CALIB_READY*/ + #define UNIPHY_PLL_VCO_RELATED_CONTROL_1_MIIREG_AUTOLOAD_SEL_PLL_VCO_CALIB_READY + #define UNIPHY_PLL_VCO_RELATED_CONTROL_1_MIIREG_AUTOLOAD_SEL_PLL_VCO_CALIB_READY_OFFSET 7 + #define UNIPHY_PLL_VCO_RELATED_CONTROL_1_MIIREG_AUTOLOAD_SEL_PLL_VCO_CALIB_READY_LEN 1 + #define UNIPHY_PLL_VCO_RELATED_CONTROL_1_MIIREG_AUTOLOAD_SEL_PLL_VCO_CALIB_READY_DEFAULT 0x0 + /*[field] MIIREG_REG_UPHY_PLL_VCO_AMP*/ + #define UNIPHY_PLL_VCO_RELATED_CONTROL_1_MIIREG_REG_UPHY_PLL_VCO_AMP + #define UNIPHY_PLL_VCO_RELATED_CONTROL_1_MIIREG_REG_UPHY_PLL_VCO_AMP_OFFSET 8 + #define UNIPHY_PLL_VCO_RELATED_CONTROL_1_MIIREG_REG_UPHY_PLL_VCO_AMP_LEN 4 + #define UNIPHY_PLL_VCO_RELATED_CONTROL_1_MIIREG_REG_UPHY_PLL_VCO_AMP_DEFAULT 0x0 + /*[field] MIIREG_REG_UPHY_PLL_VCO_GAIN*/ + #define UNIPHY_PLL_VCO_RELATED_CONTROL_1_MIIREG_REG_UPHY_PLL_VCO_GAIN + #define UNIPHY_PLL_VCO_RELATED_CONTROL_1_MIIREG_REG_UPHY_PLL_VCO_GAIN_OFFSET 12 + #define UNIPHY_PLL_VCO_RELATED_CONTROL_1_MIIREG_REG_UPHY_PLL_VCO_GAIN_LEN 3 + #define UNIPHY_PLL_VCO_RELATED_CONTROL_1_MIIREG_REG_UPHY_PLL_VCO_GAIN_DEFAULT 0x0 + /*[field] MIIREG_UPHY_PLL_LCKDT_EN*/ + #define UNIPHY_PLL_VCO_RELATED_CONTROL_1_MIIREG_UPHY_PLL_LCKDT_EN + #define UNIPHY_PLL_VCO_RELATED_CONTROL_1_MIIREG_UPHY_PLL_LCKDT_EN_OFFSET 15 + #define UNIPHY_PLL_VCO_RELATED_CONTROL_1_MIIREG_UPHY_PLL_LCKDT_EN_LEN 1 + #define UNIPHY_PLL_VCO_RELATED_CONTROL_1_MIIREG_UPHY_PLL_LCKDT_EN_DEFAULT 0x0 + +struct uniphy_pll_vco_related_control_1 { + a_uint32_t miireg_reg_uphy_pll_vco_temp_cmp:6; + a_uint32_t miireg_reg_uphy_pll_vco_calib_ready:1; + a_uint32_t miireg_autoload_sel_pll_vco_calib_ready:1; + a_uint32_t miireg_reg_uphy_pll_vco_amp:4; + a_uint32_t miireg_reg_uphy_pll_vco_gain:3; + a_uint32_t miireg_uphy_pll_lckdt_en:1; + a_uint32_t _reserved0:16; +}; + +union uniphy_pll_vco_related_control_1_u { + a_uint32_t val; + struct uniphy_pll_vco_related_control_1 bf; +}; + +/*[register] UNIPHY_RX_AFE_2*/ +#define UNIPHY_RX_AFE_2 +#define UNIPHY_RX_AFE_2_ADDRESS 0x7c4 +#define UNIPHY_RX_AFE_2_NUM 3 +#define UNIPHY_RX_AFE_2_INC 0x1 +#define UNIPHY_RX_AFE_2_TYPE REG_TYPE_RW +#define UNIPHY_RX_AFE_2_DEFAULT 0x0 + /*[field] MIIREG_REG_UPHY_RX_AFE_RES1*/ + #define UNIPHY_RX_AFE_2_MIIREG_REG_UPHY_RX_AFE_RES1 + #define UNIPHY_RX_AFE_2_MIIREG_REG_UPHY_RX_AFE_RES1_OFFSET 0 + #define UNIPHY_RX_AFE_2_MIIREG_REG_UPHY_RX_AFE_RES1_LEN 4 + #define UNIPHY_RX_AFE_2_MIIREG_REG_UPHY_RX_AFE_RES1_DEFAULT 0x0 + /*[field] MIIREG_REG_UPHY_RX_AFE_CAP1*/ + #define UNIPHY_RX_AFE_2_MIIREG_REG_UPHY_RX_AFE_CAP1 + #define UNIPHY_RX_AFE_2_MIIREG_REG_UPHY_RX_AFE_CAP1_OFFSET 4 + #define UNIPHY_RX_AFE_2_MIIREG_REG_UPHY_RX_AFE_CAP1_LEN 3 + #define UNIPHY_RX_AFE_2_MIIREG_REG_UPHY_RX_AFE_CAP1_DEFAULT 0x0 + /*[field] MIIREG_REG_UPHY_RX_RESCAL_CODE*/ + #define UNIPHY_RX_AFE_2_MIIREG_REG_UPHY_RX_RESCAL_CODE + #define UNIPHY_RX_AFE_2_MIIREG_REG_UPHY_RX_RESCAL_CODE_OFFSET 8 + #define UNIPHY_RX_AFE_2_MIIREG_REG_UPHY_RX_RESCAL_CODE_LEN 5 + #define UNIPHY_RX_AFE_2_MIIREG_REG_UPHY_RX_RESCAL_CODE_DEFAULT 0x0 + +struct uniphy_rx_afe_2 { + a_uint32_t miireg_reg_uphy_rx_afe_res1:4; + a_uint32_t miireg_reg_uphy_rx_afe_cap1:3; + a_uint32_t _reserved0:1; + a_uint32_t miireg_reg_uphy_rx_rescal_code:5; + a_uint32_t _reserved1:19; +}; + +union uniphy_rx_afe_2_u { + a_uint32_t val; + struct uniphy_rx_afe_2 bf; +}; + +/*[register] BANDGAP_IP_MBIAS_2*/ +#define BANDGAP_IP_MBIAS_2 +#define BANDGAP_IP_MBIAS_2_ADDRESS 0x9b004 +#define BANDGAP_IP_MBIAS_2_NUM 4 +#define BANDGAP_IP_MBIAS_2_INC 0x1 +#define BANDGAP_IP_MBIAS_2_TYPE REG_TYPE_RW +#define BANDGAP_IP_MBIAS_2_DEFAULT 0x0 + /*[field] CMN_MMD1_REG_CMN_BG_RSV*/ + #define BANDGAP_IP_MBIAS_2_CMN_MMD1_REG_CMN_BG_RSV + #define BANDGAP_IP_MBIAS_2_CMN_MMD1_REG_CMN_BG_RSV_OFFSET 0 + #define BANDGAP_IP_MBIAS_2_CMN_MMD1_REG_CMN_BG_RSV_LEN 8 + #define BANDGAP_IP_MBIAS_2_CMN_MMD1_REG_CMN_BG_RSV_DEFAULT 0x0 + /*[field] CMN_MMD1_REG_CMN_ICC_RESCODE*/ + #define BANDGAP_IP_MBIAS_2_CMN_MMD1_REG_CMN_ICC_RESCODE + #define BANDGAP_IP_MBIAS_2_CMN_MMD1_REG_CMN_ICC_RESCODE_OFFSET 8 + #define BANDGAP_IP_MBIAS_2_CMN_MMD1_REG_CMN_ICC_RESCODE_LEN 7 + #define BANDGAP_IP_MBIAS_2_CMN_MMD1_REG_CMN_ICC_RESCODE_DEFAULT 0x0 + /*[field] CMN_MMD1_REG_MBIAS_EN*/ + #define BANDGAP_IP_MBIAS_2_CMN_MMD1_REG_MBIAS_EN + #define BANDGAP_IP_MBIAS_2_CMN_MMD1_REG_MBIAS_EN_OFFSET 15 + #define BANDGAP_IP_MBIAS_2_CMN_MMD1_REG_MBIAS_EN_LEN 1 + #define BANDGAP_IP_MBIAS_2_CMN_MMD1_REG_MBIAS_EN_DEFAULT 0x0 + +struct bandgap_ip_mbias_2 { + a_uint32_t cmn_mmd1_reg_cmn_bg_rsv:8; + a_uint32_t cmn_mmd1_reg_cmn_icc_rescode:7; + a_uint32_t cmn_mmd1_reg_mbias_en:1; + a_uint32_t _reserved0:16; +}; + +union bandgap_ip_mbias_2_u { + a_uint32_t val; + struct bandgap_ip_mbias_2 bf; +}; + +/*[register] LDO_0P9V_RELATED_1*/ +#define LDO_0P9V_RELATED_1 +#define LDO_0P9V_RELATED_1_ADDRESS 0x9b054 +#define LDO_0P9V_RELATED_1_NUM 4 +#define LDO_0P9V_RELATED_1_INC 0x1 +#define LDO_0P9V_RELATED_1_TYPE REG_TYPE_RW +#define LDO_0P9V_RELATED_1_DEFAULT 0x0 + /*[field] CMN_MMD1_REG_CMN_LDO_INT_RES_CTRL*/ + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_LDO_INT_RES_CTRL + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_LDO_INT_RES_CTRL_OFFSET 0 + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_LDO_INT_RES_CTRL_LEN 2 + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_LDO_INT_RES_CTRL_DEFAULT 0x0 + /*[field] CMN_MMD1_REG_CMN_LDO_INT_LOAD_EN*/ + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_LDO_INT_LOAD_EN + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_LDO_INT_LOAD_EN_OFFSET 2 + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_LDO_INT_LOAD_EN_LEN 1 + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_LDO_INT_LOAD_EN_DEFAULT 0x0 + /*[field] CMN_MMD1_REG_CMN_LDO_OCP_CURRENT_SEL*/ + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_LDO_OCP_CURRENT_SEL + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_LDO_OCP_CURRENT_SEL_OFFSET 3 + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_LDO_OCP_CURRENT_SEL_LEN 1 + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_LDO_OCP_CURRENT_SEL_DEFAULT 0x0 + /*[field] CMN_MMD1_REG_CMN_LDO_OCP_EN*/ + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_LDO_OCP_EN + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_LDO_OCP_EN_OFFSET 4 + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_LDO_OCP_EN_LEN 1 + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_LDO_OCP_EN_DEFAULT 0x0 + /*[field] CMN_MMD1_REG_CMN_LDO_BIAS_CTRL*/ + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_LDO_BIAS_CTRL + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_LDO_BIAS_CTRL_OFFSET 5 + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_LDO_BIAS_CTRL_LEN 2 + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_LDO_BIAS_CTRL_DEFAULT 0x0 + /*[field] CMN_MMD1_REG_CMN_LDO_VOUT_CTRL*/ + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_LDO_VOUT_CTRL + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_LDO_VOUT_CTRL_OFFSET 7 + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_LDO_VOUT_CTRL_LEN 4 + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_LDO_VOUT_CTRL_DEFAULT 0x0 + /*[field] CMN_MMD1_REG_CMN_LDO_EN*/ + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_LDO_EN + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_LDO_EN_OFFSET 11 + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_LDO_EN_LEN 1 + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_LDO_EN_DEFAULT 0x0 + /*[field] CMN_MMD1_REG_CMN_LDO_COMP_CURRENT_EN*/ + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_LDO_COMP_CURRENT_EN + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_LDO_COMP_CURRENT_EN_OFFSET 12 + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_LDO_COMP_CURRENT_EN_LEN 1 + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_LDO_COMP_CURRENT_EN_DEFAULT 0x0 + /*[field] CMN_MMD1_REG_CMN_VTT_LDO_BIASGEN_SEL*/ + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_VTT_LDO_BIASGEN_SEL + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_VTT_LDO_BIASGEN_SEL_OFFSET 13 + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_VTT_LDO_BIASGEN_SEL_LEN 3 + #define LDO_0P9V_RELATED_1_CMN_MMD1_REG_CMN_VTT_LDO_BIASGEN_SEL_DEFAULT 0x0 + +struct ldo_0p9v_related_1 { + a_uint32_t cmn_mmd1_reg_cmn_ldo_int_res_ctrl:2; + a_uint32_t cmn_mmd1_reg_cmn_ldo_int_load_en:1; + a_uint32_t cmn_mmd1_reg_cmn_ldo_ocp_current_sel:1; + a_uint32_t cmn_mmd1_reg_cmn_ldo_ocp_en:1; + a_uint32_t cmn_mmd1_reg_cmn_ldo_bias_ctrl:2; + a_uint32_t cmn_mmd1_reg_cmn_ldo_vout_ctrl:4; + a_uint32_t cmn_mmd1_reg_cmn_ldo_en:1; + a_uint32_t cmn_mmd1_reg_cmn_ldo_comp_current_en:1; + a_uint32_t cmn_mmd1_reg_cmn_vtt_ldo_biasgen_sel:3; + a_uint32_t _reserved0:16; +}; + +union ldo_0p9v_related_1_u { + a_uint32_t val; + struct ldo_0p9v_related_1 bf; +}; + +/*[register] OTP_VTT_LDO_RELATED*/ +#define OTP_VTT_LDO_RELATED +#define OTP_VTT_LDO_RELATED_ADDRESS 0x9b05c +#define OTP_VTT_LDO_RELATED_NUM 4 +#define OTP_VTT_LDO_RELATED_INC 0x1 +#define OTP_VTT_LDO_RELATED_TYPE REG_TYPE_RW +#define OTP_VTT_LDO_RELATED_DEFAULT 0x0 + /*[field] CMN_MMD1_REG_CMN_VTT_LDO_RSV*/ + #define OTP_VTT_LDO_RELATED_CMN_MMD1_REG_CMN_VTT_LDO_RSV + #define OTP_VTT_LDO_RELATED_CMN_MMD1_REG_CMN_VTT_LDO_RSV_OFFSET 0 + #define OTP_VTT_LDO_RELATED_CMN_MMD1_REG_CMN_VTT_LDO_RSV_LEN 8 + #define OTP_VTT_LDO_RELATED_CMN_MMD1_REG_CMN_VTT_LDO_RSV_DEFAULT 0x0 + /*[field] CMN_MMD1_REG_CMN_VTT_LDO_INT_LOAD_CTRL*/ + #define OTP_VTT_LDO_RELATED_CMN_MMD1_REG_CMN_VTT_LDO_INT_LOAD_CTRL + #define OTP_VTT_LDO_RELATED_CMN_MMD1_REG_CMN_VTT_LDO_INT_LOAD_CTRL_OFFSET 8 + #define OTP_VTT_LDO_RELATED_CMN_MMD1_REG_CMN_VTT_LDO_INT_LOAD_CTRL_LEN 2 + #define OTP_VTT_LDO_RELATED_CMN_MMD1_REG_CMN_VTT_LDO_INT_LOAD_CTRL_DEFAULT 0x0 + /*[field] CMN_MMD1_REG_CMN_VTT_LDO_OCP_CURRENT_SEL*/ + #define OTP_VTT_LDO_RELATED_CMN_MMD1_REG_CMN_VTT_LDO_OCP_CURRENT_SEL + #define OTP_VTT_LDO_RELATED_CMN_MMD1_REG_CMN_VTT_LDO_OCP_CURRENT_SEL_OFFSET 10 + #define OTP_VTT_LDO_RELATED_CMN_MMD1_REG_CMN_VTT_LDO_OCP_CURRENT_SEL_LEN 1 + #define OTP_VTT_LDO_RELATED_CMN_MMD1_REG_CMN_VTT_LDO_OCP_CURRENT_SEL_DEFAULT 0x0 + /*[field] CMN_MMD1_REG_CMN_VTT_LDO_OCP_EN*/ + #define OTP_VTT_LDO_RELATED_CMN_MMD1_REG_CMN_VTT_LDO_OCP_EN + #define OTP_VTT_LDO_RELATED_CMN_MMD1_REG_CMN_VTT_LDO_OCP_EN_OFFSET 11 + #define OTP_VTT_LDO_RELATED_CMN_MMD1_REG_CMN_VTT_LDO_OCP_EN_LEN 1 + #define OTP_VTT_LDO_RELATED_CMN_MMD1_REG_CMN_VTT_LDO_OCP_EN_DEFAULT 0x0 + /*[field] CMN_MMD1_REG_CMN_VTT_LDO_BIAS_CTRL*/ + #define OTP_VTT_LDO_RELATED_CMN_MMD1_REG_CMN_VTT_LDO_BIAS_CTRL + #define OTP_VTT_LDO_RELATED_CMN_MMD1_REG_CMN_VTT_LDO_BIAS_CTRL_OFFSET 12 + #define OTP_VTT_LDO_RELATED_CMN_MMD1_REG_CMN_VTT_LDO_BIAS_CTRL_LEN 2 + #define OTP_VTT_LDO_RELATED_CMN_MMD1_REG_CMN_VTT_LDO_BIAS_CTRL_DEFAULT 0x0 + /*[field] CMN_MMD1_REG_CMN_VTT_LDO_EN*/ + #define OTP_VTT_LDO_RELATED_CMN_MMD1_REG_CMN_VTT_LDO_EN + #define OTP_VTT_LDO_RELATED_CMN_MMD1_REG_CMN_VTT_LDO_EN_OFFSET 14 + #define OTP_VTT_LDO_RELATED_CMN_MMD1_REG_CMN_VTT_LDO_EN_LEN 1 + #define OTP_VTT_LDO_RELATED_CMN_MMD1_REG_CMN_VTT_LDO_EN_DEFAULT 0x0 + /*[field] CMN_MMD1_REG_CMN_ANA_ISOLATION*/ + #define OTP_VTT_LDO_RELATED_CMN_MMD1_REG_CMN_ANA_ISOLATION + #define OTP_VTT_LDO_RELATED_CMN_MMD1_REG_CMN_ANA_ISOLATION_OFFSET 15 + #define OTP_VTT_LDO_RELATED_CMN_MMD1_REG_CMN_ANA_ISOLATION_LEN 1 + #define OTP_VTT_LDO_RELATED_CMN_MMD1_REG_CMN_ANA_ISOLATION_DEFAULT 0x0 + +struct otp_vtt_ldo_related { + a_uint32_t cmn_mmd1_reg_cmn_vtt_ldo_rsv:8; + a_uint32_t cmn_mmd1_reg_cmn_vtt_ldo_int_load_ctrl:2; + a_uint32_t cmn_mmd1_reg_cmn_vtt_ldo_ocp_current_sel:1; + a_uint32_t cmn_mmd1_reg_cmn_vtt_ldo_ocp_en:1; + a_uint32_t cmn_mmd1_reg_cmn_vtt_ldo_bias_ctrl:2; + a_uint32_t cmn_mmd1_reg_cmn_vtt_ldo_en:1; + a_uint32_t cmn_mmd1_reg_cmn_ana_isolation:1; + a_uint32_t _reserved0:16; +}; + +union otp_vtt_ldo_related_u { + a_uint32_t val; + struct otp_vtt_ldo_related bf; +}; + +/*[register] OTP_TEMPERATURE_COMPENSATE_1*/ +#define OTP_TEMPERATURE_COMPENSATE_1 +#define OTP_TEMPERATURE_COMPENSATE_1_ADDRESS 0x9b08c +#define OTP_TEMPERATURE_COMPENSATE_1_NUM 4 +#define OTP_TEMPERATURE_COMPENSATE_1_INC 0x1 +#define OTP_TEMPERATURE_COMPENSATE_1_TYPE REG_TYPE_RW +#define OTP_TEMPERATURE_COMPENSATE_1_DEFAULT 0x0 + /*[field] CMN_MMD1_REG_UPHY_ICTAT100U_CTRL0*/ + #define OTP_TEMPERATURE_COMPENSATE_1_CMN_MMD1_REG_UPHY_ICTAT100U_CTRL0 + #define OTP_TEMPERATURE_COMPENSATE_1_CMN_MMD1_REG_UPHY_ICTAT100U_CTRL0_OFFSET 0 + #define OTP_TEMPERATURE_COMPENSATE_1_CMN_MMD1_REG_UPHY_ICTAT100U_CTRL0_LEN 3 + #define OTP_TEMPERATURE_COMPENSATE_1_CMN_MMD1_REG_UPHY_ICTAT100U_CTRL0_DEFAULT 0x0 + /*[field] CMN_MMD1_REG_UPHY_ICTAT100U_CTRL1*/ + #define OTP_TEMPERATURE_COMPENSATE_1_CMN_MMD1_REG_UPHY_ICTAT100U_CTRL1 + #define OTP_TEMPERATURE_COMPENSATE_1_CMN_MMD1_REG_UPHY_ICTAT100U_CTRL1_OFFSET 4 + #define OTP_TEMPERATURE_COMPENSATE_1_CMN_MMD1_REG_UPHY_ICTAT100U_CTRL1_LEN 3 + #define OTP_TEMPERATURE_COMPENSATE_1_CMN_MMD1_REG_UPHY_ICTAT100U_CTRL1_DEFAULT 0x0 + /*[field] CMN_MMD1_REG_UPHY_ICTAT100U_CTRL2*/ + #define OTP_TEMPERATURE_COMPENSATE_1_CMN_MMD1_REG_UPHY_ICTAT100U_CTRL2 + #define OTP_TEMPERATURE_COMPENSATE_1_CMN_MMD1_REG_UPHY_ICTAT100U_CTRL2_OFFSET 8 + #define OTP_TEMPERATURE_COMPENSATE_1_CMN_MMD1_REG_UPHY_ICTAT100U_CTRL2_LEN 3 + #define OTP_TEMPERATURE_COMPENSATE_1_CMN_MMD1_REG_UPHY_ICTAT100U_CTRL2_DEFAULT 0x0 + /*[field] CMN_MMD1_REG_UPHY_ICTAT100U_EN*/ + #define OTP_TEMPERATURE_COMPENSATE_1_CMN_MMD1_REG_UPHY_ICTAT100U_EN + #define OTP_TEMPERATURE_COMPENSATE_1_CMN_MMD1_REG_UPHY_ICTAT100U_EN_OFFSET 12 + #define OTP_TEMPERATURE_COMPENSATE_1_CMN_MMD1_REG_UPHY_ICTAT100U_EN_LEN 3 + #define OTP_TEMPERATURE_COMPENSATE_1_CMN_MMD1_REG_UPHY_ICTAT100U_EN_DEFAULT 0x0 + /*[field] CMN_MMD1_REG_CMN_PLL_ICTAT100U_EN*/ + #define OTP_TEMPERATURE_COMPENSATE_1_CMN_MMD1_REG_CMN_PLL_ICTAT100U_EN + #define OTP_TEMPERATURE_COMPENSATE_1_CMN_MMD1_REG_CMN_PLL_ICTAT100U_EN_OFFSET 15 + #define OTP_TEMPERATURE_COMPENSATE_1_CMN_MMD1_REG_CMN_PLL_ICTAT100U_EN_LEN 1 + #define OTP_TEMPERATURE_COMPENSATE_1_CMN_MMD1_REG_CMN_PLL_ICTAT100U_EN_DEFAULT 0x0 + +struct otp_temperature_compensate_1 { + a_uint32_t cmn_mmd1_reg_uphy_ictat100u_ctrl0:3; + a_uint32_t _reserved0:1; + a_uint32_t cmn_mmd1_reg_uphy_ictat100u_ctrl1:3; + a_uint32_t _reserved1:1; + a_uint32_t cmn_mmd1_reg_uphy_ictat100u_ctrl2:3; + a_uint32_t _reserved2:1; + a_uint32_t cmn_mmd1_reg_uphy_ictat100u_en:3; + a_uint32_t cmn_mmd1_reg_cmn_pll_ictat100u_en:1; + a_uint32_t _reserved3:16; +}; + +union otp_temperature_compensate_1_u { + a_uint32_t val; + struct otp_temperature_compensate_1 bf; +}; + +/*[register] PLL_VCO_RELATED_CONTROL_1*/ +#define PLL_VCO_RELATED_CONTROL_1 +#define PLL_VCO_RELATED_CONTROL_1_ADDRESS 0x9b78c +#define PLL_VCO_RELATED_CONTROL_1_NUM 4 +#define PLL_VCO_RELATED_CONTROL_1_INC 0x1 +#define PLL_VCO_RELATED_CONTROL_1_TYPE REG_TYPE_RW +#define PLL_VCO_RELATED_CONTROL_1_DEFAULT 0x0 + /*[field] CMN_MII_REG_REG_CMN_PLL_VCO_TEMP_CMP*/ + #define PLL_VCO_RELATED_CONTROL_1_CMN_MII_REG_REG_CMN_PLL_VCO_TEMP_CMP + #define PLL_VCO_RELATED_CONTROL_1_CMN_MII_REG_REG_CMN_PLL_VCO_TEMP_CMP_OFFSET 0 + #define PLL_VCO_RELATED_CONTROL_1_CMN_MII_REG_REG_CMN_PLL_VCO_TEMP_CMP_LEN 6 + #define PLL_VCO_RELATED_CONTROL_1_CMN_MII_REG_REG_CMN_PLL_VCO_TEMP_CMP_DEFAULT 0x0 + /*[field] CMN_MII_REG_REG_CMN_PLL_VCO_CALIB_READY*/ + #define PLL_VCO_RELATED_CONTROL_1_CMN_MII_REG_REG_CMN_PLL_VCO_CALIB_READY + #define PLL_VCO_RELATED_CONTROL_1_CMN_MII_REG_REG_CMN_PLL_VCO_CALIB_READY_OFFSET 6 + #define PLL_VCO_RELATED_CONTROL_1_CMN_MII_REG_REG_CMN_PLL_VCO_CALIB_READY_LEN 1 + #define PLL_VCO_RELATED_CONTROL_1_CMN_MII_REG_REG_CMN_PLL_VCO_CALIB_READY_DEFAULT 0x0 + /*[field] CMN_MII_REG_AUTOLOAD_SEL_PLL_VCO_CALIB_READY*/ + #define PLL_VCO_RELATED_CONTROL_1_CMN_MII_REG_AUTOLOAD_SEL_PLL_VCO_CALIB_READY + #define PLL_VCO_RELATED_CONTROL_1_CMN_MII_REG_AUTOLOAD_SEL_PLL_VCO_CALIB_READY_OFFSET 7 + #define PLL_VCO_RELATED_CONTROL_1_CMN_MII_REG_AUTOLOAD_SEL_PLL_VCO_CALIB_READY_LEN 1 + #define PLL_VCO_RELATED_CONTROL_1_CMN_MII_REG_AUTOLOAD_SEL_PLL_VCO_CALIB_READY_DEFAULT 0x0 + /*[field] CMN_MII_REG_REG_CMN_PLL_VCO_AMP*/ + #define PLL_VCO_RELATED_CONTROL_1_CMN_MII_REG_REG_CMN_PLL_VCO_AMP + #define PLL_VCO_RELATED_CONTROL_1_CMN_MII_REG_REG_CMN_PLL_VCO_AMP_OFFSET 8 + #define PLL_VCO_RELATED_CONTROL_1_CMN_MII_REG_REG_CMN_PLL_VCO_AMP_LEN 4 + #define PLL_VCO_RELATED_CONTROL_1_CMN_MII_REG_REG_CMN_PLL_VCO_AMP_DEFAULT 0x0 + /*[field] CMN_MII_REG_CMN_PLL_LCKDT_EN*/ + #define PLL_VCO_RELATED_CONTROL_1_CMN_MII_REG_CMN_PLL_LCKDT_EN + #define PLL_VCO_RELATED_CONTROL_1_CMN_MII_REG_CMN_PLL_LCKDT_EN_OFFSET 15 + #define PLL_VCO_RELATED_CONTROL_1_CMN_MII_REG_CMN_PLL_LCKDT_EN_LEN 1 + #define PLL_VCO_RELATED_CONTROL_1_CMN_MII_REG_CMN_PLL_LCKDT_EN_DEFAULT 0x0 + +struct pll_vco_related_control_1 { + a_uint32_t cmn_mii_reg_reg_cmn_pll_vco_temp_cmp:6; + a_uint32_t cmn_mii_reg_reg_cmn_pll_vco_calib_ready:1; + a_uint32_t cmn_mii_reg_autoload_sel_pll_vco_calib_ready:1; + a_uint32_t cmn_mii_reg_reg_cmn_pll_vco_amp:4; + a_uint32_t _reserved0:3; + a_uint32_t cmn_mii_reg_cmn_pll_lckdt_en:1; + a_uint32_t _reserved1:16; +}; + +union pll_vco_related_control_1_u { + a_uint32_t val; + struct pll_vco_related_control_1 bf; +}; + +/*[register] PLL_CONTROL_VCO_RELATED_SELECTION_2*/ +#define PLL_CONTROL_VCO_RELATED_SELECTION_2 +#define PLL_CONTROL_VCO_RELATED_SELECTION_2_ADDRESS 0x9b02c +#define PLL_CONTROL_VCO_RELATED_SELECTION_2_NUM 4 +#define PLL_CONTROL_VCO_RELATED_SELECTION_2_INC 0x1 +#define PLL_CONTROL_VCO_RELATED_SELECTION_2_TYPE REG_TYPE_RW +#define PLL_CONTROL_VCO_RELATED_SELECTION_2_DEFAULT 0x0 + /*[field] CMN_MMD1_REG_SRC_CMN_PLL_VCO_TEMP_CMP*/ + #define PLL_CONTROL_VCO_RELATED_SELECTION_2_CMN_MMD1_REG_SRC_CMN_PLL_VCO_TEMP_CMP + #define PLL_CONTROL_VCO_RELATED_SELECTION_2_CMN_MMD1_REG_SRC_CMN_PLL_VCO_TEMP_CMP_OFFSET 0 + #define PLL_CONTROL_VCO_RELATED_SELECTION_2_CMN_MMD1_REG_SRC_CMN_PLL_VCO_TEMP_CMP_LEN 2 + #define PLL_CONTROL_VCO_RELATED_SELECTION_2_CMN_MMD1_REG_SRC_CMN_PLL_VCO_TEMP_CMP_DEFAULT 0x0 + /*[field] CMN_MMD1_REG_SRC_CMN_PLL_VCO_AMP*/ + #define PLL_CONTROL_VCO_RELATED_SELECTION_2_CMN_MMD1_REG_SRC_CMN_PLL_VCO_AMP + #define PLL_CONTROL_VCO_RELATED_SELECTION_2_CMN_MMD1_REG_SRC_CMN_PLL_VCO_AMP_OFFSET 2 + #define PLL_CONTROL_VCO_RELATED_SELECTION_2_CMN_MMD1_REG_SRC_CMN_PLL_VCO_AMP_LEN 2 + #define PLL_CONTROL_VCO_RELATED_SELECTION_2_CMN_MMD1_REG_SRC_CMN_PLL_VCO_AMP_DEFAULT 0x0 + /*[field] CMN_MMD1_REG_SRC_CMN_PLL_FBCLK_DIV*/ + #define PLL_CONTROL_VCO_RELATED_SELECTION_2_CMN_MMD1_REG_SRC_CMN_PLL_FBCLK_DIV + #define PLL_CONTROL_VCO_RELATED_SELECTION_2_CMN_MMD1_REG_SRC_CMN_PLL_FBCLK_DIV_OFFSET 4 + #define PLL_CONTROL_VCO_RELATED_SELECTION_2_CMN_MMD1_REG_SRC_CMN_PLL_FBCLK_DIV_LEN 2 + #define PLL_CONTROL_VCO_RELATED_SELECTION_2_CMN_MMD1_REG_SRC_CMN_PLL_FBCLK_DIV_DEFAULT 0x0 + /*[field] CMN_MMD1_REG_SRC_CMN_PLL_VCO_CALIB_READY*/ + #define PLL_CONTROL_VCO_RELATED_SELECTION_2_CMN_MMD1_REG_SRC_CMN_PLL_VCO_CALIB_READY + #define PLL_CONTROL_VCO_RELATED_SELECTION_2_CMN_MMD1_REG_SRC_CMN_PLL_VCO_CALIB_READY_OFFSET 6 + #define PLL_CONTROL_VCO_RELATED_SELECTION_2_CMN_MMD1_REG_SRC_CMN_PLL_VCO_CALIB_READY_LEN 2 + #define PLL_CONTROL_VCO_RELATED_SELECTION_2_CMN_MMD1_REG_SRC_CMN_PLL_VCO_CALIB_READY_DEFAULT 0x0 + /*[field] CMN_MMD1_REG_SRC_CMN_PLL_VCO_CALIB_CODE*/ + #define PLL_CONTROL_VCO_RELATED_SELECTION_2_CMN_MMD1_REG_SRC_CMN_PLL_VCO_CALIB_CODE + #define PLL_CONTROL_VCO_RELATED_SELECTION_2_CMN_MMD1_REG_SRC_CMN_PLL_VCO_CALIB_CODE_OFFSET 8 + #define PLL_CONTROL_VCO_RELATED_SELECTION_2_CMN_MMD1_REG_SRC_CMN_PLL_VCO_CALIB_CODE_LEN 2 + #define PLL_CONTROL_VCO_RELATED_SELECTION_2_CMN_MMD1_REG_SRC_CMN_PLL_VCO_CALIB_CODE_DEFAULT 0x0 + /*[field] CMN_MMD1_REG_SRC_CMN_PLL_VCO_CALIB_START*/ + #define PLL_CONTROL_VCO_RELATED_SELECTION_2_CMN_MMD1_REG_SRC_CMN_PLL_VCO_CALIB_START + #define PLL_CONTROL_VCO_RELATED_SELECTION_2_CMN_MMD1_REG_SRC_CMN_PLL_VCO_CALIB_START_OFFSET 10 + #define PLL_CONTROL_VCO_RELATED_SELECTION_2_CMN_MMD1_REG_SRC_CMN_PLL_VCO_CALIB_START_LEN 2 + #define PLL_CONTROL_VCO_RELATED_SELECTION_2_CMN_MMD1_REG_SRC_CMN_PLL_VCO_CALIB_START_DEFAULT 0x0 + +struct pll_control_vco_related_selection_2 { + a_uint32_t cmn_mmd1_reg_src_cmn_pll_vco_temp_cmp:2; + a_uint32_t cmn_mmd1_reg_src_cmn_pll_vco_amp:2; + a_uint32_t cmn_mmd1_reg_src_cmn_pll_fbclk_div:2; + a_uint32_t cmn_mmd1_reg_src_cmn_pll_vco_calib_ready:2; + a_uint32_t cmn_mmd1_reg_src_cmn_pll_vco_calib_code:2; + a_uint32_t cmn_mmd1_reg_src_cmn_pll_vco_calib_start:2; + a_uint32_t _reserved0:20; +}; + +union pll_control_vco_related_selection_2_u { + a_uint32_t val; + struct pll_control_vco_related_selection_2 bf; +}; + +/*[register] PLL_POWER_ON_AND_RESET*/ +#define PLL_POWER_ON_AND_RESET +#define PLL_POWER_ON_AND_RESET_ADDRESS 0x780 +#define PLL_POWER_ON_AND_RESET_NUM 4 +#define PLL_POWER_ON_AND_RESET_INC 0x1 +#define PLL_POWER_ON_AND_RESET_TYPE REG_TYPE_RW +#define PLL_POWER_ON_AND_RESET_DEFAULT 0x2ff + /*[field] MIIREG_UPHY_PLL_RSTN*/ + #define MIIREG_UPHY_PLL_RSTN_MIIREG_UPHY_PLL_RSTN + #define MIIREG_UPHY_PLL_RSTN_MIIREG_UPHY_PLL_RSTN_OFFSET 0 + #define MIIREG_UPHY_PLL_RSTN_MIIREG_UPHY_PLL_RSTN_LEN 1 + #define MIIREG_UPHY_PLL_RSTN_MIIREG_UPHY_PLL_RSTN_DEFAULT 0x1 + /*[field] MIIREG_REG_UPHY_PLL_EN*/ + #define PLL_POWER_ON_AND_RESET_MIIREG_REG_UPHY_PLL_EN + #define PLL_POWER_ON_AND_RESET_MIIREG_REG_UPHY_PLL_EN_OFFSET 1 + #define PLL_POWER_ON_AND_RESET_MIIREG_REG_UPHY_PLL_EN_LEN 1 + #define PLL_POWER_ON_AND_RESET_MIIREG_REG_UPHY_PLL_EN_DEFAULT 0x1 + /*[field] MIIREG_UPHY_RXCLK_SW_RSTN*/ + #define PLL_POWER_ON_AND_RESET_MIIREG_UPHY_RXCLK_SW_RSTN + #define PLL_POWER_ON_AND_RESET_MIIREG_UPHY_RXCLK_SW_RSTN_OFFSET 2 + #define PLL_POWER_ON_AND_RESET_MIIREG_UPHY_RXCLK_SW_RSTN_LEN 1 + #define PLL_POWER_ON_AND_RESET_MIIREG_UPHY_RXCLK_SW_RSTN_DEFAULT 0x1 + /*[field] MIIREG_UPHY_RXCLK_FLOOP_SW_RSTN*/ + #define PLL_POWER_ON_AND_RESET_MIIREG_UPHY_RXCLK_FLOOP_SW_RSTN + #define PLL_POWER_ON_AND_RESET_MIIREG_UPHY_RXCLK_FLOOP_SW_RSTN_OFFSET 3 + #define PLL_POWER_ON_AND_RESET_MIIREG_UPHY_RXCLK_FLOOP_SW_RSTN_LEN 1 + #define PLL_POWER_ON_AND_RESET_MIIREG_UPHY_RXCLK_FLOOP_SW_RSTN_DEFAULT 0x1 + /*[field] MIIREG_UPHY_TXCLK_SW_RSTN*/ + #define PLL_POWER_ON_AND_RESET_MIIREG_UPHY_TXCLK_SW_RSTN + #define PLL_POWER_ON_AND_RESET_MIIREG_UPHY_TXCLK_SW_RSTN_OFFSET 4 + #define PLL_POWER_ON_AND_RESET_MIIREG_UPHY_TXCLK_SW_RSTN_LEN 1 + #define PLL_POWER_ON_AND_RESET_MIIREG_UPHY_TXCLK_SW_RSTN_DEFAULT 0x0 + /*[field] MIIREG_UPHY_SSC_CTRL_CLK_SW_RSTN*/ + #define PLL_POWER_ON_AND_RESET_MIIREG_UPHY_SSC_CTRL_CLK_SW_RSTN + #define PLL_POWER_ON_AND_RESET_MIIREG_UPHY_SSC_CTRL_CLK_SW_RSTN_OFFSET 5 + #define PLL_POWER_ON_AND_RESET_MIIREG_UPHY_SSC_CTRL_CLK_SW_RSTN_LEN 1 + #define PLL_POWER_ON_AND_RESET_MIIREG_UPHY_SSC_CTRL_CLK_SW_RSTN_DEFAULT 0x0 + /*[field] MIIREG_UPHY_ANA_EN_SW_RSTN*/ + #define PLL_POWER_ON_AND_RESET_MIIREG_UPHY_ANA_EN_SW_RSTN + #define PLL_POWER_ON_AND_RESET_MIIREG_UPHY_ANA_EN_SW_RSTN_OFFSET 6 + #define PLL_POWER_ON_AND_RESET_MIIREG_UPHY_ANA_EN_SW_RSTN_LEN 1 + #define PLL_POWER_ON_AND_RESET_MIIREG_UPHY_ANA_EN_SW_RSTN_DEFAULT 0x0 + /*[field] MIIREG_UPHY_PLL_MMDIV_RSTN*/ + #define PLL_POWER_ON_AND_RESET_MIIREG_UPHY_PLL_MMDIV_RSTN + #define PLL_POWER_ON_AND_RESET_MIIREG_UPHY_PLL_MMDIV_RSTN_OFFSET 7 + #define PLL_POWER_ON_AND_RESET_MIIREG_UPHY_PLL_MMDIV_RSTN_LEN 1 + #define PLL_POWER_ON_AND_RESET_MIIREG_UPHY_PLL_MMDIV_RSTN_DEFAULT 0x0 + /*[field] MIIREG_UPHY_CMN_12GPLL_ISOLATION*/ + #define PLL_POWER_ON_AND_RESET_MIIREG_UPHY_CMN_12GPLL_ISOLATION + #define PLL_POWER_ON_AND_RESET_MIIREG_UPHY_CMN_12GPLL_ISOLATION_OFFSET 8 + #define PLL_POWER_ON_AND_RESET_MIIREG_UPHY_CMN_12GPLL_ISOLATION_LEN 1 + #define PLL_POWER_ON_AND_RESET_MIIREG_UPHY_CMN_12GPLL_ISOLATION_DEFAULT 0x0 + /*[field] MIIREG_UPHY_PCS_SW_RSTN*/ + #define PLL_POWER_ON_AND_RESET_MIIREG_UPHY_PCS_SW_RSTN + #define PLL_POWER_ON_AND_RESET_MIIREG_UPHY_PCS_SW_RSTN_OFFSET 9 + #define PLL_POWER_ON_AND_RESET_MIIREG_UPHY_PCS_SW_RSTN_LEN 1 + #define PLL_POWER_ON_AND_RESET_MIIREG_UPHY_PCS_SW_RSTN_DEFAULT 0x0 + +struct pll_power_on_and_reset { + a_uint32_t pll_reset:1; + a_uint32_t pll_power_on:1; + a_uint32_t software_reset_rxclk:1; + a_uint32_t software_reset_rxclk_floop:1; + a_uint32_t software_reset_txclk:1; + a_uint32_t software_reset_ctrlclk:1; + a_uint32_t software_reset_analog_reset:1; + a_uint32_t reference_clock_reset:1; + a_uint32_t cmn_12gpll_isolation:1; + a_uint32_t pqsgmii_pcs_reset:1; + a_uint32_t _reserved0:22; +}; + +union pll_power_on_and_reset_u { + a_uint32_t val; + struct pll_power_on_and_reset bf; +}; + +/*[register] UNIPHY_MISC2_PHY_MODE*/ +#define UNIPHY_MISC2_PHY_MODE +#define UNIPHY_MISC2_PHY_MODE_ADDRESS 0x218 +#define UNIPHY_MISC2_PHY_MODE_NUM 4 +#define UNIPHY_MISC2_PHY_MODE_INC 0x1 +#define UNIPHY_MISC2_PHY_MODE_TYPE REG_TYPE_RW +#define UNIPHY_MISC2_PHY_MODE_DEFAULT 0x0 + /*[field] MMD1_REG_REG_RATE*/ + #define UNIPHY_MISC2_PHY_MODE_MMD1_REG_REG_RATE + #define UNIPHY_MISC2_PHY_MODE_MMD1_REG_REG_RATE_OFFSET 0 + #define UNIPHY_MISC2_PHY_MODE_MMD1_REG_REG_RATE_LEN 2 + #define UNIPHY_MISC2_PHY_MODE_MMD1_REG_REG_RATE_DEFAULT 0x1 + /*[field] MMD1_REG_REG_PHY_MODE*/ + #define UNIPHY_MISC2_PHY_MODE_MMD1_REG_REG_PHY_MODE + #define UNIPHY_MISC2_PHY_MODE_MMD1_REG_REG_PHY_MODE_OFFSET 4 + #define UNIPHY_MISC2_PHY_MODE_MMD1_REG_REG_PHY_MODE_LEN 3 + #define UNIPHY_MISC2_PHY_MODE_MMD1_REG_REG_PHY_MODE_DEFAULT 0x1 + + +struct uniphy_misc2_phy_mode { + a_uint32_t phy_rate:2; + a_uint32_t _reserved0:2; + a_uint32_t phy_mode:3; + a_uint32_t _reserved1:25; +}; + +union uniphy_misc2_phy_mode_u { + a_uint32_t val; + struct uniphy_misc2_phy_mode bf; +}; + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_vsi.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_vsi.h new file mode 100755 index 000000000..b8f9b5fbb --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_vsi.h @@ -0,0 +1,270 @@ +/* + * 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 + * @{ + */ +#ifndef _HPPE_VSI_H_ +#define _HPPE_VSI_H_ + +#define VSI_TBL_MAX_ENTRY 32 +#define VLAN_CNT_TBL_MAX_ENTRY 32 +#define EG_VSI_COUNTER_TBL_MAX_ENTRY 32 +#define PRE_L2_CNT_TBL_MAX_ENTRY 32 + +sw_error_t +hppe_vsi_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union vsi_tbl_u *value); + +sw_error_t +hppe_vsi_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union vsi_tbl_u *value); + +sw_error_t +hppe_vsi_tbl_umc_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vsi_tbl_umc_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vsi_tbl_station_move_lrn_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vsi_tbl_station_move_lrn_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vsi_tbl_new_addr_fwd_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vsi_tbl_new_addr_fwd_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vsi_tbl_uuc_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vsi_tbl_uuc_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vsi_tbl_member_port_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vsi_tbl_member_port_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vsi_tbl_new_addr_lrn_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vsi_tbl_new_addr_lrn_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vsi_tbl_bc_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vsi_tbl_bc_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vsi_tbl_station_move_fwd_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vsi_tbl_station_move_fwd_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_vlan_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union vlan_cnt_tbl_u *value); + +sw_error_t +hppe_vlan_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union vlan_cnt_tbl_u *value); + +sw_error_t +hppe_vlan_cnt_tbl_rx_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_vlan_cnt_tbl_rx_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_vlan_cnt_tbl_rx_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_vlan_cnt_tbl_rx_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_eg_vsi_counter_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union eg_vsi_counter_tbl_u *value); + +sw_error_t +hppe_eg_vsi_counter_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union eg_vsi_counter_tbl_u *value); + + +sw_error_t +hppe_eg_vsi_counter_tbl_tx_bytes_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_eg_vsi_counter_tbl_tx_bytes_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_eg_vsi_counter_tbl_tx_packets_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_eg_vsi_counter_tbl_tx_packets_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pre_l2_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union pre_l2_cnt_tbl_u *value); + +sw_error_t +hppe_pre_l2_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union pre_l2_cnt_tbl_u *value); + +sw_error_t +hppe_pre_l2_cnt_tbl_rx_drop_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_pre_l2_cnt_tbl_rx_drop_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_pre_l2_cnt_tbl_rx_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value); + +sw_error_t +hppe_pre_l2_cnt_tbl_rx_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value); + +sw_error_t +hppe_pre_l2_cnt_tbl_rx_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pre_l2_cnt_tbl_rx_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_pre_l2_cnt_tbl_rx_drop_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_pre_l2_cnt_tbl_rx_drop_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_vsi_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_vsi_reg.h new file mode 100755 index 000000000..7a94bc332 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_vsi_reg.h @@ -0,0 +1,192 @@ +/* + * 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 + * @{ + */ +#ifndef HPPE_VSI_REG_H +#define HPPE_VSI_REG_H + +/*[table] VSI_TBL*/ +#define VSI_TBL +#define VSI_TBL_ADDRESS 0x1800 +#define VSI_TBL_NUM 32 +#define VSI_TBL_INC 0x10 +#define VSI_TBL_TYPE REG_TYPE_RW +#define VSI_TBL_DEFAULT 0x0 + /*[field] MEMBER_PORT_BITMAP*/ + #define VSI_TBL_MEMBER_PORT_BITMAP + #define VSI_TBL_MEMBER_PORT_BITMAP_OFFSET 0 + #define VSI_TBL_MEMBER_PORT_BITMAP_LEN 8 + #define VSI_TBL_MEMBER_PORT_BITMAP_DEFAULT 0x0 + /*[field] UUC_BITMAP*/ + #define VSI_TBL_UUC_BITMAP + #define VSI_TBL_UUC_BITMAP_OFFSET 8 + #define VSI_TBL_UUC_BITMAP_LEN 8 + #define VSI_TBL_UUC_BITMAP_DEFAULT 0x0 + /*[field] UMC_BITMAP*/ + #define VSI_TBL_UMC_BITMAP + #define VSI_TBL_UMC_BITMAP_OFFSET 16 + #define VSI_TBL_UMC_BITMAP_LEN 8 + #define VSI_TBL_UMC_BITMAP_DEFAULT 0x0 + /*[field] BC_BITMAP*/ + #define VSI_TBL_BC_BITMAP + #define VSI_TBL_BC_BITMAP_OFFSET 24 + #define VSI_TBL_BC_BITMAP_LEN 8 + #define VSI_TBL_BC_BITMAP_DEFAULT 0x0 + /*[field] NEW_ADDR_LRN_EN*/ + #define VSI_TBL_NEW_ADDR_LRN_EN + #define VSI_TBL_NEW_ADDR_LRN_EN_OFFSET 32 + #define VSI_TBL_NEW_ADDR_LRN_EN_LEN 1 + #define VSI_TBL_NEW_ADDR_LRN_EN_DEFAULT 0x0 + /*[field] NEW_ADDR_FWD_CMD*/ + #define VSI_TBL_NEW_ADDR_FWD_CMD + #define VSI_TBL_NEW_ADDR_FWD_CMD_OFFSET 33 + #define VSI_TBL_NEW_ADDR_FWD_CMD_LEN 2 + #define VSI_TBL_NEW_ADDR_FWD_CMD_DEFAULT 0x0 + /*[field] STATION_MOVE_LRN_EN*/ + #define VSI_TBL_STATION_MOVE_LRN_EN + #define VSI_TBL_STATION_MOVE_LRN_EN_OFFSET 35 + #define VSI_TBL_STATION_MOVE_LRN_EN_LEN 1 + #define VSI_TBL_STATION_MOVE_LRN_EN_DEFAULT 0x0 + /*[field] STATION_MOVE_FWD_CMD*/ + #define VSI_TBL_STATION_MOVE_FWD_CMD + #define VSI_TBL_STATION_MOVE_FWD_CMD_OFFSET 36 + #define VSI_TBL_STATION_MOVE_FWD_CMD_LEN 2 + #define VSI_TBL_STATION_MOVE_FWD_CMD_DEFAULT 0x0 + +struct vsi_tbl { + a_uint32_t member_port_bitmap:8; + a_uint32_t uuc_bitmap:8; + a_uint32_t umc_bitmap:8; + a_uint32_t bc_bitmap:8; + a_uint32_t new_addr_lrn_en:1; + a_uint32_t new_addr_fwd_cmd:2; + a_uint32_t station_move_lrn_en:1; + a_uint32_t station_move_fwd_cmd:2; + a_uint32_t _reserved0:26; +}; + +union vsi_tbl_u { + a_uint32_t val[2]; + struct vsi_tbl bf; +}; + +/*[table] VLAN_CNT_TBL*/ +#define VLAN_CNT_TBL +#define VLAN_CNT_TBL_ADDRESS 0x78000 +#define VLAN_CNT_TBL_NUM 32 +#define VLAN_CNT_TBL_INC 0x10 +#define VLAN_CNT_TBL_TYPE REG_TYPE_RW +#define VLAN_CNT_TBL_DEFAULT 0x0 + /*[field] RX_PKT_CNT*/ + #define VLAN_CNT_TBL_RX_PKT_CNT + #define VLAN_CNT_TBL_RX_PKT_CNT_OFFSET 0 + #define VLAN_CNT_TBL_RX_PKT_CNT_LEN 32 + #define VLAN_CNT_TBL_RX_PKT_CNT_DEFAULT 0x0 + /*[field] RX_BYTE_CNT*/ + #define VLAN_CNT_TBL_RX_BYTE_CNT + #define VLAN_CNT_TBL_RX_BYTE_CNT_OFFSET 32 + #define VLAN_CNT_TBL_RX_BYTE_CNT_LEN 40 + #define VLAN_CNT_TBL_RX_BYTE_CNT_DEFAULT 0x0 + +struct vlan_cnt_tbl { + a_uint32_t rx_pkt_cnt:32; + a_uint32_t rx_byte_cnt_0:32; + a_uint32_t rx_byte_cnt_1:8; + a_uint32_t _reserved0:24; +}; + +union vlan_cnt_tbl_u { + a_uint32_t val[3]; + struct vlan_cnt_tbl bf; +}; + +/*[table] EG_VSI_COUNTER_TBL*/ +#define EG_VSI_COUNTER_TBL +#define EG_VSI_COUNTER_TBL_ADDRESS 0x600 +#define EG_VSI_COUNTER_TBL_NUM 32 +#define EG_VSI_COUNTER_TBL_INC 0x10 +#define EG_VSI_COUNTER_TBL_TYPE REG_TYPE_RW +#define EG_VSI_COUNTER_TBL_DEFAULT 0x0 + /*[field] TX_PACKETS*/ + #define EG_VSI_COUNTER_TBL_TX_PACKETS + #define EG_VSI_COUNTER_TBL_TX_PACKETS_OFFSET 0 + #define EG_VSI_COUNTER_TBL_TX_PACKETS_LEN 32 + #define EG_VSI_COUNTER_TBL_TX_PACKETS_DEFAULT 0x0 + /*[field] TX_BYTES*/ + #define EG_VSI_COUNTER_TBL_TX_BYTES + #define EG_VSI_COUNTER_TBL_TX_BYTES_OFFSET 32 + #define EG_VSI_COUNTER_TBL_TX_BYTES_LEN 40 + #define EG_VSI_COUNTER_TBL_TX_BYTES_DEFAULT 0x0 + +struct eg_vsi_counter_tbl { + a_uint32_t tx_packets:32; + a_uint32_t tx_bytes_0:32; + a_uint32_t tx_bytes_1:8; + a_uint32_t _reserved0:24; +}; + +union eg_vsi_counter_tbl_u { + a_uint32_t val[3]; + struct eg_vsi_counter_tbl bf; +}; + +/*[table] PRE_L2_CNT_TBL*/ +#define PRE_L2_CNT_TBL +#define PRE_L2_CNT_TBL_ADDRESS 0x7c000 +#define PRE_L2_CNT_TBL_NUM 32 +#define PRE_L2_CNT_TBL_INC 0x20 +#define PRE_L2_CNT_TBL_TYPE REG_TYPE_RW +#define PRE_L2_CNT_TBL_DEFAULT 0x0 + /*[field] RX_PKT_CNT*/ + #define PRE_L2_CNT_TBL_RX_PKT_CNT + #define PRE_L2_CNT_TBL_RX_PKT_CNT_OFFSET 0 + #define PRE_L2_CNT_TBL_RX_PKT_CNT_LEN 32 + #define PRE_L2_CNT_TBL_RX_PKT_CNT_DEFAULT 0x0 + /*[field] RX_BYTE_CNT*/ + #define PRE_L2_CNT_TBL_RX_BYTE_CNT + #define PRE_L2_CNT_TBL_RX_BYTE_CNT_OFFSET 32 + #define PRE_L2_CNT_TBL_RX_BYTE_CNT_LEN 40 + #define PRE_L2_CNT_TBL_RX_BYTE_CNT_DEFAULT 0x0 + /*[field] RX_DROP_PKT_CNT*/ + #define PRE_L2_CNT_TBL_RX_DROP_PKT_CNT + #define PRE_L2_CNT_TBL_RX_DROP_PKT_CNT_OFFSET 72 + #define PRE_L2_CNT_TBL_RX_DROP_PKT_CNT_LEN 32 + #define PRE_L2_CNT_TBL_RX_DROP_PKT_CNT_DEFAULT 0x0 + /*[field] RX_DROP_BYTE_CNT*/ + #define PRE_L2_CNT_TBL_RX_DROP_BYTE_CNT + #define PRE_L2_CNT_TBL_RX_DROP_BYTE_CNT_OFFSET 104 + #define PRE_L2_CNT_TBL_RX_DROP_BYTE_CNT_LEN 40 + #define PRE_L2_CNT_TBL_RX_DROP_BYTE_CNT_DEFAULT 0x0 + +struct pre_l2_cnt_tbl { + a_uint32_t rx_pkt_cnt:32; + a_uint32_t rx_byte_cnt_0:32; + a_uint32_t rx_byte_cnt_1:8; + a_uint32_t rx_drop_pkt_cnt_0:24; + a_uint32_t rx_drop_pkt_cnt_1:8; + a_uint32_t rx_drop_byte_cnt_0:24; + a_uint32_t rx_drop_byte_cnt_1:16; + a_uint32_t _reserved0:16; +}; + +union pre_l2_cnt_tbl_u { + a_uint32_t val[5]; + struct pre_l2_cnt_tbl bf; +}; + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_xgmacmib.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_xgmacmib.h new file mode 100755 index 000000000..40997c6f2 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_xgmacmib.h @@ -0,0 +1,2252 @@ +/* + * 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 + * @{ + */ +#ifndef _HPPE_XGMACMIB_H_ +#define _HPPE_XGMACMIB_H_ + +#define MMC_CONTROL_MAX_ENTRY 2 +#define MMC_RECEIVE_INTERRUPT_MAX_ENTRY 2 +#define MMC_TRANSMIT_INTERRUPT_MAX_ENTRY 2 +#define MMC_RECEIVE_INTERRUPT_ENABLE_MAX_ENTRY 2 +#define MMC_TRANSMIT_INTERRUPT_ENABLE_MAX_ENTRY 2 +#define TX_OCTET_COUNT_GOOD_BAD_LOW_MAX_ENTRY 2 +#define TX_OCTET_COUNT_GOOD_BAD_HIGH_MAX_ENTRY 2 +#define TX_FRAME_COUNT_GOOD_BAD_LOW_MAX_ENTRY 2 +#define TX_FRAME_COUNT_GOOD_BAD_HIGH_MAX_ENTRY 2 +#define TX_BROADCAST_FRAMES_GOOD_LOW_MAX_ENTRY 2 +#define TX_BROADCAST_FRAMES_GOOD_HIGH_MAX_ENTRY 2 +#define TX_MULTICAST_FRAMES_GOOD_LOW_MAX_ENTRY 2 +#define TX_MULTICAST_FRAMES_GOOD_HIGH_MAX_ENTRY 2 +#define TX_64OCTETS_FRAMES_GOOD_BAD_LOW_MAX_ENTRY 2 +#define TX_64OCTETS_FRAMES_GOOD_BAD_HIGH_MAX_ENTRY 2 +#define TX_65TO127OCTETS_FRAMES_GOOD_BAD_LOW_MAX_ENTRY 2 +#define TX_65TO127OCTETS_FRAMES_GOOD_BAD_HIGH_MAX_ENTRY 2 +#define TX_128TO255OCTETS_FRAMES_GOOD_BAD_LOW_MAX_ENTRY 2 +#define TX_128TO255OCTETS_FRAMES_GOOD_BAD_HIGH_MAX_ENTRY 2 +#define TX_256TO511OCTETS_FRAMES_GOOD_BAD_LOW_MAX_ENTRY 2 +#define TX_256TO511OCTETS_FRAMES_GOOD_BAD_HIGH_MAX_ENTRY 2 +#define TX_512TO1023OCTETS_FRAMES_GOOD_BAD_LOW_MAX_ENTRY 2 +#define TX_512TO1023OCTETS_FRAMES_GOOD_BAD_HIGH_MAX_ENTRY 2 +#define TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_LOW_MAX_ENTRY 2 +#define TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_HIGH_MAX_ENTRY 2 +#define TX_UNICAST_FRAMES_GOOD_BAD_LOW_MAX_ENTRY 2 +#define TX_UNICAST_FRAMES_GOOD_BAD_HIGH_MAX_ENTRY 2 +#define TX_MULTICAST_FRAMES_GOOD_BAD_LOW_MAX_ENTRY 2 +#define TX_MULTICAST_FRAMES_GOOD_BAD_HIGH_MAX_ENTRY 2 +#define TX_BROADCAST_FRAMES_GOOD_BAD_LOW_MAX_ENTRY 2 +#define TX_BROADCAST_FRAMES_GOOD_BAD_HIGH_MAX_ENTRY 2 +#define TX_UNDERFLOW_ERROR_FRAMES_LOW_MAX_ENTRY 2 +#define TX_UNDERFLOW_ERROR_FRAMES_HIGH_MAX_ENTRY 2 +#define TX_OCTET_COUNT_GOOD_LOW_MAX_ENTRY 2 +#define TX_OCTET_COUNT_GOOD_HIGH_MAX_ENTRY 2 +#define TX_FRAME_COUNT_GOOD_LOW_MAX_ENTRY 2 +#define TX_FRAME_COUNT_GOOD_HIGH_MAX_ENTRY 2 +#define TX_PAUSE_FRAMES_LOW_MAX_ENTRY 2 +#define TX_PAUSE_FRAMES_HIGH_MAX_ENTRY 2 +#define TX_VLAN_FRAMES_GOOD_LOW_MAX_ENTRY 2 +#define TX_VLAN_FRAMES_GOOD_HIGH_MAX_ENTRY 2 +#define TX_LPI_USEC_CNTR_MAX_ENTRY 2 +#define TX_LPI_TRAN_CNTR_MAX_ENTRY 2 +#define RX_FRAME_COUNT_GOOD_BAD_LOW_MAX_ENTRY 2 +#define RX_FRAME_COUNT_GOOD_BAD_HIGH_MAX_ENTRY 2 +#define RX_OCTET_COUNT_GOOD_BAD_LOW_MAX_ENTRY 2 +#define RX_OCTET_COUNT_GOOD_BAD_HIGH_MAX_ENTRY 2 +#define RX_OCTET_COUNT_GOOD_LOW_MAX_ENTRY 2 +#define RX_OCTET_COUNT_GOOD_HIGH_MAX_ENTRY 2 +#define RX_BROADCAST_FRAMES_GOOD_LOW_MAX_ENTRY 2 +#define RX_BROADCAST_FRAMES_GOOD_HIGH_MAX_ENTRY 2 +#define RX_MULTICAST_FRAMES_GOOD_LOW_MAX_ENTRY 2 +#define RX_MULTICAST_FRAMES_GOOD_HIGH_MAX_ENTRY 2 +#define RX_CRC_ERROR_FRAMES_LOW_MAX_ENTRY 2 +#define RX_CRC_ERROR_FRAMES_HIGH_MAX_ENTRY 2 +#define RX_RUNT_ERROR_FRAMES_MAX_ENTRY 2 +#define RX_JABBER_ERROR_FRAMES_MAX_ENTRY 2 +#define RX_UNDERSIZE_FRAMES_GOOD_MAX_ENTRY 2 +#define RX_OVERSIZE_FRAMES_GOOD_MAX_ENTRY 2 +#define RX_64OCTETS_FRAMES_GOOD_BAD_LOW_MAX_ENTRY 2 +#define RX_64OCTETS_FRAMES_GOOD_BAD_HIGH_MAX_ENTRY 2 +#define RX_65TO127OCTETS_FRAMES_GOOD_BAD_LOW_MAX_ENTRY 2 +#define RX_65TO127OCTETS_FRAMES_GOOD_BAD_HIGH_MAX_ENTRY 2 +#define RX_128TO255OCTETS_FRAMES_GOOD_BAD_LOW_MAX_ENTRY 2 +#define RX_128TO255OCTETS_FRAMES_GOOD_BAD_HIGH_MAX_ENTRY 2 +#define RX_256TO511OCTETS_FRAMES_GOOD_BAD_LOW_MAX_ENTRY 2 +#define RX_256TO511OCTETS_FRAMES_GOOD_BAD_HIGH_MAX_ENTRY 2 +#define RX_512TO1023OCTETS_FRAMES_GOOD_BAD_LOW_MAX_ENTRY 2 +#define RX_512TO1023OCTETS_FRAMES_GOOD_BAD_HIGH_MAX_ENTRY 2 +#define RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_LOW_MAX_ENTRY 2 +#define RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_HIGH_MAX_ENTRY 2 +#define RX_UNICAST_FRAMES_GOOD_LOW_MAX_ENTRY 2 +#define RX_UNICAST_FRAMES_GOOD_HIGH_MAX_ENTRY 2 +#define RX_LENGTH_ERROR_FRAMES_LOW_MAX_ENTRY 2 +#define RX_LENGTH_ERROR_FRAMES_HIGH_MAX_ENTRY 2 +#define RX_OUTOFRANGE_FRAMES_LOW_MAX_ENTRY 2 +#define RX_OUTOFRANGE_FRAMES_HIGH_MAX_ENTRY 2 +#define RX_PAUSE_FRAMES_LOW_MAX_ENTRY 2 +#define RX_PAUSE_FRAMES_HIGH_MAX_ENTRY 2 +#define RX_FIFOOVERFLOW_FRAMES_LOW_MAX_ENTRY 2 +#define RX_FIFOOVERFLOW_FRAMES_HIGH_MAX_ENTRY 2 +#define RX_VLAN_FRAMES_GOOD_BAD_LOW_MAX_ENTRY 2 +#define RX_VLAN_FRAMES_GOOD_BAD_HIGH_MAX_ENTRY 2 +#define RX_WATCHDOG_ERROR_FRAMES_MAX_ENTRY 2 +#define RX_LPI_USEC_CNTR_MAX_ENTRY 2 +#define RX_LPI_TRAN_CNTR_MAX_ENTRY 2 +#define RX_DISCARD_FRAME_COUNT_GOOD_BAD_LOW_MAX_ENTRY 2 +#define RX_DISCARD_FRAME_COUNT_GOOD_BAD_HIGH_MAX_ENTRY 2 +#define RX_DISCARD_OCTET_COUNT_GOOD_BAD_LOW_MAX_ENTRY 2 +#define RX_DISCARD_OCTET_COUNT_GOOD_BAD_HIGH_MAX_ENTRY 2 + +sw_error_t +hppe_mmc_control_get( + a_uint32_t dev_id, + a_uint32_t index, + union mmc_control_u *value); + +sw_error_t +hppe_mmc_control_set( + a_uint32_t dev_id, + a_uint32_t index, + union mmc_control_u *value); + +sw_error_t +hppe_tx_octet_count_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_octet_count_good_bad_low_u *value); + +sw_error_t +hppe_tx_octet_count_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_octet_count_good_bad_low_u *value); + +sw_error_t +hppe_tx_octet_count_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_octet_count_good_bad_high_u *value); + +sw_error_t +hppe_tx_octet_count_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_octet_count_good_bad_high_u *value); + +sw_error_t +hppe_tx_frame_count_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_frame_count_good_bad_low_u *value); + +sw_error_t +hppe_tx_frame_count_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_frame_count_good_bad_low_u *value); + +sw_error_t +hppe_tx_frame_count_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_frame_count_good_bad_high_u *value); + +sw_error_t +hppe_tx_frame_count_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_frame_count_good_bad_high_u *value); + +sw_error_t +hppe_tx_broadcast_frames_good_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_broadcast_frames_good_low_u *value); + +sw_error_t +hppe_tx_broadcast_frames_good_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_broadcast_frames_good_low_u *value); + +sw_error_t +hppe_tx_broadcast_frames_good_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_broadcast_frames_good_high_u *value); + +sw_error_t +hppe_tx_broadcast_frames_good_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_broadcast_frames_good_high_u *value); + +sw_error_t +hppe_tx_multicast_frames_good_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_multicast_frames_good_low_u *value); + +sw_error_t +hppe_tx_multicast_frames_good_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_multicast_frames_good_low_u *value); + +sw_error_t +hppe_tx_multicast_frames_good_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_multicast_frames_good_high_u *value); + +sw_error_t +hppe_tx_multicast_frames_good_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_multicast_frames_good_high_u *value); + +sw_error_t +hppe_tx_64octets_frames_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_64octets_frames_good_bad_low_u *value); + +sw_error_t +hppe_tx_64octets_frames_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_64octets_frames_good_bad_low_u *value); + +sw_error_t +hppe_tx_64octets_frames_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_64octets_frames_good_bad_high_u *value); + +sw_error_t +hppe_tx_64octets_frames_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_64octets_frames_good_bad_high_u *value); + +sw_error_t +hppe_tx_65to127octets_frames_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_65to127octets_frames_good_bad_low_u *value); + +sw_error_t +hppe_tx_65to127octets_frames_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_65to127octets_frames_good_bad_low_u *value); + +sw_error_t +hppe_tx_65to127octets_frames_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_65to127octets_frames_good_bad_high_u *value); + +sw_error_t +hppe_tx_65to127octets_frames_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_65to127octets_frames_good_bad_high_u *value); + +sw_error_t +hppe_tx_128to255octets_frames_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_128to255octets_frames_good_bad_low_u *value); + +sw_error_t +hppe_tx_128to255octets_frames_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_128to255octets_frames_good_bad_low_u *value); + +sw_error_t +hppe_tx_128to255octets_frames_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_128to255octets_frames_good_bad_high_u *value); + +sw_error_t +hppe_tx_128to255octets_frames_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_128to255octets_frames_good_bad_high_u *value); + +sw_error_t +hppe_tx_256to511octets_frames_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_256to511octets_frames_good_bad_low_u *value); + +sw_error_t +hppe_tx_256to511octets_frames_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_256to511octets_frames_good_bad_low_u *value); + +sw_error_t +hppe_tx_256to511octets_frames_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_256to511octets_frames_good_bad_high_u *value); + +sw_error_t +hppe_tx_256to511octets_frames_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_256to511octets_frames_good_bad_high_u *value); + +sw_error_t +hppe_tx_512to1023octets_frames_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_512to1023octets_frames_good_bad_low_u *value); + +sw_error_t +hppe_tx_512to1023octets_frames_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_512to1023octets_frames_good_bad_low_u *value); + +sw_error_t +hppe_tx_512to1023octets_frames_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_512to1023octets_frames_good_bad_high_u *value); + +sw_error_t +hppe_tx_512to1023octets_frames_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_512to1023octets_frames_good_bad_high_u *value); + +sw_error_t +hppe_tx_1024tomaxoctets_frames_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_1024tomaxoctets_frames_good_bad_low_u *value); + +sw_error_t +hppe_tx_1024tomaxoctets_frames_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_1024tomaxoctets_frames_good_bad_low_u *value); + +sw_error_t +hppe_tx_1024tomaxoctets_frames_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_1024tomaxoctets_frames_good_bad_high_u *value); + +sw_error_t +hppe_tx_1024tomaxoctets_frames_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_1024tomaxoctets_frames_good_bad_high_u *value); + +sw_error_t +hppe_tx_unicast_frames_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_unicast_frames_good_bad_low_u *value); + +sw_error_t +hppe_tx_unicast_frames_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_unicast_frames_good_bad_low_u *value); + +sw_error_t +hppe_tx_unicast_frames_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_unicast_frames_good_bad_high_u *value); + +sw_error_t +hppe_tx_unicast_frames_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_unicast_frames_good_bad_high_u *value); + +sw_error_t +hppe_tx_multicast_frames_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_multicast_frames_good_bad_low_u *value); + +sw_error_t +hppe_tx_multicast_frames_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_multicast_frames_good_bad_low_u *value); + +sw_error_t +hppe_tx_multicast_frames_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_multicast_frames_good_bad_high_u *value); + +sw_error_t +hppe_tx_multicast_frames_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_multicast_frames_good_bad_high_u *value); + +sw_error_t +hppe_tx_broadcast_frames_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_broadcast_frames_good_bad_low_u *value); + +sw_error_t +hppe_tx_broadcast_frames_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_broadcast_frames_good_bad_low_u *value); + +sw_error_t +hppe_tx_broadcast_frames_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_broadcast_frames_good_bad_high_u *value); + +sw_error_t +hppe_tx_broadcast_frames_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_broadcast_frames_good_bad_high_u *value); + +sw_error_t +hppe_tx_underflow_error_frames_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_underflow_error_frames_low_u *value); + +sw_error_t +hppe_tx_underflow_error_frames_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_underflow_error_frames_low_u *value); + +sw_error_t +hppe_tx_underflow_error_frames_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_underflow_error_frames_high_u *value); + +sw_error_t +hppe_tx_underflow_error_frames_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_underflow_error_frames_high_u *value); + +sw_error_t +hppe_tx_octet_count_good_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_octet_count_good_low_u *value); + +sw_error_t +hppe_tx_octet_count_good_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_octet_count_good_low_u *value); + +sw_error_t +hppe_tx_octet_count_good_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_octet_count_good_high_u *value); + +sw_error_t +hppe_tx_octet_count_good_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_octet_count_good_high_u *value); + +sw_error_t +hppe_tx_frame_count_good_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_frame_count_good_low_u *value); + +sw_error_t +hppe_tx_frame_count_good_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_frame_count_good_low_u *value); + +sw_error_t +hppe_tx_frame_count_good_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_frame_count_good_high_u *value); + +sw_error_t +hppe_tx_frame_count_good_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_frame_count_good_high_u *value); + +sw_error_t +hppe_tx_pause_frames_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_pause_frames_low_u *value); + +sw_error_t +hppe_tx_pause_frames_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_pause_frames_low_u *value); + +sw_error_t +hppe_tx_pause_frames_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_pause_frames_high_u *value); + +sw_error_t +hppe_tx_pause_frames_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_pause_frames_high_u *value); + +sw_error_t +hppe_tx_vlan_frames_good_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_vlan_frames_good_low_u *value); + +sw_error_t +hppe_tx_vlan_frames_good_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_vlan_frames_good_low_u *value); + +sw_error_t +hppe_tx_vlan_frames_good_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_vlan_frames_good_high_u *value); + +sw_error_t +hppe_tx_vlan_frames_good_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_vlan_frames_good_high_u *value); + +sw_error_t +hppe_tx_lpi_usec_cntr_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_lpi_usec_cntr_u *value); + +sw_error_t +hppe_tx_lpi_usec_cntr_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_lpi_usec_cntr_u *value); + +sw_error_t +hppe_tx_lpi_tran_cntr_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_lpi_tran_cntr_u *value); + +sw_error_t +hppe_tx_lpi_tran_cntr_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_lpi_tran_cntr_u *value); + +sw_error_t +hppe_rx_frame_count_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_frame_count_good_bad_low_u *value); + +sw_error_t +hppe_rx_frame_count_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_frame_count_good_bad_low_u *value); + +sw_error_t +hppe_rx_frame_count_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_frame_count_good_bad_high_u *value); + +sw_error_t +hppe_rx_frame_count_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_frame_count_good_bad_high_u *value); + +sw_error_t +hppe_rx_octet_count_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_octet_count_good_bad_low_u *value); + +sw_error_t +hppe_rx_octet_count_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_octet_count_good_bad_low_u *value); + +sw_error_t +hppe_rx_octet_count_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_octet_count_good_bad_high_u *value); + +sw_error_t +hppe_rx_octet_count_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_octet_count_good_bad_high_u *value); + +sw_error_t +hppe_rx_octet_count_good_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_octet_count_good_low_u *value); + +sw_error_t +hppe_rx_octet_count_good_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_octet_count_good_low_u *value); + +sw_error_t +hppe_rx_octet_count_good_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_octet_count_good_high_u *value); + +sw_error_t +hppe_rx_octet_count_good_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_octet_count_good_high_u *value); + +sw_error_t +hppe_rx_broadcast_frames_good_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_broadcast_frames_good_low_u *value); + +sw_error_t +hppe_rx_broadcast_frames_good_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_broadcast_frames_good_low_u *value); + +sw_error_t +hppe_rx_broadcast_frames_good_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_broadcast_frames_good_high_u *value); + +sw_error_t +hppe_rx_broadcast_frames_good_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_broadcast_frames_good_high_u *value); + +sw_error_t +hppe_rx_multicast_frames_good_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_multicast_frames_good_low_u *value); + +sw_error_t +hppe_rx_multicast_frames_good_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_multicast_frames_good_low_u *value); + +sw_error_t +hppe_rx_multicast_frames_good_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_multicast_frames_good_high_u *value); + +sw_error_t +hppe_rx_multicast_frames_good_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_multicast_frames_good_high_u *value); + +sw_error_t +hppe_rx_crc_error_frames_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_crc_error_frames_low_u *value); + +sw_error_t +hppe_rx_crc_error_frames_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_crc_error_frames_low_u *value); + +sw_error_t +hppe_rx_crc_error_frames_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_crc_error_frames_high_u *value); + +sw_error_t +hppe_rx_crc_error_frames_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_crc_error_frames_high_u *value); + +sw_error_t +hppe_rx_runt_error_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_runt_error_frames_u *value); + +sw_error_t +hppe_rx_runt_error_frames_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_runt_error_frames_u *value); + +sw_error_t +hppe_rx_jabber_error_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_jabber_error_frames_u *value); + +sw_error_t +hppe_rx_jabber_error_frames_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_jabber_error_frames_u *value); + +sw_error_t +hppe_rx_undersize_frames_good_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_undersize_frames_good_u *value); + +sw_error_t +hppe_rx_undersize_frames_good_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_undersize_frames_good_u *value); + +sw_error_t +hppe_rx_oversize_frames_good_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_oversize_frames_good_u *value); + +sw_error_t +hppe_rx_oversize_frames_good_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_oversize_frames_good_u *value); + +sw_error_t +hppe_rx_64octets_frames_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_64octets_frames_good_bad_low_u *value); + +sw_error_t +hppe_rx_64octets_frames_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_64octets_frames_good_bad_low_u *value); + +sw_error_t +hppe_rx_64octets_frames_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_64octets_frames_good_bad_high_u *value); + +sw_error_t +hppe_rx_64octets_frames_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_64octets_frames_good_bad_high_u *value); + +sw_error_t +hppe_rx_65to127octets_frames_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_65to127octets_frames_good_bad_low_u *value); + +sw_error_t +hppe_rx_65to127octets_frames_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_65to127octets_frames_good_bad_low_u *value); + +sw_error_t +hppe_rx_65to127octets_frames_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_65to127octets_frames_good_bad_high_u *value); + +sw_error_t +hppe_rx_65to127octets_frames_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_65to127octets_frames_good_bad_high_u *value); + +sw_error_t +hppe_rx_128to255octets_frames_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_128to255octets_frames_good_bad_low_u *value); + +sw_error_t +hppe_rx_128to255octets_frames_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_128to255octets_frames_good_bad_low_u *value); + +sw_error_t +hppe_rx_128to255octets_frames_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_128to255octets_frames_good_bad_high_u *value); + +sw_error_t +hppe_rx_128to255octets_frames_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_128to255octets_frames_good_bad_high_u *value); + +sw_error_t +hppe_rx_256to511octets_frames_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_256to511octets_frames_good_bad_low_u *value); + +sw_error_t +hppe_rx_256to511octets_frames_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_256to511octets_frames_good_bad_low_u *value); + +sw_error_t +hppe_rx_256to511octets_frames_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_256to511octets_frames_good_bad_high_u *value); + +sw_error_t +hppe_rx_256to511octets_frames_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_256to511octets_frames_good_bad_high_u *value); + +sw_error_t +hppe_rx_512to1023octets_frames_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_512to1023octets_frames_good_bad_low_u *value); + +sw_error_t +hppe_rx_512to1023octets_frames_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_512to1023octets_frames_good_bad_low_u *value); + +sw_error_t +hppe_rx_512to1023octets_frames_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_512to1023octets_frames_good_bad_high_u *value); + +sw_error_t +hppe_rx_512to1023octets_frames_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_512to1023octets_frames_good_bad_high_u *value); + +sw_error_t +hppe_rx_1024tomaxoctets_frames_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_1024tomaxoctets_frames_good_bad_low_u *value); + +sw_error_t +hppe_rx_1024tomaxoctets_frames_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_1024tomaxoctets_frames_good_bad_low_u *value); + +sw_error_t +hppe_rx_1024tomaxoctets_frames_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_1024tomaxoctets_frames_good_bad_high_u *value); + +sw_error_t +hppe_rx_1024tomaxoctets_frames_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_1024tomaxoctets_frames_good_bad_high_u *value); + +sw_error_t +hppe_rx_unicast_frames_good_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_unicast_frames_good_low_u *value); + +sw_error_t +hppe_rx_unicast_frames_good_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_unicast_frames_good_low_u *value); + +sw_error_t +hppe_rx_unicast_frames_good_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_unicast_frames_good_high_u *value); + +sw_error_t +hppe_rx_unicast_frames_good_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_unicast_frames_good_high_u *value); + +sw_error_t +hppe_rx_length_error_frames_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_length_error_frames_low_u *value); + +sw_error_t +hppe_rx_length_error_frames_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_length_error_frames_low_u *value); + +sw_error_t +hppe_rx_length_error_frames_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_length_error_frames_high_u *value); + +sw_error_t +hppe_rx_length_error_frames_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_length_error_frames_high_u *value); + +sw_error_t +hppe_rx_outofrange_frames_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_outofrange_frames_low_u *value); + +sw_error_t +hppe_rx_outofrange_frames_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_outofrange_frames_low_u *value); + +sw_error_t +hppe_rx_outofrange_frames_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_outofrange_frames_high_u *value); + +sw_error_t +hppe_rx_outofrange_frames_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_outofrange_frames_high_u *value); + +sw_error_t +hppe_rx_pause_frames_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_pause_frames_low_u *value); + +sw_error_t +hppe_rx_pause_frames_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_pause_frames_low_u *value); + +sw_error_t +hppe_rx_pause_frames_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_pause_frames_high_u *value); + +sw_error_t +hppe_rx_pause_frames_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_pause_frames_high_u *value); + +sw_error_t +hppe_rx_fifooverflow_frames_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_fifooverflow_frames_low_u *value); + +sw_error_t +hppe_rx_fifooverflow_frames_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_fifooverflow_frames_low_u *value); + +sw_error_t +hppe_rx_fifooverflow_frames_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_fifooverflow_frames_high_u *value); + +sw_error_t +hppe_rx_fifooverflow_frames_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_fifooverflow_frames_high_u *value); + +sw_error_t +hppe_rx_vlan_frames_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_vlan_frames_good_bad_low_u *value); + +sw_error_t +hppe_rx_vlan_frames_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_vlan_frames_good_bad_low_u *value); + +sw_error_t +hppe_rx_vlan_frames_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_vlan_frames_good_bad_high_u *value); + +sw_error_t +hppe_rx_vlan_frames_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_vlan_frames_good_bad_high_u *value); + +sw_error_t +hppe_rx_watchdog_error_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_watchdog_error_frames_u *value); + +sw_error_t +hppe_rx_watchdog_error_frames_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_watchdog_error_frames_u *value); + +sw_error_t +hppe_rx_lpi_usec_cntr_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_lpi_usec_cntr_u *value); + +sw_error_t +hppe_rx_lpi_usec_cntr_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_lpi_usec_cntr_u *value); + +sw_error_t +hppe_rx_lpi_tran_cntr_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_lpi_tran_cntr_u *value); + +sw_error_t +hppe_rx_lpi_tran_cntr_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_lpi_tran_cntr_u *value); + +sw_error_t +hppe_rx_discard_frame_count_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_discard_frame_count_good_bad_low_u *value); + +sw_error_t +hppe_rx_discard_frame_count_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_discard_frame_count_good_bad_low_u *value); + +sw_error_t +hppe_rx_discard_frame_count_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_discard_frame_count_good_bad_high_u *value); + +sw_error_t +hppe_rx_discard_frame_count_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_discard_frame_count_good_bad_high_u *value); + +sw_error_t +hppe_rx_discard_octet_count_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_discard_octet_count_good_bad_low_u *value); + +sw_error_t +hppe_rx_discard_octet_count_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_discard_octet_count_good_bad_low_u *value); + +sw_error_t +hppe_rx_discard_octet_count_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_discard_octet_count_good_bad_high_u *value); + +sw_error_t +hppe_rx_discard_octet_count_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_discard_octet_count_good_bad_high_u *value); + + +sw_error_t +hppe_mmc_control_cntrst_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_control_cntrst_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_control_rstonrd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_control_rstonrd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_control_cntstopro_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_control_cntstopro_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_control_mct_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_control_mct_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_control_pr_mmc_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_control_pr_mmc_sel_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_control_cntprst_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_control_cntprst_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_control_mcf_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_control_mcf_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_octet_count_good_bad_low_txoctgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_octet_count_good_bad_low_txoctgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_octet_count_good_bad_high_txoctgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_octet_count_good_bad_high_txoctgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_frame_count_good_bad_low_txfrmgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_frame_count_good_bad_low_txfrmgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_frame_count_good_bad_high_txfrmgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_frame_count_good_bad_high_txfrmgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_broadcast_frames_good_low_txbcastglo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_broadcast_frames_good_low_txbcastglo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_broadcast_frames_good_high_txbcastghi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_broadcast_frames_good_high_txbcastghi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_multicast_frames_good_low_txmcastglo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_multicast_frames_good_low_txmcastglo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_multicast_frames_good_high_txmcastghi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_multicast_frames_good_high_txmcastghi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_64octets_frames_good_bad_low_tx64octgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_64octets_frames_good_bad_low_tx64octgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_64octets_frames_good_bad_high_tx64octgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_64octets_frames_good_bad_high_tx64octgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_65to127octets_frames_good_bad_low_tx65_127octgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_65to127octets_frames_good_bad_low_tx65_127octgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_65to127octets_frames_good_bad_high_tx65_127octgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_65to127octets_frames_good_bad_high_tx65_127octgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_128to255octets_frames_good_bad_low_tx128_255octgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_128to255octets_frames_good_bad_low_tx128_255octgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_128to255octets_frames_good_bad_high_tx128_255octgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_128to255octets_frames_good_bad_high_tx128_255octgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_256to511octets_frames_good_bad_low_tx256_511octgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_256to511octets_frames_good_bad_low_tx256_511octgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_256to511octets_frames_good_bad_high_tx256_511octgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_256to511octets_frames_good_bad_high_tx256_511octgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_512to1023octets_frames_good_bad_low_tx512_1023octgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_512to1023octets_frames_good_bad_low_tx512_1023octgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_512to1023octets_frames_good_bad_high_tx512_1023octgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_512to1023octets_frames_good_bad_high_tx512_1023octgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_1024tomaxoctets_frames_good_bad_low_tx1024_maxoctgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_1024tomaxoctets_frames_good_bad_low_tx1024_maxoctgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_1024tomaxoctets_frames_good_bad_high_tx1024_maxoctgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_1024tomaxoctets_frames_good_bad_high_tx1024_maxoctgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_unicast_frames_good_bad_low_txucastgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_unicast_frames_good_bad_low_txucastgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_unicast_frames_good_bad_high_txucastgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_unicast_frames_good_bad_high_txucastgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_multicast_frames_good_bad_low_txmcastgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_multicast_frames_good_bad_low_txmcastgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_multicast_frames_good_bad_high_txmcastgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_multicast_frames_good_bad_high_txmcastgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_broadcast_frames_good_bad_low_txbcastgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_broadcast_frames_good_bad_low_txbcastgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_broadcast_frames_good_bad_high_txbcastgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_broadcast_frames_good_bad_high_txbcastgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_underflow_error_frames_low_txundrflwlo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_underflow_error_frames_low_txundrflwlo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_underflow_error_frames_high_txundrflwhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_underflow_error_frames_high_txundrflwhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_octet_count_good_low_txoctglo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_octet_count_good_low_txoctglo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_octet_count_good_high_txoctghi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_octet_count_good_high_txoctghi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_frame_count_good_low_txfrmglo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_frame_count_good_low_txfrmglo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_frame_count_good_high_txfrmghi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_frame_count_good_high_txfrmghi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_pause_frames_low_txpauseglo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_pause_frames_low_txpauseglo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_pause_frames_high_txpauseghi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_pause_frames_high_txpauseghi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_vlan_frames_good_low_txvlanglo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_vlan_frames_good_low_txvlanglo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_vlan_frames_good_high_txvlanghi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_vlan_frames_good_high_txvlanghi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_lpi_usec_cntr_txlpiusc_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_lpi_usec_cntr_txlpiusc_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_tx_lpi_tran_cntr_txlpitrc_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_tx_lpi_tran_cntr_txlpitrc_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_frame_count_good_bad_low_rxfrmgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_frame_count_good_bad_low_rxfrmgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_frame_count_good_bad_high_rxfrmgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_frame_count_good_bad_high_rxfrmgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_octet_count_good_bad_low_rxoctgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_octet_count_good_bad_low_rxoctgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_octet_count_good_bad_high_rxoctgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_octet_count_good_bad_high_rxoctgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_octet_count_good_low_rxoctglo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_octet_count_good_low_rxoctglo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_octet_count_good_high_rxoctghi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_octet_count_good_high_rxoctghi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_broadcast_frames_good_low_rxbcastglo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_broadcast_frames_good_low_rxbcastglo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_broadcast_frames_good_high_rxbcastghi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_broadcast_frames_good_high_rxbcastghi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_multicast_frames_good_low_rxmcastglo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_multicast_frames_good_low_rxmcastglo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_multicast_frames_good_high_rxmcastghi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_multicast_frames_good_high_rxmcastghi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_crc_error_frames_low_rxcrcerlo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_crc_error_frames_low_rxcrcerlo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_crc_error_frames_high_rxcrcerhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_crc_error_frames_high_rxcrcerhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_runt_error_frames_rxrunter_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_runt_error_frames_rxrunter_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_jabber_error_frames_rxjaberer_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_jabber_error_frames_rxjaberer_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_undersize_frames_good_rxusizeg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_undersize_frames_good_rxusizeg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_oversize_frames_good_rxosizeg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_oversize_frames_good_rxosizeg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_64octets_frames_good_bad_low_rx64octgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_64octets_frames_good_bad_low_rx64octgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_64octets_frames_good_bad_high_rx64octgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_64octets_frames_good_bad_high_rx64octgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_65to127octets_frames_good_bad_low_rx65_127octgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_65to127octets_frames_good_bad_low_rx65_127octgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_65to127octets_frames_good_bad_high_rx65_127octgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_65to127octets_frames_good_bad_high_rx65_127octgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_128to255octets_frames_good_bad_low_rx128_255octgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_128to255octets_frames_good_bad_low_rx128_255octgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_128to255octets_frames_good_bad_high_rx128_255octgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_128to255octets_frames_good_bad_high_rx128_255octgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_256to511octets_frames_good_bad_low_rx256_511octgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_256to511octets_frames_good_bad_low_rx256_511octgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_256to511octets_frames_good_bad_high_rx256_511octgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_256to511octets_frames_good_bad_high_rx256_511octgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_512to1023octets_frames_good_bad_low_rx512_1023octgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_512to1023octets_frames_good_bad_low_rx512_1023octgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_512to1023octets_frames_good_bad_high_rx512_1023octgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_512to1023octets_frames_good_bad_high_rx512_1023octgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_1024tomaxoctets_frames_good_bad_low_rx1024_maxgboctlo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_1024tomaxoctets_frames_good_bad_low_rx1024_maxgboctlo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_1024tomaxoctets_frames_good_bad_high_rx1024_maxgbocthi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_1024tomaxoctets_frames_good_bad_high_rx1024_maxgbocthi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_unicast_frames_good_low_rxucastglo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_unicast_frames_good_low_rxucastglo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_unicast_frames_good_high_rxucastghi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_unicast_frames_good_high_rxucastghi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_length_error_frames_low_rxlenerrlo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_length_error_frames_low_rxlenerrlo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_length_error_frames_high_rxlenerrhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_length_error_frames_high_rxlenerrhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_outofrange_frames_low_rxorangelo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_outofrange_frames_low_rxorangelo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_outofrange_frames_high_rxorangehi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_outofrange_frames_high_rxorangehi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_pause_frames_low_rxpauselo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_pause_frames_low_rxpauselo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_pause_frames_high_rxpausehi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_pause_frames_high_rxpausehi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_fifooverflow_frames_low_rxfovflo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_fifooverflow_frames_low_rxfovflo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_fifooverflow_frames_high_rxfovfhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_fifooverflow_frames_high_rxfovfhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_vlan_frames_good_bad_low_rxvlangblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_vlan_frames_good_bad_low_rxvlangblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_vlan_frames_good_bad_high_rxvlangbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_vlan_frames_good_bad_high_rxvlangbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_watchdog_error_frames_rxwdogerr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_watchdog_error_frames_rxwdogerr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_lpi_usec_cntr_rxlpiusc_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_lpi_usec_cntr_rxlpiusc_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_lpi_tran_cntr_rxlpitrc_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_lpi_tran_cntr_rxlpitrc_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_discard_frame_count_good_bad_low_rxdfcntgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_discard_frame_count_good_bad_low_rxdfcntgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_discard_frame_count_good_bad_high_rxdfcntgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_discard_frame_count_good_bad_high_rxdfcntgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_discard_octet_count_good_bad_low_rxdocntgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_discard_octet_count_good_bad_low_rxdocntgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_rx_discard_octet_count_good_bad_high_rxdocntgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_rx_discard_octet_count_good_bad_high_rxdocntgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_xgmacmib_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_xgmacmib_reg.h new file mode 100755 index 000000000..8059aeb6d --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_xgmacmib_reg.h @@ -0,0 +1,1956 @@ +/* + * 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 + * @{ + */ +#ifndef HPPE_XGMACMIB_REG_H +#define HPPE_XGMACMIB_REG_H + +/*[register] MMC_CONTROL*/ +#define MMC_CONTROL +#define MMC_CONTROL_ADDRESS 0x800 +#define MMC_CONTROL_NUM 2 +#define MMC_CONTROL_INC 0x4000 +#define MMC_CONTROL_TYPE REG_TYPE_RO +#define MMC_CONTROL_DEFAULT 0x0 + /*[field] CNTRST*/ + #define MMC_CONTROL_CNTRST + #define MMC_CONTROL_CNTRST_OFFSET 0 + #define MMC_CONTROL_CNTRST_LEN 1 + #define MMC_CONTROL_CNTRST_DEFAULT 0x0 + /*[field] CNTSTOPRO*/ + #define MMC_CONTROL_CNTSTOPRO + #define MMC_CONTROL_CNTSTOPRO_OFFSET 1 + #define MMC_CONTROL_CNTSTOPRO_LEN 1 + #define MMC_CONTROL_CNTSTOPRO_DEFAULT 0x0 + /*[field] RSTONRD*/ + #define MMC_CONTROL_RSTONRD + #define MMC_CONTROL_RSTONRD_OFFSET 2 + #define MMC_CONTROL_RSTONRD_LEN 1 + #define MMC_CONTROL_RSTONRD_DEFAULT 0x0 + /*[field] MCF*/ + #define MMC_CONTROL_MCF + #define MMC_CONTROL_MCF_OFFSET 3 + #define MMC_CONTROL_MCF_LEN 1 + #define MMC_CONTROL_MCF_DEFAULT 0x0 + /*[field] MCT*/ + #define MMC_CONTROL_MCT + #define MMC_CONTROL_MCT_OFFSET 4 + #define MMC_CONTROL_MCT_LEN 2 + #define MMC_CONTROL_MCT_DEFAULT 0x0 + /*[field] CNTPRST*/ + #define MMC_CONTROL_CNTPRST + #define MMC_CONTROL_CNTPRST_OFFSET 7 + #define MMC_CONTROL_CNTPRST_LEN 1 + #define MMC_CONTROL_CNTPRST_DEFAULT 0x0 + /*[field] PR_MMC_SEL*/ + #define MMC_CONTROL_PR_MMC_SEL + #define MMC_CONTROL_PR_MMC_SEL_OFFSET 16 + #define MMC_CONTROL_PR_MMC_SEL_LEN 3 + #define MMC_CONTROL_PR_MMC_SEL_DEFAULT 0x0 + +struct mmc_control { + a_uint32_t cntrst:1; + a_uint32_t cntstopro:1; + a_uint32_t rstonrd:1; + a_uint32_t mcf:1; + a_uint32_t mct:2; + a_uint32_t _reserved0:1; + a_uint32_t cntprst:1; + a_uint32_t _reserved1:8; + a_uint32_t pr_mmc_sel:3; + a_uint32_t _reserved2:13; +}; + +union mmc_control_u { + a_uint32_t val; + struct mmc_control bf; +}; + +/*[register] TX_OCTET_COUNT_GOOD_BAD_LOW*/ +#define TX_OCTET_COUNT_GOOD_BAD_LOW +#define TX_OCTET_COUNT_GOOD_BAD_LOW_ADDRESS 0x814 +#define TX_OCTET_COUNT_GOOD_BAD_LOW_NUM 2 +#define TX_OCTET_COUNT_GOOD_BAD_LOW_INC 0x4000 +#define TX_OCTET_COUNT_GOOD_BAD_LOW_TYPE REG_TYPE_RO +#define TX_OCTET_COUNT_GOOD_BAD_LOW_DEFAULT 0x0 + /*[field] TXOCTGBLO*/ + #define TX_OCTET_COUNT_GOOD_BAD_LOW_TXOCTGBLO + #define TX_OCTET_COUNT_GOOD_BAD_LOW_TXOCTGBLO_OFFSET 0 + #define TX_OCTET_COUNT_GOOD_BAD_LOW_TXOCTGBLO_LEN 32 + #define TX_OCTET_COUNT_GOOD_BAD_LOW_TXOCTGBLO_DEFAULT 0x0 + +struct tx_octet_count_good_bad_low { + a_uint32_t txoctgblo:32; +}; + +union tx_octet_count_good_bad_low_u { + a_uint32_t val; + struct tx_octet_count_good_bad_low bf; +}; + +/*[register] TX_OCTET_COUNT_GOOD_BAD_HIGH*/ +#define TX_OCTET_COUNT_GOOD_BAD_HIGH +#define TX_OCTET_COUNT_GOOD_BAD_HIGH_ADDRESS 0x818 +#define TX_OCTET_COUNT_GOOD_BAD_HIGH_NUM 2 +#define TX_OCTET_COUNT_GOOD_BAD_HIGH_INC 0x4000 +#define TX_OCTET_COUNT_GOOD_BAD_HIGH_TYPE REG_TYPE_RO +#define TX_OCTET_COUNT_GOOD_BAD_HIGH_DEFAULT 0x0 + /*[field] TXOCTGBHI*/ + #define TX_OCTET_COUNT_GOOD_BAD_HIGH_TXOCTGBHI + #define TX_OCTET_COUNT_GOOD_BAD_HIGH_TXOCTGBHI_OFFSET 0 + #define TX_OCTET_COUNT_GOOD_BAD_HIGH_TXOCTGBHI_LEN 32 + #define TX_OCTET_COUNT_GOOD_BAD_HIGH_TXOCTGBHI_DEFAULT 0x0 + +struct tx_octet_count_good_bad_high { + a_uint32_t txoctgbhi:32; +}; + +union tx_octet_count_good_bad_high_u { + a_uint32_t val; + struct tx_octet_count_good_bad_high bf; +}; + +/*[register] TX_FRAME_COUNT_GOOD_BAD_LOW*/ +#define TX_FRAME_COUNT_GOOD_BAD_LOW +#define TX_FRAME_COUNT_GOOD_BAD_LOW_ADDRESS 0x81c +#define TX_FRAME_COUNT_GOOD_BAD_LOW_NUM 2 +#define TX_FRAME_COUNT_GOOD_BAD_LOW_INC 0x4000 +#define TX_FRAME_COUNT_GOOD_BAD_LOW_TYPE REG_TYPE_RO +#define TX_FRAME_COUNT_GOOD_BAD_LOW_DEFAULT 0x0 + /*[field] TXFRMGBLO*/ + #define TX_FRAME_COUNT_GOOD_BAD_LOW_TXFRMGBLO + #define TX_FRAME_COUNT_GOOD_BAD_LOW_TXFRMGBLO_OFFSET 0 + #define TX_FRAME_COUNT_GOOD_BAD_LOW_TXFRMGBLO_LEN 32 + #define TX_FRAME_COUNT_GOOD_BAD_LOW_TXFRMGBLO_DEFAULT 0x0 + +struct tx_frame_count_good_bad_low { + a_uint32_t txfrmgblo:32; +}; + +union tx_frame_count_good_bad_low_u { + a_uint32_t val; + struct tx_frame_count_good_bad_low bf; +}; + +/*[register] TX_FRAME_COUNT_GOOD_BAD_HIGH*/ +#define TX_FRAME_COUNT_GOOD_BAD_HIGH +#define TX_FRAME_COUNT_GOOD_BAD_HIGH_ADDRESS 0x820 +#define TX_FRAME_COUNT_GOOD_BAD_HIGH_NUM 2 +#define TX_FRAME_COUNT_GOOD_BAD_HIGH_INC 0x4000 +#define TX_FRAME_COUNT_GOOD_BAD_HIGH_TYPE REG_TYPE_RO +#define TX_FRAME_COUNT_GOOD_BAD_HIGH_DEFAULT 0x0 + /*[field] TXFRMGBHI*/ + #define TX_FRAME_COUNT_GOOD_BAD_HIGH_TXFRMGBHI + #define TX_FRAME_COUNT_GOOD_BAD_HIGH_TXFRMGBHI_OFFSET 0 + #define TX_FRAME_COUNT_GOOD_BAD_HIGH_TXFRMGBHI_LEN 32 + #define TX_FRAME_COUNT_GOOD_BAD_HIGH_TXFRMGBHI_DEFAULT 0x0 + +struct tx_frame_count_good_bad_high { + a_uint32_t txfrmgbhi:32; +}; + +union tx_frame_count_good_bad_high_u { + a_uint32_t val; + struct tx_frame_count_good_bad_high bf; +}; + +/*[register] TX_BROADCAST_FRAMES_GOOD_LOW*/ +#define TX_BROADCAST_FRAMES_GOOD_LOW +#define TX_BROADCAST_FRAMES_GOOD_LOW_ADDRESS 0x824 +#define TX_BROADCAST_FRAMES_GOOD_LOW_NUM 2 +#define TX_BROADCAST_FRAMES_GOOD_LOW_INC 0x4000 +#define TX_BROADCAST_FRAMES_GOOD_LOW_TYPE REG_TYPE_RO +#define TX_BROADCAST_FRAMES_GOOD_LOW_DEFAULT 0x0 + /*[field] TXBCASTGLO*/ + #define TX_BROADCAST_FRAMES_GOOD_LOW_TXBCASTGLO + #define TX_BROADCAST_FRAMES_GOOD_LOW_TXBCASTGLO_OFFSET 0 + #define TX_BROADCAST_FRAMES_GOOD_LOW_TXBCASTGLO_LEN 32 + #define TX_BROADCAST_FRAMES_GOOD_LOW_TXBCASTGLO_DEFAULT 0x0 + +struct tx_broadcast_frames_good_low { + a_uint32_t txbcastglo:32; +}; + +union tx_broadcast_frames_good_low_u { + a_uint32_t val; + struct tx_broadcast_frames_good_low bf; +}; + +/*[register] TX_BROADCAST_FRAMES_GOOD_HIGH*/ +#define TX_BROADCAST_FRAMES_GOOD_HIGH +#define TX_BROADCAST_FRAMES_GOOD_HIGH_ADDRESS 0x828 +#define TX_BROADCAST_FRAMES_GOOD_HIGH_NUM 2 +#define TX_BROADCAST_FRAMES_GOOD_HIGH_INC 0x4000 +#define TX_BROADCAST_FRAMES_GOOD_HIGH_TYPE REG_TYPE_RO +#define TX_BROADCAST_FRAMES_GOOD_HIGH_DEFAULT 0x0 + /*[field] TXBCASTGHI*/ + #define TX_BROADCAST_FRAMES_GOOD_HIGH_TXBCASTGHI + #define TX_BROADCAST_FRAMES_GOOD_HIGH_TXBCASTGHI_OFFSET 0 + #define TX_BROADCAST_FRAMES_GOOD_HIGH_TXBCASTGHI_LEN 32 + #define TX_BROADCAST_FRAMES_GOOD_HIGH_TXBCASTGHI_DEFAULT 0x0 + +struct tx_broadcast_frames_good_high { + a_uint32_t txbcastghi:32; +}; + +union tx_broadcast_frames_good_high_u { + a_uint32_t val; + struct tx_broadcast_frames_good_high bf; +}; + +/*[register] TX_MULTICAST_FRAMES_GOOD_LOW*/ +#define TX_MULTICAST_FRAMES_GOOD_LOW +#define TX_MULTICAST_FRAMES_GOOD_LOW_ADDRESS 0x82c +#define TX_MULTICAST_FRAMES_GOOD_LOW_NUM 2 +#define TX_MULTICAST_FRAMES_GOOD_LOW_INC 0x4000 +#define TX_MULTICAST_FRAMES_GOOD_LOW_TYPE REG_TYPE_RO +#define TX_MULTICAST_FRAMES_GOOD_LOW_DEFAULT 0x0 + /*[field] TXMCASTGLO*/ + #define TX_MULTICAST_FRAMES_GOOD_LOW_TXMCASTGLO + #define TX_MULTICAST_FRAMES_GOOD_LOW_TXMCASTGLO_OFFSET 0 + #define TX_MULTICAST_FRAMES_GOOD_LOW_TXMCASTGLO_LEN 32 + #define TX_MULTICAST_FRAMES_GOOD_LOW_TXMCASTGLO_DEFAULT 0x0 + +struct tx_multicast_frames_good_low { + a_uint32_t txmcastglo:32; +}; + +union tx_multicast_frames_good_low_u { + a_uint32_t val; + struct tx_multicast_frames_good_low bf; +}; + +/*[register] TX_MULTICAST_FRAMES_GOOD_HIGH*/ +#define TX_MULTICAST_FRAMES_GOOD_HIGH +#define TX_MULTICAST_FRAMES_GOOD_HIGH_ADDRESS 0x830 +#define TX_MULTICAST_FRAMES_GOOD_HIGH_NUM 2 +#define TX_MULTICAST_FRAMES_GOOD_HIGH_INC 0x4000 +#define TX_MULTICAST_FRAMES_GOOD_HIGH_TYPE REG_TYPE_RO +#define TX_MULTICAST_FRAMES_GOOD_HIGH_DEFAULT 0x0 + /*[field] TXMCASTGHI*/ + #define TX_MULTICAST_FRAMES_GOOD_HIGH_TXMCASTGHI + #define TX_MULTICAST_FRAMES_GOOD_HIGH_TXMCASTGHI_OFFSET 0 + #define TX_MULTICAST_FRAMES_GOOD_HIGH_TXMCASTGHI_LEN 32 + #define TX_MULTICAST_FRAMES_GOOD_HIGH_TXMCASTGHI_DEFAULT 0x0 + +struct tx_multicast_frames_good_high { + a_uint32_t txmcastghi:32; +}; + +union tx_multicast_frames_good_high_u { + a_uint32_t val; + struct tx_multicast_frames_good_high bf; +}; + +/*[register] TX_64OCTETS_FRAMES_GOOD_BAD_LOW*/ +#define TX_64OCTETS_FRAMES_GOOD_BAD_LOW +#define TX_64OCTETS_FRAMES_GOOD_BAD_LOW_ADDRESS 0x834 +#define TX_64OCTETS_FRAMES_GOOD_BAD_LOW_NUM 2 +#define TX_64OCTETS_FRAMES_GOOD_BAD_LOW_INC 0x4000 +#define TX_64OCTETS_FRAMES_GOOD_BAD_LOW_TYPE REG_TYPE_RO +#define TX_64OCTETS_FRAMES_GOOD_BAD_LOW_DEFAULT 0x0 + /*[field] TX64OCTGBLO*/ + #define TX_64OCTETS_FRAMES_GOOD_BAD_LOW_TX64OCTGBLO + #define TX_64OCTETS_FRAMES_GOOD_BAD_LOW_TX64OCTGBLO_OFFSET 0 + #define TX_64OCTETS_FRAMES_GOOD_BAD_LOW_TX64OCTGBLO_LEN 32 + #define TX_64OCTETS_FRAMES_GOOD_BAD_LOW_TX64OCTGBLO_DEFAULT 0x0 + +struct tx_64octets_frames_good_bad_low { + a_uint32_t tx64octgblo:32; +}; + +union tx_64octets_frames_good_bad_low_u { + a_uint32_t val; + struct tx_64octets_frames_good_bad_low bf; +}; + +/*[register] TX_64OCTETS_FRAMES_GOOD_BAD_HIGH*/ +#define TX_64OCTETS_FRAMES_GOOD_BAD_HIGH +#define TX_64OCTETS_FRAMES_GOOD_BAD_HIGH_ADDRESS 0x838 +#define TX_64OCTETS_FRAMES_GOOD_BAD_HIGH_NUM 2 +#define TX_64OCTETS_FRAMES_GOOD_BAD_HIGH_INC 0x4000 +#define TX_64OCTETS_FRAMES_GOOD_BAD_HIGH_TYPE REG_TYPE_RO +#define TX_64OCTETS_FRAMES_GOOD_BAD_HIGH_DEFAULT 0x0 + /*[field] TX64OCTGBHI*/ + #define TX_64OCTETS_FRAMES_GOOD_BAD_HIGH_TX64OCTGBHI + #define TX_64OCTETS_FRAMES_GOOD_BAD_HIGH_TX64OCTGBHI_OFFSET 0 + #define TX_64OCTETS_FRAMES_GOOD_BAD_HIGH_TX64OCTGBHI_LEN 32 + #define TX_64OCTETS_FRAMES_GOOD_BAD_HIGH_TX64OCTGBHI_DEFAULT 0x0 + +struct tx_64octets_frames_good_bad_high { + a_uint32_t tx64octgbhi:32; +}; + +union tx_64octets_frames_good_bad_high_u { + a_uint32_t val; + struct tx_64octets_frames_good_bad_high bf; +}; + +/*[register] TX_65TO127OCTETS_FRAMES_GOOD_BAD_LOW*/ +#define TX_65TO127OCTETS_FRAMES_GOOD_BAD_LOW +#define TX_65TO127OCTETS_FRAMES_GOOD_BAD_LOW_ADDRESS 0x83c +#define TX_65TO127OCTETS_FRAMES_GOOD_BAD_LOW_NUM 2 +#define TX_65TO127OCTETS_FRAMES_GOOD_BAD_LOW_INC 0x4000 +#define TX_65TO127OCTETS_FRAMES_GOOD_BAD_LOW_TYPE REG_TYPE_RO +#define TX_65TO127OCTETS_FRAMES_GOOD_BAD_LOW_DEFAULT 0x0 + /*[field] TX65_127OCTGBLO*/ + #define TX_65TO127OCTETS_FRAMES_GOOD_BAD_LOW_TX65_127OCTGBLO + #define TX_65TO127OCTETS_FRAMES_GOOD_BAD_LOW_TX65_127OCTGBLO_OFFSET 0 + #define TX_65TO127OCTETS_FRAMES_GOOD_BAD_LOW_TX65_127OCTGBLO_LEN 32 + #define TX_65TO127OCTETS_FRAMES_GOOD_BAD_LOW_TX65_127OCTGBLO_DEFAULT 0x0 + +struct tx_65to127octets_frames_good_bad_low { + a_uint32_t tx65_127octgblo:32; +}; + +union tx_65to127octets_frames_good_bad_low_u { + a_uint32_t val; + struct tx_65to127octets_frames_good_bad_low bf; +}; + +/*[register] TX_65TO127OCTETS_FRAMES_GOOD_BAD_HIGH*/ +#define TX_65TO127OCTETS_FRAMES_GOOD_BAD_HIGH +#define TX_65TO127OCTETS_FRAMES_GOOD_BAD_HIGH_ADDRESS 0x840 +#define TX_65TO127OCTETS_FRAMES_GOOD_BAD_HIGH_NUM 2 +#define TX_65TO127OCTETS_FRAMES_GOOD_BAD_HIGH_INC 0x4000 +#define TX_65TO127OCTETS_FRAMES_GOOD_BAD_HIGH_TYPE REG_TYPE_RO +#define TX_65TO127OCTETS_FRAMES_GOOD_BAD_HIGH_DEFAULT 0x0 + /*[field] TX65_127OCTGBHI*/ + #define TX_65TO127OCTETS_FRAMES_GOOD_BAD_HIGH_TX65_127OCTGBHI + #define TX_65TO127OCTETS_FRAMES_GOOD_BAD_HIGH_TX65_127OCTGBHI_OFFSET 0 + #define TX_65TO127OCTETS_FRAMES_GOOD_BAD_HIGH_TX65_127OCTGBHI_LEN 32 + #define TX_65TO127OCTETS_FRAMES_GOOD_BAD_HIGH_TX65_127OCTGBHI_DEFAULT 0x0 + +struct tx_65to127octets_frames_good_bad_high { + a_uint32_t tx65_127octgbhi:32; +}; + +union tx_65to127octets_frames_good_bad_high_u { + a_uint32_t val; + struct tx_65to127octets_frames_good_bad_high bf; +}; + +/*[register] TX_128TO255OCTETS_FRAMES_GOOD_BAD_LOW*/ +#define TX_128TO255OCTETS_FRAMES_GOOD_BAD_LOW +#define TX_128TO255OCTETS_FRAMES_GOOD_BAD_LOW_ADDRESS 0x844 +#define TX_128TO255OCTETS_FRAMES_GOOD_BAD_LOW_NUM 2 +#define TX_128TO255OCTETS_FRAMES_GOOD_BAD_LOW_INC 0x4000 +#define TX_128TO255OCTETS_FRAMES_GOOD_BAD_LOW_TYPE REG_TYPE_RO +#define TX_128TO255OCTETS_FRAMES_GOOD_BAD_LOW_DEFAULT 0x0 + /*[field] TX128_255OCTGBLO*/ + #define TX_128TO255OCTETS_FRAMES_GOOD_BAD_LOW_TX128_255OCTGBLO + #define TX_128TO255OCTETS_FRAMES_GOOD_BAD_LOW_TX128_255OCTGBLO_OFFSET 0 + #define TX_128TO255OCTETS_FRAMES_GOOD_BAD_LOW_TX128_255OCTGBLO_LEN 32 + #define TX_128TO255OCTETS_FRAMES_GOOD_BAD_LOW_TX128_255OCTGBLO_DEFAULT 0x0 + +struct tx_128to255octets_frames_good_bad_low { + a_uint32_t tx128_255octgblo:32; +}; + +union tx_128to255octets_frames_good_bad_low_u { + a_uint32_t val; + struct tx_128to255octets_frames_good_bad_low bf; +}; + +/*[register] TX_128TO255OCTETS_FRAMES_GOOD_BAD_HIGH*/ +#define TX_128TO255OCTETS_FRAMES_GOOD_BAD_HIGH +#define TX_128TO255OCTETS_FRAMES_GOOD_BAD_HIGH_ADDRESS 0x848 +#define TX_128TO255OCTETS_FRAMES_GOOD_BAD_HIGH_NUM 2 +#define TX_128TO255OCTETS_FRAMES_GOOD_BAD_HIGH_INC 0x4000 +#define TX_128TO255OCTETS_FRAMES_GOOD_BAD_HIGH_TYPE REG_TYPE_RO +#define TX_128TO255OCTETS_FRAMES_GOOD_BAD_HIGH_DEFAULT 0x0 + /*[field] TX128_255OCTGBHI*/ + #define TX_128TO255OCTETS_FRAMES_GOOD_BAD_HIGH_TX128_255OCTGBHI + #define TX_128TO255OCTETS_FRAMES_GOOD_BAD_HIGH_TX128_255OCTGBHI_OFFSET 0 + #define TX_128TO255OCTETS_FRAMES_GOOD_BAD_HIGH_TX128_255OCTGBHI_LEN 32 + #define TX_128TO255OCTETS_FRAMES_GOOD_BAD_HIGH_TX128_255OCTGBHI_DEFAULT 0x0 + +struct tx_128to255octets_frames_good_bad_high { + a_uint32_t tx128_255octgbhi:32; +}; + +union tx_128to255octets_frames_good_bad_high_u { + a_uint32_t val; + struct tx_128to255octets_frames_good_bad_high bf; +}; + +/*[register] TX_256TO511OCTETS_FRAMES_GOOD_BAD_LOW*/ +#define TX_256TO511OCTETS_FRAMES_GOOD_BAD_LOW +#define TX_256TO511OCTETS_FRAMES_GOOD_BAD_LOW_ADDRESS 0x84c +#define TX_256TO511OCTETS_FRAMES_GOOD_BAD_LOW_NUM 1 +#define TX_256TO511OCTETS_FRAMES_GOOD_BAD_LOW_INC 0x4000 +#define TX_256TO511OCTETS_FRAMES_GOOD_BAD_LOW_TYPE REG_TYPE_RO +#define TX_256TO511OCTETS_FRAMES_GOOD_BAD_LOW_DEFAULT 0x0 + /*[field] TX256_511OCTGBLO*/ + #define TX_256TO511OCTETS_FRAMES_GOOD_BAD_LOW_TX256_511OCTGBLO + #define TX_256TO511OCTETS_FRAMES_GOOD_BAD_LOW_TX256_511OCTGBLO_OFFSET 0 + #define TX_256TO511OCTETS_FRAMES_GOOD_BAD_LOW_TX256_511OCTGBLO_LEN 32 + #define TX_256TO511OCTETS_FRAMES_GOOD_BAD_LOW_TX256_511OCTGBLO_DEFAULT 0x0 + +struct tx_256to511octets_frames_good_bad_low { + a_uint32_t tx256_511octgblo:32; +}; + +union tx_256to511octets_frames_good_bad_low_u { + a_uint32_t val; + struct tx_256to511octets_frames_good_bad_low bf; +}; + +/*[register] TX_256TO511OCTETS_FRAMES_GOOD_BAD_HIGH*/ +#define TX_256TO511OCTETS_FRAMES_GOOD_BAD_HIGH +#define TX_256TO511OCTETS_FRAMES_GOOD_BAD_HIGH_ADDRESS 0x850 +#define TX_256TO511OCTETS_FRAMES_GOOD_BAD_HIGH_NUM 1 +#define TX_256TO511OCTETS_FRAMES_GOOD_BAD_HIGH_INC 0x4000 +#define TX_256TO511OCTETS_FRAMES_GOOD_BAD_HIGH_TYPE REG_TYPE_RO +#define TX_256TO511OCTETS_FRAMES_GOOD_BAD_HIGH_DEFAULT 0x0 + /*[field] TX256_511OCTGBHI*/ + #define TX_256TO511OCTETS_FRAMES_GOOD_BAD_HIGH_TX256_511OCTGBHI + #define TX_256TO511OCTETS_FRAMES_GOOD_BAD_HIGH_TX256_511OCTGBHI_OFFSET 0 + #define TX_256TO511OCTETS_FRAMES_GOOD_BAD_HIGH_TX256_511OCTGBHI_LEN 32 + #define TX_256TO511OCTETS_FRAMES_GOOD_BAD_HIGH_TX256_511OCTGBHI_DEFAULT 0x0 + +struct tx_256to511octets_frames_good_bad_high { + a_uint32_t tx256_511octgbhi:32; +}; + +union tx_256to511octets_frames_good_bad_high_u { + a_uint32_t val; + struct tx_256to511octets_frames_good_bad_high bf; +}; + +/*[register] TX_512TO1023OCTETS_FRAMES_GOOD_BAD_LOW*/ +#define TX_512TO1023OCTETS_FRAMES_GOOD_BAD_LOW +#define TX_512TO1023OCTETS_FRAMES_GOOD_BAD_LOW_ADDRESS 0x854 +#define TX_512TO1023OCTETS_FRAMES_GOOD_BAD_LOW_NUM 1 +#define TX_512TO1023OCTETS_FRAMES_GOOD_BAD_LOW_INC 0x4000 +#define TX_512TO1023OCTETS_FRAMES_GOOD_BAD_LOW_TYPE REG_TYPE_RO +#define TX_512TO1023OCTETS_FRAMES_GOOD_BAD_LOW_DEFAULT 0x0 + /*[field] TX512_1023OCTGBLO*/ + #define TX_512TO1023OCTETS_FRAMES_GOOD_BAD_LOW_TX512_1023OCTGBLO + #define TX_512TO1023OCTETS_FRAMES_GOOD_BAD_LOW_TX512_1023OCTGBLO_OFFSET 0 + #define TX_512TO1023OCTETS_FRAMES_GOOD_BAD_LOW_TX512_1023OCTGBLO_LEN 32 + #define TX_512TO1023OCTETS_FRAMES_GOOD_BAD_LOW_TX512_1023OCTGBLO_DEFAULT 0x0 + +struct tx_512to1023octets_frames_good_bad_low { + a_uint32_t tx512_1023octgblo:32; +}; + +union tx_512to1023octets_frames_good_bad_low_u { + a_uint32_t val; + struct tx_512to1023octets_frames_good_bad_low bf; +}; + +/*[register] TX_512TO1023OCTETS_FRAMES_GOOD_BAD_HIGH*/ +#define TX_512TO1023OCTETS_FRAMES_GOOD_BAD_HIGH +#define TX_512TO1023OCTETS_FRAMES_GOOD_BAD_HIGH_ADDRESS 0x858 +#define TX_512TO1023OCTETS_FRAMES_GOOD_BAD_HIGH_NUM 1 +#define TX_512TO1023OCTETS_FRAMES_GOOD_BAD_HIGH_INC 0x4000 +#define TX_512TO1023OCTETS_FRAMES_GOOD_BAD_HIGH_TYPE REG_TYPE_RO +#define TX_512TO1023OCTETS_FRAMES_GOOD_BAD_HIGH_DEFAULT 0x0 + /*[field] TX512_1023OCTGBHI*/ + #define TX_512TO1023OCTETS_FRAMES_GOOD_BAD_HIGH_TX512_1023OCTGBHI + #define TX_512TO1023OCTETS_FRAMES_GOOD_BAD_HIGH_TX512_1023OCTGBHI_OFFSET 0 + #define TX_512TO1023OCTETS_FRAMES_GOOD_BAD_HIGH_TX512_1023OCTGBHI_LEN 32 + #define TX_512TO1023OCTETS_FRAMES_GOOD_BAD_HIGH_TX512_1023OCTGBHI_DEFAULT 0x0 + +struct tx_512to1023octets_frames_good_bad_high { + a_uint32_t tx512_1023octgbhi:32; +}; + +union tx_512to1023octets_frames_good_bad_high_u { + a_uint32_t val; + struct tx_512to1023octets_frames_good_bad_high bf; +}; + +/*[register] TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_LOW*/ +#define TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_LOW +#define TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_LOW_ADDRESS 0x85c +#define TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_LOW_NUM 1 +#define TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_LOW_INC 0x4000 +#define TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_LOW_TYPE REG_TYPE_RO +#define TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_LOW_DEFAULT 0x0 + /*[field] TX1024_MAXOCTGBLO*/ + #define TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_LOW_TX1024_MAXOCTGBLO + #define TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_LOW_TX1024_MAXOCTGBLO_OFFSET 0 + #define TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_LOW_TX1024_MAXOCTGBLO_LEN 32 + #define TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_LOW_TX1024_MAXOCTGBLO_DEFAULT 0x0 + +struct tx_1024tomaxoctets_frames_good_bad_low { + a_uint32_t tx1024_maxoctgblo:32; +}; + +union tx_1024tomaxoctets_frames_good_bad_low_u { + a_uint32_t val; + struct tx_1024tomaxoctets_frames_good_bad_low bf; +}; + +/*[register] TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_HIGH*/ +#define TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_HIGH +#define TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_HIGH_ADDRESS 0x860 +#define TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_HIGH_NUM 1 +#define TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_HIGH_INC 0x4000 +#define TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_HIGH_TYPE REG_TYPE_RO +#define TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_HIGH_DEFAULT 0x0 + /*[field] TX1024_MAXOCTGBHI*/ + #define TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_HIGH_TX1024_MAXOCTGBHI + #define TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_HIGH_TX1024_MAXOCTGBHI_OFFSET 0 + #define TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_HIGH_TX1024_MAXOCTGBHI_LEN 32 + #define TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_HIGH_TX1024_MAXOCTGBHI_DEFAULT 0x0 + +struct tx_1024tomaxoctets_frames_good_bad_high { + a_uint32_t tx1024_maxoctgbhi:32; +}; + +union tx_1024tomaxoctets_frames_good_bad_high_u { + a_uint32_t val; + struct tx_1024tomaxoctets_frames_good_bad_high bf; +}; + +/*[register] TX_UNICAST_FRAMES_GOOD_BAD_LOW*/ +#define TX_UNICAST_FRAMES_GOOD_BAD_LOW +#define TX_UNICAST_FRAMES_GOOD_BAD_LOW_ADDRESS 0x864 +#define TX_UNICAST_FRAMES_GOOD_BAD_LOW_NUM 1 +#define TX_UNICAST_FRAMES_GOOD_BAD_LOW_INC 0x4000 +#define TX_UNICAST_FRAMES_GOOD_BAD_LOW_TYPE REG_TYPE_RO +#define TX_UNICAST_FRAMES_GOOD_BAD_LOW_DEFAULT 0x0 + /*[field] TXUCASTGBLO*/ + #define TX_UNICAST_FRAMES_GOOD_BAD_LOW_TXUCASTGBLO + #define TX_UNICAST_FRAMES_GOOD_BAD_LOW_TXUCASTGBLO_OFFSET 0 + #define TX_UNICAST_FRAMES_GOOD_BAD_LOW_TXUCASTGBLO_LEN 32 + #define TX_UNICAST_FRAMES_GOOD_BAD_LOW_TXUCASTGBLO_DEFAULT 0x0 + +struct tx_unicast_frames_good_bad_low { + a_uint32_t txucastgblo:32; +}; + +union tx_unicast_frames_good_bad_low_u { + a_uint32_t val; + struct tx_unicast_frames_good_bad_low bf; +}; + +/*[register] TX_UNICAST_FRAMES_GOOD_BAD_HIGH*/ +#define TX_UNICAST_FRAMES_GOOD_BAD_HIGH +#define TX_UNICAST_FRAMES_GOOD_BAD_HIGH_ADDRESS 0x868 +#define TX_UNICAST_FRAMES_GOOD_BAD_HIGH_NUM 1 +#define TX_UNICAST_FRAMES_GOOD_BAD_HIGH_INC 0x4000 +#define TX_UNICAST_FRAMES_GOOD_BAD_HIGH_TYPE REG_TYPE_RO +#define TX_UNICAST_FRAMES_GOOD_BAD_HIGH_DEFAULT 0x0 + /*[field] TXUCASTGBHI*/ + #define TX_UNICAST_FRAMES_GOOD_BAD_HIGH_TXUCASTGBHI + #define TX_UNICAST_FRAMES_GOOD_BAD_HIGH_TXUCASTGBHI_OFFSET 0 + #define TX_UNICAST_FRAMES_GOOD_BAD_HIGH_TXUCASTGBHI_LEN 32 + #define TX_UNICAST_FRAMES_GOOD_BAD_HIGH_TXUCASTGBHI_DEFAULT 0x0 + +struct tx_unicast_frames_good_bad_high { + a_uint32_t txucastgbhi:32; +}; + +union tx_unicast_frames_good_bad_high_u { + a_uint32_t val; + struct tx_unicast_frames_good_bad_high bf; +}; + +/*[register] TX_MULTICAST_FRAMES_GOOD_BAD_LOW*/ +#define TX_MULTICAST_FRAMES_GOOD_BAD_LOW +#define TX_MULTICAST_FRAMES_GOOD_BAD_LOW_ADDRESS 0x86c +#define TX_MULTICAST_FRAMES_GOOD_BAD_LOW_NUM 1 +#define TX_MULTICAST_FRAMES_GOOD_BAD_LOW_INC 0x4000 +#define TX_MULTICAST_FRAMES_GOOD_BAD_LOW_TYPE REG_TYPE_RO +#define TX_MULTICAST_FRAMES_GOOD_BAD_LOW_DEFAULT 0x0 + /*[field] TXMCASTGBLO*/ + #define TX_MULTICAST_FRAMES_GOOD_BAD_LOW_TXMCASTGBLO + #define TX_MULTICAST_FRAMES_GOOD_BAD_LOW_TXMCASTGBLO_OFFSET 0 + #define TX_MULTICAST_FRAMES_GOOD_BAD_LOW_TXMCASTGBLO_LEN 32 + #define TX_MULTICAST_FRAMES_GOOD_BAD_LOW_TXMCASTGBLO_DEFAULT 0x0 + +struct tx_multicast_frames_good_bad_low { + a_uint32_t txmcastgblo:32; +}; + +union tx_multicast_frames_good_bad_low_u { + a_uint32_t val; + struct tx_multicast_frames_good_bad_low bf; +}; + +/*[register] TX_MULTICAST_FRAMES_GOOD_BAD_HIGH*/ +#define TX_MULTICAST_FRAMES_GOOD_BAD_HIGH +#define TX_MULTICAST_FRAMES_GOOD_BAD_HIGH_ADDRESS 0x870 +#define TX_MULTICAST_FRAMES_GOOD_BAD_HIGH_NUM 1 +#define TX_MULTICAST_FRAMES_GOOD_BAD_HIGH_INC 0x4000 +#define TX_MULTICAST_FRAMES_GOOD_BAD_HIGH_TYPE REG_TYPE_RO +#define TX_MULTICAST_FRAMES_GOOD_BAD_HIGH_DEFAULT 0x0 + /*[field] TXMCASTGBHI*/ + #define TX_MULTICAST_FRAMES_GOOD_BAD_HIGH_TXMCASTGBHI + #define TX_MULTICAST_FRAMES_GOOD_BAD_HIGH_TXMCASTGBHI_OFFSET 0 + #define TX_MULTICAST_FRAMES_GOOD_BAD_HIGH_TXMCASTGBHI_LEN 32 + #define TX_MULTICAST_FRAMES_GOOD_BAD_HIGH_TXMCASTGBHI_DEFAULT 0x0 + +struct tx_multicast_frames_good_bad_high { + a_uint32_t txmcastgbhi:32; +}; + +union tx_multicast_frames_good_bad_high_u { + a_uint32_t val; + struct tx_multicast_frames_good_bad_high bf; +}; + +/*[register] TX_BROADCAST_FRAMES_GOOD_BAD_LOW*/ +#define TX_BROADCAST_FRAMES_GOOD_BAD_LOW +#define TX_BROADCAST_FRAMES_GOOD_BAD_LOW_ADDRESS 0x874 +#define TX_BROADCAST_FRAMES_GOOD_BAD_LOW_NUM 1 +#define TX_BROADCAST_FRAMES_GOOD_BAD_LOW_INC 0x4000 +#define TX_BROADCAST_FRAMES_GOOD_BAD_LOW_TYPE REG_TYPE_RO +#define TX_BROADCAST_FRAMES_GOOD_BAD_LOW_DEFAULT 0x0 + /*[field] TXBCASTGBLO*/ + #define TX_BROADCAST_FRAMES_GOOD_BAD_LOW_TXBCASTGBLO + #define TX_BROADCAST_FRAMES_GOOD_BAD_LOW_TXBCASTGBLO_OFFSET 0 + #define TX_BROADCAST_FRAMES_GOOD_BAD_LOW_TXBCASTGBLO_LEN 32 + #define TX_BROADCAST_FRAMES_GOOD_BAD_LOW_TXBCASTGBLO_DEFAULT 0x0 + +struct tx_broadcast_frames_good_bad_low { + a_uint32_t txbcastgblo:32; +}; + +union tx_broadcast_frames_good_bad_low_u { + a_uint32_t val; + struct tx_broadcast_frames_good_bad_low bf; +}; + +/*[register] TX_BROADCAST_FRAMES_GOOD_BAD_HIGH*/ +#define TX_BROADCAST_FRAMES_GOOD_BAD_HIGH +#define TX_BROADCAST_FRAMES_GOOD_BAD_HIGH_ADDRESS 0x878 +#define TX_BROADCAST_FRAMES_GOOD_BAD_HIGH_NUM 1 +#define TX_BROADCAST_FRAMES_GOOD_BAD_HIGH_INC 0x4000 +#define TX_BROADCAST_FRAMES_GOOD_BAD_HIGH_TYPE REG_TYPE_RO +#define TX_BROADCAST_FRAMES_GOOD_BAD_HIGH_DEFAULT 0x0 + /*[field] TXBCASTGBHI*/ + #define TX_BROADCAST_FRAMES_GOOD_BAD_HIGH_TXBCASTGBHI + #define TX_BROADCAST_FRAMES_GOOD_BAD_HIGH_TXBCASTGBHI_OFFSET 0 + #define TX_BROADCAST_FRAMES_GOOD_BAD_HIGH_TXBCASTGBHI_LEN 32 + #define TX_BROADCAST_FRAMES_GOOD_BAD_HIGH_TXBCASTGBHI_DEFAULT 0x0 + +struct tx_broadcast_frames_good_bad_high { + a_uint32_t txbcastgbhi:32; +}; + +union tx_broadcast_frames_good_bad_high_u { + a_uint32_t val; + struct tx_broadcast_frames_good_bad_high bf; +}; + +/*[register] TX_UNDERFLOW_ERROR_FRAMES_LOW*/ +#define TX_UNDERFLOW_ERROR_FRAMES_LOW +#define TX_UNDERFLOW_ERROR_FRAMES_LOW_ADDRESS 0x87c +#define TX_UNDERFLOW_ERROR_FRAMES_LOW_NUM 1 +#define TX_UNDERFLOW_ERROR_FRAMES_LOW_INC 0x4000 +#define TX_UNDERFLOW_ERROR_FRAMES_LOW_TYPE REG_TYPE_RO +#define TX_UNDERFLOW_ERROR_FRAMES_LOW_DEFAULT 0x0 + /*[field] TXUNDRFLWLO*/ + #define TX_UNDERFLOW_ERROR_FRAMES_LOW_TXUNDRFLWLO + #define TX_UNDERFLOW_ERROR_FRAMES_LOW_TXUNDRFLWLO_OFFSET 0 + #define TX_UNDERFLOW_ERROR_FRAMES_LOW_TXUNDRFLWLO_LEN 32 + #define TX_UNDERFLOW_ERROR_FRAMES_LOW_TXUNDRFLWLO_DEFAULT 0x0 + +struct tx_underflow_error_frames_low { + a_uint32_t txundrflwlo:32; +}; + +union tx_underflow_error_frames_low_u { + a_uint32_t val; + struct tx_underflow_error_frames_low bf; +}; + +/*[register] TX_UNDERFLOW_ERROR_FRAMES_HIGH*/ +#define TX_UNDERFLOW_ERROR_FRAMES_HIGH +#define TX_UNDERFLOW_ERROR_FRAMES_HIGH_ADDRESS 0x880 +#define TX_UNDERFLOW_ERROR_FRAMES_HIGH_NUM 1 +#define TX_UNDERFLOW_ERROR_FRAMES_HIGH_INC 0x4000 +#define TX_UNDERFLOW_ERROR_FRAMES_HIGH_TYPE REG_TYPE_RO +#define TX_UNDERFLOW_ERROR_FRAMES_HIGH_DEFAULT 0x0 + /*[field] TXUNDRFLWHI*/ + #define TX_UNDERFLOW_ERROR_FRAMES_HIGH_TXUNDRFLWHI + #define TX_UNDERFLOW_ERROR_FRAMES_HIGH_TXUNDRFLWHI_OFFSET 0 + #define TX_UNDERFLOW_ERROR_FRAMES_HIGH_TXUNDRFLWHI_LEN 32 + #define TX_UNDERFLOW_ERROR_FRAMES_HIGH_TXUNDRFLWHI_DEFAULT 0x0 + +struct tx_underflow_error_frames_high { + a_uint32_t txundrflwhi:32; +}; + +union tx_underflow_error_frames_high_u { + a_uint32_t val; + struct tx_underflow_error_frames_high bf; +}; + +/*[register] TX_OCTET_COUNT_GOOD_LOW*/ +#define TX_OCTET_COUNT_GOOD_LOW +#define TX_OCTET_COUNT_GOOD_LOW_ADDRESS 0x884 +#define TX_OCTET_COUNT_GOOD_LOW_NUM 1 +#define TX_OCTET_COUNT_GOOD_LOW_INC 0x4000 +#define TX_OCTET_COUNT_GOOD_LOW_TYPE REG_TYPE_RO +#define TX_OCTET_COUNT_GOOD_LOW_DEFAULT 0x0 + /*[field] TXOCTGLO*/ + #define TX_OCTET_COUNT_GOOD_LOW_TXOCTGLO + #define TX_OCTET_COUNT_GOOD_LOW_TXOCTGLO_OFFSET 0 + #define TX_OCTET_COUNT_GOOD_LOW_TXOCTGLO_LEN 32 + #define TX_OCTET_COUNT_GOOD_LOW_TXOCTGLO_DEFAULT 0x0 + +struct tx_octet_count_good_low { + a_uint32_t txoctglo:32; +}; + +union tx_octet_count_good_low_u { + a_uint32_t val; + struct tx_octet_count_good_low bf; +}; + +/*[register] TX_OCTET_COUNT_GOOD_HIGH*/ +#define TX_OCTET_COUNT_GOOD_HIGH +#define TX_OCTET_COUNT_GOOD_HIGH_ADDRESS 0x888 +#define TX_OCTET_COUNT_GOOD_HIGH_NUM 1 +#define TX_OCTET_COUNT_GOOD_HIGH_INC 0x4000 +#define TX_OCTET_COUNT_GOOD_HIGH_TYPE REG_TYPE_RO +#define TX_OCTET_COUNT_GOOD_HIGH_DEFAULT 0x0 + /*[field] TXOCTGHI*/ + #define TX_OCTET_COUNT_GOOD_HIGH_TXOCTGHI + #define TX_OCTET_COUNT_GOOD_HIGH_TXOCTGHI_OFFSET 0 + #define TX_OCTET_COUNT_GOOD_HIGH_TXOCTGHI_LEN 32 + #define TX_OCTET_COUNT_GOOD_HIGH_TXOCTGHI_DEFAULT 0x0 + +struct tx_octet_count_good_high { + a_uint32_t txoctghi:32; +}; + +union tx_octet_count_good_high_u { + a_uint32_t val; + struct tx_octet_count_good_high bf; +}; + +/*[register] TX_FRAME_COUNT_GOOD_LOW*/ +#define TX_FRAME_COUNT_GOOD_LOW +#define TX_FRAME_COUNT_GOOD_LOW_ADDRESS 0x88c +#define TX_FRAME_COUNT_GOOD_LOW_NUM 1 +#define TX_FRAME_COUNT_GOOD_LOW_INC 0x4000 +#define TX_FRAME_COUNT_GOOD_LOW_TYPE REG_TYPE_RO +#define TX_FRAME_COUNT_GOOD_LOW_DEFAULT 0x0 + /*[field] TXFRMGLO*/ + #define TX_FRAME_COUNT_GOOD_LOW_TXFRMGLO + #define TX_FRAME_COUNT_GOOD_LOW_TXFRMGLO_OFFSET 0 + #define TX_FRAME_COUNT_GOOD_LOW_TXFRMGLO_LEN 32 + #define TX_FRAME_COUNT_GOOD_LOW_TXFRMGLO_DEFAULT 0x0 + +struct tx_frame_count_good_low { + a_uint32_t txfrmglo:32; +}; + +union tx_frame_count_good_low_u { + a_uint32_t val; + struct tx_frame_count_good_low bf; +}; + +/*[register] TX_FRAME_COUNT_GOOD_HIGH*/ +#define TX_FRAME_COUNT_GOOD_HIGH +#define TX_FRAME_COUNT_GOOD_HIGH_ADDRESS 0x890 +#define TX_FRAME_COUNT_GOOD_HIGH_NUM 1 +#define TX_FRAME_COUNT_GOOD_HIGH_INC 0x4000 +#define TX_FRAME_COUNT_GOOD_HIGH_TYPE REG_TYPE_RO +#define TX_FRAME_COUNT_GOOD_HIGH_DEFAULT 0x0 + /*[field] TXFRMGHI*/ + #define TX_FRAME_COUNT_GOOD_HIGH_TXFRMGHI + #define TX_FRAME_COUNT_GOOD_HIGH_TXFRMGHI_OFFSET 0 + #define TX_FRAME_COUNT_GOOD_HIGH_TXFRMGHI_LEN 32 + #define TX_FRAME_COUNT_GOOD_HIGH_TXFRMGHI_DEFAULT 0x0 + +struct tx_frame_count_good_high { + a_uint32_t txfrmghi:32; +}; + +union tx_frame_count_good_high_u { + a_uint32_t val; + struct tx_frame_count_good_high bf; +}; + +/*[register] TX_PAUSE_FRAMES_LOW*/ +#define TX_PAUSE_FRAMES_LOW +#define TX_PAUSE_FRAMES_LOW_ADDRESS 0x894 +#define TX_PAUSE_FRAMES_LOW_NUM 1 +#define TX_PAUSE_FRAMES_LOW_INC 0x4000 +#define TX_PAUSE_FRAMES_LOW_TYPE REG_TYPE_RO +#define TX_PAUSE_FRAMES_LOW_DEFAULT 0x0 + /*[field] TXPAUSEGLO*/ + #define TX_PAUSE_FRAMES_LOW_TXPAUSEGLO + #define TX_PAUSE_FRAMES_LOW_TXPAUSEGLO_OFFSET 0 + #define TX_PAUSE_FRAMES_LOW_TXPAUSEGLO_LEN 32 + #define TX_PAUSE_FRAMES_LOW_TXPAUSEGLO_DEFAULT 0x0 + +struct tx_pause_frames_low { + a_uint32_t txpauseglo:32; +}; + +union tx_pause_frames_low_u { + a_uint32_t val; + struct tx_pause_frames_low bf; +}; + +/*[register] TX_PAUSE_FRAMES_HIGH*/ +#define TX_PAUSE_FRAMES_HIGH +#define TX_PAUSE_FRAMES_HIGH_ADDRESS 0x898 +#define TX_PAUSE_FRAMES_HIGH_NUM 1 +#define TX_PAUSE_FRAMES_HIGH_INC 0x4000 +#define TX_PAUSE_FRAMES_HIGH_TYPE REG_TYPE_RO +#define TX_PAUSE_FRAMES_HIGH_DEFAULT 0x0 + /*[field] TXPAUSEGHI*/ + #define TX_PAUSE_FRAMES_HIGH_TXPAUSEGHI + #define TX_PAUSE_FRAMES_HIGH_TXPAUSEGHI_OFFSET 0 + #define TX_PAUSE_FRAMES_HIGH_TXPAUSEGHI_LEN 32 + #define TX_PAUSE_FRAMES_HIGH_TXPAUSEGHI_DEFAULT 0x0 + +struct tx_pause_frames_high { + a_uint32_t txpauseghi:32; +}; + +union tx_pause_frames_high_u { + a_uint32_t val; + struct tx_pause_frames_high bf; +}; + +/*[register] TX_VLAN_FRAMES_GOOD_LOW*/ +#define TX_VLAN_FRAMES_GOOD_LOW +#define TX_VLAN_FRAMES_GOOD_LOW_ADDRESS 0x89c +#define TX_VLAN_FRAMES_GOOD_LOW_NUM 1 +#define TX_VLAN_FRAMES_GOOD_LOW_INC 0x4000 +#define TX_VLAN_FRAMES_GOOD_LOW_TYPE REG_TYPE_RO +#define TX_VLAN_FRAMES_GOOD_LOW_DEFAULT 0x0 + /*[field] TXVLANGLO*/ + #define TX_VLAN_FRAMES_GOOD_LOW_TXVLANGLO + #define TX_VLAN_FRAMES_GOOD_LOW_TXVLANGLO_OFFSET 0 + #define TX_VLAN_FRAMES_GOOD_LOW_TXVLANGLO_LEN 32 + #define TX_VLAN_FRAMES_GOOD_LOW_TXVLANGLO_DEFAULT 0x0 + +struct tx_vlan_frames_good_low { + a_uint32_t txvlanglo:32; +}; + +union tx_vlan_frames_good_low_u { + a_uint32_t val; + struct tx_vlan_frames_good_low bf; +}; + +/*[register] TX_VLAN_FRAMES_GOOD_HIGH*/ +#define TX_VLAN_FRAMES_GOOD_HIGH +#define TX_VLAN_FRAMES_GOOD_HIGH_ADDRESS 0x8a0 +#define TX_VLAN_FRAMES_GOOD_HIGH_NUM 1 +#define TX_VLAN_FRAMES_GOOD_HIGH_INC 0x4000 +#define TX_VLAN_FRAMES_GOOD_HIGH_TYPE REG_TYPE_RO +#define TX_VLAN_FRAMES_GOOD_HIGH_DEFAULT 0x0 + /*[field] TXVLANGHI*/ + #define TX_VLAN_FRAMES_GOOD_HIGH_TXVLANGHI + #define TX_VLAN_FRAMES_GOOD_HIGH_TXVLANGHI_OFFSET 0 + #define TX_VLAN_FRAMES_GOOD_HIGH_TXVLANGHI_LEN 32 + #define TX_VLAN_FRAMES_GOOD_HIGH_TXVLANGHI_DEFAULT 0x0 + +struct tx_vlan_frames_good_high { + a_uint32_t txvlanghi:32; +}; + +union tx_vlan_frames_good_high_u { + a_uint32_t val; + struct tx_vlan_frames_good_high bf; +}; + +/*[register] TX_LPI_USEC_CNTR*/ +#define TX_LPI_USEC_CNTR +#define TX_LPI_USEC_CNTR_ADDRESS 0x8a4 +#define TX_LPI_USEC_CNTR_NUM 1 +#define TX_LPI_USEC_CNTR_INC 0x4000 +#define TX_LPI_USEC_CNTR_TYPE REG_TYPE_RO +#define TX_LPI_USEC_CNTR_DEFAULT 0x0 + /*[field] TXLPIUSC*/ + #define TX_LPI_USEC_CNTR_TXLPIUSC + #define TX_LPI_USEC_CNTR_TXLPIUSC_OFFSET 0 + #define TX_LPI_USEC_CNTR_TXLPIUSC_LEN 32 + #define TX_LPI_USEC_CNTR_TXLPIUSC_DEFAULT 0x0 + +struct tx_lpi_usec_cntr { + a_uint32_t txlpiusc:32; +}; + +union tx_lpi_usec_cntr_u { + a_uint32_t val; + struct tx_lpi_usec_cntr bf; +}; + +/*[register] TX_LPI_TRAN_CNTR*/ +#define TX_LPI_TRAN_CNTR +#define TX_LPI_TRAN_CNTR_ADDRESS 0x8a8 +#define TX_LPI_TRAN_CNTR_NUM 1 +#define TX_LPI_TRAN_CNTR_INC 0x4000 +#define TX_LPI_TRAN_CNTR_TYPE REG_TYPE_RO +#define TX_LPI_TRAN_CNTR_DEFAULT 0x0 + /*[field] TXLPITRC*/ + #define TX_LPI_TRAN_CNTR_TXLPITRC + #define TX_LPI_TRAN_CNTR_TXLPITRC_OFFSET 0 + #define TX_LPI_TRAN_CNTR_TXLPITRC_LEN 32 + #define TX_LPI_TRAN_CNTR_TXLPITRC_DEFAULT 0x0 + +struct tx_lpi_tran_cntr { + a_uint32_t txlpitrc:32; +}; + +union tx_lpi_tran_cntr_u { + a_uint32_t val; + struct tx_lpi_tran_cntr bf; +}; + +/*[register] RX_FRAME_COUNT_GOOD_BAD_LOW*/ +#define RX_FRAME_COUNT_GOOD_BAD_LOW +#define RX_FRAME_COUNT_GOOD_BAD_LOW_ADDRESS 0x900 +#define RX_FRAME_COUNT_GOOD_BAD_LOW_NUM 1 +#define RX_FRAME_COUNT_GOOD_BAD_LOW_INC 0x4000 +#define RX_FRAME_COUNT_GOOD_BAD_LOW_TYPE REG_TYPE_RO +#define RX_FRAME_COUNT_GOOD_BAD_LOW_DEFAULT 0x0 + /*[field] RXFRMGBLO*/ + #define RX_FRAME_COUNT_GOOD_BAD_LOW_RXFRMGBLO + #define RX_FRAME_COUNT_GOOD_BAD_LOW_RXFRMGBLO_OFFSET 0 + #define RX_FRAME_COUNT_GOOD_BAD_LOW_RXFRMGBLO_LEN 32 + #define RX_FRAME_COUNT_GOOD_BAD_LOW_RXFRMGBLO_DEFAULT 0x0 + +struct rx_frame_count_good_bad_low { + a_uint32_t rxfrmgblo:32; +}; + +union rx_frame_count_good_bad_low_u { + a_uint32_t val; + struct rx_frame_count_good_bad_low bf; +}; + +/*[register] RX_FRAME_COUNT_GOOD_BAD_HIGH*/ +#define RX_FRAME_COUNT_GOOD_BAD_HIGH +#define RX_FRAME_COUNT_GOOD_BAD_HIGH_ADDRESS 0x904 +#define RX_FRAME_COUNT_GOOD_BAD_HIGH_NUM 1 +#define RX_FRAME_COUNT_GOOD_BAD_HIGH_INC 0x4000 +#define RX_FRAME_COUNT_GOOD_BAD_HIGH_TYPE REG_TYPE_RO +#define RX_FRAME_COUNT_GOOD_BAD_HIGH_DEFAULT 0x0 + /*[field] RXFRMGBHI*/ + #define RX_FRAME_COUNT_GOOD_BAD_HIGH_RXFRMGBHI + #define RX_FRAME_COUNT_GOOD_BAD_HIGH_RXFRMGBHI_OFFSET 0 + #define RX_FRAME_COUNT_GOOD_BAD_HIGH_RXFRMGBHI_LEN 32 + #define RX_FRAME_COUNT_GOOD_BAD_HIGH_RXFRMGBHI_DEFAULT 0x0 + +struct rx_frame_count_good_bad_high { + a_uint32_t rxfrmgbhi:32; +}; + +union rx_frame_count_good_bad_high_u { + a_uint32_t val; + struct rx_frame_count_good_bad_high bf; +}; + +/*[register] RX_OCTET_COUNT_GOOD_BAD_LOW*/ +#define RX_OCTET_COUNT_GOOD_BAD_LOW +#define RX_OCTET_COUNT_GOOD_BAD_LOW_ADDRESS 0x908 +#define RX_OCTET_COUNT_GOOD_BAD_LOW_NUM 1 +#define RX_OCTET_COUNT_GOOD_BAD_LOW_INC 0x4000 +#define RX_OCTET_COUNT_GOOD_BAD_LOW_TYPE REG_TYPE_RO +#define RX_OCTET_COUNT_GOOD_BAD_LOW_DEFAULT 0x0 + /*[field] RXOCTGBLO*/ + #define RX_OCTET_COUNT_GOOD_BAD_LOW_RXOCTGBLO + #define RX_OCTET_COUNT_GOOD_BAD_LOW_RXOCTGBLO_OFFSET 0 + #define RX_OCTET_COUNT_GOOD_BAD_LOW_RXOCTGBLO_LEN 32 + #define RX_OCTET_COUNT_GOOD_BAD_LOW_RXOCTGBLO_DEFAULT 0x0 + +struct rx_octet_count_good_bad_low { + a_uint32_t rxoctgblo:32; +}; + +union rx_octet_count_good_bad_low_u { + a_uint32_t val; + struct rx_octet_count_good_bad_low bf; +}; + +/*[register] RX_OCTET_COUNT_GOOD_BAD_HIGH*/ +#define RX_OCTET_COUNT_GOOD_BAD_HIGH +#define RX_OCTET_COUNT_GOOD_BAD_HIGH_ADDRESS 0x90c +#define RX_OCTET_COUNT_GOOD_BAD_HIGH_NUM 1 +#define RX_OCTET_COUNT_GOOD_BAD_HIGH_INC 0x4000 +#define RX_OCTET_COUNT_GOOD_BAD_HIGH_TYPE REG_TYPE_RO +#define RX_OCTET_COUNT_GOOD_BAD_HIGH_DEFAULT 0x0 + /*[field] RXOCTGBHI*/ + #define RX_OCTET_COUNT_GOOD_BAD_HIGH_RXOCTGBHI + #define RX_OCTET_COUNT_GOOD_BAD_HIGH_RXOCTGBHI_OFFSET 0 + #define RX_OCTET_COUNT_GOOD_BAD_HIGH_RXOCTGBHI_LEN 32 + #define RX_OCTET_COUNT_GOOD_BAD_HIGH_RXOCTGBHI_DEFAULT 0x0 + +struct rx_octet_count_good_bad_high { + a_uint32_t rxoctgbhi:32; +}; + +union rx_octet_count_good_bad_high_u { + a_uint32_t val; + struct rx_octet_count_good_bad_high bf; +}; + +/*[register] RX_OCTET_COUNT_GOOD_LOW*/ +#define RX_OCTET_COUNT_GOOD_LOW +#define RX_OCTET_COUNT_GOOD_LOW_ADDRESS 0x910 +#define RX_OCTET_COUNT_GOOD_LOW_NUM 1 +#define RX_OCTET_COUNT_GOOD_LOW_INC 0x4000 +#define RX_OCTET_COUNT_GOOD_LOW_TYPE REG_TYPE_RO +#define RX_OCTET_COUNT_GOOD_LOW_DEFAULT 0x0 + /*[field] RXOCTGLO*/ + #define RX_OCTET_COUNT_GOOD_LOW_RXOCTGLO + #define RX_OCTET_COUNT_GOOD_LOW_RXOCTGLO_OFFSET 0 + #define RX_OCTET_COUNT_GOOD_LOW_RXOCTGLO_LEN 32 + #define RX_OCTET_COUNT_GOOD_LOW_RXOCTGLO_DEFAULT 0x0 + +struct rx_octet_count_good_low { + a_uint32_t rxoctglo:32; +}; + +union rx_octet_count_good_low_u { + a_uint32_t val; + struct rx_octet_count_good_low bf; +}; + +/*[register] RX_OCTET_COUNT_GOOD_HIGH*/ +#define RX_OCTET_COUNT_GOOD_HIGH +#define RX_OCTET_COUNT_GOOD_HIGH_ADDRESS 0x914 +#define RX_OCTET_COUNT_GOOD_HIGH_NUM 1 +#define RX_OCTET_COUNT_GOOD_HIGH_INC 0x4000 +#define RX_OCTET_COUNT_GOOD_HIGH_TYPE REG_TYPE_RO +#define RX_OCTET_COUNT_GOOD_HIGH_DEFAULT 0x0 + /*[field] RXOCTGHI*/ + #define RX_OCTET_COUNT_GOOD_HIGH_RXOCTGHI + #define RX_OCTET_COUNT_GOOD_HIGH_RXOCTGHI_OFFSET 0 + #define RX_OCTET_COUNT_GOOD_HIGH_RXOCTGHI_LEN 32 + #define RX_OCTET_COUNT_GOOD_HIGH_RXOCTGHI_DEFAULT 0x0 + +struct rx_octet_count_good_high { + a_uint32_t rxoctghi:32; +}; + +union rx_octet_count_good_high_u { + a_uint32_t val; + struct rx_octet_count_good_high bf; +}; + +/*[register] RX_BROADCAST_FRAMES_GOOD_LOW*/ +#define RX_BROADCAST_FRAMES_GOOD_LOW +#define RX_BROADCAST_FRAMES_GOOD_LOW_ADDRESS 0x918 +#define RX_BROADCAST_FRAMES_GOOD_LOW_NUM 1 +#define RX_BROADCAST_FRAMES_GOOD_LOW_INC 0x4000 +#define RX_BROADCAST_FRAMES_GOOD_LOW_TYPE REG_TYPE_RO +#define RX_BROADCAST_FRAMES_GOOD_LOW_DEFAULT 0x0 + /*[field] RXBCASTGLO*/ + #define RX_BROADCAST_FRAMES_GOOD_LOW_RXBCASTGLO + #define RX_BROADCAST_FRAMES_GOOD_LOW_RXBCASTGLO_OFFSET 0 + #define RX_BROADCAST_FRAMES_GOOD_LOW_RXBCASTGLO_LEN 32 + #define RX_BROADCAST_FRAMES_GOOD_LOW_RXBCASTGLO_DEFAULT 0x0 + +struct rx_broadcast_frames_good_low { + a_uint32_t rxbcastglo:32; +}; + +union rx_broadcast_frames_good_low_u { + a_uint32_t val; + struct rx_broadcast_frames_good_low bf; +}; + +/*[register] RX_BROADCAST_FRAMES_GOOD_HIGH*/ +#define RX_BROADCAST_FRAMES_GOOD_HIGH +#define RX_BROADCAST_FRAMES_GOOD_HIGH_ADDRESS 0x91c +#define RX_BROADCAST_FRAMES_GOOD_HIGH_NUM 1 +#define RX_BROADCAST_FRAMES_GOOD_HIGH_INC 0x4000 +#define RX_BROADCAST_FRAMES_GOOD_HIGH_TYPE REG_TYPE_RO +#define RX_BROADCAST_FRAMES_GOOD_HIGH_DEFAULT 0x0 + /*[field] RXBCASTGHI*/ + #define RX_BROADCAST_FRAMES_GOOD_HIGH_RXBCASTGHI + #define RX_BROADCAST_FRAMES_GOOD_HIGH_RXBCASTGHI_OFFSET 0 + #define RX_BROADCAST_FRAMES_GOOD_HIGH_RXBCASTGHI_LEN 32 + #define RX_BROADCAST_FRAMES_GOOD_HIGH_RXBCASTGHI_DEFAULT 0x0 + +struct rx_broadcast_frames_good_high { + a_uint32_t rxbcastghi:32; +}; + +union rx_broadcast_frames_good_high_u { + a_uint32_t val; + struct rx_broadcast_frames_good_high bf; +}; + +/*[register] RX_MULTICAST_FRAMES_GOOD_LOW*/ +#define RX_MULTICAST_FRAMES_GOOD_LOW +#define RX_MULTICAST_FRAMES_GOOD_LOW_ADDRESS 0x920 +#define RX_MULTICAST_FRAMES_GOOD_LOW_NUM 1 +#define RX_MULTICAST_FRAMES_GOOD_LOW_INC 0x4000 +#define RX_MULTICAST_FRAMES_GOOD_LOW_TYPE REG_TYPE_RO +#define RX_MULTICAST_FRAMES_GOOD_LOW_DEFAULT 0x0 + /*[field] RXMCASTGLO*/ + #define RX_MULTICAST_FRAMES_GOOD_LOW_RXMCASTGLO + #define RX_MULTICAST_FRAMES_GOOD_LOW_RXMCASTGLO_OFFSET 0 + #define RX_MULTICAST_FRAMES_GOOD_LOW_RXMCASTGLO_LEN 32 + #define RX_MULTICAST_FRAMES_GOOD_LOW_RXMCASTGLO_DEFAULT 0x0 + +struct rx_multicast_frames_good_low { + a_uint32_t rxmcastglo:32; +}; + +union rx_multicast_frames_good_low_u { + a_uint32_t val; + struct rx_multicast_frames_good_low bf; +}; + +/*[register] RX_MULTICAST_FRAMES_GOOD_HIGH*/ +#define RX_MULTICAST_FRAMES_GOOD_HIGH +#define RX_MULTICAST_FRAMES_GOOD_HIGH_ADDRESS 0x924 +#define RX_MULTICAST_FRAMES_GOOD_HIGH_NUM 1 +#define RX_MULTICAST_FRAMES_GOOD_HIGH_INC 0x4000 +#define RX_MULTICAST_FRAMES_GOOD_HIGH_TYPE REG_TYPE_RO +#define RX_MULTICAST_FRAMES_GOOD_HIGH_DEFAULT 0x0 + /*[field] RXMCASTGHI*/ + #define RX_MULTICAST_FRAMES_GOOD_HIGH_RXMCASTGHI + #define RX_MULTICAST_FRAMES_GOOD_HIGH_RXMCASTGHI_OFFSET 0 + #define RX_MULTICAST_FRAMES_GOOD_HIGH_RXMCASTGHI_LEN 32 + #define RX_MULTICAST_FRAMES_GOOD_HIGH_RXMCASTGHI_DEFAULT 0x0 + +struct rx_multicast_frames_good_high { + a_uint32_t rxmcastghi:32; +}; + +union rx_multicast_frames_good_high_u { + a_uint32_t val; + struct rx_multicast_frames_good_high bf; +}; + +/*[register] RX_CRC_ERROR_FRAMES_LOW*/ +#define RX_CRC_ERROR_FRAMES_LOW +#define RX_CRC_ERROR_FRAMES_LOW_ADDRESS 0x928 +#define RX_CRC_ERROR_FRAMES_LOW_NUM 1 +#define RX_CRC_ERROR_FRAMES_LOW_INC 0x4000 +#define RX_CRC_ERROR_FRAMES_LOW_TYPE REG_TYPE_RO +#define RX_CRC_ERROR_FRAMES_LOW_DEFAULT 0x0 + /*[field] RXCRCERLO*/ + #define RX_CRC_ERROR_FRAMES_LOW_RXCRCERLO + #define RX_CRC_ERROR_FRAMES_LOW_RXCRCERLO_OFFSET 0 + #define RX_CRC_ERROR_FRAMES_LOW_RXCRCERLO_LEN 32 + #define RX_CRC_ERROR_FRAMES_LOW_RXCRCERLO_DEFAULT 0x0 + +struct rx_crc_error_frames_low { + a_uint32_t rxcrcerlo:32; +}; + +union rx_crc_error_frames_low_u { + a_uint32_t val; + struct rx_crc_error_frames_low bf; +}; + +/*[register] RX_CRC_ERROR_FRAMES_HIGH*/ +#define RX_CRC_ERROR_FRAMES_HIGH +#define RX_CRC_ERROR_FRAMES_HIGH_ADDRESS 0x92c +#define RX_CRC_ERROR_FRAMES_HIGH_NUM 1 +#define RX_CRC_ERROR_FRAMES_HIGH_INC 0x4000 +#define RX_CRC_ERROR_FRAMES_HIGH_TYPE REG_TYPE_RO +#define RX_CRC_ERROR_FRAMES_HIGH_DEFAULT 0x0 + /*[field] RXCRCERHI*/ + #define RX_CRC_ERROR_FRAMES_HIGH_RXCRCERHI + #define RX_CRC_ERROR_FRAMES_HIGH_RXCRCERHI_OFFSET 0 + #define RX_CRC_ERROR_FRAMES_HIGH_RXCRCERHI_LEN 32 + #define RX_CRC_ERROR_FRAMES_HIGH_RXCRCERHI_DEFAULT 0x0 + +struct rx_crc_error_frames_high { + a_uint32_t rxcrcerhi:32; +}; + +union rx_crc_error_frames_high_u { + a_uint32_t val; + struct rx_crc_error_frames_high bf; +}; + +/*[register] RX_RUNT_ERROR_FRAMES*/ +#define RX_RUNT_ERROR_FRAMES +#define RX_RUNT_ERROR_FRAMES_ADDRESS 0x930 +#define RX_RUNT_ERROR_FRAMES_NUM 1 +#define RX_RUNT_ERROR_FRAMES_INC 0x4000 +#define RX_RUNT_ERROR_FRAMES_TYPE REG_TYPE_RO +#define RX_RUNT_ERROR_FRAMES_DEFAULT 0x0 + /*[field] RXRUNTER*/ + #define RX_RUNT_ERROR_FRAMES_RXRUNTER + #define RX_RUNT_ERROR_FRAMES_RXRUNTER_OFFSET 0 + #define RX_RUNT_ERROR_FRAMES_RXRUNTER_LEN 32 + #define RX_RUNT_ERROR_FRAMES_RXRUNTER_DEFAULT 0x0 + +struct rx_runt_error_frames { + a_uint32_t rxrunter:32; +}; + +union rx_runt_error_frames_u { + a_uint32_t val; + struct rx_runt_error_frames bf; +}; + +/*[register] RX_JABBER_ERROR_FRAMES*/ +#define RX_JABBER_ERROR_FRAMES +#define RX_JABBER_ERROR_FRAMES_ADDRESS 0x934 +#define RX_JABBER_ERROR_FRAMES_NUM 1 +#define RX_JABBER_ERROR_FRAMES_INC 0x4000 +#define RX_JABBER_ERROR_FRAMES_TYPE REG_TYPE_RO +#define RX_JABBER_ERROR_FRAMES_DEFAULT 0x0 + /*[field] RXJABERER*/ + #define RX_JABBER_ERROR_FRAMES_RXJABERER + #define RX_JABBER_ERROR_FRAMES_RXJABERER_OFFSET 0 + #define RX_JABBER_ERROR_FRAMES_RXJABERER_LEN 32 + #define RX_JABBER_ERROR_FRAMES_RXJABERER_DEFAULT 0x0 + +struct rx_jabber_error_frames { + a_uint32_t rxjaberer:32; +}; + +union rx_jabber_error_frames_u { + a_uint32_t val; + struct rx_jabber_error_frames bf; +}; + +/*[register] RX_UNDERSIZE_FRAMES_GOOD*/ +#define RX_UNDERSIZE_FRAMES_GOOD +#define RX_UNDERSIZE_FRAMES_GOOD_ADDRESS 0x938 +#define RX_UNDERSIZE_FRAMES_GOOD_NUM 1 +#define RX_UNDERSIZE_FRAMES_GOOD_INC 0x4000 +#define RX_UNDERSIZE_FRAMES_GOOD_TYPE REG_TYPE_RO +#define RX_UNDERSIZE_FRAMES_GOOD_DEFAULT 0x0 + /*[field] RXUSIZEG*/ + #define RX_UNDERSIZE_FRAMES_GOOD_RXUSIZEG + #define RX_UNDERSIZE_FRAMES_GOOD_RXUSIZEG_OFFSET 0 + #define RX_UNDERSIZE_FRAMES_GOOD_RXUSIZEG_LEN 32 + #define RX_UNDERSIZE_FRAMES_GOOD_RXUSIZEG_DEFAULT 0x0 + +struct rx_undersize_frames_good { + a_uint32_t rxusizeg:32; +}; + +union rx_undersize_frames_good_u { + a_uint32_t val; + struct rx_undersize_frames_good bf; +}; + +/*[register] RX_OVERSIZE_FRAMES_GOOD*/ +#define RX_OVERSIZE_FRAMES_GOOD +#define RX_OVERSIZE_FRAMES_GOOD_ADDRESS 0x93c +#define RX_OVERSIZE_FRAMES_GOOD_NUM 1 +#define RX_OVERSIZE_FRAMES_GOOD_INC 0x4000 +#define RX_OVERSIZE_FRAMES_GOOD_TYPE REG_TYPE_RO +#define RX_OVERSIZE_FRAMES_GOOD_DEFAULT 0x0 + /*[field] RXOSIZEG*/ + #define RX_OVERSIZE_FRAMES_GOOD_RXOSIZEG + #define RX_OVERSIZE_FRAMES_GOOD_RXOSIZEG_OFFSET 0 + #define RX_OVERSIZE_FRAMES_GOOD_RXOSIZEG_LEN 32 + #define RX_OVERSIZE_FRAMES_GOOD_RXOSIZEG_DEFAULT 0x0 + +struct rx_oversize_frames_good { + a_uint32_t rxosizeg:32; +}; + +union rx_oversize_frames_good_u { + a_uint32_t val; + struct rx_oversize_frames_good bf; +}; + +/*[register] RX_64OCTETS_FRAMES_GOOD_BAD_LOW*/ +#define RX_64OCTETS_FRAMES_GOOD_BAD_LOW +#define RX_64OCTETS_FRAMES_GOOD_BAD_LOW_ADDRESS 0x940 +#define RX_64OCTETS_FRAMES_GOOD_BAD_LOW_NUM 1 +#define RX_64OCTETS_FRAMES_GOOD_BAD_LOW_INC 0x4000 +#define RX_64OCTETS_FRAMES_GOOD_BAD_LOW_TYPE REG_TYPE_RO +#define RX_64OCTETS_FRAMES_GOOD_BAD_LOW_DEFAULT 0x0 + /*[field] RX64OCTGBLO*/ + #define RX_64OCTETS_FRAMES_GOOD_BAD_LOW_RX64OCTGBLO + #define RX_64OCTETS_FRAMES_GOOD_BAD_LOW_RX64OCTGBLO_OFFSET 0 + #define RX_64OCTETS_FRAMES_GOOD_BAD_LOW_RX64OCTGBLO_LEN 32 + #define RX_64OCTETS_FRAMES_GOOD_BAD_LOW_RX64OCTGBLO_DEFAULT 0x0 + +struct rx_64octets_frames_good_bad_low { + a_uint32_t rx64octgblo:32; +}; + +union rx_64octets_frames_good_bad_low_u { + a_uint32_t val; + struct rx_64octets_frames_good_bad_low bf; +}; + +/*[register] RX_64OCTETS_FRAMES_GOOD_BAD_HIGH*/ +#define RX_64OCTETS_FRAMES_GOOD_BAD_HIGH +#define RX_64OCTETS_FRAMES_GOOD_BAD_HIGH_ADDRESS 0x944 +#define RX_64OCTETS_FRAMES_GOOD_BAD_HIGH_NUM 1 +#define RX_64OCTETS_FRAMES_GOOD_BAD_HIGH_INC 0x4000 +#define RX_64OCTETS_FRAMES_GOOD_BAD_HIGH_TYPE REG_TYPE_RO +#define RX_64OCTETS_FRAMES_GOOD_BAD_HIGH_DEFAULT 0x0 + /*[field] RX64OCTGBHI*/ + #define RX_64OCTETS_FRAMES_GOOD_BAD_HIGH_RX64OCTGBHI + #define RX_64OCTETS_FRAMES_GOOD_BAD_HIGH_RX64OCTGBHI_OFFSET 0 + #define RX_64OCTETS_FRAMES_GOOD_BAD_HIGH_RX64OCTGBHI_LEN 32 + #define RX_64OCTETS_FRAMES_GOOD_BAD_HIGH_RX64OCTGBHI_DEFAULT 0x0 + +struct rx_64octets_frames_good_bad_high { + a_uint32_t rx64octgbhi:32; +}; + +union rx_64octets_frames_good_bad_high_u { + a_uint32_t val; + struct rx_64octets_frames_good_bad_high bf; +}; + +/*[register] RX_65TO127OCTETS_FRAMES_GOOD_BAD_LOW*/ +#define RX_65TO127OCTETS_FRAMES_GOOD_BAD_LOW +#define RX_65TO127OCTETS_FRAMES_GOOD_BAD_LOW_ADDRESS 0x948 +#define RX_65TO127OCTETS_FRAMES_GOOD_BAD_LOW_NUM 1 +#define RX_65TO127OCTETS_FRAMES_GOOD_BAD_LOW_INC 0x4000 +#define RX_65TO127OCTETS_FRAMES_GOOD_BAD_LOW_TYPE REG_TYPE_RO +#define RX_65TO127OCTETS_FRAMES_GOOD_BAD_LOW_DEFAULT 0x0 + /*[field] RX65_127OCTGBLO*/ + #define RX_65TO127OCTETS_FRAMES_GOOD_BAD_LOW_RX65_127OCTGBLO + #define RX_65TO127OCTETS_FRAMES_GOOD_BAD_LOW_RX65_127OCTGBLO_OFFSET 0 + #define RX_65TO127OCTETS_FRAMES_GOOD_BAD_LOW_RX65_127OCTGBLO_LEN 32 + #define RX_65TO127OCTETS_FRAMES_GOOD_BAD_LOW_RX65_127OCTGBLO_DEFAULT 0x0 + +struct rx_65to127octets_frames_good_bad_low { + a_uint32_t rx65_127octgblo:32; +}; + +union rx_65to127octets_frames_good_bad_low_u { + a_uint32_t val; + struct rx_65to127octets_frames_good_bad_low bf; +}; + +/*[register] RX_65TO127OCTETS_FRAMES_GOOD_BAD_HIGH*/ +#define RX_65TO127OCTETS_FRAMES_GOOD_BAD_HIGH +#define RX_65TO127OCTETS_FRAMES_GOOD_BAD_HIGH_ADDRESS 0x94c +#define RX_65TO127OCTETS_FRAMES_GOOD_BAD_HIGH_NUM 1 +#define RX_65TO127OCTETS_FRAMES_GOOD_BAD_HIGH_INC 0x4000 +#define RX_65TO127OCTETS_FRAMES_GOOD_BAD_HIGH_TYPE REG_TYPE_RO +#define RX_65TO127OCTETS_FRAMES_GOOD_BAD_HIGH_DEFAULT 0x0 + /*[field] RX65_127OCTGBHI*/ + #define RX_65TO127OCTETS_FRAMES_GOOD_BAD_HIGH_RX65_127OCTGBHI + #define RX_65TO127OCTETS_FRAMES_GOOD_BAD_HIGH_RX65_127OCTGBHI_OFFSET 0 + #define RX_65TO127OCTETS_FRAMES_GOOD_BAD_HIGH_RX65_127OCTGBHI_LEN 32 + #define RX_65TO127OCTETS_FRAMES_GOOD_BAD_HIGH_RX65_127OCTGBHI_DEFAULT 0x0 + +struct rx_65to127octets_frames_good_bad_high { + a_uint32_t rx65_127octgbhi:32; +}; + +union rx_65to127octets_frames_good_bad_high_u { + a_uint32_t val; + struct rx_65to127octets_frames_good_bad_high bf; +}; + +/*[register] RX_128TO255OCTETS_FRAMES_GOOD_BAD_LOW*/ +#define RX_128TO255OCTETS_FRAMES_GOOD_BAD_LOW +#define RX_128TO255OCTETS_FRAMES_GOOD_BAD_LOW_ADDRESS 0x950 +#define RX_128TO255OCTETS_FRAMES_GOOD_BAD_LOW_NUM 1 +#define RX_128TO255OCTETS_FRAMES_GOOD_BAD_LOW_INC 0x4000 +#define RX_128TO255OCTETS_FRAMES_GOOD_BAD_LOW_TYPE REG_TYPE_RO +#define RX_128TO255OCTETS_FRAMES_GOOD_BAD_LOW_DEFAULT 0x0 + /*[field] RX128_255OCTGBLO*/ + #define RX_128TO255OCTETS_FRAMES_GOOD_BAD_LOW_RX128_255OCTGBLO + #define RX_128TO255OCTETS_FRAMES_GOOD_BAD_LOW_RX128_255OCTGBLO_OFFSET 0 + #define RX_128TO255OCTETS_FRAMES_GOOD_BAD_LOW_RX128_255OCTGBLO_LEN 32 + #define RX_128TO255OCTETS_FRAMES_GOOD_BAD_LOW_RX128_255OCTGBLO_DEFAULT 0x0 + +struct rx_128to255octets_frames_good_bad_low { + a_uint32_t rx128_255octgblo:32; +}; + +union rx_128to255octets_frames_good_bad_low_u { + a_uint32_t val; + struct rx_128to255octets_frames_good_bad_low bf; +}; + +/*[register] RX_128TO255OCTETS_FRAMES_GOOD_BAD_HIGH*/ +#define RX_128TO255OCTETS_FRAMES_GOOD_BAD_HIGH +#define RX_128TO255OCTETS_FRAMES_GOOD_BAD_HIGH_ADDRESS 0x954 +#define RX_128TO255OCTETS_FRAMES_GOOD_BAD_HIGH_NUM 1 +#define RX_128TO255OCTETS_FRAMES_GOOD_BAD_HIGH_INC 0x4000 +#define RX_128TO255OCTETS_FRAMES_GOOD_BAD_HIGH_TYPE REG_TYPE_RO +#define RX_128TO255OCTETS_FRAMES_GOOD_BAD_HIGH_DEFAULT 0x0 + /*[field] RX128_255OCTGBHI*/ + #define RX_128TO255OCTETS_FRAMES_GOOD_BAD_HIGH_RX128_255OCTGBHI + #define RX_128TO255OCTETS_FRAMES_GOOD_BAD_HIGH_RX128_255OCTGBHI_OFFSET 0 + #define RX_128TO255OCTETS_FRAMES_GOOD_BAD_HIGH_RX128_255OCTGBHI_LEN 32 + #define RX_128TO255OCTETS_FRAMES_GOOD_BAD_HIGH_RX128_255OCTGBHI_DEFAULT 0x0 + +struct rx_128to255octets_frames_good_bad_high { + a_uint32_t rx128_255octgbhi:32; +}; + +union rx_128to255octets_frames_good_bad_high_u { + a_uint32_t val; + struct rx_128to255octets_frames_good_bad_high bf; +}; + +/*[register] RX_256TO511OCTETS_FRAMES_GOOD_BAD_LOW*/ +#define RX_256TO511OCTETS_FRAMES_GOOD_BAD_LOW +#define RX_256TO511OCTETS_FRAMES_GOOD_BAD_LOW_ADDRESS 0x958 +#define RX_256TO511OCTETS_FRAMES_GOOD_BAD_LOW_NUM 1 +#define RX_256TO511OCTETS_FRAMES_GOOD_BAD_LOW_INC 0x4000 +#define RX_256TO511OCTETS_FRAMES_GOOD_BAD_LOW_TYPE REG_TYPE_RO +#define RX_256TO511OCTETS_FRAMES_GOOD_BAD_LOW_DEFAULT 0x0 + /*[field] RX256_511OCTGBLO*/ + #define RX_256TO511OCTETS_FRAMES_GOOD_BAD_LOW_RX256_511OCTGBLO + #define RX_256TO511OCTETS_FRAMES_GOOD_BAD_LOW_RX256_511OCTGBLO_OFFSET 0 + #define RX_256TO511OCTETS_FRAMES_GOOD_BAD_LOW_RX256_511OCTGBLO_LEN 32 + #define RX_256TO511OCTETS_FRAMES_GOOD_BAD_LOW_RX256_511OCTGBLO_DEFAULT 0x0 + +struct rx_256to511octets_frames_good_bad_low { + a_uint32_t rx256_511octgblo:32; +}; + +union rx_256to511octets_frames_good_bad_low_u { + a_uint32_t val; + struct rx_256to511octets_frames_good_bad_low bf; +}; + +/*[register] RX_256TO511OCTETS_FRAMES_GOOD_BAD_HIGH*/ +#define RX_256TO511OCTETS_FRAMES_GOOD_BAD_HIGH +#define RX_256TO511OCTETS_FRAMES_GOOD_BAD_HIGH_ADDRESS 0x95c +#define RX_256TO511OCTETS_FRAMES_GOOD_BAD_HIGH_NUM 1 +#define RX_256TO511OCTETS_FRAMES_GOOD_BAD_HIGH_INC 0x4000 +#define RX_256TO511OCTETS_FRAMES_GOOD_BAD_HIGH_TYPE REG_TYPE_RO +#define RX_256TO511OCTETS_FRAMES_GOOD_BAD_HIGH_DEFAULT 0x0 + /*[field] RX256_511OCTGBHI*/ + #define RX_256TO511OCTETS_FRAMES_GOOD_BAD_HIGH_RX256_511OCTGBHI + #define RX_256TO511OCTETS_FRAMES_GOOD_BAD_HIGH_RX256_511OCTGBHI_OFFSET 0 + #define RX_256TO511OCTETS_FRAMES_GOOD_BAD_HIGH_RX256_511OCTGBHI_LEN 32 + #define RX_256TO511OCTETS_FRAMES_GOOD_BAD_HIGH_RX256_511OCTGBHI_DEFAULT 0x0 + +struct rx_256to511octets_frames_good_bad_high { + a_uint32_t rx256_511octgbhi:32; +}; + +union rx_256to511octets_frames_good_bad_high_u { + a_uint32_t val; + struct rx_256to511octets_frames_good_bad_high bf; +}; + +/*[register] RX_512TO1023OCTETS_FRAMES_GOOD_BAD_LOW*/ +#define RX_512TO1023OCTETS_FRAMES_GOOD_BAD_LOW +#define RX_512TO1023OCTETS_FRAMES_GOOD_BAD_LOW_ADDRESS 0x960 +#define RX_512TO1023OCTETS_FRAMES_GOOD_BAD_LOW_NUM 1 +#define RX_512TO1023OCTETS_FRAMES_GOOD_BAD_LOW_INC 0x4000 +#define RX_512TO1023OCTETS_FRAMES_GOOD_BAD_LOW_TYPE REG_TYPE_RO +#define RX_512TO1023OCTETS_FRAMES_GOOD_BAD_LOW_DEFAULT 0x0 + /*[field] RX512_1023OCTGBLO*/ + #define RX_512TO1023OCTETS_FRAMES_GOOD_BAD_LOW_RX512_1023OCTGBLO + #define RX_512TO1023OCTETS_FRAMES_GOOD_BAD_LOW_RX512_1023OCTGBLO_OFFSET 0 + #define RX_512TO1023OCTETS_FRAMES_GOOD_BAD_LOW_RX512_1023OCTGBLO_LEN 32 + #define RX_512TO1023OCTETS_FRAMES_GOOD_BAD_LOW_RX512_1023OCTGBLO_DEFAULT 0x0 + +struct rx_512to1023octets_frames_good_bad_low { + a_uint32_t rx512_1023octgblo:32; +}; + +union rx_512to1023octets_frames_good_bad_low_u { + a_uint32_t val; + struct rx_512to1023octets_frames_good_bad_low bf; +}; + +/*[register] RX_512TO1023OCTETS_FRAMES_GOOD_BAD_HIGH*/ +#define RX_512TO1023OCTETS_FRAMES_GOOD_BAD_HIGH +#define RX_512TO1023OCTETS_FRAMES_GOOD_BAD_HIGH_ADDRESS 0x964 +#define RX_512TO1023OCTETS_FRAMES_GOOD_BAD_HIGH_NUM 1 +#define RX_512TO1023OCTETS_FRAMES_GOOD_BAD_HIGH_INC 0x4000 +#define RX_512TO1023OCTETS_FRAMES_GOOD_BAD_HIGH_TYPE REG_TYPE_RO +#define RX_512TO1023OCTETS_FRAMES_GOOD_BAD_HIGH_DEFAULT 0x0 + /*[field] RX512_1023OCTGBHI*/ + #define RX_512TO1023OCTETS_FRAMES_GOOD_BAD_HIGH_RX512_1023OCTGBHI + #define RX_512TO1023OCTETS_FRAMES_GOOD_BAD_HIGH_RX512_1023OCTGBHI_OFFSET 0 + #define RX_512TO1023OCTETS_FRAMES_GOOD_BAD_HIGH_RX512_1023OCTGBHI_LEN 32 + #define RX_512TO1023OCTETS_FRAMES_GOOD_BAD_HIGH_RX512_1023OCTGBHI_DEFAULT 0x0 + +struct rx_512to1023octets_frames_good_bad_high { + a_uint32_t rx512_1023octgbhi:32; +}; + +union rx_512to1023octets_frames_good_bad_high_u { + a_uint32_t val; + struct rx_512to1023octets_frames_good_bad_high bf; +}; + +/*[register] RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_LOW*/ +#define RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_LOW +#define RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_LOW_ADDRESS 0x968 +#define RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_LOW_NUM 1 +#define RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_LOW_INC 0x4000 +#define RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_LOW_TYPE REG_TYPE_RO +#define RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_LOW_DEFAULT 0x0 + /*[field] RX1024_MAXGBOCTLO*/ + #define RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_LOW_RX1024_MAXGBOCTLO + #define RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_LOW_RX1024_MAXGBOCTLO_OFFSET 0 + #define RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_LOW_RX1024_MAXGBOCTLO_LEN 32 + #define RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_LOW_RX1024_MAXGBOCTLO_DEFAULT 0x0 + +struct rx_1024tomaxoctets_frames_good_bad_low { + a_uint32_t rx1024_maxgboctlo:32; +}; + +union rx_1024tomaxoctets_frames_good_bad_low_u { + a_uint32_t val; + struct rx_1024tomaxoctets_frames_good_bad_low bf; +}; + +/*[register] RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_HIGH*/ +#define RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_HIGH +#define RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_HIGH_ADDRESS 0x96c +#define RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_HIGH_NUM 1 +#define RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_HIGH_INC 0x4000 +#define RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_HIGH_TYPE REG_TYPE_RO +#define RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_HIGH_DEFAULT 0x0 + /*[field] RX1024_MAXGBOCTHI*/ + #define RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_HIGH_RX1024_MAXGBOCTHI + #define RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_HIGH_RX1024_MAXGBOCTHI_OFFSET 0 + #define RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_HIGH_RX1024_MAXGBOCTHI_LEN 32 + #define RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_HIGH_RX1024_MAXGBOCTHI_DEFAULT 0x0 + +struct rx_1024tomaxoctets_frames_good_bad_high { + a_uint32_t rx1024_maxgbocthi:32; +}; + +union rx_1024tomaxoctets_frames_good_bad_high_u { + a_uint32_t val; + struct rx_1024tomaxoctets_frames_good_bad_high bf; +}; + +/*[register] RX_UNICAST_FRAMES_GOOD_LOW*/ +#define RX_UNICAST_FRAMES_GOOD_LOW +#define RX_UNICAST_FRAMES_GOOD_LOW_ADDRESS 0x970 +#define RX_UNICAST_FRAMES_GOOD_LOW_NUM 1 +#define RX_UNICAST_FRAMES_GOOD_LOW_INC 0x4000 +#define RX_UNICAST_FRAMES_GOOD_LOW_TYPE REG_TYPE_RO +#define RX_UNICAST_FRAMES_GOOD_LOW_DEFAULT 0x0 + /*[field] RXUCASTGLO*/ + #define RX_UNICAST_FRAMES_GOOD_LOW_RXUCASTGLO + #define RX_UNICAST_FRAMES_GOOD_LOW_RXUCASTGLO_OFFSET 0 + #define RX_UNICAST_FRAMES_GOOD_LOW_RXUCASTGLO_LEN 32 + #define RX_UNICAST_FRAMES_GOOD_LOW_RXUCASTGLO_DEFAULT 0x0 + +struct rx_unicast_frames_good_low { + a_uint32_t rxucastglo:32; +}; + +union rx_unicast_frames_good_low_u { + a_uint32_t val; + struct rx_unicast_frames_good_low bf; +}; + +/*[register] RX_UNICAST_FRAMES_GOOD_HIGH*/ +#define RX_UNICAST_FRAMES_GOOD_HIGH +#define RX_UNICAST_FRAMES_GOOD_HIGH_ADDRESS 0x974 +#define RX_UNICAST_FRAMES_GOOD_HIGH_NUM 1 +#define RX_UNICAST_FRAMES_GOOD_HIGH_INC 0x4000 +#define RX_UNICAST_FRAMES_GOOD_HIGH_TYPE REG_TYPE_RO +#define RX_UNICAST_FRAMES_GOOD_HIGH_DEFAULT 0x0 + /*[field] RXUCASTGHI*/ + #define RX_UNICAST_FRAMES_GOOD_HIGH_RXUCASTGHI + #define RX_UNICAST_FRAMES_GOOD_HIGH_RXUCASTGHI_OFFSET 0 + #define RX_UNICAST_FRAMES_GOOD_HIGH_RXUCASTGHI_LEN 32 + #define RX_UNICAST_FRAMES_GOOD_HIGH_RXUCASTGHI_DEFAULT 0x0 + +struct rx_unicast_frames_good_high { + a_uint32_t rxucastghi:32; +}; + +union rx_unicast_frames_good_high_u { + a_uint32_t val; + struct rx_unicast_frames_good_high bf; +}; + +/*[register] RX_LENGTH_ERROR_FRAMES_LOW*/ +#define RX_LENGTH_ERROR_FRAMES_LOW +#define RX_LENGTH_ERROR_FRAMES_LOW_ADDRESS 0x978 +#define RX_LENGTH_ERROR_FRAMES_LOW_NUM 1 +#define RX_LENGTH_ERROR_FRAMES_LOW_INC 0x4000 +#define RX_LENGTH_ERROR_FRAMES_LOW_TYPE REG_TYPE_RO +#define RX_LENGTH_ERROR_FRAMES_LOW_DEFAULT 0x0 + /*[field] RXLENERRLO*/ + #define RX_LENGTH_ERROR_FRAMES_LOW_RXLENERRLO + #define RX_LENGTH_ERROR_FRAMES_LOW_RXLENERRLO_OFFSET 0 + #define RX_LENGTH_ERROR_FRAMES_LOW_RXLENERRLO_LEN 32 + #define RX_LENGTH_ERROR_FRAMES_LOW_RXLENERRLO_DEFAULT 0x0 + +struct rx_length_error_frames_low { + a_uint32_t rxlenerrlo:32; +}; + +union rx_length_error_frames_low_u { + a_uint32_t val; + struct rx_length_error_frames_low bf; +}; + +/*[register] RX_LENGTH_ERROR_FRAMES_HIGH*/ +#define RX_LENGTH_ERROR_FRAMES_HIGH +#define RX_LENGTH_ERROR_FRAMES_HIGH_ADDRESS 0x97c +#define RX_LENGTH_ERROR_FRAMES_HIGH_NUM 1 +#define RX_LENGTH_ERROR_FRAMES_HIGH_INC 0x4000 +#define RX_LENGTH_ERROR_FRAMES_HIGH_TYPE REG_TYPE_RO +#define RX_LENGTH_ERROR_FRAMES_HIGH_DEFAULT 0x0 + /*[field] RXLENERRHI*/ + #define RX_LENGTH_ERROR_FRAMES_HIGH_RXLENERRHI + #define RX_LENGTH_ERROR_FRAMES_HIGH_RXLENERRHI_OFFSET 0 + #define RX_LENGTH_ERROR_FRAMES_HIGH_RXLENERRHI_LEN 32 + #define RX_LENGTH_ERROR_FRAMES_HIGH_RXLENERRHI_DEFAULT 0x0 + +struct rx_length_error_frames_high { + a_uint32_t rxlenerrhi:32; +}; + +union rx_length_error_frames_high_u { + a_uint32_t val; + struct rx_length_error_frames_high bf; +}; + +/*[register] RX_OUTOFRANGE_FRAMES_LOW*/ +#define RX_OUTOFRANGE_FRAMES_LOW +#define RX_OUTOFRANGE_FRAMES_LOW_ADDRESS 0x980 +#define RX_OUTOFRANGE_FRAMES_LOW_NUM 1 +#define RX_OUTOFRANGE_FRAMES_LOW_INC 0x4000 +#define RX_OUTOFRANGE_FRAMES_LOW_TYPE REG_TYPE_RO +#define RX_OUTOFRANGE_FRAMES_LOW_DEFAULT 0x0 + /*[field] RXORANGELO*/ + #define RX_OUTOFRANGE_FRAMES_LOW_RXORANGELO + #define RX_OUTOFRANGE_FRAMES_LOW_RXORANGELO_OFFSET 0 + #define RX_OUTOFRANGE_FRAMES_LOW_RXORANGELO_LEN 32 + #define RX_OUTOFRANGE_FRAMES_LOW_RXORANGELO_DEFAULT 0x0 + +struct rx_outofrange_frames_low { + a_uint32_t rxorangelo:32; +}; + +union rx_outofrange_frames_low_u { + a_uint32_t val; + struct rx_outofrange_frames_low bf; +}; + +/*[register] RX_OUTOFRANGE_FRAMES_HIGH*/ +#define RX_OUTOFRANGE_FRAMES_HIGH +#define RX_OUTOFRANGE_FRAMES_HIGH_ADDRESS 0x984 +#define RX_OUTOFRANGE_FRAMES_HIGH_NUM 1 +#define RX_OUTOFRANGE_FRAMES_HIGH_INC 0x4000 +#define RX_OUTOFRANGE_FRAMES_HIGH_TYPE REG_TYPE_RO +#define RX_OUTOFRANGE_FRAMES_HIGH_DEFAULT 0x0 + /*[field] RXORANGEHI*/ + #define RX_OUTOFRANGE_FRAMES_HIGH_RXORANGEHI + #define RX_OUTOFRANGE_FRAMES_HIGH_RXORANGEHI_OFFSET 0 + #define RX_OUTOFRANGE_FRAMES_HIGH_RXORANGEHI_LEN 32 + #define RX_OUTOFRANGE_FRAMES_HIGH_RXORANGEHI_DEFAULT 0x0 + +struct rx_outofrange_frames_high { + a_uint32_t rxorangehi:32; +}; + +union rx_outofrange_frames_high_u { + a_uint32_t val; + struct rx_outofrange_frames_high bf; +}; + +/*[register] RX_PAUSE_FRAMES_LOW*/ +#define RX_PAUSE_FRAMES_LOW +#define RX_PAUSE_FRAMES_LOW_ADDRESS 0x988 +#define RX_PAUSE_FRAMES_LOW_NUM 1 +#define RX_PAUSE_FRAMES_LOW_INC 0x4000 +#define RX_PAUSE_FRAMES_LOW_TYPE REG_TYPE_RO +#define RX_PAUSE_FRAMES_LOW_DEFAULT 0x0 + /*[field] RXPAUSELO*/ + #define RX_PAUSE_FRAMES_LOW_RXPAUSELO + #define RX_PAUSE_FRAMES_LOW_RXPAUSELO_OFFSET 0 + #define RX_PAUSE_FRAMES_LOW_RXPAUSELO_LEN 32 + #define RX_PAUSE_FRAMES_LOW_RXPAUSELO_DEFAULT 0x0 + +struct rx_pause_frames_low { + a_uint32_t rxpauselo:32; +}; + +union rx_pause_frames_low_u { + a_uint32_t val; + struct rx_pause_frames_low bf; +}; + +/*[register] RX_PAUSE_FRAMES_HIGH*/ +#define RX_PAUSE_FRAMES_HIGH +#define RX_PAUSE_FRAMES_HIGH_ADDRESS 0x98c +#define RX_PAUSE_FRAMES_HIGH_NUM 1 +#define RX_PAUSE_FRAMES_HIGH_INC 0x4000 +#define RX_PAUSE_FRAMES_HIGH_TYPE REG_TYPE_RO +#define RX_PAUSE_FRAMES_HIGH_DEFAULT 0x0 + /*[field] RXPAUSEHI*/ + #define RX_PAUSE_FRAMES_HIGH_RXPAUSEHI + #define RX_PAUSE_FRAMES_HIGH_RXPAUSEHI_OFFSET 0 + #define RX_PAUSE_FRAMES_HIGH_RXPAUSEHI_LEN 32 + #define RX_PAUSE_FRAMES_HIGH_RXPAUSEHI_DEFAULT 0x0 + +struct rx_pause_frames_high { + a_uint32_t rxpausehi:32; +}; + +union rx_pause_frames_high_u { + a_uint32_t val; + struct rx_pause_frames_high bf; +}; + +/*[register] RX_FIFOOVERFLOW_FRAMES_LOW*/ +#define RX_FIFOOVERFLOW_FRAMES_LOW +#define RX_FIFOOVERFLOW_FRAMES_LOW_ADDRESS 0x990 +#define RX_FIFOOVERFLOW_FRAMES_LOW_NUM 1 +#define RX_FIFOOVERFLOW_FRAMES_LOW_INC 0x4000 +#define RX_FIFOOVERFLOW_FRAMES_LOW_TYPE REG_TYPE_RO +#define RX_FIFOOVERFLOW_FRAMES_LOW_DEFAULT 0x0 + /*[field] RXFOVFLO*/ + #define RX_FIFOOVERFLOW_FRAMES_LOW_RXFOVFLO + #define RX_FIFOOVERFLOW_FRAMES_LOW_RXFOVFLO_OFFSET 0 + #define RX_FIFOOVERFLOW_FRAMES_LOW_RXFOVFLO_LEN 32 + #define RX_FIFOOVERFLOW_FRAMES_LOW_RXFOVFLO_DEFAULT 0x0 + +struct rx_fifooverflow_frames_low { + a_uint32_t rxfovflo:32; +}; + +union rx_fifooverflow_frames_low_u { + a_uint32_t val; + struct rx_fifooverflow_frames_low bf; +}; + +/*[register] RX_FIFOOVERFLOW_FRAMES_HIGH*/ +#define RX_FIFOOVERFLOW_FRAMES_HIGH +#define RX_FIFOOVERFLOW_FRAMES_HIGH_ADDRESS 0x994 +#define RX_FIFOOVERFLOW_FRAMES_HIGH_NUM 1 +#define RX_FIFOOVERFLOW_FRAMES_HIGH_INC 0x4000 +#define RX_FIFOOVERFLOW_FRAMES_HIGH_TYPE REG_TYPE_RO +#define RX_FIFOOVERFLOW_FRAMES_HIGH_DEFAULT 0x0 + /*[field] RXFOVFHI*/ + #define RX_FIFOOVERFLOW_FRAMES_HIGH_RXFOVFHI + #define RX_FIFOOVERFLOW_FRAMES_HIGH_RXFOVFHI_OFFSET 0 + #define RX_FIFOOVERFLOW_FRAMES_HIGH_RXFOVFHI_LEN 32 + #define RX_FIFOOVERFLOW_FRAMES_HIGH_RXFOVFHI_DEFAULT 0x0 + +struct rx_fifooverflow_frames_high { + a_uint32_t rxfovfhi:32; +}; + +union rx_fifooverflow_frames_high_u { + a_uint32_t val; + struct rx_fifooverflow_frames_high bf; +}; + +/*[register] RX_VLAN_FRAMES_GOOD_BAD_LOW*/ +#define RX_VLAN_FRAMES_GOOD_BAD_LOW +#define RX_VLAN_FRAMES_GOOD_BAD_LOW_ADDRESS 0x998 +#define RX_VLAN_FRAMES_GOOD_BAD_LOW_NUM 1 +#define RX_VLAN_FRAMES_GOOD_BAD_LOW_INC 0x4000 +#define RX_VLAN_FRAMES_GOOD_BAD_LOW_TYPE REG_TYPE_RO +#define RX_VLAN_FRAMES_GOOD_BAD_LOW_DEFAULT 0x0 + /*[field] RXVLANGBLO*/ + #define RX_VLAN_FRAMES_GOOD_BAD_LOW_RXVLANGBLO + #define RX_VLAN_FRAMES_GOOD_BAD_LOW_RXVLANGBLO_OFFSET 0 + #define RX_VLAN_FRAMES_GOOD_BAD_LOW_RXVLANGBLO_LEN 32 + #define RX_VLAN_FRAMES_GOOD_BAD_LOW_RXVLANGBLO_DEFAULT 0x0 + +struct rx_vlan_frames_good_bad_low { + a_uint32_t rxvlangblo:32; +}; + +union rx_vlan_frames_good_bad_low_u { + a_uint32_t val; + struct rx_vlan_frames_good_bad_low bf; +}; + +/*[register] RX_VLAN_FRAMES_GOOD_BAD_HIGH*/ +#define RX_VLAN_FRAMES_GOOD_BAD_HIGH +#define RX_VLAN_FRAMES_GOOD_BAD_HIGH_ADDRESS 0x99c +#define RX_VLAN_FRAMES_GOOD_BAD_HIGH_NUM 1 +#define RX_VLAN_FRAMES_GOOD_BAD_HIGH_INC 0x4000 +#define RX_VLAN_FRAMES_GOOD_BAD_HIGH_TYPE REG_TYPE_RO +#define RX_VLAN_FRAMES_GOOD_BAD_HIGH_DEFAULT 0x0 + /*[field] RXVLANGBHI*/ + #define RX_VLAN_FRAMES_GOOD_BAD_HIGH_RXVLANGBHI + #define RX_VLAN_FRAMES_GOOD_BAD_HIGH_RXVLANGBHI_OFFSET 0 + #define RX_VLAN_FRAMES_GOOD_BAD_HIGH_RXVLANGBHI_LEN 32 + #define RX_VLAN_FRAMES_GOOD_BAD_HIGH_RXVLANGBHI_DEFAULT 0x0 + +struct rx_vlan_frames_good_bad_high { + a_uint32_t rxvlangbhi:32; +}; + +union rx_vlan_frames_good_bad_high_u { + a_uint32_t val; + struct rx_vlan_frames_good_bad_high bf; +}; + +/*[register] RX_WATCHDOG_ERROR_FRAMES*/ +#define RX_WATCHDOG_ERROR_FRAMES +#define RX_WATCHDOG_ERROR_FRAMES_ADDRESS 0x9a0 +#define RX_WATCHDOG_ERROR_FRAMES_NUM 1 +#define RX_WATCHDOG_ERROR_FRAMES_INC 0x4000 +#define RX_WATCHDOG_ERROR_FRAMES_TYPE REG_TYPE_RO +#define RX_WATCHDOG_ERROR_FRAMES_DEFAULT 0x0 + /*[field] RXWDOGERR*/ + #define RX_WATCHDOG_ERROR_FRAMES_RXWDOGERR + #define RX_WATCHDOG_ERROR_FRAMES_RXWDOGERR_OFFSET 0 + #define RX_WATCHDOG_ERROR_FRAMES_RXWDOGERR_LEN 32 + #define RX_WATCHDOG_ERROR_FRAMES_RXWDOGERR_DEFAULT 0x0 + +struct rx_watchdog_error_frames { + a_uint32_t rxwdogerr:32; +}; + +union rx_watchdog_error_frames_u { + a_uint32_t val; + struct rx_watchdog_error_frames bf; +}; + +/*[register] RX_LPI_USEC_CNTR*/ +#define RX_LPI_USEC_CNTR +#define RX_LPI_USEC_CNTR_ADDRESS 0x9a4 +#define RX_LPI_USEC_CNTR_NUM 1 +#define RX_LPI_USEC_CNTR_INC 0x4000 +#define RX_LPI_USEC_CNTR_TYPE REG_TYPE_RO +#define RX_LPI_USEC_CNTR_DEFAULT 0x0 + /*[field] RXLPIUSC*/ + #define RX_LPI_USEC_CNTR_RXLPIUSC + #define RX_LPI_USEC_CNTR_RXLPIUSC_OFFSET 0 + #define RX_LPI_USEC_CNTR_RXLPIUSC_LEN 32 + #define RX_LPI_USEC_CNTR_RXLPIUSC_DEFAULT 0x0 + +struct rx_lpi_usec_cntr { + a_uint32_t rxlpiusc:32; +}; + +union rx_lpi_usec_cntr_u { + a_uint32_t val; + struct rx_lpi_usec_cntr bf; +}; + +/*[register] RX_LPI_TRAN_CNTR*/ +#define RX_LPI_TRAN_CNTR +#define RX_LPI_TRAN_CNTR_ADDRESS 0x9a8 +#define RX_LPI_TRAN_CNTR_NUM 1 +#define RX_LPI_TRAN_CNTR_INC 0x4000 +#define RX_LPI_TRAN_CNTR_TYPE REG_TYPE_RO +#define RX_LPI_TRAN_CNTR_DEFAULT 0x0 + /*[field] RXLPITRC*/ + #define RX_LPI_TRAN_CNTR_RXLPITRC + #define RX_LPI_TRAN_CNTR_RXLPITRC_OFFSET 0 + #define RX_LPI_TRAN_CNTR_RXLPITRC_LEN 32 + #define RX_LPI_TRAN_CNTR_RXLPITRC_DEFAULT 0x0 + +struct rx_lpi_tran_cntr { + a_uint32_t rxlpitrc:32; +}; + +union rx_lpi_tran_cntr_u { + a_uint32_t val; + struct rx_lpi_tran_cntr bf; +}; + +/*[register] RX_DISCARD_FRAME_COUNT_GOOD_BAD_LOW*/ +#define RX_DISCARD_FRAME_COUNT_GOOD_BAD_LOW +#define RX_DISCARD_FRAME_COUNT_GOOD_BAD_LOW_ADDRESS 0x9ac +#define RX_DISCARD_FRAME_COUNT_GOOD_BAD_LOW_NUM 1 +#define RX_DISCARD_FRAME_COUNT_GOOD_BAD_LOW_INC 0x4000 +#define RX_DISCARD_FRAME_COUNT_GOOD_BAD_LOW_TYPE REG_TYPE_RO +#define RX_DISCARD_FRAME_COUNT_GOOD_BAD_LOW_DEFAULT 0x0 + /*[field] RXDFCNTGBLO*/ + #define RX_DISCARD_FRAME_COUNT_GOOD_BAD_LOW_RXDFCNTGBLO + #define RX_DISCARD_FRAME_COUNT_GOOD_BAD_LOW_RXDFCNTGBLO_OFFSET 0 + #define RX_DISCARD_FRAME_COUNT_GOOD_BAD_LOW_RXDFCNTGBLO_LEN 32 + #define RX_DISCARD_FRAME_COUNT_GOOD_BAD_LOW_RXDFCNTGBLO_DEFAULT 0x0 + +struct rx_discard_frame_count_good_bad_low { + a_uint32_t rxdfcntgblo:32; +}; + +union rx_discard_frame_count_good_bad_low_u { + a_uint32_t val; + struct rx_discard_frame_count_good_bad_low bf; +}; + +/*[register] RX_DISCARD_FRAME_COUNT_GOOD_BAD_HIGH*/ +#define RX_DISCARD_FRAME_COUNT_GOOD_BAD_HIGH +#define RX_DISCARD_FRAME_COUNT_GOOD_BAD_HIGH_ADDRESS 0x9b0 +#define RX_DISCARD_FRAME_COUNT_GOOD_BAD_HIGH_NUM 1 +#define RX_DISCARD_FRAME_COUNT_GOOD_BAD_HIGH_INC 0x4000 +#define RX_DISCARD_FRAME_COUNT_GOOD_BAD_HIGH_TYPE REG_TYPE_RO +#define RX_DISCARD_FRAME_COUNT_GOOD_BAD_HIGH_DEFAULT 0x0 + /*[field] RXDFCNTGBHI*/ + #define RX_DISCARD_FRAME_COUNT_GOOD_BAD_HIGH_RXDFCNTGBHI + #define RX_DISCARD_FRAME_COUNT_GOOD_BAD_HIGH_RXDFCNTGBHI_OFFSET 0 + #define RX_DISCARD_FRAME_COUNT_GOOD_BAD_HIGH_RXDFCNTGBHI_LEN 32 + #define RX_DISCARD_FRAME_COUNT_GOOD_BAD_HIGH_RXDFCNTGBHI_DEFAULT 0x0 + +struct rx_discard_frame_count_good_bad_high { + a_uint32_t rxdfcntgbhi:32; +}; + +union rx_discard_frame_count_good_bad_high_u { + a_uint32_t val; + struct rx_discard_frame_count_good_bad_high bf; +}; + +/*[register] RX_DISCARD_OCTET_COUNT_GOOD_BAD_LOW*/ +#define RX_DISCARD_OCTET_COUNT_GOOD_BAD_LOW +#define RX_DISCARD_OCTET_COUNT_GOOD_BAD_LOW_ADDRESS 0x9b4 +#define RX_DISCARD_OCTET_COUNT_GOOD_BAD_LOW_NUM 1 +#define RX_DISCARD_OCTET_COUNT_GOOD_BAD_LOW_INC 0x4000 +#define RX_DISCARD_OCTET_COUNT_GOOD_BAD_LOW_TYPE REG_TYPE_RO +#define RX_DISCARD_OCTET_COUNT_GOOD_BAD_LOW_DEFAULT 0x0 + /*[field] RXDOCNTGBLO*/ + #define RX_DISCARD_OCTET_COUNT_GOOD_BAD_LOW_RXDOCNTGBLO + #define RX_DISCARD_OCTET_COUNT_GOOD_BAD_LOW_RXDOCNTGBLO_OFFSET 0 + #define RX_DISCARD_OCTET_COUNT_GOOD_BAD_LOW_RXDOCNTGBLO_LEN 32 + #define RX_DISCARD_OCTET_COUNT_GOOD_BAD_LOW_RXDOCNTGBLO_DEFAULT 0x0 + +struct rx_discard_octet_count_good_bad_low { + a_uint32_t rxdocntgblo:32; +}; + +union rx_discard_octet_count_good_bad_low_u { + a_uint32_t val; + struct rx_discard_octet_count_good_bad_low bf; +}; + +/*[register] RX_DISCARD_OCTET_COUNT_GOOD_BAD_HIGH*/ +#define RX_DISCARD_OCTET_COUNT_GOOD_BAD_HIGH +#define RX_DISCARD_OCTET_COUNT_GOOD_BAD_HIGH_ADDRESS 0x9b8 +#define RX_DISCARD_OCTET_COUNT_GOOD_BAD_HIGH_NUM 1 +#define RX_DISCARD_OCTET_COUNT_GOOD_BAD_HIGH_INC 0x4000 +#define RX_DISCARD_OCTET_COUNT_GOOD_BAD_HIGH_TYPE REG_TYPE_RO +#define RX_DISCARD_OCTET_COUNT_GOOD_BAD_HIGH_DEFAULT 0x0 + /*[field] RXDOCNTGBHI*/ + #define RX_DISCARD_OCTET_COUNT_GOOD_BAD_HIGH_RXDOCNTGBHI + #define RX_DISCARD_OCTET_COUNT_GOOD_BAD_HIGH_RXDOCNTGBHI_OFFSET 0 + #define RX_DISCARD_OCTET_COUNT_GOOD_BAD_HIGH_RXDOCNTGBHI_LEN 32 + #define RX_DISCARD_OCTET_COUNT_GOOD_BAD_HIGH_RXDOCNTGBHI_DEFAULT 0x0 + +struct rx_discard_octet_count_good_bad_high { + a_uint32_t rxdocntgbhi:32; +}; + +union rx_discard_octet_count_good_bad_high_u { + a_uint32_t val; + struct rx_discard_octet_count_good_bad_high bf; +}; + + + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_xgportctrl.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_xgportctrl.h new file mode 100755 index 000000000..c55a104bb --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_xgportctrl.h @@ -0,0 +1,2758 @@ +/* + * 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 + * @{ + */ +#ifndef _HPPE_XGPORTCTRL_H_ +#define _HPPE_XGPORTCTRL_H_ + +#define MAC_TX_CONFIGURATION_MAX_ENTRY 2 +#define MAC_RX_CONFIGURATION_MAX_ENTRY 2 +#define MAC_PACKET_FILTER_MAX_ENTRY 2 +#define MAC_WATCHDOG_TIMEOUT_MAX_ENTRY 2 +#define MAC_VLAN_TAG_MAX_ENTRY 2 +#define MAC_RX_ETH_TYPE_MATCH_MAX_ENTRY 2 +#define MAC_Q0_TX_FLOW_CTRL_MAX_ENTRY 2 +#define MAC_RX_FLOW_CTRL_MAX_ENTRY 2 +#define MAC_INTERRUPT_STATUS_MAX_ENTRY 2 +#define MAC_INTERRUPT_ENABLE_MAX_ENTRY 2 +#define MAC_RX_TX_STATUS_MAX_ENTRY 2 +#define MAC_LPI_CONTROL_STATUS_MAX_ENTRY 2 +#define MAC_LPI_TIMERS_CONTROL_MAX_ENTRY 2 +#define MAC_LPI_AUTO_ENTRY_TIMER_MAX_ENTRY 2 +#define MAC_1US_TIC_COUNTER_MAX_ENTRY 2 +#define MAC_ADDRESS0_HIGH_MAX_ENTRY 2 +#define MAC_ADDRESS0_LOW_MAX_ENTRY 2 +#define MMC_RECEIVE_INTERRUPT_MAX_ENTRY 2 +#define MMC_TRANSMIT_INTERRUPT_MAX_ENTRY 2 +#define MMC_RECEIVE_INTERRUPT_ENABLE_MAX_ENTRY 2 +#define MMC_TRANSMIT_INTERRUPT_ENABLE_MAX_ENTRY 2 + +sw_error_t +hppe_mac_tx_configuration_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_tx_configuration_u *value); + +sw_error_t +hppe_mac_tx_configuration_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_tx_configuration_u *value); + +sw_error_t +hppe_mac_rx_configuration_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_rx_configuration_u *value); + +sw_error_t +hppe_mac_rx_configuration_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_rx_configuration_u *value); + +sw_error_t +hppe_mac_packet_filter_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_packet_filter_u *value); + +sw_error_t +hppe_mac_packet_filter_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_packet_filter_u *value); + +sw_error_t +hppe_mac_watchdog_timeout_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_watchdog_timeout_u *value); + +sw_error_t +hppe_mac_watchdog_timeout_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_watchdog_timeout_u *value); + +sw_error_t +hppe_mac_vlan_tag_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_vlan_tag_u *value); + +sw_error_t +hppe_mac_vlan_tag_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_vlan_tag_u *value); + +sw_error_t +hppe_mac_rx_eth_type_match_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_rx_eth_type_match_u *value); + +sw_error_t +hppe_mac_rx_eth_type_match_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_rx_eth_type_match_u *value); + +sw_error_t +hppe_mac_q0_tx_flow_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_q0_tx_flow_ctrl_u *value); + +sw_error_t +hppe_mac_q0_tx_flow_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_q0_tx_flow_ctrl_u *value); + +sw_error_t +hppe_mac_rx_flow_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_rx_flow_ctrl_u *value); + +sw_error_t +hppe_mac_rx_flow_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_rx_flow_ctrl_u *value); + +sw_error_t +hppe_mac_interrupt_status_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_interrupt_status_u *value); + +sw_error_t +hppe_mac_interrupt_status_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_interrupt_status_u *value); + +sw_error_t +hppe_mac_interrupt_enable_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_interrupt_enable_u *value); + +sw_error_t +hppe_mac_interrupt_enable_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_interrupt_enable_u *value); + +sw_error_t +hppe_mac_rx_tx_status_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_rx_tx_status_u *value); + +sw_error_t +hppe_mac_rx_tx_status_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_rx_tx_status_u *value); + +sw_error_t +hppe_mac_lpi_control_status_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_lpi_control_status_u *value); + +sw_error_t +hppe_mac_lpi_control_status_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_lpi_control_status_u *value); + +sw_error_t +hppe_mac_lpi_timers_control_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_lpi_timers_control_u *value); + +sw_error_t +hppe_mac_lpi_timers_control_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_lpi_timers_control_u *value); + +sw_error_t +hppe_mac_lpi_auto_entry_timer_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_lpi_auto_entry_timer_u *value); + +sw_error_t +hppe_mac_lpi_auto_entry_timer_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_lpi_auto_entry_timer_u *value); + +sw_error_t +hppe_mac_1us_tic_counter_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_1us_tic_counter_u *value); + +sw_error_t +hppe_mac_1us_tic_counter_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_1us_tic_counter_u *value); + +sw_error_t +hppe_mac_address0_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_address0_high_u *value); + +sw_error_t +hppe_mac_address0_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_address0_high_u *value); + +sw_error_t +hppe_mac_address0_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_address0_low_u *value); + +sw_error_t +hppe_mac_address0_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_address0_low_u *value); + +sw_error_t +hppe_mmc_receive_interrupt_get( + a_uint32_t dev_id, + a_uint32_t index, + union mmc_receive_interrupt_u *value); + +sw_error_t +hppe_mmc_receive_interrupt_set( + a_uint32_t dev_id, + a_uint32_t index, + union mmc_receive_interrupt_u *value); + +sw_error_t +hppe_mmc_transmit_interrupt_get( + a_uint32_t dev_id, + a_uint32_t index, + union mmc_transmit_interrupt_u *value); + +sw_error_t +hppe_mmc_transmit_interrupt_set( + a_uint32_t dev_id, + a_uint32_t index, + union mmc_transmit_interrupt_u *value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_get( + a_uint32_t dev_id, + a_uint32_t index, + union mmc_receive_interrupt_enable_u *value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_set( + a_uint32_t dev_id, + a_uint32_t index, + union mmc_receive_interrupt_enable_u *value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_get( + a_uint32_t dev_id, + a_uint32_t index, + union mmc_transmit_interrupt_enable_u *value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_set( + a_uint32_t dev_id, + a_uint32_t index, + union mmc_transmit_interrupt_enable_u *value); + +sw_error_t +hppe_mac_tx_configuration_vne_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_tx_configuration_vne_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_tx_configuration_ddic_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_tx_configuration_ddic_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_tx_configuration_te_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_tx_configuration_te_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_tx_configuration_ipg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_tx_configuration_ipg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_tx_configuration_ism_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_tx_configuration_ism_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_tx_configuration_ifp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_tx_configuration_ifp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_tx_configuration_sarc_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_tx_configuration_sarc_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_tx_configuration_isr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_tx_configuration_isr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_tx_configuration_ss_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_tx_configuration_ss_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_tx_configuration_g9991en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_tx_configuration_g9991en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_tx_configuration_uss_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_tx_configuration_uss_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_tx_configuration_vnm_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_tx_configuration_vnm_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_tx_configuration_jd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_tx_configuration_jd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_rx_configuration_lm_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_rx_configuration_lm_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_rx_configuration_je_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_rx_configuration_je_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_rx_configuration_arpen_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_rx_configuration_arpen_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_rx_configuration_elen_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_rx_configuration_elen_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_rx_configuration_gmpslce_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_rx_configuration_gmpslce_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_rx_configuration_hdsms_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_rx_configuration_hdsms_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_rx_configuration_spen_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_rx_configuration_spen_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_rx_configuration_usp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_rx_configuration_usp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_rx_configuration_ipc_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_rx_configuration_ipc_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_rx_configuration_gpsl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_rx_configuration_gpsl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_rx_configuration_re_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_rx_configuration_re_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_rx_configuration_cst_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_rx_configuration_cst_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_rx_configuration_dcrcc_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_rx_configuration_dcrcc_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_rx_configuration_wd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_rx_configuration_wd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_rx_configuration_acs_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_rx_configuration_acs_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_rx_configuration_s2kp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_rx_configuration_s2kp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_packet_filter_pcf_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_packet_filter_pcf_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_packet_filter_hmc_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_packet_filter_hmc_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_packet_filter_dntu_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_packet_filter_dntu_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_packet_filter_saf_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_packet_filter_saf_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_packet_filter_dbf_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_packet_filter_dbf_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_packet_filter_huc_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_packet_filter_huc_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_packet_filter_vtfe_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_packet_filter_vtfe_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_packet_filter_daif_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_packet_filter_daif_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_packet_filter_ra_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_packet_filter_ra_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_packet_filter_hpf_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_packet_filter_hpf_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_packet_filter_pm_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_packet_filter_pm_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_packet_filter_vucc_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_packet_filter_vucc_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_packet_filter_pr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_packet_filter_pr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_packet_filter_ipfe_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_packet_filter_ipfe_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_packet_filter_saif_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_packet_filter_saif_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_watchdog_timeout_pwe_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_watchdog_timeout_pwe_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_watchdog_timeout_wto_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_watchdog_timeout_wto_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_vlan_tag_eivls_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_vlan_tag_eivls_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_vlan_tag_vthm_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_vlan_tag_vthm_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_vlan_tag_vl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_vlan_tag_vl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_vlan_tag_dovltc_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_vlan_tag_dovltc_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_vlan_tag_etv_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_vlan_tag_etv_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_vlan_tag_erivlt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_vlan_tag_erivlt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_vlan_tag_eivlrxs_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_vlan_tag_eivlrxs_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_vlan_tag_vtim_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_vlan_tag_vtim_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_vlan_tag_edvlp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_vlan_tag_edvlp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_vlan_tag_evlrxs_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_vlan_tag_evlrxs_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_vlan_tag_evls_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_vlan_tag_evls_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_vlan_tag_esvl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_vlan_tag_esvl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_vlan_tag_ersvlm_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_vlan_tag_ersvlm_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_rx_eth_type_match_et_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_rx_eth_type_match_et_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_q0_tx_flow_ctrl_pt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_q0_tx_flow_ctrl_pt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_q0_tx_flow_ctrl_plt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_q0_tx_flow_ctrl_plt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_q0_tx_flow_ctrl_tfe_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_q0_tx_flow_ctrl_tfe_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_q0_tx_flow_ctrl_fcb_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_q0_tx_flow_ctrl_fcb_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_q0_tx_flow_ctrl_dapq_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_q0_tx_flow_ctrl_dapq_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_rx_flow_ctrl_pfce_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_rx_flow_ctrl_pfce_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_rx_flow_ctrl_up_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_rx_flow_ctrl_up_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_rx_flow_ctrl_rfe_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_rx_flow_ctrl_rfe_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_interrupt_status_txesis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_interrupt_status_txesis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_interrupt_status_gpiis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_interrupt_status_gpiis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_interrupt_status_tsis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_interrupt_status_tsis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_interrupt_status_mmctxis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_interrupt_status_mmctxis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_interrupt_status_ls_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_interrupt_status_ls_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_interrupt_status_mmcrxis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_interrupt_status_mmcrxis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_interrupt_status_smi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_interrupt_status_smi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_interrupt_status_pmtis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_interrupt_status_pmtis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_interrupt_status_rxesis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_interrupt_status_rxesis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_interrupt_status_lpiis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_interrupt_status_lpiis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_interrupt_enable_tsie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_interrupt_enable_tsie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_interrupt_enable_lpiie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_interrupt_enable_lpiie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_interrupt_enable_txesie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_interrupt_enable_txesie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_interrupt_enable_pmtie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_interrupt_enable_pmtie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_interrupt_enable_rxesie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_interrupt_enable_rxesie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_rx_tx_status_tjt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_rx_tx_status_tjt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_rx_tx_status_rwt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_rx_tx_status_rwt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_lpi_control_status_tlpien_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_lpi_control_status_tlpien_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_lpi_control_status_lpitcse_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_lpi_control_status_lpitcse_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_lpi_control_status_rxrstp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_lpi_control_status_rxrstp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_lpi_control_status_lpite_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_lpi_control_status_lpite_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_lpi_control_status_pls_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_lpi_control_status_pls_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_lpi_control_status_rlpiex_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_lpi_control_status_rlpiex_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_lpi_control_status_rlpien_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_lpi_control_status_rlpien_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_lpi_control_status_rlpist_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_lpi_control_status_rlpist_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_lpi_control_status_tlpist_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_lpi_control_status_tlpist_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_lpi_control_status_txrstp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_lpi_control_status_txrstp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_lpi_control_status_plsdis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_lpi_control_status_plsdis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_lpi_control_status_lpitxa_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_lpi_control_status_lpitxa_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_lpi_control_status_tlpiex_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_lpi_control_status_tlpiex_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_lpi_control_status_lpitxen_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_lpi_control_status_lpitxen_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_lpi_timers_control_lst_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_lpi_timers_control_lst_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_lpi_timers_control_twt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_lpi_timers_control_twt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_lpi_auto_entry_timer_lpiet_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_lpi_auto_entry_timer_lpiet_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_1us_tic_counter_tic_1us_cntr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_1us_tic_counter_tic_1us_cntr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_address0_high_addrhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_address0_high_addrhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_address0_high_ae_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_address0_high_ae_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_address0_high_dcs_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_address0_high_dcs_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mac_address0_low_addrlo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mac_address0_low_addrlo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_rxorangefis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_rxorangefis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_rxlenerfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_rxlenerfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_rx65t127octgbfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_rx65t127octgbfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_rxprmmcis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_rxprmmcis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_rx512t1023octgbfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_rx512t1023octgbfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_rxgboctis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_rxgboctis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_rxlpiuscis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_rxlpiuscis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_rxjaberfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_rxjaberfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_rxvlangbfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_rxvlangbfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_rxpausfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_rxpausfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_rxcrcerfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_rxcrcerfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_rxdisocgbis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_rxdisocgbis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_rxwdogfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_rxwdogfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_rx128t255octgbfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_rx128t255octgbfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_rxdisfcgbis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_rxdisfcgbis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_rxosizegfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_rxosizegfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_rx1024tmaxoctgbfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_rx1024tmaxoctgbfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_rxruntfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_rxruntfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_rxmcgfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_rxmcgfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_rx256t511octgbfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_rx256t511octgbfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_rx64octgbfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_rx64octgbfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_rxfovfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_rxfovfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_rxgoctis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_rxgoctis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_rxgbfrmis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_rxgbfrmis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_rxlpitrcis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_rxlpitrcis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_rxbcgfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_rxbcgfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_rxusizegfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_rxusizegfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_rxucgfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_rxucgfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_txgbfrmis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_txgbfrmis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_txprmmcis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_txprmmcis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_tx1024tmaxoctgbfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_tx1024tmaxoctgbfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_tx256t511octgbfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_tx256t511octgbfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_txlpitrcis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_txlpitrcis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_txbcgfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_txbcgfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_tx64octgbfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_tx64octgbfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_txlpiuscis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_txlpiuscis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_txuflowerfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_txuflowerfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_txbcgbfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_txbcgbfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_txpausfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_txpausfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_txvlangfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_txvlangfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_txgboctis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_txgboctis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_txgfrmis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_txgfrmis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_tx512t1023octgbfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_tx512t1023octgbfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_txmcgfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_txmcgfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_txucgbfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_txucgbfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_tx65t127octgbfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_tx65t127octgbfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_txmcgbfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_txmcgbfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_tx128t255octgbfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_tx128t255octgbfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_txgoctis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_txgoctis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxprmmcise_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxprmmcise_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rx65t127octgbfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rx65t127octgbfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxruntfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxruntfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxcrcerfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxcrcerfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rx256t511octgbfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rx256t511octgbfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxlenerfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxlenerfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxusizegfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxusizegfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxosizegfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxosizegfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxfovfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxfovfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxmcgfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxmcgfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxvlangbfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxvlangbfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxwdogfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxwdogfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxdisocie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxdisocie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxgbfrmie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxgbfrmie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxjaberfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxjaberfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxlpiuscie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxlpiuscie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxucgfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxucgfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rx1024tmaxoctgbfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rx1024tmaxoctgbfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxpausfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxpausfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxdisfcie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxdisfcie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxgoctie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxgoctie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxgboctie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxgboctie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rx128t255octgbfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rx128t255octgbfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxlpitrcie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxlpitrcie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxbcgfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxbcgfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rx64octgbfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rx64octgbfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxorangefie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxorangefie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rx512t1023octgbfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_receive_interrupt_enable_rx512t1023octgbfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txucgbfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txucgbfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_tx64octgbfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_tx64octgbfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txbcgfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txbcgfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txgbfrmie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txgbfrmie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txgfrmie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txgfrmie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txgoctie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txgoctie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txbcgbfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txbcgbfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txlpitrcie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txlpitrcie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txvlangfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txvlangfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txpausfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txpausfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txgboctie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txgboctie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txmcgfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txmcgfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txuflowerfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txuflowerfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txlpiuscie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txlpiuscie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_tx256t511octgbfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_tx256t511octgbfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_tx65t127octgbfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_tx65t127octgbfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_tx128t255octgbfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_tx128t255octgbfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_tx512t1023octgbfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_tx512t1023octgbfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_tx1024tmaxoctgbfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_tx1024tmaxoctgbfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txprmmcise_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txprmmcise_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txmcgbfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value); + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txmcgbfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value); + +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_xgportctrl_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_xgportctrl_reg.h new file mode 100755 index 000000000..2adf06375 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hppe/hppe_xgportctrl_reg.h @@ -0,0 +1,1627 @@ +/* + * 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 + * @{ + */ +#ifndef HPPE_XGPORTCTRL_REG_H +#define HPPE_XGPORTCTRL_REG_H + +/*[register] MAC_TX_CONFIGURATION*/ +#define MAC_TX_CONFIGURATION +#define MAC_TX_CONFIGURATION_ADDRESS 0x0 +#define MAC_TX_CONFIGURATION_NUM 2 +#define MAC_TX_CONFIGURATION_INC 0x4000 +#define MAC_TX_CONFIGURATION_TYPE REG_TYPE_RW +#define MAC_TX_CONFIGURATION_DEFAULT 0x4000000 + /*[field] TE*/ + #define MAC_TX_CONFIGURATION_TE + #define MAC_TX_CONFIGURATION_TE_OFFSET 0 + #define MAC_TX_CONFIGURATION_TE_LEN 1 + #define MAC_TX_CONFIGURATION_TE_DEFAULT 0x0 + /*[field] DDIC*/ + #define MAC_TX_CONFIGURATION_DDIC + #define MAC_TX_CONFIGURATION_DDIC_OFFSET 1 + #define MAC_TX_CONFIGURATION_DDIC_LEN 1 + #define MAC_TX_CONFIGURATION_DDIC_DEFAULT 0x0 + /*[field] ISM*/ + #define MAC_TX_CONFIGURATION_ISM + #define MAC_TX_CONFIGURATION_ISM_OFFSET 3 + #define MAC_TX_CONFIGURATION_ISM_LEN 1 + #define MAC_TX_CONFIGURATION_ISM_DEFAULT 0x0 + /*[field] ISR*/ + #define MAC_TX_CONFIGURATION_ISR + #define MAC_TX_CONFIGURATION_ISR_OFFSET 4 + #define MAC_TX_CONFIGURATION_ISR_LEN 4 + #define MAC_TX_CONFIGURATION_ISR_DEFAULT 0x0 + /*[field] IPG*/ + #define MAC_TX_CONFIGURATION_IPG + #define MAC_TX_CONFIGURATION_IPG_OFFSET 8 + #define MAC_TX_CONFIGURATION_IPG_LEN 3 + #define MAC_TX_CONFIGURATION_IPG_DEFAULT 0x0 + /*[field] IFP*/ + #define MAC_TX_CONFIGURATION_IFP + #define MAC_TX_CONFIGURATION_IFP_OFFSET 11 + #define MAC_TX_CONFIGURATION_IFP_LEN 1 + #define MAC_TX_CONFIGURATION_IFP_DEFAULT 0x0 + /*[field] JD*/ + #define MAC_TX_CONFIGURATION_JD + #define MAC_TX_CONFIGURATION_JD_OFFSET 16 + #define MAC_TX_CONFIGURATION_JD_LEN 1 + #define MAC_TX_CONFIGURATION_JD_DEFAULT 0x0 + /*[field] SARC*/ + #define MAC_TX_CONFIGURATION_SARC + #define MAC_TX_CONFIGURATION_SARC_OFFSET 20 + #define MAC_TX_CONFIGURATION_SARC_LEN 3 + #define MAC_TX_CONFIGURATION_SARC_DEFAULT 0x0 + /*[field] VNE*/ + #define MAC_TX_CONFIGURATION_VNE + #define MAC_TX_CONFIGURATION_VNE_OFFSET 24 + #define MAC_TX_CONFIGURATION_VNE_LEN 1 + #define MAC_TX_CONFIGURATION_VNE_DEFAULT 0x0 + /*[field] VNM*/ + #define MAC_TX_CONFIGURATION_VNM + #define MAC_TX_CONFIGURATION_VNM_OFFSET 25 + #define MAC_TX_CONFIGURATION_VNM_LEN 1 + #define MAC_TX_CONFIGURATION_VNM_DEFAULT 0x0 + /*[field] G9991EN*/ + #define MAC_TX_CONFIGURATION_G9991EN + #define MAC_TX_CONFIGURATION_G9991EN_OFFSET 28 + #define MAC_TX_CONFIGURATION_G9991EN_LEN 1 + #define MAC_TX_CONFIGURATION_G9991EN_DEFAULT 0x0 + /*[field] SS*/ + #define MAC_TX_CONFIGURATION_SS + #define MAC_TX_CONFIGURATION_SS_OFFSET 29 + #define MAC_TX_CONFIGURATION_SS_LEN 2 + #define MAC_TX_CONFIGURATION_SS_DEFAULT 0x0 + /*[field] USS*/ + #define MAC_TX_CONFIGURATION_USS + #define MAC_TX_CONFIGURATION_USS_OFFSET 31 + #define MAC_TX_CONFIGURATION_USS_LEN 1 + #define MAC_TX_CONFIGURATION_USS_DEFAULT 0x0 + +struct mac_tx_configuration { + a_uint32_t te:1; + a_uint32_t ddic:1; + a_uint32_t _reserved0:1; + a_uint32_t ism:1; + a_uint32_t isr:4; + a_uint32_t ipg:3; + a_uint32_t ifp:1; + a_uint32_t _reserved1:4; + a_uint32_t jd:1; + a_uint32_t _reserved2:3; + a_uint32_t sarc:3; + a_uint32_t _reserved3:1; + a_uint32_t vne:1; + a_uint32_t vnm:1; + a_uint32_t _reserved4:2; + a_uint32_t g9991en:1; + a_uint32_t ss:2; + a_uint32_t uss:1; +}; + +union mac_tx_configuration_u { + a_uint32_t val; + struct mac_tx_configuration bf; +}; + +/*[register] MAC_RX_CONFIGURATION*/ +#define MAC_RX_CONFIGURATION +#define MAC_RX_CONFIGURATION_ADDRESS 0x4 +#define MAC_RX_CONFIGURATION_NUM 2 +#define MAC_RX_CONFIGURATION_INC 0x4000 +#define MAC_RX_CONFIGURATION_TYPE REG_TYPE_RW +#define MAC_RX_CONFIGURATION_DEFAULT 0x0 + /*[field] RE*/ + #define MAC_RX_CONFIGURATION_RE + #define MAC_RX_CONFIGURATION_RE_OFFSET 0 + #define MAC_RX_CONFIGURATION_RE_LEN 1 + #define MAC_RX_CONFIGURATION_RE_DEFAULT 0x0 + /*[field] ACS*/ + #define MAC_RX_CONFIGURATION_ACS + #define MAC_RX_CONFIGURATION_ACS_OFFSET 1 + #define MAC_RX_CONFIGURATION_ACS_LEN 1 + #define MAC_RX_CONFIGURATION_ACS_DEFAULT 0x0 + /*[field] CST*/ + #define MAC_RX_CONFIGURATION_CST + #define MAC_RX_CONFIGURATION_CST_OFFSET 2 + #define MAC_RX_CONFIGURATION_CST_LEN 1 + #define MAC_RX_CONFIGURATION_CST_DEFAULT 0x0 + /*[field] DCRCC*/ + #define MAC_RX_CONFIGURATION_DCRCC + #define MAC_RX_CONFIGURATION_DCRCC_OFFSET 3 + #define MAC_RX_CONFIGURATION_DCRCC_LEN 1 + #define MAC_RX_CONFIGURATION_DCRCC_DEFAULT 0x0 + /*[field] SPEN*/ + #define MAC_RX_CONFIGURATION_SPEN + #define MAC_RX_CONFIGURATION_SPEN_OFFSET 4 + #define MAC_RX_CONFIGURATION_SPEN_LEN 1 + #define MAC_RX_CONFIGURATION_SPEN_DEFAULT 0x0 + /*[field] USP*/ + #define MAC_RX_CONFIGURATION_USP + #define MAC_RX_CONFIGURATION_USP_OFFSET 5 + #define MAC_RX_CONFIGURATION_USP_LEN 1 + #define MAC_RX_CONFIGURATION_USP_DEFAULT 0x0 + /*[field] GMPSLCE*/ + #define MAC_RX_CONFIGURATION_GMPSLCE + #define MAC_RX_CONFIGURATION_GMPSLCE_OFFSET 6 + #define MAC_RX_CONFIGURATION_GMPSLCE_LEN 1 + #define MAC_RX_CONFIGURATION_GMPSLCE_DEFAULT 0x0 + /*[field] WD*/ + #define MAC_RX_CONFIGURATION_WD + #define MAC_RX_CONFIGURATION_WD_OFFSET 7 + #define MAC_RX_CONFIGURATION_WD_LEN 1 + #define MAC_RX_CONFIGURATION_WD_DEFAULT 0x0 + /*[field] JE*/ + #define MAC_RX_CONFIGURATION_JE + #define MAC_RX_CONFIGURATION_JE_OFFSET 8 + #define MAC_RX_CONFIGURATION_JE_LEN 1 + #define MAC_RX_CONFIGURATION_JE_DEFAULT 0x0 + /*[field] IPC*/ + #define MAC_RX_CONFIGURATION_IPC + #define MAC_RX_CONFIGURATION_IPC_OFFSET 9 + #define MAC_RX_CONFIGURATION_IPC_LEN 1 + #define MAC_RX_CONFIGURATION_IPC_DEFAULT 0x0 + /*[field] LM*/ + #define MAC_RX_CONFIGURATION_LM + #define MAC_RX_CONFIGURATION_LM_OFFSET 10 + #define MAC_RX_CONFIGURATION_LM_LEN 1 + #define MAC_RX_CONFIGURATION_LM_DEFAULT 0x0 + /*[field] S2KP*/ + #define MAC_RX_CONFIGURATION_S2KP + #define MAC_RX_CONFIGURATION_S2KP_OFFSET 11 + #define MAC_RX_CONFIGURATION_S2KP_LEN 1 + #define MAC_RX_CONFIGURATION_S2KP_DEFAULT 0x0 + /*[field] HDSMS*/ + #define MAC_RX_CONFIGURATION_HDSMS + #define MAC_RX_CONFIGURATION_HDSMS_OFFSET 12 + #define MAC_RX_CONFIGURATION_HDSMS_LEN 3 + #define MAC_RX_CONFIGURATION_HDSMS_DEFAULT 0x0 + /*[field] GPSL*/ + #define MAC_RX_CONFIGURATION_GPSL + #define MAC_RX_CONFIGURATION_GPSL_OFFSET 16 + #define MAC_RX_CONFIGURATION_GPSL_LEN 14 + #define MAC_RX_CONFIGURATION_GPSL_DEFAULT 0x0 + /*[field] ELEN*/ + #define MAC_RX_CONFIGURATION_ELEN + #define MAC_RX_CONFIGURATION_ELEN_OFFSET 30 + #define MAC_RX_CONFIGURATION_ELEN_LEN 1 + #define MAC_RX_CONFIGURATION_ELEN_DEFAULT 0x0 + /*[field] ARPEN*/ + #define MAC_RX_CONFIGURATION_ARPEN + #define MAC_RX_CONFIGURATION_ARPEN_OFFSET 31 + #define MAC_RX_CONFIGURATION_ARPEN_LEN 1 + #define MAC_RX_CONFIGURATION_ARPEN_DEFAULT 0x0 + +struct mac_rx_configuration { + a_uint32_t re:1; + a_uint32_t acs:1; + a_uint32_t cst:1; + a_uint32_t dcrcc:1; + a_uint32_t spen:1; + a_uint32_t usp:1; + a_uint32_t gmpslce:1; + a_uint32_t wd:1; + a_uint32_t je:1; + a_uint32_t ipc:1; + a_uint32_t lm:1; + a_uint32_t s2kp:1; + a_uint32_t hdsms:3; + a_uint32_t _reserved0:1; + a_uint32_t gpsl:14; + a_uint32_t elen:1; + a_uint32_t arpen:1; +}; + +union mac_rx_configuration_u { + a_uint32_t val; + struct mac_rx_configuration bf; +}; + +/*[register] MAC_PACKET_FILTER*/ +#define MAC_PACKET_FILTER +#define MAC_PACKET_FILTER_ADDRESS 0x8 +#define MAC_PACKET_FILTER_NUM 2 +#define MAC_PACKET_FILTER_INC 0x4000 +#define MAC_PACKET_FILTER_TYPE REG_TYPE_RW +#define MAC_PACKET_FILTER_DEFAULT 0x0 + /*[field] PR*/ + #define MAC_PACKET_FILTER_PR + #define MAC_PACKET_FILTER_PR_OFFSET 0 + #define MAC_PACKET_FILTER_PR_LEN 1 + #define MAC_PACKET_FILTER_PR_DEFAULT 0x0 + /*[field] HUC*/ + #define MAC_PACKET_FILTER_HUC + #define MAC_PACKET_FILTER_HUC_OFFSET 1 + #define MAC_PACKET_FILTER_HUC_LEN 1 + #define MAC_PACKET_FILTER_HUC_DEFAULT 0x0 + /*[field] HMC*/ + #define MAC_PACKET_FILTER_HMC + #define MAC_PACKET_FILTER_HMC_OFFSET 2 + #define MAC_PACKET_FILTER_HMC_LEN 1 + #define MAC_PACKET_FILTER_HMC_DEFAULT 0x0 + /*[field] DAIF*/ + #define MAC_PACKET_FILTER_DAIF + #define MAC_PACKET_FILTER_DAIF_OFFSET 3 + #define MAC_PACKET_FILTER_DAIF_LEN 1 + #define MAC_PACKET_FILTER_DAIF_DEFAULT 0x0 + /*[field] PM*/ + #define MAC_PACKET_FILTER_PM + #define MAC_PACKET_FILTER_PM_OFFSET 4 + #define MAC_PACKET_FILTER_PM_LEN 1 + #define MAC_PACKET_FILTER_PM_DEFAULT 0x0 + /*[field] DBF*/ + #define MAC_PACKET_FILTER_DBF + #define MAC_PACKET_FILTER_DBF_OFFSET 5 + #define MAC_PACKET_FILTER_DBF_LEN 1 + #define MAC_PACKET_FILTER_DBF_DEFAULT 0x0 + /*[field] PCF*/ + #define MAC_PACKET_FILTER_PCF + #define MAC_PACKET_FILTER_PCF_OFFSET 6 + #define MAC_PACKET_FILTER_PCF_LEN 2 + #define MAC_PACKET_FILTER_PCF_DEFAULT 0x0 + /*[field] SAIF*/ + #define MAC_PACKET_FILTER_SAIF + #define MAC_PACKET_FILTER_SAIF_OFFSET 8 + #define MAC_PACKET_FILTER_SAIF_LEN 1 + #define MAC_PACKET_FILTER_SAIF_DEFAULT 0x0 + /*[field] SAF*/ + #define MAC_PACKET_FILTER_SAF + #define MAC_PACKET_FILTER_SAF_OFFSET 9 + #define MAC_PACKET_FILTER_SAF_LEN 1 + #define MAC_PACKET_FILTER_SAF_DEFAULT 0x0 + /*[field] HPF*/ + #define MAC_PACKET_FILTER_HPF + #define MAC_PACKET_FILTER_HPF_OFFSET 10 + #define MAC_PACKET_FILTER_HPF_LEN 1 + #define MAC_PACKET_FILTER_HPF_DEFAULT 0x0 + /*[field] VTFE*/ + #define MAC_PACKET_FILTER_VTFE + #define MAC_PACKET_FILTER_VTFE_OFFSET 16 + #define MAC_PACKET_FILTER_VTFE_LEN 1 + #define MAC_PACKET_FILTER_VTFE_DEFAULT 0x0 + /*[field] IPFE*/ + #define MAC_PACKET_FILTER_IPFE + #define MAC_PACKET_FILTER_IPFE_OFFSET 20 + #define MAC_PACKET_FILTER_IPFE_LEN 1 + #define MAC_PACKET_FILTER_IPFE_DEFAULT 0x0 + /*[field] DNTU*/ + #define MAC_PACKET_FILTER_DNTU + #define MAC_PACKET_FILTER_DNTU_OFFSET 21 + #define MAC_PACKET_FILTER_DNTU_LEN 1 + #define MAC_PACKET_FILTER_DNTU_DEFAULT 0x0 + /*[field] VUCC*/ + #define MAC_PACKET_FILTER_VUCC + #define MAC_PACKET_FILTER_VUCC_OFFSET 22 + #define MAC_PACKET_FILTER_VUCC_LEN 1 + #define MAC_PACKET_FILTER_VUCC_DEFAULT 0x0 + /*[field] RA*/ + #define MAC_PACKET_FILTER_RA + #define MAC_PACKET_FILTER_RA_OFFSET 31 + #define MAC_PACKET_FILTER_RA_LEN 1 + #define MAC_PACKET_FILTER_RA_DEFAULT 0x0 + +struct mac_packet_filter { + a_uint32_t pr:1; + a_uint32_t huc:1; + a_uint32_t hmc:1; + a_uint32_t daif:1; + a_uint32_t pm:1; + a_uint32_t dbf:1; + a_uint32_t pcf:2; + a_uint32_t saif:1; + a_uint32_t saf:1; + a_uint32_t hpf:1; + a_uint32_t _reserved0:5; + a_uint32_t vtfe:1; + a_uint32_t _reserved1:3; + a_uint32_t ipfe:1; + a_uint32_t dntu:1; + a_uint32_t vucc:1; + a_uint32_t _reserved2:8; + a_uint32_t ra:1; +}; + +union mac_packet_filter_u { + a_uint32_t val; + struct mac_packet_filter bf; +}; + +/*[register] MAC_WATCHDOG_TIMEOUT*/ +#define MAC_WATCHDOG_TIMEOUT +#define MAC_WATCHDOG_TIMEOUT_ADDRESS 0xc +#define MAC_WATCHDOG_TIMEOUT_NUM 2 +#define MAC_WATCHDOG_TIMEOUT_INC 0x4000 +#define MAC_WATCHDOG_TIMEOUT_TYPE REG_TYPE_RW +#define MAC_WATCHDOG_TIMEOUT_DEFAULT 0x0 + /*[field] WTO*/ + #define MAC_WATCHDOG_TIMEOUT_WTO + #define MAC_WATCHDOG_TIMEOUT_WTO_OFFSET 0 + #define MAC_WATCHDOG_TIMEOUT_WTO_LEN 4 + #define MAC_WATCHDOG_TIMEOUT_WTO_DEFAULT 0x0 + /*[field] PWE*/ + #define MAC_WATCHDOG_TIMEOUT_PWE + #define MAC_WATCHDOG_TIMEOUT_PWE_OFFSET 8 + #define MAC_WATCHDOG_TIMEOUT_PWE_LEN 1 + #define MAC_WATCHDOG_TIMEOUT_PWE_DEFAULT 0x0 + +struct mac_watchdog_timeout { + a_uint32_t wto:4; + a_uint32_t _reserved0:4; + a_uint32_t pwe:1; + a_uint32_t _reserved1:23; +}; + +union mac_watchdog_timeout_u { + a_uint32_t val; + struct mac_watchdog_timeout bf; +}; + +/*[register] MAC_VLAN_TAG*/ +#define MAC_VLAN_TAG +#define MAC_VLAN_TAG_ADDRESS 0x50 +#define MAC_VLAN_TAG_NUM 2 +#define MAC_VLAN_TAG_INC 0x4000 +#define MAC_VLAN_TAG_TYPE REG_TYPE_RW +#define MAC_VLAN_TAG_DEFAULT 0x1b800000 + /*[field] VL*/ + #define MAC_VLAN_TAG_VL + #define MAC_VLAN_TAG_VL_OFFSET 0 + #define MAC_VLAN_TAG_VL_LEN 16 + #define MAC_VLAN_TAG_VL_DEFAULT 0x0 + /*[field] ETV*/ + #define MAC_VLAN_TAG_ETV + #define MAC_VLAN_TAG_ETV_OFFSET 16 + #define MAC_VLAN_TAG_ETV_LEN 1 + #define MAC_VLAN_TAG_ETV_DEFAULT 0x0 + /*[field] VTIM*/ + #define MAC_VLAN_TAG_VTIM + #define MAC_VLAN_TAG_VTIM_OFFSET 17 + #define MAC_VLAN_TAG_VTIM_LEN 1 + #define MAC_VLAN_TAG_VTIM_DEFAULT 0x0 + /*[field] ESVL*/ + #define MAC_VLAN_TAG_ESVL + #define MAC_VLAN_TAG_ESVL_OFFSET 18 + #define MAC_VLAN_TAG_ESVL_LEN 1 + #define MAC_VLAN_TAG_ESVL_DEFAULT 0x0 + /*[field] ERSVLM*/ + #define MAC_VLAN_TAG_ERSVLM + #define MAC_VLAN_TAG_ERSVLM_OFFSET 19 + #define MAC_VLAN_TAG_ERSVLM_LEN 1 + #define MAC_VLAN_TAG_ERSVLM_DEFAULT 0x0 + /*[field] DOVLTC*/ + #define MAC_VLAN_TAG_DOVLTC + #define MAC_VLAN_TAG_DOVLTC_OFFSET 20 + #define MAC_VLAN_TAG_DOVLTC_LEN 1 + #define MAC_VLAN_TAG_DOVLTC_DEFAULT 0x0 + /*[field] EVLS*/ + #define MAC_VLAN_TAG_EVLS + #define MAC_VLAN_TAG_EVLS_OFFSET 21 + #define MAC_VLAN_TAG_EVLS_LEN 2 + #define MAC_VLAN_TAG_EVLS_DEFAULT 0x0 + /*[field] EVLRXS*/ + #define MAC_VLAN_TAG_EVLRXS + #define MAC_VLAN_TAG_EVLRXS_OFFSET 24 + #define MAC_VLAN_TAG_EVLRXS_LEN 1 + #define MAC_VLAN_TAG_EVLRXS_DEFAULT 0x1 + /*[field] VTHM*/ + #define MAC_VLAN_TAG_VTHM + #define MAC_VLAN_TAG_VTHM_OFFSET 25 + #define MAC_VLAN_TAG_VTHM_LEN 1 + #define MAC_VLAN_TAG_VTHM_DEFAULT 0x1 + /*[field] EDVLP*/ + #define MAC_VLAN_TAG_EDVLP + #define MAC_VLAN_TAG_EDVLP_OFFSET 26 + #define MAC_VLAN_TAG_EDVLP_LEN 1 + #define MAC_VLAN_TAG_EDVLP_DEFAULT 0x0 + /*[field] ERIVLT*/ + #define MAC_VLAN_TAG_ERIVLT + #define MAC_VLAN_TAG_ERIVLT_OFFSET 27 + #define MAC_VLAN_TAG_ERIVLT_LEN 1 + #define MAC_VLAN_TAG_ERIVLT_DEFAULT 0x1 + /*[field] EIVLS*/ + #define MAC_VLAN_TAG_EIVLS + #define MAC_VLAN_TAG_EIVLS_OFFSET 28 + #define MAC_VLAN_TAG_EIVLS_LEN 2 + #define MAC_VLAN_TAG_EIVLS_DEFAULT 0x1 + /*[field] EIVLRXS*/ + #define MAC_VLAN_TAG_EIVLRXS + #define MAC_VLAN_TAG_EIVLRXS_OFFSET 31 + #define MAC_VLAN_TAG_EIVLRXS_LEN 1 + #define MAC_VLAN_TAG_EIVLRXS_DEFAULT 0x0 + +struct mac_vlan_tag { + a_uint32_t vl:16; + a_uint32_t etv:1; + a_uint32_t vtim:1; + a_uint32_t esvl:1; + a_uint32_t ersvlm:1; + a_uint32_t dovltc:1; + a_uint32_t evls:2; + a_uint32_t _reserved0:1; + a_uint32_t evlrxs:1; + a_uint32_t vthm:1; + a_uint32_t edvlp:1; + a_uint32_t erivlt:1; + a_uint32_t eivls:2; + a_uint32_t _reserved1:1; + a_uint32_t eivlrxs:1; +}; + +union mac_vlan_tag_u { + a_uint32_t val; + struct mac_vlan_tag bf; +}; + +/*[register] MAC_RX_ETH_TYPE_MATCH*/ +#define MAC_RX_ETH_TYPE_MATCH +#define MAC_RX_ETH_TYPE_MATCH_ADDRESS 0x6c +#define MAC_RX_ETH_TYPE_MATCH_NUM 2 +#define MAC_RX_ETH_TYPE_MATCH_INC 0x4000 +#define MAC_RX_ETH_TYPE_MATCH_TYPE REG_TYPE_RW +#define MAC_RX_ETH_TYPE_MATCH_DEFAULT 0x0 + /*[field] ET*/ + #define MAC_RX_ETH_TYPE_MATCH_ET + #define MAC_RX_ETH_TYPE_MATCH_ET_OFFSET 0 + #define MAC_RX_ETH_TYPE_MATCH_ET_LEN 16 + #define MAC_RX_ETH_TYPE_MATCH_ET_DEFAULT 0x0 + +struct mac_rx_eth_type_match { + a_uint32_t et:16; + a_uint32_t _reserved0:16; +}; + +union mac_rx_eth_type_match_u { + a_uint32_t val; + struct mac_rx_eth_type_match bf; +}; + +/*[register] MAC_Q0_TX_FLOW_CTRL*/ +#define MAC_Q0_TX_FLOW_CTRL +#define MAC_Q0_TX_FLOW_CTRL_ADDRESS 0x70 +#define MAC_Q0_TX_FLOW_CTRL_NUM 2 +#define MAC_Q0_TX_FLOW_CTRL_INC 0x4000 +#define MAC_Q0_TX_FLOW_CTRL_TYPE REG_TYPE_RW +#define MAC_Q0_TX_FLOW_CTRL_DEFAULT 0x2 + /*[field] FCB*/ + #define MAC_Q0_TX_FLOW_CTRL_FCB + #define MAC_Q0_TX_FLOW_CTRL_FCB_OFFSET 0 + #define MAC_Q0_TX_FLOW_CTRL_FCB_LEN 1 + #define MAC_Q0_TX_FLOW_CTRL_FCB_DEFAULT 0x0 + /*[field] TFE*/ + #define MAC_Q0_TX_FLOW_CTRL_TFE + #define MAC_Q0_TX_FLOW_CTRL_TFE_OFFSET 1 + #define MAC_Q0_TX_FLOW_CTRL_TFE_LEN 1 + #define MAC_Q0_TX_FLOW_CTRL_TFE_DEFAULT 0x1 + /*[field] PLT*/ + #define MAC_Q0_TX_FLOW_CTRL_PLT + #define MAC_Q0_TX_FLOW_CTRL_PLT_OFFSET 4 + #define MAC_Q0_TX_FLOW_CTRL_PLT_LEN 3 + #define MAC_Q0_TX_FLOW_CTRL_PLT_DEFAULT 0x0 + /*[field] DAPQ*/ + #define MAC_Q0_TX_FLOW_CTRL_DAPQ + #define MAC_Q0_TX_FLOW_CTRL_DAPQ_OFFSET 7 + #define MAC_Q0_TX_FLOW_CTRL_DAPQ_LEN 1 + #define MAC_Q0_TX_FLOW_CTRL_DAPQ_DEFAULT 0x0 + /*[field] PT*/ + #define MAC_Q0_TX_FLOW_CTRL_PT + #define MAC_Q0_TX_FLOW_CTRL_PT_OFFSET 16 + #define MAC_Q0_TX_FLOW_CTRL_PT_LEN 16 + #define MAC_Q0_TX_FLOW_CTRL_PT_DEFAULT 0x0 + +struct mac_q0_tx_flow_ctrl { + a_uint32_t fcb:1; + a_uint32_t tfe:1; + a_uint32_t _reserved0:2; + a_uint32_t plt:3; + a_uint32_t dapq:1; + a_uint32_t _reserved1:8; + a_uint32_t pt:16; +}; + +union mac_q0_tx_flow_ctrl_u { + a_uint32_t val; + struct mac_q0_tx_flow_ctrl bf; +}; + +/*[register] MAC_RX_FLOW_CTRL*/ +#define MAC_RX_FLOW_CTRL +#define MAC_RX_FLOW_CTRL_ADDRESS 0x90 +#define MAC_RX_FLOW_CTRL_NUM 2 +#define MAC_RX_FLOW_CTRL_INC 0x4000 +#define MAC_RX_FLOW_CTRL_TYPE REG_TYPE_RW +#define MAC_RX_FLOW_CTRL_DEFAULT 0x80e + /*[field] RFE*/ + #define MAC_RX_FLOW_CTRL_RFE + #define MAC_RX_FLOW_CTRL_RFE_OFFSET 0 + #define MAC_RX_FLOW_CTRL_RFE_LEN 1 + #define MAC_RX_FLOW_CTRL_RFE_DEFAULT 0x0 + /*[field] UP*/ + #define MAC_RX_FLOW_CTRL_UP + #define MAC_RX_FLOW_CTRL_UP_OFFSET 1 + #define MAC_RX_FLOW_CTRL_UP_LEN 1 + #define MAC_RX_FLOW_CTRL_UP_DEFAULT 0x7 + /*[field] PFCE*/ + #define MAC_RX_FLOW_CTRL_PFCE + #define MAC_RX_FLOW_CTRL_PFCE_OFFSET 8 + #define MAC_RX_FLOW_CTRL_PFCE_LEN 1 + #define MAC_RX_FLOW_CTRL_PFCE_DEFAULT 0x0 + +struct mac_rx_flow_ctrl { + a_uint32_t rfe:1; + a_uint32_t up:1; + a_uint32_t _reserved0:6; + a_uint32_t pfce:1; + a_uint32_t _reserved1:23; +}; + +union mac_rx_flow_ctrl_u { + a_uint32_t val; + struct mac_rx_flow_ctrl bf; +}; + +/*[register] MAC_INTERRUPT_STATUS*/ +#define MAC_INTERRUPT_STATUS +#define MAC_INTERRUPT_STATUS_ADDRESS 0xb0 +#define MAC_INTERRUPT_STATUS_NUM 2 +#define MAC_INTERRUPT_STATUS_INC 0x4000 +#define MAC_INTERRUPT_STATUS_TYPE REG_TYPE_RW +#define MAC_INTERRUPT_STATUS_DEFAULT 0x0 + /*[field] SMI*/ + #define MAC_INTERRUPT_STATUS_SMI + #define MAC_INTERRUPT_STATUS_SMI_OFFSET 1 + #define MAC_INTERRUPT_STATUS_SMI_LEN 1 + #define MAC_INTERRUPT_STATUS_SMI_DEFAULT 0x0 + /*[field] PMTIS*/ + #define MAC_INTERRUPT_STATUS_PMTIS + #define MAC_INTERRUPT_STATUS_PMTIS_OFFSET 4 + #define MAC_INTERRUPT_STATUS_PMTIS_LEN 1 + #define MAC_INTERRUPT_STATUS_PMTIS_DEFAULT 0x0 + /*[field] LPIIS*/ + #define MAC_INTERRUPT_STATUS_LPIIS + #define MAC_INTERRUPT_STATUS_LPIIS_OFFSET 5 + #define MAC_INTERRUPT_STATUS_LPIIS_LEN 1 + #define MAC_INTERRUPT_STATUS_LPIIS_DEFAULT 0x0 + /*[field] MMCRXIS*/ + #define MAC_INTERRUPT_STATUS_MMCRXIS + #define MAC_INTERRUPT_STATUS_MMCRXIS_OFFSET 9 + #define MAC_INTERRUPT_STATUS_MMCRXIS_LEN 1 + #define MAC_INTERRUPT_STATUS_MMCRXIS_DEFAULT 0x0 + /*[field] MMCTXIS*/ + #define MAC_INTERRUPT_STATUS_MMCTXIS + #define MAC_INTERRUPT_STATUS_MMCTXIS_OFFSET 10 + #define MAC_INTERRUPT_STATUS_MMCTXIS_LEN 1 + #define MAC_INTERRUPT_STATUS_MMCTXIS_DEFAULT 0x0 + /*[field] TSIS*/ + #define MAC_INTERRUPT_STATUS_TSIS + #define MAC_INTERRUPT_STATUS_TSIS_OFFSET 12 + #define MAC_INTERRUPT_STATUS_TSIS_LEN 1 + #define MAC_INTERRUPT_STATUS_TSIS_DEFAULT 0x0 + /*[field] TXESIS*/ + #define MAC_INTERRUPT_STATUS_TXESIS + #define MAC_INTERRUPT_STATUS_TXESIS_OFFSET 13 + #define MAC_INTERRUPT_STATUS_TXESIS_LEN 1 + #define MAC_INTERRUPT_STATUS_TXESIS_DEFAULT 0x0 + /*[field] RXESIS*/ + #define MAC_INTERRUPT_STATUS_RXESIS + #define MAC_INTERRUPT_STATUS_RXESIS_OFFSET 14 + #define MAC_INTERRUPT_STATUS_RXESIS_LEN 1 + #define MAC_INTERRUPT_STATUS_RXESIS_DEFAULT 0x0 + /*[field] GPIIS*/ + #define MAC_INTERRUPT_STATUS_GPIIS + #define MAC_INTERRUPT_STATUS_GPIIS_OFFSET 15 + #define MAC_INTERRUPT_STATUS_GPIIS_LEN 1 + #define MAC_INTERRUPT_STATUS_GPIIS_DEFAULT 0x0 + /*[field] LS*/ + #define MAC_INTERRUPT_STATUS_LS + #define MAC_INTERRUPT_STATUS_LS_OFFSET 24 + #define MAC_INTERRUPT_STATUS_LS_LEN 2 + #define MAC_INTERRUPT_STATUS_LS_DEFAULT 0x0 + +struct mac_interrupt_status { + a_uint32_t smi:1; + a_uint32_t _reserved0:2; + a_uint32_t pmtis:1; + a_uint32_t lpiis:1; + a_uint32_t _reserved1:3; + a_uint32_t mmcrxis:1; + a_uint32_t mmctxis:1; + a_uint32_t _reserved2:1; + a_uint32_t tsis:1; + a_uint32_t txesis:1; + a_uint32_t rxesis:1; + a_uint32_t gpiis:1; + a_uint32_t _reserved3:8; + a_uint32_t ls:2; + a_uint32_t _reserved4:6; +}; + +union mac_interrupt_status_u { + a_uint32_t val; + struct mac_interrupt_status bf; +}; + +/*[register] MAC_INTERRUPT_ENABLE*/ +#define MAC_INTERRUPT_ENABLE +#define MAC_INTERRUPT_ENABLE_ADDRESS 0xb4 +#define MAC_INTERRUPT_ENABLE_NUM 2 +#define MAC_INTERRUPT_ENABLE_INC 0x4000 +#define MAC_INTERRUPT_ENABLE_TYPE REG_TYPE_RO +#define MAC_INTERRUPT_ENABLE_DEFAULT 0x0 + /*[field] PMTIE*/ + #define MAC_INTERRUPT_ENABLE_PMTIE + #define MAC_INTERRUPT_ENABLE_PMTIE_OFFSET 4 + #define MAC_INTERRUPT_ENABLE_PMTIE_LEN 1 + #define MAC_INTERRUPT_ENABLE_PMTIE_DEFAULT 0x0 + /*[field] LPIIE*/ + #define MAC_INTERRUPT_ENABLE_LPIIE + #define MAC_INTERRUPT_ENABLE_LPIIE_OFFSET 5 + #define MAC_INTERRUPT_ENABLE_LPIIE_LEN 1 + #define MAC_INTERRUPT_ENABLE_LPIIE_DEFAULT 0x0 + /*[field] TSIE*/ + #define MAC_INTERRUPT_ENABLE_TSIE + #define MAC_INTERRUPT_ENABLE_TSIE_OFFSET 12 + #define MAC_INTERRUPT_ENABLE_TSIE_LEN 1 + #define MAC_INTERRUPT_ENABLE_TSIE_DEFAULT 0x0 + /*[field] TXESIE*/ + #define MAC_INTERRUPT_ENABLE_TXESIE + #define MAC_INTERRUPT_ENABLE_TXESIE_OFFSET 13 + #define MAC_INTERRUPT_ENABLE_TXESIE_LEN 1 + #define MAC_INTERRUPT_ENABLE_TXESIE_DEFAULT 0x0 + /*[field] RXESIE*/ + #define MAC_INTERRUPT_ENABLE_RXESIE + #define MAC_INTERRUPT_ENABLE_RXESIE_OFFSET 14 + #define MAC_INTERRUPT_ENABLE_RXESIE_LEN 1 + #define MAC_INTERRUPT_ENABLE_RXESIE_DEFAULT 0x0 + +struct mac_interrupt_enable { + a_uint32_t pmtie:1; + a_uint32_t lpiie:1; + a_uint32_t _reserved0:6; + a_uint32_t tsie:1; + a_uint32_t txesie:1; + a_uint32_t rxesie:1; + a_uint32_t _reserved1:17; +}; + +union mac_interrupt_enable_u { + a_uint32_t val; + struct mac_interrupt_enable bf; +}; + +/*[register] MAC_RX_TX_STATUS*/ +#define MAC_RX_TX_STATUS +#define MAC_RX_TX_STATUS_ADDRESS 0xb8 +#define MAC_RX_TX_STATUS_NUM 2 +#define MAC_RX_TX_STATUS_INC 0x4000 +#define MAC_RX_TX_STATUS_TYPE REG_TYPE_RW +#define MAC_RX_TX_STATUS_DEFAULT 0x0 + /*[field] TJT*/ + #define MAC_RX_TX_STATUS_TJT + #define MAC_RX_TX_STATUS_TJT_OFFSET 0 + #define MAC_RX_TX_STATUS_TJT_LEN 1 + #define MAC_RX_TX_STATUS_TJT_DEFAULT 0x0 + /*[field] RWT*/ + #define MAC_RX_TX_STATUS_RWT + #define MAC_RX_TX_STATUS_RWT_OFFSET 8 + #define MAC_RX_TX_STATUS_RWT_LEN 1 + #define MAC_RX_TX_STATUS_RWT_DEFAULT 0x0 + +struct mac_rx_tx_status { + a_uint32_t tjt:1; + a_uint32_t _reserved0:7; + a_uint32_t rwt:1; + a_uint32_t _reserved1:23; +}; + +union mac_rx_tx_status_u { + a_uint32_t val; + struct mac_rx_tx_status bf; +}; + +/*[register] MAC_LPI_CONTROL_STATUS*/ +#define MAC_LPI_CONTROL_STATUS +#define MAC_LPI_CONTROL_STATUS_ADDRESS 0xd0 +#define MAC_LPI_CONTROL_STATUS_NUM 2 +#define MAC_LPI_CONTROL_STATUS_INC 0x4000 +#define MAC_LPI_CONTROL_STATUS_TYPE REG_TYPE_RW +#define MAC_LPI_CONTROL_STATUS_DEFAULT 0x0 + /*[field] TLPIEN*/ + #define MAC_LPI_CONTROL_STATUS_TLPIEN + #define MAC_LPI_CONTROL_STATUS_TLPIEN_OFFSET 0 + #define MAC_LPI_CONTROL_STATUS_TLPIEN_LEN 1 + #define MAC_LPI_CONTROL_STATUS_TLPIEN_DEFAULT 0x0 + /*[field] TLPIEX*/ + #define MAC_LPI_CONTROL_STATUS_TLPIEX + #define MAC_LPI_CONTROL_STATUS_TLPIEX_OFFSET 1 + #define MAC_LPI_CONTROL_STATUS_TLPIEX_LEN 1 + #define MAC_LPI_CONTROL_STATUS_TLPIEX_DEFAULT 0x0 + /*[field] RLPIEN*/ + #define MAC_LPI_CONTROL_STATUS_RLPIEN + #define MAC_LPI_CONTROL_STATUS_RLPIEN_OFFSET 2 + #define MAC_LPI_CONTROL_STATUS_RLPIEN_LEN 1 + #define MAC_LPI_CONTROL_STATUS_RLPIEN_DEFAULT 0x0 + /*[field] RLPIEX*/ + #define MAC_LPI_CONTROL_STATUS_RLPIEX + #define MAC_LPI_CONTROL_STATUS_RLPIEX_OFFSET 3 + #define MAC_LPI_CONTROL_STATUS_RLPIEX_LEN 1 + #define MAC_LPI_CONTROL_STATUS_RLPIEX_DEFAULT 0x0 + /*[field] TLPIST*/ + #define MAC_LPI_CONTROL_STATUS_TLPIST + #define MAC_LPI_CONTROL_STATUS_TLPIST_OFFSET 8 + #define MAC_LPI_CONTROL_STATUS_TLPIST_LEN 1 + #define MAC_LPI_CONTROL_STATUS_TLPIST_DEFAULT 0x0 + /*[field] RLPIST*/ + #define MAC_LPI_CONTROL_STATUS_RLPIST + #define MAC_LPI_CONTROL_STATUS_RLPIST_OFFSET 9 + #define MAC_LPI_CONTROL_STATUS_RLPIST_LEN 1 + #define MAC_LPI_CONTROL_STATUS_RLPIST_DEFAULT 0x0 + /*[field] RXRSTP*/ + #define MAC_LPI_CONTROL_STATUS_RXRSTP + #define MAC_LPI_CONTROL_STATUS_RXRSTP_OFFSET 10 + #define MAC_LPI_CONTROL_STATUS_RXRSTP_LEN 1 + #define MAC_LPI_CONTROL_STATUS_RXRSTP_DEFAULT 0x0 + /*[field] TXRSTP*/ + #define MAC_LPI_CONTROL_STATUS_TXRSTP + #define MAC_LPI_CONTROL_STATUS_TXRSTP_OFFSET 11 + #define MAC_LPI_CONTROL_STATUS_TXRSTP_LEN 1 + #define MAC_LPI_CONTROL_STATUS_TXRSTP_DEFAULT 0x0 + /*[field] LPITXEN*/ + #define MAC_LPI_CONTROL_STATUS_LPITXEN + #define MAC_LPI_CONTROL_STATUS_LPITXEN_OFFSET 16 + #define MAC_LPI_CONTROL_STATUS_LPITXEN_LEN 1 + #define MAC_LPI_CONTROL_STATUS_LPITXEN_DEFAULT 0x0 + /*[field] PLS*/ + #define MAC_LPI_CONTROL_STATUS_PLS + #define MAC_LPI_CONTROL_STATUS_PLS_OFFSET 17 + #define MAC_LPI_CONTROL_STATUS_PLS_LEN 1 + #define MAC_LPI_CONTROL_STATUS_PLS_DEFAULT 0x0 + /*[field] PLSDIS*/ + #define MAC_LPI_CONTROL_STATUS_PLSDIS + #define MAC_LPI_CONTROL_STATUS_PLSDIS_OFFSET 18 + #define MAC_LPI_CONTROL_STATUS_PLSDIS_LEN 1 + #define MAC_LPI_CONTROL_STATUS_PLSDIS_DEFAULT 0x0 + /*[field] LPITXA*/ + #define MAC_LPI_CONTROL_STATUS_LPITXA + #define MAC_LPI_CONTROL_STATUS_LPITXA_OFFSET 19 + #define MAC_LPI_CONTROL_STATUS_LPITXA_LEN 1 + #define MAC_LPI_CONTROL_STATUS_LPITXA_DEFAULT 0x0 + /*[field] LPITE*/ + #define MAC_LPI_CONTROL_STATUS_LPITE + #define MAC_LPI_CONTROL_STATUS_LPITE_OFFSET 20 + #define MAC_LPI_CONTROL_STATUS_LPITE_LEN 1 + #define MAC_LPI_CONTROL_STATUS_LPITE_DEFAULT 0x0 + /*[field] LPITCSE*/ + #define MAC_LPI_CONTROL_STATUS_LPITCSE + #define MAC_LPI_CONTROL_STATUS_LPITCSE_OFFSET 21 + #define MAC_LPI_CONTROL_STATUS_LPITCSE_LEN 1 + #define MAC_LPI_CONTROL_STATUS_LPITCSE_DEFAULT 0x0 + +struct mac_lpi_control_status { + a_uint32_t tlpien:1; + a_uint32_t tlpiex:1; + a_uint32_t rlpien:1; + a_uint32_t rlpiex:1; + a_uint32_t _reserved0:4; + a_uint32_t tlpist:1; + a_uint32_t rlpist:1; + a_uint32_t rxrstp:1; + a_uint32_t txrstp:1; + a_uint32_t _reserved1:4; + a_uint32_t lpitxen:1; + a_uint32_t pls:1; + a_uint32_t plsdis:1; + a_uint32_t lpitxa:1; + a_uint32_t lpite:1; + a_uint32_t lpitcse:1; + a_uint32_t _reserved2:10; +}; + +union mac_lpi_control_status_u { + a_uint32_t val; + struct mac_lpi_control_status bf; +}; + +/*[register] MAC_LPI_TIMERS_CONTROL*/ +#define MAC_LPI_TIMERS_CONTROL +#define MAC_LPI_TIMERS_CONTROL_ADDRESS 0xd4 +#define MAC_LPI_TIMERS_CONTROL_NUM 2 +#define MAC_LPI_TIMERS_CONTROL_INC 0x4000 +#define MAC_LPI_TIMERS_CONTROL_TYPE REG_TYPE_RO +#define MAC_LPI_TIMERS_CONTROL_DEFAULT 0x0 + /*[field] TWT*/ + #define MAC_LPI_TIMERS_CONTROL_TWT + #define MAC_LPI_TIMERS_CONTROL_TWT_OFFSET 0 + #define MAC_LPI_TIMERS_CONTROL_TWT_LEN 16 + #define MAC_LPI_TIMERS_CONTROL_TWT_DEFAULT 0x0 + /*[field] LST*/ + #define MAC_LPI_TIMERS_CONTROL_LST + #define MAC_LPI_TIMERS_CONTROL_LST_OFFSET 16 + #define MAC_LPI_TIMERS_CONTROL_LST_LEN 10 + #define MAC_LPI_TIMERS_CONTROL_LST_DEFAULT 0x0 + +struct mac_lpi_timers_control { + a_uint32_t twt:16; + a_uint32_t lst:10; + a_uint32_t _reserved0:6; +}; + +union mac_lpi_timers_control_u { + a_uint32_t val; + struct mac_lpi_timers_control bf; +}; + +/*[register] MAC_LPI_AUTO_ENTRY_TIMER*/ +#define MAC_LPI_AUTO_ENTRY_TIMER +#define MAC_LPI_AUTO_ENTRY_TIMER_ADDRESS 0xd8 +#define MAC_LPI_AUTO_ENTRY_TIMER_NUM 2 +#define MAC_LPI_AUTO_ENTRY_TIMER_INC 0x4000 +#define MAC_LPI_AUTO_ENTRY_TIMER_TYPE REG_TYPE_RO +#define MAC_LPI_AUTO_ENTRY_TIMER_DEFAULT 0x0 + /*[field] LPIET*/ + #define MAC_LPI_AUTO_ENTRY_TIMER_LPIET + #define MAC_LPI_AUTO_ENTRY_TIMER_LPIET_OFFSET 3 + #define MAC_LPI_AUTO_ENTRY_TIMER_LPIET_LEN 17 + #define MAC_LPI_AUTO_ENTRY_TIMER_LPIET_DEFAULT 0x0 + +struct mac_lpi_auto_entry_timer { + a_uint32_t lpiet:17; + a_uint32_t _reserved0:12; +}; + +union mac_lpi_auto_entry_timer_u { + a_uint32_t val; + struct mac_lpi_auto_entry_timer bf; +}; + +/*[register] MAC_1US_TIC_COUNTER*/ +#define MAC_1US_TIC_COUNTER +#define MAC_1US_TIC_COUNTER_ADDRESS 0xdc +#define MAC_1US_TIC_COUNTER_NUM 2 +#define MAC_1US_TIC_COUNTER_INC 0x4000 +#define MAC_1US_TIC_COUNTER_TYPE REG_TYPE_RO +#define MAC_1US_TIC_COUNTER_DEFAULT 0x0 + /*[field] TIC_1US_CNTR*/ + #define MAC_1US_TIC_COUNTER_TIC_1US_CNTR + #define MAC_1US_TIC_COUNTER_TIC_1US_CNTR_OFFSET 0 + #define MAC_1US_TIC_COUNTER_TIC_1US_CNTR_LEN 12 + #define MAC_1US_TIC_COUNTER_TIC_1US_CNTR_DEFAULT 0x0 + +struct mac_1us_tic_counter { + a_uint32_t tic_1us_cntr:12; + a_uint32_t _reserved0:20; +}; + +union mac_1us_tic_counter_u { + a_uint32_t val; + struct mac_1us_tic_counter bf; +}; + +/*[register] MAC_ADDRESS0_HIGH*/ +#define MAC_ADDRESS0_HIGH +#define MAC_ADDRESS0_HIGH_ADDRESS 0x300 +#define MAC_ADDRESS0_HIGH_NUM 2 +#define MAC_ADDRESS0_HIGH_INC 0x4000 +#define MAC_ADDRESS0_HIGH_TYPE REG_TYPE_RO +#define MAC_ADDRESS0_HIGH_DEFAULT 0x0 + /*[field] ADDRHI*/ + #define MAC_ADDRESS0_HIGH_ADDRHI + #define MAC_ADDRESS0_HIGH_ADDRHI_OFFSET 0 + #define MAC_ADDRESS0_HIGH_ADDRHI_LEN 16 + #define MAC_ADDRESS0_HIGH_ADDRHI_DEFAULT 0x0 + /*[field] DCS*/ + #define MAC_ADDRESS0_HIGH_DCS + #define MAC_ADDRESS0_HIGH_DCS_OFFSET 16 + #define MAC_ADDRESS0_HIGH_DCS_LEN 1 + #define MAC_ADDRESS0_HIGH_DCS_DEFAULT 0x0 + /*[field] AE*/ + #define MAC_ADDRESS0_HIGH_AE + #define MAC_ADDRESS0_HIGH_AE_OFFSET 31 + #define MAC_ADDRESS0_HIGH_AE_LEN 1 + #define MAC_ADDRESS0_HIGH_AE_DEFAULT 0x0 + +struct mac_address0_high { + a_uint32_t addrhi:16; + a_uint32_t dcs:1; + a_uint32_t _reserved0:14; + a_uint32_t ae:1; +}; + +union mac_address0_high_u { + a_uint32_t val; + struct mac_address0_high bf; +}; + +/*[register] MAC_ADDRESS0_LOW*/ +#define MAC_ADDRESS0_LOW +#define MAC_ADDRESS0_LOW_ADDRESS 0x304 +#define MAC_ADDRESS0_LOW_NUM 2 +#define MAC_ADDRESS0_LOW_INC 0x4000 +#define MAC_ADDRESS0_LOW_TYPE REG_TYPE_RO +#define MAC_ADDRESS0_LOW_DEFAULT 0x0 + /*[field] ADDRLO*/ + #define MAC_ADDRESS0_LOW_ADDRLO + #define MAC_ADDRESS0_LOW_ADDRLO_OFFSET 0 + #define MAC_ADDRESS0_LOW_ADDRLO_LEN 32 + #define MAC_ADDRESS0_LOW_ADDRLO_DEFAULT 0x0 + +struct mac_address0_low { + a_uint32_t addrlo:32; +}; + +union mac_address0_low_u { + a_uint32_t val; + struct mac_address0_low bf; +}; + +/*[register] MMC_RECEIVE_INTERRUPT*/ +#define MMC_RECEIVE_INTERRUPT +#define MMC_RECEIVE_INTERRUPT_ADDRESS 0x804 +#define MMC_RECEIVE_INTERRUPT_NUM 2 +#define MMC_RECEIVE_INTERRUPT_INC 0x4000 +#define MMC_RECEIVE_INTERRUPT_TYPE REG_TYPE_RO +#define MMC_RECEIVE_INTERRUPT_DEFAULT 0x0 + /*[field] RXGBFRMIS*/ + #define MMC_RECEIVE_INTERRUPT_RXGBFRMIS + #define MMC_RECEIVE_INTERRUPT_RXGBFRMIS_OFFSET 0 + #define MMC_RECEIVE_INTERRUPT_RXGBFRMIS_LEN 1 + #define MMC_RECEIVE_INTERRUPT_RXGBFRMIS_DEFAULT 0x0 + /*[field] RXGBOCTIS*/ + #define MMC_RECEIVE_INTERRUPT_RXGBOCTIS + #define MMC_RECEIVE_INTERRUPT_RXGBOCTIS_OFFSET 1 + #define MMC_RECEIVE_INTERRUPT_RXGBOCTIS_LEN 1 + #define MMC_RECEIVE_INTERRUPT_RXGBOCTIS_DEFAULT 0x0 + /*[field] RXGOCTIS*/ + #define MMC_RECEIVE_INTERRUPT_RXGOCTIS + #define MMC_RECEIVE_INTERRUPT_RXGOCTIS_OFFSET 2 + #define MMC_RECEIVE_INTERRUPT_RXGOCTIS_LEN 1 + #define MMC_RECEIVE_INTERRUPT_RXGOCTIS_DEFAULT 0x0 + /*[field] RXBCGFIS*/ + #define MMC_RECEIVE_INTERRUPT_RXBCGFIS + #define MMC_RECEIVE_INTERRUPT_RXBCGFIS_OFFSET 3 + #define MMC_RECEIVE_INTERRUPT_RXBCGFIS_LEN 1 + #define MMC_RECEIVE_INTERRUPT_RXBCGFIS_DEFAULT 0x0 + /*[field] RXMCGFIS*/ + #define MMC_RECEIVE_INTERRUPT_RXMCGFIS + #define MMC_RECEIVE_INTERRUPT_RXMCGFIS_OFFSET 4 + #define MMC_RECEIVE_INTERRUPT_RXMCGFIS_LEN 1 + #define MMC_RECEIVE_INTERRUPT_RXMCGFIS_DEFAULT 0x0 + /*[field] RXCRCERFIS*/ + #define MMC_RECEIVE_INTERRUPT_RXCRCERFIS + #define MMC_RECEIVE_INTERRUPT_RXCRCERFIS_OFFSET 5 + #define MMC_RECEIVE_INTERRUPT_RXCRCERFIS_LEN 1 + #define MMC_RECEIVE_INTERRUPT_RXCRCERFIS_DEFAULT 0x0 + /*[field] RXRUNTFIS*/ + #define MMC_RECEIVE_INTERRUPT_RXRUNTFIS + #define MMC_RECEIVE_INTERRUPT_RXRUNTFIS_OFFSET 6 + #define MMC_RECEIVE_INTERRUPT_RXRUNTFIS_LEN 1 + #define MMC_RECEIVE_INTERRUPT_RXRUNTFIS_DEFAULT 0x0 + /*[field] RXJABERFIS*/ + #define MMC_RECEIVE_INTERRUPT_RXJABERFIS + #define MMC_RECEIVE_INTERRUPT_RXJABERFIS_OFFSET 7 + #define MMC_RECEIVE_INTERRUPT_RXJABERFIS_LEN 1 + #define MMC_RECEIVE_INTERRUPT_RXJABERFIS_DEFAULT 0x0 + /*[field] RXUSIZEGFIS*/ + #define MMC_RECEIVE_INTERRUPT_RXUSIZEGFIS + #define MMC_RECEIVE_INTERRUPT_RXUSIZEGFIS_OFFSET 8 + #define MMC_RECEIVE_INTERRUPT_RXUSIZEGFIS_LEN 1 + #define MMC_RECEIVE_INTERRUPT_RXUSIZEGFIS_DEFAULT 0x0 + /*[field] RXOSIZEGFIS*/ + #define MMC_RECEIVE_INTERRUPT_RXOSIZEGFIS + #define MMC_RECEIVE_INTERRUPT_RXOSIZEGFIS_OFFSET 9 + #define MMC_RECEIVE_INTERRUPT_RXOSIZEGFIS_LEN 1 + #define MMC_RECEIVE_INTERRUPT_RXOSIZEGFIS_DEFAULT 0x0 + /*[field] RX64OCTGBFIS*/ + #define MMC_RECEIVE_INTERRUPT_RX64OCTGBFIS + #define MMC_RECEIVE_INTERRUPT_RX64OCTGBFIS_OFFSET 10 + #define MMC_RECEIVE_INTERRUPT_RX64OCTGBFIS_LEN 1 + #define MMC_RECEIVE_INTERRUPT_RX64OCTGBFIS_DEFAULT 0x0 + /*[field] RX65T127OCTGBFIS*/ + #define MMC_RECEIVE_INTERRUPT_RX65T127OCTGBFIS + #define MMC_RECEIVE_INTERRUPT_RX65T127OCTGBFIS_OFFSET 11 + #define MMC_RECEIVE_INTERRUPT_RX65T127OCTGBFIS_LEN 1 + #define MMC_RECEIVE_INTERRUPT_RX65T127OCTGBFIS_DEFAULT 0x0 + /*[field] RX128T255OCTGBFIS*/ + #define MMC_RECEIVE_INTERRUPT_RX128T255OCTGBFIS + #define MMC_RECEIVE_INTERRUPT_RX128T255OCTGBFIS_OFFSET 12 + #define MMC_RECEIVE_INTERRUPT_RX128T255OCTGBFIS_LEN 1 + #define MMC_RECEIVE_INTERRUPT_RX128T255OCTGBFIS_DEFAULT 0x0 + /*[field] RX256T511OCTGBFIS*/ + #define MMC_RECEIVE_INTERRUPT_RX256T511OCTGBFIS + #define MMC_RECEIVE_INTERRUPT_RX256T511OCTGBFIS_OFFSET 13 + #define MMC_RECEIVE_INTERRUPT_RX256T511OCTGBFIS_LEN 1 + #define MMC_RECEIVE_INTERRUPT_RX256T511OCTGBFIS_DEFAULT 0x0 + /*[field] RX512T1023OCTGBFIS*/ + #define MMC_RECEIVE_INTERRUPT_RX512T1023OCTGBFIS + #define MMC_RECEIVE_INTERRUPT_RX512T1023OCTGBFIS_OFFSET 14 + #define MMC_RECEIVE_INTERRUPT_RX512T1023OCTGBFIS_LEN 1 + #define MMC_RECEIVE_INTERRUPT_RX512T1023OCTGBFIS_DEFAULT 0x0 + /*[field] RX1024TMAXOCTGBFIS*/ + #define MMC_RECEIVE_INTERRUPT_RX1024TMAXOCTGBFIS + #define MMC_RECEIVE_INTERRUPT_RX1024TMAXOCTGBFIS_OFFSET 15 + #define MMC_RECEIVE_INTERRUPT_RX1024TMAXOCTGBFIS_LEN 1 + #define MMC_RECEIVE_INTERRUPT_RX1024TMAXOCTGBFIS_DEFAULT 0x0 + /*[field] RXUCGFIS*/ + #define MMC_RECEIVE_INTERRUPT_RXUCGFIS + #define MMC_RECEIVE_INTERRUPT_RXUCGFIS_OFFSET 16 + #define MMC_RECEIVE_INTERRUPT_RXUCGFIS_LEN 1 + #define MMC_RECEIVE_INTERRUPT_RXUCGFIS_DEFAULT 0x0 + /*[field] RXLENERFIS*/ + #define MMC_RECEIVE_INTERRUPT_RXLENERFIS + #define MMC_RECEIVE_INTERRUPT_RXLENERFIS_OFFSET 17 + #define MMC_RECEIVE_INTERRUPT_RXLENERFIS_LEN 1 + #define MMC_RECEIVE_INTERRUPT_RXLENERFIS_DEFAULT 0x0 + /*[field] RXORANGEFIS*/ + #define MMC_RECEIVE_INTERRUPT_RXORANGEFIS + #define MMC_RECEIVE_INTERRUPT_RXORANGEFIS_OFFSET 18 + #define MMC_RECEIVE_INTERRUPT_RXORANGEFIS_LEN 1 + #define MMC_RECEIVE_INTERRUPT_RXORANGEFIS_DEFAULT 0x0 + /*[field] RXPAUSFIS*/ + #define MMC_RECEIVE_INTERRUPT_RXPAUSFIS + #define MMC_RECEIVE_INTERRUPT_RXPAUSFIS_OFFSET 19 + #define MMC_RECEIVE_INTERRUPT_RXPAUSFIS_LEN 1 + #define MMC_RECEIVE_INTERRUPT_RXPAUSFIS_DEFAULT 0x0 + /*[field] RXFOVFIS*/ + #define MMC_RECEIVE_INTERRUPT_RXFOVFIS + #define MMC_RECEIVE_INTERRUPT_RXFOVFIS_OFFSET 20 + #define MMC_RECEIVE_INTERRUPT_RXFOVFIS_LEN 1 + #define MMC_RECEIVE_INTERRUPT_RXFOVFIS_DEFAULT 0x0 + /*[field] RXVLANGBFIS*/ + #define MMC_RECEIVE_INTERRUPT_RXVLANGBFIS + #define MMC_RECEIVE_INTERRUPT_RXVLANGBFIS_OFFSET 21 + #define MMC_RECEIVE_INTERRUPT_RXVLANGBFIS_LEN 1 + #define MMC_RECEIVE_INTERRUPT_RXVLANGBFIS_DEFAULT 0x0 + /*[field] RXWDOGFIS*/ + #define MMC_RECEIVE_INTERRUPT_RXWDOGFIS + #define MMC_RECEIVE_INTERRUPT_RXWDOGFIS_OFFSET 22 + #define MMC_RECEIVE_INTERRUPT_RXWDOGFIS_LEN 1 + #define MMC_RECEIVE_INTERRUPT_RXWDOGFIS_DEFAULT 0x0 + /*[field] RXDISFCGBIS*/ + #define MMC_RECEIVE_INTERRUPT_RXDISFCGBIS + #define MMC_RECEIVE_INTERRUPT_RXDISFCGBIS_OFFSET 23 + #define MMC_RECEIVE_INTERRUPT_RXDISFCGBIS_LEN 1 + #define MMC_RECEIVE_INTERRUPT_RXDISFCGBIS_DEFAULT 0x0 + /*[field] RXDISOCGBIS*/ + #define MMC_RECEIVE_INTERRUPT_RXDISOCGBIS + #define MMC_RECEIVE_INTERRUPT_RXDISOCGBIS_OFFSET 24 + #define MMC_RECEIVE_INTERRUPT_RXDISOCGBIS_LEN 1 + #define MMC_RECEIVE_INTERRUPT_RXDISOCGBIS_DEFAULT 0x0 + /*[field] RXLPIUSCIS*/ + #define MMC_RECEIVE_INTERRUPT_RXLPIUSCIS + #define MMC_RECEIVE_INTERRUPT_RXLPIUSCIS_OFFSET 25 + #define MMC_RECEIVE_INTERRUPT_RXLPIUSCIS_LEN 1 + #define MMC_RECEIVE_INTERRUPT_RXLPIUSCIS_DEFAULT 0x0 + /*[field] RXLPITRCIS*/ + #define MMC_RECEIVE_INTERRUPT_RXLPITRCIS + #define MMC_RECEIVE_INTERRUPT_RXLPITRCIS_OFFSET 26 + #define MMC_RECEIVE_INTERRUPT_RXLPITRCIS_LEN 1 + #define MMC_RECEIVE_INTERRUPT_RXLPITRCIS_DEFAULT 0x0 + /*[field] RXPRMMCIS*/ + #define MMC_RECEIVE_INTERRUPT_RXPRMMCIS + #define MMC_RECEIVE_INTERRUPT_RXPRMMCIS_OFFSET 31 + #define MMC_RECEIVE_INTERRUPT_RXPRMMCIS_LEN 1 + #define MMC_RECEIVE_INTERRUPT_RXPRMMCIS_DEFAULT 0x0 + +struct mmc_receive_interrupt { + a_uint32_t rxgbfrmis:1; + a_uint32_t rxgboctis:1; + a_uint32_t rxgoctis:1; + a_uint32_t rxbcgfis:1; + a_uint32_t rxmcgfis:1; + a_uint32_t rxcrcerfis:1; + a_uint32_t rxruntfis:1; + a_uint32_t rxjaberfis:1; + a_uint32_t rxusizegfis:1; + a_uint32_t rxosizegfis:1; + a_uint32_t rx64octgbfis:1; + a_uint32_t rx65t127octgbfis:1; + a_uint32_t rx128t255octgbfis:1; + a_uint32_t rx256t511octgbfis:1; + a_uint32_t rx512t1023octgbfis:1; + a_uint32_t rx1024tmaxoctgbfis:1; + a_uint32_t rxucgfis:1; + a_uint32_t rxlenerfis:1; + a_uint32_t rxorangefis:1; + a_uint32_t rxpausfis:1; + a_uint32_t rxfovfis:1; + a_uint32_t rxvlangbfis:1; + a_uint32_t rxwdogfis:1; + a_uint32_t rxdisfcgbis:1; + a_uint32_t rxdisocgbis:1; + a_uint32_t rxlpiuscis:1; + a_uint32_t rxlpitrcis:1; + a_uint32_t _reserved0:4; + a_uint32_t rxprmmcis:1; +}; + +union mmc_receive_interrupt_u { + a_uint32_t val; + struct mmc_receive_interrupt bf; +}; + +/*[register] MMC_TRANSMIT_INTERRUPT*/ +#define MMC_TRANSMIT_INTERRUPT +#define MMC_TRANSMIT_INTERRUPT_ADDRESS 0x808 +#define MMC_TRANSMIT_INTERRUPT_NUM 2 +#define MMC_TRANSMIT_INTERRUPT_INC 0x4000 +#define MMC_TRANSMIT_INTERRUPT_TYPE REG_TYPE_RO +#define MMC_TRANSMIT_INTERRUPT_DEFAULT 0x0 + /*[field] TXGBOCTIS*/ + #define MMC_TRANSMIT_INTERRUPT_TXGBOCTIS + #define MMC_TRANSMIT_INTERRUPT_TXGBOCTIS_OFFSET 0 + #define MMC_TRANSMIT_INTERRUPT_TXGBOCTIS_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_TXGBOCTIS_DEFAULT 0x0 + /*[field] TXGBFRMIS*/ + #define MMC_TRANSMIT_INTERRUPT_TXGBFRMIS + #define MMC_TRANSMIT_INTERRUPT_TXGBFRMIS_OFFSET 1 + #define MMC_TRANSMIT_INTERRUPT_TXGBFRMIS_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_TXGBFRMIS_DEFAULT 0x0 + /*[field] TXBCGFIS*/ + #define MMC_TRANSMIT_INTERRUPT_TXBCGFIS + #define MMC_TRANSMIT_INTERRUPT_TXBCGFIS_OFFSET 2 + #define MMC_TRANSMIT_INTERRUPT_TXBCGFIS_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_TXBCGFIS_DEFAULT 0x0 + /*[field] TXMCGFIS*/ + #define MMC_TRANSMIT_INTERRUPT_TXMCGFIS + #define MMC_TRANSMIT_INTERRUPT_TXMCGFIS_OFFSET 3 + #define MMC_TRANSMIT_INTERRUPT_TXMCGFIS_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_TXMCGFIS_DEFAULT 0x0 + /*[field] TX64OCTGBFIS*/ + #define MMC_TRANSMIT_INTERRUPT_TX64OCTGBFIS + #define MMC_TRANSMIT_INTERRUPT_TX64OCTGBFIS_OFFSET 4 + #define MMC_TRANSMIT_INTERRUPT_TX64OCTGBFIS_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_TX64OCTGBFIS_DEFAULT 0x0 + /*[field] TX65T127OCTGBFIS*/ + #define MMC_TRANSMIT_INTERRUPT_TX65T127OCTGBFIS + #define MMC_TRANSMIT_INTERRUPT_TX65T127OCTGBFIS_OFFSET 5 + #define MMC_TRANSMIT_INTERRUPT_TX65T127OCTGBFIS_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_TX65T127OCTGBFIS_DEFAULT 0x0 + /*[field] TX128T255OCTGBFIS*/ + #define MMC_TRANSMIT_INTERRUPT_TX128T255OCTGBFIS + #define MMC_TRANSMIT_INTERRUPT_TX128T255OCTGBFIS_OFFSET 6 + #define MMC_TRANSMIT_INTERRUPT_TX128T255OCTGBFIS_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_TX128T255OCTGBFIS_DEFAULT 0x0 + /*[field] TX256T511OCTGBFIS*/ + #define MMC_TRANSMIT_INTERRUPT_TX256T511OCTGBFIS + #define MMC_TRANSMIT_INTERRUPT_TX256T511OCTGBFIS_OFFSET 7 + #define MMC_TRANSMIT_INTERRUPT_TX256T511OCTGBFIS_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_TX256T511OCTGBFIS_DEFAULT 0x0 + /*[field] TX512T1023OCTGBFIS*/ + #define MMC_TRANSMIT_INTERRUPT_TX512T1023OCTGBFIS + #define MMC_TRANSMIT_INTERRUPT_TX512T1023OCTGBFIS_OFFSET 8 + #define MMC_TRANSMIT_INTERRUPT_TX512T1023OCTGBFIS_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_TX512T1023OCTGBFIS_DEFAULT 0x0 + /*[field] TX1024TMAXOCTGBFIS*/ + #define MMC_TRANSMIT_INTERRUPT_TX1024TMAXOCTGBFIS + #define MMC_TRANSMIT_INTERRUPT_TX1024TMAXOCTGBFIS_OFFSET 9 + #define MMC_TRANSMIT_INTERRUPT_TX1024TMAXOCTGBFIS_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_TX1024TMAXOCTGBFIS_DEFAULT 0x0 + /*[field] TXUCGBFIS*/ + #define MMC_TRANSMIT_INTERRUPT_TXUCGBFIS + #define MMC_TRANSMIT_INTERRUPT_TXUCGBFIS_OFFSET 10 + #define MMC_TRANSMIT_INTERRUPT_TXUCGBFIS_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_TXUCGBFIS_DEFAULT 0x0 + /*[field] TXMCGBFIS*/ + #define MMC_TRANSMIT_INTERRUPT_TXMCGBFIS + #define MMC_TRANSMIT_INTERRUPT_TXMCGBFIS_OFFSET 11 + #define MMC_TRANSMIT_INTERRUPT_TXMCGBFIS_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_TXMCGBFIS_DEFAULT 0x0 + /*[field] TXBCGBFIS*/ + #define MMC_TRANSMIT_INTERRUPT_TXBCGBFIS + #define MMC_TRANSMIT_INTERRUPT_TXBCGBFIS_OFFSET 12 + #define MMC_TRANSMIT_INTERRUPT_TXBCGBFIS_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_TXBCGBFIS_DEFAULT 0x0 + /*[field] TXUFLOWERFIS*/ + #define MMC_TRANSMIT_INTERRUPT_TXUFLOWERFIS + #define MMC_TRANSMIT_INTERRUPT_TXUFLOWERFIS_OFFSET 13 + #define MMC_TRANSMIT_INTERRUPT_TXUFLOWERFIS_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_TXUFLOWERFIS_DEFAULT 0x0 + /*[field] TXGOCTIS*/ + #define MMC_TRANSMIT_INTERRUPT_TXGOCTIS + #define MMC_TRANSMIT_INTERRUPT_TXGOCTIS_OFFSET 14 + #define MMC_TRANSMIT_INTERRUPT_TXGOCTIS_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_TXGOCTIS_DEFAULT 0x0 + /*[field] TXGFRMIS*/ + #define MMC_TRANSMIT_INTERRUPT_TXGFRMIS + #define MMC_TRANSMIT_INTERRUPT_TXGFRMIS_OFFSET 15 + #define MMC_TRANSMIT_INTERRUPT_TXGFRMIS_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_TXGFRMIS_DEFAULT 0x0 + /*[field] TXPAUSFIS*/ + #define MMC_TRANSMIT_INTERRUPT_TXPAUSFIS + #define MMC_TRANSMIT_INTERRUPT_TXPAUSFIS_OFFSET 16 + #define MMC_TRANSMIT_INTERRUPT_TXPAUSFIS_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_TXPAUSFIS_DEFAULT 0x0 + /*[field] TXVLANGFIS*/ + #define MMC_TRANSMIT_INTERRUPT_TXVLANGFIS + #define MMC_TRANSMIT_INTERRUPT_TXVLANGFIS_OFFSET 17 + #define MMC_TRANSMIT_INTERRUPT_TXVLANGFIS_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_TXVLANGFIS_DEFAULT 0x0 + /*[field] TXLPIUSCIS*/ + #define MMC_TRANSMIT_INTERRUPT_TXLPIUSCIS + #define MMC_TRANSMIT_INTERRUPT_TXLPIUSCIS_OFFSET 18 + #define MMC_TRANSMIT_INTERRUPT_TXLPIUSCIS_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_TXLPIUSCIS_DEFAULT 0x0 + /*[field] TXLPITRCIS*/ + #define MMC_TRANSMIT_INTERRUPT_TXLPITRCIS + #define MMC_TRANSMIT_INTERRUPT_TXLPITRCIS_OFFSET 19 + #define MMC_TRANSMIT_INTERRUPT_TXLPITRCIS_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_TXLPITRCIS_DEFAULT 0x0 + /*[field] TXPRMMCIS*/ + #define MMC_TRANSMIT_INTERRUPT_TXPRMMCIS + #define MMC_TRANSMIT_INTERRUPT_TXPRMMCIS_OFFSET 31 + #define MMC_TRANSMIT_INTERRUPT_TXPRMMCIS_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_TXPRMMCIS_DEFAULT 0x0 + +struct mmc_transmit_interrupt { + a_uint32_t txgboctis:1; + a_uint32_t txgbfrmis:1; + a_uint32_t txbcgfis:1; + a_uint32_t txmcgfis:1; + a_uint32_t tx64octgbfis:1; + a_uint32_t tx65t127octgbfis:1; + a_uint32_t tx128t255octgbfis:1; + a_uint32_t tx256t511octgbfis:1; + a_uint32_t tx512t1023octgbfis:1; + a_uint32_t tx1024tmaxoctgbfis:1; + a_uint32_t txucgbfis:1; + a_uint32_t txmcgbfis:1; + a_uint32_t txbcgbfis:1; + a_uint32_t txuflowerfis:1; + a_uint32_t txgoctis:1; + a_uint32_t txgfrmis:1; + a_uint32_t txpausfis:1; + a_uint32_t txvlangfis:1; + a_uint32_t txlpiuscis:1; + a_uint32_t txlpitrcis:1; + a_uint32_t _reserved0:11; + a_uint32_t txprmmcis:1; +}; + +union mmc_transmit_interrupt_u { + a_uint32_t val; + struct mmc_transmit_interrupt bf; +}; + +/*[register] MMC_RECEIVE_INTERRUPT_ENABLE*/ +#define MMC_RECEIVE_INTERRUPT_ENABLE +#define MMC_RECEIVE_INTERRUPT_ENABLE_ADDRESS 0x80c +#define MMC_RECEIVE_INTERRUPT_ENABLE_NUM 2 +#define MMC_RECEIVE_INTERRUPT_ENABLE_INC 0x4000 +#define MMC_RECEIVE_INTERRUPT_ENABLE_TYPE REG_TYPE_RO +#define MMC_RECEIVE_INTERRUPT_ENABLE_DEFAULT 0x0 + /*[field] RXGBFRMIE*/ + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXGBFRMIE + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXGBFRMIE_OFFSET 0 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXGBFRMIE_LEN 1 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXGBFRMIE_DEFAULT 0x0 + /*[field] RXGBOCTIE*/ + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXGBOCTIE + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXGBOCTIE_OFFSET 1 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXGBOCTIE_LEN 1 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXGBOCTIE_DEFAULT 0x0 + /*[field] RXGOCTIE*/ + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXGOCTIE + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXGOCTIE_OFFSET 2 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXGOCTIE_LEN 1 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXGOCTIE_DEFAULT 0x0 + /*[field] RXBCGFIE*/ + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXBCGFIE + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXBCGFIE_OFFSET 3 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXBCGFIE_LEN 1 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXBCGFIE_DEFAULT 0x0 + /*[field] RXMCGFIE*/ + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXMCGFIE + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXMCGFIE_OFFSET 4 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXMCGFIE_LEN 1 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXMCGFIE_DEFAULT 0x0 + /*[field] RXCRCERFIE*/ + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXCRCERFIE + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXCRCERFIE_OFFSET 5 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXCRCERFIE_LEN 1 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXCRCERFIE_DEFAULT 0x0 + /*[field] RXRUNTFIE*/ + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXRUNTFIE + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXRUNTFIE_OFFSET 6 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXRUNTFIE_LEN 1 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXRUNTFIE_DEFAULT 0x0 + /*[field] RXJABERFIE*/ + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXJABERFIE + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXJABERFIE_OFFSET 7 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXJABERFIE_LEN 1 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXJABERFIE_DEFAULT 0x0 + /*[field] RXUSIZEGFIE*/ + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXUSIZEGFIE + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXUSIZEGFIE_OFFSET 8 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXUSIZEGFIE_LEN 1 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXUSIZEGFIE_DEFAULT 0x0 + /*[field] RXOSIZEGFIE*/ + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXOSIZEGFIE + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXOSIZEGFIE_OFFSET 9 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXOSIZEGFIE_LEN 1 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXOSIZEGFIE_DEFAULT 0x0 + /*[field] RX64OCTGBFIE*/ + #define MMC_RECEIVE_INTERRUPT_ENABLE_RX64OCTGBFIE + #define MMC_RECEIVE_INTERRUPT_ENABLE_RX64OCTGBFIE_OFFSET 10 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RX64OCTGBFIE_LEN 1 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RX64OCTGBFIE_DEFAULT 0x0 + /*[field] RX65T127OCTGBFIE*/ + #define MMC_RECEIVE_INTERRUPT_ENABLE_RX65T127OCTGBFIE + #define MMC_RECEIVE_INTERRUPT_ENABLE_RX65T127OCTGBFIE_OFFSET 11 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RX65T127OCTGBFIE_LEN 1 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RX65T127OCTGBFIE_DEFAULT 0x0 + /*[field] RX128T255OCTGBFIE*/ + #define MMC_RECEIVE_INTERRUPT_ENABLE_RX128T255OCTGBFIE + #define MMC_RECEIVE_INTERRUPT_ENABLE_RX128T255OCTGBFIE_OFFSET 12 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RX128T255OCTGBFIE_LEN 1 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RX128T255OCTGBFIE_DEFAULT 0x0 + /*[field] RX256T511OCTGBFIE*/ + #define MMC_RECEIVE_INTERRUPT_ENABLE_RX256T511OCTGBFIE + #define MMC_RECEIVE_INTERRUPT_ENABLE_RX256T511OCTGBFIE_OFFSET 13 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RX256T511OCTGBFIE_LEN 1 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RX256T511OCTGBFIE_DEFAULT 0x0 + /*[field] RX512T1023OCTGBFIE*/ + #define MMC_RECEIVE_INTERRUPT_ENABLE_RX512T1023OCTGBFIE + #define MMC_RECEIVE_INTERRUPT_ENABLE_RX512T1023OCTGBFIE_OFFSET 14 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RX512T1023OCTGBFIE_LEN 1 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RX512T1023OCTGBFIE_DEFAULT 0x0 + /*[field] RX1024TMAXOCTGBFIE*/ + #define MMC_RECEIVE_INTERRUPT_ENABLE_RX1024TMAXOCTGBFIE + #define MMC_RECEIVE_INTERRUPT_ENABLE_RX1024TMAXOCTGBFIE_OFFSET 15 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RX1024TMAXOCTGBFIE_LEN 1 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RX1024TMAXOCTGBFIE_DEFAULT 0x0 + /*[field] RXUCGFIE*/ + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXUCGFIE + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXUCGFIE_OFFSET 16 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXUCGFIE_LEN 1 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXUCGFIE_DEFAULT 0x0 + /*[field] RXLENERFIE*/ + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXLENERFIE + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXLENERFIE_OFFSET 17 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXLENERFIE_LEN 1 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXLENERFIE_DEFAULT 0x0 + /*[field] RXORANGEFIE*/ + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXORANGEFIE + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXORANGEFIE_OFFSET 18 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXORANGEFIE_LEN 1 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXORANGEFIE_DEFAULT 0x0 + /*[field] RXPAUSFIE*/ + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXPAUSFIE + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXPAUSFIE_OFFSET 19 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXPAUSFIE_LEN 1 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXPAUSFIE_DEFAULT 0x0 + /*[field] RXFOVFIE*/ + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXFOVFIE + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXFOVFIE_OFFSET 20 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXFOVFIE_LEN 1 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXFOVFIE_DEFAULT 0x0 + /*[field] RXVLANGBFIE*/ + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXVLANGBFIE + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXVLANGBFIE_OFFSET 21 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXVLANGBFIE_LEN 1 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXVLANGBFIE_DEFAULT 0x0 + /*[field] RXWDOGFIE*/ + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXWDOGFIE + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXWDOGFIE_OFFSET 22 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXWDOGFIE_LEN 1 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXWDOGFIE_DEFAULT 0x0 + /*[field] RXDISFCIE*/ + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXDISFCIE + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXDISFCIE_OFFSET 23 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXDISFCIE_LEN 1 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXDISFCIE_DEFAULT 0x0 + /*[field] RXDISOCIE*/ + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXDISOCIE + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXDISOCIE_OFFSET 24 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXDISOCIE_LEN 1 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXDISOCIE_DEFAULT 0x0 + /*[field] RXLPIUSCIE*/ + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXLPIUSCIE + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXLPIUSCIE_OFFSET 25 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXLPIUSCIE_LEN 1 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXLPIUSCIE_DEFAULT 0x0 + /*[field] RXLPITRCIE*/ + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXLPITRCIE + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXLPITRCIE_OFFSET 26 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXLPITRCIE_LEN 1 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXLPITRCIE_DEFAULT 0x0 + /*[field] RXPRMMCISE*/ + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXPRMMCISE + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXPRMMCISE_OFFSET 31 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXPRMMCISE_LEN 1 + #define MMC_RECEIVE_INTERRUPT_ENABLE_RXPRMMCISE_DEFAULT 0x0 + +struct mmc_receive_interrupt_enable { + a_uint32_t rxgbfrmie:1; + a_uint32_t rxgboctie:1; + a_uint32_t rxgoctie:1; + a_uint32_t rxbcgfie:1; + a_uint32_t rxmcgfie:1; + a_uint32_t rxcrcerfie:1; + a_uint32_t rxruntfie:1; + a_uint32_t rxjaberfie:1; + a_uint32_t rxusizegfie:1; + a_uint32_t rxosizegfie:1; + a_uint32_t rx64octgbfie:1; + a_uint32_t rx65t127octgbfie:1; + a_uint32_t rx128t255octgbfie:1; + a_uint32_t rx256t511octgbfie:1; + a_uint32_t rx512t1023octgbfie:1; + a_uint32_t rx1024tmaxoctgbfie:1; + a_uint32_t rxucgfie:1; + a_uint32_t rxlenerfie:1; + a_uint32_t rxorangefie:1; + a_uint32_t rxpausfie:1; + a_uint32_t rxfovfie:1; + a_uint32_t rxvlangbfie:1; + a_uint32_t rxwdogfie:1; + a_uint32_t rxdisfcie:1; + a_uint32_t rxdisocie:1; + a_uint32_t rxlpiuscie:1; + a_uint32_t rxlpitrcie:1; + a_uint32_t _reserved0:4; + a_uint32_t rxprmmcise:1; +}; + +union mmc_receive_interrupt_enable_u { + a_uint32_t val; + struct mmc_receive_interrupt_enable bf; +}; + +/*[register] MMC_TRANSMIT_INTERRUPT_ENABLE*/ +#define MMC_TRANSMIT_INTERRUPT_ENABLE +#define MMC_TRANSMIT_INTERRUPT_ENABLE_ADDRESS 0x810 +#define MMC_TRANSMIT_INTERRUPT_ENABLE_NUM 2 +#define MMC_TRANSMIT_INTERRUPT_ENABLE_INC 0x4000 +#define MMC_TRANSMIT_INTERRUPT_ENABLE_TYPE REG_TYPE_RO +#define MMC_TRANSMIT_INTERRUPT_ENABLE_DEFAULT 0x0 + /*[field] TXGBOCTIE*/ + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXGBOCTIE + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXGBOCTIE_OFFSET 0 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXGBOCTIE_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXGBOCTIE_DEFAULT 0x0 + /*[field] TXGBFRMIE*/ + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXGBFRMIE + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXGBFRMIE_OFFSET 1 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXGBFRMIE_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXGBFRMIE_DEFAULT 0x0 + /*[field] TXBCGFIE*/ + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXBCGFIE + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXBCGFIE_OFFSET 2 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXBCGFIE_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXBCGFIE_DEFAULT 0x0 + /*[field] TXMCGFIE*/ + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXMCGFIE + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXMCGFIE_OFFSET 3 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXMCGFIE_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXMCGFIE_DEFAULT 0x0 + /*[field] TX64OCTGBFIE*/ + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TX64OCTGBFIE + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TX64OCTGBFIE_OFFSET 4 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TX64OCTGBFIE_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TX64OCTGBFIE_DEFAULT 0x0 + /*[field] TX65T127OCTGBFIE*/ + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TX65T127OCTGBFIE + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TX65T127OCTGBFIE_OFFSET 5 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TX65T127OCTGBFIE_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TX65T127OCTGBFIE_DEFAULT 0x0 + /*[field] TX128T255OCTGBFIE*/ + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TX128T255OCTGBFIE + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TX128T255OCTGBFIE_OFFSET 6 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TX128T255OCTGBFIE_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TX128T255OCTGBFIE_DEFAULT 0x0 + /*[field] TX256T511OCTGBFIE*/ + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TX256T511OCTGBFIE + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TX256T511OCTGBFIE_OFFSET 7 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TX256T511OCTGBFIE_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TX256T511OCTGBFIE_DEFAULT 0x0 + /*[field] TX512T1023OCTGBFIE*/ + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TX512T1023OCTGBFIE + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TX512T1023OCTGBFIE_OFFSET 8 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TX512T1023OCTGBFIE_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TX512T1023OCTGBFIE_DEFAULT 0x0 + /*[field] TX1024TMAXOCTGBFIE*/ + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TX1024TMAXOCTGBFIE + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TX1024TMAXOCTGBFIE_OFFSET 9 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TX1024TMAXOCTGBFIE_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TX1024TMAXOCTGBFIE_DEFAULT 0x0 + /*[field] TXUCGBFIE*/ + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXUCGBFIE + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXUCGBFIE_OFFSET 10 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXUCGBFIE_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXUCGBFIE_DEFAULT 0x0 + /*[field] TXMCGBFIE*/ + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXMCGBFIE + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXMCGBFIE_OFFSET 11 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXMCGBFIE_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXMCGBFIE_DEFAULT 0x0 + /*[field] TXBCGBFIE*/ + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXBCGBFIE + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXBCGBFIE_OFFSET 12 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXBCGBFIE_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXBCGBFIE_DEFAULT 0x0 + /*[field] TXUFLOWERFIE*/ + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXUFLOWERFIE + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXUFLOWERFIE_OFFSET 13 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXUFLOWERFIE_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXUFLOWERFIE_DEFAULT 0x0 + /*[field] TXGOCTIE*/ + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXGOCTIE + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXGOCTIE_OFFSET 14 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXGOCTIE_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXGOCTIE_DEFAULT 0x0 + /*[field] TXGFRMIE*/ + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXGFRMIE + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXGFRMIE_OFFSET 15 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXGFRMIE_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXGFRMIE_DEFAULT 0x0 + /*[field] TXPAUSFIE*/ + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXPAUSFIE + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXPAUSFIE_OFFSET 16 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXPAUSFIE_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXPAUSFIE_DEFAULT 0x0 + /*[field] TXVLANGFIE*/ + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXVLANGFIE + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXVLANGFIE_OFFSET 17 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXVLANGFIE_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXVLANGFIE_DEFAULT 0x0 + /*[field] TXLPIUSCIE*/ + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXLPIUSCIE + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXLPIUSCIE_OFFSET 18 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXLPIUSCIE_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXLPIUSCIE_DEFAULT 0x0 + /*[field] TXLPITRCIE*/ + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXLPITRCIE + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXLPITRCIE_OFFSET 19 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXLPITRCIE_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXLPITRCIE_DEFAULT 0x0 + /*[field] TXPRMMCISE*/ + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXPRMMCISE + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXPRMMCISE_OFFSET 31 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXPRMMCISE_LEN 1 + #define MMC_TRANSMIT_INTERRUPT_ENABLE_TXPRMMCISE_DEFAULT 0x0 + +struct mmc_transmit_interrupt_enable { + a_uint32_t txgboctie:1; + a_uint32_t txgbfrmie:1; + a_uint32_t txbcgfie:1; + a_uint32_t txmcgfie:1; + a_uint32_t tx64octgbfie:1; + a_uint32_t tx65t127octgbfie:1; + a_uint32_t tx128t255octgbfie:1; + a_uint32_t tx256t511octgbfie:1; + a_uint32_t tx512t1023octgbfie:1; + a_uint32_t tx1024tmaxoctgbfie:1; + a_uint32_t txucgbfie:1; + a_uint32_t txmcgbfie:1; + a_uint32_t txbcgbfie:1; + a_uint32_t txuflowerfie:1; + a_uint32_t txgoctie:1; + a_uint32_t txgfrmie:1; + a_uint32_t txpausfie:1; + a_uint32_t txvlangfie:1; + a_uint32_t txlpiuscie:1; + a_uint32_t txlpitrcie:1; + a_uint32_t _reserved0:11; + a_uint32_t txprmmcise:1; +}; + +union mmc_transmit_interrupt_enable_u { + a_uint32_t val; + struct mmc_transmit_interrupt_enable bf; +}; + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hsl.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hsl.h new file mode 100755 index 000000000..1bb923ab3 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hsl.h @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2012,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 _HSL_H +#define _HSL_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "ssdk_init.h" + + typedef sw_error_t + (*hsl_acl_rule_copy) (a_uint32_t dev_id, a_uint32_t src_addr, + a_uint32_t dest_addr, a_uint32_t size); + + typedef sw_error_t + (*hsl_acl_rule_invalid) (a_uint32_t dev_id, a_uint32_t addr, + a_uint32_t size); + + typedef sw_error_t + (*hsl_acl_addr_update) (a_uint32_t dev_id, a_uint32_t old_addr, + a_uint32_t new_addr, a_uint32_t info); + + typedef struct + { + hsl_acl_rule_copy acl_rule_copy; + hsl_acl_rule_invalid acl_rule_invalid; + hsl_acl_addr_update acl_addr_update; + } hsl_acl_func_t; +/*qca808x_end*/ + +#if 1 +extern sw_error_t reduce_hsl_reg_entry_get(a_uint32_t dev,a_uint32_t reg,a_uint8_t* value,a_uint8_t val_len); +#define HSL_REG_ENTRY_GET(rv, dev, reg, index, value, val_len) \ + rv = reduce_hsl_reg_entry_get(dev,reg##_OFFSET + ((a_uint32_t)index) * reg##_E_OFFSET,value,val_len); + + +extern sw_error_t reduce_hsl_reg_entry_set(a_uint32_t dev,a_uint32_t reg,a_uint8_t* value,a_uint8_t val_len); +#define HSL_REG_ENTRY_SET(rv, dev, reg, index, value, val_len) \ + rv = reduce_hsl_reg_entry_set(dev,reg##_OFFSET + ((a_uint32_t)index) * reg##_E_OFFSET,value,val_len); + +extern sw_error_t reduce_hsl_reg_field_get(a_uint32_t dev,a_uint32_t reg,a_uint32_t reg_offset, + a_uint32_t reg_offset_len,a_uint8_t* value,a_uint8_t val_len); +#define HSL_REG_FIELD_GET(rv, dev, reg, index, field, value, val_len) \ + rv = reduce_hsl_reg_field_get(dev,reg##_OFFSET + ((a_uint32_t)index) * reg##_E_OFFSET,\ + reg##_##field##_BOFFSET, \ + reg##_##field##_BLEN,value,val_len); + +extern sw_error_t reduce_hsl_reg_field_set(a_uint32_t dev,a_uint32_t reg,a_uint32_t reg_offset, + a_uint32_t reg_offset_len,a_uint8_t* value,a_uint8_t val_len); + +#define HSL_REG_FIELD_SET(rv, dev, reg, index, field, value, val_len) \ + rv = reduce_hsl_reg_field_set(dev,reg##_OFFSET + ((a_uint32_t)index) * reg##_E_OFFSET,\ + reg##_##field##_BOFFSET, \ + reg##_##field##_BLEN,value,val_len); + + + +extern sw_error_t reduce_hsl_reg_entry_gen_get(a_uint32_t dev,a_uint32_t addr,a_uint8_t* value,a_uint8_t val_len); +#define HSL_REG_ENTRY_GEN_GET(rv, dev, addr, reg_len, value, val_len) \ + rv = reduce_hsl_reg_entry_gen_get(dev,addr,(a_uint8_t*)value,val_len); + + +extern sw_error_t reduce_hsl_reg_entry_gen_set(a_uint32_t dev,a_uint32_t addr,a_uint8_t* value,a_uint8_t val_len); +#define HSL_REG_ENTRY_GEN_SET(rv, dev, addr, reg_len, value, val_len) \ + rv = reduce_hsl_reg_entry_gen_set(dev,addr,(a_uint8_t*)value,val_len); + + + + +extern sw_error_t reduce_hsl_reg_field_gen_get(a_uint32_t dev,a_uint32_t reg_addr, + a_uint32_t bitoffset, a_uint32_t field_len, a_uint8_t* value,a_uint8_t val_len); +#define HSL_REG_FIELD_GEN_GET(rv, dev, regaddr, bitlength, bitoffset, value, val_len) \ + rv = reduce_hsl_reg_field_gen_get(dev, regaddr, bitoffset, bitlength, (a_uint8_t*)value, val_len); + +extern sw_error_t reduce_hsl_reg_field_gen_set(a_uint32_t dev,a_uint32_t regaddr,a_uint32_t bitoffset, + a_uint32_t bitlength,a_uint8_t* value,a_uint8_t val_len); + +#define HSL_REG_FIELD_GEN_SET(rv, dev, regaddr, bitlength, bitoffset, value, val_len) \ + rv = reduce_hsl_reg_field_gen_set(dev,regaddr,bitoffset,bitlength, (a_uint8_t*)value,val_len); + + +/*qca808x_start*/ +extern sw_error_t reduce_hsl_phy_get(a_uint32_t dev,a_uint32_t phy_addr,a_uint32_t reg,a_uint16_t* value); +#define HSL_PHY_GET(rv, dev, phy_addr, reg, value) \ + rv = reduce_hsl_phy_get(dev,phy_addr,reg,value); + + +extern sw_error_t reduce_hsl_phy_set(a_uint32_t dev,a_uint32_t phy_addr,a_uint32_t reg,a_uint16_t value); +#define HSL_PHY_SET(rv, dev, phy_addr, reg, value) \ + rv = reduce_hsl_phy_set(dev,phy_addr,reg,value); + +extern sw_error_t hsl_phy_i2c_get(a_uint32_t dev,a_uint32_t phy_addr,a_uint32_t reg,a_uint16_t* value); +#define HSL_PHY_I2C_GET(rv, dev, phy_addr, reg, value) \ + rv = hsl_phy_i2c_get(dev,phy_addr,reg,value); + + +extern sw_error_t hsl_phy_i2c_set(a_uint32_t dev,a_uint32_t phy_addr,a_uint32_t reg,a_uint16_t value); +#define HSL_PHY_I2C_SET(rv, dev, phy_addr, reg, value) \ + rv = hsl_phy_i2c_set(dev,phy_addr,reg,value); +/*qca808x_end*/ + + + + +#else +#define HSL_REG_ENTRY_GET(rv, dev, reg, index, value, val_len) \ +do { \ + hsl_api_t *p_api = hsl_api_ptr_get(dev); \ + if (p_api) { \ + rv = p_api->reg_get(dev, reg##_OFFSET + ((a_uint32_t)index) * reg##_E_OFFSET,\ + (a_uint8_t*)value, (a_uint8_t)val_len); \ + } else { \ + rv = SW_NOT_INITIALIZED; \ + } \ +} while (0); + +#define HSL_REG_ENTRY_SET(rv, dev, reg, index, value, val_len) \ +do { \ + hsl_api_t *p_api = hsl_api_ptr_get(dev); \ + if (p_api) { \ + rv = p_api->reg_set (dev, reg##_OFFSET + ((a_uint32_t)index) * reg##_E_OFFSET,\ + (a_uint8_t*)value, (a_uint8_t)val_len); \ + } else { \ + rv = SW_NOT_INITIALIZED; \ + } \ +} while (0); + +#define HSL_REG_FIELD_GET(rv, dev, reg, index, field, value, val_len) \ +do { \ + hsl_api_t *p_api = hsl_api_ptr_get(dev); \ + if (p_api) { \ + rv = p_api->reg_field_get(dev, reg##_OFFSET + ((a_uint32_t)index) * reg##_E_OFFSET,\ + reg##_##field##_BOFFSET, \ + reg##_##field##_BLEN, (a_uint8_t*)value, val_len);\ + } else { \ + rv = SW_NOT_INITIALIZED; \ + } \ +} while (0); + +#define HSL_REG_FIELD_SET(rv, dev, reg, index, field, value, val_len) \ +do { \ + hsl_api_t *p_api = hsl_api_ptr_get(dev); \ + if (p_api){ \ + rv = p_api->reg_field_set(dev, reg##_OFFSET + ((a_uint32_t)index) * reg##_E_OFFSET,\ + reg##_##field##_BOFFSET, \ + reg##_##field##_BLEN, (a_uint8_t*)value, val_len);\ + } else { \ + rv = SW_NOT_INITIALIZED; \ + } \ +} while (0); + +#define HSL_REG_ENTRY_GEN_GET(rv, dev, addr, reg_len, value, val_len) \ +do { \ + hsl_api_t *p_api = hsl_api_ptr_get(dev); \ + if (p_api) { \ + rv = p_api->reg_get(dev, addr, (a_uint8_t*)value, val_len);\ + } else { \ + rv = SW_NOT_INITIALIZED; \ + } \ +} while (0); + +#define HSL_REG_ENTRY_GEN_SET(rv, dev, addr, reg_len, value, val_len) \ +do { \ + hsl_api_t *p_api = hsl_api_ptr_get(dev); \ + if (p_api) { \ + rv = p_api->reg_set(dev, addr, (a_uint8_t*)value, val_len); \ + } else { \ + rv = SW_NOT_INITIALIZED; \ + } \ +} while (0); + +#define HSL_REG_FIELD_GEN_GET(rv, dev, regaddr, bitlength, bitoffset, value, val_len) \ +do { \ + hsl_api_t *p_api = hsl_api_ptr_get(dev); \ + if (p_api) { \ + rv = p_api->reg_field_get(dev, regaddr, bitoffset, bitlength, \ + (a_uint8_t *) value, val_len);\ + } else { \ + rv = SW_NOT_INITIALIZED; \ + } \ +} while (0); + +#define HSL_REG_FIELD_GEN_SET(rv, dev, regaddr, bitlength, bitoffset, value, val_len) \ +do { \ + hsl_api_t *p_api = hsl_api_ptr_get(dev); \ + if (p_api) {\ + rv = p_api->reg_field_set(dev, regaddr, bitoffset, bitlength, \ + (a_uint8_t *) value, val_len);\ + } else { \ + rv = SW_NOT_INITIALIZED; \ + } \ +} while (0); + +#define HSL_PHY_GET(rv, dev, phy_addr, reg, value) \ +do { \ + hsl_api_t *p_api = hsl_api_ptr_get(dev); \ + if (p_api) { \ + rv = p_api->phy_get(dev, phy_addr, reg, value); \ + } else { \ + rv = SW_NOT_INITIALIZED; \ + } \ +} while (0); + +#define HSL_PHY_SET(rv, dev, phy_addr, reg, value) \ +do { \ + hsl_api_t *p_api = hsl_api_ptr_get(dev); \ + if (p_api) { \ + rv = p_api->phy_set(dev, phy_addr, reg, value); \ + } else { \ + rv = SW_NOT_INITIALIZED; \ + } \ +} while (0); +#endif +/*qca808x_start*/ +#if (defined(API_LOCK) \ +&& (defined(HSL_STANDALONG) || (defined(KERNEL_MODULE) && defined(USER_MODE)))) + extern aos_lock_t sw_hsl_api_lock; +#define HSL_API_LOCK aos_lock(&sw_hsl_api_lock) +#define HSL_API_UNLOCK aos_unlock(&sw_hsl_api_lock) +#else +#define HSL_API_LOCK +#define HSL_API_UNLOCK +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _HSL_H */ +/*qca808x_end*/ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hsl_acl.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hsl_acl.h new file mode 100755 index 000000000..ab9518561 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hsl_acl.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _HSL_ACL_H_ +#define _HSL_ACL_H_ + +#ifdef __cplusplus +extern "c" { +#endif + + sw_error_t + hsl_acl_pool_creat(a_uint32_t dev_id, a_uint32_t blk_nr, a_uint32_t rsc_nr); + + sw_error_t + hsl_acl_pool_destroy(a_uint32_t dev_id); + + sw_error_t + hsl_acl_blk_alloc(a_uint32_t dev_id, a_uint32_t pri, a_uint32_t size, + a_uint32_t info, a_uint32_t * addr); + + sw_error_t + hsl_acl_blk_free(a_uint32_t dev_id, a_uint32_t addr); + + sw_error_t + hsl_acl_blk_resize(a_uint32_t dev_id, a_uint32_t addr, a_uint32_t new_size); + + sw_error_t + hsl_acl_free_rsc_get(a_uint32_t dev_id, a_uint32_t * free_rsc); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /*_HSL_ACL_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hsl_api.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hsl_api.h new file mode 100755 index 000000000..7ea0cc35d --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hsl_api.h @@ -0,0 +1,2619 @@ +/* + * Copyright (c) 2012, 2015, 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 _HSL_API_H +#define _HSL_API_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include "fal.h" +/*qca808x_end*/ + + /* Misc */ +#define MISC_FUNC_PROTOTYPE_DEF + typedef sw_error_t + (*hsl_arp_status_set) (a_uint32_t dev_id, a_bool_t enable); + + typedef sw_error_t + (*hsl_arp_status_get) (a_uint32_t dev_id, a_bool_t * enable); + + typedef sw_error_t + (*hsl_frame_max_size_set) (a_uint32_t dev_id, a_uint32_t size); + + typedef sw_error_t + (*hsl_frame_max_size_get) (a_uint32_t dev_id, a_uint32_t * size); + + typedef sw_error_t + (*hsl_port_unk_sa_cmd_set) (a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t cmd); + + typedef sw_error_t + (*hsl_port_unk_sa_cmd_get) (a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t * cmd); + + typedef sw_error_t + (*hsl_port_unk_uc_filter_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_port_unk_uc_filter_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_port_unk_mc_filter_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_port_unk_mc_filter_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_port_bc_filter_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_port_bc_filter_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_cpu_port_status_set) (a_uint32_t dev_id, a_bool_t enable); + + typedef sw_error_t + (*hsl_cpu_port_status_get) (a_uint32_t dev_id, a_bool_t * enable); + + typedef sw_error_t + (*hsl_bc_to_cpu_port_set) (a_uint32_t dev_id, a_bool_t enable); + + typedef sw_error_t + (*hsl_bc_to_cpu_port_get) (a_uint32_t dev_id, a_bool_t * enable); + + typedef sw_error_t + (*hsl_port_dhcp_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_pppoe_cmd_set) (a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + typedef sw_error_t + (*hsl_pppoe_cmd_get) (a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + typedef sw_error_t + (*hsl_pppoe_status_set) (a_uint32_t dev_id, a_bool_t enable); + + typedef sw_error_t + (*hsl_pppoe_status_get) (a_uint32_t dev_id, a_bool_t * enable); + + typedef sw_error_t + (*hsl_port_dhcp_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_arp_cmd_set) (a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + typedef sw_error_t + (*hsl_arp_cmd_get) (a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + typedef sw_error_t + (*hsl_eapol_cmd_set) (a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + typedef sw_error_t + (*hsl_eapol_cmd_get) (a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + typedef sw_error_t + (*hsl_pppoe_session_add) (a_uint32_t dev_id, a_uint32_t session_id, + a_bool_t strip_hdr); + + typedef sw_error_t + (*hsl_pppoe_session_del) (a_uint32_t dev_id, a_uint32_t session_id); + + typedef sw_error_t + (*hsl_pppoe_session_get) (a_uint32_t dev_id, a_uint32_t session_id, + a_bool_t * strip_hdr); + + typedef sw_error_t + (*hsl_eapol_status_set) (a_uint32_t dev_id, a_uint32_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_eapol_status_get) (a_uint32_t dev_id, a_uint32_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_ripv1_status_set) (a_uint32_t dev_id, a_bool_t enable); + + typedef sw_error_t + (*hsl_ripv1_status_get) (a_uint32_t dev_id, a_bool_t * enable); + + typedef sw_error_t + (*hsl_port_arp_req_status_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_port_arp_req_status_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_port_arp_ack_status_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_port_arp_ack_status_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_pppoe_session_table_add) (a_uint32_t dev_id, + fal_pppoe_session_t * session_tbl); + + typedef sw_error_t + (*hsl_pppoe_session_table_del) (a_uint32_t dev_id, + fal_pppoe_session_t * session_tbl); + + typedef sw_error_t + (*hsl_pppoe_session_table_get) (a_uint32_t dev_id, + fal_pppoe_session_t * session_tbl); + + typedef sw_error_t + (*hsl_pppoe_session_id_set) (a_uint32_t dev_id, a_uint32_t index, + a_uint32_t id); + + typedef sw_error_t + (*hsl_pppoe_session_id_get) (a_uint32_t dev_id, a_uint32_t index, + a_uint32_t * id); + + typedef sw_error_t + (*hsl_intr_mask_set) (a_uint32_t dev_id, a_uint32_t intr_mask); + + typedef sw_error_t + (*hsl_intr_mask_get) (a_uint32_t dev_id, a_uint32_t * intr_mask); + + typedef sw_error_t + (*hsl_intr_status_get) (a_uint32_t dev_id, a_uint32_t * intr_status); + + typedef sw_error_t + (*hsl_intr_status_clear) (a_uint32_t dev_id, a_uint32_t intr_status); + + typedef sw_error_t + (*hsl_intr_port_link_mask_set) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t intr_mask); + + typedef sw_error_t + (*hsl_intr_port_link_mask_get) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * intr_mask); + + typedef sw_error_t + (*hsl_intr_port_link_status_get) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * intr_mask); + + typedef sw_error_t + (*hsl_intr_mask_mac_linkchg_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_intr_mask_mac_linkchg_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_intr_status_mac_linkchg_get) (a_uint32_t dev_id, + fal_pbmp_t * port_bitmap); + + typedef sw_error_t (*hsl_intr_status_mac_linkchg_clear) (a_uint32_t dev_id); + + typedef sw_error_t + (*hsl_cpu_vid_en_set) (a_uint32_t dev_id, a_bool_t enable); + + typedef sw_error_t + (*hsl_cpu_vid_en_get) (a_uint32_t dev_id, a_bool_t * enable); + + typedef sw_error_t + (*hsl_rtd_pppoe_en_set) (a_uint32_t dev_id, a_bool_t enable); + + typedef sw_error_t + (*hsl_rtd_pppoe_en_get) (a_uint32_t dev_id, a_bool_t * enable); + + typedef sw_error_t + (*hsl_global_macaddr_set) (a_uint32_t dev_id, fal_mac_addr_t * addr); + + typedef sw_error_t + (*hsl_global_macaddr_get) (a_uint32_t dev_id, fal_mac_addr_t * addr); + + typedef sw_error_t + (*hsl_lldp_status_set) (a_uint32_t dev_id, a_bool_t enable); + + typedef sw_error_t + (*hsl_lldp_status_get) (a_uint32_t dev_id, a_bool_t * enable); + + typedef sw_error_t + (*hsl_frame_crc_reserve_set) (a_uint32_t dev_id, a_bool_t enable); + + typedef sw_error_t + (*hsl_frame_crc_reserve_get) (a_uint32_t dev_id, a_bool_t * enable); + + + typedef sw_error_t + (*hsl_register_dump) (a_uint32_t dev_id,a_uint32_t register_idx, fal_reg_dump_t * reg_dump); + + typedef sw_error_t + (*hsl_debug_register_dump) (a_uint32_t dev_id, fal_debug_reg_dump_t * reg_dump); + /*qca808x_start*/ + + /* Port Control */ +#define PORT_CONTROL_FUNC_PROTOTYPE_DEF + typedef sw_error_t + (*hsl_port_duplex_get) (a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t * pduplex); + + typedef sw_error_t + (*hsl_port_duplex_set) (a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t duplex); + + typedef sw_error_t + (*hsl_port_speed_get) (a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t * pspeed); + + typedef sw_error_t + (*hsl_port_autoneg_status_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status); + + typedef sw_error_t + (*hsl_port_speed_set) (a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t speed); + + typedef sw_error_t + (*hsl_port_autoneg_enable) (a_uint32_t dev_id, fal_port_t port_id); + + typedef sw_error_t + (*hsl_port_autoneg_restart) (a_uint32_t dev_id, fal_port_t port_id); + + typedef sw_error_t + (*hsl_port_autoneg_adv_get) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * autoadv); + + typedef sw_error_t + (*hsl_port_autoneg_adv_set) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t autoadv); + + typedef sw_error_t + (*hsl_port_hdr_status_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_port_hdr_status_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_port_flowctrl_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_port_flowctrl_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); +typedef sw_error_t + (*hsl_port_flowctrl_thresh_set) (a_uint32_t dev_id, fal_port_t port_id, + a_uint8_t on, a_uint8_t off); + + typedef sw_error_t + (*hsl_port_flowctrl_forcemode_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_port_flowctrl_forcemode_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_port_powersave_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + typedef sw_error_t + (*hsl_port_powersave_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + typedef sw_error_t + (*hsl_port_hibernate_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + typedef sw_error_t + (*hsl_port_hibernate_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + typedef sw_error_t + (*hsl_port_cdt) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mdi_pair, fal_cable_status_t * cable_status, + a_uint32_t * cable_len); + + typedef sw_error_t + (*hsl_port_rxhdr_mode_set) (a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t mode); + + typedef sw_error_t + (*hsl_port_rxhdr_mode_get) (a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t * mode); + + typedef sw_error_t + (*hsl_port_txhdr_mode_set) (a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t mode); + + typedef sw_error_t + (*hsl_port_txhdr_mode_get) (a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t * mode); + + typedef sw_error_t + (*hsl_header_type_set) (a_uint32_t dev_id, a_bool_t enable, + a_uint32_t type); + + typedef sw_error_t + (*hsl_header_type_get) (a_uint32_t dev_id, a_bool_t * enable, + a_uint32_t * type); + + typedef sw_error_t + (*hsl_port_txmac_status_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_port_txmac_status_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_port_rxmac_status_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_port_rxmac_status_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_port_txfc_status_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_port_txfc_status_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_port_rxfc_status_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_port_rxfc_status_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_port_bp_status_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_port_bp_status_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_port_link_forcemode_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_port_link_forcemode_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_port_link_status_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status); + + typedef sw_error_t + (*hsl_ports_link_status_get) (a_uint32_t dev_id, a_uint32_t * status); + + typedef sw_error_t + (*hsl_port_mac_loopback_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_port_mac_loopback_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_port_congestion_drop_set) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t queue_id, a_bool_t enable); + + typedef sw_error_t + (*hsl_port_congestion_drop_get) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t queue_id, a_bool_t * enable); + + typedef sw_error_t + (*hsl_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); + + typedef sw_error_t + (*hsl_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); + + typedef sw_error_t + (*hsl_port_8023az_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + typedef sw_error_t + (*hsl_port_8023az_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_port_mdix_set) (a_uint32_t dev_id, fal_port_t port_id, + fal_port_mdix_mode_t mode); + + typedef sw_error_t + (*hsl_port_mdix_get) (a_uint32_t dev_id, fal_port_t port_id, + fal_port_mdix_mode_t * mode); + + typedef sw_error_t + (*hsl_port_mdix_status_get) (a_uint32_t dev_id, fal_port_t port_id, + fal_port_mdix_status_t * mode); + + typedef sw_error_t + (*hsl_port_combo_prefer_medium_set) (a_uint32_t dev_id, + fal_port_t port_id, + fal_port_medium_t medium); + + typedef sw_error_t + (*hsl_port_combo_prefer_medium_get) (a_uint32_t dev_id, + fal_port_t port_id, + fal_port_medium_t * medium); + + typedef sw_error_t + (*hsl_port_combo_medium_status_get) (a_uint32_t dev_id, + fal_port_t port_id, + fal_port_medium_t * medium); + + typedef sw_error_t + (*hsl_port_combo_fiber_mode_set) (a_uint32_t dev_id, fal_port_t port_id, + fal_port_fiber_mode_t mode); + + typedef sw_error_t + (*hsl_port_combo_fiber_mode_get) (a_uint32_t dev_id, fal_port_t port_id, + fal_port_fiber_mode_t * mode); + + typedef sw_error_t + (*hsl_port_local_loopback_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_port_local_loopback_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_port_remote_loopback_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_port_remote_loopback_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_port_reset) (a_uint32_t dev_id, fal_port_t port_id); + + typedef sw_error_t + (*hsl_port_power_off) (a_uint32_t dev_id, fal_port_t port_id); + + typedef sw_error_t + (*hsl_port_power_on) (a_uint32_t dev_id, fal_port_t port_id); + + typedef sw_error_t + (*hsl_port_phy_id_get) (a_uint32_t dev_id, fal_port_t port_id,a_uint16_t * org_id, a_uint16_t * rev_id); + + typedef sw_error_t + (*hsl_port_wol_status_set) (a_uint32_t dev_id, fal_port_t port_id,a_bool_t enable); + + typedef sw_error_t + (*hsl_port_wol_status_get) (a_uint32_t dev_id, fal_port_t port_id,a_bool_t *enable); + + typedef sw_error_t + (*hsl_port_magic_frame_mac_set) (a_uint32_t dev_id, fal_port_t port_id,fal_mac_addr_t * mac); + + typedef sw_error_t + (*hsl_port_magic_frame_mac_get) (a_uint32_t dev_id, fal_port_t port_id,fal_mac_addr_t * mac); + + typedef sw_error_t + (*hsl_port_interface_mode_set) (a_uint32_t dev_id, fal_port_t port_id, + fal_port_interface_mode_t mode); + + typedef sw_error_t + (*hsl_port_interface_mode_get) (a_uint32_t dev_id, fal_port_t port_id, + fal_port_interface_mode_t * mode); + typedef sw_error_t + (*hsl_port_interface_mode_apply) (a_uint32_t dev_id); + + typedef sw_error_t + (*hsl_port_interface_mode_status_get) (a_uint32_t dev_id, fal_port_t port_id, + fal_port_interface_mode_t * mode); + typedef sw_error_t + (*hsl_port_counter_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + typedef sw_error_t + (*hsl_port_counter_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + typedef sw_error_t + (*hsl_port_counter_show) (a_uint32_t dev_id, fal_port_t port_id, + fal_port_counter_info_t * counter_info); +/*qca808x_end*/ + + /* VLAN */ +#define VLAN_FUNC_PROTOTYPE_DEF + typedef sw_error_t + (*hsl_vlan_entry_append) (a_uint32_t dev_id, + const fal_vlan_t * vlan_entry); + + typedef sw_error_t + (*hsl_vlan_create) (a_uint32_t dev_id, a_uint32_t vlan_id); + + typedef sw_error_t + (*hsl_vlan_next) (a_uint32_t dev_id, a_uint32_t vlan_id, + fal_vlan_t * p_vlan); + + typedef sw_error_t + (*hsl_vlan_find) (a_uint32_t dev_id, a_uint32_t vlan_id, + fal_vlan_t * p_vlan); + + typedef sw_error_t + (*hsl_vlan_member_update) (a_uint32_t dev_id, a_uint32_t vlan_id, + fal_pbmp_t member, fal_pbmp_t u_member); + + typedef sw_error_t + (*hsl_vlan_delete) (a_uint32_t dev_id, a_uint32_t vlan_id); + + typedef sw_error_t (*hsl_vlan_flush) (a_uint32_t dev_id); + + typedef sw_error_t + (*hsl_vlan_fid_set) (a_uint32_t dev_id, a_uint32_t vlan_id, + a_uint32_t fid); + + typedef sw_error_t + (*hsl_vlan_fid_get) (a_uint32_t dev_id, a_uint32_t vlan_id, + a_uint32_t * fid); + + typedef sw_error_t + (*hsl_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); + + typedef sw_error_t + (*hsl_vlan_member_del) (a_uint32_t dev_id, a_uint32_t vlan_id, + fal_port_t port_id); + + typedef sw_error_t + (*hsl_vlan_learning_state_set) (a_uint32_t dev_id, a_uint32_t vlan_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_vlan_learning_state_get) (a_uint32_t dev_id, a_uint32_t vlan_id, + a_bool_t * enable); + + /* Port Vlan */ +#define PORT_VLAN_FUNC_PROTOTYPE_DEF + typedef sw_error_t + (*hsl_port_1qmode_get) (a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t * pport_1qmode); + + typedef sw_error_t + (*hsl_port_1qmode_set) (a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t port_1qmode); + + typedef sw_error_t + (*hsl_port_egvlanmode_get) (a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t * pport_egvlanmode); + + typedef sw_error_t + (*hsl_port_egvlanmode_set) (a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t port_egvlanmode); + + typedef sw_error_t + (*hsl_portvlan_member_add) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id); + + typedef sw_error_t + (*hsl_portvlan_member_del) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id); + + typedef sw_error_t + (*hsl_portvlan_member_update) (a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t mem_port_map); + + typedef sw_error_t + (*hsl_portvlan_member_get) (a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t * mem_port_map); + + typedef sw_error_t + (*hsl_port_nestvlan_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_port_nestvlan_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_nestvlan_tpid_set) (a_uint32_t dev_id, a_uint32_t tpid); + + typedef sw_error_t + (*hsl_nestvlan_tpid_get) (a_uint32_t dev_id, a_uint32_t * tpid); + + typedef sw_error_t + (*hsl_port_default_vid_set) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vid); + + typedef sw_error_t + (*hsl_port_default_vid_get) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vid); + + typedef sw_error_t + (*hsl_port_force_default_vid_set) (a_uint32_t dev_id, + fal_port_t port_id, a_bool_t enable); + + typedef sw_error_t + (*hsl_port_force_default_vid_get) (a_uint32_t dev_id, + fal_port_t port_id, a_bool_t * enable); + + typedef sw_error_t + (*hsl_port_force_portvlan_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_port_force_portvlan_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_port_invlan_mode_set) (a_uint32_t dev_id, fal_port_t port_id, + fal_pt_invlan_mode_t mode); + + typedef sw_error_t + (*hsl_port_invlan_mode_get) (a_uint32_t dev_id, fal_port_t port_id, + fal_pt_invlan_mode_t * mode); + + typedef sw_error_t + (*hsl_port_tls_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_port_tls_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_port_pri_propagation_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_port_pri_propagation_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_port_default_svid_set) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vid); + + typedef sw_error_t + (*hsl_port_default_svid_get) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vid); + + typedef sw_error_t + (*hsl_port_default_cvid_set) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vid); + + typedef sw_error_t + (*hsl_port_default_cvid_get) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vid); + + typedef sw_error_t + (*hsl_port_vlan_propagation_set) (a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_propagation_mode_t mode); + + typedef sw_error_t + (*hsl_port_vlan_propagation_get) (a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_propagation_mode_t * mode); + + typedef sw_error_t + (*hsl_port_vlan_trans_add) (a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_trans_entry_t * entry); + + typedef sw_error_t + (*hsl_port_vlan_trans_del) (a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_trans_entry_t * entry); + + typedef sw_error_t + (*hsl_port_vlan_trans_get) (a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_trans_entry_t * entry); + + typedef sw_error_t + (*hsl_qinq_mode_set) (a_uint32_t dev_id, fal_qinq_mode_t mode); + + typedef sw_error_t + (*hsl_qinq_mode_get) (a_uint32_t dev_id, fal_qinq_mode_t * mode); + + typedef sw_error_t + (*hsl_port_qinq_role_set) (a_uint32_t dev_id, fal_port_t port_id, + fal_qinq_port_role_t role); + + typedef sw_error_t + (*hsl_port_qinq_role_get) (a_uint32_t dev_id, fal_port_t port_id, + fal_qinq_port_role_t * role); + + typedef sw_error_t + (*hsl_port_vlan_trans_iterate) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * iterator, + fal_vlan_trans_entry_t * entry); + + typedef sw_error_t + (*hsl_port_mac_vlan_xlt_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_port_mac_vlan_xlt_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_netisolate_set) (a_uint32_t dev_id, a_uint32_t enable); + + typedef sw_error_t + (*hsl_netisolate_get) (a_uint32_t dev_id, a_uint32_t * enable); + + typedef sw_error_t + (*hsl_eg_trans_filter_bypass_en_set) (a_uint32_t dev_id, + a_uint32_t enable); + + typedef sw_error_t + (*hsl_eg_trans_filter_bypass_en_get) (a_uint32_t dev_id, + a_uint32_t * enable); + + typedef sw_error_t + (*hsl_port_vrf_id_set) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vrf_id); + + typedef sw_error_t + (*hsl_port_vrf_id_get) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vrf_id); + + /* FDB */ +#define FDB_FUNC_PROTOTYPE_DEF + typedef sw_error_t + (*hsl_fdb_add) (a_uint32_t dev_id, const fal_fdb_entry_t * entry); + + typedef sw_error_t + (*hsl_fdb_rfs_set) (a_uint32_t dev_id, const fal_fdb_rfs_t * entry); + + typedef sw_error_t + (*hsl_fdb_rfs_del) (a_uint32_t dev_id, const fal_fdb_rfs_t * entry); + + typedef sw_error_t (*hsl_fdb_del_all) (a_uint32_t dev_id, a_uint32_t flag); + + typedef sw_error_t + (*hsl_fdb_del_by_port) (a_uint32_t dev_id, a_uint32_t port_id, + a_uint32_t flag); + + typedef sw_error_t + (*hsl_fdb_del_by_mac) (a_uint32_t dev_id, const fal_fdb_entry_t * addr); + + typedef sw_error_t + (*hsl_fdb_first) (a_uint32_t dev_id, fal_fdb_entry_t * entry); + + typedef sw_error_t + (*hsl_fdb_next) (a_uint32_t dev_id, fal_fdb_entry_t * entry); + + typedef sw_error_t + (*hsl_fdb_find) (a_uint32_t dev_id, fal_fdb_entry_t * entry); + + typedef sw_error_t + (*hsl_fdb_port_learn_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_fdb_port_learn_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_fdb_age_ctrl_set) (a_uint32_t dev_id, a_bool_t enable); + + typedef sw_error_t + (*hsl_fdb_age_ctrl_get) (a_uint32_t dev_id, a_bool_t * enable); + + typedef sw_error_t + (*hsl_fdb_vlan_ivl_svl_set) (a_uint32_t dev_id, fal_fdb_smode smode); + + typedef sw_error_t + (*hsl_fdb_vlan_ivl_svl_get) (a_uint32_t dev_id, fal_fdb_smode * smode); + + typedef sw_error_t + (*hsl_fdb_age_time_set) (a_uint32_t dev_id, a_uint32_t * time); + + typedef sw_error_t + (*hsl_fdb_age_time_get) (a_uint32_t dev_id, a_uint32_t * time); + + typedef sw_error_t + (*hsl_fdb_iterate) (a_uint32_t dev_id, a_uint32_t * iterator, + fal_fdb_entry_t * entry); + + typedef sw_error_t + (*hsl_fdb_extend_next) (a_uint32_t dev_id, fal_fdb_op_t * op, + fal_fdb_entry_t * entry); + + typedef sw_error_t + (*hsl_fdb_extend_first) (a_uint32_t dev_id, fal_fdb_op_t * option, + fal_fdb_entry_t * entry); + + typedef sw_error_t + (*hsl_fdb_transfer) (a_uint32_t dev_id, fal_port_t old_port, + fal_port_t new_port, a_uint32_t fid, + fal_fdb_op_t * option); + + typedef sw_error_t + (*hsl_port_fdb_learn_limit_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable, a_uint32_t cnt); + + typedef sw_error_t + (*hsl_port_fdb_learn_limit_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable, a_uint32_t * cnt); + + typedef sw_error_t + (*hsl_port_fdb_learn_exceed_cmd_set) (a_uint32_t dev_id, + fal_port_t port_id, + fal_fwd_cmd_t cmd); + + typedef sw_error_t + (*hsl_port_fdb_learn_exceed_cmd_get) (a_uint32_t dev_id, + fal_port_t port_id, + fal_fwd_cmd_t * cmd); + + typedef sw_error_t + (*hsl_fdb_learn_limit_set) (a_uint32_t dev_id, a_bool_t enable, + a_uint32_t cnt); + + typedef sw_error_t + (*hsl_fdb_learn_limit_get) (a_uint32_t dev_id, a_bool_t * enable, + a_uint32_t * cnt); + + typedef sw_error_t + (*hsl_fdb_learn_exceed_cmd_set) (a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + typedef sw_error_t + (*hsl_fdb_learn_exceed_cmd_get) (a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + typedef sw_error_t + (*hsl_fdb_resv_add) (a_uint32_t dev_id, fal_fdb_entry_t * entry); + + typedef sw_error_t + (*hsl_fdb_resv_del) (a_uint32_t dev_id, fal_fdb_entry_t * entry); + + typedef sw_error_t + (*hsl_fdb_resv_find) (a_uint32_t dev_id, fal_fdb_entry_t * entry); + + typedef sw_error_t + (*hsl_fdb_resv_iterate) (a_uint32_t dev_id, a_uint32_t * iterator, + fal_fdb_entry_t * entry); + + typedef sw_error_t + (*hsl_fdb_port_learn_static_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_fdb_port_learn_static_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_fdb_port_add) (a_uint32_t dev_id, a_uint32_t fid, + fal_mac_addr_t * addr, fal_port_t port_id); + + typedef sw_error_t + (*hsl_fdb_port_del) (a_uint32_t dev_id, a_uint32_t fid, + fal_mac_addr_t * addr, fal_port_t port_id); + + /* QOS */ +#define QOS_FUNC_PROTOTYPE_DEF + typedef sw_error_t + (*hsl_cosmap_up_queue_set) (a_uint32_t dev_id, a_uint32_t up, + fal_queue_t queue); + + typedef sw_error_t + (*hsl_cosmap_up_queue_get) (a_uint32_t dev_id, a_uint32_t up, + fal_queue_t * queue); + + typedef sw_error_t + (*hsl_cosmap_dscp_queue_set) (a_uint32_t dev_id, a_uint32_t dscp, + fal_queue_t queue); + + typedef sw_error_t + (*hsl_cosmap_dscp_queue_get) (a_uint32_t dev_id, a_uint32_t dscp, + fal_queue_t * queue); + + typedef sw_error_t + (*hsl_qos_port_mode_set) (a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_bool_t enable); + + typedef sw_error_t + (*hsl_qos_port_mode_get) (a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_bool_t * enable); + + typedef sw_error_t + (*hsl_qos_port_mode_pri_set) (a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_uint32_t pri); + + typedef sw_error_t + (*hsl_qos_port_mode_pri_get) (a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_uint32_t * pri); + + typedef sw_error_t + (*hsl_qos_port_default_up_set) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t up); + + typedef sw_error_t + (*hsl_qos_port_default_up_get) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * up); + + typedef sw_error_t + (*hsl_qos_sch_mode_set) (a_uint32_t dev_id, + fal_sch_mode_t mode, const a_uint32_t weight[]); + + typedef sw_error_t + (*hsl_qos_sch_mode_get) (a_uint32_t dev_id, + fal_sch_mode_t * mode, a_uint32_t weight[]); + + typedef sw_error_t + (*hsl_qos_queue_tx_buf_status_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_qos_queue_tx_buf_status_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_qos_queue_tx_buf_nr_set) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t queue_id, a_uint32_t * number); + + typedef sw_error_t + (*hsl_qos_queue_tx_buf_nr_get) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t queue_id, a_uint32_t * number); + + typedef sw_error_t + (*hsl_qos_port_tx_buf_status_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_qos_port_tx_buf_status_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_qos_port_red_en_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_qos_port_red_en_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_qos_port_tx_buf_nr_set) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number); + + typedef sw_error_t + (*hsl_qos_port_tx_buf_nr_get) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number); + + typedef sw_error_t + (*hsl_qos_port_rx_buf_nr_set) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number); + + typedef sw_error_t + (*hsl_qos_port_rx_buf_nr_get) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number); + + typedef sw_error_t + (*hsl_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[]); + + typedef sw_error_t + (*hsl_qos_port_sch_mode_get) (a_uint32_t dev_id, a_uint32_t port_id, + fal_sch_mode_t * mode, a_uint32_t weight[]); + + typedef sw_error_t + (*hsl_qos_port_default_spri_set) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t spri); + + typedef sw_error_t + (*hsl_qos_port_default_spri_get) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * spri); + + typedef sw_error_t + (*hsl_qos_port_default_cpri_set) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t cpri); + + typedef sw_error_t + (*hsl_qos_port_default_cpri_get) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * cpri); + + typedef sw_error_t + (*hsl_qos_port_force_spri_status_set) (a_uint32_t dev_id, + fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_qos_port_force_spri_status_get) (a_uint32_t dev_id, + fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_qos_port_force_cpri_status_set) (a_uint32_t dev_id, + fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_qos_port_force_cpri_status_get) (a_uint32_t dev_id, + fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_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); + + typedef sw_error_t + (*hsl_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); + + typedef sw_error_t + (*hsl_port_static_thresh_get)(a_uint32_t dev_id, fal_port_t port, + fal_bm_static_cfg_t *cfg); + + typedef sw_error_t + (*hsl_port_static_thresh_set)(a_uint32_t dev_id, fal_port_t port, + fal_bm_static_cfg_t *cfg); + + /* Rate */ +#define RATE_FUNC_PROTOTYPE_DEF + typedef sw_error_t + (*hsl_rate_queue_egrl_set) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t queue_id, a_uint32_t * speed, + a_bool_t enable); + + typedef sw_error_t + (*hsl_rate_queue_egrl_get) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t queue_id, a_uint32_t * speed, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_rate_port_egrl_set) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * speed, a_bool_t enable); + + typedef sw_error_t + (*hsl_rate_port_egrl_get) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * speed, a_bool_t * enable); + + typedef sw_error_t + (*hsl_rate_port_inrl_set) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * speed, a_bool_t enable); + + typedef sw_error_t + (*hsl_rate_port_inrl_get) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * speed, a_bool_t * enable); + + typedef sw_error_t + (*hsl_storm_ctrl_frame_set) (a_uint32_t dev_id, fal_port_t port_id, + fal_storm_type_t storm_type, + a_bool_t enable); + + typedef sw_error_t + (*hsl_storm_ctrl_frame_get) (a_uint32_t dev_id, fal_port_t port_id, + fal_storm_type_t storm_type, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_storm_ctrl_rate_set) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * rate); + + typedef sw_error_t + (*hsl_storm_ctrl_rate_get) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * rate); + + typedef sw_error_t + (*hsl_rate_port_policer_set) (a_uint32_t dev_id, fal_port_t port_id, + fal_port_policer_t * policer); + + typedef sw_error_t + (*hsl_rate_port_policer_get) (a_uint32_t dev_id, fal_port_t port_id, + fal_port_policer_t * policer); + + typedef sw_error_t + (*hsl_rate_port_shaper_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable, + fal_egress_shaper_t * shaper); + + typedef sw_error_t + (*hsl_rate_port_shaper_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable, + fal_egress_shaper_t * shaper); + + typedef sw_error_t + (*hsl_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); + + typedef sw_error_t + (*hsl_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); + + typedef sw_error_t + (*hsl_rate_acl_policer_set) (a_uint32_t dev_id, a_uint32_t policer_id, + fal_acl_policer_t * policer); + + typedef sw_error_t + (*hsl_rate_acl_policer_get) (a_uint32_t dev_id, a_uint32_t policer_id, + fal_acl_policer_t * policer); + + typedef sw_error_t + (*hsl_rate_port_add_rate_byte_set) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t number); + + typedef sw_error_t + (*hsl_rate_port_add_rate_byte_get) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number); + typedef sw_error_t + (*hsl_rate_port_gol_flow_en_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_rate_port_gol_flow_en_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + /* Mirror */ +#define MIRROR_FUNC_PROTOTYPE_DEF + typedef sw_error_t + (*hsl_mirr_analysis_port_set) (a_uint32_t dev_id, fal_port_t port_id); + + typedef sw_error_t + (*hsl_mirr_analysis_port_get) (a_uint32_t dev_id, fal_port_t * port_id); + + typedef sw_error_t + (*hsl_mirr_port_in_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_mirr_port_in_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_mirr_port_eg_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_mirr_port_eg_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + /* STP */ +#define STP_FUNC_PROTOTYPE_DEF + typedef sw_error_t + (*hsl_stp_port_state_set) (a_uint32_t dev_id, a_uint32_t st_id, + fal_port_t port_id, fal_stp_state_t state); + + typedef sw_error_t + (*hsl_stp_port_state_get) (a_uint32_t dev_id, a_uint32_t st_id, + fal_port_t port_id, fal_stp_state_t * state); + /* IGMP */ +#define IGMP_FUNC_PROTOTYPE_DEF + typedef sw_error_t + (*hsl_port_igmps_status_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_port_igmps_status_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_igmp_mld_cmd_set) (a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + typedef sw_error_t + (*hsl_igmp_mld_cmd_get) (a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + typedef sw_error_t + (*hsl_port_igmp_join_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_port_igmp_join_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_port_igmp_leave_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_port_igmp_leave_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t (*hsl_igmp_rp_set) (a_uint32_t dev_id, fal_pbmp_t pts); + + typedef sw_error_t (*hsl_igmp_rp_get) (a_uint32_t dev_id, fal_pbmp_t * pts); + + typedef sw_error_t + (*hsl_igmp_entry_creat_set) (a_uint32_t dev_id, a_bool_t enable); + + typedef sw_error_t + (*hsl_igmp_entry_creat_get) (a_uint32_t dev_id, a_bool_t * enable); + + typedef sw_error_t + (*hsl_igmp_entry_static_set) (a_uint32_t dev_id, a_bool_t enable); + + typedef sw_error_t + (*hsl_igmp_entry_static_get) (a_uint32_t dev_id, a_bool_t * enable); + + typedef sw_error_t + (*hsl_igmp_entry_leaky_set) (a_uint32_t dev_id, a_bool_t enable); + + typedef sw_error_t + (*hsl_igmp_entry_leaky_get) (a_uint32_t dev_id, a_bool_t * enable); + + typedef sw_error_t + (*hsl_igmp_entry_v3_set) (a_uint32_t dev_id, a_bool_t enable); + + typedef sw_error_t + (*hsl_igmp_entry_v3_get) (a_uint32_t dev_id, a_bool_t * enable); + + typedef sw_error_t + (*hsl_igmp_entry_queue_set) (a_uint32_t dev_id, a_bool_t enable, + a_uint32_t queue); + + typedef sw_error_t + (*hsl_igmp_entry_queue_get) (a_uint32_t dev_id, a_bool_t * enable, + a_uint32_t * queue); + + typedef sw_error_t + (*hsl_port_igmp_mld_learn_limit_set) (a_uint32_t dev_id, + fal_port_t port_id, a_bool_t enable, + a_uint32_t cnt); + + typedef sw_error_t + (*hsl_port_igmp_mld_learn_limit_get) (a_uint32_t dev_id, + fal_port_t port_id, + a_bool_t * enable, + a_uint32_t * cnt); + + typedef sw_error_t + (*hsl_port_igmp_mld_learn_exceed_cmd_set) (a_uint32_t dev_id, + fal_port_t port_id, + fal_fwd_cmd_t cmd); + + typedef sw_error_t + (*hsl_port_igmp_mld_learn_exceed_cmd_get) (a_uint32_t dev_id, + fal_port_t port_id, + fal_fwd_cmd_t * cmd); + typedef sw_error_t (*hsl_igmp_sg_entry_set) (a_uint32_t dev_id, + fal_igmp_sg_entry_t * entry); + + typedef sw_error_t + (*hsl_igmp_sg_entry_clear) (a_uint32_t dev_id, + fal_igmp_sg_entry_t * entry); + + typedef sw_error_t (*hsl_igmp_sg_entry_show) (a_uint32_t dev_id); + + typedef sw_error_t + (*hsl_igmp_sg_entry_query) (a_uint32_t dev_id, fal_igmp_sg_info_t * info); + + /* Leaky */ +#define LEAKY_FUNC_PROTOTYPE_DEF + typedef sw_error_t + (*hsl_uc_leaky_mode_set) (a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode); + + typedef sw_error_t + (*hsl_uc_leaky_mode_get) (a_uint32_t dev_id, + fal_leaky_ctrl_mode_t * ctrl_mode); + + typedef sw_error_t + (*hsl_mc_leaky_mode_set) (a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode); + + typedef sw_error_t + (*hsl_mc_leaky_mode_get) (a_uint32_t dev_id, + fal_leaky_ctrl_mode_t * ctrl_mode); + + typedef sw_error_t + (*hsl_port_arp_leaky_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_port_arp_leaky_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_port_uc_leaky_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_port_uc_leaky_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_port_mc_leaky_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_port_mc_leaky_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + /* Mib */ +#define MIB_FUNC_PROTOTYPE_DEF + typedef sw_error_t + (*hsl_get_mib_info) (a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info); + + typedef sw_error_t + (*hsl_get_rx_mib_info) (a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info); + + typedef sw_error_t + (*hsl_get_tx_mib_info) (a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info); + + typedef sw_error_t + (*hsl_mib_status_set) (a_uint32_t dev_id, a_bool_t enable); + + typedef sw_error_t + (*hsl_mib_status_get) (a_uint32_t dev_id, a_bool_t * enable); + + typedef sw_error_t + (*hsl_mib_port_flush_counters) (a_uint32_t dev_id, fal_port_t port_id); + + typedef sw_error_t + (*hsl_mib_cpukeep_set) (a_uint32_t dev_id, a_bool_t enable); + + typedef sw_error_t + (*hsl_mib_cpukeep_get) (a_uint32_t dev_id, a_bool_t * enable); + + /* Acl */ +#define ACL_FUNC_PROTOTYPE_DEF + typedef sw_error_t + (*hsl_acl_list_creat) (a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t list_pri); + + typedef sw_error_t + (*hsl_acl_list_destroy) (a_uint32_t dev_id, a_uint32_t list_id); + + typedef sw_error_t + (*hsl_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); + + typedef sw_error_t + (*hsl_acl_rule_delete) (a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t rule_id, a_uint32_t rule_nr); + + typedef sw_error_t + (*hsl_acl_rule_query) (a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t rule_id, fal_acl_rule_t * rule); + + typedef sw_error_t + (*hsl_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); + + typedef sw_error_t + (*hsl_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); + + typedef sw_error_t + (*hsl_acl_status_set) (a_uint32_t dev_id, a_bool_t enable); + + typedef sw_error_t + (*hsl_acl_status_get) (a_uint32_t dev_id, a_bool_t * enable); + + typedef sw_error_t (*hsl_acl_list_dump) (a_uint32_t dev_id); + + typedef sw_error_t (*hsl_acl_rule_dump) (a_uint32_t dev_id); + + typedef sw_error_t + (*hsl_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); + + typedef sw_error_t + (*hsl_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); + + typedef sw_error_t + (*hsl_acl_rule_active) (a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t rule_id, a_uint32_t rule_nr); + + typedef sw_error_t + (*hsl_acl_rule_deactive) (a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t rule_id, a_uint32_t rule_nr); + + typedef sw_error_t + (*hsl_acl_rule_src_filter_sts_set) (a_uint32_t dev_id, + a_uint32_t rule_id, a_bool_t enable); + + typedef sw_error_t + (*hsl_acl_rule_src_filter_sts_get) (a_uint32_t dev_id, + a_uint32_t rule_id, + a_bool_t * enable); + + typedef a_uint32_t + (*hsl_acl_rule_get_offset) (a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t rule_id); + + typedef sw_error_t + (*hsl_acl_rule_sync_multi_portmap) (a_uint32_t dev_id, a_uint32_t pos, + a_uint32_t * act); +/*qca808x_start*/ + + typedef sw_error_t (*hsl_dev_reset) (a_uint32_t dev_id); + + typedef sw_error_t (*hsl_dev_clean) (a_uint32_t dev_id); + + typedef sw_error_t + (*hsl_dev_access_set) (a_uint32_t dev_id, hsl_access_mode mode); +/*qca808x_end*/ + + /* LED */ +#define LED_FUNC_PROTOTYPE_DEF + typedef sw_error_t + (*hsl_led_ctrl_pattern_set) (a_uint32_t dev_id, led_pattern_group_t group, + led_pattern_id_t id, + led_ctrl_pattern_t * pattern); + + typedef sw_error_t + (*hsl_led_ctrl_pattern_get) (a_uint32_t dev_id, led_pattern_group_t group, + led_pattern_id_t id, + led_ctrl_pattern_t * pattern); + + typedef sw_error_t + (*hsl_led_ctrl_source_set) (a_uint32_t dev_id, a_uint32_t source_id, + led_ctrl_pattern_t * pattern); + + /* CoSMAP */ +#define COSMAP_FUNC_PROTOTYPE_DEF + typedef sw_error_t + (*hsl_cosmap_dscp_to_pri_set) (a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t pri); + + typedef sw_error_t + (*hsl_cosmap_dscp_to_pri_get) (a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t * pri); + + typedef sw_error_t + (*hsl_cosmap_dscp_to_dp_set) (a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t dp); + + typedef sw_error_t + (*hsl_cosmap_dscp_to_dp_get) (a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t * dp); + + typedef sw_error_t + (*hsl_cosmap_up_to_pri_set) (a_uint32_t dev_id, a_uint32_t up, + a_uint32_t pri); + + typedef sw_error_t + (*hsl_cosmap_up_to_pri_get) (a_uint32_t dev_id, a_uint32_t up, + a_uint32_t * pri); + + typedef sw_error_t + (*hsl_cosmap_up_to_dp_set) (a_uint32_t dev_id, a_uint32_t up, + a_uint32_t dp); + + typedef sw_error_t + (*hsl_cosmap_up_to_dp_get) (a_uint32_t dev_id, a_uint32_t up, + a_uint32_t * dp); + + typedef sw_error_t + (*hsl_cosmap_dscp_to_ehpri_set) (a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t pri); + + typedef sw_error_t + (*hsl_cosmap_dscp_to_ehpri_get) (a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t * pri); + + typedef sw_error_t + (*hsl_cosmap_dscp_to_ehdp_set) (a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t dp); + + typedef sw_error_t + (*hsl_cosmap_dscp_to_ehdp_get) (a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t * dp); + + typedef sw_error_t + (*hsl_cosmap_up_to_ehpri_set) (a_uint32_t dev_id, a_uint32_t up, + a_uint32_t pri); + + typedef sw_error_t + (*hsl_cosmap_up_to_ehpri_get) (a_uint32_t dev_id, a_uint32_t up, + a_uint32_t * pri); + + typedef sw_error_t + (*hsl_cosmap_up_to_ehdp_set) (a_uint32_t dev_id, a_uint32_t up, + a_uint32_t dp); + + typedef sw_error_t + (*hsl_cosmap_up_to_ehdp_get) (a_uint32_t dev_id, a_uint32_t up, + a_uint32_t * dp); + + typedef sw_error_t + (*hsl_cosmap_pri_to_queue_set) (a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t queue); + + typedef sw_error_t + (*hsl_cosmap_pri_to_queue_get) (a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t * queue); + + typedef sw_error_t + (*hsl_cosmap_pri_to_ehqueue_set) (a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t queue); + + typedef sw_error_t + (*hsl_cosmap_pri_to_ehqueue_get) (a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t * queue); + + typedef sw_error_t + (*hsl_cosmap_egress_remark_set) (a_uint32_t dev_id, a_uint32_t tbl_id, + fal_egress_remark_table_t * tbl); + + typedef sw_error_t + (*hsl_cosmap_egress_remark_get) (a_uint32_t dev_id, a_uint32_t tbl_id, + fal_egress_remark_table_t * tbl); + + + /* IP */ +#define IP_FUNC_PROTOTYPE_DEF + typedef sw_error_t + (*hsl_ip_host_add) (a_uint32_t dev_id, fal_host_entry_t * host_entry); + + typedef sw_error_t + (*hsl_ip_host_del) (a_uint32_t dev_id, a_uint32_t del_mode, + fal_host_entry_t * host_entry); + + typedef sw_error_t + (*hsl_ip_host_get) (a_uint32_t dev_id, a_uint32_t get_mode, + fal_host_entry_t * host_entry); + + typedef sw_error_t + (*hsl_ip_host_next) (a_uint32_t dev_id, a_uint32_t next_mode, + fal_host_entry_t * host_entry); + + typedef sw_error_t + (*hsl_ip_host_counter_bind) (a_uint32_t dev_id, a_uint32_t entry_id, + a_uint32_t cnt_id, a_bool_t enable); + + typedef sw_error_t + (*hsl_ip_host_pppoe_bind) (a_uint32_t dev_id, a_uint32_t entry_id, + a_uint32_t pppoe_id, a_bool_t enable); + + typedef sw_error_t + (*hsl_ip_pt_arp_learn_set) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t flags); + + typedef sw_error_t + (*hsl_ip_pt_arp_learn_get) (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * flags); + + typedef sw_error_t + (*hsl_ip_arp_learn_set) (a_uint32_t dev_id, fal_arp_learn_mode_t mode); + + typedef sw_error_t + (*hsl_ip_arp_learn_get) (a_uint32_t dev_id, fal_arp_learn_mode_t * mode); + + typedef sw_error_t + (*hsl_ip_source_guard_set) (a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t mode); + + typedef sw_error_t + (*hsl_ip_source_guard_get) (a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t * mode); + + typedef sw_error_t + (*hsl_ip_unk_source_cmd_set) (a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + typedef sw_error_t + (*hsl_ip_unk_source_cmd_get) (a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + typedef sw_error_t + (*hsl_ip_arp_guard_set) (a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t mode); + + typedef sw_error_t + (*hsl_ip_arp_guard_get) (a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t * mode); + + typedef sw_error_t + (*hsl_arp_unk_source_cmd_set) (a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + typedef sw_error_t + (*hsl_arp_unk_source_cmd_get) (a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + typedef sw_error_t + (*hsl_ip_route_status_set) (a_uint32_t dev_id, a_bool_t enable); + + typedef sw_error_t + (*hsl_ip_route_status_get) (a_uint32_t dev_id, a_bool_t * enable); + + typedef sw_error_t + (*hsl_ip_intf_entry_add) (a_uint32_t dev_id, + fal_intf_mac_entry_t * entry); + + typedef sw_error_t + (*hsl_ip_intf_entry_del) (a_uint32_t dev_id, a_uint32_t del_mode, + fal_intf_mac_entry_t * entry); + + typedef sw_error_t + (*hsl_ip_intf_entry_next) (a_uint32_t dev_id, a_uint32_t next_mode, + fal_intf_mac_entry_t * entry); + + typedef sw_error_t + (*hsl_ip_age_time_set) (a_uint32_t dev_id, a_uint32_t * time); + + typedef sw_error_t + (*hsl_ip_age_time_get) (a_uint32_t dev_id, a_uint32_t * time); + + typedef sw_error_t + (*hsl_ip_wcmp_hash_mode_set) (a_uint32_t dev_id, a_uint32_t hash_mode); + + typedef sw_error_t + (*hsl_ip_wcmp_hash_mode_get) (a_uint32_t dev_id, a_uint32_t * hash_mode); + + typedef sw_error_t + (*hsl_ip_vrf_base_addr_set) (a_uint32_t dev_id, + a_uint32_t vrf_id, fal_ip4_addr_t addr); + + typedef sw_error_t + (*hsl_ip_vrf_base_addr_get) (a_uint32_t dev_id, + a_uint32_t vrf_id, fal_ip4_addr_t * addr); + + typedef sw_error_t + (*hsl_ip_vrf_base_mask_set) (a_uint32_t dev_id, + a_uint32_t vrf_id, fal_ip4_addr_t addr); + + typedef sw_error_t + (*hsl_ip_vrf_base_mask_get) (a_uint32_t dev_id, + a_uint32_t vrf_id, fal_ip4_addr_t * addr); + + typedef sw_error_t + (*hsl_ip_default_route_set) (a_uint32_t dev_id, + a_uint32_t droute_id, + fal_default_route_t * entry); + + typedef sw_error_t + (*hsl_ip_default_route_get) (a_uint32_t dev_id, + a_uint32_t droute_id, + fal_default_route_t * entry); + + typedef sw_error_t + (*hsl_ip_host_route_set) (a_uint32_t dev_id, + a_uint32_t hroute_id, fal_host_route_t * entry); + + typedef sw_error_t + (*hsl_ip_host_route_get) (a_uint32_t dev_id, + a_uint32_t hroute_id, fal_host_route_t * entry); + + typedef sw_error_t + (*hsl_ip_wcmp_entry_set) (a_uint32_t dev_id, + a_uint32_t wcmp_id, fal_ip_wcmp_t * wcmp); + + typedef sw_error_t + (*hsl_ip_wcmp_entry_get) (a_uint32_t dev_id, + a_uint32_t wcmp_id, fal_ip_wcmp_t * wcmp); + typedef sw_error_t + (*hsl_ip_rfs_ip4_set) (a_uint32_t dev_id, fal_ip4_rfs_t * rfs); + + typedef sw_error_t + (*hsl_ip_rfs_ip6_set) (a_uint32_t dev_id, fal_ip6_rfs_t * rfs); + typedef sw_error_t + (*hsl_ip_rfs_ip4_del) (a_uint32_t dev_id, fal_ip4_rfs_t * rfs); + + typedef sw_error_t + (*hsl_ip_rfs_ip6_del) (a_uint32_t dev_id, fal_ip6_rfs_t * rfs); + + typedef sw_error_t + (*hsl_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); + + typedef sw_error_t + (*hsl_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); + + typedef sw_error_t + (*hsl_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); + + typedef sw_error_t + (*hsl_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); + +typedef sw_error_t + (*hsl_ip_glb_lock_time_set) (a_uint32_t dev_id, fal_glb_lock_time_t lock_time); + + /* NAT */ +#define NAT_FUNC_PROTOTYPE_DEF + typedef sw_error_t + (*hsl_nat_add) (a_uint32_t dev_id, fal_nat_entry_t * nat_entry); + + typedef sw_error_t + (*hsl_nat_del) (a_uint32_t dev_id, a_uint32_t del_mode, + fal_nat_entry_t * nat_entry); + + typedef sw_error_t + (*hsl_nat_get) (a_uint32_t dev_id, a_uint32_t get_mode, + fal_nat_entry_t * nat_entry); + + typedef sw_error_t + (*hsl_nat_next) (a_uint32_t dev_id, a_uint32_t next_mode, + fal_nat_entry_t * nat_entry); + + typedef sw_error_t + (*hsl_nat_counter_bind) (a_uint32_t dev_id, a_uint32_t entry_id, + a_uint32_t cnt_id, a_bool_t enable); + + typedef sw_error_t + (*hsl_napt_add) (a_uint32_t dev_id, fal_napt_entry_t * napt_entry); + + typedef sw_error_t + (*hsl_napt_del) (a_uint32_t dev_id, a_uint32_t del_mode, + fal_napt_entry_t * napt_entry); + + typedef sw_error_t + (*hsl_napt_get) (a_uint32_t dev_id, a_uint32_t get_mode, + fal_napt_entry_t * napt_entry); + + typedef sw_error_t + (*hsl_napt_next) (a_uint32_t dev_id, a_uint32_t next_mode, + fal_napt_entry_t * napt_entry); + + typedef sw_error_t + (*hsl_napt_counter_bind) (a_uint32_t dev_id, a_uint32_t entry_id, + a_uint32_t cnt_id, a_bool_t enable); + + typedef sw_error_t + (*hsl_nat_status_set) (a_uint32_t dev_id, a_bool_t enable); + + typedef sw_error_t + (*hsl_nat_status_get) (a_uint32_t dev_id, a_bool_t * enable); + + typedef sw_error_t + (*hsl_nat_hash_mode_set) (a_uint32_t dev_id, a_uint32_t mode); + + typedef sw_error_t + (*hsl_nat_hash_mode_get) (a_uint32_t dev_id, a_uint32_t * mode); + + typedef sw_error_t + (*hsl_napt_status_set) (a_uint32_t dev_id, a_bool_t enable); + + typedef sw_error_t + (*hsl_napt_status_get) (a_uint32_t dev_id, a_bool_t * enable); + + typedef sw_error_t + (*hsl_napt_mode_set) (a_uint32_t dev_id, fal_napt_mode_t mode); + + typedef sw_error_t + (*hsl_napt_mode_get) (a_uint32_t dev_id, fal_napt_mode_t * mode); + + typedef sw_error_t + (*hsl_nat_prv_base_addr_set) (a_uint32_t dev_id, fal_ip4_addr_t addr); + + typedef sw_error_t + (*hsl_nat_prv_base_addr_get) (a_uint32_t dev_id, fal_ip4_addr_t * addr); + + typedef sw_error_t + (*hsl_nat_prv_base_mask_set) (a_uint32_t dev_id, fal_ip4_addr_t mask); + + typedef sw_error_t + (*hsl_nat_prv_base_mask_get) (a_uint32_t dev_id, fal_ip4_addr_t * mask); + + typedef sw_error_t + (*hsl_nat_prv_addr_mode_set) (a_uint32_t dev_id, a_bool_t map_en); + + typedef sw_error_t + (*hsl_nat_prv_addr_mode_get) (a_uint32_t dev_id, a_bool_t * map_en); + + typedef sw_error_t + (*hsl_nat_pub_addr_add) (a_uint32_t dev_id, fal_nat_pub_addr_t * entry); + + typedef sw_error_t + (*hsl_nat_pub_addr_del) (a_uint32_t dev_id, a_uint32_t del_mode, + fal_nat_pub_addr_t * entry); + + typedef sw_error_t + (*hsl_nat_pub_addr_next) (a_uint32_t dev_id, a_uint32_t next_mode, + fal_nat_pub_addr_t * entry); + + typedef sw_error_t + (*hsl_nat_unk_session_cmd_set) (a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + typedef sw_error_t + (*hsl_nat_unk_session_cmd_get) (a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + typedef sw_error_t + (*hsl_nat_global_set) (a_uint32_t dev_id, a_bool_t enable, a_uint32_t portbmp); + + typedef sw_error_t + (*hsl_flow_cookie_set) (a_uint32_t dev_id, + fal_flow_cookie_t * flow_cookie); + + typedef sw_error_t + (*hsl_flow_rfs_set) (a_uint32_t dev_id, a_uint8_t action, + fal_flow_rfs_t * rfs); + + /* SEC */ +#define SEC_FUNC_PROTOTYPE_DEF + typedef sw_error_t + (*hsl_sec_norm_item_set) (a_uint32_t dev_id, fal_norm_item_t item, + void *value); + + typedef sw_error_t + (*hsl_sec_norm_item_get) (a_uint32_t dev_id, fal_norm_item_t item, + void *value); + + + /* Trunk */ +#define TRUNK_FUNC_PROTOTYPE_DEF + typedef sw_error_t + (*hsl_trunk_group_set) (a_uint32_t dev_id, a_uint32_t trunk_id, + a_bool_t enable, fal_pbmp_t member); + + typedef sw_error_t + (*hsl_trunk_group_get) (a_uint32_t dev_id, a_uint32_t trunk_id, + a_bool_t * enable, fal_pbmp_t * member); + + typedef sw_error_t + (*hsl_trunk_hash_mode_set) (a_uint32_t dev_id, a_uint32_t hash_mode); + + typedef sw_error_t + (*hsl_trunk_hash_mode_get) (a_uint32_t dev_id, a_uint32_t * hash_mode); + + typedef sw_error_t + (*hsl_trunk_manipulate_sa_set) (a_uint32_t dev_id, fal_mac_addr_t * addr); + + typedef sw_error_t + (*hsl_trunk_manipulate_sa_get) (a_uint32_t dev_id, fal_mac_addr_t * addr); + + /* Interface Control */ +#define INTERFACE_CONTROL_FUNC_PROTOTYPE_DEF + typedef sw_error_t + (*hsl_interface_mac_mode_set) (a_uint32_t dev_id, fal_port_t port_id, + fal_mac_config_t * config); + + typedef sw_error_t + (*hsl_interface_mac_mode_get) (a_uint32_t dev_id, fal_port_t port_id, + fal_mac_config_t * config); + + typedef sw_error_t + (*hsl_port_3az_status_set) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + typedef sw_error_t + (*hsl_port_3az_status_get) (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + typedef sw_error_t + (*hsl_interface_phy_mode_set) (a_uint32_t dev_id, a_uint32_t phy_id, + fal_phy_config_t * config); + + typedef sw_error_t + (*hsl_interface_phy_mode_get) (a_uint32_t dev_id, a_uint32_t phy_id, + fal_phy_config_t * config); + + typedef sw_error_t + (*hsl_interface_fx100_ctrl_set) (a_uint32_t dev_id, + fal_fx100_ctrl_config_t * config); + + typedef sw_error_t + (*hsl_interface_fx100_ctrl_get) (a_uint32_t dev_id, + fal_fx100_ctrl_config_t * config); + + typedef sw_error_t + (*hsl_interface_fx100_status_get) (a_uint32_t dev_id, + a_uint32_t * status); + + typedef sw_error_t + (*hsl_interface_mac06_exch_set) (a_uint32_t dev_id, a_bool_t enable); + + typedef sw_error_t + (*hsl_interface_mac06_exch_get) (a_uint32_t dev_id, a_bool_t * enable); + + typedef sw_error_t + (*hsl_interface_pad_get) (a_uint32_t dev_id,a_uint32_t port_num, a_uint32_t *value); + + typedef sw_error_t + (*hsl_interface_pad_set) (a_uint32_t dev_id,a_uint32_t port_num, a_uint32_t value); + + typedef sw_error_t + (*hsl_interface_sgmii_get) (a_uint32_t dev_id, a_uint32_t * value); + + typedef sw_error_t + (*hsl_interface_sgmii_set) (a_uint32_t dev_id, a_uint32_t value); + + + /* REG */ +/*qca808x_start*/ +#define REG_FUNC_PROTOTYPE_DEF + typedef sw_error_t + (*hsl_phy_get) (a_uint32_t dev_id, a_uint32_t phy_addr, a_uint32_t reg, + a_uint16_t * value); + + typedef sw_error_t + (*hsl_phy_set) (a_uint32_t dev_id, a_uint32_t phy_addr, a_uint32_t reg, + a_uint16_t value); +/*qca808x_end*/ + typedef sw_error_t + (*hsl_reg_get) (a_uint32_t dev_id, a_uint32_t reg_addr, + a_uint8_t value[], a_uint32_t value_len); + + typedef sw_error_t + (*hsl_reg_set) (a_uint32_t dev_id, a_uint32_t reg_addr, + a_uint8_t value[], a_uint32_t value_len); + + typedef sw_error_t + (*hsl_psgmii_reg_get) (a_uint32_t dev_id, a_uint32_t reg_addr, + a_uint8_t *value, a_uint32_t value_len); + + typedef sw_error_t + (*hsl_psgmii_reg_set) (a_uint32_t dev_id, a_uint32_t reg_addr, + a_uint8_t *value, a_uint32_t value_len); + + typedef sw_error_t + (*hsl_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); + + typedef sw_error_t + (*hsl_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); + + typedef sw_error_t + (*hsl_reg_entries_get) (a_uint32_t dev_id, a_uint32_t reg_addr, + a_uint32_t entry_len, a_uint8_t value[], + a_uint32_t value_len); + + typedef sw_error_t + (*hsl_reg_entries_set) (a_uint32_t dev_id, a_uint32_t reg_addr, + a_uint32_t entry_len, const a_uint8_t value[], + a_uint32_t value_len); + + typedef sw_error_t + (*hsl_debug_psgmii_self_test) (a_uint32_t dev_id, a_bool_t enable, + a_uint32_t times, a_uint32_t *result); + typedef sw_error_t + (*hsl_phy_dump)(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t idx,fal_phy_dump_t *phy_dump); + + typedef sw_error_t + (*hsl_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); + + typedef sw_error_t + (*hsl_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); +/*qca808x_start*/ + + typedef struct + { +/*qca808x_end*/ +#if (!(defined(USER_MODE) && defined(KERNEL_MODULE))) +#ifndef HSL_STANDALONG + + /* Misc */ + hsl_arp_status_set arp_status_set; + hsl_arp_status_get arp_status_get; + hsl_frame_max_size_set frame_max_size_set; + hsl_frame_max_size_get frame_max_size_get; + hsl_port_unk_sa_cmd_set port_unk_sa_cmd_set; + hsl_port_unk_sa_cmd_get port_unk_sa_cmd_get; + hsl_port_unk_uc_filter_set port_unk_uc_filter_set; + hsl_port_unk_uc_filter_get port_unk_uc_filter_get; + hsl_port_unk_mc_filter_set port_unk_mc_filter_set; + hsl_port_unk_mc_filter_get port_unk_mc_filter_get; + hsl_port_bc_filter_set port_bc_filter_set; + hsl_port_bc_filter_get port_bc_filter_get; + hsl_nestvlan_tpid_set nestvlan_tpid_set; + hsl_nestvlan_tpid_get nestvlan_tpid_get; + hsl_cpu_port_status_set cpu_port_status_set; + hsl_cpu_port_status_get cpu_port_status_get; + hsl_bc_to_cpu_port_set bc_to_cpu_port_set; + hsl_bc_to_cpu_port_get bc_to_cpu_port_get; + hsl_pppoe_cmd_set pppoe_cmd_set; + hsl_pppoe_cmd_get pppoe_cmd_get; + hsl_pppoe_status_set pppoe_status_set; + hsl_pppoe_status_get pppoe_status_get; + hsl_port_dhcp_set port_dhcp_set; + hsl_port_dhcp_get port_dhcp_get; + hsl_arp_cmd_set arp_cmd_set; + hsl_arp_cmd_get arp_cmd_get; + hsl_eapol_cmd_set eapol_cmd_set; + hsl_eapol_cmd_get eapol_cmd_get; + hsl_pppoe_session_add pppoe_session_add; + hsl_pppoe_session_del pppoe_session_del; + hsl_pppoe_session_get pppoe_session_get; + hsl_eapol_status_set eapol_status_set; + hsl_eapol_status_get eapol_status_get; + hsl_ripv1_status_set ripv1_status_set; + hsl_ripv1_status_get ripv1_status_get; + hsl_port_arp_req_status_set port_arp_req_status_set; + hsl_port_arp_req_status_get port_arp_req_status_get; + hsl_port_arp_ack_status_set port_arp_ack_status_set; + hsl_port_arp_ack_status_get port_arp_ack_status_get; + hsl_pppoe_session_table_add pppoe_session_table_add; + hsl_pppoe_session_table_del pppoe_session_table_del; + hsl_pppoe_session_table_get pppoe_session_table_get; + hsl_pppoe_session_id_set pppoe_session_id_set; + hsl_pppoe_session_id_get pppoe_session_id_get; + hsl_intr_mask_set intr_mask_set; + hsl_intr_mask_get intr_mask_get; + hsl_intr_status_get intr_status_get; + hsl_intr_status_clear intr_status_clear; + hsl_intr_port_link_mask_set intr_port_link_mask_set; + hsl_intr_port_link_mask_get intr_port_link_mask_get; + hsl_intr_port_link_status_get intr_port_link_status_get; + hsl_intr_mask_mac_linkchg_set intr_mask_mac_linkchg_set; + hsl_intr_mask_mac_linkchg_get intr_mask_mac_linkchg_get; + hsl_intr_status_mac_linkchg_get intr_status_mac_linkchg_get; + hsl_cpu_vid_en_set cpu_vid_en_set; + hsl_cpu_vid_en_get cpu_vid_en_get; + hsl_rtd_pppoe_en_set rtd_pppoe_en_set; + hsl_rtd_pppoe_en_get rtd_pppoe_en_get; + hsl_intr_status_mac_linkchg_clear intr_status_mac_linkchg_clear; + hsl_global_macaddr_set global_macaddr_set; + hsl_global_macaddr_get global_macaddr_get; + hsl_lldp_status_set lldp_status_set; + hsl_lldp_status_get lldp_status_get; + hsl_frame_crc_reserve_set frame_crc_reserve_set; + hsl_frame_crc_reserve_get frame_crc_reserve_get; + +/*qca808x_start*/ + /* Port control */ + hsl_port_duplex_set port_duplex_set; + hsl_port_duplex_get port_duplex_get; + hsl_port_speed_set port_speed_set; + hsl_port_speed_get port_speed_get; + hsl_port_autoneg_status_get port_autoneg_status_get; + hsl_port_autoneg_enable port_autoneg_enable; + hsl_port_autoneg_restart port_autoneg_restart; + hsl_port_autoneg_adv_get port_autoneg_adv_get; + hsl_port_autoneg_adv_set port_autoneg_adv_set; +/*qca808x_end*/ + hsl_port_hdr_status_set port_hdr_status_set; + hsl_port_hdr_status_get port_hdr_status_get; +/*qca808x_start*/ + hsl_port_flowctrl_set port_flowctrl_set; + hsl_port_flowctrl_get port_flowctrl_get; +/*qca808x_end*/ + hsl_port_flowctrl_thresh_set port_flowctrl_thresh_set; + hsl_port_flowctrl_forcemode_set port_flowctrl_forcemode_set; + hsl_port_flowctrl_forcemode_get port_flowctrl_forcemode_get; +/*qca808x_start*/ + hsl_port_powersave_set port_powersave_set; + hsl_port_powersave_get port_powersave_get; + hsl_port_hibernate_set port_hibernate_set; + hsl_port_hibernate_get port_hibernate_get; + hsl_port_cdt port_cdt; +/*qca808x_end*/ + hsl_port_rxhdr_mode_set port_rxhdr_mode_set; + hsl_port_rxhdr_mode_get port_rxhdr_mode_get; + hsl_port_txhdr_mode_set port_txhdr_mode_set; + hsl_port_txhdr_mode_get port_txhdr_mode_get; + hsl_header_type_set header_type_set; + hsl_header_type_get header_type_get; + hsl_port_txmac_status_set port_txmac_status_set; + hsl_port_txmac_status_get port_txmac_status_get; + hsl_port_rxmac_status_set port_rxmac_status_set; + hsl_port_rxmac_status_get port_rxmac_status_get; + hsl_port_txfc_status_set port_txfc_status_set; + hsl_port_txfc_status_get port_txfc_status_get; + hsl_port_rxfc_status_set port_rxfc_status_set; + hsl_port_rxfc_status_get port_rxfc_status_get; + hsl_port_bp_status_set port_bp_status_set; + hsl_port_bp_status_get port_bp_status_get; + hsl_port_link_forcemode_set port_link_forcemode_set; + hsl_port_link_forcemode_get port_link_forcemode_get; +/*qca808x_start*/ + hsl_port_link_status_get port_link_status_get; + hsl_ports_link_status_get ports_link_status_get; +/*qca808x_end*/ + hsl_port_mac_loopback_set port_mac_loopback_set; + hsl_port_mac_loopback_get port_mac_loopback_get; + hsl_port_congestion_drop_set port_congestion_drop_set; + hsl_port_congestion_drop_get port_congestion_drop_get; + hsl_ring_flow_ctrl_thres_set ring_flow_ctrl_thres_set; + hsl_ring_flow_ctrl_thres_get ring_flow_ctrl_thres_get; +/*qca808x_start*/ + hsl_port_8023az_set port_8023az_set; + hsl_port_8023az_get port_8023az_get; + hsl_port_mdix_set port_mdix_set; + hsl_port_mdix_get port_mdix_get; + hsl_port_mdix_status_get port_mdix_status_get; +/*qca808x_end*/ + hsl_port_combo_prefer_medium_set port_combo_prefer_medium_set; + hsl_port_combo_prefer_medium_get port_combo_prefer_medium_get; + hsl_port_combo_medium_status_get port_combo_medium_status_get; + hsl_port_combo_fiber_mode_set port_combo_fiber_mode_set; + hsl_port_combo_fiber_mode_get port_combo_fiber_mode_get; +/*qca808x_start*/ + hsl_port_local_loopback_set port_local_loopback_set; + hsl_port_local_loopback_get port_local_loopback_get; + hsl_port_remote_loopback_set port_remote_loopback_set; + hsl_port_remote_loopback_get port_remote_loopback_get; + hsl_port_reset port_reset; + hsl_port_power_off port_power_off; + hsl_port_power_on port_power_on; + hsl_port_phy_id_get port_phy_id_get; + hsl_port_wol_status_set port_wol_status_set; + hsl_port_wol_status_get port_wol_status_get; + hsl_port_magic_frame_mac_set port_magic_frame_mac_set; + hsl_port_magic_frame_mac_get port_magic_frame_mac_get; +/*qca808x_end*/ + hsl_port_interface_mode_set port_interface_mode_set; + hsl_port_interface_mode_get port_interface_mode_get; + hsl_port_interface_mode_apply port_interface_mode_apply; +/*qca808x_start*/ + hsl_port_interface_mode_status_get port_interface_mode_status_get; + hsl_port_counter_set port_counter_set; + hsl_port_counter_get port_counter_get; + hsl_port_counter_show port_counter_show; +/*qca808x_end*/ + + /* VLAN */ + hsl_vlan_entry_append vlan_entry_append; + hsl_vlan_create vlan_creat; + hsl_vlan_member_update vlan_member_update; + hsl_vlan_delete vlan_delete; + hsl_vlan_find vlan_find; + hsl_vlan_next vlan_next; + hsl_vlan_flush vlan_flush; + hsl_vlan_fid_set vlan_fid_set; + hsl_vlan_fid_get vlan_fid_get; + hsl_vlan_member_add vlan_member_add; + hsl_vlan_member_del vlan_member_del; + hsl_vlan_learning_state_set vlan_learning_state_set; + hsl_vlan_learning_state_get vlan_learning_state_get; + + /* Port VLAN */ + hsl_port_1qmode_set port_1qmode_set; + hsl_port_1qmode_get port_1qmode_get; + hsl_port_egvlanmode_get port_egvlanmode_get; + hsl_port_egvlanmode_set port_egvlanmode_set; + hsl_portvlan_member_add portvlan_member_add; + hsl_portvlan_member_del portvlan_member_del; + hsl_portvlan_member_update portvlan_member_update; + hsl_portvlan_member_get portvlan_member_get; + hsl_port_default_vid_set port_default_vid_set; + hsl_port_default_vid_get port_default_vid_get; + hsl_port_force_default_vid_set port_force_default_vid_set; + hsl_port_force_default_vid_get port_force_default_vid_get; + hsl_port_force_portvlan_set port_force_portvlan_set; + hsl_port_force_portvlan_get port_force_portvlan_get; + hsl_port_nestvlan_set port_nestvlan_set; + hsl_port_nestvlan_get port_nestvlan_get; + hsl_port_invlan_mode_set port_invlan_mode_set; + hsl_port_invlan_mode_get port_invlan_mode_get; + hsl_port_tls_set port_tls_set; + hsl_port_tls_get port_tls_get; + hsl_port_pri_propagation_set port_pri_propagation_set; + hsl_port_pri_propagation_get port_pri_propagation_get; + hsl_port_default_svid_set port_default_svid_set; + hsl_port_default_svid_get port_default_svid_get; + hsl_port_default_cvid_set port_default_cvid_set; + hsl_port_default_cvid_get port_default_cvid_get; + hsl_port_vlan_propagation_set port_vlan_propagation_set; + hsl_port_vlan_propagation_get port_vlan_propagation_get; + hsl_port_vlan_trans_add port_vlan_trans_add; + hsl_port_vlan_trans_del port_vlan_trans_del; + hsl_port_vlan_trans_get port_vlan_trans_get; + hsl_qinq_mode_set qinq_mode_set; + hsl_qinq_mode_get qinq_mode_get; + hsl_port_qinq_role_set port_qinq_role_set; + hsl_port_qinq_role_get port_qinq_role_get; + hsl_port_vlan_trans_iterate port_vlan_trans_iterate; + hsl_port_mac_vlan_xlt_set port_mac_vlan_xlt_set; + hsl_port_mac_vlan_xlt_get port_mac_vlan_xlt_get; + hsl_netisolate_set netisolate_set; + hsl_netisolate_get netisolate_get; + hsl_eg_trans_filter_bypass_en_set eg_trans_filter_bypass_en_set; + hsl_eg_trans_filter_bypass_en_get eg_trans_filter_bypass_en_get; + hsl_port_vrf_id_set port_vrf_id_set; + hsl_port_vrf_id_get port_vrf_id_get; + + /* FDB */ + hsl_fdb_add fdb_add; + hsl_fdb_del_all fdb_del_all; + hsl_fdb_del_by_port fdb_del_by_port; + hsl_fdb_del_by_mac fdb_del_by_mac; + hsl_fdb_first fdb_first; + hsl_fdb_next fdb_next; + hsl_fdb_find fdb_find; + hsl_fdb_port_learn_set port_learn_set; + hsl_fdb_port_learn_get port_learn_get; + hsl_fdb_age_ctrl_set age_ctrl_set; + hsl_fdb_age_ctrl_get age_ctrl_get; + hsl_fdb_vlan_ivl_svl_set vlan_ivl_svl_set; + hsl_fdb_vlan_ivl_svl_get vlan_ivl_svl_get; + hsl_fdb_age_time_set age_time_set; + hsl_fdb_age_time_get age_time_get; + hsl_fdb_iterate fdb_iterate; + hsl_fdb_extend_next fdb_extend_next; + hsl_fdb_extend_first fdb_extend_first; + hsl_fdb_transfer fdb_transfer; + hsl_port_fdb_learn_limit_set port_fdb_learn_limit_set; + hsl_port_fdb_learn_limit_get port_fdb_learn_limit_get; + hsl_port_fdb_learn_exceed_cmd_set port_fdb_learn_exceed_cmd_set; + hsl_port_fdb_learn_exceed_cmd_get port_fdb_learn_exceed_cmd_get; + hsl_fdb_learn_limit_set fdb_learn_limit_set; + hsl_fdb_learn_limit_get fdb_learn_limit_get; + hsl_fdb_learn_exceed_cmd_set fdb_learn_exceed_cmd_set; + hsl_fdb_learn_exceed_cmd_get fdb_learn_exceed_cmd_get; + hsl_fdb_resv_add fdb_resv_add; + hsl_fdb_resv_del fdb_resv_del; + hsl_fdb_resv_find fdb_resv_find; + hsl_fdb_resv_iterate fdb_resv_iterate; + hsl_fdb_port_learn_static_set fdb_port_learn_static_set; + hsl_fdb_port_learn_static_get fdb_port_learn_static_get; + hsl_fdb_port_add fdb_port_add; + hsl_fdb_port_del fdb_port_del; + hsl_fdb_rfs_set fdb_rfs_set; + hsl_fdb_rfs_del fdb_rfs_del; + + /* QOS */ + hsl_qos_sch_mode_set qos_sch_mode_set; + hsl_qos_sch_mode_get qos_sch_mode_get; + hsl_qos_queue_tx_buf_status_set qos_queue_tx_buf_status_set; + hsl_qos_queue_tx_buf_status_get qos_queue_tx_buf_status_get; + hsl_qos_port_tx_buf_status_set qos_port_tx_buf_status_set; + hsl_qos_port_tx_buf_status_get qos_port_tx_buf_status_get; + hsl_qos_port_red_en_set qos_port_red_en_set; + hsl_qos_port_red_en_get qos_port_red_en_get; + hsl_qos_queue_tx_buf_nr_set qos_queue_tx_buf_nr_set; + hsl_qos_queue_tx_buf_nr_get qos_queue_tx_buf_nr_get; + hsl_qos_port_tx_buf_nr_set qos_port_tx_buf_nr_set; + hsl_qos_port_tx_buf_nr_get qos_port_tx_buf_nr_get; + hsl_qos_port_rx_buf_nr_set qos_port_rx_buf_nr_set; + hsl_qos_port_rx_buf_nr_get qos_port_rx_buf_nr_get; + hsl_cosmap_up_queue_set cosmap_up_queue_set; + hsl_cosmap_up_queue_get cosmap_up_queue_get; + hsl_cosmap_dscp_queue_set cosmap_dscp_queue_set; + hsl_cosmap_dscp_queue_get cosmap_dscp_queue_get; + hsl_qos_port_mode_set qos_port_mode_set; + hsl_qos_port_mode_get qos_port_mode_get; + hsl_qos_port_mode_pri_set qos_port_mode_pri_set; + hsl_qos_port_mode_pri_get qos_port_mode_pri_get; + hsl_qos_port_default_up_set qos_port_default_up_set; + hsl_qos_port_default_up_get qos_port_default_up_get; + hsl_qos_port_sch_mode_set qos_port_sch_mode_set; + hsl_qos_port_sch_mode_get qos_port_sch_mode_get; + hsl_qos_port_default_spri_set qos_port_default_spri_set; + hsl_qos_port_default_spri_get qos_port_default_spri_get; + hsl_qos_port_default_cpri_set qos_port_default_cpri_set; + hsl_qos_port_default_cpri_get qos_port_default_cpri_get; + hsl_qos_port_force_spri_status_set qos_port_force_spri_status_set; + hsl_qos_port_force_spri_status_get qos_port_force_spri_status_get; + hsl_qos_port_force_cpri_status_set qos_port_force_cpri_status_set; + hsl_qos_port_force_cpri_status_get qos_port_force_cpri_status_get; + + hsl_qos_queue_remark_table_set qos_queue_remark_table_set; + hsl_qos_queue_remark_table_get qos_queue_remark_table_get; + hsl_port_static_thresh_get port_static_thresh_get; + hsl_port_static_thresh_set port_static_thresh_set; + + /* Rate */ + hsl_storm_ctrl_frame_set storm_ctrl_frame_set; + hsl_storm_ctrl_frame_get storm_ctrl_frame_get; + hsl_storm_ctrl_rate_set storm_ctrl_rate_set; + hsl_storm_ctrl_rate_get storm_ctrl_rate_get; + hsl_rate_queue_egrl_set rate_queue_egrl_set; + hsl_rate_queue_egrl_get rate_queue_egrl_get; + hsl_rate_port_egrl_set rate_port_egrl_set; + hsl_rate_port_egrl_get rate_port_egrl_get; + hsl_rate_port_inrl_set rate_port_inrl_set; + hsl_rate_port_inrl_get rate_port_inrl_get; + hsl_rate_port_policer_set rate_port_policer_set; + hsl_rate_port_policer_get rate_port_policer_get; + hsl_rate_port_shaper_set rate_port_shaper_set; + hsl_rate_port_shaper_get rate_port_shaper_get; + hsl_rate_queue_shaper_set rate_queue_shaper_set; + hsl_rate_queue_shaper_get rate_queue_shaper_get; + hsl_rate_acl_policer_set rate_acl_policer_set; + hsl_rate_acl_policer_get rate_acl_policer_get; + hsl_rate_port_add_rate_byte_set rate_port_add_rate_byte_set; + hsl_rate_port_add_rate_byte_get rate_port_add_rate_byte_get; + hsl_rate_port_gol_flow_en_set rate_port_gol_flow_en_set; + hsl_rate_port_gol_flow_en_get rate_port_gol_flow_en_get; + + /* Mirror */ + hsl_mirr_analysis_port_set mirr_analysis_port_set; + hsl_mirr_analysis_port_get mirr_analysis_port_get; + hsl_mirr_port_in_set mirr_port_in_set; + hsl_mirr_port_in_get mirr_port_in_get; + hsl_mirr_port_eg_set mirr_port_eg_set; + hsl_mirr_port_eg_get mirr_port_eg_get; + + /* Stp */ + hsl_stp_port_state_set stp_port_state_set; + hsl_stp_port_state_get stp_port_state_get; + + /* IGMP */ + hsl_port_igmps_status_set port_igmps_status_set; + hsl_port_igmps_status_get port_igmps_status_get; + hsl_igmp_mld_cmd_set igmp_mld_cmd_set; + hsl_igmp_mld_cmd_get igmp_mld_cmd_get; + hsl_port_igmp_join_set port_igmp_join_set; + hsl_port_igmp_join_get port_igmp_join_get; + hsl_port_igmp_leave_set port_igmp_leave_set; + hsl_port_igmp_leave_get port_igmp_leave_get; + hsl_igmp_rp_set igmp_rp_set; + hsl_igmp_rp_get igmp_rp_get; + hsl_igmp_entry_creat_set igmp_entry_creat_set; + hsl_igmp_entry_creat_get igmp_entry_creat_get; + hsl_igmp_entry_static_set igmp_entry_static_set; + hsl_igmp_entry_static_get igmp_entry_static_get; + hsl_igmp_entry_leaky_set igmp_entry_leaky_set; + hsl_igmp_entry_leaky_get igmp_entry_leaky_get; + hsl_igmp_entry_v3_set igmp_entry_v3_set; + hsl_igmp_entry_v3_get igmp_entry_v3_get; + hsl_igmp_entry_queue_set igmp_entry_queue_set; + hsl_igmp_entry_queue_get igmp_entry_queue_get; + hsl_port_igmp_mld_learn_limit_set port_igmp_mld_learn_limit_set; + hsl_port_igmp_mld_learn_limit_get port_igmp_mld_learn_limit_get; + hsl_port_igmp_mld_learn_exceed_cmd_set port_igmp_mld_learn_exceed_cmd_set; + hsl_port_igmp_mld_learn_exceed_cmd_get port_igmp_mld_learn_exceed_cmd_get; + hsl_igmp_sg_entry_set igmp_sg_entry_set; + hsl_igmp_sg_entry_clear igmp_sg_entry_clear; + hsl_igmp_sg_entry_show igmp_sg_entry_show; + hsl_igmp_sg_entry_query igmp_sg_entry_query; + + /* Leaky */ + hsl_uc_leaky_mode_set uc_leaky_mode_set; + hsl_uc_leaky_mode_get uc_leaky_mode_get; + hsl_mc_leaky_mode_set mc_leaky_mode_set; + hsl_mc_leaky_mode_get mc_leaky_mode_get; + hsl_port_arp_leaky_set port_arp_leaky_set; + hsl_port_arp_leaky_get port_arp_leaky_get; + hsl_port_uc_leaky_set port_uc_leaky_set; + hsl_port_uc_leaky_get port_uc_leaky_get; + hsl_port_mc_leaky_set port_mc_leaky_set; + hsl_port_mc_leaky_get port_mc_leaky_get; + + /* MIB API */ + hsl_get_mib_info get_mib_info; + hsl_get_rx_mib_info get_rx_mib_info; + hsl_get_tx_mib_info get_tx_mib_info; + hsl_mib_status_set mib_status_set; + hsl_mib_status_get mib_status_get; + hsl_mib_port_flush_counters mib_port_flush_counters; + hsl_mib_cpukeep_set mib_cpukeep_set; + hsl_mib_cpukeep_get mib_cpukeep_get; + + + /* Acl */ + hsl_acl_list_creat acl_list_creat; + hsl_acl_list_destroy acl_list_destroy; + hsl_acl_rule_add acl_rule_add; + hsl_acl_rule_delete acl_rule_delete; + hsl_acl_rule_query acl_rule_query; + hsl_acl_list_bind acl_list_bind; + hsl_acl_list_unbind acl_list_unbind; + hsl_acl_status_set acl_status_set; + hsl_acl_status_get acl_status_get; + hsl_acl_list_dump acl_list_dump; + hsl_acl_rule_dump acl_rule_dump; + hsl_acl_port_udf_profile_set acl_port_udf_profile_set; + hsl_acl_port_udf_profile_get acl_port_udf_profile_get; + hsl_acl_rule_active acl_rule_active; + hsl_acl_rule_deactive acl_rule_deactive; + hsl_acl_rule_src_filter_sts_set acl_rule_src_filter_sts_set; + hsl_acl_rule_src_filter_sts_get acl_rule_src_filter_sts_get; + hsl_acl_rule_get_offset acl_rule_get_offset; + hsl_acl_rule_sync_multi_portmap acl_rule_sync_multi_portmap; + + /* LED */ + hsl_led_ctrl_pattern_set led_ctrl_pattern_set; + hsl_led_ctrl_pattern_get led_ctrl_pattern_get; + hsl_led_ctrl_source_set led_ctrl_source_set; + + /* CoSMap */ + hsl_cosmap_dscp_to_pri_set cosmap_dscp_to_pri_set; + hsl_cosmap_dscp_to_pri_get cosmap_dscp_to_pri_get; + hsl_cosmap_dscp_to_dp_set cosmap_dscp_to_dp_set; + hsl_cosmap_dscp_to_dp_get cosmap_dscp_to_dp_get; + hsl_cosmap_up_to_pri_set cosmap_up_to_pri_set; + hsl_cosmap_up_to_pri_get cosmap_up_to_pri_get; + hsl_cosmap_up_to_dp_set cosmap_up_to_dp_set; + hsl_cosmap_up_to_dp_get cosmap_up_to_dp_get; + hsl_cosmap_dscp_to_ehpri_set cosmap_dscp_to_ehpri_set; + hsl_cosmap_dscp_to_ehpri_get cosmap_dscp_to_ehpri_get; + hsl_cosmap_dscp_to_ehdp_set cosmap_dscp_to_ehdp_set; + hsl_cosmap_dscp_to_ehdp_get cosmap_dscp_to_ehdp_get; + hsl_cosmap_up_to_ehpri_set cosmap_up_to_ehpri_set; + hsl_cosmap_up_to_ehpri_get cosmap_up_to_ehpri_get; + hsl_cosmap_up_to_ehdp_set cosmap_up_to_ehdp_set; + hsl_cosmap_up_to_ehdp_get cosmap_up_to_ehdp_get; + hsl_cosmap_pri_to_queue_set cosmap_pri_to_queue_set; + hsl_cosmap_pri_to_queue_get cosmap_pri_to_queue_get; + hsl_cosmap_pri_to_ehqueue_set cosmap_pri_to_ehqueue_set; + hsl_cosmap_pri_to_ehqueue_get cosmap_pri_to_ehqueue_get; + hsl_cosmap_egress_remark_set cosmap_egress_remark_set; + hsl_cosmap_egress_remark_get cosmap_egress_remark_get; + + /* IP */ + hsl_ip_host_add ip_host_add; + hsl_ip_host_del ip_host_del; + hsl_ip_host_get ip_host_get; + hsl_ip_host_next ip_host_next; + hsl_ip_host_counter_bind ip_host_counter_bind; + hsl_ip_host_pppoe_bind ip_host_pppoe_bind; + hsl_ip_pt_arp_learn_set ip_pt_arp_learn_set; + hsl_ip_pt_arp_learn_get ip_pt_arp_learn_get; + hsl_ip_arp_learn_set ip_arp_learn_set; + hsl_ip_arp_learn_get ip_arp_learn_get; + hsl_ip_source_guard_set ip_source_guard_set; + hsl_ip_source_guard_get ip_source_guard_get; + hsl_ip_unk_source_cmd_set ip_unk_source_cmd_set; + hsl_ip_unk_source_cmd_get ip_unk_source_cmd_get; + hsl_ip_arp_guard_set ip_arp_guard_set; + hsl_ip_arp_guard_get ip_arp_guard_get; + hsl_arp_unk_source_cmd_set arp_unk_source_cmd_set; + hsl_arp_unk_source_cmd_get arp_unk_source_cmd_get; + hsl_ip_route_status_set ip_route_status_set; + hsl_ip_route_status_get ip_route_status_get; + hsl_ip_intf_entry_add ip_intf_entry_add; + hsl_ip_intf_entry_del ip_intf_entry_del; + hsl_ip_intf_entry_next ip_intf_entry_next; + hsl_ip_age_time_set ip_age_time_set; + hsl_ip_age_time_get ip_age_time_get; + hsl_ip_wcmp_hash_mode_set ip_wcmp_hash_mode_set; + hsl_ip_wcmp_hash_mode_get ip_wcmp_hash_mode_get; + hsl_ip_vrf_base_addr_set ip_vrf_base_addr_set; + hsl_ip_vrf_base_addr_get ip_vrf_base_addr_get; + hsl_ip_vrf_base_mask_set ip_vrf_base_mask_set; + hsl_ip_vrf_base_mask_get ip_vrf_base_mask_get; + hsl_ip_default_route_set ip_default_route_set; + hsl_ip_default_route_get ip_default_route_get; + hsl_ip_host_route_set ip_host_route_set; + hsl_ip_host_route_get ip_host_route_get; + hsl_ip_wcmp_entry_set ip_wcmp_entry_set; + hsl_ip_wcmp_entry_get ip_wcmp_entry_get; + hsl_ip_rfs_ip4_set ip_rfs_ip4_set; + hsl_ip_rfs_ip6_set ip_rfs_ip6_set; + hsl_ip_rfs_ip4_del ip_rfs_ip4_del; + hsl_ip_rfs_ip6_del ip_rfs_ip6_del; + hsl_default_flow_cmd_set ip_default_flow_cmd_set; + hsl_default_flow_cmd_get ip_default_flow_cmd_get; + hsl_default_rt_flow_cmd_set ip_default_rt_flow_cmd_set; + hsl_default_rt_flow_cmd_get ip_default_rt_flow_cmd_get; + hsl_ip_glb_lock_time_set ip_glb_lock_time_set; + + /* NAT */ + hsl_nat_add nat_add; + hsl_nat_del nat_del; + hsl_nat_get nat_get; + hsl_nat_next nat_next; + hsl_nat_counter_bind nat_counter_bind; + hsl_napt_add napt_add; + hsl_napt_del napt_del; + hsl_napt_get napt_get; + hsl_napt_next napt_next; + hsl_napt_counter_bind napt_counter_bind; + hsl_napt_add flow_add; + hsl_napt_del flow_del; + hsl_napt_get flow_get; + hsl_napt_next flow_next; + hsl_napt_counter_bind flow_counter_bind; + hsl_nat_status_set nat_status_set; + hsl_nat_status_get nat_status_get; + hsl_nat_hash_mode_set nat_hash_mode_set; + hsl_nat_hash_mode_get nat_hash_mode_get; + hsl_napt_status_set napt_status_set; + hsl_napt_status_get napt_status_get; + hsl_napt_mode_set napt_mode_set; + hsl_napt_mode_get napt_mode_get; + hsl_nat_prv_base_addr_set nat_prv_base_addr_set; + hsl_nat_prv_base_addr_get nat_prv_base_addr_get; + hsl_nat_prv_base_mask_set nat_prv_base_mask_set; + hsl_nat_prv_base_mask_get nat_prv_base_mask_get; + hsl_nat_prv_addr_mode_set nat_prv_addr_mode_set; + hsl_nat_prv_addr_mode_get nat_prv_addr_mode_get; + hsl_nat_pub_addr_add nat_pub_addr_add; + hsl_nat_pub_addr_del nat_pub_addr_del; + hsl_nat_pub_addr_next nat_pub_addr_next; + hsl_nat_unk_session_cmd_set nat_unk_session_cmd_set; + hsl_nat_unk_session_cmd_get nat_unk_session_cmd_get; + hsl_nat_global_set nat_global_set; + hsl_flow_cookie_set flow_cookie_set; + hsl_flow_rfs_set flow_rfs_set; + + /* SEC */ + hsl_sec_norm_item_set sec_norm_item_set; + hsl_sec_norm_item_get sec_norm_item_get; + + /* Trunk */ + hsl_trunk_group_set trunk_group_set; + hsl_trunk_group_get trunk_group_get; + hsl_trunk_hash_mode_set trunk_hash_mode_set; + hsl_trunk_hash_mode_get trunk_hash_mode_get; + hsl_trunk_manipulate_sa_set trunk_manipulate_sa_set; + hsl_trunk_manipulate_sa_get trunk_manipulate_sa_get; + + /* Interface Control */ + hsl_interface_mac_mode_set interface_mac_mode_set; + hsl_interface_mac_mode_get interface_mac_mode_get; + hsl_port_3az_status_set port_3az_status_set; + hsl_port_3az_status_get port_3az_status_get; + hsl_interface_phy_mode_set interface_phy_mode_set; + hsl_interface_phy_mode_get interface_phy_mode_get; + hsl_interface_fx100_ctrl_set interface_fx100_ctrl_set; + hsl_interface_fx100_ctrl_get interface_fx100_ctrl_get; + hsl_interface_fx100_status_get interface_fx100_status_get; + hsl_interface_mac06_exch_set interface_mac06_exch_set; + hsl_interface_mac06_exch_get interface_mac06_exch_get; + hsl_interface_pad_get interface_mac_pad_get; + hsl_interface_pad_set interface_mac_pad_set; + hsl_interface_sgmii_get interface_mac_sgmii_get; + hsl_interface_sgmii_set interface_mac_sgmii_set; +#endif +#endif +/*qca808x_start*/ + /* REG Access */ + hsl_phy_get phy_get; + hsl_phy_set phy_set; +/*qca808x_end*/ + hsl_reg_get reg_get; + hsl_reg_set reg_set; + hsl_reg_field_get reg_field_get; + hsl_reg_field_set reg_field_set; + hsl_reg_entries_get reg_entries_get; + hsl_reg_entries_set reg_entries_set; + hsl_psgmii_reg_get psgmii_reg_get; + hsl_psgmii_reg_set psgmii_reg_set; + hsl_register_dump register_dump; + hsl_debug_register_dump debug_register_dump; + hsl_debug_psgmii_self_test debug_psgmii_self_test; + hsl_phy_dump phy_dump; + hsl_uniphy_reg_get uniphy_reg_get; + hsl_uniphy_reg_set uniphy_reg_set; +/*qca808x_start*/ + /*INIT*/ hsl_dev_reset dev_reset; + hsl_dev_clean dev_clean; +/*qca808x_end*/ + hsl_dev_access_set dev_access_set; +/*qca808x_start*/ + hsl_phy_get phy_i2c_get; + hsl_phy_set phy_i2c_set; + } hsl_api_t; + + hsl_api_t *hsl_api_ptr_get (a_uint32_t dev_id); + + sw_error_t hsl_api_init (a_uint32_t dev_id); + +#if defined(SW_API_LOCK) && (!defined(HSL_STANDALONG)) + extern aos_lock_t sw_hsl_api_lock; +#define FAL_API_LOCK aos_lock(&sw_hsl_api_lock) +#define FAL_API_UNLOCK aos_unlock(&sw_hsl_api_lock) +#else +#define FAL_API_LOCK +#define FAL_API_UNLOCK +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _SW_API_H */ +/*qca808x_end*/ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hsl_dev.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hsl_dev.h new file mode 100755 index 000000000..48d3eb581 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hsl_dev.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2012, 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 _HSL_DEV_H +#define _HSL_DEV_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "hsl_api.h" +#include "ssdk_init.h" + +#define HSL_DEV_ID_CHECK(dev_id) \ +do { \ + if (dev_id >= SW_MAX_NR_DEV) \ + return SW_OUT_OF_RANGE; \ +} while (0) + +#define HSL_PORT_ID_CHECK(port_id) \ +do { \ + if (port_id >= SW_MAX_NR_PORT) \ + return SW_OUT_OF_RANGE; \ +} while (0) + + typedef struct + { + a_uint32_t dev_id; + a_uint8_t cpu_port_nr; + a_uint8_t nr_ports; + a_uint8_t nr_phy; + a_uint8_t nr_queue; + a_uint16_t nr_vlans; + a_bool_t hw_vlan_query; + hsl_acl_func_t acl_func; + hsl_init_mode cpu_mode; + a_uint32_t wan_bmp; + } hsl_dev_t; + + hsl_dev_t *hsl_dev_ptr_get(a_uint32_t dev_id); +/*qca808x_end*/ + hsl_acl_func_t *hsl_acl_ptr_get(a_uint32_t dev_id); +/*qca808x_start*/ + sw_error_t + hsl_dev_init(a_uint32_t dev_id, ssdk_init_cfg * cfg); + + sw_error_t + hsl_dev_cleanup(void); + +/*qca808x_end*/ + sw_error_t + hsl_ssdk_cfg(a_uint32_t dev_id, ssdk_cfg_t *ssdk_cfg); + + sw_error_t + hsl_access_mode_set(a_uint32_t dev_id, hsl_access_mode reg_mode); + + a_uint32_t hsl_dev_inner_ports_get(a_uint32_t dev_id); + +/*qca808x_start*/ +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _HSL_DEV_H */ +/*qca808x_end*/ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hsl_lock.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hsl_lock.h new file mode 100755 index 000000000..db79fd5e0 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hsl_lock.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _HSL_LOCK_H_ +#define _HSL_LOCK_H_ + +#ifdef __cplusplus +extern "c" { +#endif + sw_error_t hsl_api_lock_init(void); + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /*_HSL_LOCK_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hsl_port_prop.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hsl_port_prop.h new file mode 100755 index 000000000..9b2c419d8 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hsl_port_prop.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2012, 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 _HSL_PORT_PROPERTY_H_ +#define _HSL_PORT_PROPERTY_H_ + +#ifdef __cplusplus +extern "c" { +#endif + + typedef enum { + HSL_PP_PHY = 0, /* setting concerning phy */ + HSL_PP_INCL_CPU, /* setting may include cpu port */ + HSL_PP_EXCL_CPU, /* setting exclude cpu port */ + HSL_PP_INNER, /* setting inner ports */ + HSL_PP_CPU, /* setting cpu ports */ + HSL_PP_BUTT + } + hsl_port_prop_t; + + a_bool_t + hsl_port_prop_check(a_uint32_t dev_id, fal_port_t port_id, + hsl_port_prop_t p_type); + + a_bool_t + hsl_mports_prop_check(a_uint32_t dev_id, fal_pbmp_t port_bitmap, + hsl_port_prop_t p_type); + a_bool_t + hsl_port_validity_check(a_uint32_t dev_id, fal_port_t port_id); + + a_bool_t + hsl_mports_validity_check(a_uint32_t dev_id, fal_pbmp_t port_bitmap); + + sw_error_t + hsl_port_prop_portmap_get(a_uint32_t dev_id, fal_pbmp_t port_bitmap); + + sw_error_t + hsl_port_prop_set(a_uint32_t dev_id, fal_port_t port_id, + hsl_port_prop_t p_type); + + sw_error_t + hsl_port_prop_portmap_set(a_uint32_t dev_id, fal_port_t port_id); + + sw_error_t + hsl_port_prop_clr(a_uint32_t dev_id, fal_port_t port_id, + hsl_port_prop_t p_type); + + sw_error_t + hsl_port_prop_get_phyid(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t *phy_id); + + sw_error_t + hsl_port_prop_set_phyid(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t phy_id); + + sw_error_t + hsl_port_prop_init_by_dev(a_uint32_t dev_id); + + sw_error_t + hsl_port_prop_cleanup_by_dev(a_uint32_t dev_id); + + sw_error_t + hsl_port_prop_init(a_uint32_t dev_id); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /*_HSL_PORT_PROPERTY_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/hsl_shared_api.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/hsl_shared_api.h new file mode 100755 index 000000000..cbf7294ec --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/hsl_shared_api.h @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2012, 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. + */ + +#ifndef _HSL_SHARED_API_H +#define _HSL_SHARED_API_H + +#include "hsl.h" +#include "hsl_api.h" +#include "ssdk_init.h" + +extern ssdk_chip_type SSDK_CURRENT_CHIP_TYPE; /*running chip type*/ + +#if !defined (HSL_STANDALONG) +/*MISC API*/ +#define PORT_BC_FILTER_SET fal_port_bc_filter_set +#define PORT_UNK_MC_FILTER_SET fal_port_unk_mc_filter_set +#define PORT_UNK_UC_FILTER_SET fal_port_unk_uc_filter_set + +/*ACL API*/ +#define ACL_RULE_QUERY fal_acl_rule_query + +/*VLAN API */ +#define VLAN_CREATE fal_vlan_create +#define VLAN_DEL fal_vlan_delete +#define VLAN_FIND fal_vlan_find +#define VLAN_MEMBER_ADD fal_vlan_member_add + +/*RATE API*/ +#define RATE_ACL_POLICER_SET fal_rate_acl_policer_set + +/*MIB API*/ +#define MIB_STATUS_SET fal_mib_status_set +#define GET_MIB_INFO fal_get_mib_info + +/* PORT_CTRL API */ +#define PORT_TXMAC_STATUS_SET fal_port_txmac_status_set +#define PORT_RXMAC_STATUS_SET fal_port_rxmac_status_set + +#elif defined(ISISC) +/* NAT API*/ +#include "isisc_nat.h" +#define NAPT_ADD isisc_napt_add +#define NAT_PUB_ADDR_ADD isisc_nat_pub_addr_add +#define NAPT_NEXT isisc_napt_next +#define NAT_PRV_BASE_ADDR_SET isisc_nat_prv_base_addr_set +#define NAT_PRV_BASE_MASK_SET isisc_nat_prv_base_mask_set +#define NAPT_DEL isisc_napt_del +#define NAT_DEL isisc_nat_del +#define NAT_PUB_ADDR_DEL isisc_nat_pub_addr_del +#define NAT_ADD isisc_nat_add +#define NAT_PRV_ADDR_MODE_GET isisc_nat_prv_addr_mode_get + +/*IP API*/ +#include "isisc_ip.h" +#define IP_INTF_ENTRY_ADD isisc_ip_intf_entry_add +#define IP_HOST_ADD isisc_ip_host_add +#define IP_HOST_DEL isisc_ip_host_del +#define IP_HOST_GET isisc_ip_host_get +#define IP_HOST_NEXT isisc_ip_host_next +#define IP_INTF_ENTRY_DEL isisc_ip_intf_entry_del +#define IP_HOST_PPPOE_BIND isisc_ip_host_pppoe_bind +#define IP_ROUTE_STATUS_SET isisc_ip_route_status_set + +/*MISC API*/ +#include "isisc_misc.h" +#define PPPOE_STATUS_GET isisc_pppoe_status_get +#define PPPOE_STATUS_SET isisc_pppoe_status_set +#define PPPOE_SESSION_ID_SET isisc_pppoe_session_id_set +#define PPPOE_SESSION_TABLE_ADD isisc_pppoe_session_table_add +#define PPPOE_SESSION_TABLE_DEL isisc_pppoe_session_table_del +#define PORT_BC_FILTER_SET isisc_port_bc_filter_set +#define PORT_UNK_MC_FILTER_SET isisc_port_unk_mc_filter_set +#define PORT_UNK_UC_FILTER_SET isisc_port_unk_uc_filter_set +#define PORT_RXMAC_STATUS_SET isisc_port_rxmac_status_set +#define MISC_ARP_CMD_SET isisc_arp_cmd_set +#define MISC_ARP_SP_NOT_FOUND_SET isisc_arp_unk_source_cmd_set +#define MISC_ARP_GUARD_SET isisc_ip_arp_guard_set +#define CPU_VID_EN_SET isisc_cpu_vid_en_set +#define RTD_PPPOE_EN_SET isisc_rtd_pppoe_en_set +#define PORT_ARP_ACK_STATUS_SET isisc_port_arp_ack_status_set +#define CPU_PORT_STATUS_SET isisc_cpu_port_status_set + +/*ACL API*/ +#include "isisc_acl.h" +#define ACL_RULE_ADD isisc_acl_rule_add +#define ACL_RULE_DEL isisc_acl_rule_delete +#define ACL_LIST_CREATE isisc_acl_list_creat +#define ACL_LIST_DESTROY isisc_acl_list_destroy +#define ACL_LIST_BIND isisc_acl_list_bind +#define ACL_LIST_UNBIND isisc_acl_list_unbind +#define ACL_RULE_GET_OFFSET isisc_acl_rule_get_offset +#define ACL_RULE_QUERY isisc_acl_rule_query +#define ACL_RULE_SYNC_MULTI_PORTMAP isisc_acl_rule_sync_multi_portmap +#define ACL_STATUS_GET isisc_acl_status_get +#define ACL_STATUS_SET isisc_acl_status_set +#define ACL_PORT_UDF_PROFILE_SET isisc_acl_port_udf_profile_set + +/*VLAN API */ +#include "isisc_vlan.h" +#define VLAN_CREATE isisc_vlan_create +#define VLAN_DEL isisc_vlan_delete +#define VLAN_FIND isisc_vlan_find +#define VLAN_MEMBER_ADD isisc_vlan_member_add + +/*RATE API*/ +#include "isisc_rate.h" +#define RATE_ACL_POLICER_SET isisc_rate_acl_policer_set + +/*MIB API*/ +#include "isisc_mib.h" +#define MIB_STATUS_SET isisc_mib_status_set +#define GET_MIB_INFO isisc_get_mib_info + +/* PORTVLAN API */ +#include "isisc_portvlan.h" +#define PORTVLAN_ROUTE_DEFV_SET isisc_port_route_defv_set +#define NETISOLATE_SET isisc_netisolate_set + +/* PORT_CTRL API */ +#include "isisc_port_ctrl.h" +#define HEADER_TYPE_SET isisc_header_type_set +#define PORT_TXHDR_MODE_SET isisc_port_txhdr_mode_set +#define PORT_TXMAC_STATUS_SET isisc_port_txmac_status_set + +#elif defined(ISIS) +/* NAT API*/ +#include "isis_nat.h" +#define NAPT_ADD isis_napt_add +#define NAT_PUB_ADDR_ADD isis_nat_pub_addr_add +#define NAPT_NEXT isis_napt_next +#define NAT_PRV_BASE_ADDR_SET isis_nat_prv_base_addr_set +#define NAT_PRV_BASE_MASK_SET isis_nat_prv_base_mask_set +#define NAPT_DEL isis_napt_del +#define NAT_DEL isis_nat_del +#define NAT_PUB_ADDR_DEL isis_nat_pub_addr_del +#define NAT_ADD isis_nat_add +#define NAT_PRV_ADDR_MODE_GET isis_nat_prv_addr_mode_get + +/*IP API*/ +#include "isis_ip.h" +#define IP_INTF_ENTRY_ADD isis_ip_intf_entry_add +#define IP_HOST_ADD isis_ip_host_add +#define IP_HOST_DEL isis_ip_host_del +#define IP_HOST_GET isis_ip_host_get +#define IP_HOST_NEXT isis_ip_host_next +#define IP_INTF_ENTRY_DEL isis_ip_intf_entry_del +#define IP_HOST_PPPOE_BIND isis_ip_host_pppoe_bind +#define IP_ROUTE_STATUS_SET isis_ip_route_status_set + +/*MISC API*/ +#include "isis_misc.h" +#define PPPOE_STATUS_GET isis_pppoe_status_get +#define PPPOE_STATUS_SET isis_pppoe_status_set +#define PPPOE_SESSION_ID_SET isis_pppoe_session_id_set +#define PPPOE_SESSION_TABLE_ADD isis_pppoe_session_table_add +#define PPPOE_SESSION_TABLE_DEL isis_pppoe_session_table_del +#define PORT_BC_FILTER_SET isis_port_bc_filter_set +#define PORT_UNK_MC_FILTER_SET isis_port_unk_mc_filter_set +#define PORT_UNK_UC_FILTER_SET isis_port_unk_uc_filter_set +#define PORT_RXMAC_STATUS_SET isis_port_rxmac_status_set +#define MISC_ARP_CMD_SET isis_arp_cmd_set +#define CPU_VID_EN_SET isis_cpu_vid_en_set +#define RTD_PPPOE_EN_SET isis_rtd_pppoe_en_set +#define PORT_ARP_ACK_STATUS_SET isis_port_arp_ack_status_set +#define CPU_PORT_STATUS_SET isis_cpu_port_status_set + +/*ACL API*/ +#include "isis_acl.h" +#define ACL_RULE_ADD isis_acl_rule_add +#define ACL_RULE_DEL isis_acl_rule_delete +#define ACL_LIST_CREATE isis_acl_list_creat +#define ACL_LIST_DESTROY isis_acl_list_destroy +#define ACL_LIST_BIND isis_acl_list_bind +#define ACL_LIST_UNBIND isis_acl_list_unbind +#define ACL_RULE_GET_OFFSET isis_acl_rule_get_offset +#define ACL_RULE_QUERY isis_acl_rule_query +#define ACL_RULE_SYNC_MULTI_PORTMAP isis_acl_rule_sync_multi_portmap +#define ACL_STATUS_GET isis_acl_status_get +#define ACL_STATUS_SET isis_acl_status_set +#define ACL_PORT_UDF_PROFILE_SET isis_acl_port_udf_profile_set + +/*VLAN API */ +#include "isis_vlan.h" +#define VLAN_CREATE isis_vlan_create +#define VLAN_DEL isis_vlan_delete +#define VLAN_FIND isis_vlan_find +#define VLAN_MEMBER_ADD isis_vlan_member_add + +/*RATE API*/ +#include "isis_rate.h" +#define RATE_ACL_POLICER_SET isis_rate_acl_policer_set + +/*MIB API*/ +#include "isis_mib.h" +#define MIB_STATUS_SET isis_mib_status_set +#define GET_MIB_INFO isis_get_mib_info + +/* PORTVLAN API */ +#include "isis_portvlan.h" +#define PORTVLAN_ROUTE_DEFV_SET isis_port_route_defv_set + +/* PORT_CTRL API */ +#include "isis_port_ctrl.h" +#define HEADER_TYPE_SET isis_header_type_set +#define PORT_TXHDR_MODE_SET isis_port_txhdr_mode_set +#define PORT_TXMAC_STATUS_SET isis_port_txmac_status_set +#endif + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_acl.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_acl.h new file mode 100755 index 000000000..8f34225e9 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_acl.h @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 isis_acl ISIS_ACL + * @{ + */ +#ifndef _ISIS_ACL_H_ +#define _ISIS_ACL_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_acl.h" + + sw_error_t isis_acl_init(a_uint32_t dev_id); + + sw_error_t isis_acl_reset(a_uint32_t dev_id); + + sw_error_t isis_acl_cleanup(a_uint32_t dev_id); + +#ifdef IN_ACL +#define ISIS_ACL_INIT(rv, dev_id) \ + { \ + rv = isis_acl_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } + +#define ISIS_ACL_RESET(rv, dev_id) \ + { \ + rv = isis_acl_reset(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#define ISIS_ACL_CLEANUP(rv, dev_id) \ + { \ + rv = isis_acl_cleanup(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISIS_ACL_INIT(rv, dev_id) +#define ISIS_ACL_RESET(rv, dev_id) +#define ISIS_ACL_CLEANUP(rv, dev_id) +#endif + + sw_error_t + isis_acl_list_creat(a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t list_pri); + + sw_error_t + isis_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 + isis_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 + isis_acl_rule_delete(a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t rule_id, a_uint32_t rule_nr); + + a_uint32_t + isis_acl_rule_get_offset(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t rule_id); + + sw_error_t + isis_acl_rule_sync_multi_portmap(a_uint32_t dev_id, a_uint32_t pos, a_uint32_t *act); + + sw_error_t + isis_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 + isis_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 + isis_acl_status_set(a_uint32_t dev_id, a_bool_t enable); + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + isis_acl_list_destroy(a_uint32_t dev_id, a_uint32_t list_id); + + HSL_LOCAL sw_error_t + isis_acl_status_get(a_uint32_t dev_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + isis_acl_list_dump(a_uint32_t dev_id); + + HSL_LOCAL sw_error_t + isis_acl_rule_dump(a_uint32_t dev_id); + + HSL_LOCAL sw_error_t + isis_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); + + HSL_LOCAL sw_error_t + isis_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); + + HSL_LOCAL sw_error_t + isis_acl_rule_active(a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t rule_id, a_uint32_t rule_nr); + + HSL_LOCAL sw_error_t + isis_acl_rule_deactive(a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t rule_id, a_uint32_t rule_nr); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISIS_ACL_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_api.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_api.h new file mode 100755 index 000000000..7fbc03f1b --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_api.h @@ -0,0 +1,992 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISIS_API_H_ +#define _ISIS_API_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifdef IN_PORTCONTROL +#define PORTCONTROL_API \ + SW_API_DEF(SW_API_PT_DUPLEX_GET, isis_port_duplex_get), \ + SW_API_DEF(SW_API_PT_DUPLEX_SET, isis_port_duplex_set), \ + SW_API_DEF(SW_API_PT_SPEED_GET, isis_port_speed_get), \ + SW_API_DEF(SW_API_PT_SPEED_SET, isis_port_speed_set), \ + SW_API_DEF(SW_API_PT_AN_GET, isis_port_autoneg_status_get), \ + SW_API_DEF(SW_API_PT_AN_ENABLE, isis_port_autoneg_enable), \ + SW_API_DEF(SW_API_PT_AN_RESTART, isis_port_autoneg_restart), \ + SW_API_DEF(SW_API_PT_AN_ADV_GET, isis_port_autoneg_adv_get), \ + SW_API_DEF(SW_API_PT_AN_ADV_SET, isis_port_autoneg_adv_set), \ + SW_API_DEF(SW_API_PT_FLOWCTRL_SET, isis_port_flowctrl_set), \ + SW_API_DEF(SW_API_PT_FLOWCTRL_GET, isis_port_flowctrl_get), \ + SW_API_DEF(SW_API_PT_FLOWCTRL_MODE_SET, isis_port_flowctrl_forcemode_set), \ + SW_API_DEF(SW_API_PT_FLOWCTRL_MODE_GET, isis_port_flowctrl_forcemode_get), \ + SW_API_DEF(SW_API_PT_POWERSAVE_SET, isis_port_powersave_set), \ + SW_API_DEF(SW_API_PT_POWERSAVE_GET, isis_port_powersave_get), \ + SW_API_DEF(SW_API_PT_HIBERNATE_SET, isis_port_hibernate_set), \ + SW_API_DEF(SW_API_PT_HIBERNATE_GET, isis_port_hibernate_get), \ + SW_API_DEF(SW_API_PT_CDT, isis_port_cdt), \ + SW_API_DEF(SW_API_PT_TXHDR_SET, isis_port_txhdr_mode_set), \ + SW_API_DEF(SW_API_PT_TXHDR_GET, isis_port_txhdr_mode_get), \ + SW_API_DEF(SW_API_PT_RXHDR_SET, isis_port_rxhdr_mode_set), \ + SW_API_DEF(SW_API_PT_RXHDR_GET, isis_port_rxhdr_mode_get), \ + SW_API_DEF(SW_API_HEADER_TYPE_SET, isis_header_type_set), \ + SW_API_DEF(SW_API_HEADER_TYPE_GET, isis_header_type_get), \ + SW_API_DEF(SW_API_TXMAC_STATUS_SET, isis_port_txmac_status_set), \ + SW_API_DEF(SW_API_TXMAC_STATUS_GET, isis_port_txmac_status_get), \ + SW_API_DEF(SW_API_RXMAC_STATUS_SET, isis_port_rxmac_status_set), \ + SW_API_DEF(SW_API_RXMAC_STATUS_GET, isis_port_rxmac_status_get), \ + SW_API_DEF(SW_API_TXFC_STATUS_SET, isis_port_txfc_status_set), \ + SW_API_DEF(SW_API_TXFC_STATUS_GET, isis_port_txfc_status_get), \ + SW_API_DEF(SW_API_RXFC_STATUS_SET, isis_port_rxfc_status_set), \ + SW_API_DEF(SW_API_RXFC_STATUS_GET, isis_port_rxfc_status_get), \ + SW_API_DEF(SW_API_BP_STATUS_SET, isis_port_bp_status_set), \ + SW_API_DEF(SW_API_BP_STATUS_GET, isis_port_bp_status_get), \ + SW_API_DEF(SW_API_PT_LINK_MODE_SET, isis_port_link_forcemode_set), \ + SW_API_DEF(SW_API_PT_LINK_MODE_GET, isis_port_link_forcemode_get), \ + SW_API_DEF(SW_API_PT_LINK_STATUS_GET, isis_port_link_status_get), \ + SW_API_DEF(SW_API_PT_MAC_LOOPBACK_SET, isis_port_mac_loopback_set), \ + SW_API_DEF(SW_API_PT_MAC_LOOPBACK_GET, isis_port_mac_loopback_get), \ + SW_API_DEF(SW_API_PT_8023AZ_SET, isis_port_8023az_set), \ + SW_API_DEF(SW_API_PT_8023AZ_GET, isis_port_8023az_get), + +#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) \ + 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) \ + SW_API_DESC(SW_API_PT_HIBERNATE_SET) \ + SW_API_DESC(SW_API_PT_HIBERNATE_GET) \ + SW_API_DESC(SW_API_PT_CDT) \ + 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) \ + SW_API_DESC(SW_API_PT_LINK_STATUS_GET) \ + SW_API_DESC(SW_API_PT_MAC_LOOPBACK_SET) \ + SW_API_DESC(SW_API_PT_MAC_LOOPBACK_GET) \ + SW_API_DESC(SW_API_PT_8023AZ_SET) \ + SW_API_DESC(SW_API_PT_8023AZ_GET) +#else +#define PORTCONTROL_API +#define PORTCONTROL_API_PARAM +#endif + +#ifdef IN_VLAN +#define VLAN_API \ + SW_API_DEF(SW_API_VLAN_ADD, isis_vlan_create), \ + SW_API_DEF(SW_API_VLAN_DEL, isis_vlan_delete), \ + SW_API_DEF(SW_API_VLAN_FIND, isis_vlan_find), \ + SW_API_DEF(SW_API_VLAN_NEXT, isis_vlan_next), \ + SW_API_DEF(SW_API_VLAN_APPEND, isis_vlan_entry_append), \ + SW_API_DEF(SW_API_VLAN_FLUSH, isis_vlan_flush), \ + SW_API_DEF(SW_API_VLAN_FID_SET, isis_vlan_fid_set), \ + SW_API_DEF(SW_API_VLAN_FID_GET, isis_vlan_fid_get), \ + SW_API_DEF(SW_API_VLAN_MEMBER_ADD, isis_vlan_member_add), \ + SW_API_DEF(SW_API_VLAN_MEMBER_DEL, isis_vlan_member_del), \ + SW_API_DEF(SW_API_VLAN_LEARN_STATE_SET, isis_vlan_learning_state_set), \ + SW_API_DEF(SW_API_VLAN_LEARN_STATE_GET, isis_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_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, isis_port_1qmode_get), \ + SW_API_DEF(SW_API_PT_ING_MODE_SET, isis_port_1qmode_set), \ + SW_API_DEF(SW_API_PT_EG_MODE_GET, isis_port_egvlanmode_get), \ + SW_API_DEF(SW_API_PT_EG_MODE_SET, isis_port_egvlanmode_set), \ + SW_API_DEF(SW_API_PT_VLAN_MEM_ADD, isis_portvlan_member_add), \ + SW_API_DEF(SW_API_PT_VLAN_MEM_DEL, isis_portvlan_member_del), \ + SW_API_DEF(SW_API_PT_VLAN_MEM_UPDATE, isis_portvlan_member_update), \ + SW_API_DEF(SW_API_PT_VLAN_MEM_GET, isis_portvlan_member_get), \ + SW_API_DEF(SW_API_PT_FORCE_DEF_VID_SET, isis_port_force_default_vid_set), \ + SW_API_DEF(SW_API_PT_FORCE_DEF_VID_GET, isis_port_force_default_vid_get), \ + SW_API_DEF(SW_API_PT_FORCE_PORTVLAN_SET, isis_port_force_portvlan_set), \ + SW_API_DEF(SW_API_PT_FORCE_PORTVLAN_GET, isis_port_force_portvlan_get), \ + SW_API_DEF(SW_API_NESTVLAN_TPID_SET, isis_nestvlan_tpid_set), \ + SW_API_DEF(SW_API_NESTVLAN_TPID_GET, isis_nestvlan_tpid_get), \ + SW_API_DEF(SW_API_PT_IN_VLAN_MODE_SET, isis_port_invlan_mode_set), \ + SW_API_DEF(SW_API_PT_IN_VLAN_MODE_GET, isis_port_invlan_mode_get), \ + SW_API_DEF(SW_API_PT_TLS_SET, isis_port_tls_set), \ + SW_API_DEF(SW_API_PT_TLS_GET, isis_port_tls_get), \ + SW_API_DEF(SW_API_PT_PRI_PROPAGATION_SET, isis_port_pri_propagation_set), \ + SW_API_DEF(SW_API_PT_PRI_PROPAGATION_GET, isis_port_pri_propagation_get), \ + SW_API_DEF(SW_API_PT_DEF_SVID_SET, isis_port_default_svid_set), \ + SW_API_DEF(SW_API_PT_DEF_SVID_GET, isis_port_default_svid_get), \ + SW_API_DEF(SW_API_PT_DEF_CVID_SET, isis_port_default_cvid_set), \ + SW_API_DEF(SW_API_PT_DEF_CVID_GET, isis_port_default_cvid_get), \ + SW_API_DEF(SW_API_PT_VLAN_PROPAGATION_SET, isis_port_vlan_propagation_set), \ + SW_API_DEF(SW_API_PT_VLAN_PROPAGATION_GET, isis_port_vlan_propagation_get), \ + SW_API_DEF(SW_API_PT_VLAN_TRANS_ADD, isis_port_vlan_trans_add), \ + SW_API_DEF(SW_API_PT_VLAN_TRANS_DEL, isis_port_vlan_trans_del), \ + SW_API_DEF(SW_API_PT_VLAN_TRANS_GET, isis_port_vlan_trans_get), \ + SW_API_DEF(SW_API_QINQ_MODE_SET, isis_qinq_mode_set), \ + SW_API_DEF(SW_API_QINQ_MODE_GET, isis_qinq_mode_get), \ + SW_API_DEF(SW_API_PT_QINQ_ROLE_SET, isis_port_qinq_role_set), \ + SW_API_DEF(SW_API_PT_QINQ_ROLE_GET, isis_port_qinq_role_get), \ + SW_API_DEF(SW_API_PT_VLAN_TRANS_ITERATE, isis_port_vlan_trans_iterate), \ + SW_API_DEF(SW_API_PT_MAC_VLAN_XLT_SET, isis_port_mac_vlan_xlt_set), \ + SW_API_DEF(SW_API_PT_MAC_VLAN_XLT_GET, isis_port_mac_vlan_xlt_get), + +#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_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_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) +#else +#define PORTVLAN_API +#define PORTVLAN_API_PARAM +#endif + +#ifdef IN_FDB +#define FDB_API \ + SW_API_DEF(SW_API_FDB_ADD, isis_fdb_add), \ + SW_API_DEF(SW_API_FDB_DELALL, isis_fdb_del_all), \ + SW_API_DEF(SW_API_FDB_DELPORT,isis_fdb_del_by_port), \ + SW_API_DEF(SW_API_FDB_DELMAC, isis_fdb_del_by_mac), \ + SW_API_DEF(SW_API_FDB_FIND, isis_fdb_find), \ + SW_API_DEF(SW_API_FDB_EXTEND_NEXT, isis_fdb_extend_next), \ + SW_API_DEF(SW_API_FDB_EXTEND_FIRST, isis_fdb_extend_first), \ + SW_API_DEF(SW_API_FDB_TRANSFER, isis_fdb_transfer), \ + SW_API_DEF(SW_API_FDB_PT_LEARN_SET, isis_fdb_port_learn_set), \ + SW_API_DEF(SW_API_FDB_PT_LEARN_GET, isis_fdb_port_learn_get), \ + SW_API_DEF(SW_API_FDB_AGE_CTRL_SET, isis_fdb_age_ctrl_set), \ + SW_API_DEF(SW_API_FDB_AGE_CTRL_GET, isis_fdb_age_ctrl_get), \ + SW_API_DEF(SW_API_FDB_AGE_TIME_SET, isis_fdb_age_time_set), \ + SW_API_DEF(SW_API_FDB_AGE_TIME_GET, isis_fdb_age_time_get), \ + SW_API_DEF(SW_API_PT_FDB_LEARN_LIMIT_SET, isis_port_fdb_learn_limit_set), \ + SW_API_DEF(SW_API_PT_FDB_LEARN_LIMIT_GET, isis_port_fdb_learn_limit_get), \ + SW_API_DEF(SW_API_PT_FDB_LEARN_EXCEED_CMD_SET, isis_port_fdb_learn_exceed_cmd_set), \ + SW_API_DEF(SW_API_PT_FDB_LEARN_EXCEED_CMD_GET, isis_port_fdb_learn_exceed_cmd_get), \ + SW_API_DEF(SW_API_FDB_LEARN_LIMIT_SET, isis_fdb_learn_limit_set), \ + SW_API_DEF(SW_API_FDB_LEARN_LIMIT_GET, isis_fdb_learn_limit_get), \ + SW_API_DEF(SW_API_FDB_LEARN_EXCEED_CMD_SET, isis_fdb_learn_exceed_cmd_set), \ + SW_API_DEF(SW_API_FDB_LEARN_EXCEED_CMD_GET, isis_fdb_learn_exceed_cmd_get), \ + SW_API_DEF(SW_API_FDB_RESV_ADD, isis_fdb_resv_add), \ + SW_API_DEF(SW_API_FDB_RESV_DEL, isis_fdb_resv_del), \ + SW_API_DEF(SW_API_FDB_RESV_FIND, isis_fdb_resv_find), \ + SW_API_DEF(SW_API_FDB_RESV_ITERATE, isis_fdb_resv_iterate), \ + SW_API_DEF(SW_API_FDB_EXTEND_FIRST, isis_fdb_extend_first), \ + SW_API_DEF(SW_API_FDB_PT_LEARN_STATIC_SET, isis_fdb_port_learn_static_set), \ + SW_API_DEF(SW_API_FDB_PT_LEARN_STATIC_GET, isis_fdb_port_learn_static_get), \ + SW_API_DEF(SW_API_FDB_PORT_ADD, isis_fdb_port_add), \ + SW_API_DEF(SW_API_FDB_PORT_DEL, isis_fdb_port_del), + +#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_FIND) \ + 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_FDB_PT_LEARN_SET) \ + SW_API_DESC(SW_API_FDB_PT_LEARN_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_AGE_TIME_SET) \ + SW_API_DESC(SW_API_FDB_AGE_TIME_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_EXTEND_FIRST) \ + 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) + +#else +#define FDB_API +#define FDB_API_PARAM +#endif + + +#ifdef IN_ACL +#define ACL_API \ + SW_API_DEF(SW_API_ACL_LIST_CREAT, isis_acl_list_creat), \ + SW_API_DEF(SW_API_ACL_LIST_DESTROY, isis_acl_list_destroy), \ + SW_API_DEF(SW_API_ACL_RULE_ADD, isis_acl_rule_add), \ + SW_API_DEF(SW_API_ACL_RULE_DELETE, isis_acl_rule_delete), \ + SW_API_DEF(SW_API_ACL_RULE_QUERY, isis_acl_rule_query), \ + SW_API_DEF(SW_API_ACL_LIST_BIND, isis_acl_list_bind), \ + SW_API_DEF(SW_API_ACL_LIST_UNBIND, isis_acl_list_unbind), \ + SW_API_DEF(SW_API_ACL_STATUS_SET, isis_acl_status_set), \ + SW_API_DEF(SW_API_ACL_STATUS_GET, isis_acl_status_get), \ + SW_API_DEF(SW_API_ACL_LIST_DUMP, isis_acl_list_dump), \ + SW_API_DEF(SW_API_ACL_RULE_DUMP, isis_acl_rule_dump), \ + SW_API_DEF(SW_API_ACL_PT_UDF_PROFILE_SET, isis_acl_port_udf_profile_set), \ + SW_API_DEF(SW_API_ACL_PT_UDF_PROFILE_GET, isis_acl_port_udf_profile_get), \ + SW_API_DEF(SW_API_ACL_RULE_ACTIVE, isis_acl_rule_active), \ + SW_API_DEF(SW_API_ACL_RULE_DEACTIVE, isis_acl_rule_deactive),\ + SW_API_DEF(SW_API_ACL_RULE_GET_OFFSET, isis_acl_rule_get_offset), + +#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) +#else +#define ACL_API +#define ACL_API_PARAM +#endif + + +#ifdef IN_QOS +#define QOS_API \ + SW_API_DEF(SW_API_QOS_QU_TX_BUF_ST_SET, isis_qos_queue_tx_buf_status_set), \ + SW_API_DEF(SW_API_QOS_QU_TX_BUF_ST_GET, isis_qos_queue_tx_buf_status_get), \ + SW_API_DEF(SW_API_QOS_QU_TX_BUF_NR_SET, isis_qos_queue_tx_buf_nr_set), \ + SW_API_DEF(SW_API_QOS_QU_TX_BUF_NR_GET, isis_qos_queue_tx_buf_nr_get), \ + SW_API_DEF(SW_API_QOS_PT_TX_BUF_ST_SET, isis_qos_port_tx_buf_status_set), \ + SW_API_DEF(SW_API_QOS_PT_TX_BUF_ST_GET, isis_qos_port_tx_buf_status_get), \ + SW_API_DEF(SW_API_QOS_PT_TX_BUF_NR_SET, isis_qos_port_tx_buf_nr_set), \ + SW_API_DEF(SW_API_QOS_PT_TX_BUF_NR_GET, isis_qos_port_tx_buf_nr_get), \ + SW_API_DEF(SW_API_QOS_PT_RX_BUF_NR_SET, isis_qos_port_rx_buf_nr_set), \ + SW_API_DEF(SW_API_QOS_PT_RX_BUF_NR_GET, isis_qos_port_rx_buf_nr_get), \ + SW_API_DEF(SW_API_QOS_PT_MODE_SET, isis_qos_port_mode_set), \ + SW_API_DEF(SW_API_QOS_PT_MODE_GET, isis_qos_port_mode_get), \ + SW_API_DEF(SW_API_QOS_PT_MODE_PRI_SET, isis_qos_port_mode_pri_set), \ + SW_API_DEF(SW_API_QOS_PT_MODE_PRI_GET, isis_qos_port_mode_pri_get), \ + SW_API_DEF(SW_API_QOS_PORT_SCH_MODE_SET, isis_qos_port_sch_mode_set), \ + SW_API_DEF(SW_API_QOS_PORT_SCH_MODE_GET, isis_qos_port_sch_mode_get), \ + SW_API_DEF(SW_API_QOS_PT_DEF_SPRI_SET, isis_qos_port_default_spri_set), \ + SW_API_DEF(SW_API_QOS_PT_DEF_SPRI_GET, isis_qos_port_default_spri_get), \ + SW_API_DEF(SW_API_QOS_PT_DEF_CPRI_SET, isis_qos_port_default_cpri_set), \ + SW_API_DEF(SW_API_QOS_PT_DEF_CPRI_GET, isis_qos_port_default_cpri_get), \ + SW_API_DEF(SW_API_QOS_QUEUE_REMARK_SET, isis_qos_queue_remark_table_set), \ + SW_API_DEF(SW_API_QOS_QUEUE_REMARK_GET, isis_qos_queue_remark_table_get), + + +#define QOS_API_PARAM \ + 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_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_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_QUEUE_REMARK_SET) \ + SW_API_DESC(SW_API_QOS_QUEUE_REMARK_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, isis_port_igmps_status_set), \ + SW_API_DEF(SW_API_PT_IGMPS_MODE_GET, isis_port_igmps_status_get), \ + SW_API_DEF(SW_API_IGMP_MLD_CMD_SET, isis_igmp_mld_cmd_set), \ + SW_API_DEF(SW_API_IGMP_MLD_CMD_GET, isis_igmp_mld_cmd_get), \ + SW_API_DEF(SW_API_IGMP_PT_JOIN_SET, isis_port_igmp_mld_join_set), \ + SW_API_DEF(SW_API_IGMP_PT_JOIN_GET, isis_port_igmp_mld_join_get), \ + SW_API_DEF(SW_API_IGMP_PT_LEAVE_SET, isis_port_igmp_mld_leave_set), \ + SW_API_DEF(SW_API_IGMP_PT_LEAVE_GET, isis_port_igmp_mld_leave_get), \ + SW_API_DEF(SW_API_IGMP_RP_SET, isis_igmp_mld_rp_set), \ + SW_API_DEF(SW_API_IGMP_RP_GET, isis_igmp_mld_rp_get), \ + SW_API_DEF(SW_API_IGMP_ENTRY_CREAT_SET, isis_igmp_mld_entry_creat_set), \ + SW_API_DEF(SW_API_IGMP_ENTRY_CREAT_GET, isis_igmp_mld_entry_creat_get), \ + SW_API_DEF(SW_API_IGMP_ENTRY_STATIC_SET, isis_igmp_mld_entry_static_set), \ + SW_API_DEF(SW_API_IGMP_ENTRY_STATIC_GET, isis_igmp_mld_entry_static_get), \ + SW_API_DEF(SW_API_IGMP_ENTRY_LEAKY_SET, isis_igmp_mld_entry_leaky_set), \ + SW_API_DEF(SW_API_IGMP_ENTRY_LEAKY_GET, isis_igmp_mld_entry_leaky_get), \ + SW_API_DEF(SW_API_IGMP_ENTRY_V3_SET, isis_igmp_mld_entry_v3_set), \ + SW_API_DEF(SW_API_IGMP_ENTRY_V3_GET, isis_igmp_mld_entry_v3_get), \ + SW_API_DEF(SW_API_IGMP_ENTRY_QUEUE_SET, isis_igmp_mld_entry_queue_set), \ + SW_API_DEF(SW_API_IGMP_ENTRY_QUEUE_GET, isis_igmp_mld_entry_queue_get), \ + SW_API_DEF(SW_API_PT_IGMP_LEARN_LIMIT_SET, isis_port_igmp_mld_learn_limit_set), \ + SW_API_DEF(SW_API_PT_IGMP_LEARN_LIMIT_GET, isis_port_igmp_mld_learn_limit_get), \ + SW_API_DEF(SW_API_PT_IGMP_LEARN_EXCEED_CMD_SET, isis_port_igmp_mld_learn_exceed_cmd_set), \ + SW_API_DEF(SW_API_PT_IGMP_LEARN_EXCEED_CMD_GET, isis_port_igmp_mld_learn_exceed_cmd_get), \ + SW_API_DEF(SW_API_IGMP_SG_ENTRY_SET, isis_igmp_sg_entry_set), \ + SW_API_DEF(SW_API_IGMP_SG_ENTRY_CLEAR, isis_igmp_sg_entry_clear), \ + SW_API_DEF(SW_API_IGMP_SG_ENTRY_SHOW, isis_igmp_sg_entry_show), + +#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) +#else +#define IGMP_API +#define IGMP_API_PARAM +#endif + + +#ifdef IN_LEAKY +#define LEAKY_API \ + SW_API_DEF(SW_API_UC_LEAKY_MODE_SET, isis_uc_leaky_mode_set), \ + SW_API_DEF(SW_API_UC_LEAKY_MODE_GET, isis_uc_leaky_mode_get), \ + SW_API_DEF(SW_API_MC_LEAKY_MODE_SET, isis_mc_leaky_mode_set), \ + SW_API_DEF(SW_API_MC_LEAKY_MODE_GET, isis_mc_leaky_mode_get), \ + SW_API_DEF(SW_API_ARP_LEAKY_MODE_SET, isis_port_arp_leaky_set), \ + SW_API_DEF(SW_API_ARP_LEAKY_MODE_GET, isis_port_arp_leaky_get), \ + SW_API_DEF(SW_API_PT_UC_LEAKY_MODE_SET, isis_port_uc_leaky_set), \ + SW_API_DEF(SW_API_PT_UC_LEAKY_MODE_GET, isis_port_uc_leaky_get), \ + SW_API_DEF(SW_API_PT_MC_LEAKY_MODE_SET, isis_port_mc_leaky_set), \ + SW_API_DEF(SW_API_PT_MC_LEAKY_MODE_GET, isis_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, isis_mirr_analysis_port_set), \ + SW_API_DEF(SW_API_MIRROR_ANALY_PT_GET, isis_mirr_analysis_port_get), \ + SW_API_DEF(SW_API_MIRROR_IN_PT_SET, isis_mirr_port_in_set), \ + SW_API_DEF(SW_API_MIRROR_IN_PT_GET, isis_mirr_port_in_get), \ + SW_API_DEF(SW_API_MIRROR_EG_PT_SET, isis_mirr_port_eg_set), \ + SW_API_DEF(SW_API_MIRROR_EG_PT_GET, isis_mirr_port_eg_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) +#else +#define MIRROR_API +#define MIRROR_API_PARAM +#endif + + +#ifdef IN_RATE +#define RATE_API \ + SW_API_DEF(SW_API_RATE_PORT_POLICER_SET, isis_rate_port_policer_set), \ + SW_API_DEF(SW_API_RATE_PORT_POLICER_GET, isis_rate_port_policer_get), \ + SW_API_DEF(SW_API_RATE_PORT_SHAPER_SET, isis_rate_port_shaper_set), \ + SW_API_DEF(SW_API_RATE_PORT_SHAPER_GET, isis_rate_port_shaper_get), \ + SW_API_DEF(SW_API_RATE_QUEUE_SHAPER_SET, isis_rate_queue_shaper_set), \ + SW_API_DEF(SW_API_RATE_QUEUE_SHAPER_GET, isis_rate_queue_shaper_get), \ + SW_API_DEF(SW_API_RATE_ACL_POLICER_SET, isis_rate_acl_policer_set), \ + SW_API_DEF(SW_API_RATE_ACL_POLICER_GET, isis_rate_acl_policer_get), \ + SW_API_DEF(SW_API_RATE_PT_ADDRATEBYTE_SET, isis_rate_port_add_rate_byte_set), \ + SW_API_DEF(SW_API_RATE_PT_ADDRATEBYTE_GET, isis_rate_port_add_rate_byte_get), + +#define RATE_API_PARAM \ + 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) +#else +#define RATE_API +#define RATE_API_PARAM +#endif + + +#ifdef IN_STP +#define STP_API \ + SW_API_DEF(SW_API_STP_PT_STATE_SET, isis_stp_port_state_set), \ + SW_API_DEF(SW_API_STP_PT_STATE_GET, isis_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, isis_get_mib_info), \ + SW_API_DEF(SW_API_MIB_STATUS_SET, isis_mib_status_set), \ + SW_API_DEF(SW_API_MIB_STATUS_GET, isis_mib_status_get), + +#define MIB_API_PARAM \ + SW_API_DESC(SW_API_PT_MIB_GET) \ + SW_API_DESC(SW_API_MIB_STATUS_SET) \ + SW_API_DESC(SW_API_MIB_STATUS_GET) +#else +#define MIB_API +#define MIB_API_PARAM +#endif + + +#ifdef IN_MISC +#define MISC_API \ + SW_API_DEF(SW_API_FRAME_MAX_SIZE_SET, isis_frame_max_size_set), \ + SW_API_DEF(SW_API_FRAME_MAX_SIZE_GET, isis_frame_max_size_get), \ + SW_API_DEF(SW_API_PT_UNK_UC_FILTER_SET, isis_port_unk_uc_filter_set), \ + SW_API_DEF(SW_API_PT_UNK_UC_FILTER_GET, isis_port_unk_uc_filter_get), \ + SW_API_DEF(SW_API_PT_UNK_MC_FILTER_SET, isis_port_unk_mc_filter_set), \ + SW_API_DEF(SW_API_PT_UNK_MC_FILTER_GET, isis_port_unk_mc_filter_get), \ + SW_API_DEF(SW_API_PT_BC_FILTER_SET, isis_port_bc_filter_set), \ + SW_API_DEF(SW_API_PT_BC_FILTER_GET, isis_port_bc_filter_get), \ + SW_API_DEF(SW_API_CPU_PORT_STATUS_SET, isis_cpu_port_status_set), \ + SW_API_DEF(SW_API_CPU_PORT_STATUS_GET, isis_cpu_port_status_get), \ + SW_API_DEF(SW_API_PPPOE_CMD_SET, isis_pppoe_cmd_set), \ + SW_API_DEF(SW_API_PPPOE_CMD_GET, isis_pppoe_cmd_get), \ + SW_API_DEF(SW_API_PPPOE_STATUS_SET, isis_pppoe_status_set), \ + SW_API_DEF(SW_API_PPPOE_STATUS_GET, isis_pppoe_status_get), \ + SW_API_DEF(SW_API_PT_DHCP_SET, isis_port_dhcp_set), \ + SW_API_DEF(SW_API_PT_DHCP_GET, isis_port_dhcp_get), \ + SW_API_DEF(SW_API_ARP_CMD_SET, isis_arp_cmd_set), \ + SW_API_DEF(SW_API_ARP_CMD_GET, isis_arp_cmd_get), \ + SW_API_DEF(SW_API_EAPOL_CMD_SET, isis_eapol_cmd_set), \ + SW_API_DEF(SW_API_EAPOL_CMD_GET, isis_eapol_cmd_get), \ + SW_API_DEF(SW_API_EAPOL_STATUS_SET, isis_eapol_status_set), \ + SW_API_DEF(SW_API_EAPOL_STATUS_GET, isis_eapol_status_get), \ + SW_API_DEF(SW_API_RIPV1_STATUS_SET, isis_ripv1_status_set), \ + SW_API_DEF(SW_API_RIPV1_STATUS_GET, isis_ripv1_status_get), \ + SW_API_DEF(SW_API_PT_ARP_REQ_STATUS_SET, isis_port_arp_req_status_set), \ + SW_API_DEF(SW_API_PT_ARP_REQ_STATUS_GET, isis_port_arp_req_status_get), \ + SW_API_DEF(SW_API_PT_ARP_ACK_STATUS_SET, isis_port_arp_ack_status_set), \ + SW_API_DEF(SW_API_PT_ARP_ACK_STATUS_GET, isis_port_arp_ack_status_get), \ + SW_API_DEF(SW_API_PPPOE_SESSION_TABLE_ADD, isis_pppoe_session_table_add), \ + SW_API_DEF(SW_API_PPPOE_SESSION_TABLE_DEL, isis_pppoe_session_table_del), \ + SW_API_DEF(SW_API_PPPOE_SESSION_TABLE_GET, isis_pppoe_session_table_get), \ + SW_API_DEF(SW_API_PPPOE_SESSION_ID_SET, isis_pppoe_session_id_set), \ + SW_API_DEF(SW_API_PPPOE_SESSION_ID_GET, isis_pppoe_session_id_get), \ + SW_API_DEF(SW_API_INTR_MASK_SET, isis_intr_mask_set), \ + SW_API_DEF(SW_API_INTR_MASK_GET, isis_intr_mask_get), \ + SW_API_DEF(SW_API_INTR_STATUS_GET, isis_intr_status_get), \ + SW_API_DEF(SW_API_INTR_STATUS_CLEAR, isis_intr_status_clear), \ + SW_API_DEF(SW_API_INTR_PORT_LINK_MASK_SET, isis_intr_port_link_mask_set), \ + SW_API_DEF(SW_API_INTR_PORT_LINK_MASK_GET, isis_intr_port_link_mask_get), \ + SW_API_DEF(SW_API_INTR_PORT_LINK_STATUS_GET, isis_intr_port_link_status_get), + +#define MISC_API_PARAM \ + 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_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_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_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_PPPOE_SESSION_ADD) \ + SW_API_DESC(SW_API_PPPOE_SESSION_DEL) \ + SW_API_DESC(SW_API_PPPOE_SESSION_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_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_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) +#else +#define MISC_API +#define MISC_API_PARAM +#endif + + +#ifdef IN_LED +#define LED_API \ + SW_API_DEF(SW_API_LED_PATTERN_SET, isis_led_ctrl_pattern_set), \ + SW_API_DEF(SW_API_LED_PATTERN_GET, isis_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, isis_cosmap_dscp_to_pri_set), \ + SW_API_DEF(SW_API_COSMAP_DSCP_TO_PRI_GET, isis_cosmap_dscp_to_pri_get), \ + SW_API_DEF(SW_API_COSMAP_DSCP_TO_DP_SET, isis_cosmap_dscp_to_dp_set), \ + SW_API_DEF(SW_API_COSMAP_DSCP_TO_DP_GET, isis_cosmap_dscp_to_dp_get), \ + SW_API_DEF(SW_API_COSMAP_UP_TO_PRI_SET, isis_cosmap_up_to_pri_set), \ + SW_API_DEF(SW_API_COSMAP_UP_TO_PRI_GET, isis_cosmap_up_to_pri_get), \ + SW_API_DEF(SW_API_COSMAP_UP_TO_DP_SET, isis_cosmap_up_to_dp_set), \ + SW_API_DEF(SW_API_COSMAP_UP_TO_DP_GET, isis_cosmap_up_to_dp_get), \ + SW_API_DEF(SW_API_COSMAP_PRI_TO_QU_SET, isis_cosmap_pri_to_queue_set), \ + SW_API_DEF(SW_API_COSMAP_PRI_TO_QU_GET, isis_cosmap_pri_to_queue_get), \ + SW_API_DEF(SW_API_COSMAP_PRI_TO_EHQU_SET, isis_cosmap_pri_to_ehqueue_set), \ + SW_API_DEF(SW_API_COSMAP_PRI_TO_EHQU_GET, isis_cosmap_pri_to_ehqueue_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) +#else +#define COSMAP_API +#define COSMAP_API_PARAM +#endif + +#ifdef IN_SEC +#define SEC_API \ + SW_API_DEF(SW_API_SEC_NORM_SET, isis_sec_norm_item_set), \ + SW_API_DEF(SW_API_SEC_NORM_GET, isis_sec_norm_item_get), + +#define SEC_API_PARAM \ + SW_API_DESC(SW_API_SEC_NORM_SET) \ + SW_API_DESC(SW_API_SEC_NORM_GET) +#else +#define SEC_API +#define SEC_API_PARAM +#endif + +#ifdef IN_IP +#define IP_API \ + SW_API_DEF(SW_API_IP_HOST_ADD, isis_ip_host_add), \ + SW_API_DEF(SW_API_IP_HOST_DEL, isis_ip_host_del), \ + SW_API_DEF(SW_API_IP_HOST_GET, isis_ip_host_get), \ + SW_API_DEF(SW_API_IP_HOST_NEXT, isis_ip_host_next), \ + SW_API_DEF(SW_API_IP_HOST_COUNTER_BIND, isis_ip_host_counter_bind), \ + SW_API_DEF(SW_API_IP_HOST_PPPOE_BIND, isis_ip_host_pppoe_bind), \ + SW_API_DEF(SW_API_IP_PT_ARP_LEARN_SET, isis_ip_pt_arp_learn_set), \ + SW_API_DEF(SW_API_IP_PT_ARP_LEARN_GET, isis_ip_pt_arp_learn_get), \ + SW_API_DEF(SW_API_IP_ARP_LEARN_SET, isis_ip_arp_learn_set), \ + SW_API_DEF(SW_API_IP_ARP_LEARN_GET, isis_ip_arp_learn_get), \ + SW_API_DEF(SW_API_IP_SOURCE_GUARD_SET, isis_ip_source_guard_set), \ + SW_API_DEF(SW_API_IP_SOURCE_GUARD_GET, isis_ip_source_guard_get), \ + SW_API_DEF(SW_API_IP_ARP_GUARD_SET, isis_ip_arp_guard_set), \ + SW_API_DEF(SW_API_IP_ARP_GUARD_GET, isis_ip_arp_guard_get), \ + SW_API_DEF(SW_API_IP_ROUTE_STATUS_SET, isis_ip_route_status_set), \ + SW_API_DEF(SW_API_IP_ROUTE_STATUS_GET, isis_ip_route_status_get), \ + SW_API_DEF(SW_API_IP_INTF_ENTRY_ADD, isis_ip_intf_entry_add), \ + SW_API_DEF(SW_API_IP_INTF_ENTRY_DEL, isis_ip_intf_entry_del), \ + SW_API_DEF(SW_API_IP_INTF_ENTRY_NEXT, isis_ip_intf_entry_next), \ + SW_API_DEF(SW_API_IP_UNK_SOURCE_CMD_SET, isis_ip_unk_source_cmd_set), \ + SW_API_DEF(SW_API_IP_UNK_SOURCE_CMD_GET, isis_ip_unk_source_cmd_get), \ + SW_API_DEF(SW_API_ARP_UNK_SOURCE_CMD_SET, isis_arp_unk_source_cmd_set), \ + SW_API_DEF(SW_API_ARP_UNK_SOURCE_CMD_GET, isis_arp_unk_source_cmd_get), \ + SW_API_DEF(SW_API_IP_AGE_TIME_SET, isis_ip_age_time_set), \ + SW_API_DEF(SW_API_IP_AGE_TIME_GET, isis_ip_age_time_get), \ + SW_API_DEF(SW_API_WCMP_HASH_MODE_SET, isis_ip_wcmp_hash_mode_set), \ + SW_API_DEF(SW_API_WCMP_HASH_MODE_GET, isis_ip_wcmp_hash_mode_get), + +#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) + +#else +#define IP_API +#define IP_API_PARAM +#endif + +#ifdef IN_NAT +#define NAT_API \ + SW_API_DEF(SW_API_NAT_ADD, isis_nat_add), \ + SW_API_DEF(SW_API_NAT_DEL, isis_nat_del), \ + SW_API_DEF(SW_API_NAT_GET, isis_nat_get), \ + SW_API_DEF(SW_API_NAT_NEXT, isis_nat_next), \ + SW_API_DEF(SW_API_NAT_COUNTER_BIND, isis_nat_counter_bind), \ + SW_API_DEF(SW_API_NAPT_ADD, isis_napt_add), \ + SW_API_DEF(SW_API_NAPT_DEL, isis_napt_del), \ + SW_API_DEF(SW_API_NAPT_GET, isis_napt_get), \ + SW_API_DEF(SW_API_NAPT_NEXT, isis_napt_next), \ + SW_API_DEF(SW_API_NAPT_COUNTER_BIND, isis_napt_counter_bind), \ + SW_API_DEF(SW_API_NAT_STATUS_SET, isis_nat_status_set), \ + SW_API_DEF(SW_API_NAT_STATUS_GET, isis_nat_status_get), \ + SW_API_DEF(SW_API_NAT_HASH_MODE_SET, isis_nat_hash_mode_set), \ + SW_API_DEF(SW_API_NAT_HASH_MODE_GET, isis_nat_hash_mode_get), \ + SW_API_DEF(SW_API_NAPT_STATUS_SET, isis_napt_status_set), \ + SW_API_DEF(SW_API_NAPT_STATUS_GET, isis_napt_status_get), \ + SW_API_DEF(SW_API_NAPT_MODE_SET, isis_napt_mode_set), \ + SW_API_DEF(SW_API_NAPT_MODE_GET, isis_napt_mode_get), \ + SW_API_DEF(SW_API_PRV_BASE_ADDR_SET, isis_nat_prv_base_addr_set), \ + SW_API_DEF(SW_API_PRV_BASE_ADDR_GET, isis_nat_prv_base_addr_get), \ + SW_API_DEF(SW_API_PRV_ADDR_MODE_SET, isis_nat_prv_addr_mode_set), \ + SW_API_DEF(SW_API_PRV_ADDR_MODE_GET, isis_nat_prv_addr_mode_get), \ + SW_API_DEF(SW_API_PUB_ADDR_ENTRY_ADD, isis_nat_pub_addr_add), \ + SW_API_DEF(SW_API_PUB_ADDR_ENTRY_DEL, isis_nat_pub_addr_del), \ + SW_API_DEF(SW_API_PUB_ADDR_ENTRY_NEXT, isis_nat_pub_addr_next), \ + SW_API_DEF(SW_API_NAT_UNK_SESSION_CMD_SET, isis_nat_unk_session_cmd_set), \ + SW_API_DEF(SW_API_NAT_UNK_SESSION_CMD_GET, isis_nat_unk_session_cmd_get), \ + SW_API_DEF(SW_API_NAT_GLOBAL_SET, isis_nat_global_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_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_NAT_GLOBAL_SET) +#else +#define NAT_API +#define NAT_API_PARAM +#endif + +#ifdef IN_TRUNK +#define TRUNK_API \ + SW_API_DEF(SW_API_TRUNK_GROUP_SET, isis_trunk_group_set), \ + SW_API_DEF(SW_API_TRUNK_GROUP_GET, isis_trunk_group_get), \ + SW_API_DEF(SW_API_TRUNK_HASH_SET, isis_trunk_hash_mode_set), \ + SW_API_DEF(SW_API_TRUNK_HASH_GET, isis_trunk_hash_mode_get), \ + SW_API_DEF(SW_API_TRUNK_MAN_SA_SET, isis_trunk_manipulate_sa_set), \ + SW_API_DEF(SW_API_TRUNK_MAN_SA_GET, isis_trunk_manipulate_sa_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) +#else +#define TRUNK_API +#define TRUNK_API_PARAM +#endif + +#ifdef IN_INTERFACECONTROL +#define INTERFACECTRL_API \ + SW_API_DEF(SW_API_MAC_MODE_SET, isis_interface_mac_mode_set), \ + SW_API_DEF(SW_API_MAC_MODE_GET, isis_interface_mac_mode_get), \ + SW_API_DEF(SW_API_PORT_3AZ_STATUS_SET, isis_port_3az_status_set), \ + SW_API_DEF(SW_API_PORT_3AZ_STATUS_GET, isis_port_3az_status_get), \ + SW_API_DEF(SW_API_PHY_MODE_SET, isis_interface_phy_mode_set), \ + SW_API_DEF(SW_API_PHY_MODE_GET, isis_interface_phy_mode_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) + +#else +#define INTERFACECTRL_API +#define INTERFACECTRL_API_PARAM +#endif + +#define REG_API \ + SW_API_DEF(SW_API_PHY_GET, isis_phy_get), \ + SW_API_DEF(SW_API_PHY_SET, isis_phy_set), \ + SW_API_DEF(SW_API_REG_GET, isis_reg_get), \ + SW_API_DEF(SW_API_REG_SET, isis_reg_set), \ + SW_API_DEF(SW_API_REG_FIELD_GET, isis_reg_field_get), \ + SW_API_DEF(SW_API_REG_FIELD_SET, isis_reg_field_set), \ + SW_API_DEF(SW_API_REG_DUMP, isis_regsiter_dump), \ + SW_API_DEF(SW_API_DBG_REG_DUMP, isis_debug_regsiter_dump), + +#define REG_API_PARAM \ + SW_API_DESC(SW_API_PHY_GET) \ + SW_API_DESC(SW_API_PHY_SET) \ + SW_API_DESC(SW_API_REG_GET) \ + SW_API_DESC(SW_API_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) + + +#define SSDK_API \ + SW_API_DEF(SW_API_SWITCH_RESET, isis_reset), \ + SW_API_DEF(SW_API_SSDK_CFG, hsl_ssdk_cfg), \ + PORTCONTROL_API \ + 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 \ + TRUNK_API \ + INTERFACECTRL_API \ + REG_API \ + SW_API_DEF(SW_API_MAX, NULL), + + +#define SSDK_PARAM \ + 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"), \ + MIB_API_PARAM \ + LEAKY_API_PARAM \ + MISC_API_PARAM \ + IGMP_API_PARAM \ + MIRROR_API_PARAM \ + PORTCONTROL_API_PARAM \ + 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 \ + TRUNK_API_PARAM \ + INTERFACECTRL_API_PARAM \ + REG_API_PARAM \ + SW_PARAM_DEF(SW_API_MAX, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), + +#if (defined(USER_MODE) && defined(KERNEL_MODULE)) +#undef SSDK_API +#undef SSDK_PARAM + +#define SSDK_API \ + REG_API \ + SW_API_DEF(SW_API_MAX, NULL), + +#define SSDK_PARAM \ + REG_API_PARAM \ + SW_PARAM_DEF(SW_API_MAX, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _ISIS_API_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_cosmap.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_cosmap.h new file mode 100755 index 000000000..c55ce7a73 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_cosmap.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 isis_cosmap ISIS_COSMAP + * @{ + */ +#ifndef _ISIS_COSMAP_H_ +#define _ISIS_COSMAP_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_cosmap.h" + + sw_error_t isis_cosmap_init(a_uint32_t dev_id); + +#ifdef IN_COSMAP +#define ISIS_COSMAP_INIT(rv, dev_id) \ + { \ + rv = isis_cosmap_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISIS_COSMAP_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + isis_cosmap_dscp_to_pri_set(a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t pri); + + HSL_LOCAL sw_error_t + isis_cosmap_dscp_to_pri_get(a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t * pri); + + HSL_LOCAL sw_error_t + isis_cosmap_dscp_to_dp_set(a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t dp); + + HSL_LOCAL sw_error_t + isis_cosmap_dscp_to_dp_get(a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t * dp); + + HSL_LOCAL sw_error_t + isis_cosmap_up_to_pri_set(a_uint32_t dev_id, a_uint32_t up, + a_uint32_t pri); + + HSL_LOCAL sw_error_t + isis_cosmap_up_to_pri_get(a_uint32_t dev_id, a_uint32_t up, + a_uint32_t * pri); + + HSL_LOCAL sw_error_t + isis_cosmap_up_to_dp_set(a_uint32_t dev_id, a_uint32_t up, + a_uint32_t dp); + + HSL_LOCAL sw_error_t + isis_cosmap_up_to_dp_get(a_uint32_t dev_id, a_uint32_t up, + a_uint32_t * dp); + + HSL_LOCAL sw_error_t + isis_cosmap_pri_to_queue_set(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t queue); + + HSL_LOCAL sw_error_t + isis_cosmap_pri_to_queue_get(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t * queue); + + HSL_LOCAL sw_error_t + isis_cosmap_pri_to_ehqueue_set(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t queue); + + HSL_LOCAL sw_error_t + isis_cosmap_pri_to_ehqueue_get(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t * queue); + + HSL_LOCAL sw_error_t + isis_cosmap_egress_remark_set(a_uint32_t dev_id, a_uint32_t tbl_id, + fal_egress_remark_table_t * tbl); + + HSL_LOCAL sw_error_t + isis_cosmap_egress_remark_get(a_uint32_t dev_id, a_uint32_t tbl_id, + fal_egress_remark_table_t * tbl); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISIS_COSMAP_H_ */ + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_fdb.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_fdb.h new file mode 100755 index 000000000..3399eea20 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_fdb.h @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 isis_fdb ISIS_FDB + * @{ + */ +#ifndef _ISIS_FDB_H_ +#define _ISIS_FDB_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_fdb.h" + + sw_error_t isis_fdb_init(a_uint32_t dev_id); + +#ifdef IN_FDB +#define ISIS_FDB_INIT(rv, dev_id) \ + { \ + rv = isis_fdb_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISIS_FDB_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + isis_fdb_add(a_uint32_t dev_id, const fal_fdb_entry_t * entry); + + HSL_LOCAL sw_error_t + isis_fdb_find(a_uint32_t dev_id, fal_fdb_entry_t * entry); + + HSL_LOCAL sw_error_t + isis_fdb_del_all(a_uint32_t dev_id, a_uint32_t flag); + + HSL_LOCAL sw_error_t + isis_fdb_del_by_port(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t flag); + + HSL_LOCAL sw_error_t + isis_fdb_del_by_mac(a_uint32_t dev_id, const fal_fdb_entry_t * entry); + + HSL_LOCAL sw_error_t + isis_fdb_extend_next(a_uint32_t dev_id, fal_fdb_op_t * op, + fal_fdb_entry_t * entry); + + HSL_LOCAL sw_error_t + isis_fdb_extend_first(a_uint32_t dev_id, fal_fdb_op_t * option, + fal_fdb_entry_t * entry); + + HSL_LOCAL sw_error_t + isis_fdb_transfer(a_uint32_t dev_id, fal_port_t old_port, + fal_port_t new_port, a_uint32_t fid, + fal_fdb_op_t * option); + + HSL_LOCAL sw_error_t + isis_fdb_port_learn_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + HSL_LOCAL sw_error_t + isis_fdb_port_learn_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + HSL_LOCAL sw_error_t + isis_fdb_age_ctrl_set(a_uint32_t dev_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + isis_fdb_age_ctrl_get(a_uint32_t dev_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + isis_fdb_age_time_set(a_uint32_t dev_id, a_uint32_t * time); + + HSL_LOCAL sw_error_t + isis_fdb_age_time_get(a_uint32_t dev_id, a_uint32_t * time); + + HSL_LOCAL sw_error_t + isis_port_fdb_learn_limit_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable, a_uint32_t cnt); + + HSL_LOCAL sw_error_t + isis_port_fdb_learn_limit_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable, a_uint32_t * cnt); + + HSL_LOCAL sw_error_t + isis_port_fdb_learn_exceed_cmd_set(a_uint32_t dev_id, + fal_port_t port_id, + fal_fwd_cmd_t cmd); + + HSL_LOCAL sw_error_t + isis_port_fdb_learn_exceed_cmd_get(a_uint32_t dev_id, + fal_port_t port_id, + fal_fwd_cmd_t * cmd); + + HSL_LOCAL sw_error_t + isis_fdb_learn_limit_set(a_uint32_t dev_id, a_bool_t enable, + a_uint32_t cnt); + + HSL_LOCAL sw_error_t + isis_fdb_learn_limit_get(a_uint32_t dev_id, a_bool_t * enable, + a_uint32_t * cnt); + + HSL_LOCAL sw_error_t + isis_fdb_learn_exceed_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + HSL_LOCAL sw_error_t + isis_fdb_learn_exceed_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + HSL_LOCAL sw_error_t + isis_fdb_resv_add(a_uint32_t dev_id, fal_fdb_entry_t * entry); + + HSL_LOCAL sw_error_t + isis_fdb_resv_del(a_uint32_t dev_id, fal_fdb_entry_t * entry); + + HSL_LOCAL sw_error_t + isis_fdb_resv_find(a_uint32_t dev_id, fal_fdb_entry_t * entry); + + HSL_LOCAL sw_error_t + isis_fdb_resv_iterate(a_uint32_t dev_id, a_uint32_t * iterator, + fal_fdb_entry_t * entry); + + HSL_LOCAL sw_error_t + isis_fdb_port_learn_static_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + HSL_LOCAL sw_error_t + isis_fdb_port_learn_static_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + HSL_LOCAL sw_error_t + isis_fdb_port_add(a_uint32_t dev_id, a_uint32_t fid, fal_mac_addr_t * addr, fal_port_t port_id); + + HSL_LOCAL sw_error_t + isis_fdb_port_del(a_uint32_t dev_id, a_uint32_t fid, fal_mac_addr_t * addr, fal_port_t port_id); + + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISIS_FDB_H_ */ + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_igmp.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_igmp.h new file mode 100755 index 000000000..db293786c --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_igmp.h @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 isis_igmp ISIS_IGMP + * @{ + */ +#ifndef _ISIS_IGMP_H_ +#define _ISIS_IGMP_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_igmp.h" +#include "fal/fal_multi.h" + + sw_error_t + isis_igmp_init(a_uint32_t dev_id); + +#ifdef IN_IGMP +#define ISIS_IGMP_INIT(rv, dev_id) \ + { \ + rv = isis_igmp_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISIS_IGMP_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + isis_port_igmps_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_port_igmps_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable); + + + HSL_LOCAL sw_error_t + isis_igmp_mld_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + + HSL_LOCAL sw_error_t + isis_igmp_mld_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + + HSL_LOCAL sw_error_t + isis_port_igmp_mld_join_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_port_igmp_mld_join_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isis_port_igmp_mld_leave_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_port_igmp_mld_leave_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isis_igmp_mld_rp_set(a_uint32_t dev_id, fal_pbmp_t pts); + + + HSL_LOCAL sw_error_t + isis_igmp_mld_rp_get(a_uint32_t dev_id, fal_pbmp_t * pts); + + + HSL_LOCAL sw_error_t + isis_igmp_mld_entry_creat_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_igmp_mld_entry_creat_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isis_igmp_mld_entry_static_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_igmp_mld_entry_static_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isis_igmp_mld_entry_leaky_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_igmp_mld_entry_leaky_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isis_igmp_mld_entry_v3_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_igmp_mld_entry_v3_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isis_igmp_mld_entry_queue_set(a_uint32_t dev_id, a_bool_t enable, a_uint32_t queue); + + + HSL_LOCAL sw_error_t + isis_igmp_mld_entry_queue_get(a_uint32_t dev_id, a_bool_t * enable, a_uint32_t * queue); + + + HSL_LOCAL sw_error_t + isis_port_igmp_mld_learn_limit_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable, a_uint32_t cnt); + + + HSL_LOCAL sw_error_t + isis_port_igmp_mld_learn_limit_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable, a_uint32_t * cnt); + + + HSL_LOCAL sw_error_t + isis_port_igmp_mld_learn_exceed_cmd_set(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t cmd); + + + HSL_LOCAL sw_error_t + isis_port_igmp_mld_learn_exceed_cmd_get(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t * cmd); + + HSL_LOCAL sw_error_t + isis_igmp_sg_entry_set(a_uint32_t dev_id, fal_igmp_sg_entry_t * entry); + + HSL_LOCAL sw_error_t + isis_igmp_sg_entry_clear(a_uint32_t dev_id, fal_igmp_sg_entry_t * entry); + + HSL_LOCAL sw_error_t + isis_igmp_sg_entry_show(a_uint32_t dev_id); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _ISIS_IGMP_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_init.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_init.h new file mode 100755 index 000000000..8c31c41a5 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_init.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 isis_init ISIS_INIT + * @{ + */ +#ifndef _ISIS_INIT_H_ +#define _ISIS_INIT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "init/ssdk_init.h" + + + sw_error_t + isis_init(a_uint32_t dev_id, ssdk_init_cfg *cfg); + + + sw_error_t + isis_cleanup(a_uint32_t dev_id); + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + isis_reset(a_uint32_t dev_id); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _ISIS_INIT_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_interface_ctrl.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_interface_ctrl.h new file mode 100755 index 000000000..c3618cc06 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_interface_ctrl.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISIS_INTERFACE_CTRL_H_ +#define _ISIS_INTERFACE_CTRL_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_interface_ctrl.h" + + sw_error_t isis_interface_ctrl_init(a_uint32_t dev_id); + +#ifdef IN_INTERFACECONTROL +#define ISIS_INTERFACE_CTRL_INIT(rv, dev_id) \ + { \ + rv = isis_interface_ctrl_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISIS_INTERFACE_CTRL_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + isis_port_3az_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + isis_port_3az_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + isis_interface_mac_mode_set(a_uint32_t dev_id, fal_port_t port_id, fal_mac_config_t * config); + + + HSL_LOCAL sw_error_t + isis_interface_mac_mode_get(a_uint32_t dev_id, fal_port_t port_id, fal_mac_config_t * config); + + HSL_LOCAL sw_error_t + isis_interface_phy_mode_set(a_uint32_t dev_id, a_uint32_t phy_id, fal_phy_config_t * config); + + HSL_LOCAL sw_error_t + isis_interface_phy_mode_get(a_uint32_t dev_id, a_uint32_t phy_id, fal_phy_config_t * config); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISIS_INTERFACE_CTRL_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_ip.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_ip.h new file mode 100755 index 000000000..409414d58 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_ip.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISIS_IP_H_ +#define _ISIS_IP_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_ip.h" + + sw_error_t isis_ip_init(a_uint32_t dev_id); + + sw_error_t isis_ip_reset(a_uint32_t dev_id); + +#ifdef IN_IP +#define ISIS_IP_INIT(rv, dev_id) \ + { \ + rv = isis_ip_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } + +#define ISIS_IP_RESET(rv, dev_id) \ + { \ + rv = isis_ip_reset(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISIS_IP_INIT(rv, dev_id) +#define ISIS_IP_RESET(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + isis_ip_host_add(a_uint32_t dev_id, fal_host_entry_t * host_entry); + + HSL_LOCAL sw_error_t + isis_ip_intf_entry_add(a_uint32_t dev_id, fal_intf_mac_entry_t * entry); + + HSL_LOCAL sw_error_t + isis_ip_host_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_host_entry_t * host_entry); + + HSL_LOCAL sw_error_t + isis_ip_host_get(a_uint32_t dev_id, a_uint32_t get_mode, + fal_host_entry_t * host_entry); + + HSL_LOCAL sw_error_t + isis_ip_host_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_host_entry_t * host_entry); + + HSL_LOCAL sw_error_t + isis_ip_host_counter_bind(a_uint32_t dev_id, a_uint32_t entry_id, + a_uint32_t cnt_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + isis_ip_host_pppoe_bind(a_uint32_t dev_id, a_uint32_t entry_id, + a_uint32_t pppoe_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + isis_ip_pt_arp_learn_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t flags); + + HSL_LOCAL sw_error_t + isis_ip_pt_arp_learn_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * flags); + + HSL_LOCAL sw_error_t + isis_ip_arp_learn_set(a_uint32_t dev_id, fal_arp_learn_mode_t mode); + + HSL_LOCAL sw_error_t + isis_ip_arp_learn_get(a_uint32_t dev_id, fal_arp_learn_mode_t * mode); + + HSL_LOCAL sw_error_t + isis_ip_source_guard_set(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t mode); + + HSL_LOCAL sw_error_t + isis_ip_source_guard_get(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t * mode); + + HSL_LOCAL sw_error_t + isis_ip_unk_source_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + HSL_LOCAL sw_error_t + isis_ip_unk_source_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + HSL_LOCAL sw_error_t + isis_ip_arp_guard_set(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t mode); + + HSL_LOCAL sw_error_t + isis_ip_arp_guard_get(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t * mode); + + HSL_LOCAL sw_error_t + isis_arp_unk_source_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + HSL_LOCAL sw_error_t + isis_arp_unk_source_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + HSL_LOCAL sw_error_t + isis_ip_route_status_set(a_uint32_t dev_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + isis_ip_route_status_get(a_uint32_t dev_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + isis_ip_intf_entry_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_intf_mac_entry_t * entry); + + HSL_LOCAL sw_error_t + isis_ip_intf_entry_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_intf_mac_entry_t * entry); + + HSL_LOCAL sw_error_t + isis_ip_age_time_set(a_uint32_t dev_id, a_uint32_t * time); + + HSL_LOCAL sw_error_t + isis_ip_age_time_get(a_uint32_t dev_id, a_uint32_t * time); + + HSL_LOCAL sw_error_t + isis_ip_wcmp_entry_set(a_uint32_t dev_id, a_uint32_t wcmp_id, fal_ip_wcmp_t * wcmp); + + HSL_LOCAL sw_error_t + isis_ip_wcmp_entry_get(a_uint32_t dev_id, a_uint32_t wcmp_id, fal_ip_wcmp_t * wcmp); + + HSL_LOCAL sw_error_t + isis_ip_wcmp_hash_mode_set(a_uint32_t dev_id, a_uint32_t hash_mode); + + HSL_LOCAL sw_error_t + isis_ip_wcmp_hash_mode_get(a_uint32_t dev_id, a_uint32_t * hash_mode); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISIS_IP_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_leaky.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_leaky.h new file mode 100755 index 000000000..02192aaa1 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_leaky.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISIS_LEAKY_H_ +#define _ISIS_LEAKY_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_leaky.h" + + sw_error_t isis_leaky_init(a_uint32_t dev_id); + +#ifdef IN_LEAKY +#define ISIS_LEAKY_INIT(rv, dev_id) \ + { \ + rv = isis_leaky_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISIS_LEAKY_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + isis_uc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode); + + + HSL_LOCAL sw_error_t + isis_uc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t * ctrl_mode); + + + HSL_LOCAL sw_error_t + isis_mc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode); + + + HSL_LOCAL sw_error_t + isis_mc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t * ctrl_mode); + + + HSL_LOCAL sw_error_t + isis_port_arp_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_port_arp_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isis_port_uc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_port_uc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isis_port_mc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_port_mc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISIS_LEAKY_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_led.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_led.h new file mode 100755 index 000000000..d11b29fbc --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_led.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISIS_LED_H_ +#define _ISIS_LED_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_led.h" + + sw_error_t + isis_led_init(a_uint32_t dev_id); + +#ifdef IN_LED +#define ISIS_LED_INIT(rv, dev_id) \ + { \ + rv = isis_led_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISIS_LED_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + isis_led_ctrl_pattern_set(a_uint32_t dev_id, led_pattern_group_t group, + led_pattern_id_t id, led_ctrl_pattern_t * pattern); + + + HSL_LOCAL sw_error_t + isis_led_ctrl_pattern_get(a_uint32_t dev_id, led_pattern_group_t group, + led_pattern_id_t id, led_ctrl_pattern_t * pattern); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _ISIS_LED_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_mib.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_mib.h new file mode 100755 index 000000000..b04389009 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_mib.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISIS_MIB_H_ +#define _ISIS_MIB_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_mib.h" + + sw_error_t + isis_mib_init(a_uint32_t dev_id); + +#ifdef IN_MIB +#define ISIS_MIB_INIT(rv, dev_id) \ + { \ + rv = isis_mib_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISIS_MIB_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + isis_get_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info ); + + + HSL_LOCAL sw_error_t + isis_mib_status_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_mib_status_get(a_uint32_t dev_id, a_bool_t * enable); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _ISIS_MIB_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_mirror.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_mirror.h new file mode 100755 index 000000000..793316812 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_mirror.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISIS_MIRROR_H_ +#define _ISIS_MIRROR_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_mirror.h" +#define MIRROR_ANALYZER_NONE 0xf + + sw_error_t isis_mirr_init(a_uint32_t dev_id); + +#ifdef IN_MIRROR +#define ISIS_MIRR_INIT(rv, dev_id) \ + { \ + rv = isis_mirr_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISIS_MIRR_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + isis_mirr_analysis_port_set(a_uint32_t dev_id, fal_port_t port_id); + + + HSL_LOCAL sw_error_t + isis_mirr_analysis_port_get(a_uint32_t dev_id, fal_port_t * port_id); + + + HSL_LOCAL sw_error_t + isis_mirr_port_in_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_mirr_port_in_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isis_mirr_port_eg_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_mirr_port_eg_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISIS_MIRROR_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_misc.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_misc.h new file mode 100755 index 000000000..c0a70f046 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_misc.h @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISIS_MISC_H_ +#define _ISIS_MISC_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_misc.h" + + sw_error_t isis_misc_init(a_uint32_t dev_id); + +#ifdef IN_MISC +#define ISIS_MISC_INIT(rv, dev_id) \ + { \ + rv = isis_misc_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISIS_MISC_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + isis_frame_max_size_set(a_uint32_t dev_id, a_uint32_t size); + + + HSL_LOCAL sw_error_t + isis_frame_max_size_get(a_uint32_t dev_id, a_uint32_t * size); + + + HSL_LOCAL sw_error_t + isis_port_unk_uc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_port_unk_uc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isis_port_unk_mc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_port_unk_mc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isis_port_bc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_port_bc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isis_cpu_port_status_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_cpu_port_status_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isis_pppoe_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + + HSL_LOCAL sw_error_t + isis_pppoe_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + + HSL_LOCAL sw_error_t + isis_pppoe_status_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_pppoe_status_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isis_port_dhcp_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_port_dhcp_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isis_arp_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + + HSL_LOCAL sw_error_t + isis_arp_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + + HSL_LOCAL sw_error_t + isis_eapol_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + + HSL_LOCAL sw_error_t + isis_eapol_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + + HSL_LOCAL sw_error_t + isis_pppoe_session_table_add(a_uint32_t dev_id, fal_pppoe_session_t * session_tbl); + + + HSL_LOCAL sw_error_t + isis_pppoe_session_table_del(a_uint32_t dev_id, fal_pppoe_session_t * session_tbl); + + + HSL_LOCAL sw_error_t + isis_pppoe_session_table_get(a_uint32_t dev_id, fal_pppoe_session_t * session_tbl); + + + HSL_LOCAL sw_error_t + isis_pppoe_session_id_set(a_uint32_t dev_id, a_uint32_t index, + a_uint32_t id); + + + HSL_LOCAL sw_error_t + isis_pppoe_session_id_get(a_uint32_t dev_id, a_uint32_t index, + a_uint32_t * id); + + + HSL_LOCAL sw_error_t + isis_eapol_status_set(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + isis_eapol_status_get(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + isis_ripv1_status_set(a_uint32_t dev_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + isis_ripv1_status_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isis_port_arp_req_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_port_arp_req_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable); + + + HSL_LOCAL sw_error_t + isis_port_arp_ack_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_port_arp_ack_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable); + + + HSL_LOCAL sw_error_t + isis_intr_mask_set(a_uint32_t dev_id, a_uint32_t intr_mask); + + + HSL_LOCAL sw_error_t + isis_intr_mask_get(a_uint32_t dev_id, a_uint32_t * intr_mask); + + + HSL_LOCAL sw_error_t + isis_intr_status_get(a_uint32_t dev_id, a_uint32_t * intr_status); + + + HSL_LOCAL sw_error_t + isis_intr_status_clear(a_uint32_t dev_id, a_uint32_t intr_status); + + + HSL_LOCAL sw_error_t + isis_intr_port_link_mask_set(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t intr_mask_flag); + + + HSL_LOCAL sw_error_t + isis_intr_port_link_mask_get(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t * intr_mask_flag); + + + HSL_LOCAL sw_error_t + isis_intr_port_link_status_get(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t * intr_mask_flag); + + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_nat.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_nat.h new file mode 100755 index 000000000..2dcb93c81 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_nat.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISIS_NAT_H_ +#define _ISIS_NAT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_nat.h" + + sw_error_t isis_nat_init(a_uint32_t dev_id); + + sw_error_t isis_nat_reset(a_uint32_t dev_id); + +#ifdef IN_NAT +#define ISIS_NAT_INIT(rv, dev_id) \ + { \ + rv = isis_nat_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } + +#define ISIS_NAT_RESET(rv, dev_id) \ + { \ + rv = isis_nat_reset(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISIS_NAT_INIT(rv, dev_id) +#define ISIS_NAT_RESET(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + isis_napt_add(a_uint32_t dev_id, fal_napt_entry_t * napt_entry); + + HSL_LOCAL sw_error_t + isis_nat_pub_addr_add(a_uint32_t dev_id, fal_nat_pub_addr_t * entry); + + HSL_LOCAL sw_error_t + isis_napt_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_napt_entry_t * napt_entry); + + HSL_LOCAL sw_error_t + isis_nat_prv_base_addr_set(a_uint32_t dev_id, fal_ip4_addr_t addr); + + HSL_LOCAL sw_error_t + isis_napt_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_napt_entry_t * napt_entry); + + HSL_LOCAL sw_error_t + isis_nat_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_nat_entry_t * nat_entry); + + HSL_LOCAL sw_error_t + isis_nat_pub_addr_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_nat_pub_addr_t * entry); + + HSL_LOCAL sw_error_t + isis_nat_add(a_uint32_t dev_id, fal_nat_entry_t * nat_entry); + + HSL_LOCAL sw_error_t + isis_nat_get(a_uint32_t dev_id, a_uint32_t get_mode, + fal_nat_entry_t * nat_entry); + + HSL_LOCAL sw_error_t + isis_nat_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_nat_entry_t * nat_entry); + + HSL_LOCAL sw_error_t + isis_nat_counter_bind(a_uint32_t dev_id, a_uint32_t entry_id, + a_uint32_t cnt_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + isis_napt_get(a_uint32_t dev_id, a_uint32_t get_mode, + fal_napt_entry_t * napt_entry); + + HSL_LOCAL sw_error_t + isis_napt_counter_bind(a_uint32_t dev_id, a_uint32_t entry_id, + a_uint32_t cnt_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + isis_nat_status_set(a_uint32_t dev_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + isis_nat_status_get(a_uint32_t dev_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + isis_nat_hash_mode_set(a_uint32_t dev_id, a_uint32_t mode); + + HSL_LOCAL sw_error_t + isis_nat_hash_mode_get(a_uint32_t dev_id, a_uint32_t * mode); + + HSL_LOCAL sw_error_t + isis_napt_status_set(a_uint32_t dev_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + isis_napt_status_get(a_uint32_t dev_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + isis_napt_mode_set(a_uint32_t dev_id, fal_napt_mode_t mode); + + HSL_LOCAL sw_error_t + isis_napt_mode_get(a_uint32_t dev_id, fal_napt_mode_t * mode); + + HSL_LOCAL sw_error_t + isis_nat_prv_base_addr_get(a_uint32_t dev_id, fal_ip4_addr_t * addr); + + HSL_LOCAL sw_error_t + isis_nat_prv_addr_mode_set(a_uint32_t dev_id, a_bool_t map_en); + + HSL_LOCAL sw_error_t + isis_nat_prv_addr_mode_get(a_uint32_t dev_id, a_bool_t * map_en); + + HSL_LOCAL sw_error_t + isis_nat_pub_addr_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_nat_pub_addr_t * entry); + + HSL_LOCAL sw_error_t + isis_nat_unk_session_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + HSL_LOCAL sw_error_t + isis_nat_unk_session_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + HSL_LOCAL sw_error_t + isis_nat_psr_prv_base_addr_set(a_uint32_t dev_id, fal_ip4_addr_t addr); + + HSL_LOCAL sw_error_t + isis_nat_psr_prv_base_addr_get(a_uint32_t dev_id, fal_ip4_addr_t * addr); + + HSL_LOCAL sw_error_t + isis_nat_global_set(a_uint32_t dev_id, a_bool_t enable); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISIS_NAT_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_nat_helper.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_nat_helper.h new file mode 100755 index 000000000..945079e19 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_nat_helper.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISIS_NAT_HELPER_H_ +#define _ISIS_NAT_HELPER_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_nat.h" + + sw_error_t nat_helper_init(a_uint32_t dev_id, a_uint32_t portbmp); + + sw_error_t nat_helper_cleanup(a_uint32_t dev_id); + +#ifdef IN_NAT_HELPER +#define ISIS_NAT_HELPER_INIT(rv, dev_id, portbmp) \ + { \ + rv = nat_helper_init(dev_id, portbmp); \ + SW_RTN_ON_ERROR(rv); \ + } + +#define ISIS_NAT_HELPER_CLEANUP(rv, dev_id) \ + { \ + rv = nat_helper_cleanup(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISIS_NAT_HELPER_INIT(rv, dev_id, portbmp) +#define ISIS_NAT_HELPER_CLEANUP(rv, dev_id) +#endif + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISIS_NAT_HELPER_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_port_ctrl.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_port_ctrl.h new file mode 100755 index 000000000..dd136d684 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_port_ctrl.h @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISIS_PORT_CTRL_H_ +#define _ISIS_PORT_CTRL_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_port_ctrl.h" + + sw_error_t isis_port_ctrl_init(a_uint32_t dev_id); + +#ifdef IN_PORTCONTROL +#define ISIS_PORT_CTRL_INIT(rv, dev_id) \ + { \ + rv = isis_port_ctrl_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISIS_PORT_CTRL_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + isis_port_duplex_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t duplex); + + + HSL_LOCAL sw_error_t + isis_port_duplex_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t * pduplex); + + + HSL_LOCAL sw_error_t + isis_port_speed_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t speed); + + + HSL_LOCAL sw_error_t + isis_port_speed_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t * pspeed); + + + HSL_LOCAL sw_error_t + isis_port_autoneg_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status); + + + HSL_LOCAL sw_error_t + isis_port_autoneg_enable(a_uint32_t dev_id, fal_port_t port_id); + + + HSL_LOCAL sw_error_t + isis_port_autoneg_restart(a_uint32_t dev_id, fal_port_t port_id); + + + HSL_LOCAL sw_error_t + isis_port_autoneg_adv_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t autoadv); + + + HSL_LOCAL sw_error_t + isis_port_autoneg_adv_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * autoadv); + + + HSL_LOCAL sw_error_t + isis_port_flowctrl_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_port_flowctrl_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isis_port_flowctrl_forcemode_set(a_uint32_t dev_id, + fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_port_flowctrl_forcemode_get(a_uint32_t dev_id, + fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isis_port_powersave_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_port_powersave_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable); + + + HSL_LOCAL sw_error_t + isis_port_hibernate_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_port_hibernate_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable); + + + HSL_LOCAL sw_error_t + isis_port_cdt(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t mdi_pair, + fal_cable_status_t *cable_status, a_uint32_t *cable_len); + + + HSL_LOCAL sw_error_t + isis_port_rxhdr_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t mode); + + + HSL_LOCAL sw_error_t + isis_port_rxhdr_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t * mode); + + + HSL_LOCAL sw_error_t + isis_port_txhdr_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t mode); + + + HSL_LOCAL sw_error_t + isis_port_txhdr_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t * mode); + + + HSL_LOCAL sw_error_t + isis_header_type_set(a_uint32_t dev_id, a_bool_t enable, a_uint32_t type); + + + HSL_LOCAL sw_error_t + isis_header_type_get(a_uint32_t dev_id, a_bool_t * enable, a_uint32_t * type); + + + HSL_LOCAL sw_error_t + isis_port_txmac_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_port_txmac_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isis_port_rxmac_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_port_rxmac_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isis_port_txfc_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_port_txfc_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isis_port_rxfc_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_port_rxfc_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isis_port_bp_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_port_bp_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isis_port_link_forcemode_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_port_link_forcemode_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isis_port_link_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * status); + + HSL_LOCAL sw_error_t + isis_port_mac_loopback_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_port_mac_loopback_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + isis_port_8023az_set (a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + isis_port_8023az_get (a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable); + + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISIS_PORT_CTRL_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_portvlan.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_portvlan.h new file mode 100755 index 000000000..a4ef074aa --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_portvlan.h @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISIS_PORTVLAN_H_ +#define _ISIS_PORTVLAN_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_portvlan.h" + + sw_error_t isis_portvlan_init(a_uint32_t dev_id); + +#ifdef IN_PORTVLAN +#define ISIS_PORTVLAN_INIT(rv, dev_id) \ + { \ + rv = isis_portvlan_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISIS_PORTVLAN_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + isis_port_1qmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t port_1qmode); + + + HSL_LOCAL sw_error_t + isis_port_1qmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t * pport_1qmode); + + + HSL_LOCAL sw_error_t + isis_port_egvlanmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t port_egvlanmode); + + + HSL_LOCAL sw_error_t + isis_port_egvlanmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t * pport_egvlanmode); + + + HSL_LOCAL sw_error_t + isis_portvlan_member_add(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id); + + + HSL_LOCAL sw_error_t + isis_portvlan_member_del(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id); + + + HSL_LOCAL sw_error_t + isis_portvlan_member_update(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t mem_port_map); + + + HSL_LOCAL sw_error_t + isis_portvlan_member_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t * mem_port_map); + + + HSL_LOCAL sw_error_t + isis_port_force_default_vid_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_port_force_default_vid_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isis_port_force_portvlan_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_port_force_portvlan_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isis_nestvlan_tpid_set(a_uint32_t dev_id, a_uint32_t tpid); + + + HSL_LOCAL sw_error_t + isis_nestvlan_tpid_get(a_uint32_t dev_id, a_uint32_t * tpid); + + + HSL_LOCAL sw_error_t + isis_port_invlan_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_invlan_mode_t mode); + + + HSL_LOCAL sw_error_t + isis_port_invlan_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_invlan_mode_t * mode); + + + HSL_LOCAL sw_error_t + isis_port_tls_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_port_tls_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isis_port_pri_propagation_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_port_pri_propagation_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isis_port_default_svid_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vid); + + + HSL_LOCAL sw_error_t + isis_port_default_svid_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vid); + + HSL_LOCAL sw_error_t + isis_port_default_cvid_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vid); + + + HSL_LOCAL sw_error_t + isis_port_default_cvid_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vid); + + + HSL_LOCAL sw_error_t + isis_port_vlan_propagation_set(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_propagation_mode_t mode); + + + HSL_LOCAL sw_error_t + isis_port_vlan_propagation_get(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_propagation_mode_t * mode); + + + HSL_LOCAL sw_error_t + isis_port_vlan_trans_add(a_uint32_t dev_id, fal_port_t port_id, fal_vlan_trans_entry_t *entry); + + + HSL_LOCAL sw_error_t + isis_port_vlan_trans_del(a_uint32_t dev_id, fal_port_t port_id, fal_vlan_trans_entry_t *entry); + + + HSL_LOCAL sw_error_t + isis_port_vlan_trans_get(a_uint32_t dev_id, fal_port_t port_id, fal_vlan_trans_entry_t *entry); + + + HSL_LOCAL sw_error_t + isis_qinq_mode_set(a_uint32_t dev_id, fal_qinq_mode_t mode); + + + HSL_LOCAL sw_error_t + isis_qinq_mode_get(a_uint32_t dev_id, fal_qinq_mode_t * mode); + + + HSL_LOCAL sw_error_t + isis_port_qinq_role_set(a_uint32_t dev_id, fal_port_t port_id, fal_qinq_port_role_t role); + + + HSL_LOCAL sw_error_t + isis_port_qinq_role_get(a_uint32_t dev_id, fal_port_t port_id, fal_qinq_port_role_t * role); + + + HSL_LOCAL sw_error_t + isis_port_vlan_trans_iterate(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * iterator, fal_vlan_trans_entry_t * entry); + + + HSL_LOCAL sw_error_t + isis_port_mac_vlan_xlt_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_port_mac_vlan_xlt_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + HSL_LOCAL sw_error_t + isis_port_route_defv_set(a_uint32_t dev_id, fal_port_t port_id); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISIS_PORTVLAN_H */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_qos.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_qos.h new file mode 100755 index 000000000..58c022a91 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_qos.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISIS_QOS_H_ +#define _ISIS_QOS_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_qos.h" + + sw_error_t isis_qos_init(a_uint32_t dev_id); + +#ifdef IN_QOS +#define ISIS_QOS_INIT(rv, dev_id) \ + { \ + rv = isis_qos_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISIS_QOS_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + isis_qos_queue_tx_buf_status_set(a_uint32_t dev_id, + fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_qos_queue_tx_buf_status_get(a_uint32_t dev_id, + fal_port_t port_id, + a_bool_t * enable); + + HSL_LOCAL sw_error_t + isis_qos_port_tx_buf_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_qos_port_tx_buf_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isis_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); + + + HSL_LOCAL sw_error_t + isis_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); + + + HSL_LOCAL sw_error_t + isis_qos_port_tx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number); + + + HSL_LOCAL sw_error_t + isis_qos_port_tx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number); + + + HSL_LOCAL sw_error_t + isis_qos_port_rx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number); + + + HSL_LOCAL sw_error_t + isis_qos_port_rx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number); + + + HSL_LOCAL sw_error_t + isis_qos_port_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_qos_port_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isis_qos_port_mode_pri_set(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_uint32_t pri); + + + HSL_LOCAL sw_error_t + isis_qos_port_mode_pri_get(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_uint32_t * pri); + + + HSL_LOCAL sw_error_t + isis_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[]); + + + HSL_LOCAL sw_error_t + isis_qos_port_sch_mode_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_sch_mode_t * mode, a_uint32_t weight[]); + + HSL_LOCAL sw_error_t + isis_qos_port_default_spri_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t spri); + + + HSL_LOCAL sw_error_t + isis_qos_port_default_spri_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * spri); + + + HSL_LOCAL sw_error_t + isis_qos_port_default_cpri_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t cpri); + + + HSL_LOCAL sw_error_t + isis_qos_port_default_cpri_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * cpri); + + + HSL_LOCAL sw_error_t + isis_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); + + + HSL_LOCAL sw_error_t + isis_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); + + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISIS_QOS_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_rate.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_rate.h new file mode 100755 index 000000000..375e1fab5 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_rate.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISIS_RATE_H_ +#define _ISIS_RATE_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_rate.h" + + sw_error_t isis_rate_init(a_uint32_t dev_id); + +#ifdef IN_RATE +#define ISIS_RATE_INIT(rv, dev_id) \ + { \ + rv = isis_rate_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISIS_RATE_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + isis_rate_port_policer_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_policer_t * policer); + + HSL_LOCAL sw_error_t + isis_rate_port_policer_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_policer_t * policer); + + HSL_LOCAL sw_error_t + isis_rate_port_shaper_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable, + fal_egress_shaper_t * shaper); + + HSL_LOCAL sw_error_t + isis_rate_port_shaper_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable, + fal_egress_shaper_t * shaper); + + HSL_LOCAL sw_error_t + isis_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); + + HSL_LOCAL sw_error_t + isis_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); + + HSL_LOCAL sw_error_t + isis_rate_acl_policer_set(a_uint32_t dev_id, a_uint32_t policer_id, + fal_acl_policer_t * policer); + + HSL_LOCAL sw_error_t + isis_rate_acl_policer_get(a_uint32_t dev_id, a_uint32_t policer_id, + fal_acl_policer_t * policer); + + HSL_LOCAL sw_error_t + isis_rate_port_add_rate_byte_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t number); + + HSL_LOCAL sw_error_t + isis_rate_port_add_rate_byte_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t *number); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISIS_RATE_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_reg.h new file mode 100755 index 000000000..d45975b45 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_reg.h @@ -0,0 +1,5229 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISIS_REG_H_ +#define _ISIS_REG_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define S16E_DEVICE_ID 0x11 +#define S17_DEVICE_ID 0x12 +#define S17_REVISION_A 0x01 + +#define MAX_ENTRY_LEN 128 + +#define HSL_RW 1 +#define HSL_RO 0 + + + /* ISIS Mask Control Register */ +#define MASK_CTL +#define MASK_CTL_ID 0 +#define MASK_CTL_OFFSET 0x0000 +#define MASK_CTL_E_LENGTH 4 +#define MASK_CTL_E_OFFSET 0 +#define MASK_CTL_NR_E 1 + +#define SOFT_RST +#define MASK_CTL_SOFT_RST_BOFFSET 31 +#define MASK_CTL_SOFT_RST_BLEN 1 +#define MASK_CTL_SOFT_RST_FLAG HSL_RW + +#define LOAD_EEPROM +#define MASK_CTL_LOAD_EEPROM_BOFFSET 16 +#define MASK_CTL_LOAD_EEPROM_BLEN 1 +#define MASK_CTL_LOAD_EEPROM_FLAG HSL_RW + +#define DEVICE_ID +#define MASK_CTL_DEVICE_ID_BOFFSET 8 +#define MASK_CTL_DEVICE_ID_BLEN 8 +#define MASK_CTL_DEVICE_ID_FLAG HSL_RO + +#define REV_ID +#define MASK_CTL_REV_ID_BOFFSET 0 +#define MASK_CTL_REV_ID_BLEN 8 +#define MASK_CTL_REV_ID_FLAG HSL_RO + + + + + /* Port0 Pad Control Register */ +#define PORT0_PAD_CTRL +#define PORT0_PAD_CTRL_ID 0 +#define PORT0_PAD_CTRL_OFFSET 0x0004 +#define PORT0_PAD_CTRL_E_LENGTH 4 +#define PORT0_PAD_CTRL_E_OFFSET 0 +#define PORT0_PAD_CTRL_NR_E 1 + +#define MAC0_RGMII_EN +#define PORT0_PAD_CTRL_MAC0_RGMII_EN_BOFFSET 26 +#define PORT0_PAD_CTRL_MAC0_RGMII_EN_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_RGMII_EN_FLAG HSL_RW + +#define MAC0_RGMII_TXCLK_DELAY_EN +#define PORT0_PAD_CTRL_MAC0_RGMII_TXCLK_DELAY_EN_BOFFSET 25 +#define PORT0_PAD_CTRL_MAC0_RGMII_TXCLK_DELAY_EN_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_RGMII_TXCLK_DELAY_EN_FLAG HSL_RW + +#define MAC0_RGMII_RXCLK_DELAY_EN +#define PORT0_PAD_CTRL_MAC0_RGMII_RXCLK_DELAY_EN_BOFFSET 24 +#define PORT0_PAD_CTRL_MAC0_RGMII_RXCLK_DELAY_EN_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_RGMII_RXCLK_DELAY_EN_FLAG HSL_RW + +#define MAC0_RGMII_TXCLK_DELAY_SEL +#define PORT0_PAD_CTRL_MAC0_RGMII_TXCLK_DELAY_SEL_BOFFSET 22 +#define PORT0_PAD_CTRL_MAC0_RGMII_TXCLK_DELAY_SEL_BLEN 2 +#define PORT0_PAD_CTRL_MAC0_RGMII_TXCLK_DELAY_SEL_FLAG HSL_RW + +#define MAC0_RGMII_RXCLK_DELAY_SEL +#define PORT0_PAD_CTRL_MAC0_RGMII_RXCLK_DELAY_SEL_BOFFSET 20 +#define PORT0_PAD_CTRL_MAC0_RGMII_RXCLK_DELAY_SEL_BLEN 2 +#define PORT0_PAD_CTRL_MAC0_RGMII_RXCLK_DELAY_SEL_FLAG HSL_RW + +#define SGMII_CLK125M_RX_SEL +#define PORT0_PAD_CTRL_SGMII_CLK125M_RX_SEL_BOFFSET 19 +#define PORT0_PAD_CTRL_SGMII_CLK125M_RX_SEL_BLEN 1 +#define PORT0_PAD_CTRL_SGMII_CLK125M_RX_SEL_FLAG HSL_RW + +#define SGMII_CLK125M_TX_SEL +#define PORT0_PAD_CTRL_SGMII_CLK125M_TX_SEL_BOFFSET 18 +#define PORT0_PAD_CTRL_SGMII_CLK125M_TX_SEL_BLEN 1 +#define PORT0_PAD_CTRL_SGMII_CLK125M_TX_SEL_FLAG HSL_RW + +#define MAC0_PHY_GMII_EN +#define PORT0_PAD_CTRL_MAC0_PHY_GMII_EN_BOFFSET 14 +#define PORT0_PAD_CTRL_MAC0_PHY_GMII_EN_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_PHY_GMII_EN_FLAG HSL_RW + +#define MAC0_PHY_GMII_TXCLK_SEL +#define PORT0_PAD_CTRL_MAC0_PHY_GMII_TXCLK_SEL_BOFFSET 13 +#define PORT0_PAD_CTRL_MAC0_PHY_GMII_TXCLK_SEL_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_PHY_GMII_TXCLK_SEL_FLAG HSL_RW + +#define MAC0_PHY_GMII_RXCLK_SEL +#define PORT0_PAD_CTRL_MAC0_PHY_GMII_RXCLK_SEL_BOFFSET 12 +#define PORT0_PAD_CTRL_MAC0_PHY_GMII_RXCLK_SEL_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_PHY_GMII_RXCLK_SEL_FLAG HSL_RW + +#define MAC0_PHY_MII_PIPE_RXCLK_SEL +#define PORT0_PAD_CTRL_MAC0_PHY_MII_PIPE_RXCLK_SEL_BOFFSET 11 +#define PORT0_PAD_CTRL_MAC0_PHY_MII_PIPE_RXCLK_SEL_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_PHY_MII_PIPE_RXCLK_SEL_FLAG HSL_RW + +#define MAC0_PHY_MII_EN +#define PORT0_PAD_CTRL_MAC0_PHY_MII_EN_BOFFSET 10 +#define PORT0_PAD_CTRL_MAC0_PHY_MII_EN_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_PHY_MII_EN_FLAG HSL_RW + +#define MAC0_PHY_MII_TXCLK_SEL +#define PORT0_PAD_CTRL_MAC0_PHY_MII_TXCLK_SEL_BOFFSET 9 +#define PORT0_PAD_CTRL_MAC0_PHY_MII_TXCLK_SEL_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_PHY_MII_TXCLK_SEL_FLAG HSL_RW + +#define MAC0_PHY_MII_RXCLK_SEL +#define PORT0_PAD_CTRL_MAC0_PHY_MII_RXCLK_SEL_BOFFSET 8 +#define PORT0_PAD_CTRL_MAC0_PHY_MII_RXCLK_SEL_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_PHY_MII_RXCLK_SEL_FLAG HSL_RW + +#define MAC0_SGMII_EN +#define PORT0_PAD_CTRL_MAC0_SGMII_EN_BOFFSET 7 +#define PORT0_PAD_CTRL_MAC0_SGMII_EN_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_SGMII_EN_FLAG HSL_RW + +#define MAC0_MAC_GMII_EN +#define PORT0_PAD_CTRL_MAC0_MAC_GMII_EN_BOFFSET 6 +#define PORT0_PAD_CTRL_MAC0_MAC_GMII_EN_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_MAC_GMII_EN_FLAG HSL_RW + +#define MAC0_MAC_GMII_TXCLK_SEL +#define PORT0_PAD_CTRL_MAC0_MAC_GMII_TXCLK_SEL_BOFFSET 5 +#define PORT0_PAD_CTRL_MAC0_MAC_GMII_TXCLK_SEL_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_MAC_GMII_TXCLK_SEL_FLAG HSL_RW + +#define MAC0_MAC_GMII_RXCLK_SEL +#define PORT0_PAD_CTRL_MAC0_MAC_GMII_RXCLK_SEL_BOFFSET 4 +#define PORT0_PAD_CTRL_MAC0_MAC_GMII_RXCLK_SEL_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_MAC_GMII_RXCLK_SEL_FLAG HSL_RW + +#define MAC0_MAC_MII_EN +#define PORT0_PAD_CTRL_MAC0_MAC_MII_EN_BOFFSET 2 +#define PORT0_PAD_CTRL_MAC0_MAC_MII_EN_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_MAC_MII_EN_FLAG HSL_RW + +#define MAC0_MAC_MII_TXCLK_SEL +#define PORT0_PAD_CTRL_MAC0_MAC_MII_TXCLK_SEL_BOFFSET 1 +#define PORT0_PAD_CTRL_MAC0_MAC_MII_TXCLK_SEL_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_MAC_MII_TXCLK_SEL_FLAG HSL_RW + +#define MAC0_MAC_MII_RXCLK_SEL +#define PORT0_PAD_CTRL_MAC0_MAC_MII_RXCLK_SEL_BOFFSET 0 +#define PORT0_PAD_CTRL_MAC0_MAC_MII_RXCLK_SEL_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_MAC_MII_RXCLK_SEL_FLAG HSL_RW + + + + + /* Port5 Pad Control Register */ +#define PORT5_PAD_CTRL +#define PORT5_PAD_CTRL_ID 0 +#define PORT5_PAD_CTRL_OFFSET 0x0008 +#define PORT5_PAD_CTRL_E_LENGTH 4 +#define PORT5_PAD_CTRL_E_OFFSET 0 +#define PORT5_PAD_CTRL_NR_E 1 + +#define MAC5_RGMII_EN +#define PORT5_PAD_CTRL_MAC5_RGMII_EN_BOFFSET 26 +#define PORT5_PAD_CTRL_MAC5_RGMII_EN_BLEN 1 +#define PORT5_PAD_CTRL_MAC5_RGMII_EN_FLAG HSL_RW + +#define MAC5_RGMII_TXCLK_DELAY_EN +#define PORT5_PAD_CTRL_MAC5_RGMII_TXCLK_DELAY_EN_BOFFSET 25 +#define PORT5_PAD_CTRL_MAC5_RGMII_TXCLK_DELAY_EN_BLEN 1 +#define PORT5_PAD_CTRL_MAC5_RGMII_TXCLK_DELAY_EN_FLAG HSL_RW + +#define MAC5_RGMII_RXCLK_DELAY_EN +#define PORT5_PAD_CTRL_MAC5_RGMII_RXCLK_DELAY_EN_BOFFSET 24 +#define PORT5_PAD_CTRL_MAC5_RGMII_RXCLK_DELAY_EN_BLEN 1 +#define PORT5_PAD_CTRL_MAC5_RGMII_RXCLK_DELAY_EN_FLAG HSL_RW + +#define MAC5_RGMII_TXCLK_DELAY_SEL +#define PORT5_PAD_CTRL_MAC5_RGMII_TXCLK_DELAY_SEL_BOFFSET 22 +#define PORT5_PAD_CTRL_MAC5_RGMII_TXCLK_DELAY_SEL_BLEN 2 +#define PORT5_PAD_CTRL_MAC5_RGMII_TXCLK_DELAY_SEL_FLAG HSL_RW + +#define MAC5_RGMII_RXCLK_DELAY_SEL +#define PORT5_PAD_CTRL_MAC5_RGMII_RXCLK_DELAY_SEL_BOFFSET 20 +#define PORT5_PAD_CTRL_MAC5_RGMII_RXCLK_DELAY_SEL_BLEN 2 +#define PORT5_PAD_CTRL_MAC5_RGMII_RXCLK_DELAY_SEL_FLAG HSL_RW + +#define MAC5_PHY_MII_PIPE_RXCLK_SEL +#define PORT5_PAD_CTRL_MAC5_PHY_MII_PIPE_RXCLK_SEL_BOFFSET 11 +#define PORT5_PAD_CTRL_MAC5_PHY_MII_PIPE_RXCLK_SEL_BLEN 1 +#define PORT5_PAD_CTRL_MAC5_PHY_MII_PIPE_RXCLK_SEL_FLAG HSL_RW + +#define MAC5_PHY_MII_EN +#define PORT5_PAD_CTRL_MAC5_PHY_MII_EN_BOFFSET 10 +#define PORT5_PAD_CTRL_MAC5_PHY_MII_EN_BLEN 1 +#define PORT5_PAD_CTRL_MAC5_PHY_MII_EN_FLAG HSL_RW + +#define MAC5_PHY_MII_TXCLK_SEL +#define PORT5_PAD_CTRL_MAC5_PHY_MII_TXCLK_SEL_BOFFSET 9 +#define PORT5_PAD_CTRL_MAC5_PHY_MII_TXCLK_SEL_BLEN 1 +#define PORT5_PAD_CTRL_MAC5_PHY_MII_TXCLK_SEL_FLAG HSL_RW + +#define MAC5_PHY_MII_RXCLK_SEL +#define PORT5_PAD_CTRL_MAC5_PHY_MII_RXCLK_SEL_BOFFSET 8 +#define PORT5_PAD_CTRL_MAC5_PHY_MII_RXCLK_SEL_BLEN 1 +#define PORT5_PAD_CTRL_MAC5_PHY_MII_RXCLK_SEL_FLAG HSL_RW + +#define MAC5_MAC_MII_EN +#define PORT5_PAD_CTRL_MAC5_MAC_MII_EN_BOFFSET 2 +#define PORT5_PAD_CTRL_MAC5_MAC_MII_EN_BLEN 1 +#define PORT5_PAD_CTRL_MAC5_MAC_MII_EN_FLAG HSL_RW + +#define MAC5_MAC_MII_TXCLK_SEL +#define PORT5_PAD_CTRL_MAC0_MAC_MII_TXCLK_SEL_BOFFSET 1 +#define PORT5_PAD_CTRL_MAC0_MAC_MII_TXCLK_SEL_BLEN 1 +#define PORT5_PAD_CTRL_MAC0_MAC_MII_TXCLK_SEL_FLAG HSL_RW + +#define MAC5_MAC_MII_RXCLK_SEL +#define PORT5_PAD_CTRL_MAC5_MAC_MII_RXCLK_SEL_BOFFSET 0 +#define PORT5_PAD_CTRL_MAC5_MAC_MII_RXCLK_SEL_BLEN 1 +#define PORT5_PAD_CTRL_MAC5_MAC_MII_RXCLK_SEL_FLAG HSL_RW + + + + + /* Port6 Pad Control Register */ +#define PORT6_PAD_CTRL +#define PORT6_PAD_CTRL_ID 0 +#define PORT6_PAD_CTRL_OFFSET 0x000c +#define PORT6_PAD_CTRL_E_LENGTH 4 +#define PORT6_PAD_CTRL_E_OFFSET 0 +#define PORT6_PAD_CTRL_NR_E 1 + +#define MAC6_RGMII_EN +#define PORT6_PAD_CTRL_MAC6_RGMII_EN_BOFFSET 26 +#define PORT6_PAD_CTRL_MAC6_RGMII_EN_BLEN 1 +#define PORT6_PAD_CTRL_MAC6_RGMII_EN_FLAG HSL_RW + +#define MAC6_RGMII_TXCLK_DELAY_EN +#define PORT6_PAD_CTRL_MAC6_RGMII_TXCLK_DELAY_EN_BOFFSET 25 +#define PORT6_PAD_CTRL_MAC6_RGMII_TXCLK_DELAY_EN_BLEN 1 +#define PORT6_PAD_CTRL_MAC6_RGMII_TXCLK_DELAY_EN_FLAG HSL_RW + +#define MAC6_RGMII_RXCLK_DELAY_EN +#define PORT6_PAD_CTRL_MAC6_RGMII_RXCLK_DELAY_EN_BOFFSET 24 +#define PORT6_PAD_CTRL_MAC6_RGMII_RXCLK_DELAY_EN_BLEN 1 +#define PORT6_PAD_CTRL_MAC6_RGMII_RXCLK_DELAY_EN_FLAG HSL_RW + +#define MAC6_RGMII_TXCLK_DELAY_SEL +#define PORT6_PAD_CTRL_MAC6_RGMII_TXCLK_DELAY_SEL_BOFFSET 22 +#define PORT6_PAD_CTRL_MAC6_RGMII_TXCLK_DELAY_SEL_BLEN 2 +#define PORT6_PAD_CTRL_MAC6_RGMII_TXCLK_DELAY_SEL_FLAG HSL_RW + +#define MAC6_RGMII_RXCLK_DELAY_SEL +#define PORT6_PAD_CTRL_MAC6_RGMII_RXCLK_DELAY_SEL_BOFFSET 20 +#define PORT6_PAD_CTRL_MAC6_RGMII_RXCLK_DELAY_SEL_BLEN 2 +#define PORT6_PAD_CTRL_MAC6_RGMII_RXCLK_DELAY_SEL_FLAG HSL_RW + +#define PHY4_MII_EN +#define PORT6_PAD_CTRL_PHY4_MII_EN_BOFFSET 18 +#define PORT6_PAD_CTRL_PHY4_MII_EN_BLEN 1 +#define PORT6_PAD_CTRL_PHY4_MII_EN_FLAG HSL_RW + +#define PHY4_RGMII_EN +#define PORT6_PAD_CTRL_PHY4_RGMII_EN_BOFFSET 17 +#define PORT6_PAD_CTRL_PHY4_RGMII_EN_BLEN 1 +#define PORT6_PAD_CTRL_PHY4_RGMII_EN_FLAG HSL_RW + +#define PHY4_GMII_EN +#define PORT6_PAD_CTRL_PHY4_GMII_EN_BOFFSET 16 +#define PORT6_PAD_CTRL_PHY4_GMII_EN_BLEN 1 +#define PORT6_PAD_CTRL_PHY4_GMII_EN_FLAG HSL_RW + +#define MAC6_PHY_GMII_EN +#define PORT6_PAD_CTRL_MAC6_PHY_GMII_EN_BOFFSET 14 +#define PORT6_PAD_CTRL_MAC6_PHY_GMII_EN_BLEN 1 +#define PORT6_PAD_CTRL_MAC6_PHY_GMII_EN_FLAG HSL_RW + +#define MAC6_PHY_GMII_TXCLK_SEL +#define PORT6_PAD_CTRL_MAC6_PHY_GMII_TXCLK_SEL_BOFFSET 13 +#define PORT6_PAD_CTRL_MAC6_PHY_GMII_TXCLK_SEL_BLEN 1 +#define PORT6_PAD_CTRL_MAC6_PHY_GMII_TXCLK_SEL_FLAG HSL_RW + +#define MAC6_PHY_GMII_RXCLK_SEL +#define PORT6_PAD_CTRL_MAC6_PHY_GMII_RXCLK_SEL_BOFFSET 12 +#define PORT6_PAD_CTRL_MAC6_PHY_GMII_RXCLK_SEL_BLEN 1 +#define PORT6_PAD_CTRL_MAC6_PHY_GMII_RXCLK_SEL_FLAG HSL_RW + +#define MAC6_PHY_MII_PIPE_RXCLK_SEL +#define PORT6_PAD_CTRL_MAC6_PHY_MII_PIPE_RXCLK_SEL_BOFFSET 11 +#define PORT6_PAD_CTRL_MAC6_PHY_MII_PIPE_RXCLK_SEL_BLEN 1 +#define PORT6_PAD_CTRL_MAC6_PHY_MII_PIPE_RXCLK_SEL_FLAG HSL_RW + +#define MAC6_PHY_MII_EN +#define PORT6_PAD_CTRL_MAC6_PHY_MII_EN_BOFFSET 10 +#define PORT6_PAD_CTRL_MAC6_PHY_MII_EN_BLEN 1 +#define PORT6_PAD_CTRL_MAC6_PHY_MII_EN_FLAG HSL_RW + +#define MAC6_PHY_MII_TXCLK_SEL +#define PORT6_PAD_CTRL_MAC6_PHY_MII_TXCLK_SEL_BOFFSET 9 +#define PORT6_PAD_CTRL_MAC6_PHY_MII_TXCLK_SEL_BLEN 1 +#define PORT6_PAD_CTRL_MAC6_PHY_MII_TXCLK_SEL_FLAG HSL_RW + +#define MAC6_PHY_MII_RXCLK_SEL +#define PORT6_PAD_CTRL_MAC6_PHY_MII_RXCLK_SEL_BOFFSET 8 +#define PORT6_PAD_CTRL_MAC6_PHY_MII_RXCLK_SEL_BLEN 1 +#define PORT6_PAD_CTRL_MAC6_PHY_MII_RXCLK_SEL_FLAG HSL_RW + +#define MAC6_SGMII_EN +#define PORT6_PAD_CTRL_MAC6_SGMII_EN_BOFFSET 7 +#define PORT6_PAD_CTRL_MAC6_SGMII_EN_BLEN 1 +#define PORT6_PAD_CTRL_MAC6_SGMII_EN_FLAG HSL_RW + +#define MAC6_MAC_GMII_EN +#define PORT6_PAD_CTRL_MAC6_MAC_GMII_EN_BOFFSET 6 +#define PORT6_PAD_CTRL_MAC6_MAC_GMII_EN_BLEN 1 +#define PORT6_PAD_CTRL_MAC6_MAC_GMII_EN_FLAG HSL_RW + +#define MAC6_MAC_GMII_TXCLK_SEL +#define PORT6_PAD_CTRL_MAC6_MAC_GMII_TXCLK_SEL_BOFFSET 5 +#define PORT6_PAD_CTRL_MAC6_MAC_GMII_TXCLK_SEL_BLEN 1 +#define PORT6_PAD_CTRL_MAC6_MAC_GMII_TXCLK_SEL_FLAG HSL_RW + +#define MAC6_MAC_GMII_RXCLK_SEL +#define PORT6_PAD_CTRL_MAC6_MAC_GMII_RXCLK_SEL_BOFFSET 4 +#define PORT6_PAD_CTRL_MAC6_MAC_GMII_RXCLK_SEL_BLEN 1 +#define PORT6_PAD_CTRL_MAC6_MAC_GMII_RXCLK_SEL_FLAG HSL_RW + +#define MAC6_MAC_MII_EN +#define PORT6_PAD_CTRL_MAC6_MAC_MII_EN_BOFFSET 2 +#define PORT6_PAD_CTRL_MAC6_MAC_MII_EN_BLEN 1 +#define PORT6_PAD_CTRL_MAC6_MAC_MII_EN_FLAG HSL_RW + +#define MAC6_MAC_MII_TXCLK_SEL +#define PORT6_PAD_CTRL_MAC6_MAC_MII_TXCLK_SEL_BOFFSET 1 +#define PORT6_PAD_CTRL_MAC6_MAC_MII_TXCLK_SEL_BLEN 1 +#define PORT6_PAD_CTRL_MAC6_MAC_MII_TXCLK_SEL_FLAG HSL_RW + +#define MAC6_MAC_MII_RXCLK_SEL +#define PORT6_PAD_CTRL_MAC6_MAC_MII_RXCLK_SEL_BOFFSET 0 +#define PORT6_PAD_CTRL_MAC6_MAC_MII_RXCLK_SEL_BLEN 1 +#define PORT6_PAD_CTRL_MAC6_MAC_MII_RXCLK_SEL_FLAG HSL_RW + + + + + /* SGMII Control Register */ +#define SGMII_CTRL +#define SGMII_CTRL_ID 0 +#define SGMII_CTRL_OFFSET 0x00e0 +#define SGMII_CTRL_E_LENGTH 4 +#define SGMII_CTRL_E_OFFSET 0 +#define SGMII_CTRL_NR_E 1 + +#define FULL_25M +#define SGMII_CTRL_FULL_25M_BOFFSET 31 +#define SGMII_CTRL_FULL_25M_BLEN 1 +#define SGMII_CTRL_FULL_25M_FLAG HSL_RW + +#define HALF_25M +#define SGMII_CTRL_HALF_25M_BOFFSET 30 +#define SGMII_CTRL_HALF_25M_BLEN 1 +#define SGMII_CTRL_HALF_25M_FLAG HSL_RW + +#define REMOTE_25M +#define SGMII_CTRL_REMOTE_25M_BOFFSET 28 +#define SGMII_CTRL_REMOTE_25M_BLEN 2 +#define SGMII_CTRL_REMOTE_25M_FLAG HSL_RW + +#define NEXT_PAGE_25M +#define SGMII_CTRL_NEXT_PAGE_25M_BOFFSET 27 +#define SGMII_CTRL_NEXT_PAGE_25M_BLEN 1 +#define SGMII_CTRL_NEXT_PAGE_25M_FLAG HSL_RW + +#define PAUSE_25M +#define SGMII_CTRL_PAUSE_25M_BOFFSET 26 +#define SGMII_CTRL_PAUSE_25M_BLEN 1 +#define SGMII_CTRL_PAUSE_25M_FLAG HSL_RW + +#define ASYM_PAUSE_25M +#define SGMII_CTRL_ASYM_PAUSE_25M_BOFFSET 25 +#define SGMII_CTRL_ASYM_PAUSE_25M_BLEN 1 +#define SGMII_CTRL_ASYM_PAUSE_25M_FLAG HSL_RW + +#define PAUSE_SG_25M +#define SGMII_CTRL_PAUSE_SG_25M_BOFFSET 24 +#define SGMII_CTRL_PAUSE_SG_25M_BLEN 1 +#define SGMII_CTRL_PAUSE_SG_25M_FLAG HSL_RW + +#define PAUSE_SG_25M +#define SGMII_CTRL_PAUSE_SG_25M_BOFFSET 24 +#define SGMII_CTRL_PAUSE_SG_25M_BLEN 1 +#define SGMII_CTRL_PAUSE_SG_25M_FLAG HSL_RW + +#define MODE_CTRL_25M +#define SGMII_CTRL_MODE_CTRL_25M_BOFFSET 22 +#define SGMII_CTRL_MODE_CTRL_25M_BLEN 2 +#define SGMII_CTRL_MODE_CTRL_25M_FLAG HSL_RW + +#define MR_LOOPBACK +#define SGMII_CTRL_MR_LOOPBACK_BOFFSET 21 +#define SGMII_CTRL_MR_LOOPBACK_BLEN 1 +#define SGMII_CTRL_MR_LOOPBACK_FLAG HSL_RW + +#define MR_REG4_25M +#define SGMII_CTRL_MR_REG4_25M_BOFFSET 20 +#define SGMII_CTRL_MR_REG4_25M_BLEN 1 +#define SGMII_CTRL_MR_REG4_25M_FLAG HSL_RW + +#define AUTO_LPI_25M +#define SGMII_CTRL_AUTO_LPI_25M_BOFFSET 19 +#define SGMII_CTRL_AUTO_LPI_25M_BLEN 1 +#define SGMII_CTRL_AUTO_LPI_25M_FLAG HSL_RW + +#define PRBS_EN +#define SGMII_CTRL_PRBS_EN_BOFFSET 18 +#define SGMII_CTRL_PRBS_EN_BLEN 1 +#define SGMII_CTRL_PRBS_EN_FLAG HSL_RW + +#define SGMII_TH_LOS1 +#define SGMII_CTRL_SGMII_TH_LOS1_BOFFSET 17 +#define SGMII_CTRL_SGMII_TH_LOS1_BLEN 1 +#define SGMII_CTRL_SGMII_TH_LOS1_FLAG HSL_RW + +#define DIS_AUTO_LPI_25M +#define SGMII_CTRL_DIS_AUTO_LPI_25M_BOFFSET 16 +#define SGMII_CTRL_DIS_AUTO_LPI_25M_BLEN 1 +#define SGMII_CTRL_DIS_AUTO_LPI_25M_FLAG HSL_RW + +#define SGMII_TH_LOS0 +#define SGMII_CTRL_SGMII_TH_LOS0_BOFFSET 15 +#define SGMII_CTRL_SGMII_TH_LOS0_BLEN 1 +#define SGMII_CTRL_SGMII_TH_LOS0_FLAG HSL_RW + +#define SGMII_CDR_BW +#define SGMII_CTRL_SGMII_CDR_BW_BOFFSET 13 +#define SGMII_CTRL_SGMII_CDR_BW_BLEN 2 +#define SGMII_CTRL_SGMII_CDR_BW_FLAG HSL_RW + +#define SGMII_TXDR_CTRL +#define SGMII_CTRL_SGMII_TXDR_CTRL_BOFFSET 10 +#define SGMII_CTRL_SGMII_TXDR_CTRL_BLEN 3 +#define SGMII_CTRL_SGMII_TXDR_CTRL_FLAG HSL_RW + +#define SGMII_FIBER_MODE +#define SGMII_CTRL_SGMII_FIBER_MODE_BOFFSET 8 +#define SGMII_CTRL_SGMII_FIBER_MODE_BLEN 2 +#define SGMII_CTRL_SGMII_FIBER_MODE_FLAG HSL_RW + +#define SGMII_SEL_125M +#define SGMII_CTRL_SGMII_SEL_125M_BOFFSET 7 +#define SGMII_CTRL_SGMII_SEL_125M_BLEN 1 +#define SGMII_CTRL_SGMII_SEL_125M_FLAG HSL_RW + +#define SGMII_PLL_BW +#define SGMII_CTRL_SGMII_PLL_BW_BOFFSET 6 +#define SGMII_CTRL_SGMII_PLL_BW_BLEN 1 +#define SGMII_CTRL_SGMII_PLL_BW_FLAG HSL_RW + +#define SGMII_HALFTX +#define SGMII_CTRL_SGMII_HALFTX_BOFFSET 5 +#define SGMII_CTRL_SGMII_HALFTX_BLEN 1 +#define SGMII_CTRL_SGMII_HALFTX_FLAG HSL_RW + +#define SGMII_EN_SD +#define SGMII_CTRL_SGMII_EN_SD_BOFFSET 4 +#define SGMII_CTRL_SGMII_EN_SD_BLEN 1 +#define SGMII_CTRL_SGMII_EN_SD_FLAG HSL_RW + +#define SGMII_EN_TX +#define SGMII_CTRL_SGMII_EN_TX_BOFFSET 3 +#define SGMII_CTRL_SGMII_EN_TX_BLEN 1 +#define SGMII_CTRL_SGMII_EN_TX_FLAG HSL_RW + +#define SGMII_EN_RX +#define SGMII_CTRL_SGMII_EN_RX_BOFFSET 2 +#define SGMII_CTRL_SGMII_EN_RX_BLEN 1 +#define SGMII_CTRL_SGMII_EN_RX_FLAG HSL_RW + +#define SGMII_EN_PLL +#define SGMII_CTRL_SGMII_EN_PLL_BOFFSET 1 +#define SGMII_CTRL_SGMII_EN_PLL_BLEN 1 +#define SGMII_CTRL_SGMII_EN_PLL_FLAG HSL_RW + +#define SGMII_EN_LCKDT +#define SGMII_CTRL_SGMII_EN_LCKDT_BOFFSET 0 +#define SGMII_CTRL_SGMII_EN_LCKDT_BLEN 1 +#define SGMII_CTRL_SGMII_EN_LCKDT_FLAG HSL_RW + + + + + /* Power On Strip Register */ +#define POWER_STRIP +#define POWER_STRIP_ID 0 +#define POWER_STRIP_OFFSET 0x0010 +#define POWER_STRIP_E_LENGTH 4 +#define POWER_STRIP_E_OFFSET 0 +#define POWER_STRIP_NR_E 1 + +#define POWER_ON_SEL +#define POWER_STRIP_POWER_ON_SEL_BOFFSET 31 +#define POWER_STRIP_POWER_ON_SEL_BLEN 1 +#define POWER_STRIP_POWER_ON_SEL_FLAG HSL_RW + +#define PKG128_EN +#define POWER_STRIP_PKG128_EN_BOFFSET 30 +#define POWER_STRIP_PKG128_EN_BLEN 1 +#define POWER_STRIP_PKG128_EN_FLAG HSL_RW + +#define PKG128_EN_LED +#define POWER_STRIP_PKG128_EN_LED_BOFFSET 29 +#define POWER_STRIP_PKG128_EN_LED_BLEN 1 +#define POWER_STRIP_PKG128_EN_LED_FLAG HSL_RW + +#define S16_MODE +#define POWER_STRIP_S16_MODE_BOFFSET 28 +#define POWER_STRIP_S16_MODE_BLEN 1 +#define POWER_STRIP_S16_MODE_FLAG HSL_RW + +#define INPUT_MODE +#define POWER_STRIP_INPUT_MODE_BOFFSET 27 +#define POWER_STRIP_INPUT_MODE_BLEN 1 +#define POWER_STRIP_INPUT_MODE_FLAG HSL_RW + +#define SGMII_POWER_ON_SEL +#define POWER_STRIP_SGMII_POWER_ON_SEL_BOFFSET 26 +#define POWER_STRIP_SGMII_POWER_ON_SEL_BLEN 1 +#define POWER_STRIP_SGMII_POWER_ON_SEL_FLAG HSL_RW + +#define SPI_EN +#define POWER_STRIP_SPI_EN_BOFFSET 25 +#define POWER_STRIP_SPI_EN_BLEN 1 +#define POWER_STRIP_SPI_EN_FLAG HSL_RW + +#define LED_OPEN_EN +#define POWER_STRIP_LED_OPEN_EN_BOFFSET 24 +#define POWER_STRIP_LED_OPEN_EN_BLEN 1 +#define POWER_STRIP_LED_OPEN_EN_FLAG HSL_RW + +#define SGMII_RXIMP_50_70 +#define POWER_STRIP_SGMII_RXIMP_50_70_BOFFSET 23 +#define POWER_STRIP_SGMII_RXIMP_50_70_BLEN 1 +#define POWER_STRIP_SGMII_RXIMP_50_70_FLAG HSL_RW + +#define SGMII_TXIMP_50_70 +#define POWER_STRIP_SGMII_TXIMP_50_70_BOFFSET 22 +#define POWER_STRIP_SGMII_TXIMP_50_70_BLEN 1 +#define POWER_STRIP_SGMII_TXIMP_50_70_FLAG HSL_RW + +#define SGMII_SIGNAL_DETECT +#define POWER_STRIP_SGMII_SIGNAL_DETECT_BOFFSET 21 +#define POWER_STRIP_SGMII_SIGNAL_DETECT_BLEN 1 +#define POWER_STRIP_SGMII_SIGNAL_DETECT_FLAG HSL_RW + +#define LPW_EXIT +#define POWER_STRIP_LPW_EXIT_BOFFSET 20 +#define POWER_STRIP_LPW_EXIT_BLEN 1 +#define POWER_STRIP_LPW_EXIT_FLAG HSL_RW + +#define MAN_EN +#define POWER_STRIP_MAN_EN_BOFFSET 18 +#define POWER_STRIP_MAN_EN_BLEN 1 +#define POWER_STRIP_MAN_EN_FLAG HSL_RW + +#define HIB_EN +#define POWER_STRIP_HIB_EN_BOFFSET 17 +#define POWER_STRIP_HIB_EN_BLEN 1 +#define POWER_STRIP_HIB_EN_FLAG HSL_RW + +#define POWER_DOWN_HW +#define POWER_STRIP_POWER_DOWN_HW_BOFFSET 16 +#define POWER_STRIP_POWER_DOWN_HW_BLEN 1 +#define POWER_STRIP_POWER_DOWN_HW_FLAG HSL_RW + +#define BIST_BYPASS_CEL +#define POWER_STRIP_BIST_BYPASS_CEL_BOFFSET 15 +#define POWER_STRIP_BIST_BYPASS_CEL_BLEN 1 +#define POWER_STRIP_BIST_BYPASS_CEL_FLAG HSL_RW + +#define BIST_BYPASS_CSR +#define POWER_STRIP_BIST_BYPASS_CSR_BOFFSET 14 +#define POWER_STRIP_BIST_BYPASS_CSR_BLEN 1 +#define POWER_STRIP_BIST_BYPASS_CSR_FLAG HSL_RW + +#define HIB_PULSE_HW +#define POWER_STRIP_HIB_PULSE_HW_BOFFSET 12 +#define POWER_STRIP_HIB_PULSE_HW_BLEN 1 +#define POWER_STRIP_HIB_PULSE_HW_FLAG HSL_RW + +#define GATE_25M_EN +#define POWER_STRIP_GATE_25M_EN_BOFFSET 10 +#define POWER_STRIP_GATE_25M_EN_BLEN 1 +#define POWER_STRIP_GATE_25M_EN_FLAG HSL_RW + +#define SEL_ANA_RST +#define POWER_STRIP_SEL_ANA_RST_BOFFSET 9 +#define POWER_STRIP_SEL_ANA_RST_BLEN 1 +#define POWER_STRIP_SEL_ANA_RST_FLAG HSL_RW + +#define SERDES_EN +#define POWER_STRIP_SERDES_EN_BOFFSET 8 +#define POWER_STRIP_SERDES_EN_BLEN 1 +#define POWER_STRIP_SERDES_EN_FLAG HSL_RW + +#define SERDES_AN_EN +#define POWER_STRIP_SERDES_AN_EN_BOFFSET 7 +#define POWER_STRIP_SERDES_AN_EN_BLEN 1 +#define POWER_STRIP_SERDES_AN_EN_FLAG HSL_RW + +#define RTL_MODE +#define POWER_STRIP_RTL_MODE_BOFFSET 5 +#define POWER_STRIP_RTL_MODE_BLEN 1 +#define POWER_STRIP_RTL_MODE_FLAG HSL_RW + +#define PAD_CTRL_FOR25M +#define POWER_STRIP_PAD_CTRL_FOR25M_BOFFSET 3 +#define POWER_STRIP_PAD_CTRL_FOR25M_BLEN 2 +#define POWER_STRIP_PAD_CTRL_FOR25M_FLAG HSL_RW + +#define PAD_CTRL +#define POWER_STRIP_PAD_CTRL_BOFFSET 0 +#define POWER_STRIP_PAD_CTRL_BLEN 2 +#define POWER_STRIP_PAD_CTRL_FLAG HSL_RW + + + + + /* Global Interrupt Status Register1 */ +#define GBL_INT_STATUS1 +#define GBL_INT_STATUS1_ID 1 +#define GBL_INT_STATUS1_OFFSET 0x0024 +#define GBL_INT_STATUS1_E_LENGTH 4 +#define GBL_INT_STATUS1_E_OFFSET 0 +#define GBL_INT_STATUS1_NR_E 1 + +#define PHY_INT_S +#define GBL_INT_STATUS1_PHY_INT_S_BOFFSET 15 +#define GBL_INT_STATUS1_PHY_INT_S_BLEN 1 +#define GBL_INT_STATUS1_PHY_INT_S_FLAG HSL_RO + + + + + /* Global Interrupt Mask Register1 */ +#define GBL_INT_MASK1 +#define GBL_INT_MASK1_ID 1 +#define GBL_INT_MASK1_OFFSET 0x002c +#define GBL_INT_MASK1_E_LENGTH 4 +#define GBL_INT_MASK1_E_OFFSET 0 +#define GBL_INT_MASK1_NR_E 1 + +#define PHY_INT_M +#define GBL_INT_MASK1_PHY_INT_M_BOFFSET 15 +#define GBL_INT_MASK1_PHY_INT_M_BLEN 1 +#define GBL_INT_MASK1_PHY_INT_M_FLAG HSL_RO + + + + + /* Module Enable Register */ +#define MOD_ENABLE +#define MOD_ENABLE_OFFSET 0x0030 +#define MOD_ENABLE_E_LENGTH 4 +#define MOD_ENABLE_E_OFFSET 0 +#define MOD_ENABLE_NR_E 1 + +#define L3_EN +#define MOD_ENABLE_L3_EN_BOFFSET 2 +#define MOD_ENABLE_L3_EN_BLEN 1 +#define MOD_ENABLE_L3_EN_FLAG HSL_RW + +#define ACL_EN +#define MOD_ENABLE_ACL_EN_BOFFSET 1 +#define MOD_ENABLE_ACL_EN_BLEN 1 +#define MOD_ENABLE_ACL_EN_FLAG HSL_RW + +#define MIB_EN +#define MOD_ENABLE_MIB_EN_BOFFSET 0 +#define MOD_ENABLE_MIB_EN_BLEN 1 +#define MOD_ENABLE_MIB_EN_FLAG HSL_RW + + + + + /* MIB Function Register */ +#define MIB_FUNC +#define MIB_FUNC_OFFSET 0x0034 +#define MIB_FUNC_E_LENGTH 4 +#define MIB_FUNC_E_OFFSET 0 +#define MIB_FUNC_NR_E 1 + +#define MIB_FUN +#define MIB_FUNC_MIB_FUN_BOFFSET 24 +#define MIB_FUNC_MIB_FUN_BLEN 3 +#define MIB_FUNC_MIB_FUN_FLAG HSL_RW + +#define MIB_BUSY +#define MIB_FUNC_MIB_BUSY_BOFFSET 17 +#define MIB_FUNC_MIB_BUSY_BLEN 1 +#define MIB_FUNC_MIB_BUSY_FLAG HSL_RW + +#define MIB_AT_HALF_EN +#define MIB_FUNC_MIB_AT_HALF_EN_BOFFSET 16 +#define MIB_FUNC_MIB_AT_HALF_EN_BLEN 1 +#define MIB_FUNC_MIB_AT_HALF_EN_FLAG HSL_RW + +#define MIB_TIMER +#define MIB_FUNC_MIB_TIMER_BOFFSET 0 +#define MIB_FUNC_MIB_TIMER_BLEN 16 +#define MIB_FUNC_MIB_TIMER_FLAG HSL_RW + + + + + /* Service tag Register */ +#define SERVICE_TAG +#define SERVICE_TAG_OFFSET 0x0048 +#define SERVICE_TAG_E_LENGTH 4 +#define SERVICE_TAG_E_OFFSET 0 +#define SERVICE_TAG_NR_E 1 + +#define STAG_MODE +#define SERVICE_TAG_STAG_MODE_BOFFSET 17 +#define SERVICE_TAG_STAG_MODE_BLEN 1 +#define SERVICE_TAG_STAG_MODE_FLAG HSL_RW + +#define TAG_VALUE +#define SERVICE_TAG_TAG_VALUE_BOFFSET 0 +#define SERVICE_TAG_TAG_VALUE_BLEN 16 +#define SERVICE_TAG_TAG_VALUE_FLAG HSL_RW + + + + + /* Global MAC Address Register */ +#define GLOBAL_MAC_ADDR0 +#define GLOBAL_MAC_ADDR0_OFFSET 0x0060 +#define GLOBAL_MAC_ADDR0_E_LENGTH 4 +#define GLOBAL_MAC_ADDR0_E_OFFSET 0 +#define GLOBAL_MAC_ADDR0_NR_E 1 + +#define GLB_BYTE4 +#define GLOBAL_MAC_ADDR0_GLB_BYTE4_BOFFSET 8 +#define GLOBAL_MAC_ADDR0_GLB_BYTE4_BLEN 8 +#define GLOBAL_MAC_ADDR0_GLB_BYTE4_FLAG HSL_RW + +#define GLB_BYTE5 +#define GLOBAL_MAC_ADDR0_GLB_BYTE5_BOFFSET 0 +#define GLOBAL_MAC_ADDR0_GLB_BYTE5_BLEN 8 +#define GLOBAL_MAC_ADDR0_GLB_BYTE5_FLAG HSL_RW + +#define GLOBAL_MAC_ADDR1 +#define GLOBAL_MAC_ADDR1_ID 4 +#define GLOBAL_MAC_ADDR1_OFFSET 0x0064 +#define GLOBAL_MAC_ADDR1_E_LENGTH 4 +#define GLOBAL_MAC_ADDR1_E_OFFSET 0 +#define GLOBAL_MAC_ADDR1_NR_E 1 + +#define GLB_BYTE0 +#define GLOBAL_MAC_ADDR1_GLB_BYTE0_BOFFSET 24 +#define GLOBAL_MAC_ADDR1_GLB_BYTE0_BLEN 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE0_FLAG HSL_RW + +#define GLB_BYTE1 +#define GLOBAL_MAC_ADDR1_GLB_BYTE1_BOFFSET 16 +#define GLOBAL_MAC_ADDR1_GLB_BYTE1_BLEN 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE1_FLAG HSL_RW + +#define GLB_BYTE2 +#define GLOBAL_MAC_ADDR1_GLB_BYTE2_BOFFSET 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE2_BLEN 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE2_FLAG HSL_RW + +#define GLB_BYTE3 +#define GLOBAL_MAC_ADDR1_GLB_BYTE3_BOFFSET 0 +#define GLOBAL_MAC_ADDR1_GLB_BYTE3_BLEN 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE3_FLAG HSL_RW + + + + + /* Max Size Register */ +#define MAX_SIZE +#define MAX_SIZE_OFFSET 0x0078 +#define MAX_SIZE_E_LENGTH 4 +#define MAX_SIZE_E_OFFSET 0 +#define MAX_SIZE_NR_E 1 + +#define MAX_FRAME_SIZE +#define MAX_SIZE_MAX_FRAME_SIZE_BOFFSET 0 +#define MAX_SIZE_MAX_FRAME_SIZE_BLEN 14 +#define MAX_SIZE_MAX_FRAME_SIZE_FLAG HSL_RW + + + + + /* Flow Control Register */ +#define FLOW_CTL0 "fctl" +#define FLOW_CTL0_ID 6 +#define FLOW_CTL0_OFFSET 0x0034 +#define FLOW_CTL0_E_LENGTH 4 +#define FLOW_CTL0_E_OFFSET 0 +#define FLOW_CTL0_NR_E 1 + +#define TEST_PAUSE "fctl_tps" +#define FLOW_CTL0_TEST_PAUSE_BOFFSET 31 +#define FLOW_CTL0_TEST_PAUSE_BLEN 1 +#define FLOW_CTL0_TEST_PAUSE_FLAG HSL_RW + + +#define GOL_PAUSE_ON_THRES "fctl_gont" +#define FLOW_CTL0_GOL_PAUSE_ON_THRES_BOFFSET 16 +#define FLOW_CTL0_GOL_PAUSE_ON_THRES_BLEN 8 +#define FLOW_CTL0_GOL_PAUSE_ON_THRES_FLAG HSL_RW + +#define GOL_PAUSE_OFF_THRES "fctl_gofft" +#define FLOW_CTL0_GOL_PAUSE_OFF_THRES_BOFFSET 0 +#define FLOW_CTL0_GOL_PAUSE_OFF_THRES_BLEN 8 +#define FLOW_CTL0_GOL_PAUSE_OFF_THRES_FLAG HSL_RW + + + + + /* Flow Control1 Register */ +#define FLOW_CTL1 "fctl1" +#define FLOW_CTL1_ID 6 +#define FLOW_CTL1_OFFSET 0x0038 +#define FLOW_CTL1_E_LENGTH 4 +#define FLOW_CTL1_E_OFFSET 0 +#define FLOW_CTL1_NR_E 1 + +#define PORT_PAUSE_ON_THRES "fctl1_pont" +#define FLOW_CTL1_PORT_PAUSE_ON_THRES_BOFFSET 16 +#define FLOW_CTL1_PORT_PAUSE_ON_THRES_BLEN 8 +#define FLOW_CTL1_PORT_PAUSE_ON_THRES_FLAG HSL_RW + +#define PORT_PAUSE_OFF_THRES "fctl1_pofft" +#define FLOW_CTL1_PORT_PAUSE_OFF_THRES_BOFFSET 0 +#define FLOW_CTL1_PORT_PAUSE_OFF_THRES_BLEN 8 +#define FLOW_CTL1_PORT_PAUSE_OFF_THRES_FLAG HSL_RW + + + + + /* Port Status Register */ +#define PORT_STATUS +#define PORT_STATUS_OFFSET 0x007c +#define PORT_STATUS_E_LENGTH 4 +#define PORT_STATUS_E_OFFSET 0x0004 +#define PORT_STATUS_NR_E 7 + +#define FLOW_LINK_EN +#define PORT_STATUS_FLOW_LINK_EN_BOFFSET 12 +#define PORT_STATUS_FLOW_LINK_EN_BLEN 1 +#define PORT_STATUS_FLOW_LINK_EN_FLAG HSL_RW + +#define AUTO_RX_FLOW +#define PORT_STATUS_AUTO_RX_FLOW_BOFFSET 11 +#define PORT_STATUS_AUTO_RX_FLOW_BLEN 1 +#define PORT_STATUS_AUTO_RX_FLOW_FLAG HSL_RO + +#define AUTO_TX_FLOW +#define PORT_STATUS_AUTO_TX_FLOW_BOFFSET 10 +#define PORT_STATUS_AUTO_TX_FLOW_BLEN 1 +#define PORT_STATUS_AUTO_TX_FLOW_FLAG HSL_RO + +#define LINK_EN +#define PORT_STATUS_LINK_EN_BOFFSET 9 +#define PORT_STATUS_LINK_EN_BLEN 1 +#define PORT_STATUS_LINK_EN_FLAG HSL_RW + +#define LINK +#define PORT_STATUS_LINK_BOFFSET 8 +#define PORT_STATUS_LINK_BLEN 1 +#define PORT_STATUS_LINK_FLAG HSL_RO + +#define TX_HALF_FLOW_EN +#define PORT_STATUS_TX_HALF_FLOW_EN_BOFFSET 7 +#define PORT_STATUS_TX_HALF_FLOW_EN_BLEN 1 +#define PORT_STATUS_TX_HALF_FLOW_EN_FLAG HSL_RW + +#define DUPLEX_MODE +#define PORT_STATUS_DUPLEX_MODE_BOFFSET 6 +#define PORT_STATUS_DUPLEX_MODE_BLEN 1 +#define PORT_STATUS_DUPLEX_MODE_FLAG HSL_RW + +#define RX_FLOW_EN +#define PORT_STATUS_RX_FLOW_EN_BOFFSET 5 +#define PORT_STATUS_RX_FLOW_EN_BLEN 1 +#define PORT_STATUS_RX_FLOW_EN_FLAG HSL_RW + +#define TX_FLOW_EN +#define PORT_STATUS_TX_FLOW_EN_BOFFSET 4 +#define PORT_STATUS_TX_FLOW_EN_BLEN 1 +#define PORT_STATUS_TX_FLOW_EN_FLAG HSL_RW + +#define RXMAC_EN +#define PORT_STATUS_RXMAC_EN_BOFFSET 3 +#define PORT_STATUS_RXMAC_EN_BLEN 1 +#define PORT_STATUS_RXMAC_EN_FLAG HSL_RW + +#define TXMAC_EN +#define PORT_STATUS_TXMAC_EN_BOFFSET 2 +#define PORT_STATUS_TXMAC_EN_BLEN 1 +#define PORT_STATUS_TXMAC_EN_FLAG HSL_RW + +#define SPEED_MODE +#define PORT_STATUS_SPEED_MODE_BOFFSET 0 +#define PORT_STATUS_SPEED_MODE_BLEN 2 +#define PORT_STATUS_SPEED_MODE_FLAG HSL_RW + + + + + /* Header Ctl Register */ +#define HEADER_CTL +#define HEADER_CTL_OFFSET 0x0098 +#define HEADER_CTL_E_LENGTH 4 +#define HEADER_CTL_E_OFFSET 0x0004 +#define HEADER_CTL_NR_E 1 + +#define TYPE_LEN +#define HEADER_CTL_TYPE_LEN_BOFFSET 16 +#define HEADER_CTL_TYPE_LEN_BLEN 1 +#define HEADER_CTL_TYPE_LEN_FLAG HSL_RW + +#define TYPE_VAL +#define HEADER_CTL_TYPE_VAL_BOFFSET 0 +#define HEADER_CTL_TYPE_VAL_BLEN 16 +#define HEADER_CTL_TYPE_VAL_FLAG HSL_RW + + + + + /* Port Header Ctl Register */ +#define PORT_HDR_CTL +#define PORT_HDR_CTL_OFFSET 0x009c +#define PORT_HDR_CTL_E_LENGTH 4 +#define PORT_HDR_CTL_E_OFFSET 0x0004 +#define PORT_HDR_CTL_NR_E 7 + +#define IPG_DEC_EN +#define PORT_HDR_CTL_IPG_DEC_EN_BOFFSET 5 +#define PORT_HDR_CTL_IPG_DEC_EN_BLEN 1 +#define PORT_HDR_CTL_IPG_DEC_EN_FLAG HSL_RW + +#define LOOPBACK_EN +#define PORT_HDR_CTL_LOOPBACK_EN_BOFFSET 4 +#define PORT_HDR_CTL_LOOPBACK_EN_BLEN 1 +#define PORT_HDR_CTL_LOOPBACK_EN_FLAG HSL_RW + +#define RXHDR_MODE +#define PORT_HDR_CTL_RXHDR_MODE_BOFFSET 2 +#define PORT_HDR_CTL_RXHDR_MODE_BLEN 2 +#define PORT_HDR_CTL_RXHDR_MODE_FLAG HSL_RW + +#define TXHDR_MODE +#define PORT_HDR_CTL_TXHDR_MODE_BOFFSET 0 +#define PORT_HDR_CTL_TXHDR_MODE_BLEN 2 +#define PORT_HDR_CTL_TXHDR_MODE_FLAG HSL_RW + + + + + /* EEE control Register */ +#define EEE_CTL +#define EEE_CTL_OFFSET 0x0100 +#define EEE_CTL_E_LENGTH 4 +#define EEE_CTL_E_OFFSET 0 +#define EEE_CTL_NR_E 1 + +#define LPI_STATE_REMAP_EN_5 +#define EEE_CTL_LPI_STATE_REMAP_EN_5_BOFFSET 13 +#define EEE_CTL_LPI_STATE_REMAP_EN_5_BLEN 1 +#define EEE_CTL_LPI_STATE_REMAP_EN_5_FLAG HSL_RW + +#define LPI_EN_5 +#define EEE_CTL_LPI_EN_5_BOFFSET 12 +#define EEE_CTL_LPI_EN_5_BLEN 1 +#define EEE_CTL_LPI_EN_5_FLAG HSL_RW + +#define LPI_STATE_REMAP_EN_4 +#define EEE_CTL_LPI_STATE_REMAP_EN_4_BOFFSET 11 +#define EEE_CTL_LPI_STATE_REMAP_EN_4_BLEN 1 +#define EEE_CTL_LPI_STATE_REMAP_EN_4_FLAG HSL_RW + +#define LPI_EN_4 +#define EEE_CTL_LPI_EN_4_BOFFSET 10 +#define EEE_CTL_LPI_EN_4_BLEN 1 +#define EEE_CTL_LPI_EN_4_FLAG HSL_RW + +#define LPI_STATE_REMAP_EN_3 +#define EEE_CTL_LPI_STATE_REMAP_EN_3_BOFFSET 9 +#define EEE_CTL_LPI_STATE_REMAP_EN_3_BLEN 1 +#define EEE_CTL_LPI_STATE_REMAP_EN_3_FLAG HSL_RW + +#define LPI_EN_3 +#define EEE_CTL_LPI_EN_3_BOFFSET 8 +#define EEE_CTL_LPI_EN_3_BLEN 1 +#define EEE_CTL_LPI_EN_3_FLAG HSL_RW + +#define LPI_STATE_REMAP_EN_2 +#define EEE_CTL_LPI_STATE_REMAP_EN_2_BOFFSET 7 +#define EEE_CTL_LPI_STATE_REMAP_EN_2_BLEN 1 +#define EEE_CTL_LPI_STATE_REMAP_EN_2_FLAG HSL_RW + +#define LPI_EN_2 +#define EEE_CTL_LPI_EN_2_BOFFSET 6 +#define EEE_CTL_LPI_EN_2_BLEN 1 +#define EEE_CTL_LPI_EN_2_FLAG HSL_RW + +#define LPI_STATE_REMAP_EN_1 +#define EEE_CTL_LPI_STATE_REMAP_EN_1_BOFFSET 5 +#define EEE_CTL_LPI_STATE_REMAP_EN_1_BLEN 1 +#define EEE_CTL_LPI_STATE_REMAP_EN_1_FLAG HSL_RW + +#define LPI_EN_1 +#define EEE_CTL_LPI_EN_1_BOFFSET 4 +#define EEE_CTL_LPI_EN_1_BLEN 1 +#define EEE_CTL_LPI_EN_1_FLAG HSL_RW + + + + + /* Frame Ack Ctl0 Register */ +#define FRAME_ACK_CTL0 +#define FRAME_ACK_CTL0_OFFSET 0x0210 +#define FRAME_ACK_CTL0_E_LENGTH 4 +#define FRAME_ACK_CTL0_E_OFFSET 0 +#define FRAME_ACK_CTL0_NR_E 1 + +#define ARP_REQ_EN +#define FRAME_ACK_CTL0_ARP_REQ_EN_BOFFSET 6 +#define FRAME_ACK_CTL0_ARP_REQ_EN_BLEN 1 +#define FRAME_ACK_CTL0_ARP_REQ_EN_FLAG HSL_RW + +#define ARP_REP_EN +#define FRAME_ACK_CTL0_ARP_REP_EN_BOFFSET 5 +#define FRAME_ACK_CTL0_ARP_REP_EN_BLEN 1 +#define FRAME_ACK_CTL0_ARP_REP_EN_FLAG HSL_RW + +#define DHCP_EN +#define FRAME_ACK_CTL0_DHCP_EN_BOFFSET 4 +#define FRAME_ACK_CTL0_DHCP_EN_BLEN 1 +#define FRAME_ACK_CTL0_DHCP_EN_FLAG HSL_RW + +#define EAPOL_EN +#define FRAME_ACK_CTL0_EAPOL_EN_BOFFSET 3 +#define FRAME_ACK_CTL0_EAPOL_EN_BLEN 1 +#define FRAME_ACK_CTL0_EAPOL_EN_FLAG HSL_RW + +#define LEAVE_EN +#define FRAME_ACK_CTL0_LEAVE_EN_BOFFSET 2 +#define FRAME_ACK_CTL0_LEAVE_EN_BLEN 1 +#define FRAME_ACK_CTL0_LEAVE_EN_FLAG HSL_RW + +#define JOIN_EN +#define FRAME_ACK_CTL0_JOIN_EN_BOFFSET 1 +#define FRAME_ACK_CTL0_JOIN_EN_BLEN 1 +#define FRAME_ACK_CTL0_JOIN_EN_FLAG HSL_RW + +#define IGMP_MLD_EN +#define FRAME_ACK_CTL0_IGMP_MLD_EN_BOFFSET 0 +#define FRAME_ACK_CTL0_IGMP_MLD_EN_BLEN 1 +#define FRAME_ACK_CTL0_IGMP_MLD_EN_FLAG HSL_RW + + + + + /* Frame Ack Ctl1 Register */ +#define FRAME_ACK_CTL1 +#define FRAME_ACK_CTL1_OFFSET 0x0214 +#define FRAME_ACK_CTL1_E_LENGTH 4 +#define FRAME_ACK_CTL1_E_OFFSET 0 +#define FRAME_ACK_CTL1_NR_E 1 + +#define PPPOE_EN +#define FRAME_ACK_CTL1_PPPOE_EN_BOFFSET 25 +#define FRAME_ACK_CTL1_PPPOE_EN_BLEN 1 +#define FRAME_ACK_CTL1_PPPOE_EN_FLAG HSL_RW + +#define IGMP_V3_EN +#define FRAME_ACK_CTL1_IGMP_V3_EN_BOFFSET 24 +#define FRAME_ACK_CTL1_IGMP_V3_EN_BLEN 1 +#define FRAME_ACK_CTL1_IGMP_V3_EN_FLAG HSL_RW + + + + + /* Window Rule Ctl0 Register */ +#define WIN_RULE_CTL0 +#define WIN_RULE_CTL0_OFFSET 0x0218 +#define WIN_RULE_CTL0_E_LENGTH 4 +#define WIN_RULE_CTL0_E_OFFSET 0x4 +#define WIN_RULE_CTL0_NR_E 7 + +#define L4_LENGTH +#define WIN_RULE_CTL0_L4_LENGTH_BOFFSET 24 +#define WIN_RULE_CTL0_L4_LENGTH_BLEN 4 +#define WIN_RULE_CTL0_L4_LENGTH_FLAG HSL_RW + +#define L3_LENGTH +#define WIN_RULE_CTL0_L3_LENGTH_BOFFSET 20 +#define WIN_RULE_CTL0_L3_LENGTH_BLEN 4 +#define WIN_RULE_CTL0_L3_LENGTH_FLAG HSL_RW + +#define L2_LENGTH +#define WIN_RULE_CTL0_L2_LENGTH_BOFFSET 16 +#define WIN_RULE_CTL0_L2_LENGTH_BLEN 4 +#define WIN_RULE_CTL0_L2_LENGTH_FLAG HSL_RW + +#define L4_OFFSET +#define WIN_RULE_CTL0_L4_OFFSET_BOFFSET 10 +#define WIN_RULE_CTL0_L4_OFFSET_BLEN 5 +#define WIN_RULE_CTL0_L4_OFFSET_FLAG HSL_RW + +#define L3_OFFSET +#define WIN_RULE_CTL0_L3_OFFSET_BOFFSET 5 +#define WIN_RULE_CTL0_L3_OFFSET_BLEN 5 +#define WIN_RULE_CTL0_L3_OFFSET_FLAG HSL_RW + +#define L2_OFFSET +#define WIN_RULE_CTL0_L2_OFFSET_BOFFSET 0 +#define WIN_RULE_CTL0_L2_OFFSET_BLEN 5 +#define WIN_RULE_CTL0_L2_OFFSET_FLAG HSL_RW + + + + + /* Window Rule Ctl1 Register */ +#define WIN_RULE_CTL1 +#define WIN_RULE_CTL1_OFFSET 0x0234 +#define WIN_RULE_CTL1_E_LENGTH 4 +#define WIN_RULE_CTL1_E_OFFSET 0x4 +#define WIN_RULE_CTL1_NR_E 7 + +#define L3P_LENGTH +#define WIN_RULE_CTL1_L3P_LENGTH_BOFFSET 20 +#define WIN_RULE_CTL1_L3P_LENGTH_BLEN 4 +#define WIN_RULE_CTL1_L3P_LENGTH_FLAG HSL_RW + +#define L2S_LENGTH +#define WIN_RULE_CTL1_L2S_LENGTH_BOFFSET 16 +#define WIN_RULE_CTL1_L2S_LENGTH_BLEN 4 +#define WIN_RULE_CTL1_L2S_LENGTH_FLAG HSL_RW + +#define L3P_OFFSET +#define WIN_RULE_CTL1_L3P_OFFSET_BOFFSET 5 +#define WIN_RULE_CTL1_L3P_OFFSET_BLEN 5 +#define WIN_RULE_CTL1_L3P_OFFSET_FLAG HSL_RW + +#define L2S_OFFSET +#define WIN_RULE_CTL1_L2S_OFFSET_BOFFSET 0 +#define WIN_RULE_CTL1_L2S_OFFSET_BLEN 5 +#define WIN_RULE_CTL1_L2S_OFFSET_FLAG HSL_RW + + + + + /* Trunk Hash Mode Register */ +#define TRUNK_HASH_MODE +#define TRUNK_HASH_MODE_OFFSET 0x0270 +#define TRUNK_HASH_MODE_E_LENGTH 4 +#define TRUNK_HASH_MODE_E_OFFSET 0x4 +#define TRUNK_HASH_MODE_NR_E 1 + +#define SIP_EN +#define TRUNK_HASH_MODE_SIP_EN_BOFFSET 3 +#define TRUNK_HASH_MODE_SIP_EN_BLEN 1 +#define TRUNK_HASH_MODE_SIP_EN_FLAG HSL_RW + +#define DIP_EN +#define TRUNK_HASH_MODE_DIP_EN_BOFFSET 2 +#define TRUNK_HASH_MODE_DIP_EN_BLEN 1 +#define TRUNK_HASH_MODE_DIP_EN_FLAG HSL_RW + +#define SA_EN +#define TRUNK_HASH_MODE_SA_EN_BOFFSET 1 +#define TRUNK_HASH_MODE_SA_EN_BLEN 1 +#define TRUNK_HASH_MODE_SA_EN_FLAG HSL_RW + +#define DA_EN +#define TRUNK_HASH_MODE_DA_EN_BOFFSET 0 +#define TRUNK_HASH_MODE_DA_EN_BLEN 1 +#define TRUNK_HASH_MODE_DA_EN_FLAG HSL_RW + + + + + /* Vlan Table Function0 Register */ +#define VLAN_TABLE_FUNC0 +#define VLAN_TABLE_FUNC0_OFFSET 0x0610 +#define VLAN_TABLE_FUNC0_E_LENGTH 4 +#define VLAN_TABLE_FUNC0_E_OFFSET 0 +#define VLAN_TABLE_FUNC0_NR_E 1 + +#define VT_VALID +#define VLAN_TABLE_FUNC0_VT_VALID_BOFFSET 20 +#define VLAN_TABLE_FUNC0_VT_VALID_BLEN 1 +#define VLAN_TABLE_FUNC0_VT_VALID_FLAG HSL_RW + +#define IVL_EN +#define VLAN_TABLE_FUNC0_IVL_EN_BOFFSET 19 +#define VLAN_TABLE_FUNC0_IVL_EN_BLEN 1 +#define VLAN_TABLE_FUNC0_IVL_EN_FLAG HSL_RW + +#define LEARN_DIS +#define VLAN_TABLE_FUNC0_LEARN_DIS_BOFFSET 18 +#define VLAN_TABLE_FUNC0_LEARN_DIS_BLEN 1 +#define VLAN_TABLE_FUNC0_LEARN_DIS_FLAG HSL_RW + +#define VID_MEM +#define VLAN_TABLE_FUNC0_VID_MEM_BOFFSET 4 +#define VLAN_TABLE_FUNC0_VID_MEM_BLEN 14 +#define VLAN_TABLE_FUNC0_VID_MEM_FLAG HSL_RW + +#define VT_PRI_EN +#define VLAN_TABLE_FUNC0_VT_PRI_EN_BOFFSET 3 +#define VLAN_TABLE_FUNC0_VT_PRI_EN_BLEN 1 +#define VLAN_TABLE_FUNC0_VT_PRI_EN_FLAG HSL_RW + +#define VT_PRI +#define VLAN_TABLE_FUNC0_VT_PRI_BOFFSET 0 +#define VLAN_TABLE_FUNC0_VT_PRI_BLEN 3 +#define VLAN_TABLE_FUNC0_VT_PRI_FLAG HSL_RW + + /* Vlan Table Function1 Register */ +#define VLAN_TABLE_FUNC1 +#define VLAN_TABLE_FUNC1_OFFSET 0x0614 +#define VLAN_TABLE_FUNC1_E_LENGTH 4 +#define VLAN_TABLE_FUNC1_E_OFFSET 0 +#define VLAN_TABLE_FUNC1_NR_E 1 + +#define VT_BUSY +#define VLAN_TABLE_FUNC1_VT_BUSY_BOFFSET 31 +#define VLAN_TABLE_FUNC1_VT_BUSY_BLEN 1 +#define VLAN_TABLE_FUNC1_VT_BUSY_FLAG HSL_RW + +#define VLAN_ID +#define VLAN_TABLE_FUNC1_VLAN_ID_BOFFSET 16 +#define VLAN_TABLE_FUNC1_VLAN_ID_BLEN 12 +#define VLAN_TABLE_FUNC1_VLAN_ID_FLAG HSL_RW + +#define VT_PORT_NUM +#define VLAN_TABLE_FUNC1_VT_PORT_NUM_BOFFSET 8 +#define VLAN_TABLE_FUNC1_VT_PORT_NUM_BLEN 4 +#define VLAN_TABLE_FUNC1_VT_PORT_NUM_FLAG HSL_RW + +#define VT_FULL_VIO +#define VLAN_TABLE_FUNC1_VT_FULL_VIO_BOFFSET 4 +#define VLAN_TABLE_FUNC1_VT_FULL_VIO_BLEN 1 +#define VLAN_TABLE_FUNC1_VT_FULL_VIO_FLAG HSL_RW + +#define VT_FUNC +#define VLAN_TABLE_FUNC1_VT_FUNC_BOFFSET 0 +#define VLAN_TABLE_FUNC1_VT_FUNC_BLEN 3 +#define VLAN_TABLE_FUNC1_VT_FUNC_FLAG HSL_RW + + + + + /* Address Table Function0 Register */ +#define ADDR_TABLE_FUNC0 +#define ADDR_TABLE_FUNC0_OFFSET 0x0600 +#define ADDR_TABLE_FUNC0_E_LENGTH 4 +#define ADDR_TABLE_FUNC0_E_OFFSET 0 +#define ADDR_TABLE_FUNC0_NR_E 1 + + +#define AT_ADDR_BYTE2 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE2_BOFFSET 24 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE2_BLEN 8 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE2_FLAG HSL_RW + +#define AT_ADDR_BYTE3 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE3_BOFFSET 16 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE3_BLEN 8 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE3_FLAG HSL_RW + +#define AT_ADDR_BYTE4 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE4_BOFFSET 8 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE4_BLEN 8 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE4_FLAG HSL_RW + +#define AT_ADDR_BYTE5 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE5_BOFFSET 0 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE5_BLEN 8 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE5_FLAG HSL_RW + + /* Address Table Function1 Register */ +#define ADDR_TABLE_FUNC1 +#define ADDR_TABLE_FUNC1_OFFSET 0x0604 +#define ADDR_TABLE_FUNC1_E_LENGTH 4 +#define ADDR_TABLE_FUNC1_E_OFFSET 0 +#define ADDR_TABLE_FUNC1_NR_E 1 + +#define SA_DROP_EN +#define ADDR_TABLE_FUNC1_SA_DROP_EN_BOFFSET 30 +#define ADDR_TABLE_FUNC1_SA_DROP_EN_BLEN 1 +#define ADDR_TABLE_FUNC1_SA_DROP_EN_FLAG HSL_RW + +#define MIRROR_EN +#define ADDR_TABLE_FUNC1_MIRROR_EN_BOFFSET 29 +#define ADDR_TABLE_FUNC1_MIRROR_EN_BLEN 1 +#define ADDR_TABLE_FUNC1_MIRROR_EN_FLAG HSL_RW + +#define AT_PRI_EN +#define ADDR_TABLE_FUNC1_AT_PRI_EN_BOFFSET 28 +#define ADDR_TABLE_FUNC1_AT_PRI_EN_BLEN 1 +#define ADDR_TABLE_FUNC1_AT_PRI_EN_FLAG HSL_RW + +#define AT_SVL_EN +#define ADDR_TABLE_FUNC1_AT_SVL_EN_BOFFSET 27 +#define ADDR_TABLE_FUNC1_AT_SVL_EN_BLEN 1 +#define ADDR_TABLE_FUNC1_AT_SVL_EN_FLAG HSL_RW + +#define AT_PRI +#define ADDR_TABLE_FUNC1_AT_PRI_BOFFSET 24 +#define ADDR_TABLE_FUNC1_AT_PRI_BLEN 3 +#define ADDR_TABLE_FUNC1_AT_PRI_FLAG HSL_RW + +#define CROSS_PT +#define ADDR_TABLE_FUNC1_CROSS_PT_BOFFSET 23 +#define ADDR_TABLE_FUNC1_CROSS_PT_BLEN 1 +#define ADDR_TABLE_FUNC1_CROSS_PT_FLAG HSL_RW + +#define DES_PORT +#define ADDR_TABLE_FUNC1_DES_PORT_BOFFSET 16 +#define ADDR_TABLE_FUNC1_DES_PORT_BLEN 7 +#define ADDR_TABLE_FUNC1_DES_PORT_FLAG HSL_RW + +#define AT_ADDR_BYTE0 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE0_BOFFSET 8 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE0_BLEN 8 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE0_FLAG HSL_RW + +#define AT_ADDR_BYTE1 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE1_BOFFSET 0 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE1_BLEN 8 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE1_FLAG HSL_RW + + /* Address Table Function2 Register */ +#define ADDR_TABLE_FUNC2 +#define ADDR_TABLE_FUNC2_OFFSET 0x0608 +#define ADDR_TABLE_FUNC2_E_LENGTH 4 +#define ADDR_TABLE_FUNC2_E_OFFSET 0 +#define ADDR_TABLE_FUNC2_NR_E 1 + +#define WL_EN +#define ADDR_TABLE_FUNC2_WL_EN_BOFFSET 20 +#define ADDR_TABLE_FUNC2_WL_EN_BLEN 1 +#define ADDR_TABLE_FUNC2_WL_EN_FLAG HSL_RW + +#define AT_VID +#define ADDR_TABLE_FUNC2_AT_VID_BOFFSET 8 +#define ADDR_TABLE_FUNC2_AT_VID_BLEN 12 +#define ADDR_TABLE_FUNC2_AT_VID_FLAG HSL_RW + +#define SHORT_LOOP +#define ADDR_TABLE_FUNC2_SHORT_LOOP_BOFFSET 7 +#define ADDR_TABLE_FUNC2_SHORT_LOOP_BLEN 1 +#define ADDR_TABLE_FUNC2_SHORT_LOOP_FLAG HSL_RW + +#define COPY_TO_CPU +#define ADDR_TABLE_FUNC2_COPY_TO_CPU_BOFFSET 6 +#define ADDR_TABLE_FUNC2_COPY_TO_CPU_BLEN 1 +#define ADDR_TABLE_FUNC2_COPY_TO_CPU_FLAG HSL_RW + +#define REDRCT_TO_CPU +#define ADDR_TABLE_FUNC2_REDRCT_TO_CPU_BOFFSET 5 +#define ADDR_TABLE_FUNC2_REDRCT_TO_CPU_BLEN 1 +#define ADDR_TABLE_FUNC2_REDRCT_TO_CPU_FLAG HSL_RW + +#define LEAKY_EN +#define ADDR_TABLE_FUNC2_LEAKY_EN_BOFFSET 4 +#define ADDR_TABLE_FUNC2_LEAKY_EN_BLEN 1 +#define ADDR_TABLE_FUNC2_LEAKY_EN_FLAG HSL_RW + +#define AT_STATUS +#define ADDR_TABLE_FUNC2_AT_STATUS_BOFFSET 0 +#define ADDR_TABLE_FUNC2_AT_STATUS_BLEN 4 +#define ADDR_TABLE_FUNC2_AT_STATUS_FLAG HSL_RW + + /* Address Table Function3 Register */ +#define ADDR_TABLE_FUNC3 +#define ADDR_TABLE_FUNC3_OFFSET 0x060c +#define ADDR_TABLE_FUNC3_E_LENGTH 4 +#define ADDR_TABLE_FUNC3_E_OFFSET 0 +#define ADDR_TABLE_FUNC3_NR_E 1 + +#define AT_BUSY +#define ADDR_TABLE_FUNC3_AT_BUSY_BOFFSET 31 +#define ADDR_TABLE_FUNC3_AT_BUSY_BLEN 1 +#define ADDR_TABLE_FUNC3_AT_BUSY_FLAG HSL_RW + +#define NEW_PORT_NUM +#define ADDR_TABLE_FUNC3_NEW_PORT_NUM_BOFFSET 22 +#define ADDR_TABLE_FUNC3_NEW_PORT_NUM_BLEN 3 +#define ADDR_TABLE_FUNC3_NEW_PORT_NUM_FLAG HSL_RW + +#define AT_INDEX +#define ADDR_TABLE_FUNC3_AT_INDEX_BOFFSET 16 +#define ADDR_TABLE_FUNC3_AT_INDEX_BLEN 5 +#define ADDR_TABLE_FUNC3_AT_INDEX_FLAG HSL_RW + +#define AT_VID_EN +#define ADDR_TABLE_FUNC3_AT_VID_EN_BOFFSET 15 +#define ADDR_TABLE_FUNC3_AT_VID_EN_BLEN 1 +#define ADDR_TABLE_FUNC3_AT_VID_EN_FLAG HSL_RW + +#define AT_PORT_EN +#define ADDR_TABLE_FUNC3_AT_PORT_EN_BOFFSET 14 +#define ADDR_TABLE_FUNC3_AT_PORT_EN_BLEN 1 +#define ADDR_TABLE_FUNC3_AT_PORT_EN_FLAG HSL_RW + +#define AT_MULTI_EN +#define ADDR_TABLE_FUNC3_AT_MULTI_EN_BOFFSET 13 +#define ADDR_TABLE_FUNC3_AT_MULTI_EN_BLEN 1 +#define ADDR_TABLE_FUNC3_AT_MULTI_EN_FLAG HSL_RW + +#define AT_FULL_VIO +#define ADDR_TABLE_FUNC3_AT_FULL_VIO_BOFFSET 12 +#define ADDR_TABLE_FUNC3_AT_FULL_VIO_BLEN 1 +#define ADDR_TABLE_FUNC3_AT_FULL_VIO_FLAG HSL_RW + +#define AT_PORT_NUM +#define ADDR_TABLE_FUNC3_AT_PORT_NUM_BOFFSET 8 +#define ADDR_TABLE_FUNC3_AT_PORT_NUM_BLEN 4 +#define ADDR_TABLE_FUNC3_AT_PORT_NUM_FLAG HSL_RW + +#define FLUSH_ST_EN +#define ADDR_TABLE_FUNC3_FLUSH_ST_EN_BOFFSET 4 +#define ADDR_TABLE_FUNC3_FLUSH_ST_EN_BLEN 1 +#define ADDR_TABLE_FUNC3_FLUSH_ST_EN_FLAG HSL_RW + +#define AT_FUNC +#define ADDR_TABLE_FUNC3_AT_FUNC_BOFFSET 0 +#define ADDR_TABLE_FUNC3_AT_FUNC_BLEN 4 +#define ADDR_TABLE_FUNC3_AT_FUNC_FLAG HSL_RW + + + + + /* Reserve Address Table0 Register */ +#define RESV_ADDR_TBL0 +#define RESV_ADDR_TBL0_OFFSET 0x3c000 +#define RESV_ADDR_TBL0_E_LENGTH 4 +#define RESV_ADDR_TBL0_E_OFFSET 0 +#define RESV_ADDR_TBL0_NR_E 1 + +#define RESV_ADDR_BYTE2 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE2_BOFFSET 24 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE2_BLEN 8 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE2_FLAG HSL_RW + +#define RESV_ADDR_BYTE3 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE3_BOFFSET 16 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE3_BLEN 8 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE3_FLAG HSL_RW + +#define RESV_ADDR_BYTE4 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE4_BOFFSET 8 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE4_BLEN 8 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE4_FLAG HSL_RW + +#define RESV_ADDR_BYTE5 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE5_BOFFSET 0 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE5_BLEN 8 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE5_FLAG HSL_RW + + /* Reserve Address Table1 Register */ +#define RESV_ADDR_TBL1 +#define RESV_ADDR_TBL1_OFFSET 0x3c004 +#define RESV_ADDR_TBL1_E_LENGTH 4 +#define RESV_ADDR_TBL1_E_OFFSET 0 +#define RESV_ADDR_TBL1_NR_E 1 + +#define RESV_COPY_TO_CPU +#define RESV_ADDR_TBL1_RESV_COPY_TO_CPU_BOFFSET 31 +#define RESV_ADDR_TBL1_RESV_COPY_TO_CPU_BLEN 1 +#define RESV_ADDR_TBL1_RESV_COPY_TO_CPU_FLAG HSL_RW + +#define RESV_REDRCT_TO_CPU +#define RESV_ADDR_TBL1_RESV_REDRCT_TO_CPU_BOFFSET 30 +#define RESV_ADDR_TBL1_RESV_REDRCT_TO_CPU_BLEN 1 +#define RESV_ADDR_TBL1_RESV_REDRCT_TO_CPU_FLAG HSL_RW + +#define RESV_LEAKY_EN +#define RESV_ADDR_TBL1_RESV_LEAKY_EN_BOFFSET 29 +#define RESV_ADDR_TBL1_RESV_LEAKY_EN_BLEN 1 +#define RESV_ADDR_TBL1_RESV_LEAKY_EN_FLAG HSL_RW + +#define RESV_MIRROR_EN +#define RESV_ADDR_TBL1_RESV_MIRROR_EN_BOFFSET 28 +#define RESV_ADDR_TBL1_RESV_MIRROR_EN_BLEN 1 +#define RESV_ADDR_TBL1_RESV_MIRROR_EN_FLAG HSL_RW + +#define RESV_PRI_EN +#define RESV_ADDR_TBL1_RESV_PRI_EN_BOFFSET 27 +#define RESV_ADDR_TBL1_RESV_PRI_EN_BLEN 1 +#define RESV_ADDR_TBL1_RESV_PRI_EN_FLAG HSL_RW + +#define RESV_PRI +#define RESV_ADDR_TBL1_RESV_PRI_BOFFSET 24 +#define RESV_ADDR_TBL1_RESV_PRI_BLEN 3 +#define RESV_ADDR_TBL1_RESV_PRI_FLAG HSL_RW + +#define RESV_CROSS_PT +#define RESV_ADDR_TBL1_RESV_CROSS_PT_BOFFSET 23 +#define RESV_ADDR_TBL1_RESV_CROSS_PT_BLEN 1 +#define RESV_ADDR_TBL1_RESV_CROSS_PT_FLAG HSL_RW + +#define RESV_DES_PORT +#define RESV_ADDR_TBL1_RESV_DES_PORT_BOFFSET 16 +#define RESV_ADDR_TBL1_RESV_DES_PORT_BLEN 7 +#define RESV_ADDR_TBL1_RESV_DES_PORT_FLAG HSL_RW + +#define RESV_ADDR_BYTE0 +#define RESV_ADDR_TBL1_RESV_ADDR_BYTE0_BOFFSET 8 +#define RESV_ADDR_TBL1_RESV_ADDR_BYTE0_BLEN 8 +#define RESV_ADDR_TBL1_RESV_ADDR_BYTE0_FLAG HSL_RW + +#define RESV_ADDR_BYTE1 +#define RESV_ADDR_TBL1_RESV_ADDR_BYTE1_BOFFSET 0 +#define RESV_ADDR_TBL1_RESV_ADDR_BYTE1_BLEN 8 +#define RESV_ADDR_TBL1_RESV_ADDR_BYTE1_FLAG HSL_RW + + /* Reserve Address Table2 Register */ +#define RESV_ADDR_TBL2 +#define RESV_ADDR_TBL2_OFFSET 0x3c008 +#define RESV_ADDR_TBL2_E_LENGTH 4 +#define RESV_ADDR_TBL2_E_OFFSET 0 +#define RESV_ADDR_TBL2_NR_E 1 + +#define RESV_STATUS +#define RESV_ADDR_TBL2_RESV_STATUS_BOFFSET 0 +#define RESV_ADDR_TBL2_RESV_STATUS_BLEN 1 +#define RESV_ADDR_TBL2_RESV_STATUS_FLAG HSL_RW + + + + + /* Address Table Control Register */ +#define ADDR_TABLE_CTL +#define ADDR_TABLE_CTL_OFFSET 0x0618 +#define ADDR_TABLE_CTL_E_LENGTH 4 +#define ADDR_TABLE_CTL_E_OFFSET 0 +#define ADDR_TABLE_CTL_NR_E 1 + +#define ARL_INI_EN +#define ADDR_TABLE_CTL_ARL_INI_EN_BOFFSET 31 +#define ADDR_TABLE_CTL_ARL_INI_EN_BLEN 1 +#define ADDR_TABLE_CTL_ARL_INI_EN_FLAG HSL_RW + +#define LEARN_CHANGE_EN +#define ADDR_TABLE_CTL_LEARN_CHANGE_EN_BOFFSET 30 +#define ADDR_TABLE_CTL_LEARN_CHANGE_EN_BLEN 1 +#define ADDR_TABLE_CTL_LEARN_CHANGE_EN_FLAG HSL_RW + +#define IGMP_JOIN_LEAKY +#define ADDR_TABLE_CTL_IGMP_JOIN_LEAKY_BOFFSET 29 +#define ADDR_TABLE_CTL_IGMP_JOIN_LEAKY_BLEN 1 +#define ADDR_TABLE_CTL_IGMP_JOIN_LEAKY_FLAG HSL_RW + +#define IGMP_CREAT_EN +#define ADDR_TABLE_CTL_IGMP_CREAT_EN_BOFFSET 28 +#define ADDR_TABLE_CTL_IGMP_CREAT_EN_BLEN 1 +#define ADDR_TABLE_CTL_IGMP_CREAT_EN_FLAG HSL_RW + +#define IGMP_PRI_EN +#define ADDR_TABLE_CTL_IGMP_PRI_EN_BOFFSET 27 +#define ADDR_TABLE_CTL_IGMP_PRI_EN_BLEN 1 +#define ADDR_TABLE_CTL_IGMP_PRI_EN_FLAG HSL_RW + +#define IGMP_PRI +#define ADDR_TABLE_CTL_IGMP_PRI_BOFFSET 24 +#define ADDR_TABLE_CTL_IGMP_PRI_BLEN 3 +#define ADDR_TABLE_CTL_IGMP_PRI_FLAG HSL_RW + +#define IGMP_JOIN_STATIC +#define ADDR_TABLE_CTL_IGMP_JOIN_STATIC_BOFFSET 20 +#define ADDR_TABLE_CTL_IGMP_JOIN_STATIC_BLEN 4 +#define ADDR_TABLE_CTL_IGMP_JOIN_STATIC_FLAG HSL_RW + +#define AGE_EN +#define ADDR_TABLE_CTL_AGE_EN_BOFFSET 19 +#define ADDR_TABLE_CTL_AGE_EN_BLEN 1 +#define ADDR_TABLE_CTL_AGE_EN_FLAG HSL_RW + +#define LOOP_CHECK_TIMER +#define ADDR_TABLE_CTL_LOOP_CHECK_TIMER_BOFFSET 16 +#define ADDR_TABLE_CTL_LOOP_CHECK_TIMER_BLEN 3 +#define ADDR_TABLE_CTL_LOOP_CHECK_TIMER_FLAG HSL_RW + +#define AGE_TIME +#define ADDR_TABLE_CTL_AGE_TIME_BOFFSET 0 +#define ADDR_TABLE_CTL_AGE_TIME_BLEN 16 +#define ADDR_TABLE_CTL_AGE_TIME_FLAG HSL_RW + + + + + /* Global Forward Control0 Register */ +#define FORWARD_CTL0 +#define FORWARD_CTL0_OFFSET 0x0620 +#define FORWARD_CTL0_E_LENGTH 4 +#define FORWARD_CTL0_E_OFFSET 0 +#define FORWARD_CTL0_NR_E 1 + +#define ARP_CMD +#define FORWARD_CTL0_ARP_CMD_BOFFSET 26 +#define FORWARD_CTL0_ARP_CMD_BLEN 2 +#define FORWARD_CTL0_ARP_CMD_FLAG HSL_RW + +#define IP_NOT_FOUND +#define FORWARD_CTL0_IP_NOT_FOUND_BOFFSET 24 +#define FORWARD_CTL0_IP_NOT_FOUND_BLEN 2 +#define FORWARD_CTL0_IP_NOT_FOUND_FLAG HSL_RW + +#define ARP_NOT_FOUND +#define FORWARD_CTL0_ARP_NOT_FOUND_BOFFSET 22 +#define FORWARD_CTL0_ARP_NOT_FOUND_BLEN 2 +#define FORWARD_CTL0_ARP_NOT_FOUND_FLAG HSL_RW + +#define HASH_MODE +#define FORWARD_CTL0_HASH_MODE_BOFFSET 20 +#define FORWARD_CTL0_HASH_MODE_BLEN 2 +#define FORWARD_CTL0_HASH_MODE_FLAG HSL_RW + +#define NAT_NOT_FOUND_DROP +#define FORWARD_CTL0_NAT_NOT_FOUND_DROP_BOFFSET 17 +#define FORWARD_CTL0_NAT_NOT_FOUND_DROP_BLEN 1 +#define FORWARD_CTL0_NAT_NOT_FOUND_DROP_FLAG HSL_RW + +#define SP_NOT_FOUND_DROP +#define FORWARD_CTL0_SP_NOT_FOUND_DROP_BOFFSET 16 +#define FORWARD_CTL0_SP_NOT_FOUND_DROP_BLEN 1 +#define FORWARD_CTL0_SP_NOT_FOUND_DROP_FLAG HSL_RW + +#define IGMP_LEAVE_DROP +#define FORWARD_CTL0_IGMP_LEAVE_DROP_BOFFSET 14 +#define FORWARD_CTL0_IGMP_LEAVE_DROP_BLEN 1 +#define FORWARD_CTL0_IGMP_LEAVE_DROP_FLAG HSL_RW + +#define ARL_UNI_LEAKY +#define FORWARD_CTL0_ARL_UNI_LEAKY_BOFFSET 13 +#define FORWARD_CTL0_ARL_UNI_LEAKY_BLEN 1 +#define FORWARD_CTL0_ARL_UNI_LEAKY_FLAG HSL_RW + +#define ARL_MUL_LEAKY +#define FORWARD_CTL0_ARL_MUL_LEAKY_BOFFSET 12 +#define FORWARD_CTL0_ARL_MUL_LEAKY_BLEN 1 +#define FORWARD_CTL0_ARL_MUL_LEAKY_FLAG HSL_RW + +#define MANAGE_VID_VIO_DROP_EN +#define FORWARD_CTL0_MANAGE_VID_VIO_DROP_EN_BOFFSET 11 +#define FORWARD_CTL0_MANAGE_VID_VIO_DROP_EN_BLEN 1 +#define FORWARD_CTL0_MANAGE_VID_VIO_DROP_EN_FLAG HSL_RW + +#define CPU_PORT_EN +#define FORWARD_CTL0_CPU_PORT_EN_BOFFSET 10 +#define FORWARD_CTL0_CPU_PORT_EN_BLEN 1 +#define FORWARD_CTL0_CPU_PORT_EN_FLAG HSL_RW + +#define PPPOE_RDT_EN +#define FORWARD_CTL0_PPPOE_RDT_EN_BOFFSET 8 +#define FORWARD_CTL0_PPPOE_RDT_EN_BLEN 1 +#define FORWARD_CTL0_PPPOE_RDT_EN_FLAG HSL_RW + +#define MIRROR_PORT_NUM +#define FORWARD_CTL0_MIRROR_PORT_NUM_BOFFSET 4 +#define FORWARD_CTL0_MIRROR_PORT_NUM_BLEN 4 +#define FORWARD_CTL0_MIRROR_PORT_NUM_FLAG HSL_RW + +#define IGMP_COPY_EN +#define FORWARD_CTL0_IGMP_COPY_EN_BOFFSET 3 +#define FORWARD_CTL0_IGMP_COPY_EN_BLEN 1 +#define FORWARD_CTL0_IGMP_COPY_EN_FLAG HSL_RW + +#define RIP_CPY_EN +#define FORWARD_CTL0_RIP_CPY_EN_BOFFSET 2 +#define FORWARD_CTL0_RIP_CPY_EN_BLEN 1 +#define FORWARD_CTL0_RIP_CPY_EN_FLAG HSL_RW + +#define EAPOL_CMD +#define FORWARD_CTL0_EAPOL_CMD_BOFFSET 0 +#define FORWARD_CTL0_EAPOL_CMD_BLEN 1 +#define FORWARD_CTL0_EAPOL_CMD_FLAG HSL_RW + + /* Global Forward Control1 Register */ +#define FORWARD_CTL1 +#define FORWARD_CTL1_OFFSET 0x0624 +#define FORWARD_CTL1_E_LENGTH 4 +#define FORWARD_CTL1_E_OFFSET 0 +#define FORWARD_CTL1_NR_E 1 + +#define IGMP_DP +#define FORWARD_CTL1_IGMP_DP_BOFFSET 24 +#define FORWARD_CTL1_IGMP_DP_BLEN 7 +#define FORWARD_CTL1_IGMP_DP_FLAG HSL_RW + +#define BC_FLOOD_DP +#define FORWARD_CTL1_BC_FLOOD_DP_BOFFSET 16 +#define FORWARD_CTL1_BC_FLOOD_DP_BLEN 7 +#define FORWARD_CTL1_BC_FLOOD_DP_FLAG HSL_RW + +#define MUL_FLOOD_DP +#define FORWARD_CTL1_MUL_FLOOD_DP_BOFFSET 8 +#define FORWARD_CTL1_MUL_FLOOD_DP_BLEN 7 +#define FORWARD_CTL1_MUL_FLOOD_DP_FLAG HSL_RW + +#define UNI_FLOOD_DP +#define FORWARD_CTL1_UNI_FLOOD_DP_BOFFSET 0 +#define FORWARD_CTL1_UNI_FLOOD_DP_BLEN 7 +#define FORWARD_CTL1_UNI_FLOOD_DP_FLAG HSL_RW + + + + + /* Global Learn Limit Ctl Register */ +#define GLOBAL_LEARN_LIMIT_CTL +#define GLOBAL_LEARN_LIMIT_CTL_OFFSET 0x0628 +#define GLOBAL_LEARN_LIMIT_CTL_E_LENGTH 4 +#define GLOBAL_LEARN_LIMIT_CTL_E_OFFSET 0 +#define GLOBAL_LEARN_LIMIT_CTL_NR_E 1 + +#define GOL_SA_LEARN_LIMIT_EN +#define GLOBAL_LEARN_LIMIT_CTL_GOL_SA_LEARN_LIMIT_EN_BOFFSET 12 +#define GLOBAL_LEARN_LIMIT_CTL_GOL_SA_LEARN_LIMIT_EN_BLEN 1 +#define GLOBAL_LEARN_LIMIT_CTL_GOL_SA_LEARN_LIMIT_EN_FLAG HSL_RW + +#define GOL_SA_LEARN_LIMIT_DROP_EN +#define GLOBAL_LEARN_LIMIT_CTL_GOL_SA_LEARN_LIMIT_DROP_EN_BOFFSET 11 +#define GLOBAL_LEARN_LIMIT_CTL_GOL_SA_LEARN_LIMIT_DROP_EN_BLEN 1 +#define GLOBAL_LEARN_LIMIT_CTL_GOL_SA_LEARN_LIMIT_DROP_EN_FLAG HSL_RW + +#define GOL_SA_LEARN_CNT +#define GLOBAL_LEARN_LIMIT_CTL_GOL_SA_LEARN_CNT_BOFFSET 0 +#define GLOBAL_LEARN_LIMIT_CTL_GOL_SA_LEARN_CNT_BLEN 11 +#define GLOBAL_LEARN_LIMIT_CTL_GOL_SA_LEARN_CNT_FLAG HSL_RW + + + + + /* DSCP To Priority Register */ +#define DSCP_TO_PRI +#define DSCP_TO_PRI_OFFSET 0x0630 +#define DSCP_TO_PRI_E_LENGTH 4 +#define DSCP_TO_PRI_E_OFFSET 0x0004 +#define DSCP_TO_PRI_NR_E 8 + + + + + /* UP To Priority Register */ +#define UP_TO_PRI +#define UP_TO_PRI_OFFSET 0x0650 +#define UP_TO_PRI_E_LENGTH 4 +#define UP_TO_PRI_E_OFFSET 0x0004 +#define UP_TO_PRI_NR_E 1 + + + + + /* Port Lookup control Register */ +#define PORT_LOOKUP_CTL +#define PORT_LOOKUP_CTL_OFFSET 0x0660 +#define PORT_LOOKUP_CTL_E_LENGTH 4 +#define PORT_LOOKUP_CTL_E_OFFSET 0x000c +#define PORT_LOOKUP_CTL_NR_E 7 + +#define MULTI_DROP_EN +#define PORT_LOOKUP_CTL_MULTI_DROP_EN_BOFFSET 31 +#define PORT_LOOKUP_CTL_MULTI_DROP_EN_BLEN 1 +#define PORT_LOOKUP_CTL_MULTI_DROP_EN_FLAG HSL_RW + +#define UNI_LEAKY_EN +#define PORT_LOOKUP_CTL_UNI_LEAKY_EN_BOFFSET 28 +#define PORT_LOOKUP_CTL_UNI_LEAKY_EN_BLEN 1 +#define PORT_LOOKUP_CTL_UNI_LEAKY_EN_FLAG HSL_RW + +#define MUL_LEAKY_EN +#define PORT_LOOKUP_CTL_MUL_LEAKY_EN_BOFFSET 27 +#define PORT_LOOKUP_CTL_MUL_LEAKY_EN_BLEN 1 +#define PORT_LOOKUP_CTL_MUL_LEAKY_EN_FLAG HSL_RW + +#define ARP_LEAKY_EN +#define PORT_LOOKUP_CTL_ARP_LEAKY_EN_BOFFSET 26 +#define PORT_LOOKUP_CTL_ARP_LEAKY_EN_BLEN 1 +#define PORT_LOOKUP_CTL_ARP_LEAKY_EN_FLAG HSL_RW + +#define ING_MIRROR_EN +#define PORT_LOOKUP_CTL_ING_MIRROR_EN_BOFFSET 25 +#define PORT_LOOKUP_CTL_ING_MIRROR_EN_BLEN 1 +#define PORT_LOOKUP_CTL_ING_MIRROR_EN_FLAG HSL_RW + +#define PORT_LOOP_BACK +#define PORT_LOOKUP_CTL_PORT_LOOP_BACK_BOFFSET 21 +#define PORT_LOOKUP_CTL_PORT_LOOP_BACK_BLEN 1 +#define PORT_LOOKUP_CTL_PORT_LOOP_BACK_FLAG HSL_RW + +#define LEARN_EN +#define PORT_LOOKUP_CTL_LEARN_EN_BOFFSET 20 +#define PORT_LOOKUP_CTL_LEARN_EN_BLEN 1 +#define PORT_LOOKUP_CTL_LEARN_EN_FLAG HSL_RW + +#define PORT_STATE +#define PORT_LOOKUP_CTL_PORT_STATE_BOFFSET 16 +#define PORT_LOOKUP_CTL_PORT_STATE_BLEN 3 +#define PORT_LOOKUP_CTL_PORT_STATE_FLAG HSL_RW + +#define FORCE_PVLAN +#define PORT_LOOKUP_CTL_FORCE_PVLAN_BOFFSET 10 +#define PORT_LOOKUP_CTL_FORCE_PVLAN_BLEN 1 +#define PORT_LOOKUP_CTL_FORCE_PVLAN_FLAG HSL_RW + +#define DOT1Q_MODE +#define PORT_LOOKUP_CTL_DOT1Q_MODE_BOFFSET 8 +#define PORT_LOOKUP_CTL_DOT1Q_MODE_BLEN 2 +#define PORT_LOOKUP_CTL_DOT1Q_MODE_FLAG HSL_RW + +#define PORT_VID_MEM +#define PORT_LOOKUP_CTL_PORT_VID_MEM_BOFFSET 0 +#define PORT_LOOKUP_CTL_PORT_VID_MEM_BLEN 7 +#define PORT_LOOKUP_CTL_PORT_VID_MEM_FLAG HSL_RW + + + + + /* Priority Control Register */ +#define PRI_CTL +#define PRI_CTL_OFFSET 0x0664 +#define PRI_CTL_E_LENGTH 4 +#define PRI_CTL_E_OFFSET 0x000c +#define PRI_CTL_NR_E 7 + +#define EG_MAC_BASE_VLAN_EN +#define PRI_CTL_EG_MAC_BASE_VLAN_EN_BOFFSET 20 +#define PRI_CTL_EG_MAC_BASE_VLAN_EN_BLEN 1 +#define PRI_CTL_EG_MAC_BASE_VLAN_EN_FLAG HSL_RW + +#define DA_PRI_EN +#define PRI_CTL_DA_PRI_EN_BOFFSET 18 +#define PRI_CTL_DA_PRI_EN_BLEN 1 +#define PRI_CTL_DA_PRI_EN_FLAG HSL_RW + +#define VLAN_PRI_EN +#define PRI_CTL_VLAN_PRI_EN_BOFFSET 17 +#define PRI_CTL_VLAN_PRI_EN_BLEN 1 +#define PRI_CTL_VLAN_PRI_EN_FLAG HSL_RW + +#define IP_PRI_EN +#define PRI_CTL_IP_PRI_EN_BOFFSET 16 +#define PRI_CTL_IP_PRI_EN_BLEN 1 +#define PRI_CTL_IP_PRI_EN_FLAG HSL_RW + +#define DA_PRI_SEL +#define PRI_CTL_DA_PRI_SEL_BOFFSET 6 +#define PRI_CTL_DA_PRI_SEL_BLEN 2 +#define PRI_CTL_DA_PRI_SEL_FLAG HSL_RW + +#define VLAN_PRI_SEL +#define PRI_CTL_VLAN_PRI_SEL_BOFFSET 4 +#define PRI_CTL_VLAN_PRI_SEL_BLEN 2 +#define PRI_CTL_VLAN_PRI_SEL_FLAG HSL_RW + +#define IP_PRI_SEL +#define PRI_CTL_IP_PRI_SEL_BOFFSET 2 +#define PRI_CTL_IP_PRI_SEL_BLEN 2 +#define PRI_CTL_IP_PRI_SEL_FLAG HSL_RW + + + + /* Port Learn Limit Ctl Register */ +#define PORT_LEARN_LIMIT_CTL +#define PORT_LEARN_LIMIT_CTL_OFFSET 0x0668 +#define PORT_LEARN_LIMIT_CTL_E_LENGTH 4 +#define PORT_LEARN_LIMIT_CTL_E_OFFSET 0x000c +#define PORT_LEARN_LIMIT_CTL_NR_E 7 + +#define IGMP_JOIN_LIMIT_EN +#define PORT_LEARN_LIMIT_CTL_IGMP_JOIN_LIMIT_EN_BOFFSET 27 +#define PORT_LEARN_LIMIT_CTL_IGMP_JOIN_LIMIT_EN_BLEN 1 +#define PORT_LEARN_LIMIT_CTL_IGMP_JOIN_LIMIT_EN_FLAG HSL_RW + +#define IGMP_JOIN_LIMIT_DROP_EN +#define PORT_LEARN_LIMIT_CTL_IGMP_JOIN_LIMIT_DROP_EN_BOFFSET 26 +#define PORT_LEARN_LIMIT_CTL_IGMP_JOIN_LIMIT_DROP_EN_BLEN 1 +#define PORT_LEARN_LIMIT_CTL_IGMP_JOIN_LIMIT_DROP_EN_FLAG HSL_RW + +#define IGMP_JOIN_CNT +#define PORT_LEARN_LIMIT_CTL_IGMP_JOIN_CNT_BOFFSET 16 +#define PORT_LEARN_LIMIT_CTL_IGMP_JOIN_CNT_BLEN 10 +#define PORT_LEARN_LIMIT_CTL_IGMP_JOIN_CNT_FLAG HSL_RW + +#define SA_LEARN_STATUS +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_STATUS_BOFFSET 12 +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_STATUS_BLEN 4 +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_STATUS_FLAG HSL_RW + +#define SA_LEARN_LIMIT_EN +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_LIMIT_EN_BOFFSET 11 +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_LIMIT_EN_BLEN 1 +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_LIMIT_EN_FLAG HSL_RW + +#define SA_LEARN_LIMIT_DROP_EN +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_LIMIT_DROP_EN_BOFFSET 10 +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_LIMIT_DROP_EN_BLEN 1 +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_LIMIT_DROP_EN_FLAG HSL_RW + +#define SA_LEARN_CNT +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_CNT_BOFFSET 0 +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_CNT_BLEN 10 +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_CNT_FLAG HSL_RW + + + + /* Global Trunk Ctl0 Register */ +#define GOL_TRUNK_CTL0 +#define GOL_TRUNK_CTL0_OFFSET 0x0700 +#define GOL_TRUNK_CTL0_E_LENGTH 4 +#define GOL_TRUNK_CTL0_E_OFFSET 0x4 +#define GOL_TRUNK_CTL0_NR_E 1 + + + /* Global Trunk Ctl1 Register */ +#define GOL_TRUNK_CTL1 +#define GOL_TRUNK_CTL1_OFFSET 0x0704 +#define GOL_TRUNK_CTL1_E_LENGTH 4 +#define GOL_TRUNK_CTL1_E_OFFSET 0x4 +#define GOL_TRUNK_CTL1_NR_E 2 + + + + + /* Port vlan0 Register */ +#define PORT_VLAN0 +#define PORT_VLAN0_OFFSET 0x0420 +#define PORT_VLAN0_E_LENGTH 4 +#define PORT_VLAN0_E_OFFSET 0x0008 +#define PORT_VLAN0_NR_E 7 + +#define ING_CPRI +#define PORT_VLAN0_ING_CPRI_BOFFSET 29 +#define PORT_VLAN0_ING_CPRI_BLEN 3 +#define PORT_VLAN0_ING_CPRI_FLAG HSL_RW + +#define DEF_CVID +#define PORT_VLAN0_DEF_CVID_BOFFSET 16 +#define PORT_VLAN0_DEF_CVID_BLEN 12 +#define PORT_VLAN0_DEF_CVID_FLAG HSL_RW + +#define ING_SPRI +#define PORT_VLAN0_ING_SPRI_BOFFSET 13 +#define PORT_VLAN0_ING_SPRI_BLEN 3 +#define PORT_VLAN0_ING_SPRI_FLAG HSL_RW + +#define DEF_SVID +#define PORT_VLAN0_DEF_SVID_BOFFSET 0 +#define PORT_VLAN0_DEF_SVID_BLEN 12 +#define PORT_VLAN0_DEF_SVID_FLAG HSL_RW + + /* Port vlan1 Register */ +#define PORT_VLAN1 +#define PORT_VLAN1_OFFSET 0x0424 +#define PORT_VLAN1_E_LENGTH 4 +#define PORT_VLAN1_E_OFFSET 0x0008 +#define PORT_VLAN1_NR_E 7 + +#define EG_VLAN_MODE +#define PORT_VLAN1_EG_VLAN_MODE_BOFFSET 12 +#define PORT_VLAN1_EG_VLAN_MODE_BLEN 2 +#define PORT_VLAN1_EG_VLAN_MODE_FLAG HSL_RW + +#define VLAN_DIS +#define PORT_VLAN1_VLAN_DIS_BOFFSET 11 +#define PORT_VLAN1_VLAN_DIS_BLEN 1 +#define PORT_VLAN1_VLAN_DIS_FLAG HSL_RW + +#define SP_CHECK_EN +#define PORT_VLAN1_SP_CHECK_EN_BOFFSET 10 +#define PORT_VLAN1_SP_CHECK_EN_BLEN 1 +#define PORT_VLAN1_SP_CHECK_EN_FLAG HSL_RW + +#define COREP_EN +#define PORT_VLAN1_COREP_EN_BOFFSET 9 +#define PORT_VLAN1_COREP_EN_BLEN 1 +#define PORT_VLAN1_COREP_EN_FLAG HSL_RW + +#define FORCE_DEF_VID +#define PORT_VLAN1_FORCE_DEF_VID_BOFFSET 8 +#define PORT_VLAN1_FORCE_DEF_VID_BLEN 1 +#define PORT_VLAN1_FORCE_DEF_VID_FLAG HSL_RW + +#define TLS_EN +#define PORT_VLAN1_TLS_EN_BOFFSET 7 +#define PORT_VLAN1_TLS_EN_BLEN 1 +#define PORT_VLAN1_TLS_EN_FLAG HSL_RW + +#define PROPAGATION_EN +#define PORT_VLAN1_PROPAGATION_EN_BOFFSET 6 +#define PORT_VLAN1_PROPAGATION_EN_BLEN 1 +#define PORT_VLAN1_PROPAGATION_EN_FLAG HSL_RW + +#define CLONE +#define PORT_VLAN1_CLONE_BOFFSET 5 +#define PORT_VLAN1_CLONE_BLEN 1 +#define PORT_VLAN1_CLONE_FLAG HSL_RW + +#define PRI_PROPAGATION +#define PORT_VLAN1_PRI_PROPAGATION_BOFFSET 4 +#define PORT_VLAN1_PRI_PROPAGATION_BLEN 1 +#define PORT_VLAN1_VLAN_PRI_PROPAGATION_FLAG HSL_RW + +#define IN_VLAN_MODE +#define PORT_VLAN1_IN_VLAN_MODE_BOFFSET 2 +#define PORT_VLAN1_IN_VLAN_MODE_BLEN 2 +#define PORT_VLAN1_IN_VLAN_MODE_FLAG HSL_RW + + + /* Route Default VID Register */ +#define ROUTER_DEFV +#define ROUTER_DEFV_OFFSET 0x0c70 +#define ROUTER_DEFV_E_LENGTH 4 +#define ROUTER_DEFV_E_OFFSET 0x0004 +#define ROUTER_DEFV_NR_E 4 + + + /* Route Egress VLAN Mode Register */ +#define ROUTER_EG +#define ROUTER_EG_OFFSET 0x0c80 +#define ROUTER_EG_E_LENGTH 4 +#define ROUTER_EG_E_OFFSET 0x0004 +#define ROUTER_EG_NR_E 1 + + + + + /* Mdio control Register */ +#define MDIO_CTRL "mctrl" +#define MDIO_CTRL_ID 24 +#define MDIO_CTRL_OFFSET 0x0098 +#define MDIO_CTRL_E_LENGTH 4 +#define MDIO_CTRL_E_OFFSET 0 +#define MDIO_CTRL_NR_E 1 + +#define MSTER_EN "mctrl_msteren" +#define MDIO_CTRL_MSTER_EN_BOFFSET 30 +#define MDIO_CTRL_MSTER_EN_BLEN 1 +#define MDIO_CTRL_MSTER_EN_FLAG HSL_RW + +#define MSTER_EN "mctrl_msteren" +#define MDIO_CTRL_MSTER_EN_BOFFSET 30 +#define MDIO_CTRL_MSTER_EN_BLEN 1 +#define MDIO_CTRL_MSTER_EN_FLAG HSL_RW + +#define CMD "mctrl_cmd" +#define MDIO_CTRL_CMD_BOFFSET 27 +#define MDIO_CTRL_CMD_BLEN 1 +#define MDIO_CTRL_CMD_FLAG HSL_RW + +#define SUP_PRE "mctrl_spre" +#define MDIO_CTRL_SUP_PRE_BOFFSET 26 +#define MDIO_CTRL_SUP_PRE_BLEN 1 +#define MDIO_CTRL_SUP_PRE_FLAG HSL_RW + +#define PHY_ADDR "mctrl_phyaddr" +#define MDIO_CTRL_PHY_ADDR_BOFFSET 21 +#define MDIO_CTRL_PHY_ADDR_BLEN 5 +#define MDIO_CTRL_PHY_ADDR_FLAG HSL_RW + +#define REG_ADDR "mctrl_regaddr" +#define MDIO_CTRL_REG_ADDR_BOFFSET 16 +#define MDIO_CTRL_REG_ADDR_BLEN 5 +#define MDIO_CTRL_REG_ADDR_FLAG HSL_RW + +#define DATA "mctrl_data" +#define MDIO_CTRL_DATA_BOFFSET 0 +#define MDIO_CTRL_DATA_BLEN 16 +#define MDIO_CTRL_DATA_FLAG HSL_RW + + + + + /* BIST control Register */ +#define BIST_CTRL "bctrl" +#define BIST_CTRL_ID 24 +#define BIST_CTRL_OFFSET 0x00a0 +#define BIST_CTRL_E_LENGTH 4 +#define BIST_CTRL_E_OFFSET 0 +#define BIST_CTRL_NR_E 1 + +#define BIST_BUSY "bctrl_bb" +#define BIST_CTRL_BIST_BUSY_BOFFSET 31 +#define BIST_CTRL_BIST_BUSY_BLEN 1 +#define BIST_CTRL_BIST_BUSY_FLAG HSL_RW + +#define ONE_ERR "bctrl_oe" +#define BIST_CTRL_ONE_ERR_BOFFSET 30 +#define BIST_CTRL_ONE_ERR_BLEN 1 +#define BIST_CTRL_ONE_ERR_FLAG HSL_RO + +#define ERR_MEM "bctrl_em" +#define BIST_CTRL_ERR_MEM_BOFFSET 24 +#define BIST_CTRL_ERR_MEM_BLEN 4 +#define BIST_CTRL_ERR_MEM_FLAG HSL_RO + +#define PTN_EN2 "bctrl_pe2" +#define BIST_CTRL_PTN_EN2_BOFFSET 22 +#define BIST_CTRL_PTN_EN2_BLEN 1 +#define BIST_CTRL_PTN_EN2_FLAG HSL_RW + +#define PTN_EN1 "bctrl_pe1" +#define BIST_CTRL_PTN_EN1_BOFFSET 21 +#define BIST_CTRL_PTN_EN1_BLEN 1 +#define BIST_CTRL_PTN_EN1_FLAG HSL_RW + +#define PTN_EN0 "bctrl_pe0" +#define BIST_CTRL_PTN_EN0_BOFFSET 20 +#define BIST_CTRL_PTN_EN0_BLEN 1 +#define BIST_CTRL_PTN_EN0_FLAG HSL_RW + +#define ERR_PTN "bctrl_ep" +#define BIST_CTRL_ERR_PTN_BOFFSET 16 +#define BIST_CTRL_ERR_PTN_BLEN 2 +#define BIST_CTRL_ERR_PTN_FLAG HSL_RO + +#define ERR_CNT "bctrl_ec" +#define BIST_CTRL_ERR_CNT_BOFFSET 13 +#define BIST_CTRL_ERR_CNT_BLEN 2 +#define BIST_CTRL_ERR_CNT_FLAG HSL_RO + +#define ERR_ADDR "bctrl_ea" +#define BIST_CTRL_ERR_ADDR_BOFFSET 0 +#define BIST_CTRL_ERR_ADDR_BLEN 12 +#define BIST_CTRL_ERR_ADDR_FLAG HSL_RO + + + + + /* BIST recover Register */ +#define BIST_RCV "brcv" +#define BIST_RCV_ID 24 +#define BIST_RCV_OFFSET 0x00a4 +#define BIST_RCV_E_LENGTH 4 +#define BIST_RCV_E_OFFSET 0 +#define BIST_RCV_NR_E 1 + +#define RCV_EN "brcv_en" +#define BIST_RCV_RCV_EN_BOFFSET 31 +#define BIST_RCV_RCV_EN_BLEN 1 +#define BIST_RCV_RCV_EN_FLAG HSL_RW + +#define RCV_ADDR "brcv_addr" +#define BIST_RCV_RCV_ADDR_BOFFSET 0 +#define BIST_RCV_RCV_ADDR_BLEN 12 +#define BIST_RCV_RCV_ADDR_FLAG HSL_RW + + + + + /* LED control Register */ +#define LED_CTRL "ledctrl" +#define LED_CTRL_ID 25 +#define LED_CTRL_OFFSET 0x0050 +#define LED_CTRL_E_LENGTH 4 +#define LED_CTRL_E_OFFSET 0 +#define LED_CTRL_NR_E 3 + +#define PATTERN_EN "lctrl_pen" +#define LED_CTRL_PATTERN_EN_BOFFSET 14 +#define LED_CTRL_PATTERN_EN_BLEN 2 +#define LED_CTRL_PATTERN_EN_FLAG HSL_RW + +#define FULL_LIGHT_EN "lctrl_fen" +#define LED_CTRL_FULL_LIGHT_EN_BOFFSET 13 +#define LED_CTRL_FULL_LIGHT_EN_BLEN 1 +#define LED_CTRL_FULL_LIGHT_EN_FLAG HSL_RW + +#define HALF_LIGHT_EN "lctrl_hen" +#define LED_CTRL_HALF_LIGHT_EN_BOFFSET 12 +#define LED_CTRL_HALF_LIGHT_EN_BLEN 1 +#define LED_CTRL_HALF_LIGHT_EN_FLAG HSL_RW + +#define POWERON_LIGHT_EN "lctrl_poen" +#define LED_CTRL_POWERON_LIGHT_EN_BOFFSET 11 +#define LED_CTRL_POWERON_LIGHT_EN_BLEN 1 +#define LED_CTRL_POWERON_LIGHT_EN_FLAG HSL_RW + +#define GE_LIGHT_EN "lctrl_geen" +#define LED_CTRL_GE_LIGHT_EN_BOFFSET 10 +#define LED_CTRL_GE_LIGHT_EN_BLEN 1 +#define LED_CTRL_GE_LIGHT_EN_FLAG HSL_RW + +#define FE_LIGHT_EN "lctrl_feen" +#define LED_CTRL_FE_LIGHT_EN_BOFFSET 9 +#define LED_CTRL_FE_LIGHT_EN_BLEN 1 +#define LED_CTRL_FE_LIGHT_EN_FLAG HSL_RW + +#define ETH_LIGHT_EN "lctrl_ethen" +#define LED_CTRL_ETH_LIGHT_EN_BOFFSET 8 +#define LED_CTRL_ETH_LIGHT_EN_BLEN 1 +#define LED_CTRL_ETH_LIGHT_EN_FLAG HSL_RW + +#define COL_BLINK_EN "lctrl_cen" +#define LED_CTRL_COL_BLINK_EN_BOFFSET 7 +#define LED_CTRL_COL_BLINK_EN_BLEN 1 +#define LED_CTRL_COL_BLINK_EN_FLAG HSL_RW + +#define RX_BLINK_EN "lctrl_rxen" +#define LED_CTRL_RX_BLINK_EN_BOFFSET 5 +#define LED_CTRL_RX_BLINK_EN_BLEN 1 +#define LED_CTRL_RX_BLINK_EN_FLAG HSL_RW + +#define TX_BLINK_EN "lctrl_txen" +#define LED_CTRL_TX_BLINK_EN_BOFFSET 4 +#define LED_CTRL_TX_BLINK_EN_BLEN 1 +#define LED_CTRL_TX_BLINK_EN_FLAG HSL_RW + +#define LINKUP_OVER_EN "lctrl_loen" +#define LED_CTRL_LINKUP_OVER_EN_BOFFSET 2 +#define LED_CTRL_LINKUP_OVER_EN_BLEN 1 +#define LED_CTRL_LINKUP_OVER_EN_FLAG HSL_RW + +#define BLINK_FREQ "lctrl_bfreq" +#define LED_CTRL_BLINK_FREQ_BOFFSET 0 +#define LED_CTRL_BLINK_FREQ_BLEN 2 +#define LED_CTRL_BLINK_FREQ_FLAG HSL_RW + + /* LED control Register */ +#define LED_PATTERN "ledpatten" +#define LED_PATTERN_ID 25 +#define LED_PATTERN_OFFSET 0x005c +#define LED_PATTERN_E_LENGTH 4 +#define LED_PATTERN_E_OFFSET 0 +#define LED_PATTERN_NR_E 1 + + +#define P3L2_MODE +#define LED_PATTERN_P3L2_MODE_BOFFSET 24 +#define LED_PATTERN_P3L2_MODE_BLEN 2 +#define LED_PATTERN_P3L2_MODE_FLAG HSL_RW + +#define P3L1_MODE +#define LED_PATTERN_P3L1_MODE_BOFFSET 22 +#define LED_PATTERN_P3L1_MODE_BLEN 2 +#define LED_PATTERN_P3L1_MODE_FLAG HSL_RW + +#define P3L0_MODE +#define LED_PATTERN_P3L0_MODE_BOFFSET 20 +#define LED_PATTERN_P3L0_MODE_BLEN 2 +#define LED_PATTERN_P3L0_MODE_FLAG HSL_RW + +#define P2L2_MODE +#define LED_PATTERN_P2L2_MODE_BOFFSET 18 +#define LED_PATTERN_P2L2_MODE_BLEN 2 +#define LED_PATTERN_P2L2_MODE_FLAG HSL_RW + +#define P2L1_MODE +#define LED_PATTERN_P2L1_MODE_BOFFSET 16 +#define LED_PATTERN_P2L1_MODE_BLEN 2 +#define LED_PATTERN_P2L1_MODE_FLAG HSL_RW + +#define P2L0_MODE +#define LED_PATTERN_P2L0_MODE_BOFFSET 14 +#define LED_PATTERN_P2L0_MODE_BLEN 2 +#define LED_PATTERN_P2L0_MODE_FLAG HSL_RW + +#define P1L2_MODE +#define LED_PATTERN_P1L2_MODE_BOFFSET 12 +#define LED_PATTERN_P1L2_MODE_BLEN 2 +#define LED_PATTERN_P1L2_MODE_FLAG HSL_RW + +#define P1L1_MODE +#define LED_PATTERN_P1L1_MODE_BOFFSET 10 +#define LED_PATTERN_P1L1_MODE_BLEN 2 +#define LED_PATTERN_P1L1_MODE_FLAG HSL_RW + +#define P1L0_MODE +#define LED_PATTERN_P1L0_MODE_BOFFSET 8 +#define LED_PATTERN_P1L0_MODE_BLEN 2 +#define LED_PATTERN_P1L0_MODE_FLAG HSL_RW + + + + + /* Pri To Queue Register */ +#define PRI_TO_QUEUE +#define PRI_TO_QUEUE_OFFSET 0x0814 +#define PRI_TO_QUEUE_E_LENGTH 4 +#define PRI_TO_QUEUE_E_OFFSET 0x0004 +#define PRI_TO_QUEUE_NR_E 1 + + + + + /* Pri To EhQueue Register */ +#define PRI_TO_EHQUEUE +#define PRI_TO_EHQUEUE_OFFSET 0x0810 +#define PRI_TO_EHQUEUE_E_LENGTH 4 +#define PRI_TO_EHQUEUE_E_OFFSET 0x0004 +#define PRI_TO_EHQUEUE_NR_E 1 + + + + + /* Port HOL CTL0 Register */ +#define PORT_HOL_CTL0 +#define PORT_HOL_CTL0_OFFSET 0x0970 +#define PORT_HOL_CTL0_E_LENGTH 4 +#define PORT_HOL_CTL0_E_OFFSET 0x0008 +#define PORT_HOL_CTL0_NR_E 7 + +#define PORT_DESC_NR +#define PORT_HOL_CTL0_PORT_DESC_NR_BOFFSET 24 +#define PORT_HOL_CTL0_PORT_DESC_NR_BLEN 6 +#define PORT_HOL_CTL0_PORT_DESC_NR_FLAG HSL_RW + +#define QUEUE5_DESC_NR +#define PORT_HOL_CTL0_QUEUE5_DESC_NR_BOFFSET 20 +#define PORT_HOL_CTL0_QUEUE5_DESC_NR_BLEN 4 +#define PORT_HOL_CTL0_QUEUE5_DESC_NR_FLAG HSL_RW + +#define QUEUE4_DESC_NR +#define PORT_HOL_CTL0_QUEUE4_DESC_NR_BOFFSET 16 +#define PORT_HOL_CTL0_QUEUE4_DESC_NR_BLEN 4 +#define PORT_HOL_CTL0_QUEUE4_DESC_NR_FLAG HSL_RW + +#define QUEUE3_DESC_NR +#define PORT_HOL_CTL0_QUEUE3_DESC_NR_BOFFSET 12 +#define PORT_HOL_CTL0_QUEUE3_DESC_NR_BLEN 4 +#define PORT_HOL_CTL0_QUEUE3_DESC_NR_FLAG HSL_RW + +#define QUEUE2_DESC_NR +#define PORT_HOL_CTL0_QUEUE2_DESC_NR_BOFFSET 8 +#define PORT_HOL_CTL0_QUEUE2_DESC_NR_BLEN 4 +#define PORT_HOL_CTL0_QUEUE2_DESC_NR_FLAG HSL_RW + +#define QUEUE1_DESC_NR +#define PORT_HOL_CTL0_QUEUE1_DESC_NR_BOFFSET 4 +#define PORT_HOL_CTL0_QUEUE1_DESC_NR_BLEN 4 +#define PORT_HOL_CTL0_QUEUE1_DESC_NR_FLAG HSL_RW + +#define QUEUE0_DESC_NR +#define PORT_HOL_CTL0_QUEUE0_DESC_NR_BOFFSET 0 +#define PORT_HOL_CTL0_QUEUE0_DESC_NR_BLEN 4 +#define PORT_HOL_CTL0_QUEUE0_DESC_NR_FLAG HSL_RW + + /* Port HOL CTL1 Register */ +#define PORT_HOL_CTL1 +#define PORT_HOL_CTL1_OFFSET 0x0974 +#define PORT_HOL_CTL1_E_LENGTH 4 +#define PORT_HOL_CTL1_E_OFFSET 0x0008 +#define PORT_HOL_CTL1_NR_E 7 + +#define EG_MIRROR_EN +#define PORT_HOL_CTL1_EG_MIRROR_EN_BOFFSET 16 +#define PORT_HOL_CTL1_EG_MIRROR_EN_BLEN 1 +#define PORT_HOL_CTL1_EG_MIRROR_EN_FLAG HSL_RW + +#define PORT_DESC_EN +#define PORT_HOL_CTL1_PORT_DESC_EN_BOFFSET 7 +#define PORT_HOL_CTL1_PORT_DESC_EN_BLEN 1 +#define PORT_HOL_CTL1_PORT_DESC_EN_FLAG HSL_RW + +#define QUEUE_DESC_EN +#define PORT_HOL_CTL1_QUEUE_DESC_EN_BOFFSET 6 +#define PORT_HOL_CTL1_QUEUE_DESC_EN_BLEN 1 +#define PORT_HOL_CTL1_QUEUE_DESC_EN_FLAG HSL_RW + +#define PORT_IN_DESC_EN +#define PORT_HOL_CTL1_PORT_IN_DESC_EN_BOFFSET 0 +#define PORT_HOL_CTL1_PORT_IN_DESC_EN_BLEN 4 +#define PORT_HOL_CTL1_PORT_IN_DESC_EN_FLAG HSL_RW + + /* PORT FLOW CTRL THRESHOLD REGISTER */ +#define PORT_FLOW_CTRL_THRESHOLD +#define PORT_FLOW_CTRL_THRESHOLD_OFFSET 0x09B0 +#define PORT_FLOW_CTRL_THRESHOLD_E_LENGTH 4 +#define PORT_FLOW_CTRL_THRESHOLD_E_OFFSET 0x0004 +#define PORT_FLOW_CTRL_THRESHOLD_NR_E 7 + +#define XON_THRES +#define PORT_FLOW_CTRL_THRESHOLD_XON_THRES_BOFFSET 16 +#define PORT_FLOW_CTRL_THRESHOLD_XON_THRES_BLEN 8 +#define PORT_FLOW_CTRL_THRESHOLD_XON_THRES_FLAG HSL_RW + +#define XOFF_THRES +#define PORT_FLOW_CTRL_THRESHOLD_XOFF_THRES_BOFFSET 0 +#define PORT_FLOW_CTRL_THRESHOLD_XOFF_THRES_BLEN 8 +#define PORT_FLOW_CTRL_THRESHOLD_XOFF_THRES_FLAG HSL_RW + + /* Port Rate Limit0 Register */ +#define RATE_LIMIT0 "rlmt0" +#define RATE_LIMIT0_ID 32 +#define RATE_LIMIT0_OFFSET 0x0110 +#define RATE_LIMIT0_E_LENGTH 4 +#define RATE_LIMIT0_E_OFFSET 0x0100 +#define RATE_LIMIT0_NR_E 7 + + +#define EG_RATE_EN "rlmt_egen" +#define RATE_LIMIT0_EG_RATE_EN_BOFFSET 23 +#define RATE_LIMIT0_EG_RATE_EN_BLEN 1 +#define RATE_LIMIT0_EG_RATE_EN_FLAG HSL_RW + +#define EG_MNG_RATE_EN "rlmt_egmngen" +#define RATE_LIMIT0_EG_MNG_RATE_EN_BOFFSET 22 +#define RATE_LIMIT0_EG_MNG_RATE_EN_BLEN 1 +#define RATE_LIMIT0_EG_MNG_RATE_EN_FLAG HSL_RW + +#define IN_MNG_RATE_EN "rlmt_inmngen" +#define RATE_LIMIT0_IN_MNG_RATE_EN_BOFFSET 21 +#define RATE_LIMIT0_IN_MNG_RATE_EN_BLEN 1 +#define RATE_LIMIT0_IN_MNG_RATE_EN_FLAG HSL_RW + +#define IN_MUL_RATE_EN "rlmt_inmulen" +#define RATE_LIMIT0_IN_MUL_RATE_EN_BOFFSET 20 +#define RATE_LIMIT0_IN_MUL_RATE_EN_BLEN 1 +#define RATE_LIMIT0_IN_MUL_RATE_EN_FLAG HSL_RW + +#define ING_RATE "rlmt_ingrate" +#define RATE_LIMIT0_ING_RATE_BOFFSET 0 +#define RATE_LIMIT0_ING_RATE_BLEN 15 +#define RATE_LIMIT0_ING_RATE_FLAG HSL_RW + + + + + + + + + + + /* mib memory info */ +#define MIB_RXBROAD +#define MIB_RXBROAD_OFFSET 0x01000 +#define MIB_RXBROAD_E_LENGTH 4 +#define MIB_RXBROAD_E_OFFSET 0x100 +#define MIB_RXBROAD_NR_E 7 + +#define MIB_RXPAUSE +#define MIB_RXPAUSE_OFFSET 0x01004 +#define MIB_RXPAUSE_E_LENGTH 4 +#define MIB_RXPAUSE_E_OFFSET 0x100 +#define MIB_RXPAUSE_NR_E 7 + +#define MIB_RXMULTI +#define MIB_RXMULTI_OFFSET 0x01008 +#define MIB_RXMULTI_E_LENGTH 4 +#define MIB_RXMULTI_E_OFFSET 0x100 +#define MIB_RXMULTI_NR_E 7 + +#define MIB_RXFCSERR +#define MIB_RXFCSERR_OFFSET 0x0100c +#define MIB_RXFCSERR_E_LENGTH 4 +#define MIB_RXFCSERR_E_OFFSET 0x100 +#define MIB_RXFCSERR_NR_E 7 + +#define MIB_RXALLIGNERR +#define MIB_RXALLIGNERR_OFFSET 0x01010 +#define MIB_RXALLIGNERR_E_LENGTH 4 +#define MIB_RXALLIGNERR_E_OFFSET 0x100 +#define MIB_RXALLIGNERR_NR_E 7 + +#define MIB_RXRUNT +#define MIB_RXRUNT_OFFSET 0x01014 +#define MIB_RXRUNT_E_LENGTH 4 +#define MIB_RXRUNT_E_OFFSET 0x100 +#define MIB_RXRUNT_NR_E 7 + +#define MIB_RXFRAGMENT +#define MIB_RXFRAGMENT_OFFSET 0x01018 +#define MIB_RXFRAGMENT_E_LENGTH 4 +#define MIB_RXFRAGMENT_E_OFFSET 0x100 +#define MIB_RXFRAGMENT_NR_E 7 + +#define MIB_RX64BYTE +#define MIB_RX64BYTE_OFFSET 0x0101c +#define MIB_RX64BYTE_E_LENGTH 4 +#define MIB_RX64BYTE_E_OFFSET 0x100 +#define MIB_RX64BYTE_NR_E 7 + +#define MIB_RX128BYTE +#define MIB_RX128BYTE_OFFSET 0x01020 +#define MIB_RX128BYTE_E_LENGTH 4 +#define MIB_RX128BYTE_E_OFFSET 0x100 +#define MIB_RX128BYTE_NR_E 7 + +#define MIB_RX256BYTE +#define MIB_RX256BYTE_OFFSET 0x01024 +#define MIB_RX256BYTE_E_LENGTH 4 +#define MIB_RX256BYTE_E_OFFSET 0x100 +#define MIB_RX256BYTE_NR_E 7 + +#define MIB_RX512BYTE +#define MIB_RX512BYTE_OFFSET 0x01028 +#define MIB_RX512BYTE_E_LENGTH 4 +#define MIB_RX512BYTE_E_OFFSET 0x100 +#define MIB_RX512BYTE_NR_E 7 + +#define MIB_RX1024BYTE +#define MIB_RX1024BYTE_OFFSET 0x0102c +#define MIB_RX1024BYTE_E_LENGTH 4 +#define MIB_RX1024BYTE_E_OFFSET 0x100 +#define MIB_RX1024BYTE_NR_E 7 + +#define MIB_RX1518BYTE +#define MIB_RX1518BYTE_OFFSET 0x01030 +#define MIB_RX1518BYTE_E_LENGTH 4 +#define MIB_RX1518BYTE_E_OFFSET 0x100 +#define MIB_RX1518BYTE_NR_E 7 + +#define MIB_RXMAXBYTE +#define MIB_RXMAXBYTE_OFFSET 0x01034 +#define MIB_RXMAXBYTE_E_LENGTH 4 +#define MIB_RXMAXBYTE_E_OFFSET 0x100 +#define MIB_RXMAXBYTE_NR_E 7 + +#define MIB_RXTOOLONG +#define MIB_RXTOOLONG_OFFSET 0x01038 +#define MIB_RXTOOLONG_E_LENGTH 4 +#define MIB_RXTOOLONG_E_OFFSET 0x100 +#define MIB_RXTOOLONG_NR_E 7 + +#define MIB_RXGOODBYTE_LO +#define MIB_RXGOODBYTE_LO_OFFSET 0x0103c +#define MIB_RXGOODBYTE_LO_E_LENGTH 4 +#define MIB_RXGOODBYTE_LO_E_OFFSET 0x100 +#define MIB_RXGOODBYTE_LO_NR_E 7 + +#define MIB_RXGOODBYTE_HI +#define MIB_RXGOODBYTE_HI_OFFSET 0x01040 +#define MIB_RXGOODBYTE_HI_E_LENGTH 4 +#define MIB_RXGOODBYTE_HI_E_OFFSET 0x100 +#define MIB_RXGOODBYTE_HI_NR_E 7 + +#define MIB_RXBADBYTE_LO +#define MIB_RXBADBYTE_LO_OFFSET 0x01044 +#define MIB_RXBADBYTE_LO_E_LENGTH 4 +#define MIB_RXBADBYTE_LO_E_OFFSET 0x100 +#define MIB_RXBADBYTE_LO_NR_E 7 + +#define MIB_RXBADBYTE_HI +#define MIB_RXBADBYTE_HI_OFFSET 0x01048 +#define MIB_RXBADBYTE_HI_E_LENGTH 4 +#define MIB_RXBADBYTE_HI_E_OFFSET 0x100 +#define MIB_RXBADBYTE_HI_NR_E 7 + +#define MIB_RXOVERFLOW +#define MIB_RXOVERFLOW_OFFSET 0x0104c +#define MIB_RXOVERFLOW_E_LENGTH 4 +#define MIB_RXOVERFLOW_E_OFFSET 0x100 +#define MIB_RXOVERFLOW_NR_E 7 + +#define MIB_FILTERED +#define MIB_FILTERED_OFFSET 0x01050 +#define MIB_FILTERED_E_LENGTH 4 +#define MIB_FILTERED_E_OFFSET 0x100 +#define MIB_FILTERED_NR_E 7 + +#define MIB_TXBROAD +#define MIB_TXBROAD_OFFSET 0x01054 +#define MIB_TXBROAD_E_LENGTH 4 +#define MIB_TXBROAD_E_OFFSET 0x100 +#define MIB_TXBROAD_NR_E 7 + +#define MIB_TXPAUSE +#define MIB_TXPAUSE_OFFSET 0x01058 +#define MIB_TXPAUSE_E_LENGTH 4 +#define MIB_TXPAUSE_E_OFFSET 0x100 +#define MIB_TXPAUSE_NR_E 7 + +#define MIB_TXMULTI +#define MIB_TXMULTI_OFFSET 0x0105c +#define MIB_TXMULTI_E_LENGTH 4 +#define MIB_TXMULTI_E_OFFSET 0x100 +#define MIB_TXMULTI_NR_E 7 + +#define MIB_TXUNDERRUN +#define MIB_TXUNDERRUN_OFFSET 0x01060 +#define MIB_TXUNDERRUN_E_LENGTH 4 +#define MIB_TXUNDERRUN_E_OFFSET 0x100 +#define MIB_TXUNDERRUN_NR_E 7 + +#define MIB_TX64BYTE +#define MIB_TX64BYTE_OFFSET 0x01064 +#define MIB_TX64BYTE_E_LENGTH 4 +#define MIB_TX64BYTE_E_OFFSET 0x100 +#define MIB_TX64BYTE_NR_E 7 + +#define MIB_TX128BYTE +#define MIB_TX128BYTE_OFFSET 0x01068 +#define MIB_TX128BYTE_E_LENGTH 4 +#define MIB_TX128BYTE_E_OFFSET 0x100 +#define MIB_TX128BYTE_NR_E 7 + +#define MIB_TX256BYTE +#define MIB_TX256BYTE_OFFSET 0x0106c +#define MIB_TX256BYTE_E_LENGTH 4 +#define MIB_TX256BYTE_E_OFFSET 0x100 +#define MIB_TX256BYTE_NR_E 7 + +#define MIB_TX512BYTE +#define MIB_TX512BYTE_OFFSET 0x01070 +#define MIB_TX512BYTE_E_LENGTH 4 +#define MIB_TX512BYTE_E_OFFSET 0x100 +#define MIB_TX512BYTE_NR_E 7 + +#define MIB_TX1024BYTE +#define MIB_TX1024BYTE_OFFSET 0x01074 +#define MIB_TX1024BYTE_E_LENGTH 4 +#define MIB_TX1024BYTE_E_OFFSET 0x100 +#define MIB_TX1024BYTE_NR_E 7 + +#define MIB_TX1518BYTE +#define MIB_TX1518BYTE_OFFSET 0x01078 +#define MIB_TX1518BYTE_E_LENGTH 4 +#define MIB_TX1518BYTE_E_OFFSET 0x100 +#define MIB_TX1518BYTE_NR_E 7 + +#define MIB_TXMAXBYTE +#define MIB_TXMAXBYTE_OFFSET 0x0107c +#define MIB_TXMAXBYTE_E_LENGTH 4 +#define MIB_TXMAXBYTE_E_OFFSET 0x100 +#define MIB_TXMAXBYTE_NR_E 7 + +#define MIB_TXOVERSIZE +#define MIB_TXOVERSIZE_OFFSET 0x01080 +#define MIB_TXOVERSIZE_E_LENGTH 4 +#define MIB_TXOVERSIZE_E_OFFSET 0x100 +#define MIB_TXOVERSIZE_NR_E 7 + +#define MIB_TXBYTE_LO +#define MIB_TXBYTE_LO_OFFSET 0x01084 +#define MIB_TXBYTE_LO_E_LENGTH 4 +#define MIB_TXBYTE_LO_E_OFFSET 0x100 +#define MIB_TXBYTE_LO_NR_E 7 + +#define MIB_TXBYTE_HI +#define MIB_TXBYTE_HI_OFFSET 0x01088 +#define MIB_TXBYTE_HI_E_LENGTH 4 +#define MIB_TXBYTE_HI_E_OFFSET 0x100 +#define MIB_TXBYTE_HI_NR_E 7 + +#define MIB_TXCOLLISION +#define MIB_TXCOLLISION_OFFSET 0x0108c +#define MIB_TXCOLLISION_E_LENGTH 4 +#define MIB_TXCOLLISION_E_OFFSET 0x100 +#define MIB_TXCOLLISION_NR_E 7 + +#define MIB_TXABORTCOL +#define MIB_TXABORTCOL_OFFSET 0x01090 +#define MIB_TXABORTCOL_E_LENGTH 4 +#define MIB_TXABORTCOL_E_OFFSET 0x100 +#define MIB_TXABORTCOL_NR_E 7 + +#define MIB_TXMULTICOL +#define MIB_TXMULTICOL_OFFSET 0x01094 +#define MIB_TXMULTICOL_E_LENGTH 4 +#define MIB_TXMULTICOL_E_OFFSET 0x100 +#define MIB_TXMULTICOL_NR_E 7 + +#define MIB_TXSINGALCOL +#define MIB_TXSINGALCOL_OFFSET 0x01098 +#define MIB_TXSINGALCOL_E_LENGTH 4 +#define MIB_TXSINGALCOL_E_OFFSET 0x100 +#define MIB_TXSINGALCOL_NR_E 7 + +#define MIB_TXEXCDEFER +#define MIB_TXEXCDEFER_OFFSET 0x0109c +#define MIB_TXEXCDEFER_E_LENGTH 4 +#define MIB_TXEXCDEFER_E_OFFSET 0x100 +#define MIB_TXEXCDEFER_NR_E 7 + +#define MIB_TXDEFER +#define MIB_TXDEFER_OFFSET 0x010a0 +#define MIB_TXDEFER_E_LENGTH 4 +#define MIB_TXDEFER_E_OFFSET 0x100 +#define MIB_TXDEFER_NR_E 7 + +#define MIB_TXLATECOL +#define MIB_TXLATECOL_OFFSET 0x010a4 +#define MIB_TXLATECOL_E_LENGTH 4 +#define MIB_TXLATECOL_E_OFFSET 0x100 +#define MIB_TXLATECOL_NR_E 7 + + + + /* ACL Action Register */ +#define ACL_RSLT0 10 +#define ACL_RSLT0_OFFSET 0x5a000 +#define ACL_RSLT0_E_LENGTH 4 +#define ACL_RSLT0_E_OFFSET 0x10 +#define ACL_RSLT0_NR_E 96 + +#define CTAGPRI +#define ACL_RSLT0_CTAGPRI_BOFFSET 29 +#define ACL_RSLT0_CTAGPRI_BLEN 3 +#define ACL_RSLT0_CTAGPRI_FLAG HSL_RW + +#define CTAGCFI +#define ACL_RSLT0_CTAGCFI_BOFFSET 28 +#define ACL_RSLT0_CTAGCFI_BLEN 1 +#define ACL_RSLT0_CTAGCFI_FLAG HSL_RW + +#define CTAGVID +#define ACL_RSLT0_CTAGVID_BOFFSET 16 +#define ACL_RSLT0_CTAGVID_BLEN 12 +#define ACL_RSLT0_CTAGVID_FLAG HSL_RW + +#define STAGPRI +#define ACL_RSLT0_STAGPRI_BOFFSET 13 +#define ACL_RSLT0_STAGPRI_BLEN 3 +#define ACL_RSLT0_STAGPRI_FLAG HSL_RW + +#define STAGDEI +#define ACL_RSLT0_STAGDEI_BOFFSET 12 +#define ACL_RSLT0_STAGDEI_BLEN 1 +#define ACL_RSLT0_STAGDEI_FLAG HSL_RW + +#define STAGVID +#define ACL_RSLT0_STAGVID_BOFFSET 0 +#define ACL_RSLT0_STAGVID_BLEN 12 +#define ACL_RSLT0_STAGVID_FLAG HSL_RW + + +#define ACL_RSLT1 11 +#define ACL_RSLT1_OFFSET 0x5a004 +#define ACL_RSLT1_E_LENGTH 4 +#define ACL_RSLT1_E_OFFSET 0x10 +#define ACL_RSLT1_NR_E 96 + +#define DES_PORT0 +#define ACL_RSLT1_DES_PORT0_BOFFSET 29 +#define ACL_RSLT1_DES_PORT0_BLEN 3 +#define ACL_RSLT1_DES_PORT0_FLAG HSL_RW + +#define PRI_QU_EN +#define ACL_RSLT1_PRI_QU_EN_BOFFSET 28 +#define ACL_RSLT1_PRI_QU_EN_BLEN 1 +#define ACL_RSLT1_PRI_QU_EN_FLAG HSL_RW + +#define PRI_QU +#define ACL_RSLT1_PRI_QU_BOFFSET 25 +#define ACL_RSLT1_PRI_QU_BLEN 3 +#define ACL_RSLT1_PRI_QU_FLAG HSL_RW + +#define WCMP_EN +#define ACL_RSLT1_WCMP_EN_BOFFSET 24 +#define ACL_RSLT1_WCMP_EN_BLEN 1 +#define ACL_RSLT1_WCMP_EN_FLAG HSL_RW + +#define ARP_PTR +#define ACL_RSLT1_ARP_PTR_BOFFSET 17 +#define ACL_RSLT1_ARP_PTR_BLEN 7 +#define ACL_RSLT1_ARP_PTR_FLAG HSL_RW + +#define ARP_PTR_EN +#define ACL_RSLT1_ARP_PTR_EN_BOFFSET 16 +#define ACL_RSLT1_ARP_PTR_EN_BLEN 1 +#define ACL_RSLT1_ARP_PTR_EN_FLAG HSL_RW + +#define FORCE_L3_MODE +#define ACL_RSLT1_FORCE_L3_MODE_BOFFSET 14 +#define ACL_RSLT1_FORCE_L3_MODE_BLEN 2 +#define ACL_RSLT1_FORCE_L3_MODE_FLAG HSL_RW + +#define LOOK_VID_CHG +#define ACL_RSLT1_LOOK_VID_CHG_BOFFSET 13 +#define ACL_RSLT1_LOOK_VID_CHG_BLEN 1 +#define ACL_RSLT1_LOOK_VID_CHG_FLAG HSL_RW + +#define TRANS_CVID_CHG +#define ACL_RSLT1_TRANS_CVID_CHG_BOFFSET 12 +#define ACL_RSLT1_TRANS_CVID_CHG_BLEN 1 +#define ACL_RSLT1_TRANS_CVID_CHG_FLAG HSL_RW + +#define TRANS_SVID_CHG +#define ACL_RSLT1_TRANS_SVID_CHG_BOFFSET 11 +#define ACL_RSLT1_TRANS_SVID_CHG_BLEN 1 +#define ACL_RSLT1_TRANS_SVID_CHG_FLAG HSL_RW + +#define CTAG_CFI_CHG +#define ACL_RSLT1_CTAG_CFI_CHG_BOFFSET 10 +#define ACL_RSLT1_CTAG_CFI_CHG_BLEN 1 +#define ACL_RSLT1_CTAG_CFI_CHG_FLAG HSL_RW + +#define CTAG_PRI_REMAP +#define ACL_RSLT1_CTAG_PRI_REMAP_BOFFSET 9 +#define ACL_RSLT1_CTAG_PRI_REMAP_BLEN 1 +#define ACL_RSLT1_CTAG_PRI_REMAP_FLAG HSL_RW + +#define STAG_DEI_CHG +#define ACL_RSLT1_STAG_DEI_CHG_BOFFSET 8 +#define ACL_RSLT1_STAG_DEI_CHG_BLEN 1 +#define ACL_RSLT1_STAG_DEI_CHG_FLAG HSL_RW + +#define STAG_PRI_REMAP +#define ACL_RSLT1_STAG_PRI_REMAP_BOFFSET 7 +#define ACL_RSLT1_STAG_PRI_REMAP_BLEN 1 +#define ACL_RSLT1_STAG_PRI_REMAP_FLAG HSL_RW + +#define DSCP_REMAP +#define ACL_RSLT1_DSCP_REMAP_BOFFSET 6 +#define ACL_RSLT1_DSCP_REMAP_BLEN 1 +#define ACL_RSLT1_DSCP_REMAP_FLAG HSL_RW + +#define DSCPV +#define ACL_RSLT1_DSCPV_BOFFSET 0 +#define ACL_RSLT1_DSCPV_BLEN 6 +#define ACL_RSLT1_DSCPV_FLAG HSL_RW + +#define ACL_RSLT2 12 +#define ACL_RSLT2_OFFSET 0x5a008 +#define ACL_RSLT2_E_LENGTH 4 +#define ACL_RSLT2_E_OFFSET 0x10 +#define ACL_RSLT2_NR_E 96 + +#define TRIGGER_INTR +#define ACL_RSLT2_TRIGGER_INTR_BOFFSET 16 +#define ACL_RSLT2_TRIGGER_INTR_BLEN 1 +#define ACL_RSLT2_TRIGGER_INTR_FLAG HSL_RW + +#define EG_BYPASS +#define ACL_RSLT2_EG_BYPASS_BOFFSET 15 +#define ACL_RSLT2_EG_BYPASS_BLEN 1 +#define ACL_RSLT2_EG_BYPASS_FLAG HSL_RW + +#define POLICER_EN +#define ACL_RSLT2_POLICER_EN_BOFFSET 14 +#define ACL_RSLT2_POLICER_EN_BLEN 1 +#define ACL_RSLT2_POLICER_EN_FLAG HSL_RW + +#define POLICER_PTR +#define ACL_RSLT2_POLICER_PTR_BOFFSET 9 +#define ACL_RSLT2_POLICER_PTR_BLEN 5 +#define ACL_RSLT2_POLICER_PTR_FLAG HSL_RW + +#define FWD_CMD +#define ACL_RSLT2_FWD_CMD_BOFFSET 6 +#define ACL_RSLT2_FWD_CMD_BLEN 3 +#define ACL_RSLT2_FWD_CMD_FLAG HSL_RW + +#define MIRR_EN +#define ACL_RSLT2_MIRR_EN_BOFFSET 5 +#define ACL_RSLT2_MIRR_EN_BLEN 1 +#define ACL_RSLT2_MIRR_EN_FLAG HSL_RW + +#define DES_PORT_EN +#define ACL_RSLT2_DES_PORT_EN_BOFFSET 4 +#define ACL_RSLT2_DES_PORT_EN_BLEN 1 +#define ACL_RSLT2_DES_PORT_EN_FLAG HSL_RW + +#define DES_PORT1 +#define ACL_RSLT2_DES_PORT1_BOFFSET 0 +#define ACL_RSLT2_DES_PORT1_BLEN 4 +#define ACL_RSLT2_DES_PORT1_FLAG HSL_RW + + + + + /* MAC Type Rule Field Define */ +#define MAC_RUL_V0 0 +#define MAC_RUL_V0_OFFSET 0x58000 +#define MAC_RUL_V0_E_LENGTH 4 +#define MAC_RUL_V0_E_OFFSET 0x20 +#define MAC_RUL_V0_NR_E 96 + +#define DAV_BYTE2 +#define MAC_RUL_V0_DAV_BYTE2_BOFFSET 24 +#define MAC_RUL_V0_DAV_BYTE2_BLEN 8 +#define MAC_RUL_V0_DAV_BYTE2_FLAG HSL_RW + +#define DAV_BYTE3 +#define MAC_RUL_V0_DAV_BYTE3_BOFFSET 16 +#define MAC_RUL_V0_DAV_BYTE3_BLEN 8 +#define MAC_RUL_V0_DAV_BYTE3_FLAG HSL_RW + +#define DAV_BYTE4 +#define MAC_RUL_V0_DAV_BYTE4_BOFFSET 8 +#define MAC_RUL_V0_DAV_BYTE4_BLEN 8 +#define MAC_RUL_V0_DAV_BYTE4_FLAG HSL_RW + +#define DAV_BYTE5 +#define MAC_RUL_V0_DAV_BYTE5_BOFFSET 0 +#define MAC_RUL_V0_DAV_BYTE5_BLEN 8 +#define MAC_RUL_V0_DAV_BYTE5_FLAG HSL_RW + + +#define MAC_RUL_V1 1 +#define MAC_RUL_V1_OFFSET 0x58004 +#define MAC_RUL_V1_E_LENGTH 4 +#define MAC_RUL_V1_E_OFFSET 0x20 +#define MAC_RUL_V1_NR_E 96 + +#define SAV_BYTE4 +#define MAC_RUL_V1_SAV_BYTE4_BOFFSET 24 +#define MAC_RUL_V1_SAV_BYTE4_BLEN 8 +#define MAC_RUL_V1_SAV_BYTE4_FLAG HSL_RW + +#define SAV_BYTE5 +#define MAC_RUL_V1_SAV_BYTE5_BOFFSET 16 +#define MAC_RUL_V1_SAV_BYTE5_BLEN 8 +#define MAC_RUL_V1_SAV_BYTE5_FLAG HSL_RW + +#define DAV_BYTE0 +#define MAC_RUL_V1_DAV_BYTE0_BOFFSET 8 +#define MAC_RUL_V1_DAV_BYTE0_BLEN 8 +#define MAC_RUL_V1_DAV_BYTE0_FLAG HSL_RW + +#define DAV_BYTE1 +#define MAC_RUL_V1_DAV_BYTE1_BOFFSET 0 +#define MAC_RUL_V1_DAV_BYTE1_BLEN 8 +#define MAC_RUL_V1_DAV_BYTE1_FLAG HSL_RW + + +#define MAC_RUL_V2 2 +#define MAC_RUL_V2_OFFSET 0x58008 +#define MAC_RUL_V2_E_LENGTH 4 +#define MAC_RUL_V2_E_OFFSET 0x20 +#define MAC_RUL_V2_NR_E 96 + +#define SAV_BYTE0 +#define MAC_RUL_V2_SAV_BYTE0_BOFFSET 24 +#define MAC_RUL_V2_SAV_BYTE0_BLEN 8 +#define MAC_RUL_V2_SAV_BYTE0_FLAG HSL_RW + +#define SAV_BYTE1 +#define MAC_RUL_V2_SAV_BYTE1_BOFFSET 16 +#define MAC_RUL_V2_SAV_BYTE1_BLEN 8 +#define MAC_RUL_V2_SAV_BYTE1_FLAG HSL_RW + +#define SAV_BYTE2 +#define MAC_RUL_V2_SAV_BYTE2_BOFFSET 8 +#define MAC_RUL_V2_SAV_BYTE2_BLEN 8 +#define MAC_RUL_V2_SAV_BYTE2_FLAG HSL_RW + +#define SAV_BYTE3 +#define MAC_RUL_V2_SAV_BYTE3_BOFFSET 0 +#define MAC_RUL_V2_SAV_BYTE3_BLEN 8 +#define MAC_RUL_V2_SAV_BYTE3_FLAG HSL_RW + + +#define MAC_RUL_V3 3 +#define MAC_RUL_V3_ID 13 +#define MAC_RUL_V3_OFFSET 0x5800c +#define MAC_RUL_V3_E_LENGTH 4 +#define MAC_RUL_V3_E_OFFSET 0x20 +#define MAC_RUL_V3_NR_E 96 + +#define ETHTYPV +#define MAC_RUL_V3_ETHTYPV_BOFFSET 16 +#define MAC_RUL_V3_ETHTYPV_BLEN 16 +#define MAC_RUL_V3_ETHTYPV_FLAG HSL_RW + +#define VLANPRIV +#define MAC_RUL_V3_VLANPRIV_BOFFSET 13 +#define MAC_RUL_V3_VLANPRIV_BLEN 3 +#define MAC_RUL_V3_VLANPRIV_FLAG HSL_RW + +#define VLANCFIV +#define MAC_RUL_V3_VLANCFIV_BOFFSET 12 +#define MAC_RUL_V3_VLANCFIV_BLEN 1 +#define MAC_RUL_V3_VLANCFIV_FLAG HSL_RW + +#define VLANIDV +#define MAC_RUL_V3_VLANIDV_BOFFSET 0 +#define MAC_RUL_V3_VLANIDV_BLEN 12 +#define MAC_RUL_V3_VLANIDV_FLAG HSL_RW + + +#define MAC_RUL_V4 4 +#define MAC_RUL_V4_OFFSET 0x58010 +#define MAC_RUL_V4_E_LENGTH 4 +#define MAC_RUL_V4_E_OFFSET 0x20 +#define MAC_RUL_V4_NR_E 96 + +#define RULE_INV +#define MAC_RUL_V4_RULE_INV_BOFFSET 7 +#define MAC_RUL_V4_RULE_INV_BLEN 1 +#define MAC_RUL_V4_RULE_INV_FLAG HSL_RW + +#define SRC_PT +#define MAC_RUL_V4_SRC_PT_BOFFSET 0 +#define MAC_RUL_V4_SRC_PT_BLEN 7 +#define MAC_RUL_V4_SRC_PT_FLAG HSL_RW + + +#define MAC_RUL_M0 5 +#define MAC_RUL_M0_OFFSET 0x59000 +#define MAC_RUL_M0_E_LENGTH 4 +#define MAC_RUL_M0_E_OFFSET 0x20 +#define MAC_RUL_M0_NR_E 96 + +#define DAM_BYTE2 +#define MAC_RUL_M0_DAM_BYTE2_BOFFSET 24 +#define MAC_RUL_M0_DAM_BYTE2_BLEN 8 +#define MAC_RUL_M0_DAM_BYTE2_FLAG HSL_RW + +#define DAM_BYTE3 +#define MAC_RUL_M0_DAM_BYTE3_BOFFSET 16 +#define MAC_RUL_M0_DAM_BYTE3_BLEN 8 +#define MAC_RUL_M0_DAM_BYTE3_FLAG HSL_RW + +#define DAM_BYTE4 +#define MAC_RUL_M0_DAM_BYTE4_BOFFSET 8 +#define MAC_RUL_M0_DAM_BYTE4_BLEN 8 +#define MAC_RUL_M0_DAM_BYTE4_FLAG HSL_RW + +#define DAM_BYTE5 +#define MAC_RUL_M0_DAM_BYTE5_BOFFSET 0 +#define MAC_RUL_M0_DAM_BYTE5_BLEN 8 +#define MAC_RUL_M0_DAM_BYTE5_FLAG HSL_RW + + +#define MAC_RUL_M1 6 +#define MAC_RUL_M1_OFFSET 0x59004 +#define MAC_RUL_M1_E_LENGTH 4 +#define MAC_RUL_M1_E_OFFSET 0x20 +#define MAC_RUL_M1_NR_E 96 + +#define SAM_BYTE4 +#define MAC_RUL_M1_SAM_BYTE4_BOFFSET 24 +#define MAC_RUL_M1_SAM_BYTE4_BLEN 8 +#define MAC_RUL_M1_SAM_BYTE4_FLAG HSL_RW + +#define SAM_BYTE5 +#define MAC_RUL_M1_SAM_BYTE5_BOFFSET 16 +#define MAC_RUL_M1_SAM_BYTE5_BLEN 8 +#define MAC_RUL_M1_SAM_BYTE5_FLAG HSL_RW + +#define DAM_BYTE0 +#define MAC_RUL_M1_DAM_BYTE0_BOFFSET 8 +#define MAC_RUL_M1_DAM_BYTE0_BLEN 8 +#define MAC_RUL_M1_DAM_BYTE0_FLAG HSL_RW + +#define DAM_BYTE1 +#define MAC_RUL_M1_DAM_BYTE1_BOFFSET 0 +#define MAC_RUL_M1_DAM_BYTE1_BLEN 8 +#define MAC_RUL_M1_DAM_BYTE1_FLAG HSL_RW + + +#define MAC_RUL_M2 7 +#define MAC_RUL_M2_OFFSET 0x59008 +#define MAC_RUL_M2_E_LENGTH 4 +#define MAC_RUL_M2_E_OFFSET 0x20 +#define MAC_RUL_M2_NR_E 96 + +#define SAM_BYTE0 +#define MAC_RUL_M2_SAM_BYTE0_BOFFSET 24 +#define MAC_RUL_M2_SAM_BYTE0_BLEN 8 +#define MAC_RUL_M2_SAM_BYTE0_FLAG HSL_RW + +#define SAM_BYTE1 +#define MAC_RUL_M2_SAM_BYTE1_BOFFSET 16 +#define MAC_RUL_M2_SAM_BYTE1_BLEN 8 +#define MAC_RUL_M2_SAM_BYTE1_FLAG HSL_RW + +#define SAM_BYTE2 +#define MAC_RUL_M2_SAM_BYTE2_BOFFSET 8 +#define MAC_RUL_M2_SAM_BYTE2_BLEN 8 +#define MAC_RUL_M2_SAM_BYTE2_FLAG HSL_RW + +#define SAM_BYTE3 +#define MAC_RUL_M2_SAM_BYTE3_BOFFSET 0 +#define MAC_RUL_M2_SAM_BYTE3_BLEN 8 +#define MAC_RUL_M2_SAM_BYTE3_FLAG HSL_RW + + +#define MAC_RUL_M3 8 +#define MAC_RUL_M3_OFFSET 0x5900c +#define MAC_RUL_M3_E_LENGTH 4 +#define MAC_RUL_M3_E_OFFSET 0x20 +#define MAC_RUL_M3_NR_E 96 + +#define ETHTYPM +#define MAC_RUL_M3_ETHTYPM_BOFFSET 16 +#define MAC_RUL_M3_ETHTYPM_BLEN 16 +#define MAC_RUL_M3_ETHTYPM_FLAG HSL_RW + +#define VLANPRIM +#define MAC_RUL_M3_VLANPRIM_BOFFSET 13 +#define MAC_RUL_M3_VLANPRIM_BLEN 3 +#define MAC_RUL_M3_VLANPRIM_FLAG HSL_RW + +#define VLANCFIM +#define MAC_RUL_M3_VLANCFIM_BOFFSET 12 +#define MAC_RUL_M3_VLANCFIM_BLEN 1 +#define MAC_RUL_M3_VLANCFIM_FLAG HSL_RW + +#define VLANIDM +#define MAC_RUL_M3_VLANIDM_BOFFSET 0 +#define MAC_RUL_M3_VLANIDM_BLEN 12 +#define MAC_RUL_M3_VLANIDM_FLAG HSL_RW + + +#define MAC_RUL_M4 9 +#define MAC_RUL_M4_OFFSET 0x59010 +#define MAC_RUL_M4_E_LENGTH 4 +#define MAC_RUL_M4_E_OFFSET 0x20 +#define MAC_RUL_M4_NR_E 96 + +#define RULE_VALID +#define MAC_RUL_M4_RULE_VALID_BOFFSET 6 +#define MAC_RUL_M4_RULE_VALID_BLEN 2 +#define MAC_RUL_M4_RULE_VALID_FLAG HSL_RW + +#define TAGGEDM +#define MAC_RUL_M4_TAGGEDM_BOFFSET 5 +#define MAC_RUL_M4_TAGGEDM_BLEN 1 +#define MAC_RUL_M4_TAGGEDM_FLAG HSL_RW + +#define TAGGEDV +#define MAC_RUL_M4_TAGGEDV_BOFFSET 4 +#define MAC_RUL_M4_TAGGEDV_BLEN 1 +#define MAC_RUL_M4_TAGGEDV_FLAG HSL_RW + +#define VIDMSK +#define MAC_RUL_M4_VIDMSK_BOFFSET 3 +#define MAC_RUL_M4_VIDMSK_BLEN 1 +#define MAC_RUL_M4_VIDMSK_FLAG HSL_RW + +#define RULE_TYP +#define MAC_RUL_M4_RULE_TYP_BOFFSET 0 +#define MAC_RUL_M4_RULE_TYP_BLEN 3 +#define MAC_RUL_M4_RULE_TYP_FLAG HSL_RW + + + + + /* IP4 Type Rule Field Define */ +#define IP4_RUL_V0 0 +#define IP4_RUL_V0_OFFSET 0x58000 +#define IP4_RUL_V0_E_LENGTH 4 +#define IP4_RUL_V0_E_OFFSET 0x20 +#define IP4_RUL_V0_NR_E 96 + +#define DIPV +#define IP4_RUL_V0_DIPV_BOFFSET 0 +#define IP4_RUL_V0_DIPV_BLEN 32 +#define IP4_RUL_V0_DIPV_FLAG HSL_RW + + +#define IP4_RUL_V1 1 +#define IP4_RUL_V1_OFFSET 0x58004 +#define IP4_RUL_V1_E_LENGTH 4 +#define IP4_RUL_V1_E_OFFSET 0x20 +#define IP4_RUL_V1_NR_E 96 + +#define SIPV +#define IP4_RUL_V1_SIPV_BOFFSET 0 +#define IP4_RUL_V1_SIPV_BLEN 32 +#define IP4_RUL_V1_SIPV_FLAG HSL_RW + + +#define IP4_RUL_V2 2 +#define IP4_RUL_V2_OFFSET 0x58008 +#define IP4_RUL_V2_E_LENGTH 4 +#define IP4_RUL_V2_E_OFFSET 0x20 +#define IP4_RUL_V2_NR_E 96 + +#define IP4PROTV +#define IP4_RUL_V2_IP4PROTV_BOFFSET 0 +#define IP4_RUL_V2_IP4PROTV_BLEN 8 +#define IP4_RUL_V2_IP4PROTV_FLAG HSL_RW + +#define IP4DSCPV +#define IP4_RUL_V2_IP4DSCPV_BOFFSET 8 +#define IP4_RUL_V2_IP4DSCPV_BLEN 8 +#define IP4_RUL_V2_IP4DSCPV_FLAG HSL_RW + +#define IP4DPORTV +#define IP4_RUL_V2_IP4DPORTV_BOFFSET 16 +#define IP4_RUL_V2_IP4DPORTV_BLEN 16 +#define IP4_RUL_V2_IP4DPORTV_FLAG HSL_RW + + +#define IP4_RUL_V3 3 +#define IP4_RUL_V3_OFFSET 0x5800c +#define IP4_RUL_V3_E_LENGTH 4 +#define IP4_RUL_V3_E_OFFSET 0x20 +#define IP4_RUL_V3_NR_E 96 + +#define IP4TCPFLAGV +#define IP4_RUL_V3_IP4TCPFLAGV_BOFFSET 24 +#define IP4_RUL_V3_IP4TCPFLAGV_BLEN 6 +#define IP4_RUL_V3_IP4TCPFLAGV_FLAG HSL_RW + +#define IP4DHCPV +#define IP4_RUL_V3_IP4DHCPV_BOFFSET 22 +#define IP4_RUL_V3_IP4DHCPV_BLEN 1 +#define IP4_RUL_V3_IP4DHCPV_FLAG HSL_RW + +#define IP4RIPV +#define IP4_RUL_V3_IP4RIPV_BOFFSET 21 +#define IP4_RUL_V3_IP4RIPV_BLEN 1 +#define IP4_RUL_V3_IP4RIPV_FLAG HSL_RW + +#define ICMP_EN +#define IP4_RUL_V3_ICMP_EN_BOFFSET 20 +#define IP4_RUL_V3_ICMP_EN_BLEN 1 +#define IP4_RUL_V3_ICMP_EN_FLAG HSL_RW + +#define IP4SPORTV +#define IP4_RUL_V3_IP4SPORTV_BOFFSET 0 +#define IP4_RUL_V3_IP4SPORTV_BLEN 16 +#define IP4_RUL_V3_IP4SPORTV_FLAG HSL_RW + +#define IP4ICMPTYPV +#define IP4_RUL_V3_IP4ICMPTYPV_BOFFSET 8 +#define IP4_RUL_V3_IP4ICMPTYPV_BLEN 8 +#define IP4_RUL_V3_IP4ICMPTYPV_FLAG HSL_RW + +#define IP4ICMPCODEV +#define IP4_RUL_V3_IP4ICMPCODEV_BOFFSET 0 +#define IP4_RUL_V3_IP4ICMPCODEV_BLEN 8 +#define IP4_RUL_V3_IP4ICMPCODEV_FLAG HSL_RW + + +#define IP4_RUL_V4 4 +#define IP4_RUL_V4_OFFSET 0x58010 +#define IP4_RUL_V4_E_LENGTH 4 +#define IP4_RUL_V4_E_OFFSET 0x20 +#define IP4_RUL_V4_NR_E 96 + + +#define IP4_RUL_M0 5 +#define IP4_RUL_M0_OFFSET 0x59000 +#define IP4_RUL_M0_E_LENGTH 4 +#define IP4_RUL_M0_E_OFFSET 0x20 +#define IP4_RUL_M0_NR_E 96 + +#define DIPM +#define IP4_RUL_M0_DIPM_BOFFSET 0 +#define IP4_RUL_M0_DIPM_BLEN 32 +#define IP4_RUL_M0_DIPM_FLAG HSL_RW + + +#define IP4_RUL_M1 6 +#define IP4_RUL_M1_OFFSET 0x59004 +#define IP4_RUL_M1_E_LENGTH 4 +#define IP4_RUL_M1_E_OFFSET 0x20 +#define IP4_RUL_M1_NR_E 96 + +#define SIPM +#define IP4_RUL_M1_SIPM_BOFFSET 0 +#define IP4_RUL_M1_SIPM_BLEN 32 +#define IP4_RUL_M1_SIPM_FLAG HSL_RW + + +#define IP4_RUL_M2 7 +#define IP4_RUL_M2_OFFSET 0x59008 +#define IP4_RUL_M2_E_LENGTH 4 +#define IP4_RUL_M2_E_OFFSET 0x20 +#define IP4_RUL_M2_NR_E 96 + +#define IP4PROTM +#define IP4_RUL_M2_IP4PROTM_BOFFSET 0 +#define IP4_RUL_M2_IP4PROTM_BLEN 8 +#define IP4_RUL_M2_IP4PROTM_FLAG HSL_RW + +#define IP4DSCPM +#define IP4_RUL_M2_IP4DSCPM_BOFFSET 8 +#define IP4_RUL_M2_IP4DSCPM_BLEN 8 +#define IP4_RUL_M2_IP4DSCPM_FLAG HSL_RW + +#define IP4DPORTM +#define IP4_RUL_M2_IP4DPORTM_BOFFSET 16 +#define IP4_RUL_M2_IP4DPORTM_BLEN 16 +#define IP4_RUL_M2_IP4DPORTM_FLAG HSL_RW + + +#define IP4_RUL_M3 8 +#define IP4_RUL_M3_OFFSET 0x5900c +#define IP4_RUL_M3_E_LENGTH 4 +#define IP4_RUL_M3_E_OFFSET 0x20 +#define IP4_RUL_M3_NR_E 96 + +#define IP4TCPFLAGM +#define IP4_RUL_M3_IP4TCPFLAGM_BOFFSET 24 +#define IP4_RUL_M3_IP4TCPFLAGM_BLEN 6 +#define IP4_RUL_M3_IP4TCPFLAGM_FLAG HSL_RW + +#define IP4DHCPM +#define IP4_RUL_M3_IP4DHCPM_BOFFSET 22 +#define IP4_RUL_M3_IP4DHCPM_BLEN 1 +#define IP4_RUL_M3_IP4DHCPM_FLAG HSL_RW + +#define IP4RIPM +#define IP4_RUL_M3_IP4RIPM_BOFFSET 21 +#define IP4_RUL_M3_IP4RIPM_BLEN 1 +#define IP4_RUL_M3_IP4RIPM_FLAG HSL_RW + +#define IP4DPORTM_EN +#define IP4_RUL_M3_IP4DPORTM_EN_BOFFSET 17 +#define IP4_RUL_M3_IP4DPORTM_EN_BLEN 1 +#define IP4_RUL_M3_IP4DPORTM_EN_FLAG HSL_RW + +#define IP4SPORTM_EN +#define IP4_RUL_M3_IP4SPORTM_EN_BOFFSET 16 +#define IP4_RUL_M3_IP4SPORTM_EN_BLEN 1 +#define IP4_RUL_M3_IP4SPORTM_EN_FLAG HSL_RW + +#define IP4SPORTM +#define IP4_RUL_M3_IP4SPORTM_BOFFSET 0 +#define IP4_RUL_M3_IP4SPORTM_BLEN 16 +#define IP4_RUL_M3_IP4SPORTM_FLAG HSL_RW + +#define IP4ICMPTYPM +#define IP4_RUL_M3_IP4ICMPTYPM_BOFFSET 8 +#define IP4_RUL_M3_IP4ICMPTYPM_BLEN 8 +#define IP4_RUL_M3_IP4ICMPTYPM_FLAG HSL_RW + +#define IP4ICMPCODEM +#define IP4_RUL_M3_IP4ICMPCODEM_BOFFSET 0 +#define IP4_RUL_M3_IP4ICMPCODEM_BLEN 8 +#define IP4_RUL_M3_IP4ICMPCODEM_FLAG HSL_RW + + +#define IP4_RUL_M4 9 +#define IP4_RUL_M4_OFFSET 0x59010 +#define IP4_RUL_M4_E_LENGTH 4 +#define IP4_RUL_M4_E_OFFSET 0x20 +#define IP4_RUL_M4_NR_E 32 + + + + + /* IP6 Type1 Rule Field Define */ +#define IP6_RUL1_V0 0 +#define IP6_RUL1_V0_OFFSET 0x58000 +#define IP6_RUL1_V0_E_LENGTH 4 +#define IP6_RUL1_V0_E_OFFSET 0x20 +#define IP6_RUL1_V0_NR_E 96 + +#define IP6_DIPV0 +#define IP6_RUL1_V0_IP6_DIPV0_BOFFSET 0 +#define IP6_RUL1_V0_IP6_DIPV0_BLEN 32 +#define IP6_RUL1_V0_IP6_DIPV0_FLAG HSL_RW + + +#define IP6_RUL1_V1 1 +#define IP6_RUL1_V1_OFFSET 0x58004 +#define IP6_RUL1_V1_E_LENGTH 4 +#define IP6_RUL1_V1_E_OFFSET 0x20 +#define IP6_RUL1_V1_NR_E 96 + +#define IP6_DIPV1 +#define IP6_RUL1_V1_IP6_DIPV1_BOFFSET 0 +#define IP6_RUL1_V1_IP6_DIPv1_BLEN 32 +#define IP6_RUL1_V1_IP6_DIPV1_FLAG HSL_RW + + +#define IP6_RUL1_V2 2 +#define IP6_RUL1_V2_OFFSET 0x58008 +#define IP6_RUL1_V2_E_LENGTH 4 +#define IP6_RUL1_V2_E_OFFSET 0x20 +#define IP6_RUL1_V2_NR_E 96 + +#define IP6_DIPV2 +#define IP6_RUL1_V2_IP6_DIPV2_BOFFSET 0 +#define IP6_RUL1_V2_IP6_DIPv2_BLEN 32 +#define IP6_RUL1_V2_IP6_DIPV2_FLAG HSL_RW + + +#define IP6_RUL1_V3 3 +#define IP6_RUL1_V3_OFFSET 0x5800c +#define IP6_RUL1_V3_E_LENGTH 4 +#define IP6_RUL1_V3_E_OFFSET 0x20 +#define IP6_RUL1_V3_NR_E 96 + +#define IP6_DIPV3 +#define IP6_RUL1_V3_IP6_DIPV3_BOFFSET 0 +#define IP6_RUL1_V3_IP6_DIPv3_BLEN 32 +#define IP6_RUL1_V3_IP6_DIPV3_FLAG HSL_RW + + +#define IP6_RUL1_V4 4 +#define IP6_RUL1_V4_OFFSET 0x58010 +#define IP6_RUL1_V4_E_LENGTH 4 +#define IP6_RUL1_V4_E_OFFSET 0x20 +#define IP6_RUL1_V4_NR_E 96 + + +#define IP6_RUL1_M0 5 +#define IP6_RUL1_M0_OFFSET 0x59000 +#define IP6_RUL1_M0_E_LENGTH 4 +#define IP6_RUL1_M0_E_OFFSET 0x20 +#define IP6_RUL1_M0_NR_E 96 + +#define IP6_DIPM0 +#define IP6_RUL1_M0_IP6_DIPM0_BOFFSET 0 +#define IP6_RUL1_M0_IP6_DIPM0_BLEN 32 +#define IP6_RUL1_M0_IP6_DIPM0_FLAG HSL_RW + + +#define IP6_RUL1_M1 6 +#define IP6_RUL1_M1_OFFSET 0x59004 +#define IP6_RUL1_M1_E_LENGTH 4 +#define IP6_RUL1_M1_E_OFFSET 0x20 +#define IP6_RUL1_M1_NR_E 96 + +#define IP6_DIPM1 +#define IP6_RUL1_M1_IP6_DIPM1_BOFFSET 0 +#define IP6_RUL1_M1_IP6_DIPM1_BLEN 32 +#define IP6_RUL1_M1_IP6_DIPM1_FLAG HSL_RW + + +#define IP6_RUL1_M2 7 +#define IP6_RUL1_M2_OFFSET 0x59008 +#define IP6_RUL1_M2_E_LENGTH 4 +#define IP6_RUL1_M2_E_OFFSET 0x20 +#define IP6_RUL1_M2_NR_E 96 + +#define IP6_DIPM2 +#define IP6_RUL1_M2_IP6_DIPM2_BOFFSET 0 +#define IP6_RUL1_M2_IP6_DIPM2_BLEN 32 +#define IP6_RUL1_M2_IP6_DIPM2_FLAG HSL_RW + + +#define IP6_RUL1_M3 8 +#define IP6_RUL1_M3_OFFSET 0x5900c +#define IP6_RUL1_M3_E_LENGTH 4 +#define IP6_RUL1_M3_E_OFFSET 0x20 +#define IP6_RUL1_M3_NR_E 96 + +#define IP6_DIPM3 +#define IP6_RUL1_M3_IP6_DIPM3_BOFFSET 0 +#define IP6_RUL1_M3_IP6_DIPM3_BLEN 32 +#define IP6_RUL1_M3_IP6_DIPM3_FLAG HSL_RW + + +#define IP6_RUL1_M4 9 +#define IP6_RUL1_M4_OFFSET 0x59010 +#define IP6_RUL1_M4_E_LENGTH 4 +#define IP6_RUL1_M4_E_OFFSET 0x20 +#define IP6_RUL1_M4_NR_E 96 + + + + + /* IP6 Type2 Rule Field Define */ +#define IP6_RUL2_V0 0 +#define IP6_RUL2_V0_OFFSET 0x58000 +#define IP6_RUL2_V0_E_LENGTH 4 +#define IP6_RUL2_V0_E_OFFSET 0x20 +#define IP6_RUL2_V0_NR_E 96 + +#define IP6_SIPV0 +#define IP6_RUL2_V0_IP6_SIPV0_BOFFSET 0 +#define IP6_RUL2_V0_IP6_SIPv0_BLEN 32 +#define IP6_RUL2_V0_IP6_SIPV0_FLAG HSL_RW + + +#define IP6_RUL2_V1 1 +#define IP6_RUL2_V1_OFFSET 0x58004 +#define IP6_RUL2_V1_E_LENGTH 4 +#define IP6_RUL2_V1_E_OFFSET 0x20 +#define IP6_RUL2_V1_NR_E 96 + +#define IP6_SIPV1 +#define IP6_RUL2_V1_IP6_SIPV1_BOFFSET 0 +#define IP6_RUL2_V1_IP6_SIPv1_BLEN 32 +#define IP6_RUL2_V1_IP6_SIPV1_FLAG HSL_RW + + +#define IP6_RUL2_V2 2 +#define IP6_RUL2_V2_OFFSET 0x58008 +#define IP6_RUL2_V2_E_LENGTH 4 +#define IP6_RUL2_V2_E_OFFSET 0x20 +#define IP6_RUL2_V2_NR_E 96 + +#define IP6_SIPV2 +#define IP6_RUL2_V2_IP6_SIPV2_BOFFSET 0 +#define IP6_RUL2_V2_IP6_SIPv2_BLEN 32 +#define IP6_RUL2_V2_IP6_SIPV2_FLAG HSL_RW + + +#define IP6_RUL2_V3 3 +#define IP6_RUL2_V3_OFFSET 0x5800c +#define IP6_RUL2_V3_E_LENGTH 4 +#define IP6_RUL2_V3_E_OFFSET 0x20 +#define IP6_RUL2_V3_NR_E 96 + +#define IP6_SIPV3 +#define IP6_RUL2_V3_IP6_SIPV3_BOFFSET 0 +#define IP6_RUL2_V3_IP6_SIPv3_BLEN 32 +#define IP6_RUL2_V3_IP6_SIPV3_FLAG HSL_RW + + +#define IP6_RUL2_V4 4 +#define IP6_RUL2_V4_OFFSET 0x58010 +#define IP6_RUL2_V4_E_LENGTH 4 +#define IP6_RUL2_V4_E_OFFSET 0x20 +#define IP6_RUL2_V4_NR_E 96 + + +#define IP6_RUL2_M0 5 +#define IP6_RUL2_M0_OFFSET 0x59000 +#define IP6_RUL2_M0_E_LENGTH 4 +#define IP6_RUL2_M0_E_OFFSET 0x20 +#define IP6_RUL2_M0_NR_E 96 + +#define IP6_SIPM0 +#define IP6_RUL2_M0_IP6_SIPM0_BOFFSET 0 +#define IP6_RUL2_M0_IP6_SIPM0_BLEN 32 +#define IP6_RUL2_M0_IP6_SIPM0_FLAG HSL_RW + + +#define IP6_RUL2_M1 6 +#define IP6_RUL2_M1_OFFSET 0x59004 +#define IP6_RUL2_M1_E_LENGTH 4 +#define IP6_RUL2_M1_E_OFFSET 0x20 +#define IP6_RUL2_M1_NR_E 96 + +#define IP6_SIPM1 +#define IP6_RUL2_M1_IP6_DIPM1_BOFFSET 0 +#define IP6_RUL2_M1_IP6_DIPM1_BLEN 32 +#define IP6_RUL2_M1_IP6_DIPM1_FLAG HSL_RW + + +#define IP6_RUL2_M2 7 +#define IP6_RUL2_M2_OFFSET 0x59008 +#define IP6_RUL2_M2_E_LENGTH 4 +#define IP6_RUL2_M2_E_OFFSET 0x20 +#define IP6_RUL2_M2_NR_E 96 + +#define IP6_SIPM2 +#define IP6_RUL2_M2_IP6_DIPM2_BOFFSET 0 +#define IP6_RUL2_M2_IP6_DIPM2_BLEN 32 +#define IP6_RUL2_M2_IP6_DIPM2_FLAG HSL_RW + + +#define IP6_RUL2_M3 8 +#define IP6_RUL2_M3_OFFSET 0x5900c +#define IP6_RUL2_M3_E_LENGTH 4 +#define IP6_RUL2_M3_E_OFFSET 0x20 +#define IP6_RUL2_M3_NR_E 96 + +#define IP6_SIPM3 +#define IP6_RUL2_M3_IP6_SIPM3_BOFFSET 0 +#define IP6_RUL2_M3_IP6_SIPM3_BLEN 32 +#define IP6_RUL2_M3_IP6_SIPM3_FLAG HSL_RW + + +#define IP6_RUL2_M4 9 +#define IP6_RUL2_M4_OFFSET 0x59010 +#define IP6_RUL2_M4_E_LENGTH 4 +#define IP6_RUL2_M4_E_OFFSET 0x20 +#define IP6_RUL2_M4_NR_E 96 + + + + + /* IP6 Type3 Rule Field Define */ +#define IP6_RUL3_V0 0 +#define IP6_RUL3_V0_OFFSET 0x58000 +#define IP6_RUL3_V0_E_LENGTH 4 +#define IP6_RUL3_V0_E_OFFSET 0x20 +#define IP6_RUL3_V0_NR_E 96 + +#define IP6PROTV +#define IP6_RUL3_V0_IP6PROTV_BOFFSET 0 +#define IP6_RUL3_V0_IP6PROTV_BLEN 8 +#define IP6_RUL3_V0_IP6PROTV_FLAG HSL_RW + +#define IP6DSCPV +#define IP6_RUL3_V0_IP6DSCPV_BOFFSET 8 +#define IP6_RUL3_V0_IP6DSCPV_BLEN 8 +#define IP6_RUL3_V0_IP6DSCPV_FLAG HSL_RW + + +#define IP6_RUL3_V1 1 +#define IP6_RUL3_V1_OFFSET 0x58004 +#define IP6_RUL3_V1_E_LENGTH 4 +#define IP6_RUL3_V1_E_OFFSET 0x20 +#define IP6_RUL3_V1_NR_E 96 + +#define IP6LABEL1V +#define IP6_RUL3_V1_IP6LABEL1V_BOFFSET 16 +#define IP6_RUL3_V1_IP6LABEL1V_BLEN 16 +#define IP6_RUL3_V1_IP6LABEL1V_FLAG HSL_RW + + +#define IP6_RUL3_V2 2 +#define IP6_RUL3_V2_OFFSET 0x58008 +#define IP6_RUL3_V2_E_LENGTH 4 +#define IP6_RUL3_V2_E_OFFSET 0x20 +#define IP6_RUL3_V2_NR_E 96 + +#define IP6LABEL2V +#define IP6_RUL3_V2_IP6LABEL2V_BOFFSET 0 +#define IP6_RUL3_V2_IP6LABEL2V_BLEN 4 +#define IP6_RUL3_V2_IP6LABEL2V_FLAG HSL_RW + +#define IP6DPORTV +#define IP6_RUL3_V2_IP6DPORTV_BOFFSET 16 +#define IP6_RUL3_V2_IP6DPORTV_BLEN 16 +#define IP6_RUL3_V2_IP6DPORTV_FLAG HSL_RW + + +#define IP6_RUL3_V3 3 +#define IP6_RUL3_V3_OFFSET 0x5800c +#define IP6_RUL3_V3_E_LENGTH 4 +#define IP6_RUL3_V3_E_OFFSET 0x20 +#define IP6_RUL3_V3_NR_E 96 + +#define IP6TCPFLAGV +#define IP6_RUL3_V3_IP6TCPFLAGV_BOFFSET 24 +#define IP6_RUL3_V3_IP6TCPFLAGV_BLEN 6 +#define IP6_RUL3_V3_IP6TCPFLAGV_FLAG HSL_RW + +#define IP6FWDTYPV +#define IP6_RUL3_V3_IP6FWDTYPV_BOFFSET 23 +#define IP6_RUL3_V3_IP6FWDTYPV_BLEN 1 +#define IP6_RUL3_V3_IP6FWDTYPV_FLAG HSL_RW + +#define IP6DHCPV +#define IP6_RUL3_V3_IP6DHCPV_BOFFSET 22 +#define IP6_RUL3_V3_IP6DHCPV_BLEN 1 +#define IP6_RUL3_V3_IP6DHCPV_FLAG HSL_RW + +#define ICMP6_EN +#define IP6_RUL3_V3_ICMP6_EN_BOFFSET 20 +#define IP6_RUL3_V3_ICMP6_EN_BLEN 1 +#define IP6_RUL3_V3_ICMP6_EN_FLAG HSL_RW + +#define IP6SPORTV +#define IP6_RUL3_V3_IP6SPORTV_BOFFSET 0 +#define IP6_RUL3_V3_IP6SPORTV_BLEN 16 +#define IP6_RUL3_V3_IP6SPORTV_FLAG HSL_RW + +#define IP6ICMPTYPV +#define IP6_RUL3_V3_IP6ICMPTYPV_BOFFSET 8 +#define IP6_RUL3_V3_IP6ICMPTYPV_BLEN 8 +#define IP6_RUL3_V3_IP6ICMPTYPV_FLAG HSL_RW + +#define IP6ICMPCODEV +#define IP6_RUL3_V3_IP6ICMPCODEV_BOFFSET 0 +#define IP6_RUL3_V3_IP6ICMPCODEV_BLEN 8 +#define IP6_RUL3_V3_IP6ICMPCODEV_FLAG HSL_RW + + +#define IP6_RUL3_V4 4 +#define IP6_RUL3_V4_OFFSET 0x58010 +#define IP6_RUL3_V4_E_LENGTH 4 +#define IP6_RUL3_V4_E_OFFSET 0x20 +#define IP6_RUL3_V4_NR_E 96 + + +#define IP6_RUL3_M0 5 +#define IP6_RUL3_M0_OFFSET 0x59000 +#define IP6_RUL3_M0_E_LENGTH 4 +#define IP6_RUL3_M0_E_OFFSET 0x20 +#define IP6_RUL3_M0_NR_E 96 + +#define IP6PROTM +#define IP6_RUL3_M0_IP6PROTM_BOFFSET 0 +#define IP6_RUL3_M0_IP6PROTM_BLEN 8 +#define IP6_RUL3_M0_IP6PROTM_FLAG HSL_RW + +#define IP6DSCPM +#define IP6_RUL3_M0_IP6DSCPM_BOFFSET 8 +#define IP6_RUL3_M0_IP6DSCPM_BLEN 8 +#define IP6_RUL3_M0_IP6DSCPM_FLAG HSL_RW + + +#define IP6_RUL3_M1 6 +#define IP6_RUL3_M1_OFFSET 0x59004 +#define IP6_RUL3_M1_E_LENGTH 4 +#define IP6_RUL3_M1_E_OFFSET 0x20 +#define IP6_RUL3_M1_NR_E 96 + +#define IP6LABEL1M +#define IP6_RUL3_M1_IP6LABEL1M_BOFFSET 16 +#define IP6_RUL3_M1_IP6LABEL1M_BLEN 16 +#define IP6_RUL3_M1_IP6LABEL1M_FLAG HSL_RW + + +#define IP6_RUL3_M2 7 +#define IP6_RUL3_M2_OFFSET 0x59008 +#define IP6_RUL3_M2_E_LENGTH 4 +#define IP6_RUL3_M2_E_OFFSET 0x20 +#define IP6_RUL3_M2_NR_E 96 + +#define IP6LABEL2M +#define IP6_RUL3_M2_IP6LABEL2M_BOFFSET 0 +#define IP6_RUL3_M2_IP6LABEL2M_BLEN 4 +#define IP6_RUL3_M2_IP6LABEL21M_FLAG HSL_RW + +#define IP6DPORTM +#define IP6_RUL3_M2_IP6DPORTM_BOFFSET 16 +#define IP6_RUL3_M2_IP6DPORTM_BLEN 16 +#define IP6_RUL3_M2_IP6DPORTM_FLAG HSL_RW + + +#define IP6_RUL3_M3 8 +#define IP6_RUL3_M3_OFFSET 0x5900c +#define IP6_RUL3_M3_E_LENGTH 4 +#define IP6_RUL3_M3_E_OFFSET 0x20 +#define IP6_RUL3_M3_NR_E 96 + +#define IP6TCPFLAGM +#define IP6_RUL3_M3_IP6TCPFLAGM_BOFFSET 24 +#define IP6_RUL3_M3_IP6TCPFLAGM_BLEN 6 +#define IP6_RUL3_M3_IP6TCPFLAGM_FLAG HSL_RW + +#define IP6RWDTYPM +#define IP6_RUL3_M3_IP6RWDTYPV_BOFFSET 23 +#define IP6_RUL3_M3_IP6RWDTYPV_BLEN 1 +#define IP6_RUL3_M3_IP6RWDTYPV_FLAG HSL_RW + +#define IP6DHCPM +#define IP6_RUL3_M3_IP6DHCPM_BOFFSET 22 +#define IP6_RUL3_M3_IP6DHCPM_BLEN 1 +#define IP6_RUL3_M3_IP6DHCPM_FLAG HSL_RW + +#define IP6DPORTM_EN +#define IP6_RUL3_M3_IP6DPORTM_EN_BOFFSET 17 +#define IP6_RUL3_M3_IP6DPORTM_EN_BLEN 1 +#define IP6_RUL3_M3_IP6DPORTM_EN_FLAG HSL_RW + +#define IP6SPORTM_EN +#define IP6_RUL3_M3_IP6SPORTM_EN_BOFFSET 16 +#define IP6_RUL3_M3_IP6SPORTM_EN_BLEN 1 +#define IP6_RUL3_M3_IP6SPORTM_EN_FLAG HSL_RW + +#define IP6SPORTM +#define IP6_RUL3_M3_IP6SPORTM_BOFFSET 0 +#define IP6_RUL3_M3_IP6SPORTM_BLEN 16 +#define IP6_RUL3_M3_IP6SPORTM_FLAG HSL_RW + +#define IP6ICMPTYPM +#define IP6_RUL3_M3_IP6ICMPTYPM_BOFFSET 8 +#define IP6_RUL3_M3_IP6ICMPTYPM_BLEN 8 +#define IP6_RUL3_M3_IP6ICMPTYPM_FLAG HSL_RW + +#define IP6ICMPCODEM +#define IP6_RUL3_M3_IP6ICMPCODEM_BOFFSET 0 +#define IP6_RUL3_M3_IP6ICMPCODEM_BLEN 8 +#define IP6_RUL3_M3_IP6ICMPCODEM_FLAG HSL_RW + + +#define IP6_RUL3_M4 9 +#define IP6_RUL3_M4_OFFSET 0x59010 +#define IP6_RUL3_M4_E_LENGTH 4 +#define IP6_RUL3_M4_E_OFFSET 0x20 +#define IP6_RUL3_M4_NR_E 96 + + + + + /* Enhanced MAC Type Rule Field Define */ +#define EHMAC_RUL_V0 0 +#define EHMAC_RUL_V0_OFFSET 0x58000 +#define EHMAC_RUL_V0_E_LENGTH 4 +#define EHMAC_RUL_V0_E_OFFSET 0x20 +#define EHMAC_RUL_V0_NR_E 96 + +#define DAV_BYTE2 +#define EHMAC_RUL_V0_DAV_BYTE2_BOFFSET 24 +#define EHMAC_RUL_V0_DAV_BYTE2_BLEN 8 +#define EHMAC_RUL_V0_DAV_BYTE2_FLAG HSL_RW + +#define DAV_BYTE3 +#define EHMAC_RUL_V0_DAV_BYTE3_BOFFSET 16 +#define EHMAC_RUL_V0_DAV_BYTE3_BLEN 8 +#define EHMAC_RUL_V0_DAV_BYTE3_FLAG HSL_RW + +#define DAV_BYTE4 +#define EHMAC_RUL_V0_DAV_BYTE4_BOFFSET 8 +#define EHMAC_RUL_V0_DAV_BYTE4_BLEN 8 +#define EHMAC_RUL_V0_DAV_BYTE4_FLAG HSL_RW + +#define DAV_BYTE5 +#define EHMAC_RUL_V0_DAV_BYTE5_BOFFSET 0 +#define EHMAC_RUL_V0_DAV_BYTE5_BLEN 8 +#define EHMAC_RUL_V0_DAV_BYTE5_FLAG HSL_RW + + +#define EHMAC_RUL_V1 1 +#define EHMAC_RUL_V1_OFFSET 0x58004 +#define EHMAC_RUL_V1_E_LENGTH 4 +#define EHMAC_RUL_V1_E_OFFSET 0x20 +#define EHMAC_RUL_V1_NR_E 96 + +#define SAV_BYTE4 +#define EHMAC_RUL_V1_SAV_BYTE4_BOFFSET 24 +#define EHMAC_RUL_V1_SAV_BYTE4_BLEN 8 +#define EHMAC_RUL_V1_SAV_BYTE4_FLAG HSL_RW + +#define SAV_BYTE5 +#define EHMAC_RUL_V1_SAV_BYTE5_BOFFSET 16 +#define EHMAC_RUL_V1_SAV_BYTE5_BLEN 8 +#define EHMAC_RUL_V1_SAV_BYTE5_FLAG HSL_RW + +#define DAV_BYTE0 +#define EHMAC_RUL_V1_DAV_BYTE0_BOFFSET 8 +#define EHMAC_RUL_V1_DAV_BYTE0_BLEN 8 +#define EHMAC_RUL_V1_DAV_BYTE0_FLAG HSL_RW + +#define DAV_BYTE1 +#define EHMAC_RUL_V1_DAV_BYTE1_BOFFSET 0 +#define EHMAC_RUL_V1_DAV_BYTE1_BLEN 8 +#define EHMAC_RUL_V1_DAV_BYTE1_FLAG HSL_RW + + +#define EHMAC_RUL_V2 2 +#define EHMAC_RUL_V2_OFFSET 0x58008 +#define EHMAC_RUL_V2_E_LENGTH 4 +#define EHMAC_RUL_V2_E_OFFSET 0x20 +#define EHMAC_RUL_V2_NR_E 96 + +#define CTAG_VIDLV +#define EHMAC_RUL_V2_CTAG_VIDLV_BOFFSET 24 +#define EHMAC_RUL_V2_CTAG_VIDLV_BLEN 8 +#define EHMAC_RUL_V2_CTAG_VIDLV_FLAG HSL_RW + +#define STAG_PRIV +#define EHMAC_RUL_V2_STAG_PRIV_BOFFSET 21 +#define EHMAC_RUL_V2_STAG_PRIV_BLEN 3 +#define EHMAC_RUL_V2_STAG_PRIV_FLAG HSL_RW + +#define STAG_DEIV +#define EHMAC_RUL_V2_STAG_DEIV_BOFFSET 20 +#define EHMAC_RUL_V2_STAG_DEIV_BLEN 1 +#define EHMAC_RUL_V2_STAG_DEIV_FLAG HSL_RW + +#define STAG_VIDV +#define EHMAC_RUL_V2_STAG_VIDV_BOFFSET 8 +#define EHMAC_RUL_V2_STAG_VIDV_BLEN 12 +#define EHMAC_RUL_V2_STAG_VIDV_FLAG HSL_RW + +#define SAV_BYTE3 +#define EHMAC_RUL_V2_SAV_BYTE3_BOFFSET 0 +#define EHMAC_RUL_V2_SAV_BYTE3_BLEN 8 +#define EHMAC_RUL_V2_SAV_BYTE3_FLAG HSL_RW + + +#define EHMAC_RUL_V3 3 +#define EHMAC_RUL_V3_ID 13 +#define EHMAC_RUL_V3_OFFSET 0x5800c +#define EHMAC_RUL_V3_E_LENGTH 4 +#define EHMAC_RUL_V3_E_OFFSET 0x20 +#define EHMAC_RUL_V3_NR_E 96 + +#define STAGGEDM +#define EHMAC_RUL_V3_STAGGEDM_BOFFSET 31 +#define EHMAC_RUL_V3_STAGGEDM_BLEN 1 +#define EHMAC_RUL_V3_STAGGEDM_FLAG HSL_RW + +#define STAGGEDV +#define EHMAC_RUL_V3_STAGGEDV_BOFFSET 30 +#define EHMAC_RUL_V3_STAGGEDV_BLEN 1 +#define EHMAC_RUL_V3_STAGGEDV_FLAG HSL_RW + +#define DA_EN +#define EHMAC_RUL_V3_DA_EN_BOFFSET 25 +#define EHMAC_RUL_V3_DA_EN_BLEN 1 +#define EHMAC_RUL_V3_DA_EN_FLAG HSL_RW + +#define SVIDMSK +#define EHMAC_RUL_V3_SVIDMSK_BOFFSET 24 +#define EHMAC_RUL_V3_SVIDMSK_BLEN 1 +#define EHMAC_RUL_V3_SVIDMSK_FLAG HSL_RW + +#define ETHTYPV +#define EHMAC_RUL_V3_ETHTYPV_BOFFSET 8 +#define EHMAC_RUL_V3_ETHTYPV_BLEN 16 +#define EHMAC_RUL_V3_ETHTYPV_FLAG HSL_RW + +#define CTAG_PRIV +#define EHMAC_RUL_V3_CTAG_PRIV_BOFFSET 5 +#define EHMAC_RUL_V3_CTAG_PRIV_BLEN 3 +#define EHMAC_RUL_V3_CTAG_PRIV_FLAG HSL_RW + +#define CTAG_CFIV +#define EHMAC_RUL_V3_CTAG_CFIV_BOFFSET 4 +#define EHMAC_RUL_V3_CTAG_CFIV_BLEN 1 +#define EHMAC_RUL_V3_CTAG_CFIV_FLAG HSL_RW + +#define CTAG_VIDHV +#define EHMAC_RUL_V3_CTAG_VIDHV_BOFFSET 0 +#define EHMAC_RUL_V3_CTAG_VIDHV_BLEN 4 +#define EHMAC_RUL_V3_CTAG_VIDHV_FLAG HSL_RW + + +#define EHMAC_RUL_V4 4 +#define EHMAC_RUL_V4_OFFSET 0x58010 +#define EHMAC_RUL_V4_E_LENGTH 4 +#define EHMAC_RUL_V4_E_OFFSET 0x20 +#define EHMAC_RUL_V4_NR_E 96 + + +#define EHMAC_RUL_M0 5 +#define EHMAC_RUL_M0_OFFSET 0x59000 +#define EHMAC_RUL_M0_E_LENGTH 4 +#define EHMAC_RUL_M0_E_OFFSET 0x20 +#define EHMAC_RUL_M0_NR_E 96 + +#define DAM_BYTE2 +#define EHMAC_RUL_M0_DAM_BYTE2_BOFFSET 24 +#define EHMAC_RUL_M0_DAM_BYTE2_BLEN 8 +#define EHMAC_RUL_M0_DAM_BYTE2_FLAG HSL_RW + +#define DAM_BYTE3 +#define EHMAC_RUL_M0_DAM_BYTE3_BOFFSET 16 +#define EHMAC_RUL_M0_DAM_BYTE3_BLEN 8 +#define EHMAC_RUL_M0_DAM_BYTE3_FLAG HSL_RW + +#define DAM_BYTE4 +#define EHMAC_RUL_M0_DAM_BYTE4_BOFFSET 8 +#define EHMAC_RUL_M0_DAM_BYTE4_BLEN 8 +#define EHMAC_RUL_M0_DAM_BYTE4_FLAG HSL_RW + +#define DAM_BYTE5 +#define EHMAC_RUL_M0_DAM_BYTE5_BOFFSET 0 +#define EHMAC_RUL_M0_DAM_BYTE5_BLEN 8 +#define EHMAC_RUL_M0_DAM_BYTE5_FLAG HSL_RW + + +#define EHMAC_RUL_M1 6 +#define EHMAC_RUL_M1_OFFSET 0x59004 +#define EHMAC_RUL_M1_E_LENGTH 4 +#define EHMAC_RUL_M1_E_OFFSET 0x20 +#define EHMAC_RUL_M1_NR_E 96 + +#define SAM_BYTE4 +#define EHMAC_RUL_M1_SAM_BYTE4_BOFFSET 24 +#define EHMAC_RUL_M1_SAM_BYTE4_BLEN 8 +#define EHMAC_RUL_M1_SAM_BYTE4_FLAG HSL_RW + +#define SAM_BYTE5 +#define EHMAC_RUL_M1_SAM_BYTE5_BOFFSET 16 +#define EHMAC_RUL_M1_SAM_BYTE5_BLEN 8 +#define EHMAC_RUL_M1_SAM_BYTE5_FLAG HSL_RW + +#define DAM_BYTE0 +#define EHMAC_RUL_M1_DAM_BYTE0_BOFFSET 8 +#define EHMAC_RUL_M1_DAM_BYTE0_BLEN 8 +#define EHMAC_RUL_M1_DAM_BYTE0_FLAG HSL_RW + +#define DAM_BYTE1 +#define EHMAC_RUL_M1_DAM_BYTE1_BOFFSET 0 +#define EHMAC_RUL_M1_DAM_BYTE1_BLEN 8 +#define EHMAC_RUL_M1_DAM_BYTE1_FLAG HSL_RW + + +#define EHMAC_RUL_M2 7 +#define EHMAC_RUL_M2_OFFSET 0x59008 +#define EHMAC_RUL_M2_E_LENGTH 4 +#define EHMAC_RUL_M2_E_OFFSET 0x20 +#define EHMAC_RUL_M2_NR_E 96 + +#define CTAG_VIDLM +#define EHMAC_RUL_M2_CTAG_VIDLM_BOFFSET 24 +#define EHMAC_RUL_M2_CTAG_VIDLM_BLEN 8 +#define EHMAC_RUL_M2_CTAG_VIDLM_FLAG HSL_RW + +#define STAG_PRIM +#define EHMAC_RUL_M2_STAG_PRIM_BOFFSET 21 +#define EHMAC_RUL_M2_STAG_PRIM_BLEN 3 +#define EHMAC_RUL_M2_STAG_PRIM_FLAG HSL_RW + +#define STAG_DEIM +#define EHMAC_RUL_M2_STAG_DEIM_BOFFSET 20 +#define EHMAC_RUL_M2_STAG_DEIM_BLEN 1 +#define EHMAC_RUL_M2_STAG_DEIM_FLAG HSL_RW + +#define STAG_VIDM +#define EHMAC_RUL_M2_STAG_VIDM_BOFFSET 8 +#define EHMAC_RUL_M2_STAG_VIDM_BLEN 12 +#define EHMAC_RUL_M2_STAG_VIDM_FLAG HSL_RW + +#define SAM_BYTE3 +#define EHMAC_RUL_M2_SAM_BYTE3_BOFFSET 0 +#define EHMAC_RUL_M2_SAM_BYTE3_BLEN 8 +#define EHMAC_RUL_M2_SAM_BYTE3_FLAG HSL_RW + + +#define EHMAC_RUL_M3 8 +#define EHMAC_RUL_M3_OFFSET 0x5900c +#define EHMAC_RUL_M3_E_LENGTH 4 +#define EHMAC_RUL_M3_E_OFFSET 0x20 +#define EHMAC_RUL_M3_NR_E 96 + +#define ETHTYPM +#define EHMAC_RUL_M3_ETHTYPM_BOFFSET 8 +#define EHMAC_RUL_M3_ETHTYPM_BLEN 16 +#define EHMAC_RUL_M3_ETHTYPM_FLAG HSL_RW + +#define CTAG_PRIM +#define EHMAC_RUL_M3_CTAG_PRIM_BOFFSET 5 +#define EHMAC_RUL_M3_CTAG_PRIM_BLEN 3 +#define EHMAC_RUL_M3_CTAG_PRIM_FLAG HSL_RW + +#define CTAG_CFIM +#define EHMAC_RUL_M3_CTAG_CFIM_BOFFSET 4 +#define EHMAC_RUL_M3_CTAG_CFIM_BLEN 1 +#define EHMAC_RUL_M3_CTAG_CFIM_FLAG HSL_RW + +#define CTAG_VIDHM +#define EHMAC_RUL_M3_CTAG_VIDHM_BOFFSET 0 +#define EHMAC_RUL_M3_CTAG_VIDHM_BLEN 4 +#define EHMAC_RUL_M3_CTAG_VIDHM_FLAG HSL_RW + + +#define EHMAC_RUL_M4 9 +#define EHMAC_RUL_M4_OFFSET 0x59010 +#define EHMAC_RUL_M4_E_LENGTH 4 +#define EHMAC_RUL_M4_E_OFFSET 0x20 +#define EHMAC_RUL_M4_NR_E 96 + +#define CTAGGEDM +#define EHMAC_RUL_M4_CTAGGEDM_BOFFSET 5 +#define EHMAC_RUL_M4_CTAGGEDM_BLEN 1 +#define EHMAC_RUL_M4_CTAGGEDM_FLAG HSL_RW + +#define CTAGGEDV +#define EHMAC_RUL_M4_CTAGGEDV_BOFFSET 4 +#define EHMAC_RUL_M4_CTAGGEDV_BLEN 1 +#define EHMAC_RUL_M4_CTAGGEDV_FLAG HSL_RW + +#define CVIDMSK +#define EHMAC_RUL_M4_CVIDMSK_BOFFSET 3 +#define EHMAC_RUL_M4_CVIDMSK_BLEN 1 +#define EHMAC_RUL_M4_CVIDMSK_FLAG HSL_RW + + + + + /* PPPoE Session Table Define */ +#define PPPOE_SESSION +#define PPPOE_SESSION_OFFSET 0x5f000 +#define PPPOE_SESSION_E_LENGTH 4 +#define PPPOE_SESSION_E_OFFSET 0x4 +#define PPPOE_SESSION_NR_E 16 + +#define ENTRY_VALID +#define PPPOE_SESSION_ENTRY_VALID_BOFFSET 16 +#define PPPOE_SESSION_ENTRY_VALID_BLEN 2 +#define PPPOE_SESSION_ENTRY_VALID_FLAG HSL_RW + +#define SEESION_ID +#define PPPOE_SESSION_SEESION_ID_BOFFSET 0 +#define PPPOE_SESSION_SEESION_ID_BLEN 16 +#define PPPOE_SESSION_SEESION_ID_FLAG HSL_RW + + +#define PPPOE_EDIT +#define PPPOE_EDIT_OFFSET 0x02200 +#define PPPOE_EDIT_E_LENGTH 4 +#define PPPOE_EDIT_E_OFFSET 0x10 +#define PPPOE_EDIT_NR_E 16 + +#define EDIT_ID +#define PPPOE_EDIT_EDIT_ID_BOFFSET 0 +#define PPPOE_EDIT_EDIT_ID_BLEN 16 +#define PPPOE_EDIT_EDIT_ID_FLAG HSL_RW + + + + + /* L3 Host Entry Defile */ +#define HOST_ENTRY0 +#define HOST_ENTRY0_OFFSET 0x0e48 +#define HOST_ENTRY0_E_LENGTH 4 +#define HOST_ENTRY0_E_OFFSET 0x0 +#define HOST_ENTRY0_NR_E 1 + +#define IP_ADDR +#define HOST_ENTRY0_IP_ADDR_BOFFSET 0 +#define HOST_ENTRY0_IP_ADDR_BLEN 32 +#define HOST_ENTRY0_IP_ADDR_FLAG HSL_RW + +#define HOST_ENTRY1 +#define HOST_ENTRY1_OFFSET 0x0e4c +#define HOST_ENTRY1_E_LENGTH 4 +#define HOST_ENTRY1_E_OFFSET 0x0 +#define HOST_ENTRY1_NR_E 1 + +#define MAC_ADDR2 +#define HOST_ENTRY1_MAC_ADDR2_BOFFSET 24 +#define HOST_ENTRY1_MAC_ADDR2_BLEN 8 +#define HOST_ENTRY1_MAC_ADDR2_FLAG HSL_RW + +#define MAC_ADDR3 +#define HOST_ENTRY1_MAC_ADDR3_BOFFSET 16 +#define HOST_ENTRY1_MAC_ADDR3_BLEN 8 +#define HOST_ENTRY1_MAC_ADDR3_FLAG HSL_RW + +#define MAC_ADDR4 +#define HOST_ENTRY1_MAC_ADDR4_BOFFSET 8 +#define HOST_ENTRY1_MAC_ADDR4_BLEN 8 +#define HOST_ENTRY1_MAC_ADDR4_FLAG HSL_RW + +#define MAC_ADDR5 +#define HOST_ENTRY1_MAC_ADDR5_BOFFSET 0 +#define HOST_ENTRY1_MAC_ADDR5_BLEN 8 +#define HOST_ENTRY1_MAC_ADDR5_FLAG HSL_RW + +#define HOST_ENTRY2 +#define HOST_ENTRY2_OFFSET 0x0e50 +#define HOST_ENTRY2_E_LENGTH 4 +#define HOST_ENTRY2_E_OFFSET 0x0 +#define HOST_ENTRY2_NR_E 1 + +#define CPU_ADDR +#define HOST_ENTRY2_CPU_ADDR_BOFFSET 31 +#define HOST_ENTRY2_CPU_ADDR_BLEN 1 +#define HOST_ENTRY2_CPU_ADDR_FLAG HSL_RW + +#define SRC_PORT +#define HOST_ENTRY2_SRC_PORT_BOFFSET 28 +#define HOST_ENTRY2_SRC_PORT_BLEN 3 +#define HOST_ENTRY2_SRC_PORT_FLAG HSL_RW + +#define INTF_ID +#define HOST_ENTRY2_INTF_ID_BOFFSET 16 +#define HOST_ENTRY2_INTF_ID_BLEN 12 +#define HOST_ENTRY2_INTF_ID_FLAG HSL_RW + +#define MAC_ADDR0 +#define HOST_ENTRY2_MAC_ADDR0_BOFFSET 8 +#define HOST_ENTRY2_MAC_ADDR0_BLEN 8 +#define HOST_ENTRY2_MAC_ADDR0_FLAG HSL_RW + +#define MAC_ADDR1 +#define HOST_ENTRY2_MAC_ADDR1_BOFFSET 0 +#define HOST_ENTRY2_MAC_ADDR1_BLEN 8 +#define HOST_ENTRY2_MAC_ADDR1_FLAG HSL_RW + + +#define HOST_ENTRY3 +#define HOST_ENTRY3_OFFSET 0x0e54 +#define HOST_ENTRY3_E_LENGTH 4 +#define HOST_ENTRY3_E_OFFSET 0x0 +#define HOST_ENTRY3_NR_E 1 + +#define IP_VER +#define HOST_ENTRY3_IP_VER_BOFFSET 15 +#define HOST_ENTRY3_IP_VER_BLEN 1 +#define HOST_ENTRY3_IP_VER_FLAG HSL_RW + +#define AGE_FLAG +#define HOST_ENTRY3_AGE_FLAG_BOFFSET 12 +#define HOST_ENTRY3_AGE_FLAG_BLEN 3 +#define HOST_ENTRY3_AGE_FLAG_FLAG HSL_RW + +#define PPPOE_EN +#define HOST_ENTRY3_PPPOE_EN_BOFFSET 11 +#define HOST_ENTRY3_PPPOE_EN_BLEN 1 +#define HOST_ENTRY3_PPPOE_EN_FLAG HSL_RW + +#define PPPOE_IDX +#define HOST_ENTRY3_PPPOE_IDX_BOFFSET 7 +#define HOST_ENTRY3_PPPOE_IDX_BLEN 4 +#define HOST_ENTRY3_PPPOE_IDX_FLAG HSL_RW + +#define CNT_EN +#define HOST_ENTRY3_CNT_EN_BOFFSET 6 +#define HOST_ENTRY3_CNT_EN_BLEN 1 +#define HOST_ENTRY3_CNT_EN_FLAG HSL_RW + +#define CNT_IDX +#define HOST_ENTRY3_CNT_IDX_BOFFSET 2 +#define HOST_ENTRY3_CNT_IDX_BLEN 4 +#define HOST_ENTRY3_CNT_IDX_FLAG HSL_RW + +#define ACTION +#define HOST_ENTRY3_ACTION_BOFFSET 0 +#define HOST_ENTRY3_ACTION_BLEN 2 +#define HOST_ENTRY3_ACTION_FLAG HSL_RW + + +#define HOST_ENTRY4 +#define HOST_ENTRY4_OFFSET 0x0e58 +#define HOST_ENTRY4_E_LENGTH 4 +#define HOST_ENTRY4_E_OFFSET 0x0 +#define HOST_ENTRY4_NR_E 1 + +#define TBL_BUSY +#define HOST_ENTRY4_TBL_BUSY_BOFFSET 31 +#define HOST_ENTRY4_TBL_BUSY_BLEN 1 +#define HOST_ENTRY4_TBL_BUSY_FLAG HSL_RW + +#define SPEC_SP +#define HOST_ENTRY4_SPEC_SP_BOFFSET 22 +#define HOST_ENTRY4_SPEC_SP_BLEN 1 +#define HOST_ENTRY4_SPEC_SP_FLAG HSL_RW + +#define SPEC_VID +#define HOST_ENTRY4_SPEC_VID_BOFFSET 21 +#define HOST_ENTRY4_SPEC_VID_BLEN 1 +#define HOST_ENTRY4_SPEC_VID_FLAG HSL_RW + +#define SPEC_PIP +#define HOST_ENTRY4_SPEC_PIP_BOFFSET 20 +#define HOST_ENTRY4_SPEC_PIP_BLEN 1 +#define HOST_ENTRY4_SPEC_PIP_FLAG HSL_RW + +#define SPEC_SIP +#define HOST_ENTRY4_SPEC_SIP_BOFFSET 19 +#define HOST_ENTRY4_SPEC_SIP_BLEN 1 +#define HOST_ENTRY4_SPEC_SIP_FLAG HSL_RW + +#define SPEC_STATUS +#define HOST_ENTRY4_SPEC_STATUS_BOFFSET 18 +#define HOST_ENTRY4_SPEC_STATUS_BLEN 1 +#define HOST_ENTRY4_SPEC_STATUS_FLAG HSL_RW + +#define TBL_IDX +#define HOST_ENTRY4_TBL_IDX_BOFFSET 8 +#define HOST_ENTRY4_TBL_IDX_BLEN 10 +#define HOST_ENTRY4_TBL_IDX_FLAG HSL_RW + +#define TBL_STAUS +#define HOST_ENTRY4_TBL_STAUS_BOFFSET 7 +#define HOST_ENTRY4_TBL_STAUS_BLEN 1 +#define HOST_ENTRY4_TBL_STAUS_FLAG HSL_RW + +#define TBL_SEL +#define HOST_ENTRY4_TBL_SEL_BOFFSET 4 +#define HOST_ENTRY4_TBL_SEL_BLEN 2 +#define HOST_ENTRY4_TBL_SEL_FLAG HSL_RW + +#define ENTRY_FUNC +#define HOST_ENTRY4_ENTRY_FUNC_BOFFSET 0 +#define HOST_ENTRY4_ENTRY_FUNC_BLEN 3 +#define HOST_ENTRY4_ENTRY_FUNC_FLAG HSL_RW + + + + +#define NAT_ENTRY0 +#define NAT_ENTRY0_OFFSET 0x0e48 +#define NAT_ENTRY0_E_LENGTH 4 +#define NAT_ENTRY0_E_OFFSET 0x0 +#define NAT_ENTRY0_NR_E 1 + +#define IP_ADDR +#define NAT_ENTRY0_IP_ADDR_BOFFSET 0 +#define NAT_ENTRY0_IP_ADDR_BLEN 32 +#define NAT_ENTRY0_IP_ADDR_FLAG HSL_RW + + +#define NAT_ENTRY1 +#define NAT_ENTRY1_OFFSET 0x0e4c +#define NAT_ENTRY1_E_LENGTH 4 +#define NAT_ENTRY1_E_OFFSET 0x0 +#define NAT_ENTRY1_NR_E 1 + +#define PRV_IPADDR0 +#define NAT_ENTRY1_PRV_IPADDR0_BOFFSET 24 +#define NAT_ENTRY1_PRV_IPADDR0_BLEN 8 +#define NAT_ENTRY1_PRV_IPADDR0_FLAG HSL_RW + +#define PORT_RANGE +#define NAT_ENTRY1_PORT_RANGE_BOFFSET 16 +#define NAT_ENTRY1_PORT_RANGE_BLEN 8 +#define NAT_ENTRY1_PORT_RANGE_FLAG HSL_RW + +#define PORT_NUM +#define NAT_ENTRY1_PORT_NUM_BOFFSET 0 +#define NAT_ENTRY1_PORT_NUM_BLEN 16 +#define NAT_ENTRY1_PORT_NUM_FLAG HSL_RW + + +#define NAT_ENTRY2 +#define NAT_ENTRY2_OFFSET 0x0e50 +#define NAT_ENTRY2_E_LENGTH 4 +#define NAT_ENTRY2_E_OFFSET 0x0 +#define NAT_ENTRY2_NR_E 1 + +#define ENTRY_VALID +#define NAT_ENTRY2_ENTRY_VALID_BOFFSET 15 +#define NAT_ENTRY2_ENTRY_VALID_BLEN 1 +#define NAT_ENTRY2_ENTRY_VALID_FLAG HSL_RW + +#define PORT_EN +#define NAT_ENTRY2_PORT_EN_BOFFSET 14 +#define NAT_ENTRY2_PORT_EN_BLEN 1 +#define NAT_ENTRY2_PORT_EN_FLAG HSL_RW + +#define PRO_TYP +#define NAT_ENTRY2_PRO_TYP_BOFFSET 12 +#define NAT_ENTRY2_PRO_TYP_BLEN 2 +#define NAT_ENTRY2_PRO_TYP_FLAG HSL_RW + +#define HASH_KEY +#define NAT_ENTRY2_HASH_KEY_BOFFSET 10 +#define NAT_ENTRY2_HASH_KEY_BLEN 2 +#define NAT_ENTRY2_HASH_KEY_FLAG HSL_RW + +#define ACTION +#define NAT_ENTRY2_ACTION_BOFFSET 8 +#define NAT_ENTRY2_ACTION_BLEN 2 +#define NAT_ENTRY2_ACTION_FLAG HSL_RW + +#define CNT_EN +#define NAT_ENTRY2_CNT_EN_BOFFSET 7 +#define NAT_ENTRY2_CNT_EN_BLEN 1 +#define NAT_ENTRY2_CNT_EN_FLAG HSL_RW + +#define CNT_IDX +#define NAT_ENTRY2_CNT_IDX_BOFFSET 4 +#define NAT_ENTRY2_CNT_IDX_BLEN 3 +#define NAT_ENTRY2_CNT_IDX_FLAG HSL_RW + +#define PRV_IPADDR1 +#define NAT_ENTRY2_PRV_IPADDR1_BOFFSET 0 +#define NAT_ENTRY2_PRV_IPADDR1_BLEN 4 +#define NAT_ENTRY2_PRV_IPADDR1_FLAG HSL_RW + + + + +#define NAPT_ENTRY0 +#define NAPT_ENTRY0_OFFSET 0x0e48 +#define NAPT_ENTRY0_E_LENGTH 4 +#define NAPT_ENTRY0_E_OFFSET 0x0 +#define NAPT_ENTRY0_NR_E 1 + +#define DST_IPADDR +#define NAPT_ENTRY0_DST_IPADDR_BOFFSET 0 +#define NAPT_ENTRY0_DST_IPADDR_BLEN 32 +#define NAPT_ENTRY0_DST_IPADDR_FLAG HSL_RW + + +#define NAPT_ENTRY1 +#define NAPT_ENTRY1_OFFSET 0x0e4c +#define NAPT_ENTRY1_E_LENGTH 4 +#define NAPT_ENTRY1_E_OFFSET 0x0 +#define NAPT_ENTRY1_NR_E 1 + +#define SRC_PORT +#define NAPT_ENTRY1_SRC_PORT_BOFFSET 16 +#define NAPT_ENTRY1_SRC_PORT_BLEN 16 +#define NAPT_ENTRY1_SRC_PORT_FLAG HSL_RW + +#define DST_PORT +#define NAPT_ENTRY1_DST_PORT_BOFFSET 0 +#define NAPT_ENTRY1_DST_PORT_BLEN 16 +#define NAPT_ENTRY1_DST_PORT_FLAG HSL_RW + + +#define NAPT_ENTRY2 +#define NAPT_ENTRY2_OFFSET 0x0e50 +#define NAPT_ENTRY2_E_LENGTH 4 +#define NAPT_ENTRY2_E_OFFSET 0x0 +#define NAPT_ENTRY2_NR_E 1 + +#define SRC_IPADDR +#define NAPT_ENTRY2_SRC_IPADDR_BOFFSET 20 +#define NAPT_ENTRY2_SRC_IPADDR_BLEN 12 +#define NAPT_ENTRY2_SRC_IPADDR_FLAG HSL_RW + +#define TRANS_IPADDR +#define NAPT_ENTRY2_TRANS_IPADDR_BOFFSET 16 +#define NAPT_ENTRY2_TRANS_IPADDR_BLEN 4 +#define NAPT_ENTRY2_TRANS_IPADDR_FLAG HSL_RW + +#define TRANS_PORT +#define NAPT_ENTRY2_TRANS_PORT_BOFFSET 0 +#define NAPT_ENTRY2_TRANS_PORT_BLEN 16 +#define NAPT_ENTRY2_TRANS_PORT_FLAG HSL_RW + + +#define NAPT_ENTRY3 +#define NAPT_ENTRY3_OFFSET 0x0e54 +#define NAPT_ENTRY3_E_LENGTH 4 +#define NAPT_ENTRY3_E_OFFSET 0x0 +#define NAPT_ENTRY3_NR_E 1 + +#define AGE_FLAG +#define NAPT_ENTRY3_AGE_FLAG_BOFFSET 12 +#define NAPT_ENTRY3_AGE_FLAG_BLEN 4 +#define NAPT_ENTRY3_AGE_FLAG_FLAG HSL_RW + +#define CNT_EN +#define NAPT_ENTRY3_CNT_EN_BOFFSET 7 +#define NAPT_ENTRY3_CNT_EN_BLEN 1 +#define NAPT_ENTRY3_CNT_EN_FLAG HSL_RW + +#define CNT_IDX +#define NAPT_ENTRY3_CNT_IDX_BOFFSET 4 +#define NAPT_ENTRY3_CNT_IDX_BLEN 3 +#define NAPT_ENTRY3_CNT_IDX_FLAG HSL_RW + +#define PROT_TYP +#define NAPT_ENTRY3_PROT_TYP_BOFFSET 2 +#define NAPT_ENTRY3_PROT_TYP_BLEN 2 +#define NAPT_ENTRY3_PROT_TYP_FLAG HSL_RW + +#define ACTION +#define NAPT_ENTRY3_ACTION_BOFFSET 0 +#define NAPT_ENTRY3_ACTION_BLEN 2 +#define NAPT_ENTRY3_ACTION_FLAG HSL_RW + + + + +#define ROUTER_CTRL +#define ROUTER_CTRL_OFFSET 0x0e00 +#define ROUTER_CTRL_E_LENGTH 4 +#define ROUTER_CTRL_E_OFFSET 0x0 +#define ROUTER_CTRL_NR_E 1 + +#define ARP_LEARN_MODE +#define ROUTER_CTRL_ARP_LEARN_MODE_BOFFSET 19 +#define ROUTER_CTRL_ARP_LEARN_MODE_BLEN 1 +#define ROUTER_CTRL_ARP_LEARN_MODE_FLAG HSL_RW + +#define GLB_LOCKTIME +#define ROUTER_CTRL_GLB_LOCKTIME_BOFFSET 16 +#define ROUTER_CTRL_GLB_LOCKTIME_BLEN 2 +#define ROUTER_CTRL_GLB_LOCKTIME_FLAG HSL_RW + +#define ARP_AGE_TIME +#define ROUTER_CTRL_ARP_AGE_TIME_BOFFSET 8 +#define ROUTER_CTRL_ARP_AGE_TIME_BLEN 8 +#define ROUTER_CTRL_ARP_AGE_TIME_FLAG HSL_RW + +#define WCMP_HAHS_DP +#define ROUTER_CTRL_WCMP_HAHS_DP_BOFFSET 7 +#define ROUTER_CTRL_WCMP_HAHS_DP_BLEN 1 +#define ROUTER_CTRL_WCMP_HAHS_DP_FLAG HSL_RW + +#define WCMP_HAHS_DIP +#define ROUTER_CTRL_WCMP_HAHS_DIP_BOFFSET 6 +#define ROUTER_CTRL_WCMP_HAHS_DIP_BLEN 1 +#define ROUTER_CTRL_WCMP_HAHS_DIP_FLAG HSL_RW + +#define WCMP_HAHS_SP +#define ROUTER_CTRL_WCMP_HAHS_SP_BOFFSET 5 +#define ROUTER_CTRL_WCMP_HAHS_SP_BLEN 1 +#define ROUTER_CTRL_WCMP_HAHS_SP_FLAG HSL_RW + +#define WCMP_HAHS_SIP +#define ROUTER_CTRL_WCMP_HAHS_SIP_BOFFSET 4 +#define ROUTER_CTRL_WCMP_HAHS_SIP_BLEN 1 +#define ROUTER_CTRL_WCMP_HAHS_SIP_FLAG HSL_RW + +#define ARP_AGE_MODE +#define ROUTER_CTRL_ARP_AGE_MODE_BOFFSET 1 +#define ROUTER_CTRL_ARP_AGE_MODE_BLEN 1 +#define ROUTER_CTRL_ARP_AGE_MODE_FLAG HSL_RW + +#define ROUTER_EN +#define ROUTER_CTRL_ROUTER_EN_BOFFSET 0 +#define ROUTER_CTRL_ROUTER_EN_BLEN 1 +#define ROUTER_CTRL_ROUTER_EN_FLAG HSL_RW + + + + +#define ROUTER_PTCTRL0 +#define ROUTER_PTCTRL0_OFFSET 0x0e04 +#define ROUTER_PTCTRL0_E_LENGTH 4 +#define ROUTER_PTCTRL0_E_OFFSET 0x0 +#define ROUTER_PTCTRL0_NR_E 1 + + + + +#define ROUTER_PTCTRL1 +#define ROUTER_PTCTRL1_OFFSET 0x0e08 +#define ROUTER_PTCTRL1_E_LENGTH 4 +#define ROUTER_PTCTRL1_E_OFFSET 0x0 +#define ROUTER_PTCTRL1_NR_E 1 + + + +#define ROUTER_PTCTRL2 +#define ROUTER_PTCTRL2_OFFSET 0x0e0c +#define ROUTER_PTCTRL2_E_LENGTH 4 +#define ROUTER_PTCTRL2_E_OFFSET 0x0 +#define ROUTER_PTCTRL2_NR_E 1 + +#define ARP_PT_UP +#define ROUTER_PTCTRL2_ARP_PT_UP_BOFFSET 16 +#define ROUTER_PTCTRL2_ARP_PT_UP_BLEN 7 +#define ROUTER_PTCTRL2_ARP_PT_UP_FLAG HSL_RW + +#define ARP_LEARN_ACK +#define ROUTER_PTCTRL2_ARP_LEARN_ACK_BOFFSET 8 +#define ROUTER_PTCTRL2_ARP_LEARN_ACK_BLEN 7 +#define ROUTER_PTCTRL2_ARP_LEARN_ACK_FLAG HSL_RW + +#define ARP_LEARN_REQ +#define ROUTER_PTCTRL2_ARP_LEARN_REQ_BOFFSET 0 +#define ROUTER_PTCTRL2_ARP_LEARN_REQ_BLEN 7 +#define ROUTER_PTCTRL2_ARP_LEARN_REQ_FLAG HSL_RW + + + + +#define NAT_CTRL +#define NAT_CTRL_OFFSET 0x0e38 +#define NAT_CTRL_E_LENGTH 4 +#define NAT_CTRL_E_OFFSET 0x0 +#define NAT_CTRL_NR_E 1 + +#define NAT_HASH_MODE +#define NAT_CTRL_NAT_HASH_MODE_BOFFSET 5 +#define NAT_CTRL_NAT_HASH_MODE_BLEN 2 +#define NAT_CTRL_NAT_HASH_MODE_FLAG HSL_RW + +#define NAPT_OVERRIDE +#define NAT_CTRL_NAPT_OVERRIDE_BOFFSET 4 +#define NAT_CTRL_NAPT_OVERRIDE_BLEN 1 +#define NAT_CTRL_NAPT_OVERRIDE_FLAG HSL_RW + +#define NAPT_MODE +#define NAT_CTRL_NAPT_MODE_BOFFSET 2 +#define NAT_CTRL_NAPT_MODE_BLEN 2 +#define NAT_CTRL_NAPT_MODE_FLAG HSL_RW + +#define NAT_EN +#define NAT_CTRL_NAT_EN_BOFFSET 1 +#define NAT_CTRL_NAT_EN_BLEN 1 +#define NAT_CTRL_NAT_EN_FLAG HSL_RW + +#define NAPT_EN +#define NAT_CTRL_NAPT_EN_BOFFSET 0 +#define NAT_CTRL_NAPT_EN_BLEN 1 +#define NAT_CTRL_NAPT_EN_FLAG HSL_RW + + + + +#define PRV_BASEADDR +#define PRV_BASEADDR_OFFSET 0x0e5c +#define PRV_BASEADDR_E_LENGTH 4 +#define PRV_BASEADDR_E_OFFSET 0x0 +#define PRV_BASEADDR_NR_E 1 + +#define IP4_ADDR +#define PRV_BASEADDR_IP4_ADDR_BOFFSET 0 +#define PRV_BASEADDR_IP4_ADDR_BLEN 20 +#define PRV_BASEADDR_IP4_ADDR_FLAG HSL_RW + + + + +#define PRVIP_CTL +#define PRVIP_CTL_OFFSET 0x0418 +#define PRVIP_CTL_E_LENGTH 4 +#define PRVIP_CTL_E_OFFSET 0x0 +#define PRVIP_CTL_NR_E 1 + +#define BASEADDR_SEL +#define PRVIP_CTL_BASEADDR_SEL_BOFFSET 28 +#define PRVIP_CTL_BASEADDR_SEL_BLEN 1 +#define PRVIP_CTL_BASEADDR_SEL_FLAG HSL_RW + +#define IP4_BASEADDR +#define PRVIP_CTL_IP4_BASEADDR_BOFFSET 0 +#define PRVIP_CTL_IP4_BASEADDR_BLEN 20 +#define PRVIP_CTL_IP4_BASEADDR_FLAG HSL_RW + + +#define OFFLOAD_PRVIP_CTL +#define OFFLOAD_PRVIP_CTL_OFFSET 0x0e5c +#define OFFLOAD_PRVIP_CTL_E_LENGTH 4 +#define OFFLOAD_PRVIP_CTL_E_OFFSET 0x0 +#define OFFLOAD_PRVIP_CTL_NR_E 1 + +#define IP4_BASEADDR +#define OFFLOAD_PRVIP_CTL_IP4_BASEADDR_BOFFSET 0 +#define OFFLOAD_PRVIP_CTL_IP4_BASEADDR_BLEN 20 +#define OFFLOAD_PRVIP_CTL_IP4_BASEADDR_FLAG HSL_RW + + + + +#define PUB_ADDR0 +#define PUB_ADDR0_OFFSET 0x5aa00 +#define PUB_ADDR0_E_LENGTH 4 +#define PUB_ADDR0_E_OFFSET 0x0 +#define PUB_ADDR0_NR_E 1 + +#define IP4_ADDR +#define PUB_ADDR0_IP4_ADDR_BOFFSET 0 +#define PUB_ADDR0_IP4_ADDR_BLEN 32 +#define PUB_ADDR0_IP4_ADDR_FLAG HSL_RW + + +#define PUB_ADDR1 +#define PUB_ADDR1_OFFSET 0x5aa04 +#define PUB_ADDR1_E_LENGTH 4 +#define PUB_ADDR1_E_OFFSET 0x0 +#define PUB_ADDR1_NR_E 1 + +#define ADDR_VALID +#define PUB_ADDR1_ADDR_VALID_BOFFSET 0 +#define PUB_ADDR1_ADDR_VALID_BLEN 1 +#define PUB_ADDR1_ADDR_VALID_FLAG HSL_RW + + + + +#define INTF_ADDR_ENTRY0 +#define INTF_ADDR_ENTRY0_OFFSET 0x5aa00 +#define INTF_ADDR_ENTRY0_E_LENGTH 4 +#define INTF_ADDR_ENTRY0_E_OFFSET 0x0 +#define INTF_ADDR_ENTRY0_NR_E 8 + +#define MAC_ADDR2 +#define INTF_ADDR_ENTRY0_MAC_ADDR2_BOFFSET 24 +#define INTF_ADDR_ENTRY0_MAC_ADDR2_BLEN 8 +#define INTF_ADDR_ENTRY0_MAC_ADDR2_FLAG HSL_RW + +#define MAC_ADDR3 +#define INTF_ADDR_ENTRY0_MAC_ADDR3_BOFFSET 16 +#define INTF_ADDR_ENTRY0_MAC_ADDR3_BLEN 8 +#define INTF_ADDR_ENTRY0_MAC_ADDR3_FLAG HSL_RW + +#define MAC_ADDR4 +#define INTF_ADDR_ENTRY0_MAC_ADDR4_BOFFSET 8 +#define INTF_ADDR_ENTRY0_MAC_ADDR4_BLEN 8 +#define INTF_ADDR_ENTRY0_MAC_ADDR4_FLAG HSL_RW + +#define MAC_ADDR5 +#define INTF_ADDR_ENTRY0_MAC_ADDR5_BOFFSET 0 +#define INTF_ADDR_ENTRY0_MAC_ADDR5_BLEN 8 +#define INTF_ADDR_ENTRY0_MAC_ADDR5_FLAG HSL_RW + + +#define INTF_ADDR_ENTRY1 +#define INTF_ADDR_ENTRY1_OFFSET 0x5aa04 +#define INTF_ADDR_ENTRY1_E_LENGTH 4 +#define INTF_ADDR_ENTRY1_E_OFFSET 0x0 +#define INTF_ADDR_ENTRY1_NR_E 8 + +#define VID_HIGH0 +#define INTF_ADDR_ENTRY1_VID_HIGH0_BOFFSET 28 +#define INTF_ADDR_ENTRY1_VID_HIGH0_BLEN 4 +#define INTF_ADDR_ENTRY1_VID_HIGH0_FLAG HSL_RW + +#define VID_LOW +#define INTF_ADDR_ENTRY1_VID_LOW_BOFFSET 16 +#define INTF_ADDR_ENTRY1_VID_LOW_BLEN 12 +#define INTF_ADDR_ENTRY1_VID_LOW_FLAG HSL_RW + +#define MAC_ADDR0 +#define INTF_ADDR_ENTRY1_MAC_ADDR0_BOFFSET 8 +#define INTF_ADDR_ENTRY1_MAC_ADDR0_BLEN 8 +#define INTF_ADDR_ENTRY1_MAC_ADDR0_FLAG HSL_RW + +#define MAC_ADDR1 +#define INTF_ADDR_ENTRY1_MAC_ADDR1_BOFFSET 0 +#define INTF_ADDR_ENTRY1_MAC_ADDR1_BLEN 8 +#define INTF_ADDR_ENTRY1_MAC_ADDR1_FLAG HSL_RW + + +#define INTF_ADDR_ENTRY2 +#define INTF_ADDR_ENTRY2_OFFSET 0x5aa08 +#define INTF_ADDR_ENTRY2_E_LENGTH 4 +#define INTF_ADDR_ENTRY2_E_OFFSET 0x0 +#define INTF_ADDR_ENTRY2_NR_E 8 + +#define IP6_ROUTE +#define INTF_ADDR_ENTRY2_IP6_ROUTE_BOFFSET 9 +#define INTF_ADDR_ENTRY2_IP6_ROUTE_BLEN 1 +#define INTF_ADDR_ENTRY2_IP6_ROUTE_FLAG HSL_RW + +#define IP4_ROUTE +#define INTF_ADDR_ENTRY2_IP4_ROUTE_BOFFSET 8 +#define INTF_ADDR_ENTRY2_IP4_ROUTE_BLEN 1 +#define INTF_ADDR_ENTRY2_IP4_ROUTE_FLAG HSL_RW + +#define VID_HIGH1 +#define INTF_ADDR_ENTRY2_VID_HIGH1_BOFFSET 0 +#define INTF_ADDR_ENTRY2_VID_HIGH1_BLEN 8 +#define INTF_ADDR_ENTRY2_VID_HIGH1_FLAG HSL_RW + + + + + /* Port Shaper Register0 */ +#define EG_SHAPER0 +#define EG_SHAPER0_OFFSET 0x0890 +#define EG_SHAPER0_E_LENGTH 4 +#define EG_SHAPER0_E_OFFSET 0x0020 +#define EG_SHAPER0_NR_E 7 + +#define EG_Q1_CIR +#define EG_SHAPER0_EG_Q1_CIR_BOFFSET 16 +#define EG_SHAPER0_EG_Q1_CIR_BLEN 15 +#define EG_SHAPER0_EG_Q1_CIR_FLAG HSL_RW + +#define EG_Q0_CIR +#define EG_SHAPER0_EG_Q0_CIR_BOFFSET 0 +#define EG_SHAPER0_EG_Q0_CIR_BLEN 15 +#define EG_SHAPER0_EG_Q0_CIR_FLAG HSL_RW + + + /* Port Shaper Register1 */ +#define EG_SHAPER1 +#define EG_SHAPER1_OFFSET 0x0894 +#define EG_SHAPER1_E_LENGTH 4 +#define EG_SHAPER1_E_OFFSET 0x0020 +#define EG_SHAPER1_NR_E 7 + +#define EG_Q3_CIR +#define EG_SHAPER1_EG_Q3_CIR_BOFFSET 16 +#define EG_SHAPER1_EG_Q3_CIR_BLEN 15 +#define EG_SHAPER1_EG_Q3_CIR_FLAG HSL_RW + +#define EG_Q2_CIR +#define EG_SHAPER1_EG_Q2_CIR_BOFFSET 0 +#define EG_SHAPER1_EG_Q2_CIR_BLEN 15 +#define EG_SHAPER1_EG_Q2_CIR_FLAG HSL_RW + + + /* Port Shaper Register2 */ +#define EG_SHAPER2 +#define EG_SHAPER2_OFFSET 0x0898 +#define EG_SHAPER2_E_LENGTH 4 +#define EG_SHAPER2_E_OFFSET 0x0020 +#define EG_SHAPER2_NR_E 7 + +#define EG_Q5_CIR +#define EG_SHAPER2_EG_Q5_CIR_BOFFSET 16 +#define EG_SHAPER2_EG_Q5_CIR_BLEN 15 +#define EG_SHAPER2_EG_Q5_CIR_FLAG HSL_RW + +#define EG_Q4_CIR +#define EG_SHAPER2_EG_Q4_CIR_BOFFSET 0 +#define EG_SHAPER2_EG_Q4_CIR_BLEN 15 +#define EG_SHAPER2_EG_Q4_CIR_FLAG HSL_RW + + + /* Port Shaper Register3 */ +#define EG_SHAPER3 +#define EG_SHAPER3_OFFSET 0x089c +#define EG_SHAPER3_E_LENGTH 4 +#define EG_SHAPER3_E_OFFSET 0x0020 +#define EG_SHAPER3_NR_E 7 + +#define EG_Q1_EIR +#define EG_SHAPER3_EG_Q1_EIR_BOFFSET 16 +#define EG_SHAPER3_EG_Q1_EIR_BLEN 15 +#define EG_SHAPER3_EG_Q1_EIR_FLAG HSL_RW + +#define EG_Q0_EIR +#define EG_SHAPER3_EG_Q0_EIR_BOFFSET 0 +#define EG_SHAPER3_EG_Q0_EIR_BLEN 15 +#define EG_SHAPER3_EG_Q0_EIR_FLAG HSL_RW + + + /* Port Shaper Register4 */ +#define EG_SHAPER4 +#define EG_SHAPER4_OFFSET 0x08a0 +#define EG_SHAPER4_E_LENGTH 4 +#define EG_SHAPER4_E_OFFSET 0x0020 +#define EG_SHAPER4_NR_E 7 + +#define EG_Q3_EIR +#define EG_SHAPER4_EG_Q3_EIR_BOFFSET 16 +#define EG_SHAPER4_EG_Q3_EIR_BLEN 15 +#define EG_SHAPER4_EG_Q3_EIR_FLAG HSL_RW + +#define EG_Q2_EIR +#define EG_SHAPER4_EG_Q2_EIR_BOFFSET 0 +#define EG_SHAPER4_EG_Q2_EIR_BLEN 15 +#define EG_SHAPER4_EG_Q2_EIR_FLAG HSL_RW + + + /* Port Shaper Register5 */ +#define EG_SHAPER5 +#define EG_SHAPER5_OFFSET 0x08a4 +#define EG_SHAPER5_E_LENGTH 4 +#define EG_SHAPER5_E_OFFSET 0x0020 +#define EG_SHAPER5_NR_E 7 + +#define EG_Q5_EIR +#define EG_SHAPER5_EG_Q5_EIR_BOFFSET 16 +#define EG_SHAPER5_EG_Q5_EIR_BLEN 15 +#define EG_SHAPER5_EG_Q5_EIR_FLAG HSL_RW + +#define EG_Q4_EIR +#define EG_SHAPER5_EG_Q4_EIR_BOFFSET 0 +#define EG_SHAPER5_EG_Q4_EIR_BLEN 15 +#define EG_SHAPER5_EG_Q4_EIR_FLAG HSL_RW + + + /* Port Shaper Register6 */ +#define EG_SHAPER6 +#define EG_SHAPER6_OFFSET 0x08a8 +#define EG_SHAPER6_E_LENGTH 4 +#define EG_SHAPER6_E_OFFSET 0x0020 +#define EG_SHAPER6_NR_E 7 + +#define EG_Q3_CBS +#define EG_SHAPER6_EG_Q3_CBS_BOFFSET 28 +#define EG_SHAPER6_EG_Q3_CBS_BLEN 3 +#define EG_SHAPER6_EG_Q3_CBS_FLAG HSL_RW + +#define EG_Q3_EBS +#define EG_SHAPER6_EG_Q3_EBS_BOFFSET 24 +#define EG_SHAPER6_EG_Q3_EBS_BLEN 3 +#define EG_SHAPER6_EG_Q3_EBS_FLAG HSL_RW + +#define EG_Q2_CBS +#define EG_SHAPER6_EG_Q2_CBS_BOFFSET 20 +#define EG_SHAPER6_EG_Q2_CBS_BLEN 3 +#define EG_SHAPER6_EG_Q2_CBS_FLAG HSL_RW + +#define EG_Q2_EBS +#define EG_SHAPER6_EG_Q2_EBS_BOFFSET 16 +#define EG_SHAPER6_EG_Q2_EBS_BLEN 3 +#define EG_SHAPER6_EG_Q2_EBS_FLAG HSL_RW + +#define EG_Q1_CBS +#define EG_SHAPER6_EG_Q1_CBS_BOFFSET 12 +#define EG_SHAPER6_EG_Q1_CBS_BLEN 3 +#define EG_SHAPER6_EG_Q1_CBS_FLAG HSL_RW + +#define EG_Q1_EBS +#define EG_SHAPER6_EG_Q1_EBS_BOFFSET 8 +#define EG_SHAPER6_EG_Q1_EBS_BLEN 3 +#define EG_SHAPER6_EG_Q1_EBS_FLAG HSL_RW + +#define EG_Q0_CBS +#define EG_SHAPER6_EG_Q0_CBS_BOFFSET 4 +#define EG_SHAPER6_EG_Q0_CBS_BLEN 3 +#define EG_SHAPER6_EG_Q0_CBS_FLAG HSL_RW + +#define EG_Q0_EBS +#define EG_SHAPER6_EG_Q0_EBS_BOFFSET 0 +#define EG_SHAPER6_EG_Q0_EBS_BLEN 3 +#define EG_SHAPER6_EG_Q0_EBS_FLAG HSL_RW + + + /* Port Shaper Register7 */ +#define EG_SHAPER7 +#define EG_SHAPER7_OFFSET 0x08ac +#define EG_SHAPER7_E_LENGTH 4 +#define EG_SHAPER7_E_OFFSET 0x0020 +#define EG_SHAPER7_NR_E 7 + +#define EG_Q5_CBS +#define EG_SHAPER7_EG_Q5_CBS_BOFFSET 28 +#define EG_SHAPER7_EG_Q5_CBS_BLEN 3 +#define EG_SHAPER7_EG_Q5_CBS_FLAG HSL_RW + +#define EG_Q5_EBS +#define EG_SHAPER7_EG_Q5_EBS_BOFFSET 24 +#define EG_SHAPER7_EG_Q5_EBS_BLEN 3 +#define EG_SHAPER7_EG_Q5_EBS_FLAG HSL_RW + +#define EG_Q4_CBS +#define EG_SHAPER7_EG_Q4_CBS_BOFFSET 20 +#define EG_SHAPER7_EG_Q4_CBS_BLEN 3 +#define EG_SHAPER7_EG_Q4_CBS_FLAG HSL_RW + +#define EG_Q4_EBS +#define EG_SHAPER7_EG_Q4_EBS_BOFFSET 16 +#define EG_SHAPER7_EG_Q4_EBS_BLEN 3 +#define EG_SHAPER7_EG_Q4_EBS_FLAG HSL_RW + +#define EG_Q5_UNIT +#define EG_SHAPER7_EG_Q5_UNIT_BOFFSET 13 +#define EG_SHAPER7_EG_Q5_UNIT_BLEN 1 +#define EG_SHAPER7_EG_Q5_UNIT_FLAG HSL_RW + +#define EG_Q4_UNIT +#define EG_SHAPER7_EG_Q4_UNIT_BOFFSET 12 +#define EG_SHAPER7_EG_Q4_UNIT_BLEN 1 +#define EG_SHAPER7_EG_Q4_UNIT_FLAG HSL_RW + +#define EG_Q3_UNIT +#define EG_SHAPER7_EG_Q3_UNIT_BOFFSET 11 +#define EG_SHAPER7_EG_Q3_UNIT_BLEN 1 +#define EG_SHAPER7_EG_Q3_UNIT_FLAG HSL_RW + +#define EG_Q2_UNIT +#define EG_SHAPER7_EG_Q2_UNIT_BOFFSET 10 +#define EG_SHAPER7_EG_Q2_UNIT_BLEN 1 +#define EG_SHAPER7_EG_Q2_UNIT_FLAG HSL_RW + +#define EG_Q1_UNIT +#define EG_SHAPER7_EG_Q1_UNIT_BOFFSET 9 +#define EG_SHAPER7_EG_Q1_UNIT_BLEN 1 +#define EG_SHAPER7_EG_Q1_UNIT_FLAG HSL_RW + +#define EG_Q0_UNIT +#define EG_SHAPER7_EG_Q0_UNIT_BOFFSET 8 +#define EG_SHAPER7_EG_Q0_UNIT_BLEN 1 +#define EG_SHAPER7_EG_Q0_UNIT_FLAG HSL_RW + +#define EG_PT +#define EG_SHAPER7_EG_PT_BOFFSET 3 +#define EG_SHAPER7_EG_PT_BLEN 1 +#define EG_SHAPER7_EG_PT_FLAG HSL_RW + +#define EG_TS +#define EG_SHAPER7_EG_TS_BOFFSET 0 +#define EG_SHAPER7_EG_TS_BLEN 3 +#define EG_SHAPER7_EG_TS_FLAG HSL_RW + + + + /* ACL Policer Register0 */ +#define ACL_POLICER0 +#define ACL_POLICER0_OFFSET 0x0a00 +#define ACL_POLICER0_E_LENGTH 4 +#define ACL_POLICER0_E_OFFSET 0x0008 +#define ACL_POLICER0_NR_E 32 + +#define ACL_CBS +#define ACL_POLICER0_ACL_CBS_BOFFSET 15 +#define ACL_POLICER0_ACL_CBS_BLEN 3 +#define ACL_POLICER0_ACL_CBS_FLAG HSL_RW + +#define ACL_CIR +#define ACL_POLICER0_ACL_CIR_BOFFSET 0 +#define ACL_POLICER0_ACL_CIR_BLEN 15 +#define ACL_POLICER0_ACL_CIR_FLAG HSL_RW + + + /* ACL Policer Register1 */ +#define ACL_POLICER1 +#define ACL_POLICER1_OFFSET 0x0a04 +#define ACL_POLICER1_E_LENGTH 4 +#define ACL_POLICER1_E_OFFSET 0x0008 +#define ACL_POLICER1_NR_E 32 + +#define ACL_BORROW +#define ACL_POLICER1_ACL_BORROW_BOFFSET 23 +#define ACL_POLICER1_ACL_BORROW_BLEN 1 +#define ACL_POLICER1_ACL_BORROW_FLAG HSL_RW + +#define ACL_UNIT +#define ACL_POLICER1_ACL_UNIT_BOFFSET 22 +#define ACL_POLICER1_ACL_UNIT_BLEN 1 +#define ACL_POLICER1_ACL_UNIT_FLAG HSL_RW + +#define ACL_CF +#define ACL_POLICER1_ACL_CF_BOFFSET 21 +#define ACL_POLICER1_ACL_CF_BLEN 1 +#define ACL_POLICER1_ACL_CF_FLAG HSL_RW + +#define ACL_CM +#define ACL_POLICER1_ACL_CM_BOFFSET 20 +#define ACL_POLICER1_ACL_CM_BLEN 1 +#define ACL_POLICER1_ACL_CM_FLAG HSL_RW + +#define ACL_TS +#define ACL_POLICER1_ACL_TS_BOFFSET 18 +#define ACL_POLICER1_ACL_TS_BLEN 2 +#define ACL_POLICER1_ACL_TS_FLAG HSL_RW + +#define ACL_EBS +#define ACL_POLICER1_ACL_EBS_BOFFSET 15 +#define ACL_POLICER1_ACL_EBS_BLEN 3 +#define ACL_POLICER1_ACL_EBS_FLAG HSL_RW + +#define ACL_EIR +#define ACL_POLICER1_ACL_EIR_BOFFSET 0 +#define ACL_POLICER1_ACL_EIR_BLEN 15 +#define ACL_POLICER1_ACL_EIR_FLAG HSL_RW + + + /* ACL Counter Register0 */ +#define ACL_COUNTER0 +#define ACL_COUNTER0_OFFSET 0x1c000 +#define ACL_COUNTER0_E_LENGTH 4 +#define ACL_COUNTER0_E_OFFSET 0x0008 +#define ACL_COUNTER0_NR_E 32 + + /* ACL Counter Register1 */ +#define ACL_COUNTER1 +#define ACL_COUNTER1_OFFSET 0x1c004 +#define ACL_COUNTER1_E_LENGTH 4 +#define ACL_COUNTER1_E_OFFSET 0x0008 +#define ACL_COUNTER1_NR_E 32 + + + + + /* INGRESS Policer Register0 */ +#define INGRESS_POLICER0 +#define INGRESS_POLICER0_OFFSET 0x0b00 +#define INGRESS_POLICER0_E_LENGTH 4 +#define INGRESS_POLICER0_E_OFFSET 0x0010 +#define INGRESS_POLICER0_NR_E 7 + +#define ADD_RATE_BYTE +#define INGRESS_POLICER0_ADD_RATE_BYTE_BOFFSET 24 +#define INGRESS_POLICER0_ADD_RATE_BYTE_BLEN 8 +#define INGRESS_POLICER0_ADD_RATE_BYTE_FLAG HSL_RW + +#define C_ING_TS +#define INGRESS_POLICER0_C_ING_TS_BOFFSET 22 +#define INGRESS_POLICER0_C_ING_TS_BLEN 2 +#define INGRESS_POLICER0_C_ING_TS_FLAG HSL_RW + +#define RATE_MODE +#define INGRESS_POLICER0_RATE_MODE_BOFFSET 20 +#define INGRESS_POLICER0_RATE_MODE_BLEN 1 +#define INGRESS_POLICER0_RATE_MODE_FLAG HSL_RW + +#define INGRESS_CBS +#define INGRESS_POLICER0_INGRESS_CBS_BOFFSET 15 +#define INGRESS_POLICER0_INGRESS_CBS_BLEN 3 +#define INGRESS_POLICER0_INGRESS_CBS_FLAG HSL_RW + +#define INGRESS_CIR +#define INGRESS_POLICER0_INGRESS_CIR_BOFFSET 0 +#define INGRESS_POLICER0_INGRESS_CIR_BLEN 15 +#define INGRESS_POLICER0_INGRESS_CIR_FLAG HSL_RW + + + /* INGRESS Policer Register1 */ +#define INGRESS_POLICER1 +#define INGRESS_POLICER1_OFFSET 0x0b04 +#define INGRESS_POLICER1_E_LENGTH 4 +#define INGRESS_POLICER1_E_OFFSET 0x0010 +#define INGRESS_POLICER1_NR_E 7 + +#define INGRESS_BORROW +#define INGRESS_POLICER1_INGRESS_BORROW_BOFFSET 23 +#define INGRESS_POLICER1_INGRESS_BORROW_BLEN 1 +#define INGRESS_POLICER1_INGRESS_BORROW_FLAG HSL_RW + +#define INGRESS_UNIT +#define INGRESS_POLICER1_INGRESS_UNIT_BOFFSET 22 +#define INGRESS_POLICER1_INGRESS_UNIT_BLEN 1 +#define INGRESS_POLICER1_INGRESS_UNIT_FLAG HSL_RW + +#define INGRESS_CF +#define INGRESS_POLICER1_INGRESS_CF_BOFFSET 21 +#define INGRESS_POLICER1_INGRESS_CF_BLEN 1 +#define INGRESS_POLICER1_INGRESS_CF_FLAG HSL_RW + +#define INGRESS_CM +#define INGRESS_POLICER1_INGRESS_CM_BOFFSET 20 +#define INGRESS_POLICER1_INGRESS_CM_BLEN 1 +#define INGRESS_POLICER1_INGRESS_CM_FLAG HSL_RW + +#define E_ING_TS +#define INGRESS_POLICER1_E_ING_TS_BOFFSET 18 +#define INGRESS_POLICER1_E_ING_TS_BLEN 2 +#define INGRESS_POLICER1_E_ING_TS_FLAG HSL_RW + +#define INGRESS_EBS +#define INGRESS_POLICER1_INGRESS_EBS_BOFFSET 15 +#define INGRESS_POLICER1_INGRESS_EBS_BLEN 3 +#define INGRESS_POLICER1_INGRESS_EBS_FLAG HSL_RW + +#define INGRESS_EIR +#define INGRESS_POLICER1_INGRESS_EIR_BOFFSET 0 +#define INGRESS_POLICER1_INGRESS_EIR_BLEN 15 +#define INGRESS_POLICER1_INGRESS_EIR_FLAG HSL_RW + + + /* INGRESS Policer Register2 */ +#define INGRESS_POLICER2 +#define INGRESS_POLICER2_OFFSET 0x0b08 +#define INGRESS_POLICER2_E_LENGTH 4 +#define INGRESS_POLICER2_E_OFFSET 0x0010 +#define INGRESS_POLICER2_NR_E 7 + +#define C_MUL +#define INGRESS_POLICER2_C_MUL_BOFFSET 15 +#define INGRESS_POLICER2_C_MUL_BLEN 1 +#define INGRESS_POLICER2_C_UNK_MUL_FLAG HSL_RW + +#define C_UNI +#define INGRESS_POLICER2_C_UNI_BOFFSET 14 +#define INGRESS_POLICER2_C_UNI_BLEN 1 +#define INGRESS_POLICER2_C_UNI_FLAG HSL_RW + +#define C_UNK_MUL +#define INGRESS_POLICER2_C_UNK_MUL_BOFFSET 13 +#define INGRESS_POLICER2_C_UNK_MUL_BLEN 1 +#define INGRESS_POLICER2_C_UNK_MUL_FLAG HSL_RW + +#define C_UNK_UNI +#define INGRESS_POLICER2_C_UNK_UNI_BOFFSET 12 +#define INGRESS_POLICER2_C_UNK_UNI_BLEN 1 +#define INGRESS_POLICER2_C_UNK_UNI_FLAG HSL_RW + +#define C_BROAD +#define INGRESS_POLICER2_C_BROAD_BOFFSET 11 +#define INGRESS_POLICER2_C_BROAD_BLEN 1 +#define INGRESS_POLICER2_C_BROAD_FLAG HSL_RW + +#define C_MANAGE +#define INGRESS_POLICER2_C_MANAGC_BOFFSET 10 +#define INGRESS_POLICER2_C_MANAGC_BLEN 1 +#define INGRESS_POLICER2_C_MANAGC_FLAG HSL_RW + +#define C_TCP +#define INGRESS_POLICER2_C_TCP_BOFFSET 9 +#define INGRESS_POLICER2_C_TCP_BLEN 1 +#define INGRESS_POLICER2_C_TCP_FLAG HSL_RW + +#define C_MIRR +#define INGRESS_POLICER2_C_MIRR_BOFFSET 8 +#define INGRESS_POLICER2_C_MIRR_BLEN 1 +#define INGRESS_POLICER2_C_MIRR_FLAG HSL_RW + +#define E_MUL +#define INGRESS_POLICER2_E_MUL_BOFFSET 7 +#define INGRESS_POLICER2_E_MUL_BLEN 1 +#define INGRESS_POLICER2_E_UNK_MUL_FLAG HSL_RW + +#define E_UNI +#define INGRESS_POLICER2_E_UNI_BOFFSET 6 +#define INGRESS_POLICER2_E_UNI_BLEN 1 +#define INGRESS_POLICER2_E_UNI_FLAG HSL_RW + +#define E_UNK_MUL +#define INGRESS_POLICER2_E_UNK_MUL_BOFFSET 5 +#define INGRESS_POLICER2_E_UNK_MUL_BLEN 1 +#define INGRESS_POLICER2_E_UNK_MUL_FLAG HSL_RW + +#define E_UNK_UNI +#define INGRESS_POLICER2_E_UNK_UNI_BOFFSET 4 +#define INGRESS_POLICER2_E_UNK_UNI_BLEN 1 +#define INGRESS_POLICER2_E_UNK_UNI_FLAG HSL_RW + +#define E_BROAD +#define INGRESS_POLICER2_E_BROAD_BOFFSET 3 +#define INGRESS_POLICER2_E_BROAD_BLEN 1 +#define INGRESS_POLICER2_E_BROAD_FLAG HSL_RW + +#define E_MANAGE +#define INGRESS_POLICER2_E_MANAGE_BOFFSET 2 +#define INGRESS_POLICER2_E_MANAGE_BLEN 1 +#define INGRESS_POLICER2_E_MANAGE_FLAG HSL_RW + +#define E_TCP +#define INGRESS_POLICER2_E_TCP_BOFFSET 1 +#define INGRESS_POLICER2_E_TCP_BLEN 1 +#define INGRESS_POLICER2_E_TCP_FLAG HSL_RW + +#define E_MIRR +#define INGRESS_POLICER2_E_MIRR_BOFFSET 0 +#define INGRESS_POLICER2_E_MIRR_BLEN 1 +#define INGRESS_POLICER2_E_MIRR_FLAG HSL_RW + + + + + /* Port Rate Limit2 Register */ +#define WRR_CTRL +#define WRR_CTRL_OFFSET 0x0830 +#define WRR_CTRL_E_LENGTH 4 +#define WRR_CTRL_E_OFFSET 0x0004 +#define WRR_CTRL_NR_E 7 + +#define SCH_MODE +#define WRR_CTRL_SCH_MODE_BOFFSET 30 +#define WRR_CTRL_SCH_MODE_BLEN 2 +#define WRR_CTRL_SCH_MODE_FLAG HSL_RW + +#define Q5_W +#define WRR_CTRL_Q5_W_BOFFSET 25 +#define WRR_CTRL_Q5_W_BLEN 5 +#define WRR_CTRL_Q5_W_FLAG HSL_RW + +#define Q4_W +#define WRR_CTRL_Q4_W_BOFFSET 20 +#define WRR_CTRL_Q4_W_BLEN 5 +#define WRR_CTRL_Q4_W_FLAG HSL_RW + +#define Q3_W +#define WRR_CTRL_Q3_W_BOFFSET 15 +#define WRR_CTRL_Q3_W_BLEN 5 +#define WRR_CTRL_Q3_W_FLAG HSL_RW + +#define Q2_W +#define WRR_CTRL_Q2_W_BOFFSET 10 +#define WRR_CTRL_Q2_W_BLEN 5 +#define WRR_CTRL_Q2_W_FLAG HSL_RW + +#define Q1_W +#define WRR_CTRL_Q1_W_BOFFSET 5 +#define WRR_CTRL_Q1_W_BLEN 5 +#define WRR_CTRL_Q1_W_FLAG HSL_RW + +#define Q0_W +#define WRR_CTRL_Q0_W_BOFFSET 0 +#define WRR_CTRL_Q0_W_BLEN 5 +#define WRR_CTRL_Q0_W_FLAG HSL_RW + + + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISIS_REG_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_reg_access.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_reg_access.h new file mode 100755 index 000000000..22fc6ca17 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_reg_access.h @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2012,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 _ISIS_REG_ACCESS_H_ +#define _ISIS_REG_ACCESS_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "sw.h" + +#define ISIS_HEADER_CMD_LEN 8 +#define ISIS_HEADER_DATA_LEN 4 +#define ISIS_HEADER_LEN 4 +#define ISIS_HEADER_MAX_DATA_LEN 16 +#define VID_LEN 2 +#define ATHRS_HEADER_4BYTE_VAL 0xaaaa + + typedef enum { + NORMAL_PACKET, + RESERVED0, + MIB_1ST, + RESERVED1, + RESERVED2, + READ_WRITE_REG, + READ_WRITE_REG_ACK, + RESERVED3 + } + ATHRS_HEADER_TYPE; + + typedef struct + { + a_uint8_t version; + a_uint8_t priority; + a_uint8_t type ; + a_uint8_t broadcast; + a_uint8_t from_cpu; + a_uint8_t port_num; + } athrs_header_t; + + typedef struct + { + a_uint32_t reg_addr; + a_uint8_t cmd_len; + a_uint8_t cmd; + a_uint16_t check_code; + a_uint32_t seq_num; + } athrs_header_regcmd_t; + + typedef struct + { + a_uint8_t data[ISIS_HEADER_MAX_DATA_LEN]; + a_uint8_t len; + a_uint16_t athrs_4byte_value; + volatile a_uint32_t seq; + } athrs_cmd_resp_t; + + sw_error_t + isis_phy_get(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t * value); + + sw_error_t + isis_phy_set(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t value); + + sw_error_t + isis_reg_get(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t value[], + a_uint32_t value_len); + + sw_error_t + isis_reg_set(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t value[], + a_uint32_t value_len); + + sw_error_t + isis_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 + isis_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 + isis_regsiter_dump(a_uint32_t dev_id,a_uint32_t register_idx, fal_reg_dump_t * reg_dump); + + sw_error_t + isis_debug_regsiter_dump(a_uint32_t dev_id, fal_debug_reg_dump_t * dbg_reg_dump); + + + sw_error_t + isis_reg_access_init(a_uint32_t dev_id, hsl_access_mode mode); + + sw_error_t + isis_access_mode_set(a_uint32_t dev_id, hsl_access_mode mode); + + int + isis_reg_config_header (a_uint8_t *header, a_uint8_t wr_flag, + a_uint32_t reg_addr, a_uint8_t cmd_len, + a_uint8_t *val, a_uint32_t seq_num); + + sw_error_t isis_reg_parser_header_skb(a_uint8_t *header_buf, athrs_cmd_resp_t *cmd_resp); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _ISIS_REG_ACCESS_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_sec.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_sec.h new file mode 100755 index 000000000..c671d4138 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_sec.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISIS_SEC_H_ +#define _ISIS_SEC_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_sec.h" + + sw_error_t isis_sec_init(a_uint32_t dev_id); + +#ifdef IN_SEC +#define ISIS_SEC_INIT(rv, dev_id) \ + { \ + rv = isis_sec_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISIS_SEC_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + isis_sec_norm_item_set(a_uint32_t dev_id, fal_norm_item_t item, + void *value); + + HSL_LOCAL sw_error_t + isis_sec_norm_item_get(a_uint32_t dev_id, fal_norm_item_t item, + void *value); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISIS_SEC_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_stp.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_stp.h new file mode 100755 index 000000000..407017d10 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_stp.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISIS_STP_H_ +#define _ISIS_STP_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_stp.h" + + sw_error_t isis_stp_init(a_uint32_t dev_id); + +#ifdef IN_STP +#define ISIS_STP_INIT(rv, dev_id) \ + { \ + rv = isis_stp_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISIS_STP_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + isis_stp_port_state_set(a_uint32_t dev_id, a_uint32_t st_id, + fal_port_t port_id, fal_stp_state_t state); + + + HSL_LOCAL sw_error_t + isis_stp_port_state_get(a_uint32_t dev_id, a_uint32_t st_id, + fal_port_t port_id, fal_stp_state_t * state); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISIS_STP_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_trunk.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_trunk.h new file mode 100755 index 000000000..66c602c7e --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_trunk.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISIS_TRUNK_H_ +#define _ISIS_TRUNK_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_trunk.h" + + sw_error_t isis_trunk_init(a_uint32_t dev_id); + +#ifdef IN_TRUNK +#define ISIS_TRUNK_INIT(rv, dev_id) \ + { \ + rv = isis_trunk_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISIS_TRUNK_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + isis_trunk_group_set(a_uint32_t dev_id, a_uint32_t trunk_id, + a_bool_t enable, fal_pbmp_t member); + + HSL_LOCAL sw_error_t + isis_trunk_group_get(a_uint32_t dev_id, a_uint32_t trunk_id, + a_bool_t * enable, fal_pbmp_t * member); + + HSL_LOCAL sw_error_t + isis_trunk_hash_mode_set(a_uint32_t dev_id, a_uint32_t hash_mode); + + HSL_LOCAL sw_error_t + isis_trunk_hash_mode_get(a_uint32_t dev_id, a_uint32_t * hash_mode); + + HSL_LOCAL sw_error_t + isis_trunk_manipulate_sa_set(a_uint32_t dev_id, fal_mac_addr_t * addr); + + HSL_LOCAL sw_error_t + isis_trunk_manipulate_sa_get(a_uint32_t dev_id, fal_mac_addr_t * addr); + + HSL_LOCAL sw_error_t + isis_trunk_manipulate_dp(a_uint32_t dev_id, a_uint8_t * header, + a_uint32_t len, fal_pbmp_t dp_member); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISIS_TRUNK_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_vlan.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_vlan.h new file mode 100755 index 000000000..245d59539 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isis/isis_vlan.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISIS_VLAN_H_ +#define _ISIS_VLAN_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_vlan.h" + + sw_error_t + isis_vlan_init(a_uint32_t dev_id); + +#ifdef IN_VLAN +#define ISIS_VLAN_INIT(rv, dev_id) \ + { \ + rv = isis_vlan_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISIS_VLAN_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + isis_vlan_entry_append(a_uint32_t dev_id, const fal_vlan_t * vlan_entry); + + + HSL_LOCAL sw_error_t + isis_vlan_create(a_uint32_t dev_id, a_uint32_t vlan_id); + + + HSL_LOCAL sw_error_t + isis_vlan_next(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan); + + + HSL_LOCAL sw_error_t + isis_vlan_find(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan); + + + HSL_LOCAL sw_error_t + isis_vlan_delete(a_uint32_t dev_id, a_uint32_t vlan_id); + + + HSL_LOCAL sw_error_t + isis_vlan_flush(a_uint32_t dev_id); + + + HSL_LOCAL sw_error_t + isis_vlan_fid_set(a_uint32_t dev_id, a_uint32_t vlan_id, a_uint32_t fid); + + + HSL_LOCAL sw_error_t + isis_vlan_fid_get(a_uint32_t dev_id, a_uint32_t vlan_id, a_uint32_t * fid); + + + HSL_LOCAL sw_error_t + isis_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); + + + HSL_LOCAL sw_error_t + isis_vlan_member_del(a_uint32_t dev_id, a_uint32_t vlan_id, fal_port_t port_id); + + + HSL_LOCAL sw_error_t + isis_vlan_learning_state_set(a_uint32_t dev_id, a_uint32_t vlan_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + isis_vlan_learning_state_get(a_uint32_t dev_id, a_uint32_t vlan_id, + a_bool_t * enable); + + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _ISIS_VLAN_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_acl.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_acl.h new file mode 100755 index 000000000..704b04749 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_acl.h @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 isisc_acl ISISC_ACL + * @{ + */ +#ifndef _ISISC_ACL_H_ +#define _ISISC_ACL_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_acl.h" + + sw_error_t isisc_acl_init(a_uint32_t dev_id); + + sw_error_t isisc_acl_reset(a_uint32_t dev_id); + + sw_error_t isisc_acl_cleanup(a_uint32_t dev_id); + + +#ifdef IN_ACL +#define ISISC_ACL_INIT(rv, dev_id) \ + { \ + rv = isisc_acl_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } + +#define ISISC_ACL_RESET(rv, dev_id) \ + { \ + rv = isisc_acl_reset(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#define ISISC_ACL_CLEANUP(rv, dev_id) \ + { \ + rv = isisc_acl_cleanup(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISISC_ACL_INIT(rv, dev_id) +#define ISISC_ACL_RESET(rv, dev_id) +#define ISISC_ACL_CLEANUP(rv, dev_id) +#endif + + sw_error_t + isisc_acl_list_creat(a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t list_pri); + + sw_error_t + isisc_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 + isisc_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 + isisc_acl_rule_query(a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t rule_id, fal_acl_rule_t * rule); + + a_uint32_t + isisc_acl_rule_get_offset(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t rule_id); + + sw_error_t + isisc_acl_rule_sync_multi_portmap(a_uint32_t dev_id, a_uint32_t pos, a_uint32_t *act); + + sw_error_t + isisc_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 + isisc_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 + isisc_acl_status_set(a_uint32_t dev_id, a_bool_t enable); + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + isisc_acl_list_destroy(a_uint32_t dev_id, a_uint32_t list_id); + + HSL_LOCAL sw_error_t + isisc_acl_status_get(a_uint32_t dev_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + isisc_acl_list_dump(a_uint32_t dev_id); + + HSL_LOCAL sw_error_t + isisc_acl_rule_dump(a_uint32_t dev_id); + + HSL_LOCAL sw_error_t + isisc_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); + + HSL_LOCAL sw_error_t + isisc_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); + + HSL_LOCAL sw_error_t + isisc_acl_rule_active(a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t rule_id, a_uint32_t rule_nr); + + HSL_LOCAL sw_error_t + isisc_acl_rule_deactive(a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t rule_id, a_uint32_t rule_nr); + HSL_LOCAL sw_error_t + isisc_acl_rule_src_filter_sts_set(a_uint32_t dev_id, + a_uint32_t rule_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + isisc_acl_rule_src_filter_sts_get(a_uint32_t dev_id, + a_uint32_t rule_id, a_bool_t* enable); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISISC_ACL_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_api.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_api.h new file mode 100755 index 000000000..4e9d75348 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_api.h @@ -0,0 +1,1093 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISISC_API_H_ +#define _ISISC_API_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifdef IN_PORTCONTROL +#define PORTCONTROL_API \ + SW_API_DEF(SW_API_PT_DUPLEX_GET, isisc_port_duplex_get), \ + SW_API_DEF(SW_API_PT_DUPLEX_SET, isisc_port_duplex_set), \ + SW_API_DEF(SW_API_PT_SPEED_GET, isisc_port_speed_get), \ + SW_API_DEF(SW_API_PT_SPEED_SET, isisc_port_speed_set), \ + SW_API_DEF(SW_API_PT_AN_GET, isisc_port_autoneg_status_get), \ + SW_API_DEF(SW_API_PT_AN_ENABLE, isisc_port_autoneg_enable), \ + SW_API_DEF(SW_API_PT_AN_RESTART, isisc_port_autoneg_restart), \ + SW_API_DEF(SW_API_PT_AN_ADV_GET, isisc_port_autoneg_adv_get), \ + SW_API_DEF(SW_API_PT_AN_ADV_SET, isisc_port_autoneg_adv_set), \ + SW_API_DEF(SW_API_PT_FLOWCTRL_SET, isisc_port_flowctrl_set), \ + SW_API_DEF(SW_API_PT_FLOWCTRL_GET, isisc_port_flowctrl_get), \ + SW_API_DEF(SW_API_PT_FLOWCTRL_MODE_SET, isisc_port_flowctrl_forcemode_set), \ + SW_API_DEF(SW_API_PT_FLOWCTRL_MODE_GET, isisc_port_flowctrl_forcemode_get), \ + SW_API_DEF(SW_API_PT_POWERSAVE_SET, isisc_port_powersave_set), \ + SW_API_DEF(SW_API_PT_POWERSAVE_GET, isisc_port_powersave_get), \ + SW_API_DEF(SW_API_PT_HIBERNATE_SET, isisc_port_hibernate_set), \ + SW_API_DEF(SW_API_PT_HIBERNATE_GET, isisc_port_hibernate_get), \ + SW_API_DEF(SW_API_PT_CDT, isisc_port_cdt), \ + SW_API_DEF(SW_API_PT_TXHDR_SET, isisc_port_txhdr_mode_set), \ + SW_API_DEF(SW_API_PT_TXHDR_GET, isisc_port_txhdr_mode_get), \ + SW_API_DEF(SW_API_PT_RXHDR_SET, isisc_port_rxhdr_mode_set), \ + SW_API_DEF(SW_API_PT_RXHDR_GET, isisc_port_rxhdr_mode_get), \ + SW_API_DEF(SW_API_HEADER_TYPE_SET, isisc_header_type_set), \ + SW_API_DEF(SW_API_HEADER_TYPE_GET, isisc_header_type_get), \ + SW_API_DEF(SW_API_TXMAC_STATUS_SET, isisc_port_txmac_status_set), \ + SW_API_DEF(SW_API_TXMAC_STATUS_GET, isisc_port_txmac_status_get), \ + SW_API_DEF(SW_API_RXMAC_STATUS_SET, isisc_port_rxmac_status_set), \ + SW_API_DEF(SW_API_RXMAC_STATUS_GET, isisc_port_rxmac_status_get), \ + SW_API_DEF(SW_API_TXFC_STATUS_SET, isisc_port_txfc_status_set), \ + SW_API_DEF(SW_API_TXFC_STATUS_GET, isisc_port_txfc_status_get), \ + SW_API_DEF(SW_API_RXFC_STATUS_SET, isisc_port_rxfc_status_set), \ + SW_API_DEF(SW_API_RXFC_STATUS_GET, isisc_port_rxfc_status_get), \ + SW_API_DEF(SW_API_BP_STATUS_SET, isisc_port_bp_status_set), \ + SW_API_DEF(SW_API_BP_STATUS_GET, isisc_port_bp_status_get), \ + SW_API_DEF(SW_API_PT_LINK_MODE_SET, isisc_port_link_forcemode_set), \ + SW_API_DEF(SW_API_PT_LINK_MODE_GET, isisc_port_link_forcemode_get), \ + SW_API_DEF(SW_API_PT_LINK_STATUS_GET, isisc_port_link_status_get), \ + SW_API_DEF(SW_API_PT_MAC_LOOPBACK_SET, isisc_port_mac_loopback_set), \ + SW_API_DEF(SW_API_PT_MAC_LOOPBACK_GET, isisc_port_mac_loopback_get), \ + SW_API_DEF(SW_API_PT_8023AZ_SET, isisc_port_8023az_set), \ + SW_API_DEF(SW_API_PT_8023AZ_GET, isisc_port_8023az_get), + +#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) \ + 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) \ + SW_API_DESC(SW_API_PT_HIBERNATE_SET) \ + SW_API_DESC(SW_API_PT_HIBERNATE_GET) \ + SW_API_DESC(SW_API_PT_CDT) \ + 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) \ + SW_API_DESC(SW_API_PT_LINK_STATUS_GET) \ + SW_API_DESC(SW_API_PT_MAC_LOOPBACK_SET) \ + SW_API_DESC(SW_API_PT_MAC_LOOPBACK_GET) \ + SW_API_DESC(SW_API_PT_8023AZ_SET) \ + SW_API_DESC(SW_API_PT_8023AZ_GET) +#else +#define PORTCONTROL_API +#define PORTCONTROL_API_PARAM +#endif + +#ifdef IN_VLAN +#define VLAN_API \ + SW_API_DEF(SW_API_VLAN_ADD, isisc_vlan_create), \ + SW_API_DEF(SW_API_VLAN_DEL, isisc_vlan_delete), \ + SW_API_DEF(SW_API_VLAN_FIND, isisc_vlan_find), \ + SW_API_DEF(SW_API_VLAN_NEXT, isisc_vlan_next), \ + SW_API_DEF(SW_API_VLAN_APPEND, isisc_vlan_entry_append), \ + SW_API_DEF(SW_API_VLAN_FLUSH, isisc_vlan_flush), \ + SW_API_DEF(SW_API_VLAN_FID_SET, isisc_vlan_fid_set), \ + SW_API_DEF(SW_API_VLAN_FID_GET, isisc_vlan_fid_get), \ + SW_API_DEF(SW_API_VLAN_MEMBER_ADD, isisc_vlan_member_add), \ + SW_API_DEF(SW_API_VLAN_MEMBER_DEL, isisc_vlan_member_del), \ + SW_API_DEF(SW_API_VLAN_LEARN_STATE_SET, isisc_vlan_learning_state_set), \ + SW_API_DEF(SW_API_VLAN_LEARN_STATE_GET, isisc_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_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, isisc_port_1qmode_get), \ + SW_API_DEF(SW_API_PT_ING_MODE_SET, isisc_port_1qmode_set), \ + SW_API_DEF(SW_API_PT_EG_MODE_GET, isisc_port_egvlanmode_get), \ + SW_API_DEF(SW_API_PT_EG_MODE_SET, isisc_port_egvlanmode_set), \ + SW_API_DEF(SW_API_PT_VLAN_MEM_ADD, isisc_portvlan_member_add), \ + SW_API_DEF(SW_API_PT_VLAN_MEM_DEL, isisc_portvlan_member_del), \ + SW_API_DEF(SW_API_PT_VLAN_MEM_UPDATE, isisc_portvlan_member_update), \ + SW_API_DEF(SW_API_PT_VLAN_MEM_GET, isisc_portvlan_member_get), \ + SW_API_DEF(SW_API_PT_FORCE_DEF_VID_SET, isisc_port_force_default_vid_set), \ + SW_API_DEF(SW_API_PT_FORCE_DEF_VID_GET, isisc_port_force_default_vid_get), \ + SW_API_DEF(SW_API_PT_FORCE_PORTVLAN_SET, isisc_port_force_portvlan_set), \ + SW_API_DEF(SW_API_PT_FORCE_PORTVLAN_GET, isisc_port_force_portvlan_get), \ + SW_API_DEF(SW_API_NESTVLAN_TPID_SET, isisc_nestvlan_tpid_set), \ + SW_API_DEF(SW_API_NESTVLAN_TPID_GET, isisc_nestvlan_tpid_get), \ + SW_API_DEF(SW_API_PT_IN_VLAN_MODE_SET, isisc_port_invlan_mode_set), \ + SW_API_DEF(SW_API_PT_IN_VLAN_MODE_GET, isisc_port_invlan_mode_get), \ + SW_API_DEF(SW_API_PT_TLS_SET, isisc_port_tls_set), \ + SW_API_DEF(SW_API_PT_TLS_GET, isisc_port_tls_get), \ + SW_API_DEF(SW_API_PT_PRI_PROPAGATION_SET, isisc_port_pri_propagation_set), \ + SW_API_DEF(SW_API_PT_PRI_PROPAGATION_GET, isisc_port_pri_propagation_get), \ + SW_API_DEF(SW_API_PT_DEF_SVID_SET, isisc_port_default_svid_set), \ + SW_API_DEF(SW_API_PT_DEF_SVID_GET, isisc_port_default_svid_get), \ + SW_API_DEF(SW_API_PT_DEF_CVID_SET, isisc_port_default_cvid_set), \ + SW_API_DEF(SW_API_PT_DEF_CVID_GET, isisc_port_default_cvid_get), \ + SW_API_DEF(SW_API_PT_VLAN_PROPAGATION_SET, isisc_port_vlan_propagation_set), \ + SW_API_DEF(SW_API_PT_VLAN_PROPAGATION_GET, isisc_port_vlan_propagation_get), \ + SW_API_DEF(SW_API_PT_VLAN_TRANS_ADD, isisc_port_vlan_trans_add), \ + SW_API_DEF(SW_API_PT_VLAN_TRANS_DEL, isisc_port_vlan_trans_del), \ + SW_API_DEF(SW_API_PT_VLAN_TRANS_GET, isisc_port_vlan_trans_get), \ + SW_API_DEF(SW_API_QINQ_MODE_SET, isisc_qinq_mode_set), \ + SW_API_DEF(SW_API_QINQ_MODE_GET, isisc_qinq_mode_get), \ + SW_API_DEF(SW_API_PT_QINQ_ROLE_SET, isisc_port_qinq_role_set), \ + SW_API_DEF(SW_API_PT_QINQ_ROLE_GET, isisc_port_qinq_role_get), \ + SW_API_DEF(SW_API_PT_VLAN_TRANS_ITERATE, isisc_port_vlan_trans_iterate), \ + SW_API_DEF(SW_API_PT_MAC_VLAN_XLT_SET, isisc_port_mac_vlan_xlt_set), \ + SW_API_DEF(SW_API_PT_MAC_VLAN_XLT_GET, isisc_port_mac_vlan_xlt_get), \ + SW_API_DEF(SW_API_NETISOLATE_SET, isisc_netisolate_set), \ + SW_API_DEF(SW_API_NETISOLATE_GET, isisc_netisolate_get),\ + SW_API_DEF(SW_API_EG_FLTR_BYPASS_EN_SET, isisc_eg_trans_filter_bypass_en_set), \ + SW_API_DEF(SW_API_EG_FLTR_BYPASS_EN_GET, isisc_eg_trans_filter_bypass_en_get), + + +#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_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_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) + +#else +#define PORTVLAN_API +#define PORTVLAN_API_PARAM +#endif + +#ifdef IN_FDB +#define FDB_API \ + SW_API_DEF(SW_API_FDB_ADD, isisc_fdb_add), \ + SW_API_DEF(SW_API_FDB_DELALL, isisc_fdb_del_all), \ + SW_API_DEF(SW_API_FDB_DELPORT,isisc_fdb_del_by_port), \ + SW_API_DEF(SW_API_FDB_DELMAC, isisc_fdb_del_by_mac), \ + SW_API_DEF(SW_API_FDB_FIND, isisc_fdb_find), \ + SW_API_DEF(SW_API_FDB_EXTEND_NEXT, isisc_fdb_extend_next), \ + SW_API_DEF(SW_API_FDB_EXTEND_FIRST, isisc_fdb_extend_first), \ + SW_API_DEF(SW_API_FDB_TRANSFER, isisc_fdb_transfer), \ + SW_API_DEF(SW_API_FDB_PT_LEARN_SET, isisc_fdb_port_learn_set), \ + SW_API_DEF(SW_API_FDB_PT_LEARN_GET, isisc_fdb_port_learn_get), \ + SW_API_DEF(SW_API_FDB_AGE_CTRL_SET, isisc_fdb_age_ctrl_set), \ + SW_API_DEF(SW_API_FDB_AGE_CTRL_GET, isisc_fdb_age_ctrl_get), \ + SW_API_DEF(SW_API_FDB_VLAN_IVL_SVL_SET, isisc_fdb_vlan_ivl_svl_set),\ + SW_API_DEF(SW_API_FDB_VLAN_IVL_SVL_GET, isisc_fdb_vlan_ivl_svl_get),\ + SW_API_DEF(SW_API_FDB_AGE_TIME_SET, isisc_fdb_age_time_set), \ + SW_API_DEF(SW_API_FDB_AGE_TIME_GET, isisc_fdb_age_time_get), \ + SW_API_DEF(SW_API_PT_FDB_LEARN_LIMIT_SET, isisc_port_fdb_learn_limit_set), \ + SW_API_DEF(SW_API_PT_FDB_LEARN_LIMIT_GET, isisc_port_fdb_learn_limit_get), \ + SW_API_DEF(SW_API_PT_FDB_LEARN_EXCEED_CMD_SET, isisc_port_fdb_learn_exceed_cmd_set), \ + SW_API_DEF(SW_API_PT_FDB_LEARN_EXCEED_CMD_GET, isisc_port_fdb_learn_exceed_cmd_get), \ + SW_API_DEF(SW_API_FDB_LEARN_LIMIT_SET, isisc_fdb_learn_limit_set), \ + SW_API_DEF(SW_API_FDB_LEARN_LIMIT_GET, isisc_fdb_learn_limit_get), \ + SW_API_DEF(SW_API_FDB_LEARN_EXCEED_CMD_SET, isisc_fdb_learn_exceed_cmd_set), \ + SW_API_DEF(SW_API_FDB_LEARN_EXCEED_CMD_GET, isisc_fdb_learn_exceed_cmd_get), \ + SW_API_DEF(SW_API_FDB_RESV_ADD, isisc_fdb_resv_add), \ + SW_API_DEF(SW_API_FDB_RESV_DEL, isisc_fdb_resv_del), \ + SW_API_DEF(SW_API_FDB_RESV_FIND, isisc_fdb_resv_find), \ + SW_API_DEF(SW_API_FDB_RESV_ITERATE, isisc_fdb_resv_iterate), \ + SW_API_DEF(SW_API_FDB_PT_LEARN_STATIC_SET, isisc_fdb_port_learn_static_set), \ + SW_API_DEF(SW_API_FDB_PT_LEARN_STATIC_GET, isisc_fdb_port_learn_static_get), \ + SW_API_DEF(SW_API_FDB_PORT_ADD, isisc_fdb_port_add), \ + SW_API_DEF(SW_API_FDB_PORT_DEL, isisc_fdb_port_del), + +#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_FIND) \ + 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_FDB_PT_LEARN_SET) \ + SW_API_DESC(SW_API_FDB_PT_LEARN_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_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_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) + +#else +#define FDB_API +#define FDB_API_PARAM +#endif + + +#ifdef IN_ACL +#define ACL_API \ + SW_API_DEF(SW_API_ACL_LIST_CREAT, isisc_acl_list_creat), \ + SW_API_DEF(SW_API_ACL_LIST_DESTROY, isisc_acl_list_destroy), \ + SW_API_DEF(SW_API_ACL_RULE_ADD, isisc_acl_rule_add), \ + SW_API_DEF(SW_API_ACL_RULE_DELETE, isisc_acl_rule_delete), \ + SW_API_DEF(SW_API_ACL_RULE_QUERY, isisc_acl_rule_query), \ + SW_API_DEF(SW_API_ACL_LIST_BIND, isisc_acl_list_bind), \ + SW_API_DEF(SW_API_ACL_LIST_UNBIND, isisc_acl_list_unbind), \ + SW_API_DEF(SW_API_ACL_STATUS_SET, isisc_acl_status_set), \ + SW_API_DEF(SW_API_ACL_STATUS_GET, isisc_acl_status_get), \ + SW_API_DEF(SW_API_ACL_LIST_DUMP, isisc_acl_list_dump), \ + SW_API_DEF(SW_API_ACL_RULE_DUMP, isisc_acl_rule_dump), \ + SW_API_DEF(SW_API_ACL_PT_UDF_PROFILE_SET, isisc_acl_port_udf_profile_set), \ + SW_API_DEF(SW_API_ACL_PT_UDF_PROFILE_GET, isisc_acl_port_udf_profile_get), \ + SW_API_DEF(SW_API_ACL_RULE_ACTIVE, isisc_acl_rule_active), \ + SW_API_DEF(SW_API_ACL_RULE_DEACTIVE, isisc_acl_rule_deactive),\ + SW_API_DEF(SW_API_ACL_RULE_SRC_FILTER_STS_SET, isisc_acl_rule_src_filter_sts_set),\ + SW_API_DEF(SW_API_ACL_RULE_SRC_FILTER_STS_GET, isisc_acl_rule_src_filter_sts_get), \ + SW_API_DEF(SW_API_ACL_RULE_GET_OFFSET, isisc_acl_rule_get_offset), + +#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) +#else +#define ACL_API +#define ACL_API_PARAM +#endif + + +#ifdef IN_QOS +#define QOS_API \ + SW_API_DEF(SW_API_QOS_QU_TX_BUF_ST_SET, isisc_qos_queue_tx_buf_status_set), \ + SW_API_DEF(SW_API_QOS_QU_TX_BUF_ST_GET, isisc_qos_queue_tx_buf_status_get), \ + SW_API_DEF(SW_API_QOS_QU_TX_BUF_NR_SET, isisc_qos_queue_tx_buf_nr_set), \ + SW_API_DEF(SW_API_QOS_QU_TX_BUF_NR_GET, isisc_qos_queue_tx_buf_nr_get), \ + SW_API_DEF(SW_API_QOS_PT_TX_BUF_ST_SET, isisc_qos_port_tx_buf_status_set), \ + SW_API_DEF(SW_API_QOS_PT_TX_BUF_ST_GET, isisc_qos_port_tx_buf_status_get), \ + SW_API_DEF(SW_API_QOS_PT_RED_EN_SET, isisc_qos_port_red_en_set),\ + SW_API_DEF(SW_API_QOS_PT_RED_EN_GET, isisc_qos_port_red_en_get),\ + SW_API_DEF(SW_API_QOS_PT_TX_BUF_NR_SET, isisc_qos_port_tx_buf_nr_set), \ + SW_API_DEF(SW_API_QOS_PT_TX_BUF_NR_GET, isisc_qos_port_tx_buf_nr_get), \ + SW_API_DEF(SW_API_QOS_PT_RX_BUF_NR_SET, isisc_qos_port_rx_buf_nr_set), \ + SW_API_DEF(SW_API_QOS_PT_RX_BUF_NR_GET, isisc_qos_port_rx_buf_nr_get), \ + SW_API_DEF(SW_API_QOS_PT_MODE_SET, isisc_qos_port_mode_set), \ + SW_API_DEF(SW_API_QOS_PT_MODE_GET, isisc_qos_port_mode_get), \ + SW_API_DEF(SW_API_QOS_PT_MODE_PRI_SET, isisc_qos_port_mode_pri_set), \ + SW_API_DEF(SW_API_QOS_PT_MODE_PRI_GET, isisc_qos_port_mode_pri_get), \ + SW_API_DEF(SW_API_QOS_PORT_SCH_MODE_SET, isisc_qos_port_sch_mode_set), \ + SW_API_DEF(SW_API_QOS_PORT_SCH_MODE_GET, isisc_qos_port_sch_mode_get), \ + SW_API_DEF(SW_API_QOS_PT_DEF_SPRI_SET, isisc_qos_port_default_spri_set), \ + SW_API_DEF(SW_API_QOS_PT_DEF_SPRI_GET, isisc_qos_port_default_spri_get), \ + SW_API_DEF(SW_API_QOS_PT_DEF_CPRI_SET, isisc_qos_port_default_cpri_set), \ + SW_API_DEF(SW_API_QOS_PT_DEF_CPRI_GET, isisc_qos_port_default_cpri_get), \ + SW_API_DEF(SW_API_QOS_PT_FORCE_SPRI_ST_SET, isisc_qos_port_force_spri_status_set), \ + SW_API_DEF(SW_API_QOS_PT_FORCE_SPRI_ST_GET, isisc_qos_port_force_spri_status_get), \ + SW_API_DEF(SW_API_QOS_PT_FORCE_CPRI_ST_SET, isisc_qos_port_force_cpri_status_set), \ + SW_API_DEF(SW_API_QOS_PT_FORCE_CPRI_ST_GET, isisc_qos_port_force_cpri_status_get), \ + SW_API_DEF(SW_API_QOS_QUEUE_REMARK_SET, isisc_qos_queue_remark_table_set), \ + SW_API_DEF(SW_API_QOS_QUEUE_REMARK_GET, isisc_qos_queue_remark_table_get), + + +#define QOS_API_PARAM \ + 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_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) +#else +#define QOS_API +#define QOS_API_PARAM +#endif + + +#ifdef IN_IGMP +#define IGMP_API \ + SW_API_DEF(SW_API_PT_IGMPS_MODE_SET, isisc_port_igmps_status_set), \ + SW_API_DEF(SW_API_PT_IGMPS_MODE_GET, isisc_port_igmps_status_get), \ + SW_API_DEF(SW_API_IGMP_MLD_CMD_SET, isisc_igmp_mld_cmd_set), \ + SW_API_DEF(SW_API_IGMP_MLD_CMD_GET, isisc_igmp_mld_cmd_get), \ + SW_API_DEF(SW_API_IGMP_PT_JOIN_SET, isisc_port_igmp_mld_join_set), \ + SW_API_DEF(SW_API_IGMP_PT_JOIN_GET, isisc_port_igmp_mld_join_get), \ + SW_API_DEF(SW_API_IGMP_PT_LEAVE_SET, isisc_port_igmp_mld_leave_set), \ + SW_API_DEF(SW_API_IGMP_PT_LEAVE_GET, isisc_port_igmp_mld_leave_get), \ + SW_API_DEF(SW_API_IGMP_RP_SET, isisc_igmp_mld_rp_set), \ + SW_API_DEF(SW_API_IGMP_RP_GET, isisc_igmp_mld_rp_get), \ + SW_API_DEF(SW_API_IGMP_ENTRY_CREAT_SET, isisc_igmp_mld_entry_creat_set), \ + SW_API_DEF(SW_API_IGMP_ENTRY_CREAT_GET, isisc_igmp_mld_entry_creat_get), \ + SW_API_DEF(SW_API_IGMP_ENTRY_STATIC_SET, isisc_igmp_mld_entry_static_set), \ + SW_API_DEF(SW_API_IGMP_ENTRY_STATIC_GET, isisc_igmp_mld_entry_static_get), \ + SW_API_DEF(SW_API_IGMP_ENTRY_LEAKY_SET, isisc_igmp_mld_entry_leaky_set), \ + SW_API_DEF(SW_API_IGMP_ENTRY_LEAKY_GET, isisc_igmp_mld_entry_leaky_get), \ + SW_API_DEF(SW_API_IGMP_ENTRY_V3_SET, isisc_igmp_mld_entry_v3_set), \ + SW_API_DEF(SW_API_IGMP_ENTRY_V3_GET, isisc_igmp_mld_entry_v3_get), \ + SW_API_DEF(SW_API_IGMP_ENTRY_QUEUE_SET, isisc_igmp_mld_entry_queue_set), \ + SW_API_DEF(SW_API_IGMP_ENTRY_QUEUE_GET, isisc_igmp_mld_entry_queue_get), \ + SW_API_DEF(SW_API_PT_IGMP_LEARN_LIMIT_SET, isisc_port_igmp_mld_learn_limit_set), \ + SW_API_DEF(SW_API_PT_IGMP_LEARN_LIMIT_GET, isisc_port_igmp_mld_learn_limit_get), \ + SW_API_DEF(SW_API_PT_IGMP_LEARN_EXCEED_CMD_SET, isisc_port_igmp_mld_learn_exceed_cmd_set), \ + SW_API_DEF(SW_API_PT_IGMP_LEARN_EXCEED_CMD_GET, isisc_port_igmp_mld_learn_exceed_cmd_get), \ + SW_API_DEF(SW_API_IGMP_SG_ENTRY_SET, isisc_igmp_sg_entry_set), \ + SW_API_DEF(SW_API_IGMP_SG_ENTRY_CLEAR, isisc_igmp_sg_entry_clear), \ + SW_API_DEF(SW_API_IGMP_SG_ENTRY_SHOW, isisc_igmp_sg_entry_show), + +#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) +#else +#define IGMP_API +#define IGMP_API_PARAM +#endif + + +#ifdef IN_LEAKY +#define LEAKY_API \ + SW_API_DEF(SW_API_UC_LEAKY_MODE_SET, isisc_uc_leaky_mode_set), \ + SW_API_DEF(SW_API_UC_LEAKY_MODE_GET, isisc_uc_leaky_mode_get), \ + SW_API_DEF(SW_API_MC_LEAKY_MODE_SET, isisc_mc_leaky_mode_set), \ + SW_API_DEF(SW_API_MC_LEAKY_MODE_GET, isisc_mc_leaky_mode_get), \ + SW_API_DEF(SW_API_ARP_LEAKY_MODE_SET, isisc_port_arp_leaky_set), \ + SW_API_DEF(SW_API_ARP_LEAKY_MODE_GET, isisc_port_arp_leaky_get), \ + SW_API_DEF(SW_API_PT_UC_LEAKY_MODE_SET, isisc_port_uc_leaky_set), \ + SW_API_DEF(SW_API_PT_UC_LEAKY_MODE_GET, isisc_port_uc_leaky_get), \ + SW_API_DEF(SW_API_PT_MC_LEAKY_MODE_SET, isisc_port_mc_leaky_set), \ + SW_API_DEF(SW_API_PT_MC_LEAKY_MODE_GET, isisc_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, isisc_mirr_analysis_port_set), \ + SW_API_DEF(SW_API_MIRROR_ANALY_PT_GET, isisc_mirr_analysis_port_get), \ + SW_API_DEF(SW_API_MIRROR_IN_PT_SET, isisc_mirr_port_in_set), \ + SW_API_DEF(SW_API_MIRROR_IN_PT_GET, isisc_mirr_port_in_get), \ + SW_API_DEF(SW_API_MIRROR_EG_PT_SET, isisc_mirr_port_eg_set), \ + SW_API_DEF(SW_API_MIRROR_EG_PT_GET, isisc_mirr_port_eg_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) +#else +#define MIRROR_API +#define MIRROR_API_PARAM +#endif + + +#ifdef IN_RATE +#define RATE_API \ + SW_API_DEF(SW_API_RATE_PORT_POLICER_SET, isisc_rate_port_policer_set), \ + SW_API_DEF(SW_API_RATE_PORT_POLICER_GET, isisc_rate_port_policer_get), \ + SW_API_DEF(SW_API_RATE_PORT_SHAPER_SET, isisc_rate_port_shaper_set), \ + SW_API_DEF(SW_API_RATE_PORT_SHAPER_GET, isisc_rate_port_shaper_get), \ + SW_API_DEF(SW_API_RATE_QUEUE_SHAPER_SET, isisc_rate_queue_shaper_set), \ + SW_API_DEF(SW_API_RATE_QUEUE_SHAPER_GET, isisc_rate_queue_shaper_get), \ + SW_API_DEF(SW_API_RATE_ACL_POLICER_SET, isisc_rate_acl_policer_set), \ + SW_API_DEF(SW_API_RATE_ACL_POLICER_GET, isisc_rate_acl_policer_get), \ + SW_API_DEF(SW_API_RATE_PT_ADDRATEBYTE_SET, isisc_rate_port_add_rate_byte_set), \ + SW_API_DEF(SW_API_RATE_PT_ADDRATEBYTE_GET, isisc_rate_port_add_rate_byte_get), \ + SW_API_DEF(SW_API_RATE_PT_GOL_FLOW_EN_SET, isisc_rate_port_gol_flow_en_set), \ + SW_API_DEF(SW_API_RATE_PT_GOL_FLOW_EN_GET, isisc_rate_port_gol_flow_en_get), + +#define RATE_API_PARAM \ + 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, isisc_stp_port_state_set), \ + SW_API_DEF(SW_API_STP_PT_STATE_GET, isisc_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, isisc_get_mib_info), \ + SW_API_DEF(SW_API_MIB_STATUS_SET, isisc_mib_status_set), \ + SW_API_DEF(SW_API_MIB_STATUS_GET, isisc_mib_status_get), \ + SW_API_DEF(SW_API_PT_MIB_FLUSH_COUNTERS, isisc_mib_port_flush_counters), \ + SW_API_DEF(SW_API_MIB_CPU_KEEP_SET, isisc_mib_cpukeep_set), \ + SW_API_DEF(SW_API_MIB_CPU_KEEP_GET, isisc_mib_cpukeep_get), + + +#define MIB_API_PARAM \ + SW_API_DESC(SW_API_PT_MIB_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) +#else +#define MIB_API +#define MIB_API_PARAM +#endif + + +#ifdef IN_MISC +#define MISC_API \ + SW_API_DEF(SW_API_FRAME_MAX_SIZE_SET, isisc_frame_max_size_set), \ + SW_API_DEF(SW_API_FRAME_MAX_SIZE_GET, isisc_frame_max_size_get), \ + SW_API_DEF(SW_API_PT_UNK_UC_FILTER_SET, isisc_port_unk_uc_filter_set), \ + SW_API_DEF(SW_API_PT_UNK_UC_FILTER_GET, isisc_port_unk_uc_filter_get), \ + SW_API_DEF(SW_API_PT_UNK_MC_FILTER_SET, isisc_port_unk_mc_filter_set), \ + SW_API_DEF(SW_API_PT_UNK_MC_FILTER_GET, isisc_port_unk_mc_filter_get), \ + SW_API_DEF(SW_API_PT_BC_FILTER_SET, isisc_port_bc_filter_set), \ + SW_API_DEF(SW_API_PT_BC_FILTER_GET, isisc_port_bc_filter_get), \ + SW_API_DEF(SW_API_CPU_PORT_STATUS_SET, isisc_cpu_port_status_set), \ + SW_API_DEF(SW_API_CPU_PORT_STATUS_GET, isisc_cpu_port_status_get), \ + SW_API_DEF(SW_API_PPPOE_CMD_SET, isisc_pppoe_cmd_set), \ + SW_API_DEF(SW_API_PPPOE_CMD_GET, isisc_pppoe_cmd_get), \ + SW_API_DEF(SW_API_PPPOE_STATUS_SET, isisc_pppoe_status_set), \ + SW_API_DEF(SW_API_PPPOE_STATUS_GET, isisc_pppoe_status_get), \ + SW_API_DEF(SW_API_PT_DHCP_SET, isisc_port_dhcp_set), \ + SW_API_DEF(SW_API_PT_DHCP_GET, isisc_port_dhcp_get), \ + SW_API_DEF(SW_API_ARP_CMD_SET, isisc_arp_cmd_set), \ + SW_API_DEF(SW_API_ARP_CMD_GET, isisc_arp_cmd_get), \ + SW_API_DEF(SW_API_EAPOL_CMD_SET, isisc_eapol_cmd_set), \ + SW_API_DEF(SW_API_EAPOL_CMD_GET, isisc_eapol_cmd_get), \ + SW_API_DEF(SW_API_EAPOL_STATUS_SET, isisc_eapol_status_set), \ + SW_API_DEF(SW_API_EAPOL_STATUS_GET, isisc_eapol_status_get), \ + SW_API_DEF(SW_API_RIPV1_STATUS_SET, isisc_ripv1_status_set), \ + SW_API_DEF(SW_API_RIPV1_STATUS_GET, isisc_ripv1_status_get), \ + SW_API_DEF(SW_API_PT_ARP_REQ_STATUS_SET, isisc_port_arp_req_status_set), \ + SW_API_DEF(SW_API_PT_ARP_REQ_STATUS_GET, isisc_port_arp_req_status_get), \ + SW_API_DEF(SW_API_PT_ARP_ACK_STATUS_SET, isisc_port_arp_ack_status_set), \ + SW_API_DEF(SW_API_PT_ARP_ACK_STATUS_GET, isisc_port_arp_ack_status_get), \ + SW_API_DEF(SW_API_PPPOE_SESSION_TABLE_ADD, isisc_pppoe_session_table_add), \ + SW_API_DEF(SW_API_PPPOE_SESSION_TABLE_DEL, isisc_pppoe_session_table_del), \ + SW_API_DEF(SW_API_PPPOE_SESSION_TABLE_GET, isisc_pppoe_session_table_get), \ + SW_API_DEF(SW_API_PPPOE_SESSION_ID_SET, isisc_pppoe_session_id_set), \ + SW_API_DEF(SW_API_PPPOE_SESSION_ID_GET, isisc_pppoe_session_id_get), \ + SW_API_DEF(SW_API_INTR_MASK_SET, isisc_intr_mask_set), \ + SW_API_DEF(SW_API_INTR_MASK_GET, isisc_intr_mask_get), \ + SW_API_DEF(SW_API_INTR_STATUS_GET, isisc_intr_status_get), \ + SW_API_DEF(SW_API_INTR_STATUS_CLEAR, isisc_intr_status_clear), \ + SW_API_DEF(SW_API_INTR_PORT_LINK_MASK_SET, isisc_intr_port_link_mask_set), \ + SW_API_DEF(SW_API_INTR_PORT_LINK_MASK_GET, isisc_intr_port_link_mask_get), \ + SW_API_DEF(SW_API_INTR_PORT_LINK_STATUS_GET, isisc_intr_port_link_status_get),\ + SW_API_DEF(SW_API_INTR_MASK_MAC_LINKCHG_SET, isisc_intr_mask_mac_linkchg_set), \ + SW_API_DEF(SW_API_INTR_MASK_MAC_LINKCHG_GET, isisc_intr_mask_mac_linkchg_get), \ + SW_API_DEF(SW_API_INTR_STATUS_MAC_LINKCHG_GET, isisc_intr_status_mac_linkchg_get), \ + SW_API_DEF(SW_API_INTR_STATUS_MAC_LINKCHG_CLEAR, isisc_intr_status_mac_linkchg_clear), \ + SW_API_DEF(SW_API_CPU_VID_EN_SET, isisc_cpu_vid_en_set), \ + SW_API_DEF(SW_API_CPU_VID_EN_GET, isisc_cpu_vid_en_get), \ + SW_API_DEF(SW_API_RTD_PPPOE_EN_SET, isisc_rtd_pppoe_en_set), \ + SW_API_DEF(SW_API_RTD_PPPOE_EN_GET, isisc_rtd_pppoe_en_get), + +#define MISC_API_PARAM \ + 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_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_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_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_PPPOE_SESSION_ADD) \ + SW_API_DESC(SW_API_PPPOE_SESSION_DEL) \ + SW_API_DESC(SW_API_PPPOE_SESSION_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_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_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_RTD_PPPOE_EN_SET) \ + SW_API_DESC(SW_API_RTD_PPPOE_EN_GET) + +#else +#define MISC_API +#define MISC_API_PARAM +#endif + + +#ifdef IN_LED +#define LED_API \ + SW_API_DEF(SW_API_LED_PATTERN_SET, isisc_led_ctrl_pattern_set), \ + SW_API_DEF(SW_API_LED_PATTERN_GET, isisc_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, isisc_cosmap_dscp_to_pri_set), \ + SW_API_DEF(SW_API_COSMAP_DSCP_TO_PRI_GET, isisc_cosmap_dscp_to_pri_get), \ + SW_API_DEF(SW_API_COSMAP_DSCP_TO_DP_SET, isisc_cosmap_dscp_to_dp_set), \ + SW_API_DEF(SW_API_COSMAP_DSCP_TO_DP_GET, isisc_cosmap_dscp_to_dp_get), \ + SW_API_DEF(SW_API_COSMAP_UP_TO_PRI_SET, isisc_cosmap_up_to_pri_set), \ + SW_API_DEF(SW_API_COSMAP_UP_TO_PRI_GET, isisc_cosmap_up_to_pri_get), \ + SW_API_DEF(SW_API_COSMAP_UP_TO_DP_SET, isisc_cosmap_up_to_dp_set), \ + SW_API_DEF(SW_API_COSMAP_UP_TO_DP_GET, isisc_cosmap_up_to_dp_get), \ + SW_API_DEF(SW_API_COSMAP_PRI_TO_QU_SET, isisc_cosmap_pri_to_queue_set), \ + SW_API_DEF(SW_API_COSMAP_PRI_TO_QU_GET, isisc_cosmap_pri_to_queue_get), \ + SW_API_DEF(SW_API_COSMAP_PRI_TO_EHQU_SET, isisc_cosmap_pri_to_ehqueue_set), \ + SW_API_DEF(SW_API_COSMAP_PRI_TO_EHQU_GET, isisc_cosmap_pri_to_ehqueue_get), \ + SW_API_DEF(SW_API_COSMAP_EG_REMARK_SET, isisc_cosmap_egress_remark_set), \ + SW_API_DEF(SW_API_COSMAP_EG_REMARK_GET, isisc_cosmap_egress_remark_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) +#else +#define COSMAP_API +#define COSMAP_API_PARAM +#endif + +#ifdef IN_SEC +#define SEC_API \ + SW_API_DEF(SW_API_SEC_NORM_SET, isisc_sec_norm_item_set), \ + SW_API_DEF(SW_API_SEC_NORM_GET, isisc_sec_norm_item_get), \ + SW_API_DEF(SW_API_SEC_MAC_SET, isisc_sec_norm_item_set), \ + SW_API_DEF(SW_API_SEC_MAC_GET, isisc_sec_norm_item_get), \ + SW_API_DEF(SW_API_SEC_IP_SET, isisc_sec_norm_item_set), \ + SW_API_DEF(SW_API_SEC_IP_GET, isisc_sec_norm_item_get), \ + SW_API_DEF(SW_API_SEC_IP4_SET, isisc_sec_norm_item_set), \ + SW_API_DEF(SW_API_SEC_IP4_GET, isisc_sec_norm_item_get), \ + SW_API_DEF(SW_API_SEC_IP6_SET, isisc_sec_norm_item_set), \ + SW_API_DEF(SW_API_SEC_IP6_GET, isisc_sec_norm_item_get), \ + SW_API_DEF(SW_API_SEC_TCP_SET, isisc_sec_norm_item_set), \ + SW_API_DEF(SW_API_SEC_TCP_GET, isisc_sec_norm_item_get), \ + SW_API_DEF(SW_API_SEC_UDP_SET, isisc_sec_norm_item_set), \ + SW_API_DEF(SW_API_SEC_UDP_GET, isisc_sec_norm_item_get), \ + SW_API_DEF(SW_API_SEC_ICMP4_SET, isisc_sec_norm_item_set), \ + SW_API_DEF(SW_API_SEC_ICMP4_GET, isisc_sec_norm_item_get), \ + SW_API_DEF(SW_API_SEC_ICMP6_SET, isisc_sec_norm_item_set), \ + SW_API_DEF(SW_API_SEC_ICMP6_GET, isisc_sec_norm_item_get), + +#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) +#else +#define SEC_API +#define SEC_API_PARAM +#endif + +#ifdef IN_IP +#define IP_API \ + SW_API_DEF(SW_API_IP_HOST_ADD, isisc_ip_host_add), \ + SW_API_DEF(SW_API_IP_HOST_DEL, isisc_ip_host_del), \ + SW_API_DEF(SW_API_IP_HOST_GET, isisc_ip_host_get), \ + SW_API_DEF(SW_API_IP_HOST_NEXT, isisc_ip_host_next), \ + SW_API_DEF(SW_API_IP_HOST_COUNTER_BIND, isisc_ip_host_counter_bind), \ + SW_API_DEF(SW_API_IP_HOST_PPPOE_BIND, isisc_ip_host_pppoe_bind), \ + SW_API_DEF(SW_API_IP_PT_ARP_LEARN_SET, isisc_ip_pt_arp_learn_set), \ + SW_API_DEF(SW_API_IP_PT_ARP_LEARN_GET, isisc_ip_pt_arp_learn_get), \ + SW_API_DEF(SW_API_IP_ARP_LEARN_SET, isisc_ip_arp_learn_set), \ + SW_API_DEF(SW_API_IP_ARP_LEARN_GET, isisc_ip_arp_learn_get), \ + SW_API_DEF(SW_API_IP_SOURCE_GUARD_SET, isisc_ip_source_guard_set), \ + SW_API_DEF(SW_API_IP_SOURCE_GUARD_GET, isisc_ip_source_guard_get), \ + SW_API_DEF(SW_API_IP_ARP_GUARD_SET, isisc_ip_arp_guard_set), \ + SW_API_DEF(SW_API_IP_ARP_GUARD_GET, isisc_ip_arp_guard_get), \ + SW_API_DEF(SW_API_IP_ROUTE_STATUS_SET, isisc_ip_route_status_set), \ + SW_API_DEF(SW_API_IP_ROUTE_STATUS_GET, isisc_ip_route_status_get), \ + SW_API_DEF(SW_API_IP_INTF_ENTRY_ADD, isisc_ip_intf_entry_add), \ + SW_API_DEF(SW_API_IP_INTF_ENTRY_DEL, isisc_ip_intf_entry_del), \ + SW_API_DEF(SW_API_IP_INTF_ENTRY_NEXT, isisc_ip_intf_entry_next), \ + SW_API_DEF(SW_API_IP_UNK_SOURCE_CMD_SET, isisc_ip_unk_source_cmd_set), \ + SW_API_DEF(SW_API_IP_UNK_SOURCE_CMD_GET, isisc_ip_unk_source_cmd_get), \ + SW_API_DEF(SW_API_ARP_UNK_SOURCE_CMD_SET, isisc_arp_unk_source_cmd_set), \ + SW_API_DEF(SW_API_ARP_UNK_SOURCE_CMD_GET, isisc_arp_unk_source_cmd_get), \ + SW_API_DEF(SW_API_IP_AGE_TIME_SET, isisc_ip_age_time_set), \ + SW_API_DEF(SW_API_IP_AGE_TIME_GET, isisc_ip_age_time_get), \ + SW_API_DEF(SW_API_WCMP_HASH_MODE_SET, isisc_ip_wcmp_hash_mode_set), \ + SW_API_DEF(SW_API_WCMP_HASH_MODE_GET, isisc_ip_wcmp_hash_mode_get), + +#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) + +#else +#define IP_API +#define IP_API_PARAM +#endif + +#ifdef IN_NAT +#define NAT_API \ + SW_API_DEF(SW_API_NAT_ADD, isisc_nat_add), \ + SW_API_DEF(SW_API_NAT_DEL, isisc_nat_del), \ + SW_API_DEF(SW_API_NAT_GET, isisc_nat_get), \ + SW_API_DEF(SW_API_NAT_NEXT, isisc_nat_next), \ + SW_API_DEF(SW_API_NAT_COUNTER_BIND, isisc_nat_counter_bind), \ + SW_API_DEF(SW_API_NAPT_ADD, isisc_napt_add), \ + SW_API_DEF(SW_API_NAPT_DEL, isisc_napt_del), \ + SW_API_DEF(SW_API_NAPT_GET, isisc_napt_get), \ + SW_API_DEF(SW_API_NAPT_NEXT, isisc_napt_next), \ + SW_API_DEF(SW_API_NAPT_COUNTER_BIND, isisc_napt_counter_bind), \ + SW_API_DEF(SW_API_NAT_STATUS_SET, isisc_nat_status_set), \ + SW_API_DEF(SW_API_NAT_STATUS_GET, isisc_nat_status_get), \ + SW_API_DEF(SW_API_NAT_HASH_MODE_SET, isisc_nat_hash_mode_set), \ + SW_API_DEF(SW_API_NAT_HASH_MODE_GET, isisc_nat_hash_mode_get), \ + SW_API_DEF(SW_API_NAPT_STATUS_SET, isisc_napt_status_set), \ + SW_API_DEF(SW_API_NAPT_STATUS_GET, isisc_napt_status_get), \ + SW_API_DEF(SW_API_NAPT_MODE_SET, isisc_napt_mode_set), \ + SW_API_DEF(SW_API_NAPT_MODE_GET, isisc_napt_mode_get), \ + SW_API_DEF(SW_API_PRV_BASE_ADDR_SET, isisc_nat_prv_base_addr_set), \ + SW_API_DEF(SW_API_PRV_BASE_ADDR_GET, isisc_nat_prv_base_addr_get), \ + SW_API_DEF(SW_API_PUB_ADDR_ENTRY_ADD, isisc_nat_pub_addr_add), \ + SW_API_DEF(SW_API_PUB_ADDR_ENTRY_DEL, isisc_nat_pub_addr_del), \ + SW_API_DEF(SW_API_PUB_ADDR_ENTRY_NEXT, isisc_nat_pub_addr_next), \ + SW_API_DEF(SW_API_NAT_UNK_SESSION_CMD_SET, isisc_nat_unk_session_cmd_set), \ + SW_API_DEF(SW_API_NAT_UNK_SESSION_CMD_GET, isisc_nat_unk_session_cmd_get), \ + SW_API_DEF(SW_API_PRV_BASE_MASK_SET, isisc_nat_prv_base_mask_set), \ + SW_API_DEF(SW_API_PRV_BASE_MASK_GET, isisc_nat_prv_base_mask_get), \ + SW_API_DEF(SW_API_NAT_GLOBAL_SET, isisc_nat_global_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_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_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) +#else +#define NAT_API +#define NAT_API_PARAM +#endif + +#ifdef IN_TRUNK +#define TRUNK_API \ + SW_API_DEF(SW_API_TRUNK_GROUP_SET, isisc_trunk_group_set), \ + SW_API_DEF(SW_API_TRUNK_GROUP_GET, isisc_trunk_group_get), \ + SW_API_DEF(SW_API_TRUNK_HASH_SET, isisc_trunk_hash_mode_set), \ + SW_API_DEF(SW_API_TRUNK_HASH_GET, isisc_trunk_hash_mode_get), \ + SW_API_DEF(SW_API_TRUNK_MAN_SA_SET, isisc_trunk_manipulate_sa_set), \ + SW_API_DEF(SW_API_TRUNK_MAN_SA_GET, isisc_trunk_manipulate_sa_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) +#else +#define TRUNK_API +#define TRUNK_API_PARAM +#endif + +#ifdef IN_INTERFACECONTROL +#define INTERFACECTRL_API \ + SW_API_DEF(SW_API_MAC_MODE_SET, isisc_interface_mac_mode_set), \ + SW_API_DEF(SW_API_MAC_MODE_GET, isisc_interface_mac_mode_get), \ + SW_API_DEF(SW_API_PORT_3AZ_STATUS_SET, isisc_port_3az_status_set), \ + SW_API_DEF(SW_API_PORT_3AZ_STATUS_GET, isisc_port_3az_status_get), \ + SW_API_DEF(SW_API_PHY_MODE_SET, isisc_interface_phy_mode_set), \ + SW_API_DEF(SW_API_PHY_MODE_GET, isisc_interface_phy_mode_get), \ + SW_API_DEF(SW_API_FX100_CTRL_SET, isisc_interface_fx100_ctrl_set), \ + SW_API_DEF(SW_API_FX100_CTRL_GET, isisc_interface_fx100_ctrl_get), \ + SW_API_DEF(SW_API_FX100_STATUS_GET, isisc_interface_fx100_status_get), \ + SW_API_DEF(SW_API_MAC06_EXCH_SET, isisc_interface_mac06_exch_set), \ + SW_API_DEF(SW_API_MAC06_EXCH_GET, isisc_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 + +#define REG_API \ + SW_API_DEF(SW_API_PHY_GET, isisc_phy_get), \ + SW_API_DEF(SW_API_PHY_SET, isisc_phy_set), \ + SW_API_DEF(SW_API_REG_GET, isisc_reg_get), \ + SW_API_DEF(SW_API_REG_SET, isisc_reg_set), \ + SW_API_DEF(SW_API_REG_FIELD_GET, isisc_reg_field_get), \ + SW_API_DEF(SW_API_REG_FIELD_SET, isisc_reg_field_set), \ + SW_API_DEF(SW_API_REG_DUMP, isisc_regsiter_dump), \ + SW_API_DEF(SW_API_DBG_REG_DUMP, isisc_debug_regsiter_dump), + +#define REG_API_PARAM \ + SW_API_DESC(SW_API_PHY_GET) \ + SW_API_DESC(SW_API_PHY_SET) \ + SW_API_DESC(SW_API_REG_GET) \ + SW_API_DESC(SW_API_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) + +#define SSDK_API \ + SW_API_DEF(SW_API_SWITCH_RESET, isisc_reset), \ + SW_API_DEF(SW_API_SSDK_CFG, hsl_ssdk_cfg), \ + PORTCONTROL_API \ + 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 \ + TRUNK_API \ + INTERFACECTRL_API \ + REG_API \ + SW_API_DEF(SW_API_MAX, NULL), + + +#define SSDK_PARAM \ + 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"), \ + MIB_API_PARAM \ + LEAKY_API_PARAM \ + MISC_API_PARAM \ + IGMP_API_PARAM \ + MIRROR_API_PARAM \ + PORTCONTROL_API_PARAM \ + 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 \ + TRUNK_API_PARAM \ + INTERFACECTRL_API_PARAM \ + REG_API_PARAM \ + SW_PARAM_DEF(SW_API_MAX, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), + +#if (defined(USER_MODE) && defined(KERNEL_MODULE)) +#undef SSDK_API +#undef SSDK_PARAM + +#define SSDK_API \ + REG_API \ + SW_API_DEF(SW_API_MAX, NULL), + +#define SSDK_PARAM \ + REG_API_PARAM \ + SW_PARAM_DEF(SW_API_MAX, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _ISISC_API_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_cosmap.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_cosmap.h new file mode 100755 index 000000000..d79a20bc9 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_cosmap.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 isisc_cosmap ISISC_COSMAP + * @{ + */ +#ifndef _ISISC_COSMAP_H_ +#define _ISISC_COSMAP_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_cosmap.h" + + sw_error_t isisc_cosmap_init(a_uint32_t dev_id); + +#ifdef IN_COSMAP +#define ISISC_COSMAP_INIT(rv, dev_id) \ + { \ + rv = isisc_cosmap_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISISC_COSMAP_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + isisc_cosmap_dscp_to_pri_set(a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t pri); + + HSL_LOCAL sw_error_t + isisc_cosmap_dscp_to_pri_get(a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t * pri); + + HSL_LOCAL sw_error_t + isisc_cosmap_dscp_to_dp_set(a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t dp); + + HSL_LOCAL sw_error_t + isisc_cosmap_dscp_to_dp_get(a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t * dp); + + HSL_LOCAL sw_error_t + isisc_cosmap_up_to_pri_set(a_uint32_t dev_id, a_uint32_t up, + a_uint32_t pri); + + HSL_LOCAL sw_error_t + isisc_cosmap_up_to_pri_get(a_uint32_t dev_id, a_uint32_t up, + a_uint32_t * pri); + + HSL_LOCAL sw_error_t + isisc_cosmap_up_to_dp_set(a_uint32_t dev_id, a_uint32_t up, + a_uint32_t dp); + + HSL_LOCAL sw_error_t + isisc_cosmap_up_to_dp_get(a_uint32_t dev_id, a_uint32_t up, + a_uint32_t * dp); + + HSL_LOCAL sw_error_t + isisc_cosmap_pri_to_queue_set(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t queue); + + HSL_LOCAL sw_error_t + isisc_cosmap_pri_to_queue_get(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t * queue); + + HSL_LOCAL sw_error_t + isisc_cosmap_pri_to_ehqueue_set(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t queue); + + HSL_LOCAL sw_error_t + isisc_cosmap_pri_to_ehqueue_get(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t * queue); + + HSL_LOCAL sw_error_t + isisc_cosmap_egress_remark_set(a_uint32_t dev_id, a_uint32_t tbl_id, + fal_egress_remark_table_t * tbl); + + HSL_LOCAL sw_error_t + isisc_cosmap_egress_remark_get(a_uint32_t dev_id, a_uint32_t tbl_id, + fal_egress_remark_table_t * tbl); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISISC_COSMAP_H_ */ + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_fdb.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_fdb.h new file mode 100755 index 000000000..13cd37c8b --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_fdb.h @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 isisc_fdb ISISC_FDB + * @{ + */ +#ifndef _ISISC_FDB_H_ +#define _ISISC_FDB_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_fdb.h" + + sw_error_t isisc_fdb_init(a_uint32_t dev_id); + +#ifdef IN_FDB +#define ISISC_FDB_INIT(rv, dev_id) \ + { \ + rv = isisc_fdb_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISISC_FDB_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + isisc_fdb_add(a_uint32_t dev_id, const fal_fdb_entry_t * entry); + + HSL_LOCAL sw_error_t + isisc_fdb_find(a_uint32_t dev_id, fal_fdb_entry_t * entry); + + HSL_LOCAL sw_error_t + isisc_fdb_del_all(a_uint32_t dev_id, a_uint32_t flag); + + HSL_LOCAL sw_error_t + isisc_fdb_del_by_port(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t flag); + + HSL_LOCAL sw_error_t + isisc_fdb_del_by_mac(a_uint32_t dev_id, const fal_fdb_entry_t * entry); + + HSL_LOCAL sw_error_t + isisc_fdb_extend_next(a_uint32_t dev_id, fal_fdb_op_t * op, + fal_fdb_entry_t * entry); + + HSL_LOCAL sw_error_t + isisc_fdb_extend_first(a_uint32_t dev_id, fal_fdb_op_t * option, + fal_fdb_entry_t * entry); + + HSL_LOCAL sw_error_t + isisc_fdb_transfer(a_uint32_t dev_id, fal_port_t old_port, + fal_port_t new_port, a_uint32_t fid, + fal_fdb_op_t * option); + + HSL_LOCAL sw_error_t + isisc_fdb_port_learn_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + HSL_LOCAL sw_error_t + isisc_fdb_port_learn_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + HSL_LOCAL sw_error_t + isisc_fdb_age_ctrl_set(a_uint32_t dev_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + isisc_fdb_age_ctrl_get(a_uint32_t dev_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + isisc_fdb_vlan_ivl_svl_set(a_uint32_t dev_id, fal_fdb_smode smode); + + HSL_LOCAL sw_error_t + isisc_fdb_vlan_ivl_svl_get(a_uint32_t dev_id, fal_fdb_smode * smode); + + HSL_LOCAL sw_error_t + isisc_fdb_age_time_set(a_uint32_t dev_id, a_uint32_t * time); + + HSL_LOCAL sw_error_t + isisc_fdb_age_time_get(a_uint32_t dev_id, a_uint32_t * time); + + HSL_LOCAL sw_error_t + isisc_port_fdb_learn_limit_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable, a_uint32_t cnt); + + HSL_LOCAL sw_error_t + isisc_port_fdb_learn_limit_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable, a_uint32_t * cnt); + + HSL_LOCAL sw_error_t + isisc_port_fdb_learn_exceed_cmd_set(a_uint32_t dev_id, + fal_port_t port_id, + fal_fwd_cmd_t cmd); + + HSL_LOCAL sw_error_t + isisc_port_fdb_learn_exceed_cmd_get(a_uint32_t dev_id, + fal_port_t port_id, + fal_fwd_cmd_t * cmd); + + HSL_LOCAL sw_error_t + isisc_fdb_learn_limit_set(a_uint32_t dev_id, a_bool_t enable, + a_uint32_t cnt); + + HSL_LOCAL sw_error_t + isisc_fdb_learn_limit_get(a_uint32_t dev_id, a_bool_t * enable, + a_uint32_t * cnt); + + HSL_LOCAL sw_error_t + isisc_fdb_learn_exceed_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + HSL_LOCAL sw_error_t + isisc_fdb_learn_exceed_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + HSL_LOCAL sw_error_t + isisc_fdb_resv_add(a_uint32_t dev_id, fal_fdb_entry_t * entry); + + HSL_LOCAL sw_error_t + isisc_fdb_resv_del(a_uint32_t dev_id, fal_fdb_entry_t * entry); + + HSL_LOCAL sw_error_t + isisc_fdb_resv_find(a_uint32_t dev_id, fal_fdb_entry_t * entry); + + HSL_LOCAL sw_error_t + isisc_fdb_resv_iterate(a_uint32_t dev_id, a_uint32_t * iterator, + fal_fdb_entry_t * entry); + + HSL_LOCAL sw_error_t + isisc_fdb_port_learn_static_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + HSL_LOCAL sw_error_t + isisc_fdb_port_learn_static_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + HSL_LOCAL sw_error_t + isisc_fdb_port_add(a_uint32_t dev_id, a_uint32_t fid, fal_mac_addr_t * addr, fal_port_t port_id); + + HSL_LOCAL sw_error_t + isisc_fdb_port_del(a_uint32_t dev_id, a_uint32_t fid, fal_mac_addr_t * addr, fal_port_t port_id); + + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISISC_FDB_H_ */ + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_fdb_prv.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_fdb_prv.h new file mode 100755 index 000000000..a67e58dc7 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_fdb_prv.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISISC_FDB_PRV_H_ +#define _ISISC_FDB_PRV_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +#define ARL_FLUSH_ALL 1 +#define ARL_LOAD_ENTRY 2 +#define ARL_PURGE_ENTRY 3 +#define ARL_FLUSH_ALL_UNLOCK 4 +#define ARL_FLUSH_PORT_UNICAST 5 +#define ARL_NEXT_ENTRY 6 +#define ARL_FIND_ENTRY 7 +#define ARL_TRANSFER_ENTRY 8 + +#define ARL_FIRST_ENTRY 1001 +#define ARL_FLUSH_PORT_NO_STATIC 1002 +#define ARL_FLUSH_PORT_AND_STATIC 1003 + +#define ISISC_MAX_FID 4095 +#define ISISC_MAX_LEARN_LIMIT_CNT 2048 +#define ISISC_MAX_PORT_LEARN_LIMIT_CNT 1024 + + sw_error_t + inter_isisc_fdb_flush(a_uint32_t dev_id, a_uint32_t flag); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISISC_FDB_PRV_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_igmp.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_igmp.h new file mode 100755 index 000000000..7d83f5d23 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_igmp.h @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 isisc_igmp ISISC_IGMP + * @{ + */ +#ifndef _ISISC_IGMP_H_ +#define _ISISC_IGMP_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_igmp.h" +#include "fal/fal_multi.h" + + sw_error_t + isisc_igmp_init(a_uint32_t dev_id); + +#ifdef IN_IGMP +#define ISISC_IGMP_INIT(rv, dev_id) \ + { \ + rv = isisc_igmp_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISISC_IGMP_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + isisc_port_igmps_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_port_igmps_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable); + + + HSL_LOCAL sw_error_t + isisc_igmp_mld_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + + HSL_LOCAL sw_error_t + isisc_igmp_mld_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + + HSL_LOCAL sw_error_t + isisc_port_igmp_mld_join_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_port_igmp_mld_join_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isisc_port_igmp_mld_leave_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_port_igmp_mld_leave_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isisc_igmp_mld_rp_set(a_uint32_t dev_id, fal_pbmp_t pts); + + + HSL_LOCAL sw_error_t + isisc_igmp_mld_rp_get(a_uint32_t dev_id, fal_pbmp_t * pts); + + + HSL_LOCAL sw_error_t + isisc_igmp_mld_entry_creat_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_igmp_mld_entry_creat_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isisc_igmp_mld_entry_static_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_igmp_mld_entry_static_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isisc_igmp_mld_entry_leaky_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_igmp_mld_entry_leaky_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isisc_igmp_mld_entry_v3_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_igmp_mld_entry_v3_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isisc_igmp_mld_entry_queue_set(a_uint32_t dev_id, a_bool_t enable, a_uint32_t queue); + + + HSL_LOCAL sw_error_t + isisc_igmp_mld_entry_queue_get(a_uint32_t dev_id, a_bool_t * enable, a_uint32_t * queue); + + + HSL_LOCAL sw_error_t + isisc_port_igmp_mld_learn_limit_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable, a_uint32_t cnt); + + + HSL_LOCAL sw_error_t + isisc_port_igmp_mld_learn_limit_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable, a_uint32_t * cnt); + + + HSL_LOCAL sw_error_t + isisc_port_igmp_mld_learn_exceed_cmd_set(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t cmd); + + + HSL_LOCAL sw_error_t + isisc_port_igmp_mld_learn_exceed_cmd_get(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t * cmd); + + HSL_LOCAL sw_error_t + isisc_igmp_sg_entry_set(a_uint32_t dev_id, fal_igmp_sg_entry_t * entry); + + HSL_LOCAL sw_error_t + isisc_igmp_sg_entry_clear(a_uint32_t dev_id, fal_igmp_sg_entry_t * entry); + + HSL_LOCAL sw_error_t + isisc_igmp_sg_entry_show(a_uint32_t dev_id); + + HSL_LOCAL sw_error_t + isisc_igmp_sg_entry_query(a_uint32_t dev_id, fal_igmp_sg_info_t * info); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _ISISC_IGMP_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_init.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_init.h new file mode 100755 index 000000000..18e8b0752 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_init.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 isisc_init ISISC_INIT + * @{ + */ +#ifndef _ISISC_INIT_H_ +#define _ISISC_INIT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "init/ssdk_init.h" + + + sw_error_t + isisc_init(a_uint32_t dev_id, ssdk_init_cfg *cfg); + + + sw_error_t + isisc_cleanup(a_uint32_t dev_id); + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + isisc_reset(a_uint32_t dev_id); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _ISISC_INIT_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_interface_ctrl.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_interface_ctrl.h new file mode 100755 index 000000000..2c9a9abb7 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_interface_ctrl.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISISC_INTERFACE_CTRL_H_ +#define _ISISC_INTERFACE_CTRL_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_interface_ctrl.h" + + sw_error_t isisc_interface_ctrl_init(a_uint32_t dev_id); + +#ifdef IN_INTERFACECONTROL +#define ISISC_INTERFACE_CTRL_INIT(rv, dev_id) \ + { \ + rv = isisc_interface_ctrl_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISISC_INTERFACE_CTRL_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + isisc_port_3az_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + isisc_port_3az_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + isisc_interface_mac_mode_set(a_uint32_t dev_id, fal_port_t port_id, fal_mac_config_t * config); + + + HSL_LOCAL sw_error_t + isisc_interface_mac_mode_get(a_uint32_t dev_id, fal_port_t port_id, fal_mac_config_t * config); + + HSL_LOCAL sw_error_t + isisc_interface_phy_mode_set(a_uint32_t dev_id, a_uint32_t phy_id, fal_phy_config_t * config); + + HSL_LOCAL sw_error_t + isisc_interface_phy_mode_get(a_uint32_t dev_id, a_uint32_t phy_id, fal_phy_config_t * config); + + HSL_LOCAL sw_error_t + isisc_interface_fx100_ctrl_set(a_uint32_t dev_id, fal_fx100_ctrl_config_t* config); + + HSL_LOCAL sw_error_t + isisc_interface_fx100_ctrl_get(a_uint32_t dev_id, fal_fx100_ctrl_config_t* config); + + HSL_LOCAL sw_error_t + isisc_interface_fx100_status_get(a_uint32_t dev_id, a_uint32_t* status); + + HSL_LOCAL sw_error_t + isisc_interface_mac06_exch_set(a_uint32_t dev_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + isisc_interface_mac06_exch_get(a_uint32_t dev_id, a_bool_t* enable); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISISC_INTERFACE_CTRL_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_ip.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_ip.h new file mode 100755 index 000000000..bf900144a --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_ip.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISISC_IP_H_ +#define _ISISC_IP_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_ip.h" + + sw_error_t isisc_ip_init(a_uint32_t dev_id); + + sw_error_t isisc_ip_reset(a_uint32_t dev_id); + +#ifdef IN_IP +#define ISISC_IP_INIT(rv, dev_id) \ + { \ + rv = isisc_ip_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } + +#define ISISC_IP_RESET(rv, dev_id) \ + { \ + rv = isisc_ip_reset(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISISC_IP_INIT(rv, dev_id) +#define ISISC_IP_RESET(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + isisc_ip_host_add(a_uint32_t dev_id, fal_host_entry_t * host_entry); + + HSL_LOCAL sw_error_t + isisc_ip_intf_entry_add(a_uint32_t dev_id, fal_intf_mac_entry_t * entry); + + HSL_LOCAL sw_error_t + isisc_ip_host_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_host_entry_t * host_entry); + + HSL_LOCAL sw_error_t + isisc_ip_host_get(a_uint32_t dev_id, a_uint32_t get_mode, + fal_host_entry_t * host_entry); + + HSL_LOCAL sw_error_t + isisc_ip_host_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_host_entry_t * host_entry); + + HSL_LOCAL sw_error_t + isisc_ip_host_counter_bind(a_uint32_t dev_id, a_uint32_t entry_id, + a_uint32_t cnt_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + isisc_ip_host_pppoe_bind(a_uint32_t dev_id, a_uint32_t entry_id, + a_uint32_t pppoe_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + isisc_ip_pt_arp_learn_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t flags); + + HSL_LOCAL sw_error_t + isisc_ip_pt_arp_learn_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * flags); + + HSL_LOCAL sw_error_t + isisc_ip_arp_learn_set(a_uint32_t dev_id, fal_arp_learn_mode_t mode); + + HSL_LOCAL sw_error_t + isisc_ip_arp_learn_get(a_uint32_t dev_id, fal_arp_learn_mode_t * mode); + + HSL_LOCAL sw_error_t + isisc_ip_source_guard_set(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t mode); + + HSL_LOCAL sw_error_t + isisc_ip_source_guard_get(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t * mode); + + HSL_LOCAL sw_error_t + isisc_ip_unk_source_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + HSL_LOCAL sw_error_t + isisc_ip_unk_source_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + HSL_LOCAL sw_error_t + isisc_ip_arp_guard_set(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t mode); + + HSL_LOCAL sw_error_t + isisc_ip_arp_guard_get(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t * mode); + + HSL_LOCAL sw_error_t + isisc_arp_unk_source_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + HSL_LOCAL sw_error_t + isisc_arp_unk_source_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + HSL_LOCAL sw_error_t + isisc_ip_route_status_set(a_uint32_t dev_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + isisc_ip_route_status_get(a_uint32_t dev_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + isisc_ip_intf_entry_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_intf_mac_entry_t * entry); + + HSL_LOCAL sw_error_t + isisc_ip_intf_entry_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_intf_mac_entry_t * entry); + + HSL_LOCAL sw_error_t + isisc_ip_age_time_set(a_uint32_t dev_id, a_uint32_t * time); + + HSL_LOCAL sw_error_t + isisc_ip_age_time_get(a_uint32_t dev_id, a_uint32_t * time); + + HSL_LOCAL sw_error_t + isisc_ip_wcmp_entry_set(a_uint32_t dev_id, a_uint32_t wcmp_id, fal_ip_wcmp_t * wcmp); + + HSL_LOCAL sw_error_t + isisc_ip_wcmp_entry_get(a_uint32_t dev_id, a_uint32_t wcmp_id, fal_ip_wcmp_t * wcmp); + + HSL_LOCAL sw_error_t + isisc_ip_wcmp_hash_mode_set(a_uint32_t dev_id, a_uint32_t hash_mode); + + HSL_LOCAL sw_error_t + isisc_ip_wcmp_hash_mode_get(a_uint32_t dev_id, a_uint32_t * hash_mode); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISISC_IP_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_leaky.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_leaky.h new file mode 100755 index 000000000..5325cdd3d --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_leaky.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISISC_LEAKY_H_ +#define _ISISC_LEAKY_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_leaky.h" + + sw_error_t isisc_leaky_init(a_uint32_t dev_id); + +#ifdef IN_LEAKY +#define ISISC_LEAKY_INIT(rv, dev_id) \ + { \ + rv = isisc_leaky_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISISC_LEAKY_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + isisc_uc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode); + + + HSL_LOCAL sw_error_t + isisc_uc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t * ctrl_mode); + + + HSL_LOCAL sw_error_t + isisc_mc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode); + + + HSL_LOCAL sw_error_t + isisc_mc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t * ctrl_mode); + + + HSL_LOCAL sw_error_t + isisc_port_arp_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_port_arp_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isisc_port_uc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_port_uc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isisc_port_mc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_port_mc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISISC_LEAKY_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_led.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_led.h new file mode 100755 index 000000000..304763e0a --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_led.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISISC_LED_H_ +#define _ISISC_LED_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_led.h" + + sw_error_t + isisc_led_init(a_uint32_t dev_id); + +#ifdef IN_LED +#define ISISC_LED_INIT(rv, dev_id) \ + { \ + rv = isisc_led_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISISC_LED_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + isisc_led_ctrl_pattern_set(a_uint32_t dev_id, led_pattern_group_t group, + led_pattern_id_t id, led_ctrl_pattern_t * pattern); + + + HSL_LOCAL sw_error_t + isisc_led_ctrl_pattern_get(a_uint32_t dev_id, led_pattern_group_t group, + led_pattern_id_t id, led_ctrl_pattern_t * pattern); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _ISISC_LED_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_mib.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_mib.h new file mode 100755 index 000000000..3a1677dcd --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_mib.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISISC_MIB_H_ +#define _ISISC_MIB_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_mib.h" + + sw_error_t + isisc_mib_init(a_uint32_t dev_id); + +#ifdef IN_MIB +#define ISISC_MIB_INIT(rv, dev_id) \ + { \ + rv = isisc_mib_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISISC_MIB_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + isisc_get_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info ); + + + HSL_LOCAL sw_error_t + isisc_mib_status_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_mib_status_get(a_uint32_t dev_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + isisc_mib_port_flush_counters(a_uint32_t dev_id, fal_port_t port_id); + + HSL_LOCAL sw_error_t + isisc_mib_cpukeep_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_mib_cpukeep_get(a_uint32_t dev_id, a_bool_t * enable); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _ISISC_MIB_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_mirror.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_mirror.h new file mode 100755 index 000000000..22e28c046 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_mirror.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISISC_MIRROR_H_ +#define _ISISC_MIRROR_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_mirror.h" +#define MIRROR_ANALYZER_NONE 0xf + + sw_error_t isisc_mirr_init(a_uint32_t dev_id); + +#ifdef IN_MIRROR +#define ISISC_MIRR_INIT(rv, dev_id) \ + { \ + rv = isisc_mirr_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISISC_MIRR_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + isisc_mirr_analysis_port_set(a_uint32_t dev_id, fal_port_t port_id); + + + HSL_LOCAL sw_error_t + isisc_mirr_analysis_port_get(a_uint32_t dev_id, fal_port_t * port_id); + + + HSL_LOCAL sw_error_t + isisc_mirr_port_in_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_mirr_port_in_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isisc_mirr_port_eg_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_mirr_port_eg_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISISC_MIRROR_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_misc.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_misc.h new file mode 100755 index 000000000..826105b1e --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_misc.h @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISISC_MISC_H_ +#define _ISISC_MISC_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_misc.h" + + sw_error_t isisc_misc_init(a_uint32_t dev_id); + +#ifdef IN_MISC +#define ISISC_MISC_INIT(rv, dev_id) \ + { \ + rv = isisc_misc_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISISC_MISC_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + isisc_frame_max_size_set(a_uint32_t dev_id, a_uint32_t size); + + + HSL_LOCAL sw_error_t + isisc_frame_max_size_get(a_uint32_t dev_id, a_uint32_t * size); + + + HSL_LOCAL sw_error_t + isisc_port_unk_uc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_port_unk_uc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isisc_port_unk_mc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_port_unk_mc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isisc_port_bc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_port_bc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isisc_cpu_port_status_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_cpu_port_status_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isisc_pppoe_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + + HSL_LOCAL sw_error_t + isisc_pppoe_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + + HSL_LOCAL sw_error_t + isisc_pppoe_status_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_pppoe_status_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isisc_port_dhcp_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_port_dhcp_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isisc_arp_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + + HSL_LOCAL sw_error_t + isisc_arp_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + + HSL_LOCAL sw_error_t + isisc_eapol_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + + HSL_LOCAL sw_error_t + isisc_eapol_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + + HSL_LOCAL sw_error_t + isisc_pppoe_session_table_add(a_uint32_t dev_id, fal_pppoe_session_t * session_tbl); + + + HSL_LOCAL sw_error_t + isisc_pppoe_session_table_del(a_uint32_t dev_id, fal_pppoe_session_t * session_tbl); + + + HSL_LOCAL sw_error_t + isisc_pppoe_session_table_get(a_uint32_t dev_id, fal_pppoe_session_t * session_tbl); + + + HSL_LOCAL sw_error_t + isisc_pppoe_session_id_set(a_uint32_t dev_id, a_uint32_t index, + a_uint32_t id); + + + HSL_LOCAL sw_error_t + isisc_pppoe_session_id_get(a_uint32_t dev_id, a_uint32_t index, + a_uint32_t * id); + + + HSL_LOCAL sw_error_t + isisc_eapol_status_set(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + isisc_eapol_status_get(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + isisc_ripv1_status_set(a_uint32_t dev_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + isisc_ripv1_status_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isisc_port_arp_req_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_port_arp_req_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable); + + + HSL_LOCAL sw_error_t + isisc_port_arp_ack_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_port_arp_ack_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable); + + + HSL_LOCAL sw_error_t + isisc_intr_mask_set(a_uint32_t dev_id, a_uint32_t intr_mask); + + + HSL_LOCAL sw_error_t + isisc_intr_mask_get(a_uint32_t dev_id, a_uint32_t * intr_mask); + + + HSL_LOCAL sw_error_t + isisc_intr_status_get(a_uint32_t dev_id, a_uint32_t * intr_status); + + + HSL_LOCAL sw_error_t + isisc_intr_status_clear(a_uint32_t dev_id, a_uint32_t intr_status); + + + HSL_LOCAL sw_error_t + isisc_intr_port_link_mask_set(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t intr_mask_flag); + + + HSL_LOCAL sw_error_t + isisc_intr_port_link_mask_get(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t * intr_mask_flag); + + + HSL_LOCAL sw_error_t + isisc_intr_port_link_status_get(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t * intr_mask_flag); + + HSL_LOCAL sw_error_t + isisc_intr_mask_mac_linkchg_set(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_intr_mask_mac_linkchg_get(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + isisc_intr_status_mac_linkchg_get(a_uint32_t dev_id, fal_pbmp_t *port_bitmap); + + HSL_LOCAL sw_error_t + isisc_cpu_vid_en_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_cpu_vid_en_get(a_uint32_t dev_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + isisc_rtd_pppoe_en_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_rtd_pppoe_en_get(a_uint32_t dev_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + isisc_intr_status_mac_linkchg_clear(a_uint32_t dev_id); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_nat.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_nat.h new file mode 100755 index 000000000..7943ce9f5 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_nat.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISISC_NAT_H_ +#define _ISISC_NAT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_nat.h" + + sw_error_t isisc_nat_init(a_uint32_t dev_id); + + sw_error_t isisc_nat_reset(a_uint32_t dev_id); + +#ifdef IN_NAT +#define ISISC_NAT_INIT(rv, dev_id) \ + { \ + rv = isisc_nat_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } + +#define ISISC_NAT_RESET(rv, dev_id) \ + { \ + rv = isisc_nat_reset(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISISC_NAT_INIT(rv, dev_id) +#define ISISC_NAT_RESET(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + isisc_napt_add(a_uint32_t dev_id, fal_napt_entry_t * napt_entry); + + HSL_LOCAL sw_error_t + isisc_nat_pub_addr_add(a_uint32_t dev_id, fal_nat_pub_addr_t * entry); + + HSL_LOCAL sw_error_t + isisc_napt_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_napt_entry_t * napt_entry); + + HSL_LOCAL sw_error_t + isisc_nat_prv_base_addr_set(a_uint32_t dev_id, fal_ip4_addr_t addr); + + HSL_LOCAL sw_error_t + isisc_napt_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_napt_entry_t * napt_entry); + + HSL_LOCAL sw_error_t + isisc_nat_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_nat_entry_t * nat_entry); + + HSL_LOCAL sw_error_t + isisc_nat_pub_addr_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_nat_pub_addr_t * entry); + + HSL_LOCAL sw_error_t + isisc_nat_add(a_uint32_t dev_id, fal_nat_entry_t * nat_entry); + + HSL_LOCAL sw_error_t + isisc_nat_get(a_uint32_t dev_id, a_uint32_t get_mode, + fal_nat_entry_t * nat_entry); + + HSL_LOCAL sw_error_t + isisc_nat_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_nat_entry_t * nat_entry); + + HSL_LOCAL sw_error_t + isisc_nat_counter_bind(a_uint32_t dev_id, a_uint32_t entry_id, + a_uint32_t cnt_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + isisc_napt_get(a_uint32_t dev_id, a_uint32_t get_mode, + fal_napt_entry_t * napt_entry); + + HSL_LOCAL sw_error_t + isisc_napt_counter_bind(a_uint32_t dev_id, a_uint32_t entry_id, + a_uint32_t cnt_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + isisc_nat_status_set(a_uint32_t dev_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + isisc_nat_status_get(a_uint32_t dev_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + isisc_nat_hash_mode_set(a_uint32_t dev_id, a_uint32_t mode); + + HSL_LOCAL sw_error_t + isisc_nat_hash_mode_get(a_uint32_t dev_id, a_uint32_t * mode); + + HSL_LOCAL sw_error_t + isisc_napt_status_set(a_uint32_t dev_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + isisc_napt_status_get(a_uint32_t dev_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + isisc_napt_mode_set(a_uint32_t dev_id, fal_napt_mode_t mode); + + HSL_LOCAL sw_error_t + isisc_napt_mode_get(a_uint32_t dev_id, fal_napt_mode_t * mode); + + HSL_LOCAL sw_error_t + isisc_nat_prv_base_addr_get(a_uint32_t dev_id, fal_ip4_addr_t * addr); + + HSL_LOCAL sw_error_t + isisc_nat_prv_base_mask_set(a_uint32_t dev_id, fal_ip4_addr_t addr); + + HSL_LOCAL sw_error_t + isisc_nat_prv_base_mask_get(a_uint32_t dev_id, fal_ip4_addr_t * addr); + + HSL_LOCAL sw_error_t + isisc_nat_pub_addr_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_nat_pub_addr_t * entry); + + HSL_LOCAL sw_error_t + isisc_nat_unk_session_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + HSL_LOCAL sw_error_t + isisc_nat_unk_session_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + HSL_LOCAL sw_error_t + isisc_nat_psr_prv_base_addr_set(a_uint32_t dev_id, fal_ip4_addr_t addr); + + HSL_LOCAL sw_error_t + isisc_nat_psr_prv_base_addr_get(a_uint32_t dev_id, fal_ip4_addr_t * addr); + + HSL_LOCAL sw_error_t + isisc_nat_global_set(a_uint32_t dev_id, a_bool_t enable); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISISC_NAT_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_nat_helper.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_nat_helper.h new file mode 100755 index 000000000..e7ff032f5 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_nat_helper.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISISC_NAT_HELPER_H_ +#define _ISISC_NAT_HELPER_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_nat.h" + + sw_error_t nat_helper_init(a_uint32_t dev_id, a_uint32_t portbmp); + + sw_error_t nat_helper_cleanup(a_uint32_t dev_id); + +#ifdef IN_NAT_HELPER +#define ISISC_NAT_HELPER_INIT(rv, dev_id, portbmp) \ + { \ + rv = nat_helper_init(dev_id, portbmp); \ + SW_RTN_ON_ERROR(rv); \ + } + +#define ISISC_NAT_HELPER_CLEANUP(rv, dev_id) \ + { \ + rv = nat_helper_cleanup(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISISC_NAT_HELPER_INIT(rv, dev_id, portbmp) +#define ISISC_NAT_HELPER_CLEANUP(rv, dev_id) +#endif + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISISC_NAT_HELPER_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_port_ctrl.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_port_ctrl.h new file mode 100755 index 000000000..19fc0875e --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_port_ctrl.h @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISISC_PORT_CTRL_H_ +#define _ISISC_PORT_CTRL_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_port_ctrl.h" + + sw_error_t isisc_port_ctrl_init(a_uint32_t dev_id); + +#ifdef IN_PORTCONTROL +#define ISISC_PORT_CTRL_INIT(rv, dev_id) \ + { \ + rv = isisc_port_ctrl_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISISC_PORT_CTRL_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + isisc_port_duplex_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t duplex); + + + HSL_LOCAL sw_error_t + isisc_port_duplex_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t * pduplex); + + + HSL_LOCAL sw_error_t + isisc_port_speed_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t speed); + + + HSL_LOCAL sw_error_t + isisc_port_speed_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t * pspeed); + + + HSL_LOCAL sw_error_t + isisc_port_autoneg_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status); + + + HSL_LOCAL sw_error_t + isisc_port_autoneg_enable(a_uint32_t dev_id, fal_port_t port_id); + + + HSL_LOCAL sw_error_t + isisc_port_autoneg_restart(a_uint32_t dev_id, fal_port_t port_id); + + + HSL_LOCAL sw_error_t + isisc_port_autoneg_adv_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t autoadv); + + + HSL_LOCAL sw_error_t + isisc_port_autoneg_adv_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * autoadv); + + + HSL_LOCAL sw_error_t + isisc_port_flowctrl_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_port_flowctrl_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isisc_port_flowctrl_forcemode_set(a_uint32_t dev_id, + fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_port_flowctrl_forcemode_get(a_uint32_t dev_id, + fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isisc_port_powersave_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_port_powersave_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable); + + + HSL_LOCAL sw_error_t + isisc_port_hibernate_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_port_hibernate_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable); + + + HSL_LOCAL sw_error_t + isisc_port_cdt(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t mdi_pair, + fal_cable_status_t *cable_status, a_uint32_t *cable_len); + + + HSL_LOCAL sw_error_t + isisc_port_rxhdr_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t mode); + + + HSL_LOCAL sw_error_t + isisc_port_rxhdr_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t * mode); + + + HSL_LOCAL sw_error_t + isisc_port_txhdr_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t mode); + + + HSL_LOCAL sw_error_t + isisc_port_txhdr_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t * mode); + + + HSL_LOCAL sw_error_t + isisc_header_type_set(a_uint32_t dev_id, a_bool_t enable, a_uint32_t type); + + + HSL_LOCAL sw_error_t + isisc_header_type_get(a_uint32_t dev_id, a_bool_t * enable, a_uint32_t * type); + + + HSL_LOCAL sw_error_t + isisc_port_txmac_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_port_txmac_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isisc_port_rxmac_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_port_rxmac_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isisc_port_txfc_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_port_txfc_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isisc_port_rxfc_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_port_rxfc_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isisc_port_bp_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_port_bp_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isisc_port_link_forcemode_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_port_link_forcemode_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isisc_port_link_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * status); + + HSL_LOCAL sw_error_t + isisc_ports_link_status_get(a_uint32_t dev_id, a_uint32_t * status); + + HSL_LOCAL sw_error_t + isisc_port_mac_loopback_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_port_mac_loopback_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + isisc_port_8023az_set (a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + isisc_port_8023az_get (a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISISC_PORT_CTRL_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_portvlan.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_portvlan.h new file mode 100755 index 000000000..248df0b30 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_portvlan.h @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISISC_PORTVLAN_H_ +#define _ISISC_PORTVLAN_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_portvlan.h" + + sw_error_t isisc_portvlan_init(a_uint32_t dev_id); + +#ifdef IN_PORTVLAN +#define ISISC_PORTVLAN_INIT(rv, dev_id) \ + { \ + rv = isisc_portvlan_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISISC_PORTVLAN_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + isisc_port_1qmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t port_1qmode); + + + HSL_LOCAL sw_error_t + isisc_port_1qmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t * pport_1qmode); + + + HSL_LOCAL sw_error_t + isisc_port_egvlanmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t port_egvlanmode); + + + HSL_LOCAL sw_error_t + isisc_port_egvlanmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t * pport_egvlanmode); + + + HSL_LOCAL sw_error_t + isisc_portvlan_member_add(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id); + + + HSL_LOCAL sw_error_t + isisc_portvlan_member_del(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id); + + + HSL_LOCAL sw_error_t + isisc_portvlan_member_update(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t mem_port_map); + + + HSL_LOCAL sw_error_t + isisc_portvlan_member_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t * mem_port_map); + + + HSL_LOCAL sw_error_t + isisc_port_force_default_vid_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_port_force_default_vid_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isisc_port_force_portvlan_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_port_force_portvlan_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isisc_nestvlan_tpid_set(a_uint32_t dev_id, a_uint32_t tpid); + + + HSL_LOCAL sw_error_t + isisc_nestvlan_tpid_get(a_uint32_t dev_id, a_uint32_t * tpid); + + + HSL_LOCAL sw_error_t + isisc_port_invlan_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_invlan_mode_t mode); + + + HSL_LOCAL sw_error_t + isisc_port_invlan_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_invlan_mode_t * mode); + + + HSL_LOCAL sw_error_t + isisc_port_tls_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_port_tls_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isisc_port_pri_propagation_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_port_pri_propagation_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isisc_port_default_svid_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vid); + + + HSL_LOCAL sw_error_t + isisc_port_default_svid_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vid); + + HSL_LOCAL sw_error_t + isisc_port_default_cvid_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vid); + + + HSL_LOCAL sw_error_t + isisc_port_default_cvid_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vid); + + + HSL_LOCAL sw_error_t + isisc_port_vlan_propagation_set(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_propagation_mode_t mode); + + + HSL_LOCAL sw_error_t + isisc_port_vlan_propagation_get(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_propagation_mode_t * mode); + + + HSL_LOCAL sw_error_t + isisc_port_vlan_trans_add(a_uint32_t dev_id, fal_port_t port_id, fal_vlan_trans_entry_t *entry); + + + HSL_LOCAL sw_error_t + isisc_port_vlan_trans_del(a_uint32_t dev_id, fal_port_t port_id, fal_vlan_trans_entry_t *entry); + + + HSL_LOCAL sw_error_t + isisc_port_vlan_trans_get(a_uint32_t dev_id, fal_port_t port_id, fal_vlan_trans_entry_t *entry); + + + HSL_LOCAL sw_error_t + isisc_qinq_mode_set(a_uint32_t dev_id, fal_qinq_mode_t mode); + + + HSL_LOCAL sw_error_t + isisc_qinq_mode_get(a_uint32_t dev_id, fal_qinq_mode_t * mode); + + + HSL_LOCAL sw_error_t + isisc_port_qinq_role_set(a_uint32_t dev_id, fal_port_t port_id, fal_qinq_port_role_t role); + + + HSL_LOCAL sw_error_t + isisc_port_qinq_role_get(a_uint32_t dev_id, fal_port_t port_id, fal_qinq_port_role_t * role); + + + HSL_LOCAL sw_error_t + isisc_port_vlan_trans_iterate(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * iterator, fal_vlan_trans_entry_t * entry); + + + HSL_LOCAL sw_error_t + isisc_port_mac_vlan_xlt_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_port_mac_vlan_xlt_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + HSL_LOCAL sw_error_t + isisc_netisolate_set(a_uint32_t dev_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + isisc_netisolate_get(a_uint32_t dev_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + isisc_eg_trans_filter_bypass_en_set(a_uint32_t dev_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + isisc_eg_trans_filter_bypass_en_get(a_uint32_t dev_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + isisc_port_route_defv_set(a_uint32_t dev_id, fal_port_t port_id); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISISC_PORTVLAN_H */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_qos.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_qos.h new file mode 100755 index 000000000..e4d932361 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_qos.h @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISISC_QOS_H_ +#define _ISISC_QOS_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_qos.h" + + sw_error_t isisc_qos_init(a_uint32_t dev_id); + +#ifdef IN_QOS +#define ISISC_QOS_INIT(rv, dev_id) \ + { \ + rv = isisc_qos_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISISC_QOS_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + isisc_qos_queue_tx_buf_status_set(a_uint32_t dev_id, + fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_qos_queue_tx_buf_status_get(a_uint32_t dev_id, + fal_port_t port_id, + a_bool_t * enable); + + HSL_LOCAL sw_error_t + isisc_qos_port_tx_buf_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_qos_port_tx_buf_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + HSL_LOCAL sw_error_t + isisc_qos_port_red_en_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + HSL_LOCAL sw_error_t + isisc_qos_port_red_en_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t* enable); + + + HSL_LOCAL sw_error_t + isisc_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); + + + HSL_LOCAL sw_error_t + isisc_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); + + + HSL_LOCAL sw_error_t + isisc_qos_port_tx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number); + + + HSL_LOCAL sw_error_t + isisc_qos_port_tx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number); + + + HSL_LOCAL sw_error_t + isisc_qos_port_rx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number); + + + HSL_LOCAL sw_error_t + isisc_qos_port_rx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number); + + + HSL_LOCAL sw_error_t + isisc_qos_port_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_qos_port_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + isisc_qos_port_mode_pri_set(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_uint32_t pri); + + + HSL_LOCAL sw_error_t + isisc_qos_port_mode_pri_get(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_uint32_t * pri); + + + HSL_LOCAL sw_error_t + isisc_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[]); + + + HSL_LOCAL sw_error_t + isisc_qos_port_sch_mode_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_sch_mode_t * mode, a_uint32_t weight[]); + + HSL_LOCAL sw_error_t + isisc_qos_port_default_spri_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t spri); + + + HSL_LOCAL sw_error_t + isisc_qos_port_default_spri_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * spri); + + + HSL_LOCAL sw_error_t + isisc_qos_port_default_cpri_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t cpri); + + + HSL_LOCAL sw_error_t + isisc_qos_port_default_cpri_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * cpri); + + sw_error_t + isisc_qos_port_force_spri_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + sw_error_t + isisc_qos_port_force_spri_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t* enable); + + sw_error_t + isisc_qos_port_force_cpri_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + sw_error_t + isisc_qos_port_force_cpri_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t* enable); + + HSL_LOCAL sw_error_t + isisc_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); + + + HSL_LOCAL sw_error_t + isisc_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); + + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISISC_QOS_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_rate.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_rate.h new file mode 100755 index 000000000..4b4f48a03 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_rate.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISISC_RATE_H_ +#define _ISISC_RATE_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_rate.h" + + sw_error_t isisc_rate_init(a_uint32_t dev_id); + +#ifdef IN_RATE +#define ISISC_RATE_INIT(rv, dev_id) \ + { \ + rv = isisc_rate_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISISC_RATE_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + isisc_rate_port_policer_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_policer_t * policer); + + HSL_LOCAL sw_error_t + isisc_rate_port_policer_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_policer_t * policer); + + HSL_LOCAL sw_error_t + isisc_rate_port_shaper_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable, + fal_egress_shaper_t * shaper); + + HSL_LOCAL sw_error_t + isisc_rate_port_shaper_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable, + fal_egress_shaper_t * shaper); + + HSL_LOCAL sw_error_t + isisc_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); + + HSL_LOCAL sw_error_t + isisc_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); + + HSL_LOCAL sw_error_t + isisc_rate_acl_policer_set(a_uint32_t dev_id, a_uint32_t policer_id, + fal_acl_policer_t * policer); + + HSL_LOCAL sw_error_t + isisc_rate_acl_policer_get(a_uint32_t dev_id, a_uint32_t policer_id, + fal_acl_policer_t * policer); + + HSL_LOCAL sw_error_t + isisc_rate_port_add_rate_byte_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t number); + + HSL_LOCAL sw_error_t + isisc_rate_port_add_rate_byte_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t *number); + + HSL_LOCAL sw_error_t + isisc_rate_port_gol_flow_en_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + HSL_LOCAL sw_error_t + isisc_rate_port_gol_flow_en_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t* enable); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISISC_RATE_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_reg.h new file mode 100755 index 000000000..1eb3d1b5f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_reg.h @@ -0,0 +1,5478 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISISC_REG_H_ +#define _ISISC_REG_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define S16E_DEVICE_ID 0x11 +#define S17C_DEVICE_ID 0x13 /* TBD */ +#define S17_REVISION_A 0x01 + +#define MAX_ENTRY_LEN 128 + +#define HSL_RW 1 +#define HSL_RO 0 + + + /* ISIS Mask Control Register */ +#define MASK_CTL +#define MASK_CTL_ID 0 +#define MASK_CTL_OFFSET 0x0000 +#define MASK_CTL_E_LENGTH 4 +#define MASK_CTL_E_OFFSET 0 +#define MASK_CTL_NR_E 1 + +#define SOFT_RST +#define MASK_CTL_SOFT_RST_BOFFSET 31 +#define MASK_CTL_SOFT_RST_BLEN 1 +#define MASK_CTL_SOFT_RST_FLAG HSL_RW + +#define LOAD_EEPROM +#define MASK_CTL_LOAD_EEPROM_BOFFSET 16 +#define MASK_CTL_LOAD_EEPROM_BLEN 1 +#define MASK_CTL_LOAD_EEPROM_FLAG HSL_RW + +#define DEVICE_ID +#define MASK_CTL_DEVICE_ID_BOFFSET 8 +#define MASK_CTL_DEVICE_ID_BLEN 8 +#define MASK_CTL_DEVICE_ID_FLAG HSL_RO + +#define REV_ID +#define MASK_CTL_REV_ID_BOFFSET 0 +#define MASK_CTL_REV_ID_BLEN 8 +#define MASK_CTL_REV_ID_FLAG HSL_RO + + + + + /* Port0 Pad Control Register */ +#define PORT0_PAD_CTRL +#define PORT0_PAD_CTRL_ID 0 +#define PORT0_PAD_CTRL_OFFSET 0x0004 +#define PORT0_PAD_CTRL_E_LENGTH 4 +#define PORT0_PAD_CTRL_E_OFFSET 0 +#define PORT0_PAD_CTRL_NR_E 1 + +#define RMII_MAC06_EXCH_EN +#define PORT0_PAD_CTRL_RMII_MAC06_EXCH_EN_BOFFSET 31 +#define PORT0_PAD_CTRL_RMII_MAC06_EXCH_EN_BLEN 1 +#define PORT0_PAD_CTRL_RMII_MAC06_EXCH_EN_FLAG HSL_RW + +#define RMII_MASTER_EN +#define PORT0_PAD_CTRL_RMII_MASTER_EN_BOFFSET 30 +#define PORT0_PAD_CTRL_RMII_MASTER_EN_BLEN 1 +#define PORT0_PAD_CTRL_RMII_MASTER_EN_FLAG HSL_RW + +#define RMII_SLAVE_EN +#define PORT0_PAD_CTRL_RMII_SLAVE_EN_BOFFSET 29 +#define PORT0_PAD_CTRL_RMII_SLAVE_EN_BLEN 1 +#define PORT0_PAD_CTRL_RMII_SLAVE_EN_FLAG HSL_RW + +#define RMII_SEL +#define PORT0_PAD_CTRL_RMII_SEL_BOFFSET 28 +#define PORT0_PAD_CTRL_RMII_SEL_BLEN 1 +#define PORT0_PAD_CTRL_RMII_SEL_FLAG HSL_RW + +#define RMII_PIPE_RXCLK_SEL +#define PORT0_PAD_CTRL_RMII_PIPE_RXCLK_SEL_BOFFSET 27 +#define PORT0_PAD_CTRL_RMII_PIPE_RXCLK_SEL_BLEN 1 +#define PORT0_PAD_CTRL_RMII_PIPE_RXCLK_SEL_FLAG HSL_RW + +#define MAC0_RGMII_EN +#define PORT0_PAD_CTRL_MAC0_RGMII_EN_BOFFSET 26 +#define PORT0_PAD_CTRL_MAC0_RGMII_EN_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_RGMII_EN_FLAG HSL_RW + +#define MAC0_RGMII_TXCLK_DELAY_EN +#define PORT0_PAD_CTRL_MAC0_RGMII_TXCLK_DELAY_EN_BOFFSET 25 +#define PORT0_PAD_CTRL_MAC0_RGMII_TXCLK_DELAY_EN_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_RGMII_TXCLK_DELAY_EN_FLAG HSL_RW + +#define MAC0_RGMII_RXCLK_DELAY_EN +#define PORT0_PAD_CTRL_MAC0_RGMII_RXCLK_DELAY_EN_BOFFSET 24 +#define PORT0_PAD_CTRL_MAC0_RGMII_RXCLK_DELAY_EN_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_RGMII_RXCLK_DELAY_EN_FLAG HSL_RW + +#define MAC0_RGMII_TXCLK_DELAY_SEL +#define PORT0_PAD_CTRL_MAC0_RGMII_TXCLK_DELAY_SEL_BOFFSET 22 +#define PORT0_PAD_CTRL_MAC0_RGMII_TXCLK_DELAY_SEL_BLEN 2 +#define PORT0_PAD_CTRL_MAC0_RGMII_TXCLK_DELAY_SEL_FLAG HSL_RW + +#define MAC0_RGMII_RXCLK_DELAY_SEL +#define PORT0_PAD_CTRL_MAC0_RGMII_RXCLK_DELAY_SEL_BOFFSET 20 +#define PORT0_PAD_CTRL_MAC0_RGMII_RXCLK_DELAY_SEL_BLEN 2 +#define PORT0_PAD_CTRL_MAC0_RGMII_RXCLK_DELAY_SEL_FLAG HSL_RW + +#define SGMII_CLK125M_RX_SEL +#define PORT0_PAD_CTRL_SGMII_CLK125M_RX_SEL_BOFFSET 19 +#define PORT0_PAD_CTRL_SGMII_CLK125M_RX_SEL_BLEN 1 +#define PORT0_PAD_CTRL_SGMII_CLK125M_RX_SEL_FLAG HSL_RW + +#define SGMII_CLK125M_TX_SEL +#define PORT0_PAD_CTRL_SGMII_CLK125M_TX_SEL_BOFFSET 18 +#define PORT0_PAD_CTRL_SGMII_CLK125M_TX_SEL_BLEN 1 +#define PORT0_PAD_CTRL_SGMII_CLK125M_TX_SEL_FLAG HSL_RW + +#define SGMII_FX100_EN +#define PORT0_PAD_CTRL_SGMII_FX100_EN_BOFFSET 17 +#define PORT0_PAD_CTRL_SGMII_FX100_EN_BLEN 1 +#define PORT0_PAD_CTRL_SGMII_FX100_EN_FLAG HSL_RW + +#define SGMII_PRBS_BERT_EN +#define PORT0_PAD_CTRL_SGMII_PRBS_BERT_EN_BOFFSET 16 +#define PORT0_PAD_CTRL_SGMII_PRBS_BERT_EN_BLEN 1 +#define PORT0_PAD_CTRL_SGMII_PRBS_BERT_EN_FLAG HSL_RW + +#define SGMII_REM_PHY_LPBK_EN +#define PORT0_PAD_CTRL_SGMII_REM_PHY_LPBK_EN_BOFFSET 15 +#define PORT0_PAD_CTRL_SGMII_REM_PHY_LPBK_EN_BLEN 1 +#define PORT0_PAD_CTRL_SGMII_REM_PHY_LPBK_EN_FLAG HSL_RW + +#define MAC0_PHY_GMII_EN +#define PORT0_PAD_CTRL_MAC0_PHY_GMII_EN_BOFFSET 14 +#define PORT0_PAD_CTRL_MAC0_PHY_GMII_EN_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_PHY_GMII_EN_FLAG HSL_RW + +#define MAC0_PHY_GMII_TXCLK_SEL +#define PORT0_PAD_CTRL_MAC0_PHY_GMII_TXCLK_SEL_BOFFSET 13 +#define PORT0_PAD_CTRL_MAC0_PHY_GMII_TXCLK_SEL_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_PHY_GMII_TXCLK_SEL_FLAG HSL_RW + +#define MAC0_PHY_GMII_RXCLK_SEL +#define PORT0_PAD_CTRL_MAC0_PHY_GMII_RXCLK_SEL_BOFFSET 12 +#define PORT0_PAD_CTRL_MAC0_PHY_GMII_RXCLK_SEL_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_PHY_GMII_RXCLK_SEL_FLAG HSL_RW + +#define MAC0_PHY_MII_PIPE_RXCLK_SEL +#define PORT0_PAD_CTRL_MAC0_PHY_MII_PIPE_RXCLK_SEL_BOFFSET 11 +#define PORT0_PAD_CTRL_MAC0_PHY_MII_PIPE_RXCLK_SEL_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_PHY_MII_PIPE_RXCLK_SEL_FLAG HSL_RW + +#define MAC0_PHY_MII_EN +#define PORT0_PAD_CTRL_MAC0_PHY_MII_EN_BOFFSET 10 +#define PORT0_PAD_CTRL_MAC0_PHY_MII_EN_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_PHY_MII_EN_FLAG HSL_RW + +#define MAC0_PHY_MII_TXCLK_SEL +#define PORT0_PAD_CTRL_MAC0_PHY_MII_TXCLK_SEL_BOFFSET 9 +#define PORT0_PAD_CTRL_MAC0_PHY_MII_TXCLK_SEL_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_PHY_MII_TXCLK_SEL_FLAG HSL_RW + +#define MAC0_PHY_MII_RXCLK_SEL +#define PORT0_PAD_CTRL_MAC0_PHY_MII_RXCLK_SEL_BOFFSET 8 +#define PORT0_PAD_CTRL_MAC0_PHY_MII_RXCLK_SEL_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_PHY_MII_RXCLK_SEL_FLAG HSL_RW + +#define MAC0_SGMII_EN +#define PORT0_PAD_CTRL_MAC0_SGMII_EN_BOFFSET 7 +#define PORT0_PAD_CTRL_MAC0_SGMII_EN_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_SGMII_EN_FLAG HSL_RW + +#define MAC0_MAC_GMII_EN +#define PORT0_PAD_CTRL_MAC0_MAC_GMII_EN_BOFFSET 6 +#define PORT0_PAD_CTRL_MAC0_MAC_GMII_EN_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_MAC_GMII_EN_FLAG HSL_RW + +#define MAC0_MAC_GMII_TXCLK_SEL +#define PORT0_PAD_CTRL_MAC0_MAC_GMII_TXCLK_SEL_BOFFSET 5 +#define PORT0_PAD_CTRL_MAC0_MAC_GMII_TXCLK_SEL_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_MAC_GMII_TXCLK_SEL_FLAG HSL_RW + +#define MAC0_MAC_GMII_RXCLK_SEL +#define PORT0_PAD_CTRL_MAC0_MAC_GMII_RXCLK_SEL_BOFFSET 4 +#define PORT0_PAD_CTRL_MAC0_MAC_GMII_RXCLK_SEL_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_MAC_GMII_RXCLK_SEL_FLAG HSL_RW + +#define MAC0_MAC_SGMII_FORCE_SPEED +#define PORT0_PAD_CTRL_MAC0_MAC_SGMII_FORCE_SPEED_BOFFSET 3 +#define PORT0_PAD_CTRL_MAC0_MAC_SGMII_FORCE_SPEED_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_MAC_SGMII_FORCE_SPEED_FLAG HSL_RW + +#define MAC0_MAC_MII_EN +#define PORT0_PAD_CTRL_MAC0_MAC_MII_EN_BOFFSET 2 +#define PORT0_PAD_CTRL_MAC0_MAC_MII_EN_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_MAC_MII_EN_FLAG HSL_RW + +#define MAC0_MAC_MII_TXCLK_SEL +#define PORT0_PAD_CTRL_MAC0_MAC_MII_TXCLK_SEL_BOFFSET 1 +#define PORT0_PAD_CTRL_MAC0_MAC_MII_TXCLK_SEL_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_MAC_MII_TXCLK_SEL_FLAG HSL_RW + +#define MAC0_MAC_MII_RXCLK_SEL +#define PORT0_PAD_CTRL_MAC0_MAC_MII_RXCLK_SEL_BOFFSET 0 +#define PORT0_PAD_CTRL_MAC0_MAC_MII_RXCLK_SEL_BLEN 1 +#define PORT0_PAD_CTRL_MAC0_MAC_MII_RXCLK_SEL_FLAG HSL_RW + + + + + /* Port5 Pad Control Register */ +#define PORT5_PAD_CTRL +#define PORT5_PAD_CTRL_ID 0 +#define PORT5_PAD_CTRL_OFFSET 0x0008 +#define PORT5_PAD_CTRL_E_LENGTH 4 +#define PORT5_PAD_CTRL_E_OFFSET 0 +#define PORT5_PAD_CTRL_NR_E 1 + +#define MAC5_RGMII_EN +#define PORT5_PAD_CTRL_MAC5_RGMII_EN_BOFFSET 26 +#define PORT5_PAD_CTRL_MAC5_RGMII_EN_BLEN 1 +#define PORT5_PAD_CTRL_MAC5_RGMII_EN_FLAG HSL_RW + +#define MAC5_RGMII_TXCLK_DELAY_EN +#define PORT5_PAD_CTRL_MAC5_RGMII_TXCLK_DELAY_EN_BOFFSET 25 +#define PORT5_PAD_CTRL_MAC5_RGMII_TXCLK_DELAY_EN_BLEN 1 +#define PORT5_PAD_CTRL_MAC5_RGMII_TXCLK_DELAY_EN_FLAG HSL_RW + +#define MAC5_RGMII_RXCLK_DELAY_EN +#define PORT5_PAD_CTRL_MAC5_RGMII_RXCLK_DELAY_EN_BOFFSET 24 +#define PORT5_PAD_CTRL_MAC5_RGMII_RXCLK_DELAY_EN_BLEN 1 +#define PORT5_PAD_CTRL_MAC5_RGMII_RXCLK_DELAY_EN_FLAG HSL_RW + +#define MAC5_RGMII_TXCLK_DELAY_SEL +#define PORT5_PAD_CTRL_MAC5_RGMII_TXCLK_DELAY_SEL_BOFFSET 22 +#define PORT5_PAD_CTRL_MAC5_RGMII_TXCLK_DELAY_SEL_BLEN 2 +#define PORT5_PAD_CTRL_MAC5_RGMII_TXCLK_DELAY_SEL_FLAG HSL_RW + +#define MAC5_RGMII_RXCLK_DELAY_SEL +#define PORT5_PAD_CTRL_MAC5_RGMII_RXCLK_DELAY_SEL_BOFFSET 20 +#define PORT5_PAD_CTRL_MAC5_RGMII_RXCLK_DELAY_SEL_BLEN 2 +#define PORT5_PAD_CTRL_MAC5_RGMII_RXCLK_DELAY_SEL_FLAG HSL_RW + +#define MAC5_PHY_MII_PIPE_RXCLK_SEL +#define PORT5_PAD_CTRL_MAC5_PHY_MII_PIPE_RXCLK_SEL_BOFFSET 11 +#define PORT5_PAD_CTRL_MAC5_PHY_MII_PIPE_RXCLK_SEL_BLEN 1 +#define PORT5_PAD_CTRL_MAC5_PHY_MII_PIPE_RXCLK_SEL_FLAG HSL_RW + +#define MAC5_PHY_MII_EN +#define PORT5_PAD_CTRL_MAC5_PHY_MII_EN_BOFFSET 10 +#define PORT5_PAD_CTRL_MAC5_PHY_MII_EN_BLEN 1 +#define PORT5_PAD_CTRL_MAC5_PHY_MII_EN_FLAG HSL_RW + +#define MAC5_PHY_MII_TXCLK_SEL +#define PORT5_PAD_CTRL_MAC5_PHY_MII_TXCLK_SEL_BOFFSET 9 +#define PORT5_PAD_CTRL_MAC5_PHY_MII_TXCLK_SEL_BLEN 1 +#define PORT5_PAD_CTRL_MAC5_PHY_MII_TXCLK_SEL_FLAG HSL_RW + +#define MAC5_PHY_MII_RXCLK_SEL +#define PORT5_PAD_CTRL_MAC5_PHY_MII_RXCLK_SEL_BOFFSET 8 +#define PORT5_PAD_CTRL_MAC5_PHY_MII_RXCLK_SEL_BLEN 1 +#define PORT5_PAD_CTRL_MAC5_PHY_MII_RXCLK_SEL_FLAG HSL_RW + +#define MAC5_MAC_MII_EN +#define PORT5_PAD_CTRL_MAC5_MAC_MII_EN_BOFFSET 2 +#define PORT5_PAD_CTRL_MAC5_MAC_MII_EN_BLEN 1 +#define PORT5_PAD_CTRL_MAC5_MAC_MII_EN_FLAG HSL_RW + +#define MAC5_MAC_MII_TXCLK_SEL +#define PORT5_PAD_CTRL_MAC0_MAC_MII_TXCLK_SEL_BOFFSET 1 +#define PORT5_PAD_CTRL_MAC0_MAC_MII_TXCLK_SEL_BLEN 1 +#define PORT5_PAD_CTRL_MAC0_MAC_MII_TXCLK_SEL_FLAG HSL_RW + +#define MAC5_MAC_MII_RXCLK_SEL +#define PORT5_PAD_CTRL_MAC5_MAC_MII_RXCLK_SEL_BOFFSET 0 +#define PORT5_PAD_CTRL_MAC5_MAC_MII_RXCLK_SEL_BLEN 1 +#define PORT5_PAD_CTRL_MAC5_MAC_MII_RXCLK_SEL_FLAG HSL_RW + + + + + /* Port6 Pad Control Register */ +#define PORT6_PAD_CTRL +#define PORT6_PAD_CTRL_ID 0 +#define PORT6_PAD_CTRL_OFFSET 0x000c +#define PORT6_PAD_CTRL_E_LENGTH 4 +#define PORT6_PAD_CTRL_E_OFFSET 0 +#define PORT6_PAD_CTRL_NR_E 1 + +#define MAC6_RGMII_EN +#define PORT6_PAD_CTRL_MAC6_RGMII_EN_BOFFSET 26 +#define PORT6_PAD_CTRL_MAC6_RGMII_EN_BLEN 1 +#define PORT6_PAD_CTRL_MAC6_RGMII_EN_FLAG HSL_RW + +#define MAC6_RGMII_TXCLK_DELAY_EN +#define PORT6_PAD_CTRL_MAC6_RGMII_TXCLK_DELAY_EN_BOFFSET 25 +#define PORT6_PAD_CTRL_MAC6_RGMII_TXCLK_DELAY_EN_BLEN 1 +#define PORT6_PAD_CTRL_MAC6_RGMII_TXCLK_DELAY_EN_FLAG HSL_RW + +#define MAC6_RGMII_RXCLK_DELAY_EN +#define PORT6_PAD_CTRL_MAC6_RGMII_RXCLK_DELAY_EN_BOFFSET 24 +#define PORT6_PAD_CTRL_MAC6_RGMII_RXCLK_DELAY_EN_BLEN 1 +#define PORT6_PAD_CTRL_MAC6_RGMII_RXCLK_DELAY_EN_FLAG HSL_RW + +#define MAC6_RGMII_TXCLK_DELAY_SEL +#define PORT6_PAD_CTRL_MAC6_RGMII_TXCLK_DELAY_SEL_BOFFSET 22 +#define PORT6_PAD_CTRL_MAC6_RGMII_TXCLK_DELAY_SEL_BLEN 2 +#define PORT6_PAD_CTRL_MAC6_RGMII_TXCLK_DELAY_SEL_FLAG HSL_RW + +#define MAC6_RGMII_RXCLK_DELAY_SEL +#define PORT6_PAD_CTRL_MAC6_RGMII_RXCLK_DELAY_SEL_BOFFSET 20 +#define PORT6_PAD_CTRL_MAC6_RGMII_RXCLK_DELAY_SEL_BLEN 2 +#define PORT6_PAD_CTRL_MAC6_RGMII_RXCLK_DELAY_SEL_FLAG HSL_RW + +#define PHY4_RGMII_EN +#define PORT6_PAD_CTRL_PHY4_RGMII_EN_BOFFSET 17 +#define PORT6_PAD_CTRL_PHY4_RGMII_EN_BLEN 1 +#define PORT6_PAD_CTRL_PHY4_RGMII_EN_FLAG HSL_RW + +#define MAC6_PHY_GMII_EN +#define PORT6_PAD_CTRL_MAC6_PHY_GMII_EN_BOFFSET 14 +#define PORT6_PAD_CTRL_MAC6_PHY_GMII_EN_BLEN 1 +#define PORT6_PAD_CTRL_MAC6_PHY_GMII_EN_FLAG HSL_RW + +#define MAC6_PHY_GMII_TXCLK_SEL +#define PORT6_PAD_CTRL_MAC6_PHY_GMII_TXCLK_SEL_BOFFSET 13 +#define PORT6_PAD_CTRL_MAC6_PHY_GMII_TXCLK_SEL_BLEN 1 +#define PORT6_PAD_CTRL_MAC6_PHY_GMII_TXCLK_SEL_FLAG HSL_RW + +#define MAC6_PHY_GMII_RXCLK_SEL +#define PORT6_PAD_CTRL_MAC6_PHY_GMII_RXCLK_SEL_BOFFSET 12 +#define PORT6_PAD_CTRL_MAC6_PHY_GMII_RXCLK_SEL_BLEN 1 +#define PORT6_PAD_CTRL_MAC6_PHY_GMII_RXCLK_SEL_FLAG HSL_RW + +#define MAC6_PHY_MII_PIPE_RXCLK_SEL +#define PORT6_PAD_CTRL_MAC6_PHY_MII_PIPE_RXCLK_SEL_BOFFSET 11 +#define PORT6_PAD_CTRL_MAC6_PHY_MII_PIPE_RXCLK_SEL_BLEN 1 +#define PORT6_PAD_CTRL_MAC6_PHY_MII_PIPE_RXCLK_SEL_FLAG HSL_RW + +#define MAC6_PHY_MII_EN +#define PORT6_PAD_CTRL_MAC6_PHY_MII_EN_BOFFSET 10 +#define PORT6_PAD_CTRL_MAC6_PHY_MII_EN_BLEN 1 +#define PORT6_PAD_CTRL_MAC6_PHY_MII_EN_FLAG HSL_RW + +#define MAC6_PHY_MII_TXCLK_SEL +#define PORT6_PAD_CTRL_MAC6_PHY_MII_TXCLK_SEL_BOFFSET 9 +#define PORT6_PAD_CTRL_MAC6_PHY_MII_TXCLK_SEL_BLEN 1 +#define PORT6_PAD_CTRL_MAC6_PHY_MII_TXCLK_SEL_FLAG HSL_RW + +#define MAC6_PHY_MII_RXCLK_SEL +#define PORT6_PAD_CTRL_MAC6_PHY_MII_RXCLK_SEL_BOFFSET 8 +#define PORT6_PAD_CTRL_MAC6_PHY_MII_RXCLK_SEL_BLEN 1 +#define PORT6_PAD_CTRL_MAC6_PHY_MII_RXCLK_SEL_FLAG HSL_RW + +#define MAC6_SGMII_EN +#define PORT6_PAD_CTRL_MAC6_SGMII_EN_BOFFSET 7 +#define PORT6_PAD_CTRL_MAC6_SGMII_EN_BLEN 1 +#define PORT6_PAD_CTRL_MAC6_SGMII_EN_FLAG HSL_RW + +#define MAC6_MAC_GMII_EN +#define PORT6_PAD_CTRL_MAC6_MAC_GMII_EN_BOFFSET 6 +#define PORT6_PAD_CTRL_MAC6_MAC_GMII_EN_BLEN 1 +#define PORT6_PAD_CTRL_MAC6_MAC_GMII_EN_FLAG HSL_RW + +#define MAC6_MAC_GMII_TXCLK_SEL +#define PORT6_PAD_CTRL_MAC6_MAC_GMII_TXCLK_SEL_BOFFSET 5 +#define PORT6_PAD_CTRL_MAC6_MAC_GMII_TXCLK_SEL_BLEN 1 +#define PORT6_PAD_CTRL_MAC6_MAC_GMII_TXCLK_SEL_FLAG HSL_RW + +#define MAC6_MAC_GMII_RXCLK_SEL +#define PORT6_PAD_CTRL_MAC6_MAC_GMII_RXCLK_SEL_BOFFSET 4 +#define PORT6_PAD_CTRL_MAC6_MAC_GMII_RXCLK_SEL_BLEN 1 +#define PORT6_PAD_CTRL_MAC6_MAC_GMII_RXCLK_SEL_FLAG HSL_RW + +#define MAC6_MAC_MII_EN +#define PORT6_PAD_CTRL_MAC6_MAC_MII_EN_BOFFSET 2 +#define PORT6_PAD_CTRL_MAC6_MAC_MII_EN_BLEN 1 +#define PORT6_PAD_CTRL_MAC6_MAC_MII_EN_FLAG HSL_RW + +#define MAC6_MAC_MII_TXCLK_SEL +#define PORT6_PAD_CTRL_MAC6_MAC_MII_TXCLK_SEL_BOFFSET 1 +#define PORT6_PAD_CTRL_MAC6_MAC_MII_TXCLK_SEL_BLEN 1 +#define PORT6_PAD_CTRL_MAC6_MAC_MII_TXCLK_SEL_FLAG HSL_RW + +#define MAC6_MAC_MII_RXCLK_SEL +#define PORT6_PAD_CTRL_MAC6_MAC_MII_RXCLK_SEL_BOFFSET 0 +#define PORT6_PAD_CTRL_MAC6_MAC_MII_RXCLK_SEL_BLEN 1 +#define PORT6_PAD_CTRL_MAC6_MAC_MII_RXCLK_SEL_FLAG HSL_RW + + + + + /* SGMII Control Register */ +#define SGMII_CTRL +#define SGMII_CTRL_ID 0 +#define SGMII_CTRL_OFFSET 0x00e0 +#define SGMII_CTRL_E_LENGTH 4 +#define SGMII_CTRL_E_OFFSET 0 +#define SGMII_CTRL_NR_E 1 + +#define FULL_25M +#define SGMII_CTRL_FULL_25M_BOFFSET 31 +#define SGMII_CTRL_FULL_25M_BLEN 1 +#define SGMII_CTRL_FULL_25M_FLAG HSL_RW + +#define HALF_25M +#define SGMII_CTRL_HALF_25M_BOFFSET 30 +#define SGMII_CTRL_HALF_25M_BLEN 1 +#define SGMII_CTRL_HALF_25M_FLAG HSL_RW + +#define REMOTE_25M +#define SGMII_CTRL_REMOTE_25M_BOFFSET 28 +#define SGMII_CTRL_REMOTE_25M_BLEN 2 +#define SGMII_CTRL_REMOTE_25M_FLAG HSL_RW + +#define NEXT_PAGE_25M +#define SGMII_CTRL_NEXT_PAGE_25M_BOFFSET 27 +#define SGMII_CTRL_NEXT_PAGE_25M_BLEN 1 +#define SGMII_CTRL_NEXT_PAGE_25M_FLAG HSL_RW + +#define PAUSE_25M +#define SGMII_CTRL_PAUSE_25M_BOFFSET 26 +#define SGMII_CTRL_PAUSE_25M_BLEN 1 +#define SGMII_CTRL_PAUSE_25M_FLAG HSL_RW + +#define ASYM_PAUSE_25M +#define SGMII_CTRL_ASYM_PAUSE_25M_BOFFSET 25 +#define SGMII_CTRL_ASYM_PAUSE_25M_BLEN 1 +#define SGMII_CTRL_ASYM_PAUSE_25M_FLAG HSL_RW + +#define PAUSE_SG_25M +#define SGMII_CTRL_PAUSE_SG_25M_BOFFSET 24 +#define SGMII_CTRL_PAUSE_SG_25M_BLEN 1 +#define SGMII_CTRL_PAUSE_SG_25M_FLAG HSL_RW + +#define PAUSE_SG_25M +#define SGMII_CTRL_PAUSE_SG_25M_BOFFSET 24 +#define SGMII_CTRL_PAUSE_SG_25M_BLEN 1 +#define SGMII_CTRL_PAUSE_SG_25M_FLAG HSL_RW + +#define MODE_CTRL_25M +#define SGMII_CTRL_MODE_CTRL_25M_BOFFSET 22 +#define SGMII_CTRL_MODE_CTRL_25M_BLEN 2 +#define SGMII_CTRL_MODE_CTRL_25M_FLAG HSL_RW + +#define MR_LOOPBACK +#define SGMII_CTRL_MR_LOOPBACK_BOFFSET 21 +#define SGMII_CTRL_MR_LOOPBACK_BLEN 1 +#define SGMII_CTRL_MR_LOOPBACK_FLAG HSL_RW + +#define MR_REG4_25M +#define SGMII_CTRL_MR_REG4_25M_BOFFSET 20 +#define SGMII_CTRL_MR_REG4_25M_BLEN 1 +#define SGMII_CTRL_MR_REG4_25M_FLAG HSL_RW + +#define AUTO_LPI_25M +#define SGMII_CTRL_AUTO_LPI_25M_BOFFSET 19 +#define SGMII_CTRL_AUTO_LPI_25M_BLEN 1 +#define SGMII_CTRL_AUTO_LPI_25M_FLAG HSL_RW + +#define PRBS_EN +#define SGMII_CTRL_PRBS_EN_BOFFSET 18 +#define SGMII_CTRL_PRBS_EN_BLEN 1 +#define SGMII_CTRL_PRBS_EN_FLAG HSL_RW + +#define SGMII_TH_LOS1 +#define SGMII_CTRL_SGMII_TH_LOS1_BOFFSET 17 +#define SGMII_CTRL_SGMII_TH_LOS1_BLEN 1 +#define SGMII_CTRL_SGMII_TH_LOS1_FLAG HSL_RW + +#define DIS_AUTO_LPI_25M +#define SGMII_CTRL_DIS_AUTO_LPI_25M_BOFFSET 16 +#define SGMII_CTRL_DIS_AUTO_LPI_25M_BLEN 1 +#define SGMII_CTRL_DIS_AUTO_LPI_25M_FLAG HSL_RW + +#define SGMII_TH_LOS0 +#define SGMII_CTRL_SGMII_TH_LOS0_BOFFSET 15 +#define SGMII_CTRL_SGMII_TH_LOS0_BLEN 1 +#define SGMII_CTRL_SGMII_TH_LOS0_FLAG HSL_RW + +#define SGMII_CDR_BW +#define SGMII_CTRL_SGMII_CDR_BW_BOFFSET 13 +#define SGMII_CTRL_SGMII_CDR_BW_BLEN 2 +#define SGMII_CTRL_SGMII_CDR_BW_FLAG HSL_RW + +#define SGMII_TXDR_CTRL +#define SGMII_CTRL_SGMII_TXDR_CTRL_BOFFSET 10 +#define SGMII_CTRL_SGMII_TXDR_CTRL_BLEN 3 +#define SGMII_CTRL_SGMII_TXDR_CTRL_FLAG HSL_RW + +#define SGMII_FIBER_MODE +#define SGMII_CTRL_SGMII_FIBER_MODE_BOFFSET 8 +#define SGMII_CTRL_SGMII_FIBER_MODE_BLEN 2 +#define SGMII_CTRL_SGMII_FIBER_MODE_FLAG HSL_RW + +#define SGMII_SEL_125M +#define SGMII_CTRL_SGMII_SEL_125M_BOFFSET 7 +#define SGMII_CTRL_SGMII_SEL_125M_BLEN 1 +#define SGMII_CTRL_SGMII_SEL_125M_FLAG HSL_RW + +#define SGMII_PLL_BW +#define SGMII_CTRL_SGMII_PLL_BW_BOFFSET 6 +#define SGMII_CTRL_SGMII_PLL_BW_BLEN 1 +#define SGMII_CTRL_SGMII_PLL_BW_FLAG HSL_RW + +#define SGMII_HALFTX +#define SGMII_CTRL_SGMII_HALFTX_BOFFSET 5 +#define SGMII_CTRL_SGMII_HALFTX_BLEN 1 +#define SGMII_CTRL_SGMII_HALFTX_FLAG HSL_RW + +#define SGMII_EN_SD +#define SGMII_CTRL_SGMII_EN_SD_BOFFSET 4 +#define SGMII_CTRL_SGMII_EN_SD_BLEN 1 +#define SGMII_CTRL_SGMII_EN_SD_FLAG HSL_RW + +#define SGMII_EN_TX +#define SGMII_CTRL_SGMII_EN_TX_BOFFSET 3 +#define SGMII_CTRL_SGMII_EN_TX_BLEN 1 +#define SGMII_CTRL_SGMII_EN_TX_FLAG HSL_RW + +#define SGMII_EN_RX +#define SGMII_CTRL_SGMII_EN_RX_BOFFSET 2 +#define SGMII_CTRL_SGMII_EN_RX_BLEN 1 +#define SGMII_CTRL_SGMII_EN_RX_FLAG HSL_RW + +#define SGMII_EN_PLL +#define SGMII_CTRL_SGMII_EN_PLL_BOFFSET 1 +#define SGMII_CTRL_SGMII_EN_PLL_BLEN 1 +#define SGMII_CTRL_SGMII_EN_PLL_FLAG HSL_RW + +#define SGMII_EN_LCKDT +#define SGMII_CTRL_SGMII_EN_LCKDT_BOFFSET 0 +#define SGMII_CTRL_SGMII_EN_LCKDT_BLEN 1 +#define SGMII_CTRL_SGMII_EN_LCKDT_FLAG HSL_RW + + + + + /* Power On Strip Register */ +#define POWER_STRIP +#define POWER_STRIP_ID 0 +#define POWER_STRIP_OFFSET 0x0010 +#define POWER_STRIP_E_LENGTH 4 +#define POWER_STRIP_E_OFFSET 0 +#define POWER_STRIP_NR_E 1 + +#define POWER_ON_SEL +#define POWER_STRIP_POWER_ON_SEL_BOFFSET 31 +#define POWER_STRIP_POWER_ON_SEL_BLEN 1 +#define POWER_STRIP_POWER_ON_SEL_FLAG HSL_RW + +#define PKG128_EN +#define POWER_STRIP_PKG128_EN_BOFFSET 30 +#define POWER_STRIP_PKG128_EN_BLEN 1 +#define POWER_STRIP_PKG128_EN_FLAG HSL_RW + +#define PKG128_EN_LED +#define POWER_STRIP_PKG128_EN_LED_BOFFSET 29 +#define POWER_STRIP_PKG128_EN_LED_BLEN 1 +#define POWER_STRIP_PKG128_EN_LED_FLAG HSL_RW + +#define S16_MODE +#define POWER_STRIP_S16_MODE_BOFFSET 28 +#define POWER_STRIP_S16_MODE_BLEN 1 +#define POWER_STRIP_S16_MODE_FLAG HSL_RW + +#define INPUT_MODE +#define POWER_STRIP_INPUT_MODE_BOFFSET 27 +#define POWER_STRIP_INPUT_MODE_BLEN 1 +#define POWER_STRIP_INPUT_MODE_FLAG HSL_RW + +#define SGMII_POWER_ON_SEL +#define POWER_STRIP_SGMII_POWER_ON_SEL_BOFFSET 26 +#define POWER_STRIP_SGMII_POWER_ON_SEL_BLEN 1 +#define POWER_STRIP_SGMII_POWER_ON_SEL_FLAG HSL_RW + +#define SPI_EN +#define POWER_STRIP_SPI_EN_BOFFSET 25 +#define POWER_STRIP_SPI_EN_BLEN 1 +#define POWER_STRIP_SPI_EN_FLAG HSL_RW + +#define LED_OPEN_EN +#define POWER_STRIP_LED_OPEN_EN_BOFFSET 24 +#define POWER_STRIP_LED_OPEN_EN_BLEN 1 +#define POWER_STRIP_LED_OPEN_EN_FLAG HSL_RW + +#define SGMII_RXIMP_50_70 +#define POWER_STRIP_SGMII_RXIMP_50_70_BOFFSET 23 +#define POWER_STRIP_SGMII_RXIMP_50_70_BLEN 1 +#define POWER_STRIP_SGMII_RXIMP_50_70_FLAG HSL_RW + +#define SGMII_TXIMP_50_70 +#define POWER_STRIP_SGMII_TXIMP_50_70_BOFFSET 22 +#define POWER_STRIP_SGMII_TXIMP_50_70_BLEN 1 +#define POWER_STRIP_SGMII_TXIMP_50_70_FLAG HSL_RW + +#define SGMII_SIGNAL_DETECT +#define POWER_STRIP_SGMII_SIGNAL_DETECT_BOFFSET 21 +#define POWER_STRIP_SGMII_SIGNAL_DETECT_BLEN 1 +#define POWER_STRIP_SGMII_SIGNAL_DETECT_FLAG HSL_RW + +#define LPW_EXIT +#define POWER_STRIP_LPW_EXIT_BOFFSET 20 +#define POWER_STRIP_LPW_EXIT_BLEN 1 +#define POWER_STRIP_LPW_EXIT_FLAG HSL_RW + +#define MAN_EN +#define POWER_STRIP_MAN_EN_BOFFSET 18 +#define POWER_STRIP_MAN_EN_BLEN 1 +#define POWER_STRIP_MAN_EN_FLAG HSL_RW + +#define HIB_EN +#define POWER_STRIP_HIB_EN_BOFFSET 17 +#define POWER_STRIP_HIB_EN_BLEN 1 +#define POWER_STRIP_HIB_EN_FLAG HSL_RW + +#define POWER_DOWN_HW +#define POWER_STRIP_POWER_DOWN_HW_BOFFSET 16 +#define POWER_STRIP_POWER_DOWN_HW_BLEN 1 +#define POWER_STRIP_POWER_DOWN_HW_FLAG HSL_RW + +#define BIST_BYPASS_CEL +#define POWER_STRIP_BIST_BYPASS_CEL_BOFFSET 15 +#define POWER_STRIP_BIST_BYPASS_CEL_BLEN 1 +#define POWER_STRIP_BIST_BYPASS_CEL_FLAG HSL_RW + +#define BIST_BYPASS_CSR +#define POWER_STRIP_BIST_BYPASS_CSR_BOFFSET 14 +#define POWER_STRIP_BIST_BYPASS_CSR_BLEN 1 +#define POWER_STRIP_BIST_BYPASS_CSR_FLAG HSL_RW + +#define HIB_PULSE_HW +#define POWER_STRIP_HIB_PULSE_HW_BOFFSET 12 +#define POWER_STRIP_HIB_PULSE_HW_BLEN 1 +#define POWER_STRIP_HIB_PULSE_HW_FLAG HSL_RW + +#define GATE_25M_EN +#define POWER_STRIP_GATE_25M_EN_BOFFSET 10 +#define POWER_STRIP_GATE_25M_EN_BLEN 1 +#define POWER_STRIP_GATE_25M_EN_FLAG HSL_RW + +#define SEL_ANA_RST +#define POWER_STRIP_SEL_ANA_RST_BOFFSET 9 +#define POWER_STRIP_SEL_ANA_RST_BLEN 1 +#define POWER_STRIP_SEL_ANA_RST_FLAG HSL_RW + +#define SERDES_EN +#define POWER_STRIP_SERDES_EN_BOFFSET 8 +#define POWER_STRIP_SERDES_EN_BLEN 1 +#define POWER_STRIP_SERDES_EN_FLAG HSL_RW + +#define SERDES_AN_EN +#define POWER_STRIP_SERDES_AN_EN_BOFFSET 7 +#define POWER_STRIP_SERDES_AN_EN_BLEN 1 +#define POWER_STRIP_SERDES_AN_EN_FLAG HSL_RW + +#define RTL_MODE +#define POWER_STRIP_RTL_MODE_BOFFSET 5 +#define POWER_STRIP_RTL_MODE_BLEN 1 +#define POWER_STRIP_RTL_MODE_FLAG HSL_RW + +#define PAD_CTRL_FOR25M +#define POWER_STRIP_PAD_CTRL_FOR25M_BOFFSET 3 +#define POWER_STRIP_PAD_CTRL_FOR25M_BLEN 2 +#define POWER_STRIP_PAD_CTRL_FOR25M_FLAG HSL_RW + +#define PAD_CTRL +#define POWER_STRIP_PAD_CTRL_BOFFSET 0 +#define POWER_STRIP_PAD_CTRL_BLEN 2 +#define POWER_STRIP_PAD_CTRL_FLAG HSL_RW + + + + + /* Global Interrupt Status Register1 */ +#define GBL_INT_STATUS1 +#define GBL_INT_STATUS1_ID 1 +#define GBL_INT_STATUS1_OFFSET 0x0024 +#define GBL_INT_STATUS1_E_LENGTH 4 +#define GBL_INT_STATUS1_E_OFFSET 0 +#define GBL_INT_STATUS1_NR_E 1 + +#define LINK_CHG_INT_S +#define GBL_INT_STATUS1_LINK_CHG_INT_S_BOFFSET 1 +#define GBL_INT_STATUS1_LINK_CHG_INT_S_BLEN 7 +#define GBL_INT_STATUS1_LINK_CHG_INT_S_FLAG HSL_RW + +#define PHY_INT_S +#define GBL_INT_STATUS1_PHY_INT_S_BOFFSET 15 +#define GBL_INT_STATUS1_PHY_INT_S_BLEN 1 +#define GBL_INT_STATUS1_PHY_INT_S_FLAG HSL_RO + + + + + /* Global Interrupt Mask Register1 */ +#define GBL_INT_MASK1 +#define GBL_INT_MASK1_ID 1 +#define GBL_INT_MASK1_OFFSET 0x002c +#define GBL_INT_MASK1_E_LENGTH 4 +#define GBL_INT_MASK1_E_OFFSET 0 +#define GBL_INT_MASK1_NR_E 1 + +#define LINK_CHG_INT_M +#define GBL_INT_MASK1_LINK_CHG_INT_M_BOFFSET 1 +#define GBL_INT_MASK1_LINK_CHG_INT_M_BLEN 7 +#define GBL_INT_MASK1_LINK_CHG_INT_M_FLAG HSL_RW + +#define PHY_INT_M +#define GBL_INT_MASK1_PHY_INT_M_BOFFSET 15 +#define GBL_INT_MASK1_PHY_INT_M_BLEN 1 +#define GBL_INT_MASK1_PHY_INT_M_FLAG HSL_RO + + + + + /* Module Enable Register */ +#define MOD_ENABLE +#define MOD_ENABLE_OFFSET 0x0030 +#define MOD_ENABLE_E_LENGTH 4 +#define MOD_ENABLE_E_OFFSET 0 +#define MOD_ENABLE_NR_E 1 + +#define L3_EN +#define MOD_ENABLE_L3_EN_BOFFSET 2 +#define MOD_ENABLE_L3_EN_BLEN 1 +#define MOD_ENABLE_L3_EN_FLAG HSL_RW + +#define ACL_EN +#define MOD_ENABLE_ACL_EN_BOFFSET 1 +#define MOD_ENABLE_ACL_EN_BLEN 1 +#define MOD_ENABLE_ACL_EN_FLAG HSL_RW + +#define MIB_EN +#define MOD_ENABLE_MIB_EN_BOFFSET 0 +#define MOD_ENABLE_MIB_EN_BLEN 1 +#define MOD_ENABLE_MIB_EN_FLAG HSL_RW + + + + + /* MIB Function Register */ +#define MIB_FUNC +#define MIB_FUNC_OFFSET 0x0034 +#define MIB_FUNC_E_LENGTH 4 +#define MIB_FUNC_E_OFFSET 0 +#define MIB_FUNC_NR_E 1 + +#define MIB_FUN +#define MIB_FUNC_MIB_FUN_BOFFSET 24 +#define MIB_FUNC_MIB_FUN_BLEN 3 +#define MIB_FUNC_MIB_FUN_FLAG HSL_RW + +#define MIB_FLUSH_PORT +#define MIB_FUNC_MIB_FLUSH_PORT_BOFFSET 21 +#define MIB_FUNC_MIB_FLUSH_PORT_BLEN 3 +#define MIB_FUNC_MIB_FLUSH_PORT_FLAG HSL_RW + +#define MIB_CPU_KEEP +#define MIB_FUNC_MIB_CPU_KEEP_BOFFSET 20 +#define MIB_FUNC_MIB_CPU_KEEP_BLEN 1 +#define MIB_FUNC_MIB_CPU_KEEP_FLAG HSL_RW + +#define MIB_BUSY +#define MIB_FUNC_MIB_BUSY_BOFFSET 17 +#define MIB_FUNC_MIB_BUSY_BLEN 1 +#define MIB_FUNC_MIB_BUSY_FLAG HSL_RW + +#define MIB_AT_HALF_EN +#define MIB_FUNC_MIB_AT_HALF_EN_BOFFSET 16 +#define MIB_FUNC_MIB_AT_HALF_EN_BLEN 1 +#define MIB_FUNC_MIB_AT_HALF_EN_FLAG HSL_RW + +#define MIB_TIMER +#define MIB_FUNC_MIB_TIMER_BOFFSET 0 +#define MIB_FUNC_MIB_TIMER_BLEN 16 +#define MIB_FUNC_MIB_TIMER_FLAG HSL_RW + + + + + /* Service tag Register */ +#define SERVICE_TAG +#define SERVICE_TAG_OFFSET 0x0048 +#define SERVICE_TAG_E_LENGTH 4 +#define SERVICE_TAG_E_OFFSET 0 +#define SERVICE_TAG_NR_E 1 + +#define STAG_MODE +#define SERVICE_TAG_STAG_MODE_BOFFSET 17 +#define SERVICE_TAG_STAG_MODE_BLEN 1 +#define SERVICE_TAG_STAG_MODE_FLAG HSL_RW + +#define TAG_VALUE +#define SERVICE_TAG_TAG_VALUE_BOFFSET 0 +#define SERVICE_TAG_TAG_VALUE_BLEN 16 +#define SERVICE_TAG_TAG_VALUE_FLAG HSL_RW + + + + + /* Global MAC Address Register */ +#define GLOBAL_MAC_ADDR0 +#define GLOBAL_MAC_ADDR0_OFFSET 0x0060 +#define GLOBAL_MAC_ADDR0_E_LENGTH 4 +#define GLOBAL_MAC_ADDR0_E_OFFSET 0 +#define GLOBAL_MAC_ADDR0_NR_E 1 + +#define GLB_BYTE4 +#define GLOBAL_MAC_ADDR0_GLB_BYTE4_BOFFSET 8 +#define GLOBAL_MAC_ADDR0_GLB_BYTE4_BLEN 8 +#define GLOBAL_MAC_ADDR0_GLB_BYTE4_FLAG HSL_RW + +#define GLB_BYTE5 +#define GLOBAL_MAC_ADDR0_GLB_BYTE5_BOFFSET 0 +#define GLOBAL_MAC_ADDR0_GLB_BYTE5_BLEN 8 +#define GLOBAL_MAC_ADDR0_GLB_BYTE5_FLAG HSL_RW + +#define GLOBAL_MAC_ADDR1 +#define GLOBAL_MAC_ADDR1_ID 4 +#define GLOBAL_MAC_ADDR1_OFFSET 0x0064 +#define GLOBAL_MAC_ADDR1_E_LENGTH 4 +#define GLOBAL_MAC_ADDR1_E_OFFSET 0 +#define GLOBAL_MAC_ADDR1_NR_E 1 + +#define GLB_BYTE0 +#define GLOBAL_MAC_ADDR1_GLB_BYTE0_BOFFSET 24 +#define GLOBAL_MAC_ADDR1_GLB_BYTE0_BLEN 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE0_FLAG HSL_RW + +#define GLB_BYTE1 +#define GLOBAL_MAC_ADDR1_GLB_BYTE1_BOFFSET 16 +#define GLOBAL_MAC_ADDR1_GLB_BYTE1_BLEN 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE1_FLAG HSL_RW + +#define GLB_BYTE2 +#define GLOBAL_MAC_ADDR1_GLB_BYTE2_BOFFSET 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE2_BLEN 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE2_FLAG HSL_RW + +#define GLB_BYTE3 +#define GLOBAL_MAC_ADDR1_GLB_BYTE3_BOFFSET 0 +#define GLOBAL_MAC_ADDR1_GLB_BYTE3_BLEN 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE3_FLAG HSL_RW + + + + + /* Max Size Register */ +#define MAX_SIZE +#define MAX_SIZE_OFFSET 0x0078 +#define MAX_SIZE_E_LENGTH 4 +#define MAX_SIZE_E_OFFSET 0 +#define MAX_SIZE_NR_E 1 + +#define MAX_FRAME_SIZE +#define MAX_SIZE_MAX_FRAME_SIZE_BOFFSET 0 +#define MAX_SIZE_MAX_FRAME_SIZE_BLEN 14 +#define MAX_SIZE_MAX_FRAME_SIZE_FLAG HSL_RW + + + + + /* Flow Control Register */ +#define FLOW_CTL0 "fctl" +#define FLOW_CTL0_ID 6 +#define FLOW_CTL0_OFFSET 0x0034 +#define FLOW_CTL0_E_LENGTH 4 +#define FLOW_CTL0_E_OFFSET 0 +#define FLOW_CTL0_NR_E 1 + +#define TEST_PAUSE "fctl_tps" +#define FLOW_CTL0_TEST_PAUSE_BOFFSET 31 +#define FLOW_CTL0_TEST_PAUSE_BLEN 1 +#define FLOW_CTL0_TEST_PAUSE_FLAG HSL_RW + + +#define GOL_PAUSE_ON_THRES "fctl_gont" +#define FLOW_CTL0_GOL_PAUSE_ON_THRES_BOFFSET 16 +#define FLOW_CTL0_GOL_PAUSE_ON_THRES_BLEN 8 +#define FLOW_CTL0_GOL_PAUSE_ON_THRES_FLAG HSL_RW + +#define GOL_PAUSE_OFF_THRES "fctl_gofft" +#define FLOW_CTL0_GOL_PAUSE_OFF_THRES_BOFFSET 0 +#define FLOW_CTL0_GOL_PAUSE_OFF_THRES_BLEN 8 +#define FLOW_CTL0_GOL_PAUSE_OFF_THRES_FLAG HSL_RW + + + + + /* Flow Control1 Register */ +#define FLOW_CTL1 "fctl1" +#define FLOW_CTL1_ID 6 +#define FLOW_CTL1_OFFSET 0x0038 +#define FLOW_CTL1_E_LENGTH 4 +#define FLOW_CTL1_E_OFFSET 0 +#define FLOW_CTL1_NR_E 1 + +#define PORT_PAUSE_ON_THRES "fctl1_pont" +#define FLOW_CTL1_PORT_PAUSE_ON_THRES_BOFFSET 16 +#define FLOW_CTL1_PORT_PAUSE_ON_THRES_BLEN 8 +#define FLOW_CTL1_PORT_PAUSE_ON_THRES_FLAG HSL_RW + +#define PORT_PAUSE_OFF_THRES "fctl1_pofft" +#define FLOW_CTL1_PORT_PAUSE_OFF_THRES_BOFFSET 0 +#define FLOW_CTL1_PORT_PAUSE_OFF_THRES_BLEN 8 +#define FLOW_CTL1_PORT_PAUSE_OFF_THRES_FLAG HSL_RW + + + + + /* Port Status Register */ +#define PORT_STATUS +#define PORT_STATUS_OFFSET 0x007c +#define PORT_STATUS_E_LENGTH 4 +#define PORT_STATUS_E_OFFSET 0x0004 +#define PORT_STATUS_NR_E 7 + +#define FLOW_LINK_EN +#define PORT_STATUS_FLOW_LINK_EN_BOFFSET 12 +#define PORT_STATUS_FLOW_LINK_EN_BLEN 1 +#define PORT_STATUS_FLOW_LINK_EN_FLAG HSL_RW + +#define AUTO_RX_FLOW +#define PORT_STATUS_AUTO_RX_FLOW_BOFFSET 11 +#define PORT_STATUS_AUTO_RX_FLOW_BLEN 1 +#define PORT_STATUS_AUTO_RX_FLOW_FLAG HSL_RO + +#define AUTO_TX_FLOW +#define PORT_STATUS_AUTO_TX_FLOW_BOFFSET 10 +#define PORT_STATUS_AUTO_TX_FLOW_BLEN 1 +#define PORT_STATUS_AUTO_TX_FLOW_FLAG HSL_RO + +#define LINK_EN +#define PORT_STATUS_LINK_EN_BOFFSET 9 +#define PORT_STATUS_LINK_EN_BLEN 1 +#define PORT_STATUS_LINK_EN_FLAG HSL_RW + +#define LINK +#define PORT_STATUS_LINK_BOFFSET 8 +#define PORT_STATUS_LINK_BLEN 1 +#define PORT_STATUS_LINK_FLAG HSL_RO + +#define TX_HALF_FLOW_EN +#define PORT_STATUS_TX_HALF_FLOW_EN_BOFFSET 7 +#define PORT_STATUS_TX_HALF_FLOW_EN_BLEN 1 +#define PORT_STATUS_TX_HALF_FLOW_EN_FLAG HSL_RW + +#define DUPLEX_MODE +#define PORT_STATUS_DUPLEX_MODE_BOFFSET 6 +#define PORT_STATUS_DUPLEX_MODE_BLEN 1 +#define PORT_STATUS_DUPLEX_MODE_FLAG HSL_RW + +#define RX_FLOW_EN +#define PORT_STATUS_RX_FLOW_EN_BOFFSET 5 +#define PORT_STATUS_RX_FLOW_EN_BLEN 1 +#define PORT_STATUS_RX_FLOW_EN_FLAG HSL_RW + +#define TX_FLOW_EN +#define PORT_STATUS_TX_FLOW_EN_BOFFSET 4 +#define PORT_STATUS_TX_FLOW_EN_BLEN 1 +#define PORT_STATUS_TX_FLOW_EN_FLAG HSL_RW + +#define RXMAC_EN +#define PORT_STATUS_RXMAC_EN_BOFFSET 3 +#define PORT_STATUS_RXMAC_EN_BLEN 1 +#define PORT_STATUS_RXMAC_EN_FLAG HSL_RW + +#define TXMAC_EN +#define PORT_STATUS_TXMAC_EN_BOFFSET 2 +#define PORT_STATUS_TXMAC_EN_BLEN 1 +#define PORT_STATUS_TXMAC_EN_FLAG HSL_RW + +#define SPEED_MODE +#define PORT_STATUS_SPEED_MODE_BOFFSET 0 +#define PORT_STATUS_SPEED_MODE_BLEN 2 +#define PORT_STATUS_SPEED_MODE_FLAG HSL_RW + + + + + /* Header Ctl Register */ +#define HEADER_CTL +#define HEADER_CTL_OFFSET 0x0098 +#define HEADER_CTL_E_LENGTH 4 +#define HEADER_CTL_E_OFFSET 0x0004 +#define HEADER_CTL_NR_E 1 + +#define TYPE_LEN +#define HEADER_CTL_TYPE_LEN_BOFFSET 16 +#define HEADER_CTL_TYPE_LEN_BLEN 1 +#define HEADER_CTL_TYPE_LEN_FLAG HSL_RW + +#define TYPE_VAL +#define HEADER_CTL_TYPE_VAL_BOFFSET 0 +#define HEADER_CTL_TYPE_VAL_BLEN 16 +#define HEADER_CTL_TYPE_VAL_FLAG HSL_RW + + + + + /* Port Header Ctl Register */ +#define PORT_HDR_CTL +#define PORT_HDR_CTL_OFFSET 0x009c +#define PORT_HDR_CTL_E_LENGTH 4 +#define PORT_HDR_CTL_E_OFFSET 0x0004 +#define PORT_HDR_CTL_NR_E 7 + +#define IPG_DEC_EN +#define PORT_HDR_CTL_IPG_DEC_EN_BOFFSET 5 +#define PORT_HDR_CTL_IPG_DEC_EN_BLEN 1 +#define PORT_HDR_CTL_IPG_DEC_EN_FLAG HSL_RW + +#define LOOPBACK_EN +#define PORT_HDR_CTL_LOOPBACK_EN_BOFFSET 4 +#define PORT_HDR_CTL_LOOPBACK_EN_BLEN 1 +#define PORT_HDR_CTL_LOOPBACK_EN_FLAG HSL_RW + +#define RXHDR_MODE +#define PORT_HDR_CTL_RXHDR_MODE_BOFFSET 2 +#define PORT_HDR_CTL_RXHDR_MODE_BLEN 2 +#define PORT_HDR_CTL_RXHDR_MODE_FLAG HSL_RW + +#define TXHDR_MODE +#define PORT_HDR_CTL_TXHDR_MODE_BOFFSET 0 +#define PORT_HDR_CTL_TXHDR_MODE_BLEN 2 +#define PORT_HDR_CTL_TXHDR_MODE_FLAG HSL_RW + + + + + /* EEE control Register */ +#define EEE_CTL +#define EEE_CTL_OFFSET 0x0100 +#define EEE_CTL_E_LENGTH 4 +#define EEE_CTL_E_OFFSET 0 +#define EEE_CTL_NR_E 1 + +#define LPI_STATE_REMAP_EN_5 +#define EEE_CTL_LPI_STATE_REMAP_EN_5_BOFFSET 13 +#define EEE_CTL_LPI_STATE_REMAP_EN_5_BLEN 1 +#define EEE_CTL_LPI_STATE_REMAP_EN_5_FLAG HSL_RW + +#define LPI_EN_5 +#define EEE_CTL_LPI_EN_5_BOFFSET 12 +#define EEE_CTL_LPI_EN_5_BLEN 1 +#define EEE_CTL_LPI_EN_5_FLAG HSL_RW + +#define LPI_STATE_REMAP_EN_4 +#define EEE_CTL_LPI_STATE_REMAP_EN_4_BOFFSET 11 +#define EEE_CTL_LPI_STATE_REMAP_EN_4_BLEN 1 +#define EEE_CTL_LPI_STATE_REMAP_EN_4_FLAG HSL_RW + +#define LPI_EN_4 +#define EEE_CTL_LPI_EN_4_BOFFSET 10 +#define EEE_CTL_LPI_EN_4_BLEN 1 +#define EEE_CTL_LPI_EN_4_FLAG HSL_RW + +#define LPI_STATE_REMAP_EN_3 +#define EEE_CTL_LPI_STATE_REMAP_EN_3_BOFFSET 9 +#define EEE_CTL_LPI_STATE_REMAP_EN_3_BLEN 1 +#define EEE_CTL_LPI_STATE_REMAP_EN_3_FLAG HSL_RW + +#define LPI_EN_3 +#define EEE_CTL_LPI_EN_3_BOFFSET 8 +#define EEE_CTL_LPI_EN_3_BLEN 1 +#define EEE_CTL_LPI_EN_3_FLAG HSL_RW + +#define LPI_STATE_REMAP_EN_2 +#define EEE_CTL_LPI_STATE_REMAP_EN_2_BOFFSET 7 +#define EEE_CTL_LPI_STATE_REMAP_EN_2_BLEN 1 +#define EEE_CTL_LPI_STATE_REMAP_EN_2_FLAG HSL_RW + +#define LPI_EN_2 +#define EEE_CTL_LPI_EN_2_BOFFSET 6 +#define EEE_CTL_LPI_EN_2_BLEN 1 +#define EEE_CTL_LPI_EN_2_FLAG HSL_RW + +#define LPI_STATE_REMAP_EN_1 +#define EEE_CTL_LPI_STATE_REMAP_EN_1_BOFFSET 5 +#define EEE_CTL_LPI_STATE_REMAP_EN_1_BLEN 1 +#define EEE_CTL_LPI_STATE_REMAP_EN_1_FLAG HSL_RW + +#define LPI_EN_1 +#define EEE_CTL_LPI_EN_1_BOFFSET 4 +#define EEE_CTL_LPI_EN_1_BLEN 1 +#define EEE_CTL_LPI_EN_1_FLAG HSL_RW + + + + + /* Frame Ack Ctl0 Register */ +#define FRAME_ACK_CTL0 +#define FRAME_ACK_CTL0_OFFSET 0x0210 +#define FRAME_ACK_CTL0_E_LENGTH 4 +#define FRAME_ACK_CTL0_E_OFFSET 0 +#define FRAME_ACK_CTL0_NR_E 1 + +#define ARP_REQ_EN +#define FRAME_ACK_CTL0_ARP_REQ_EN_BOFFSET 6 +#define FRAME_ACK_CTL0_ARP_REQ_EN_BLEN 1 +#define FRAME_ACK_CTL0_ARP_REQ_EN_FLAG HSL_RW + +#define ARP_REP_EN +#define FRAME_ACK_CTL0_ARP_REP_EN_BOFFSET 5 +#define FRAME_ACK_CTL0_ARP_REP_EN_BLEN 1 +#define FRAME_ACK_CTL0_ARP_REP_EN_FLAG HSL_RW + +#define DHCP_EN +#define FRAME_ACK_CTL0_DHCP_EN_BOFFSET 4 +#define FRAME_ACK_CTL0_DHCP_EN_BLEN 1 +#define FRAME_ACK_CTL0_DHCP_EN_FLAG HSL_RW + +#define EAPOL_EN +#define FRAME_ACK_CTL0_EAPOL_EN_BOFFSET 3 +#define FRAME_ACK_CTL0_EAPOL_EN_BLEN 1 +#define FRAME_ACK_CTL0_EAPOL_EN_FLAG HSL_RW + +#define LEAVE_EN +#define FRAME_ACK_CTL0_LEAVE_EN_BOFFSET 2 +#define FRAME_ACK_CTL0_LEAVE_EN_BLEN 1 +#define FRAME_ACK_CTL0_LEAVE_EN_FLAG HSL_RW + +#define JOIN_EN +#define FRAME_ACK_CTL0_JOIN_EN_BOFFSET 1 +#define FRAME_ACK_CTL0_JOIN_EN_BLEN 1 +#define FRAME_ACK_CTL0_JOIN_EN_FLAG HSL_RW + +#define IGMP_MLD_EN +#define FRAME_ACK_CTL0_IGMP_MLD_EN_BOFFSET 0 +#define FRAME_ACK_CTL0_IGMP_MLD_EN_BLEN 1 +#define FRAME_ACK_CTL0_IGMP_MLD_EN_FLAG HSL_RW + + + + + /* Frame Ack Ctl1 Register */ +#define FRAME_ACK_CTL1 +#define FRAME_ACK_CTL1_OFFSET 0x0214 +#define FRAME_ACK_CTL1_E_LENGTH 4 +#define FRAME_ACK_CTL1_E_OFFSET 0 +#define FRAME_ACK_CTL1_NR_E 1 + +#define PPPOE_EN +#define FRAME_ACK_CTL1_PPPOE_EN_BOFFSET 25 +#define FRAME_ACK_CTL1_PPPOE_EN_BLEN 1 +#define FRAME_ACK_CTL1_PPPOE_EN_FLAG HSL_RW + +#define IGMP_V3_EN +#define FRAME_ACK_CTL1_IGMP_V3_EN_BOFFSET 24 +#define FRAME_ACK_CTL1_IGMP_V3_EN_BLEN 1 +#define FRAME_ACK_CTL1_IGMP_V3_EN_FLAG HSL_RW + + + + + /* Window Rule Ctl0 Register */ +#define WIN_RULE_CTL0 +#define WIN_RULE_CTL0_OFFSET 0x0218 +#define WIN_RULE_CTL0_E_LENGTH 4 +#define WIN_RULE_CTL0_E_OFFSET 0x4 +#define WIN_RULE_CTL0_NR_E 7 + +#define L4_LENGTH +#define WIN_RULE_CTL0_L4_LENGTH_BOFFSET 24 +#define WIN_RULE_CTL0_L4_LENGTH_BLEN 4 +#define WIN_RULE_CTL0_L4_LENGTH_FLAG HSL_RW + +#define L3_LENGTH +#define WIN_RULE_CTL0_L3_LENGTH_BOFFSET 20 +#define WIN_RULE_CTL0_L3_LENGTH_BLEN 4 +#define WIN_RULE_CTL0_L3_LENGTH_FLAG HSL_RW + +#define L2_LENGTH +#define WIN_RULE_CTL0_L2_LENGTH_BOFFSET 16 +#define WIN_RULE_CTL0_L2_LENGTH_BLEN 4 +#define WIN_RULE_CTL0_L2_LENGTH_FLAG HSL_RW + +#define L4_OFFSET +#define WIN_RULE_CTL0_L4_OFFSET_BOFFSET 10 +#define WIN_RULE_CTL0_L4_OFFSET_BLEN 5 +#define WIN_RULE_CTL0_L4_OFFSET_FLAG HSL_RW + +#define L3_OFFSET +#define WIN_RULE_CTL0_L3_OFFSET_BOFFSET 5 +#define WIN_RULE_CTL0_L3_OFFSET_BLEN 5 +#define WIN_RULE_CTL0_L3_OFFSET_FLAG HSL_RW + +#define L2_OFFSET +#define WIN_RULE_CTL0_L2_OFFSET_BOFFSET 0 +#define WIN_RULE_CTL0_L2_OFFSET_BLEN 5 +#define WIN_RULE_CTL0_L2_OFFSET_FLAG HSL_RW + + + + + /* Window Rule Ctl1 Register */ +#define WIN_RULE_CTL1 +#define WIN_RULE_CTL1_OFFSET 0x0234 +#define WIN_RULE_CTL1_E_LENGTH 4 +#define WIN_RULE_CTL1_E_OFFSET 0x4 +#define WIN_RULE_CTL1_NR_E 7 + +#define L3P_LENGTH +#define WIN_RULE_CTL1_L3P_LENGTH_BOFFSET 20 +#define WIN_RULE_CTL1_L3P_LENGTH_BLEN 4 +#define WIN_RULE_CTL1_L3P_LENGTH_FLAG HSL_RW + +#define L2S_LENGTH +#define WIN_RULE_CTL1_L2S_LENGTH_BOFFSET 16 +#define WIN_RULE_CTL1_L2S_LENGTH_BLEN 4 +#define WIN_RULE_CTL1_L2S_LENGTH_FLAG HSL_RW + +#define L3P_OFFSET +#define WIN_RULE_CTL1_L3P_OFFSET_BOFFSET 5 +#define WIN_RULE_CTL1_L3P_OFFSET_BLEN 5 +#define WIN_RULE_CTL1_L3P_OFFSET_FLAG HSL_RW + +#define L2S_OFFSET +#define WIN_RULE_CTL1_L2S_OFFSET_BOFFSET 0 +#define WIN_RULE_CTL1_L2S_OFFSET_BLEN 5 +#define WIN_RULE_CTL1_L2S_OFFSET_FLAG HSL_RW + + + + + /* Trunk Hash Mode Register */ +#define TRUNK_HASH_MODE +#define TRUNK_HASH_MODE_OFFSET 0x0270 +#define TRUNK_HASH_MODE_E_LENGTH 4 +#define TRUNK_HASH_MODE_E_OFFSET 0x4 +#define TRUNK_HASH_MODE_NR_E 1 + +#define SIP_EN +#define TRUNK_HASH_MODE_SIP_EN_BOFFSET 3 +#define TRUNK_HASH_MODE_SIP_EN_BLEN 1 +#define TRUNK_HASH_MODE_SIP_EN_FLAG HSL_RW + +#define DIP_EN +#define TRUNK_HASH_MODE_DIP_EN_BOFFSET 2 +#define TRUNK_HASH_MODE_DIP_EN_BLEN 1 +#define TRUNK_HASH_MODE_DIP_EN_FLAG HSL_RW + +#define SA_EN +#define TRUNK_HASH_MODE_SA_EN_BOFFSET 1 +#define TRUNK_HASH_MODE_SA_EN_BLEN 1 +#define TRUNK_HASH_MODE_SA_EN_FLAG HSL_RW + +#define DA_EN +#define TRUNK_HASH_MODE_DA_EN_BOFFSET 0 +#define TRUNK_HASH_MODE_DA_EN_BLEN 1 +#define TRUNK_HASH_MODE_DA_EN_FLAG HSL_RW + + + + + /* Vlan Table Function0 Register */ +#define VLAN_TABLE_FUNC0 +#define VLAN_TABLE_FUNC0_OFFSET 0x0610 +#define VLAN_TABLE_FUNC0_E_LENGTH 4 +#define VLAN_TABLE_FUNC0_E_OFFSET 0 +#define VLAN_TABLE_FUNC0_NR_E 1 + +#define VT_VALID +#define VLAN_TABLE_FUNC0_VT_VALID_BOFFSET 20 +#define VLAN_TABLE_FUNC0_VT_VALID_BLEN 1 +#define VLAN_TABLE_FUNC0_VT_VALID_FLAG HSL_RW + +#define IVL_EN +#define VLAN_TABLE_FUNC0_IVL_EN_BOFFSET 19 +#define VLAN_TABLE_FUNC0_IVL_EN_BLEN 1 +#define VLAN_TABLE_FUNC0_IVL_EN_FLAG HSL_RW + +#define LEARN_DIS +#define VLAN_TABLE_FUNC0_LEARN_DIS_BOFFSET 18 +#define VLAN_TABLE_FUNC0_LEARN_DIS_BLEN 1 +#define VLAN_TABLE_FUNC0_LEARN_DIS_FLAG HSL_RW + +#define VID_MEM +#define VLAN_TABLE_FUNC0_VID_MEM_BOFFSET 4 +#define VLAN_TABLE_FUNC0_VID_MEM_BLEN 14 +#define VLAN_TABLE_FUNC0_VID_MEM_FLAG HSL_RW + +#define VT_PRI_EN +#define VLAN_TABLE_FUNC0_VT_PRI_EN_BOFFSET 3 +#define VLAN_TABLE_FUNC0_VT_PRI_EN_BLEN 1 +#define VLAN_TABLE_FUNC0_VT_PRI_EN_FLAG HSL_RW + +#define VT_PRI +#define VLAN_TABLE_FUNC0_VT_PRI_BOFFSET 0 +#define VLAN_TABLE_FUNC0_VT_PRI_BLEN 3 +#define VLAN_TABLE_FUNC0_VT_PRI_FLAG HSL_RW + + /* Vlan Table Function1 Register */ +#define VLAN_TABLE_FUNC1 +#define VLAN_TABLE_FUNC1_OFFSET 0x0614 +#define VLAN_TABLE_FUNC1_E_LENGTH 4 +#define VLAN_TABLE_FUNC1_E_OFFSET 0 +#define VLAN_TABLE_FUNC1_NR_E 1 + +#define VT_BUSY +#define VLAN_TABLE_FUNC1_VT_BUSY_BOFFSET 31 +#define VLAN_TABLE_FUNC1_VT_BUSY_BLEN 1 +#define VLAN_TABLE_FUNC1_VT_BUSY_FLAG HSL_RW + +#define VLAN_ID +#define VLAN_TABLE_FUNC1_VLAN_ID_BOFFSET 16 +#define VLAN_TABLE_FUNC1_VLAN_ID_BLEN 12 +#define VLAN_TABLE_FUNC1_VLAN_ID_FLAG HSL_RW + +#define VT_PORT_NUM +#define VLAN_TABLE_FUNC1_VT_PORT_NUM_BOFFSET 8 +#define VLAN_TABLE_FUNC1_VT_PORT_NUM_BLEN 4 +#define VLAN_TABLE_FUNC1_VT_PORT_NUM_FLAG HSL_RW + +#define VT_FULL_VIO +#define VLAN_TABLE_FUNC1_VT_FULL_VIO_BOFFSET 4 +#define VLAN_TABLE_FUNC1_VT_FULL_VIO_BLEN 1 +#define VLAN_TABLE_FUNC1_VT_FULL_VIO_FLAG HSL_RW + +#define VT_FUNC +#define VLAN_TABLE_FUNC1_VT_FUNC_BOFFSET 0 +#define VLAN_TABLE_FUNC1_VT_FUNC_BLEN 3 +#define VLAN_TABLE_FUNC1_VT_FUNC_FLAG HSL_RW + + + + + /* Address Table Function0 Register */ +#define ADDR_TABLE_FUNC0 +#define ADDR_TABLE_FUNC0_OFFSET 0x0600 +#define ADDR_TABLE_FUNC0_E_LENGTH 4 +#define ADDR_TABLE_FUNC0_E_OFFSET 0 +#define ADDR_TABLE_FUNC0_NR_E 1 + + +#define AT_ADDR_BYTE2 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE2_BOFFSET 24 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE2_BLEN 8 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE2_FLAG HSL_RW + +#define AT_ADDR_BYTE3 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE3_BOFFSET 16 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE3_BLEN 8 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE3_FLAG HSL_RW + +#define AT_ADDR_BYTE4 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE4_BOFFSET 8 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE4_BLEN 8 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE4_FLAG HSL_RW + +#define AT_ADDR_BYTE5 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE5_BOFFSET 0 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE5_BLEN 8 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE5_FLAG HSL_RW + + /* Address Table Function1 Register */ +#define ADDR_TABLE_FUNC1 +#define ADDR_TABLE_FUNC1_OFFSET 0x0604 +#define ADDR_TABLE_FUNC1_E_LENGTH 4 +#define ADDR_TABLE_FUNC1_E_OFFSET 0 +#define ADDR_TABLE_FUNC1_NR_E 1 + +#define SA_DROP_EN +#define ADDR_TABLE_FUNC1_SA_DROP_EN_BOFFSET 30 +#define ADDR_TABLE_FUNC1_SA_DROP_EN_BLEN 1 +#define ADDR_TABLE_FUNC1_SA_DROP_EN_FLAG HSL_RW + +#define MIRROR_EN +#define ADDR_TABLE_FUNC1_MIRROR_EN_BOFFSET 29 +#define ADDR_TABLE_FUNC1_MIRROR_EN_BLEN 1 +#define ADDR_TABLE_FUNC1_MIRROR_EN_FLAG HSL_RW + +#define AT_PRI_EN +#define ADDR_TABLE_FUNC1_AT_PRI_EN_BOFFSET 28 +#define ADDR_TABLE_FUNC1_AT_PRI_EN_BLEN 1 +#define ADDR_TABLE_FUNC1_AT_PRI_EN_FLAG HSL_RW + +#define AT_SVL_EN +#define ADDR_TABLE_FUNC1_AT_SVL_EN_BOFFSET 27 +#define ADDR_TABLE_FUNC1_AT_SVL_EN_BLEN 1 +#define ADDR_TABLE_FUNC1_AT_SVL_EN_FLAG HSL_RW + +#define AT_PRI +#define ADDR_TABLE_FUNC1_AT_PRI_BOFFSET 24 +#define ADDR_TABLE_FUNC1_AT_PRI_BLEN 3 +#define ADDR_TABLE_FUNC1_AT_PRI_FLAG HSL_RW + +#define CROSS_PT +#define ADDR_TABLE_FUNC1_CROSS_PT_BOFFSET 23 +#define ADDR_TABLE_FUNC1_CROSS_PT_BLEN 1 +#define ADDR_TABLE_FUNC1_CROSS_PT_FLAG HSL_RW + +#define DES_PORT +#define ADDR_TABLE_FUNC1_DES_PORT_BOFFSET 16 +#define ADDR_TABLE_FUNC1_DES_PORT_BLEN 7 +#define ADDR_TABLE_FUNC1_DES_PORT_FLAG HSL_RW + +#define AT_ADDR_BYTE0 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE0_BOFFSET 8 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE0_BLEN 8 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE0_FLAG HSL_RW + +#define AT_ADDR_BYTE1 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE1_BOFFSET 0 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE1_BLEN 8 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE1_FLAG HSL_RW + + /* Address Table Function2 Register */ +#define ADDR_TABLE_FUNC2 +#define ADDR_TABLE_FUNC2_OFFSET 0x0608 +#define ADDR_TABLE_FUNC2_E_LENGTH 4 +#define ADDR_TABLE_FUNC2_E_OFFSET 0 +#define ADDR_TABLE_FUNC2_NR_E 1 + +#define WL_EN +#define ADDR_TABLE_FUNC2_WL_EN_BOFFSET 20 +#define ADDR_TABLE_FUNC2_WL_EN_BLEN 1 +#define ADDR_TABLE_FUNC2_WL_EN_FLAG HSL_RW + +#define AT_VID +#define ADDR_TABLE_FUNC2_AT_VID_BOFFSET 8 +#define ADDR_TABLE_FUNC2_AT_VID_BLEN 12 +#define ADDR_TABLE_FUNC2_AT_VID_FLAG HSL_RW + +#define SHORT_LOOP +#define ADDR_TABLE_FUNC2_SHORT_LOOP_BOFFSET 7 +#define ADDR_TABLE_FUNC2_SHORT_LOOP_BLEN 1 +#define ADDR_TABLE_FUNC2_SHORT_LOOP_FLAG HSL_RW + +#define COPY_TO_CPU +#define ADDR_TABLE_FUNC2_COPY_TO_CPU_BOFFSET 6 +#define ADDR_TABLE_FUNC2_COPY_TO_CPU_BLEN 1 +#define ADDR_TABLE_FUNC2_COPY_TO_CPU_FLAG HSL_RW + +#define REDRCT_TO_CPU +#define ADDR_TABLE_FUNC2_REDRCT_TO_CPU_BOFFSET 5 +#define ADDR_TABLE_FUNC2_REDRCT_TO_CPU_BLEN 1 +#define ADDR_TABLE_FUNC2_REDRCT_TO_CPU_FLAG HSL_RW + +#define LEAKY_EN +#define ADDR_TABLE_FUNC2_LEAKY_EN_BOFFSET 4 +#define ADDR_TABLE_FUNC2_LEAKY_EN_BLEN 1 +#define ADDR_TABLE_FUNC2_LEAKY_EN_FLAG HSL_RW + +#define AT_STATUS +#define ADDR_TABLE_FUNC2_AT_STATUS_BOFFSET 0 +#define ADDR_TABLE_FUNC2_AT_STATUS_BLEN 4 +#define ADDR_TABLE_FUNC2_AT_STATUS_FLAG HSL_RW + + /* Address Table Function3 Register */ +#define ADDR_TABLE_FUNC3 +#define ADDR_TABLE_FUNC3_OFFSET 0x060c +#define ADDR_TABLE_FUNC3_E_LENGTH 4 +#define ADDR_TABLE_FUNC3_E_OFFSET 0 +#define ADDR_TABLE_FUNC3_NR_E 1 + +#define AT_BUSY +#define ADDR_TABLE_FUNC3_AT_BUSY_BOFFSET 31 +#define ADDR_TABLE_FUNC3_AT_BUSY_BLEN 1 +#define ADDR_TABLE_FUNC3_AT_BUSY_FLAG HSL_RW + +#define NEW_PORT_NUM +#define ADDR_TABLE_FUNC3_NEW_PORT_NUM_BOFFSET 22 +#define ADDR_TABLE_FUNC3_NEW_PORT_NUM_BLEN 3 +#define ADDR_TABLE_FUNC3_NEW_PORT_NUM_FLAG HSL_RW + +#define AT_INDEX +#define ADDR_TABLE_FUNC3_AT_INDEX_BOFFSET 16 +#define ADDR_TABLE_FUNC3_AT_INDEX_BLEN 5 +#define ADDR_TABLE_FUNC3_AT_INDEX_FLAG HSL_RW + +#define AT_VID_EN +#define ADDR_TABLE_FUNC3_AT_VID_EN_BOFFSET 15 +#define ADDR_TABLE_FUNC3_AT_VID_EN_BLEN 1 +#define ADDR_TABLE_FUNC3_AT_VID_EN_FLAG HSL_RW + +#define AT_PORT_EN +#define ADDR_TABLE_FUNC3_AT_PORT_EN_BOFFSET 14 +#define ADDR_TABLE_FUNC3_AT_PORT_EN_BLEN 1 +#define ADDR_TABLE_FUNC3_AT_PORT_EN_FLAG HSL_RW + +#define AT_MULTI_EN +#define ADDR_TABLE_FUNC3_AT_MULTI_EN_BOFFSET 13 +#define ADDR_TABLE_FUNC3_AT_MULTI_EN_BLEN 1 +#define ADDR_TABLE_FUNC3_AT_MULTI_EN_FLAG HSL_RW + +#define AT_FULL_VIO +#define ADDR_TABLE_FUNC3_AT_FULL_VIO_BOFFSET 12 +#define ADDR_TABLE_FUNC3_AT_FULL_VIO_BLEN 1 +#define ADDR_TABLE_FUNC3_AT_FULL_VIO_FLAG HSL_RW + +#define AT_PORT_NUM +#define ADDR_TABLE_FUNC3_AT_PORT_NUM_BOFFSET 8 +#define ADDR_TABLE_FUNC3_AT_PORT_NUM_BLEN 4 +#define ADDR_TABLE_FUNC3_AT_PORT_NUM_FLAG HSL_RW + +#define FLUSH_ST_EN +#define ADDR_TABLE_FUNC3_FLUSH_ST_EN_BOFFSET 4 +#define ADDR_TABLE_FUNC3_FLUSH_ST_EN_BLEN 1 +#define ADDR_TABLE_FUNC3_FLUSH_ST_EN_FLAG HSL_RW + +#define AT_FUNC +#define ADDR_TABLE_FUNC3_AT_FUNC_BOFFSET 0 +#define ADDR_TABLE_FUNC3_AT_FUNC_BLEN 4 +#define ADDR_TABLE_FUNC3_AT_FUNC_FLAG HSL_RW + + + + + /* Reserve Address Table0 Register */ +#define RESV_ADDR_TBL0 +#define RESV_ADDR_TBL0_OFFSET 0x3c000 +#define RESV_ADDR_TBL0_E_LENGTH 4 +#define RESV_ADDR_TBL0_E_OFFSET 0 +#define RESV_ADDR_TBL0_NR_E 1 + +#define RESV_ADDR_BYTE2 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE2_BOFFSET 24 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE2_BLEN 8 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE2_FLAG HSL_RW + +#define RESV_ADDR_BYTE3 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE3_BOFFSET 16 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE3_BLEN 8 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE3_FLAG HSL_RW + +#define RESV_ADDR_BYTE4 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE4_BOFFSET 8 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE4_BLEN 8 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE4_FLAG HSL_RW + +#define RESV_ADDR_BYTE5 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE5_BOFFSET 0 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE5_BLEN 8 +#define RESV_ADDR_TBL0_RESV_ADDR_BYTE5_FLAG HSL_RW + + /* Reserve Address Table1 Register */ +#define RESV_ADDR_TBL1 +#define RESV_ADDR_TBL1_OFFSET 0x3c004 +#define RESV_ADDR_TBL1_E_LENGTH 4 +#define RESV_ADDR_TBL1_E_OFFSET 0 +#define RESV_ADDR_TBL1_NR_E 1 + +#define RESV_COPY_TO_CPU +#define RESV_ADDR_TBL1_RESV_COPY_TO_CPU_BOFFSET 31 +#define RESV_ADDR_TBL1_RESV_COPY_TO_CPU_BLEN 1 +#define RESV_ADDR_TBL1_RESV_COPY_TO_CPU_FLAG HSL_RW + +#define RESV_REDRCT_TO_CPU +#define RESV_ADDR_TBL1_RESV_REDRCT_TO_CPU_BOFFSET 30 +#define RESV_ADDR_TBL1_RESV_REDRCT_TO_CPU_BLEN 1 +#define RESV_ADDR_TBL1_RESV_REDRCT_TO_CPU_FLAG HSL_RW + +#define RESV_LEAKY_EN +#define RESV_ADDR_TBL1_RESV_LEAKY_EN_BOFFSET 29 +#define RESV_ADDR_TBL1_RESV_LEAKY_EN_BLEN 1 +#define RESV_ADDR_TBL1_RESV_LEAKY_EN_FLAG HSL_RW + +#define RESV_MIRROR_EN +#define RESV_ADDR_TBL1_RESV_MIRROR_EN_BOFFSET 28 +#define RESV_ADDR_TBL1_RESV_MIRROR_EN_BLEN 1 +#define RESV_ADDR_TBL1_RESV_MIRROR_EN_FLAG HSL_RW + +#define RESV_PRI_EN +#define RESV_ADDR_TBL1_RESV_PRI_EN_BOFFSET 27 +#define RESV_ADDR_TBL1_RESV_PRI_EN_BLEN 1 +#define RESV_ADDR_TBL1_RESV_PRI_EN_FLAG HSL_RW + +#define RESV_PRI +#define RESV_ADDR_TBL1_RESV_PRI_BOFFSET 24 +#define RESV_ADDR_TBL1_RESV_PRI_BLEN 3 +#define RESV_ADDR_TBL1_RESV_PRI_FLAG HSL_RW + +#define RESV_CROSS_PT +#define RESV_ADDR_TBL1_RESV_CROSS_PT_BOFFSET 23 +#define RESV_ADDR_TBL1_RESV_CROSS_PT_BLEN 1 +#define RESV_ADDR_TBL1_RESV_CROSS_PT_FLAG HSL_RW + +#define RESV_DES_PORT +#define RESV_ADDR_TBL1_RESV_DES_PORT_BOFFSET 16 +#define RESV_ADDR_TBL1_RESV_DES_PORT_BLEN 7 +#define RESV_ADDR_TBL1_RESV_DES_PORT_FLAG HSL_RW + +#define RESV_ADDR_BYTE0 +#define RESV_ADDR_TBL1_RESV_ADDR_BYTE0_BOFFSET 8 +#define RESV_ADDR_TBL1_RESV_ADDR_BYTE0_BLEN 8 +#define RESV_ADDR_TBL1_RESV_ADDR_BYTE0_FLAG HSL_RW + +#define RESV_ADDR_BYTE1 +#define RESV_ADDR_TBL1_RESV_ADDR_BYTE1_BOFFSET 0 +#define RESV_ADDR_TBL1_RESV_ADDR_BYTE1_BLEN 8 +#define RESV_ADDR_TBL1_RESV_ADDR_BYTE1_FLAG HSL_RW + + /* Reserve Address Table2 Register */ +#define RESV_ADDR_TBL2 +#define RESV_ADDR_TBL2_OFFSET 0x3c008 +#define RESV_ADDR_TBL2_E_LENGTH 4 +#define RESV_ADDR_TBL2_E_OFFSET 0 +#define RESV_ADDR_TBL2_NR_E 1 + +#define RESV_STATUS +#define RESV_ADDR_TBL2_RESV_STATUS_BOFFSET 0 +#define RESV_ADDR_TBL2_RESV_STATUS_BLEN 1 +#define RESV_ADDR_TBL2_RESV_STATUS_FLAG HSL_RW + + + + + /* Address Table Control Register */ +#define ADDR_TABLE_CTL +#define ADDR_TABLE_CTL_OFFSET 0x0618 +#define ADDR_TABLE_CTL_E_LENGTH 4 +#define ADDR_TABLE_CTL_E_OFFSET 0 +#define ADDR_TABLE_CTL_NR_E 1 + +#define ARL_INI_EN +#define ADDR_TABLE_CTL_ARL_INI_EN_BOFFSET 31 +#define ADDR_TABLE_CTL_ARL_INI_EN_BLEN 1 +#define ADDR_TABLE_CTL_ARL_INI_EN_FLAG HSL_RW + +#define LEARN_CHANGE_EN +#define ADDR_TABLE_CTL_LEARN_CHANGE_EN_BOFFSET 30 +#define ADDR_TABLE_CTL_LEARN_CHANGE_EN_BLEN 1 +#define ADDR_TABLE_CTL_LEARN_CHANGE_EN_FLAG HSL_RW + +#define IGMP_JOIN_LEAKY +#define ADDR_TABLE_CTL_IGMP_JOIN_LEAKY_BOFFSET 29 +#define ADDR_TABLE_CTL_IGMP_JOIN_LEAKY_BLEN 1 +#define ADDR_TABLE_CTL_IGMP_JOIN_LEAKY_FLAG HSL_RW + +#define IGMP_CREAT_EN +#define ADDR_TABLE_CTL_IGMP_CREAT_EN_BOFFSET 28 +#define ADDR_TABLE_CTL_IGMP_CREAT_EN_BLEN 1 +#define ADDR_TABLE_CTL_IGMP_CREAT_EN_FLAG HSL_RW + +#define IGMP_PRI_EN +#define ADDR_TABLE_CTL_IGMP_PRI_EN_BOFFSET 27 +#define ADDR_TABLE_CTL_IGMP_PRI_EN_BLEN 1 +#define ADDR_TABLE_CTL_IGMP_PRI_EN_FLAG HSL_RW + +#define IGMP_PRI +#define ADDR_TABLE_CTL_IGMP_PRI_BOFFSET 24 +#define ADDR_TABLE_CTL_IGMP_PRI_BLEN 3 +#define ADDR_TABLE_CTL_IGMP_PRI_FLAG HSL_RW + +#define IGMP_JOIN_STATIC +#define ADDR_TABLE_CTL_IGMP_JOIN_STATIC_BOFFSET 20 +#define ADDR_TABLE_CTL_IGMP_JOIN_STATIC_BLEN 4 +#define ADDR_TABLE_CTL_IGMP_JOIN_STATIC_FLAG HSL_RW + +#define AGE_EN +#define ADDR_TABLE_CTL_AGE_EN_BOFFSET 19 +#define ADDR_TABLE_CTL_AGE_EN_BLEN 1 +#define ADDR_TABLE_CTL_AGE_EN_FLAG HSL_RW + +#define LOOP_CHECK_TIMER +#define ADDR_TABLE_CTL_LOOP_CHECK_TIMER_BOFFSET 16 +#define ADDR_TABLE_CTL_LOOP_CHECK_TIMER_BLEN 3 +#define ADDR_TABLE_CTL_LOOP_CHECK_TIMER_FLAG HSL_RW + +#define AGE_TIME +#define ADDR_TABLE_CTL_AGE_TIME_BOFFSET 0 +#define ADDR_TABLE_CTL_AGE_TIME_BLEN 16 +#define ADDR_TABLE_CTL_AGE_TIME_FLAG HSL_RW + + + + + /* Global Forward Control0 Register */ +#define FORWARD_CTL0 +#define FORWARD_CTL0_OFFSET 0x0620 +#define FORWARD_CTL0_E_LENGTH 4 +#define FORWARD_CTL0_E_OFFSET 0 +#define FORWARD_CTL0_NR_E 1 + +#define ARP_CMD +#define FORWARD_CTL0_ARP_CMD_BOFFSET 26 +#define FORWARD_CTL0_ARP_CMD_BLEN 2 +#define FORWARD_CTL0_ARP_CMD_FLAG HSL_RW + +#define IP_NOT_FOUND +#define FORWARD_CTL0_IP_NOT_FOUND_BOFFSET 24 +#define FORWARD_CTL0_IP_NOT_FOUND_BLEN 2 +#define FORWARD_CTL0_IP_NOT_FOUND_FLAG HSL_RW + +#define ARP_NOT_FOUND +#define FORWARD_CTL0_ARP_NOT_FOUND_BOFFSET 22 +#define FORWARD_CTL0_ARP_NOT_FOUND_BLEN 2 +#define FORWARD_CTL0_ARP_NOT_FOUND_FLAG HSL_RW + +#define HASH_MODE +#define FORWARD_CTL0_HASH_MODE_BOFFSET 20 +#define FORWARD_CTL0_HASH_MODE_BLEN 2 +#define FORWARD_CTL0_HASH_MODE_FLAG HSL_RW + +#define NAT_NOT_FOUND_DROP +#define FORWARD_CTL0_NAT_NOT_FOUND_DROP_BOFFSET 17 +#define FORWARD_CTL0_NAT_NOT_FOUND_DROP_BLEN 1 +#define FORWARD_CTL0_NAT_NOT_FOUND_DROP_FLAG HSL_RW + +#define SP_NOT_FOUND_DROP +#define FORWARD_CTL0_SP_NOT_FOUND_DROP_BOFFSET 16 +#define FORWARD_CTL0_SP_NOT_FOUND_DROP_BLEN 1 +#define FORWARD_CTL0_SP_NOT_FOUND_DROP_FLAG HSL_RW + +#define IGMP_LEAVE_DROP +#define FORWARD_CTL0_IGMP_LEAVE_DROP_BOFFSET 14 +#define FORWARD_CTL0_IGMP_LEAVE_DROP_BLEN 1 +#define FORWARD_CTL0_IGMP_LEAVE_DROP_FLAG HSL_RW + +#define ARL_UNI_LEAKY +#define FORWARD_CTL0_ARL_UNI_LEAKY_BOFFSET 13 +#define FORWARD_CTL0_ARL_UNI_LEAKY_BLEN 1 +#define FORWARD_CTL0_ARL_UNI_LEAKY_FLAG HSL_RW + +#define ARL_MUL_LEAKY +#define FORWARD_CTL0_ARL_MUL_LEAKY_BOFFSET 12 +#define FORWARD_CTL0_ARL_MUL_LEAKY_BLEN 1 +#define FORWARD_CTL0_ARL_MUL_LEAKY_FLAG HSL_RW + +#define MANAGE_VID_VIO_DROP_EN +#define FORWARD_CTL0_MANAGE_VID_VIO_DROP_EN_BOFFSET 11 +#define FORWARD_CTL0_MANAGE_VID_VIO_DROP_EN_BLEN 1 +#define FORWARD_CTL0_MANAGE_VID_VIO_DROP_EN_FLAG HSL_RW + +#define CPU_PORT_EN +#define FORWARD_CTL0_CPU_PORT_EN_BOFFSET 10 +#define FORWARD_CTL0_CPU_PORT_EN_BLEN 1 +#define FORWARD_CTL0_CPU_PORT_EN_FLAG HSL_RW + +#define PPPOE_RDT_EN +#define FORWARD_CTL0_PPPOE_RDT_EN_BOFFSET 8 +#define FORWARD_CTL0_PPPOE_RDT_EN_BLEN 1 +#define FORWARD_CTL0_PPPOE_RDT_EN_FLAG HSL_RW + +#define MIRROR_PORT_NUM +#define FORWARD_CTL0_MIRROR_PORT_NUM_BOFFSET 4 +#define FORWARD_CTL0_MIRROR_PORT_NUM_BLEN 4 +#define FORWARD_CTL0_MIRROR_PORT_NUM_FLAG HSL_RW + +#define IGMP_COPY_EN +#define FORWARD_CTL0_IGMP_COPY_EN_BOFFSET 3 +#define FORWARD_CTL0_IGMP_COPY_EN_BLEN 1 +#define FORWARD_CTL0_IGMP_COPY_EN_FLAG HSL_RW + +#define RIP_CPY_EN +#define FORWARD_CTL0_RIP_CPY_EN_BOFFSET 2 +#define FORWARD_CTL0_RIP_CPY_EN_BLEN 1 +#define FORWARD_CTL0_RIP_CPY_EN_FLAG HSL_RW + +#define EAPOL_CMD +#define FORWARD_CTL0_EAPOL_CMD_BOFFSET 0 +#define FORWARD_CTL0_EAPOL_CMD_BLEN 1 +#define FORWARD_CTL0_EAPOL_CMD_FLAG HSL_RW + + /* Global Forward Control1 Register */ +#define FORWARD_CTL1 +#define FORWARD_CTL1_OFFSET 0x0624 +#define FORWARD_CTL1_E_LENGTH 4 +#define FORWARD_CTL1_E_OFFSET 0 +#define FORWARD_CTL1_NR_E 1 + +#define IGMP_DP +#define FORWARD_CTL1_IGMP_DP_BOFFSET 24 +#define FORWARD_CTL1_IGMP_DP_BLEN 7 +#define FORWARD_CTL1_IGMP_DP_FLAG HSL_RW + +#define BC_FLOOD_DP +#define FORWARD_CTL1_BC_FLOOD_DP_BOFFSET 16 +#define FORWARD_CTL1_BC_FLOOD_DP_BLEN 7 +#define FORWARD_CTL1_BC_FLOOD_DP_FLAG HSL_RW + +#define MUL_FLOOD_DP +#define FORWARD_CTL1_MUL_FLOOD_DP_BOFFSET 8 +#define FORWARD_CTL1_MUL_FLOOD_DP_BLEN 7 +#define FORWARD_CTL1_MUL_FLOOD_DP_FLAG HSL_RW + +#define UNI_FLOOD_DP +#define FORWARD_CTL1_UNI_FLOOD_DP_BOFFSET 0 +#define FORWARD_CTL1_UNI_FLOOD_DP_BLEN 7 +#define FORWARD_CTL1_UNI_FLOOD_DP_FLAG HSL_RW + + + + + /* Global Learn Limit Ctl Register */ +#define GLOBAL_LEARN_LIMIT_CTL +#define GLOBAL_LEARN_LIMIT_CTL_OFFSET 0x0628 +#define GLOBAL_LEARN_LIMIT_CTL_E_LENGTH 4 +#define GLOBAL_LEARN_LIMIT_CTL_E_OFFSET 0 +#define GLOBAL_LEARN_LIMIT_CTL_NR_E 1 + +#define GOL_SA_LEARN_LIMIT_EN +#define GLOBAL_LEARN_LIMIT_CTL_GOL_SA_LEARN_LIMIT_EN_BOFFSET 12 +#define GLOBAL_LEARN_LIMIT_CTL_GOL_SA_LEARN_LIMIT_EN_BLEN 1 +#define GLOBAL_LEARN_LIMIT_CTL_GOL_SA_LEARN_LIMIT_EN_FLAG HSL_RW + +#define GOL_SA_LEARN_LIMIT_DROP_EN +#define GLOBAL_LEARN_LIMIT_CTL_GOL_SA_LEARN_LIMIT_DROP_EN_BOFFSET 13 +#define GLOBAL_LEARN_LIMIT_CTL_GOL_SA_LEARN_LIMIT_DROP_EN_BLEN 1 +#define GLOBAL_LEARN_LIMIT_CTL_GOL_SA_LEARN_LIMIT_DROP_EN_FLAG HSL_RW + +#define GOL_SA_LEARN_CNT +#define GLOBAL_LEARN_LIMIT_CTL_GOL_SA_LEARN_CNT_BOFFSET 0 +#define GLOBAL_LEARN_LIMIT_CTL_GOL_SA_LEARN_CNT_BLEN 12 +#define GLOBAL_LEARN_LIMIT_CTL_GOL_SA_LEARN_CNT_FLAG HSL_RW + + + + + /* DSCP To Priority Register */ +#define DSCP_TO_PRI +#define DSCP_TO_PRI_OFFSET 0x0630 +#define DSCP_TO_PRI_E_LENGTH 4 +#define DSCP_TO_PRI_E_OFFSET 0x0004 +#define DSCP_TO_PRI_NR_E 8 + + + + + /* UP To Priority Register */ +#define UP_TO_PRI +#define UP_TO_PRI_OFFSET 0x0650 +#define UP_TO_PRI_E_LENGTH 4 +#define UP_TO_PRI_E_OFFSET 0x0004 +#define UP_TO_PRI_NR_E 1 + + + + + /* Port Lookup control Register */ +#define PORT_LOOKUP_CTL +#define PORT_LOOKUP_CTL_OFFSET 0x0660 +#define PORT_LOOKUP_CTL_E_LENGTH 4 +#define PORT_LOOKUP_CTL_E_OFFSET 0x000c +#define PORT_LOOKUP_CTL_NR_E 7 + +#define MULTI_DROP_EN +#define PORT_LOOKUP_CTL_MULTI_DROP_EN_BOFFSET 31 +#define PORT_LOOKUP_CTL_MULTI_DROP_EN_BLEN 1 +#define PORT_LOOKUP_CTL_MULTI_DROP_EN_FLAG HSL_RW + +#define UNI_LEAKY_EN +#define PORT_LOOKUP_CTL_UNI_LEAKY_EN_BOFFSET 28 +#define PORT_LOOKUP_CTL_UNI_LEAKY_EN_BLEN 1 +#define PORT_LOOKUP_CTL_UNI_LEAKY_EN_FLAG HSL_RW + +#define MUL_LEAKY_EN +#define PORT_LOOKUP_CTL_MUL_LEAKY_EN_BOFFSET 27 +#define PORT_LOOKUP_CTL_MUL_LEAKY_EN_BLEN 1 +#define PORT_LOOKUP_CTL_MUL_LEAKY_EN_FLAG HSL_RW + +#define ARP_LEAKY_EN +#define PORT_LOOKUP_CTL_ARP_LEAKY_EN_BOFFSET 26 +#define PORT_LOOKUP_CTL_ARP_LEAKY_EN_BLEN 1 +#define PORT_LOOKUP_CTL_ARP_LEAKY_EN_FLAG HSL_RW + +#define ING_MIRROR_EN +#define PORT_LOOKUP_CTL_ING_MIRROR_EN_BOFFSET 25 +#define PORT_LOOKUP_CTL_ING_MIRROR_EN_BLEN 1 +#define PORT_LOOKUP_CTL_ING_MIRROR_EN_FLAG HSL_RW + +#define PORT_LOOP_BACK +#define PORT_LOOKUP_CTL_PORT_LOOP_BACK_BOFFSET 21 +#define PORT_LOOKUP_CTL_PORT_LOOP_BACK_BLEN 1 +#define PORT_LOOKUP_CTL_PORT_LOOP_BACK_FLAG HSL_RW + +#define LEARN_EN +#define PORT_LOOKUP_CTL_LEARN_EN_BOFFSET 20 +#define PORT_LOOKUP_CTL_LEARN_EN_BLEN 1 +#define PORT_LOOKUP_CTL_LEARN_EN_FLAG HSL_RW + +#define PORT_STATE +#define PORT_LOOKUP_CTL_PORT_STATE_BOFFSET 16 +#define PORT_LOOKUP_CTL_PORT_STATE_BLEN 3 +#define PORT_LOOKUP_CTL_PORT_STATE_FLAG HSL_RW + +#define FORCE_PVLAN +#define PORT_LOOKUP_CTL_FORCE_PVLAN_BOFFSET 10 +#define PORT_LOOKUP_CTL_FORCE_PVLAN_BLEN 1 +#define PORT_LOOKUP_CTL_FORCE_PVLAN_FLAG HSL_RW + +#define DOT1Q_MODE +#define PORT_LOOKUP_CTL_DOT1Q_MODE_BOFFSET 8 +#define PORT_LOOKUP_CTL_DOT1Q_MODE_BLEN 2 +#define PORT_LOOKUP_CTL_DOT1Q_MODE_FLAG HSL_RW + +#define PORT_VID_MEM +#define PORT_LOOKUP_CTL_PORT_VID_MEM_BOFFSET 0 +#define PORT_LOOKUP_CTL_PORT_VID_MEM_BLEN 7 +#define PORT_LOOKUP_CTL_PORT_VID_MEM_FLAG HSL_RW + + + + + /* Priority Control Register */ +#define PRI_CTL +#define PRI_CTL_OFFSET 0x0664 +#define PRI_CTL_E_LENGTH 4 +#define PRI_CTL_E_OFFSET 0x000c +#define PRI_CTL_NR_E 7 + +#define EG_MAC_BASE_VLAN_EN +#define PRI_CTL_EG_MAC_BASE_VLAN_EN_BOFFSET 20 +#define PRI_CTL_EG_MAC_BASE_VLAN_EN_BLEN 1 +#define PRI_CTL_EG_MAC_BASE_VLAN_EN_FLAG HSL_RW + +#define DA_PRI_EN +#define PRI_CTL_DA_PRI_EN_BOFFSET 18 +#define PRI_CTL_DA_PRI_EN_BLEN 1 +#define PRI_CTL_DA_PRI_EN_FLAG HSL_RW + +#define VLAN_PRI_EN +#define PRI_CTL_VLAN_PRI_EN_BOFFSET 17 +#define PRI_CTL_VLAN_PRI_EN_BLEN 1 +#define PRI_CTL_VLAN_PRI_EN_FLAG HSL_RW + +#define IP_PRI_EN +#define PRI_CTL_IP_PRI_EN_BOFFSET 16 +#define PRI_CTL_IP_PRI_EN_BLEN 1 +#define PRI_CTL_IP_PRI_EN_FLAG HSL_RW + +#define DA_PRI_SEL +#define PRI_CTL_DA_PRI_SEL_BOFFSET 6 +#define PRI_CTL_DA_PRI_SEL_BLEN 2 +#define PRI_CTL_DA_PRI_SEL_FLAG HSL_RW + +#define VLAN_PRI_SEL +#define PRI_CTL_VLAN_PRI_SEL_BOFFSET 4 +#define PRI_CTL_VLAN_PRI_SEL_BLEN 2 +#define PRI_CTL_VLAN_PRI_SEL_FLAG HSL_RW + +#define IP_PRI_SEL +#define PRI_CTL_IP_PRI_SEL_BOFFSET 2 +#define PRI_CTL_IP_PRI_SEL_BLEN 2 +#define PRI_CTL_IP_PRI_SEL_FLAG HSL_RW + + + + /* Port Learn Limit Ctl Register */ +#define PORT_LEARN_LIMIT_CTL +#define PORT_LEARN_LIMIT_CTL_OFFSET 0x0668 +#define PORT_LEARN_LIMIT_CTL_E_LENGTH 4 +#define PORT_LEARN_LIMIT_CTL_E_OFFSET 0x000c +#define PORT_LEARN_LIMIT_CTL_NR_E 7 + +#define IGMP_JOIN_LIMIT_DROP_EN +#define PORT_LEARN_LIMIT_CTL_IGMP_JOIN_LIMIT_DROP_EN_BOFFSET 29 +#define PORT_LEARN_LIMIT_CTL_IGMP_JOIN_LIMIT_DROP_EN_BLEN 1 +#define PORT_LEARN_LIMIT_CTL_IGMP_JOIN_LIMIT_DROP_EN_FLAG HSL_RW + +#define SA_LEARN_LIMIT_DROP_EN +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_LIMIT_DROP_EN_BOFFSET 28 +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_LIMIT_DROP_EN_BLEN 1 +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_LIMIT_DROP_EN_FLAG HSL_RW + +#define IGMP_JOIN_LIMIT_EN +#define PORT_LEARN_LIMIT_CTL_IGMP_JOIN_LIMIT_EN_BOFFSET 27 +#define PORT_LEARN_LIMIT_CTL_IGMP_JOIN_LIMIT_EN_BLEN 1 +#define PORT_LEARN_LIMIT_CTL_IGMP_JOIN_LIMIT_EN_FLAG HSL_RW + +#define IGMP_JOIN_CNT +#define PORT_LEARN_LIMIT_CTL_IGMP_JOIN_CNT_BOFFSET 16 +#define PORT_LEARN_LIMIT_CTL_IGMP_JOIN_CNT_BLEN 11 +#define PORT_LEARN_LIMIT_CTL_IGMP_JOIN_CNT_FLAG HSL_RW + +#define SA_LEARN_STATUS +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_STATUS_BOFFSET 12 +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_STATUS_BLEN 4 +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_STATUS_FLAG HSL_RW + +#define SA_LEARN_LIMIT_EN +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_LIMIT_EN_BOFFSET 11 +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_LIMIT_EN_BLEN 1 +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_LIMIT_EN_FLAG HSL_RW + +#define SA_LEARN_CNT +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_CNT_BOFFSET 0 +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_CNT_BLEN 11 +#define PORT_LEARN_LIMIT_CTL_SA_LEARN_CNT_FLAG HSL_RW + + + + /* Global Trunk Ctl0 Register */ +#define GOL_TRUNK_CTL0 +#define GOL_TRUNK_CTL0_OFFSET 0x0700 +#define GOL_TRUNK_CTL0_E_LENGTH 4 +#define GOL_TRUNK_CTL0_E_OFFSET 0x4 +#define GOL_TRUNK_CTL0_NR_E 1 + + + /* Global Trunk Ctl1 Register */ +#define GOL_TRUNK_CTL1 +#define GOL_TRUNK_CTL1_OFFSET 0x0704 +#define GOL_TRUNK_CTL1_E_LENGTH 4 +#define GOL_TRUNK_CTL1_E_OFFSET 0x4 +#define GOL_TRUNK_CTL1_NR_E 2 + + + /* ACL Forward source filter Register */ +#define ACL_FWD_SRC_FILTER_CTL0 +#define ACL_FWD_SRC_FILTER_CTL0_OFFSET 0x0710 +#define ACL_FWD_SRC_FILTER_CTL0_E_LENGTH 4 +#define ACL_FWD_SRC_FILTER_CTL0_E_OFFSET 0x4 +#define ACL_FWD_SRC_FILTER_CTL0_NR_E 3 + + + /* VLAN translation register */ +#define VLAN_TRANS +#define VLAN_TRANS_OFFSET 0x0418 +#define VLAN_TRANS_E_LENGTH 4 +#define VLAN_TRANS_E_OFFSET 0 +#define VLAN_TRANS_NR_E 7 + +#define EG_FLTR_BYPASS_EN +#define VLAN_TRANS_EG_FLTR_BYPASS_EN_BOFFSET 1 +#define VLAN_TRANS_EG_FLTR_BYPASS_EN_BLEN 1 +#define VLAN_TRANS_EG_FLTR_BYPASS_EN_FLAG HSL_RW + +#define NET_ISO +#define VLAN_TRANS_NET_ISO_BOFFSET 0 +#define VLAN_TRANS_NET_ISO_BLEN 1 +#define VLAN_TRANS_NET_ISO_FLAG HSL_RW + + + /* Port vlan0 Register */ +#define PORT_VLAN0 +#define PORT_VLAN0_OFFSET 0x0420 +#define PORT_VLAN0_E_LENGTH 4 +#define PORT_VLAN0_E_OFFSET 0x0008 +#define PORT_VLAN0_NR_E 7 + +#define ING_CPRI +#define PORT_VLAN0_ING_CPRI_BOFFSET 29 +#define PORT_VLAN0_ING_CPRI_BLEN 3 +#define PORT_VLAN0_ING_CPRI_FLAG HSL_RW + +#define ING_FORCE_CPRI +#define PORT_VLAN0_ING_FORCE_CPRI_BOFFSET 28 +#define PORT_VLAN0_ING_FORCE_CPRI_BLEN 1 +#define PORT_VLAN0_ING_FORCE_CPRI_FLAG HSL_RW + +#define DEF_CVID +#define PORT_VLAN0_DEF_CVID_BOFFSET 16 +#define PORT_VLAN0_DEF_CVID_BLEN 12 +#define PORT_VLAN0_DEF_CVID_FLAG HSL_RW + +#define ING_SPRI +#define PORT_VLAN0_ING_SPRI_BOFFSET 13 +#define PORT_VLAN0_ING_SPRI_BLEN 3 +#define PORT_VLAN0_ING_SPRI_FLAG HSL_RW + +#define ING_FORCE_SPRI +#define PORT_VLAN0_ING_FORCE_SPRI_BOFFSET 12 +#define PORT_VLAN0_ING_FORCE_SPRI_BLEN 1 +#define PORT_VLAN0_ING_FORCE_SPRI_FLAG HSL_RW + +#define DEF_SVID +#define PORT_VLAN0_DEF_SVID_BOFFSET 0 +#define PORT_VLAN0_DEF_SVID_BLEN 12 +#define PORT_VLAN0_DEF_SVID_FLAG HSL_RW + + /* Port vlan1 Register */ +#define PORT_VLAN1 +#define PORT_VLAN1_OFFSET 0x0424 +#define PORT_VLAN1_E_LENGTH 4 +#define PORT_VLAN1_E_OFFSET 0x0008 +#define PORT_VLAN1_NR_E 7 + +#define EG_VLAN_MODE +#define PORT_VLAN1_EG_VLAN_MODE_BOFFSET 12 +#define PORT_VLAN1_EG_VLAN_MODE_BLEN 2 +#define PORT_VLAN1_EG_VLAN_MODE_FLAG HSL_RW + +#define VLAN_DIS +#define PORT_VLAN1_VLAN_DIS_BOFFSET 11 +#define PORT_VLAN1_VLAN_DIS_BLEN 1 +#define PORT_VLAN1_VLAN_DIS_FLAG HSL_RW + +#define SP_CHECK_EN +#define PORT_VLAN1_SP_CHECK_EN_BOFFSET 10 +#define PORT_VLAN1_SP_CHECK_EN_BLEN 1 +#define PORT_VLAN1_SP_CHECK_EN_FLAG HSL_RW + +#define COREP_EN +#define PORT_VLAN1_COREP_EN_BOFFSET 9 +#define PORT_VLAN1_COREP_EN_BLEN 1 +#define PORT_VLAN1_COREP_EN_FLAG HSL_RW + +#define FORCE_DEF_VID +#define PORT_VLAN1_FORCE_DEF_VID_BOFFSET 8 +#define PORT_VLAN1_FORCE_DEF_VID_BLEN 1 +#define PORT_VLAN1_FORCE_DEF_VID_FLAG HSL_RW + +#define TLS_EN +#define PORT_VLAN1_TLS_EN_BOFFSET 7 +#define PORT_VLAN1_TLS_EN_BLEN 1 +#define PORT_VLAN1_TLS_EN_FLAG HSL_RW + +#define PROPAGATION_EN +#define PORT_VLAN1_PROPAGATION_EN_BOFFSET 6 +#define PORT_VLAN1_PROPAGATION_EN_BLEN 1 +#define PORT_VLAN1_PROPAGATION_EN_FLAG HSL_RW + +#define CLONE +#define PORT_VLAN1_CLONE_BOFFSET 5 +#define PORT_VLAN1_CLONE_BLEN 1 +#define PORT_VLAN1_CLONE_FLAG HSL_RW + +#define PRI_PROPAGATION +#define PORT_VLAN1_PRI_PROPAGATION_BOFFSET 4 +#define PORT_VLAN1_PRI_PROPAGATION_BLEN 1 +#define PORT_VLAN1_VLAN_PRI_PROPAGATION_FLAG HSL_RW + +#define IN_VLAN_MODE +#define PORT_VLAN1_IN_VLAN_MODE_BOFFSET 2 +#define PORT_VLAN1_IN_VLAN_MODE_BLEN 2 +#define PORT_VLAN1_IN_VLAN_MODE_FLAG HSL_RW + + + /* Route Default VID Register */ +#define ROUTER_DEFV +#define ROUTER_DEFV_OFFSET 0x0c70 +#define ROUTER_DEFV_E_LENGTH 4 +#define ROUTER_DEFV_E_OFFSET 0x0004 +#define ROUTER_DEFV_NR_E 4 + + + /* Route Egress VLAN Mode Register */ +#define ROUTER_EG +#define ROUTER_EG_OFFSET 0x0c80 +#define ROUTER_EG_E_LENGTH 4 +#define ROUTER_EG_E_OFFSET 0x0004 +#define ROUTER_EG_NR_E 1 + + + + + /* Mdio control Register */ +#define MDIO_CTRL "mctrl" +#define MDIO_CTRL_ID 24 +#define MDIO_CTRL_OFFSET 0x0098 +#define MDIO_CTRL_E_LENGTH 4 +#define MDIO_CTRL_E_OFFSET 0 +#define MDIO_CTRL_NR_E 1 + +#define MSTER_EN "mctrl_msteren" +#define MDIO_CTRL_MSTER_EN_BOFFSET 30 +#define MDIO_CTRL_MSTER_EN_BLEN 1 +#define MDIO_CTRL_MSTER_EN_FLAG HSL_RW + +#define MSTER_EN "mctrl_msteren" +#define MDIO_CTRL_MSTER_EN_BOFFSET 30 +#define MDIO_CTRL_MSTER_EN_BLEN 1 +#define MDIO_CTRL_MSTER_EN_FLAG HSL_RW + +#define CMD "mctrl_cmd" +#define MDIO_CTRL_CMD_BOFFSET 27 +#define MDIO_CTRL_CMD_BLEN 1 +#define MDIO_CTRL_CMD_FLAG HSL_RW + +#define SUP_PRE "mctrl_spre" +#define MDIO_CTRL_SUP_PRE_BOFFSET 26 +#define MDIO_CTRL_SUP_PRE_BLEN 1 +#define MDIO_CTRL_SUP_PRE_FLAG HSL_RW + +#define PHY_ADDR "mctrl_phyaddr" +#define MDIO_CTRL_PHY_ADDR_BOFFSET 21 +#define MDIO_CTRL_PHY_ADDR_BLEN 5 +#define MDIO_CTRL_PHY_ADDR_FLAG HSL_RW + +#define REG_ADDR "mctrl_regaddr" +#define MDIO_CTRL_REG_ADDR_BOFFSET 16 +#define MDIO_CTRL_REG_ADDR_BLEN 5 +#define MDIO_CTRL_REG_ADDR_FLAG HSL_RW + +#define DATA "mctrl_data" +#define MDIO_CTRL_DATA_BOFFSET 0 +#define MDIO_CTRL_DATA_BLEN 16 +#define MDIO_CTRL_DATA_FLAG HSL_RW + + + + + /* BIST control Register */ +#define BIST_CTRL "bctrl" +#define BIST_CTRL_ID 24 +#define BIST_CTRL_OFFSET 0x00a0 +#define BIST_CTRL_E_LENGTH 4 +#define BIST_CTRL_E_OFFSET 0 +#define BIST_CTRL_NR_E 1 + +#define BIST_BUSY "bctrl_bb" +#define BIST_CTRL_BIST_BUSY_BOFFSET 31 +#define BIST_CTRL_BIST_BUSY_BLEN 1 +#define BIST_CTRL_BIST_BUSY_FLAG HSL_RW + +#define ONE_ERR "bctrl_oe" +#define BIST_CTRL_ONE_ERR_BOFFSET 30 +#define BIST_CTRL_ONE_ERR_BLEN 1 +#define BIST_CTRL_ONE_ERR_FLAG HSL_RO + +#define ERR_MEM "bctrl_em" +#define BIST_CTRL_ERR_MEM_BOFFSET 24 +#define BIST_CTRL_ERR_MEM_BLEN 4 +#define BIST_CTRL_ERR_MEM_FLAG HSL_RO + +#define PTN_EN2 "bctrl_pe2" +#define BIST_CTRL_PTN_EN2_BOFFSET 22 +#define BIST_CTRL_PTN_EN2_BLEN 1 +#define BIST_CTRL_PTN_EN2_FLAG HSL_RW + +#define PTN_EN1 "bctrl_pe1" +#define BIST_CTRL_PTN_EN1_BOFFSET 21 +#define BIST_CTRL_PTN_EN1_BLEN 1 +#define BIST_CTRL_PTN_EN1_FLAG HSL_RW + +#define PTN_EN0 "bctrl_pe0" +#define BIST_CTRL_PTN_EN0_BOFFSET 20 +#define BIST_CTRL_PTN_EN0_BLEN 1 +#define BIST_CTRL_PTN_EN0_FLAG HSL_RW + +#define ERR_PTN "bctrl_ep" +#define BIST_CTRL_ERR_PTN_BOFFSET 16 +#define BIST_CTRL_ERR_PTN_BLEN 2 +#define BIST_CTRL_ERR_PTN_FLAG HSL_RO + +#define ERR_CNT "bctrl_ec" +#define BIST_CTRL_ERR_CNT_BOFFSET 13 +#define BIST_CTRL_ERR_CNT_BLEN 2 +#define BIST_CTRL_ERR_CNT_FLAG HSL_RO + +#define ERR_ADDR "bctrl_ea" +#define BIST_CTRL_ERR_ADDR_BOFFSET 0 +#define BIST_CTRL_ERR_ADDR_BLEN 12 +#define BIST_CTRL_ERR_ADDR_FLAG HSL_RO + + + + + /* BIST recover Register */ +#define BIST_RCV "brcv" +#define BIST_RCV_ID 24 +#define BIST_RCV_OFFSET 0x00a4 +#define BIST_RCV_E_LENGTH 4 +#define BIST_RCV_E_OFFSET 0 +#define BIST_RCV_NR_E 1 + +#define RCV_EN "brcv_en" +#define BIST_RCV_RCV_EN_BOFFSET 31 +#define BIST_RCV_RCV_EN_BLEN 1 +#define BIST_RCV_RCV_EN_FLAG HSL_RW + +#define RCV_ADDR "brcv_addr" +#define BIST_RCV_RCV_ADDR_BOFFSET 0 +#define BIST_RCV_RCV_ADDR_BLEN 12 +#define BIST_RCV_RCV_ADDR_FLAG HSL_RW + + + + + /* LED control Register */ +#define LED_CTRL "ledctrl" +#define LED_CTRL_ID 25 +#define LED_CTRL_OFFSET 0x0050 +#define LED_CTRL_E_LENGTH 4 +#define LED_CTRL_E_OFFSET 0 +#define LED_CTRL_NR_E 3 + +#define PATTERN_EN "lctrl_pen" +#define LED_CTRL_PATTERN_EN_BOFFSET 14 +#define LED_CTRL_PATTERN_EN_BLEN 2 +#define LED_CTRL_PATTERN_EN_FLAG HSL_RW + +#define FULL_LIGHT_EN "lctrl_fen" +#define LED_CTRL_FULL_LIGHT_EN_BOFFSET 13 +#define LED_CTRL_FULL_LIGHT_EN_BLEN 1 +#define LED_CTRL_FULL_LIGHT_EN_FLAG HSL_RW + +#define HALF_LIGHT_EN "lctrl_hen" +#define LED_CTRL_HALF_LIGHT_EN_BOFFSET 12 +#define LED_CTRL_HALF_LIGHT_EN_BLEN 1 +#define LED_CTRL_HALF_LIGHT_EN_FLAG HSL_RW + +#define POWERON_LIGHT_EN "lctrl_poen" +#define LED_CTRL_POWERON_LIGHT_EN_BOFFSET 11 +#define LED_CTRL_POWERON_LIGHT_EN_BLEN 1 +#define LED_CTRL_POWERON_LIGHT_EN_FLAG HSL_RW + +#define GE_LIGHT_EN "lctrl_geen" +#define LED_CTRL_GE_LIGHT_EN_BOFFSET 10 +#define LED_CTRL_GE_LIGHT_EN_BLEN 1 +#define LED_CTRL_GE_LIGHT_EN_FLAG HSL_RW + +#define FE_LIGHT_EN "lctrl_feen" +#define LED_CTRL_FE_LIGHT_EN_BOFFSET 9 +#define LED_CTRL_FE_LIGHT_EN_BLEN 1 +#define LED_CTRL_FE_LIGHT_EN_FLAG HSL_RW + +#define ETH_LIGHT_EN "lctrl_ethen" +#define LED_CTRL_ETH_LIGHT_EN_BOFFSET 8 +#define LED_CTRL_ETH_LIGHT_EN_BLEN 1 +#define LED_CTRL_ETH_LIGHT_EN_FLAG HSL_RW + +#define COL_BLINK_EN "lctrl_cen" +#define LED_CTRL_COL_BLINK_EN_BOFFSET 7 +#define LED_CTRL_COL_BLINK_EN_BLEN 1 +#define LED_CTRL_COL_BLINK_EN_FLAG HSL_RW + +#define RX_BLINK_EN "lctrl_rxen" +#define LED_CTRL_RX_BLINK_EN_BOFFSET 5 +#define LED_CTRL_RX_BLINK_EN_BLEN 1 +#define LED_CTRL_RX_BLINK_EN_FLAG HSL_RW + +#define TX_BLINK_EN "lctrl_txen" +#define LED_CTRL_TX_BLINK_EN_BOFFSET 4 +#define LED_CTRL_TX_BLINK_EN_BLEN 1 +#define LED_CTRL_TX_BLINK_EN_FLAG HSL_RW + +#define LINKUP_OVER_EN "lctrl_loen" +#define LED_CTRL_LINKUP_OVER_EN_BOFFSET 2 +#define LED_CTRL_LINKUP_OVER_EN_BLEN 1 +#define LED_CTRL_LINKUP_OVER_EN_FLAG HSL_RW + +#define BLINK_FREQ "lctrl_bfreq" +#define LED_CTRL_BLINK_FREQ_BOFFSET 0 +#define LED_CTRL_BLINK_FREQ_BLEN 2 +#define LED_CTRL_BLINK_FREQ_FLAG HSL_RW + + /* LED control Register */ +#define LED_PATTERN "ledpatten" +#define LED_PATTERN_ID 25 +#define LED_PATTERN_OFFSET 0x005c +#define LED_PATTERN_E_LENGTH 4 +#define LED_PATTERN_E_OFFSET 0 +#define LED_PATTERN_NR_E 1 + + +#define P3L2_MODE +#define LED_PATTERN_P3L2_MODE_BOFFSET 24 +#define LED_PATTERN_P3L2_MODE_BLEN 2 +#define LED_PATTERN_P3L2_MODE_FLAG HSL_RW + +#define P3L1_MODE +#define LED_PATTERN_P3L1_MODE_BOFFSET 22 +#define LED_PATTERN_P3L1_MODE_BLEN 2 +#define LED_PATTERN_P3L1_MODE_FLAG HSL_RW + +#define P3L0_MODE +#define LED_PATTERN_P3L0_MODE_BOFFSET 20 +#define LED_PATTERN_P3L0_MODE_BLEN 2 +#define LED_PATTERN_P3L0_MODE_FLAG HSL_RW + +#define P2L2_MODE +#define LED_PATTERN_P2L2_MODE_BOFFSET 18 +#define LED_PATTERN_P2L2_MODE_BLEN 2 +#define LED_PATTERN_P2L2_MODE_FLAG HSL_RW + +#define P2L1_MODE +#define LED_PATTERN_P2L1_MODE_BOFFSET 16 +#define LED_PATTERN_P2L1_MODE_BLEN 2 +#define LED_PATTERN_P2L1_MODE_FLAG HSL_RW + +#define P2L0_MODE +#define LED_PATTERN_P2L0_MODE_BOFFSET 14 +#define LED_PATTERN_P2L0_MODE_BLEN 2 +#define LED_PATTERN_P2L0_MODE_FLAG HSL_RW + +#define P1L2_MODE +#define LED_PATTERN_P1L2_MODE_BOFFSET 12 +#define LED_PATTERN_P1L2_MODE_BLEN 2 +#define LED_PATTERN_P1L2_MODE_FLAG HSL_RW + +#define P1L1_MODE +#define LED_PATTERN_P1L1_MODE_BOFFSET 10 +#define LED_PATTERN_P1L1_MODE_BLEN 2 +#define LED_PATTERN_P1L1_MODE_FLAG HSL_RW + +#define P1L0_MODE +#define LED_PATTERN_P1L0_MODE_BOFFSET 8 +#define LED_PATTERN_P1L0_MODE_BLEN 2 +#define LED_PATTERN_P1L0_MODE_FLAG HSL_RW + + + + + /* Pri To Queue Register */ +#define PRI_TO_QUEUE +#define PRI_TO_QUEUE_OFFSET 0x0814 +#define PRI_TO_QUEUE_E_LENGTH 4 +#define PRI_TO_QUEUE_E_OFFSET 0x0004 +#define PRI_TO_QUEUE_NR_E 1 + + + + + /* Pri To EhQueue Register */ +#define PRI_TO_EHQUEUE +#define PRI_TO_EHQUEUE_OFFSET 0x0810 +#define PRI_TO_EHQUEUE_E_LENGTH 4 +#define PRI_TO_EHQUEUE_E_OFFSET 0x0004 +#define PRI_TO_EHQUEUE_NR_E 1 + + + + + /*Global Flow Control Register*/ +#define QM_CTRL_REG +#define QM_CTRL_REG_OFFSET 0X0808 +#define QM_CTRL_REG_E_LENGTH 4 +#define QM_CTRL_REG_E_OFFSET 0x0004 +#define QM_CTRL_REG_NR_E 1 + +#define GOL_FLOW_EN +#define QM_CTRL_REG_GOL_FLOW_EN_BOFFSET 16 +#define QM_CTRL_REG_GOL_FLOW_EN_BLEN 7 +#define QM_CTRL_REG_GOL_FLOW_EN_FLAG HSL_RW + +#define QM_FUNC_TEST +#define QM_CTRL_REG_QM_FUNC_TEST_BOFFSET 10 +#define QM_CTRL_REG_QM_FUNC_TEST_BLEN 1 +#define QM_CTRL_REG_QM_FUNC_TEST_FLAG HSL_RW + +#define RATE_DROP_EN +#define QM_CTRL_REG_RATE_DROP_EN_BOFFSET 7 +#define QM_CTRL_REG_RATE_DROP_EN_BLEN 1 +#define QM_CTRL_REG_RATE_DROP_EN_FLAG HSL_RW + +#define FLOW_DROP_EN +#define QM_CTRL_REG_FLOW_DROP_EN_BOFFSET 6 +#define QM_CTRL_REG_FLOW_DROP_EN_BLEN 1 +#define QM_CTRL_REG_FLOW_DROP_EN_FLAG HSL_RW + +#define FLOW_DROP_CNT +#define QM_CTRL_REG_FLOW_DROP_CNT_BOFFSET 0 +#define QM_CTRL_REG_FLOW_DROP_CNT_BLEN 6 +#define QM_CTRL_REG_FLOW_DROP_CNT_FLAG HSL_RW + + + + + /* Port HOL CTL0 Register */ +#define PORT_HOL_CTL0 +#define PORT_HOL_CTL0_OFFSET 0x0970 +#define PORT_HOL_CTL0_E_LENGTH 4 +#define PORT_HOL_CTL0_E_OFFSET 0x0008 +#define PORT_HOL_CTL0_NR_E 7 + +#define PORT_DESC_NR +#define PORT_HOL_CTL0_PORT_DESC_NR_BOFFSET 24 +#define PORT_HOL_CTL0_PORT_DESC_NR_BLEN 6 +#define PORT_HOL_CTL0_PORT_DESC_NR_FLAG HSL_RW + +#define QUEUE5_DESC_NR +#define PORT_HOL_CTL0_QUEUE5_DESC_NR_BOFFSET 20 +#define PORT_HOL_CTL0_QUEUE5_DESC_NR_BLEN 4 +#define PORT_HOL_CTL0_QUEUE5_DESC_NR_FLAG HSL_RW + +#define QUEUE4_DESC_NR +#define PORT_HOL_CTL0_QUEUE4_DESC_NR_BOFFSET 16 +#define PORT_HOL_CTL0_QUEUE4_DESC_NR_BLEN 4 +#define PORT_HOL_CTL0_QUEUE4_DESC_NR_FLAG HSL_RW + +#define QUEUE3_DESC_NR +#define PORT_HOL_CTL0_QUEUE3_DESC_NR_BOFFSET 12 +#define PORT_HOL_CTL0_QUEUE3_DESC_NR_BLEN 4 +#define PORT_HOL_CTL0_QUEUE3_DESC_NR_FLAG HSL_RW + +#define QUEUE2_DESC_NR +#define PORT_HOL_CTL0_QUEUE2_DESC_NR_BOFFSET 8 +#define PORT_HOL_CTL0_QUEUE2_DESC_NR_BLEN 4 +#define PORT_HOL_CTL0_QUEUE2_DESC_NR_FLAG HSL_RW + +#define QUEUE1_DESC_NR +#define PORT_HOL_CTL0_QUEUE1_DESC_NR_BOFFSET 4 +#define PORT_HOL_CTL0_QUEUE1_DESC_NR_BLEN 4 +#define PORT_HOL_CTL0_QUEUE1_DESC_NR_FLAG HSL_RW + +#define QUEUE0_DESC_NR +#define PORT_HOL_CTL0_QUEUE0_DESC_NR_BOFFSET 0 +#define PORT_HOL_CTL0_QUEUE0_DESC_NR_BLEN 4 +#define PORT_HOL_CTL0_QUEUE0_DESC_NR_FLAG HSL_RW + + /* Port HOL CTL1 Register */ +#define PORT_HOL_CTL1 +#define PORT_HOL_CTL1_OFFSET 0x0974 +#define PORT_HOL_CTL1_E_LENGTH 4 +#define PORT_HOL_CTL1_E_OFFSET 0x0008 +#define PORT_HOL_CTL1_NR_E 7 + +#define EG_MIRROR_EN +#define PORT_HOL_CTL1_EG_MIRROR_EN_BOFFSET 16 +#define PORT_HOL_CTL1_EG_MIRROR_EN_BLEN 1 +#define PORT_HOL_CTL1_EG_MIRROR_EN_FLAG HSL_RW + +#define PORT_RED_EN +#define PORT_HOL_CTL1_PORT_RED_EN_BOFFSET 8 +#define PORT_HOL_CTL1_PORT_RED_EN_BLEN 1 +#define PORT_HOL_CTL1_PORT_RED_EN_FLAG HSL_RW + +#define PORT_DESC_EN +#define PORT_HOL_CTL1_PORT_DESC_EN_BOFFSET 7 +#define PORT_HOL_CTL1_PORT_DESC_EN_BLEN 1 +#define PORT_HOL_CTL1_PORT_DESC_EN_FLAG HSL_RW + +#define QUEUE_DESC_EN +#define PORT_HOL_CTL1_QUEUE_DESC_EN_BOFFSET 6 +#define PORT_HOL_CTL1_QUEUE_DESC_EN_BLEN 1 +#define PORT_HOL_CTL1_QUEUE_DESC_EN_FLAG HSL_RW + +#define PORT_IN_DESC_EN +#define PORT_HOL_CTL1_PORT_IN_DESC_EN_BOFFSET 0 +#define PORT_HOL_CTL1_PORT_IN_DESC_EN_BLEN 4 +#define PORT_HOL_CTL1_PORT_IN_DESC_EN_FLAG HSL_RW + + /* PORT FLOW CTRL THRESHOLD REGISTER */ +#define PORT_FLOW_CTRL_THRESHOLD +#define PORT_FLOW_CTRL_THRESHOLD_OFFSET 0x09B0 +#define PORT_FLOW_CTRL_THRESHOLD_E_LENGTH 4 +#define PORT_FLOW_CTRL_THRESHOLD_E_OFFSET 0x0004 +#define PORT_FLOW_CTRL_THRESHOLD_NR_E 7 + +#define XON_THRES +#define PORT_FLOW_CTRL_THRESHOLD_XON_THRES_BOFFSET 16 +#define PORT_FLOW_CTRL_THRESHOLD_XON_THRES_BLEN 8 +#define PORT_FLOW_CTRL_THRESHOLD_XON_THRES_FLAG HSL_RW + +#define XOFF_THRES +#define PORT_FLOW_CTRL_THRESHOLD_XOFF_THRES_BOFFSET 0 +#define PORT_FLOW_CTRL_THRESHOLD_XOFF_THRES_BLEN 8 +#define PORT_FLOW_CTRL_THRESHOLD_XOFF_THRES_FLAG HSL_RW + + /* FX100 CTRL Register */ +#define FX100_CTRL +#define FX100_CTRL_OFFSET 0x00fc +#define FX100_CTRL_E_LENGTH 4 +#define FX100_CTRL_E_OFFSET 0X0004 +#define FX100_CTRL_NR_E 1 + +#define FX100_STATUS +#define FX100_CTRL_FX100_STATUS_BOFFSET 24 +#define FX100_CTRL_FX100_STATUS_BLEN 8 +#define FX100_CTRL_FX100_STATUS_FLAG HSL_RO + +#define FX100_LOOP_EN +#define FX100_CTRL_FX100_LOOP_EN_BOFFSET 23 +#define FX100_CTRL_FX100_LOOP_EN_BLEN 1 +#define FX100_CTRL_FX100_LOOP_EN_FLAG HSL_Rw + +#define SGMII_FIBER +#define FX100_CTRL_SGMII_FIBER_BOFFSET 15 +#define FX100_CTRL_SGMII_FIBER_BLEN 2 +#define FX100_CTRL_SGMII_FIBER_FLAG HSL_Rw + +#define CRS_COL_100_CTRL +#define FX100_CTRL_CRS_COL_100_CTRL_BOFFSET 14 +#define FX100_CTRL_CRS_COL_100_CTRL_BLEN 1 +#define FX100_CTRL_CRS_COL_100_CTRL_FLAG HSL_Rw + +#define LOOPBACK_TEST +#define FX100_CTRL_LOOPBACK_TEST_BOFFSET 13 +#define FX100_CTRL_LOOPBACK_TEST_BLEN 1 +#define FX100_CTRL_LOOPBACK_TEST_FLAG HSL_Rw + +#define CRS_CTRL +#define FX100_CTRL_CRS_CTRL_BOFFSET 12 +#define FX100_CTRL_CRS_CTRL_BLEN 1 +#define FX100_CTRL_CRS_CTRL_FLAG HSL_Rw + +#define COL_TEST +#define FX100_CTRL_COL_TEST_BOFFSET 11 +#define FX100_CTRL_COL_TEST_BLEN 1 +#define FX100_CTRL_COL_TEST_FLAG HSL_Rw + +#define FD_MODE +#define FX100_CTRL_FD_MODE_BOFFSET 10 +#define FX100_CTRL_FD_MODE_BLEN 1 +#define FX100_CTRL_FD_MODE_FLAG HSL_Rw + +#define LINK_CTRL +#define FX100_CTRL_LINK_CTRL_BOFFSET 8 +#define FX100_CTRL_LINK_CTRL_BLEN 2 +#define FX100_CTRL_LINK_CTRL_FLAG HSL_Rw + +#define OVERSHOOT_MODE +#define FX100_CTRL_OVERSHOOT_MODE_BOFFSET 6 +#define FX100_CTRL_OVERSHOOT_MODE_BLEN 1 +#define FX100_CTRL_OVERSHOOT_MODE_FLAG HSL_Rw + +#define LOOPBACK_MODE +#define FX100_CTRL_LOOPBACK_MODE_BOFFSET 3 +#define FX100_CTRL_LOOPBACK_MODE_BLEN 1 +#define FX100_CTRL_LOOPBACK_MODE_FLAG HSL_Rw + + + + /* Port Rate Limit0 Register */ +#define RATE_LIMIT0 "rlmt0" +#define RATE_LIMIT0_ID 32 +#define RATE_LIMIT0_OFFSET 0x0110 +#define RATE_LIMIT0_E_LENGTH 4 +#define RATE_LIMIT0_E_OFFSET 0x0100 +#define RATE_LIMIT0_NR_E 7 + + +#define EG_RATE_EN "rlmt_egen" +#define RATE_LIMIT0_EG_RATE_EN_BOFFSET 23 +#define RATE_LIMIT0_EG_RATE_EN_BLEN 1 +#define RATE_LIMIT0_EG_RATE_EN_FLAG HSL_RW + +#define EG_MNG_RATE_EN "rlmt_egmngen" +#define RATE_LIMIT0_EG_MNG_RATE_EN_BOFFSET 22 +#define RATE_LIMIT0_EG_MNG_RATE_EN_BLEN 1 +#define RATE_LIMIT0_EG_MNG_RATE_EN_FLAG HSL_RW + +#define IN_MNG_RATE_EN "rlmt_inmngen" +#define RATE_LIMIT0_IN_MNG_RATE_EN_BOFFSET 21 +#define RATE_LIMIT0_IN_MNG_RATE_EN_BLEN 1 +#define RATE_LIMIT0_IN_MNG_RATE_EN_FLAG HSL_RW + +#define IN_MUL_RATE_EN "rlmt_inmulen" +#define RATE_LIMIT0_IN_MUL_RATE_EN_BOFFSET 20 +#define RATE_LIMIT0_IN_MUL_RATE_EN_BLEN 1 +#define RATE_LIMIT0_IN_MUL_RATE_EN_FLAG HSL_RW + +#define ING_RATE "rlmt_ingrate" +#define RATE_LIMIT0_ING_RATE_BOFFSET 0 +#define RATE_LIMIT0_ING_RATE_BLEN 15 +#define RATE_LIMIT0_ING_RATE_FLAG HSL_RW + + + + /* PKT edit control register */ +#define PKT_CTRL +#define PKT_CTRL_OFFSET 0x0c00 +#define PKT_CTRL_E_LENGTH 4 +#define PKT_CTRL_E_OFFSET 0 +#define PKT_CTRL_NR_E 7 + +#define CPU_VID_EN +#define PKT_CTRL_CPU_VID_EN_BOFFSET 1 +#define PKT_CTRL_CPU_VID_EN_BLEN 1 +#define PKT_CTRL_CPU_VID_EN_FLAG HSL_RW + + +#define RTD_PPPOE_EN +#define PKT_CTRL_RTD_PPPOE_EN_BOFFSET 0 +#define PKT_CTRL_RTD_PPPOE_EN_BLEN 1 +#define PKT_CTRL_RTD_PPPOE_EN_FLAG HSL_RW + + + + + /* mib memory info */ +#define MIB_RXBROAD +#define MIB_RXBROAD_OFFSET 0x01000 +#define MIB_RXBROAD_E_LENGTH 4 +#define MIB_RXBROAD_E_OFFSET 0x100 +#define MIB_RXBROAD_NR_E 7 + +#define MIB_RXPAUSE +#define MIB_RXPAUSE_OFFSET 0x01004 +#define MIB_RXPAUSE_E_LENGTH 4 +#define MIB_RXPAUSE_E_OFFSET 0x100 +#define MIB_RXPAUSE_NR_E 7 + +#define MIB_RXMULTI +#define MIB_RXMULTI_OFFSET 0x01008 +#define MIB_RXMULTI_E_LENGTH 4 +#define MIB_RXMULTI_E_OFFSET 0x100 +#define MIB_RXMULTI_NR_E 7 + +#define MIB_RXFCSERR +#define MIB_RXFCSERR_OFFSET 0x0100c +#define MIB_RXFCSERR_E_LENGTH 4 +#define MIB_RXFCSERR_E_OFFSET 0x100 +#define MIB_RXFCSERR_NR_E 7 + +#define MIB_RXALLIGNERR +#define MIB_RXALLIGNERR_OFFSET 0x01010 +#define MIB_RXALLIGNERR_E_LENGTH 4 +#define MIB_RXALLIGNERR_E_OFFSET 0x100 +#define MIB_RXALLIGNERR_NR_E 7 + +#define MIB_RXRUNT +#define MIB_RXRUNT_OFFSET 0x01014 +#define MIB_RXRUNT_E_LENGTH 4 +#define MIB_RXRUNT_E_OFFSET 0x100 +#define MIB_RXRUNT_NR_E 7 + +#define MIB_RXFRAGMENT +#define MIB_RXFRAGMENT_OFFSET 0x01018 +#define MIB_RXFRAGMENT_E_LENGTH 4 +#define MIB_RXFRAGMENT_E_OFFSET 0x100 +#define MIB_RXFRAGMENT_NR_E 7 + +#define MIB_RX64BYTE +#define MIB_RX64BYTE_OFFSET 0x0101c +#define MIB_RX64BYTE_E_LENGTH 4 +#define MIB_RX64BYTE_E_OFFSET 0x100 +#define MIB_RX64BYTE_NR_E 7 + +#define MIB_RX128BYTE +#define MIB_RX128BYTE_OFFSET 0x01020 +#define MIB_RX128BYTE_E_LENGTH 4 +#define MIB_RX128BYTE_E_OFFSET 0x100 +#define MIB_RX128BYTE_NR_E 7 + +#define MIB_RX256BYTE +#define MIB_RX256BYTE_OFFSET 0x01024 +#define MIB_RX256BYTE_E_LENGTH 4 +#define MIB_RX256BYTE_E_OFFSET 0x100 +#define MIB_RX256BYTE_NR_E 7 + +#define MIB_RX512BYTE +#define MIB_RX512BYTE_OFFSET 0x01028 +#define MIB_RX512BYTE_E_LENGTH 4 +#define MIB_RX512BYTE_E_OFFSET 0x100 +#define MIB_RX512BYTE_NR_E 7 + +#define MIB_RX1024BYTE +#define MIB_RX1024BYTE_OFFSET 0x0102c +#define MIB_RX1024BYTE_E_LENGTH 4 +#define MIB_RX1024BYTE_E_OFFSET 0x100 +#define MIB_RX1024BYTE_NR_E 7 + +#define MIB_RX1518BYTE +#define MIB_RX1518BYTE_OFFSET 0x01030 +#define MIB_RX1518BYTE_E_LENGTH 4 +#define MIB_RX1518BYTE_E_OFFSET 0x100 +#define MIB_RX1518BYTE_NR_E 7 + +#define MIB_RXMAXBYTE +#define MIB_RXMAXBYTE_OFFSET 0x01034 +#define MIB_RXMAXBYTE_E_LENGTH 4 +#define MIB_RXMAXBYTE_E_OFFSET 0x100 +#define MIB_RXMAXBYTE_NR_E 7 + +#define MIB_RXTOOLONG +#define MIB_RXTOOLONG_OFFSET 0x01038 +#define MIB_RXTOOLONG_E_LENGTH 4 +#define MIB_RXTOOLONG_E_OFFSET 0x100 +#define MIB_RXTOOLONG_NR_E 7 + +#define MIB_RXGOODBYTE_LO +#define MIB_RXGOODBYTE_LO_OFFSET 0x0103c +#define MIB_RXGOODBYTE_LO_E_LENGTH 4 +#define MIB_RXGOODBYTE_LO_E_OFFSET 0x100 +#define MIB_RXGOODBYTE_LO_NR_E 7 + +#define MIB_RXGOODBYTE_HI +#define MIB_RXGOODBYTE_HI_OFFSET 0x01040 +#define MIB_RXGOODBYTE_HI_E_LENGTH 4 +#define MIB_RXGOODBYTE_HI_E_OFFSET 0x100 +#define MIB_RXGOODBYTE_HI_NR_E 7 + +#define MIB_RXBADBYTE_LO +#define MIB_RXBADBYTE_LO_OFFSET 0x01044 +#define MIB_RXBADBYTE_LO_E_LENGTH 4 +#define MIB_RXBADBYTE_LO_E_OFFSET 0x100 +#define MIB_RXBADBYTE_LO_NR_E 7 + +#define MIB_RXBADBYTE_HI +#define MIB_RXBADBYTE_HI_OFFSET 0x01048 +#define MIB_RXBADBYTE_HI_E_LENGTH 4 +#define MIB_RXBADBYTE_HI_E_OFFSET 0x100 +#define MIB_RXBADBYTE_HI_NR_E 7 + +#define MIB_RXOVERFLOW +#define MIB_RXOVERFLOW_OFFSET 0x0104c +#define MIB_RXOVERFLOW_E_LENGTH 4 +#define MIB_RXOVERFLOW_E_OFFSET 0x100 +#define MIB_RXOVERFLOW_NR_E 7 + +#define MIB_FILTERED +#define MIB_FILTERED_OFFSET 0x01050 +#define MIB_FILTERED_E_LENGTH 4 +#define MIB_FILTERED_E_OFFSET 0x100 +#define MIB_FILTERED_NR_E 7 + +#define MIB_TXBROAD +#define MIB_TXBROAD_OFFSET 0x01054 +#define MIB_TXBROAD_E_LENGTH 4 +#define MIB_TXBROAD_E_OFFSET 0x100 +#define MIB_TXBROAD_NR_E 7 + +#define MIB_TXPAUSE +#define MIB_TXPAUSE_OFFSET 0x01058 +#define MIB_TXPAUSE_E_LENGTH 4 +#define MIB_TXPAUSE_E_OFFSET 0x100 +#define MIB_TXPAUSE_NR_E 7 + +#define MIB_TXMULTI +#define MIB_TXMULTI_OFFSET 0x0105c +#define MIB_TXMULTI_E_LENGTH 4 +#define MIB_TXMULTI_E_OFFSET 0x100 +#define MIB_TXMULTI_NR_E 7 + +#define MIB_TXUNDERRUN +#define MIB_TXUNDERRUN_OFFSET 0x01060 +#define MIB_TXUNDERRUN_E_LENGTH 4 +#define MIB_TXUNDERRUN_E_OFFSET 0x100 +#define MIB_TXUNDERRUN_NR_E 7 + +#define MIB_TX64BYTE +#define MIB_TX64BYTE_OFFSET 0x01064 +#define MIB_TX64BYTE_E_LENGTH 4 +#define MIB_TX64BYTE_E_OFFSET 0x100 +#define MIB_TX64BYTE_NR_E 7 + +#define MIB_TX128BYTE +#define MIB_TX128BYTE_OFFSET 0x01068 +#define MIB_TX128BYTE_E_LENGTH 4 +#define MIB_TX128BYTE_E_OFFSET 0x100 +#define MIB_TX128BYTE_NR_E 7 + +#define MIB_TX256BYTE +#define MIB_TX256BYTE_OFFSET 0x0106c +#define MIB_TX256BYTE_E_LENGTH 4 +#define MIB_TX256BYTE_E_OFFSET 0x100 +#define MIB_TX256BYTE_NR_E 7 + +#define MIB_TX512BYTE +#define MIB_TX512BYTE_OFFSET 0x01070 +#define MIB_TX512BYTE_E_LENGTH 4 +#define MIB_TX512BYTE_E_OFFSET 0x100 +#define MIB_TX512BYTE_NR_E 7 + +#define MIB_TX1024BYTE +#define MIB_TX1024BYTE_OFFSET 0x01074 +#define MIB_TX1024BYTE_E_LENGTH 4 +#define MIB_TX1024BYTE_E_OFFSET 0x100 +#define MIB_TX1024BYTE_NR_E 7 + +#define MIB_TX1518BYTE +#define MIB_TX1518BYTE_OFFSET 0x01078 +#define MIB_TX1518BYTE_E_LENGTH 4 +#define MIB_TX1518BYTE_E_OFFSET 0x100 +#define MIB_TX1518BYTE_NR_E 7 + +#define MIB_TXMAXBYTE +#define MIB_TXMAXBYTE_OFFSET 0x0107c +#define MIB_TXMAXBYTE_E_LENGTH 4 +#define MIB_TXMAXBYTE_E_OFFSET 0x100 +#define MIB_TXMAXBYTE_NR_E 7 + +#define MIB_TXOVERSIZE +#define MIB_TXOVERSIZE_OFFSET 0x01080 +#define MIB_TXOVERSIZE_E_LENGTH 4 +#define MIB_TXOVERSIZE_E_OFFSET 0x100 +#define MIB_TXOVERSIZE_NR_E 7 + +#define MIB_TXBYTE_LO +#define MIB_TXBYTE_LO_OFFSET 0x01084 +#define MIB_TXBYTE_LO_E_LENGTH 4 +#define MIB_TXBYTE_LO_E_OFFSET 0x100 +#define MIB_TXBYTE_LO_NR_E 7 + +#define MIB_TXBYTE_HI +#define MIB_TXBYTE_HI_OFFSET 0x01088 +#define MIB_TXBYTE_HI_E_LENGTH 4 +#define MIB_TXBYTE_HI_E_OFFSET 0x100 +#define MIB_TXBYTE_HI_NR_E 7 + +#define MIB_TXCOLLISION +#define MIB_TXCOLLISION_OFFSET 0x0108c +#define MIB_TXCOLLISION_E_LENGTH 4 +#define MIB_TXCOLLISION_E_OFFSET 0x100 +#define MIB_TXCOLLISION_NR_E 7 + +#define MIB_TXABORTCOL +#define MIB_TXABORTCOL_OFFSET 0x01090 +#define MIB_TXABORTCOL_E_LENGTH 4 +#define MIB_TXABORTCOL_E_OFFSET 0x100 +#define MIB_TXABORTCOL_NR_E 7 + +#define MIB_TXMULTICOL +#define MIB_TXMULTICOL_OFFSET 0x01094 +#define MIB_TXMULTICOL_E_LENGTH 4 +#define MIB_TXMULTICOL_E_OFFSET 0x100 +#define MIB_TXMULTICOL_NR_E 7 + +#define MIB_TXSINGALCOL +#define MIB_TXSINGALCOL_OFFSET 0x01098 +#define MIB_TXSINGALCOL_E_LENGTH 4 +#define MIB_TXSINGALCOL_E_OFFSET 0x100 +#define MIB_TXSINGALCOL_NR_E 7 + +#define MIB_TXEXCDEFER +#define MIB_TXEXCDEFER_OFFSET 0x0109c +#define MIB_TXEXCDEFER_E_LENGTH 4 +#define MIB_TXEXCDEFER_E_OFFSET 0x100 +#define MIB_TXEXCDEFER_NR_E 7 + +#define MIB_TXDEFER +#define MIB_TXDEFER_OFFSET 0x010a0 +#define MIB_TXDEFER_E_LENGTH 4 +#define MIB_TXDEFER_E_OFFSET 0x100 +#define MIB_TXDEFER_NR_E 7 + +#define MIB_TXLATECOL +#define MIB_TXLATECOL_OFFSET 0x010a4 +#define MIB_TXLATECOL_E_LENGTH 4 +#define MIB_TXLATECOL_E_OFFSET 0x100 +#define MIB_TXLATECOL_NR_E 7 + +#define MIB_RXUNICAST +#define MIB_RXUNICAST_OFFSET 0x010a8 +#define MIB_RXUNICAST_E_LENGTH 4 +#define MIB_RXUNICAST_E_OFFSET 0x100 +#define MIB_RXUNICAST_NR_E 7 + +#define MIB_TXUNICAST +#define MIB_TXUNICAST_OFFSET 0x010ac +#define MIB_TXUNICAST_E_LENGTH 4 +#define MIB_TXUNICAST_E_OFFSET 0x100 +#define MIB_TXUNICAST_NR_E 7 + + /* ACL Action Register */ +#define ACL_RSLT0 10 +#define ACL_RSLT0_OFFSET 0x5a000 +#define ACL_RSLT0_E_LENGTH 4 +#define ACL_RSLT0_E_OFFSET 0x10 +#define ACL_RSLT0_NR_E 96 + +#define CTAGPRI +#define ACL_RSLT0_CTAGPRI_BOFFSET 29 +#define ACL_RSLT0_CTAGPRI_BLEN 3 +#define ACL_RSLT0_CTAGPRI_FLAG HSL_RW + +#define CTAGCFI +#define ACL_RSLT0_CTAGCFI_BOFFSET 28 +#define ACL_RSLT0_CTAGCFI_BLEN 1 +#define ACL_RSLT0_CTAGCFI_FLAG HSL_RW + +#define CTAGVID +#define ACL_RSLT0_CTAGVID_BOFFSET 16 +#define ACL_RSLT0_CTAGVID_BLEN 12 +#define ACL_RSLT0_CTAGVID_FLAG HSL_RW + +#define STAGPRI +#define ACL_RSLT0_STAGPRI_BOFFSET 13 +#define ACL_RSLT0_STAGPRI_BLEN 3 +#define ACL_RSLT0_STAGPRI_FLAG HSL_RW + +#define STAGDEI +#define ACL_RSLT0_STAGDEI_BOFFSET 12 +#define ACL_RSLT0_STAGDEI_BLEN 1 +#define ACL_RSLT0_STAGDEI_FLAG HSL_RW + +#define STAGVID +#define ACL_RSLT0_STAGVID_BOFFSET 0 +#define ACL_RSLT0_STAGVID_BLEN 12 +#define ACL_RSLT0_STAGVID_FLAG HSL_RW + + +#define ACL_RSLT1 11 +#define ACL_RSLT1_OFFSET 0x5a004 +#define ACL_RSLT1_E_LENGTH 4 +#define ACL_RSLT1_E_OFFSET 0x10 +#define ACL_RSLT1_NR_E 96 + +#define DES_PORT0 +#define ACL_RSLT1_DES_PORT0_BOFFSET 29 +#define ACL_RSLT1_DES_PORT0_BLEN 3 +#define ACL_RSLT1_DES_PORT0_FLAG HSL_RW + +#define PRI_QU_EN +#define ACL_RSLT1_PRI_QU_EN_BOFFSET 28 +#define ACL_RSLT1_PRI_QU_EN_BLEN 1 +#define ACL_RSLT1_PRI_QU_EN_FLAG HSL_RW + +#define PRI_QU +#define ACL_RSLT1_PRI_QU_BOFFSET 25 +#define ACL_RSLT1_PRI_QU_BLEN 3 +#define ACL_RSLT1_PRI_QU_FLAG HSL_RW + +#define WCMP_EN +#define ACL_RSLT1_WCMP_EN_BOFFSET 24 +#define ACL_RSLT1_WCMP_EN_BLEN 1 +#define ACL_RSLT1_WCMP_EN_FLAG HSL_RW + +#define ARP_PTR +#define ACL_RSLT1_ARP_PTR_BOFFSET 17 +#define ACL_RSLT1_ARP_PTR_BLEN 7 +#define ACL_RSLT1_ARP_PTR_FLAG HSL_RW + +#define ARP_PTR_EN +#define ACL_RSLT1_ARP_PTR_EN_BOFFSET 16 +#define ACL_RSLT1_ARP_PTR_EN_BLEN 1 +#define ACL_RSLT1_ARP_PTR_EN_FLAG HSL_RW + +#define FORCE_L3_MODE +#define ACL_RSLT1_FORCE_L3_MODE_BOFFSET 14 +#define ACL_RSLT1_FORCE_L3_MODE_BLEN 2 +#define ACL_RSLT1_FORCE_L3_MODE_FLAG HSL_RW + +#define LOOK_VID_CHG +#define ACL_RSLT1_LOOK_VID_CHG_BOFFSET 13 +#define ACL_RSLT1_LOOK_VID_CHG_BLEN 1 +#define ACL_RSLT1_LOOK_VID_CHG_FLAG HSL_RW + +#define TRANS_CVID_CHG +#define ACL_RSLT1_TRANS_CVID_CHG_BOFFSET 12 +#define ACL_RSLT1_TRANS_CVID_CHG_BLEN 1 +#define ACL_RSLT1_TRANS_CVID_CHG_FLAG HSL_RW + +#define TRANS_SVID_CHG +#define ACL_RSLT1_TRANS_SVID_CHG_BOFFSET 11 +#define ACL_RSLT1_TRANS_SVID_CHG_BLEN 1 +#define ACL_RSLT1_TRANS_SVID_CHG_FLAG HSL_RW + +#define CTAG_CFI_CHG +#define ACL_RSLT1_CTAG_CFI_CHG_BOFFSET 10 +#define ACL_RSLT1_CTAG_CFI_CHG_BLEN 1 +#define ACL_RSLT1_CTAG_CFI_CHG_FLAG HSL_RW + +#define CTAG_PRI_REMAP +#define ACL_RSLT1_CTAG_PRI_REMAP_BOFFSET 9 +#define ACL_RSLT1_CTAG_PRI_REMAP_BLEN 1 +#define ACL_RSLT1_CTAG_PRI_REMAP_FLAG HSL_RW + +#define STAG_DEI_CHG +#define ACL_RSLT1_STAG_DEI_CHG_BOFFSET 8 +#define ACL_RSLT1_STAG_DEI_CHG_BLEN 1 +#define ACL_RSLT1_STAG_DEI_CHG_FLAG HSL_RW + +#define STAG_PRI_REMAP +#define ACL_RSLT1_STAG_PRI_REMAP_BOFFSET 7 +#define ACL_RSLT1_STAG_PRI_REMAP_BLEN 1 +#define ACL_RSLT1_STAG_PRI_REMAP_FLAG HSL_RW + +#define DSCP_REMAP +#define ACL_RSLT1_DSCP_REMAP_BOFFSET 6 +#define ACL_RSLT1_DSCP_REMAP_BLEN 1 +#define ACL_RSLT1_DSCP_REMAP_FLAG HSL_RW + +#define DSCPV +#define ACL_RSLT1_DSCPV_BOFFSET 0 +#define ACL_RSLT1_DSCPV_BLEN 6 +#define ACL_RSLT1_DSCPV_FLAG HSL_RW + +#define ACL_RSLT2 12 +#define ACL_RSLT2_OFFSET 0x5a008 +#define ACL_RSLT2_E_LENGTH 4 +#define ACL_RSLT2_E_OFFSET 0x10 +#define ACL_RSLT2_NR_E 96 + +#define TRIGGER_INTR +#define ACL_RSLT2_TRIGGER_INTR_BOFFSET 16 +#define ACL_RSLT2_TRIGGER_INTR_BLEN 1 +#define ACL_RSLT2_TRIGGER_INTR_FLAG HSL_RW + +#define EG_BYPASS +#define ACL_RSLT2_EG_BYPASS_BOFFSET 15 +#define ACL_RSLT2_EG_BYPASS_BLEN 1 +#define ACL_RSLT2_EG_BYPASS_FLAG HSL_RW + +#define POLICER_EN +#define ACL_RSLT2_POLICER_EN_BOFFSET 14 +#define ACL_RSLT2_POLICER_EN_BLEN 1 +#define ACL_RSLT2_POLICER_EN_FLAG HSL_RW + +#define POLICER_PTR +#define ACL_RSLT2_POLICER_PTR_BOFFSET 9 +#define ACL_RSLT2_POLICER_PTR_BLEN 5 +#define ACL_RSLT2_POLICER_PTR_FLAG HSL_RW + +#define FWD_CMD +#define ACL_RSLT2_FWD_CMD_BOFFSET 6 +#define ACL_RSLT2_FWD_CMD_BLEN 3 +#define ACL_RSLT2_FWD_CMD_FLAG HSL_RW + +#define MIRR_EN +#define ACL_RSLT2_MIRR_EN_BOFFSET 5 +#define ACL_RSLT2_MIRR_EN_BLEN 1 +#define ACL_RSLT2_MIRR_EN_FLAG HSL_RW + +#define DES_PORT_EN +#define ACL_RSLT2_DES_PORT_EN_BOFFSET 4 +#define ACL_RSLT2_DES_PORT_EN_BLEN 1 +#define ACL_RSLT2_DES_PORT_EN_FLAG HSL_RW + +#define DES_PORT1 +#define ACL_RSLT2_DES_PORT1_BOFFSET 0 +#define ACL_RSLT2_DES_PORT1_BLEN 4 +#define ACL_RSLT2_DES_PORT1_FLAG HSL_RW + + + + + /* MAC Type Rule Field Define */ +#define MAC_RUL_V0 0 +#define MAC_RUL_V0_OFFSET 0x58000 +#define MAC_RUL_V0_E_LENGTH 4 +#define MAC_RUL_V0_E_OFFSET 0x20 +#define MAC_RUL_V0_NR_E 96 + +#define DAV_BYTE2 +#define MAC_RUL_V0_DAV_BYTE2_BOFFSET 24 +#define MAC_RUL_V0_DAV_BYTE2_BLEN 8 +#define MAC_RUL_V0_DAV_BYTE2_FLAG HSL_RW + +#define DAV_BYTE3 +#define MAC_RUL_V0_DAV_BYTE3_BOFFSET 16 +#define MAC_RUL_V0_DAV_BYTE3_BLEN 8 +#define MAC_RUL_V0_DAV_BYTE3_FLAG HSL_RW + +#define DAV_BYTE4 +#define MAC_RUL_V0_DAV_BYTE4_BOFFSET 8 +#define MAC_RUL_V0_DAV_BYTE4_BLEN 8 +#define MAC_RUL_V0_DAV_BYTE4_FLAG HSL_RW + +#define DAV_BYTE5 +#define MAC_RUL_V0_DAV_BYTE5_BOFFSET 0 +#define MAC_RUL_V0_DAV_BYTE5_BLEN 8 +#define MAC_RUL_V0_DAV_BYTE5_FLAG HSL_RW + + +#define MAC_RUL_V1 1 +#define MAC_RUL_V1_OFFSET 0x58004 +#define MAC_RUL_V1_E_LENGTH 4 +#define MAC_RUL_V1_E_OFFSET 0x20 +#define MAC_RUL_V1_NR_E 96 + +#define SAV_BYTE4 +#define MAC_RUL_V1_SAV_BYTE4_BOFFSET 24 +#define MAC_RUL_V1_SAV_BYTE4_BLEN 8 +#define MAC_RUL_V1_SAV_BYTE4_FLAG HSL_RW + +#define SAV_BYTE5 +#define MAC_RUL_V1_SAV_BYTE5_BOFFSET 16 +#define MAC_RUL_V1_SAV_BYTE5_BLEN 8 +#define MAC_RUL_V1_SAV_BYTE5_FLAG HSL_RW + +#define DAV_BYTE0 +#define MAC_RUL_V1_DAV_BYTE0_BOFFSET 8 +#define MAC_RUL_V1_DAV_BYTE0_BLEN 8 +#define MAC_RUL_V1_DAV_BYTE0_FLAG HSL_RW + +#define DAV_BYTE1 +#define MAC_RUL_V1_DAV_BYTE1_BOFFSET 0 +#define MAC_RUL_V1_DAV_BYTE1_BLEN 8 +#define MAC_RUL_V1_DAV_BYTE1_FLAG HSL_RW + + +#define MAC_RUL_V2 2 +#define MAC_RUL_V2_OFFSET 0x58008 +#define MAC_RUL_V2_E_LENGTH 4 +#define MAC_RUL_V2_E_OFFSET 0x20 +#define MAC_RUL_V2_NR_E 96 + +#define SAV_BYTE0 +#define MAC_RUL_V2_SAV_BYTE0_BOFFSET 24 +#define MAC_RUL_V2_SAV_BYTE0_BLEN 8 +#define MAC_RUL_V2_SAV_BYTE0_FLAG HSL_RW + +#define SAV_BYTE1 +#define MAC_RUL_V2_SAV_BYTE1_BOFFSET 16 +#define MAC_RUL_V2_SAV_BYTE1_BLEN 8 +#define MAC_RUL_V2_SAV_BYTE1_FLAG HSL_RW + +#define SAV_BYTE2 +#define MAC_RUL_V2_SAV_BYTE2_BOFFSET 8 +#define MAC_RUL_V2_SAV_BYTE2_BLEN 8 +#define MAC_RUL_V2_SAV_BYTE2_FLAG HSL_RW + +#define SAV_BYTE3 +#define MAC_RUL_V2_SAV_BYTE3_BOFFSET 0 +#define MAC_RUL_V2_SAV_BYTE3_BLEN 8 +#define MAC_RUL_V2_SAV_BYTE3_FLAG HSL_RW + + +#define MAC_RUL_V3 3 +#define MAC_RUL_V3_ID 13 +#define MAC_RUL_V3_OFFSET 0x5800c +#define MAC_RUL_V3_E_LENGTH 4 +#define MAC_RUL_V3_E_OFFSET 0x20 +#define MAC_RUL_V3_NR_E 96 + +#define ETHTYPV +#define MAC_RUL_V3_ETHTYPV_BOFFSET 16 +#define MAC_RUL_V3_ETHTYPV_BLEN 16 +#define MAC_RUL_V3_ETHTYPV_FLAG HSL_RW + +#define VLANPRIV +#define MAC_RUL_V3_VLANPRIV_BOFFSET 13 +#define MAC_RUL_V3_VLANPRIV_BLEN 3 +#define MAC_RUL_V3_VLANPRIV_FLAG HSL_RW + +#define VLANCFIV +#define MAC_RUL_V3_VLANCFIV_BOFFSET 12 +#define MAC_RUL_V3_VLANCFIV_BLEN 1 +#define MAC_RUL_V3_VLANCFIV_FLAG HSL_RW + +#define VLANIDV +#define MAC_RUL_V3_VLANIDV_BOFFSET 0 +#define MAC_RUL_V3_VLANIDV_BLEN 12 +#define MAC_RUL_V3_VLANIDV_FLAG HSL_RW + + +#define MAC_RUL_V4 4 +#define MAC_RUL_V4_OFFSET 0x58010 +#define MAC_RUL_V4_E_LENGTH 4 +#define MAC_RUL_V4_E_OFFSET 0x20 +#define MAC_RUL_V4_NR_E 96 + +#define RULE_INV +#define MAC_RUL_V4_RULE_INV_BOFFSET 7 +#define MAC_RUL_V4_RULE_INV_BLEN 1 +#define MAC_RUL_V4_RULE_INV_FLAG HSL_RW + +#define SRC_PT +#define MAC_RUL_V4_SRC_PT_BOFFSET 0 +#define MAC_RUL_V4_SRC_PT_BLEN 7 +#define MAC_RUL_V4_SRC_PT_FLAG HSL_RW + + +#define MAC_RUL_M0 5 +#define MAC_RUL_M0_OFFSET 0x59000 +#define MAC_RUL_M0_E_LENGTH 4 +#define MAC_RUL_M0_E_OFFSET 0x20 +#define MAC_RUL_M0_NR_E 96 + +#define DAM_BYTE2 +#define MAC_RUL_M0_DAM_BYTE2_BOFFSET 24 +#define MAC_RUL_M0_DAM_BYTE2_BLEN 8 +#define MAC_RUL_M0_DAM_BYTE2_FLAG HSL_RW + +#define DAM_BYTE3 +#define MAC_RUL_M0_DAM_BYTE3_BOFFSET 16 +#define MAC_RUL_M0_DAM_BYTE3_BLEN 8 +#define MAC_RUL_M0_DAM_BYTE3_FLAG HSL_RW + +#define DAM_BYTE4 +#define MAC_RUL_M0_DAM_BYTE4_BOFFSET 8 +#define MAC_RUL_M0_DAM_BYTE4_BLEN 8 +#define MAC_RUL_M0_DAM_BYTE4_FLAG HSL_RW + +#define DAM_BYTE5 +#define MAC_RUL_M0_DAM_BYTE5_BOFFSET 0 +#define MAC_RUL_M0_DAM_BYTE5_BLEN 8 +#define MAC_RUL_M0_DAM_BYTE5_FLAG HSL_RW + + +#define MAC_RUL_M1 6 +#define MAC_RUL_M1_OFFSET 0x59004 +#define MAC_RUL_M1_E_LENGTH 4 +#define MAC_RUL_M1_E_OFFSET 0x20 +#define MAC_RUL_M1_NR_E 96 + +#define SAM_BYTE4 +#define MAC_RUL_M1_SAM_BYTE4_BOFFSET 24 +#define MAC_RUL_M1_SAM_BYTE4_BLEN 8 +#define MAC_RUL_M1_SAM_BYTE4_FLAG HSL_RW + +#define SAM_BYTE5 +#define MAC_RUL_M1_SAM_BYTE5_BOFFSET 16 +#define MAC_RUL_M1_SAM_BYTE5_BLEN 8 +#define MAC_RUL_M1_SAM_BYTE5_FLAG HSL_RW + +#define DAM_BYTE0 +#define MAC_RUL_M1_DAM_BYTE0_BOFFSET 8 +#define MAC_RUL_M1_DAM_BYTE0_BLEN 8 +#define MAC_RUL_M1_DAM_BYTE0_FLAG HSL_RW + +#define DAM_BYTE1 +#define MAC_RUL_M1_DAM_BYTE1_BOFFSET 0 +#define MAC_RUL_M1_DAM_BYTE1_BLEN 8 +#define MAC_RUL_M1_DAM_BYTE1_FLAG HSL_RW + + +#define MAC_RUL_M2 7 +#define MAC_RUL_M2_OFFSET 0x59008 +#define MAC_RUL_M2_E_LENGTH 4 +#define MAC_RUL_M2_E_OFFSET 0x20 +#define MAC_RUL_M2_NR_E 96 + +#define SAM_BYTE0 +#define MAC_RUL_M2_SAM_BYTE0_BOFFSET 24 +#define MAC_RUL_M2_SAM_BYTE0_BLEN 8 +#define MAC_RUL_M2_SAM_BYTE0_FLAG HSL_RW + +#define SAM_BYTE1 +#define MAC_RUL_M2_SAM_BYTE1_BOFFSET 16 +#define MAC_RUL_M2_SAM_BYTE1_BLEN 8 +#define MAC_RUL_M2_SAM_BYTE1_FLAG HSL_RW + +#define SAM_BYTE2 +#define MAC_RUL_M2_SAM_BYTE2_BOFFSET 8 +#define MAC_RUL_M2_SAM_BYTE2_BLEN 8 +#define MAC_RUL_M2_SAM_BYTE2_FLAG HSL_RW + +#define SAM_BYTE3 +#define MAC_RUL_M2_SAM_BYTE3_BOFFSET 0 +#define MAC_RUL_M2_SAM_BYTE3_BLEN 8 +#define MAC_RUL_M2_SAM_BYTE3_FLAG HSL_RW + + +#define MAC_RUL_M3 8 +#define MAC_RUL_M3_OFFSET 0x5900c +#define MAC_RUL_M3_E_LENGTH 4 +#define MAC_RUL_M3_E_OFFSET 0x20 +#define MAC_RUL_M3_NR_E 96 + +#define ETHTYPM +#define MAC_RUL_M3_ETHTYPM_BOFFSET 16 +#define MAC_RUL_M3_ETHTYPM_BLEN 16 +#define MAC_RUL_M3_ETHTYPM_FLAG HSL_RW + +#define VLANPRIM +#define MAC_RUL_M3_VLANPRIM_BOFFSET 13 +#define MAC_RUL_M3_VLANPRIM_BLEN 3 +#define MAC_RUL_M3_VLANPRIM_FLAG HSL_RW + +#define VLANCFIM +#define MAC_RUL_M3_VLANCFIM_BOFFSET 12 +#define MAC_RUL_M3_VLANCFIM_BLEN 1 +#define MAC_RUL_M3_VLANCFIM_FLAG HSL_RW + +#define VLANIDM +#define MAC_RUL_M3_VLANIDM_BOFFSET 0 +#define MAC_RUL_M3_VLANIDM_BLEN 12 +#define MAC_RUL_M3_VLANIDM_FLAG HSL_RW + + +#define MAC_RUL_M4 9 +#define MAC_RUL_M4_OFFSET 0x59010 +#define MAC_RUL_M4_E_LENGTH 4 +#define MAC_RUL_M4_E_OFFSET 0x20 +#define MAC_RUL_M4_NR_E 96 + +#define RULE_VALID +#define MAC_RUL_M4_RULE_VALID_BOFFSET 6 +#define MAC_RUL_M4_RULE_VALID_BLEN 2 +#define MAC_RUL_M4_RULE_VALID_FLAG HSL_RW + +#define TAGGEDM +#define MAC_RUL_M4_TAGGEDM_BOFFSET 5 +#define MAC_RUL_M4_TAGGEDM_BLEN 1 +#define MAC_RUL_M4_TAGGEDM_FLAG HSL_RW + +#define TAGGEDV +#define MAC_RUL_M4_TAGGEDV_BOFFSET 4 +#define MAC_RUL_M4_TAGGEDV_BLEN 1 +#define MAC_RUL_M4_TAGGEDV_FLAG HSL_RW + +#define VIDMSK +#define MAC_RUL_M4_VIDMSK_BOFFSET 3 +#define MAC_RUL_M4_VIDMSK_BLEN 1 +#define MAC_RUL_M4_VIDMSK_FLAG HSL_RW + +#define RULE_TYP +#define MAC_RUL_M4_RULE_TYP_BOFFSET 0 +#define MAC_RUL_M4_RULE_TYP_BLEN 3 +#define MAC_RUL_M4_RULE_TYP_FLAG HSL_RW + + + + + /* IP4 Type Rule Field Define */ +#define IP4_RUL_V0 0 +#define IP4_RUL_V0_OFFSET 0x58000 +#define IP4_RUL_V0_E_LENGTH 4 +#define IP4_RUL_V0_E_OFFSET 0x20 +#define IP4_RUL_V0_NR_E 96 + +#define DIPV +#define IP4_RUL_V0_DIPV_BOFFSET 0 +#define IP4_RUL_V0_DIPV_BLEN 32 +#define IP4_RUL_V0_DIPV_FLAG HSL_RW + + +#define IP4_RUL_V1 1 +#define IP4_RUL_V1_OFFSET 0x58004 +#define IP4_RUL_V1_E_LENGTH 4 +#define IP4_RUL_V1_E_OFFSET 0x20 +#define IP4_RUL_V1_NR_E 96 + +#define SIPV +#define IP4_RUL_V1_SIPV_BOFFSET 0 +#define IP4_RUL_V1_SIPV_BLEN 32 +#define IP4_RUL_V1_SIPV_FLAG HSL_RW + + +#define IP4_RUL_V2 2 +#define IP4_RUL_V2_OFFSET 0x58008 +#define IP4_RUL_V2_E_LENGTH 4 +#define IP4_RUL_V2_E_OFFSET 0x20 +#define IP4_RUL_V2_NR_E 96 + +#define IP4PROTV +#define IP4_RUL_V2_IP4PROTV_BOFFSET 0 +#define IP4_RUL_V2_IP4PROTV_BLEN 8 +#define IP4_RUL_V2_IP4PROTV_FLAG HSL_RW + +#define IP4DSCPV +#define IP4_RUL_V2_IP4DSCPV_BOFFSET 8 +#define IP4_RUL_V2_IP4DSCPV_BLEN 8 +#define IP4_RUL_V2_IP4DSCPV_FLAG HSL_RW + +#define IP4DPORTV +#define IP4_RUL_V2_IP4DPORTV_BOFFSET 16 +#define IP4_RUL_V2_IP4DPORTV_BLEN 16 +#define IP4_RUL_V2_IP4DPORTV_FLAG HSL_RW + + +#define IP4_RUL_V3 3 +#define IP4_RUL_V3_OFFSET 0x5800c +#define IP4_RUL_V3_E_LENGTH 4 +#define IP4_RUL_V3_E_OFFSET 0x20 +#define IP4_RUL_V3_NR_E 96 + +#define IP4TCPFLAGV +#define IP4_RUL_V3_IP4TCPFLAGV_BOFFSET 24 +#define IP4_RUL_V3_IP4TCPFLAGV_BLEN 6 +#define IP4_RUL_V3_IP4TCPFLAGV_FLAG HSL_RW + +#define IP4DHCPV +#define IP4_RUL_V3_IP4DHCPV_BOFFSET 22 +#define IP4_RUL_V3_IP4DHCPV_BLEN 1 +#define IP4_RUL_V3_IP4DHCPV_FLAG HSL_RW + +#define IP4RIPV +#define IP4_RUL_V3_IP4RIPV_BOFFSET 21 +#define IP4_RUL_V3_IP4RIPV_BLEN 1 +#define IP4_RUL_V3_IP4RIPV_FLAG HSL_RW + +#define ICMP_EN +#define IP4_RUL_V3_ICMP_EN_BOFFSET 20 +#define IP4_RUL_V3_ICMP_EN_BLEN 1 +#define IP4_RUL_V3_ICMP_EN_FLAG HSL_RW + +#define IP4SPORTV +#define IP4_RUL_V3_IP4SPORTV_BOFFSET 0 +#define IP4_RUL_V3_IP4SPORTV_BLEN 16 +#define IP4_RUL_V3_IP4SPORTV_FLAG HSL_RW + +#define IP4ICMPTYPV +#define IP4_RUL_V3_IP4ICMPTYPV_BOFFSET 8 +#define IP4_RUL_V3_IP4ICMPTYPV_BLEN 8 +#define IP4_RUL_V3_IP4ICMPTYPV_FLAG HSL_RW + +#define IP4ICMPCODEV +#define IP4_RUL_V3_IP4ICMPCODEV_BOFFSET 0 +#define IP4_RUL_V3_IP4ICMPCODEV_BLEN 8 +#define IP4_RUL_V3_IP4ICMPCODEV_FLAG HSL_RW + + +#define IP4_RUL_V4 4 +#define IP4_RUL_V4_OFFSET 0x58010 +#define IP4_RUL_V4_E_LENGTH 4 +#define IP4_RUL_V4_E_OFFSET 0x20 +#define IP4_RUL_V4_NR_E 96 + + +#define IP4_RUL_M0 5 +#define IP4_RUL_M0_OFFSET 0x59000 +#define IP4_RUL_M0_E_LENGTH 4 +#define IP4_RUL_M0_E_OFFSET 0x20 +#define IP4_RUL_M0_NR_E 96 + +#define DIPM +#define IP4_RUL_M0_DIPM_BOFFSET 0 +#define IP4_RUL_M0_DIPM_BLEN 32 +#define IP4_RUL_M0_DIPM_FLAG HSL_RW + + +#define IP4_RUL_M1 6 +#define IP4_RUL_M1_OFFSET 0x59004 +#define IP4_RUL_M1_E_LENGTH 4 +#define IP4_RUL_M1_E_OFFSET 0x20 +#define IP4_RUL_M1_NR_E 96 + +#define SIPM +#define IP4_RUL_M1_SIPM_BOFFSET 0 +#define IP4_RUL_M1_SIPM_BLEN 32 +#define IP4_RUL_M1_SIPM_FLAG HSL_RW + + +#define IP4_RUL_M2 7 +#define IP4_RUL_M2_OFFSET 0x59008 +#define IP4_RUL_M2_E_LENGTH 4 +#define IP4_RUL_M2_E_OFFSET 0x20 +#define IP4_RUL_M2_NR_E 96 + +#define IP4PROTM +#define IP4_RUL_M2_IP4PROTM_BOFFSET 0 +#define IP4_RUL_M2_IP4PROTM_BLEN 8 +#define IP4_RUL_M2_IP4PROTM_FLAG HSL_RW + +#define IP4DSCPM +#define IP4_RUL_M2_IP4DSCPM_BOFFSET 8 +#define IP4_RUL_M2_IP4DSCPM_BLEN 8 +#define IP4_RUL_M2_IP4DSCPM_FLAG HSL_RW + +#define IP4DPORTM +#define IP4_RUL_M2_IP4DPORTM_BOFFSET 16 +#define IP4_RUL_M2_IP4DPORTM_BLEN 16 +#define IP4_RUL_M2_IP4DPORTM_FLAG HSL_RW + + +#define IP4_RUL_M3 8 +#define IP4_RUL_M3_OFFSET 0x5900c +#define IP4_RUL_M3_E_LENGTH 4 +#define IP4_RUL_M3_E_OFFSET 0x20 +#define IP4_RUL_M3_NR_E 96 + +#define IP4TCPFLAGM +#define IP4_RUL_M3_IP4TCPFLAGM_BOFFSET 24 +#define IP4_RUL_M3_IP4TCPFLAGM_BLEN 6 +#define IP4_RUL_M3_IP4TCPFLAGM_FLAG HSL_RW + +#define IP4DHCPM +#define IP4_RUL_M3_IP4DHCPM_BOFFSET 22 +#define IP4_RUL_M3_IP4DHCPM_BLEN 1 +#define IP4_RUL_M3_IP4DHCPM_FLAG HSL_RW + +#define IP4RIPM +#define IP4_RUL_M3_IP4RIPM_BOFFSET 21 +#define IP4_RUL_M3_IP4RIPM_BLEN 1 +#define IP4_RUL_M3_IP4RIPM_FLAG HSL_RW + +#define IP4DPORTM_EN +#define IP4_RUL_M3_IP4DPORTM_EN_BOFFSET 17 +#define IP4_RUL_M3_IP4DPORTM_EN_BLEN 1 +#define IP4_RUL_M3_IP4DPORTM_EN_FLAG HSL_RW + +#define IP4SPORTM_EN +#define IP4_RUL_M3_IP4SPORTM_EN_BOFFSET 16 +#define IP4_RUL_M3_IP4SPORTM_EN_BLEN 1 +#define IP4_RUL_M3_IP4SPORTM_EN_FLAG HSL_RW + +#define IP4SPORTM +#define IP4_RUL_M3_IP4SPORTM_BOFFSET 0 +#define IP4_RUL_M3_IP4SPORTM_BLEN 16 +#define IP4_RUL_M3_IP4SPORTM_FLAG HSL_RW + +#define IP4ICMPTYPM +#define IP4_RUL_M3_IP4ICMPTYPM_BOFFSET 8 +#define IP4_RUL_M3_IP4ICMPTYPM_BLEN 8 +#define IP4_RUL_M3_IP4ICMPTYPM_FLAG HSL_RW + +#define IP4ICMPCODEM +#define IP4_RUL_M3_IP4ICMPCODEM_BOFFSET 0 +#define IP4_RUL_M3_IP4ICMPCODEM_BLEN 8 +#define IP4_RUL_M3_IP4ICMPCODEM_FLAG HSL_RW + + +#define IP4_RUL_M4 9 +#define IP4_RUL_M4_OFFSET 0x59010 +#define IP4_RUL_M4_E_LENGTH 4 +#define IP4_RUL_M4_E_OFFSET 0x20 +#define IP4_RUL_M4_NR_E 32 + + + + + /* IP6 Type1 Rule Field Define */ +#define IP6_RUL1_V0 0 +#define IP6_RUL1_V0_OFFSET 0x58000 +#define IP6_RUL1_V0_E_LENGTH 4 +#define IP6_RUL1_V0_E_OFFSET 0x20 +#define IP6_RUL1_V0_NR_E 96 + +#define IP6_DIPV0 +#define IP6_RUL1_V0_IP6_DIPV0_BOFFSET 0 +#define IP6_RUL1_V0_IP6_DIPV0_BLEN 32 +#define IP6_RUL1_V0_IP6_DIPV0_FLAG HSL_RW + + +#define IP6_RUL1_V1 1 +#define IP6_RUL1_V1_OFFSET 0x58004 +#define IP6_RUL1_V1_E_LENGTH 4 +#define IP6_RUL1_V1_E_OFFSET 0x20 +#define IP6_RUL1_V1_NR_E 96 + +#define IP6_DIPV1 +#define IP6_RUL1_V1_IP6_DIPV1_BOFFSET 0 +#define IP6_RUL1_V1_IP6_DIPv1_BLEN 32 +#define IP6_RUL1_V1_IP6_DIPV1_FLAG HSL_RW + + +#define IP6_RUL1_V2 2 +#define IP6_RUL1_V2_OFFSET 0x58008 +#define IP6_RUL1_V2_E_LENGTH 4 +#define IP6_RUL1_V2_E_OFFSET 0x20 +#define IP6_RUL1_V2_NR_E 96 + +#define IP6_DIPV2 +#define IP6_RUL1_V2_IP6_DIPV2_BOFFSET 0 +#define IP6_RUL1_V2_IP6_DIPv2_BLEN 32 +#define IP6_RUL1_V2_IP6_DIPV2_FLAG HSL_RW + + +#define IP6_RUL1_V3 3 +#define IP6_RUL1_V3_OFFSET 0x5800c +#define IP6_RUL1_V3_E_LENGTH 4 +#define IP6_RUL1_V3_E_OFFSET 0x20 +#define IP6_RUL1_V3_NR_E 96 + +#define IP6_DIPV3 +#define IP6_RUL1_V3_IP6_DIPV3_BOFFSET 0 +#define IP6_RUL1_V3_IP6_DIPv3_BLEN 32 +#define IP6_RUL1_V3_IP6_DIPV3_FLAG HSL_RW + + +#define IP6_RUL1_V4 4 +#define IP6_RUL1_V4_OFFSET 0x58010 +#define IP6_RUL1_V4_E_LENGTH 4 +#define IP6_RUL1_V4_E_OFFSET 0x20 +#define IP6_RUL1_V4_NR_E 96 + + +#define IP6_RUL1_M0 5 +#define IP6_RUL1_M0_OFFSET 0x59000 +#define IP6_RUL1_M0_E_LENGTH 4 +#define IP6_RUL1_M0_E_OFFSET 0x20 +#define IP6_RUL1_M0_NR_E 96 + +#define IP6_DIPM0 +#define IP6_RUL1_M0_IP6_DIPM0_BOFFSET 0 +#define IP6_RUL1_M0_IP6_DIPM0_BLEN 32 +#define IP6_RUL1_M0_IP6_DIPM0_FLAG HSL_RW + + +#define IP6_RUL1_M1 6 +#define IP6_RUL1_M1_OFFSET 0x59004 +#define IP6_RUL1_M1_E_LENGTH 4 +#define IP6_RUL1_M1_E_OFFSET 0x20 +#define IP6_RUL1_M1_NR_E 96 + +#define IP6_DIPM1 +#define IP6_RUL1_M1_IP6_DIPM1_BOFFSET 0 +#define IP6_RUL1_M1_IP6_DIPM1_BLEN 32 +#define IP6_RUL1_M1_IP6_DIPM1_FLAG HSL_RW + + +#define IP6_RUL1_M2 7 +#define IP6_RUL1_M2_OFFSET 0x59008 +#define IP6_RUL1_M2_E_LENGTH 4 +#define IP6_RUL1_M2_E_OFFSET 0x20 +#define IP6_RUL1_M2_NR_E 96 + +#define IP6_DIPM2 +#define IP6_RUL1_M2_IP6_DIPM2_BOFFSET 0 +#define IP6_RUL1_M2_IP6_DIPM2_BLEN 32 +#define IP6_RUL1_M2_IP6_DIPM2_FLAG HSL_RW + + +#define IP6_RUL1_M3 8 +#define IP6_RUL1_M3_OFFSET 0x5900c +#define IP6_RUL1_M3_E_LENGTH 4 +#define IP6_RUL1_M3_E_OFFSET 0x20 +#define IP6_RUL1_M3_NR_E 96 + +#define IP6_DIPM3 +#define IP6_RUL1_M3_IP6_DIPM3_BOFFSET 0 +#define IP6_RUL1_M3_IP6_DIPM3_BLEN 32 +#define IP6_RUL1_M3_IP6_DIPM3_FLAG HSL_RW + + +#define IP6_RUL1_M4 9 +#define IP6_RUL1_M4_OFFSET 0x59010 +#define IP6_RUL1_M4_E_LENGTH 4 +#define IP6_RUL1_M4_E_OFFSET 0x20 +#define IP6_RUL1_M4_NR_E 96 + + + + + /* IP6 Type2 Rule Field Define */ +#define IP6_RUL2_V0 0 +#define IP6_RUL2_V0_OFFSET 0x58000 +#define IP6_RUL2_V0_E_LENGTH 4 +#define IP6_RUL2_V0_E_OFFSET 0x20 +#define IP6_RUL2_V0_NR_E 96 + +#define IP6_SIPV0 +#define IP6_RUL2_V0_IP6_SIPV0_BOFFSET 0 +#define IP6_RUL2_V0_IP6_SIPv0_BLEN 32 +#define IP6_RUL2_V0_IP6_SIPV0_FLAG HSL_RW + + +#define IP6_RUL2_V1 1 +#define IP6_RUL2_V1_OFFSET 0x58004 +#define IP6_RUL2_V1_E_LENGTH 4 +#define IP6_RUL2_V1_E_OFFSET 0x20 +#define IP6_RUL2_V1_NR_E 96 + +#define IP6_SIPV1 +#define IP6_RUL2_V1_IP6_SIPV1_BOFFSET 0 +#define IP6_RUL2_V1_IP6_SIPv1_BLEN 32 +#define IP6_RUL2_V1_IP6_SIPV1_FLAG HSL_RW + + +#define IP6_RUL2_V2 2 +#define IP6_RUL2_V2_OFFSET 0x58008 +#define IP6_RUL2_V2_E_LENGTH 4 +#define IP6_RUL2_V2_E_OFFSET 0x20 +#define IP6_RUL2_V2_NR_E 96 + +#define IP6_SIPV2 +#define IP6_RUL2_V2_IP6_SIPV2_BOFFSET 0 +#define IP6_RUL2_V2_IP6_SIPv2_BLEN 32 +#define IP6_RUL2_V2_IP6_SIPV2_FLAG HSL_RW + + +#define IP6_RUL2_V3 3 +#define IP6_RUL2_V3_OFFSET 0x5800c +#define IP6_RUL2_V3_E_LENGTH 4 +#define IP6_RUL2_V3_E_OFFSET 0x20 +#define IP6_RUL2_V3_NR_E 96 + +#define IP6_SIPV3 +#define IP6_RUL2_V3_IP6_SIPV3_BOFFSET 0 +#define IP6_RUL2_V3_IP6_SIPv3_BLEN 32 +#define IP6_RUL2_V3_IP6_SIPV3_FLAG HSL_RW + + +#define IP6_RUL2_V4 4 +#define IP6_RUL2_V4_OFFSET 0x58010 +#define IP6_RUL2_V4_E_LENGTH 4 +#define IP6_RUL2_V4_E_OFFSET 0x20 +#define IP6_RUL2_V4_NR_E 96 + + +#define IP6_RUL2_M0 5 +#define IP6_RUL2_M0_OFFSET 0x59000 +#define IP6_RUL2_M0_E_LENGTH 4 +#define IP6_RUL2_M0_E_OFFSET 0x20 +#define IP6_RUL2_M0_NR_E 96 + +#define IP6_SIPM0 +#define IP6_RUL2_M0_IP6_SIPM0_BOFFSET 0 +#define IP6_RUL2_M0_IP6_SIPM0_BLEN 32 +#define IP6_RUL2_M0_IP6_SIPM0_FLAG HSL_RW + + +#define IP6_RUL2_M1 6 +#define IP6_RUL2_M1_OFFSET 0x59004 +#define IP6_RUL2_M1_E_LENGTH 4 +#define IP6_RUL2_M1_E_OFFSET 0x20 +#define IP6_RUL2_M1_NR_E 96 + +#define IP6_SIPM1 +#define IP6_RUL2_M1_IP6_DIPM1_BOFFSET 0 +#define IP6_RUL2_M1_IP6_DIPM1_BLEN 32 +#define IP6_RUL2_M1_IP6_DIPM1_FLAG HSL_RW + + +#define IP6_RUL2_M2 7 +#define IP6_RUL2_M2_OFFSET 0x59008 +#define IP6_RUL2_M2_E_LENGTH 4 +#define IP6_RUL2_M2_E_OFFSET 0x20 +#define IP6_RUL2_M2_NR_E 96 + +#define IP6_SIPM2 +#define IP6_RUL2_M2_IP6_DIPM2_BOFFSET 0 +#define IP6_RUL2_M2_IP6_DIPM2_BLEN 32 +#define IP6_RUL2_M2_IP6_DIPM2_FLAG HSL_RW + + +#define IP6_RUL2_M3 8 +#define IP6_RUL2_M3_OFFSET 0x5900c +#define IP6_RUL2_M3_E_LENGTH 4 +#define IP6_RUL2_M3_E_OFFSET 0x20 +#define IP6_RUL2_M3_NR_E 96 + +#define IP6_SIPM3 +#define IP6_RUL2_M3_IP6_SIPM3_BOFFSET 0 +#define IP6_RUL2_M3_IP6_SIPM3_BLEN 32 +#define IP6_RUL2_M3_IP6_SIPM3_FLAG HSL_RW + + +#define IP6_RUL2_M4 9 +#define IP6_RUL2_M4_OFFSET 0x59010 +#define IP6_RUL2_M4_E_LENGTH 4 +#define IP6_RUL2_M4_E_OFFSET 0x20 +#define IP6_RUL2_M4_NR_E 96 + + + + + /* IP6 Type3 Rule Field Define */ +#define IP6_RUL3_V0 0 +#define IP6_RUL3_V0_OFFSET 0x58000 +#define IP6_RUL3_V0_E_LENGTH 4 +#define IP6_RUL3_V0_E_OFFSET 0x20 +#define IP6_RUL3_V0_NR_E 96 + +#define IP6PROTV +#define IP6_RUL3_V0_IP6PROTV_BOFFSET 0 +#define IP6_RUL3_V0_IP6PROTV_BLEN 8 +#define IP6_RUL3_V0_IP6PROTV_FLAG HSL_RW + +#define IP6DSCPV +#define IP6_RUL3_V0_IP6DSCPV_BOFFSET 8 +#define IP6_RUL3_V0_IP6DSCPV_BLEN 8 +#define IP6_RUL3_V0_IP6DSCPV_FLAG HSL_RW + + +#define IP6_RUL3_V1 1 +#define IP6_RUL3_V1_OFFSET 0x58004 +#define IP6_RUL3_V1_E_LENGTH 4 +#define IP6_RUL3_V1_E_OFFSET 0x20 +#define IP6_RUL3_V1_NR_E 96 + +#define IP6LABEL1V +#define IP6_RUL3_V1_IP6LABEL1V_BOFFSET 16 +#define IP6_RUL3_V1_IP6LABEL1V_BLEN 16 +#define IP6_RUL3_V1_IP6LABEL1V_FLAG HSL_RW + + +#define IP6_RUL3_V2 2 +#define IP6_RUL3_V2_OFFSET 0x58008 +#define IP6_RUL3_V2_E_LENGTH 4 +#define IP6_RUL3_V2_E_OFFSET 0x20 +#define IP6_RUL3_V2_NR_E 96 + +#define IP6LABEL2V +#define IP6_RUL3_V2_IP6LABEL2V_BOFFSET 0 +#define IP6_RUL3_V2_IP6LABEL2V_BLEN 4 +#define IP6_RUL3_V2_IP6LABEL2V_FLAG HSL_RW + +#define IP6DPORTV +#define IP6_RUL3_V2_IP6DPORTV_BOFFSET 16 +#define IP6_RUL3_V2_IP6DPORTV_BLEN 16 +#define IP6_RUL3_V2_IP6DPORTV_FLAG HSL_RW + + +#define IP6_RUL3_V3 3 +#define IP6_RUL3_V3_OFFSET 0x5800c +#define IP6_RUL3_V3_E_LENGTH 4 +#define IP6_RUL3_V3_E_OFFSET 0x20 +#define IP6_RUL3_V3_NR_E 96 + +#define IP6TCPFLAGV +#define IP6_RUL3_V3_IP6TCPFLAGV_BOFFSET 24 +#define IP6_RUL3_V3_IP6TCPFLAGV_BLEN 6 +#define IP6_RUL3_V3_IP6TCPFLAGV_FLAG HSL_RW + +#define IP6FWDTYPV +#define IP6_RUL3_V3_IP6FWDTYPV_BOFFSET 23 +#define IP6_RUL3_V3_IP6FWDTYPV_BLEN 1 +#define IP6_RUL3_V3_IP6FWDTYPV_FLAG HSL_RW + +#define IP6DHCPV +#define IP6_RUL3_V3_IP6DHCPV_BOFFSET 22 +#define IP6_RUL3_V3_IP6DHCPV_BLEN 1 +#define IP6_RUL3_V3_IP6DHCPV_FLAG HSL_RW + +#define ICMP6_EN +#define IP6_RUL3_V3_ICMP6_EN_BOFFSET 20 +#define IP6_RUL3_V3_ICMP6_EN_BLEN 1 +#define IP6_RUL3_V3_ICMP6_EN_FLAG HSL_RW + +#define IP6SPORTV +#define IP6_RUL3_V3_IP6SPORTV_BOFFSET 0 +#define IP6_RUL3_V3_IP6SPORTV_BLEN 16 +#define IP6_RUL3_V3_IP6SPORTV_FLAG HSL_RW + +#define IP6ICMPTYPV +#define IP6_RUL3_V3_IP6ICMPTYPV_BOFFSET 8 +#define IP6_RUL3_V3_IP6ICMPTYPV_BLEN 8 +#define IP6_RUL3_V3_IP6ICMPTYPV_FLAG HSL_RW + +#define IP6ICMPCODEV +#define IP6_RUL3_V3_IP6ICMPCODEV_BOFFSET 0 +#define IP6_RUL3_V3_IP6ICMPCODEV_BLEN 8 +#define IP6_RUL3_V3_IP6ICMPCODEV_FLAG HSL_RW + + +#define IP6_RUL3_V4 4 +#define IP6_RUL3_V4_OFFSET 0x58010 +#define IP6_RUL3_V4_E_LENGTH 4 +#define IP6_RUL3_V4_E_OFFSET 0x20 +#define IP6_RUL3_V4_NR_E 96 + + +#define IP6_RUL3_M0 5 +#define IP6_RUL3_M0_OFFSET 0x59000 +#define IP6_RUL3_M0_E_LENGTH 4 +#define IP6_RUL3_M0_E_OFFSET 0x20 +#define IP6_RUL3_M0_NR_E 96 + +#define IP6PROTM +#define IP6_RUL3_M0_IP6PROTM_BOFFSET 0 +#define IP6_RUL3_M0_IP6PROTM_BLEN 8 +#define IP6_RUL3_M0_IP6PROTM_FLAG HSL_RW + +#define IP6DSCPM +#define IP6_RUL3_M0_IP6DSCPM_BOFFSET 8 +#define IP6_RUL3_M0_IP6DSCPM_BLEN 8 +#define IP6_RUL3_M0_IP6DSCPM_FLAG HSL_RW + + +#define IP6_RUL3_M1 6 +#define IP6_RUL3_M1_OFFSET 0x59004 +#define IP6_RUL3_M1_E_LENGTH 4 +#define IP6_RUL3_M1_E_OFFSET 0x20 +#define IP6_RUL3_M1_NR_E 96 + +#define IP6LABEL1M +#define IP6_RUL3_M1_IP6LABEL1M_BOFFSET 16 +#define IP6_RUL3_M1_IP6LABEL1M_BLEN 16 +#define IP6_RUL3_M1_IP6LABEL1M_FLAG HSL_RW + + +#define IP6_RUL3_M2 7 +#define IP6_RUL3_M2_OFFSET 0x59008 +#define IP6_RUL3_M2_E_LENGTH 4 +#define IP6_RUL3_M2_E_OFFSET 0x20 +#define IP6_RUL3_M2_NR_E 96 + +#define IP6LABEL2M +#define IP6_RUL3_M2_IP6LABEL2M_BOFFSET 0 +#define IP6_RUL3_M2_IP6LABEL2M_BLEN 4 +#define IP6_RUL3_M2_IP6LABEL21M_FLAG HSL_RW + +#define IP6DPORTM +#define IP6_RUL3_M2_IP6DPORTM_BOFFSET 16 +#define IP6_RUL3_M2_IP6DPORTM_BLEN 16 +#define IP6_RUL3_M2_IP6DPORTM_FLAG HSL_RW + + +#define IP6_RUL3_M3 8 +#define IP6_RUL3_M3_OFFSET 0x5900c +#define IP6_RUL3_M3_E_LENGTH 4 +#define IP6_RUL3_M3_E_OFFSET 0x20 +#define IP6_RUL3_M3_NR_E 96 + +#define IP6TCPFLAGM +#define IP6_RUL3_M3_IP6TCPFLAGM_BOFFSET 24 +#define IP6_RUL3_M3_IP6TCPFLAGM_BLEN 6 +#define IP6_RUL3_M3_IP6TCPFLAGM_FLAG HSL_RW + +#define IP6RWDTYPM +#define IP6_RUL3_M3_IP6RWDTYPV_BOFFSET 23 +#define IP6_RUL3_M3_IP6RWDTYPV_BLEN 1 +#define IP6_RUL3_M3_IP6RWDTYPV_FLAG HSL_RW + +#define IP6DHCPM +#define IP6_RUL3_M3_IP6DHCPM_BOFFSET 22 +#define IP6_RUL3_M3_IP6DHCPM_BLEN 1 +#define IP6_RUL3_M3_IP6DHCPM_FLAG HSL_RW + +#define IP6DPORTM_EN +#define IP6_RUL3_M3_IP6DPORTM_EN_BOFFSET 17 +#define IP6_RUL3_M3_IP6DPORTM_EN_BLEN 1 +#define IP6_RUL3_M3_IP6DPORTM_EN_FLAG HSL_RW + +#define IP6SPORTM_EN +#define IP6_RUL3_M3_IP6SPORTM_EN_BOFFSET 16 +#define IP6_RUL3_M3_IP6SPORTM_EN_BLEN 1 +#define IP6_RUL3_M3_IP6SPORTM_EN_FLAG HSL_RW + +#define IP6SPORTM +#define IP6_RUL3_M3_IP6SPORTM_BOFFSET 0 +#define IP6_RUL3_M3_IP6SPORTM_BLEN 16 +#define IP6_RUL3_M3_IP6SPORTM_FLAG HSL_RW + +#define IP6ICMPTYPM +#define IP6_RUL3_M3_IP6ICMPTYPM_BOFFSET 8 +#define IP6_RUL3_M3_IP6ICMPTYPM_BLEN 8 +#define IP6_RUL3_M3_IP6ICMPTYPM_FLAG HSL_RW + +#define IP6ICMPCODEM +#define IP6_RUL3_M3_IP6ICMPCODEM_BOFFSET 0 +#define IP6_RUL3_M3_IP6ICMPCODEM_BLEN 8 +#define IP6_RUL3_M3_IP6ICMPCODEM_FLAG HSL_RW + + +#define IP6_RUL3_M4 9 +#define IP6_RUL3_M4_OFFSET 0x59010 +#define IP6_RUL3_M4_E_LENGTH 4 +#define IP6_RUL3_M4_E_OFFSET 0x20 +#define IP6_RUL3_M4_NR_E 96 + + + + + /* Enhanced MAC Type Rule Field Define */ +#define EHMAC_RUL_V0 0 +#define EHMAC_RUL_V0_OFFSET 0x58000 +#define EHMAC_RUL_V0_E_LENGTH 4 +#define EHMAC_RUL_V0_E_OFFSET 0x20 +#define EHMAC_RUL_V0_NR_E 96 + +#define DAV_BYTE2 +#define EHMAC_RUL_V0_DAV_BYTE2_BOFFSET 24 +#define EHMAC_RUL_V0_DAV_BYTE2_BLEN 8 +#define EHMAC_RUL_V0_DAV_BYTE2_FLAG HSL_RW + +#define DAV_BYTE3 +#define EHMAC_RUL_V0_DAV_BYTE3_BOFFSET 16 +#define EHMAC_RUL_V0_DAV_BYTE3_BLEN 8 +#define EHMAC_RUL_V0_DAV_BYTE3_FLAG HSL_RW + +#define DAV_BYTE4 +#define EHMAC_RUL_V0_DAV_BYTE4_BOFFSET 8 +#define EHMAC_RUL_V0_DAV_BYTE4_BLEN 8 +#define EHMAC_RUL_V0_DAV_BYTE4_FLAG HSL_RW + +#define DAV_BYTE5 +#define EHMAC_RUL_V0_DAV_BYTE5_BOFFSET 0 +#define EHMAC_RUL_V0_DAV_BYTE5_BLEN 8 +#define EHMAC_RUL_V0_DAV_BYTE5_FLAG HSL_RW + + +#define EHMAC_RUL_V1 1 +#define EHMAC_RUL_V1_OFFSET 0x58004 +#define EHMAC_RUL_V1_E_LENGTH 4 +#define EHMAC_RUL_V1_E_OFFSET 0x20 +#define EHMAC_RUL_V1_NR_E 96 + +#define SAV_BYTE4 +#define EHMAC_RUL_V1_SAV_BYTE4_BOFFSET 24 +#define EHMAC_RUL_V1_SAV_BYTE4_BLEN 8 +#define EHMAC_RUL_V1_SAV_BYTE4_FLAG HSL_RW + +#define SAV_BYTE5 +#define EHMAC_RUL_V1_SAV_BYTE5_BOFFSET 16 +#define EHMAC_RUL_V1_SAV_BYTE5_BLEN 8 +#define EHMAC_RUL_V1_SAV_BYTE5_FLAG HSL_RW + +#define DAV_BYTE0 +#define EHMAC_RUL_V1_DAV_BYTE0_BOFFSET 8 +#define EHMAC_RUL_V1_DAV_BYTE0_BLEN 8 +#define EHMAC_RUL_V1_DAV_BYTE0_FLAG HSL_RW + +#define DAV_BYTE1 +#define EHMAC_RUL_V1_DAV_BYTE1_BOFFSET 0 +#define EHMAC_RUL_V1_DAV_BYTE1_BLEN 8 +#define EHMAC_RUL_V1_DAV_BYTE1_FLAG HSL_RW + + +#define EHMAC_RUL_V2 2 +#define EHMAC_RUL_V2_OFFSET 0x58008 +#define EHMAC_RUL_V2_E_LENGTH 4 +#define EHMAC_RUL_V2_E_OFFSET 0x20 +#define EHMAC_RUL_V2_NR_E 96 + +#define CTAG_VIDLV +#define EHMAC_RUL_V2_CTAG_VIDLV_BOFFSET 24 +#define EHMAC_RUL_V2_CTAG_VIDLV_BLEN 8 +#define EHMAC_RUL_V2_CTAG_VIDLV_FLAG HSL_RW + +#define STAG_PRIV +#define EHMAC_RUL_V2_STAG_PRIV_BOFFSET 21 +#define EHMAC_RUL_V2_STAG_PRIV_BLEN 3 +#define EHMAC_RUL_V2_STAG_PRIV_FLAG HSL_RW + +#define STAG_DEIV +#define EHMAC_RUL_V2_STAG_DEIV_BOFFSET 20 +#define EHMAC_RUL_V2_STAG_DEIV_BLEN 1 +#define EHMAC_RUL_V2_STAG_DEIV_FLAG HSL_RW + +#define STAG_VIDV +#define EHMAC_RUL_V2_STAG_VIDV_BOFFSET 8 +#define EHMAC_RUL_V2_STAG_VIDV_BLEN 12 +#define EHMAC_RUL_V2_STAG_VIDV_FLAG HSL_RW + +#define SAV_BYTE3 +#define EHMAC_RUL_V2_SAV_BYTE3_BOFFSET 0 +#define EHMAC_RUL_V2_SAV_BYTE3_BLEN 8 +#define EHMAC_RUL_V2_SAV_BYTE3_FLAG HSL_RW + + +#define EHMAC_RUL_V3 3 +#define EHMAC_RUL_V3_ID 13 +#define EHMAC_RUL_V3_OFFSET 0x5800c +#define EHMAC_RUL_V3_E_LENGTH 4 +#define EHMAC_RUL_V3_E_OFFSET 0x20 +#define EHMAC_RUL_V3_NR_E 96 + +#define STAGGEDM +#define EHMAC_RUL_V3_STAGGEDM_BOFFSET 31 +#define EHMAC_RUL_V3_STAGGEDM_BLEN 1 +#define EHMAC_RUL_V3_STAGGEDM_FLAG HSL_RW + +#define STAGGEDV +#define EHMAC_RUL_V3_STAGGEDV_BOFFSET 30 +#define EHMAC_RUL_V3_STAGGEDV_BLEN 1 +#define EHMAC_RUL_V3_STAGGEDV_FLAG HSL_RW + +#define DA_EN +#define EHMAC_RUL_V3_DA_EN_BOFFSET 25 +#define EHMAC_RUL_V3_DA_EN_BLEN 1 +#define EHMAC_RUL_V3_DA_EN_FLAG HSL_RW + +#define SVIDMSK +#define EHMAC_RUL_V3_SVIDMSK_BOFFSET 24 +#define EHMAC_RUL_V3_SVIDMSK_BLEN 1 +#define EHMAC_RUL_V3_SVIDMSK_FLAG HSL_RW + +#define ETHTYPV +#define EHMAC_RUL_V3_ETHTYPV_BOFFSET 8 +#define EHMAC_RUL_V3_ETHTYPV_BLEN 16 +#define EHMAC_RUL_V3_ETHTYPV_FLAG HSL_RW + +#define CTAG_PRIV +#define EHMAC_RUL_V3_CTAG_PRIV_BOFFSET 5 +#define EHMAC_RUL_V3_CTAG_PRIV_BLEN 3 +#define EHMAC_RUL_V3_CTAG_PRIV_FLAG HSL_RW + +#define CTAG_CFIV +#define EHMAC_RUL_V3_CTAG_CFIV_BOFFSET 4 +#define EHMAC_RUL_V3_CTAG_CFIV_BLEN 1 +#define EHMAC_RUL_V3_CTAG_CFIV_FLAG HSL_RW + +#define CTAG_VIDHV +#define EHMAC_RUL_V3_CTAG_VIDHV_BOFFSET 0 +#define EHMAC_RUL_V3_CTAG_VIDHV_BLEN 4 +#define EHMAC_RUL_V3_CTAG_VIDHV_FLAG HSL_RW + + +#define EHMAC_RUL_V4 4 +#define EHMAC_RUL_V4_OFFSET 0x58010 +#define EHMAC_RUL_V4_E_LENGTH 4 +#define EHMAC_RUL_V4_E_OFFSET 0x20 +#define EHMAC_RUL_V4_NR_E 96 + + +#define EHMAC_RUL_M0 5 +#define EHMAC_RUL_M0_OFFSET 0x59000 +#define EHMAC_RUL_M0_E_LENGTH 4 +#define EHMAC_RUL_M0_E_OFFSET 0x20 +#define EHMAC_RUL_M0_NR_E 96 + +#define DAM_BYTE2 +#define EHMAC_RUL_M0_DAM_BYTE2_BOFFSET 24 +#define EHMAC_RUL_M0_DAM_BYTE2_BLEN 8 +#define EHMAC_RUL_M0_DAM_BYTE2_FLAG HSL_RW + +#define DAM_BYTE3 +#define EHMAC_RUL_M0_DAM_BYTE3_BOFFSET 16 +#define EHMAC_RUL_M0_DAM_BYTE3_BLEN 8 +#define EHMAC_RUL_M0_DAM_BYTE3_FLAG HSL_RW + +#define DAM_BYTE4 +#define EHMAC_RUL_M0_DAM_BYTE4_BOFFSET 8 +#define EHMAC_RUL_M0_DAM_BYTE4_BLEN 8 +#define EHMAC_RUL_M0_DAM_BYTE4_FLAG HSL_RW + +#define DAM_BYTE5 +#define EHMAC_RUL_M0_DAM_BYTE5_BOFFSET 0 +#define EHMAC_RUL_M0_DAM_BYTE5_BLEN 8 +#define EHMAC_RUL_M0_DAM_BYTE5_FLAG HSL_RW + + +#define EHMAC_RUL_M1 6 +#define EHMAC_RUL_M1_OFFSET 0x59004 +#define EHMAC_RUL_M1_E_LENGTH 4 +#define EHMAC_RUL_M1_E_OFFSET 0x20 +#define EHMAC_RUL_M1_NR_E 96 + +#define SAM_BYTE4 +#define EHMAC_RUL_M1_SAM_BYTE4_BOFFSET 24 +#define EHMAC_RUL_M1_SAM_BYTE4_BLEN 8 +#define EHMAC_RUL_M1_SAM_BYTE4_FLAG HSL_RW + +#define SAM_BYTE5 +#define EHMAC_RUL_M1_SAM_BYTE5_BOFFSET 16 +#define EHMAC_RUL_M1_SAM_BYTE5_BLEN 8 +#define EHMAC_RUL_M1_SAM_BYTE5_FLAG HSL_RW + +#define DAM_BYTE0 +#define EHMAC_RUL_M1_DAM_BYTE0_BOFFSET 8 +#define EHMAC_RUL_M1_DAM_BYTE0_BLEN 8 +#define EHMAC_RUL_M1_DAM_BYTE0_FLAG HSL_RW + +#define DAM_BYTE1 +#define EHMAC_RUL_M1_DAM_BYTE1_BOFFSET 0 +#define EHMAC_RUL_M1_DAM_BYTE1_BLEN 8 +#define EHMAC_RUL_M1_DAM_BYTE1_FLAG HSL_RW + + +#define EHMAC_RUL_M2 7 +#define EHMAC_RUL_M2_OFFSET 0x59008 +#define EHMAC_RUL_M2_E_LENGTH 4 +#define EHMAC_RUL_M2_E_OFFSET 0x20 +#define EHMAC_RUL_M2_NR_E 96 + +#define CTAG_VIDLM +#define EHMAC_RUL_M2_CTAG_VIDLM_BOFFSET 24 +#define EHMAC_RUL_M2_CTAG_VIDLM_BLEN 8 +#define EHMAC_RUL_M2_CTAG_VIDLM_FLAG HSL_RW + +#define STAG_PRIM +#define EHMAC_RUL_M2_STAG_PRIM_BOFFSET 21 +#define EHMAC_RUL_M2_STAG_PRIM_BLEN 3 +#define EHMAC_RUL_M2_STAG_PRIM_FLAG HSL_RW + +#define STAG_DEIM +#define EHMAC_RUL_M2_STAG_DEIM_BOFFSET 20 +#define EHMAC_RUL_M2_STAG_DEIM_BLEN 1 +#define EHMAC_RUL_M2_STAG_DEIM_FLAG HSL_RW + +#define STAG_VIDM +#define EHMAC_RUL_M2_STAG_VIDM_BOFFSET 8 +#define EHMAC_RUL_M2_STAG_VIDM_BLEN 12 +#define EHMAC_RUL_M2_STAG_VIDM_FLAG HSL_RW + +#define SAM_BYTE3 +#define EHMAC_RUL_M2_SAM_BYTE3_BOFFSET 0 +#define EHMAC_RUL_M2_SAM_BYTE3_BLEN 8 +#define EHMAC_RUL_M2_SAM_BYTE3_FLAG HSL_RW + + +#define EHMAC_RUL_M3 8 +#define EHMAC_RUL_M3_OFFSET 0x5900c +#define EHMAC_RUL_M3_E_LENGTH 4 +#define EHMAC_RUL_M3_E_OFFSET 0x20 +#define EHMAC_RUL_M3_NR_E 96 + +#define ETHTYPM +#define EHMAC_RUL_M3_ETHTYPM_BOFFSET 8 +#define EHMAC_RUL_M3_ETHTYPM_BLEN 16 +#define EHMAC_RUL_M3_ETHTYPM_FLAG HSL_RW + +#define CTAG_PRIM +#define EHMAC_RUL_M3_CTAG_PRIM_BOFFSET 5 +#define EHMAC_RUL_M3_CTAG_PRIM_BLEN 3 +#define EHMAC_RUL_M3_CTAG_PRIM_FLAG HSL_RW + +#define CTAG_CFIM +#define EHMAC_RUL_M3_CTAG_CFIM_BOFFSET 4 +#define EHMAC_RUL_M3_CTAG_CFIM_BLEN 1 +#define EHMAC_RUL_M3_CTAG_CFIM_FLAG HSL_RW + +#define CTAG_VIDHM +#define EHMAC_RUL_M3_CTAG_VIDHM_BOFFSET 0 +#define EHMAC_RUL_M3_CTAG_VIDHM_BLEN 4 +#define EHMAC_RUL_M3_CTAG_VIDHM_FLAG HSL_RW + + +#define EHMAC_RUL_M4 9 +#define EHMAC_RUL_M4_OFFSET 0x59010 +#define EHMAC_RUL_M4_E_LENGTH 4 +#define EHMAC_RUL_M4_E_OFFSET 0x20 +#define EHMAC_RUL_M4_NR_E 96 + +#define CTAGGEDM +#define EHMAC_RUL_M4_CTAGGEDM_BOFFSET 5 +#define EHMAC_RUL_M4_CTAGGEDM_BLEN 1 +#define EHMAC_RUL_M4_CTAGGEDM_FLAG HSL_RW + +#define CTAGGEDV +#define EHMAC_RUL_M4_CTAGGEDV_BOFFSET 4 +#define EHMAC_RUL_M4_CTAGGEDV_BLEN 1 +#define EHMAC_RUL_M4_CTAGGEDV_FLAG HSL_RW + +#define CVIDMSK +#define EHMAC_RUL_M4_CVIDMSK_BOFFSET 3 +#define EHMAC_RUL_M4_CVIDMSK_BLEN 1 +#define EHMAC_RUL_M4_CVIDMSK_FLAG HSL_RW + + + + + /* PPPoE Session Table Define */ +#define PPPOE_SESSION +#define PPPOE_SESSION_OFFSET 0x5f000 +#define PPPOE_SESSION_E_LENGTH 4 +#define PPPOE_SESSION_E_OFFSET 0x4 +#define PPPOE_SESSION_NR_E 16 + +#define ENTRY_VALID +#define PPPOE_SESSION_ENTRY_VALID_BOFFSET 16 +#define PPPOE_SESSION_ENTRY_VALID_BLEN 2 +#define PPPOE_SESSION_ENTRY_VALID_FLAG HSL_RW + +#define SEESION_ID +#define PPPOE_SESSION_SEESION_ID_BOFFSET 0 +#define PPPOE_SESSION_SEESION_ID_BLEN 16 +#define PPPOE_SESSION_SEESION_ID_FLAG HSL_RW + + +#define PPPOE_EDIT +#define PPPOE_EDIT_OFFSET 0x02200 +#define PPPOE_EDIT_E_LENGTH 4 +#define PPPOE_EDIT_E_OFFSET 0x10 +#define PPPOE_EDIT_NR_E 16 + +#define EDIT_ID +#define PPPOE_EDIT_EDIT_ID_BOFFSET 0 +#define PPPOE_EDIT_EDIT_ID_BLEN 16 +#define PPPOE_EDIT_EDIT_ID_FLAG HSL_RW + + + + + /* L3 Host Entry Define */ +#define HOST_ENTRY0 +#define HOST_ENTRY0_OFFSET 0x0e80 +#define HOST_ENTRY0_E_LENGTH 4 +#define HOST_ENTRY0_E_OFFSET 0x0 +#define HOST_ENTRY0_NR_E 1 + +#define IP_ADDR +#define HOST_ENTRY0_IP_ADDR_BOFFSET 0 +#define HOST_ENTRY0_IP_ADDR_BLEN 32 +#define HOST_ENTRY0_IP_ADDR_FLAG HSL_RW + + +#define HOST_ENTRY1 +#define HOST_ENTRY1_OFFSET 0x0e84 +#define HOST_ENTRY1_E_LENGTH 4 +#define HOST_ENTRY1_E_OFFSET 0x0 +#define HOST_ENTRY1_NR_E 1 + + +#define HOST_ENTRY2 +#define HOST_ENTRY2_OFFSET 0x0e88 +#define HOST_ENTRY2_E_LENGTH 4 +#define HOST_ENTRY2_E_OFFSET 0x0 +#define HOST_ENTRY2_NR_E 1 + + +#define HOST_ENTRY3 +#define HOST_ENTRY3_OFFSET 0x0e8c +#define HOST_ENTRY3_E_LENGTH 4 +#define HOST_ENTRY3_E_OFFSET 0x0 +#define HOST_ENTRY3_NR_E 1 + + +#define HOST_ENTRY4 +#define HOST_ENTRY4_OFFSET 0x0e90 +#define HOST_ENTRY4_E_LENGTH 4 +#define HOST_ENTRY4_E_OFFSET 0x0 +#define HOST_ENTRY4_NR_E 1 + +#define MAC_ADDR2 +#define HOST_ENTRY4_MAC_ADDR2_BOFFSET 24 +#define HOST_ENTRY4_MAC_ADDR2_BLEN 8 +#define HOST_ENTRY4_MAC_ADDR2_FLAG HSL_RW + +#define MAC_ADDR3 +#define HOST_ENTRY4_MAC_ADDR3_BOFFSET 16 +#define HOST_ENTRY4_MAC_ADDR3_BLEN 8 +#define HOST_ENTRY4_MAC_ADDR3_FLAG HSL_RW + +#define MAC_ADDR4 +#define HOST_ENTRY4_MAC_ADDR4_BOFFSET 8 +#define HOST_ENTRY4_MAC_ADDR4_BLEN 8 +#define HOST_ENTRY4_MAC_ADDR4_FLAG HSL_RW + +#define MAC_ADDR5 +#define HOST_ENTRY4_MAC_ADDR5_BOFFSET 0 +#define HOST_ENTRY4_MAC_ADDR5_BLEN 8 +#define HOST_ENTRY4_MAC_ADDR5_FLAG HSL_RW + +#define HOST_ENTRY5 +#define HOST_ENTRY5_OFFSET 0x0e94 +#define HOST_ENTRY5_E_LENGTH 4 +#define HOST_ENTRY5_E_OFFSET 0x0 +#define HOST_ENTRY5_NR_E 1 + +#define CPU_ADDR +#define HOST_ENTRY5_CPU_ADDR_BOFFSET 31 +#define HOST_ENTRY5_CPU_ADDR_BLEN 1 +#define HOST_ENTRY5_CPU_ADDR_FLAG HSL_RW + +#define SRC_PORT +#define HOST_ENTRY5_SRC_PORT_BOFFSET 28 +#define HOST_ENTRY5_SRC_PORT_BLEN 3 +#define HOST_ENTRY5_SRC_PORT_FLAG HSL_RW + +#define INTF_ID +#define HOST_ENTRY5_INTF_ID_BOFFSET 16 +#define HOST_ENTRY5_INTF_ID_BLEN 12 +#define HOST_ENTRY5_INTF_ID_FLAG HSL_RW + +#define MAC_ADDR0 +#define HOST_ENTRY5_MAC_ADDR0_BOFFSET 8 +#define HOST_ENTRY5_MAC_ADDR0_BLEN 8 +#define HOST_ENTRY5_MAC_ADDR0_FLAG HSL_RW + +#define MAC_ADDR1 +#define HOST_ENTRY5_MAC_ADDR1_BOFFSET 0 +#define HOST_ENTRY5_MAC_ADDR1_BLEN 8 +#define HOST_ENTRY5_MAC_ADDR1_FLAG HSL_RW + + +#define HOST_ENTRY6 +#define HOST_ENTRY6_OFFSET 0x0e98 +#define HOST_ENTRY6_E_LENGTH 4 +#define HOST_ENTRY6_E_OFFSET 0x0 +#define HOST_ENTRY6_NR_E 1 + +#define IP_VER +#define HOST_ENTRY6_IP_VER_BOFFSET 15 +#define HOST_ENTRY6_IP_VER_BLEN 1 +#define HOST_ENTRY6_IP_VER_FLAG HSL_RW + +#define AGE_FLAG +#define HOST_ENTRY6_AGE_FLAG_BOFFSET 12 +#define HOST_ENTRY6_AGE_FLAG_BLEN 3 +#define HOST_ENTRY6_AGE_FLAG_FLAG HSL_RW + +#define PPPOE_EN +#define HOST_ENTRY6_PPPOE_EN_BOFFSET 11 +#define HOST_ENTRY6_PPPOE_EN_BLEN 1 +#define HOST_ENTRY6_PPPOE_EN_FLAG HSL_RW + +#define PPPOE_IDX +#define HOST_ENTRY6_PPPOE_IDX_BOFFSET 7 +#define HOST_ENTRY6_PPPOE_IDX_BLEN 4 +#define HOST_ENTRY6_PPPOE_IDX_FLAG HSL_RW + +#define CNT_EN +#define HOST_ENTRY6_CNT_EN_BOFFSET 6 +#define HOST_ENTRY6_CNT_EN_BLEN 1 +#define HOST_ENTRY6_CNT_EN_FLAG HSL_RW + +#define CNT_IDX +#define HOST_ENTRY6_CNT_IDX_BOFFSET 2 +#define HOST_ENTRY6_CNT_IDX_BLEN 4 +#define HOST_ENTRY6_CNT_IDX_FLAG HSL_RW + +#define ACTION +#define HOST_ENTRY6_ACTION_BOFFSET 0 +#define HOST_ENTRY6_ACTION_BLEN 2 +#define HOST_ENTRY6_ACTION_FLAG HSL_RW + + +#define HOST_ENTRY7 +#define HOST_ENTRY7_OFFSET 0x0e58 +#define HOST_ENTRY7_E_LENGTH 4 +#define HOST_ENTRY7_E_OFFSET 0x0 +#define HOST_ENTRY7_NR_E 1 + +#define TBL_BUSY +#define HOST_ENTRY7_TBL_BUSY_BOFFSET 31 +#define HOST_ENTRY7_TBL_BUSY_BLEN 1 +#define HOST_ENTRY7_TBL_BUSY_FLAG HSL_RW + +#define SPEC_SP +#define HOST_ENTRY7_SPEC_SP_BOFFSET 22 +#define HOST_ENTRY7_SPEC_SP_BLEN 1 +#define HOST_ENTRY7_SPEC_SP_FLAG HSL_RW + +#define SPEC_VID +#define HOST_ENTRY7_SPEC_VID_BOFFSET 21 +#define HOST_ENTRY7_SPEC_VID_BLEN 1 +#define HOST_ENTRY7_SPEC_VID_FLAG HSL_RW + +#define SPEC_PIP +#define HOST_ENTRY7_SPEC_PIP_BOFFSET 20 +#define HOST_ENTRY7_SPEC_PIP_BLEN 1 +#define HOST_ENTRY7_SPEC_PIP_FLAG HSL_RW + +#define SPEC_SIP +#define HOST_ENTRY7_SPEC_SIP_BOFFSET 19 +#define HOST_ENTRY7_SPEC_SIP_BLEN 1 +#define HOST_ENTRY7_SPEC_SIP_FLAG HSL_RW + +#define SPEC_STATUS +#define HOST_ENTRY7_SPEC_STATUS_BOFFSET 18 +#define HOST_ENTRY7_SPEC_STATUS_BLEN 1 +#define HOST_ENTRY7_SPEC_STATUS_FLAG HSL_RW + +#define TBL_IDX +#define HOST_ENTRY7_TBL_IDX_BOFFSET 8 +#define HOST_ENTRY7_TBL_IDX_BLEN 10 +#define HOST_ENTRY7_TBL_IDX_FLAG HSL_RW + +#define TBL_STAUS +#define HOST_ENTRY7_TBL_STAUS_BOFFSET 7 +#define HOST_ENTRY7_TBL_STAUS_BLEN 1 +#define HOST_ENTRY7_TBL_STAUS_FLAG HSL_RW + +#define TBL_SEL +#define HOST_ENTRY7_TBL_SEL_BOFFSET 4 +#define HOST_ENTRY7_TBL_SEL_BLEN 2 +#define HOST_ENTRY7_TBL_SEL_FLAG HSL_RW + +#define ENTRY_FUNC +#define HOST_ENTRY7_ENTRY_FUNC_BOFFSET 0 +#define HOST_ENTRY7_ENTRY_FUNC_BLEN 3 +#define HOST_ENTRY7_ENTRY_FUNC_FLAG HSL_RW + + + + +#define NAT_ENTRY0 +#define NAT_ENTRY0_OFFSET 0x0e80 +#define NAT_ENTRY0_E_LENGTH 4 +#define NAT_ENTRY0_E_OFFSET 0x0 +#define NAT_ENTRY0_NR_E 1 + +#define IP_ADDR +#define NAT_ENTRY0_IP_ADDR_BOFFSET 0 +#define NAT_ENTRY0_IP_ADDR_BLEN 32 +#define NAT_ENTRY0_IP_ADDR_FLAG HSL_RW + + +#define NAT_ENTRY1 +#define NAT_ENTRY1_OFFSET 0x0e84 +#define NAT_ENTRY1_E_LENGTH 4 +#define NAT_ENTRY1_E_OFFSET 0x0 +#define NAT_ENTRY1_NR_E 1 + +#define PRV_IPADDR0 +#define NAT_ENTRY1_PRV_IPADDR0_BOFFSET 24 +#define NAT_ENTRY1_PRV_IPADDR0_BLEN 8 +#define NAT_ENTRY1_PRV_IPADDR0_FLAG HSL_RW + +#define PORT_RANGE +#define NAT_ENTRY1_PORT_RANGE_BOFFSET 16 +#define NAT_ENTRY1_PORT_RANGE_BLEN 8 +#define NAT_ENTRY1_PORT_RANGE_FLAG HSL_RW + +#define PORT_NUM +#define NAT_ENTRY1_PORT_NUM_BOFFSET 0 +#define NAT_ENTRY1_PORT_NUM_BLEN 16 +#define NAT_ENTRY1_PORT_NUM_FLAG HSL_RW + + +#define NAT_ENTRY2 +#define NAT_ENTRY2_OFFSET 0x0e88 +#define NAT_ENTRY2_E_LENGTH 4 +#define NAT_ENTRY2_E_OFFSET 0x0 +#define NAT_ENTRY2_NR_E 1 + +#define HASH_KEY +#define NAT_ENTRY2_HASH_KEY_BOFFSET 30 +#define NAT_ENTRY2_HASH_KEY_BLEN 2 +#define NAT_ENTRY2_HASH_KEY_FLAG HSL_RW + +#define ACTION +#define NAT_ENTRY2_ACTION_BOFFSET 28 +#define NAT_ENTRY2_ACTION_BLEN 2 +#define NAT_ENTRY2_ACTION_FLAG HSL_RW + +#define CNT_EN +#define NAT_ENTRY2_CNT_EN_BOFFSET 27 +#define NAT_ENTRY2_CNT_EN_BLEN 1 +#define NAT_ENTRY2_CNT_EN_FLAG HSL_RW + +#define CNT_IDX +#define NAT_ENTRY2_CNT_IDX_BOFFSET 24 +#define NAT_ENTRY2_CNT_IDX_BLEN 3 +#define NAT_ENTRY2_CNT_IDX_FLAG HSL_RW + +#define PRV_IPADDR1 +#define NAT_ENTRY2_PRV_IPADDR1_BOFFSET 0 +#define NAT_ENTRY2_PRV_IPADDR1_BLEN 24 +#define NAT_ENTRY2_PRV_IPADDR1_FLAG HSL_RW + + +#define NAT_ENTRY3 +#define NAT_ENTRY3_OFFSET 0x0e8c +#define NAT_ENTRY3_E_LENGTH 4 +#define NAT_ENTRY3_E_OFFSET 0x0 +#define NAT_ENTRY3_NR_E 1 + +#define ENTRY_VALID +#define NAT_ENTRY3_ENTRY_VALID_BOFFSET 3 +#define NAT_ENTRY3_ENTRY_VALID_BLEN 1 +#define NAT_ENTRY3_ENTRY_VALID_FLAG HSL_RW + +#define PORT_EN +#define NAT_ENTRY3_PORT_EN_BOFFSET 2 +#define NAT_ENTRY3_PORT_EN_BLEN 1 +#define NAT_ENTRY3_PORT_EN_FLAG HSL_RW + +#define PRO_TYP +#define NAT_ENTRY3_PRO_TYP_BOFFSET 0 +#define NAT_ENTRY3_PRO_TYP_BLEN 2 +#define NAT_ENTRY3_PRO_TYP_FLAG HSL_RW + + +#define NAPT_ENTRY0 +#define NAPT_ENTRY0_OFFSET 0x0e80 +#define NAPT_ENTRY0_E_LENGTH 4 +#define NAPT_ENTRY0_E_OFFSET 0x0 +#define NAPT_ENTRY0_NR_E 1 + +#define DST_IPADDR +#define NAPT_ENTRY0_DST_IPADDR_BOFFSET 0 +#define NAPT_ENTRY0_DST_IPADDR_BLEN 32 +#define NAPT_ENTRY0_DST_IPADDR_FLAG HSL_RW + + +#define NAPT_ENTRY1 +#define NAPT_ENTRY1_OFFSET 0x0e84 +#define NAPT_ENTRY1_E_LENGTH 4 +#define NAPT_ENTRY1_E_OFFSET 0x0 +#define NAPT_ENTRY1_NR_E 1 + +#define SRC_PORT +#define NAPT_ENTRY1_SRC_PORT_BOFFSET 16 +#define NAPT_ENTRY1_SRC_PORT_BLEN 16 +#define NAPT_ENTRY1_SRC_PORT_FLAG HSL_RW + +#define DST_PORT +#define NAPT_ENTRY1_DST_PORT_BOFFSET 0 +#define NAPT_ENTRY1_DST_PORT_BLEN 16 +#define NAPT_ENTRY1_DST_PORT_FLAG HSL_RW + + +#define NAPT_ENTRY2 +#define NAPT_ENTRY2_OFFSET 0x0e88 +#define NAPT_ENTRY2_E_LENGTH 4 +#define NAPT_ENTRY2_E_OFFSET 0x0 +#define NAPT_ENTRY2_NR_E 1 + +#define SRC_IPADDR0 +#define NAPT_ENTRY2_SRC_IPADDR0_BOFFSET 20 +#define NAPT_ENTRY2_SRC_IPADDR0_BLEN 12 +#define NAPT_ENTRY2_SRC_IPADDR0_FLAG HSL_RW + +#define TRANS_IPADDR +#define NAPT_ENTRY2_TRANS_IPADDR_BOFFSET 16 +#define NAPT_ENTRY2_TRANS_IPADDR_BLEN 4 +#define NAPT_ENTRY2_TRANS_IPADDR_FLAG HSL_RW + +#define TRANS_PORT +#define NAPT_ENTRY2_TRANS_PORT_BOFFSET 0 +#define NAPT_ENTRY2_TRANS_PORT_BLEN 16 +#define NAPT_ENTRY2_TRANS_PORT_FLAG HSL_RW + + +#define NAPT_ENTRY3 +#define NAPT_ENTRY3_OFFSET 0x0e8c +#define NAPT_ENTRY3_E_LENGTH 4 +#define NAPT_ENTRY3_E_OFFSET 0x0 +#define NAPT_ENTRY3_NR_E 1 + +#define CNT_EN +#define NAPT_ENTRY3_CNT_EN_BOFFSET 27 +#define NAPT_ENTRY3_CNT_EN_BLEN 1 +#define NAPT_ENTRY3_CNT_EN_FLAG HSL_RW + +#define CNT_IDX +#define NAPT_ENTRY3_CNT_IDX_BOFFSET 24 +#define NAPT_ENTRY3_CNT_IDX_BLEN 3 +#define NAPT_ENTRY3_CNT_IDX_FLAG HSL_RW + +#define PROT_TYP +#define NAPT_ENTRY3_PROT_TYP_BOFFSET 22 +#define NAPT_ENTRY3_PROT_TYP_BLEN 2 +#define NAPT_ENTRY3_PROT_TYP_FLAG HSL_RW + +#define ACTION +#define NAPT_ENTRY3_ACTION_BOFFSET 20 +#define NAPT_ENTRY3_ACTION_BLEN 2 +#define NAPT_ENTRY3_ACTION_FLAG HSL_RW + +#define SRC_IPADDR1 +#define NAPT_ENTRY3_SRC_IPADDR1_BOFFSET 0 +#define NAPT_ENTRY3_SRC_IPADDR1_BLEN 20 +#define NAPT_ENTRY3_SRC_IPADDR1_FLAG HSL_RW + + +#define NAPT_ENTRY4 +#define NAPT_ENTRY4_OFFSET 0x0e90 +#define NAPT_ENTRY4_E_LENGTH 4 +#define NAPT_ENTRY4_E_OFFSET 0x0 +#define NAPT_ENTRY4_NR_E 1 + +#define AGE_FLAG +#define NAPT_ENTRY4_AGE_FLAG_BOFFSET 0 +#define NAPT_ENTRY4_AGE_FLAG_BLEN 4 +#define NAPT_ENTRY4_AGE_FLAG_FLAG HSL_RW + + +#define ROUTER_CTRL +#define ROUTER_CTRL_OFFSET 0x0e00 +#define ROUTER_CTRL_E_LENGTH 4 +#define ROUTER_CTRL_E_OFFSET 0x0 +#define ROUTER_CTRL_NR_E 1 + +#define ARP_LEARN_MODE +#define ROUTER_CTRL_ARP_LEARN_MODE_BOFFSET 19 +#define ROUTER_CTRL_ARP_LEARN_MODE_BLEN 1 +#define ROUTER_CTRL_ARP_LEARN_MODE_FLAG HSL_RW + +#define GLB_LOCKTIME +#define ROUTER_CTRL_GLB_LOCKTIME_BOFFSET 16 +#define ROUTER_CTRL_GLB_LOCKTIME_BLEN 2 +#define ROUTER_CTRL_GLB_LOCKTIME_FLAG HSL_RW + +#define ARP_AGE_TIME +#define ROUTER_CTRL_ARP_AGE_TIME_BOFFSET 8 +#define ROUTER_CTRL_ARP_AGE_TIME_BLEN 8 +#define ROUTER_CTRL_ARP_AGE_TIME_FLAG HSL_RW + +#define WCMP_HAHS_DP +#define ROUTER_CTRL_WCMP_HAHS_DP_BOFFSET 7 +#define ROUTER_CTRL_WCMP_HAHS_DP_BLEN 1 +#define ROUTER_CTRL_WCMP_HAHS_DP_FLAG HSL_RW + +#define WCMP_HAHS_DIP +#define ROUTER_CTRL_WCMP_HAHS_DIP_BOFFSET 6 +#define ROUTER_CTRL_WCMP_HAHS_DIP_BLEN 1 +#define ROUTER_CTRL_WCMP_HAHS_DIP_FLAG HSL_RW + +#define WCMP_HAHS_SP +#define ROUTER_CTRL_WCMP_HAHS_SP_BOFFSET 5 +#define ROUTER_CTRL_WCMP_HAHS_SP_BLEN 1 +#define ROUTER_CTRL_WCMP_HAHS_SP_FLAG HSL_RW + +#define WCMP_HAHS_SIP +#define ROUTER_CTRL_WCMP_HAHS_SIP_BOFFSET 4 +#define ROUTER_CTRL_WCMP_HAHS_SIP_BLEN 1 +#define ROUTER_CTRL_WCMP_HAHS_SIP_FLAG HSL_RW + +#define ARP_AGE_MODE +#define ROUTER_CTRL_ARP_AGE_MODE_BOFFSET 1 +#define ROUTER_CTRL_ARP_AGE_MODE_BLEN 1 +#define ROUTER_CTRL_ARP_AGE_MODE_FLAG HSL_RW + +#define ROUTER_EN +#define ROUTER_CTRL_ROUTER_EN_BOFFSET 0 +#define ROUTER_CTRL_ROUTER_EN_BLEN 1 +#define ROUTER_CTRL_ROUTER_EN_FLAG HSL_RW + + + + +#define ROUTER_PTCTRL0 +#define ROUTER_PTCTRL0_OFFSET 0x0e04 +#define ROUTER_PTCTRL0_E_LENGTH 4 +#define ROUTER_PTCTRL0_E_OFFSET 0x0 +#define ROUTER_PTCTRL0_NR_E 1 + + + + +#define ROUTER_PTCTRL1 +#define ROUTER_PTCTRL1_OFFSET 0x0e08 +#define ROUTER_PTCTRL1_E_LENGTH 4 +#define ROUTER_PTCTRL1_E_OFFSET 0x0 +#define ROUTER_PTCTRL1_NR_E 1 + + + +#define ROUTER_PTCTRL2 +#define ROUTER_PTCTRL2_OFFSET 0x0e0c +#define ROUTER_PTCTRL2_E_LENGTH 4 +#define ROUTER_PTCTRL2_E_OFFSET 0x0 +#define ROUTER_PTCTRL2_NR_E 1 + +#define ARP_PT_UP +#define ROUTER_PTCTRL2_ARP_PT_UP_BOFFSET 16 +#define ROUTER_PTCTRL2_ARP_PT_UP_BLEN 7 +#define ROUTER_PTCTRL2_ARP_PT_UP_FLAG HSL_RW + +#define ARP_LEARN_ACK +#define ROUTER_PTCTRL2_ARP_LEARN_ACK_BOFFSET 8 +#define ROUTER_PTCTRL2_ARP_LEARN_ACK_BLEN 7 +#define ROUTER_PTCTRL2_ARP_LEARN_ACK_FLAG HSL_RW + +#define ARP_LEARN_REQ +#define ROUTER_PTCTRL2_ARP_LEARN_REQ_BOFFSET 0 +#define ROUTER_PTCTRL2_ARP_LEARN_REQ_BLEN 7 +#define ROUTER_PTCTRL2_ARP_LEARN_REQ_FLAG HSL_RW + + + + +#define NAT_CTRL +#define NAT_CTRL_OFFSET 0x0e38 +#define NAT_CTRL_E_LENGTH 4 +#define NAT_CTRL_E_OFFSET 0x0 +#define NAT_CTRL_NR_E 1 + +#define NAT_HASH_MODE +#define NAT_CTRL_NAT_HASH_MODE_BOFFSET 5 +#define NAT_CTRL_NAT_HASH_MODE_BLEN 2 +#define NAT_CTRL_NAT_HASH_MODE_FLAG HSL_RW + +#define NAPT_OVERRIDE +#define NAT_CTRL_NAPT_OVERRIDE_BOFFSET 4 +#define NAT_CTRL_NAPT_OVERRIDE_BLEN 1 +#define NAT_CTRL_NAPT_OVERRIDE_FLAG HSL_RW + +#define NAPT_MODE +#define NAT_CTRL_NAPT_MODE_BOFFSET 2 +#define NAT_CTRL_NAPT_MODE_BLEN 2 +#define NAT_CTRL_NAPT_MODE_FLAG HSL_RW + +#define NAT_EN +#define NAT_CTRL_NAT_EN_BOFFSET 1 +#define NAT_CTRL_NAT_EN_BLEN 1 +#define NAT_CTRL_NAT_EN_FLAG HSL_RW + +#define NAPT_EN +#define NAT_CTRL_NAPT_EN_BOFFSET 0 +#define NAT_CTRL_NAPT_EN_BLEN 1 +#define NAT_CTRL_NAPT_EN_FLAG HSL_RW + + + + +#define PRV_BASEADDR +#define PRV_BASEADDR_OFFSET 0x0e5c +#define PRV_BASEADDR_E_LENGTH 4 +#define PRV_BASEADDR_E_OFFSET 0x0 +#define PRV_BASEADDR_NR_E 1 + +#define IP4_ADDR +#define PRV_BASEADDR_IP4_ADDR_BOFFSET 0 +#define PRV_BASEADDR_IP4_ADDR_BLEN 20 +#define PRV_BASEADDR_IP4_ADDR_FLAG HSL_RW + + + + +#define PRVIP_ADDR +#define PRVIP_ADDR_OFFSET 0x0470 +#define PRVIP_ADDR_E_LENGTH 4 +#define PRVIP_ADDR_E_OFFSET 0x0 +#define PRVIP_ADDR_NR_E 1 + +#define IP4_BASEADDR +#define PRVIP_ADDR_IP4_BASEADDR_BOFFSET 0 +#define PRVIP_ADDR_IP4_BASEADDR_BLEN 32 +#define PRVIP_ADDR_IP4_BASEADDR_FLAG HSL_RW + + +#define PRVIP_MASK +#define PRVIP_MASK_OFFSET 0x0474 +#define PRVIP_MASK_E_LENGTH 4 +#define PRVIP_MASK_E_OFFSET 0x0 +#define PRVIP_MASK_NR_E 1 + +#define IP4_BASEMASK +#define PRVIP_MASK_IP4_BASEMASK_BOFFSET 0 +#define PRVIP_MASK_IP4_BASEMASK_BLEN 32 +#define PRVIP_MASK_IP4_BASEMASK_FLAG HSL_RW + + + + +#define PUB_ADDR0 +#define PUB_ADDR0_OFFSET 0x5aa00 +#define PUB_ADDR0_E_LENGTH 4 +#define PUB_ADDR0_E_OFFSET 0x0 +#define PUB_ADDR0_NR_E 1 + +#define IP4_ADDR +#define PUB_ADDR0_IP4_ADDR_BOFFSET 0 +#define PUB_ADDR0_IP4_ADDR_BLEN 32 +#define PUB_ADDR0_IP4_ADDR_FLAG HSL_RW + + +#define PUB_ADDR1 +#define PUB_ADDR1_OFFSET 0x5aa04 +#define PUB_ADDR1_E_LENGTH 4 +#define PUB_ADDR1_E_OFFSET 0x0 +#define PUB_ADDR1_NR_E 1 + +#define ADDR_VALID +#define PUB_ADDR1_ADDR_VALID_BOFFSET 0 +#define PUB_ADDR1_ADDR_VALID_BLEN 1 +#define PUB_ADDR1_ADDR_VALID_FLAG HSL_RW + + + + +#define INTF_ADDR_ENTRY0 +#define INTF_ADDR_ENTRY0_OFFSET 0x5aa00 +#define INTF_ADDR_ENTRY0_E_LENGTH 4 +#define INTF_ADDR_ENTRY0_E_OFFSET 0x0 +#define INTF_ADDR_ENTRY0_NR_E 8 + +#define MAC_ADDR2 +#define INTF_ADDR_ENTRY0_MAC_ADDR2_BOFFSET 24 +#define INTF_ADDR_ENTRY0_MAC_ADDR2_BLEN 8 +#define INTF_ADDR_ENTRY0_MAC_ADDR2_FLAG HSL_RW + +#define MAC_ADDR3 +#define INTF_ADDR_ENTRY0_MAC_ADDR3_BOFFSET 16 +#define INTF_ADDR_ENTRY0_MAC_ADDR3_BLEN 8 +#define INTF_ADDR_ENTRY0_MAC_ADDR3_FLAG HSL_RW + +#define MAC_ADDR4 +#define INTF_ADDR_ENTRY0_MAC_ADDR4_BOFFSET 8 +#define INTF_ADDR_ENTRY0_MAC_ADDR4_BLEN 8 +#define INTF_ADDR_ENTRY0_MAC_ADDR4_FLAG HSL_RW + +#define MAC_ADDR5 +#define INTF_ADDR_ENTRY0_MAC_ADDR5_BOFFSET 0 +#define INTF_ADDR_ENTRY0_MAC_ADDR5_BLEN 8 +#define INTF_ADDR_ENTRY0_MAC_ADDR5_FLAG HSL_RW + + +#define INTF_ADDR_ENTRY1 +#define INTF_ADDR_ENTRY1_OFFSET 0x5aa04 +#define INTF_ADDR_ENTRY1_E_LENGTH 4 +#define INTF_ADDR_ENTRY1_E_OFFSET 0x0 +#define INTF_ADDR_ENTRY1_NR_E 8 + +#define VID_HIGH0 +#define INTF_ADDR_ENTRY1_VID_HIGH0_BOFFSET 28 +#define INTF_ADDR_ENTRY1_VID_HIGH0_BLEN 4 +#define INTF_ADDR_ENTRY1_VID_HIGH0_FLAG HSL_RW + +#define VID_LOW +#define INTF_ADDR_ENTRY1_VID_LOW_BOFFSET 16 +#define INTF_ADDR_ENTRY1_VID_LOW_BLEN 12 +#define INTF_ADDR_ENTRY1_VID_LOW_FLAG HSL_RW + +#define MAC_ADDR0 +#define INTF_ADDR_ENTRY1_MAC_ADDR0_BOFFSET 8 +#define INTF_ADDR_ENTRY1_MAC_ADDR0_BLEN 8 +#define INTF_ADDR_ENTRY1_MAC_ADDR0_FLAG HSL_RW + +#define MAC_ADDR1 +#define INTF_ADDR_ENTRY1_MAC_ADDR1_BOFFSET 0 +#define INTF_ADDR_ENTRY1_MAC_ADDR1_BLEN 8 +#define INTF_ADDR_ENTRY1_MAC_ADDR1_FLAG HSL_RW + + +#define INTF_ADDR_ENTRY2 +#define INTF_ADDR_ENTRY2_OFFSET 0x5aa08 +#define INTF_ADDR_ENTRY2_E_LENGTH 4 +#define INTF_ADDR_ENTRY2_E_OFFSET 0x0 +#define INTF_ADDR_ENTRY2_NR_E 8 + +#define IP6_ROUTE +#define INTF_ADDR_ENTRY2_IP6_ROUTE_BOFFSET 9 +#define INTF_ADDR_ENTRY2_IP6_ROUTE_BLEN 1 +#define INTF_ADDR_ENTRY2_IP6_ROUTE_FLAG HSL_RW + +#define IP4_ROUTE +#define INTF_ADDR_ENTRY2_IP4_ROUTE_BOFFSET 8 +#define INTF_ADDR_ENTRY2_IP4_ROUTE_BLEN 1 +#define INTF_ADDR_ENTRY2_IP4_ROUTE_FLAG HSL_RW + +#define VID_HIGH1 +#define INTF_ADDR_ENTRY2_VID_HIGH1_BOFFSET 0 +#define INTF_ADDR_ENTRY2_VID_HIGH1_BLEN 8 +#define INTF_ADDR_ENTRY2_VID_HIGH1_FLAG HSL_RW + + + + + /* Port Shaper Register0 */ +#define EG_SHAPER0 +#define EG_SHAPER0_OFFSET 0x0890 +#define EG_SHAPER0_E_LENGTH 4 +#define EG_SHAPER0_E_OFFSET 0x0020 +#define EG_SHAPER0_NR_E 7 + +#define EG_Q1_CIR +#define EG_SHAPER0_EG_Q1_CIR_BOFFSET 16 +#define EG_SHAPER0_EG_Q1_CIR_BLEN 15 +#define EG_SHAPER0_EG_Q1_CIR_FLAG HSL_RW + +#define EG_Q0_CIR +#define EG_SHAPER0_EG_Q0_CIR_BOFFSET 0 +#define EG_SHAPER0_EG_Q0_CIR_BLEN 15 +#define EG_SHAPER0_EG_Q0_CIR_FLAG HSL_RW + + + /* Port Shaper Register1 */ +#define EG_SHAPER1 +#define EG_SHAPER1_OFFSET 0x0894 +#define EG_SHAPER1_E_LENGTH 4 +#define EG_SHAPER1_E_OFFSET 0x0020 +#define EG_SHAPER1_NR_E 7 + +#define EG_Q3_CIR +#define EG_SHAPER1_EG_Q3_CIR_BOFFSET 16 +#define EG_SHAPER1_EG_Q3_CIR_BLEN 15 +#define EG_SHAPER1_EG_Q3_CIR_FLAG HSL_RW + +#define EG_Q2_CIR +#define EG_SHAPER1_EG_Q2_CIR_BOFFSET 0 +#define EG_SHAPER1_EG_Q2_CIR_BLEN 15 +#define EG_SHAPER1_EG_Q2_CIR_FLAG HSL_RW + + + /* Port Shaper Register2 */ +#define EG_SHAPER2 +#define EG_SHAPER2_OFFSET 0x0898 +#define EG_SHAPER2_E_LENGTH 4 +#define EG_SHAPER2_E_OFFSET 0x0020 +#define EG_SHAPER2_NR_E 7 + +#define EG_Q5_CIR +#define EG_SHAPER2_EG_Q5_CIR_BOFFSET 16 +#define EG_SHAPER2_EG_Q5_CIR_BLEN 15 +#define EG_SHAPER2_EG_Q5_CIR_FLAG HSL_RW + +#define EG_Q4_CIR +#define EG_SHAPER2_EG_Q4_CIR_BOFFSET 0 +#define EG_SHAPER2_EG_Q4_CIR_BLEN 15 +#define EG_SHAPER2_EG_Q4_CIR_FLAG HSL_RW + + + /* Port Shaper Register3 */ +#define EG_SHAPER3 +#define EG_SHAPER3_OFFSET 0x089c +#define EG_SHAPER3_E_LENGTH 4 +#define EG_SHAPER3_E_OFFSET 0x0020 +#define EG_SHAPER3_NR_E 7 + +#define EG_Q1_EIR +#define EG_SHAPER3_EG_Q1_EIR_BOFFSET 16 +#define EG_SHAPER3_EG_Q1_EIR_BLEN 15 +#define EG_SHAPER3_EG_Q1_EIR_FLAG HSL_RW + +#define EG_Q0_EIR +#define EG_SHAPER3_EG_Q0_EIR_BOFFSET 0 +#define EG_SHAPER3_EG_Q0_EIR_BLEN 15 +#define EG_SHAPER3_EG_Q0_EIR_FLAG HSL_RW + + + /* Port Shaper Register4 */ +#define EG_SHAPER4 +#define EG_SHAPER4_OFFSET 0x08a0 +#define EG_SHAPER4_E_LENGTH 4 +#define EG_SHAPER4_E_OFFSET 0x0020 +#define EG_SHAPER4_NR_E 7 + +#define EG_Q3_EIR +#define EG_SHAPER4_EG_Q3_EIR_BOFFSET 16 +#define EG_SHAPER4_EG_Q3_EIR_BLEN 15 +#define EG_SHAPER4_EG_Q3_EIR_FLAG HSL_RW + +#define EG_Q2_EIR +#define EG_SHAPER4_EG_Q2_EIR_BOFFSET 0 +#define EG_SHAPER4_EG_Q2_EIR_BLEN 15 +#define EG_SHAPER4_EG_Q2_EIR_FLAG HSL_RW + + + /* Port Shaper Register5 */ +#define EG_SHAPER5 +#define EG_SHAPER5_OFFSET 0x08a4 +#define EG_SHAPER5_E_LENGTH 4 +#define EG_SHAPER5_E_OFFSET 0x0020 +#define EG_SHAPER5_NR_E 7 + +#define EG_Q5_EIR +#define EG_SHAPER5_EG_Q5_EIR_BOFFSET 16 +#define EG_SHAPER5_EG_Q5_EIR_BLEN 15 +#define EG_SHAPER5_EG_Q5_EIR_FLAG HSL_RW + +#define EG_Q4_EIR +#define EG_SHAPER5_EG_Q4_EIR_BOFFSET 0 +#define EG_SHAPER5_EG_Q4_EIR_BLEN 15 +#define EG_SHAPER5_EG_Q4_EIR_FLAG HSL_RW + + + /* Port Shaper Register6 */ +#define EG_SHAPER6 +#define EG_SHAPER6_OFFSET 0x08a8 +#define EG_SHAPER6_E_LENGTH 4 +#define EG_SHAPER6_E_OFFSET 0x0020 +#define EG_SHAPER6_NR_E 7 + +#define EG_Q3_CBS +#define EG_SHAPER6_EG_Q3_CBS_BOFFSET 28 +#define EG_SHAPER6_EG_Q3_CBS_BLEN 3 +#define EG_SHAPER6_EG_Q3_CBS_FLAG HSL_RW + +#define EG_Q3_EBS +#define EG_SHAPER6_EG_Q3_EBS_BOFFSET 24 +#define EG_SHAPER6_EG_Q3_EBS_BLEN 3 +#define EG_SHAPER6_EG_Q3_EBS_FLAG HSL_RW + +#define EG_Q2_CBS +#define EG_SHAPER6_EG_Q2_CBS_BOFFSET 20 +#define EG_SHAPER6_EG_Q2_CBS_BLEN 3 +#define EG_SHAPER6_EG_Q2_CBS_FLAG HSL_RW + +#define EG_Q2_EBS +#define EG_SHAPER6_EG_Q2_EBS_BOFFSET 16 +#define EG_SHAPER6_EG_Q2_EBS_BLEN 3 +#define EG_SHAPER6_EG_Q2_EBS_FLAG HSL_RW + +#define EG_Q1_CBS +#define EG_SHAPER6_EG_Q1_CBS_BOFFSET 12 +#define EG_SHAPER6_EG_Q1_CBS_BLEN 3 +#define EG_SHAPER6_EG_Q1_CBS_FLAG HSL_RW + +#define EG_Q1_EBS +#define EG_SHAPER6_EG_Q1_EBS_BOFFSET 8 +#define EG_SHAPER6_EG_Q1_EBS_BLEN 3 +#define EG_SHAPER6_EG_Q1_EBS_FLAG HSL_RW + +#define EG_Q0_CBS +#define EG_SHAPER6_EG_Q0_CBS_BOFFSET 4 +#define EG_SHAPER6_EG_Q0_CBS_BLEN 3 +#define EG_SHAPER6_EG_Q0_CBS_FLAG HSL_RW + +#define EG_Q0_EBS +#define EG_SHAPER6_EG_Q0_EBS_BOFFSET 0 +#define EG_SHAPER6_EG_Q0_EBS_BLEN 3 +#define EG_SHAPER6_EG_Q0_EBS_FLAG HSL_RW + + + /* Port Shaper Register7 */ +#define EG_SHAPER7 +#define EG_SHAPER7_OFFSET 0x08ac +#define EG_SHAPER7_E_LENGTH 4 +#define EG_SHAPER7_E_OFFSET 0x0020 +#define EG_SHAPER7_NR_E 7 + +#define EG_Q5_CBS +#define EG_SHAPER7_EG_Q5_CBS_BOFFSET 28 +#define EG_SHAPER7_EG_Q5_CBS_BLEN 3 +#define EG_SHAPER7_EG_Q5_CBS_FLAG HSL_RW + +#define EG_Q5_EBS +#define EG_SHAPER7_EG_Q5_EBS_BOFFSET 24 +#define EG_SHAPER7_EG_Q5_EBS_BLEN 3 +#define EG_SHAPER7_EG_Q5_EBS_FLAG HSL_RW + +#define EG_Q4_CBS +#define EG_SHAPER7_EG_Q4_CBS_BOFFSET 20 +#define EG_SHAPER7_EG_Q4_CBS_BLEN 3 +#define EG_SHAPER7_EG_Q4_CBS_FLAG HSL_RW + +#define EG_Q4_EBS +#define EG_SHAPER7_EG_Q4_EBS_BOFFSET 16 +#define EG_SHAPER7_EG_Q4_EBS_BLEN 3 +#define EG_SHAPER7_EG_Q4_EBS_FLAG HSL_RW + +#define EG_Q5_UNIT +#define EG_SHAPER7_EG_Q5_UNIT_BOFFSET 13 +#define EG_SHAPER7_EG_Q5_UNIT_BLEN 1 +#define EG_SHAPER7_EG_Q5_UNIT_FLAG HSL_RW + +#define EG_Q4_UNIT +#define EG_SHAPER7_EG_Q4_UNIT_BOFFSET 12 +#define EG_SHAPER7_EG_Q4_UNIT_BLEN 1 +#define EG_SHAPER7_EG_Q4_UNIT_FLAG HSL_RW + +#define EG_Q3_UNIT +#define EG_SHAPER7_EG_Q3_UNIT_BOFFSET 11 +#define EG_SHAPER7_EG_Q3_UNIT_BLEN 1 +#define EG_SHAPER7_EG_Q3_UNIT_FLAG HSL_RW + +#define EG_Q2_UNIT +#define EG_SHAPER7_EG_Q2_UNIT_BOFFSET 10 +#define EG_SHAPER7_EG_Q2_UNIT_BLEN 1 +#define EG_SHAPER7_EG_Q2_UNIT_FLAG HSL_RW + +#define EG_Q1_UNIT +#define EG_SHAPER7_EG_Q1_UNIT_BOFFSET 9 +#define EG_SHAPER7_EG_Q1_UNIT_BLEN 1 +#define EG_SHAPER7_EG_Q1_UNIT_FLAG HSL_RW + +#define EG_Q0_UNIT +#define EG_SHAPER7_EG_Q0_UNIT_BOFFSET 8 +#define EG_SHAPER7_EG_Q0_UNIT_BLEN 1 +#define EG_SHAPER7_EG_Q0_UNIT_FLAG HSL_RW + +#define EG_PT +#define EG_SHAPER7_EG_PT_BOFFSET 3 +#define EG_SHAPER7_EG_PT_BLEN 1 +#define EG_SHAPER7_EG_PT_FLAG HSL_RW + +#define EG_TS +#define EG_SHAPER7_EG_TS_BOFFSET 0 +#define EG_SHAPER7_EG_TS_BLEN 3 +#define EG_SHAPER7_EG_TS_FLAG HSL_RW + + + + /* ACL Policer Register0 */ +#define ACL_POLICER0 +#define ACL_POLICER0_OFFSET 0x0a00 +#define ACL_POLICER0_E_LENGTH 4 +#define ACL_POLICER0_E_OFFSET 0x0008 +#define ACL_POLICER0_NR_E 32 + +#define ACL_CBS +#define ACL_POLICER0_ACL_CBS_BOFFSET 15 +#define ACL_POLICER0_ACL_CBS_BLEN 3 +#define ACL_POLICER0_ACL_CBS_FLAG HSL_RW + +#define ACL_CIR +#define ACL_POLICER0_ACL_CIR_BOFFSET 0 +#define ACL_POLICER0_ACL_CIR_BLEN 15 +#define ACL_POLICER0_ACL_CIR_FLAG HSL_RW + + + /* ACL Policer Register1 */ +#define ACL_POLICER1 +#define ACL_POLICER1_OFFSET 0x0a04 +#define ACL_POLICER1_E_LENGTH 4 +#define ACL_POLICER1_E_OFFSET 0x0008 +#define ACL_POLICER1_NR_E 32 + +#define ACL_BORROW +#define ACL_POLICER1_ACL_BORROW_BOFFSET 23 +#define ACL_POLICER1_ACL_BORROW_BLEN 1 +#define ACL_POLICER1_ACL_BORROW_FLAG HSL_RW + +#define ACL_UNIT +#define ACL_POLICER1_ACL_UNIT_BOFFSET 22 +#define ACL_POLICER1_ACL_UNIT_BLEN 1 +#define ACL_POLICER1_ACL_UNIT_FLAG HSL_RW + +#define ACL_CF +#define ACL_POLICER1_ACL_CF_BOFFSET 21 +#define ACL_POLICER1_ACL_CF_BLEN 1 +#define ACL_POLICER1_ACL_CF_FLAG HSL_RW + +#define ACL_CM +#define ACL_POLICER1_ACL_CM_BOFFSET 20 +#define ACL_POLICER1_ACL_CM_BLEN 1 +#define ACL_POLICER1_ACL_CM_FLAG HSL_RW + +#define ACL_TS +#define ACL_POLICER1_ACL_TS_BOFFSET 18 +#define ACL_POLICER1_ACL_TS_BLEN 2 +#define ACL_POLICER1_ACL_TS_FLAG HSL_RW + +#define ACL_EBS +#define ACL_POLICER1_ACL_EBS_BOFFSET 15 +#define ACL_POLICER1_ACL_EBS_BLEN 3 +#define ACL_POLICER1_ACL_EBS_FLAG HSL_RW + +#define ACL_EIR +#define ACL_POLICER1_ACL_EIR_BOFFSET 0 +#define ACL_POLICER1_ACL_EIR_BLEN 15 +#define ACL_POLICER1_ACL_EIR_FLAG HSL_RW + + + /* ACL Counter Register0 */ +#define ACL_COUNTER0 +#define ACL_COUNTER0_OFFSET 0x1c000 +#define ACL_COUNTER0_E_LENGTH 4 +#define ACL_COUNTER0_E_OFFSET 0x0008 +#define ACL_COUNTER0_NR_E 32 + + /* ACL Counter Register1 */ +#define ACL_COUNTER1 +#define ACL_COUNTER1_OFFSET 0x1c004 +#define ACL_COUNTER1_E_LENGTH 4 +#define ACL_COUNTER1_E_OFFSET 0x0008 +#define ACL_COUNTER1_NR_E 32 + + + + + /* INGRESS Policer Register0 */ +#define INGRESS_POLICER0 +#define INGRESS_POLICER0_OFFSET 0x0b00 +#define INGRESS_POLICER0_E_LENGTH 4 +#define INGRESS_POLICER0_E_OFFSET 0x0010 +#define INGRESS_POLICER0_NR_E 7 + +#define ADD_RATE_BYTE +#define INGRESS_POLICER0_ADD_RATE_BYTE_BOFFSET 24 +#define INGRESS_POLICER0_ADD_RATE_BYTE_BLEN 8 +#define INGRESS_POLICER0_ADD_RATE_BYTE_FLAG HSL_RW + +#define C_ING_TS +#define INGRESS_POLICER0_C_ING_TS_BOFFSET 22 +#define INGRESS_POLICER0_C_ING_TS_BLEN 2 +#define INGRESS_POLICER0_C_ING_TS_FLAG HSL_RW + +#define RATE_MODE +#define INGRESS_POLICER0_RATE_MODE_BOFFSET 20 +#define INGRESS_POLICER0_RATE_MODE_BLEN 1 +#define INGRESS_POLICER0_RATE_MODE_FLAG HSL_RW + +#define INGRESS_CBS +#define INGRESS_POLICER0_INGRESS_CBS_BOFFSET 15 +#define INGRESS_POLICER0_INGRESS_CBS_BLEN 3 +#define INGRESS_POLICER0_INGRESS_CBS_FLAG HSL_RW + +#define INGRESS_CIR +#define INGRESS_POLICER0_INGRESS_CIR_BOFFSET 0 +#define INGRESS_POLICER0_INGRESS_CIR_BLEN 15 +#define INGRESS_POLICER0_INGRESS_CIR_FLAG HSL_RW + + + /* INGRESS Policer Register1 */ +#define INGRESS_POLICER1 +#define INGRESS_POLICER1_OFFSET 0x0b04 +#define INGRESS_POLICER1_E_LENGTH 4 +#define INGRESS_POLICER1_E_OFFSET 0x0010 +#define INGRESS_POLICER1_NR_E 7 + +#define INGRESS_BORROW +#define INGRESS_POLICER1_INGRESS_BORROW_BOFFSET 23 +#define INGRESS_POLICER1_INGRESS_BORROW_BLEN 1 +#define INGRESS_POLICER1_INGRESS_BORROW_FLAG HSL_RW + +#define INGRESS_UNIT +#define INGRESS_POLICER1_INGRESS_UNIT_BOFFSET 22 +#define INGRESS_POLICER1_INGRESS_UNIT_BLEN 1 +#define INGRESS_POLICER1_INGRESS_UNIT_FLAG HSL_RW + +#define INGRESS_CF +#define INGRESS_POLICER1_INGRESS_CF_BOFFSET 21 +#define INGRESS_POLICER1_INGRESS_CF_BLEN 1 +#define INGRESS_POLICER1_INGRESS_CF_FLAG HSL_RW + +#define INGRESS_CM +#define INGRESS_POLICER1_INGRESS_CM_BOFFSET 20 +#define INGRESS_POLICER1_INGRESS_CM_BLEN 1 +#define INGRESS_POLICER1_INGRESS_CM_FLAG HSL_RW + +#define E_ING_TS +#define INGRESS_POLICER1_E_ING_TS_BOFFSET 18 +#define INGRESS_POLICER1_E_ING_TS_BLEN 2 +#define INGRESS_POLICER1_E_ING_TS_FLAG HSL_RW + +#define INGRESS_EBS +#define INGRESS_POLICER1_INGRESS_EBS_BOFFSET 15 +#define INGRESS_POLICER1_INGRESS_EBS_BLEN 3 +#define INGRESS_POLICER1_INGRESS_EBS_FLAG HSL_RW + +#define INGRESS_EIR +#define INGRESS_POLICER1_INGRESS_EIR_BOFFSET 0 +#define INGRESS_POLICER1_INGRESS_EIR_BLEN 15 +#define INGRESS_POLICER1_INGRESS_EIR_FLAG HSL_RW + + + /* INGRESS Policer Register2 */ +#define INGRESS_POLICER2 +#define INGRESS_POLICER2_OFFSET 0x0b08 +#define INGRESS_POLICER2_E_LENGTH 4 +#define INGRESS_POLICER2_E_OFFSET 0x0010 +#define INGRESS_POLICER2_NR_E 7 + +#define C_MUL +#define INGRESS_POLICER2_C_MUL_BOFFSET 15 +#define INGRESS_POLICER2_C_MUL_BLEN 1 +#define INGRESS_POLICER2_C_UNK_MUL_FLAG HSL_RW + +#define C_UNI +#define INGRESS_POLICER2_C_UNI_BOFFSET 14 +#define INGRESS_POLICER2_C_UNI_BLEN 1 +#define INGRESS_POLICER2_C_UNI_FLAG HSL_RW + +#define C_UNK_MUL +#define INGRESS_POLICER2_C_UNK_MUL_BOFFSET 13 +#define INGRESS_POLICER2_C_UNK_MUL_BLEN 1 +#define INGRESS_POLICER2_C_UNK_MUL_FLAG HSL_RW + +#define C_UNK_UNI +#define INGRESS_POLICER2_C_UNK_UNI_BOFFSET 12 +#define INGRESS_POLICER2_C_UNK_UNI_BLEN 1 +#define INGRESS_POLICER2_C_UNK_UNI_FLAG HSL_RW + +#define C_BROAD +#define INGRESS_POLICER2_C_BROAD_BOFFSET 11 +#define INGRESS_POLICER2_C_BROAD_BLEN 1 +#define INGRESS_POLICER2_C_BROAD_FLAG HSL_RW + +#define C_MANAGE +#define INGRESS_POLICER2_C_MANAGC_BOFFSET 10 +#define INGRESS_POLICER2_C_MANAGC_BLEN 1 +#define INGRESS_POLICER2_C_MANAGC_FLAG HSL_RW + +#define C_TCP +#define INGRESS_POLICER2_C_TCP_BOFFSET 9 +#define INGRESS_POLICER2_C_TCP_BLEN 1 +#define INGRESS_POLICER2_C_TCP_FLAG HSL_RW + +#define C_MIRR +#define INGRESS_POLICER2_C_MIRR_BOFFSET 8 +#define INGRESS_POLICER2_C_MIRR_BLEN 1 +#define INGRESS_POLICER2_C_MIRR_FLAG HSL_RW + +#define E_MUL +#define INGRESS_POLICER2_E_MUL_BOFFSET 7 +#define INGRESS_POLICER2_E_MUL_BLEN 1 +#define INGRESS_POLICER2_E_UNK_MUL_FLAG HSL_RW + +#define E_UNI +#define INGRESS_POLICER2_E_UNI_BOFFSET 6 +#define INGRESS_POLICER2_E_UNI_BLEN 1 +#define INGRESS_POLICER2_E_UNI_FLAG HSL_RW + +#define E_UNK_MUL +#define INGRESS_POLICER2_E_UNK_MUL_BOFFSET 5 +#define INGRESS_POLICER2_E_UNK_MUL_BLEN 1 +#define INGRESS_POLICER2_E_UNK_MUL_FLAG HSL_RW + +#define E_UNK_UNI +#define INGRESS_POLICER2_E_UNK_UNI_BOFFSET 4 +#define INGRESS_POLICER2_E_UNK_UNI_BLEN 1 +#define INGRESS_POLICER2_E_UNK_UNI_FLAG HSL_RW + +#define E_BROAD +#define INGRESS_POLICER2_E_BROAD_BOFFSET 3 +#define INGRESS_POLICER2_E_BROAD_BLEN 1 +#define INGRESS_POLICER2_E_BROAD_FLAG HSL_RW + +#define E_MANAGE +#define INGRESS_POLICER2_E_MANAGE_BOFFSET 2 +#define INGRESS_POLICER2_E_MANAGE_BLEN 1 +#define INGRESS_POLICER2_E_MANAGE_FLAG HSL_RW + +#define E_TCP +#define INGRESS_POLICER2_E_TCP_BOFFSET 1 +#define INGRESS_POLICER2_E_TCP_BLEN 1 +#define INGRESS_POLICER2_E_TCP_FLAG HSL_RW + +#define E_MIRR +#define INGRESS_POLICER2_E_MIRR_BOFFSET 0 +#define INGRESS_POLICER2_E_MIRR_BLEN 1 +#define INGRESS_POLICER2_E_MIRR_FLAG HSL_RW + + + + + /* Port Rate Limit2 Register */ +#define WRR_CTRL +#define WRR_CTRL_OFFSET 0x0830 +#define WRR_CTRL_E_LENGTH 4 +#define WRR_CTRL_E_OFFSET 0x0004 +#define WRR_CTRL_NR_E 7 + +#define SCH_MODE +#define WRR_CTRL_SCH_MODE_BOFFSET 30 +#define WRR_CTRL_SCH_MODE_BLEN 2 +#define WRR_CTRL_SCH_MODE_FLAG HSL_RW + +#define Q5_W +#define WRR_CTRL_Q5_W_BOFFSET 25 +#define WRR_CTRL_Q5_W_BLEN 5 +#define WRR_CTRL_Q5_W_FLAG HSL_RW + +#define Q4_W +#define WRR_CTRL_Q4_W_BOFFSET 20 +#define WRR_CTRL_Q4_W_BLEN 5 +#define WRR_CTRL_Q4_W_FLAG HSL_RW + +#define Q3_W +#define WRR_CTRL_Q3_W_BOFFSET 15 +#define WRR_CTRL_Q3_W_BLEN 5 +#define WRR_CTRL_Q3_W_FLAG HSL_RW + +#define Q2_W +#define WRR_CTRL_Q2_W_BOFFSET 10 +#define WRR_CTRL_Q2_W_BLEN 5 +#define WRR_CTRL_Q2_W_FLAG HSL_RW + +#define Q1_W +#define WRR_CTRL_Q1_W_BOFFSET 5 +#define WRR_CTRL_Q1_W_BLEN 5 +#define WRR_CTRL_Q1_W_FLAG HSL_RW + +#define Q0_W +#define WRR_CTRL_Q0_W_BOFFSET 0 +#define WRR_CTRL_Q0_W_BLEN 5 +#define WRR_CTRL_Q0_W_FLAG HSL_RW + + + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISISC_REG_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_reg_access.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_reg_access.h new file mode 100755 index 000000000..5f6ea310b --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_reg_access.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2012,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 _ISISC_REG_ACCESS_H_ +#define _ISISC_REG_ACCESS_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "sw.h" + + sw_error_t + isisc_phy_get(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t * value); + + sw_error_t + isisc_phy_set(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t value); + + sw_error_t + isisc_reg_get(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t value[], + a_uint32_t value_len); + + sw_error_t + isisc_reg_set(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t value[], + a_uint32_t value_len); + + sw_error_t + isisc_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 + isisc_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 + isisc_regsiter_dump(a_uint32_t dev_id,a_uint32_t register_idx, fal_reg_dump_t * reg_dump); + + sw_error_t + isisc_debug_regsiter_dump(a_uint32_t dev_id, fal_debug_reg_dump_t * reg_dump); + + sw_error_t + isisc_reg_access_init(a_uint32_t dev_id, hsl_access_mode mode); + + sw_error_t + isisc_access_mode_set(a_uint32_t dev_id, hsl_access_mode mode); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _ISISC_REG_ACCESS_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_sec.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_sec.h new file mode 100755 index 000000000..93849b49f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_sec.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISISC_SEC_H_ +#define _ISISC_SEC_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_sec.h" + + sw_error_t isisc_sec_init(a_uint32_t dev_id); + +#ifdef IN_SEC +#define ISISC_SEC_INIT(rv, dev_id) \ + { \ + rv = isisc_sec_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISISC_SEC_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + isisc_sec_norm_item_set(a_uint32_t dev_id, fal_norm_item_t item, + void *value); + + HSL_LOCAL sw_error_t + isisc_sec_norm_item_get(a_uint32_t dev_id, fal_norm_item_t item, + void *value); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISISC_SEC_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_stp.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_stp.h new file mode 100755 index 000000000..cb4b9c6f9 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_stp.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISISC_STP_H_ +#define _ISISC_STP_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_stp.h" + + sw_error_t isisc_stp_init(a_uint32_t dev_id); + +#ifdef IN_STP +#define ISISC_STP_INIT(rv, dev_id) \ + { \ + rv = isisc_stp_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISISC_STP_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + isisc_stp_port_state_set(a_uint32_t dev_id, a_uint32_t st_id, + fal_port_t port_id, fal_stp_state_t state); + + + HSL_LOCAL sw_error_t + isisc_stp_port_state_get(a_uint32_t dev_id, a_uint32_t st_id, + fal_port_t port_id, fal_stp_state_t * state); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISISC_STP_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_trunk.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_trunk.h new file mode 100755 index 000000000..4346e08d2 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_trunk.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISISC_TRUNK_H_ +#define _ISISC_TRUNK_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_trunk.h" + + sw_error_t isisc_trunk_init(a_uint32_t dev_id); + +#ifdef IN_TRUNK +#define ISISC_TRUNK_INIT(rv, dev_id) \ + { \ + rv = isisc_trunk_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISISC_TRUNK_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + isisc_trunk_group_set(a_uint32_t dev_id, a_uint32_t trunk_id, + a_bool_t enable, fal_pbmp_t member); + + HSL_LOCAL sw_error_t + isisc_trunk_group_get(a_uint32_t dev_id, a_uint32_t trunk_id, + a_bool_t * enable, fal_pbmp_t * member); + + HSL_LOCAL sw_error_t + isisc_trunk_hash_mode_set(a_uint32_t dev_id, a_uint32_t hash_mode); + + HSL_LOCAL sw_error_t + isisc_trunk_hash_mode_get(a_uint32_t dev_id, a_uint32_t * hash_mode); + + HSL_LOCAL sw_error_t + isisc_trunk_manipulate_sa_set(a_uint32_t dev_id, fal_mac_addr_t * addr); + + HSL_LOCAL sw_error_t + isisc_trunk_manipulate_sa_get(a_uint32_t dev_id, fal_mac_addr_t * addr); + + HSL_LOCAL sw_error_t + isisc_trunk_manipulate_dp(a_uint32_t dev_id, a_uint8_t * header, + a_uint32_t len, fal_pbmp_t dp_member); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ISISC_TRUNK_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_vlan.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_vlan.h new file mode 100755 index 000000000..c198a7208 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/isisc/isisc_vlan.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _ISISC_VLAN_H_ +#define _ISISC_VLAN_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_vlan.h" + + sw_error_t + isisc_vlan_init(a_uint32_t dev_id); + +#ifdef IN_VLAN +#define ISISC_VLAN_INIT(rv, dev_id) \ + { \ + rv = isisc_vlan_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define ISISC_VLAN_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + isisc_vlan_entry_append(a_uint32_t dev_id, const fal_vlan_t * vlan_entry); + + + HSL_LOCAL sw_error_t + isisc_vlan_create(a_uint32_t dev_id, a_uint32_t vlan_id); + + + HSL_LOCAL sw_error_t + isisc_vlan_next(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan); + + + HSL_LOCAL sw_error_t + isisc_vlan_find(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan); + + + HSL_LOCAL sw_error_t + isisc_vlan_delete(a_uint32_t dev_id, a_uint32_t vlan_id); + + + HSL_LOCAL sw_error_t + isisc_vlan_flush(a_uint32_t dev_id); + + + HSL_LOCAL sw_error_t + isisc_vlan_fid_set(a_uint32_t dev_id, a_uint32_t vlan_id, a_uint32_t fid); + + + HSL_LOCAL sw_error_t + isisc_vlan_fid_get(a_uint32_t dev_id, a_uint32_t vlan_id, a_uint32_t * fid); + + + HSL_LOCAL sw_error_t + isisc_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); + + + HSL_LOCAL sw_error_t + isisc_vlan_member_del(a_uint32_t dev_id, a_uint32_t vlan_id, fal_port_t port_id); + + + HSL_LOCAL sw_error_t + isisc_vlan_learning_state_set(a_uint32_t dev_id, a_uint32_t vlan_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + isisc_vlan_learning_state_get(a_uint32_t dev_id, a_uint32_t vlan_id, + a_bool_t * enable); + + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _ISISC_VLAN_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/mp/mp_mib.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/mp/mp_mib.h new file mode 100755 index 000000000..f79a761e5 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/mp/mp_mib.h @@ -0,0 +1,392 @@ +/* + * 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 _MP_MIB_H_ +#define _MP_MIB_H_ + +#define MMC_CONTROL_MAX_ENTRY 2 +#define TX_OCTET_COUNT_GOOD_BAD_MAX_ENTRY 2 +#define TX_FRAME_COUNT_GOOD_BAD_MAX_ENTRY 2 +#define TX_BROADCAST_FRAMES_GOOD_MAX_ENTRY 2 +#define TX_MULTICAST_FRAMES_GOOD_MAX_ENTRY 2 +#define TX_64OCTETS_FRAMES_GOOD_BAD_MAX_ENTRY 2 +#define TX_65TO127OCTETS_FRAMES_GOOD_BAD_MAX_ENTRY 2 +#define TX_128TO255OCTETS_FRAMES_GOOD_BAD_MAX_ENTRY 2 +#define TX_256TO511OCTETS_FRAMES_GOOD_BAD_MAX_ENTRY 2 +#define TX_512TO1023OCTETS_FRAMES_GOOD_BAD_MAX_ENTRY 2 +#define TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_MAX_ENTRY 2 +#define TX_UNICAST_FRAMES_GOOD_BAD_MAX_ENTRY 2 +#define TX_MULTICAST_FRAMES_GOOD_BAD_MAX_ENTRY 2 +#define TX_BROADCAST_FRAMES_GOOD_BAD_MAX_ENTRY 2 +#define TX_UNDERFERROR_FRAMES_MAX_ENTRY 2 +#define TX_SINGLE_COLLISION_GOOD_FRAMES_MAX_ENTRY 2 +#define TX_MULTIPLE_COLLISION_GOOD_FRAMES_MAX_ENTRY 2 +#define TX_DEFERRED_FRAMES_MAX_ENTRY 2 +#define TX_LATE_COLLISION_FRAMES_MAX_ENTRY 2 +#define TX_EXCESSIVE_COLLISION_FRAMES_MAX_ENTRY 2 +#define TX_CARRIER_ERROR_FRAMES_MAX_ENTRY 2 +#define TX_OCTET_COUNT_GOOD_MAX_ENTRY 2 +#define TX_FRAME_COUNT_GOOD_MAX_ENTRY 2 +#define TX_PAUSE_FRAMES_MAX_ENTRY 2 +#define TX_VLAN_FRAMES_GOOD_MAX_ENTRY 2 +#define TX_OSIZE_FRAMES_GOOD_MAX_ENTRY 2 +#define RX_FRAME_COUNT_GOOD_BAD_MAX_ENTRY 2 +#define RX_OCTET_COUNT_GOOD_BAD_MAX_ENTRY 2 +#define RX_OCTET_COUNT_GOOD_MAX_ENTRY 2 +#define RX_BROADCAST_FRAMES_GOOD_MAX_ENTRY 2 +#define RX_MULTICAST_FRAMES_GOOD_MAX_ENTRY 2 +#define RX_CRC_ERROR_FRAMES_MAX_ENTRY 2 +#define RX_ALIGNMENT_ERROR_FRAMES_MAX_ENTRY 2 +#define RX_RUNT_ERROR_FRAMES_MAX_ENTRY 2 +#define RX_JABBER_ERROR_FRAMES_MAX_ENTRY 2 +#define RX_UNDERSIZE_FRAMES_GOOD_MAX_ENTRY 2 +#define RX_OVERSIZE_FRAMES_GOOD_MAX_ENTRY 2 +#define RX_64OCTETS_FRAMES_GOOD_BAD_MAX_ENTRY 2 +#define RX_65TO127OCTETS_FRAMES_GOOD_BAD_MAX_ENTRY 2 +#define RX_128TO255OCTETS_FRAMES_GOOD_BAD_MAX_ENTRY 2 +#define RX_256TO511OCTETS_FRAMES_GOOD_BAD_MAX_ENTRY 2 +#define RX_512TO1023OCTETS_FRAMES_GOOD_BAD_MAX_ENTRY 2 +#define RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_MAX_ENTRY 2 +#define RX_UNICAST_FRAMES_GOOD_MAX_ENTRY 2 +#define RX_LENGTH_ERROR_FRAMES_MAX_ENTRY 2 +#define RX_OUTOFRANGE_FRAMES_MAX_ENTRY 2 +#define RX_PAUSE_FRAMES_MAX_ENTRY 2 +#define RX_FIFO_OVER_FLOW_FRAMES_MAX_ENTRY 2 +#define RX_VLAN_FRAMES_GOOD_BAD_MAX_ENTRY 2 +#define RX_WATCHDOG_ERROR_FRAMES_MAX_ENTRY 2 +#define RX_RECEIVE_ERROR_FRAMES_MAX_ENTRY 2 +#define RX_CONTROL_FRAMES_GOOD_MAX_ENTRY 2 + +sw_error_t +mp_mmc_control_get( + a_uint32_t dev_id, + a_uint32_t index, + union mmc_control_u *value); + +sw_error_t +mp_mmc_control_set( + a_uint32_t dev_id, + a_uint32_t index, + union mmc_control_u *value); + +sw_error_t +mp_tx_octet_count_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_octet_count_good_bad_u *value); + +sw_error_t +mp_tx_frame_count_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_frame_count_good_bad_u *value); + +sw_error_t +mp_tx_broadcast_frames_good_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_broadcast_frames_good_u *value); + +sw_error_t +mp_tx_multicast_frames_good_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_multicast_frames_good_u *value); + +sw_error_t +mp_tx_64octets_frames_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_64octets_frames_good_bad_u *value); + +sw_error_t +mp_tx_65to127octets_frames_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_65to127octets_frames_good_bad_u *value); + +sw_error_t +mp_tx_128to255octets_frames_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_128to255octets_frames_good_bad_u *value); + +sw_error_t +mp_tx_256to511octets_frames_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_256to511octets_frames_good_bad_u *value); + +sw_error_t +mp_tx_512to1023octets_frames_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_512to1023octets_frames_good_bad_u *value); + +sw_error_t +mp_tx_1024tomaxoctets_frames_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_1024tomaxoctets_frames_good_bad_u *value); + +sw_error_t +mp_tx_unicast_frames_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_unicast_frames_good_bad_u *value); + +sw_error_t +mp_tx_multicast_frames_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_multicast_frames_good_bad_u *value); + +sw_error_t +mp_tx_broadcast_frames_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_broadcast_frames_good_bad_u *value); + +sw_error_t +mp_tx_underflow_error_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_underflow_error_frames_u *value); + +sw_error_t +mp_tx_single_col_good_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_single_collision_good_frames_u *value); + + +sw_error_t +mp_t_multi_col_good_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_multiple_collision_good_frames_u *value); + +sw_error_t +mp_tx_defer_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_deferred_frames_u *value); + +sw_error_t +mp_tx_late_col_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_late_collision_frames_u *value); + +sw_error_t +mp_tx_excessive_col_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_excessive_collision_frames_u *value); + +sw_error_t +mp_tx_carrier_error_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_carrier_error_frames_u *value); + +sw_error_t +mp_tx_octet_count_good_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_octet_count_good_u *value); + +sw_error_t +mp_tx_frame_count_good_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_frame_count_good_u *value); + +sw_error_t +mp_tx_pause_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_pause_frames_u *value); + +sw_error_t +mp_tx_vlan_frames_good_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_vlan_frames_good_u *value); + +sw_error_t +mp_tx_osize_frames_good_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_osize_frames_good_u *value); + +sw_error_t +mp_rx_frame_count_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_frame_count_good_bad_u *value); + +sw_error_t +mp_rx_octet_count_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_octet_count_good_bad_u *value); + +sw_error_t +mp_rx_octet_count_good_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_octet_count_good_u *value); + +sw_error_t +mp_rx_broadcast_frames_good_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_broadcast_frames_good_u *value); + +sw_error_t +mp_rx_multicast_frames_good_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_multicast_frames_good_u *value); + +sw_error_t +mp_rx_crc_error_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_crc_error_frames_u *value); + +sw_error_t +mp_rx_alignment_error_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_crc_error_frames_u *value); + +sw_error_t +mp_rx_runt_error_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_runt_error_frames_u *value); + +sw_error_t +mp_rx_jabber_error_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_jabber_error_frames_u *value); + +sw_error_t +mp_rx_undersize_frames_good_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_undersize_frames_good_u *value); + +sw_error_t +mp_rx_oversize_frames_good_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_oversize_frames_good_u *value); + +sw_error_t +mp_rx_64octets_frames_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_64octets_frames_good_bad_u *value); + +sw_error_t +mp_rx_65to127octets_frames_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_65to127octets_frames_good_bad_u *value); + +sw_error_t +mp_rx_128to255octets_frames_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_128to255octets_frames_good_bad_u *value); + +sw_error_t +mp_rx_256to511octets_frames_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_256to511octets_frames_good_bad_u *value); + +sw_error_t +mp_rx_512to1023octets_frames_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_512to1023octets_frames_good_bad_u *value); + +sw_error_t +mp_rx_1024tomaxoctets_frames_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_1024tomaxoctets_frames_good_bad_u *value); + +sw_error_t +mp_rx_unicast_frames_good_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_unicast_frames_good_u *value); + +sw_error_t +mp_rx_length_error_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_length_error_frames_u *value); + +sw_error_t +mp_rx_outofrange_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_outofrange_frames_u *value); + +sw_error_t +mp_rx_pause_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_pause_frames_u *value); + +sw_error_t +mp_rx_fifo_over_flow_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_fifo_over_flow_frames_u *value); + +sw_error_t +mp_rx_vlan_frames_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_vlan_frames_good_bad_u *value); + +sw_error_t +mp_rx_watchdog_error_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_watchdog_error_frames_u *value); + +sw_error_t +mp_rx_receive_error_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_receive_error_frames_u *value); + +sw_error_t +mp_rx_control_frames_good_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_control_frames_good_u *value); +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/mp/mp_mib_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/mp/mp_mib_reg.h new file mode 100755 index 000000000..45929f154 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/mp/mp_mib_reg.h @@ -0,0 +1,875 @@ +/* + * 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 MP_MIB_REG_H +#define MP_MIB_REG_H + +/*[register] MMC_CONTROL*/ +#define MMC_CONTROL +#define MMC_CONTROL_ADDRESS 0x100 +#define MMC_CONTROL_NUM 2 +#define MMC_CONTROL_INC 0x100000 +#define MMC_CONTROL_DEFAULT 0x0 + +struct mmc_control { + a_uint32_t cntrst:1; + a_uint32_t cntstopro:1; + a_uint32_t rstonrd:1; + a_uint32_t cntfreez:1; + a_uint32_t cntprst:1; + a_uint32_t cntprstlvl:1; + a_uint32_t _reserved1:2; + a_uint32_t ucdbc:8; + a_uint32_t _reserved2:23; +}; + +union mmc_control_u { + a_uint32_t val; + struct mmc_control bf; +}; + +/*[register] TX_OCTET_COUNT_GOOD_BAD*/ +#define TX_OCTET_COUNT_GOOD_BAD +#define TX_OCTET_COUNT_GOOD_BAD_ADDRESS 0x114 +#define TX_OCTET_COUNT_GOOD_BAD_NUM 2 +#define TX_OCTET_COUNT_GOOD_BAD_INC 0x100000 +#define TX_OCTET_COUNT_GOOD_BAD_DEFAULT 0x0 + +struct tx_octet_count_good_bad { + a_uint32_t txoctgb:32; +}; + +union tx_octet_count_good_bad_u { + a_uint32_t val; + struct tx_octet_count_good_bad bf; +}; + +/*[register] TX_FRAME_COUNT_GOOD_BAD*/ +#define TX_FRAME_COUNT_GOOD_BAD +#define TX_FRAME_COUNT_GOOD_BAD_ADDRESS 0x118 +#define TX_FRAME_COUNT_GOOD_BAD_NUM 2 +#define TX_FRAME_COUNT_GOOD_BAD_INC 0x100000 +#define TX_FRAME_COUNT_GOOD_BAD_DEFAULT 0x0 + +struct tx_frame_count_good_bad { + a_uint32_t txfrmgb:32; +}; + +union tx_frame_count_good_bad_u { + a_uint32_t val; + struct tx_frame_count_good_bad bf; +}; + +/*[register] TX_BROADCAST_FRAMES_GOOD*/ +#define TX_BROADCAST_FRAMES_GOOD +#define TX_BROADCAST_FRAMES_GOOD_ADDRESS 0x11c +#define TX_BROADCAST_FRAMES_GOOD_NUM 2 +#define TX_BROADCAST_FRAMES_GOOD_INC 0x100000 +#define TX_BROADCAST_FRAMES_GOOD_DEFAULT 0x0 + +struct tx_broadcast_frames_good { + a_uint32_t txbcastg:32; +}; + +union tx_broadcast_frames_good_u { + a_uint32_t val; + struct tx_broadcast_frames_good bf; +}; + +/*[register] TX_MULTICAST_FRAMES_GOOD*/ +#define TX_MULTICAST_FRAMES_GOOD +#define TX_MULTICAST_FRAMES_GOOD_ADDRESS 0x120 +#define TX_MULTICAST_FRAMES_GOOD_NUM 2 +#define TX_MULTICAST_FRAMES_GOOD_INC 0x100000 +#define TX_MULTICAST_FRAMES_GOOD_DEFAULT 0x0 + +struct tx_multicast_frames_good { + a_uint32_t txmcastg:32; +}; + +union tx_multicast_frames_good_u { + a_uint32_t val; + struct tx_multicast_frames_good bf; +}; + +/*[register] TX_64OCTETS_FRAMES_GOOD_BAD*/ +#define TX_64OCTETS_FRAMES_GOOD_BAD +#define TX_64OCTETS_FRAMES_GOOD_BAD_ADDRESS 0x124 +#define TX_64OCTETS_FRAMES_GOOD_BAD_NUM 2 +#define TX_64OCTETS_FRAMES_GOOD_BAD_INC 0x100000 +#define TX_64OCTETS_FRAMES_GOOD_BAD_DEFAULT 0x0 + +struct tx_64octets_frames_good_bad { + a_uint32_t tx64octgb:32; +}; + +union tx_64octets_frames_good_bad_u { + a_uint32_t val; + struct tx_64octets_frames_good_bad bf; +}; + +/*[register] TX_65TO127OCTETS_FRAMES_GOOD_BAD*/ +#define TX_65TO127OCTETS_FRAMES_GOOD_BAD +#define TX_65TO127OCTETS_FRAMES_GOOD_BAD_ADDRESS 0x128 +#define TX_65TO127OCTETS_FRAMES_GOOD_BAD_NUM 2 +#define TX_65TO127OCTETS_FRAMES_GOOD_BAD_INC 0x100000 +#define TX_65TO127OCTETS_FRAMES_GOOD_BAD_DEFAULT 0x0 + +struct tx_65to127octets_frames_good_bad { + a_uint32_t tx65_127octgb:32; +}; + +union tx_65to127octets_frames_good_bad_u { + a_uint32_t val; + struct tx_65to127octets_frames_good_bad bf; +}; + +/*[register] TX_128TO255OCTETS_FRAMES_GOOD_BAD*/ +#define TX_128TO255OCTETS_FRAMES_GOOD_BAD +#define TX_128TO255OCTETS_FRAMES_GOOD_BAD_ADDRESS 0x12c +#define TX_128TO255OCTETS_FRAMES_GOOD_BAD_NUM 2 +#define TX_128TO255OCTETS_FRAMES_GOOD_BAD_INC 0x100000 +#define TX_128TO255OCTETS_FRAMES_GOOD_BAD_DEFAULT 0x0 + +struct tx_128to255octets_frames_good_bad { + a_uint32_t tx128_255octgb:32; +}; + +union tx_128to255octets_frames_good_bad_u { + a_uint32_t val; + struct tx_128to255octets_frames_good_bad bf; +}; + +/*[register] TX_256TO511OCTETS_FRAMES_GOOD_BAD*/ +#define TX_256TO511OCTETS_FRAMES_GOOD_BAD +#define TX_256TO511OCTETS_FRAMES_GOOD_BAD_ADDRESS 0x130 +#define TX_256TO511OCTETS_FRAMES_GOOD_BAD_NUM 2 +#define TX_256TO511OCTETS_FRAMES_GOOD_BAD_INC 0x100000 +#define TX_256TO511OCTETS_FRAMES_GOOD_BAD_DEFAULT 0x0 + +struct tx_256to511octets_frames_good_bad { + a_uint32_t tx256_511octgb:32; +}; + +union tx_256to511octets_frames_good_bad_u { + a_uint32_t val; + struct tx_256to511octets_frames_good_bad bf; +}; + +/*[register] TX_512TO1023OCTETS_FRAMES_GOOD_BAD*/ +#define TX_512TO1023OCTETS_FRAMES_GOOD_BAD +#define TX_512TO1023OCTETS_FRAMES_GOOD_BAD_ADDRESS 0x134 +#define TX_512TO1023OCTETS_FRAMES_GOOD_BAD_NUM 2 +#define TX_512TO1023OCTETS_FRAMES_GOOD_BAD_INC 0x100000 +#define TX_512TO1023OCTETS_FRAMES_GOOD_BAD_DEFAULT 0x0 + +struct tx_512to1023octets_frames_good_bad { + a_uint32_t tx512_1023octgb:32; +}; + +union tx_512to1023octets_frames_good_bad_u { + a_uint32_t val; + struct tx_512to1023octets_frames_good_bad bf; +}; + +/*[register] TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD*/ +#define TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD +#define TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_ADDRESS 0x138 +#define TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_NUM 2 +#define TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_INC 0x100000 +#define TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_DEFAULT 0x0 + +struct tx_1024tomaxoctets_frames_good_bad { + a_uint32_t tx1024_maxoctgb:32; +}; + +union tx_1024tomaxoctets_frames_good_bad_u { + a_uint32_t val; + struct tx_1024tomaxoctets_frames_good_bad bf; +}; + +/*[register] TX_UNICAST_FRAMES_GOOD_BAD*/ +#define TX_UNICAST_FRAMES_GOOD_BAD +#define TX_UNICAST_FRAMES_GOOD_BAD_ADDRESS 0x13c +#define TX_UNICAST_FRAMES_GOOD_BAD_NUM 2 +#define TX_UNICAST_FRAMES_GOOD_BAD_INC 0x100000 +#define TX_UNICAST_FRAMES_GOOD_BAD_DEFAULT 0x0 + +struct tx_unicast_frames_good_bad { + a_uint32_t txucastgb:32; +}; + +union tx_unicast_frames_good_bad_u { + a_uint32_t val; + struct tx_unicast_frames_good_bad bf; +}; + +/*[register] TX_MULTICAST_FRAMES_GOOD_BAD*/ +#define TX_MULTICAST_FRAMES_GOOD_BAD +#define TX_MULTICAST_FRAMES_GOOD_BAD_ADDRESS 0x140 +#define TX_MULTICAST_FRAMES_GOOD_BAD_NUM 2 +#define TX_MULTICAST_FRAMES_GOOD_BAD_INC 0x100000 +#define TX_MULTICAST_FRAMES_GOOD_BAD_DEFAULT 0x0 + +struct tx_multicast_frames_good_bad { + a_uint32_t txmcastgb:32; +}; + +union tx_multicast_frames_good_bad_u { + a_uint32_t val; + struct tx_multicast_frames_good_bad bf; +}; + +/*[register] TX_BROADCAST_FRAMES_GOOD_BAD*/ +#define TX_BROADCAST_FRAMES_GOOD_BAD +#define TX_BROADCAST_FRAMES_GOOD_BAD_ADDRESS 0x144 +#define TX_BROADCAST_FRAMES_GOOD_BAD_NUM 2 +#define TX_BROADCAST_FRAMES_GOOD_BAD_INC 0x100000 +#define TX_BROADCAST_FRAMES_GOOD_BAD_DEFAULT 0x0 + +struct tx_broadcast_frames_good_bad { + a_uint32_t txbcastgb:32; +}; + +union tx_broadcast_frames_good_bad_u { + a_uint32_t val; + struct tx_broadcast_frames_good_bad bf; +}; + +/*[register] TX_UNDERFLOW_ERROR_FRAMES*/ +#define TX_UNDERFLOW_ERROR_FRAMES +#define TX_UNDERFLOW_ERROR_FRAMES_ADDRESS 0x148 +#define TX_UNDERFLOW_ERROR_FRAMES_NUM 2 +#define TX_UNDERFLOW_ERROR_FRAMES_INC 0x100000 +#define TX_UNDERFLOW_ERROR_FRAMES_DEFAULT 0x0 + +struct tx_underflow_error_frames { + a_uint32_t txundrflw:32; +}; + +union tx_underflow_error_frames_u { + a_uint32_t val; + struct tx_underflow_error_frames bf; +}; + +/*[register] TX_SINGLE_COLLISION_GOOD_FRAMES*/ +#define TX_SINGLE_COLLISION_GOOD_FRAMES +#define TX_SINGLE_COLLISION_GOOD_FRAMES_ADDRESS 0x14c +#define TX_SINGLE_COLLISION_GOOD_FRAMES_NUM 2 +#define TX_SINGLE_COLLISION_GOOD_FRAMES_INC 0x100000 +#define TX_SINGLE_COLLISION_GOOD_FRAMES_DEFAULT 0x0 + +struct tx_single_collision_good_frames { + a_uint32_t txsnglcolg:32; +}; + +union tx_single_collision_good_frames_u { + a_uint32_t val; + struct tx_single_collision_good_frames bf; +}; + +/*[register] TX_MULTIPLE_COLLISION_GOOD_FRAMES*/ +#define TX_MULTIPLE_COLLISION_GOOD_FRAMES +#define TX_MULTIPLE_COLLISION_GOOD_FRAMES_ADDRESS 0x150 +#define TX_MULTIPLE_COLLISION_GOOD_FRAMES_NUM 2 +#define TX_MULTIPLE_COLLISION_GOOD_FRAMES_INC 0x100000 +#define TX_MULTIPLE_COLLISION_GOOD_FRAMES_DEFAULT 0x0 + +struct tx_multiple_collision_good_frames { + a_uint32_t txmultcolg:32; +}; + +union tx_multiple_collision_good_frames_u { + a_uint32_t val; + struct tx_multiple_collision_good_frames bf; +}; + +/*[register] TX_DEFERRED_FRAMES*/ +#define TX_DEFERRED_FRAMES +#define TX_DEFERRED_FRAMES_ADDRESS 0x154 +#define TX_DEFERRED_FRAMES_NUM 2 +#define TX_DEFERRED_FRAMES_INC 0x100000 +#define TX_DEFERRED_FRAMES_DEFAULT 0x0 + +struct tx_deferred_frames { + a_uint32_t txdefrd:32; +}; + +union tx_deferred_frames_u { + a_uint32_t val; + struct tx_deferred_frames bf; +}; + +/*[register] TX_LATE_COLLISION_FRAMES*/ +#define TX_LATE_COLLISION_FRAMES +#define TX_LATE_COLLISION_FRAMES_ADDRESS 0x158 +#define TX_LATE_COLLISION_FRAMES_NUM 2 +#define TX_LATE_COLLISION_FRAMES_INC 0x100000 +#define TX_LATE_COLLISION_FRAMES_DEFAULT 0x0 + +struct tx_late_collision_frames { + a_uint32_t txlatecol:32; +}; + +union tx_late_collision_frames_u { + a_uint32_t val; + struct tx_late_collision_frames bf; +}; + +/*[register] TX_EXCESSIVE_COLLISION_FRAMES*/ +#define TX_EXCESSIVE_COLLISION_FRAMES +#define TX_EXCESSIVE_COLLISION_FRAMES_ADDRESS 0x15c +#define TX_EXCESSIVE_COLLISION_FRAMES_NUM 2 +#define TX_EXCESSIVE_COLLISION_FRAMES_INC 0x100000 +#define TX_EXCESSIVE_COLLISION_FRAMES_DEFAULT 0x0 + +struct tx_excessive_collision_frames { + a_uint32_t txexscol:32; +}; + +union tx_excessive_collision_frames_u { + a_uint32_t val; + struct tx_excessive_collision_frames bf; +}; + +/*[register] TX_CARRIER_ERROR_FRAMES*/ +#define TX_CARRIER_ERROR_FRAMES +#define TX_CARRIER_ERROR_FRAMES_ADDRESS 0x160 +#define TX_CARRIER_ERROR_FRAMES_NUM 2 +#define TX_CARRIER_ERROR_FRAMES_INC 0x100000 +#define TX_CARRIER_ERROR_FRAMES_DEFAULT 0x0 + +struct tx_carrier_error_frames { + a_uint32_t txexscol:32; +}; + +union tx_carrier_error_frames_u { + a_uint32_t val; + struct tx_carrier_error_frames bf; +}; + +/*[register] TX_OCTET_COUNT_GOOD*/ +#define TX_OCTET_COUNT_GOOD +#define TX_OCTET_COUNT_GOOD_ADDRESS 0x164 +#define TX_OCTET_COUNT_GOOD_NUM 2 +#define TX_OCTET_COUNT_GOOD_INC 0x100000 +#define TX_OCTET_COUNT_GOOD_DEFAULT 0x0 + +struct tx_octet_count_good { + a_uint32_t txoctg:32; +}; + +union tx_octet_count_good_u { + a_uint32_t val; + struct tx_octet_count_good bf; +}; + +/*[register] TX_FRAME_COUNT_GOOD*/ +#define TX_FRAME_COUNT_GOOD +#define TX_FRAME_COUNT_GOOD_ADDRESS 0x168 +#define TX_FRAME_COUNT_GOOD_NUM 2 +#define TX_FRAME_COUNT_GOOD_INC 0x100000 +#define TX_FRAME_COUNT_GOOD_DEFAULT 0x0 + +struct tx_frame_count_good { + a_uint32_t txfrmg:32; +}; + +union tx_frame_count_good_u { + a_uint32_t val; + struct tx_frame_count_good bf; +}; + +/*[register] TX_EXCESSIVE_DEFERRAL_ERROR*/ +#define TX_EXCESSIVE_DEFERRAL_ERROR +#define TX_EXCESSIVE_DEFERRAL_ERROR_ADDRESS 0x16c +#define TX_EXCESSIVE_DEFERRAL_ERROR_NUM 2 +#define TX_EXCESSIVE_DEFERRAL_ERROR_INC 0x100000 +#define TX_EXCESSIVE_DEFERRAL_ERRORD_DEFAULT 0x0 + +struct tx_excessive_deferral_error { + a_uint32_t txexsdef:32; +}; + +union tx_excessive_deferral_error_u { + a_uint32_t val; + struct tx_excessive_deferral_error bf; +}; + +/*[register] TX_PAUSE_FRAMES*/ +#define TX_PAUSE_FRAMES +#define TX_PAUSE_FRAMES_ADDRESS 0x170 +#define TX_PAUSE_FRAMES_NUM 2 +#define TX_PAUSE_FRAMES_INC 0x100000 +#define TX_PAUSE_FRAMES_DEFAULT 0x0 + +struct tx_pause_frames { + a_uint32_t txpauseg:32; +}; + +union tx_pause_frames_u { + a_uint32_t val; + struct tx_pause_frames bf; +}; + +/*[register] TX_VLAN_FRAMES_GOOD*/ +#define TX_VLAN_FRAMES_GOOD +#define TX_VLAN_FRAMES_GOOD_ADDRESS 0x174 +#define TX_VLAN_FRAMES_GOOD_NUM 2 +#define TX_VLAN_FRAMES_GOOD_INC 0x100000 +#define TX_VLAN_FRAMES_GOOD_DEFAULT 0x0 + +struct tx_vlan_frames_good { + a_uint32_t txvlang:32; +}; + +union tx_vlan_frames_good_u { + a_uint32_t val; + struct tx_vlan_frames_good bf; +}; + +/*[register] TX_OSIZE_FRAMES_GOOD*/ +#define TX_OSIZE_FRAMES_GOOD +#define TX_OSIZE_FRAMES_GOOD_ADDRESS 0x178 +#define TX_OSIZE_FRAMES_GOOD_NUM 2 +#define TX_OSIZE_FRAMES_GOOD_INC 0x100000 +#define TX_OSIZE_FRAMES_GOOD_DEFAULT 0x0 + +struct tx_osize_frames_good { + a_uint32_t txosize:32; +}; + +union tx_osize_frames_good_u { + a_uint32_t val; + struct tx_osize_frames_good bf; +}; + +/*[register] RX_FRAME_COUNT_GOOD_BAD*/ +#define RX_FRAME_COUNT_GOOD_BAD +#define RX_FRAME_COUNT_GOOD_BAD_ADDRESS 0x180 +#define RX_FRAME_COUNT_GOOD_BAD_NUM 2 +#define RX_FRAME_COUNT_GOOD_BAD_INC 0x100000 +#define RX_FRAME_COUNT_GOOD_BAD_DEFAULT 0x0 + +struct rx_frame_count_good_bad { + a_uint32_t rxfrmgb:32; +}; + +union rx_frame_count_good_bad_u { + a_uint32_t val; + struct rx_frame_count_good_bad bf; +}; + +/*[register] RX_OCTET_COUNT_GOOD_BAD*/ +#define RX_OCTET_COUNT_GOOD_BAD +#define RX_OCTET_COUNT_GOOD_BAD_ADDRESS 0x184 +#define RX_OCTET_COUNT_GOOD_BAD_NUM 2 +#define RX_OCTET_COUNT_GOOD_BAD_INC 0x100000 +#define RX_OCTET_COUNT_GOOD_BAD_DEFAULT 0x0 + +struct rx_octet_count_good_bad { + a_uint32_t rxoctgb:32; +}; + +union rx_octet_count_good_bad_u { + a_uint32_t val; + struct rx_octet_count_good_bad bf; +}; + +/*[register] RX_OCTET_COUNT_GOOD*/ +#define RX_OCTET_COUNT_GOOD +#define RX_OCTET_COUNT_GOOD_ADDRESS 0x188 +#define RX_OCTET_COUNT_GOOD_NUM 2 +#define RX_OCTET_COUNT_GOOD_INC 0x100000 +#define RX_OCTET_COUNT_GOOD_DEFAULT 0x0 + +struct rx_octet_count_good { + a_uint32_t rxoctg:32; +}; + +union rx_octet_count_good_u { + a_uint32_t val; + struct rx_octet_count_good bf; +}; + +/*[register] RX_BROADCAST_FRAMES_GOOD*/ +#define RX_BROADCAST_FRAMES_GOOD +#define RX_BROADCAST_FRAMES_GOOD_ADDRESS 0x18c +#define RX_BROADCAST_FRAMES_GOOD_NUM 2 +#define RX_BROADCAST_FRAMES_GOOD_INC 0x100000 +#define RX_BROADCAST_FRAMES_GOOD_DEFAULT 0x0 + +struct rx_broadcast_frames_good { + a_uint32_t rxbcastg:32; +}; + +union rx_broadcast_frames_good_u { + a_uint32_t val; + struct rx_broadcast_frames_good bf; +}; + +/*[register] RX_MULTICAST_FRAMES_GOOD*/ +#define RX_MULTICAST_FRAMES_GOOD +#define RX_MULTICAST_FRAMES_GOOD_ADDRESS 0x190 +#define RX_MULTICAST_FRAMES_GOOD_NUM 2 +#define RX_MULTICAST_FRAMES_GOOD_INC 0x100000 +#define RX_MULTICAST_FRAMES_GOOD_DEFAULT 0x0 + +struct rx_multicast_frames_good { + a_uint32_t rxmcastg:32; +}; + +union rx_multicast_frames_good_u { + a_uint32_t val; + struct rx_multicast_frames_good bf; +}; + +/*[register] RX_CRC_ERROR_FRAMES*/ +#define RX_CRC_ERROR_FRAMES +#define RX_CRC_ERROR_FRAMES_ADDRESS 0x194 +#define RX_CRC_ERROR_FRAMES_NUM 2 +#define RX_CRC_ERROR_FRAMES_INC 0x100000 +#define RX_CRC_ERROR_FRAMES_DEFAULT 0x0 + +struct rx_crc_error_frames { + a_uint32_t rxcrcer:32; +}; + +union rx_crc_error_frames_u { + a_uint32_t val; + struct rx_crc_error_frames bf; +}; + +/*[register] RX_ALIGNMENT_ERROR_FRAMES*/ +#define RX_ALIGNMENT_ERROR_FRAMES +#define RX_ALIGNMENT_ERROR_FRAMES_ADDRESS 0x198 +#define RX_ALIGNMENT_ERROR_FRAMES_NUM 2 +#define RX_ALIGNMENT_ERROR_FRAMES_INC 0x100000 +#define RX_ALIGNMENT_ERROR_FRAMES_DEFAULT 0x0 + +struct rx_alignment_error_frames { + a_uint32_t rxalgnerr:32; +}; + +union rx_alignment_error_frames_u { + a_uint32_t val; + struct rx_alignment_error_frames bf; +}; + +/*[register] RX_RUNT_ERROR_FRAMES*/ +#define RX_RUNT_ERROR_FRAMES +#define RX_RUNT_ERROR_FRAMES_ADDRESS 0x19c +#define RX_RUNT_ERROR_FRAMES_NUM 2 +#define RX_RUNT_ERROR_FRAMES_INC 0x100000 +#define RX_RUNT_ERROR_FRAMES_DEFAULT 0x0 + +struct rx_runt_error_frames { + a_uint32_t rxrunter:32; +}; + +union rx_runt_error_frames_u { + a_uint32_t val; + struct rx_runt_error_frames bf; +}; + +/*[register] RX_JABBER_ERROR_FRAMES*/ +#define RX_JABBER_ERROR_FRAMES +#define RX_JABBER_ERROR_FRAMES_ADDRESS 0x1a0 +#define RX_JABBER_ERROR_FRAMES_NUM 2 +#define RX_JABBER_ERROR_FRAMES_INC 0x100000 +#define RX_JABBER_ERROR_FRAMES_DEFAULT 0x0 + +struct rx_jabber_error_frames { + a_uint32_t rxjaberer:32; +}; + +union rx_jabber_error_frames_u { + a_uint32_t val; + struct rx_jabber_error_frames bf; +}; + +/*[register] RX_UNDERSIZE_FRAMES_GOOD*/ +#define RX_UNDERSIZE_FRAMES_GOOD +#define RX_UNDERSIZE_FRAMES_GOOD_ADDRESS 0x1a4 +#define RX_UNDERSIZE_FRAMES_GOOD_NUM 2 +#define RX_UNDERSIZE_FRAMES_GOOD_INC 0x100000 +#define RX_UNDERSIZE_FRAMES_GOOD_DEFAULT 0x0 + +struct rx_undersize_frames_good { + a_uint32_t rxusizeg:32; +}; + +union rx_undersize_frames_good_u { + a_uint32_t val; + struct rx_undersize_frames_good bf; +}; + +/*[register] RX_OVERSIZE_FRAMES_GOOD*/ +#define RX_OVERSIZE_FRAMES_GOOD +#define RX_OVERSIZE_FRAMES_GOOD_ADDRESS 0x1a8 +#define RX_OVERSIZE_FRAMES_GOOD_NUM 2 +#define RX_OVERSIZE_FRAMES_GOOD_INC 0x100000 +#define RX_OVERSIZE_FRAMES_GOOD_DEFAULT 0x0 + +struct rx_oversize_frames_good { + a_uint32_t rxosizeg:32; +}; + +union rx_oversize_frames_good_u { + a_uint32_t val; + struct rx_oversize_frames_good bf; +}; + +/*[register] RX_64OCTETS_FRAMES_GOOD_BAD*/ +#define RX_64OCTETS_FRAMES_GOOD_BAD +#define RX_64OCTETS_FRAMES_GOOD_BAD_ADDRESS 0x1ac +#define RX_64OCTETS_FRAMES_GOOD_BAD_NUM 2 +#define RX_64OCTETS_FRAMES_GOOD_BAD_INC 0x100000 +#define RX_64OCTETS_FRAMES_GOOD_BAD_DEFAULT 0x0 + +struct rx_64octets_frames_good_bad { + a_uint32_t rx64octgb:32; +}; + +union rx_64octets_frames_good_bad_u { + a_uint32_t val; + struct rx_64octets_frames_good_bad bf; +}; + +/*[register] RX_65TO127OCTETS_FRAMES_GOOD_BAD*/ +#define RX_65TO127OCTETS_FRAMES_GOOD_BAD +#define RX_65TO127OCTETS_FRAMES_GOOD_BAD_ADDRESS 0x1b0 +#define RX_65TO127OCTETS_FRAMES_GOOD_BAD_NUM 2 +#define RX_65TO127OCTETS_FRAMES_GOOD_BAD_INC 0x100000 +#define RX_65TO127OCTETS_FRAMES_GOOD_BAD_DEFAULT 0x0 + +struct rx_65to127octets_frames_good_bad { + a_uint32_t rx65_127octgb:32; +}; + +union rx_65to127octets_frames_good_bad_u { + a_uint32_t val; + struct rx_65to127octets_frames_good_bad bf; +}; + +/*[register] RX_128TO255OCTETS_FRAMES_GOOD_BAD*/ +#define RX_128TO255OCTETS_FRAMES_GOOD_BAD +#define RX_128TO255OCTETS_FRAMES_GOOD_BAD_ADDRESS 0x1b4 +#define RX_128TO255OCTETS_FRAMES_GOOD_BAD_NUM 2 +#define RX_128TO255OCTETS_FRAMES_GOOD_BAD_INC 0x100000 +#define RX_128TO255OCTETS_FRAMES_GOOD_BAD_DEFAULT 0x0 + +struct rx_128to255octets_frames_good_bad { + a_uint32_t rx128_255octgb:32; +}; + +union rx_128to255octets_frames_good_bad_u { + a_uint32_t val; + struct rx_128to255octets_frames_good_bad bf; +}; + +/*[register] RX_256TO511OCTETS_FRAMES_GOOD_BAD*/ +#define RX_256TO511OCTETS_FRAMES_GOOD_BAD +#define RX_256TO511OCTETS_FRAMES_GOOD_BAD_ADDRESS 0x1b8 +#define RX_256TO511OCTETS_FRAMES_GOOD_BAD_NUM 2 +#define RX_256TO511OCTETS_FRAMES_GOOD_BAD_INC 0x100000 +#define RX_256TO511OCTETS_FRAMES_GOOD_BAD_DEFAULT 0x0 + +struct rx_256to511octets_frames_good_bad { + a_uint32_t rx256_511octgb:32; +}; + +union rx_256to511octets_frames_good_bad_u { + a_uint32_t val; + struct rx_256to511octets_frames_good_bad bf; +}; + +/*[register] RX_512TO1023OCTETS_FRAMES_GOOD_BAD*/ +#define RX_512TO1023OCTETS_FRAMES_GOOD_BAD +#define RX_512TO1023OCTETS_FRAMES_GOOD_BAD_ADDRESS 0x1bc +#define RX_512TO1023OCTETS_FRAMES_GOOD_BAD_NUM 2 +#define RX_512TO1023OCTETS_FRAMES_GOOD_BAD_INC 0x100000 +#define RX_512TO1023OCTETS_FRAMES_GOOD_BAD_DEFAULT 0x0 + +struct rx_512to1023octets_frames_good_bad { + a_uint32_t rx512_1023octgb:32; +}; + +union rx_512to1023octets_frames_good_bad_u { + a_uint32_t val; + struct rx_512to1023octets_frames_good_bad bf; +}; + +/*[register] RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD*/ +#define RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD +#define RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_ADDRESS 0x1c0 +#define RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_NUM 2 +#define RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_INC 0x100000 +#define RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_DEFAULT 0x0 + +struct rx_1024tomaxoctets_frames_good_bad { + a_uint32_t rx1024_maxgboct:32; +}; + +union rx_1024tomaxoctets_frames_good_bad_u { + a_uint32_t val; + struct rx_1024tomaxoctets_frames_good_bad bf; +}; + +/*[register] RX_UNICAST_FRAMES_GOOD*/ +#define RX_UNICAST_FRAMES_GOOD +#define RX_UNICAST_FRAMES_GOOD_ADDRESS 0x1c4 +#define RX_UNICAST_FRAMES_GOOD_NUM 2 +#define RX_UNICAST_FRAMES_GOOD_INC 0x100000 +#define RX_UNICAST_FRAMES_GOOD_DEFAULT 0x0 + +struct rx_unicast_frames_good { + a_uint32_t rxucastg:32; +}; + +union rx_unicast_frames_good_u { + a_uint32_t val; + struct rx_unicast_frames_good bf; +}; + +/*[register] RX_LENGTH_ERROR_FRAMES*/ +#define RX_LENGTH_ERROR_FRAMES +#define RX_LENGTH_ERROR_FRAMES_ADDRESS 0x1c8 +#define RX_LENGTH_ERROR_FRAMES_NUM 2 +#define RX_LENGTH_ERROR_FRAMES_INC 0x100000 +#define RX_LENGTH_ERROR_FRAMES_DEFAULT 0x0 + +struct rx_length_error_frames { + a_uint32_t rxlenerr:32; +}; + +union rx_length_error_frames_u { + a_uint32_t val; + struct rx_length_error_frames bf; +}; + +/*[register] RX_OUTOFRANGE_FRAMES*/ +#define RX_OUTOFRANGE_FRAMES +#define RX_OUTOFRANGE_FRAMES_ADDRESS 0x1cc +#define RX_OUTOFRANGE_FRAMES_NUM 2 +#define RX_OUTOFRANGE_FRAMES_INC 0x100000 +#define RX_OUTOFRANGE_FRAMES_DEFAULT 0x0 + +struct rx_outofrange_frames { + a_uint32_t rxorange:32; +}; + +union rx_outofrange_frames_u { + a_uint32_t val; + struct rx_outofrange_frames bf; +}; + +/*[register] RX_PAUSE_FRAMES*/ +#define RX_PAUSE_FRAMES +#define RX_PAUSE_FRAMES_ADDRESS 0x1d0 +#define RX_PAUSE_FRAMES_NUM 2 +#define RX_PAUSE_FRAMES_INC 0x100000 +#define RX_PAUSE_FRAMES_DEFAULT 0x0 + +struct rx_pause_frames { + a_uint32_t rxpause:32; +}; + +union rx_pause_frames_u { + a_uint32_t val; + struct rx_pause_frames bf; +}; + +/*[register] RX_FIFOOVERFW_FRAMES*/ +#define RX_FIFOOVERFW_FRAMES +#define RX_FIFOOVERFW_FRAMES_ADDRESS 0x1d4 +#define RX_FIFOOVERFW_FRAMES_NUM 2 +#define RX_FIFOOVERFW_FRAMES_INC 0x100000 +#define RX_FIFOOVERFW_FRAMES_DEFAULT 0x0 + +struct rx_fifo_over_flow_frames { + a_uint32_t rxfovf:32; +}; + +union rx_fifo_over_flow_frames_u { + a_uint32_t val; + struct rx_fifo_over_flow_frames bf; +}; + +/*[register] RX_VLAN_FRAMES_GOOD_BAD*/ +#define RX_VLAN_FRAMES_GOOD_BAD +#define RX_VLAN_FRAMES_GOOD_BAD_ADDRESS 0x1d8 +#define RX_VLAN_FRAMES_GOOD_BAD_NUM 2 +#define RX_VLAN_FRAMES_GOOD_BAD_INC 0x100000 +#define RX_VLAN_FRAMES_GOOD_BAD_DEFAULT 0x0 + +struct rx_vlan_frames_good_bad { + a_uint32_t rxvlangb:32; +}; + +union rx_vlan_frames_good_bad_u { + a_uint32_t val; + struct rx_vlan_frames_good_bad bf; +}; + +/*[register] RX_WATCHDOG_ERROR_FRAMES*/ +#define RX_WATCHDOG_ERROR_FRAMES +#define RX_WATCHDOG_ERROR_FRAMES_ADDRESS 0x1dc +#define RX_WATCHDOG_ERROR_FRAMES_NUM 2 +#define RX_WATCHDOG_ERROR_FRAMES_INC 0x100000 +#define RX_WATCHDOG_ERROR_FRAMES_DEFAULT 0x0 + +struct rx_watchdog_error_frames { + a_uint32_t rxwdogerr:32; +}; + +union rx_watchdog_error_frames_u { + a_uint32_t val; + struct rx_watchdog_error_frames bf; +}; + +/*[register] GMAC0_RX_RECEIVE_ERROR_FRAMES*/ +#define RX_RECEIVE_ERROR_FRAMES +#define RX_RECEIVE_ERROR_FRAMES_ADDRESS 0x1e0 +#define RX_RECEIVE_ERROR_FRAMES_NUM 2 +#define RX_RECEIVE_ERROR_FRAMES_INC 0x100000 +#define RX_RECEIVE_ERROR_FRAMES_DEFAULT 0x0 + +struct rx_receive_error_frames { + a_uint32_t rxrcverr:32; +}; + +union rx_receive_error_frames_u { + a_uint32_t val; + struct rx_receive_error_frames bf; +}; + +/*[register] RX_CONTROL_FRAMES_GOOD*/ +#define RX_CONTROL_FRAMES_GOOD +#define RX_CONTROL_FRAMES_GOOD_ADDRESS 0x1e4 +#define RX_CONTROL_FRAMES_GOOD_NUM 2 +#define RX_CONTROL_FRAMES_GOOD_INC 0x100000 +#define RX_CONTROL_FRAMES_GOOD_DEFAULT 0x0 + +struct rx_control_frames_good { + a_uint32_t rxctlg:32; +}; + +union rx_control_frames_good_u { + a_uint32_t val; + struct rx_control_frames_good bf; +}; +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/mp/mp_portctrl.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/mp/mp_portctrl.h new file mode 100755 index 000000000..32c95ca3d --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/mp/mp_portctrl.h @@ -0,0 +1,113 @@ +/* + * 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 MAPLE_PORTCTRL_H +#define MAPLE_PORTCTRL_H + +#define MAC_CONFIGURATION_MAX_ENTRY 2 +#define MAC_FRAME_FILTER_MAX_ENTRY 2 +#define MAC_FLOW_CTRL_MAX_ENTRY 2 +#define MAC_LPI_CTRL_STATUS_MAX_ENTRY 2 +#define MAC_LPI_TIMER_CTRL_MAX_ENTRY 2 +#define MAC_MAX_FRAME_CTRL_MAX_ENTRY 2 +#define MAC_OPERATION_MODE_CTRL_MAX_ENTRY 2 + +sw_error_t +mp_mac_configuration_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_configuration_u *value); + +sw_error_t +mp_mac_configuration_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_configuration_u *value); + + +sw_error_t +mp_mac_frame_filter_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_frame_filter_u *value); + +sw_error_t +mp_mac_frame_filter_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_frame_filter_u *value); + +sw_error_t +mp_mac_flowctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_flow_ctrl_u *value); + +sw_error_t +mp_mac_flowctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_flow_ctrl_u *value); + +sw_error_t +mp_mac_lpi_ctrl_status_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_lpi_ctrl_status_u *value); + +sw_error_t +mp_mac_lpi_ctrl_status_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_lpi_ctrl_status_u *value); + +sw_error_t +mp_mac_lpi_timer_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_lpi_timer_ctrl_u *value); + +sw_error_t +mp_mac_lpi_timer_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_lpi_timer_ctrl_u *value); + +sw_error_t +mp_mac_max_frame_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_max_frame_ctrl_u *value); + +sw_error_t +mp_mac_max_frame_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_max_frame_ctrl_u *value); + +sw_error_t +mp_mac_operation_mode_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_operation_mode_ctrl_u *value); + +sw_error_t +mp_mac_operation_mode_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_operation_mode_ctrl_u *value); +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/mp/mp_portctrl_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/mp/mp_portctrl_reg.h new file mode 100755 index 000000000..9ead6b6dc --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/mp/mp_portctrl_reg.h @@ -0,0 +1,219 @@ +/* + * 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 MAPLE_PORTCTRL_REG_H +#define MAPLE_PORTCTRL_REG_H + +/*[register] MAC_CONFIGURATION*/ +#define MAC_CONFIGURATION +#define MAC_CONFIGURATION_ADDRESS 0x0 +#define MAC_CONFIGURATION_NUM 2 +#define MAC_CONFIGURATION_INC 0x100000 +#define MAC_CONFIGURATION_DEFAULT 0x0 + +struct mac_configuration { + a_uint32_t preamble_length:2; + a_uint32_t rx_enable:1; + a_uint32_t tx_enable:1; + a_uint32_t deferral_check:1; + a_uint32_t back_off_limit:2; + a_uint32_t acs:1; + a_uint32_t link_status:1; + a_uint32_t disable_retry:1; + a_uint32_t checksum_offload:1; + a_uint32_t duplex:1; + a_uint32_t loopback:1; + a_uint32_t disable_receive_own:1; + a_uint32_t mii_speed:1; + a_uint32_t port_select:1; + a_uint32_t disable_carrier_sense:1; + a_uint32_t ipg:3; + a_uint32_t jumbo_frame_enable:1; + a_uint32_t frame_burst_enable:1; + a_uint32_t jabber_disable:1; + a_uint32_t watchdog_disable:1; + a_uint32_t tc:1; + a_uint32_t crc_strpping:1; + a_uint32_t sfterr:1; + a_uint32_t twokpe:1; + a_uint32_t sarc:3; + a_uint32_t reserved:1; + +}; + +union mac_configuration_u { + a_uint32_t val; + struct mac_configuration bf; +}; + +/*[register] MAC_FRAME_FILTER*/ +#define MAC_FRAME_FILTER +#define MAC_FRAME_FILTER_ADDRESS 0x4 +#define MAC_FRAME_FILTER_NUM 2 +#define MAC_FRAME_FILTER_INC 0x100000 +#define MAC_FRAME_FILTER_DEFAULT 0x0 + +struct mac_frame_filter { + a_uint32_t promiscuous_mode:1; + a_uint32_t hash_unicast:1; + a_uint32_t hash_multicast:1; + a_uint32_t da_inverse_filtering:1; + a_uint32_t pass_multicast:1; + a_uint32_t disable_broadcast:1; + a_uint32_t pass_control_frame:2; + a_uint32_t sa_inverse_filtering:1; + a_uint32_t source_addr_filter_enable:1; + a_uint32_t perfect_filter:1; + a_uint32_t reserved_0:5; + a_uint32_t vlan_tag_filter_enable:1; + a_uint32_t resereved_1:3; + a_uint32_t layer_3_4_filter_enable:1; + a_uint32_t drop_non_tcp_udp:1; + a_uint32_t reserved_2:9; + a_uint32_t receive_all:1; +}; + +union mac_frame_filter_u { + a_uint32_t val; + struct mac_frame_filter bf; +}; + +/*[register] MAC_FLOW_CTRL*/ +#define MAC_FLOW_CTRL +#define MAC_FLOW_CTRL_ADDRESS 0x18 +#define MAC_FLOW_CTRL_NUM 2 +#define MAC_FLOW_CTRL_INC 0x100000 +#define MAC_FLOW_CTRL_DEFAULT 0x0 + +struct mac_flow_ctrl { + a_uint32_t flowctrl_busy:1; + a_uint32_t flowctrl_tx_enable:1; + a_uint32_t flowctrl_rx_enable:1; + a_uint32_t unicast_pause_frame_detect:1; + a_uint32_t pause_low_threshold:2; + a_uint32_t reserved_0:1; + a_uint32_t disable_zero_quanta_pause:1; + a_uint32_t reserved_1:8; + a_uint32_t pause_time:16; +}; + +union mac_flow_ctrl_u { + a_uint32_t val; + struct mac_flow_ctrl bf; +}; + +/*[register] LPI_CONTROL_STATUS*/ +#define MAC_LPI_CTRL_STATUS +#define MAC_LPI_CTRL_STATUS_ADDRESS 0x30 +#define MAC_LPI_CTRL_STATUS_NUM 2 +#define MAC_LPI_CTRL_STATUS_INC 0x100000 +#define MAC_LPI_CTRL_STATUS_DEFAULT 0x0 + +struct mac_lpi_ctrl_status { + a_uint32_t tx_lpi_entry:1; + a_uint32_t tx_lpi_exit:1; + a_uint32_t rx_lpi_entry:1; + a_uint32_t rx_lpi_exit:1; + a_uint32_t reserved_0:4; + a_uint32_t tx_lpi_state:1; + a_uint32_t rx_lpi_state:1; + a_uint32_t reserved_1:6; + a_uint32_t lpi_enable:1; + a_uint32_t link_status:1; + a_uint32_t link_status_enable:1; + a_uint32_t lpi_tx_auto_enable:1; + a_uint32_t reserved_2:12; +}; + +union mac_lpi_ctrl_status_u { + a_uint32_t val; + struct mac_lpi_ctrl_status bf; +}; + +/*[register] LPI_TIMER_CONTROL*/ +#define MAC_LPI_TIMER_CTRL +#define MAC_LPI_TIMER_CTRL_ADDRESS 0x34 +#define MAC_LPI_TIMER_CTRL_NUM 2 +#define MAC_LPI_TIMER_CTRL_INC 0x100000 +#define MAC_LPI_TIMER_CTRL_DEFAULT 0x0 + +struct mac_lpi_timer_ctrl { + a_uint32_t lpi_tw_timer:16; + a_uint32_t lpi_ls_timer:10; + a_uint32_t reserved_0:6; +}; + +union mac_lpi_timer_ctrl_u { + a_uint32_t val; + struct mac_lpi_timer_ctrl bf; +}; + +/*[register] MAX_FRAME_CONTROL*/ +#define MAC_MAX_FRAME_CTRL +#define MAC_MAX_FRAME_CTRL_ADDRESS 0xDC +#define MAC_MAX_FRAME_CTRL_NUM 2 +#define MAC_MAX_FRAME_CTRL_INC 0x100000 +#define MAC_MAX_FRAME_CTRL_DEFAULT 0x0 + +struct mac_max_frame_ctrl { + a_uint32_t max_frame_ctrl:14; + a_uint32_t reserved_0:2; + a_uint32_t max_frame_ctrl_enable:1; +}; + +union mac_max_frame_ctrl_u { + a_uint32_t val; + struct mac_max_frame_ctrl bf; +}; + +/*[register] OPERATION_MODE*/ +#define MAC_OPERATION_MODE_CTRL +#define MAC_OPERATION_MODE_CTRL_ADDRESS 0x01018 +#define MAC_OPERATION_MODE_CTRL_NUM 2 +#define MAC_OPERATION_MODE_CTRL_INC 0x100000 +#define MAC_OPERATION_MODE_CTRL_DEFAULT 0x0 + +struct mac_operation_mode_ctrl { + a_uint32_t reserved_0:1; + a_uint32_t stop_receive:1; + a_uint32_t second_frame:1; + a_uint32_t receive_threshold_ctrl:2; + a_uint32_t drop_gaint_frame:1; + a_uint32_t forwad_good_undersize_frame:1; + a_uint32_t forward_error_frame:1; + a_uint32_t enable_hw_flowctrl:1; + a_uint32_t threshold_of_activating:2; + a_uint32_t threshold_of_deactivating:2; + a_uint32_t stop_transmission_command:1; + a_uint32_t transmit_threshold_ctrl:3; + a_uint32_t reserved_1:3; + a_uint32_t flush_transmit_fifo:1; + a_uint32_t transmit_store_and_foward:1; + a_uint32_t msb_threshold_of_deactivating:1; + a_uint32_t msb_threshold_of_activating:1; + a_uint32_t disable_flushing_receiving_frame:1; + a_uint32_t receive_store_and_foward:1; + a_uint32_t disable_dropping_checking_error_frame:1; + a_uint32_t reserved_2:5; +}; + +union mac_operation_mode_ctrl_u { + a_uint32_t val; + struct mac_operation_mode_ctrl bf; +}; + +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/mp/mp_uniphy.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/mp/mp_uniphy.h new file mode 100755 index 000000000..5c3920c64 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/mp/mp_uniphy.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. + */ + +/** + * @defgroup + * @{ + */ + +#ifndef _MP_UNIPHY_H_ +#define _MP_UNIPHY_H_ + +#define UNIPHY_CLK_DIV_25M 1 +#define UNIPHY_CLK_DIV_50M 0 +#define UNIPHY_CLK_DRV_1 1 + +sw_error_t +mp_uniphy_clock_output_control_get( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_clock_output_control_u *value); +sw_error_t +mp_uniphy_clock_output_control_set( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_clock_output_control_u *value); +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/mp/mp_uniphy_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/mp/mp_uniphy_reg.h new file mode 100755 index 000000000..8a509096e --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/mp/mp_uniphy_reg.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. + */ + +/** + * @defgroup + * @{ + */ + +#ifndef MP_UNIPHY_REG_H +#define MP_UNIPHY_REG_H + +#define UNIPHY_CLOCK_OUTPUT_CONTROL_MAX_ENTRY 1 +/*[register] UNIPHY_ALLREG_DEC_REFCLKOUTPUTCONTROLREGISTERS*/ +#define UNIPHY_CLOCK_OUTPUT_CONTROL +#define UNIPHY_CLOCK_OUTPUT_CONTROL_ADDRESS 0x74 +#define UNIPHY_CLOCK_OUTPUT_CONTROL_NUM 0x1 +#define UNIPHY_CLOCK_OUTPUT_CONTROL_INC 0x1 +#define UNIPHY_CLOCK_OUTPUT_CONTROL_TYPE REG_TYPE_RW +#define UNIPHY_CLOCK_OUTPUT_CONTROL_DEFAULT 0x5 + /*[field] MMD1_REG_REFCLK_OUTPUT_EN*/ + #define MMD1_REG_REFCLK_OUTPUT_EN + #define MMD1_REG_REFCLK_OUTPUT_EN_OFFSET 0 + #define MMD1_REG_REFCLK_OUTPUT_EN_LEN 1 + #define MMD1_REG_REFCLK_OUTPUT_EN_DEFAULT 0x1 + /*[field] MMD1_REG_REFCLK_OUTPUT_DIV*/ + #define MMD1_REG_REFCLK_OUTPUT_DIV + #define MMD1_REG_REFCLK_OUTPUT_DIV_OFFSET 1 + #define MMD1_REG_REFCLK_OUTPUT_DIV_LEN 1 + #define MMD1_REG_REFCLK_OUTPUT_DIV_DEFAULT 0x0 + /*[field] MMD1_REG_REFCLK_OUTPUT_DRV*/ + #define MMD1_REG_REFCLK_OUTPUT_DRV + #define MMD1_REG_REFCLK_OUTPUT_DRV_OFFSET 2 + #define MMD1_REG_REFCLK_OUTPUT_DRV_LEN 2 + #define MMD1_REG_REFCLK_OUTPUT_DRV_DEFAULT 0x1 + +struct uniphy_clock_output_control { + a_uint32_t ref_clk_output_en:1; + a_uint32_t ref_clk_output_div:1; + a_uint32_t ref_clk_output_drv:2; + a_uint32_t _reserved1:28; +}; + +union uniphy_clock_output_control_u { + a_uint32_t val; + struct uniphy_clock_output_control bf; +}; +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/aquantia_phy.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/aquantia_phy.h new file mode 100755 index 000000000..71930d1de --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/aquantia_phy.h @@ -0,0 +1,394 @@ +/* + * 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 _AQUANTIA_PHY_H_ +#define _AQUANTIA_PHY_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ +#define PHY_ID_AQ1202 0x03a1b445 +#define PHY_ID_AQ2104 0x03a1b460 +#define PHY_ID_AQR105 0x03a1b4a2 +#define PHY_ID_AQR405 0x03a1b4b0 +#define PHY_ID_AQR107 0x03a1b4e1 + +#define AQUANTIA_MII_ADDR_C45 (1<<30) +#define AQUANTIA_REG_ADDRESS(dev_ad, reg_num) (AQUANTIA_MII_ADDR_C45 |\ + ((dev_ad & 0x1f) << 16) | (reg_num & 0xFFFF)) +#define AQUANTIA_MMD_AUTONEG 0x7 +#define AQUANTIA_MMD_PHY_XS_REGISTERS 4 +#define AQUANTIA_MMD_GLOBAL_REGISTERS 0x1E +#define AQUANTIA_MMD_GBE_STANDARD_REGISTERS 0x1D +#define AQUANTIA_MMD_PCS_REGISTERS 0x3 + /* PHY Registers */ +#define AQUANTIA_GLOBAL_STANDARD_CONTROL1 0 +#define AQUANTIA_EEE_ADVERTISTMENT_REGISTER 0x3C +#define AQUANTIA_EEE_ADVERTISTMENT_REGISTER1 0x3E +#define AQUANTIA_EEE_PARTNER_ADVERTISTMENT_REGISTER 0x3D +#define AQUANTIA_EEE_PARTNER_ADVERTISTMENT_REGISTER1 0x3F +#define AQUANTIA_EEE_CAPABILITY_REGISTER 0x14 +#define AQUANTIA_EEE_CAPABILITY_REGISTER1 0x15 + +#define AQUANTIA_REG_AUTONEG_VENDOR_STATUS 0xC800 +#define AQUANTIA_AUTONEG_STANDARD_STATUS1 0x1 +#define AQUANTIA_AUTONEG_STANDARD_CONTROL1 0 +#define AQUANTIA_AUTONEG_TRANSMIT_VENDOR_INTR_MASK 0xD401 +#define AQUANTIA_GLOBAL_INTR_STANDARD_MASK 0xff00 +#define AQUANTIA_GLOBAL_INTR_VENDOR_MASK 0xff01 +#define AQUANTIA_PHY_XS_USX_TRANSMIT 0xc441 +#define AQUANTIA_PHY_INTR_STATUS 19 +#define AQUANTIA_RESERVED_VENDOR_PROVISIONING1 0xC410 +#define AQUANTIA_RESERVED_VENDOR_STATUS1 0xC810 +#define AQUANTIA_GLOBAL_RESERVED_PROVISIONING 0xC47a +#define AQUANTIA_GLOBAL_RESERVED_PROVISIONING6 0xC475 +#define AQUANTIA_PHY_XS_TRANAMIT_RESERVED_VENDOR_PROVISION5 0xC444 +#define AQUANTIA_CHIP_WIDE_VENDORT_INTERRUPT_FLAGS 0xFC01 +#define AQUANTIA_AUTONEG_ADVERTISEMENT_REGISTER 0x10 +#define AQUANTIA_AUTONEG_VENDOR_PROVISION1 0xC400 +#define AQUANTIA_AUTONEG_10GBASE_T_CONTROL_REGISTER 0x20 +#define AQUANTIA_AUTONEG_LINK_PARTNER_ABILITY 0x13 +#define AQUANTIA_AUTONEG_LINK_PARTNER_5G_ABILITY 0xE820 +#define AQUANTIA_AUTONEG_LINK_PARTNER_10G_ABILITY 0x21 + +#define AQUANTIA_GLOBAL_CDT_CONTROL 0xC470 +#define AQUANTIA_GLOBAL_GENERAL_STATUS 0xC831 +#define AQUANTIA_NORMAL_CABLE_DIAGNOSTICS 0x10 +#define AQUANTIA_CABLE_DIAGNOSTICS_STATUS 0x8000 +/*AQUANTIA PHY LINE SIDE PACKETS COUNTER REGISTER*/ +#define AQUANTIA_LINE_SIDE_TRANSMIT_GOOD_FRAME_COUNTER2 0xc821 +#define AQUANTIA_LINE_SIDE_TRANSMIT_GOOD_FRAME_COUNTER1 0xc820 +#define AQUANTIA_LINE_SIDE_TRANSMIT_ERROR_FRAME_COUNTER2 0xc823 +#define AQUANTIA_LINE_SIDE_TRANSMIT_ERROR_FRAME_COUNTER1 0xc822 + +#define AQUANTIA_LINE_SIDE_RECEIVE_GOOD_FRAME_COUNTER2 0xe813 +#define AQUANTIA_LINE_SIDE_RECEIVE_GOOD_FRAME_COUNTER1 0xe812 +#define AQUANTIA_LINE_SIDE_RECEIVE_ERROR_FRAME_COUNTER2 0xe815 +#define AQUANTIA_LINE_SIDE_RECEIVE_ERROR_FRAME_COUNTER1 0xe814 + +/*AQUANTIA PHY SYSTEM SIDE PACKETS COUNTER REGISTER*/ +#define AQUANTIA_SYSTEM_SIDE_TRANSMIT_GOOD_FRAME_COUNTER2 0xc861 +#define AQUANTIA_SYSTEM_SIDE_TRANSMIT_GOOD_FRAME_COUNTER1 0xc860 +#define AQUANTIA_SYSTEM_SIDE_TRANSMIT_ERROR_FRAME_COUNTER2 0xc863 +#define AQUANTIA_SYSTEM_SIDE_TRANSMIT_ERROR_FRAME_COUNTER1 0xc862 + +#define AQUANTIA_SYSTEM_SIDE_RECEIVE_GOOD_FRAME_COUNTER2 0xe861 +#define AQUANTIA_SYSTEM_SIDE_RECEIVE_GOOD_FRAME_COUNTER1 0xe860 +#define AQUANTIA_SYSTEM_SIDE_RECEIVE_ERROR_FRAME_COUNTER2 0xe863 +#define AQUANTIA_SYSTEM_SIDE_RECEIVE_ERROR_FRAME_COUNTER1 0xe862 + +#define AQUANTIA_CABLE_DIAGNOSTIC_STATUS1 0xC800 +#define AQUANTIA_CABLE_DIAGNOSTIC_STATUS_PAIRA 0x7000/*0XC800, BITC:E*/ +#define AQUANTIA_CABLE_DIAGNOSTIC_STATUS_PAIRB 0x0700/*0XC800, BITA:8*/ +#define AQUANTIA_CABLE_DIAGNOSTIC_STATUS_PAIRC 0x0070/*0XC800, BIT6:4*/ +#define AQUANTIA_CABLE_DIAGNOSTIC_STATUS_PAIRD 0x0007/*0XC800, BIT2:0*/ + + +#define AQUANTIA_CABLE_DIAGNOSTIC_STATUS2 0xC801 +#define AQUANTIA_CABLE_DIAGNOSTIC_STATUS4 0xC803 +#define AQUANTIA_CABLE_DIAGNOSTIC_STATUS6 0xC805 +#define AQUANTIA_CABLE_DIAGNOSTIC_STATUS8 0xC807 +#define AQUANTIA_ACT_LED_STATUS 0xc430 +#define AQUANTIA_LINK_LED_STATUS 0xc431 +#define AQUANTIA_ACT_LED_VALUE 0xc0ef +#define AQUANTIA_LINK_LED_VALUE 0xc0e0 + + +#define AQUANTIA_PHY_ID1 0x2 +#define AQUANTIA_PHY_ID2 0x3 +#define AQUANTIA_MAGIC_FRAME_MAC0 0xC339 +#define AQUANTIA_MAGIC_FRAME_MAC1 0xC33a +#define AQUANTIA_MAGIC_FRAME_MAC2 0xC33b +#define AQUANTIA_MAGIC_ENGINE_REGISTER1 0xC355 +#define AQUANTIA_MAGIC_ENGINE_REGISTER2 0xC356 + +#define AQUANTIA_GLOBAL_SYS_CONFIG_FOR_100M 0x31B +#define AQUANTIA_GLOBAL_SYS_CONFIG_FOR_1000M 0x31C +#define AQUANTIA_GLOBAL_SYS_CONFIG_FOR_2500M 0x31D +#define AQUANTIA_GLOBAL_SYS_CONFIG_FOR_5000M 0x31E +#define AQUANTIA_GLOBAL_SYS_CONFIG_FOR_10000M 0x31F + + + /* PHY Registers Field */ +#define AQUANTIA_SERDES_MODE_XFI 0 +#define AQUANTIA_SERDES_MODE_SGMII 0x3 +#define AQUANTIA_SERDES_MODE_OCSGMII 0X4 + +#define AQUANTIA_MAGIC_PACKETS_ENABLE 0x0001 +#define AQUANTIA_PHY_MDIX_CONTRO_BIT 3 +#define AQUANTIA_PHY_MDIX_AUTO 0 +#define AQUANTIA_PHY_MDI 1 +#define AQUANTIA_PHY_MDIX 2 +#define AQUANTIA_PHY_MDIX_STATUS 0x0100 +#define AQUANTIA_PHY_WOL_ENABLE 0x0040 +#define AQUANTIA_PHY_REMOTE_LOOPBACK 0x1800 +#define AQUANTIA_COMMON_CTRL 0x1040 +#define AQUANTIA_INTERNAL_LOOPBACK 0x4800 +#define AQUANTIA_100M_LOOPBACK 0x0001 +#define AQUANTIA_1000M_LOOPBACK 0x0002 +#define AQUANTIA_10000M_LOOPBACK 0x0003 +#define AQUANTIA_2500M_LOOPBACK 0x0004 +#define AQUANTIA_5000M_LOOPBACK 0x0005 +#define AQUANTIA_POWER_DOWN 0x0800 +#define AQUANTIA_ALL_SPEED_LOOPBACK (AQUANTIA_100M_LOOPBACK |\ + AQUANTIA_1000M_LOOPBACK | AQUANTIA_1000M_LOOPBACK |AQUANTIA_2500M_LOOPBACK |\ + AQUANTIA_5000M_LOOPBACK | AQUANTIA_10000M_LOOPBACK) + +#define AQUANTIA_POWER_SAVE 0x0004 +#define AQUANTIA_STATUS_LINK 0x0004 +#define AQUANTIA_EEE_ADV_1000M 0x0004 +#define AQUANTIA_EEE_ADV_2500M 0x0001 +#define AQUANTIA_EEE_ADV_5000M 0x0002 +#define AQUANTIA_EEE_ADV_10000M 0x0008 +#define AQUANTIA_EEE_PARTNER_ADV_1000M 0x0004 +#define AQUANTIA_EEE_PARTNER_ADV_2500M 0x0001 +#define AQUANTIA_EEE_PARTNER_ADV_5000M 0x0002 +#define AQUANTIA_EEE_PARTNER_ADV_10000M 0x0008 +#define AQUANTIA_EEE_CAPABILITY_1000M 0x0004 +#define AQUANTIA_EEE_CAPABILITY_2500M 0x0001 +#define AQUANTIA_EEE_CAPABILITY_5000M 0x0002 +#define AQUANTIA_EEE_CAPABILITY_10000M 0x0008 + +#define AQUANTIA_PHY_USX_AUTONEG_ENABLE 0x0008 + +#define AQUANTIA_PHY_RX_FLOWCTRL_STATUS 0x0002 +#define AQUANTIA_PHY_TX_FLOWCTRL_STATUS 0x0001 + /* FDX =1, half duplex =0 */ +#define AQUANTIA_CTRL_FULL_DUPLEX 0x0100 + + /* Restart auto negotiation */ +#define AQUANTIA_CTRL_RESTART_AUTONEGOTIATION 0x0200 + + /* Power down */ +#define AQUANTIA_CTRL_POWER_DOWN 0x0800 + + /* Auto Neg Enable */ +#define AQUANTIA_CTRL_AUTONEGOTIATION_ENABLE 0x1000 + + /* Local Loopback Enable */ +#define AQUANTIA_LOCAL_LOOPBACK_ENABLE 0x4000 + + /* 0 = normal, 1 = loopback */ +#define AQUANTIA_CTRL_SOFTWARE_RESET 0x8000 + +#define AQUANTIA_RESET_DONE(phy_control) \ + (((phy_control) & (AQUANTIA_CTRL_SOFTWARE_RESET)) == 0) + + /* Auto Neg Complete */ +#define AQUANTIA_STATUS_AUTO_NEG_DONE 0x0020 + +#define AQUANTIA_AUTONEG_DONE(ip_phy_status) \ + (((ip_phy_status) & (AQUANTIA_STATUS_AUTO_NEG_DONE)) == \ + (AQUANTIA_STATUS_AUTO_NEG_DONE)) + +/*AQUANTIA interrupt flag */ +#define AQUANTIA_INTR_DUPLEX_CHANGE 0x2000 +#define AQUANTIA_INTR_LINK_STATUS_CHANGE 0x0001 +#define AQUANTIA_ALL_VENDOR_ALARMS_INTR_MASK 0x0001 +#define AQUANTIA_AUTO_AND_ALARMS_INTR_MASK 0x1001 + + /* 10T Half Duplex Capable */ +#define AQUANTIA_ADVERTISE_10HALF 0x0020 + + /* 10T Full Duplex Capable */ +#define AQUANTIA_ADVERTISE_10FULL 0x0040 + + /* 100TX Half Duplex Capable */ +#define AQUANTIA_ADVERTISE_100HALF 0x0080 + + /* 100TX Full Duplex Capable */ +#define AQUANTIA_ADVERTISE_100FULL 0x0100 + + /* Pause operation desired */ +#define AQUANTIA_ADVERTISE_PAUSE 0x0400 + + /* Asymmetric Pause Direction bit */ +#define AQUANTIA_ADVERTISE_ASYM_PAUSE 0x0800 + + /* Remote Fault detected */ +#define AQUANTIA_ADVERTISE_REMOTE_FAULT 0x2000 + + /* Next Page ability supported */ +#define AQUANTIA_ADVERTISE_NEXT_PAGE 0x8000 + + /* 1000TX Half Duplex Capable */ +#define AQUANTIA_ADVERTISE_1000HALF 0x4000 + + /* 1000TX Full Duplex Capable */ +#define AQUANTIA_ADVERTISE_1000FULL 0x8000 + + /* 2500TX Full Duplex Capable */ +#define AQUANTIA_ADVERTISE_2500FULL 0x0400 +#define AQUANTIA_ADVERTISE_8023BZ_2500FULL 0x80 + + /* 10000TX Full Duplex Capable */ +#define AQUANTIA_ADVERTISE_10000FULL 0x1000 + + /* 5000TX Full Duplex Capable */ +#define AQUANTIA_ADVERTISE_5000FULL 0x0800 +#define AQUANTIA_ADVERTISE_8023BZ_5000FULL 0x100 + +#define AQUANTIA_ADVERTISE_ALL \ + (AQUANTIA_ADVERTISE_10HALF | AQUANTIA_ADVERTISE_10FULL | \ + AQUANTIA_ADVERTISE_100HALF | AQUANTIA_ADVERTISE_100FULL | \ + AQUANTIA_ADVERTISE_1000HALF |AQUANTIA_ADVERTISE_1000FULL |\ + AQUANTIA_ADVERTISE_10000FULL | AQUANTIA_ADVERTISE_2500FULL |\ + AQUANTIA_ADVERTISE_5000FULL) + +#define AQUANTIA_ADVERTISE_MEGA_ALL \ + (AQUANTIA_ADVERTISE_10HALF | AQUANTIA_ADVERTISE_10FULL | \ + AQUANTIA_ADVERTISE_100HALF | AQUANTIA_ADVERTISE_100FULL) + +#define AQUANTIA_ADVERTISE_GIGA_ALL \ + (AQUANTIA_ADVERTISE_1000HALF |AQUANTIA_ADVERTISE_1000FULL |\ + AQUANTIA_ADVERTISE_2500FULL | AQUANTIA_ADVERTISE_5000FULL) + + #define AQUANTIA_ADVERTISE_GIGA_PLUS_ALL \ + (AQUANTIA_ADVERTISE_10000FULL | AQUANTIA_ADVERTISE_8023BZ_2500FULL|\ + AQUANTIA_ADVERTISE_8023BZ_5000FULL) + + +#define AQUANTIA_BX_ADVERTISE_1000FULL 0x0020 +#define AQUANTIA_BX_ADVERTISE_1000HALF 0x0040 +#define AQUANTIA_BX_ADVERTISE_PAUSE 0x0080 +#define AQUANTIA_BX_ADVERTISE_ASYM_PAUSE 0x0100 + +#define AQUANTIA_BX_ADVERTISE_ALL \ + (AQUANTIA_BX_ADVERTISE_ASYM_PAUSE | AQUANTIA_BX_ADVERTISE_PAUSE | \ + AQUANTIA_BX_ADVERTISE_1000HALF | AQUANTIA_BX_ADVERTISE_1000FULL) + + /* Link Partner ability offset:5 */ + /* Same as advertise selector */ +#define AQUANTIA_LINK_SLCT 0x001f + + /* Can do 10mbps half-duplex */ +#define AQUANTIA_LINK_10BASETX_HALF_DUPLEX 0x0020 + + /* Can do 10mbps full-duplex */ +#define AQUANTIA_LINK_10BASETX_FULL_DUPLEX 0x0040 + + /* Can do 100mbps half-duplex */ +#define AQUANTIA_LINK_100BASETX_HALF_DUPLEX 0x0080 +#define AQUANTIA_LINK_100BASETX_FULL_DUPLEX 0x0100 +/*Can do 1G*/ + +#define AQUANTIA_LINK_1000BASETX_FULL_DUPLEX 0x8000 + /*Can do 5G*/ +#define AQUANTIA_LINK_5000BASETX_FULL_DUPLEX 0x0800 +/*Can do 2.5G*/ +#define AQUANTIA_LINK_2500BASETX_FULL_DUPLEX 0x0400 +/*Can do 10G*/ +#define AQUANTIA_LINK_10000BASETX_FULL_DUPLEX 0x1 + + + + /* 1=Duplex 0=Half Duplex */ +#define AQUANTIA_STATUS_FULL_DUPLEX 0x0001 + + /* Speed, bits 1 : 3*/ +#define AQUANTIA_STATUS_SPEED 0xC000 +#define AQUANTIA_STATUS_SPEED_MASK 0x000E + /* 000=10Mbs */ +#define AQUANTIA_STATUS_SPEED_10MBS 0x0000 + /* 001=100Mbs */ +#define AQUANTIA_STATUS_SPEED_100MBS 0x0001 + /* 010=1000Mbs */ +#define AQUANTIA_STATUS_SPEED_1000MBS 0x0002 + /* 011=10000Mbs */ +#define AQUANTIA_STATUS_SPEED_10000MBS 0x0003 + /* 100=2500Mbs */ +#define AQUANTIA_STATUS_SPEED_2500MBS 0x0004 + /* 101=5000Mbs */ +#define AQUANTIA_STATUS_SPEED_5000MBS 0x0005 + +#define RUN_CDT 0x8000 +#define CABLE_LENGTH_UNIT 0x0400 +#define AQUANTIA_PHY_CDT_MODE0 0 +#define AQUANTIA_PHY_CDT_MODE1 1 +#define AQUANTIA_PHY_CDT_MODE2 2 + +/** Phy pages */ + typedef enum + { + AQUANTIA_PHY_SGBX_PAGES = 0, + /**< sgbx pages */ + AQUANTIA_PHY_COPPER_PAGES = 1 + /**< copper pages */ + } AQUANTIA_PHY_reg_pages_t; +#ifndef IN_PORTCONTROL_MINI +sw_error_t + aquantia_phy_set_powersave (a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t enable); + +sw_error_t + aquantia_phy_get_powersave (a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t * enable); + +sw_error_t + aquantia_phy_cdt (a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t mdi_pair, + fal_cable_status_t * cable_status, + a_uint32_t * cable_len); +#endif +sw_error_t + aquantia_phy_set_duplex (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_duplex_t duplex); + +sw_error_t + aquantia_phy_get_duplex (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_duplex_t * duplex); + +sw_error_t + aquantia_phy_set_speed (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_speed_t speed); + +sw_error_t +aquantia_phy_get_speed (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_speed_t * speed); + +sw_error_t + aquantia_phy_restart_autoneg (a_uint32_t dev_id, a_uint32_t phy_id); + +sw_error_t + aquantia_phy_enable_autoneg (a_uint32_t dev_id, a_uint32_t phy_id); + +a_bool_t + aquantia_phy_get_link_status (a_uint32_t dev_id, a_uint32_t phy_id); + +sw_error_t + aquantia_phy_set_autoneg_adv (a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t autoneg); + +sw_error_t + aquantia_phy_get_autoneg_adv (a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * autoneg); + +a_bool_t + aquantia_phy_autoneg_status (a_uint32_t dev_id, a_uint32_t phy_id); +#ifndef IN_PORTCONTROL_MINI +sw_error_t + aquantia_phy_intr_mask_set (a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t intr_mask_flag); + +sw_error_t + aquantia_phy_intr_mask_get (a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * intr_mask_flag); +#endif +int aquantia_phy_init(a_uint32_t dev_id, a_uint32_t port_bmp); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _AQUANTIA_PHY_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/f1_phy.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/f1_phy.h new file mode 100755 index 000000000..b3f7ed2fe --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/f1_phy.h @@ -0,0 +1,479 @@ +/* + * Copyright (c) 2012, 2015, 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 _F1_PHY_H_ +#define _F1_PHY_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + /* PHY Registers */ +#define F1_PHY_CONTROL 0 +#define F1_PHY_STATUS 1 +#define F1_PHY_ID1 2 +#define F1_PHY_ID2 3 +#define F1_AUTONEG_ADVERT 4 +#define F1_LINK_PARTNER_ABILITY 5 +#define F1_AUTONEG_EXPANSION 6 +#define F1_NEXT_PAGE_TRANSMIT 7 +#define F1_LINK_PARTNER_NEXT_PAGE 8 +#define F1_1000BASET_CONTROL 9 +#define F1_1000BASET_STATUS 10 +#define F1_MMD_CTRL_REG 13 +#define F1_MMD_DATA_REG 14 +#define F1_EXTENDED_STATUS 15 +#define F1_PHY_SPEC_CONTROL 16 +#define F1_PHY_SPEC_STATUS 17 +#define F1_PHY_INTR_MASK 18 +#define F1_PHY_INTR_STATUS 19 +#define F1_PHY_CDT_CONTROL 22 +#define F1_PHY_CDT_STATUS 28 +#define F1_DEBUG_PORT_ADDRESS 29 +#define F1_DEBUG_PORT_DATA 30 +#define F1_PHY_8023AZ_EEE_CTRL 0x3c +#define F1_PHY_MMD7_NUM 7 +#define F1_PHY_AZ_ENABLE 0x6 + + /*debug port*/ +#define F1_DEBUG_PORT_RGMII_MODE 18 +#define F1_DEBUG_PORT_RGMII_MODE_EN 0x0008 + +#define F1_DEBUG_PORT_RX_DELAY 0 +#define F1_DEBUG_PORT_RX_DELAY_EN 0x8000 + +#define F1_DEBUG_PORT_TX_DELAY 5 +#define F1_DEBUG_PORT_TX_DELAY_EN 0x0100 + + /* PHY Registers Field*/ + + /* Control Register fields offset:0*/ + /* bits 6,13: 10=1000, 01=100, 00=10 */ +#define F1_CTRL_SPEED_MSB 0x0040 + + /* Collision test enable */ +#define F1_CTRL_COLL_TEST_ENABLE 0x0080 + + /* FDX =1, half duplex =0 */ +#define F1_CTRL_FULL_DUPLEX 0x0100 + + /* Restart auto negotiation */ +#define F1_CTRL_RESTART_AUTONEGOTIATION 0x0200 + + /* Isolate PHY from MII */ +#define F1_CTRL_ISOLATE 0x0400 + + /* Power down */ +#define F1_CTRL_POWER_DOWN 0x0800 + + /* Auto Neg Enable */ +#define F1_CTRL_AUTONEGOTIATION_ENABLE 0x1000 + + /* bits 6,13: 10=1000, 01=100, 00=10 */ +#define F1_CTRL_SPEED_LSB 0x2000 + + /* 0 = normal, 1 = loopback */ +#define F1_LOCAL_LOOPBACK_ENABLE 0x4000 +#define F1_COMMON_CTRL 0x1040 +#define F1_10M_LOOPBACK 0x4100 +#define F1_100M_LOOPBACK 0x6100 +#define F1_1000M_LOOPBACK 0x4140 + +#define F1_PHY_MMD3_NUM 3 +#define F1_PHY_MMD3_ADDR_REMOTE_LOOPBACK_CTRL 0x805a +#define F1_PHY_REMOTE_LOOPBACK_ENABLE 0x0001 +#define F1_CTRL_SOFTWARE_RESET 0x8000 + +#define F1_CTRL_SPEED_MASK 0x2040 +#define F1_CTRL_SPEED_1000 0x0040 +#define F1_CTRL_SPEED_100 0x2000 +#define F1_CTRL_SPEED_10 0x0000 + +#define F1_RESET_DONE(phy_control) \ + (((phy_control) & (F1_CTRL_SOFTWARE_RESET)) == 0) + + /* Status Register fields offset:1*/ + /* Extended register capabilities */ +#define F1_STATUS_EXTENDED_CAPS 0x0001 + + /* Jabber Detected */ +#define F1_STATUS_JABBER_DETECT 0x0002 + + /* Link Status 1 = link */ +#define F1_STATUS_LINK_STATUS_UP 0x0004 + + /* Auto Neg Capable */ +#define F1_STATUS_AUTONEG_CAPS 0x0008 + + /* Remote Fault Detect */ +#define F1_STATUS_REMOTE_FAULT 0x0010 + + /* Auto Neg Complete */ +#define F1_STATUS_AUTO_NEG_DONE 0x0020 + + /* Preamble may be suppressed */ +#define F1_STATUS_PREAMBLE_SUPPRESS 0x0040 + + /* Ext. status info in Reg 0x0F */ +#define F1_STATUS_EXTENDED_STATUS 0x0100 + + /* 100T2 Half Duplex Capable */ +#define F1_STATUS_100T2_HD_CAPS 0x0200 + + /* 100T2 Full Duplex Capable */ +#define F1_STATUS_100T2_FD_CAPS 0x0400 + + /* 10T Half Duplex Capable */ +#define F1_STATUS_10T_HD_CAPS 0x0800 + + /* 10T Full Duplex Capable */ +#define F1_STATUS_10T_FD_CAPS 0x1000 + + /* 100X Half Duplex Capable */ +#define F1_STATUS_100X_HD_CAPS 0x2000 + + /* 100X Full Duplex Capable */ +#define F1_STATUS_100X_FD_CAPS 0x4000 + + /* 100T4 Capable */ +#define F1_STATUS_100T4_CAPS 0x8000 + + /* extended status register capabilities */ + +#define F1_STATUS_1000T_HD_CAPS 0x1000 + +#define F1_STATUS_1000T_FD_CAPS 0x2000 + +#define F1_STATUS_1000X_HD_CAPS 0x4000 + +#define F1_STATUS_1000X_FD_CAPS 0x8000 + +#define F1_AUTONEG_DONE(ip_phy_status) \ + (((ip_phy_status) & (F1_STATUS_AUTO_NEG_DONE)) == \ + (F1_STATUS_AUTO_NEG_DONE)) + + /* PHY identifier1 offset:2*/ +//Organizationally Unique Identifier bits 3:18 + + /* PHY identifier2 offset:3*/ +//Organizationally Unique Identifier bits 19:24 + + /* Auto-Negotiation Advertisement register. offset:4*/ + /* indicates IEEE 802.3 CSMA/CD */ +#define F1_ADVERTISE_SELECTOR_FIELD 0x0001 + + /* 10T Half Duplex Capable */ +#define F1_ADVERTISE_10HALF 0x0020 + + /* 10T Full Duplex Capable */ +#define F1_ADVERTISE_10FULL 0x0040 + + /* 100TX Half Duplex Capable */ +#define F1_ADVERTISE_100HALF 0x0080 + + /* 100TX Full Duplex Capable */ +#define F1_ADVERTISE_100FULL 0x0100 + + /* 100T4 Capable */ +#define F1_ADVERTISE_100T4 0x0200 + + /* Pause operation desired */ +#define F1_ADVERTISE_PAUSE 0x0400 + + /* Asymmetric Pause Direction bit */ +#define F1_ADVERTISE_ASYM_PAUSE 0x0800 + + /* Remote Fault detected */ +#define F1_ADVERTISE_REMOTE_FAULT 0x2000 + + /* Next Page ability supported */ +#define F1_ADVERTISE_NEXT_PAGE 0x8000 + + /* 100TX Half Duplex Capable */ +#define F1_ADVERTISE_1000HALF 0x0100 + + /* 100TX Full Duplex Capable */ +#define F1_ADVERTISE_1000FULL 0x0200 + +#define F1_ADVERTISE_ALL \ + (F1_ADVERTISE_10HALF | F1_ADVERTISE_10FULL | \ + F1_ADVERTISE_100HALF | F1_ADVERTISE_100FULL | \ + F1_ADVERTISE_1000FULL) + +#define F1_ADVERTISE_MEGA_ALL \ + (F1_ADVERTISE_10HALF | F1_ADVERTISE_10FULL | \ + F1_ADVERTISE_100HALF | F1_ADVERTISE_100FULL) + + /* Link Partner ability offset:5*/ + /* Same as advertise selector */ +#define F1_LINK_SLCT 0x001f + + /* Can do 10mbps half-duplex */ +#define F1_LINK_10BASETX_HALF_DUPLEX 0x0020 + + /* Can do 10mbps full-duplex */ +#define F1_LINK_10BASETX_FULL_DUPLEX 0x0040 + + /* Can do 100mbps half-duplex */ +#define F1_LINK_100BASETX_HALF_DUPLEX 0x0080 + + /* Can do 100mbps full-duplex */ +#define F1_LINK_100BASETX_FULL_DUPLEX 0x0100 + + /* Can do 1000mbps full-duplex */ +#define F1_LINK_1000BASETX_FULL_DUPLEX 0x0800 + + /* Can do 1000mbps half-duplex */ +#define F1_LINK_1000BASETX_HALF_DUPLEX 0x0400 + + /* 100BASE-T4 */ +#define F1_LINK_100BASE4 0x0200 + + /* PAUSE */ +#define F1_LINK_PAUSE 0x0400 + + /* Asymmetrical PAUSE */ +#define F1_LINK_ASYPAUSE 0x0800 + + /* Link partner faulted */ +#define F1_LINK_RFAULT 0x2000 + + /* Link partner acked us */ +#define F1_LINK_LPACK 0x4000 + + /* Next page bit */ +#define F1_LINK_NPAGE 0x8000 + + /* Auto-Negotiation Expansion Register offset:6 */ + + /* Next Page Transmit Register offset:7 */ + + /* Link partner Next Page Register offset:8*/ + + /* 1000BASE-T Control Register offset:9*/ + /* Advertise 1000T HD capability */ +#define F1_CTL_1000T_HD_CAPS 0x0100 + + /* Advertise 1000T FD capability */ +#define F1_CTL_1000T_FD_CAPS 0x0200 + + /* 1=Repeater/switch device port 0=DTE device*/ +#define F1_CTL_1000T_REPEATER_DTE 0x0400 + + /* 1=Configure PHY as Master 0=Configure PHY as Slave */ +#define F1_CTL_1000T_MS_VALUE 0x0800 + + /* 1=Master/Slave manual config value 0=Automatic Master/Slave config */ +#define F1_CTL_1000T_MS_ENABLE 0x1000 + + /* Normal Operation */ +#define F1_CTL_1000T_TEST_MODE_NORMAL 0x0000 + + /* Transmit Waveform test */ +#define F1_CTL_1000T_TEST_MODE_1 0x2000 + + /* Master Transmit Jitter test */ +#define F1_CTL_1000T_TEST_MODE_2 0x4000 + + /* Slave Transmit Jitter test */ +#define F1_CTL_1000T_TEST_MODE_3 0x6000 + + /* Transmitter Distortion test */ +#define F1_CTL_1000T_TEST_MODE_4 0x8000 +#define F1_CTL_1000T_SPEED_MASK 0x0300 +#define F1_CTL_1000T_DEFAULT_CAP_MASK 0x0300 + + /* 1000BASE-T Status Register offset:10 */ + /* LP is 1000T HD capable */ +#define F1_STATUS_1000T_LP_HD_CAPS 0x0400 + + /* LP is 1000T FD capable */ +#define F1_STATUS_1000T_LP_FD_CAPS 0x0800 + + /* Remote receiver OK */ +#define F1_STATUS_1000T_REMOTE_RX_STATUS 0x1000 + + /* Local receiver OK */ +#define F1_STATUS_1000T_LOCAL_RX_STATUS 0x2000 + + /* 1=Local TX is Master, 0=Slave */ +#define F1_STATUS_1000T_MS_CONFIG_RES 0x4000 + +#define F1_STATUS_1000T_MS_CONFIG_FAULT 0x8000 + + /* Master/Slave config fault */ +#define F1_STATUS_1000T_REMOTE_RX_STATUS_SHIFT 12 +#define F1_STATUS_1000T_LOCAL_RX_STATUS_SHIFT 13 + + /* Phy Specific Control Register offset:16*/ + /* 1=Jabber Function disabled */ +#define F1_CTL_JABBER_DISABLE 0x0001 + + /* 1=Polarity Reversal enabled */ +#define F1_CTL_POLARITY_REVERSAL 0x0002 + + /* 1=SQE Test enabled */ +#define F1_CTL_SQE_TEST 0x0004 +#define F1_CTL_MAC_POWERDOWN 0x0008 + + /* 1=CLK125 low, 0=CLK125 toggling + #define F1_CTL_CLK125_DISABLE 0x0010 + */ + /* MDI Crossover Mode bits 6:5 */ + /* Manual MDI configuration */ +#define F1_CTL_MDI_MANUAL_MODE 0x0000 + + /* Manual MDIX configuration */ +#define F1_CTL_MDIX_MANUAL_MODE 0x0020 + + /* 1000BASE-T: Auto crossover, 100BASE-TX/10BASE-T: MDI Mode */ +#define F1_CTL_AUTO_X_1000T 0x0040 + + /* Auto crossover enabled all speeds */ +#define F1_CTL_AUTO_X_MODE 0x0060 + + /* 1=Enable Extended 10BASE-T distance + * (Lower 10BASE-T RX Threshold) + * 0=Normal 10BASE-T RX Threshold */ +#define F1_CTL_10BT_EXT_DIST_ENABLE 0x0080 + + /* 1=5-Bit interface in 100BASE-TX + * 0=MII interface in 100BASE-TX */ +#define F1_CTL_MII_5BIT_ENABLE 0x0100 + + /* 1=Scrambler disable */ +#define F1_CTL_SCRAMBLER_DISABLE 0x0200 + + /* 1=Force link good */ +#define F1_CTL_FORCE_LINK_GOOD 0x0400 + + /* 1=Assert CRS on Transmit */ +#define F1_CTL_ASSERT_CRS_ON_TX 0x0800 + +#define F1_CTL_POLARITY_REVERSAL_SHIFT 1 +#define F1_CTL_AUTO_X_MODE_SHIFT 5 +#define F1_CTL_10BT_EXT_DIST_ENABLE_SHIFT 7 + + /* Phy Specific status fields offset:17*/ + /* 1=Speed & Duplex resolved */ +#define F1_STATUS_LINK_PASS 0x0400 +#define F1_STATUS_RESOVLED 0x0800 + + /* 1=Duplex 0=Half Duplex */ +#define F1_STATUS_FULL_DUPLEX 0x2000 + + /* Speed, bits 14:15 */ +#define F1_STATUS_SPEED 0xC000 +#define F1_STATUS_SPEED_MASK 0xC000 + + /* 00=10Mbs */ +#define F1_STATUS_SPEED_10MBS 0x0000 + + /* 01=100Mbs */ +#define F1_STATUS_SPEED_100MBS 0x4000 + + /* 10=1000Mbs */ +#define F1_STATUS_SPEED_1000MBS 0x8000 +#define F1_SPEED_DUPLEX_RESOVLED(phy_status) \ + (((phy_status) & \ + (F1_STATUS_RESOVLED)) == \ + (F1_STATUS_RESOVLED)) + + /*phy debug port1 register offset:29*/ + /*phy debug port2 register offset:30*/ + + /*F1 interrupt flag */ +#define F1_INTR_SPEED_CHANGE 0x4000 +#define F1_INTR_DUPLEX_CHANGE 0x2000 +#define F1_INTR_STATUS_UP_CHANGE 0x0400 +#define F1_INTR_STATUS_DOWN_CHANGE 0x0800 + + sw_error_t + f1_phy_set_powersave(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable); + + sw_error_t + f1_phy_get_powersave(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t *enable); + + sw_error_t + f1_phy_set_hibernate(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable); + + sw_error_t + f1_phy_get_hibernate(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t *enable); + + sw_error_t + f1_phy_cdt(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t mdi_pair, + fal_cable_status_t *cable_status, a_uint32_t *cable_len) ; + + sw_error_t + f1_phy_set_duplex(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_duplex_t duplex); + + sw_error_t + f1_phy_get_duplex(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_duplex_t * duplex); + + sw_error_t + f1_phy_set_speed(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_speed_t speed); + + sw_error_t + f1_phy_get_speed(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_speed_t * speed); + + sw_error_t + f1_phy_restart_autoneg(a_uint32_t dev_id, a_uint32_t phy_id); + + sw_error_t + f1_phy_enable_autoneg(a_uint32_t dev_id, a_uint32_t phy_id); + + a_bool_t + f1_phy_get_link_status(a_uint32_t dev_id, a_uint32_t phy_id); + + sw_error_t + f1_phy_set_autoneg_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t autoneg); + + sw_error_t + f1_phy_get_autoneg_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * autoneg); + + a_bool_t f1_phy_autoneg_status(a_uint32_t dev_id, a_uint32_t phy_id); + + sw_error_t + f1_phy_intr_mask_set(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t intr_mask_flag); + + sw_error_t + f1_phy_intr_mask_get(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * intr_mask_flag); + + sw_error_t + f1_phy_intr_status_get(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * intr_status_flag); + + sw_error_t + f1_phy_set_8023az(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable); + + sw_error_t + f1_phy_get_8023az(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t *enable); + + int + f1_phy_init(a_uint32_t dev_id, a_uint32_t port_bmp); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _F1_PHY_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/f2_phy.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/f2_phy.h new file mode 100755 index 000000000..13ce278a8 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/f2_phy.h @@ -0,0 +1,399 @@ +/* + * Copyright (c) 2012, 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. + */ + + + +#ifndef _F2_PHY_H_ +#define _F2_PHY_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + /* Athena PHY Registers */ +#define F2_PHY_CONTROL 0 +#define F2_PHY_STATUS 1 +#define F2_PHY_ID1 2 +#define F2_PHY_ID2 3 +#define F2_AUTONEG_ADVERT 4 +#define F2_LINK_PARTNER_ABILITY 5 +#define F2_AUTONEG_EXPANSION 6 +#define F2_NEXT_PAGE_TRANSMIT 7 +#define F2_LINK_PARTNER_NEXT_PAGE 8 +#define F2_1000BASET_CONTROL 9 +#define F2_1000BASET_STATUS 10 +#define F2_PHY_SPEC_CONTROL 16 +#define F2_PHY_SPEC_STATUS 17 +#define F2_PHY_CDT_CONTROL 22 +#define F2_PHY_CDT_STATUS 28 +#define F2_DEBUG_PORT_ADDRESS 29 +#define F2_DEBUG_PORT_DATA 30 + + /* Athena PHY Registers Field*/ + + /* Control Register fields offset:0*/ + /* bits 6,13: 10=1000, 01=100, 00=10 */ +#define F2_CTRL_SPEED_MSB 0x0040 + + /* Collision test enable */ +#define F2_CTRL_COLL_TEST_ENABLE 0x0080 + + /* FDX =1, half duplex =0 */ +#define F2_CTRL_FULL_DUPLEX 0x0100 + + /* Restart auto negotiation */ +#define F2_CTRL_RESTART_AUTONEGOTIATION 0x0200 + + /* Isolate PHY from MII */ +#define F2_CTRL_ISOLATE 0x0400 + + /* Power down */ +#define F2_CTRL_POWER_DOWN 0x0800 + + /* Auto Neg Enable */ +#define F2_CTRL_AUTONEGOTIATION_ENABLE 0x1000 + + /* bits 6,13: 10=1000, 01=100, 00=10 */ +#define F2_CTRL_SPEED_LSB 0x2000 + + /* 0 = normal, 1 = loopback */ +#define F2_CTRL_LOOPBACK 0x4000 +#define F2_CTRL_SOFTWARE_RESET 0x8000 + +#define F2_CTRL_SPEED_MASK 0x2040 +#define F2_CTRL_SPEED_1000 0x0040 +#define F2_CTRL_SPEED_100 0x2000 +#define F2_CTRL_SPEED_10 0x0000 + +#define F2_RESET_DONE(phy_control) \ + (((phy_control) & (F2_CTRL_SOFTWARE_RESET)) == 0) + + /* Status Register fields offset:1*/ + /* Extended register capabilities */ +#define F2_STATUS_EXTENDED_CAPS 0x0001 + + /* Jabber Detected */ +#define F2_STATUS_JABBER_DETECT 0x0002 + + /* Link Status 1 = link */ +#define F2_STATUS_LINK_STATUS_UP 0x0004 + + /* Auto Neg Capable */ +#define F2_STATUS_AUTONEG_CAPS 0x0008 + + /* Remote Fault Detect */ +#define F2_STATUS_REMOTE_FAULT 0x0010 + + /* Auto Neg Complete */ +#define F2_STATUS_AUTO_NEG_DONE 0x0020 + + /* Preamble may be suppressed */ +#define F2_STATUS_PREAMBLE_SUPPRESS 0x0040 + + /* Ext. status info in Reg 0x0F */ +#define F2_STATUS_EXTENDED_STATUS 0x0100 + + /* 100T2 Half Duplex Capable */ +#define F2_STATUS_100T2_HD_CAPS 0x0200 + + /* 100T2 Full Duplex Capable */ +#define F2_STATUS_100T2_FD_CAPS 0x0400 + + /* 10T Half Duplex Capable */ +#define F2_STATUS_10T_HD_CAPS 0x0800 + + /* 10T Full Duplex Capable */ +#define F2_STATUS_10T_FD_CAPS 0x1000 + + /* 100X Half Duplex Capable */ +#define F2_STATUS_100X_HD_CAPS 0x2000 + + /* 100X Full Duplex Capable */ +#define F2_STATUS_100X_FD_CAPS 0x4000 + + /* 100T4 Capable */ +#define F2_STATUS_100T4_CAPS 0x8000 + +#define F2_AUTONEG_DONE(ip_phy_status) \ + (((ip_phy_status) & (F2_STATUS_AUTO_NEG_DONE)) == \ + (F2_STATUS_AUTO_NEG_DONE)) + + /* PHY identifier1 offset:2*/ +//Organizationally Unique Identifier bits 3:18 + + /* PHY identifier2 offset:3*/ +//Organizationally Unique Identifier bits 19:24 + + /* Auto-Negotiation Advertisement register. offset:4*/ + /* indicates IEEE 802.3 CSMA/CD */ +#define F2_ADVERTISE_SELECTOR_FIELD 0x0001 + + /* 10T Half Duplex Capable */ +#define F2_ADVERTISE_10HALF 0x0020 + + /* 10T Full Duplex Capable */ +#define F2_ADVERTISE_10FULL 0x0040 + + /* 100TX Half Duplex Capable */ +#define F2_ADVERTISE_100HALF 0x0080 + + /* 100TX Full Duplex Capable */ +#define F2_ADVERTISE_100FULL 0x0100 + + /* 100T4 Capable */ +#define F2_ADVERTISE_100T4 0x0200 + + /* Pause operation desired */ +#define F2_ADVERTISE_PAUSE 0x0400 + + /* Asymmetric Pause Direction bit */ +#define F2_ADVERTISE_ASYM_PAUSE 0x0800 + + /* Remote Fault detected */ +#define F2_ADVERTISE_REMOTE_FAULT 0x2000 + + /* Next Page ability supported */ +#define F2_ADVERTISE_NEXT_PAGE 0x8000 + +#define F2_ADVERTISE_ALL \ + (F2_ADVERTISE_10HALF | F2_ADVERTISE_10FULL | \ + F2_ADVERTISE_100HALF | F2_ADVERTISE_100FULL ) + + /* Link Partner ability offset:5*/ + /* Same as advertise selector */ +#define F2_LINK_SLCT 0x001f + + /* Can do 10mbps half-duplex */ +#define F2_LINK_10BASETX_HALF_DUPLEX 0x0020 + + /* Can do 10mbps full-duplex */ +#define F2_LINK_10BASETX_FULL_DUPLEX 0x0040 + + /* Can do 100mbps half-duplex */ +#define F2_LINK_100BASETX_HALF_DUPLEX 0x0080 + + /* Can do 100mbps full-duplex */ +#define F2_LINK_100BASETX_FULL_DUPLEX 0x0100 + + /* 100BASE-T4 */ +#define F2_LINK_100BASE4 0x0200 + + /* PAUSE */ +#define F2_LINK_PAUSE 0x0400 + + /* Asymmetrical PAUSE */ +#define F2_LINK_ASYPAUSE 0x0800 + + /* Link partner faulted */ +#define F2_LINK_RFAULT 0x2000 + + /* Link partner acked us */ +#define F2_LINK_LPACK 0x4000 + + /* Next page bit */ +#define F2_LINK_NPAGE 0x8000 + + /* Auto-Negotiation Expansion Register offset:6 */ + + /* Next Page Transmit Register offset:7 */ + + /* Link partner Next Page Register offset:8*/ + + /* 1000BASE-T Control Register offset:9*/ + /* Advertise 1000T HD capability */ +#define F2_CTL_1000T_HD_CAPS 0x0100 + + /* Advertise 1000T FD capability */ +#define F2_CTL_1000T_FD_CAPS 0x0200 + + /* 1=Repeater/switch device port 0=DTE device*/ +#define F2_CTL_1000T_REPEATER_DTE 0x0400 + + /* 1=Configure PHY as Master 0=Configure PHY as Slave */ +#define F2_CTL_1000T_MS_VALUE 0x0800 + + /* 1=Master/Slave manual config value 0=Automatic Master/Slave config */ +#define F2_CTL_1000T_MS_ENABLE 0x1000 + + /* Normal Operation */ +#define F2_CTL_1000T_TEST_MODE_NORMAL 0x0000 + + /* Transmit Waveform test */ +#define F2_CTL_1000T_TEST_MODE_1 0x2000 + + /* Master Transmit Jitter test */ +#define F2_CTL_1000T_TEST_MODE_2 0x4000 + + /* Slave Transmit Jitter test */ +#define F2_CTL_1000T_TEST_MODE_3 0x6000 + + /* Transmitter Distortion test */ +#define F2_CTL_1000T_TEST_MODE_4 0x8000 +#define F2_CTL_1000T_SPEED_MASK 0x0300 +#define F2_CTL_1000T_DEFAULT_CAP_MASK 0x0300 + + /* 1000BASE-T Status Register offset:10 */ + /* LP is 1000T HD capable */ +#define F2_STATUS_1000T_LP_HD_CAPS 0x0400 + + /* LP is 1000T FD capable */ +#define F2_STATUS_1000T_LP_FD_CAPS 0x0800 + + /* Remote receiver OK */ +#define F2_STATUS_1000T_REMOTE_RX_STATUS 0x1000 + + /* Local receiver OK */ +#define F2_STATUS_1000T_LOCAL_RX_STATUS 0x2000 + + /* 1=Local TX is Master, 0=Slave */ +#define F2_STATUS_1000T_MS_CONFIG_RES 0x4000 + +#define F2_STATUS_1000T_MS_CONFIG_FAULT 0x8000 + + /* Master/Slave config fault */ +#define F2_STATUS_1000T_REMOTE_RX_STATUS_SHIFT 12 +#define F2_STATUS_1000T_LOCAL_RX_STATUS_SHIFT 13 + + /* Phy Specific Control Register offset:16*/ + /* 1=Jabber Function disabled */ +#define F2_CTL_JABBER_DISABLE 0x0001 + + /* 1=Polarity Reversal enabled */ +#define F2_CTL_POLARITY_REVERSAL 0x0002 + + /* 1=SQE Test enabled */ +#define F2_CTL_SQE_TEST 0x0004 +#define F2_CTL_MAC_POWERDOWN 0x0008 + + /* 1=CLK125 low, 0=CLK125 toggling + #define F2_CTL_CLK125_DISABLE 0x0010 + */ + /* MDI Crossover Mode bits 6:5 */ + /* Manual MDI configuration */ +#define F2_CTL_MDI_MANUAL_MODE 0x0000 + + /* Manual MDIX configuration */ +#define F2_CTL_MDIX_MANUAL_MODE 0x0020 + + /* 1000BASE-T: Auto crossover, 100BASE-TX/10BASE-T: MDI Mode */ +#define F2_CTL_AUTO_X_1000T 0x0040 + + /* Auto crossover enabled all speeds */ +#define F2_CTL_AUTO_X_MODE 0x0060 + + /* 1=Enable Extended 10BASE-T distance + * (Lower 10BASE-T RX Threshold) + * 0=Normal 10BASE-T RX Threshold */ +#define F2_CTL_10BT_EXT_DIST_ENABLE 0x0080 + + /* 1=5-Bit interface in 100BASE-TX + * 0=MII interface in 100BASE-TX */ +#define F2_CTL_MII_5BIT_ENABLE 0x0100 + + /* 1=Scrambler disable */ +#define F2_CTL_SCRAMBLER_DISABLE 0x0200 + + /* 1=Force link good */ +#define F2_CTL_FORCE_LINK_GOOD 0x0400 + + /* 1=Assert CRS on Transmit */ +#define F2_CTL_ASSERT_CRS_ON_TX 0x0800 + +#define F2_CTL_POLARITY_REVERSAL_SHIFT 1 +#define F2_CTL_AUTO_X_MODE_SHIFT 5 +#define F2_CTL_10BT_EXT_DIST_ENABLE_SHIFT 7 + + /* Phy Specific status fields offset:17*/ + /* 1=Speed & Duplex resolved */ +#define F2_STATUS_RESOVLED 0x0800 + + /* 1=Duplex 0=Half Duplex */ +#define F2_STATUS_FULL_DUPLEX 0x2000 + + /* Speed, bits 14:15 */ +#define F2_STATUS_SPEED 0xC000 +#define F2_STATUS_SPEED_MASK 0xC000 + + /* 00=10Mbs */ +#define F2_STATUS_SPEED_10MBS 0x0000 + + /* 01=100Mbs */ +#define F2_STATUS_SPEED_100MBS 0x4000 + + /* 10=1000Mbs */ +#define F2_STATUS_SPEED_1000MBS 0x8000 +#define F2_SPEED_DUPLEX_RESOVLED(phy_status) \ + (((phy_status) & \ + (F2_STATUS_RESOVLED)) == \ + (F2_STATUS_RESOVLED)) + + /*phy debug port1 register offset:29*/ + /*phy debug port2 register offset:30*/ + + sw_error_t + f2_phy_set_powersave(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable); + + sw_error_t + f2_phy_get_powersave(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t *enable); + + sw_error_t + f2_phy_set_hibernate(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable); + + sw_error_t + f2_phy_get_hibernate(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t *enable); + + sw_error_t + f2_phy_cdt(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t mdi_pair, + fal_cable_status_t *cable_status, a_uint32_t *cable_len) ; + + sw_error_t + f2_phy_set_duplex(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_duplex_t duplex); + + sw_error_t + f2_phy_get_duplex(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_duplex_t * duplex); + + sw_error_t + f2_phy_set_speed(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_speed_t speed); + + sw_error_t + f2_phy_get_speed(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_speed_t * speed); + + sw_error_t + f2_phy_restart_autoneg(a_uint32_t dev_id, a_uint32_t phy_id); + + sw_error_t + f2_phy_enable_autoneg(a_uint32_t dev_id, a_uint32_t phy_id); + + sw_error_t + f2_phy_set_autoneg_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t autoneg); + + sw_error_t + f2_phy_get_autoneg_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * autoneg); + + a_bool_t + f2_phy_autoneg_status(a_uint32_t dev_id, a_uint32_t phy_id); + + int f2_phy_init(a_uint32_t dev_id, a_uint32_t port_bmp); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _F2_PHY_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/hsl_phy.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/hsl_phy.h new file mode 100755 index 000000000..7597aeba7 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/hsl_phy.h @@ -0,0 +1,722 @@ +/* + * 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. + */ +/*qca808x_start*/ +#ifndef _HSL_PHY_H_ +#define _HSL_PHY_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal.h" +#include + + /** Phy function reset type */ + typedef enum { + PHY_FIFO_RESET = 0, /**< Phy fifo reset */ + } hsl_phy_function_reset_t; + + typedef sw_error_t(*hsl_phy_init) (a_uint32_t dev_id, + a_uint32_t phy_id); + typedef sw_error_t(*hsl_phy_hibernation_set) (a_uint32_t dev_id, + a_uint32_t phy_id, + a_bool_t enable); + typedef sw_error_t(*hsl_phy_hibernation_get) (a_uint32_t dev_id, + a_uint32_t phy_id, + a_bool_t * enable); + typedef sw_error_t(*hsl_phy_speed_get) (a_uint32_t dev_id, + a_uint32_t phy_id, + fal_port_speed_t * speed); + typedef sw_error_t(*hsl_phy_speed_set) (a_uint32_t dev_id, + a_uint32_t phy_id, + fal_port_speed_t speed); + typedef sw_error_t(*hsl_phy_duplex_get) (a_uint32_t dev_id, + a_uint32_t phy_id, + fal_port_duplex_t * duplex); + typedef sw_error_t(*hsl_phy_duplex_set) (a_uint32_t dev_id, + a_uint32_t phy_id, + fal_port_duplex_t duplex); + typedef sw_error_t(*hsl_phy_autoneg_enable_set) (a_uint32_t dev_id, + a_uint32_t phy_id); + typedef sw_error_t(*hsl_phy_autoneg_enable_get) (a_uint32_t dev_id, + a_uint32_t phy_id, + a_bool_t * enable); + typedef sw_error_t(*hsl_phy_restart_autoneg) (a_uint32_t dev_id, + a_uint32_t phy_id); + typedef a_bool_t(*hsl_phy_autoneg_status_get) (a_uint32_t dev_id, + a_uint32_t phy_id); + typedef sw_error_t(*hsl_phy_powersave_set) (a_uint32_t dev_id, + a_uint32_t phy_id, + a_bool_t enable); + typedef sw_error_t(*hsl_phy_powersave_get) (a_uint32_t dev_id, + a_uint32_t phy_id, + a_bool_t * enable); + typedef sw_error_t(*hsl_phy_cdt) (a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t mdi_pair, + fal_cable_status_t * cable_status, + a_uint32_t * cable_len); + typedef a_bool_t(*hsl_phy_link_status_get) (a_uint32_t dev_id, + a_uint32_t phy_id); + typedef sw_error_t(*hsl_phy_get_ability) (a_uint32_t dev_id, + a_uint32_t phy_id, + a_uint32_t * ability); + typedef sw_error_t(*hsl_phy_mdix_set) (a_uint32_t dev_id, + a_uint32_t phy_id, + fal_port_mdix_mode_t mode); + typedef sw_error_t(*hsl_phy_mdix_get) (a_uint32_t dev_id, + a_uint32_t phy_id, + fal_port_mdix_mode_t * mode); + typedef sw_error_t(*hsl_phy_mdix_status_get) (a_uint32_t dev_id, + a_uint32_t phy_id, + fal_port_mdix_status_t * + mode); + typedef sw_error_t(*hsl_phy_8023az_set) (a_uint32_t dev_id, + a_uint32_t phy_id, + a_bool_t enable); + typedef sw_error_t(*hsl_phy_8023az_get) (a_uint32_t dev_id, + a_uint32_t phy_id, + a_bool_t * enable); + typedef sw_error_t(*hsl_phy_local_loopback_set) (a_uint32_t dev_id, + a_uint32_t phy_id, + a_bool_t enable); + typedef sw_error_t(*hsl_phy_local_loopback_get) (a_uint32_t dev_id, + a_uint32_t phy_id, + a_bool_t * enable); + typedef sw_error_t(*hsl_phy_remote_loopback_set) (a_uint32_t dev_id, + a_uint32_t phy_id, + a_bool_t enable); + typedef sw_error_t(*hsl_phy_remote_loopback_get) (a_uint32_t dev_id, + a_uint32_t phy_id, + a_bool_t * enable); + typedef sw_error_t(*hsl_phy_master_set) (a_uint32_t dev_id, + a_uint32_t phy_id, + fal_port_master_t master); + typedef sw_error_t(*hsl_phy_master_get) (a_uint32_t dev_id, + a_uint32_t phy_id, + fal_port_master_t * master); +/*qca808x_end*/ + typedef sw_error_t(*hsl_phy_combo_prefer_medium_set) (a_uint32_t dev_id, + a_uint32_t phy_id, + fal_port_medium_t + phy_medium); + typedef sw_error_t(*hsl_phy_combo_prefer_medium_get) (a_uint32_t dev_id, + a_uint32_t phy_id, + fal_port_medium_t + * phy_medium); + typedef sw_error_t(*hsl_phy_combo_medium_status_get) (a_uint32_t dev_id, + a_uint32_t phy_id, + fal_port_medium_t + * phy_medium); + typedef sw_error_t(*hsl_phy_combo_fiber_mode_set) (a_uint32_t dev_id, + a_uint32_t phy_id, + fal_port_fiber_mode_t + fiber_mode); + typedef sw_error_t(*hsl_phy_combo_fiber_mode_get) (a_uint32_t dev_id, + a_uint32_t phy_id, + fal_port_fiber_mode_t + * fiber_mode); + typedef sw_error_t (*hsl_phy_function_reset) (a_uint32_t dev_id, + a_uint32_t phy_id, + hsl_phy_function_reset_t + phy_reset_type); +/*qca808x_start*/ + typedef sw_error_t(*hsl_phy_reset) (a_uint32_t dev_id, + a_uint32_t phy_id); + typedef sw_error_t(*hsl_phy_reset_status_get) (a_uint32_t dev_id, + a_uint32_t phy_id, + fal_port_reset_status_t * + status); + typedef sw_error_t(*hsl_phy_power_off) (a_uint32_t dev_id, + a_uint32_t phy_id); + typedef sw_error_t(*hsl_phy_power_on) (a_uint32_t dev_id, + a_uint32_t phy_id); + typedef sw_error_t(*hsl_phy_id_get) (a_uint32_t dev_id, + a_uint32_t phy_id, + a_uint32_t *phy_chip_id); + typedef sw_error_t(*hsl_phy_autoneg_adv_set) (a_uint32_t dev_id, + a_uint32_t phy_id, + a_uint32_t autoneg); + typedef sw_error_t(*hsl_phy_autoneg_adv_get) (a_uint32_t dev_id, + a_uint32_t phy_id, + a_uint32_t * autoneg); + typedef sw_error_t(*hsl_phy_reg_write) (a_uint32_t dev_id, + a_uint32_t phy_addr, + a_uint32_t reg, + a_uint16_t reg_val); + typedef a_uint16_t(*hsl_phy_reg_read) (a_uint32_t dev_id, + a_uint32_t phy_addr, + a_uint32_t reg); + typedef sw_error_t(*hsl_phy_debug_write) (a_uint32_t dev_id, + a_uint32_t phy_id, + a_uint16_t reg_id, + a_uint16_t reg_val); + typedef a_uint16_t(*hsl_phy_debug_read) (a_uint32_t dev_id, + a_uint32_t phy_id, + a_uint16_t reg_id); + typedef sw_error_t(*hsl_phy_mmd_write) (a_uint32_t dev_id, + a_uint32_t phy_id, + a_uint16_t mmd_num, + a_uint16_t reg_id, + a_uint16_t reg_val); + typedef a_uint16_t(*hsl_phy_mmd_read) (a_uint32_t dev_id, + a_uint32_t phy_id, + a_uint16_t mmd_num, + a_uint16_t reg_id); + + typedef sw_error_t(*hsl_phy_magic_frame_mac_set) (a_uint32_t dev_id, + a_uint32_t phy_id, + fal_mac_addr_t * mac); + + typedef sw_error_t(*hsl_phy_magic_frame_mac_get) (a_uint32_t dev_id, + a_uint32_t phy_id, + fal_mac_addr_t * mac); + typedef sw_error_t(*hsl_phy_wol_status_set) (a_uint32_t dev_id, + a_uint32_t phy_id, + a_bool_t enable); + typedef sw_error_t(*hsl_phy_wol_status_get) (a_uint32_t dev_id, + a_uint32_t phy_id, + a_bool_t * enable); + typedef sw_error_t(*hsl_phy_interface_mode_set) (a_uint32_t dev_id, + a_uint32_t phy_id, + fal_port_interface_mode_t + interface_mode); + typedef sw_error_t(*hsl_phy_interface_mode_get) (a_uint32_t dev_id, + a_uint32_t phy_id, + fal_port_interface_mode_t + * interface_mode); + typedef sw_error_t(*hsl_phy_interface_mode_status_get) (a_uint32_t dev_id, + a_uint32_t phy_id, + fal_port_interface_mode_t + * interface_mode); + typedef sw_error_t(*hsl_phy_intr_mask_set) (a_uint32_t dev_id, + a_uint32_t phy_id, + a_uint32_t mask); + typedef sw_error_t(*hsl_phy_intr_mask_get) (a_uint32_t dev_id, + a_uint32_t phy_id, + a_uint32_t * mask); + typedef sw_error_t(*hsl_phy_intr_status_get) (a_uint32_t dev_id, + a_uint32_t phy_id, + a_uint32_t * status); + typedef sw_error_t(*hsl_phy_counter_set) (a_uint32_t dev_id, + a_uint32_t phy_id, + a_bool_t enable); + typedef sw_error_t(*hsl_phy_counter_get) (a_uint32_t dev_id, + a_uint32_t phy_id, + a_bool_t * enable); + typedef sw_error_t(*hsl_phy_counter_show) (a_uint32_t dev_id, + a_uint32_t phy_id, + fal_port_counter_info_t * counter_info); + typedef sw_error_t(*hsl_phy_serdes_reset) (a_uint32_t dev_id); + + typedef sw_error_t(*hsl_phy_get_status) (a_uint32_t dev_id, + a_uint32_t phy_id, struct port_phy_status *phy_status); + + typedef sw_error_t(*hsl_phy_eee_adv_set) (a_uint32_t dev_id, + a_uint32_t phy_id, + a_uint32_t adv); + typedef sw_error_t(*hsl_phy_eee_adv_get) (a_uint32_t dev_id, + a_uint32_t phy_id, + a_uint32_t * adv); + typedef sw_error_t(*hsl_phy_eee_partner_adv_get) (a_uint32_t dev_id, + a_uint32_t phy_id, + a_uint32_t * adv); + typedef sw_error_t(*hsl_phy_eee_cap_get) (a_uint32_t dev_id, + a_uint32_t phy_id, + a_uint32_t * cap); + typedef sw_error_t(*hsl_phy_eee_status_get) (a_uint32_t dev_id, + a_uint32_t phy_id, + a_uint32_t * status); +/*qca808x_end*/ + typedef sw_error_t(*hsl_phy_led_ctrl_pattern_set) (a_uint32_t dev_id, + a_uint32_t phy_id, + led_ctrl_pattern_t * pattern); + typedef sw_error_t(*hsl_phy_led_ctrl_pattern_get) (a_uint32_t dev_id, + a_uint32_t phy_id, + led_ctrl_pattern_t * pattern); + typedef sw_error_t(*hsl_phy_led_ctrl_source_set) (a_uint32_t dev_id, + a_uint32_t phy_id, + a_uint32_t source_id, + led_ctrl_pattern_t * pattern); + typedef sw_error_t(*hsl_phy_ptp_security_set) (a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_security_t *sec); + + typedef sw_error_t(*hsl_phy_ptp_link_delay_set) (a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_time_t *time); + + typedef sw_error_t(*hsl_phy_ptp_rx_crc_recalc_status_get) (a_uint32_t dev_id, + a_uint32_t phy_id, a_bool_t *status); + + typedef sw_error_t(*hsl_phy_ptp_tod_uart_set) (a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_tod_uart_t *tod_uart); + + typedef sw_error_t(*hsl_phy_ptp_enhanced_timestamp_engine_get) (a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_direction_t direction, + fal_ptp_enhanced_ts_engine_t *ts_engine); + + typedef sw_error_t(*hsl_phy_ptp_pps_signal_control_set) (a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_pps_signal_control_t *sig_control); + + typedef sw_error_t(*hsl_phy_ptp_timestamp_get) (a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_direction_t direction, + fal_ptp_pkt_info_t *pkt_info, fal_ptp_time_t *time); + + typedef sw_error_t(*hsl_phy_ptp_asym_correction_get) (a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_asym_correction_t* asym_cf); + + typedef sw_error_t(*hsl_phy_ptp_rtc_time_snapshot_status_get) (a_uint32_t dev_id, + a_uint32_t phy_id, a_bool_t *status); + + typedef sw_error_t(*hsl_phy_ptp_capture_set) (a_uint32_t dev_id, + a_uint32_t phy_id, a_uint32_t capture_id, + fal_ptp_capture_t *capture); + + typedef sw_error_t(*hsl_phy_ptp_rtc_adjfreq_set) (a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_time_t *time); + + typedef sw_error_t(*hsl_phy_ptp_asym_correction_set) (a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_asym_correction_t *asym_cf); + + typedef sw_error_t(*hsl_phy_ptp_pkt_timestamp_set) (a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_time_t *time); + + typedef sw_error_t(*hsl_phy_ptp_rtc_time_get) (a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_time_t *time); + + typedef sw_error_t(*hsl_phy_ptp_rtc_time_set) (a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_time_t *time); + + typedef sw_error_t(*hsl_phy_ptp_pkt_timestamp_get) (a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_time_t *time); + + typedef sw_error_t(*hsl_phy_ptp_interrupt_set) (a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_interrupt_t *interrupt); + + typedef sw_error_t(*hsl_phy_ptp_trigger_set) (a_uint32_t dev_id, + a_uint32_t phy_id, a_uint32_t trigger_id, + fal_ptp_trigger_t *triger); + + typedef sw_error_t(*hsl_phy_ptp_pps_signal_control_get) (a_uint32_t dev_id, + a_uint32_t phy_id, + fal_ptp_pps_signal_control_t *sig_control); + + typedef sw_error_t(*hsl_phy_ptp_capture_get) (a_uint32_t dev_id, + a_uint32_t phy_id, a_uint32_t capture_id, + fal_ptp_capture_t *capture); + + typedef sw_error_t(*hsl_phy_ptp_rx_crc_recalc_enable) (a_uint32_t dev_id, + a_uint32_t phy_id, a_bool_t status); + + typedef sw_error_t(*hsl_phy_ptp_security_get) (a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_security_t *sec); + + typedef sw_error_t(*hsl_phy_ptp_increment_sync_from_clock_status_get) (a_uint32_t dev_id, + a_uint32_t phy_id, a_bool_t *status); + + typedef sw_error_t(*hsl_phy_ptp_tod_uart_get) (a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_tod_uart_t *tod_uart); + + typedef sw_error_t(*hsl_phy_ptp_enhanced_timestamp_engine_set) (a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_direction_t direction, + fal_ptp_enhanced_ts_engine_t *ts_engine); + + typedef sw_error_t(*hsl_phy_ptp_rtc_time_clear) (a_uint32_t dev_id, + a_uint32_t phy_id); + + typedef sw_error_t(*hsl_phy_ptp_reference_clock_set) (a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_reference_clock_t ref_clock); + + typedef sw_error_t(*hsl_phy_ptp_output_waveform_set) (a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_output_waveform_t *waveform); + + typedef sw_error_t(*hsl_phy_ptp_rx_timestamp_mode_set) (a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_rx_timestamp_mode_t ts_mode); + + typedef sw_error_t(*hsl_phy_ptp_grandmaster_mode_set) (a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_grandmaster_mode_t *gm_mode); + + typedef sw_error_t(*hsl_phy_ptp_config_set) (a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_config_t *config); + + typedef sw_error_t(*hsl_phy_ptp_trigger_get) (a_uint32_t dev_id, + a_uint32_t phy_id, a_uint32_t trigger_id, + fal_ptp_trigger_t *triger); + + typedef sw_error_t(*hsl_phy_ptp_rtc_adjfreq_get) (a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_time_t *time); + + typedef sw_error_t(*hsl_phy_ptp_grandmaster_mode_get) (a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_grandmaster_mode_t *gm_mode); + + typedef sw_error_t(*hsl_phy_ptp_rx_timestamp_mode_get) (a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_rx_timestamp_mode_t *ts_mode); + + typedef sw_error_t(*hsl_phy_ptp_rtc_adjtime_set) (a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_time_t *time); + + typedef sw_error_t(*hsl_phy_ptp_link_delay_get) (a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_time_t *time); + + typedef sw_error_t(*hsl_phy_ptp_increment_sync_from_clock_enable) (a_uint32_t dev_id, + a_uint32_t phy_id, a_bool_t status); + + typedef sw_error_t(*hsl_phy_ptp_config_get) (a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_config_t *config); + + typedef sw_error_t(*hsl_phy_ptp_output_waveform_get) (a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_output_waveform_t *waveform); + + typedef sw_error_t(*hsl_phy_ptp_interrupt_get) (a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_interrupt_t *interrupt); + + typedef sw_error_t(*hsl_phy_ptp_rtc_time_snapshot_enable) (a_uint32_t dev_id, + a_uint32_t phy_id, a_bool_t status); + + typedef sw_error_t(*hsl_phy_ptp_reference_clock_get) (a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_reference_clock_t *ref_clock); + + typedef struct hsl_phy_ptp_ops_s { + hsl_phy_ptp_security_set phy_ptp_security_set; + hsl_phy_ptp_link_delay_set phy_ptp_link_delay_set; + hsl_phy_ptp_rx_crc_recalc_status_get phy_ptp_rx_crc_recalc_status_get; + hsl_phy_ptp_tod_uart_set phy_ptp_tod_uart_set; + hsl_phy_ptp_enhanced_timestamp_engine_get phy_ptp_enhanced_timestamp_engine_get; + hsl_phy_ptp_pps_signal_control_set phy_ptp_pps_signal_control_set; + hsl_phy_ptp_timestamp_get phy_ptp_timestamp_get; + hsl_phy_ptp_asym_correction_get phy_ptp_asym_correction_get; + hsl_phy_ptp_rtc_time_snapshot_status_get phy_ptp_rtc_time_snapshot_status_get; + hsl_phy_ptp_capture_set phy_ptp_capture_set; + hsl_phy_ptp_rtc_adjfreq_set phy_ptp_rtc_adjfreq_set; + hsl_phy_ptp_asym_correction_set phy_ptp_asym_correction_set; + hsl_phy_ptp_pkt_timestamp_set phy_ptp_pkt_timestamp_set; + hsl_phy_ptp_rtc_time_get phy_ptp_rtc_time_get; + hsl_phy_ptp_rtc_time_set phy_ptp_rtc_time_set; + hsl_phy_ptp_pkt_timestamp_get phy_ptp_pkt_timestamp_get; + hsl_phy_ptp_interrupt_set phy_ptp_interrupt_set; + hsl_phy_ptp_trigger_set phy_ptp_trigger_set; + hsl_phy_ptp_pps_signal_control_get phy_ptp_pps_signal_control_get; + hsl_phy_ptp_capture_get phy_ptp_capture_get; + hsl_phy_ptp_rx_crc_recalc_enable phy_ptp_rx_crc_recalc_enable; + hsl_phy_ptp_security_get phy_ptp_security_get; + hsl_phy_ptp_increment_sync_from_clock_status_get \ + phy_ptp_increment_sync_from_clock_status_get; + hsl_phy_ptp_tod_uart_get phy_ptp_tod_uart_get; + hsl_phy_ptp_enhanced_timestamp_engine_set phy_ptp_enhanced_timestamp_engine_set; + hsl_phy_ptp_rtc_time_clear phy_ptp_rtc_time_clear; + hsl_phy_ptp_reference_clock_set phy_ptp_reference_clock_set; + hsl_phy_ptp_output_waveform_set phy_ptp_output_waveform_set; + hsl_phy_ptp_rx_timestamp_mode_set phy_ptp_rx_timestamp_mode_set; + hsl_phy_ptp_grandmaster_mode_set phy_ptp_grandmaster_mode_set; + hsl_phy_ptp_config_set phy_ptp_config_set; + hsl_phy_ptp_trigger_get phy_ptp_trigger_get; + hsl_phy_ptp_rtc_adjfreq_get phy_ptp_rtc_adjfreq_get; + hsl_phy_ptp_grandmaster_mode_get phy_ptp_grandmaster_mode_get; + hsl_phy_ptp_rx_timestamp_mode_get phy_ptp_rx_timestamp_mode_get; + hsl_phy_ptp_rtc_adjtime_set phy_ptp_rtc_adjtime_set; + hsl_phy_ptp_link_delay_get phy_ptp_link_delay_get; + hsl_phy_ptp_increment_sync_from_clock_enable \ + phy_ptp_increment_sync_from_clock_enable; + hsl_phy_ptp_config_get phy_ptp_config_get; + hsl_phy_ptp_output_waveform_get phy_ptp_output_waveform_get; + hsl_phy_ptp_interrupt_get phy_ptp_interrupt_get; + hsl_phy_ptp_rtc_time_snapshot_enable phy_ptp_rtc_time_snapshot_enable; + hsl_phy_ptp_reference_clock_get phy_ptp_reference_clock_get; + } hsl_phy_ptp_ops_t; + +/*qca808x_start*/ + typedef struct hsl_phy_ops_s { + + hsl_phy_init phy_init; + hsl_phy_hibernation_set phy_hibernation_set; + hsl_phy_hibernation_get phy_hibernation_get; + hsl_phy_speed_get phy_speed_get; + hsl_phy_speed_set phy_speed_set; + hsl_phy_duplex_get phy_duplex_get; + hsl_phy_duplex_set phy_duplex_set; + hsl_phy_autoneg_enable_set phy_autoneg_enable_set; + hsl_phy_autoneg_enable_get phy_autoneg_enable_get; + hsl_phy_restart_autoneg phy_restart_autoneg; + hsl_phy_autoneg_status_get phy_autoneg_status_get; + hsl_phy_autoneg_adv_set phy_autoneg_adv_set; + hsl_phy_autoneg_adv_get phy_autoneg_adv_get; + hsl_phy_powersave_set phy_powersave_set; + hsl_phy_powersave_get phy_powersave_get; + hsl_phy_cdt phy_cdt; + hsl_phy_link_status_get phy_link_status_get; + hsl_phy_get_ability phy_get_ability; + hsl_phy_mdix_set phy_mdix_set; + hsl_phy_mdix_get phy_mdix_get; + hsl_phy_mdix_status_get phy_mdix_status_get; + hsl_phy_8023az_set phy_8023az_set; + hsl_phy_8023az_get phy_8023az_get; + hsl_phy_local_loopback_set phy_local_loopback_set; + hsl_phy_local_loopback_get phy_local_loopback_get; + hsl_phy_remote_loopback_set phy_remote_loopback_set; + hsl_phy_remote_loopback_get phy_remote_loopback_get; + hsl_phy_master_set phy_master_set; + hsl_phy_master_get phy_master_get; +/*qca808x_end*/ + hsl_phy_combo_prefer_medium_set phy_combo_prefer_medium_set; + hsl_phy_combo_prefer_medium_get phy_combo_prefer_medium_get; + hsl_phy_combo_medium_status_get phy_combo_medium_status_get; + hsl_phy_combo_fiber_mode_set phy_combo_fiber_mode_set; + hsl_phy_combo_fiber_mode_get phy_combo_fiber_mode_get; + hsl_phy_function_reset phy_function_reset; +/*qca808x_start*/ + hsl_phy_reset phy_reset; + hsl_phy_power_off phy_power_off; + hsl_phy_power_on phy_power_on; + hsl_phy_reset_status_get phy_reset_status_get; + hsl_phy_id_get phy_id_get; + hsl_phy_reg_write phy_reg_write; + hsl_phy_reg_read phy_reg_read; + hsl_phy_debug_write phy_debug_write; + hsl_phy_debug_read phy_debug_read; + hsl_phy_mmd_write phy_mmd_write; + hsl_phy_mmd_read phy_mmd_read; + hsl_phy_magic_frame_mac_set phy_magic_frame_mac_set; + hsl_phy_magic_frame_mac_get phy_magic_frame_mac_get; + hsl_phy_wol_status_set phy_wol_status_set; + hsl_phy_wol_status_get phy_wol_status_get; + hsl_phy_interface_mode_set phy_interface_mode_set; + hsl_phy_interface_mode_get phy_interface_mode_get; + hsl_phy_interface_mode_status_get phy_interface_mode_status_get; + hsl_phy_intr_mask_set phy_intr_mask_set; + hsl_phy_intr_mask_get phy_intr_mask_get; + hsl_phy_intr_status_get phy_intr_status_get; + hsl_phy_counter_set phy_counter_set; + hsl_phy_counter_get phy_counter_get; + hsl_phy_counter_show phy_counter_show; + hsl_phy_serdes_reset phy_serdes_reset; + hsl_phy_get_status phy_get_status; + hsl_phy_eee_adv_set phy_eee_adv_set; + hsl_phy_eee_adv_get phy_eee_adv_get; + hsl_phy_eee_partner_adv_get phy_eee_partner_adv_get; + hsl_phy_eee_cap_get phy_eee_cap_get; + hsl_phy_eee_status_get phy_eee_status_get; +/*qca808x_end*/ + hsl_phy_led_ctrl_pattern_set phy_led_ctrl_pattern_set; + hsl_phy_led_ctrl_pattern_get phy_led_ctrl_pattern_get; + hsl_phy_led_ctrl_source_set phy_led_ctrl_source_set; + hsl_phy_ptp_ops_t phy_ptp_ops; +/*qca808x_start*/ + } hsl_phy_ops_t; + +typedef struct phy_driver_instance { + a_uint32_t phy_type; + a_uint32_t port_bmp[SW_MAX_NR_DEV]; + hsl_phy_ops_t *phy_ops; + int (*init)(a_uint32_t dev_id, a_uint32_t portbmp); + void (*exit)(a_uint32_t dev_id, a_uint32_t portbmp); +} phy_driver_instance_t; + +typedef enum +{ +/*qca808x_end*/ + F1_PHY_CHIP = 0, + F2_PHY_CHIP, + MALIBU_PHY_CHIP, + AQUANTIA_PHY_CHIP, + QCA803X_PHY_CHIP, + SFP_PHY_CHIP, + MPGE_PHY_CHIP, +/*qca808x_start*/ + QCA808X_PHY_CHIP, + MAX_PHY_CHIP, +} phy_type_t; + +#define PHY_INVALID_DAC 0 + +typedef struct { + a_uint8_t mdac; + a_uint8_t edac; +} phy_dac_t; + +typedef struct { + a_uint32_t phy_address[SW_MAX_NR_PORT]; + a_uint32_t phy_type[SW_MAX_NR_PORT]; + /* fake mdio address is used to register the phy device, + * when the phy is not accessed by the MDIO bus. + * */ + a_uint32_t phy_mdio_fake_address[SW_MAX_NR_PORT]; + a_uint8_t phy_access_type[SW_MAX_NR_PORT]; + a_bool_t phy_c45[SW_MAX_NR_PORT]; + a_bool_t phy_combo[SW_MAX_NR_PORT]; + a_uint32_t phy_reset_gpio[SW_MAX_NR_PORT]; + phy_dac_t phy_dac[SW_MAX_NR_PORT]; +} phy_info_t; +/*qca808x_end*/ +#define MALIBU5PORT_PHY 0x004DD0B1 +#define MALIBU2PORT_PHY 0x004DD0B2 +#define QCA8030_PHY 0x004DD076 +#define QCA8033_PHY 0x004DD074 +#define QCA8035_PHY 0x004DD072 +/*qca808x_start*/ +#define QCA8081_PHY_V1_1 0x004DD101 +#define INVALID_PHY_ID 0 + +/*qca808x_end*/ +#define F1V1_PHY 0x004DD033 +#define F1V2_PHY 0x004DD034 +#define F1V3_PHY 0x004DD035 +#define F1V4_PHY 0x004DD036 +#define F2V1_PHY 0x004DD042 +#define AQUANTIA_PHY_107 0x03a1b4e2 +#define AQUANTIA_PHY_108 0x03a1b4f2 +#define AQUANTIA_PHY_109 0x03a1b502 +#define AQUANTIA_PHY_111 0x03a1b610 +#define AQUANTIA_PHY_111B0 0x03a1b612 +#define AQUANTIA_PHY_112 0x03a1b660 +#define AQUANTIA_PHY_113C_A0 0x31c31C10 +#define AQUANTIA_PHY_113C_A1 0x31c31C11 +#define AQUANTIA_PHY_112C 0x03a1b792 + +#define PHY_805XV2 0x004DD082 +#define PHY_805XV1 0x004DD081 +/*qca808x_start*/ +#define SFP_PHY 0xaaaabbbb +/*qca808x_end*/ +#define MP_GEPHY 0x004DD0C0 +#define SFP_PHY_MASK 0xffffffff + +#define CABLE_PAIR_A 0 +#define CABLE_PAIR_B 1 +#define CABLE_PAIR_C 2 +#define CABLE_PAIR_D 3 +/*qca808x_start*/ +#define PHY_MDIO_ACCESS 0 +#define PHY_I2C_ACCESS 1 + +#define INVALID_PHY_ADDR 0xff +#define MAX_PHY_ADDR 0x1f +#define QCA8072_PHY_NUM 0x2 + +#define PHY_INVALID_DATA 0xffff + +#define PHY_RTN_ON_READ_ERROR(phy_data) \ + do { if (phy_data == PHY_INVALID_DATA) return(SW_READ_ERROR); } while(0); + +#define PHY_RTN_ON_ERROR(rv) \ + do { if (rv != SW_OK) return(rv); } while(0); + +sw_error_t +hsl_phy_api_ops_register(phy_type_t phy_type, hsl_phy_ops_t * phy_api_ops); + +sw_error_t +hsl_phy_api_ops_unregister(phy_type_t phy_type, hsl_phy_ops_t * phy_api_ops); + +hsl_phy_ops_t *hsl_phy_api_ops_get(a_uint32_t dev_id, a_uint32_t port_id); + +sw_error_t phy_api_ops_init(phy_type_t phy_type); + +int ssdk_phy_driver_init(a_uint32_t dev_id, ssdk_init_cfg *cfg); + +int qca_ssdk_phy_info_init(a_uint32_t dev_id); + +void qca_ssdk_port_bmp_init(a_uint32_t dev_id); +/*qca808x_end*/ +void hsl_phy_address_init(a_uint32_t dev_id, a_uint32_t i, + a_uint32_t value); +/*qca808x_start*/ +a_uint32_t +hsl_phyid_get(a_uint32_t dev_id, a_uint32_t port_id, ssdk_init_cfg *cfg); + +a_uint32_t +qca_ssdk_port_to_phy_addr(a_uint32_t dev_id, a_uint32_t port_id); +/*qca808x_end*/ +a_uint32_t +qca_ssdk_port_to_phy_mdio_fake_addr(a_uint32_t dev_id, a_uint32_t port_id); + +a_uint32_t +qca_ssdk_phy_mdio_fake_addr_to_port(a_uint32_t dev_id, a_uint32_t phy_addr); + +void qca_ssdk_phy_mdio_fake_address_set(a_uint32_t dev_id, a_uint32_t i, + a_uint32_t value); +/*qca808x_start*/ +void qca_ssdk_port_bmp_set(a_uint32_t dev_id, a_uint32_t value); + +a_uint32_t qca_ssdk_port_bmp_get(a_uint32_t dev_id); +/*qca808x_end*/ +a_uint32_t qca_ssdk_phy_type_port_bmp_get(a_uint32_t dev_id, + phy_type_t phy_type); +/*qca808x_start*/ +a_uint32_t +qca_ssdk_phy_addr_to_port(a_uint32_t dev_id, a_uint32_t phy_addr); +/*qca808x_end*/ +void +hsl_port_phy_c45_capability_set(a_uint32_t dev_id, a_uint32_t port_id, + a_bool_t enable); + +a_bool_t +hsl_port_phy_combo_capability_get(a_uint32_t dev_id, a_uint32_t port_id); + +void +hsl_port_phy_combo_capability_set(a_uint32_t dev_id, a_uint32_t port_id, + a_bool_t enable); +/*qca808x_start*/ +a_uint8_t +hsl_port_phy_access_type_get(a_uint32_t dev_id, a_uint32_t port_id); + +void +hsl_port_phy_access_type_set(a_uint32_t dev_id, a_uint32_t port_id, + a_uint8_t access_type); +/*qca808x_end*/ +sw_error_t +hsl_port_phy_serdes_reset(a_uint32_t dev_id); + +sw_error_t +hsl_port_phy_mode_set(a_uint32_t dev_id, fal_port_interface_mode_t mode); +phy_type_t hsl_phy_type_get(a_uint32_t dev_id, a_uint32_t port_id); + +a_uint32_t +hsl_port_phyid_get(a_uint32_t dev_id, fal_port_t port_id); + +a_uint32_t hsl_port_phy_reset_gpio_get(a_uint32_t dev_id, a_uint32_t port_id); + +void hsl_port_phy_reset_gpio_set(a_uint32_t dev_id, a_uint32_t port_id, + a_uint32_t phy_reset_gpio); + +void hsl_port_phy_gpio_reset(a_uint32_t dev_id, a_uint32_t port_id); + +void +hsl_port_phy_dac_get(a_uint32_t dev_id, a_uint32_t port_id, + phy_dac_t *phy_dac); + +void +hsl_port_phy_dac_set(a_uint32_t dev_id, a_uint32_t port_id, + phy_dac_t phy_dac); +/*qca808x_start*/ +sw_error_t ssdk_phy_driver_cleanup(void); +/*qca808x_end*/ +sw_error_t +hsl_phydriver_update(a_uint32_t dev_id, a_uint32_t port_id, + a_uint32_t mode); + +void +qca_ssdk_phy_address_set(a_uint32_t dev_id, a_uint32_t port_id, + a_uint32_t phy_addr); + +sw_error_t +hsl_port_phy_hw_init(a_uint32_t dev_id, a_uint32_t port_id); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)) +sw_error_t +hsl_port_phydev_adv_update(a_uint32_t dev_id, a_uint32_t port_id, + a_uint32_t autoadv); +#endif +/*qca808x_start*/ +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _HSL_PHY_H_ */ +/*qca808x_end*/ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/malibu_phy.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/malibu_phy.h new file mode 100755 index 000000000..b73540417 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/malibu_phy.h @@ -0,0 +1,676 @@ +/* + * Copyright (c) 2015, 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 _MALIBU_PHY_H_ +#define _MALIBU_PHY_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#define BIT_15 15 +#define BIT_14 14 +#define BIT_13 13 +#define BIT_12 12 +#define BIT_11 11 +#define BIT_10 10 +#define BIT_9 9 +#define BIT_8 8 +#define BIT_7 7 +#define BIT_6 6 +#define BIT_5 5 +#define BIT_4 4 +#define BIT_3 3 +#define BIT_2 2 +#define BIT_1 1 +#define BIT_0 0 +#define COMBO_PHY_ID 4 +#define PSGMII_ID 5 + +#define MALIBU_COMMON_CTRL 0x1040 +#define MALIBU_10M_LOOPBACK 0x4100 +#define MALIBU_100M_LOOPBACK 0x6100 +#define MALIBU_1000M_LOOPBACK 0x4140 + +#define MALIBU_1_0 0x004DD0B0 +#define MALIBU_1_1 0x004DD0B1 +#define MALIBU_1_1_2PORT 0x004DD0B2 +#define MALIBU_ORG_ID_OFFSET_LEN 16 +#define MALIBU_PHY_COPPER_MODE 0x8000 + + /* PHY Registers */ +#define MALIBU_PHY_CONTROL 0 +#define MALIBU_PHY_STATUS 1 +#define MALIBU_PHY_ID1 2 +#define MALIBU_PHY_ID2 3 +#define MALIBU_AUTONEG_ADVERT 4 +#define MALIBU_LINK_PARTNER_ABILITY 5 +#define MALIBU_AUTONEG_EXPANSION 6 +#define MALIBU_NEXT_PAGE_TRANSMIT 7 +#define MALIBU_LINK_PARTNER_NEXT_PAGE 8 +#define MALIBU_1000BASET_CONTROL 9 +#define MALIBU_1000BASET_STATUS 10 +#define MALIBU_MMD_CTRL_REG 13 +#define MALIBU_MMD_DATA_REG 14 +#define MALIBU_EXTENDED_STATUS 15 +#define MALIBU_PHY_SPEC_CONTROL 16 +#define MALIBU_PHY_SPEC_STATUS 17 +#define MALIBU_PHY_INTR_MASK 18 +#define MALIBU_PHY_INTR_STATUS 19 +#define MALIBU_PHY_CDT_CONTROL 22 +#define MALIBU_PHY_CDT_STATUS 28 +#define MALIBU_DEBUG_PORT_ADDRESS 29 +#define MALIBU_DEBUG_PORT_DATA 30 + +#define MALIBU_DEBUG_PHY_HIBERNATION_CTRL 0xb +#define MALIBU_DEBUG_PHY_POWER_SAVING_CTRL 0x29 +#define MALIBU_PHY_MMD7_ADDR_8023AZ_EEE_CTRL 0x3c +#define MALIBU_PHY_MMD7_ADDR_8023AZ_EEE_PARTNER 0x3d +#define MALIBU_PHY_MMD7_ADDR_8023AZ_EEE_STATUS 0x8000 +#define MALIBU_PHY_MMD3_ADDR_8023AZ_EEE_CAPABILITY 0x14 + +#define MALIBU_PHY_MMD3_ADDR_REMOTE_LOOPBACK_CTRL 0x805a +#define MALIBU_PHY_MMD3_WOL_MAGIC_MAC_CTRL1 0x804a +#define MALIBU_PHY_MMD3_WOL_MAGIC_MAC_CTRL2 0x804b +#define MALIBU_PHY_MMD3_WOL_MAGIC_MAC_CTRL3 0x804c +#define MALIBU_PHY_MMD3_WOL_CTRL 0x8012 +#define MALIBU_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL 0x804e +#define MALIBU_PHY_MMD3_ADDR_8023AZ_CLD_CTRL 0x8007 +#define MALIBU_PHY_MMD3_ADDR_CLD_CTRL5 0x8005 +#define MALIBU_PHY_MMD3_ADDR_CLD_CTRL3 0x8003 +#define MALIBU_PHY_MMD7_DAC_CTRL 0x801a +#define MALIBU_DAC_CTRL_MASK 0x380 +#define MALIBU_DAC_CTRL_VALUE 0x280 +#define MALIBU_LED_1000_CTRL1_100_10_MASK 0x30 + +#define MALIBU_PHY_EEE_ADV_100M 0x0002 +#define MALIBU_PHY_EEE_ADV_1000M 0x0004 +#define MALIBU_PHY_EEE_PARTNER_ADV_100M 0x0002 +#define MALIBU_PHY_EEE_PARTNER_ADV_1000M 0x0004 +#define MALIBU_PHY_EEE_CAPABILITY_100M 0x0002 +#define MALIBU_PHY_EEE_CAPABILITY_1000M 0x0004 +#define MALIBU_PHY_EEE_STATUS_100M 0x0002 +#define MALIBU_PHY_EEE_STATUS_1000M 0x0004 + + +#define AZ_TIMER_CTRL_DEFAULT_VALUE 0x3062 +#define AZ_CLD_CTRL_DEFAULT_VALUE 0x83f6 +#define AZ_TIMER_CTRL_ADJUST_VALUE 0x7062 +#define AZ_CLD_CTRL_ADJUST_VALUE 0x8396 + + +#define MALIBU_PHY_MMD7_COUNTER_CTRL 0x8029 +#define MALIBU_PHY_MMD7_INGRESS_COUNTER_HIGH 0x802a +#define MALIBU_PHY_MMD7_INGRESS_COUNTER_LOW 0x802b +#define MALIBU_PHY_MMD7_INGRESS_ERROR_COUNTER 0x802c +#define MALIBU_PHY_MMD7_EGRESS_COUNTER_HIGH 0x802d +#define MALIBU_PHY_MMD7_EGRESS_COUNTER_LOW 0x802e +#define MALIBU_PHY_MMD7_EGRESS_ERROR_COUNTER 0x802f +#define MALIBU_PHY_MMD7_LED_1000_CTRL1 0x8076 + + + +#define MALIBU_PSGMII_FIFI_CTRL 0x6e +#define MALIBU_PSGMII_CALIB_CTRL 0x27 +#define MALIBU_PSGMII_MODE_CTRL 0x6d +#define MALIBU_PSGMII_TX_DRIVER_1_CTRL 0xb + +#define MALIBU_PHY_PSGMII_MODE_CTRL_DEFAULT_VALUE 0x220d +#define MALIBU_PHY_PSGMII_MODE_CTRL_ADJUST_VALUE 0x220c +#define MALIBU_PHY_PSGMII_REDUCE_SERDES_TX_AMP 0x8a + +#define MALIBU_PHY_QSGMII 0x8504 +#define MALIBU_PHY_PSGMII_ADDR_INC 0x5 +#define MALIBU_PHY_MAX_ADDR_INC 0x4 +#define MALIBU_MODE_CHANAGE_RESET 0x0 +#define MALIBU_MODE_RESET_DEFAULT_VALUE 0x5f +#define MALIBU_MODE_RESET_REG 0x0 + +#define MALIBU_PHY_TX_FLOWCTRL_STATUS 0x8 +#define MALIBU_PHY_RX_FLOWCTRL_STATUS 0x4 + + +#define MALIBU_PHY_MMD7_NUM 7 +#define MALIBU_PHY_MMD3_NUM 3 +#define MALIBU_PHY_MMD1_NUM 1 + +#define MALIBU_PHY_SGMII_STATUS 0x1a /* sgmii_status Register */ +#define MALIBU_PHY4_AUTO_SGMII_SELECT 0x40 +#define MALIBU_PHY4_AUTO_COPPER_SELECT 0x20 +#define MALIBU_PHY4_AUTO_BX1000_SELECT 0x10 +#define MALIBU_PHY4_AUTO_FX100_SELECT 0x8 + +#define MALIBU_PHY_CHIP_CONFIG 0x1f /* Chip Configuration Register */ +#define BT_BX_SG_REG_SELECT BIT_15 +#define BT_BX_SG_REG_SELECT_OFFSET 15 +#define BT_BX_SG_REG_SELECT_LEN 1 +#define MALIBU_SG_BX_PAGES 0x0 +#define MALIBU_SG_COPPER_PAGES 0x1 + +#define MALIBU_PHY_PSGMII_BASET 0x0 +#define MALIBU_PHY_PSGMII_BX1000 0x1 +#define MALIBU_PHY_PSGMII_FX100 0x2 +#define MALIBU_PHY_PSGMII_AMDET 0x3 +#define MALIBU_PHY_SGMII_BASET 0x4 + +#define MALIBU_PHY4_PREFER_FIBER 0x400 +#define PHY4_PREFER_COPPER 0x0 +#define PHY4_PREFER_FIBER 0x1 + +#define MALIBU_PHY4_FIBER_MODE_1000BX 0x100 +#define AUTO_100FX_FIBER 0x0 +#define AUTO_1000BX_FIBER 0x1 + +#define MALIBU_PHY_MDIX 0x0020 +#define MALIBU_PHY_MDIX_AUTO 0x0060 +#define MALIBU_PHY_MDIX_STATUS 0x0040 + +#define MODE_CFG_QUAL BIT_4 +#define MODE_CFG_QUAL_OFFSET 4 +#define MODE_CFG_QUAL_LEN 4 + +#define MODE_CFG BIT_0 +#define MODE_CFG_OFFSET 0 +#define MODE_CFG_LEN 4 + +#define MALIBU_MODECTRL_DFLT 0x533 +#define MALIBU_MIICTRL_DFLT 0x140 + + /*debug port */ +#define MALIBU_DEBUG_PORT_RGMII_MODE 18 +#define MALIBU_DEBUG_PORT_RGMII_MODE_EN 0x0008 + +#define MALIBU_DEBUG_PORT_RX_DELAY 0 +#define MALIBU_DEBUG_PORT_RX_DELAY_EN 0x8000 + +#define MALIBU_DEBUG_PORT_TX_DELAY 5 +#define MALIBU_DEBUG_PORT_TX_DELAY_EN 0x0100 + + /* PHY Registers Field */ + + /* Control Register fields offset:0 */ + /* bits 6,13: 10=1000, 01=100, 00=10 */ +#define MALIBU_CTRL_SPEED_MSB 0x0040 + + /* Collision test enable */ +#define MALIBU_CTRL_COLL_TEST_ENABLE 0x0080 + + /* FDX =1, half duplex =0 */ +#define MALIBU_CTRL_FULL_DUPLEX 0x0100 + + /* Restart auto negotiation */ +#define MALIBU_CTRL_RESTART_AUTONEGOTIATION 0x0200 + + /* Isolate PHY from MII */ +#define MALIBU_CTRL_ISOLATE 0x0400 + + /* Power down */ +#define MALIBU_CTRL_POWER_DOWN 0x0800 + + /* Auto Neg Enable */ +#define MALIBU_CTRL_AUTONEGOTIATION_ENABLE 0x1000 + + /* Local Loopback Enable */ +#define MALIBU_LOCAL_LOOPBACK_ENABLE 0x4000 + + /* bits 6,13: 10=1000, 01=100, 00=10 */ +#define MALIBU_CTRL_SPEED_LSB 0x2000 + + /* 0 = normal, 1 = loopback */ +#define MALIBU_CTRL_LOOPBACK 0x4000 +#define MALIBU_CTRL_SOFTWARE_RESET 0x8000 + +#define MALIBU_CTRL_SPEED_MASK 0x2040 +#define MALIBU_CTRL_SPEED_1000 0x0040 +#define MALIBU_CTRL_SPEED_100 0x2000 +#define MALIBU_CTRL_SPEED_10 0x0000 + +#define MALIBU_RESET_DONE(phy_control) \ + (((phy_control) & (MALIBU_CTRL_SOFTWARE_RESET)) == 0) + + /* Status Register fields offset:1 */ + /* Extended register capabilities */ +#define MALIBU_STATUS_EXTENDED_CAPS 0x0001 + + /* Jabber Detected */ +#define MALIBU_STATUS_JABBER_DETECT 0x0002 + + /* Link Status 1 = link */ +#define MALIBU_STATUS_LINK_STATUS_UP 0x0004 + + /* Auto Neg Capable */ +#define MALIBU_STATUS_AUTONEG_CAPS 0x0008 + + /* Remote Fault Detect */ +#define MALIBU_STATUS_REMOTE_FAULT 0x0010 + + /* Auto Neg Complete */ +#define MALIBU_STATUS_AUTO_NEG_DONE 0x0020 + + /* Preamble may be suppressed */ +#define MALIBU_STATUS_PREAMBLE_SUPPRESS 0x0040 + + /* Ext. status info in Reg 0x0F */ +#define MALIBU_STATUS_EXTENDED_STATUS 0x0100 + + /* 100T2 Half Duplex Capable */ +#define MALIBU_STATUS_100T2_HD_CAPS 0x0200 + + /* 100T2 Full Duplex Capable */ +#define MALIBU_STATUS_100T2_FD_CAPS 0x0400 + + /* 10T Half Duplex Capable */ +#define MALIBU_STATUS_10T_HD_CAPS 0x0800 + + /* 10T Full Duplex Capable */ +#define MALIBU_STATUS_10T_FD_CAPS 0x1000 + + /* 100X Half Duplex Capable */ +#define MALIBU_STATUS_100X_HD_CAPS 0x2000 + + /* 100X Full Duplex Capable */ +#define MALIBU_STATUS_100X_FD_CAPS 0x4000 + + /* 100T4 Capable */ +#define MALIBU_STATUS_100T4_CAPS 0x8000 + + /* extended status register capabilities */ + +#define MALIBU_STATUS_1000T_HD_CAPS 0x1000 + +#define MALIBU_STATUS_1000T_FD_CAPS 0x2000 + +#define MALIBU_STATUS_1000X_HD_CAPS 0x4000 + +#define MALIBU_STATUS_1000X_FD_CAPS 0x8000 + +#define MALIBU_AUTONEG_DONE(ip_phy_status) \ + (((ip_phy_status) & (MALIBU_STATUS_AUTO_NEG_DONE)) == \ + (MALIBU_STATUS_AUTO_NEG_DONE)) + + /* PHY identifier1 offset:2 */ +//Organizationally Unique Identifier bits 3:18 + + /* PHY identifier2 offset:3 */ +//Organizationally Unique Identifier bits 19:24 + + /* Auto-Negotiation Advertisement register. offset:4 */ + /* indicates IEEE 802.3 CSMA/CD */ +#define MALIBU_ADVERTISE_SELECTOR_FIELD 0x0001 + + /* 10T Half Duplex Capable */ +#define MALIBU_ADVERTISE_10HALF 0x0020 + + /* 10T Full Duplex Capable */ +#define MALIBU_ADVERTISE_10FULL 0x0040 + + /* 100TX Half Duplex Capable */ +#define MALIBU_ADVERTISE_100HALF 0x0080 + + /* 100TX Full Duplex Capable */ +#define MALIBU_ADVERTISE_100FULL 0x0100 + + /* 100T4 Capable */ +#define MALIBU_ADVERTISE_100T4 0x0200 + + /* Pause operation desired */ +#define MALIBU_ADVERTISE_PAUSE 0x0400 + + /* Asymmetric Pause Direction bit */ +#define MALIBU_ADVERTISE_ASYM_PAUSE 0x0800 + + /* Remote Fault detected */ +#define MALIBU_ADVERTISE_REMOTE_FAULT 0x2000 + + /* Next Page ability supported */ +#define MALIBU_ADVERTISE_NEXT_PAGE 0x8000 + + /* 100TX Half Duplex Capable */ +#define MALIBU_ADVERTISE_1000HALF 0x0100 + + /* 100TX Full Duplex Capable */ +#define MALIBU_ADVERTISE_1000FULL 0x0200 + + /* Extended next page enable control */ +#define MALIBU_EXTENDED_NEXT_PAGE_EN 0x1000 + +#define MALIBU_ADVERTISE_ALL \ + (MALIBU_ADVERTISE_10HALF | MALIBU_ADVERTISE_10FULL | \ + MALIBU_ADVERTISE_100HALF | MALIBU_ADVERTISE_100FULL | \ + MALIBU_ADVERTISE_1000FULL) + +#define MALIBU_ADVERTISE_MEGA_ALL \ + (MALIBU_ADVERTISE_10HALF | MALIBU_ADVERTISE_10FULL | \ + MALIBU_ADVERTISE_100HALF | MALIBU_ADVERTISE_100FULL) + +#define MALIBU_BX_ADVERTISE_1000FULL 0x0020 +#define MALIBU_BX_ADVERTISE_1000HALF 0x0040 +#define MALIBU_BX_ADVERTISE_PAUSE 0x0080 +#define MALIBU_BX_ADVERTISE_ASYM_PAUSE 0x0100 + +#define MALIBU_BX_ADVERTISE_ALL \ + (MALIBU_BX_ADVERTISE_ASYM_PAUSE | MALIBU_BX_ADVERTISE_PAUSE | \ + MALIBU_BX_ADVERTISE_1000HALF | MALIBU_BX_ADVERTISE_1000FULL) + + /* Link Partner ability offset:5 */ + /* Same as advertise selector */ +#define MALIBU_LINK_SLCT 0x001f + + /* Can do 10mbps half-duplex */ +#define MALIBU_LINK_10BASETX_HALF_DUPLEX 0x0020 + + /* Can do 10mbps full-duplex */ +#define MALIBU_LINK_10BASETX_FULL_DUPLEX 0x0040 + + /* Can do 100mbps half-duplex */ +#define MALIBU_LINK_100BASETX_HALF_DUPLEX 0x0080 + + /* Can do 100mbps full-duplex */ +#define MALIBU_LINK_100BASETX_FULL_DUPLEX 0x0100 + + /* Can do 1000mbps full-duplex */ +#define MALIBU_LINK_1000BASETX_FULL_DUPLEX 0x0800 + + /* Can do 1000mbps half-duplex */ +#define MALIBU_LINK_1000BASETX_HALF_DUPLEX 0x0400 + + /* 100BASE-T4 */ +#define MALIBU_LINK_100BASE4 0x0200 + + /* PAUSE */ +#define MALIBU_LINK_PAUSE 0x0400 + + /* Asymmetrical PAUSE */ +#define MALIBU_LINK_ASYPAUSE 0x0800 + + /* Link partner faulted */ +#define MALIBU_LINK_RFAULT 0x2000 + + /* Link partner acked us */ +#define MALIBU_LINK_LPACK 0x4000 + + /* Next page bit */ +#define MALIBU_LINK_NPAGE 0x8000 + + /* Auto-Negotiation Expansion Register offset:6 */ + + /* Next Page Transmit Register offset:7 */ + + /* Link partner Next Page Register offset:8 */ + + /* 1000BASE-T Control Register offset:9 */ + /* Advertise 1000T HD capability */ +#define MALIBU_CTL_1000T_HD_CAPS 0x0100 + + /* Advertise 1000T FD capability */ +#define MALIBU_CTL_1000T_FD_CAPS 0x0200 + + /* 1=Repeater/switch device port 0=DTE device */ +#define MALIBU_CTL_1000T_REPEATER_DTE 0x0400 + + /* 1=Configure PHY as Master 0=Configure PHY as Slave */ +#define MALIBU_CTL_1000T_MS_VALUE 0x0800 + + /* 1=Master/Slave manual config value 0=Automatic Master/Slave config */ +#define MALIBU_CTL_1000T_MS_ENABLE 0x1000 + + /* Normal Operation */ +#define MALIBU_CTL_1000T_TEST_MODE_NORMAL 0x0000 + + /* Transmit Waveform test */ +#define MALIBU_CTL_1000T_TEST_MODE_1 0x2000 + + /* Master Transmit Jitter test */ +#define MALIBU_CTL_1000T_TEST_MODE_2 0x4000 + + /* Slave Transmit Jitter test */ +#define MALIBU_CTL_1000T_TEST_MODE_3 0x6000 + + /* Transmitter Distortion test */ +#define MALIBU_CTL_1000T_TEST_MODE_4 0x8000 +#define MALIBU_CTL_1000T_SPEED_MASK 0x0300 +#define MALIBU_CTL_1000T_DEFAULT_CAP_MASK 0x0300 + + /* 1000BASE-T Status Register offset:10 */ + /* LP is 1000T HD capable */ +#define MALIBU_STATUS_1000T_LP_HD_CAPS 0x0400 + + /* LP is 1000T FD capable */ +#define MALIBU_STATUS_1000T_LP_FD_CAPS 0x0800 + + /* Remote receiver OK */ +#define MALIBU_STATUS_1000T_REMOTE_RX_STATUS 0x1000 + + /* Local receiver OK */ +#define MALIBU_STATUS_1000T_LOCAL_RX_STATUS 0x2000 + + /* 1=Local TX is Master, 0=Slave */ +#define MALIBU_STATUS_1000T_MS_CONFIG_RES 0x4000 + +#define MALIBU_STATUS_1000T_MS_CONFIG_FAULT 0x8000 + + /* Master/Slave config fault */ +#define MALIBU_STATUS_1000T_REMOTE_RX_STATUS_SHIFT 12 +#define MALIBU_STATUS_1000T_LOCAL_RX_STATUS_SHIFT 13 + + /* Phy Specific Control Register offset:16 */ + /* 1=Jabber Function disabled */ +#define MALIBU_CTL_JABBER_DISABLE 0x0001 + + /* 1=Polarity Reversal enabled */ +#define MALIBU_CTL_POLARITY_REVERSAL 0x0002 + + /* 1=SQE Test enabled */ +#define MALIBU_CTL_SQE_TEST 0x0004 +#define MALIBU_CTL_MAC_POWERDOWN 0x0008 + + /* 1=CLK125 low, 0=CLK125 toggling + #define MALIBU_CTL_CLK125_DISABLE 0x0010 + */ + /* MDI Crossover Mode bits 6:5 */ + /* Manual MDI configuration */ +#define MALIBU_CTL_MDI_MANUAL_MODE 0x0000 + + /* Manual MDIX configuration */ +#define MALIBU_CTL_MDIX_MANUAL_MODE 0x0020 + + /* 1000BASE-T: Auto crossover, 100BASE-TX/10BASE-T: MDI Mode */ +#define MALIBU_CTL_AUTO_X_1000T 0x0040 + + /* Auto crossover enabled all speeds */ +#define MALIBU_CTL_AUTO_X_MODE 0x0060 + + /* 1=Enable Extended 10BASE-T distance + * (Lower 10BASE-T RX Threshold) + * 0=Normal 10BASE-T RX Threshold */ +#define MALIBU_CTL_10BT_EXT_DIST_ENABLE 0x0080 + + /* 1=5-Bit interface in 100BASE-TX + * 0=MII interface in 100BASE-TX */ +#define MALIBU_CTL_MII_5BIT_ENABLE 0x0100 + + /* 1=Scrambler disable */ +#define MALIBU_CTL_SCRAMBLER_DISABLE 0x0200 + + /* 1=Force link good */ +#define MALIBU_CTL_FORCE_LINK_GOOD 0x0400 + + /* 1=Assert CRS on Transmit */ +#define MALIBU_CTL_ASSERT_CRS_ON_TX 0x0800 + +#define MALIBU_CTL_POLARITY_REVERSAL_SHIFT 1 +#define MALIBU_CTL_AUTO_X_MODE_SHIFT 5 +#define MALIBU_CTL_10BT_EXT_DIST_ENABLE_SHIFT 7 + + /* Phy Specific status fields offset:17 */ + /* 1=Speed & Duplex resolved */ +#define MALIBU_STATUS_LINK_PASS 0x0400 +#define MALIBU_STATUS_RESOVLED 0x0800 + + /* 1=Duplex 0=Half Duplex */ +#define MALIBU_STATUS_FULL_DUPLEX 0x2000 + + /* Speed, bits 14:15 */ +#define MALIBU_STATUS_SPEED 0xC000 +#define MALIBU_STATUS_SPEED_MASK 0xC000 + + /* 00=10Mbs */ +#define MALIBU_STATUS_SPEED_10MBS 0x0000 + + /* 01=100Mbs */ +#define MALIBU_STATUS_SPEED_100MBS 0x4000 + + /* 10=1000Mbs */ +#define MALIBU_STATUS_SPEED_1000MBS 0x8000 +#define MALIBU_SPEED_DUPLEX_RESOVLED(phy_status) \ + (((phy_status) & \ + (MALIBU_STATUS_RESOVLED)) == \ + (MALIBU_STATUS_RESOVLED)) + + /*phy debug port1 register offset:29 */ + /*phy debug port2 register offset:30 */ + + /*MALIBU interrupt flag */ +#define MALIBU_INTR_SPEED_CHANGE 0x4000 +#define MALIBU_INTR_DUPLEX_CHANGE 0x2000 +#define MALIBU_INTR_STATUS_UP_CHANGE 0x0400 +#define MALIBU_INTR_STATUS_DOWN_CHANGE 0x0800 +#define MALIBU_INTR_BX_FX_STATUS_DOWN_CHANGE 0x0100 +#define MALIBU_INTR_BX_FX_STATUS_UP_CHANGE 0x0080 +#define MALIBU_INTR_MEDIA_STATUS_CHANGE 0x1000 +#define MALIBU_INTR_WOL 0x0001 +#define MALIBU_INTR_POE 0x0002 + +#define RUN_CDT 0x8000 +#define CABLE_LENGTH_UNIT 0x0400 + +/** Phy preferred medium type */ + typedef enum + { + MALIBU_PHY_MEDIUM_COPPER = 0, + /**< Copper */ + MALIBU_PHY_MEDIUM_FIBER = 1, + /**< Fiber */ + + } malibu_phy_medium_t; + +/** Phy pages */ + typedef enum + { + MALIBU_PHY_SGBX_PAGES = 0, + /**< sgbx pages */ + MALIBU_PHY_COPPER_PAGES = 1 + /**< copper pages */ + } malibu_phy_reg_pages_t; +#ifndef IN_PORTCONTROL_MINI + sw_error_t + malibu_phy_set_powersave (a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t enable); + + sw_error_t + malibu_phy_get_powersave (a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t * enable); + + sw_error_t + malibu_phy_set_hibernate (a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t enable); + + sw_error_t + malibu_phy_get_hibernate (a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t * enable); + + sw_error_t + malibu_phy_cdt (a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t mdi_pair, + fal_cable_status_t * cable_status, + a_uint32_t * cable_len); +#endif + sw_error_t + malibu_phy_set_duplex (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_duplex_t duplex); + + sw_error_t + malibu_phy_get_duplex (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_duplex_t * duplex); + + sw_error_t + malibu_phy_set_speed (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_speed_t speed); + + sw_error_t + malibu_phy_get_speed (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_speed_t * speed); + + sw_error_t + malibu_phy_restart_autoneg (a_uint32_t dev_id, a_uint32_t phy_id); + + sw_error_t + malibu_phy_enable_autoneg (a_uint32_t dev_id, a_uint32_t phy_id); + + a_bool_t + malibu_phy_get_link_status (a_uint32_t dev_id, a_uint32_t phy_id); + + sw_error_t + malibu_phy_set_autoneg_adv (a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t autoneg); + + sw_error_t + malibu_phy_get_autoneg_adv (a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * autoneg); + + a_bool_t malibu_phy_autoneg_status (a_uint32_t dev_id, a_uint32_t phy_id); +#ifndef IN_PORTCONTROL_MINI + sw_error_t + malibu_phy_intr_mask_set (a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t intr_mask_flag); + + sw_error_t + malibu_phy_intr_mask_get (a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * intr_mask_flag); + + sw_error_t + malibu_phy_intr_status_get (a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * intr_status_flag); + + sw_error_t + malibu_phy_set_counter (a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t enable); + + sw_error_t + malibu_phy_get_counter (a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t * enable); + + sw_error_t + malibu_phy_show_counter (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_counter_info_t * counter_info); +#endif + sw_error_t + malibu_phy_get_8023az(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t * enable); +#ifndef IN_PORTCONTROL_MINI + sw_error_t + malibu_phy_set_8023az(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t enable); + + sw_error_t + malibu_phy_get_phy_id(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *phy_data); +#endif + int malibu_phy_init(a_uint32_t dev_id, a_uint32_t port_bmp); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _MALIBU_PHY_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/mpge_led.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/mpge_led.h new file mode 100644 index 000000000..81d4b5e2c --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/mpge_led.h @@ -0,0 +1,41 @@ +/* + * 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 _MPGE_LED_H_ +#define _MPGE_LED_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +sw_error_t +mpge_phy_led_ctrl_pattern_set(a_uint32_t dev_id, a_uint32_t phy_id, + led_ctrl_pattern_t *pattern); + +sw_error_t +mpge_phy_led_ctrl_pattern_get(a_uint32_t dev_id, a_uint32_t phy_id, + led_ctrl_pattern_t * pattern); + +sw_error_t +mpge_phy_led_ctrl_source_set(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t source_id, led_ctrl_pattern_t * pattern); + +void mpge_phy_led_api_ops_init(hsl_phy_ops_t *mpge_phy_led_api_ops); +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _MPGE_LED_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/mpge_phy.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/mpge_phy.h new file mode 100644 index 000000000..7c750721d --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/mpge_phy.h @@ -0,0 +1,95 @@ +/* + * 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 _MPGE_PHY_H_ +#define _MPGE_PHY_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ +/*MII register*/ +#define MPGE_PHY_CONTROL 0x0 +#define MPGE_PHY_FIFO_CONTROL 0x19 +#define MPGE_PHY_INTR_MASK 0x12 +#define MPGE_PHY_INTR_STATUS 0x13 + + /*MII register field*/ +#define MPGE_CTRL_AUTONEGOTIATION_ENABLE 0x1000 +#define MPGE_CTRL_RESTART_AUTONEGOTIATION 0x0200 +#define MPGE_CTRL_FULL_DUPLEX 0x0100 +#define MPGE_CONTROL_SPEED_MASK 0x2040 +#define MPGE_CONTROL_100M 0x2000 +#define MPGE_CONTROL_10M 0x0 +#define MPGE_PHY_FIFO_RESET 0x3 +#define MPGE_INTR_SPEED_CHANGE 0x4000 +#define MPGE_INTR_DUPLEX_CHANGE 0x2000 +#define MPGE_INTR_STATUS_LINK_DOWN 0x0800 +#define MPGE_INTR_STATUS_LINK_UP 0x0400 +#define MPGE_INTR_DOWNSHIF 0x0020 +#define MPGE_INTR_WOL 0x0001 +#define MPGE_INTR_FAST_LINK_DOWN_STAT_10M 0x40 +#define MPGE_INTR_FAST_LINK_DOWN_STAT_100M 0x200 +#define MPGE_INTR_FAST_LINK_DOWN_STAT_1000M 0x240 +#define MPGE_COMMON_CTRL 0x1040 +#define MPGE_10M_LOOPBACK 0x4100 +#define MPGE_100M_LOOPBACK 0x6100 +#define MPGE_1000M_LOOPBACK 0x4140 + +/*MMD1 register*/ +#define MPGE_PHY_MMD1_NUM 0x1 +#define MPGE_PHY_MMD1_MSE_THRESH1 0x1000 +#define MPGE_PHY_MMD1_MSE_THRESH2 0x1001 +#define MPGE_PHY_MMD1_DAC 0x8100 +/*MMD1 register field*/ +#define MPGE_PHY_MMD1_MSE_THRESH1_VAL 0xf1 +#define MPGE_PHY_MMD1_MSE_THRESH2_VAL 0x1f6 + +/*MMD3 register*/ +#define MPGE_PHY_MMD3_NUM 0x3 +#define MPGE_PHY_MMD3_AZ_CTRL1 0x8008 +#define MPGE_PHY_MMD3_AZ_CTRL2 0x8009 +#define MPGE_PHY_MMD3_CDT_THRESH_CTRL3 0x8074 +#define MPGE_PHY_MMD3_CDT_THRESH_CTRL4 0x8075 +#define MPGE_PHY_MMD3_CDT_THRESH_CTRL5 0x8076 +#define MPGE_PHY_MMD3_CDT_THRESH_CTRL6 0x8077 +#define MPGE_PHY_MMD3_CDT_THRESH_CTRL7 0x8078 +#define MPGE_PHY_MMD3_CDT_THRESH_CTRL9 0x807a +#define MPGE_PHY_MMD3_CDT_THRESH_CTRL13 0x807e +#define MPGE_PHY_MMD3_CDT_THRESH_CTRL14 0x807f + + /*MMD3 register field*/ +#define MPGE_PHY_MMD3_AZ_CTRL1_VAL 0x7880 +#define MPGE_PHY_MMD3_AZ_CTRL2_VAL 0xc8 +#define MPGE_PHY_MMD3_CDT_THRESH_CTRL3_VAL 0xc040 +#define MPGE_PHY_MMD3_CDT_THRESH_CTRL4_VAL 0xa060 +#define MPGE_PHY_MMD3_CDT_THRESH_CTRL5_VAL 0xc040 +#define MPGE_PHY_MMD3_CDT_THRESH_CTRL6_VAL 0xa060 +#define MPGE_PHY_MMD3_CDT_THRESH_CTRL7_VAL 0xc24c +#define MPGE_PHY_MMD3_CDT_THRESH_CTRL9_VAL 0xc060 +#define MPGE_PHY_MMD3_CDT_THRESH_CTRL13_VAL 0xb060 +#define MPGE_PHY_MMD3_NEAR_ECHO_THRESH_VAL 0x90b0 + +/*debug register*/ +#define MPGE_PHY_DEBUG_EDAC 0x4380 + +int mpge_phy_init(a_uint32_t dev_id, a_uint32_t port_bmp); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _MPGE_PHY_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/qca803x_phy.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/qca803x_phy.h new file mode 100755 index 000000000..33013cc7d --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/qca803x_phy.h @@ -0,0 +1,425 @@ +/* + * 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 _QCA803X_PHY_H_ +#define _QCA803X_PHY_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#define QCA803X_COMMON_CTRL 0x1040 +#define QCA803X_10M_LOOPBACK 0x4100 +#define QCA803X_100M_LOOPBACK 0x6100 +#define QCA803X_1000M_LOOPBACK 0x4140 + + /* PHY Registers */ +#define QCA803X_PHY_CONTROL 0 +#define QCA803X_PHY_STATUS 1 +#define QCA803X_PHY_SPEC_STATUS 17 + +#define QCA803X_PHY_ID1 2 +#define QCA803X_PHY_ID2 3 +#define QCA803X_AUTONEG_ADVERT 4 +#define QCA803X_LINK_PARTNER_ABILITY 5 +#define QCA803X_1000BASET_CONTROL 9 +#define QCA803X_1000BASET_STATUS 10 +#define QCA803X_MMD_CTRL_REG 13 +#define QCA803X_MMD_DATA_REG 14 +#define QCA803X_EXTENDED_STATUS 15 +#define QCA803X_PHY_SPEC_CONTROL 16 +#define QCA803X_PHY_INTR_MASK 18 +#define QCA803X_PHY_INTR_STATUS 19 +#define QCA803X_PHY_CDT_CONTROL 22 +#define QCA803X_PHY_CDT_STATUS 28 +#define QCA803X_DEBUG_PORT_ADDRESS 29 +#define QCA803X_DEBUG_PORT_DATA 30 +#define QCA803X_PHY_CHIP_CONFIG 31 /* Chip Configuration Register */ +#define QCA803X_DEBUG_MSE_THRESH 27 +#define QCA803X_DEBUG_MSE_OVER_THRESH_TIMES 28 + +#define QCA803X_PHY_MSE_THRESH_MASK 0x3f8 +#define QCA803X_PHY_MSE_THRESH_LINK_DOWN 0x170 +#define QCA803X_PHY_MSE_THRESH_LINK_UP 0x2e8 +#define QCA803X_PHY_MSE_OVER_THRESH_TIMES_MAX 0x7000 + +#define QCA803X_PHY_FIBER_MODE_1000BX 0x100 + +#define QCA803X_PHY_COPPER_PAGE_SEL 0x8000 +#define QCA803X_PHY_PREFER_FIBER 0x400 + +#define QCA803X_PHY_CHIP_MODE_CFG 0x000f +#define QCA803X_PHY_CHIP_MODE_STAT 0x00f0 + +#define QCA803X_DEBUG_PHY_HIBERNATION_CTRL 0xb +#define QCA803X_DEBUG_PHY_POWER_SAVING_CTRL 0x29 +#define QCA803X_PHY_MMD7_ADDR_8023AZ_EEE_CTRL 0x3c +#define QCA803X_PHY_MMD7_ADDR_8023AZ_EEE_PARTNER 0x3d +#define QCA803X_PHY_MMD7_ADDR_8023AZ_EEE_STATUS 0x8000 +#define QCA803X_PHY_MMD3_ADDR_8023AZ_EEE_CAPABILITY 0x14 + +#define QCA803X_PHY_MMD3_ADDR_REMOTE_LOOPBACK_CTRL 0x805a +#define QCA803X_PHY_MMD3_WOL_MAGIC_MAC_CTRL1 0x804a +#define QCA803X_PHY_MMD3_WOL_MAGIC_MAC_CTRL2 0x804b +#define QCA803X_PHY_MMD3_WOL_MAGIC_MAC_CTRL3 0x804c +#define QCA803X_PHY_MMD3_WOL_CTRL 0x8012 +#define QCA803X_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL 0x804e +#define QCA803X_PHY_MMD3_ADDR_8023AZ_CLD_CTRL 0x8007 +#define QCA803X_PHY_MMD3_ADDR_CLD_CTRL5 0x8005 +#define QCA803X_PHY_MMD3_ADDR_CLD_CTRL3 0x8003 + +#define QCA803X_PHY_MDIX 0x0020 +#define QCA803X_PHY_MDIX_AUTO 0x0060 +#define QCA803X_PHY_MDIX_STATUS 0x0040 + +#define QCA803X_PHY_MMD7_NUM 7 +#define QCA803X_PHY_MMD3_NUM 3 + +#define QCA803X_PWR_SAVE 0x29 +#define QCA803X_PWR_SAVE_EN 0x8000 + +#define QCA803X_PHY_EEE_ADV_100M 0x0002 +#define QCA803X_PHY_EEE_ADV_1000M 0x0004 +#define QCA803X_PHY_EEE_PARTNER_ADV_100M 0x0002 +#define QCA803X_PHY_EEE_PARTNER_ADV_1000M 0x0004 +#define QCA803X_PHY_EEE_CAPABILITY_100M 0x0002 +#define QCA803X_PHY_EEE_CAPABILITY_1000M 0x0004 +#define QCA803X_PHY_EEE_STATUS_100M 0x0002 +#define QCA803X_PHY_EEE_STATUS_1000M 0x0004 + + /* CDT */ +#define QCA803X_MDI_PAIR_NUM 4 +#define QCA803X_RUN_CDT 0x1 +#define CDT_PAIR_MASK 0x0300 + + /* PHY Registers Field */ +#define QCA803X_STATUS_LINK_PASS 0x0400 + + /* Control Register fields offset:0 */ + /* bits 6,13: 10=1000, 01=100, 00=10 */ +#define QCA803X_CTRL_SPEED_MSB 0x0040 + + /* Collision test enable */ +#define QCA803X_CTRL_COLL_TEST_ENABLE 0x0080 + + /* FDX =1, half duplex =0 */ +#define QCA803X_CTRL_FULL_DUPLEX 0x0100 + + /* Restart auto negotiation */ +#define QCA803X_CTRL_RESTART_AUTONEGOTIATION 0x0200 + + /* Power down */ +#define QCA803X_CTRL_POWER_DOWN 0x0800 + + /* Auto Neg Enable */ +#define QCA803X_CTRL_AUTONEGOTIATION_ENABLE 0x1000 + + /* Local Loopback Enable */ +#define QCA803X_LOCAL_LOOPBACK_ENABLE 0x4000 + + /* bits 6,13: 10=1000, 01=100, 00=10 */ +#define QCA803X_CTRL_SPEED_LSB 0x2000 + + /* 0 = normal, 1 = loopback */ +#define QCA803X_CTRL_LOOPBACK 0x4000 +#define QCA803X_CTRL_SOFTWARE_RESET 0x8000 + +#define QCA803X_CTRL_SPEED_MASK 0x2040 +#define QCA803X_CTRL_SPEED_1000 0x0040 +#define QCA803X_CTRL_SPEED_100 0x2000 +#define QCA803X_CTRL_SPEED_10 0x0000 + +#define QCA803X_RESET_DONE(phy_control) \ + (((phy_control) & (QCA803X_CTRL_SOFTWARE_RESET)) == 0) + + /* Status Register fields offset:1 */ +#define QCA803X_STATUS_EXTENDED_CAPS 0x0001 + + /* Jabber Detected */ +#define QCA803X_STATUS_JABBER_DETECT 0x0002 + + /* Link Status 1 = link */ +#define QCA803X_STATUS_LINK_STATUS_UP 0x0004 + + /* Auto Neg Capable */ +#define QCA803X_STATUS_AUTONEG_CAPS 0x0008 + + /* Remote Fault Detect */ +#define QCA803X_STATUS_REMOTE_FAULT 0x0010 + + /* Auto Neg Complete */ +#define QCA803X_STATUS_AUTO_NEG_DONE 0x0020 + + /* Preamble may be suppressed */ +#define QCA803X_STATUS_PREAMBLE_SUPPRESS 0x0040 + + /* Ext. status info in Reg 0x0F */ +#define QCA803X_STATUS_EXTENDED_STATUS 0x0100 + + /* 100T2 Half Duplex Capable */ +#define QCA803X_STATUS_100T2_HD_CAPS 0x0200 + + /* 100T2 Full Duplex Capable */ +#define QCA803X_STATUS_100T2_FD_CAPS 0x0400 + + /* 10T Half Duplex Capable */ +#define QCA803X_STATUS_10T_HD_CAPS 0x0800 + + /* 10T Full Duplex Capable */ +#define QCA803X_STATUS_10T_FD_CAPS 0x1000 + + /* 100X Half Duplex Capable */ +#define QCA803X_STATUS_100X_HD_CAPS 0x2000 + + /* 100X Full Duplex Capable */ +#define QCA803X_STATUS_100X_FD_CAPS 0x4000 + + /* 100T4 Capable */ +#define QCA803X_STATUS_100T4_CAPS 0x8000 + + /* extended status register capabilities */ + +#define QCA803X_STATUS_1000T_HD_CAPS 0x1000 + +#define QCA803X_STATUS_1000T_FD_CAPS 0x2000 + +#define QCA803X_STATUS_1000X_HD_CAPS 0x4000 + +#define QCA803X_STATUS_1000X_FD_CAPS 0x8000 + + /* Link Partner ability offset:5 */ +#define QCA803X_LINK_SLCT 0x001f + + /* Can do 10mbps half-duplex */ +#define QCA803X_LINK_10BASETX_HALF_DUPLEX 0x0020 + + /* Can do 10mbps full-duplex */ +#define QCA803X_LINK_10BASETX_FULL_DUPLEX 0x0040 + + /* Can do 100mbps half-duplex */ +#define QCA803X_LINK_100BASETX_HALF_DUPLEX 0x0080 + + /* Can do 100mbps full-duplex */ +#define QCA803X_LINK_100BASETX_FULL_DUPLEX 0x0100 + + /* Can do 1000mbps full-duplex */ +#define QCA803X_LINK_1000BASETX_FULL_DUPLEX 0x0800 + + /* Can do 1000mbps half-duplex */ +#define QCA803X_LINK_1000BASETX_HALF_DUPLEX 0x0400 + + /* 100BASE-T4 */ +#define QCA803X_LINK_100BASE4 0x0200 + + /* PAUSE */ +#define QCA803X_LINK_PAUSE 0x0400 + + /* Asymmetrical PAUSE */ +#define QCA803X_LINK_ASYPAUSE 0x0800 + + /* Link partner faulted */ +#define QCA803X_LINK_RFAULT 0x2000 + + /* Link partner acked us */ +#define QCA803X_LINK_LPACK 0x4000 + + /* Next page bit */ +#define QCA803X_LINK_NPAGE 0x8000 + + /* Auto Neg Complete */ +#define QCA803X_STATUS_AUTO_NEG_DONE 0x0020 +#define QCA803X_AUTONEG_DONE(ip_phy_status) \ + (((ip_phy_status) & (QCA803X_STATUS_AUTO_NEG_DONE)) == \ + (QCA803X_STATUS_AUTO_NEG_DONE)) + +#define QCA803X_STATUS_RESOVLED 0x0800 +#define QCA803X_SPEED_DUPLEX_RESOVLED(phy_status) \ + (((phy_status) & \ + (QCA803X_STATUS_RESOVLED)) == \ + (QCA803X_STATUS_RESOVLED)) + + /* Auto-Negotiation Advertisement register. offset:4 */ +#define QCA803X_ADVERTISE_SELECTOR_FIELD 0x0001 + + /* 10T Half Duplex Capable */ +#define QCA803X_ADVERTISE_10HALF 0x0020 + + /* 10T Full Duplex Capable */ +#define QCA803X_ADVERTISE_10FULL 0x0040 + + /* 100TX Half Duplex Capable */ +#define QCA803X_ADVERTISE_100HALF 0x0080 + + /* 100TX Full Duplex Capable */ +#define QCA803X_ADVERTISE_100FULL 0x0100 + + /* 100T4 Capable */ +#define QCA803X_ADVERTISE_100T4 0x0200 + + /* Pause operation desired */ +#define QCA803X_ADVERTISE_PAUSE 0x0400 + + /* Asymmetric Pause Direction bit */ +#define QCA803X_ADVERTISE_ASYM_PAUSE 0x0800 + + /* Remote Fault detected */ +#define QCA803X_ADVERTISE_REMOTE_FAULT 0x2000 + + /* 100TX Half Duplex Capable */ +#define QCA803X_ADVERTISE_1000HALF 0x0100 + + /* 100TX Full Duplex Capable */ +#define QCA803X_ADVERTISE_1000FULL 0x0200 + + /* Extended next page enable control */ +#define QCA803X_EXTENDED_NEXT_PAGE_EN 0x1000 + +#define QCA803X_ADVERTISE_ALL \ + (QCA803X_ADVERTISE_10HALF | QCA803X_ADVERTISE_10FULL | \ + QCA803X_ADVERTISE_100HALF | QCA803X_ADVERTISE_100FULL | \ + QCA803X_ADVERTISE_1000FULL) + +#define QCA803X_ADVERTISE_MEGA_ALL \ + (QCA803X_ADVERTISE_10HALF | QCA803X_ADVERTISE_10FULL | \ + QCA803X_ADVERTISE_100HALF | QCA803X_ADVERTISE_100FULL | \ + QCA803X_ADVERTISE_PAUSE | QCA803X_ADVERTISE_ASYM_PAUSE) + +#define QCA803X_BX_ADVERTISE_1000FULL 0x0020 +#define QCA803X_BX_ADVERTISE_1000HALF 0x0040 +#define QCA803X_BX_ADVERTISE_PAUSE 0x0080 +#define QCA803X_BX_ADVERTISE_ASYM_PAUSE 0x0100 + +#define QCA803X_BX_ADVERTISE_ALL \ + (QCA803X_BX_ADVERTISE_ASYM_PAUSE | QCA803X_BX_ADVERTISE_PAUSE | \ + QCA803X_BX_ADVERTISE_1000HALF | QCA803X_BX_ADVERTISE_1000FULL) + + /* 1=Duplex 0=Half Duplex */ +#define QCA803X_STATUS_FULL_DUPLEX 0x2000 + + /* Speed, bits 14:15 */ +#define QCA803X_STATUS_SPEED 0xC000 +#define QCA803X_STATUS_SPEED_MASK 0xC000 + + /* 00=10Mbs */ +#define QCA803X_STATUS_SPEED_10MBS 0x0000 + + /* 01=100Mbs */ +#define QCA803X_STATUS_SPEED_100MBS 0x4000 + + /* 10=1000Mbs */ +#define QCA803X_STATUS_SPEED_1000MBS 0x8000 + + /*pause status */ +#define QCA803X_PHY_RX_FLOWCTRL_STATUS 0x4 +#define QCA803X_PHY_TX_FLOWCTRL_STATUS 0x8 + + /*QCA803X interrupt flag */ +#define QCA803X_INTR_SPEED_CHANGE 0x4000 +#define QCA803X_INTR_DUPLEX_CHANGE 0x2000 +#define QCA803X_INTR_STATUS_UP_CHANGE 0x0400 +#define QCA803X_INTR_STATUS_DOWN_CHANGE 0x0800 +#define QCA803X_INTR_BX_FX_STATUS_DOWN_CHANGE 0x0100 +#define QCA803X_INTR_BX_FX_STATUS_UP_CHANGE 0x0080 +#define QCA803X_INTR_MEDIA_STATUS_CHANGE 0x1000 +#define QCA803X_INTR_WOL 0x0001 +#define QCA803X_INTR_POE 0x0002 + +/*QCA803X phy counter*/ +#define QCA803X_PHY_MMD7_FRAME_CTRL 0x8020 +#define QCA803X_PHY_MMD7_FRAME_DATA 0x8021 + +#define QCA803X_PHY_MMD7_FRAME_CHECK 0x2000 +#define QCA803X_PHY_MMD7_FRAME_DIR 0x4000 +#define QCA803X_PHY_FRAME_CNT 0x00FF +#define QCA803X_PHY_FRAME_ERROR 0xFF00 + + /** phy chip config */ + typedef enum { + QCA803X_PHY_RGMII_BASET = 0, + QCA803X_PHY_SGMII_BASET = 1, + QCA803X_PHY_BX1000_RGMII_50 = 2, + QCA803X_PHY_FX100_RGMII_50 = 6, + QCA803X_PHY_RGMII_AMDET = 11 + } qca803x_cfg_t; + + typedef enum { + QCA803X_CHIP_CFG_SET, + QCA803X_CHIP_CFG_STAT + } qca803x_cfg_type_t; + +/** Phy preferred medium type */ + typedef enum + { + QCA803X_PHY_MEDIUM_COPPER = 0, /* Copper */ + QCA803X_PHY_MEDIUM_FIBER = 1, /* Fiber */ + QCA803X_PHY_MEDIUM_MAX + } qca803x_phy_medium_t; + +sw_error_t +qca803x_phy_set_duplex (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_duplex_t duplex); + +sw_error_t +qca803x_phy_get_duplex (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_duplex_t * duplex); + +sw_error_t +qca803x_phy_set_speed (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_speed_t speed); + +sw_error_t +qca803x_phy_get_speed (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_speed_t * speed); + +sw_error_t +qca803x_phy_restart_autoneg (a_uint32_t dev_id, a_uint32_t phy_id); + +sw_error_t +qca803x_phy_enable_autoneg (a_uint32_t dev_id, a_uint32_t phy_id); + +a_bool_t +qca803x_phy_get_link_status (a_uint32_t dev_id, a_uint32_t phy_id); + +sw_error_t +qca803x_phy_set_autoneg_adv (a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t autoneg); + +sw_error_t +qca803x_phy_get_autoneg_adv (a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * autoneg); + +a_bool_t qca803x_phy_autoneg_status (a_uint32_t dev_id, a_uint32_t phy_id); +#ifndef IN_PORTCONTROL_MINI +sw_error_t +qca803x_phy_intr_mask_set (a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t intr_mask_flag); + +sw_error_t +qca803x_phy_intr_mask_get (a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * intr_mask_flag); + +sw_error_t +qca803x_phy_intr_status_get (a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * intr_status_flag); +#endif +sw_error_t +qca803x_phy_get_phy_id(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *phy_data); +int qca803x_phy_init(a_uint32_t dev_id, a_uint32_t port_bmp); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _qca803x_PHY_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/qca808x.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/qca808x.h new file mode 100755 index 000000000..12fb3f4d9 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/qca808x.h @@ -0,0 +1,135 @@ +/* + * 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 +#include +#include +#include + +#include "hsl.h" +#include "ssdk_plat.h" +#include "hsl_phy.h" +#include "qca808x_phy.h" + +#if defined(IN_LINUX_STD_PTP) +#include +enum { + PTP_PKT_SEQID_UNMATCHED, + PTP_PKT_SEQID_MATCHED, + PTP_PKT_SEQID_MATCH_MAX +}; + +enum { + QCA808X_PTP_MSG_SYNC, + QCA808X_PTP_MSG_DREQ, + QCA808X_PTP_MSG_PREQ, + QCA808X_PTP_MSG_PRESP, + QCA808X_PTP_MSG_MAX +}; + +typedef struct { + /* ptp filter class */ + a_int32_t ptp_type; + /* ptp frame type */ + a_int32_t pkt_type; +} qca808x_ptp_cb; + +/* statistics for the event packet*/ +typedef struct { + /* the counter saves the packet with sequence id + * matched and unmatched */ + a_uint64_t sync_cnt[PTP_PKT_SEQID_MATCH_MAX]; + a_uint64_t delay_req_cnt[PTP_PKT_SEQID_MATCH_MAX]; + a_uint64_t pdelay_req_cnt[PTP_PKT_SEQID_MATCH_MAX]; + a_uint64_t pdelay_resp_cnt[PTP_PKT_SEQID_MATCH_MAX]; + a_uint64_t event_pkt_cnt; +} ptp_packet_stat; + +typedef struct { + a_uint8_t reserved0; + a_uint8_t reserved1; + a_uint8_t msg_type; + a_uint16_t seqid; + a_uint32_t reserved2; + a_int64_t correction; +} qca808x_embeded_ts; + +struct qca808x_ptp_info { + a_int32_t hwts_tx_type; + a_int32_t hwts_rx_type; + struct qca808x_ptp_clock *clock; + struct delayed_work tx_ts_work; + struct delayed_work rx_ts_work; + /* work for writing ingress time to register */ + struct delayed_work ingress_trig_work; + a_int32_t ingress_time; + struct sk_buff_head tx_queue; + struct sk_buff_head rx_queue; + qca808x_embeded_ts embeded_ts; +}; +#endif + +struct qca808x_phy_info { + struct list_head list; + a_uint32_t dev_id; + /* phy real address,it is the mdio addr or the i2c slave addr */ + a_uint32_t phy_addr; + /* the address of phy device, it is a fake addr for the i2c accessed phy */ + a_uint32_t phydev_addr; +#if defined(IN_LINUX_STD_PTP) + a_int32_t speed; + a_uint16_t clock_mode; + a_uint16_t step_mode; + /* work for gps sencond sync */ + struct delayed_work ts_schedule_work; + a_bool_t gps_seconds_sync_en; + /*the statistics array records the counter of + * rx and tx ptp event packet */ + ptp_packet_stat pkt_stat[2]; +#endif +}; + +typedef struct { + struct phy_device *phydev; + struct qca808x_phy_info *phy_info; +#if defined(IN_LINUX_STD_PTP) + struct qca808x_ptp_info ptp_info; +#endif +} qca808x_priv; + +#if defined(IN_LINUX_STD_PTP) +struct qca808x_ptp_clock{ + struct ptp_clock_info caps; + struct ptp_clock *ptp_clock; + struct mutex tsreg_lock; + qca808x_priv *priv; +}; + +struct qca808x_phy_info* qca808x_phy_info_get(a_uint32_t phy_addr); +void qca808x_ptp_change_notify(struct phy_device *phydev); +int qca808x_hwtstamp(struct phy_device *phydev, struct ifreq *ifr); +bool qca808x_rxtstamp(struct phy_device *phydev, struct sk_buff *skb, int type); +void qca808x_txtstamp(struct phy_device *phydev, struct sk_buff *skb, int type); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) +int qca808x_ts_info(struct phy_device *phydev, struct ethtool_ts_info *info); +#endif +sw_error_t qca808x_ptp_config_init(struct phy_device *phydev); +int qca808x_ptp_init(qca808x_priv *priv); +void qca808x_ptp_deinit(qca808x_priv *priv); +#endif + +void qca808x_phydev_init(a_uint32_t dev_id, a_uint32_t port_id); +void qca808x_phydev_deinit(a_uint32_t dev_id, a_uint32_t port_id); +a_int32_t qca808x_phy_driver_register(void); +void qca808x_phy_driver_unregister(void); diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/qca808x_led.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/qca808x_led.h new file mode 100644 index 000000000..8991b09d4 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/qca808x_led.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. + */ + +#ifndef _QCA808X_LED_H_ +#define _QCA808X_LED_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ +#define QCA808X_PHY_MMD7_LED_POLARITY_MASK 0x40 +#define QCA808X_PHY_LINK_2500M_LIGHT_EN 0x8000 +#define QCA808X_PHY_LINK_1000M_LIGHT_EN 0x40 +#define QCA808X_PHY_LINK_100M_LIGHT_EN 0x20 +#define QCA808X_PHY_LINK_10M_LIGHT_EN 0x10 +#define QCA808X_PHY_RX_TRAFFIC_BLINK_EN 0x200 +#define QCA808X_PHY_TX_TRAFFIC_BLINK_EN 0x400 + +#define QCA808X_PHY_LED_SOURCE0 0x0 +#define QCA808X_PHY_LED_SOURCE1 0x1 +#define QCA808X_PHY_LED_SOURCE2 0x2 + +sw_error_t +qca808x_phy_led_ctrl_pattern_set(a_uint32_t dev_id, a_uint32_t phy_id, + led_ctrl_pattern_t *pattern); +sw_error_t +qca808x_phy_led_ctrl_pattern_get(a_uint32_t dev_id, a_uint32_t phy_id, + led_ctrl_pattern_t *pattern); +sw_error_t +qca808x_phy_led_ctrl_source_set(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t source_id, led_ctrl_pattern_t *pattern); +sw_error_t +qca808x_phy_led_ctrl_source_get(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t source_id, led_ctrl_pattern_t *pattern); +void qca808x_phy_led_api_ops_init(hsl_phy_ops_t *qca808x_phy_led_api_ops); +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _qca808x_LED_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/qca808x_phy.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/qca808x_phy.h new file mode 100644 index 000000000..41c5f66e5 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/qca808x_phy.h @@ -0,0 +1,630 @@ +/* + * 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 _QCA808X_PHY_H_ +#define _QCA808X_PHY_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#define QCA808X_MII_ADDR_C45 (1<<30) +#define QCA808X_REG_C45_ADDRESS(dev_type, reg_num) (QCA808X_MII_ADDR_C45 | \ + ((dev_type & 0x1f) << 16) | (reg_num & 0xffff)) + +#define QCA808X_COMMON_CTRL 0x1040 + +#define QCA808X_PHY_MMD1_PMA_CONTROL 0x0 +#define QCA808X_PMA_CONTROL_SPEED_MASK 0x2040 +#define QCA808X_PMA_CONTROL_2500M 0x2040 +#define QCA808X_PMA_CONTROL_1000M 0x40 +#define QCA808X_PMA_CONTROL_100M 0x2000 +#define QCA808X_PMA_CONTROL_10M 0x0 + +#define QCA808X_PHY_MMD1_PMA_TYPE 0x7 +#define QCA808X_PMA_TYPE_MASK 0x3f +#define QCA808X_PMA_TYPE_2500M 0x30 +#define QCA808X_PMA_TYPE_1000M 0xc +#define QCA808X_PMA_TYPE_100M 0xe +#define QCA808X_PMA_TYPE_10M 0xf + + /* PHY Registers */ +#define QCA808X_PHY_CONTROL 0 +#define QCA808X_PHY_STATUS 1 +#define QCA808X_PHY_SPEC_STATUS 17 + +#define QCA808X_PHY_ID1 2 +#define QCA808X_PHY_ID2 3 +#define QCA808X_AUTONEG_ADVERT 4 +#define QCA808X_LINK_PARTNER_ABILITY 5 +#define QCA808X_1000BASET_CONTROL 9 +#define QCA808X_1000BASET_STATUS 10 +#define QCA808X_MMD_CTRL_REG 13 +#define QCA808X_MMD_DATA_REG 14 +#define QCA808X_EXTENDED_STATUS 15 +#define QCA808X_PHY_SPEC_CONTROL 16 +#define QCA808X_PHY_INTR_MASK 18 +#define QCA808X_PHY_INTR_STATUS 19 +#define QCA808X_PHY_CDT_CONTROL 22 +#define QCA808X_DEBUG_PORT_ADDRESS 29 +#define QCA808X_DEBUG_PORT_DATA 30 +#define QCA808X_DEBUG_LOCAL_SEED 9 + +/* Chip Configuration Register */ +#define QCA808X_PHY_CHIP_CONFIG 31 + +#define QCA808X_PHY_MODE_MASK 0x6000 +#define QCA808X_PHY_SGMII_MODE 0x0000 +#define QCA808X_PHY_SGMII_PLUS_MODE 0x2000 +#define QCA808X_PHY_SGMII_BASET 0x4 +#define QCA808X_PHY_CHIP_MODE_CFG 0xf + +#define QCA808X_DEBUG_PHY_HIBERNATION_CTRL 0xb +#define QCA808X_DEBUG_PHY_HIBERNATION_STAT 0xc +#define QCA808X_DEBUG_PHY_POWER_SAVING_CTRL 0x29 +#define QCA808X_PHY_MMD7_ADDR_8023AZ_EEE_CTRL 0x3c +#define QCA808X_PHY_MMD7_ADDR_8023AZ_EEE_PARTNER 0x3d +#define QCA808X_PHY_MMD7_ADDR_8023AZ_EEE_STATUS 0x8000 +#define QCA808X_PHY_MMD3_ADDR_8023AZ_EEE_CAPABILITY 0x14 +#define QCA808X_PHY_MMD7_ADDR_EEE_LP_ADVERTISEMENT 0x40 + +#define QCA808X_PHY_MMD3_ADDR_8023AZ_EEE_DB 0x800f +#define QCA808X_PHY_8023AZ_EEE_LP_STAT 0x2000 +#define QCA808X_PHY_MMD3_ADDR_REMOTE_LOOPBACK_CTRL 0x805a +#define QCA808X_PHY_MMD3_WOL_MAGIC_MAC_CTRL1 0x804a +#define QCA808X_PHY_MMD3_WOL_MAGIC_MAC_CTRL2 0x804b +#define QCA808X_PHY_MMD3_WOL_MAGIC_MAC_CTRL3 0x804c +#define QCA808X_PHY_MMD3_WOL_CTRL 0x8012 +#define QCA808X_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL 0x804e +#define QCA808X_PHY_MMD3_ADDR_CLD_CTRL7 0x8007 +#define QCA808X_PHY_MMD3_ADDR_CLD_CTRL5 0x8005 +#define QCA808X_PHY_MMD3_ADDR_CLD_CTRL3 0x8003 +#define QCA808X_PHY_MMD3_AZ_TRAINING_CTRL 0x8008 + +#define QCA808X_PHY_HIBERNATION_CFG 0x8000 +#define QCA808X_PHY_HIBERNATION_STAT_EN 0x0800 + +#define QCA808X_PHY_WOL_EN 0x0020 + +#define QCA808X_PHY_REMOTE_LOOPBACK_EN 0x0001 + +#define QCA808X_PHY_8023AZ_EEE_1000BT 0x0004 +#define QCA808X_PHY_8023AZ_EEE_100BT 0x0002 +#define QCA808X_PHY_MMD3_AZ_TRAINING_VAL 0x1c32 + +#define QCA808X_PHY_MDIX 0x0020 +#define QCA808X_PHY_MDIX_AUTO 0x0060 +#define QCA808X_PHY_MDIX_STATUS 0x0040 + +#define QCA808X_PHY_MMD7_NUM 7 +#define QCA808X_PHY_MMD3_NUM 3 +#define QCA808X_PHY_MMD1_NUM 1 + +#define QCA808X_PHY_MMD1_FAST_RETRAIN_STATUS_CTL 0x93 +#define QCA808X_PHY_MMD1_MSE_THRESHOLD_20DB 0x8014 +#define QCA808X_PHY_MMD1_MSE_THRESHOLD_17DB 0x800E +#define QCA808X_PHY_MMD1_MSE_THRESHOLD_27DB 0x801E +#define QCA808X_PHY_MMD1_MSE_THRESHOLD_28DB 0x8020 +#define QCA808X_PHY_MMD7_TOP_OPTION1 0x901c +#define QCA808X_PHY_EEE_ADV_100M 0x0002 +#define QCA808X_PHY_EEE_ADV_1000M 0x0004 +#define QCA808X_PHY_EEE_PARTNER_ADV_100M 0x0002 +#define QCA808X_PHY_EEE_PARTNER_ADV_1000M 0x0004 +#define QCA808X_PHY_EEE_CAPABILITY_100M 0x0002 +#define QCA808X_PHY_EEE_CAPABILITY_1000M 0x0004 +#define QCA808X_PHY_EEE_STATUS_100M 0x0002 +#define QCA808X_PHY_EEE_STATUS_1000M 0x0004 + +#define QCA808X_PHY_FAST_RETRAIN_CTRL 0x1 +#define QCA808X_PHY_MSE_THRESHOLD_20DB_VALUE 0x529 +#define QCA808X_PHY_MSE_THRESHOLD_17DB_VALUE 0x341 +#define QCA808X_PHY_MSE_THRESHOLD_27DB_VALUE 0x419 +#define QCA808X_PHY_MSE_THRESHOLD_28DB_VALUE 0x341 +#define QCA808X_PHY_FAST_RETRAIN_2500BT 0x20 +#define QCA808X_PHY_ADV_LOOP_TIMING 0x1 +#define QCA808X_PHY_EEE_ADV_THP 0x8 +#define QCA808X_PHY_TOP_OPTION1_DATA 0x0 + + /* CDT */ +#define QCA808X_MDI_PAIR_NUM 4 +#define QCA808X_RUN_CDT 0x8000 +#define QCA808X_CABLE_LENGTH_UNIT 0x0400 +#define QCA808X_PHY_CDT_STATUS 0X8064 +#define QCA808X_PHY_CDT_DIAG_PAIR0 0X8065 +#define QCA808X_PHY_CDT_DIAG_PAIR1 0X8066 +#define QCA808X_PHY_CDT_DIAG_PAIR2 0X8067 +#define QCA808X_PHY_CDT_DIAG_PAIR3 0X8068 + + /* SYNCE CLOCK OUTPUT */ +#define QCA808X_DEBUG_ANA_CLOCK_CTRL_REG 0x3e80 +#define QCA808X_ANALOG_PHY_SYNCE_CLOCK_EN 0x20 + +#define QCA808X_MMD7_CLOCK_CTRL_REG 0x8072 +#define QCA808X_DIGITAL_PHY_SYNCE_CLOCK_EN 0x1 + + /* PHY Registers Field */ +#define QCA808X_STATUS_LINK_PASS 0x0400 + + /* Control Register fields offset:0 */ + /* bits 6,13: 10=1000, 01=100, 00=10 */ +#define QCA808X_CTRL_SPEED_MSB 0x0040 + + /* Collision test enable */ +#define QCA808X_CTRL_COLL_TEST_ENABLE 0x0080 +/* FDX =1, half duplex =0 */ +#define QCA808X_CTRL_FULL_DUPLEX 0x0100 + + /* Restart auto negotiation */ +#define QCA808X_CTRL_RESTART_AUTONEGOTIATION 0x0200 + + /* Power down */ +#define QCA808X_CTRL_POWER_DOWN 0x0800 + + /* Auto Neg Enable */ +#define QCA808X_CTRL_AUTONEGOTIATION_ENABLE 0x1000 + + /* Local Loopback Enable */ +#define QCA808X_LOCAL_LOOPBACK_ENABLE 0x4000 + + /* bits 6,13: 10=1000, 01=100, 00=10 */ +#define QCA808X_CTRL_SPEED_LSB 0x2000 + + /* 0 = normal, 1 = loopback */ +#define QCA808X_CTRL_LOOPBACK 0x4000 +#define QCA808X_CTRL_SOFTWARE_RESET 0x8000 + +#define QCA808X_PHY_MMD7_AUTONEGOTIATION_CONTROL 0x20 + +#define QCA808X_CTRL_SPEED_MASK 0x2040 +#define QCA808X_CTRL_SPEED_1000 0x0040 +#define QCA808X_CTRL_SPEED_100 0x2000 +#define QCA808X_CTRL_SPEED_10 0x0000 + +#define QCA808X_MASTER_SLAVE_SEED_ENABLE 0x2 +#define QCA808X_MASTER_SLAVE_SEED_CFG 0x1FFC +#define QCA808X_MASTER_SLAVE_SEED_RANGE 0x32 +#define QCA808X_MASTER_SLAVE_CONFIG_FAULT 0x8000 + +#define QCA808X_RESET_DONE(phy_control) \ + (((phy_control) & (QCA808X_CTRL_SOFTWARE_RESET)) == 0) + + /* Status Register fields offset:1 */ +#define QCA808X_STATUS_EXTENDED_CAPS 0x0001 + + /* Jabber Detected */ +#define QCA808X_STATUS_JABBER_DETECT 0x0002 + + /* Link Status 1 = link */ +#define QCA808X_STATUS_LINK_STATUS_UP 0x0004 + + /* Auto Neg Capable */ +#define QCA808X_STATUS_AUTONEG_CAPS 0x0008 + + /* Remote Fault Detect */ +#define QCA808X_STATUS_REMOTE_FAULT 0x0010 + + /* Auto Neg Complete */ +#define QCA808X_STATUS_AUTO_NEG_DONE 0x0020 + + /* Preamble may be suppressed */ +#define QCA808X_STATUS_PREAMBLE_SUPPRESS 0x0040 + + /* Ext. status info in Reg 0x0F */ +#define QCA808X_STATUS_EXTENDED_STATUS 0x0100 + + /* 100T2 Half Duplex Capable */ +#define QCA808X_STATUS_100T2_HD_CAPS 0x0200 + + /* 100T2 Full Duplex Capable */ +#define QCA808X_STATUS_100T2_FD_CAPS 0x0400 + + /* 10T Half Duplex Capable */ +#define QCA808X_STATUS_10T_HD_CAPS 0x0800 + + /* 10T Full Duplex Capable */ +#define QCA808X_STATUS_10T_FD_CAPS 0x1000 + + /* 100TX Half Duplex Capable */ +#define QCA808X_STATUS_100TX_HD_CAPS 0x2000 + + /* 100TX Full Duplex Capable */ +#define QCA808X_STATUS_100TX_FD_CAPS 0x4000 + + /* 100T4 Capable */ +#define QCA808X_STATUS_100T4_CAPS 0x8000 + + /* extended status register capabilities */ + +#define QCA808X_STATUS_1000T_HD_CAPS 0x1000 + +#define QCA808X_STATUS_1000T_FD_CAPS 0x2000 + +#define QCA808X_STATUS_1000X_HD_CAPS 0x4000 + +#define QCA808X_STATUS_1000X_FD_CAPS 0x8000 + +#define QCA808X_MMD1_PMA_CAP_REG 0x4 + /* MMD1 2500T capabilities */ +#define QCA808X_STATUS_2500T_FD_CAPS 0x2000 + + /* Link Partner ability offset:5 */ +#define QCA808X_LINK_SLCT 0x001f + + /* Can do 10mbps half-duplex */ +#define QCA808X_LINK_10BASETX_HALF_DUPLEX 0x0020 + + /* Can do 10mbps full-duplex */ +#define QCA808X_LINK_10BASETX_FULL_DUPLEX 0x0040 + + /* Can do 100mbps half-duplex */ +#define QCA808X_LINK_100BASETX_HALF_DUPLEX 0x0080 + + /* Can do 100mbps full-duplex */ +#define QCA808X_LINK_100BASETX_FULL_DUPLEX 0x0100 + + /* Can do 1000mbps full-duplex */ +#define QCA808X_LINK_1000BASETX_FULL_DUPLEX 0x0800 + + /* Can do 1000mbps half-duplex */ +#define QCA808X_LINK_1000BASETX_HALF_DUPLEX 0x0400 + + /* Can do 2500mbps full-duplex */ +#define QCA808X_LINK_2500BASETX_FULL_DUPLEX 0x0020 + + /* 100BASE-T4 */ +#define QCA808X_LINK_100BASE4 0x0200 + + /* PAUSE */ +#define QCA808X_LINK_PAUSE 0x0400 + + /* Asymmetrical PAUSE */ +#define QCA808X_LINK_ASYPAUSE 0x0800 + + /* Link partner faulted */ +#define QCA808X_LINK_RFAULT 0x2000 + + /* Link partner acked us */ +#define QCA808X_LINK_LPACK 0x4000 + + /* Next page bit */ +#define QCA808X_LINK_NPAGE 0x8000 + + /* Auto Neg Complete */ +#define QCA808X_STATUS_AUTO_NEG_DONE 0x0020 +#define QCA808X_AUTONEG_DONE(ip_phy_status) \ + (((ip_phy_status) & (QCA808X_STATUS_AUTO_NEG_DONE)) == \ + (QCA808X_STATUS_AUTO_NEG_DONE)) + +#define QCA808X_STATUS_RESOVLED 0x0800 +#define QCA808X_SPEED_DUPLEX_RESOVLED(phy_status) \ + (((phy_status) & \ + (QCA808X_STATUS_RESOVLED)) == \ + (QCA808X_STATUS_RESOVLED)) + + /* Auto-Negotiation Advertisement register. offset:4 */ +#define QCA808X_ADVERTISE_SELECTOR_FIELD 0x0001 + + /* 10T Half Duplex Capable */ +#define QCA808X_ADVERTISE_10HALF 0x0020 + + /* 10T Full Duplex Capable */ +#define QCA808X_ADVERTISE_10FULL 0x0040 + + /* 100TX Half Duplex Capable */ +#define QCA808X_ADVERTISE_100HALF 0x0080 + + /* 100TX Full Duplex Capable */ +#define QCA808X_ADVERTISE_100FULL 0x0100 + + /* 100T4 Capable */ +#define QCA808X_ADVERTISE_100T4 0x0200 + + /* Pause operation desired */ +#define QCA808X_ADVERTISE_PAUSE 0x0400 + + /* Asymmetric Pause Direction bit */ +#define QCA808X_ADVERTISE_ASYM_PAUSE 0x0800 + + /* Remote Fault detected */ +#define QCA808X_ADVERTISE_REMOTE_FAULT 0x2000 + + /* 1000TX Half Duplex Capable */ +#define QCA808X_ADVERTISE_1000HALF 0x0100 + + /* 1000TX Full Duplex Capable */ +#define QCA808X_ADVERTISE_1000FULL 0x0200 + + /* 2500TX Full Duplex Capable */ +#define QCA808X_ADVERTISE_2500FULL 0x80 + +#define QCA808X_ADVERTISE_ALL \ + (QCA808X_ADVERTISE_10HALF | QCA808X_ADVERTISE_10FULL | \ + QCA808X_ADVERTISE_100HALF | QCA808X_ADVERTISE_100FULL | \ + QCA808X_ADVERTISE_1000FULL) + +#define QCA808X_ADVERTISE_MEGA_ALL \ + (QCA808X_ADVERTISE_10HALF | QCA808X_ADVERTISE_10FULL | \ + QCA808X_ADVERTISE_100HALF | QCA808X_ADVERTISE_100FULL | \ + QCA808X_ADVERTISE_PAUSE | QCA808X_ADVERTISE_ASYM_PAUSE) + +#define QCA808X_BX_ADVERTISE_1000FULL 0x0020 +#define QCA808X_BX_ADVERTISE_1000HALF 0x0040 +#define QCA808X_BX_ADVERTISE_PAUSE 0x0080 +#define QCA808X_BX_ADVERTISE_ASYM_PAUSE 0x0100 + +#define QCA808X_BX_ADVERTISE_ALL \ + (QCA808X_BX_ADVERTISE_ASYM_PAUSE | QCA808X_BX_ADVERTISE_PAUSE | \ + QCA808X_BX_ADVERTISE_1000HALF | QCA808X_BX_ADVERTISE_1000FULL) + + /* 1=Duplex 0=Half Duplex */ +#define QCA808X_STATUS_FULL_DUPLEX 0x2000 +#define QCA808X_PHY_RX_FLOWCTRL_STATUS 0x4 +#define QCA808X_PHY_TX_FLOWCTRL_STATUS 0x8 + + /* Speed, bits 9:7 */ +#define QCA808X_STATUS_SPEED_MASK 0x380 + + /* 000=10Mbs */ +#define QCA808X_STATUS_SPEED_10MBS 0x0000 + + /* 001=100Mbs */ +#define QCA808X_STATUS_SPEED_100MBS 0x80 + + /* 010=1000Mbs */ +#define QCA808X_STATUS_SPEED_1000MBS 0x100 + + /* 100=2500Mbs */ +#define QCA808X_STATUS_SPEED_2500MBS 0x200 + + /*QCA808X interrupt flag */ +#define QCA808X_INTR_FAST_LINK_DOWN 0x8000 +#define QCA808X_INTR_SPEED_CHANGE 0x4000 +#define QCA808X_INTR_SEC_ENA_CHANGE 0x2000 +#define QCA808X_INTR_STATUS_DOWN_CHANGE 0x0800 +#define QCA808X_INTR_STATUS_UP_CHANGE 0x0400 +#define QCA808X_INTR_FAST_LINK_DOWN_MASK 0x240 +#define QCA808X_INTR_FAST_LINK_DOWN_STAT_10M 0x40 +#define QCA808X_INTR_FAST_LINK_DOWN_STAT_100M 0x200 +#define QCA808X_INTR_FAST_LINK_DOWN_STAT_1000M 0x240 +#define QCA808X_INTR_LINK_FAIL_SG 0x0100 +#define QCA808X_INTR_LINK_SUCCESS_SG 0x0080 +#define QCA808X_INTR_DOWNSHIF 0x0020 +#define QCA808X_INTR_10MS_PTP 0x0010 +#define QCA808X_INTR_RX_PTP 0x0008 +#define QCA808X_INTR_TX_PTP 0x0004 +#define QCA808X_INTR_POE 0x0002 +#define QCA808X_INTR_WOL 0x0001 + + /* QCA808X counter */ +#define QCA808X_PHY_MMD7_COUNTER_CTRL 0x8029 +#define QCA808X_PHY_MMD7_INGRESS_COUNTER_HIGH 0x802a +#define QCA808X_PHY_MMD7_INGRESS_COUNTER_LOW 0x802b +#define QCA808X_PHY_MMD7_INGRESS_ERROR_COUNTER 0x802c +#define QCA808X_PHY_MMD7_EGRESS_COUNTER_HIGH 0x802d +#define QCA808X_PHY_MMD7_EGRESS_COUNTER_LOW 0x802e +#define QCA808X_PHY_MMD7_EGRESS_ERROR_COUNTER 0x802f +#define QCA808X_PHY_MMD7_LED_POLARITY_CTRL 0x901a +#define QCA808X_PHY_MMD7_LED0_CTRL 0x8078 +#define QCA808X_PHY_MMD7_LED1_CTRL 0x8074 +#define QCA808X_PHY_MMD7_LED2_CTRL 0x8076 +#define QCA808X_PHY_MMD7_LED_POLARITY_ACTIVE_HIGH 0x46 +#define QCA808X_PHY_MMD7_LED0_CTRL_ENABLE 0x8670 +#define QCA808X_PHY_MMD7_LED1_CTRL_DISABLE 0x0 +#define QCA808X_PHY_MMD7_LED2_CTRL_DISABLE 0x0 + +#define QCA808X_PHY_FRAME_CHECK_EN 0x0001 +#define QCA808X_PHY_XMIT_MAC_CNT_SELFCLR 0x0002 + +#define QCA808X_PHY_ADC_THRESHOLD 0x2c80 +#define QCA808X_PHY_ADC_THRESHOLD_80MV 0 +#define QCA808X_PHY_ADC_THRESHOLD_100MV 0xf0 +#define QCA808X_PHY_ADC_THRESHOLD_200MV 0x0f +#define QCA808X_PHY_ADC_THRESHOLD_300MV 0xff + +a_uint16_t +qca808x_phy_reg_read(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t reg_id); + +sw_error_t +qca808x_phy_reg_write(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t reg_id, a_uint16_t reg_val); + +sw_error_t +qca808x_phy_mmd_write(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint16_t mmd_num, a_uint16_t reg_id, + a_uint16_t reg_val); + +a_uint16_t +qca808x_phy_mmd_read(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint16_t mmd_num, a_uint16_t reg_id); + +a_uint16_t +qca808x_phy_reg_read(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t reg_id); + +sw_error_t +qca808x_phy_reg_write(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t +reg_id, a_uint16_t reg_val); + +sw_error_t +qca808x_phy_debug_write(a_uint32_t dev_id, a_uint32_t phy_id, a_uint16_t reg_id, + a_uint16_t reg_val); +a_uint16_t +qca808x_phy_debug_read(a_uint32_t dev_id, a_uint32_t phy_id, a_uint16_t reg_id); + +sw_error_t +qca808x_phy_mmd_write(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint16_t mmd_num, a_uint16_t reg_id, a_uint16_t +reg_val); + +a_uint16_t +qca808x_phy_mmd_read(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint16_t mmd_num, a_uint16_t reg_id); + +#define QCA808X_PHY_8023AZ_AFE_CTRL_MASK 0x01f0 +#define QCA808X_PHY_8023AZ_AFE_EN 0x0090 + +sw_error_t +qca808x_phy_set_duplex (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_duplex_t duplex); + +sw_error_t +qca808x_phy_get_duplex (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_duplex_t * duplex); + +sw_error_t +qca808x_phy_set_speed (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_speed_t speed); + +sw_error_t +qca808x_phy_get_speed (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_speed_t * speed); + +sw_error_t +qca808x_phy_restart_autoneg (a_uint32_t dev_id, a_uint32_t phy_id); + +sw_error_t +qca808x_phy_enable_autoneg (a_uint32_t dev_id, a_uint32_t phy_id); + +a_bool_t +qca808x_phy_get_link_status (a_uint32_t dev_id, a_uint32_t phy_id); + +sw_error_t +qca808x_phy_set_autoneg_adv (a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t autoneg); + +sw_error_t +qca808x_phy_get_autoneg_adv (a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * autoneg); + +a_bool_t qca808x_phy_autoneg_status (a_uint32_t dev_id, a_uint32_t phy_id); +#ifndef IN_PORTCONTROL_MINI +sw_error_t +qca808x_phy_intr_mask_set (a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t intr_mask_flag); + +sw_error_t +qca808x_phy_intr_mask_get (a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * intr_mask_flag); + +sw_error_t +qca808x_phy_intr_status_get (a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * intr_status_flag); +#endif +sw_error_t +qca808x_phy_get_phy_id(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *phy_data); + +sw_error_t +qca808x_phy_get_status(a_uint32_t dev_id, a_uint32_t phy_id, + struct port_phy_status *phy_status); + +sw_error_t +qca808x_phy_interface_get_mode_status(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_interface_mode_t *interface_mode_status); + +sw_error_t qca808x_phy_reset(a_uint32_t dev_id, a_uint32_t phy_id); + +sw_error_t +qca808x_phy_set_force_speed(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_speed_t speed); +sw_error_t qca808x_phy_poweroff(a_uint32_t dev_id, a_uint32_t phy_id); +sw_error_t qca808x_phy_poweron(a_uint32_t dev_id, a_uint32_t phy_id); +#ifndef IN_PORTCONTROL_MINI +sw_error_t +qca808x_phy_set_hibernate(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable); +sw_error_t +qca808x_phy_get_hibernate(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t * enable); +sw_error_t +qca808x_phy_cdt(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t mdi_pair, + fal_cable_status_t * cable_status, a_uint32_t * cable_len); +sw_error_t +qca808x_phy_set_mdix(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_mdix_mode_t mode); +sw_error_t +qca808x_phy_get_mdix(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_mdix_mode_t * mode); +sw_error_t +qca808x_phy_get_mdix_status(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_mdix_status_t * mode); +sw_error_t +qca808x_phy_set_local_loopback(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t enable); +sw_error_t +qca808x_phy_get_local_loopback(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t * enable); +sw_error_t +qca808x_phy_set_remote_loopback(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t enable); +sw_error_t +qca808x_phy_get_remote_loopback(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t * enable); +sw_error_t +qca808x_phy_set_wol_status(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable); +sw_error_t +qca808x_phy_get_wol_status(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t * enable); +sw_error_t +qca808x_phy_set_magic_frame_mac(a_uint32_t dev_id, a_uint32_t phy_id, + fal_mac_addr_t * mac); +sw_error_t +qca808x_phy_get_magic_frame_mac(a_uint32_t dev_id, a_uint32_t phy_id, + fal_mac_addr_t * mac); +sw_error_t +qca808x_phy_set_counter(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable); +sw_error_t +qca808x_phy_get_counter(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t * enable); +sw_error_t +qca808x_phy_show_counter(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_counter_info_t * counter_infor); +sw_error_t +qca808x_phy_set_intr_mask(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t intr_mask_flag); +sw_error_t +qca808x_phy_get_intr_mask(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * intr_mask_flag); +sw_error_t +qca808x_phy_get_intr_status(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * intr_status_flag); +sw_error_t +qca808x_phy_set_8023az(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable); +sw_error_t +qca808x_phy_get_8023az(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t * enable); +#endif +sw_error_t +qca808x_phy_set_eee_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t adv); +sw_error_t +qca808x_phy_get_eee_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *adv); +sw_error_t +qca808x_phy_get_eee_partner_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *adv); +sw_error_t +qca808x_phy_get_eee_cap(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *cap); +sw_error_t +qca808x_phy_get_eee_status(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *status); +void qca808x_phy_lock_init(void); +int qca808x_phy_init(a_uint32_t dev_id, a_uint32_t port_bmp); + +void qca808x_phy_exit(a_uint32_t dev_id, a_uint32_t port_id); +a_bool_t +qca808x_phy_2500caps(a_uint32_t dev_id, a_uint32_t phy_id); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _qca808x_PHY_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/qca808x_ptp.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/qca808x_ptp.h new file mode 100755 index 000000000..045c3702e --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/qca808x_ptp.h @@ -0,0 +1,223 @@ +/* + * 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 _QCA808X_PTP_H_ +#define _QCA808X_PTP_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#define PTP_DEV_ID 0 + +sw_error_t +qca808x_phy_ptp_security_set(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_security_t *sec); + +sw_error_t +qca808x_phy_ptp_link_delay_set(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_time_t *time); + +sw_error_t +qca808x_phy_ptp_rx_crc_recalc_status_get(a_uint32_t dev_id, + a_uint32_t phy_id, a_bool_t *status); + +sw_error_t +qca808x_phy_ptp_tod_uart_set(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_tod_uart_t *tod_uart); + +sw_error_t +qca808x_phy_ptp_enhanced_timestamp_engine_get(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_direction_t direction, + fal_ptp_enhanced_ts_engine_t *ts_engine); + +sw_error_t +qca808x_phy_ptp_pps_signal_control_set(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_pps_signal_control_t *sig_control); + +sw_error_t +qca808x_phy_ptp_timestamp_get(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_direction_t direction, + fal_ptp_pkt_info_t *pkt_info, fal_ptp_time_t *time); + +sw_error_t +qca808x_phy_ptp_asym_correction_get(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_asym_correction_t* asym_cf); + +sw_error_t +qca808x_phy_ptp_rtc_time_snapshot_status_get(a_uint32_t dev_id, + a_uint32_t phy_id, a_bool_t *status); + +sw_error_t +qca808x_phy_ptp_capture_set(a_uint32_t dev_id, + a_uint32_t phy_id, a_uint32_t capture_id, + fal_ptp_capture_t *capture); + +sw_error_t +qca808x_phy_ptp_rtc_adjfreq_set(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_time_t *time); + +sw_error_t +qca808x_phy_ptp_asym_correction_set(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_asym_correction_t *asym_cf); + +sw_error_t +qca808x_phy_ptp_pkt_timestamp_set(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_time_t *time); + +sw_error_t +qca808x_phy_ptp_rtc_time_get(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_time_t *time); + +sw_error_t +qca808x_phy_ptp_rtc_time_set(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_time_t *time); + +sw_error_t +qca808x_phy_ptp_pkt_timestamp_get(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_time_t *time); + +sw_error_t +qca808x_phy_ptp_interrupt_set(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_interrupt_t *interrupt); + +sw_error_t +qca808x_phy_ptp_trigger_set(a_uint32_t dev_id, + a_uint32_t phy_id, a_uint32_t trigger_id, + fal_ptp_trigger_t *triger); + +sw_error_t +qca808x_phy_ptp_pps_signal_control_get(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_pps_signal_control_t *sig_control); + +sw_error_t +qca808x_phy_ptp_capture_get(a_uint32_t dev_id, + a_uint32_t phy_id, a_uint32_t capture_id, + fal_ptp_capture_t *capture); + +sw_error_t +qca808x_phy_ptp_rx_crc_recalc_enable(a_uint32_t dev_id, + a_uint32_t phy_id, a_bool_t status); + +sw_error_t +qca808x_phy_ptp_security_get(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_security_t *sec); + +sw_error_t +qca808x_phy_ptp_increment_sync_from_clock_status_get(a_uint32_t dev_id, + a_uint32_t phy_id, a_bool_t *status); + +sw_error_t +qca808x_phy_ptp_tod_uart_get(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_tod_uart_t *tod_uart); + +sw_error_t +qca808x_phy_ptp_enhanced_timestamp_engine_set(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_direction_t direction, + fal_ptp_enhanced_ts_engine_t *ts_engine); + +sw_error_t +qca808x_phy_ptp_rtc_time_clear(a_uint32_t dev_id, + a_uint32_t phy_id); + +sw_error_t +qca808x_phy_ptp_reference_clock_set(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_reference_clock_t ref_clock); + +sw_error_t +qca808x_phy_ptp_output_waveform_set(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_output_waveform_t *waveform); + +sw_error_t +qca808x_phy_ptp_rx_timestamp_mode_set(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_rx_timestamp_mode_t ts_mode); + +sw_error_t +qca808x_phy_ptp_grandmaster_mode_set(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_grandmaster_mode_t *gm_mode); + +sw_error_t +qca808x_phy_ptp_config_set(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_config_t *config); + +sw_error_t +qca808x_phy_ptp_trigger_get(a_uint32_t dev_id, + a_uint32_t phy_id, a_uint32_t trigger_id, + fal_ptp_trigger_t *triger); + +sw_error_t +qca808x_phy_ptp_rtc_adjfreq_get(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_time_t *time); + +sw_error_t +qca808x_phy_ptp_grandmaster_mode_get(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_grandmaster_mode_t *gm_mode); + +sw_error_t +qca808x_phy_ptp_rx_timestamp_mode_get(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_rx_timestamp_mode_t *ts_mode); + +sw_error_t +qca808x_phy_ptp_rtc_adjtime_set(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_time_t *time); + +sw_error_t +qca808x_phy_ptp_link_delay_get(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_time_t *time); + +sw_error_t +qca808x_phy_ptp_increment_sync_from_clock_enable(a_uint32_t dev_id, + a_uint32_t phy_id, a_bool_t status); + +sw_error_t +qca808x_phy_ptp_config_get(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_config_t *config); + +sw_error_t +qca808x_phy_ptp_output_waveform_get(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_output_waveform_t *waveform); + +sw_error_t +qca808x_phy_ptp_interrupt_get(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_interrupt_t *interrupt); + +sw_error_t +qca808x_phy_ptp_rtc_time_snapshot_enable(a_uint32_t dev_id, + a_uint32_t phy_id, a_bool_t status); + +sw_error_t +qca808x_phy_ptp_reference_clock_get(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_reference_clock_t *ref_clock); + +void qca808x_phy_ptp_api_ops_init(hsl_phy_ptp_ops_t *phy_ptp_ops); + +#if defined(IN_LINUX_STD_PTP) +void qca808x_ptp_gm_gps_seconds_sync_enable(a_uint32_t dev_id, + a_uint32_t phy_addr, a_bool_t en); + +a_bool_t qca808x_ptp_gm_gps_seconds_sync_status_get(a_uint32_t dev_id, + a_uint32_t phy_addr); + +void qca808x_ptp_clock_mode_config(a_uint32_t dev_id, + a_uint32_t phy_addr, a_uint16_t clock_mode, a_uint16_t step_mode); + +void qca808x_ptp_stat_get(void); + +void qca808x_ptp_stat_set(void); +#endif +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _qca808x_PTP_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/qca808x_ptp_api.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/qca808x_ptp_api.h new file mode 100755 index 000000000..5e1464fdb --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/qca808x_ptp_api.h @@ -0,0 +1,5858 @@ +/* + * 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. + */ + + +/** + * @defgroup + * @{ + */ +#ifndef _PTP_REG_API_H_ +#define _PTP_REG_API_H_ + +#define PTP_REG_BASE_ADDR 0x3000 + + +sw_error_t +qca808x_ptp_imr_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_imr_reg_u *value); + +sw_error_t +qca808x_ptp_imr_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_imr_reg_u *value); + +sw_error_t +qca808x_ptp_isr_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_isr_reg_u *value); + +sw_error_t +qca808x_ptp_isr_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_isr_reg_u *value); + +sw_error_t +qca808x_ptp_hw_enable_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_hw_enable_reg_u *value); + +sw_error_t +qca808x_ptp_hw_enable_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_hw_enable_reg_u *value); + +sw_error_t +qca808x_ptp_main_conf_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_main_conf_reg_u *value); + +sw_error_t +qca808x_ptp_main_conf_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_main_conf_reg_u *value); + +sw_error_t +qca808x_ptp_rx_seqid0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_seqid0_reg_u *value); + +sw_error_t +qca808x_ptp_rx_seqid0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_seqid0_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid0_0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid0_0_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid0_0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid0_0_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid0_1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid0_1_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid0_1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid0_1_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid0_2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid0_2_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid0_2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid0_2_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid0_3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid0_3_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid0_3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid0_3_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid0_4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid0_4_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid0_4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid0_4_reg_u *value); + +sw_error_t +qca808x_ptp_rtc_clk_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_clk_reg_u *value); + +sw_error_t +qca808x_ptp_rtc_clk_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_clk_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts0_0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts0_0_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts0_0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts0_0_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts0_1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts0_1_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts0_1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts0_1_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts0_2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts0_2_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts0_2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts0_2_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts0_3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts0_3_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts0_3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts0_3_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts0_4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts0_4_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts0_4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts0_4_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts0_5_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts0_5_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts0_5_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts0_5_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts0_6_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts0_6_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts0_6_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts0_6_reg_u *value); + +sw_error_t +qca808x_ptp_tx_seqid_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_seqid_reg_u *value); + +sw_error_t +qca808x_ptp_tx_seqid_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_seqid_reg_u *value); + +sw_error_t +qca808x_ptp_tx_portid0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_portid0_reg_u *value); + +sw_error_t +qca808x_ptp_tx_portid0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_portid0_reg_u *value); + +sw_error_t +qca808x_ptp_tx_portid1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_portid1_reg_u *value); + +sw_error_t +qca808x_ptp_tx_portid1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_portid1_reg_u *value); + +sw_error_t +qca808x_ptp_tx_portid2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_portid2_reg_u *value); + +sw_error_t +qca808x_ptp_tx_portid2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_portid2_reg_u *value); + +sw_error_t +qca808x_ptp_tx_portid3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_portid3_reg_u *value); + +sw_error_t +qca808x_ptp_tx_portid3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_portid3_reg_u *value); + +sw_error_t +qca808x_ptp_tx_portid4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_portid4_reg_u *value); + +sw_error_t +qca808x_ptp_tx_portid4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_portid4_reg_u *value); + +sw_error_t +qca808x_ptp_tx_ts0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_ts0_reg_u *value); + +sw_error_t +qca808x_ptp_tx_ts0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_ts0_reg_u *value); + +sw_error_t +qca808x_ptp_tx_ts1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_ts1_reg_u *value); + +sw_error_t +qca808x_ptp_tx_ts1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_ts1_reg_u *value); + +sw_error_t +qca808x_ptp_tx_ts2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_ts2_reg_u *value); + +sw_error_t +qca808x_ptp_tx_ts2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_ts2_reg_u *value); + +sw_error_t +qca808x_ptp_tx_ts3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_ts3_reg_u *value); + +sw_error_t +qca808x_ptp_tx_ts3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_ts3_reg_u *value); + +sw_error_t +qca808x_ptp_tx_ts4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_ts4_reg_u *value); + +sw_error_t +qca808x_ptp_tx_ts4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_ts4_reg_u *value); + +sw_error_t +qca808x_ptp_tx_ts5_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_ts5_reg_u *value); + +sw_error_t +qca808x_ptp_tx_ts5_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_ts5_reg_u *value); + +sw_error_t +qca808x_ptp_tx_ts6_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_ts6_reg_u *value); + +sw_error_t +qca808x_ptp_tx_ts6_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_ts6_reg_u *value); + +sw_error_t +qca808x_ptp_orig_corr0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_orig_corr0_reg_u *value); + +sw_error_t +qca808x_ptp_orig_corr0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_orig_corr0_reg_u *value); + +sw_error_t +qca808x_ptp_orig_corr1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_orig_corr1_reg_u *value); + +sw_error_t +qca808x_ptp_orig_corr1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_orig_corr1_reg_u *value); + +sw_error_t +qca808x_ptp_orig_corr2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_orig_corr2_reg_u *value); + +sw_error_t +qca808x_ptp_orig_corr2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_orig_corr2_reg_u *value); + +sw_error_t +qca808x_ptp_orig_corr3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_orig_corr3_reg_u *value); + +sw_error_t +qca808x_ptp_orig_corr3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_orig_corr3_reg_u *value); + +sw_error_t +qca808x_ptp_in_trig0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_in_trig0_reg_u *value); + +sw_error_t +qca808x_ptp_in_trig0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_in_trig0_reg_u *value); + +sw_error_t +qca808x_ptp_in_trig1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_in_trig1_reg_u *value); + +sw_error_t +qca808x_ptp_in_trig1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_in_trig1_reg_u *value); + +sw_error_t +qca808x_ptp_in_trig2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_in_trig2_reg_u *value); + +sw_error_t +qca808x_ptp_in_trig2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_in_trig2_reg_u *value); + +sw_error_t +qca808x_ptp_in_trig3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_in_trig3_reg_u *value); + +sw_error_t +qca808x_ptp_in_trig3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_in_trig3_reg_u *value); + +sw_error_t +qca808x_ptp_tx_latency_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_latency_reg_u *value); + +sw_error_t +qca808x_ptp_tx_latency_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_latency_reg_u *value); + +sw_error_t +qca808x_ptp_rtc_inc0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_inc0_reg_u *value); + +sw_error_t +qca808x_ptp_rtc_inc0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_inc0_reg_u *value); + +sw_error_t +qca808x_ptp_rtc_inc1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_inc1_reg_u *value); + +sw_error_t +qca808x_ptp_rtc_inc1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_inc1_reg_u *value); + +sw_error_t +qca808x_ptp_rtcoffs0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtcoffs0_reg_u *value); + +sw_error_t +qca808x_ptp_rtcoffs0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtcoffs0_reg_u *value); + +sw_error_t +qca808x_ptp_rtcoffs1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtcoffs1_reg_u *value); + +sw_error_t +qca808x_ptp_rtcoffs1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtcoffs1_reg_u *value); + +sw_error_t +qca808x_ptp_rtcoffs2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtcoffs2_reg_u *value); + +sw_error_t +qca808x_ptp_rtcoffs2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtcoffs2_reg_u *value); + +sw_error_t +qca808x_ptp_rtcoffs3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtcoffs3_reg_u *value); + +sw_error_t +qca808x_ptp_rtcoffs3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtcoffs3_reg_u *value); + +sw_error_t +qca808x_ptp_rtcoffs4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtcoffs4_reg_u *value); + +sw_error_t +qca808x_ptp_rtcoffs4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtcoffs4_reg_u *value); + +sw_error_t +qca808x_ptp_rtc0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc0_reg_u *value); + +sw_error_t +qca808x_ptp_rtc0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc0_reg_u *value); + +sw_error_t +qca808x_ptp_rtc1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc1_reg_u *value); + +sw_error_t +qca808x_ptp_rtc1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc1_reg_u *value); + +sw_error_t +qca808x_ptp_rtc2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc2_reg_u *value); + +sw_error_t +qca808x_ptp_rtc2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc2_reg_u *value); + +sw_error_t +qca808x_ptp_rtc3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc3_reg_u *value); + +sw_error_t +qca808x_ptp_rtc3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc3_reg_u *value); + +sw_error_t +qca808x_ptp_rtc4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc4_reg_u *value); + +sw_error_t +qca808x_ptp_rtc4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc4_reg_u *value); + +sw_error_t +qca808x_ptp_rtc5_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc5_reg_u *value); + +sw_error_t +qca808x_ptp_rtc5_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc5_reg_u *value); + +sw_error_t +qca808x_ptp_rtc6_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc6_reg_u *value); + +sw_error_t +qca808x_ptp_rtc6_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc6_reg_u *value); + +sw_error_t +qca808x_ptp_rtcoffs_valid_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtcoffs_valid_reg_u *value); + +sw_error_t +qca808x_ptp_rtcoffs_valid_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtcoffs_valid_reg_u *value); + +sw_error_t +qca808x_ptp_misc_config_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_misc_config_reg_u *value); + +sw_error_t +qca808x_ptp_misc_config_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_misc_config_reg_u *value); + +sw_error_t +qca808x_ptp_ext_imr_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ext_imr_reg_u *value); + +sw_error_t +qca808x_ptp_ext_imr_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ext_imr_reg_u *value); + +sw_error_t +qca808x_ptp_ext_isr_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ext_isr_reg_u *value); + +sw_error_t +qca808x_ptp_ext_isr_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ext_isr_reg_u *value); + +sw_error_t +qca808x_ptp_rtc_ext_conf_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_ext_conf_reg_u *value); + +sw_error_t +qca808x_ptp_rtc_ext_conf_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_ext_conf_reg_u *value); + +sw_error_t +qca808x_ptp_rtc_preloaded0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_preloaded0_reg_u *value); + +sw_error_t +qca808x_ptp_rtc_preloaded0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_preloaded0_reg_u *value); + +sw_error_t +qca808x_ptp_rtc_preloaded1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_preloaded1_reg_u *value); + +sw_error_t +qca808x_ptp_rtc_preloaded1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_preloaded1_reg_u *value); + +sw_error_t +qca808x_ptp_rtc_preloaded2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_preloaded2_reg_u *value); + +sw_error_t +qca808x_ptp_rtc_preloaded2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_preloaded2_reg_u *value); + +sw_error_t +qca808x_ptp_rtc_preloaded3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_preloaded3_reg_u *value); + +sw_error_t +qca808x_ptp_rtc_preloaded3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_preloaded3_reg_u *value); + +sw_error_t +qca808x_ptp_rtc_preloaded4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_preloaded4_reg_u *value); + +sw_error_t +qca808x_ptp_rtc_preloaded4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_preloaded4_reg_u *value); + +sw_error_t +qca808x_ptp_gm_conf0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_gm_conf0_reg_u *value); + +sw_error_t +qca808x_ptp_gm_conf0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_gm_conf0_reg_u *value); + +sw_error_t +qca808x_ptp_gm_conf1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_gm_conf1_reg_u *value); + +sw_error_t +qca808x_ptp_gm_conf1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_gm_conf1_reg_u *value); + +sw_error_t +qca808x_ptp_ppsin_ts0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ppsin_ts0_reg_u *value); + +sw_error_t +qca808x_ptp_ppsin_ts0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ppsin_ts0_reg_u *value); + +sw_error_t +qca808x_ptp_ppsin_ts1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ppsin_ts1_reg_u *value); + +sw_error_t +qca808x_ptp_ppsin_ts1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ppsin_ts1_reg_u *value); + +sw_error_t +qca808x_ptp_ppsin_ts2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ppsin_ts2_reg_u *value); + +sw_error_t +qca808x_ptp_ppsin_ts2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ppsin_ts2_reg_u *value); + +sw_error_t +qca808x_ptp_ppsin_ts3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ppsin_ts3_reg_u *value); + +sw_error_t +qca808x_ptp_ppsin_ts3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ppsin_ts3_reg_u *value); + +sw_error_t +qca808x_ptp_ppsin_ts4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ppsin_ts4_reg_u *value); + +sw_error_t +qca808x_ptp_ppsin_ts4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ppsin_ts4_reg_u *value); + +sw_error_t +qca808x_ptp_hwpll_inc0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_hwpll_inc0_reg_u *value); + +sw_error_t +qca808x_ptp_hwpll_inc0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_hwpll_inc0_reg_u *value); + +sw_error_t +qca808x_ptp_hwpll_inc1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_hwpll_inc1_reg_u *value); + +sw_error_t +qca808x_ptp_hwpll_inc1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_hwpll_inc1_reg_u *value); + +sw_error_t +qca808x_ptp_ppsin_latency_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ppsin_latency_reg_u *value); + +sw_error_t +qca808x_ptp_ppsin_latency_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ppsin_latency_reg_u *value); + +sw_error_t +qca808x_ptp_trigger0_config_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger0_config_reg_u *value); + +sw_error_t +qca808x_ptp_trigger0_config_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger0_config_reg_u *value); + +sw_error_t +qca808x_ptp_trigger0_status_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger0_status_reg_u *value); + +sw_error_t +qca808x_ptp_trigger0_status_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger0_status_reg_u *value); + +sw_error_t +qca808x_ptp_trigger1_config_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger1_config_reg_u *value); + +sw_error_t +qca808x_ptp_trigger1_config_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger1_config_reg_u *value); + +sw_error_t +qca808x_ptp_trigger1_status_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger1_status_reg_u *value); + +sw_error_t +qca808x_ptp_trigger1_status_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger1_status_reg_u *value); + +sw_error_t +qca808x_ptp_trigger0_timestamp0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger0_timestamp0_reg_u *value); + +sw_error_t +qca808x_ptp_trigger0_timestamp0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger0_timestamp0_reg_u *value); + +sw_error_t +qca808x_ptp_trigger0_timestamp1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger0_timestamp1_reg_u *value); + +sw_error_t +qca808x_ptp_trigger0_timestamp1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger0_timestamp1_reg_u *value); + +sw_error_t +qca808x_ptp_trigger0_timestamp2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger0_timestamp2_reg_u *value); + +sw_error_t +qca808x_ptp_trigger0_timestamp2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger0_timestamp2_reg_u *value); + +sw_error_t +qca808x_ptp_trigger0_timestamp3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger0_timestamp3_reg_u *value); + +sw_error_t +qca808x_ptp_trigger0_timestamp3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger0_timestamp3_reg_u *value); + +sw_error_t +qca808x_ptp_trigger0_timestamp4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger0_timestamp4_reg_u *value); + +sw_error_t +qca808x_ptp_trigger0_timestamp4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger0_timestamp4_reg_u *value); + +sw_error_t +qca808x_ptp_trigger1_timestamp0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger1_timestamp0_reg_u *value); + +sw_error_t +qca808x_ptp_trigger1_timestamp0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger1_timestamp0_reg_u *value); + +sw_error_t +qca808x_ptp_trigger1_timestamp1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger1_timestamp1_reg_u *value); + +sw_error_t +qca808x_ptp_trigger1_timestamp1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger1_timestamp1_reg_u *value); + +sw_error_t +qca808x_ptp_trigger1_timestamp2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger1_timestamp2_reg_u *value); + +sw_error_t +qca808x_ptp_trigger1_timestamp2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger1_timestamp2_reg_u *value); + +sw_error_t +qca808x_ptp_trigger1_timestamp3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger1_timestamp3_reg_u *value); + +sw_error_t +qca808x_ptp_trigger1_timestamp3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger1_timestamp3_reg_u *value); + +sw_error_t +qca808x_ptp_trigger1_timestamp4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger1_timestamp4_reg_u *value); + +sw_error_t +qca808x_ptp_trigger1_timestamp4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger1_timestamp4_reg_u *value); + +sw_error_t +qca808x_ptp_event0_config_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event0_config_reg_u *value); + +sw_error_t +qca808x_ptp_event0_config_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event0_config_reg_u *value); + +sw_error_t +qca808x_ptp_event0_status_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event0_status_reg_u *value); + +sw_error_t +qca808x_ptp_event0_status_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event0_status_reg_u *value); + +sw_error_t +qca808x_ptp_event1_config_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event1_config_reg_u *value); + +sw_error_t +qca808x_ptp_event1_config_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event1_config_reg_u *value); + +sw_error_t +qca808x_ptp_event1_status_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event1_status_reg_u *value); + +sw_error_t +qca808x_ptp_event1_status_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event1_status_reg_u *value); + +sw_error_t +qca808x_ptp_event0_timestamp0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event0_timestamp0_reg_u *value); + +sw_error_t +qca808x_ptp_event0_timestamp0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event0_timestamp0_reg_u *value); + +sw_error_t +qca808x_ptp_event0_timestamp1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event0_timestamp1_reg_u *value); + +sw_error_t +qca808x_ptp_event0_timestamp1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event0_timestamp1_reg_u *value); + +sw_error_t +qca808x_ptp_event0_timestamp2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event0_timestamp2_reg_u *value); + +sw_error_t +qca808x_ptp_event0_timestamp2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event0_timestamp2_reg_u *value); + +sw_error_t +qca808x_ptp_event0_timestamp3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event0_timestamp3_reg_u *value); + +sw_error_t +qca808x_ptp_event0_timestamp3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event0_timestamp3_reg_u *value); + +sw_error_t +qca808x_ptp_event0_timestamp4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event0_timestamp4_reg_u *value); + +sw_error_t +qca808x_ptp_event0_timestamp4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event0_timestamp4_reg_u *value); + +sw_error_t +qca808x_ptp_event1_timestamp0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event1_timestamp0_reg_u *value); + +sw_error_t +qca808x_ptp_event1_timestamp0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event1_timestamp0_reg_u *value); + +sw_error_t +qca808x_ptp_event1_timestamp1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event1_timestamp1_reg_u *value); + +sw_error_t +qca808x_ptp_event1_timestamp1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event1_timestamp1_reg_u *value); + +sw_error_t +qca808x_ptp_event1_timestamp2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event1_timestamp2_reg_u *value); + +sw_error_t +qca808x_ptp_event1_timestamp2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event1_timestamp2_reg_u *value); + +sw_error_t +qca808x_ptp_event1_timestamp3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event1_timestamp3_reg_u *value); + +sw_error_t +qca808x_ptp_event1_timestamp3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event1_timestamp3_reg_u *value); + +sw_error_t +qca808x_ptp_event1_timestamp4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event1_timestamp4_reg_u *value); + +sw_error_t +qca808x_ptp_event1_timestamp4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event1_timestamp4_reg_u *value); + +sw_error_t +qca808x_ptp_rx_seqid1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_seqid1_reg_u *value); + +sw_error_t +qca808x_ptp_rx_seqid1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_seqid1_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid1_0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid1_0_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid1_0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid1_0_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid1_1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid1_1_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid1_1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid1_1_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid1_2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid1_2_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid1_2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid1_2_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid1_3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid1_3_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid1_3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid1_3_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid1_4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid1_4_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid1_4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid1_4_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts1_0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts1_0_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts1_0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts1_0_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts1_1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts1_1_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts1_1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts1_1_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts1_2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts1_2_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts1_2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts1_2_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts1_3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts1_3_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts1_3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts1_3_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts1_4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts1_4_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts1_4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts1_4_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts1_5_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts1_5_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts1_5_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts1_5_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts1_6_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts1_6_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts1_6_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts1_6_reg_u *value); + +sw_error_t +qca808x_ptp_rx_seqid2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_seqid2_reg_u *value); + +sw_error_t +qca808x_ptp_rx_seqid2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_seqid2_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid2_0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid2_0_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid2_0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid2_0_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid2_1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid2_1_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid2_1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid2_1_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid2_2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid2_2_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid2_2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid2_2_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid2_3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid2_3_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid2_3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid2_3_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid2_4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid2_4_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid2_4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid2_4_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts2_0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts2_0_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts2_0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts2_0_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts2_1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts2_1_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts2_1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts2_1_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts2_2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts2_2_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts2_2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts2_2_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts2_3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts2_3_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts2_3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts2_3_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts2_4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts2_4_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts2_4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts2_4_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts2_5_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts2_5_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts2_5_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts2_5_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts2_6_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts2_6_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts2_6_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts2_6_reg_u *value); + +sw_error_t +qca808x_ptp_rx_seqid3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_seqid3_reg_u *value); + +sw_error_t +qca808x_ptp_rx_seqid3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_seqid3_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid3_0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid3_0_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid3_0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid3_0_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid3_1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid3_1_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid3_1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid3_1_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid3_2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid3_2_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid3_2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid3_2_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid3_3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid3_3_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid3_3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid3_3_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid3_4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid3_4_reg_u *value); + +sw_error_t +qca808x_ptp_rx_portid3_4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid3_4_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts3_0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts3_0_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts3_0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts3_0_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts3_1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts3_1_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts3_1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts3_1_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts3_2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts3_2_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts3_2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts3_2_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts3_3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts3_3_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts3_3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts3_3_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts3_4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts3_4_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts3_4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts3_4_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts3_5_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts3_5_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts3_5_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts3_5_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts3_6_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts3_6_reg_u *value); + +sw_error_t +qca808x_ptp_rx_ts3_6_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts3_6_reg_u *value); + +sw_error_t +qca808x_ptp_imr_reg_mask_bmp_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_imr_reg_mask_bmp_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_isr_reg_status_bmp_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_isr_reg_status_bmp_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_hw_enable_reg_ptp_hw_enable_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_hw_enable_reg_ptp_hw_enable_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_main_conf_reg_ts_attach_mode_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_main_conf_reg_ts_attach_mode_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_main_conf_reg_ptp_clk_sel_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_main_conf_reg_ptp_clk_sel_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_main_conf_reg_disable_1588_phy_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_main_conf_reg_disable_1588_phy_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_main_conf_reg_attach_crc_recal_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_main_conf_reg_attach_crc_recal_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_main_conf_reg_ipv4_force_checksum_zero_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_main_conf_reg_ipv4_force_checksum_zero_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_main_conf_reg_ipv6_embed_force_checksum_zero_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_main_conf_reg_ipv6_embed_force_checksum_zero_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_main_conf_reg_ptp_bypass_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_main_conf_reg_ptp_bypass_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_main_conf_reg_wol_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_main_conf_reg_wol_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_main_conf_reg_ptp_clock_mode_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_main_conf_reg_ptp_clock_mode_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_seqid0_reg_rx_seqid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_seqid0_reg_rx_seqid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_portid0_0_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_portid0_0_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_portid0_1_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_portid0_1_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_portid0_2_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_portid0_2_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_portid0_3_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_portid0_3_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_portid0_4_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_portid0_4_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rtc_clk_reg_rtc_clk_selection_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rtc_clk_reg_rtc_clk_selection_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_ts0_0_reg_rx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_ts0_0_reg_rx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_ts0_1_reg_rx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_ts0_1_reg_rx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_ts0_2_reg_rx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_ts0_2_reg_rx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_ts0_3_reg_rx_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_ts0_3_reg_rx_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_ts0_4_reg_rx_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_ts0_4_reg_rx_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_ts0_5_reg_rx_ts_nfsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_ts0_5_reg_rx_ts_nfsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_ts0_5_reg_rx_msg_type_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_ts0_5_reg_rx_msg_type_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_ts0_6_reg_rx_ts_nfsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_ts0_6_reg_rx_ts_nfsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_seqid_reg_tx_seqid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_seqid_reg_tx_seqid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_portid0_reg_tx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_portid0_reg_tx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_portid1_reg_tx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_portid1_reg_tx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_portid2_reg_tx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_portid2_reg_tx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_portid3_reg_tx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_portid3_reg_tx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_portid4_reg_tx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_portid4_reg_tx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_ts0_reg_tx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_ts0_reg_tx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_ts1_reg_tx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_ts1_reg_tx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_ts2_reg_tx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_ts2_reg_tx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_ts3_reg_tx_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_ts3_reg_tx_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_ts4_reg_tx_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_ts4_reg_tx_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_ts5_reg_tx_ts_nfsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_ts5_reg_tx_ts_nfsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_ts5_reg_tx_msg_type_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_ts5_reg_tx_msg_type_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_ts6_reg_tx_ts_nfsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_ts6_reg_tx_ts_nfsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_orig_corr0_reg_ptp_orig_corr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_orig_corr0_reg_ptp_orig_corr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_orig_corr1_reg_ptp_orig_corr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_orig_corr1_reg_ptp_orig_corr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_orig_corr2_reg_ptp_orig_corr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_orig_corr2_reg_ptp_orig_corr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_orig_corr3_reg_ptp_orig_corr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_orig_corr3_reg_ptp_orig_corr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_in_trig0_reg_ptp_in_trig_nisec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_in_trig0_reg_ptp_in_trig_nisec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_in_trig1_reg_ptp_in_trig_nisec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_in_trig1_reg_ptp_in_trig_nisec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_in_trig2_reg_ptp_in_trig_nisec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_in_trig2_reg_ptp_in_trig_nisec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_in_trig3_reg_ptp_in_trig_nisec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_in_trig3_reg_ptp_in_trig_nisec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_latency_reg_ptp_tx_latency_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_latency_reg_ptp_tx_latency_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rtc_inc0_reg_ptp_rtc_inc_nis_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rtc_inc0_reg_ptp_rtc_inc_nis_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rtc_inc0_reg_ptp_rtc_inc_nfs_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rtc_inc0_reg_ptp_rtc_inc_nfs_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rtc_inc1_reg_ptp_rtc_inc_nfs_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rtc_inc1_reg_ptp_rtc_inc_nfs_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rtcoffs0_reg_ptp_rtcoffs_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rtcoffs0_reg_ptp_rtcoffs_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rtcoffs1_reg_ptp_rtcoffs_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rtcoffs1_reg_ptp_rtcoffs_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rtcoffs2_reg_ptp_rtcoffs_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rtcoffs2_reg_ptp_rtcoffs_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rtcoffs3_reg_ptp_rtcoffs_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rtcoffs3_reg_ptp_rtcoffs_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rtcoffs4_reg_ptp_rtcoffs_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rtcoffs4_reg_ptp_rtcoffs_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rtc0_reg_ptp_rtc_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rtc0_reg_ptp_rtc_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rtc1_reg_ptp_rtc_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rtc1_reg_ptp_rtc_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rtc2_reg_ptp_rtc_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rtc2_reg_ptp_rtc_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rtc3_reg_ptp_rtc_nisec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rtc3_reg_ptp_rtc_nisec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rtc4_reg_ptp_rtc_nisec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rtc4_reg_ptp_rtc_nisec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rtc5_reg_ptp_rtc_nfsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rtc5_reg_ptp_rtc_nfsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rtc6_reg_ptp_rtc_nfsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rtc6_reg_ptp_rtc_nfsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rtcoffs_valid_reg_ptp_rtcoffs_valid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rtcoffs_valid_reg_ptp_rtcoffs_valid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_misc_config_reg_ptp_ver_chk_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_misc_config_reg_ptp_ver_chk_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_misc_config_reg_ipv6_udp_chk_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_misc_config_reg_ipv6_udp_chk_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_misc_config_reg_cf_from_pkt_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_misc_config_reg_cf_from_pkt_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_misc_config_reg_embed_ingress_time_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_misc_config_reg_embed_ingress_time_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_misc_config_reg_ptp_addr_chk_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_misc_config_reg_ptp_addr_chk_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_misc_config_reg_crc_validate_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_misc_config_reg_crc_validate_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_misc_config_reg_pkt_one_step_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_misc_config_reg_pkt_one_step_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_misc_config_reg_ptp_version_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_misc_config_reg_ptp_version_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_misc_config_reg_appended_timestamp_size_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_misc_config_reg_appended_timestamp_size_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_misc_config_reg_ts_rtc_select_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_misc_config_reg_ts_rtc_select_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_ext_imr_reg_mask_bmp_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_ext_imr_reg_mask_bmp_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_ext_isr_reg_status_bmp_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_ext_isr_reg_status_bmp_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rtc_ext_conf_reg_rtc_snapshot_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rtc_ext_conf_reg_rtc_snapshot_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rtc_ext_conf_reg_set_incval_mode_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rtc_ext_conf_reg_set_incval_mode_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rtc_ext_conf_reg_load_rtc_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rtc_ext_conf_reg_load_rtc_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rtc_ext_conf_reg_clear_rtc_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rtc_ext_conf_reg_clear_rtc_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rtc_ext_conf_reg_rtc_read_mode_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rtc_ext_conf_reg_rtc_read_mode_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rtc_ext_conf_reg_select_output_waveform_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rtc_ext_conf_reg_select_output_waveform_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rtc_ext_conf_reg_set_incval_valid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rtc_ext_conf_reg_set_incval_valid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rtc_preloaded0_reg_ptp_rtc_preloaded_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rtc_preloaded0_reg_ptp_rtc_preloaded_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rtc_preloaded1_reg_ptp_rtc_preloaded_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rtc_preloaded1_reg_ptp_rtc_preloaded_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rtc_preloaded2_reg_ptp_rtc_preloaded_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rtc_preloaded2_reg_ptp_rtc_preloaded_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rtc_preloaded3_reg_ptp_rtc_preloaded_nisec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rtc_preloaded3_reg_ptp_rtc_preloaded_nisec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rtc_preloaded4_reg_ptp_rtc_preloaded_nisec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rtc_preloaded4_reg_ptp_rtc_preloaded_nisec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_gm_conf0_reg_gm_pps_sync_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_gm_conf0_reg_gm_pps_sync_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_gm_conf0_reg_gm_pll_mode_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_gm_conf0_reg_gm_pll_mode_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_gm_conf0_reg_gm_maxfreq_offset_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_gm_conf0_reg_gm_maxfreq_offset_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_gm_conf0_reg_grandmaster_mode_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_gm_conf0_reg_grandmaster_mode_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_gm_conf1_reg_gm_kp_ldn_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_gm_conf1_reg_gm_kp_ldn_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_gm_conf1_reg_gm_ki_ldn_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_gm_conf1_reg_gm_ki_ldn_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_ppsin_ts0_reg_rx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_ppsin_ts0_reg_rx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_ppsin_ts1_reg_rx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_ppsin_ts1_reg_rx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_ppsin_ts2_reg_rx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_ppsin_ts2_reg_rx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_ppsin_ts3_reg_rx_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_ppsin_ts3_reg_rx_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_ppsin_ts4_reg_rx_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_ppsin_ts4_reg_rx_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_hwpll_inc0_reg_ptp_rtc_inc_nfs1_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_hwpll_inc0_reg_ptp_rtc_inc_nfs1_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_hwpll_inc0_reg_ptp_rtc_inc_nis_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_hwpll_inc0_reg_ptp_rtc_inc_nis_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_hwpll_inc1_reg_ptp_rtc_inc_nfs0_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_hwpll_inc1_reg_ptp_rtc_inc_nfs0_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_ppsin_latency_reg_ptp_ppsin_latency_sign_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_ppsin_latency_reg_ptp_ppsin_latency_sign_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_ppsin_latency_reg_ptp_ppsin_latency_value_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_ppsin_latency_reg_ptp_ppsin_latency_value_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_trigger0_config_reg_force_value_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_trigger0_config_reg_force_value_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_trigger0_config_reg_pattern_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_trigger0_config_reg_pattern_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_trigger0_config_reg_status_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_trigger0_config_reg_status_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_trigger0_config_reg_force_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_trigger0_config_reg_force_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_trigger0_config_reg_setting_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_trigger0_config_reg_setting_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_trigger0_config_reg_notify_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_trigger0_config_reg_notify_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_trigger0_config_reg_if_late_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_trigger0_config_reg_if_late_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_trigger0_status_reg_error_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_trigger0_status_reg_error_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_trigger0_status_reg_active_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_trigger0_status_reg_active_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_trigger0_status_reg_finished_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_trigger0_status_reg_finished_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_trigger1_config_reg_force_value_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_trigger1_config_reg_force_value_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_trigger1_config_reg_pattern_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_trigger1_config_reg_pattern_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_trigger1_config_reg_status_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_trigger1_config_reg_status_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_trigger1_config_reg_force_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_trigger1_config_reg_force_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_trigger1_config_reg_setting_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_trigger1_config_reg_setting_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_trigger1_config_reg_notify_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_trigger1_config_reg_notify_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_trigger1_config_reg_if_late_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_trigger1_config_reg_if_late_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_trigger1_status_reg_error_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_trigger1_status_reg_error_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_trigger1_status_reg_active_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_trigger1_status_reg_active_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_trigger1_status_reg_finished_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_trigger1_status_reg_finished_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_trigger0_timestamp0_reg_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_trigger0_timestamp0_reg_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_trigger0_timestamp1_reg_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_trigger0_timestamp1_reg_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_trigger0_timestamp2_reg_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_trigger0_timestamp2_reg_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_trigger0_timestamp3_reg_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_trigger0_timestamp3_reg_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_trigger0_timestamp4_reg_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_trigger0_timestamp4_reg_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_trigger1_timestamp0_reg_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_trigger1_timestamp0_reg_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_trigger1_timestamp1_reg_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_trigger1_timestamp1_reg_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_trigger1_timestamp2_reg_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_trigger1_timestamp2_reg_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_trigger1_timestamp3_reg_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_trigger1_timestamp3_reg_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_trigger1_timestamp4_reg_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_trigger1_timestamp4_reg_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_event0_config_reg_rise_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_event0_config_reg_rise_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_event0_config_reg_single_cap_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_event0_config_reg_single_cap_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_event0_config_reg_fall_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_event0_config_reg_fall_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_event0_config_reg_notify_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_event0_config_reg_notify_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_event0_config_reg_clear_stat_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_event0_config_reg_clear_stat_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_event0_status_reg_mul_event_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_event0_status_reg_mul_event_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_event0_status_reg_missed_count_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_event0_status_reg_missed_count_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_event0_status_reg_dir_detected_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_event0_status_reg_dir_detected_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_event0_status_reg_detected_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_event0_status_reg_detected_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_event1_config_reg_rise_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_event1_config_reg_rise_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_event1_config_reg_single_cap_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_event1_config_reg_single_cap_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_event1_config_reg_fall_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_event1_config_reg_fall_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_event1_config_reg_notify_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_event1_config_reg_notify_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_event1_config_reg_clear_stat_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_event1_config_reg_clear_stat_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_event1_status_reg_mul_event_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_event1_status_reg_mul_event_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_event1_status_reg_missed_count_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_event1_status_reg_missed_count_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_event1_status_reg_dir_detected_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_event1_status_reg_dir_detected_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_event1_status_reg_detected_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_event1_status_reg_detected_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_event0_timestamp0_reg_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_event0_timestamp0_reg_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_event0_timestamp1_reg_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_event0_timestamp1_reg_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_event0_timestamp2_reg_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_event0_timestamp2_reg_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_event0_timestamp3_reg_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_event0_timestamp3_reg_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_event0_timestamp4_reg_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_event0_timestamp4_reg_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_event1_timestamp0_reg_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_event1_timestamp0_reg_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_event1_timestamp1_reg_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_event1_timestamp1_reg_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_event1_timestamp2_reg_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_event1_timestamp2_reg_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_event1_timestamp3_reg_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_event1_timestamp3_reg_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_event1_timestamp4_reg_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_event1_timestamp4_reg_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_seqid1_reg_rx_seqid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_seqid1_reg_rx_seqid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_portid1_0_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_portid1_0_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_portid1_1_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_portid1_1_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_portid1_2_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_portid1_2_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_portid1_3_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_portid1_3_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_portid1_4_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_portid1_4_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_ts1_0_reg_rx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_ts1_0_reg_rx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_ts1_1_reg_rx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_ts1_1_reg_rx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_ts1_2_reg_rx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_ts1_2_reg_rx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_ts1_3_reg_rx_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_ts1_3_reg_rx_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_ts1_4_reg_rx_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_ts1_4_reg_rx_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_ts1_5_reg_rx_ts_nfsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_ts1_5_reg_rx_ts_nfsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_ts1_5_reg_rx_msg_type_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_ts1_5_reg_rx_msg_type_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_ts1_6_reg_rx_ts_nfsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_ts1_6_reg_rx_ts_nfsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_seqid2_reg_rx_seqid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_seqid2_reg_rx_seqid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_portid2_0_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_portid2_0_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_portid2_1_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_portid2_1_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_portid2_2_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_portid2_2_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_portid2_3_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_portid2_3_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_portid2_4_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_portid2_4_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_ts2_0_reg_rx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_ts2_0_reg_rx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_ts2_1_reg_rx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_ts2_1_reg_rx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_ts2_2_reg_rx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_ts2_2_reg_rx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_ts2_3_reg_rx_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_ts2_3_reg_rx_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_ts2_4_reg_rx_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_ts2_4_reg_rx_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_ts2_5_reg_rx_ts_nfsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_ts2_5_reg_rx_ts_nfsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_ts2_5_reg_rx_msg_type_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_ts2_5_reg_rx_msg_type_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_ts2_6_reg_rx_ts_nfsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_ts2_6_reg_rx_ts_nfsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_seqid3_reg_rx_seqid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_seqid3_reg_rx_seqid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_portid3_0_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_portid3_0_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_portid3_1_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_portid3_1_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_portid3_2_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_portid3_2_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_portid3_3_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_portid3_3_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_portid3_4_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_portid3_4_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_ts3_0_reg_rx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_ts3_0_reg_rx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_ts3_1_reg_rx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_ts3_1_reg_rx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_ts3_2_reg_rx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_ts3_2_reg_rx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_ts3_3_reg_rx_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_ts3_3_reg_rx_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_ts3_4_reg_rx_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_ts3_4_reg_rx_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_ts3_5_reg_rx_ts_nfsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_ts3_5_reg_rx_ts_nfsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_ts3_5_reg_rx_msg_type_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_ts3_5_reg_rx_msg_type_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_ts3_6_reg_rx_ts_nfsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_ts3_6_reg_rx_ts_nfsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_phase_adjust_0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_phase_adjust_0_reg_u *value); + +sw_error_t +qca808x_ptp_phase_adjust_0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_phase_adjust_0_reg_u *value); + +sw_error_t +qca808x_ptp_phase_adjust_0_reg_phase_value_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_phase_adjust_0_reg_phase_value_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_phase_adjust_1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_phase_adjust_1_reg_u *value); + +sw_error_t +qca808x_ptp_phase_adjust_1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_phase_adjust_1_reg_u *value); + +sw_error_t +qca808x_ptp_phase_adjust_1_reg_phase_value_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_phase_adjust_1_reg_phase_value_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_pps_pul_width_0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_pps_pul_width_0_reg_u *value); + +sw_error_t +qca808x_ptp_pps_pul_width_0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_pps_pul_width_0_reg_u *value); + +sw_error_t +qca808x_ptp_pps_pul_width_0_reg_pul_value_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_pps_pul_width_0_reg_pul_value_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_pps_pul_width_1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_pps_pul_width_1_reg_u *value); + +sw_error_t +qca808x_ptp_pps_pul_width_1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_pps_pul_width_1_reg_u *value); + +sw_error_t +qca808x_ptp_pps_pul_width_1_reg_pul_value_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_pps_pul_width_1_reg_pul_value_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_freq_waveform_period_0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_freq_waveform_period_0_reg_u *value); + +sw_error_t +qca808x_ptp_freq_waveform_period_0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_freq_waveform_period_0_reg_u *value); + +sw_error_t +qca808x_ptp_freq_waveform_period_0_reg_wave_period_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_freq_waveform_period_0_reg_wave_period_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_freq_waveform_period_0_reg_phase_ali_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_freq_waveform_period_0_reg_phase_ali_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_freq_waveform_period_1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_freq_waveform_period_1_reg_u *value); + +sw_error_t +qca808x_ptp_freq_waveform_period_1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_freq_waveform_period_1_reg_u *value); + +sw_error_t +qca808x_ptp_freq_waveform_period_1_reg_wave_period_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_freq_waveform_period_1_reg_wave_period_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_freq_waveform_period_2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_freq_waveform_period_2_reg_u *value); + +sw_error_t +qca808x_ptp_freq_waveform_period_2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_freq_waveform_period_2_reg_u *value); + +sw_error_t +qca808x_ptp_freq_waveform_period_2_reg_wave_period_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_freq_waveform_period_2_reg_wave_period_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_ts_ctrl_reg_u *value); + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_ts_ctrl_reg_u *value); + +sw_error_t +qca808x_ptp_rx_filt_mac_da0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_mac_da0_reg_u *value); + +sw_error_t +qca808x_ptp_rx_filt_mac_da0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_mac_da0_reg_u *value); + +sw_error_t +qca808x_ptp_rx_filt_mac_da1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_mac_da1_reg_u *value); + +sw_error_t +qca808x_ptp_rx_filt_mac_da1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_mac_da1_reg_u *value); + +sw_error_t +qca808x_ptp_rx_filt_mac_da2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_mac_da2_reg_u *value); + +sw_error_t +qca808x_ptp_rx_filt_mac_da2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_mac_da2_reg_u *value); + +sw_error_t +qca808x_ptp_rx_filt_ipv4_da0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv4_da0_reg_u *value); + +sw_error_t +qca808x_ptp_rx_filt_ipv4_da0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv4_da0_reg_u *value); + +sw_error_t +qca808x_ptp_rx_filt_ipv4_da1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv4_da1_reg_u *value); + +sw_error_t +qca808x_ptp_rx_filt_ipv4_da1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv4_da1_reg_u *value); + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv6_da0_reg_u *value); + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv6_da0_reg_u *value); + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv6_da1_reg_u *value); + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv6_da1_reg_u *value); + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv6_da2_reg_u *value); + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv6_da2_reg_u *value); + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv6_da3_reg_u *value); + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv6_da3_reg_u *value); + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv6_da4_reg_u *value); + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv6_da4_reg_u *value); + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da5_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv6_da5_reg_u *value); + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da5_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv6_da5_reg_u *value); + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da6_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv6_da6_reg_u *value); + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da6_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv6_da6_reg_u *value); + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da7_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv6_da7_reg_u *value); + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da7_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv6_da7_reg_u *value); + +sw_error_t +qca808x_ptp_rx_filt_mac_lengthtype_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_mac_lengthtype_reg_u *value); + +sw_error_t +qca808x_ptp_rx_filt_mac_lengthtype_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_mac_lengthtype_reg_u *value); + +sw_error_t +qca808x_ptp_rx_filt_layer4_protocol_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_layer4_protocol_reg_u *value); + +sw_error_t +qca808x_ptp_rx_filt_layer4_protocol_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_layer4_protocol_reg_u *value); + +sw_error_t +qca808x_ptp_rx_filt_udp_port_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_udp_port_reg_u *value); + +sw_error_t +qca808x_ptp_rx_filt_udp_port_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_udp_port_reg_u *value); + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_ts_status_reg_u *value); + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_ts_status_reg_u *value); + +sw_error_t +qca808x_ptp_rx_com_timestamp0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp0_reg_u *value); + +sw_error_t +qca808x_ptp_rx_com_timestamp0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp0_reg_u *value); + +sw_error_t +qca808x_ptp_rx_com_timestamp1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp1_reg_u *value); + +sw_error_t +qca808x_ptp_rx_com_timestamp1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp1_reg_u *value); + +sw_error_t +qca808x_ptp_rx_com_timestamp2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp2_reg_u *value); + +sw_error_t +qca808x_ptp_rx_com_timestamp2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp2_reg_u *value); + +sw_error_t +qca808x_ptp_rx_com_timestamp3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp3_reg_u *value); + +sw_error_t +qca808x_ptp_rx_com_timestamp3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp3_reg_u *value); + +sw_error_t +qca808x_ptp_rx_com_timestamp4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp4_reg_u *value); + +sw_error_t +qca808x_ptp_rx_com_timestamp4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp4_reg_u *value); + +sw_error_t +qca808x_ptp_rx_com_frac_nano_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_frac_nano_reg_u *value); + +sw_error_t +qca808x_ptp_rx_com_frac_nano_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_frac_nano_reg_u *value); + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp_pre0_reg_u *value); + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp_pre0_reg_u *value); + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp_pre1_reg_u *value); + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp_pre1_reg_u *value); + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp_pre2_reg_u *value); + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp_pre2_reg_u *value); + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp_pre3_reg_u *value); + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp_pre3_reg_u *value); + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp_pre4_reg_u *value); + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp_pre4_reg_u *value); + +sw_error_t +qca808x_ptp_rx_com_frac_nano_pre_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_frac_nano_pre_reg_u *value); + +sw_error_t +qca808x_ptp_rx_com_frac_nano_pre_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_frac_nano_pre_reg_u *value); + +sw_error_t +qca808x_ptp_rx_y1731_identify_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_y1731_identify_reg_u *value); + +sw_error_t +qca808x_ptp_rx_y1731_identify_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_y1731_identify_reg_u *value); + +sw_error_t +qca808x_ptp_rx_y1731_identify_pre_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_y1731_identify_pre_reg_u *value); + +sw_error_t +qca808x_ptp_rx_y1731_identify_pre_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_y1731_identify_pre_reg_u *value); + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_com_ts_ctrl_reg_u *value); + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_com_ts_ctrl_reg_u *value); + +sw_error_t +qca808x_ptp_tx_filt_mac_da0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_mac_da0_reg_u *value); + +sw_error_t +qca808x_ptp_tx_filt_mac_da0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_mac_da0_reg_u *value); + +sw_error_t +qca808x_ptp_tx_filt_mac_da1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_mac_da1_reg_u *value); + +sw_error_t +qca808x_ptp_tx_filt_mac_da1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_mac_da1_reg_u *value); + +sw_error_t +qca808x_ptp_tx_filt_mac_da2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_mac_da2_reg_u *value); + +sw_error_t +qca808x_ptp_tx_filt_mac_da2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_mac_da2_reg_u *value); + +sw_error_t +qca808x_ptp_tx_filt_ipv4_da0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv4_da0_reg_u *value); + +sw_error_t +qca808x_ptp_tx_filt_ipv4_da0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv4_da0_reg_u *value); + +sw_error_t +qca808x_ptp_tx_filt_ipv4_da1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv4_da1_reg_u *value); + +sw_error_t +qca808x_ptp_tx_filt_ipv4_da1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv4_da1_reg_u *value); + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv6_da0_reg_u *value); + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv6_da0_reg_u *value); + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv6_da1_reg_u *value); + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv6_da1_reg_u *value); + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv6_da2_reg_u *value); + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv6_da2_reg_u *value); + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv6_da3_reg_u *value); + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv6_da3_reg_u *value); + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv6_da4_reg_u *value); + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv6_da4_reg_u *value); + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da5_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv6_da5_reg_u *value); + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da5_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv6_da5_reg_u *value); + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da6_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv6_da6_reg_u *value); + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da6_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv6_da6_reg_u *value); + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da7_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv6_da7_reg_u *value); + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da7_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv6_da7_reg_u *value); + +sw_error_t +qca808x_ptp_tx_filt_mac_lengthtype_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_mac_lengthtype_reg_u *value); + +sw_error_t +qca808x_ptp_tx_filt_mac_lengthtype_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_mac_lengthtype_reg_u *value); + +sw_error_t +qca808x_ptp_tx_filt_layer4_protocol_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_layer4_protocol_reg_u *value); + +sw_error_t +qca808x_ptp_tx_filt_layer4_protocol_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_layer4_protocol_reg_u *value); + +sw_error_t +qca808x_ptp_tx_filt_udp_port_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_udp_port_reg_u *value); + +sw_error_t +qca808x_ptp_tx_filt_udp_port_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_udp_port_reg_u *value); + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_com_ts_status_reg_u *value); + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_com_ts_status_reg_u *value); + +sw_error_t +qca808x_ptp_tx_com_timestamp0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_com_timestamp0_reg_u *value); + +sw_error_t +qca808x_ptp_tx_com_timestamp0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_com_timestamp0_reg_u *value); + +sw_error_t +qca808x_ptp_tx_com_timestamp1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_com_timestamp1_reg_u *value); + +sw_error_t +qca808x_ptp_tx_com_timestamp1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_com_timestamp1_reg_u *value); + +sw_error_t +qca808x_ptp_tx_com_timestamp2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_com_timestamp2_reg_u *value); + +sw_error_t +qca808x_ptp_tx_com_timestamp2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_com_timestamp2_reg_u *value); + +sw_error_t +qca808x_ptp_tx_com_timestamp3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_com_timestamp3_reg_u *value); + +sw_error_t +qca808x_ptp_tx_com_timestamp3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_com_timestamp3_reg_u *value); + +sw_error_t +qca808x_ptp_tx_com_timestamp4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_com_timestamp4_reg_u *value); + +sw_error_t +qca808x_ptp_tx_com_timestamp4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_com_timestamp4_reg_u *value); + +sw_error_t +qca808x_ptp_tx_com_frac_nano_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_com_frac_nano_reg_u *value); + +sw_error_t +qca808x_ptp_tx_com_frac_nano_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_com_frac_nano_reg_u *value); + +sw_error_t +qca808x_ptp_tx_y1731_identify_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_y1731_identify_reg_u *value); + +sw_error_t +qca808x_ptp_tx_y1731_identify_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_y1731_identify_reg_u *value); + +sw_error_t +qca808x_ptp_y1731_dm_control_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_y1731_dm_control_reg_u *value); + +sw_error_t +qca808x_ptp_y1731_dm_control_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_y1731_dm_control_reg_u *value); + +sw_error_t +qca808x_ptp_rx_com_ts_status_pre_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_ts_status_pre_reg_u *value); + +sw_error_t +qca808x_ptp_rx_com_ts_status_pre_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_ts_status_pre_reg_u *value); + +sw_error_t +qca808x_ptp_baud_config_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_baud_config_reg_u *value); + +sw_error_t +qca808x_ptp_baud_config_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_baud_config_reg_u *value); + +sw_error_t +qca808x_ptp_uart_configuration_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_uart_configuration_reg_u *value); + +sw_error_t +qca808x_ptp_uart_configuration_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_uart_configuration_reg_u *value); + +sw_error_t +qca808x_ptp_reset_buffer_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_reset_buffer_reg_u *value); + +sw_error_t +qca808x_ptp_reset_buffer_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_reset_buffer_reg_u *value); + +sw_error_t +qca808x_ptp_buffer_status_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_buffer_status_reg_u *value); + +sw_error_t +qca808x_ptp_buffer_status_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_buffer_status_reg_u *value); + +sw_error_t +qca808x_ptp_tx_buffer_write_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_buffer_write_reg_u *value); + +sw_error_t +qca808x_ptp_tx_buffer_write_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_buffer_write_reg_u *value); + +sw_error_t +qca808x_ptp_rx_buffer_read_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_buffer_read_reg_u *value); + +sw_error_t +qca808x_ptp_rx_buffer_read_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_buffer_read_reg_u *value); + + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_ipv4_da_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_ipv4_da_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_mac_lengthtype_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_mac_lengthtype_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_y1731_da_chk_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_y1731_da_chk_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_pw_mac_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_pw_mac_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_udp_ptp_event_filt_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_udp_ptp_event_filt_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_udp_dport_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_udp_dport_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_mac_ptp_filt_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_mac_ptp_filt_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_ipv6_da_filt_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_ipv6_da_filt_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_ipv6_next_header_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_ipv6_next_header_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_ipv4_layer4_protocol_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_ipv4_layer4_protocol_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_y1731_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_y1731_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_filt_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_filt_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_ipv6_ptp_filt_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_ipv6_ptp_filt_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_ipv4_ptp_filt_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_ipv4_ptp_filt_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_y1731_insert_ts_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_y1731_insert_ts_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_mac_da_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_mac_da_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_filt_mac_da0_reg_mac_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_filt_mac_da0_reg_mac_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_filt_mac_da1_reg_mac_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_filt_mac_da1_reg_mac_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_filt_mac_da2_reg_mac_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_filt_mac_da2_reg_mac_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_filt_ipv4_da0_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_filt_ipv4_da0_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_filt_ipv4_da1_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_filt_ipv4_da1_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da0_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da0_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da1_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da1_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da2_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da2_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da3_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da3_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da4_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da4_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da5_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da5_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da6_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da6_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da7_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da7_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_filt_mac_lengthtype_reg_length_type_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_filt_mac_lengthtype_reg_length_type_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_filt_layer4_protocol_reg_l4_protocol_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_filt_layer4_protocol_reg_l4_protocol_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_filt_udp_port_reg_udp_port_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_filt_udp_port_reg_udp_port_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_mac_ptp_pdelay_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_mac_ptp_pdelay_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_mac_da_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_mac_da_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_ipv4_ptp_pdelay_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_ipv4_ptp_pdelay_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_mac_lengthtype_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_mac_lengthtype_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_udp_dport_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_udp_dport_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_ipv4_layer4_protocol_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_ipv4_layer4_protocol_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_udp_ptp_event_dport_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_udp_ptp_event_dport_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_ipv6_da_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_ipv6_da_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_ipv4_ptp_prim_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_ipv4_ptp_prim_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_ipv4_da_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_ipv4_da_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_ipv6_ptp_pdelay_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_ipv6_ptp_pdelay_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_ipv6_ptp_prim_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_ipv6_ptp_prim_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_ipv6_next_header_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_ipv6_next_header_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_y1731_mach_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_y1731_mach_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_mac_ptp_prim_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_mac_ptp_prim_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_timestamp0_reg_com_ts_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_timestamp0_reg_com_ts_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_timestamp1_reg_com_ts_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_timestamp1_reg_com_ts_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_timestamp2_reg_com_ts_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_timestamp2_reg_com_ts_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_timestamp3_reg_com_ts_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_timestamp3_reg_com_ts_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_timestamp4_reg_com_ts_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_timestamp4_reg_com_ts_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_frac_nano_reg_frac_nano_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_frac_nano_reg_frac_nano_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre0_reg_com_ts_pre_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre0_reg_com_ts_pre_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre1_reg_com_ts_pre_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre1_reg_com_ts_pre_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre2_reg_com_ts_pre_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre2_reg_com_ts_pre_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre3_reg_com_ts_pre_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre3_reg_com_ts_pre_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre4_reg_com_ts_pre_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre4_reg_com_ts_pre_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_com_frac_nano_pre_reg_frac_nano_pre_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_com_frac_nano_pre_reg_frac_nano_pre_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_y1731_identify_reg_identify_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_y1731_identify_reg_identify_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_y1731_identify_pre_reg_identify_pre_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_y1731_identify_pre_reg_identify_pre_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_ipv4_da_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_ipv4_da_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_mac_lengthtype_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_mac_lengthtype_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_ipv6_da_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_ipv6_da_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_pw_mac_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_pw_mac_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_udp_ptp_event_filt_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_udp_ptp_event_filt_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_udp_dport_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_udp_dport_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_mac_ptp_filt_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_mac_ptp_filt_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_ipv6_next_header_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_ipv6_next_header_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_ipv4_layer4_protocol_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_ipv4_layer4_protocol_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_y1731_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_y1731_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_filt_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_filt_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_ipv6_ptp_filt_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_ipv6_ptp_filt_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_ipv4_ptp_filt_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_ipv4_ptp_filt_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_y1731_insert_ts_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_y1731_insert_ts_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_mac_da_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_mac_da_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_y1731_sa_chk_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_y1731_sa_chk_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_filt_mac_da0_reg_mac_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_filt_mac_da0_reg_mac_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_filt_mac_da1_reg_mac_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_filt_mac_da1_reg_mac_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_filt_mac_da2_reg_mac_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_filt_mac_da2_reg_mac_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_filt_ipv4_da0_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_filt_ipv4_da0_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_filt_ipv4_da1_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_filt_ipv4_da1_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da0_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da0_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da1_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da1_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da2_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da2_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da3_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da3_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da4_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da4_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da5_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da5_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da6_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da6_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da7_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da7_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_filt_mac_lengthtype_reg_length_type_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_filt_mac_lengthtype_reg_length_type_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_filt_layer4_protocol_reg_l4_protocol_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_filt_layer4_protocol_reg_l4_protocol_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_filt_udp_port_reg_udp_port_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_filt_udp_port_reg_udp_port_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_mac_ptp_pdelay_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_mac_ptp_pdelay_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_mac_da_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_mac_da_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_ipv4_ptp_pdelay_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_ipv4_ptp_pdelay_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_mac_lengthtype_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_mac_lengthtype_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_udp_dport_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_udp_dport_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_ipv4_layer4_protocol_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_ipv4_layer4_protocol_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_udp_ptp_event_dport_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_udp_ptp_event_dport_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_ipv6_da_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_ipv6_da_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_ipv4_ptp_prim_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_ipv4_ptp_prim_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_ipv4_da_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_ipv4_da_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_ipv6_ptp_pdelay_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_ipv6_ptp_pdelay_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_ipv6_ptp_prim_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_ipv6_ptp_prim_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_ipv6_next_header_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_ipv6_next_header_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_y1731_mach_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_y1731_mach_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_mac_ptp_prim_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_mac_ptp_prim_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_timestamp0_reg_com_ts_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_timestamp0_reg_com_ts_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_timestamp1_reg_com_ts_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_timestamp1_reg_com_ts_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_timestamp2_reg_com_ts_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_timestamp2_reg_com_ts_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_timestamp3_reg_com_ts_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_timestamp3_reg_com_ts_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_timestamp4_reg_com_ts_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_timestamp4_reg_com_ts_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_com_frac_nano_reg_frac_nano_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_com_frac_nano_reg_frac_nano_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_y1731_identify_reg_identify_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_y1731_identify_reg_identify_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_y1731_dm_control_reg_y1731_dmm_lpbk_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_y1731_dm_control_reg_y1731_dmm_lpbk_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_y1731_dm_control_reg_valid_msg_lev_bmp_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_y1731_dm_control_reg_valid_msg_lev_bmp_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_baud_config_reg_baud_rate_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_baud_config_reg_baud_rate_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_uart_configuration_reg_start_polarity_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_uart_configuration_reg_start_polarity_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_uart_configuration_reg_msb_first_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_uart_configuration_reg_msb_first_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_uart_configuration_reg_parity_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_uart_configuration_reg_parity_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_uart_configuration_reg_auto_tod_out_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_uart_configuration_reg_auto_tod_out_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_uart_configuration_reg_auto_tod_in_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_uart_configuration_reg_auto_tod_in_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_reset_buffer_reg_reset_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_reset_buffer_reg_reset_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_buffer_status_reg_tx_buffer_almost_empty_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_buffer_status_reg_tx_buffer_almost_empty_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_buffer_status_reg_tx_buffer_almost_full_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_buffer_status_reg_tx_buffer_almost_full_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_buffer_status_reg_tx_buffer_half_full_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_buffer_status_reg_tx_buffer_half_full_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_buffer_status_reg_tx_buffer_full_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_buffer_status_reg_tx_buffer_full_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_buffer_status_reg_rx_buffer_almost_empty_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_buffer_status_reg_rx_buffer_almost_empty_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_buffer_status_reg_rx_buffer_almost_full_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_buffer_status_reg_rx_buffer_almost_full_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_buffer_status_reg_rx_buffer_half_full_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_buffer_status_reg_rx_buffer_half_full_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_buffer_status_reg_rx_buffer_full_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_buffer_status_reg_rx_buffer_full_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_buffer_status_reg_rx_buffer_data_present_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_buffer_status_reg_rx_buffer_data_present_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_tx_buffer_write_reg_tx_buffer_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_tx_buffer_write_reg_tx_buffer_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_buffer_read_reg_rx_data_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_buffer_read_reg_rx_data_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_buffer_read_reg_rx_buffer_almost_empty_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_buffer_read_reg_rx_buffer_almost_empty_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_buffer_read_reg_rx_buffer_almost_full_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_buffer_read_reg_rx_buffer_almost_full_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_buffer_read_reg_rx_buffer_half_full_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_buffer_read_reg_rx_buffer_half_full_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_buffer_read_reg_rx_buffer_full_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_buffer_read_reg_rx_buffer_full_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_rx_buffer_read_reg_rx_buffer_data_present_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_rx_buffer_read_reg_rx_buffer_data_present_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_loc_mac_addr_0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_loc_mac_addr_0_reg_u *value); + +sw_error_t +qca808x_ptp_loc_mac_addr_0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_loc_mac_addr_0_reg_u *value); + +sw_error_t +qca808x_ptp_loc_mac_addr_1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_loc_mac_addr_1_reg_u *value); + +sw_error_t +qca808x_ptp_loc_mac_addr_1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_loc_mac_addr_1_reg_u *value); + +sw_error_t +qca808x_ptp_loc_mac_addr_2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_loc_mac_addr_2_reg_u *value); + +sw_error_t +qca808x_ptp_loc_mac_addr_2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_loc_mac_addr_2_reg_u *value); + +sw_error_t +qca808x_ptp_loc_mac_addr_0_reg_mac_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_loc_mac_addr_0_reg_mac_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_loc_mac_addr_1_reg_mac_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_loc_mac_addr_1_reg_mac_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_loc_mac_addr_2_reg_mac_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_loc_mac_addr_2_reg_mac_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_link_delay_0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_link_delay_0_reg_u *value); + +sw_error_t +qca808x_ptp_link_delay_0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_link_delay_0_reg_u *value); + +sw_error_t +qca808x_ptp_link_delay_1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_link_delay_1_reg_u *value); + +sw_error_t +qca808x_ptp_link_delay_1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_link_delay_1_reg_u *value); + +sw_error_t +qca808x_ptp_link_delay_0_reg_link_delay_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_link_delay_0_reg_link_delay_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_link_delay_1_reg_link_delay_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value); + +sw_error_t +qca808x_ptp_link_delay_1_reg_link_delay_set( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int value); + +sw_error_t +qca808x_ptp_misc_control_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_misc_control_reg_u *value); + +sw_error_t +qca808x_ptp_misc_control_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_misc_control_reg_u *value); + +sw_error_t +qca808x_ptp_ingress_asymmetry_0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ingress_asymmetry_0_reg_u *value); + +sw_error_t +qca808x_ptp_ingress_asymmetry_0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ingress_asymmetry_0_reg_u *value); + +sw_error_t +qca808x_ptp_ingress_asymmetry_1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ingress_asymmetry_1_reg_u *value); + +sw_error_t +qca808x_ptp_ingress_asymmetry_1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ingress_asymmetry_1_reg_u *value); + +sw_error_t +qca808x_ptp_egress_asymmetry_0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_egress_asymmetry_0_reg_u *value); + +sw_error_t +qca808x_ptp_egress_asymmetry_0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_egress_asymmetry_0_reg_u *value); + +sw_error_t +qca808x_ptp_egress_asymmetry_1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_egress_asymmetry_1_reg_u *value); + +sw_error_t +qca808x_ptp_egress_asymmetry_1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_egress_asymmetry_1_reg_u *value); + +sw_error_t +qca808x_ptp_backup_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_backup_reg_u *value); + +sw_error_t +qca808x_ptp_backup_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_backup_reg_u *value); + +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/qca808x_ptp_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/qca808x_ptp_reg.h new file mode 100755 index 000000000..4e8c4c0a4 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/qca808x_ptp_reg.h @@ -0,0 +1,5853 @@ +/* + * 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. + */ + + +/** + * @defgroup + * @{ + */ +#ifndef PTP_REG_REG_H +#define PTP_REG_REG_H + +#define PTP_REG_BIT_FALSE 0 +#define PTP_REG_BIT_TRUE 1 + +/*[register] PTP_IMR_REG*/ +#define PTP_IMR_REG +#define PTP_IMR_REG_ADDRESS 0x12 +#define PTP_IMR_REG_NUM 1 +#define PTP_IMR_REG_INC 0x1 +#define PTP_IMR_REG_TYPE REG_TYPE_RW +#define PTP_IMR_REG_DEFAULT 0x0 + /*[field] MASK_BMP*/ + #define PTP_IMR_REG_MASK_BMP + #define PTP_IMR_REG_MASK_BMP_OFFSET 0 + #define PTP_IMR_REG_MASK_BMP_LEN 16 + #define PTP_IMR_REG_MASK_BMP_DEFAULT 0x0 + +struct ptp_imr_reg { + a_uint16_t mask_bmp:16; +}; + +union ptp_imr_reg_u { + a_uint32_t val; + struct ptp_imr_reg bf; +}; + +/*[register] PTP_ISR_REG*/ +#define PTP_ISR_REG +#define PTP_ISR_REG_ADDRESS 0x13 +#define PTP_ISR_REG_NUM 1 +#define PTP_ISR_REG_INC 0x1 +#define PTP_ISR_REG_TYPE REG_TYPE_RW +#define PTP_ISR_REG_DEFAULT 0x0 + /*[field] STATUS_BMP*/ + #define PTP_ISR_REG_STATUS_BMP + #define PTP_ISR_REG_STATUS_BMP_OFFSET 0 + #define PTP_ISR_REG_STATUS_BMP_LEN 16 + #define PTP_ISR_REG_STATUS_BMP_DEFAULT 0x0 + +struct ptp_isr_reg { + a_uint16_t status_bmp:16; +}; + +union ptp_isr_reg_u { + a_uint32_t val; + struct ptp_isr_reg bf; +}; + +/*[register] PTP_HW_ENABLE_REG*/ +#define PTP_HW_ENABLE_REG +#define PTP_HW_ENABLE_REG_ADDRESS 0x1f +#define PTP_HW_ENABLE_REG_NUM 1 +#define PTP_HW_ENABLE_REG_INC 0x1 +#define PTP_HW_ENABLE_REG_TYPE REG_TYPE_RW +#define PTP_HW_ENABLE_REG_DEFAULT 0x0 + /*[field] PTP_HW_ENABLE*/ + #define PTP_HW_ENABLE_REG_PTP_HW_ENABLE + #define PTP_HW_ENABLE_REG_PTP_HW_ENABLE_OFFSET 1 + #define PTP_HW_ENABLE_REG_PTP_HW_ENABLE_LEN 1 + #define PTP_HW_ENABLE_REG_PTP_HW_ENABLE_DEFAULT 0x0 + +struct ptp_hw_enable_reg { + a_uint16_t _reserved0:1; + a_uint16_t ptp_hw_enable:1; +}; + +union ptp_hw_enable_reg_u { + a_uint32_t val; + struct ptp_hw_enable_reg bf; +}; + +/*[register] PTP_MAIN_CONF_REG*/ +#define PTP_MAIN_CONF_REG +#define PTP_MAIN_CONF_REG_ADDRESS 0x8012 +#define PTP_MAIN_CONF_REG_NUM 1 +#define PTP_MAIN_CONF_REG_INC 0x1 +#define PTP_MAIN_CONF_REG_TYPE REG_TYPE_RW +#define PTP_MAIN_CONF_REG_DEFAULT 0x0 + /*[field] PTP_CLOCK_MODE*/ + #define PTP_MAIN_CONF_REG_PTP_CLOCK_MODE + #define PTP_MAIN_CONF_REG_PTP_CLOCK_MODE_OFFSET 1 + #define PTP_MAIN_CONF_REG_PTP_CLOCK_MODE_LEN 2 + #define PTP_MAIN_CONF_REG_PTP_CLOCK_MODE_DEFAULT 0x0 + #define PTP_MAIN_CONF_REG_PTP_CLOCK_MODE_OC_TWO_STEP 0x0 + #define PTP_MAIN_CONF_REG_PTP_CLOCK_MODE_OC_ONE_STEP 0x1 + #define PTP_MAIN_CONF_REG_PTP_CLOCK_MODE_TC_TWO_STEP 0x2 + #define PTP_MAIN_CONF_REG_PTP_CLOCK_MODE_TC_ONE_STEP 0x3 + /*[field] PTP_BYPASS*/ + #define PTP_MAIN_CONF_REG_PTP_BYPASS + #define PTP_MAIN_CONF_REG_PTP_BYPASS_OFFSET 3 + #define PTP_MAIN_CONF_REG_PTP_BYPASS_LEN 1 + #define PTP_MAIN_CONF_REG_PTP_BYPASS_DEFAULT 0x0 + /*[field] TS_ATTACH_MODE*/ + #define PTP_MAIN_CONF_REG_TS_ATTACH_MODE + #define PTP_MAIN_CONF_REG_TS_ATTACH_MODE_OFFSET 4 + #define PTP_MAIN_CONF_REG_TS_ATTACH_MODE_LEN 1 + #define PTP_MAIN_CONF_REG_TS_ATTACH_MODE_DEFAULT 0x0 + /*[field] WOL_EN*/ + #define PTP_MAIN_CONF_REG_WOL_EN + #define PTP_MAIN_CONF_REG_WOL_EN_OFFSET 5 + #define PTP_MAIN_CONF_REG_WOL_EN_LEN 1 + #define PTP_MAIN_CONF_REG_WOL_EN_DEFAULT 0x0 + /*[field] PTP_CLK_SEL*/ + #define PTP_MAIN_CONF_REG_PTP_CLK_SEL + #define PTP_MAIN_CONF_REG_PTP_CLK_SEL_OFFSET 7 + #define PTP_MAIN_CONF_REG_PTP_CLK_SEL_LEN 1 + #define PTP_MAIN_CONF_REG_PTP_CLK_SEL_DEFAULT 0x0 + /*[field] DISABLE_1588_PHY*/ + #define PTP_MAIN_CONF_REG_DISABLE_1588_PHY + #define PTP_MAIN_CONF_REG_DISABLE_1588_PHY_OFFSET 8 + #define PTP_MAIN_CONF_REG_DISABLE_1588_PHY_LEN 1 + #define PTP_MAIN_CONF_REG_DISABLE_1588_PHY_DEFAULT 0x0 + /*[field] ATTACH_CRC_RECAL*/ + #define PTP_MAIN_CONF_REG_ATTACH_CRC_RECAL + #define PTP_MAIN_CONF_REG_ATTACH_CRC_RECAL_OFFSET 9 + #define PTP_MAIN_CONF_REG_ATTACH_CRC_RECAL_LEN 1 + #define PTP_MAIN_CONF_REG_ATTACH_CRC_RECAL_DEFAULT 0x0 + /*[field] IPV4_FORCE_CHECKSUM_ZERO*/ + #define PTP_MAIN_CONF_REG_IPV4_FORCE_CHECKSUM_ZERO + #define PTP_MAIN_CONF_REG_IPV4_FORCE_CHECKSUM_ZERO_OFFSET 10 + #define PTP_MAIN_CONF_REG_IPV4_FORCE_CHECKSUM_ZERO_LEN 1 + #define PTP_MAIN_CONF_REG_IPV4_FORCE_CHECKSUM_ZERO_DEFAULT 0x1 + /*[field] IPV6_EMBED_FORCE_CHECKSUM_ZERO*/ + #define PTP_MAIN_CONF_REG_IPV6_EMBED_FORCE_CHECKSUM_ZERO + #define PTP_MAIN_CONF_REG_IPV6_EMBED_FORCE_CHECKSUM_ZERO_OFFSET 11 + #define PTP_MAIN_CONF_REG_IPV6_EMBED_FORCE_CHECKSUM_ZERO_LEN 1 + #define PTP_MAIN_CONF_REG_IPV6_EMBED_FORCE_CHECKSUM_ZERO_DEFAULT 0x0 + +struct ptp_main_conf_reg { + a_uint16_t _reserved0:1; + a_uint16_t ptp_clock_mode:2; + a_uint16_t ptp_bypass:1; + a_uint16_t ts_attach_mode:1; + a_uint16_t wol_en:1; + a_uint16_t _reserved1:1; + a_uint16_t ptp_clk_sel:1; + a_uint16_t disable_1588_phy:1; + a_uint16_t attach_crc_recal:1; + a_uint16_t ipv4_force_checksum_zero:1; + a_uint16_t ipv6_embed_force_checksum_zero:1; +}; + +union ptp_main_conf_reg_u { + a_uint32_t val; + struct ptp_main_conf_reg bf; +}; + +/*[register] PTP_RX_SEQID0_REG*/ +#define PTP_RX_SEQID0_REG +#define PTP_RX_SEQID0_REG_ADDRESS 0x8013 +#define PTP_RX_SEQID0_REG_NUM 1 +#define PTP_RX_SEQID0_REG_INC 0x1 +#define PTP_RX_SEQID0_REG_TYPE REG_TYPE_RW +#define PTP_RX_SEQID0_REG_DEFAULT 0x0 + /*[field] RX_SEQID*/ + #define PTP_RX_SEQID0_REG_RX_SEQID + #define PTP_RX_SEQID0_REG_RX_SEQID_OFFSET 0 + #define PTP_RX_SEQID0_REG_RX_SEQID_LEN 16 + #define PTP_RX_SEQID0_REG_RX_SEQID_DEFAULT 0x0 + +struct ptp_rx_seqid0_reg { + a_uint16_t rx_seqid:16; +}; + +union ptp_rx_seqid0_reg_u { + a_uint32_t val; + struct ptp_rx_seqid0_reg bf; +}; + +/*[register] PTP_RX_PORTID0_0_REG*/ +#define PTP_RX_PORTID0_0_REG +#define PTP_RX_PORTID0_0_REG_ADDRESS 0x8014 +#define PTP_RX_PORTID0_0_REG_NUM 1 +#define PTP_RX_PORTID0_0_REG_INC 0x1 +#define PTP_RX_PORTID0_0_REG_TYPE REG_TYPE_RW +#define PTP_RX_PORTID0_0_REG_DEFAULT 0x0 + /*[field] RX_PORTID*/ + #define PTP_RX_PORTID0_0_REG_RX_PORTID + #define PTP_RX_PORTID0_0_REG_RX_PORTID_OFFSET 0 + #define PTP_RX_PORTID0_0_REG_RX_PORTID_LEN 16 + #define PTP_RX_PORTID0_0_REG_RX_PORTID_DEFAULT 0x0 + +struct ptp_rx_portid0_0_reg { + a_uint16_t rx_portid:16; +}; + +union ptp_rx_portid0_0_reg_u { + a_uint32_t val; + struct ptp_rx_portid0_0_reg bf; +}; + +/*[register] PTP_RX_PORTID0_1_REG*/ +#define PTP_RX_PORTID0_1_REG +#define PTP_RX_PORTID0_1_REG_ADDRESS 0x8015 +#define PTP_RX_PORTID0_1_REG_NUM 1 +#define PTP_RX_PORTID0_1_REG_INC 0x1 +#define PTP_RX_PORTID0_1_REG_TYPE REG_TYPE_RW +#define PTP_RX_PORTID0_1_REG_DEFAULT 0x0 + /*[field] RX_PORTID*/ + #define PTP_RX_PORTID0_1_REG_RX_PORTID + #define PTP_RX_PORTID0_1_REG_RX_PORTID_OFFSET 0 + #define PTP_RX_PORTID0_1_REG_RX_PORTID_LEN 16 + #define PTP_RX_PORTID0_1_REG_RX_PORTID_DEFAULT 0x0 + +struct ptp_rx_portid0_1_reg { + a_uint16_t rx_portid:16; +}; + +union ptp_rx_portid0_1_reg_u { + a_uint32_t val; + struct ptp_rx_portid0_1_reg bf; +}; + +/*[register] PTP_RX_PORTID0_2_REG*/ +#define PTP_RX_PORTID0_2_REG +#define PTP_RX_PORTID0_2_REG_ADDRESS 0x8016 +#define PTP_RX_PORTID0_2_REG_NUM 1 +#define PTP_RX_PORTID0_2_REG_INC 0x1 +#define PTP_RX_PORTID0_2_REG_TYPE REG_TYPE_RW +#define PTP_RX_PORTID0_2_REG_DEFAULT 0x0 + /*[field] RX_PORTID*/ + #define PTP_RX_PORTID0_2_REG_RX_PORTID + #define PTP_RX_PORTID0_2_REG_RX_PORTID_OFFSET 0 + #define PTP_RX_PORTID0_2_REG_RX_PORTID_LEN 16 + #define PTP_RX_PORTID0_2_REG_RX_PORTID_DEFAULT 0x0 + +struct ptp_rx_portid0_2_reg { + a_uint16_t rx_portid:16; +}; + +union ptp_rx_portid0_2_reg_u { + a_uint32_t val; + struct ptp_rx_portid0_2_reg bf; +}; + +/*[register] PTP_RX_PORTID0_3_REG*/ +#define PTP_RX_PORTID0_3_REG +#define PTP_RX_PORTID0_3_REG_ADDRESS 0x8017 +#define PTP_RX_PORTID0_3_REG_NUM 1 +#define PTP_RX_PORTID0_3_REG_INC 0x1 +#define PTP_RX_PORTID0_3_REG_TYPE REG_TYPE_RW +#define PTP_RX_PORTID0_3_REG_DEFAULT 0x0 + /*[field] RX_PORTID*/ + #define PTP_RX_PORTID0_3_REG_RX_PORTID + #define PTP_RX_PORTID0_3_REG_RX_PORTID_OFFSET 0 + #define PTP_RX_PORTID0_3_REG_RX_PORTID_LEN 16 + #define PTP_RX_PORTID0_3_REG_RX_PORTID_DEFAULT 0x0 + +struct ptp_rx_portid0_3_reg { + a_uint16_t rx_portid:16; +}; + +union ptp_rx_portid0_3_reg_u { + a_uint32_t val; + struct ptp_rx_portid0_3_reg bf; +}; + +/*[register] PTP_RX_PORTID0_4_REG*/ +#define PTP_RX_PORTID0_4_REG +#define PTP_RX_PORTID0_4_REG_ADDRESS 0x8018 +#define PTP_RX_PORTID0_4_REG_NUM 1 +#define PTP_RX_PORTID0_4_REG_INC 0x1 +#define PTP_RX_PORTID0_4_REG_TYPE REG_TYPE_RW +#define PTP_RX_PORTID0_4_REG_DEFAULT 0x0 + /*[field] RX_PORTID*/ + #define PTP_RX_PORTID0_4_REG_RX_PORTID + #define PTP_RX_PORTID0_4_REG_RX_PORTID_OFFSET 0 + #define PTP_RX_PORTID0_4_REG_RX_PORTID_LEN 16 + #define PTP_RX_PORTID0_4_REG_RX_PORTID_DEFAULT 0x0 + +struct ptp_rx_portid0_4_reg { + a_uint16_t rx_portid:16; +}; + +union ptp_rx_portid0_4_reg_u { + a_uint32_t val; + struct ptp_rx_portid0_4_reg bf; +}; + + +// +/*[register] PTP_RTC_CLK_REG*/ +#define PTP_RTC_CLK_REG +#define PTP_RTC_CLK_REG_ADDRESS 0x8017 +#define PTP_RTC_CLK_REG_NUM 1 +#define PTP_RTC_CLK_REG_INC 0x1 +#define PTP_RTC_CLK_REG_TYPE REG_TYPE_RW +#define PTP_RTC_CLK_REG_DEFAULT 0x0 + /*[field] RTC_CLK_SELECTION*/ + #define PTP_RTC_CLK_REG_RTC_CLK_SELECTION + #define PTP_RTC_CLK_REG_RTC_CLK_SELECTION_OFFSET 11 + #define PTP_RTC_CLK_REG_RTC_CLK_SELECTION_LEN 1 + #define PTP_RTC_CLK_REG_RTC_CLK_SELECTION_DEFAULT 0x0 + +struct ptp_rtc_clk_reg { + a_uint16_t _reserved0:11; + a_uint16_t rtc_clk_selection:1; +}; + +union ptp_rtc_clk_reg_u { + a_uint32_t val; + struct ptp_rtc_clk_reg bf; +}; + +/*[register] PTP_RX_TS0_0_REG*/ +#define PTP_RX_TS0_0_REG +#define PTP_RX_TS0_0_REG_ADDRESS 0x8019 +#define PTP_RX_TS0_0_REG_NUM 1 +#define PTP_RX_TS0_0_REG_INC 0x1 +#define PTP_RX_TS0_0_REG_TYPE REG_TYPE_RW +#define PTP_RX_TS0_0_REG_DEFAULT 0x0 + /*[field] RX_TS_SEC*/ + #define PTP_RX_TS0_0_REG_RX_TS_SEC + #define PTP_RX_TS0_0_REG_RX_TS_SEC_OFFSET 0 + #define PTP_RX_TS0_0_REG_RX_TS_SEC_LEN 16 + #define PTP_RX_TS0_0_REG_RX_TS_SEC_DEFAULT 0x0 + +struct ptp_rx_ts0_0_reg { + a_uint16_t rx_ts_sec:16; +}; + +union ptp_rx_ts0_0_reg_u { + a_uint32_t val; + struct ptp_rx_ts0_0_reg bf; +}; + +/*[register] PTP_RX_TS0_1_REG*/ +#define PTP_RX_TS0_1_REG +#define PTP_RX_TS0_1_REG_ADDRESS 0x801a +#define PTP_RX_TS0_1_REG_NUM 1 +#define PTP_RX_TS0_1_REG_INC 0x1 +#define PTP_RX_TS0_1_REG_TYPE REG_TYPE_RW +#define PTP_RX_TS0_1_REG_DEFAULT 0x0 + /*[field] RX_TS_SEC*/ + #define PTP_RX_TS0_1_REG_RX_TS_SEC + #define PTP_RX_TS0_1_REG_RX_TS_SEC_OFFSET 0 + #define PTP_RX_TS0_1_REG_RX_TS_SEC_LEN 16 + #define PTP_RX_TS0_1_REG_RX_TS_SEC_DEFAULT 0x0 + +struct ptp_rx_ts0_1_reg { + a_uint16_t rx_ts_sec:16; +}; + +union ptp_rx_ts0_1_reg_u { + a_uint32_t val; + struct ptp_rx_ts0_1_reg bf; +}; + +/*[register] PTP_RX_TS0_2_REG*/ +#define PTP_RX_TS0_2_REG +#define PTP_RX_TS0_2_REG_ADDRESS 0x801b +#define PTP_RX_TS0_2_REG_NUM 1 +#define PTP_RX_TS0_2_REG_INC 0x1 +#define PTP_RX_TS0_2_REG_TYPE REG_TYPE_RW +#define PTP_RX_TS0_2_REG_DEFAULT 0x0 + /*[field] RX_TS_SEC*/ + #define PTP_RX_TS0_2_REG_RX_TS_SEC + #define PTP_RX_TS0_2_REG_RX_TS_SEC_OFFSET 0 + #define PTP_RX_TS0_2_REG_RX_TS_SEC_LEN 16 + #define PTP_RX_TS0_2_REG_RX_TS_SEC_DEFAULT 0x0 + +struct ptp_rx_ts0_2_reg { + a_uint16_t rx_ts_sec:16; +}; + +union ptp_rx_ts0_2_reg_u { + a_uint32_t val; + struct ptp_rx_ts0_2_reg bf; +}; + +/*[register] PTP_RX_TS0_3_REG*/ +#define PTP_RX_TS0_3_REG +#define PTP_RX_TS0_3_REG_ADDRESS 0x801c +#define PTP_RX_TS0_3_REG_NUM 1 +#define PTP_RX_TS0_3_REG_INC 0x1 +#define PTP_RX_TS0_3_REG_TYPE REG_TYPE_RW +#define PTP_RX_TS0_3_REG_DEFAULT 0x0 + /*[field] RX_TS_NSEC*/ + #define PTP_RX_TS0_3_REG_RX_TS_NSEC + #define PTP_RX_TS0_3_REG_RX_TS_NSEC_OFFSET 0 + #define PTP_RX_TS0_3_REG_RX_TS_NSEC_LEN 16 + #define PTP_RX_TS0_3_REG_RX_TS_NSEC_DEFAULT 0x0 + +struct ptp_rx_ts0_3_reg { + a_uint16_t rx_ts_nsec:16; +}; + +union ptp_rx_ts0_3_reg_u { + a_uint32_t val; + struct ptp_rx_ts0_3_reg bf; +}; + +/*[register] PTP_RX_TS0_4_REG*/ +#define PTP_RX_TS0_4_REG +#define PTP_RX_TS0_4_REG_ADDRESS 0x801d +#define PTP_RX_TS0_4_REG_NUM 1 +#define PTP_RX_TS0_4_REG_INC 0x1 +#define PTP_RX_TS0_4_REG_TYPE REG_TYPE_RW +#define PTP_RX_TS0_4_REG_DEFAULT 0x0 + /*[field] RX_TS_NSEC*/ + #define PTP_RX_TS0_4_REG_RX_TS_NSEC + #define PTP_RX_TS0_4_REG_RX_TS_NSEC_OFFSET 0 + #define PTP_RX_TS0_4_REG_RX_TS_NSEC_LEN 16 + #define PTP_RX_TS0_4_REG_RX_TS_NSEC_DEFAULT 0x0 + +struct ptp_rx_ts0_4_reg { + a_uint16_t rx_ts_nsec:16; +}; + +union ptp_rx_ts0_4_reg_u { + a_uint32_t val; + struct ptp_rx_ts0_4_reg bf; +}; + +/*[register] PTP_RX_TS0_5_REG*/ +#define PTP_RX_TS0_5_REG +#define PTP_RX_TS0_5_REG_ADDRESS 0x801e +#define PTP_RX_TS0_5_REG_NUM 1 +#define PTP_RX_TS0_5_REG_INC 0x1 +#define PTP_RX_TS0_5_REG_TYPE REG_TYPE_RW +#define PTP_RX_TS0_5_REG_DEFAULT 0x0 + /*[field] RX_TS_NFSEC*/ + #define PTP_RX_TS0_5_REG_RX_TS_NFSEC + #define PTP_RX_TS0_5_REG_RX_TS_NFSEC_OFFSET 0 + #define PTP_RX_TS0_5_REG_RX_TS_NFSEC_LEN 12 + #define PTP_RX_TS0_5_REG_RX_TS_NFSEC_DEFAULT 0x0 + /*[field] RX_MSG_TYPE*/ + #define PTP_RX_TS0_5_REG_RX_MSG_TYPE + #define PTP_RX_TS0_5_REG_RX_MSG_TYPE_OFFSET 12 + #define PTP_RX_TS0_5_REG_RX_MSG_TYPE_LEN 4 + #define PTP_RX_TS0_5_REG_RX_MSG_TYPE_DEFAULT 0x0 + +struct ptp_rx_ts0_5_reg { + a_uint16_t rx_ts_nfsec:12; + a_uint16_t rx_msg_type:4; +}; + +union ptp_rx_ts0_5_reg_u { + a_uint32_t val; + struct ptp_rx_ts0_5_reg bf; +}; + +/*[register] PTP_RX_TS0_6_REG*/ +#define PTP_RX_TS0_6_REG +#define PTP_RX_TS0_6_REG_ADDRESS 0x801f +#define PTP_RX_TS0_6_REG_NUM 1 +#define PTP_RX_TS0_6_REG_INC 0x1 +#define PTP_RX_TS0_6_REG_TYPE REG_TYPE_RW +#define PTP_RX_TS0_6_REG_DEFAULT 0x0 + /*[field] RX_TS_NFSEC*/ + #define PTP_RX_TS0_6_REG_RX_TS_NFSEC + #define PTP_RX_TS0_6_REG_RX_TS_NFSEC_OFFSET 0 + #define PTP_RX_TS0_6_REG_RX_TS_NFSEC_LEN 8 + #define PTP_RX_TS0_6_REG_RX_TS_NFSEC_DEFAULT 0x0 + +struct ptp_rx_ts0_6_reg { + a_uint16_t rx_ts_nfsec:8; +}; + +union ptp_rx_ts0_6_reg_u { + a_uint32_t val; + struct ptp_rx_ts0_6_reg bf; +}; + +/*[register] PTP_TX_SEQID_REG*/ +#define PTP_TX_SEQID_REG +#define PTP_TX_SEQID_REG_ADDRESS 0x8020 +#define PTP_TX_SEQID_REG_NUM 1 +#define PTP_TX_SEQID_REG_INC 0x1 +#define PTP_TX_SEQID_REG_TYPE REG_TYPE_RW +#define PTP_TX_SEQID_REG_DEFAULT 0x0 + /*[field] TX_SEQID*/ + #define PTP_TX_SEQID_REG_TX_SEQID + #define PTP_TX_SEQID_REG_TX_SEQID_OFFSET 0 + #define PTP_TX_SEQID_REG_TX_SEQID_LEN 16 + #define PTP_TX_SEQID_REG_TX_SEQID_DEFAULT 0x0 + +struct ptp_tx_seqid_reg { + a_uint16_t tx_seqid:16; +}; + +union ptp_tx_seqid_reg_u { + a_uint32_t val; + struct ptp_tx_seqid_reg bf; +}; + +/*[register] PTP_TX_PORTID0_REG*/ +#define PTP_TX_PORTID0_REG +#define PTP_TX_PORTID0_REG_ADDRESS 0x8021 +#define PTP_TX_PORTID0_REG_NUM 1 +#define PTP_TX_PORTID0_REG_INC 0x1 +#define PTP_TX_PORTID0_REG_TYPE REG_TYPE_RW +#define PTP_TX_PORTID0_REG_DEFAULT 0x0 + /*[field] TX_PORTID*/ + #define PTP_TX_PORTID0_REG_TX_PORTID + #define PTP_TX_PORTID0_REG_TX_PORTID_OFFSET 0 + #define PTP_TX_PORTID0_REG_TX_PORTID_LEN 16 + #define PTP_TX_PORTID0_REG_TX_PORTID_DEFAULT 0x0 + +struct ptp_tx_portid0_reg { + a_uint16_t tx_portid:16; +}; + +union ptp_tx_portid0_reg_u { + a_uint32_t val; + struct ptp_tx_portid0_reg bf; +}; + +/*[register] PTP_TX_PORTID1_REG*/ +#define PTP_TX_PORTID1_REG +#define PTP_TX_PORTID1_REG_ADDRESS 0x8022 +#define PTP_TX_PORTID1_REG_NUM 1 +#define PTP_TX_PORTID1_REG_INC 0x1 +#define PTP_TX_PORTID1_REG_TYPE REG_TYPE_RW +#define PTP_TX_PORTID1_REG_DEFAULT 0x0 + /*[field] TX_PORTID*/ + #define PTP_TX_PORTID1_REG_TX_PORTID + #define PTP_TX_PORTID1_REG_TX_PORTID_OFFSET 0 + #define PTP_TX_PORTID1_REG_TX_PORTID_LEN 16 + #define PTP_TX_PORTID1_REG_TX_PORTID_DEFAULT 0x0 + +struct ptp_tx_portid1_reg { + a_uint16_t tx_portid:16; +}; + +union ptp_tx_portid1_reg_u { + a_uint32_t val; + struct ptp_tx_portid1_reg bf; +}; + +/*[register] PTP_TX_PORTID2_REG*/ +#define PTP_TX_PORTID2_REG +#define PTP_TX_PORTID2_REG_ADDRESS 0x8023 +#define PTP_TX_PORTID2_REG_NUM 1 +#define PTP_TX_PORTID2_REG_INC 0x1 +#define PTP_TX_PORTID2_REG_TYPE REG_TYPE_RW +#define PTP_TX_PORTID2_REG_DEFAULT 0x0 + /*[field] TX_PORTID*/ + #define PTP_TX_PORTID2_REG_TX_PORTID + #define PTP_TX_PORTID2_REG_TX_PORTID_OFFSET 0 + #define PTP_TX_PORTID2_REG_TX_PORTID_LEN 16 + #define PTP_TX_PORTID2_REG_TX_PORTID_DEFAULT 0x0 + +struct ptp_tx_portid2_reg { + a_uint16_t tx_portid:16; +}; + +union ptp_tx_portid2_reg_u { + a_uint32_t val; + struct ptp_tx_portid2_reg bf; +}; + +/*[register] PTP_TX_PORTID3_REG*/ +#define PTP_TX_PORTID3_REG +#define PTP_TX_PORTID3_REG_ADDRESS 0x8024 +#define PTP_TX_PORTID3_REG_NUM 1 +#define PTP_TX_PORTID3_REG_INC 0x1 +#define PTP_TX_PORTID3_REG_TYPE REG_TYPE_RW +#define PTP_TX_PORTID3_REG_DEFAULT 0x0 + /*[field] TX_PORTID*/ + #define PTP_TX_PORTID3_REG_TX_PORTID + #define PTP_TX_PORTID3_REG_TX_PORTID_OFFSET 0 + #define PTP_TX_PORTID3_REG_TX_PORTID_LEN 16 + #define PTP_TX_PORTID3_REG_TX_PORTID_DEFAULT 0x0 + +struct ptp_tx_portid3_reg { + a_uint16_t tx_portid:16; +}; + +union ptp_tx_portid3_reg_u { + a_uint32_t val; + struct ptp_tx_portid3_reg bf; +}; + +/*[register] PTP_TX_PORTID4_REG*/ +#define PTP_TX_PORTID4_REG +#define PTP_TX_PORTID4_REG_ADDRESS 0x8025 +#define PTP_TX_PORTID4_REG_NUM 1 +#define PTP_TX_PORTID4_REG_INC 0x1 +#define PTP_TX_PORTID4_REG_TYPE REG_TYPE_RW +#define PTP_TX_PORTID4_REG_DEFAULT 0x0 + /*[field] TX_PORTID*/ + #define PTP_TX_PORTID4_REG_TX_PORTID + #define PTP_TX_PORTID4_REG_TX_PORTID_OFFSET 0 + #define PTP_TX_PORTID4_REG_TX_PORTID_LEN 16 + #define PTP_TX_PORTID4_REG_TX_PORTID_DEFAULT 0x0 + +struct ptp_tx_portid4_reg { + a_uint16_t tx_portid:16; +}; + +union ptp_tx_portid4_reg_u { + a_uint32_t val; + struct ptp_tx_portid4_reg bf; +}; + +/*[register] PTP_TX_TS0_REG*/ +#define PTP_TX_TS0_REG +#define PTP_TX_TS0_REG_ADDRESS 0x8026 +#define PTP_TX_TS0_REG_NUM 1 +#define PTP_TX_TS0_REG_INC 0x1 +#define PTP_TX_TS0_REG_TYPE REG_TYPE_RW +#define PTP_TX_TS0_REG_DEFAULT 0x0 + /*[field] TX_TS_SEC*/ + #define PTP_TX_TS0_REG_TX_TS_SEC + #define PTP_TX_TS0_REG_TX_TS_SEC_OFFSET 0 + #define PTP_TX_TS0_REG_TX_TS_SEC_LEN 16 + #define PTP_TX_TS0_REG_TX_TS_SEC_DEFAULT 0x0 + +struct ptp_tx_ts0_reg { + a_uint16_t tx_ts_sec:16; +}; + +union ptp_tx_ts0_reg_u { + a_uint32_t val; + struct ptp_tx_ts0_reg bf; +}; + +/*[register] PTP_TX_TS1_REG*/ +#define PTP_TX_TS1_REG +#define PTP_TX_TS1_REG_ADDRESS 0x8027 +#define PTP_TX_TS1_REG_NUM 1 +#define PTP_TX_TS1_REG_INC 0x1 +#define PTP_TX_TS1_REG_TYPE REG_TYPE_RW +#define PTP_TX_TS1_REG_DEFAULT 0x0 + /*[field] TX_TS_SEC*/ + #define PTP_TX_TS1_REG_TX_TS_SEC + #define PTP_TX_TS1_REG_TX_TS_SEC_OFFSET 0 + #define PTP_TX_TS1_REG_TX_TS_SEC_LEN 16 + #define PTP_TX_TS1_REG_TX_TS_SEC_DEFAULT 0x0 + +struct ptp_tx_ts1_reg { + a_uint16_t tx_ts_sec:16; +}; + +union ptp_tx_ts1_reg_u { + a_uint32_t val; + struct ptp_tx_ts1_reg bf; +}; + +/*[register] PTP_TX_TS2_REG*/ +#define PTP_TX_TS2_REG +#define PTP_TX_TS2_REG_ADDRESS 0x8028 +#define PTP_TX_TS2_REG_NUM 1 +#define PTP_TX_TS2_REG_INC 0x1 +#define PTP_TX_TS2_REG_TYPE REG_TYPE_RW +#define PTP_TX_TS2_REG_DEFAULT 0x0 + /*[field] TX_TS_SEC*/ + #define PTP_TX_TS2_REG_TX_TS_SEC + #define PTP_TX_TS2_REG_TX_TS_SEC_OFFSET 0 + #define PTP_TX_TS2_REG_TX_TS_SEC_LEN 16 + #define PTP_TX_TS2_REG_TX_TS_SEC_DEFAULT 0x0 + +struct ptp_tx_ts2_reg { + a_uint16_t tx_ts_sec:16; +}; + +union ptp_tx_ts2_reg_u { + a_uint32_t val; + struct ptp_tx_ts2_reg bf; +}; + +/*[register] PTP_TX_TS3_REG*/ +#define PTP_TX_TS3_REG +#define PTP_TX_TS3_REG_ADDRESS 0x8029 +#define PTP_TX_TS3_REG_NUM 1 +#define PTP_TX_TS3_REG_INC 0x1 +#define PTP_TX_TS3_REG_TYPE REG_TYPE_RW +#define PTP_TX_TS3_REG_DEFAULT 0x0 + /*[field] TX_TS_NSEC*/ + #define PTP_TX_TS3_REG_TX_TS_NSEC + #define PTP_TX_TS3_REG_TX_TS_NSEC_OFFSET 0 + #define PTP_TX_TS3_REG_TX_TS_NSEC_LEN 16 + #define PTP_TX_TS3_REG_TX_TS_NSEC_DEFAULT 0x0 + +struct ptp_tx_ts3_reg { + a_uint16_t tx_ts_nsec:16; +}; + +union ptp_tx_ts3_reg_u { + a_uint32_t val; + struct ptp_tx_ts3_reg bf; +}; + +/*[register] PTP_TX_TS4_REG*/ +#define PTP_TX_TS4_REG +#define PTP_TX_TS4_REG_ADDRESS 0x802a +#define PTP_TX_TS4_REG_NUM 1 +#define PTP_TX_TS4_REG_INC 0x1 +#define PTP_TX_TS4_REG_TYPE REG_TYPE_RW +#define PTP_TX_TS4_REG_DEFAULT 0x0 + /*[field] TX_TS_NSEC*/ + #define PTP_TX_TS4_REG_TX_TS_NSEC + #define PTP_TX_TS4_REG_TX_TS_NSEC_OFFSET 0 + #define PTP_TX_TS4_REG_TX_TS_NSEC_LEN 16 + #define PTP_TX_TS4_REG_TX_TS_NSEC_DEFAULT 0x0 + +struct ptp_tx_ts4_reg { + a_uint16_t tx_ts_nsec:16; +}; + +union ptp_tx_ts4_reg_u { + a_uint32_t val; + struct ptp_tx_ts4_reg bf; +}; + +/*[register] PTP_TX_TS5_REG*/ +#define PTP_TX_TS5_REG +#define PTP_TX_TS5_REG_ADDRESS 0x802b +#define PTP_TX_TS5_REG_NUM 1 +#define PTP_TX_TS5_REG_INC 0x1 +#define PTP_TX_TS5_REG_TYPE REG_TYPE_RW +#define PTP_TX_TS5_REG_DEFAULT 0x0 + /*[field] TX_TS_NFSEC*/ + #define PTP_TX_TS5_REG_TX_TS_NFSEC + #define PTP_TX_TS5_REG_TX_TS_NFSEC_OFFSET 0 + #define PTP_TX_TS5_REG_TX_TS_NFSEC_LEN 12 + #define PTP_TX_TS5_REG_TX_TS_NFSEC_DEFAULT 0x0 + /*[field] TX_MSG_TYPE*/ + #define PTP_TX_TS5_REG_TX_MSG_TYPE + #define PTP_TX_TS5_REG_TX_MSG_TYPE_OFFSET 12 + #define PTP_TX_TS5_REG_TX_MSG_TYPE_LEN 4 + #define PTP_TX_TS5_REG_TX_MSG_TYPE_DEFAULT 0x0 + +struct ptp_tx_ts5_reg { + a_uint16_t tx_ts_nfsec:12; + a_uint16_t tx_msg_type:4; +}; + +union ptp_tx_ts5_reg_u { + a_uint32_t val; + struct ptp_tx_ts5_reg bf; +}; + +/*[register] PTP_TX_TS6_REG*/ +#define PTP_TX_TS6_REG +#define PTP_TX_TS6_REG_ADDRESS 0x802c +#define PTP_TX_TS6_REG_NUM 1 +#define PTP_TX_TS6_REG_INC 0x1 +#define PTP_TX_TS6_REG_TYPE REG_TYPE_RW +#define PTP_TX_TS6_REG_DEFAULT 0x0 + /*[field] TX_TS_NFSEC*/ + #define PTP_TX_TS6_REG_TX_TS_NFSEC + #define PTP_TX_TS6_REG_TX_TS_NFSEC_OFFSET 0 + #define PTP_TX_TS6_REG_TX_TS_NFSEC_LEN 8 + #define PTP_TX_TS6_REG_TX_TS_NFSEC_DEFAULT 0x0 + +struct ptp_tx_ts6_reg { + a_uint16_t tx_ts_nfsec:8; +}; + +union ptp_tx_ts6_reg_u { + a_uint32_t val; + struct ptp_tx_ts6_reg bf; +}; + +/*[register] PTP_ORIG_CORR0_REG*/ +#define PTP_ORIG_CORR0_REG +#define PTP_ORIG_CORR0_REG_ADDRESS 0x802d +#define PTP_ORIG_CORR0_REG_NUM 1 +#define PTP_ORIG_CORR0_REG_INC 0x1 +#define PTP_ORIG_CORR0_REG_TYPE REG_TYPE_RW +#define PTP_ORIG_CORR0_REG_DEFAULT 0x0 + /*[field] PTP_ORIG_CORR*/ + #define PTP_ORIG_CORR0_REG_PTP_ORIG_CORR + #define PTP_ORIG_CORR0_REG_PTP_ORIG_CORR_OFFSET 0 + #define PTP_ORIG_CORR0_REG_PTP_ORIG_CORR_LEN 16 + #define PTP_ORIG_CORR0_REG_PTP_ORIG_CORR_DEFAULT 0x0 + +struct ptp_orig_corr0_reg { + a_uint16_t ptp_orig_corr:16; +}; + +union ptp_orig_corr0_reg_u { + a_uint32_t val; + struct ptp_orig_corr0_reg bf; +}; + +/*[register] PTP_ORIG_CORR1_REG*/ +#define PTP_ORIG_CORR1_REG +#define PTP_ORIG_CORR1_REG_ADDRESS 0x802e +#define PTP_ORIG_CORR1_REG_NUM 1 +#define PTP_ORIG_CORR1_REG_INC 0x1 +#define PTP_ORIG_CORR1_REG_TYPE REG_TYPE_RW +#define PTP_ORIG_CORR1_REG_DEFAULT 0x0 + /*[field] PTP_ORIG_CORR*/ + #define PTP_ORIG_CORR1_REG_PTP_ORIG_CORR + #define PTP_ORIG_CORR1_REG_PTP_ORIG_CORR_OFFSET 0 + #define PTP_ORIG_CORR1_REG_PTP_ORIG_CORR_LEN 16 + #define PTP_ORIG_CORR1_REG_PTP_ORIG_CORR_DEFAULT 0x0 + +struct ptp_orig_corr1_reg { + a_uint16_t ptp_orig_corr:16; +}; + +union ptp_orig_corr1_reg_u { + a_uint32_t val; + struct ptp_orig_corr1_reg bf; +}; + +/*[register] PTP_ORIG_CORR2_REG*/ +#define PTP_ORIG_CORR2_REG +#define PTP_ORIG_CORR2_REG_ADDRESS 0x802f +#define PTP_ORIG_CORR2_REG_NUM 1 +#define PTP_ORIG_CORR2_REG_INC 0x1 +#define PTP_ORIG_CORR2_REG_TYPE REG_TYPE_RW +#define PTP_ORIG_CORR2_REG_DEFAULT 0x0 + /*[field] PTP_ORIG_CORR*/ + #define PTP_ORIG_CORR2_REG_PTP_ORIG_CORR + #define PTP_ORIG_CORR2_REG_PTP_ORIG_CORR_OFFSET 0 + #define PTP_ORIG_CORR2_REG_PTP_ORIG_CORR_LEN 16 + #define PTP_ORIG_CORR2_REG_PTP_ORIG_CORR_DEFAULT 0x0 + +struct ptp_orig_corr2_reg { + a_uint16_t ptp_orig_corr:16; +}; + +union ptp_orig_corr2_reg_u { + a_uint32_t val; + struct ptp_orig_corr2_reg bf; +}; + +/*[register] PTP_ORIG_CORR3_REG*/ +#define PTP_ORIG_CORR3_REG +#define PTP_ORIG_CORR3_REG_ADDRESS 0x8030 +#define PTP_ORIG_CORR3_REG_NUM 1 +#define PTP_ORIG_CORR3_REG_INC 0x1 +#define PTP_ORIG_CORR3_REG_TYPE REG_TYPE_RW +#define PTP_ORIG_CORR3_REG_DEFAULT 0x0 + /*[field] PTP_ORIG_CORR*/ + #define PTP_ORIG_CORR3_REG_PTP_ORIG_CORR + #define PTP_ORIG_CORR3_REG_PTP_ORIG_CORR_OFFSET 0 + #define PTP_ORIG_CORR3_REG_PTP_ORIG_CORR_LEN 16 + #define PTP_ORIG_CORR3_REG_PTP_ORIG_CORR_DEFAULT 0x0 + +struct ptp_orig_corr3_reg { + a_uint16_t ptp_orig_corr:16; +}; + +union ptp_orig_corr3_reg_u { + a_uint32_t val; + struct ptp_orig_corr3_reg bf; +}; + +/*[register] PTP_IN_TRIG0_REG*/ +#define PTP_IN_TRIG0_REG +#define PTP_IN_TRIG0_REG_ADDRESS 0x8031 +#define PTP_IN_TRIG0_REG_NUM 1 +#define PTP_IN_TRIG0_REG_INC 0x1 +#define PTP_IN_TRIG0_REG_TYPE REG_TYPE_RW +#define PTP_IN_TRIG0_REG_DEFAULT 0x0 + /*[field] PTP_IN_TRIG_NISEC*/ + #define PTP_IN_TRIG0_REG_PTP_IN_TRIG_NISEC + #define PTP_IN_TRIG0_REG_PTP_IN_TRIG_NISEC_OFFSET 0 + #define PTP_IN_TRIG0_REG_PTP_IN_TRIG_NISEC_LEN 16 + #define PTP_IN_TRIG0_REG_PTP_IN_TRIG_NISEC_DEFAULT 0x0 + +struct ptp_in_trig0_reg { + a_uint16_t ptp_in_trig_nisec:16; +}; + +union ptp_in_trig0_reg_u { + a_uint32_t val; + struct ptp_in_trig0_reg bf; +}; + +/*[register] PTP_IN_TRIG1_REG*/ +#define PTP_IN_TRIG1_REG +#define PTP_IN_TRIG1_REG_ADDRESS 0x8032 +#define PTP_IN_TRIG1_REG_NUM 1 +#define PTP_IN_TRIG1_REG_INC 0x1 +#define PTP_IN_TRIG1_REG_TYPE REG_TYPE_RW +#define PTP_IN_TRIG1_REG_DEFAULT 0x0 + /*[field] PTP_IN_TRIG_NISEC*/ + #define PTP_IN_TRIG1_REG_PTP_IN_TRIG_NISEC + #define PTP_IN_TRIG1_REG_PTP_IN_TRIG_NISEC_OFFSET 0 + #define PTP_IN_TRIG1_REG_PTP_IN_TRIG_NISEC_LEN 16 + #define PTP_IN_TRIG1_REG_PTP_IN_TRIG_NISEC_DEFAULT 0x0 + +struct ptp_in_trig1_reg { + a_uint16_t ptp_in_trig_nisec:16; +}; + +union ptp_in_trig1_reg_u { + a_uint32_t val; + struct ptp_in_trig1_reg bf; +}; + +/*[register] PTP_IN_TRIG2_REG*/ +#define PTP_IN_TRIG2_REG +#define PTP_IN_TRIG2_REG_ADDRESS 0x8033 +#define PTP_IN_TRIG2_REG_NUM 1 +#define PTP_IN_TRIG2_REG_INC 0x1 +#define PTP_IN_TRIG2_REG_TYPE REG_TYPE_RW +#define PTP_IN_TRIG2_REG_DEFAULT 0x0 + /*[field] PTP_IN_TRIG_NISEC*/ + #define PTP_IN_TRIG2_REG_PTP_IN_TRIG_NISEC + #define PTP_IN_TRIG2_REG_PTP_IN_TRIG_NISEC_OFFSET 0 + #define PTP_IN_TRIG2_REG_PTP_IN_TRIG_NISEC_LEN 16 + #define PTP_IN_TRIG2_REG_PTP_IN_TRIG_NISEC_DEFAULT 0x0 + +struct ptp_in_trig2_reg { + a_uint16_t ptp_in_trig_nisec:16; +}; + +union ptp_in_trig2_reg_u { + a_uint32_t val; + struct ptp_in_trig2_reg bf; +}; + +/*[register] PTP_IN_TRIG3_REG*/ +#define PTP_IN_TRIG3_REG +#define PTP_IN_TRIG3_REG_ADDRESS 0x8034 +#define PTP_IN_TRIG3_REG_NUM 1 +#define PTP_IN_TRIG3_REG_INC 0x1 +#define PTP_IN_TRIG3_REG_TYPE REG_TYPE_RW +#define PTP_IN_TRIG3_REG_DEFAULT 0x0 + /*[field] PTP_IN_TRIG_NISEC*/ + #define PTP_IN_TRIG3_REG_PTP_IN_TRIG_NISEC + #define PTP_IN_TRIG3_REG_PTP_IN_TRIG_NISEC_OFFSET 0 + #define PTP_IN_TRIG3_REG_PTP_IN_TRIG_NISEC_LEN 4 + #define PTP_IN_TRIG3_REG_PTP_IN_TRIG_NISEC_DEFAULT 0x0 + +struct ptp_in_trig3_reg { + a_uint16_t ptp_in_trig_nisec:4; +}; + +union ptp_in_trig3_reg_u { + a_uint32_t val; + struct ptp_in_trig3_reg bf; +}; + +/*[register] PTP_TX_LATENCY_REG*/ +#define PTP_TX_LATENCY_REG +#define PTP_TX_LATENCY_REG_ADDRESS 0x8035 +#define PTP_TX_LATENCY_REG_NUM 1 +#define PTP_TX_LATENCY_REG_INC 0x1 +#define PTP_TX_LATENCY_REG_TYPE REG_TYPE_RW +#define PTP_TX_LATENCY_REG_DEFAULT 0x0 + /*[field] PTP_TX_LATENCY*/ + #define PTP_TX_LATENCY_REG_PTP_TX_LATENCY + #define PTP_TX_LATENCY_REG_PTP_TX_LATENCY_OFFSET 0 + #define PTP_TX_LATENCY_REG_PTP_TX_LATENCY_LEN 16 + #define PTP_TX_LATENCY_REG_PTP_TX_LATENCY_DEFAULT 0x0 + +struct ptp_tx_latency_reg { + a_uint16_t ptp_tx_latency:16; +}; + +union ptp_tx_latency_reg_u { + a_uint32_t val; + struct ptp_tx_latency_reg bf; +}; + +/*[register] PTP_RTC_INC0_REG*/ +#define PTP_RTC_INC0_REG +#define PTP_RTC_INC0_REG_ADDRESS 0x8036 +#define PTP_RTC_INC0_REG_NUM 1 +#define PTP_RTC_INC0_REG_INC 0x1 +#define PTP_RTC_INC0_REG_TYPE REG_TYPE_RW +#define PTP_RTC_INC0_REG_DEFAULT 0x0 + /*[field] PTP_RTC_INC_NFS*/ + #define PTP_RTC_INC0_REG_PTP_RTC_INC_NFS + #define PTP_RTC_INC0_REG_PTP_RTC_INC_NFS_OFFSET 0 + #define PTP_RTC_INC0_REG_PTP_RTC_INC_NFS_LEN 10 + #define PTP_RTC_INC0_REG_PTP_RTC_INC_NFS_DEFAULT 0x0 + /*[field] PTP_RTC_INC_NIS*/ + #define PTP_RTC_INC0_REG_PTP_RTC_INC_NIS + #define PTP_RTC_INC0_REG_PTP_RTC_INC_NIS_OFFSET 10 + #define PTP_RTC_INC0_REG_PTP_RTC_INC_NIS_LEN 6 + #define PTP_RTC_INC0_REG_PTP_RTC_INC_NIS_DEFAULT 0x0 + +struct ptp_rtc_inc0_reg { + a_uint16_t ptp_rtc_inc_nfs:10; + a_uint16_t ptp_rtc_inc_nis:6; +}; + +union ptp_rtc_inc0_reg_u { + a_uint32_t val; + struct ptp_rtc_inc0_reg bf; +}; + +/*[register] PTP_RTC_INC1_REG*/ +#define PTP_RTC_INC1_REG +#define PTP_RTC_INC1_REG_ADDRESS 0x8037 +#define PTP_RTC_INC1_REG_NUM 1 +#define PTP_RTC_INC1_REG_INC 0x1 +#define PTP_RTC_INC1_REG_TYPE REG_TYPE_RW +#define PTP_RTC_INC1_REG_DEFAULT 0x0 + /*[field] PTP_RTC_INC_NFS*/ + #define PTP_RTC_INC1_REG_PTP_RTC_INC_NFS + #define PTP_RTC_INC1_REG_PTP_RTC_INC_NFS_OFFSET 0 + #define PTP_RTC_INC1_REG_PTP_RTC_INC_NFS_LEN 16 + #define PTP_RTC_INC1_REG_PTP_RTC_INC_NFS_DEFAULT 0x0 + +struct ptp_rtc_inc1_reg { + a_uint16_t ptp_rtc_inc_nfs:16; +}; + +union ptp_rtc_inc1_reg_u { + a_uint32_t val; + struct ptp_rtc_inc1_reg bf; +}; + +/*[register] PTP_RTCOFFS0_REG*/ +#define PTP_RTCOFFS0_REG +#define PTP_RTCOFFS0_REG_ADDRESS 0x8038 +#define PTP_RTCOFFS0_REG_NUM 1 +#define PTP_RTCOFFS0_REG_INC 0x1 +#define PTP_RTCOFFS0_REG_TYPE REG_TYPE_RW +#define PTP_RTCOFFS0_REG_DEFAULT 0x0 + /*[field] PTP_RTCOFFS_NSEC*/ + #define PTP_RTCOFFS0_REG_PTP_RTCOFFS_NSEC + #define PTP_RTCOFFS0_REG_PTP_RTCOFFS_NSEC_OFFSET 0 + #define PTP_RTCOFFS0_REG_PTP_RTCOFFS_NSEC_LEN 16 + #define PTP_RTCOFFS0_REG_PTP_RTCOFFS_NSEC_DEFAULT 0x0 + +struct ptp_rtcoffs0_reg { + a_uint16_t ptp_rtcoffs_nsec:16; +}; + +union ptp_rtcoffs0_reg_u { + a_uint32_t val; + struct ptp_rtcoffs0_reg bf; +}; + +/*[register] PTP_RTCOFFS1_REG*/ +#define PTP_RTCOFFS1_REG +#define PTP_RTCOFFS1_REG_ADDRESS 0x8039 +#define PTP_RTCOFFS1_REG_NUM 1 +#define PTP_RTCOFFS1_REG_INC 0x1 +#define PTP_RTCOFFS1_REG_TYPE REG_TYPE_RW +#define PTP_RTCOFFS1_REG_DEFAULT 0x0 + /*[field] PTP_RTCOFFS_NSEC*/ + #define PTP_RTCOFFS1_REG_PTP_RTCOFFS_NSEC + #define PTP_RTCOFFS1_REG_PTP_RTCOFFS_NSEC_OFFSET 0 + #define PTP_RTCOFFS1_REG_PTP_RTCOFFS_NSEC_LEN 16 + #define PTP_RTCOFFS1_REG_PTP_RTCOFFS_NSEC_DEFAULT 0x0 + +struct ptp_rtcoffs1_reg { + a_uint16_t ptp_rtcoffs_nsec:16; +}; + +union ptp_rtcoffs1_reg_u { + a_uint32_t val; + struct ptp_rtcoffs1_reg bf; +}; + +/*[register] PTP_RTCOFFS2_REG*/ +#define PTP_RTCOFFS2_REG +#define PTP_RTCOFFS2_REG_ADDRESS 0x803a +#define PTP_RTCOFFS2_REG_NUM 1 +#define PTP_RTCOFFS2_REG_INC 0x1 +#define PTP_RTCOFFS2_REG_TYPE REG_TYPE_RW +#define PTP_RTCOFFS2_REG_DEFAULT 0x0 + /*[field] PTP_RTCOFFS_SEC*/ + #define PTP_RTCOFFS2_REG_PTP_RTCOFFS_SEC + #define PTP_RTCOFFS2_REG_PTP_RTCOFFS_SEC_OFFSET 0 + #define PTP_RTCOFFS2_REG_PTP_RTCOFFS_SEC_LEN 16 + #define PTP_RTCOFFS2_REG_PTP_RTCOFFS_SEC_DEFAULT 0x0 + +struct ptp_rtcoffs2_reg { + a_uint16_t ptp_rtcoffs_sec:16; +}; + +union ptp_rtcoffs2_reg_u { + a_uint32_t val; + struct ptp_rtcoffs2_reg bf; +}; + +/*[register] PTP_RTCOFFS3_REG*/ +#define PTP_RTCOFFS3_REG +#define PTP_RTCOFFS3_REG_ADDRESS 0x803b +#define PTP_RTCOFFS3_REG_NUM 1 +#define PTP_RTCOFFS3_REG_INC 0x1 +#define PTP_RTCOFFS3_REG_TYPE REG_TYPE_RW +#define PTP_RTCOFFS3_REG_DEFAULT 0x0 + /*[field] PTP_RTCOFFS_SEC*/ + #define PTP_RTCOFFS3_REG_PTP_RTCOFFS_SEC + #define PTP_RTCOFFS3_REG_PTP_RTCOFFS_SEC_OFFSET 0 + #define PTP_RTCOFFS3_REG_PTP_RTCOFFS_SEC_LEN 16 + #define PTP_RTCOFFS3_REG_PTP_RTCOFFS_SEC_DEFAULT 0x0 + +struct ptp_rtcoffs3_reg { + a_uint16_t ptp_rtcoffs_sec:16; +}; + +union ptp_rtcoffs3_reg_u { + a_uint32_t val; + struct ptp_rtcoffs3_reg bf; +}; + +/*[register] PTP_RTCOFFS4_REG*/ +#define PTP_RTCOFFS4_REG +#define PTP_RTCOFFS4_REG_ADDRESS 0x803c +#define PTP_RTCOFFS4_REG_NUM 1 +#define PTP_RTCOFFS4_REG_INC 0x1 +#define PTP_RTCOFFS4_REG_TYPE REG_TYPE_RW +#define PTP_RTCOFFS4_REG_DEFAULT 0x0 + /*[field] PTP_RTCOFFS_SEC*/ + #define PTP_RTCOFFS4_REG_PTP_RTCOFFS_SEC + #define PTP_RTCOFFS4_REG_PTP_RTCOFFS_SEC_OFFSET 0 + #define PTP_RTCOFFS4_REG_PTP_RTCOFFS_SEC_LEN 16 + #define PTP_RTCOFFS4_REG_PTP_RTCOFFS_SEC_DEFAULT 0x0 + +struct ptp_rtcoffs4_reg { + a_uint16_t ptp_rtcoffs_sec:16; +}; + +union ptp_rtcoffs4_reg_u { + a_uint32_t val; + struct ptp_rtcoffs4_reg bf; +}; + +/*[register] PTP_RTC0_REG*/ +#define PTP_RTC0_REG +#define PTP_RTC0_REG_ADDRESS 0x803d +#define PTP_RTC0_REG_NUM 1 +#define PTP_RTC0_REG_INC 0x1 +#define PTP_RTC0_REG_TYPE REG_TYPE_RW +#define PTP_RTC0_REG_DEFAULT 0x0 + /*[field] PTP_RTC_SEC*/ + #define PTP_RTC0_REG_PTP_RTC_SEC + #define PTP_RTC0_REG_PTP_RTC_SEC_OFFSET 0 + #define PTP_RTC0_REG_PTP_RTC_SEC_LEN 16 + #define PTP_RTC0_REG_PTP_RTC_SEC_DEFAULT 0x0 + +struct ptp_rtc0_reg { + a_uint16_t ptp_rtc_sec:16; +}; + +union ptp_rtc0_reg_u { + a_uint32_t val; + struct ptp_rtc0_reg bf; +}; + +/*[register] PTP_RTC1_REG*/ +#define PTP_RTC1_REG +#define PTP_RTC1_REG_ADDRESS 0x803e +#define PTP_RTC1_REG_NUM 1 +#define PTP_RTC1_REG_INC 0x1 +#define PTP_RTC1_REG_TYPE REG_TYPE_RW +#define PTP_RTC1_REG_DEFAULT 0x0 + /*[field] PTP_RTC_SEC*/ + #define PTP_RTC1_REG_PTP_RTC_SEC + #define PTP_RTC1_REG_PTP_RTC_SEC_OFFSET 0 + #define PTP_RTC1_REG_PTP_RTC_SEC_LEN 16 + #define PTP_RTC1_REG_PTP_RTC_SEC_DEFAULT 0x0 + +struct ptp_rtc1_reg { + a_uint16_t ptp_rtc_sec:16; +}; + +union ptp_rtc1_reg_u { + a_uint32_t val; + struct ptp_rtc1_reg bf; +}; + +/*[register] PTP_RTC2_REG*/ +#define PTP_RTC2_REG +#define PTP_RTC2_REG_ADDRESS 0x803f +#define PTP_RTC2_REG_NUM 1 +#define PTP_RTC2_REG_INC 0x1 +#define PTP_RTC2_REG_TYPE REG_TYPE_RW +#define PTP_RTC2_REG_DEFAULT 0x0 + /*[field] PTP_RTC_SEC*/ + #define PTP_RTC2_REG_PTP_RTC_SEC + #define PTP_RTC2_REG_PTP_RTC_SEC_OFFSET 0 + #define PTP_RTC2_REG_PTP_RTC_SEC_LEN 16 + #define PTP_RTC2_REG_PTP_RTC_SEC_DEFAULT 0x0 + +struct ptp_rtc2_reg { + a_uint16_t ptp_rtc_sec:16; +}; + +union ptp_rtc2_reg_u { + a_uint32_t val; + struct ptp_rtc2_reg bf; +}; + +/*[register] PTP_RTC3_REG*/ +#define PTP_RTC3_REG +#define PTP_RTC3_REG_ADDRESS 0x8040 +#define PTP_RTC3_REG_NUM 1 +#define PTP_RTC3_REG_INC 0x1 +#define PTP_RTC3_REG_TYPE REG_TYPE_RW +#define PTP_RTC3_REG_DEFAULT 0x0 + /*[field] PTP_RTC_NISEC*/ + #define PTP_RTC3_REG_PTP_RTC_NISEC + #define PTP_RTC3_REG_PTP_RTC_NISEC_OFFSET 0 + #define PTP_RTC3_REG_PTP_RTC_NISEC_LEN 16 + #define PTP_RTC3_REG_PTP_RTC_NISEC_DEFAULT 0x0 + +struct ptp_rtc3_reg { + a_uint16_t ptp_rtc_nisec:16; +}; + +union ptp_rtc3_reg_u { + a_uint32_t val; + struct ptp_rtc3_reg bf; +}; + +/*[register] PTP_RTC4_REG*/ +#define PTP_RTC4_REG +#define PTP_RTC4_REG_ADDRESS 0x8041 +#define PTP_RTC4_REG_NUM 1 +#define PTP_RTC4_REG_INC 0x1 +#define PTP_RTC4_REG_TYPE REG_TYPE_RW +#define PTP_RTC4_REG_DEFAULT 0x0 + /*[field] PTP_RTC_NISEC*/ + #define PTP_RTC4_REG_PTP_RTC_NISEC + #define PTP_RTC4_REG_PTP_RTC_NISEC_OFFSET 0 + #define PTP_RTC4_REG_PTP_RTC_NISEC_LEN 16 + #define PTP_RTC4_REG_PTP_RTC_NISEC_DEFAULT 0x0 + +struct ptp_rtc4_reg { + a_uint16_t ptp_rtc_nisec:16; +}; + +union ptp_rtc4_reg_u { + a_uint32_t val; + struct ptp_rtc4_reg bf; +}; + +/*[register] PTP_RTC5_REG*/ +#define PTP_RTC5_REG +#define PTP_RTC5_REG_ADDRESS 0x8042 +#define PTP_RTC5_REG_NUM 1 +#define PTP_RTC5_REG_INC 0x1 +#define PTP_RTC5_REG_TYPE REG_TYPE_RW +#define PTP_RTC5_REG_DEFAULT 0x0 + /*[field] PTP_RTC_NFSEC*/ + #define PTP_RTC5_REG_PTP_RTC_NFSEC + #define PTP_RTC5_REG_PTP_RTC_NFSEC_OFFSET 0 + #define PTP_RTC5_REG_PTP_RTC_NFSEC_LEN 16 + #define PTP_RTC5_REG_PTP_RTC_NFSEC_DEFAULT 0x0 + +struct ptp_rtc5_reg { + a_uint16_t ptp_rtc_nfsec:16; +}; + +union ptp_rtc5_reg_u { + a_uint32_t val; + struct ptp_rtc5_reg bf; +}; + +/*[register] PTP_RTC6_REG*/ +#define PTP_RTC6_REG +#define PTP_RTC6_REG_ADDRESS 0x8043 +#define PTP_RTC6_REG_NUM 1 +#define PTP_RTC6_REG_INC 0x1 +#define PTP_RTC6_REG_TYPE REG_TYPE_RW +#define PTP_RTC6_REG_DEFAULT 0x0 + /*[field] PTP_RTC_NFSEC*/ + #define PTP_RTC6_REG_PTP_RTC_NFSEC + #define PTP_RTC6_REG_PTP_RTC_NFSEC_OFFSET 0 + #define PTP_RTC6_REG_PTP_RTC_NFSEC_LEN 4 + #define PTP_RTC6_REG_PTP_RTC_NFSEC_DEFAULT 0x0 + +struct ptp_rtc6_reg { + a_uint16_t ptp_rtc_nfsec:4; +}; + +union ptp_rtc6_reg_u { + a_uint32_t val; + struct ptp_rtc6_reg bf; +}; + +/*[register] PTP_RTCOFFS_VALID_REG*/ +#define PTP_RTCOFFS_VALID_REG +#define PTP_RTCOFFS_VALID_REG_ADDRESS 0x8044 +#define PTP_RTCOFFS_VALID_REG_NUM 1 +#define PTP_RTCOFFS_VALID_REG_INC 0x1 +#define PTP_RTCOFFS_VALID_REG_TYPE REG_TYPE_RW +#define PTP_RTCOFFS_VALID_REG_DEFAULT 0x0 + /*[field] PTP_RTCOFFS_VALID*/ + #define PTP_RTCOFFS_VALID_REG_PTP_RTCOFFS_VALID + #define PTP_RTCOFFS_VALID_REG_PTP_RTCOFFS_VALID_OFFSET 0 + #define PTP_RTCOFFS_VALID_REG_PTP_RTCOFFS_VALID_LEN 1 + #define PTP_RTCOFFS_VALID_REG_PTP_RTCOFFS_VALID_DEFAULT 0x0 + +struct ptp_rtcoffs_valid_reg { + a_uint16_t ptp_rtcoffs_valid:1; +}; + +union ptp_rtcoffs_valid_reg_u { + a_uint32_t val; + struct ptp_rtcoffs_valid_reg bf; +}; + +/*[register] PTP_MISC_CONFIG_REG*/ +#define PTP_MISC_CONFIG_REG +#define PTP_MISC_CONFIG_REG_ADDRESS 0x80f0 +#define PTP_MISC_CONFIG_REG_NUM 1 +#define PTP_MISC_CONFIG_REG_INC 0x1 +#define PTP_MISC_CONFIG_REG_TYPE REG_TYPE_RW +#define PTP_MISC_CONFIG_REG_DEFAULT 0x4 + /*[field] IPV6_UDP_CHK_EN*/ + #define PTP_MISC_CONFIG_REG_IPV6_UDP_CHK_EN + #define PTP_MISC_CONFIG_REG_IPV6_UDP_CHK_EN_OFFSET 0 + #define PTP_MISC_CONFIG_REG_IPV6_UDP_CHK_EN_LEN 1 + #define PTP_MISC_CONFIG_REG_IPV6_UDP_CHK_EN_DEFAULT 0x0 + /*[field] PTP_VERSION*/ + #define PTP_MISC_CONFIG_REG_PTP_VERSION + #define PTP_MISC_CONFIG_REG_PTP_VERSION_OFFSET 1 + #define PTP_MISC_CONFIG_REG_PTP_VERSION_LEN 4 + #define PTP_MISC_CONFIG_REG_PTP_VERSION_DEFAULT 0x2 + /*[field] PTP_VER_CHK_EN*/ + #define PTP_MISC_CONFIG_REG_PTP_VER_CHK_EN + #define PTP_MISC_CONFIG_REG_PTP_VER_CHK_EN_OFFSET 5 + #define PTP_MISC_CONFIG_REG_PTP_VER_CHK_EN_LEN 1 + #define PTP_MISC_CONFIG_REG_PTP_VER_CHK_EN_DEFAULT 0x0 + /*[field] PTP_ADDR_CHK_EN*/ + #define PTP_MISC_CONFIG_REG_PTP_ADDR_CHK_EN + #define PTP_MISC_CONFIG_REG_PTP_ADDR_CHK_EN_OFFSET 6 + #define PTP_MISC_CONFIG_REG_PTP_ADDR_CHK_EN_LEN 1 + #define PTP_MISC_CONFIG_REG_PTP_ADDR_CHK_EN_DEFAULT 0x0 + /*[field] CRC_VALIDATE_EN*/ + #define PTP_MISC_CONFIG_REG_CRC_VALIDATE_EN + #define PTP_MISC_CONFIG_REG_CRC_VALIDATE_EN_OFFSET 7 + #define PTP_MISC_CONFIG_REG_CRC_VALIDATE_EN_LEN 1 + #define PTP_MISC_CONFIG_REG_CRC_VALIDATE_EN_DEFAULT 0x0 + /*[field] APPENDED_TIMESTAMP_SIZE*/ + #define PTP_MISC_CONFIG_REG_APPENDED_TIMESTAMP_SIZE + #define PTP_MISC_CONFIG_REG_APPENDED_TIMESTAMP_SIZE_OFFSET 8 + #define PTP_MISC_CONFIG_REG_APPENDED_TIMESTAMP_SIZE_LEN 2 + #define PTP_MISC_CONFIG_REG_APPENDED_TIMESTAMP_SIZE_DEFAULT 0x0 + /*[field] TS_RTC_SELECT*/ + #define PTP_MISC_CONFIG_REG_TS_RTC_SELECT + #define PTP_MISC_CONFIG_REG_TS_RTC_SELECT_OFFSET 10 + #define PTP_MISC_CONFIG_REG_TS_RTC_SELECT_LEN 1 + #define PTP_MISC_CONFIG_REG_TS_RTC_SELECT_DEFAULT 0x0 + /*[field] PKT_ONE_STEP_EN*/ + #define PTP_MISC_CONFIG_REG_PKT_ONE_STEP_EN + #define PTP_MISC_CONFIG_REG_PKT_ONE_STEP_EN_OFFSET 11 + #define PTP_MISC_CONFIG_REG_PKT_ONE_STEP_EN_LEN 1 + #define PTP_MISC_CONFIG_REG_PKT_ONE_STEP_EN_DEFAULT 0x0 + /*[field] CF_FROM_PKT_EN*/ + #define PTP_MISC_CONFIG_REG_CF_FROM_PKT_EN + #define PTP_MISC_CONFIG_REG_CF_FROM_PKT_EN_OFFSET 12 + #define PTP_MISC_CONFIG_REG_CF_FROM_PKT_EN_LEN 1 + #define PTP_MISC_CONFIG_REG_CF_FROM_PKT_EN_DEFAULT 0x0 + /*[field] EMBED_INGRESS_TIME_EN*/ + #define PTP_MISC_CONFIG_REG_EMBED_INGRESS_TIME_EN + #define PTP_MISC_CONFIG_REG_EMBED_INGRESS_TIME_EN_OFFSET 13 + #define PTP_MISC_CONFIG_REG_EMBED_INGRESS_TIME_EN_LEN 1 + #define PTP_MISC_CONFIG_REG_EMBED_INGRESS_TIME_EN_DEFAULT 0x0 + /*[field] DROP_NEXT_PREAMBLE_EN*/ + #define PTP_MISC_CONFIG_REG_DROP_NEXT_PREAMBLE_EN + #define PTP_MISC_CONFIG_REG_DROP_NEXT_PREAMBLE_EN_OFFSET 14 + #define PTP_MISC_CONFIG_REG_DROP_NEXT_PREAMBLE_EN_LEN 1 + #define PTP_MISC_CONFIG_REG_DROP_NEXT_PREAMBLE_EN_DEFAULT 0x0 + /*[field] P2P_TC_OFFLOAD*/ + #define PTP_MISC_CONFIG_REG_P2P_TC_OFFLOAD + #define PTP_MISC_CONFIG_REG_P2P_TC_OFFLOAD_OFFSET 15 + #define PTP_MISC_CONFIG_REG_P2P_TC_OFFLOAD_LEN 1 + #define PTP_MISC_CONFIG_REG_P2P_TC_OFFLOAD_DEFAULT 0x0 + +struct ptp_misc_config_reg { + a_uint16_t ipv6_udp_chk_en:1; + a_uint16_t ptp_version:4; + a_uint16_t ptp_ver_chk_en:1; + a_uint16_t ptp_addr_chk_en:1; + a_uint16_t crc_validate_en:1; + a_uint16_t appended_timestamp_size:2; + a_uint16_t ts_rtc_select:1; + a_uint16_t pkt_one_step_en:1; + a_uint16_t cf_from_pkt_en:1; + a_uint16_t embed_ingress_time_en:1; + a_uint16_t drop_next_preamble_en:1; + a_uint16_t tc_offload:1; +}; + +union ptp_misc_config_reg_u { + a_uint32_t val; + struct ptp_misc_config_reg bf; +}; + +/*[register] PTP_EXT_IMR_REG*/ +#define PTP_EXT_IMR_REG +#define PTP_EXT_IMR_REG_ADDRESS 0x80f1 +#define PTP_EXT_IMR_REG_NUM 1 +#define PTP_EXT_IMR_REG_INC 0x1 +#define PTP_EXT_IMR_REG_TYPE REG_TYPE_RW +#define PTP_EXT_IMR_REG_DEFAULT 0x0 + /*[field] MASK_BMP*/ + #define PTP_EXT_IMR_REG_MASK_BMP + #define PTP_EXT_IMR_REG_MASK_BMP_OFFSET 0 + #define PTP_EXT_IMR_REG_MASK_BMP_LEN 5 + #define PTP_EXT_IMR_REG_MASK_BMP_DEFAULT 0x0 + +struct ptp_ext_imr_reg { + a_uint16_t mask_bmp:16; +}; + +union ptp_ext_imr_reg_u { + a_uint32_t val; + struct ptp_ext_imr_reg bf; +}; + +/*[register] PTP_EXT_ISR_REG*/ +#define PTP_EXT_ISR_REG +#define PTP_EXT_ISR_REG_ADDRESS 0x80f2 +#define PTP_EXT_ISR_REG_NUM 1 +#define PTP_EXT_ISR_REG_INC 0x1 +#define PTP_EXT_ISR_REG_TYPE REG_TYPE_RW +#define PTP_EXT_ISR_REG_DEFAULT 0x0 + /*[field] STATUS_BMP*/ + #define PTP_EXT_ISR_REG_STATUS_BMP + #define PTP_EXT_ISR_REG_STATUS_BMP_OFFSET 0 + #define PTP_EXT_ISR_REG_STATUS_BMP_LEN 5 + #define PTP_EXT_ISR_REG_STATUS_BMP_DEFAULT 0x0 + +struct ptp_ext_isr_reg { + a_uint16_t status_bmp:16; +}; + +union ptp_ext_isr_reg_u { + a_uint32_t val; + struct ptp_ext_isr_reg bf; +}; + +/*[register] PTP_RTC_EXT_CONF_REG*/ +#define PTP_RTC_EXT_CONF_REG +#define PTP_RTC_EXT_CONF_REG_ADDRESS 0x8100 +#define PTP_RTC_EXT_CONF_REG_NUM 1 +#define PTP_RTC_EXT_CONF_REG_INC 0x1 +#define PTP_RTC_EXT_CONF_REG_TYPE REG_TYPE_RW +#define PTP_RTC_EXT_CONF_REG_DEFAULT 0x0 + /*[field] LOAD_RTC*/ + #define PTP_RTC_EXT_CONF_REG_LOAD_RTC + #define PTP_RTC_EXT_CONF_REG_LOAD_RTC_OFFSET 0 + #define PTP_RTC_EXT_CONF_REG_LOAD_RTC_LEN 1 + #define PTP_RTC_EXT_CONF_REG_LOAD_RTC_DEFAULT 0x0 + /*[field] CLEAR_RTC*/ + #define PTP_RTC_EXT_CONF_REG_CLEAR_RTC + #define PTP_RTC_EXT_CONF_REG_CLEAR_RTC_OFFSET 1 + #define PTP_RTC_EXT_CONF_REG_CLEAR_RTC_LEN 1 + #define PTP_RTC_EXT_CONF_REG_CLEAR_RTC_DEFAULT 0x0 + /*[field] SET_INCVAL_VALID*/ + #define PTP_RTC_EXT_CONF_REG_SET_INCVAL_VALID + #define PTP_RTC_EXT_CONF_REG_SET_INCVAL_VALID_OFFSET 2 + #define PTP_RTC_EXT_CONF_REG_SET_INCVAL_VALID_LEN 1 + #define PTP_RTC_EXT_CONF_REG_SET_INCVAL_VALID_DEFAULT 0x0 + /*[field] SET_INCVAL_MODE*/ + #define PTP_RTC_EXT_CONF_REG_SET_INCVAL_MODE + #define PTP_RTC_EXT_CONF_REG_SET_INCVAL_MODE_OFFSET 3 + #define PTP_RTC_EXT_CONF_REG_SET_INCVAL_MODE_LEN 1 + #define PTP_RTC_EXT_CONF_REG_SET_INCVAL_MODE_DEFAULT 0x0 + /*[field] RTC_SNAPSHOT*/ + #define PTP_RTC_EXT_CONF_REG_RTC_SNAPSHOT + #define PTP_RTC_EXT_CONF_REG_RTC_SNAPSHOT_OFFSET 4 + #define PTP_RTC_EXT_CONF_REG_RTC_SNAPSHOT_LEN 1 + #define PTP_RTC_EXT_CONF_REG_RTC_SNAPSHOT_DEFAULT 0x0 + /*[field] RTC_READ_MODE*/ + #define PTP_RTC_EXT_CONF_REG_RTC_READ_MODE + #define PTP_RTC_EXT_CONF_REG_RTC_READ_MODE_OFFSET 5 + #define PTP_RTC_EXT_CONF_REG_RTC_READ_MODE_LEN 1 + #define PTP_RTC_EXT_CONF_REG_RTC_READ_MODE_DEFAULT 0x0 + /*[field] SELECT_OUTPUT_WAVEFORM*/ + #define PTP_RTC_EXT_CONF_REG_SELECT_OUTPUT_WAVEFORM + #define PTP_RTC_EXT_CONF_REG_SELECT_OUTPUT_WAVEFORM_OFFSET 6 + #define PTP_RTC_EXT_CONF_REG_SELECT_OUTPUT_WAVEFORM_LEN 3 + #define PTP_RTC_EXT_CONF_REG_SELECT_OUTPUT_WAVEFORM_DEFAULT 0x0 + +#define PTP_RTC_EXT_CONF_REG_SELECT_OUTPUT_WAVEFORM_FREQ 0 +#define PTP_RTC_EXT_CONF_REG_SELECT_OUTPUT_WAVEFORM_PULSE_10MS 2 +#define PTP_RTC_EXT_CONF_REG_SELECT_OUTPUT_WAVEFORM_TRIG0_GPIO 5 +#define PTP_RTC_EXT_CONF_REG_SELECT_OUTPUT_WAVEFORM_RXTS_VALID 7 + +struct ptp_rtc_ext_conf_reg { + a_uint16_t load_rtc:1; + a_uint16_t clear_rtc:1; + a_uint16_t set_incval_valid:1; + a_uint16_t set_incval_mode:1; + a_uint16_t rtc_snapshot:1; + a_uint16_t rtc_read_mode:1; + a_uint16_t select_output_waveform:3; +}; + +union ptp_rtc_ext_conf_reg_u { + a_uint32_t val; + struct ptp_rtc_ext_conf_reg bf; +}; + +/*[register] PTP_RTC_PRELOADED0_REG*/ +#define PTP_RTC_PRELOADED0_REG +#define PTP_RTC_PRELOADED0_REG_ADDRESS 0x8101 +#define PTP_RTC_PRELOADED0_REG_NUM 1 +#define PTP_RTC_PRELOADED0_REG_INC 0x1 +#define PTP_RTC_PRELOADED0_REG_TYPE REG_TYPE_RW +#define PTP_RTC_PRELOADED0_REG_DEFAULT 0x0 + /*[field] PTP_RTC_PRELOADED_SEC*/ + #define PTP_RTC_PRELOADED0_REG_PTP_RTC_PRELOADED_SEC + #define PTP_RTC_PRELOADED0_REG_PTP_RTC_PRELOADED_SEC_OFFSET 0 + #define PTP_RTC_PRELOADED0_REG_PTP_RTC_PRELOADED_SEC_LEN 16 + #define PTP_RTC_PRELOADED0_REG_PTP_RTC_PRELOADED_SEC_DEFAULT 0x0 + +struct ptp_rtc_preloaded0_reg { + a_uint16_t ptp_rtc_preloaded_sec:16; +}; + +union ptp_rtc_preloaded0_reg_u { + a_uint32_t val; + struct ptp_rtc_preloaded0_reg bf; +}; + +/*[register] PTP_RTC_PRELOADED1_REG*/ +#define PTP_RTC_PRELOADED1_REG +#define PTP_RTC_PRELOADED1_REG_ADDRESS 0x8102 +#define PTP_RTC_PRELOADED1_REG_NUM 1 +#define PTP_RTC_PRELOADED1_REG_INC 0x1 +#define PTP_RTC_PRELOADED1_REG_TYPE REG_TYPE_RW +#define PTP_RTC_PRELOADED1_REG_DEFAULT 0x0 + /*[field] PTP_RTC_PRELOADED_SEC*/ + #define PTP_RTC_PRELOADED1_REG_PTP_RTC_PRELOADED_SEC + #define PTP_RTC_PRELOADED1_REG_PTP_RTC_PRELOADED_SEC_OFFSET 0 + #define PTP_RTC_PRELOADED1_REG_PTP_RTC_PRELOADED_SEC_LEN 16 + #define PTP_RTC_PRELOADED1_REG_PTP_RTC_PRELOADED_SEC_DEFAULT 0x0 + +struct ptp_rtc_preloaded1_reg { + a_uint16_t ptp_rtc_preloaded_sec:16; +}; + +union ptp_rtc_preloaded1_reg_u { + a_uint32_t val; + struct ptp_rtc_preloaded1_reg bf; +}; + +/*[register] PTP_RTC_PRELOADED2_REG*/ +#define PTP_RTC_PRELOADED2_REG +#define PTP_RTC_PRELOADED2_REG_ADDRESS 0x8103 +#define PTP_RTC_PRELOADED2_REG_NUM 1 +#define PTP_RTC_PRELOADED2_REG_INC 0x1 +#define PTP_RTC_PRELOADED2_REG_TYPE REG_TYPE_RW +#define PTP_RTC_PRELOADED2_REG_DEFAULT 0x0 + /*[field] PTP_RTC_PRELOADED_SEC*/ + #define PTP_RTC_PRELOADED2_REG_PTP_RTC_PRELOADED_SEC + #define PTP_RTC_PRELOADED2_REG_PTP_RTC_PRELOADED_SEC_OFFSET 0 + #define PTP_RTC_PRELOADED2_REG_PTP_RTC_PRELOADED_SEC_LEN 16 + #define PTP_RTC_PRELOADED2_REG_PTP_RTC_PRELOADED_SEC_DEFAULT 0x0 + +struct ptp_rtc_preloaded2_reg { + a_uint16_t ptp_rtc_preloaded_sec:16; +}; + +union ptp_rtc_preloaded2_reg_u { + a_uint32_t val; + struct ptp_rtc_preloaded2_reg bf; +}; + +/*[register] PTP_RTC_PRELOADED3_REG*/ +#define PTP_RTC_PRELOADED3_REG +#define PTP_RTC_PRELOADED3_REG_ADDRESS 0x8104 +#define PTP_RTC_PRELOADED3_REG_NUM 1 +#define PTP_RTC_PRELOADED3_REG_INC 0x1 +#define PTP_RTC_PRELOADED3_REG_TYPE REG_TYPE_RW +#define PTP_RTC_PRELOADED3_REG_DEFAULT 0x0 + /*[field] PTP_RTC_PRELOADED_NISEC*/ + #define PTP_RTC_PRELOADED3_REG_PTP_RTC_PRELOADED_NISEC + #define PTP_RTC_PRELOADED3_REG_PTP_RTC_PRELOADED_NISEC_OFFSET 0 + #define PTP_RTC_PRELOADED3_REG_PTP_RTC_PRELOADED_NISEC_LEN 16 + #define PTP_RTC_PRELOADED3_REG_PTP_RTC_PRELOADED_NISEC_DEFAULT 0x0 + +struct ptp_rtc_preloaded3_reg { + a_uint16_t ptp_rtc_preloaded_nisec:16; +}; + +union ptp_rtc_preloaded3_reg_u { + a_uint32_t val; + struct ptp_rtc_preloaded3_reg bf; +}; + +/*[register] PTP_RTC_PRELOADED4_REG*/ +#define PTP_RTC_PRELOADED4_REG +#define PTP_RTC_PRELOADED4_REG_ADDRESS 0x8105 +#define PTP_RTC_PRELOADED4_REG_NUM 1 +#define PTP_RTC_PRELOADED4_REG_INC 0x1 +#define PTP_RTC_PRELOADED4_REG_TYPE REG_TYPE_RW +#define PTP_RTC_PRELOADED4_REG_DEFAULT 0x0 + /*[field] PTP_RTC_PRELOADED_NISEC*/ + #define PTP_RTC_PRELOADED4_REG_PTP_RTC_PRELOADED_NISEC + #define PTP_RTC_PRELOADED4_REG_PTP_RTC_PRELOADED_NISEC_OFFSET 0 + #define PTP_RTC_PRELOADED4_REG_PTP_RTC_PRELOADED_NISEC_LEN 16 + #define PTP_RTC_PRELOADED4_REG_PTP_RTC_PRELOADED_NISEC_DEFAULT 0x0 + +struct ptp_rtc_preloaded4_reg { + a_uint16_t ptp_rtc_preloaded_nisec:16; +}; + +union ptp_rtc_preloaded4_reg_u { + a_uint32_t val; + struct ptp_rtc_preloaded4_reg bf; +}; + +/*[register] PTP_GM_CONF0_REG*/ +#define PTP_GM_CONF0_REG +#define PTP_GM_CONF0_REG_ADDRESS 0x8200 +#define PTP_GM_CONF0_REG_NUM 1 +#define PTP_GM_CONF0_REG_INC 0x1 +#define PTP_GM_CONF0_REG_TYPE REG_TYPE_RW +#define PTP_GM_CONF0_REG_DEFAULT 0x0 + /*[field] GM_MAXFREQ_OFFSET*/ + #define PTP_GM_CONF0_REG_GM_MAXFREQ_OFFSET + #define PTP_GM_CONF0_REG_GM_MAXFREQ_OFFSET_OFFSET 0 + #define PTP_GM_CONF0_REG_GM_MAXFREQ_OFFSET_LEN 4 + #define PTP_GM_CONF0_REG_GM_MAXFREQ_OFFSET_DEFAULT 0x0 + /*[field] GM_PLL_MODE*/ + #define PTP_GM_CONF0_REG_GM_PLL_MODE + #define PTP_GM_CONF0_REG_GM_PLL_MODE_OFFSET 4 + #define PTP_GM_CONF0_REG_GM_PLL_MODE_LEN 1 + #define PTP_GM_CONF0_REG_GM_PLL_MODE_DEFAULT 0x0 + /*[field] GM_PPS_SYNC*/ + #define PTP_GM_CONF0_REG_GM_PPS_SYNC + #define PTP_GM_CONF0_REG_GM_PPS_SYNC_OFFSET 5 + #define PTP_GM_CONF0_REG_GM_PPS_SYNC_LEN 1 + #define PTP_GM_CONF0_REG_GM_PPS_SYNC_DEFAULT 0x0 + /*[field] GRANDMASTER_MODE*/ + #define PTP_GM_CONF0_REG_GRANDMASTER_MODE + #define PTP_GM_CONF0_REG_GRANDMASTER_MODE_OFFSET 6 + #define PTP_GM_CONF0_REG_GRANDMASTER_MODE_LEN 1 + #define PTP_GM_CONF0_REG_GRANDMASTER_MODE_DEFAULT 0x0 + +struct ptp_gm_conf0_reg { + a_uint16_t gm_maxfreq_offset:4; + a_uint16_t gm_pll_mode:1; + a_uint16_t gm_pps_sync:1; + a_uint16_t grandmaster_mode:1; +}; + +union ptp_gm_conf0_reg_u { + a_uint32_t val; + struct ptp_gm_conf0_reg bf; +}; + +/*[register] PTP_GM_CONF1_REG*/ +#define PTP_GM_CONF1_REG +#define PTP_GM_CONF1_REG_ADDRESS 0x8201 +#define PTP_GM_CONF1_REG_NUM 1 +#define PTP_GM_CONF1_REG_INC 0x1 +#define PTP_GM_CONF1_REG_TYPE REG_TYPE_RW +#define PTP_GM_CONF1_REG_DEFAULT 0x0 + /*[field] GM_KI_LDN*/ + #define PTP_GM_CONF1_REG_GM_KI_LDN + #define PTP_GM_CONF1_REG_GM_KI_LDN_OFFSET 0 + #define PTP_GM_CONF1_REG_GM_KI_LDN_LEN 6 + #define PTP_GM_CONF1_REG_GM_KI_LDN_DEFAULT 0x0 + /*[field] GM_KP_LDN*/ + #define PTP_GM_CONF1_REG_GM_KP_LDN + #define PTP_GM_CONF1_REG_GM_KP_LDN_OFFSET 6 + #define PTP_GM_CONF1_REG_GM_KP_LDN_LEN 6 + #define PTP_GM_CONF1_REG_GM_KP_LDN_DEFAULT 0x0 + +struct ptp_gm_conf1_reg { + a_uint16_t gm_ki_ldn:6; + a_uint16_t gm_kp_ldn:6; +}; + +union ptp_gm_conf1_reg_u { + a_uint32_t val; + struct ptp_gm_conf1_reg bf; +}; + +/*[register] PTP_PPSIN_TS0_REG*/ +#define PTP_PPSIN_TS0_REG +#define PTP_PPSIN_TS0_REG_ADDRESS 0x8202 +#define PTP_PPSIN_TS0_REG_NUM 1 +#define PTP_PPSIN_TS0_REG_INC 0x1 +#define PTP_PPSIN_TS0_REG_TYPE REG_TYPE_RW +#define PTP_PPSIN_TS0_REG_DEFAULT 0x0 + /*[field] RX_TS_SEC*/ + #define PTP_PPSIN_TS0_REG_RX_TS_SEC + #define PTP_PPSIN_TS0_REG_RX_TS_SEC_OFFSET 0 + #define PTP_PPSIN_TS0_REG_RX_TS_SEC_LEN 16 + #define PTP_PPSIN_TS0_REG_RX_TS_SEC_DEFAULT 0x0 + +struct ptp_ppsin_ts0_reg { + a_uint16_t rx_ts_sec:16; +}; + +union ptp_ppsin_ts0_reg_u { + a_uint32_t val; + struct ptp_ppsin_ts0_reg bf; +}; + +/*[register] PTP_PPSIN_TS1_REG*/ +#define PTP_PPSIN_TS1_REG +#define PTP_PPSIN_TS1_REG_ADDRESS 0x8203 +#define PTP_PPSIN_TS1_REG_NUM 1 +#define PTP_PPSIN_TS1_REG_INC 0x1 +#define PTP_PPSIN_TS1_REG_TYPE REG_TYPE_RW +#define PTP_PPSIN_TS1_REG_DEFAULT 0x0 + /*[field] RX_TS_SEC*/ + #define PTP_PPSIN_TS1_REG_RX_TS_SEC + #define PTP_PPSIN_TS1_REG_RX_TS_SEC_OFFSET 0 + #define PTP_PPSIN_TS1_REG_RX_TS_SEC_LEN 16 + #define PTP_PPSIN_TS1_REG_RX_TS_SEC_DEFAULT 0x0 + +struct ptp_ppsin_ts1_reg { + a_uint16_t rx_ts_sec:16; +}; + +union ptp_ppsin_ts1_reg_u { + a_uint32_t val; + struct ptp_ppsin_ts1_reg bf; +}; + +/*[register] PTP_PPSIN_TS2_REG*/ +#define PTP_PPSIN_TS2_REG +#define PTP_PPSIN_TS2_REG_ADDRESS 0x8204 +#define PTP_PPSIN_TS2_REG_NUM 1 +#define PTP_PPSIN_TS2_REG_INC 0x1 +#define PTP_PPSIN_TS2_REG_TYPE REG_TYPE_RW +#define PTP_PPSIN_TS2_REG_DEFAULT 0x0 + /*[field] RX_TS_SEC*/ + #define PTP_PPSIN_TS2_REG_RX_TS_SEC + #define PTP_PPSIN_TS2_REG_RX_TS_SEC_OFFSET 0 + #define PTP_PPSIN_TS2_REG_RX_TS_SEC_LEN 16 + #define PTP_PPSIN_TS2_REG_RX_TS_SEC_DEFAULT 0x0 + +struct ptp_ppsin_ts2_reg { + a_uint16_t rx_ts_sec:16; +}; + +union ptp_ppsin_ts2_reg_u { + a_uint32_t val; + struct ptp_ppsin_ts2_reg bf; +}; + +/*[register] PTP_PPSIN_TS3_REG*/ +#define PTP_PPSIN_TS3_REG +#define PTP_PPSIN_TS3_REG_ADDRESS 0x8205 +#define PTP_PPSIN_TS3_REG_NUM 1 +#define PTP_PPSIN_TS3_REG_INC 0x1 +#define PTP_PPSIN_TS3_REG_TYPE REG_TYPE_RW +#define PTP_PPSIN_TS3_REG_DEFAULT 0x0 + /*[field] RX_TS_NSEC*/ + #define PTP_PPSIN_TS3_REG_RX_TS_NSEC + #define PTP_PPSIN_TS3_REG_RX_TS_NSEC_OFFSET 0 + #define PTP_PPSIN_TS3_REG_RX_TS_NSEC_LEN 16 + #define PTP_PPSIN_TS3_REG_RX_TS_NSEC_DEFAULT 0x0 + +struct ptp_ppsin_ts3_reg { + a_uint16_t rx_ts_nsec:16; +}; + +union ptp_ppsin_ts3_reg_u { + a_uint32_t val; + struct ptp_ppsin_ts3_reg bf; +}; + +/*[register] PTP_PPSIN_TS4_REG*/ +#define PTP_PPSIN_TS4_REG +#define PTP_PPSIN_TS4_REG_ADDRESS 0x8206 +#define PTP_PPSIN_TS4_REG_NUM 1 +#define PTP_PPSIN_TS4_REG_INC 0x1 +#define PTP_PPSIN_TS4_REG_TYPE REG_TYPE_RW +#define PTP_PPSIN_TS4_REG_DEFAULT 0x0 + /*[field] RX_TS_NSEC*/ + #define PTP_PPSIN_TS4_REG_RX_TS_NSEC + #define PTP_PPSIN_TS4_REG_RX_TS_NSEC_OFFSET 0 + #define PTP_PPSIN_TS4_REG_RX_TS_NSEC_LEN 16 + #define PTP_PPSIN_TS4_REG_RX_TS_NSEC_DEFAULT 0x0 + +struct ptp_ppsin_ts4_reg { + a_uint16_t rx_ts_nsec:16; +}; + +union ptp_ppsin_ts4_reg_u { + a_uint32_t val; + struct ptp_ppsin_ts4_reg bf; +}; + +/*[register] PTP_HWPLL_INC0_REG*/ +#define PTP_HWPLL_INC0_REG +#define PTP_HWPLL_INC0_REG_ADDRESS 0x8207 +#define PTP_HWPLL_INC0_REG_NUM 1 +#define PTP_HWPLL_INC0_REG_INC 0x1 +#define PTP_HWPLL_INC0_REG_TYPE REG_TYPE_RW +#define PTP_HWPLL_INC0_REG_DEFAULT 0x0 + /*[field] PTP_RTC_INC_NFS1*/ + #define PTP_HWPLL_INC0_REG_PTP_RTC_INC_NFS1 + #define PTP_HWPLL_INC0_REG_PTP_RTC_INC_NFS1_OFFSET 0 + #define PTP_HWPLL_INC0_REG_PTP_RTC_INC_NFS1_LEN 10 + #define PTP_HWPLL_INC0_REG_PTP_RTC_INC_NFS1_DEFAULT 0x0 + /*[field] PTP_RTC_INC_NIS*/ + #define PTP_HWPLL_INC0_REG_PTP_RTC_INC_NIS + #define PTP_HWPLL_INC0_REG_PTP_RTC_INC_NIS_OFFSET 10 + #define PTP_HWPLL_INC0_REG_PTP_RTC_INC_NIS_LEN 6 + #define PTP_HWPLL_INC0_REG_PTP_RTC_INC_NIS_DEFAULT 0x0 + +struct ptp_hwpll_inc0_reg { + a_uint16_t ptp_rtc_inc_nfs1:10; + a_uint16_t ptp_rtc_inc_nis:6; +}; + +union ptp_hwpll_inc0_reg_u { + a_uint32_t val; + struct ptp_hwpll_inc0_reg bf; +}; + +/*[register] PTP_HWPLL_INC1_REG*/ +#define PTP_HWPLL_INC1_REG +#define PTP_HWPLL_INC1_REG_ADDRESS 0x8208 +#define PTP_HWPLL_INC1_REG_NUM 1 +#define PTP_HWPLL_INC1_REG_INC 0x1 +#define PTP_HWPLL_INC1_REG_TYPE REG_TYPE_RW +#define PTP_HWPLL_INC1_REG_DEFAULT 0x0 + /*[field] PTP_RTC_INC_NFS0*/ + #define PTP_HWPLL_INC1_REG_PTP_RTC_INC_NFS0 + #define PTP_HWPLL_INC1_REG_PTP_RTC_INC_NFS0_OFFSET 0 + #define PTP_HWPLL_INC1_REG_PTP_RTC_INC_NFS0_LEN 16 + #define PTP_HWPLL_INC1_REG_PTP_RTC_INC_NFS0_DEFAULT 0x0 + +struct ptp_hwpll_inc1_reg { + a_uint16_t ptp_rtc_inc_nfs0:16; +}; + +union ptp_hwpll_inc1_reg_u { + a_uint32_t val; + struct ptp_hwpll_inc1_reg bf; +}; + +/*[register] PTP_PPSIN_LATENCY_REG*/ +#define PTP_PPSIN_LATENCY_REG +#define PTP_PPSIN_LATENCY_REG_ADDRESS 0x8209 +#define PTP_PPSIN_LATENCY_REG_NUM 1 +#define PTP_PPSIN_LATENCY_REG_INC 0x1 +#define PTP_PPSIN_LATENCY_REG_TYPE REG_TYPE_RW +#define PTP_PPSIN_LATENCY_REG_DEFAULT 0x0 + /*[field] PTP_PPSIN_LATENCY_VALUE*/ + #define PTP_PPSIN_LATENCY_REG_PTP_PPSIN_LATENCY_VALUE + #define PTP_PPSIN_LATENCY_REG_PTP_PPSIN_LATENCY_VALUE_OFFSET 0 + #define PTP_PPSIN_LATENCY_REG_PTP_PPSIN_LATENCY_VALUE_LEN 7 + #define PTP_PPSIN_LATENCY_REG_PTP_PPSIN_LATENCY_VALUE_DEFAULT 0x0 + /*[field] PTP_PPSIN_LATENCY_SIGN*/ + #define PTP_PPSIN_LATENCY_REG_PTP_PPSIN_LATENCY_SIGN + #define PTP_PPSIN_LATENCY_REG_PTP_PPSIN_LATENCY_SIGN_OFFSET 7 + #define PTP_PPSIN_LATENCY_REG_PTP_PPSIN_LATENCY_SIGN_LEN 1 + #define PTP_PPSIN_LATENCY_REG_PTP_PPSIN_LATENCY_SIGN_DEFAULT 0x0 + +struct ptp_ppsin_latency_reg { + a_uint16_t ptp_ppsin_latency_value:7; + a_uint16_t ptp_ppsin_latency_sign:1; +}; + +union ptp_ppsin_latency_reg_u { + a_uint32_t val; + struct ptp_ppsin_latency_reg bf; +}; + +/*[register] PTP_TRIGGER0_CONFIG_REG*/ +#define PTP_TRIGGER0_CONFIG_REG +#define PTP_TRIGGER0_CONFIG_REG_ADDRESS 0x8400 +#define PTP_TRIGGER0_CONFIG_REG_NUM 1 +#define PTP_TRIGGER0_CONFIG_REG_INC 0x1 +#define PTP_TRIGGER0_CONFIG_REG_TYPE REG_TYPE_RW +#define PTP_TRIGGER0_CONFIG_REG_DEFAULT 0x0 + /*[field] STATUS*/ + #define PTP_TRIGGER0_CONFIG_REG_STATUS + #define PTP_TRIGGER0_CONFIG_REG_STATUS_OFFSET 0 + #define PTP_TRIGGER0_CONFIG_REG_STATUS_LEN 1 + #define PTP_TRIGGER0_CONFIG_REG_STATUS_DEFAULT 0x0 + /*[field] FORCE_EN*/ + #define PTP_TRIGGER0_CONFIG_REG_FORCE_EN + #define PTP_TRIGGER0_CONFIG_REG_FORCE_EN_OFFSET 1 + #define PTP_TRIGGER0_CONFIG_REG_FORCE_EN_LEN 1 + #define PTP_TRIGGER0_CONFIG_REG_FORCE_EN_DEFAULT 0x0 + /*[field] FORCE_VALUE*/ + #define PTP_TRIGGER0_CONFIG_REG_FORCE_VALUE + #define PTP_TRIGGER0_CONFIG_REG_FORCE_VALUE_OFFSET 2 + #define PTP_TRIGGER0_CONFIG_REG_FORCE_VALUE_LEN 1 + #define PTP_TRIGGER0_CONFIG_REG_FORCE_VALUE_DEFAULT 0x0 + /*[field] PATTERN*/ + #define PTP_TRIGGER0_CONFIG_REG_PATTERN + #define PTP_TRIGGER0_CONFIG_REG_PATTERN_OFFSET 3 + #define PTP_TRIGGER0_CONFIG_REG_PATTERN_LEN 3 + #define PTP_TRIGGER0_CONFIG_REG_PATTERN_DEFAULT 0x0 + /*[field] IF_LATE*/ + #define PTP_TRIGGER0_CONFIG_REG_IF_LATE + #define PTP_TRIGGER0_CONFIG_REG_IF_LATE_OFFSET 6 + #define PTP_TRIGGER0_CONFIG_REG_IF_LATE_LEN 1 + #define PTP_TRIGGER0_CONFIG_REG_IF_LATE_DEFAULT 0x0 + /*[field] NOTIFY*/ + #define PTP_TRIGGER0_CONFIG_REG_NOTIFY + #define PTP_TRIGGER0_CONFIG_REG_NOTIFY_OFFSET 7 + #define PTP_TRIGGER0_CONFIG_REG_NOTIFY_LEN 1 + #define PTP_TRIGGER0_CONFIG_REG_NOTIFY_DEFAULT 0x0 + /*[field] SETTING*/ + #define PTP_TRIGGER0_CONFIG_REG_SETTING + #define PTP_TRIGGER0_CONFIG_REG_SETTING_OFFSET 8 + #define PTP_TRIGGER0_CONFIG_REG_SETTING_LEN 1 + #define PTP_TRIGGER0_CONFIG_REG_SETTING_DEFAULT 0x0 + +struct ptp_trigger0_config_reg { + a_uint16_t status:1; + a_uint16_t force_en:1; + a_uint16_t force_value:1; + a_uint16_t pattern:3; + a_uint16_t if_late:1; + a_uint16_t notify:1; + a_uint16_t setting:1; +}; + +union ptp_trigger0_config_reg_u { + a_uint32_t val; + struct ptp_trigger0_config_reg bf; +}; + +/*[register] PTP_TRIGGER0_STATUS_REG*/ +#define PTP_TRIGGER0_STATUS_REG +#define PTP_TRIGGER0_STATUS_REG_ADDRESS 0x8401 +#define PTP_TRIGGER0_STATUS_REG_NUM 1 +#define PTP_TRIGGER0_STATUS_REG_INC 0x1 +#define PTP_TRIGGER0_STATUS_REG_TYPE REG_TYPE_RW +#define PTP_TRIGGER0_STATUS_REG_DEFAULT 0x0 + /*[field] FINISHED*/ + #define PTP_TRIGGER0_STATUS_REG_FINISHED + #define PTP_TRIGGER0_STATUS_REG_FINISHED_OFFSET 0 + #define PTP_TRIGGER0_STATUS_REG_FINISHED_LEN 1 + #define PTP_TRIGGER0_STATUS_REG_FINISHED_DEFAULT 0x0 + /*[field] ACTIVE*/ + #define PTP_TRIGGER0_STATUS_REG_ACTIVE + #define PTP_TRIGGER0_STATUS_REG_ACTIVE_OFFSET 1 + #define PTP_TRIGGER0_STATUS_REG_ACTIVE_LEN 1 + #define PTP_TRIGGER0_STATUS_REG_ACTIVE_DEFAULT 0x0 + /*[field] ERROR*/ + #define PTP_TRIGGER0_STATUS_REG_ERROR + #define PTP_TRIGGER0_STATUS_REG_ERROR_OFFSET 2 + #define PTP_TRIGGER0_STATUS_REG_ERROR_LEN 2 + #define PTP_TRIGGER0_STATUS_REG_ERROR_DEFAULT 0x0 + +struct ptp_trigger0_status_reg { + a_uint16_t finished:1; + a_uint16_t active:1; + a_uint16_t error:2; +}; + +union ptp_trigger0_status_reg_u { + a_uint32_t val; + struct ptp_trigger0_status_reg bf; +}; + +/*[register] PTP_TRIGGER1_CONFIG_REG*/ +#define PTP_TRIGGER1_CONFIG_REG +#define PTP_TRIGGER1_CONFIG_REG_ADDRESS 0x8402 +#define PTP_TRIGGER1_CONFIG_REG_NUM 1 +#define PTP_TRIGGER1_CONFIG_REG_INC 0x1 +#define PTP_TRIGGER1_CONFIG_REG_TYPE REG_TYPE_RW +#define PTP_TRIGGER1_CONFIG_REG_DEFAULT 0x0 + /*[field] STATUS*/ + #define PTP_TRIGGER1_CONFIG_REG_STATUS + #define PTP_TRIGGER1_CONFIG_REG_STATUS_OFFSET 0 + #define PTP_TRIGGER1_CONFIG_REG_STATUS_LEN 1 + #define PTP_TRIGGER1_CONFIG_REG_STATUS_DEFAULT 0x0 + /*[field] FORCE_EN*/ + #define PTP_TRIGGER1_CONFIG_REG_FORCE_EN + #define PTP_TRIGGER1_CONFIG_REG_FORCE_EN_OFFSET 1 + #define PTP_TRIGGER1_CONFIG_REG_FORCE_EN_LEN 1 + #define PTP_TRIGGER1_CONFIG_REG_FORCE_EN_DEFAULT 0x0 + /*[field] FORCE_VALUE*/ + #define PTP_TRIGGER1_CONFIG_REG_FORCE_VALUE + #define PTP_TRIGGER1_CONFIG_REG_FORCE_VALUE_OFFSET 2 + #define PTP_TRIGGER1_CONFIG_REG_FORCE_VALUE_LEN 1 + #define PTP_TRIGGER1_CONFIG_REG_FORCE_VALUE_DEFAULT 0x0 + /*[field] PATTERN*/ + #define PTP_TRIGGER1_CONFIG_REG_PATTERN + #define PTP_TRIGGER1_CONFIG_REG_PATTERN_OFFSET 3 + #define PTP_TRIGGER1_CONFIG_REG_PATTERN_LEN 3 + #define PTP_TRIGGER1_CONFIG_REG_PATTERN_DEFAULT 0x0 + /*[field] IF_LATE*/ + #define PTP_TRIGGER1_CONFIG_REG_IF_LATE + #define PTP_TRIGGER1_CONFIG_REG_IF_LATE_OFFSET 6 + #define PTP_TRIGGER1_CONFIG_REG_IF_LATE_LEN 1 + #define PTP_TRIGGER1_CONFIG_REG_IF_LATE_DEFAULT 0x0 + /*[field] NOTIFY*/ + #define PTP_TRIGGER1_CONFIG_REG_NOTIFY + #define PTP_TRIGGER1_CONFIG_REG_NOTIFY_OFFSET 7 + #define PTP_TRIGGER1_CONFIG_REG_NOTIFY_LEN 1 + #define PTP_TRIGGER1_CONFIG_REG_NOTIFY_DEFAULT 0x0 + /*[field] SETTING*/ + #define PTP_TRIGGER1_CONFIG_REG_SETTING + #define PTP_TRIGGER1_CONFIG_REG_SETTING_OFFSET 8 + #define PTP_TRIGGER1_CONFIG_REG_SETTING_LEN 1 + #define PTP_TRIGGER1_CONFIG_REG_SETTING_DEFAULT 0x0 + +struct ptp_trigger1_config_reg { + a_uint16_t status:1; + a_uint16_t force_en:1; + a_uint16_t force_value:1; + a_uint16_t pattern:3; + a_uint16_t if_late:1; + a_uint16_t notify:1; + a_uint16_t setting:1; +}; + +union ptp_trigger1_config_reg_u { + a_uint32_t val; + struct ptp_trigger1_config_reg bf; +}; + +/*[register] PTP_TRIGGER1_STATUS_REG*/ +#define PTP_TRIGGER1_STATUS_REG +#define PTP_TRIGGER1_STATUS_REG_ADDRESS 0x8403 +#define PTP_TRIGGER1_STATUS_REG_NUM 1 +#define PTP_TRIGGER1_STATUS_REG_INC 0x1 +#define PTP_TRIGGER1_STATUS_REG_TYPE REG_TYPE_RW +#define PTP_TRIGGER1_STATUS_REG_DEFAULT 0x0 + /*[field] FINISHED*/ + #define PTP_TRIGGER1_STATUS_REG_FINISHED + #define PTP_TRIGGER1_STATUS_REG_FINISHED_OFFSET 0 + #define PTP_TRIGGER1_STATUS_REG_FINISHED_LEN 1 + #define PTP_TRIGGER1_STATUS_REG_FINISHED_DEFAULT 0x0 + /*[field] ACTIVE*/ + #define PTP_TRIGGER1_STATUS_REG_ACTIVE + #define PTP_TRIGGER1_STATUS_REG_ACTIVE_OFFSET 1 + #define PTP_TRIGGER1_STATUS_REG_ACTIVE_LEN 1 + #define PTP_TRIGGER1_STATUS_REG_ACTIVE_DEFAULT 0x0 + /*[field] ERROR*/ + #define PTP_TRIGGER1_STATUS_REG_ERROR + #define PTP_TRIGGER1_STATUS_REG_ERROR_OFFSET 2 + #define PTP_TRIGGER1_STATUS_REG_ERROR_LEN 2 + #define PTP_TRIGGER1_STATUS_REG_ERROR_DEFAULT 0x0 + +struct ptp_trigger1_status_reg { + a_uint16_t finished:1; + a_uint16_t active:1; + a_uint16_t error:2; +}; + +union ptp_trigger1_status_reg_u { + a_uint32_t val; + struct ptp_trigger1_status_reg bf; +}; + +/*[register] PTP_TRIGGER0_TIMESTAMP0_REG*/ +#define PTP_TRIGGER0_TIMESTAMP0_REG +#define PTP_TRIGGER0_TIMESTAMP0_REG_ADDRESS 0x8404 +#define PTP_TRIGGER0_TIMESTAMP0_REG_NUM 1 +#define PTP_TRIGGER0_TIMESTAMP0_REG_INC 0x1 +#define PTP_TRIGGER0_TIMESTAMP0_REG_TYPE REG_TYPE_RW +#define PTP_TRIGGER0_TIMESTAMP0_REG_DEFAULT 0x0 + /*[field] TS_SEC*/ + #define PTP_TRIGGER0_TIMESTAMP0_REG_TS_SEC + #define PTP_TRIGGER0_TIMESTAMP0_REG_TS_SEC_OFFSET 0 + #define PTP_TRIGGER0_TIMESTAMP0_REG_TS_SEC_LEN 16 + #define PTP_TRIGGER0_TIMESTAMP0_REG_TS_SEC_DEFAULT 0x0 + +struct ptp_trigger0_timestamp0_reg { + a_uint16_t ts_sec:16; +}; + +union ptp_trigger0_timestamp0_reg_u { + a_uint32_t val; + struct ptp_trigger0_timestamp0_reg bf; +}; + +/*[register] PTP_TRIGGER0_TIMESTAMP1_REG*/ +#define PTP_TRIGGER0_TIMESTAMP1_REG +#define PTP_TRIGGER0_TIMESTAMP1_REG_ADDRESS 0x8405 +#define PTP_TRIGGER0_TIMESTAMP1_REG_NUM 1 +#define PTP_TRIGGER0_TIMESTAMP1_REG_INC 0x1 +#define PTP_TRIGGER0_TIMESTAMP1_REG_TYPE REG_TYPE_RW +#define PTP_TRIGGER0_TIMESTAMP1_REG_DEFAULT 0x0 + /*[field] TS_SEC*/ + #define PTP_TRIGGER0_TIMESTAMP1_REG_TS_SEC + #define PTP_TRIGGER0_TIMESTAMP1_REG_TS_SEC_OFFSET 0 + #define PTP_TRIGGER0_TIMESTAMP1_REG_TS_SEC_LEN 16 + #define PTP_TRIGGER0_TIMESTAMP1_REG_TS_SEC_DEFAULT 0x0 + +struct ptp_trigger0_timestamp1_reg { + a_uint16_t ts_sec:16; +}; + +union ptp_trigger0_timestamp1_reg_u { + a_uint32_t val; + struct ptp_trigger0_timestamp1_reg bf; +}; + +/*[register] PTP_TRIGGER0_TIMESTAMP2_REG*/ +#define PTP_TRIGGER0_TIMESTAMP2_REG +#define PTP_TRIGGER0_TIMESTAMP2_REG_ADDRESS 0x8406 +#define PTP_TRIGGER0_TIMESTAMP2_REG_NUM 1 +#define PTP_TRIGGER0_TIMESTAMP2_REG_INC 0x1 +#define PTP_TRIGGER0_TIMESTAMP2_REG_TYPE REG_TYPE_RW +#define PTP_TRIGGER0_TIMESTAMP2_REG_DEFAULT 0x0 + /*[field] TS_SEC*/ + #define PTP_TRIGGER0_TIMESTAMP2_REG_TS_SEC + #define PTP_TRIGGER0_TIMESTAMP2_REG_TS_SEC_OFFSET 0 + #define PTP_TRIGGER0_TIMESTAMP2_REG_TS_SEC_LEN 16 + #define PTP_TRIGGER0_TIMESTAMP2_REG_TS_SEC_DEFAULT 0x0 + +struct ptp_trigger0_timestamp2_reg { + a_uint16_t ts_sec:16; +}; + +union ptp_trigger0_timestamp2_reg_u { + a_uint32_t val; + struct ptp_trigger0_timestamp2_reg bf; +}; + +/*[register] PTP_TRIGGER0_TIMESTAMP3_REG*/ +#define PTP_TRIGGER0_TIMESTAMP3_REG +#define PTP_TRIGGER0_TIMESTAMP3_REG_ADDRESS 0x8407 +#define PTP_TRIGGER0_TIMESTAMP3_REG_NUM 1 +#define PTP_TRIGGER0_TIMESTAMP3_REG_INC 0x1 +#define PTP_TRIGGER0_TIMESTAMP3_REG_TYPE REG_TYPE_RW +#define PTP_TRIGGER0_TIMESTAMP3_REG_DEFAULT 0x0 + /*[field] TS_NSEC*/ + #define PTP_TRIGGER0_TIMESTAMP3_REG_TS_NSEC + #define PTP_TRIGGER0_TIMESTAMP3_REG_TS_NSEC_OFFSET 0 + #define PTP_TRIGGER0_TIMESTAMP3_REG_TS_NSEC_LEN 16 + #define PTP_TRIGGER0_TIMESTAMP3_REG_TS_NSEC_DEFAULT 0x0 + +struct ptp_trigger0_timestamp3_reg { + a_uint16_t ts_nsec:16; +}; + +union ptp_trigger0_timestamp3_reg_u { + a_uint32_t val; + struct ptp_trigger0_timestamp3_reg bf; +}; + +/*[register] PTP_TRIGGER0_TIMESTAMP4_REG*/ +#define PTP_TRIGGER0_TIMESTAMP4_REG +#define PTP_TRIGGER0_TIMESTAMP4_REG_ADDRESS 0x8408 +#define PTP_TRIGGER0_TIMESTAMP4_REG_NUM 1 +#define PTP_TRIGGER0_TIMESTAMP4_REG_INC 0x1 +#define PTP_TRIGGER0_TIMESTAMP4_REG_TYPE REG_TYPE_RW +#define PTP_TRIGGER0_TIMESTAMP4_REG_DEFAULT 0x0 + /*[field] TS_NSEC*/ + #define PTP_TRIGGER0_TIMESTAMP4_REG_TS_NSEC + #define PTP_TRIGGER0_TIMESTAMP4_REG_TS_NSEC_OFFSET 0 + #define PTP_TRIGGER0_TIMESTAMP4_REG_TS_NSEC_LEN 16 + #define PTP_TRIGGER0_TIMESTAMP4_REG_TS_NSEC_DEFAULT 0x0 + +struct ptp_trigger0_timestamp4_reg { + a_uint16_t ts_nsec:16; +}; + +union ptp_trigger0_timestamp4_reg_u { + a_uint32_t val; + struct ptp_trigger0_timestamp4_reg bf; +}; + +/*[register] PTP_TRIGGER1_TIMESTAMP0_REG*/ +#define PTP_TRIGGER1_TIMESTAMP0_REG +#define PTP_TRIGGER1_TIMESTAMP0_REG_ADDRESS 0x8409 +#define PTP_TRIGGER1_TIMESTAMP0_REG_NUM 1 +#define PTP_TRIGGER1_TIMESTAMP0_REG_INC 0x1 +#define PTP_TRIGGER1_TIMESTAMP0_REG_TYPE REG_TYPE_RW +#define PTP_TRIGGER1_TIMESTAMP0_REG_DEFAULT 0x0 + /*[field] TS_SEC*/ + #define PTP_TRIGGER1_TIMESTAMP0_REG_TS_SEC + #define PTP_TRIGGER1_TIMESTAMP0_REG_TS_SEC_OFFSET 0 + #define PTP_TRIGGER1_TIMESTAMP0_REG_TS_SEC_LEN 16 + #define PTP_TRIGGER1_TIMESTAMP0_REG_TS_SEC_DEFAULT 0x0 + +struct ptp_trigger1_timestamp0_reg { + a_uint16_t ts_sec:16; +}; + +union ptp_trigger1_timestamp0_reg_u { + a_uint32_t val; + struct ptp_trigger1_timestamp0_reg bf; +}; + +/*[register] PTP_TRIGGER1_TIMESTAMP1_REG*/ +#define PTP_TRIGGER1_TIMESTAMP1_REG +#define PTP_TRIGGER1_TIMESTAMP1_REG_ADDRESS 0x840a +#define PTP_TRIGGER1_TIMESTAMP1_REG_NUM 1 +#define PTP_TRIGGER1_TIMESTAMP1_REG_INC 0x1 +#define PTP_TRIGGER1_TIMESTAMP1_REG_TYPE REG_TYPE_RW +#define PTP_TRIGGER1_TIMESTAMP1_REG_DEFAULT 0x0 + /*[field] TS_SEC*/ + #define PTP_TRIGGER1_TIMESTAMP1_REG_TS_SEC + #define PTP_TRIGGER1_TIMESTAMP1_REG_TS_SEC_OFFSET 0 + #define PTP_TRIGGER1_TIMESTAMP1_REG_TS_SEC_LEN 16 + #define PTP_TRIGGER1_TIMESTAMP1_REG_TS_SEC_DEFAULT 0x0 + +struct ptp_trigger1_timestamp1_reg { + a_uint16_t ts_sec:16; +}; + +union ptp_trigger1_timestamp1_reg_u { + a_uint32_t val; + struct ptp_trigger1_timestamp1_reg bf; +}; + +/*[register] PTP_TRIGGER1_TIMESTAMP2_REG*/ +#define PTP_TRIGGER1_TIMESTAMP2_REG +#define PTP_TRIGGER1_TIMESTAMP2_REG_ADDRESS 0x840b +#define PTP_TRIGGER1_TIMESTAMP2_REG_NUM 1 +#define PTP_TRIGGER1_TIMESTAMP2_REG_INC 0x1 +#define PTP_TRIGGER1_TIMESTAMP2_REG_TYPE REG_TYPE_RW +#define PTP_TRIGGER1_TIMESTAMP2_REG_DEFAULT 0x0 + /*[field] TS_SEC*/ + #define PTP_TRIGGER1_TIMESTAMP2_REG_TS_SEC + #define PTP_TRIGGER1_TIMESTAMP2_REG_TS_SEC_OFFSET 0 + #define PTP_TRIGGER1_TIMESTAMP2_REG_TS_SEC_LEN 16 + #define PTP_TRIGGER1_TIMESTAMP2_REG_TS_SEC_DEFAULT 0x0 + +struct ptp_trigger1_timestamp2_reg { + a_uint16_t ts_sec:16; +}; + +union ptp_trigger1_timestamp2_reg_u { + a_uint32_t val; + struct ptp_trigger1_timestamp2_reg bf; +}; + +/*[register] PTP_TRIGGER1_TIMESTAMP3_REG*/ +#define PTP_TRIGGER1_TIMESTAMP3_REG +#define PTP_TRIGGER1_TIMESTAMP3_REG_ADDRESS 0x840c +#define PTP_TRIGGER1_TIMESTAMP3_REG_NUM 1 +#define PTP_TRIGGER1_TIMESTAMP3_REG_INC 0x1 +#define PTP_TRIGGER1_TIMESTAMP3_REG_TYPE REG_TYPE_RW +#define PTP_TRIGGER1_TIMESTAMP3_REG_DEFAULT 0x0 + /*[field] TS_NSEC*/ + #define PTP_TRIGGER1_TIMESTAMP3_REG_TS_NSEC + #define PTP_TRIGGER1_TIMESTAMP3_REG_TS_NSEC_OFFSET 0 + #define PTP_TRIGGER1_TIMESTAMP3_REG_TS_NSEC_LEN 16 + #define PTP_TRIGGER1_TIMESTAMP3_REG_TS_NSEC_DEFAULT 0x0 + +struct ptp_trigger1_timestamp3_reg { + a_uint16_t ts_nsec:16; +}; + +union ptp_trigger1_timestamp3_reg_u { + a_uint32_t val; + struct ptp_trigger1_timestamp3_reg bf; +}; + +/*[register] PTP_TRIGGER1_TIMESTAMP4_REG*/ +#define PTP_TRIGGER1_TIMESTAMP4_REG +#define PTP_TRIGGER1_TIMESTAMP4_REG_ADDRESS 0x840d +#define PTP_TRIGGER1_TIMESTAMP4_REG_NUM 1 +#define PTP_TRIGGER1_TIMESTAMP4_REG_INC 0x1 +#define PTP_TRIGGER1_TIMESTAMP4_REG_TYPE REG_TYPE_RW +#define PTP_TRIGGER1_TIMESTAMP4_REG_DEFAULT 0x0 + /*[field] TS_NSEC*/ + #define PTP_TRIGGER1_TIMESTAMP4_REG_TS_NSEC + #define PTP_TRIGGER1_TIMESTAMP4_REG_TS_NSEC_OFFSET 0 + #define PTP_TRIGGER1_TIMESTAMP4_REG_TS_NSEC_LEN 16 + #define PTP_TRIGGER1_TIMESTAMP4_REG_TS_NSEC_DEFAULT 0x0 + +struct ptp_trigger1_timestamp4_reg { + a_uint16_t ts_nsec:16; +}; + +union ptp_trigger1_timestamp4_reg_u { + a_uint32_t val; + struct ptp_trigger1_timestamp4_reg bf; +}; + +/*[register] PTP_EVENT0_CONFIG_REG*/ +#define PTP_EVENT0_CONFIG_REG +#define PTP_EVENT0_CONFIG_REG_ADDRESS 0x840e +#define PTP_EVENT0_CONFIG_REG_NUM 1 +#define PTP_EVENT0_CONFIG_REG_INC 0x1 +#define PTP_EVENT0_CONFIG_REG_TYPE REG_TYPE_RW +#define PTP_EVENT0_CONFIG_REG_DEFAULT 0x0 + /*[field] CLEAR_STAT*/ + #define PTP_EVENT0_CONFIG_REG_CLEAR_STAT + #define PTP_EVENT0_CONFIG_REG_CLEAR_STAT_OFFSET 0 + #define PTP_EVENT0_CONFIG_REG_CLEAR_STAT_LEN 1 + #define PTP_EVENT0_CONFIG_REG_CLEAR_STAT_DEFAULT 0x0 + /*[field] NOTIFY*/ + #define PTP_EVENT0_CONFIG_REG_NOTIFY + #define PTP_EVENT0_CONFIG_REG_NOTIFY_OFFSET 1 + #define PTP_EVENT0_CONFIG_REG_NOTIFY_LEN 1 + #define PTP_EVENT0_CONFIG_REG_NOTIFY_DEFAULT 0x0 + /*[field] SINGLE_CAP*/ + #define PTP_EVENT0_CONFIG_REG_SINGLE_CAP + #define PTP_EVENT0_CONFIG_REG_SINGLE_CAP_OFFSET 2 + #define PTP_EVENT0_CONFIG_REG_SINGLE_CAP_LEN 1 + #define PTP_EVENT0_CONFIG_REG_SINGLE_CAP_DEFAULT 0x0 + /*[field] FALL_EN*/ + #define PTP_EVENT0_CONFIG_REG_FALL_EN + #define PTP_EVENT0_CONFIG_REG_FALL_EN_OFFSET 3 + #define PTP_EVENT0_CONFIG_REG_FALL_EN_LEN 1 + #define PTP_EVENT0_CONFIG_REG_FALL_EN_DEFAULT 0x0 + /*[field] RISE_EN*/ + #define PTP_EVENT0_CONFIG_REG_RISE_EN + #define PTP_EVENT0_CONFIG_REG_RISE_EN_OFFSET 4 + #define PTP_EVENT0_CONFIG_REG_RISE_EN_LEN 1 + #define PTP_EVENT0_CONFIG_REG_RISE_EN_DEFAULT 0x0 + +struct ptp_event0_config_reg { + a_uint16_t clear_stat:1; + a_uint16_t notify:1; + a_uint16_t single_cap:1; + a_uint16_t fall_en:1; + a_uint16_t rise_en:1; +}; + +union ptp_event0_config_reg_u { + a_uint32_t val; + struct ptp_event0_config_reg bf; +}; + +/*[register] PTP_EVENT0_STATUS_REG*/ +#define PTP_EVENT0_STATUS_REG +#define PTP_EVENT0_STATUS_REG_ADDRESS 0x840f +#define PTP_EVENT0_STATUS_REG_NUM 1 +#define PTP_EVENT0_STATUS_REG_INC 0x1 +#define PTP_EVENT0_STATUS_REG_TYPE REG_TYPE_RW +#define PTP_EVENT0_STATUS_REG_DEFAULT 0x0 + /*[field] DETECTED*/ + #define PTP_EVENT0_STATUS_REG_DETECTED + #define PTP_EVENT0_STATUS_REG_DETECTED_OFFSET 0 + #define PTP_EVENT0_STATUS_REG_DETECTED_LEN 1 + #define PTP_EVENT0_STATUS_REG_DETECTED_DEFAULT 0x0 + /*[field] DIR_DETECTED*/ + #define PTP_EVENT0_STATUS_REG_DIR_DETECTED + #define PTP_EVENT0_STATUS_REG_DIR_DETECTED_OFFSET 1 + #define PTP_EVENT0_STATUS_REG_DIR_DETECTED_LEN 1 + #define PTP_EVENT0_STATUS_REG_DIR_DETECTED_DEFAULT 0x0 + /*[field] MUL_EVENT*/ + #define PTP_EVENT0_STATUS_REG_MUL_EVENT + #define PTP_EVENT0_STATUS_REG_MUL_EVENT_OFFSET 2 + #define PTP_EVENT0_STATUS_REG_MUL_EVENT_LEN 1 + #define PTP_EVENT0_STATUS_REG_MUL_EVENT_DEFAULT 0x0 + /*[field] MISSED_COUNT*/ + #define PTP_EVENT0_STATUS_REG_MISSED_COUNT + #define PTP_EVENT0_STATUS_REG_MISSED_COUNT_OFFSET 3 + #define PTP_EVENT0_STATUS_REG_MISSED_COUNT_LEN 4 + #define PTP_EVENT0_STATUS_REG_MISSED_COUNT_DEFAULT 0x0 + +struct ptp_event0_status_reg { + a_uint16_t detected:1; + a_uint16_t dir_detected:1; + a_uint16_t mul_event:1; + a_uint16_t missed_count:4; +}; + +union ptp_event0_status_reg_u { + a_uint32_t val; + struct ptp_event0_status_reg bf; +}; + +/*[register] PTP_EVENT1_CONFIG_REG*/ +#define PTP_EVENT1_CONFIG_REG +#define PTP_EVENT1_CONFIG_REG_ADDRESS 0x8410 +#define PTP_EVENT1_CONFIG_REG_NUM 1 +#define PTP_EVENT1_CONFIG_REG_INC 0x1 +#define PTP_EVENT1_CONFIG_REG_TYPE REG_TYPE_RW +#define PTP_EVENT1_CONFIG_REG_DEFAULT 0x0 + /*[field] CLEAR_STAT*/ + #define PTP_EVENT1_CONFIG_REG_CLEAR_STAT + #define PTP_EVENT1_CONFIG_REG_CLEAR_STAT_OFFSET 0 + #define PTP_EVENT1_CONFIG_REG_CLEAR_STAT_LEN 1 + #define PTP_EVENT1_CONFIG_REG_CLEAR_STAT_DEFAULT 0x0 + /*[field] NOTIFY*/ + #define PTP_EVENT1_CONFIG_REG_NOTIFY + #define PTP_EVENT1_CONFIG_REG_NOTIFY_OFFSET 1 + #define PTP_EVENT1_CONFIG_REG_NOTIFY_LEN 1 + #define PTP_EVENT1_CONFIG_REG_NOTIFY_DEFAULT 0x0 + /*[field] SINGLE_CAP*/ + #define PTP_EVENT1_CONFIG_REG_SINGLE_CAP + #define PTP_EVENT1_CONFIG_REG_SINGLE_CAP_OFFSET 2 + #define PTP_EVENT1_CONFIG_REG_SINGLE_CAP_LEN 1 + #define PTP_EVENT1_CONFIG_REG_SINGLE_CAP_DEFAULT 0x0 + /*[field] FALL_EN*/ + #define PTP_EVENT1_CONFIG_REG_FALL_EN + #define PTP_EVENT1_CONFIG_REG_FALL_EN_OFFSET 3 + #define PTP_EVENT1_CONFIG_REG_FALL_EN_LEN 1 + #define PTP_EVENT1_CONFIG_REG_FALL_EN_DEFAULT 0x0 + /*[field] RISE_EN*/ + #define PTP_EVENT1_CONFIG_REG_RISE_EN + #define PTP_EVENT1_CONFIG_REG_RISE_EN_OFFSET 4 + #define PTP_EVENT1_CONFIG_REG_RISE_EN_LEN 1 + #define PTP_EVENT1_CONFIG_REG_RISE_EN_DEFAULT 0x0 + +struct ptp_event1_config_reg { + a_uint16_t clear_stat:1; + a_uint16_t notify:1; + a_uint16_t single_cap:1; + a_uint16_t fall_en:1; + a_uint16_t rise_en:1; +}; + +union ptp_event1_config_reg_u { + a_uint32_t val; + struct ptp_event1_config_reg bf; +}; + +/*[register] PTP_EVENT1_STATUS_REG*/ +#define PTP_EVENT1_STATUS_REG +#define PTP_EVENT1_STATUS_REG_ADDRESS 0x8411 +#define PTP_EVENT1_STATUS_REG_NUM 1 +#define PTP_EVENT1_STATUS_REG_INC 0x1 +#define PTP_EVENT1_STATUS_REG_TYPE REG_TYPE_RW +#define PTP_EVENT1_STATUS_REG_DEFAULT 0x0 + /*[field] DETECTED*/ + #define PTP_EVENT1_STATUS_REG_DETECTED + #define PTP_EVENT1_STATUS_REG_DETECTED_OFFSET 0 + #define PTP_EVENT1_STATUS_REG_DETECTED_LEN 1 + #define PTP_EVENT1_STATUS_REG_DETECTED_DEFAULT 0x0 + /*[field] DIR_DETECTED*/ + #define PTP_EVENT1_STATUS_REG_DIR_DETECTED + #define PTP_EVENT1_STATUS_REG_DIR_DETECTED_OFFSET 1 + #define PTP_EVENT1_STATUS_REG_DIR_DETECTED_LEN 1 + #define PTP_EVENT1_STATUS_REG_DIR_DETECTED_DEFAULT 0x0 + /*[field] MUL_EVENT*/ + #define PTP_EVENT1_STATUS_REG_MUL_EVENT + #define PTP_EVENT1_STATUS_REG_MUL_EVENT_OFFSET 2 + #define PTP_EVENT1_STATUS_REG_MUL_EVENT_LEN 1 + #define PTP_EVENT1_STATUS_REG_MUL_EVENT_DEFAULT 0x0 + /*[field] MISSED_COUNT*/ + #define PTP_EVENT1_STATUS_REG_MISSED_COUNT + #define PTP_EVENT1_STATUS_REG_MISSED_COUNT_OFFSET 3 + #define PTP_EVENT1_STATUS_REG_MISSED_COUNT_LEN 4 + #define PTP_EVENT1_STATUS_REG_MISSED_COUNT_DEFAULT 0x0 + +struct ptp_event1_status_reg { + a_uint16_t detected:1; + a_uint16_t dir_detected:1; + a_uint16_t mul_event:1; + a_uint16_t missed_count:4; +}; + +union ptp_event1_status_reg_u { + a_uint32_t val; + struct ptp_event1_status_reg bf; +}; + +/*[register] PTP_EVENT0_TIMESTAMP0_REG*/ +#define PTP_EVENT0_TIMESTAMP0_REG +#define PTP_EVENT0_TIMESTAMP0_REG_ADDRESS 0x8412 +#define PTP_EVENT0_TIMESTAMP0_REG_NUM 1 +#define PTP_EVENT0_TIMESTAMP0_REG_INC 0x1 +#define PTP_EVENT0_TIMESTAMP0_REG_TYPE REG_TYPE_RW +#define PTP_EVENT0_TIMESTAMP0_REG_DEFAULT 0x0 + /*[field] TS_NSEC*/ + #define PTP_EVENT0_TIMESTAMP0_REG_TS_NSEC + #define PTP_EVENT0_TIMESTAMP0_REG_TS_NSEC_OFFSET 0 + #define PTP_EVENT0_TIMESTAMP0_REG_TS_NSEC_LEN 16 + #define PTP_EVENT0_TIMESTAMP0_REG_TS_NSEC_DEFAULT 0x0 + +struct ptp_event0_timestamp0_reg { + a_uint16_t ts_nsec:16; +}; + +union ptp_event0_timestamp0_reg_u { + a_uint32_t val; + struct ptp_event0_timestamp0_reg bf; +}; + +/*[register] PTP_EVENT0_TIMESTAMP1_REG*/ +#define PTP_EVENT0_TIMESTAMP1_REG +#define PTP_EVENT0_TIMESTAMP1_REG_ADDRESS 0x8413 +#define PTP_EVENT0_TIMESTAMP1_REG_NUM 1 +#define PTP_EVENT0_TIMESTAMP1_REG_INC 0x1 +#define PTP_EVENT0_TIMESTAMP1_REG_TYPE REG_TYPE_RW +#define PTP_EVENT0_TIMESTAMP1_REG_DEFAULT 0x0 + /*[field] TS_NSEC*/ + #define PTP_EVENT0_TIMESTAMP1_REG_TS_NSEC + #define PTP_EVENT0_TIMESTAMP1_REG_TS_NSEC_OFFSET 0 + #define PTP_EVENT0_TIMESTAMP1_REG_TS_NSEC_LEN 16 + #define PTP_EVENT0_TIMESTAMP1_REG_TS_NSEC_DEFAULT 0x0 + +struct ptp_event0_timestamp1_reg { + a_uint16_t ts_nsec:16; +}; + +union ptp_event0_timestamp1_reg_u { + a_uint32_t val; + struct ptp_event0_timestamp1_reg bf; +}; + +/*[register] PTP_EVENT0_TIMESTAMP2_REG*/ +#define PTP_EVENT0_TIMESTAMP2_REG +#define PTP_EVENT0_TIMESTAMP2_REG_ADDRESS 0x8414 +#define PTP_EVENT0_TIMESTAMP2_REG_NUM 1 +#define PTP_EVENT0_TIMESTAMP2_REG_INC 0x1 +#define PTP_EVENT0_TIMESTAMP2_REG_TYPE REG_TYPE_RW +#define PTP_EVENT0_TIMESTAMP2_REG_DEFAULT 0x0 + /*[field] TS_NSEC*/ + #define PTP_EVENT0_TIMESTAMP2_REG_TS_NSEC + #define PTP_EVENT0_TIMESTAMP2_REG_TS_NSEC_OFFSET 0 + #define PTP_EVENT0_TIMESTAMP2_REG_TS_NSEC_LEN 16 + #define PTP_EVENT0_TIMESTAMP2_REG_TS_NSEC_DEFAULT 0x0 + +struct ptp_event0_timestamp2_reg { + a_uint16_t ts_nsec:16; +}; + +union ptp_event0_timestamp2_reg_u { + a_uint32_t val; + struct ptp_event0_timestamp2_reg bf; +}; + +/*[register] PTP_EVENT0_TIMESTAMP3_REG*/ +#define PTP_EVENT0_TIMESTAMP3_REG +#define PTP_EVENT0_TIMESTAMP3_REG_ADDRESS 0x8415 +#define PTP_EVENT0_TIMESTAMP3_REG_NUM 1 +#define PTP_EVENT0_TIMESTAMP3_REG_INC 0x1 +#define PTP_EVENT0_TIMESTAMP3_REG_TYPE REG_TYPE_RW +#define PTP_EVENT0_TIMESTAMP3_REG_DEFAULT 0x0 + /*[field] TS_NSEC*/ + #define PTP_EVENT0_TIMESTAMP3_REG_TS_NSEC + #define PTP_EVENT0_TIMESTAMP3_REG_TS_NSEC_OFFSET 0 + #define PTP_EVENT0_TIMESTAMP3_REG_TS_NSEC_LEN 16 + #define PTP_EVENT0_TIMESTAMP3_REG_TS_NSEC_DEFAULT 0x0 + +struct ptp_event0_timestamp3_reg { + a_uint16_t ts_nsec:16; +}; + +union ptp_event0_timestamp3_reg_u { + a_uint32_t val; + struct ptp_event0_timestamp3_reg bf; +}; + +/*[register] PTP_EVENT0_TIMESTAMP4_REG*/ +#define PTP_EVENT0_TIMESTAMP4_REG +#define PTP_EVENT0_TIMESTAMP4_REG_ADDRESS 0x8416 +#define PTP_EVENT0_TIMESTAMP4_REG_NUM 1 +#define PTP_EVENT0_TIMESTAMP4_REG_INC 0x1 +#define PTP_EVENT0_TIMESTAMP4_REG_TYPE REG_TYPE_RW +#define PTP_EVENT0_TIMESTAMP4_REG_DEFAULT 0x0 + /*[field] TS_NSEC*/ + #define PTP_EVENT0_TIMESTAMP4_REG_TS_NSEC + #define PTP_EVENT0_TIMESTAMP4_REG_TS_NSEC_OFFSET 0 + #define PTP_EVENT0_TIMESTAMP4_REG_TS_NSEC_LEN 16 + #define PTP_EVENT0_TIMESTAMP4_REG_TS_NSEC_DEFAULT 0x0 + +struct ptp_event0_timestamp4_reg { + a_uint16_t ts_nsec:16; +}; + +union ptp_event0_timestamp4_reg_u { + a_uint32_t val; + struct ptp_event0_timestamp4_reg bf; +}; + +/*[register] PTP_EVENT1_TIMESTAMP0_REG*/ +#define PTP_EVENT1_TIMESTAMP0_REG +#define PTP_EVENT1_TIMESTAMP0_REG_ADDRESS 0x8417 +#define PTP_EVENT1_TIMESTAMP0_REG_NUM 1 +#define PTP_EVENT1_TIMESTAMP0_REG_INC 0x1 +#define PTP_EVENT1_TIMESTAMP0_REG_TYPE REG_TYPE_RW +#define PTP_EVENT1_TIMESTAMP0_REG_DEFAULT 0x0 + /*[field] TS_NSEC*/ + #define PTP_EVENT1_TIMESTAMP0_REG_TS_NSEC + #define PTP_EVENT1_TIMESTAMP0_REG_TS_NSEC_OFFSET 0 + #define PTP_EVENT1_TIMESTAMP0_REG_TS_NSEC_LEN 16 + #define PTP_EVENT1_TIMESTAMP0_REG_TS_NSEC_DEFAULT 0x0 + +struct ptp_event1_timestamp0_reg { + a_uint16_t ts_nsec:16; +}; + +union ptp_event1_timestamp0_reg_u { + a_uint32_t val; + struct ptp_event1_timestamp0_reg bf; +}; + +/*[register] PTP_EVENT1_TIMESTAMP1_REG*/ +#define PTP_EVENT1_TIMESTAMP1_REG +#define PTP_EVENT1_TIMESTAMP1_REG_ADDRESS 0x8418 +#define PTP_EVENT1_TIMESTAMP1_REG_NUM 1 +#define PTP_EVENT1_TIMESTAMP1_REG_INC 0x1 +#define PTP_EVENT1_TIMESTAMP1_REG_TYPE REG_TYPE_RW +#define PTP_EVENT1_TIMESTAMP1_REG_DEFAULT 0x0 + /*[field] TS_NSEC*/ + #define PTP_EVENT1_TIMESTAMP1_REG_TS_NSEC + #define PTP_EVENT1_TIMESTAMP1_REG_TS_NSEC_OFFSET 0 + #define PTP_EVENT1_TIMESTAMP1_REG_TS_NSEC_LEN 16 + #define PTP_EVENT1_TIMESTAMP1_REG_TS_NSEC_DEFAULT 0x0 + +struct ptp_event1_timestamp1_reg { + a_uint16_t ts_nsec:16; +}; + +union ptp_event1_timestamp1_reg_u { + a_uint32_t val; + struct ptp_event1_timestamp1_reg bf; +}; + +/*[register] PTP_EVENT1_TIMESTAMP2_REG*/ +#define PTP_EVENT1_TIMESTAMP2_REG +#define PTP_EVENT1_TIMESTAMP2_REG_ADDRESS 0x8419 +#define PTP_EVENT1_TIMESTAMP2_REG_NUM 1 +#define PTP_EVENT1_TIMESTAMP2_REG_INC 0x1 +#define PTP_EVENT1_TIMESTAMP2_REG_TYPE REG_TYPE_RW +#define PTP_EVENT1_TIMESTAMP2_REG_DEFAULT 0x0 + /*[field] TS_NSEC*/ + #define PTP_EVENT1_TIMESTAMP2_REG_TS_NSEC + #define PTP_EVENT1_TIMESTAMP2_REG_TS_NSEC_OFFSET 0 + #define PTP_EVENT1_TIMESTAMP2_REG_TS_NSEC_LEN 16 + #define PTP_EVENT1_TIMESTAMP2_REG_TS_NSEC_DEFAULT 0x0 + +struct ptp_event1_timestamp2_reg { + a_uint16_t ts_nsec:16; +}; + +union ptp_event1_timestamp2_reg_u { + a_uint32_t val; + struct ptp_event1_timestamp2_reg bf; +}; + +/*[register] PTP_EVENT1_TIMESTAMP3_REG*/ +#define PTP_EVENT1_TIMESTAMP3_REG +#define PTP_EVENT1_TIMESTAMP3_REG_ADDRESS 0x841a +#define PTP_EVENT1_TIMESTAMP3_REG_NUM 1 +#define PTP_EVENT1_TIMESTAMP3_REG_INC 0x4 +#define PTP_EVENT1_TIMESTAMP3_REG_TYPE REG_TYPE_RW +#define PTP_EVENT1_TIMESTAMP3_REG_DEFAULT 0x0 + /*[field] TS_NSEC*/ + #define PTP_EVENT1_TIMESTAMP3_REG_TS_NSEC + #define PTP_EVENT1_TIMESTAMP3_REG_TS_NSEC_OFFSET 0 + #define PTP_EVENT1_TIMESTAMP3_REG_TS_NSEC_LEN 16 + #define PTP_EVENT1_TIMESTAMP3_REG_TS_NSEC_DEFAULT 0x0 + +struct ptp_event1_timestamp3_reg { + a_uint16_t ts_nsec:16; +}; + +union ptp_event1_timestamp3_reg_u { + a_uint32_t val; + struct ptp_event1_timestamp3_reg bf; +}; + +/*[register] PTP_EVENT1_TIMESTAMP4_REG*/ +#define PTP_EVENT1_TIMESTAMP4_REG +#define PTP_EVENT1_TIMESTAMP4_REG_ADDRESS 0x841b +#define PTP_EVENT1_TIMESTAMP4_REG_NUM 1 +#define PTP_EVENT1_TIMESTAMP4_REG_INC 0x1 +#define PTP_EVENT1_TIMESTAMP4_REG_TYPE REG_TYPE_RW +#define PTP_EVENT1_TIMESTAMP4_REG_DEFAULT 0x0 + /*[field] TS_NSEC*/ + #define PTP_EVENT1_TIMESTAMP4_REG_TS_NSEC + #define PTP_EVENT1_TIMESTAMP4_REG_TS_NSEC_OFFSET 0 + #define PTP_EVENT1_TIMESTAMP4_REG_TS_NSEC_LEN 16 + #define PTP_EVENT1_TIMESTAMP4_REG_TS_NSEC_DEFAULT 0x0 + +struct ptp_event1_timestamp4_reg { + a_uint16_t ts_nsec:16; +}; + +union ptp_event1_timestamp4_reg_u { + a_uint32_t val; + struct ptp_event1_timestamp4_reg bf; +}; + +/*[register] PTP_RX_SEQID1_REG*/ +#define PTP_RX_SEQID1_REG +#define PTP_RX_SEQID1_REG_ADDRESS 0x8500 +#define PTP_RX_SEQID1_REG_NUM 1 +#define PTP_RX_SEQID1_REG_INC 0x1 +#define PTP_RX_SEQID1_REG_TYPE REG_TYPE_RW +#define PTP_RX_SEQID1_REG_DEFAULT 0x0 + /*[field] RX_SEQID*/ + #define PTP_RX_SEQID1_REG_RX_SEQID + #define PTP_RX_SEQID1_REG_RX_SEQID_OFFSET 0 + #define PTP_RX_SEQID1_REG_RX_SEQID_LEN 16 + #define PTP_RX_SEQID1_REG_RX_SEQID_DEFAULT 0x0 + +struct ptp_rx_seqid1_reg { + a_uint16_t rx_seqid:16; +}; + +union ptp_rx_seqid1_reg_u { + a_uint32_t val; + struct ptp_rx_seqid1_reg bf; +}; + +/*[register] PTP_RX_PORTID1_0_REG*/ +#define PTP_RX_PORTID1_0_REG +#define PTP_RX_PORTID1_0_REG_ADDRESS 0x8501 +#define PTP_RX_PORTID1_0_REG_NUM 1 +#define PTP_RX_PORTID1_0_REG_INC 0x1 +#define PTP_RX_PORTID1_0_REG_TYPE REG_TYPE_RW +#define PTP_RX_PORTID1_0_REG_DEFAULT 0x0 + /*[field] RX_PORTID*/ + #define PTP_RX_PORTID1_0_REG_RX_PORTID + #define PTP_RX_PORTID1_0_REG_RX_PORTID_OFFSET 0 + #define PTP_RX_PORTID1_0_REG_RX_PORTID_LEN 16 + #define PTP_RX_PORTID1_0_REG_RX_PORTID_DEFAULT 0x0 + +struct ptp_rx_portid1_0_reg { + a_uint16_t rx_portid:16; +}; + +union ptp_rx_portid1_0_reg_u { + a_uint32_t val; + struct ptp_rx_portid1_0_reg bf; +}; + +/*[register] PTP_RX_PORTID1_1_REG*/ +#define PTP_RX_PORTID1_1_REG +#define PTP_RX_PORTID1_1_REG_ADDRESS 0x8502 +#define PTP_RX_PORTID1_1_REG_NUM 1 +#define PTP_RX_PORTID1_1_REG_INC 0x1 +#define PTP_RX_PORTID1_1_REG_TYPE REG_TYPE_RW +#define PTP_RX_PORTID1_1_REG_DEFAULT 0x0 + /*[field] RX_PORTID*/ + #define PTP_RX_PORTID1_1_REG_RX_PORTID + #define PTP_RX_PORTID1_1_REG_RX_PORTID_OFFSET 0 + #define PTP_RX_PORTID1_1_REG_RX_PORTID_LEN 16 + #define PTP_RX_PORTID1_1_REG_RX_PORTID_DEFAULT 0x0 + +struct ptp_rx_portid1_1_reg { + a_uint16_t rx_portid:16; +}; + +union ptp_rx_portid1_1_reg_u { + a_uint32_t val; + struct ptp_rx_portid1_1_reg bf; +}; + +/*[register] PTP_RX_PORTID1_2_REG*/ +#define PTP_RX_PORTID1_2_REG +#define PTP_RX_PORTID1_2_REG_ADDRESS 0x8503 +#define PTP_RX_PORTID1_2_REG_NUM 1 +#define PTP_RX_PORTID1_2_REG_INC 0x1 +#define PTP_RX_PORTID1_2_REG_TYPE REG_TYPE_RW +#define PTP_RX_PORTID1_2_REG_DEFAULT 0x0 + /*[field] RX_PORTID*/ + #define PTP_RX_PORTID1_2_REG_RX_PORTID + #define PTP_RX_PORTID1_2_REG_RX_PORTID_OFFSET 0 + #define PTP_RX_PORTID1_2_REG_RX_PORTID_LEN 16 + #define PTP_RX_PORTID1_2_REG_RX_PORTID_DEFAULT 0x0 + +struct ptp_rx_portid1_2_reg { + a_uint16_t rx_portid:16; +}; + +union ptp_rx_portid1_2_reg_u { + a_uint32_t val; + struct ptp_rx_portid1_2_reg bf; +}; + +/*[register] PTP_RX_PORTID1_3_REG*/ +#define PTP_RX_PORTID1_3_REG +#define PTP_RX_PORTID1_3_REG_ADDRESS 0x8504 +#define PTP_RX_PORTID1_3_REG_NUM 1 +#define PTP_RX_PORTID1_3_REG_INC 0x1 +#define PTP_RX_PORTID1_3_REG_TYPE REG_TYPE_RW +#define PTP_RX_PORTID1_3_REG_DEFAULT 0x0 + /*[field] RX_PORTID*/ + #define PTP_RX_PORTID1_3_REG_RX_PORTID + #define PTP_RX_PORTID1_3_REG_RX_PORTID_OFFSET 0 + #define PTP_RX_PORTID1_3_REG_RX_PORTID_LEN 16 + #define PTP_RX_PORTID1_3_REG_RX_PORTID_DEFAULT 0x0 + +struct ptp_rx_portid1_3_reg { + a_uint16_t rx_portid:16; +}; + +union ptp_rx_portid1_3_reg_u { + a_uint32_t val; + struct ptp_rx_portid1_3_reg bf; +}; + +/*[register] PTP_RX_PORTID1_4_REG*/ +#define PTP_RX_PORTID1_4_REG +#define PTP_RX_PORTID1_4_REG_ADDRESS 0x8505 +#define PTP_RX_PORTID1_4_REG_NUM 1 +#define PTP_RX_PORTID1_4_REG_INC 0x1 +#define PTP_RX_PORTID1_4_REG_TYPE REG_TYPE_RW +#define PTP_RX_PORTID1_4_REG_DEFAULT 0x0 + /*[field] RX_PORTID*/ + #define PTP_RX_PORTID1_4_REG_RX_PORTID + #define PTP_RX_PORTID1_4_REG_RX_PORTID_OFFSET 0 + #define PTP_RX_PORTID1_4_REG_RX_PORTID_LEN 16 + #define PTP_RX_PORTID1_4_REG_RX_PORTID_DEFAULT 0x0 + +struct ptp_rx_portid1_4_reg { + a_uint16_t rx_portid:16; +}; + +union ptp_rx_portid1_4_reg_u { + a_uint32_t val; + struct ptp_rx_portid1_4_reg bf; +}; + +/*[register] PTP_RX_TS1_0_REG*/ +#define PTP_RX_TS1_0_REG +#define PTP_RX_TS1_0_REG_ADDRESS 0x8506 +#define PTP_RX_TS1_0_REG_NUM 1 +#define PTP_RX_TS1_0_REG_INC 0x1 +#define PTP_RX_TS1_0_REG_TYPE REG_TYPE_RW +#define PTP_RX_TS1_0_REG_DEFAULT 0x0 + /*[field] RX_TS_SEC*/ + #define PTP_RX_TS1_0_REG_RX_TS_SEC + #define PTP_RX_TS1_0_REG_RX_TS_SEC_OFFSET 0 + #define PTP_RX_TS1_0_REG_RX_TS_SEC_LEN 16 + #define PTP_RX_TS1_0_REG_RX_TS_SEC_DEFAULT 0x0 + +struct ptp_rx_ts1_0_reg { + a_uint16_t rx_ts_sec:16; +}; + +union ptp_rx_ts1_0_reg_u { + a_uint32_t val; + struct ptp_rx_ts1_0_reg bf; +}; + +/*[register] PTP_RX_TS1_1_REG*/ +#define PTP_RX_TS1_1_REG +#define PTP_RX_TS1_1_REG_ADDRESS 0x8507 +#define PTP_RX_TS1_1_REG_NUM 1 +#define PTP_RX_TS1_1_REG_INC 0x1 +#define PTP_RX_TS1_1_REG_TYPE REG_TYPE_RW +#define PTP_RX_TS1_1_REG_DEFAULT 0x0 + /*[field] RX_TS_SEC*/ + #define PTP_RX_TS1_1_REG_RX_TS_SEC + #define PTP_RX_TS1_1_REG_RX_TS_SEC_OFFSET 0 + #define PTP_RX_TS1_1_REG_RX_TS_SEC_LEN 16 + #define PTP_RX_TS1_1_REG_RX_TS_SEC_DEFAULT 0x0 + +struct ptp_rx_ts1_1_reg { + a_uint16_t rx_ts_sec:16; +}; + +union ptp_rx_ts1_1_reg_u { + a_uint32_t val; + struct ptp_rx_ts1_1_reg bf; +}; + +/*[register] PTP_RX_TS1_2_REG*/ +#define PTP_RX_TS1_2_REG +#define PTP_RX_TS1_2_REG_ADDRESS 0x8508 +#define PTP_RX_TS1_2_REG_NUM 1 +#define PTP_RX_TS1_2_REG_INC 0x1 +#define PTP_RX_TS1_2_REG_TYPE REG_TYPE_RW +#define PTP_RX_TS1_2_REG_DEFAULT 0x0 + /*[field] RX_TS_SEC*/ + #define PTP_RX_TS1_2_REG_RX_TS_SEC + #define PTP_RX_TS1_2_REG_RX_TS_SEC_OFFSET 0 + #define PTP_RX_TS1_2_REG_RX_TS_SEC_LEN 16 + #define PTP_RX_TS1_2_REG_RX_TS_SEC_DEFAULT 0x0 + +struct ptp_rx_ts1_2_reg { + a_uint16_t rx_ts_sec:16; +}; + +union ptp_rx_ts1_2_reg_u { + a_uint32_t val; + struct ptp_rx_ts1_2_reg bf; +}; + +/*[register] PTP_RX_TS1_3_REG*/ +#define PTP_RX_TS1_3_REG +#define PTP_RX_TS1_3_REG_ADDRESS 0x8509 +#define PTP_RX_TS1_3_REG_NUM 1 +#define PTP_RX_TS1_3_REG_INC 0x1 +#define PTP_RX_TS1_3_REG_TYPE REG_TYPE_RW +#define PTP_RX_TS1_3_REG_DEFAULT 0x0 + /*[field] RX_TS_NSEC*/ + #define PTP_RX_TS1_3_REG_RX_TS_NSEC + #define PTP_RX_TS1_3_REG_RX_TS_NSEC_OFFSET 0 + #define PTP_RX_TS1_3_REG_RX_TS_NSEC_LEN 16 + #define PTP_RX_TS1_3_REG_RX_TS_NSEC_DEFAULT 0x0 + +struct ptp_rx_ts1_3_reg { + a_uint16_t rx_ts_nsec:16; +}; + +union ptp_rx_ts1_3_reg_u { + a_uint32_t val; + struct ptp_rx_ts1_3_reg bf; +}; + +/*[register] PTP_RX_TS1_4_REG*/ +#define PTP_RX_TS1_4_REG +#define PTP_RX_TS1_4_REG_ADDRESS 0x850a +#define PTP_RX_TS1_4_REG_NUM 1 +#define PTP_RX_TS1_4_REG_INC 0x1 +#define PTP_RX_TS1_4_REG_TYPE REG_TYPE_RW +#define PTP_RX_TS1_4_REG_DEFAULT 0x0 + /*[field] RX_TS_NSEC*/ + #define PTP_RX_TS1_4_REG_RX_TS_NSEC + #define PTP_RX_TS1_4_REG_RX_TS_NSEC_OFFSET 0 + #define PTP_RX_TS1_4_REG_RX_TS_NSEC_LEN 16 + #define PTP_RX_TS1_4_REG_RX_TS_NSEC_DEFAULT 0x0 + +struct ptp_rx_ts1_4_reg { + a_uint16_t rx_ts_nsec:16; +}; + +union ptp_rx_ts1_4_reg_u { + a_uint32_t val; + struct ptp_rx_ts1_4_reg bf; +}; + +/*[register] PTP_RX_TS1_5_REG*/ +#define PTP_RX_TS1_5_REG +#define PTP_RX_TS1_5_REG_ADDRESS 0x850b +#define PTP_RX_TS1_5_REG_NUM 1 +#define PTP_RX_TS1_5_REG_INC 0x1 +#define PTP_RX_TS1_5_REG_TYPE REG_TYPE_RW +#define PTP_RX_TS1_5_REG_DEFAULT 0x0 + /*[field] RX_TS_NFSEC*/ + #define PTP_RX_TS1_5_REG_RX_TS_NFSEC + #define PTP_RX_TS1_5_REG_RX_TS_NFSEC_OFFSET 0 + #define PTP_RX_TS1_5_REG_RX_TS_NFSEC_LEN 12 + #define PTP_RX_TS1_5_REG_RX_TS_NFSEC_DEFAULT 0x0 + /*[field] RX_MSG_TYPE*/ + #define PTP_RX_TS1_5_REG_RX_MSG_TYPE + #define PTP_RX_TS1_5_REG_RX_MSG_TYPE_OFFSET 12 + #define PTP_RX_TS1_5_REG_RX_MSG_TYPE_LEN 4 + #define PTP_RX_TS1_5_REG_RX_MSG_TYPE_DEFAULT 0x0 + +struct ptp_rx_ts1_5_reg { + a_uint16_t rx_ts_nfsec:12; + a_uint16_t rx_msg_type:4; +}; + +union ptp_rx_ts1_5_reg_u { + a_uint32_t val; + struct ptp_rx_ts1_5_reg bf; +}; + +/*[register] PTP_RX_TS1_6_REG*/ +#define PTP_RX_TS1_6_REG +#define PTP_RX_TS1_6_REG_ADDRESS 0x850c +#define PTP_RX_TS1_6_REG_NUM 1 +#define PTP_RX_TS1_6_REG_INC 0x1 +#define PTP_RX_TS1_6_REG_TYPE REG_TYPE_RW +#define PTP_RX_TS1_6_REG_DEFAULT 0x0 + /*[field] RX_TS_NFSEC*/ + #define PTP_RX_TS1_6_REG_RX_TS_NFSEC + #define PTP_RX_TS1_6_REG_RX_TS_NFSEC_OFFSET 0 + #define PTP_RX_TS1_6_REG_RX_TS_NFSEC_LEN 8 + #define PTP_RX_TS1_6_REG_RX_TS_NFSEC_DEFAULT 0x0 + +struct ptp_rx_ts1_6_reg { + a_uint16_t rx_ts_nfsec:8; +}; + +union ptp_rx_ts1_6_reg_u { + a_uint32_t val; + struct ptp_rx_ts1_6_reg bf; +}; + +/*[register] PTP_RX_SEQID2_REG*/ +#define PTP_RX_SEQID2_REG +#define PTP_RX_SEQID2_REG_ADDRESS 0x851a +#define PTP_RX_SEQID2_REG_NUM 1 +#define PTP_RX_SEQID2_REG_INC 0x1 +#define PTP_RX_SEQID2_REG_TYPE REG_TYPE_RW +#define PTP_RX_SEQID2_REG_DEFAULT 0x0 + /*[field] RX_SEQID*/ + #define PTP_RX_SEQID2_REG_RX_SEQID + #define PTP_RX_SEQID2_REG_RX_SEQID_OFFSET 0 + #define PTP_RX_SEQID2_REG_RX_SEQID_LEN 16 + #define PTP_RX_SEQID2_REG_RX_SEQID_DEFAULT 0x0 + +struct ptp_rx_seqid2_reg { + a_uint16_t rx_seqid:16; +}; + +union ptp_rx_seqid2_reg_u { + a_uint32_t val; + struct ptp_rx_seqid2_reg bf; +}; + +/*[register] PTP_RX_PORTID2_0_REG*/ +#define PTP_RX_PORTID2_0_REG +#define PTP_RX_PORTID2_0_REG_ADDRESS 0x851b +#define PTP_RX_PORTID2_0_REG_NUM 1 +#define PTP_RX_PORTID2_0_REG_INC 0x1 +#define PTP_RX_PORTID2_0_REG_TYPE REG_TYPE_RW +#define PTP_RX_PORTID2_0_REG_DEFAULT 0x0 + /*[field] RX_PORTID*/ + #define PTP_RX_PORTID2_0_REG_RX_PORTID + #define PTP_RX_PORTID2_0_REG_RX_PORTID_OFFSET 0 + #define PTP_RX_PORTID2_0_REG_RX_PORTID_LEN 16 + #define PTP_RX_PORTID2_0_REG_RX_PORTID_DEFAULT 0x0 + +struct ptp_rx_portid2_0_reg { + a_uint16_t rx_portid:16; +}; + +union ptp_rx_portid2_0_reg_u { + a_uint32_t val; + struct ptp_rx_portid2_0_reg bf; +}; + +/*[register] PTP_RX_PORTID2_1_REG*/ +#define PTP_RX_PORTID2_1_REG +#define PTP_RX_PORTID2_1_REG_ADDRESS 0x851c +#define PTP_RX_PORTID2_1_REG_NUM 1 +#define PTP_RX_PORTID2_1_REG_INC 0x1 +#define PTP_RX_PORTID2_1_REG_TYPE REG_TYPE_RW +#define PTP_RX_PORTID2_1_REG_DEFAULT 0x0 + /*[field] RX_PORTID*/ + #define PTP_RX_PORTID2_1_REG_RX_PORTID + #define PTP_RX_PORTID2_1_REG_RX_PORTID_OFFSET 0 + #define PTP_RX_PORTID2_1_REG_RX_PORTID_LEN 16 + #define PTP_RX_PORTID2_1_REG_RX_PORTID_DEFAULT 0x0 + +struct ptp_rx_portid2_1_reg { + a_uint16_t rx_portid:16; +}; + +union ptp_rx_portid2_1_reg_u { + a_uint32_t val; + struct ptp_rx_portid2_1_reg bf; +}; + +/*[register] PTP_RX_PORTID2_2_REG*/ +#define PTP_RX_PORTID2_2_REG +#define PTP_RX_PORTID2_2_REG_ADDRESS 0x851d +#define PTP_RX_PORTID2_2_REG_NUM 1 +#define PTP_RX_PORTID2_2_REG_INC 0x1 +#define PTP_RX_PORTID2_2_REG_TYPE REG_TYPE_RW +#define PTP_RX_PORTID2_2_REG_DEFAULT 0x0 + /*[field] RX_PORTID*/ + #define PTP_RX_PORTID2_2_REG_RX_PORTID + #define PTP_RX_PORTID2_2_REG_RX_PORTID_OFFSET 0 + #define PTP_RX_PORTID2_2_REG_RX_PORTID_LEN 16 + #define PTP_RX_PORTID2_2_REG_RX_PORTID_DEFAULT 0x0 + +struct ptp_rx_portid2_2_reg { + a_uint16_t rx_portid:16; +}; + +union ptp_rx_portid2_2_reg_u { + a_uint32_t val; + struct ptp_rx_portid2_2_reg bf; +}; + +/*[register] PTP_RX_PORTID2_3_REG*/ +#define PTP_RX_PORTID2_3_REG +#define PTP_RX_PORTID2_3_REG_ADDRESS 0x851e +#define PTP_RX_PORTID2_3_REG_NUM 1 +#define PTP_RX_PORTID2_3_REG_INC 0x1 +#define PTP_RX_PORTID2_3_REG_TYPE REG_TYPE_RW +#define PTP_RX_PORTID2_3_REG_DEFAULT 0x0 + /*[field] RX_PORTID*/ + #define PTP_RX_PORTID2_3_REG_RX_PORTID + #define PTP_RX_PORTID2_3_REG_RX_PORTID_OFFSET 0 + #define PTP_RX_PORTID2_3_REG_RX_PORTID_LEN 16 + #define PTP_RX_PORTID2_3_REG_RX_PORTID_DEFAULT 0x0 + +struct ptp_rx_portid2_3_reg { + a_uint16_t rx_portid:16; +}; + +union ptp_rx_portid2_3_reg_u { + a_uint32_t val; + struct ptp_rx_portid2_3_reg bf; +}; + +/*[register] PTP_RX_PORTID2_4_REG*/ +#define PTP_RX_PORTID2_4_REG +#define PTP_RX_PORTID2_4_REG_ADDRESS 0x851f +#define PTP_RX_PORTID2_4_REG_NUM 1 +#define PTP_RX_PORTID2_4_REG_INC 0x1 +#define PTP_RX_PORTID2_4_REG_TYPE REG_TYPE_RW +#define PTP_RX_PORTID2_4_REG_DEFAULT 0x0 + /*[field] RX_PORTID*/ + #define PTP_RX_PORTID2_4_REG_RX_PORTID + #define PTP_RX_PORTID2_4_REG_RX_PORTID_OFFSET 0 + #define PTP_RX_PORTID2_4_REG_RX_PORTID_LEN 16 + #define PTP_RX_PORTID2_4_REG_RX_PORTID_DEFAULT 0x0 + +struct ptp_rx_portid2_4_reg { + a_uint16_t rx_portid:16; +}; + +union ptp_rx_portid2_4_reg_u { + a_uint32_t val; + struct ptp_rx_portid2_4_reg bf; +}; + +/*[register] PTP_RX_TS2_0_REG*/ +#define PTP_RX_TS2_0_REG +#define PTP_RX_TS2_0_REG_ADDRESS 0x8520 +#define PTP_RX_TS2_0_REG_NUM 1 +#define PTP_RX_TS2_0_REG_INC 0x1 +#define PTP_RX_TS2_0_REG_TYPE REG_TYPE_RW +#define PTP_RX_TS2_0_REG_DEFAULT 0x0 + /*[field] RX_TS_SEC*/ + #define PTP_RX_TS2_0_REG_RX_TS_SEC + #define PTP_RX_TS2_0_REG_RX_TS_SEC_OFFSET 0 + #define PTP_RX_TS2_0_REG_RX_TS_SEC_LEN 16 + #define PTP_RX_TS2_0_REG_RX_TS_SEC_DEFAULT 0x0 + +struct ptp_rx_ts2_0_reg { + a_uint16_t rx_ts_sec:16; +}; + +union ptp_rx_ts2_0_reg_u { + a_uint32_t val; + struct ptp_rx_ts2_0_reg bf; +}; + +/*[register] PTP_RX_TS2_1_REG*/ +#define PTP_RX_TS2_1_REG +#define PTP_RX_TS2_1_REG_ADDRESS 0x8521 +#define PTP_RX_TS2_1_REG_NUM 1 +#define PTP_RX_TS2_1_REG_INC 0x1 +#define PTP_RX_TS2_1_REG_TYPE REG_TYPE_RW +#define PTP_RX_TS2_1_REG_DEFAULT 0x0 + /*[field] RX_TS_SEC*/ + #define PTP_RX_TS2_1_REG_RX_TS_SEC + #define PTP_RX_TS2_1_REG_RX_TS_SEC_OFFSET 0 + #define PTP_RX_TS2_1_REG_RX_TS_SEC_LEN 16 + #define PTP_RX_TS2_1_REG_RX_TS_SEC_DEFAULT 0x0 + +struct ptp_rx_ts2_1_reg { + a_uint16_t rx_ts_sec:16; +}; + +union ptp_rx_ts2_1_reg_u { + a_uint32_t val; + struct ptp_rx_ts2_1_reg bf; +}; + +/*[register] PTP_RX_TS2_2_REG*/ +#define PTP_RX_TS2_2_REG +#define PTP_RX_TS2_2_REG_ADDRESS 0x8522 +#define PTP_RX_TS2_2_REG_NUM 1 +#define PTP_RX_TS2_2_REG_INC 0x1 +#define PTP_RX_TS2_2_REG_TYPE REG_TYPE_RW +#define PTP_RX_TS2_2_REG_DEFAULT 0x0 + /*[field] RX_TS_SEC*/ + #define PTP_RX_TS2_2_REG_RX_TS_SEC + #define PTP_RX_TS2_2_REG_RX_TS_SEC_OFFSET 0 + #define PTP_RX_TS2_2_REG_RX_TS_SEC_LEN 16 + #define PTP_RX_TS2_2_REG_RX_TS_SEC_DEFAULT 0x0 + +struct ptp_rx_ts2_2_reg { + a_uint16_t rx_ts_sec:16; +}; + +union ptp_rx_ts2_2_reg_u { + a_uint32_t val; + struct ptp_rx_ts2_2_reg bf; +}; + +/*[register] PTP_RX_TS2_3_REG*/ +#define PTP_RX_TS2_3_REG +#define PTP_RX_TS2_3_REG_ADDRESS 0x8523 +#define PTP_RX_TS2_3_REG_NUM 1 +#define PTP_RX_TS2_3_REG_INC 0x1 +#define PTP_RX_TS2_3_REG_TYPE REG_TYPE_RW +#define PTP_RX_TS2_3_REG_DEFAULT 0x0 + /*[field] RX_TS_NSEC*/ + #define PTP_RX_TS2_3_REG_RX_TS_NSEC + #define PTP_RX_TS2_3_REG_RX_TS_NSEC_OFFSET 0 + #define PTP_RX_TS2_3_REG_RX_TS_NSEC_LEN 16 + #define PTP_RX_TS2_3_REG_RX_TS_NSEC_DEFAULT 0x0 + +struct ptp_rx_ts2_3_reg { + a_uint16_t rx_ts_nsec:16; +}; + +union ptp_rx_ts2_3_reg_u { + a_uint32_t val; + struct ptp_rx_ts2_3_reg bf; +}; + +/*[register] PTP_RX_TS2_4_REG*/ +#define PTP_RX_TS2_4_REG +#define PTP_RX_TS2_4_REG_ADDRESS 0x8524 +#define PTP_RX_TS2_4_REG_NUM 1 +#define PTP_RX_TS2_4_REG_INC 0x1 +#define PTP_RX_TS2_4_REG_TYPE REG_TYPE_RW +#define PTP_RX_TS2_4_REG_DEFAULT 0x0 + /*[field] RX_TS_NSEC*/ + #define PTP_RX_TS2_4_REG_RX_TS_NSEC + #define PTP_RX_TS2_4_REG_RX_TS_NSEC_OFFSET 0 + #define PTP_RX_TS2_4_REG_RX_TS_NSEC_LEN 16 + #define PTP_RX_TS2_4_REG_RX_TS_NSEC_DEFAULT 0x0 + +struct ptp_rx_ts2_4_reg { + a_uint16_t rx_ts_nsec:16; +}; + +union ptp_rx_ts2_4_reg_u { + a_uint32_t val; + struct ptp_rx_ts2_4_reg bf; +}; + +/*[register] PTP_RX_TS2_5_REG*/ +#define PTP_RX_TS2_5_REG +#define PTP_RX_TS2_5_REG_ADDRESS 0x8525 +#define PTP_RX_TS2_5_REG_NUM 1 +#define PTP_RX_TS2_5_REG_INC 0x1 +#define PTP_RX_TS2_5_REG_TYPE REG_TYPE_RW +#define PTP_RX_TS2_5_REG_DEFAULT 0x0 + /*[field] RX_TS_NFSEC*/ + #define PTP_RX_TS2_5_REG_RX_TS_NFSEC + #define PTP_RX_TS2_5_REG_RX_TS_NFSEC_OFFSET 0 + #define PTP_RX_TS2_5_REG_RX_TS_NFSEC_LEN 12 + #define PTP_RX_TS2_5_REG_RX_TS_NFSEC_DEFAULT 0x0 + /*[field] RX_MSG_TYPE*/ + #define PTP_RX_TS2_5_REG_RX_MSG_TYPE + #define PTP_RX_TS2_5_REG_RX_MSG_TYPE_OFFSET 12 + #define PTP_RX_TS2_5_REG_RX_MSG_TYPE_LEN 4 + #define PTP_RX_TS2_5_REG_RX_MSG_TYPE_DEFAULT 0x0 + +struct ptp_rx_ts2_5_reg { + a_uint16_t rx_ts_nfsec:12; + a_uint16_t rx_msg_type:4; +}; + +union ptp_rx_ts2_5_reg_u { + a_uint32_t val; + struct ptp_rx_ts2_5_reg bf; +}; + +/*[register] PTP_RX_TS2_6_REG*/ +#define PTP_RX_TS2_6_REG +#define PTP_RX_TS2_6_REG_ADDRESS 0x8526 +#define PTP_RX_TS2_6_REG_NUM 1 +#define PTP_RX_TS2_6_REG_INC 0x1 +#define PTP_RX_TS2_6_REG_TYPE REG_TYPE_RW +#define PTP_RX_TS2_6_REG_DEFAULT 0x0 + /*[field] RX_TS_NFSEC*/ + #define PTP_RX_TS2_6_REG_RX_TS_NFSEC + #define PTP_RX_TS2_6_REG_RX_TS_NFSEC_OFFSET 0 + #define PTP_RX_TS2_6_REG_RX_TS_NFSEC_LEN 8 + #define PTP_RX_TS2_6_REG_RX_TS_NFSEC_DEFAULT 0x0 + +struct ptp_rx_ts2_6_reg { + a_uint16_t rx_ts_nfsec:8; +}; + +union ptp_rx_ts2_6_reg_u { + a_uint32_t val; + struct ptp_rx_ts2_6_reg bf; +}; + +/*[register] PTP_RX_SEQID3_REG*/ +#define PTP_RX_SEQID3_REG +#define PTP_RX_SEQID3_REG_ADDRESS 0x8534 +#define PTP_RX_SEQID3_REG_NUM 1 +#define PTP_RX_SEQID3_REG_INC 0x1 +#define PTP_RX_SEQID3_REG_TYPE REG_TYPE_RW +#define PTP_RX_SEQID3_REG_DEFAULT 0x0 + /*[field] RX_SEQID*/ + #define PTP_RX_SEQID3_REG_RX_SEQID + #define PTP_RX_SEQID3_REG_RX_SEQID_OFFSET 0 + #define PTP_RX_SEQID3_REG_RX_SEQID_LEN 16 + #define PTP_RX_SEQID3_REG_RX_SEQID_DEFAULT 0x0 + +struct ptp_rx_seqid3_reg { + a_uint16_t rx_seqid:16; +}; + +union ptp_rx_seqid3_reg_u { + a_uint32_t val; + struct ptp_rx_seqid3_reg bf; +}; + +/*[register] PTP_RX_PORTID3_0_REG*/ +#define PTP_RX_PORTID3_0_REG +#define PTP_RX_PORTID3_0_REG_ADDRESS 0x8535 +#define PTP_RX_PORTID3_0_REG_NUM 1 +#define PTP_RX_PORTID3_0_REG_INC 0x1 +#define PTP_RX_PORTID3_0_REG_TYPE REG_TYPE_RW +#define PTP_RX_PORTID3_0_REG_DEFAULT 0x0 + /*[field] RX_PORTID*/ + #define PTP_RX_PORTID3_0_REG_RX_PORTID + #define PTP_RX_PORTID3_0_REG_RX_PORTID_OFFSET 0 + #define PTP_RX_PORTID3_0_REG_RX_PORTID_LEN 16 + #define PTP_RX_PORTID3_0_REG_RX_PORTID_DEFAULT 0x0 + +struct ptp_rx_portid3_0_reg { + a_uint16_t rx_portid:16; +}; + +union ptp_rx_portid3_0_reg_u { + a_uint32_t val; + struct ptp_rx_portid3_0_reg bf; +}; + +/*[register] PTP_RX_PORTID3_1_REG*/ +#define PTP_RX_PORTID3_1_REG +#define PTP_RX_PORTID3_1_REG_ADDRESS 0x8536 +#define PTP_RX_PORTID3_1_REG_NUM 1 +#define PTP_RX_PORTID3_1_REG_INC 0x1 +#define PTP_RX_PORTID3_1_REG_TYPE REG_TYPE_RW +#define PTP_RX_PORTID3_1_REG_DEFAULT 0x0 + /*[field] RX_PORTID*/ + #define PTP_RX_PORTID3_1_REG_RX_PORTID + #define PTP_RX_PORTID3_1_REG_RX_PORTID_OFFSET 0 + #define PTP_RX_PORTID3_1_REG_RX_PORTID_LEN 16 + #define PTP_RX_PORTID3_1_REG_RX_PORTID_DEFAULT 0x0 + +struct ptp_rx_portid3_1_reg { + a_uint16_t rx_portid:16; +}; + +union ptp_rx_portid3_1_reg_u { + a_uint32_t val; + struct ptp_rx_portid3_1_reg bf; +}; + +/*[register] PTP_RX_PORTID3_2_REG*/ +#define PTP_RX_PORTID3_2_REG +#define PTP_RX_PORTID3_2_REG_ADDRESS 0x8537 +#define PTP_RX_PORTID3_2_REG_NUM 1 +#define PTP_RX_PORTID3_2_REG_INC 0x1 +#define PTP_RX_PORTID3_2_REG_TYPE REG_TYPE_RW +#define PTP_RX_PORTID3_2_REG_DEFAULT 0x0 + /*[field] RX_PORTID*/ + #define PTP_RX_PORTID3_2_REG_RX_PORTID + #define PTP_RX_PORTID3_2_REG_RX_PORTID_OFFSET 0 + #define PTP_RX_PORTID3_2_REG_RX_PORTID_LEN 16 + #define PTP_RX_PORTID3_2_REG_RX_PORTID_DEFAULT 0x0 + +struct ptp_rx_portid3_2_reg { + a_uint16_t rx_portid:16; +}; + +union ptp_rx_portid3_2_reg_u { + a_uint32_t val; + struct ptp_rx_portid3_2_reg bf; +}; + +/*[register] PTP_RX_PORTID3_3_REG*/ +#define PTP_RX_PORTID3_3_REG +#define PTP_RX_PORTID3_3_REG_ADDRESS 0x8538 +#define PTP_RX_PORTID3_3_REG_NUM 1 +#define PTP_RX_PORTID3_3_REG_INC 0x1 +#define PTP_RX_PORTID3_3_REG_TYPE REG_TYPE_RW +#define PTP_RX_PORTID3_3_REG_DEFAULT 0x0 + /*[field] RX_PORTID*/ + #define PTP_RX_PORTID3_3_REG_RX_PORTID + #define PTP_RX_PORTID3_3_REG_RX_PORTID_OFFSET 0 + #define PTP_RX_PORTID3_3_REG_RX_PORTID_LEN 16 + #define PTP_RX_PORTID3_3_REG_RX_PORTID_DEFAULT 0x0 + +struct ptp_rx_portid3_3_reg { + a_uint16_t rx_portid:16; +}; + +union ptp_rx_portid3_3_reg_u { + a_uint32_t val; + struct ptp_rx_portid3_3_reg bf; +}; + +/*[register] PTP_RX_PORTID3_4_REG*/ +#define PTP_RX_PORTID3_4_REG +#define PTP_RX_PORTID3_4_REG_ADDRESS 0x8539 +#define PTP_RX_PORTID3_4_REG_NUM 1 +#define PTP_RX_PORTID3_4_REG_INC 0x1 +#define PTP_RX_PORTID3_4_REG_TYPE REG_TYPE_RW +#define PTP_RX_PORTID3_4_REG_DEFAULT 0x0 + /*[field] RX_PORTID*/ + #define PTP_RX_PORTID3_4_REG_RX_PORTID + #define PTP_RX_PORTID3_4_REG_RX_PORTID_OFFSET 0 + #define PTP_RX_PORTID3_4_REG_RX_PORTID_LEN 16 + #define PTP_RX_PORTID3_4_REG_RX_PORTID_DEFAULT 0x0 + +struct ptp_rx_portid3_4_reg { + a_uint16_t rx_portid:16; +}; + +union ptp_rx_portid3_4_reg_u { + a_uint32_t val; + struct ptp_rx_portid3_4_reg bf; +}; + +/*[register] PTP_RX_TS3_0_REG*/ +#define PTP_RX_TS3_0_REG +#define PTP_RX_TS3_0_REG_ADDRESS 0x853a +#define PTP_RX_TS3_0_REG_NUM 1 +#define PTP_RX_TS3_0_REG_INC 0x1 +#define PTP_RX_TS3_0_REG_TYPE REG_TYPE_RW +#define PTP_RX_TS3_0_REG_DEFAULT 0x0 + /*[field] RX_TS_SEC*/ + #define PTP_RX_TS3_0_REG_RX_TS_SEC + #define PTP_RX_TS3_0_REG_RX_TS_SEC_OFFSET 0 + #define PTP_RX_TS3_0_REG_RX_TS_SEC_LEN 16 + #define PTP_RX_TS3_0_REG_RX_TS_SEC_DEFAULT 0x0 + +struct ptp_rx_ts3_0_reg { + a_uint16_t rx_ts_sec:16; +}; + +union ptp_rx_ts3_0_reg_u { + a_uint32_t val; + struct ptp_rx_ts3_0_reg bf; +}; + +/*[register] PTP_RX_TS3_1_REG*/ +#define PTP_RX_TS3_1_REG +#define PTP_RX_TS3_1_REG_ADDRESS 0x853b +#define PTP_RX_TS3_1_REG_NUM 1 +#define PTP_RX_TS3_1_REG_INC 0x1 +#define PTP_RX_TS3_1_REG_TYPE REG_TYPE_RW +#define PTP_RX_TS3_1_REG_DEFAULT 0x0 + /*[field] RX_TS_SEC*/ + #define PTP_RX_TS3_1_REG_RX_TS_SEC + #define PTP_RX_TS3_1_REG_RX_TS_SEC_OFFSET 0 + #define PTP_RX_TS3_1_REG_RX_TS_SEC_LEN 16 + #define PTP_RX_TS3_1_REG_RX_TS_SEC_DEFAULT 0x0 + +struct ptp_rx_ts3_1_reg { + a_uint16_t rx_ts_sec:16; +}; + +union ptp_rx_ts3_1_reg_u { + a_uint32_t val; + struct ptp_rx_ts3_1_reg bf; +}; + +/*[register] PTP_RX_TS3_2_REG*/ +#define PTP_RX_TS3_2_REG +#define PTP_RX_TS3_2_REG_ADDRESS 0x853c +#define PTP_RX_TS3_2_REG_NUM 1 +#define PTP_RX_TS3_2_REG_INC 0x1 +#define PTP_RX_TS3_2_REG_TYPE REG_TYPE_RW +#define PTP_RX_TS3_2_REG_DEFAULT 0x0 + /*[field] RX_TS_SEC*/ + #define PTP_RX_TS3_2_REG_RX_TS_SEC + #define PTP_RX_TS3_2_REG_RX_TS_SEC_OFFSET 0 + #define PTP_RX_TS3_2_REG_RX_TS_SEC_LEN 16 + #define PTP_RX_TS3_2_REG_RX_TS_SEC_DEFAULT 0x0 + +struct ptp_rx_ts3_2_reg { + a_uint16_t rx_ts_sec:16; +}; + +union ptp_rx_ts3_2_reg_u { + a_uint32_t val; + struct ptp_rx_ts3_2_reg bf; +}; + +/*[register] PTP_RX_TS3_3_REG*/ +#define PTP_RX_TS3_3_REG +#define PTP_RX_TS3_3_REG_ADDRESS 0x853d +#define PTP_RX_TS3_3_REG_NUM 1 +#define PTP_RX_TS3_3_REG_INC 0x1 +#define PTP_RX_TS3_3_REG_TYPE REG_TYPE_RW +#define PTP_RX_TS3_3_REG_DEFAULT 0x0 + /*[field] RX_TS_NSEC*/ + #define PTP_RX_TS3_3_REG_RX_TS_NSEC + #define PTP_RX_TS3_3_REG_RX_TS_NSEC_OFFSET 0 + #define PTP_RX_TS3_3_REG_RX_TS_NSEC_LEN 16 + #define PTP_RX_TS3_3_REG_RX_TS_NSEC_DEFAULT 0x0 + +struct ptp_rx_ts3_3_reg { + a_uint16_t rx_ts_nsec:16; +}; + +union ptp_rx_ts3_3_reg_u { + a_uint32_t val; + struct ptp_rx_ts3_3_reg bf; +}; + +/*[register] PTP_RX_TS3_4_REG*/ +#define PTP_RX_TS3_4_REG +#define PTP_RX_TS3_4_REG_ADDRESS 0x853e +#define PTP_RX_TS3_4_REG_NUM 1 +#define PTP_RX_TS3_4_REG_INC 0x1 +#define PTP_RX_TS3_4_REG_TYPE REG_TYPE_RW +#define PTP_RX_TS3_4_REG_DEFAULT 0x0 + /*[field] RX_TS_NSEC*/ + #define PTP_RX_TS3_4_REG_RX_TS_NSEC + #define PTP_RX_TS3_4_REG_RX_TS_NSEC_OFFSET 0 + #define PTP_RX_TS3_4_REG_RX_TS_NSEC_LEN 16 + #define PTP_RX_TS3_4_REG_RX_TS_NSEC_DEFAULT 0x0 + +struct ptp_rx_ts3_4_reg { + a_uint16_t rx_ts_nsec:16; +}; + +union ptp_rx_ts3_4_reg_u { + a_uint32_t val; + struct ptp_rx_ts3_4_reg bf; +}; + +/*[register] PTP_RX_TS3_5_REG*/ +#define PTP_RX_TS3_5_REG +#define PTP_RX_TS3_5_REG_ADDRESS 0x853f +#define PTP_RX_TS3_5_REG_NUM 1 +#define PTP_RX_TS3_5_REG_INC 0x1 +#define PTP_RX_TS3_5_REG_TYPE REG_TYPE_RW +#define PTP_RX_TS3_5_REG_DEFAULT 0x0 + /*[field] RX_TS_NFSEC*/ + #define PTP_RX_TS3_5_REG_RX_TS_NFSEC + #define PTP_RX_TS3_5_REG_RX_TS_NFSEC_OFFSET 0 + #define PTP_RX_TS3_5_REG_RX_TS_NFSEC_LEN 12 + #define PTP_RX_TS3_5_REG_RX_TS_NFSEC_DEFAULT 0x0 + /*[field] RX_MSG_TYPE*/ + #define PTP_RX_TS3_5_REG_RX_MSG_TYPE + #define PTP_RX_TS3_5_REG_RX_MSG_TYPE_OFFSET 12 + #define PTP_RX_TS3_5_REG_RX_MSG_TYPE_LEN 4 + #define PTP_RX_TS3_5_REG_RX_MSG_TYPE_DEFAULT 0x0 + +struct ptp_rx_ts3_5_reg { + a_uint16_t rx_ts_nfsec:12; + a_uint16_t rx_msg_type:4; +}; + +union ptp_rx_ts3_5_reg_u { + a_uint32_t val; + struct ptp_rx_ts3_5_reg bf; +}; + +/*[register] PTP_RX_TS3_6_REG*/ +#define PTP_RX_TS3_6_REG +#define PTP_RX_TS3_6_REG_ADDRESS 0x8540 +#define PTP_RX_TS3_6_REG_NUM 1 +#define PTP_RX_TS3_6_REG_INC 0x1 +#define PTP_RX_TS3_6_REG_TYPE REG_TYPE_RW +#define PTP_RX_TS3_6_REG_DEFAULT 0x0 + /*[field] RX_TS_NFSEC*/ + #define PTP_RX_TS3_6_REG_RX_TS_NFSEC + #define PTP_RX_TS3_6_REG_RX_TS_NFSEC_OFFSET 0 + #define PTP_RX_TS3_6_REG_RX_TS_NFSEC_LEN 8 + #define PTP_RX_TS3_6_REG_RX_TS_NFSEC_DEFAULT 0x0 + +struct ptp_rx_ts3_6_reg { + a_uint16_t rx_ts_nfsec:8; +}; + +union ptp_rx_ts3_6_reg_u { + a_uint32_t val; + struct ptp_rx_ts3_6_reg bf; +}; + +/*[register] PTP_PHASE_ADJUST_0*/ +#define PTP_PHASE_ADJUST_0_REG +#define PTP_PHASE_ADJUST_0_REG_ADDRESS 0x8300 +#define PTP_PHASE_ADJUST_0_REG_NUM 1 +#define PTP_PHASE_ADJUST_0_REG_INC 0x1 +#define PTP_PHASE_ADJUST_0_REG_TYPE REG_TYPE_RW +#define PTP_PHASE_ADJUST_0_REG_DEFAULT 0x0 + /*[field] PTP_PHASE_ADJUST_0*/ + #define PTP_PHASE_ADJUST_0_REG_PHASE_VALUE + #define PTP_PHASE_ADJUST_0_REG_PHASE_VALUE_OFFSET 0 + #define PTP_PHASE_ADJUST_0_REG_PHASE_VALUE_LEN 16 + #define PTP_PHASE_ADJUST_0_REG_PHASE_VALUE_DEFAULT 0x0 + +struct ptp_phase_adjust_0_reg { + a_uint16_t phase_value:16; +}; + +union ptp_phase_adjust_0_reg_u { + a_uint32_t val; + struct ptp_phase_adjust_0_reg bf; +}; + +/*[register] PTP_PHASE_ADJUST_1*/ +#define PTP_PHASE_ADJUST_1_REG +#define PTP_PHASE_ADJUST_1_REG_ADDRESS 0x8301 +#define PTP_PHASE_ADJUST_1_REG_NUM 1 +#define PTP_PHASE_ADJUST_1_REG_INC 0x1 +#define PTP_PHASE_ADJUST_1_REG_TYPE REG_TYPE_RW +#define PTP_PHASE_ADJUST_1_REG_DEFAULT 0x0 + /*[field] PTP_PHASE_ADJUST_1*/ + #define PTP_PHASE_ADJUST_1_REG_PHASE_VALUE + #define PTP_PHASE_ADJUST_1_REG_PHASE_VALUE_OFFSET 0 + #define PTP_PHASE_ADJUST_1_REG_PHASE_VALUE_LEN 16 + #define PTP_PHASE_ADJUST_1_REG_PHASE_VALUE_DEFAULT 0x0 + +struct ptp_phase_adjust_1_reg { + a_uint16_t phase_value:16; +}; + +union ptp_phase_adjust_1_reg_u { + a_uint32_t val; + struct ptp_phase_adjust_1_reg bf; +}; + +/*[register] PTP_PPS_PUL_WIDTH_0*/ +#define PTP_PPS_PUL_WIDTH_0_REG +#define PTP_PPS_PUL_WIDTH_0_REG_ADDRESS 0x8303 +#define PTP_PPS_PUL_WIDTH_0_REG_NUM 1 +#define PTP_PPS_PUL_WIDTH_0_REG_INC 0x1 +#define PTP_PPS_PUL_WIDTH_0_REG_TYPE REG_TYPE_RW +#define PTP_PPS_PUL_WIDTH_0_REG_DEFAULT 0x0 + /*[field] PTP_PPS_PUL_WIDTH_0*/ + #define PTP_PPS_PUL_WIDTH_0_REG_PUL_VALUE + #define PTP_PPS_PUL_WIDTH_0_REG_PUL_VALUE_OFFSET 0 + #define PTP_PPS_PUL_WIDTH_0_REG_PUL_VALUE_LEN 16 + #define PTP_PPS_PUL_WIDTH_0_REG_PUL_VALUE_DEFAULT 0x0 + +struct ptp_pps_pul_width_0_reg { + a_uint16_t pul_value:16; +}; + +union ptp_pps_pul_width_0_reg_u { + a_uint32_t val; + struct ptp_pps_pul_width_0_reg bf; +}; + +/*[register] PTP_PPS_PUL_WIDTH_1*/ +#define PTP_PPS_PUL_WIDTH_1_REG +#define PTP_PPS_PUL_WIDTH_1_REG_ADDRESS 0x8304 +#define PTP_PPS_PUL_WIDTH_1_REG_NUM 1 +#define PTP_PPS_PUL_WIDTH_1_REG_INC 0x1 +#define PTP_PPS_PUL_WIDTH_1_REG_TYPE REG_TYPE_RW +#define PTP_PPS_PUL_WIDTH_1_REG_DEFAULT 0x0 + /*[field] PTP_PPS_PUL_WIDTH_1*/ + #define PTP_PPS_PUL_WIDTH_1_REG_PUL_VALUE + #define PTP_PPS_PUL_WIDTH_1_REG_PUL_VALUE_OFFSET 0 + #define PTP_PPS_PUL_WIDTH_1_REG_PUL_VALUE_LEN 16 + #define PTP_PPS_PUL_WIDTH_1_REG_PUL_VALUE_DEFAULT 0x0 + +struct ptp_pps_pul_width_1_reg { + a_uint16_t pul_value:16; +}; + +union ptp_pps_pul_width_1_reg_u { + a_uint32_t val; + struct ptp_pps_pul_width_1_reg bf; +}; + +/*[register] PTP_FREQ_WAVEFORM_PERIOD_0_REG*/ +#define PTP_FREQ_WAVEFORM_PERIOD_0_REG +#define PTP_FREQ_WAVEFORM_PERIOD_0_REG_ADDRESS 0x8305 +#define PTP_FREQ_WAVEFORM_PERIOD_0_REG_NUM 1 +#define PTP_FREQ_WAVEFORM_PERIOD_0_REG_INC 0x1 +#define PTP_FREQ_WAVEFORM_PERIOD_0_REG_TYPE REG_TYPE_RW +#define PTP_FREQ_WAVEFORM_PERIOD_0_REG_DEFAULT 0x0 + /*[field] WAVE_PERIOD*/ + #define PTP_FREQ_WAVEFORM_PERIOD_0_REG_WAVE_PERIOD + #define PTP_FREQ_WAVEFORM_PERIOD_0_REG_WAVE_PERIOD_OFFSET 0 + #define PTP_FREQ_WAVEFORM_PERIOD_0_REG_WAVE_PERIOD_LEN 15 + #define PTP_FREQ_WAVEFORM_PERIOD_0_REG_WAVE_PERIOD_DEFAULT 0x0 + /*[field] PHASE_ALI*/ + #define PTP_FREQ_WAVEFORM_PERIOD_0_REG_PHASE_ALI + #define PTP_FREQ_WAVEFORM_PERIOD_0_REG_PHASE_ALI_OFFSET 15 + #define PTP_FREQ_WAVEFORM_PERIOD_0_REG_PHASE_ALI_LEN 1 + #define PTP_FREQ_WAVEFORM_PERIOD_0_REG_PHASE_ALI_DEFAULT 0x0 + +struct ptp_freq_waveform_period_0_reg { + a_uint16_t wave_period:15; + a_uint16_t phase_ali:1; +}; + +union ptp_freq_waveform_period_0_reg_u { + a_uint32_t val; + struct ptp_freq_waveform_period_0_reg bf; +}; + +/*[register] PTP_FREQ_WAVEFORM_PERIOD_1_REG*/ +#define PTP_FREQ_WAVEFORM_PERIOD_1_REG +#define PTP_FREQ_WAVEFORM_PERIOD_1_REG_ADDRESS 0x8306 +#define PTP_FREQ_WAVEFORM_PERIOD_1_REG_NUM 1 +#define PTP_FREQ_WAVEFORM_PERIOD_1_REG_INC 0x1 +#define PTP_FREQ_WAVEFORM_PERIOD_1_REG_TYPE REG_TYPE_RW +#define PTP_FREQ_WAVEFORM_PERIOD_1_REG_DEFAULT 0x0 + /*[field] WAVE_PERIOD*/ + #define PTP_FREQ_WAVEFORM_PERIOD_1_REG_WAVE_PERIOD + #define PTP_FREQ_WAVEFORM_PERIOD_1_REG_WAVE_PERIOD_OFFSET 0 + #define PTP_FREQ_WAVEFORM_PERIOD_1_REG_WAVE_PERIOD_LEN 16 + #define PTP_FREQ_WAVEFORM_PERIOD_1_REG_WAVE_PERIOD_DEFAULT 0x0 + +struct ptp_freq_waveform_period_1_reg { + a_uint16_t wave_period:16; +}; + +union ptp_freq_waveform_period_1_reg_u { + a_uint32_t val; + struct ptp_freq_waveform_period_1_reg bf; +}; + +/*[register] PTP_FREQ_WAVEFORM_PERIOD_2_REG*/ +#define PTP_FREQ_WAVEFORM_PERIOD_2_REG +#define PTP_FREQ_WAVEFORM_PERIOD_2_REG_ADDRESS 0x8307 +#define PTP_FREQ_WAVEFORM_PERIOD_2_REG_NUM 1 +#define PTP_FREQ_WAVEFORM_PERIOD_2_REG_INC 0x1 +#define PTP_FREQ_WAVEFORM_PERIOD_2_REG_TYPE REG_TYPE_RW +#define PTP_FREQ_WAVEFORM_PERIOD_2_REG_DEFAULT 0x0 + /*[field] WAVE_PERIOD*/ + #define PTP_FREQ_WAVEFORM_PERIOD_2_REG_WAVE_PERIOD + #define PTP_FREQ_WAVEFORM_PERIOD_2_REG_WAVE_PERIOD_OFFSET 0 + #define PTP_FREQ_WAVEFORM_PERIOD_2_REG_WAVE_PERIOD_LEN 16 + #define PTP_FREQ_WAVEFORM_PERIOD_2_REG_WAVE_PERIOD_DEFAULT 0x0 + +struct ptp_freq_waveform_period_2_reg { + a_uint16_t wave_period:16; +}; + +union ptp_freq_waveform_period_2_reg_u { + a_uint32_t val; + struct ptp_freq_waveform_period_2_reg bf; +}; + +/*[register] PTP_RX_COM_TS_CTRL_REG*/ +#define PTP_RX_COM_TS_CTRL_REG +#define PTP_RX_COM_TS_CTRL_REG_ADDRESS 0x8600 +#define PTP_RX_COM_TS_CTRL_REG_NUM 1 +#define PTP_RX_COM_TS_CTRL_REG_INC 0x1 +#define PTP_RX_COM_TS_CTRL_REG_TYPE REG_TYPE_RW +#define PTP_RX_COM_TS_CTRL_REG_DEFAULT 0x0 + /*[field] FILT_EN*/ + #define PTP_RX_COM_TS_CTRL_REG_FILT_EN + #define PTP_RX_COM_TS_CTRL_REG_FILT_EN_OFFSET 0 + #define PTP_RX_COM_TS_CTRL_REG_FILT_EN_LEN 1 + #define PTP_RX_COM_TS_CTRL_REG_FILT_EN_DEFAULT 0x0 + /*[field] MAC_LENGTHTYPE_EN*/ + #define PTP_RX_COM_TS_CTRL_REG_MAC_LENGTHTYPE_EN + #define PTP_RX_COM_TS_CTRL_REG_MAC_LENGTHTYPE_EN_OFFSET 1 + #define PTP_RX_COM_TS_CTRL_REG_MAC_LENGTHTYPE_EN_LEN 1 + #define PTP_RX_COM_TS_CTRL_REG_MAC_LENGTHTYPE_EN_DEFAULT 0x0 + /*[field] MAC_DA_EN*/ + #define PTP_RX_COM_TS_CTRL_REG_MAC_DA_EN + #define PTP_RX_COM_TS_CTRL_REG_MAC_DA_EN_OFFSET 2 + #define PTP_RX_COM_TS_CTRL_REG_MAC_DA_EN_LEN 1 + #define PTP_RX_COM_TS_CTRL_REG_MAC_DA_EN_DEFAULT 0x0 + /*[field] MAC_PTP_FILT_EN*/ + #define PTP_RX_COM_TS_CTRL_REG_MAC_PTP_FILT_EN + #define PTP_RX_COM_TS_CTRL_REG_MAC_PTP_FILT_EN_OFFSET 3 + #define PTP_RX_COM_TS_CTRL_REG_MAC_PTP_FILT_EN_LEN 1 + #define PTP_RX_COM_TS_CTRL_REG_MAC_PTP_FILT_EN_DEFAULT 0x0 + /*[field] IPV4_LAYER4_PROTOCOL_EN*/ + #define PTP_RX_COM_TS_CTRL_REG_IPV4_LAYER4_PROTOCOL_EN + #define PTP_RX_COM_TS_CTRL_REG_IPV4_LAYER4_PROTOCOL_EN_OFFSET 4 + #define PTP_RX_COM_TS_CTRL_REG_IPV4_LAYER4_PROTOCOL_EN_LEN 1 + #define PTP_RX_COM_TS_CTRL_REG_IPV4_LAYER4_PROTOCOL_EN_DEFAULT 0x0 + /*[field] IPV4_DA_EN*/ + #define PTP_RX_COM_TS_CTRL_REG_IPV4_DA_EN + #define PTP_RX_COM_TS_CTRL_REG_IPV4_DA_EN_OFFSET 5 + #define PTP_RX_COM_TS_CTRL_REG_IPV4_DA_EN_LEN 1 + #define PTP_RX_COM_TS_CTRL_REG_IPV4_DA_EN_DEFAULT 0x0 + /*[field] IPV4_PTP_FILT_EN*/ + #define PTP_RX_COM_TS_CTRL_REG_IPV4_PTP_FILT_EN + #define PTP_RX_COM_TS_CTRL_REG_IPV4_PTP_FILT_EN_OFFSET 6 + #define PTP_RX_COM_TS_CTRL_REG_IPV4_PTP_FILT_EN_LEN 1 + #define PTP_RX_COM_TS_CTRL_REG_IPV4_PTP_FILT_EN_DEFAULT 0x0 + /*[field] IPV6_NEXT_HEADER_EN*/ + #define PTP_RX_COM_TS_CTRL_REG_IPV6_NEXT_HEADER_EN + #define PTP_RX_COM_TS_CTRL_REG_IPV6_NEXT_HEADER_EN_OFFSET 7 + #define PTP_RX_COM_TS_CTRL_REG_IPV6_NEXT_HEADER_EN_LEN 1 + #define PTP_RX_COM_TS_CTRL_REG_IPV6_NEXT_HEADER_EN_DEFAULT 0x0 + /*[field] IPV6_DA_FILT_EN*/ + #define PTP_RX_COM_TS_CTRL_REG_IPV6_DA_FILT_EN + #define PTP_RX_COM_TS_CTRL_REG_IPV6_DA_FILT_EN_OFFSET 8 + #define PTP_RX_COM_TS_CTRL_REG_IPV6_DA_FILT_EN_LEN 1 + #define PTP_RX_COM_TS_CTRL_REG_IPV6_DA_FILT_EN_DEFAULT 0x0 + /*[field] IPV6_PTP_FILT_EN*/ + #define PTP_RX_COM_TS_CTRL_REG_IPV6_PTP_FILT_EN + #define PTP_RX_COM_TS_CTRL_REG_IPV6_PTP_FILT_EN_OFFSET 9 + #define PTP_RX_COM_TS_CTRL_REG_IPV6_PTP_FILT_EN_LEN 1 + #define PTP_RX_COM_TS_CTRL_REG_IPV6_PTP_FILT_EN_DEFAULT 0x0 + /*[field] UDP_DPORT_EN*/ + #define PTP_RX_COM_TS_CTRL_REG_UDP_DPORT_EN + #define PTP_RX_COM_TS_CTRL_REG_UDP_DPORT_EN_OFFSET 10 + #define PTP_RX_COM_TS_CTRL_REG_UDP_DPORT_EN_LEN 1 + #define PTP_RX_COM_TS_CTRL_REG_UDP_DPORT_EN_DEFAULT 0x0 + /*[field] UDP_PTP_EVENT_FILT_EN*/ + #define PTP_RX_COM_TS_CTRL_REG_UDP_PTP_EVENT_FILT_EN + #define PTP_RX_COM_TS_CTRL_REG_UDP_PTP_EVENT_FILT_EN_OFFSET 11 + #define PTP_RX_COM_TS_CTRL_REG_UDP_PTP_EVENT_FILT_EN_LEN 1 + #define PTP_RX_COM_TS_CTRL_REG_UDP_PTP_EVENT_FILT_EN_DEFAULT 0x0 + /*[field] Y1731_EN*/ + #define PTP_RX_COM_TS_CTRL_REG_Y1731_EN + #define PTP_RX_COM_TS_CTRL_REG_Y1731_EN_OFFSET 12 + #define PTP_RX_COM_TS_CTRL_REG_Y1731_EN_LEN 1 + #define PTP_RX_COM_TS_CTRL_REG_Y1731_EN_DEFAULT 0x0 + /*[field] Y1731_INSERT_TS_EN*/ + #define PTP_RX_COM_TS_CTRL_REG_Y1731_INSERT_TS_EN + #define PTP_RX_COM_TS_CTRL_REG_Y1731_INSERT_TS_EN_OFFSET 13 + #define PTP_RX_COM_TS_CTRL_REG_Y1731_INSERT_TS_EN_LEN 1 + #define PTP_RX_COM_TS_CTRL_REG_Y1731_INSERT_TS_EN_DEFAULT 0x0 + /*[field] Y1731_DA_CHK_EN*/ + #define PTP_RX_COM_TS_CTRL_REG_Y1731_DA_CHK_EN + #define PTP_RX_COM_TS_CTRL_REG_Y1731_DA_CHK_EN_OFFSET 14 + #define PTP_RX_COM_TS_CTRL_REG_Y1731_DA_CHK_EN_LEN 1 + #define PTP_RX_COM_TS_CTRL_REG_Y1731_DA_CHK_EN_DEFAULT 0x0 + /*[field] PW_MAC_EN*/ + #define PTP_RX_COM_TS_CTRL_REG_PW_MAC_EN + #define PTP_RX_COM_TS_CTRL_REG_PW_MAC_EN_OFFSET 15 + #define PTP_RX_COM_TS_CTRL_REG_PW_MAC_EN_LEN 1 + #define PTP_RX_COM_TS_CTRL_REG_PW_MAC_EN_DEFAULT 0x0 + +struct ptp_rx_com_ts_ctrl_reg { + a_uint32_t filt_en:1; + a_uint32_t mac_lengthtype_en:1; + a_uint32_t mac_da_en:1; + a_uint32_t mac_ptp_filt_en:1; + a_uint32_t ipv4_layer4_protocol_en:1; + a_uint32_t ipv4_da_en:1; + a_uint32_t ipv4_ptp_filt_en:1; + a_uint32_t ipv6_next_header_en:1; + a_uint32_t ipv6_da_filt_en:1; + a_uint32_t ipv6_ptp_filt_en:1; + a_uint32_t udp_dport_en:1; + a_uint32_t udp_ptp_event_filt_en:1; + a_uint32_t y1731_en:1; + a_uint32_t y1731_insert_ts_en:1; + a_uint32_t y1731_da_chk_en:1; + a_uint32_t pw_mac_en:1; +}; + +union ptp_rx_com_ts_ctrl_reg_u { + a_uint32_t val; + struct ptp_rx_com_ts_ctrl_reg bf; +}; + +/*[register] PTP_RX_FILT_MAC_DA0_REG*/ +#define PTP_RX_FILT_MAC_DA0_REG +#define PTP_RX_FILT_MAC_DA0_REG_ADDRESS 0x8601 +#define PTP_RX_FILT_MAC_DA0_REG_NUM 1 +#define PTP_RX_FILT_MAC_DA0_REG_INC 0x1 +#define PTP_RX_FILT_MAC_DA0_REG_TYPE REG_TYPE_RW +#define PTP_RX_FILT_MAC_DA0_REG_DEFAULT 0x0 + /*[field] MAC_ADDR*/ + #define PTP_RX_FILT_MAC_DA0_REG_MAC_ADDR + #define PTP_RX_FILT_MAC_DA0_REG_MAC_ADDR_OFFSET 0 + #define PTP_RX_FILT_MAC_DA0_REG_MAC_ADDR_LEN 16 + #define PTP_RX_FILT_MAC_DA0_REG_MAC_ADDR_DEFAULT 0x0 + +struct ptp_rx_filt_mac_da0_reg { + a_uint32_t mac_addr:16; +}; + +union ptp_rx_filt_mac_da0_reg_u { + a_uint32_t val; + struct ptp_rx_filt_mac_da0_reg bf; +}; + +/*[register] PTP_RX_FILT_MAC_DA1_REG*/ +#define PTP_RX_FILT_MAC_DA1_REG +#define PTP_RX_FILT_MAC_DA1_REG_ADDRESS 0x8602 +#define PTP_RX_FILT_MAC_DA1_REG_NUM 1 +#define PTP_RX_FILT_MAC_DA1_REG_INC 0x1 +#define PTP_RX_FILT_MAC_DA1_REG_TYPE REG_TYPE_RW +#define PTP_RX_FILT_MAC_DA1_REG_DEFAULT 0x0 + /*[field] MAC_ADDR*/ + #define PTP_RX_FILT_MAC_DA1_REG_MAC_ADDR + #define PTP_RX_FILT_MAC_DA1_REG_MAC_ADDR_OFFSET 0 + #define PTP_RX_FILT_MAC_DA1_REG_MAC_ADDR_LEN 16 + #define PTP_RX_FILT_MAC_DA1_REG_MAC_ADDR_DEFAULT 0x0 + +struct ptp_rx_filt_mac_da1_reg { + a_uint32_t mac_addr:16; +}; + +union ptp_rx_filt_mac_da1_reg_u { + a_uint32_t val; + struct ptp_rx_filt_mac_da1_reg bf; +}; + +/*[register] PTP_RX_FILT_MAC_DA2_REG*/ +#define PTP_RX_FILT_MAC_DA2_REG +#define PTP_RX_FILT_MAC_DA2_REG_ADDRESS 0x8603 +#define PTP_RX_FILT_MAC_DA2_REG_NUM 1 +#define PTP_RX_FILT_MAC_DA2_REG_INC 0x1 +#define PTP_RX_FILT_MAC_DA2_REG_TYPE REG_TYPE_RW +#define PTP_RX_FILT_MAC_DA2_REG_DEFAULT 0x0 + /*[field] MAC_ADDR*/ + #define PTP_RX_FILT_MAC_DA2_REG_MAC_ADDR + #define PTP_RX_FILT_MAC_DA2_REG_MAC_ADDR_OFFSET 0 + #define PTP_RX_FILT_MAC_DA2_REG_MAC_ADDR_LEN 16 + #define PTP_RX_FILT_MAC_DA2_REG_MAC_ADDR_DEFAULT 0x0 + +struct ptp_rx_filt_mac_da2_reg { + a_uint32_t mac_addr:16; +}; + +union ptp_rx_filt_mac_da2_reg_u { + a_uint32_t val; + struct ptp_rx_filt_mac_da2_reg bf; +}; + +/*[register] PTP_RX_FILT_IPV4_DA0_REG*/ +#define PTP_RX_FILT_IPV4_DA0_REG +#define PTP_RX_FILT_IPV4_DA0_REG_ADDRESS 0x8604 +#define PTP_RX_FILT_IPV4_DA0_REG_NUM 1 +#define PTP_RX_FILT_IPV4_DA0_REG_INC 0x1 +#define PTP_RX_FILT_IPV4_DA0_REG_TYPE REG_TYPE_RW +#define PTP_RX_FILT_IPV4_DA0_REG_DEFAULT 0x0 + /*[field] IP_ADDR*/ + #define PTP_RX_FILT_IPV4_DA0_REG_IP_ADDR + #define PTP_RX_FILT_IPV4_DA0_REG_IP_ADDR_OFFSET 0 + #define PTP_RX_FILT_IPV4_DA0_REG_IP_ADDR_LEN 16 + #define PTP_RX_FILT_IPV4_DA0_REG_IP_ADDR_DEFAULT 0x0 + +struct ptp_rx_filt_ipv4_da0_reg { + a_uint32_t ip_addr:16; +}; + +union ptp_rx_filt_ipv4_da0_reg_u { + a_uint32_t val; + struct ptp_rx_filt_ipv4_da0_reg bf; +}; + +/*[register] PTP_RX_FILT_IPV4_DA1_REG*/ +#define PTP_RX_FILT_IPV4_DA1_REG +#define PTP_RX_FILT_IPV4_DA1_REG_ADDRESS 0x8605 +#define PTP_RX_FILT_IPV4_DA1_REG_NUM 1 +#define PTP_RX_FILT_IPV4_DA1_REG_INC 0x1 +#define PTP_RX_FILT_IPV4_DA1_REG_TYPE REG_TYPE_RW +#define PTP_RX_FILT_IPV4_DA1_REG_DEFAULT 0x0 + /*[field] IP_ADDR*/ + #define PTP_RX_FILT_IPV4_DA1_REG_IP_ADDR + #define PTP_RX_FILT_IPV4_DA1_REG_IP_ADDR_OFFSET 0 + #define PTP_RX_FILT_IPV4_DA1_REG_IP_ADDR_LEN 16 + #define PTP_RX_FILT_IPV4_DA1_REG_IP_ADDR_DEFAULT 0x0 + +struct ptp_rx_filt_ipv4_da1_reg { + a_uint32_t ip_addr:16; +}; + +union ptp_rx_filt_ipv4_da1_reg_u { + a_uint32_t val; + struct ptp_rx_filt_ipv4_da1_reg bf; +}; + +/*[register] PTP_RX_FILT_IPV6_DA0_REG*/ +#define PTP_RX_FILT_IPV6_DA0_REG +#define PTP_RX_FILT_IPV6_DA0_REG_ADDRESS 0x8606 +#define PTP_RX_FILT_IPV6_DA0_REG_NUM 1 +#define PTP_RX_FILT_IPV6_DA0_REG_INC 0x1 +#define PTP_RX_FILT_IPV6_DA0_REG_TYPE REG_TYPE_RW +#define PTP_RX_FILT_IPV6_DA0_REG_DEFAULT 0x0 + /*[field] IP_ADDR*/ + #define PTP_RX_FILT_IPV6_DA0_REG_IP_ADDR + #define PTP_RX_FILT_IPV6_DA0_REG_IP_ADDR_OFFSET 0 + #define PTP_RX_FILT_IPV6_DA0_REG_IP_ADDR_LEN 16 + #define PTP_RX_FILT_IPV6_DA0_REG_IP_ADDR_DEFAULT 0x0 + +struct ptp_rx_filt_ipv6_da0_reg { + a_uint32_t ip_addr:16; +}; + +union ptp_rx_filt_ipv6_da0_reg_u { + a_uint32_t val; + struct ptp_rx_filt_ipv6_da0_reg bf; +}; + +/*[register] PTP_RX_FILT_IPV6_DA1_REG*/ +#define PTP_RX_FILT_IPV6_DA1_REG +#define PTP_RX_FILT_IPV6_DA1_REG_ADDRESS 0x8607 +#define PTP_RX_FILT_IPV6_DA1_REG_NUM 1 +#define PTP_RX_FILT_IPV6_DA1_REG_INC 0x1 +#define PTP_RX_FILT_IPV6_DA1_REG_TYPE REG_TYPE_RW +#define PTP_RX_FILT_IPV6_DA1_REG_DEFAULT 0x0 + /*[field] IP_ADDR*/ + #define PTP_RX_FILT_IPV6_DA1_REG_IP_ADDR + #define PTP_RX_FILT_IPV6_DA1_REG_IP_ADDR_OFFSET 0 + #define PTP_RX_FILT_IPV6_DA1_REG_IP_ADDR_LEN 16 + #define PTP_RX_FILT_IPV6_DA1_REG_IP_ADDR_DEFAULT 0x0 + +struct ptp_rx_filt_ipv6_da1_reg { + a_uint32_t ip_addr:16; +}; + +union ptp_rx_filt_ipv6_da1_reg_u { + a_uint32_t val; + struct ptp_rx_filt_ipv6_da1_reg bf; +}; + +/*[register] PTP_RX_FILT_IPV6_DA2_REG*/ +#define PTP_RX_FILT_IPV6_DA2_REG +#define PTP_RX_FILT_IPV6_DA2_REG_ADDRESS 0x8608 +#define PTP_RX_FILT_IPV6_DA2_REG_NUM 1 +#define PTP_RX_FILT_IPV6_DA2_REG_INC 0x1 +#define PTP_RX_FILT_IPV6_DA2_REG_TYPE REG_TYPE_RW +#define PTP_RX_FILT_IPV6_DA2_REG_DEFAULT 0x0 + /*[field] IP_ADDR*/ + #define PTP_RX_FILT_IPV6_DA2_REG_IP_ADDR + #define PTP_RX_FILT_IPV6_DA2_REG_IP_ADDR_OFFSET 0 + #define PTP_RX_FILT_IPV6_DA2_REG_IP_ADDR_LEN 16 + #define PTP_RX_FILT_IPV6_DA2_REG_IP_ADDR_DEFAULT 0x0 + +struct ptp_rx_filt_ipv6_da2_reg { + a_uint32_t ip_addr:16; +}; + +union ptp_rx_filt_ipv6_da2_reg_u { + a_uint32_t val; + struct ptp_rx_filt_ipv6_da2_reg bf; +}; + +/*[register] PTP_RX_FILT_IPV6_DA3_REG*/ +#define PTP_RX_FILT_IPV6_DA3_REG +#define PTP_RX_FILT_IPV6_DA3_REG_ADDRESS 0x8609 +#define PTP_RX_FILT_IPV6_DA3_REG_NUM 1 +#define PTP_RX_FILT_IPV6_DA3_REG_INC 0x1 +#define PTP_RX_FILT_IPV6_DA3_REG_TYPE REG_TYPE_RW +#define PTP_RX_FILT_IPV6_DA3_REG_DEFAULT 0x0 + /*[field] IP_ADDR*/ + #define PTP_RX_FILT_IPV6_DA3_REG_IP_ADDR + #define PTP_RX_FILT_IPV6_DA3_REG_IP_ADDR_OFFSET 0 + #define PTP_RX_FILT_IPV6_DA3_REG_IP_ADDR_LEN 16 + #define PTP_RX_FILT_IPV6_DA3_REG_IP_ADDR_DEFAULT 0x0 + +struct ptp_rx_filt_ipv6_da3_reg { + a_uint32_t ip_addr:16; +}; + +union ptp_rx_filt_ipv6_da3_reg_u { + a_uint32_t val; + struct ptp_rx_filt_ipv6_da3_reg bf; +}; + +/*[register] PTP_RX_FILT_IPV6_DA4_REG*/ +#define PTP_RX_FILT_IPV6_DA4_REG +#define PTP_RX_FILT_IPV6_DA4_REG_ADDRESS 0x860a +#define PTP_RX_FILT_IPV6_DA4_REG_NUM 1 +#define PTP_RX_FILT_IPV6_DA4_REG_INC 0x1 +#define PTP_RX_FILT_IPV6_DA4_REG_TYPE REG_TYPE_RW +#define PTP_RX_FILT_IPV6_DA4_REG_DEFAULT 0x0 + /*[field] IP_ADDR*/ + #define PTP_RX_FILT_IPV6_DA4_REG_IP_ADDR + #define PTP_RX_FILT_IPV6_DA4_REG_IP_ADDR_OFFSET 0 + #define PTP_RX_FILT_IPV6_DA4_REG_IP_ADDR_LEN 16 + #define PTP_RX_FILT_IPV6_DA4_REG_IP_ADDR_DEFAULT 0x0 + +struct ptp_rx_filt_ipv6_da4_reg { + a_uint32_t ip_addr:16; +}; + +union ptp_rx_filt_ipv6_da4_reg_u { + a_uint32_t val; + struct ptp_rx_filt_ipv6_da4_reg bf; +}; + +/*[register] PTP_RX_FILT_IPV6_DA5_REG*/ +#define PTP_RX_FILT_IPV6_DA5_REG +#define PTP_RX_FILT_IPV6_DA5_REG_ADDRESS 0x860b +#define PTP_RX_FILT_IPV6_DA5_REG_NUM 1 +#define PTP_RX_FILT_IPV6_DA5_REG_INC 0x1 +#define PTP_RX_FILT_IPV6_DA5_REG_TYPE REG_TYPE_RW +#define PTP_RX_FILT_IPV6_DA5_REG_DEFAULT 0x0 + /*[field] IP_ADDR*/ + #define PTP_RX_FILT_IPV6_DA5_REG_IP_ADDR + #define PTP_RX_FILT_IPV6_DA5_REG_IP_ADDR_OFFSET 0 + #define PTP_RX_FILT_IPV6_DA5_REG_IP_ADDR_LEN 16 + #define PTP_RX_FILT_IPV6_DA5_REG_IP_ADDR_DEFAULT 0x0 + +struct ptp_rx_filt_ipv6_da5_reg { + a_uint32_t ip_addr:16; +}; + +union ptp_rx_filt_ipv6_da5_reg_u { + a_uint32_t val; + struct ptp_rx_filt_ipv6_da5_reg bf; +}; + +/*[register] PTP_RX_FILT_IPV6_DA6_REG*/ +#define PTP_RX_FILT_IPV6_DA6_REG +#define PTP_RX_FILT_IPV6_DA6_REG_ADDRESS 0x860c +#define PTP_RX_FILT_IPV6_DA6_REG_NUM 1 +#define PTP_RX_FILT_IPV6_DA6_REG_INC 0x1 +#define PTP_RX_FILT_IPV6_DA6_REG_TYPE REG_TYPE_RW +#define PTP_RX_FILT_IPV6_DA6_REG_DEFAULT 0x0 + /*[field] IP_ADDR*/ + #define PTP_RX_FILT_IPV6_DA6_REG_IP_ADDR + #define PTP_RX_FILT_IPV6_DA6_REG_IP_ADDR_OFFSET 0 + #define PTP_RX_FILT_IPV6_DA6_REG_IP_ADDR_LEN 16 + #define PTP_RX_FILT_IPV6_DA6_REG_IP_ADDR_DEFAULT 0x0 + +struct ptp_rx_filt_ipv6_da6_reg { + a_uint32_t ip_addr:16; +}; + +union ptp_rx_filt_ipv6_da6_reg_u { + a_uint32_t val; + struct ptp_rx_filt_ipv6_da6_reg bf; +}; + +/*[register] PTP_RX_FILT_IPV6_DA7_REG*/ +#define PTP_RX_FILT_IPV6_DA7_REG +#define PTP_RX_FILT_IPV6_DA7_REG_ADDRESS 0x860d +#define PTP_RX_FILT_IPV6_DA7_REG_NUM 1 +#define PTP_RX_FILT_IPV6_DA7_REG_INC 0x1 +#define PTP_RX_FILT_IPV6_DA7_REG_TYPE REG_TYPE_RW +#define PTP_RX_FILT_IPV6_DA7_REG_DEFAULT 0x0 + /*[field] IP_ADDR*/ + #define PTP_RX_FILT_IPV6_DA7_REG_IP_ADDR + #define PTP_RX_FILT_IPV6_DA7_REG_IP_ADDR_OFFSET 0 + #define PTP_RX_FILT_IPV6_DA7_REG_IP_ADDR_LEN 16 + #define PTP_RX_FILT_IPV6_DA7_REG_IP_ADDR_DEFAULT 0x0 + +struct ptp_rx_filt_ipv6_da7_reg { + a_uint32_t ip_addr:16; +}; + +union ptp_rx_filt_ipv6_da7_reg_u { + a_uint32_t val; + struct ptp_rx_filt_ipv6_da7_reg bf; +}; + +/*[register] PTP_RX_FILT_MAC_LENGTHTYPE_REG*/ +#define PTP_RX_FILT_MAC_LENGTHTYPE_REG +#define PTP_RX_FILT_MAC_LENGTHTYPE_REG_ADDRESS 0x860e +#define PTP_RX_FILT_MAC_LENGTHTYPE_REG_NUM 1 +#define PTP_RX_FILT_MAC_LENGTHTYPE_REG_INC 0x1 +#define PTP_RX_FILT_MAC_LENGTHTYPE_REG_TYPE REG_TYPE_RW +#define PTP_RX_FILT_MAC_LENGTHTYPE_REG_DEFAULT 0x0 + /*[field] LENGTH_TYPE*/ + #define PTP_RX_FILT_MAC_LENGTHTYPE_REG_LENGTH_TYPE + #define PTP_RX_FILT_MAC_LENGTHTYPE_REG_LENGTH_TYPE_OFFSET 0 + #define PTP_RX_FILT_MAC_LENGTHTYPE_REG_LENGTH_TYPE_LEN 16 + #define PTP_RX_FILT_MAC_LENGTHTYPE_REG_LENGTH_TYPE_DEFAULT 0x0 + +struct ptp_rx_filt_mac_lengthtype_reg { + a_uint32_t length_type:16; +}; + +union ptp_rx_filt_mac_lengthtype_reg_u { + a_uint32_t val; + struct ptp_rx_filt_mac_lengthtype_reg bf; +}; + +/*[register] PTP_RX_FILT_LAYER4_PROTOCOL_REG*/ +#define PTP_RX_FILT_LAYER4_PROTOCOL_REG +#define PTP_RX_FILT_LAYER4_PROTOCOL_REG_ADDRESS 0x860f +#define PTP_RX_FILT_LAYER4_PROTOCOL_REG_NUM 1 +#define PTP_RX_FILT_LAYER4_PROTOCOL_REG_INC 0x1 +#define PTP_RX_FILT_LAYER4_PROTOCOL_REG_TYPE REG_TYPE_RW +#define PTP_RX_FILT_LAYER4_PROTOCOL_REG_DEFAULT 0x0 + /*[field] L4_PROTOCOL*/ + #define PTP_RX_FILT_LAYER4_PROTOCOL_REG_L4_PROTOCOL + #define PTP_RX_FILT_LAYER4_PROTOCOL_REG_L4_PROTOCOL_OFFSET 0 + #define PTP_RX_FILT_LAYER4_PROTOCOL_REG_L4_PROTOCOL_LEN 16 + #define PTP_RX_FILT_LAYER4_PROTOCOL_REG_L4_PROTOCOL_DEFAULT 0x0 + +struct ptp_rx_filt_layer4_protocol_reg { + a_uint32_t l4_protocol:16; +}; + +union ptp_rx_filt_layer4_protocol_reg_u { + a_uint32_t val; + struct ptp_rx_filt_layer4_protocol_reg bf; +}; + +/*[register] PTP_RX_FILT_UDP_PORT_REG*/ +#define PTP_RX_FILT_UDP_PORT_REG +#define PTP_RX_FILT_UDP_PORT_REG_ADDRESS 0x8610 +#define PTP_RX_FILT_UDP_PORT_REG_NUM 1 +#define PTP_RX_FILT_UDP_PORT_REG_INC 0x1 +#define PTP_RX_FILT_UDP_PORT_REG_TYPE REG_TYPE_RW +#define PTP_RX_FILT_UDP_PORT_REG_DEFAULT 0x0 + /*[field] UDP_PORT*/ + #define PTP_RX_FILT_UDP_PORT_REG_UDP_PORT + #define PTP_RX_FILT_UDP_PORT_REG_UDP_PORT_OFFSET 0 + #define PTP_RX_FILT_UDP_PORT_REG_UDP_PORT_LEN 16 + #define PTP_RX_FILT_UDP_PORT_REG_UDP_PORT_DEFAULT 0x0 + +struct ptp_rx_filt_udp_port_reg { + a_uint32_t udp_port:16; +}; + +union ptp_rx_filt_udp_port_reg_u { + a_uint32_t val; + struct ptp_rx_filt_udp_port_reg bf; +}; + +/*[register] PTP_RX_COM_TS_STATUS_REG*/ +#define PTP_RX_COM_TS_STATUS_REG +#define PTP_RX_COM_TS_STATUS_REG_ADDRESS 0x8611 +#define PTP_RX_COM_TS_STATUS_REG_NUM 1 +#define PTP_RX_COM_TS_STATUS_REG_INC 0x1 +#define PTP_RX_COM_TS_STATUS_REG_TYPE REG_TYPE_RW +#define PTP_RX_COM_TS_STATUS_REG_DEFAULT 0x0 + /*[field] MAC_LENGTHTYPE*/ + #define PTP_RX_COM_TS_STATUS_REG_MAC_LENGTHTYPE + #define PTP_RX_COM_TS_STATUS_REG_MAC_LENGTHTYPE_OFFSET 0 + #define PTP_RX_COM_TS_STATUS_REG_MAC_LENGTHTYPE_LEN 1 + #define PTP_RX_COM_TS_STATUS_REG_MAC_LENGTHTYPE_DEFAULT 0x0 + /*[field] MAC_DA*/ + #define PTP_RX_COM_TS_STATUS_REG_MAC_DA + #define PTP_RX_COM_TS_STATUS_REG_MAC_DA_OFFSET 1 + #define PTP_RX_COM_TS_STATUS_REG_MAC_DA_LEN 1 + #define PTP_RX_COM_TS_STATUS_REG_MAC_DA_DEFAULT 0x0 + /*[field] MAC_PTP_PRIM_ADDR*/ + #define PTP_RX_COM_TS_STATUS_REG_MAC_PTP_PRIM_ADDR + #define PTP_RX_COM_TS_STATUS_REG_MAC_PTP_PRIM_ADDR_OFFSET 2 + #define PTP_RX_COM_TS_STATUS_REG_MAC_PTP_PRIM_ADDR_LEN 1 + #define PTP_RX_COM_TS_STATUS_REG_MAC_PTP_PRIM_ADDR_DEFAULT 0x0 + /*[field] MAC_PTP_PDELAY_ADDR*/ + #define PTP_RX_COM_TS_STATUS_REG_MAC_PTP_PDELAY_ADDR + #define PTP_RX_COM_TS_STATUS_REG_MAC_PTP_PDELAY_ADDR_OFFSET 3 + #define PTP_RX_COM_TS_STATUS_REG_MAC_PTP_PDELAY_ADDR_LEN 1 + #define PTP_RX_COM_TS_STATUS_REG_MAC_PTP_PDELAY_ADDR_DEFAULT 0x0 + /*[field] IPV4_LAYER4_PROTOCOL*/ + #define PTP_RX_COM_TS_STATUS_REG_IPV4_LAYER4_PROTOCOL + #define PTP_RX_COM_TS_STATUS_REG_IPV4_LAYER4_PROTOCOL_OFFSET 4 + #define PTP_RX_COM_TS_STATUS_REG_IPV4_LAYER4_PROTOCOL_LEN 1 + #define PTP_RX_COM_TS_STATUS_REG_IPV4_LAYER4_PROTOCOL_DEFAULT 0x0 + /*[field] IPV4_DA*/ + #define PTP_RX_COM_TS_STATUS_REG_IPV4_DA + #define PTP_RX_COM_TS_STATUS_REG_IPV4_DA_OFFSET 5 + #define PTP_RX_COM_TS_STATUS_REG_IPV4_DA_LEN 1 + #define PTP_RX_COM_TS_STATUS_REG_IPV4_DA_DEFAULT 0x0 + /*[field] IPV4_PTP_PRIM_ADDR*/ + #define PTP_RX_COM_TS_STATUS_REG_IPV4_PTP_PRIM_ADDR + #define PTP_RX_COM_TS_STATUS_REG_IPV4_PTP_PRIM_ADDR_OFFSET 6 + #define PTP_RX_COM_TS_STATUS_REG_IPV4_PTP_PRIM_ADDR_LEN 1 + #define PTP_RX_COM_TS_STATUS_REG_IPV4_PTP_PRIM_ADDR_DEFAULT 0x0 + /*[field] IPV4_PTP_PDELAY_ADDR*/ + #define PTP_RX_COM_TS_STATUS_REG_IPV4_PTP_PDELAY_ADDR + #define PTP_RX_COM_TS_STATUS_REG_IPV4_PTP_PDELAY_ADDR_OFFSET 7 + #define PTP_RX_COM_TS_STATUS_REG_IPV4_PTP_PDELAY_ADDR_LEN 1 + #define PTP_RX_COM_TS_STATUS_REG_IPV4_PTP_PDELAY_ADDR_DEFAULT 0x0 + /*[field] IPV6_NEXT_HEADER*/ + #define PTP_RX_COM_TS_STATUS_REG_IPV6_NEXT_HEADER + #define PTP_RX_COM_TS_STATUS_REG_IPV6_NEXT_HEADER_OFFSET 8 + #define PTP_RX_COM_TS_STATUS_REG_IPV6_NEXT_HEADER_LEN 1 + #define PTP_RX_COM_TS_STATUS_REG_IPV6_NEXT_HEADER_DEFAULT 0x0 + /*[field] IPV6_DA*/ + #define PTP_RX_COM_TS_STATUS_REG_IPV6_DA + #define PTP_RX_COM_TS_STATUS_REG_IPV6_DA_OFFSET 9 + #define PTP_RX_COM_TS_STATUS_REG_IPV6_DA_LEN 1 + #define PTP_RX_COM_TS_STATUS_REG_IPV6_DA_DEFAULT 0x0 + /*[field] IPV6_PTP_PRIM_ADDR*/ + #define PTP_RX_COM_TS_STATUS_REG_IPV6_PTP_PRIM_ADDR + #define PTP_RX_COM_TS_STATUS_REG_IPV6_PTP_PRIM_ADDR_OFFSET 10 + #define PTP_RX_COM_TS_STATUS_REG_IPV6_PTP_PRIM_ADDR_LEN 1 + #define PTP_RX_COM_TS_STATUS_REG_IPV6_PTP_PRIM_ADDR_DEFAULT 0x0 + /*[field] IPV6_PTP_PDELAY_ADDR*/ + #define PTP_RX_COM_TS_STATUS_REG_IPV6_PTP_PDELAY_ADDR + #define PTP_RX_COM_TS_STATUS_REG_IPV6_PTP_PDELAY_ADDR_OFFSET 11 + #define PTP_RX_COM_TS_STATUS_REG_IPV6_PTP_PDELAY_ADDR_LEN 1 + #define PTP_RX_COM_TS_STATUS_REG_IPV6_PTP_PDELAY_ADDR_DEFAULT 0x0 + /*[field] UDP_DPORT*/ + #define PTP_RX_COM_TS_STATUS_REG_UDP_DPORT + #define PTP_RX_COM_TS_STATUS_REG_UDP_DPORT_OFFSET 12 + #define PTP_RX_COM_TS_STATUS_REG_UDP_DPORT_LEN 1 + #define PTP_RX_COM_TS_STATUS_REG_UDP_DPORT_DEFAULT 0x0 + /*[field] UDP_PTP_EVENT_DPORT*/ + #define PTP_RX_COM_TS_STATUS_REG_UDP_PTP_EVENT_DPORT + #define PTP_RX_COM_TS_STATUS_REG_UDP_PTP_EVENT_DPORT_OFFSET 13 + #define PTP_RX_COM_TS_STATUS_REG_UDP_PTP_EVENT_DPORT_LEN 1 + #define PTP_RX_COM_TS_STATUS_REG_UDP_PTP_EVENT_DPORT_DEFAULT 0x0 + /*[field] Y1731_MACH*/ + #define PTP_RX_COM_TS_STATUS_REG_Y1731_MACH + #define PTP_RX_COM_TS_STATUS_REG_Y1731_MACH_OFFSET 14 + #define PTP_RX_COM_TS_STATUS_REG_Y1731_MACH_LEN 1 + #define PTP_RX_COM_TS_STATUS_REG_Y1731_MACH_DEFAULT 0x0 + +struct ptp_rx_com_ts_status_reg { + a_uint32_t mac_lengthtype:1; + a_uint32_t mac_da:1; + a_uint32_t mac_ptp_prim_addr:1; + a_uint32_t mac_ptp_pdelay_addr:1; + a_uint32_t ipv4_layer4_protocol:1; + a_uint32_t ipv4_da:1; + a_uint32_t ipv4_ptp_prim_addr:1; + a_uint32_t ipv4_ptp_pdelay_addr:1; + a_uint32_t ipv6_next_header:1; + a_uint32_t ipv6_da:1; + a_uint32_t ipv6_ptp_prim_addr:1; + a_uint32_t ipv6_ptp_pdelay_addr:1; + a_uint32_t udp_dport:1; + a_uint32_t udp_ptp_event_dport:1; + a_uint32_t y1731_mach:1; +}; + +union ptp_rx_com_ts_status_reg_u { + a_uint32_t val; + struct ptp_rx_com_ts_status_reg bf; +}; + +/*[register] PTP_RX_COM_TIMESTAMP0_REG*/ +#define PTP_RX_COM_TIMESTAMP0_REG +#define PTP_RX_COM_TIMESTAMP0_REG_ADDRESS 0x8612 +#define PTP_RX_COM_TIMESTAMP0_REG_NUM 1 +#define PTP_RX_COM_TIMESTAMP0_REG_INC 0x1 +#define PTP_RX_COM_TIMESTAMP0_REG_TYPE REG_TYPE_RW +#define PTP_RX_COM_TIMESTAMP0_REG_DEFAULT 0x0 + /*[field] COM_TS*/ + #define PTP_RX_COM_TIMESTAMP0_REG_COM_TS + #define PTP_RX_COM_TIMESTAMP0_REG_COM_TS_OFFSET 0 + #define PTP_RX_COM_TIMESTAMP0_REG_COM_TS_LEN 16 + #define PTP_RX_COM_TIMESTAMP0_REG_COM_TS_DEFAULT 0x0 + +struct ptp_rx_com_timestamp0_reg { + a_uint32_t com_ts:16; +}; + +union ptp_rx_com_timestamp0_reg_u { + a_uint32_t val; + struct ptp_rx_com_timestamp0_reg bf; +}; + +/*[register] PTP_RX_COM_TIMESTAMP1_REG*/ +#define PTP_RX_COM_TIMESTAMP1_REG +#define PTP_RX_COM_TIMESTAMP1_REG_ADDRESS 0x8613 +#define PTP_RX_COM_TIMESTAMP1_REG_NUM 1 +#define PTP_RX_COM_TIMESTAMP1_REG_INC 0x1 +#define PTP_RX_COM_TIMESTAMP1_REG_TYPE REG_TYPE_RW +#define PTP_RX_COM_TIMESTAMP1_REG_DEFAULT 0x0 + /*[field] COM_TS*/ + #define PTP_RX_COM_TIMESTAMP1_REG_COM_TS + #define PTP_RX_COM_TIMESTAMP1_REG_COM_TS_OFFSET 0 + #define PTP_RX_COM_TIMESTAMP1_REG_COM_TS_LEN 16 + #define PTP_RX_COM_TIMESTAMP1_REG_COM_TS_DEFAULT 0x0 + +struct ptp_rx_com_timestamp1_reg { + a_uint32_t com_ts:16; +}; + +union ptp_rx_com_timestamp1_reg_u { + a_uint32_t val; + struct ptp_rx_com_timestamp1_reg bf; +}; + +/*[register] PTP_RX_COM_TIMESTAMP2_REG*/ +#define PTP_RX_COM_TIMESTAMP2_REG +#define PTP_RX_COM_TIMESTAMP2_REG_ADDRESS 0x8614 +#define PTP_RX_COM_TIMESTAMP2_REG_NUM 1 +#define PTP_RX_COM_TIMESTAMP2_REG_INC 0x1 +#define PTP_RX_COM_TIMESTAMP2_REG_TYPE REG_TYPE_RW +#define PTP_RX_COM_TIMESTAMP2_REG_DEFAULT 0x0 + /*[field] COM_TS*/ + #define PTP_RX_COM_TIMESTAMP2_REG_COM_TS + #define PTP_RX_COM_TIMESTAMP2_REG_COM_TS_OFFSET 0 + #define PTP_RX_COM_TIMESTAMP2_REG_COM_TS_LEN 16 + #define PTP_RX_COM_TIMESTAMP2_REG_COM_TS_DEFAULT 0x0 + +struct ptp_rx_com_timestamp2_reg { + a_uint32_t com_ts:16; +}; + +union ptp_rx_com_timestamp2_reg_u { + a_uint32_t val; + struct ptp_rx_com_timestamp2_reg bf; +}; + +/*[register] PTP_RX_COM_TIMESTAMP3_REG*/ +#define PTP_RX_COM_TIMESTAMP3_REG +#define PTP_RX_COM_TIMESTAMP3_REG_ADDRESS 0x8615 +#define PTP_RX_COM_TIMESTAMP3_REG_NUM 1 +#define PTP_RX_COM_TIMESTAMP3_REG_INC 0x1 +#define PTP_RX_COM_TIMESTAMP3_REG_TYPE REG_TYPE_RW +#define PTP_RX_COM_TIMESTAMP3_REG_DEFAULT 0x0 + /*[field] COM_TS*/ + #define PTP_RX_COM_TIMESTAMP3_REG_COM_TS + #define PTP_RX_COM_TIMESTAMP3_REG_COM_TS_OFFSET 0 + #define PTP_RX_COM_TIMESTAMP3_REG_COM_TS_LEN 16 + #define PTP_RX_COM_TIMESTAMP3_REG_COM_TS_DEFAULT 0x0 + +struct ptp_rx_com_timestamp3_reg { + a_uint32_t com_ts:16; +}; + +union ptp_rx_com_timestamp3_reg_u { + a_uint32_t val; + struct ptp_rx_com_timestamp3_reg bf; +}; + +/*[register] PTP_RX_COM_TIMESTAMP4_REG*/ +#define PTP_RX_COM_TIMESTAMP4_REG +#define PTP_RX_COM_TIMESTAMP4_REG_ADDRESS 0x8616 +#define PTP_RX_COM_TIMESTAMP4_REG_NUM 1 +#define PTP_RX_COM_TIMESTAMP4_REG_INC 0x1 +#define PTP_RX_COM_TIMESTAMP4_REG_TYPE REG_TYPE_RW +#define PTP_RX_COM_TIMESTAMP4_REG_DEFAULT 0x0 + /*[field] COM_TS*/ + #define PTP_RX_COM_TIMESTAMP4_REG_COM_TS + #define PTP_RX_COM_TIMESTAMP4_REG_COM_TS_OFFSET 0 + #define PTP_RX_COM_TIMESTAMP4_REG_COM_TS_LEN 16 + #define PTP_RX_COM_TIMESTAMP4_REG_COM_TS_DEFAULT 0x0 + +struct ptp_rx_com_timestamp4_reg { + a_uint32_t com_ts:16; +}; + +union ptp_rx_com_timestamp4_reg_u { + a_uint32_t val; + struct ptp_rx_com_timestamp4_reg bf; +}; + +/*[register] PTP_RX_COM_FRAC_NANO_REG*/ +#define PTP_RX_COM_FRAC_NANO_REG +#define PTP_RX_COM_FRAC_NANO_REG_ADDRESS 0x8617 +#define PTP_RX_COM_FRAC_NANO_REG_NUM 1 +#define PTP_RX_COM_FRAC_NANO_REG_INC 0x1 +#define PTP_RX_COM_FRAC_NANO_REG_TYPE REG_TYPE_RW +#define PTP_RX_COM_FRAC_NANO_REG_DEFAULT 0x0 + /*[field] FRAC_NANO*/ + #define PTP_RX_COM_FRAC_NANO_REG_FRAC_NANO + #define PTP_RX_COM_FRAC_NANO_REG_FRAC_NANO_OFFSET 0 + #define PTP_RX_COM_FRAC_NANO_REG_FRAC_NANO_LEN 16 + #define PTP_RX_COM_FRAC_NANO_REG_FRAC_NANO_DEFAULT 0x0 + +struct ptp_rx_com_frac_nano_reg { + a_uint32_t frac_nano:16; +}; + +union ptp_rx_com_frac_nano_reg_u { + a_uint32_t val; + struct ptp_rx_com_frac_nano_reg bf; +}; + +/*[register] PTP_RX_COM_TIMESTAMP_PRE0_REG*/ +#define PTP_RX_COM_TIMESTAMP_PRE0_REG +#define PTP_RX_COM_TIMESTAMP_PRE0_REG_ADDRESS 0x8618 +#define PTP_RX_COM_TIMESTAMP_PRE0_REG_NUM 1 +#define PTP_RX_COM_TIMESTAMP_PRE0_REG_INC 0x1 +#define PTP_RX_COM_TIMESTAMP_PRE0_REG_TYPE REG_TYPE_RW +#define PTP_RX_COM_TIMESTAMP_PRE0_REG_DEFAULT 0x0 + /*[field] COM_TS_PRE*/ + #define PTP_RX_COM_TIMESTAMP_PRE0_REG_COM_TS_PRE + #define PTP_RX_COM_TIMESTAMP_PRE0_REG_COM_TS_PRE_OFFSET 0 + #define PTP_RX_COM_TIMESTAMP_PRE0_REG_COM_TS_PRE_LEN 16 + #define PTP_RX_COM_TIMESTAMP_PRE0_REG_COM_TS_PRE_DEFAULT 0x0 + +struct ptp_rx_com_timestamp_pre0_reg { + a_uint32_t com_ts_pre:16; +}; + +union ptp_rx_com_timestamp_pre0_reg_u { + a_uint32_t val; + struct ptp_rx_com_timestamp_pre0_reg bf; +}; + +/*[register] PTP_RX_COM_TIMESTAMP_PRE1_REG*/ +#define PTP_RX_COM_TIMESTAMP_PRE1_REG +#define PTP_RX_COM_TIMESTAMP_PRE1_REG_ADDRESS 0x8619 +#define PTP_RX_COM_TIMESTAMP_PRE1_REG_NUM 1 +#define PTP_RX_COM_TIMESTAMP_PRE1_REG_INC 0x1 +#define PTP_RX_COM_TIMESTAMP_PRE1_REG_TYPE REG_TYPE_RW +#define PTP_RX_COM_TIMESTAMP_PRE1_REG_DEFAULT 0x0 + /*[field] COM_TS_PRE*/ + #define PTP_RX_COM_TIMESTAMP_PRE1_REG_COM_TS_PRE + #define PTP_RX_COM_TIMESTAMP_PRE1_REG_COM_TS_PRE_OFFSET 0 + #define PTP_RX_COM_TIMESTAMP_PRE1_REG_COM_TS_PRE_LEN 16 + #define PTP_RX_COM_TIMESTAMP_PRE1_REG_COM_TS_PRE_DEFAULT 0x0 + +struct ptp_rx_com_timestamp_pre1_reg { + a_uint32_t com_ts_pre:16; +}; + +union ptp_rx_com_timestamp_pre1_reg_u { + a_uint32_t val; + struct ptp_rx_com_timestamp_pre1_reg bf; +}; + +/*[register] PTP_RX_COM_TIMESTAMP_PRE2_REG*/ +#define PTP_RX_COM_TIMESTAMP_PRE2_REG +#define PTP_RX_COM_TIMESTAMP_PRE2_REG_ADDRESS 0x861a +#define PTP_RX_COM_TIMESTAMP_PRE2_REG_NUM 1 +#define PTP_RX_COM_TIMESTAMP_PRE2_REG_INC 0x1 +#define PTP_RX_COM_TIMESTAMP_PRE2_REG_TYPE REG_TYPE_RW +#define PTP_RX_COM_TIMESTAMP_PRE2_REG_DEFAULT 0x0 + /*[field] COM_TS_PRE*/ + #define PTP_RX_COM_TIMESTAMP_PRE2_REG_COM_TS_PRE + #define PTP_RX_COM_TIMESTAMP_PRE2_REG_COM_TS_PRE_OFFSET 0 + #define PTP_RX_COM_TIMESTAMP_PRE2_REG_COM_TS_PRE_LEN 16 + #define PTP_RX_COM_TIMESTAMP_PRE2_REG_COM_TS_PRE_DEFAULT 0x0 + +struct ptp_rx_com_timestamp_pre2_reg { + a_uint32_t com_ts_pre:16; +}; + +union ptp_rx_com_timestamp_pre2_reg_u { + a_uint32_t val; + struct ptp_rx_com_timestamp_pre2_reg bf; +}; + +/*[register] PTP_RX_COM_TIMESTAMP_PRE3_REG*/ +#define PTP_RX_COM_TIMESTAMP_PRE3_REG +#define PTP_RX_COM_TIMESTAMP_PRE3_REG_ADDRESS 0x861b +#define PTP_RX_COM_TIMESTAMP_PRE3_REG_NUM 1 +#define PTP_RX_COM_TIMESTAMP_PRE3_REG_INC 0x1 +#define PTP_RX_COM_TIMESTAMP_PRE3_REG_TYPE REG_TYPE_RW +#define PTP_RX_COM_TIMESTAMP_PRE3_REG_DEFAULT 0x0 + /*[field] COM_TS_PRE*/ + #define PTP_RX_COM_TIMESTAMP_PRE3_REG_COM_TS_PRE + #define PTP_RX_COM_TIMESTAMP_PRE3_REG_COM_TS_PRE_OFFSET 0 + #define PTP_RX_COM_TIMESTAMP_PRE3_REG_COM_TS_PRE_LEN 16 + #define PTP_RX_COM_TIMESTAMP_PRE3_REG_COM_TS_PRE_DEFAULT 0x0 + +struct ptp_rx_com_timestamp_pre3_reg { + a_uint32_t com_ts_pre:16; +}; + +union ptp_rx_com_timestamp_pre3_reg_u { + a_uint32_t val; + struct ptp_rx_com_timestamp_pre3_reg bf; +}; + +/*[register] PTP_RX_COM_TIMESTAMP_PRE4_REG*/ +#define PTP_RX_COM_TIMESTAMP_PRE4_REG +#define PTP_RX_COM_TIMESTAMP_PRE4_REG_ADDRESS 0x861c +#define PTP_RX_COM_TIMESTAMP_PRE4_REG_NUM 1 +#define PTP_RX_COM_TIMESTAMP_PRE4_REG_INC 0x1 +#define PTP_RX_COM_TIMESTAMP_PRE4_REG_TYPE REG_TYPE_RW +#define PTP_RX_COM_TIMESTAMP_PRE4_REG_DEFAULT 0x0 + /*[field] COM_TS_PRE*/ + #define PTP_RX_COM_TIMESTAMP_PRE4_REG_COM_TS_PRE + #define PTP_RX_COM_TIMESTAMP_PRE4_REG_COM_TS_PRE_OFFSET 0 + #define PTP_RX_COM_TIMESTAMP_PRE4_REG_COM_TS_PRE_LEN 16 + #define PTP_RX_COM_TIMESTAMP_PRE4_REG_COM_TS_PRE_DEFAULT 0x0 + +struct ptp_rx_com_timestamp_pre4_reg { + a_uint32_t com_ts_pre:16; +}; + +union ptp_rx_com_timestamp_pre4_reg_u { + a_uint32_t val; + struct ptp_rx_com_timestamp_pre4_reg bf; +}; + +/*[register] PTP_RX_COM_FRAC_NANO_PRE_REG*/ +#define PTP_RX_COM_FRAC_NANO_PRE_REG +#define PTP_RX_COM_FRAC_NANO_PRE_REG_ADDRESS 0x861d +#define PTP_RX_COM_FRAC_NANO_PRE_REG_NUM 1 +#define PTP_RX_COM_FRAC_NANO_PRE_REG_INC 0x1 +#define PTP_RX_COM_FRAC_NANO_PRE_REG_TYPE REG_TYPE_RW +#define PTP_RX_COM_FRAC_NANO_PRE_REG_DEFAULT 0x0 + /*[field] FRAC_NANO_PRE*/ + #define PTP_RX_COM_FRAC_NANO_PRE_REG_FRAC_NANO_PRE + #define PTP_RX_COM_FRAC_NANO_PRE_REG_FRAC_NANO_PRE_OFFSET 0 + #define PTP_RX_COM_FRAC_NANO_PRE_REG_FRAC_NANO_PRE_LEN 16 + #define PTP_RX_COM_FRAC_NANO_PRE_REG_FRAC_NANO_PRE_DEFAULT 0x0 + +struct ptp_rx_com_frac_nano_pre_reg { + a_uint32_t frac_nano_pre:16; +}; + +union ptp_rx_com_frac_nano_pre_reg_u { + a_uint32_t val; + struct ptp_rx_com_frac_nano_pre_reg bf; +}; + +/*[register] PTP_RX_Y1731_IDENTIFY_REG*/ +#define PTP_RX_Y1731_IDENTIFY_REG +#define PTP_RX_Y1731_IDENTIFY_REG_ADDRESS 0x861e +#define PTP_RX_Y1731_IDENTIFY_REG_NUM 1 +#define PTP_RX_Y1731_IDENTIFY_REG_INC 0x1 +#define PTP_RX_Y1731_IDENTIFY_REG_TYPE REG_TYPE_RW +#define PTP_RX_Y1731_IDENTIFY_REG_DEFAULT 0x0 + /*[field] IDENTIFY*/ + #define PTP_RX_Y1731_IDENTIFY_REG_IDENTIFY + #define PTP_RX_Y1731_IDENTIFY_REG_IDENTIFY_OFFSET 0 + #define PTP_RX_Y1731_IDENTIFY_REG_IDENTIFY_LEN 16 + #define PTP_RX_Y1731_IDENTIFY_REG_IDENTIFY_DEFAULT 0x0 + +struct ptp_rx_y1731_identify_reg { + a_uint32_t identify:16; +}; + +union ptp_rx_y1731_identify_reg_u { + a_uint32_t val; + struct ptp_rx_y1731_identify_reg bf; +}; + +/*[register] PTP_RX_Y1731_IDENTIFY_PRE_REG*/ +#define PTP_RX_Y1731_IDENTIFY_PRE_REG +#define PTP_RX_Y1731_IDENTIFY_PRE_REG_ADDRESS 0x861f +#define PTP_RX_Y1731_IDENTIFY_PRE_REG_NUM 1 +#define PTP_RX_Y1731_IDENTIFY_PRE_REG_INC 0x1 +#define PTP_RX_Y1731_IDENTIFY_PRE_REG_TYPE REG_TYPE_RW +#define PTP_RX_Y1731_IDENTIFY_PRE_REG_DEFAULT 0x0 + /*[field] IDENTIFY_PRE*/ + #define PTP_RX_Y1731_IDENTIFY_PRE_REG_IDENTIFY_PRE + #define PTP_RX_Y1731_IDENTIFY_PRE_REG_IDENTIFY_PRE_OFFSET 0 + #define PTP_RX_Y1731_IDENTIFY_PRE_REG_IDENTIFY_PRE_LEN 16 + #define PTP_RX_Y1731_IDENTIFY_PRE_REG_IDENTIFY_PRE_DEFAULT 0x0 + +struct ptp_rx_y1731_identify_pre_reg { + a_uint32_t identify_pre:16; +}; + +union ptp_rx_y1731_identify_pre_reg_u { + a_uint32_t val; + struct ptp_rx_y1731_identify_pre_reg bf; +}; + +/*[register] PTP_TX_COM_TS_CTRL_REG*/ +#define PTP_TX_COM_TS_CTRL_REG +#define PTP_TX_COM_TS_CTRL_REG_ADDRESS 0x8620 +#define PTP_TX_COM_TS_CTRL_REG_NUM 1 +#define PTP_TX_COM_TS_CTRL_REG_INC 0x1 +#define PTP_TX_COM_TS_CTRL_REG_TYPE REG_TYPE_RW +#define PTP_TX_COM_TS_CTRL_REG_DEFAULT 0x0 + /*[field] FILT_EN*/ + #define PTP_TX_COM_TS_CTRL_REG_FILT_EN + #define PTP_TX_COM_TS_CTRL_REG_FILT_EN_OFFSET 0 + #define PTP_TX_COM_TS_CTRL_REG_FILT_EN_LEN 1 + #define PTP_TX_COM_TS_CTRL_REG_FILT_EN_DEFAULT 0x0 + /*[field] MAC_LENGTHTYPE_EN*/ + #define PTP_TX_COM_TS_CTRL_REG_MAC_LENGTHTYPE_EN + #define PTP_TX_COM_TS_CTRL_REG_MAC_LENGTHTYPE_EN_OFFSET 1 + #define PTP_TX_COM_TS_CTRL_REG_MAC_LENGTHTYPE_EN_LEN 1 + #define PTP_TX_COM_TS_CTRL_REG_MAC_LENGTHTYPE_EN_DEFAULT 0x0 + /*[field] MAC_DA_EN*/ + #define PTP_TX_COM_TS_CTRL_REG_MAC_DA_EN + #define PTP_TX_COM_TS_CTRL_REG_MAC_DA_EN_OFFSET 2 + #define PTP_TX_COM_TS_CTRL_REG_MAC_DA_EN_LEN 1 + #define PTP_TX_COM_TS_CTRL_REG_MAC_DA_EN_DEFAULT 0x0 + /*[field] MAC_PTP_FILT_EN*/ + #define PTP_TX_COM_TS_CTRL_REG_MAC_PTP_FILT_EN + #define PTP_TX_COM_TS_CTRL_REG_MAC_PTP_FILT_EN_OFFSET 3 + #define PTP_TX_COM_TS_CTRL_REG_MAC_PTP_FILT_EN_LEN 1 + #define PTP_TX_COM_TS_CTRL_REG_MAC_PTP_FILT_EN_DEFAULT 0x0 + /*[field] IPV4_LAYER4_PROTOCOL_EN*/ + #define PTP_TX_COM_TS_CTRL_REG_IPV4_LAYER4_PROTOCOL_EN + #define PTP_TX_COM_TS_CTRL_REG_IPV4_LAYER4_PROTOCOL_EN_OFFSET 4 + #define PTP_TX_COM_TS_CTRL_REG_IPV4_LAYER4_PROTOCOL_EN_LEN 1 + #define PTP_TX_COM_TS_CTRL_REG_IPV4_LAYER4_PROTOCOL_EN_DEFAULT 0x0 + /*[field] IPV4_DA_EN*/ + #define PTP_TX_COM_TS_CTRL_REG_IPV4_DA_EN + #define PTP_TX_COM_TS_CTRL_REG_IPV4_DA_EN_OFFSET 5 + #define PTP_TX_COM_TS_CTRL_REG_IPV4_DA_EN_LEN 1 + #define PTP_TX_COM_TS_CTRL_REG_IPV4_DA_EN_DEFAULT 0x0 + /*[field] IPV4_PTP_FILT_EN*/ + #define PTP_TX_COM_TS_CTRL_REG_IPV4_PTP_FILT_EN + #define PTP_TX_COM_TS_CTRL_REG_IPV4_PTP_FILT_EN_OFFSET 6 + #define PTP_TX_COM_TS_CTRL_REG_IPV4_PTP_FILT_EN_LEN 1 + #define PTP_TX_COM_TS_CTRL_REG_IPV4_PTP_FILT_EN_DEFAULT 0x0 + /*[field] IPV6_NEXT_HEADER_EN*/ + #define PTP_TX_COM_TS_CTRL_REG_IPV6_NEXT_HEADER_EN + #define PTP_TX_COM_TS_CTRL_REG_IPV6_NEXT_HEADER_EN_OFFSET 7 + #define PTP_TX_COM_TS_CTRL_REG_IPV6_NEXT_HEADER_EN_LEN 1 + #define PTP_TX_COM_TS_CTRL_REG_IPV6_NEXT_HEADER_EN_DEFAULT 0x0 + /*[field] IPV6_DA_EN*/ + #define PTP_TX_COM_TS_CTRL_REG_IPV6_DA_EN + #define PTP_TX_COM_TS_CTRL_REG_IPV6_DA_EN_OFFSET 8 + #define PTP_TX_COM_TS_CTRL_REG_IPV6_DA_EN_LEN 1 + #define PTP_TX_COM_TS_CTRL_REG_IPV6_DA_EN_DEFAULT 0x0 + /*[field] IPV6_PTP_FILT_EN*/ + #define PTP_TX_COM_TS_CTRL_REG_IPV6_PTP_FILT_EN + #define PTP_TX_COM_TS_CTRL_REG_IPV6_PTP_FILT_EN_OFFSET 9 + #define PTP_TX_COM_TS_CTRL_REG_IPV6_PTP_FILT_EN_LEN 1 + #define PTP_TX_COM_TS_CTRL_REG_IPV6_PTP_FILT_EN_DEFAULT 0x0 + /*[field] UDP_DPORT_EN*/ + #define PTP_TX_COM_TS_CTRL_REG_UDP_DPORT_EN + #define PTP_TX_COM_TS_CTRL_REG_UDP_DPORT_EN_OFFSET 10 + #define PTP_TX_COM_TS_CTRL_REG_UDP_DPORT_EN_LEN 1 + #define PTP_TX_COM_TS_CTRL_REG_UDP_DPORT_EN_DEFAULT 0x0 + /*[field] UDP_PTP_EVENT_FILT_EN*/ + #define PTP_TX_COM_TS_CTRL_REG_UDP_PTP_EVENT_FILT_EN + #define PTP_TX_COM_TS_CTRL_REG_UDP_PTP_EVENT_FILT_EN_OFFSET 11 + #define PTP_TX_COM_TS_CTRL_REG_UDP_PTP_EVENT_FILT_EN_LEN 1 + #define PTP_TX_COM_TS_CTRL_REG_UDP_PTP_EVENT_FILT_EN_DEFAULT 0x0 + /*[field] Y1731_EN*/ + #define PTP_TX_COM_TS_CTRL_REG_Y1731_EN + #define PTP_TX_COM_TS_CTRL_REG_Y1731_EN_OFFSET 12 + #define PTP_TX_COM_TS_CTRL_REG_Y1731_EN_LEN 1 + #define PTP_TX_COM_TS_CTRL_REG_Y1731_EN_DEFAULT 0x0 + /*[field] Y1731_INSERT_TS_EN*/ + #define PTP_TX_COM_TS_CTRL_REG_Y1731_INSERT_TS_EN + #define PTP_TX_COM_TS_CTRL_REG_Y1731_INSERT_TS_EN_OFFSET 13 + #define PTP_TX_COM_TS_CTRL_REG_Y1731_INSERT_TS_EN_LEN 1 + #define PTP_TX_COM_TS_CTRL_REG_Y1731_INSERT_TS_EN_DEFAULT 0x0 + /*[field] Y1731_SA_CHK_EN*/ + #define PTP_TX_COM_TS_CTRL_REG_Y1731_SA_CHK_EN + #define PTP_TX_COM_TS_CTRL_REG_Y1731_SA_CHK_EN_OFFSET 14 + #define PTP_TX_COM_TS_CTRL_REG_Y1731_SA_CHK_EN_LEN 1 + #define PTP_TX_COM_TS_CTRL_REG_Y1731_SA_CHK_EN_DEFAULT 0x0 + /*[field] PW_MAC_EN*/ + #define PTP_TX_COM_TS_CTRL_REG_PW_MAC_EN + #define PTP_TX_COM_TS_CTRL_REG_PW_MAC_EN_OFFSET 15 + #define PTP_TX_COM_TS_CTRL_REG_PW_MAC_EN_LEN 1 + #define PTP_TX_COM_TS_CTRL_REG_PW_MAC_EN_DEFAULT 0x0 + +struct ptp_tx_com_ts_ctrl_reg { + a_uint32_t filt_en:1; + a_uint32_t mac_lengthtype_en:1; + a_uint32_t mac_da_en:1; + a_uint32_t mac_ptp_filt_en:1; + a_uint32_t ipv4_layer4_protocol_en:1; + a_uint32_t ipv4_da_en:1; + a_uint32_t ipv4_ptp_filt_en:1; + a_uint32_t ipv6_next_header_en:1; + a_uint32_t ipv6_da_en:1; + a_uint32_t ipv6_ptp_filt_en:1; + a_uint32_t udp_dport_en:1; + a_uint32_t udp_ptp_event_filt_en:1; + a_uint32_t y1731_en:1; + a_uint32_t y1731_insert_ts_en:1; + a_uint32_t y1731_sa_chk_en:1; + a_uint32_t pw_mac_en:1; +}; + +union ptp_tx_com_ts_ctrl_reg_u { + a_uint32_t val; + struct ptp_tx_com_ts_ctrl_reg bf; +}; + +/*[register] PTP_TX_FILT_MAC_DA0_REG*/ +#define PTP_TX_FILT_MAC_DA0_REG +#define PTP_TX_FILT_MAC_DA0_REG_ADDRESS 0x8621 +#define PTP_TX_FILT_MAC_DA0_REG_NUM 1 +#define PTP_TX_FILT_MAC_DA0_REG_INC 0x1 +#define PTP_TX_FILT_MAC_DA0_REG_TYPE REG_TYPE_RW +#define PTP_TX_FILT_MAC_DA0_REG_DEFAULT 0x0 + /*[field] MAC_ADDR*/ + #define PTP_TX_FILT_MAC_DA0_REG_MAC_ADDR + #define PTP_TX_FILT_MAC_DA0_REG_MAC_ADDR_OFFSET 0 + #define PTP_TX_FILT_MAC_DA0_REG_MAC_ADDR_LEN 16 + #define PTP_TX_FILT_MAC_DA0_REG_MAC_ADDR_DEFAULT 0x0 + +struct ptp_tx_filt_mac_da0_reg { + a_uint32_t mac_addr:16; +}; + +union ptp_tx_filt_mac_da0_reg_u { + a_uint32_t val; + struct ptp_tx_filt_mac_da0_reg bf; +}; + +/*[register] PTP_TX_FILT_MAC_DA1_REG*/ +#define PTP_TX_FILT_MAC_DA1_REG +#define PTP_TX_FILT_MAC_DA1_REG_ADDRESS 0x8622 +#define PTP_TX_FILT_MAC_DA1_REG_NUM 1 +#define PTP_TX_FILT_MAC_DA1_REG_INC 0x1 +#define PTP_TX_FILT_MAC_DA1_REG_TYPE REG_TYPE_RW +#define PTP_TX_FILT_MAC_DA1_REG_DEFAULT 0x0 + /*[field] MAC_ADDR*/ + #define PTP_TX_FILT_MAC_DA1_REG_MAC_ADDR + #define PTP_TX_FILT_MAC_DA1_REG_MAC_ADDR_OFFSET 0 + #define PTP_TX_FILT_MAC_DA1_REG_MAC_ADDR_LEN 16 + #define PTP_TX_FILT_MAC_DA1_REG_MAC_ADDR_DEFAULT 0x0 + +struct ptp_tx_filt_mac_da1_reg { + a_uint32_t mac_addr:16; +}; + +union ptp_tx_filt_mac_da1_reg_u { + a_uint32_t val; + struct ptp_tx_filt_mac_da1_reg bf; +}; + +/*[register] PTP_TX_FILT_MAC_DA2_REG*/ +#define PTP_TX_FILT_MAC_DA2_REG +#define PTP_TX_FILT_MAC_DA2_REG_ADDRESS 0x8623 +#define PTP_TX_FILT_MAC_DA2_REG_NUM 1 +#define PTP_TX_FILT_MAC_DA2_REG_INC 0x1 +#define PTP_TX_FILT_MAC_DA2_REG_TYPE REG_TYPE_RW +#define PTP_TX_FILT_MAC_DA2_REG_DEFAULT 0x0 + /*[field] MAC_ADDR*/ + #define PTP_TX_FILT_MAC_DA2_REG_MAC_ADDR + #define PTP_TX_FILT_MAC_DA2_REG_MAC_ADDR_OFFSET 0 + #define PTP_TX_FILT_MAC_DA2_REG_MAC_ADDR_LEN 16 + #define PTP_TX_FILT_MAC_DA2_REG_MAC_ADDR_DEFAULT 0x0 + +struct ptp_tx_filt_mac_da2_reg { + a_uint32_t mac_addr:16; +}; + +union ptp_tx_filt_mac_da2_reg_u { + a_uint32_t val; + struct ptp_tx_filt_mac_da2_reg bf; +}; + +/*[register] PTP_TX_FILT_IPV4_DA0_REG*/ +#define PTP_TX_FILT_IPV4_DA0_REG +#define PTP_TX_FILT_IPV4_DA0_REG_ADDRESS 0x8624 +#define PTP_TX_FILT_IPV4_DA0_REG_NUM 1 +#define PTP_TX_FILT_IPV4_DA0_REG_INC 0x1 +#define PTP_TX_FILT_IPV4_DA0_REG_TYPE REG_TYPE_RW +#define PTP_TX_FILT_IPV4_DA0_REG_DEFAULT 0x0 + /*[field] IP_ADDR*/ + #define PTP_TX_FILT_IPV4_DA0_REG_IP_ADDR + #define PTP_TX_FILT_IPV4_DA0_REG_IP_ADDR_OFFSET 0 + #define PTP_TX_FILT_IPV4_DA0_REG_IP_ADDR_LEN 16 + #define PTP_TX_FILT_IPV4_DA0_REG_IP_ADDR_DEFAULT 0x0 + +struct ptp_tx_filt_ipv4_da0_reg { + a_uint32_t ip_addr:16; +}; + +union ptp_tx_filt_ipv4_da0_reg_u { + a_uint32_t val; + struct ptp_tx_filt_ipv4_da0_reg bf; +}; + +/*[register] PTP_TX_FILT_IPV4_DA1_REG*/ +#define PTP_TX_FILT_IPV4_DA1_REG +#define PTP_TX_FILT_IPV4_DA1_REG_ADDRESS 0x8625 +#define PTP_TX_FILT_IPV4_DA1_REG_NUM 1 +#define PTP_TX_FILT_IPV4_DA1_REG_INC 0x1 +#define PTP_TX_FILT_IPV4_DA1_REG_TYPE REG_TYPE_RW +#define PTP_TX_FILT_IPV4_DA1_REG_DEFAULT 0x0 + /*[field] IP_ADDR*/ + #define PTP_TX_FILT_IPV4_DA1_REG_IP_ADDR + #define PTP_TX_FILT_IPV4_DA1_REG_IP_ADDR_OFFSET 0 + #define PTP_TX_FILT_IPV4_DA1_REG_IP_ADDR_LEN 16 + #define PTP_TX_FILT_IPV4_DA1_REG_IP_ADDR_DEFAULT 0x0 + +struct ptp_tx_filt_ipv4_da1_reg { + a_uint32_t ip_addr:16; +}; + +union ptp_tx_filt_ipv4_da1_reg_u { + a_uint32_t val; + struct ptp_tx_filt_ipv4_da1_reg bf; +}; + +/*[register] PTP_TX_FILT_IPV6_DA0_REG*/ +#define PTP_TX_FILT_IPV6_DA0_REG +#define PTP_TX_FILT_IPV6_DA0_REG_ADDRESS 0x8626 +#define PTP_TX_FILT_IPV6_DA0_REG_NUM 1 +#define PTP_TX_FILT_IPV6_DA0_REG_INC 0x1 +#define PTP_TX_FILT_IPV6_DA0_REG_TYPE REG_TYPE_RW +#define PTP_TX_FILT_IPV6_DA0_REG_DEFAULT 0x0 + /*[field] IP_ADDR*/ + #define PTP_TX_FILT_IPV6_DA0_REG_IP_ADDR + #define PTP_TX_FILT_IPV6_DA0_REG_IP_ADDR_OFFSET 0 + #define PTP_TX_FILT_IPV6_DA0_REG_IP_ADDR_LEN 16 + #define PTP_TX_FILT_IPV6_DA0_REG_IP_ADDR_DEFAULT 0x0 + +struct ptp_tx_filt_ipv6_da0_reg { + a_uint32_t ip_addr:16; +}; + +union ptp_tx_filt_ipv6_da0_reg_u { + a_uint32_t val; + struct ptp_tx_filt_ipv6_da0_reg bf; +}; + +/*[register] PTP_TX_FILT_IPV6_DA1_REG*/ +#define PTP_TX_FILT_IPV6_DA1_REG +#define PTP_TX_FILT_IPV6_DA1_REG_ADDRESS 0x8627 +#define PTP_TX_FILT_IPV6_DA1_REG_NUM 1 +#define PTP_TX_FILT_IPV6_DA1_REG_INC 0x1 +#define PTP_TX_FILT_IPV6_DA1_REG_TYPE REG_TYPE_RW +#define PTP_TX_FILT_IPV6_DA1_REG_DEFAULT 0x0 + /*[field] IP_ADDR*/ + #define PTP_TX_FILT_IPV6_DA1_REG_IP_ADDR + #define PTP_TX_FILT_IPV6_DA1_REG_IP_ADDR_OFFSET 0 + #define PTP_TX_FILT_IPV6_DA1_REG_IP_ADDR_LEN 16 + #define PTP_TX_FILT_IPV6_DA1_REG_IP_ADDR_DEFAULT 0x0 + +struct ptp_tx_filt_ipv6_da1_reg { + a_uint32_t ip_addr:16; +}; + +union ptp_tx_filt_ipv6_da1_reg_u { + a_uint32_t val; + struct ptp_tx_filt_ipv6_da1_reg bf; +}; + +/*[register] PTP_TX_FILT_IPV6_DA2_REG*/ +#define PTP_TX_FILT_IPV6_DA2_REG +#define PTP_TX_FILT_IPV6_DA2_REG_ADDRESS 0x8628 +#define PTP_TX_FILT_IPV6_DA2_REG_NUM 1 +#define PTP_TX_FILT_IPV6_DA2_REG_INC 0x1 +#define PTP_TX_FILT_IPV6_DA2_REG_TYPE REG_TYPE_RW +#define PTP_TX_FILT_IPV6_DA2_REG_DEFAULT 0x0 + /*[field] IP_ADDR*/ + #define PTP_TX_FILT_IPV6_DA2_REG_IP_ADDR + #define PTP_TX_FILT_IPV6_DA2_REG_IP_ADDR_OFFSET 0 + #define PTP_TX_FILT_IPV6_DA2_REG_IP_ADDR_LEN 16 + #define PTP_TX_FILT_IPV6_DA2_REG_IP_ADDR_DEFAULT 0x0 + +struct ptp_tx_filt_ipv6_da2_reg { + a_uint32_t ip_addr:16; +}; + +union ptp_tx_filt_ipv6_da2_reg_u { + a_uint32_t val; + struct ptp_tx_filt_ipv6_da2_reg bf; +}; + +/*[register] PTP_TX_FILT_IPV6_DA3_REG*/ +#define PTP_TX_FILT_IPV6_DA3_REG +#define PTP_TX_FILT_IPV6_DA3_REG_ADDRESS 0x8629 +#define PTP_TX_FILT_IPV6_DA3_REG_NUM 1 +#define PTP_TX_FILT_IPV6_DA3_REG_INC 0x1 +#define PTP_TX_FILT_IPV6_DA3_REG_TYPE REG_TYPE_RW +#define PTP_TX_FILT_IPV6_DA3_REG_DEFAULT 0x0 + /*[field] IP_ADDR*/ + #define PTP_TX_FILT_IPV6_DA3_REG_IP_ADDR + #define PTP_TX_FILT_IPV6_DA3_REG_IP_ADDR_OFFSET 0 + #define PTP_TX_FILT_IPV6_DA3_REG_IP_ADDR_LEN 16 + #define PTP_TX_FILT_IPV6_DA3_REG_IP_ADDR_DEFAULT 0x0 + +struct ptp_tx_filt_ipv6_da3_reg { + a_uint32_t ip_addr:16; +}; + +union ptp_tx_filt_ipv6_da3_reg_u { + a_uint32_t val; + struct ptp_tx_filt_ipv6_da3_reg bf; +}; + +/*[register] PTP_TX_FILT_IPV6_DA4_REG*/ +#define PTP_TX_FILT_IPV6_DA4_REG +#define PTP_TX_FILT_IPV6_DA4_REG_ADDRESS 0x862a +#define PTP_TX_FILT_IPV6_DA4_REG_NUM 1 +#define PTP_TX_FILT_IPV6_DA4_REG_INC 0x1 +#define PTP_TX_FILT_IPV6_DA4_REG_TYPE REG_TYPE_RW +#define PTP_TX_FILT_IPV6_DA4_REG_DEFAULT 0x0 + /*[field] IP_ADDR*/ + #define PTP_TX_FILT_IPV6_DA4_REG_IP_ADDR + #define PTP_TX_FILT_IPV6_DA4_REG_IP_ADDR_OFFSET 0 + #define PTP_TX_FILT_IPV6_DA4_REG_IP_ADDR_LEN 16 + #define PTP_TX_FILT_IPV6_DA4_REG_IP_ADDR_DEFAULT 0x0 + +struct ptp_tx_filt_ipv6_da4_reg { + a_uint32_t ip_addr:16; +}; + +union ptp_tx_filt_ipv6_da4_reg_u { + a_uint32_t val; + struct ptp_tx_filt_ipv6_da4_reg bf; +}; + +/*[register] PTP_TX_FILT_IPV6_DA5_REG*/ +#define PTP_TX_FILT_IPV6_DA5_REG +#define PTP_TX_FILT_IPV6_DA5_REG_ADDRESS 0x862b +#define PTP_TX_FILT_IPV6_DA5_REG_NUM 1 +#define PTP_TX_FILT_IPV6_DA5_REG_INC 0x1 +#define PTP_TX_FILT_IPV6_DA5_REG_TYPE REG_TYPE_RW +#define PTP_TX_FILT_IPV6_DA5_REG_DEFAULT 0x0 + /*[field] IP_ADDR*/ + #define PTP_TX_FILT_IPV6_DA5_REG_IP_ADDR + #define PTP_TX_FILT_IPV6_DA5_REG_IP_ADDR_OFFSET 0 + #define PTP_TX_FILT_IPV6_DA5_REG_IP_ADDR_LEN 16 + #define PTP_TX_FILT_IPV6_DA5_REG_IP_ADDR_DEFAULT 0x0 + +struct ptp_tx_filt_ipv6_da5_reg { + a_uint32_t ip_addr:16; +}; + +union ptp_tx_filt_ipv6_da5_reg_u { + a_uint32_t val; + struct ptp_tx_filt_ipv6_da5_reg bf; +}; + +/*[register] PTP_TX_FILT_IPV6_DA6_REG*/ +#define PTP_TX_FILT_IPV6_DA6_REG +#define PTP_TX_FILT_IPV6_DA6_REG_ADDRESS 0x862c +#define PTP_TX_FILT_IPV6_DA6_REG_NUM 1 +#define PTP_TX_FILT_IPV6_DA6_REG_INC 0x1 +#define PTP_TX_FILT_IPV6_DA6_REG_TYPE REG_TYPE_RW +#define PTP_TX_FILT_IPV6_DA6_REG_DEFAULT 0x0 + /*[field] IP_ADDR*/ + #define PTP_TX_FILT_IPV6_DA6_REG_IP_ADDR + #define PTP_TX_FILT_IPV6_DA6_REG_IP_ADDR_OFFSET 0 + #define PTP_TX_FILT_IPV6_DA6_REG_IP_ADDR_LEN 16 + #define PTP_TX_FILT_IPV6_DA6_REG_IP_ADDR_DEFAULT 0x0 + +struct ptp_tx_filt_ipv6_da6_reg { + a_uint32_t ip_addr:16; +}; + +union ptp_tx_filt_ipv6_da6_reg_u { + a_uint32_t val; + struct ptp_tx_filt_ipv6_da6_reg bf; +}; + +/*[register] PTP_TX_FILT_IPV6_DA7_REG*/ +#define PTP_TX_FILT_IPV6_DA7_REG +#define PTP_TX_FILT_IPV6_DA7_REG_ADDRESS 0x862d +#define PTP_TX_FILT_IPV6_DA7_REG_NUM 1 +#define PTP_TX_FILT_IPV6_DA7_REG_INC 0x1 +#define PTP_TX_FILT_IPV6_DA7_REG_TYPE REG_TYPE_RW +#define PTP_TX_FILT_IPV6_DA7_REG_DEFAULT 0x0 + /*[field] IP_ADDR*/ + #define PTP_TX_FILT_IPV6_DA7_REG_IP_ADDR + #define PTP_TX_FILT_IPV6_DA7_REG_IP_ADDR_OFFSET 0 + #define PTP_TX_FILT_IPV6_DA7_REG_IP_ADDR_LEN 16 + #define PTP_TX_FILT_IPV6_DA7_REG_IP_ADDR_DEFAULT 0x0 + +struct ptp_tx_filt_ipv6_da7_reg { + a_uint32_t ip_addr:16; +}; + +union ptp_tx_filt_ipv6_da7_reg_u { + a_uint32_t val; + struct ptp_tx_filt_ipv6_da7_reg bf; +}; + +/*[register] PTP_TX_FILT_MAC_LENGTHTYPE_REG*/ +#define PTP_TX_FILT_MAC_LENGTHTYPE_REG +#define PTP_TX_FILT_MAC_LENGTHTYPE_REG_ADDRESS 0x862e +#define PTP_TX_FILT_MAC_LENGTHTYPE_REG_NUM 1 +#define PTP_TX_FILT_MAC_LENGTHTYPE_REG_INC 0x1 +#define PTP_TX_FILT_MAC_LENGTHTYPE_REG_TYPE REG_TYPE_RW +#define PTP_TX_FILT_MAC_LENGTHTYPE_REG_DEFAULT 0x0 + /*[field] LENGTH_TYPE*/ + #define PTP_TX_FILT_MAC_LENGTHTYPE_REG_LENGTH_TYPE + #define PTP_TX_FILT_MAC_LENGTHTYPE_REG_LENGTH_TYPE_OFFSET 0 + #define PTP_TX_FILT_MAC_LENGTHTYPE_REG_LENGTH_TYPE_LEN 16 + #define PTP_TX_FILT_MAC_LENGTHTYPE_REG_LENGTH_TYPE_DEFAULT 0x0 + +struct ptp_tx_filt_mac_lengthtype_reg { + a_uint32_t length_type:16; +}; + +union ptp_tx_filt_mac_lengthtype_reg_u { + a_uint32_t val; + struct ptp_tx_filt_mac_lengthtype_reg bf; +}; + +/*[register] PTP_TX_FILT_LAYER4_PROTOCOL_REG*/ +#define PTP_TX_FILT_LAYER4_PROTOCOL_REG +#define PTP_TX_FILT_LAYER4_PROTOCOL_REG_ADDRESS 0x862f +#define PTP_TX_FILT_LAYER4_PROTOCOL_REG_NUM 1 +#define PTP_TX_FILT_LAYER4_PROTOCOL_REG_INC 0x1 +#define PTP_TX_FILT_LAYER4_PROTOCOL_REG_TYPE REG_TYPE_RW +#define PTP_TX_FILT_LAYER4_PROTOCOL_REG_DEFAULT 0x0 + /*[field] L4_PROTOCOL*/ + #define PTP_TX_FILT_LAYER4_PROTOCOL_REG_L4_PROTOCOL + #define PTP_TX_FILT_LAYER4_PROTOCOL_REG_L4_PROTOCOL_OFFSET 0 + #define PTP_TX_FILT_LAYER4_PROTOCOL_REG_L4_PROTOCOL_LEN 16 + #define PTP_TX_FILT_LAYER4_PROTOCOL_REG_L4_PROTOCOL_DEFAULT 0x0 + +struct ptp_tx_filt_layer4_protocol_reg { + a_uint32_t l4_protocol:16; +}; + +union ptp_tx_filt_layer4_protocol_reg_u { + a_uint32_t val; + struct ptp_tx_filt_layer4_protocol_reg bf; +}; + +/*[register] PTP_TX_FILT_UDP_PORT_REG*/ +#define PTP_TX_FILT_UDP_PORT_REG +#define PTP_TX_FILT_UDP_PORT_REG_ADDRESS 0x8630 +#define PTP_TX_FILT_UDP_PORT_REG_NUM 1 +#define PTP_TX_FILT_UDP_PORT_REG_INC 0x1 +#define PTP_TX_FILT_UDP_PORT_REG_TYPE REG_TYPE_RW +#define PTP_TX_FILT_UDP_PORT_REG_DEFAULT 0x0 + /*[field] UDP_PORT*/ + #define PTP_TX_FILT_UDP_PORT_REG_UDP_PORT + #define PTP_TX_FILT_UDP_PORT_REG_UDP_PORT_OFFSET 0 + #define PTP_TX_FILT_UDP_PORT_REG_UDP_PORT_LEN 16 + #define PTP_TX_FILT_UDP_PORT_REG_UDP_PORT_DEFAULT 0x0 + +struct ptp_tx_filt_udp_port_reg { + a_uint32_t udp_port:16; +}; + +union ptp_tx_filt_udp_port_reg_u { + a_uint32_t val; + struct ptp_tx_filt_udp_port_reg bf; +}; + +/*[register] PTP_TX_COM_TS_STATUS_REG*/ +#define PTP_TX_COM_TS_STATUS_REG +#define PTP_TX_COM_TS_STATUS_REG_ADDRESS 0x8631 +#define PTP_TX_COM_TS_STATUS_REG_NUM 1 +#define PTP_TX_COM_TS_STATUS_REG_INC 0x1 +#define PTP_TX_COM_TS_STATUS_REG_TYPE REG_TYPE_RW +#define PTP_TX_COM_TS_STATUS_REG_DEFAULT 0x0 + /*[field] MAC_LENGTHTYPE*/ + #define PTP_TX_COM_TS_STATUS_REG_MAC_LENGTHTYPE + #define PTP_TX_COM_TS_STATUS_REG_MAC_LENGTHTYPE_OFFSET 0 + #define PTP_TX_COM_TS_STATUS_REG_MAC_LENGTHTYPE_LEN 1 + #define PTP_TX_COM_TS_STATUS_REG_MAC_LENGTHTYPE_DEFAULT 0x0 + /*[field] MAC_DA*/ + #define PTP_TX_COM_TS_STATUS_REG_MAC_DA + #define PTP_TX_COM_TS_STATUS_REG_MAC_DA_OFFSET 1 + #define PTP_TX_COM_TS_STATUS_REG_MAC_DA_LEN 1 + #define PTP_TX_COM_TS_STATUS_REG_MAC_DA_DEFAULT 0x0 + /*[field] MAC_PTP_PRIM_ADDR*/ + #define PTP_TX_COM_TS_STATUS_REG_MAC_PTP_PRIM_ADDR + #define PTP_TX_COM_TS_STATUS_REG_MAC_PTP_PRIM_ADDR_OFFSET 2 + #define PTP_TX_COM_TS_STATUS_REG_MAC_PTP_PRIM_ADDR_LEN 1 + #define PTP_TX_COM_TS_STATUS_REG_MAC_PTP_PRIM_ADDR_DEFAULT 0x0 + /*[field] MAC_PTP_PDELAY_ADDR*/ + #define PTP_TX_COM_TS_STATUS_REG_MAC_PTP_PDELAY_ADDR + #define PTP_TX_COM_TS_STATUS_REG_MAC_PTP_PDELAY_ADDR_OFFSET 3 + #define PTP_TX_COM_TS_STATUS_REG_MAC_PTP_PDELAY_ADDR_LEN 1 + #define PTP_TX_COM_TS_STATUS_REG_MAC_PTP_PDELAY_ADDR_DEFAULT 0x0 + /*[field] IPV4_LAYER4_PROTOCOL*/ + #define PTP_TX_COM_TS_STATUS_REG_IPV4_LAYER4_PROTOCOL + #define PTP_TX_COM_TS_STATUS_REG_IPV4_LAYER4_PROTOCOL_OFFSET 4 + #define PTP_TX_COM_TS_STATUS_REG_IPV4_LAYER4_PROTOCOL_LEN 1 + #define PTP_TX_COM_TS_STATUS_REG_IPV4_LAYER4_PROTOCOL_DEFAULT 0x0 + /*[field] IPV4_DA*/ + #define PTP_TX_COM_TS_STATUS_REG_IPV4_DA + #define PTP_TX_COM_TS_STATUS_REG_IPV4_DA_OFFSET 5 + #define PTP_TX_COM_TS_STATUS_REG_IPV4_DA_LEN 1 + #define PTP_TX_COM_TS_STATUS_REG_IPV4_DA_DEFAULT 0x0 + /*[field] IPV4_PTP_PRIM_ADDR*/ + #define PTP_TX_COM_TS_STATUS_REG_IPV4_PTP_PRIM_ADDR + #define PTP_TX_COM_TS_STATUS_REG_IPV4_PTP_PRIM_ADDR_OFFSET 6 + #define PTP_TX_COM_TS_STATUS_REG_IPV4_PTP_PRIM_ADDR_LEN 1 + #define PTP_TX_COM_TS_STATUS_REG_IPV4_PTP_PRIM_ADDR_DEFAULT 0x0 + /*[field] IPV4_PTP_PDELAY_ADDR*/ + #define PTP_TX_COM_TS_STATUS_REG_IPV4_PTP_PDELAY_ADDR + #define PTP_TX_COM_TS_STATUS_REG_IPV4_PTP_PDELAY_ADDR_OFFSET 7 + #define PTP_TX_COM_TS_STATUS_REG_IPV4_PTP_PDELAY_ADDR_LEN 1 + #define PTP_TX_COM_TS_STATUS_REG_IPV4_PTP_PDELAY_ADDR_DEFAULT 0x0 + /*[field] IPV6_NEXT_HEADER*/ + #define PTP_TX_COM_TS_STATUS_REG_IPV6_NEXT_HEADER + #define PTP_TX_COM_TS_STATUS_REG_IPV6_NEXT_HEADER_OFFSET 8 + #define PTP_TX_COM_TS_STATUS_REG_IPV6_NEXT_HEADER_LEN 1 + #define PTP_TX_COM_TS_STATUS_REG_IPV6_NEXT_HEADER_DEFAULT 0x0 + /*[field] IPV6_DA*/ + #define PTP_TX_COM_TS_STATUS_REG_IPV6_DA + #define PTP_TX_COM_TS_STATUS_REG_IPV6_DA_OFFSET 9 + #define PTP_TX_COM_TS_STATUS_REG_IPV6_DA_LEN 1 + #define PTP_TX_COM_TS_STATUS_REG_IPV6_DA_DEFAULT 0x0 + /*[field] IPV6_PTP_PRIM_ADDR*/ + #define PTP_TX_COM_TS_STATUS_REG_IPV6_PTP_PRIM_ADDR + #define PTP_TX_COM_TS_STATUS_REG_IPV6_PTP_PRIM_ADDR_OFFSET 10 + #define PTP_TX_COM_TS_STATUS_REG_IPV6_PTP_PRIM_ADDR_LEN 1 + #define PTP_TX_COM_TS_STATUS_REG_IPV6_PTP_PRIM_ADDR_DEFAULT 0x0 + /*[field] IPV6_PTP_PDELAY_ADDR*/ + #define PTP_TX_COM_TS_STATUS_REG_IPV6_PTP_PDELAY_ADDR + #define PTP_TX_COM_TS_STATUS_REG_IPV6_PTP_PDELAY_ADDR_OFFSET 11 + #define PTP_TX_COM_TS_STATUS_REG_IPV6_PTP_PDELAY_ADDR_LEN 1 + #define PTP_TX_COM_TS_STATUS_REG_IPV6_PTP_PDELAY_ADDR_DEFAULT 0x0 + /*[field] UDP_DPORT*/ + #define PTP_TX_COM_TS_STATUS_REG_UDP_DPORT + #define PTP_TX_COM_TS_STATUS_REG_UDP_DPORT_OFFSET 12 + #define PTP_TX_COM_TS_STATUS_REG_UDP_DPORT_LEN 1 + #define PTP_TX_COM_TS_STATUS_REG_UDP_DPORT_DEFAULT 0x0 + /*[field] UDP_PTP_EVENT_DPORT*/ + #define PTP_TX_COM_TS_STATUS_REG_UDP_PTP_EVENT_DPORT + #define PTP_TX_COM_TS_STATUS_REG_UDP_PTP_EVENT_DPORT_OFFSET 13 + #define PTP_TX_COM_TS_STATUS_REG_UDP_PTP_EVENT_DPORT_LEN 1 + #define PTP_TX_COM_TS_STATUS_REG_UDP_PTP_EVENT_DPORT_DEFAULT 0x0 + /*[field] Y1731_MACH*/ + #define PTP_TX_COM_TS_STATUS_REG_Y1731_MACH + #define PTP_TX_COM_TS_STATUS_REG_Y1731_MACH_OFFSET 14 + #define PTP_TX_COM_TS_STATUS_REG_Y1731_MACH_LEN 1 + #define PTP_TX_COM_TS_STATUS_REG_Y1731_MACH_DEFAULT 0x0 + +struct ptp_tx_com_ts_status_reg { + a_uint32_t mac_lengthtype:1; + a_uint32_t mac_da:1; + a_uint32_t mac_ptp_prim_addr:1; + a_uint32_t mac_ptp_pdelay_addr:1; + a_uint32_t ipv4_layer4_protocol:1; + a_uint32_t ipv4_da:1; + a_uint32_t ipv4_ptp_prim_addr:1; + a_uint32_t ipv4_ptp_pdelay_addr:1; + a_uint32_t ipv6_next_header:1; + a_uint32_t ipv6_da:1; + a_uint32_t ipv6_ptp_prim_addr:1; + a_uint32_t ipv6_ptp_pdelay_addr:1; + a_uint32_t udp_dport:1; + a_uint32_t udp_ptp_event_dport:1; + a_uint32_t y1731_mach:1; +}; + +union ptp_tx_com_ts_status_reg_u { + a_uint32_t val; + struct ptp_tx_com_ts_status_reg bf; +}; + +/*[register] PTP_TX_COM_TIMESTAMP0_REG*/ +#define PTP_TX_COM_TIMESTAMP0_REG +#define PTP_TX_COM_TIMESTAMP0_REG_ADDRESS 0x8632 +#define PTP_TX_COM_TIMESTAMP0_REG_NUM 1 +#define PTP_TX_COM_TIMESTAMP0_REG_INC 0x1 +#define PTP_TX_COM_TIMESTAMP0_REG_TYPE REG_TYPE_RW +#define PTP_TX_COM_TIMESTAMP0_REG_DEFAULT 0x0 + /*[field] COM_TS*/ + #define PTP_TX_COM_TIMESTAMP0_REG_COM_TS + #define PTP_TX_COM_TIMESTAMP0_REG_COM_TS_OFFSET 0 + #define PTP_TX_COM_TIMESTAMP0_REG_COM_TS_LEN 16 + #define PTP_TX_COM_TIMESTAMP0_REG_COM_TS_DEFAULT 0x0 + +struct ptp_tx_com_timestamp0_reg { + a_uint32_t com_ts:16; +}; + +union ptp_tx_com_timestamp0_reg_u { + a_uint32_t val; + struct ptp_tx_com_timestamp0_reg bf; +}; + +/*[register] PTP_TX_COM_TIMESTAMP1_REG*/ +#define PTP_TX_COM_TIMESTAMP1_REG +#define PTP_TX_COM_TIMESTAMP1_REG_ADDRESS 0x8633 +#define PTP_TX_COM_TIMESTAMP1_REG_NUM 1 +#define PTP_TX_COM_TIMESTAMP1_REG_INC 0x1 +#define PTP_TX_COM_TIMESTAMP1_REG_TYPE REG_TYPE_RW +#define PTP_TX_COM_TIMESTAMP1_REG_DEFAULT 0x0 + /*[field] COM_TS*/ + #define PTP_TX_COM_TIMESTAMP1_REG_COM_TS + #define PTP_TX_COM_TIMESTAMP1_REG_COM_TS_OFFSET 0 + #define PTP_TX_COM_TIMESTAMP1_REG_COM_TS_LEN 16 + #define PTP_TX_COM_TIMESTAMP1_REG_COM_TS_DEFAULT 0x0 + +struct ptp_tx_com_timestamp1_reg { + a_uint32_t com_ts:16; +}; + +union ptp_tx_com_timestamp1_reg_u { + a_uint32_t val; + struct ptp_tx_com_timestamp1_reg bf; +}; + +/*[register] PTP_TX_COM_TIMESTAMP2_REG*/ +#define PTP_TX_COM_TIMESTAMP2_REG +#define PTP_TX_COM_TIMESTAMP2_REG_ADDRESS 0x8634 +#define PTP_TX_COM_TIMESTAMP2_REG_NUM 1 +#define PTP_TX_COM_TIMESTAMP2_REG_INC 0x1 +#define PTP_TX_COM_TIMESTAMP2_REG_TYPE REG_TYPE_RW +#define PTP_TX_COM_TIMESTAMP2_REG_DEFAULT 0x0 + /*[field] COM_TS*/ + #define PTP_TX_COM_TIMESTAMP2_REG_COM_TS + #define PTP_TX_COM_TIMESTAMP2_REG_COM_TS_OFFSET 0 + #define PTP_TX_COM_TIMESTAMP2_REG_COM_TS_LEN 16 + #define PTP_TX_COM_TIMESTAMP2_REG_COM_TS_DEFAULT 0x0 + +struct ptp_tx_com_timestamp2_reg { + a_uint32_t com_ts:16; +}; + +union ptp_tx_com_timestamp2_reg_u { + a_uint32_t val; + struct ptp_tx_com_timestamp2_reg bf; +}; + +/*[register] PTP_TX_COM_TIMESTAMP3_REG*/ +#define PTP_TX_COM_TIMESTAMP3_REG +#define PTP_TX_COM_TIMESTAMP3_REG_ADDRESS 0x8635 +#define PTP_TX_COM_TIMESTAMP3_REG_NUM 1 +#define PTP_TX_COM_TIMESTAMP3_REG_INC 0x1 +#define PTP_TX_COM_TIMESTAMP3_REG_TYPE REG_TYPE_RW +#define PTP_TX_COM_TIMESTAMP3_REG_DEFAULT 0x0 + /*[field] COM_TS*/ + #define PTP_TX_COM_TIMESTAMP3_REG_COM_TS + #define PTP_TX_COM_TIMESTAMP3_REG_COM_TS_OFFSET 0 + #define PTP_TX_COM_TIMESTAMP3_REG_COM_TS_LEN 16 + #define PTP_TX_COM_TIMESTAMP3_REG_COM_TS_DEFAULT 0x0 + +struct ptp_tx_com_timestamp3_reg { + a_uint32_t com_ts:16; +}; + +union ptp_tx_com_timestamp3_reg_u { + a_uint32_t val; + struct ptp_tx_com_timestamp3_reg bf; +}; + +/*[register] PTP_TX_COM_TIMESTAMP4_REG*/ +#define PTP_TX_COM_TIMESTAMP4_REG +#define PTP_TX_COM_TIMESTAMP4_REG_ADDRESS 0x8636 +#define PTP_TX_COM_TIMESTAMP4_REG_NUM 1 +#define PTP_TX_COM_TIMESTAMP4_REG_INC 0x1 +#define PTP_TX_COM_TIMESTAMP4_REG_TYPE REG_TYPE_RW +#define PTP_TX_COM_TIMESTAMP4_REG_DEFAULT 0x0 + /*[field] COM_TS*/ + #define PTP_TX_COM_TIMESTAMP4_REG_COM_TS + #define PTP_TX_COM_TIMESTAMP4_REG_COM_TS_OFFSET 0 + #define PTP_TX_COM_TIMESTAMP4_REG_COM_TS_LEN 16 + #define PTP_TX_COM_TIMESTAMP4_REG_COM_TS_DEFAULT 0x0 + +struct ptp_tx_com_timestamp4_reg { + a_uint32_t com_ts:16; +}; + +union ptp_tx_com_timestamp4_reg_u { + a_uint32_t val; + struct ptp_tx_com_timestamp4_reg bf; +}; + +/*[register] PTP_TX_COM_FRAC_NANO_REG*/ +#define PTP_TX_COM_FRAC_NANO_REG +#define PTP_TX_COM_FRAC_NANO_REG_ADDRESS 0x8637 +#define PTP_TX_COM_FRAC_NANO_REG_NUM 1 +#define PTP_TX_COM_FRAC_NANO_REG_INC 0x1 +#define PTP_TX_COM_FRAC_NANO_REG_TYPE REG_TYPE_RW +#define PTP_TX_COM_FRAC_NANO_REG_DEFAULT 0x0 + /*[field] FRAC_NANO*/ + #define PTP_TX_COM_FRAC_NANO_REG_FRAC_NANO + #define PTP_TX_COM_FRAC_NANO_REG_FRAC_NANO_OFFSET 0 + #define PTP_TX_COM_FRAC_NANO_REG_FRAC_NANO_LEN 16 + #define PTP_TX_COM_FRAC_NANO_REG_FRAC_NANO_DEFAULT 0x0 + +struct ptp_tx_com_frac_nano_reg { + a_uint32_t frac_nano:16; +}; + +union ptp_tx_com_frac_nano_reg_u { + a_uint32_t val; + struct ptp_tx_com_frac_nano_reg bf; +}; + +/*[register] PTP_TX_Y1731_IDENTIFY_REG*/ +#define PTP_TX_Y1731_IDENTIFY_REG +#define PTP_TX_Y1731_IDENTIFY_REG_ADDRESS 0x863e +#define PTP_TX_Y1731_IDENTIFY_REG_NUM 1 +#define PTP_TX_Y1731_IDENTIFY_REG_INC 0x1 +#define PTP_TX_Y1731_IDENTIFY_REG_TYPE REG_TYPE_RW +#define PTP_TX_Y1731_IDENTIFY_REG_DEFAULT 0x0 + /*[field] IDENTIFY*/ + #define PTP_TX_Y1731_IDENTIFY_REG_IDENTIFY + #define PTP_TX_Y1731_IDENTIFY_REG_IDENTIFY_OFFSET 0 + #define PTP_TX_Y1731_IDENTIFY_REG_IDENTIFY_LEN 16 + #define PTP_TX_Y1731_IDENTIFY_REG_IDENTIFY_DEFAULT 0x0 + +struct ptp_tx_y1731_identify_reg { + a_uint32_t identify:16; +}; + +union ptp_tx_y1731_identify_reg_u { + a_uint32_t val; + struct ptp_tx_y1731_identify_reg bf; +}; + +/*[register] PTP_Y1731_DM_CONTROL_REG*/ +#define PTP_Y1731_DM_CONTROL_REG +#define PTP_Y1731_DM_CONTROL_REG_ADDRESS 0x8640 +#define PTP_Y1731_DM_CONTROL_REG_NUM 1 +#define PTP_Y1731_DM_CONTROL_REG_INC 0x1 +#define PTP_Y1731_DM_CONTROL_REG_TYPE REG_TYPE_RW +#define PTP_Y1731_DM_CONTROL_REG_DEFAULT 0x0 + /*[field] VALID_MSG_LEV_BMP*/ + #define PTP_Y1731_DM_CONTROL_REG_VALID_MSG_LEV_BMP + #define PTP_Y1731_DM_CONTROL_REG_VALID_MSG_LEV_BMP_OFFSET 0 + #define PTP_Y1731_DM_CONTROL_REG_VALID_MSG_LEV_BMP_LEN 8 + #define PTP_Y1731_DM_CONTROL_REG_VALID_MSG_LEV_BMP_DEFAULT 0x0 + /*[field] Y1731_DMM_LPBK_EN*/ + #define PTP_Y1731_DM_CONTROL_REG_Y1731_DMM_LPBK_EN + #define PTP_Y1731_DM_CONTROL_REG_Y1731_DMM_LPBK_EN_OFFSET 8 + #define PTP_Y1731_DM_CONTROL_REG_Y1731_DMM_LPBK_EN_LEN 1 + #define PTP_Y1731_DM_CONTROL_REG_Y1731_DMM_LPBK_EN_DEFAULT 0x0 + +struct ptp_y1731_dm_control_reg { + a_uint32_t valid_msg_lev_bmp:8; + a_uint32_t y1731_dmm_lpbk_en:1; +}; + +union ptp_y1731_dm_control_reg_u { + a_uint32_t val; + struct ptp_y1731_dm_control_reg bf; +}; + +/*[register] PTP_RX_COM_TS_STATUS_PRE_REG*/ +#define PTP_RX_COM_TS_STATUS_PRE_REG +#define PTP_RX_COM_TS_STATUS_PRE_REG_ADDRESS 0x8641 +#define PTP_RX_COM_TS_STATUS_PRE_REG_NUM 1 +#define PTP_RX_COM_TS_STATUS_PRE_REG_INC 0x1 +#define PTP_RX_COM_TS_STATUS_PRE_REG_TYPE REG_TYPE_RW +#define PTP_RX_COM_TS_STATUS_PRE_REG_DEFAULT 0x0 + /*[field] TS_STATUS*/ + #define PTP_RX_COM_TS_STATUS_PRE_REG_TS_STATUS + #define PTP_RX_COM_TS_STATUS_PRE_REG_TS_STATUS_OFFSET 0 + #define PTP_RX_COM_TS_STATUS_PRE_REG_TS_STATUS_LEN 15 + #define PTP_RX_COM_TS_STATUS_PRE_REG_TS_STATUS_DEFAULT 0x0 + +struct ptp_rx_com_ts_status_pre_reg { + a_uint32_t mac_lengthtype:1; + a_uint32_t mac_da:1; + a_uint32_t mac_ptp_prim_addr:1; + a_uint32_t mac_ptp_pdelay_addr:1; + a_uint32_t ipv4_layer4_protocol:1; + a_uint32_t ipv4_da:1; + a_uint32_t ipv4_ptp_prim_addr:1; + a_uint32_t ipv4_ptp_pdelay_addr:1; + a_uint32_t ipv6_next_header:1; + a_uint32_t ipv6_da:1; + a_uint32_t ipv6_ptp_prim_addr:1; + a_uint32_t ipv6_ptp_pdelay_addr:1; + a_uint32_t udp_dport:1; + a_uint32_t udp_ptp_event_dport:1; + a_uint32_t y1731_mach:1; +}; + +union ptp_rx_com_ts_status_pre_reg_u { + a_uint32_t val; + struct ptp_rx_com_ts_status_pre_reg bf; +}; + +/*[register] PTP_BAUD_CONFIG_REG*/ +#define PTP_BAUD_CONFIG_REG +#define PTP_BAUD_CONFIG_REG_ADDRESS 0x8700 +#define PTP_BAUD_CONFIG_REG_NUM 1 +#define PTP_BAUD_CONFIG_REG_INC 0x1 +#define PTP_BAUD_CONFIG_REG_TYPE REG_TYPE_RW +#define PTP_BAUD_CONFIG_REG_DEFAULT 0x0 + /*[field] BAUD_RATE*/ + #define PTP_BAUD_CONFIG_REG_BAUD_RATE + #define PTP_BAUD_CONFIG_REG_BAUD_RATE_OFFSET 0 + #define PTP_BAUD_CONFIG_REG_BAUD_RATE_LEN 16 + #define PTP_BAUD_CONFIG_REG_BAUD_RATE_DEFAULT 0x0 + +struct ptp_baud_config_reg { + a_uint32_t baud_rate:16; +}; + +union ptp_baud_config_reg_u { + a_uint32_t val; + struct ptp_baud_config_reg bf; +}; + +/*[register] PTP_UART_CONFIGURATION_REG*/ +#define PTP_UART_CONFIGURATION_REG +#define PTP_UART_CONFIGURATION_REG_ADDRESS 0x8701 +#define PTP_UART_CONFIGURATION_REG_NUM 1 +#define PTP_UART_CONFIGURATION_REG_INC 0x1 +#define PTP_UART_CONFIGURATION_REG_TYPE REG_TYPE_RW +#define PTP_UART_CONFIGURATION_REG_DEFAULT 0x0 + /*[field] START_POLARITY*/ + #define PTP_UART_CONFIGURATION_REG_START_POLARITY + #define PTP_UART_CONFIGURATION_REG_START_POLARITY_OFFSET 0 + #define PTP_UART_CONFIGURATION_REG_START_POLARITY_LEN 1 + #define PTP_UART_CONFIGURATION_REG_START_POLARITY_DEFAULT 0x0 + /*[field] MSB_FIRST*/ + #define PTP_UART_CONFIGURATION_REG_MSB_FIRST + #define PTP_UART_CONFIGURATION_REG_MSB_FIRST_OFFSET 1 + #define PTP_UART_CONFIGURATION_REG_MSB_FIRST_LEN 1 + #define PTP_UART_CONFIGURATION_REG_MSB_FIRST_DEFAULT 0x0 + /*[field] PARITY_EN*/ + #define PTP_UART_CONFIGURATION_REG_PARITY_EN + #define PTP_UART_CONFIGURATION_REG_PARITY_EN_OFFSET 2 + #define PTP_UART_CONFIGURATION_REG_PARITY_EN_LEN 1 + #define PTP_UART_CONFIGURATION_REG_PARITY_EN_DEFAULT 0x0 + /*[field] AUTO_TOD_OUT_EN*/ + #define PTP_UART_CONFIGURATION_REG_AUTO_TOD_OUT_EN + #define PTP_UART_CONFIGURATION_REG_AUTO_TOD_OUT_EN_OFFSET 3 + #define PTP_UART_CONFIGURATION_REG_AUTO_TOD_OUT_EN_LEN 1 + #define PTP_UART_CONFIGURATION_REG_AUTO_TOD_OUT_EN_DEFAULT 0x0 + /*[field] AUTO_TOD_IN_EN*/ + #define PTP_UART_CONFIGURATION_REG_AUTO_TOD_IN_EN + #define PTP_UART_CONFIGURATION_REG_AUTO_TOD_IN_EN_OFFSET 4 + #define PTP_UART_CONFIGURATION_REG_AUTO_TOD_IN_EN_LEN 1 + #define PTP_UART_CONFIGURATION_REG_AUTO_TOD_IN_EN_DEFAULT 0x0 + +struct ptp_uart_configuration_reg { + a_uint32_t start_polarity:1; + a_uint32_t msb_first:1; + a_uint32_t parity_en:1; + a_uint32_t auto_tod_out_en:1; + a_uint32_t auto_tod_in_en:1; +}; + +union ptp_uart_configuration_reg_u { + a_uint32_t val; + struct ptp_uart_configuration_reg bf; +}; + +/*[register] PTP_RESET_BUFFER_REG*/ +#define PTP_RESET_BUFFER_REG +#define PTP_RESET_BUFFER_REG_ADDRESS 0x8702 +#define PTP_RESET_BUFFER_REG_NUM 1 +#define PTP_RESET_BUFFER_REG_INC 0x1 +#define PTP_RESET_BUFFER_REG_TYPE REG_TYPE_RW +#define PTP_RESET_BUFFER_REG_DEFAULT 0x0 + /*[field] RESET*/ + #define PTP_RESET_BUFFER_REG_RESET + #define PTP_RESET_BUFFER_REG_RESET_OFFSET 0 + #define PTP_RESET_BUFFER_REG_RESET_LEN 1 + #define PTP_RESET_BUFFER_REG_RESET_DEFAULT 0x0 + +struct ptp_reset_buffer_reg { + a_uint32_t reset:1; +}; + +union ptp_reset_buffer_reg_u { + a_uint32_t val; + struct ptp_reset_buffer_reg bf; +}; + +/*[register] PTP_BUFFER_STATUS_REG*/ +#define PTP_BUFFER_STATUS_REG +#define PTP_BUFFER_STATUS_REG_ADDRESS 0x8703 +#define PTP_BUFFER_STATUS_REG_NUM 1 +#define PTP_BUFFER_STATUS_REG_INC 0x1 +#define PTP_BUFFER_STATUS_REG_TYPE REG_TYPE_RW +#define PTP_BUFFER_STATUS_REG_DEFAULT 0x0 + /*[field] TX_BUFFER_ALMOST_EMPTY*/ + #define PTP_BUFFER_STATUS_REG_TX_BUFFER_ALMOST_EMPTY + #define PTP_BUFFER_STATUS_REG_TX_BUFFER_ALMOST_EMPTY_OFFSET 0 + #define PTP_BUFFER_STATUS_REG_TX_BUFFER_ALMOST_EMPTY_LEN 1 + #define PTP_BUFFER_STATUS_REG_TX_BUFFER_ALMOST_EMPTY_DEFAULT 0x0 + /*[field] TX_BUFFER_ALMOST_FULL*/ + #define PTP_BUFFER_STATUS_REG_TX_BUFFER_ALMOST_FULL + #define PTP_BUFFER_STATUS_REG_TX_BUFFER_ALMOST_FULL_OFFSET 1 + #define PTP_BUFFER_STATUS_REG_TX_BUFFER_ALMOST_FULL_LEN 1 + #define PTP_BUFFER_STATUS_REG_TX_BUFFER_ALMOST_FULL_DEFAULT 0x0 + /*[field] TX_BUFFER_HALF_FULL*/ + #define PTP_BUFFER_STATUS_REG_TX_BUFFER_HALF_FULL + #define PTP_BUFFER_STATUS_REG_TX_BUFFER_HALF_FULL_OFFSET 2 + #define PTP_BUFFER_STATUS_REG_TX_BUFFER_HALF_FULL_LEN 1 + #define PTP_BUFFER_STATUS_REG_TX_BUFFER_HALF_FULL_DEFAULT 0x0 + /*[field] TX_BUFFER_FULL*/ + #define PTP_BUFFER_STATUS_REG_TX_BUFFER_FULL + #define PTP_BUFFER_STATUS_REG_TX_BUFFER_FULL_OFFSET 3 + #define PTP_BUFFER_STATUS_REG_TX_BUFFER_FULL_LEN 1 + #define PTP_BUFFER_STATUS_REG_TX_BUFFER_FULL_DEFAULT 0x0 + /*[field] RX_BUFFER_ALMOST_EMPTY*/ + #define PTP_BUFFER_STATUS_REG_RX_BUFFER_ALMOST_EMPTY + #define PTP_BUFFER_STATUS_REG_RX_BUFFER_ALMOST_EMPTY_OFFSET 4 + #define PTP_BUFFER_STATUS_REG_RX_BUFFER_ALMOST_EMPTY_LEN 1 + #define PTP_BUFFER_STATUS_REG_RX_BUFFER_ALMOST_EMPTY_DEFAULT 0x0 + /*[field] RX_BUFFER_ALMOST_FULL*/ + #define PTP_BUFFER_STATUS_REG_RX_BUFFER_ALMOST_FULL + #define PTP_BUFFER_STATUS_REG_RX_BUFFER_ALMOST_FULL_OFFSET 5 + #define PTP_BUFFER_STATUS_REG_RX_BUFFER_ALMOST_FULL_LEN 1 + #define PTP_BUFFER_STATUS_REG_RX_BUFFER_ALMOST_FULL_DEFAULT 0x0 + /*[field] RX_BUFFER_HALF_FULL*/ + #define PTP_BUFFER_STATUS_REG_RX_BUFFER_HALF_FULL + #define PTP_BUFFER_STATUS_REG_RX_BUFFER_HALF_FULL_OFFSET 6 + #define PTP_BUFFER_STATUS_REG_RX_BUFFER_HALF_FULL_LEN 1 + #define PTP_BUFFER_STATUS_REG_RX_BUFFER_HALF_FULL_DEFAULT 0x0 + /*[field] RX_BUFFER_FULL*/ + #define PTP_BUFFER_STATUS_REG_RX_BUFFER_FULL + #define PTP_BUFFER_STATUS_REG_RX_BUFFER_FULL_OFFSET 7 + #define PTP_BUFFER_STATUS_REG_RX_BUFFER_FULL_LEN 1 + #define PTP_BUFFER_STATUS_REG_RX_BUFFER_FULL_DEFAULT 0x0 + /*[field] RX_BUFFER_DATA_PRESENT*/ + #define PTP_BUFFER_STATUS_REG_RX_BUFFER_DATA_PRESENT + #define PTP_BUFFER_STATUS_REG_RX_BUFFER_DATA_PRESENT_OFFSET 8 + #define PTP_BUFFER_STATUS_REG_RX_BUFFER_DATA_PRESENT_LEN 1 + #define PTP_BUFFER_STATUS_REG_RX_BUFFER_DATA_PRESENT_DEFAULT 0x0 + +struct ptp_buffer_status_reg { + a_uint32_t tx_buffer_almost_empty:1; + a_uint32_t tx_buffer_almost_full:1; + a_uint32_t tx_buffer_half_full:1; + a_uint32_t tx_buffer_full:1; + a_uint32_t rx_buffer_almost_empty:1; + a_uint32_t rx_buffer_almost_full:1; + a_uint32_t rx_buffer_half_full:1; + a_uint32_t rx_buffer_full:1; + a_uint32_t rx_buffer_data_present:1; +}; + +union ptp_buffer_status_reg_u { + a_uint32_t val; + struct ptp_buffer_status_reg bf; +}; + +/*[register] PTP_TX_BUFFER_WRITE_REG*/ +#define PTP_TX_BUFFER_WRITE_REG +#define PTP_TX_BUFFER_WRITE_REG_ADDRESS 0x8704 +#define PTP_TX_BUFFER_WRITE_REG_NUM 1 +#define PTP_TX_BUFFER_WRITE_REG_INC 0x1 +#define PTP_TX_BUFFER_WRITE_REG_TYPE REG_TYPE_RW +#define PTP_TX_BUFFER_WRITE_REG_DEFAULT 0x0 + /*[field] TX_BUFFER*/ + #define PTP_TX_BUFFER_WRITE_REG_TX_BUFFER + #define PTP_TX_BUFFER_WRITE_REG_TX_BUFFER_OFFSET 0 + #define PTP_TX_BUFFER_WRITE_REG_TX_BUFFER_LEN 8 + #define PTP_TX_BUFFER_WRITE_REG_TX_BUFFER_DEFAULT 0x0 + +struct ptp_tx_buffer_write_reg { + a_uint32_t tx_buffer:8; +}; + +union ptp_tx_buffer_write_reg_u { + a_uint32_t val; + struct ptp_tx_buffer_write_reg bf; +}; + +/*[register] PTP_RX_BUFFER_READ_REG*/ +#define PTP_RX_BUFFER_READ_REG +#define PTP_RX_BUFFER_READ_REG_ADDRESS 0x8705 +#define PTP_RX_BUFFER_READ_REG_NUM 1 +#define PTP_RX_BUFFER_READ_REG_INC 0x1 +#define PTP_RX_BUFFER_READ_REG_TYPE REG_TYPE_RW +#define PTP_RX_BUFFER_READ_REG_DEFAULT 0x0 + /*[field] RX_DATA*/ + #define PTP_RX_BUFFER_READ_REG_RX_DATA + #define PTP_RX_BUFFER_READ_REG_RX_DATA_OFFSET 0 + #define PTP_RX_BUFFER_READ_REG_RX_DATA_LEN 8 + #define PTP_RX_BUFFER_READ_REG_RX_DATA_DEFAULT 0x0 + /*[field] RX_BUFFER_ALMOST_EMPTY*/ + #define PTP_RX_BUFFER_READ_REG_RX_BUFFER_ALMOST_EMPTY + #define PTP_RX_BUFFER_READ_REG_RX_BUFFER_ALMOST_EMPTY_OFFSET 8 + #define PTP_RX_BUFFER_READ_REG_RX_BUFFER_ALMOST_EMPTY_LEN 1 + #define PTP_RX_BUFFER_READ_REG_RX_BUFFER_ALMOST_EMPTY_DEFAULT 0x0 + /*[field] RX_BUFFER_ALMOST_FULL*/ + #define PTP_RX_BUFFER_READ_REG_RX_BUFFER_ALMOST_FULL + #define PTP_RX_BUFFER_READ_REG_RX_BUFFER_ALMOST_FULL_OFFSET 9 + #define PTP_RX_BUFFER_READ_REG_RX_BUFFER_ALMOST_FULL_LEN 1 + #define PTP_RX_BUFFER_READ_REG_RX_BUFFER_ALMOST_FULL_DEFAULT 0x0 + /*[field] RX_BUFFER_HALF_FULL*/ + #define PTP_RX_BUFFER_READ_REG_RX_BUFFER_HALF_FULL + #define PTP_RX_BUFFER_READ_REG_RX_BUFFER_HALF_FULL_OFFSET 10 + #define PTP_RX_BUFFER_READ_REG_RX_BUFFER_HALF_FULL_LEN 1 + #define PTP_RX_BUFFER_READ_REG_RX_BUFFER_HALF_FULL_DEFAULT 0x0 + /*[field] RX_BUFFER_FULL*/ + #define PTP_RX_BUFFER_READ_REG_RX_BUFFER_FULL + #define PTP_RX_BUFFER_READ_REG_RX_BUFFER_FULL_OFFSET 11 + #define PTP_RX_BUFFER_READ_REG_RX_BUFFER_FULL_LEN 1 + #define PTP_RX_BUFFER_READ_REG_RX_BUFFER_FULL_DEFAULT 0x0 + /*[field] RX_BUFFER_DATA_PRESENT*/ + #define PTP_RX_BUFFER_READ_REG_RX_BUFFER_DATA_PRESENT + #define PTP_RX_BUFFER_READ_REG_RX_BUFFER_DATA_PRESENT_OFFSET 12 + #define PTP_RX_BUFFER_READ_REG_RX_BUFFER_DATA_PRESENT_LEN 1 + #define PTP_RX_BUFFER_READ_REG_RX_BUFFER_DATA_PRESENT_DEFAULT 0x0 + +struct ptp_rx_buffer_read_reg { + a_uint32_t rx_data:8; + a_uint32_t rx_buffer_almost_empty:1; + a_uint32_t rx_buffer_almost_full:1; + a_uint32_t rx_buffer_half_full:1; + a_uint32_t rx_buffer_full:1; + a_uint32_t rx_buffer_data_present:1; +}; + +union ptp_rx_buffer_read_reg_u { + a_uint32_t val; + struct ptp_rx_buffer_read_reg bf; +}; + +/*[register] PTP_LOC_MAC_ADDR_0_REG*/ +#define PTP_LOC_MAC_ADDR_0_REG +#define PTP_LOC_MAC_ADDR_0_REG_ADDRESS 0x804a +#define PTP_LOC_MAC_ADDR_0_REG_NUM 1 +#define PTP_LOC_MAC_ADDR_0_REG_INC 0x1 +#define PTP_LOC_MAC_ADDR_0_REG_TYPE REG_TYPE_RW +#define PTP_LOC_MAC_ADDR_0_REG_DEFAULT 0x0 + /*[field] MAC_ADDR*/ + #define PTP_LOC_MAC_ADDR_0_REG_MAC_ADDR + #define PTP_LOC_MAC_ADDR_0_REG_MAC_ADDR_OFFSET 0 + #define PTP_LOC_MAC_ADDR_0_REG_MAC_ADDR_LEN 16 + #define PTP_LOC_MAC_ADDR_0_REG_MAC_ADDR_DEFAULT 0x0 + +struct ptp_loc_mac_addr_0_reg { + a_uint32_t mac_addr:16; +}; + +union ptp_loc_mac_addr_0_reg_u { + a_uint32_t val; + struct ptp_loc_mac_addr_0_reg bf; +}; + +/*[register] PTP_LOC_MAC_ADDR_1_REG*/ +#define PTP_LOC_MAC_ADDR_1_REG +#define PTP_LOC_MAC_ADDR_1_REG_ADDRESS 0x804b +#define PTP_LOC_MAC_ADDR_1_REG_NUM 1 +#define PTP_LOC_MAC_ADDR_1_REG_INC 0x1 +#define PTP_LOC_MAC_ADDR_1_REG_TYPE REG_TYPE_RW +#define PTP_LOC_MAC_ADDR_1_REG_DEFAULT 0x0 + /*[field] MAC_ADDR*/ + #define PTP_LOC_MAC_ADDR_1_REG_MAC_ADDR + #define PTP_LOC_MAC_ADDR_1_REG_MAC_ADDR_OFFSET 0 + #define PTP_LOC_MAC_ADDR_1_REG_MAC_ADDR_LEN 16 + #define PTP_LOC_MAC_ADDR_1_REG_MAC_ADDR_DEFAULT 0x0 + +struct ptp_loc_mac_addr_1_reg { + a_uint32_t mac_addr:16; +}; + +union ptp_loc_mac_addr_1_reg_u { + a_uint32_t val; + struct ptp_loc_mac_addr_1_reg bf; +}; + +/*[register] PTP_LOC_MAC_ADDR_2_REG*/ +#define PTP_LOC_MAC_ADDR_2_REG +#define PTP_LOC_MAC_ADDR_2_REG_ADDRESS 0x804c +#define PTP_LOC_MAC_ADDR_2_REG_NUM 1 +#define PTP_LOC_MAC_ADDR_2_REG_INC 0x1 +#define PTP_LOC_MAC_ADDR_2_REG_TYPE REG_TYPE_RW +#define PTP_LOC_MAC_ADDR_2_REG_DEFAULT 0x0 + /*[field] MAC_ADDR*/ + #define PTP_LOC_MAC_ADDR_2_REG_MAC_ADDR + #define PTP_LOC_MAC_ADDR_2_REG_MAC_ADDR_OFFSET 0 + #define PTP_LOC_MAC_ADDR_2_REG_MAC_ADDR_LEN 16 + #define PTP_LOC_MAC_ADDR_2_REG_MAC_ADDR_DEFAULT 0x0 + +struct ptp_loc_mac_addr_2_reg { + a_uint32_t mac_addr:16; +}; + +union ptp_loc_mac_addr_2_reg_u { + a_uint32_t val; + struct ptp_loc_mac_addr_2_reg bf; +}; + +/*[register] PTP_LINK_DELAY_0_REG*/ +#define PTP_LINK_DELAY_0_REG +#define PTP_LINK_DELAY_0_REG_ADDRESS 0x80f3 +#define PTP_LINK_DELAY_0_REG_NUM 1 +#define PTP_LINK_DELAY_0_REG_INC 0x1 +#define PTP_LINK_DELAY_0_REG_TYPE REG_TYPE_RW +#define PTP_LINK_DELAY_0_REG_DEFAULT 0x0 + /*[field] LINK_DELAY*/ + #define PTP_LINK_DELAY_0_REG_LINK_DELAY + #define PTP_LINK_DELAY_0_REG_LINK_DELAY_OFFSET 0 + #define PTP_LINK_DELAY_0_REG_LINK_DELAY_LEN 16 + #define PTP_LINK_DELAY_0_REG_LINK_DELAY_DEFAULT 0x0 + +struct ptp_link_delay_0_reg { + a_uint32_t link_delay:16; +}; + +union ptp_link_delay_0_reg_u { + a_uint32_t val; + struct ptp_link_delay_0_reg bf; +}; + +/*[register] PTP_LINK_DELAY_1_REG*/ +#define PTP_LINK_DELAY_1_REG +#define PTP_LINK_DELAY_1_REG_ADDRESS 0x80f4 +#define PTP_LINK_DELAY_1_REG_NUM 1 +#define PTP_LINK_DELAY_1_REG_INC 0x1 +#define PTP_LINK_DELAY_1_REG_TYPE REG_TYPE_RW +#define PTP_LINK_DELAY_1_REG_DEFAULT 0x0 + /*[field] LINK_DELAY*/ + #define PTP_LINK_DELAY_1_REG_LINK_DELAY + #define PTP_LINK_DELAY_1_REG_LINK_DELAY_OFFSET 0 + #define PTP_LINK_DELAY_1_REG_LINK_DELAY_LEN 16 + #define PTP_LINK_DELAY_1_REG_LINK_DELAY_DEFAULT 0x0 + +struct ptp_link_delay_1_reg { + a_uint32_t link_delay:16; +}; + +union ptp_link_delay_1_reg_u { + a_uint32_t val; + struct ptp_link_delay_1_reg bf; +}; + +/*[register] PTP_MISC_CONTROL_REG*/ +#define PTP_MISC_CONTROL_REG +#define PTP_MISC_CONTROL_REG_ADDRESS 0x80f5 +#define PTP_MISC_CONTROL_REG_NUM 1 +#define PTP_MISC_CONTROL_REG_INC 0x1 +#define PTP_MISC_CONTROL_REG_TYPE REG_TYPE_RW +#define PTP_MISC_CONTROL_REG_DEFAULT 0x0 + /*[field] EG_ASYM_EN*/ + #define PTP_MISC_CONTROL_REG_EG_ASYM_EN + #define PTP_MISC_CONTROL_REG_EG_ASYM_EN_OFFSET 0 + #define PTP_MISC_CONTROL_REG_EG_ASYM_EN_LEN 1 + #define PTP_MISC_CONTROL_REG_EG_ASYM_EN_DEFAULT 0x0 + /*[field] IN_ASYM_EN*/ + #define PTP_MISC_CONTROL_REG_IN_ASYM_EN + #define PTP_MISC_CONTROL_REG_IN_ASYM_EN_OFFSET 1 + #define PTP_MISC_CONTROL_REG_IN_ASYM_EN_LEN 1 + #define PTP_MISC_CONTROL_REG_IN_ASYM_EN_DEFAULT 0x0 + +struct ptp_misc_control_reg { + a_uint32_t eg_asym_en:1; + a_uint32_t in_asym_en:1; +}; + +union ptp_misc_control_reg_u { + a_uint32_t val; + struct ptp_misc_control_reg bf; +}; + +/*[register] PTP_INGRESS_ASYMMETRY_0_REG*/ +#define PTP_INGRESS_ASYMMETRY_0_REG +#define PTP_INGRESS_ASYMMETRY_0_REG_ADDRESS 0x80f6 +#define PTP_INGRESS_ASYMMETRY_0_REG_NUM 1 +#define PTP_INGRESS_ASYMMETRY_0_REG_INC 0x1 +#define PTP_INGRESS_ASYMMETRY_0_REG_TYPE REG_TYPE_RW +#define PTP_INGRESS_ASYMMETRY_0_REG_DEFAULT 0x0 + /*[field] IN_ASYM*/ + #define PTP_INGRESS_ASYMMETRY_0_REG_IN_ASYM + #define PTP_INGRESS_ASYMMETRY_0_REG_IN_ASYM_OFFSET 0 + #define PTP_INGRESS_ASYMMETRY_0_REG_IN_ASYM_LEN 16 + #define PTP_INGRESS_ASYMMETRY_0_REG_IN_ASYM_DEFAULT 0x0 + +struct ptp_ingress_asymmetry_0_reg { + a_uint32_t in_asym:16; +}; + +union ptp_ingress_asymmetry_0_reg_u { + a_uint32_t val; + struct ptp_ingress_asymmetry_0_reg bf; +}; + +/*[register] PTP_INGRESS_ASYMMETRY_1_REG*/ +#define PTP_INGRESS_ASYMMETRY_1_REG +#define PTP_INGRESS_ASYMMETRY_1_REG_ADDRESS 0x80f7 +#define PTP_INGRESS_ASYMMETRY_1_REG_NUM 1 +#define PTP_INGRESS_ASYMMETRY_1_REG_INC 0x1 +#define PTP_INGRESS_ASYMMETRY_1_REG_TYPE REG_TYPE_RW +#define PTP_INGRESS_ASYMMETRY_1_REG_DEFAULT 0x0 + /*[field] IN_ASYM*/ + #define PTP_INGRESS_ASYMMETRY_1_REG_IN_ASYM + #define PTP_INGRESS_ASYMMETRY_1_REG_IN_ASYM_OFFSET 0 + #define PTP_INGRESS_ASYMMETRY_1_REG_IN_ASYM_LEN 16 + #define PTP_INGRESS_ASYMMETRY_1_REG_IN_ASYM_DEFAULT 0x0 + +struct ptp_ingress_asymmetry_1_reg { + a_uint32_t in_asym:16; +}; + +union ptp_ingress_asymmetry_1_reg_u { + a_uint32_t val; + struct ptp_ingress_asymmetry_1_reg bf; +}; + +/*[register] PTP_EGRESS_ASYMMETRY_0_REG*/ +#define PTP_EGRESS_ASYMMETRY_0_REG +#define PTP_EGRESS_ASYMMETRY_0_REG_ADDRESS 0x80f8 +#define PTP_EGRESS_ASYMMETRY_0_REG_NUM 1 +#define PTP_EGRESS_ASYMMETRY_0_REG_INC 0x1 +#define PTP_EGRESS_ASYMMETRY_0_REG_TYPE REG_TYPE_RW +#define PTP_EGRESS_ASYMMETRY_0_REG_DEFAULT 0x0 + /*[field] EG_ASYM*/ + #define PTP_EGRESS_ASYMMETRY_0_REG_EG_ASYM + #define PTP_EGRESS_ASYMMETRY_0_REG_EG_ASYM_OFFSET 0 + #define PTP_EGRESS_ASYMMETRY_0_REG_EG_ASYM_LEN 16 + #define PTP_EGRESS_ASYMMETRY_0_REG_EG_ASYM_DEFAULT 0x0 + +struct ptp_egress_asymmetry_0_reg { + a_uint32_t eg_asym:16; +}; + +union ptp_egress_asymmetry_0_reg_u { + a_uint32_t val; + struct ptp_egress_asymmetry_0_reg bf; +}; + +/*[register] PTP_EGRESS_ASYMMETRY_1_REG*/ +#define PTP_EGRESS_ASYMMETRY_1_REG +#define PTP_EGRESS_ASYMMETRY_1_REG_ADDRESS 0x80f9 +#define PTP_EGRESS_ASYMMETRY_1_REG_NUM 1 +#define PTP_EGRESS_ASYMMETRY_1_REG_INC 0x1 +#define PTP_EGRESS_ASYMMETRY_1_REG_TYPE REG_TYPE_RW +#define PTP_EGRESS_ASYMMETRY_1_REG_DEFAULT 0x0 + /*[field] EG_ASYM*/ + #define PTP_EGRESS_ASYMMETRY_1_REG_EG_ASYM + #define PTP_EGRESS_ASYMMETRY_1_REG_EG_ASYM_OFFSET 0 + #define PTP_EGRESS_ASYMMETRY_1_REG_EG_ASYM_LEN 16 + #define PTP_EGRESS_ASYMMETRY_1_REG_EG_ASYM_DEFAULT 0x0 + +struct ptp_egress_asymmetry_1_reg { + a_uint32_t eg_asym:16; +}; + +union ptp_egress_asymmetry_1_reg_u { + a_uint32_t val; + struct ptp_egress_asymmetry_1_reg bf; +}; + +/*[register] PTP_BACKUP_REG*/ +#define PTP_BACKUP_REG +#define PTP_BACKUP_REG_ADDRESS 0x9036 +#define PTP_BACKUP_REG_NUM 1 +#define PTP_BACKUP_REG_INC 0x1 +#define PTP_BACKUP_REG_TYPE REG_TYPE_RW +#define PTP_BACKUP_REG_DEFAULT 0x0 + /*[field] P2P_TC_EN*/ + #define PTP_BACKUP_REG_P2P_TC_EN + #define PTP_BACKUP_REG_P2P_TC_EN_OFFSET 0 + #define PTP_BACKUP_REG_P2P_TC_EN_LEN 1 + #define PTP_BACKUP_REG_P2P_TC_EN_DEFAULT 0x0 + +struct ptp_backup_reg { + a_uint32_t p2p_tc_en:1; +}; + +union ptp_backup_reg_u { + a_uint32_t val; + struct ptp_backup_reg bf; +}; + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/sfp_phy.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/sfp_phy.h new file mode 100755 index 000000000..8b4c7a127 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/phy/sfp_phy.h @@ -0,0 +1,47 @@ +/* + * 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 _SFP_PHY_H_ +#define _SFP_PHY_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + +#define SFP_ANEG_DONE 0x20 + +#define SFP_E2PROM_ADDR 0x50 +#define SFP_SPEED_ADDR 0xc +#define SFP_SPEED_1000M 10 +#define SFP_SPEED_2500M 25 +#define SFP_SPEED_10000M 100 + +#define SFP_TO_SFP_SPEED(reg_data) ((reg_data >> 8) & 0xff) + +int sfp_phy_device_setup(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t phy_id); +void sfp_phy_device_remove(a_uint32_t dev_id, a_uint32_t port); + +int sfp_phy_init(a_uint32_t dev_id, a_uint32_t port_bmp); +void sfp_phy_exit(a_uint32_t dev_id, a_uint32_t port_bmp); + +sw_error_t sfp_phy_interface_get_mode_status(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_interface_mode_t *interface_mode); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _SFP_PHY_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/scomphy/scomphy_init.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/scomphy/scomphy_init.h new file mode 100755 index 000000000..decb90945 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/scomphy/scomphy_init.h @@ -0,0 +1,42 @@ +/* + * 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. + */ + + +/** + * @defgroup scomphy_init SCOMPHY_INIT + * @{ + */ +#ifndef _SCOMPHY_INIT_H_ +#define _SCOMPHY_INIT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "ssdk_init.h" + +sw_error_t +scomphy_init(a_uint32_t dev_id, ssdk_init_cfg *cfg); + +sw_error_t +scomphy_cleanup(a_uint32_t dev_id); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _SCOMPHY_INIT_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/scomphy/scomphy_port_ctrl.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/scomphy/scomphy_port_ctrl.h new file mode 100644 index 000000000..399e25306 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/scomphy/scomphy_port_ctrl.h @@ -0,0 +1,233 @@ +/* + * 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. + */ + +/*qca808x_start*/ +#ifndef _SCOMPHY_PORT_CTRL_H_ +#define _SCOMPHY_PORT_CTRL_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include "fal/fal_port_ctrl.h" + +sw_error_t scomphy_port_ctrl_init (a_uint32_t dev_id); + +sw_error_t +scomphy_port_reset (a_uint32_t dev_id, fal_port_t port_id); + +/*qca808x_end*/ +#ifdef IN_PORTCONTROL +/*qca808x_start*/ +#define SCOMPHY_PORT_CTRL_INIT(rv, dev_id) \ + { \ + rv = scomphy_port_ctrl_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +/*qca808x_end*/ +#else +#define SCOMPHY_PORT_CTRL_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + +HSL_LOCAL sw_error_t +scomphy_port_duplex_set (a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t duplex); + + +HSL_LOCAL sw_error_t +scomphy_port_duplex_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t * pduplex); + + +HSL_LOCAL sw_error_t +scomphy_port_speed_set (a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t speed); + + +HSL_LOCAL sw_error_t +scomphy_port_speed_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t * pspeed); + + +HSL_LOCAL sw_error_t +scomphy_port_autoneg_status_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status); + + +HSL_LOCAL sw_error_t +scomphy_port_autoneg_enable (a_uint32_t dev_id, fal_port_t port_id); + + +HSL_LOCAL sw_error_t +scomphy_port_autoneg_restart (a_uint32_t dev_id, fal_port_t port_id); + + +HSL_LOCAL sw_error_t +scomphy_port_autoneg_adv_set (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t autoadv); + + +HSL_LOCAL sw_error_t +scomphy_port_autoneg_adv_get (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * autoadv); + +#ifndef IN_PORTCONTROL_MINI +HSL_LOCAL sw_error_t +scomphy_port_powersave_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + +HSL_LOCAL sw_error_t +scomphy_port_powersave_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + +HSL_LOCAL sw_error_t +scomphy_port_hibernate_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + +HSL_LOCAL sw_error_t +scomphy_port_hibernate_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + +HSL_LOCAL sw_error_t +scomphy_port_cdt (a_uint32_t dev_id, fal_port_t port_id, a_uint32_t mdi_pair, + fal_cable_status_t * cable_status, a_uint32_t * cable_len); +#endif + +HSL_LOCAL sw_error_t +scomphy_port_link_status_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status); +#ifndef IN_PORTCONTROL_MINI + +HSL_LOCAL sw_error_t +scomphy_port_8023az_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + +HSL_LOCAL sw_error_t +scomphy_port_8023az_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + +HSL_LOCAL sw_error_t +scomphy_port_mdix_set (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_mdix_mode_t mode); + +HSL_LOCAL sw_error_t +scomphy_port_mdix_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_mdix_mode_t * mode); + +HSL_LOCAL sw_error_t +scomphy_port_mdix_status_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_mdix_status_t * mode); + +HSL_LOCAL sw_error_t +scomphy_port_combo_prefer_medium_set (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_medium_t phy_medium); + +HSL_LOCAL sw_error_t +scomphy_port_combo_prefer_medium_get (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_medium_t * phy_medium); + +HSL_LOCAL sw_error_t +scomphy_port_combo_medium_status_get (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_medium_t * phy_medium); + +HSL_LOCAL sw_error_t +scomphy_port_combo_fiber_mode_set (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_fiber_mode_t fiber_mode); + +HSL_LOCAL sw_error_t +scomphy_port_combo_fiber_mode_get (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_fiber_mode_t * fiber_mode); + +HSL_LOCAL sw_error_t +scomphy_port_local_loopback_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + +HSL_LOCAL sw_error_t +scomphy_port_local_loopback_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + +HSL_LOCAL sw_error_t +scomphy_port_remote_loopback_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + +HSL_LOCAL sw_error_t +scomphy_port_remote_loopback_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + +HSL_LOCAL sw_error_t +scomphy_port_magic_frame_mac_set (a_uint32_t dev_id, fal_port_t port_id, + fal_mac_addr_t * mac); + +HSL_LOCAL sw_error_t +scomphy_port_magic_frame_mac_get (a_uint32_t dev_id, fal_port_t port_id, + fal_mac_addr_t * mac); + +HSL_LOCAL sw_error_t +scomphy_port_phy_id_get (a_uint32_t dev_id, fal_port_t port_id, + a_uint16_t * org_id, a_uint16_t * rev_id); + +HSL_LOCAL sw_error_t +scomphy_port_wol_status_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + +HSL_LOCAL sw_error_t +scomphy_port_wol_status_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); +#endif +HSL_LOCAL sw_error_t +scomphy_port_power_off (a_uint32_t dev_id, fal_port_t port_id); + +HSL_LOCAL sw_error_t +scomphy_port_power_on (a_uint32_t dev_id, fal_port_t port_id); + +#ifndef IN_PORTCONTROL_MINI +HSL_LOCAL sw_error_t +scomphy_port_interface_mode_set (a_uint32_t dev_id, fal_port_t port_id, + fal_port_interface_mode_t mode); + +HSL_LOCAL sw_error_t +scomphy_port_interface_mode_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_interface_mode_t * mode); + +HSL_LOCAL sw_error_t +scomphy_port_interface_mode_status_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_interface_mode_t * mode); + +HSL_LOCAL sw_error_t +scomphy_port_counter_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + +HSL_LOCAL sw_error_t +scomphy_port_counter_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + +HSL_LOCAL sw_error_t +scomphy_port_counter_show (a_uint32_t dev_id, fal_port_t port_id, + fal_port_counter_info_t * counter_info); +#endif +#endif +/*qca808x_start*/ +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _SCOMPHY_PORT_CTRL_H_ */ +/*qca808x_end*/ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/scomphy/scomphy_reg_access.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/scomphy/scomphy_reg_access.h new file mode 100755 index 000000000..995ff35af --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/scomphy/scomphy_reg_access.h @@ -0,0 +1,62 @@ +/* + * 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. + */ + + +/*qca808x_start*/ + +#ifndef _SCOMPHY_REG_ACCESS_H_ +#define _SCOMPHY_REG_ACCESS_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "sw.h" + +sw_error_t +scomphy_phy_get(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t * value); + +sw_error_t +scomphy_phy_set(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t value); +/*qca808x_end*/ + +sw_error_t +scomphy_reg_get(a_uint32_t dev_id, a_uint32_t reg_addr, + a_uint8_t *val, a_uint32_t len); + +sw_error_t +scomphy_reg_set(a_uint32_t dev_id, a_uint32_t reg_addr, + a_uint8_t *val, a_uint32_t len); + +sw_error_t +scomphy_uniphy_reg_get(a_uint32_t dev_id, a_uint32_t index, + a_uint32_t reg_addr, a_uint8_t *val, a_uint32_t len); + +sw_error_t +scomphy_uniphy_reg_set(a_uint32_t dev_id, a_uint32_t index, + a_uint32_t reg_addr, a_uint8_t *val, a_uint32_t len); + +/*qca808x_start*/ +sw_error_t +scomphy_reg_access_init(a_uint32_t dev_id, ssdk_init_cfg *cfg); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _SCOMPHY_REG_ACCESS_H_ */ +/*qca808x_end*/ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/sfp/sfp.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/sfp/sfp.h new file mode 100644 index 000000000..186332663 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/sfp/sfp.h @@ -0,0 +1,956 @@ +/* + * 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 + * @{ + */ +#ifndef _SFP_H_ +#define _SFP_H_ + + +sw_error_t +sfp_eeprom_data_get(a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t i2c_slave, + a_uint32_t offset, a_uint8_t *buf, a_uint32_t counter); + +sw_error_t +sfp_eeprom_data_set(a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t i2c_slave, + a_uint32_t offset, a_uint8_t *buf, a_uint32_t counter); + +sw_error_t +sfp_dev_type_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_dev_type_u *value); + +sw_error_t +sfp_dev_type_ext_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_dev_type_ext_u *value); + +sw_error_t +sfp_dev_connector_type_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_dev_connector_type_u *value); + +sw_error_t +sfp_transc_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_transc_u *value); + +sw_error_t +sfp_encoding_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_encoding_u *value); + +sw_error_t +sfp_br_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_br_u *value); + +sw_error_t +sfp_rate_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_rate_u *value); + +sw_error_t +sfp_link_len_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_link_len_u *value); + +sw_error_t +sfp_vendor_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_vendor_u *value); + +sw_error_t +sfp_laser_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_laser_u *value); + +sw_error_t +sfp_base_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_base_u *value); + +sw_error_t +sfp_option_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_option_u *value); + +sw_error_t +sfp_rate_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_rate_ctrl_u *value); + +sw_error_t +sfp_vendor_ext_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_vendor_ext_u *value); + +sw_error_t +sfp_enhanced_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_enhanced_u *value); + +sw_error_t +sfp_ext_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_ext_u *value); + +sw_error_t +sfp_dev_type_id_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_dev_type_ext_id_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_dev_connector_type_code_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_transc_sonet_ccode_2_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_transc_fiber_ch_tech_1_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_transc_sonet_ccode_1_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_transc_fiber_ch_speed_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_transc_fiber_ch_tech_2_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_transc_cable_tech_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_transc_fiber_ch_link_len_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_transc_unallocated_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_transc_fiber_chan_tm_media_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_transc_escon_ccode_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_transc_infiniband_ccode_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_transc_eth_ccode_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_transc_eth_10g_ccode_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_encoding_code_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_br_bit_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_rate_id_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_link_len_om3_mode_1m_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_link_len_single_mode_100m_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_link_len_om2_mode_10m_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_link_len_copper_mode_1m_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_link_len_om1_mode_10m_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_link_len_single_mode_km_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_vendor_rev_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint8_t *value); + +sw_error_t +sfp_vendor_name_get( + a_uint32_t dev_id, a_uint32_t index, + a_uint8_t *value); + +sw_error_t +sfp_vendor_oui_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint8_t *value); + +sw_error_t +sfp_vendor_pn_get( + a_uint32_t dev_id, a_uint32_t index, + a_uint8_t *value); + +sw_error_t +sfp_laser_wavelength_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_base_check_code_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_option_linear_recv_output_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_option_pwr_level_declar_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_option_unallocated_1_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_option_unallocated_3_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_option_loss_signal_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_option_rate_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_option_unallocated_2_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_option_loss_invert_signal_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_option_tx_disable_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_option_cool_transc_declar_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_option_tx_fault_signal_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_rate_ctrl_upper_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_rate_ctrl_lower_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_vendor_ext_date_code_get( + a_uint32_t dev_id, a_uint32_t index, + a_uint8_t *value); + +sw_error_t +sfp_vendor_ext_sn_get( + a_uint32_t dev_id, a_uint32_t index, + a_uint8_t *value); + +sw_error_t +sfp_enhanced_diag_mon_flag_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_enhanced_rx_los_op_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_enhanced_cmpl_feature_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_enhanced_tx_disable_ctrl_op_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_enhanced_alarm_warning_flag_op_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_enhanced_addr_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_enhanced_unallocated_op_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_enhanced_soft_rate_sel_op_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_enhanced_external_cal_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_enhanced_internal_cal_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_enhanced_re_pwr_type_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_enhanced_soft_rate_ctrl_op_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_enhanced_app_sel_op_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_enhanced_legacy_type_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_enhanced_tx_fault_op_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_enhanced_unallocated_type_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_ext_check_code_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_threshold_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_diag_threshold_u *value); + +sw_error_t +sfp_diag_cal_const_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_diag_cal_const_u *value); + +sw_error_t +sfp_diag_dmi_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_diag_dmi_u *value); + +sw_error_t +sfp_diag_realtime_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_diag_realtime_u *value); + +sw_error_t +sfp_diag_optional_ctrl_status_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_diag_optional_ctrl_status_u *value); + +sw_error_t +sfp_diag_flag_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_diag_flag_u *value); + +sw_error_t +sfp_diag_extended_ctrl_status_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_diag_extended_ctrl_status_u *value); + +sw_error_t +sfp_diag_threshold_rx_pwr_low_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_threshold_rx_pwr_high_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_threshold_temp_low_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_threshold_vol_high_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_threshold_tx_pwr_high_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_threshold_bias_low_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_threshold_bias_high_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_threshold_vol_low_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_threshold_bias_high_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_threshold_temp_high_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_threshold_rx_pwr_low_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_threshold_vol_low_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_threshold_tx_pwr_low_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_threshold_bias_low_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_threshold_temp_high_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_threshold_tx_pwr_high_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_threshold_vol_high_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_threshold_temp_low_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_threshold_rx_pwr_high_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_threshold_tx_pwr_low_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_cal_const_rx_pwr_1_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_cal_const_t_slope_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_cal_const_rx_pwr_3_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_cal_const_rx_pwr_2_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_cal_const_tx_i_slope_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_cal_const_v_slope_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_cal_const_tx_pwr_slope_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_cal_const_rx_pwr_4_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_cal_const_rx_pwr_0_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_dmi_check_code_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_realtime_vcc_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_realtime_tx_pwr_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_realtime_tx_bias_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_realtime_rx_pwr_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_realtime_tmp_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_optional_ctrl_status_rs_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_optional_ctrl_status_tx_fault_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_optional_ctrl_status_rx_los_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_optional_ctrl_status_data_ready_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_optional_ctrl_status_soft_rate_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_optional_ctrl_status_soft_tx_disable_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_optional_ctrl_status_rate_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_optional_ctrl_status_tx_disable_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_flag_rx_pwr_low_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_flag_rx_pwr_high_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_flag_tx_bias_high_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_flag_tmp_high_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_flag_tmp_low_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_flag_tx_pwr_high_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_flag_vcc_low_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_flag_vcc_high_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_flag_rx_pwr_low_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_flag_unallocated_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_flag_tx_bias_high_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_flag_vcc_low_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_flag_tx_pwr_low_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_flag_vcc_high_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_flag_tmp_low_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_flag_tx_bias_low_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_flag_tx_bias_low_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_flag_tmp_high_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_flag_tx_pwr_high_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_flag_rx_pwr_high_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_flag_tx_pwr_low_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_extended_ctrl_status_unallocated_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_extended_ctrl_status_pwr_level_op_state_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_extended_ctrl_status_soft_rs_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +sw_error_t +sfp_diag_extended_ctrl_status_pwr_level_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + unsigned int *value); + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/sfp/sfp_access.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/sfp/sfp_access.h new file mode 100755 index 000000000..d96c66ee2 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/sfp/sfp_access.h @@ -0,0 +1,53 @@ +/* + * 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 _SFP_ACCESS_H_ +#define _SFP_ACCESS_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "sw.h" + +#define SFP_BASE_ADDR 0x0 +#define SFP_DIAG_BASE_ADDR 0x0 + +#define SFP_EEPROM_BASE_A0 0x50 +#define SFP_EEPROM_DIAG_A2 0x51 + + +sw_error_t +sfp_data_tbl_get(a_uint32_t dev_id, a_uint32_t index, a_uint32_t i2c_slave, + a_uint32_t data_addr, a_uint8_t *buf, a_uint32_t count); + +sw_error_t +sfp_data_get(a_uint32_t dev_id, a_uint32_t index, a_uint32_t i2c_slave, + a_uint32_t data_addr, a_uint8_t *buf); + +sw_error_t +sfp_data_tbl_set(a_uint32_t dev_id, a_uint32_t index, a_uint32_t i2c_slave, + a_uint32_t data_addr, a_uint8_t *buf, a_uint32_t count); + +sw_error_t +sfp_data_set(a_uint32_t dev_id, a_uint32_t index, a_uint32_t i2c_slave, + a_uint32_t data_addr, a_uint8_t *buf); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _PPE_SFP_ACCESS_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/sfp/sfp_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/sfp/sfp_reg.h new file mode 100755 index 000000000..59fb4dcf6 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/sfp/sfp_reg.h @@ -0,0 +1,1319 @@ +/* + * 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 + * @{ + */ +#ifndef _SFP_REG_H_ +#define _SFP_REG_H_ + +/*[register] SFP_DEV_TYPE*/ +#define SFP_DEV_TYPE +#define SFP_DEV_TYPE_ADDRESS 0x0 +#define SFP_DEV_TYPE_NUM 1 +#define SFP_DEV_TYPE_INC 0x1 +#define SFP_DEV_TYPE_TYPE REG_TYPE_RO +#define SFP_DEV_TYPE_DEFAULT 0x0 + /*[field] ID*/ + #define SFP_DEV_TYPE_ID + #define SFP_DEV_TYPE_ID_OFFSET 0 + #define SFP_DEV_TYPE_ID_LEN 8 + #define SFP_DEV_TYPE_ID_DEFAULT 0x0 + +struct sfp_dev_type { + a_uint8_t id:8; +}; + +union sfp_dev_type_u { + a_uint8_t val; + struct sfp_dev_type bf; +}; + +/*[register] SFP_DEV_TYPE_EXT*/ +#define SFP_DEV_TYPE_EXT +#define SFP_DEV_TYPE_EXT_ADDRESS 0x1 +#define SFP_DEV_TYPE_EXT_NUM 1 +#define SFP_DEV_TYPE_EXT_INC 0x1 +#define SFP_DEV_TYPE_EXT_TYPE REG_TYPE_RO +#define SFP_DEV_TYPE_EXT_DEFAULT 0x0 + /*[field] ID*/ + #define SFP_DEV_TYPE_EXT_ID + #define SFP_DEV_TYPE_EXT_ID_OFFSET 0 + #define SFP_DEV_TYPE_EXT_ID_LEN 8 + #define SFP_DEV_TYPE_EXT_ID_DEFAULT 0x0 + +struct sfp_dev_type_ext { + a_uint8_t id:8; +}; + +union sfp_dev_type_ext_u { + a_uint8_t val; + struct sfp_dev_type_ext bf; +}; + +/*[register] SFP_DEV_CONNECTOR_TYPE*/ +#define SFP_DEV_CONNECTOR_TYPE +#define SFP_DEV_CONNECTOR_TYPE_ADDRESS 0x2 +#define SFP_DEV_CONNECTOR_TYPE_NUM 1 +#define SFP_DEV_CONNECTOR_TYPE_INC 0x1 +#define SFP_DEV_CONNECTOR_TYPE_TYPE REG_TYPE_RO +#define SFP_DEV_CONNECTOR_TYPE_DEFAULT 0x0 + /*[field] CODE*/ + #define SFP_DEV_CONNECTOR_TYPE_CODE + #define SFP_DEV_CONNECTOR_TYPE_CODE_OFFSET 0 + #define SFP_DEV_CONNECTOR_TYPE_CODE_LEN 8 + #define SFP_DEV_CONNECTOR_TYPE_CODE_DEFAULT 0x0 + +struct sfp_dev_connector_type { + a_uint8_t code:8; +}; + +union sfp_dev_connector_type_u { + a_uint8_t val; + struct sfp_dev_connector_type bf; +}; + +/*[register] SFP_TRANSC*/ +#define SFP_TRANSC +#define SFP_TRANSC_ADDRESS 0x3 +#define SFP_TRANSC_NUM 1 +#define SFP_TRANSC_INC 0x8 +#define SFP_TRANSC_TYPE REG_TYPE_RO +#define SFP_TRANSC_DEFAULT 0x0 + /*[field] INFINIBAND_CCODE*/ + #define SFP_TRANSC_INFINIBAND_CCODE + #define SFP_TRANSC_INFINIBAND_CCODE_OFFSET 0 + #define SFP_TRANSC_INFINIBAND_CCODE_LEN 4 + #define SFP_TRANSC_INFINIBAND_CCODE_DEFAULT 0x0 + /*[field] ETH_10G_CCODE*/ + #define SFP_TRANSC_ETH_10G_CCODE + #define SFP_TRANSC_ETH_10G_CCODE_OFFSET 4 + #define SFP_TRANSC_ETH_10G_CCODE_LEN 4 + #define SFP_TRANSC_ETH_10G_CCODE_DEFAULT 0x0 + /*[field] SONET_CCODE_1*/ + #define SFP_TRANSC_SONET_CCODE_1 + #define SFP_TRANSC_SONET_CCODE_1_OFFSET 8 + #define SFP_TRANSC_SONET_CCODE_1_LEN 6 + #define SFP_TRANSC_SONET_CCODE_1_DEFAULT 0x0 + /*[field] ESCON_CCODE*/ + #define SFP_TRANSC_ESCON_CCODE + #define SFP_TRANSC_ESCON_CCODE_OFFSET 14 + #define SFP_TRANSC_ESCON_CCODE_LEN 2 + #define SFP_TRANSC_ESCON_CCODE_DEFAULT 0x0 + /*[field] SONET_CCODE_2*/ + #define SFP_TRANSC_SONET_CCODE_2 + #define SFP_TRANSC_SONET_CCODE_2_OFFSET 16 + #define SFP_TRANSC_SONET_CCODE_2_LEN 8 + #define SFP_TRANSC_SONET_CCODE_2_DEFAULT 0x0 + /*[field] ETH_CCODE*/ + #define SFP_TRANSC_ETH_CCODE + #define SFP_TRANSC_ETH_CCODE_OFFSET 24 + #define SFP_TRANSC_ETH_CCODE_LEN 8 + #define SFP_TRANSC_ETH_CCODE_DEFAULT 0x0 + /*[field] FIBER_CH_TECH_1*/ + #define SFP_TRANSC_FIBER_CH_TECH_1 + #define SFP_TRANSC_FIBER_CH_TECH_1_OFFSET 32 + #define SFP_TRANSC_FIBER_CH_TECH_1_LEN 3 + #define SFP_TRANSC_FIBER_CH_TECH_1_DEFAULT 0x0 + /*[field] FIBER_CH_LINK_LEN*/ + #define SFP_TRANSC_FIBER_CH_LINK_LEN + #define SFP_TRANSC_FIBER_CH_LINK_LEN_OFFSET 35 + #define SFP_TRANSC_FIBER_CH_LINK_LEN_LEN 5 + #define SFP_TRANSC_FIBER_CH_LINK_LEN_DEFAULT 0x0 + /*[field] UNALLOCATED*/ + #define SFP_TRANSC_UNALLOCATED + #define SFP_TRANSC_UNALLOCATED_OFFSET 40 + #define SFP_TRANSC_UNALLOCATED_LEN 2 + #define SFP_TRANSC_UNALLOCATED_DEFAULT 0x0 + /*[field] CABLE_TECH*/ + #define SFP_TRANSC_CABLE_TECH + #define SFP_TRANSC_CABLE_TECH_OFFSET 42 + #define SFP_TRANSC_CABLE_TECH_LEN 2 + #define SFP_TRANSC_CABLE_TECH_DEFAULT 0x0 + /*[field] FIBER_CH_TECH_2*/ + #define SFP_TRANSC_FIBER_CH_TECH_2 + #define SFP_TRANSC_FIBER_CH_TECH_2_OFFSET 44 + #define SFP_TRANSC_FIBER_CH_TECH_2_LEN 4 + #define SFP_TRANSC_FIBER_CH_TECH_2_DEFAULT 0x0 + /*[field] FIBER_CHAN_TM_MEDIA*/ + #define SFP_TRANSC_FIBER_CHAN_TM_MEDIA + #define SFP_TRANSC_FIBER_CHAN_TM_MEDIA_OFFSET 48 + #define SFP_TRANSC_FIBER_CHAN_TM_MEDIA_LEN 8 + #define SFP_TRANSC_FIBER_CHAN_TM_MEDIA_DEFAULT 0x0 + /*[field] FIBER_CH_SPEED*/ + #define SFP_TRANSC_FIBER_CH_SPEED + #define SFP_TRANSC_FIBER_CH_SPEED_OFFSET 56 + #define SFP_TRANSC_FIBER_CH_SPEED_LEN 8 + #define SFP_TRANSC_FIBER_CH_SPEED_DEFAULT 0x0 + +struct sfp_transc { + a_uint8_t infiniband_ccode:4; + a_uint8_t eth_10g_ccode:4; + a_uint8_t sonet_ccode_1:6; + a_uint8_t escon_ccode:2; + a_uint8_t sonet_ccode_2:8; + a_uint8_t eth_ccode:8; + a_uint8_t fiber_ch_tech_1:3; + a_uint8_t fiber_ch_link_len:5; + a_uint8_t unallocated:2; + a_uint8_t cable_tech:2; + a_uint8_t fiber_ch_tech_2:4; + a_uint8_t fiber_chan_tm_media:8; + a_uint8_t fiber_ch_speed:8; +}; + +union sfp_transc_u { + a_uint8_t val[8]; + struct sfp_transc bf; +}; + +/*[register] SFP_ENCODING*/ +#define SFP_ENCODING +#define SFP_ENCODING_ADDRESS 0xb +#define SFP_ENCODING_NUM 1 +#define SFP_ENCODING_INC 0x1 +#define SFP_ENCODING_TYPE REG_TYPE_RO +#define SFP_ENCODING_DEFAULT 0x0 + /*[field] CODE*/ + #define SFP_ENCODING_CODE + #define SFP_ENCODING_CODE_OFFSET 0 + #define SFP_ENCODING_CODE_LEN 8 + #define SFP_ENCODING_CODE_DEFAULT 0x0 + +struct sfp_encoding { + a_uint8_t code:8; +}; + +union sfp_encoding_u { + a_uint8_t val; + struct sfp_encoding bf; +}; + +/*[register] SFP_BR*/ +#define SFP_BR +#define SFP_BR_ADDRESS 0xc +#define SFP_BR_NUM 1 +#define SFP_BR_INC 0x1 +#define SFP_BR_TYPE REG_TYPE_RO +#define SFP_BR_DEFAULT 0x0 + /*[field] BIT*/ + #define SFP_BR_BIT + #define SFP_BR_BIT_OFFSET 0 + #define SFP_BR_BIT_LEN 8 + #define SFP_BR_BIT_DEFAULT 0x0 + +struct sfp_br { + a_uint8_t bit:8; +}; + +union sfp_br_u { + a_uint8_t val; + struct sfp_br bf; +}; + +/*[register] SFP_RATE*/ +#define SFP_RATE +#define SFP_RATE_ADDRESS 0xd +#define SFP_RATE_NUM 1 +#define SFP_RATE_INC 0x1 +#define SFP_RATE_TYPE REG_TYPE_RO +#define SFP_RATE_DEFAULT 0x0 + /*[field] ID*/ + #define SFP_RATE_ID + #define SFP_RATE_ID_OFFSET 0 + #define SFP_RATE_ID_LEN 8 + #define SFP_RATE_ID_DEFAULT 0x0 + +struct sfp_rate { + a_uint8_t id:8; +}; + +union sfp_rate_u { + a_uint8_t val; + struct sfp_rate bf; +}; + +/*[register] SFP_LINK_LEN*/ +#define SFP_LINK_LEN +#define SFP_LINK_LEN_ADDRESS 0xe +#define SFP_LINK_LEN_NUM 1 +#define SFP_LINK_LEN_INC 0x6 +#define SFP_LINK_LEN_TYPE REG_TYPE_RO +#define SFP_LINK_LEN_DEFAULT 0x0 + /*[field] SINGLE_MODE_KM*/ + #define SFP_LINK_LEN_SINGLE_MODE_KM + #define SFP_LINK_LEN_SINGLE_MODE_KM_OFFSET 0 + #define SFP_LINK_LEN_SINGLE_MODE_KM_LEN 8 + #define SFP_LINK_LEN_SINGLE_MODE_KM_DEFAULT 0x0 + /*[field] SINGLE_MODE_100M*/ + #define SFP_LINK_LEN_SINGLE_MODE_100M + #define SFP_LINK_LEN_SINGLE_MODE_100M_OFFSET 8 + #define SFP_LINK_LEN_SINGLE_MODE_100M_LEN 8 + #define SFP_LINK_LEN_SINGLE_MODE_100M_DEFAULT 0x0 + /*[field] OM2_MODE_10M*/ + #define SFP_LINK_LEN_OM2_MODE_10M + #define SFP_LINK_LEN_OM2_MODE_10M_OFFSET 16 + #define SFP_LINK_LEN_OM2_MODE_10M_LEN 8 + #define SFP_LINK_LEN_OM2_MODE_10M_DEFAULT 0x0 + /*[field] OM1_MODE_10M*/ + #define SFP_LINK_LEN_OM1_MODE_10M + #define SFP_LINK_LEN_OM1_MODE_10M_OFFSET 24 + #define SFP_LINK_LEN_OM1_MODE_10M_LEN 8 + #define SFP_LINK_LEN_OM1_MODE_10M_DEFAULT 0x0 + /*[field] COPPER_MODE_1M*/ + #define SFP_LINK_LEN_COPPER_MODE_1M + #define SFP_LINK_LEN_COPPER_MODE_1M_OFFSET 32 + #define SFP_LINK_LEN_COPPER_MODE_1M_LEN 8 + #define SFP_LINK_LEN_COPPER_MODE_1M_DEFAULT 0x0 + /*[field] OM3_MODE_1M*/ + #define SFP_LINK_LEN_OM3_MODE_1M + #define SFP_LINK_LEN_OM3_MODE_1M_OFFSET 40 + #define SFP_LINK_LEN_OM3_MODE_1M_LEN 8 + #define SFP_LINK_LEN_OM3_MODE_1M_DEFAULT 0x0 + +struct sfp_link_len { + a_uint8_t single_mode_km:8; + a_uint8_t single_mode_100m:8; + a_uint8_t om2_mode_10m:8; + a_uint8_t om1_mode_10m:8; + a_uint8_t copper_mode_1m:8; + a_uint8_t om3_mode_1m:8; +}; + +union sfp_link_len_u { + a_uint8_t val[6]; + struct sfp_link_len bf; +}; + +/*[register] SFP_VENDOR*/ +#define SFP_VENDOR +#define SFP_VENDOR_ADDRESS 0x14 +#define SFP_VENDOR_NUM 1 +#define SFP_VENDOR_INC 0x28 +#define SFP_VENDOR_TYPE REG_TYPE_RO +#define SFP_VENDOR_DEFAULT 0x0 + /*[field] NAME*/ + #define SFP_VENDOR_NAME + #define SFP_VENDOR_NAME_OFFSET 0 + #define SFP_VENDOR_NAME_LEN 128 + #define SFP_VENDOR_NAME_DEFAULT 0x0 + /*[field] TRANSCODE*/ + #define SFP_VENDOR_TRANSCODE + #define SFP_VENDOR_TRANSCODE_OFFSET 128 + #define SFP_VENDOR_TRANSCODE_LEN 8 + #define SFP_VENDOR_TRANSCODE_DEFAULT 0x0 + /*[field] OUI*/ + #define SFP_VENDOR_OUI + #define SFP_VENDOR_OUI_OFFSET 136 + #define SFP_VENDOR_OUI_LEN 24 + #define SFP_VENDOR_OUI_DEFAULT 0x0 + /*[field] PN*/ + #define SFP_VENDOR_PN + #define SFP_VENDOR_PN_OFFSET 160 + #define SFP_VENDOR_PN_LEN 128 + #define SFP_VENDOR_PN_DEFAULT 0x0 + /*[field] REV*/ + #define SFP_VENDOR_REV + #define SFP_VENDOR_REV_OFFSET 288 + #define SFP_VENDOR_REV_LEN 32 + #define SFP_VENDOR_REV_DEFAULT 0x0 + +struct sfp_vendor { + a_uint8_t name_0:8; + a_uint8_t name_1:8; + a_uint8_t name_2:8; + a_uint8_t name_3:8; + a_uint8_t name_4:8; + a_uint8_t name_5:8; + a_uint8_t name_6:8; + a_uint8_t name_7:8; + a_uint8_t name_8:8; + a_uint8_t name_9:8; + a_uint8_t name_10:8; + a_uint8_t name_11:8; + a_uint8_t name_12:8; + a_uint8_t name_13:8; + a_uint8_t name_14:8; + a_uint8_t name_15:8; + a_uint8_t transcode:8; + a_uint8_t oui_0:8; + a_uint8_t oui_1:8; + a_uint8_t oui_2:8; + a_uint8_t pn_0:8; + a_uint8_t pn_1:8; + a_uint8_t pn_2:8; + a_uint8_t pn_3:8; + a_uint8_t pn_4:8; + a_uint8_t pn_5:8; + a_uint8_t pn_6:8; + a_uint8_t pn_7:8; + a_uint8_t pn_8:8; + a_uint8_t pn_9:8; + a_uint8_t pn_10:8; + a_uint8_t pn_11:8; + a_uint8_t pn_12:8; + a_uint8_t pn_13:8; + a_uint8_t pn_14:8; + a_uint8_t pn_15:8; + a_uint8_t rev_0:8; + a_uint8_t rev_1:8; + a_uint8_t rev_2:8; + a_uint8_t rev_3:8; +}; + +union sfp_vendor_u { + a_uint8_t val[40]; + struct sfp_vendor bf; +}; + +/*[register] SFP_LASER*/ +#define SFP_LASER +#define SFP_LASER_ADDRESS 0x3c +#define SFP_LASER_NUM 1 +#define SFP_LASER_INC 0x2 +#define SFP_LASER_TYPE REG_TYPE_RO +#define SFP_LASER_DEFAULT 0x0 + /*[field] WAVELENGTH*/ + #define SFP_LASER_WAVELENGTH + #define SFP_LASER_WAVELENGTH_OFFSET 0 + #define SFP_LASER_WAVELENGTH_LEN 16 + #define SFP_LASER_WAVELENGTH_DEFAULT 0x0 + +struct sfp_laser { + a_uint8_t wavelength_0:8; + a_uint8_t wavelength_1:8; +}; + +union sfp_laser_u { + a_uint8_t val[2]; + struct sfp_laser bf; +}; + +/*[register] SFP_BASE*/ +#define SFP_BASE +#define SFP_BASE_ADDRESS 0x3f +#define SFP_BASE_NUM 1 +#define SFP_BASE_INC 0x1 +#define SFP_BASE_TYPE REG_TYPE_RO +#define SFP_BASE_DEFAULT 0x0 + /*[field] CHECK_CODE*/ + #define SFP_BASE_CHECK_CODE + #define SFP_BASE_CHECK_CODE_OFFSET 0 + #define SFP_BASE_CHECK_CODE_LEN 8 + #define SFP_BASE_CHECK_CODE_DEFAULT 0x0 + +struct sfp_base { + a_uint8_t check_code:8; +}; + +union sfp_base_u { + a_uint8_t val; + struct sfp_base bf; +}; + +/*[register] SFP_OPTION*/ +#define SFP_OPTION +#define SFP_OPTION_ADDRESS 0x40 +#define SFP_OPTION_NUM 1 +#define SFP_OPTION_INC 0x2 +#define SFP_OPTION_TYPE REG_TYPE_RO +#define SFP_OPTION_DEFAULT 0x0 + /*[field] LINEAR_RECV_OUTPUT*/ + #define SFP_OPTION_LINEAR_RECV_OUTPUT + #define SFP_OPTION_LINEAR_RECV_OUTPUT_OFFSET 0 + #define SFP_OPTION_LINEAR_RECV_OUTPUT_LEN 1 + #define SFP_OPTION_LINEAR_RECV_OUTPUT_DEFAULT 0x0 + /*[field] PWR_LEVEL_DECLAR*/ + #define SFP_OPTION_PWR_LEVEL_DECLAR + #define SFP_OPTION_PWR_LEVEL_DECLAR_OFFSET 1 + #define SFP_OPTION_PWR_LEVEL_DECLAR_LEN 1 + #define SFP_OPTION_PWR_LEVEL_DECLAR_DEFAULT 0x0 + /*[field] COOL_TRANSC_DECLAR*/ + #define SFP_OPTION_COOL_TRANSC_DECLAR + #define SFP_OPTION_COOL_TRANSC_DECLAR_OFFSET 2 + #define SFP_OPTION_COOL_TRANSC_DECLAR_LEN 1 + #define SFP_OPTION_COOL_TRANSC_DECLAR_DEFAULT 0x0 + /*[field] UNALLOCATED_1*/ + #define SFP_OPTION_UNALLOCATED_1 + #define SFP_OPTION_UNALLOCATED_1_OFFSET 3 + #define SFP_OPTION_UNALLOCATED_1_LEN 5 + #define SFP_OPTION_UNALLOCATED_1_DEFAULT 0x0 + /*[field] UNALLOCATED_2*/ + #define SFP_OPTION_UNALLOCATED_2 + #define SFP_OPTION_UNALLOCATED_2_OFFSET 8 + #define SFP_OPTION_UNALLOCATED_2_LEN 1 + #define SFP_OPTION_UNALLOCATED_2_DEFAULT 0x0 + /*[field] LOSS_SIGNAL*/ + #define SFP_OPTION_LOSS_SIGNAL + #define SFP_OPTION_LOSS_SIGNAL_OFFSET 9 + #define SFP_OPTION_LOSS_SIGNAL_LEN 1 + #define SFP_OPTION_LOSS_SIGNAL_DEFAULT 0x0 + /*[field] LOSS_INVERT_SIGNAL*/ + #define SFP_OPTION_LOSS_INVERT_SIGNAL + #define SFP_OPTION_LOSS_INVERT_SIGNAL_OFFSET 10 + #define SFP_OPTION_LOSS_INVERT_SIGNAL_LEN 1 + #define SFP_OPTION_LOSS_INVERT_SIGNAL_DEFAULT 0x0 + /*[field] TX_FAULT_SIGNAL*/ + #define SFP_OPTION_TX_FAULT_SIGNAL + #define SFP_OPTION_TX_FAULT_SIGNAL_OFFSET 11 + #define SFP_OPTION_TX_FAULT_SIGNAL_LEN 1 + #define SFP_OPTION_TX_FAULT_SIGNAL_DEFAULT 0x0 + /*[field] TX_DISABLE*/ + #define SFP_OPTION_TX_DISABLE + #define SFP_OPTION_TX_DISABLE_OFFSET 12 + #define SFP_OPTION_TX_DISABLE_LEN 1 + #define SFP_OPTION_TX_DISABLE_DEFAULT 0x0 + /*[field] RATE_SEL*/ + #define SFP_OPTION_RATE_SEL + #define SFP_OPTION_RATE_SEL_OFFSET 13 + #define SFP_OPTION_RATE_SEL_LEN 1 + #define SFP_OPTION_RATE_SEL_DEFAULT 0x0 + /*[field] UNALLOCATED_3*/ + #define SFP_OPTION_UNALLOCATED_3 + #define SFP_OPTION_UNALLOCATED_3_OFFSET 14 + #define SFP_OPTION_UNALLOCATED_3_LEN 2 + #define SFP_OPTION_UNALLOCATED_3_DEFAULT 0x0 + +struct sfp_option { + a_uint8_t linear_recv_output:1; + a_uint8_t pwr_level_declar:1; + a_uint8_t cool_transc_declar:1; + a_uint8_t unallocated_1:5; + a_uint8_t unallocated_2:1; + a_uint8_t loss_signal:1; + a_uint8_t loss_invert_signal:1; + a_uint8_t tx_fault_signal:1; + a_uint8_t tx_disable:1; + a_uint8_t rate_sel:1; + a_uint8_t unallocated_3:2; +}; + +union sfp_option_u { + a_uint8_t val[2]; + struct sfp_option bf; +}; + +/*[register] SFP_RATE_CTRL*/ +#define SFP_RATE_CTRL +#define SFP_RATE_CTRL_ADDRESS 0x42 +#define SFP_RATE_CTRL_NUM 1 +#define SFP_RATE_CTRL_INC 0x2 +#define SFP_RATE_CTRL_TYPE REG_TYPE_RO +#define SFP_RATE_CTRL_DEFAULT 0x0 + /*[field] UPPER*/ + #define SFP_RATE_CTRL_UPPER + #define SFP_RATE_CTRL_UPPER_OFFSET 0 + #define SFP_RATE_CTRL_UPPER_LEN 8 + #define SFP_RATE_CTRL_UPPER_DEFAULT 0x0 + /*[field] LOWER*/ + #define SFP_RATE_CTRL_LOWER + #define SFP_RATE_CTRL_LOWER_OFFSET 8 + #define SFP_RATE_CTRL_LOWER_LEN 8 + #define SFP_RATE_CTRL_LOWER_DEFAULT 0x0 + +struct sfp_rate_ctrl { + a_uint8_t upper:8; + a_uint8_t lower:8; +}; + +union sfp_rate_ctrl_u { + a_uint8_t val[2]; + struct sfp_rate_ctrl bf; +}; + +/*[register] SFP_VENDOR_EXT*/ +#define SFP_VENDOR_EXT +#define SFP_VENDOR_EXT_ADDRESS 0x44 +#define SFP_VENDOR_EXT_NUM 1 +#define SFP_VENDOR_EXT_INC 0x18 +#define SFP_VENDOR_EXT_TYPE REG_TYPE_RO +#define SFP_VENDOR_EXT_DEFAULT 0x0 + /*[field] SN*/ + #define SFP_VENDOR_EXT_SN + #define SFP_VENDOR_EXT_SN_OFFSET 0 + #define SFP_VENDOR_EXT_SN_LEN 128 + #define SFP_VENDOR_EXT_SN_DEFAULT 0x0 + /*[field] DATE_CODE*/ + #define SFP_VENDOR_EXT_DATE_CODE + #define SFP_VENDOR_EXT_DATE_CODE_OFFSET 128 + #define SFP_VENDOR_EXT_DATE_CODE_LEN 64 + #define SFP_VENDOR_EXT_DATE_CODE_DEFAULT 0x0 + +struct sfp_vendor_ext { + a_uint8_t sn_0:8; + a_uint8_t sn_1:8; + a_uint8_t sn_2:8; + a_uint8_t sn_3:8; + a_uint8_t sn_4:8; + a_uint8_t sn_5:8; + a_uint8_t sn_6:8; + a_uint8_t sn_7:8; + a_uint8_t sn_8:8; + a_uint8_t sn_9:8; + a_uint8_t sn_10:8; + a_uint8_t sn_11:8; + a_uint8_t sn_12:8; + a_uint8_t sn_13:8; + a_uint8_t sn_14:8; + a_uint8_t sn_15:8; + a_uint8_t date_code_0:8; + a_uint8_t date_code_1:8; + a_uint8_t date_code_2:8; + a_uint8_t date_code_3:8; + a_uint8_t date_code_4:8; + a_uint8_t date_code_5:8; + a_uint8_t date_code_6:8; + a_uint8_t date_code_7:8; +}; + +union sfp_vendor_ext_u { + a_uint8_t val[24]; + struct sfp_vendor_ext bf; +}; + +/*[register] SFP_ENHANCED*/ +#define SFP_ENHANCED +#define SFP_ENHANCED_ADDRESS 0x5c +#define SFP_ENHANCED_NUM 1 +#define SFP_ENHANCED_INC 0x3 +#define SFP_ENHANCED_TYPE REG_TYPE_RO +#define SFP_ENHANCED_DEFAULT 0x0 + /*[field] UNALLOCATED_TYPE*/ + #define SFP_ENHANCED_UNALLOCATED_TYPE + #define SFP_ENHANCED_UNALLOCATED_TYPE_OFFSET 0 + #define SFP_ENHANCED_UNALLOCATED_TYPE_LEN 2 + #define SFP_ENHANCED_UNALLOCATED_TYPE_DEFAULT 0x0 + /*[field] ADDR_MODE*/ + #define SFP_ENHANCED_ADDR_MODE + #define SFP_ENHANCED_ADDR_MODE_OFFSET 2 + #define SFP_ENHANCED_ADDR_MODE_LEN 1 + #define SFP_ENHANCED_ADDR_MODE_DEFAULT 0x0 + /*[field] RE_PWR_TYPE*/ + #define SFP_ENHANCED_RE_PWR_TYPE + #define SFP_ENHANCED_RE_PWR_TYPE_OFFSET 3 + #define SFP_ENHANCED_RE_PWR_TYPE_LEN 1 + #define SFP_ENHANCED_RE_PWR_TYPE_DEFAULT 0x0 + /*[field] EXTERNAL_CAL*/ + #define SFP_ENHANCED_EXTERNAL_CAL + #define SFP_ENHANCED_EXTERNAL_CAL_OFFSET 4 + #define SFP_ENHANCED_EXTERNAL_CAL_LEN 1 + #define SFP_ENHANCED_EXTERNAL_CAL_DEFAULT 0x0 + /*[field] INTERNAL_CAL*/ + #define SFP_ENHANCED_INTERNAL_CAL + #define SFP_ENHANCED_INTERNAL_CAL_OFFSET 5 + #define SFP_ENHANCED_INTERNAL_CAL_LEN 1 + #define SFP_ENHANCED_INTERNAL_CAL_DEFAULT 0x0 + /*[field] DIAG_MON_FLAG*/ + #define SFP_ENHANCED_DIAG_MON_FLAG + #define SFP_ENHANCED_DIAG_MON_FLAG_OFFSET 6 + #define SFP_ENHANCED_DIAG_MON_FLAG_LEN 1 + #define SFP_ENHANCED_DIAG_MON_FLAG_DEFAULT 0x0 + /*[field] LEGACY_TYPE*/ + #define SFP_ENHANCED_LEGACY_TYPE + #define SFP_ENHANCED_LEGACY_TYPE_OFFSET 7 + #define SFP_ENHANCED_LEGACY_TYPE_LEN 1 + #define SFP_ENHANCED_LEGACY_TYPE_DEFAULT 0x0 + /*[field] UNALLOCATED_OP*/ + #define SFP_ENHANCED_UNALLOCATED_OP + #define SFP_ENHANCED_UNALLOCATED_OP_OFFSET 8 + #define SFP_ENHANCED_UNALLOCATED_OP_LEN 1 + #define SFP_ENHANCED_UNALLOCATED_OP_DEFAULT 0x0 + /*[field] SOFT_RATE_SEL_OP*/ + #define SFP_ENHANCED_SOFT_RATE_SEL_OP + #define SFP_ENHANCED_SOFT_RATE_SEL_OP_OFFSET 9 + #define SFP_ENHANCED_SOFT_RATE_SEL_OP_LEN 1 + #define SFP_ENHANCED_SOFT_RATE_SEL_OP_DEFAULT 0x0 + /*[field] APP_SEL_OP*/ + #define SFP_ENHANCED_APP_SEL_OP + #define SFP_ENHANCED_APP_SEL_OP_OFFSET 10 + #define SFP_ENHANCED_APP_SEL_OP_LEN 1 + #define SFP_ENHANCED_APP_SEL_OP_DEFAULT 0x0 + /*[field] SOFT_RATE_CTRL_OP*/ + #define SFP_ENHANCED_SOFT_RATE_CTRL_OP + #define SFP_ENHANCED_SOFT_RATE_CTRL_OP_OFFSET 11 + #define SFP_ENHANCED_SOFT_RATE_CTRL_OP_LEN 1 + #define SFP_ENHANCED_SOFT_RATE_CTRL_OP_DEFAULT 0x0 + /*[field] RX_LOS_OP*/ + #define SFP_ENHANCED_RX_LOS_OP + #define SFP_ENHANCED_RX_LOS_OP_OFFSET 12 + #define SFP_ENHANCED_RX_LOS_OP_LEN 1 + #define SFP_ENHANCED_RX_LOS_OP_DEFAULT 0x0 + /*[field] TX_FAULT_OP*/ + #define SFP_ENHANCED_TX_FAULT_OP + #define SFP_ENHANCED_TX_FAULT_OP_OFFSET 13 + #define SFP_ENHANCED_TX_FAULT_OP_LEN 1 + #define SFP_ENHANCED_TX_FAULT_OP_DEFAULT 0x0 + /*[field] TX_DISABLE_CTRL_OP*/ + #define SFP_ENHANCED_TX_DISABLE_CTRL_OP + #define SFP_ENHANCED_TX_DISABLE_CTRL_OP_OFFSET 14 + #define SFP_ENHANCED_TX_DISABLE_CTRL_OP_LEN 1 + #define SFP_ENHANCED_TX_DISABLE_CTRL_OP_DEFAULT 0x0 + /*[field] ALARM_WARNING_FLAG_OP*/ + #define SFP_ENHANCED_ALARM_WARNING_FLAG_OP + #define SFP_ENHANCED_ALARM_WARNING_FLAG_OP_OFFSET 15 + #define SFP_ENHANCED_ALARM_WARNING_FLAG_OP_LEN 1 + #define SFP_ENHANCED_ALARM_WARNING_FLAG_OP_DEFAULT 0x0 + /*[field] CMPL_FEATURE*/ + #define SFP_ENHANCED_CMPL_FEATURE + #define SFP_ENHANCED_CMPL_FEATURE_OFFSET 16 + #define SFP_ENHANCED_CMPL_FEATURE_LEN 8 + #define SFP_ENHANCED_CMPL_FEATURE_DEFAULT 0x0 + +struct sfp_enhanced { + a_uint8_t unallocated_type:2; + a_uint8_t addr_mode:1; + a_uint8_t re_pwr_type:1; + a_uint8_t external_cal:1; + a_uint8_t internal_cal:1; + a_uint8_t diag_mon_flag:1; + a_uint8_t legacy_type:1; + a_uint8_t unallocated_op:1; + a_uint8_t soft_rate_sel_op:1; + a_uint8_t app_sel_op:1; + a_uint8_t soft_rate_ctrl_op:1; + a_uint8_t rx_los_op:1; + a_uint8_t tx_fault_op:1; + a_uint8_t tx_disable_ctrl_op:1; + a_uint8_t alarm_warning_flag_op:1; + a_uint8_t cmpl_feature:8; +}; + +union sfp_enhanced_u { + a_uint8_t val[3]; + struct sfp_enhanced bf; +}; + +/*[register] SFP_EXT*/ +#define SFP_EXT +#define SFP_EXT_ADDRESS 0x5f +#define SFP_EXT_NUM 1 +#define SFP_EXT_INC 0x1 +#define SFP_EXT_TYPE REG_TYPE_RO +#define SFP_EXT_DEFAULT 0x0 + /*[field] CHECK_CODE*/ + #define SFP_EXT_CHECK_CODE + #define SFP_EXT_CHECK_CODE_OFFSET 0 + #define SFP_EXT_CHECK_CODE_LEN 8 + #define SFP_EXT_CHECK_CODE_DEFAULT 0x0 + +struct sfp_ext { + a_uint8_t check_code:8; +}; + +union sfp_ext_u { + a_uint8_t val; + struct sfp_ext bf; +}; + +/*[register] SFP_DIAG_THRESHOLD*/ +#define SFP_DIAG_THRESHOLD +#define SFP_DIAG_THRESHOLD_ADDRESS 0x0 +#define SFP_DIAG_THRESHOLD_NUM 1 +#define SFP_DIAG_THRESHOLD_INC 0x28 +#define SFP_DIAG_THRESHOLD_TYPE REG_TYPE_RO +#define SFP_DIAG_THRESHOLD_DEFAULT 0x0 + /*[field] TEMP_HIGH_ALARM*/ + #define SFP_DIAG_THRESHOLD_TEMP_HIGH_ALARM + #define SFP_DIAG_THRESHOLD_TEMP_HIGH_ALARM_OFFSET 0 + #define SFP_DIAG_THRESHOLD_TEMP_HIGH_ALARM_LEN 16 + #define SFP_DIAG_THRESHOLD_TEMP_HIGH_ALARM_DEFAULT 0x0 + /*[field] TEMP_LOW_ALARM*/ + #define SFP_DIAG_THRESHOLD_TEMP_LOW_ALARM + #define SFP_DIAG_THRESHOLD_TEMP_LOW_ALARM_OFFSET 16 + #define SFP_DIAG_THRESHOLD_TEMP_LOW_ALARM_LEN 16 + #define SFP_DIAG_THRESHOLD_TEMP_LOW_ALARM_DEFAULT 0x0 + /*[field] TEMP_HIGH_WARNING*/ + #define SFP_DIAG_THRESHOLD_TEMP_HIGH_WARNING + #define SFP_DIAG_THRESHOLD_TEMP_HIGH_WARNING_OFFSET 32 + #define SFP_DIAG_THRESHOLD_TEMP_HIGH_WARNING_LEN 16 + #define SFP_DIAG_THRESHOLD_TEMP_HIGH_WARNING_DEFAULT 0x0 + /*[field] TEMP_LOW_WARNING*/ + #define SFP_DIAG_THRESHOLD_TEMP_LOW_WARNING + #define SFP_DIAG_THRESHOLD_TEMP_LOW_WARNING_OFFSET 48 + #define SFP_DIAG_THRESHOLD_TEMP_LOW_WARNING_LEN 16 + #define SFP_DIAG_THRESHOLD_TEMP_LOW_WARNING_DEFAULT 0x0 + /*[field] VOL_HIGH_ALARM*/ + #define SFP_DIAG_THRESHOLD_VOL_HIGH_ALARM + #define SFP_DIAG_THRESHOLD_VOL_HIGH_ALARM_OFFSET 64 + #define SFP_DIAG_THRESHOLD_VOL_HIGH_ALARM_LEN 16 + #define SFP_DIAG_THRESHOLD_VOL_HIGH_ALARM_DEFAULT 0x0 + /*[field] VOL_LOW_ALARM*/ + #define SFP_DIAG_THRESHOLD_VOL_LOW_ALARM + #define SFP_DIAG_THRESHOLD_VOL_LOW_ALARM_OFFSET 80 + #define SFP_DIAG_THRESHOLD_VOL_LOW_ALARM_LEN 16 + #define SFP_DIAG_THRESHOLD_VOL_LOW_ALARM_DEFAULT 0x0 + /*[field] VOL_HIGH_WARNING*/ + #define SFP_DIAG_THRESHOLD_VOL_HIGH_WARNING + #define SFP_DIAG_THRESHOLD_VOL_HIGH_WARNING_OFFSET 96 + #define SFP_DIAG_THRESHOLD_VOL_HIGH_WARNING_LEN 16 + #define SFP_DIAG_THRESHOLD_VOL_HIGH_WARNING_DEFAULT 0x0 + /*[field] VOL_LOW_WARNING*/ + #define SFP_DIAG_THRESHOLD_VOL_LOW_WARNING + #define SFP_DIAG_THRESHOLD_VOL_LOW_WARNING_OFFSET 112 + #define SFP_DIAG_THRESHOLD_VOL_LOW_WARNING_LEN 16 + #define SFP_DIAG_THRESHOLD_VOL_LOW_WARNING_DEFAULT 0x0 + /*[field] BIAS_HIGH_ALARM*/ + #define SFP_DIAG_THRESHOLD_BIAS_HIGH_ALARM + #define SFP_DIAG_THRESHOLD_BIAS_HIGH_ALARM_OFFSET 128 + #define SFP_DIAG_THRESHOLD_BIAS_HIGH_ALARM_LEN 16 + #define SFP_DIAG_THRESHOLD_BIAS_HIGH_ALARM_DEFAULT 0x0 + /*[field] BIAS_LOW_ALARM*/ + #define SFP_DIAG_THRESHOLD_BIAS_LOW_ALARM + #define SFP_DIAG_THRESHOLD_BIAS_LOW_ALARM_OFFSET 144 + #define SFP_DIAG_THRESHOLD_BIAS_LOW_ALARM_LEN 16 + #define SFP_DIAG_THRESHOLD_BIAS_LOW_ALARM_DEFAULT 0x0 + /*[field] BIAS_HIGH_WARNING*/ + #define SFP_DIAG_THRESHOLD_BIAS_HIGH_WARNING + #define SFP_DIAG_THRESHOLD_BIAS_HIGH_WARNING_OFFSET 160 + #define SFP_DIAG_THRESHOLD_BIAS_HIGH_WARNING_LEN 16 + #define SFP_DIAG_THRESHOLD_BIAS_HIGH_WARNING_DEFAULT 0x0 + /*[field] BIAS_LOW_WARNING*/ + #define SFP_DIAG_THRESHOLD_BIAS_LOW_WARNING + #define SFP_DIAG_THRESHOLD_BIAS_LOW_WARNING_OFFSET 176 + #define SFP_DIAG_THRESHOLD_BIAS_LOW_WARNING_LEN 16 + #define SFP_DIAG_THRESHOLD_BIAS_LOW_WARNING_DEFAULT 0x0 + /*[field] TX_PWR_HIGH_ALARM*/ + #define SFP_DIAG_THRESHOLD_TX_PWR_HIGH_ALARM + #define SFP_DIAG_THRESHOLD_TX_PWR_HIGH_ALARM_OFFSET 192 + #define SFP_DIAG_THRESHOLD_TX_PWR_HIGH_ALARM_LEN 16 + #define SFP_DIAG_THRESHOLD_TX_PWR_HIGH_ALARM_DEFAULT 0x0 + /*[field] TX_PWR_LOW_ALARM*/ + #define SFP_DIAG_THRESHOLD_TX_PWR_LOW_ALARM + #define SFP_DIAG_THRESHOLD_TX_PWR_LOW_ALARM_OFFSET 208 + #define SFP_DIAG_THRESHOLD_TX_PWR_LOW_ALARM_LEN 16 + #define SFP_DIAG_THRESHOLD_TX_PWR_LOW_ALARM_DEFAULT 0x0 + /*[field] TX_PWR_HIGH_WARNING*/ + #define SFP_DIAG_THRESHOLD_TX_PWR_HIGH_WARNING + #define SFP_DIAG_THRESHOLD_TX_PWR_HIGH_WARNING_OFFSET 224 + #define SFP_DIAG_THRESHOLD_TX_PWR_HIGH_WARNING_LEN 16 + #define SFP_DIAG_THRESHOLD_TX_PWR_HIGH_WARNING_DEFAULT 0x0 + /*[field] TX_PWR_LOW_WARNING*/ + #define SFP_DIAG_THRESHOLD_TX_PWR_LOW_WARNING + #define SFP_DIAG_THRESHOLD_TX_PWR_LOW_WARNING_OFFSET 240 + #define SFP_DIAG_THRESHOLD_TX_PWR_LOW_WARNING_LEN 16 + #define SFP_DIAG_THRESHOLD_TX_PWR_LOW_WARNING_DEFAULT 0x0 + /*[field] RX_PWR_HIGH_ALARM*/ + #define SFP_DIAG_THRESHOLD_RX_PWR_HIGH_ALARM + #define SFP_DIAG_THRESHOLD_RX_PWR_HIGH_ALARM_OFFSET 256 + #define SFP_DIAG_THRESHOLD_RX_PWR_HIGH_ALARM_LEN 16 + #define SFP_DIAG_THRESHOLD_RX_PWR_HIGH_ALARM_DEFAULT 0x0 + /*[field] RX_PWR_LOW_ALARM*/ + #define SFP_DIAG_THRESHOLD_RX_PWR_LOW_ALARM + #define SFP_DIAG_THRESHOLD_RX_PWR_LOW_ALARM_OFFSET 272 + #define SFP_DIAG_THRESHOLD_RX_PWR_LOW_ALARM_LEN 16 + #define SFP_DIAG_THRESHOLD_RX_PWR_LOW_ALARM_DEFAULT 0x0 + /*[field] RX_PWR_HIGH_WARNING*/ + #define SFP_DIAG_THRESHOLD_RX_PWR_HIGH_WARNING + #define SFP_DIAG_THRESHOLD_RX_PWR_HIGH_WARNING_OFFSET 288 + #define SFP_DIAG_THRESHOLD_RX_PWR_HIGH_WARNING_LEN 16 + #define SFP_DIAG_THRESHOLD_RX_PWR_HIGH_WARNING_DEFAULT 0x0 + /*[field] RX_PWR_LOW_WARNING*/ + #define SFP_DIAG_THRESHOLD_RX_PWR_LOW_WARNING + #define SFP_DIAG_THRESHOLD_RX_PWR_LOW_WARNING_OFFSET 304 + #define SFP_DIAG_THRESHOLD_RX_PWR_LOW_WARNING_LEN 16 + #define SFP_DIAG_THRESHOLD_RX_PWR_LOW_WARNING_DEFAULT 0x0 + +struct sfp_diag_threshold { + a_uint8_t temp_high_alarm_0:8; + a_uint8_t temp_high_alarm_1:8; + a_uint8_t temp_low_alarm_0:8; + a_uint8_t temp_low_alarm_1:8; + a_uint8_t temp_high_warning_0:8; + a_uint8_t temp_high_warning_1:8; + a_uint8_t temp_low_warning_0:8; + a_uint8_t temp_low_warning_1:8; + a_uint8_t vol_high_alarm_0:8; + a_uint8_t vol_high_alarm_1:8; + a_uint8_t vol_low_alarm_0:8; + a_uint8_t vol_low_alarm_1:8; + a_uint8_t vol_high_warning_0:8; + a_uint8_t vol_high_warning_1:8; + a_uint8_t vol_low_warning_0:8; + a_uint8_t vol_low_warning_1:8; + a_uint8_t bias_high_alarm_0:8; + a_uint8_t bias_high_alarm_1:8; + a_uint8_t bias_low_alarm_0:8; + a_uint8_t bias_low_alarm_1:8; + a_uint8_t bias_high_warning_0:8; + a_uint8_t bias_high_warning_1:8; + a_uint8_t bias_low_warning_0:8; + a_uint8_t bias_low_warning_1:8; + a_uint8_t tx_pwr_high_alarm_0:8; + a_uint8_t tx_pwr_high_alarm_1:8; + a_uint8_t tx_pwr_low_alarm_0:8; + a_uint8_t tx_pwr_low_alarm_1:8; + a_uint8_t tx_pwr_high_warning_0:8; + a_uint8_t tx_pwr_high_warning_1:8; + a_uint8_t tx_pwr_low_warning_0:8; + a_uint8_t tx_pwr_low_warning_1:8; + a_uint8_t rx_pwr_high_alarm_0:8; + a_uint8_t rx_pwr_high_alarm_1:8; + a_uint8_t rx_pwr_low_alarm_0:8; + a_uint8_t rx_pwr_low_alarm_1:8; + a_uint8_t rx_pwr_high_warning_0:8; + a_uint8_t rx_pwr_high_warning_1:8; + a_uint8_t rx_pwr_low_warning_0:8; + a_uint8_t rx_pwr_low_warning_1:8; +}; + +union sfp_diag_threshold_u { + a_uint8_t val[40]; + struct sfp_diag_threshold bf; +}; + +/*[register] SFP_DIAG_CAL_CONST*/ +#define SFP_DIAG_CAL_CONST +#define SFP_DIAG_CAL_CONST_ADDRESS 0x38 +#define SFP_DIAG_CAL_CONST_NUM 1 +#define SFP_DIAG_CAL_CONST_INC 0x24 +#define SFP_DIAG_CAL_CONST_TYPE REG_TYPE_RO +#define SFP_DIAG_CAL_CONST_DEFAULT 0x0 + /*[field] RX_PWR_4*/ + #define SFP_DIAG_CAL_CONST_RX_PWR_4 + #define SFP_DIAG_CAL_CONST_RX_PWR_4_OFFSET 0 + #define SFP_DIAG_CAL_CONST_RX_PWR_4_LEN 32 + #define SFP_DIAG_CAL_CONST_RX_PWR_4_DEFAULT 0x0 + /*[field] RX_PWR_3*/ + #define SFP_DIAG_CAL_CONST_RX_PWR_3 + #define SFP_DIAG_CAL_CONST_RX_PWR_3_OFFSET 32 + #define SFP_DIAG_CAL_CONST_RX_PWR_3_LEN 32 + #define SFP_DIAG_CAL_CONST_RX_PWR_3_DEFAULT 0x0 + /*[field] RX_PWR_2*/ + #define SFP_DIAG_CAL_CONST_RX_PWR_2 + #define SFP_DIAG_CAL_CONST_RX_PWR_2_OFFSET 64 + #define SFP_DIAG_CAL_CONST_RX_PWR_2_LEN 32 + #define SFP_DIAG_CAL_CONST_RX_PWR_2_DEFAULT 0x0 + /*[field] RX_PWR_1*/ + #define SFP_DIAG_CAL_CONST_RX_PWR_1 + #define SFP_DIAG_CAL_CONST_RX_PWR_1_OFFSET 96 + #define SFP_DIAG_CAL_CONST_RX_PWR_1_LEN 32 + #define SFP_DIAG_CAL_CONST_RX_PWR_1_DEFAULT 0x0 + /*[field] RX_PWR_0*/ + #define SFP_DIAG_CAL_CONST_RX_PWR_0 + #define SFP_DIAG_CAL_CONST_RX_PWR_0_OFFSET 128 + #define SFP_DIAG_CAL_CONST_RX_PWR_0_LEN 32 + #define SFP_DIAG_CAL_CONST_RX_PWR_0_DEFAULT 0x0 + /*[field] TX_I_SLOPE*/ + #define SFP_DIAG_CAL_CONST_TX_I_SLOPE + #define SFP_DIAG_CAL_CONST_TX_I_SLOPE_OFFSET 160 + #define SFP_DIAG_CAL_CONST_TX_I_SLOPE_LEN 16 + #define SFP_DIAG_CAL_CONST_TX_I_SLOPE_DEFAULT 0x0 + /*[field] TX_I_OFFSET*/ + #define SFP_DIAG_CAL_CONST_TX_I_OFFSET + #define SFP_DIAG_CAL_CONST_TX_I_OFFSET_OFFSET 176 + #define SFP_DIAG_CAL_CONST_TX_I_OFFSET_LEN 16 + #define SFP_DIAG_CAL_CONST_TX_I_OFFSET_DEFAULT 0x0 + /*[field] TX_PWR_SLOPE*/ + #define SFP_DIAG_CAL_CONST_TX_PWR_SLOPE + #define SFP_DIAG_CAL_CONST_TX_PWR_SLOPE_OFFSET 192 + #define SFP_DIAG_CAL_CONST_TX_PWR_SLOPE_LEN 16 + #define SFP_DIAG_CAL_CONST_TX_PWR_SLOPE_DEFAULT 0x0 + /*[field] TX_PWR_OFFSET*/ + #define SFP_DIAG_CAL_CONST_TX_PWR_OFFSET + #define SFP_DIAG_CAL_CONST_TX_PWR_OFFSET_OFFSET 208 + #define SFP_DIAG_CAL_CONST_TX_PWR_OFFSET_LEN 16 + #define SFP_DIAG_CAL_CONST_TX_PWR_OFFSET_DEFAULT 0x0 + /*[field] T_SLOPE*/ + #define SFP_DIAG_CAL_CONST_T_SLOPE + #define SFP_DIAG_CAL_CONST_T_SLOPE_OFFSET 224 + #define SFP_DIAG_CAL_CONST_T_SLOPE_LEN 16 + #define SFP_DIAG_CAL_CONST_T_SLOPE_DEFAULT 0x0 + /*[field] T_OFFSET*/ + #define SFP_DIAG_CAL_CONST_T_OFFSET + #define SFP_DIAG_CAL_CONST_T_OFFSET_OFFSET 240 + #define SFP_DIAG_CAL_CONST_T_OFFSET_LEN 16 + #define SFP_DIAG_CAL_CONST_T_OFFSET_DEFAULT 0x0 + /*[field] V_SLOPE*/ + #define SFP_DIAG_CAL_CONST_V_SLOPE + #define SFP_DIAG_CAL_CONST_V_SLOPE_OFFSET 256 + #define SFP_DIAG_CAL_CONST_V_SLOPE_LEN 16 + #define SFP_DIAG_CAL_CONST_V_SLOPE_DEFAULT 0x0 + /*[field] V_OFFSET*/ + #define SFP_DIAG_CAL_CONST_V_OFFSET + #define SFP_DIAG_CAL_CONST_V_OFFSET_OFFSET 272 + #define SFP_DIAG_CAL_CONST_V_OFFSET_LEN 16 + #define SFP_DIAG_CAL_CONST_V_OFFSET_DEFAULT 0x0 + +struct sfp_diag_cal_const { + a_uint8_t rx_pwr_4_0:8; + a_uint8_t rx_pwr_4_1:8; + a_uint8_t rx_pwr_4_2:8; + a_uint8_t rx_pwr_4_3:8; + a_uint8_t rx_pwr_3_0:8; + a_uint8_t rx_pwr_3_1:8; + a_uint8_t rx_pwr_3_2:8; + a_uint8_t rx_pwr_3_3:8; + a_uint8_t rx_pwr_2_0:8; + a_uint8_t rx_pwr_2_1:8; + a_uint8_t rx_pwr_2_2:8; + a_uint8_t rx_pwr_2_3:8; + a_uint8_t rx_pwr_1_0:8; + a_uint8_t rx_pwr_1_1:8; + a_uint8_t rx_pwr_1_2:8; + a_uint8_t rx_pwr_1_3:8; + a_uint8_t rx_pwr_0_0:8; + a_uint8_t rx_pwr_0_1:8; + a_uint8_t rx_pwr_0_2:8; + a_uint8_t rx_pwr_0_3:8; + a_uint8_t tx_i_slope_0:8; + a_uint8_t tx_i_slope_1:8; + a_uint8_t tx_i_offset_0:8; + a_uint8_t tx_i_offset_1:8; + a_uint8_t tx_pwr_slope_0:8; + a_uint8_t tx_pwr_slope_1:8; + a_uint8_t tx_pwr_offset_0:8; + a_uint8_t tx_pwr_offset_1:8; + a_uint8_t t_slope_0:8; + a_uint8_t t_slope_1:8; + a_uint8_t t_offset_0:8; + a_uint8_t t_offset_1:8; + a_uint8_t v_slope_0:8; + a_uint8_t v_slope_1:8; + a_uint8_t v_offset_0:8; + a_uint8_t v_offset_1:8; +}; + +union sfp_diag_cal_const_u { + a_uint8_t val[36]; + struct sfp_diag_cal_const bf; +}; + +/*[register] SFP_DIAG_DMI*/ +#define SFP_DIAG_DMI +#define SFP_DIAG_DMI_ADDRESS 0x5f +#define SFP_DIAG_DMI_NUM 1 +#define SFP_DIAG_DMI_INC 0x1 +#define SFP_DIAG_DMI_TYPE REG_TYPE_RO +#define SFP_DIAG_DMI_DEFAULT 0x0 + /*[field] CHECK_CODE*/ + #define SFP_DIAG_DMI_CHECK_CODE + #define SFP_DIAG_DMI_CHECK_CODE_OFFSET 0 + #define SFP_DIAG_DMI_CHECK_CODE_LEN 8 + #define SFP_DIAG_DMI_CHECK_CODE_DEFAULT 0x0 + +struct sfp_diag_dmi { + a_uint8_t check_code:8; +}; + +union sfp_diag_dmi_u { + a_uint8_t val; + struct sfp_diag_dmi bf; +}; + +/*[register] SFP_DIAG_REALTIME*/ +#define SFP_DIAG_REALTIME +#define SFP_DIAG_REALTIME_ADDRESS 0x60 +#define SFP_DIAG_REALTIME_NUM 1 +#define SFP_DIAG_REALTIME_INC 0xa +#define SFP_DIAG_REALTIME_TYPE REG_TYPE_RO +#define SFP_DIAG_REALTIME_DEFAULT 0x0 + /*[field] TMP*/ + #define SFP_DIAG_REALTIME_TMP + #define SFP_DIAG_REALTIME_TMP_OFFSET 0 + #define SFP_DIAG_REALTIME_TMP_LEN 16 + #define SFP_DIAG_REALTIME_TMP_DEFAULT 0x0 + /*[field] VCC*/ + #define SFP_DIAG_REALTIME_VCC + #define SFP_DIAG_REALTIME_VCC_OFFSET 16 + #define SFP_DIAG_REALTIME_VCC_LEN 16 + #define SFP_DIAG_REALTIME_VCC_DEFAULT 0x0 + /*[field] TX_BIAS*/ + #define SFP_DIAG_REALTIME_TX_BIAS + #define SFP_DIAG_REALTIME_TX_BIAS_OFFSET 32 + #define SFP_DIAG_REALTIME_TX_BIAS_LEN 16 + #define SFP_DIAG_REALTIME_TX_BIAS_DEFAULT 0x0 + /*[field] TX_PWR*/ + #define SFP_DIAG_REALTIME_TX_PWR + #define SFP_DIAG_REALTIME_TX_PWR_OFFSET 48 + #define SFP_DIAG_REALTIME_TX_PWR_LEN 16 + #define SFP_DIAG_REALTIME_TX_PWR_DEFAULT 0x0 + /*[field] RX_PWR*/ + #define SFP_DIAG_REALTIME_RX_PWR + #define SFP_DIAG_REALTIME_RX_PWR_OFFSET 64 + #define SFP_DIAG_REALTIME_RX_PWR_LEN 16 + #define SFP_DIAG_REALTIME_RX_PWR_DEFAULT 0x0 + +struct sfp_diag_realtime { + a_uint8_t tmp_0:8; + a_uint8_t tmp_1:8; + a_uint8_t vcc_0:8; + a_uint8_t vcc_1:8; + a_uint8_t tx_bias_0:8; + a_uint8_t tx_bias_1:8; + a_uint8_t tx_pwr_0:8; + a_uint8_t tx_pwr_1:8; + a_uint8_t rx_pwr_0:8; + a_uint8_t rx_pwr_1:8; +}; + +union sfp_diag_realtime_u { + a_uint8_t val[10]; + struct sfp_diag_realtime bf; +}; + +/*[register] SFP_DIAG_OPTIONAL_CTRL_STATUS*/ +#define SFP_DIAG_OPTIONAL_CTRL_STATUS +#define SFP_DIAG_OPTIONAL_CTRL_STATUS_ADDRESS 0x6e +#define SFP_DIAG_OPTIONAL_CTRL_STATUS_NUM 1 +#define SFP_DIAG_OPTIONAL_CTRL_STATUS_INC 0x2 +#define SFP_DIAG_OPTIONAL_CTRL_STATUS_TYPE REG_TYPE_RO +#define SFP_DIAG_OPTIONAL_CTRL_STATUS_DEFAULT 0x0 + /*[field] DATA_READY*/ + #define SFP_DIAG_OPTIONAL_CTRL_STATUS_DATA_READY + #define SFP_DIAG_OPTIONAL_CTRL_STATUS_DATA_READY_OFFSET 0 + #define SFP_DIAG_OPTIONAL_CTRL_STATUS_DATA_READY_LEN 1 + #define SFP_DIAG_OPTIONAL_CTRL_STATUS_DATA_READY_DEFAULT 0x0 + /*[field] RX_LOS*/ + #define SFP_DIAG_OPTIONAL_CTRL_STATUS_RX_LOS + #define SFP_DIAG_OPTIONAL_CTRL_STATUS_RX_LOS_OFFSET 1 + #define SFP_DIAG_OPTIONAL_CTRL_STATUS_RX_LOS_LEN 1 + #define SFP_DIAG_OPTIONAL_CTRL_STATUS_RX_LOS_DEFAULT 0x0 + /*[field] TX_FAULT*/ + #define SFP_DIAG_OPTIONAL_CTRL_STATUS_TX_FAULT + #define SFP_DIAG_OPTIONAL_CTRL_STATUS_TX_FAULT_OFFSET 2 + #define SFP_DIAG_OPTIONAL_CTRL_STATUS_TX_FAULT_LEN 1 + #define SFP_DIAG_OPTIONAL_CTRL_STATUS_TX_FAULT_DEFAULT 0x0 + /*[field] SOFT_RATE_SEL*/ + #define SFP_DIAG_OPTIONAL_CTRL_STATUS_SOFT_RATE_SEL + #define SFP_DIAG_OPTIONAL_CTRL_STATUS_SOFT_RATE_SEL_OFFSET 3 + #define SFP_DIAG_OPTIONAL_CTRL_STATUS_SOFT_RATE_SEL_LEN 1 + #define SFP_DIAG_OPTIONAL_CTRL_STATUS_SOFT_RATE_SEL_DEFAULT 0x0 + /*[field] RATE_SEL*/ + #define SFP_DIAG_OPTIONAL_CTRL_STATUS_RATE_SEL + #define SFP_DIAG_OPTIONAL_CTRL_STATUS_RATE_SEL_OFFSET 4 + #define SFP_DIAG_OPTIONAL_CTRL_STATUS_RATE_SEL_LEN 1 + #define SFP_DIAG_OPTIONAL_CTRL_STATUS_RATE_SEL_DEFAULT 0x0 + /*[field] RS*/ + #define SFP_DIAG_OPTIONAL_CTRL_STATUS_RS + #define SFP_DIAG_OPTIONAL_CTRL_STATUS_RS_OFFSET 5 + #define SFP_DIAG_OPTIONAL_CTRL_STATUS_RS_LEN 1 + #define SFP_DIAG_OPTIONAL_CTRL_STATUS_RS_DEFAULT 0x0 + /*[field] SOFT_TX_DISABLE_SEL*/ + #define SFP_DIAG_OPTIONAL_CTRL_STATUS_SOFT_TX_DISABLE_SEL + #define SFP_DIAG_OPTIONAL_CTRL_STATUS_SOFT_TX_DISABLE_SEL_OFFSET 6 + #define SFP_DIAG_OPTIONAL_CTRL_STATUS_SOFT_TX_DISABLE_SEL_LEN 1 + #define SFP_DIAG_OPTIONAL_CTRL_STATUS_SOFT_TX_DISABLE_SEL_DEFAULT 0x0 + /*[field] TX_DISABLE*/ + #define SFP_DIAG_OPTIONAL_CTRL_STATUS_TX_DISABLE + #define SFP_DIAG_OPTIONAL_CTRL_STATUS_TX_DISABLE_OFFSET 7 + #define SFP_DIAG_OPTIONAL_CTRL_STATUS_TX_DISABLE_LEN 1 + #define SFP_DIAG_OPTIONAL_CTRL_STATUS_TX_DISABLE_DEFAULT 0x0 + +struct sfp_diag_optional_ctrl_status { + a_uint8_t data_ready:1; + a_uint8_t rx_los:1; + a_uint8_t tx_fault:1; + a_uint8_t soft_rate_sel:1; + a_uint8_t rate_sel:1; + a_uint8_t rs:1; + a_uint8_t soft_tx_disable_sel:1; + a_uint8_t tx_disable:1; + a_uint8_t _reserved0:8; +}; + +union sfp_diag_optional_ctrl_status_u { + a_uint8_t val[2]; + struct sfp_diag_optional_ctrl_status bf; +}; + +/*[register] SFP_DIAG_FLAG*/ +#define SFP_DIAG_FLAG +#define SFP_DIAG_FLAG_ADDRESS 0x70 +#define SFP_DIAG_FLAG_NUM 1 +#define SFP_DIAG_FLAG_INC 0x6 +#define SFP_DIAG_FLAG_TYPE REG_TYPE_RO +#define SFP_DIAG_FLAG_DEFAULT 0x0 + /*[field] TX_PWR_LOW_ALARM*/ + #define SFP_DIAG_FLAG_TX_PWR_LOW_ALARM + #define SFP_DIAG_FLAG_TX_PWR_LOW_ALARM_OFFSET 0 + #define SFP_DIAG_FLAG_TX_PWR_LOW_ALARM_LEN 1 + #define SFP_DIAG_FLAG_TX_PWR_LOW_ALARM_DEFAULT 0x0 + /*[field] TX_PWR_HIGH_ALARM*/ + #define SFP_DIAG_FLAG_TX_PWR_HIGH_ALARM + #define SFP_DIAG_FLAG_TX_PWR_HIGH_ALARM_OFFSET 1 + #define SFP_DIAG_FLAG_TX_PWR_HIGH_ALARM_LEN 1 + #define SFP_DIAG_FLAG_TX_PWR_HIGH_ALARM_DEFAULT 0x0 + /*[field] TX_BIAS_LOW_ALARM*/ + #define SFP_DIAG_FLAG_TX_BIAS_LOW_ALARM + #define SFP_DIAG_FLAG_TX_BIAS_LOW_ALARM_OFFSET 2 + #define SFP_DIAG_FLAG_TX_BIAS_LOW_ALARM_LEN 1 + #define SFP_DIAG_FLAG_TX_BIAS_LOW_ALARM_DEFAULT 0x0 + /*[field] TX_BIAS_HIGH_ALARM*/ + #define SFP_DIAG_FLAG_TX_BIAS_HIGH_ALARM + #define SFP_DIAG_FLAG_TX_BIAS_HIGH_ALARM_OFFSET 3 + #define SFP_DIAG_FLAG_TX_BIAS_HIGH_ALARM_LEN 1 + #define SFP_DIAG_FLAG_TX_BIAS_HIGH_ALARM_DEFAULT 0x0 + /*[field] VCC_LOW_ALARM*/ + #define SFP_DIAG_FLAG_VCC_LOW_ALARM + #define SFP_DIAG_FLAG_VCC_LOW_ALARM_OFFSET 4 + #define SFP_DIAG_FLAG_VCC_LOW_ALARM_LEN 1 + #define SFP_DIAG_FLAG_VCC_LOW_ALARM_DEFAULT 0x0 + /*[field] VCC_HIGH_ALARM*/ + #define SFP_DIAG_FLAG_VCC_HIGH_ALARM + #define SFP_DIAG_FLAG_VCC_HIGH_ALARM_OFFSET 5 + #define SFP_DIAG_FLAG_VCC_HIGH_ALARM_LEN 1 + #define SFP_DIAG_FLAG_VCC_HIGH_ALARM_DEFAULT 0x0 + /*[field] TMP_LOW_ALARM*/ + #define SFP_DIAG_FLAG_TMP_LOW_ALARM + #define SFP_DIAG_FLAG_TMP_LOW_ALARM_OFFSET 6 + #define SFP_DIAG_FLAG_TMP_LOW_ALARM_LEN 1 + #define SFP_DIAG_FLAG_TMP_LOW_ALARM_DEFAULT 0x0 + /*[field] TMP_HIGH_ALARM*/ + #define SFP_DIAG_FLAG_TMP_HIGH_ALARM + #define SFP_DIAG_FLAG_TMP_HIGH_ALARM_OFFSET 7 + #define SFP_DIAG_FLAG_TMP_HIGH_ALARM_LEN 1 + #define SFP_DIAG_FLAG_TMP_HIGH_ALARM_DEFAULT 0x0 + /*[field] RX_PWR_LOW_ALARM*/ + #define SFP_DIAG_FLAG_RX_PWR_LOW_ALARM + #define SFP_DIAG_FLAG_RX_PWR_LOW_ALARM_OFFSET 14 + #define SFP_DIAG_FLAG_RX_PWR_LOW_ALARM_LEN 1 + #define SFP_DIAG_FLAG_RX_PWR_LOW_ALARM_DEFAULT 0x0 + /*[field] RX_PWR_HIGH_ALARM*/ + #define SFP_DIAG_FLAG_RX_PWR_HIGH_ALARM + #define SFP_DIAG_FLAG_RX_PWR_HIGH_ALARM_OFFSET 15 + #define SFP_DIAG_FLAG_RX_PWR_HIGH_ALARM_LEN 1 + #define SFP_DIAG_FLAG_RX_PWR_HIGH_ALARM_DEFAULT 0x0 + /*[field] UNALLOCATED*/ + #define SFP_DIAG_FLAG_UNALLOCATED + #define SFP_DIAG_FLAG_UNALLOCATED_OFFSET 16 + #define SFP_DIAG_FLAG_UNALLOCATED_LEN 16 + #define SFP_DIAG_FLAG_UNALLOCATED_DEFAULT 0x0 + /*[field] TX_PWR_LOW_WARNING*/ + #define SFP_DIAG_FLAG_TX_PWR_LOW_WARNING + #define SFP_DIAG_FLAG_TX_PWR_LOW_WARNING_OFFSET 32 + #define SFP_DIAG_FLAG_TX_PWR_LOW_WARNING_LEN 1 + #define SFP_DIAG_FLAG_TX_PWR_LOW_WARNING_DEFAULT 0x0 + /*[field] TX_PWR_HIGH_WARNING*/ + #define SFP_DIAG_FLAG_TX_PWR_HIGH_WARNING + #define SFP_DIAG_FLAG_TX_PWR_HIGH_WARNING_OFFSET 33 + #define SFP_DIAG_FLAG_TX_PWR_HIGH_WARNING_LEN 1 + #define SFP_DIAG_FLAG_TX_PWR_HIGH_WARNING_DEFAULT 0x0 + /*[field] TX_BIAS_LOW_WARNING*/ + #define SFP_DIAG_FLAG_TX_BIAS_LOW_WARNING + #define SFP_DIAG_FLAG_TX_BIAS_LOW_WARNING_OFFSET 34 + #define SFP_DIAG_FLAG_TX_BIAS_LOW_WARNING_LEN 1 + #define SFP_DIAG_FLAG_TX_BIAS_LOW_WARNING_DEFAULT 0x0 + /*[field] TX_BIAS_HIGH_WARNING*/ + #define SFP_DIAG_FLAG_TX_BIAS_HIGH_WARNING + #define SFP_DIAG_FLAG_TX_BIAS_HIGH_WARNING_OFFSET 35 + #define SFP_DIAG_FLAG_TX_BIAS_HIGH_WARNING_LEN 1 + #define SFP_DIAG_FLAG_TX_BIAS_HIGH_WARNING_DEFAULT 0x0 + /*[field] VCC_LOW_WARNING*/ + #define SFP_DIAG_FLAG_VCC_LOW_WARNING + #define SFP_DIAG_FLAG_VCC_LOW_WARNING_OFFSET 36 + #define SFP_DIAG_FLAG_VCC_LOW_WARNING_LEN 1 + #define SFP_DIAG_FLAG_VCC_LOW_WARNING_DEFAULT 0x0 + /*[field] VCC_HIGH_WARNING*/ + #define SFP_DIAG_FLAG_VCC_HIGH_WARNING + #define SFP_DIAG_FLAG_VCC_HIGH_WARNING_OFFSET 37 + #define SFP_DIAG_FLAG_VCC_HIGH_WARNING_LEN 1 + #define SFP_DIAG_FLAG_VCC_HIGH_WARNING_DEFAULT 0x0 + /*[field] TMP_LOW_WARNING*/ + #define SFP_DIAG_FLAG_TMP_LOW_WARNING + #define SFP_DIAG_FLAG_TMP_LOW_WARNING_OFFSET 38 + #define SFP_DIAG_FLAG_TMP_LOW_WARNING_LEN 1 + #define SFP_DIAG_FLAG_TMP_LOW_WARNING_DEFAULT 0x0 + /*[field] TMP_HIGH_WARNING*/ + #define SFP_DIAG_FLAG_TMP_HIGH_WARNING + #define SFP_DIAG_FLAG_TMP_HIGH_WARNING_OFFSET 39 + #define SFP_DIAG_FLAG_TMP_HIGH_WARNING_LEN 1 + #define SFP_DIAG_FLAG_TMP_HIGH_WARNING_DEFAULT 0x0 + /*[field] RX_PWR_LOW_WARNING*/ + #define SFP_DIAG_FLAG_RX_PWR_LOW_WARNING + #define SFP_DIAG_FLAG_RX_PWR_LOW_WARNING_OFFSET 46 + #define SFP_DIAG_FLAG_RX_PWR_LOW_WARNING_LEN 1 + #define SFP_DIAG_FLAG_RX_PWR_LOW_WARNING_DEFAULT 0x0 + /*[field] RX_PWR_HIGH_WARNING*/ + #define SFP_DIAG_FLAG_RX_PWR_HIGH_WARNING + #define SFP_DIAG_FLAG_RX_PWR_HIGH_WARNING_OFFSET 47 + #define SFP_DIAG_FLAG_RX_PWR_HIGH_WARNING_LEN 1 + #define SFP_DIAG_FLAG_RX_PWR_HIGH_WARNING_DEFAULT 0x0 + +struct sfp_diag_flag { + a_uint8_t tx_pwr_low_alarm:1; + a_uint8_t tx_pwr_high_alarm:1; + a_uint8_t tx_bias_low_alarm:1; + a_uint8_t tx_bias_high_alarm:1; + a_uint8_t vcc_low_alarm:1; + a_uint8_t vcc_high_alarm:1; + a_uint8_t tmp_low_alarm:1; + a_uint8_t tmp_high_alarm:1; + a_uint8_t _reserved0:6; + a_uint8_t rx_pwr_low_alarm:1; + a_uint8_t rx_pwr_high_alarm:1; + a_uint8_t unallocated_0:8; + a_uint8_t unallocated_1:8; + a_uint8_t tx_pwr_low_warning:1; + a_uint8_t tx_pwr_high_warning:1; + a_uint8_t tx_bias_low_warning:1; + a_uint8_t tx_bias_high_warning:1; + a_uint8_t vcc_low_warning:1; + a_uint8_t vcc_high_warning:1; + a_uint8_t tmp_low_warning:1; + a_uint8_t tmp_high_warning:1; + a_uint8_t _reserved1:6; + a_uint8_t rx_pwr_low_warning:1; + a_uint8_t rx_pwr_high_warning:1; +}; + +union sfp_diag_flag_u { + a_uint8_t val[6]; + struct sfp_diag_flag bf; +}; + +/*[register] SFP_DIAG_EXTENDED_CTRL_STATUS*/ +#define SFP_DIAG_EXTENDED_CTRL_STATUS +#define SFP_DIAG_EXTENDED_CTRL_STATUS_ADDRESS 0x76 +#define SFP_DIAG_EXTENDED_CTRL_STATUS_NUM 1 +#define SFP_DIAG_EXTENDED_CTRL_STATUS_INC 0x2 +#define SFP_DIAG_EXTENDED_CTRL_STATUS_TYPE REG_TYPE_RO +#define SFP_DIAG_EXTENDED_CTRL_STATUS_DEFAULT 0x0 + /*[field] PWR_LEVEL_SEL*/ + #define SFP_DIAG_EXTENDED_CTRL_STATUS_PWR_LEVEL_SEL + #define SFP_DIAG_EXTENDED_CTRL_STATUS_PWR_LEVEL_SEL_OFFSET 0 + #define SFP_DIAG_EXTENDED_CTRL_STATUS_PWR_LEVEL_SEL_LEN 1 + #define SFP_DIAG_EXTENDED_CTRL_STATUS_PWR_LEVEL_SEL_DEFAULT 0x0 + /*[field] PWR_LEVEL_OP_STATE*/ + #define SFP_DIAG_EXTENDED_CTRL_STATUS_PWR_LEVEL_OP_STATE + #define SFP_DIAG_EXTENDED_CTRL_STATUS_PWR_LEVEL_OP_STATE_OFFSET 1 + #define SFP_DIAG_EXTENDED_CTRL_STATUS_PWR_LEVEL_OP_STATE_LEN 1 + #define SFP_DIAG_EXTENDED_CTRL_STATUS_PWR_LEVEL_OP_STATE_DEFAULT 0x0 + /*[field] SOFT_RS_SEL*/ + #define SFP_DIAG_EXTENDED_CTRL_STATUS_SOFT_RS_SEL + #define SFP_DIAG_EXTENDED_CTRL_STATUS_SOFT_RS_SEL_OFFSET 3 + #define SFP_DIAG_EXTENDED_CTRL_STATUS_SOFT_RS_SEL_LEN 1 + #define SFP_DIAG_EXTENDED_CTRL_STATUS_SOFT_RS_SEL_DEFAULT 0x0 + /*[field] UNALLOCATED*/ + #define SFP_DIAG_EXTENDED_CTRL_STATUS_UNALLOCATED + #define SFP_DIAG_EXTENDED_CTRL_STATUS_UNALLOCATED_OFFSET 4 + #define SFP_DIAG_EXTENDED_CTRL_STATUS_UNALLOCATED_LEN 12 + #define SFP_DIAG_EXTENDED_CTRL_STATUS_UNALLOCATED_DEFAULT 0x0 + +struct sfp_diag_extended_ctrl_status { + a_uint8_t pwr_level_sel:1; + a_uint8_t pwr_level_op_state:1; + a_uint8_t _reserved0:1; + a_uint8_t soft_rs_sel:1; + a_uint8_t unallocated_0:4; + a_uint8_t unallocated_1:8; +}; + +union sfp_diag_extended_ctrl_status_u { + a_uint8_t val[2]; + struct sfp_diag_extended_ctrl_status bf; +}; + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_acl.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_acl.h new file mode 100755 index 000000000..7ad6d9540 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_acl.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 shiva_acl SHIVA_ACL + * @{ + */ +#ifndef _SHIVA_ACL_H_ +#define _SHIVA_ACL_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_acl.h" + + sw_error_t + shiva_acl_init(a_uint32_t dev_id); + + sw_error_t + shiva_acl_reset(a_uint32_t dev_id); + +#ifdef IN_ACL +#define SHIVA_ACL_INIT(rv, dev_id) \ + { \ + rv = shiva_acl_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } + +#define SHIVA_ACL_RESET(rv, dev_id) \ + { \ + rv = shiva_acl_reset(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define SHIVA_ACL_INIT(rv, dev_id) +#define SHIVA_ACL_RESET(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + shiva_acl_list_creat(a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t list_pri); + + + HSL_LOCAL sw_error_t + shiva_acl_list_destroy(a_uint32_t dev_id, a_uint32_t list_id); + + + HSL_LOCAL sw_error_t + shiva_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); + + + HSL_LOCAL sw_error_t + shiva_acl_rule_delete(a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t rule_id, a_uint32_t rule_nr); + + + HSL_LOCAL sw_error_t + shiva_acl_rule_query(a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t rule_id, fal_acl_rule_t * rule); + + + HSL_LOCAL sw_error_t + shiva_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); + + + HSL_LOCAL sw_error_t + shiva_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); + + + HSL_LOCAL sw_error_t + shiva_acl_status_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_acl_status_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + shiva_acl_list_dump(a_uint32_t dev_id); + + + HSL_LOCAL sw_error_t + shiva_acl_rule_dump(a_uint32_t dev_id); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _SHIVA_ACL_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_api.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_api.h new file mode 100755 index 000000000..cdc428d7d --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_api.h @@ -0,0 +1,609 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _SHIVA_API_H_ +#define _SHIVA_API_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifdef IN_PORTCONTROL +#define PORTCONTROL_API \ + SW_API_DEF(SW_API_PT_DUPLEX_GET, shiva_port_duplex_get), \ + SW_API_DEF(SW_API_PT_DUPLEX_SET, shiva_port_duplex_set), \ + SW_API_DEF(SW_API_PT_SPEED_GET, shiva_port_speed_get), \ + SW_API_DEF(SW_API_PT_SPEED_SET, shiva_port_speed_set), \ + SW_API_DEF(SW_API_PT_AN_GET, shiva_port_autoneg_status_get), \ + SW_API_DEF(SW_API_PT_AN_ENABLE, shiva_port_autoneg_enable), \ + SW_API_DEF(SW_API_PT_AN_RESTART, shiva_port_autoneg_restart), \ + SW_API_DEF(SW_API_PT_AN_ADV_GET, shiva_port_autoneg_adv_get), \ + SW_API_DEF(SW_API_PT_AN_ADV_SET, shiva_port_autoneg_adv_set), \ + SW_API_DEF(SW_API_PT_HDR_SET, shiva_port_hdr_status_set), \ + SW_API_DEF(SW_API_PT_HDR_GET, shiva_port_hdr_status_get), \ + SW_API_DEF(SW_API_PT_FLOWCTRL_SET, shiva_port_flowctrl_set), \ + SW_API_DEF(SW_API_PT_FLOWCTRL_GET, shiva_port_flowctrl_get), \ + SW_API_DEF(SW_API_PT_FLOWCTRL_MODE_SET, shiva_port_flowctrl_forcemode_set), \ + SW_API_DEF(SW_API_PT_FLOWCTRL_MODE_GET, shiva_port_flowctrl_forcemode_get), \ + SW_API_DEF(SW_API_PT_POWERSAVE_SET, shiva_port_powersave_set), \ + SW_API_DEF(SW_API_PT_POWERSAVE_GET, shiva_port_powersave_get), \ + SW_API_DEF(SW_API_PT_HIBERNATE_SET, shiva_port_hibernate_set), \ + SW_API_DEF(SW_API_PT_HIBERNATE_GET, shiva_port_hibernate_get), \ + SW_API_DEF(SW_API_PT_CDT, shiva_port_cdt), + + +#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) \ + 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) \ + SW_API_DESC(SW_API_PT_HIBERNATE_SET) \ + SW_API_DESC(SW_API_PT_HIBERNATE_GET) \ + SW_API_DESC(SW_API_PT_CDT) + +#else +#define PORTCONTROL_API +#define PORTCONTROL_API_PARAM +#endif + +#ifdef IN_VLAN +#define VLAN_API \ + SW_API_DEF(SW_API_VLAN_ADD, shiva_vlan_create), \ + SW_API_DEF(SW_API_VLAN_DEL, shiva_vlan_delete), \ + SW_API_DEF(SW_API_VLAN_MEM_UPDATE, shiva_vlan_member_update), \ + SW_API_DEF(SW_API_VLAN_FIND, shiva_vlan_find), \ + SW_API_DEF(SW_API_VLAN_NEXT, shiva_vlan_next), \ + SW_API_DEF(SW_API_VLAN_APPEND, shiva_vlan_entry_append), \ + SW_API_DEF(SW_API_VLAN_FLUSH, shiva_vlan_flush), + +#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) +#else +#define VLAN_API +#define VLAN_API_PARAM +#endif + +#ifdef IN_PORTVLAN +#define PORTVLAN_API \ + SW_API_DEF(SW_API_PT_ING_MODE_GET, shiva_port_1qmode_get), \ + SW_API_DEF(SW_API_PT_ING_MODE_SET, shiva_port_1qmode_set), \ + SW_API_DEF(SW_API_PT_EG_MODE_GET, shiva_port_egvlanmode_get), \ + SW_API_DEF(SW_API_PT_EG_MODE_SET, shiva_port_egvlanmode_set), \ + SW_API_DEF(SW_API_PT_VLAN_MEM_ADD, shiva_portvlan_member_add), \ + SW_API_DEF(SW_API_PT_VLAN_MEM_DEL, shiva_portvlan_member_del), \ + SW_API_DEF(SW_API_PT_VLAN_MEM_UPDATE, shiva_portvlan_member_update), \ + SW_API_DEF(SW_API_PT_VLAN_MEM_GET, shiva_portvlan_member_get), \ + SW_API_DEF(SW_API_PT_FORCE_DEF_VID_SET, shiva_port_force_default_vid_set), \ + SW_API_DEF(SW_API_PT_FORCE_DEF_VID_GET, shiva_port_force_default_vid_get), \ + SW_API_DEF(SW_API_PT_FORCE_PORTVLAN_SET, shiva_port_force_portvlan_set), \ + SW_API_DEF(SW_API_PT_FORCE_PORTVLAN_GET, shiva_port_force_portvlan_get), \ + SW_API_DEF(SW_API_NESTVLAN_TPID_SET, shiva_nestvlan_tpid_set), \ + SW_API_DEF(SW_API_NESTVLAN_TPID_GET, shiva_nestvlan_tpid_get), \ + SW_API_DEF(SW_API_PT_IN_VLAN_MODE_SET, shiva_port_invlan_mode_set), \ + SW_API_DEF(SW_API_PT_IN_VLAN_MODE_GET, shiva_port_invlan_mode_get), \ + SW_API_DEF(SW_API_PT_TLS_SET, shiva_port_tls_set), \ + SW_API_DEF(SW_API_PT_TLS_GET, shiva_port_tls_get), \ + SW_API_DEF(SW_API_PT_PRI_PROPAGATION_SET, shiva_port_pri_propagation_set), \ + SW_API_DEF(SW_API_PT_PRI_PROPAGATION_GET, shiva_port_pri_propagation_get), \ + SW_API_DEF(SW_API_PT_DEF_SVID_SET, shiva_port_default_svid_set), \ + SW_API_DEF(SW_API_PT_DEF_SVID_GET, shiva_port_default_svid_get), \ + SW_API_DEF(SW_API_PT_DEF_CVID_SET, shiva_port_default_cvid_set), \ + SW_API_DEF(SW_API_PT_DEF_CVID_GET, shiva_port_default_cvid_get), \ + SW_API_DEF(SW_API_PT_VLAN_PROPAGATION_SET, shiva_port_vlan_propagation_set), \ + SW_API_DEF(SW_API_PT_VLAN_PROPAGATION_GET, shiva_port_vlan_propagation_get), \ + SW_API_DEF(SW_API_PT_VLAN_TRANS_ADD, shiva_port_vlan_trans_add), \ + SW_API_DEF(SW_API_PT_VLAN_TRANS_DEL, shiva_port_vlan_trans_del), \ + SW_API_DEF(SW_API_PT_VLAN_TRANS_GET, shiva_port_vlan_trans_get), \ + SW_API_DEF(SW_API_QINQ_MODE_SET, shiva_qinq_mode_set), \ + SW_API_DEF(SW_API_QINQ_MODE_GET, shiva_qinq_mode_get), \ + SW_API_DEF(SW_API_PT_QINQ_ROLE_SET, shiva_port_qinq_role_set), \ + SW_API_DEF(SW_API_PT_QINQ_ROLE_GET, shiva_port_qinq_role_get), \ + SW_API_DEF(SW_API_PT_VLAN_TRANS_ITERATE, shiva_port_vlan_trans_iterate), + +#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_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_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) +#else +#define PORTVLAN_API +#define PORTVLAN_API_PARAM +#endif + +#ifdef IN_FDB +#define FDB_API \ + SW_API_DEF(SW_API_FDB_ADD, shiva_fdb_add), \ + SW_API_DEF(SW_API_FDB_DELALL, shiva_fdb_del_all), \ + SW_API_DEF(SW_API_FDB_DELPORT,shiva_fdb_del_by_port), \ + SW_API_DEF(SW_API_FDB_DELMAC, shiva_fdb_del_by_mac), \ + SW_API_DEF(SW_API_FDB_FIRST, shiva_fdb_first), \ + SW_API_DEF(SW_API_FDB_FIND, shiva_fdb_find), \ + SW_API_DEF(SW_API_FDB_PT_LEARN_SET, shiva_fdb_port_learn_set), \ + SW_API_DEF(SW_API_FDB_PT_LEARN_GET, shiva_fdb_port_learn_get), \ + SW_API_DEF(SW_API_FDB_AGE_CTRL_SET, shiva_fdb_age_ctrl_set), \ + SW_API_DEF(SW_API_FDB_AGE_CTRL_GET, shiva_fdb_age_ctrl_get), \ + SW_API_DEF(SW_API_FDB_AGE_TIME_SET, shiva_fdb_age_time_set), \ + SW_API_DEF(SW_API_FDB_AGE_TIME_GET, shiva_fdb_age_time_get), \ + SW_API_DEF(SW_API_FDB_ITERATE, shiva_fdb_iterate), + +#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_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_AGE_CTRL_SET) \ + SW_API_DESC(SW_API_FDB_AGE_CTRL_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) +#else +#define FDB_API +#define FDB_API_PARAM +#endif + +#ifdef IN_ACL +#define ACL_API \ + SW_API_DEF(SW_API_ACL_LIST_CREAT, shiva_acl_list_creat), \ + SW_API_DEF(SW_API_ACL_LIST_DESTROY, shiva_acl_list_destroy), \ + SW_API_DEF(SW_API_ACL_RULE_ADD, shiva_acl_rule_add), \ + SW_API_DEF(SW_API_ACL_RULE_DELETE, shiva_acl_rule_delete), \ + SW_API_DEF(SW_API_ACL_RULE_QUERY, shiva_acl_rule_query), \ + SW_API_DEF(SW_API_ACL_LIST_BIND, shiva_acl_list_bind), \ + SW_API_DEF(SW_API_ACL_LIST_UNBIND, shiva_acl_list_unbind), \ + SW_API_DEF(SW_API_ACL_STATUS_SET, shiva_acl_status_set), \ + SW_API_DEF(SW_API_ACL_STATUS_GET, shiva_acl_status_get), \ + SW_API_DEF(SW_API_ACL_LIST_DUMP, shiva_acl_list_dump), \ + SW_API_DEF(SW_API_ACL_RULE_DUMP, shiva_acl_rule_dump), + +#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) +#else +#define ACL_API +#define ACL_API_PARAM +#endif + +#ifdef IN_QOS +#define QOS_API \ + SW_API_DEF(SW_API_QOS_QU_TX_BUF_ST_SET, shiva_qos_queue_tx_buf_status_set), \ + SW_API_DEF(SW_API_QOS_QU_TX_BUF_ST_GET, shiva_qos_queue_tx_buf_status_get), \ + SW_API_DEF(SW_API_QOS_QU_TX_BUF_NR_SET, shiva_qos_queue_tx_buf_nr_set), \ + SW_API_DEF(SW_API_QOS_QU_TX_BUF_NR_GET, shiva_qos_queue_tx_buf_nr_get), \ + SW_API_DEF(SW_API_QOS_PT_TX_BUF_ST_SET, shiva_qos_port_tx_buf_status_set), \ + SW_API_DEF(SW_API_QOS_PT_TX_BUF_ST_GET, shiva_qos_port_tx_buf_status_get), \ + SW_API_DEF(SW_API_QOS_PT_TX_BUF_NR_SET, shiva_qos_port_tx_buf_nr_set), \ + SW_API_DEF(SW_API_QOS_PT_TX_BUF_NR_GET, shiva_qos_port_tx_buf_nr_get), \ + SW_API_DEF(SW_API_QOS_PT_RX_BUF_NR_SET, shiva_qos_port_rx_buf_nr_set), \ + SW_API_DEF(SW_API_QOS_PT_RX_BUF_NR_GET, shiva_qos_port_rx_buf_nr_get), \ + SW_API_DEF(SW_API_COSMAP_UP_QU_SET, shiva_cosmap_up_queue_set), \ + SW_API_DEF(SW_API_COSMAP_UP_QU_GET, shiva_cosmap_up_queue_get), \ + SW_API_DEF(SW_API_COSMAP_DSCP_QU_SET, shiva_cosmap_dscp_queue_set), \ + SW_API_DEF(SW_API_COSMAP_DSCP_QU_GET, shiva_cosmap_dscp_queue_get), \ + SW_API_DEF(SW_API_QOS_PT_MODE_SET, shiva_qos_port_mode_set), \ + SW_API_DEF(SW_API_QOS_PT_MODE_GET, shiva_qos_port_mode_get), \ + SW_API_DEF(SW_API_QOS_PT_MODE_PRI_SET, shiva_qos_port_mode_pri_set), \ + SW_API_DEF(SW_API_QOS_PT_MODE_PRI_GET, shiva_qos_port_mode_pri_get), \ + SW_API_DEF(SW_API_QOS_PORT_DEF_UP_SET, shiva_qos_port_default_up_set), \ + SW_API_DEF(SW_API_QOS_PORT_DEF_UP_GET, shiva_qos_port_default_up_get), \ + SW_API_DEF(SW_API_QOS_PORT_SCH_MODE_SET, shiva_qos_port_sch_mode_set), \ + SW_API_DEF(SW_API_QOS_PORT_SCH_MODE_GET, shiva_qos_port_sch_mode_get), + +#define QOS_API_PARAM \ + 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_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) +#else +#define QOS_API +#define QOS_API_PARAM +#endif + +#ifdef IN_IGMP +#define IGMP_API \ + SW_API_DEF(SW_API_PT_IGMPS_MODE_SET, shiva_port_igmps_status_set), \ + SW_API_DEF(SW_API_PT_IGMPS_MODE_GET, shiva_port_igmps_status_get), \ + SW_API_DEF(SW_API_IGMP_MLD_CMD_SET, shiva_igmp_mld_cmd_set), \ + SW_API_DEF(SW_API_IGMP_MLD_CMD_GET, shiva_igmp_mld_cmd_get), \ + SW_API_DEF(SW_API_IGMP_PT_JOIN_SET, shiva_port_igmp_mld_join_set), \ + SW_API_DEF(SW_API_IGMP_PT_JOIN_GET, shiva_port_igmp_mld_join_get), \ + SW_API_DEF(SW_API_IGMP_PT_LEAVE_SET, shiva_port_igmp_mld_leave_set), \ + SW_API_DEF(SW_API_IGMP_PT_LEAVE_GET, shiva_port_igmp_mld_leave_get), \ + SW_API_DEF(SW_API_IGMP_RP_SET, shiva_igmp_mld_rp_set), \ + SW_API_DEF(SW_API_IGMP_RP_GET, shiva_igmp_mld_rp_get), \ + SW_API_DEF(SW_API_IGMP_ENTRY_CREAT_SET, shiva_igmp_mld_entry_creat_set), \ + SW_API_DEF(SW_API_IGMP_ENTRY_CREAT_GET, shiva_igmp_mld_entry_creat_get), \ + SW_API_DEF(SW_API_IGMP_ENTRY_STATIC_SET, shiva_igmp_mld_entry_static_set), \ + SW_API_DEF(SW_API_IGMP_ENTRY_STATIC_GET, shiva_igmp_mld_entry_static_get), \ + SW_API_DEF(SW_API_IGMP_ENTRY_LEAKY_SET, shiva_igmp_mld_entry_leaky_set), \ + SW_API_DEF(SW_API_IGMP_ENTRY_LEAKY_GET, shiva_igmp_mld_entry_leaky_get), \ + SW_API_DEF(SW_API_IGMP_ENTRY_V3_SET, shiva_igmp_mld_entry_v3_set), \ + SW_API_DEF(SW_API_IGMP_ENTRY_V3_GET, shiva_igmp_mld_entry_v3_get), \ + SW_API_DEF(SW_API_IGMP_ENTRY_QUEUE_SET, shiva_igmp_mld_entry_queue_set), \ + SW_API_DEF(SW_API_IGMP_ENTRY_QUEUE_GET, shiva_igmp_mld_entry_queue_get), + +#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) +#else +#define IGMP_API +#define IGMP_API_PARAM +#endif + +#ifdef IN_LEAKY +#define LEAKY_API \ + SW_API_DEF(SW_API_UC_LEAKY_MODE_SET, shiva_uc_leaky_mode_set), \ + SW_API_DEF(SW_API_UC_LEAKY_MODE_GET, shiva_uc_leaky_mode_get), \ + SW_API_DEF(SW_API_MC_LEAKY_MODE_SET, shiva_mc_leaky_mode_set), \ + SW_API_DEF(SW_API_MC_LEAKY_MODE_GET, shiva_mc_leaky_mode_get), \ + SW_API_DEF(SW_API_ARP_LEAKY_MODE_SET, shiva_port_arp_leaky_set), \ + SW_API_DEF(SW_API_ARP_LEAKY_MODE_GET, shiva_port_arp_leaky_get), \ + SW_API_DEF(SW_API_PT_UC_LEAKY_MODE_SET, shiva_port_uc_leaky_set), \ + SW_API_DEF(SW_API_PT_UC_LEAKY_MODE_GET, shiva_port_uc_leaky_get), \ + SW_API_DEF(SW_API_PT_MC_LEAKY_MODE_SET, shiva_port_mc_leaky_set), \ + SW_API_DEF(SW_API_PT_MC_LEAKY_MODE_GET, shiva_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, shiva_mirr_analysis_port_set), \ + SW_API_DEF(SW_API_MIRROR_ANALY_PT_GET, shiva_mirr_analysis_port_get), \ + SW_API_DEF(SW_API_MIRROR_IN_PT_SET, shiva_mirr_port_in_set), \ + SW_API_DEF(SW_API_MIRROR_IN_PT_GET, shiva_mirr_port_in_get), \ + SW_API_DEF(SW_API_MIRROR_EG_PT_SET, shiva_mirr_port_eg_set), \ + SW_API_DEF(SW_API_MIRROR_EG_PT_GET, shiva_mirr_port_eg_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) +#else +#define MIRROR_API +#define MIRROR_API_PARAM +#endif + +#ifdef IN_RATE +#define RATE_API \ + SW_API_DEF(SW_API_RATE_QU_EGRL_SET, shiva_rate_queue_egrl_set), \ + SW_API_DEF(SW_API_RATE_QU_EGRL_GET, shiva_rate_queue_egrl_get), \ + SW_API_DEF(SW_API_RATE_PT_EGRL_SET, shiva_rate_port_egrl_set), \ + SW_API_DEF(SW_API_RATE_PT_EGRL_GET, shiva_rate_port_egrl_get), \ + SW_API_DEF(SW_API_RATE_PT_INRL_SET, shiva_rate_port_inrl_set), \ + SW_API_DEF(SW_API_RATE_PT_INRL_GET, shiva_rate_port_inrl_get), \ + SW_API_DEF(SW_API_STORM_CTRL_FRAME_SET, shiva_storm_ctrl_frame_set), \ + SW_API_DEF(SW_API_STORM_CTRL_FRAME_GET, shiva_storm_ctrl_frame_get), \ + SW_API_DEF(SW_API_STORM_CTRL_RATE_SET, shiva_storm_ctrl_rate_set), \ + SW_API_DEF(SW_API_STORM_CTRL_RATE_GET, shiva_storm_ctrl_rate_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) +#else +#define RATE_API +#define RATE_API_PARAM +#endif + +#ifdef IN_STP +#define STP_API \ + SW_API_DEF(SW_API_STP_PT_STATE_SET, shiva_stp_port_state_set), \ + SW_API_DEF(SW_API_STP_PT_STATE_GET, shiva_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, shiva_get_mib_info), \ + SW_API_DEF(SW_API_MIB_STATUS_SET, shiva_mib_status_set), \ + SW_API_DEF(SW_API_MIB_STATUS_GET, shiva_mib_status_get), + +#define MIB_API_PARAM \ + SW_API_DESC(SW_API_PT_MIB_GET) \ + SW_API_DESC(SW_API_MIB_STATUS_SET) \ + SW_API_DESC(SW_API_MIB_STATUS_GET) +#else +#define MIB_API +#define MIB_API_PARAM +#endif + +#ifdef IN_MISC +#define MISC_API \ + SW_API_DEF(SW_API_ARP_STATUS_SET, shiva_arp_status_set), \ + SW_API_DEF(SW_API_ARP_STATUS_GET, shiva_arp_status_get), \ + SW_API_DEF(SW_API_FRAME_MAX_SIZE_SET, shiva_frame_max_size_set), \ + SW_API_DEF(SW_API_FRAME_MAX_SIZE_GET, shiva_frame_max_size_get), \ + SW_API_DEF(SW_API_PT_UNK_SA_CMD_SET, shiva_port_unk_sa_cmd_set), \ + SW_API_DEF(SW_API_PT_UNK_SA_CMD_GET, shiva_port_unk_sa_cmd_get), \ + SW_API_DEF(SW_API_PT_UNK_UC_FILTER_SET, shiva_port_unk_uc_filter_set), \ + SW_API_DEF(SW_API_PT_UNK_UC_FILTER_GET, shiva_port_unk_uc_filter_get), \ + SW_API_DEF(SW_API_PT_UNK_MC_FILTER_SET, shiva_port_unk_mc_filter_set), \ + SW_API_DEF(SW_API_PT_UNK_MC_FILTER_GET, shiva_port_unk_mc_filter_get), \ + SW_API_DEF(SW_API_PT_BC_FILTER_SET, shiva_port_bc_filter_set), \ + SW_API_DEF(SW_API_PT_BC_FILTER_GET, shiva_port_bc_filter_get), \ + SW_API_DEF(SW_API_CPU_PORT_STATUS_SET, shiva_cpu_port_status_set), \ + SW_API_DEF(SW_API_CPU_PORT_STATUS_GET, shiva_cpu_port_status_get), \ + SW_API_DEF(SW_API_PPPOE_CMD_SET, shiva_pppoe_cmd_set), \ + SW_API_DEF(SW_API_PPPOE_CMD_GET, shiva_pppoe_cmd_get), \ + SW_API_DEF(SW_API_PPPOE_STATUS_SET, shiva_pppoe_status_set), \ + SW_API_DEF(SW_API_PPPOE_STATUS_GET, shiva_pppoe_status_get), \ + SW_API_DEF(SW_API_PT_DHCP_SET, shiva_port_dhcp_set), \ + SW_API_DEF(SW_API_PT_DHCP_GET, shiva_port_dhcp_get), \ + SW_API_DEF(SW_API_ARP_CMD_SET, shiva_arp_cmd_set), \ + SW_API_DEF(SW_API_ARP_CMD_GET, shiva_arp_cmd_get), \ + SW_API_DEF(SW_API_EAPOL_CMD_SET, shiva_eapol_cmd_set), \ + SW_API_DEF(SW_API_EAPOL_CMD_GET, shiva_eapol_cmd_get), \ + SW_API_DEF(SW_API_PPPOE_SESSION_ADD, shiva_pppoe_session_add), \ + SW_API_DEF(SW_API_PPPOE_SESSION_DEL, shiva_pppoe_session_del), \ + SW_API_DEF(SW_API_PPPOE_SESSION_GET, shiva_pppoe_session_get), \ + SW_API_DEF(SW_API_EAPOL_STATUS_SET, shiva_eapol_status_set), \ + SW_API_DEF(SW_API_EAPOL_STATUS_GET, shiva_eapol_status_get), \ + SW_API_DEF(SW_API_RIPV1_STATUS_SET, shiva_ripv1_status_set), \ + SW_API_DEF(SW_API_RIPV1_STATUS_GET, shiva_ripv1_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_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_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_PPPOE_SESSION_ADD) \ + SW_API_DESC(SW_API_PPPOE_SESSION_DEL) \ + SW_API_DESC(SW_API_PPPOE_SESSION_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) +#else +#define MISC_API +#define MISC_API_PARAM +#endif + +#ifdef IN_LED +#define LED_API \ + SW_API_DEF(SW_API_LED_PATTERN_SET, shiva_led_ctrl_pattern_set), \ + SW_API_DEF(SW_API_LED_PATTERN_GET, shiva_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 + +#define REG_API \ + SW_API_DEF(SW_API_PHY_GET, shiva_phy_get), \ + SW_API_DEF(SW_API_PHY_SET, shiva_phy_set), \ + SW_API_DEF(SW_API_REG_GET, shiva_reg_get), \ + SW_API_DEF(SW_API_REG_SET, shiva_reg_set), \ + SW_API_DEF(SW_API_REG_FIELD_GET, shiva_reg_field_get), \ + SW_API_DEF(SW_API_REG_FIELD_SET, shiva_reg_field_set), + +#define REG_API_PARAM \ + SW_API_DESC(SW_API_PHY_GET) \ + SW_API_DESC(SW_API_PHY_SET) \ + SW_API_DESC(SW_API_REG_GET) \ + SW_API_DESC(SW_API_REG_SET) \ + SW_API_DESC(SW_API_REG_FIELD_GET) \ + SW_API_DESC(SW_API_REG_FIELD_SET) + +#define SSDK_API \ + SW_API_DEF(SW_API_SWITCH_RESET, shiva_reset), \ + SW_API_DEF(SW_API_SSDK_CFG, hsl_ssdk_cfg), \ + PORTCONTROL_API \ + 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 \ + REG_API \ + SW_API_DEF(SW_API_MAX, NULL), + + +#define SSDK_PARAM \ + 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"), \ + MIB_API_PARAM \ + LEAKY_API_PARAM \ + MISC_API_PARAM \ + IGMP_API_PARAM \ + MIRROR_API_PARAM \ + PORTCONTROL_API_PARAM \ + PORTVLAN_API_PARAM \ + VLAN_API_PARAM \ + FDB_API_PARAM \ + QOS_API_PARAM \ + RATE_API_PARAM \ + STP_API_PARAM \ + ACL_API_PARAM \ + LED_API_PARAM \ + REG_API_PARAM \ + SW_PARAM_DEF(SW_API_MAX, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), + +#if (defined(USER_MODE) && defined(KERNEL_MODULE)) +#undef SSDK_API +#undef SSDK_PARAM + +#define SSDK_API \ + REG_API \ + SW_API_DEF(SW_API_MAX, NULL), + +#define SSDK_PARAM \ + REG_API_PARAM \ + SW_PARAM_DEF(SW_API_MAX, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _SHIVA_API_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_fdb.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_fdb.h new file mode 100755 index 000000000..f5e450e17 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_fdb.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 shiva_fdb SHIVA_FDB + * @{ + */ +#ifndef _SHIVA_FDB_H_ +#define _SHIVA_FDB_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_fdb.h" + + sw_error_t + shiva_fdb_init(a_uint32_t dev_id); + +#ifdef IN_FDB +#define SHIVA_FDB_INIT(rv, dev_id) \ + { \ + rv = shiva_fdb_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define SHIVA_FDB_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + shiva_fdb_add(a_uint32_t dev_id, const fal_fdb_entry_t * entry); + + + HSL_LOCAL sw_error_t + shiva_fdb_del_all(a_uint32_t dev_id, a_uint32_t flag); + + + HSL_LOCAL sw_error_t + shiva_fdb_del_by_port(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t flag); + + + HSL_LOCAL sw_error_t + shiva_fdb_del_by_mac(a_uint32_t dev_id, + const fal_fdb_entry_t *entry); + + + HSL_LOCAL sw_error_t + shiva_fdb_first(a_uint32_t dev_id, fal_fdb_entry_t * entry); + + + HSL_LOCAL sw_error_t + shiva_fdb_find(a_uint32_t dev_id, fal_fdb_entry_t * entry); + + + HSL_LOCAL sw_error_t + shiva_fdb_port_learn_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_fdb_port_learn_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable); + + + HSL_LOCAL sw_error_t + shiva_fdb_age_ctrl_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_fdb_age_ctrl_get(a_uint32_t dev_id, a_bool_t *enable); + + + HSL_LOCAL sw_error_t + shiva_fdb_age_time_set(a_uint32_t dev_id, a_uint32_t * time); + + + HSL_LOCAL sw_error_t + shiva_fdb_age_time_get(a_uint32_t dev_id, a_uint32_t * time); + + + HSL_LOCAL sw_error_t + shiva_fdb_iterate(a_uint32_t dev_id, a_uint32_t * iterator, fal_fdb_entry_t * entry); + + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _SHIVA_FDB_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_igmp.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_igmp.h new file mode 100755 index 000000000..cfae2f764 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_igmp.h @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 shiva_igmp SHIVA_IGMP + * @{ + */ +#ifndef _SHIVA_IGMP_H_ +#define _SHIVA_IGMP_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_igmp.h" + + sw_error_t + shiva_igmp_init(a_uint32_t dev_id); + +#ifdef IN_IGMP +#define SHIVA_IGMP_INIT(rv, dev_id) \ + { \ + rv = shiva_igmp_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define SHIVA_IGMP_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + shiva_port_igmps_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_port_igmps_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable); + + + HSL_LOCAL sw_error_t + shiva_igmp_mld_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + + HSL_LOCAL sw_error_t + shiva_igmp_mld_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + + HSL_LOCAL sw_error_t + shiva_port_igmp_mld_join_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_port_igmp_mld_join_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + shiva_port_igmp_mld_leave_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_port_igmp_mld_leave_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + shiva_igmp_mld_rp_set(a_uint32_t dev_id, fal_pbmp_t pts); + + + HSL_LOCAL sw_error_t + shiva_igmp_mld_rp_get(a_uint32_t dev_id, fal_pbmp_t * pts); + + + HSL_LOCAL sw_error_t + shiva_igmp_mld_entry_creat_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_igmp_mld_entry_creat_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + shiva_igmp_mld_entry_static_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_igmp_mld_entry_static_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + shiva_igmp_mld_entry_leaky_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_igmp_mld_entry_leaky_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + shiva_igmp_mld_entry_v3_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_igmp_mld_entry_v3_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + shiva_igmp_mld_entry_queue_set(a_uint32_t dev_id, a_bool_t enable, a_uint32_t queue); + + + HSL_LOCAL sw_error_t + shiva_igmp_mld_entry_queue_get(a_uint32_t dev_id, a_bool_t * enable, a_uint32_t * queue); + + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _SHIVA_IGMP_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_init.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_init.h new file mode 100755 index 000000000..8610ec098 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_init.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 shiva_init SHIVA_INIT + * @{ + */ +#ifndef _SHIVA_INIT_H_ +#define _SHIVA_INIT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "init/ssdk_init.h" + + + sw_error_t + shiva_init(a_uint32_t dev_id, ssdk_init_cfg *cfg); + + + sw_error_t + shiva_cleanup(a_uint32_t dev_id); + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + shiva_reset(a_uint32_t dev_id); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _SHIVA_INIT_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_leaky.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_leaky.h new file mode 100755 index 000000000..6cd53b24e --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_leaky.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 shiva_leaky SHIVA_LEAKY + * @{ + */ +#ifndef _SHIVA_LEAKY_H_ +#define _SHIVA_LEAKY_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_leaky.h" + + sw_error_t shiva_leaky_init(a_uint32_t dev_id); + +#ifdef IN_LEAKY +#define SHIVA_LEAKY_INIT(rv, dev_id) \ + { \ + rv = shiva_leaky_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define SHIVA_LEAKY_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + shiva_uc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode); + + + HSL_LOCAL sw_error_t + shiva_uc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t * ctrl_mode); + + + HSL_LOCAL sw_error_t + shiva_mc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode); + + + HSL_LOCAL sw_error_t + shiva_mc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t * ctrl_mode); + + + HSL_LOCAL sw_error_t + shiva_port_arp_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_port_arp_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + shiva_port_uc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_port_uc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + shiva_port_mc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_port_mc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _SHIVA_LEAKY_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_led.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_led.h new file mode 100755 index 000000000..a75369fba --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_led.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _SHIVA_LED_H_ +#define _SHIVA_LED_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_led.h" + + sw_error_t + shiva_led_init(a_uint32_t dev_id); + +#ifdef IN_LED +#define SHIVA_LED_INIT(rv, dev_id) \ + { \ + rv = shiva_led_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define SHIVA_LED_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + shiva_led_ctrl_pattern_set(a_uint32_t dev_id, led_pattern_group_t group, + led_pattern_id_t id, led_ctrl_pattern_t * pattern); + + + HSL_LOCAL sw_error_t + shiva_led_ctrl_pattern_get(a_uint32_t dev_id, led_pattern_group_t group, + led_pattern_id_t id, led_ctrl_pattern_t * pattern); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _SHIVA_LED_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_mib.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_mib.h new file mode 100755 index 000000000..0b91b5b35 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_mib.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 shiva_mib SHIVA_MIB + * @{ + */ +#ifndef _SHIVA_MIB_H_ +#define _SHIVA_MIB_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_mib.h" + + sw_error_t + shiva_mib_init(a_uint32_t dev_id); + +#ifdef IN_MIB +#define SHIVA_MIB_INIT(rv, dev_id) \ + { \ + rv = shiva_mib_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define SHIVA_MIB_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + shiva_get_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info ); + + + HSL_LOCAL sw_error_t + shiva_mib_status_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_mib_status_get(a_uint32_t dev_id, a_bool_t * enable); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _SHIVA_MIB_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_mirror.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_mirror.h new file mode 100755 index 000000000..d889fd597 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_mirror.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 shiva_mirror SHIVA_MIRROR + * @{ + */ +#ifndef _SHIVA_MIRROR_H_ +#define _SHIVA_MIRROR_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_mirror.h" +#define MIRROR_ANALYZER_NONE 0xf + + sw_error_t shiva_mirr_init(a_uint32_t dev_id); + +#ifdef IN_MIRROR +#define SHIVA_MIRR_INIT(rv, dev_id) \ + { \ + rv = shiva_mirr_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define SHIVA_MIRR_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + shiva_mirr_analysis_port_set(a_uint32_t dev_id, fal_port_t port_id); + + + HSL_LOCAL sw_error_t + shiva_mirr_analysis_port_get(a_uint32_t dev_id, fal_port_t * port_id); + + + HSL_LOCAL sw_error_t + shiva_mirr_port_in_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_mirr_port_in_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + shiva_mirr_port_eg_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_mirr_port_eg_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _SHIVA_MIRROR_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_misc.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_misc.h new file mode 100755 index 000000000..5c4fdbd2e --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_misc.h @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 shiva_misc SHIVA_MISC + * @{ + */ +#ifndef _SHIVA_MISC_H_ +#define _SHIVA_MISC_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_misc.h" + + sw_error_t shiva_misc_init(a_uint32_t dev_id); + +#ifdef IN_MISC +#define SHIVA_MISC_INIT(rv, dev_id) \ + { \ + rv = shiva_misc_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define SHIVA_MISC_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + HSL_LOCAL sw_error_t + shiva_arp_status_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_arp_status_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + shiva_frame_max_size_set(a_uint32_t dev_id, a_uint32_t size); + + + HSL_LOCAL sw_error_t + shiva_frame_max_size_get(a_uint32_t dev_id, a_uint32_t * size); + + + HSL_LOCAL sw_error_t + shiva_port_unk_sa_cmd_set(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t cmd); + + + HSL_LOCAL sw_error_t + shiva_port_unk_sa_cmd_get(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t * cmd); + + + HSL_LOCAL sw_error_t + shiva_port_unk_uc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_port_unk_uc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + shiva_port_unk_mc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_port_unk_mc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + shiva_port_bc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_port_bc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + shiva_cpu_port_status_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_cpu_port_status_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + shiva_pppoe_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + + HSL_LOCAL sw_error_t + shiva_pppoe_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + + HSL_LOCAL sw_error_t + shiva_pppoe_status_set(a_uint32_t dev_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_pppoe_status_get(a_uint32_t dev_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + shiva_port_dhcp_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_port_dhcp_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + shiva_arp_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + + HSL_LOCAL sw_error_t + shiva_arp_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + + HSL_LOCAL sw_error_t + shiva_eapol_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + + HSL_LOCAL sw_error_t + shiva_eapol_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + + HSL_LOCAL sw_error_t + shiva_pppoe_session_add(a_uint32_t dev_id, a_uint32_t session_id, a_bool_t strip_hdr); + + + HSL_LOCAL sw_error_t + shiva_pppoe_session_del(a_uint32_t dev_id, a_uint32_t session_id); + + + HSL_LOCAL sw_error_t + shiva_pppoe_session_get(a_uint32_t dev_id, a_uint32_t session_id, a_bool_t * strip_hdr); + + HSL_LOCAL sw_error_t + shiva_eapol_status_set(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + shiva_eapol_status_get(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + shiva_ripv1_status_set(a_uint32_t dev_id, a_bool_t enable); + + HSL_LOCAL sw_error_t + shiva_ripv1_status_get(a_uint32_t dev_id, a_bool_t * enable); + + HSL_LOCAL sw_error_t + shiva_loop_check_status_set(a_uint32_t dev_id, fal_loop_check_time_t time, a_bool_t enable); + + HSL_LOCAL sw_error_t + shiva_loop_check_status_get(a_uint32_t dev_id, fal_loop_check_time_t * time, a_bool_t * enable); + + HSL_LOCAL sw_error_t + shiva_loop_check_info_get(a_uint32_t dev_id, a_uint32_t * old_port_id, a_uint32_t * new_port_id); + + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _SHIVA_GEN_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_port_ctrl.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_port_ctrl.h new file mode 100755 index 000000000..169041339 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_port_ctrl.h @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 shiva_port_ctrl SHIVA_PORT_CONTROL + * @{ + */ +#ifndef _SHIVA_PORT_CTRL_H_ +#define _SHIVA_PORT_CTRL_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_port_ctrl.h" + +#define RX_FC_EN 1 +#define TX_FC_FULL_EN 1 +#define TX_FC_HALF_EN 1 + +sw_error_t shiva_port_ctrl_init(a_uint32_t dev_id); + +#ifdef IN_PORTCONTROL +#define SHIVA_PORT_CTRL_INIT(rv, dev_id) \ + { \ + rv = shiva_port_ctrl_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define SHIVA_PORT_CTRL_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + shiva_port_duplex_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t duplex); + + + HSL_LOCAL sw_error_t + shiva_port_duplex_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t * pduplex); + + + HSL_LOCAL sw_error_t + shiva_port_speed_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t speed); + + + HSL_LOCAL sw_error_t + shiva_port_speed_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t * pspeed); + + + HSL_LOCAL sw_error_t + shiva_port_autoneg_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status); + + + HSL_LOCAL sw_error_t + shiva_port_autoneg_enable(a_uint32_t dev_id, fal_port_t port_id); + + + HSL_LOCAL sw_error_t + shiva_port_autoneg_restart(a_uint32_t dev_id, fal_port_t port_id); + + + HSL_LOCAL sw_error_t + shiva_port_autoneg_adv_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t autoadv); + + + HSL_LOCAL sw_error_t + shiva_port_autoneg_adv_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * autoadv); + + + HSL_LOCAL sw_error_t + shiva_port_hdr_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_port_hdr_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + shiva_port_flowctrl_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_port_flowctrl_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + shiva_port_flowctrl_forcemode_set(a_uint32_t dev_id, + fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_port_flowctrl_forcemode_get(a_uint32_t dev_id, + fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + shiva_port_powersave_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_port_powersave_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable); + + + HSL_LOCAL sw_error_t + shiva_port_hibernate_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_port_hibernate_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable); + + + HSL_LOCAL sw_error_t + shiva_port_cdt(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t mdi_pair, + fal_cable_status_t *cable_status, a_uint32_t *cable_len); + + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _SHIVA_PORT_CTRL_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_portvlan.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_portvlan.h new file mode 100755 index 000000000..fdfa27d4f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_portvlan.h @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 shiva_port_vlan SHIVA_PORT_VLAN + * @{ + */ +#ifndef _SHIVA_PORTVLAN_H_ +#define _SHIVA_PORTVLAN_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_portvlan.h" + + sw_error_t shiva_portvlan_init(a_uint32_t dev_id); + +#ifdef IN_PORTVLAN +#define SHIVA_PORTVLAN_INIT(rv, dev_id) \ + { \ + rv = shiva_portvlan_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define SHIVA_PORTVLAN_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + shiva_port_1qmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t port_1qmode); + + + HSL_LOCAL sw_error_t + shiva_port_1qmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t * pport_1qmode); + + + HSL_LOCAL sw_error_t + shiva_port_egvlanmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t port_egvlanmode); + + + HSL_LOCAL sw_error_t + shiva_port_egvlanmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t * pport_egvlanmode); + + + HSL_LOCAL sw_error_t + shiva_portvlan_member_add(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id); + + + HSL_LOCAL sw_error_t + shiva_portvlan_member_del(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id); + + + HSL_LOCAL sw_error_t + shiva_portvlan_member_update(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t mem_port_map); + + + HSL_LOCAL sw_error_t + shiva_portvlan_member_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t * mem_port_map); + + + HSL_LOCAL sw_error_t + shiva_port_force_default_vid_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_port_force_default_vid_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + shiva_port_force_portvlan_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_port_force_portvlan_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + shiva_nestvlan_tpid_set(a_uint32_t dev_id, a_uint32_t tpid); + + + HSL_LOCAL sw_error_t + shiva_nestvlan_tpid_get(a_uint32_t dev_id, a_uint32_t * tpid); + + + HSL_LOCAL sw_error_t + shiva_port_invlan_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_invlan_mode_t mode); + + + HSL_LOCAL sw_error_t + shiva_port_invlan_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_invlan_mode_t * mode); + + + HSL_LOCAL sw_error_t + shiva_port_tls_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_port_tls_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + shiva_port_pri_propagation_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_port_pri_propagation_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + shiva_port_default_svid_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vid); + + + HSL_LOCAL sw_error_t + shiva_port_default_svid_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vid); + + HSL_LOCAL sw_error_t + shiva_port_default_cvid_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vid); + + + HSL_LOCAL sw_error_t + shiva_port_default_cvid_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vid); + + + HSL_LOCAL sw_error_t + shiva_port_vlan_propagation_set(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_propagation_mode_t mode); + + + HSL_LOCAL sw_error_t + shiva_port_vlan_propagation_get(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_propagation_mode_t * mode); + + + HSL_LOCAL sw_error_t + shiva_port_vlan_trans_add(a_uint32_t dev_id, fal_port_t port_id, fal_vlan_trans_entry_t *entry); + + + HSL_LOCAL sw_error_t + shiva_port_vlan_trans_del(a_uint32_t dev_id, fal_port_t port_id, fal_vlan_trans_entry_t *entry); + + + HSL_LOCAL sw_error_t + shiva_port_vlan_trans_get(a_uint32_t dev_id, fal_port_t port_id, fal_vlan_trans_entry_t *entry); + + + HSL_LOCAL sw_error_t + shiva_qinq_mode_set(a_uint32_t dev_id, fal_qinq_mode_t mode); + + + HSL_LOCAL sw_error_t + shiva_qinq_mode_get(a_uint32_t dev_id, fal_qinq_mode_t * mode); + + + HSL_LOCAL sw_error_t + shiva_port_qinq_role_set(a_uint32_t dev_id, fal_port_t port_id, fal_qinq_port_role_t role); + + + HSL_LOCAL sw_error_t + shiva_port_qinq_role_get(a_uint32_t dev_id, fal_port_t port_id, fal_qinq_port_role_t * role); + + + HSL_LOCAL sw_error_t + shiva_port_vlan_trans_iterate(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * iterator, fal_vlan_trans_entry_t * entry); + + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _SHIVA_PORTVLAN_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_qos.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_qos.h new file mode 100755 index 000000000..cd588ac6f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_qos.h @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 shiva_qos SHIVA_QOS + * @{ + */ +#ifndef _SHIVA_QOS_H_ +#define _SHIVA_QOS_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_qos.h" + + sw_error_t shiva_qos_init(a_uint32_t dev_id); + +#ifdef IN_QOS +#define SHIVA_QOS_INIT(rv, dev_id) \ + { \ + rv = shiva_qos_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define SHIVA_QOS_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + shiva_qos_queue_tx_buf_status_set(a_uint32_t dev_id, + fal_port_t port_id, a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_qos_queue_tx_buf_status_get(a_uint32_t dev_id, + fal_port_t port_id, + a_bool_t * enable); + + HSL_LOCAL sw_error_t + shiva_qos_port_tx_buf_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_qos_port_tx_buf_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + HSL_LOCAL sw_error_t + shiva_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); + + + HSL_LOCAL sw_error_t + shiva_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); + + + HSL_LOCAL sw_error_t + shiva_qos_port_tx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number); + + + HSL_LOCAL sw_error_t + shiva_qos_port_tx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number); + + + HSL_LOCAL sw_error_t + shiva_qos_port_rx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number); + + + HSL_LOCAL sw_error_t + shiva_qos_port_rx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number); + + + HSL_LOCAL sw_error_t + shiva_cosmap_up_queue_set(a_uint32_t dev_id, a_uint32_t up, + fal_queue_t queue); + + + HSL_LOCAL sw_error_t + shiva_cosmap_up_queue_get(a_uint32_t dev_id, a_uint32_t up, + fal_queue_t * queue); + + + HSL_LOCAL sw_error_t + shiva_cosmap_dscp_queue_set(a_uint32_t dev_id, a_uint32_t dscp, + fal_queue_t queue); + + + HSL_LOCAL sw_error_t + shiva_cosmap_dscp_queue_get(a_uint32_t dev_id, a_uint32_t dscp, + fal_queue_t * queue); + + + HSL_LOCAL sw_error_t + shiva_qos_port_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_qos_port_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + shiva_qos_port_mode_pri_set(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_uint32_t pri); + + + HSL_LOCAL sw_error_t + shiva_qos_port_mode_pri_get(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_uint32_t * pri); + + + HSL_LOCAL sw_error_t + shiva_qos_port_default_up_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t up); + + + HSL_LOCAL sw_error_t + shiva_qos_port_default_up_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * up); + + + HSL_LOCAL sw_error_t + shiva_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[]); + + + HSL_LOCAL sw_error_t + shiva_qos_port_sch_mode_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_sch_mode_t * mode, a_uint32_t weight[]); + + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _SHIVA_QOS_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_rate.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_rate.h new file mode 100755 index 000000000..7648dbbfa --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_rate.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 shiva_rate SHIVA_RATE + * @{ + */ +#ifndef _SHIVA_RATE_H_ +#define _SHIVA_RATE_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_rate.h" + + sw_error_t shiva_rate_init(a_uint32_t dev_id); + +#ifdef IN_RATE +#define SHIVA_RATE_INIT(rv, dev_id) \ + { \ + rv = shiva_rate_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define SHIVA_RATE_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + shiva_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); + + + HSL_LOCAL sw_error_t + shiva_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); + + + HSL_LOCAL sw_error_t + shiva_rate_port_egrl_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * speed, a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_rate_port_egrl_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * speed, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + shiva_rate_port_inrl_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * speed, a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_rate_port_inrl_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * speed, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + shiva_storm_ctrl_frame_set(a_uint32_t dev_id, fal_port_t port_id, + fal_storm_type_t storm_type, a_bool_t enable); + + + HSL_LOCAL sw_error_t + shiva_storm_ctrl_frame_get(a_uint32_t dev_id, fal_port_t port_id, + fal_storm_type_t storm_type, a_bool_t * enable); + + + HSL_LOCAL sw_error_t + shiva_storm_ctrl_rate_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * rate_in_pps); + + + HSL_LOCAL sw_error_t + shiva_storm_ctrl_rate_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * rate_in_pps); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _SHIVA_RATE_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_reduced_acl.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_reduced_acl.h new file mode 100755 index 000000000..51fa9a10f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_reduced_acl.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2012,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 _SHIVA_REDUCED_ACL_H_ +#define _SHIVA_REDUCED_ACL_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "sw.h" + + sw_error_t + shiva_acl_rule_write(a_uint32_t dev_id, a_uint32_t rule_idx, a_uint32_t vlu[8], + a_uint32_t msk[8]); + + sw_error_t + shiva_acl_action_write(a_uint32_t dev_id, a_uint32_t act_idx, + a_uint32_t act[3]); + + sw_error_t + shiva_acl_slct_write(a_uint32_t dev_id, a_uint32_t slct_idx, + a_uint32_t slct[8]); + + sw_error_t + shiva_acl_rule_read(a_uint32_t dev_id, a_uint32_t rule_idx, a_uint32_t vlu[8], + a_uint32_t msk[8]); + + sw_error_t + shiva_acl_action_read(a_uint32_t dev_id, a_uint32_t act_idx, + a_uint32_t act[3]); + + sw_error_t + shiva_acl_slct_read(a_uint32_t dev_id, a_uint32_t slct_idx, + a_uint32_t slct[8]); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _SHIVA_REDUCED_ACL_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_reg.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_reg.h new file mode 100755 index 000000000..48561c7ea --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_reg.h @@ -0,0 +1,4075 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 _SHIVA_REG_H_ +#define _SHIVA_REG_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define MAX_ENTRY_LEN 128 + +#define HSL_RW 1 +#define HSL_RO 0 + + + /* SHIVA Mask Control Register */ +#define MASK_CTL "mask" +#define MASK_CTL_ID 0 +#define MASK_CTL_OFFSET 0x0000 +#define MASK_CTL_E_LENGTH 4 +#define MASK_CTL_E_OFFSET 0 +#define MASK_CTL_NR_E 1 + +#define SOFT_RST "mask_rst" +#define MASK_CTL_SOFT_RST_BOFFSET 31 +#define MASK_CTL_SOFT_RST_BLEN 1 +#define MASK_CTL_SOFT_RST_FLAG HSL_RW + +#define MII_CLK5_SEL "mask_clk5s" +#define MASK_CTL_MII_CLK5_SEL_BOFFSET 21 +#define MASK_CTL_MII_CLK5_SEL_BLEN 1 +#define MASK_CTL_MII_CLK5_SEL_FLAG HSL_RW + +#define MII_CLK0_SEL "mask_clk0s" +#define MASK_CTL_MII_CLK0_SEL_BOFFSET 20 +#define MASK_CTL_MII_CLK0_SEL_BLEN 1 +#define MASK_CTL_MII_CLK0_SEL_FLAG HSL_RW + +#define LOAD_EEPROM "mask_ldro" +#define MASK_CTL_LOAD_EEPROM_BOFFSET 16 +#define MASK_CTL_LOAD_EEPROM_BLEN 1 +#define MASK_CTL_LOAD_EEPROM_FLAG HSL_RW + +#define DEVICE_ID "mask_did" +#define MASK_CTL_DEVICE_ID_BOFFSET 8 +#define MASK_CTL_DEVICE_ID_BLEN 8 +#define MASK_CTL_DEVICE_ID_FLAG HSL_RO + +#define REV_ID "mask_rid" +#define MASK_CTL_REV_ID_BOFFSET 0 +#define MASK_CTL_REV_ID_BLEN 8 +#define MASK_CTL_REV_ID_FLAG HSL_RO + + + /* SHIVA Mask Control Register */ +#define POSTRIP "postrip" +#define POSTRIP_ID 0 +#define POSTRIP_OFFSET 0x0008 +#define POSTRIP_E_LENGTH 4 +#define POSTRIP_E_OFFSET 0 +#define POSTRIP_NR_E 1 + +#define POWER_ON_SEL "postrip_sel" +#define POSTRIP_POWER_ON_SEL_BOFFSET 31 +#define POSTRIP_POWER_ON_SEL_BLEN 1 +#define POSTRIP_POWER_ON_SEL_FLAG HSL_RW + +#define RXDELAY_S1 "postrip_rx_s1" +#define POSTRIP_RXDELAY_S1_BOFFSET 26 +#define POSTRIP_RXDELAY_S1_BLEN 1 +#define POSTRIP_RXDELAY_S1_FLAG HSL_RW + +#define SPI_EN "postrip_spi" +#define POSTRIP_SPI_EN_BOFFSET 25 +#define POSTRIP_SPI_EN_BLEN 1 +#define POSTRIP_SPI_EN_FLAG HSL_RW + +#define LED_OPEN_EN "postrip_led" +#define POSTRIP_LED_OPEN_EN_BOFFSET 24 +#define POSTRIP_LED_OPEN_EN_BLEN 1 +#define POSTRIP_LED_OPEN_EN_FLAG HSL_RW + +#define RXDELAY_S0 "postrip_rx_s0" +#define POSTRIP_RXDELAY_S0_BOFFSET 23 +#define POSTRIP_RXDELAY_S0_BLEN 1 +#define POSTRIP_RXDELAY_S0_FLAG HSL_RW + +#define TXDELAY_S1 "postrip_tx_s1" +#define POSTRIP_TXDELAY_S1_BOFFSET 22 +#define POSTRIP_TXDELAY_S1_BLEN 1 +#define POSTRIP_TXDELAY_S1_FLAG HSL_RW + +#define TXDELAY_S0 "postrip_tx_s0" +#define POSTRIP_TXDELAY_S0_BOFFSET 21 +#define POSTRIP_TXDELAY_S0_BLEN 1 +#define POSTRIP_TXDELAY_S0_FLAG HSL_RW + +#define LPW_EXIT "postrip_lpw_exit" +#define POSTRIP_LPW_EXIT_BOFFSET 20 +#define POSTRIP_LPW_EXIT_BLEN 1 +#define POSTRIP_LPW_EXIT_FLAG HSL_RW + +#define PHY_PLL_ON "postrip_phy_pll" +#define POSTRIP_PHY_PLL_ON_BOFFSET 19 +#define POSTRIP_PHY_PLL_ON_BLEN 1 +#define POSTRIP_PHY_PLL_ON_FLAG HSL_RW + +#define MAN_ENABLE "postrip_man_en" +#define POSTRIP_MAN_ENABLE_BOFFSET 18 +#define POSTRIP_MAN_ENABLE_BLEN 1 +#define POSTRIP_MAN_ENABLE_FLAG HSL_RW + +#define LPW_STATE_EN "postrip_lpw_state" +#define POSTRIP_LPW_STATE_EN_BOFFSET 17 +#define POSTRIP_LPW_STATE_EN_BLEN 1 +#define POSTRIP_LPW_STATE_EN_FLAG HSL_RW + +#define POWER_DOWN_HW "postrip_power_down" +#define POSTRIP_POWER_DOWN_HW_BOFFSET 16 +#define POSTRIP_POWER_DOWN_HW_BLEN 1 +#define POSTRIP_POWER_DOWN_HW_FLAG HSL_RW + +#define MAC5_PHY_MODE "postrip_mac5_phy" +#define POSTRIP_MAC5_PHY_MODE_BOFFSET 15 +#define POSTRIP_MAC5_PHY_MODE_BLEN 1 +#define POSTRIP_MAC5_PHY_MODE_FLAG HSL_RW + +#define MAC5_MAC_MODE "postrip_mac5_mac" +#define POSTRIP_MAC5_MAC_MODE_BOFFSET 14 +#define POSTRIP_MAC5_MAC_MODE_BLEN 1 +#define POSTRIP_MAC5_MAC_MODE_FLAG HSL_RW + +#define DBG_MODE_I "postrip_dbg" +#define POSTRIP_DBG_MODE_I_BOFFSET 13 +#define POSTRIP_DBG_MODE_I_BLEN 1 +#define POSTRIP_DBG_MODE_I_FLAG HSL_RW + +#define HIB_PULSE_HW "postrip_hib" +#define POSTRIP_HIB_PULSE_HW_BOFFSET 12 +#define POSTRIP_HIB_PULSE_HW_BLEN 1 +#define POSTRIP_HIB_PULSE_HW_FLAG HSL_RW + +#define SEL_CLK25M "postrip_clk25" +#define POSTRIP_SEL_CLK25M_BOFFSET 11 +#define POSTRIP_SEL_CLK25M_BLEN 1 +#define POSTRIP_SEL_CLK25M_FLAG HSL_RW + +#define GATE_25M_EN "postrip_gate25" +#define POSTRIP_GATE_25M_EN_BOFFSET 10 +#define POSTRIP_GATE_25M_EN_BLEN 1 +#define POSTRIP_GATE_25M_EN_FLAG HSL_RW + +#define SEL_ANA_RST "postrip_sel_ana" +#define POSTRIP_SEL_ANA_RST_BOFFSET 9 +#define POSTRIP_SEL_ANA_RST_BLEN 1 +#define POSTRIP_SEL_ANA_RST_FLAG HSL_RW + +#define SERDES_EN "postrip_serdes_en" +#define POSTRIP_SERDES_EN_BOFFSET 8 +#define POSTRIP_SERDES_EN_BLEN 1 +#define POSTRIP_SERDES_EN_FLAG HSL_RW + +#define RGMII_TXCLK_DELAY_EN "postrip_tx_delay" +#define POSTRIP_RGMII_TXCLK_DELAY_EN_BOFFSET 7 +#define POSTRIP_RGMII_TXCLK_DELAY_EN_BLEN 1 +#define POSTRIP_RGMII_TXCLK_DELAY_EN_FLAG HSL_RW + +#define RGMII_RXCLK_DELAY_EN "postrip_rx_delay" +#define POSTRIP_RGMII_RXCLK_DELAY_EN_BOFFSET 6 +#define POSTRIP_RGMII_RXCLK_DELAY_EN_BLEN 1 +#define POSTRIP_RGMII_RXCLK_DELAY_EN_FLAG HSL_RW + +#define RTL_MODE "postrip_rtl" +#define POSTRIP_RTL_MODE_BOFFSET 5 +#define POSTRIP_RTL_MODE_BLEN 1 +#define POSTRIP_RTL_MODE_FLAG HSL_RW + +#define MAC0_MAC_MODE "postrip_mac0_mac" +#define POSTRIP_MAC0_MAC_MODE_BOFFSET 4 +#define POSTRIP_MAC0_MAC_MODE_BLEN 1 +#define POSTRIP_MAC0_MAC_MODE_FLAG HSL_RW + +#define PHY4_RGMII_EN "postrip_phy4_rgmii" +#define POSTRIP_PHY4_RGMII_EN_BOFFSET 3 +#define POSTRIP_PHY4_RGMII_EN_BLEN 1 +#define POSTRIP_PHY4_RGMII_EN_FLAG HSL_RW + +#define PHY4_GMII_EN "postrip_phy4_gmii" +#define POSTRIP_PHY4_GMII_EN_BOFFSET 2 +#define POSTRIP_PHY4_GMII_EN_BLEN 1 +#define POSTRIP_PHY4_GMII_EN_FLAG HSL_RW + +#define MAC0_RGMII_EN "postrip_mac0_rgmii" +#define POSTRIP_MAC0_RGMII_EN_BOFFSET 1 +#define POSTRIP_MAC0_RGMII_EN_BLEN 1 +#define POSTRIP_MAC0_RGMII_EN_FLAG HSL_RW + +#define MAC0_GMII_EN "postrip_mac0_gmii" +#define POSTRIP_MAC0_GMII_EN_BOFFSET 0 +#define POSTRIP_MAC0_GMII_EN_BLEN 1 +#define POSTRIP_MAC0_GMII_EN_FLAG HSL_RW + + + + /* Global Interrupt Register */ +#define GLOBAL_INT "gint" +#define GLOBAL_INT_ID 1 +#define GLOBAL_INT_OFFSET 0x0014 +#define GLOBAL_INT_E_LENGTH 4 +#define GLOBAL_INT_E_OFFSET 0 +#define GLOBAL_INT_NR_E 1 + +#define GLB_QM_ERR_CNT "gint_qmen" +#define GLOBAL_INT_GLB_QM_ERR_CNT_BOFFSET 24 +#define GLOBAL_INT_GLB_QM_ERR_CNT_BLEN 8 +#define GLOBAL_INT_GLB_QM_ERR_CNT_FLAG HSL_RO + +#define GLB_LOOKUP_ERR "gint_glblper" +#define GLOBAL_INT_GLB_LOOKUP_ERR_BOFFSET 17 +#define GLOBAL_INT_GLB_LOOKUP_ERR_BLEN 1 +#define GLOBAL_INT_GLB_LOOKUP_ERR_FLAG HSL_RW + +#define GLB_QM_ERR "gint_glbqmer" +#define GLOBAL_INT_GLB_QM_ERR_BOFFSET 16 +#define GLOBAL_INT_GLB_QM_ERR_BLEN 1 +#define GLOBAL_INT_GLB_QM_ERR_FLAG HSL_RW + +#define GLB_HW_INI_DONE "gint_hwid" +#define GLOBAL_INT_GLB_HW_INI_DONE_BOFFSET 14 +#define GLOBAL_INT_GLB_HW_INI_DONE_BLEN 1 +#define GLOBAL_INT_GLB_HW_INI_DONE_FLAG HSL_RW + +#define GLB_MIB_INI "gint_mibi" +#define GLOBAL_INT_GLB_MIB_INI_BOFFSET 13 +#define GLOBAL_INT_GLB_MIB_INI_BLEN 1 +#define GLOBAL_INT_GLB_MIB_INI_FLAG HSL_RW + +#define GLB_MIB_DONE "gint_mibd" +#define GLOBAL_INT_GLB_MIB_DONE_BOFFSET 12 +#define GLOBAL_INT_GLB_MIB_DONE_BLEN 1 +#define GLOBAL_INT_GLB_MIB_DONE_FLAG HSL_RW + +#define GLB_BIST_DONE "gint_bisd" +#define GLOBAL_INT_GLB_BIST_DONE_BOFFSET 11 +#define GLOBAL_INT_GLB_BIST_DONE_BLEN 1 +#define GLOBAL_INT_GLB_BIST_DONE_FLAG HSL_RW + +#define GLB_VT_MISS_VIO "gint_vtms" +#define GLOBAL_INT_GLB_VT_MISS_VIO_BOFFSET 10 +#define GLOBAL_INT_GLB_VT_MISS_VIO_BLEN 1 +#define GLOBAL_INT_GLB_VT_MISS_VIO_FLAG HSL_RW + +#define GLB_VT_MEM_VIO "gint_vtme" +#define GLOBAL_INT_GLB_VT_MEM_VIO_BOFFSET 9 +#define GLOBAL_INT_GLB_VT_MEM_VIO_BLEN 1 +#define GLOBAL_INT_GLB_VT_MEM_VIO_FLAG HSL_RW + +#define GLB_VT_DONE "gint_vtd" +#define GLOBAL_INT_GLB_VT_DONE_BOFFSET 8 +#define GLOBAL_INT_GLB_VT_DONE_BLEN 1 +#define GLOBAL_INT_GLB_VT_DONE_FLAG HSL_RW + +#define GLB_QM_INI "gint_qmin" +#define GLOBAL_INT_GLB_QM_INI_BOFFSET 7 +#define GLOBAL_INT_GLB_QM_INI_BLEN 1 +#define GLOBAL_INT_GLB_QM_INI_FLAG HSL_RW + +#define GLB_AT_INI "gint_atin" +#define GLOBAL_INT_GLB_AT_INI_BOFFSET 6 +#define GLOBAL_INT_GLB_AT_INI_BLEN 1 +#define GLOBAL_INT_GLB_AT_INI_FLAG HSL_RW + +#define GLB_ARL_FULL "gint_arlf" +#define GLOBAL_INT_GLB_ARL_FULL_BOFFSET 5 +#define GLOBAL_INT_GLB_ARL_FULL_BLEN 1 +#define GLOBAL_INT_GLB_ARL_FULL_FLAG HSL_RW + +#define GLB_ARL_DONE "gint_arld" +#define GLOBAL_INT_GLB_ARL_DONE_BOFFSET 4 +#define GLOBAL_INT_GLB_ARL_DONE_BLEN 1 +#define GLOBAL_INT_GLB_ARL_DONE_FLAG HSL_RW + +#define GLB_MDIO_DONE "gint_mdid" +#define GLOBAL_INT_GLB_MDIO_DONE_BOFFSET 3 +#define GLOBAL_INT_GLB_MDIO_DONE_BLEN 1 +#define GLOBAL_INT_GLB_MDIO_DONE_FLAG HSL_RW + +#define GLB_PHY_INT "gint_phyi" +#define GLOBAL_INT_GLB_PHY_INT_BOFFSET 2 +#define GLOBAL_INT_GLB_PHY_INT_BLEN 1 +#define GLOBAL_INT_GLB_PHY_INT_FLAG HSL_RW + +#define GLB_EEPROM_ERR "gint_epei" +#define GLOBAL_INT_GLB_EEPROM_ERR_BOFFSET 1 +#define GLOBAL_INT_GLB_EEPROM_ERR_BLEN 1 +#define GLOBAL_INT_GLB_EEPROM_ERR_FLAG HSL_RW + +#define GLB_EEPROM_INT "gint_epi" +#define GLOBAL_INT_GLB_EEPROM_INT_BOFFSET 0 +#define GLOBAL_INT_GLB_EEPROM_INT_BLEN 1 +#define GLOBAL_INT_GLB_EEPROM_INT_FLAG HSL_RW + + + /* Global Interrupt Mask Register */ +#define GLOBAL_INT_MASK "gintm" +#define GLOBAL_INT_MASK_ID 2 +#define GLOBAL_INT_MASK_OFFSET 0x0018 +#define GLOBAL_INT_MASK_E_LENGTH 4 +#define GLOBAL_INT_MASK_E_OFFSET 0 +#define GLOBAL_INT_MASK_NR_E 1 + +#define GLBM_LOOP_CHECK "gintm_lc" +#define GLOBAL_INT_MASK_GLBM_LOOP_CHECK_BOFFSET 18 +#define GLOBAL_INT_MASK_GLBM_LOOP_CHECK_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_LOOP_CHECK_FLAG HSL_RW + +#define GLBM_LOOKUP_ERR "gintm_lpe" +#define GLOBAL_INT_MASK_GLBM_LOOKUP_ERR_BOFFSET 17 +#define GLOBAL_INT_MASK_GLBM_LOOKUP_ERR_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_LOOKUP_ERR_FLAG HSL_RW + +#define GLBM_QM_ERR "gintm_qme" +#define GLOBAL_INT_MASK_GLBM_QM_ERR_BOFFSET 16 +#define GLOBAL_INT_MASK_GLBM_QM_ERR_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_QM_ERR_FLAG HSL_RW + +#define GLBM_HW_INI_DONE "gintm_hwid" +#define GLOBAL_INT_MASK_GLBM_HW_INI_DONE_BOFFSET 14 +#define GLOBAL_INT_MASK_GLBM_HW_INI_DONE_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_HW_INI_DONE_FLAG HSL_RW + +#define GLBM_MIB_INI "gintm_mibi" +#define GLOBAL_INT_MASK_GLBM_MIB_INI_BOFFSET 13 +#define GLOBAL_INT_MASK_GLBM_MIB_INI_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_MIB_INI_FLAG HSL_RW + +#define GLBM_MIB_DONE "gintm_mibd" +#define GLOBAL_INT_MASK_GLBM_MIB_DONE_BOFFSET 12 +#define GLOBAL_INT_MASK_GLBM_MIB_DONE_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_MIB_DONE_FLAG HSL_RW + +#define GLBM_BIST_DONE "gintm_bisd" +#define GLOBAL_INT_MASK_GLBM_BIST_DONE_BOFFSET 11 +#define GLOBAL_INT_MASK_GLBM_BIST_DONE_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_BIST_DONE_FLAG HSL_RW + +#define GLBM_VT_MISS_VIO "gintm_vtms" +#define GLOBAL_INT_MASK_GLBM_VT_MISS_VIO_BOFFSET 10 +#define GLOBAL_INT_MASK_GLBM_VT_MISS_VIO_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_VT_MISS_VIO_FLAG HSL_RW + +#define GLBM_VT_MEM_VIO "gintm_vtme" +#define GLOBAL_INT_MASK_GLBM_VT_MEM_VIO_BOFFSET 9 +#define GLOBAL_INT_MASK_GLBM_VT_MEM_VIO_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_VT_MEM_VIO_FLAG HSL_RW + +#define GLBM_VT_DONE "gintm_vtd" +#define GLOBAL_INT_MASK_GLBM_VT_DONE_BOFFSET 8 +#define GLOBAL_INT_MASK_GLBM_VT_DONE_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_VT_DONE_FLAG HSL_RW + +#define GLBM_QM_INI "gintm_qmin" +#define GLOBAL_INT_MASK_GLBM_QM_INI_BOFFSET 7 +#define GLOBAL_INT_MASK_GLBM_QM_INI_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_QM_INI_FLAG HSL_RW + +#define GLBM_AT_INI "gintm_atin" +#define GLOBAL_INT_MASK_GLBM_AT_INI_BOFFSET 6 +#define GLOBAL_INT_MASK_GLBM_AT_INI_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_AT_INI_FLAG HSL_RW + +#define GLBM_ARL_FULL "gintm_arlf" +#define GLOBAL_INT_MASK_GLBM_ARL_FULL_BOFFSET 5 +#define GLOBAL_INT_MASK_GLBM_ARL_FULL_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_ARL_FULL_FLAG HSL_RW + +#define GLBM_ARL_DONE "gintm_arld" +#define GLOBAL_INT_MASK_GLBM_ARL_DONE_BOFFSET 4 +#define GLOBAL_INT_MASK_GLBM_ARL_DONE_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_ARL_DONE_FLAG HSL_RW + +#define GLBM_MDIO_DONE "gintm_mdid" +#define GLOBAL_INT_MASK_GLBM_MDIO_DONE_BOFFSET 3 +#define GLOBAL_INT_MASK_GLBM_MDIO_DONE_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_MDIO_DONE_FLAG HSL_RW + +#define GLBM_PHY_INT "gintm_phy" +#define GLOBAL_INT_MASK_GLBM_PHY_INT_BOFFSET 2 +#define GLOBAL_INT_MASK_GLBM_PHY_INT_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_PHY_INT_FLAG HSL_RW + +#define GLBM_EEPROM_ERR "gintm_epe" +#define GLOBAL_INT_MASK_GLBM_EEPROM_ERR_BOFFSET 1 +#define GLOBAL_INT_MASK_GLBM_EEPROM_ERR_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_EEPROM_ERR_FLAG HSL_RW + +#define GLBM_EEPROM_INT "gintm_ep" +#define GLOBAL_INT_MASK_GLBM_EEPROM_INT_BOFFSET 0 +#define GLOBAL_INT_MASK_GLBM_EEPROM_INT_BLEN 1 +#define GLOBAL_INT_MASK_GLBM_EEPROM_INT_FLAG HSL_RW + + + /* Global MAC Address Register */ +#define GLOBAL_MAC_ADDR0 "gmac0" +#define GLOBAL_MAC_ADDR0_ID 3 +#define GLOBAL_MAC_ADDR0_OFFSET 0x0020 +#define GLOBAL_MAC_ADDR0_E_LENGTH 4 +#define GLOBAL_MAC_ADDR0_E_OFFSET 0 +#define GLOBAL_MAC_ADDR0_NR_E 1 + +#define GLB_BYTE4 "gmac_b4" +#define GLOBAL_MAC_ADDR0_GLB_BYTE4_BOFFSET 8 +#define GLOBAL_MAC_ADDR0_GLB_BYTE4_BLEN 8 +#define GLOBAL_MAC_ADDR0_GLB_BYTE4_FLAG HSL_RW + +#define GLB_BYTE5 "gmac_b5" +#define GLOBAL_MAC_ADDR0_GLB_BYTE5_BOFFSET 0 +#define GLOBAL_MAC_ADDR0_GLB_BYTE5_BLEN 8 +#define GLOBAL_MAC_ADDR0_GLB_BYTE5_FLAG HSL_RW + +#define GLOBAL_MAC_ADDR1 "gmac1" +#define GLOBAL_MAC_ADDR1_ID 4 +#define GLOBAL_MAC_ADDR1_OFFSET 0x0024 +#define GLOBAL_MAC_ADDR1_E_LENGTH 4 +#define GLOBAL_MAC_ADDR1_E_OFFSET 0 +#define GLOBAL_MAC_ADDR1_NR_E 1 + +#define GLB_BYTE0 "gmac_b0" +#define GLOBAL_MAC_ADDR1_GLB_BYTE0_BOFFSET 24 +#define GLOBAL_MAC_ADDR1_GLB_BYTE0_BLEN 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE0_FLAG HSL_RW + +#define GLB_BYTE1 "gmac_b1" +#define GLOBAL_MAC_ADDR1_GLB_BYTE1_BOFFSET 16 +#define GLOBAL_MAC_ADDR1_GLB_BYTE1_BLEN 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE1_FLAG HSL_RW + +#define GLB_BYTE2 "gmac_b2" +#define GLOBAL_MAC_ADDR1_GLB_BYTE2_BOFFSET 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE2_BLEN 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE2_FLAG HSL_RW + +#define GLB_BYTE3 "gmac_b3" +#define GLOBAL_MAC_ADDR1_GLB_BYTE3_BOFFSET 0 +#define GLOBAL_MAC_ADDR1_GLB_BYTE3_BLEN 8 +#define GLOBAL_MAC_ADDR1_GLB_BYTE3_FLAG HSL_RW + + + /* Flood Mask Register */ +#define LOOP_CHECK "loopc" +#define LOOP_CHECK_ID 4 +#define LOOP_CHECK_OFFSET 0x0028 +#define LOOP_CHECK_E_LENGTH 4 +#define LOOP_CHECK_E_OFFSET 0 +#define LOOP_CHECK_NR_E 1 + +#define NEW_PORT +#define LOOP_CHECK_NEW_PORT_BOFFSET 4 +#define LOOP_CHECK_NEW_PORT_BLEN 4 +#define LOOP_CHECK_NEW_PORT_FLAG HSL_RW + +#define OLD_PORT +#define LOOP_CHECK_OLD_PORT_BOFFSET 0 +#define LOOP_CHECK_OLD_PORT_BLEN 4 +#define LOOP_CHECK_OLD_PORT_FLAG HSL_RW + + + /* Flood Mask Register */ +#define FLOOD_MASK "fmask" +#define FLOOD_MASK_ID 5 +#define FLOOD_MASK_OFFSET 0x002c +#define FLOOD_MASK_E_LENGTH 4 +#define FLOOD_MASK_E_OFFSET 0 +#define FLOOD_MASK_NR_E 1 + +#define BC_FLOOD_DP "fmask_bfdp" +#define FLOOD_MASK_BC_FLOOD_DP_BOFFSET 25 +#define FLOOD_MASK_BC_FLOOD_DP_BLEN 7 +#define FLOOD_MASK_BC_FLOOD_DP_FLAG HSL_RW + +#define ARL_UNI_LEAKY "fmask_aulky" +#define FLOOD_MASK_ARL_UNI_LEAKY_BOFFSET 24 +#define FLOOD_MASK_ARL_UNI_LEAKY_BLEN 1 +#define FLOOD_MASK_ARL_UNI_LEAKY_FLAG HSL_RW + +#define ARL_MUL_LEAKY "fmask_amlky" +#define FLOOD_MASK_ARL_MUL_LEAKY_BOFFSET 23 +#define FLOOD_MASK_ARL_MUL_LEAKY_BLEN 1 +#define FLOOD_MASK_ARL_MUL_LEAKY_FLAG HSL_RW + +#define MUL_FLOOD_DP "fmask_mfdp" +#define FLOOD_MASK_MUL_FLOOD_DP_BOFFSET 16 +#define FLOOD_MASK_MUL_FLOOD_DP_BLEN 7 +#define FLOOD_MASK_MUL_FLOOD_DP_FLAG HSL_RW + +#define IGMP_DP "fmask_igmpdp" +#define FLOOD_MASK_IGMP_DP_BOFFSET 8 +#define FLOOD_MASK_IGMP_DP_BLEN 7 +#define FLOOD_MASK_IGMP_DP_FLAG HSL_RW + +#define UNI_FLOOD_DP "fmask_ufdp" +#define FLOOD_MASK_UNI_FLOOD_DP_BOFFSET 0 +#define FLOOD_MASK_UNI_FLOOD_DP_BLEN 7 +#define FLOOD_MASK_UNI_FLOOD_DP_FLAG HSL_RW + + + /* Global Control Register */ +#define GLOBAL_CTL "gctl" +#define GLOBAL_CTL_ID 5 +#define GLOBAL_CTL_OFFSET 0x0030 +#define GLOBAL_CTL_E_LENGTH 4 +#define GLOBAL_CTL_E_OFFSET 0 +#define GLOBAL_CTL_NR_E 1 + +#define RATE_DROP_EN "gctl_rden" +#define GLOBAL_CTL_RATE_DROP_EN_BOFFSET 29 +#define GLOBAL_CTL_RATE_DROP_EN_BLEN 1 +#define GLOBAL_CTL_RATE_DROP_EN_FLAG HSL_RW + +#define QM_PRI_MODE "gctl_qmpm" +#define GLOBAL_CTL_QM_PRI_MODE_BOFFSET 28 +#define GLOBAL_CTL_QM_PRI_MODE_BLEN 1 +#define GLOBAL_CTL_QM_PRI_MODE_FLAG HSL_RW + +#define RATE_CRE_LIMIT "gctl_rcrl" +#define GLOBAL_CTL_RATE_CRE_LIMIT_BOFFSET 26 +#define GLOBAL_CTL_RATE_CRE_LIMIT_BLEN 2 +#define GLOBAL_CTL_RATE_CRE_LIMIT_FLAG HSL_RW + +#define RATE_TIME_SLOT "gctl_rtms" +#define GLOBAL_CTL_RATE_TIME_SLOT_BOFFSET 24 +#define GLOBAL_CTL_RATE_TIME_SLOT_BLEN 2 +#define GLOBAL_CTL_RATE_TIME_SLOT_FLAG HSL_RW + +#define RELOAD_TIMER "gctl_rdtm" +#define GLOBAL_CTL_RELOAD_TIMER_BOFFSET 20 +#define GLOBAL_CTL_RELOAD_TIMER_BLEN 4 +#define GLOBAL_CTL_RELOAD_TIMER_FLAG HSL_RW + +#define QM_CNT_LOCK "gctl_qmcl" +#define GLOBAL_CTL_QM_CNT_LOCK_BOFFSET 19 +#define GLOBAL_CTL_QM_CNT_LOCK_BLEN 1 +#define GLOBAL_CTL_QM_CNT_LOCK_FLAG HSL_RO + +#define BROAD_DROP_EN "gctl_bden" +#define GLOBAL_CTL_BROAD_DROP_EN_BOFFSET 18 +#define GLOBAL_CTL_BROAD_DROP_EN_BLEN 1 +#define GLOBAL_CTL_BROAD_DROP_EN_FLAG HSL_RW + +#define MAX_FRAME_SIZE "gctl_mfsz" +#define GLOBAL_CTL_MAX_FRAME_SIZE_BOFFSET 0 +#define GLOBAL_CTL_MAX_FRAME_SIZE_BLEN 14 +#define GLOBAL_CTL_MAX_FRAME_SIZE_FLAG HSL_RW + + + /* Flow Control Register */ +#define FLOW_CTL0 "fctl" +#define FLOW_CTL0_ID 6 +#define FLOW_CTL0_OFFSET 0x0034 +#define FLOW_CTL0_E_LENGTH 4 +#define FLOW_CTL0_E_OFFSET 0 +#define FLOW_CTL0_NR_E 1 + +#define TEST_PAUSE "fctl_tps" +#define FLOW_CTL0_TEST_PAUSE_BOFFSET 31 +#define FLOW_CTL0_TEST_PAUSE_BLEN 1 +#define FLOW_CTL0_TEST_PAUSE_FLAG HSL_RW + + +#define GOL_PAUSE_ON_THRES "fctl_gont" +#define FLOW_CTL0_GOL_PAUSE_ON_THRES_BOFFSET 16 +#define FLOW_CTL0_GOL_PAUSE_ON_THRES_BLEN 8 +#define FLOW_CTL0_GOL_PAUSE_ON_THRES_FLAG HSL_RW + +#define GOL_PAUSE_OFF_THRES "fctl_gofft" +#define FLOW_CTL0_GOL_PAUSE_OFF_THRES_BOFFSET 0 +#define FLOW_CTL0_GOL_PAUSE_OFF_THRES_BLEN 8 +#define FLOW_CTL0_GOL_PAUSE_OFF_THRES_FLAG HSL_RW + + + + + /* Flow Control1 Register */ +#define FLOW_CTL1 "fctl1" +#define FLOW_CTL1_ID 6 +#define FLOW_CTL1_OFFSET 0x0038 +#define FLOW_CTL1_E_LENGTH 4 +#define FLOW_CTL1_E_OFFSET 0 +#define FLOW_CTL1_NR_E 1 + +#define PORT_PAUSE_ON_THRES "fctl1_pont" +#define FLOW_CTL1_PORT_PAUSE_ON_THRES_BOFFSET 16 +#define FLOW_CTL1_PORT_PAUSE_ON_THRES_BLEN 8 +#define FLOW_CTL1_PORT_PAUSE_ON_THRES_FLAG HSL_RW + +#define PORT_PAUSE_OFF_THRES "fctl1_pofft" +#define FLOW_CTL1_PORT_PAUSE_OFF_THRES_BOFFSET 0 +#define FLOW_CTL1_PORT_PAUSE_OFF_THRES_BLEN 8 +#define FLOW_CTL1_PORT_PAUSE_OFF_THRES_FLAG HSL_RW + + + + + /* QM Control Register */ +#define QM_CTL "qmct" +#define QM_CTL_ID 7 +#define QM_CTL_OFFSET 0x003c +#define QM_CTL_E_LENGTH 4 +#define QM_CTL_E_OFFSET 0 +#define QM_CTL_NR_E 1 + +#define QM_ERR_RST_EN "qmct_qeren" +#define QM_CTL_QM_ERR_RST_EN_BOFFSET 31 +#define QM_CTL_QM_ERR_RST_EN_BLEN 1 +#define QM_CTL_QM_ERR_RST_EN_FLAG HSL_RW + +#define LOOKUP_ERR_RST_EN "qmct_lpesen" +#define QM_CTL_LOOKUP_ERR_RST_EN_BOFFSET 30 +#define QM_CTL_LOOKUP_ERR_RST_EN_BLEN 1 +#define QM_CTL_LOOKUP_ERR_RST_EN_FLAG HSL_RW + +#define IGMP_JOIN_STATIC "qmct_igmpjs" +#define QM_CTL_IGMP_JOIN_STATIC_BOFFSET 24 +#define QM_CTL_IGMP_JOIN_STATIC_BLEN 4 +#define QM_CTL_IGMP_JOIN_STATIC_FLAG HSL_RW + +#define IGMP_JOIN_LEAKY "qmct_igmpjl" +#define QM_CTL_IGMP_JOIN_LEAKY_BOFFSET 23 +#define QM_CTL_IGMP_JOIN_LEAKY_BLEN 1 +#define QM_CTL_IGMP_JOIN_LEAKY_FLAG HSL_RW + +#define IGMP_CREAT_EN "qmct_igmpcrt" +#define QM_CTL_IGMP_CREAT_EN_BOFFSET 22 +#define QM_CTL_IGMP_CREAT_EN_BLEN 1 +#define QM_CTL_IGMP_CREAT_EN_FLAG HSL_RW + +#define ACL_EN "qmct_aclen" +#define QM_CTL_ACL_EN_BOFFSET 21 +#define QM_CTL_ACL_EN_BLEN 1 +#define QM_CTL_ACL_EN_FLAG HSL_RW + +#define PPPOE_RDT_EN "qmct_pppoerdten" +#define QM_CTL_PPPOE_RDT_EN_BOFFSET 20 +#define QM_CTL_PPPOE_RDT_EN_BLEN 1 +#define QM_CTL_PPPOE_RDT_EN_FLAG HSL_RW + +#define IGMP_V3_EN "qmct_igmpv3e" +#define QM_CTL_IGMP_V3_EN_BOFFSET 19 +#define QM_CTL_IGMP_V3_EN_BLEN 1 +#define QM_CTL_IGMP_V3_EN_FLAG HSL_RW + +#define IGMP_PRI_EN "qmct_igmpprie" +#define QM_CTL_IGMP_PRI_EN_BOFFSET 18 +#define QM_CTL_IGMP_PRI_EN_BLEN 1 +#define QM_CTL_IGMP_PRI_EN_FLAG HSL_RW + +#define IGMP_PRI "qmct_igmppri" +#define QM_CTL_IGMP_PRI_BOFFSET 16 +#define QM_CTL_IGMP_PRI_BLEN 2 +#define QM_CTL_IGMP_PRI_FLAG HSL_RW + +#define ARP_EN "qmct_arpe" +#define QM_CTL_ARP_EN_BOFFSET 15 +#define QM_CTL_ARP_EN_BLEN 1 +#define QM_CTL_ARP_EN_FLAG HSL_RW + +#define ARP_CMD "qmct_arpc" +#define QM_CTL_ARP_CMD_BOFFSET 14 +#define QM_CTL_ARP_CMD_BLEN 1 +#define QM_CTL_ARP_CMD_FLAG HSL_RW + +#define RIP_CPY_EN "qmct_ripcpyen" +#define QM_CTL_RIP_CPY_EN_BOFFSET 13 +#define QM_CTL_RIP_CPY_EN_BLEN 1 +#define QM_CTL_RIP_CPY_EN_FLAG HSL_RW + +#define EAPOL_CMD "qmct_eapolc" +#define QM_CTL_EAPOL_CMD_BOFFSET 12 +#define QM_CTL_EAPOL_CMD_BLEN 1 +#define QM_CTL_EAPOL_CMD_FLAG HSL_RW + +#define IGMP_COPY_EN "qmct_igmpcpy" +#define QM_CTL_IGMP_COPY_EN_BOFFSET 11 +#define QM_CTL_IGMP_COPY_EN_BLEN 1 +#define QM_CTL_IGMP_COPY_EN_FLAG HSL_RW + +#define PPPOE_EN "qmct_pppoeen" +#define QM_CTL_PPPOE_EN_BOFFSET 10 +#define QM_CTL_PPPOE_EN_BLEN 1 +#define QM_CTL_PPPOE_EN_FLAG HSL_RW + +#define QM_FUNC_TEST "qmct_qmft" +#define QM_CTL_QM_FUNC_TEST_BOFFSET 9 +#define QM_CTL_QM_FUNC_TEST_BLEN 1 +#define QM_CTL_QM_FUNC_TEST_FLAG HSL_RW + +#define MS_FC_EN "qmct_msfe" +#define QM_CTL_MS_FC_EN_BOFFSET 8 +#define QM_CTL_MS_FC_EN_BLEN 1 +#define QM_CTL_MS_FC_EN_FLAG HSL_RW + +#define FLOW_DROP_EN "qmct_fden" +#define QM_CTL_FLOW_DROP_EN_BOFFSET 7 +#define QM_CTL_FLOW_DROP_EN_BLEN 1 +#define QM_CTL_FLOW_DROP_EN_FLAG HSL_RW + +#define MANAGE_VID_VIO_DROP_EN "qmct_mden" +#define QM_CTL_MANAGE_VID_VIO_DROP_EN_BOFFSET 6 +#define QM_CTL_MANAGE_VID_VIO_DROP_EN_BLEN 1 +#define QM_CTL_MANAGE_VID_VIO_DROP_EN_FLAG HSL_RW + +#define FLOW_DROP_CNT "qmct_fdcn" +#define QM_CTL_FLOW_DROP_CNT_BOFFSET 0 +#define QM_CTL_FLOW_DROP_CNT_BLEN 6 +#define QM_CTL_FLOW_DROP_CNT_FLAG HSL_RW + + + /* Vlan Table Function Register */ +#define VLAN_TABLE_FUNC0 "vtbf0" +#define VLAN_TABLE_FUNC0_ID 9 +#define VLAN_TABLE_FUNC0_OFFSET 0x0040 +#define VLAN_TABLE_FUNC0_E_LENGTH 4 +#define VLAN_TABLE_FUNC0_E_OFFSET 0 +#define VLAN_TABLE_FUNC0_NR_E 1 + +#define VT_PRI_EN "vtbf_vtpen" +#define VLAN_TABLE_FUNC0_VT_PRI_EN_BOFFSET 31 +#define VLAN_TABLE_FUNC0_VT_PRI_EN_BLEN 1 +#define VLAN_TABLE_FUNC0_VT_PRI_EN_FLAG HSL_RW + +#define VT_PRI "vtbf_vtpri" +#define VLAN_TABLE_FUNC0_VT_PRI_BOFFSET 28 +#define VLAN_TABLE_FUNC0_VT_PRI_BLEN 3 +#define VLAN_TABLE_FUNC0_VT_PRI_FLAG HSL_RW + +#define VLAN_ID "vtbf_vid" +#define VLAN_TABLE_FUNC0_VLAN_ID_BOFFSET 16 +#define VLAN_TABLE_FUNC0_VLAN_ID_BLEN 12 +#define VLAN_TABLE_FUNC0_VLAN_ID_FLAG HSL_RW + +#define VT_PORT_NUM "vtbf_vtpn" +#define VLAN_TABLE_FUNC0_VT_PORT_NUM_BOFFSET 8 +#define VLAN_TABLE_FUNC0_VT_PORT_NUM_BLEN 4 +#define VLAN_TABLE_FUNC0_VT_PORT_NUM_FLAG HSL_RW + +#define VT_FULL_VIO "vtbf_vtflv" +#define VLAN_TABLE_FUNC0_VT_FULL_VIO_BOFFSET 4 +#define VLAN_TABLE_FUNC0_VT_FULL_VIO_BLEN 1 +#define VLAN_TABLE_FUNC0_VT_FULL_VIO_FLAG HSL_RW + +#define VT_BUSY "vtbf_vtbs" +#define VLAN_TABLE_FUNC0_VT_BUSY_BOFFSET 3 +#define VLAN_TABLE_FUNC0_VT_BUSY_BLEN 1 +#define VLAN_TABLE_FUNC0_VT_BUSY_FLAG HSL_RW + +#define VT_FUNC "vtbf_vtfc" +#define VLAN_TABLE_FUNC0_VT_FUNC_BOFFSET 0 +#define VLAN_TABLE_FUNC0_VT_FUNC_BLEN 3 +#define VLAN_TABLE_FUNC0_VT_FUNC_FLAG HSL_RW + +#define VLAN_TABLE_FUNC1 "vtbf1" +#define VLAN_TABLE_FUNC1_ID 10 +#define VLAN_TABLE_FUNC1_OFFSET 0x0044 +#define VLAN_TABLE_FUNC1_E_LENGTH 4 +#define VLAN_TABLE_FUNC1_E_OFFSET 0 +#define VLAN_TABLE_FUNC1_NR_E 1 + +#define VT_VALID "vtbf_vtvd" +#define VLAN_TABLE_FUNC1_VT_VALID_BOFFSET 11 +#define VLAN_TABLE_FUNC1_VT_VALID_BLEN 1 +#define VLAN_TABLE_FUNC1_VT_VALID_FLAG HSL_RW + +#define VID_MEM "vtbf_vidm" +#define VLAN_TABLE_FUNC1_VID_MEM_BOFFSET 0 +#define VLAN_TABLE_FUNC1_VID_MEM_BLEN 7 +#define VLAN_TABLE_FUNC1_VID_MEM_FLAG HSL_RW + + + /* Address Table Function Register */ +#define ADDR_TABLE_FUNC0 "atbf0" +#define ADDR_TABLE_FUNC0_ID 11 +#define ADDR_TABLE_FUNC0_OFFSET 0x0050 +#define ADDR_TABLE_FUNC0_E_LENGTH 4 +#define ADDR_TABLE_FUNC0_E_OFFSET 0 +#define ADDR_TABLE_FUNC0_NR_E 1 + +#define AT_ADDR_BYTE4 "atbf_adb4" +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE4_BOFFSET 24 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE4_BLEN 8 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE4_FLAG HSL_RW + +#define AT_ADDR_BYTE5 "atbf_adb5" +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE5_BOFFSET 16 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE5_BLEN 8 +#define ADDR_TABLE_FUNC0_AT_ADDR_BYTE5_FLAG HSL_RW + +#define AT_FULL_VIO "atbf_atfv" +#define ADDR_TABLE_FUNC0_AT_FULL_VIO_BOFFSET 12 +#define ADDR_TABLE_FUNC0_AT_FULL_VIO_BLEN 1 +#define ADDR_TABLE_FUNC0_AT_FULL_VIO_FLAG HSL_RW + +#define AT_PORT_NUM "atbf_atpn" +#define ADDR_TABLE_FUNC0_AT_PORT_NUM_BOFFSET 8 +#define ADDR_TABLE_FUNC0_AT_PORT_NUM_BLEN 4 +#define ADDR_TABLE_FUNC0_AT_PORT_NUM_FLAG HSL_RW + +#define FLUSH_ST_EN "atbf_fsen" +#define ADDR_TABLE_FUNC0_FLUSH_ST_EN_BOFFSET 4 +#define ADDR_TABLE_FUNC0_FLUSH_ST_EN_BLEN 1 +#define ADDR_TABLE_FUNC0_FLUSH_ST_EN_FLAG HSL_RW + +#define AT_BUSY "atbf_atbs" +#define ADDR_TABLE_FUNC0_AT_BUSY_BOFFSET 3 +#define ADDR_TABLE_FUNC0_AT_BUSY_BLEN 1 +#define ADDR_TABLE_FUNC0_AT_BUSY_FLAG HSL_RW + +#define AT_FUNC "atbf_atfc" +#define ADDR_TABLE_FUNC0_AT_FUNC_BOFFSET 0 +#define ADDR_TABLE_FUNC0_AT_FUNC_BLEN 3 +#define ADDR_TABLE_FUNC0_AT_FUNC_FLAG HSL_RW + +#define ADDR_TABLE_FUNC1 "atbf1" +#define ADDR_TABLE_FUNC1_ID 12 +#define ADDR_TABLE_FUNC1_OFFSET 0x0054 +#define ADDR_TABLE_FUNC1_E_LENGTH 4 +#define ADDR_TABLE_FUNC1_E_OFFSET 0 +#define ADDR_TABLE_FUNC1_NR_E 0 + +#define AT_ADDR_BYTE0 "atbf_adb0" +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE0_BOFFSET 24 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE0_BLEN 8 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE0_FLAG HSL_RW + +#define AT_ADDR_BYTE1 "atbf_adb1" +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE1_BOFFSET 16 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE1_BLEN 8 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE1_FLAG HSL_RW + +#define AT_ADDR_BYTE2 "atbf_adb2" +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE2_BOFFSET 8 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE2_BLEN 8 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE2_FLAG HSL_RW + +#define AT_ADDR_BYTE3 "atbf_adb3" +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE3_BOFFSET 0 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE3_BLEN 8 +#define ADDR_TABLE_FUNC1_AT_ADDR_BYTE3_FLAG HSL_RW + +#define ADDR_TABLE_FUNC2 "atbf2" +#define ADDR_TABLE_FUNC2_ID 13 +#define ADDR_TABLE_FUNC2_OFFSET 0x0058 +#define ADDR_TABLE_FUNC2_E_LENGTH 4 +#define ADDR_TABLE_FUNC2_E_OFFSET 0 +#define ADDR_TABLE_FUNC2_NR_E 0 + +#define COPY_TO_CPU "atbf_cpcpu" +#define ADDR_TABLE_FUNC2_COPY_TO_CPU_BOFFSET 26 +#define ADDR_TABLE_FUNC2_COPY_TO_CPU_BLEN 1 +#define ADDR_TABLE_FUNC2_COPY_TO_CPU_FLAG HSL_RW + +#define REDRCT_TO_CPU "atbf_rdcpu" +#define ADDR_TABLE_FUNC2_REDRCT_TO_CPU_BOFFSET 25 +#define ADDR_TABLE_FUNC2_REDRCT_TO_CPU_BLEN 1 +#define ADDR_TABLE_FUNC2_REDRCT_TO_CPU_FLAG HSL_RW + +#define LEAKY_EN "atbf_lkyen" +#define ADDR_TABLE_FUNC2_LEAKY_EN_BOFFSET 24 +#define ADDR_TABLE_FUNC2_LEAKY_EN_BLEN 1 +#define ADDR_TABLE_FUNC2_LEAKY_EN_FLAG HSL_RW + +#define AT_STATUS "atbf_atsts" +#define ADDR_TABLE_FUNC2_AT_STATUS_BOFFSET 16 +#define ADDR_TABLE_FUNC2_AT_STATUS_BLEN 4 +#define ADDR_TABLE_FUNC2_AT_STATUS_FLAG HSL_RW + +#define CLONE_EN "atbf_clone" +#define ADDR_TABLE_FUNC2_CLONE_EN_BOFFSET 15 +#define ADDR_TABLE_FUNC2_CLONE_EN_BLEN 1 +#define ADDR_TABLE_FUNC2_CLONE_EN_FLAG HSL_RW + +#define SA_DROP_EN "atbf_saden" +#define ADDR_TABLE_FUNC2_SA_DROP_EN_BOFFSET 14 +#define ADDR_TABLE_FUNC2_SA_DROP_EN_BLEN 1 +#define ADDR_TABLE_FUNC2_SA_DROP_EN_FLAG HSL_RW + +#define MIRROR_EN "atbf_miren" +#define ADDR_TABLE_FUNC2_MIRROR_EN_BOFFSET 13 +#define ADDR_TABLE_FUNC2_MIRROR_EN_BLEN 1 +#define ADDR_TABLE_FUNC2_MIRROR_EN_FLAG HSL_RW + +#define AT_PRI_EN "atbf_atpen" +#define ADDR_TABLE_FUNC2_AT_PRI_EN_BOFFSET 12 +#define ADDR_TABLE_FUNC2_AT_PRI_EN_BLEN 1 +#define ADDR_TABLE_FUNC2_AT_PRI_EN_FLAG HSL_RW + +#define AT_PRI "atbf_atpri" +#define ADDR_TABLE_FUNC2_AT_PRI_BOFFSET 10 +#define ADDR_TABLE_FUNC2_AT_PRI_BLEN 2 +#define ADDR_TABLE_FUNC2_AT_PRI_FLAG HSL_RW + +#define CROSS_PT "atbf_cpt" +#define ADDR_TABLE_FUNC2_CROSS_PT_BOFFSET 8 +#define ADDR_TABLE_FUNC2_CROSS_PT_BLEN 1 +#define ADDR_TABLE_FUNC2_CROSS_PT_FLAG HSL_RW + +#define DES_PORT "atbf_desp" +#define ADDR_TABLE_FUNC2_DES_PORT_BOFFSET 0 +#define ADDR_TABLE_FUNC2_DES_PORT_BLEN 7 +#define ADDR_TABLE_FUNC2_DES_PORT_FLAG HSL_RW + + + /* FDB entry Register0 */ +#define FDB_TABLE_FUNC0 "fdb0" +#define FDB_TABLE_FUNC0_ID 11 +#define FDB_TABLE_FUNC0_OFFSET 0x30000 +#define FDB_TABLE_FUNC0_E_LENGTH 4 +#define FDB_TABLE_FUNC0_E_OFFSET 0 +#define FDB_TABLE_FUNC0_NR_E 1 + +#define FDB_ADDR_BYTE2 +#define FDB_TABLE_FUNC0_FDB_ADDR_BYTE2_BOFFSET 24 +#define FDB_TABLE_FUNC0_FDB_ADDR_BYTE2_BLEN 8 +#define FDB_TABLE_FUNC0_FDB_ADDR_BYTE2_FLAG HSL_RW + +#define FDB_ADDR_BYTE3 +#define FDB_TABLE_FUNC0_FDB_ADDR_BYTE3_BOFFSET 16 +#define FDB_TABLE_FUNC0_FDB_ADDR_BYTE3_BLEN 8 +#define FDB_TABLE_FUNC0_FDB_ADDR_BYTE3_FLAG HSL_RW + +#define FDB_ADDR_BYTE4 +#define FDB_TABLE_FUNC0_FDB_ADDR_BYTE4_BOFFSET 8 +#define FDB_TABLE_FUNC0_FDB_ADDR_BYTE4_BLEN 8 +#define FDB_TABLE_FUNC0_FDB_ADDR_BYTE4_FLAG HSL_RW + +#define FDB_ADDR_BYTE5 +#define FDB_TABLE_FUNC0_FDB_ADDR_BYTE5_BOFFSET 0 +#define FDB_TABLE_FUNC0_FDB_ADDR_BYTE5_BLEN 8 +#define FDB_TABLE_FUNC0_FDB_ADDR_BYTE5_FLAG HSL_RW + + + /* FDB entry Register1 */ +#define FDB_TABLE_FUNC1 "fdb1" +#define FDB_TABLE_FUNC1_ID 11 +#define FDB_TABLE_FUNC1_OFFSET 0x30004 +#define FDB_TABLE_FUNC1_E_LENGTH 4 +#define FDB_TABLE_FUNC1_E_OFFSET 0 +#define FDB_TABLE_FUNC1_NR_E 1 + +#define FDB_MACCLONE_EN +#define FDB_TABLE_FUNC1_FDB_MACCLONE_EN_BOFFSET 31 +#define FDB_TABLE_FUNC1_FDB_MACCLONE_EN_BLEN 1 +#define FDB_TABLE_FUNC1_FDB_MACCLONE_EN_FLAG HSL_RW + +#define FDB_SADROP_EN +#define FDB_TABLE_FUNC1_FDB_SADROP_EN_BOFFSET 30 +#define FDB_TABLE_FUNC1_FDB_SADROP_EN_BLEN 1 +#define FDB_TABLE_FUNC1_FDB_SADROP_EN_FLAG HSL_RW + +#define FDB_MIRROR_EN +#define FDB_TABLE_FUNC1_FDB_MIRROR_EN_BOFFSET 29 +#define FDB_TABLE_FUNC1_FDB_MIRROR_EN_BLEN 1 +#define FDB_TABLE_FUNC1_FDB_MIRROR_EN_FLAG HSL_RW + +#define FDB_PRIORITY_EN +#define FDB_TABLE_FUNC1_FDB_PRIORITY_EN_BOFFSET 28 +#define FDB_TABLE_FUNC1_FDB_PRIORITY_EN_BLEN 1 +#define FDB_TABLE_FUNC1_FDB_PRIORITY_EN_FLAG HSL_RW + +#define FDB_PRIORITY +#define FDB_TABLE_FUNC1_FDB_PRIORITY_BOFFSET 26 +#define FDB_TABLE_FUNC1_FDB_PRIORITY_BLEN 2 +#define FDB_TABLE_FUNC1_FDB_PRIORITY_FLAG HSL_RW + +#define FDB_CROSS_STATE +#define FDB_TABLE_FUNC1_FDB_CROSS_STATE_BOFFSET 24 +#define FDB_TABLE_FUNC1_FDB_CROSS_STATE_BLEN 1 +#define FDB_TABLE_FUNC1_FDB_CROSS_STATE_FLAG HSL_RW + +#define FDB_DES_PORT +#define FDB_TABLE_FUNC1_FDB_DES_PORT_BOFFSET 16 +#define FDB_TABLE_FUNC1_FDB_DES_PORT_BLEN 7 +#define FDB_TABLE_FUNC1_FDB_DES_PORT_FLAG HSL_RW + +#define FDB_ADDR_BYTE0 +#define FDB_TABLE_FUNC1_FDB_ADDR_BYTE0_BOFFSET 8 +#define FDB_TABLE_FUNC1_FDB_ADDR_BYTE0_BLEN 8 +#define FDB_TABLE_FUNC1_FDB_ADDR_BYTE0_FLAG HSL_RW + +#define FDB_ADDR_BYTE1 +#define FDB_TABLE_FUNC1_FDB_ADDR_BYTE1_BOFFSET 0 +#define FDB_TABLE_FUNC1_FDB_ADDR_BYTE1_BLEN 8 +#define FDB_TABLE_FUNC1_FDB_ADDR_BYTE1_FLAG HSL_RW + + + /* FDB entry Register2 */ +#define FDB_TABLE_FUNC2 "fdb2" +#define FDB_TABLE_FUNC2_ID 11 +#define FDB_TABLE_FUNC2_OFFSET 0x30008 +#define FDB_TABLE_FUNC2_E_LENGTH 4 +#define FDB_TABLE_FUNC2_E_OFFSET 0 +#define FDB_TABLE_FUNC2_NR_E 1 + +#define FDB_CPYCPU_EN +#define FDB_TABLE_FUNC2_FDB_CPYCPU_EN_BOFFSET 6 +#define FDB_TABLE_FUNC2_FDB_CPYCPU_EN_BLEN 1 +#define FDB_TABLE_FUNC2_FDB_CPYCPU_EN_FLAG HSL_RW + +#define FDB_RDTCPU_EN +#define FDB_TABLE_FUNC2_FDB_RDTCPU_EN_BOFFSET 5 +#define FDB_TABLE_FUNC2_FDB_RDTCPU_EN_BLEN 1 +#define FDB_TABLE_FUNC2_FDB_RDTCPU_EN_FLAG HSL_RW + +#define FDB_LEANKY_EN +#define FDB_TABLE_FUNC2_FDB_LEANKY_EN_BOFFSET 4 +#define FDB_TABLE_FUNC2_FDB_LEANKY_EN_BLEN 1 +#define FDB_TABLE_FUNC2_FDB_LEANKY_EN_FLAG HSL_RW + +#define FDB_STATUS +#define FDB_TABLE_FUNC2_FDB_STATUS_BOFFSET 0 +#define FDB_TABLE_FUNC2_FDB_STATUS_BLEN 4 +#define FDB_TABLE_FUNC2_FDB_STATUS_FLAG HSL_RW + + + /* Address Table Control Register */ +#define ADDR_TABLE_CTL "atbc" +#define ADDR_TABLE_CTL_ID 14 +#define ADDR_TABLE_CTL_OFFSET 0x005C +#define ADDR_TABLE_CTL_E_LENGTH 4 +#define ADDR_TABLE_CTL_E_OFFSET 0 +#define ADDR_TABLE_CTL_NR_E 1 + +#define LOOP_CHK_TIME "atbc_lctime" +#define ADDR_TABLE_CTL_LOOP_CHK_TIME_BOFFSET 24 +#define ADDR_TABLE_CTL_LOOP_CHK_TIME_BLEN 3 +#define ADDR_TABLE_CTL_LOOP_CHK_TIME_FLAG HSL_RW + +#define RESVID_DROP "atbc_rviddrop" +#define ADDR_TABLE_CTL_RESVID_DROP_BOFFSET 22 +#define ADDR_TABLE_CTL_RESVID_DROP_BLEN 1 +#define ADDR_TABLE_CTL_RESVID_DROP_FLAG HSL_RW + +#define STAG_MODE "atbc_stag" +#define ADDR_TABLE_CTL_STAG_MODE_BOFFSET 21 +#define ADDR_TABLE_CTL_STAG_MODE_BLEN 1 +#define ADDR_TABLE_CTL_STAG_MODE_FLAG HSL_RW + +#define ARL_INI_EN "atbc_arlie" +#define ADDR_TABLE_CTL_ARL_INI_EN_BOFFSET 19 +#define ADDR_TABLE_CTL_ARL_INI_EN_BLEN 1 +#define ADDR_TABLE_CTL_ARL_INI_EN_FLAG HSL_RW + +#define LEARN_CHANGE_EN "atbc_lcen" +#define ADDR_TABLE_CTL_LEARN_CHANGE_EN_BOFFSET 18 +#define ADDR_TABLE_CTL_LEARN_CHANGE_EN_BLEN 1 +#define ADDR_TABLE_CTL_LEARN_CHANGE_EN_FLAG HSL_RW + +#define AGE_EN "atbc_agee" +#define ADDR_TABLE_CTL_AGE_EN_BOFFSET 17 +#define ADDR_TABLE_CTL_AGE_EN_BLEN 1 +#define ADDR_TABLE_CTL_AGE_EN_FLAG HSL_RW + +#define AGE_TIME "atbc_aget" +#define ADDR_TABLE_CTL_AGE_TIME_BOFFSET 0 +#define ADDR_TABLE_CTL_AGE_TIME_BLEN 16 +#define ADDR_TABLE_CTL_AGE_TIME_FLAG HSL_RW + + + /* IP Priority Mapping Register */ +#define IP_PRI_MAPPING "imap" +#define IP_PRI_MAPPING_ID 15 +#define IP_PRI_MAPPING_OFFSET 0x0060 +#define IP_PRI_MAPPING_E_LENGTH 4 +#define IP_PRI_MAPPING_E_OFFSET 0 +#define IP_PRI_MAPPING_NR_E 1 + + + /* IP Priority Mapping Register */ +#define IP_PRI_MAPPING0 "imap0" +#define IP_PRI_MAPPING0_ID 15 +#define IP_PRI_MAPPING0_OFFSET 0x0060 +#define IP_PRI_MAPPING0_E_LENGTH 4 +#define IP_PRI_MAPPING0_E_OFFSET 0 +#define IP_PRI_MAPPING0_NR_E 0 + +#define IP_0X3C "imap_ip3c" +#define IP_PRI_MAPPING0_IP_0X3C_BOFFSET 30 +#define IP_PRI_MAPPING0_IP_0X3C_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X3C_FLAG HSL_RW + +#define IP_0X38 "imap_ip38" +#define IP_PRI_MAPPING0_IP_0X38_BOFFSET 28 +#define IP_PRI_MAPPING0_IP_0X38_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X38_FLAG HSL_RW + +#define IP_0X34 "imap_ip34" +#define IP_PRI_MAPPING0_IP_0X34_BOFFSET 26 +#define IP_PRI_MAPPING0_IP_0X34_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X34_FLAG HSL_RW + +#define IP_0X30 "imap_ip30" +#define IP_PRI_MAPPING0_IP_0X30_BOFFSET 24 +#define IP_PRI_MAPPING0_IP_0X30_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X30_FLAG HSL_RW + +#define IP_0X2C "imap_ip2c" +#define IP_PRI_MAPPING0_IP_0X2C_BOFFSET 22 +#define IP_PRI_MAPPING0_IP_0X2C_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X2C_FLAG HSL_RW + +#define IP_0X28 "imap_ip28" +#define IP_PRI_MAPPING0_IP_0X28_BOFFSET 20 +#define IP_PRI_MAPPING0_IP_0X28_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X28_FLAG HSL_RW + +#define IP_0X24 "imap_ip24" +#define IP_PRI_MAPPING0_IP_0X24_BOFFSET 18 +#define IP_PRI_MAPPING0_IP_0X24_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X24_FLAG HSL_RW + +#define IP_0X20 "imap_ip20" +#define IP_PRI_MAPPING0_IP_0X20_BOFFSET 16 +#define IP_PRI_MAPPING0_IP_0X20_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X20_FLAG HSL_RW + +#define IP_0X1C "imap_ip1c" +#define IP_PRI_MAPPING0_IP_0X1C_BOFFSET 14 +#define IP_PRI_MAPPING0_IP_0X1C_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X1C_FLAG HSL_RW + +#define IP_0X18 "imap_ip18" +#define IP_PRI_MAPPING0_IP_0X18_BOFFSET 12 +#define IP_PRI_MAPPING0_IP_0X18_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X18_FLAG HSL_RW + +#define IP_0X14 "imap_ip14" +#define IP_PRI_MAPPING0_IP_0X14_BOFFSET 10 +#define IP_PRI_MAPPING0_IP_0X14_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X14_FLAG HSL_RW + +#define IP_0X10 "imap_ip10" +#define IP_PRI_MAPPING0_IP_0X10_BOFFSET 8 +#define IP_PRI_MAPPING0_IP_0X10_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X10_FLAG HSL_RW + +#define IP_0X0C "imap_ip0c" +#define IP_PRI_MAPPING0_IP_0X0C_BOFFSET 6 +#define IP_PRI_MAPPING0_IP_0X0C_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X0C_FLAG HSL_RW + +#define IP_0X08 "imap_ip08" +#define IP_PRI_MAPPING0_IP_0X08_BOFFSET 4 +#define IP_PRI_MAPPING0_IP_0X08_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X08_FLAG HSL_RW + +#define IP_0X04 "imap_ip04" +#define IP_PRI_MAPPING0_IP_0X04_BOFFSET 2 +#define IP_PRI_MAPPING0_IP_0X04_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X04_FLAG HSL_RW + +#define IP_0X00 "imap_ip00" +#define IP_PRI_MAPPING0_IP_0X00_BOFFSET 0 +#define IP_PRI_MAPPING0_IP_0X00_BLEN 2 +#define IP_PRI_MAPPING0_IP_0X00_FLAG HSL_RW + +#define IP_PRI_MAPPING1 "imap1" +#define IP_PRI_MAPPING1_ID 16 +#define IP_PRI_MAPPING1_OFFSET 0x0064 +#define IP_PRI_MAPPING1_E_LENGTH 4 +#define IP_PRI_MAPPING1_E_OFFSET 0 +#define IP_PRI_MAPPING1_NR_E 0 + +#define IP_0X7C "imap_ip7c" +#define IP_PRI_MAPPING1_IP_0X7C_BOFFSET 30 +#define IP_PRI_MAPPING1_IP_0X7C_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X7C_FLAG HSL_RW + +#define IP_0X78 "imap_ip78" +#define IP_PRI_MAPPING1_IP_0X78_BOFFSET 28 +#define IP_PRI_MAPPING1_IP_0X78_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X78_FLAG HSL_RW + +#define IP_0X74 "imap_ip74" +#define IP_PRI_MAPPING1_IP_0X74_BOFFSET 26 +#define IP_PRI_MAPPING1_IP_0X74_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X74_FLAG HSL_RW + +#define IP_0X70 "imap_ip70" +#define IP_PRI_MAPPING1_IP_0X70_BOFFSET 24 +#define IP_PRI_MAPPING1_IP_0X70_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X70_FLAG HSL_RW + +#define IP_0X6C "imap_ip6c" +#define IP_PRI_MAPPING1_IP_0X6C_BOFFSET 22 +#define IP_PRI_MAPPING1_IP_0X6C_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X6C_FLAG HSL_RW + +#define IP_0X68 "imap_ip68" +#define IP_PRI_MAPPING1_IP_0X68_BOFFSET 20 +#define IP_PRI_MAPPING1_IP_0X68_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X68_FLAG HSL_RW + +#define IP_0X64 "imap_ip64" +#define IP_PRI_MAPPING1_IP_0X64_BOFFSET 18 +#define IP_PRI_MAPPING1_IP_0X64_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X64_FLAG HSL_RW + +#define IP_0X60 "imap_ip60" +#define IP_PRI_MAPPING1_IP_0X60_BOFFSET 16 +#define IP_PRI_MAPPING1_IP_0X60_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X60_FLAG HSL_RW + +#define IP_0X5C "imap_ip5c" +#define IP_PRI_MAPPING1_IP_0X5C_BOFFSET 14 +#define IP_PRI_MAPPING1_IP_0X5C_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X5C_FLAG HSL_RW + +#define IP_0X58 "imap_ip58" +#define IP_PRI_MAPPING1_IP_0X58_BOFFSET 12 +#define IP_PRI_MAPPING1_IP_0X58_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X58_FLAG HSL_RW + +#define IP_0X54 "imap_ip54" +#define IP_PRI_MAPPING1_IP_0X54_BOFFSET 10 +#define IP_PRI_MAPPING1_IP_0X54_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X54_FLAG HSL_RW + +#define IP_0X50 "imap_ip50" +#define IP_PRI_MAPPING1_IP_0X50_BOFFSET 8 +#define IP_PRI_MAPPING1_IP_0X50_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X50_FLAG HSL_RW + +#define IP_0X4C "imap_ip4c" +#define IP_PRI_MAPPING1_IP_0X4C_BOFFSET 6 +#define IP_PRI_MAPPING1_IP_0X4C_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X4C_FLAG HSL_RW + +#define IP_0X48 "imap_ip48" +#define IP_PRI_MAPPING1_IP_0X48_BOFFSET 4 +#define IP_PRI_MAPPING1_IP_0X48_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X48_FLAG HSL_RW + +#define IP_0X44 "imap_ip44" +#define IP_PRI_MAPPING1_IP_0X44_BOFFSET 2 +#define IP_PRI_MAPPING1_IP_0X44_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X44_FLAG HSL_RW + +#define IP_0X40 "imap_ip40" +#define IP_PRI_MAPPING1_IP_0X40_BOFFSET 0 +#define IP_PRI_MAPPING1_IP_0X40_BLEN 2 +#define IP_PRI_MAPPING1_IP_0X40_FLAG HSL_RW + + +#define IP_PRI_MAPPING2 "imap2" +#define IP_PRI_MAPPING2_ID 17 +#define IP_PRI_MAPPING2_OFFSET 0x0068 +#define IP_PRI_MAPPING2_E_LENGTH 4 +#define IP_PRI_MAPPING2_E_OFFSET 0 +#define IP_PRI_MAPPING2_NR_E 0 + +#define IP_0XBC "imap_ipbc" +#define IP_PRI_MAPPING2_IP_0XBC_BOFFSET 30 +#define IP_PRI_MAPPING2_IP_0XBC_BLEN 2 +#define IP_PRI_MAPPING2_IP_0XBC_FLAG HSL_RW + +#define IP_0XB8 "imap_ipb8" +#define IP_PRI_MAPPING2_IP_0XB8_BOFFSET 28 +#define IP_PRI_MAPPING2_IP_0XB8_BLEN 2 +#define IP_PRI_MAPPING2_IP_0XB8_FLAG HSL_RW + +#define IP_0XB4 "imap_ipb4" +#define IP_PRI_MAPPING2_IP_0XB4_BOFFSET 26 +#define IP_PRI_MAPPING2_IP_0XB4_BLEN 2 +#define IP_PRI_MAPPING2_IP_0XB4_FLAG HSL_RW + +#define IP_0XB0 "imap_ipb0" +#define IP_PRI_MAPPING2_IP_0XB0_BOFFSET 24 +#define IP_PRI_MAPPING2_IP_0XB0_BLEN 2 +#define IP_PRI_MAPPING2_IP_0XB0_FLAG HSL_RW + +#define IP_0XAC "imap_ipac" +#define IP_PRI_MAPPING2_IP_0XAC_BOFFSET 22 +#define IP_PRI_MAPPING2_IP_0XAC_BLEN 2 +#define IP_PRI_MAPPING2_IP_0XAC_FLAG HSL_RW + +#define IP_0XA8 "imap_ipa8" +#define IP_PRI_MAPPING2_IP_0XA8_BOFFSET 20 +#define IP_PRI_MAPPING2_IP_0XA8_BLEN 2 +#define IP_PRI_MAPPING2_IP_0XA8_FLAG HSL_RW + +#define IP_0XA4 "imap_ipa4" +#define IP_PRI_MAPPING2_IP_0XA4_BOFFSET 18 +#define IP_PRI_MAPPING2_IP_0XA4_BLEN 2 +#define IP_PRI_MAPPING2_IP_0XA4_FLAG HSL_RW + +#define IP_0XA0 "imap_ipa0" +#define IP_PRI_MAPPING2_IP_0XA0_BOFFSET 16 +#define IP_PRI_MAPPING2_IP_0XA0_BLEN 2 +#define IP_PRI_MAPPING2_IP_0XA0_FLAG HSL_RW + +#define IP_0X9C "imap_ip9c" +#define IP_PRI_MAPPING2_IP_0X9C_BOFFSET 14 +#define IP_PRI_MAPPING2_IP_0X9C_BLEN 2 +#define IP_PRI_MAPPING2_IP_0X9C_FLAG HSL_RW + +#define IP_0X98 "imap_ip98" +#define IP_PRI_MAPPING2_IP_0X98_BOFFSET 12 +#define IP_PRI_MAPPING2_IP_0X98_BLEN 2 +#define IP_PRI_MAPPING2_IP_0X98_FLAG HSL_RW + +#define IP_0X94 "imap_ip94" +#define IP_PRI_MAPPING2_IP_0X94_BOFFSET 10 +#define IP_PRI_MAPPING2_IP_0X94_BLEN 2 +#define IP_PRI_MAPPING2_IP_0X94_FLAG HSL_RW + +#define IP_0X90 "imap_ip90" +#define IP_PRI_MAPPING2_IP_0X90_BOFFSET 8 +#define IP_PRI_MAPPING2_IP_0X90_BLEN 2 +#define IP_PRI_MAPPING2_IP_0X90_FLAG HSL_RW + +#define IP_0X8C "imap_ip8c" +#define IP_PRI_MAPPING2_IP_0X8C_BOFFSET 6 +#define IP_PRI_MAPPING2_IP_0X8C_BLEN 2 +#define IP_PRI_MAPPING2_IP_0X8C_FLAG HSL_RW + +#define IP_0X88 "imap_ip88" +#define IP_PRI_MAPPING2_IP_0X88_BOFFSET 4 +#define IP_PRI_MAPPING2_IP_0X88_BLEN 2 +#define IP_PRI_MAPPING2_IP_0X88_FLAG HSL_RW + +#define IP_0X84 "imap_ip84" +#define IP_PRI_MAPPING2_IP_0X84_BOFFSET 2 +#define IP_PRI_MAPPING2_IP_0X84_BLEN 2 +#define IP_PRI_MAPPING2_IP_0X84_FLAG HSL_RW + +#define IP_0X80 "imap_ip80" +#define IP_PRI_MAPPING2_IP_0X80_BOFFSET 0 +#define IP_PRI_MAPPING2_IP_0X80_BLEN 2 +#define IP_PRI_MAPPING2_IP_0X80_FLAG HSL_RW + +#define IP_PRI_MAPPING3 "imap3" +#define IP_PRI_MAPPING3_ID 18 +#define IP_PRI_MAPPING3_OFFSET 0x006C +#define IP_PRI_MAPPING3_E_LENGTH 4 +#define IP_PRI_MAPPING3_E_OFFSET 0 +#define IP_PRI_MAPPING3_NR_E 0 + +#define IP_0XFC "imap_ipfc" +#define IP_PRI_MAPPING3_IP_0XFC_BOFFSET 30 +#define IP_PRI_MAPPING3_IP_0XFC_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XFC_FLAG HSL_RW + +#define IP_0XF8 "imap_ipf8" +#define IP_PRI_MAPPING3_IP_0XF8_BOFFSET 28 +#define IP_PRI_MAPPING3_IP_0XF8_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XF8_FLAG HSL_RW + +#define IP_0XF4 "imap_ipf4" +#define IP_PRI_MAPPING3_IP_0XF4_BOFFSET 26 +#define IP_PRI_MAPPING3_IP_0XF4_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XF4_FLAG HSL_RW + +#define IP_0XF0 "imap_ipf0" +#define IP_PRI_MAPPING3_IP_0XF0_BOFFSET 24 +#define IP_PRI_MAPPING3_IP_0XF0_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XF0_FLAG HSL_RW + +#define IP_0XEC "imap_ipec" +#define IP_PRI_MAPPING3_IP_0XEC_BOFFSET 22 +#define IP_PRI_MAPPING3_IP_0XEC_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XEC_FLAG HSL_RW + +#define IP_0XE8 "imap_ipe8" +#define IP_PRI_MAPPING3_IP_0XE8_BOFFSET 20 +#define IP_PRI_MAPPING3_IP_0XE8_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XE8_FLAG HSL_RW + +#define IP_0XE4 "imap_ipe4" +#define IP_PRI_MAPPING3_IP_0XE4_BOFFSET 18 +#define IP_PRI_MAPPING3_IP_0XE4_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XE4_FLAG HSL_RW + +#define IP_0XE0 "imap_ipe0" +#define IP_PRI_MAPPING3_IP_0XE0_BOFFSET 16 +#define IP_PRI_MAPPING3_IP_0XE0_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XE0_FLAG HSL_RW + +#define IP_0XDC "imap_ipdc" +#define IP_PRI_MAPPING3_IP_0XDC_BOFFSET 14 +#define IP_PRI_MAPPING3_IP_0XDC_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XDC_FLAG HSL_RW + +#define IP_0XD8 "imap_ipd8" +#define IP_PRI_MAPPING3_IP_0XD8_BOFFSET 12 +#define IP_PRI_MAPPING3_IP_0XD8_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XD8_FLAG HSL_RW + +#define IP_0XD4 "imap_ipd4" +#define IP_PRI_MAPPING3_IP_0XD4_BOFFSET 10 +#define IP_PRI_MAPPING3_IP_0XD4_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XD4_FLAG HSL_RW + +#define IP_0XD0 "imap_ipd0" +#define IP_PRI_MAPPING3_IP_0XD0_BOFFSET 8 +#define IP_PRI_MAPPING3_IP_0XD0_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XD0_FLAG HSL_RW + +#define IP_0XCC "imap_ipcc" +#define IP_PRI_MAPPING3_IP_0XCC_BOFFSET 6 +#define IP_PRI_MAPPING3_IP_0XCC_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XCC_FLAG HSL_RW + +#define IP_0XC8 "imap_ipc8" +#define IP_PRI_MAPPING3_IP_0XC8_BOFFSET 4 +#define IP_PRI_MAPPING3_IP_0XC8_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XC8_FLAG HSL_RW + +#define IP_0XC4 "imap_ipc4" +#define IP_PRI_MAPPING3_IP_0XC4_BOFFSET 2 +#define IP_PRI_MAPPING3_IP_0XC4_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XC4_FLAG HSL_RW + +#define IP_0XC0 "imap_ipc0" +#define IP_PRI_MAPPING3_IP_0XC0_BOFFSET 0 +#define IP_PRI_MAPPING3_IP_0XC0_BLEN 2 +#define IP_PRI_MAPPING3_IP_0XC0_FLAG HSL_RW + + + /* Tag Priority Mapping Register */ +#define TAG_PRI_MAPPING "tpmap" +#define TAG_PRI_MAPPING_ID 19 +#define TAG_PRI_MAPPING_OFFSET 0x0070 +#define TAG_PRI_MAPPING_E_LENGTH 4 +#define TAG_PRI_MAPPING_E_OFFSET 0 +#define TAG_PRI_MAPPING_NR_E 1 + +#define TAG_0X07 "tpmap_tg07" +#define TAG_PRI_MAPPING_TAG_0X07_BOFFSET 14 +#define TAG_PRI_MAPPING_TAG_0X07_BLEN 2 +#define TAG_PRI_MAPPING_TAG_0X07_FLAG HSL_RW + +#define TAG_0X06 "tpmap_tg06" +#define TAG_PRI_MAPPING_TAG_0X06_BOFFSET 12 +#define TAG_PRI_MAPPING_TAG_0X06_BLEN 2 +#define TAG_PRI_MAPPING_TAG_0X06_FLAG HSL_RW + +#define TAG_0X05 "tpmap_tg05" +#define TAG_PRI_MAPPING_TAG_0X05_BOFFSET 10 +#define TAG_PRI_MAPPING_TAG_0X05_BLEN 2 +#define TAG_PRI_MAPPING_TAG_0X05_FLAG HSL_RW + +#define TAG_0X04 "tpmap_tg04" +#define TAG_PRI_MAPPING_TAG_0X04_BOFFSET 8 +#define TAG_PRI_MAPPING_TAG_0X04_BLEN 2 +#define TAG_PRI_MAPPING_TAG_0X04_FLAG HSL_RW + +#define TAG_0X03 "tpmap_tg03" +#define TAG_PRI_MAPPING_TAG_0X03_BOFFSET 6 +#define TAG_PRI_MAPPING_TAG_0X03_BLEN 2 +#define TAG_PRI_MAPPING_TAG_0X03_FLAG HSL_RW + +#define TAG_0X02 "tpmap_tg02" +#define TAG_PRI_MAPPING_TAG_0X02_BOFFSET 4 +#define TAG_PRI_MAPPING_TAG_0X02_BLEN 2 +#define TAG_PRI_MAPPING_TAG_0X02_FLAG HSL_RW + +#define TAG_0X01 "tpmap_tg01" +#define TAG_PRI_MAPPING_TAG_0X01_BOFFSET 2 +#define TAG_PRI_MAPPING_TAG_0X01_BLEN 2 +#define TAG_PRI_MAPPING_TAG_0X01_FLAG HSL_RW + +#define TAG_0X00 "tpmap_tg00" +#define TAG_PRI_MAPPING_TAG_0X00_BOFFSET 0 +#define TAG_PRI_MAPPING_TAG_0X00_BLEN 2 +#define TAG_PRI_MAPPING_TAG_0X00_FLAG HSL_RW + + + /* Service tag Register */ +#define SERVICE_TAG "servicetag" +#define SERVICE_TAG_ID 20 +#define SERVICE_TAG_OFFSET 0x0074 +#define SERVICE_TAG_E_LENGTH 4 +#define SERVICE_TAG_E_OFFSET 0 +#define SERVICE_TAG_NR_E 1 + +#define TAG_VALUE "servicetag_val" +#define SERVICE_TAG_TAG_VALUE_BOFFSET 0 +#define SERVICE_TAG_TAG_VALUE_BLEN 16 +#define SERVICE_TAG_TAG_VALUE_FLAG HSL_RW + + + /* Cpu Port Register */ +#define CPU_PORT "cpup" +#define CPU_PORT_ID 20 +#define CPU_PORT_OFFSET 0x0078 +#define CPU_PORT_E_LENGTH 4 +#define CPU_PORT_E_OFFSET 0 +#define CPU_PORT_NR_E 0 + +#define CPU_PORT_EN "cpup_cpupe" +#define CPU_PORT_CPU_PORT_EN_BOFFSET 8 +#define CPU_PORT_CPU_PORT_EN_BLEN 1 +#define CPU_PORT_CPU_PORT_EN_FLAG HSL_RW + +#define MIRROR_PORT_NUM "cpup_mirpn" +#define CPU_PORT_MIRROR_PORT_NUM_BOFFSET 4 +#define CPU_PORT_MIRROR_PORT_NUM_BLEN 4 +#define CPU_PORT_MIRROR_PORT_NUM_FLAG HSL_RW + + + /* MIB Function Register */ +#define MIB_FUNC "mibfunc" +#define MIB_FUNC_ID 21 +#define MIB_FUNC_OFFSET 0x0080 +#define MIB_FUNC_E_LENGTH 4 +#define MIB_FUNC_E_OFFSET 0 +#define MIB_FUNC_NR_E 1 + +#define MAC_CRC_EN "mibfunc_crcen" +#define MIB_FUNC_MAC_CRC_EN_BOFFSET 31 +#define MIB_FUNC_MAC_CRC_EN_BLEN 1 +#define MIB_FUNC_MAC_CRC_EN_FLAG HSL_RW + +#define MIB_EN "mib_en" +#define MIB_FUNC_MIB_EN_BOFFSET 30 +#define MIB_FUNC_MIB_EN_BLEN 1 +#define MIB_FUNC_MIB_EN_FLAG HSL_RW + +#define MIB_FUN "mibfunc_mibf" +#define MIB_FUNC_MIB_FUN_BOFFSET 24 +#define MIB_FUNC_MIB_FUN_BLEN 3 +#define MIB_FUNC_MIB_FUN_FLAG HSL_RW + +#define MIB_BUSY "mibfunc_mibb" +#define MIB_FUNC_MIB_BUSY_BOFFSET 17 +#define MIB_FUNC_MIB_BUSY_BLEN 1 +#define MIB_FUNC_MIB_BUSY_FLAG HSL_RW + +#define MIB_AT_HALF_EN "mibfunc_mibhe" +#define MIB_FUNC_MIB_AT_HALF_EN_BOFFSET 16 +#define MIB_FUNC_MIB_AT_HALF_EN_BLEN 1 +#define MIB_FUNC_MIB_AT_HALF_EN_FLAG HSL_RW + +#define MIB_TIMER "mibfunc_mibt" +#define MIB_FUNC_MIB_TIMER_BOFFSET 0 +#define MIB_FUNC_MIB_TIMER_BLEN 16 +#define MIB_FUNC_MIB_TIMER_FLAG HSL_RW + + + /* Mdio control Register */ +#define MDIO_CTRL "mctrl" +#define MDIO_CTRL_ID 24 +#define MDIO_CTRL_OFFSET 0x0098 +#define MDIO_CTRL_E_LENGTH 4 +#define MDIO_CTRL_E_OFFSET 0 +#define MDIO_CTRL_NR_E 1 + +#define MSTER_EN "mctrl_msteren" +#define MDIO_CTRL_MSTER_EN_BOFFSET 30 +#define MDIO_CTRL_MSTER_EN_BLEN 1 +#define MDIO_CTRL_MSTER_EN_FLAG HSL_RW + +#define MSTER_EN "mctrl_msteren" +#define MDIO_CTRL_MSTER_EN_BOFFSET 30 +#define MDIO_CTRL_MSTER_EN_BLEN 1 +#define MDIO_CTRL_MSTER_EN_FLAG HSL_RW + +#define CMD "mctrl_cmd" +#define MDIO_CTRL_CMD_BOFFSET 27 +#define MDIO_CTRL_CMD_BLEN 1 +#define MDIO_CTRL_CMD_FLAG HSL_RW + +#define SUP_PRE "mctrl_spre" +#define MDIO_CTRL_SUP_PRE_BOFFSET 26 +#define MDIO_CTRL_SUP_PRE_BLEN 1 +#define MDIO_CTRL_SUP_PRE_FLAG HSL_RW + +#define PHY_ADDR "mctrl_phyaddr" +#define MDIO_CTRL_PHY_ADDR_BOFFSET 21 +#define MDIO_CTRL_PHY_ADDR_BLEN 5 +#define MDIO_CTRL_PHY_ADDR_FLAG HSL_RW + +#define REG_ADDR "mctrl_regaddr" +#define MDIO_CTRL_REG_ADDR_BOFFSET 16 +#define MDIO_CTRL_REG_ADDR_BLEN 5 +#define MDIO_CTRL_REG_ADDR_FLAG HSL_RW + +#define DATA "mctrl_data" +#define MDIO_CTRL_DATA_BOFFSET 0 +#define MDIO_CTRL_DATA_BLEN 16 +#define MDIO_CTRL_DATA_FLAG HSL_RW + + + + + /* BIST control Register */ +#define BIST_CTRL "bctrl" +#define BIST_CTRL_ID 24 +#define BIST_CTRL_OFFSET 0x00a0 +#define BIST_CTRL_E_LENGTH 4 +#define BIST_CTRL_E_OFFSET 0 +#define BIST_CTRL_NR_E 1 + +#define BIST_BUSY "bctrl_bb" +#define BIST_CTRL_BIST_BUSY_BOFFSET 31 +#define BIST_CTRL_BIST_BUSY_BLEN 1 +#define BIST_CTRL_BIST_BUSY_FLAG HSL_RW + +#define ONE_ERR "bctrl_oe" +#define BIST_CTRL_ONE_ERR_BOFFSET 30 +#define BIST_CTRL_ONE_ERR_BLEN 1 +#define BIST_CTRL_ONE_ERR_FLAG HSL_RO + +#define ERR_MEM "bctrl_em" +#define BIST_CTRL_ERR_MEM_BOFFSET 24 +#define BIST_CTRL_ERR_MEM_BLEN 4 +#define BIST_CTRL_ERR_MEM_FLAG HSL_RO + +#define PTN_EN2 "bctrl_pe2" +#define BIST_CTRL_PTN_EN2_BOFFSET 22 +#define BIST_CTRL_PTN_EN2_BLEN 1 +#define BIST_CTRL_PTN_EN2_FLAG HSL_RW + +#define PTN_EN1 "bctrl_pe1" +#define BIST_CTRL_PTN_EN1_BOFFSET 21 +#define BIST_CTRL_PTN_EN1_BLEN 1 +#define BIST_CTRL_PTN_EN1_FLAG HSL_RW + +#define PTN_EN0 "bctrl_pe0" +#define BIST_CTRL_PTN_EN0_BOFFSET 20 +#define BIST_CTRL_PTN_EN0_BLEN 1 +#define BIST_CTRL_PTN_EN0_FLAG HSL_RW + +#define ERR_PTN "bctrl_ep" +#define BIST_CTRL_ERR_PTN_BOFFSET 16 +#define BIST_CTRL_ERR_PTN_BLEN 2 +#define BIST_CTRL_ERR_PTN_FLAG HSL_RO + +#define ERR_CNT "bctrl_ec" +#define BIST_CTRL_ERR_CNT_BOFFSET 13 +#define BIST_CTRL_ERR_CNT_BLEN 2 +#define BIST_CTRL_ERR_CNT_FLAG HSL_RO + +#define ERR_ADDR "bctrl_ea" +#define BIST_CTRL_ERR_ADDR_BOFFSET 0 +#define BIST_CTRL_ERR_ADDR_BLEN 12 +#define BIST_CTRL_ERR_ADDR_FLAG HSL_RO + + + + + /* BIST recover Register */ +#define BIST_RCV "brcv" +#define BIST_RCV_ID 24 +#define BIST_RCV_OFFSET 0x00a4 +#define BIST_RCV_E_LENGTH 4 +#define BIST_RCV_E_OFFSET 0 +#define BIST_RCV_NR_E 1 + +#define RCV_EN "brcv_en" +#define BIST_RCV_RCV_EN_BOFFSET 31 +#define BIST_RCV_RCV_EN_BLEN 1 +#define BIST_RCV_RCV_EN_FLAG HSL_RW + +#define RCV_ADDR "brcv_addr" +#define BIST_RCV_RCV_ADDR_BOFFSET 0 +#define BIST_RCV_RCV_ADDR_BLEN 12 +#define BIST_RCV_RCV_ADDR_FLAG HSL_RW + + + + + /* LED control Register */ +#define LED_CTRL "ledctrl" +#define LED_CTRL_ID 25 +#define LED_CTRL_OFFSET 0x00b0 +#define LED_CTRL_E_LENGTH 4 +#define LED_CTRL_E_OFFSET 0 +#define LED_CTRL_NR_E 1 + +#define PATTERN_EN "lctrl_pen" +#define LED_CTRL_PATTERN_EN_BOFFSET 14 +#define LED_CTRL_PATTERN_EN_BLEN 2 +#define LED_CTRL_PATTERN_EN_FLAG HSL_RW + +#define FULL_LIGHT_EN "lctrl_fen" +#define LED_CTRL_FULL_LIGHT_EN_BOFFSET 13 +#define LED_CTRL_FULL_LIGHT_EN_BLEN 1 +#define LED_CTRL_FULL_LIGHT_EN_FLAG HSL_RW + +#define HALF_LIGHT_EN "lctrl_hen" +#define LED_CTRL_HALF_LIGHT_EN_BOFFSET 12 +#define LED_CTRL_HALF_LIGHT_EN_BLEN 1 +#define LED_CTRL_HALF_LIGHT_EN_FLAG HSL_RW + +#define POWERON_LIGHT_EN "lctrl_poen" +#define LED_CTRL_POWERON_LIGHT_EN_BOFFSET 11 +#define LED_CTRL_POWERON_LIGHT_EN_BLEN 1 +#define LED_CTRL_POWERON_LIGHT_EN_FLAG HSL_RW + +#define GE_LIGHT_EN "lctrl_geen" +#define LED_CTRL_GE_LIGHT_EN_BOFFSET 10 +#define LED_CTRL_GE_LIGHT_EN_BLEN 1 +#define LED_CTRL_GE_LIGHT_EN_FLAG HSL_RW + +#define FE_LIGHT_EN "lctrl_feen" +#define LED_CTRL_FE_LIGHT_EN_BOFFSET 9 +#define LED_CTRL_FE_LIGHT_EN_BLEN 1 +#define LED_CTRL_FE_LIGHT_EN_FLAG HSL_RW + +#define ETH_LIGHT_EN "lctrl_ethen" +#define LED_CTRL_ETH_LIGHT_EN_BOFFSET 8 +#define LED_CTRL_ETH_LIGHT_EN_BLEN 1 +#define LED_CTRL_ETH_LIGHT_EN_FLAG HSL_RW + +#define COL_BLINK_EN "lctrl_cen" +#define LED_CTRL_COL_BLINK_EN_BOFFSET 7 +#define LED_CTRL_COL_BLINK_EN_BLEN 1 +#define LED_CTRL_COL_BLINK_EN_FLAG HSL_RW + +#define RX_BLINK_EN "lctrl_rxen" +#define LED_CTRL_RX_BLINK_EN_BOFFSET 5 +#define LED_CTRL_RX_BLINK_EN_BLEN 1 +#define LED_CTRL_RX_BLINK_EN_FLAG HSL_RW + +#define TX_BLINK_EN "lctrl_txen" +#define LED_CTRL_TX_BLINK_EN_BOFFSET 4 +#define LED_CTRL_TX_BLINK_EN_BLEN 1 +#define LED_CTRL_TX_BLINK_EN_FLAG HSL_RW + +#define LINKUP_OVER_EN "lctrl_loen" +#define LED_CTRL_LINKUP_OVER_EN_BOFFSET 2 +#define LED_CTRL_LINKUP_OVER_EN_BLEN 1 +#define LED_CTRL_LINKUP_OVER_EN_FLAG HSL_RW + +#define BLINK_FREQ "lctrl_bfreq" +#define LED_CTRL_BLINK_FREQ_BOFFSET 0 +#define LED_CTRL_BLINK_FREQ_BLEN 2 +#define LED_CTRL_BLINK_FREQ_FLAG HSL_RW + + /* LED control Register */ +#define LED_PATTERN "ledpatten" +#define LED_PATTERN_ID 25 +#define LED_PATTERN_OFFSET 0x00bc +#define LED_PATTERN_E_LENGTH 4 +#define LED_PATTERN_E_OFFSET 0 +#define LED_PATTERN_NR_E 1 + +#define P3L1_MODE "p3l1_mode" +#define LED_PATTERN_P3L1_MODE_BOFFSET 24 +#define LED_PATTERN_P3L1_MODE_BLEN 2 +#define LED_PATTERN_P3L1_MODE_FLAG HSL_RW + +#define P3L0_MODE "p3l0_mode" +#define LED_PATTERN_P3L0_MODE_BOFFSET 22 +#define LED_PATTERN_P3L0_MODE_BLEN 2 +#define LED_PATTERN_P3L0_MODE_FLAG HSL_RW + +#define P2L1_MODE "p2l1_mode" +#define LED_PATTERN_P2L1_MODE_BOFFSET 20 +#define LED_PATTERN_P2L1_MODE_BLEN 2 +#define LED_PATTERN_P2L1_MODE_FLAG HSL_RW + +#define P2L0_MODE "p2l0_mode" +#define LED_PATTERN_P2L0_MODE_BOFFSET 18 +#define LED_PATTERN_P2L0_MODE_BLEN 2 +#define LED_PATTERN_P2L0_MODE_FLAG HSL_RW + +#define P1L1_MODE "p1l1_mode" +#define LED_PATTERN_P1L1_MODE_BOFFSET 16 +#define LED_PATTERN_P1L1_MODE_BLEN 2 +#define LED_PATTERN_P1L1_MODE_FLAG HSL_RW + +#define P1L0_MODE "p1l0_mode" +#define LED_PATTERN_P1L0_MODE_BOFFSET 14 +#define LED_PATTERN_P1L0_MODE_BLEN 2 +#define LED_PATTERN_P1L0_MODE_FLAG HSL_RW + +#define M6_MODE "m6_mode" +#define LED_PATTERN_M6_MODE_BOFFSET 12 +#define LED_PATTERN_M6_MODE_BLEN 2 +#define LED_PATTERN_M6_MODE_FLAG HSL_RW + +#define M5_MODE "m5_mode" +#define LED_PATTERN_M5_MODE_BOFFSET 10 +#define LED_PATTERN_M5_MODE_BLEN 2 +#define LED_PATTERN_M5_MODE_FLAG HSL_RW + + + /* Port Status Register */ +#define PORT_STATUS "ptsts" +#define PORT_STATUS_ID 29 +#define PORT_STATUS_OFFSET 0x0100 +#define PORT_STATUS_E_LENGTH 4 +#define PORT_STATUS_E_OFFSET 0x0100 +#define PORT_STATUS_NR_E 7 + +#define FLOW_LINK_EN "ptsts_flen" +#define PORT_STATUS_FLOW_LINK_EN_BOFFSET 12 +#define PORT_STATUS_FLOW_LINK_EN_BLEN 1 +#define PORT_STATUS_FLOW_LINK_EN_FLAG HSL_RW + + +#define LINK_ASYN_PAUSE "ptsts_lasynp" +#define PORT_STATUS_LINK_ASYN_PAUSE_BOFFSET 11 +#define PORT_STATUS_LINK_ASYN_PAUSE_BLEN 1 +#define PORT_STATUS_LINK_ASYN_PAUSE_FLAG HSL_RO + +#define LINK_PAUSE "ptsts_lpause" +#define PORT_STATUS_LINK_PAUSE_BOFFSET 10 +#define PORT_STATUS_LINK_PAUSE_BLEN 1 +#define PORT_STATUS_LINK_PAUSE_FLAG HSL_RO + +#define LINK_EN "ptsts_linken" +#define PORT_STATUS_LINK_EN_BOFFSET 9 +#define PORT_STATUS_LINK_EN_BLEN 1 +#define PORT_STATUS_LINK_EN_FLAG HSL_RW + +#define LINK "ptsts_ptlink" +#define PORT_STATUS_LINK_BOFFSET 8 +#define PORT_STATUS_LINK_BLEN 1 +#define PORT_STATUS_LINK_FLAG HSL_RO + +#define TX_HALF_FLOW_EN +#define PORT_STATUS_TX_HALF_FLOW_EN_BOFFSET 7 +#define PORT_STATUS_TX_HALF_FLOW_EN_BLEN 1 +#define PORT_STATUS_TX_HALF_FLOW_EN_FLAG HSL_RW + +#define DUPLEX_MODE "ptsts_dupmod" +#define PORT_STATUS_DUPLEX_MODE_BOFFSET 6 +#define PORT_STATUS_DUPLEX_MODE_BLEN 1 +#define PORT_STATUS_DUPLEX_MODE_FLAG HSL_RW + +#define RX_FLOW_EN "ptsts_rxfwen" +#define PORT_STATUS_RX_FLOW_EN_BOFFSET 5 +#define PORT_STATUS_RX_FLOW_EN_BLEN 1 +#define PORT_STATUS_RX_FLOW_EN_FLAG HSL_RW + +#define TX_FLOW_EN "ptsts_txfwen" +#define PORT_STATUS_TX_FLOW_EN_BOFFSET 4 +#define PORT_STATUS_TX_FLOW_EN_BLEN 1 +#define PORT_STATUS_TX_FLOW_EN_FLAG HSL_RW + +#define RXMAC_EN "ptsts_rxmacen" +#define PORT_STATUS_RXMAC_EN_BOFFSET 3 +#define PORT_STATUS_RXMAC_EN_BLEN 1 +#define PORT_STATUS_RXMAC_EN_FLAG HSL_RW + +#define TXMAC_EN "ptsts_txmacen" +#define PORT_STATUS_TXMAC_EN_BOFFSET 2 +#define PORT_STATUS_TXMAC_EN_BLEN 1 +#define PORT_STATUS_TXMAC_EN_FLAG HSL_RW + +#define SPEED_MODE "ptsts_speed" +#define PORT_STATUS_SPEED_MODE_BOFFSET 0 +#define PORT_STATUS_SPEED_MODE_BLEN 2 +#define PORT_STATUS_SPEED_MODE_FLAG HSL_RW + + + /* Port Control Register */ +#define PORT_CTL "pctl" +#define PORT_CTL_ID 30 +#define PORT_CTL_OFFSET 0x0104 +#define PORT_CTL_E_LENGTH 4 +#define PORT_CTL_E_OFFSET 0x0100 +#define PORT_CTL_NR_E 7 + +#define EAPOL_EN "pctl_eapolen" +#define PORT_CTL_EAPOL_EN_BOFFSET 23 +#define PORT_CTL_EAPOL_EN_BLEN 1 +#define PORT_CTL_EAPOL_EN_FLAG HSL_RW + +#define ARP_LEAKY_EN "pbvlan_alen" +#define PORT_CTL_ARP_LEAKY_EN_BOFFSET 22 +#define PORT_CTL_ARP_LEAKY_EN_BLEN 1 +#define PORT_CTL_ARP_LEAKY_EN_FLAG HSL_RW + +#define LEAVE_EN "pctl_leaveen" +#define PORT_CTL_LEAVE_EN_BOFFSET 21 +#define PORT_CTL_LEAVE_EN_BLEN 1 +#define PORT_CTL_LEAVE_EN_FLAG HSL_RW + +#define JOIN_EN "pctl_joinen" +#define PORT_CTL_JOIN_EN_BOFFSET 20 +#define PORT_CTL_JOIN_EN_BLEN 1 +#define PORT_CTL_JOIN_EN_FLAG HSL_RW + +#define DHCP_EN "pctl_dhcpen" +#define PORT_CTL_DHCP_EN_BOFFSET 19 +#define PORT_CTL_DHCP_EN_BLEN 1 +#define PORT_CTL_DHCP_EN_FLAG HSL_RW + +#define ING_MIRROR_EN "pctl_ingmiren" +#define PORT_CTL_ING_MIRROR_EN_BOFFSET 17 +#define PORT_CTL_ING_MIRROR_EN_BLEN 1 +#define PORT_CTL_ING_MIRROR_EN_FLAG HSL_RW + +#define EG_MIRROR_EN "pctl_egmiren" +#define PORT_CTL_EG_MIRROR_EN_BOFFSET 16 +#define PORT_CTL_EG_MIRROR_EN_BLEN 1 +#define PORT_CTL_EG_MIRROR_EN_FLAG HSL_RW + +#define DTAG_EN "pctl_dtagen" +#define PORT_CTL_DTAG_EN_BOFFSET 15 +#define PORT_CTL_DTAG_EN_BLEN 1 +#define PORT_CTL_DTAG_EN_FLAG HSL_RW + +#define LEARN_EN "pctl_learnen" +#define PORT_CTL_LEARN_EN_BOFFSET 14 +#define PORT_CTL_LEARN_EN_BLEN 1 +#define PORT_CTL_LEARN_EN_FLAG HSL_RW + +#define SINGLE_VLAN_EN "pctl_svlanen" +#define PORT_CTL_SINGLE_VLAN_EN_BOFFSET 13 +#define PORT_CTL_SINGLE_VLAN_EN_BLEN 1 +#define PORT_CTL_SINGLE_VLAN_EN_FLAG HSL_RW + +#define MAC_LOOP_BACK "pctl_maclp" +#define PORT_CTL_MAC_LOOP_BACK_BOFFSET 12 +#define PORT_CTL_MAC_LOOP_BACK_BLEN 1 +#define PORT_CTL_MAC_LOOP_BACK_FLAG HSL_RW + +#define HEAD_EN "pctl_headen" +#define PORT_CTL_HEAD_EN_BOFFSET 11 +#define PORT_CTL_HEAD_EN_BLEN 1 +#define PORT_CTL_HEAD_EN_FLAG HSL_RW + +#define IGMP_MLD_EN "pctl_imlden" +#define PORT_CTL_IGMP_MLD_EN_BOFFSET 10 +#define PORT_CTL_IGMP_MLD_EN_BLEN 1 +#define PORT_CTL_IGMP_MLD_EN_FLAG HSL_RW + +#define EG_VLAN_MODE "pctl_egvmode" +#define PORT_CTL_EG_VLAN_MODE_BOFFSET 8 +#define PORT_CTL_EG_VLAN_MODE_BLEN 2 +#define PORT_CTL_EG_VLAN_MODE_FLAG HSL_RW + +#define LEARN_ONE_LOCK "pctl_lonelck" +#define PORT_CTL_LEARN_ONE_LOCK_BOFFSET 7 +#define PORT_CTL_LEARN_ONE_LOCK_BLEN 1 +#define PORT_CTL_LEARN_ONE_LOCK_FLAG HSL_RW + +#define PORT_LOCK_EN "pctl_locken" +#define PORT_CTL_PORT_LOCK_EN_BOFFSET 6 +#define PORT_CTL_PORT_LOCK_EN_BLEN 1 +#define PORT_CTL_PORT_LOCK_EN_FLAG HSL_RW + +#define LOCK_DROP_EN "pctl_dropen" +#define PORT_CTL_LOCK_DROP_EN_BOFFSET 5 +#define PORT_CTL_LOCK_DROP_EN_BLEN 1 +#define PORT_CTL_LOCK_DROP_EN_FLAG HSL_RW + +#define PORT_STATE "pctl_pstate" +#define PORT_CTL_PORT_STATE_BOFFSET 0 +#define PORT_CTL_PORT_STATE_BLEN 3 +#define PORT_CTL_PORT_STATE_FLAG HSL_RW + + + /* Port dot1ad Register */ +#define PORT_DOT1AD "pdot1ad" +#define PORT_DOT1AD_ID 31 +#define PORT_DOT1AD_OFFSET 0x0108 +#define PORT_DOT1AD_E_LENGTH 4 +#define PORT_DOT1AD_E_OFFSET 0x0100 +#define PORT_DOT1AD_NR_E 7 + +#define ING_PRI "pdot1ad_ingpri" +#define PORT_DOT1AD_ING_PRI_BOFFSET 29 +#define PORT_DOT1AD_ING_PRI_BLEN 3 +#define PORT_DOT1AD_ING_PRI_FLAG HSL_RW + +#define FORCE_PVLAN "pdot1ad_fpvlan" +#define PORT_DOT1AD_FORCE_PVLAN_BOFFSET 28 +#define PORT_DOT1AD_FORCE_PVLAN_BLEN 1 +#define PORT_DOT1AD_FORCE_PVLAN_FLAG HSL_RW + +#define DEF_CVID "pdot1ad_dcvid" +#define PORT_DOT1AD_DEF_CVID_BOFFSET 16 +#define PORT_DOT1AD_DEF_CVID_BLEN 12 +#define PORT_DOT1AD_DEF_CVID_FLAG HSL_RW + +#define CLONE "pdot1ad_clone" +#define PORT_DOT1AD_CLONE_BOFFSET 15 +#define PORT_DOT1AD_CLONE_BLEN 1 +#define PORT_DOT1AD_CLONE_FLAG HSL_RW + +#define PROPAGATION_EN "pdot1ad_pen" +#define PORT_DOT1AD_PROPAGATION_EN_BOFFSET 14 +#define PORT_DOT1AD_PROPAGATION_EN_BLEN 1 +#define PORT_DOT1AD_PROPAGATION_EN_FLAG HSL_RW + +#define TLS_EN "pdot1ad_tlsen" +#define PORT_DOT1AD_TLS_EN_BOFFSET 13 +#define PORT_DOT1AD_TLS_EN_BLEN 1 +#define PORT_DOT1AD_TLS_EN_FLAG HSL_RW + +#define FORCE_DEF_VID "pbot1ad_fdvid" +#define PORT_DOT1AD_FORCE_DEF_VID_BOFFSET 12 +#define PORT_DOT1AD_FORCE_DEF_VID_BLEN 1 +#define PORT_DOT1AD_FORCE_DEF_VID_FLAG HSL_RW + +#define DEF_SVID "pdot1ad_dsvid" +#define PORT_DOT1AD_DEF_SVID_BOFFSET 0 +#define PORT_DOT1AD_DEF_SVID_BLEN 12 +#define PORT_DOT1AD_DEF_SVID_FLAG HSL_RW + + + /* Port Based Vlan Register */ +#define PORT_BASE_VLAN "pbvlan" +#define PORT_BASE_VLAN_ID 31 +#define PORT_BASE_VLAN_OFFSET 0x010c +#define PORT_BASE_VLAN_E_LENGTH 4 +#define PORT_BASE_VLAN_E_OFFSET 0x0100 +#define PORT_BASE_VLAN_NR_E 7 + +#define DOT1Q_MODE "pbvlan_8021q" +#define PORT_BASE_VLAN_DOT1Q_MODE_BOFFSET 30 +#define PORT_BASE_VLAN_DOT1Q_MODE_BLEN 2 +#define PORT_BASE_VLAN_DOT1Q_MODE_FLAG HSL_RW + +#define COREP_EN "pbvlan_corepen" +#define PORT_BASE_VLAN_COREP_EN_BOFFSET 29 +#define PORT_BASE_VLAN_COREP_EN_BLEN 1 +#define PORT_BASE_VLAN_COREP_EN_FLAG HSL_RW + +#define IN_VLAN_MODE "pbvlan_imode" +#define PORT_BASE_VLAN_IN_VLAN_MODE_BOFFSET 27 +#define PORT_BASE_VLAN_IN_VLAN_MODE_BLEN 2 +#define PORT_BASE_VLAN_IN_VLAN_MODE_FLAG HSL_RW + +#define PRI_PROPAGATION "pbvlan_prip" +#define PORT_BASE_VLAN_PRI_PROPAGATION_BOFFSET 23 +#define PORT_BASE_VLAN_PRI_PROPAGATION_BLEN 1 +#define PORT_BASE_VLAN_PRI_PROPAGATION_FLAG HSL_RW + +#define PORT_VID_MEM "pbvlan_pvidm" +#define PORT_BASE_VLAN_PORT_VID_MEM_BOFFSET 16 +#define PORT_BASE_VLAN_PORT_VID_MEM_BLEN 7 +#define PORT_BASE_VLAN_PORT_VID_MEM_FLAG HSL_RW + +#define UNI_LEAKY_EN "pbvlan_ulen" +#define PORT_BASE_VLAN_UNI_LEAKY_EN_BOFFSET 14 +#define PORT_BASE_VLAN_UNI_LEAKY_EN_BLEN 1 +#define PORT_BASE_VLAN_UNI_LEAKY_EN_FLAG HSL_RW + +#define MUL_LEAKY_EN "pbvlan_mlen" +#define PORT_BASE_VLAN_MUL_LEAKY_EN_BOFFSET 13 +#define PORT_BASE_VLAN_MUL_LEAKY_EN_BLEN 1 +#define PORT_BASE_VLAN_MUL_LEAKY_EN_FLAG HSL_RW + + + /* Port Rate Limit0 Register */ +#define RATE_LIMIT0 "rlmt0" +#define RATE_LIMIT0_ID 32 +#define RATE_LIMIT0_OFFSET 0x0110 +#define RATE_LIMIT0_E_LENGTH 4 +#define RATE_LIMIT0_E_OFFSET 0x0100 +#define RATE_LIMIT0_NR_E 7 + +#define ADD_RATE_BYTE "rlmt_addbyte" +#define RATE_LIMIT0_ADD_RATE_BYTE_BOFFSET 24 +#define RATE_LIMIT0_ADD_RATE_BYTE_BLEN 8 +#define RATE_LIMIT0_ADD_RATE_BYTE_FLAG HSL_RW + +#define EG_RATE_EN "rlmt_egen" +#define RATE_LIMIT0_EG_RATE_EN_BOFFSET 23 +#define RATE_LIMIT0_EG_RATE_EN_BLEN 1 +#define RATE_LIMIT0_EG_RATE_EN_FLAG HSL_RW + +#define EG_MNG_RATE_EN "rlmt_egmngen" +#define RATE_LIMIT0_EG_MNG_RATE_EN_BOFFSET 22 +#define RATE_LIMIT0_EG_MNG_RATE_EN_BLEN 1 +#define RATE_LIMIT0_EG_MNG_RATE_EN_FLAG HSL_RW + +#define IN_MNG_RATE_EN "rlmt_inmngen" +#define RATE_LIMIT0_IN_MNG_RATE_EN_BOFFSET 21 +#define RATE_LIMIT0_IN_MNG_RATE_EN_BLEN 1 +#define RATE_LIMIT0_IN_MNG_RATE_EN_FLAG HSL_RW + +#define IN_MUL_RATE_EN "rlmt_inmulen" +#define RATE_LIMIT0_IN_MUL_RATE_EN_BOFFSET 20 +#define RATE_LIMIT0_IN_MUL_RATE_EN_BLEN 1 +#define RATE_LIMIT0_IN_MUL_RATE_EN_FLAG HSL_RW + +#define ING_RATE "rlmt_ingrate" +#define RATE_LIMIT0_ING_RATE_BOFFSET 0 +#define RATE_LIMIT0_ING_RATE_BLEN 15 +#define RATE_LIMIT0_ING_RATE_FLAG HSL_RW + + + /* Priority Control Register */ +#define PRI_CTL "prctl" +#define PRI_CTL_ID 33 +#define PRI_CTL_OFFSET 0x0114 +#define PRI_CTL_E_LENGTH 4 +#define PRI_CTL_E_OFFSET 0x0100 +#define PRI_CTL_NR_E 7 + +#define PORT_PRI_EN "prctl_ptprien" +#define PRI_CTL_PORT_PRI_EN_BOFFSET 19 +#define PRI_CTL_PORT_PRI_EN_BLEN 1 +#define PRI_CTL_PORT_PRI_EN_FLAG HSL_RW + +#define DA_PRI_EN "prctl_daprien" +#define PRI_CTL_DA_PRI_EN_BOFFSET 18 +#define PRI_CTL_DA_PRI_EN_BLEN 1 +#define PRI_CTL_DA_PRI_EN_FLAG HSL_RW + +#define VLAN_PRI_EN "prctl_vprien" +#define PRI_CTL_VLAN_PRI_EN_BOFFSET 17 +#define PRI_CTL_VLAN_PRI_EN_BLEN 1 +#define PRI_CTL_VLAN_PRI_EN_FLAG HSL_RW + +#define IP_PRI_EN "prctl_ipprien" +#define PRI_CTL_IP_PRI_EN_BOFFSET 16 +#define PRI_CTL_IP_PRI_EN_BLEN 1 +#define PRI_CTL_IP_PRI_EN_FLAG HSL_RW + +#define DA_PRI_SEL "prctl_dapris" +#define PRI_CTL_DA_PRI_SEL_BOFFSET 6 +#define PRI_CTL_DA_PRI_SEL_BLEN 2 +#define PRI_CTL_DA_PRI_SEL_FLAG HSL_RW + +#define VLAN_PRI_SEL "prctl_vpris" +#define PRI_CTL_VLAN_PRI_SEL_BOFFSET 4 +#define PRI_CTL_VLAN_PRI_SEL_BLEN 2 +#define PRI_CTL_VLAN_PRI_SEL_FLAG HSL_RW + +#define IP_PRI_SEL "prctl_ippris" +#define PRI_CTL_IP_PRI_SEL_BOFFSET 2 +#define PRI_CTL_IP_PRI_SEL_BLEN 2 +#define PRI_CTL_IP_PRI_SEL_FLAG HSL_RW + +#define PORT_PRI_SEL "prctl_ptpris" +#define PRI_CTL_PORT_PRI_SEL_BOFFSET 0 +#define PRI_CTL_PORT_PRI_SEL_BLEN 2 +#define PRI_CTL_PORT_PRI_SEL_FLAG HSL_RW + + + /* Storm Control Register */ +#define STORM_CTL "sctrl" +#define STORM_CTL_ID 33 +#define STORM_CTL_OFFSET 0x0118 +#define STORM_CTL_E_LENGTH 4 +#define STORM_CTL_E_OFFSET 0x0100 +#define STORM_CTL_NR_E 7 + +#define UNIT "sctrl_unit" +#define STORM_CTL_UNIT_BOFFSET 24 +#define STORM_CTL_UNIT_BLEN 2 +#define STORM_CTL_UNIT_FLAG HSL_RW + +#define MUL_EN "sctrl_mulen" +#define STORM_CTL_MUL_EN_BOFFSET 10 +#define STORM_CTL_MUL_EN_BLEN 1 +#define STORM_CTL_MUL_EN_FLAG HSL_RW + +#define UNI_EN "sctrl_unien" +#define STORM_CTL_UNI_EN_BOFFSET 9 +#define STORM_CTL_UNI_EN_BLEN 1 +#define STORM_CTL_UNI_EN_FLAG HSL_RW + +#define BRO_EN "sctrl_broen" +#define STORM_CTL_BRO_EN_BOFFSET 8 +#define STORM_CTL_BRO_EN_BLEN 1 +#define STORM_CTL_BRO_EN_FLAG HSL_RW + +#define RATE "sctrl_rate" +#define STORM_CTL_RATE_BOFFSET 0 +#define STORM_CTL_RATE_BLEN 4 +#define STORM_CTL_RATE_FLAG HSL_RW + + + /* Queue Control Register */ +#define QUEUE_CTL "qctl" +#define QUEUE_CTL_ID 34 +#define QUEUE_CTL_OFFSET 0x011c +#define QUEUE_CTL_E_LENGTH 4 +#define QUEUE_CTL_E_OFFSET 0x0100 +#define QUEUE_CTL_NR_E 7 + +#define PORT_IN_DESC_EN "qctl_pdescen" +#define QUEUE_CTL_PORT_IN_DESC_EN_BOFFSET 28 +#define QUEUE_CTL_PORT_IN_DESC_EN_BLEN 4 +#define QUEUE_CTL_PORT_IN_DESC_EN_FLAG HSL_RW + +#define PORT_DESC_EN "qctl_pdescen" +#define QUEUE_CTL_PORT_DESC_EN_BOFFSET 25 +#define QUEUE_CTL_PORT_DESC_EN_BLEN 1 +#define QUEUE_CTL_PORT_DESC_EN_FLAG HSL_RW + +#define QUEUE_DESC_EN "qctl_qdescen" +#define QUEUE_CTL_QUEUE_DESC_EN_BOFFSET 24 +#define QUEUE_CTL_QUEUE_DESC_EN_BLEN 1 +#define QUEUE_CTL_QUEUE_DESC_EN_FLAG HSL_RW + +#define PORT_DESC_NR "qctl_pdscpnr" +#define QUEUE_CTL_PORT_DESC_NR_BOFFSET 16 +#define QUEUE_CTL_PORT_DESC_NR_BLEN 6 +#define QUEUE_CTL_PORT_DESC_NR_FLAG HSL_RW + +#define QUEUE3_DESC_NR "qctl_q3dscpnr" +#define QUEUE_CTL_QUEUE3_DESC_NR_BOFFSET 12 +#define QUEUE_CTL_QUEUE3_DESC_NR_BLEN 4 +#define QUEUE_CTL_QUEUE3_DESC_NR_FLAG HSL_RW + +#define QUEUE2_DESC_NR "qctl_q2dscpnr" +#define QUEUE_CTL_QUEUE2_DESC_NR_BOFFSET 8 +#define QUEUE_CTL_QUEUE2_DESC_NR_BLEN 4 +#define QUEUE_CTL_QUEUE2_DESC_NR_FLAG HSL_RW + +#define QUEUE1_DESC_NR "qctl_q1dscpnr" +#define QUEUE_CTL_QUEUE1_DESC_NR_BOFFSET 4 +#define QUEUE_CTL_QUEUE1_DESC_NR_BLEN 4 +#define QUEUE_CTL_QUEUE1_DESC_NR_FLAG HSL_RW + +#define QUEUE0_DESC_NR "qctl_q0dscpnr" +#define QUEUE_CTL_QUEUE0_DESC_NR_BOFFSET 0 +#define QUEUE_CTL_QUEUE0_DESC_NR_BLEN 4 +#define QUEUE_CTL_QUEUE0_DESC_NR_FLAG HSL_RW + + + /* Port Rate Limit1 Register */ +#define RATE_LIMIT1 "rlmt1" +#define RATE_LIMIT1_ID 32 +#define RATE_LIMIT1_OFFSET 0x0120 +#define RATE_LIMIT1_E_LENGTH 4 +#define RATE_LIMIT1_E_OFFSET 0x0100 +#define RATE_LIMIT1_NR_E 7 + +#define EG_Q1_RATE "rlmt_egq1rate" +#define RATE_LIMIT1_EG_Q1_RATE_BOFFSET 16 +#define RATE_LIMIT1_EG_Q1_RATE_BLEN 15 +#define RATE_LIMIT1_EG_Q1_RATE_FLAG HSL_RW + +#define EG_Q0_RATE "rlmt_egq0rate" +#define RATE_LIMIT1_EG_Q0_RATE_BOFFSET 0 +#define RATE_LIMIT1_EG_Q0_RATE_BLEN 15 +#define RATE_LIMIT1_EG_Q0_RATE_FLAG HSL_RW + + + /* Port Rate Limit2 Register */ +#define RATE_LIMIT2 "rlmt2" +#define RATE_LIMIT2_ID 32 +#define RATE_LIMIT2_OFFSET 0x0124 +#define RATE_LIMIT2_E_LENGTH 4 +#define RATE_LIMIT2_E_OFFSET 0x0100 +#define RATE_LIMIT2_NR_E 7 + +#define EG_Q3_RATE "rlmt_egq3rate" +#define RATE_LIMIT2_EG_Q3_RATE_BOFFSET 16 +#define RATE_LIMIT2_EG_Q3_RATE_BLEN 15 +#define RATE_LIMIT2_EG_Q3_RATE_FLAG HSL_RW + +#define EG_Q2_RATE "rlmt_egq2rate" +#define RATE_LIMIT2_EG_Q2_RATE_BOFFSET 0 +#define RATE_LIMIT2_EG_Q2_RATE_BLEN 15 +#define RATE_LIMIT2_EG_Q2_RATE_FLAG HSL_RW + + + + + /* Port Rate Limit3 Register */ +#define RATE_LIMIT3 "rlmt3" +#define RATE_LIMIT3_ID 32 +#define RATE_LIMIT3_OFFSET 0x0128 +#define RATE_LIMIT3_E_LENGTH 4 +#define RATE_LIMIT3_E_OFFSET 0x0100 +#define RATE_LIMIT3_NR_E 7 + +#define EG_Q3_CBS "rlmt_egq3cbs" +#define RATE_LIMIT3_EG_Q3_CBS_BOFFSET 22 +#define RATE_LIMIT3_EG_Q3_CBS_BLEN 2 +#define RATE_LIMIT3_EG_Q3_CBS_FLAG HSL_RW + +#define EG_Q2_CBS "rlmt_egq2cbs" +#define RATE_LIMIT3_EG_Q2_CBS_BOFFSET 20 +#define RATE_LIMIT3_EG_Q2_CBS_BLEN 2 +#define RATE_LIMIT3_EG_Q2_CBS_FLAG HSL_RW + +#define EG_Q1_CBS "rlmt_egq1cbs" +#define RATE_LIMIT3_EG_Q1_CBS_BOFFSET 18 +#define RATE_LIMIT3_EG_Q1_CBS_BLEN 2 +#define RATE_LIMIT3_EG_Q1_CBS_FLAG HSL_RW + +#define EG_Q0_CBS "rlmt_egq0cbs" +#define RATE_LIMIT3_EG_Q0_CBS_BOFFSET 16 +#define RATE_LIMIT3_EG_Q0_CBS_BLEN 2 +#define RATE_LIMIT3_EG_Q0_CBS_FLAG HSL_RW + +#define EG_TS "rlmt_egts" +#define RATE_LIMIT3_EG_TS_BOFFSET 0 +#define RATE_LIMIT3_EG_TS_BLEN 3 +#define RATE_LIMIT3_EG_TS_FLAG HSL_RW + + + + + /* Port Rate Limit2 Register */ +#define WRR_CTRL "wrrc" +#define WRR_CTRL_ID 32 +#define WRR_CTRL_OFFSET 0x012c +#define WRR_CTRL_E_LENGTH 4 +#define WRR_CTRL_E_OFFSET 0x0100 +#define WRR_CTRL_NR_E 7 + +#define SCH_MODE "wrrc_mode" +#define WRR_CTRL_SCH_MODE_BOFFSET 29 +#define WRR_CTRL_SCH_MODE_BLEN 2 +#define WRR_CTRL_SCH_MODE_FLAG HSL_RW + +#define Q3_W "wrrc_q3w" +#define WRR_CTRL_Q3_W_BOFFSET 24 +#define WRR_CTRL_Q3_W_BLEN 5 +#define WRR_CTRL_Q3_W_FLAG HSL_RW + +#define Q2_W "wrrc_q2w" +#define WRR_CTRL_Q2_W_BOFFSET 16 +#define WRR_CTRL_Q2_W_BLEN 5 +#define WRR_CTRL_Q2_W_FLAG HSL_RW + +#define Q1_W "wrrc_q1w" +#define WRR_CTRL_Q1_W_BOFFSET 8 +#define WRR_CTRL_Q1_W_BLEN 5 +#define WRR_CTRL_Q1_W_FLAG HSL_RW + +#define Q0_W "wrrc_q0w" +#define WRR_CTRL_Q0_W_BOFFSET 0 +#define WRR_CTRL_Q0_W_BLEN 5 +#define WRR_CTRL_Q0_W_FLAG HSL_RW + + + /* mib memory info */ +#define MIB_RXBROAD "RxBroad" +#define MIB_RXBROAD_ID 34 +#define MIB_RXBROAD_OFFSET 0x20000 +#define MIB_RXBROAD_E_LENGTH 4 +#define MIB_RXBROAD_E_OFFSET 0x100 +#define MIB_RXBROAD_NR_E 6 + +#define MIB_RXPAUSE "RxPause" +#define MIB_RXPAUSE_ID 35 +#define MIB_RXPAUSE_OFFSET 0x20004 +#define MIB_RXPAUSE_E_LENGTH 4 +#define MIB_RXPAUSE_E_OFFSET 0x100 +#define MIB_RXPAUSE_NR_E 6 + +#define MIB_RXMULTI "RxMulti" +#define MIB_RXMULTI_ID 36 +#define MIB_RXMULTI_OFFSET 0x20008 +#define MIB_RXMULTI_E_LENGTH 4 +#define MIB_RXMULTI_E_OFFSET 0x100 +#define MIB_RXMULTI_NR_E 6 + +#define MIB_RXFCSERR "RxFcsErr" +#define MIB_RXFCSERR_ID 37 +#define MIB_RXFCSERR_OFFSET 0x2000c +#define MIB_RXFCSERR_E_LENGTH 4 +#define MIB_RXFCSERR_E_OFFSET 0x100 +#define MIB_RXFCSERR_NR_E 6 + +#define MIB_RXALLIGNERR "RxAllignErr" +#define MIB_RXALLIGNERR_ID 38 +#define MIB_RXALLIGNERR_OFFSET 0x20010 +#define MIB_RXALLIGNERR_E_LENGTH 4 +#define MIB_RXALLIGNERR_E_OFFSET 0x100 +#define MIB_RXALLIGNERR_NR_E 6 + +#define MIB_RXRUNT "RxRunt" +#define MIB_RXRUNT_ID 39 +#define MIB_RXRUNT_OFFSET 0x20014 +#define MIB_RXRUNT_E_LENGTH 4 +#define MIB_RXRUNT_E_OFFSET 0x100 +#define MIB_RXRUNT_NR_E 6 + +#define MIB_RXFRAGMENT "RxFragment" +#define MIB_RXFRAGMENT_ID 40 +#define MIB_RXFRAGMENT_OFFSET 0x20018 +#define MIB_RXFRAGMENT_E_LENGTH 4 +#define MIB_RXFRAGMENT_E_OFFSET 0x100 +#define MIB_RXFRAGMENT_NR_E 6 + +#define MIB_RX64BYTE "Rx64Byte" +#define MIB_RX64BYTE_ID 41 +#define MIB_RX64BYTE_OFFSET 0x2001c +#define MIB_RX64BYTE_E_LENGTH 4 +#define MIB_RX64BYTE_E_OFFSET 0x100 +#define MIB_RX64BYTE_NR_E 6 + +#define MIB_RX128BYTE "Rx128Byte" +#define MIB_RX128BYTE_ID 42 +#define MIB_RX128BYTE_OFFSET 0x20020 +#define MIB_RX128BYTE_E_LENGTH 4 +#define MIB_RX128BYTE_E_OFFSET 0x100 +#define MIB_RX128BYTE_NR_E 6 + +#define MIB_RX256BYTE "Rx256Byte" +#define MIB_RX256BYTE_ID 43 +#define MIB_RX256BYTE_OFFSET 0x20024 +#define MIB_RX256BYTE_E_LENGTH 4 +#define MIB_RX256BYTE_E_OFFSET 0x100 +#define MIB_RX256BYTE_NR_E 6 + +#define MIB_RX512BYTE "Rx512Byte" +#define MIB_RX512BYTE_ID 44 +#define MIB_RX512BYTE_OFFSET 0x20028 +#define MIB_RX512BYTE_E_LENGTH 4 +#define MIB_RX512BYTE_E_OFFSET 0x100 +#define MIB_RX512BYTE_NR_E 6 + +#define MIB_RX1024BYTE "Rx1024Byte" +#define MIB_RX1024BYTE_ID 45 +#define MIB_RX1024BYTE_OFFSET 0x2002c +#define MIB_RX1024BYTE_E_LENGTH 4 +#define MIB_RX1024BYTE_E_OFFSET 0x100 +#define MIB_RX1024BYTE_NR_E 6 + +#define MIB_RX1518BYTE "Rx1518Byte" +#define MIB_RX1518BYTE_ID 45 +#define MIB_RX1518BYTE_OFFSET 0x20030 +#define MIB_RX1518BYTE_E_LENGTH 4 +#define MIB_RX1518BYTE_E_OFFSET 0x100 +#define MIB_RX1518BYTE_NR_E 6 + +#define MIB_RXMAXBYTE "RxMaxByte" +#define MIB_RXMAXBYTE_ID 46 +#define MIB_RXMAXBYTE_OFFSET 0x20034 +#define MIB_RXMAXBYTE_E_LENGTH 4 +#define MIB_RXMAXBYTE_E_OFFSET 0x100 +#define MIB_RXMAXBYTE_NR_E 6 + +#define MIB_RXTOOLONG "RxTooLong" +#define MIB_RXTOOLONG_ID 47 +#define MIB_RXTOOLONG_OFFSET 0x20038 +#define MIB_RXTOOLONG_E_LENGTH 4 +#define MIB_RXTOOLONG_E_OFFSET 0x100 +#define MIB_RXTOOLONG_NR_E 6 + +#define MIB_RXGOODBYTE_LO "RxGoodByteLo" +#define MIB_RXGOODBYTE_LO_ID 48 +#define MIB_RXGOODBYTE_LO_OFFSET 0x2003c +#define MIB_RXGOODBYTE_LO_E_LENGTH 4 +#define MIB_RXGOODBYTE_LO_E_OFFSET 0x100 +#define MIB_RXGOODBYTE_LO_NR_E 6 + +#define MIB_RXGOODBYTE_HI "RxGoodByteHi" +#define MIB_RXGOODBYTE_HI_ID 49 +#define MIB_RXGOODBYTE_HI_OFFSET 0x20040 +#define MIB_RXGOODBYTE_HI_E_LENGTH 4 +#define MIB_RXGOODBYTE_HI_E_OFFSET 0x100 +#define MIB_RXGOODBYTE_HI_NR_E 6 + +#define MIB_RXBADBYTE_LO "RxBadByteLo" +#define MIB_RXBADBYTE_LO_ID 50 +#define MIB_RXBADBYTE_LO_OFFSET 0x20044 +#define MIB_RXBADBYTE_LO_E_LENGTH 4 +#define MIB_RXBADBYTE_LO_E_OFFSET 0x100 +#define MIB_RXBADBYTE_LO_NR_E 6 + +#define MIB_RXBADBYTE_HI "RxBadByteHi" +#define MIB_RXBADBYTE_HI_ID 51 +#define MIB_RXBADBYTE_HI_OFFSET 0x20048 +#define MIB_RXBADBYTE_HI_E_LENGTH 4 +#define MIB_RXBADBYTE_HI_E_OFFSET 0x100 +#define MIB_RXBADBYTE_HI_NR_E 6 + +#define MIB_RXOVERFLOW "RxOverFlow" +#define MIB_RXOVERFLOW_ID 52 +#define MIB_RXOVERFLOW_OFFSET 0x2004c +#define MIB_RXOVERFLOW_E_LENGTH 4 +#define MIB_RXOVERFLOW_E_OFFSET 0x100 +#define MIB_RXOVERFLOW_NR_E 6 + +#define MIB_FILTERED "Filtered" +#define MIB_FILTERED_ID 53 +#define MIB_FILTERED_OFFSET 0x20050 +#define MIB_FILTERED_E_LENGTH 4 +#define MIB_FILTERED_E_OFFSET 0x100 +#define MIB_FILTERED_NR_E 6 + +#define MIB_TXBROAD "TxBroad" +#define MIB_TXBROAD_ID 54 +#define MIB_TXBROAD_OFFSET 0x20054 +#define MIB_TXBROAD_E_LENGTH 4 +#define MIB_TXBROAD_E_OFFSET 0x100 +#define MIB_TXBROAD_NR_E 6 + +#define MIB_TXPAUSE "TxPause" +#define MIB_TXPAUSE_ID 55 +#define MIB_TXPAUSE_OFFSET 0x20058 +#define MIB_TXPAUSE_E_LENGTH 4 +#define MIB_TXPAUSE_E_OFFSET 0x100 +#define MIB_TXPAUSE_NR_E 6 + +#define MIB_TXMULTI "TxMulti" +#define MIB_TXMULTI_ID 56 +#define MIB_TXMULTI_OFFSET 0x2005c +#define MIB_TXMULTI_E_LENGTH 4 +#define MIB_TXMULTI_E_OFFSET 0x100 +#define MIB_TXMULTI_NR_E 6 + +#define MIB_TXUNDERRUN "TxUnderRun" +#define MIB_TXUNDERRUN_ID 57 +#define MIB_TXUNDERRUN_OFFSET 0x20060 +#define MIB_TXUNDERRUN_E_LENGTH 4 +#define MIB_TXUNDERRUN_E_OFFSET 0x100 +#define MIB_TXUNDERRUN_NR_E 6 + +#define MIB_TX64BYTE "Tx64Byte" +#define MIB_TX64BYTE_ID 58 +#define MIB_TX64BYTE_OFFSET 0x20064 +#define MIB_TX64BYTE_E_LENGTH 4 +#define MIB_TX64BYTE_E_OFFSET 0x100 +#define MIB_TX64BYTE_NR_E 6 + +#define MIB_TX128BYTE "Tx128Byte" +#define MIB_TX128BYTE_ID 59 +#define MIB_TX128BYTE_OFFSET 0x20068 +#define MIB_TX128BYTE_E_LENGTH 4 +#define MIB_TX128BYTE_E_OFFSET 0x100 +#define MIB_TX128BYTE_NR_E 6 + +#define MIB_TX256BYTE "Tx256Byte" +#define MIB_TX256BYTE_ID 60 +#define MIB_TX256BYTE_OFFSET 0x2006c +#define MIB_TX256BYTE_E_LENGTH 4 +#define MIB_TX256BYTE_E_OFFSET 0x100 +#define MIB_TX256BYTE_NR_E 6 + +#define MIB_TX512BYTE "Tx512Byte" +#define MIB_TX512BYTE_ID 61 +#define MIB_TX512BYTE_OFFSET 0x20070 +#define MIB_TX512BYTE_E_LENGTH 4 +#define MIB_TX512BYTE_E_OFFSET 0x100 +#define MIB_TX512BYTE_NR_E 6 + +#define MIB_TX1024BYTE "Tx1024Byte" +#define MIB_TX1024BYTE_ID 62 +#define MIB_TX1024BYTE_OFFSET 0x20074 +#define MIB_TX1024BYTE_E_LENGTH 4 +#define MIB_TX1024BYTE_E_OFFSET 0x100 +#define MIB_TX1024BYTE_NR_E 6 + +#define MIB_TX1518BYTE "Tx1518Byte" +#define MIB_TX1518BYTE_ID 62 +#define MIB_TX1518BYTE_OFFSET 0x20078 +#define MIB_TX1518BYTE_E_LENGTH 4 +#define MIB_TX1518BYTE_E_OFFSET 0x100 +#define MIB_TX1518BYTE_NR_E 6 + +#define MIB_TXMAXBYTE "TxMaxByte" +#define MIB_TXMAXBYTE_ID 63 +#define MIB_TXMAXBYTE_OFFSET 0x2007c +#define MIB_TXMAXBYTE_E_LENGTH 4 +#define MIB_TXMAXBYTE_E_OFFSET 0x100 +#define MIB_TXMAXBYTE_NR_E 6 + +#define MIB_TXOVERSIZE "TxOverSize" +#define MIB_TXOVERSIZE_ID 64 +#define MIB_TXOVERSIZE_OFFSET 0x20080 +#define MIB_TXOVERSIZE_E_LENGTH 4 +#define MIB_TXOVERSIZE_E_OFFSET 0x100 +#define MIB_TXOVERSIZE_NR_E 6 + +#define MIB_TXBYTE_LO "TxByteLo" +#define MIB_TXBYTE_LO_ID 65 +#define MIB_TXBYTE_LO_OFFSET 0x20084 +#define MIB_TXBYTE_LO_E_LENGTH 4 +#define MIB_TXBYTE_LO_E_OFFSET 0x100 +#define MIB_TXBYTE_LO_NR_E 6 + +#define MIB_TXBYTE_HI "TxByteHi" +#define MIB_TXBYTE_HI_ID 66 +#define MIB_TXBYTE_HI_OFFSET 0x20088 +#define MIB_TXBYTE_HI_E_LENGTH 4 +#define MIB_TXBYTE_HI_E_OFFSET 0x100 +#define MIB_TXBYTE_HI_NR_E 6 + +#define MIB_TXCOLLISION "TxCollision" +#define MIB_TXCOLLISION_ID 67 +#define MIB_TXCOLLISION_OFFSET 0x2008c +#define MIB_TXCOLLISION_E_LENGTH 4 +#define MIB_TXCOLLISION_E_OFFSET 0x100 +#define MIB_TXCOLLISION_NR_E 6 + +#define MIB_TXABORTCOL "TxAbortCol" +#define MIB_TXABORTCOL_ID 68 +#define MIB_TXABORTCOL_OFFSET 0x20090 +#define MIB_TXABORTCOL_E_LENGTH 4 +#define MIB_TXABORTCOL_E_OFFSET 0x100 +#define MIB_TXABORTCOL_NR_E 6 + +#define MIB_TXMULTICOL "TxMultiCol" +#define MIB_TXMULTICOL_ID 69 +#define MIB_TXMULTICOL_OFFSET 0x20094 +#define MIB_TXMULTICOL_E_LENGTH 4 +#define MIB_TXMULTICOL_E_OFFSET 0x100 +#define MIB_TXMULTICOL_NR_E 6 + +#define MIB_TXSINGALCOL "TxSingalCol" +#define MIB_TXSINGALCOL_ID 70 +#define MIB_TXSINGALCOL_OFFSET 0x20098 +#define MIB_TXSINGALCOL_E_LENGTH 4 +#define MIB_TXSINGALCOL_E_OFFSET 0x100 +#define MIB_TXSINGALCOL_NR_E 6 + +#define MIB_TXEXCDEFER "TxExcDefer" +#define MIB_TXEXCDEFER_ID 71 +#define MIB_TXEXCDEFER_OFFSET 0x2009c +#define MIB_TXEXCDEFER_E_LENGTH 4 +#define MIB_TXEXCDEFER_E_OFFSET 0x100 +#define MIB_TXEXCDEFER_NR_E 6 + +#define MIB_TXDEFER "TxDefer" +#define MIB_TXDEFER_ID 72 +#define MIB_TXDEFER_OFFSET 0x200a0 +#define MIB_TXDEFER_E_LENGTH 4 +#define MIB_TXDEFER_E_OFFSET 0x100 +#define MIB_TXDEFER_NR_E 6 + +#define MIB_TXLATECOL "TxLateCol" +#define MIB_TXLATECOL_ID 73 +#define MIB_TXLATECOL_OFFSET 0x200a4 +#define MIB_TXLATECOL_E_LENGTH 4 +#define MIB_TXLATECOL_E_OFFSET 0x100 +#define MIB_TXLATECOL_NR_E 6 + +#if 0 + /* mib info second mem block */ +#define MIB_RXBROAD_2 "RxBroad_2" +#define MIB_RXBROAD_2_ID 34 +#define MIB_RXBROAD_2_OFFSET (MIB_RXBROAD_OFFSET + 0x400) +#define MIB_RXBROAD_2_E_LENGTH 4 +#define MIB_RXBROAD_2_E_OFFSET 0xa8 +#define MIB_RXBROAD_2_NR_E 6 + +#define MIB_RXPAUSE_2 "RxPause_2" +#define MIB_RXPAUSE_2_ID 35 +#define MIB_RXPAUSE_2_OFFSET (MIB_RXPAUSE_OFFSET + 0x400) +#define MIB_RXPAUSE_2_E_LENGTH 4 +#define MIB_RXPAUSE_2_E_OFFSET 0xa8 +#define MIB_RXPAUSE_2_NR_E 6 + +#define MIB_RXMULTI_2 "RxMulti_2" +#define MIB_RXMULTI_2_ID 36 +#define MIB_RXMULTI_2_OFFSET (MIB_RXMULTI_OFFSET + 0x400) +#define MIB_RXMULTI_2_E_LENGTH 4 +#define MIB_RXMULTI_2_E_OFFSET 0xa8 +#define MIB_RXMULTI_2_NR_E 6 + +#define MIB_RXFCSERR_2 "RxFcsErr_2" +#define MIB_RXFCSERR_2_ID 37 +#define MIB_RXFCSERR_2_OFFSET (MIB_RXFCSERR_OFFSET + 0x400) +#define MIB_RXFCSERR_2_E_LENGTH 4 +#define MIB_RXFCSERR_2_E_OFFSET 0xa8 +#define MIB_RXFCSERR_2_NR_E 6 + +#define MIB_RXALLIGNERR_2 "RxAllignErr_2" +#define MIB_RXALLIGNERR_2_ID 38 +#define MIB_RXALLIGNERR_2_OFFSET (MIB_RXALLIGNERR_OFFSET + 0x400) +#define MIB_RXALLIGNERR_2_E_LENGTH 4 +#define MIB_RXALLIGNERR_2_E_OFFSET 0xa8 +#define MIB_RXALLIGNERR_2_NR_E 6 + +#define MIB_RXRUNT_2 "RxRunt_2" +#define MIB_RXRUNT_2_ID 39 +#define MIB_RXRUNT_2_OFFSET (MIB_RXRUNT_OFFSET + 0x400) +#define MIB_RXRUNT_2_E_LENGTH 4 +#define MIB_RXRUNT_2_E_OFFSET 0xa8 +#define MIB_RXRUNT_2_NR_E 6 + +#define MIB_RXFRAGMENT_2 "RxFragment_2" +#define MIB_RXFRAGMENT_2_ID 40 +#define MIB_RXFRAGMENT_2_OFFSET (MIB_RXFRAGMENT_OFFSET + 0x400) +#define MIB_RXFRAGMENT_2_E_LENGTH 4 +#define MIB_RXFRAGMENT_2_E_OFFSET 0xa8 +#define MIB_RXFRAGMENT_2_NR_E 6 + +#define MIB_RX64BYTE_2 "Rx64Byte_2" +#define MIB_RX64BYTE_2_ID 41 +#define MIB_RX64BYTE_2_OFFSET (MIB_RX64BYTE_OFFSET + 0x400) +#define MIB_RX64BYTE_2_E_LENGTH 4 +#define MIB_RX64BYTE_2_E_OFFSET 0xa8 +#define MIB_RX64BYTE_2_NR_E 6 + +#define MIB_RX128BYTE_2 "Rx128Byte_2" +#define MIB_RX128BYTE_2_ID 42 +#define MIB_RX128BYTE_2_OFFSET (MIB_RX128BYTE_OFFSET + 0x400) +#define MIB_RX128BYTE_2_E_LENGTH 4 +#define MIB_RX128BYTE_2_E_OFFSET 0xa8 +#define MIB_RX128BYTE_2_NR_E 6 + +#define MIB_RX256BYTE_2 "Rx256Byte_2" +#define MIB_RX256BYTE_2_ID 43 +#define MIB_RX256BYTE_2_OFFSET (MIB_RX256BYTE_OFFSET + 0x400) +#define MIB_RX256BYTE_2_E_LENGTH 4 +#define MIB_RX256BYTE_2_E_OFFSET 0xa8 +#define MIB_RX256BYTE_2_NR_E 6 + +#define MIB_RX512BYTE_2 "Rx512Byte_2" +#define MIB_RX512BYTE_2_ID 44 +#define MIB_RX512BYTE_2_OFFSET (MIB_RX512BYTE_OFFSET + 0x400) +#define MIB_RX512BYTE_2_E_LENGTH 4 +#define MIB_RX512BYTE_2_E_OFFSET 0xa8 +#define MIB_RX512BYTE_2_NR_E 6 + +#define MIB_RX1024BYTE_2 "Rx1024Byte_2" +#define MIB_RX1024BYTE_2_ID 45 +#define MIB_RX1024BYTE_2_OFFSET (MIB_RX1024BYTE_OFFSET + 0x400) +#define MIB_RX1024BYTE_2_E_LENGTH 4 +#define MIB_RX1024BYTE_2_E_OFFSET 0xa8 +#define MIB_RX1024BYTE_2_NR_E 6 + +#define MIB_RX1518BYTE_2 "Rx1518Byte_2" +#define MIB_RX1518BYTE_2_ID 45 +#define MIB_RX1518BYTE_2_OFFSET (MIB_RX1518BYTE_OFFSET + 0x400) +#define MIB_RX1518BYTE_2_E_LENGTH 4 +#define MIB_RX1518BYTE_2_E_OFFSET 0xa8 +#define MIB_RX1518BYTE_2_NR_E 6 + +#define MIB_RXMAXBYTE_2 "RxMaxByte_2" +#define MIB_RXMAXBYTE_2_ID 46 +#define MIB_RXMAXBYTE_2_OFFSET (MIB_RXMAXBYTE_OFFSET + 0x400) +#define MIB_RXMAXBYTE_2_E_LENGTH 4 +#define MIB_RXMAXBYTE_2_E_OFFSET 0xa8 +#define MIB_RXMAXBYTE_2_NR_E 6 + +#define MIB_RXTOOLONG_2 "RxTooLong_2" +#define MIB_RXTOOLONG_2_ID 47 +#define MIB_RXTOOLONG_2_OFFSET (MIB_RXTOOLONG_OFFSET + 0x400) +#define MIB_RXTOOLONG_2_E_LENGTH 4 +#define MIB_RXTOOLONG_2_E_OFFSET 0xa8 +#define MIB_RXTOOLONG_2_NR_E 6 + +#define MIB_RXGOODBYTE_LO_2 "RxGoodByteLo_2" +#define MIB_RXGOODBYTE_LO_2_ID 48 +#define MIB_RXGOODBYTE_LO_2_OFFSET (MIB_RXGOODBYTE_LO_OFFSET + 0x400) +#define MIB_RXGOODBYTE_LO_2_E_LENGTH 4 +#define MIB_RXGOODBYTE_LO_2_E_OFFSET 0xa8 +#define MIB_RXGOODBYTE_LO_2_NR_E 6 + +#define MIB_RXGOODBYTE_HI_2 "RxGoodByteHi_2" +#define MIB_RXGOODBYTE_HI_2_ID 49 +#define MIB_RXGOODBYTE_HI_2_OFFSET (MIB_RXGOODBYTE_HI_OFFSET + 0x400) +#define MIB_RXGOODBYTE_HI_2_E_LENGTH 4 +#define MIB_RXGOODBYTE_HI_2_E_OFFSET 0xa8 +#define MIB_RXGOODBYTE_HI_2_NR_E 6 + +#define MIB_RXBADBYTE_LO_2 "RxBadByteLo_2" +#define MIB_RXBADBYTE_LO_2_ID 50 +#define MIB_RXBADBYTE_LO_2_OFFSET (MIB_RXBADBYTE_LO_OFFSET + 0x400) +#define MIB_RXBADBYTE_LO_2_E_LENGTH 4 +#define MIB_RXBADBYTE_LO_2_E_OFFSET 0xa8 +#define MIB_RXBADBYTE_LO_2_NR_E 6 + +#define MIB_RXBADBYTE_HI_2 "RxBadByteHi_2" +#define MIB_RXBADBYTE_HI_2_ID 51 +#define MIB_RXBADBYTE_HI_2_OFFSET (MIB_RXBADBYTE_HI_OFFSET + 0x400) +#define MIB_RXBADBYTE_HI_2_E_LENGTH 4 +#define MIB_RXBADBYTE_HI_2_E_OFFSET 0xa8 +#define MIB_RXBADBYTE_HI_2_NR_E 6 + +#define MIB_RXOVERFLOW_2 "RxOverFlow_2" +#define MIB_RXOVERFLOW_2_ID 52 +#define MIB_RXOVERFLOW_2_OFFSET (MIB_RXOVERFLOW_OFFSET + 0x400) +#define MIB_RXOVERFLOW_2_E_LENGTH 4 +#define MIB_RXOVERFLOW_2_E_OFFSET 0xa8 +#define MIB_RXOVERFLOW_2_NR_E 6 + +#define MIB_FILTERED_2 "Filtered_2" +#define MIB_FILTERED_2_ID 53 +#define MIB_FILTERED_2_OFFSET (MIB_FILTERED_OFFSET + 0x400) +#define MIB_FILTERED_2_E_LENGTH 4 +#define MIB_FILTERED_2_E_OFFSET 0xa8 +#define MIB_FILTERED_2_NR_E 6 + +#define MIB_TXBROAD_2 "TxBroad_2" +#define MIB_TXBROAD_2_ID 54 +#define MIB_TXBROAD_2_OFFSET (MIB_TXBROAD_OFFSET + 0x400) +#define MIB_TXBROAD_2_E_LENGTH 4 +#define MIB_TXBROAD_2_E_OFFSET 0xa8 +#define MIB_TXBROAD_2_NR_E 6 + +#define MIB_TXPAUSE_2 "TxPause_2" +#define MIB_TXPAUSE_2_ID 55 +#define MIB_TXPAUSE_2_OFFSET (MIB_TXPAUSE_OFFSET + 0x400) +#define MIB_TXPAUSE_2_E_LENGTH 4 +#define MIB_TXPAUSE_2_E_OFFSET 0xa8 +#define MIB_TXPAUSE_2_NR_E 6 + +#define MIB_TXMULTI_2 "TxMulti_2" +#define MIB_TXMULTI_2_ID 56 +#define MIB_TXMULTI_2_OFFSET (MIB_TXMULTI_OFFSET + 0x400) +#define MIB_TXMULTI_2_E_LENGTH 4 +#define MIB_TXMULTI_2_E_OFFSET 0xa8 +#define MIB_TXMULTI_2_NR_E 6 + +#define MIB_TXUNDERRUN_2 "TxUnderRun_2" +#define MIB_TXUNDERRUN_2_ID 57 +#define MIB_TXUNDERRUN_2_OFFSET (MIB_TXUNDERRUN_OFFSET + 0x400) +#define MIB_TXUNDERRUN_2_E_LENGTH 4 +#define MIB_TXUNDERRUN_2_E_OFFSET 0xa8 +#define MIB_TXUNDERRUN_2_NR_E 6 + +#define MIB_TX64BYTE_2 "Tx64Byte_2" +#define MIB_TX64BYTE_2_ID 58 +#define MIB_TX64BYTE_2_OFFSET (MIB_TX64BYTE_OFFSET + 0x400) +#define MIB_TX64BYTE_2_E_LENGTH 4 +#define MIB_TX64BYTE_2_E_OFFSET 0xa8 +#define MIB_TX64BYTE_2_NR_E 6 + +#define MIB_TX128BYTE_2 "Tx128Byte_2" +#define MIB_TX128BYTE_2_ID 59 +#define MIB_TX128BYTE_2_OFFSET (MIB_TX128BYTE_OFFSET + 0x400) +#define MIB_TX128BYTE_2_E_LENGTH 4 +#define MIB_TX128BYTE_2_E_OFFSET 0xa8 +#define MIB_TX128BYTE_2_NR_E 6 + +#define MIB_TX256BYTE_2 "Tx256Byte_2" +#define MIB_TX256BYTE_2_ID 60 +#define MIB_TX256BYTE_2_OFFSET (MIB_TX256BYTE_OFFSET + 0x400) +#define MIB_TX256BYTE_2_E_LENGTH 4 +#define MIB_TX256BYTE_2_E_OFFSET 0xa8 +#define MIB_TX256BYTE_2_NR_E 6 + +#define MIB_TX512BYTE_2 "Tx512Byte_2" +#define MIB_TX512BYTE_2_ID 61 +#define MIB_TX512BYTE_2_OFFSET (MIB_TX512BYTE_OFFSET + 0x400) +#define MIB_TX512BYTE_2_E_LENGTH 4 +#define MIB_TX512BYTE_2_E_OFFSET 0xa8 +#define MIB_TX512BYTE_2_NR_E 6 + +#define MIB_TX1024BYTE_2 "Tx1024Byte_2" +#define MIB_TX1024BYTE_2_ID 62 +#define MIB_TX1024BYTE_2_OFFSET (MIB_TX1024BYTE_OFFSET + 0x400) +#define MIB_TX1024BYTE_2_E_LENGTH 4 +#define MIB_TX1024BYTE_2_E_OFFSET 0xa8 +#define MIB_TX1024BYTE_2_NR_E 6 + +#define MIB_TX1518BYTE_2 "Tx1518Byte_2" +#define MIB_TX1518BYTE_2_ID 62 +#define MIB_TX1518BYTE_2_OFFSET (MIB_TX1518BYTE_OFFSET + 0x400) +#define MIB_TX1518BYTE_2_E_LENGTH 4 +#define MIB_TX1518BYTE_2_E_OFFSET 0xa8 +#define MIB_TX1518BYTE_2_NR_E 6 + +#define MIB_TXMAXBYTE_2 "TxMaxByte_2" +#define MIB_TXMAXBYTE_2_ID 63 +#define MIB_TXMAXBYTE_2_OFFSET (MIB_TXMAXBYTE_OFFSET + 0x400) +#define MIB_TXMAXBYTE_2_E_LENGTH 4 +#define MIB_TXMAXBYTE_2_E_OFFSET 0xa8 +#define MIB_TXMAXBYTE_2_NR_E 6 + +#define MIB_TXOVERSIZE_2 "TxOverSize_2" +#define MIB_TXOVERSIZE_2_ID 64 +#define MIB_TXOVERSIZE_2_OFFSET (MIB_TXOVERSIZE_OFFSET + 0x400) +#define MIB_TXOVERSIZE_2_E_LENGTH 4 +#define MIB_TXOVERSIZE_2_E_OFFSET 0xa8 +#define MIB_TXOVERSIZE_2_NR_E 6 + +#define MIB_TXBYTE_LO_2 "TxByteLo_2" +#define MIB_TXBYTE_LO_2_ID 65 +#define MIB_TXBYTE_LO_2_OFFSET (MIB_TXBYTE_LO_OFFSET + 0x400) +#define MIB_TXBYTE_LO_2_E_LENGTH 4 +#define MIB_TXBYTE_LO_2_E_OFFSET 0xa8 +#define MIB_TXBYTE_LO_2_NR_E 6 + +#define MIB_TXBYTE_HI_2 "TxByteHi_2" +#define MIB_TXBYTE_HI_2_ID 66 +#define MIB_TXBYTE_HI_2_OFFSET (MIB_TXBYTE_HI_OFFSET + 0x400) +#define MIB_TXBYTE_HI_2_E_LENGTH 4 +#define MIB_TXBYTE_HI_2_E_OFFSET 0xa8 +#define MIB_TXBYTE_HI_2_NR_E 6 + +#define MIB_TXCOLLISION_2 "TxCollision_2" +#define MIB_TXCOLLISION_2_ID 67 +#define MIB_TXCOLLISION_2_OFFSET (MIB_TXCOLLISION_OFFSET + 0x400) +#define MIB_TXCOLLISION_2_E_LENGTH 4 +#define MIB_TXCOLLISION_2_E_OFFSET 0xa8 +#define MIB_TXCOLLISION_2_NR_E 6 + +#define MIB_TXABORTCOL_2 "TxAbortCol_2" +#define MIB_TXABORTCOL_2_ID 68 +#define MIB_TXABORTCOL_2_OFFSET (MIB_TXABORTCOL_OFFSET + 0x400) +#define MIB_TXABORTCOL_2_E_LENGTH 4 +#define MIB_TXABORTCOL_2_E_OFFSET 0xa8 +#define MIB_TXABORTCOL_2_NR_E 6 + +#define MIB_TXMULTICOL_2 "TxMultiCol_2" +#define MIB_TXMULTICOL_2_ID 69 +#define MIB_TXMULTICOL_2_OFFSET (MIB_TXMULTICOL_OFFSET + 0x400) +#define MIB_TXMULTICOL_2_E_LENGTH 4 +#define MIB_TXMULTICOL_2_E_OFFSET 0xa8 +#define MIB_TXMULTICOL_2_NR_E 6 + +#define MIB_TXSINGALCOL_2 "TxSingalCol_2" +#define MIB_TXSINGALCOL_2_ID 70 +#define MIB_TXSINGALCOL_2_OFFSET (MIB_TXSINGALCOL_OFFSET + 0x400) +#define MIB_TXSINGALCOL_2_E_LENGTH 4 +#define MIB_TXSINGALCOL_2_E_OFFSET 0xa8 +#define MIB_TXSINGALCOL_2_NR_E 6 + +#define MIB_TXEXCDEFER_2 "TxExcDefer_2" +#define MIB_TXEXCDEFER_2_ID 71 +#define MIB_TXEXCDEFER_2_OFFSET (MIB_TXEXCDEFER_OFFSET + 0x400) +#define MIB_TXEXCDEFER_2_E_LENGTH 4 +#define MIB_TXEXCDEFER_2_E_OFFSET 0xa8 +#define MIB_TXEXCDEFER_2_NR_E 6 + +#define MIB_TXDEFER_2 "TxDefer_2" +#define MIB_TXDEFER_2_ID 72 +#define MIB_TXDEFER_2_OFFSET (MIB_TXDEFER_OFFSET + 0x400) +#define MIB_TXDEFER_2_E_LENGTH 4 +#define MIB_TXDEFER_2_E_OFFSET 0xa8 +#define MIB_TXDEFER_2_NR_E 6 + +#define MIB_TXLATECOL_2 "TxLateCol_2" +#define MIB_TXLATECOL_2_ID 73 +#define MIB_TXLATECOL_2_OFFSET (MIB_TXLATECOL_OFFSET + 0x400) +#define MIB_TXLATECOL_2_E_LENGTH 4 +#define MIB_TXLATECOL_2_E_OFFSET 0xa8 +#define MIB_TXLATECOL_2_NR_E 6 +#endif + + + + +#define ACL_RSLT0 "aclact0" +#define ACL_RSLT0_ID 13 +#define ACL_RSLT0_OFFSET 0x58000 +#define ACL_RSLT0_E_LENGTH 4 +#define ACL_RSLT0_E_OFFSET 0x20 +#define ACL_RSLT0_NR_E 32 + +#define MATCH_CNT "aclact_cnt" +#define ACL_RSLT0_MATCH_CNT_BOFFSET 0 +#define ACL_RSLT0_MATCH_CNT_BLEN 32 +#define ACL_RSLT0_MATCH_CNT_FLAG HSL_RW + + + + +#define ACL_RSLT1 "aclact1" +#define ACL_RSLT1_ID 13 +#define ACL_RSLT1_OFFSET 0x58004 +#define ACL_RSLT1_E_LENGTH 4 +#define ACL_RSLT1_E_OFFSET 0x20 +#define ACL_RSLT1_NR_E 32 + +#define MIRR_EN "aclact1_mirr" +#define ACL_RSLT1_MIRR_EN_BOFFSET 31 +#define ACL_RSLT1_MIRR_EN_BLEN 1 +#define ACL_RSLT1_MIRR_EN_FLAG HSL_RW + +#define STAG_CHG_EN "aclact1_rdcpu" +#define ACL_RSLT1_STAG_CHG_EN_BOFFSET 30 +#define ACL_RSLT1_STAG_CHG_EN_BLEN 1 +#define ACL_RSLT1_STAG_CHG_EN_FLAG HSL_RW + +#define VID_MEM_EN "aclact1_rdcpu" +#define ACL_RSLT1_VID_MEM_EN_BOFFSET 29 +#define ACL_RSLT1_VID_MEM_EN_BLEN 1 +#define ACL_RSLT1_VID_MEM_EN_FLAG HSL_RW + +#define DES_PORT_EN "aclact1_rdcpu" +#define ACL_RSLT1_DES_PORT_EN_BOFFSET 28 +#define ACL_RSLT1_DES_PORT_EN_BLEN 1 +#define ACL_RSLT1_DES_PORT_EN_FLAG HSL_RW + +#define PORT_MEM "aclact1_rdcpu" +#define ACL_RSLT1_PORT_MEM_BOFFSET 20 +#define ACL_RSLT1_PORT_MEM_BLEN 7 +#define ACL_RSLT1_PORT_MEM_FLAG HSL_RW + +#define REMARK_PRI_QU "aclact1_rdcpu" +#define ACL_RSLT1_REMARK_PRI_QU_BOFFSET 19 +#define ACL_RSLT1_REMARK_PRI_QU_BLEN 1 +#define ACL_RSLT1_REMARK_PRI_QU_FLAG HSL_RW + +#define DOT1P "aclact1_rdcpu" +#define ACL_RSLT1_DOT1P_BOFFSET 16 +#define ACL_RSLT1_DOT1P_BLEN 3 +#define ACL_RSLT1_DOT1P_FLAG HSL_RW + +#define PRI_QU "aclact1_rdcpu" +#define ACL_RSLT1_PRI_QU_BOFFSET 14 +#define ACL_RSLT1_PRI_QU_BLEN 2 +#define ACL_RSLT1_PRI_QU_FLAG HSL_RW + +#define REMARK_DOT1P "aclact1_rdcpu" +#define ACL_RSLT1_REMARK_DOT1P_BOFFSET 13 +#define ACL_RSLT1_REMARK_DOT1P_BLEN 1 +#define ACL_RSLT1_REMARK_DOT1P_FLAG HSL_RW + +#define CHG_VID_EN "aclact1_rdcpu" +#define ACL_RSLT1_CHG_VID_EN_BOFFSET 12 +#define ACL_RSLT1_CHG_VID_EN_BLEN 1 +#define ACL_RSLT1_CHG_VID_EN_FLAG HSL_RW + +#define VID "aclact1_rdcpu" +#define ACL_RSLT1_VID_BOFFSET 0 +#define ACL_RSLT1_VID_BLEN 12 +#define ACL_RSLT1_VID_FLAG HSL_RW + + + + +#define ACL_RSLT2 "aclact2" +#define ACL_RSLT2_ID 13 +#define ACL_RSLT2_OFFSET 0x58008 +#define ACL_RSLT2_E_LENGTH 4 +#define ACL_RSLT2_E_OFFSET 0x20 +#define ACL_RSLT2_NR_E 32 + +#define RDTCPU "aclact2_rdtpu" +#define ACL_RSLT2_RDTCPU_BOFFSET 1 +#define ACL_RSLT2_RDTCPU_BLEN 1 +#define ACL_RSLT2_RDTCPU_FLAG HSL_RW + +#define CPYCPU "aclact2_cpcpu" +#define ACL_RSLT2_CPYCPU_BOFFSET 0 +#define ACL_RSLT2_CPYCPU_BLEN 1 +#define ACL_RSLT2_CPYCPU_FLAG HSL_RW + + + + + +#define RUL_SLCT0 "rulslct0" +#define RUL_SLCT0_ID 13 +#define RUL_SLCT0_OFFSET 0x58800 +#define RUL_SLCT0_E_LENGTH 4 +#define RUL_SLCT0_E_OFFSET 0x20 +#define RUL_SLCT0_NR_E 32 + +#define ADDR3_EN "rulslct_addr3en" +#define RUL_SLCT0_ADDR3_EN_BOFFSET 3 +#define RUL_SLCT0_ADDR3_EN_BLEN 1 +#define RUL_SLCT0_ADDR3_EN_FLAG HSL_RW + +#define ADDR2_EN "rulslct_addr2en" +#define RUL_SLCT0_ADDR2_EN_BOFFSET 2 +#define RUL_SLCT0_ADDR2_EN_BLEN 1 +#define RUL_SLCT0_ADDR2_EN_FLAG HSL_RW + +#define ADDR1_EN "rulslct_addr1en" +#define RUL_SLCT0_ADDR1_EN_BOFFSET 1 +#define RUL_SLCT0_ADDR1_EN_BLEN 1 +#define RUL_SLCT0_ADDR1_EN_FLAG HSL_RW + +#define ADDR0_EN "rulslct_addr0en" +#define RUL_SLCT0_ADDR0_EN_BOFFSET 0 +#define RUL_SLCT0_ADDR0_EN_BLEN 1 +#define RUL_SLCT0_ADDR0_EN_FLAG HSL_RW + + + + +#define RUL_SLCT1 "rulslct1" +#define RUL_SLCT1_ID 13 +#define RUL_SLCT1_OFFSET 0x58804 +#define RUL_SLCT1_E_LENGTH 4 +#define RUL_SLCT1_E_OFFSET 0x20 +#define RUL_SLCT1_NR_E 32 + +#define ADDR0 "rulslct1_addr0" +#define RUL_SLCT1_ADDR0_BOFFSET 0 +#define RUL_SLCT1_ADDR0_BLEN 5 +#define RUL_SLCT1_ADDR0_FLAG HSL_RW + + + + +#define RUL_SLCT2 "rulslct2" +#define RUL_SLCT2_ID 13 +#define RUL_SLCT2_OFFSET 0x58808 +#define RUL_SLCT2_E_LENGTH 4 +#define RUL_SLCT2_E_OFFSET 0x20 +#define RUL_SLCT2_NR_E 32 + +#define ADDR1 "rulslct2_addr1" +#define RUL_SLCT2_ADDR1_BOFFSET 0 +#define RUL_SLCT2_ADDR1_BLEN 5 +#define RUL_SLCT2_ADDR1_FLAG HSL_RW + + + + +#define RUL_SLCT3 "rulslct3" +#define RUL_SLCT3_ID 13 +#define RUL_SLCT3_OFFSET 0x5880c +#define RUL_SLCT3_E_LENGTH 4 +#define RUL_SLCT3_E_OFFSET 0x20 +#define RUL_SLCT3_NR_E 32 + +#define ADDR2 "rulslct3_addr2" +#define RUL_SLCT3_ADDR2_BOFFSET 0 +#define RUL_SLCT3_ADDR2_BLEN 5 +#define RUL_SLCT3_ADDR2_FLAG HSL_RW + + + + +#define RUL_SLCT4 "rulslct4" +#define RUL_SLCT4_ID 13 +#define RUL_SLCT4_OFFSET 0x58810 +#define RUL_SLCT4_E_LENGTH 4 +#define RUL_SLCT4_E_OFFSET 0x20 +#define RUL_SLCT4_NR_E 32 + +#define ADDR3 "rulslct4_addr3" +#define RUL_SLCT4_ADDR3_BOFFSET 0 +#define RUL_SLCT4_ADDR3_BLEN 5 +#define RUL_SLCT4_ADDR3_FLAG HSL_RW + + + + +#define RUL_SLCT5 "rulslct5" +#define RUL_SLCT5_ID 13 +#define RUL_SLCT5_OFFSET 0x58814 +#define RUL_SLCT5_E_LENGTH 4 +#define RUL_SLCT5_E_OFFSET 0x20 +#define RUL_SLCT5_NR_E 32 + +#define SRC_PT "rulslct5_srcpt" +#define RUL_SLCT5_SRC_PT_BOFFSET 0 +#define RUL_SLCT5_SRC_PT_BLEN 7 +#define RUL_SLCT5_SRC_PT_FLAG HSL_RW + + + + +#define RUL_SLCT6 "rulslct6" +#define RUL_SLCT6_ID 13 +#define RUL_SLCT6_OFFSET 0x58818 +#define RUL_SLCT6_E_LENGTH 4 +#define RUL_SLCT6_E_OFFSET 0x20 +#define RUL_SLCT6_NR_E 32 + +#define RULE_LEN "rulslct6_rulelen" +#define RUL_SLCT6_RULE_LEN_BOFFSET 0 +#define RUL_SLCT6_RULE_LEN_BLEN 8 +#define RUL_SLCT6_RULE_LEN_FLAG HSL_RW + + + + +#define RUL_SLCT7 "rulslct7" +#define RUL_SLCT7_ID 13 +#define RUL_SLCT7_OFFSET 0x5881c +#define RUL_SLCT7_E_LENGTH 4 +#define RUL_SLCT7_E_OFFSET 0x20 +#define RUL_SLCT7_NR_E 32 + +#define RULE_TYP "rulslct7_ruletyp" +#define RUL_SLCT7_RULE_TYP_BOFFSET 0 +#define RUL_SLCT7_RULE_TYP_BLEN 3 +#define RUL_SLCT7_RULE_TYP_FLAG HSL_RW + + + + +#define MAC_RUL_V0 "macrv0" +#define MAC_RUL_V0_ID 13 +#define MAC_RUL_V0_OFFSET 0x58400 +#define MAC_RUL_V0_E_LENGTH 4 +#define MAC_RUL_V0_E_OFFSET 0x20 +#define MAC_RUL_V0_NR_E 32 + +#define DAV_BYTE2 "macrv0_dav2" +#define MAC_RUL_V0_DAV_BYTE2_BOFFSET 24 +#define MAC_RUL_V0_DAV_BYTE2_BLEN 8 +#define MAC_RUL_V0_DAV_BYTE2_FLAG HSL_RW + +#define DAV_BYTE3 "macrv0_dav3" +#define MAC_RUL_V0_DAV_BYTE3_BOFFSET 16 +#define MAC_RUL_V0_DAV_BYTE3_BLEN 8 +#define MAC_RUL_V0_DAV_BYTE3_FLAG HSL_RW + +#define DAV_BYTE4 "macrv0_dav4" +#define MAC_RUL_V0_DAV_BYTE4_BOFFSET 8 +#define MAC_RUL_V0_DAV_BYTE4_BLEN 8 +#define MAC_RUL_V0_DAV_BYTE4_FLAG HSL_RW + +#define DAV_BYTE5 "macrv0_dav5" +#define MAC_RUL_V0_DAV_BYTE5_BOFFSET 0 +#define MAC_RUL_V0_DAV_BYTE5_BLEN 8 +#define MAC_RUL_V0_DAV_BYTE5_FLAG HSL_RW + + + + +#define MAC_RUL_V1 "macrv1" +#define MAC_RUL_V1_ID 13 +#define MAC_RUL_V1_OFFSET 0x58404 +#define MAC_RUL_V1_E_LENGTH 4 +#define MAC_RUL_V1_E_OFFSET 0x20 +#define MAC_RUL_V1_NR_E 32 + +#define SAV_BYTE4 "macrv1_sav4" +#define MAC_RUL_V1_SAV_BYTE4_BOFFSET 24 +#define MAC_RUL_V1_SAV_BYTE4_BLEN 8 +#define MAC_RUL_V1_SAV_BYTE4_FLAG HSL_RW + +#define SAV_BYTE5 "macrv1_sav5" +#define MAC_RUL_V1_SAV_BYTE5_BOFFSET 16 +#define MAC_RUL_V1_SAV_BYTE5_BLEN 8 +#define MAC_RUL_V1_SAV_BYTE5_FLAG HSL_RW + +#define DAV_BYTE0 "macrv1_dav0" +#define MAC_RUL_V1_DAV_BYTE0_BOFFSET 8 +#define MAC_RUL_V1_DAV_BYTE0_BLEN 8 +#define MAC_RUL_V1_DAV_BYTE0_FLAG HSL_RW + +#define DAV_BYTE1 "macrv1_dav1" +#define MAC_RUL_V1_DAV_BYTE1_BOFFSET 0 +#define MAC_RUL_V1_DAV_BYTE1_BLEN 8 +#define MAC_RUL_V1_DAV_BYTE1_FLAG HSL_RW + + + + +#define MAC_RUL_V2 "macrv2" +#define MAC_RUL_V2_ID 13 +#define MAC_RUL_V2_OFFSET 0x58408 +#define MAC_RUL_V2_E_LENGTH 4 +#define MAC_RUL_V2_E_OFFSET 0x20 +#define MAC_RUL_V2_NR_E 32 + +#define SAV_BYTE0 "macrv2_sav0" +#define MAC_RUL_V2_SAV_BYTE0_BOFFSET 24 +#define MAC_RUL_V2_SAV_BYTE0_BLEN 8 +#define MAC_RUL_V2_SAV_BYTE0_FLAG HSL_RW + +#define SAV_BYTE1 "macrv2_sav1" +#define MAC_RUL_V2_SAV_BYTE1_BOFFSET 16 +#define MAC_RUL_V2_SAV_BYTE1_BLEN 8 +#define MAC_RUL_V2_SAV_BYTE1_FLAG HSL_RW + +#define SAV_BYTE2 "macrv2_sav2" +#define MAC_RUL_V2_SAV_BYTE2_BOFFSET 8 +#define MAC_RUL_V2_SAV_BYTE2_BLEN 8 +#define MAC_RUL_V2_SAV_BYTE2_FLAG HSL_RW + +#define SAV_BYTE3 "macrv2_sav3" +#define MAC_RUL_V2_SAV_BYTE3_BOFFSET 0 +#define MAC_RUL_V2_SAV_BYTE3_BLEN 8 +#define MAC_RUL_V2_SAV_BYTE3_FLAG HSL_RW + + + + +#define MAC_RUL_V3 "macrv3" +#define MAC_RUL_V3_ID 13 +#define MAC_RUL_V3_OFFSET 0x5840c +#define MAC_RUL_V3_E_LENGTH 4 +#define MAC_RUL_V3_E_OFFSET 0x20 +#define MAC_RUL_V3_NR_E 32 + +#define ETHTYPV "macrv3_ethtypv" +#define MAC_RUL_V3_ETHTYPV_BOFFSET 16 +#define MAC_RUL_V3_ETHTYPV_BLEN 16 +#define MAC_RUL_V3_ETHTYPV_FLAG HSL_RW + +#define VLANPRIV "macrv3_vlanpriv" +#define MAC_RUL_V3_VLANPRIV_BOFFSET 13 +#define MAC_RUL_V3_VLANPRIV_BLEN 3 +#define MAC_RUL_V3_VLANPRIV_FLAG HSL_RW + +#define VLANCFIV "macrv3_vlancfiv" +#define MAC_RUL_V3_VLANCFIV_BOFFSET 12 +#define MAC_RUL_V3_VLANCFIV_BLEN 1 +#define MAC_RUL_V3_VLANCFIV_FLAG HSL_RW + +#define VLANIDV "macrv3_vlanidv" +#define MAC_RUL_V3_VLANIDV_BOFFSET 0 +#define MAC_RUL_V3_VLANIDV_BLEN 12 +#define MAC_RUL_V3_VLANIDV_FLAG HSL_RW + + + + +#define MAC_RUL_V4 "macrv4" +#define MAC_RUL_V4_ID 13 +#define MAC_RUL_V4_OFFSET 0x58410 +#define MAC_RUL_V4_E_LENGTH 4 +#define MAC_RUL_V4_E_OFFSET 0x20 +#define MAC_RUL_V4_NR_E 32 + +#define TAGGEDM "macrv4_vlanid" +#define MAC_RUL_V4_TAGGEDM_BOFFSET 7 +#define MAC_RUL_V4_TAGGEDM_BLEN 1 +#define MAC_RUL_V4_TAGGEDM_FLAG HSL_RW + +#define TAGGEDV "macrv4_vlanid" +#define MAC_RUL_V4_TAGGEDV_BOFFSET 6 +#define MAC_RUL_V4_TAGGEDV_BLEN 1 +#define MAC_RUL_V4_TAGGEDV_FLAG HSL_RW + +#define VIDMSK "macrv4_vidmsk" +#define MAC_RUL_V4_VIDMSK_BOFFSET 0 +#define MAC_RUL_V4_VIDMSK_BLEN 1 +#define MAC_RUL_V4_VIDMSK_FLAG HSL_RW + + + + + +#define MAC_RUL_M0 "macrv0" +#define MAC_RUL_M0_ID 13 +#define MAC_RUL_M0_OFFSET 0x58c00 +#define MAC_RUL_M0_E_LENGTH 4 +#define MAC_RUL_M0_E_OFFSET 0x20 +#define MAC_RUL_M0_NR_E 32 + +#define DAM_BYTE2 "macrv0_dam2" +#define MAC_RUL_M0_DAM_BYTE2_BOFFSET 24 +#define MAC_RUL_M0_DAM_BYTE2_BLEN 8 +#define MAC_RUL_M0_DAM_BYTE2_FLAG HSL_RW + +#define DAM_BYTE3 "macrv0_dam3" +#define MAC_RUL_M0_DAM_BYTE3_BOFFSET 16 +#define MAC_RUL_M0_DAM_BYTE3_BLEN 8 +#define MAC_RUL_M0_DAM_BYTE3_FLAG HSL_RW + +#define DAM_BYTE4 "macrv0_dam4" +#define MAC_RUL_M0_DAM_BYTE4_BOFFSET 8 +#define MAC_RUL_M0_DAM_BYTE4_BLEN 8 +#define MAC_RUL_M0_DAM_BYTE4_FLAG HSL_RW + +#define DAM_BYTE5 "macrv0_dam5" +#define MAC_RUL_M0_DAM_BYTE5_BOFFSET 0 +#define MAC_RUL_M0_DAM_BYTE5_BLEN 8 +#define MAC_RUL_M0_DAM_BYTE5_FLAG HSL_RW + + + + +#define MAC_RUL_M1 "macrm1" +#define MAC_RUL_M1_ID 13 +#define MAC_RUL_M1_OFFSET 0x58c04 +#define MAC_RUL_M1_E_LENGTH 4 +#define MAC_RUL_M1_E_OFFSET 0x20 +#define MAC_RUL_M1_NR_E 32 + +#define SAM_BYTE4 "macrm1_sam4" +#define MAC_RUL_M1_SAM_BYTE4_BOFFSET 24 +#define MAC_RUL_M1_SAM_BYTE4_BLEN 8 +#define MAC_RUL_M1_SAM_BYTE4_FLAG HSL_RW + +#define SAM_BYTE5 "macrm1_sam5" +#define MAC_RUL_M1_SAM_BYTE5_BOFFSET 16 +#define MAC_RUL_M1_SAM_BYTE5_BLEN 8 +#define MAC_RUL_M1_SAM_BYTE5_FLAG HSL_RW + +#define DAM_BYTE0 "macrm1_dam0" +#define MAC_RUL_M1_DAM_BYTE0_BOFFSET 8 +#define MAC_RUL_M1_DAM_BYTE0_BLEN 8 +#define MAC_RUL_M1_DAM_BYTE0_FLAG HSL_RW + +#define DAM_BYTE1 "macrm1_dam1" +#define MAC_RUL_M1_DAM_BYTE1_BOFFSET 0 +#define MAC_RUL_M1_DAM_BYTE1_BLEN 8 +#define MAC_RUL_M1_DAM_BYTE1_FLAG HSL_RW + + + + +#define MAC_RUL_M2 "macrm2" +#define MAC_RUL_M2_ID 13 +#define MAC_RUL_M2_OFFSET 0x58c08 +#define MAC_RUL_M2_E_LENGTH 4 +#define MAC_RUL_M2_E_OFFSET 0x20 +#define MAC_RUL_M2_NR_E 32 + +#define SAM_BYTE0 "macrm2_sam0" +#define MAC_RUL_M2_SAM_BYTE0_BOFFSET 24 +#define MAC_RUL_M2_SAM_BYTE0_BLEN 8 +#define MAC_RUL_M2_SAM_BYTE0_FLAG HSL_RW + +#define SAM_BYTE1 "macrm2_samv1" +#define MAC_RUL_M2_SAM_BYTE1_BOFFSET 16 +#define MAC_RUL_M2_SAM_BYTE1_BLEN 8 +#define MAC_RUL_M2_SAM_BYTE1_FLAG HSL_RW + +#define SAM_BYTE2 "macrm2_sam2" +#define MAC_RUL_M2_SAM_BYTE2_BOFFSET 8 +#define MAC_RUL_M2_SAM_BYTE2_BLEN 8 +#define MAC_RUL_M2_SAM_BYTE2_FLAG HSL_RW + +#define SAM_BYTE3 "macrm2_sam3" +#define MAC_RUL_M2_SAM_BYTE3_BOFFSET 0 +#define MAC_RUL_M2_SAM_BYTE3_BLEN 8 +#define MAC_RUL_M2_SAM_BYTE3_FLAG HSL_RW + + + + +#define MAC_RUL_M3 "macrv3" +#define MAC_RUL_M3_ID 13 +#define MAC_RUL_M3_OFFSET 0x58c0c +#define MAC_RUL_M3_E_LENGTH 4 +#define MAC_RUL_M3_E_OFFSET 0x20 +#define MAC_RUL_M3_NR_E 32 + +#define ETHTYPM "macrm3_ethtypm" +#define MAC_RUL_M3_ETHTYPM_BOFFSET 16 +#define MAC_RUL_M3_ETHTYPM_BLEN 16 +#define MAC_RUL_M3_ETHTYPM_FLAG HSL_RW + +#define VLANPRIM "macrm3_vlanprim" +#define MAC_RUL_M3_VLANPRIM_BOFFSET 13 +#define MAC_RUL_M3_VLANPRIM_BLEN 3 +#define MAC_RUL_M3_VLANPRIM_FLAG HSL_RW + +#define VLANCFIM "macrm3_vlancfim" +#define MAC_RUL_M3_VLANCFIM_BOFFSET 12 +#define MAC_RUL_M3_VLANCFIM_BLEN 1 +#define MAC_RUL_M3_VLANCFIM_FLAG HSL_RW + +#define VLANIDM "macrm3_vlanidm" +#define MAC_RUL_M3_VLANIDM_BOFFSET 0 +#define MAC_RUL_M3_VLANIDM_BLEN 12 +#define MAC_RUL_M3_VLANIDM_FLAG HSL_RW + + + + +#define IP4_RUL_V0 "ip4v0" +#define IP4_RUL_V0_ID 13 +#define IP4_RUL_V0_OFFSET 0x58400 +#define IP4_RUL_V0_E_LENGTH 4 +#define IP4_RUL_V0_E_OFFSET 0x20 +#define IP4_RUL_V0_NR_E 32 + +#define DIPV "ip4v0_dipv" +#define IP4_RUL_V0_DIPV_BOFFSET 0 +#define IP4_RUL_V0_DIPV_BLEN 32 +#define IP4_RUL_V0_DIPV_FLAG HSL_RW + + + + +#define IP4_RUL_V1 "ip4v1" +#define IP4_RUL_V1_ID 13 +#define IP4_RUL_V1_OFFSET 0x58404 +#define IP4_RUL_V1_E_LENGTH 4 +#define IP4_RUL_V1_E_OFFSET 0x20 +#define IP4_RUL_V1_NR_E 32 + +#define SIPV "ip4v1_sipv" +#define IP4_RUL_V1_SIPV_BOFFSET 0 +#define IP4_RUL_V1_SIPV_BLEN 32 +#define IP4_RUL_V1_SIPV_FLAG HSL_RW + + + + +#define IP4_RUL_V2 "ip4v2" +#define IP4_RUL_V2_ID 13 +#define IP4_RUL_V2_OFFSET 0x58408 +#define IP4_RUL_V2_E_LENGTH 4 +#define IP4_RUL_V2_E_OFFSET 0x20 +#define IP4_RUL_V2_NR_E 32 + +#define IP4PROTV "ip4v2_protv" +#define IP4_RUL_V2_IP4PROTV_BOFFSET 0 +#define IP4_RUL_V2_IP4PROTV_BLEN 8 +#define IP4_RUL_V2_IP4PROTV_FLAG HSL_RW + +#define IP4DSCPV "ip4v2_dscpv" +#define IP4_RUL_V2_IP4DSCPV_BOFFSET 8 +#define IP4_RUL_V2_IP4DSCPV_BLEN 8 +#define IP4_RUL_V2_IP4DSCPV_FLAG HSL_RW + +#define IP4DPORTV "ip4v2_dportv" +#define IP4_RUL_V2_IP4DPORTV_BOFFSET 16 +#define IP4_RUL_V2_IP4DPORTV_BLEN 16 +#define IP4_RUL_V2_IP4DPORTV_FLAG HSL_RW + + + + +#define IP4_RUL_V3 "ip4v3" +#define IP4_RUL_V3_ID 13 +#define IP4_RUL_V3_OFFSET 0x5840c +#define IP4_RUL_V3_E_LENGTH 4 +#define IP4_RUL_V3_E_OFFSET 0x20 +#define IP4_RUL_V3_NR_E 32 + +#define IP4SPORTV "ip4v3_sportv" +#define IP4_RUL_V3_IP4SPORTV_BOFFSET 0 +#define IP4_RUL_V3_IP4SPORTV_BLEN 16 +#define IP4_RUL_V3_IP4SPORTV_FLAG HSL_RW + + +#define IP4_RUL_V4 "ip4v2" +#define IP4_RUL_V4_ID 13 +#define IP4_RUL_V4_OFFSET 0x58410 +#define IP4_RUL_V4_E_LENGTH 4 +#define IP4_RUL_V4_E_OFFSET 0x20 +#define IP4_RUL_V4_NR_E 32 + +#define IP4_INPT "ip4rv4_inpt" +#define IP4_RUL_V4_IP4_INPT_BOFFSET 0 +#define IP4_RUL_V4_IP4_INPT_BLEN 6 +#define IP4_RUL_V4_IP4_INPT_FLAG HSL_RW + + + + + + +#define IP4_RUL_M0 "ip4m0" +#define IP4_RUL_M0_ID 13 +#define IP4_RUL_M0_OFFSET 0x58c00 +#define IP4_RUL_M0_E_LENGTH 4 +#define IP4_RUL_M0_E_OFFSET 0x20 +#define IP4_RUL_M0_NR_E 32 + +#define DIPM "ip4m0_dipm" +#define IP4_RUL_M0_DIPM_BOFFSET 0 +#define IP4_RUL_M0_DIPM_BLEN 32 +#define IP4_RUL_M0_DIPM_FLAG HSL_RW + + + + +#define IP4_RUL_M1 "ip4m1" +#define IP4_RUL_M1_ID 13 +#define IP4_RUL_M1_OFFSET 0x58c04 +#define IP4_RUL_M1_E_LENGTH 4 +#define IP4_RUL_M1_E_OFFSET 0x20 +#define IP4_RUL_M1_NR_E 32 + +#define SIPM "ip4m1_sipm" +#define IP4_RUL_M1_SIPM_BOFFSET 0 +#define IP4_RUL_M1_SIPM_BLEN 32 +#define IP4_RUL_M1_SIPM_FLAG HSL_RW + + + + +#define IP4_RUL_M2 "ip4m2" +#define IP4_RUL_M2_ID 13 +#define IP4_RUL_M2_OFFSET 0x58c08 +#define IP4_RUL_M2_E_LENGTH 4 +#define IP4_RUL_M2_E_OFFSET 0x20 +#define IP4_RUL_M2_NR_E 32 + +#define IP4PROTM "ip4m2_protm" +#define IP4_RUL_M2_IP4PROTM_BOFFSET 0 +#define IP4_RUL_M2_IP4PROTM_BLEN 8 +#define IP4_RUL_M2_IP4PROTM_FLAG HSL_RW + +#define IP4DSCPM "ip4m2_dscpm" +#define IP4_RUL_M2_IP4DSCPM_BOFFSET 8 +#define IP4_RUL_M2_IP4DSCPM_BLEN 8 +#define IP4_RUL_M2_IP4DSCPM_FLAG HSL_RW + +#define IP4DPORTM "ip4m2_dportm" +#define IP4_RUL_M2_IP4DPORTM_BOFFSET 16 +#define IP4_RUL_M2_IP4DPORTM_BLEN 16 +#define IP4_RUL_M2_IP4DPORTM_FLAG HSL_RW + + + + +#define IP4_RUL_M3 "ip4m3" +#define IP4_RUL_M3_ID 13 +#define IP4_RUL_M3_OFFSET 0x58c0c +#define IP4_RUL_M3_E_LENGTH 4 +#define IP4_RUL_M3_E_OFFSET 0x20 +#define IP4_RUL_M3_NR_E 32 + +#define IP4SPORTM "ip4m3_sportm" +#define IP4_RUL_M3_IP4SPORTM_BOFFSET 0 +#define IP4_RUL_M3_IP4SPORTM_BLEN 16 +#define IP4_RUL_M3_IP4SPORTM_FLAG HSL_RW + +#define IP4SPORTM_EN "ip4m3_sportmen" +#define IP4_RUL_M3_IP4SPORTM_EN_BOFFSET 16 +#define IP4_RUL_M3_IP4SPORTM_EN_BLEN 1 +#define IP4_RUL_M3_IP4SPORTM_EN_FLAG HSL_RW + +#define IP4DPORTM_EN "ip4m3_dportmen" +#define IP4_RUL_M3_IP4DPORTM_EN_BOFFSET 17 +#define IP4_RUL_M3_IP4DPORTM_EN_BLEN 1 +#define IP4_RUL_M3_IP4DPORTM_EN_FLAG HSL_RW + + + + +#define IP6_RUL1_V0 "ip6r1v0" +#define IP6_RUL1_V0_ID 13 +#define IP6_RUL1_V0_OFFSET 0x58400 +#define IP6_RUL1_V0_E_LENGTH 4 +#define IP6_RUL1_V0_E_OFFSET 0x20 +#define IP6_RUL1_V0_NR_E 32 + +#define IP6_DIPV0 "ip6r1v0_dipv0" +#define IP6_RUL1_V0_IP6_DIPV0_BOFFSET 0 +#define IP6_RUL1_V0_IP6_DIPV0_BLEN 32 +#define IP6_RUL1_V0_IP6_DIPV0_FLAG HSL_RW + + + + +#define IP6_RUL1_V1 "ip6r1v1" +#define IP6_RUL1_V1_ID 13 +#define IP6_RUL1_V1_OFFSET 0x58404 +#define IP6_RUL1_V1_E_LENGTH 4 +#define IP6_RUL1_V1_E_OFFSET 0x20 +#define IP6_RUL1_V1_NR_E 32 + +#define IP6_DIPV1 "ip6r1v1_dipv1" +#define IP6_RUL1_V1_IP6_DIPV1_BOFFSET 0 +#define IP6_RUL1_V1_IP6_DIPv1_BLEN 32 +#define IP6_RUL1_V1_IP6_DIPV1_FLAG HSL_RW + + + +#define IP6_RUL1_V2 "ip6r1v2" +#define IP6_RUL1_V2_ID 13 +#define IP6_RUL1_V2_OFFSET 0x58408 +#define IP6_RUL1_V2_E_LENGTH 4 +#define IP6_RUL1_V2_E_OFFSET 0x20 +#define IP6_RUL1_V2_NR_E 32 + +#define IP6_DIPV2 "ip6r1v2_dipv2" +#define IP6_RUL1_V2_IP6_DIPV2_BOFFSET 0 +#define IP6_RUL1_V2_IP6_DIPv2_BLEN 32 +#define IP6_RUL1_V2_IP6_DIPV2_FLAG HSL_RW + + + + +#define IP6_RUL1_V3 "ip6r1v3" +#define IP6_RUL1_V3_ID 13 +#define IP6_RUL1_V3_OFFSET 0x5840c +#define IP6_RUL1_V3_E_LENGTH 4 +#define IP6_RUL1_V3_E_OFFSET 0x20 +#define IP6_RUL1_V3_NR_E 32 + +#define IP6_DIPV3 "ip6r1v3_dipv3" +#define IP6_RUL1_V3_IP6_DIPV3_BOFFSET 0 +#define IP6_RUL1_V3_IP6_DIPv3_BLEN 32 +#define IP6_RUL1_V3_IP6_DIPV3_FLAG HSL_RW + + + + +#define IP6_RUL1_V4 "ip6r1v4" +#define IP6_RUL1_V4_ID 13 +#define IP6_RUL1_V4_OFFSET 0x58410 +#define IP6_RUL1_V4_E_LENGTH 4 +#define IP6_RUL1_V4_E_OFFSET 0x20 +#define IP6_RUL1_V4_NR_E 32 + +#define IP6_RUL1_INPT "ip6r1v4_inpt" +#define IP6_RUL1_V4_IP6_RUL1_INPT_BOFFSET 0 +#define IP6_RUL1_V4_IP6_RUL1_INPT_BLEN 6 +#define IP6_RUL1_V4_IP6_RUL1_INPT_FLAG HSL_RW + + + + + +#define IP6_RUL1_M0 "ip6r1m0" +#define IP6_RUL1_M0_ID 13 +#define IP6_RUL1_M0_OFFSET 0x58c00 +#define IP6_RUL1_M0_E_LENGTH 4 +#define IP6_RUL1_M0_E_OFFSET 0x20 +#define IP6_RUL1_M0_NR_E 32 + +#define IP6_DIPM0 "ip6r1m0_dipm0" +#define IP6_RUL1_M0_IP6_DIPM0_BOFFSET 0 +#define IP6_RUL1_M0_IP6_DIPM0_BLEN 32 +#define IP6_RUL1_M0_IP6_DIPM0_FLAG HSL_RW + + + + +#define IP6_RUL1_M1 "ip6r1m1" +#define IP6_RUL1_M1_ID 13 +#define IP6_RUL1_M1_OFFSET 0x58c04 +#define IP6_RUL1_M1_E_LENGTH 4 +#define IP6_RUL1_M1_E_OFFSET 0x20 +#define IP6_RUL1_M1_NR_E 32 + +#define IP6_DIPM1 "ip6r1m1_dipm1" +#define IP6_RUL1_M1_IP6_DIPM1_BOFFSET 0 +#define IP6_RUL1_M1_IP6_DIPM1_BLEN 32 +#define IP6_RUL1_M1_IP6_DIPM1_FLAG HSL_RW + + + +#define IP6_RUL1_M2 "ip6r1m2" +#define IP6_RUL1_M2_ID 13 +#define IP6_RUL1_M2_OFFSET 0x58c08 +#define IP6_RUL1_M2_E_LENGTH 4 +#define IP6_RUL1_M2_E_OFFSET 0x20 +#define IP6_RUL1_M2_NR_E 32 + +#define IP6_DIPM2 "ip6r1m2_dipm2" +#define IP6_RUL1_M2_IP6_DIPM2_BOFFSET 0 +#define IP6_RUL1_M2_IP6_DIPM2_BLEN 32 +#define IP6_RUL1_M2_IP6_DIPM2_FLAG HSL_RW + + + + +#define IP6_RUL1_M3 "ip6r1m3" +#define IP6_RUL1_M3_ID 13 +#define IP6_RUL1_M3_OFFSET 0x58c0c +#define IP6_RUL1_M3_E_LENGTH 4 +#define IP6_RUL1_M3_E_OFFSET 0x20 +#define IP6_RUL1_M3_NR_E 32 + +#define IP6_DIPM3 "ip6r1m3_dipm3" +#define IP6_RUL1_M3_IP6_DIPM3_BOFFSET 0 +#define IP6_RUL1_M3_IP6_DIPM3_BLEN 32 +#define IP6_RUL1_M3_IP6_DIPM3_FLAG HSL_RW + + + + + +#define IP6_RUL2_V0 "ip6r2v0" +#define IP6_RUL2_V0_ID 13 +#define IP6_RUL2_V0_OFFSET 0x58400 +#define IP6_RUL2_V0_E_LENGTH 4 +#define IP6_RUL2_V0_E_OFFSET 0x20 +#define IP6_RUL2_V0_NR_E 32 + +#define IP6_SIPV0 "ip6r2v0_sipv0" +#define IP6_RUL2_V0_IP6_SIPV0_BOFFSET 0 +#define IP6_RUL2_V0_IP6_SIPv0_BLEN 32 +#define IP6_RUL2_V0_IP6_SIPV0_FLAG HSL_RW + + + + +#define IP6_RUL2_V1 "ip6r2v1" +#define IP6_RUL2_V1_ID 13 +#define IP6_RUL2_V1_OFFSET 0x58404 +#define IP6_RUL2_V1_E_LENGTH 4 +#define IP6_RUL2_V1_E_OFFSET 0x20 +#define IP6_RUL2_V1_NR_E 32 + +#define IP6_SIPV1 "ip6r2v1_sipv1" +#define IP6_RUL2_V1_IP6_SIPV1_BOFFSET 0 +#define IP6_RUL2_V1_IP6_SIPv1_BLEN 32 +#define IP6_RUL2_V1_IP6_SIPV1_FLAG HSL_RW + + + +#define IP6_RUL2_V2 "ip6r2v2" +#define IP6_RUL2_V2_ID 13 +#define IP6_RUL2_V2_OFFSET 0x58408 +#define IP6_RUL2_V2_E_LENGTH 4 +#define IP6_RUL2_V2_E_OFFSET 0x20 +#define IP6_RUL2_V2_NR_E 32 + +#define IP6_SIPV2 "ip6r2v2_sipv2" +#define IP6_RUL2_V2_IP6_SIPV2_BOFFSET 0 +#define IP6_RUL2_V2_IP6_SIPv2_BLEN 32 +#define IP6_RUL2_V2_IP6_SIPV2_FLAG HSL_RW + + + + +#define IP6_RUL2_V3 "ip6r2v3" +#define IP6_RUL2_V3_ID 13 +#define IP6_RUL2_V3_OFFSET 0x5840c +#define IP6_RUL2_V3_E_LENGTH 4 +#define IP6_RUL2_V3_E_OFFSET 0x20 +#define IP6_RUL2_V3_NR_E 32 + +#define IP6_SIPV3 "ip6r2v3_sipv3" +#define IP6_RUL2_V3_IP6_SIPV3_BOFFSET 0 +#define IP6_RUL2_V3_IP6_SIPv3_BLEN 32 +#define IP6_RUL2_V3_IP6_SIPV3_FLAG HSL_RW + + + + +#define IP6_RUL2_V4 "ip6r2v4" +#define IP6_RUL2_V4_ID 13 +#define IP6_RUL2_V4_OFFSET 0x58410 +#define IP6_RUL2_V4_E_LENGTH 4 +#define IP6_RUL2_V4_E_OFFSET 0x20 +#define IP6_RUL2_V4_NR_E 32 + +#define IP6_RUL2_INPT "ip6r2v4_inptm" +#define IP6_RUL2_V4_IP6_RUL2_INPT_BOFFSET 0 +#define IP6_RUL2_V4_IP6_RUL2_INPT_BLEN 6 +#define IP6_RUL2_V4_IP6_RUL2_INPT_FLAG HSL_RW + + + + +#define IP6_RUL2_M0 "ip6r2m0" +#define IP6_RUL2_M0_ID 13 +#define IP6_RUL2_M0_OFFSET 0x58c00 +#define IP6_RUL2_M0_E_LENGTH 4 +#define IP6_RUL2_M0_E_OFFSET 0x20 +#define IP6_RUL2_M0_NR_E 32 + +#define IP6_SIPM0 "ip6r2m0_sipm0" +#define IP6_RUL2_M0_IP6_SIPM0_BOFFSET 0 +#define IP6_RUL2_M0_IP6_SIPM0_BLEN 32 +#define IP6_RUL2_M0_IP6_SIPM0_FLAG HSL_RW + + + + +#define IP6_RUL2_M1 "ip6r2m1" +#define IP6_RUL2_M1_ID 13 +#define IP6_RUL2_M1_OFFSET 0x58c04 +#define IP6_RUL2_M1_E_LENGTH 4 +#define IP6_RUL2_M1_E_OFFSET 0x20 +#define IP6_RUL2_M1_NR_E 32 + +#define IP6_SIPM1 "ip6r2m1_sipm1" +#define IP6_RUL2_M1_IP6_DIPM1_BOFFSET 0 +#define IP6_RUL2_M1_IP6_DIPM1_BLEN 32 +#define IP6_RUL2_M1_IP6_DIPM1_FLAG HSL_RW + + + +#define IP6_RUL2_M2 "ip6r2m2" +#define IP6_RUL2_M2_ID 13 +#define IP6_RUL2_M2_OFFSET 0x58c08 +#define IP6_RUL2_M2_E_LENGTH 4 +#define IP6_RUL2_M2_E_OFFSET 0x20 +#define IP6_RUL2_M2_NR_E 32 + +#define IP6_SIPM2 "ip6r2m2_sipm2" +#define IP6_RUL2_M2_IP6_DIPM2_BOFFSET 0 +#define IP6_RUL2_M2_IP6_DIPM2_BLEN 32 +#define IP6_RUL2_M2_IP6_DIPM2_FLAG HSL_RW + + + + +#define IP6_RUL2_M3 "ip6r2m3" +#define IP6_RUL2_M3_ID 13 +#define IP6_RUL2_M3_OFFSET 0x58c0c +#define IP6_RUL2_M3_E_LENGTH 4 +#define IP6_RUL2_M3_E_OFFSET 0x20 +#define IP6_RUL2_M3_NR_E 32 + +#define IP6_SIPM3 "ip6r2m3_sipm3" +#define IP6_RUL2_M3_IP6_SIPM3_BOFFSET 0 +#define IP6_RUL2_M3_IP6_SIPM3_BLEN 32 +#define IP6_RUL2_M3_IP6_SIPM3_FLAG HSL_RW + + + + + +#define IP6_RUL3_V0 "ip6r3v0" +#define IP6_RUL3_V0_ID 13 +#define IP6_RUL3_V0_OFFSET 0x58400 +#define IP6_RUL3_V0_E_LENGTH 4 +#define IP6_RUL3_V0_E_OFFSET 0x20 +#define IP6_RUL3_V0_NR_E 32 + +#define IP6PROTV "ip6r3v0_protv" +#define IP6_RUL3_V0_IP6PROTV_BOFFSET 0 +#define IP6_RUL3_V0_IP6PROTV_BLEN 8 +#define IP6_RUL3_V0_IP6PROTV_FLAG HSL_RW + +#define IP6DSCPV "ip6r3v0_dscpv" +#define IP6_RUL3_V0_IP6DSCPV_BOFFSET 8 +#define IP6_RUL3_V0_IP6DSCPV_BLEN 8 +#define IP6_RUL3_V0_IP6DSCPV_FLAG HSL_RW + + + + +#define IP6_RUL3_V1 "ip6r3v1" +#define IP6_RUL3_V1_ID 13 +#define IP6_RUL3_V1_OFFSET 0x58404 +#define IP6_RUL3_V1_E_LENGTH 4 +#define IP6_RUL3_V1_E_OFFSET 0x20 +#define IP6_RUL3_V1_NR_E 32 + +#define IP6LABEL1V "ip6r3v1_label1v" +#define IP6_RUL3_V1_IP6LABEL1V_BOFFSET 16 +#define IP6_RUL3_V1_IP6LABEL1V_BLEN 16 +#define IP6_RUL3_V1_IP6LABEL1V_FLAG HSL_RW + + + + +#define IP6_RUL3_V2 "ip6r3v2" +#define IP6_RUL3_V2_ID 13 +#define IP6_RUL3_V2_OFFSET 0x58408 +#define IP6_RUL3_V2_E_LENGTH 4 +#define IP6_RUL3_V2_E_OFFSET 0x20 +#define IP6_RUL3_V2_NR_E 32 + +#define IP6LABEL2V "ip6r3v2_label2v" +#define IP6_RUL3_V2_IP6LABEL2V_BOFFSET 0 +#define IP6_RUL3_V2_IP6LABEL2V_BLEN 4 +#define IP6_RUL3_V2_IP6LABEL2V_FLAG HSL_RW + +#define IP6DPORTV "ip6r3v2_dportv" +#define IP6_RUL3_V2_IP6DPORTV_BOFFSET 16 +#define IP6_RUL3_V2_IP6DPORTV_BLEN 16 +#define IP6_RUL3_V2_IP6DPORTV_FLAG HSL_RW + + + + +#define IP6_RUL3_V3 "ip6r3v3" +#define IP6_RUL3_V3_ID 13 +#define IP6_RUL3_V3_OFFSET 0x5840c +#define IP6_RUL3_V3_E_LENGTH 4 +#define IP6_RUL3_V3_E_OFFSET 0x20 +#define IP6_RUL3_V3_NR_E 32 + +#define IP6SPORTV "ip6r3v3_sportv" +#define IP6_RUL3_V3_IP6SPORTV_BOFFSET 0 +#define IP6_RUL3_V3_IP6SPORTV_BLEN 16 +#define IP6_RUL3_V3_IP6SPORTV_FLAG HSL_RW + + + +#define IP6_RUL3_M0 "ip6r3m0" +#define IP6_RUL3_M0_ID 13 +#define IP6_RUL3_M0_OFFSET 0x58c00 +#define IP6_RUL3_M0_E_LENGTH 4 +#define IP6_RUL3_M0_E_OFFSET 0x20 +#define IP6_RUL3_M0_NR_E 32 + +#define IP6PROTM "ip6r3m0_protm" +#define IP6_RUL3_M0_IP6PROTM_BOFFSET 0 +#define IP6_RUL3_M0_IP6PROTM_BLEN 8 +#define IP6_RUL3_M0_IP6PROTM_FLAG HSL_RW + +#define IP6DSCPM "ip6r3m0_dscpm" +#define IP6_RUL3_M0_IP6DSCPM_BOFFSET 8 +#define IP6_RUL3_M0_IP6DSCPM_BLEN 8 +#define IP6_RUL3_M0_IP6DSCPM_FLAG HSL_RW + + + + +#define IP6_RUL3_M1 "ip6r3m1" +#define IP6_RUL3_M1_ID 13 +#define IP6_RUL3_M1_OFFSET 0x58c04 +#define IP6_RUL3_M1_E_LENGTH 4 +#define IP6_RUL3_M1_E_OFFSET 0x20 +#define IP6_RUL3_M1_NR_E 32 + +#define IP6LABEL1M "ip6r3m1_label1m" +#define IP6_RUL3_M1_IP6LABEL1M_BOFFSET 16 +#define IP6_RUL3_M1_IP6LABEL1M_BLEN 16 +#define IP6_RUL3_M1_IP6LABEL1M_FLAG HSL_RW + + + + +#define IP6_RUL3_M2 "ip6r3m2" +#define IP6_RUL3_M2_ID 13 +#define IP6_RUL3_M2_OFFSET 0x58c08 +#define IP6_RUL3_M2_E_LENGTH 4 +#define IP6_RUL3_M2_E_OFFSET 0x20 +#define IP6_RUL3_M2_NR_E 32 + +#define IP6LABEL2M "ip6r3m2_label2m" +#define IP6_RUL3_M2_IP6LABEL2M_BOFFSET 0 +#define IP6_RUL3_M2_IP6LABEL2M_BLEN 4 +#define IP6_RUL3_M2_IP6LABEL21M_FLAG HSL_RW + +#define IP6DPORTM "ip6r3m2_dportm" +#define IP6_RUL3_M2_IP6DPORTM_BOFFSET 16 +#define IP6_RUL3_M2_IP6DPORTM_BLEN 16 +#define IP6_RUL3_M2_IP6DPORTM_FLAG HSL_RW + + + + +#define IP6_RUL3_M3 "ip6r3m3" +#define IP6_RUL3_M3_ID 13 +#define IP6_RUL3_M3_OFFSET 0x58c0c +#define IP6_RUL3_M3_E_LENGTH 4 +#define IP6_RUL3_M3_E_OFFSET 0x20 +#define IP6_RUL3_M3_NR_E 32 + +#define IP6SPORTM "ip6r3m3_sportm" +#define IP6_RUL3_M3_IP6SPORTM_BOFFSET 0 +#define IP6_RUL3_M3_IP6SPORTM_BLEN 16 +#define IP6_RUL3_M3_IP6SPORTM_FLAG HSL_RW + +#define IP6DPORTM_EN "ip6r3m3_dportmen" +#define IP6_RUL3_M3_IP6DPORTM_EN_BOFFSET 17 +#define IP6_RUL3_M3_IP6DPORTM_EN_BLEN 1 +#define IP6_RUL3_M3_IP6DPORTM_EN_FLAG HSL_RW + +#define IP6SPORTM_EN "ip6r3m3_sportmen" +#define IP6_RUL3_M3_IP6SPORTM_EN_BOFFSET 16 +#define IP6_RUL3_M3_IP6SPORTM_EN_BLEN 1 +#define IP6_RUL3_M3_IP6SPORTM_EN_FLAG HSL_RW + + + + +#define UDF_RUL_V4 "udfv4" +#define UDF_RUL_V4_ID 13 +#define UDF_RUL_V4_OFFSET 0x58410 +#define UDF_RUL_V4_E_LENGTH 4 +#define UDF_RUL_V4_E_OFFSET 0x20 +#define UDF_RUL_V4_NR_E 32 + + +#define LAYER_TYP "udfv4_typ" +#define UDF_RUL_V4_LAYER_TYP_BOFFSET 7 +#define UDF_RUL_V4_LAYER_TYP_BLEN 1 +#define UDF_RUL_V4_LAYER_TYP_FLAG HSL_RW + +#define LAYER_OFFSET "udfv4_offset" +#define UDF_RUL_V4_LAYER_OFFSET_BOFFSET 0 +#define UDF_RUL_V4_LAYER_OFFSET_BLEN 7 +#define UDF_RUL_V4_LAYER_OFFSET_FLAG HSL_RW + + + + +#define PPPOE_SESSION "pppoes" +#define PPPOE_SESSION_ID 13 +#define PPPOE_SESSION_OFFSET 0x59100 +#define PPPOE_SESSION_E_LENGTH 4 +#define PPPOE_SESSION_E_OFFSET 0x4 +#define PPPOE_SESSION_NR_E 16 + +#define ENTRY_VALID "pppoes_v" +#define PPPOE_SESSION_ENTRY_VALID_BOFFSET 19 +#define PPPOE_SESSION_ENTRY_VALID_BLEN 1 +#define PPPOE_SESSION_ENTRY_VALID_FLAG HSL_RW + +#define STRIP_EN "pppoes_s" +#define PPPOE_SESSION_STRIP_EN_BOFFSET 16 +#define PPPOE_SESSION_STRIP_EN_BLEN 1 +#define PPPOE_SESSION_STRIP_EN_FLAG HSL_RW + +#define SEESION_ID "pppoes_id" +#define PPPOE_SESSION_SEESION_ID_BOFFSET 0 +#define PPPOE_SESSION_SEESION_ID_BLEN 16 +#define PPPOE_SESSION_SEESION_ID_FLAG HSL_RW + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _SHIVA_REG_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_reg_access.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_reg_access.h new file mode 100755 index 000000000..5cb9df621 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_reg_access.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2012,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 _SHIVA_REG_ACCESS_H_ +#define _SHIVA_REG_ACCESS_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "sw.h" + + sw_error_t + shiva_phy_get(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t * value); + + sw_error_t + shiva_phy_set(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t value); + + sw_error_t + shiva_reg_get(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t value[], + a_uint32_t value_len); + + sw_error_t + shiva_reg_set(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t value[], + a_uint32_t value_len); + + sw_error_t + shiva_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 + shiva_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 + shiva_reg_access_init(a_uint32_t dev_id, hsl_access_mode mode); + + sw_error_t + shiva_access_mode_set(a_uint32_t dev_id, hsl_access_mode mode); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _SHIVA_REG_ACCESS_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_stp.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_stp.h new file mode 100755 index 000000000..6d2195560 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_stp.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 shiva_stp SHIVA_STP + * @{ + */ +#ifndef _SHIVA_STP_H_ +#define _SHIVA_STP_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_stp.h" + + sw_error_t shiva_stp_init(a_uint32_t dev_id); + +#ifdef IN_STP +#define SHIVA_STP_INIT(rv, dev_id) \ + { \ + rv = shiva_stp_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define SHIVA_STP_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + shiva_stp_port_state_set(a_uint32_t dev_id, a_uint32_t st_id, + fal_port_t port_id, fal_stp_state_t state); + + + HSL_LOCAL sw_error_t + shiva_stp_port_state_get(a_uint32_t dev_id, a_uint32_t st_id, + fal_port_t port_id, fal_stp_state_t * state); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _SHIVA_STP_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_vlan.h b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_vlan.h new file mode 100755 index 000000000..5d50dfc78 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/hsl/shiva/shiva_vlan.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 shiva_vlan SHIVA_VLAN + * @{ + */ +#ifndef _SHIVA_VLAN_H_ +#define _SHIVA_VLAN_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "fal/fal_vlan.h" + + sw_error_t + shiva_vlan_init(a_uint32_t dev_id); + +#ifdef IN_VLAN +#define SHIVA_VLAN_INIT(rv, dev_id) \ + { \ + rv = shiva_vlan_init(dev_id); \ + SW_RTN_ON_ERROR(rv); \ + } +#else +#define SHIVA_VLAN_INIT(rv, dev_id) +#endif + +#ifdef HSL_STANDALONG + + + HSL_LOCAL sw_error_t + shiva_vlan_entry_append(a_uint32_t dev_id, const fal_vlan_t * vlan_entry); + + + HSL_LOCAL sw_error_t + shiva_vlan_create(a_uint32_t dev_id, a_uint32_t vlan_id); + + + HSL_LOCAL sw_error_t + shiva_vlan_next(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan); + + + HSL_LOCAL sw_error_t + shiva_vlan_find(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan); + + + HSL_LOCAL sw_error_t + shiva_vlan_member_update(a_uint32_t dev_id, a_uint32_t vlan_id, + fal_pbmp_t member, fal_pbmp_t u_member); + + + HSL_LOCAL sw_error_t + shiva_vlan_delete(a_uint32_t dev_id, a_uint32_t vlan_id); + + + HSL_LOCAL sw_error_t + shiva_vlan_flush(a_uint32_t dev_id); + + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _SHIVA_VLAN_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/init/ssdk_clk.h b/feeds/ipq807x/qca-ssdk/src/include/init/ssdk_clk.h new file mode 100755 index 000000000..ccc8ca605 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/init/ssdk_clk.h @@ -0,0 +1,307 @@ +/* + * 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 _SSDK_CLK_H_ +#define _SSDK_CLK_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define PPE_RESET_ID "ppe_rst" +#define UNIPHY0_SOFT_RESET_ID "uniphy0_soft_rst" +#define UNIPHY0_XPCS_RESET_ID "uniphy0_xpcs_rst" +#define UNIPHY1_SOFT_RESET_ID "uniphy1_soft_rst" +#define UNIPHY1_XPCS_RESET_ID "uniphy1_xpcs_rst" +#define UNIPHY2_SOFT_RESET_ID "uniphy2_soft_rst" +#define UNIPHY2_XPCS_RESET_ID "uniphy2_xpcs_rst" +#define UNIPHY0_PORT1_DISABLE_ID "uniphy0_port1_dis" +#define UNIPHY0_PORT2_DISABLE_ID "uniphy0_port2_dis" +#define UNIPHY0_PORT3_DISABLE_ID "uniphy0_port3_dis" +#define UNIPHY0_PORT4_DISABLE_ID "uniphy0_port4_dis" +#define UNIPHY0_PORT5_DISABLE_ID "uniphy0_port5_dis" +#define UNIPHY0_PORT_4_5_RESET_ID "uniphy0_port_4_5_rst" +#define UNIPHY0_PORT_4_RESET_ID "uniphy0_port_4_rst" + +#define SSDK_PORT1_RESET_ID "nss_port1_rst" +#define SSDK_PORT2_RESET_ID "nss_port2_rst" +#define SSDK_PORT3_RESET_ID "nss_port3_rst" +#define SSDK_PORT4_RESET_ID "nss_port4_rst" +#define SSDK_PORT5_RESET_ID "nss_port5_rst" +#define SSDK_PORT6_RESET_ID "nss_port6_rst" + +enum ssdk_rst_action { + SSDK_RESET_DEASSERT = 0, + SSDK_RESET_ASSERT = 1 +}; + +enum unphy_rst_type { + UNIPHY0_SOFT_RESET_E = 0, + UNIPHY0_XPCS_RESET_E, + UNIPHY1_SOFT_RESET_E, + UNIPHY1_XPCS_RESET_E, + UNIPHY2_SOFT_RESET_E, + UNIPHY2_XPCS_RESET_E, + UNIPHY0_PORT1_DISABLE_E, + UNIPHY0_PORT2_DISABLE_E, + UNIPHY0_PORT3_DISABLE_E, + UNIPHY0_PORT4_DISABLE_E, + UNIPHY0_PORT5_DISABLE_E, + UNIPHY0_PORT_4_5_RESET_E, + UNIPHY0_PORT_4_RESET_E, + UNIPHY_RST_MAX +}; + +#define CMN_AHB_CLK "cmn_ahb_clk" +#define CMN_SYS_CLK "cmn_sys_clk" +#define UNIPHY0_AHB_CLK "uniphy0_ahb_clk" +#define UNIPHY0_SYS_CLK "uniphy0_sys_clk" +#define UNIPHY1_AHB_CLK "uniphy1_ahb_clk" +#define UNIPHY1_SYS_CLK "uniphy1_sys_clk" +#define UNIPHY2_AHB_CLK "uniphy2_ahb_clk" +#define UNIPHY2_SYS_CLK "uniphy2_sys_clk" +#define PORT1_MAC_CLK "port1_mac_clk" +#define PORT2_MAC_CLK "port2_mac_clk" +#define PORT3_MAC_CLK "port3_mac_clk" +#define PORT4_MAC_CLK "port4_mac_clk" +#define PORT5_MAC_CLK "port5_mac_clk" +#define PORT6_MAC_CLK "port6_mac_clk" +#define NSS_PPE_CLK "nss_ppe_clk" +#define NSS_PPE_CFG_CLK "nss_ppe_cfg_clk" +#define NSSNOC_PPE_CLK "nssnoc_ppe_clk" +#define NSSNOC_PPE_CFG_CLK "nssnoc_ppe_cfg_clk" +#define NSS_EDMA_CLK "nss_edma_clk" +#define NSS_EDMA_CFG_CLK "nss_edma_cfg_clk" +#define NSS_PPE_IPE_CLK "nss_ppe_ipe_clk" +#define NSS_PPE_BTQ_CLK "nss_ppe_btq_clk" +#define MDIO_AHB_CLK "gcc_mdio_ahb_clk" +#define NSSNOC_CLK "gcc_nss_noc_clk" +#define NSSNOC_SNOC_CLK "gcc_nssnoc_snoc_clk" +#define MEM_NOC_NSSAXI_CLK "gcc_mem_noc_nss_axi_clk" +#define CRYPTO_PPE_CLK "gcc_nss_crypto_clk" +#define NSS_IMEM_CLK "gcc_nss_imem_clk" +#define NSS_PTP_REF_CLK "gcc_nss_ptp_ref_clk" +#define SNOC_NSSNOC_CLK "gcc_snoc_nssnoc_clk" + +#define UNIPHY_AHB_CLK "uniphy_ahb_clk" +#define UNIPHY_SYS_CLK "uniphy_sys_clk" +#define MP_UNIPHY_SYS_CLK_RATE 24000000 +#define MDIO0_AHB_CLK "gcc_mdio0_ahb_clk" +#define MDIO1_AHB_CLK "gcc_mdio1_ahb_clk" +#define GMAC0_CFG_CLK "gcc_gmac0_cfg_clk" +#define GMAC0_SYS_CLK "gcc_gmac0_sys_clk" +#define GMAC1_CFG_CLK "gcc_gmac1_cfg_clk" +#define GMAC1_SYS_CLK "gcc_gmac1_sys_clk" +#define SNOC_GMAC0_AHB_CLK "gcc_snoc_gmac0_ahb_clk" +#define SNOC_GMAC1_AHB_CLK "gcc_snoc_gmac1_ahb_clk" +#define GMAC0_PTP_CLK "gcc_gmac0_ptp_clk" +#define GMAC1_PTP_CLK "gcc_gmac1_ptp_clk" +#define GMAC_CLK_RATE 240000000 + +#define NSS_PORT1_RX_CLK "nss_port1_rx_clk" +#define NSS_PORT1_TX_CLK "nss_port1_tx_clk" +#define NSS_PORT2_RX_CLK "nss_port2_rx_clk" +#define NSS_PORT2_TX_CLK "nss_port2_tx_clk" +#define NSS_PORT3_RX_CLK "nss_port3_rx_clk" +#define NSS_PORT3_TX_CLK "nss_port3_tx_clk" +#define NSS_PORT4_RX_CLK "nss_port4_rx_clk" +#define NSS_PORT4_TX_CLK "nss_port4_tx_clk" +#define NSS_PORT5_RX_CLK "nss_port5_rx_clk" +#define NSS_PORT5_TX_CLK "nss_port5_tx_clk" +#define NSS_PORT6_RX_CLK "nss_port6_rx_clk" +#define NSS_PORT6_TX_CLK "nss_port6_tx_clk" +#define UNIPHY0_PORT1_RX_CLK "uniphy0_port1_rx_clk" +#define UNIPHY0_PORT1_TX_CLK "uniphy0_port1_tx_clk" +#define UNIPHY0_PORT2_RX_CLK "uniphy0_port2_rx_clk" +#define UNIPHY0_PORT2_TX_CLK "uniphy0_port2_tx_clk" +#define UNIPHY0_PORT3_RX_CLK "uniphy0_port3_rx_clk" +#define UNIPHY0_PORT3_TX_CLK "uniphy0_port3_tx_clk" +#define UNIPHY0_PORT4_RX_CLK "uniphy0_port4_rx_clk" +#define UNIPHY0_PORT4_TX_CLK "uniphy0_port4_tx_clk" +#define UNIPHY0_PORT5_RX_CLK "uniphy0_port5_rx_clk" +#define UNIPHY0_PORT5_TX_CLK "uniphy0_port5_tx_clk" +#define UNIPHY1_PORT5_RX_CLK "uniphy1_port5_rx_clk" +#define UNIPHY1_PORT5_TX_CLK "uniphy1_port5_tx_clk" +#define UNIPHY2_PORT6_RX_CLK "uniphy2_port6_rx_clk" +#define UNIPHY2_PORT6_TX_CLK "uniphy2_port6_tx_clk" +#define PORT5_RX_SRC "nss_port5_rx_clk_src" +#define PORT5_TX_SRC "nss_port5_tx_clk_src" + +enum unphy_clk_type { + NSS_PORT1_RX_CLK_E = 0, + NSS_PORT1_TX_CLK_E, + NSS_PORT2_RX_CLK_E, + NSS_PORT2_TX_CLK_E, + NSS_PORT3_RX_CLK_E, + NSS_PORT3_TX_CLK_E, + NSS_PORT4_RX_CLK_E, + NSS_PORT4_TX_CLK_E, + NSS_PORT5_RX_CLK_E, + NSS_PORT5_TX_CLK_E, + NSS_PORT6_RX_CLK_E, + NSS_PORT6_TX_CLK_E, + UNIPHY0_PORT1_RX_CLK_E, + UNIPHY0_PORT1_TX_CLK_E, + UNIPHY0_PORT2_RX_CLK_E, + UNIPHY0_PORT2_TX_CLK_E, + UNIPHY0_PORT3_RX_CLK_E, + UNIPHY0_PORT3_TX_CLK_E, + UNIPHY0_PORT4_RX_CLK_E, + UNIPHY0_PORT4_TX_CLK_E, + UNIPHY0_PORT5_RX_CLK_E, + UNIPHY0_PORT5_TX_CLK_E, + UNIPHY1_PORT5_RX_CLK_E, + UNIPHY1_PORT5_TX_CLK_E, + UNIPHY2_PORT6_RX_CLK_E, + UNIPHY2_PORT6_TX_CLK_E, + PORT5_RX_SRC_E, + PORT5_TX_SRC_E, + UNIPHYT_CLK_MAX +}; + +enum cmnblk_clk_type { + INTERNAL_48MHZ = 0, + EXTERNAL_25MHZ, + EXTERNAL_31250KHZ, + EXTERNAL_40MHZ, + EXTERNAL_48MHZ, + EXTERNAL_50MHZ, + INTERNAL_96MHZ, +}; + +enum cmnblk_pll_src_type { + CMN_BLK_PLL_SRC_SEL_FROM_REG = 0, + CMN_BLK_PLL_SRC_SEL_FROM_LOGIC = 1, + CMN_BLK_PLL_SRC_SEL_FROM_PCS = 2, +}; + +enum mp_bcr_rst_type { + GEPHY_BCR_RESET_E = 0, + UNIPHY_BCR_RESET_E, + GMAC0_BCR_RESET_E, + GMAC1_BCR_RESET_E, + GEPHY_MISC_RESET_E, + MP_BCR_RST_MAX +}; + +#define GEHPY_BCR_RESET_ID "gephy_bcr_rst" +#define UNIPHY_BCR_RESET_ID "uniphy_bcr_rst" +#define GMAC0_BCR_RESET_ID "gmac0_bcr_rst" +#define GMAC1_BCR_RESET_ID "gmac1_bcr_rst" +#define GEPHY_MISC_RESET_ID "gephy_misc_rst" + +#define CMN_BLK_ADDR 0x0009B780 +#define CMN_BLK_PLL_SRC_ADDR 0x0009B028 +#define CMN_BLK_SIZE 0x100 +#define PLL_CTRL_SRC_MASK 0xfffffcff +#define PLL_REFCLK_DIV_MASK 0xfffffe0f +#define PLL_REFCLK_DIV_2 0x20 +#define FREQUENCY_MASK 0xfffffdf0 +#define INTERNAL_48MHZ_CLOCK 0x7 +#define EXTERNAL_25MHZ_CLOCK 0x203 +#define EXTERNAL_31250KHZ_CLOCK 0x204 +#define EXTERNAL_40MHZ_CLOCK 0x206 +#define EXTERNAL_48MHZ_CLOCK 0x207 +#define EXTERNAL_50MHZ_CLOCK 0x208 +#define UNIPHY_AHB_CLK_RATE 100000000 +#define UNIPHY_SYS_CLK_RATE 19200000 +#define CPPE_UNIPHY_SYS_CLK_RATE 24000000 +#define PPE_CLK_RATE 300000000 +#define MDIO_AHB_RATE 100000000 +#define NSS_NOC_RATE 461500000 +#define NSSNOC_SNOC_RATE 266670000 +#define NSS_IMEM_RATE 400000000 +#define PTP_REF_RARE 150000000 +#define NSS_AXI_RATE 461500000 +#define NSS_PORT5_DFLT_RATE 19200000 + +#define UNIPHY_CLK_RATE_25M 25000000 +#define UNIPHY_CLK_RATE_50M 50000000 +#define UNIPHY_CLK_RATE_125M 125000000 +#define UNIPHY_CLK_RATE_312M 312500000 +#define UNIPHY_DEFAULT_RATE UNIPHY_CLK_RATE_125M + +#define PQSGMII_SPEED_10M_CLK 2500000 +#define PQSGMII_SPEED_100M_CLK 25000000 +#define PQSGMII_SPEED_1000M_CLK 125000000 +#define USXGMII_SPEED_10M_CLK 1250000 +#define USXGMII_SPEED_100M_CLK 12500000 +#define USXGMII_SPEED_1000M_CLK 125000000 +#define USXGMII_SPEED_2500M_CLK 78125000 +#define USXGMII_SPEED_5000M_CLK 156250000 +#define USXGMII_SPEED_10000M_CLK 312500000 +#define SGMII_PLUS_SPEED_2500M_CLK 312500000 +#define SGMII_SPEED_10M_CLK 2500000 +#define SGMII_SPEED_100M_CLK 25000000 +#define SGMII_SPEED_1000M_CLK 125000000 + +#define CPPE_XGMAC_CLK_REG 0x0194900c +#define CPPE_XGMAC_CLK_SIZE 0x10 +#define CPPE_XGMAC_CLK_ENABLE 0x20 + +enum { + UNIPHY_RX = 0, + UNIPHY_TX, +}; + +void ssdk_uniphy_reset( + a_uint32_t dev_id, + enum unphy_rst_type rst_type, + a_uint32_t action); + +void ssdk_port_reset( + a_uint32_t dev_id, + a_uint32_t port_id, + a_uint32_t action); + +#if defined(HPPE) || defined(MP) +void +qca_gcc_mac_port_clock_set(a_uint32_t dev_id, a_uint32_t port_id, + a_bool_t enable); + +void +qca_gcc_uniphy_port_clock_set(a_uint32_t dev_id, a_uint32_t uniphy_index, + a_uint32_t port_id, a_bool_t enable); +void ssdk_gcc_clock_init(void); +void +ssdk_port_speed_clock_set( + a_uint32_t dev_id, + a_uint32_t port_id, + a_uint32_t rate); +void ssdk_port_mac_clock_reset( + a_uint32_t dev_id, + a_uint32_t port_id); +#endif + +#if defined(HPPE) +void ssdk_ppe_reset_init(void); +void ssdk_uniphy_raw_clock_reset(a_uint8_t uniphy_index); +void ssdk_uniphy_raw_clock_set( + a_uint8_t uniphy_index, + a_uint8_t direction, + a_uint32_t clock); +#endif + +#if defined(MP) +void ssdk_mp_raw_clock_set( + a_uint8_t uniphy_index, + a_uint8_t direction, + a_uint32_t clock); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _SSDK_CLK_H */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/init/ssdk_dts.h b/feeds/ipq807x/qca-ssdk/src/include/init/ssdk_dts.h new file mode 100644 index 000000000..d7ffe0482 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/init/ssdk_dts.h @@ -0,0 +1,188 @@ +/* + * 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 _SSDK_DTS_H_ +#define _SSDK_DTS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef BOARD_AR71XX +#include +#endif +#include "ssdk_init.h" +#include + +typedef struct { + a_uint16_t ucastq_start; + a_uint16_t ucastq_end; + a_uint16_t mcastq_start; + a_uint16_t mcastq_end; + a_uint8_t l0sp_start; + a_uint8_t l0sp_end; + a_uint8_t l0cdrr_start; + a_uint8_t l0cdrr_end; + a_uint8_t l0edrr_start; + a_uint8_t l0edrr_end; + a_uint8_t l1cdrr_start; + a_uint8_t l1cdrr_end; + a_uint8_t l1edrr_start; + a_uint8_t l1edrr_end; +} ssdk_dt_portscheduler_cfg; + +typedef struct { + a_uint8_t valid; + a_uint8_t port_id; + a_uint8_t cpri; + a_uint8_t cdrr_id; + a_uint8_t epri; + a_uint8_t edrr_id; + a_uint8_t sp_id; +} ssdk_dt_l0scheduler_cfg; + +typedef struct { + a_uint8_t valid; + a_uint8_t port_id; + a_uint8_t cpri; + a_uint8_t cdrr_id; + a_uint8_t epri; + a_uint8_t edrr_id; +} ssdk_dt_l1scheduler_cfg; + +typedef struct { + ssdk_dt_portscheduler_cfg pool[SSDK_MAX_PORT_NUM]; + ssdk_dt_l0scheduler_cfg l0cfg[SSDK_L0SCHEDULER_CFG_MAX]; + ssdk_dt_l1scheduler_cfg l1cfg[SSDK_L1SCHEDULER_CFG_MAX]; +} ssdk_dt_scheduler_cfg; + +typedef struct +{ + a_uint8_t port_id; + a_uint8_t phy_addr; + a_uint8_t port_duplex; + a_uint32_t port_speed; + phy_features_t phy_features; + struct mii_bus *miibus; +} ssdk_port_phyinfo; + +typedef struct +{ + a_uint32_t switchreg_base_addr; + a_uint32_t switchreg_size; + a_uint32_t psgmiireg_base_addr; + a_uint32_t psgmiireg_size; + a_uint8_t *reg_access_mode; + a_uint8_t *psgmii_reg_access_str; + hsl_reg_mode switch_reg_access_mode; + hsl_reg_mode psgmii_reg_access_mode; + struct clk *ess_clk; + struct clk *cmnblk_clk; + ssdk_port_cfg port_cfg; + a_uint32_t phyinfo_num; + ssdk_port_phyinfo *port_phyinfo; + a_uint32_t mac_mode; + a_uint32_t mac_mode1; + a_uint32_t mac_mode2; + a_uint32_t uniphyreg_base_addr; + a_uint32_t uniphyreg_size; + a_uint8_t *uniphy_access_mode; + hsl_reg_mode uniphy_reg_access_mode; + ssdk_dt_scheduler_cfg scheduler_cfg; + a_uint8_t bm_tick_mode; + a_uint8_t tm_tick_mode; + a_bool_t ess_switch_flag; + a_uint32_t device_id; + struct device_node *of_node; + a_bool_t is_emulation; + a_uint32_t emu_chip_ver; /*only valid when is_emulation is true*/ +} ssdk_dt_cfg; + +#define SSDK_MAX_NR_ETH 6 +#define SSDK_PHY_RESET_GPIO_INDEX 0 + +typedef struct +{ + a_uint32_t num_devices; + ssdk_dt_cfg **ssdk_dt_switch_nodes; + a_uint32_t num_intf_mac; + fal_mac_addr_t intf_mac[SSDK_MAX_NR_ETH]; +} ssdk_dt_global_t; + +typedef struct +{ + a_uint32_t base_addr; + a_uint32_t size; +} ssdk_reg_map_info; + +/* DTS info for get */ +#ifdef HPPE +#ifdef IN_QOS +a_uint8_t ssdk_tm_tick_mode_get(a_uint32_t dev_id); +ssdk_dt_scheduler_cfg* ssdk_bootup_shceduler_cfg_get(a_uint32_t dev_id); +#endif +#endif +#ifdef IN_BM +a_uint8_t ssdk_bm_tick_mode_get(a_uint32_t dev_id); +#endif +#ifdef IN_QM +a_uint16_t ssdk_ucast_queue_start_get(a_uint32_t dev_id, a_uint32_t port); +#endif +a_uint32_t ssdk_intf_mac_num_get(void); +a_uint8_t* ssdk_intf_macaddr_get(a_uint32_t index); +a_uint32_t ssdk_dt_global_get_mac_mode(a_uint32_t dev_id, a_uint32_t index); +a_uint32_t ssdk_dt_global_set_mac_mode(a_uint32_t dev_id, a_uint32_t index, a_uint32_t mode); +a_uint32_t ssdk_cpu_bmp_get(a_uint32_t dev_id); +a_uint32_t ssdk_lan_bmp_get(a_uint32_t dev_id); +a_uint32_t ssdk_wan_bmp_get(a_uint32_t dev_id); +sw_error_t ssdk_lan_bmp_set(a_uint32_t dev_id, a_uint32_t lan_bmp); +sw_error_t ssdk_wan_bmp_set(a_uint32_t dev_id, a_uint32_t wan_bmp); +a_uint32_t ssdk_inner_bmp_get(a_uint32_t dev_id); +ssdk_port_phyinfo* ssdk_port_phyinfo_get(a_uint32_t dev_id, a_uint32_t port_id); +a_bool_t ssdk_port_feature_get(a_uint32_t dev_id, a_uint32_t port_id, phy_features_t feature); +a_uint32_t ssdk_port_force_speed_get(a_uint32_t dev_id, a_uint32_t port_id); +struct mii_bus * +ssdk_dts_miibus_get(a_uint32_t dev_id, a_uint32_t phy_addr); +hsl_reg_mode ssdk_switch_reg_access_mode_get(a_uint32_t dev_id); +void ssdk_switch_reg_map_info_get(a_uint32_t dev_id, ssdk_reg_map_info *info); +#ifdef DESS +hsl_reg_mode ssdk_psgmii_reg_access_mode_get(a_uint32_t dev_id); +void ssdk_psgmii_reg_map_info_get(a_uint32_t dev_id, ssdk_reg_map_info *info); +#endif +#ifdef IN_UNIPHY +hsl_reg_mode ssdk_uniphy_reg_access_mode_get(a_uint32_t dev_id); +void ssdk_uniphy_reg_map_info_get(a_uint32_t dev_id, ssdk_reg_map_info *info); +#endif +a_bool_t ssdk_ess_switch_flag_get(a_uint32_t dev_id); +a_uint32_t ssdk_device_id_get(a_uint32_t index); +struct device_node *ssdk_dts_node_get(a_uint32_t dev_id); +struct clk *ssdk_dts_essclk_get(a_uint32_t dev_id); +struct clk *ssdk_dts_cmnclk_get(a_uint32_t dev_id); + +int ssdk_switch_device_num_init(void); +void ssdk_switch_device_num_exit(void); +a_uint32_t ssdk_switch_device_num_get(void); +a_bool_t ssdk_is_emulation(a_uint32_t dev_id); +a_uint32_t ssdk_emu_chip_ver_get(a_uint32_t dev_id); + +#ifndef BOARD_AR71XX +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) +sw_error_t ssdk_dt_parse(ssdk_init_cfg *cfg, a_uint32_t num, a_uint32_t *dev_id); +#endif +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _SSDK_DTS_H */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/init/ssdk_hppe.h b/feeds/ipq807x/qca-ssdk/src/include/init/ssdk_hppe.h new file mode 100755 index 000000000..6e8c68cb9 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/init/ssdk_hppe.h @@ -0,0 +1,32 @@ +/* + * 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 _SSDK_HPPE_H_ +#define _SSDK_HPPE_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "init/ssdk_init.h" + +sw_error_t qca_hppe_hw_init(ssdk_init_cfg *cfg, a_uint32_t dev_id); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _SSDK_HPPE_H */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/init/ssdk_init.h b/feeds/ipq807x/qca-ssdk/src/include/init/ssdk_init.h new file mode 100755 index 000000000..9187479ba --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/init/ssdk_init.h @@ -0,0 +1,390 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/*qca808x_start*/ +#ifndef _SSDK_INIT_H_ +#define _SSDK_INIT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "sw.h" +#include "fal_type.h" +/*qca808x_end*/ +#include "fal/fal_led.h" +/*qca808x_start*/ +#define SSDK_MAX_PORT_NUM 8 +/*qca808x_end*/ +#define SSDK_MAX_VIRTUAL_PORT_NUM 256 +#define SSDK_MAX_SERVICE_CODE_NUM 256 +#define SSDK_MAX_CPU_CODE_NUM 256 +#define SSDK_L0SCHEDULER_CFG_MAX 300 +#define SSDK_L0SCHEDULER_UCASTQ_CFG_MAX 256 +#define SSDK_L1SCHEDULER_CFG_MAX 64 +#define SSDK_SP_MAX_PRIORITY 8 +#define SSDK_MAX_FRAME_SIZE 0x3000 + +#define PORT_GMAC_TYPE 1 +#define PORT_XGMAC_TYPE 2 +#define PORT_LINK_UP 1 +#define PORT_LINK_DOWN 0 + +/*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 enum + { + HSL_REG_MDIO = 0, + HSL_REG_LOCAL_BUS, + } hsl_reg_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 dev_id, a_uint32_t reg, a_uint32_t val); + + typedef a_uint32_t (*mii_reg_get)(a_uint32_t dev_id, a_uint32_t reg); +/*qca808x_start*/ +enum ssdk_port_wrapper_cfg { + PORT_WRAPPER_PSGMII = 0, + PORT_WRAPPER_PSGMII_RGMII5, + PORT_WRAPPER_SGMII0_RGMII5, + PORT_WRAPPER_SGMII1_RGMII5, + PORT_WRAPPER_PSGMII_RMII0, + PORT_WRAPPER_PSGMII_RMII1, + PORT_WRAPPER_PSGMII_RMII0_RMII1, + PORT_WRAPPER_PSGMII_RGMII4, + PORT_WRAPPER_SGMII0_RGMII4, + PORT_WRAPPER_SGMII1_RGMII4, + PORT_WRAPPER_SGMII4_RGMII4, + PORT_WRAPPER_QSGMII, + PORT_WRAPPER_SGMII_PLUS, + PORT_WRAPPER_USXGMII, + PORT_WRAPPER_10GBASE_R, + PORT_WRAPPER_SGMII_CHANNEL0, + PORT_WRAPPER_SGMII_CHANNEL1, + PORT_WRAPPER_SGMII_CHANNEL4, + PORT_WRAPPER_RGMII, + PORT_WRAPPER_PSGMII_FIBER, + PORT_WRAPPER_SGMII_FIBER, + PORT_WRAPPER_MAX = 0xFF +}; + + 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, + CHIP_SCOMPHY, + } 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; + +enum { + QCA_PHY_F_CLAUSE45_BIT, + QCA_PHY_F_COMBO_BIT, + QCA_PHY_F_QGMAC_BIT, + QCA_PHY_F_XGMAC_BIT, + QCA_PHY_F_I2C_BIT, + QCA_PHY_F_INIT_BIT, + QCA_PHY_F_FORCE_BIT, + QCA_PHY_FEATURE_MAX +}; +/*qca808x_start*/ +#define phy_features_t a_uint16_t +#define __PHY_F_BIT(bit) ((phy_features_t)1 << (bit)) +#define _PHY_F(name) __PHY_F_BIT(QCA_PHY_F_##name##_BIT) + +#define PHY_F_CLAUSE45 _PHY_F(CLAUSE45) +#define PHY_F_COMBO _PHY_F(COMBO) +#define PHY_F_QGMAC _PHY_F(QGMAC) +#define PHY_F_XGMAC _PHY_F(XGMAC) +#define PHY_F_I2C _PHY_F(I2C) +#define PHY_F_INIT _PHY_F(INIT) +#define PHY_F_FORCE _PHY_F(FORCE) + +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 +#define def_init_cfg {.reg_mode = HSL_MDIO, .cpu_mode = HSL_CPU_2}; +#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; + +#define SSDK_RFS_INTF_MAX 8 +typedef struct +{ + a_uint32_t if_idx; /*netdevic idx*/ + fal_mac_addr_t macaddr; + a_uint16_t vid; + a_uint8_t hw_idx; /* HW table entry idx*/ +} ssdk_rfs_intf_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); + +a_uint32_t ssdk_dt_global_get_mac_mode(a_uint32_t dev_id, a_uint32_t index); +a_uint32_t ssdk_dt_global_set_mac_mode(a_uint32_t dev_id, a_uint32_t index, a_uint32_t mode); + +a_uint32_t +qca_hppe_port_mac_type_get(a_uint32_t dev_id, a_uint32_t port_id); +a_uint32_t +qca_hppe_port_mac_type_set(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t port_type); + +void ssdk_portvlan_init(a_uint32_t dev_id); +sw_error_t ssdk_dess_trunk_init(a_uint32_t dev_id, a_uint32_t wan_bitmap); + +void +qca_mac_port_status_init(a_uint32_t dev_id, a_uint32_t port_id); +void +qca_mac_sw_sync_port_status_init(a_uint32_t dev_id); +/*qca808x_start*/ +struct qca_phy_priv* ssdk_phy_priv_data_get(a_uint32_t dev_id); +/*qca808x_end*/ +sw_error_t qca_switch_init(a_uint32_t dev_id); +void qca_mac_sw_sync_work_stop(struct qca_phy_priv *priv); +void qca_mac_sw_sync_work_resume(struct qca_phy_priv *priv); +int qca_mac_sw_sync_work_start(struct qca_phy_priv *priv); +/*qca808x_start*/ +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _SSDK_INIT_H */ +/*qca808x_end*/ diff --git a/feeds/ipq807x/qca-ssdk/src/include/init/ssdk_interrupt.h b/feeds/ipq807x/qca-ssdk/src/include/init/ssdk_interrupt.h new file mode 100755 index 000000000..fb5ed629f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/init/ssdk_interrupt.h @@ -0,0 +1,29 @@ +/* + * 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 "ssdk_plat.h" + +#ifndef _SSDK_INTERRUPT_H_ +#define _SSDK_INTERRUPT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +int qca_mac_enable_intr(struct qca_phy_priv *priv); +int qca_intr_init(struct qca_phy_priv *priv); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _SSDK_INTERRUPT_H */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/init/ssdk_led.h b/feeds/ipq807x/qca-ssdk/src/include/init/ssdk_led.h new file mode 100644 index 000000000..748ea5716 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/init/ssdk_led.h @@ -0,0 +1,53 @@ +/* + * 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 _SSDK_LED_H_ +#define _SSDK_LED_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define SRC_SELECTION_0 0x0 +#define SRC_SELECTION_1 0x1 +#define SRC_SELECTION_2 0x2 +#define LED_SRC_ID_1 0x1 +#define LED_SRC_ID_2 0x2 +#define LED_SRC_ID_3 0x3 +#define LED_SRC_ID_4 0x4 +#define LED_SRC_ID_5 0x5 +#define LED_SRC_ID_6 0x6 +#define LED_SRC_ID_7 0x7 +#define LED_SRC_ID_8 0x8 +#define LED_SRC_ID_9 0x9 +#define LED_SRC_ID_10 0xa +#define LED_SRC_ID_11 0xb +#define LED_SRC_ID_12 0xc +#define LED_SRC_ID_13 0xd +#define LED_SRC_ID_14 0xe +#define LED_SRC_ID_15 0xf + + +#ifdef DESS +int ssdk_dess_led_init(ssdk_init_cfg *cfg); +#endif + +#ifdef IN_LED +sw_error_t ssdk_led_init(a_uint32_t dev_id, ssdk_init_cfg *cfg); +#endif +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _SSDK_LED_H */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/init/ssdk_mp.h b/feeds/ipq807x/qca-ssdk/src/include/init/ssdk_mp.h new file mode 100644 index 000000000..90d6062f6 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/init/ssdk_mp.h @@ -0,0 +1,35 @@ +/* + * 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 _SSDK_MP_H_ +#define _SSDK_MP_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "sw.h" + +#define MP_LPI_WAKEUP_TIMER 0x46 + +sw_error_t qca_mp_hw_init(a_uint32_t dev_id, ssdk_init_cfg *cfg); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _SSDK_MP_H */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/init/ssdk_phy_i2c.h b/feeds/ipq807x/qca-ssdk/src/include/init/ssdk_phy_i2c.h new file mode 100755 index 000000000..e682c8a9f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/init/ssdk_phy_i2c.h @@ -0,0 +1,76 @@ +/* + * 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 _SSDK_PHY_I2C_H_ +#define _SSDK_PHY_I2C_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#define QCA_PHY_I2C_MMD_OR_MII_SHIFT 6 +#define QCA_PHY_I2C_IS_MMD 1 +#define QCA_PHY_I2C_IS_MII 0 +#define QCA_PHY_I2C_MMD_ADDR_OR_DATA_SHIFT 5 +#define QCA_PHY_I2C_MMD_IS_ADDR 1 +#define QCA_PHY_I2C_MMD_IS_DATA 0 + +#define QCA_PHY_MII_ADDR_C45 (1<<30) +#define QCA_PHY_MII_ADDR_C45_IS_MMD(reg_addr_c45) ((reg_addr_c45) & QCA_PHY_MII_ADDR_C45) +#define QCA_PHY_MII_ADDR_C45_MMD_NUM(reg_addr_c45) (((reg_addr_c45) >> 16) & 0x1f) +#define QCA_PHY_MII_ADDR_C45_REG_ADDR(reg_addr_c45) ((reg_addr_c45) & 0xffff) + +#define QCA_PHY_I2C_PHYCORE_DEVADDR 0x44 +#define QCA_PHY_I2C_SERDES_DEVADDR 0x45 +#define QCA_PHY_I2C_DEVADDR_MASK 0x47 + +#define QCA_PHY_MMD1_NUM 1 +#define QCA_PHY_MMD3_NUM 3 +#define QCA_PHY_MMD7_NUM 7 + +sw_error_t +qca_phy_i2c_mii_read(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg_addr, a_uint16_t *reg_data); +sw_error_t +qca_phy_i2c_mii_write(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg_addr, a_uint16_t reg_data); +sw_error_t +qca_i2c_data_get(a_uint32_t dev_id, a_uint32_t i2c_slave, + a_uint32_t data_addr, a_uint8_t *buf, a_uint32_t count); + +sw_error_t +qca_i2c_data_set(a_uint32_t dev_id, a_uint32_t i2c_slave, + a_uint32_t data_addr, a_uint8_t *buf, a_uint32_t count); + +#ifdef IN_PHY_I2C_MODE +sw_error_t +qca_phy_i2c_mmd_read(a_uint32_t dev_id, a_uint32_t phy_addr, a_uint16_t mmd_num, + a_uint32_t reg_addr, a_uint16_t *reg_data); +sw_error_t +qca_phy_i2c_mmd_write(a_uint32_t dev_id, a_uint32_t phy_addr, a_uint16_t mmd_num, + a_uint32_t reg_addr, a_uint16_t reg_data); +a_bool_t +qca_phy_is_i2c_addr(a_uint32_t phy_addr); +sw_error_t +qca_phy_i2c_read(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg_addr_c45, a_uint16_t *reg_data); +sw_error_t +qca_phy_i2c_write(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg_addr_c45, a_uint16_t reg_data); +#endif +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _SSDK_PHY_I2C_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/init/ssdk_plat.h b/feeds/ipq807x/qca-ssdk/src/include/init/ssdk_plat.h new file mode 100644 index 000000000..a0735e78b --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/init/ssdk_plat.h @@ -0,0 +1,413 @@ +/* + * Copyright (c) 2012, 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. + */ +/*qca808x_start*/ +#ifndef __SSDK_PLAT_H +#define __SSDK_PLAT_H + +#include "sw.h" +/*qca808x_end*/ +#include +#include +#include +#include +#if defined(IN_SWCONFIG) +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) +#include +#else +#include +#endif +#endif +/*qca808x_start*/ +#include + +#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 +/*qca808x_end*/ +#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_PORT5_PHY_ADDR 4 +/*AR8327 inner phy debug register for RGMII mode*/ +#define AR8327_PHY_REG_MODE_SEL 0x12 +#define AR8327_PHY_RGMII_MODE BIT(3) +#define AR8327_PHY_REG_TEST_CTRL 0x0 +#define AR8327_PHY_RGMII_RX_DELAY BIT(15) +#define AR8327_PHY_REG_SYS_CTRL 0x5 +#define AR8327_PHY_RGMII_TX_DELAY BIT(8) + + +#define AR8327_REG_POS 0x10 +#define AR8327_REG_POS_HW_INIT 0x261320 +#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_MODULE_EN 0x30 +#define AR8327_REG_MODULE_EN_QM_ERR BIT(8) +#define AR8327_REG_MODULE_EN_LOOKUP_ERR BIT(9) + +#define AR8327_REG_MAC_SFT_RST 0x68 + +#define AR8327_REG_PAD_SGMII_CTRL 0xe0 +#define AR8327_REG_PAD_SGMII_CTRL_HW_INIT 0xc70164c0 +#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(18) +#define AR8327_PAD_MAC_PWR_RGMII1_1_8V BIT(19) + +#define AR8327_REG_PORT_LOOKUP(_i) (0x660 + (_i) * 0xc) +#define AR8327_REG_PORT_VLAN0(_i) (0x420 + (_i) * 0x8) + +#define DESS_PSGMII_MODE_CONTROL 0x1b4 +#define DESS_PSGMII_ATHR_CSCO_MODE_25M BIT(0) + +#define DESS_PSGMIIPHY_TX_CONTROL 0x288 + +#define DESS_PSGMII_PLL_VCO_RELATED_CONTROL_1 0x78c +#define DESS_PSGMII_MII_REG_UPHY_PLL_LCKDT_EN BIT(0) + +#define DESS_PSGMII_VCO_CALIBRATION_CONTROL_1 0x9c + +#define SSDK_PSGMII_ID 5 +/*qca808x_start*/ +#define SSDK_PHY_BCAST_ID 0x1f +#define SSDK_PHY_MIN_ID 0x0 +#define SSDK_PORT_CPU 0 +/*qca808x_end*/ +#define SSDK_PORT0_FC_THRESH_ON_DFLT 0x60 +#define SSDK_PORT0_FC_THRESH_OFF_DFLT 0x90 + +#define AR8327_NUM_PHYS 5 +#define AR8327_PORT_CPU 0 +#define AR8327_NUM_PORTS 7 +#define AR8327_MAX_VLANS 128 + +#define MII_PHYADDR_C45 (1<<30) + +#define SSDK_GPIO_RESET 0 +#define SSDK_GPIO_RELEASE 1 +#define SSDK_INVALID_GPIO 0 + +enum { + AR8327_PORT_SPEED_10M = 0, + AR8327_PORT_SPEED_100M = 1, + AR8327_PORT_SPEED_1000M = 2, + AR8327_PORT_SPEED_NONE = 3, +}; +/*qca808x_start*/ +enum { + QCA_VER_AR8216 = 0x01, + QCA_VER_AR8227 = 0x02, + QCA_VER_AR8236 = 0x03, + QCA_VER_AR8316 = 0x10, + QCA_VER_AR8327 = 0x12, + QCA_VER_AR8337 = 0x13, + QCA_VER_DESS = 0x14, + QCA_VER_HPPE = 0x15, + QCA_VER_SCOMPHY = 0xEE +}; +/*qca808x_end*/ +/*poll mib per 120secs*/ +#define QCA_PHY_MIB_WORK_DELAY 120000 +#define QCA_MIB_ITEM_NUMBER 41 + +#define SSDK_MAX_UNIPHY_INSTANCE 3 +#define SSDK_UNIPHY_INSTANCE0 0 +#define SSDK_UNIPHY_INSTANCE1 1 +#define SSDK_UNIPHY_INSTANCE2 2 +#define SSDK_UNIPHY_CHANNEL0 0 +#define SSDK_UNIPHY_CHANNEL1 1 +#define SSDK_UNIPHY_CHANNEL4 4 + +/*qca808x_start*/ +#define SSDK_PHYSICAL_PORT0 0 +#define SSDK_PHYSICAL_PORT1 1 +#define SSDK_PHYSICAL_PORT2 2 +#define SSDK_PHYSICAL_PORT3 3 +#define SSDK_PHYSICAL_PORT4 4 +#define SSDK_PHYSICAL_PORT5 5 +#define SSDK_PHYSICAL_PORT6 6 +#define SSDK_PHYSICAL_PORT7 7 +/*qca808x_end*/ +#define SSDK_GLOBAL_INT0_ACL_INI_INT (1<<29) +#define SSDK_GLOBAL_INT0_LOOKUP_INI_INT (1<<28) +#define SSDK_GLOBAL_INT0_QM_INI_INT (1<<27) +#define SSDK_GLOBAL_INT0_MIB_INI_INT (1<<26) +#define SSDK_GLOBAL_INT0_OFFLOAD_INI_INT (1<<25) +#define SSDK_GLOBAL_INT0_HARDWARE_INI_DONE (1<<24) + +#define SSDK_GLOBAL_INITIALIZED_STATUS \ + ( \ + SSDK_GLOBAL_INT0_ACL_INI_INT | \ + SSDK_GLOBAL_INT0_LOOKUP_INI_INT | \ + SSDK_GLOBAL_INT0_QM_INI_INT | \ + SSDK_GLOBAL_INT0_MIB_INI_INT | \ + SSDK_GLOBAL_INT0_OFFLOAD_INI_INT | \ + SSDK_GLOBAL_INT0_HARDWARE_INI_DONE \ + ) +/*qca808x_start*/ +#define SSDK_LOG_LEVEL_ERROR 0 +#define SSDK_LOG_LEVEL_WARN 1 +#define SSDK_LOG_LEVEL_INFO 2 +#define SSDK_LOG_LEVEL_DEBUG 3 +#define SSDK_LOG_LEVEL_DEFAULT SSDK_LOG_LEVEL_INFO + +extern a_uint32_t ssdk_log_level; + +#define __SSDK_LOG_FUN(lev, fmt, ...) \ + do { \ + if (SSDK_LOG_LEVEL_##lev <= ssdk_log_level) { \ + printk("%s[%u]:"#lev":"fmt, \ + __FUNCTION__, __LINE__, ##__VA_ARGS__); \ + } \ + } while(0) +#define SSDK_DUMP_BUF(lev, buf, len) \ + do {\ + if (SSDK_LOG_LEVEL_##lev <= ssdk_log_level) {\ + a_uint32_t i_buf = 0;\ + for(i_buf=0; i_buf<(len); i_buf++) {\ + printk("%08lx ", *((buf)+i_buf));\ + }\ + printk("\n");\ + }\ + } while(0) + +#define SSDK_ERROR(fmt, ...) __SSDK_LOG_FUN(ERROR, fmt, ##__VA_ARGS__) +#define SSDK_WARN(fmt, ...) __SSDK_LOG_FUN(WARN, fmt, ##__VA_ARGS__) +#define SSDK_INFO(fmt, ...) __SSDK_LOG_FUN(INFO, fmt, ##__VA_ARGS__) +#define SSDK_DEBUG(fmt, ...) __SSDK_LOG_FUN(DEBUG, fmt, ##__VA_ARGS__) + +struct qca_phy_priv { + struct phy_device *phy; +#if defined(IN_SWCONFIG) + struct switch_dev sw_dev; +#endif + a_uint8_t version; + a_uint8_t revision; + a_uint32_t (*mii_read)(a_uint32_t dev_id, a_uint32_t reg); + void (*mii_write)(a_uint32_t dev_id, 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_dbg_read)(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); + sw_error_t (*phy_write)(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t data); + sw_error_t (*phy_read)(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t* data); + + bool init; +/*qca808x_end*/ + a_bool_t qca_ssdk_sw_dev_registered; + a_bool_t ess_switch_flag; + struct mutex reg_mutex; + struct mutex mib_lock; + struct delayed_work mib_dwork; + /*qm_err_check*/ + struct mutex qm_lock; + a_uint32_t port_link_down[SW_MAX_NR_PORT]; + a_uint32_t port_link_up[SW_MAX_NR_PORT]; + a_uint32_t port_old_link[SW_MAX_NR_PORT]; + a_uint32_t port_old_speed[SW_MAX_NR_PORT]; + a_uint32_t port_old_duplex[SW_MAX_NR_PORT]; + a_uint32_t port_old_phy_status[SW_MAX_NR_PORT]; + a_uint32_t port_qm_buf[SW_MAX_NR_PORT]; + a_bool_t port_old_tx_flowctrl[SW_MAX_NR_PORT]; + a_bool_t port_old_rx_flowctrl[SW_MAX_NR_PORT]; + a_bool_t port_tx_flowctrl_forcemode[SW_MAX_NR_PORT]; + a_bool_t port_rx_flowctrl_forcemode[SW_MAX_NR_PORT]; + struct delayed_work qm_dwork_polling; + struct work_struct intr_workqueue; + /*qm_err_check end*/ +/*qca808x_start*/ + a_uint8_t device_id; + struct device_node *of_node; +/*qca808x_end*/ + /*dess_rgmii_mac*/ + struct mutex rgmii_lock; + struct delayed_work rgmii_dwork; + /*dess_rgmii_mac end*/ + /*hppe_mac_sw_sync*/ + struct mutex mac_sw_sync_lock; + struct delayed_work mac_sw_sync_dwork; + /*hppe_mac_sw_sync end*/ +/*qca808x_start*/ + struct mii_bus *miibus; +/*qca808x_end*/ + u64 *mib_counters; + /* dump buf */ + a_uint8_t buf[2048]; + a_uint32_t link_polling_required; + /* it is valid only when link_polling_required is false*/ + a_uint32_t link_interrupt_no; + a_uint32_t interrupt_flag; + char link_intr_name[IFNAMSIZ]; + /* 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[AR8327_MAX_VLANS]; + a_uint16_t pvid[SSDK_MAX_PORT_NUM]; + a_uint32_t ports; + u8 __iomem *hw_addr; + u8 __iomem *psgmii_hw_addr; + u8 __iomem *uniphy_hw_addr; +/*qca808x_start*/ +}; + +struct ipq40xx_mdio_data { + struct mii_bus *mii_bus; + void __iomem *membase; + int phy_irq[PHY_MAX_ADDR]; +}; + +#if defined(IN_SWCONFIG) +#define qca_phy_priv_get(_dev) \ + container_of(_dev, struct qca_phy_priv, sw_dev) +#endif + +/*qca808x_end*/ +a_uint32_t +qca_ar8216_mii_read(a_uint32_t dev_id, a_uint32_t reg); +void +qca_ar8216_mii_write(a_uint32_t dev_id, a_uint32_t reg, a_uint32_t val); +/*qca808x_start*/ +sw_error_t +qca_ar8327_phy_read(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t* data); +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); +void +qca_ar8327_mmd_write(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint16_t addr, a_uint16_t data); +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); +void +qca_ar8327_phy_dbg_read(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint16_t dbg_addr, a_uint16_t *dbg_data); + +void +qca_phy_mmd_write(u32 dev_id, u32 phy_id, + u16 mmd_num, u16 reg_id, u16 reg_val); + +u16 +qca_phy_mmd_read(u32 dev_id, u32 phy_id, + u16 mmd_num, u16 reg_id); +/*qca808x_end*/ +sw_error_t +qca_switch_reg_read(a_uint32_t dev_id, a_uint32_t reg_addr, + a_uint8_t * reg_data, a_uint32_t len); + +sw_error_t +qca_switch_reg_write(a_uint32_t dev_id, a_uint32_t reg_addr, + a_uint8_t * reg_data, a_uint32_t len); + +sw_error_t +qca_psgmii_reg_read(a_uint32_t dev_id, a_uint32_t reg_addr, + a_uint8_t * reg_data, a_uint32_t len); + +sw_error_t +qca_psgmii_reg_write(a_uint32_t dev_id, a_uint32_t reg_addr, + a_uint8_t * reg_data, a_uint32_t len); + +sw_error_t +qca_uniphy_reg_write(a_uint32_t dev_id, a_uint32_t uniphy_index, + a_uint32_t reg_addr, a_uint8_t * reg_data, a_uint32_t len); + +sw_error_t +qca_uniphy_reg_read(a_uint32_t dev_id, a_uint32_t uniphy_index, + a_uint32_t reg_addr, a_uint8_t * reg_data, a_uint32_t len); + +struct mii_bus *ssdk_miibus_get_by_device(a_uint32_t dev_id); + +int ssdk_sysfs_init (void); +void ssdk_sysfs_exit (void); +/*qca808x_start*/ +int ssdk_plat_init(ssdk_init_cfg *cfg, a_uint32_t dev_id); +void ssdk_plat_exit(a_uint32_t dev_id); + +#endif +/*qca808x_end*/ diff --git a/feeds/ipq807x/qca-ssdk/src/include/init/ssdk_scomphy.h b/feeds/ipq807x/qca-ssdk/src/include/init/ssdk_scomphy.h new file mode 100755 index 000000000..45ef0ffa6 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/init/ssdk_scomphy.h @@ -0,0 +1,33 @@ +/* + * 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 _SSDK_SCOMPHY_H_ +#define _SSDK_SCOMPHY_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "ssdk_init.h" + +sw_error_t qca_scomphy_hw_init(ssdk_init_cfg *cfg, a_uint32_t dev_id); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _SSDK_SCOMPY_H */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/init/ssdk_uci.h b/feeds/ipq807x/qca-ssdk/src/include/init/ssdk_uci.h new file mode 100755 index 000000000..52cc0a969 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/init/ssdk_uci.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 _SSDK_UCI_H_ +#define _SSDK_UCI_H_ + +#ifdef BOARD_AR71XX +int ssdk_uci_takeover_init(void); +void ssdk_uci_takeover_exit(void); +int ssdk_uci_sw_set_vlan(const struct switch_attr *attr, + struct switch_val *val); +int ssdk_uci_sw_set_vid(const struct switch_attr *attr, + struct switch_val *val); +int ssdk_uci_sw_set_pvid(int port, int vlan); +int ssdk_uci_sw_set_ports(struct switch_val *val); + + +#endif + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/ref/ref_api.h b/feeds/ipq807x/qca-ssdk/src/include/ref/ref_api.h new file mode 100755 index 000000000..ec3d9371a --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/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 */ + +#if defined(IN_VLAN) && !defined(IN_VLAN_MINI) +#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/src/include/ref/ref_fdb.h b/feeds/ipq807x/qca-ssdk/src/include/ref/ref_fdb.h new file mode 100755 index 000000000..31592c8f4 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/ref/ref_fdb.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2012,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 _REF_FDB_H_ +#define _REF_FDB_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include +#if defined(IN_SWCONFIG) +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) +#include +#else +#include +#endif +#endif + +#include +#include "sw.h" +#include "fal/fal_type.h" + +#if defined(IN_SWCONFIG) +int + qca_ar8327_sw_atu_flush(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val); + +int +qca_ar8327_sw_atu_dump(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val); +#endif + +fal_port_t +ref_fdb_get_port_by_mac(unsigned int vid, const char * addr); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _REF_FDB_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/ref/ref_mib.h b/feeds/ipq807x/qca-ssdk/src/include/ref/ref_mib.h new file mode 100755 index 000000000..6cb063956 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/ref/ref_mib.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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_MIB_H_ +#define _REF_MIB_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#if defined(IN_SWCONFIG) +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) +#include +#else +#include +#endif + +int +qca_ar8327_sw_set_reset_mibs(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val); + +int +qca_ar8327_sw_set_port_reset_mib(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val); + + +int +qca_ar8327_sw_get_port_mib(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val); + +#endif +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _REF_MIB_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/ref/ref_misc.h b/feeds/ipq807x/qca-ssdk/src/include/ref/ref_misc.h new file mode 100755 index 000000000..70ab4b9b8 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/ref/ref_misc.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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_MISC_H_ +#define _REF_MISC_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#if defined(IN_SWCONFIG) +int +qca_ar8327_sw_set_max_frame_size(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val); + +int +qca_ar8327_sw_get_max_frame_size(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val); + +int +qca_ar8327_sw_reset_switch(struct switch_dev *dev); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _REF_MISC_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/ref/ref_port_ctrl.h b/feeds/ipq807x/qca-ssdk/src/include/ref/ref_port_ctrl.h new file mode 100755 index 000000000..5ddc38ad0 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/ref/ref_port_ctrl.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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_PORT_CTRL_H_ +#define _REF_PORT_CTRL_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include +#if defined(IN_SWCONFIG) +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) +#include +#else +#include +#endif +#endif + +#include + +/** + * @brief QCA SSDK port link context + */ + +typedef struct{ + unsigned char port_id;/*port 1-5*/ + unsigned char port_link; /*0:linkdown, 1:linkup*/ + unsigned char speed; /*0:10M, 1:100M, 2:1000M*/ + unsigned char duplex;/*0:half, 1:full*/ +}ssdk_port_status; + +#if defined(IN_SWCONFIG) +int +qca_ar8327_sw_get_port_link(struct switch_dev *dev, int port, + struct switch_port_link *link); +#endif + +int ssdk_port_link_notify_register(struct notifier_block *nb); +int ssdk_port_link_notify_unregister(struct notifier_block *nb); +int ssdk_port_link_notify(unsigned char port_id, + unsigned char link, unsigned char speed, unsigned char duplex); +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _REF_PORT_CTRL_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/ref/ref_uci.h b/feeds/ipq807x/qca-ssdk/src/include/ref/ref_uci.h new file mode 100755 index 000000000..107a9e7c9 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/ref/ref_uci.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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_UCI_H_ +#define _REF_UCI_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +#if defined(IN_SWCONFIG) +int +qca_ar8327_sw_switch_ext(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val); +#endif + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _REF_FDB_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/ref/ref_vlan.h b/feeds/ipq807x/qca-ssdk/src/include/ref/ref_vlan.h new file mode 100755 index 000000000..e76bbac3b --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/ref/ref_vlan.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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_VLAN_H_ +#define _REF_VLAN_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#if defined(IN_SWCONFIG) +#include +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) +#include +#else +#include +#endif + +int +qca_ar8327_sw_set_vlan(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val); + +int +qca_ar8327_sw_get_vlan(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val); + +int +qca_ar8327_sw_set_vid(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val); + +int +qca_ar8327_sw_get_vid(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val); + +int +qca_ar8327_sw_get_pvid(struct switch_dev *dev, int port, int *vlan); + +int +qca_ar8327_sw_set_pvid(struct switch_dev *dev, int port, int vlan); + +int +qca_ar8327_sw_get_ports(struct switch_dev *dev, struct switch_val *val); + +int +qca_ar8327_sw_set_ports(struct switch_dev *dev, struct switch_val *val); + +int +qca_ar8327_sw_hw_apply(struct switch_dev *dev); +#endif + +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/src/include/ref/ref_vsi.h b/feeds/ipq807x/qca-ssdk/src/include/ref/ref_vsi.h new file mode 100755 index 000000000..0698f933f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/ref/ref_vsi.h @@ -0,0 +1,73 @@ +/* + * 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. + */ +#ifndef REF_VSI_H +#define REF_VSI_H +#include "sw.h" +#include "fal/fal_type.h" +#include "fal/fal_vsi.h" + + +#define REF_DEV_ID_CHECK(dev_id) \ +do { \ + if (dev_id >= SW_MAX_NR_DEV) \ + return SW_OUT_OF_RANGE; \ +} while (0) + +#define REF_PORT_ID_CHECK(port_id) \ +do { \ + if (port_id >= SW_MAX_NR_PORT) \ + return SW_OUT_OF_RANGE; \ +} while (0) + +#define REF_NULL_POINT_CHECK(point) \ +do { \ + if (point == NULL) \ + return SW_BAD_PTR; \ +} while (0) + + +enum{ + PPE_VSI_ADD, + PPE_VSI_DEL +}; +typedef struct REF_VLAN_INFO_T { + a_uint32_t stag_vid; + a_uint32_t ctag_vid; + a_uint32_t vport_bitmap; /*vlan based vsi*/ + struct REF_VLAN_INFO_T *pNext; +}ref_vlan_info_t; + +typedef struct{ + a_uint32_t valid; + a_uint32_t pport_bitmap; /*port based vsi*/ + ref_vlan_info_t *pHead; +}ref_vsi_t; + +#define PPE_VSI_PPORT_NR 7 +#define PPE_VSI_INVALID FAL_VSI_INVALID + +sw_error_t ppe_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 ppe_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 ppe_port_vsi_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vsi_id); +sw_error_t ppe_port_vsi_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t *vsi_id); +sw_error_t ppe_vsi_alloc(a_uint32_t dev_id, a_uint32_t *vsi); +sw_error_t ppe_vsi_free(a_uint32_t dev_id, a_uint32_t vsi_id); +sw_error_t ppe_vsi_tbl_dump(a_uint32_t dev_id); +sw_error_t ppe_vsi_init(a_uint32_t dev_id); +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/include/sal/os/aos_lock.h b/feeds/ipq807x/qca-ssdk/src/include/sal/os/aos_lock.h new file mode 100755 index 000000000..830151e95 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/sal/os/aos_lock.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2012,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_LOCK_H +#define _AOS_LOCK_H + + +#include "aos_lock_pvt.h" + + +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_lock_bh(lock) __aos_lock_bh(lock) + +#define aos_unlock_bh(lock) __aos_unlock_bh(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/src/include/sal/os/aos_mem.h b/feeds/ipq807x/qca-ssdk/src/include/sal/os/aos_mem.h new file mode 100755 index 000000000..b9365b955 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/sal/os/aos_mem.h @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2012,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" +#include "aos_mem_pvt.h" + +/** + * @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/src/include/sal/os/aos_timer.h b/feeds/ipq807x/qca-ssdk/src/include/sal/os/aos_timer.h new file mode 100755 index 000000000..3b4161b9b --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/sal/os/aos_timer.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2012,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_TIMER_H +#define _AOS_TIMER_H + +#include "aos_types.h" +#include "aos_timer_pvt.h" + + +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/src/include/sal/os/aos_types.h b/feeds/ipq807x/qca-ssdk/src/include/sal/os/aos_types.h new file mode 100755 index 000000000..c26fb1805 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/sal/os/aos_types.h @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2012,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 + +#include "aos_types_pvt.h" + +#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 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/src/include/sal/os/linux/aos_lock_pvt.h b/feeds/ipq807x/qca-ssdk/src/include/sal/os/linux/aos_lock_pvt.h new file mode 100755 index 000000000..fe220abd3 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/sal/os/linux/aos_lock_pvt.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 + + +typedef spinlock_t aos_lock_pvt_t; + + +#define __aos_lock_init(lock) spin_lock_init(lock) + + +#define __aos_lock(lock) spin_lock(lock) + + +#define __aos_unlock(lock) spin_unlock(lock) + +#define __aos_lock_bh(lock) spin_lock_bh(lock) + +#define __aos_unlock_bh(lock) spin_unlock_bh(lock) + +#define __aos_irq_save(flags) local_irq_save(flags) + +#define __aos_irq_restore(flags) local_irq_restore(flags) + +#ifndef KVER32 +#define __aos_default_unlock SPIN_LOCK_UNLOCKED +#endif + +#endif /*_AOS_LOCK_PVT_H*/ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/sal/os/linux/aos_mem_pvt.h b/feeds/ipq807x/qca-ssdk/src/include/sal/os/linux/aos_mem_pvt.h new file mode 100755 index 000000000..f81e23c50 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/sal/os/linux/aos_mem_pvt.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 + +static inline void *__aos_mem_alloc(aos_size_t size) +{ + return (kmalloc(size, GFP_KERNEL | __GFP_ZERO)); +} + +static inline void __aos_mem_free(void *buf) +{ + kfree(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/src/include/sal/os/linux/aos_timer_pvt.h b/feeds/ipq807x/qca-ssdk/src/include/sal/os/linux/aos_timer_pvt.h new file mode 100755 index 000000000..8bb49bc06 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/sal/os/linux/aos_timer_pvt.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 + +#ifdef KVER26 +#include +#endif +#include +#include + + +/* + * timer data type + */ +typedef struct timer_list __aos_timer_t; + + +static inline void +__aos_udelay(int usecs) +{ + udelay(usecs); +} + +static inline void +__aos_mdelay(int msecs) +{ + mdelay(msecs); +} + +#endif /*_AOS_TIMER_PVT_H*/ diff --git a/feeds/ipq807x/qca-ssdk/src/include/sal/os/linux/aos_types_pvt.h b/feeds/ipq807x/qca-ssdk/src/include/sal/os/linux/aos_types_pvt.h new file mode 100755 index 000000000..6d85ecb89 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/sal/os/linux/aos_types_pvt.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 +#include +/* + * Private definitions of general data types + */ + +/* generic data types */ +typedef struct device * __aos_device_t; +typedef int __aos_size_t; + +#ifdef KVER26 +#ifdef LNX26_22 +typedef __u8 * __aos_iomem_t; +#else +typedef u8 __iomem * __aos_iomem_t; +#endif +#else /*Linux Kernel 2.4 */ +typedef u8 * __aos_iomem_t; +#endif + +#ifdef KVER32 +typedef u8 __iomem * __aos_iomem_t; +#endif + +#ifdef LNX26_22 /* > Linux 2.6.22 */ +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; +#else +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; +#endif + +#define aos_printk printk + +#define AUTO_UPDATE_PPPOE_INFO 1 +#if 0 +#undef AUTO_UPDATE_PPPOE_INFO +#endif + +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/include/sal/sd/linux/uk_interface/sw_api_ks.h b/feeds/ipq807x/qca-ssdk/src/include/sal/sd/linux/uk_interface/sw_api_ks.h new file mode 100755 index 000000000..fcc05521e --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/sal/sd/linux/uk_interface/sw_api_ks.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2012,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_KS_H +#define _SW_API_KS_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); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _SW_API_KS_H */ diff --git a/feeds/ipq807x/qca-ssdk/src/include/sal/sd/sd.h b/feeds/ipq807x/qca-ssdk/src/include/sal/sd/sd.h new file mode 100755 index 000000000..ada85ac6a --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/sal/sd/sd.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2012, 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 _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_i2c_set(a_uint32_t dev_id, a_uint32_t phy, a_uint32_t reg, + a_uint16_t data); + + sw_error_t + sd_reg_i2c_get(a_uint32_t dev_id, a_uint32_t phy, a_uint32_t reg, + a_uint16_t * data); +/*qca808x_end*/ + 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_psgmii_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_psgmii_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 dev_id, a_uint32_t reg, a_uint32_t val); + + a_uint32_t + sd_reg_mii_get(a_uint32_t dev_id, a_uint32_t reg); +/*qca808x_start*/ + sw_error_t sd_init(a_uint32_t dev_id, ssdk_init_cfg * cfg); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _SD_H_ */ +/*qca808x_end*/ + diff --git a/feeds/ipq807x/qca-ssdk/src/include/shell_lib/shell.h b/feeds/ipq807x/qca-ssdk/src/include/shell_lib/shell.h new file mode 100755 index 000000000..5bdcfb480 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/shell_lib/shell.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2013, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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" + + +#define IOCTL_BUF_SIZE 2048 +#define CMDSTR_BUF_SIZE 1024 +#define CMDSTR_ARGS_MAX 128 +#define dprintf + +int cmd_run_one(char *cmd_str); +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/src/include/shell_lib/shell_config.h b/feeds/ipq807x/qca-ssdk/src/include/shell_lib/shell_config.h new file mode 100755 index 000000000..173c75587 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/shell_lib/shell_config.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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_MAX (SW_API_MAX + 11) + +#define MAX_SUB_CMD_DES_NUM 40 + + struct sub_cmd_des_t + { + char *sub_name; + char *sub_act; + int sub_api; + sw_error_t (*sub_func) (void); + }; + struct cmd_des_t + { + char *name; + struct sub_cmd_des_t *sub_cmd_des; + }; + 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/src/include/shell_lib/shell_io.h b/feeds/ipq807x/qca-ssdk/src/include/shell_lib/shell_io.h new file mode 100644 index 000000000..7a8d3196b --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/shell_lib/shell_io.h @@ -0,0 +1,484 @@ +/* + * Copyright (c) 2013, 2015-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 _SHELL_IO_H +#define _SHELL_IO_H + +#include "sw.h" +#include "sw_api.h" +#include "fal.h" + +#define SW_TYPE_DEF(type, parser, show) {type, parser, show} +typedef sw_error_t + (*param_check_t)(char *, a_uint32_t *, a_uint32_t); +typedef sw_error_t + (*param_check_range_t)(char *, a_uint32_t *, a_uint32_t, a_uint32_t); +typedef sw_error_t + (*param_check_boolean_t)(char *, a_bool_t, a_bool_t *, a_uint32_t); +typedef struct +{ + sw_data_type_e data_type; + param_check_t param_check; + void (*show_func) (void); +} 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_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_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); +#ifdef IN_PORTCONTROL +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); +#ifndef IN_PORTCONTROL_MINI +sw_error_t +cmd_data_check_port_eee_config(char *cmd_str, void * val, a_uint32_t size); +sw_error_t +cmd_data_check_switch_port_loopback_config(char *cmd_str, void * val, + a_uint32_t size); +#endif +#endif +#ifdef IN_PORTVLAN +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); +#ifdef HPPE +sw_error_t +cmd_data_check_global_qinqmode(char *info, void *val, a_uint32_t size); +sw_error_t +cmd_data_check_port_qinqmode(char *info, void *val, a_uint32_t size); +sw_error_t +cmd_data_check_tpid(char *info, void *val, a_uint32_t size); +sw_error_t +cmd_data_check_ingress_filter(char *info, void *val, 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); +sw_error_t +cmd_data_check_port_default_vid_en(char *info, void *val, a_uint32_t size); +sw_error_t +cmd_data_check_port_vlan_tag(char *info, void *val, a_uint32_t size); +sw_error_t +cmd_data_check_tag_propagation(char *info, void *val, a_uint32_t size); +sw_error_t +cmd_data_check_egress_mode(char *info, void *val, a_uint32_t size); +sw_error_t +cmd_data_check_port_vlan_translation_adv_rule(char *info, void *val, + a_uint32_t size); +sw_error_t +cmd_data_check_port_vlan_translation_adv_action(char *info, void *val, + a_uint32_t size); +#endif +#endif +#ifdef IN_PORTCONTROL +sw_error_t cmd_data_check_capable(char *cmd_str, a_uint32_t * arg_val, + a_uint32_t size); +#endif +#ifdef IN_FDB +sw_error_t cmd_data_check_fdbentry(char *cmdstr, void *val, a_uint32_t size); +#ifndef IN_FDB_MINI +sw_error_t cmd_data_check_maclimit_ctrl(char *info, void *val, a_uint32_t size); +#endif +#endif +sw_error_t cmd_data_check_macaddr(char *cmdstr, void *val, a_uint32_t size); +#ifdef IN_VLAN +sw_error_t cmd_data_check_vlan(char *cmdstr, fal_vlan_t * val, a_uint32_t size); +#endif +#ifdef IN_QOS +#ifndef IN_QOS_MINI +sw_error_t cmd_data_check_qos_sch(char *cmdstr, fal_sch_mode_t * val, + a_uint32_t size); +sw_error_t cmd_data_check_qos_pt(char *cmdstr, fal_qos_mode_t * val, + a_uint32_t size); +sw_error_t +cmd_data_check_port_group(char *cmd_str, void * val, a_uint32_t size); +sw_error_t +cmd_data_check_port_pri(char *cmd_str, void * val, a_uint32_t size); +sw_error_t +cmd_data_check_port_remark(char *cmd_str, void * val, a_uint32_t size); +sw_error_t +cmd_data_check_cosmap(char *cmd_str, void * val, a_uint32_t size); +sw_error_t +cmd_data_check_queue_scheduler(char *cmd_str, void * val, a_uint32_t size); +sw_error_t +cmd_data_check_ring_queue(char *cmd_str, void * val, a_uint32_t size); +#endif +#endif +#ifdef IN_RATE +sw_error_t cmd_data_check_storm(char *cmdstr, fal_storm_type_t * val, + a_uint32_t size); +#endif +#ifdef IN_STP +sw_error_t cmd_data_check_stp_state(char *cmdstr, fal_stp_state_t * val, + a_uint32_t size); +#endif +#ifdef IN_LEAKY +sw_error_t cmd_data_check_leaky(char *cmdstr, fal_leaky_ctrl_mode_t * val, + a_uint32_t size); +#endif +sw_error_t cmd_data_check_uinta(char *cmdstr, a_uint32_t * val, + a_uint32_t size); +sw_error_t cmd_data_check_maccmd(char *cmdstr, fal_fwd_cmd_t * val, + a_uint32_t size); +#ifdef IN_IP +#ifndef IN_IP_MINI +sw_error_t cmd_data_check_flowcmd(char *cmdstr, fal_default_flow_cmd_t * val, + a_uint32_t size); +sw_error_t cmd_data_check_flowtype(char *cmdstr, fal_flow_type_t * val, + a_uint32_t size); +#endif +#endif +#ifdef IN_LED +sw_error_t cmd_data_check_ledpattern(char *info, void * val, a_uint32_t size); +#endif +#ifdef IN_PORTVLAN +sw_error_t +cmd_data_check_invlan_mode(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size); +sw_error_t +cmd_data_check_vlan_propagation(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size); +#ifndef IN_PORTVLAN_MINI +sw_error_t +cmd_data_check_vlan_translation(char *info, fal_vlan_trans_entry_t *val, a_uint32_t size); +#endif +sw_error_t +cmd_data_check_qinq_mode(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size); +sw_error_t +cmd_data_check_qinq_role(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size); +#endif +#ifdef IN_PORTCONTROL +sw_error_t +cmd_data_check_hdrmode(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size); +#endif +#ifdef IN_FDB +sw_error_t +cmd_data_check_fdboperation(char *cmd_str, void * val, a_uint32_t size); +#endif +#ifdef IN_PPPOE +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); +#endif +#if defined(IN_IP) || defined(IN_NAT) +sw_error_t +cmd_data_check_host_entry(char *cmd_str, void * val, 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); + +sw_error_t +cmd_data_check_ip_guard_mode(char *cmd_str, fal_source_guard_mode_t * arg_val, a_uint32_t size); + + +sw_error_t +cmd_data_check_nat_entry(char *cmd_str, void * val, a_uint32_t size); + + +sw_error_t +cmd_data_check_napt_entry(char *cmd_str, void * val, a_uint32_t size); + +sw_error_t +cmd_data_check_flow_entry(char *cmd_str, void * val, 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); + + +sw_error_t +cmd_data_check_intf_mac_entry(char *cmd_str, void * val, a_uint32_t size); + +sw_error_t +cmd_data_check_pub_addr_entry(char *cmd_str, void * val, a_uint32_t size); +#endif + +sw_error_t +cmd_data_check_ip4addr(char *cmdstr, void * val, a_uint32_t size); + +sw_error_t +cmd_data_check_ip6addr(char *cmdstr, void * val, a_uint32_t size); + + +sw_error_t +cmd_data_check_egress_shaper(char *cmd_str, void * val, a_uint32_t size); + +#ifdef IN_RATE +sw_error_t +cmd_data_check_port_policer(char *cmd_str, void * val, a_uint32_t size); + +sw_error_t +cmd_data_check_policer_timesslot(char *cmd_str, a_uint32_t * val, a_uint32_t size); + +sw_error_t +cmd_data_check_acl_policer(char *cmd_str, void * val, a_uint32_t size); +#endif +#ifdef IN_FDB +#ifndef IN_FDB_MINI +sw_error_t +cmd_data_check_fdb_smode(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size); +#endif +#endif +#ifdef IN_IGMP +sw_error_t +cmd_data_check_multi(char *info, void *val, a_uint32_t size); +#endif +#ifdef IN_SEC +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); +#ifdef HPPE +sw_error_t +cmd_data_check_l3_parser(char *cmd_str, void * val, a_uint32_t size); + +sw_error_t +cmd_data_check_l4_parser(char *cmd_str, void * val, a_uint32_t size); + +sw_error_t +cmd_data_check_exp_ctrl(char *cmd_str, void * val, a_uint32_t size); +#endif +#endif +#ifdef IN_COSMAP +#ifndef IN_COSMAP_MINI +sw_error_t +cmd_data_check_remark_entry(char *info, void *val, a_uint32_t size); +#endif +#endif +#ifdef IN_IP +#ifndef IN_IP_MINI +sw_error_t +cmd_data_check_default_route_entry(char *cmd_str, void * val, a_uint32_t size); + +sw_error_t +cmd_data_check_host_route_entry(char *cmd_str, void * val, 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_arp_sg(char *cmd_str, void * val, a_uint32_t size); +sw_error_t +cmd_data_check_network_route(char *cmd_str, void * val, a_uint32_t size); +sw_error_t +cmd_data_check_intf(char *cmd_str, void * val, a_uint32_t size); +sw_error_t +cmd_data_check_vsi_intf(char *cmd_str, void * val, a_uint32_t size); +sw_error_t +cmd_data_check_nexthop(char *cmd_str, void * val, a_uint32_t size); +sw_error_t +cmd_data_check_ip_sg(char *cmd_str, void * val, a_uint32_t size); +sw_error_t +cmd_data_check_ip_pub(char *cmd_str, void * val, a_uint32_t size); +sw_error_t +cmd_data_check_ip_portmac(char *cmd_str, void * val, a_uint32_t size); +sw_error_t +cmd_data_check_ip_mcmode(char *cmd_str, void * val, a_uint32_t size); +sw_error_t +cmd_data_check_ip_global(char *cmd_str, void * val, a_uint32_t size); +#endif +#endif +#if defined(IN_IP) || defined(IN_NAT) +sw_error_t +cmd_data_check_flow_cookie(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); +#endif +#ifdef IN_PORTCONTROL +#ifndef IN_PORTCONTROL_MINI +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); + +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); + +sw_error_t +cmd_data_check_src_filter_config(char *cmd_str, a_uint32_t * arg_val, 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); + + +#endif +#endif +#ifdef IN_INTERFACECONTROL +sw_error_t +cmd_data_check_interface_mode(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size); +#endif +#ifdef IN_VSI +sw_error_t +cmd_data_check_newadr_lrn(char *cmd_str, void * val, a_uint32_t size); + +sw_error_t +cmd_data_check_stamove(char *cmd_str, void * val, a_uint32_t size); + +sw_error_t +cmd_data_check_vsi_member(char *cmd_str, void * val, a_uint32_t size); + +#endif +#ifdef IN_BM +sw_error_t +cmd_data_check_bm_dynamic_thresh(char *cmd_str, void * val, a_uint32_t size); +sw_error_t +cmd_data_check_bm_static_thresh(char *cmd_str, void * val, a_uint32_t size); +#endif +#ifdef IN_QM +sw_error_t +cmd_data_check_u_qmap(char *cmd_str, void * val, a_uint32_t size); + +sw_error_t +cmd_data_check_ac_static_thresh(char *cmd_str, void * val, a_uint32_t size); + +sw_error_t +cmd_data_check_ac_dynamic_thresh(char *cmd_str, void * val, a_uint32_t size); + +sw_error_t +cmd_data_check_ac_group_buff(char *cmd_str, void * val, a_uint32_t size); + +sw_error_t +cmd_data_check_ac_ctrl(char *cmd_str, void * val, a_uint32_t size); + +sw_error_t +cmd_data_check_ac_obj(char *cmd_str, void * val, a_uint32_t size); + +#endif +#ifdef IN_FLOW +sw_error_t +cmd_data_check_flow_age(char *cmd_str, void * val, a_uint32_t size); +sw_error_t +cmd_data_check_flow_ctrl(char *cmd_str, void * val, a_uint32_t size); +sw_error_t +cmd_data_check_flow(char *cmd_str, void * val, a_uint32_t size); +sw_error_t +cmd_data_check_flow_global(char *cmd_str, void * val, a_uint32_t size); +sw_error_t +cmd_data_check_flow_host(char *cmd_str, void * val, a_uint32_t size); +#endif + +#ifdef IN_POLICER +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); + +sw_error_t +cmd_data_check_acl_policer_config(char *cmd_str, void * val, a_uint32_t size); + +#endif + +#ifdef IN_SHAPER +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); + +#endif + +#ifdef IN_SERVCODE +sw_error_t +cmd_data_check_servcode_config(char *info, fal_servcode_config_t *val, a_uint32_t size); +#endif + +#ifdef IN_RSS_HASH +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); +#endif + +#ifdef IN_MIRROR +sw_error_t +cmd_data_check_mirr_analy_cfg(char *info, void *val, a_uint32_t size); +sw_error_t +cmd_data_check_mirr_direction(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size); +#endif +sw_error_t +cmd_data_check_integer(char *cmd_str, a_uint32_t * arg_val, a_uint32_t max_val, a_uint32_t min_val); +#ifdef IN_CTRLPKT +sw_error_t +cmd_data_check_ctrlpkt_appprofile(char *info, void *val, a_uint32_t size); +#endif +#ifdef IN_ACL +sw_error_t +cmd_data_check_ruletype(char *cmd_str, fal_acl_rule_type_t * arg_val, a_uint32_t size); +sw_error_t +cmd_data_check_udf_pkt_type(char *cmdstr, fal_acl_udf_pkt_type_t * arg_val, 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); +sw_error_t +cmd_data_check_udf_element(char *cmdstr, a_uint8_t * val, a_uint32_t * len); +sw_error_t +cmd_data_check_fieldop(char *cmdstr, fal_acl_field_op_t def, fal_acl_field_op_t * val); + +#endif +sw_error_t +cmd_data_check_module(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size); +sw_error_t +cmd_data_check_func_ctrl(char *cmd_str, void * val, a_uint32_t size); +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/include/shell_lib/shell_sw.h b/feeds/ipq807x/qca-ssdk/src/include/shell_lib/shell_sw.h new file mode 100755 index 000000000..80d3acb32 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/include/shell_lib/shell_sw.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2013, 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_SW_H_ +#define _SHELL_SW_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + int get_devid(void); + sw_error_t cmd_set_devid(a_uint32_t *arg_val); + sw_error_t uci_set_devid(a_uint32_t dev_id); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _SHELL_SW_H_ */ diff --git a/feeds/ipq807x/qca-ssdk/src/ko_Makefile b/feeds/ipq807x/qca-ssdk/src/ko_Makefile new file mode 100755 index 000000000..5cfb1f37d --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/ko_Makefile @@ -0,0 +1,3 @@ +obj-m := qca-ssdk.o +OBJ_LIST:=$(notdir $(wildcard $(PRJ_PATH)/temp/*.o)) +qca-ssdk-objs := $(OBJ_LIST) diff --git a/feeds/ipq807x/qca-ssdk/src/make/.build_number b/feeds/ipq807x/qca-ssdk/src/make/.build_number new file mode 100644 index 000000000..0cfbf0888 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/make/.build_number @@ -0,0 +1 @@ +2 diff --git a/feeds/ipq807x/qca-ssdk/src/make/components.mk b/feeds/ipq807x/qca-ssdk/src/make/components.mk new file mode 100755 index 000000000..01970652a --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/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 SHELIB + ifeq (TRUE, $(FAL)) + COMPONENTS += FAL ADPT + 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 ADPT + endif + else + COMPONENTS = UK_IF SAL + endif + + ifeq (TRUE, $(UK_IF)) + COMPONENTS += API + endif + endif + + ifeq (SHELL, $(MODULE_TYPE)) + COMPONENTS = SHELL + endif +endif diff --git a/feeds/ipq807x/qca-ssdk/src/make/config.mk b/feeds/ipq807x/qca-ssdk/src/make/config.mk new file mode 100755 index 000000000..e357259a1 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/make/config.mk @@ -0,0 +1,119 @@ + +include $(PRJ_PATH)/config +-include $(SYS_PATH)/include/config/auto.conf + +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 (DESS, $(CHIP_TYPE)) + SUPPORT_CHIP = DESS + endif + + ifeq (HPPE, $(CHIP_TYPE)) + SUPPORT_CHIP = HPPE + endif + + ifeq (CPPE, $(CHIP_TYPE)) + SUPPORT_CHIP = HPPE CPPE + endif + + ifeq (MP, $(CHIP_TYPE)) + SUPPORT_CHIP = SCOMPHY MP + endif + + ifeq ($(ISISC_ENABLE), enable) + 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 = ISIS ISISC SHIVA DESS HPPE CPPE SCOMPHY MP + endif + + ifeq (NONHK_CHIP, $(CHIP_TYPE)) + ifneq (TRUE, $(FAL)) + $(error FAL must be TRUE when CHIP_TYPE is defined as ALL_CHIP!) + endif + SUPPORT_CHIP = ISIS ISISC SHIVA DESS + 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_NUMBER) +BUILD_DATE=$(shell date -u +%F-%T) diff --git a/feeds/ipq807x/qca-ssdk/src/make/defs.mk b/feeds/ipq807x/qca-ssdk/src/make/defs.mk new file mode 100755 index 000000000..7d1c75bb9 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/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/src/make/linux_opt.mk b/feeds/ipq807x/qca-ssdk/src/make/linux_opt.mk new file mode 100755 index 000000000..17c75dd6e --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/make/linux_opt.mk @@ -0,0 +1,698 @@ +MODULE_CFLAG := +LOCAL_CFLAGS := + +ifeq (TRUE, $(SWCONFIG)) + MODULE_CFLAG += -DIN_SWCONFIG +endif + +ifeq (TRUE, $(IN_ACL)) + MODULE_CFLAG += -DIN_ACL +endif + +ifeq (TRUE, $(IN_FDB)) + MODULE_CFLAG += -DIN_FDB +endif + +ifeq (TRUE, $(IN_FDB_MINI)) + MODULE_CFLAG += -DIN_FDB_MINI +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_MISC_MINI)) + MODULE_CFLAG += -DIN_MISC_MINI +endif + +ifeq (TRUE, $(IN_PORTCONTROL)) + MODULE_CFLAG += -DIN_PORTCONTROL +endif + +ifeq (TRUE, $(IN_PORTCONTROL_MINI)) + MODULE_CFLAG += -DIN_PORTCONTROL_MINI +endif + +ifeq (TRUE, $(IN_PORTVLAN)) + MODULE_CFLAG += -DIN_PORTVLAN +endif + +ifeq (TRUE, $(IN_PORTVLAN_MINI)) + MODULE_CFLAG += -DIN_PORTVLAN_MINI +endif + +ifeq (TRUE, $(IN_QOS)) + MODULE_CFLAG += -DIN_QOS +endif + +ifeq (TRUE, $(IN_QOS_MINI)) + MODULE_CFLAG += -DIN_QOS_MINI +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_VLAN_MINI)) + MODULE_CFLAG += -DIN_VLAN_MINI +endif + +ifeq (TRUE, $(IN_REDUCED_ACL)) + MODULE_CFLAG += -DIN_REDUCED_ACL +endif + +ifeq (TRUE, $(IN_COSMAP)) + MODULE_CFLAG += -DIN_COSMAP +endif + +ifeq (TRUE, $(IN_COSMAP_MINI)) + MODULE_CFLAG += -DIN_COSMAP_MINI +endif + +ifeq (TRUE, $(IN_IP)) + MODULE_CFLAG += -DIN_IP +endif + +ifeq (TRUE, $(IN_IP_MINI)) + MODULE_CFLAG += -DIN_IP_MINI +endif + +ifeq (TRUE, $(IN_NAT)) + MODULE_CFLAG += -DIN_NAT +endif + +ifeq (TRUE, $(IN_FLOW)) + MODULE_CFLAG += -DIN_FLOW +endif + +ifeq (TRUE, $(IN_FLOW_MINI)) + MODULE_CFLAG += -DIN_FLOW_MINI +endif + +ifeq (TRUE, $(IN_SFE)) + MODULE_CFLAG += -DIN_SFE +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_QM_MINI)) + MODULE_CFLAG += -DIN_QM_MINI +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_RFS)) + MODULE_CFLAG += -DIN_RFS +endif + +ifeq (TRUE, $(IN_MALIBU_PHY)) + MODULE_CFLAG += -DIN_MALIBU_PHY +endif +ifeq (TRUE, $(IN_AQUANTIA_PHY)) + MODULE_CFLAG += -DIN_AQUANTIA_PHY +endif + +ifeq (TRUE, $(IN_QCA803X_PHY)) + MODULE_CFLAG += -DIN_QCA803X_PHY +endif + +ifeq (TRUE, $(IN_QCA808X_PHY)) + MODULE_CFLAG += -DIN_QCA808X_PHY +endif +ifeq (TRUE, $(IN_SFP_PHY)) + MODULE_CFLAG += -DIN_SFP_PHY +endif + +ifeq (TRUE, $(IN_PHY_I2C_MODE)) + MODULE_CFLAG += -DIN_PHY_I2C_MODE +endif + +ifeq (TRUE, $(IN_VSI)) + MODULE_CFLAG += -DIN_VSI +endif + +ifeq (TRUE, $(IN_VSI_MINI)) + MODULE_CFLAG += -DIN_VSI_MINI +endif + +ifeq (TRUE, $(IN_PPPOE)) + MODULE_CFLAG += -DIN_PPPOE +endif + +ifeq (TRUE, $(IN_BM)) + MODULE_CFLAG += -DIN_BM +endif + +ifeq (TRUE, $(IN_BM_MINI)) + MODULE_CFLAG += -DIN_BM_MINI +endif + +ifeq (TRUE, $(IN_SHAPER)) + MODULE_CFLAG += -DIN_SHAPER +endif + +ifeq (TRUE, $(IN_SHAPER_MINI)) + MODULE_CFLAG += -DIN_SHAPER_MINI +endif + +ifeq (TRUE, $(IN_POLICER)) + MODULE_CFLAG += -DIN_POLICER +endif + +ifeq (TRUE, $(IN_POLICER_MINI)) + MODULE_CFLAG += -DIN_POLICER_MINI +endif + +ifeq (TRUE, $(IN_UNIPHY)) + MODULE_CFLAG += -DIN_UNIPHY +endif + +ifeq (TRUE, $(IN_UNIPHY_MINI)) + MODULE_CFLAG += -DIN_UNIPHY_MINI +endif + +ifeq (TRUE, $(RUMI_EMULATION)) + MODULE_CFLAG += -DRUMI_EMULATION +endif + +ifeq (TRUE, $(IN_PTP)) + MODULE_CFLAG += -DIN_PTP +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 -DVERSION=\"$(VERSION)\" -DBUILD_DATE=\"$(BUILD_DATE)\" -DOS=\"$(OS)\" -D"KBUILD_STR(s)=\#s" -D"KBUILD_MODNAME=KBUILD_STR(qca-ssdk)" + +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/adpt \ + -I$(PRJ_PATH)/include/hsl \ + -I$(PRJ_PATH)/include/hsl/phy \ + -I$(PRJ_PATH)/include/sal/os \ + -I$(PRJ_PATH)/include/sal/os/linux \ + -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 (,$(filter ISIS, $(SUPPORT_CHIP))) + MODULE_INC += -I$(PRJ_PATH)/include/hsl/isis + MODULE_CFLAG += -DISIS +endif + +ifneq (,$(findstring ISISC, $(SUPPORT_CHIP))) + MODULE_INC += -I$(PRJ_PATH)/include/hsl/isisc + MODULE_CFLAG += -DISISC +endif + +ifneq (,$(findstring DESS, $(SUPPORT_CHIP))) + MODULE_INC += -I$(PRJ_PATH)/include/hsl/dess + MODULE_CFLAG += -DDESS +endif + +ifneq (,$(findstring HPPE, $(SUPPORT_CHIP))) + MODULE_INC += -I$(PRJ_PATH)/include/hsl/hppe + MODULE_INC += -I$(PRJ_PATH)/include/adpt/hppe + MODULE_CFLAG += -DHPPE +endif + +ifneq (,$(filter MP, $(SUPPORT_CHIP))) + MODULE_INC += -I$(PRJ_PATH)/include/hsl/hppe + MODULE_INC += -I$(PRJ_PATH)/include/adpt/mp + MODULE_INC += -I$(PRJ_PATH)/include/hsl/mp + MODULE_CFLAG += -DMP +endif + +ifneq (,$(findstring CPPE, $(SUPPORT_CHIP))) + MODULE_INC += -I$(PRJ_PATH)/include/hsl/cppe + MODULE_INC += -I$(PRJ_PATH)/include/adpt/cppe + MODULE_CFLAG += -DCPPE +endif + + +ifneq (,$(findstring SCOMPHY, $(SUPPORT_CHIP))) + MODULE_INC += -I$(PRJ_PATH)/include/hsl/scomphy + MODULE_CFLAG += -DSCOMPHY +endif + +ifeq (TRUE, $(IN_SFP)) + MODULE_INC += -I$(PRJ_PATH)/include/hsl/sfp + MODULE_INC += -I$(PRJ_PATH)/include/adpt/sfp + MODULE_CFLAG += -DIN_SFP +endif + +# check for GCC version +ifeq (4, $(GCC_VER)) + MODULE_CFLAG += -DGCCV4 +endif + +ifeq (TRUE, $(IN_PTP)) +ifeq ($(CONFIG_PTP_1588_CLOCK), y) + MODULE_CFLAG += -DIN_LINUX_STD_PTP +endif +endif + +ifeq (KSLIB, $(MODULE_TYPE)) + + MODULE_INC += -I$(PRJ_PATH)/include/shell_lib + ifndef TARGET_NAME + TARGET_NAME=arm-openwrt-linux-$(TARGET_SUFFIX) + endif + + ifeq ($(CONFIG_KASAN_INLINE),y) + CALL_THRESHOLD=10000 + else + CALL_THRESHOLD=0 + endif + ifneq ($(CONFIG_KASAN_SHADOW_OFFSET),) + SHADOW_OFFSET=$(CONFIG_KASAN_SHADOW_OFFSET) + else + SHADOW_OFFSET=0xdfffff9000000000 + endif + KASAN_OPTION=-fsanitize=kernel-address -fasan-shadow-offset=$(SHADOW_OFFSET) \ + --param asan-stack=1 --param asan-globals=1 \ + --param asan-instrumentation-with-call-threshold=$(CALL_THRESHOLD) + + ifeq ($(CONFIG_KASAN_SW_TAGS), y) + KASAN_SHADOW_SCALE_SHIFT := 4 + else + KASAN_SHADOW_SCALE_SHIFT := 3 + endif + + ifeq (5_4, $(OS_VER)) + ifeq ($(ARCH), arm64) + KASAN_OPTION += -DKASAN_SHADOW_SCALE_SHIFT=$(KASAN_SHADOW_SCALE_SHIFT) + endif + endif + ifeq ($(CONFIG_KASAN),y) + MODULE_CFLAG += $(KASAN_OPTION) + endif + + ifeq (3_18, $(OS_VER)) + MODULE_CFLAG += -DKVER34 + MODULE_CFLAG += -DKVER32 + MODULE_CFLAG += -DLNX26_22 + MODULE_INC += -I$(SYS_PATH) \ + -I$(TOOL_PATH)/../lib/gcc/$(TARGET_NAME)/$(GCC_VERSION)/include/ \ + -I$(SYS_PATH)/include \ + -I$(SYS_PATH)/source/include \ + -I$(SYS_PATH)/source/arch/arm/mach-msm/include \ + -I$(SYS_PATH)/arch/arm/mach-msm/include \ + -I$(SYS_PATH)/source/arch/arm/include \ + -I$(SYS_PATH)/arch/arm/include \ + -I$(SYS_PATH)/source/arch/arm/include/asm \ + -I$(SYS_PATH)/arch/arm/include/generated \ + -I$(SYS_PATH)/include/generated/uapi \ + -I$(SYS_PATH)/include/uapi \ + -I$(SYS_PATH)/arch/arm/include/uapi \ + -I$(SYS_PATH)/source/arch/arm/include/asm/mach \ + -include $(SYS_PATH)/include/linux/kconfig.h + + endif + + ifeq ($(OS_VER),$(filter 4_4 5_4, $(OS_VER))) + MODULE_CFLAG += -DKVER34 + MODULE_CFLAG += -DKVER32 + MODULE_CFLAG += -DLNX26_22 + ifeq ($(ARCH), arm64) + MODULE_INC += -I$(SYS_PATH) \ + -I$(TOOL_PATH)/../lib/gcc/$(TARGET_NAME)/$(GCC_VERSION)/include/ \ + -I$(SYS_PATH)/include \ + -I$(SYS_PATH)/source \ + -I$(SYS_PATH)/source/include \ + -I$(SYS_PATH)/source/arch/arm64/mach-msm/include \ + -I$(SYS_PATH)/arch/arm64/mach-msm/include \ + -I$(SYS_PATH)/source/arch/arm64/include \ + -I$(SYS_PATH)/arch/arm64/include \ + -I$(SYS_PATH)/source/arch/arm64/include/asm \ + -I$(SYS_PATH)/arch/arm64/include/generated \ + -I$(SYS_PATH)/include/generated/uapi \ + -I$(SYS_PATH)/include/uapi \ + -I$(SYS_PATH)/arch/arm64/include/uapi \ + -I$(SYS_PATH)/source/arch/arm64/include/asm/mach + + ifneq ($(wildcard $(SYS_PATH)/include/linux/kconfig.h),) + MODULE_INC += -include $(SYS_PATH)/include/linux/kconfig.h + else + MODULE_INC += -include $(KERNEL_SRC)/include/linux/kconfig.h + endif + + else ifeq ($(ARCH), arm) + MODULE_INC += -I$(SYS_PATH) \ + -I$(TOOL_PATH)/../lib/gcc/$(TARGET_NAME)/$(GCC_VERSION)/include/ \ + -I$(TOOL_PATH)/../lib/gcc/$(TARGET_NAME)/7.5.0/include/ \ + -I$(TOOL_PATH)/../../lib/armv7a-vfp-neon-rdk-linux-gnueabi/gcc/arm-rdk-linux-gnueabi/4.8.4/include/ \ + -I$(TOOL_PATH)/../../lib/arm-rdk-linux-musleabi/gcc/arm-rdk-linux-musleabi/6.4.0/include/ \ + -I$(SYS_PATH)/include \ + -I$(SYS_PATH)/source \ + -I$(SYS_PATH)/source/include \ + -I$(SYS_PATH)/source/arch/arm/mach-msm/include \ + -I$(SYS_PATH)/arch/arm/mach-msm/include \ + -I$(SYS_PATH)/source/arch/arm/include \ + -I$(SYS_PATH)/arch/arm/include \ + -I$(SYS_PATH)/source/arch/arm/include/asm \ + -I$(SYS_PATH)/arch/arm/include/generated \ + -I$(SYS_PATH)/arch/arm/include/generated/uapi \ + -I$(SYS_PATH)/source/include/uapi \ + -I$(SYS_PATH)/include/generated/uapi \ + -I$(SYS_PATH)/include/uapi \ + -I$(SYS_PATH)/arch/arm/include/uapi \ + -I$(SYS_PATH)/source/arch/arm/include/asm/mach + + ifneq ($(wildcard $(SYS_PATH)/include/linux/kconfig.h),) + MODULE_INC += -include $(SYS_PATH)/include/linux/kconfig.h + else + MODULE_INC += -include $(KERNEL_SRC)/include/linux/kconfig.h + endif + + else + MODULE_INC += -I$(SYS_PATH) \ + -I$(TOOL_PATH)/../lib/gcc/$(TARGET_NAME)/$(GCC_VERSION)/include/ \ + -I$(SYS_PATH)/include \ + -I$(SYS_PATH)/source \ + -I$(SYS_PATH)/source/include \ + -I$(SYS_PATH)/source/arch/mips/mach-msm/include \ + -I$(SYS_PATH)/arch/mips/mach-msm/include \ + -I$(SYS_PATH)/source/arch/mips/include \ + -I$(SYS_PATH)/arch/mips/include \ + -I$(SYS_PATH)/source/arch/mips/include/asm \ + -I$(SYS_PATH)/arch/mips/include/generated \ + -I$(SYS_PATH)/include/generated/uapi \ + -I$(SYS_PATH)/include/uapi \ + -I$(SYS_PATH)/arch/mips/include/uapi \ + -I$(SYS_PATH)/source/arch/mips/include/asm/mach \ + -include $(SYS_PATH)/include/linux/kconfig.h \ + -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 + endif + + endif + + ifeq ($(OS_VER),$(filter 4_9 4_1, $(OS_VER))) + MODULE_CFLAG += -DKVER34 + MODULE_CFLAG += -DKVER32 + MODULE_CFLAG += -DLNX26_22 + ifeq ($(ARCH), arm64) + KCONF_FILE = $(SYS_PATH)/source/include/linux/kconfig.h + MODULE_INC += -I$(SYS_PATH) \ + -I$(TOOL_PATH)/../lib/gcc/$(TARGET_NAME)/$(GCC_VERSION)/include/ \ + -I$(SYS_PATH)/include \ + -I$(SYS_PATH)/source/include \ + -I$(SYS_PATH)/source/arch/arm64/mach-msm/include \ + -I$(SYS_PATH)/arch/arm64/mach-msm/include \ + -I$(SYS_PATH)/source/arch/arm64/include \ + -I$(SYS_PATH)/arch/arm64/include \ + -I$(SYS_PATH)/source/arch/arm64/include/asm \ + -I$(SYS_PATH)/arch/arm64/include/generated \ + -I$(SYS_PATH)/include/generated/uapi \ + -I$(SYS_PATH)/include/uapi \ + -I$(SYS_PATH)/arch/arm64/include/uapi \ + -I$(SYS_PATH)/source/include/uapi \ + -I$(SYS_PATH)/source/arch/arm64/include/asm/mach \ + -include $(KCONF_FILE) + else ifeq ($(ARCH), arm) + MODULE_INC += -I$(SYS_PATH) \ + -I$(TOOL_PATH)/../lib/gcc/$(TARGET_NAME)/$(GCC_VERSION)/include/ \ + -I$(TOOL_PATH)/../../lib/armv7a-vfp-neon-rdk-linux-gnueabi/gcc/arm-rdk-linux-gnueabi/4.8.4/include/ \ + -I$(SYS_PATH)/include \ + -I$(SYS_PATH)/source/include \ + -I$(SYS_PATH)/source/arch/arm/mach-msm/include \ + -I$(SYS_PATH)/arch/arm/mach-msm/include \ + -I$(SYS_PATH)/source/arch/arm/include \ + -I$(SYS_PATH)/arch/arm/include \ + -I$(SYS_PATH)/source/arch/arm/include/asm \ + -I$(SYS_PATH)/arch/arm/include/generated \ + -I$(SYS_PATH)/include/generated/uapi \ + -I$(SYS_PATH)/include/uapi \ + -I$(SYS_PATH)/arch/arm/include/uapi \ + -I$(SYS_PATH)/source/arch/arm/include/asm/mach \ + -include $(SYS_PATH)/include/linux/kconfig.h + endif + endif + + ifeq (3_14, $(OS_VER)) + MODULE_CFLAG += -DKVER34 + MODULE_CFLAG += -DKVER32 + MODULE_CFLAG += -DLNX26_22 + MODULE_INC += -I$(SYS_PATH) \ + -I$(TOOL_PATH)/../lib/gcc/$(TARGET_NAME)/$(GCC_VERSION)/include/ \ + -I$(TOOL_PATH)/../../lib/arm-poky-linux-gnueabi/gcc/arm-poky-linux-gnueabi/5.3.0/include/ \ + -I$(TOOL_PATH)/../../lib/armv7a-vfp-neon-rdk-linux-gnueabi/gcc/arm-rdk-linux-gnueabi/4.8.4/include/ \ + -I$(SYS_PATH)/include \ + -I$(SYS_PATH)/source/ \ + -I$(SYS_PATH)/source/include \ + -I$(SYS_PATH)/source/arch/arm/mach-msm/include \ + -I$(SYS_PATH)/arch/arm/mach-msm/include \ + -I$(SYS_PATH)/source/arch/arm/include \ + -I$(SYS_PATH)/arch/arm/include \ + -I$(SYS_PATH)/source/arch/arm/include/asm \ + -I$(SYS_PATH)/arch/arm/include/generated \ + -I$(SYS_PATH)/include/generated/uapi \ + -I$(SYS_PATH)/include/uapi \ + -I$(SYS_PATH)/source/include/uapi \ + -I$(SYS_PATH)/source/include/generated \ + -I$(SYS_PATH)/include/genearted \ + -I$(SYS_PATH)/arch/arm/include/uapi \ + -I$(SYS_PATH)/source/arch/arm/include/uapi \ + -I$(EXT_PATH) \ + -I$(SYS_PATH)/source/arch/arm/include/asm/mach + ifneq ($(wildcard $(SYS_PATH)/include/linux/kconfig.h),) + MODULE_INC += \ + -include $(SYS_PATH)/include/linux/kconfig.h + else + MODULE_INC += \ + -include $(SYS_PATH)/source/include/linux/kconfig.h + endif + + endif + + ifeq (3_4, $(OS_VER)) + MODULE_CFLAG += -DKVER34 + MODULE_CFLAG += -DKVER32 + MODULE_CFLAG += -DLNX26_22 + MODULE_CFLAG += -Werror + 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 \ + -I${KERN_SRC_PATH} \ + -I${KERN_SRC_PATH}/include \ + -I$(KERN_SRC_PATH)/arch/mips/include \ + -I$(KERN_SRC_PATH)/arch/mips/include/asm/mach-ar7240 \ + -I$(KERN_SRC_PATH)/arch/mips/include/asm/mach-generic \ + -I$(KERN_SRC_PATH)/arch/mips/include/asm/mach-ar7 \ + -I$(KERN_SRC_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 + + ifeq (TRUE, $(KERNEL_MODE)) + MODULE_CFLAG += -static + else + MODULE_CFLAG += -static -DUSER_MODE + endif +endif + +ifneq (TRUE, $(KERNEL_MODE)) + ifneq (SHELL, $(MODULE_TYPE)) + MODULE_CFLAG += -DUSER_MODE + endif +endif + +LOCAL_CFLAGS += $(MODULE_INC) $(MODULE_CFLAG) $(EXTRA_CFLAGS) diff --git a/feeds/ipq807x/qca-ssdk/src/make/target.mk b/feeds/ipq807x/qca-ssdk/src/make/target.mk new file mode 100755 index 000000000..72264f5cf --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/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) $(LOCAL_CFLAGS) -c $< -o $(DST_DIR)/$@ + +$(DEP_LIST) : %.d : %.c + $(CC) $(CFLAGS) $(LOCAL_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/src/make/tools.mk b/feeds/ipq807x/qca-ssdk/src/make/tools.mk new file mode 100755 index 000000000..6ed387298 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/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/src/src/adpt/Makefile b/feeds/ipq807x/qca-ssdk/src/src/adpt/Makefile new file mode 100755 index 000000000..de3c0c095 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/Makefile @@ -0,0 +1,12 @@ +LOC_DIR=/src/adpt +LIB=ADPT + +include $(PRJ_PATH)/make/config.mk + +SRC_LIST=adpt.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/src/src/adpt/adpt.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/adpt.c new file mode 100644 index 000000000..77d577496 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/adpt.c @@ -0,0 +1,658 @@ +/* + * 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 "adpt.h" +#include "ssdk_init.h" +#if defined(HPPE) +#include "adpt_hppe.h" +#endif +#if defined(IN_SFP) +#include "adpt_sfp.h" +#endif +#if defined(MP) +#include "adpt_mp.h" +#endif +#include "hsl_phy.h" + +adpt_api_t *g_adpt_api[SW_MAX_NR_DEV] = {NULL}; + +adpt_chip_ver_t g_chip_ver[SW_MAX_NR_DEV] = {0}; + +adpt_api_t *adpt_api_ptr_get(a_uint32_t dev_id) +{ + if (dev_id >= SW_MAX_NR_DEV) + return NULL; + + return g_adpt_api[dev_id]; +} +#if defined (SCOMPHY) +a_uint32_t adapt_scomphy_revision_get(a_uint32_t dev_id) +{ + return g_chip_ver[dev_id].chip_revision; +} +#endif +#if defined(HPPE) +a_uint32_t adpt_hppe_chip_revision_get(a_uint32_t dev_id) +{ + return g_chip_ver[dev_id].chip_revision; +} + +static sw_error_t adpt_hppe_module_func_register(a_uint32_t dev_id, a_uint32_t module) +{ + sw_error_t rv= SW_OK; + + switch (module) + { + case FAL_MODULE_ACL: +#if defined(IN_ACL) + rv = adpt_hppe_acl_init(dev_id); +#endif + break; + case FAL_MODULE_VSI: +#if defined(IN_VSI) + rv = adpt_hppe_vsi_init(dev_id); +#endif + break; + case FAL_MODULE_IP: +#if defined(IN_IP) + rv = adpt_hppe_ip_init(dev_id); +#endif + break; + case FAL_MODULE_FLOW: +#if defined(IN_FLOW) + rv = adpt_hppe_flow_init(dev_id); +#endif + break; + case FAL_MODULE_QM: +#if defined(IN_QM) + rv = adpt_hppe_qm_init(dev_id); +#endif + break; + case FAL_MODULE_QOS: +#if defined(IN_QOS) + rv = adpt_hppe_qos_init(dev_id); +#endif + break; + case FAL_MODULE_BM: +#if defined(IN_BM) + rv = adpt_hppe_bm_init(dev_id); +#endif + break; + case FAL_MODULE_SERVCODE: +#if defined(IN_SERVCODE) + rv = adpt_hppe_servcode_init( dev_id); +#endif + break; + case FAL_MODULE_RSS_HASH: +#if defined(IN_RSS_HASH) + rv = adpt_hppe_rss_hash_init( dev_id); +#endif + break; + case FAL_MODULE_PPPOE: +#if defined(IN_PPPOE) + rv = adpt_hppe_pppoe_init(dev_id); +#endif + break; + case FAL_MODULE_PORTCTRL: +#if defined(IN_PORTCONTROL) + rv = adpt_hppe_port_ctrl_init(dev_id); +#endif + break; + case FAL_MODULE_SHAPER: +#if defined(IN_SHAPER) + rv = adpt_hppe_shaper_init( dev_id); +#endif + break; + case FAL_MODULE_MIB: +#if defined(IN_MIB) + rv = adpt_hppe_mib_init(dev_id); +#endif + break; + case FAL_MODULE_MIRROR: +#if defined(IN_MIRROR) + rv = adpt_hppe_mirror_init( dev_id); +#endif + break; + case FAL_MODULE_FDB: +#if defined(IN_FDB) + rv = adpt_hppe_fdb_init(dev_id); +#endif + break; + case FAL_MODULE_STP: +#if defined(IN_STP) + rv = adpt_hppe_stp_init(dev_id); +#endif + break; + case FAL_MODULE_TRUNK: +#if defined(IN_TRUNK) + rv = adpt_hppe_trunk_init( dev_id); +#endif + break; + case FAL_MODULE_PORTVLAN: +#if defined(IN_PORTVLAN) + rv = adpt_hppe_portvlan_init(dev_id); +#endif + break; + case FAL_MODULE_CTRLPKT: +#if defined(IN_CTRLPKT) + rv = adpt_hppe_ctrlpkt_init( dev_id); +#endif + break; + case FAL_MODULE_SEC: +#if defined(IN_SEC) + rv = adpt_hppe_sec_init(dev_id); +#endif + break; + case FAL_MODULE_POLICER: +#if defined(IN_POLICER) + rv = adpt_hppe_policer_init(dev_id); +#endif + break; + case FAL_MODULE_MISC: +#if defined(IN_MISC) + rv = adpt_hppe_misc_init(dev_id); +#endif + break; + case FAL_MODULE_PTP: +#if defined(IN_PTP) + rv = adpt_hppe_ptp_init(dev_id); +#endif + break; + case FAL_MODULE_SFP: +#if defined(IN_SFP) + rv = adpt_sfp_init(dev_id); +#endif + break; + default: + break; + } + + return rv; +} +#endif + +sw_error_t adpt_module_func_ctrl_set(a_uint32_t dev_id, + a_uint32_t module, fal_func_ctrl_t *func_ctrl) +{ + sw_error_t rv= SW_OK; + + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return SW_FAIL; + + if(module == FAL_MODULE_ACL){ + p_adpt_api->adpt_acl_func_bitmap = func_ctrl->bitmap[0]; + } else if (module == FAL_MODULE_VSI) { + p_adpt_api->adpt_vsi_func_bitmap = func_ctrl->bitmap[0]; + }else if (module == FAL_MODULE_IP) { + p_adpt_api->adpt_ip_func_bitmap[0] = func_ctrl->bitmap[0]; + p_adpt_api->adpt_ip_func_bitmap[1] = func_ctrl->bitmap[1]; + } else if (module == FAL_MODULE_FLOW) { + p_adpt_api->adpt_flow_func_bitmap = func_ctrl->bitmap[0]; + } else if (module == FAL_MODULE_QM) { + p_adpt_api->adpt_qm_func_bitmap[0] = func_ctrl->bitmap[0]; + p_adpt_api->adpt_qm_func_bitmap[1] = func_ctrl->bitmap[1]; + } else if (module == FAL_MODULE_QOS) { + p_adpt_api->adpt_qos_func_bitmap = func_ctrl->bitmap[0]; + } else if (module == FAL_MODULE_BM) { + p_adpt_api->adpt_bm_func_bitmap = func_ctrl->bitmap[0]; + } else if (module == FAL_MODULE_SERVCODE) { + p_adpt_api->adpt_servcode_func_bitmap = func_ctrl->bitmap[0]; + } else if (module == FAL_MODULE_RSS_HASH) { + p_adpt_api->adpt_rss_hash_func_bitmap = func_ctrl->bitmap[0]; + } else if (module == FAL_MODULE_PPPOE) { + p_adpt_api->adpt_pppoe_func_bitmap = func_ctrl->bitmap[0]; + } else if (module == FAL_MODULE_PORTCTRL) { + p_adpt_api->adpt_port_ctrl_func_bitmap[0] = func_ctrl->bitmap[0]; + p_adpt_api->adpt_port_ctrl_func_bitmap[1] = func_ctrl->bitmap[1]; + p_adpt_api->adpt_port_ctrl_func_bitmap[2] = func_ctrl->bitmap[2]; + } else if (module == FAL_MODULE_SHAPER) { + p_adpt_api->adpt_shaper_func_bitmap = func_ctrl->bitmap[0]; + } else if(module == FAL_MODULE_MIB){ + p_adpt_api->adpt_mib_func_bitmap = func_ctrl->bitmap[0]; + } else if(module == FAL_MODULE_MIRROR){ + p_adpt_api->adpt_mirror_func_bitmap = func_ctrl->bitmap[0]; + } else if(module == FAL_MODULE_FDB){ + p_adpt_api->adpt_fdb_func_bitmap[0] = func_ctrl->bitmap[0]; + p_adpt_api->adpt_fdb_func_bitmap[1] = func_ctrl->bitmap[1]; + } else if(module == FAL_MODULE_STP){ + p_adpt_api->adpt_stp_func_bitmap = func_ctrl->bitmap[0]; + } else if(module == FAL_MODULE_TRUNK){ + p_adpt_api->adpt_trunk_func_bitmap = func_ctrl->bitmap[0]; + } else if(module == FAL_MODULE_PORTVLAN){ + p_adpt_api->adpt_portvlan_func_bitmap[0] = func_ctrl->bitmap[0]; + p_adpt_api->adpt_portvlan_func_bitmap[1] = func_ctrl->bitmap[1]; + } else if(module == FAL_MODULE_CTRLPKT){ + p_adpt_api->adpt_ctrlpkt_func_bitmap = func_ctrl->bitmap[0]; + } else if(module == FAL_MODULE_SEC){ + p_adpt_api->adpt_sec_func_bitmap = func_ctrl->bitmap[0]; + } else if(module == FAL_MODULE_POLICER){ + p_adpt_api->adpt_policer_func_bitmap = func_ctrl->bitmap[0]; + } + + + switch (g_chip_ver[dev_id].chip_type) + { + #if defined(HPPE) + case CHIP_HPPE: + rv = adpt_hppe_module_func_register(dev_id, module); + break; + #endif + default: + break; + } + + return rv; +} + +sw_error_t adpt_module_func_ctrl_get(a_uint32_t dev_id, + a_uint32_t module, fal_func_ctrl_t *func_ctrl) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return SW_FAIL; + + if(module == FAL_MODULE_ACL){ + func_ctrl->bitmap[0] = p_adpt_api->adpt_acl_func_bitmap; + } else if (module == FAL_MODULE_VSI) { + func_ctrl->bitmap[0] = p_adpt_api->adpt_vsi_func_bitmap; + } else if (module == FAL_MODULE_IP) { + func_ctrl->bitmap[0] = p_adpt_api->adpt_ip_func_bitmap[0]; + func_ctrl->bitmap[1] = p_adpt_api->adpt_ip_func_bitmap[1]; + } else if (module == FAL_MODULE_FLOW) { + func_ctrl->bitmap[0] = p_adpt_api->adpt_flow_func_bitmap; + } else if (module == FAL_MODULE_QM) { + func_ctrl->bitmap[0] = p_adpt_api->adpt_qm_func_bitmap[0]; + func_ctrl->bitmap[1] = p_adpt_api->adpt_qm_func_bitmap[1]; + } else if (module == FAL_MODULE_QOS) { + func_ctrl->bitmap[0] = p_adpt_api->adpt_qos_func_bitmap; + } else if (module == FAL_MODULE_BM) { + func_ctrl->bitmap[0] = p_adpt_api->adpt_bm_func_bitmap; + } else if (module == FAL_MODULE_SERVCODE) { + func_ctrl->bitmap[0] = p_adpt_api->adpt_servcode_func_bitmap; + } else if (module == FAL_MODULE_RSS_HASH) { + func_ctrl->bitmap[0] = p_adpt_api->adpt_rss_hash_func_bitmap; + } else if (module == FAL_MODULE_PPPOE) { + func_ctrl->bitmap[0] = p_adpt_api->adpt_pppoe_func_bitmap; + } else if (module == FAL_MODULE_PORTCTRL) { + func_ctrl->bitmap[0] = p_adpt_api->adpt_port_ctrl_func_bitmap[0]; + func_ctrl->bitmap[1] = p_adpt_api->adpt_port_ctrl_func_bitmap[1]; + func_ctrl->bitmap[2] = p_adpt_api->adpt_port_ctrl_func_bitmap[2]; + } else if (module == FAL_MODULE_SHAPER) { + func_ctrl->bitmap[0] = p_adpt_api->adpt_shaper_func_bitmap; + } else if(module == FAL_MODULE_MIB) { + func_ctrl->bitmap[0] = p_adpt_api->adpt_mib_func_bitmap; + } else if(module == FAL_MODULE_MIRROR) { + func_ctrl->bitmap[0] = p_adpt_api->adpt_mirror_func_bitmap; + } else if(module == FAL_MODULE_FDB) { + func_ctrl->bitmap[0] = p_adpt_api->adpt_fdb_func_bitmap[0]; + func_ctrl->bitmap[1] = p_adpt_api->adpt_fdb_func_bitmap[1]; + } else if(module == FAL_MODULE_STP) { + func_ctrl->bitmap[0] = p_adpt_api->adpt_stp_func_bitmap; + } else if(module == FAL_MODULE_TRUNK) { + func_ctrl->bitmap[0] = p_adpt_api->adpt_trunk_func_bitmap; + } else if(module == FAL_MODULE_PORTVLAN) { + func_ctrl->bitmap[0] = p_adpt_api->adpt_portvlan_func_bitmap[0]; + func_ctrl->bitmap[1] = p_adpt_api->adpt_portvlan_func_bitmap[1]; + } else if(module == FAL_MODULE_CTRLPKT) { + func_ctrl->bitmap[0] = p_adpt_api->adpt_ctrlpkt_func_bitmap; + } else if(module == FAL_MODULE_SEC) { + func_ctrl->bitmap[0] = p_adpt_api->adpt_sec_func_bitmap; + } else if(module == FAL_MODULE_POLICER) { + func_ctrl->bitmap[0] = p_adpt_api->adpt_policer_func_bitmap; + } + + return SW_OK; +} + +sw_error_t adpt_init(a_uint32_t dev_id, ssdk_init_cfg *cfg) +{ + sw_error_t rv= SW_OK; + + switch (cfg->chip_type) + { +#if defined(HPPE) + case CHIP_HPPE: + g_adpt_api[dev_id] = aos_mem_alloc(sizeof(adpt_api_t)); + if(g_adpt_api[dev_id] == NULL) + { + printk("%s, %d:malloc fail for adpt api\n", __FUNCTION__, __LINE__); + return SW_FAIL; + } + aos_mem_zero(g_adpt_api[dev_id], sizeof(adpt_api_t)); + + g_chip_ver[dev_id].chip_type = cfg->chip_type; + g_chip_ver[dev_id].chip_revision = cfg->chip_revision; + g_adpt_api[dev_id]->adpt_mirror_func_bitmap = 0xffffffff; + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_MIRROR); + SW_RTN_ON_ERROR(rv); + + g_adpt_api[dev_id]->adpt_fdb_func_bitmap[0] = 0xffffffff; + g_adpt_api[dev_id]->adpt_fdb_func_bitmap[1] = 0xffffffff; + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_FDB); + SW_RTN_ON_ERROR(rv); + + g_adpt_api[dev_id]->adpt_stp_func_bitmap = 0xffffffff; + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_STP); + SW_RTN_ON_ERROR(rv); + + g_adpt_api[dev_id]->adpt_trunk_func_bitmap = 0xffffffff; + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_TRUNK); + SW_RTN_ON_ERROR(rv); + + g_adpt_api[dev_id]->adpt_portvlan_func_bitmap[0] = 0xffffffff; + g_adpt_api[dev_id]->adpt_portvlan_func_bitmap[1] = 0xffffffff; + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_PORTVLAN); + SW_RTN_ON_ERROR(rv); + + g_adpt_api[dev_id]->adpt_ctrlpkt_func_bitmap = 0xffffffff; + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_CTRLPKT); + SW_RTN_ON_ERROR(rv); + + g_adpt_api[dev_id]->adpt_sec_func_bitmap = 0xffffffff; + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_SEC); + SW_RTN_ON_ERROR(rv); + + g_adpt_api[dev_id]->adpt_acl_func_bitmap = 0xffffffff; + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_ACL); + SW_RTN_ON_ERROR(rv); + + g_adpt_api[dev_id]->adpt_vsi_func_bitmap = 0xffffffff; + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_VSI); + SW_RTN_ON_ERROR(rv); + + g_adpt_api[dev_id]->adpt_ip_func_bitmap[0] = 0xffffffff; + g_adpt_api[dev_id]->adpt_ip_func_bitmap[1] = 0xffffffff; + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_IP); + SW_RTN_ON_ERROR(rv); + + g_adpt_api[dev_id]->adpt_flow_func_bitmap = 0xffffffff; + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_FLOW); + SW_RTN_ON_ERROR(rv); + + g_adpt_api[dev_id]->adpt_qm_func_bitmap[0] = 0xffffffff; + g_adpt_api[dev_id]->adpt_qm_func_bitmap[1] = 0xffffffff; + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_QM); + SW_RTN_ON_ERROR(rv); + + g_adpt_api[dev_id]->adpt_qos_func_bitmap = 0xffffffff; + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_QOS); + SW_RTN_ON_ERROR(rv); + + g_adpt_api[dev_id]->adpt_bm_func_bitmap = 0xffffffff; + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_BM); + SW_RTN_ON_ERROR(rv); + + g_adpt_api[dev_id]->adpt_servcode_func_bitmap = 0xffffffff; + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_SERVCODE); + SW_RTN_ON_ERROR(rv); + + g_adpt_api[dev_id]->adpt_rss_hash_func_bitmap = 0xffffffff; + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_RSS_HASH); + SW_RTN_ON_ERROR(rv); + + g_adpt_api[dev_id]->adpt_pppoe_func_bitmap = 0xffffffff; + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_PPPOE); + SW_RTN_ON_ERROR(rv); + + g_adpt_api[dev_id]->adpt_port_ctrl_func_bitmap[0] = 0xffffffff; + g_adpt_api[dev_id]->adpt_port_ctrl_func_bitmap[1] = 0xffffffff; + g_adpt_api[dev_id]->adpt_port_ctrl_func_bitmap[2] = 0xffffffff; + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_PORTCTRL); + SW_RTN_ON_ERROR(rv); + + g_adpt_api[dev_id]->adpt_shaper_func_bitmap = 0xffffffff; + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_SHAPER); + SW_RTN_ON_ERROR(rv); + + g_adpt_api[dev_id]->adpt_mib_func_bitmap = 0xffffffff; + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_MIB); + SW_RTN_ON_ERROR(rv); + + g_adpt_api[dev_id]->adpt_policer_func_bitmap = 0xffffffff; + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_POLICER); + SW_RTN_ON_ERROR(rv); + + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_MISC); + SW_RTN_ON_ERROR(rv); + + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_PTP); + SW_RTN_ON_ERROR(rv); + + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_SFP); + SW_RTN_ON_ERROR(rv); + + /* uniphy */ + rv = adpt_hppe_uniphy_init(dev_id); + SW_RTN_ON_ERROR(rv); + + break; +#endif +#if defined (SCOMPHY) + case CHIP_SCOMPHY: + g_chip_ver[dev_id].chip_type = cfg->chip_type; + g_chip_ver[dev_id].chip_revision = cfg->phy_id; +#if defined (MP) + if(cfg->phy_id == MP_GEPHY) + { + g_adpt_api[dev_id] = aos_mem_alloc(sizeof(adpt_api_t)); + if(g_adpt_api[dev_id] == NULL) + { + SSDK_ERROR("malloc fail for adpt api\n"); + return SW_FAIL; + } + aos_mem_zero(g_adpt_api[dev_id], sizeof(adpt_api_t)); + rv = adpt_mp_intr_init(dev_id); + SW_RTN_ON_ERROR(rv); +#if defined (IN_MIB) + rv = adpt_mp_mib_init(dev_id); + SW_RTN_ON_ERROR(rv); +#endif +#if defined (IN_PORTCONTROL) + rv = adpt_mp_portctrl_init(dev_id); + SW_RTN_ON_ERROR(rv); +#endif +#if defined (IN_UNIPHY) + rv = adpt_mp_uniphy_init(dev_id); + SW_RTN_ON_ERROR(rv); +#endif +#if defined (IN_LED) + rv = adpt_mp_led_init(dev_id); + SW_RTN_ON_ERROR(rv); +#endif + } +#endif + break; +#endif + default: + break; + } + return rv; +} + +sw_error_t adpt_module_func_init(a_uint32_t dev_id, ssdk_init_cfg *cfg) +{ + sw_error_t rv= SW_OK; + + switch (cfg->chip_type) + { + #if defined(HPPE) + case CHIP_HPPE: + g_adpt_api[dev_id]->adpt_mirror_func_bitmap = 0; +#if defined(IN_MIRROR) + adpt_hppe_mirror_func_bitmap_init(dev_id); + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_MIRROR); + SW_RTN_ON_ERROR(rv); +#endif + + g_adpt_api[dev_id]->adpt_fdb_func_bitmap[0] = 0; + g_adpt_api[dev_id]->adpt_fdb_func_bitmap[1] = 0; +#if defined(IN_FDB) + adpt_hppe_fdb_func_bitmap_init(dev_id); + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_FDB); + SW_RTN_ON_ERROR(rv); +#endif + + g_adpt_api[dev_id]->adpt_stp_func_bitmap = 0; +#if defined(IN_STP) + adpt_hppe_stp_func_bitmap_init(dev_id); + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_STP); + SW_RTN_ON_ERROR(rv); +#endif + + g_adpt_api[dev_id]->adpt_trunk_func_bitmap = 0; +#if defined(IN_TRUNK) + adpt_hppe_trunk_func_bitmap_init(dev_id); + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_TRUNK); + SW_RTN_ON_ERROR(rv); +#endif + + g_adpt_api[dev_id]->adpt_portvlan_func_bitmap[0] = 0; + g_adpt_api[dev_id]->adpt_portvlan_func_bitmap[1] = 0; +#if defined(IN_PORTVLAN) + adpt_hppe_portvlan_func_bitmap_init(dev_id); + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_PORTVLAN); + SW_RTN_ON_ERROR(rv); +#endif + + g_adpt_api[dev_id]->adpt_ctrlpkt_func_bitmap = 0; +#if defined(IN_CTRLPKT) + adpt_hppe_ctrlpkt_func_bitmap_init(dev_id); + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_CTRLPKT); + SW_RTN_ON_ERROR(rv); +#endif + + g_adpt_api[dev_id]->adpt_sec_func_bitmap = 0; +#if defined(IN_SEC) + adpt_hppe_sec_func_bitmap_init(dev_id); + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_SEC); + SW_RTN_ON_ERROR(rv); +#endif + + g_adpt_api[dev_id]->adpt_acl_func_bitmap = 0; +#if defined(IN_ACL) + adpt_hppe_acl_func_bitmap_init(dev_id); + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_ACL); + SW_RTN_ON_ERROR(rv); +#endif + + g_adpt_api[dev_id]->adpt_vsi_func_bitmap = 0; +#if defined(IN_VSI) + adpt_hppe_vsi_func_bitmap_init(dev_id); + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_VSI); + SW_RTN_ON_ERROR(rv); +#endif + + g_adpt_api[dev_id]->adpt_ip_func_bitmap[0] = 0; + g_adpt_api[dev_id]->adpt_ip_func_bitmap[1] = 0; +#if defined(IN_IP) + adpt_hppe_ip_func_bitmap_init(dev_id); + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_IP); + SW_RTN_ON_ERROR(rv); +#endif + + g_adpt_api[dev_id]->adpt_flow_func_bitmap = 0; +#if defined(IN_FLOW) + adpt_hppe_flow_func_bitmap_init(dev_id); + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_FLOW); + SW_RTN_ON_ERROR(rv); +#endif + + g_adpt_api[dev_id]->adpt_qm_func_bitmap[0] = 0; + g_adpt_api[dev_id]->adpt_qm_func_bitmap[1] = 0; +#if defined(IN_QM) + adpt_hppe_qm_func_bitmap_init(dev_id); + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_QM); + SW_RTN_ON_ERROR(rv); +#endif + + g_adpt_api[dev_id]->adpt_qos_func_bitmap = 0; +#if defined(IN_QOS) + adpt_hppe_qos_func_bitmap_init(dev_id); + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_QOS); + SW_RTN_ON_ERROR(rv); +#endif + + g_adpt_api[dev_id]->adpt_bm_func_bitmap = 0; +#if defined(IN_BM) + adpt_hppe_bm_func_bitmap_init(dev_id); + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_BM); + SW_RTN_ON_ERROR(rv); +#endif + + g_adpt_api[dev_id]->adpt_servcode_func_bitmap = 0; +#if defined(IN_SERVCODE) + adpt_hppe_servcode_func_bitmap_init(dev_id); + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_SERVCODE); + SW_RTN_ON_ERROR(rv); +#endif + + g_adpt_api[dev_id]->adpt_rss_hash_func_bitmap = 0; +#if defined(IN_RSS_HASH) + adpt_hppe_rss_hash_func_bitmap_init(dev_id); + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_RSS_HASH); + SW_RTN_ON_ERROR(rv); +#endif + + g_adpt_api[dev_id]->adpt_pppoe_func_bitmap = 0; +#if defined(IN_PPPOE) + adpt_hppe_pppoe_func_bitmap_init(dev_id); + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_PPPOE); + SW_RTN_ON_ERROR(rv); +#endif + + g_adpt_api[dev_id]->adpt_port_ctrl_func_bitmap[0] = 0; + g_adpt_api[dev_id]->adpt_port_ctrl_func_bitmap[1] = 0; + g_adpt_api[dev_id]->adpt_port_ctrl_func_bitmap[2] = 0; +#if defined(IN_PORTCONTROL) + adpt_hppe_port_ctrl_func_bitmap_init(dev_id); + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_PORTCTRL); + SW_RTN_ON_ERROR(rv); +#endif + + g_adpt_api[dev_id]->adpt_shaper_func_bitmap = 0; +#if defined(IN_SHAPER) + adpt_hppe_shaper_func_bitmap_init(dev_id); + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_SHAPER); + SW_RTN_ON_ERROR(rv); +#endif + + g_adpt_api[dev_id]->adpt_mib_func_bitmap = 0; +#if defined(IN_MIB) + adpt_hppe_mib_func_bitmap_init(dev_id); + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_MIB); + SW_RTN_ON_ERROR(rv); +#endif + + g_adpt_api[dev_id]->adpt_policer_func_bitmap = 0; +#if defined(IN_POLICER) + adpt_hppe_policer_func_bitmap_init(dev_id); + rv = adpt_hppe_module_func_register(dev_id, FAL_MODULE_POLICER); + SW_RTN_ON_ERROR(rv); +#endif + + break; + #endif + default: + break; + } + return rv; +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/cppe/Makefile b/feeds/ipq807x/qca-ssdk/src/src/adpt/cppe/Makefile new file mode 100755 index 000000000..990c62937 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/cppe/Makefile @@ -0,0 +1,48 @@ +LOC_DIR=src/adpt/cppe +LIB=ADPT + +include $(PRJ_PATH)/make/config.mk + +SRC_LIST= + +ifeq (TRUE, $(IN_PORTCONTROL)) + SRC_LIST += adpt_cppe_portctrl.c +endif + +ifeq (TRUE, $(IN_QM)) + SRC_LIST += adpt_cppe_qm.c +endif + +ifeq (TRUE, $(IN_QOS)) + SRC_LIST += adpt_cppe_qos.c +endif + +ifeq (TRUE, $(IN_UNIPHY)) + SRC_LIST += adpt_cppe_uniphy.c +endif + +ifeq (TRUE, $(IN_MISC)) +ifneq (TRUE, $(IN_MISC_MINI)) + SRC_LIST += adpt_cppe_misc.c +endif +endif + +ifeq (TRUE, $(IN_FLOW)) +ifneq (TRUE, $(IN_FLOW_MINI)) + SRC_LIST += adpt_cppe_flow.c +endif +endif + +ifeq (TRUE, $(IN_MIB)) + SRC_LIST += adpt_cppe_mib.c +endif + +ifeq (, $(findstring CPPE, $(SUPPORT_CHIP))) + SRC_LIST= +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/src/src/adpt/cppe/adpt_cppe_flow.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/cppe/adpt_cppe_flow.c new file mode 100755 index 000000000..ea3877d34 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/cppe/adpt_cppe_flow.c @@ -0,0 +1,77 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hppe_fdb_reg.h" +#include "hppe_fdb.h" +#include "hppe_ip_reg.h" +#include "hppe_ip.h" +#include "adpt.h" + +sw_error_t +adpt_cppe_flow_copy_escape_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv = SW_OK; + union l2_global_conf_u l2_global_conf; + union l3_route_ctrl_ext_u l3_route_ctrl_ext; + + ADPT_DEV_ID_CHECK(dev_id); + + memset(&l2_global_conf, 0, sizeof(l2_global_conf)); + rv = hppe_l2_global_conf_get(dev_id, &l2_global_conf); + SW_RTN_ON_ERROR(rv); + l2_global_conf.bf.l2_flow_copy_escape = enable; + rv = hppe_l2_global_conf_set(dev_id, &l2_global_conf); + SW_RTN_ON_ERROR(rv); + + memset(&l3_route_ctrl_ext, 0, sizeof(l3_route_ctrl_ext)); + rv = hppe_l3_route_ctrl_ext_get(dev_id, &l3_route_ctrl_ext); + SW_RTN_ON_ERROR(rv); + l3_route_ctrl_ext.bf.l3_flow_copy_escape = enable; + rv = hppe_l3_route_ctrl_ext_set(dev_id, &l3_route_ctrl_ext); + + return rv; +} + +sw_error_t +adpt_cppe_flow_copy_escape_get(a_uint32_t dev_id, a_bool_t *enable) +{ + + sw_error_t rv = SW_OK; + union l2_global_conf_u l2_global_conf; + union l3_route_ctrl_ext_u l3_route_ctrl_ext; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + + memset(&l2_global_conf, 0, sizeof(l2_global_conf)); + rv = hppe_l2_global_conf_get(dev_id, &l2_global_conf); + SW_RTN_ON_ERROR(rv); + + memset(&l3_route_ctrl_ext, 0, sizeof(l3_route_ctrl_ext)); + rv = hppe_l3_route_ctrl_ext_get(dev_id, &l3_route_ctrl_ext); + SW_RTN_ON_ERROR(rv); + + *enable = l2_global_conf.bf.l2_flow_copy_escape & l3_route_ctrl_ext.bf.l3_flow_copy_escape; + return rv; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/cppe/adpt_cppe_mib.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/cppe/adpt_cppe_mib.c new file mode 100755 index 000000000..60c4f622d --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/cppe/adpt_cppe_mib.c @@ -0,0 +1,181 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "adpt.h" +#include "cppe_loopback_reg.h" +#include "cppe_loopback.h" +#include "hppe_init.h" + +sw_error_t +adpt_cppe_lpbk_mib_cpukeep_get(a_uint32_t dev_id, a_uint32_t port_id, + a_bool_t *enable) +{ + sw_error_t rv = SW_OK; + union lpbk_mib_ctrl_u reg_value; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + + rv = cppe_lpbk_mib_ctrl_get(dev_id, port_id, ®_value); + SW_RTN_ON_ERROR(rv); + + if (reg_value.bf.mib_rd_clr == A_TRUE) + { + *enable = A_FALSE; + } + else + { + *enable = A_TRUE; + } + + return SW_OK; +} + +sw_error_t +adpt_cppe_lpbk_mib_cpukeep_set(a_uint32_t dev_id, a_uint32_t port_id, + a_bool_t enable) +{ + union lpbk_mib_ctrl_u reg_value; + sw_error_t rv = SW_OK; + + ADPT_DEV_ID_CHECK(dev_id); + port_id = HPPE_TO_GMAC_PORT_ID(port_id); + rv = cppe_lpbk_mib_ctrl_get(dev_id, port_id, ®_value); + SW_RTN_ON_ERROR(rv); + if(!enable) + { + reg_value.bf.mib_rd_clr = A_TRUE; + } + else + { + reg_value.bf.mib_rd_clr = A_FALSE; + } + rv = cppe_lpbk_mib_ctrl_set(dev_id, port_id, ®_value); + + return rv; +} + +sw_error_t +adpt_hppe_lpbk_mib_status_get(a_uint32_t dev_id, a_uint32_t port_id, + a_bool_t *enable) +{ + sw_error_t rv = SW_OK; + union lpbk_mib_ctrl_u reg_value; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + + rv = cppe_lpbk_mib_ctrl_get(dev_id, port_id, ®_value); + SW_RTN_ON_ERROR(rv); + *enable = reg_value.bf.mib_en; + + return rv; +} + +sw_error_t +adpt_cppe_lpbk_mib_status_set(a_uint32_t dev_id, a_uint32_t port_id, + a_bool_t enable) +{ + union lpbk_mib_ctrl_u reg_value; + sw_error_t rv = SW_OK; + + ADPT_DEV_ID_CHECK(dev_id); + + port_id = HPPE_TO_GMAC_PORT_ID(port_id); + rv = cppe_lpbk_mib_ctrl_get(dev_id, port_id, ®_value); + SW_RTN_ON_ERROR(rv); + reg_value.bf.mib_en = enable; + rv = cppe_lpbk_mib_ctrl_set(dev_id, port_id, ®_value); + + return rv; +} + +sw_error_t +adpt_cppe_lpbk_mib_flush_counters(a_uint32_t dev_id, fal_port_t port_id) +{ + union lpbk_mib_ctrl_u reg_value; + sw_error_t rv = SW_OK; + + ADPT_DEV_ID_CHECK(dev_id); + port_id = HPPE_TO_GMAC_PORT_ID(port_id); + rv = cppe_lpbk_mib_ctrl_get(dev_id, port_id, ®_value); + SW_RTN_ON_ERROR(rv); + reg_value.bf.mib_reset = A_TRUE; + rv = cppe_lpbk_mib_ctrl_set(dev_id, port_id, ®_value); + SW_RTN_ON_ERROR(rv); + reg_value.bf.mib_reset = A_FALSE; + rv = cppe_lpbk_mib_ctrl_set(dev_id, port_id, ®_value); + + return rv; +} + +sw_error_t +adpt_cppe_lpbk_get_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info ) +{ + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(mib_info); + memset(mib_info, 0, sizeof(*mib_info)); + + port_id = HPPE_TO_GMAC_PORT_ID(port_id); + cppe_lpbk_mib_uni_get(dev_id, (a_uint32_t)port_id, + (union lpbkuni_u *)&mib_info->RxUniCast); + cppe_lpbk_mib_multi_get(dev_id, (a_uint32_t)port_id, + (union lpbkmulti_u *)&mib_info->RxMulti); + cppe_lpbk_mib_broad_get(dev_id, (a_uint32_t)port_id, + (union lpbkbroad_u *)&mib_info->RxBroad); + cppe_lpbk_mib_pkt64_get(dev_id, (a_uint32_t)port_id, + (union lpbkpkt64_u *)&mib_info->Rx64Byte); + cppe_lpbk_mib_pkt65to127_get(dev_id, (a_uint32_t)port_id, + (union lpbkpkt65to127_u *)&mib_info->Rx128Byte); + cppe_lpbk_mib_pkt128to255_get(dev_id, (a_uint32_t)port_id, + (union lpbkpkt128to255_u *)&mib_info->Rx256Byte); + cppe_lpbk_mib_pkt256to511_get(dev_id, (a_uint32_t)port_id, + (union lpbkpkt256to511_u *)&mib_info->Rx512Byte); + cppe_lpbk_mib_pkt512to1023_get(dev_id, (a_uint32_t)port_id, + (union lpbkpkt512to1023_u *)&mib_info->Rx1024Byte); + cppe_lpbk_mib_pkt1024to1518_get(dev_id, (a_uint32_t)port_id, + (union lpbkpkt1024to1518_u *)&mib_info->Rx1518Byte); + cppe_lpbk_mib_pkt1519tox_get(dev_id, (a_uint32_t)port_id, + (union lpbkpkt1519tox_u *)&mib_info->RxMaxByte); + cppe_lpbk_mib_toolong_get(dev_id, (a_uint32_t)port_id, + (union lpbkpkttoolong_u *)&mib_info->RxTooLong); + cppe_lpbk_mib_byte_l_get(dev_id, (a_uint32_t)port_id, + (union lpbkbyte_l_u *)&mib_info->RxGoodByte_lo); + cppe_lpbk_mib_byte_h_get(dev_id, (a_uint32_t)port_id, + (union lpbkbyte_h_u *)&mib_info->RxGoodByte_hi); + cppe_lpbk_mib_drop_get(dev_id, (a_uint32_t)port_id, + (union lpbkdropcounter_u *)&mib_info->Filtered); + cppe_lpbk_mib_tooshort_get(dev_id, (a_uint32_t)port_id, + (union lpbkpkttooshort_u *)&mib_info->RxRunt); + cppe_lpbk_mib_pkt14to63_get(dev_id, (a_uint32_t)port_id, + (union lpbkpkt14to63_u *)&mib_info->Rx14To63); + cppe_lpbk_mib_toolongbyte_l_get(dev_id, (a_uint32_t)port_id, + (union lpbktoolongbyte_l_u *)&mib_info->RxTooLongByte_lo); + cppe_lpbk_mib_toolongbyte_h_get(dev_id, (a_uint32_t)port_id, + (union lpbktoolongbyte_h_u *)&mib_info->RxTooLongByte_hi); + cppe_lpbk_mib_tooshortbyte_l_get(dev_id, (a_uint32_t)port_id, + (union lpbktooshortbyte_l_u *)&mib_info->RxRuntByte_lo); + cppe_lpbk_mib_tooshortbyte_h_get(dev_id, (a_uint32_t)port_id, + (union lpbktooshortbyte_h_u *)&mib_info->RxRuntByte_hi); + + return SW_OK; +} +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/cppe/adpt_cppe_misc.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/cppe/adpt_cppe_misc.c new file mode 100755 index 000000000..f7c257607 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/cppe/adpt_cppe_misc.c @@ -0,0 +1,121 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hppe_portctrl_reg.h" +#include "hppe_portctrl.h" +#include "hppe_portvlan_reg.h" +#include "hppe_portvlan.h" +#include "cppe_portctrl_reg.h" +#include "cppe_portctrl.h" +#include "adpt.h" + +sw_error_t +adpt_cppe_debug_port_counter_enable(a_uint32_t dev_id, fal_port_t port_id, + fal_counter_en_t *cnt_en) +{ + union cppe_mru_mtu_ctrl_tbl_u mru_mtu_ctrl_tbl; + union mc_mtu_ctrl_tbl_u mc_mtu_ctrl_tbl; + union port_eg_vlan_u port_eg_vlan; + sw_error_t rv = SW_OK; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cnt_en); + + port_id = FAL_PORT_ID_VALUE(port_id); + + if (port_id < SSDK_MAX_PORT_NUM) { + rv = cppe_mru_mtu_ctrl_tbl_get(dev_id, port_id, &mru_mtu_ctrl_tbl); + SW_RTN_ON_ERROR(rv); + rv = hppe_mc_mtu_ctrl_tbl_get(dev_id, port_id, &mc_mtu_ctrl_tbl); + SW_RTN_ON_ERROR(rv); + rv = hppe_port_eg_vlan_get(dev_id, port_id, &port_eg_vlan); + SW_RTN_ON_ERROR(rv); + + mru_mtu_ctrl_tbl.bf.rx_cnt_en = cnt_en->rx_counter_en; + mru_mtu_ctrl_tbl.bf.tx_cnt_en = cnt_en->vp_uni_tx_counter_en; + mc_mtu_ctrl_tbl.bf.tx_cnt_en = cnt_en->port_mc_tx_counter_en; + port_eg_vlan.bf.tx_counting_en = cnt_en->port_tx_counter_en; + + rv = cppe_mru_mtu_ctrl_tbl_set(dev_id, port_id, &mru_mtu_ctrl_tbl); + SW_RTN_ON_ERROR(rv); + rv = hppe_mc_mtu_ctrl_tbl_set(dev_id, port_id, &mc_mtu_ctrl_tbl); + SW_RTN_ON_ERROR(rv); + rv = hppe_port_eg_vlan_set(dev_id, port_id, &port_eg_vlan); + SW_RTN_ON_ERROR(rv); + } else if (port_id >= SSDK_MAX_PORT_NUM && + port_id < SSDK_MAX_VIRTUAL_PORT_NUM) { + rv = cppe_mru_mtu_ctrl_tbl_get(dev_id, port_id, &mru_mtu_ctrl_tbl); + SW_RTN_ON_ERROR(rv); + + mru_mtu_ctrl_tbl.bf.rx_cnt_en = cnt_en->rx_counter_en; + mru_mtu_ctrl_tbl.bf.tx_cnt_en = cnt_en->vp_uni_tx_counter_en; + + rv = cppe_mru_mtu_ctrl_tbl_set(dev_id, port_id, &mru_mtu_ctrl_tbl); + SW_RTN_ON_ERROR(rv); + } else { + return SW_OUT_OF_RANGE; + } + + return rv; +} + +sw_error_t +adpt_cppe_debug_port_counter_status_get(a_uint32_t dev_id, fal_port_t port_id, + fal_counter_en_t *cnt_en) +{ + union cppe_mru_mtu_ctrl_tbl_u mru_mtu_ctrl_tbl; + union mc_mtu_ctrl_tbl_u mc_mtu_ctrl_tbl; + union port_eg_vlan_u port_eg_vlan; + sw_error_t rv = SW_OK; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cnt_en); + + port_id = FAL_PORT_ID_VALUE(port_id); + + if (port_id < SSDK_MAX_PORT_NUM) { + rv = cppe_mru_mtu_ctrl_tbl_get(dev_id, port_id, &mru_mtu_ctrl_tbl); + SW_RTN_ON_ERROR(rv); + rv = hppe_mc_mtu_ctrl_tbl_get(dev_id, port_id, &mc_mtu_ctrl_tbl); + SW_RTN_ON_ERROR(rv); + rv = hppe_port_eg_vlan_get(dev_id, port_id, &port_eg_vlan); + SW_RTN_ON_ERROR(rv); + + cnt_en->rx_counter_en = mru_mtu_ctrl_tbl.bf.rx_cnt_en; + cnt_en->vp_uni_tx_counter_en = mru_mtu_ctrl_tbl.bf.tx_cnt_en; + cnt_en->port_mc_tx_counter_en = mc_mtu_ctrl_tbl.bf.tx_cnt_en; + cnt_en->port_tx_counter_en = port_eg_vlan.bf.tx_counting_en; + } else if (port_id >= SSDK_MAX_PORT_NUM && + port_id < SSDK_MAX_VIRTUAL_PORT_NUM) { + rv = cppe_mru_mtu_ctrl_tbl_get(dev_id, port_id, &mru_mtu_ctrl_tbl); + SW_RTN_ON_ERROR(rv); + + cnt_en->rx_counter_en = mru_mtu_ctrl_tbl.bf.rx_cnt_en; + cnt_en->vp_uni_tx_counter_en = mru_mtu_ctrl_tbl.bf.tx_cnt_en; + } else { + return SW_OUT_OF_RANGE; + } + + return rv; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/cppe/adpt_cppe_portctrl.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/cppe/adpt_cppe_portctrl.c new file mode 100755 index 000000000..aad289da7 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/cppe/adpt_cppe_portctrl.c @@ -0,0 +1,541 @@ +/* + * 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. + */ + + +/** + * @defgroup + * @{ + */ +#include "sw.h" +#include "hppe_global_reg.h" +#include "hppe_global.h" +#include "hppe_portctrl_reg.h" +#include "hppe_portctrl.h" +#include "cppe_portctrl_reg.h" +#include "cppe_portctrl.h" +#include "hppe_fdb_reg.h" +#include "hppe_fdb.h" +#include "cppe_loopback_reg.h" +#include "cppe_loopback.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_phy.h" +#include "hsl_port_prop.h" +#include "hppe_init.h" +#include "adpt.h" +#include "adpt_hppe.h" +#include "adpt_cppe_portctrl.h" + +sw_error_t +_adpt_cppe_port_mux_mac_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t port_type) +{ + sw_error_t rv = SW_OK; + a_uint32_t mode0, mode1; + union cppe_port_mux_ctrl_u cppe_port_mux_ctrl; + + ADPT_DEV_ID_CHECK(dev_id); + memset(&cppe_port_mux_ctrl, 0, sizeof(cppe_port_mux_ctrl)); + + rv = cppe_port_mux_ctrl_get(dev_id, &cppe_port_mux_ctrl); + SW_RTN_ON_ERROR (rv); + + mode0 = ssdk_dt_global_get_mac_mode(dev_id, SSDK_UNIPHY_INSTANCE0); + mode1 = ssdk_dt_global_get_mac_mode(dev_id, SSDK_UNIPHY_INSTANCE1); + + switch (port_id) { + case SSDK_PHYSICAL_PORT3: + case SSDK_PHYSICAL_PORT4: + if (mode0 == PORT_WRAPPER_PSGMII) { + if (hsl_port_phyid_get(dev_id, + SSDK_PHYSICAL_PORT3) == MALIBU2PORT_PHY) { + cppe_port_mux_ctrl.bf.port3_pcs_sel = + CPPE_PORT3_PCS_SEL_PCS0_CHANNEL4; + cppe_port_mux_ctrl.bf.port4_pcs_sel = + CPPE_PORT4_PCS_SEL_PCS0_CHANNEL3; + } else { + cppe_port_mux_ctrl.bf.port3_pcs_sel = + CPPE_PORT3_PCS_SEL_PCS0_CHANNEL2; + cppe_port_mux_ctrl.bf.port4_pcs_sel = + CPPE_PORT4_PCS_SEL_PCS0_CHANNEL3; + } + } else if (mode0 == PORT_WRAPPER_QSGMII) { + cppe_port_mux_ctrl.bf.port3_pcs_sel = + CPPE_PORT3_PCS_SEL_PCS0_CHANNEL2; + cppe_port_mux_ctrl.bf.port4_pcs_sel = + CPPE_PORT4_PCS_SEL_PCS0_CHANNEL3; + } else if (mode0 == PORT_WRAPPER_SGMII_PLUS) { + cppe_port_mux_ctrl.bf.port3_pcs_sel = + CPPE_PORT3_PCS_SEL_PCS0_CHANNEL2; + cppe_port_mux_ctrl.bf.port4_pcs_sel = + CPPE_PORT4_PCS_SEL_PCS0_SGMIIPLUS; + } else if (mode0 ==PORT_WRAPPER_SGMII_CHANNEL0) { + if (hsl_port_prop_check(dev_id, SSDK_PHYSICAL_PORT4, + HSL_PP_EXCL_CPU) == A_TRUE) { + cppe_port_mux_ctrl.bf.port3_pcs_sel = + CPPE_PORT3_PCS_SEL_PCS0_CHANNEL2; + cppe_port_mux_ctrl.bf.port4_pcs_sel = + CPPE_PORT4_PCS_SEL_PCS0_SGMIIPLUS; + } else { + cppe_port_mux_ctrl.bf.port3_pcs_sel = + CPPE_PORT3_PCS_SEL_PCS0_CHANNEL2; + cppe_port_mux_ctrl.bf.port4_pcs_sel = + CPPE_PORT4_PCS_SEL_PCS0_CHANNEL3; + } + } else if ((mode0 == PORT_WRAPPER_SGMII_CHANNEL4) || + (mode0 == PORT_WRAPPER_SGMII0_RGMII4)) { + cppe_port_mux_ctrl.bf.port3_pcs_sel = + CPPE_PORT3_PCS_SEL_PCS0_CHANNEL2; + cppe_port_mux_ctrl.bf.port4_pcs_sel = + CPPE_PORT4_PCS_SEL_PCS0_CHANNEL3; + cppe_port_mux_ctrl.bf.port5_pcs_sel = + CPPE_PORT5_PCS_SEL_PCS0_CHANNEL4; + cppe_port_mux_ctrl.bf.port5_gmac_sel = + CPPE_PORT5_GMAC_SEL_GMAC; + } else if ((mode0 == PORT_WRAPPER_SGMII_CHANNEL1) || + (mode0 == PORT_WRAPPER_SGMII1_RGMII4)) { + cppe_port_mux_ctrl.bf.port3_pcs_sel = + CPPE_PORT3_PCS_SEL_PCS0_CHANNEL2; + cppe_port_mux_ctrl.bf.port4_pcs_sel = + CPPE_PORT4_PCS_SEL_PCS0_CHANNEL3; + } + break; + case SSDK_PHYSICAL_PORT5: + if (mode0 == PORT_WRAPPER_PSGMII) { + if (hsl_port_phyid_get(dev_id, + SSDK_PHYSICAL_PORT3) != MALIBU2PORT_PHY) { + cppe_port_mux_ctrl.bf.port5_pcs_sel = + CPPE_PORT5_PCS_SEL_PCS0_CHANNEL4; + cppe_port_mux_ctrl.bf.port5_gmac_sel = + CPPE_PORT5_GMAC_SEL_GMAC; + } + } + if ((mode1 == PORT_WRAPPER_SGMII_PLUS) || + (mode1 == PORT_WRAPPER_SGMII0_RGMII4) || + (mode1 == PORT_WRAPPER_SGMII_CHANNEL0) || + (mode1 == PORT_WRAPPER_SGMII_FIBER)) { + cppe_port_mux_ctrl.bf.port5_pcs_sel = + CPPE_PORT5_PCS_SEL_PCS1_CHANNEL0; + cppe_port_mux_ctrl.bf.port5_gmac_sel = + CPPE_PORT5_GMAC_SEL_GMAC; + } else if ((mode1 == PORT_WRAPPER_USXGMII) || + (mode1 == PORT_WRAPPER_10GBASE_R)) { + cppe_port_mux_ctrl.bf.port5_pcs_sel = + CPPE_PORT5_PCS_SEL_PCS1_CHANNEL0; + cppe_port_mux_ctrl.bf.port5_gmac_sel = + CPPE_PORT5_GMAC_SEL_XGMAC; + } + break; + default: + break; + } + + rv = cppe_port_mux_ctrl_set(dev_id, &cppe_port_mux_ctrl); + + return rv; +} + +sw_error_t +adpt_cppe_port_mru_set(a_uint32_t dev_id, fal_port_t port_id, + fal_mru_ctrl_t *ctrl) +{ + sw_error_t rv = SW_OK; + union cppe_mru_mtu_ctrl_tbl_u mru_mtu_ctrl_tbl; + + memset(&mru_mtu_ctrl_tbl, 0, sizeof(mru_mtu_ctrl_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(ctrl); + + rv = cppe_mru_mtu_ctrl_tbl_get(dev_id, port_id, &mru_mtu_ctrl_tbl); + SW_RTN_ON_ERROR (rv); + + mru_mtu_ctrl_tbl.bf.mru = ctrl->mru_size; + mru_mtu_ctrl_tbl.bf.mru_cmd = (a_uint32_t)ctrl->action; + rv = cppe_mru_mtu_ctrl_tbl_set(dev_id, port_id, &mru_mtu_ctrl_tbl); + + return rv; +} + +sw_error_t +adpt_cppe_port_mru_get(a_uint32_t dev_id, fal_port_t port_id, + fal_mru_ctrl_t *ctrl) +{ + sw_error_t rv = SW_OK; + union cppe_mru_mtu_ctrl_tbl_u mru_mtu_ctrl_tbl; + + memset(&mru_mtu_ctrl_tbl, 0, sizeof(mru_mtu_ctrl_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(ctrl); + + rv = cppe_mru_mtu_ctrl_tbl_get(dev_id, port_id, &mru_mtu_ctrl_tbl); + SW_RTN_ON_ERROR (rv); + + ctrl->mru_size = mru_mtu_ctrl_tbl.bf.mru; + ctrl->action = (fal_fwd_cmd_t)mru_mtu_ctrl_tbl.bf.mru_cmd; + + return SW_OK; +} + +#ifndef IN_PORTCONTROL_MINI +sw_error_t +adpt_cppe_port_mtu_set(a_uint32_t dev_id, fal_port_t port_id, + fal_mtu_ctrl_t *ctrl) +{ + sw_error_t rv = SW_OK; + union cppe_mru_mtu_ctrl_tbl_u mru_mtu_ctrl_tbl; + + memset(&mru_mtu_ctrl_tbl, 0, sizeof(mru_mtu_ctrl_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(ctrl); + + rv = cppe_mru_mtu_ctrl_tbl_get(dev_id, port_id, &mru_mtu_ctrl_tbl); + SW_RTN_ON_ERROR (rv); + + mru_mtu_ctrl_tbl.bf.mtu = ctrl->mtu_size; + mru_mtu_ctrl_tbl.bf.mtu_cmd = (a_uint32_t)ctrl->action; + rv = cppe_mru_mtu_ctrl_tbl_set(dev_id, port_id, &mru_mtu_ctrl_tbl); + SW_RTN_ON_ERROR (rv); + + if ((port_id >= SSDK_PHYSICAL_PORT0) && (port_id <= SSDK_PHYSICAL_PORT7)) + { + rv = hppe_mc_mtu_ctrl_tbl_mtu_set(dev_id, port_id, ctrl->mtu_size); + SW_RTN_ON_ERROR (rv); + rv = hppe_mc_mtu_ctrl_tbl_mtu_cmd_set(dev_id, port_id, (a_uint32_t)ctrl->action); + SW_RTN_ON_ERROR (rv); + } + + return rv; +} + +sw_error_t +adpt_cppe_port_mtu_get(a_uint32_t dev_id, fal_port_t port_id, + fal_mtu_ctrl_t *ctrl) +{ + sw_error_t rv = SW_OK; + union cppe_mru_mtu_ctrl_tbl_u mru_mtu_ctrl_tbl; + + memset(&mru_mtu_ctrl_tbl, 0, sizeof(mru_mtu_ctrl_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(ctrl); + + rv = cppe_mru_mtu_ctrl_tbl_get(dev_id, port_id, &mru_mtu_ctrl_tbl); + SW_RTN_ON_ERROR (rv); + + ctrl->mtu_size = mru_mtu_ctrl_tbl.bf.mtu; + ctrl->action = (fal_fwd_cmd_t)mru_mtu_ctrl_tbl.bf.mtu_cmd; + + return SW_OK; +} +#endif + +sw_error_t +adpt_cppe_port_to_channel_convert(a_uint32_t dev_id, a_uint32_t port_id, + a_uint32_t *channel_id) +{ + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(channel_id); + + *channel_id = port_id; + + if (port_id == SSDK_PHYSICAL_PORT3) { + if (hsl_port_phyid_get(dev_id, + port_id) == MALIBU2PORT_PHY) { + *channel_id = SSDK_PHYSICAL_PORT5; + } + } + return SW_OK; +} + +#ifndef IN_PORTCONTROL_MINI +sw_error_t +adpt_cppe_port_source_filter_set(a_uint32_t dev_id, + fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv = SW_OK; + fal_src_filter_config_t src_filter_config; + + ADPT_DEV_ID_CHECK(dev_id); + + rv = adpt_cppe_port_source_filter_config_get(dev_id, + port_id, &src_filter_config); + SW_RTN_ON_ERROR(rv); + src_filter_config.src_filter_enable = enable; + rv = adpt_cppe_port_source_filter_config_set(dev_id, port_id, + &src_filter_config); + + return rv; +} + +sw_error_t +adpt_cppe_port_source_filter_get(a_uint32_t dev_id, + fal_port_t port_id, a_bool_t *enable) +{ + sw_error_t rv = SW_OK; + fal_src_filter_config_t src_filter_config; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + + rv = adpt_cppe_port_source_filter_config_get(dev_id, port_id, + &src_filter_config); + SW_RTN_ON_ERROR(rv); + *enable = src_filter_config.src_filter_enable; + + return rv; +} + +sw_error_t +adpt_cppe_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 = SW_OK; + a_bool_t src_filter_bypass; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(src_filter_config); + + port_id = FAL_PORT_ID_VALUE(port_id); + if(src_filter_config->src_filter_enable == A_TRUE) + { + src_filter_bypass = A_FALSE; + } + else + { + src_filter_bypass = A_TRUE; + } + rv = cppe_mru_mtu_ctrl_tbl_source_filter_set(dev_id, port_id, + src_filter_bypass); + SW_RTN_ON_ERROR(rv); + rv = cppe_mru_mtu_ctrl_tbl_source_filter_mode_set(dev_id, port_id, + src_filter_config->src_filter_mode); + + return rv; +} + +sw_error_t +adpt_cppe_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 = SW_OK; + a_bool_t src_filter_bypass; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(src_filter_config); + + port_id = FAL_PORT_ID_VALUE(port_id); + rv = cppe_mru_mtu_ctrl_tbl_source_filter_get(dev_id, port_id, + &src_filter_bypass); + SW_RTN_ON_ERROR(rv); + if(src_filter_bypass == A_TRUE) + { + src_filter_config->src_filter_enable = A_FALSE; + } + else + { + src_filter_config->src_filter_enable = A_TRUE; + } + + rv = cppe_mru_mtu_ctrl_tbl_source_filter_mode_get(dev_id, + port_id, &(src_filter_config->src_filter_mode)); + + return rv; +} +#endif + +static a_uint32_t port_loopback_rate[SW_MAX_NR_DEV][CPPE_LOOPBACK_PORT_NUM] = { + {14}, + {14}, + {14}, +}; /* unit is Mpps*/ + +sw_error_t +adpt_cppe_switch_port_loopback_set(a_uint32_t dev_id, fal_port_t port_id, + fal_loopback_config_t *loopback_cfg) +{ + sw_error_t rv = SW_OK; + union lpbk_enable_u loopback_cfg_tbl; + union lpbk_pps_ctrl_u loopback_rate_ctrl_tbl; + union port_bridge_ctrl_u port_bridge_ctrl; + a_uint32_t physical_port = 0; + + if (port_id != SSDK_PHYSICAL_PORT6) { + return SW_BAD_PARAM; + } + + memset(&loopback_cfg_tbl, 0, sizeof(loopback_cfg_tbl)); + memset(&loopback_rate_ctrl_tbl, 0, sizeof(loopback_rate_ctrl_tbl)); + memset(&port_bridge_ctrl, 0, sizeof(port_bridge_ctrl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(loopback_cfg); + + physical_port = port_id; + rv = hppe_port_bridge_ctrl_get(dev_id, physical_port, &port_bridge_ctrl); + SW_RTN_ON_ERROR (rv); + port_bridge_ctrl.bf.txmac_en = loopback_cfg->enable; + + port_id = HPPE_TO_GMAC_PORT_ID(port_id); + rv = cppe_lpbk_pps_ctrl_get(dev_id, port_id, &loopback_rate_ctrl_tbl); + SW_RTN_ON_ERROR (rv); + + loopback_rate_ctrl_tbl.bf.lpbk_pps_threshold = + CPPE_LOOPBACK_PORT_RATE_FREQUENCY / loopback_cfg->loopback_rate; + + rv = cppe_lpbk_enable_get(dev_id, port_id, &loopback_cfg_tbl); + SW_RTN_ON_ERROR (rv); + loopback_cfg_tbl.bf.lpbk_en = loopback_cfg->enable; + loopback_cfg_tbl.bf.crc_strip_en = loopback_cfg->crc_stripped; + + if (loopback_cfg->enable == A_TRUE) { + rv = cppe_lpbk_pps_ctrl_set(dev_id, port_id, &loopback_rate_ctrl_tbl); + SW_RTN_ON_ERROR (rv); + rv = cppe_lpbk_enable_set(dev_id, port_id, &loopback_cfg_tbl); + SW_RTN_ON_ERROR (rv); + msleep(100); + rv = hppe_port_bridge_ctrl_set(dev_id, physical_port, + &port_bridge_ctrl); + SW_RTN_ON_ERROR (rv); + } else { + rv = hppe_port_bridge_ctrl_set(dev_id, physical_port, + &port_bridge_ctrl); + SW_RTN_ON_ERROR (rv); + msleep(100); + rv = cppe_lpbk_pps_ctrl_set(dev_id, port_id, &loopback_rate_ctrl_tbl); + SW_RTN_ON_ERROR (rv); + rv = cppe_lpbk_enable_set(dev_id, port_id, &loopback_cfg_tbl); + SW_RTN_ON_ERROR (rv); + } + + port_loopback_rate[dev_id][CPPE_LOOPBACK_PORT_NUM - 1] = + loopback_cfg->loopback_rate; + return rv; +} + +sw_error_t +adpt_cppe_switch_port_loopback_get(a_uint32_t dev_id, fal_port_t port_id, + fal_loopback_config_t *loopback_cfg) +{ + sw_error_t rv = SW_OK; + union lpbk_enable_u loopback_cfg_tbl; + union lpbk_pps_ctrl_u loopback_rate_ctrl_tbl; + + if (port_id != SSDK_PHYSICAL_PORT6) { + return SW_BAD_PARAM; + } + + memset(&loopback_cfg_tbl, 0, sizeof(loopback_cfg_tbl)); + memset(&loopback_rate_ctrl_tbl, 0, sizeof(loopback_rate_ctrl_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(loopback_cfg); + + port_id = HPPE_TO_GMAC_PORT_ID(port_id); + rv = cppe_lpbk_enable_get(dev_id, port_id, &loopback_cfg_tbl); + SW_RTN_ON_ERROR (rv); + rv = cppe_lpbk_pps_ctrl_get(dev_id, port_id, &loopback_rate_ctrl_tbl); + SW_RTN_ON_ERROR (rv); + + loopback_cfg->enable = loopback_cfg_tbl.bf.lpbk_en; + loopback_cfg->crc_stripped = loopback_cfg_tbl.bf.crc_strip_en; + loopback_cfg->loopback_rate = + port_loopback_rate[dev_id][CPPE_LOOPBACK_PORT_NUM - 1]; + + return rv; +} + +sw_error_t +adpt_cppe_switch_port_loopback_flowctrl_set(a_uint32_t dev_id, + fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv = SW_OK; + union lpbk_enable_u loopback_cfg_tbl; + + memset(&loopback_cfg_tbl, 0, sizeof(loopback_cfg_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + + if (port_id != SSDK_PHYSICAL_PORT6) { + return SW_BAD_PARAM; + } + + port_id = HPPE_TO_GMAC_PORT_ID(port_id); + rv = cppe_lpbk_enable_get(dev_id, port_id, &loopback_cfg_tbl); + SW_RTN_ON_ERROR (rv); + loopback_cfg_tbl.bf.flowctrl_en = enable; + rv = cppe_lpbk_enable_set(dev_id, port_id, &loopback_cfg_tbl); + + return rv; +} + +sw_error_t +adpt_cppe_switch_port_loopback_flowctrl_get(a_uint32_t dev_id, + fal_port_t port_id, a_bool_t *enable) +{ + sw_error_t rv = SW_OK; + union lpbk_enable_u loopback_cfg_tbl; + + memset(&loopback_cfg_tbl, 0, sizeof(loopback_cfg_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + + if (port_id != SSDK_PHYSICAL_PORT6) { + return SW_BAD_PARAM; + } + + port_id = HPPE_TO_GMAC_PORT_ID(port_id); + rv = cppe_lpbk_enable_get(dev_id, port_id, &loopback_cfg_tbl); + SW_RTN_ON_ERROR (rv); + *enable = loopback_cfg_tbl.bf.flowctrl_en; + + return rv; +} + +sw_error_t +adpt_cppe_lpbk_max_frame_size_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t *max_frame) +{ + sw_error_t rv = SW_OK; + union lpbk_mac_junmo_size_u lpbk_mac_junmo_size; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(max_frame); + port_id = HPPE_TO_GMAC_PORT_ID(port_id); + rv = cppe_lpbk_mac_junmo_size_get(dev_id, port_id, &lpbk_mac_junmo_size); + SW_RTN_ON_ERROR(rv); + *max_frame = lpbk_mac_junmo_size.bf.lpbk_mac_jumbo_size; + + return rv; +} + +sw_error_t +adpt_cppe_lpbk_max_frame_size_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t max_frame) +{ + sw_error_t rv = SW_OK; + union lpbk_mac_junmo_size_u lpbk_mac_junmo_size; + + ADPT_DEV_ID_CHECK(dev_id); + memset(&lpbk_mac_junmo_size, 0, sizeof(lpbk_mac_junmo_size)); + if (max_frame > SSDK_MAX_FRAME_SIZE) + { + return SW_BAD_VALUE; + } + port_id = HPPE_TO_GMAC_PORT_ID(port_id); + rv = cppe_lpbk_mac_junmo_size_get(dev_id, port_id, &lpbk_mac_junmo_size); + SW_RTN_ON_ERROR(rv); + lpbk_mac_junmo_size.bf.lpbk_mac_jumbo_size = max_frame; + rv = cppe_lpbk_mac_junmo_size_set(dev_id, port_id, &lpbk_mac_junmo_size); + + return rv; +} +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/cppe/adpt_cppe_qm.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/cppe/adpt_cppe_qm.c new file mode 100755 index 000000000..d4317d513 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/cppe/adpt_cppe_qm.c @@ -0,0 +1,60 @@ +/* + * 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. + */ + + +/** + * @defgroup + * @{ + */ +#include "sw.h" +#include "fal_qos.h" +#include "cppe_portctrl_reg.h" +#include "cppe_portctrl.h" +#include "adpt.h" + +#ifndef IN_QM_MINI +sw_error_t +adpt_cppe_qm_port_source_profile_set( + a_uint32_t dev_id, fal_port_t port, a_uint32_t src_profile) +{ + union cppe_mru_mtu_ctrl_tbl_u mru_mtu_ctrl_tbl; + a_uint32_t index = FAL_PORT_ID_VALUE(port); + + ADPT_DEV_ID_CHECK(dev_id); + memset(&mru_mtu_ctrl_tbl, 0, sizeof(mru_mtu_ctrl_tbl)); + + + return cppe_mru_mtu_ctrl_tbl_src_profile_set(dev_id, index, + src_profile); +} + +sw_error_t +adpt_cppe_qm_port_source_profile_get( + a_uint32_t dev_id, fal_port_t port, a_uint32_t *src_profile) +{ + union cppe_mru_mtu_ctrl_tbl_u mru_mtu_ctrl_tbl; + a_uint32_t index = FAL_PORT_ID_VALUE(port); + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(src_profile); + memset(&mru_mtu_ctrl_tbl, 0, sizeof(mru_mtu_ctrl_tbl)); + + return cppe_mru_mtu_ctrl_tbl_src_profile_get(dev_id, index, + src_profile); +} +#endif + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/cppe/adpt_cppe_qos.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/cppe/adpt_cppe_qos.c new file mode 100644 index 000000000..c0e0209cd --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/cppe/adpt_cppe_qos.c @@ -0,0 +1,289 @@ +/* + * 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. + */ + + +/** + * @defgroup + * @{ + */ +#include "sw.h" +#include "fal_qos.h" +#include "cppe_portctrl_reg.h" +#include "cppe_portctrl.h" +#include "cppe_qos_reg.h" +#include "cppe_qos.h" +#include "adpt.h" + +static sw_error_t +adpt_cppe_qos_mapping_get(a_uint32_t dev_id, a_uint32_t index, + fal_qos_cosmap_t *cosmap) +{ + sw_error_t rv = SW_OK; + union qos_mapping_tbl_u qos_mapping_tbl; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cosmap); + + rv = cppe_qos_mapping_tbl_get(dev_id, index, &qos_mapping_tbl); + if (rv != SW_OK) + return rv; + + cosmap->internal_pcp = qos_mapping_tbl.bf.int_pcp; + cosmap->internal_dei = qos_mapping_tbl.bf.int_dei; + cosmap->internal_pri = qos_mapping_tbl.bf.int_pri; + cosmap->internal_dscp = qos_mapping_tbl.bf.int_dscp_tc; + cosmap->internal_dp = qos_mapping_tbl.bf.int_dp; + cosmap->dscp_mask = qos_mapping_tbl.bf.dscp_tc_mask; + cosmap->dscp_en = qos_mapping_tbl.bf.int_dscp_en; + cosmap->pcp_en = qos_mapping_tbl.bf.int_pcp_en; + cosmap->dei_en = qos_mapping_tbl.bf.int_dei_en; + cosmap->pri_en = qos_mapping_tbl.bf.int_pri_en; + cosmap->dp_en = qos_mapping_tbl.bf.int_dp_en; + cosmap->qos_prec = qos_mapping_tbl.bf.qos_res_prec_0 | + qos_mapping_tbl.bf.qos_res_prec_1 << 1; + + return SW_OK; +} + +static sw_error_t +adpt_cppe_qos_mapping_set(a_uint32_t dev_id, a_uint32_t index, + fal_qos_cosmap_t *cosmap) +{ + union qos_mapping_tbl_u qos_mapping_tbl; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cosmap); + + memset(&qos_mapping_tbl, 0, sizeof(qos_mapping_tbl)); + + qos_mapping_tbl.bf.int_pcp = cosmap->internal_pcp; + qos_mapping_tbl.bf.int_dei = cosmap->internal_dei; + qos_mapping_tbl.bf.int_pri = cosmap->internal_pri; + qos_mapping_tbl.bf.int_dscp_tc = cosmap->internal_dscp; + qos_mapping_tbl.bf.int_dp = cosmap->internal_dp; + qos_mapping_tbl.bf.dscp_tc_mask = cosmap->dscp_mask; + qos_mapping_tbl.bf.int_dscp_en = cosmap->dscp_en; + qos_mapping_tbl.bf.int_pcp_en = cosmap->pcp_en; + qos_mapping_tbl.bf.int_dei_en = cosmap->dei_en; + qos_mapping_tbl.bf.int_pri_en = cosmap->pri_en; + qos_mapping_tbl.bf.int_dp_en = cosmap->dp_en; + qos_mapping_tbl.bf.qos_res_prec_0 = cosmap->qos_prec & 1; + qos_mapping_tbl.bf.qos_res_prec_1 = (cosmap->qos_prec >> 1) & 3; + + return cppe_qos_mapping_tbl_set(dev_id, index, &qos_mapping_tbl); +} + +sw_error_t +adpt_cppe_qos_port_pri_set(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_pri_precedence_t *pri) +{ + union cppe_mru_mtu_ctrl_tbl_u cppe_mru_mtu_ctrl; + + memset(&cppe_mru_mtu_ctrl, 0, sizeof(cppe_mru_mtu_ctrl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(pri); + + cppe_mru_mtu_ctrl_tbl_get(dev_id, port_id, &cppe_mru_mtu_ctrl); + + cppe_mru_mtu_ctrl.bf.pcp_res_prec = pri->pcp_pri; + cppe_mru_mtu_ctrl.bf.dscp_res_prec = pri->dscp_pri; + cppe_mru_mtu_ctrl.bf.preheader_res_prec = pri->preheader_pri; + cppe_mru_mtu_ctrl.bf.flow_res_prec = pri->flow_pri; + cppe_mru_mtu_ctrl.bf.pre_acl_res_prec = pri->acl_pri; + cppe_mru_mtu_ctrl.bf.post_acl_res_prec = pri->post_acl_pri; + cppe_mru_mtu_ctrl.bf.pcp_res_prec_force = pri->pcp_pri_force; + cppe_mru_mtu_ctrl.bf.dscp_res_prec_force = pri->dscp_pri_force; + + return cppe_mru_mtu_ctrl_tbl_set(dev_id, port_id, &cppe_mru_mtu_ctrl); +} + +sw_error_t +adpt_cppe_qos_port_pri_get(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_pri_precedence_t *pri) +{ + sw_error_t rv = SW_OK; + union cppe_mru_mtu_ctrl_tbl_u cppe_mru_mtu_ctrl; + + memset(&cppe_mru_mtu_ctrl, 0, sizeof(cppe_mru_mtu_ctrl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(pri); + + rv = cppe_mru_mtu_ctrl_tbl_get(dev_id, port_id, &cppe_mru_mtu_ctrl); + if( rv != SW_OK ) + return rv; + + pri->pcp_pri = cppe_mru_mtu_ctrl.bf.pcp_res_prec; + pri->dscp_pri = cppe_mru_mtu_ctrl.bf.dscp_res_prec; + pri->preheader_pri = cppe_mru_mtu_ctrl.bf.preheader_res_prec; + pri->flow_pri = cppe_mru_mtu_ctrl.bf.flow_res_prec; + pri->acl_pri = cppe_mru_mtu_ctrl.bf.pre_acl_res_prec; + pri->post_acl_pri = cppe_mru_mtu_ctrl.bf.post_acl_res_prec; + pri->pcp_pri_force = cppe_mru_mtu_ctrl.bf.pcp_res_prec_force; + pri->dscp_pri_force = cppe_mru_mtu_ctrl.bf.dscp_res_prec_force; + + return SW_OK; +} + +sw_error_t +adpt_cppe_qos_cosmap_pcp_get(a_uint32_t dev_id, a_uint8_t group_id, + a_uint8_t pcp, + fal_qos_cosmap_t *cosmap) +{ + a_uint32_t index = 0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cosmap); + + if (group_id >= QOS_MAPPING_TBL_MAX_GROUP) + return SW_BAD_PARAM; + + index = QOS_MAPPING_FLOW_TBL_MAX_ENTRY + + 2 * QOS_MAPPING_DSCP_TBL_MAX_ENTRY + + group_id * QOS_MAPPING_PCP_TBL_MAX_ENTRY + pcp; + + return adpt_cppe_qos_mapping_get(dev_id, index, cosmap); +} + +sw_error_t +adpt_cppe_qos_cosmap_pcp_set(a_uint32_t dev_id, a_uint8_t group_id, + a_uint8_t pcp, + fal_qos_cosmap_t *cosmap) +{ + a_uint32_t index = 0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cosmap); + + if (group_id >= QOS_MAPPING_TBL_MAX_GROUP) + return SW_BAD_PARAM; + + index = QOS_MAPPING_FLOW_TBL_MAX_ENTRY + + 2 * QOS_MAPPING_DSCP_TBL_MAX_ENTRY + + group_id * QOS_MAPPING_PCP_TBL_MAX_ENTRY + pcp; + + return adpt_cppe_qos_mapping_set(dev_id, index, cosmap); +} + +sw_error_t +adpt_cppe_qos_cosmap_dscp_get(a_uint32_t dev_id, a_uint8_t group_id, + a_uint8_t dscp, + fal_qos_cosmap_t *cosmap) +{ + a_uint32_t index = 0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cosmap); + + if (group_id >= QOS_MAPPING_TBL_MAX_GROUP) + return SW_BAD_PARAM; + + index = QOS_MAPPING_FLOW_TBL_MAX_ENTRY + + group_id * QOS_MAPPING_DSCP_TBL_MAX_ENTRY + + dscp; + + return adpt_cppe_qos_mapping_get(dev_id, index, cosmap); +} + +sw_error_t +adpt_cppe_qos_cosmap_flow_set(a_uint32_t dev_id, a_uint8_t group_id, + a_uint16_t flow, + fal_qos_cosmap_t *cosmap) +{ + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cosmap); + + if (flow >= QOS_MAPPING_FLOW_TBL_MAX_ENTRY) + return SW_BAD_PARAM; + + return adpt_cppe_qos_mapping_set(dev_id, flow, cosmap); +} + +sw_error_t +adpt_cppe_qos_port_group_set(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_group_t *group) +{ + union cppe_mru_mtu_ctrl_tbl_u cppe_mru_mtu_ctrl; + + memset(&cppe_mru_mtu_ctrl, 0, sizeof(cppe_mru_mtu_ctrl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(group); + + cppe_mru_mtu_ctrl_tbl_get(dev_id, port_id, &cppe_mru_mtu_ctrl); + + cppe_mru_mtu_ctrl.bf.pcp_qos_group_id = group->pcp_group; + cppe_mru_mtu_ctrl.bf.dscp_qos_group_id = group->dscp_group; + + return cppe_mru_mtu_ctrl_tbl_set(dev_id, port_id, &cppe_mru_mtu_ctrl); +} + +sw_error_t +adpt_cppe_qos_cosmap_dscp_set(a_uint32_t dev_id, a_uint8_t group_id, + a_uint8_t dscp, + fal_qos_cosmap_t *cosmap) +{ + a_uint32_t index = 0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cosmap); + + if (group_id >= QOS_MAPPING_TBL_MAX_GROUP) + return SW_BAD_PARAM; + + index = QOS_MAPPING_FLOW_TBL_MAX_ENTRY + + group_id * QOS_MAPPING_DSCP_TBL_MAX_ENTRY + + dscp; + + return adpt_cppe_qos_mapping_set(dev_id, index, cosmap); +} + +sw_error_t +adpt_cppe_qos_cosmap_flow_get(a_uint32_t dev_id, a_uint8_t group_id, + a_uint16_t flow, + fal_qos_cosmap_t *cosmap) +{ + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cosmap); + + if (flow >= QOS_MAPPING_FLOW_TBL_MAX_ENTRY) + return SW_BAD_PARAM; + + return adpt_cppe_qos_mapping_get(dev_id, flow, cosmap); +} + +sw_error_t +adpt_cppe_qos_port_group_get(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_group_t *group) +{ + sw_error_t rv = SW_OK; + union cppe_mru_mtu_ctrl_tbl_u cppe_mru_mtu_ctrl; + + memset(&cppe_mru_mtu_ctrl, 0, sizeof(cppe_mru_mtu_ctrl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(group); + + rv = cppe_mru_mtu_ctrl_tbl_get(dev_id, port_id, &cppe_mru_mtu_ctrl); + if( rv != SW_OK ) + return rv; + + group->pcp_group = cppe_mru_mtu_ctrl.bf.pcp_qos_group_id; + group->dscp_group = cppe_mru_mtu_ctrl.bf.dscp_qos_group_id; + + return SW_OK; +} + + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/cppe/adpt_cppe_uniphy.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/cppe/adpt_cppe_uniphy.c new file mode 100755 index 000000000..cf38c00fe --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/cppe/adpt_cppe_uniphy.c @@ -0,0 +1,304 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hppe_global_reg.h" +#include "hppe_global.h" +#include "hppe_uniphy_reg.h" +#include "hppe_uniphy.h" +#include "hppe_init.h" +#include "ssdk_init.h" +#include "ssdk_clk.h" +#include "adpt_hppe.h" +#include "adpt.h" +#include "hppe_reg_access.h" +#include "hsl_phy.h" +#include "adpt_cppe_portctrl.h" +#include "adpt_cppe_uniphy.h" + +static sw_error_t +__adpt_cppe_uniphy_reset(a_uint32_t dev_id, a_uint32_t uniphy_index) +{ + sw_error_t rv = SW_OK; + union pll_power_on_and_reset_u pll_software_reset; + + memset(&pll_software_reset, 0, sizeof(pll_software_reset)); + ADPT_DEV_ID_CHECK(dev_id); + + rv = hppe_uniphy_pll_reset_ctrl_get(dev_id, uniphy_index, + &pll_software_reset); + SW_RTN_ON_ERROR (rv); + pll_software_reset.bf.software_reset_analog_reset = 0; + rv = hppe_uniphy_pll_reset_ctrl_set(dev_id, uniphy_index, + &pll_software_reset); + SW_RTN_ON_ERROR (rv); + msleep(500); + pll_software_reset.bf.software_reset_analog_reset = 1; + rv = hppe_uniphy_pll_reset_ctrl_set(dev_id, uniphy_index, + &pll_software_reset); + SW_RTN_ON_ERROR (rv); + msleep(500); + + return SW_OK; +} + +static sw_error_t +__adpt_cppe_uniphy_port_disable(a_uint32_t dev_id, a_uint32_t uniphy_index, + a_uint32_t port_id) +{ + enum unphy_rst_type rst_type = 0; + + if (uniphy_index != SSDK_UNIPHY_INSTANCE0) { + return SW_BAD_VALUE; + } + + switch (port_id) { + case SSDK_PHYSICAL_PORT1: + rst_type = UNIPHY0_PORT1_DISABLE_E; + break; + case SSDK_PHYSICAL_PORT2: + rst_type = UNIPHY0_PORT2_DISABLE_E; + break; + case SSDK_PHYSICAL_PORT3: + rst_type = UNIPHY0_PORT3_DISABLE_E; + break; + case SSDK_PHYSICAL_PORT4: + rst_type = UNIPHY0_PORT4_DISABLE_E; + break; + case SSDK_PHYSICAL_PORT5: + rst_type = UNIPHY0_PORT5_DISABLE_E; + break; + default: + break; + } + ssdk_uniphy_reset(dev_id, rst_type, SSDK_RESET_ASSERT); + + return SW_OK; +} + +void +__adpt_cppe_gcc_uniphy_software_reset(a_uint32_t dev_id, + a_uint32_t uniphy_index) +{ + a_uint32_t phy_type = 0; + enum unphy_rst_type rst_type = 0; + + if (uniphy_index >= SSDK_UNIPHY_INSTANCE2) { + return; + } + + if (uniphy_index == SSDK_UNIPHY_INSTANCE0) { + phy_type = hsl_port_phyid_get(dev_id, SSDK_PHYSICAL_PORT4); + if (phy_type == MALIBU2PORT_PHY) { + rst_type = UNIPHY0_PORT_4_5_RESET_E; + } else if (phy_type == QCA8081_PHY_V1_1) { + rst_type = UNIPHY0_PORT_4_RESET_E; + } else { + rst_type = UNIPHY0_SOFT_RESET_E; + } + } else { + rst_type = UNIPHY1_SOFT_RESET_E; + } + + ssdk_uniphy_reset(dev_id, rst_type, SSDK_RESET_ASSERT); + + msleep(100); + + ssdk_uniphy_reset(dev_id, rst_type, SSDK_RESET_DEASSERT); + + return; +} + +sw_error_t +__adpt_cppe_uniphy_channel_selection_set(a_uint32_t dev_id, + a_uint32_t ch0_selection, a_uint32_t ch4_selection) +{ + sw_error_t rv = SW_OK; + union cppe_port_mux_ctrl_u cppe_port_mux_ctrl; + + memset(&cppe_port_mux_ctrl, 0, sizeof(cppe_port_mux_ctrl)); + ADPT_DEV_ID_CHECK(dev_id); + + rv = cppe_port_mux_ctrl_get(dev_id, &cppe_port_mux_ctrl); + SW_RTN_ON_ERROR (rv); + cppe_port_mux_ctrl.bf.pcs0_ch0_sel = ch0_selection; + cppe_port_mux_ctrl.bf.pcs0_ch4_sel = ch4_selection; + rv = cppe_port_mux_ctrl_set(dev_id, &cppe_port_mux_ctrl); + SW_RTN_ON_ERROR (rv); + + return rv; +} + +static sw_error_t +__adpt_cppe_uniphy_mode_ctrl_set(a_uint32_t dev_id, + a_uint32_t uniphy_index, a_uint32_t mode) +{ + sw_error_t rv = SW_OK; + union uniphy_mode_ctrl_u uniphy_mode_ctrl; + + memset(&uniphy_mode_ctrl, 0, sizeof(uniphy_mode_ctrl)); + + /* configure uniphy mode ctrl to psgmii/sgmii/sgmiiplus */ + rv = hppe_uniphy_mode_ctrl_get(dev_id, uniphy_index, &uniphy_mode_ctrl); + SW_RTN_ON_ERROR (rv); + uniphy_mode_ctrl.bf.newaddedfromhere_ch0_autoneg_mode = + UNIPHY_ATHEROS_NEGOTIATION; + if (mode == PORT_WRAPPER_PSGMII) { + uniphy_mode_ctrl.bf.newaddedfromhere_ch0_psgmii_qsgmii = + UNIPHY_CH0_PSGMII_MODE; + uniphy_mode_ctrl.bf.newaddedfromhere_sg_mode = + UNIPHY_SGMII_MODE_DISABLE; + uniphy_mode_ctrl.bf.newaddedfromhere_sgplus_mode = + UNIPHY_SGMIIPLUS_MODE_DISABLE; + } else if (mode == PORT_WRAPPER_SGMII_CHANNEL0) { + uniphy_mode_ctrl.bf.newaddedfromhere_ch0_psgmii_qsgmii = + UNIPHY_CH0_QSGMII_SGMII_MODE; + uniphy_mode_ctrl.bf.newaddedfromhere_sg_mode = + UNIPHY_SGMII_MODE_ENABLE; + uniphy_mode_ctrl.bf.newaddedfromhere_sgplus_mode = + UNIPHY_SGMIIPLUS_MODE_DISABLE; + } else { + uniphy_mode_ctrl.bf.newaddedfromhere_ch0_psgmii_qsgmii = + UNIPHY_CH0_QSGMII_SGMII_MODE; + uniphy_mode_ctrl.bf.newaddedfromhere_sg_mode = + UNIPHY_SGMII_MODE_DISABLE; + uniphy_mode_ctrl.bf.newaddedfromhere_sgplus_mode = + UNIPHY_SGMIIPLUS_MODE_ENABLE; + } + uniphy_mode_ctrl.bf.newaddedfromhere_ch0_qsgmii_sgmii = + UNIPHY_CH0_SGMII_MODE; + uniphy_mode_ctrl.bf.newaddedfromhere_xpcs_mode = + UNIPHY_XPCS_MODE_DISABLE; + rv = hppe_uniphy_mode_ctrl_set(dev_id, uniphy_index, &uniphy_mode_ctrl); + + return rv; +} + +sw_error_t +__adpt_cppe_uniphy_mode_set(a_uint32_t dev_id, + a_uint32_t uniphy_index, a_uint32_t mode) +{ + sw_error_t rv = SW_OK; + a_uint32_t i = 0; + union uniphy_misc2_phy_mode_u uniphy_misc2_phy_mode; + + memset(&uniphy_misc2_phy_mode, 0, sizeof(uniphy_misc2_phy_mode)); + + ADPT_DEV_ID_CHECK(dev_id); + + if (uniphy_index != SSDK_UNIPHY_INSTANCE0) { + SSDK_ERROR("uniphy index is %d\n", uniphy_index); + return SW_BAD_VALUE; + } + + if ((mode == PORT_WRAPPER_SGMII_CHANNEL0) || + (mode == PORT_WRAPPER_SGMII_PLUS)) { + /*set the PHY mode to SGMII or SGMIIPLUS*/ + rv = hppe_uniphy_phy_mode_ctrl_get(dev_id, uniphy_index, + &uniphy_misc2_phy_mode); + SW_RTN_ON_ERROR (rv); + if (mode == PORT_WRAPPER_SGMII_CHANNEL0) { + uniphy_misc2_phy_mode.bf.phy_mode = + UNIPHY_PHY_SGMII_MODE; + } else { + uniphy_misc2_phy_mode.bf.phy_mode = + UNIPHY_PHY_SGMIIPLUS_MODE; + } + rv = hppe_uniphy_phy_mode_ctrl_set(dev_id, uniphy_index, + &uniphy_misc2_phy_mode); + SW_RTN_ON_ERROR (rv); + + /*reset uniphy*/ + rv = __adpt_cppe_uniphy_reset(dev_id, uniphy_index); + SW_RTN_ON_ERROR (rv); + } + /* keep xpcs to reset status */ + __adpt_hppe_gcc_uniphy_xpcs_reset(dev_id, uniphy_index, A_TRUE); + + SW_RTN_ON_ERROR (rv); + if (mode == PORT_WRAPPER_PSGMII) { + /* disable GCC_UNIPHY0_MISC port 1, 2 and 3*/ + for (i = SSDK_PHYSICAL_PORT1; i < SSDK_PHYSICAL_PORT4; i++) { + rv = __adpt_cppe_uniphy_port_disable(dev_id, uniphy_index, i); + SW_RTN_ON_ERROR (rv); + } + + /* disable instance0 port 4 and 5 clock */ + for (i = SSDK_PHYSICAL_PORT4; i < SSDK_PHYSICAL_PORT6; i++) { + qca_gcc_uniphy_port_clock_set(dev_id, uniphy_index, + i, A_FALSE); + } + rv = __adpt_cppe_uniphy_channel_selection_set(dev_id, + CPPE_PCS0_CHANNEL0_SEL_PSGMII, + CPPE_PCS0_CHANNEL4_SEL_PORT3_CLOCK); + SW_RTN_ON_ERROR (rv); + } else { + /* disable GCC_UNIPHY0_MISC port 2, 3 and 5*/ + for (i = SSDK_PHYSICAL_PORT1; i < SSDK_PHYSICAL_PORT6; i++) { + if ((i == SSDK_PHYSICAL_PORT1) || (i == SSDK_PHYSICAL_PORT4)) { + continue; + } + rv = __adpt_cppe_uniphy_port_disable(dev_id, uniphy_index, i); + SW_RTN_ON_ERROR (rv); + } + /* disable instance0 port 4 clock */ + qca_gcc_uniphy_port_clock_set(dev_id, uniphy_index, + SSDK_PHYSICAL_PORT4, A_FALSE); + rv = __adpt_cppe_uniphy_channel_selection_set(dev_id, + CPPE_PCS0_CHANNEL0_SEL_SGMIIPLUS, + CPPE_PCS0_CHANNEL4_SEL_PORT5_CLOCK); + SW_RTN_ON_ERROR (rv); + } + + rv = __adpt_cppe_uniphy_mode_ctrl_set(dev_id, uniphy_index, mode); + SW_RTN_ON_ERROR (rv); + + __adpt_cppe_gcc_uniphy_software_reset(dev_id, uniphy_index); + + /* wait uniphy calibration done */ + rv = __adpt_hppe_uniphy_calibrate(dev_id, uniphy_index); + SW_RTN_ON_ERROR (rv); + + if (mode == PORT_WRAPPER_PSGMII) { + rv = hsl_port_phy_serdes_reset(dev_id); + SW_RTN_ON_ERROR (rv); + /* enable instance0 clock */ + for (i = SSDK_PHYSICAL_PORT4; i < SSDK_PHYSICAL_PORT6; i++) { + qca_gcc_uniphy_port_clock_set(dev_id, uniphy_index, + i, A_TRUE); + } + } else { + /* enable instance clock */ + qca_gcc_uniphy_port_clock_set(dev_id, uniphy_index, + SSDK_PHYSICAL_PORT4, A_TRUE); + } + if (mode == PORT_WRAPPER_PSGMII) { + SSDK_DEBUG("cypress uniphy %d psgmii configuration is done!\n", uniphy_index); + } else if (mode == PORT_WRAPPER_SGMII_CHANNEL0) { + SSDK_DEBUG("cypress uniphy %d sgmii configuration is done!\n", uniphy_index); + } else { + SSDK_DEBUG("cypress uniphy %d sgmiiplus configuration is done!\n", uniphy_index); + } + + return rv; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/Makefile b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/Makefile new file mode 100755 index 000000000..8a81feed7 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/Makefile @@ -0,0 +1,112 @@ +LOC_DIR=src/adpt/hppe +LIB=ADPT + +include $(PRJ_PATH)/make/config.mk + +SRC_LIST= + +ifeq (TRUE, $(IN_FDB)) + SRC_LIST += adpt_hppe_fdb.c +endif + +ifeq (TRUE, $(IN_MIB)) + SRC_LIST += adpt_hppe_mib.c +endif + +ifeq (TRUE, $(IN_STP)) + SRC_LIST += adpt_hppe_stp.c +endif + +ifeq (TRUE, $(IN_VSI)) + SRC_LIST += adpt_hppe_vsi.c +endif + +ifeq (TRUE, $(IN_PORTCONTROL)) + SRC_LIST += adpt_hppe_portctrl.c +endif + +ifeq (TRUE, $(IN_MIRROR)) + SRC_LIST += adpt_hppe_mirror.c +endif + +ifeq (TRUE, $(IN_TRUNK)) + SRC_LIST += adpt_hppe_trunk.c +endif + +ifeq (TRUE, $(IN_IP)) + SRC_LIST += adpt_hppe_ip.c +endif + +ifeq (TRUE, $(IN_FLOW)) + SRC_LIST += adpt_hppe_flow.c +endif + +ifeq (TRUE, $(IN_QM)) + SRC_LIST += adpt_hppe_qm.c +endif + +ifeq (TRUE, $(IN_PPPOE)) + SRC_LIST += adpt_hppe_pppoe.c +endif + +ifeq (TRUE, $(IN_PORTVLAN)) + SRC_LIST += adpt_hppe_portvlan.c +endif + +ifeq (TRUE, $(IN_CTRLPKT)) + SRC_LIST += adpt_hppe_ctrlpkt.c +endif + +ifeq (TRUE, $(IN_SERVCODE)) + SRC_LIST += adpt_hppe_servcode.c +endif + +ifeq (TRUE, $(IN_RSS_HASH)) + SRC_LIST += adpt_hppe_rss_hash.c +endif + +ifeq (TRUE, $(IN_SEC)) + SRC_LIST += adpt_hppe_sec.c +endif + +ifeq (TRUE, $(IN_ACL)) + SRC_LIST += adpt_hppe_acl.c +endif + +ifeq (TRUE, $(IN_QOS)) + SRC_LIST += adpt_hppe_qos.c +endif + +ifeq (TRUE, $(IN_BM)) + SRC_LIST += adpt_hppe_bm.c +endif + +ifeq (TRUE, $(IN_SHAPER)) + SRC_LIST += adpt_hppe_shaper.c +endif + +ifeq (TRUE, $(IN_POLICER)) + SRC_LIST += adpt_hppe_policer.c +endif + +ifeq (TRUE, $(IN_MISC)) + SRC_LIST += adpt_hppe_misc.c +endif + +ifeq (TRUE, $(IN_UNIPHY)) + SRC_LIST += adpt_hppe_uniphy.c +endif + +ifeq (TRUE, $(IN_PTP)) + SRC_LIST += adpt_hppe_ptp.c +endif + +ifeq (, $(findstring HPPE, $(SUPPORT_CHIP))) + SRC_LIST= +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/src/src/adpt/hppe/adpt_hppe_acl.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_acl.c new file mode 100755 index 000000000..a79138b13 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_acl.c @@ -0,0 +1,4021 @@ +/* + * 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. + */ + + +/** + * @defgroup + * @{ + */ +#include "sw.h" +#include "adpt.h" +#include "adpt_hppe.h" +#include "hppe_acl_reg.h" +#include "hppe_acl.h" +#include + +#define ADPT_ACL_HPPE_MAC_DA_RULE 0 +#define ADPT_ACL_HPPE_MAC_SA_RULE 1 +#define ADPT_ACL_HPPE_VLAN_RULE 2 +#define ADPT_ACL_HPPE_L2_MISC_RULE 3 +#define ADPT_ACL_HPPE_IPV4_DIP_RULE 4 +#define ADPT_ACL_HPPE_IPV4_SIP_RULE 5 +#define ADPT_ACL_HPPE_IPV6_DIP0_RULE 6 +#define ADPT_ACL_HPPE_IPV6_DIP1_RULE 7 +#define ADPT_ACL_HPPE_IPV6_DIP2_RULE 8 +#define ADPT_ACL_HPPE_IPV6_SIP0_RULE 9 +#define ADPT_ACL_HPPE_IPV6_SIP1_RULE 10 +#define ADPT_ACL_HPPE_IPV6_SIP2_RULE 11 +#define ADPT_ACL_HPPE_IPMISC_RULE 12 +#define ADPT_ACL_HPPE_UDF0_RULE 13 +#define ADPT_ACL_HPPE_UDF1_RULE 14 +#define ADPT_ACL_HPPE_RULE_TYPE_NUM 15 + + +#define ADPT_ACL_SW_LIST_NUM 512 +#define ADPT_ACL_HW_LIST_NUM 64 +#define ADPT_ACL_RULE_NUM_PER_LIST 8 /* can change this MACRO to support more rules per ACL list */ +#define ADPT_ACL_ENTRY_NUM_PER_LIST 8 + +typedef struct{ + struct list_head list; + a_uint16_t rule_id; + a_uint8_t rule_type; + a_uint8_t rule_hw_entry; + a_uint8_t rule_hw_list_id; + a_uint8_t ext1_val; + a_uint8_t ext2_val; + a_uint8_t ext4_val; +}ADPT_HPPE_ACL_SW_RULE; + +typedef struct{ + struct list_head list; + struct list_head list_sw_rule; + a_uint32_t list_pri; + a_uint16_t list_id; +}ADPT_HPPE_ACL_SW_LIST; + +typedef struct{ + struct list_head list_sw_list; +}ADPT_HPPE_ACL_SW_LIST_HEAD; + +typedef struct{ + a_bool_t hw_list_valid; + a_uint8_t hw_list_id; + a_uint8_t free_hw_entry_bitmap; + a_uint8_t free_hw_entry_count; +}ADPT_HPPE_ACL_HW_LIST; + +typedef struct{ + a_uint8_t mac[6]; + a_uint32_t is_ip:1; + a_uint32_t is_ipv6:1; + a_uint32_t is_ethernet:1; + a_uint32_t is_snap:1; + a_uint32_t is_fake_mac_header:1; +}ADPT_HPPE_ACL_MAC_RULE; +typedef struct{ + a_uint8_t mac_mask[6]; + a_uint32_t is_ip_mask:1; + a_uint32_t is_ipv6_mask:1; + a_uint32_t is_ethernet_mask:1; + a_uint32_t is_snap_mask:1; + a_uint32_t is_fake_mac_header_mask:1; +}ADPT_HPPE_ACL_MAC_RULE_MASK; + +typedef struct{ + a_uint32_t cvid:12;/*it is min cvid when range is enable*/ + a_uint32_t reserved:4; + a_uint32_t cpcp:3; + a_uint32_t cdei:1; + a_uint32_t svid:12; + a_uint32_t spcp:3; + a_uint32_t sdei:1; + a_uint32_t ctag_fmt:3; + a_uint32_t stag_fmt:3; + a_uint32_t vsi:5; + a_uint32_t vsi_valid:1; + a_uint32_t is_ip:1; + a_uint32_t is_ipv6:1; + a_uint32_t is_ethernet:1; + a_uint32_t is_snap:1; + a_uint32_t is_fake_mac_header:1; +}ADPT_HPPE_ACL_VLAN_RULE; + +typedef struct{ + a_uint32_t cvid_mask:12;/*it is max cvid when range is enable*/ + a_uint32_t reserved:4; + a_uint32_t cpcp_mask:3; + a_uint32_t cdei_mask:1; + a_uint32_t svid_mask:12; + a_uint32_t spcp_mask:3; + a_uint32_t sdei_mask:1; + a_uint32_t ctag_fmt_mask:3; + a_uint32_t stag_fmt_mask:3; + a_uint32_t vsi_mask:5; + a_uint32_t vsi_valid_mask:1; + a_uint32_t is_ip_mask:1; + a_uint32_t is_ipv6_mask:1; + a_uint32_t is_ethernet_mask:1; + a_uint32_t is_snap_mask:1; + a_uint32_t is_fake_mac_header_mask:1; +}ADPT_HPPE_ACL_VLAN_RULE_MASK; + +typedef struct{ + a_uint32_t svid:12;/*it is min svid when range is enable*/ + a_uint32_t reserved:4; + a_uint32_t l2prot:16; + a_uint32_t pppoe_sessionid:16; + a_uint32_t is_ip:1; + a_uint32_t is_ipv6:1; + a_uint32_t is_ethernet:1; + a_uint32_t is_snap:1; + a_uint32_t is_fake_mac_header:1; +}ADPT_HPPE_ACL_L2MISC_RULE; + +typedef struct{ + a_uint32_t svid_mask:12;/*it is max svid when range is enable*/ + a_uint32_t reserved:4; + a_uint32_t l2prot_mask:16; + a_uint32_t pppoe_sessionid_mask:16; + a_uint32_t is_ip_mask:1; + a_uint32_t is_ipv6_mask:1; + a_uint32_t is_ethernet_mask:1; + a_uint32_t is_snap_mask:1; + a_uint32_t is_fake_mac_header_mask:1; +}ADPT_HPPE_ACL_L2MISC_RULE_MASK; + +typedef struct{ + a_uint32_t l4_port:16;/*it is min dport when range is enable*/ + a_uint32_t ip_0:16; + a_uint32_t ip_1:16; + a_uint32_t l3_fragment:1; + a_uint32_t l3_packet_type:3; + a_uint32_t is_ip:1; + a_uint32_t reserved:11; +}ADPT_HPPE_ACL_IPV4_RULE; + +typedef struct{ + a_uint32_t l4_port_mask:16;/*it is min dport when range is enable*/ + a_uint32_t ip_mask_0:16; + a_uint32_t ip_mask_1:16; + a_uint32_t l3_fragment_mask:1; + a_uint32_t l3_packet_type_mask:3; + a_uint32_t is_ip_mask:1; + a_uint32_t reserved:11; +}ADPT_HPPE_ACL_IPV4_RULE_MASK; + +typedef struct{ + a_uint32_t udf0:16; + a_uint32_t udf1:16; + a_uint32_t udf2:16; + a_uint32_t udf0_valid:1; + a_uint32_t udf1_valid:1; + a_uint32_t udf2_valid:1; + a_uint32_t is_ipv6:1; + a_uint32_t is_ip:1; +}ADPT_HPPE_ACL_UDF_RULE; + +typedef struct{ + a_uint32_t udf0_mask:16; + a_uint32_t udf1_mask:16; + a_uint32_t udf2_mask:16; + a_uint32_t udf0_valid:1; + a_uint32_t udf1_valid:1; + a_uint32_t udf2_valid:1; + a_uint32_t is_ipv6:1; + a_uint32_t is_ip:1; +}ADPT_HPPE_ACL_UDF_RULE_MASK; + + +typedef struct{ + a_uint32_t ip_port:16; /*it is port when DIP_2_RULE or SIP_2_RULE*/ + a_uint32_t ip_ext_1:16; + a_uint32_t ip_ext_2:16; + a_uint32_t l3_fragment:1; + a_uint32_t l3_packet_type:3; + a_uint32_t reserved:1; +}ADPT_HPPE_ACL_IPV6_RULE; + +typedef struct{ + a_uint32_t ip_port_mask:16; /*it is port when DIP_2_RULE or SIP_2_RULE*/ + a_uint32_t ip_ext_1_mask:16; + a_uint32_t ip_ext_2_mask:16; + a_uint32_t l3_fragment_mask:1; + a_uint32_t l3_packet_type_mask:3; + a_uint32_t reserved:1; +}ADPT_HPPE_ACL_IPV6_RULE_MASK; + +typedef struct{ + a_uint32_t l3_length:16;/*it is min length when range is enable*/ + a_uint32_t l3_prot:8; /*ipv4 protocol or ipv6 next header*/ + a_uint32_t l3_dscp_tc:8; + a_uint32_t first_fragment:1; + a_uint32_t tcp_flags:6; + a_uint32_t ipv4_option_state:1; + a_uint32_t l3_ttl:2; /*ipv4 ttl, ipv6 hop limit*/ + a_uint32_t ah_header:1; + a_uint32_t esp_header:1; + a_uint32_t mobility_header:1; + a_uint32_t fragment_header:1; + a_uint32_t other_header:1; + a_uint32_t reserved0:1; + a_uint32_t l3_fragment:1; + a_uint32_t is_ipv6:1; + a_uint32_t reserved1:3; +}ADPT_HPPE_ACL_IPMISC_RULE; + +typedef struct{ + a_uint32_t l3_length_mask:16;/*it is max length when range is enable*/ + a_uint32_t l3_prot_mask:8; /*ipv4 protocol or ipv6 next header*/ + a_uint32_t l3_dscp_tc_mask:8; + a_uint32_t first_fragment_mask:1; + a_uint32_t tcp_flags_mask:6; + a_uint32_t ipv4_option_state_mask:1; + a_uint32_t l3_ttl_mask:2; /*ipv4 ttl, ipv6 hop limit*/ + a_uint32_t ah_header_mask:1; + a_uint32_t esp_header_mask:1; + a_uint32_t mobility_header_mask:1; + a_uint32_t fragment_header_mask:1; + a_uint32_t other_header_mask:1; + a_uint32_t reserved0:1; + a_uint32_t l3_fragment_mask:1; + a_uint32_t is_ipv6_mask:1; + a_uint32_t reserved1:3; +}ADPT_HPPE_ACL_IPMISC_RULE_MASK; + +static ADPT_HPPE_ACL_SW_LIST_HEAD g_acl_sw_list[SW_MAX_NR_DEV]; +static ADPT_HPPE_ACL_HW_LIST g_acl_hw_list[SW_MAX_NR_DEV][ADPT_ACL_HW_LIST_NUM]; +static aos_lock_t hppe_acl_lock[SW_MAX_NR_DEV]; + +const a_uint8_t s_acl_ext2[7][2] = { + {0,1},{2,3},{4,5},{6,7},{0,2},{4,6},{0,4} +}; +typedef struct +{ + a_uint8_t num; + a_uint8_t ext_1; + a_uint8_t ext_2; + a_uint8_t ext_4; + a_uint8_t entries; +}ADPT_HPPE_ACL_ENTRY_EXTEND_INFO; +const ADPT_HPPE_ACL_ENTRY_EXTEND_INFO s_acl_entries[] = { + /*num ext_1 ext_2 ext_4 entries*/ + {1, 0, 0, 0, 0x2}, + {1, 0, 0, 0, 0x8}, + {1, 0, 0, 0, 0x20}, + {1, 0, 0, 0, 0x80}, + {1, 0, 0, 0, 0x1}, + {1, 0, 0, 0, 0x4}, + {1, 0, 0, 0, 0x10}, + {1, 0, 0, 0, 0x40}, + {2, 0x1, 0, 0, 0x3}, + {2, 0x2, 0, 0, 0xc}, + {2, 0x4, 0, 0, 0x30}, + {2, 0x8, 0, 0, 0xc0}, + {2, 0, 0x1, 0, 0x5}, + {2, 0, 0x2, 0, 0x50}, + {2, 0, 0, 0x1, 0x11}, + {3, 0x1, 0x1, 0x0, 0x7}, + {3, 0x1, 0x0, 0x1, 0x13}, + {3, 0x2, 0x1, 0x0, 0xd}, + {3, 0x4, 0x2, 0x0, 0x70}, + {3, 0x4, 0x0, 0x1, 0x31}, + {3, 0x8, 0x2, 0x0, 0xd0}, + {3, 0x0, 0x1, 0x1, 0x15}, + {3, 0x0, 0x2, 0x1, 0x51}, + {4, 0x3, 0x1, 0x0, 0xf}, + {4, 0x5, 0x0, 0x1, 0x33}, + {4, 0x2, 0x1, 0x1, 0x1d}, + {4, 0xc, 0x2, 0x0, 0xf0}, + {4, 0x4, 0x1, 0x1, 0x35}, + {4, 0x8, 0x2, 0x1, 0xd1}, + {4, 0x0, 0x3, 0x1, 0x55}, + {5, 0x3, 0x1, 0x1, 0x1f}, + {5, 0x6, 0x1, 0x1, 0x3d}, + {5, 0xc, 0x2, 0x1, 0xf1}, + {5, 0x8, 0x3, 0x1, 0xd5}, + {6, 0x7, 0x1, 0x1, 0x3f}, + {6, 0x6, 0x3, 0x1, 0x7d}, + {6, 0xc, 0x3, 0x1, 0xf5}, + {7, 0x7, 0x3, 0x1, 0x7f}, + {7, 0xe, 0x3, 0x1, 0xfd}, + {8, 0xf, 0x3, 0x1, 0xff}, +}; + +static void _adpt_acl_reg_dump(a_uint8_t *reg, a_uint32_t len) +{ + a_int32_t i = 0; + + for(i = 0; i < len; i++) + { + if(i%32 == 0) + printk("\n"); + printk("%02x ", reg[i]); + } + + return; +} + +/*type = 0, count all; type = 1 count odd; type = 2 count even*/ +static a_uint32_t _acl_bits_count(a_uint32_t bits, a_uint32_t max, a_uint32_t type) +{ + a_uint32_t i = 0, count = 0; + while(i < max) + { + if((bits >> i) &0x1) + { + if(type == 1) + { + if(i%2!=0) + count++; + } + else if(type == 2) + { + if(i%2==0) + count++; + } + else + count++; + } + i++; + } + return count; +} + +/*type = 0, count all; type = 1 count odd; type = 2 count even*/ +static a_uint32_t _acl_bit_index(a_uint32_t bits, a_uint32_t max, a_uint32_t type) +{ + a_uint32_t i = 0; + while(i < max) + { + if((bits >> i) &0x1) + { + if(type == 1)/*odd*/ + { + if(i%2!=0) + break; + } + else if(type == 2)/*even*/ + { + if(i%2==0) + break; + } + else + break; + } + i++; + } + if(i>12)&0x3) +#define HPPE_ACL_DEST_VALUE(dest) ((dest)&0xfff) + +static a_uint32_t _adpt_hppe_acl_srctype_to_hw(fal_acl_bind_obj_t obj_t) +{ + a_uint32_t src_type = HPPE_ACL_TYPE_INVALID; + + switch(obj_t) + { + case FAL_ACL_BIND_PORTBITMAP: + src_type = HPPE_ACL_TYPE_PORTBITMAP; + break; + case FAL_ACL_BIND_PORT: + src_type = HPPE_ACL_TYPE_PORT; + break; + case FAL_ACL_BIND_SERVICE_CODE: + src_type = HPPE_ACL_TYPE_SERVICE_CODE; + break; + case FAL_ACL_BIND_L3_IF: + src_type = HPPE_ACL_TYPE_L3_IF; + break; + } + return src_type; +} + +static sw_error_t +_adpt_hppe_acl_rule_bind(a_uint32_t dev_id, a_uint32_t list_id, ADPT_HPPE_ACL_SW_RULE *rule_entry, + fal_acl_direc_t direc, fal_acl_bind_obj_t obj_t, a_uint32_t obj_idx) +{ + a_uint32_t hw_index = 0, hw_entries = 0, hw_srctype = 0, hw_list_id = 0; + union ipo_rule_reg_u hw_reg = {0}; + + hw_entries = rule_entry->rule_hw_entry; + hw_list_id = rule_entry->rule_hw_list_id; + /* msg for debug */ + SSDK_DEBUG("ACL bind rule: list_id=%d, rule_id=%d, hw_entries=0x%x, hw_list_id=%d\n", + list_id, rule_entry->rule_id, hw_entries, hw_list_id); + + while(hw_entries != 0) + { + hw_index = _acl_bit_index(hw_entries, ADPT_ACL_ENTRY_NUM_PER_LIST, 0); + if(hw_index >= ADPT_ACL_ENTRY_NUM_PER_LIST) + { + break; + } + + hppe_ipo_rule_reg_get(dev_id, hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_index, + &hw_reg); + + if(obj_t == FAL_ACL_BIND_PORT && obj_idx < SSDK_MAX_PORT_NUM) + { + /*convert port to bitmap if it is physical port*/ + obj_t = FAL_ACL_BIND_PORTBITMAP; + obj_idx = (1<>3)&0x1f; + } + else + { + hw_reg.bf.src_0 = obj_idx&0x7; + hw_reg.bf.src_1 = (obj_idx>>3)&0x1f; + } + hw_reg.bf.src_type = hw_srctype; + + hppe_ipo_rule_reg_set(dev_id, hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_index, + &hw_reg); + SSDK_DEBUG("ACL bind entry %d source type %d, source value 0x%x\n", + hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_index, obj_t, obj_idx); + hw_entries &= (~(1<list_id == list_id) + { + break; + } + } + if(list_pos == &g_acl_sw_list[dev_id].list_sw_list) + { + return NULL; + } + else + { + return list_entry; + } +} + +sw_error_t +adpt_hppe_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) +{ + struct list_head *rule_pos = NULL; + ADPT_HPPE_ACL_SW_RULE *rule_bind_entry = NULL; + ADPT_HPPE_ACL_SW_LIST *list_bind_entry = NULL; + + ADPT_DEV_ID_CHECK(dev_id); + + if(list_id >= ADPT_ACL_SW_LIST_NUM) + { + return SW_OUT_OF_RANGE; + } + + aos_lock_bh(&hppe_acl_lock[dev_id]); + list_bind_entry = _adpt_hppe_acl_list_entry_get(dev_id, list_id); + if(list_bind_entry == NULL) + { + aos_unlock_bh(&hppe_acl_lock[dev_id]); + return SW_NOT_FOUND; + } + + list_for_each(rule_pos, &list_bind_entry->list_sw_rule) + { + rule_bind_entry = list_entry(rule_pos, ADPT_HPPE_ACL_SW_RULE, list); + if(rule_bind_entry->rule_hw_entry) + { + sw_error_t rc; + rc = _adpt_hppe_acl_rule_bind(dev_id, list_id, rule_bind_entry, + direc, obj_t, obj_idx); + if(rc != SW_OK) + { + SSDK_ERROR("rule %d bind fail\n", rule_bind_entry->rule_id); + aos_unlock_bh(&hppe_acl_lock[dev_id]); + return SW_FAIL; + } + } + } + aos_unlock_bh(&hppe_acl_lock[dev_id]); + return SW_OK; +} + +static sw_error_t _adpt_hppe_acl_mac_rule_hw_2_sw(a_uint32_t is_mac_da, + union ipo_rule_reg_u *hw_reg, union ipo_mask_reg_u *hw_mask, fal_acl_rule_t * rule) +{ + ADPT_HPPE_ACL_MAC_RULE *macrule = (ADPT_HPPE_ACL_MAC_RULE *)hw_reg; + ADPT_HPPE_ACL_MAC_RULE_MASK *macrule_mask = (ADPT_HPPE_ACL_MAC_RULE_MASK *)hw_mask; + + if(is_mac_da) + { + rule->dest_mac_val.uc[0] = macrule->mac[5]; + rule->dest_mac_val.uc[1] = macrule->mac[4]; + rule->dest_mac_val.uc[2] = macrule->mac[3]; + rule->dest_mac_val.uc[3] = macrule->mac[2]; + rule->dest_mac_val.uc[4] = macrule->mac[1]; + rule->dest_mac_val.uc[5] = macrule->mac[0]; + rule->dest_mac_mask.uc[0] = macrule_mask->mac_mask[5]; + rule->dest_mac_mask.uc[1] = macrule_mask->mac_mask[4]; + rule->dest_mac_mask.uc[2] = macrule_mask->mac_mask[3]; + rule->dest_mac_mask.uc[3] = macrule_mask->mac_mask[2]; + rule->dest_mac_mask.uc[4] = macrule_mask->mac_mask[1]; + rule->dest_mac_mask.uc[5] = macrule_mask->mac_mask[0]; + } + else + { + rule->src_mac_val.uc[0] = macrule->mac[5]; + rule->src_mac_val.uc[1] = macrule->mac[4]; + rule->src_mac_val.uc[2] = macrule->mac[3]; + rule->src_mac_val.uc[3] = macrule->mac[2]; + rule->src_mac_val.uc[4] = macrule->mac[1]; + rule->src_mac_val.uc[5] = macrule->mac[0]; + rule->src_mac_mask.uc[0] = macrule_mask->mac_mask[5]; + rule->src_mac_mask.uc[1] = macrule_mask->mac_mask[4]; + rule->src_mac_mask.uc[2] = macrule_mask->mac_mask[3]; + rule->src_mac_mask.uc[3] = macrule_mask->mac_mask[2]; + rule->src_mac_mask.uc[4] = macrule_mask->mac_mask[1]; + rule->src_mac_mask.uc[5] = macrule_mask->mac_mask[0]; + } + if(A_FALSE == _adpt_acl_zero_addr(rule->dest_mac_mask)) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_MAC_DA); + } + if(A_FALSE == _adpt_acl_zero_addr(rule->src_mac_mask)) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_MAC_SA); + } + + if(macrule_mask->is_ip_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IP); + rule->is_ip_val = macrule->is_ip; + } + + if(macrule_mask->is_ipv6_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IPV6); + rule->is_ipv6_val = macrule->is_ipv6; + } + + if(macrule_mask->is_ethernet_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_ETHERNET); + rule->is_ethernet_val = macrule->is_ethernet; + } + + if(macrule_mask->is_snap_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_SNAP); + rule->is_snap_val = macrule->is_snap; + } + + if(macrule_mask->is_fake_mac_header_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_FAKE_MAC_HEADER); + rule->is_fake_mac_header_val = macrule->is_fake_mac_header; + } + + return SW_OK; +} + +static sw_error_t _adpt_hppe_acl_vlan_rule_hw_2_sw(union ipo_rule_reg_u *hw_reg, + union ipo_mask_reg_u *hw_mask, fal_acl_rule_t * rule) +{ + ADPT_HPPE_ACL_VLAN_RULE * vlanrule = (ADPT_HPPE_ACL_VLAN_RULE *)hw_reg; + ADPT_HPPE_ACL_VLAN_RULE_MASK *vlanrule_mask = (ADPT_HPPE_ACL_VLAN_RULE_MASK *)hw_mask; + + /*ctag*/ + if(vlanrule_mask->cvid_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_MAC_CTAG_VID); + rule->ctag_vid_mask = vlanrule_mask->cvid_mask; + } + if(hw_reg->bf.range_en) + { + if(vlanrule->cvid == 0) + { + rule->ctag_vid_op = FAL_ACL_FIELD_LE; + rule->ctag_vid_val = vlanrule_mask->cvid_mask; + } + else if(vlanrule_mask->cvid_mask == 0xfff) + { + rule->ctag_vid_op = FAL_ACL_FIELD_GE; + rule->ctag_vid_val = vlanrule->cvid; + } + else + { + rule->ctag_vid_op = FAL_ACL_FIELD_RANGE; + rule->ctag_vid_val = vlanrule->cvid; + } + + } + else + { + rule->ctag_vid_op = FAL_ACL_FIELD_MASK; + rule->ctag_vid_val = vlanrule->cvid; + } + + if(vlanrule_mask->cpcp_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_MAC_CTAG_PRI); + rule->ctag_pri_val = vlanrule->cpcp; + rule->ctag_pri_mask = vlanrule_mask->cpcp_mask; + } + + if(vlanrule_mask->cdei_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_MAC_CTAG_CFI); + rule->ctag_cfi_val = vlanrule->cdei; + rule->ctag_cfi_mask = vlanrule_mask->cdei_mask; + } + + if(vlanrule_mask->ctag_fmt_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_MAC_CTAGGED); + rule->ctagged_val = vlanrule->ctag_fmt; + rule->ctagged_mask = vlanrule_mask->ctag_fmt_mask; + } + + /*stag*/ + if(vlanrule_mask->svid_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_MAC_STAG_VID); + rule->stag_vid_val = vlanrule->svid; + rule->stag_vid_mask = vlanrule_mask->svid_mask; + } + if(vlanrule_mask->spcp_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_MAC_STAG_PRI); + rule->stag_pri_val = vlanrule->spcp; + rule->stag_pri_mask = vlanrule_mask->spcp_mask; + } + if(vlanrule_mask->sdei_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_MAC_STAG_DEI); + rule->stag_dei_val = vlanrule->sdei; + rule->stag_dei_mask = vlanrule_mask->sdei_mask; + } + if(vlanrule_mask->stag_fmt_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_MAC_STAGGED); + rule->stagged_val = vlanrule->stag_fmt; + rule->stagged_mask = vlanrule_mask->stag_fmt_mask; + } + /*vsi*/ + if(vlanrule_mask->vsi_valid_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_VSI_VALID); + rule->vsi_valid = vlanrule->vsi_valid; + rule->vsi_valid_mask = vlanrule_mask->vsi_valid_mask; + } + if(vlanrule_mask->vsi_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_VSI); + rule->vsi = vlanrule->vsi; + rule->vsi_mask = vlanrule_mask->vsi_mask; + } + + if(vlanrule_mask->is_ip_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IP); + rule->is_ip_val = vlanrule->is_ip; + } + + if(vlanrule_mask->is_ipv6_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IPV6); + rule->is_ipv6_val = vlanrule->is_ipv6; + } + + if(vlanrule_mask->is_ethernet_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_ETHERNET); + rule->is_ethernet_val = vlanrule->is_ethernet; + } + + if(vlanrule_mask->is_snap_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_SNAP); + rule->is_snap_val = vlanrule->is_snap; + } + + if(vlanrule_mask->is_fake_mac_header_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_FAKE_MAC_HEADER); + rule->is_fake_mac_header_val = vlanrule->is_fake_mac_header; + } + + return SW_OK; +} +static sw_error_t _adpt_hppe_acl_l2_misc_rule_hw_2_sw(union ipo_rule_reg_u *hw_reg, + union ipo_mask_reg_u *hw_mask, fal_acl_rule_t * rule) +{ + ADPT_HPPE_ACL_L2MISC_RULE * l2misc_rule = (ADPT_HPPE_ACL_L2MISC_RULE *)hw_reg; + ADPT_HPPE_ACL_L2MISC_RULE_MASK *l2misc_mask = (ADPT_HPPE_ACL_L2MISC_RULE_MASK *)hw_mask; + + /*stag*/ + if(l2misc_mask->svid_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_MAC_STAG_VID); + rule->stag_vid_mask = l2misc_mask->svid_mask; + } + if(hw_reg->bf.range_en) + { + if(l2misc_rule->svid == 0) + { + rule->stag_vid_op = FAL_ACL_FIELD_LE; + rule->stag_vid_val = l2misc_mask->svid_mask; + } + else if(l2misc_mask->svid_mask == 0xfff) + { + rule->stag_vid_op = FAL_ACL_FIELD_GE; + rule->stag_vid_val = l2misc_rule->svid; + } + else + { + rule->stag_vid_op = FAL_ACL_FIELD_RANGE; + rule->stag_vid_val = l2misc_rule->svid; + } + + } + else + { + rule->stag_vid_op = FAL_ACL_FIELD_MASK; + rule->stag_vid_val = l2misc_rule->svid; + } + + if(l2misc_mask->l2prot_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_MAC_ETHTYPE); + rule->ethtype_val = l2misc_rule->l2prot; + rule->ethtype_mask = l2misc_mask->l2prot_mask; + } + + if(l2misc_mask->pppoe_sessionid_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_PPPOE_SESSIONID); + rule->pppoe_sessionid = l2misc_rule->pppoe_sessionid; + rule->pppoe_sessionid_mask = l2misc_mask->pppoe_sessionid_mask; + } + + if(l2misc_mask->is_ip_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IP); + rule->is_ip_val = l2misc_rule->is_ip; + } + + if(l2misc_mask->is_ipv6_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IPV6); + rule->is_ipv6_val = l2misc_rule->is_ipv6; + } + + if(l2misc_mask->is_ethernet_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_ETHERNET); + rule->is_ethernet_val = l2misc_rule->is_ethernet; + } + + if(l2misc_mask->is_snap_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_SNAP); + rule->is_snap_val = l2misc_rule->is_snap; + } + + if(l2misc_mask->is_fake_mac_header_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_FAKE_MAC_HEADER); + rule->is_fake_mac_header_val = l2misc_rule->is_fake_mac_header; + } + + return SW_OK; +} + +static sw_error_t _adpt_hppe_acl_ipv4_rule_hw_2_sw(a_uint32_t is_ip_da, + union ipo_rule_reg_u *hw_reg, union ipo_mask_reg_u *hw_mask, fal_acl_rule_t *rule) +{ + ADPT_HPPE_ACL_IPV4_RULE * ipv4rule = (ADPT_HPPE_ACL_IPV4_RULE *)hw_reg; + ADPT_HPPE_ACL_IPV4_RULE_MASK *ipv4rule_mask = (ADPT_HPPE_ACL_IPV4_RULE_MASK *)hw_mask; + + if(is_ip_da) + { + if(ipv4rule_mask->ip_mask_0 || ipv4rule_mask->ip_mask_1) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IP4_DIP); + rule->dest_ip4_val = ipv4rule->ip_1<<16|ipv4rule->ip_0; + rule->dest_ip4_mask = (ipv4rule_mask->ip_mask_1<<16)|ipv4rule_mask->ip_mask_0; + } + if(ipv4rule_mask->l4_port_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_L4_DPORT); + rule->dest_l4port_mask = ipv4rule_mask->l4_port_mask; + } + if(hw_reg->bf.range_en) + { + if(ipv4rule->l4_port == 0) + { + rule->dest_l4port_op = FAL_ACL_FIELD_LE; + rule->dest_l4port_val = ipv4rule_mask->l4_port_mask; + } + else if(ipv4rule_mask->l4_port_mask == 0xffff) + { + rule->dest_l4port_op = FAL_ACL_FIELD_GE; + rule->dest_l4port_val = ipv4rule->l4_port; + } + else + { + rule->dest_l4port_op = FAL_ACL_FIELD_RANGE; + rule->dest_l4port_val = ipv4rule->l4_port; + } + } + else + { + rule->dest_l4port_op = FAL_ACL_FIELD_MASK; + rule->dest_l4port_val = ipv4rule->l4_port; + } + } + else + { + if(ipv4rule_mask->ip_mask_0 || ipv4rule_mask->ip_mask_1) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IP4_SIP); + rule->src_ip4_val = ipv4rule->ip_1<<16|ipv4rule->ip_0; + rule->src_ip4_mask = ipv4rule_mask->ip_mask_1<<16|ipv4rule_mask->ip_mask_0; + } + if(ipv4rule_mask->l4_port_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_L4_SPORT); + rule->src_l4port_mask = ipv4rule_mask->l4_port_mask; + } + if(hw_reg->bf.range_en) + { + if(ipv4rule->l4_port == 0) + { + rule->src_l4port_op = FAL_ACL_FIELD_LE; + rule->src_l4port_val = ipv4rule_mask->l4_port_mask; + } + else if(ipv4rule_mask->l4_port_mask == 0xffff) + { + rule->src_l4port_op = FAL_ACL_FIELD_GE; + rule->src_l4port_val = ipv4rule->l4_port; + } + else + { + rule->src_l4port_op = FAL_ACL_FIELD_RANGE; + rule->src_l4port_val = ipv4rule->l4_port; + } + } + else + { + rule->src_l4port_op = FAL_ACL_FIELD_MASK; + rule->src_l4port_val = ipv4rule->l4_port; + } + } + + if(ipv4rule_mask->is_ip_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IP); + rule->is_ip_val = ipv4rule->is_ip; + } + if(ipv4rule_mask->l3_fragment_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_L3_FRAGMENT); + rule->is_fragement_val = ipv4rule->l3_fragment; + rule->is_fragement_mask = ipv4rule_mask->l3_fragment_mask; + } + if(ipv4rule_mask->l3_packet_type_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IP_PKT_TYPE); + rule->l3_pkt_type = ipv4rule->l3_packet_type; + rule->l3_pkt_type_mask = ipv4rule_mask->l3_packet_type_mask; + } + + return SW_OK; +} + +/*ip_bit_range: 0 mean DIP0 or SIP0, 1 mean DIP1 or SIP1, 2 mean DIP2 or SIP2,*/ +static sw_error_t _adpt_hppe_acl_ipv6_rule_hw_2_sw(a_uint32_t is_ip_da, a_uint32_t ip_bit_range, + union ipo_rule_reg_u *hw_reg, union ipo_mask_reg_u *hw_mask, fal_acl_rule_t *rule) +{ + ADPT_HPPE_ACL_IPV6_RULE * ipv6rule = (ADPT_HPPE_ACL_IPV6_RULE *)hw_reg; + ADPT_HPPE_ACL_IPV6_RULE_MASK *ipv6rule_mask = (ADPT_HPPE_ACL_IPV6_RULE_MASK *)hw_mask; + + if(is_ip_da) + { + if(ip_bit_range == 0) + { + if(ipv6rule_mask->ip_port_mask + || ipv6rule_mask->ip_ext_1_mask + || ipv6rule_mask->ip_ext_2_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IP6_DIP); + } + + rule->dest_ip6_val.ul[3] = ipv6rule->ip_ext_1<<16|ipv6rule->ip_port; + rule->dest_ip6_val.ul[2] |= (ipv6rule->ip_ext_2)&0xffff; + rule->dest_ip6_mask.ul[3] = + ipv6rule_mask->ip_ext_1_mask<<16|ipv6rule_mask->ip_port_mask; + rule->dest_ip6_mask.ul[2] |= (ipv6rule_mask->ip_ext_2_mask)&0xffff; + } + else if(ip_bit_range == 1) + { + if(ipv6rule_mask->ip_port_mask + || ipv6rule_mask->ip_ext_1_mask + || ipv6rule_mask->ip_ext_2_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IP6_DIP); + } + rule->dest_ip6_val.ul[2] |= (ipv6rule->ip_port<<16)&0xffff0000; + rule->dest_ip6_val.ul[1] = ipv6rule->ip_ext_2<<16|ipv6rule->ip_ext_1; + rule->dest_ip6_mask.ul[2] |= (ipv6rule_mask->ip_port_mask<<16)&0xffff0000; + rule->dest_ip6_mask.ul[1] = + ipv6rule_mask->ip_ext_2_mask<<16|ipv6rule_mask->ip_ext_1_mask; + } + else if(ip_bit_range == 2) + { + if(ipv6rule_mask->ip_ext_1_mask + || ipv6rule_mask->ip_ext_2_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IP6_DIP); + rule->dest_ip6_val.ul[0] = + ipv6rule->ip_ext_2<<16|ipv6rule->ip_ext_1; + rule->dest_ip6_mask.ul[0] = ipv6rule_mask->ip_ext_2_mask<<16| + ipv6rule_mask->ip_ext_1_mask; + } + if(ipv6rule_mask->ip_port_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_L4_DPORT); + rule->dest_l4port_mask = ipv6rule_mask->ip_port_mask; + } + if(hw_reg->bf.range_en) + { + if(ipv6rule->ip_port == 0) + { + rule->dest_l4port_op = FAL_ACL_FIELD_LE; + rule->dest_l4port_val = ipv6rule_mask->ip_port_mask; + } + else if(ipv6rule_mask->ip_port_mask == 0xffff) + { + rule->dest_l4port_op = FAL_ACL_FIELD_GE; + rule->dest_l4port_val= ipv6rule->ip_port; + } + else + { + rule->dest_l4port_op = FAL_ACL_FIELD_RANGE; + rule->dest_l4port_val= ipv6rule->ip_port; + } + } + else + { + rule->dest_l4port_op = FAL_ACL_FIELD_MASK; + rule->dest_l4port_val = ipv6rule->ip_port; + } + + } + } + else + { + if(ip_bit_range == 0) + { + if(ipv6rule_mask->ip_port_mask + || ipv6rule_mask->ip_ext_1_mask + || ipv6rule_mask->ip_ext_2_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IP6_SIP); + } + rule->src_ip6_val.ul[3] = ipv6rule->ip_ext_1<<16|ipv6rule->ip_port; + rule->src_ip6_val.ul[2] |= (ipv6rule->ip_ext_2)&0xffff; + rule->src_ip6_mask.ul[3] = + ipv6rule_mask->ip_ext_1_mask<<16|ipv6rule_mask->ip_port_mask; + rule->src_ip6_mask.ul[2] |= (ipv6rule_mask->ip_ext_2_mask)&0xffff; + } + else if(ip_bit_range == 1) + { + if(ipv6rule_mask->ip_port_mask + || ipv6rule_mask->ip_ext_1_mask + || ipv6rule_mask->ip_ext_2_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IP6_SIP); + } + rule->src_ip6_val.ul[2] |= (ipv6rule->ip_port<<16)&0xffff0000; + rule->src_ip6_val.ul[1] = ipv6rule->ip_ext_2<<16|ipv6rule->ip_ext_1; + rule->src_ip6_mask.ul[2] |= (ipv6rule_mask->ip_port_mask<<16)&0xffff0000; + rule->src_ip6_mask.ul[1] = + ipv6rule_mask->ip_ext_2_mask<<16|ipv6rule_mask->ip_ext_1_mask; + } + else if(ip_bit_range == 2) + { + if(ipv6rule_mask->ip_ext_1_mask + || ipv6rule_mask->ip_ext_2_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IP6_SIP); + rule->src_ip6_val.ul[0] = ipv6rule->ip_ext_2<<16|ipv6rule->ip_ext_1; + rule->src_ip6_mask.ul[0] = ipv6rule_mask->ip_ext_2_mask<<16| + ipv6rule_mask->ip_ext_1_mask; + } + if(ipv6rule_mask->ip_port_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_L4_SPORT); + rule->src_l4port_mask = ipv6rule_mask->ip_port_mask; + } + if(hw_reg->bf.range_en) + { + if(ipv6rule->ip_port == 0) + { + rule->src_l4port_op = FAL_ACL_FIELD_LE; + rule->src_l4port_val = ipv6rule_mask->ip_port_mask; + } + else if(ipv6rule_mask->ip_port_mask == 0xffff) + { + rule->src_l4port_op = FAL_ACL_FIELD_GE; + rule->src_l4port_val= ipv6rule->ip_port; + } + else + { + rule->src_l4port_op = FAL_ACL_FIELD_RANGE; + rule->src_l4port_val= ipv6rule->ip_port; + } + } + else + { + rule->src_l4port_op = FAL_ACL_FIELD_MASK; + rule->src_l4port_val = ipv6rule->ip_port; + } + + } + } + + if(ipv6rule_mask->l3_fragment_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_L3_FRAGMENT); + rule->is_fragement_val = ipv6rule->l3_fragment; + rule->is_fragement_mask = ipv6rule_mask->l3_fragment_mask; + } + if(ipv6rule_mask->l3_packet_type_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IP_PKT_TYPE); + rule->l3_pkt_type = ipv6rule->l3_packet_type; + rule->l3_pkt_type_mask = ipv6rule_mask->l3_packet_type_mask; + } + return SW_OK; +} + +static sw_error_t _adpt_hppe_acl_ipmisc_rule_hw_2_sw(union ipo_rule_reg_u *hw_reg, + union ipo_mask_reg_u *hw_mask, fal_acl_rule_t *rule) +{ + ADPT_HPPE_ACL_IPMISC_RULE * ipmisc_rule = (ADPT_HPPE_ACL_IPMISC_RULE *)hw_reg; + ADPT_HPPE_ACL_IPMISC_RULE_MASK *ipmisc_mask = (ADPT_HPPE_ACL_IPMISC_RULE_MASK *)hw_mask; + + if(ipmisc_mask->l3_length_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_L3_LENGTH); + rule->l3_length_mask = ipmisc_mask->l3_length_mask; + } + if(hw_reg->bf.range_en) + { + if(ipmisc_rule->l3_length == 0) + { + rule->l3_length_op = FAL_ACL_FIELD_LE; + rule->l3_length = ipmisc_mask->l3_length_mask; + } + else if(ipmisc_mask->l3_length_mask == 0xffff) + { + rule->l3_length_op = FAL_ACL_FIELD_GE; + rule->l3_length = ipmisc_rule->l3_length; + } + else + { + rule->l3_length_op = FAL_ACL_FIELD_RANGE; + rule->l3_length = ipmisc_rule->l3_length; + } + } + else + { + rule->l3_length_op = FAL_ACL_FIELD_MASK; + rule->l3_length = ipmisc_rule->l3_length; + } + + if(ipmisc_mask->l3_prot_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IP_PROTO); + rule->ip_proto_val = ipmisc_rule->l3_prot; + rule->ip_proto_mask = ipmisc_mask->l3_prot_mask; + } + if(ipmisc_mask->l3_dscp_tc_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IP_DSCP); + rule->ip_dscp_val = ipmisc_rule->l3_dscp_tc; + rule->ip_dscp_mask = ipmisc_mask->l3_dscp_tc_mask; + } + + if(ipmisc_mask->first_fragment_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_FIRST_FRAGMENT); + rule->is_first_frag_val = ipmisc_rule->first_fragment; + } + if(ipmisc_mask->tcp_flags_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_TCP_FLAG); + rule->tcp_flag_val = ipmisc_rule->tcp_flags; + rule->tcp_flag_mask = ipmisc_mask->tcp_flags_mask; + } + if(ipmisc_mask->ipv4_option_state_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IPV4_OPTION); + rule->is_ipv4_option_val = ipmisc_rule->ipv4_option_state; + } + if(ipmisc_mask->l3_ttl_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_L3_TTL); + rule->l3_ttl = ipmisc_rule->l3_ttl; + rule->l3_ttl_mask = ipmisc_mask->l3_ttl_mask; + } + if(ipmisc_mask->ah_header_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_AH_HEADER); + rule->is_ah_header_val = ipmisc_rule->ah_header; + } + if(ipmisc_mask->esp_header_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_ESP_HEADER); + rule->is_esp_header_val = ipmisc_rule->esp_header; + } + if(ipmisc_mask->mobility_header_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_MOBILITY_HEADER); + rule->is_mobility_header_val = ipmisc_rule->mobility_header; + } + if(ipmisc_mask->fragment_header_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_FRAGMENT_HEADER); + rule->is_fragment_header_val = ipmisc_rule->fragment_header; + } + if(ipmisc_mask->other_header_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_OTHER_EXT_HEADER); + rule->is_other_header_val = ipmisc_rule->other_header; + } + if(ipmisc_mask->is_ipv6_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IPV6); + rule->is_ipv6_val = ipmisc_rule->is_ipv6; + } + if(ipmisc_mask->l3_fragment_mask) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_L3_FRAGMENT); + rule->is_fragement_val = ipmisc_rule->l3_fragment; + } + return SW_OK; +} + +static sw_error_t _adpt_hppe_acl_udf_rule_hw_2_sw(union ipo_rule_reg_u *hw_reg, a_uint32_t is_win1, + union ipo_mask_reg_u *hw_mask, fal_acl_rule_t *rule) +{ + ADPT_HPPE_ACL_UDF_RULE * udfrule = (ADPT_HPPE_ACL_UDF_RULE *)hw_reg; + ADPT_HPPE_ACL_UDF_RULE_MASK *udfrule_mask = (ADPT_HPPE_ACL_UDF_RULE_MASK *)hw_mask; + + if(is_win1) + { + if(udfrule->udf2_valid == 1) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_UDF3); + rule->udf3_val = udfrule->udf2; + rule->udf3_mask = udfrule_mask->udf2_mask; + } + if(udfrule->udf1_valid == 1) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_UDF2); + rule->udf2_val = udfrule->udf1; + rule->udf2_mask = udfrule_mask->udf1_mask; + } + if(udfrule->udf0_valid == 1) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_UDF1); + if(hw_reg->bf.range_en == 1) + { + if(udfrule->udf0 == 0) + { + rule->udf1_op = FAL_ACL_FIELD_LE; + rule->udf1_val = udfrule_mask->udf0_mask; + } + else if(rule->udf1_mask == 0xffff) + { + rule->udf1_op = FAL_ACL_FIELD_GE; + rule->udf1_val = udfrule->udf0; + } + else + { + rule->udf1_op = FAL_ACL_FIELD_RANGE; + rule->udf1_val = udfrule->udf0; + rule->udf1_mask = udfrule_mask->udf0_mask; + } + } + else + { + rule->udf1_op = FAL_ACL_FIELD_MASK; + rule->udf1_val = udfrule->udf0; + rule->udf1_mask = udfrule_mask->udf0_mask; + } + + } + } + else + { + if(udfrule->udf2_valid == 1) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_UDF2); + rule->udf2_val = udfrule->udf2; + rule->udf2_mask = udfrule_mask->udf2_mask; + } + if(udfrule->udf1_valid == 1) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_UDF1); + rule->udf1_val = udfrule->udf1; + rule->udf1_mask = udfrule_mask->udf1_mask; + } + if(udfrule->udf0_valid == 1) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_UDF0); + if(hw_reg->bf.range_en == 1) + { + if(udfrule->udf0 == 0) + { + rule->udf0_op = FAL_ACL_FIELD_LE; + rule->udf0_val = udfrule_mask->udf0_mask; + } + else if(rule->udf0_mask == 0xffff) + { + rule->udf0_op = FAL_ACL_FIELD_GE; + rule->udf0_val = udfrule->udf0; + } + else + { + rule->udf0_op = FAL_ACL_FIELD_RANGE; + rule->udf0_val = udfrule->udf0; + rule->udf0_mask = udfrule_mask->udf0_mask; + } + } + else + { + rule->udf0_op = FAL_ACL_FIELD_MASK; + rule->udf0_val = udfrule->udf0; + rule->udf0_mask = udfrule_mask->udf0_mask; + } + + } + } + + if(udfrule_mask->is_ip) + { + rule->is_ip_val = udfrule->is_ip; + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IP); + } + if(udfrule_mask->is_ipv6) + { + udfrule->is_ipv6= rule->is_ipv6_val; + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IPV6); + } + return SW_OK; +} + +static sw_error_t +_adpt_hppe_acl_action_hw_2_sw(a_uint32_t dev_id,union ipo_action_u *hw_act, fal_acl_rule_t *rule) +{ + if(hw_act->bf.dest_info_change_en) + { + a_uint32_t dest_type = HPPE_ACL_DEST_TYPE(hw_act->bf.dest_info); + a_uint32_t dest_val = HPPE_ACL_DEST_VALUE(hw_act->bf.dest_info); + SSDK_DEBUG("hw_act->bf.dest_info = %x\n", hw_act->bf.dest_info); + if(dest_type == HPPE_ACL_DEST_NEXTHOP) /*nexthop*/ + { + rule->ports = FAL_ACL_DEST_OFFSET(FAL_ACL_DEST_NEXTHOP, + dest_val); + } + else if(dest_type == HPPE_ACL_DEST_PORT_ID) /*vp or trunk*/ + { + rule->ports = FAL_ACL_DEST_OFFSET(FAL_ACL_DEST_PORT_ID, + dest_val); + } + else if(dest_type == HPPE_ACL_DEST_PORT_BMP) /*bitmap*/ + { + rule->ports = FAL_ACL_DEST_OFFSET(FAL_ACL_DEST_PORT_BMP, + dest_val); + } + if(rule->ports != 0) + { + FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_REDPT); + } + else if(hw_act->bf.fwd_cmd == HPPE_ACL_ACTION_RDTCPU) + { + FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_RDTCPU); + } + else if(hw_act->bf.fwd_cmd == HPPE_ACL_ACTION_COPYCPU) + { + FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_CPYCPU); + } + else if(hw_act->bf.fwd_cmd == HPPE_ACL_ACTION_DROP) + { + FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_DENY); + } + else if(hw_act->bf.fwd_cmd == HPPE_ACL_ACTION_FWD) + { + FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_PERMIT); + } + } + + if(hw_act->bf.mirror_en == 1) + { + FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_MIRROR); + } + if(hw_act->bf.bypass_bitmap_0 != 0 || + hw_act->bf.bypass_bitmap_1 != 0) + { + rule->bypass_bitmap = (hw_act->bf.bypass_bitmap_1<<14)|hw_act->bf.bypass_bitmap_0; + } + if(hw_act->bf.svid_change_en == 1) + { + FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_REMARK_STAG_VID); + rule->stag_fmt = hw_act->bf.stag_fmt; + rule->stag_vid = hw_act->bf.svid; + } + if(hw_act->bf.stag_pcp_change_en == 1) + { + FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_REMARK_STAG_PRI); + rule->stag_pri = hw_act->bf.stag_pcp; + } + if(hw_act->bf.stag_dei_change_en == 1) + { + FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_REMARK_STAG_DEI); + rule->stag_dei = hw_act->bf.stag_dei; + } + if(hw_act->bf.cvid_change_en == 1) + { + FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_REMARK_CTAG_VID); + rule->ctag_fmt = hw_act->bf.ctag_fmt; + rule->ctag_vid = hw_act->bf.cvid; + } + if(hw_act->bf.ctag_pcp_change_en == 1) + { + FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_REMARK_CTAG_PRI); + rule->ctag_pri = (hw_act->bf.ctag_pcp_1<<2)|hw_act->bf.ctag_pcp_0; + } + if(hw_act->bf.ctag_dei_change_en == 1) + { + FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_REMARK_CTAG_CFI); + rule->ctag_cfi = hw_act->bf.ctag_dei; + } + if(hw_act->bf.dscp_tc_change_en == 1) + { + FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_REMARK_DSCP); + rule->dscp = hw_act->bf.dscp_tc; +#if defined(CPPE) + if(adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) + { + rule->dscp_mask = hw_act->bf.dscp_tc_mask; + } +#endif + } + if(hw_act->bf.int_dp_change_en == 1) + { + FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_INT_DP); + rule->int_dp = hw_act->bf.int_dp; + } + if(hw_act->bf.policer_en == 1) + { + FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_POLICER_EN); + rule->policer_ptr = hw_act->bf.policer_index; + } + if(hw_act->bf.qid_en == 1) + { + FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_REMARK_QUEUE); + rule->queue = hw_act->bf.qid; + } + if(hw_act->bf.enqueue_pri_change_en == 1) + { + FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_ENQUEUE_PRI); + rule->enqueue_pri = hw_act->bf.enqueue_pri; + } + if(hw_act->bf.service_code_en == 1) + { + FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_SERVICE_CODE); + rule->service_code = (hw_act->bf.service_code_1<<1)|hw_act->bf.service_code_0; + } + if(hw_act->bf.syn_toggle) + { + FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_SYN_TOGGLE); + } + if(hw_act->bf.cpu_code_en == 1) + { + FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_CPU_CODE); + rule->cpu_code = hw_act->bf.cpu_code; + } + if(hw_act->bf.metadata_en == 1) + { + FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_METADATA_EN); + } +#if defined(CPPE) + if(adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) + { + rule->qos_res_prec = hw_act->bf.qos_res_prec; + } +#endif + return SW_OK; +} +sw_error_t +adpt_hppe_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 = 0; + a_uint32_t hw_index = 0, hw_entries = 0, hw_list_id = 0; + union ipo_rule_reg_u hw_reg = {0}; + union ipo_mask_reg_u hw_mask = {0}; + union ipo_action_u hw_act = {0}; + union ipo_cnt_tbl_u hw_match = {0}; + struct list_head *rule_pos = NULL; + ADPT_HPPE_ACL_SW_RULE *rule_query_entry = NULL; + ADPT_HPPE_ACL_SW_LIST *list_query_entry = NULL; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(rule); + + if(list_id >= ADPT_ACL_SW_LIST_NUM) + { + return SW_OUT_OF_RANGE; + } + + if(rule_id >= ADPT_ACL_RULE_NUM_PER_LIST) + { + return SW_OUT_OF_RANGE; + } + + aos_lock_bh(&hppe_acl_lock[dev_id]); + list_query_entry = _adpt_hppe_acl_list_entry_get(dev_id, list_id); + if(list_query_entry == NULL) + { + aos_unlock_bh(&hppe_acl_lock[dev_id]); + return SW_NOT_FOUND; + } + + list_for_each(rule_pos, &list_query_entry->list_sw_rule) + { + rule_query_entry = list_entry(rule_pos, ADPT_HPPE_ACL_SW_RULE, list); + if((rule_query_entry->rule_id == rule_id) && (rule_query_entry->rule_hw_entry != 0)) + { + rule->rule_type = rule_query_entry->rule_type; + hw_entries = rule_query_entry->rule_hw_entry; + hw_list_id = rule_query_entry->rule_hw_list_id; + break; + } + } + if(rule_pos == &list_query_entry->list_sw_rule) + { + aos_unlock_bh(&hppe_acl_lock[dev_id]); + return SW_NOT_FOUND; + } + aos_unlock_bh(&hppe_acl_lock[dev_id]); + + hw_index = _acl_bit_index(hw_entries, ADPT_ACL_ENTRY_NUM_PER_LIST, 0); + if(hw_index >= ADPT_ACL_ENTRY_NUM_PER_LIST) + { + return SW_FAIL; + } + hppe_ipo_cnt_tbl_get(dev_id, hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_index, &hw_match); + + rule->match_cnt = hw_match.bf.hit_pkt_cnt; + rule->match_bytes = hw_match.bf.hit_byte_cnt_1; + rule->match_bytes = rule->match_bytes<<32|hw_match.bf.hit_byte_cnt_0; + while(hw_entries != 0) + { + hw_index = _acl_bit_index(hw_entries, ADPT_ACL_ENTRY_NUM_PER_LIST, 0); + if(hw_index >= ADPT_ACL_ENTRY_NUM_PER_LIST) + { + break; + } + rv |= hppe_ipo_rule_reg_get(dev_id, hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_index, + &hw_reg); + rv |= hppe_ipo_mask_reg_get(dev_id, hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_index, + &hw_mask); + rv |= hppe_ipo_action_get(dev_id, hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_index, + &hw_act); + rule->post_routing = hw_reg.bf.post_routing_en; + rule->acl_pool = hw_reg.bf.res_chain; + rule->pri = hw_reg.bf.pri&0x7; + + if(hw_reg.bf.rule_type == ADPT_ACL_HPPE_MAC_DA_RULE) + { + _adpt_hppe_acl_mac_rule_hw_2_sw(1, &hw_reg, &hw_mask, rule); + } + if(hw_reg.bf.rule_type == ADPT_ACL_HPPE_MAC_SA_RULE) + { + _adpt_hppe_acl_mac_rule_hw_2_sw(0, &hw_reg, &hw_mask, rule); + } + if(hw_reg.bf.rule_type == ADPT_ACL_HPPE_VLAN_RULE) + { + _adpt_hppe_acl_vlan_rule_hw_2_sw(&hw_reg, &hw_mask, rule); + } + if(hw_reg.bf.rule_type == ADPT_ACL_HPPE_L2_MISC_RULE) + { + _adpt_hppe_acl_l2_misc_rule_hw_2_sw(&hw_reg, &hw_mask, rule); + } + if(hw_reg.bf.rule_type == ADPT_ACL_HPPE_IPV4_DIP_RULE) + { + _adpt_hppe_acl_ipv4_rule_hw_2_sw(1, &hw_reg, &hw_mask, rule); + } + if(hw_reg.bf.rule_type == ADPT_ACL_HPPE_IPV4_SIP_RULE) + { + _adpt_hppe_acl_ipv4_rule_hw_2_sw(0, &hw_reg, &hw_mask, rule); + } + if(hw_reg.bf.rule_type == ADPT_ACL_HPPE_IPV6_DIP0_RULE) + { + _adpt_hppe_acl_ipv6_rule_hw_2_sw(1, 0, &hw_reg, &hw_mask, rule); + } + if(hw_reg.bf.rule_type == ADPT_ACL_HPPE_IPV6_DIP1_RULE) + { + _adpt_hppe_acl_ipv6_rule_hw_2_sw(1, 1, &hw_reg, &hw_mask, rule); + } + if(hw_reg.bf.rule_type == ADPT_ACL_HPPE_IPV6_DIP2_RULE) + { + _adpt_hppe_acl_ipv6_rule_hw_2_sw(1, 2, &hw_reg, &hw_mask, rule); + } + if(hw_reg.bf.rule_type == ADPT_ACL_HPPE_IPV6_SIP0_RULE) + { + _adpt_hppe_acl_ipv6_rule_hw_2_sw(0, 0, &hw_reg, &hw_mask, rule); + } + if(hw_reg.bf.rule_type == ADPT_ACL_HPPE_IPV6_SIP1_RULE) + { + _adpt_hppe_acl_ipv6_rule_hw_2_sw(0, 1, &hw_reg, &hw_mask, rule); + } + if(hw_reg.bf.rule_type == ADPT_ACL_HPPE_IPV6_SIP2_RULE) + { + _adpt_hppe_acl_ipv6_rule_hw_2_sw(0, 2, &hw_reg, &hw_mask, rule); + } + if(hw_reg.bf.rule_type == ADPT_ACL_HPPE_IPMISC_RULE) + { + _adpt_hppe_acl_ipmisc_rule_hw_2_sw(&hw_reg, &hw_mask, rule); + } + if(hw_reg.bf.rule_type == ADPT_ACL_HPPE_UDF0_RULE) + { + _adpt_hppe_acl_udf_rule_hw_2_sw(&hw_reg, 0, &hw_mask, rule); + } + if(hw_reg.bf.rule_type == ADPT_ACL_HPPE_UDF1_RULE) + { + _adpt_hppe_acl_udf_rule_hw_2_sw(&hw_reg, 1, &hw_mask, rule); + } + + if(hw_reg.bf.inverse_en == 1) + { + FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_INVERSE_ALL); + } + + _adpt_hppe_acl_action_hw_2_sw(dev_id,&hw_act, rule); + hw_entries &= (~(1<rule_hw_entry; + hw_list_id = rule_entry->rule_hw_list_id; + /* msg for debug */ + SSDK_DEBUG("ACL unbind rule: list_id=%d, rule_id=%d, hw_entries=0x%x, hw_list_id=%d\n", + list_id, rule_entry->rule_id, hw_entries, hw_list_id); + + while(hw_entries != 0) + { + hw_index = _acl_bit_index(hw_entries, ADPT_ACL_ENTRY_NUM_PER_LIST, 0); + if(hw_index >= ADPT_ACL_ENTRY_NUM_PER_LIST) + { + break; + } + + hppe_ipo_rule_reg_get(dev_id, hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_index, + &hw_reg); + + if(obj_t == FAL_ACL_BIND_PORT && obj_idx < SSDK_MAX_PORT_NUM) + { + /*convert port to bitmap if it is physical port*/ + obj_t = FAL_ACL_BIND_PORTBITMAP; + obj_idx = (1<>3))&0x1f); + } + else + { + hw_reg.bf.src_type = HPPE_ACL_TYPE_PORTBITMAP; + hw_reg.bf.src_0 = 0; + hw_reg.bf.src_1 = 0; + } + hppe_ipo_rule_reg_set(dev_id, hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_index, + &hw_reg); + SSDK_DEBUG("ACL unbind entry %d source type %d, source value 0x%x\n", + hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_index, obj_t, obj_idx); + hw_entries &= (~(1<= ADPT_ACL_SW_LIST_NUM) + { + return SW_OUT_OF_RANGE; + } + + aos_lock_bh(&hppe_acl_lock[dev_id]); + list_unbind_entry = _adpt_hppe_acl_list_entry_get(dev_id, list_id); + if(list_unbind_entry != NULL) + { + list_for_each(rule_pos, &list_unbind_entry->list_sw_rule) + { + rule_unbind_entry = list_entry(rule_pos, ADPT_HPPE_ACL_SW_RULE, list); + if(rule_unbind_entry->rule_hw_entry) + { + _adpt_hppe_acl_rule_unbind(dev_id, list_id, rule_unbind_entry, + direc, obj_t, obj_idx); + } + } + } + aos_unlock_bh(&hppe_acl_lock[dev_id]); + return SW_OK; +} +sw_error_t +adpt_hppe_acl_rule_active(a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t rule_id, a_uint32_t rule_nr) +{ + + ADPT_DEV_ID_CHECK(dev_id); + + return SW_NOT_SUPPORTED; +} + +static sw_error_t _adpt_hppe_acl_rule_range_match(a_uint32_t dev_id, a_uint32_t hw_list_index, + a_uint32_t rule_id, a_uint32_t rule_nr, fal_acl_rule_t * rule, a_uint8_t entries) +{ + a_uint8_t rangecount = 0, even_entry_count = 0; + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_STAG_VID)) + { + if (FAL_ACL_FIELD_MASK != rule->stag_vid_op) + { + rangecount++; + } + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_CTAG_VID)) + { + if (FAL_ACL_FIELD_MASK != rule->ctag_vid_op) + { + rangecount++; + } + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L4_DPORT)) + { + if (FAL_ACL_FIELD_MASK != rule->dest_l4port_op) + { + rangecount++; + } + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L4_SPORT)) + { + if (FAL_ACL_FIELD_MASK != rule->src_l4port_op) + { + rangecount++; + } + } + + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L3_LENGTH)) + { + if (FAL_ACL_FIELD_MASK != rule->l3_length_op) + { + rangecount++; + } + } + + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_UDF0)) + { + if (FAL_ACL_FIELD_MASK != rule->udf0_op) + { + rangecount++; + } + } + + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_UDF1)) + { + if (FAL_ACL_FIELD_MASK != rule->udf1_op) + { + rangecount++; + } + } + + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ICMP_TYPE)) + { + if (FAL_ACL_FIELD_MASK != rule->icmp_type_code_op) + { + rangecount++; + } + } + + even_entry_count = _acl_bits_count(entries, ADPT_ACL_ENTRY_NUM_PER_LIST, 2); + + if(rangecount <= even_entry_count) + { + return SW_OK; + } + return SW_NO_RESOURCE; +} +sw_error_t _adpt_hppe_acl_alloc_entries(a_uint32_t dev_id, a_uint32_t *hw_list_index, + a_uint32_t rule_id, a_uint32_t rule_nr, fal_acl_rule_t * rule, + a_uint32_t rule_type_map, a_uint32_t rule_type_count, a_uint32_t *index) +{ + a_uint8_t free_hw_entry_bitmap = 0, free_hw_entry_count = 0, i = 0; + a_uint32_t j = 0; + a_uint8_t map_info_count = sizeof(s_acl_entries)/sizeof(ADPT_HPPE_ACL_ENTRY_EXTEND_INFO); + + for(j = 0 ; j < ADPT_ACL_HW_LIST_NUM; j++) + { + free_hw_entry_bitmap = g_acl_hw_list[dev_id][j].free_hw_entry_bitmap; + free_hw_entry_count = g_acl_hw_list[dev_id][j].free_hw_entry_count; + /* msg for debug */ + SSDK_DEBUG("_adpt_hppe_acl_alloc_entries():hw_list_index=%d, hw_list_id=%d, " + "free_hw_entry_bitmap=0x%x, free_hw_entry_count=%d\n", j, + g_acl_hw_list[dev_id][j].hw_list_id, free_hw_entry_bitmap, + free_hw_entry_count); + if(free_hw_entry_count < rule_type_count) + { + continue; + } + for(i = 0; i < map_info_count; i++) + { + if((rule_type_count == s_acl_entries[i].num) && + ((free_hw_entry_bitmap & s_acl_entries[i].entries) == + s_acl_entries[i].entries)) + { + if(SW_OK == _adpt_hppe_acl_rule_range_match(dev_id, j, + rule_id, rule_nr, rule, s_acl_entries[i].entries)) + { + SSDK_DEBUG("\n{%d, 0x%x, 0x%x, 0x%x, 0x%x},\n", + s_acl_entries[i].num, s_acl_entries[i].ext_1, + s_acl_entries[i].ext_2, s_acl_entries[i].ext_4, + s_acl_entries[i].entries); + *index = i; + *hw_list_index = j; + return SW_OK; + } + } + } + } + return SW_NO_RESOURCE; +} + +static sw_error_t +_adpt_hppe_acl_l2_fields_check(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, a_uint32_t *rule_type_map) +{ + a_uint32_t l2_rule_type_map = 0; + SSDK_DEBUG("fields[0] = 0x%x, fields[1] = 0x%x\n", rule->field_flg[0], rule->field_flg[1]); + + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_DA)) + { + SSDK_DEBUG("select MAC DA rule\n"); + l2_rule_type_map |= (1<field_flg, FAL_ACL_FIELD_MAC_SA)) + { + SSDK_DEBUG("select MAC SA rule\n"); + l2_rule_type_map |= (1<field_flg, FAL_ACL_FIELD_MAC_STAG_PRI)) || + (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_STAG_DEI)) || + (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_STAGGED)) || + (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_CTAG_VID)) || + (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_CTAG_PRI)) || + (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_CTAG_CFI)) || + (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_CTAGGED)) || + (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_VSI)) || + (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_VSI_VALID))) + { + SSDK_DEBUG("select VLAN rule\n"); + l2_rule_type_map |= (1<field_flg, FAL_ACL_FIELD_MAC_ETHTYPE)) || + (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_PPPOE_SESSIONID))) + { + SSDK_DEBUG("select L2 MISC rule\n"); + l2_rule_type_map |= (1<field_flg, FAL_ACL_FIELD_MAC_STAG_VID)) + { + if(rule->stag_vid_op == FAL_ACL_FIELD_MASK) + { + SSDK_DEBUG("select VLAN rule\n"); + l2_rule_type_map |= (1<field_flg, FAL_ACL_FIELD_SNAP)) || + (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ETHERNET)) || + (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_FAKE_MAC_HEADER))) + { + SSDK_DEBUG("select MAC DA rule\n"); + l2_rule_type_map |= (1<field_flg[0], rule->field_flg[1]); + + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L4_SPORT) || + FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP4_SIP) || + FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ICMP_TYPE) || + FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ICMP_CODE)) + { + *rule_type_map |= (1<field_flg, FAL_ACL_FIELD_L4_DPORT) || + FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP4_DIP)) + { + *rule_type_map |= (1<field_flg, FAL_ACL_FIELD_L3_LENGTH) || + FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP_DSCP) || + FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_FIRST_FRAGMENT) || + FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_TCP_FLAG) || + FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IPV4_OPTION) || + FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L3_TTL) || + FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L3_FRAGMENT) || + FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_AH_HEADER) || + FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ESP_HEADER) || + FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP_PROTO)) + { + *rule_type_map |= (1<field_flg, FAL_ACL_FIELD_IP_PKT_TYPE)) + { + *rule_type_map |= (1<field_flg, FAL_ACL_FIELD_L3_FRAGMENT)) + { + *rule_type_map |= (1<field_flg[0], rule->field_flg[1]); + + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L4_SPORT) || + FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ICMP_TYPE) || + FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ICMP_CODE)) + { + *rule_type_map |= (1<field_flg, FAL_ACL_FIELD_IP6_SIP)) + { + if(rule->src_ip6_mask.ul[3] != 0 || rule->src_ip6_mask.ul[2]&0x0000ffff) + *rule_type_map |= (1<src_ip6_mask.ul[1] != 0 || rule->src_ip6_mask.ul[2]&0xffff0000) + *rule_type_map |= (1<src_ip6_mask.ul[0] != 0 ) + *rule_type_map |= (1<field_flg, FAL_ACL_FIELD_L4_DPORT)) + { + *rule_type_map |= (1<field_flg, FAL_ACL_FIELD_IP6_DIP)) + { + if(rule->dest_ip6_mask.ul[3] != 0 || rule->dest_ip6_mask.ul[2]&0x0000ffff) + *rule_type_map |= (1<dest_ip6_mask.ul[1] != 0 || rule->dest_ip6_mask.ul[2]&0xffff0000) + *rule_type_map |= (1<dest_ip6_mask.ul[0] != 0 ) + *rule_type_map |= (1<field_flg, FAL_ACL_FIELD_L3_LENGTH) || + FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP_DSCP) || + FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_FIRST_FRAGMENT) || + FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_TCP_FLAG) || + FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L3_TTL) || + FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L3_FRAGMENT)|| + FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ESP_HEADER) || + FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MOBILITY_HEADER) || + FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_FRAGMENT_HEADER)|| + FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_OTHER_EXT_HEADER)|| + FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_AH_HEADER) || + FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP_PROTO)) + { + *rule_type_map |= (1<field_flg, FAL_ACL_FIELD_IP_PKT_TYPE)) + { + *rule_type_map |= (1<field_flg, FAL_ACL_FIELD_L3_FRAGMENT)) + { + *rule_type_map |= (1<field_flg[0], rule->field_flg[1]); + + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_UDF0)) + { + *rule_type_map |= (1<field_flg, FAL_ACL_FIELD_UDF3)) + { + *rule_type_map |= (1<field_flg, FAL_ACL_FIELD_UDF1) && + rule->udf1_op != FAL_ACL_FIELD_MASK) + { + *rule_type_map |= (1<field_flg, FAL_ACL_FIELD_UDF1) || + FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_UDF2)) + { + *rule_type_map |= (1<field_flg, FAL_ACL_FIELD_MAC_DA)) + { + macrule->mac[5] = rule->dest_mac_val.uc[0]; + macrule->mac[4] = rule->dest_mac_val.uc[1]; + macrule->mac[3] = rule->dest_mac_val.uc[2]; + macrule->mac[2] = rule->dest_mac_val.uc[3]; + macrule->mac[1] = rule->dest_mac_val.uc[4]; + macrule->mac[0] = rule->dest_mac_val.uc[5]; + macrule_mask->mac_mask[5] = rule->dest_mac_mask.uc[0]; + macrule_mask->mac_mask[4] = rule->dest_mac_mask.uc[1]; + macrule_mask->mac_mask[3] = rule->dest_mac_mask.uc[2]; + macrule_mask->mac_mask[2] = rule->dest_mac_mask.uc[3]; + macrule_mask->mac_mask[1] = rule->dest_mac_mask.uc[4]; + macrule_mask->mac_mask[0] = rule->dest_mac_mask.uc[5]; + } + } + else + { + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_SA)) + { + macrule->mac[5] = rule->src_mac_val.uc[0]; + macrule->mac[4] = rule->src_mac_val.uc[1]; + macrule->mac[3] = rule->src_mac_val.uc[2]; + macrule->mac[2] = rule->src_mac_val.uc[3]; + macrule->mac[1] = rule->src_mac_val.uc[4]; + macrule->mac[0] = rule->src_mac_val.uc[5]; + macrule_mask->mac_mask[5] = rule->src_mac_mask.uc[0]; + macrule_mask->mac_mask[4] = rule->src_mac_mask.uc[1]; + macrule_mask->mac_mask[3] = rule->src_mac_mask.uc[2]; + macrule_mask->mac_mask[2] = rule->src_mac_mask.uc[3]; + macrule_mask->mac_mask[1] = rule->src_mac_mask.uc[4]; + macrule_mask->mac_mask[0] = rule->src_mac_mask.uc[5]; + } + } + + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP)) + { + macrule->is_ip = rule->is_ip_val; + macrule_mask->is_ip_mask = 1; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IPV6)) + { + macrule->is_ipv6 = rule->is_ipv6_val; + macrule_mask->is_ipv6_mask = 1; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ETHERNET)) + { + macrule->is_ethernet = rule->is_ethernet_val; + macrule_mask->is_ethernet_mask = 1; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_SNAP)) + { + macrule->is_snap = rule->is_snap_val; + macrule_mask->is_snap_mask = 1; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_FAKE_MAC_HEADER)) + { + macrule->is_fake_mac_header = rule->is_fake_mac_header_val; + macrule_mask->is_fake_mac_header_mask = 1; + } + + return SW_OK; +} + +static sw_error_t _adpt_hppe_acl_vlan_rule_sw_2_hw(fal_acl_rule_t *rule, + union ipo_rule_reg_u *hw_reg, union ipo_mask_reg_u *hw_mask) +{ + ADPT_HPPE_ACL_VLAN_RULE * vlanrule = (ADPT_HPPE_ACL_VLAN_RULE *)hw_reg; + ADPT_HPPE_ACL_VLAN_RULE_MASK *vlanrule_mask = (ADPT_HPPE_ACL_VLAN_RULE_MASK *)hw_mask; + + /*ctag*/ + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_CTAG_VID)) + { + if(FAL_ACL_FIELD_MASK == rule->ctag_vid_op) + { + vlanrule->cvid = rule->ctag_vid_val; + vlanrule_mask->cvid_mask = rule->ctag_vid_mask; + } + else + { + a_uint16_t min, max; + if(FAL_ACL_FIELD_LE == rule->ctag_vid_op) + { + min = 0; + max = rule->ctag_vid_val; + } + else if(FAL_ACL_FIELD_GE == rule->ctag_vid_op) + { + min = rule->ctag_vid_val; + max = 0xfff; + } + else if(FAL_ACL_FIELD_RANGE == rule->ctag_vid_op) + { + min = rule->ctag_vid_val; + max = rule->ctag_vid_mask; + } + else + return SW_NOT_SUPPORTED; + vlanrule->cvid = min; + vlanrule_mask->cvid_mask = max; + hw_reg->bf.range_en = 1; + } + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_CTAG_PRI)) + { + vlanrule->cpcp = rule->ctag_pri_val; + vlanrule_mask->cpcp_mask = rule->ctag_pri_mask; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_CTAG_CFI)) + { + vlanrule->cdei = rule->ctag_cfi_val; + vlanrule_mask->cdei_mask = rule->ctag_cfi_mask; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_CTAGGED)) + { + vlanrule->ctag_fmt = rule->ctagged_val; + vlanrule_mask->ctag_fmt_mask = rule->ctagged_mask; + } + /*stag*/ + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_STAG_VID)) + { + vlanrule->svid = rule->stag_vid_val; + vlanrule_mask->svid_mask = rule->stag_vid_mask; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_STAG_PRI)) + { + vlanrule->spcp = rule->stag_pri_val; + vlanrule_mask->spcp_mask = rule->stag_pri_mask; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_STAG_DEI)) + { + vlanrule->sdei = rule->stag_dei_val; + vlanrule_mask->sdei_mask = rule->stag_dei_mask; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_STAGGED)) + { + vlanrule->stag_fmt = rule->stagged_val; + vlanrule_mask->stag_fmt_mask = rule->stagged_mask; + } + /*vsi*/ + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_VSI_VALID)) + { + vlanrule->vsi_valid= rule->vsi_valid; + vlanrule_mask->vsi_valid_mask = rule->vsi_valid_mask; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_VSI)) + { + vlanrule->vsi= rule->vsi; + vlanrule_mask->vsi_mask = rule->vsi_mask; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP)) + { + vlanrule->is_ip = rule->is_ip_val; + vlanrule_mask->is_ip_mask = 1; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IPV6)) + { + vlanrule->is_ipv6 = rule->is_ipv6_val; + vlanrule_mask->is_ipv6_mask = 1; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ETHERNET)) + { + vlanrule->is_ethernet = rule->is_ethernet_val; + vlanrule_mask->is_ethernet_mask = 1; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_SNAP)) + { + vlanrule->is_snap = rule->is_snap_val; + vlanrule_mask->is_snap_mask = 1; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_FAKE_MAC_HEADER)) + { + vlanrule->is_fake_mac_header = rule->is_fake_mac_header_val; + vlanrule_mask->is_fake_mac_header_mask = 1; + } + + return SW_OK; +} + + +static sw_error_t _adpt_hppe_acl_l2_misc_rule_sw_2_hw(fal_acl_rule_t *rule, + union ipo_rule_reg_u *hw_reg, union ipo_mask_reg_u *hw_mask) +{ + ADPT_HPPE_ACL_L2MISC_RULE * l2misc_rule = (ADPT_HPPE_ACL_L2MISC_RULE *)hw_reg; + ADPT_HPPE_ACL_L2MISC_RULE_MASK *l2misc_mask = (ADPT_HPPE_ACL_L2MISC_RULE_MASK *)hw_mask; + + /*stag*/ + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_STAG_VID)) + { + if(FAL_ACL_FIELD_MASK == rule->stag_vid_op) + { + l2misc_rule->svid = rule->stag_vid_val; + l2misc_mask->svid_mask = rule->stag_vid_mask; + } + else + { + a_uint16_t min, max; + if(FAL_ACL_FIELD_LE == rule->stag_vid_op) + { + min = 0; + max = rule->stag_vid_val; + } + else if(FAL_ACL_FIELD_GE == rule->stag_vid_op) + { + min = rule->stag_vid_val; + max = 0xfff; + } + else if(FAL_ACL_FIELD_RANGE == rule->stag_vid_op) + { + min = rule->stag_vid_val; + max = rule->stag_vid_mask; + } + else + { + return SW_NOT_SUPPORTED; + } + l2misc_rule->svid = min; + l2misc_mask->svid_mask = max; + hw_reg->bf.range_en = 1; + } + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_ETHTYPE)) + { + l2misc_rule->l2prot = rule->ethtype_val; + l2misc_mask->l2prot_mask = rule->ethtype_mask; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_PPPOE_SESSIONID)) + { + l2misc_rule->pppoe_sessionid = rule->pppoe_sessionid; + l2misc_mask->pppoe_sessionid_mask = rule->pppoe_sessionid_mask; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP)) + { + l2misc_rule->is_ip = rule->is_ip_val; + l2misc_mask->is_ip_mask = 1; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IPV6)) + { + l2misc_rule->is_ipv6 = rule->is_ipv6_val; + l2misc_mask->is_ipv6_mask = 1; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ETHERNET)) + { + l2misc_rule->is_ethernet = rule->is_ethernet_val; + l2misc_mask->is_ethernet_mask = 1; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_SNAP)) + { + l2misc_rule->is_snap = rule->is_snap_val; + l2misc_mask->is_snap_mask = 1; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_FAKE_MAC_HEADER)) + { + l2misc_rule->is_fake_mac_header = rule->is_fake_mac_header_val; + l2misc_mask->is_fake_mac_header_mask = 1; + } + + return SW_OK; +} + +static sw_error_t _adpt_hppe_acl_ipv4_rule_sw_2_hw(fal_acl_rule_t *rule, a_uint32_t is_ip_da, + union ipo_rule_reg_u *hw_reg, union ipo_mask_reg_u *hw_mask) +{ + ADPT_HPPE_ACL_IPV4_RULE * ipv4rule = (ADPT_HPPE_ACL_IPV4_RULE *)hw_reg; + ADPT_HPPE_ACL_IPV4_RULE_MASK *ipv4rule_mask = (ADPT_HPPE_ACL_IPV4_RULE_MASK *)hw_mask; + + if(is_ip_da) + { + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP4_DIP)) + { + ipv4rule->ip_0 = rule->dest_ip4_val&0xffff; + ipv4rule->ip_1 = (rule->dest_ip4_val>>16)&0xffff; + ipv4rule_mask->ip_mask_0 = rule->dest_ip4_mask&0xffff; + ipv4rule_mask->ip_mask_1 = (rule->dest_ip4_mask)>>16&0xffff; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L4_DPORT)) + { + if(FAL_ACL_FIELD_MASK == rule->dest_l4port_op) + { + ipv4rule->l4_port = rule->dest_l4port_val; + ipv4rule_mask->l4_port_mask = rule->dest_l4port_mask; + } + else + { + a_uint16_t min, max; + if(FAL_ACL_FIELD_LE == rule->dest_l4port_op) + { + min = 0; + max = rule->dest_l4port_val; + } + else if(FAL_ACL_FIELD_GE == rule->dest_l4port_op) + { + min = rule->dest_l4port_val; + max = 0xffff; + } + else if(FAL_ACL_FIELD_RANGE == rule->dest_l4port_op) + { + min = rule->dest_l4port_val; + max = rule->dest_l4port_mask; + } + else + return SW_NOT_SUPPORTED; + ipv4rule->l4_port = min; + ipv4rule_mask->l4_port_mask = max; + hw_reg->bf.range_en = 1; + } + } + } + else + { + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP4_SIP)) + { + ipv4rule->ip_0 = rule->src_ip4_val&0xffff; + ipv4rule->ip_1 = (rule->src_ip4_val>>16)&0xffff; + ipv4rule_mask->ip_mask_0 = rule->src_ip4_mask&0xffff; + ipv4rule_mask->ip_mask_1 = (rule->src_ip4_mask>>16)&0xffff; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L4_SPORT)) + { + if(FAL_ACL_FIELD_MASK == rule->src_l4port_op) + { + ipv4rule->l4_port = rule->src_l4port_val; + ipv4rule_mask->l4_port_mask = rule->src_l4port_mask; + } + else + { + a_uint16_t min, max; + if(FAL_ACL_FIELD_LE == rule->src_l4port_op) + { + min = 0; + max = rule->src_l4port_val; + } + else if(FAL_ACL_FIELD_GE == rule->src_l4port_op) + { + min = rule->src_l4port_val; + max = 0xffff; + } + else if(FAL_ACL_FIELD_RANGE == rule->src_l4port_op) + { + min = rule->src_l4port_val; + max = rule->src_l4port_mask; + } + else + return SW_NOT_SUPPORTED; + ipv4rule->l4_port = min; + ipv4rule_mask->l4_port_mask = max; + hw_reg->bf.range_en = 1; + } + } + } + + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ICMP_CODE) || + FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ICMP_TYPE)) + { + if(FAL_ACL_FIELD_MASK == rule->icmp_type_code_op) + { + ipv4rule->l4_port = (rule->icmp_type_val<<8)|rule->icmp_code_val; + ipv4rule_mask->l4_port_mask = (rule->icmp_type_mask<<8)|rule->icmp_code_mask; + } + else + { + a_uint16_t min, max; + if(FAL_ACL_FIELD_LE == rule->icmp_type_code_op) + { + min = 0; + max = (rule->icmp_type_val<<8)|rule->icmp_code_val; + } + else if(FAL_ACL_FIELD_GE == rule->icmp_type_code_op) + { + min = (rule->icmp_type_val<<8)|rule->icmp_code_val; + max = 0xffff; + } + else if(FAL_ACL_FIELD_RANGE == rule->icmp_type_code_op) + { + min = (rule->icmp_type_val<<8)|rule->icmp_code_val; + max = (rule->icmp_type_mask<<8)|rule->icmp_code_mask; + } + else + return SW_NOT_SUPPORTED; + ipv4rule->l4_port = min; + ipv4rule_mask->l4_port_mask = max; + hw_reg->bf.range_en = 1; + } + } + + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP)) + { + ipv4rule->is_ip = rule->is_ip_val; + ipv4rule_mask->is_ip_mask = 1; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L3_FRAGMENT)) + { + ipv4rule->l3_fragment = rule->is_fragement_val; + ipv4rule_mask->l3_fragment_mask = rule->is_fragement_mask; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP_PKT_TYPE)) + { + ipv4rule->l3_packet_type = rule->l3_pkt_type; + ipv4rule_mask->l3_packet_type_mask = rule->l3_pkt_type_mask; + } + + return SW_OK; +} + +/*ip_bit_range: 0 mean DIP0 or SIP0, 1 mean DIP1 or SIP1, 2 mean DIP2 or SIP2,*/ +static sw_error_t _adpt_hppe_acl_ipv6_rule_sw_2_hw(fal_acl_rule_t *rule, a_uint32_t is_ip_da, a_uint32_t ip_bit_range, + union ipo_rule_reg_u *hw_reg, union ipo_mask_reg_u *hw_mask) +{ + ADPT_HPPE_ACL_IPV6_RULE * ipv6rule = (ADPT_HPPE_ACL_IPV6_RULE *)hw_reg; + ADPT_HPPE_ACL_IPV6_RULE_MASK *ipv6rule_mask = (ADPT_HPPE_ACL_IPV6_RULE_MASK *)hw_mask; + + if(is_ip_da) + { + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP6_DIP)) + { + if(ip_bit_range == 0) + { + ipv6rule->ip_port = rule->dest_ip6_val.ul[3]&0xffff; + ipv6rule->ip_ext_1 = (rule->dest_ip6_val.ul[3]>>16)&0xffff; + ipv6rule->ip_ext_2 = (rule->dest_ip6_val.ul[2])&0xffff; + ipv6rule_mask->ip_port_mask = rule->dest_ip6_mask.ul[3]&0xffff; + ipv6rule_mask->ip_ext_1_mask = (rule->dest_ip6_mask.ul[3]>>16)&0xffff; + ipv6rule_mask->ip_ext_2_mask = (rule->dest_ip6_mask.ul[2])&0xffff; + } + else if(ip_bit_range == 1) + { + ipv6rule->ip_port = (rule->dest_ip6_val.ul[2]>>16)&0xffff; + ipv6rule->ip_ext_1 = (rule->dest_ip6_val.ul[1])&0xffff; + ipv6rule->ip_ext_2 = (rule->dest_ip6_val.ul[1]>>16)&0xffff; + ipv6rule_mask->ip_port_mask = (rule->dest_ip6_mask.ul[2]>>16)&0xffff; + ipv6rule_mask->ip_ext_1_mask = (rule->dest_ip6_mask.ul[1])&0xffff; + ipv6rule_mask->ip_ext_2_mask = (rule->dest_ip6_mask.ul[1]>>16)&0xffff; + } + else if(ip_bit_range == 2) + { + ipv6rule->ip_ext_1 = (rule->dest_ip6_val.ul[0])&0xffff; + ipv6rule->ip_ext_2 = (rule->dest_ip6_val.ul[0]>>16)&0xffff; + ipv6rule_mask->ip_ext_1_mask = (rule->dest_ip6_mask.ul[0])&0xffff; + ipv6rule_mask->ip_ext_2_mask = (rule->dest_ip6_mask.ul[0]>>16)&0xffff; + } + } + if((ip_bit_range == 2) && (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L4_DPORT))) + { + if(FAL_ACL_FIELD_MASK == rule->dest_l4port_op) + { + ipv6rule->ip_port = rule->dest_l4port_val; + ipv6rule_mask->ip_port_mask = rule->dest_l4port_mask; + } + else + { + a_uint16_t min, max; + if(FAL_ACL_FIELD_LE == rule->dest_l4port_op) + { + min = 0; + max = rule->dest_l4port_val; + } + else if(FAL_ACL_FIELD_GE == rule->dest_l4port_op) + { + min = rule->dest_l4port_val; + max = 0xffff; + } + else if(FAL_ACL_FIELD_RANGE == rule->dest_l4port_op) + { + min = rule->dest_l4port_val; + max = rule->dest_l4port_mask; + } + else + return SW_NOT_SUPPORTED; + ipv6rule->ip_port = min; + ipv6rule_mask->ip_port_mask = max; + hw_reg->bf.range_en = 1; + } + } + } + else + { + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP6_SIP)) + { + if(ip_bit_range == 0) + { + ipv6rule->ip_port = rule->src_ip6_val.ul[3]&0xffff; + ipv6rule->ip_ext_1 = (rule->src_ip6_val.ul[3]>>16)&0xffff; + ipv6rule->ip_ext_2 = (rule->src_ip6_val.ul[2])&0xffff; + ipv6rule_mask->ip_port_mask = rule->src_ip6_mask.ul[3]&0xffff; + ipv6rule_mask->ip_ext_1_mask = (rule->src_ip6_mask.ul[3]>>16)&0xffff; + ipv6rule_mask->ip_ext_2_mask = (rule->src_ip6_mask.ul[2])&0xffff; + } + else if(ip_bit_range == 1) + { + ipv6rule->ip_port = (rule->src_ip6_val.ul[2]>>16)&0xffff; + ipv6rule->ip_ext_1 = (rule->src_ip6_val.ul[1])&0xffff; + ipv6rule->ip_ext_2 = (rule->src_ip6_val.ul[1]>>16)&0xffff; + ipv6rule_mask->ip_port_mask = (rule->src_ip6_mask.ul[2]>>16)&0xffff; + ipv6rule_mask->ip_ext_1_mask = (rule->src_ip6_mask.ul[1])&0xffff; + ipv6rule_mask->ip_ext_2_mask = (rule->src_ip6_mask.ul[1]>>16)&0xffff; + } + else if(ip_bit_range == 2) + { + ipv6rule->ip_ext_1 = (rule->src_ip6_val.ul[0])&0xffff; + ipv6rule->ip_ext_2 = (rule->src_ip6_val.ul[0]>>16)&0xffff; + ipv6rule_mask->ip_ext_1_mask = (rule->src_ip6_mask.ul[0])&0xffff; + ipv6rule_mask->ip_ext_2_mask = (rule->src_ip6_mask.ul[0]>>16)&0xffff; + } + } + if((ip_bit_range == 2) && (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L4_SPORT))) + { + if(FAL_ACL_FIELD_MASK == rule->src_l4port_op) + { + ipv6rule->ip_port = rule->src_l4port_val; + ipv6rule_mask->ip_port_mask = rule->src_l4port_mask; + } + else + { + a_uint16_t min, max; + if(FAL_ACL_FIELD_LE == rule->src_l4port_op) + { + min = 0; + max = rule->src_l4port_val; + } + else if(FAL_ACL_FIELD_GE == rule->src_l4port_op) + { + min = rule->src_l4port_val; + max = 0xffff; + } + else if(FAL_ACL_FIELD_RANGE == rule->src_l4port_op) + { + min = rule->src_l4port_val; + max = rule->src_l4port_mask; + } + else + return SW_NOT_SUPPORTED; + ipv6rule->ip_port = min; + ipv6rule_mask->ip_port_mask = max; + hw_reg->bf.range_en = 1; + } + } + } + + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ICMP_CODE) || + FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ICMP_TYPE)) + { + if(FAL_ACL_FIELD_MASK == rule->icmp_type_code_op) + { + ipv6rule->ip_port = (rule->icmp_type_val<<8)|rule->icmp_code_val; + ipv6rule_mask->ip_port_mask = (rule->icmp_type_mask<<8)|rule->icmp_code_mask; + } + else + { + a_uint16_t min, max; + if(FAL_ACL_FIELD_LE == rule->icmp_type_code_op) + { + min = 0; + max = (rule->icmp_type_val<<8)|rule->icmp_code_val; + } + else if(FAL_ACL_FIELD_GE == rule->icmp_type_code_op) + { + min = (rule->icmp_type_val<<8)|rule->icmp_code_val; + max = 0xffff; + } + else if(FAL_ACL_FIELD_RANGE == rule->icmp_type_code_op) + { + min = (rule->icmp_type_val<<8)|rule->icmp_code_val; + max = (rule->icmp_type_mask<<8)|rule->icmp_code_mask; + } + else + return SW_NOT_SUPPORTED; + ipv6rule->ip_port = min; + ipv6rule_mask->ip_port_mask = max; + hw_reg->bf.range_en = 1; + } + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L3_FRAGMENT)) + { + ipv6rule->l3_fragment = rule->is_fragement_val; + ipv6rule_mask->l3_fragment_mask = rule->is_fragement_mask; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP_PKT_TYPE)) + { + ipv6rule->l3_packet_type = rule->l3_pkt_type; + ipv6rule_mask->l3_packet_type_mask = rule->l3_pkt_type_mask; + } + return SW_OK; +} + +static sw_error_t _adpt_hppe_acl_ipmisc_rule_sw_2_hw(fal_acl_rule_t *rule, + union ipo_rule_reg_u *hw_reg, union ipo_mask_reg_u *hw_mask) +{ + ADPT_HPPE_ACL_IPMISC_RULE * ipmisc_rule = (ADPT_HPPE_ACL_IPMISC_RULE *)hw_reg; + ADPT_HPPE_ACL_IPMISC_RULE_MASK *ipmisc_mask = (ADPT_HPPE_ACL_IPMISC_RULE_MASK *)hw_mask; + + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L3_LENGTH)) + { + if(FAL_ACL_FIELD_MASK == rule->l3_length_op) + { + ipmisc_rule->l3_length = rule->l3_length; + ipmisc_mask->l3_length_mask = rule->l3_length_mask; + } + else + { + a_uint16_t min, max; + if(FAL_ACL_FIELD_LE == rule->l3_length_op) + { + min = 0; + max = rule->l3_length; + } + else if(FAL_ACL_FIELD_GE == rule->l3_length_op) + { + min = rule->l3_length; + max = 0xffff; + } + else if(FAL_ACL_FIELD_RANGE == rule->l3_length_op) + { + min = rule->l3_length; + max = rule->l3_length_mask; + } + else + return SW_NOT_SUPPORTED; + ipmisc_rule->l3_length = min; + ipmisc_mask->l3_length_mask = max; + hw_reg->bf.range_en = 1; + } + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP_PROTO)) + { + ipmisc_rule->l3_prot = rule->ip_proto_val; + ipmisc_mask->l3_prot_mask = rule->ip_proto_mask; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP_DSCP)) + { + ipmisc_rule->l3_dscp_tc = rule->ip_dscp_val; + ipmisc_mask->l3_dscp_tc_mask = rule->ip_dscp_mask; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_FIRST_FRAGMENT)) + { + ipmisc_rule->first_fragment = rule->is_first_frag_val; + ipmisc_mask->first_fragment_mask = 1; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_TCP_FLAG)) + { + ipmisc_rule->tcp_flags = rule->tcp_flag_val; + ipmisc_mask->tcp_flags_mask = rule->tcp_flag_mask; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IPV4_OPTION)) + { + ipmisc_rule->ipv4_option_state = rule->is_ipv4_option_val; + ipmisc_mask->ipv4_option_state_mask = 1; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L3_TTL)) + { + ipmisc_rule->l3_ttl = rule->l3_ttl; + ipmisc_mask->l3_ttl_mask = rule->l3_ttl_mask; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_AH_HEADER)) + { + ipmisc_rule->ah_header = rule->is_ah_header_val; + ipmisc_mask->ah_header_mask = 1; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ESP_HEADER)) + { + ipmisc_rule->esp_header = rule->is_esp_header_val; + ipmisc_mask->esp_header_mask = 1; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MOBILITY_HEADER)) + { + ipmisc_rule->mobility_header = rule->is_mobility_header_val; + ipmisc_mask->mobility_header_mask = 1; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_FRAGMENT_HEADER)) + { + ipmisc_rule->fragment_header = rule->is_fragment_header_val; + ipmisc_mask->fragment_header_mask= 1; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_OTHER_EXT_HEADER)) + { + ipmisc_rule->other_header = rule->is_other_header_val; + ipmisc_mask->other_header_mask = 1; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IPV6)) + { + ipmisc_rule->is_ipv6 = rule->is_ipv6_val; + ipmisc_mask->is_ipv6_mask = 1; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L3_FRAGMENT)) + { + ipmisc_rule->l3_fragment = rule->is_fragement_val; + ipmisc_mask->l3_fragment_mask = 1; + } + return SW_OK; +} + +static sw_error_t _adpt_hppe_acl_udf_rule_sw_2_hw(fal_acl_rule_t *rule, a_uint32_t is_win1, + union ipo_rule_reg_u *hw_reg, union ipo_mask_reg_u *hw_mask) +{ + ADPT_HPPE_ACL_UDF_RULE * udfrule = (ADPT_HPPE_ACL_UDF_RULE *)hw_reg; + ADPT_HPPE_ACL_UDF_RULE_MASK *udfrule_mask = (ADPT_HPPE_ACL_UDF_RULE_MASK *)hw_mask; + + if(is_win1) + { + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_UDF3)) + { + udfrule->udf2_valid = 1; + udfrule->udf2 = rule->udf3_val; + udfrule_mask->udf2_valid = 1; + udfrule_mask->udf2_mask = rule->udf3_mask; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_UDF2)) + { + udfrule->udf1_valid = 1; + udfrule->udf1 = rule->udf2_val; + udfrule_mask->udf1_valid = 1; + udfrule_mask->udf1_mask = rule->udf2_mask; + } + + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_UDF1)) + { + udfrule->udf0_valid = 1; + udfrule_mask->udf0_valid = 1; + if(FAL_ACL_FIELD_MASK == rule->udf1_op) + { + udfrule->udf0 = rule->udf1_val; + udfrule_mask->udf0_mask = rule->udf1_mask; + } + else + { + a_uint16_t min, max; + if(FAL_ACL_FIELD_LE == rule->udf1_op) + { + min = 0; + max = rule->udf1_val; + } + else if(FAL_ACL_FIELD_GE == rule->udf1_op) + { + min = rule->udf1_val; + max = 0xffff; + } + else if(FAL_ACL_FIELD_RANGE == rule->udf1_op) + { + min = rule->udf1_val; + max = rule->udf1_mask; + } + else + return SW_NOT_SUPPORTED; + udfrule->udf0 = min; + udfrule_mask->udf0_mask = max; + hw_reg->bf.range_en = 1; + } + } + } + else + { + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_UDF1) && + FAL_ACL_FIELD_MASK == rule->udf1_op) + { + udfrule->udf1_valid = 1; + udfrule->udf1 = rule->udf1_val; + udfrule_mask->udf1_valid = 1; + udfrule_mask->udf1_mask = rule->udf1_mask; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_UDF2)) + { + udfrule->udf2_valid = 1; + udfrule->udf2 = rule->udf2_val; + udfrule_mask->udf2_valid = 1; + udfrule_mask->udf2_mask = rule->udf2_mask; + } + + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_UDF0)) + { + udfrule->udf0_valid = 1; + udfrule_mask->udf0_valid = 1; + if(FAL_ACL_FIELD_MASK == rule->udf0_op) + { + udfrule->udf0 = rule->udf0_val; + udfrule_mask->udf0_mask = rule->udf0_mask; + } + else + { + a_uint16_t min, max; + if(FAL_ACL_FIELD_LE == rule->udf0_op) + { + min = 0; + max = rule->udf0_val; + } + else if(FAL_ACL_FIELD_GE == rule->udf0_op) + { + min = rule->udf0_val; + max = 0xffff; + } + else if(FAL_ACL_FIELD_RANGE == rule->udf0_op) + { + min = rule->udf0_val; + max = rule->udf0_mask; + } + else + return SW_NOT_SUPPORTED; + udfrule->udf0 = min; + udfrule_mask->udf0_mask = max; + hw_reg->bf.range_en = 1; + } + } + } + + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP)) + { + udfrule->is_ip = rule->is_ip_val; + udfrule_mask->is_ip = 1; + } + if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IPV6)) + { + udfrule->is_ipv6= rule->is_ipv6_val; + udfrule_mask->is_ipv6 = 1; + } + return SW_OK; +} +static sw_error_t +_adpt_hppe_acl_action_sw_2_hw(a_uint32_t dev_id,fal_acl_rule_t *rule, union ipo_action_u *hw_act) +{ + if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_REDPT)) + { + a_uint32_t dest_type = FAL_ACL_DEST_TYPE(rule->ports); + a_uint32_t dest_val = FAL_ACL_DEST_VALUE(rule->ports); + + SSDK_DEBUG("rule->ports = %x\n", rule->ports); + + hw_act->bf.dest_info_change_en = 1; + if(dest_type == FAL_ACL_DEST_NEXTHOP) /*nexthop*/ + { + hw_act->bf.dest_info = + HPPE_ACL_DEST_INFO(HPPE_ACL_DEST_NEXTHOP, dest_val); + } + else if(FAL_ACL_DEST_TYPE(rule->ports) == FAL_ACL_DEST_PORT_ID)/*vp*/ + { + hw_act->bf.dest_info = + HPPE_ACL_DEST_INFO(HPPE_ACL_DEST_PORT_ID, dest_val); + } + else if(FAL_ACL_DEST_TYPE(rule->ports) == FAL_ACL_DEST_PORT_BMP)/*bitmap*/ + { + hw_act->bf.dest_info = + HPPE_ACL_DEST_INFO(HPPE_ACL_DEST_PORT_BMP, dest_val); + } + } + if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_PERMIT)) + { + hw_act->bf.dest_info_change_en = 1; + hw_act->bf.fwd_cmd = 0;/*forward*/ + } + if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_DENY)) + { + hw_act->bf.dest_info_change_en = 1; + hw_act->bf.fwd_cmd = 1;/*drop*/ + } + if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_CPYCPU)) + { + hw_act->bf.dest_info_change_en = 1; + hw_act->bf.fwd_cmd = 2;/*copy to cpu*/ + } + if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_RDTCPU)) + { + hw_act->bf.dest_info_change_en = 1; + hw_act->bf.fwd_cmd = 3;/*redirect to cpu*/ + } + if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_MIRROR)) + { + hw_act->bf.mirror_en= 1; + } + hw_act->bf.bypass_bitmap_0 = rule->bypass_bitmap & 0x3fff; + hw_act->bf.bypass_bitmap_1 = (rule->bypass_bitmap>>14) & 0x3ffff; + if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_REMARK_STAG_VID)) + { + hw_act->bf.svid_change_en = 1; + hw_act->bf.stag_fmt = rule->stag_fmt; + hw_act->bf.svid = rule->stag_vid; + } + if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_REMARK_STAG_PRI)) + { + hw_act->bf.stag_pcp_change_en = 1; + hw_act->bf.stag_pcp = rule->stag_pri; + } + if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_REMARK_STAG_DEI)) + { + hw_act->bf.stag_dei_change_en = 1; + hw_act->bf.stag_dei = rule->stag_dei; + } + if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_REMARK_CTAG_VID)) + { + hw_act->bf.cvid_change_en = 1; + hw_act->bf.ctag_fmt = rule->ctag_fmt; + hw_act->bf.cvid = rule->ctag_vid; + } + if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_REMARK_CTAG_PRI)) + { + hw_act->bf.ctag_pcp_change_en = 1; + hw_act->bf.ctag_pcp_0 = rule->ctag_pri&0x3; + hw_act->bf.ctag_pcp_1 = (rule->ctag_pri>>2)&0x1; + } + if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_REMARK_CTAG_CFI)) + { + hw_act->bf.ctag_dei_change_en = 1; + hw_act->bf.ctag_dei = rule->ctag_cfi; + } + if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_REMARK_DSCP)) + { + hw_act->bf.dscp_tc_change_en = 1; + hw_act->bf.dscp_tc = rule->dscp; +#if defined(CPPE) + if(adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) + { + hw_act->bf.dscp_tc_mask = rule->dscp_mask; + } +#endif + } + if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_INT_DP)) + { + hw_act->bf.int_dp_change_en = 1; + hw_act->bf.int_dp = rule->int_dp; + } + if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_POLICER_EN)) + { + hw_act->bf.policer_en = 1; + hw_act->bf.policer_index = rule->policer_ptr; + } + if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_REMARK_QUEUE)) + { + hw_act->bf.qid_en = 1; + hw_act->bf.qid = rule->queue; + } + if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_ENQUEUE_PRI)) + { + hw_act->bf.enqueue_pri_change_en = 1; + hw_act->bf.enqueue_pri = rule->enqueue_pri; + } + if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_SERVICE_CODE)) + { + hw_act->bf.service_code_en = 1; + hw_act->bf.service_code_0 = rule->service_code&0x1; + hw_act->bf.service_code_1 = (rule->service_code>>1)&0x7f; + } + if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_SYN_TOGGLE)) + { + hw_act->bf.syn_toggle = 1; + } + if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_CPU_CODE)) + { + hw_act->bf.cpu_code_en = 1; + hw_act->bf.cpu_code = rule->cpu_code; + } + if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_METADATA_EN)) + { + hw_act->bf.metadata_en = 1; + } +#if defined(CPPE) + if(adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) + { + hw_act->bf.qos_res_prec = rule->qos_res_prec; + } +#endif + return SW_OK; +} + +sw_error_t +_adpt_hppe_acl_rule_hw_add(a_uint32_t dev_id, ADPT_HPPE_ACL_SW_LIST *list_entry, + a_uint32_t hw_list_id, a_uint32_t rule_id, a_uint32_t rule_nr, + fal_acl_rule_t * rule, a_uint32_t rule_type_map, a_uint32_t allocated_entries) +{ + union ipo_rule_reg_u hw_reg = {0}; + union ipo_mask_reg_u hw_mask = {0}; + union ipo_action_u hw_act = {0}; + sw_error_t rv = 0; + a_uint32_t hw_entry = 0; + a_uint32_t i = 0; + + hw_reg.bf.post_routing_en = rule->post_routing; + hw_reg.bf.res_chain = rule->acl_pool; + hw_reg.bf.pri = ((list_entry->list_pri)<<3)|rule->pri; + + for( i = 0; i < ADPT_ACL_HPPE_RULE_TYPE_NUM; i++) + { + if(!((1<field_flg, FAL_ACL_FIELD_INVERSE_ALL)) + { + hw_reg.bf.inverse_en = 1; + } + + SSDK_DEBUG("rule and mask set hw_entry = %d\n", + hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_entry); + SSDK_DEBUG("post_route %d, chain %d, pri %d, src_1 %d, src_0 %d, src_type %d " + "rule_type %d, inverse %d, range %d\n", hw_reg.bf.post_routing_en, + hw_reg.bf.res_chain, hw_reg.bf.pri, hw_reg.bf.src_1, hw_reg.bf.src_0, + hw_reg.bf.src_type, hw_reg.bf.rule_type, hw_reg.bf.inverse_en, + hw_reg.bf.range_en); + /*_adpt_acl_reg_dump((a_uint8_t *)&hw_reg, sizeof(hw_reg));*/ + rv |= hppe_ipo_rule_reg_set(dev_id, hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_entry, + &hw_reg); + /*_adpt_acl_reg_dump((a_uint8_t *)&hw_mask, sizeof(hw_mask));*/ + rv |= hppe_ipo_mask_reg_set(dev_id, hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_entry, + &hw_mask); + _adpt_hppe_acl_action_sw_2_hw(dev_id,rule, &hw_act); + /*_adpt_acl_reg_dump((a_uint8_t *)&hw_act, sizeof(hw_act));*/ + rv |= hppe_ipo_action_set(dev_id, hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_entry, + &hw_act); + + if(rv != SW_OK) + { + return rv; + } + } + + return SW_OK; +} + +static sw_error_t +_adpt_hppe_acl_hw_list_resort(a_uint32_t dev_id, a_uint32_t hw_list_index, a_bool_t move_up) +{ + a_uint32_t i = 0; + ADPT_HPPE_ACL_HW_LIST temp = {0}; + + if(hw_list_index >= ADPT_ACL_HW_LIST_NUM) + { + return SW_OUT_OF_RANGE; + } + + if(move_up) + { + temp.hw_list_id = g_acl_hw_list[dev_id][hw_list_index].hw_list_id; + temp.free_hw_entry_bitmap = + g_acl_hw_list[dev_id][hw_list_index].free_hw_entry_bitmap; + temp.free_hw_entry_count = + g_acl_hw_list[dev_id][hw_list_index].free_hw_entry_count; + for(i = hw_list_index; i > 0; i--) + { + if(temp.free_hw_entry_count < + g_acl_hw_list[dev_id][i-1].free_hw_entry_count) + { + g_acl_hw_list[dev_id][i].hw_list_id = + g_acl_hw_list[dev_id][i-1].hw_list_id; + g_acl_hw_list[dev_id][i].free_hw_entry_bitmap = + g_acl_hw_list[dev_id][i-1].free_hw_entry_bitmap; + g_acl_hw_list[dev_id][i].free_hw_entry_count = + g_acl_hw_list[dev_id][i-1].free_hw_entry_count; + } + else + { + break; + } + } + g_acl_hw_list[dev_id][i].hw_list_id = temp.hw_list_id; + g_acl_hw_list[dev_id][i].free_hw_entry_bitmap = temp.free_hw_entry_bitmap; + g_acl_hw_list[dev_id][i].free_hw_entry_count = temp.free_hw_entry_count; + } + else + { + temp.hw_list_id = g_acl_hw_list[dev_id][hw_list_index].hw_list_id; + temp.free_hw_entry_bitmap = + g_acl_hw_list[dev_id][hw_list_index].free_hw_entry_bitmap; + temp.free_hw_entry_count = + g_acl_hw_list[dev_id][hw_list_index].free_hw_entry_count; + for(i = hw_list_index; i < ADPT_ACL_HW_LIST_NUM-1; i++) + { + if(temp.free_hw_entry_count > + g_acl_hw_list[dev_id][i+1].free_hw_entry_count) + { + g_acl_hw_list[dev_id][i].hw_list_id = + g_acl_hw_list[dev_id][i+1].hw_list_id; + g_acl_hw_list[dev_id][i].free_hw_entry_bitmap = + g_acl_hw_list[dev_id][i+1].free_hw_entry_bitmap; + g_acl_hw_list[dev_id][i].free_hw_entry_count = + g_acl_hw_list[dev_id][i+1].free_hw_entry_count; + } + else + { + break; + } + } + g_acl_hw_list[dev_id][i].hw_list_id = temp.hw_list_id; + g_acl_hw_list[dev_id][i].free_hw_entry_bitmap = temp.free_hw_entry_bitmap; + g_acl_hw_list[dev_id][i].free_hw_entry_count = temp.free_hw_entry_count; + } + return SW_OK; +} + +sw_error_t +adpt_hppe_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) +{ + a_uint32_t rule_type_map = 0; + a_uint32_t rule_type_count = 0; + a_uint32_t index = 0, hw_list_index = 0, hw_list_id = 0; + sw_error_t rv = 0; + union rule_ext_1_reg_u ext_1 = {0}; + union rule_ext_2_reg_u ext_2 = {0}; + union rule_ext_4_reg_u ext_4 = {0}; + struct list_head *rule_pos = NULL; + ADPT_HPPE_ACL_SW_RULE *rule_exist_entry = NULL, *rule_add_entry = NULL; + ADPT_HPPE_ACL_SW_LIST *list_find_entry = NULL; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(rule); + + if(list_id >= ADPT_ACL_SW_LIST_NUM) + { + return SW_OUT_OF_RANGE; + } + + if(rule_id >= ADPT_ACL_RULE_NUM_PER_LIST) + { + return SW_OUT_OF_RANGE; + } + + aos_lock_bh(&hppe_acl_lock[dev_id]); + list_find_entry = _adpt_hppe_acl_list_entry_get(dev_id, list_id); + if(list_find_entry == NULL) + { + SSDK_ERROR("List %d not create, no resource to insert rules into it\n", list_id); + aos_unlock_bh(&hppe_acl_lock[dev_id]); + return SW_NO_RESOURCE; + } + + list_for_each(rule_pos, &list_find_entry->list_sw_rule) + { + rule_exist_entry = list_entry(rule_pos, ADPT_HPPE_ACL_SW_RULE, list); + if((rule_exist_entry->rule_id == rule_id) && (rule_exist_entry->rule_hw_entry != 0)) + { + aos_unlock_bh(&hppe_acl_lock[dev_id]); + return SW_ALREADY_EXIST; + } + } + + SSDK_DEBUG("fields[0] = 0x%x, fields[1] = 0x%x\n", + rule->field_flg[0], rule->field_flg[1]); + if(rule->rule_type == FAL_ACL_RULE_IP4)/*input ipv4 type*/ + { + _adpt_hppe_acl_ipv4_fields_check(dev_id, list_id, rule_id, rule_nr, rule, + &rule_type_map); + } + else if(rule->rule_type == FAL_ACL_RULE_IP6)/*input ipv6 type*/ + { + _adpt_hppe_acl_ipv6_fields_check(dev_id, list_id, rule_id, rule_nr, rule, + &rule_type_map); + } + _adpt_hppe_acl_udf_fields_check(dev_id, list_id, rule_id, rule_nr, rule, &rule_type_map); + _adpt_hppe_acl_l2_fields_check(dev_id, list_id, rule_id, rule_nr, rule, &rule_type_map); + + if(rule_type_map == 0) + { + rule_type_map |= (1< ADPT_ACL_ENTRY_NUM_PER_LIST) + { + SSDK_ERROR("rule_type_count = %d\n", rule_type_count); + aos_unlock_bh(&hppe_acl_lock[dev_id]); + return SW_NOT_SUPPORTED; + } + + rv = _adpt_hppe_acl_alloc_entries(dev_id, &hw_list_index, rule_id, rule_nr, rule, + rule_type_map, rule_type_count, &index); + if(rv != SW_OK) + { + SSDK_ERROR("Alloc hw entries fail for rule %d\n", rule_id); + aos_unlock_bh(&hppe_acl_lock[dev_id]); + return rv; + } + /* msg for debug */ + SSDK_DEBUG("ACL rule add before:list_id=%d, hw_list_index=%d, hw_list_id=%d, " + "free_hw_entry_bitmap=0x%x, free_hw_entry_count=%d\n", list_id, hw_list_index, + g_acl_hw_list[dev_id][hw_list_index].hw_list_id, + g_acl_hw_list[dev_id][hw_list_index].free_hw_entry_bitmap, + g_acl_hw_list[dev_id][hw_list_index].free_hw_entry_count); + + hw_list_id = g_acl_hw_list[dev_id][hw_list_index].hw_list_id; + rv = _adpt_hppe_acl_rule_hw_add(dev_id, list_find_entry, hw_list_id, rule_id, rule_nr, rule, + rule_type_map, s_acl_entries[index].entries); + if(rv != SW_OK) + { + aos_unlock_bh(&hppe_acl_lock[dev_id]); + return rv; + } + + if(s_acl_entries[index].ext_1 != 0) + { + rv |= hppe_rule_ext_1_reg_get(dev_id, hw_list_id, &ext_1); + ext_1.val |= s_acl_entries[index].ext_1; + SSDK_DEBUG("ext_1.val = 0x%x\n", ext_1.val); + rv |= hppe_rule_ext_1_reg_set(dev_id, hw_list_id, &ext_1); + } + if(s_acl_entries[index].ext_2 != 0) + { + rv |= hppe_rule_ext_2_reg_get(dev_id, hw_list_id, &ext_2); + ext_2.val |= s_acl_entries[index].ext_2; + SSDK_DEBUG("ext_2.val = 0x%x\n", ext_2.val); + rv |= hppe_rule_ext_2_reg_set(dev_id, hw_list_id, &ext_2); + } + if(s_acl_entries[index].ext_4 != 0) + { + rv |= hppe_rule_ext_4_reg_get(dev_id, hw_list_id, &ext_4); + ext_4.val |= s_acl_entries[index].ext_4; + SSDK_DEBUG("ext_4.val = 0x%x\n", ext_4.val); + rv |= hppe_rule_ext_4_reg_set(dev_id, hw_list_id, &ext_4); + } + + /*record sw info and insert the sw rule entry to the sw list entry*/ + rule_add_entry = (ADPT_HPPE_ACL_SW_RULE*)aos_mem_alloc(sizeof(ADPT_HPPE_ACL_SW_RULE)); + if(rule_add_entry == NULL) + { + SSDK_ERROR("%s, %d:malloc fail for rule add entry\n", __FUNCTION__, __LINE__); + aos_unlock_bh(&hppe_acl_lock[dev_id]); + return SW_FAIL; + } + rule_add_entry->rule_id = rule_id; + rule_add_entry->rule_type = rule->rule_type; + rule_add_entry->rule_hw_entry = s_acl_entries[index].entries; + rule_add_entry->rule_hw_list_id = hw_list_id; + rule_add_entry->ext1_val = s_acl_entries[index].ext_1; + rule_add_entry->ext2_val = s_acl_entries[index].ext_2; + rule_add_entry->ext4_val = s_acl_entries[index].ext_4; + list_add(&rule_add_entry->list, &list_find_entry->list_sw_rule); + + /*update hw list info */ + g_acl_hw_list[dev_id][hw_list_index].free_hw_entry_bitmap &= + (~(s_acl_entries[index].entries)); + g_acl_hw_list[dev_id][hw_list_index].free_hw_entry_count -= s_acl_entries[index].num; + + /* msg for debug */ + SSDK_DEBUG("ACL rule add after:list_id=%d, hw_list_index=%d, hw_list_id=%d, " + "free_hw_entry_bitmap=0x%x, free_hw_entry_count=%d\n", list_id, hw_list_index, + hw_list_id, g_acl_hw_list[dev_id][hw_list_index].free_hw_entry_bitmap, + g_acl_hw_list[dev_id][hw_list_index].free_hw_entry_count); + /*resort hw list */ + _adpt_hppe_acl_hw_list_resort(dev_id, hw_list_index, A_TRUE); + + aos_unlock_bh(&hppe_acl_lock[dev_id]); + return SW_OK; +} + +static sw_error_t +_adpt_hppe_acl_rule_delete(a_uint32_t dev_id, a_uint32_t list_id, + ADPT_HPPE_ACL_SW_RULE *rule_entry, a_uint32_t rule_nr) +{ + sw_error_t rv = 0; + a_uint32_t hw_index = 0, hw_entries = 0, hw_list_id = 0, hw_list_index = 0, i = 0; + union ipo_rule_reg_u hw_reg = {0}; + union ipo_mask_reg_u hw_mask = {0}; + union ipo_action_u hw_act = {0}; + union rule_ext_1_reg_u ext_1 = {0}; + union rule_ext_2_reg_u ext_2 = {0}; + union rule_ext_4_reg_u ext_4 = {0}; + + hw_entries = rule_entry->rule_hw_entry; + hw_list_id = rule_entry->rule_hw_list_id; + /* msg for debug */ + SSDK_DEBUG("ACL delete rule entry before:list_id=%d, rule_id=%d, " + "hw_entries=0x%x, hw_list_id=%d\n", list_id, + rule_entry->rule_id, rule_entry->rule_hw_entry, + rule_entry->rule_hw_list_id); + while(hw_entries != 0) + { + union ipo_cnt_tbl_u counters = {0}; + hw_index = _acl_bit_index(hw_entries, ADPT_ACL_ENTRY_NUM_PER_LIST, 0); + if(hw_index >= ADPT_ACL_ENTRY_NUM_PER_LIST) + { + break; + } + + rv |= hppe_ipo_rule_reg_set(dev_id, + hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_index, &hw_reg); + rv |= hppe_ipo_mask_reg_set(dev_id, + hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_index, &hw_mask); + rv |= hppe_ipo_action_set(dev_id, + hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_index, &hw_act); + SSDK_DEBUG("ACL destroy entry %d\n", + hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_index); + hw_entries &= (~(1<ext1_val) + { + rv |= hppe_rule_ext_1_reg_get(dev_id, hw_list_id, &ext_1); + ext_1.val &= (~rule_entry->ext1_val); + SSDK_DEBUG("ext_1.val = 0x%x\n", ext_1.val); + rv |= hppe_rule_ext_1_reg_set(dev_id, hw_list_id, &ext_1); + } + if(rule_entry->ext2_val) + { + rv |= hppe_rule_ext_2_reg_get(dev_id, hw_list_id, &ext_2); + ext_2.val &= (~rule_entry->ext2_val); + SSDK_DEBUG("ext_2.val = 0x%x\n", ext_2.val); + rv |= hppe_rule_ext_2_reg_set(dev_id, hw_list_id, &ext_2); + } + if(rule_entry->ext4_val) + { + rv |= hppe_rule_ext_4_reg_get(dev_id, hw_list_id, &ext_4); + ext_4.val &= (~rule_entry->ext4_val); + SSDK_DEBUG("ext_4.val = 0x%x\n", ext_4.val); + rv |= hppe_rule_ext_4_reg_set(dev_id, hw_list_id, &ext_4); + } + + /*find hw_list_index*/ + for(i = 0; i < ADPT_ACL_HW_LIST_NUM; i++) + { + if(g_acl_hw_list[dev_id][i].hw_list_id == hw_list_id) + { + hw_list_index = i; + break; + } + } + + /*update hw list info and resort hw list*/ + g_acl_hw_list[dev_id][hw_list_index].free_hw_entry_bitmap |= rule_entry->rule_hw_entry; + g_acl_hw_list[dev_id][hw_list_index].free_hw_entry_count += + _acl_bits_count(rule_entry->rule_hw_entry, ADPT_ACL_ENTRY_NUM_PER_LIST, 0); + /* msg for debug */ + SSDK_DEBUG("ACL delete rule entry after:hw_list_index=%d, list_id=%d, " + "rule_id=%d, hw_entries=0x%x, hw_list_id=%d\n", hw_list_index, + list_id, rule_entry->rule_id, rule_entry->rule_hw_entry, + rule_entry->rule_hw_list_id); + _adpt_hppe_acl_hw_list_resort(dev_id, hw_list_index, A_FALSE); + + /*delete rule entry from the sw list*/ + list_del(&rule_entry->list); + aos_mem_free(rule_entry); + rule_entry = NULL; + + return rv; +} + +sw_error_t +adpt_hppe_acl_rule_delete(a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t rule_id, a_uint32_t rule_nr) +{ + struct list_head *rule_pos = NULL; + ADPT_HPPE_ACL_SW_RULE *rule_delete_entry = NULL; + ADPT_HPPE_ACL_SW_LIST *list_find_entry = NULL; + + ADPT_DEV_ID_CHECK(dev_id); + + if(list_id >= ADPT_ACL_SW_LIST_NUM) + { + return SW_OUT_OF_RANGE; + } + + if(rule_id >= ADPT_ACL_RULE_NUM_PER_LIST) + { + return SW_OUT_OF_RANGE; + } + + aos_lock_bh(&hppe_acl_lock[dev_id]); + list_find_entry = _adpt_hppe_acl_list_entry_get(dev_id, list_id); + if(list_find_entry != NULL) + { + list_for_each(rule_pos, &list_find_entry->list_sw_rule) + { + rule_delete_entry = list_entry(rule_pos, ADPT_HPPE_ACL_SW_RULE, list); + if(rule_delete_entry->rule_id == rule_id) + { + _adpt_hppe_acl_rule_delete(dev_id, list_id, + rule_delete_entry, rule_nr); + break; + } + } + } + aos_unlock_bh(&hppe_acl_lock[dev_id]); + return SW_OK; +} + +static sw_error_t +_adpt_hppe_acl_rule_dump(a_uint32_t dev_id, a_uint32_t list_id, ADPT_HPPE_ACL_SW_RULE *rule_entry) +{ + a_uint8_t i = 0; + a_uint8_t hw_entries = rule_entry->rule_hw_entry; + a_uint32_t hw_list_id = rule_entry->rule_hw_list_id; + union ipo_rule_reg_u hw_reg = {0}; + union ipo_mask_reg_u hw_mask = {0}; + union ipo_action_u hw_act = {0}; + + if(hw_entries != 0) + { + printk("######list_id %d, rule_id %d, hw_list_id %d\n", list_id, + rule_entry->rule_id, hw_list_id); + for(i = 0; i < ADPT_ACL_ENTRY_NUM_PER_LIST; i++) + { + if((1<list_sw_rule) + { + rule_dump_entry = list_entry(rule_pos, ADPT_HPPE_ACL_SW_RULE, list); + _adpt_hppe_acl_rule_dump(dev_id, list_dump_entry->list_id, rule_dump_entry); + } + } + aos_unlock_bh(&hppe_acl_lock[dev_id]); + return SW_OK; +} + +sw_error_t +adpt_hppe_acl_list_dump(a_uint32_t dev_id) +{ + adpt_hppe_acl_rule_dump(dev_id); + + return SW_OK; +} + + +sw_error_t +adpt_hppe_acl_list_creat(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t list_pri) +{ + ADPT_HPPE_ACL_SW_LIST *list_create_entry = NULL; + + ADPT_DEV_ID_CHECK(dev_id); + + if(list_id >= ADPT_ACL_SW_LIST_NUM) + { + return SW_OUT_OF_RANGE; + } + + aos_lock_bh(&hppe_acl_lock[dev_id]); + list_create_entry = _adpt_hppe_acl_list_entry_get(dev_id, list_id); + if(list_create_entry != NULL) + { + aos_unlock_bh(&hppe_acl_lock[dev_id]); + return SW_ALREADY_EXIST; + } + + list_create_entry = (ADPT_HPPE_ACL_SW_LIST*)aos_mem_alloc(sizeof(ADPT_HPPE_ACL_SW_LIST)); + if(list_create_entry == NULL) + { + SSDK_ERROR("%s, %d:malloc fail for list create entry\n", __FUNCTION__, __LINE__); + aos_unlock_bh(&hppe_acl_lock[dev_id]); + return SW_FAIL; + } + INIT_LIST_HEAD(&list_create_entry->list_sw_rule); + list_create_entry->list_id = list_id; + list_create_entry->list_pri = list_pri; + list_add(&list_create_entry->list, &g_acl_sw_list[dev_id].list_sw_list); + aos_unlock_bh(&hppe_acl_lock[dev_id]); + return SW_OK; +} + +sw_error_t +adpt_hppe_acl_list_destroy(a_uint32_t dev_id, a_uint32_t list_id) +{ + struct list_head *rule_pos=NULL, *rule_pos_temp = NULL; + ADPT_HPPE_ACL_SW_RULE *rule_delete_entry = NULL; + ADPT_HPPE_ACL_SW_LIST *list_destroy_entry = NULL; + + ADPT_DEV_ID_CHECK(dev_id); + + if(list_id >= ADPT_ACL_SW_LIST_NUM) + { + return SW_OUT_OF_RANGE; + } + + aos_lock_bh(&hppe_acl_lock[dev_id]); + list_destroy_entry = _adpt_hppe_acl_list_entry_get(dev_id, list_id); + if(list_destroy_entry != NULL) + { + list_for_each_safe(rule_pos, rule_pos_temp, &list_destroy_entry->list_sw_rule) + { + rule_delete_entry = list_entry(rule_pos, ADPT_HPPE_ACL_SW_RULE, list); + _adpt_hppe_acl_rule_delete(dev_id, list_id, rule_delete_entry, 1); + } + list_del(&list_destroy_entry->list); + aos_mem_free(list_destroy_entry); + list_destroy_entry = NULL; + } + aos_unlock_bh(&hppe_acl_lock[dev_id]); + return SW_OK; +} + +typedef sw_error_t (*hppe_acl_udp_set_func)(a_uint32_t dev_id, union udf_ctrl_reg_u *udf_ctrl); +typedef sw_error_t (*hppe_acl_udp_get_func)(a_uint32_t dev_id, union udf_ctrl_reg_u *udf_ctrl); + +hppe_acl_udp_set_func g_udf_set_func[FAL_ACL_UDF_BUTT][4] = { + {hppe_non_ip_udf0_ctrl_reg_set, hppe_non_ip_udf1_ctrl_reg_set, + hppe_non_ip_udf2_ctrl_reg_set, hppe_non_ip_udf3_ctrl_reg_set}, + {hppe_ipv4_udf0_ctrl_reg_set, hppe_ipv4_udf1_ctrl_reg_set, hppe_ipv4_udf2_ctrl_reg_set, + hppe_ipv4_udf3_ctrl_reg_set}, + {hppe_ipv6_udf0_ctrl_reg_set, hppe_ipv6_udf1_ctrl_reg_set, hppe_ipv6_udf2_ctrl_reg_set, + hppe_ipv6_udf3_ctrl_reg_set}, +}; + +hppe_acl_udp_get_func g_udf_get_func[FAL_ACL_UDF_BUTT][4] = { + {hppe_non_ip_udf0_ctrl_reg_get, hppe_non_ip_udf1_ctrl_reg_get, + hppe_non_ip_udf2_ctrl_reg_get, hppe_non_ip_udf3_ctrl_reg_get}, + {hppe_ipv4_udf0_ctrl_reg_get, hppe_ipv4_udf1_ctrl_reg_get, hppe_ipv4_udf2_ctrl_reg_get, + hppe_ipv4_udf3_ctrl_reg_get}, + {hppe_ipv6_udf0_ctrl_reg_get, hppe_ipv6_udf1_ctrl_reg_get, hppe_ipv6_udf2_ctrl_reg_get, + hppe_ipv6_udf3_ctrl_reg_get}, +}; + +sw_error_t +adpt_hppe_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) +{ + union udf_ctrl_reg_u udf_ctrl = {0}; + sw_error_t rv = SW_OK; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(udf_type); + ADPT_NULL_POINT_CHECK(offset); + + rv = g_udf_get_func[pkt_type][udf_idx](dev_id, &udf_ctrl); + + if(rv != SW_OK) + return rv; + + if(udf_ctrl.bf.udf_base == 0) + { + *udf_type = FAL_ACL_UDF_TYPE_L2; + } + else if(udf_ctrl.bf.udf_base == 1) + { + *udf_type = FAL_ACL_UDF_TYPE_L3; + } + else if(udf_ctrl.bf.udf_base == 2) + { + *udf_type = FAL_ACL_UDF_TYPE_L4; + } + + *offset = udf_ctrl.bf.udf_offset*2; + + return SW_OK; +} + + +sw_error_t +adpt_hppe_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) +{ + union udf_ctrl_reg_u udf_ctrl = {0}; + ADPT_DEV_ID_CHECK(dev_id); + + if(udf_type == FAL_ACL_UDF_TYPE_L2) + { + udf_ctrl.bf.udf_base = 0; + } + else if(udf_type == FAL_ACL_UDF_TYPE_L3) + { + udf_ctrl.bf.udf_base = 1; + } + else if(udf_type == FAL_ACL_UDF_TYPE_L4) + { + udf_ctrl.bf.udf_base = 2; + } + else + return SW_NOT_SUPPORTED; + + if(offset % 2)/*only support even data*/ + return SW_BAD_VALUE; + udf_ctrl.bf.udf_offset = offset/2; + + return g_udf_set_func[pkt_type][udf_idx](dev_id, &udf_ctrl); +} + +void adpt_hppe_acl_func_bitmap_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_acl_func_bitmap = ((1<adpt_acl_list_creat = NULL; + p_adpt_api->adpt_acl_list_destroy = NULL; + p_adpt_api->adpt_acl_rule_add = NULL; + p_adpt_api->adpt_acl_rule_delete = NULL; + p_adpt_api->adpt_acl_rule_query = NULL; + p_adpt_api->adpt_acl_rule_dump = NULL; + p_adpt_api->adpt_acl_list_dump = NULL; + p_adpt_api->adpt_acl_list_bind = NULL; + p_adpt_api->adpt_acl_list_unbind = NULL; + p_adpt_api->adpt_acl_udf_profile_set = NULL; + p_adpt_api->adpt_acl_udf_profile_get = NULL; + + return; +} + +sw_error_t adpt_hppe_acl_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + a_uint8_t hw_list_index = 0; + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + { + return SW_FAIL; + } + + for(hw_list_index = 0; hw_list_index < ADPT_ACL_HW_LIST_NUM; hw_list_index++) + { + if(g_acl_hw_list[dev_id][hw_list_index].hw_list_valid == A_FALSE) + { + g_acl_hw_list[dev_id][hw_list_index].free_hw_entry_bitmap = 0xff; + g_acl_hw_list[dev_id][hw_list_index].free_hw_entry_count = + ADPT_ACL_ENTRY_NUM_PER_LIST; + g_acl_hw_list[dev_id][hw_list_index].hw_list_id = + ADPT_ACL_HW_LIST_NUM - 1 - hw_list_index; + g_acl_hw_list [dev_id][hw_list_index].hw_list_valid = A_TRUE; + INIT_LIST_HEAD(&g_acl_sw_list[dev_id].list_sw_list); + } + } + + adpt_hppe_acl_func_unregister(dev_id, p_adpt_api); + + if(p_adpt_api->adpt_acl_func_bitmap & (1<adpt_acl_list_bind = adpt_hppe_acl_list_bind; + } + if(p_adpt_api->adpt_acl_func_bitmap & (1<adpt_acl_list_dump = adpt_hppe_acl_list_dump; + } + if(p_adpt_api->adpt_acl_func_bitmap & (1<adpt_acl_rule_query = adpt_hppe_acl_rule_query; + } + if(p_adpt_api->adpt_acl_func_bitmap & (1<adpt_acl_list_unbind = adpt_hppe_acl_list_unbind; + } + if(p_adpt_api->adpt_acl_func_bitmap & (1<adpt_acl_rule_add = adpt_hppe_acl_rule_add; + } + if(p_adpt_api->adpt_acl_func_bitmap & (1<adpt_acl_rule_delete = adpt_hppe_acl_rule_delete; + } + if(p_adpt_api->adpt_acl_func_bitmap & (1<adpt_acl_rule_dump = adpt_hppe_acl_rule_dump; + } + if(p_adpt_api->adpt_acl_func_bitmap & (1<adpt_acl_list_creat = adpt_hppe_acl_list_creat; + } + if(p_adpt_api->adpt_acl_func_bitmap & (1<adpt_acl_list_destroy = adpt_hppe_acl_list_destroy; + } + if(p_adpt_api->adpt_acl_func_bitmap & (1<adpt_acl_udf_profile_set = adpt_hppe_acl_udf_profile_set; + } + if(p_adpt_api->adpt_acl_func_bitmap & (1<adpt_acl_udf_profile_get = adpt_hppe_acl_udf_profile_get; + } + + aos_lock_init(&hppe_acl_lock[dev_id]); + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_bm.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_bm.c new file mode 100755 index 000000000..1c6f08782 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_bm.c @@ -0,0 +1,452 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "fal_bm.h" +#include "hppe_bm_reg.h" +#include "hppe_bm.h" +#include "hppe_portctrl_reg.h" +#include "hppe_portctrl.h" +#include "adpt.h" + +#ifndef IN_BM_MINI +sw_error_t +adpt_hppe_port_bufgroup_map_get(a_uint32_t dev_id, fal_port_t port, + a_uint8_t *group) +{ + sw_error_t rv = SW_OK; + union port_group_id_u port_group_id; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(group); + memset(&port_group_id, 0, sizeof(port_group_id)); + + rv = hppe_port_group_id_get(dev_id, port, &port_group_id); + if( rv != SW_OK ) + return rv; + + *group = port_group_id.bf.port_shared_group_id; + + return SW_OK; +} + +sw_error_t +adpt_hppe_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 = SW_OK; + union port_fc_cfg_u port_fc_cfg; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(prealloc_buff); + ADPT_NULL_POINT_CHECK(react_buff); + memset(&port_fc_cfg, 0, sizeof(port_fc_cfg)); + + rv = hppe_port_fc_cfg_get(dev_id, port, &port_fc_cfg); + if (rv) + return rv; + + *prealloc_buff = port_fc_cfg.bf.port_pre_alloc; + *react_buff = port_fc_cfg.bf.port_react_limit; + + return SW_OK; +} + +sw_error_t +adpt_hppe_bm_bufgroup_buffer_get(a_uint32_t dev_id, a_uint8_t group, + a_uint16_t *buff_num) +{ + sw_error_t rv = SW_OK; + union shared_group_cfg_u shared_group_cfg; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(buff_num); + memset(&shared_group_cfg, 0, sizeof(shared_group_cfg)); + + rv = hppe_shared_group_cfg_get(dev_id, group, &shared_group_cfg); + if( rv != SW_OK ) + return rv; + + *buff_num = shared_group_cfg.bf.shared_group_limit; + + return SW_OK; +} + +sw_error_t +adpt_hppe_bm_port_dynamic_thresh_get(a_uint32_t dev_id, fal_port_t port, + fal_bm_dynamic_cfg_t *cfg) +{ + sw_error_t rv = SW_OK; + union port_fc_cfg_u port_fc_cfg; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cfg); + memset(&port_fc_cfg, 0, sizeof(port_fc_cfg)); + + rv = hppe_port_fc_cfg_get(dev_id, port, &port_fc_cfg); + if( rv != SW_OK ) + return rv; + + if (!port_fc_cfg.bf.port_shared_dynamic) + return SW_FAIL; + + cfg->weight = port_fc_cfg.bf.port_shared_weight; + cfg->shared_ceiling = port_fc_cfg.bf.port_shared_ceiling_0 | + port_fc_cfg.bf.port_shared_ceiling_1 << 3; + cfg->resume_off = port_fc_cfg.bf.port_resume_offset; + cfg->resume_min_thresh = port_fc_cfg.bf.port_resume_floor_th; + + return SW_OK; +} + +sw_error_t +adpt_hppe_port_bm_ctrl_get(a_uint32_t dev_id, fal_port_t port, a_bool_t *enable) +{ + sw_error_t rv = SW_OK; + union port_fc_mode_u port_fc_mode; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + memset(&port_fc_mode, 0, sizeof(port_fc_mode)); + + rv = hppe_port_fc_mode_get(dev_id, port, &port_fc_mode); + if( rv != SW_OK ) + return rv; + + *enable = port_fc_mode.bf.fc_en; + + return SW_OK; +} +#endif + +sw_error_t +adpt_hppe_bm_bufgroup_buffer_set(a_uint32_t dev_id, a_uint8_t group, + a_uint16_t buff_num) +{ + sw_error_t rv = SW_OK; + union shared_group_cfg_u shared_group_cfg; + + ADPT_DEV_ID_CHECK(dev_id); + memset(&shared_group_cfg, 0, sizeof(shared_group_cfg)); + + shared_group_cfg.bf.shared_group_limit = buff_num; + rv = hppe_shared_group_cfg_set(dev_id, group, &shared_group_cfg); + if( rv != SW_OK ) + return rv; + + return SW_OK; +} + +sw_error_t +adpt_hppe_port_bufgroup_map_set(a_uint32_t dev_id, fal_port_t port, + a_uint8_t group) +{ + sw_error_t rv = SW_OK; + union port_group_id_u port_group_id; + + ADPT_DEV_ID_CHECK(dev_id); + memset(&port_group_id, 0, sizeof(port_group_id)); + + port_group_id.bf.port_shared_group_id = group; + rv = hppe_port_group_id_set(dev_id, port, &port_group_id); + if( rv != SW_OK ) + return rv; + + return SW_OK; +} + +#ifndef IN_BM_MINI +sw_error_t +adpt_hppe_bm_port_static_thresh_get(a_uint32_t dev_id, fal_port_t port, + fal_bm_static_cfg_t *cfg) +{ + sw_error_t rv = SW_OK; + union port_fc_cfg_u port_fc_cfg; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cfg); + memset(&port_fc_cfg, 0, sizeof(port_fc_cfg)); + + rv = hppe_port_fc_cfg_get(dev_id, port, &port_fc_cfg); + if( rv != SW_OK ) + return rv; + + if (port_fc_cfg.bf.port_shared_dynamic) + return SW_FAIL; + + cfg->resume_off = port_fc_cfg.bf.port_resume_offset; + cfg->max_thresh = port_fc_cfg.bf.port_shared_ceiling_0 | + port_fc_cfg.bf.port_shared_ceiling_1 << 3; + + return SW_OK; +} +#endif + +sw_error_t +adpt_hppe_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 = SW_OK; + union port_fc_cfg_u port_fc_cfg; + + ADPT_DEV_ID_CHECK(dev_id); + memset(&port_fc_cfg, 0, sizeof(port_fc_cfg)); + + rv = hppe_port_fc_cfg_get(dev_id, port, &port_fc_cfg); + if (rv) + return rv; + + port_fc_cfg.bf.port_pre_alloc = prealloc_buff; + port_fc_cfg.bf.port_react_limit = react_buff; + + return hppe_port_fc_cfg_set(dev_id, port, &port_fc_cfg); +} + +sw_error_t +adpt_hppe_bm_port_static_thresh_set(a_uint32_t dev_id, fal_port_t port, + fal_bm_static_cfg_t *cfg) +{ + sw_error_t rv = SW_OK; + union port_fc_cfg_u port_fc_cfg; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cfg); + memset(&port_fc_cfg, 0, sizeof(port_fc_cfg)); + + rv = hppe_port_fc_cfg_get(dev_id, port, &port_fc_cfg); + if( rv != SW_OK ) + return rv; + + port_fc_cfg.bf.port_resume_offset = cfg->resume_off; + port_fc_cfg.bf.port_shared_ceiling_0 = cfg->max_thresh; + port_fc_cfg.bf.port_shared_ceiling_1 = cfg->max_thresh >> 3; + port_fc_cfg.bf.port_shared_dynamic = 0; + + return hppe_port_fc_cfg_set(dev_id, port, &port_fc_cfg);; +} + +sw_error_t +adpt_hppe_bm_port_dynamic_thresh_set(a_uint32_t dev_id, fal_port_t port, + fal_bm_dynamic_cfg_t *cfg) +{ + sw_error_t rv = SW_OK; + union port_fc_cfg_u port_fc_cfg; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cfg); + memset(&port_fc_cfg, 0, sizeof(port_fc_cfg)); + + rv = hppe_port_fc_cfg_get(dev_id, port, &port_fc_cfg); + if( rv != SW_OK ) + return rv; + + port_fc_cfg.bf.port_shared_weight = cfg->weight; + port_fc_cfg.bf.port_shared_ceiling_0 = cfg->shared_ceiling; + port_fc_cfg.bf.port_shared_ceiling_1 = cfg->shared_ceiling >> 3; + port_fc_cfg.bf.port_resume_offset = cfg->resume_off; + port_fc_cfg.bf.port_resume_floor_th = cfg->resume_min_thresh; + port_fc_cfg.bf.port_shared_dynamic = 1; + + return hppe_port_fc_cfg_set(dev_id, port, &port_fc_cfg);; +} + +sw_error_t +adpt_hppe_port_bm_ctrl_set(a_uint32_t dev_id, fal_port_t port, a_bool_t enable) +{ + union port_fc_mode_u port_fc_mode; + + ADPT_DEV_ID_CHECK(dev_id); + memset(&port_fc_mode, 0, sizeof(port_fc_mode)); + + port_fc_mode.bf.fc_en = enable; + return hppe_port_fc_mode_set(dev_id, port, &port_fc_mode); +} + +sw_error_t +adpt_hppe_port_tdm_ctrl_set(a_uint32_t dev_id, fal_port_tdm_ctrl_t *ctrl) +{ + union tdm_ctrl_u tdm_ctrl; + + ADPT_DEV_ID_CHECK(dev_id); + memset(&tdm_ctrl, 0, sizeof(tdm_ctrl)); + + tdm_ctrl.bf.tdm_en = ctrl->enable; + tdm_ctrl.bf.tdm_offset = ctrl->offset; + tdm_ctrl.bf.tdm_depth = ctrl->depth; + return hppe_tdm_ctrl_set(dev_id, &tdm_ctrl); +} + +sw_error_t +adpt_hppe_port_tdm_tick_cfg_set(a_uint32_t dev_id, a_uint32_t tick_index, + fal_port_tdm_tick_cfg_t *cfg) +{ + union tdm_cfg_u tdm_cfg; + + ADPT_DEV_ID_CHECK(dev_id); + memset(&tdm_cfg, 0, sizeof(tdm_cfg)); + + tdm_cfg.bf.valid = cfg->valid; + tdm_cfg.bf.dir = cfg->direction; + tdm_cfg.bf.port_num = cfg->port; + return hppe_tdm_cfg_set(dev_id, tick_index, &tdm_cfg); +} + +#ifndef IN_BM_MINI +sw_error_t +adpt_hppe_bm_port_counter_get(a_uint32_t dev_id, fal_port_t port, + fal_bm_port_counter_t *counter) +{ + sw_error_t rv = SW_OK; + union port_cnt_u port_cnt; + union port_reacted_cnt_u reacted_cnt; + union drop_stat_u drop_stat; + a_uint32_t index = FAL_PORT_ID_VALUE(port); + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(counter); + memset(&port_cnt, 0, sizeof(port_cnt)); + memset(&reacted_cnt, 0, sizeof(reacted_cnt)); + + rv = hppe_port_cnt_get(dev_id, index, &port_cnt); + if( rv != SW_OK ) + return rv; + counter->used_counter = port_cnt.bf.port_cnt; + + rv = hppe_port_reacted_cnt_get(dev_id, index, &reacted_cnt); + if( rv != SW_OK ) + return rv; + counter->react_counter = reacted_cnt.bf.port_reacted_cnt; + + rv = hppe_drop_stat_get(dev_id, index, &drop_stat); + if( rv != SW_OK ) + return rv; + counter->drop_byte_counter = drop_stat.bf.bytes_0 | ((a_uint64_t)drop_stat.bf.bytes_1 << 32); + counter->drop_packet_counter = drop_stat.bf.pkts; + rv = hppe_drop_stat_get(dev_id, index + 15, &drop_stat); + if( rv != SW_OK ) + return rv; + counter->fc_drop_byte_counter = drop_stat.bf.bytes_0 | ((a_uint64_t)drop_stat.bf.bytes_1 << 32); + counter->fc_drop_packet_counter = drop_stat.bf.pkts; + + return SW_OK; +} +#endif + +void adpt_hppe_bm_func_bitmap_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_bm_func_bitmap = ((1 << FUNC_PORT_BUFGROUP_MAP_GET) | + (1 << FUNC_BM_PORT_RESERVED_BUFFER_GET) | + (1 << FUNC_BM_BUFGROUP_BUFFER_GET) | + (1 << FUNC_BM_PORT_DYNAMIC_THRESH_GET) | + (1 << FUNC_PORT_BM_CTRL_GET) | + (1 << FUNC_BM_BUFGROUP_BUFFER_SET) | + (1 << FUNC_PORT_BUFGROUP_MAP_SET) | + (1 << FUNC_BM_PORT_STATIC_THRESH_GET) | + (1 << FUNC_BM_PORT_RESERVED_BUFFER_SET) | + (1 << FUNC_BM_PORT_STATIC_THRESH_SET) | + (1 << FUNC_BM_PORT_DYNAMIC_THRESH_SET) | + (1 << FUNC_PORT_BM_CTRL_SET) | + (1 << FUNC_PORT_TDM_CTRL_SET) | + (1 << FUNC_PORT_TDM_TICK_CFG_SET) | + (1 << FUNC_BM_PORT_COUNTER_GET)); + return; +} + +static void adpt_hppe_bm_func_unregister(a_uint32_t dev_id, adpt_api_t *p_adpt_api) +{ + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_port_bufgroup_map_get = NULL; + p_adpt_api->adpt_bm_port_reserved_buffer_get = NULL; + p_adpt_api->adpt_bm_bufgroup_buffer_get = NULL; + p_adpt_api->adpt_bm_port_dynamic_thresh_get = NULL; + p_adpt_api->adpt_port_bm_ctrl_get = NULL; + p_adpt_api->adpt_bm_bufgroup_buffer_set = NULL; + p_adpt_api->adpt_port_bufgroup_map_set = NULL; + p_adpt_api->adpt_bm_port_static_thresh_get = NULL; + p_adpt_api->adpt_bm_port_reserved_buffer_set = NULL; + p_adpt_api->adpt_bm_port_static_thresh_set = NULL; + p_adpt_api->adpt_bm_port_dynamic_thresh_set = NULL; + p_adpt_api->adpt_port_bm_ctrl_set = NULL; + p_adpt_api->adpt_port_tdm_ctrl_set = NULL; + p_adpt_api->adpt_port_tdm_tick_cfg_set = NULL; + p_adpt_api->adpt_bm_port_counter_get = NULL; + + return; +} + + +sw_error_t adpt_hppe_bm_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return SW_FAIL; + + adpt_hppe_bm_func_unregister(dev_id, p_adpt_api); + +#ifndef IN_BM_MINI + if (p_adpt_api->adpt_bm_func_bitmap & (1 << FUNC_PORT_BUFGROUP_MAP_GET)) + p_adpt_api->adpt_port_bufgroup_map_get = adpt_hppe_port_bufgroup_map_get; + if (p_adpt_api->adpt_bm_func_bitmap & (1 << FUNC_BM_PORT_RESERVED_BUFFER_GET)) + p_adpt_api->adpt_bm_port_reserved_buffer_get = adpt_hppe_bm_port_reserved_buffer_get; + if (p_adpt_api->adpt_bm_func_bitmap & (1 << FUNC_BM_BUFGROUP_BUFFER_GET)) + p_adpt_api->adpt_bm_bufgroup_buffer_get = adpt_hppe_bm_bufgroup_buffer_get; + if (p_adpt_api->adpt_bm_func_bitmap & (1 << FUNC_BM_PORT_DYNAMIC_THRESH_GET)) + p_adpt_api->adpt_bm_port_dynamic_thresh_get = adpt_hppe_bm_port_dynamic_thresh_get; + if (p_adpt_api->adpt_bm_func_bitmap & (1 << FUNC_PORT_BM_CTRL_GET)) + p_adpt_api->adpt_port_bm_ctrl_get = adpt_hppe_port_bm_ctrl_get; + if (p_adpt_api->adpt_bm_func_bitmap & (1 << FUNC_BM_PORT_STATIC_THRESH_GET)) + p_adpt_api->adpt_bm_port_static_thresh_get = adpt_hppe_bm_port_static_thresh_get; + if (p_adpt_api->adpt_bm_func_bitmap & (1 << FUNC_BM_PORT_COUNTER_GET)) + p_adpt_api->adpt_bm_port_counter_get = adpt_hppe_bm_port_counter_get; +#endif + if (p_adpt_api->adpt_bm_func_bitmap & (1 << FUNC_BM_BUFGROUP_BUFFER_SET)) + p_adpt_api->adpt_bm_bufgroup_buffer_set = adpt_hppe_bm_bufgroup_buffer_set; + if (p_adpt_api->adpt_bm_func_bitmap & (1 << FUNC_PORT_BUFGROUP_MAP_SET)) + p_adpt_api->adpt_port_bufgroup_map_set = adpt_hppe_port_bufgroup_map_set; + if (p_adpt_api->adpt_bm_func_bitmap & (1 << FUNC_BM_PORT_RESERVED_BUFFER_SET)) + p_adpt_api->adpt_bm_port_reserved_buffer_set = adpt_hppe_bm_port_reserved_buffer_set; + if (p_adpt_api->adpt_bm_func_bitmap & (1 << FUNC_BM_PORT_STATIC_THRESH_SET)) + p_adpt_api->adpt_bm_port_static_thresh_set = adpt_hppe_bm_port_static_thresh_set; + if (p_adpt_api->adpt_bm_func_bitmap & (1 << FUNC_BM_PORT_DYNAMIC_THRESH_SET)) + p_adpt_api->adpt_bm_port_dynamic_thresh_set = adpt_hppe_bm_port_dynamic_thresh_set; + if (p_adpt_api->adpt_bm_func_bitmap & (1 << FUNC_PORT_BM_CTRL_SET)) + p_adpt_api->adpt_port_bm_ctrl_set = adpt_hppe_port_bm_ctrl_set; + if (p_adpt_api->adpt_bm_func_bitmap & (1 << FUNC_PORT_TDM_CTRL_SET)) + p_adpt_api->adpt_port_tdm_ctrl_set = adpt_hppe_port_tdm_ctrl_set; + if (p_adpt_api->adpt_bm_func_bitmap & (1 << FUNC_PORT_TDM_TICK_CFG_SET)) + p_adpt_api->adpt_port_tdm_tick_cfg_set = adpt_hppe_port_tdm_tick_cfg_set; + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_ctrlpkt.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_ctrlpkt.c new file mode 100755 index 000000000..d4659f15d --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_ctrlpkt.c @@ -0,0 +1,385 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hppe_ctrlpkt_reg.h" +#include "hppe_ctrlpkt.h" +#include "hppe_fdb_reg.h" +#include "hppe_fdb.h" +#include "adpt.h" + +a_uint32_t +_get_mgmtctrl_ctrlpkt_profile_by_index(a_uint32_t dev_id, a_uint32_t index, fal_ctrlpkt_profile_t *ctrlpkt) +{ + union app_ctrl_u entry; + + SW_RTN_ON_ERROR(hppe_app_ctrl_get(dev_id, index, &entry)); + + ctrlpkt->action.action = entry.bf.cmd; + ctrlpkt->action.sg_bypass = entry.bf.sg_byp; + ctrlpkt->action.l2_filter_bypass = entry.bf.l2_sec_byp; + ctrlpkt->action.in_stp_bypass = entry.bf.in_stg_byp; + ctrlpkt->action.in_vlan_fltr_bypass = entry.bf.in_vlan_fltr_byp; + + if (entry.bf.portbitmap_include) + ctrlpkt->port_map = entry.bf.portbitmap; + + if (entry.bf.ethertype_include) + ctrlpkt->ethtype_profile_bitmap = entry.bf.ethertype_index_bitmap_0 | (entry.bf.ethertype_index_bitmap_1 << 2); + + if (entry.bf.rfdb_include) + ctrlpkt->rfdb_profile_bitmap = entry.bf.rfdb_index_bitmap_0| (entry.bf.rfdb_index_bitmap_1 << 30); + + if (entry.bf.protocol_include) { + ctrlpkt->protocol_types.mgt_eapol = (entry.bf.protocol_bitmap & (0x1 << 0))?1:0; + ctrlpkt->protocol_types.mgt_pppoe = (entry.bf.protocol_bitmap & (0x1 << 1))?1:0; + ctrlpkt->protocol_types.mgt_igmp = (entry.bf.protocol_bitmap & (0x1 << 2))?1:0; + ctrlpkt->protocol_types.mgt_arp_req = (entry.bf.protocol_bitmap & (0x1 << 3))?1:0; + ctrlpkt->protocol_types.mgt_arp_rep = (entry.bf.protocol_bitmap & (0x1 << 4))?1:0; + ctrlpkt->protocol_types.mgt_dhcp4 = (entry.bf.protocol_bitmap & (0x1 << 5))?1:0; + ctrlpkt->protocol_types.mgt_mld = (entry.bf.protocol_bitmap & (0x1 << 6))?1:0; + ctrlpkt->protocol_types.mgt_ns = (entry.bf.protocol_bitmap & (0x1 << 7))?1:0; + ctrlpkt->protocol_types.mgt_na = (entry.bf.protocol_bitmap & (0x1 << 8))?1:0; + ctrlpkt->protocol_types.mgt_dhcp6 = (entry.bf.protocol_bitmap & (0x1 << 9))?1:0; + } + + return entry.bf.valid; +} + +a_uint32_t +_check_if_ctrlpkt_equal(fal_ctrlpkt_profile_t *ctrlpkt1, fal_ctrlpkt_profile_t *ctrlpkt2) +{ + if (ctrlpkt1->action.action == ctrlpkt2->action.action && + ctrlpkt1->action.sg_bypass == ctrlpkt2->action.sg_bypass && + ctrlpkt1->action.l2_filter_bypass == ctrlpkt2->action.l2_filter_bypass && + ctrlpkt1->action.in_stp_bypass == ctrlpkt2->action.in_stp_bypass && + ctrlpkt1->action.in_vlan_fltr_bypass == ctrlpkt2->action.in_vlan_fltr_bypass && + ctrlpkt1->port_map == ctrlpkt2->port_map && + ctrlpkt1->ethtype_profile_bitmap == ctrlpkt2->ethtype_profile_bitmap && + ctrlpkt1->rfdb_profile_bitmap == ctrlpkt2->rfdb_profile_bitmap && + ctrlpkt1->protocol_types.mgt_eapol == ctrlpkt2->protocol_types.mgt_eapol && + ctrlpkt1->protocol_types.mgt_pppoe == ctrlpkt2->protocol_types.mgt_pppoe && + ctrlpkt1->protocol_types.mgt_igmp == ctrlpkt2->protocol_types.mgt_igmp && + ctrlpkt1->protocol_types.mgt_arp_req == ctrlpkt2->protocol_types.mgt_arp_req && + ctrlpkt1->protocol_types.mgt_arp_rep == ctrlpkt2->protocol_types.mgt_arp_rep && + ctrlpkt1->protocol_types.mgt_dhcp4 == ctrlpkt2->protocol_types.mgt_dhcp4 && + ctrlpkt1->protocol_types.mgt_mld == ctrlpkt2->protocol_types.mgt_mld && + ctrlpkt1->protocol_types.mgt_ns == ctrlpkt2->protocol_types.mgt_ns && + ctrlpkt1->protocol_types.mgt_na == ctrlpkt2->protocol_types.mgt_na && + ctrlpkt1->protocol_types.mgt_dhcp6 == ctrlpkt2->protocol_types.mgt_dhcp6) + return 1; + + return 0; +} + +sw_error_t +adpt_hppe_mgmtctrl_ethtype_profile_set(a_uint32_t dev_id, a_uint32_t profile_id, a_uint32_t ethtype) +{ + sw_error_t rtn = SW_OK; + + ADPT_DEV_ID_CHECK(dev_id); + + SW_RTN_ON_ERROR(hppe_ethertype_ctrl_ethertype_set(dev_id, profile_id, ethtype)); + SW_RTN_ON_ERROR(hppe_ethertype_ctrl_ethertype_en_set(dev_id, profile_id, A_TRUE)); + + return rtn; +} + +sw_error_t +adpt_hppe_mgmtctrl_ethtype_profile_get(a_uint32_t dev_id, a_uint32_t profile_id, a_uint32_t *ethtype) +{ + sw_error_t rtn = SW_OK; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(ethtype); + + SW_RTN_ON_ERROR(hppe_ethertype_ctrl_ethertype_get(dev_id, profile_id, ethtype)); + + return rtn; +} + +sw_error_t +adpt_hppe_mgmtctrl_rfdb_profile_set(a_uint32_t dev_id, a_uint32_t profile_id, fal_mac_addr_t *addr) +{ + sw_error_t rtn = SW_OK; + a_uint64_t value = 0; + + ADPT_DEV_ID_CHECK(dev_id); + + if (profile_id >= RFDB_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + + value = ((((a_uint64_t)(addr->uc[5])) << 0) | + (((a_uint64_t)(addr->uc[4])) << 8) | + (((a_uint64_t)(addr->uc[3])) << 16) | + (((a_uint64_t)(addr->uc[2])) << 24) | + (((a_uint64_t)(addr->uc[1])) << 32) | + (((a_uint64_t)(addr->uc[0])) << 40)); + + SW_RTN_ON_ERROR(hppe_rfdb_tbl_mac_addr_set(dev_id, profile_id, value)); + SW_RTN_ON_ERROR(hppe_rfdb_tbl_valid_set(dev_id, profile_id, A_TRUE)); + + return rtn; +} + +sw_error_t +adpt_hppe_mgmtctrl_rfdb_profile_get(a_uint32_t dev_id, a_uint32_t profile_id, fal_mac_addr_t *addr) +{ + sw_error_t rtn = SW_OK; + a_uint64_t value = 0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(addr); + + if (profile_id >= RFDB_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + + SW_RTN_ON_ERROR(hppe_rfdb_tbl_mac_addr_get(dev_id, profile_id, &value)); + addr->uc[0] = (a_uint8_t)((value >> 40)& 0xff); + addr->uc[1] = (a_uint8_t)((value >> 32) & 0xff); + addr->uc[2] = (a_uint8_t)((value >> 24) & 0xff); + addr->uc[3] = (a_uint8_t)((value >> 16) & 0xff); + addr->uc[4] = (a_uint8_t)((value >> 8) & 0xff); + addr->uc[5] = (a_uint8_t)((value >> 0) & 0xff); + + return rtn; +} + +sw_error_t +adpt_hppe_mgmtctrl_ctrlpkt_profile_add(a_uint32_t dev_id, fal_ctrlpkt_profile_t *ctrlpkt) +{ + union app_ctrl_u entry; + a_uint32_t index, ctrlpkt_valid, entry_sign, entry_index; + fal_ctrlpkt_profile_t ctrlpkt_temp; + + ADPT_DEV_ID_CHECK(dev_id); + + entry_index = 0; + entry_sign = 0; + for (index = 0; index < APP_CTRL_MAX_ENTRY; index++) + { + memset(&ctrlpkt_temp, 0, sizeof(fal_ctrlpkt_profile_t)); + ctrlpkt_valid = _get_mgmtctrl_ctrlpkt_profile_by_index(dev_id, index, &ctrlpkt_temp); + if (ctrlpkt_valid == 1) + { + if (_check_if_ctrlpkt_equal(&ctrlpkt_temp, ctrlpkt)) + return SW_ALREADY_EXIST; + } + else + { + if (entry_sign == 0) { + entry_index = index; + entry_sign = 1; + } + } + } + + if (entry_sign == 0) + return SW_NO_RESOURCE; + + memset(&entry, 0, sizeof(union app_ctrl_u)); + + entry.bf.valid = A_TRUE; + entry.bf.rfdb_include = ctrlpkt->rfdb_profile_bitmap?1:0; + entry.bf.rfdb_index_bitmap_0 = (ctrlpkt->rfdb_profile_bitmap & 0x3fffffff); + entry.bf.rfdb_index_bitmap_1 = (ctrlpkt->rfdb_profile_bitmap >> 30); + + if (ctrlpkt->protocol_types.mgt_eapol) + entry.bf.protocol_bitmap |= (0x1 << 0); + if (ctrlpkt->protocol_types.mgt_pppoe) + entry.bf.protocol_bitmap |= (0x1 << 1); + if (ctrlpkt->protocol_types.mgt_igmp) + entry.bf.protocol_bitmap |= (0x1 << 2); + if (ctrlpkt->protocol_types.mgt_arp_req) + entry.bf.protocol_bitmap |= (0x1 << 3); + if (ctrlpkt->protocol_types.mgt_arp_rep) + entry.bf.protocol_bitmap |= (0x1 << 4); + if (ctrlpkt->protocol_types.mgt_dhcp4) + entry.bf.protocol_bitmap |= (0x1 << 5); + if (ctrlpkt->protocol_types.mgt_mld) + entry.bf.protocol_bitmap |= (0x1 << 6); + if (ctrlpkt->protocol_types.mgt_ns) + entry.bf.protocol_bitmap |= (0x1 << 7); + if (ctrlpkt->protocol_types.mgt_na) + entry.bf.protocol_bitmap |= (0x1 << 8); + if (ctrlpkt->protocol_types.mgt_dhcp6) + entry.bf.protocol_bitmap |= (0x1 << 9); + + entry.bf.protocol_include = entry.bf.protocol_bitmap?1:0; + + entry.bf.ethertype_include = ctrlpkt->ethtype_profile_bitmap?1:0; + entry.bf.ethertype_index_bitmap_0 = (ctrlpkt->ethtype_profile_bitmap & 0x3); + entry.bf.ethertype_index_bitmap_1 = (ctrlpkt->ethtype_profile_bitmap >> 2); + + entry.bf.portbitmap_include = ctrlpkt->port_map?1:0; + entry.bf.portbitmap = ctrlpkt->port_map; + + entry.bf.in_vlan_fltr_byp = ctrlpkt->action.in_vlan_fltr_bypass?1:0; + entry.bf.in_stg_byp = ctrlpkt->action.in_stp_bypass?1:0; + entry.bf.l2_sec_byp = ctrlpkt->action.l2_filter_bypass?1:0; + entry.bf.sg_byp = ctrlpkt->action.sg_bypass?1:0; + entry.bf.cmd = (a_uint32_t)ctrlpkt->action.action; + SW_RTN_ON_ERROR(hppe_app_ctrl_set(dev_id, entry_index, &entry)); + + return SW_OK; +} + +sw_error_t +adpt_hppe_mgmtctrl_ctrlpkt_profile_del(a_uint32_t dev_id, fal_ctrlpkt_profile_t *ctrlpkt) +{ + a_uint32_t index, ctrlpkt_valid; + union app_ctrl_u entry; + fal_ctrlpkt_profile_t ctrlpkt_temp; + + memset(&entry, 0, sizeof(union app_ctrl_u)); + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(ctrlpkt); + + for (index = 0; index < APP_CTRL_MAX_ENTRY; index++) + { + memset(&ctrlpkt_temp, 0, sizeof(fal_ctrlpkt_profile_t)); + ctrlpkt_valid = _get_mgmtctrl_ctrlpkt_profile_by_index(dev_id, index, &ctrlpkt_temp); + if (ctrlpkt_valid == 1) + { + if (_check_if_ctrlpkt_equal(&ctrlpkt_temp, ctrlpkt)) + { + SW_RTN_ON_ERROR(hppe_app_ctrl_set(dev_id, index, &entry)); + return SW_OK; + } + } + } + + return SW_NOT_FOUND; +} + +sw_error_t +adpt_hppe_mgmtctrl_ctrlpkt_profile_getfirst(a_uint32_t dev_id, fal_ctrlpkt_profile_t *ctrlpkt) +{ + a_uint32_t index, ctrlpkt_valid; + + for (index = 0; index < APP_CTRL_MAX_ENTRY; index++) + { + ctrlpkt_valid = _get_mgmtctrl_ctrlpkt_profile_by_index(dev_id, index, ctrlpkt); + if (ctrlpkt_valid == 1) + return SW_OK; + } + + return SW_NO_MORE; +} + +sw_error_t +adpt_hppe_mgmtctrl_ctrlpkt_profile_getnext(a_uint32_t dev_id, fal_ctrlpkt_profile_t *ctrlpkt) +{ + a_uint32_t index, ctrlpkt_valid, sign_tag; + fal_ctrlpkt_profile_t ctrlpkt_temp; + + sign_tag = 0; + + for (index = 0; index < APP_CTRL_MAX_ENTRY; index++) + { + memset(&ctrlpkt_temp, 0, sizeof(fal_ctrlpkt_profile_t)); + ctrlpkt_valid = _get_mgmtctrl_ctrlpkt_profile_by_index(dev_id, index, &ctrlpkt_temp); + if (ctrlpkt_valid == 1) + { + if (sign_tag == 1) { + aos_mem_copy(ctrlpkt, &ctrlpkt_temp, sizeof(fal_ctrlpkt_profile_t)); + return SW_OK; + } + if (_check_if_ctrlpkt_equal(&ctrlpkt_temp, ctrlpkt)) + sign_tag = 1; + } + } + + return SW_NO_MORE; +} + +void adpt_hppe_ctrlpkt_func_bitmap_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_ctrlpkt_func_bitmap = ((1 << FUNC_MGMTCTRL_ETHTYPE_PROFILE_SET) | + (1 << FUNC_MGMTCTRL_ETHTYPE_PROFILE_GET) | + (1 << FUNC_MGMTCTRL_RFDB_PROFILE_SET) | + (1 << FUNC_MGMTCTRL_RFDB_PROFILE_GET) | + (1 << FUNC_MGMTCTRL_CTRLPKT_PROFILE_ADD) | + (1 << FUNC_MGMTCTRL_CTRLPKT_PROFILE_DEL) | + (1 << FUNC_MGMTCTRL_CTRLPKT_PROFILE_GETFIRST) | + (1 << FUNC_MGMTCTRL_CTRLPKT_PROFILE_GETNEXT)); + + return; +} + +static void adpt_hppe_ctrlpkt_func_unregister(a_uint32_t dev_id, adpt_api_t *p_adpt_api) +{ + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_mgmtctrl_ethtype_profile_set = NULL; + p_adpt_api->adpt_mgmtctrl_ethtype_profile_get = NULL; + p_adpt_api->adpt_mgmtctrl_rfdb_profile_set = NULL; + p_adpt_api->adpt_mgmtctrl_rfdb_profile_get = NULL; + p_adpt_api->adpt_mgmtctrl_ctrlpkt_profile_add = NULL; + p_adpt_api->adpt_mgmtctrl_ctrlpkt_profile_del = NULL; + p_adpt_api->adpt_mgmtctrl_ctrlpkt_profile_getfirst = NULL; + p_adpt_api->adpt_mgmtctrl_ctrlpkt_profile_getnext = NULL; + + return; +} + +sw_error_t adpt_hppe_ctrlpkt_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return SW_FAIL; + + adpt_hppe_ctrlpkt_func_unregister(dev_id, p_adpt_api); + + if (p_adpt_api->adpt_ctrlpkt_func_bitmap & (1 << FUNC_MGMTCTRL_ETHTYPE_PROFILE_SET)) + p_adpt_api->adpt_mgmtctrl_ethtype_profile_set = adpt_hppe_mgmtctrl_ethtype_profile_set; + if (p_adpt_api->adpt_ctrlpkt_func_bitmap & (1 << FUNC_MGMTCTRL_ETHTYPE_PROFILE_GET)) + p_adpt_api->adpt_mgmtctrl_ethtype_profile_get = adpt_hppe_mgmtctrl_ethtype_profile_get; + if (p_adpt_api->adpt_ctrlpkt_func_bitmap & (1 << FUNC_MGMTCTRL_RFDB_PROFILE_SET)) + p_adpt_api->adpt_mgmtctrl_rfdb_profile_set = adpt_hppe_mgmtctrl_rfdb_profile_set; + if (p_adpt_api->adpt_ctrlpkt_func_bitmap & (1 << FUNC_MGMTCTRL_RFDB_PROFILE_GET)) + p_adpt_api->adpt_mgmtctrl_rfdb_profile_get = adpt_hppe_mgmtctrl_rfdb_profile_get; + if (p_adpt_api->adpt_ctrlpkt_func_bitmap & (1 << FUNC_MGMTCTRL_CTRLPKT_PROFILE_ADD)) + p_adpt_api->adpt_mgmtctrl_ctrlpkt_profile_add = adpt_hppe_mgmtctrl_ctrlpkt_profile_add; + if (p_adpt_api->adpt_ctrlpkt_func_bitmap & (1 << FUNC_MGMTCTRL_CTRLPKT_PROFILE_DEL)) + p_adpt_api->adpt_mgmtctrl_ctrlpkt_profile_del = adpt_hppe_mgmtctrl_ctrlpkt_profile_del; + if (p_adpt_api->adpt_ctrlpkt_func_bitmap & (1 << FUNC_MGMTCTRL_CTRLPKT_PROFILE_GETFIRST)) + p_adpt_api->adpt_mgmtctrl_ctrlpkt_profile_getfirst = adpt_hppe_mgmtctrl_ctrlpkt_profile_getfirst; + if (p_adpt_api->adpt_ctrlpkt_func_bitmap & (1 << FUNC_MGMTCTRL_CTRLPKT_PROFILE_GETNEXT)) + p_adpt_api->adpt_mgmtctrl_ctrlpkt_profile_getnext = adpt_hppe_mgmtctrl_ctrlpkt_profile_getnext; + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_fdb.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_fdb.c new file mode 100755 index 000000000..2d8a6352d --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_fdb.c @@ -0,0 +1,1520 @@ +/* + * 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. + */ + + +/** + * @defgroup + * @{ + */ +#include "sw.h" +#include "hppe_fdb_reg.h" +#include "hppe_fdb.h" +#include "adpt.h" + +#define OP_TYPE_ADD 0x0 +#define OP_TYPE_DEL 0x1 +#define OP_TYPE_GET 0x2 +#define OP_TYPE_FLUSH 0x4 +#define OP_TYPE_AGE 0x5 + +#define OP_MODE_HASH 0x0 +#define OP_MODE_INDEX 0x1 + +#define OP_CMD_ID_SIZE 0xf + +#define OP_FIFO_CNT_SIZE 0x8 + +#define ARL_FIRST_ENTRY 0x0 +#define ARL_NEXT_ENTRY 0x1 +#define ARL_EXTENDFIRST_ENTRY 0x2 +#define ARL_EXTENDNEXT_ENTRY 0x3 + + +static aos_lock_t hppe_fdb_lock; + +/* + * Remove port type. + * Current fal_port_t format: + * 1) highest 8 bits is defined as port type. + * 2) lowest 24 bits for port id value. + * The range of physical port id is 0-7, the range of trunk id is 32-33, and the range of virtual port is 64-255. + * Port type: 0 is physical port, 1 is trunk port, 2 is virtual port. + */ +sw_error_t +_remove_port_type(fal_port_t * port_id) +{ + *port_id = FAL_PORT_ID_VALUE(*port_id); + return SW_OK; +} + +/* + * Add port type. + * Current fal_port_t format: + * 1) highest 8 bits is defined as port type. + * 2) lowest 24 bits for port id value. + * The range of physical port id is 0-7, the range of trunk id is 32-33, and the range of virtual port is 64-255. + * Port type: 0 is physical port, 1 is trunk port, 2 is virtual port. + */ +sw_error_t +_add_port_type(a_bool_t bitmap, fal_port_t * port_id) +{ + if (bitmap == A_TRUE) + return SW_OK; + + if (*port_id == 32 || *port_id == 33) + *port_id = FAL_PORT_ID(FAL_PORT_TYPE_TRUNK, *port_id); + else if (*port_id >= 64) + *port_id = FAL_PORT_ID(FAL_PORT_TYPE_VPORT, *port_id); + return SW_OK; +} + +/* + * set values to register FDB_TBL_OP + */ +sw_error_t +_adpt_hppe_fdb_tbl_op_reg_set(a_uint32_t dev_id, a_uint32_t cmd_id, a_uint32_t op_type) +{ + sw_error_t rv = SW_OK; + union fdb_tbl_op_u reg_val_op; + a_uint32_t op_mode = OP_MODE_HASH; + a_uint32_t entry_index = 0x0; + + reg_val_op.bf.cmd_id = cmd_id; + reg_val_op.bf.byp_rslt_en = 0x0; + reg_val_op.bf.op_type = op_type; + reg_val_op.bf.hash_block_bitmap = 0x3; + reg_val_op.bf.op_mode = op_mode; + reg_val_op.bf.entry_index = entry_index; + rv = hppe_fdb_tbl_op_set(dev_id, ®_val_op); + + return rv; +} + +/* + * get results from register FDB_TBL_OP_RSLT + */ +sw_error_t +_adpt_hppe_fdb_tbl_op_rslt_reg_get(a_uint32_t dev_id, a_uint32_t cmd_id) +{ + sw_error_t rv = SW_OK; + union fdb_tbl_op_rslt_u reg_val_op_rslt; + + rv = hppe_fdb_tbl_op_rslt_get(dev_id, ®_val_op_rslt); + + if (rv != SW_OK || reg_val_op_rslt.bf.cmd_id != cmd_id || reg_val_op_rslt.bf.valid_cnt > OP_FIFO_CNT_SIZE) + return SW_FAIL; + + return SW_OK; +} + +/* + * set values to register FDB_TBL_RD_OP + */ +sw_error_t +_adpt_hppe_fdb_tbl_rd_op_reg_set(a_uint32_t dev_id, a_uint32_t cmd_id, a_uint32_t op_mode, a_uint32_t entry_index) +{ + sw_error_t rv = SW_OK; + union fdb_tbl_rd_op_u reg_val_rd_op; + a_uint32_t op_type = OP_TYPE_GET; + + reg_val_rd_op.bf.cmd_id = cmd_id; + reg_val_rd_op.bf.byp_rslt_en = 0x0; + reg_val_rd_op.bf.op_type = op_type; + reg_val_rd_op.bf.hash_block_bitmap = 0x3; + reg_val_rd_op.bf.op_mode = op_mode; + reg_val_rd_op.bf.entry_index = entry_index; + rv = hppe_fdb_tbl_rd_op_set(dev_id, ®_val_rd_op); + + return rv; +} + +/* + * get results from register FDB_TBL_RD_OP_RSLT + */ +sw_error_t +_adpt_hppe_fdb_tbl_rd_op_rslt_reg_get(a_uint32_t dev_id, a_uint32_t cmd_id, a_uint32_t *entry_index) +{ + sw_error_t rv = SW_OK; + union fdb_tbl_rd_op_rslt_u reg_val_rd_op_rslt; + + rv = hppe_fdb_tbl_rd_op_rslt_get(dev_id, ®_val_rd_op_rslt); + + if (rv != SW_OK || reg_val_rd_op_rslt.bf.cmd_id != cmd_id || + reg_val_rd_op_rslt.bf.valid_cnt > OP_FIFO_CNT_SIZE) + { + return SW_FAIL; + } + + *entry_index = reg_val_rd_op_rslt.bf.entry_index; + + return SW_OK; +} + +/* + * set values to register FDB_TBL_OP_DATA0/FDB_TBL_OP_DATA1/FDB_TBL_OP_DATA2 + */ +sw_error_t +_adpt_hppe_fdb_tbl_op_data_reg_set(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv = SW_OK; + a_uint32_t i, port_value, dst_type = 0x0; + a_uint32_t reg_value[3] = {0}; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(entry); + + for (i = 2; i < 6; i++) + { + reg_value[0] = (reg_value[0] << 8) + entry->addr.uc[i]; + } + rv = hppe_fdb_tbl_op_data0_data_set(dev_id, reg_value[0]); + if (rv != SW_OK) + return rv; + + for (i = 0; i < 2; i++) + { + reg_value[1] = (reg_value[1] << 8) + entry->addr.uc[i]; + } + reg_value[1] += (0x1 << (FDB_TBL_ENTRY_VALID_OFFSET - 32)) + (0x1 << (FDB_TBL_LOOKUP_VALID_OFFSET -32)) + + (entry->fid << (FDB_TBL_VSI_OFFSET - 32)); + if (entry->portmap_en == A_TRUE) + { + port_value = entry->port.map; + dst_type = 0x3; + } + else + { + port_value = entry->port.id; + dst_type = 0x2; + } + reg_value[1] += ((port_value & 0x1ff) << (FDB_TBL_DST_INFO_OFFSET - 32)); + rv = hppe_fdb_tbl_op_data1_data_set(dev_id, reg_value[1]); + if (rv != SW_OK) + return rv; + + reg_value[2] = ((port_value >> 0x9) & 0x7) + ((dst_type & 0x3) << 3) + + ((entry->sacmd & 0x3) << (FDB_TBL_SA_CMD_OFFSET - 64)) + + ((entry->dacmd & 0x3) << (FDB_TBL_DA_CMD_OFFSET - 64)); + if (entry->static_en == A_TRUE) + reg_value[2] += (0x3 << (FDB_TBL_HIT_AGE_OFFSET - 64)); + else + reg_value[2] += (0x2 << (FDB_TBL_HIT_AGE_OFFSET - 64)); + rv = hppe_fdb_tbl_op_data2_data_set(dev_id, reg_value[2]); + if (rv != SW_OK) + return rv; + + return SW_OK; +} + +/* + * set values to register FDB_TBL_RD_OP_DATA0/FDB_TBL_RD_OP_DATA1/FDB_TBL_RD_OP_DATA2 + */ +sw_error_t +_adpt_hppe_fdb_tbl_rd_op_data_reg_set(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv = SW_OK; + a_uint32_t i, reg_value[3] = {0}; + + for (i = 2; i < 6; i++) + { + reg_value[0] = (reg_value[0] << 8) + entry->addr.uc[i]; + } + rv = hppe_fdb_tbl_rd_op_data0_data_set(dev_id, reg_value[0]); + if (rv != SW_OK) + return rv; + + for (i = 0; i < 2; i++) + { + reg_value[1] = (reg_value[1] << 8) + entry->addr.uc[i]; + } + reg_value[1] += (entry->fid << (FDB_TBL_VSI_OFFSET - 32)); + rv = hppe_fdb_tbl_rd_op_data1_data_set(dev_id, reg_value[1]); + if (rv != SW_OK) + return rv; + + rv = hppe_fdb_tbl_rd_op_data2_data_set(dev_id, reg_value[2]); + if (rv != SW_OK) + return rv; + + return SW_OK; +} + +/* + * get values from register FDB_TBL_RD_OP_RSLT_DATA0/FDB_TBL_RD_OP_RSLT_DATA1/FDB_TBL_RD_OP_RSLT_DATA2 + */ +sw_error_t +_adpt_hppe_fdb_tbl_rd_op_rslt_data_reg_get(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + a_uint32_t rslt_data[3]; + a_uint32_t entry_valid, lookup_valid; + a_uint32_t i, dst_info_encode; + + hppe_fdb_tbl_rd_op_rslt_data0_data_get(dev_id, &rslt_data[0]); + hppe_fdb_tbl_rd_op_rslt_data1_data_get(dev_id, &rslt_data[1]); + hppe_fdb_tbl_rd_op_rslt_data2_data_get(dev_id, &rslt_data[2]); + + entry_valid = (rslt_data[1] >> (FDB_TBL_ENTRY_VALID_OFFSET - 32)) & 0x1; + lookup_valid = (rslt_data[1] >> (FDB_TBL_LOOKUP_VALID_OFFSET - 32)) & 0x1; + dst_info_encode = (rslt_data[2] >> (FDB_TBL_DST_INFO_OFFSET + 12 -64)) & 0x3; + + if (entry_valid == 0x0 || dst_info_encode == 0x0) + { + return SW_NOT_FOUND; + } + else + { + entry->entry_valid = A_TRUE; + if (lookup_valid == 0x1) + entry->lookup_valid = A_TRUE; + else + entry->lookup_valid = A_FALSE; + entry->fid = (rslt_data[1] >> (FDB_TBL_VSI_OFFSET - 32)) & 0x1f; + entry->sacmd = (rslt_data[2] >> (FDB_TBL_SA_CMD_OFFSET - 64)) & 0x3; + entry->dacmd = (rslt_data[2] >> (FDB_TBL_DA_CMD_OFFSET - 64)) & 0x3; + if (((rslt_data[2] >> (FDB_TBL_HIT_AGE_OFFSET - 64)) & 0x3) == 0x3) + entry->static_en = A_TRUE; + else + entry->static_en = A_FALSE; + if (dst_info_encode == 0x2) + { + entry->portmap_en = A_FALSE; + entry->port.id = ((rslt_data[2] & 0x7) << 9) + ((rslt_data[1] >> (FDB_TBL_DST_INFO_OFFSET - 32)) & 0x1ff); + } + else + { + entry->portmap_en = A_TRUE; + entry->port.map = ((rslt_data[2] & 0x7) << 9) + ((rslt_data[1] >> (FDB_TBL_DST_INFO_OFFSET - 32)) & 0x1ff); + } + for (i = 2; i < 6; i++) + entry->addr.uc[i] = (rslt_data[0] >> ((5 - i) << 3)) & 0xff; + for (i = 0; i < 2; i++) + entry->addr.uc[i] = (rslt_data[1] >> ((1 - i) << 3)) & 0xff; + } + + return SW_OK; +} + +sw_error_t +_get_fdb_table_entryindex_by_entry(a_uint32_t dev_id, fal_fdb_entry_t * entry, + a_uint32_t *entry_index, a_uint32_t cmd_id) +{ + sw_error_t rv = SW_OK; + a_uint32_t init_entry_index = 0; + fal_fdb_entry_t temp_entry; + + aos_lock_bh(&hppe_fdb_lock); + rv = _adpt_hppe_fdb_tbl_rd_op_data_reg_set(dev_id, entry); + if (rv != SW_OK) + { + aos_unlock_bh(&hppe_fdb_lock); + return rv; + } + + rv = _adpt_hppe_fdb_tbl_rd_op_reg_set(dev_id, cmd_id, OP_MODE_HASH, init_entry_index); + if (rv != SW_OK) + { + aos_unlock_bh(&hppe_fdb_lock); + return rv; + } + + rv = _adpt_hppe_fdb_tbl_rd_op_rslt_data_reg_get(dev_id, &temp_entry); + + rv = _adpt_hppe_fdb_tbl_rd_op_rslt_reg_get(dev_id, cmd_id, entry_index); + if (rv != SW_OK) + { + aos_unlock_bh(&hppe_fdb_lock); + return rv; + } + + aos_unlock_bh(&hppe_fdb_lock); + + if (*entry_index == 0) + { + if (!(temp_entry.addr.uc[0] == entry->addr.uc[0] && temp_entry.addr.uc[1] == entry->addr.uc[1] && + temp_entry.addr.uc[2] == entry->addr.uc[2] && temp_entry.addr.uc[3] == entry->addr.uc[3] && + temp_entry.addr.uc[4] == entry->addr.uc[4] && temp_entry.addr.uc[5] == entry->addr.uc[5] && + temp_entry.fid == entry->fid)) + return SW_NOT_FOUND; + } + + return SW_OK; +} + +sw_error_t +_get_fdb_table_entry_by_entryindex(a_uint32_t dev_id, fal_fdb_entry_t * entry, + a_uint32_t entry_index, a_uint32_t cmd_id) +{ + sw_error_t rv = SW_OK, rv1 = SW_OK; + fal_fdb_entry_t init_entry; + a_uint32_t rslt_entry_index = 0; + + aos_mem_zero(&init_entry, sizeof (fal_fdb_entry_t)); + + aos_lock_bh(&hppe_fdb_lock); + rv = _adpt_hppe_fdb_tbl_rd_op_data_reg_set(dev_id, &init_entry); + if (rv != SW_OK) + { + aos_unlock_bh(&hppe_fdb_lock); + return rv; + } + + rv = _adpt_hppe_fdb_tbl_rd_op_reg_set(dev_id, cmd_id, OP_MODE_INDEX, entry_index); + if (rv != SW_OK) + { + aos_unlock_bh(&hppe_fdb_lock); + return rv; + } + + rv = _adpt_hppe_fdb_tbl_rd_op_rslt_data_reg_get(dev_id, entry); + if (rv != SW_OK && rv != SW_NOT_FOUND) + { + aos_unlock_bh(&hppe_fdb_lock); + return rv; + } + else + rv1 = rv; + + rv = _adpt_hppe_fdb_tbl_rd_op_rslt_reg_get(dev_id, cmd_id, &rslt_entry_index); + if (rv != SW_OK) + { + aos_unlock_bh(&hppe_fdb_lock); + return rv; + } + + aos_unlock_bh(&hppe_fdb_lock); + + return rv1; +} + +sw_error_t +_modify_fdb_table_entry(a_uint32_t dev_id, fal_fdb_entry_t * entry, a_uint32_t op_type, + a_uint32_t cmd_id) +{ + sw_error_t rv = SW_OK; + fal_fdb_entry_t temp_entry; + + aos_lock_bh(&hppe_fdb_lock); + rv = _adpt_hppe_fdb_tbl_op_data_reg_set(dev_id, entry); + if (rv != SW_OK) + { + aos_unlock_bh(&hppe_fdb_lock); + return rv; + } + + rv = _adpt_hppe_fdb_tbl_op_reg_set(dev_id, cmd_id, op_type); + if (rv != SW_OK) + { + aos_unlock_bh(&hppe_fdb_lock); + return rv; + } + + rv = _adpt_hppe_fdb_tbl_rd_op_rslt_data_reg_get(dev_id, &temp_entry); + + rv = _adpt_hppe_fdb_tbl_op_rslt_reg_get(dev_id, cmd_id); + if (rv != SW_OK) + { + aos_unlock_bh(&hppe_fdb_lock); + return rv; + } + + aos_unlock_bh(&hppe_fdb_lock); + + return SW_OK; +} + +sw_error_t +_adpt_hppe_fdb_extend_first_next(a_uint32_t dev_id, fal_fdb_entry_t * entry, fal_fdb_op_t * option, a_uint32_t hwop) +{ + sw_error_t rv; + a_uint32_t cmd_id = 0x0; + a_uint32_t entry_index = 0x0; + fal_fdb_entry_t ori_entry; + + aos_mem_zero(&ori_entry, sizeof (fal_fdb_entry_t)); + + if (hwop == ARL_EXTENDFIRST_ENTRY || hwop == ARL_EXTENDNEXT_ENTRY) + { + ori_entry.portmap_en = entry->portmap_en; + ori_entry.port.id = entry->port.id; + ori_entry.fid = entry->fid; + } + + if (hwop == ARL_FIRST_ENTRY || hwop == ARL_EXTENDFIRST_ENTRY) + aos_mem_zero(entry, sizeof (fal_fdb_entry_t)); + + rv = _get_fdb_table_entryindex_by_entry(dev_id, entry, &entry_index, cmd_id); + if (rv != SW_OK && rv != SW_NOT_FOUND) + return rv; + + if (rv != SW_NOT_FOUND) + entry_index += 1; + + for (; entry_index < FDB_TBL_NUM; entry_index++) + { + cmd_id = entry_index % OP_CMD_ID_SIZE; + rv = _get_fdb_table_entry_by_entryindex(dev_id, entry, entry_index, cmd_id); + if (rv == SW_NOT_FOUND) + continue; + else if (rv == SW_OK) + { + if (hwop == ARL_EXTENDFIRST_ENTRY || hwop == ARL_EXTENDNEXT_ENTRY) + { + if (option->fid_en == A_TRUE && ori_entry.fid != entry->fid) + continue; + if (option->port_en == A_TRUE && !(ori_entry.portmap_en == entry->portmap_en && + ori_entry.port.id == entry->port.id)) + continue; + } + break; + } + else + return rv; + } + + if (entry_index == FDB_TBL_NUM) + return SW_NO_MORE; + return SW_OK; +} + +void _fdb_copy(fal_fdb_entry_t *new, const fal_fdb_entry_t *old) +{ + a_uint32_t i; + + aos_mem_zero(new, sizeof (fal_fdb_entry_t)); + + for (i = 0; i < 6; i++) + new->addr.uc[i] = old->addr.uc[i]; + + new->fid = old->fid; + new->dacmd = old->dacmd; + new->sacmd = old->sacmd; + new->port.id = old->port.id; + new->portmap_en = old->portmap_en; + new->is_multicast = old->is_multicast; + new->static_en = old->static_en; + +} + +sw_error_t +adpt_hppe_fdb_first(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + fal_fdb_op_t option; + sw_error_t rv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(entry); + + aos_mem_zero(&option, sizeof (fal_fdb_op_t)); + + _remove_port_type(&entry->port.id); + rv = _adpt_hppe_fdb_extend_first_next(dev_id, entry, &option, ARL_FIRST_ENTRY); + _add_port_type(entry->portmap_en, &entry->port.id); + + return rv; +} +#ifndef IN_FDB_MINI +sw_error_t +adpt_hppe_fdb_next(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + fal_fdb_op_t option; + sw_error_t rv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(entry); + + aos_mem_zero(&option, sizeof (fal_fdb_op_t)); + + _remove_port_type(&entry->port.id); + rv = _adpt_hppe_fdb_extend_first_next(dev_id, entry, &option, ARL_NEXT_ENTRY); + _add_port_type(entry->portmap_en, &entry->port.id); + + return rv; +} +#endif +sw_error_t +adpt_hppe_fdb_add(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv = SW_OK; + fal_fdb_entry_t entry_temp; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(entry); + + _fdb_copy(&entry_temp, entry); + + _remove_port_type(&entry_temp.port.id); + rv = _modify_fdb_table_entry(dev_id, &entry_temp, OP_TYPE_ADD, 0x0); + _add_port_type(entry_temp.portmap_en, &entry_temp.port.id); + + return rv; +} + +sw_error_t +adpt_hppe_fdb_del_by_mac(a_uint32_t dev_id, const fal_fdb_entry_t *entry) +{ + sw_error_t rv = SW_OK; + fal_fdb_entry_t entry_temp; + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(entry); + + _fdb_copy(&entry_temp, entry); + _remove_port_type(&entry_temp.port.id); + rv = _modify_fdb_table_entry(dev_id, &entry_temp, OP_TYPE_DEL, 0x0); + _add_port_type(entry_temp.portmap_en, &entry_temp.port.id); + + return rv; +} + +sw_error_t +adpt_hppe_fdb_del_by_port(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t flag) +{ + a_uint32_t entry_index, id, cmd_id = 0; + sw_error_t rv = SW_OK; + fal_fdb_entry_t entry; + + ADPT_DEV_ID_CHECK(dev_id); + + _remove_port_type(&port_id); + + for (entry_index = 0; entry_index < FDB_TBL_NUM; entry_index++) + { + cmd_id = entry_index % OP_CMD_ID_SIZE; + aos_mem_zero(&entry, sizeof (fal_fdb_entry_t)); + rv = _get_fdb_table_entry_by_entryindex(dev_id, &entry, entry_index, cmd_id); + + if (rv == SW_NOT_FOUND) + continue; + else if (rv == SW_OK) + { + if (entry.portmap_en == A_TRUE) + { + if (((entry.port.map >> port_id) & 0x1) == 1) + { + if ((!flag && entry.static_en == A_FALSE) || (flag & FAL_FDB_DEL_STATIC)) + { + id = entry.port.map & (~(0x1 << port_id)); + if (id == 0) + { + rv = _modify_fdb_table_entry(dev_id, &entry, OP_TYPE_DEL, 0x0); + if (rv != SW_OK) + return rv; + } + else + { + entry.port.map &= (~(0x1 << port_id)); + rv = adpt_hppe_fdb_add(dev_id, &entry); + if (rv != SW_OK) + return rv; + } + } + } + } + else + { + if (entry.port.id == port_id && + ((!flag && entry.static_en == A_FALSE) || (flag & FAL_FDB_DEL_STATIC))) + { + rv = _modify_fdb_table_entry(dev_id, &entry, OP_TYPE_DEL, 0x0); + if (rv != SW_OK) + return rv; + } + } + } + else + return rv; + } + + return SW_OK; +} + +sw_error_t +adpt_hppe_fdb_del_all(a_uint32_t dev_id, a_uint32_t flag) +{ + sw_error_t rv; + fal_fdb_entry_t entry; + a_uint32_t entry_index = 0, cmd_id; + + ADPT_DEV_ID_CHECK(dev_id); + + if (FAL_FDB_DEL_STATIC & flag) + { + aos_mem_zero(&entry, sizeof (fal_fdb_entry_t)); + return _modify_fdb_table_entry(dev_id, &entry, OP_TYPE_FLUSH, 0x0); + } + else + { + for (entry_index = 0; entry_index < FDB_TBL_NUM; entry_index++) + { + cmd_id = entry_index % OP_CMD_ID_SIZE; + aos_mem_zero(&entry, sizeof (fal_fdb_entry_t)); + rv = _get_fdb_table_entry_by_entryindex(dev_id, &entry, entry_index, cmd_id); + if (rv != SW_OK && rv != SW_NOT_FOUND) + return rv; + + if (entry.static_en == A_FALSE) + { + rv = _modify_fdb_table_entry(dev_id, &entry, OP_TYPE_DEL, 0x0); + if (rv != SW_OK) + return rv; + } + } + } + + return SW_OK; +} +#ifndef IN_FDB_MINI +sw_error_t +adpt_hppe_fdb_transfer(a_uint32_t dev_id, fal_port_t old_port, fal_port_t new_port, + a_uint32_t fid, fal_fdb_op_t * option) +{ + a_uint32_t entry_index, cmd_id = 0; + sw_error_t rv = SW_OK; + fal_fdb_entry_t entry; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(option); + + if (option->port_en == A_TRUE) + return SW_NOT_SUPPORTED; + + _remove_port_type(&old_port); + _remove_port_type(&new_port); + + for (entry_index = 0; entry_index < FDB_TBL_NUM; entry_index++) + { + cmd_id = entry_index % OP_CMD_ID_SIZE; + aos_mem_zero(&entry, sizeof (fal_fdb_entry_t)); + rv = _get_fdb_table_entry_by_entryindex(dev_id, &entry, entry_index, cmd_id); + + if (rv == SW_NOT_FOUND) + continue; + else if (rv == SW_OK) + { + if (option->fid_en == A_TRUE && entry.fid != fid) + continue; + if (entry.portmap_en == A_TRUE) + { + if (((entry.port.map >> old_port) & 0x1) == 1) + { + entry.port.map &= (~(0x1 << old_port)); + entry.port.map |= (0x1 << new_port); + rv = adpt_hppe_fdb_add(dev_id, &entry); + if (rv != SW_OK) + return rv; + } + } + else + { + if (entry.port.id == old_port) + { + entry.port.id = new_port; + rv = adpt_hppe_fdb_add(dev_id, &entry); + if (rv != SW_OK) + return rv; + } + } + } + else + return rv; + } + + return SW_OK; +} +#endif +sw_error_t +adpt_hppe_fdb_find(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t cmd_id = 0x0; + a_uint32_t entry_index = 0x0; + + _remove_port_type(&entry->port.id); + rv = _get_fdb_table_entryindex_by_entry(dev_id, entry, &entry_index, cmd_id); + if (rv != SW_OK) + return rv; + + cmd_id = entry_index % OP_CMD_ID_SIZE; + + rv = _get_fdb_table_entry_by_entryindex(dev_id, entry, entry_index, cmd_id); + _add_port_type(entry->portmap_en, &entry->port.id); + + return rv; +} + +sw_error_t +adpt_hppe_fdb_iterate(a_uint32_t dev_id, a_uint32_t * iterator, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t cmd_id = 0x0; + a_uint32_t entry_index = 0x0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(iterator); + ADPT_NULL_POINT_CHECK(entry); + + _remove_port_type(&entry->port.id); + for (entry_index = *iterator; entry_index < FDB_TBL_NUM; entry_index++) + { + cmd_id = entry_index % OP_CMD_ID_SIZE; + rv = _get_fdb_table_entry_by_entryindex(dev_id, entry, entry_index, cmd_id); + if (rv == SW_NOT_FOUND) + continue; + else if (rv == SW_OK) + break; + else + return rv; + } + + if (entry_index == FDB_TBL_NUM) + return SW_NO_MORE; + + _add_port_type(entry->portmap_en, &entry->port.id); + *iterator = entry_index + 1; + return SW_OK; +} +#ifndef IN_FDB_MINI +sw_error_t +adpt_hppe_fdb_age_time_set(a_uint32_t dev_id, a_uint32_t * time) +{ + union age_timer_u age_timer = {0}; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(time); + + if (*time < 1 || *time > 1048575) + return SW_BAD_PARAM; + + age_timer.bf.age_val = *time; + + return hppe_age_timer_set(dev_id, &age_timer); +} + +sw_error_t +adpt_hppe_fdb_age_time_get(a_uint32_t dev_id, a_uint32_t * time) +{ + sw_error_t rv = SW_OK; + union age_timer_u age_timer = {0}; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(time); + + rv = hppe_age_timer_get(dev_id, &age_timer); + + if( rv != SW_OK ) + return rv; + + *time = age_timer.bf.age_val; + + return SW_OK; +} +#endif +sw_error_t +adpt_hppe_fdb_extend_first(a_uint32_t dev_id, fal_fdb_op_t * option, + fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(option); + ADPT_NULL_POINT_CHECK(entry); + + _remove_port_type(&entry->port.id); + rv = _adpt_hppe_fdb_extend_first_next(dev_id, entry, option, ARL_EXTENDFIRST_ENTRY); + _add_port_type(entry->portmap_en, &entry->port.id); + + return rv; +} + +sw_error_t +adpt_hppe_fdb_extend_next(a_uint32_t dev_id, fal_fdb_op_t * option, + fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(option); + ADPT_NULL_POINT_CHECK(entry); + + _remove_port_type(&entry->port.id); + rv = _adpt_hppe_fdb_extend_first_next(dev_id, entry, option, ARL_EXTENDNEXT_ENTRY); + _add_port_type(entry->portmap_en, &entry->port.id); + + return rv; +} + +sw_error_t +adpt_hppe_fdb_learn_ctrl_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv = SW_OK; + union l2_global_conf_u l2_global_conf = {0}; + + ADPT_DEV_ID_CHECK(dev_id); + + rv = hppe_l2_global_conf_get(dev_id, &l2_global_conf); + + if( rv != SW_OK ) + return rv; + + l2_global_conf.bf.lrn_en = enable; + + return hppe_l2_global_conf_set(dev_id, &l2_global_conf); +} +#ifndef IN_FDB_MINI +sw_error_t +adpt_hppe_fdb_learn_ctrl_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv = SW_OK; + union l2_global_conf_u l2_global_conf = {0}; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + + + rv = hppe_l2_global_conf_get(dev_id, &l2_global_conf); + + if( rv != SW_OK ) + return rv; + + *enable = l2_global_conf.bf.lrn_en; + + return SW_OK; +} + +sw_error_t +adpt_hppe_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 = SW_OK; + union port_lrn_limit_ctrl_u port_lrn_limit_ctrl = {0}; + + ADPT_DEV_ID_CHECK(dev_id); + + rv = hppe_port_lrn_limit_ctrl_get(dev_id, port_id, &port_lrn_limit_ctrl); + + if( rv != SW_OK ) + return rv; + + port_lrn_limit_ctrl.bf.lrn_lmt_en = maclimit_ctrl->enable; + port_lrn_limit_ctrl.bf.lrn_lmt_cnt = maclimit_ctrl->limit_num; + port_lrn_limit_ctrl.bf.lrn_lmt_exceed_fwd = maclimit_ctrl->action; + + return hppe_port_lrn_limit_ctrl_set(dev_id, port_id, &port_lrn_limit_ctrl); +} + +sw_error_t +adpt_hppe_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 = SW_OK; + union port_lrn_limit_ctrl_u port_lrn_limit_ctrl = {0}; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(maclimit_ctrl); + + rv = hppe_port_lrn_limit_ctrl_get(dev_id, port_id, &port_lrn_limit_ctrl); + + if( rv != SW_OK ) + return rv; + + maclimit_ctrl->enable = port_lrn_limit_ctrl.bf.lrn_lmt_en; + maclimit_ctrl->limit_num = port_lrn_limit_ctrl.bf.lrn_lmt_cnt; + maclimit_ctrl->action = port_lrn_limit_ctrl.bf.lrn_lmt_exceed_fwd; + + return SW_OK; +} + +sw_error_t +adpt_hppe_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 = SW_OK; + fal_maclimit_ctrl_t maclimit_ctrl; + + ADPT_DEV_ID_CHECK(dev_id); + + rv = adpt_hppe_fdb_port_maclimit_ctrl_get(dev_id, port_id, &maclimit_ctrl); + if( rv != SW_OK ) + return rv; + + maclimit_ctrl.enable = enable; + maclimit_ctrl.limit_num = cnt; + + return adpt_hppe_fdb_port_maclimit_ctrl_set(dev_id, port_id, &maclimit_ctrl); +} + +sw_error_t +adpt_hppe_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 = SW_OK; + fal_maclimit_ctrl_t maclimit_ctrl; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + ADPT_NULL_POINT_CHECK(cnt); + + rv = adpt_hppe_fdb_port_maclimit_ctrl_get(dev_id, port_id, &maclimit_ctrl); + if( rv != SW_OK ) + return rv; + + *enable = maclimit_ctrl.enable; + *cnt = maclimit_ctrl.limit_num; + + return SW_OK; +} + +sw_error_t +adpt_hppe_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 = SW_OK; + fal_fdb_entry_t entry; + int i, cmd_id = 0x0, entry_index = 0x0, id; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(addr); + + _remove_port_type(&port_id); + + aos_mem_zero(&entry, sizeof (fal_fdb_entry_t)); + + entry.fid = fid; + for (i = 0; i < 6; i++) + entry.addr.uc[i] = addr->uc[i]; + + rv = _get_fdb_table_entryindex_by_entry(dev_id, &entry, &entry_index, cmd_id); + if (rv != SW_OK) + return rv; + + cmd_id = entry_index % OP_CMD_ID_SIZE; + rv = _get_fdb_table_entry_by_entryindex(dev_id, &entry, entry_index, cmd_id); + if (rv != SW_OK) + return rv; + + if (entry.portmap_en == A_TRUE) + { + if (port_id >= 12) + return SW_FAIL; + entry.port.map |= (0x1 << port_id); + } + else + { + if (port_id >= 12 || entry.port.id >= 12) + return SW_FAIL; + entry.portmap_en = A_TRUE; + id = entry.port.id; + entry.port.map = 0; + entry.port.map |= (0x1 << id); + entry.port.map |= (0x1 << port_id); + } + + return adpt_hppe_fdb_add(dev_id, &entry); +} + +sw_error_t +adpt_hppe_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 = SW_OK; + fal_fdb_entry_t entry; + int i, cmd_id = 0x0, entry_index = 0x0, id; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(addr); + + _remove_port_type(&port_id); + + aos_mem_zero(&entry, sizeof (fal_fdb_entry_t)); + + entry.fid = fid; + for (i = 0; i < 6; i++) + entry.addr.uc[i] = addr->uc[i]; + + rv = _get_fdb_table_entryindex_by_entry(dev_id, &entry, &entry_index, cmd_id); + if (rv != SW_OK) + return rv; + + cmd_id = entry_index % OP_CMD_ID_SIZE; + rv = _get_fdb_table_entry_by_entryindex(dev_id, &entry, entry_index, cmd_id); + if (rv != SW_OK) + return rv; + + if (entry.portmap_en == A_TRUE) + { + if (((entry.port.map >> port_id) & 0x1) == 1) + { + id = entry.port.map & (~(0x1 << port_id)); + if (id == 0) + { + rv = _modify_fdb_table_entry(dev_id, &entry, OP_TYPE_DEL, 0x0); + } + else + { + entry.port.map &= (~(0x1 << port_id)); + rv = adpt_hppe_fdb_add(dev_id, &entry); + } + } + } + else + { + if (entry.port.id == port_id) + rv = _modify_fdb_table_entry(dev_id, &entry, OP_TYPE_DEL, 0x0); + } + + return rv; +} +#endif +sw_error_t +adpt_hppe_fdb_port_learn_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv = SW_OK; + union port_bridge_ctrl_u port_bridge_ctrl = {0}; + + ADPT_DEV_ID_CHECK(dev_id); + + rv = hppe_port_bridge_ctrl_get(dev_id, port_id, &port_bridge_ctrl); + + if( rv != SW_OK ) + return rv; + + port_bridge_ctrl.bf.new_addr_lrn_en = enable; + port_bridge_ctrl.bf.station_move_lrn_en = enable; + + return hppe_port_bridge_ctrl_set(dev_id, port_id, &port_bridge_ctrl); +} +#ifndef IN_FDB_MINI +sw_error_t +adpt_hppe_fdb_port_learn_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable) +{ + sw_error_t rv = SW_OK; + union port_bridge_ctrl_u port_bridge_ctrl = {0}; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + + rv = hppe_port_bridge_ctrl_get(dev_id, port_id, &port_bridge_ctrl); + + if( rv != SW_OK ) + return rv; + + *enable = port_bridge_ctrl.bf.new_addr_lrn_en; + + return SW_OK; +} +#endif +sw_error_t +adpt_hppe_fdb_port_newaddr_lrn_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable, fal_fwd_cmd_t cmd) +{ + sw_error_t rv = SW_OK; + union port_bridge_ctrl_u port_bridge_ctrl; + + memset(&port_bridge_ctrl, 0, sizeof(port_bridge_ctrl)); + ADPT_DEV_ID_CHECK(dev_id); + + rv = hppe_port_bridge_ctrl_get(dev_id, port_id, &port_bridge_ctrl); + + if( rv != SW_OK ) + return rv; + + port_bridge_ctrl.bf.new_addr_lrn_en = enable; + port_bridge_ctrl.bf.new_addr_fwd_cmd = cmd; + + return hppe_port_bridge_ctrl_set(dev_id, port_id, &port_bridge_ctrl); +} +#ifndef IN_FDB_MINI +sw_error_t +adpt_hppe_fdb_port_newaddr_lrn_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable, fal_fwd_cmd_t *cmd) +{ + sw_error_t rv = SW_OK; + union port_bridge_ctrl_u port_bridge_ctrl; + + memset(&port_bridge_ctrl, 0, sizeof(port_bridge_ctrl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + ADPT_NULL_POINT_CHECK(cmd); + + rv = hppe_port_bridge_ctrl_get(dev_id, port_id, &port_bridge_ctrl); + + if( rv != SW_OK ) + return rv; + + *enable = port_bridge_ctrl.bf.new_addr_lrn_en; + *cmd = port_bridge_ctrl.bf.new_addr_fwd_cmd; + + return SW_OK; +} +#endif +sw_error_t +adpt_hppe_fdb_port_stamove_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable, fal_fwd_cmd_t cmd) +{ + sw_error_t rv = SW_OK; + union port_bridge_ctrl_u port_bridge_ctrl; + + memset(&port_bridge_ctrl, 0, sizeof(port_bridge_ctrl)); + ADPT_DEV_ID_CHECK(dev_id); + + rv = hppe_port_bridge_ctrl_get(dev_id, port_id, &port_bridge_ctrl); + + if( rv != SW_OK ) + return rv; + + port_bridge_ctrl.bf.station_move_lrn_en = enable; + port_bridge_ctrl.bf.station_move_fwd_cmd = cmd; + + return hppe_port_bridge_ctrl_set(dev_id, port_id, &port_bridge_ctrl); +} +#ifndef IN_FDB_MINI +sw_error_t +adpt_hppe_fdb_port_stamove_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable, fal_fwd_cmd_t *cmd) +{ + sw_error_t rv = SW_OK; + union port_bridge_ctrl_u port_bridge_ctrl; + + memset(&port_bridge_ctrl, 0, sizeof(port_bridge_ctrl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + ADPT_NULL_POINT_CHECK(cmd); + + rv = hppe_port_bridge_ctrl_get(dev_id, port_id, &port_bridge_ctrl); + + if( rv != SW_OK ) + return rv; + + *enable = port_bridge_ctrl.bf.station_move_lrn_en; + *cmd = port_bridge_ctrl.bf.station_move_fwd_cmd; + + return SW_OK; +} + +sw_error_t +adpt_hppe_port_fdb_learn_counter_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * cnt) +{ + sw_error_t rv = SW_OK; + union port_lrn_limit_counter_u port_lrn_limit_counter = {0}; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cnt); + + rv = hppe_port_lrn_limit_counter_get(dev_id, port_id, &port_lrn_limit_counter); + + if( rv != SW_OK ) + return rv; + + *cnt = port_lrn_limit_counter.bf.lrn_cnt; + + return SW_OK; +} + +sw_error_t +adpt_hppe_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 = SW_OK; + fal_maclimit_ctrl_t maclimit_ctrl; + + ADPT_DEV_ID_CHECK(dev_id); + + rv = adpt_hppe_fdb_port_maclimit_ctrl_get(dev_id, port_id, &maclimit_ctrl); + if( rv != SW_OK ) + return rv; + + maclimit_ctrl.action = cmd; + + return adpt_hppe_fdb_port_maclimit_ctrl_set(dev_id, port_id, &maclimit_ctrl); +} + +sw_error_t +adpt_hppe_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 = SW_OK; + fal_maclimit_ctrl_t maclimit_ctrl; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cmd); + + rv = adpt_hppe_fdb_port_maclimit_ctrl_get(dev_id, port_id, &maclimit_ctrl); + if( rv != SW_OK ) + return rv; + + *cmd = maclimit_ctrl.action; + + return SW_OK; +} +#endif +sw_error_t +adpt_hppe_fdb_age_ctrl_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv = SW_OK; + union l2_global_conf_u l2_global_conf = {0}; + + ADPT_DEV_ID_CHECK(dev_id); + + rv = hppe_l2_global_conf_get(dev_id, &l2_global_conf); + + if( rv != SW_OK ) + return rv; + + l2_global_conf.bf.age_en = enable; + + return hppe_l2_global_conf_set(dev_id, &l2_global_conf); +} +#ifndef IN_FDB_MINI +sw_error_t +adpt_hppe_fdb_age_ctrl_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv = SW_OK; + union l2_global_conf_u l2_global_conf = {0}; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + + rv = hppe_l2_global_conf_get(dev_id, &l2_global_conf); + + if( rv != SW_OK ) + return rv; + + *enable = l2_global_conf.bf.age_en; + + return SW_OK; +} +#endif +sw_error_t +adpt_hppe_fdb_del_by_fid(a_uint32_t dev_id, a_uint16_t fid, a_uint32_t flag) +{ + a_uint32_t entry_index, cmd_id = 0; + sw_error_t rv = SW_OK; + fal_fdb_entry_t entry; + + ADPT_DEV_ID_CHECK(dev_id); + + for (entry_index = 0; entry_index < FDB_TBL_NUM; entry_index++) + { + cmd_id = entry_index % OP_CMD_ID_SIZE; + aos_mem_zero(&entry, sizeof (fal_fdb_entry_t)); + rv = _get_fdb_table_entry_by_entryindex(dev_id, &entry, entry_index, cmd_id); + + if (rv == SW_NOT_FOUND) + { + continue; + } + else if (rv == SW_OK) + { + if (entry.fid == fid && + ((!flag && entry.static_en == A_FALSE) || (flag & FAL_FDB_DEL_STATIC))) + { + rv = _modify_fdb_table_entry(dev_id, &entry, OP_TYPE_DEL, 0x0); + if (rv != SW_OK) + { + return rv; + } + } + } + else + { + return rv; + } + } + + return SW_OK; +} + +void adpt_hppe_fdb_func_bitmap_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_fdb_func_bitmap[0] = ((1 << FUNC_FDB_ENTRY_ADD) | + (1 << FUNC_FDB_ENTRY_FLUSH) | + (1 << FUNC_FDB_ENTRY_DEL_BYPORT) | + (1 << FUNC_FDB_ENTRY_DEL_BYMAC) | + (1 << FUNC_FDB_ENTRY_GETFIRST) | + (1 << FUNC_FDB_ENTRY_GETNEXT) | + (1 << FUNC_FDB_ENTRY_SEARCH) | + (1 << FUNC_FDB_PORT_LEARN_SET) | + (1 << FUNC_FDB_PORT_LEARN_GET) | + (1 << FUNC_FDB_PORT_LEARNING_CTRL_SET) | + (1 << FUNC_FDB_PORT_LEARNING_CTRL_GET) | + (1 << FUNC_FDB_PORT_STAMOVE_CTRL_SET) | + (1 << FUNC_FDB_PORT_STAMOVE_CTRL_GET) | + (1 << FUNC_FDB_AGING_CTRL_SET) | + (1 << FUNC_FDB_AGING_CTRL_GET) | + (1 << FUNC_FDB_LEARNING_CTRL_SET) | + (1 << FUNC_FDB_LEARNING_CTRL_GET) | + (1 << FUNC_FDB_AGING_TIME_SET) | + (1 << FUNC_FDB_AGING_TIME_GET) | + (1 << FUNC_FDB_ENTRY_GETNEXT_BYINDEX) | + (1 << FUNC_FDB_ENTRY_EXTEND_GETNEXT) | + (1 << FUNC_FDB_ENTRY_EXTEND_GETFIRST) | + (1 << FUNC_FDB_ENTRY_UPDATE_BYPORT) | + (1 << FUNC_PORT_FDB_LEARN_LIMIT_SET) | + (1 << FUNC_PORT_FDB_LEARN_LIMIT_GET) | + (1 << FUNC_PORT_FDB_LEARN_EXCEED_CMD_SET) | + (1 << FUNC_PORT_FDB_LEARN_EXCEED_CMD_GET) | + (1 << FUNC_FDB_PORT_LEARNED_MAC_COUNTER_GET) | + (1 << FUNC_FDB_PORT_ADD) | + (1 << FUNC_FDB_PORT_DEL) | + (1 << FUNC_FDB_PORT_MACLIMIT_CTRL_SET) | + (1 << FUNC_FDB_PORT_MACLIMIT_CTRL_GET)); + p_adpt_api->adpt_fdb_func_bitmap[1] = ((1 << (FUNC_FDB_DEL_BY_FID % 32))); + + return; +} + +static void adpt_hppe_fdb_func_unregister(a_uint32_t dev_id, adpt_api_t *p_adpt_api) +{ + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_fdb_first = NULL; + p_adpt_api->adpt_fdb_next = NULL; + p_adpt_api->adpt_fdb_add = NULL; + p_adpt_api->adpt_fdb_del_by_port = NULL; + p_adpt_api->adpt_fdb_del_by_mac = NULL; + p_adpt_api->adpt_fdb_del_all = NULL; + p_adpt_api->adpt_fdb_transfer = NULL; + p_adpt_api->adpt_fdb_find = NULL; + p_adpt_api->adpt_fdb_iterate = NULL; + p_adpt_api->adpt_fdb_age_time_set = NULL; + p_adpt_api->adpt_fdb_age_time_get = NULL; + p_adpt_api->adpt_fdb_extend_first = NULL; + p_adpt_api->adpt_fdb_extend_next = NULL; + p_adpt_api->adpt_fdb_learn_ctrl_set = NULL; + p_adpt_api->adpt_fdb_learn_ctrl_get = NULL; + p_adpt_api->adpt_port_fdb_learn_limit_set = NULL; + p_adpt_api->adpt_port_fdb_learn_limit_get = NULL; + p_adpt_api->adpt_fdb_port_add = NULL; + p_adpt_api->adpt_fdb_port_del = NULL; + p_adpt_api->adpt_fdb_port_learn_set = NULL; + p_adpt_api->adpt_fdb_port_learn_get = NULL; + p_adpt_api->adpt_fdb_port_newaddr_lrn_set = NULL; + p_adpt_api->adpt_fdb_port_newaddr_lrn_get = NULL; + p_adpt_api->adpt_fdb_port_stamove_set = NULL; + p_adpt_api->adpt_fdb_port_stamove_get = NULL; + p_adpt_api->adpt_port_fdb_learn_counter_get = NULL; + p_adpt_api->adpt_port_fdb_learn_exceed_cmd_set = NULL; + p_adpt_api->adpt_port_fdb_learn_exceed_cmd_get = NULL; + p_adpt_api->adpt_fdb_age_ctrl_set = NULL; + p_adpt_api->adpt_fdb_age_ctrl_get = NULL; + p_adpt_api->adpt_fdb_port_maclimit_ctrl_set = NULL; + p_adpt_api->adpt_fdb_port_maclimit_ctrl_get = NULL; + p_adpt_api->adpt_fdb_del_by_fid = NULL; + + return; +} + +sw_error_t adpt_hppe_fdb_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return SW_FAIL; + + adpt_hppe_fdb_func_unregister(dev_id, p_adpt_api); + + if (p_adpt_api->adpt_fdb_func_bitmap[0] & (1 << FUNC_FDB_ENTRY_GETFIRST)) + p_adpt_api->adpt_fdb_first = adpt_hppe_fdb_first; +#ifndef IN_FDB_MINI + if (p_adpt_api->adpt_fdb_func_bitmap[0] & (1 << FUNC_FDB_ENTRY_GETNEXT)) + p_adpt_api->adpt_fdb_next = adpt_hppe_fdb_next; +#endif + if (p_adpt_api->adpt_fdb_func_bitmap[0] & (1 << FUNC_FDB_ENTRY_ADD)) + p_adpt_api->adpt_fdb_add = adpt_hppe_fdb_add; + if (p_adpt_api->adpt_fdb_func_bitmap[0] & (1 << FUNC_FDB_ENTRY_DEL_BYPORT)) + p_adpt_api->adpt_fdb_del_by_port = adpt_hppe_fdb_del_by_port; + if (p_adpt_api->adpt_fdb_func_bitmap[0] & (1 << FUNC_FDB_ENTRY_DEL_BYMAC)) + p_adpt_api->adpt_fdb_del_by_mac = adpt_hppe_fdb_del_by_mac; + if (p_adpt_api->adpt_fdb_func_bitmap[0] & (1 << FUNC_FDB_ENTRY_FLUSH)) + p_adpt_api->adpt_fdb_del_all = adpt_hppe_fdb_del_all; +#ifndef IN_FDB_MINI + if (p_adpt_api->adpt_fdb_func_bitmap[0] & (1 << FUNC_FDB_ENTRY_UPDATE_BYPORT)) + p_adpt_api->adpt_fdb_transfer = adpt_hppe_fdb_transfer; +#endif + if (p_adpt_api->adpt_fdb_func_bitmap[0] & (1 << FUNC_FDB_ENTRY_SEARCH)) + p_adpt_api->adpt_fdb_find = adpt_hppe_fdb_find; + if (p_adpt_api->adpt_fdb_func_bitmap[0] & (1 << FUNC_FDB_ENTRY_GETNEXT_BYINDEX)) + p_adpt_api->adpt_fdb_iterate = adpt_hppe_fdb_iterate; +#ifndef IN_FDB_MINI + if (p_adpt_api->adpt_fdb_func_bitmap[0] & (1 << FUNC_FDB_AGING_TIME_SET)) + p_adpt_api->adpt_fdb_age_time_set = adpt_hppe_fdb_age_time_set; + if (p_adpt_api->adpt_fdb_func_bitmap[0] & (1 << FUNC_FDB_AGING_TIME_GET)) + p_adpt_api->adpt_fdb_age_time_get = adpt_hppe_fdb_age_time_get; +#endif + if (p_adpt_api->adpt_fdb_func_bitmap[0] & (1 << FUNC_FDB_ENTRY_EXTEND_GETFIRST)) + p_adpt_api->adpt_fdb_extend_first = adpt_hppe_fdb_extend_first; + if (p_adpt_api->adpt_fdb_func_bitmap[0] & (1 << FUNC_FDB_ENTRY_EXTEND_GETNEXT)) + p_adpt_api->adpt_fdb_extend_next = adpt_hppe_fdb_extend_next; + if (p_adpt_api->adpt_fdb_func_bitmap[0] & (1 << FUNC_FDB_LEARNING_CTRL_SET)) + p_adpt_api->adpt_fdb_learn_ctrl_set = adpt_hppe_fdb_learn_ctrl_set; +#ifndef IN_FDB_MINI + if (p_adpt_api->adpt_fdb_func_bitmap[0] & (1 << FUNC_FDB_LEARNING_CTRL_GET)) + p_adpt_api->adpt_fdb_learn_ctrl_get = adpt_hppe_fdb_learn_ctrl_get; + if (p_adpt_api->adpt_fdb_func_bitmap[0] & (1 << FUNC_PORT_FDB_LEARN_LIMIT_SET)) + p_adpt_api->adpt_port_fdb_learn_limit_set = adpt_hppe_port_fdb_learn_limit_set; + if (p_adpt_api->adpt_fdb_func_bitmap[0] & (1 << FUNC_PORT_FDB_LEARN_LIMIT_GET)) + p_adpt_api->adpt_port_fdb_learn_limit_get = adpt_hppe_port_fdb_learn_limit_get; + if (p_adpt_api->adpt_fdb_func_bitmap[0] & (1 << FUNC_FDB_PORT_ADD)) + p_adpt_api->adpt_fdb_port_add = adpt_hppe_fdb_port_add; + if (p_adpt_api->adpt_fdb_func_bitmap[0] & (1 << FUNC_FDB_PORT_DEL)) + p_adpt_api->adpt_fdb_port_del = adpt_hppe_fdb_port_del; +#endif + if (p_adpt_api->adpt_fdb_func_bitmap[0] & (1 << FUNC_FDB_PORT_LEARN_SET)) + p_adpt_api->adpt_fdb_port_learn_set = adpt_hppe_fdb_port_learn_set; +#ifndef IN_FDB_MINI + if (p_adpt_api->adpt_fdb_func_bitmap[0] & (1 << FUNC_FDB_PORT_LEARN_GET)) + p_adpt_api->adpt_fdb_port_learn_get = adpt_hppe_fdb_port_learn_get; +#endif + if (p_adpt_api->adpt_fdb_func_bitmap[0] & (1 << FUNC_FDB_PORT_LEARNING_CTRL_SET)) + p_adpt_api->adpt_fdb_port_newaddr_lrn_set = adpt_hppe_fdb_port_newaddr_lrn_set; +#ifndef IN_FDB_MINI + if (p_adpt_api->adpt_fdb_func_bitmap[0] & (1 << FUNC_FDB_PORT_LEARNING_CTRL_GET)) + p_adpt_api->adpt_fdb_port_newaddr_lrn_get = adpt_hppe_fdb_port_newaddr_lrn_get; +#endif + if (p_adpt_api->adpt_fdb_func_bitmap[0] & (1 << FUNC_FDB_PORT_STAMOVE_CTRL_SET)) + p_adpt_api->adpt_fdb_port_stamove_set = adpt_hppe_fdb_port_stamove_set; +#ifndef IN_FDB_MINI + if (p_adpt_api->adpt_fdb_func_bitmap[0] & (1 << FUNC_FDB_PORT_STAMOVE_CTRL_GET)) + p_adpt_api->adpt_fdb_port_stamove_get = adpt_hppe_fdb_port_stamove_get; + if (p_adpt_api->adpt_fdb_func_bitmap[0] & (1 << FUNC_FDB_PORT_LEARNED_MAC_COUNTER_GET)) + p_adpt_api->adpt_port_fdb_learn_counter_get = adpt_hppe_port_fdb_learn_counter_get; + if (p_adpt_api->adpt_fdb_func_bitmap[0] & (1 << FUNC_PORT_FDB_LEARN_EXCEED_CMD_SET)) + p_adpt_api->adpt_port_fdb_learn_exceed_cmd_set = adpt_hppe_port_fdb_learn_exceed_cmd_set; + if (p_adpt_api->adpt_fdb_func_bitmap[0] & (1 << FUNC_PORT_FDB_LEARN_EXCEED_CMD_GET)) + p_adpt_api->adpt_port_fdb_learn_exceed_cmd_get = adpt_hppe_port_fdb_learn_exceed_cmd_get; +#endif + if (p_adpt_api->adpt_fdb_func_bitmap[0] & (1 << FUNC_FDB_AGING_CTRL_SET)) + p_adpt_api->adpt_fdb_age_ctrl_set = adpt_hppe_fdb_age_ctrl_set; +#ifndef IN_FDB_MINI + if (p_adpt_api->adpt_fdb_func_bitmap[0] & (1 << FUNC_FDB_AGING_CTRL_GET)) + p_adpt_api->adpt_fdb_age_ctrl_get = adpt_hppe_fdb_age_ctrl_get; + if (p_adpt_api->adpt_fdb_func_bitmap[0] & (1 << FUNC_FDB_PORT_MACLIMIT_CTRL_SET)) + p_adpt_api->adpt_fdb_port_maclimit_ctrl_set = adpt_hppe_fdb_port_maclimit_ctrl_set; + if (p_adpt_api->adpt_fdb_func_bitmap[0] & (1 << FUNC_FDB_PORT_MACLIMIT_CTRL_GET)) + p_adpt_api->adpt_fdb_port_maclimit_ctrl_get = adpt_hppe_fdb_port_maclimit_ctrl_get; +#endif + if (p_adpt_api->adpt_fdb_func_bitmap[1] & (1 << (FUNC_FDB_DEL_BY_FID % 32))) + p_adpt_api->adpt_fdb_del_by_fid = adpt_hppe_fdb_del_by_fid; + + aos_lock_init(&hppe_fdb_lock); + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_flow.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_flow.c new file mode 100755 index 000000000..9302a4cb0 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_flow.c @@ -0,0 +1,1850 @@ +/* + * 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. + */ + + +/** + * @defgroup + * @{ + */ +#include "sw.h" +#include "fal_flow.h" +#include "hppe_ip_reg.h" +#include "hppe_ip.h" +#include "hppe_flow_reg.h" +#include "hppe_flow.h" +#include "adpt_hppe.h" +#include "adpt.h" + +#if defined(CPPE) +#include "adpt_cppe_flow.h" +#endif + + +#define FLOW_ENTRY_TYPE_IPV4 0 +#define FLOW_ENTRY_TYPE_IPV6 1 +#define FLOW_TUPLE_TYPE_3 0 + +#ifndef IN_FLOW_MINI +sw_error_t +adpt_hppe_ip_flow_host_data_rd_add(a_uint32_t dev_id, fal_host_entry_t * host_entry) + +{ + a_uint8_t mode = 0, type = 0; + sw_error_t rv = SW_OK; + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(host_entry); + + mode = host_entry->flags >> 24; + type = host_entry->flags & 0xff; + + if ((type & FAL_IP_IP4_ADDR) == FAL_IP_IP4_ADDR) { + union host_tbl_u entry; + entry.bf.valid= host_entry->status; + entry.bf.key_type = 0; + entry.bf.fwd_cmd = host_entry->action; + entry.bf.syn_toggle = host_entry->syn_toggle; + entry.bf.dst_info = host_entry->port_id; + entry.bf.lan_wan = host_entry->lan_wan; + entry.bf.ip_addr = host_entry->ip4_addr; + rv = hppe_flow_host_ipv4_data_rd_add(dev_id, (a_uint32_t)mode, &host_entry->entry_id, &entry); + } else if ((type & FAL_IP_IP6_ADDR) == FAL_IP_IP6_ADDR) { + union host_ipv6_tbl_u entry; + entry.bf.valid= host_entry->status; + entry.bf.key_type = 2; + entry.bf.fwd_cmd = host_entry->action; + entry.bf.syn_toggle = host_entry->syn_toggle; + entry.bf.dst_info = host_entry->port_id; + entry.bf.lan_wan = host_entry->lan_wan; + entry.bf.ipv6_addr_0 = host_entry->ip6_addr.ul[3]; + entry.bf.ipv6_addr_1 = host_entry->ip6_addr.ul[3] >> 10 | \ + host_entry->ip6_addr.ul[2] << 22; + entry.bf.ipv6_addr_2 = host_entry->ip6_addr.ul[2] >> 10 | \ + host_entry->ip6_addr.ul[1] << 22; + entry.bf.ipv6_addr_3 = host_entry->ip6_addr.ul[1] >> 10 | \ + host_entry->ip6_addr.ul[0] << 22; + entry.bf.ipv6_addr_4 = host_entry->ip6_addr.ul[0] >> 10; + rv = hppe_flow_host_ipv6_data_rd_add(dev_id, (a_uint32_t)mode, &host_entry->entry_id, &entry); + } + + return SW_OK; +} + +sw_error_t +adpt_hppe_ip_flow_host_data_add(a_uint32_t dev_id, fal_host_entry_t * host_entry) +{ + a_uint8_t mode = 0, type = 0; + sw_error_t rv = SW_OK; + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(host_entry); + + mode = host_entry->flags >> 24; + type = host_entry->flags & 0xff; + + if ((type & FAL_IP_IP4_ADDR) == FAL_IP_IP4_ADDR) { + union host_tbl_u entry; + entry.bf.valid= host_entry->status; + entry.bf.key_type = 0; + entry.bf.fwd_cmd = host_entry->action; + entry.bf.syn_toggle = host_entry->syn_toggle; + entry.bf.dst_info = host_entry->port_id; + entry.bf.lan_wan = host_entry->lan_wan; + entry.bf.ip_addr = host_entry->ip4_addr; + rv = hppe_flow_host_ipv4_data_add(dev_id, (a_uint32_t)mode, &host_entry->entry_id, &entry); + } else if ((type & FAL_IP_IP6_ADDR) == FAL_IP_IP6_ADDR) { + union host_ipv6_tbl_u entry; + entry.bf.valid= host_entry->status; + entry.bf.key_type = 2; + entry.bf.fwd_cmd = host_entry->action; + entry.bf.syn_toggle = host_entry->syn_toggle; + entry.bf.dst_info = host_entry->port_id; + entry.bf.lan_wan = host_entry->lan_wan; + entry.bf.ipv6_addr_0 = host_entry->ip6_addr.ul[3]; + entry.bf.ipv6_addr_1 = host_entry->ip6_addr.ul[3] >> 10 | \ + host_entry->ip6_addr.ul[2] << 22; + entry.bf.ipv6_addr_2 = host_entry->ip6_addr.ul[2] >> 10 | \ + host_entry->ip6_addr.ul[1] << 22; + entry.bf.ipv6_addr_3 = host_entry->ip6_addr.ul[1] >> 10 | \ + host_entry->ip6_addr.ul[0] << 22; + entry.bf.ipv6_addr_4 = host_entry->ip6_addr.ul[0] >> 10; + rv = hppe_flow_host_ipv6_data_add(dev_id, (a_uint32_t)mode, &host_entry->entry_id, &entry); + } + + return SW_OK; +} + +sw_error_t +adpt_hppe_ip_flow_host_data_get(a_uint32_t dev_id, a_uint32_t get_mode, + fal_host_entry_t *host_entry) +{ + a_uint8_t mode = 0, type = 0; + sw_error_t rv = SW_OK; + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(host_entry); + + mode = host_entry->flags >> 24; + type = host_entry->flags & 0xff; + + if (get_mode & FAL_IP_ENTRY_ID_EN) + mode = 1; + else if (get_mode & FAL_IP_ENTRY_IPADDR_EN) + mode = 0; + + if ((type & FAL_IP_IP4_ADDR) == FAL_IP_IP4_ADDR) { + union host_tbl_u entry; + entry.bf.key_type = 0; + entry.bf.ip_addr = host_entry->ip4_addr; + rv = hppe_flow_host_ipv4_data_get(dev_id, (a_uint32_t)mode, &host_entry->entry_id, &entry); + host_entry->ip4_addr = entry.bf.ip_addr; + host_entry->lan_wan = entry.bf.lan_wan; + host_entry->port_id = entry.bf.dst_info; + host_entry->syn_toggle = entry.bf.syn_toggle; + host_entry->action = entry.bf.fwd_cmd; + host_entry->status = entry.bf.valid; + } else if ((type & FAL_IP_IP6_ADDR) == FAL_IP_IP6_ADDR) { + union host_ipv6_tbl_u entry; + entry.bf.key_type = 2; + entry.bf.ipv6_addr_0 = host_entry->ip6_addr.ul[3]; + entry.bf.ipv6_addr_1 = host_entry->ip6_addr.ul[3] >> 10 | \ + host_entry->ip6_addr.ul[2] << 22; + entry.bf.ipv6_addr_2 = host_entry->ip6_addr.ul[2] >> 10 | \ + host_entry->ip6_addr.ul[1] << 22; + entry.bf.ipv6_addr_3 = host_entry->ip6_addr.ul[1] >> 10 | \ + host_entry->ip6_addr.ul[0] << 22; + entry.bf.ipv6_addr_4 = host_entry->ip6_addr.ul[0] >> 10; + rv = hppe_flow_host_ipv6_data_get(dev_id, (a_uint32_t)mode, &host_entry->entry_id, &entry); + host_entry->ip6_addr.ul[3] = entry.bf.ipv6_addr_0 | entry.bf.ipv6_addr_1 << 10; + host_entry->ip6_addr.ul[2] = entry.bf.ipv6_addr_1 >> 22 | entry.bf.ipv6_addr_2 << 10; + host_entry->ip6_addr.ul[1] = entry.bf.ipv6_addr_2 >> 22 | entry.bf.ipv6_addr_3 << 10; + host_entry->ip6_addr.ul[0] = entry.bf.ipv6_addr_3 >> 22 | entry.bf.ipv6_addr_4 << 10; + host_entry->lan_wan = entry.bf.lan_wan; + host_entry->port_id = entry.bf.dst_info; + host_entry->syn_toggle = entry.bf.syn_toggle; + host_entry->action = entry.bf.fwd_cmd; + host_entry->status = entry.bf.valid; + } + return rv; +} + +sw_error_t +adpt_hppe_ip_flow_host_data_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_host_entry_t * host_entry) +{ + a_uint8_t mode = 0, type = 0; + sw_error_t rv = SW_OK; + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(host_entry); + + mode = host_entry->flags >> 24; + type = host_entry->flags & 0xff; + + if (del_mode & FAL_IP_ENTRY_ID_EN) + mode = 1; + else if (del_mode & FAL_IP_ENTRY_IPADDR_EN) + mode = 0; + else if (del_mode & FAL_IP_ENTRY_ALL_EN) { + return hppe_flow_host_flush_common(dev_id); + } + + if ((type & FAL_IP_IP4_ADDR) == FAL_IP_IP4_ADDR) { + union host_tbl_u entry; + entry.bf.valid= 1; + entry.bf.key_type = 0; + entry.bf.fwd_cmd = host_entry->action; + entry.bf.syn_toggle = host_entry->syn_toggle; + entry.bf.dst_info = host_entry->port_id; + entry.bf.lan_wan = host_entry->lan_wan; + entry.bf.ip_addr = host_entry->ip4_addr; + rv = hppe_flow_host_ipv4_data_del(dev_id, (a_uint32_t)mode, &host_entry->entry_id, &entry); + } else if ((type & FAL_IP_IP6_ADDR) == FAL_IP_IP6_ADDR) { + union host_ipv6_tbl_u entry; + entry.bf.valid= 1; + entry.bf.key_type = 2; + entry.bf.fwd_cmd = host_entry->action; + entry.bf.syn_toggle = host_entry->syn_toggle; + entry.bf.dst_info = host_entry->port_id; + entry.bf.lan_wan = host_entry->lan_wan; + entry.bf.ipv6_addr_0 = host_entry->ip6_addr.ul[3]; + entry.bf.ipv6_addr_1 = host_entry->ip6_addr.ul[3] >> 10 | \ + host_entry->ip6_addr.ul[2] << 22; + entry.bf.ipv6_addr_2 = host_entry->ip6_addr.ul[2] >> 10 | \ + host_entry->ip6_addr.ul[1] << 22; + entry.bf.ipv6_addr_3 = host_entry->ip6_addr.ul[1] >> 10 | \ + host_entry->ip6_addr.ul[0] << 22; + entry.bf.ipv6_addr_4 = host_entry->ip6_addr.ul[0] >> 10; + rv = hppe_flow_host_ipv6_data_del(dev_id, (a_uint32_t)mode, &host_entry->entry_id, &entry); + } + return rv; +} + + +sw_error_t +adpt_hppe_flow_entry_host_op_add( + a_uint32_t dev_id, + a_uint32_t add_mode, /*index or hash*/ + fal_flow_entry_t *flow_entry) +{ + sw_error_t rv = SW_OK; + a_uint32_t type = 0; + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(flow_entry); + + type = flow_entry->entry_type; + if ((type & FAL_FLOW_IP4_5TUPLE_ADDR) == FAL_FLOW_IP4_5TUPLE_ADDR) { + union in_flow_tbl_u entry; + entry.bf0.valid= 1; + entry.bf0.entry_type = FLOW_ENTRY_TYPE_IPV4; + entry.bf0.host_addr_index_type = flow_entry->host_addr_type; + entry.bf0.host_addr_index = flow_entry->host_addr_index; + entry.bf0.protocol_type = flow_entry->protocol; + entry.bf0.age = flow_entry->age; + entry.bf0.src_l3_if_valid = flow_entry->src_intf_valid; + entry.bf0.src_l3_if = flow_entry->src_intf_index; + entry.bf0.fwd_type = flow_entry->fwd_type; + if (flow_entry->fwd_type == FAL_FLOW_SNAT) { + entry.bf0.next_hop1 = flow_entry->snat_nexthop; + entry.bf0.l4_port1 = flow_entry->snat_srcport; + } else if (flow_entry->fwd_type == FAL_FLOW_DNAT) { + entry.bf3.next_hop2 = flow_entry->dnat_nexthop; + entry.bf3.l4_port2 = flow_entry->dnat_dstport; + } else if (flow_entry->fwd_type == FAL_FLOW_ROUTE) { + entry.bf2.next_hop3 = flow_entry->route_nexthop; + entry.bf2.port_vp_valid1= flow_entry->port_valid; + entry.bf2.port_vp1 = flow_entry->route_port; + } else if (flow_entry->fwd_type == FAL_FLOW_BRIDGE) { + entry.bf1.port_vp2 = flow_entry->bridge_port; + } + entry.bf0.de_acce = flow_entry->deacclr_en; + entry.bf0.copy_to_cpu_en = flow_entry->copy_tocpu_en; + entry.bf0.syn_toggle = flow_entry->syn_toggle; + entry.bf0.pri_profile_0 = flow_entry->pri_profile; + entry.bf0.pri_profile_1 = flow_entry->pri_profile >> 1; + entry.bf0.service_code = flow_entry->sevice_code; + entry.bf0.ip_addr_0 = flow_entry->flow_ip.ipv4; + entry.bf0.ip_addr_1 = flow_entry->flow_ip.ipv4 >> 20; + entry.bf0.l4_sport = flow_entry->src_port; + entry.bf0.l4_dport_0 = flow_entry->dst_port; + entry.bf0.l4_dport_1 = flow_entry->dst_port >> 4; + rv = hppe_flow_entry_host_op_ipv4_5tuple_add(dev_id, (a_uint32_t)add_mode, &flow_entry->entry_id, &entry); + } else if ((type & FAL_FLOW_IP6_5TUPLE_ADDR) == FAL_FLOW_IP6_5TUPLE_ADDR) { + union in_flow_ipv6_5tuple_tbl_u entry; + entry.bf0.valid= 1; + entry.bf0.entry_type = FLOW_ENTRY_TYPE_IPV6; + entry.bf0.host_addr_index_type = flow_entry->host_addr_type; + entry.bf0.host_addr_index = flow_entry->host_addr_index; + entry.bf0.protocol_type = flow_entry->protocol; + entry.bf0.age = flow_entry->age; + entry.bf0.src_l3_if_valid = flow_entry->src_intf_valid; + entry.bf0.src_l3_if = flow_entry->src_intf_index; + entry.bf0.fwd_type = flow_entry->fwd_type; + if (flow_entry->fwd_type == FAL_FLOW_SNAT) { + entry.bf0.next_hop1 = flow_entry->snat_nexthop; + } else if (flow_entry->fwd_type == FAL_FLOW_DNAT) { + entry.bf3.next_hop2 = flow_entry->dnat_nexthop; + } else if (flow_entry->fwd_type == FAL_FLOW_ROUTE) { + entry.bf2.next_hop3 = flow_entry->route_nexthop; + entry.bf2.port_vp_valid1= flow_entry->port_valid; + entry.bf2.port_vp1 = flow_entry->route_port; + } else if (flow_entry->fwd_type == FAL_FLOW_BRIDGE) { + entry.bf1.port_vp2 = flow_entry->bridge_port; + } + entry.bf0.de_acce = flow_entry->deacclr_en; + entry.bf0.copy_to_cpu_en = flow_entry->copy_tocpu_en; + entry.bf0.syn_toggle = flow_entry->syn_toggle; + entry.bf0.pri_profile_0 = flow_entry->pri_profile; + entry.bf0.pri_profile_1 = flow_entry->pri_profile >> 1; + entry.bf0.service_code = flow_entry->sevice_code; + entry.bf0.ip_addr_0 = flow_entry->flow_ip.ipv6.ul[3]; + entry.bf0.ip_addr_1 = flow_entry->flow_ip.ipv6.ul[3] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[2] << 12; + entry.bf0.ip_addr_2 = flow_entry->flow_ip.ipv6.ul[2] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[1] << 12; + entry.bf0.ip_addr_3 = flow_entry->flow_ip.ipv6.ul[1] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[0] << 12; + entry.bf0.ip_addr_4 = flow_entry->flow_ip.ipv6.ul[0] >> 20; + entry.bf0.l4_sport = flow_entry->src_port; + entry.bf0.l4_dport_0 = flow_entry->dst_port; + entry.bf0.l4_dport_1 = flow_entry->dst_port >> 4; + rv = hppe_flow_entry_host_op_ipv6_5tuple_add(dev_id, (a_uint32_t)add_mode, &flow_entry->entry_id, &entry); + } else if ((type & FAL_FLOW_IP4_3TUPLE_ADDR) == FAL_FLOW_IP4_3TUPLE_ADDR) { + union in_flow_3tuple_tbl_u entry; + entry.bf0.valid= 1; + entry.bf0.entry_type = FLOW_ENTRY_TYPE_IPV4; + entry.bf0.host_addr_index_type = flow_entry->host_addr_type; + entry.bf0.host_addr_index = flow_entry->host_addr_index; + entry.bf0.protocol_type = flow_entry->protocol; + entry.bf0.age = flow_entry->age; + entry.bf0.src_l3_if_valid = flow_entry->src_intf_valid; + entry.bf0.src_l3_if = flow_entry->src_intf_index; + entry.bf0.fwd_type = flow_entry->fwd_type; + if (flow_entry->fwd_type == FAL_FLOW_SNAT) { + entry.bf0.next_hop1 = flow_entry->snat_nexthop; + } else if (flow_entry->fwd_type == FAL_FLOW_DNAT) { + entry.bf3.next_hop2 = flow_entry->dnat_nexthop; + } else if (flow_entry->fwd_type == FAL_FLOW_ROUTE) { + entry.bf2.next_hop3 = flow_entry->route_nexthop; + entry.bf2.port_vp_valid1= flow_entry->port_valid; + entry.bf2.port_vp1 = flow_entry->route_port; + } else if (flow_entry->fwd_type == FAL_FLOW_BRIDGE) { + entry.bf1.port_vp2 = flow_entry->bridge_port; + } + entry.bf0.de_acce = flow_entry->deacclr_en; + entry.bf0.copy_to_cpu_en = flow_entry->copy_tocpu_en; + entry.bf0.syn_toggle = flow_entry->syn_toggle; + entry.bf0.pri_profile_0 = flow_entry->pri_profile; + entry.bf0.pri_profile_1 = flow_entry->pri_profile >> 1; + entry.bf0.service_code = flow_entry->sevice_code; + entry.bf0.ip_addr_0 = flow_entry->flow_ip.ipv4; + entry.bf0.ip_addr_1 = flow_entry->flow_ip.ipv4 >> 20; + entry.bf0.ip_protocol = flow_entry->ip_type; + rv = hppe_flow_entry_host_op_ipv4_3tuple_add(dev_id, (a_uint32_t)add_mode, &flow_entry->entry_id, &entry); + } else if ((type & FAL_FLOW_IP6_3TUPLE_ADDR) == FAL_FLOW_IP6_3TUPLE_ADDR) { + union in_flow_ipv6_3tuple_tbl_u entry; + entry.bf0.valid= 1; + entry.bf0.entry_type = FLOW_ENTRY_TYPE_IPV6; + entry.bf0.host_addr_index_type = flow_entry->host_addr_type; + entry.bf0.host_addr_index = flow_entry->host_addr_index; + entry.bf0.protocol_type = flow_entry->protocol; + entry.bf0.age = flow_entry->age; + entry.bf0.src_l3_if_valid = flow_entry->src_intf_valid; + entry.bf0.src_l3_if = flow_entry->src_intf_index; + entry.bf0.fwd_type = flow_entry->fwd_type; + if (flow_entry->fwd_type == FAL_FLOW_SNAT) { + entry.bf1.next_hop1 = flow_entry->snat_nexthop; + } else if (flow_entry->fwd_type == FAL_FLOW_DNAT) { + entry.bf3.next_hop2 = flow_entry->dnat_nexthop; + } else if (flow_entry->fwd_type == FAL_FLOW_ROUTE) { + entry.bf2.next_hop3 = flow_entry->route_nexthop; + entry.bf2.port_vp_valid1= flow_entry->port_valid; + entry.bf2.port_vp1 = flow_entry->route_port; + } else if (flow_entry->fwd_type == FAL_FLOW_BRIDGE) { + entry.bf0.port_vp2 = flow_entry->bridge_port; + } + entry.bf0.de_acce = flow_entry->deacclr_en; + entry.bf0.copy_to_cpu_en = flow_entry->copy_tocpu_en; + entry.bf0.syn_toggle = flow_entry->syn_toggle; + entry.bf0.pri_profile_0 = flow_entry->pri_profile; + entry.bf0.pri_profile_1 = flow_entry->pri_profile >> 1; + entry.bf0.service_code = flow_entry->sevice_code; + entry.bf0.ip_addr_0 = flow_entry->flow_ip.ipv6.ul[3]; + entry.bf0.ip_addr_1 = flow_entry->flow_ip.ipv6.ul[3] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[2] << 12; + entry.bf0.ip_addr_2 = flow_entry->flow_ip.ipv6.ul[2] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[1] << 12; + entry.bf0.ip_addr_3 = flow_entry->flow_ip.ipv6.ul[1] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[0] << 12; + entry.bf0.ip_addr_4 = flow_entry->flow_ip.ipv6.ul[0] >> 20; + entry.bf0.ip_protocol = flow_entry->ip_type; + rv = hppe_flow_entry_host_op_ipv6_3tuple_add(dev_id, (a_uint32_t)add_mode, &flow_entry->entry_id, &entry); + } else + return SW_FAIL; + if (rv == SW_OK) { + union eg_flow_tree_map_tbl_u eg_treemap; + eg_treemap.bf.tree_id = flow_entry->tree_id; + rv = hppe_eg_flow_tree_map_tbl_set(dev_id, flow_entry->entry_id, &eg_treemap); + } + return rv; +} + +sw_error_t +adpt_hppe_flow_entry_host_op_get( + a_uint32_t dev_id, + a_uint32_t get_mode, + fal_flow_entry_t *flow_entry) +{ + sw_error_t rv = SW_OK; + a_uint32_t type = 0; + a_uint32_t entry_id = 0; + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(flow_entry); + + type = flow_entry->entry_type; + if ((type & FAL_FLOW_IP4_5TUPLE_ADDR) == FAL_FLOW_IP4_5TUPLE_ADDR) { + union in_flow_tbl_u entry; + entry.bf0.valid= 1; + entry.bf0.entry_type = FLOW_ENTRY_TYPE_IPV4; + entry.bf0.host_addr_index_type = flow_entry->host_addr_type; + entry.bf0.host_addr_index = flow_entry->host_addr_index; + entry.bf0.protocol_type = flow_entry->protocol; + entry.bf0.ip_addr_0 = flow_entry->flow_ip.ipv4; + entry.bf0.ip_addr_1 = flow_entry->flow_ip.ipv4 >> 20; + entry.bf0.l4_sport = flow_entry->src_port; + entry.bf0.l4_dport_0 = flow_entry->dst_port; + entry.bf0.l4_dport_1 = flow_entry->dst_port >> 4; + rv = hppe_flow_entry_host_op_ipv4_5tuple_get(dev_id, get_mode, &entry_id, &entry); + flow_entry->entry_id = entry_id; + flow_entry->host_addr_type = entry.bf0.host_addr_index_type; + flow_entry->host_addr_index = entry.bf0.host_addr_index; + flow_entry->protocol = entry.bf0.protocol_type; + flow_entry->age = entry.bf0.age; + flow_entry->src_intf_valid = entry.bf0.src_l3_if_valid; + flow_entry->src_intf_index = entry.bf0.src_l3_if; + flow_entry->fwd_type = entry.bf0.fwd_type; + if (flow_entry->fwd_type == FAL_FLOW_SNAT) { + flow_entry->snat_nexthop = entry.bf0.next_hop1; + flow_entry->snat_srcport = entry.bf0.l4_port1; + } else if (flow_entry->fwd_type == FAL_FLOW_DNAT) { + flow_entry->dnat_nexthop = entry.bf3.next_hop2; + flow_entry->dnat_dstport = entry.bf3.l4_port2; + } else if (flow_entry->fwd_type == FAL_FLOW_ROUTE) { + flow_entry->route_nexthop = entry.bf2.next_hop3; + flow_entry->port_valid = entry.bf2.port_vp_valid1; + flow_entry->route_port = entry.bf2.port_vp1; + } else if (flow_entry->fwd_type == FAL_FLOW_BRIDGE) { + flow_entry->bridge_port = entry.bf1.port_vp2; + } + flow_entry->deacclr_en = entry.bf0.de_acce; + flow_entry->copy_tocpu_en = entry.bf0.copy_to_cpu_en; + flow_entry->syn_toggle = entry.bf0.syn_toggle; + flow_entry->pri_profile = entry.bf0.pri_profile_0 |\ + entry.bf0.pri_profile_1 << 1; + flow_entry->sevice_code = entry.bf0.service_code; + flow_entry->flow_ip.ipv4 = entry.bf0.ip_addr_0 |\ + entry.bf0.ip_addr_1 << 20; + flow_entry->src_port = entry.bf0.l4_sport; + flow_entry->dst_port = entry.bf0.l4_dport_0 |\ + entry.bf0.l4_dport_1 << 4; + } else if ((type & FAL_FLOW_IP6_5TUPLE_ADDR) == FAL_FLOW_IP6_5TUPLE_ADDR) { + union in_flow_ipv6_5tuple_tbl_u entry; + entry.bf0.valid= 1; + entry.bf0.entry_type = FLOW_ENTRY_TYPE_IPV6; + entry.bf0.host_addr_index_type = flow_entry->host_addr_type; + entry.bf0.host_addr_index = flow_entry->host_addr_index; + entry.bf0.protocol_type = flow_entry->protocol; + entry.bf0.ip_addr_0 = flow_entry->flow_ip.ipv6.ul[3]; + entry.bf0.ip_addr_1 = flow_entry->flow_ip.ipv6.ul[3] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[2] << 12; + entry.bf0.ip_addr_2 = flow_entry->flow_ip.ipv6.ul[2] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[1] << 12; + entry.bf0.ip_addr_3 = flow_entry->flow_ip.ipv6.ul[1] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[0] << 12; + entry.bf0.ip_addr_4 = flow_entry->flow_ip.ipv6.ul[0] >> 20; + entry.bf0.l4_sport = flow_entry->src_port; + entry.bf0.l4_dport_0 = flow_entry->dst_port; + entry.bf0.l4_dport_1 = flow_entry->dst_port >> 4; + rv = hppe_flow_entry_host_op_ipv6_5tuple_get(dev_id, get_mode, &entry_id, &entry); + flow_entry->entry_id = entry_id; + flow_entry->host_addr_type = entry.bf0.host_addr_index_type; + flow_entry->host_addr_index = entry.bf0.host_addr_index; + flow_entry->protocol = entry.bf0.protocol_type; + flow_entry->age = entry.bf0.age; + flow_entry->src_intf_valid = entry.bf0.src_l3_if_valid; + flow_entry->src_intf_index = entry.bf0.src_l3_if; + flow_entry->fwd_type = entry.bf0.fwd_type; + if (flow_entry->fwd_type == FAL_FLOW_SNAT) { + flow_entry->snat_nexthop = entry.bf0.next_hop1; + } else if (flow_entry->fwd_type == FAL_FLOW_DNAT) { + flow_entry->dnat_nexthop = entry.bf3.next_hop2; + } else if (flow_entry->fwd_type == FAL_FLOW_ROUTE) { + flow_entry->route_nexthop = entry.bf2.next_hop3; + flow_entry->port_valid = entry.bf2.port_vp_valid1; + flow_entry->route_port = entry.bf2.port_vp1; + } else if (flow_entry->fwd_type == FAL_FLOW_BRIDGE) { + flow_entry->bridge_port = entry.bf1.port_vp2; + } + flow_entry->deacclr_en = entry.bf0.de_acce; + flow_entry->copy_tocpu_en = entry.bf0.copy_to_cpu_en; + flow_entry->syn_toggle = entry.bf0.syn_toggle; + flow_entry->pri_profile = entry.bf0.pri_profile_0 |\ + entry.bf0.pri_profile_1 << 1; + flow_entry->sevice_code = entry.bf0.service_code; + flow_entry->flow_ip.ipv6.ul[3] = entry.bf0.ip_addr_0 |\ + entry.bf0.ip_addr_1 << 20; + flow_entry->flow_ip.ipv6.ul[2] = entry.bf0.ip_addr_1 >> 12 |\ + entry.bf0.ip_addr_2 << 20; + flow_entry->flow_ip.ipv6.ul[1] = entry.bf0.ip_addr_2 >> 12 |\ + entry.bf0.ip_addr_3 << 20; + flow_entry->flow_ip.ipv6.ul[0] = entry.bf0.ip_addr_3 >> 12 |\ + entry.bf0.ip_addr_4 << 20; + flow_entry->src_port = entry.bf0.l4_sport; + flow_entry->dst_port = entry.bf0.l4_dport_0 |\ + entry.bf0.l4_dport_1 << 4; + } else if ((type & FAL_FLOW_IP4_3TUPLE_ADDR) == FAL_FLOW_IP4_3TUPLE_ADDR) { + union in_flow_3tuple_tbl_u entry; + entry.bf0.valid= 1; + entry.bf0.entry_type = FLOW_ENTRY_TYPE_IPV4; + entry.bf0.host_addr_index_type = flow_entry->host_addr_type; + entry.bf0.host_addr_index = flow_entry->host_addr_index; + entry.bf0.protocol_type = flow_entry->protocol; + entry.bf0.ip_addr_0 = flow_entry->flow_ip.ipv4; + entry.bf0.ip_addr_1 = flow_entry->flow_ip.ipv4 >> 20; + entry.bf0.ip_protocol = flow_entry->ip_type; + rv = hppe_flow_entry_host_op_ipv4_3tuple_get(dev_id, get_mode, &entry_id, &entry); + flow_entry->entry_id = entry_id; + flow_entry->host_addr_type = entry.bf0.host_addr_index_type; + flow_entry->host_addr_index = entry.bf0.host_addr_index; + flow_entry->protocol = entry.bf0.protocol_type; + flow_entry->age = entry.bf0.age; + flow_entry->src_intf_valid = entry.bf0.src_l3_if_valid; + flow_entry->src_intf_index = entry.bf0.src_l3_if; + flow_entry->fwd_type = entry.bf0.fwd_type; + if (flow_entry->fwd_type == FAL_FLOW_SNAT) { + flow_entry->snat_nexthop = entry.bf0.next_hop1; + } else if (flow_entry->fwd_type == FAL_FLOW_DNAT) { + flow_entry->dnat_nexthop = entry.bf3.next_hop2; + } else if (flow_entry->fwd_type == FAL_FLOW_ROUTE) { + flow_entry->route_nexthop = entry.bf2.next_hop3; + flow_entry->port_valid = entry.bf2.port_vp_valid1; + flow_entry->route_port = entry.bf2.port_vp1; + } else if (flow_entry->fwd_type == FAL_FLOW_BRIDGE) { + flow_entry->bridge_port = entry.bf1.port_vp2; + } + flow_entry->deacclr_en = entry.bf0.de_acce; + flow_entry->copy_tocpu_en = entry.bf0.copy_to_cpu_en; + flow_entry->syn_toggle = entry.bf0.syn_toggle; + flow_entry->pri_profile = entry.bf0.pri_profile_0 |\ + entry.bf0.pri_profile_1 << 1; + flow_entry->sevice_code = entry.bf0.service_code; + flow_entry->flow_ip.ipv4 = entry.bf0.ip_addr_0 |\ + entry.bf0.ip_addr_1 << 20; + flow_entry->ip_type = entry.bf0.ip_protocol; + } else if ((type & FAL_FLOW_IP6_3TUPLE_ADDR) == FAL_FLOW_IP6_3TUPLE_ADDR) { + union in_flow_ipv6_3tuple_tbl_u entry; + entry.bf0.valid= 1; + entry.bf0.entry_type = FLOW_ENTRY_TYPE_IPV6; + entry.bf0.host_addr_index_type = flow_entry->host_addr_type; + entry.bf0.host_addr_index = flow_entry->host_addr_index; + entry.bf0.protocol_type = flow_entry->protocol; + entry.bf0.ip_addr_0 = flow_entry->flow_ip.ipv6.ul[3]; + entry.bf0.ip_addr_1 = flow_entry->flow_ip.ipv6.ul[3] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[2] << 12; + entry.bf0.ip_addr_2 = flow_entry->flow_ip.ipv6.ul[2] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[1] << 12; + entry.bf0.ip_addr_3 = flow_entry->flow_ip.ipv6.ul[1] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[0] << 12; + entry.bf0.ip_addr_4 = flow_entry->flow_ip.ipv6.ul[0] >> 20; + entry.bf0.ip_protocol = flow_entry->ip_type; + rv = hppe_flow_entry_host_op_ipv6_3tuple_get(dev_id, get_mode, &entry_id, &entry); + flow_entry->entry_id = entry_id; + flow_entry->host_addr_type = entry.bf0.host_addr_index_type; + flow_entry->host_addr_index = entry.bf0.host_addr_index; + flow_entry->protocol = entry.bf0.protocol_type; + flow_entry->age = entry.bf0.age; + flow_entry->src_intf_valid = entry.bf0.src_l3_if_valid; + flow_entry->src_intf_index = entry.bf0.src_l3_if; + flow_entry->fwd_type = entry.bf0.fwd_type; + if (flow_entry->fwd_type == FAL_FLOW_SNAT) { + flow_entry->snat_nexthop = entry.bf1.next_hop1; + } else if (flow_entry->fwd_type == FAL_FLOW_DNAT) { + flow_entry->dnat_nexthop = entry.bf3.next_hop2; + } else if (flow_entry->fwd_type == FAL_FLOW_ROUTE) { + flow_entry->route_nexthop = entry.bf2.next_hop3; + flow_entry->port_valid = entry.bf2.port_vp_valid1; + flow_entry->route_port = entry.bf2.port_vp1; + } else if (flow_entry->fwd_type == FAL_FLOW_BRIDGE) { + flow_entry->bridge_port = entry.bf0.port_vp2; + } + flow_entry->deacclr_en = entry.bf0.de_acce; + flow_entry->copy_tocpu_en = entry.bf0.copy_to_cpu_en; + flow_entry->syn_toggle = entry.bf0.syn_toggle; + flow_entry->pri_profile = entry.bf0.pri_profile_0 |\ + entry.bf0.pri_profile_1 << 1; + flow_entry->sevice_code = entry.bf0.service_code; + flow_entry->flow_ip.ipv6.ul[3] = entry.bf0.ip_addr_0 |\ + entry.bf0.ip_addr_1 << 20; + flow_entry->flow_ip.ipv6.ul[2] = entry.bf0.ip_addr_1 >> 12 |\ + entry.bf0.ip_addr_2 << 20; + flow_entry->flow_ip.ipv6.ul[1] = entry.bf0.ip_addr_2 >> 12 |\ + entry.bf0.ip_addr_3 << 20; + flow_entry->flow_ip.ipv6.ul[0] = entry.bf0.ip_addr_3 >> 12 |\ + entry.bf0.ip_addr_4 << 20; + flow_entry->ip_type = entry.bf0.ip_protocol; + } else + return SW_FAIL; + + if (rv == SW_OK) { + union eg_flow_tree_map_tbl_u eg_treemap; + union in_flow_cnt_tbl_u cnt; + rv = hppe_eg_flow_tree_map_tbl_get(dev_id, flow_entry->entry_id, &eg_treemap); + flow_entry->tree_id = eg_treemap.bf.tree_id; + rv = hppe_in_flow_cnt_tbl_get(dev_id, flow_entry->entry_id, &cnt); + flow_entry->pkt_counter = cnt.bf.hit_pkt_counter; + flow_entry->byte_counter = cnt.bf.hit_byte_counter_0 | \ + ((a_uint64_t)cnt.bf.hit_byte_counter_1 << 32); + } + return rv; +} + +sw_error_t +adpt_hppe_flow_entry_host_op_del( + a_uint32_t dev_id, + a_uint32_t del_mode, + fal_flow_entry_t *flow_entry) +{ + sw_error_t rv = SW_OK; + a_uint32_t type = 0; + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(flow_entry); + + if (del_mode == FAL_FLOW_OP_MODE_FLUSH) + return hppe_flow_host_flush_common(dev_id); + //return hppe_flow_flush_common(dev_id); + + type = flow_entry->entry_type; + if ((type & FAL_FLOW_IP4_5TUPLE_ADDR) == FAL_FLOW_IP4_5TUPLE_ADDR) { + union in_flow_tbl_u entry; + entry.bf0.entry_type = FLOW_ENTRY_TYPE_IPV4; + entry.bf0.host_addr_index_type = flow_entry->host_addr_type; + entry.bf0.host_addr_index = flow_entry->host_addr_index; + entry.bf0.protocol_type = flow_entry->protocol; + entry.bf0.age = flow_entry->age; + entry.bf0.src_l3_if_valid = flow_entry->src_intf_valid; + entry.bf0.src_l3_if = flow_entry->src_intf_index; + entry.bf0.fwd_type = flow_entry->fwd_type; + if (flow_entry->fwd_type == FAL_FLOW_SNAT) { + entry.bf0.next_hop1 = flow_entry->snat_nexthop; + entry.bf0.l4_port1 = flow_entry->snat_srcport; + } else if (flow_entry->fwd_type == FAL_FLOW_DNAT) { + entry.bf3.next_hop2 = flow_entry->dnat_nexthop; + entry.bf3.l4_port2 = flow_entry->dnat_dstport; + } else if (flow_entry->fwd_type == FAL_FLOW_ROUTE) { + entry.bf2.next_hop3 = flow_entry->route_nexthop; + entry.bf2.port_vp_valid1= flow_entry->port_valid; + entry.bf2.port_vp1 = flow_entry->route_port; + } else if (flow_entry->fwd_type == FAL_FLOW_BRIDGE) { + entry.bf1.port_vp2 = flow_entry->bridge_port; + } + entry.bf0.de_acce = flow_entry->deacclr_en; + entry.bf0.copy_to_cpu_en = flow_entry->copy_tocpu_en; + entry.bf0.syn_toggle = flow_entry->syn_toggle; + entry.bf0.pri_profile_0 = flow_entry->pri_profile; + entry.bf0.pri_profile_1 = flow_entry->pri_profile >> 1; + entry.bf0.service_code = flow_entry->sevice_code; + entry.bf0.ip_addr_0 = flow_entry->flow_ip.ipv4; + entry.bf0.ip_addr_1 = flow_entry->flow_ip.ipv4 >> 20; + entry.bf0.l4_sport = flow_entry->src_port; + entry.bf0.l4_dport_0 = flow_entry->dst_port; + entry.bf0.l4_dport_1 = flow_entry->dst_port >> 4; + rv = hppe_flow_entry_host_op_ipv4_5tuple_del(dev_id, del_mode, &flow_entry->entry_id, &entry); + } else if ((type & FAL_FLOW_IP6_5TUPLE_ADDR) == FAL_FLOW_IP6_5TUPLE_ADDR) { + union in_flow_ipv6_5tuple_tbl_u entry; + entry.bf0.entry_type = FLOW_ENTRY_TYPE_IPV6; + entry.bf0.host_addr_index_type = flow_entry->host_addr_type; + entry.bf0.host_addr_index = flow_entry->host_addr_index; + entry.bf0.protocol_type = flow_entry->protocol; + entry.bf0.age = flow_entry->age; + entry.bf0.src_l3_if_valid = flow_entry->src_intf_valid; + entry.bf0.src_l3_if = flow_entry->src_intf_index; + entry.bf0.fwd_type = flow_entry->fwd_type; + if (flow_entry->fwd_type == FAL_FLOW_SNAT) { + entry.bf0.next_hop1 = flow_entry->snat_nexthop; + } else if (flow_entry->fwd_type == FAL_FLOW_DNAT) { + entry.bf3.next_hop2 = flow_entry->dnat_nexthop; + } else if (flow_entry->fwd_type == FAL_FLOW_ROUTE) { + entry.bf2.next_hop3 = flow_entry->route_nexthop; + entry.bf2.port_vp_valid1= flow_entry->port_valid; + entry.bf2.port_vp1 = flow_entry->route_port; + } else if (flow_entry->fwd_type == FAL_FLOW_BRIDGE) { + entry.bf1.port_vp2 = flow_entry->bridge_port; + } + entry.bf0.de_acce = flow_entry->deacclr_en; + entry.bf0.copy_to_cpu_en = flow_entry->copy_tocpu_en; + entry.bf0.syn_toggle = flow_entry->syn_toggle; + entry.bf0.pri_profile_0 = flow_entry->pri_profile; + entry.bf0.pri_profile_1 = flow_entry->pri_profile >> 1; + entry.bf0.service_code = flow_entry->sevice_code; + entry.bf0.ip_addr_0 = flow_entry->flow_ip.ipv6.ul[3]; + entry.bf0.ip_addr_1 = flow_entry->flow_ip.ipv6.ul[3] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[2] << 12; + entry.bf0.ip_addr_2 = flow_entry->flow_ip.ipv6.ul[2] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[1] << 12; + entry.bf0.ip_addr_3 = flow_entry->flow_ip.ipv6.ul[1] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[0] << 12; + entry.bf0.ip_addr_4 = flow_entry->flow_ip.ipv6.ul[0] >> 20; + entry.bf0.l4_sport = flow_entry->src_port; + entry.bf0.l4_dport_0 = flow_entry->dst_port; + entry.bf0.l4_dport_1 = flow_entry->dst_port >> 4; + rv = hppe_flow_entry_host_op_ipv6_5tuple_del(dev_id, del_mode, &flow_entry->entry_id, &entry); + } else if ((type & FAL_FLOW_IP4_3TUPLE_ADDR) == FAL_FLOW_IP4_3TUPLE_ADDR) { + union in_flow_3tuple_tbl_u entry; + entry.bf0.entry_type = FLOW_ENTRY_TYPE_IPV4; + entry.bf0.host_addr_index_type = flow_entry->host_addr_type; + entry.bf0.host_addr_index = flow_entry->host_addr_index; + entry.bf0.protocol_type = flow_entry->protocol; + entry.bf0.age = flow_entry->age; + entry.bf0.src_l3_if_valid = flow_entry->src_intf_valid; + entry.bf0.src_l3_if = flow_entry->src_intf_index; + entry.bf0.fwd_type = flow_entry->fwd_type; + if (flow_entry->fwd_type == FAL_FLOW_SNAT) { + entry.bf0.next_hop1 = flow_entry->snat_nexthop; + } else if (flow_entry->fwd_type == FAL_FLOW_DNAT) { + entry.bf3.next_hop2 = flow_entry->dnat_nexthop; + } else if (flow_entry->fwd_type == FAL_FLOW_ROUTE) { + entry.bf2.next_hop3 = flow_entry->route_nexthop; + entry.bf2.port_vp_valid1= flow_entry->port_valid; + entry.bf2.port_vp1 = flow_entry->route_port; + } else if (flow_entry->fwd_type == FAL_FLOW_BRIDGE) { + entry.bf1.port_vp2 = flow_entry->bridge_port; + } + entry.bf0.de_acce = flow_entry->deacclr_en; + entry.bf0.copy_to_cpu_en = flow_entry->copy_tocpu_en; + entry.bf0.syn_toggle = flow_entry->syn_toggle; + entry.bf0.pri_profile_0 = flow_entry->pri_profile; + entry.bf0.pri_profile_1 = flow_entry->pri_profile >> 1; + entry.bf0.service_code = flow_entry->sevice_code; + entry.bf0.ip_addr_0 = flow_entry->flow_ip.ipv4; + entry.bf0.ip_addr_1 = flow_entry->flow_ip.ipv4 >> 20; + entry.bf0.ip_protocol = flow_entry->ip_type; + rv = hppe_flow_entry_host_op_ipv4_3tuple_del(dev_id, del_mode, &flow_entry->entry_id, &entry); + } else if ((type & FAL_FLOW_IP6_3TUPLE_ADDR) == FAL_FLOW_IP6_3TUPLE_ADDR) { + union in_flow_ipv6_3tuple_tbl_u entry; + entry.bf0.entry_type = FLOW_ENTRY_TYPE_IPV6; + entry.bf0.host_addr_index_type = flow_entry->host_addr_type; + entry.bf0.host_addr_index = flow_entry->host_addr_index; + entry.bf0.protocol_type = flow_entry->protocol; + entry.bf0.age = flow_entry->age; + entry.bf0.src_l3_if_valid = flow_entry->src_intf_valid; + entry.bf0.src_l3_if = flow_entry->src_intf_index; + entry.bf0.fwd_type = flow_entry->fwd_type; + if (flow_entry->fwd_type == FAL_FLOW_SNAT) { + entry.bf1.next_hop1 = flow_entry->snat_nexthop; + } else if (flow_entry->fwd_type == FAL_FLOW_DNAT) { + entry.bf3.next_hop2 = flow_entry->dnat_nexthop; + } else if (flow_entry->fwd_type == FAL_FLOW_ROUTE) { + entry.bf2.next_hop3 = flow_entry->route_nexthop; + entry.bf2.port_vp_valid1= flow_entry->port_valid; + entry.bf2.port_vp1 = flow_entry->route_port; + } else if (flow_entry->fwd_type == FAL_FLOW_BRIDGE) { + entry.bf0.port_vp2 = flow_entry->bridge_port; + } + entry.bf0.de_acce = flow_entry->deacclr_en; + entry.bf0.copy_to_cpu_en = flow_entry->copy_tocpu_en; + entry.bf0.syn_toggle = flow_entry->syn_toggle; + entry.bf0.pri_profile_0 = flow_entry->pri_profile; + entry.bf0.pri_profile_1 = flow_entry->pri_profile >> 1; + entry.bf0.service_code = flow_entry->sevice_code; + entry.bf0.ip_addr_0 = flow_entry->flow_ip.ipv6.ul[3]; + entry.bf0.ip_addr_1 = flow_entry->flow_ip.ipv6.ul[3] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[2] << 12; + entry.bf0.ip_addr_2 = flow_entry->flow_ip.ipv6.ul[2] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[1] << 12; + entry.bf0.ip_addr_3 = flow_entry->flow_ip.ipv6.ul[1] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[0] << 12; + entry.bf0.ip_addr_4 = flow_entry->flow_ip.ipv6.ul[0] >> 20; + entry.bf0.ip_protocol = flow_entry->ip_type; + rv = hppe_flow_entry_host_op_ipv6_3tuple_del(dev_id, del_mode, &flow_entry->entry_id, &entry); + } else + return SW_FAIL; + return rv; +} + +sw_error_t +adpt_hppe_flow_host_add( + a_uint32_t dev_id, + a_uint32_t add_mode, + fal_flow_host_entry_t *flow_host) +{ + sw_error_t rv = SW_OK; + fal_flow_entry_t *flow_entry = &(flow_host->flow_entry); + fal_host_entry_t *host_entry = &(flow_host->host_entry); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(flow_host); + + rv = adpt_hppe_ip_flow_host_data_add(dev_id, host_entry); + SW_RTN_ON_ERROR(rv); + rv = adpt_hppe_flow_entry_host_op_add(dev_id, add_mode, flow_entry); + SW_RTN_ON_ERROR(rv); + + rv = hppe_flow_host_tbl_op_rslt_host_entry_index_get(dev_id, &host_entry->entry_id); + return rv; +} + +sw_error_t +adpt_hppe_flow_host_get( + a_uint32_t dev_id, + a_uint32_t get_mode, + fal_flow_host_entry_t *flow_host) +{ + sw_error_t rv = SW_OK; + fal_flow_entry_t *flow_entry = &(flow_host->flow_entry); + fal_host_entry_t *host_entry = &(flow_host->host_entry); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(flow_host); + + rv = adpt_hppe_ip_flow_host_data_rd_add(dev_id, host_entry); + rv = adpt_hppe_flow_entry_host_op_get(dev_id, get_mode, flow_entry); + if(rv != SW_OK) + return rv; + + rv = hppe_flow_host_tbl_rd_op_rslt_host_entry_index_get(dev_id, &host_entry->entry_id); + if(rv != SW_OK) + return rv; + + rv = adpt_hppe_ip_flow_host_data_get(dev_id, get_mode, host_entry); + + return rv; +} + +sw_error_t +adpt_hppe_flow_host_del( + a_uint32_t dev_id, + a_uint32_t del_mode, + fal_flow_host_entry_t *flow_host) +{ + fal_flow_entry_t *flow_entry = &(flow_host->flow_entry); + fal_host_entry_t *host_entry = &(flow_host->host_entry); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(flow_host); + + adpt_hppe_ip_flow_host_data_del(dev_id, del_mode, host_entry); + adpt_hppe_flow_entry_host_op_del(dev_id, del_mode, flow_entry); + return SW_OK; +} + + +sw_error_t +adpt_hppe_flow_entry_get( + a_uint32_t dev_id, + a_uint32_t get_mode, + fal_flow_entry_t *flow_entry) +{ + sw_error_t rv = SW_OK; + a_uint32_t type = 0; + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(flow_entry); + + + type = flow_entry->entry_type; + if ((type & FAL_FLOW_IP4_5TUPLE_ADDR) == FAL_FLOW_IP4_5TUPLE_ADDR) { + union in_flow_tbl_u entry; + entry.bf0.entry_type = FLOW_ENTRY_TYPE_IPV4; + entry.bf0.host_addr_index_type = flow_entry->host_addr_type; + entry.bf0.host_addr_index = flow_entry->host_addr_index; + entry.bf0.protocol_type = flow_entry->protocol; + entry.bf0.ip_addr_0 = flow_entry->flow_ip.ipv4; + entry.bf0.ip_addr_1 = flow_entry->flow_ip.ipv4 >> 20; + entry.bf0.l4_sport = flow_entry->src_port; + entry.bf0.l4_dport_0 = flow_entry->dst_port; + entry.bf0.l4_dport_1 = flow_entry->dst_port >> 4; + rv = hppe_flow_ipv4_5tuple_get(dev_id, get_mode, &flow_entry->entry_id, &entry); + if (entry.bf0.entry_type != FLOW_ENTRY_TYPE_IPV4 || + entry.bf0.protocol_type == FLOW_TUPLE_TYPE_3) { + return SW_BAD_VALUE; + } + flow_entry->host_addr_type = entry.bf0.host_addr_index_type; + flow_entry->host_addr_index = entry.bf0.host_addr_index; + flow_entry->protocol = entry.bf0.protocol_type; + flow_entry->age = entry.bf0.age; + flow_entry->src_intf_valid = entry.bf0.src_l3_if_valid; + flow_entry->src_intf_index = entry.bf0.src_l3_if; + flow_entry->fwd_type = entry.bf0.fwd_type; + if (flow_entry->fwd_type == FAL_FLOW_SNAT) { + flow_entry->snat_nexthop = entry.bf0.next_hop1; + flow_entry->snat_srcport = entry.bf0.l4_port1; + } else if (flow_entry->fwd_type == FAL_FLOW_DNAT) { + flow_entry->dnat_nexthop = entry.bf3.next_hop2; + flow_entry->dnat_dstport = entry.bf3.l4_port2; + } else if (flow_entry->fwd_type == FAL_FLOW_ROUTE) { + flow_entry->route_nexthop = entry.bf2.next_hop3; + flow_entry->port_valid = entry.bf2.port_vp_valid1; + flow_entry->route_port = entry.bf2.port_vp1; + if (entry.bf2.port_vp1 >= 64) + flow_entry->route_port |= 0x1000000; + } else if (flow_entry->fwd_type == FAL_FLOW_BRIDGE) { + flow_entry->bridge_port = entry.bf1.port_vp2; + if (entry.bf1.port_vp2 >= 64) + flow_entry->bridge_port |= 0x1000000; + } + flow_entry->deacclr_en = entry.bf0.de_acce; + flow_entry->copy_tocpu_en = entry.bf0.copy_to_cpu_en; + flow_entry->syn_toggle = entry.bf0.syn_toggle; + flow_entry->pri_profile = entry.bf0.pri_profile_0 |\ + entry.bf0.pri_profile_1 << 1; + flow_entry->sevice_code = entry.bf0.service_code; + flow_entry->flow_ip.ipv4 = entry.bf0.ip_addr_0 |\ + entry.bf0.ip_addr_1 << 20; + flow_entry->src_port = entry.bf0.l4_sport; + flow_entry->dst_port = entry.bf0.l4_dport_0 |\ + entry.bf0.l4_dport_1 << 4; + + } else if ((type & FAL_FLOW_IP6_5TUPLE_ADDR) == FAL_FLOW_IP6_5TUPLE_ADDR) { + union in_flow_ipv6_5tuple_tbl_u entry; + entry.bf0.entry_type = FLOW_ENTRY_TYPE_IPV6; + entry.bf0.host_addr_index_type = flow_entry->host_addr_type; + entry.bf0.host_addr_index = flow_entry->host_addr_index; + entry.bf0.protocol_type = flow_entry->protocol; + entry.bf0.ip_addr_0 = flow_entry->flow_ip.ipv6.ul[3]; + entry.bf0.ip_addr_1 = flow_entry->flow_ip.ipv6.ul[3] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[2] << 12; + entry.bf0.ip_addr_2 = flow_entry->flow_ip.ipv6.ul[2] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[1] << 12; + entry.bf0.ip_addr_3 = flow_entry->flow_ip.ipv6.ul[1] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[0] << 12; + entry.bf0.ip_addr_4 = flow_entry->flow_ip.ipv6.ul[0] >> 20; + entry.bf0.l4_sport = flow_entry->src_port; + entry.bf0.l4_dport_0 = flow_entry->dst_port; + entry.bf0.l4_dport_1 = flow_entry->dst_port >> 4; + rv = hppe_flow_ipv6_5tuple_get(dev_id, get_mode, &flow_entry->entry_id, &entry); + if (entry.bf0.entry_type != FLOW_ENTRY_TYPE_IPV6 || + entry.bf0.protocol_type == FLOW_TUPLE_TYPE_3) { + return SW_BAD_VALUE; + } + flow_entry->host_addr_type = entry.bf0.host_addr_index_type; + flow_entry->host_addr_index = entry.bf0.host_addr_index; + flow_entry->protocol = entry.bf0.protocol_type; + flow_entry->age = entry.bf0.age; + flow_entry->src_intf_valid = entry.bf0.src_l3_if_valid; + flow_entry->src_intf_index = entry.bf0.src_l3_if; + flow_entry->fwd_type = entry.bf0.fwd_type; + if (flow_entry->fwd_type == FAL_FLOW_SNAT) { + flow_entry->snat_nexthop = entry.bf0.next_hop1; + } else if (flow_entry->fwd_type == FAL_FLOW_DNAT) { + flow_entry->dnat_nexthop = entry.bf3.next_hop2; + } else if (flow_entry->fwd_type == FAL_FLOW_ROUTE) { + flow_entry->route_nexthop = entry.bf2.next_hop3; + flow_entry->port_valid = entry.bf2.port_vp_valid1; + flow_entry->route_port = entry.bf2.port_vp1; + if (entry.bf2.port_vp1 >= 64) + flow_entry->route_port |= 0x1000000; + } else if (flow_entry->fwd_type == FAL_FLOW_BRIDGE) { + flow_entry->bridge_port = entry.bf1.port_vp2; + if (entry.bf1.port_vp2 >= 64) + flow_entry->bridge_port |= 0x1000000; + } + flow_entry->deacclr_en = entry.bf0.de_acce; + flow_entry->copy_tocpu_en = entry.bf0.copy_to_cpu_en; + flow_entry->syn_toggle = entry.bf0.syn_toggle; + flow_entry->pri_profile = entry.bf0.pri_profile_0 |\ + entry.bf0.pri_profile_1 << 1; + flow_entry->sevice_code = entry.bf0.service_code; + flow_entry->flow_ip.ipv6.ul[3] = entry.bf0.ip_addr_0 |\ + entry.bf0.ip_addr_1 << 20; + flow_entry->flow_ip.ipv6.ul[2] = entry.bf0.ip_addr_1 >> 12 |\ + entry.bf0.ip_addr_2 << 20; + flow_entry->flow_ip.ipv6.ul[1] = entry.bf0.ip_addr_2 >> 12 |\ + entry.bf0.ip_addr_3 << 20; + flow_entry->flow_ip.ipv6.ul[0] = entry.bf0.ip_addr_3 >> 12 |\ + entry.bf0.ip_addr_4 << 20; + flow_entry->src_port = entry.bf0.l4_sport; + flow_entry->dst_port = entry.bf0.l4_dport_0 |\ + entry.bf0.l4_dport_1 << 4; + + } else if ((type & FAL_FLOW_IP4_3TUPLE_ADDR) == FAL_FLOW_IP4_3TUPLE_ADDR) { + union in_flow_3tuple_tbl_u entry; + entry.bf0.entry_type = FLOW_ENTRY_TYPE_IPV4; + entry.bf0.host_addr_index_type = flow_entry->host_addr_type; + entry.bf0.host_addr_index = flow_entry->host_addr_index; + entry.bf0.protocol_type = flow_entry->protocol; + entry.bf0.ip_addr_0 = flow_entry->flow_ip.ipv4; + entry.bf0.ip_addr_1 = flow_entry->flow_ip.ipv4 >> 20; + entry.bf0.ip_protocol = flow_entry->ip_type; + rv = hppe_flow_ipv4_3tuple_get(dev_id, get_mode, &flow_entry->entry_id, &entry); + if (entry.bf0.entry_type != FLOW_ENTRY_TYPE_IPV4 || + entry.bf0.protocol_type != FLOW_TUPLE_TYPE_3) { + return SW_BAD_VALUE; + } + flow_entry->host_addr_type = entry.bf0.host_addr_index_type; + flow_entry->host_addr_index = entry.bf0.host_addr_index; + flow_entry->protocol = entry.bf0.protocol_type; + flow_entry->age = entry.bf0.age; + flow_entry->src_intf_valid = entry.bf0.src_l3_if_valid; + flow_entry->src_intf_index = entry.bf0.src_l3_if; + flow_entry->fwd_type = entry.bf0.fwd_type; + if (flow_entry->fwd_type == FAL_FLOW_SNAT) { + flow_entry->snat_nexthop = entry.bf0.next_hop1; + } else if (flow_entry->fwd_type == FAL_FLOW_DNAT) { + flow_entry->dnat_nexthop = entry.bf3.next_hop2; + } else if (flow_entry->fwd_type == FAL_FLOW_ROUTE) { + flow_entry->route_nexthop = entry.bf2.next_hop3; + flow_entry->port_valid = entry.bf2.port_vp_valid1; + flow_entry->route_port = entry.bf2.port_vp1; + if (entry.bf2.port_vp1 >= 64) + flow_entry->route_port |= 0x1000000; + } else if (flow_entry->fwd_type == FAL_FLOW_BRIDGE) { + flow_entry->bridge_port = entry.bf1.port_vp2; + if (entry.bf1.port_vp2 >= 64) + flow_entry->bridge_port |= 0x1000000; + } + flow_entry->deacclr_en = entry.bf0.de_acce; + flow_entry->copy_tocpu_en = entry.bf0.copy_to_cpu_en; + flow_entry->syn_toggle = entry.bf0.syn_toggle; + flow_entry->pri_profile = entry.bf0.pri_profile_0 |\ + entry.bf0.pri_profile_1 << 1; + flow_entry->sevice_code = entry.bf0.service_code; + flow_entry->flow_ip.ipv4 = entry.bf0.ip_addr_0 |\ + entry.bf0.ip_addr_1 << 20; + flow_entry->ip_type = entry.bf0.ip_protocol; + } else if ((type & FAL_FLOW_IP6_3TUPLE_ADDR) == FAL_FLOW_IP6_3TUPLE_ADDR) { + union in_flow_ipv6_3tuple_tbl_u entry; + entry.bf0.entry_type = FLOW_ENTRY_TYPE_IPV6; + entry.bf0.host_addr_index_type = flow_entry->host_addr_type; + entry.bf0.host_addr_index = flow_entry->host_addr_index; + entry.bf0.protocol_type = flow_entry->protocol; + entry.bf0.ip_addr_0 = flow_entry->flow_ip.ipv6.ul[3]; + entry.bf0.ip_addr_1 = flow_entry->flow_ip.ipv6.ul[3] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[2] << 12; + entry.bf0.ip_addr_2 = flow_entry->flow_ip.ipv6.ul[2] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[1] << 12; + entry.bf0.ip_addr_3 = flow_entry->flow_ip.ipv6.ul[1] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[0] << 12; + entry.bf0.ip_addr_4 = flow_entry->flow_ip.ipv6.ul[0] >> 20; + entry.bf0.ip_protocol = flow_entry->ip_type; + rv = hppe_flow_ipv6_3tuple_get(dev_id, get_mode, &flow_entry->entry_id, &entry); + if (entry.bf0.entry_type != FLOW_ENTRY_TYPE_IPV6 || + entry.bf0.protocol_type != FLOW_TUPLE_TYPE_3) { + return SW_BAD_VALUE; + } + flow_entry->host_addr_type = entry.bf0.host_addr_index_type; + flow_entry->host_addr_index = entry.bf0.host_addr_index; + flow_entry->protocol = entry.bf0.protocol_type; + flow_entry->age = entry.bf0.age; + flow_entry->src_intf_valid = entry.bf0.src_l3_if_valid; + flow_entry->src_intf_index = entry.bf0.src_l3_if; + flow_entry->fwd_type = entry.bf0.fwd_type; + if (flow_entry->fwd_type == FAL_FLOW_SNAT) { + flow_entry->snat_nexthop = entry.bf1.next_hop1; + } else if (flow_entry->fwd_type == FAL_FLOW_DNAT) { + flow_entry->dnat_nexthop = entry.bf3.next_hop2; + } else if (flow_entry->fwd_type == FAL_FLOW_ROUTE) { + flow_entry->route_nexthop = entry.bf2.next_hop3; + flow_entry->port_valid = entry.bf2.port_vp_valid1; + flow_entry->route_port = entry.bf2.port_vp1; + if (entry.bf2.port_vp1 >= 64) + flow_entry->route_port |= 0x1000000; + } else if (flow_entry->fwd_type == FAL_FLOW_BRIDGE) { + flow_entry->bridge_port = entry.bf0.port_vp2; + if (entry.bf0.port_vp2 >= 64) + flow_entry->bridge_port |= 0x1000000; + } + flow_entry->deacclr_en = entry.bf0.de_acce; + flow_entry->copy_tocpu_en = entry.bf0.copy_to_cpu_en; + flow_entry->syn_toggle = entry.bf0.syn_toggle; + flow_entry->pri_profile = entry.bf0.pri_profile_0 |\ + entry.bf0.pri_profile_1 << 1; + flow_entry->sevice_code = entry.bf0.service_code; + flow_entry->flow_ip.ipv6.ul[3] = entry.bf0.ip_addr_0 |\ + entry.bf0.ip_addr_1 << 20; + flow_entry->flow_ip.ipv6.ul[2] = entry.bf0.ip_addr_1 >> 12 |\ + entry.bf0.ip_addr_2 << 20; + flow_entry->flow_ip.ipv6.ul[1] = entry.bf0.ip_addr_2 >> 12 |\ + entry.bf0.ip_addr_3 << 20; + flow_entry->flow_ip.ipv6.ul[0] = entry.bf0.ip_addr_3 >> 12 |\ + entry.bf0.ip_addr_4 << 20; + flow_entry->ip_type = entry.bf0.ip_protocol; + } else + return SW_FAIL; + + if (rv == SW_OK) { + union eg_flow_tree_map_tbl_u eg_treemap; + union in_flow_cnt_tbl_u cnt; + rv = hppe_eg_flow_tree_map_tbl_get(dev_id, flow_entry->entry_id, &eg_treemap); + flow_entry->tree_id = eg_treemap.bf.tree_id; + rv = hppe_in_flow_cnt_tbl_get(dev_id, flow_entry->entry_id, &cnt); + flow_entry->pkt_counter = cnt.bf.hit_pkt_counter; + flow_entry->byte_counter = cnt.bf.hit_byte_counter_0 | \ + ((a_uint64_t)cnt.bf.hit_byte_counter_1 << 32); + } + return rv; +} + +sw_error_t +adpt_hppe_flow_entry_next( + a_uint32_t dev_id, + a_uint32_t next_mode, + fal_flow_entry_t *flow_entry) +{ + a_uint32_t i = 0, step = 0; + sw_error_t rv = SW_OK; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(flow_entry); + + if (FAL_NEXT_ENTRY_FIRST_ID == flow_entry->entry_id) + i = 0; + + if (next_mode == FAL_FLOW_IP4_3TUPLE_ADDR || + next_mode == FAL_FLOW_IP4_5TUPLE_ADDR) { + if (FAL_NEXT_ENTRY_FIRST_ID != flow_entry->entry_id) + i = flow_entry->entry_id + 1; + step = 1; + } else if (next_mode == FAL_FLOW_IP6_5TUPLE_ADDR || + next_mode == FAL_FLOW_IP6_3TUPLE_ADDR) { + if (FAL_NEXT_ENTRY_FIRST_ID != flow_entry->entry_id) + i = (flow_entry->entry_id & ~1) + 2; + step = 2; + } + for (; i < IN_FLOW_TBL_MAX_ENTRY;) { + flow_entry->entry_type = next_mode; + flow_entry->entry_id = i; + rv = adpt_hppe_flow_entry_get(dev_id, 1, flow_entry); + if (!rv) { + return rv; + } + i += step; + } + + return SW_FAIL; + +} + +sw_error_t +adpt_hppe_flow_entry_del( + a_uint32_t dev_id, + a_uint32_t del_mode, + fal_flow_entry_t *flow_entry) +{ + sw_error_t rv = SW_OK; + a_uint32_t type = 0; + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(flow_entry); + + if (del_mode == FAL_FLOW_OP_MODE_FLUSH) + return hppe_flow_flush_common(dev_id); + + type = flow_entry->entry_type; + if ((type & FAL_FLOW_IP4_5TUPLE_ADDR) == FAL_FLOW_IP4_5TUPLE_ADDR) { + union in_flow_tbl_u entry; + entry.bf0.entry_type = FLOW_ENTRY_TYPE_IPV4; + entry.bf0.host_addr_index_type = flow_entry->host_addr_type; + entry.bf0.host_addr_index = flow_entry->host_addr_index; + entry.bf0.protocol_type = flow_entry->protocol; + entry.bf0.age = flow_entry->age; + entry.bf0.src_l3_if_valid = flow_entry->src_intf_valid; + entry.bf0.src_l3_if = flow_entry->src_intf_index; + entry.bf0.fwd_type = flow_entry->fwd_type; + if (flow_entry->fwd_type == FAL_FLOW_SNAT) { + entry.bf0.next_hop1 = flow_entry->snat_nexthop; + entry.bf0.l4_port1 = flow_entry->snat_srcport; + } else if (flow_entry->fwd_type == FAL_FLOW_DNAT) { + entry.bf3.next_hop2 = flow_entry->dnat_nexthop; + entry.bf3.l4_port2 = flow_entry->dnat_dstport; + } else if (flow_entry->fwd_type == FAL_FLOW_ROUTE) { + entry.bf2.next_hop3 = flow_entry->route_nexthop; + entry.bf2.port_vp_valid1= flow_entry->port_valid; + entry.bf2.port_vp1 = flow_entry->route_port & 0xffffff; + } else if (flow_entry->fwd_type == FAL_FLOW_BRIDGE) { + entry.bf1.port_vp2 = flow_entry->bridge_port & 0xffffff; + } + entry.bf0.de_acce = flow_entry->deacclr_en; + entry.bf0.copy_to_cpu_en = flow_entry->copy_tocpu_en; + entry.bf0.syn_toggle = flow_entry->syn_toggle; + entry.bf0.pri_profile_0 = flow_entry->pri_profile; + entry.bf0.pri_profile_1 = flow_entry->pri_profile >> 1; + entry.bf0.service_code = flow_entry->sevice_code; + entry.bf0.ip_addr_0 = flow_entry->flow_ip.ipv4; + entry.bf0.ip_addr_1 = flow_entry->flow_ip.ipv4 >> 20; + entry.bf0.l4_sport = flow_entry->src_port; + entry.bf0.l4_dport_0 = flow_entry->dst_port; + entry.bf0.l4_dport_1 = flow_entry->dst_port >> 4; + rv = hppe_flow_ipv4_5tuple_del(dev_id, del_mode, &flow_entry->entry_id, &entry); + } else if ((type & FAL_FLOW_IP6_5TUPLE_ADDR) == FAL_FLOW_IP6_5TUPLE_ADDR) { + union in_flow_ipv6_5tuple_tbl_u entry; + entry.bf0.entry_type = FLOW_ENTRY_TYPE_IPV6; + entry.bf0.host_addr_index_type = flow_entry->host_addr_type; + entry.bf0.host_addr_index = flow_entry->host_addr_index; + entry.bf0.protocol_type = flow_entry->protocol; + entry.bf0.age = flow_entry->age; + entry.bf0.src_l3_if_valid = flow_entry->src_intf_valid; + entry.bf0.src_l3_if = flow_entry->src_intf_index; + entry.bf0.fwd_type = flow_entry->fwd_type; + if (flow_entry->fwd_type == FAL_FLOW_SNAT) { + entry.bf0.next_hop1 = flow_entry->snat_nexthop; + } else if (flow_entry->fwd_type == FAL_FLOW_DNAT) { + entry.bf3.next_hop2 = flow_entry->dnat_nexthop; + } else if (flow_entry->fwd_type == FAL_FLOW_ROUTE) { + entry.bf2.next_hop3 = flow_entry->route_nexthop; + entry.bf2.port_vp_valid1= flow_entry->port_valid; + entry.bf2.port_vp1 = flow_entry->route_port & 0xffffff; + } else if (flow_entry->fwd_type == FAL_FLOW_BRIDGE) { + entry.bf1.port_vp2 = flow_entry->bridge_port & 0xffffff; + } + entry.bf0.de_acce = flow_entry->deacclr_en; + entry.bf0.copy_to_cpu_en = flow_entry->copy_tocpu_en; + entry.bf0.syn_toggle = flow_entry->syn_toggle; + entry.bf0.pri_profile_0 = flow_entry->pri_profile; + entry.bf0.pri_profile_1 = flow_entry->pri_profile >> 1; + entry.bf0.service_code = flow_entry->sevice_code; + entry.bf0.ip_addr_0 = flow_entry->flow_ip.ipv6.ul[3]; + entry.bf0.ip_addr_1 = flow_entry->flow_ip.ipv6.ul[3] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[2] << 12; + entry.bf0.ip_addr_2 = flow_entry->flow_ip.ipv6.ul[2] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[1] << 12; + entry.bf0.ip_addr_3 = flow_entry->flow_ip.ipv6.ul[1] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[0] << 12; + entry.bf0.ip_addr_4 = flow_entry->flow_ip.ipv6.ul[0] >> 20; + entry.bf0.l4_sport = flow_entry->src_port; + entry.bf0.l4_dport_0 = flow_entry->dst_port; + entry.bf0.l4_dport_1 = flow_entry->dst_port >> 4; + rv = hppe_flow_ipv6_5tuple_del(dev_id, del_mode, &flow_entry->entry_id, &entry); + } else if ((type & FAL_FLOW_IP4_3TUPLE_ADDR) == FAL_FLOW_IP4_3TUPLE_ADDR) { + union in_flow_3tuple_tbl_u entry; + entry.bf0.entry_type = FLOW_ENTRY_TYPE_IPV4; + entry.bf0.host_addr_index_type = flow_entry->host_addr_type; + entry.bf0.host_addr_index = flow_entry->host_addr_index; + entry.bf0.protocol_type = flow_entry->protocol; + entry.bf0.age = flow_entry->age; + entry.bf0.src_l3_if_valid = flow_entry->src_intf_valid; + entry.bf0.src_l3_if = flow_entry->src_intf_index; + entry.bf0.fwd_type = flow_entry->fwd_type; + if (flow_entry->fwd_type == FAL_FLOW_SNAT) { + entry.bf0.next_hop1 = flow_entry->snat_nexthop; + } else if (flow_entry->fwd_type == FAL_FLOW_DNAT) { + entry.bf3.next_hop2 = flow_entry->dnat_nexthop; + } else if (flow_entry->fwd_type == FAL_FLOW_ROUTE) { + entry.bf2.next_hop3 = flow_entry->route_nexthop; + entry.bf2.port_vp_valid1= flow_entry->port_valid; + entry.bf2.port_vp1 = flow_entry->route_port & 0xffffff; + } else if (flow_entry->fwd_type == FAL_FLOW_BRIDGE) { + entry.bf1.port_vp2 = flow_entry->bridge_port & 0xffffff; + } + entry.bf0.de_acce = flow_entry->deacclr_en; + entry.bf0.copy_to_cpu_en = flow_entry->copy_tocpu_en; + entry.bf0.syn_toggle = flow_entry->syn_toggle; + entry.bf0.pri_profile_0 = flow_entry->pri_profile; + entry.bf0.pri_profile_1 = flow_entry->pri_profile >> 1; + entry.bf0.service_code = flow_entry->sevice_code; + entry.bf0.ip_addr_0 = flow_entry->flow_ip.ipv4; + entry.bf0.ip_addr_1 = flow_entry->flow_ip.ipv4 >> 20; + entry.bf0.ip_protocol = flow_entry->ip_type; + rv = hppe_flow_ipv4_3tuple_del(dev_id, del_mode, &flow_entry->entry_id, &entry); + } else if ((type & FAL_FLOW_IP6_3TUPLE_ADDR) == FAL_FLOW_IP6_3TUPLE_ADDR) { + union in_flow_ipv6_3tuple_tbl_u entry; + entry.bf0.entry_type = FLOW_ENTRY_TYPE_IPV6; + entry.bf0.host_addr_index_type = flow_entry->host_addr_type; + entry.bf0.host_addr_index = flow_entry->host_addr_index; + entry.bf0.protocol_type = flow_entry->protocol; + entry.bf0.age = flow_entry->age; + entry.bf0.src_l3_if_valid = flow_entry->src_intf_valid; + entry.bf0.src_l3_if = flow_entry->src_intf_index; + entry.bf0.fwd_type = flow_entry->fwd_type; + if (flow_entry->fwd_type == FAL_FLOW_SNAT) { + entry.bf1.next_hop1 = flow_entry->snat_nexthop; + } else if (flow_entry->fwd_type == FAL_FLOW_DNAT) { + entry.bf3.next_hop2 = flow_entry->dnat_nexthop; + } else if (flow_entry->fwd_type == FAL_FLOW_ROUTE) { + entry.bf2.next_hop3 = flow_entry->route_nexthop; + entry.bf2.port_vp_valid1= flow_entry->port_valid; + entry.bf2.port_vp1 = flow_entry->route_port & 0xffffff; + } else if (flow_entry->fwd_type == FAL_FLOW_BRIDGE) { + entry.bf0.port_vp2 = flow_entry->bridge_port & 0xffffff; + } + entry.bf0.de_acce = flow_entry->deacclr_en; + entry.bf0.copy_to_cpu_en = flow_entry->copy_tocpu_en; + entry.bf0.syn_toggle = flow_entry->syn_toggle; + entry.bf0.pri_profile_0 = flow_entry->pri_profile; + entry.bf0.pri_profile_1 = flow_entry->pri_profile >> 1; + entry.bf0.service_code = flow_entry->sevice_code; + entry.bf0.ip_addr_0 = flow_entry->flow_ip.ipv6.ul[3]; + entry.bf0.ip_addr_1 = flow_entry->flow_ip.ipv6.ul[3] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[2] << 12; + entry.bf0.ip_addr_2 = flow_entry->flow_ip.ipv6.ul[2] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[1] << 12; + entry.bf0.ip_addr_3 = flow_entry->flow_ip.ipv6.ul[1] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[0] << 12; + entry.bf0.ip_addr_4 = flow_entry->flow_ip.ipv6.ul[0] >> 20; + entry.bf0.ip_protocol = flow_entry->ip_type; + rv = hppe_flow_ipv6_3tuple_del(dev_id, del_mode, &flow_entry->entry_id, &entry); + } else + return SW_FAIL; + return rv; +} +sw_error_t +adpt_hppe_flow_status_get(a_uint32_t dev_id, a_bool_t *enable) +{ + sw_error_t rv = SW_OK; + union flow_ctrl0_u flow_ctrl0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + + memset(&flow_ctrl0, 0, sizeof(flow_ctrl0)); + + rv = hppe_flow_ctrl0_get(dev_id, &flow_ctrl0); + if( rv != SW_OK ) + return rv; + + *enable = flow_ctrl0.bf.flow_en; + return SW_OK; +} +#endif + +sw_error_t +adpt_hppe_flow_ctrl_set( + a_uint32_t dev_id, + fal_flow_pkt_type_t type, + fal_flow_direction_t dir, + fal_flow_mgmt_t *ctrl) +{ + sw_error_t rv = SW_OK; + union flow_ctrl1_u flow_ctrl1; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(ctrl); + + memset(&flow_ctrl1, 0, sizeof(flow_ctrl1)); + rv = hppe_flow_ctrl1_get(dev_id, type, &flow_ctrl1); + if( rv != SW_OK ) + return rv; + + if (dir == FAL_FLOW_LAN_TO_LAN_DIR) { + flow_ctrl1.bf.flow_ctl0_miss_action = ctrl->miss_action; + flow_ctrl1.bf.flow_ctl0_frag_bypass = ctrl->frag_bypass_en; + flow_ctrl1.bf.flow_ctl0_tcp_special = ctrl->tcp_spec_bypass_en; + flow_ctrl1.bf.flow_ctl0_bypass = ctrl->all_bypass_en; + flow_ctrl1.bf.flow_ctl0_key_sel = ctrl->key_sel; + } else if (dir == FAL_FLOW_LAN_TO_WAN_DIR) { + flow_ctrl1.bf.flow_ctl1_miss_action = ctrl->miss_action; + flow_ctrl1.bf.flow_ctl1_frag_bypass = ctrl->frag_bypass_en; + flow_ctrl1.bf.flow_ctl1_tcp_special = ctrl->tcp_spec_bypass_en; + flow_ctrl1.bf.flow_ctl1_bypass = ctrl->all_bypass_en; + flow_ctrl1.bf.flow_ctl1_key_sel = ctrl->key_sel; + } else if (dir == FAL_FLOW_WAN_TO_LAN_DIR) { + flow_ctrl1.bf.flow_ctl2_miss_action = ctrl->miss_action; + flow_ctrl1.bf.flow_ctl2_frag_bypass = ctrl->frag_bypass_en; + flow_ctrl1.bf.flow_ctl2_tcp_special = ctrl->tcp_spec_bypass_en; + flow_ctrl1.bf.flow_ctl2_bypass = ctrl->all_bypass_en; + flow_ctrl1.bf.flow_ctl2_key_sel = ctrl->key_sel; + } else if (dir == FAL_FLOW_WAN_TO_WAN_DIR) { + flow_ctrl1.bf.flow_ctl3_miss_action = ctrl->miss_action; + flow_ctrl1.bf.flow_ctl3_frag_bypass = ctrl->frag_bypass_en; + flow_ctrl1.bf.flow_ctl3_tcp_special = ctrl->tcp_spec_bypass_en; + flow_ctrl1.bf.flow_ctl3_bypass = ctrl->all_bypass_en; + flow_ctrl1.bf.flow_ctl3_key_sel = ctrl->key_sel; + } else if (dir == FAL_FLOW_UNKOWN_DIR_DIR) { + flow_ctrl1.bf.flow_ctl4_miss_action = ctrl->miss_action; + flow_ctrl1.bf.flow_ctl4_frag_bypass = ctrl->frag_bypass_en; + flow_ctrl1.bf.flow_ctl4_tcp_special = ctrl->tcp_spec_bypass_en; + flow_ctrl1.bf.flow_ctl4_bypass = ctrl->all_bypass_en; + flow_ctrl1.bf.flow_ctl4_key_sel = ctrl->key_sel; + } else + return SW_FAIL; + + return hppe_flow_ctrl1_set(dev_id, type, &flow_ctrl1);; +} + +#ifndef IN_FLOW_MINI +sw_error_t +adpt_hppe_flow_age_timer_get(a_uint32_t dev_id, fal_flow_age_timer_t *age_timer) +{ + sw_error_t rv = SW_OK; + union flow_ctrl0_u flow_ctrl0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(age_timer); + + memset(&flow_ctrl0, 0, sizeof(flow_ctrl0)); + + rv = hppe_flow_ctrl0_get(dev_id, &flow_ctrl0); + if( rv != SW_OK ) + return rv; + + age_timer->age_time = flow_ctrl0.bf.flow_age_timer; + age_timer->unit = flow_ctrl0.bf.flow_age_timer_unit; + return SW_OK; +} + +sw_error_t +adpt_hppe_flow_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv = SW_OK; + union flow_ctrl0_u flow_ctrl0; + + ADPT_DEV_ID_CHECK(dev_id); + + memset(&flow_ctrl0, 0, sizeof(flow_ctrl0)); + + rv = hppe_flow_ctrl0_get(dev_id, &flow_ctrl0); + if( rv != SW_OK ) + return rv; + + flow_ctrl0.bf.flow_en = enable; + return hppe_flow_ctrl0_set(dev_id, &flow_ctrl0); +} +#endif + +sw_error_t +adpt_hppe_flow_ctrl_get( + a_uint32_t dev_id, + fal_flow_pkt_type_t type, + fal_flow_direction_t dir, + fal_flow_mgmt_t *ctrl) +{ + sw_error_t rv = SW_OK; + union flow_ctrl1_u flow_ctrl1; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(ctrl); + + memset(&flow_ctrl1, 0, sizeof(flow_ctrl1)); + rv = hppe_flow_ctrl1_get(dev_id, type, &flow_ctrl1); + if( rv != SW_OK ) + return rv; + + if (dir == FAL_FLOW_LAN_TO_LAN_DIR) { + ctrl->miss_action = flow_ctrl1.bf.flow_ctl0_miss_action; + ctrl->frag_bypass_en = flow_ctrl1.bf.flow_ctl0_frag_bypass; + ctrl->tcp_spec_bypass_en = flow_ctrl1.bf.flow_ctl0_tcp_special; + ctrl->all_bypass_en = flow_ctrl1.bf.flow_ctl0_bypass; + ctrl->key_sel = flow_ctrl1.bf.flow_ctl0_key_sel; + } else if (dir == FAL_FLOW_LAN_TO_WAN_DIR) { + ctrl->miss_action = flow_ctrl1.bf.flow_ctl1_miss_action; + ctrl->frag_bypass_en = flow_ctrl1.bf.flow_ctl1_frag_bypass; + ctrl->tcp_spec_bypass_en = flow_ctrl1.bf.flow_ctl1_tcp_special; + ctrl->all_bypass_en = flow_ctrl1.bf.flow_ctl1_bypass; + ctrl->key_sel = flow_ctrl1.bf.flow_ctl1_key_sel; + } else if (dir == FAL_FLOW_WAN_TO_LAN_DIR) { + ctrl->miss_action = flow_ctrl1.bf.flow_ctl2_miss_action; + ctrl->frag_bypass_en = flow_ctrl1.bf.flow_ctl2_frag_bypass; + ctrl->tcp_spec_bypass_en = flow_ctrl1.bf.flow_ctl2_tcp_special; + ctrl->all_bypass_en = flow_ctrl1.bf.flow_ctl2_bypass; + ctrl->key_sel = flow_ctrl1.bf.flow_ctl2_key_sel; + } else if (dir == FAL_FLOW_WAN_TO_WAN_DIR) { + ctrl->miss_action = flow_ctrl1.bf.flow_ctl3_miss_action; + ctrl->frag_bypass_en = flow_ctrl1.bf.flow_ctl3_frag_bypass; + ctrl->tcp_spec_bypass_en = flow_ctrl1.bf.flow_ctl3_tcp_special; + ctrl->all_bypass_en = flow_ctrl1.bf.flow_ctl3_bypass; + ctrl->key_sel = flow_ctrl1.bf.flow_ctl3_key_sel; + } else if (dir == FAL_FLOW_UNKOWN_DIR_DIR) { + ctrl->miss_action = flow_ctrl1.bf.flow_ctl4_miss_action; + ctrl->frag_bypass_en = flow_ctrl1.bf.flow_ctl4_frag_bypass; + ctrl->tcp_spec_bypass_en = flow_ctrl1.bf.flow_ctl4_tcp_special; + ctrl->all_bypass_en = flow_ctrl1.bf.flow_ctl4_bypass; + ctrl->key_sel = flow_ctrl1.bf.flow_ctl4_key_sel; + } else + return SW_FAIL; + + return SW_OK; +} + +#ifndef IN_FLOW_MINI +sw_error_t +adpt_hppe_flow_age_timer_set(a_uint32_t dev_id, fal_flow_age_timer_t *age_timer) +{ + sw_error_t rv = SW_OK; + union flow_ctrl0_u flow_ctrl0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(age_timer); + + memset(&flow_ctrl0, 0, sizeof(flow_ctrl0)); + + rv = hppe_flow_ctrl0_get(dev_id, &flow_ctrl0); + if( rv != SW_OK ) + return rv; + + flow_ctrl0.bf.flow_age_timer = age_timer->age_time; + flow_ctrl0.bf.flow_age_timer_unit = age_timer->unit; + return hppe_flow_ctrl0_set(dev_id, &flow_ctrl0); +} + +sw_error_t +adpt_hppe_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 = SW_OK; + a_uint32_t type = 0; + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(flow_entry); + + type = flow_entry->entry_type; + if ((type & FAL_FLOW_IP4_5TUPLE_ADDR) == FAL_FLOW_IP4_5TUPLE_ADDR) { + union in_flow_tbl_u entry; + entry.bf0.valid= 1; + entry.bf0.entry_type = FLOW_ENTRY_TYPE_IPV4; + entry.bf0.host_addr_index_type = flow_entry->host_addr_type; + entry.bf0.host_addr_index = flow_entry->host_addr_index; + entry.bf0.protocol_type = flow_entry->protocol; + entry.bf0.age = flow_entry->age; + entry.bf0.src_l3_if_valid = flow_entry->src_intf_valid; + entry.bf0.src_l3_if = flow_entry->src_intf_index; + entry.bf0.fwd_type = flow_entry->fwd_type; + if (flow_entry->fwd_type == FAL_FLOW_SNAT) { + entry.bf0.next_hop1 = flow_entry->snat_nexthop; + entry.bf0.l4_port1 = flow_entry->snat_srcport; + } else if (flow_entry->fwd_type == FAL_FLOW_DNAT) { + entry.bf3.next_hop2 = flow_entry->dnat_nexthop; + entry.bf3.l4_port2 = flow_entry->dnat_dstport; + } else if (flow_entry->fwd_type == FAL_FLOW_ROUTE) { + entry.bf2.next_hop3 = flow_entry->route_nexthop; + entry.bf2.port_vp_valid1= flow_entry->port_valid; + entry.bf2.port_vp1 = flow_entry->route_port & 0xffffff; + } else if (flow_entry->fwd_type == FAL_FLOW_BRIDGE) { + entry.bf1.port_vp2 = flow_entry->bridge_port & 0xffffff; + } + entry.bf0.de_acce = flow_entry->deacclr_en; + entry.bf0.copy_to_cpu_en = flow_entry->copy_tocpu_en; + entry.bf0.syn_toggle = flow_entry->syn_toggle; + entry.bf0.pri_profile_0 = flow_entry->pri_profile; + entry.bf0.pri_profile_1 = flow_entry->pri_profile >> 1; + entry.bf0.service_code = flow_entry->sevice_code; + entry.bf0.ip_addr_0 = flow_entry->flow_ip.ipv4; + entry.bf0.ip_addr_1 = flow_entry->flow_ip.ipv4 >> 20; + entry.bf0.l4_sport = flow_entry->src_port; + entry.bf0.l4_dport_0 = flow_entry->dst_port; + entry.bf0.l4_dport_1 = flow_entry->dst_port >> 4; + rv = hppe_flow_ipv4_5tuple_add(dev_id, (a_uint32_t)add_mode, &flow_entry->entry_id, &entry); + } else if ((type & FAL_FLOW_IP6_5TUPLE_ADDR) == FAL_FLOW_IP6_5TUPLE_ADDR) { + union in_flow_ipv6_5tuple_tbl_u entry; + entry.bf0.valid= 1; + entry.bf0.entry_type = FLOW_ENTRY_TYPE_IPV6; + entry.bf0.host_addr_index_type = flow_entry->host_addr_type; + entry.bf0.host_addr_index = flow_entry->host_addr_index; + entry.bf0.protocol_type = flow_entry->protocol; + entry.bf0.age = flow_entry->age; + entry.bf0.src_l3_if_valid = flow_entry->src_intf_valid; + entry.bf0.src_l3_if = flow_entry->src_intf_index; + entry.bf0.fwd_type = flow_entry->fwd_type; + if (flow_entry->fwd_type == FAL_FLOW_SNAT) { + entry.bf0.next_hop1 = flow_entry->snat_nexthop; + } else if (flow_entry->fwd_type == FAL_FLOW_DNAT) { + entry.bf3.next_hop2 = flow_entry->dnat_nexthop; + } else if (flow_entry->fwd_type == FAL_FLOW_ROUTE) { + entry.bf2.next_hop3 = flow_entry->route_nexthop; + entry.bf2.port_vp_valid1= flow_entry->port_valid; + entry.bf2.port_vp1 = flow_entry->route_port & 0xffffff; + } else if (flow_entry->fwd_type == FAL_FLOW_BRIDGE) { + entry.bf1.port_vp2 = flow_entry->bridge_port & 0xffffff; + } + entry.bf0.de_acce = flow_entry->deacclr_en; + entry.bf0.copy_to_cpu_en = flow_entry->copy_tocpu_en; + entry.bf0.syn_toggle = flow_entry->syn_toggle; + entry.bf0.pri_profile_0 = flow_entry->pri_profile; + entry.bf0.pri_profile_1 = flow_entry->pri_profile >> 1; + entry.bf0.service_code = flow_entry->sevice_code; + entry.bf0.ip_addr_0 = flow_entry->flow_ip.ipv6.ul[3]; + entry.bf0.ip_addr_1 = flow_entry->flow_ip.ipv6.ul[3] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[2] << 12; + entry.bf0.ip_addr_2 = flow_entry->flow_ip.ipv6.ul[2] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[1] << 12; + entry.bf0.ip_addr_3 = flow_entry->flow_ip.ipv6.ul[1] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[0] << 12; + entry.bf0.ip_addr_4 = flow_entry->flow_ip.ipv6.ul[0] >> 20; + entry.bf0.l4_sport = flow_entry->src_port; + entry.bf0.l4_dport_0 = flow_entry->dst_port; + entry.bf0.l4_dport_1 = flow_entry->dst_port >> 4; + rv = hppe_flow_ipv6_5tuple_add(dev_id, (a_uint32_t)add_mode, &flow_entry->entry_id, &entry); + } else if ((type & FAL_FLOW_IP4_3TUPLE_ADDR) == FAL_FLOW_IP4_3TUPLE_ADDR) { + union in_flow_3tuple_tbl_u entry; + entry.bf0.valid= 1; + entry.bf0.entry_type = FLOW_ENTRY_TYPE_IPV4; + entry.bf0.host_addr_index_type = flow_entry->host_addr_type; + entry.bf0.host_addr_index = flow_entry->host_addr_index; + entry.bf0.protocol_type = flow_entry->protocol; + entry.bf0.age = flow_entry->age; + entry.bf0.src_l3_if_valid = flow_entry->src_intf_valid; + entry.bf0.src_l3_if = flow_entry->src_intf_index; + entry.bf0.fwd_type = flow_entry->fwd_type; + if (flow_entry->fwd_type == FAL_FLOW_SNAT) { + entry.bf0.next_hop1 = flow_entry->snat_nexthop; + } else if (flow_entry->fwd_type == FAL_FLOW_DNAT) { + entry.bf3.next_hop2 = flow_entry->dnat_nexthop; + } else if (flow_entry->fwd_type == FAL_FLOW_ROUTE) { + entry.bf2.next_hop3 = flow_entry->route_nexthop; + entry.bf2.port_vp_valid1= flow_entry->port_valid; + entry.bf2.port_vp1 = flow_entry->route_port & 0xffffff; + } else if (flow_entry->fwd_type == FAL_FLOW_BRIDGE) { + entry.bf1.port_vp2 = flow_entry->bridge_port & 0xffffff; + } + entry.bf0.de_acce = flow_entry->deacclr_en; + entry.bf0.copy_to_cpu_en = flow_entry->copy_tocpu_en; + entry.bf0.syn_toggle = flow_entry->syn_toggle; + entry.bf0.pri_profile_0 = flow_entry->pri_profile; + entry.bf0.pri_profile_1 = flow_entry->pri_profile >> 1; + entry.bf0.service_code = flow_entry->sevice_code; + entry.bf0.ip_addr_0 = flow_entry->flow_ip.ipv4; + entry.bf0.ip_addr_1 = flow_entry->flow_ip.ipv4 >> 20; + entry.bf0.ip_protocol = flow_entry->ip_type; + rv = hppe_flow_ipv4_3tuple_add(dev_id, (a_uint32_t)add_mode, &flow_entry->entry_id, &entry); + } else if ((type & FAL_FLOW_IP6_3TUPLE_ADDR) == FAL_FLOW_IP6_3TUPLE_ADDR) { + union in_flow_ipv6_3tuple_tbl_u entry; + entry.bf0.valid= 1; + entry.bf0.entry_type = FLOW_ENTRY_TYPE_IPV6; + entry.bf0.host_addr_index_type = flow_entry->host_addr_type; + entry.bf0.host_addr_index = flow_entry->host_addr_index; + entry.bf0.protocol_type = flow_entry->protocol; + entry.bf0.age = flow_entry->age; + entry.bf0.src_l3_if_valid = flow_entry->src_intf_valid; + entry.bf0.src_l3_if = flow_entry->src_intf_index; + entry.bf0.fwd_type = flow_entry->fwd_type; + if (flow_entry->fwd_type == FAL_FLOW_SNAT) { + entry.bf1.next_hop1 = flow_entry->snat_nexthop; + } else if (flow_entry->fwd_type == FAL_FLOW_DNAT) { + entry.bf3.next_hop2 = flow_entry->dnat_nexthop; + } else if (flow_entry->fwd_type == FAL_FLOW_ROUTE) { + entry.bf2.next_hop3 = flow_entry->route_nexthop; + entry.bf2.port_vp_valid1= flow_entry->port_valid; + entry.bf2.port_vp1 = flow_entry->route_port & 0xffffff; + } else if (flow_entry->fwd_type == FAL_FLOW_BRIDGE) { + entry.bf0.port_vp2 = flow_entry->bridge_port & 0xffffff; + } + entry.bf0.de_acce = flow_entry->deacclr_en; + entry.bf0.copy_to_cpu_en = flow_entry->copy_tocpu_en; + entry.bf0.syn_toggle = flow_entry->syn_toggle; + entry.bf0.pri_profile_0 = flow_entry->pri_profile; + entry.bf0.pri_profile_1 = flow_entry->pri_profile >> 1; + entry.bf0.service_code = flow_entry->sevice_code; + entry.bf0.ip_addr_0 = flow_entry->flow_ip.ipv6.ul[3]; + entry.bf0.ip_addr_1 = flow_entry->flow_ip.ipv6.ul[3] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[2] << 12; + entry.bf0.ip_addr_2 = flow_entry->flow_ip.ipv6.ul[2] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[1] << 12; + entry.bf0.ip_addr_3 = flow_entry->flow_ip.ipv6.ul[1] >> 20 |\ + flow_entry->flow_ip.ipv6.ul[0] << 12; + entry.bf0.ip_addr_4 = flow_entry->flow_ip.ipv6.ul[0] >> 20; + entry.bf0.ip_protocol = flow_entry->ip_type; + rv = hppe_flow_ipv6_3tuple_add(dev_id, (a_uint32_t)add_mode, &flow_entry->entry_id, &entry); + } else + return SW_FAIL; + if (rv == SW_OK) { + union eg_flow_tree_map_tbl_u eg_treemap; + eg_treemap.bf.tree_id = flow_entry->tree_id; + rv = hppe_eg_flow_tree_map_tbl_set(dev_id, flow_entry->entry_id, &eg_treemap); + } + return rv; +} + +sw_error_t +adpt_hppe_flow_global_cfg_get( + a_uint32_t dev_id, + fal_flow_global_cfg_t *cfg) +{ + sw_error_t rv = SW_OK; +#if defined(CPPE) + a_uint32_t chip_ver = 0; + a_bool_t flow_cpy_escape = A_FALSE; +#endif + union flow_ctrl0_u flow_ctrl0; + union l3_route_ctrl_u route_ctrl; + union l3_route_ctrl_ext_u route_ctrl_ext; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cfg); + + memset(&flow_ctrl0, 0, sizeof(flow_ctrl0)); + memset(&route_ctrl, 0, sizeof(route_ctrl)); + memset(&route_ctrl_ext, 0, sizeof(route_ctrl_ext)); + + rv = hppe_flow_ctrl0_get(dev_id, &flow_ctrl0); + if( rv != SW_OK ) + return rv; + rv = hppe_l3_route_ctrl_get(dev_id, &route_ctrl); + if( rv != SW_OK ) + return rv; + rv = hppe_l3_route_ctrl_ext_get(dev_id, &route_ctrl_ext); + if( rv != SW_OK ) + return rv; + +#if defined(CPPE) + chip_ver = adpt_hppe_chip_revision_get(dev_id); + if (chip_ver == CPPE_REVISION) { + rv = adpt_cppe_flow_copy_escape_get(dev_id, &flow_cpy_escape); + SW_RTN_ON_ERROR(rv); + cfg->flow_mismatch_copy_escape_en = flow_cpy_escape; + } +#endif + + cfg->src_if_check_action= route_ctrl.bf.flow_src_if_check_cmd; + cfg->src_if_check_deacclr_en= route_ctrl.bf.flow_src_if_check_de_acce; + cfg->service_loop_en = route_ctrl_ext.bf.flow_service_code_loop_en; + cfg->service_loop_action = route_ctrl.bf.flow_service_code_loop; + cfg->service_loop_deacclr_en = route_ctrl.bf.flow_service_code_loop_de_acce; + cfg->flow_deacclr_action = route_ctrl.bf.flow_de_acce_cmd; + cfg->sync_mismatch_action = route_ctrl.bf.flow_sync_mismatch_cmd; + cfg->sync_mismatch_deacclr_en = route_ctrl.bf.flow_sync_mismatch_de_acce; + cfg->hash_mode_0 = flow_ctrl0.bf.flow_hash_mode_0; + cfg->hash_mode_1 = flow_ctrl0.bf.flow_hash_mode_1; + + return SW_OK; +} + +sw_error_t +adpt_hppe_flow_global_cfg_set( + a_uint32_t dev_id, + fal_flow_global_cfg_t *cfg) +{ + sw_error_t rv = SW_OK; +#if defined(CPPE) + a_uint32_t chip_ver = 0; +#endif + union flow_ctrl0_u flow_ctrl0; + union l3_route_ctrl_u route_ctrl; + union l3_route_ctrl_ext_u route_ctrl_ext; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cfg); + + memset(&flow_ctrl0, 0, sizeof(flow_ctrl0)); + memset(&route_ctrl, 0, sizeof(route_ctrl)); + memset(&route_ctrl_ext, 0, sizeof(route_ctrl_ext)); + + rv = hppe_flow_ctrl0_get(dev_id, &flow_ctrl0); + SW_RTN_ON_ERROR(rv); + + rv = hppe_l3_route_ctrl_get(dev_id, &route_ctrl); + SW_RTN_ON_ERROR(rv); + + rv = hppe_l3_route_ctrl_ext_get(dev_id, &route_ctrl_ext); + SW_RTN_ON_ERROR(rv); + + route_ctrl.bf.flow_src_if_check_cmd = cfg->src_if_check_action; + route_ctrl.bf.flow_src_if_check_de_acce = cfg->src_if_check_deacclr_en; + route_ctrl_ext.bf.flow_service_code_loop_en = cfg->service_loop_en; + route_ctrl.bf.flow_service_code_loop = cfg->service_loop_action; + route_ctrl.bf.flow_service_code_loop_de_acce = cfg->service_loop_deacclr_en; + route_ctrl.bf.flow_de_acce_cmd = cfg->flow_deacclr_action; + route_ctrl.bf.flow_sync_mismatch_cmd = cfg->sync_mismatch_action; + route_ctrl.bf.flow_sync_mismatch_de_acce = cfg->sync_mismatch_deacclr_en; + flow_ctrl0.bf.flow_hash_mode_0 = cfg->hash_mode_0; + flow_ctrl0.bf.flow_hash_mode_1 = cfg->hash_mode_1; + + rv = hppe_flow_ctrl0_set(dev_id, &flow_ctrl0); + SW_RTN_ON_ERROR(rv); + + rv = hppe_l3_route_ctrl_set(dev_id, &route_ctrl); + SW_RTN_ON_ERROR(rv); + + rv = hppe_l3_route_ctrl_ext_set(dev_id, &route_ctrl_ext); + SW_RTN_ON_ERROR(rv); + +#if defined(CPPE) + chip_ver = adpt_hppe_chip_revision_get(dev_id); + if (chip_ver == CPPE_REVISION) { + rv = adpt_cppe_flow_copy_escape_set(dev_id, + cfg->flow_mismatch_copy_escape_en); + SW_RTN_ON_ERROR(rv); + } +#endif + + return SW_OK; +} +#endif + +void adpt_hppe_flow_func_bitmap_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_flow_func_bitmap = 0; + return; +} + +static void adpt_hppe_flow_func_unregister(a_uint32_t dev_id, adpt_api_t *p_adpt_api) +{ + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_flow_host_add = NULL; + p_adpt_api->adpt_flow_entry_get = NULL; + p_adpt_api->adpt_flow_entry_del = NULL; + p_adpt_api->adpt_flow_status_get = NULL; + p_adpt_api->adpt_flow_ctrl_set = NULL; + p_adpt_api->adpt_flow_age_timer_get = NULL; + p_adpt_api->adpt_flow_status_set = NULL; + p_adpt_api->adpt_flow_host_get = NULL; + p_adpt_api->adpt_flow_host_del = NULL; + p_adpt_api->adpt_flow_ctrl_get = NULL; + p_adpt_api->adpt_flow_age_timer_set = NULL; + p_adpt_api->adpt_flow_entry_add = NULL; + p_adpt_api->adpt_flow_global_cfg_get = NULL; + p_adpt_api->adpt_flow_global_cfg_set = NULL; + p_adpt_api->adpt_flow_entry_next = NULL; + + return; +} + +sw_error_t adpt_hppe_flow_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return SW_FAIL; + + adpt_hppe_flow_func_unregister(dev_id, p_adpt_api); + +#ifndef IN_FLOW_MINI + if (p_adpt_api->adpt_flow_func_bitmap & (1 << FUNC_FLOW_HOST_ADD)) + p_adpt_api->adpt_flow_host_add = adpt_hppe_flow_host_add; + if (p_adpt_api->adpt_flow_func_bitmap & (1 << FUNC_FLOW_ENTRY_GET)) + p_adpt_api->adpt_flow_entry_get = adpt_hppe_flow_entry_get; + if (p_adpt_api->adpt_flow_func_bitmap & (1 << FUNC_FLOW_ENTRY_DEL)) + p_adpt_api->adpt_flow_entry_del = adpt_hppe_flow_entry_del; + if (p_adpt_api->adpt_flow_func_bitmap & (1 << FUNC_FLOW_STATUS_GET)) + p_adpt_api->adpt_flow_status_get = adpt_hppe_flow_status_get; + if (p_adpt_api->adpt_flow_func_bitmap & (1 << FUNC_FLOW_AGE_TIMER_GET)) + p_adpt_api->adpt_flow_age_timer_get = adpt_hppe_flow_age_timer_get; + if (p_adpt_api->adpt_flow_func_bitmap & (1 << FUNC_FLOW_STATUS_SET)) + p_adpt_api->adpt_flow_status_set = adpt_hppe_flow_status_set; + if (p_adpt_api->adpt_flow_func_bitmap & (1 << FUNC_FLOW_HOST_GET)) + p_adpt_api->adpt_flow_host_get = adpt_hppe_flow_host_get; + if (p_adpt_api->adpt_flow_func_bitmap & (1 << FUNC_FLOW_HOST_DEL)) + p_adpt_api->adpt_flow_host_del = adpt_hppe_flow_host_del; + if (p_adpt_api->adpt_flow_func_bitmap & (1 << FUNC_FLOW_AGE_TIMER_SET)) + p_adpt_api->adpt_flow_age_timer_set = adpt_hppe_flow_age_timer_set; + if (p_adpt_api->adpt_flow_func_bitmap & (1 << FUNC_FLOW_ENTRY_ADD)) + p_adpt_api->adpt_flow_entry_add = adpt_hppe_flow_entry_add; + if (p_adpt_api->adpt_flow_func_bitmap & (1 << FUNC_FLOW_GLOBAL_CFG_GET)) + p_adpt_api->adpt_flow_global_cfg_get = adpt_hppe_flow_global_cfg_get; + if (p_adpt_api->adpt_flow_func_bitmap & (1 << FUNC_FLOW_GLOBAL_CFG_SET)) + p_adpt_api->adpt_flow_global_cfg_set = adpt_hppe_flow_global_cfg_set; + if (p_adpt_api->adpt_flow_func_bitmap & (1 << FUNC_FLOW_ENTRY_NEXT)) + p_adpt_api->adpt_flow_entry_next = adpt_hppe_flow_entry_next; +#endif + if (p_adpt_api->adpt_flow_func_bitmap & (1 << FUNC_FLOW_CTRL_GET)) + p_adpt_api->adpt_flow_ctrl_get = adpt_hppe_flow_ctrl_get; + if (p_adpt_api->adpt_flow_func_bitmap & (1 << FUNC_FLOW_CTRL_SET)) + p_adpt_api->adpt_flow_ctrl_set = adpt_hppe_flow_ctrl_set; + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_ip.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_ip.c new file mode 100755 index 000000000..f4a40dd50 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_ip.c @@ -0,0 +1,1355 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "fal_ip.h" +#include "hppe_ip_reg.h" +#include "hppe_ip.h" +#include "adpt.h" + +#ifndef IN_IP_MINI +sw_error_t +adpt_hppe_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 = SW_OK; + union network_route_ip_u network_route_ip; + union network_route_ip_ext_u network_route_ip_ext; + union network_route_action_u network_route_action; + fal_ip6_addr_t ipv6, ipv6_mask; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(entry); + memset(&network_route_ip, 0, sizeof(network_route_ip)); + memset(&network_route_ip_ext, 0, sizeof(network_route_ip_ext)); + memset(&network_route_action, 0, sizeof(network_route_action)); + + if (type > 1 || (type == 0 && index > 31) || (type == 1 && index > 7)) + return SW_BAD_VALUE; + + if (type == 0) { + rv = hppe_network_route_ip_get(dev_id, index, + &network_route_ip); + if( rv != SW_OK ) + return rv; + rv = hppe_network_route_ip_ext_get(dev_id, index, + &network_route_ip_ext); + if( rv != SW_OK ) + return rv; + rv = hppe_network_route_action_get(dev_id, index, + &network_route_action); + if( rv != SW_OK ) + return rv; + } else { + rv = hppe_network_route_ip_get(dev_id, index * 4, &network_route_ip); + if( rv != SW_OK ) + return rv; + ipv6.ul[3] = network_route_ip.val[0]; + ipv6.ul[2] = network_route_ip.val[1]; + rv = hppe_network_route_ip_get(dev_id, index * 4 + 1, &network_route_ip); + if( rv != SW_OK ) + return rv; + ipv6.ul[1] = network_route_ip.val[0]; + ipv6.ul[0] = network_route_ip.val[1]; + rv = hppe_network_route_ip_get(dev_id, index * 4 + 2, &network_route_ip); + if( rv != SW_OK ) + return rv; + ipv6_mask.ul[3] = network_route_ip.val[0]; + ipv6_mask.ul[2] = network_route_ip.val[1]; + rv = hppe_network_route_ip_get(dev_id, index * 4 + 3, &network_route_ip); + if( rv != SW_OK ) + return rv; + ipv6_mask.ul[1] = network_route_ip.val[0]; + ipv6_mask.ul[0] = network_route_ip.val[1]; + rv = hppe_network_route_ip_ext_get(dev_id, index * 4, + &network_route_ip_ext); + if( rv != SW_OK ) + return rv; + rv = hppe_network_route_action_get(dev_id, index * 4, + &network_route_action); + if( rv != SW_OK ) + return rv; + } + + if (!network_route_ip_ext.bf.valid) + return SW_FAIL; + entry->action = (fal_fwd_cmd_t)network_route_action.bf.fwd_cmd; + entry->lan_wan = network_route_action.bf.lan_wan; + entry->dst_info = network_route_action.bf.dst_info; + entry->type = network_route_ip_ext.bf.entry_type; + if (type == 0) { + entry->route_addr.ip4_addr = network_route_ip.bf.ip_addr; + entry->route_addr_mask.ip4_addr_mask = network_route_ip.bf.ip_addr_mask; + } else { + memcpy(&entry->route_addr.ip6_addr , &ipv6, sizeof(ipv6)); + memcpy(&entry->route_addr_mask.ip6_addr_mask, + &ipv6_mask, sizeof(ipv6_mask)); + } + + return SW_OK; +} + +sw_error_t +adpt_hppe_ip_host_add(a_uint32_t dev_id, fal_host_entry_t * host_entry) +{ + a_uint8_t mode = 0, type = 0; + sw_error_t rv = SW_OK; + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(host_entry); + + mode = host_entry->flags >> 24; + type = host_entry->flags & 0xff; + + if ((type & FAL_IP_IP4_ADDR) == FAL_IP_IP4_ADDR) { + union host_tbl_u entry; + entry.bf.valid= host_entry->status; + entry.bf.key_type = 0; + entry.bf.fwd_cmd = host_entry->action; + entry.bf.syn_toggle = host_entry->syn_toggle; + entry.bf.dst_info = host_entry->dst_info; + entry.bf.lan_wan = host_entry->lan_wan; + entry.bf.ip_addr = host_entry->ip4_addr; + rv = hppe_host_ipv4_add(dev_id, (a_uint32_t)mode, &host_entry->entry_id, &entry); + } else if ((type & FAL_IP_IP6_ADDR) == FAL_IP_IP6_ADDR) { + union host_ipv6_tbl_u entry; + entry.bf.valid= host_entry->status; + entry.bf.key_type = 2; + entry.bf.fwd_cmd = host_entry->action; + entry.bf.syn_toggle = host_entry->syn_toggle; + entry.bf.dst_info = host_entry->dst_info; + entry.bf.lan_wan = host_entry->lan_wan; + entry.bf.ipv6_addr_0 = host_entry->ip6_addr.ul[3]; + entry.bf.ipv6_addr_1 = host_entry->ip6_addr.ul[3] >> 10 | \ + host_entry->ip6_addr.ul[2] << 22; + entry.bf.ipv6_addr_2 = host_entry->ip6_addr.ul[2] >> 10 | \ + host_entry->ip6_addr.ul[1] << 22; + entry.bf.ipv6_addr_3 = host_entry->ip6_addr.ul[1] >> 10 | \ + host_entry->ip6_addr.ul[0] << 22; + entry.bf.ipv6_addr_4 = host_entry->ip6_addr.ul[0] >> 10; + rv = hppe_host_ipv6_add(dev_id, (a_uint32_t)mode, &host_entry->entry_id, &entry); + } else if ((type & FAL_IP_IP4_ADDR_MCAST) == FAL_IP_IP4_ADDR_MCAST) { + union host_ipv4_mcast_tbl_u entry; + entry.bf.valid= host_entry->status; + entry.bf.key_type = 1; + entry.bf.fwd_cmd = host_entry->action; + entry.bf.syn_toggle = host_entry->syn_toggle; + entry.bf.dst_info = host_entry->dst_info; + entry.bf.lan_wan = host_entry->lan_wan; + entry.bf.gip_addr_0 = host_entry->ip4_addr; + entry.bf.gip_addr_1 = host_entry->ip4_addr >> 11; + entry.bf.vsi = host_entry->mcast_info.vsi; + entry.bf.sip_addr_0 = host_entry->mcast_info.sip4_addr; + entry.bf.sip_addr_1 = host_entry->mcast_info.sip4_addr >> 11; + rv = hppe_host_ipv4_mcast_add(dev_id, (a_uint32_t)mode, &host_entry->entry_id, &entry); + } else if ((type & FAL_IP_IP6_ADDR_MCAST) == FAL_IP_IP6_ADDR_MCAST) { + union host_ipv6_mcast_tbl_u entry; + entry.bf.valid= host_entry->status; + entry.bf.key_type = 3; + entry.bf.fwd_cmd = host_entry->action; + entry.bf.syn_toggle = host_entry->syn_toggle; + entry.bf.dst_info = host_entry->dst_info; + entry.bf.lan_wan = host_entry->lan_wan; + entry.bf.gipv6_addr_0 = host_entry->ip6_addr.ul[3]; + entry.bf.gipv6_addr_1 = host_entry->ip6_addr.ul[3] >> 20 | \ + host_entry->ip6_addr.ul[2] << 12; + entry.bf.gipv6_addr_2 = host_entry->ip6_addr.ul[2] >> 20 | \ + host_entry->ip6_addr.ul[1] << 12; + entry.bf.gipv6_addr_3 = host_entry->ip6_addr.ul[1] >> 20 | \ + host_entry->ip6_addr.ul[0] << 12; + entry.bf.gipv6_addr_4 = host_entry->ip6_addr.ul[0] >> 20; + entry.bf.vsi = host_entry->mcast_info.vsi; + entry.bf.sipv6_addr_0 = host_entry->mcast_info.sip6_addr.ul[3]; + entry.bf.sipv6_addr_1 = host_entry->mcast_info.sip6_addr.ul[3] >> 20 | \ + host_entry->mcast_info.sip6_addr.ul[2] << 12; + entry.bf.sipv6_addr_2 = host_entry->mcast_info.sip6_addr.ul[2] >> 20 | \ + host_entry->mcast_info.sip6_addr.ul[1] << 12; + entry.bf.sipv6_addr_3 = host_entry->mcast_info.sip6_addr.ul[1] >> 20 | \ + host_entry->mcast_info.sip6_addr.ul[0] << 12; + entry.bf.sipv6_addr_4 = host_entry->mcast_info.sip6_addr.ul[0] >> 20; + rv = hppe_host_ipv6_mcast_add(dev_id, (a_uint32_t)mode, &host_entry->entry_id, &entry); + } + return rv; +} +sw_error_t +adpt_hppe_ip_vsi_sg_cfg_get(a_uint32_t dev_id, a_uint32_t vsi, + fal_sg_cfg_t *sg_cfg) +{ + sw_error_t rv = SW_OK; + union l3_vsi_ext_u l3_vsi_ext; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(sg_cfg); + memset(&l3_vsi_ext, 0, sizeof(l3_vsi_ext)); + + rv = hppe_l3_vsi_ext_get(dev_id, vsi, &l3_vsi_ext); + if( rv != SW_OK ) + return rv; + + sg_cfg->ipv4_sg_en = l3_vsi_ext.bf.ipv4_sg_en; + sg_cfg->ipv4_sg_vio_action = l3_vsi_ext.bf.ipv4_sg_vio_cmd; + sg_cfg->ipv4_sg_port_en = l3_vsi_ext.bf.ipv4_sg_port_en; + sg_cfg->ipv4_sg_svlan_en = l3_vsi_ext.bf.ipv4_sg_svlan_en; + sg_cfg->ipv4_sg_cvlan_en = l3_vsi_ext.bf.ipv4_sg_cvlan_en; + sg_cfg->ipv4_src_unk_action = l3_vsi_ext.bf.ipv4_src_unk_cmd; + sg_cfg->ipv6_sg_en = l3_vsi_ext.bf.ipv6_sg_en; + sg_cfg->ipv6_sg_vio_action = l3_vsi_ext.bf.ipv6_sg_vio_cmd; + sg_cfg->ipv6_sg_port_en = l3_vsi_ext.bf.ipv6_sg_port_en; + sg_cfg->ipv6_sg_svlan_en = l3_vsi_ext.bf.ipv6_sg_svlan_en; + sg_cfg->ipv6_sg_cvlan_en = l3_vsi_ext.bf.ipv6_sg_cvlan_en; + sg_cfg->ipv6_src_unk_action = l3_vsi_ext.bf.ipv6_src_unk_cmd; + + return SW_OK; +} + +sw_error_t +adpt_hppe_ip_port_sg_cfg_set(a_uint32_t dev_id, fal_port_t port_id, + fal_sg_cfg_t *sg_cfg) +{ + union l3_vp_port_tbl_u l3_vp_port_tbl; + + memset(&l3_vp_port_tbl, 0, sizeof(l3_vp_port_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + + hppe_l3_vp_port_tbl_get(dev_id, port_id, &l3_vp_port_tbl); + + l3_vp_port_tbl.bf.ipv4_sg_en = sg_cfg->ipv4_sg_en; + l3_vp_port_tbl.bf.ipv4_sg_vio_cmd = sg_cfg->ipv4_sg_vio_action; + l3_vp_port_tbl.bf.ipv4_sg_port_en = sg_cfg->ipv4_sg_port_en; + l3_vp_port_tbl.bf.ipv4_sg_svlan_en = sg_cfg->ipv4_sg_svlan_en; + l3_vp_port_tbl.bf.ipv4_sg_cvlan_en = sg_cfg->ipv4_sg_cvlan_en; + l3_vp_port_tbl.bf.ipv4_src_unk_cmd = sg_cfg->ipv4_src_unk_action; + l3_vp_port_tbl.bf.ipv6_sg_en = sg_cfg->ipv6_sg_en; + l3_vp_port_tbl.bf.ipv6_sg_vio_cmd = sg_cfg->ipv6_sg_vio_action; + l3_vp_port_tbl.bf.ipv6_sg_port_en = sg_cfg->ipv6_sg_port_en; + l3_vp_port_tbl.bf.ipv6_sg_svlan_en = sg_cfg->ipv6_sg_svlan_en; + l3_vp_port_tbl.bf.ipv6_sg_cvlan_en = sg_cfg->ipv6_sg_cvlan_en; + l3_vp_port_tbl.bf.ipv6_src_unk_cmd = sg_cfg->ipv6_src_unk_action; + + return hppe_l3_vp_port_tbl_set(dev_id, port_id, &l3_vp_port_tbl); +} +sw_error_t +adpt_hppe_ip_port_intf_get(a_uint32_t dev_id, fal_port_t port_id, fal_intf_id_t *id) +{ + sw_error_t rv = SW_OK; + union l3_vp_port_tbl_u l3_vp_port_tbl; + + memset(&l3_vp_port_tbl, 0, sizeof(l3_vp_port_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(id); + + rv = hppe_l3_vp_port_tbl_get(dev_id, port_id, &l3_vp_port_tbl); + if( rv != SW_OK ) + return rv; + + id->l3_if_valid = l3_vp_port_tbl.bf.l3_if_valid; + id->l3_if_index = l3_vp_port_tbl.bf.l3_if_index; + + return SW_OK; +} + +sw_error_t +adpt_hppe_ip_vsi_arp_sg_cfg_set(a_uint32_t dev_id, a_uint32_t vsi, + fal_arp_sg_cfg_t *arp_sg_cfg) +{ + union l3_vsi_ext_u l3_vsi_ext; + + memset(&l3_vsi_ext, 0, sizeof(l3_vsi_ext)); + ADPT_DEV_ID_CHECK(dev_id); + + hppe_l3_vsi_ext_get(dev_id, vsi, &l3_vsi_ext); + + l3_vsi_ext.bf.ip_arp_sg_en = arp_sg_cfg->ipv4_arp_sg_en; + l3_vsi_ext.bf.ip_arp_sg_vio_cmd = arp_sg_cfg->ipv4_arp_sg_vio_action; + l3_vsi_ext.bf.ip_arp_sg_port_en = arp_sg_cfg->ipv4_arp_sg_port_en; + l3_vsi_ext.bf.ip_arp_sg_svlan_en = arp_sg_cfg->ipv4_arp_sg_svlan_en; + l3_vsi_ext.bf.ip_arp_sg_cvlan_en = arp_sg_cfg->ipv4_arp_sg_cvlan_en; + l3_vsi_ext.bf.ip_arp_src_unk_cmd = arp_sg_cfg->ipv4_arp_src_unk_action; + l3_vsi_ext.bf.ip_nd_sg_en = arp_sg_cfg->ip_nd_sg_en; + l3_vsi_ext.bf.ip_nd_sg_vio_cmd = arp_sg_cfg->ip_nd_sg_vio_action; + l3_vsi_ext.bf.ip_nd_sg_port_en = arp_sg_cfg->ip_nd_sg_port_en; + l3_vsi_ext.bf.ip_nd_sg_svlan_en = arp_sg_cfg->ip_nd_sg_svlan_en; + l3_vsi_ext.bf.ip_nd_sg_cvlan_en = arp_sg_cfg->ip_nd_sg_cvlan_en; + l3_vsi_ext.bf.ip_nd_src_unk_cmd = arp_sg_cfg->ip_nd_src_unk_action; + + return hppe_l3_vsi_ext_set(dev_id, vsi, &l3_vsi_ext); +} +sw_error_t +adpt_hppe_ip_pub_addr_get(a_uint32_t dev_id, + a_uint32_t index, fal_ip_pub_addr_t *entry) +{ + sw_error_t rv = SW_OK; + union in_pub_ip_addr_tbl_u in_pub_ip_addr_tbl; + + memset(&in_pub_ip_addr_tbl, 0, sizeof(in_pub_ip_addr_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(entry); + + rv = hppe_in_pub_ip_addr_tbl_get(dev_id, index, &in_pub_ip_addr_tbl); + if( rv != SW_OK ) + return rv; + + entry->pub_ip_addr = in_pub_ip_addr_tbl.bf.ip_addr; + return SW_OK; +} + +sw_error_t +adpt_hppe_ip_port_intf_set(a_uint32_t dev_id, fal_port_t port_id, fal_intf_id_t *id) +{ + union l3_vp_port_tbl_u l3_vp_port_tbl; + + memset(&l3_vp_port_tbl, 0, sizeof(l3_vp_port_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + + hppe_l3_vp_port_tbl_get(dev_id, port_id, &l3_vp_port_tbl); + + l3_vp_port_tbl.bf.l3_if_valid = id->l3_if_valid; + l3_vp_port_tbl.bf.l3_if_index = id->l3_if_index; + + return hppe_l3_vp_port_tbl_set(dev_id, port_id, &l3_vp_port_tbl); +} + +sw_error_t +adpt_hppe_ip_vsi_sg_cfg_set(a_uint32_t dev_id, a_uint32_t vsi, + fal_sg_cfg_t *sg_cfg) +{ + union l3_vsi_ext_u l3_vsi_ext; + + memset(&l3_vsi_ext, 0, sizeof(l3_vsi_ext)); + ADPT_DEV_ID_CHECK(dev_id); + + hppe_l3_vsi_ext_get(dev_id, vsi, &l3_vsi_ext); + + l3_vsi_ext.bf.ipv4_sg_en = sg_cfg->ipv4_sg_en; + l3_vsi_ext.bf.ipv4_sg_vio_cmd = sg_cfg->ipv4_sg_vio_action; + l3_vsi_ext.bf.ipv4_sg_port_en = sg_cfg->ipv4_sg_port_en; + l3_vsi_ext.bf.ipv4_sg_svlan_en = sg_cfg->ipv4_sg_svlan_en; + l3_vsi_ext.bf.ipv4_sg_cvlan_en = sg_cfg->ipv4_sg_cvlan_en; + l3_vsi_ext.bf.ipv4_src_unk_cmd = sg_cfg->ipv4_src_unk_action; + l3_vsi_ext.bf.ipv6_sg_en = sg_cfg->ipv6_sg_en; + l3_vsi_ext.bf.ipv6_sg_vio_cmd = sg_cfg->ipv6_sg_vio_action; + l3_vsi_ext.bf.ipv6_sg_port_en = sg_cfg->ipv6_sg_port_en; + l3_vsi_ext.bf.ipv6_sg_svlan_en = sg_cfg->ipv6_sg_svlan_en; + l3_vsi_ext.bf.ipv6_sg_cvlan_en = sg_cfg->ipv6_sg_cvlan_en; + l3_vsi_ext.bf.ipv6_src_unk_cmd = sg_cfg->ipv6_src_unk_action; + + return hppe_l3_vsi_ext_set(dev_id, vsi, &l3_vsi_ext); +} +sw_error_t +adpt_hppe_ip_port_macaddr_set(a_uint32_t dev_id, fal_port_t port_id, + fal_macaddr_entry_t *macaddr) +{ + union l3_vp_port_tbl_u l3_vp_port_tbl; + + memset(&l3_vp_port_tbl, 0, sizeof(l3_vp_port_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + + hppe_l3_vp_port_tbl_get(dev_id, port_id, &l3_vp_port_tbl); + + l3_vp_port_tbl.bf.mac_valid = macaddr->valid; + l3_vp_port_tbl.bf.mac_da_0 = macaddr->mac_addr.uc[4] << 8 | \ + macaddr->mac_addr.uc[5]; + l3_vp_port_tbl.bf.mac_da_1 = macaddr->mac_addr.uc[0] << 24 | \ + macaddr->mac_addr.uc[1] << 16 | \ + macaddr->mac_addr.uc[2] << 8 | \ + macaddr->mac_addr.uc[3]; + + return hppe_l3_vp_port_tbl_set(dev_id, port_id, &l3_vp_port_tbl); +} +sw_error_t +adpt_hppe_ip_vsi_intf_get(a_uint32_t dev_id, a_uint32_t vsi, fal_intf_id_t *id) +{ + sw_error_t rv = SW_OK; + union l3_vsi_u l3_vsi; + + memset(&l3_vsi, 0, sizeof(l3_vsi)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(id); + + + rv = hppe_l3_vsi_get(dev_id, vsi, &l3_vsi); + + if( rv != SW_OK ) + return rv; + + id->l3_if_valid = l3_vsi.bf.l3_if_valid; + id->l3_if_index = l3_vsi.bf.l3_if_index; + + return SW_OK; +} + +sw_error_t +adpt_hppe_ip_network_route_add(a_uint32_t dev_id, + a_uint32_t index, + fal_network_route_entry_t *entry) +{ + union network_route_ip_u network_route_ip; + union network_route_ip_ext_u network_route_ip_ext; + union network_route_action_u network_route_action; + + memset(&network_route_ip, 0, sizeof(network_route_ip)); + memset(&network_route_ip_ext, 0, sizeof(network_route_ip_ext)); + memset(&network_route_action, 0, sizeof(network_route_action)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(entry); + + if (entry->type > 1 || (entry->type == 0 && index > 31) || (entry->type == 1 && index > 7)) + return SW_BAD_VALUE; + + if (entry->type == 0) { + network_route_ip.bf.ip_addr = entry->route_addr.ip4_addr; + network_route_ip.bf.ip_addr_mask = entry->route_addr_mask.ip4_addr_mask; + network_route_ip_ext.bf.valid = 1; + network_route_ip_ext.bf.entry_type = entry->type; + network_route_action.bf.dst_info = entry->dst_info; + network_route_action.bf.fwd_cmd = entry->action; + network_route_action.bf.lan_wan = entry->lan_wan; + hppe_network_route_ip_set(dev_id, index, &network_route_ip); + hppe_network_route_ip_ext_set(dev_id, index, &network_route_ip_ext); + hppe_network_route_action_set(dev_id, index, &network_route_action); + } else { + network_route_ip_ext.bf.valid = 1; + network_route_ip_ext.bf.entry_type = entry->type; + network_route_action.bf.dst_info = entry->dst_info; + network_route_action.bf.fwd_cmd = entry->action; + network_route_action.bf.lan_wan = entry->lan_wan; + hppe_network_route_ip_ext_set(dev_id, index * 4, &network_route_ip_ext); + hppe_network_route_action_set(dev_id, index * 4, &network_route_action); + network_route_ip.bf.ip_addr = entry->route_addr.ip6_addr.ul[3]; + network_route_ip.bf.ip_addr_mask = entry->route_addr.ip6_addr.ul[2]; + hppe_network_route_ip_set(dev_id, index * 4, &network_route_ip); + network_route_ip.bf.ip_addr = entry->route_addr.ip6_addr.ul[1]; + network_route_ip.bf.ip_addr_mask = entry->route_addr.ip6_addr.ul[0]; + hppe_network_route_ip_set(dev_id, index * 4 + 1, &network_route_ip); + network_route_ip.bf.ip_addr = entry->route_addr_mask.ip6_addr_mask.ul[3]; + network_route_ip.bf.ip_addr_mask = entry->route_addr_mask.ip6_addr_mask.ul[2]; + hppe_network_route_ip_set(dev_id, index * 4 + 2, &network_route_ip); + network_route_ip.bf.ip_addr = entry->route_addr_mask.ip6_addr_mask.ul[1]; + network_route_ip.bf.ip_addr_mask = entry->route_addr_mask.ip6_addr_mask.ul[0]; + hppe_network_route_ip_set(dev_id, index * 4 + 3, &network_route_ip); + } + return SW_OK; +} + +sw_error_t +adpt_hppe_ip_network_route_del(a_uint32_t dev_id, + a_uint32_t index, a_uint8_t type) +{ + union network_route_ip_u network_route_ip; + union network_route_ip_ext_u network_route_ip_ext; + union network_route_action_u network_route_action; + + memset(&network_route_ip, 0, sizeof(network_route_ip)); + memset(&network_route_ip_ext, 0, sizeof(network_route_ip_ext)); + memset(&network_route_action, 0, sizeof(network_route_action)); + ADPT_DEV_ID_CHECK(dev_id); + + if (type > 1 || (type == 0 && index > 31) || (type == 1 && index > 7)) + return SW_BAD_VALUE; + + network_route_ip_ext.bf.valid = 0; + if (type == 0) { + hppe_network_route_ip_ext_set(dev_id, index, &network_route_ip_ext); + } else { + hppe_network_route_ip_ext_set(dev_id, index * 4, &network_route_ip_ext); + } + return SW_OK; +} + +sw_error_t +adpt_hppe_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 = SW_OK; + union l3_vp_port_tbl_u l3_vp_port_tbl; + + memset(&l3_vp_port_tbl, 0, sizeof(l3_vp_port_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(sg_cfg); + + rv = hppe_l3_vp_port_tbl_get(dev_id, port_id, &l3_vp_port_tbl); + if( rv != SW_OK ) + return rv; + + sg_cfg->ipv4_sg_en = l3_vp_port_tbl.bf.ipv4_sg_en; + sg_cfg->ipv4_sg_vio_action= l3_vp_port_tbl.bf.ipv4_sg_vio_cmd; + sg_cfg->ipv4_sg_port_en = l3_vp_port_tbl.bf.ipv4_sg_port_en; + sg_cfg->ipv4_sg_svlan_en = l3_vp_port_tbl.bf.ipv4_sg_svlan_en; + sg_cfg->ipv4_sg_cvlan_en = l3_vp_port_tbl.bf.ipv4_sg_cvlan_en; + sg_cfg->ipv4_src_unk_action = l3_vp_port_tbl.bf.ipv4_src_unk_cmd; + sg_cfg->ipv6_sg_en = l3_vp_port_tbl.bf.ipv6_sg_en; + sg_cfg->ipv6_sg_vio_action = l3_vp_port_tbl.bf.ipv6_sg_vio_cmd; + sg_cfg->ipv6_sg_port_en = l3_vp_port_tbl.bf.ipv6_sg_port_en; + sg_cfg->ipv6_sg_svlan_en = l3_vp_port_tbl.bf.ipv6_sg_svlan_en; + sg_cfg->ipv6_sg_cvlan_en = l3_vp_port_tbl.bf.ipv6_sg_cvlan_en; + sg_cfg->ipv6_src_unk_action = l3_vp_port_tbl.bf.ipv6_src_unk_cmd; + + return SW_OK; +} + +sw_error_t +adpt_hppe_ip_intf_get( + a_uint32_t dev_id, + a_uint32_t index, + fal_intf_entry_t *entry) +{ + sw_error_t rv = SW_OK; + union in_l3_if_tbl_u in_l3_if_tbl; + union eg_l3_if_tbl_u eg_l3_if_tbl; + + memset(&in_l3_if_tbl, 0, sizeof(in_l3_if_tbl)); + memset(&eg_l3_if_tbl, 0, sizeof(eg_l3_if_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(entry); + + rv = hppe_in_l3_if_tbl_get(dev_id, index, &in_l3_if_tbl); + if( rv != SW_OK ) + return rv; + rv = hppe_eg_l3_if_tbl_get(dev_id, index, &eg_l3_if_tbl); + if( rv != SW_OK ) + return rv; + + entry->mru = in_l3_if_tbl.bf.mru; + entry->mtu = in_l3_if_tbl.bf.mtu; + entry->ttl_dec_bypass_en = in_l3_if_tbl.bf.ttl_dec_bypass; + entry->ipv4_uc_route_en = in_l3_if_tbl.bf.ipv4_uc_route_en; + entry->ipv6_uc_route_en = in_l3_if_tbl.bf.ipv6_uc_route_en; + entry->icmp_trigger_en = in_l3_if_tbl.bf.icmp_trigger_en; + entry->ttl_exceed_action = in_l3_if_tbl.bf.ttl_exceed_cmd; + entry->ttl_exceed_deacclr_en = in_l3_if_tbl.bf.ttl_exceed_de_acce; + entry->mac_addr_bitmap = in_l3_if_tbl.bf.mac_bitmap; + entry->mac_addr.uc[5] = eg_l3_if_tbl.bf.mac_addr_0; + entry->mac_addr.uc[4] = eg_l3_if_tbl.bf.mac_addr_0 >> 8; + entry->mac_addr.uc[3] = eg_l3_if_tbl.bf.mac_addr_0 >> 16; + entry->mac_addr.uc[2] = eg_l3_if_tbl.bf.mac_addr_0 >> 24; + entry->mac_addr.uc[1] = eg_l3_if_tbl.bf.mac_addr_1; + entry->mac_addr.uc[0] = eg_l3_if_tbl.bf.mac_addr_1 >> 8; + + if (rv == SW_OK) { + union rt_interface_cnt_tbl_u cnt_ingress, cnt_egress; + hppe_rt_interface_cnt_tbl_get(dev_id, index, &cnt_ingress); + hppe_rt_interface_cnt_tbl_get(dev_id, index + 256, &cnt_egress); + entry->counter.rx_pkt_counter = cnt_ingress.bf.pkt_cnt; + entry->counter.rx_byte_counter = cnt_ingress.bf.byte_cnt_0 | ((a_uint64_t)cnt_ingress.bf.byte_cnt_1 << 32); + entry->counter.rx_drop_pkt_counter = cnt_ingress.bf.drop_pkt_cnt_0 | (cnt_ingress.bf.drop_pkt_cnt_1 << 24); + entry->counter.rx_drop_byte_counter = cnt_ingress.bf.drop_byte_cnt_0 | \ + ((a_uint64_t)cnt_ingress.bf.drop_byte_cnt_1 << 24); + + entry->counter.tx_pkt_counter = cnt_egress.bf.pkt_cnt; + entry->counter.tx_byte_counter = cnt_egress.bf.byte_cnt_0 | ((a_uint64_t)cnt_egress.bf.byte_cnt_1 << 32); + entry->counter.tx_drop_pkt_counter = cnt_egress.bf.drop_pkt_cnt_0 | (cnt_egress.bf.drop_pkt_cnt_1 << 24); + entry->counter.tx_drop_byte_counter = cnt_egress.bf.drop_byte_cnt_0 | \ + ((a_uint64_t)cnt_egress.bf.drop_byte_cnt_1 << 24); + } + + return SW_OK; +} + +sw_error_t +adpt_hppe_ip_pub_addr_set(a_uint32_t dev_id, + a_uint32_t index, fal_ip_pub_addr_t *entry) +{ + union in_pub_ip_addr_tbl_u in_pub_ip_addr_tbl; + + memset(&in_pub_ip_addr_tbl, 0, sizeof(in_pub_ip_addr_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(entry); + + in_pub_ip_addr_tbl.bf.ip_addr = entry->pub_ip_addr; + return hppe_in_pub_ip_addr_tbl_set(dev_id, index, &in_pub_ip_addr_tbl); +} + +sw_error_t +adpt_hppe_ip_host_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_host_entry_t * host_entry) +{ + a_uint8_t mode = 0, type = 0; + sw_error_t rv = SW_OK; + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(host_entry); + + mode = host_entry->flags >> 24; + type = host_entry->flags & 0xff; + + if (del_mode & FAL_IP_ENTRY_ID_EN) + mode = 1; + else if (del_mode & FAL_IP_ENTRY_IPADDR_EN) + mode = 0; + else if (del_mode & FAL_IP_ENTRY_ALL_EN) { + return hppe_host_flush_common(dev_id); + } + + if ((type & FAL_IP_IP4_ADDR) == FAL_IP_IP4_ADDR) { + union host_tbl_u entry; + entry.bf.valid= 1; + entry.bf.key_type = 0; + entry.bf.fwd_cmd = host_entry->action; + entry.bf.syn_toggle = host_entry->syn_toggle; + entry.bf.dst_info = host_entry->dst_info; + entry.bf.lan_wan = host_entry->lan_wan; + entry.bf.ip_addr = host_entry->ip4_addr; + rv = hppe_host_ipv4_del(dev_id, (a_uint32_t)mode, &host_entry->entry_id, &entry); + } else if ((type & FAL_IP_IP6_ADDR) == FAL_IP_IP6_ADDR) { + union host_ipv6_tbl_u entry; + entry.bf.valid= 1; + entry.bf.key_type = 2; + entry.bf.fwd_cmd = host_entry->action; + entry.bf.syn_toggle = host_entry->syn_toggle; + entry.bf.dst_info = host_entry->dst_info; + entry.bf.lan_wan = host_entry->lan_wan; + entry.bf.ipv6_addr_0 = host_entry->ip6_addr.ul[3]; + entry.bf.ipv6_addr_1 = host_entry->ip6_addr.ul[3] >> 10 | \ + host_entry->ip6_addr.ul[2] << 22; + entry.bf.ipv6_addr_2 = host_entry->ip6_addr.ul[2] >> 10 | \ + host_entry->ip6_addr.ul[1] << 22; + entry.bf.ipv6_addr_3 = host_entry->ip6_addr.ul[1] >> 10 | \ + host_entry->ip6_addr.ul[0] << 22; + entry.bf.ipv6_addr_4 = host_entry->ip6_addr.ul[0] >> 10; + rv = hppe_host_ipv6_del(dev_id, (a_uint32_t)mode, &host_entry->entry_id, &entry); + } else if ((type & FAL_IP_IP4_ADDR_MCAST) == FAL_IP_IP4_ADDR_MCAST) { + union host_ipv4_mcast_tbl_u entry; + entry.bf.valid= 1; + entry.bf.key_type = 1; + entry.bf.fwd_cmd = host_entry->action; + entry.bf.syn_toggle = host_entry->syn_toggle; + entry.bf.dst_info = host_entry->dst_info; + entry.bf.lan_wan = host_entry->lan_wan; + entry.bf.gip_addr_0 = host_entry->ip4_addr; + entry.bf.gip_addr_1 = host_entry->ip4_addr >> 11; + entry.bf.vsi = host_entry->mcast_info.vsi; + entry.bf.sip_addr_0 = host_entry->mcast_info.sip4_addr; + entry.bf.sip_addr_1 = host_entry->mcast_info.sip4_addr >> 11; + rv = hppe_host_ipv4_mcast_del(dev_id, (a_uint32_t)mode, &host_entry->entry_id, &entry); + } else if ((type & FAL_IP_IP6_ADDR_MCAST) == FAL_IP_IP6_ADDR_MCAST) { + union host_ipv6_mcast_tbl_u entry; + entry.bf.valid= 1; + entry.bf.key_type = 3; + entry.bf.fwd_cmd = host_entry->action; + entry.bf.syn_toggle = host_entry->syn_toggle; + entry.bf.dst_info = host_entry->dst_info; + entry.bf.lan_wan = host_entry->lan_wan; + entry.bf.gipv6_addr_0 = host_entry->ip6_addr.ul[3]; + entry.bf.gipv6_addr_1 = host_entry->ip6_addr.ul[3] >> 20 | \ + host_entry->ip6_addr.ul[2] << 12; + entry.bf.gipv6_addr_2 = host_entry->ip6_addr.ul[2] >> 20 | \ + host_entry->ip6_addr.ul[1] << 12; + entry.bf.gipv6_addr_3 = host_entry->ip6_addr.ul[1] >> 20 | \ + host_entry->ip6_addr.ul[0] << 12; + entry.bf.gipv6_addr_4 = host_entry->ip6_addr.ul[0] >> 20; + entry.bf.vsi = host_entry->mcast_info.vsi; + entry.bf.sipv6_addr_0 = host_entry->mcast_info.sip6_addr.ul[3]; + entry.bf.sipv6_addr_1 = host_entry->mcast_info.sip6_addr.ul[3] >> 20 | \ + host_entry->mcast_info.sip6_addr.ul[2] << 12; + entry.bf.sipv6_addr_2 = host_entry->mcast_info.sip6_addr.ul[2] >> 20 | \ + host_entry->mcast_info.sip6_addr.ul[1] << 12; + entry.bf.sipv6_addr_3 = host_entry->mcast_info.sip6_addr.ul[1] >> 20 | \ + host_entry->mcast_info.sip6_addr.ul[0] << 12; + entry.bf.sipv6_addr_4 = host_entry->mcast_info.sip6_addr.ul[0] >> 20; + rv = hppe_host_ipv6_mcast_del(dev_id, (a_uint32_t)mode, &host_entry->entry_id, &entry); + } + return rv; +} +sw_error_t +adpt_hppe_ip_route_mismatch_get(a_uint32_t dev_id, fal_fwd_cmd_t *cmd) +{ + sw_error_t rv = SW_OK; + union l3_route_ctrl_ext_u l3_route_ctrl_ext; + + memset(&l3_route_ctrl_ext, 0, sizeof(l3_route_ctrl_ext)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cmd); + + rv = hppe_l3_route_ctrl_ext_get(dev_id, &l3_route_ctrl_ext); + if( rv != SW_OK ) + return rv; + + *cmd = (fal_fwd_cmd_t)l3_route_ctrl_ext.bf.ip_route_mismatch; + return rv; +} + +sw_error_t +adpt_hppe_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 = SW_OK; + union l3_vsi_ext_u l3_vsi_ext; + + memset(&l3_vsi_ext, 0, sizeof(l3_vsi_ext)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(arp_sg_cfg); + + rv = hppe_l3_vsi_ext_get(dev_id, vsi, &l3_vsi_ext); + if( rv != SW_OK ) + return rv; + + arp_sg_cfg->ipv4_arp_sg_en = l3_vsi_ext.bf.ip_arp_sg_en; + arp_sg_cfg->ipv4_arp_sg_vio_action = l3_vsi_ext.bf.ip_arp_sg_vio_cmd; + arp_sg_cfg->ipv4_arp_sg_port_en = l3_vsi_ext.bf.ip_arp_sg_port_en; + arp_sg_cfg->ipv4_arp_sg_svlan_en = l3_vsi_ext.bf.ip_arp_sg_svlan_en; + arp_sg_cfg->ipv4_arp_sg_cvlan_en = l3_vsi_ext.bf.ip_arp_sg_cvlan_en; + arp_sg_cfg->ipv4_arp_src_unk_action = l3_vsi_ext.bf.ip_arp_src_unk_cmd; + arp_sg_cfg->ip_nd_sg_en = l3_vsi_ext.bf.ip_nd_sg_en; + arp_sg_cfg->ip_nd_sg_vio_action = l3_vsi_ext.bf.ip_nd_sg_vio_cmd; + arp_sg_cfg->ip_nd_sg_port_en = l3_vsi_ext.bf.ip_nd_sg_port_en; + arp_sg_cfg->ip_nd_sg_svlan_en = l3_vsi_ext.bf.ip_nd_sg_svlan_en; + arp_sg_cfg->ip_nd_sg_cvlan_en = l3_vsi_ext.bf.ip_nd_sg_cvlan_en; + arp_sg_cfg->ip_nd_src_unk_action = l3_vsi_ext.bf.ip_nd_src_unk_cmd; + + return rv; +} + +sw_error_t +adpt_hppe_ip_port_arp_sg_cfg_set(a_uint32_t dev_id, fal_port_t port_id, + fal_arp_sg_cfg_t *arp_sg_cfg) +{ + union l3_vp_port_tbl_u l3_vp_port_tbl; + + memset(&l3_vp_port_tbl, 0, sizeof(l3_vp_port_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + + hppe_l3_vp_port_tbl_get(dev_id, port_id, &l3_vp_port_tbl); + + l3_vp_port_tbl.bf.ip_arp_sg_en = arp_sg_cfg->ipv4_arp_sg_en; + l3_vp_port_tbl.bf.ip_arp_sg_vio_cmd = arp_sg_cfg->ipv4_arp_sg_vio_action; + l3_vp_port_tbl.bf.ip_arp_sg_port_en = arp_sg_cfg->ipv4_arp_sg_port_en; + l3_vp_port_tbl.bf.ip_arp_sg_svlan_en = arp_sg_cfg->ipv4_arp_sg_svlan_en; + l3_vp_port_tbl.bf.ip_arp_sg_cvlan_en = arp_sg_cfg->ipv4_arp_sg_cvlan_en; + l3_vp_port_tbl.bf.ip_arp_src_unk_cmd = arp_sg_cfg->ipv4_arp_src_unk_action; + l3_vp_port_tbl.bf.ip_nd_sg_en = arp_sg_cfg->ip_nd_sg_en; + l3_vp_port_tbl.bf.ip_nd_sg_vio_cmd = arp_sg_cfg->ip_nd_sg_vio_action; + l3_vp_port_tbl.bf.ip_nd_sg_port_en = arp_sg_cfg->ip_nd_sg_port_en; + l3_vp_port_tbl.bf.ip_nd_sg_svlan_en = arp_sg_cfg->ip_nd_sg_svlan_en; + l3_vp_port_tbl.bf.ip_nd_sg_cvlan_en = arp_sg_cfg->ip_nd_sg_cvlan_en; + l3_vp_port_tbl.bf.ip_nd_src_unk_cmd = arp_sg_cfg->ip_nd_src_unk_action; + + return hppe_l3_vp_port_tbl_set(dev_id, port_id, &l3_vp_port_tbl); +} +sw_error_t +adpt_hppe_ip_vsi_mc_mode_set(a_uint32_t dev_id, a_uint32_t vsi, + fal_mc_mode_cfg_t *cfg) +{ + union l3_vsi_u l3_vsi; + + memset(&l3_vsi, 0, sizeof(l3_vsi)); + ADPT_DEV_ID_CHECK(dev_id); + + hppe_l3_vsi_get(dev_id, vsi, &l3_vsi); + + l3_vsi.bf.l2_ipv4_mc_en = cfg->l2_ipv4_mc_en; + l3_vsi.bf.l2_ipv4_mc_mode = cfg->l2_ipv4_mc_mode; + l3_vsi.bf.l2_ipv6_mc_en = cfg->l2_ipv6_mc_en; + l3_vsi.bf.l2_ipv6_mc_mode = cfg->l2_ipv6_mc_mode; + + return hppe_l3_vsi_set(dev_id, vsi, &l3_vsi); +} + +sw_error_t +adpt_hppe_ip_vsi_intf_set(a_uint32_t dev_id, a_uint32_t vsi, fal_intf_id_t *id) +{ + union l3_vsi_u l3_vsi; + + memset(&l3_vsi, 0, sizeof(l3_vsi)); + ADPT_DEV_ID_CHECK(dev_id); + + hppe_l3_vsi_get(dev_id, vsi, &l3_vsi); + + l3_vsi.bf.l3_if_valid = id->l3_if_valid; + l3_vsi.bf.l3_if_index = id->l3_if_index; + + return hppe_l3_vsi_set(dev_id, vsi, &l3_vsi); +} + +sw_error_t +adpt_hppe_ip_nexthop_get(a_uint32_t dev_id, + a_uint32_t index, fal_ip_nexthop_t *entry) +{ + sw_error_t rv = SW_OK; + union in_nexthop_tbl_u in_nexthop_tbl; + + memset(&in_nexthop_tbl, 0, sizeof(in_nexthop_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(entry); + + rv = hppe_in_nexthop_tbl_get(dev_id, index, &in_nexthop_tbl); + if( rv != SW_OK ) + return rv; + + entry->type = in_nexthop_tbl.bf0.type; + entry->vsi = in_nexthop_tbl.bf1.vsi; + entry->port = in_nexthop_tbl.bf0.port; + entry->if_index = in_nexthop_tbl.bf0.post_l3_if; + entry->ip_to_me_en = in_nexthop_tbl.bf0.ip_to_me; + entry->pub_ip_index = in_nexthop_tbl.bf1.ip_pub_addr_index; + entry->stag_fmt = in_nexthop_tbl.bf0.stag_fmt; + entry->svid = in_nexthop_tbl.bf0.svid; + entry->ctag_fmt = in_nexthop_tbl.bf0.ctag_fmt; + entry->cvid = in_nexthop_tbl.bf0.cvid; + entry->mac_addr.uc[5] = in_nexthop_tbl.bf1.mac_addr_0; + entry->mac_addr.uc[4] = in_nexthop_tbl.bf1.mac_addr_0 >> 8; + entry->mac_addr.uc[3] = in_nexthop_tbl.bf1.mac_addr_1; + entry->mac_addr.uc[2] = in_nexthop_tbl.bf1.mac_addr_1 >> 8; + entry->mac_addr.uc[1] = in_nexthop_tbl.bf1.mac_addr_1 >> 16; + entry->mac_addr.uc[0] = in_nexthop_tbl.bf1.mac_addr_1 >> 24; + entry->dnat_ip = in_nexthop_tbl.bf0.ip_addr_dnat; + + return SW_OK; +} + +sw_error_t +adpt_hppe_ip_route_mismatch_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + union l3_route_ctrl_ext_u l3_route_ctrl_ext; + + memset(&l3_route_ctrl_ext, 0, sizeof(l3_route_ctrl_ext)); + ADPT_DEV_ID_CHECK(dev_id); + + hppe_l3_route_ctrl_ext_get(dev_id, &l3_route_ctrl_ext); + l3_route_ctrl_ext.bf.ip_route_mismatch = cmd; + + return hppe_l3_route_ctrl_ext_set(dev_id, &l3_route_ctrl_ext); +} +sw_error_t +adpt_hppe_ip_host_get(a_uint32_t dev_id, a_uint32_t get_mode, + fal_host_entry_t *host_entry) +{ + a_uint8_t mode = 0, type = 0; + sw_error_t rv = SW_OK; + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(host_entry); + + mode = host_entry->flags >> 24; + type = host_entry->flags & 0xff; + + if (get_mode & FAL_IP_ENTRY_ID_EN) + mode = 1; + else if (get_mode & FAL_IP_ENTRY_IPADDR_EN) + mode = 0; + + if ((type & FAL_IP_IP4_ADDR) == FAL_IP_IP4_ADDR) { + union host_tbl_u entry; + entry.bf.key_type = 0; + entry.bf.ip_addr = host_entry->ip4_addr; + rv = hppe_host_ipv4_get(dev_id, (a_uint32_t)mode, &host_entry->entry_id, &entry); + if (!rv && (entry.bf.key_type != 0)) + rv = SW_FAIL; + host_entry->ip4_addr = entry.bf.ip_addr; + host_entry->lan_wan = entry.bf.lan_wan; + host_entry->dst_info = entry.bf.dst_info; + host_entry->syn_toggle = entry.bf.syn_toggle; + host_entry->action = entry.bf.fwd_cmd; + host_entry->status = entry.bf.valid; + } else if ((type & FAL_IP_IP6_ADDR) == FAL_IP_IP6_ADDR) { + union host_ipv6_tbl_u entry; + entry.bf.key_type = 2; + entry.bf.ipv6_addr_0 = host_entry->ip6_addr.ul[3]; + entry.bf.ipv6_addr_1 = host_entry->ip6_addr.ul[3] >> 10 | \ + host_entry->ip6_addr.ul[2] << 22; + entry.bf.ipv6_addr_2 = host_entry->ip6_addr.ul[2] >> 10 | \ + host_entry->ip6_addr.ul[1] << 22; + entry.bf.ipv6_addr_3 = host_entry->ip6_addr.ul[1] >> 10 | \ + host_entry->ip6_addr.ul[0] << 22; + entry.bf.ipv6_addr_4 = host_entry->ip6_addr.ul[0] >> 10; + rv = hppe_host_ipv6_get(dev_id, (a_uint32_t)mode, &host_entry->entry_id, &entry); + if (!rv && (entry.bf.key_type != 2)) + rv = SW_FAIL; + host_entry->ip6_addr.ul[3] = entry.bf.ipv6_addr_0 | entry.bf.ipv6_addr_1 << 10; + host_entry->ip6_addr.ul[2] = entry.bf.ipv6_addr_1 >> 22 | entry.bf.ipv6_addr_2 << 10; + host_entry->ip6_addr.ul[1] = entry.bf.ipv6_addr_2 >> 22 | entry.bf.ipv6_addr_3 << 10; + host_entry->ip6_addr.ul[0] = entry.bf.ipv6_addr_3 >> 22 | entry.bf.ipv6_addr_4 << 10; + host_entry->lan_wan = entry.bf.lan_wan; + host_entry->dst_info = entry.bf.dst_info; + host_entry->syn_toggle = entry.bf.syn_toggle; + host_entry->action = entry.bf.fwd_cmd; + host_entry->status = entry.bf.valid; + } else if ((type & FAL_IP_IP4_ADDR_MCAST) == FAL_IP_IP4_ADDR_MCAST) { + union host_ipv4_mcast_tbl_u entry; + entry.bf.key_type = 1; + entry.bf.gip_addr_0 = host_entry->ip4_addr; + entry.bf.gip_addr_1 = host_entry->ip4_addr >> 11; + entry.bf.vsi = host_entry->mcast_info.vsi; + entry.bf.sip_addr_0 = host_entry->mcast_info.sip4_addr; + entry.bf.sip_addr_1 = host_entry->mcast_info.sip4_addr >> 11; + rv = hppe_host_ipv4_mcast_get(dev_id, (a_uint32_t)mode, &host_entry->entry_id, &entry); + if (!rv && (entry.bf.key_type != 1)) + rv = SW_FAIL; + host_entry->lan_wan = entry.bf.lan_wan; + host_entry->dst_info = entry.bf.dst_info; + host_entry->syn_toggle = entry.bf.syn_toggle; + host_entry->action = entry.bf.fwd_cmd; + host_entry->status = entry.bf.valid; + host_entry->ip4_addr = entry.bf.gip_addr_0 | entry.bf.gip_addr_1 << 11; + host_entry->mcast_info.vsi = entry.bf.vsi; + host_entry->mcast_info.sip4_addr = entry.bf.sip_addr_0 | entry.bf.sip_addr_1 << 11; + } else if ((type & FAL_IP_IP6_ADDR_MCAST) == FAL_IP_IP6_ADDR_MCAST) { + union host_ipv6_mcast_tbl_u entry; + entry.bf.key_type = 3; + entry.bf.vsi = host_entry->mcast_info.vsi; + entry.bf.gipv6_addr_0 = host_entry->ip6_addr.ul[3]; + entry.bf.gipv6_addr_1 = host_entry->ip6_addr.ul[3] >> 20 | \ + host_entry->ip6_addr.ul[2] << 12; + entry.bf.gipv6_addr_2 = host_entry->ip6_addr.ul[2] >> 20 | \ + host_entry->ip6_addr.ul[1] << 12; + entry.bf.gipv6_addr_3 = host_entry->ip6_addr.ul[1] >> 20 | \ + host_entry->ip6_addr.ul[0] << 12; + entry.bf.gipv6_addr_4 = host_entry->ip6_addr.ul[0] >> 20; + entry.bf.sipv6_addr_0 = host_entry->mcast_info.sip6_addr.ul[3]; + entry.bf.sipv6_addr_1 = host_entry->mcast_info.sip6_addr.ul[3] >> 20 | \ + host_entry->mcast_info.sip6_addr.ul[2] << 12; + entry.bf.sipv6_addr_2 = host_entry->mcast_info.sip6_addr.ul[2] >> 20 | \ + host_entry->mcast_info.sip6_addr.ul[1] << 12; + entry.bf.sipv6_addr_3 = host_entry->mcast_info.sip6_addr.ul[1] >> 20 | \ + host_entry->mcast_info.sip6_addr.ul[0] << 12; + entry.bf.sipv6_addr_4 = host_entry->mcast_info.sip6_addr.ul[0] >> 20; + rv = hppe_host_ipv6_mcast_get(dev_id, (a_uint32_t)mode, &host_entry->entry_id, &entry); + if (!rv && (entry.bf.key_type != 3)) + rv = SW_FAIL; + host_entry->lan_wan = entry.bf.lan_wan; + host_entry->dst_info = entry.bf.dst_info; + host_entry->syn_toggle = entry.bf.syn_toggle; + host_entry->action = entry.bf.fwd_cmd; + host_entry->status = entry.bf.valid; + host_entry->ip6_addr.ul[3] = entry.bf.gipv6_addr_0 | entry.bf.gipv6_addr_1 << 20; + host_entry->ip6_addr.ul[2] = entry.bf.gipv6_addr_1 >> 12 | entry.bf.gipv6_addr_2 << 20; + host_entry->ip6_addr.ul[1] = entry.bf.gipv6_addr_2 >> 12 | entry.bf.gipv6_addr_3 << 20; + host_entry->ip6_addr.ul[0] = entry.bf.gipv6_addr_3 >> 12 | entry.bf.gipv6_addr_4 << 20; + host_entry->mcast_info.vsi = entry.bf.vsi; + host_entry->mcast_info.sip6_addr.ul[3] = entry.bf.sipv6_addr_0 | entry.bf.sipv6_addr_1 << 20; + host_entry->mcast_info.sip6_addr.ul[2] = entry.bf.sipv6_addr_1 >> 12 | entry.bf.sipv6_addr_2 << 20; + host_entry->mcast_info.sip6_addr.ul[1] = entry.bf.sipv6_addr_2 >> 12 | entry.bf.sipv6_addr_3 << 20; + host_entry->mcast_info.sip6_addr.ul[0] = entry.bf.sipv6_addr_3 >> 12 | entry.bf.sipv6_addr_4 << 20; + } + + return rv; +} + +sw_error_t +adpt_hppe_ip_host_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_host_entry_t * host_entry) +{ + a_uint32_t i = 0, step = 0; + sw_error_t rv = SW_OK; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(host_entry); + + if (FAL_NEXT_ENTRY_FIRST_ID == host_entry->entry_id) + i = 0; + + if (next_mode == FAL_IP_IP6_ADDR_MCAST) { + if (FAL_NEXT_ENTRY_FIRST_ID != host_entry->entry_id) + i = (host_entry->entry_id & ~3) + 4; + step = 4; + } else if (next_mode == FAL_IP_IP4_ADDR_MCAST) { + if (FAL_NEXT_ENTRY_FIRST_ID != host_entry->entry_id) + i = (host_entry->entry_id & ~1) + 2; + step = 2; + } else if (next_mode == FAL_IP_IP4_ADDR) { + if (FAL_NEXT_ENTRY_FIRST_ID != host_entry->entry_id) + i = host_entry->entry_id + 1; + step = 1; + } else if (next_mode == FAL_IP_IP6_ADDR) { + if (FAL_NEXT_ENTRY_FIRST_ID != host_entry->entry_id) + i = (host_entry->entry_id & ~1) + 2; + step = 2; + } + for (; i < HOST_TBL_MAX_ENTRY;) { + host_entry->flags = next_mode; + host_entry->entry_id = i; + rv = adpt_hppe_ip_host_get(dev_id, FAL_IP_ENTRY_ID_EN, host_entry); + if (!rv) { + return rv; + } + i += step; + } + + return SW_FAIL; + +} +sw_error_t +adpt_hppe_ip_intf_set( + a_uint32_t dev_id, + a_uint32_t index, + fal_intf_entry_t *entry) +{ + union in_l3_if_tbl_u in_l3_if_tbl; + union eg_l3_if_tbl_u eg_l3_if_tbl; + a_uint8_t i = 0; + + memset(&in_l3_if_tbl, 0, sizeof(in_l3_if_tbl)); + memset(&eg_l3_if_tbl, 0, sizeof(eg_l3_if_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(entry); + + in_l3_if_tbl.bf.mru = entry->mru; + in_l3_if_tbl.bf.mtu = entry->mtu; + in_l3_if_tbl.bf.ttl_dec_bypass = entry->ttl_dec_bypass_en; + in_l3_if_tbl.bf.ipv4_uc_route_en = entry->ipv4_uc_route_en; + in_l3_if_tbl.bf.ipv6_uc_route_en = entry->ipv6_uc_route_en; + in_l3_if_tbl.bf.icmp_trigger_en = entry->icmp_trigger_en; + in_l3_if_tbl.bf.ttl_exceed_cmd = entry->ttl_exceed_action; + in_l3_if_tbl.bf.ttl_exceed_de_acce = entry->ttl_exceed_deacclr_en; + in_l3_if_tbl.bf.mac_bitmap = entry->mac_addr_bitmap; + eg_l3_if_tbl.bf.mac_addr_0 = entry->mac_addr.uc[5] | \ + entry->mac_addr.uc[4] << 8 | \ + entry->mac_addr.uc[3] << 16 | \ + entry->mac_addr.uc[2] << 24; + eg_l3_if_tbl.bf.mac_addr_1 = entry->mac_addr.uc[1] | \ + entry->mac_addr.uc[0] << 8; + + for (i = 0; i < 8; i++) { + if ((entry->mac_addr_bitmap >> i) & 0x1) { + union my_mac_tbl_u mymac; + mymac.bf.valid = 1; + mymac.bf.mac_da_0 = eg_l3_if_tbl.bf.mac_addr_0; + mymac.bf.mac_da_1 = eg_l3_if_tbl.bf.mac_addr_1; + hppe_my_mac_tbl_set(dev_id, i, &mymac); + break; + } + } + + hppe_in_l3_if_tbl_set(dev_id, index, &in_l3_if_tbl); + hppe_eg_l3_if_tbl_set(dev_id, index, &eg_l3_if_tbl); + return SW_OK; +} + +sw_error_t +adpt_hppe_ip_vsi_mc_mode_get(a_uint32_t dev_id, a_uint32_t vsi, + fal_mc_mode_cfg_t *cfg) +{ + sw_error_t rv = SW_OK; + union l3_vsi_u l3_vsi; + + memset(&l3_vsi, 0, sizeof(l3_vsi)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cfg); + + rv = hppe_l3_vsi_get(dev_id, vsi, &l3_vsi); + if( rv != SW_OK ) + return rv; + + cfg->l2_ipv4_mc_en = l3_vsi.bf.l2_ipv4_mc_en; + cfg->l2_ipv4_mc_mode = l3_vsi.bf.l2_ipv4_mc_mode; + cfg->l2_ipv6_mc_en = l3_vsi.bf.l2_ipv6_mc_en; + cfg->l2_ipv6_mc_mode = l3_vsi.bf.l2_ipv6_mc_mode; + + return SW_OK; +} + +sw_error_t +adpt_hppe_ip_port_macaddr_get(a_uint32_t dev_id, fal_port_t port_id, + fal_macaddr_entry_t *macaddr) +{ + sw_error_t rv = SW_OK; + union l3_vp_port_tbl_u l3_vp_port_tbl; + + memset(&l3_vp_port_tbl, 0, sizeof(l3_vp_port_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(macaddr); + + rv = hppe_l3_vp_port_tbl_get(dev_id, port_id, &l3_vp_port_tbl); + if( rv != SW_OK ) + return rv; + + macaddr->valid = l3_vp_port_tbl.bf.mac_valid; + macaddr->mac_addr.uc[5] = l3_vp_port_tbl.bf.mac_da_0; + macaddr->mac_addr.uc[4] = l3_vp_port_tbl.bf.mac_da_0 >> 8; + macaddr->mac_addr.uc[3] = l3_vp_port_tbl.bf.mac_da_1; + macaddr->mac_addr.uc[2] = l3_vp_port_tbl.bf.mac_da_1 >> 8; + macaddr->mac_addr.uc[1] = l3_vp_port_tbl.bf.mac_da_1 >> 16; + macaddr->mac_addr.uc[0] = l3_vp_port_tbl.bf.mac_da_1 >> 24; + + return SW_OK; +} + +sw_error_t +adpt_hppe_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 = SW_OK; + union l3_vp_port_tbl_u l3_vp_port_tbl; + + memset(&l3_vp_port_tbl, 0, sizeof(l3_vp_port_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(arp_sg_cfg); + + rv = hppe_l3_vp_port_tbl_get(dev_id, port_id, &l3_vp_port_tbl); + if( rv != SW_OK ) + return rv; + + arp_sg_cfg->ipv4_arp_sg_en = l3_vp_port_tbl.bf.ip_arp_sg_en; + arp_sg_cfg->ipv4_arp_sg_vio_action = l3_vp_port_tbl.bf.ip_arp_sg_vio_cmd; + arp_sg_cfg->ipv4_arp_sg_port_en = l3_vp_port_tbl.bf.ip_arp_sg_port_en; + arp_sg_cfg->ipv4_arp_sg_svlan_en = l3_vp_port_tbl.bf.ip_arp_sg_svlan_en; + arp_sg_cfg->ipv4_arp_sg_cvlan_en = l3_vp_port_tbl.bf.ip_arp_sg_cvlan_en; + arp_sg_cfg->ipv4_arp_src_unk_action = l3_vp_port_tbl.bf.ip_arp_src_unk_cmd; + arp_sg_cfg->ip_nd_sg_en = l3_vp_port_tbl.bf.ip_nd_sg_en; + arp_sg_cfg->ip_nd_sg_vio_action = l3_vp_port_tbl.bf.ip_nd_sg_vio_cmd; + arp_sg_cfg->ip_nd_sg_port_en = l3_vp_port_tbl.bf.ip_nd_sg_port_en; + arp_sg_cfg->ip_nd_sg_svlan_en = l3_vp_port_tbl.bf.ip_nd_sg_svlan_en; + arp_sg_cfg->ip_nd_sg_cvlan_en = l3_vp_port_tbl.bf.ip_nd_sg_cvlan_en; + arp_sg_cfg->ip_nd_src_unk_action = l3_vp_port_tbl.bf.ip_nd_src_unk_cmd; + + return SW_OK; +} + +sw_error_t +adpt_hppe_ip_global_ctrl_get(a_uint32_t dev_id, fal_ip_global_cfg_t *cfg) +{ + sw_error_t rv = SW_OK; + union l3_route_ctrl_u l3_route_ctrl; + union l3_route_ctrl_ext_u l3_route_ctrl_ext; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cfg); + memset(&l3_route_ctrl, 0, sizeof(l3_route_ctrl)); + memset(&l3_route_ctrl, 0, sizeof(l3_route_ctrl_ext)); + + rv = hppe_l3_route_ctrl_get(dev_id, &l3_route_ctrl); + if( rv != SW_OK ) + return rv; + + rv = hppe_l3_route_ctrl_ext_get(dev_id, &l3_route_ctrl_ext); + if( rv != SW_OK ) + return rv; + + cfg->mru_fail_action = l3_route_ctrl.bf.ip_mru_check_fail; + cfg->mru_deacclr_en = l3_route_ctrl.bf.ip_mru_check_fail_de_acce; + cfg->mtu_fail_action = l3_route_ctrl.bf.ip_mtu_fail; + cfg->mtu_deacclr_en = l3_route_ctrl.bf.ip_mtu_fail_de_acce; + cfg->mtu_nonfrag_fail_action = l3_route_ctrl.bf.ip_mtu_df_fail; + cfg->mtu_df_deacclr_en = l3_route_ctrl.bf.ip_mtu_df_fail_de_acce; + cfg->prefix_bc_action = l3_route_ctrl.bf.ip_prefix_bc_cmd; + cfg->prefix_deacclr_en = l3_route_ctrl.bf.ip_prefix_bc_de_acce; + cfg->icmp_rdt_action = l3_route_ctrl.bf.icmp_rdt_cmd; + cfg->icmp_rdt_deacclr_en = l3_route_ctrl.bf.icmp_rdt_de_acce; + cfg->hash_mode_0 = l3_route_ctrl_ext.bf.host_hash_mode_0; + cfg->hash_mode_1 = l3_route_ctrl_ext.bf.host_hash_mode_1; + + return SW_OK; +} + +sw_error_t +adpt_hppe_ip_global_ctrl_set(a_uint32_t dev_id, fal_ip_global_cfg_t *cfg) +{ + sw_error_t rv = SW_OK; + union l3_route_ctrl_u l3_route_ctrl; + union l3_route_ctrl_ext_u l3_route_ctrl_ext; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cfg); + memset(&l3_route_ctrl, 0, sizeof(l3_route_ctrl)); + memset(&l3_route_ctrl, 0, sizeof(l3_route_ctrl_ext)); + + rv = hppe_l3_route_ctrl_get(dev_id, &l3_route_ctrl); + if( rv != SW_OK ) + return rv; + + rv = hppe_l3_route_ctrl_ext_get(dev_id, &l3_route_ctrl_ext); + if( rv != SW_OK ) + return rv; + + l3_route_ctrl.bf.ip_mru_check_fail = cfg->mru_fail_action; + l3_route_ctrl.bf.ip_mru_check_fail_de_acce = cfg->mru_deacclr_en; + l3_route_ctrl.bf.ip_mtu_fail = cfg->mtu_fail_action; + l3_route_ctrl.bf.ip_mtu_fail_de_acce = cfg->mtu_deacclr_en; + l3_route_ctrl.bf.ip_mtu_df_fail = cfg->mtu_nonfrag_fail_action; + l3_route_ctrl.bf.ip_mtu_df_fail_de_acce = cfg->mtu_df_deacclr_en; + l3_route_ctrl.bf.ip_prefix_bc_cmd =cfg->prefix_bc_action; + l3_route_ctrl.bf.ip_prefix_bc_de_acce = cfg->prefix_deacclr_en; + l3_route_ctrl.bf.icmp_rdt_cmd = cfg->icmp_rdt_action; + l3_route_ctrl.bf.icmp_rdt_de_acce = cfg->icmp_rdt_deacclr_en; + l3_route_ctrl_ext.bf.host_hash_mode_0 = cfg->hash_mode_0; + l3_route_ctrl_ext.bf.host_hash_mode_1 = cfg->hash_mode_1; + + hppe_l3_route_ctrl_set(dev_id, &l3_route_ctrl); + hppe_l3_route_ctrl_ext_set(dev_id, &l3_route_ctrl_ext); + return SW_OK; +} + +sw_error_t +adpt_hppe_ip_nexthop_set(a_uint32_t dev_id, + a_uint32_t index, fal_ip_nexthop_t *entry) +{ + union in_nexthop_tbl_u in_nexthop_tbl; + + memset(&in_nexthop_tbl, 0, sizeof(in_nexthop_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(entry); + + in_nexthop_tbl.bf0.type = entry->type; + if (entry->type == 0) + in_nexthop_tbl.bf1.vsi = entry->vsi; + else + in_nexthop_tbl.bf0.port = entry->port; + in_nexthop_tbl.bf0.post_l3_if = entry->if_index; + in_nexthop_tbl.bf0.ip_to_me = entry->ip_to_me_en; + in_nexthop_tbl.bf0.ip_pub_addr_index = entry->pub_ip_index; + in_nexthop_tbl.bf0.stag_fmt = entry->stag_fmt; + in_nexthop_tbl.bf0.svid = entry->svid; + in_nexthop_tbl.bf0.ctag_fmt = entry->ctag_fmt; + in_nexthop_tbl.bf0.cvid = entry->cvid; + in_nexthop_tbl.bf0.mac_addr_0 = entry->mac_addr.uc[5] | + entry->mac_addr.uc[4] << 8; + in_nexthop_tbl.bf0.mac_addr_1 = entry->mac_addr.uc[3] | + entry->mac_addr.uc[2] << 8 | + entry->mac_addr.uc[1] << 16 | + entry->mac_addr.uc[0] << 24; + in_nexthop_tbl.bf0.ip_addr_dnat = entry->dnat_ip; + + return hppe_in_nexthop_tbl_set(dev_id, index, &in_nexthop_tbl); +} +#endif +void adpt_hppe_ip_func_bitmap_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_ip_func_bitmap[0] = 0; + p_adpt_api->adpt_ip_func_bitmap[1] = 0; + return; +} + +static void adpt_hppe_ip_func_unregister(a_uint32_t dev_id, adpt_api_t *p_adpt_api) +{ + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_ip_network_route_get = NULL; + p_adpt_api->adpt_ip_host_add = NULL; + p_adpt_api->adpt_ip_vsi_sg_cfg_get = NULL; + p_adpt_api->adpt_ip_pub_addr_set = NULL; + p_adpt_api->adpt_ip_port_sg_cfg_set = NULL; + p_adpt_api->adpt_ip_port_intf_get = NULL; + p_adpt_api->adpt_ip_vsi_arp_sg_cfg_set = NULL; + p_adpt_api->adpt_ip_pub_addr_get = NULL; + p_adpt_api->adpt_ip_port_intf_set = NULL; + p_adpt_api->adpt_ip_vsi_sg_cfg_set = NULL; + p_adpt_api->adpt_ip_host_next = NULL; + p_adpt_api->adpt_ip_port_macaddr_set = NULL; + p_adpt_api->adpt_ip_vsi_intf_get = NULL; + p_adpt_api->adpt_ip_network_route_add = NULL; + p_adpt_api->adpt_ip_port_sg_cfg_get = NULL; + p_adpt_api->adpt_ip_intf_get = NULL; + p_adpt_api->adpt_ip_network_route_del = NULL; + p_adpt_api->adpt_ip_host_del = NULL; + p_adpt_api->adpt_ip_route_mismatch_get = NULL; + p_adpt_api->adpt_ip_vsi_arp_sg_cfg_get = NULL; + p_adpt_api->adpt_ip_port_arp_sg_cfg_set = NULL; + p_adpt_api->adpt_ip_vsi_mc_mode_set = NULL; + p_adpt_api->adpt_ip_vsi_intf_set = NULL; + p_adpt_api->adpt_ip_nexthop_get = NULL; + p_adpt_api->adpt_ip_route_mismatch_set = NULL; + p_adpt_api->adpt_ip_host_get = NULL; + p_adpt_api->adpt_ip_intf_set = NULL; + p_adpt_api->adpt_ip_vsi_mc_mode_get = NULL; + p_adpt_api->adpt_ip_port_macaddr_get = NULL; + p_adpt_api->adpt_ip_port_arp_sg_cfg_get = NULL; + p_adpt_api->adpt_ip_nexthop_set = NULL; + p_adpt_api->adpt_ip_global_ctrl_get = NULL; + p_adpt_api->adpt_ip_global_ctrl_set = NULL; + + return; +} +sw_error_t adpt_hppe_ip_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return SW_FAIL; + + adpt_hppe_ip_func_unregister(dev_id, p_adpt_api); +#ifndef IN_IP_MINI + if (p_adpt_api->adpt_ip_func_bitmap[0] & (1 << FUNC_IP_NETWORK_ROUTE_GET)) + p_adpt_api->adpt_ip_network_route_get = adpt_hppe_ip_network_route_get; + if (p_adpt_api->adpt_ip_func_bitmap[0] & (1 << FUNC_IP_HOST_ADD)) + p_adpt_api->adpt_ip_host_add = adpt_hppe_ip_host_add; + if (p_adpt_api->adpt_ip_func_bitmap[0] & (1 << FUNC_IP_VSI_SG_CFG_GET)) + p_adpt_api->adpt_ip_vsi_sg_cfg_get = adpt_hppe_ip_vsi_sg_cfg_get; + if (p_adpt_api->adpt_ip_func_bitmap[0] & (1 << FUNC_IP_PUB_ADDR_SET)) + p_adpt_api->adpt_ip_pub_addr_set = adpt_hppe_ip_pub_addr_set; + if (p_adpt_api->adpt_ip_func_bitmap[0] & (1 << FUNC_IP_PORT_SG_CFG_SET)) + p_adpt_api->adpt_ip_port_sg_cfg_set = adpt_hppe_ip_port_sg_cfg_set; + if (p_adpt_api->adpt_ip_func_bitmap[0] & (1 << FUNC_IP_PORT_INTF_GET)) + p_adpt_api->adpt_ip_port_intf_get = adpt_hppe_ip_port_intf_get; + if (p_adpt_api->adpt_ip_func_bitmap[0] & (1 << FUNC_IP_VSI_ARP_SG_CFG_SET)) + p_adpt_api->adpt_ip_vsi_arp_sg_cfg_set = adpt_hppe_ip_vsi_arp_sg_cfg_set; + if (p_adpt_api->adpt_ip_func_bitmap[0] & (1 << FUNC_IP_PUB_ADDR_GET)) + p_adpt_api->adpt_ip_pub_addr_get = adpt_hppe_ip_pub_addr_get; + if (p_adpt_api->adpt_ip_func_bitmap[0] & (1 << FUNC_IP_PORT_INTF_SET)) + p_adpt_api->adpt_ip_port_intf_set = adpt_hppe_ip_port_intf_set; + if (p_adpt_api->adpt_ip_func_bitmap[0] & (1 << FUNC_IP_VSI_SG_CFG_SET)) + p_adpt_api->adpt_ip_vsi_sg_cfg_set = adpt_hppe_ip_vsi_sg_cfg_set; + if (p_adpt_api->adpt_ip_func_bitmap[0] & (1 << FUNC_IP_HOST_NEXT)) + p_adpt_api->adpt_ip_host_next = adpt_hppe_ip_host_next; + if (p_adpt_api->adpt_ip_func_bitmap[0] & (1 << FUNC_IP_PORT_MACADDR_SET)) + p_adpt_api->adpt_ip_port_macaddr_set = adpt_hppe_ip_port_macaddr_set; + if (p_adpt_api->adpt_ip_func_bitmap[0] & (1 << FUNC_IP_VSI_INTF_GET)) + p_adpt_api->adpt_ip_vsi_intf_get = adpt_hppe_ip_vsi_intf_get; + if (p_adpt_api->adpt_ip_func_bitmap[0] & (1 << FUNC_IP_NETWORK_ROUTE_ADD)) + p_adpt_api->adpt_ip_network_route_add = adpt_hppe_ip_network_route_add; + if (p_adpt_api->adpt_ip_func_bitmap[0] & (1 << FUNC_IP_PORT_SG_CFG_GET)) + p_adpt_api->adpt_ip_port_sg_cfg_get = adpt_hppe_ip_port_sg_cfg_get; + if (p_adpt_api->adpt_ip_func_bitmap[0] & (1 << FUNC_IP_INTF_GET)) + p_adpt_api->adpt_ip_intf_get = adpt_hppe_ip_intf_get; + if (p_adpt_api->adpt_ip_func_bitmap[0] & (1 << FUNC_IP_NETWORK_ROUTE_DEL)) + p_adpt_api->adpt_ip_network_route_del = adpt_hppe_ip_network_route_del; + if (p_adpt_api->adpt_ip_func_bitmap[0] & (1 << FUNC_IP_HOST_DEL)) + p_adpt_api->adpt_ip_host_del = adpt_hppe_ip_host_del; + if (p_adpt_api->adpt_ip_func_bitmap[0] & (1 << FUNC_IP_ROUTE_MISMATCH_GET)) + p_adpt_api->adpt_ip_route_mismatch_get = adpt_hppe_ip_route_mismatch_get; + if (p_adpt_api->adpt_ip_func_bitmap[0] & (1 << FUNC_IP_VSI_ARP_SG_CFG_GET)) + p_adpt_api->adpt_ip_vsi_arp_sg_cfg_get = adpt_hppe_ip_vsi_arp_sg_cfg_get; + if (p_adpt_api->adpt_ip_func_bitmap[0] & (1 << FUNC_IP_PORT_ARP_SG_CFG_SET)) + p_adpt_api->adpt_ip_port_arp_sg_cfg_set = adpt_hppe_ip_port_arp_sg_cfg_set; + if (p_adpt_api->adpt_ip_func_bitmap[0] & (1 << FUNC_IP_VSI_MC_MODE_SET)) + p_adpt_api->adpt_ip_vsi_mc_mode_set = adpt_hppe_ip_vsi_mc_mode_set; + if (p_adpt_api->adpt_ip_func_bitmap[0] & (1 << FUNC_IP_VSI_INTF_SET)) + p_adpt_api->adpt_ip_vsi_intf_set = adpt_hppe_ip_vsi_intf_set; + if (p_adpt_api->adpt_ip_func_bitmap[0] & (1 << FUNC_IP_NEXTHOP_GET)) + p_adpt_api->adpt_ip_nexthop_get = adpt_hppe_ip_nexthop_get; + if (p_adpt_api->adpt_ip_func_bitmap[0] & (1 << FUNC_IP_ROUTE_MISMATCH_SET)) + p_adpt_api->adpt_ip_route_mismatch_set = adpt_hppe_ip_route_mismatch_set; + if (p_adpt_api->adpt_ip_func_bitmap[0] & (1 << FUNC_IP_HOST_GET)) + p_adpt_api->adpt_ip_host_get = adpt_hppe_ip_host_get; + if (p_adpt_api->adpt_ip_func_bitmap[0] & (1 << FUNC_IP_INTF_SET)) + p_adpt_api->adpt_ip_intf_set = adpt_hppe_ip_intf_set; + if (p_adpt_api->adpt_ip_func_bitmap[0] & (1 << FUNC_IP_VSI_MC_MODE_GET)) + p_adpt_api->adpt_ip_vsi_mc_mode_get = adpt_hppe_ip_vsi_mc_mode_get; + if (p_adpt_api->adpt_ip_func_bitmap[0] & (1 << FUNC_IP_PORT_MACADDR_GET)) + p_adpt_api->adpt_ip_port_macaddr_get = adpt_hppe_ip_port_macaddr_get; + if (p_adpt_api->adpt_ip_func_bitmap[0] & (1 << FUNC_IP_PORT_ARP_SG_CFG_GET)) + p_adpt_api->adpt_ip_port_arp_sg_cfg_get = adpt_hppe_ip_port_arp_sg_cfg_get; + if (p_adpt_api->adpt_ip_func_bitmap[0] & (1 << FUNC_IP_NEXTHOP_SET)) + p_adpt_api->adpt_ip_nexthop_set = adpt_hppe_ip_nexthop_set; + if (p_adpt_api->adpt_ip_func_bitmap[0] & (1 << FUNC_IP_GLOBAL_CTRL_GET)) + p_adpt_api->adpt_ip_global_ctrl_get = adpt_hppe_ip_global_ctrl_get; + if (p_adpt_api->adpt_ip_func_bitmap[1] & (1 << (FUNC_IP_GLOBAL_CTRL_SET % 32))) + p_adpt_api->adpt_ip_global_ctrl_set = adpt_hppe_ip_global_ctrl_set; +#endif + return SW_OK; +} +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_mib.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_mib.c new file mode 100755 index 000000000..523707213 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_mib.c @@ -0,0 +1,1019 @@ +/* + * 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. + */ + + +/** + * @defgroup + * @{ + */ +#include "sw.h" +#include "hppe_mib_reg.h" +#include "hppe_mib.h" +#include "adpt.h" +#include "hppe_xgmacmib_reg.h" +#include "hppe_xgmacmib.h" + +#include "hppe_init.h" +#include "adpt_hppe.h" +#ifdef CPPE +#include "adpt_cppe_mib.h" +#endif + +sw_error_t +adpt_hppe_mib_cpukeep_get(a_uint32_t dev_id, a_bool_t *enable) +{ + sw_error_t rv = SW_OK; + a_uint32_t port_id = 0, status = 0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + + rv = hppe_mac_mib_ctrl_mib_rd_clr_get(dev_id, port_id, &status); + + if (status == A_TRUE) + { + *enable = A_FALSE; + } + else + { + *enable = A_TRUE; + } + + if( rv != SW_OK ) + { + return rv; + } + + return SW_OK; +} + +sw_error_t +adpt_ppe_mib_cpukeep_set(a_uint32_t dev_id, a_bool_t enable) +{ + a_uint32_t port_id = 0, g_port_id = 0; + sw_error_t rv = SW_OK; + + ADPT_DEV_ID_CHECK(dev_id); + + for (port_id = SSDK_PHYSICAL_PORT1; port_id <= SSDK_PHYSICAL_PORT6; port_id++) + { +#ifdef CPPE + if (adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION && + port_id == SSDK_PHYSICAL_PORT6) + { + rv = adpt_cppe_lpbk_mib_cpukeep_set(dev_id, port_id, enable); + SW_RTN_ON_ERROR(rv); + continue; + } +#endif + g_port_id = HPPE_TO_GMAC_PORT_ID(port_id); + hppe_mac_mib_ctrl_mib_rd_clr_set(dev_id, g_port_id, (a_uint32_t)(!enable)); + } + + return rv; +} + +static sw_error_t +adpt_hppe_get_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info ) +{ + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(mib_info); + memset(mib_info, 0, sizeof(fal_mib_info_t)); + + port_id = HPPE_TO_GMAC_PORT_ID(port_id); + hppe_rxbroad_get(dev_id, (a_uint32_t)port_id, (union rxbroad_u *)&mib_info->RxBroad); + hppe_rxpause_get(dev_id, (a_uint32_t)port_id, (union rxpause_u *)&mib_info->RxPause); + hppe_rxmulti_get(dev_id, (a_uint32_t)port_id, (union rxmulti_u *)&mib_info->RxMulti); + hppe_rxfcserr_get(dev_id, (a_uint32_t)port_id, (union rxfcserr_u *)&mib_info->RxFcsErr); + hppe_rxalignerr_get(dev_id, (a_uint32_t)port_id, + (union rxalignerr_u *)&mib_info->RxAllignErr); + hppe_rxrunt_get(dev_id, (a_uint32_t)port_id, (union rxrunt_u *)&mib_info->RxRunt); + hppe_rxfrag_get(dev_id, (a_uint32_t)port_id, (union rxfrag_u *)&mib_info->RxFragment); + hppe_rxjumbofcserr_get(dev_id, (a_uint32_t)port_id, + (union rxjumbofcserr_u *)&mib_info->RxJumboFcsErr); + hppe_rxjumboalignerr_get(dev_id, (a_uint32_t)port_id, + (union rxjumboalignerr_u *)&mib_info->RxJumboAligenErr); + hppe_rxpkt64_get(dev_id, (a_uint32_t)port_id, (union rxpkt64_u *)&mib_info->Rx64Byte); + hppe_rxpkt65to127_get(dev_id, (a_uint32_t)port_id, + (union rxpkt65to127_u *)&mib_info->Rx128Byte); + hppe_rxpkt128to255_get(dev_id, (a_uint32_t)port_id, + (union rxpkt128to255_u *)&mib_info->Rx256Byte); + hppe_rxpkt256to511_get(dev_id, (a_uint32_t)port_id, + (union rxpkt256to511_u *)&mib_info->Rx512Byte); + hppe_rxpkt512to1023_get(dev_id, (a_uint32_t)port_id, + (union rxpkt512to1023_u *)&mib_info->Rx1024Byte); + hppe_rxpkt1024to1518_get(dev_id, (a_uint32_t)port_id, + (union rxpkt1024to1518_u *)&mib_info->Rx1518Byte); + hppe_rxpkt1519tox_get(dev_id, (a_uint32_t)port_id, + (union rxpkt1519tox_u *)&mib_info->RxMaxByte); + hppe_rxtoolong_get(dev_id, (a_uint32_t)port_id, + (union rxtoolong_u *)&mib_info->RxTooLong); + hppe_rxgoodbyte_l_get(dev_id, (a_uint32_t)port_id, + (union rxgoodbyte_l_u *)&mib_info->RxGoodByte_lo); + hppe_rxgoodbyte_h_get(dev_id, (a_uint32_t)port_id, + (union rxgoodbyte_h_u *)&mib_info->RxGoodByte_hi); + hppe_rxbadbyte_l_get(dev_id, (a_uint32_t)port_id, + (union rxbadbyte_l_u *)&mib_info->RxBadByte_lo); + hppe_rxbadbyte_h_get(dev_id, (a_uint32_t)port_id, + (union rxbadbyte_h_u *)&mib_info->RxBadByte_hi); + hppe_rxuni_get(dev_id, (a_uint32_t)port_id, (union rxuni_u *)&mib_info->RxUniCast); + hppe_txbroad_get(dev_id, (a_uint32_t)port_id, (union txbroad_u *)&mib_info->TxBroad); + hppe_txpause_get(dev_id, (a_uint32_t)port_id, (union txpause_u *)&mib_info->TxPause); + hppe_txmulti_get(dev_id, (a_uint32_t)port_id, (union txmulti_u *)&mib_info->TxMulti); + hppe_txunderrun_get(dev_id, (a_uint32_t)port_id, + (union txunderrun_u *)&mib_info->TxUnderRun); + hppe_txpkt64_get(dev_id, (a_uint32_t)port_id, (union txpkt64_u *)&mib_info->Tx64Byte); + hppe_txpkt65to127_get(dev_id, (a_uint32_t)port_id, + (union txpkt65to127_u *)&mib_info->Tx128Byte); + hppe_txpkt128to255_get(dev_id, (a_uint32_t)port_id, + (union txpkt128to255_u *)&mib_info->Tx256Byte); + hppe_txpkt256to511_get(dev_id, (a_uint32_t)port_id, + (union txpkt256to511_u *)&mib_info->Tx512Byte); + hppe_txpkt512to1023_get(dev_id, (a_uint32_t)port_id, + (union txpkt512to1023_u *)&mib_info->Tx1024Byte); + hppe_txpkt1024to1518_get(dev_id, (a_uint32_t)port_id, + (union txpkt1024to1518_u *)&mib_info->Tx1518Byte); + hppe_txpkt1519tox_get(dev_id, (a_uint32_t)port_id, + (union txpkt1519tox_u *)&mib_info->TxMaxByte); + hppe_txbyte_l_get(dev_id, (a_uint32_t)port_id, + (union txbyte_l_u *)&mib_info->TxByte_lo); + hppe_txbyte_h_get(dev_id, (a_uint32_t)port_id, + (union txbyte_h_u *)&mib_info->TxByte_hi); + hppe_txcollisions_get(dev_id, (a_uint32_t)port_id, + (union txcollisions_u *)&mib_info->TxCollision); + hppe_txabortcol_get(dev_id, (a_uint32_t)port_id, + (union txabortcol_u *)&mib_info->TxAbortCol); + hppe_txmulticol_get(dev_id, (a_uint32_t)port_id, + (union txmulticol_u *)&mib_info->TxMultiCol); + hppe_txsinglecol_get(dev_id, (a_uint32_t)port_id, + (union txsinglecol_u *)&mib_info->TxSingalCol); + hppe_txexcessivedefer_get(dev_id, (a_uint32_t)port_id, + (union txexcessivedefer_u *)&mib_info->TxExcDefer); + hppe_txdefer_get(dev_id, (a_uint32_t)port_id, (union txdefer_u *)&mib_info->TxDefer); + hppe_txlatecol_get(dev_id, (a_uint32_t)port_id, (union txlatecol_u *)&mib_info->TxLateCol); + hppe_txuni_get(dev_id, (a_uint32_t)port_id, (union txuni_u *)&mib_info->TxUniCast); + + return SW_OK; +} + +sw_error_t +adpt_ppe_get_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info) +{ + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(mib_info); +#ifdef CPPE + if (adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION && + port_id == SSDK_PHYSICAL_PORT6) + { + return adpt_cppe_lpbk_get_mib_info(dev_id, port_id, mib_info); + } +#endif + return adpt_hppe_get_mib_info(dev_id, port_id, mib_info); +} + +sw_error_t +adpt_hppe_get_tx_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info ) +{ + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(mib_info); + memset(mib_info, 0, sizeof(fal_mib_info_t)); + + port_id = HPPE_TO_GMAC_PORT_ID(port_id); + hppe_txbroad_get(dev_id, (a_uint32_t)port_id, (union txbroad_u *)&mib_info->TxBroad); + hppe_txpause_get(dev_id, (a_uint32_t)port_id, (union txpause_u *)&mib_info->TxPause); + hppe_txmulti_get(dev_id, (a_uint32_t)port_id, (union txmulti_u *)&mib_info->TxMulti); + hppe_txunderrun_get(dev_id, (a_uint32_t)port_id, + (union txunderrun_u *)&mib_info->TxUnderRun); + hppe_txpkt64_get(dev_id, (a_uint32_t)port_id, (union txpkt64_u *)&mib_info->Tx64Byte); + hppe_txpkt65to127_get(dev_id, (a_uint32_t)port_id, + (union txpkt65to127_u *)&mib_info->Tx128Byte); + hppe_txpkt128to255_get(dev_id, (a_uint32_t)port_id, + (union txpkt128to255_u *)&mib_info->Tx256Byte); + hppe_txpkt256to511_get(dev_id, (a_uint32_t)port_id, + (union txpkt256to511_u *)&mib_info->Tx512Byte); + hppe_txpkt512to1023_get(dev_id, (a_uint32_t)port_id, + (union txpkt512to1023_u *)&mib_info->Tx1024Byte); + hppe_txpkt1024to1518_get(dev_id, (a_uint32_t)port_id, + (union txpkt1024to1518_u *)&mib_info->Tx1518Byte); + hppe_txpkt1519tox_get(dev_id, (a_uint32_t)port_id, + (union txpkt1519tox_u *)&mib_info->TxMaxByte); + hppe_txbyte_l_get(dev_id, (a_uint32_t)port_id, (union txbyte_l_u *)&mib_info->TxByte_lo); + hppe_txbyte_h_get(dev_id, (a_uint32_t)port_id, (union txbyte_h_u *)&mib_info->TxByte_hi); + hppe_txcollisions_get(dev_id, (a_uint32_t)port_id, + (union txcollisions_u *)&mib_info->TxCollision); + hppe_txabortcol_get(dev_id, (a_uint32_t)port_id, + (union txabortcol_u *)&mib_info->TxAbortCol); + hppe_txmulticol_get(dev_id, (a_uint32_t)port_id, + (union txmulticol_u *)&mib_info->TxMultiCol); + hppe_txsinglecol_get(dev_id, (a_uint32_t)port_id, + (union txsinglecol_u *)&mib_info->TxSingalCol); + hppe_txexcessivedefer_get(dev_id, (a_uint32_t)port_id, + (union txexcessivedefer_u *)&mib_info->TxExcDefer); + hppe_txdefer_get(dev_id, (a_uint32_t)port_id, (union txdefer_u *)&mib_info->TxDefer); + hppe_txlatecol_get(dev_id, (a_uint32_t)port_id, + (union txlatecol_u *)&mib_info->TxLateCol); + hppe_txuni_get(dev_id, (a_uint32_t)port_id, (union txuni_u *)&mib_info->TxUniCast); + + return SW_OK; +} + +sw_error_t +adpt_ppe_mib_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + a_uint32_t port_id = 0, xg_port_id = 0, g_port_id = 0; + a_uint32_t port_num = SSDK_PHYSICAL_PORT6; + union mmc_control_u mmc_control; + sw_error_t rv = SW_OK; + + memset(&mmc_control, 0, sizeof(mmc_control)); + ADPT_DEV_ID_CHECK(dev_id); +#ifdef CPPE + if (adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) + { + port_num = SSDK_PHYSICAL_PORT5; + rv = adpt_cppe_lpbk_mib_status_set(dev_id, SSDK_PHYSICAL_PORT6, enable); + SW_RTN_ON_ERROR(rv); + } +#endif + for (port_id = SSDK_PHYSICAL_PORT1; port_id <= port_num; port_id++) { + g_port_id = HPPE_TO_GMAC_PORT_ID(port_id); + hppe_mac_mib_ctrl_mib_en_set(dev_id, g_port_id, (a_uint32_t)enable); + } + + for (port_id = SSDK_PHYSICAL_PORT5; port_id <= port_num; port_id++) { + xg_port_id = HPPE_TO_XGMAC_PORT_ID(port_id); + hppe_mmc_control_get(dev_id, xg_port_id, &mmc_control); + + if(A_TRUE == enable) + mmc_control.bf.mcf = 0; + else + mmc_control.bf.mcf = 1; + + hppe_mmc_control_set(dev_id, xg_port_id, &mmc_control); + } + + return rv; +} + +sw_error_t +adpt_hppe_mib_port_flush_counters(a_uint32_t dev_id, fal_port_t port_id) +{ + union mmc_control_u mmc_control; + + memset(&mmc_control, 0, sizeof(mmc_control)); + ADPT_DEV_ID_CHECK(dev_id); + + if(port_id < SSDK_PHYSICAL_PORT1 || port_id > SSDK_PHYSICAL_PORT6) + return SW_BAD_PARAM; + /*GMAC*/ + if(!hppe_xgmac_port_check(port_id)) + { + port_id = HPPE_TO_GMAC_PORT_ID(port_id); + hppe_mac_mib_ctrl_mib_reset_set(dev_id, port_id, A_TRUE); + hppe_mac_mib_ctrl_mib_reset_set(dev_id, port_id, A_FALSE); + } + /*XGMAC*/ + else + { + port_id = HPPE_TO_XGMAC_PORT_ID(port_id); + hppe_mmc_control_get(dev_id, port_id, &mmc_control); + mmc_control.bf.cntrst = 1; + hppe_mmc_control_set(dev_id, port_id, &mmc_control); + } + + return SW_OK; +} + +sw_error_t +adpt_ppe_mib_port_flush_counters(a_uint32_t dev_id, fal_port_t port_id) +{ +#ifdef CPPE + if (adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION && + port_id == SSDK_PHYSICAL_PORT6) + { + return adpt_cppe_lpbk_mib_flush_counters(dev_id, port_id); + } +#endif + return adpt_hppe_mib_port_flush_counters(dev_id, port_id); +} + +sw_error_t +adpt_hppe_mib_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv = SW_OK; + a_uint32_t port_id = 0, status = 0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + + rv = hppe_mac_mib_ctrl_mib_en_get(dev_id, port_id, &status); + *enable = status; + + if( rv != SW_OK ) + return rv; + + return SW_OK; +} + +sw_error_t +adpt_hppe_get_rx_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info ) +{ + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(mib_info); + memset(mib_info, 0, sizeof(fal_mib_info_t)); + + port_id = HPPE_TO_GMAC_PORT_ID(port_id); + hppe_rxbroad_get(dev_id, (a_uint32_t)port_id, (union rxbroad_u *)&mib_info->RxBroad); + hppe_rxpause_get(dev_id, (a_uint32_t)port_id, (union rxpause_u *)&mib_info->RxPause); + hppe_rxmulti_get(dev_id, (a_uint32_t)port_id, (union rxmulti_u *)&mib_info->RxMulti); + hppe_rxfcserr_get(dev_id, (a_uint32_t)port_id, (union rxfcserr_u *)&mib_info->RxFcsErr); + hppe_rxalignerr_get(dev_id, (a_uint32_t)port_id, + (union rxalignerr_u *)&mib_info->RxAllignErr); + hppe_rxrunt_get(dev_id, (a_uint32_t)port_id, (union rxrunt_u *)&mib_info->RxRunt); + hppe_rxfrag_get(dev_id, (a_uint32_t)port_id, (union rxfrag_u *)&mib_info->RxFragment); + hppe_rxjumbofcserr_get(dev_id, (a_uint32_t)port_id, + (union rxjumbofcserr_u *)&mib_info->RxJumboFcsErr); + hppe_rxjumboalignerr_get(dev_id, (a_uint32_t)port_id, + (union rxjumboalignerr_u *)&mib_info->RxJumboAligenErr); + hppe_rxpkt64_get(dev_id, (a_uint32_t)port_id, (union rxpkt64_u *)&mib_info->Rx64Byte); + hppe_rxpkt65to127_get(dev_id, (a_uint32_t)port_id, + (union rxpkt65to127_u *)&mib_info->Rx128Byte); + hppe_rxpkt128to255_get(dev_id, (a_uint32_t)port_id, + (union rxpkt128to255_u *)&mib_info->Rx256Byte); + hppe_rxpkt256to511_get(dev_id, (a_uint32_t)port_id, + (union rxpkt256to511_u *)&mib_info->Rx512Byte); + hppe_rxpkt512to1023_get(dev_id, (a_uint32_t)port_id, + (union rxpkt512to1023_u *)&mib_info->Rx1024Byte); + hppe_rxpkt1024to1518_get(dev_id, (a_uint32_t)port_id, + (union rxpkt1024to1518_u *)&mib_info->Rx1518Byte); + hppe_rxpkt1519tox_get(dev_id, (a_uint32_t)port_id, + (union rxpkt1519tox_u *)&mib_info->RxMaxByte); + hppe_rxtoolong_get(dev_id, (a_uint32_t)port_id, + (union rxtoolong_u *)&mib_info->RxTooLong); + hppe_rxgoodbyte_l_get(dev_id, (a_uint32_t)port_id, + (union rxgoodbyte_l_u *)&mib_info->RxGoodByte_lo); + hppe_rxgoodbyte_h_get(dev_id, (a_uint32_t)port_id, + (union rxgoodbyte_h_u *)&mib_info->RxGoodByte_hi); + hppe_rxbadbyte_l_get(dev_id, (a_uint32_t)port_id, + (union rxbadbyte_l_u *)&mib_info->RxBadByte_lo); + hppe_rxbadbyte_h_get(dev_id, (a_uint32_t)port_id, + (union rxbadbyte_h_u *)&mib_info->RxBadByte_hi); + hppe_rxuni_get(dev_id, (a_uint32_t)port_id, (union rxuni_u *)&mib_info->RxUniCast); + + return SW_OK; +} + +sw_error_t +adpt_ppe_get_rx_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info) +{ + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(mib_info); +#ifdef CPPE + if (adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION && + port_id == SSDK_PHYSICAL_PORT6) + { + return adpt_cppe_lpbk_get_mib_info(dev_id, port_id, mib_info); + } +#endif + return adpt_hppe_get_rx_mib_info(dev_id, port_id, mib_info); +} + +void adpt_hppe_mib_func_bitmap_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_mib_func_bitmap = ((1<adpt_get_mib_info = NULL; + p_adpt_api->adpt_get_rx_mib_info = NULL; + p_adpt_api->adpt_get_tx_mib_info = NULL; + p_adpt_api->adpt_mib_status_set = NULL; + p_adpt_api->adpt_mib_status_get = NULL; + p_adpt_api->adpt_mib_port_flush_counters = NULL; + p_adpt_api->adpt_mib_cpukeep_set = NULL; + p_adpt_api->adpt_mib_cpukeep_get = NULL; + p_adpt_api->adpt_get_xgmib_info = NULL; + p_adpt_api->adpt_get_tx_xgmib_info = NULL; + p_adpt_api->adpt_get_rx_xgmib_info = NULL; + + return; +} + +sw_error_t +adpt_hppe_get_xgmib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_xgmib_info_t * mib_info ) +{ + a_uint64_t data_low , data_high ; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(mib_info); + memset(mib_info, 0, sizeof( * mib_info )); + + if(!(hppe_xgmac_port_check(port_id))) + { + printk("this port is not xg port!\n"); + return SW_FAIL; + } + port_id = HPPE_TO_XGMAC_PORT_ID(port_id); + + /*get tx xgmib information*/ + data_low = 0; data_high = 0; + hppe_tx_octet_count_good_bad_low_get(dev_id, port_id, (union tx_octet_count_good_bad_low_u*)&data_low); + hppe_tx_octet_count_good_bad_high_get(dev_id, port_id, (union tx_octet_count_good_bad_high_u *)&data_high); + mib_info->TxByte = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_tx_frame_count_good_bad_low_get(dev_id, port_id, (union tx_frame_count_good_bad_low_u *)&data_low); + hppe_tx_frame_count_good_bad_high_get(dev_id, port_id, (union tx_frame_count_good_bad_high_u *)&data_high); + mib_info->TxFrame = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_tx_broadcast_frames_good_low_get(dev_id, port_id, (union tx_broadcast_frames_good_low_u *)&data_low); + hppe_tx_broadcast_frames_good_high_get(dev_id, port_id, (union tx_broadcast_frames_good_high_u*)&data_high); + mib_info->TxBroadGood = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_tx_multicast_frames_good_low_get(dev_id, port_id, (union tx_multicast_frames_good_low_u*)&data_low); + hppe_tx_multicast_frames_good_high_get(dev_id, port_id, (union tx_multicast_frames_good_high_u*)&data_high); + mib_info->TxMultiGood = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_tx_64octets_frames_good_bad_low_get(dev_id, port_id, (union tx_64octets_frames_good_bad_low_u*)&data_low); + hppe_tx_64octets_frames_good_bad_high_get(dev_id, port_id, (union tx_64octets_frames_good_bad_high_u*)&data_high); + mib_info->Tx64Byte = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_tx_65to127octets_frames_good_bad_low_get(dev_id, port_id, (union tx_65to127octets_frames_good_bad_low_u *)&data_low); + hppe_tx_65to127octets_frames_good_bad_high_get(dev_id, port_id, (union tx_65to127octets_frames_good_bad_high_u *)&data_high); + mib_info->Tx128Byte = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_tx_128to255octets_frames_good_bad_low_get(dev_id, port_id, (union tx_128to255octets_frames_good_bad_low_u *)&data_low); + hppe_tx_128to255octets_frames_good_bad_high_get(dev_id, port_id, (union tx_128to255octets_frames_good_bad_high_u *)&data_high); + mib_info->Tx256Byte = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_tx_256to511octets_frames_good_bad_low_get(dev_id, port_id, (union tx_256to511octets_frames_good_bad_low_u *)&data_low); + hppe_tx_256to511octets_frames_good_bad_high_get(dev_id, port_id, (union tx_256to511octets_frames_good_bad_high_u *)&data_high); + mib_info->Tx512Byte = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_tx_512to1023octets_frames_good_bad_low_get(dev_id, port_id, (union tx_512to1023octets_frames_good_bad_low_u*)&data_low); + hppe_tx_512to1023octets_frames_good_bad_high_get(dev_id, port_id, (union tx_512to1023octets_frames_good_bad_high_u*)&data_high); + mib_info->Tx1024Byte = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_tx_1024tomaxoctets_frames_good_bad_low_get(dev_id, port_id, (union tx_1024tomaxoctets_frames_good_bad_low_u*)&data_low); + hppe_tx_1024tomaxoctets_frames_good_bad_high_get(dev_id, port_id, (union tx_1024tomaxoctets_frames_good_bad_high_u*)&data_high); + mib_info->TxMaxByte = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_tx_unicast_frames_good_bad_low_get(dev_id, port_id, (union tx_unicast_frames_good_bad_low_u*)&data_low); + hppe_tx_unicast_frames_good_bad_high_get(dev_id, port_id, (union tx_unicast_frames_good_bad_high_u*)&data_high); + mib_info->TxUnicast = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_tx_multicast_frames_good_bad_low_get(dev_id, port_id, (union tx_multicast_frames_good_bad_low_u *)&data_low); + hppe_tx_multicast_frames_good_bad_high_get(dev_id, port_id, (union tx_multicast_frames_good_bad_high_u *)&data_high); + mib_info->TxMulti = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_tx_broadcast_frames_good_bad_low_get(dev_id, port_id, (union tx_broadcast_frames_good_bad_low_u*)&data_low); + hppe_tx_broadcast_frames_good_bad_high_get(dev_id, port_id, (union tx_broadcast_frames_good_bad_high_u*)&data_high); + mib_info->TxBroad = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_tx_underflow_error_frames_low_get(dev_id, port_id, (union tx_underflow_error_frames_low_u*)&data_low); + hppe_tx_underflow_error_frames_high_get(dev_id, port_id, (union tx_underflow_error_frames_high_u*)&data_high); + mib_info->TxUnderFlowError = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_tx_octet_count_good_low_get(dev_id, port_id, (union tx_octet_count_good_low_u*)&data_low); + hppe_tx_octet_count_good_high_get(dev_id, port_id, (union tx_octet_count_good_high_u*)&data_high); + mib_info->TxByteGood = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_tx_frame_count_good_low_get(dev_id, port_id, (union tx_frame_count_good_low_u*)&data_low); + hppe_tx_frame_count_good_high_get(dev_id, port_id, (union tx_frame_count_good_high_u*)&data_high); + mib_info->TxFrameGood = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_tx_pause_frames_low_get(dev_id, port_id, (union tx_pause_frames_low_u *)&data_low); + hppe_tx_pause_frames_high_get(dev_id, port_id, (union tx_pause_frames_high_u *)&data_high); + mib_info->TxPause = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_tx_vlan_frames_good_low_get(dev_id, port_id, (union tx_vlan_frames_good_low_u *)&data_low); + hppe_tx_vlan_frames_good_high_get(dev_id, port_id, (union tx_vlan_frames_good_high_u *)&data_high); + mib_info->TxVLANFrameGood = (data_high<<32) |data_low; + + data_low = 0; + hppe_tx_lpi_usec_cntr_get(dev_id, port_id, (union tx_lpi_usec_cntr_u *)&data_low); + mib_info->TxLPIUsec = data_low; + + data_low = 0; + hppe_tx_lpi_tran_cntr_get(dev_id, port_id, (union tx_lpi_tran_cntr_u *)&data_low); + mib_info->TxLPITran = data_low; + + /*get rx xgmib information*/ + data_low = 0; data_high = 0; + hppe_rx_frame_count_good_bad_low_get(dev_id, port_id, (union rx_frame_count_good_bad_low_u *)&data_low); + hppe_rx_frame_count_good_bad_high_get(dev_id, port_id, (union rx_frame_count_good_bad_high_u *)&data_high); + mib_info->RxFrame = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_rx_octet_count_good_bad_low_get(dev_id, port_id, (union rx_octet_count_good_bad_low_u*)&data_low); + hppe_rx_octet_count_good_bad_high_get(dev_id, port_id, (union rx_octet_count_good_bad_high_u*)&data_high); + mib_info->RxByte = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_rx_octet_count_good_low_get(dev_id, port_id, (union rx_octet_count_good_low_u *)&data_low); + hppe_rx_octet_count_good_high_get(dev_id, port_id, (union rx_octet_count_good_high_u *)&data_high); + mib_info->RxByteGood = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_rx_broadcast_frames_good_low_get(dev_id, port_id, (union rx_broadcast_frames_good_low_u *)&data_low); + hppe_rx_broadcast_frames_good_high_get(dev_id, port_id, (union rx_broadcast_frames_good_high_u*)&data_high); + mib_info->RxBroadGood = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_rx_multicast_frames_good_low_get(dev_id, port_id, (union rx_multicast_frames_good_low_u*)&data_low); + hppe_rx_multicast_frames_good_high_get(dev_id, port_id, (union rx_multicast_frames_good_high_u*)&data_high); + mib_info->RxMultiGood = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_rx_crc_error_frames_low_get(dev_id, port_id, (union rx_crc_error_frames_low_u *)&data_low); + hppe_rx_crc_error_frames_high_get(dev_id, port_id, (union rx_crc_error_frames_high_u *)&data_high); + mib_info->RxFcsErr = (data_high<<32) |data_low; + + data_low = 0; + hppe_rx_runt_error_frames_get(dev_id, port_id, (union rx_runt_error_frames_u *)&data_low); + mib_info->RxRuntErr = data_low; + + data_low = 0; + hppe_rx_jabber_error_frames_get(dev_id, port_id, (union rx_jabber_error_frames_u *)&data_low); + mib_info->RxJabberError = data_low; + + data_low = 0; + hppe_rx_undersize_frames_good_get(dev_id, port_id, (union rx_undersize_frames_good_u *)&data_low); + mib_info->RxUndersizeGood = data_low; + + data_low = 0; + hppe_rx_oversize_frames_good_get(dev_id, port_id, (union rx_oversize_frames_good_u *)&data_low); + mib_info->RxOversizeGood = data_low; + + data_low = 0; data_high = 0; + hppe_rx_64octets_frames_good_bad_low_get(dev_id, port_id, (union rx_64octets_frames_good_bad_low_u *)&data_low); + hppe_rx_64octets_frames_good_bad_high_get(dev_id, port_id, (union rx_64octets_frames_good_bad_high_u *)&data_high); + mib_info->Rx64Byte = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_rx_65to127octets_frames_good_bad_low_get(dev_id, port_id, (union rx_65to127octets_frames_good_bad_low_u *)&data_low); + hppe_rx_65to127octets_frames_good_bad_high_get(dev_id, port_id, (union rx_65to127octets_frames_good_bad_high_u *)&data_high); + mib_info->Rx128Byte = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_rx_128to255octets_frames_good_bad_low_get(dev_id, port_id, (union rx_128to255octets_frames_good_bad_low_u *)&data_low); + hppe_rx_128to255octets_frames_good_bad_high_get(dev_id, port_id, (union rx_128to255octets_frames_good_bad_high_u *)&data_high); + mib_info->Rx256Byte = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_rx_256to511octets_frames_good_bad_low_get (dev_id, port_id, (union rx_256to511octets_frames_good_bad_low_u *)&data_low); + hppe_rx_256to511octets_frames_good_bad_high_get(dev_id, port_id, (union rx_256to511octets_frames_good_bad_high_u *)&data_high); + mib_info->Rx512Byte = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_rx_512to1023octets_frames_good_bad_low_get(dev_id, port_id, (union rx_512to1023octets_frames_good_bad_low_u *)&data_low); + hppe_rx_512to1023octets_frames_good_bad_high_get(dev_id, port_id, (union rx_512to1023octets_frames_good_bad_high_u *)&data_high); + mib_info->Rx1024Byte = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_rx_1024tomaxoctets_frames_good_bad_low_get(dev_id, port_id, (union rx_1024tomaxoctets_frames_good_bad_low_u *)&data_low); + hppe_rx_1024tomaxoctets_frames_good_bad_high_get(dev_id, port_id, (union rx_1024tomaxoctets_frames_good_bad_high_u *)&data_high); + mib_info->RxMaxByte = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_rx_unicast_frames_good_low_get(dev_id, port_id, (union rx_unicast_frames_good_low_u *)&data_low); + hppe_rx_unicast_frames_good_high_get(dev_id, port_id, (union rx_unicast_frames_good_high_u *)&data_high); + mib_info->RxUnicastGood = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_rx_length_error_frames_low_get(dev_id, port_id, (union rx_length_error_frames_low_u *)&data_low); + hppe_rx_length_error_frames_high_get(dev_id, port_id, (union rx_length_error_frames_high_u *)&data_high); + mib_info->RxLengthError = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_rx_outofrange_frames_low_get(dev_id, port_id, (union rx_outofrange_frames_low_u*)&data_low); + hppe_rx_outofrange_frames_high_get(dev_id, port_id, (union rx_outofrange_frames_high_u*)&data_high); + mib_info->RxOutOfRangeError = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_rx_pause_frames_low_get(dev_id, port_id, (union rx_pause_frames_low_u *)&data_low); + hppe_rx_pause_frames_high_get(dev_id, port_id, (union rx_pause_frames_high_u *)&data_high); + mib_info->RxPause = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_rx_fifooverflow_frames_low_get(dev_id, port_id, (union rx_fifooverflow_frames_low_u *)&data_low); + hppe_rx_fifooverflow_frames_high_get(dev_id, port_id, (union rx_fifooverflow_frames_high_u *)&data_high); + mib_info->RxOverFlow = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_rx_vlan_frames_good_bad_low_get(dev_id, port_id, (union rx_vlan_frames_good_bad_low_u *)&data_low); + hppe_rx_vlan_frames_good_bad_high_get(dev_id, port_id, (union rx_vlan_frames_good_bad_high_u*)&data_high); + mib_info->RxVLANFrameGoodBad = (data_high<<32) |data_low; + + data_low = 0; + hppe_rx_watchdog_error_frames_get(dev_id, port_id, (union rx_watchdog_error_frames_u*)&data_low); + mib_info->RxWatchDogError = data_low; + + data_low = 0; + hppe_rx_lpi_usec_cntr_get(dev_id, port_id, (union rx_lpi_usec_cntr_u *)&data_low); + mib_info->RxLPIUsec = data_low; + + data_low = 0; + hppe_rx_lpi_tran_cntr_get(dev_id, port_id, (union rx_lpi_tran_cntr_u *)&data_low); + mib_info->RxLPITran = data_low; + + data_low = 0; data_high = 0; + hppe_rx_discard_frame_count_good_bad_low_get(dev_id, port_id, (union rx_discard_frame_count_good_bad_low_u *)&data_low); + hppe_rx_discard_frame_count_good_bad_high_get(dev_id, port_id, (union rx_discard_frame_count_good_bad_high_u *)&data_high); + mib_info->RxDropFrameGoodBad = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_rx_discard_octet_count_good_bad_low_get(dev_id, port_id, (union rx_discard_octet_count_good_bad_low_u *)&data_low); + hppe_rx_discard_octet_count_good_bad_high_get(dev_id, port_id, (union rx_discard_octet_count_good_bad_high_u *)&data_high); + mib_info->RxDropByteGoodBad = (data_high<<32) |data_low; + + return SW_OK; +} + +sw_error_t +adpt_hppe_get_tx_xgmib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_xgmib_info_t * mib_info ) +{ + + a_uint64_t data_low , data_high ; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(mib_info); + memset(mib_info, 0, sizeof(* mib_info)); + + if(!(hppe_xgmac_port_check(port_id))) + { + printk("this port is not xg port!\n"); + return SW_FAIL; + } + port_id = HPPE_TO_XGMAC_PORT_ID(port_id); + + /*get tx xgmib information*/ + data_low = 0; data_high = 0; + hppe_tx_octet_count_good_bad_low_get(dev_id, port_id, (union tx_octet_count_good_bad_low_u*)&data_low); + hppe_tx_octet_count_good_bad_high_get(dev_id, port_id, (union tx_octet_count_good_bad_high_u *)&data_high); + mib_info->TxByte = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_tx_frame_count_good_bad_low_get(dev_id, port_id, (union tx_frame_count_good_bad_low_u *)&data_low); + hppe_tx_frame_count_good_bad_high_get(dev_id, port_id, (union tx_frame_count_good_bad_high_u *)&data_high); + mib_info->TxFrame = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_tx_broadcast_frames_good_low_get(dev_id, port_id, (union tx_broadcast_frames_good_low_u *)&data_low); + hppe_tx_broadcast_frames_good_high_get(dev_id, port_id, (union tx_broadcast_frames_good_high_u*)&data_high); + mib_info->TxBroadGood = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_tx_multicast_frames_good_low_get(dev_id, port_id, (union tx_multicast_frames_good_low_u*)&data_low); + hppe_tx_multicast_frames_good_high_get(dev_id, port_id, (union tx_multicast_frames_good_high_u*)&data_high); + mib_info->TxMultiGood = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_tx_64octets_frames_good_bad_low_get(dev_id, port_id, (union tx_64octets_frames_good_bad_low_u*)&data_low); + hppe_tx_64octets_frames_good_bad_high_get(dev_id, port_id, (union tx_64octets_frames_good_bad_high_u*)&data_high); + mib_info->Tx64Byte = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_tx_65to127octets_frames_good_bad_low_get(dev_id, port_id, (union tx_65to127octets_frames_good_bad_low_u *)&data_low); + hppe_tx_65to127octets_frames_good_bad_high_get(dev_id, port_id, (union tx_65to127octets_frames_good_bad_high_u *)&data_high); + mib_info->Tx128Byte = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_tx_128to255octets_frames_good_bad_low_get(dev_id, port_id, (union tx_128to255octets_frames_good_bad_low_u *)&data_low); + hppe_tx_128to255octets_frames_good_bad_high_get(dev_id, port_id, (union tx_128to255octets_frames_good_bad_high_u *)&data_high); + mib_info->Tx256Byte = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_tx_256to511octets_frames_good_bad_low_get(dev_id, port_id, (union tx_256to511octets_frames_good_bad_low_u *)&data_low); + hppe_tx_256to511octets_frames_good_bad_high_get(dev_id, port_id, (union tx_256to511octets_frames_good_bad_high_u *)&data_high); + mib_info->Tx512Byte = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_tx_512to1023octets_frames_good_bad_low_get(dev_id, port_id, (union tx_512to1023octets_frames_good_bad_low_u*)&data_low); + hppe_tx_512to1023octets_frames_good_bad_high_get(dev_id, port_id, (union tx_512to1023octets_frames_good_bad_high_u*)&data_high); + mib_info->Tx1024Byte = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_tx_1024tomaxoctets_frames_good_bad_low_get(dev_id, port_id, (union tx_1024tomaxoctets_frames_good_bad_low_u*)&data_low); + hppe_tx_1024tomaxoctets_frames_good_bad_high_get(dev_id, port_id, (union tx_1024tomaxoctets_frames_good_bad_high_u*)&data_high); + mib_info->TxMaxByte = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_tx_unicast_frames_good_bad_low_get(dev_id, port_id, (union tx_unicast_frames_good_bad_low_u*)&data_low); + hppe_tx_unicast_frames_good_bad_high_get(dev_id, port_id, (union tx_unicast_frames_good_bad_high_u*)&data_high); + mib_info->TxUnicast = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_tx_multicast_frames_good_bad_low_get(dev_id, port_id, (union tx_multicast_frames_good_bad_low_u *)&data_low); + hppe_tx_multicast_frames_good_bad_high_get(dev_id, port_id, (union tx_multicast_frames_good_bad_high_u *)&data_high); + mib_info->TxMulti = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_tx_broadcast_frames_good_bad_low_get(dev_id, port_id, (union tx_broadcast_frames_good_bad_low_u*)&data_low); + hppe_tx_broadcast_frames_good_bad_high_get(dev_id, port_id, (union tx_broadcast_frames_good_bad_high_u*)&data_high); + mib_info->TxBroad = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_tx_underflow_error_frames_low_get(dev_id, port_id, (union tx_underflow_error_frames_low_u*)&data_low); + hppe_tx_underflow_error_frames_high_get(dev_id, port_id, (union tx_underflow_error_frames_high_u*)&data_high); + mib_info->TxUnderFlowError = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_tx_octet_count_good_low_get(dev_id, port_id, (union tx_octet_count_good_low_u*)&data_low); + hppe_tx_octet_count_good_high_get(dev_id, port_id, (union tx_octet_count_good_high_u*)&data_high); + mib_info->TxByteGood = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_tx_frame_count_good_low_get(dev_id, port_id, (union tx_frame_count_good_low_u*)&data_low); + hppe_tx_frame_count_good_high_get(dev_id, port_id, (union tx_frame_count_good_high_u*)&data_high); + mib_info->TxFrameGood = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_tx_pause_frames_low_get(dev_id, port_id, (union tx_pause_frames_low_u *)&data_low); + hppe_tx_pause_frames_high_get(dev_id, port_id, (union tx_pause_frames_high_u *)&data_high); + mib_info->TxPause = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_tx_vlan_frames_good_low_get(dev_id, port_id, (union tx_vlan_frames_good_low_u *)&data_low); + hppe_tx_vlan_frames_good_high_get(dev_id, port_id, (union tx_vlan_frames_good_high_u *)&data_high); + mib_info->TxVLANFrameGood = (data_high<<32) |data_low; + + data_low = 0; + hppe_tx_lpi_usec_cntr_get(dev_id, port_id, (union tx_lpi_usec_cntr_u *)&data_low); + mib_info->TxLPIUsec = data_low; + + data_low = 0; + hppe_tx_lpi_tran_cntr_get(dev_id, port_id, (union tx_lpi_tran_cntr_u *)&data_low); + mib_info->TxLPITran = data_low; + + return SW_OK; +} + +sw_error_t +adpt_hppe_get_rx_xgmib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_xgmib_info_t * mib_info ) +{ + a_uint64_t data_low , data_high ; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(mib_info); + memset(mib_info, 0, sizeof(* mib_info)); + + if(!(hppe_xgmac_port_check(port_id))) + { + printk("this port is not xg port!\n"); + return SW_FAIL; + } + port_id = HPPE_TO_XGMAC_PORT_ID(port_id); + + /*get tx xgmib information*/ + data_low = 0; data_high = 0; + hppe_rx_frame_count_good_bad_low_get(dev_id, port_id, (union rx_frame_count_good_bad_low_u *)&data_low); + hppe_rx_frame_count_good_bad_high_get(dev_id, port_id, (union rx_frame_count_good_bad_high_u *)&data_high); + mib_info->RxFrame = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_rx_octet_count_good_bad_low_get(dev_id, port_id, (union rx_octet_count_good_bad_low_u*)&data_low); + hppe_rx_octet_count_good_bad_high_get(dev_id, port_id, (union rx_octet_count_good_bad_high_u*)&data_high); + mib_info->RxByte = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_rx_octet_count_good_low_get(dev_id, port_id, (union rx_octet_count_good_low_u *)&data_low); + hppe_rx_octet_count_good_high_get(dev_id, port_id, (union rx_octet_count_good_high_u *)&data_high); + mib_info->RxByteGood = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_rx_broadcast_frames_good_low_get(dev_id, port_id, (union rx_broadcast_frames_good_low_u *)&data_low); + hppe_rx_broadcast_frames_good_high_get(dev_id, port_id, (union rx_broadcast_frames_good_high_u*)&data_high); + mib_info->RxBroadGood = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_rx_multicast_frames_good_low_get(dev_id, port_id, (union rx_multicast_frames_good_low_u*)&data_low); + hppe_rx_multicast_frames_good_high_get(dev_id, port_id, (union rx_multicast_frames_good_high_u*)&data_high); + mib_info->RxMultiGood = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_rx_crc_error_frames_low_get(dev_id, port_id, (union rx_crc_error_frames_low_u *)&data_low); + hppe_rx_crc_error_frames_high_get(dev_id, port_id, (union rx_crc_error_frames_high_u *)&data_high); + mib_info->RxFcsErr = (data_high<<32) |data_low; + + data_low = 0; + hppe_rx_runt_error_frames_get(dev_id, port_id, (union rx_runt_error_frames_u *)&data_low); + mib_info->RxRuntErr = data_low; + + data_low = 0; + hppe_rx_jabber_error_frames_get(dev_id, port_id, (union rx_jabber_error_frames_u *)&data_low); + mib_info->RxJabberError = data_low; + + data_low = 0; + hppe_rx_undersize_frames_good_get(dev_id, port_id, (union rx_undersize_frames_good_u *)&data_low); + mib_info->RxUndersizeGood = data_low; + + data_low = 0; + hppe_rx_oversize_frames_good_get(dev_id, port_id, (union rx_oversize_frames_good_u *)&data_low); + mib_info->RxOversizeGood = data_low; + + data_low = 0; data_high = 0; + hppe_rx_64octets_frames_good_bad_low_get(dev_id, port_id, (union rx_64octets_frames_good_bad_low_u *)&data_low); + hppe_rx_64octets_frames_good_bad_high_get(dev_id, port_id, (union rx_64octets_frames_good_bad_high_u *)&data_high); + mib_info->Rx64Byte = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_rx_65to127octets_frames_good_bad_low_get(dev_id, port_id, (union rx_65to127octets_frames_good_bad_low_u *)&data_low); + hppe_rx_65to127octets_frames_good_bad_high_get(dev_id, port_id, (union rx_65to127octets_frames_good_bad_high_u *)&data_high); + mib_info->Rx128Byte = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_rx_128to255octets_frames_good_bad_low_get(dev_id, port_id, (union rx_128to255octets_frames_good_bad_low_u *)&data_low); + hppe_rx_128to255octets_frames_good_bad_high_get(dev_id, port_id, (union rx_128to255octets_frames_good_bad_high_u *)&data_high); + mib_info->Rx256Byte = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_rx_256to511octets_frames_good_bad_low_get (dev_id, port_id, (union rx_256to511octets_frames_good_bad_low_u *)&data_low); + hppe_rx_256to511octets_frames_good_bad_high_get(dev_id, port_id, (union rx_256to511octets_frames_good_bad_high_u *)&data_high); + mib_info->Rx512Byte = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_rx_512to1023octets_frames_good_bad_low_get(dev_id, port_id, (union rx_512to1023octets_frames_good_bad_low_u *)&data_low); + hppe_rx_512to1023octets_frames_good_bad_high_get(dev_id, port_id, (union rx_512to1023octets_frames_good_bad_high_u *)&data_high); + mib_info->Rx1024Byte = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_rx_1024tomaxoctets_frames_good_bad_low_get(dev_id, port_id, (union rx_1024tomaxoctets_frames_good_bad_low_u *)&data_low); + hppe_rx_1024tomaxoctets_frames_good_bad_high_get(dev_id, port_id, (union rx_1024tomaxoctets_frames_good_bad_high_u *)&data_high); + mib_info->RxMaxByte = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_rx_unicast_frames_good_low_get(dev_id, port_id, (union rx_unicast_frames_good_low_u *)&data_low); + hppe_rx_unicast_frames_good_high_get(dev_id, port_id, (union rx_unicast_frames_good_high_u *)&data_high); + mib_info->RxUnicastGood = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_rx_length_error_frames_low_get(dev_id, port_id, (union rx_length_error_frames_low_u *)&data_low); + hppe_rx_length_error_frames_high_get(dev_id, port_id, (union rx_length_error_frames_high_u *)&data_high); + mib_info->RxLengthError = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_rx_outofrange_frames_low_get(dev_id, port_id, (union rx_outofrange_frames_low_u*)&data_low); + hppe_rx_outofrange_frames_high_get(dev_id, port_id, (union rx_outofrange_frames_high_u*)&data_high); + mib_info->RxOutOfRangeError = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_rx_pause_frames_low_get(dev_id, port_id, (union rx_pause_frames_low_u *)&data_low); + hppe_rx_pause_frames_high_get(dev_id, port_id, (union rx_pause_frames_high_u *)&data_high); + mib_info->RxPause = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_rx_fifooverflow_frames_low_get(dev_id, port_id, (union rx_fifooverflow_frames_low_u *)&data_low); + hppe_rx_fifooverflow_frames_high_get(dev_id, port_id, (union rx_fifooverflow_frames_high_u *)&data_high); + mib_info->RxOverFlow = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_rx_vlan_frames_good_bad_low_get(dev_id, port_id, (union rx_vlan_frames_good_bad_low_u *)&data_low); + hppe_rx_vlan_frames_good_bad_high_get(dev_id, port_id, (union rx_vlan_frames_good_bad_high_u*)&data_high); + mib_info->RxVLANFrameGoodBad = (data_high<<32) |data_low; + + data_low = 0; + hppe_rx_watchdog_error_frames_get(dev_id, port_id, (union rx_watchdog_error_frames_u*)&data_low); + mib_info->RxWatchDogError = data_low; + + data_low = 0; + hppe_rx_lpi_usec_cntr_get(dev_id, port_id, (union rx_lpi_usec_cntr_u *)&data_low); + mib_info->RxLPIUsec = data_low; + + data_low = 0; + hppe_rx_lpi_tran_cntr_get(dev_id, port_id, (union rx_lpi_tran_cntr_u *)&data_low); + mib_info->RxLPITran = (data_high<<32) & data_low; + + data_low = 0; data_high = 0; + hppe_rx_discard_frame_count_good_bad_low_get(dev_id, port_id, (union rx_discard_frame_count_good_bad_low_u *)&data_low); + hppe_rx_discard_frame_count_good_bad_high_get(dev_id, port_id, (union rx_discard_frame_count_good_bad_high_u *)&data_high); + mib_info->RxDropFrameGoodBad = (data_high<<32) |data_low; + + data_low = 0; data_high = 0; + hppe_rx_discard_octet_count_good_bad_low_get(dev_id, port_id, (union rx_discard_octet_count_good_bad_low_u *)&data_low); + hppe_rx_discard_octet_count_good_bad_high_get(dev_id, port_id, (union rx_discard_octet_count_good_bad_high_u *)&data_high); + mib_info->RxDropByteGoodBad = (data_high<<32) |data_low; + + return SW_OK; +} + +sw_error_t adpt_hppe_mib_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return SW_FAIL; + + adpt_hppe_mib_func_unregister(dev_id, p_adpt_api); + + if(p_adpt_api->adpt_mib_func_bitmap & (1<adpt_get_mib_info = adpt_ppe_get_mib_info; + } + if(p_adpt_api->adpt_mib_func_bitmap & (1<adpt_get_rx_mib_info = adpt_ppe_get_rx_mib_info; + } + if(p_adpt_api->adpt_mib_func_bitmap & (1<adpt_get_tx_mib_info = adpt_hppe_get_tx_mib_info; + } + if(p_adpt_api->adpt_mib_func_bitmap & (1<adpt_mib_status_set = adpt_ppe_mib_status_set; + } + if(p_adpt_api->adpt_mib_func_bitmap & (1<adpt_mib_status_get = adpt_hppe_mib_status_get; + } + if(p_adpt_api->adpt_mib_func_bitmap & (1<adpt_mib_port_flush_counters = adpt_ppe_mib_port_flush_counters; + } + if(p_adpt_api->adpt_mib_func_bitmap & (1<adpt_mib_cpukeep_set = adpt_ppe_mib_cpukeep_set; + } + if(p_adpt_api->adpt_mib_func_bitmap & (1<adpt_mib_cpukeep_get = adpt_hppe_mib_cpukeep_get; + } + if(p_adpt_api->adpt_mib_func_bitmap & (1<adpt_get_xgmib_info= adpt_hppe_get_xgmib_info; + } + if(p_adpt_api->adpt_mib_func_bitmap & (1<adpt_get_tx_xgmib_info = adpt_hppe_get_tx_xgmib_info; + } + if(p_adpt_api->adpt_mib_func_bitmap & (1<adpt_get_rx_xgmib_info = adpt_hppe_get_rx_xgmib_info; + } + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_mirror.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_mirror.c new file mode 100755 index 000000000..346e95e60 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_mirror.c @@ -0,0 +1,345 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hppe_mirror_reg.h" +#include "hppe_mirror.h" +#include "hppe_qm_reg.h" +#include "hppe_qm.h" +#include "adpt.h" + +sw_error_t +adpt_hppe_mirr_port_in_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv = SW_OK; + union port_mirror_u port_mirror; + + memset(&port_mirror, 0, sizeof(port_mirror)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + + /* mirror port just support physical port, not support trunk and virtual port */ + if (FAL_PORT_ID_TYPE(port_id) != 0) + return SW_BAD_PARAM; + + rv = hppe_port_mirror_get(dev_id, port_id, &port_mirror); + + if( rv != SW_OK ) + return rv; + + *enable = port_mirror.bf.in_mirr_en; + + return SW_OK; +} + +sw_error_t +adpt_hppe_mirr_port_eg_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv = SW_OK; + union port_mirror_u port_mirror; + + memset(&port_mirror, 0, sizeof(port_mirror)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + + /* mirror port just support physical port, not support trunk and virtual port */ + if (FAL_PORT_ID_TYPE(port_id) != 0) + return SW_BAD_PARAM; + + rv = hppe_port_mirror_get(dev_id, port_id, &port_mirror); + + if( rv != SW_OK ) + return rv; + + *enable = port_mirror.bf.eg_mirr_en; + + return SW_OK; +} + +sw_error_t +adpt_hppe_mirr_analysis_port_get(a_uint32_t dev_id, fal_port_t * port_id) +{ + sw_error_t rv = SW_OK; + union mirror_analyzer_u mirror_analyzer; + + memset(&mirror_analyzer, 0, sizeof(mirror_analyzer)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(port_id); + + /* analysis port just support physical port and trunk port, not support virtual port */ + if (FAL_PORT_ID_TYPE(*port_id) != 0 && FAL_PORT_ID_TYPE(*port_id) != 1) + return SW_BAD_PARAM; + + rv = hppe_mirror_analyzer_get(dev_id, &mirror_analyzer); + + if( rv != SW_OK ) + return rv; + + if (mirror_analyzer.bf.in_analyzer_port != mirror_analyzer.bf.eg_analyzer_port) + return SW_FAIL; + + *port_id = mirror_analyzer.bf.eg_analyzer_port; + + if (*port_id == 32 || *port_id == 33) + *port_id = FAL_PORT_ID(FAL_PORT_TYPE_TRUNK, *port_id); + + return SW_OK; +} + +sw_error_t +adpt_hppe_mirr_port_in_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + union port_mirror_u port_mirror; + + memset(&port_mirror, 0, sizeof(port_mirror)); + ADPT_DEV_ID_CHECK(dev_id); + + /* mirror port just support physical port, not support trunk and virtual port */ + if (FAL_PORT_ID_TYPE(port_id) != 0) + return SW_BAD_PARAM; + + hppe_port_mirror_get(dev_id, port_id, &port_mirror); + port_mirror.bf.in_mirr_en = enable; + + hppe_port_mirror_set(dev_id, port_id, &port_mirror); + + return SW_OK; +} +sw_error_t +adpt_hppe_mirr_port_eg_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + union port_mirror_u port_mirror; + + memset(&port_mirror, 0, sizeof(port_mirror)); + ADPT_DEV_ID_CHECK(dev_id); + + /* mirror port just support physical port, not support trunk and virtual port */ + if (FAL_PORT_ID_TYPE(port_id) != 0) + return SW_BAD_PARAM; + + hppe_port_mirror_get(dev_id, port_id, &port_mirror); + port_mirror.bf.eg_mirr_en = enable; + + hppe_port_mirror_set(dev_id, port_id, &port_mirror); + + return SW_OK; +} +sw_error_t +adpt_hppe_mirr_analysis_port_set(a_uint32_t dev_id, fal_port_t port_id) +{ + union mirror_analyzer_u mirror_analyzer; + + memset(&mirror_analyzer, 0, sizeof(mirror_analyzer)); + ADPT_DEV_ID_CHECK(dev_id); + + /* analysis port just support physical port and trunk port, not support port */ + if (FAL_PORT_ID_TYPE(port_id) != 0 && FAL_PORT_ID_TYPE(port_id) != 1) + return SW_BAD_PARAM; + + port_id = FAL_PORT_ID_VALUE(port_id); + + hppe_mirror_analyzer_get(dev_id, &mirror_analyzer); + + mirror_analyzer.bf.in_analyzer_port = port_id; + mirror_analyzer.bf.eg_analyzer_port = port_id; + + hppe_mirror_analyzer_set(dev_id, &mirror_analyzer); + + return SW_OK; +} + +sw_error_t +adpt_hppe_mirr_analysis_config_set(a_uint32_t dev_id, fal_mirr_direction_t direction, fal_mirr_analysis_config_t * config) +{ + union mirror_analyzer_u mirror_analyzer; + union in_mirror_priority_ctrl_u in_mirror_priority_ctrl; + union eg_mirror_priority_ctrl_u eg_mirror_priority_ctrl; + + memset(&mirror_analyzer, 0, sizeof(mirror_analyzer)); + memset(&in_mirror_priority_ctrl, 0, sizeof(in_mirror_priority_ctrl)); + memset(&eg_mirror_priority_ctrl, 0, sizeof(eg_mirror_priority_ctrl)); + + ADPT_DEV_ID_CHECK(dev_id); + + /* analysis port just support physical port and trunk port, not support port */ + if (FAL_PORT_ID_TYPE(config->port_id) != 0 && FAL_PORT_ID_TYPE(config->port_id) != 1) + return SW_BAD_PARAM; + + config->port_id = FAL_PORT_ID_VALUE(config->port_id); + + hppe_mirror_analyzer_get(dev_id, &mirror_analyzer); + + if (direction == FAL_MIRR_BOTH) + { + mirror_analyzer.bf.in_analyzer_port = config->port_id; + mirror_analyzer.bf.eg_analyzer_port = config->port_id; + in_mirror_priority_ctrl.bf.priority = config->priority; + eg_mirror_priority_ctrl.bf.priority = config->priority; + hppe_mirror_analyzer_set(dev_id, &mirror_analyzer); + hppe_in_mirror_priority_ctrl_set(dev_id, &in_mirror_priority_ctrl); + hppe_eg_mirror_priority_ctrl_set(dev_id, &eg_mirror_priority_ctrl); + } + else if (direction == FAL_MIRR_INGRESS) + { + mirror_analyzer.bf.in_analyzer_port = config->port_id; + in_mirror_priority_ctrl.bf.priority = config->priority; + hppe_mirror_analyzer_set(dev_id, &mirror_analyzer); + hppe_in_mirror_priority_ctrl_set(dev_id, &in_mirror_priority_ctrl); + } + else if (direction == FAL_MIRR_EGRESS) + { + mirror_analyzer.bf.eg_analyzer_port = config->port_id; + eg_mirror_priority_ctrl.bf.priority = config->priority; + hppe_mirror_analyzer_set(dev_id, &mirror_analyzer); + hppe_eg_mirror_priority_ctrl_set(dev_id, &eg_mirror_priority_ctrl); + } + else + return SW_NOT_SUPPORTED; + + return SW_OK; +} + +sw_error_t +adpt_hppe_mirr_analysis_config_get(a_uint32_t dev_id, fal_mirr_direction_t direction, fal_mirr_analysis_config_t * config) +{ + union mirror_analyzer_u mirror_analyzer; + union in_mirror_priority_ctrl_u in_mirror_priority_ctrl; + union eg_mirror_priority_ctrl_u eg_mirror_priority_ctrl; + + memset(&mirror_analyzer, 0, sizeof(mirror_analyzer)); + memset(&in_mirror_priority_ctrl, 0, sizeof(in_mirror_priority_ctrl)); + memset(&eg_mirror_priority_ctrl, 0, sizeof(eg_mirror_priority_ctrl)); + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(config); + /* analysis port just support physical port and trunk port, not support virtual port */ + if (FAL_PORT_ID_TYPE(config->port_id) != 0 && FAL_PORT_ID_TYPE(config->port_id) != 1) + return SW_BAD_PARAM; + + hppe_mirror_analyzer_get(dev_id, &mirror_analyzer); + hppe_in_mirror_priority_ctrl_get(dev_id, &in_mirror_priority_ctrl); + hppe_eg_mirror_priority_ctrl_get(dev_id, &eg_mirror_priority_ctrl); + + if (direction == FAL_MIRR_BOTH) + { + if ((mirror_analyzer.bf.in_analyzer_port != mirror_analyzer.bf.eg_analyzer_port) || + (in_mirror_priority_ctrl.bf.priority != eg_mirror_priority_ctrl.bf.priority)) + return SW_FAIL; + + config->port_id = mirror_analyzer.bf.in_analyzer_port; + config->priority = in_mirror_priority_ctrl.bf.priority; + } + else if (direction == FAL_MIRR_INGRESS) + { + config->port_id = mirror_analyzer.bf.in_analyzer_port; + config->priority = in_mirror_priority_ctrl.bf.priority; + } + else if (direction == FAL_MIRR_EGRESS) + { + config->port_id = mirror_analyzer.bf.eg_analyzer_port; + config->priority = eg_mirror_priority_ctrl.bf.priority; + } + else + return SW_NOT_SUPPORTED; + + if (config->port_id == 32 || config->port_id == 33) + config->port_id = FAL_PORT_ID(FAL_PORT_TYPE_TRUNK, config->port_id); + + return SW_OK; +} + +void adpt_hppe_mirror_func_bitmap_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_mirror_func_bitmap = ((1 << FUNC_MIRR_ANALYSIS_PORT_SET) | + (1 << FUNC_MIRR_ANALYSIS_PORT_GET) | + (1 << FUNC_MIRR_PORT_IN_SET) | + (1 << FUNC_MIRR_PORT_IN_GET) | + (1 << FUNC_MIRR_PORT_EG_SET) | + (1 << FUNC_MIRR_PORT_EG_GET) | + (1 << FUNC_MIRR_ANALYSIS_CONFIG_SET) | + (1 << FUNC_MIRR_ANALYSIS_CONFIG_GET)); + + return; +} + +static void adpt_hppe_mirror_func_unregister(a_uint32_t dev_id, adpt_api_t *p_adpt_api) +{ + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_mirr_port_in_set = NULL; + p_adpt_api->adpt_mirr_port_in_get = NULL; + p_adpt_api->adpt_mirr_port_eg_set = NULL; + p_adpt_api->adpt_mirr_port_eg_get = NULL; + p_adpt_api->adpt_mirr_analysis_port_set = NULL; + p_adpt_api->adpt_mirr_analysis_port_get = NULL; + p_adpt_api->adpt_mirr_analysis_config_set = NULL; + p_adpt_api->adpt_mirr_analysis_config_get = NULL; + + return; +} + + + + +sw_error_t adpt_hppe_mirror_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return SW_FAIL; + + adpt_hppe_mirror_func_unregister(dev_id, p_adpt_api); + + if (p_adpt_api->adpt_mirror_func_bitmap & (1 << FUNC_MIRR_PORT_IN_SET)) + p_adpt_api->adpt_mirr_port_in_set = adpt_hppe_mirr_port_in_set; + if (p_adpt_api->adpt_mirror_func_bitmap & (1 << FUNC_MIRR_PORT_IN_GET)) + p_adpt_api->adpt_mirr_port_in_get = adpt_hppe_mirr_port_in_get; + if (p_adpt_api->adpt_mirror_func_bitmap & (1 << FUNC_MIRR_PORT_EG_SET)) + p_adpt_api->adpt_mirr_port_eg_set = adpt_hppe_mirr_port_eg_set; + if (p_adpt_api->adpt_mirror_func_bitmap & (1 << FUNC_MIRR_PORT_EG_GET)) + p_adpt_api->adpt_mirr_port_eg_get = adpt_hppe_mirr_port_eg_get; + if (p_adpt_api->adpt_mirror_func_bitmap & (1 << FUNC_MIRR_ANALYSIS_PORT_SET)) + p_adpt_api->adpt_mirr_analysis_port_set = adpt_hppe_mirr_analysis_port_set; + if (p_adpt_api->adpt_mirror_func_bitmap & (1 << FUNC_MIRR_ANALYSIS_PORT_GET)) + p_adpt_api->adpt_mirr_analysis_port_get = adpt_hppe_mirr_analysis_port_get; + if (p_adpt_api->adpt_mirror_func_bitmap & (1 << FUNC_MIRR_ANALYSIS_CONFIG_SET)) + p_adpt_api->adpt_mirr_analysis_config_set = adpt_hppe_mirr_analysis_config_set; + if (p_adpt_api->adpt_mirror_func_bitmap & (1 << FUNC_MIRR_ANALYSIS_CONFIG_GET)) + p_adpt_api->adpt_mirr_analysis_config_get = adpt_hppe_mirr_analysis_config_get; + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_misc.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_misc.c new file mode 100755 index 000000000..104c3652c --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_misc.c @@ -0,0 +1,1011 @@ +/* + * 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. + */ + + +/** + * @defgroup + * @{ + */ +#include "sw.h" +#include "hppe_portctrl_reg.h" +#include "hppe_portctrl.h" +#include "hppe_portvlan_reg.h" +#include "hppe_portvlan.h" +#include "hppe_vsi_reg.h" +#include "hppe_vsi.h" +#include "hppe_policer_reg.h" +#include "hppe_policer.h" +#include "hppe_qm_reg.h" +#include "hppe_qm.h" +#include "adpt_hppe.h" +#include "adpt.h" +#if defined(CPPE) +#include "adpt_cppe_misc.h" +#endif + + +#ifndef IN_MISC_MINI +char cpucode[][85] = { +"Forwarding to CPU", +"Unkown L2 protocol exception redirect/copy to CPU", +"PPPoE wrong version or wrong type exception redirect/copy to CPU", +"PPPoE wrong code exception redirect/copy to CPU", +"PPPoE unsupported PPP protocol exception redirect/copy to CPU", +"IPv4 wrong version exception redirect/copy to CPU", +"IPv4 small IHL exception redirect/copy to CPU", +"IPv4 with option exception redirect/copy to CPU", +"IPv4 header incomplete exception redirect/copy to CPU", +"IPv4 bad total length exception redirect/copy to CPU", +"IPv4 data incomplete exception redirect/copy to CPU", +"IPv4 fragment exception redirect/copy to CPU", +"IPv4 ping of death exception redirect/copy to CPU", +"IPv4 small TTL exception redirect/copy to CPU", +"IPv4 unknown IP protocol exception redirect/copy to CPU", +"IPv4 checksum error exception redirect/copy to CPU", +"IPv4 invalid SIP exception redirect/copy to CPU", +"IPv4 invalid DIP exception redirect/copy to CPU", +"IPv4 LAND attack exception redirect/copy to CPU", +"IPv4 AH header incomplete exception redirect/copy to CPU", +"IPv4 AH header cross 128-byte exception redirect/copy to CPU", +"IPv4 ESP header incomplete exception redirect/copy to CPU", +"IPv6 wrong version exception redirect/copy to CPU", +"IPv6 header incomplete exception redirect/copy to CPU", +"IPv6 bad total length exception redirect/copy to CPU", +"IPv6 data incomplete exception redirect/copy to CPU", +"IPv6 with extension header exception redirect/copy to CPU", +"IPv6 small hop limit exception redirect/copy to CPU", +"IPv6 invalid SIP exception redirect/copy to CPU", +"IPv6 invalid DIP exception redirect/copy to CPU", +"IPv6 LAND attack exception redirect/copy to CPU", +"IPv6 fragment exception redirect/copy to CPU", +"IPv6 ping of death exception redirect/copy to CPU", +"IPv6 with more than 2 extension headers exception redirect/copy to CPU", +"IPv6 unknown last next header exception redirect/copy to CPU", +"IPv6 mobility header incomplete exception redirect/copy to CPU", +"IPv6 mobility header cross 128-byte exception redirect/copy to CPU", +"IPv6 AH header incomplete exception redirect/copy to CPU", +"IPv6 AH header cross 128-byte exception redirect/copy to CPU", +"IPv6 ESP header incomplete exception redirect/copy to CPU", +"IPv6 ESP header cross 128-byte exception redirect/copy to CPU", +"IPv6 other extension header incomplete exception redirect/copy to CPU", +"IPv6 other extension header cross 128-byte exception redirect/copy to CPU", +"TCP header incomplete exception redirect/copy to CPU", +"TCP header cross 128-byte exception redirect/copy to CPU", +"TCP same SP and DP exception redirect/copy to CPU", +"TCP small data offset redirect/copy to CPU", +"TCP flags VALUE/MASK group 0 exception redirect/copy to CPU", +"TCP flags VALUE/MASK group 1 exception redirect/copy to CPU", +"TCP flags VALUE/MASK group 2 exception redirect/copy to CPU", +"TCP flags VALUE/MASK group 3 exception redirect/copy to CPU", +"TCP flags VALUE/MASK group 4 exception redirect/copy to CPU", +"TCP flags VALUE/MASK group 5 exception redirect/copy to CPU", +"TCP flags VALUE/MASK group 6 exception redirect/copy to CPU", +"TCP flags VALUE/MASK group 7 exception redirect/copy to CPU", +"TCP checksum error exception redirect/copy to CPU", +"UDP header incomplete exception redirect/copy to CPU", +"UDP header cross 128-byte exception redirect/copy to CPU", +"UDP same SP and DP exception redirect/copy to CPU", +"UDP bad length exception redirect/copy to CPU", +"UDP data incomplete exception redirect/copy to CPU", +"UDP checksum error exception redirect/copy to CPU", +"UDP-Lite header incomplete exception redirect/copy to CPU", +"UDP-Lite header cross 128-byte exception redirect/copy to CPU", +"UDP-Lite same SP and DP exception redirect/copy to CPU", +"UDP-Lite checksum coverage value 0-7 exception redirect/copy to CPU", +"UDP-Lite checksum coverage value too big exception redirect/copy to CPU", +"UDP-Lite checksum coverage value cross 128-byte exception redirect/copy to CPU", +"UDP-Lite checksum error exception redirect/copy to CPU", +"Fake L2 protocol packet redirect/copy to CPU", +"Fake MAC header packet redirect/copy to CPU", +"L2 MRU checking fail redirect/copy to CPU", +"L2 MTU checking fail redirect/copy to CPU", +"IP prefix broadcast redirect/copy to CPU", +"L3 MTU checking fail redirect/copy to CPU", +"L3 MRU checking fail redirect/copy to CPU", +"ICMP redirect/copy to CPU", +"IP to me routing TTL 1 redirect/copy to CPU", +"IP to me routing TTL 0 redirect/copy to CPU", +"Flow service code loop redirect/copy to CPU", +"Flow de-accelearate redirect/copy to CPU", +"Flow source interface check fail redirect/copy to CPU", +"Flow sync toggle mismatch redirect/copy to CPU", +"MTU check fail if DF set redirect/copy to CPU", +"PPPoE multicast redirect/copy to CPU", +"EAPoL packet redirect/copy to CPU", +"PPPoE discovery packet redirect/copy to CPU", +"IGMP packet redirect/copy to CPU", +"ARP request packet redirect/copy to CPU", +"ARP reply packet redirect/copy to CPU", +"DHCPv4 packet redirect/copy to CPU", +"MLD packet redirect/copy to CPU", +"NS packet redirect/copy to CPU", +"NA packet redirect/copy to CPU", +"DHCPv6 packet redirect/copy to CPU", +"PTP sync packet redirect/copy to CPU", +"PTP follow up packet redirect/copy to CPU", +"PTP delay request packet redirect/copy to CPU", +"PTP delay response packet redirect/copy to CPU", +"PTP pdelay request packet redirect/copy to CPU", +"PTP pdelay response packet redirect/copy to CPU", +"PTP pdelay response follow up packet redirect/copy to CPU", +"PTP announce packet redirect/copy to CPU", +"PTP management packet redirect/copy to CPU", +"PTP signaling packet redirect/copy to CPU", +"PTP message reserved type 0 packet redirect/copy to CPU", +"PTP message reserved type 1 packet redirect/copy to CPU", +"PTP message reserved type 2 packet redirect/copy to CPU", +"PTP message reserved type 3 packet redirect/copy to CPU", +"PTP message reserved type packet redirect/copy to CPU", +"IPv4 source guard unknown packet redirect/copy to CPU", +"IPv6 source guard unknown packet redirect/copy to CPU", +"ARP source guard unknown packet redirect/copy to CPU", +"ND source guard unknown packet redirect/copy to CPU", +"IPv4 source guard violation packet redirect/copy to CPU", +"IPv6 source guard violation packet redirect/copy to CPU", +"ARP source guard violation packet redirect/copy to CPU", +"ND source guard violation packet redirect/copy to CPU", +"L3 route host mismatch action redirect/copy to CPU", +"L3 flow SNAT action redirect/copy to CPU", +"L3 flow DNAT action redirect/copy to CPU", +"L3 flow routing action redirect/copy to CPU", +"L3 flow bridging action redirect/copy to CPU", +"L3 multicast bridging action redirect/copy to CPU", +"L3 route Preheader routing action redirect/copy to CPU", +"L3 route Preheader SNAPT action redirect/copy to CPU", +"L3 route Preheader DNAPT action redirect/copy to CPU", +"L3 route Preheader SNAT action redirect/copy to CPU", +"L3 route Preheader DNAT action redirect/copy to CPU", +"L3 no route preheader NAT action redirect/copy to CPU", +"L3 no route preheader NAT error redirect/copy to CPU", +"L3 route action redirect/copy to CPU", +"L3 no route action redirect/copy to CPU", +"L3 no route next hop invalid action redirect/copy to CPU", +"L3 no route preheader action redirect/copy to CPU", +"L3 bridge action redirect/copy to CPU", +"L3 flow action redirect/copy to CPU", +"L3 flow miss action redirect/copy to CPU", +"L2 new MAC address redirect/copy to CPU", +"L2 hash violation redirect/copy to CPU", +"L2 station move redirect/copy to CPU", +"L2 learn limit redirect/copy to CPU", +"L2 SA lookup action redirect/copy to CPU", +"L2 DA lookup action redirect/copy to CPU", +"APP_CTRL action redirect/copy to CPU", +"Pre-IPO action", +"Post-IPO action", +"Service code action", +"Egress mirror to CPU", +"Ingress mirror to CPU", +}; + +char dropcode[][75] = { +"None", +"Unkown L2 protocol exception drop", +"PPPoE wrong version or wrong type exception drop", +"PPPoE wrong code exception drop", +"PPPoE unsupported PPP protocol exception drop", +"IPv4 wrong version exception drop", +"IPv4 small IHL exception drop", +"IPv4 with option exception drop", +"IPv4 header incomplete exception drop", +"IPv4 bad total length exception drop", +"IPv4 data incomplete exception drop", +"IPv4 fragment exception drop", +"IPv4 ping of death exception drop", +"IPv4 small TTL exception drop", +"IPv4 unknown IP protocol exception drop", +"IPv4 checksum error exception drop", +"IPv4 invalid SIP exception drop", +"IPv4 invalid DIP exception drop", +"IPv4 LAND attack exception drop", +"IPv4 AH header incomplete exception drop", +"IPv4 AH header cross 128-byte exception drop", +"IPv4 ESP header incomplete exception drop", +"IPv6 wrong version exception drop", +"IPv6 header incomplete exception drop", +"IPv6 bad total length exception drop", +"IPv6 data incomplete exception drop", +"IPv6 with extension header exception drop", +"IPv6 small hop limit exception drop", +"IPv6 invalid SIP exception drop", +"IPv6 invalid DIP exception drop", +"IPv6 LAND attack exception drop", +"IPv6 fragment exception drop", +"IPv6 ping of death exception drop", +"IPv6 with more than 2 extension headers exception drop", +"IPv6 unknown last next header exception drop", +"IPv6 mobility header incomplete exception drop", +"IPv6 mobility header cross 128-byte exception drop", +"IPv6 AH header incomplete exception drop", +"IPv6 AH header cross 128-byte exception drop", +"IPv6 ESP header incomplete exception drop", +"IPv6 ESP header cross 128-byte exception drop", +"IPv6 other extension header incomplete exception drop", +"IPv6 other extension header cross 128-byte exception drop", +"TCP header incomplete exception drop", +"TCP header cross 128-byte exception drop", +"TCP same SP and DP exception drop", +"TCP small data offset drop", +"TCP flags VALUE/MASK group 0 exception drop", +"TCP flags VALUE/MASK group 1 exception drop", +"TCP flags VALUE/MASK group 2 exception drop", +"TCP flags VALUE/MASK group 3 exception drop", +"TCP flags VALUE/MASK group 4 exception drop", +"TCP flags VALUE/MASK group 5 exception drop", +"TCP flags VALUE/MASK group 6 exception drop", +"TCP flags VALUE/MASK group 7 exception drop", +"TCP checksum error exception drop", +"UDP header incomplete exception drop", +"UDP header cross 128-byte exception drop", +"UDP same SP and DP exception drop", +"UDP bad length exception drop", +"UDP data incomplete exception drop", +"UDP checksum error exception drop", +"UDP-Lite header incomplete exception drop", +"UDP-Lite header cross 128-byte exception drop", +"UDP-Lite same SP and DP exception drop", +"UDP-Lite checksum coverage value 0-7 exception drop", +"UDP-Lite checksum coverage value too big exception drop", +"UDP-Lite checksum coverage value cross 128-byte exception drop", +"UDP-Lite checksum error exception drop", +"L3 multicast bridging action", +"L3 no route with Preheader NAT action", +"L3 no route with Preheader NAT action error configuration", +"L3 route action drop", +"L3 no route action drop", +"L3 no route next hop invalid action drop", +"L3 no route preheader action drop", +"L3 bridge action drop", +"L3 flow action drop", +"L3 flow miss action drop", +"L2 MRU checking fail drop", +"L2 MTU checking fail drop", +"L3 IP prefix broadcast drop", +"L3 MTU checking fail drop", +"L3 MRU checking fail drop", +"L3 ICMP redirect drop", +"Fake MAC header indicated packet not routing or bypass L3 edit drop", +"L3 IP route TTL zero drop", +"L3 flow service code loop drop", +"L3 flow de-accelerate drop", +"L3 flow source interface check fail drop", +"Flow toggle mismatch exception drop", +"MTU check exception if DF set drop", +"PPPoE multicast packet with IP routing enabled drop", +"IPv4 SG unkown drop", +"IPv6 SG unkown drop", +"ARP SG unkown drop", +"ND SG unkown drop", +"IPv4 SG violation drop", +"IPv6 SG violation drop", +"ARP SG violation drop", +"ND SG violation drop", +"L2 new MAC address drop", +"L2 hash violation drop", +"L2 station move drop", +"L2 learn limit drop", +"L2 SA lookup action drop", +"L2 DA lookup action drop", +"APP_CTRL action drop", +"Ingress VLAN filtering action drop", +"Ingress VLAN translation miss drop", +"Egress VLAN filtering drop", +"Pre-IPO entry hit action drop", +"Post-IPO entry hit action drop", +"Multicast SA or broadcast SA drop", +"No destination drop", +"STG ingress filtering drop", +"STG egress filtering drop", +"Source port filter drop", +"Trunk select fail drop", +"TX MAC disable drop", +"Ingress VLAN tag format drop", +"CRC error drop", +"PAUSE frame drop", +"Promisc drop", +"Isolation drop", +"Magagement packet APP_CTRL drop", +"Fake L2 protocol indicated packet not routing or bypass L3 edit drop", +"Policing drop" +}; + +sw_error_t +adpt_hppe_debug_port_counter_enable(a_uint32_t dev_id, fal_port_t port_id, + fal_counter_en_t *cnt_en) +{ + union mru_mtu_ctrl_tbl_u mru_mtu_ctrl_tbl; + union mc_mtu_ctrl_tbl_u mc_mtu_ctrl_tbl; + union port_eg_vlan_u port_eg_vlan; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cnt_en); + + port_id = FAL_PORT_ID_VALUE(port_id); + + if (port_id < SSDK_MAX_PORT_NUM) { + SW_RTN_ON_ERROR(hppe_mru_mtu_ctrl_tbl_get(dev_id, port_id, &mru_mtu_ctrl_tbl)); + SW_RTN_ON_ERROR(hppe_mc_mtu_ctrl_tbl_get(dev_id, port_id, &mc_mtu_ctrl_tbl)); + SW_RTN_ON_ERROR(hppe_port_eg_vlan_get(dev_id, port_id, &port_eg_vlan)); + mru_mtu_ctrl_tbl.bf.rx_cnt_en = cnt_en->rx_counter_en; + mru_mtu_ctrl_tbl.bf.tx_cnt_en = cnt_en->vp_uni_tx_counter_en; + mc_mtu_ctrl_tbl.bf.tx_cnt_en = cnt_en->port_mc_tx_counter_en; + port_eg_vlan.bf.tx_counting_en = cnt_en->port_tx_counter_en; + SW_RTN_ON_ERROR(hppe_mru_mtu_ctrl_tbl_set(dev_id, port_id, &mru_mtu_ctrl_tbl)); + SW_RTN_ON_ERROR(hppe_mc_mtu_ctrl_tbl_set(dev_id, port_id, &mc_mtu_ctrl_tbl)); + SW_RTN_ON_ERROR(hppe_port_eg_vlan_set(dev_id, port_id, &port_eg_vlan)); + } + else if (port_id >= SSDK_MAX_PORT_NUM && + port_id < SSDK_MAX_VIRTUAL_PORT_NUM) { + SW_RTN_ON_ERROR(hppe_mru_mtu_ctrl_tbl_get(dev_id, port_id, &mru_mtu_ctrl_tbl)); + mru_mtu_ctrl_tbl.bf.rx_cnt_en = cnt_en->rx_counter_en; + mru_mtu_ctrl_tbl.bf.tx_cnt_en = cnt_en->vp_uni_tx_counter_en; + SW_RTN_ON_ERROR(hppe_mru_mtu_ctrl_tbl_set(dev_id, port_id, &mru_mtu_ctrl_tbl)); + } else { + return SW_OUT_OF_RANGE; + } + + return SW_OK; +} + +sw_error_t +adpt_ppe_debug_port_counter_enable(a_uint32_t dev_id, fal_port_t port_id, + fal_counter_en_t *cnt_en) +{ + a_uint32_t chip_ver = 0; + + chip_ver = adpt_hppe_chip_revision_get(dev_id); +#if defined(CPPE) + if (chip_ver == CPPE_REVISION) { + return adpt_cppe_debug_port_counter_enable(dev_id, port_id, cnt_en); + } else +#endif + { + return adpt_hppe_debug_port_counter_enable(dev_id, port_id, cnt_en); + } +} + +sw_error_t +adpt_hppe_debug_port_counter_status_get(a_uint32_t dev_id, fal_port_t port_id, + fal_counter_en_t *cnt_en) +{ + union mru_mtu_ctrl_tbl_u mru_mtu_ctrl_tbl; + union mc_mtu_ctrl_tbl_u mc_mtu_ctrl_tbl; + union port_eg_vlan_u port_eg_vlan; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cnt_en); + + port_id = FAL_PORT_ID_VALUE(port_id); + + if (port_id < SSDK_MAX_PORT_NUM) { + SW_RTN_ON_ERROR(hppe_mru_mtu_ctrl_tbl_get(dev_id, port_id, &mru_mtu_ctrl_tbl)); + SW_RTN_ON_ERROR(hppe_mc_mtu_ctrl_tbl_get(dev_id, port_id, &mc_mtu_ctrl_tbl)); + SW_RTN_ON_ERROR(hppe_port_eg_vlan_get(dev_id, port_id, &port_eg_vlan)); + cnt_en->rx_counter_en = mru_mtu_ctrl_tbl.bf.rx_cnt_en; + cnt_en->vp_uni_tx_counter_en = mru_mtu_ctrl_tbl.bf.tx_cnt_en; + cnt_en->port_mc_tx_counter_en = mc_mtu_ctrl_tbl.bf.tx_cnt_en; + cnt_en->port_tx_counter_en = port_eg_vlan.bf.tx_counting_en; + } else if (port_id >= SSDK_MAX_PORT_NUM && + port_id < SSDK_MAX_VIRTUAL_PORT_NUM) { + SW_RTN_ON_ERROR(hppe_mru_mtu_ctrl_tbl_get(dev_id, port_id, &mru_mtu_ctrl_tbl)); + cnt_en->rx_counter_en = mru_mtu_ctrl_tbl.bf.rx_cnt_en; + cnt_en->vp_uni_tx_counter_en = mru_mtu_ctrl_tbl.bf.tx_cnt_en; + } else { + return SW_OUT_OF_RANGE; + } + + return SW_OK; +} + +sw_error_t +adpt_ppe_debug_port_counter_status_get(a_uint32_t dev_id, fal_port_t port_id, + fal_counter_en_t *cnt_en) +{ + a_uint32_t chip_ver = 0; + + chip_ver = adpt_hppe_chip_revision_get(dev_id); +#if defined(CPPE) + if (chip_ver == CPPE_REVISION) { + return adpt_cppe_debug_port_counter_status_get(dev_id, port_id, cnt_en); + } else +#endif + { + return adpt_hppe_debug_port_counter_status_get(dev_id, port_id, cnt_en); + } +} + +sw_error_t +adpt_hppe_debug_counter_set(void) +{ + union vlan_cnt_tbl_u vlan_cnt_tbl = {0}; + union pre_l2_cnt_tbl_u pre_l2_cnt_tbl = {0}; + union port_tx_drop_cnt_tbl_u port_tx_drop_cnt_tbl = {0}; + union eg_vsi_counter_tbl_u eg_vsi_counter_tbl = {0}; + union port_tx_counter_tbl_reg_u port_tx_counter_tbl = {0}; + union vp_tx_counter_tbl_reg_u vp_tx_counter_tbl = {0}; + union queue_tx_counter_tbl_u queue_tx_counter_tbl = {0}; + union epe_dbg_in_cnt_reg_u epe_dbg_in_cnt = {0}; + union epe_dbg_out_cnt_reg_u epe_dbg_out_cnt = {0}; + union vp_tx_drop_cnt_tbl_u vp_tx_drop_cnt_tbl = {0}; + union drop_cpu_cnt_tbl_u drop_cpu_cnt_tbl = {0}; + + a_uint32_t i; + + /* clear PRX DROP_CNT */ + for (i = 0; i < DROP_CNT_MAX_ENTRY; i++) + hppe_drop_cnt_drop_cnt_set(0, i, 0); + + /* clear PRX DROP_PKT_STAT */ + for (i = 0; i < DROP_PKT_STAT_MAX_ENTRY; i++) { + hppe_drop_stat_pkts_set(0, i, 0); + hppe_drop_stat_bytes_set(0, i, 0); + } + + /* clear IPR_PKT_NUM */ + for (i = 0; i < IPR_PKT_NUM_TBL_REG_MAX_ENTRY; i++) { + hppe_ipr_pkt_num_tbl_reg_packets_set(0, i, 0); + hppe_ipr_byte_low_reg_reg_bytes_set(0, i, 0); + hppe_ipr_byte_high_reg_bytes_set(0, i, 0); + } + + /* clear VLAN_CNT_TBL */ + for (i = 0; i < VLAN_CNT_TBL_MAX_ENTRY; i++) + hppe_vlan_cnt_tbl_set(0, i, &vlan_cnt_tbl); + + /* clear PRE_L2_CNT_TBL */ + for (i = 0; i < PRE_L2_CNT_TBL_MAX_ENTRY; i++) + hppe_pre_l2_cnt_tbl_set(0, i, &pre_l2_cnt_tbl); + + /* clear PORT_TX_DROP_CNT_TBL */ + for (i = 0; i < PORT_TX_DROP_CNT_TBL_MAX_ENTRY; i++) + hppe_port_tx_drop_cnt_tbl_set(0, i, &port_tx_drop_cnt_tbl); + + /* clear EG_VSI_COUNTER_TBL */ + for (i = 0; i < EG_VSI_COUNTER_TBL_MAX_ENTRY; i++) + hppe_eg_vsi_counter_tbl_set(0, i, &eg_vsi_counter_tbl); + + /* clear PORT_TX_COUNTER_TBL */ + for (i = 0; i < PORT_TX_COUNTER_TBL_REG_MAX_ENTRY; i++) + hppe_port_tx_counter_tbl_reg_set(0, i, &port_tx_counter_tbl); + + /* clear VP_TX_COUNTER_TBL */ + for (i = 0; i < VP_TX_COUNTER_TBL_REG_MAX_ENTRY; i++) + hppe_vp_tx_counter_tbl_reg_set(0, i, &vp_tx_counter_tbl); + + /* clear QUEUE_TX_COUNTER_TBL */ + for (i = 0; i < QUEUE_TX_COUNTER_TBL_MAX_ENTRY; i++) + hppe_queue_tx_counter_tbl_set(0, i, &queue_tx_counter_tbl); + + /* clear EPE_DBG_IN_CNT & EPE_DBG_OUT_CNT */ + hppe_epe_dbg_in_cnt_reg_set(0, &epe_dbg_in_cnt); + hppe_epe_dbg_out_cnt_reg_set(0, &epe_dbg_out_cnt); + + /* clear VP_TX_DROP_CNT_TBL */ + for (i = 0; i < VP_TX_DROP_CNT_TBL_MAX_ENTRY; i++) + hppe_vp_tx_drop_cnt_tbl_set(0, i, &vp_tx_drop_cnt_tbl); + + /* clear DROP_CPU_CNT_TBL */ + for (i = 0; i < DROP_CPU_CNT_TBL_MAX_ENTRY; i++) + hppe_drop_cpu_cnt_tbl_set(0, i, &drop_cpu_cnt_tbl); + + return SW_OK; +} + +void +adpt_hppe_debug_prx_drop_cnt_get(void) +{ + a_uint32_t value; + int i, tags, sign; + + sign = tags = 0; + printk("%-35s", "PRX_DROP_CNT RX:"); + for (i = 0; i < DROP_CNT_MAX_ENTRY; i++) + { + hppe_drop_cnt_drop_cnt_get(0, i, &value); + if (value > 0) + { + if (sign) { + printk("\n"); + printk("%-35s", ""); + } + sign = 0; + printk("%15u(port=%04d)", value, i); + if (++tags % 3 == 0) + sign = 1; + } + } + printk("\n"); +} + +void +adpt_hppe_debug_prx_drop_pkt_stat_get(a_bool_t show_type) +{ + a_uint32_t value32; + a_uint64_t value; + int i, tags, sign; + + sign = tags = 0; + printk("%-35s", "PRX_DROP_PKT_STAT RX:"); + for (i = 0; i < DROP_PKT_STAT_MAX_ENTRY; i++) + { + if (show_type == A_FALSE) + { + hppe_drop_stat_pkts_get(0, i, &value32); + value = (a_uint64_t)value32; + } + else + hppe_drop_stat_bytes_get(0, i, &value); + if (value > 0) + { + if (sign) { + printk("\n"); + printk("%-35s", ""); + } + sign = 0; + printk("%15llu(port=%04d)", value, i); + if (++tags % 3 == 0) + sign = 1; + } + } + printk("\n"); +} + +void +adpt_hppe_debug_ipx_pkt_num_get(a_bool_t show_type) +{ + union ipr_pkt_num_tbl_reg_u ipr_pkt_num_tbl_reg; + union ipr_byte_low_reg_reg_u ipr_byte_low_reg; + union ipr_byte_high_reg_u ipr_byte_high_reg; + a_uint64_t value; + int i, tags, sign; + + sign = tags = 0; + printk("%-35s", "IPR_PKT_NUM RX:"); + for (i = 0; i < IPR_PKT_NUM_TBL_REG_MAX_ENTRY; i++) + { + hppe_ipr_pkt_num_tbl_reg_get(0, i, &ipr_pkt_num_tbl_reg); + hppe_ipr_byte_low_reg_reg_get(0, i, &ipr_byte_low_reg); + hppe_ipr_byte_high_reg_get(0, i, &ipr_byte_high_reg); + if (show_type == A_FALSE) + value = (a_uint64_t)ipr_pkt_num_tbl_reg.bf.packets; + else + value = ipr_byte_low_reg.bf.bytes | ((a_uint64_t)ipr_byte_high_reg.bf.bytes << 32); + + if (value > 0) + { + if (sign) { + printk("\n"); + printk("%-35s", ""); + } + sign = 0; + printk("%15llu(port=%04d)", value, i); + if (++tags % 3 == 0) + sign = 1; + } + } + printk("\n"); +} + +void +adpt_hppe_debug_vlan_counter_get(a_bool_t show_type) +{ + union vlan_cnt_tbl_u vlan_cnt_tbl; + a_uint64_t value; + int i, tags, sign; + + sign = tags = 0; + printk("%-35s", "VLAN_CNT_TBL RX:"); + for (i = 0; i < VLAN_CNT_TBL_MAX_ENTRY; i++) + { + hppe_vlan_cnt_tbl_get(0, i, &vlan_cnt_tbl); + if (show_type == A_FALSE) + value = (a_uint64_t)vlan_cnt_tbl.bf.rx_pkt_cnt; + else + value = vlan_cnt_tbl.bf.rx_byte_cnt_0 | ((a_uint64_t)vlan_cnt_tbl.bf.rx_byte_cnt_1 << 32); + if (value > 0) + { + if (sign) { + printk("\n"); + printk("%-35s", ""); + } + sign = 0; + printk("%15llu(vsi=%04d)", value, i); + if (++tags % 3 == 0) + sign = 1; + } + } + printk("\n"); +} + +void +adpt_hppe_debug_pre_l2_counter_get(a_bool_t show_type) +{ + union pre_l2_cnt_tbl_u pre_l2_cnt_tbl; + a_uint64_t value; + int i, tags, sign; + + sign = tags = 0; + printk("%-35s", "PRE_L2_CNT_TBL RX:"); + for (i = 0; i < PRE_L2_CNT_TBL_MAX_ENTRY; i++) + { + hppe_pre_l2_cnt_tbl_get(0, i, &pre_l2_cnt_tbl); + if (show_type == A_FALSE) + value = (a_uint64_t)pre_l2_cnt_tbl.bf.rx_pkt_cnt; + else + value = pre_l2_cnt_tbl.bf.rx_byte_cnt_0 | ((a_uint64_t)pre_l2_cnt_tbl.bf.rx_byte_cnt_1 << 32); + if (value > 0) + { + if (sign) { + printk("\n"); + printk("%-35s", ""); + } + sign = 0; + printk("%15llu(vsi=%04d)", value, i); + if (++tags % 3 == 0) + sign = 1; + } + } + printk("\n"); + + sign = tags = 0; + printk("%-35s", "PRE_L2_CNT_TBL RX_DROP:"); + for (i = 0; i < PRE_L2_CNT_TBL_MAX_ENTRY; i++) + { + hppe_pre_l2_cnt_tbl_get(0, i, &pre_l2_cnt_tbl); + if (show_type == A_FALSE) + value = pre_l2_cnt_tbl.bf.rx_drop_pkt_cnt_0 | ((a_uint64_t)pre_l2_cnt_tbl.bf.rx_drop_pkt_cnt_1 << 24); + else + value = pre_l2_cnt_tbl.bf.rx_drop_byte_cnt_0 | ((a_uint64_t)pre_l2_cnt_tbl.bf.rx_drop_byte_cnt_1 << 24); + if (value > 0) + { + if (sign) { + printk("\n"); + printk("%-35s", ""); + } + sign = 0; + printk("%15llu(vsi=%04d)", value, i); + if (++tags % 3 == 0) + sign = 1; + } + } + printk("\n"); +} + +void adpt_hppe_debug_port_tx_drop_counter_get(a_bool_t show_type) +{ + union port_tx_drop_cnt_tbl_u port_tx_drop_cnt_tbl; + a_uint64_t value; + int i, tags, sign; + + sign = tags = 0; + printk("%-35s", "PORT_TX_DROP_CNT_TBL TX_DROP:"); + for (i = 0; i < PORT_TX_DROP_CNT_TBL_MAX_ENTRY; i++) + { + hppe_port_tx_drop_cnt_tbl_get(0, i, &port_tx_drop_cnt_tbl); + if (show_type == A_FALSE) + value = (a_uint64_t)port_tx_drop_cnt_tbl.bf.tx_drop_pkt_cnt; + else + value = port_tx_drop_cnt_tbl.bf.tx_drop_byte_cnt_0 | ((a_uint64_t)port_tx_drop_cnt_tbl.bf.tx_drop_byte_cnt_1 << 32); + if (value > 0) + { + if (sign) { + printk("\n"); + printk("%-35s", ""); + } + sign = 0; + printk("%15llu(port=%04d)", value, i); + if (++tags % 3 == 0) + sign = 1; + } + } + printk("\n"); +} + +void +adpt_hppe_debug_eg_vsi_counter_get(a_bool_t show_type) +{ + union eg_vsi_counter_tbl_u eg_vsi_counter_tbl; + a_uint64_t value; + int i, tags, sign; + + sign = tags = 0; + printk("%-35s", "EG_VSI_COUNTER_TBL TX:"); + for (i = 0; i < EG_VSI_COUNTER_TBL_MAX_ENTRY; i++) + { + hppe_eg_vsi_counter_tbl_get(0, i, &eg_vsi_counter_tbl); + if (show_type == A_FALSE) + value = (a_uint64_t)eg_vsi_counter_tbl.bf.tx_packets; + else + value = eg_vsi_counter_tbl.bf.tx_bytes_0 | ((a_uint64_t)eg_vsi_counter_tbl.bf.tx_bytes_1 << 32); + if (value > 0) + { + if (sign) { + printk("\n"); + printk("%-35s", ""); + } + sign = 0; + printk("%15llu(vsi=%04d)", value, i); + if (++tags % 3 == 0) + sign = 1; + } + } + printk("\n"); +} + +void +adpt_hppe_debug_port_tx_counter_get(a_bool_t show_type) +{ + union port_tx_counter_tbl_reg_u port_tx_counter_tbl; + a_uint64_t value; + int i, tags, sign; + + sign = tags = 0; + printk("%-35s", "PORT_TX_COUNTER_TBL TX:"); + for (i = 0; i < PORT_TX_COUNTER_TBL_REG_MAX_ENTRY; i++) + { + hppe_port_tx_counter_tbl_reg_get(0, i, &port_tx_counter_tbl); + if (show_type == A_FALSE) + value = (a_uint64_t)port_tx_counter_tbl.bf.tx_packets; + else + value = port_tx_counter_tbl.bf.tx_bytes_0 | ((a_uint64_t)port_tx_counter_tbl.bf.tx_bytes_1 << 32); + if (value > 0) + { + if (sign) { + printk("\n"); + printk("%-35s", ""); + } + sign = 0; + printk("%15llu(port=%04d)", value, i); + if (++tags % 3 == 0) + sign = 1; + } + } + printk("\n"); +} + +void +adpt_hppe_debug_vp_tx_counter_get(a_bool_t show_type) +{ + union vp_tx_counter_tbl_reg_u vp_tx_counter_tbl; + a_uint64_t value; + int i, tags, sign; + + sign = tags = 0; + printk("%-35s", "VP_TX_COUNTER_TBL TX:"); + for (i = 0; i < VP_TX_COUNTER_TBL_REG_MAX_ENTRY; i++) + { + hppe_vp_tx_counter_tbl_reg_get(0, i, &vp_tx_counter_tbl); + if (show_type == A_FALSE) + value = (a_uint64_t)vp_tx_counter_tbl.bf.tx_packets; + else + value = vp_tx_counter_tbl.bf.tx_bytes_0 | ((a_uint64_t)vp_tx_counter_tbl.bf.tx_bytes_1 << 32); + if (value > 0) + { + if (sign) { + printk("\n"); + printk("%-35s", ""); + } + sign = 0; + printk("%15llu(port=%04d)", value, i); + if (++tags % 3 == 0) + sign = 1; + } + } + printk("\n"); +} + +void +adpt_hppe_debug_queue_tx_counter_get(a_bool_t show_type) +{ + union queue_tx_counter_tbl_u queue_tx_counter_tbl; + a_uint64_t value; + int i, tags, sign; + + sign = tags = 0; + printk("%-35s", "QUEUE_TX_COUNTER_TBL TX:"); + for (i = 0; i < QUEUE_TX_COUNTER_TBL_MAX_ENTRY; i++) + { + hppe_queue_tx_counter_tbl_get(0, i, &queue_tx_counter_tbl); + if (show_type == A_FALSE) + value = (a_uint64_t)queue_tx_counter_tbl.bf.tx_packets; + else + value = queue_tx_counter_tbl.bf.tx_bytes_0 | ((a_uint64_t)queue_tx_counter_tbl.bf.tx_bytes_1 << 32); + if (value > 0) + { + if (sign) { + printk("\n"); + printk("%-35s", ""); + } + sign = 0; + printk("%15llu(queue=%04d)", value, i); + if (++tags % 3 == 0) + sign = 1; + } + } + printk("\n"); +} + +void +adpt_hppe_debug_vp_tx_drop_counter_get(a_bool_t show_type) +{ + union vp_tx_drop_cnt_tbl_u vp_tx_drop_cnt_tbl; + a_uint64_t value; + int i, tags, sign; + + sign = tags = 0; + printk("%-35s", "VP_TX_DROP_CNT_TBL TX_DROP:"); + for (i = 0; i < VP_TX_DROP_CNT_TBL_MAX_ENTRY; i++) + { + hppe_vp_tx_drop_cnt_tbl_get(0, i, &vp_tx_drop_cnt_tbl); + if (show_type == A_FALSE) + value = (a_uint64_t)vp_tx_drop_cnt_tbl.bf.tx_drop_pkt_cnt; + else + value = vp_tx_drop_cnt_tbl.bf.tx_drop_byte_cnt_0 | ((a_uint64_t)vp_tx_drop_cnt_tbl.bf.tx_drop_byte_cnt_1 << 32); + if (value > 0) + { + if (sign) { + printk("\n"); + printk("%-35s", ""); + } + sign = 0; + printk("%15llu(port=%04d)", value, i); + if (++tags % 3 == 0) + sign = 1; + } + } + printk("\n"); +} + +void +adpt_hppe_debug_cpu_code_counter_get(a_bool_t show_type) +{ + union drop_cpu_cnt_tbl_u drop_cpu_cnt_tbl; + a_uint64_t value; + int i, tags, sign; + + sign = tags = 0; + printk("%-35s", "CPU_CODE_CNT_TBL:"); + for (i = 0; i < CPU_CODE_CNT_TBL_MAX_ENTRY; i++) + { + hppe_drop_cpu_cnt_tbl_get(0, i, &drop_cpu_cnt_tbl); + if (show_type == A_FALSE) + value = (a_uint64_t)drop_cpu_cnt_tbl.bf.pkt_cnt; + else + value = drop_cpu_cnt_tbl.bf.byte_cnt_0 | ((a_uint64_t)drop_cpu_cnt_tbl.bf.byte_cnt_1 << 32); + if (value > 0) + { + printk("\n"); + printk("%-35s", ""); + if (i >=0 && i <= 70) + printk("%15llu(%s)", value, cpucode[i]); + else if (i >= 79 && i <= 92) + printk("%15llu(%s)", value, cpucode[i - 8]); + else if (i >= 97 && i <= 102) + printk("%15llu(%s)", value, cpucode[i - 12]); + else if (i >= 107 && i <= 110) + printk("%15llu(%s)", value, cpucode[i - 16]); + else if (i >= 113 && i <= 127) + printk("%15llu(%s)", value, cpucode[i - 18]); + else if (i >= 136 && i <= 143) + printk("%15llu(%s)", value, cpucode[i - 26]); + else if (i >= 148 && i <= 174) + printk("%15llu(%s)", value, cpucode[i - 30]); + else if (i >= 178 && i <= 180) + printk("%15llu(%s)", value, cpucode[i - 33]); + else if (i >= 254 && i <= 255) + printk("%15llu(%s)", value, cpucode[i - 106]); + else + printk("%15llu(Reserved)", value); + } + } + printk("\n"); +} + +void +adpt_hppe_debug_drop_cpu_counter_get(a_bool_t show_type) +{ + union drop_cpu_cnt_tbl_u drop_cpu_cnt_tbl; + a_uint64_t value; + int i, tags, sign; + + sign = tags = 0; + printk("%-35s", "DROP_CPU_CNT_TBL:"); + for (i = CPU_CODE_CNT_TBL_MAX_ENTRY; i < DROP_CPU_CNT_TBL_MAX_ENTRY; i++) + { + hppe_drop_cpu_cnt_tbl_get(0, i, &drop_cpu_cnt_tbl); + if (show_type == A_FALSE) + value = (a_uint64_t)drop_cpu_cnt_tbl.bf.pkt_cnt; + else + value = drop_cpu_cnt_tbl.bf.byte_cnt_0 | ((a_uint64_t)drop_cpu_cnt_tbl.bf.byte_cnt_1 << 32); + if (value > 0) + { + printk("\n"); + printk("%-35s", ""); + printk("%15llu(port=%d:%s)", value, (i - 256) % 8, dropcode[(i - 256) / 8]); + } + } + printk("\n"); +} + +/* if show_type = A_FALSE, show packets. + * if show_type = A_TRUE, show bytes. + */ +sw_error_t +adpt_hppe_debug_counter_get(a_bool_t show_type) +{ + /* show PRX DROP_CNT */ + adpt_hppe_debug_prx_drop_cnt_get(); + + /* show PRX DROP_PKT_STAT */ + adpt_hppe_debug_prx_drop_pkt_stat_get(show_type); + + /* show IPR_PKT_NUM */ + adpt_hppe_debug_ipx_pkt_num_get(show_type); + + /* show VLAN_CNT_TBL */ + adpt_hppe_debug_vlan_counter_get(show_type); + + /* show PRE_L2_CNT_TBL */ + adpt_hppe_debug_pre_l2_counter_get(show_type); + + /* show PORT_TX_DROP_CNT_TBL */ + adpt_hppe_debug_port_tx_drop_counter_get(show_type); + + /* show EG_VSI_COUNTER_TBL */ + adpt_hppe_debug_eg_vsi_counter_get(show_type); + + /* show PORT_TX_COUNTER_TBL */ + adpt_hppe_debug_port_tx_counter_get(show_type); + + /* show VP_TX_COUNTER_TBL */ + adpt_hppe_debug_vp_tx_counter_get(show_type); + + /* show QUEUE_TX_COUNTER_TBL */ + adpt_hppe_debug_queue_tx_counter_get(show_type); + + /* show VP_TX_DROP_CNT_TBL */ + adpt_hppe_debug_vp_tx_drop_counter_get(show_type); + + /* show CPU_CODE_CNT */ + adpt_hppe_debug_cpu_code_counter_get(show_type); + + /* show DROP_CPU_CNT_TBL */ + adpt_hppe_debug_drop_cpu_counter_get(show_type); + + return SW_OK; +} +#endif +sw_error_t adpt_hppe_misc_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) { + return SW_FAIL; + } + +#ifndef IN_MISC_MINI + p_adpt_api->adpt_debug_port_counter_enable = adpt_ppe_debug_port_counter_enable; + p_adpt_api->adpt_debug_port_counter_status_get = adpt_ppe_debug_port_counter_status_get; + + p_adpt_api->adpt_debug_counter_set = adpt_hppe_debug_counter_set; + p_adpt_api->adpt_debug_counter_get = adpt_hppe_debug_counter_get; +#endif + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_policer.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_policer.c new file mode 100755 index 000000000..7ffcf1318 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_policer.c @@ -0,0 +1,1080 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hppe_policer_reg.h" +#include "hppe_policer.h" +#include "adpt.h" + +#define NR_ADPT_HPPE_POLICER_METER_UNIT 2 +#define NR_ADPT_HPPE_POLICER_METER_TOKEN_UNIT 8 +#define ADPT_HPPE_POLICER_METER_UNIT_BYTE 0 +#define ADPT_HPPE_POLICER_METER_UNIT_FRAME 1 +#define ADPT_HPPE_FREQUENCY 300 /*MHZ*/ +#define ADPT_HPPE_POLICER_BURST_SIZE_UNIT 65536 +#define ADPT_HPPE_POLICER_REFRESH_BITS 18 +#define ADPT_HPPE_POLICER_BUCKET_SIZE_BITS 16 +#define ADPT_HPPE_POLICER_REFRESH_MAX ((1 << ADPT_HPPE_POLICER_REFRESH_BITS) - 1) +#define ADPT_HPPE_POLICER_BUCKET_SIZE_MAX ((1 << ADPT_HPPE_POLICER_BUCKET_SIZE_BITS) - 1) +#define BYTE_POLICER_MAX_RATE 10000000 +#define BYTE_POLICER_MIN_RATE 64 +#define FRAME_POLICER_MAX_RATE 14881000 +#define FRAME_POLICER_MIN_RATE 6 + + +static a_uint32_t hppe_policer_token_unit[NR_ADPT_HPPE_POLICER_METER_UNIT] + [NR_ADPT_HPPE_POLICER_METER_TOKEN_UNIT] = {{2048 * 8, + 512 * 8,128 * 8,32 * 8,8 * 8,2 * 8, 4, 1}, + {2097152,524288,131072,32768,8192,2048,512,128}}; + +typedef struct +{ + a_uint64_t rate_1bit; + a_uint64_t rate_max; +} adpt_hppe_policer_rate_t; + +typedef struct +{ + a_uint64_t burst_size_1bit; + a_uint64_t burst_size_max; +} adpt_hppe_policer_burst_size_t; + +static adpt_hppe_policer_rate_t +hppe_policer_rate[NR_ADPT_HPPE_POLICER_METER_UNIT][NR_ADPT_HPPE_POLICER_METER_TOKEN_UNIT] = +{ + /* byte based*/ + { + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + }, + + /*frame based */ + { + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + }, +}; + +static adpt_hppe_policer_burst_size_t +hppe_policer_burst_size[NR_ADPT_HPPE_POLICER_METER_UNIT][NR_ADPT_HPPE_POLICER_METER_TOKEN_UNIT] = +{ + { {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}, + }, +}; + +#ifndef IN_POLICER_MINI +sw_error_t +adpt_hppe_acl_policer_counter_get(a_uint32_t dev_id, a_uint32_t index, + fal_policer_counter_t *counter) +{ + union in_acl_meter_cnt_tbl_u in_acl_meter_cnt_tbl; + + memset(&in_acl_meter_cnt_tbl, 0, sizeof(in_acl_meter_cnt_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(counter); + + if (index < 0 || index > 511) + return SW_BAD_PARAM; + + hppe_in_acl_meter_cnt_tbl_get(dev_id, index * 3, &in_acl_meter_cnt_tbl); + counter->green_packet_counter = in_acl_meter_cnt_tbl.bf.pkt_cnt; + counter->green_byte_counter = in_acl_meter_cnt_tbl.bf.byte_cnt_1; + counter->green_byte_counter = (counter->green_byte_counter << 32) | in_acl_meter_cnt_tbl.bf.byte_cnt_0; + + hppe_in_acl_meter_cnt_tbl_get(dev_id, index * 3 + 1, &in_acl_meter_cnt_tbl); + counter->yellow_packet_counter = in_acl_meter_cnt_tbl.bf.pkt_cnt; + counter->yellow_byte_counter = in_acl_meter_cnt_tbl.bf.byte_cnt_1; + counter->yellow_byte_counter = (counter->yellow_byte_counter << 32) | in_acl_meter_cnt_tbl.bf.byte_cnt_0; + + hppe_in_acl_meter_cnt_tbl_get(dev_id, index * 3 + 2, &in_acl_meter_cnt_tbl); + counter->red_packet_counter = in_acl_meter_cnt_tbl.bf.pkt_cnt; + counter->red_byte_counter = in_acl_meter_cnt_tbl.bf.byte_cnt_1; + counter->red_byte_counter = (counter->red_byte_counter << 32) | in_acl_meter_cnt_tbl.bf.byte_cnt_0; + + return SW_OK; +} + +sw_error_t +adpt_hppe_port_policer_counter_get(a_uint32_t dev_id, fal_port_t port_id, + fal_policer_counter_t *counter) +{ + union in_port_meter_cnt_tbl_u in_port_meter_cnt_tbl; + + memset(&in_port_meter_cnt_tbl, 0, sizeof(in_port_meter_cnt_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(counter); + + if (port_id < 0 || port_id > 7) + return SW_BAD_PARAM; + + hppe_in_port_meter_cnt_tbl_get(dev_id, port_id * 3, &in_port_meter_cnt_tbl); + counter->green_packet_counter = in_port_meter_cnt_tbl.bf.pkt_cnt; + counter->green_byte_counter = in_port_meter_cnt_tbl.bf.byte_cnt_1; + counter->green_byte_counter = (counter->green_byte_counter << 32) | in_port_meter_cnt_tbl.bf.byte_cnt_0; + + hppe_in_port_meter_cnt_tbl_get(dev_id, port_id * 3 + 1, &in_port_meter_cnt_tbl); + counter->yellow_packet_counter = in_port_meter_cnt_tbl.bf.pkt_cnt; + counter->yellow_byte_counter = in_port_meter_cnt_tbl.bf.byte_cnt_1; + counter->yellow_byte_counter = (counter->yellow_byte_counter << 32) | in_port_meter_cnt_tbl.bf.byte_cnt_0; + + hppe_in_port_meter_cnt_tbl_get(dev_id, port_id * 3 + 2, &in_port_meter_cnt_tbl); + counter->red_packet_counter = in_port_meter_cnt_tbl.bf.pkt_cnt; + counter->red_byte_counter = in_port_meter_cnt_tbl.bf.byte_cnt_1; + counter->red_byte_counter = (counter->red_byte_counter << 32) | in_port_meter_cnt_tbl.bf.byte_cnt_0; + + return SW_OK; +} + +sw_error_t +adpt_hppe_port_compensation_byte_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t *length) +{ + sw_error_t rv = SW_OK; + union meter_cmpst_length_reg_u meter_cmpst_length_reg; + + memset(&meter_cmpst_length_reg, 0, sizeof(meter_cmpst_length_reg)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(length); + + if (port_id < 0 || port_id > 7) + return SW_BAD_PARAM; + + rv = hppe_meter_cmpst_length_reg_get(dev_id, port_id, &meter_cmpst_length_reg); + + if( rv != SW_OK ) + return rv; + + *length = meter_cmpst_length_reg.bf.cmpst_length; + + return SW_OK; +} + +static sw_error_t +__adpt_hppe_policer_rate_to_refresh(a_uint32_t rate, + a_uint32_t *refresh, + a_bool_t meter_unit, + a_uint32_t token_unit) +{ + a_uint32_t temp_refresh; + a_uint64_t temp_rate; + + if(hppe_policer_rate[meter_unit][token_unit].rate_1bit > 0) + { + temp_rate = ((a_uint64_t)rate) * 1000; + do_div(temp_rate, hppe_policer_rate[meter_unit][token_unit].rate_1bit); + temp_refresh = temp_rate; + } + else + { + return SW_BAD_PARAM;; + } + + if (temp_refresh > ADPT_HPPE_POLICER_REFRESH_MAX) + { + temp_refresh = ADPT_HPPE_POLICER_REFRESH_MAX; + } + + *refresh = temp_refresh; + + return SW_OK; +} + +static sw_error_t +__adpt_hppe_policer_burst_size_to_bucket_size(a_uint32_t burst_size, + a_uint32_t *bucket_size, + a_bool_t meter_unit, + a_uint32_t token_unit) +{ + a_uint32_t temp_bucket_size; + a_uint64_t temp_burst_size; + + if(hppe_policer_burst_size[meter_unit][token_unit].burst_size_1bit > 0) + { + temp_burst_size = ((a_uint64_t)burst_size) * 1000; + do_div(temp_burst_size, hppe_policer_burst_size[meter_unit][token_unit].burst_size_1bit); + temp_bucket_size = temp_burst_size; + } + else + { + return SW_BAD_PARAM; + } + + if(temp_bucket_size > ADPT_HPPE_POLICER_BUCKET_SIZE_MAX) + { + temp_bucket_size = ADPT_HPPE_POLICER_BUCKET_SIZE_MAX; + } + + *bucket_size = temp_bucket_size; + + return SW_OK; +} + +static sw_error_t +__adpt_hppe_policer_refresh_to_rate(a_uint32_t refresh, + a_uint32_t *rate, + a_bool_t meter_unit, + a_uint32_t token_unit) +{ + a_uint32_t temp_rate; + a_uint64_t temp_refresh; + + if(hppe_policer_rate[meter_unit][token_unit].rate_1bit > 0) + { + temp_refresh = ((a_uint64_t)refresh) * hppe_policer_rate[meter_unit][token_unit].rate_1bit; + do_div(temp_refresh, 1000); + temp_rate = temp_refresh; + } + else + { + return SW_BAD_PARAM;; + } + + *rate = temp_rate; + + return SW_OK; +} + +static sw_error_t +__adpt_hppe_policer_bucket_size_to_burst_size(a_uint32_t bucket_size, + a_uint32_t *burst_size, + a_bool_t meter_unit, + a_uint32_t token_unit) +{ + a_uint32_t temp_burst_size; + a_uint64_t temp_bucket_size; + + if(hppe_policer_burst_size[meter_unit][token_unit].burst_size_1bit > 0) + { + temp_bucket_size = ((a_uint64_t)bucket_size) * hppe_policer_burst_size[meter_unit][token_unit].burst_size_1bit; + do_div(temp_bucket_size, 1000); + temp_burst_size = temp_bucket_size; + } + else + { + return SW_BAD_PARAM; + } + + *burst_size = temp_burst_size; + + return SW_OK; +} +#endif + +static sw_error_t +__adpt_hppe_policer_max_rate(a_uint32_t time_slot) +{ + a_uint32_t i = 0, j = 0; + a_uint32_t time_cycle = 0; + a_uint64_t temp = 0, temp1 = 0, temp2 = 0; + + + /* time_cycle is ns*/ + time_cycle = ( time_slot * 8)/ ADPT_HPPE_FREQUENCY; + + for (j = 0; j < 8; j++) + { + /*max rate is bps*/ + temp1 = (a_uint64_t)(ADPT_HPPE_POLICER_REFRESH_MAX * 1000 * 8) * 1000; + temp2 = hppe_policer_token_unit[i][j] * time_cycle; + + do_div(temp1, temp2); + hppe_policer_rate[i][j].rate_max= temp1; + + temp = temp1; + do_div(temp, ADPT_HPPE_POLICER_REFRESH_MAX); + hppe_policer_rate[i][j].rate_1bit = temp; + + // printk("hppe policer byte max_rate generating =%llu\n", hppe_policer_rate[i][j].rate_max); + // printk("hppe policer byte based step =%llu\n", hppe_policer_rate[i][j].rate_1bit); + } + + i = i + 1; + for (j = 0; j < 8; j++) + { + /* max rate unit is 1/1000 pps*/ + temp1 = (a_uint64_t)(ADPT_HPPE_POLICER_REFRESH_MAX * 1000) * 1000 * 1000; + temp2 = (a_uint64_t)hppe_policer_token_unit[i][j] * time_cycle; + + do_div(temp1, temp2); + hppe_policer_rate[i][j].rate_max = temp1; + + temp = temp1; + do_div(temp, ADPT_HPPE_POLICER_REFRESH_MAX); + hppe_policer_rate[i][j].rate_1bit = temp; + + // printk("policer frame hppe_max_rate generating =%llu\n", hppe_policer_rate[i][j].rate_max); + // printk("policer frame step rate =%llu\n", hppe_policer_rate[i][j].rate_1bit); + } + + return SW_OK; +} + +static sw_error_t +__adpt_hppe_policer_max_burst_size(void) +{ + a_uint32_t i = 0, j = 0; + a_uint64_t temp = 0, temp1 = 0; + + + for (j = 0; j < 8; j++) + { + /*max size unit is 1/1000 byte based*/ + temp = ((a_uint64_t)(ADPT_HPPE_POLICER_BURST_SIZE_UNIT)) * + ADPT_HPPE_POLICER_BUCKET_SIZE_MAX; + do_div(temp, hppe_policer_token_unit[i][j]); + hppe_policer_burst_size[i][j].burst_size_max = (a_uint64_t)(temp * 1000); + + temp1 = hppe_policer_burst_size[i][j].burst_size_max; + do_div(temp1, ADPT_HPPE_POLICER_BUCKET_SIZE_MAX); + hppe_policer_burst_size[i][j].burst_size_1bit = temp1; + + /* + printk("policer byte hppe_max_burst_size generating =%llu\n", + hppe_policer_burst_size[i][j].burst_size_max); + printk("policer byte hppe_max_burst_size step =%llu\n", + hppe_policer_burst_size[i][j].burst_size_1bit); + */ + + } + + i = i + 1; + for (j = 0; j < 8; j++) + { + /* max size unit is 1/1000 frame based */ + temp = ((a_uint64_t)(ADPT_HPPE_POLICER_BURST_SIZE_UNIT)) * + ADPT_HPPE_POLICER_BUCKET_SIZE_MAX; + do_div(temp, hppe_policer_token_unit[i][j]); + hppe_policer_burst_size[i][j].burst_size_max = (a_uint64_t)(temp * 1000); + + temp1 = hppe_policer_burst_size[i][j].burst_size_max; + do_div(temp1, ADPT_HPPE_POLICER_BUCKET_SIZE_MAX); + hppe_policer_burst_size[i][j].burst_size_1bit = temp1; + + /* + printk("policer frame hppe_max_burst_size generating =%llu\n", + hppe_policer_burst_size[i][j].burst_size_max); + printk("policer frame hppe_max_burst_size step =%llu\n", + hppe_policer_burst_size[i][j].burst_size_1bit); + */ + + } + + return SW_OK; +} + +#ifndef IN_POLICER_MINI +static sw_error_t +__adpt_hppe_policer_two_bucket_parameter_select(a_uint64_t c_rate, + a_uint64_t c_burst_size, + a_uint64_t e_rate, + a_uint64_t e_burst_size, + a_uint32_t meter_unit, + a_uint32_t *token_unit) +{ + a_uint32_t temp_token_unit; + a_uint32_t match = A_FALSE; + a_uint64_t temp_rate = 0, temp_burst_size = 0; + + if(c_rate > e_rate) + temp_rate = c_rate; + else + temp_rate = e_rate; + + if(c_burst_size > e_burst_size) + temp_burst_size = c_burst_size; + else + temp_burst_size = e_burst_size; + + for (temp_token_unit = 0; temp_token_unit < 8; temp_token_unit++) + { + if (temp_rate > hppe_policer_rate[meter_unit][temp_token_unit].rate_max) + { + continue; + } + else if(temp_burst_size <= hppe_policer_burst_size[meter_unit][temp_token_unit].burst_size_max) + { + *token_unit = temp_token_unit; + match = A_TRUE; + break; + } + } + + if (match == A_FALSE) + { + printk("Not match C and E token bucket parameter rate configuration \n"); + return SW_BAD_PARAM; + } + + return SW_OK; +} + +#if 0 +static sw_error_t +__adpt_hppe_policer_one_bucket_parameter_select(a_uint64_t c_rate, + a_uint64_t c_burst_size, + a_uint32_t meter_unit, + a_uint32_t *token_unit) +{ + a_uint32_t temp_token_unit; + a_uint32_t match = A_FALSE; + + for (temp_token_unit = 0; temp_token_unit < 8; temp_token_unit++) + { + if (c_rate > hppe_policer_rate[meter_unit][temp_token_unit].rate_max) + { + continue; + } + else if (c_burst_size <= hppe_policer_burst_size[meter_unit][temp_token_unit].burst_size_max) + { + *token_unit = temp_token_unit; + match = A_TRUE; + break; + } + } + + if (match == A_FALSE) + { + printk("Not match policer C token bucket parameter rate configuration \n"); + return SW_BAD_PARAM; + } + + return SW_OK; +} +#endif + +sw_error_t +adpt_hppe_port_policer_entry_get(a_uint32_t dev_id, fal_port_t port_id, + fal_policer_config_t *policer, fal_policer_action_t *action) +{ + union in_port_meter_cfg_tbl_u in_port_meter_cfg_tbl; + a_uint32_t hppe_cir =0, hppe_cbs = 0, hppe_eir = 0,hppe_ebs = 0; + + memset(&in_port_meter_cfg_tbl, 0, sizeof(in_port_meter_cfg_tbl)); + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(policer); + ADPT_NULL_POINT_CHECK(action); + + if (port_id < 0 || port_id > 7) + return SW_BAD_PARAM; + + hppe_in_port_meter_cfg_tbl_get(dev_id, port_id, &in_port_meter_cfg_tbl); + + hppe_cir = (in_port_meter_cfg_tbl.bf.cir_1 << 3) | in_port_meter_cfg_tbl.bf.cir_0; + hppe_cbs = in_port_meter_cfg_tbl.bf.cbs; + hppe_eir = (in_port_meter_cfg_tbl.bf.eir_1 << 1) | in_port_meter_cfg_tbl.bf.eir_0; + hppe_ebs = in_port_meter_cfg_tbl.bf.ebs; + + + __adpt_hppe_policer_refresh_to_rate(hppe_cir, + &policer->cir, + in_port_meter_cfg_tbl.bf.meter_unit, + in_port_meter_cfg_tbl.bf.token_unit); + + __adpt_hppe_policer_refresh_to_rate(hppe_eir, + &policer->eir, + in_port_meter_cfg_tbl.bf.meter_unit, + in_port_meter_cfg_tbl.bf.token_unit); + + __adpt_hppe_policer_bucket_size_to_burst_size(hppe_cbs, + &policer->cbs, + in_port_meter_cfg_tbl.bf.meter_unit, + in_port_meter_cfg_tbl.bf.token_unit); + + __adpt_hppe_policer_bucket_size_to_burst_size(hppe_ebs, + &policer->ebs, + in_port_meter_cfg_tbl.bf.meter_unit, + in_port_meter_cfg_tbl.bf.token_unit); + + policer->meter_en = in_port_meter_cfg_tbl.bf.meter_en; + policer->color_mode = in_port_meter_cfg_tbl.bf.color_mode; + policer->frame_type = in_port_meter_cfg_tbl.bf.meter_flag; + policer->couple_en = in_port_meter_cfg_tbl.bf.coupling_flag; + policer->meter_mode = in_port_meter_cfg_tbl.bf.meter_mode; + policer->meter_unit = in_port_meter_cfg_tbl.bf.meter_unit; + action->yellow_priority_en = in_port_meter_cfg_tbl.bf.exceed_chg_pri_cmd; + action->yellow_drop_priority_en = in_port_meter_cfg_tbl.bf.exceed_chg_dp_cmd; + action->yellow_pcp_en = in_port_meter_cfg_tbl.bf.exceed_chg_pcp_cmd; + action->yellow_dei_en = in_port_meter_cfg_tbl.bf.exceed_chg_dei_cmd; + action->yellow_priority = in_port_meter_cfg_tbl.bf.exceed_pri; + action->yellow_drop_priority = in_port_meter_cfg_tbl.bf.exceed_dp; + action->yellow_pcp = in_port_meter_cfg_tbl.bf.exceed_pcp; + action->yellow_dei = in_port_meter_cfg_tbl.bf.exceed_dei; + if (in_port_meter_cfg_tbl.bf.violate_cmd == 0) + action->red_action = FAL_MAC_DROP; + else + action->red_action = FAL_MAC_FRWRD; + action->red_priority_en = in_port_meter_cfg_tbl.bf.violate_chg_pri_cmd; + action->red_drop_priority_en = in_port_meter_cfg_tbl.bf.violate_chg_dp_cmd; + action->red_pcp_en = in_port_meter_cfg_tbl.bf.violate_chg_pcp_cmd; + action->red_dei_en = in_port_meter_cfg_tbl.bf.violate_chg_dei_cmd; + action->red_priority = in_port_meter_cfg_tbl.bf.violate_pri; + action->red_drop_priority = in_port_meter_cfg_tbl.bf.violate_dp; + action->red_pcp = in_port_meter_cfg_tbl.bf.violate_pcp; + action->red_dei = in_port_meter_cfg_tbl.bf.violate_dei; + + return SW_OK; +} + +sw_error_t +adpt_hppe_port_policer_entry_set(a_uint32_t dev_id, fal_port_t port_id, + fal_policer_config_t *policer, fal_policer_action_t *action) +{ + union in_port_meter_cfg_tbl_u in_port_meter_cfg_tbl; + a_uint32_t hppe_cir = 0, hppe_cbs = 0, hppe_eir = 0,hppe_ebs = 0; + a_uint64_t temp_cir = 0, temp_eir =0, temp_cbs =0, temp_ebs = 0; + a_uint32_t token_unit = 0; + sw_error_t rv = SW_OK; + + memset(&in_port_meter_cfg_tbl, 0, sizeof(in_port_meter_cfg_tbl)); + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(policer); + ADPT_NULL_POINT_CHECK(action); + + if (port_id < 0 || port_id > 7) + return SW_BAD_PARAM; + + if(ADPT_HPPE_POLICER_METER_UNIT_BYTE == policer->meter_unit) + { + if ((policer->cir > BYTE_POLICER_MAX_RATE) || (policer->eir > BYTE_POLICER_MAX_RATE)) + return SW_BAD_PARAM; + if ((policer->cir < BYTE_POLICER_MIN_RATE) && (policer->cir != 0)) + return SW_BAD_PARAM; + if ((policer->eir < BYTE_POLICER_MIN_RATE) && (policer->eir != 0)) + return SW_BAD_PARAM; + } + + if(ADPT_HPPE_POLICER_METER_UNIT_FRAME == policer->meter_unit) + { + if ((policer->cir > FRAME_POLICER_MAX_RATE) || (policer->eir > FRAME_POLICER_MAX_RATE)) + return SW_BAD_PARAM; + if ((policer->cir < FRAME_POLICER_MIN_RATE) && (policer->cir != 0)) + return SW_BAD_PARAM; + if ((policer->eir < FRAME_POLICER_MIN_RATE) && (policer->eir != 0)) + return SW_BAD_PARAM; + } + + if((0 == policer->meter_mode) && (policer->cir > policer->eir)) + return SW_BAD_PARAM; + + temp_cir = ((a_uint64_t)policer->cir) * 1000; + temp_cbs = ((a_uint64_t)policer->cbs) * 1000; + temp_eir = ((a_uint64_t)policer->eir) * 1000; + temp_ebs = ((a_uint64_t)policer->ebs) * 1000; + + rv = __adpt_hppe_policer_two_bucket_parameter_select(temp_cir, + temp_cbs, + temp_eir, + temp_ebs, + policer->meter_unit, + &token_unit); + if( rv != SW_OK ) + return rv; + +// printk("current meter unit is = %d\n", policer->meter_unit); +// printk("current token unit is = %d\n", token_unit); + + __adpt_hppe_policer_rate_to_refresh(policer->cir, + &hppe_cir, + policer->meter_unit, + token_unit); + + __adpt_hppe_policer_rate_to_refresh(policer->eir, + &hppe_eir, + policer->meter_unit, + token_unit); + + __adpt_hppe_policer_burst_size_to_bucket_size(policer->cbs, + &hppe_cbs, + policer->meter_unit, + token_unit); + + __adpt_hppe_policer_burst_size_to_bucket_size(policer->ebs, + &hppe_ebs, + policer->meter_unit, + token_unit); + + in_port_meter_cfg_tbl.bf.meter_en = policer->meter_en; + in_port_meter_cfg_tbl.bf.color_mode = policer->color_mode; + in_port_meter_cfg_tbl.bf.meter_flag = policer->frame_type; + in_port_meter_cfg_tbl.bf.coupling_flag = policer->couple_en; + in_port_meter_cfg_tbl.bf.meter_mode = policer->meter_mode; + in_port_meter_cfg_tbl.bf.token_unit = token_unit; + in_port_meter_cfg_tbl.bf.meter_unit = (a_uint32_t)policer->meter_unit; + in_port_meter_cfg_tbl.bf.cbs = hppe_cbs; + in_port_meter_cfg_tbl.bf.cir_0 = hppe_cir & 0x7; + in_port_meter_cfg_tbl.bf.cir_1 = hppe_cir >> 3; + in_port_meter_cfg_tbl.bf.ebs = hppe_ebs; + in_port_meter_cfg_tbl.bf.eir_0 = hppe_eir & 0x1; + in_port_meter_cfg_tbl.bf.eir_1 = hppe_eir >> 1; + in_port_meter_cfg_tbl.bf.exceed_chg_pri_cmd = action->yellow_priority_en; + in_port_meter_cfg_tbl.bf.exceed_chg_dp_cmd = action->yellow_drop_priority_en; + in_port_meter_cfg_tbl.bf.exceed_chg_pcp_cmd = action->yellow_pcp_en; + in_port_meter_cfg_tbl.bf.exceed_chg_dei_cmd = action->yellow_dei_en; + in_port_meter_cfg_tbl.bf.exceed_pri = action->yellow_priority; + in_port_meter_cfg_tbl.bf.exceed_dp = action->yellow_drop_priority; + in_port_meter_cfg_tbl.bf.exceed_pcp = action->yellow_pcp; + in_port_meter_cfg_tbl.bf.exceed_dei = action->yellow_dei; + if (action->red_action == FAL_MAC_DROP) + in_port_meter_cfg_tbl.bf.violate_cmd = 0; + else + in_port_meter_cfg_tbl.bf.violate_cmd = 1; + in_port_meter_cfg_tbl.bf.violate_chg_pri_cmd = action->red_priority_en; + in_port_meter_cfg_tbl.bf.violate_chg_dp_cmd = action->red_drop_priority_en; + in_port_meter_cfg_tbl.bf.violate_chg_pcp_cmd = action->red_pcp_en; + in_port_meter_cfg_tbl.bf.violate_chg_dei_cmd = action->red_dei_en; + in_port_meter_cfg_tbl.bf.violate_pri = action->red_priority; + in_port_meter_cfg_tbl.bf.violate_dp = action->red_drop_priority; + in_port_meter_cfg_tbl.bf.violate_pcp = action->red_pcp; + in_port_meter_cfg_tbl.bf.violate_dei = action->red_dei; + + hppe_in_port_meter_cfg_tbl_set(dev_id, port_id, &in_port_meter_cfg_tbl); + + return SW_OK; + +} +sw_error_t +adpt_hppe_acl_policer_entry_get(a_uint32_t dev_id, a_uint32_t index, + fal_policer_config_t *policer, fal_policer_action_t *action) +{ + union in_acl_meter_cfg_tbl_u in_acl_meter_cfg_tbl; + a_uint32_t hppe_cir =0, hppe_cbs = 0, hppe_eir = 0,hppe_ebs = 0; + + memset(&in_acl_meter_cfg_tbl, 0, sizeof(in_acl_meter_cfg_tbl)); + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(policer); + ADPT_NULL_POINT_CHECK(action); + + if (index < 0 || index > 511) + return SW_BAD_PARAM; + + hppe_in_acl_meter_cfg_tbl_get(dev_id, index, &in_acl_meter_cfg_tbl); + + hppe_cir = (in_acl_meter_cfg_tbl.bf.cir_1 << 8) | in_acl_meter_cfg_tbl.bf.cir_0; + hppe_cbs = in_acl_meter_cfg_tbl.bf.cbs; + hppe_eir = (in_acl_meter_cfg_tbl.bf.eir_1 << 6) | in_acl_meter_cfg_tbl.bf.eir_0; + hppe_ebs = in_acl_meter_cfg_tbl.bf.ebs; + + __adpt_hppe_policer_refresh_to_rate(hppe_cir, + &policer->cir, + in_acl_meter_cfg_tbl.bf.meter_unit, + in_acl_meter_cfg_tbl.bf.token_unit); + + __adpt_hppe_policer_refresh_to_rate(hppe_eir, + &policer->eir, + in_acl_meter_cfg_tbl.bf.meter_unit, + in_acl_meter_cfg_tbl.bf.token_unit); + + __adpt_hppe_policer_bucket_size_to_burst_size(hppe_cbs, + &policer->cbs, + in_acl_meter_cfg_tbl.bf.meter_unit, + in_acl_meter_cfg_tbl.bf.token_unit); + + __adpt_hppe_policer_bucket_size_to_burst_size(hppe_ebs, + &policer->ebs, + in_acl_meter_cfg_tbl.bf.meter_unit, + in_acl_meter_cfg_tbl.bf.token_unit); + + policer->meter_en = in_acl_meter_cfg_tbl.bf.meter_en; + policer->color_mode = in_acl_meter_cfg_tbl.bf.color_mode; + policer->couple_en= in_acl_meter_cfg_tbl.bf.coupling_flag; + policer->meter_mode = in_acl_meter_cfg_tbl.bf.meter_mode; + policer->meter_unit = in_acl_meter_cfg_tbl.bf.meter_unit; + action->yellow_priority_en = in_acl_meter_cfg_tbl.bf.exceed_chg_pri_cmd; + action->yellow_drop_priority_en = in_acl_meter_cfg_tbl.bf.exceed_chg_dp_cmd; + action->yellow_pcp_en = in_acl_meter_cfg_tbl.bf.exceed_chg_pcp_cmd; + action->yellow_dei_en = in_acl_meter_cfg_tbl.bf.exceed_chg_dei_cmd; + action->yellow_priority = in_acl_meter_cfg_tbl.bf.exceed_pri; + action->yellow_drop_priority = in_acl_meter_cfg_tbl.bf.exceed_dp; + action->yellow_pcp = in_acl_meter_cfg_tbl.bf.exceed_pcp; + action->yellow_dei = in_acl_meter_cfg_tbl.bf.exceed_dei; + if (in_acl_meter_cfg_tbl.bf.violate_cmd == 0) + action->red_action = FAL_MAC_DROP; + else + action->red_action = FAL_MAC_FRWRD; + action->red_priority_en = in_acl_meter_cfg_tbl.bf.violate_chg_pri_cmd; + action->red_drop_priority_en = in_acl_meter_cfg_tbl.bf.violate_chg_dp_cmd; + action->red_pcp_en = in_acl_meter_cfg_tbl.bf.violate_chg_pcp_cmd; + action->red_dei_en = in_acl_meter_cfg_tbl.bf.violate_chg_dei_cmd; + action->red_priority = (in_acl_meter_cfg_tbl.bf.violate_pri_1 << 1) |in_acl_meter_cfg_tbl.bf.violate_pri_0; + action->red_drop_priority = in_acl_meter_cfg_tbl.bf.violate_dp; + action->red_pcp = in_acl_meter_cfg_tbl.bf.violate_pcp; + action->red_dei = in_acl_meter_cfg_tbl.bf.violate_dei; + + return SW_OK; +} + +sw_error_t +adpt_hppe_acl_policer_entry_set(a_uint32_t dev_id, a_uint32_t index, + fal_policer_config_t *policer, fal_policer_action_t *action) +{ + union in_acl_meter_cfg_tbl_u in_acl_meter_cfg_tbl; + a_uint32_t hppe_cir =0, hppe_cbs = 0, hppe_eir = 0,hppe_ebs = 0; + a_uint64_t temp_cir = 0, temp_eir =0, temp_cbs =0, temp_ebs = 0; + a_uint32_t token_unit = 0; + sw_error_t rv = SW_OK; + + memset(&in_acl_meter_cfg_tbl, 0, sizeof(in_acl_meter_cfg_tbl)); + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(policer); + ADPT_NULL_POINT_CHECK(action); + + if (index < 0 || index > 511) + return SW_BAD_PARAM; + + if(ADPT_HPPE_POLICER_METER_UNIT_BYTE == policer->meter_unit) + { + if ((policer->cir > BYTE_POLICER_MAX_RATE) || (policer->eir > BYTE_POLICER_MAX_RATE)) + return SW_BAD_PARAM; + if ((policer->cir < BYTE_POLICER_MIN_RATE) && (policer->cir != 0)) + return SW_BAD_PARAM; + if ((policer->eir < BYTE_POLICER_MIN_RATE) && (policer->eir != 0)) + return SW_BAD_PARAM; + } + + if(ADPT_HPPE_POLICER_METER_UNIT_FRAME == policer->meter_unit) + { + if ((policer->cir > FRAME_POLICER_MAX_RATE) || (policer->eir > FRAME_POLICER_MAX_RATE)) + return SW_BAD_PARAM; + if ((policer->cir < FRAME_POLICER_MIN_RATE) && (policer->cir != 0)) + return SW_BAD_PARAM; + if ((policer->eir < FRAME_POLICER_MIN_RATE) && (policer->eir != 0)) + return SW_BAD_PARAM; + } + + if((0 == policer->meter_mode) && (policer->cir > policer->eir)) + return SW_BAD_PARAM; + + temp_cir = ((a_uint64_t)policer->cir) * 1000; + temp_cbs = ((a_uint64_t)policer->cbs) * 1000; + temp_eir = ((a_uint64_t)policer->eir) * 1000; + temp_ebs = ((a_uint64_t)policer->ebs) * 1000; + + rv = __adpt_hppe_policer_two_bucket_parameter_select(temp_cir, + temp_cbs, + temp_eir, + temp_ebs, + policer->meter_unit, + &token_unit); + if( rv != SW_OK ) + return rv; + +// printk("current meter unit is = %d\n", policer->meter_unit); +// printk("current token unit is = %d\n", token_unit); + + __adpt_hppe_policer_rate_to_refresh(policer->cir, + &hppe_cir, + policer->meter_unit, + token_unit); + + __adpt_hppe_policer_rate_to_refresh(policer->eir, + &hppe_eir, + policer->meter_unit, + token_unit); + + __adpt_hppe_policer_burst_size_to_bucket_size(policer->cbs, + &hppe_cbs, + policer->meter_unit, + token_unit); + + __adpt_hppe_policer_burst_size_to_bucket_size(policer->ebs, + &hppe_ebs, + policer->meter_unit, + token_unit); + + in_acl_meter_cfg_tbl.bf.meter_en = policer->meter_en; + in_acl_meter_cfg_tbl.bf.color_mode = policer->color_mode; + in_acl_meter_cfg_tbl.bf.coupling_flag = policer->couple_en; + in_acl_meter_cfg_tbl.bf.meter_mode = policer->meter_mode; + in_acl_meter_cfg_tbl.bf.token_unit = token_unit; + in_acl_meter_cfg_tbl.bf.meter_unit = policer->meter_unit; + in_acl_meter_cfg_tbl.bf.cbs = hppe_cbs; + in_acl_meter_cfg_tbl.bf.cir_0 = hppe_cir & 0xff; + in_acl_meter_cfg_tbl.bf.cir_1 = hppe_cir >> 8; + in_acl_meter_cfg_tbl.bf.ebs = hppe_ebs; + in_acl_meter_cfg_tbl.bf.eir_0 = hppe_eir & 0x3f; + in_acl_meter_cfg_tbl.bf.eir_1 = hppe_eir >> 6; + in_acl_meter_cfg_tbl.bf.exceed_chg_pri_cmd = action->yellow_priority_en; + in_acl_meter_cfg_tbl.bf.exceed_chg_dp_cmd = action->yellow_drop_priority_en; + in_acl_meter_cfg_tbl.bf.exceed_chg_pcp_cmd = action->yellow_pcp_en; + in_acl_meter_cfg_tbl.bf.exceed_chg_dei_cmd = action->yellow_dei_en; + in_acl_meter_cfg_tbl.bf.exceed_pri = action->yellow_priority; + in_acl_meter_cfg_tbl.bf.exceed_dp = action->yellow_drop_priority; + in_acl_meter_cfg_tbl.bf.exceed_pcp = action->yellow_pcp; + in_acl_meter_cfg_tbl.bf.exceed_dei = action->yellow_dei; + if (action->red_action == FAL_MAC_DROP) + in_acl_meter_cfg_tbl.bf.violate_cmd = 0; + else + in_acl_meter_cfg_tbl.bf.violate_cmd = 1; + in_acl_meter_cfg_tbl.bf.violate_chg_pri_cmd = action->red_priority_en; + in_acl_meter_cfg_tbl.bf.violate_chg_dp_cmd = action->red_drop_priority_en; + in_acl_meter_cfg_tbl.bf.violate_chg_pcp_cmd = action->red_pcp_en; + in_acl_meter_cfg_tbl.bf.violate_chg_dei_cmd = action->red_dei_en; + in_acl_meter_cfg_tbl.bf.violate_pri_0 = action->red_priority & 0x1; + in_acl_meter_cfg_tbl.bf.violate_pri_1 = action->red_priority >>1; + in_acl_meter_cfg_tbl.bf.violate_dp = action->red_drop_priority; + in_acl_meter_cfg_tbl.bf.violate_pcp = action->red_pcp; + in_acl_meter_cfg_tbl.bf.violate_dei = action->red_dei; + + hppe_in_acl_meter_cfg_tbl_set(dev_id, index, &in_acl_meter_cfg_tbl); + + return SW_OK; +} + +sw_error_t +adpt_hppe_policer_time_slot_get(a_uint32_t dev_id, a_uint32_t *time_slot) +{ + sw_error_t rv = SW_OK; + union time_slot_reg_u time_slot_reg; + + memset(&time_slot_reg, 0, sizeof(time_slot_reg)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(time_slot); + + + rv = hppe_time_slot_reg_get(dev_id, &time_slot_reg); + + if( rv != SW_OK ) + return rv; + + *time_slot = time_slot_reg.bf.time_slot; + + return SW_OK; +} +#endif + +sw_error_t +adpt_hppe_port_compensation_byte_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t length) +{ + union meter_cmpst_length_reg_u meter_cmpst_length_reg; + + memset(&meter_cmpst_length_reg, 0, sizeof(meter_cmpst_length_reg)); + ADPT_DEV_ID_CHECK(dev_id); + + if (port_id < 0 || port_id > 7) + return SW_BAD_PARAM; + + if (length > 0x1f) + return SW_BAD_PARAM; + + hppe_meter_cmpst_length_reg_get(dev_id, port_id, &meter_cmpst_length_reg); + meter_cmpst_length_reg.bf.cmpst_length = length; + + hppe_meter_cmpst_length_reg_set(dev_id, port_id, &meter_cmpst_length_reg); + + return SW_OK; +} +sw_error_t +adpt_hppe_policer_time_slot_set(a_uint32_t dev_id, a_uint32_t time_slot) +{ + union time_slot_reg_u time_slot_reg; + + memset(&time_slot_reg, 0, sizeof(time_slot_reg)); + ADPT_DEV_ID_CHECK(dev_id); + + if ((time_slot > 1024) || (time_slot < 512)) + return SW_BAD_PARAM; + + time_slot_reg.bf.time_slot = time_slot; + hppe_time_slot_reg_set(dev_id, &time_slot_reg); + + __adpt_hppe_policer_max_rate(time_slot); + + __adpt_hppe_policer_max_burst_size(); + + return SW_OK; +} +#ifndef IN_POLICER_MINI +sw_error_t +adpt_hppe_policer_global_counter_get(a_uint32_t dev_id, + fal_policer_global_counter_t *counter) +{ + union pc_global_cnt_tbl_u pc_global_cnt_tbl; + a_uint32_t index = 0; + + memset(&pc_global_cnt_tbl, 0, sizeof(pc_global_cnt_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(counter); + + hppe_pc_global_cnt_tbl_get(dev_id, index, &pc_global_cnt_tbl); + counter->policer_drop_packet_counter = pc_global_cnt_tbl.bf.pkt_cnt; + counter->policer_drop_byte_counter = pc_global_cnt_tbl.bf.byte_cnt_1; + counter->policer_drop_byte_counter = (counter->policer_drop_byte_counter << 32) | + pc_global_cnt_tbl.bf.byte_cnt_0; + + hppe_pc_global_cnt_tbl_get(dev_id, index + 1, &pc_global_cnt_tbl); + counter->policer_forward_packet_counter = pc_global_cnt_tbl.bf.pkt_cnt; + counter->policer_forward_byte_counter = pc_global_cnt_tbl.bf.byte_cnt_1; + counter->policer_forward_byte_counter = (counter->policer_forward_byte_counter << 32) | + pc_global_cnt_tbl.bf.byte_cnt_0; + + hppe_pc_global_cnt_tbl_get(dev_id, index + 2, &pc_global_cnt_tbl); + counter->policer_bypass_packet_counter = pc_global_cnt_tbl.bf.pkt_cnt; + counter->policer_bypass_byte_counter = pc_global_cnt_tbl.bf.byte_cnt_1; + counter->policer_bypass_byte_counter = (counter->policer_bypass_byte_counter << 32) | + pc_global_cnt_tbl.bf.byte_cnt_0; + + return SW_OK; +} +#endif + +void adpt_hppe_policer_func_bitmap_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_policer_func_bitmap = ((1 << FUNC_ADPT_ACL_POLICER_COUNTER_GET)| + (1 << FUNC_ADPT_PORT_POLICER_COUNTER_GET)| + (1 << FUNC_ADPT_PORT_COMPENSATION_BYTE_GET)| + (1 << FUNC_ADPT_PORT_POLICER_ENTRY_GET)| + (1 << FUNC_ADPT_PORT_POLICER_ENTRY_SET)| + (1 << FUNC_ADPT_ACL_POLICER_ENTRY_GET)| + (1 << FUNC_ADPT_ACL_POLICER_ENTRY_SET)| + (1 << FUNC_ADPT_POLICER_TIME_SLOT_GET)| + (1 << FUNC_ADPT_PORT_COMPENSATION_BYTE_SET)| + (1 << FUNC_ADPT_POLICER_TIME_SLOT_SET) | + (1 << FUNC_ADPT_POLICER_GLOBAL_COUNTER_GET)); + + return; + +} + +static void adpt_hppe_policer_func_unregister(a_uint32_t dev_id, adpt_api_t *p_adpt_api) +{ + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_acl_policer_counter_get = NULL; + p_adpt_api->adpt_port_policer_counter_get = NULL; + p_adpt_api->adpt_port_compensation_byte_get = NULL; + p_adpt_api->adpt_port_policer_entry_get = NULL; + p_adpt_api->adpt_port_policer_entry_set = NULL; + p_adpt_api->adpt_acl_policer_entry_get = NULL; + p_adpt_api->adpt_acl_policer_entry_set = NULL; + p_adpt_api->adpt_policer_time_slot_get = NULL; + p_adpt_api->adpt_port_compensation_byte_set = NULL; + p_adpt_api->adpt_policer_time_slot_set = NULL; + p_adpt_api->adpt_policer_global_counter_get = NULL; + + return; + +} + + +sw_error_t adpt_hppe_policer_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return SW_FAIL; + + adpt_hppe_policer_func_unregister(dev_id, p_adpt_api); + +#ifndef IN_POLICER_MINI + if(p_adpt_api->adpt_policer_func_bitmap & (1 << FUNC_ADPT_ACL_POLICER_COUNTER_GET)) + { + p_adpt_api->adpt_acl_policer_counter_get = adpt_hppe_acl_policer_counter_get; + } + if(p_adpt_api->adpt_policer_func_bitmap & (1 << FUNC_ADPT_PORT_POLICER_COUNTER_GET)) + { + p_adpt_api->adpt_port_policer_counter_get = adpt_hppe_port_policer_counter_get; + } + if(p_adpt_api->adpt_policer_func_bitmap & (1 << FUNC_ADPT_PORT_COMPENSATION_BYTE_GET)) + { + p_adpt_api->adpt_port_compensation_byte_get = adpt_hppe_port_compensation_byte_get; + } + if(p_adpt_api->adpt_policer_func_bitmap & (1 << FUNC_ADPT_PORT_POLICER_ENTRY_GET)) + { + p_adpt_api->adpt_port_policer_entry_get = adpt_hppe_port_policer_entry_get; + } + if(p_adpt_api->adpt_policer_func_bitmap & (1 << FUNC_ADPT_PORT_POLICER_ENTRY_SET)) + { + p_adpt_api->adpt_port_policer_entry_set = adpt_hppe_port_policer_entry_set; + } + if(p_adpt_api->adpt_policer_func_bitmap & (1 << FUNC_ADPT_ACL_POLICER_ENTRY_GET)) + { + p_adpt_api->adpt_acl_policer_entry_get = adpt_hppe_acl_policer_entry_get; + } + if(p_adpt_api->adpt_policer_func_bitmap & (1 << FUNC_ADPT_ACL_POLICER_ENTRY_SET)) + { + p_adpt_api->adpt_acl_policer_entry_set = adpt_hppe_acl_policer_entry_set; + } + if(p_adpt_api->adpt_policer_func_bitmap & (1 << FUNC_ADPT_POLICER_TIME_SLOT_GET)) + { + p_adpt_api->adpt_policer_time_slot_get = adpt_hppe_policer_time_slot_get; + } + if(p_adpt_api->adpt_policer_func_bitmap & (1 << FUNC_ADPT_POLICER_GLOBAL_COUNTER_GET)) + { + p_adpt_api->adpt_policer_global_counter_get = adpt_hppe_policer_global_counter_get; + } +#endif + if(p_adpt_api->adpt_policer_func_bitmap & (1 << FUNC_ADPT_PORT_COMPENSATION_BYTE_SET)) + { + p_adpt_api->adpt_port_compensation_byte_set = adpt_hppe_port_compensation_byte_set; + } + if(p_adpt_api->adpt_policer_func_bitmap & (1 << FUNC_ADPT_POLICER_TIME_SLOT_SET)) + { + p_adpt_api->adpt_policer_time_slot_set = adpt_hppe_policer_time_slot_set; + } + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_portctrl.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_portctrl.c new file mode 100755 index 000000000..f1b29ef41 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_portctrl.c @@ -0,0 +1,5560 @@ +/* + * 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. + */ + + +/** + * @defgroup + * @{ + */ +#include "sw.h" +#include "hppe_portctrl_reg.h" +#include "hppe_portctrl.h" +#include "hppe_xgportctrl_reg.h" +#include "hppe_xgportctrl.h" +#include "hppe_uniphy_reg.h" +#include "hppe_uniphy.h" +#include "hppe_fdb_reg.h" +#include "hppe_fdb.h" +#include "hppe_global_reg.h" +#include "hppe_global.h" +#include "adpt.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "hsl_phy.h" +#include "hppe_init.h" +#include "ssdk_init.h" +#include "ssdk_dts.h" +#include "ssdk_clk.h" +#include "adpt_hppe.h" +#if defined(CPPE) +#include "adpt_cppe_portctrl.h" +#include "cppe_portctrl.h" +#endif +#include "sfp_phy.h" + +#define PORT4_PCS_SEL_GMII_FROM_PCS0 1 +#define PORT4_PCS_SEL_RGMII 0 + +#define PORT5_PCS_SEL_RGMII 0 +#define PORT5_PCS_SEL_GMII_FROM_PCS0 1 +#define PORT5_PCS_SEL_GMII_FROM_PCS1 2 +#define PORT5_GMAC_SEL_GMAC 1 +#define PORT5_GMAC_SEL_XGMAC 0 + +#define PORT6_PCS_SEL_RGMII 0 +#define PORT6_PCS_SEL_GMII_FROM_PCS2 1 +#define PORT6_GMAC_SEL_GMAC 1 +#define PORT6_GMAC_SEL_XGMAC 0 + +#define MAC_SPEED_10M 0 +#define MAC_SPEED_100M 1 +#define MAC_SPEED_1000M 2 +#define MAC_SPEED_10000M 3 + +#define XGMAC_USXGMII_ENABLE 1 +#define XGMAC_USXGMII_CLEAR 0 + +#define XGMAC_SPEED_SELECT_10000M 0 +#define XGMAC_SPEED_SELECT_5000M 1 +#define XGMAC_SPEED_SELECT_2500M 2 +#define XGMAC_SPEED_SELECT_1000M 3 +#define LPI_WAKEUP_TIMER 0x20 +#define LPI_SLEEP_TIMER 0x100 +#define PROMISCUOUS_MODE 0x1 +#define PASS_CONTROL_PACKET 0x2 +#define XGMAC_PAUSE_TIME 0xffff +#define CARRIER_SENSE_SIGNAL_FROM_MAC 0x0 + +#define PHY_PORT_TO_BM_PORT(port) (port + 7) +#define GMAC_IPG_CHECK 0xc +#define LPI_EEE_TIMER_FREQUENCY 300 /* 300MHZ*/ +#define LPI_EEE_TIMER_UNIT 256 + +/* This register is used to adjust the write timing for reserving + * some bandwidth of the memory to read operation. + */ +#define GMAC_TX_THD 0x1 + +static a_uint32_t port_interface_mode[SW_MAX_NR_DEV][SW_MAX_NR_PORT] = {0}; + +static a_bool_t +_adpt_hppe_port_phy_connected (a_uint32_t dev_id, fal_port_t port_id) +{ + a_uint32_t mode1, mode2; + a_bool_t force_port = 0; + + ADPT_DEV_ID_CHECK(dev_id); + + /* force port which connect s17c or other device chip*/ + force_port = ssdk_port_feature_get(dev_id, port_id, PHY_F_FORCE); + if (force_port == A_TRUE) { + SSDK_DEBUG("port_id %d is a force port!\n", port_id); + return A_FALSE; + } + + mode1 = ssdk_dt_global_get_mac_mode(dev_id, SSDK_UNIPHY_INSTANCE1); + mode2 = ssdk_dt_global_get_mac_mode(dev_id, SSDK_UNIPHY_INSTANCE2); + + if ((SSDK_PHYSICAL_PORT0 == port_id) || (SSDK_PHYSICAL_PORT7 == port_id)|| + ((SSDK_PHYSICAL_PORT5 == port_id) && ((mode1 == PORT_WRAPPER_10GBASE_R) || + mode1 == PORT_WRAPPER_SGMII_FIBER)) || + ((SSDK_PHYSICAL_PORT6 == port_id) && ((mode2 == PORT_WRAPPER_10GBASE_R) || + mode2 == PORT_WRAPPER_SGMII_FIBER))) + return A_FALSE; + else + return hppe_mac_port_valid_check (dev_id, port_id); +} + +static sw_error_t +_adpt_phy_status_get_from_ppe(a_uint32_t dev_id, a_uint32_t port_id, + struct port_phy_status *phy_status) +{ + sw_error_t rv = SW_OK; + a_uint32_t reg_field = 0; + + ADPT_DEV_ID_CHECK(dev_id); + + if (port_id == SSDK_PHYSICAL_PORT5) + { + + if (adpt_hppe_chip_revision_get(dev_id) + == HPPE_REVISION) + { + rv = hppe_port_phy_status_1_port5_1_phy_status_get(dev_id, + ®_field); + SW_RTN_ON_ERROR (rv); + } +#ifdef CPPE + else + { + rv = cppe_port5_pcs1_phy_status_get(dev_id, + ®_field); + SW_RTN_ON_ERROR (rv); + } +#endif + } + else + { + rv = hppe_port_phy_status_1_port6_phy_status_get(dev_id, + ®_field); + SW_RTN_ON_ERROR (rv); + } + + phy_status->tx_flowctrl = A_TRUE; + phy_status->rx_flowctrl = A_TRUE; + + if ((reg_field >> 7) & 0x1) + { + phy_status->link_status = PORT_LINK_UP; + switch (reg_field & 0x7) + { + case MAC_SPEED_1000M: + phy_status->speed = FAL_SPEED_1000; + break; + case MAC_SPEED_10000M: + phy_status->speed = FAL_SPEED_10000; + break; + default: + phy_status->speed = FAL_SPEED_BUTT; + break; + } + phy_status->duplex = FAL_FULL_DUPLEX; + } + else + { + phy_status->link_status = PORT_LINK_DOWN; + phy_status->speed = FAL_SPEED_BUTT; + phy_status->duplex = FAL_DUPLEX_BUTT; + } + + return rv; +} +#ifndef IN_PORTCONTROL_MINI +static sw_error_t +_adpt_hppe_port_xgmac_loopback_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv = SW_OK; + + port_id = HPPE_TO_XGMAC_PORT_ID(port_id); + rv = hppe_mac_rx_configuration_lm_get(dev_id, port_id, (a_uint32_t*)enable); + + return rv; +} + +static sw_error_t +_adpt_hppe_port_gmac_loopback_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv = SW_OK; + + port_id = HPPE_TO_GMAC_PORT_ID(port_id); + rv = hppe_mac_ctrl2_mac_loop_back_get(dev_id, port_id, (a_uint32_t*)enable); + + return rv; +} + +static sw_error_t +_adpt_hppe_port_xgmac_loopback_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv = SW_OK; + + port_id = HPPE_TO_XGMAC_PORT_ID(port_id); + rv = hppe_mac_rx_configuration_lm_set(dev_id, port_id, (a_uint32_t)enable); + + return rv; +} + +static sw_error_t +_adpt_hppe_port_gmac_loopback_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv = SW_OK; + + port_id = HPPE_TO_GMAC_PORT_ID(port_id); + rv = hppe_mac_ctrl2_mac_loop_back_set(dev_id, port_id, (a_uint32_t)enable); + + return rv; +} +#endif +static sw_error_t +_adpt_hppe_port_jumbo_size_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t jumbo_size) +{ + sw_error_t rv = SW_OK; + + port_id = HPPE_TO_GMAC_PORT_ID(port_id); + rv = hppe_mac_jumbo_size_mac_jumbo_size_set(dev_id, port_id, jumbo_size); + + return rv; +} + +static sw_error_t +_adpt_xgmac_port_max_frame_size_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t *max_frame) +{ + sw_error_t rv = SW_OK; + + port_id = HPPE_TO_XGMAC_PORT_ID(port_id); + rv = hppe_mac_rx_configuration_gpsl_get(dev_id,port_id, max_frame); + + return rv; +} + +static sw_error_t +_adpt_gmac_port_max_frame_size_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t *max_frame) +{ + sw_error_t rv = SW_OK; + + port_id = HPPE_TO_GMAC_PORT_ID(port_id); + rv = hppe_mac_jumbo_size_mac_jumbo_size_get(dev_id, port_id, max_frame); + + return rv; +} + +static sw_error_t +_adpt_xgmac_port_max_frame_size_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t max_frame) +{ + sw_error_t rv = SW_OK; + + port_id = HPPE_TO_XGMAC_PORT_ID(port_id); + rv |= hppe_mac_tx_configuration_jd_set(dev_id, port_id, (a_uint32_t)A_TRUE); + rv |= hppe_mac_rx_configuration_gpsl_set(dev_id, port_id, max_frame); + rv |= hppe_mac_rx_configuration_wd_set(dev_id, port_id, 1); + rv |= hppe_mac_rx_configuration_gmpslce_set(dev_id, port_id, 1); + rv |= hppe_mac_packet_filter_pr_set(dev_id, port_id, PROMISCUOUS_MODE); + rv |= hppe_mac_packet_filter_pcf_set(dev_id, port_id, PASS_CONTROL_PACKET); + + return rv; +} + +static sw_error_t +_adpt_gmac_port_max_frame_size_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t max_frame) +{ + sw_error_t rv = SW_OK; + + port_id = HPPE_TO_GMAC_PORT_ID(port_id); + rv |= hppe_mac_ctrl2_maxfr_set(dev_id, port_id, max_frame); + rv |= hppe_mac_ctrl2_crs_sel_set(dev_id, port_id, CARRIER_SENSE_SIGNAL_FROM_MAC); + rv |= hppe_mac_dbg_ctrl_hihg_ipg_set(dev_id, port_id, GMAC_IPG_CHECK); + rv |= hppe_mac_ctrl2_mac_tx_thd_set(dev_id, port_id, GMAC_TX_THD); + + return rv; +} +#ifndef IN_PORTCONTROL_MINI +static sw_error_t +_adpt_xgmac_port_rx_status_get(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t* port_rxmac_status) +{ + sw_error_t rv = SW_OK; + union mac_rx_configuration_u xgmac_rx_enable; + + memset(&xgmac_rx_enable, 0, sizeof(xgmac_rx_enable)); + port_id = HPPE_TO_XGMAC_PORT_ID(port_id); + rv = hppe_mac_rx_configuration_get(dev_id, port_id, &xgmac_rx_enable); + if( rv != SW_OK ) + return rv; + *port_rxmac_status = xgmac_rx_enable.bf.re; + + return rv; +} +static sw_error_t +_adpt_gmac_port_rx_status_get(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t* port_rxmac_status) +{ + sw_error_t rv = SW_OK; + union mac_enable_u gmac_rx_enable; + + memset(&gmac_rx_enable, 0, sizeof(gmac_rx_enable)); + port_id = HPPE_TO_GMAC_PORT_ID(port_id); + rv = hppe_mac_enable_get(dev_id, port_id, &gmac_rx_enable); + if( rv != SW_OK ) + return rv; + * port_rxmac_status = gmac_rx_enable.bf.rxmac_en; + + return rv; +} +#endif +static sw_error_t +_adpt_xgmac_port_rx_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv = SW_OK; + union mac_rx_configuration_u xgmac_rx_enable; + + memset(&xgmac_rx_enable, 0, sizeof(xgmac_rx_enable)); + port_id = HPPE_TO_XGMAC_PORT_ID(port_id); + rv |= hppe_mac_rx_configuration_get(dev_id, port_id, &xgmac_rx_enable); + + xgmac_rx_enable.bf.acs = 1; + xgmac_rx_enable.bf.cst = 1; + if (A_TRUE == enable) + { + xgmac_rx_enable.bf.re = 1; + } + else { + xgmac_rx_enable.bf.re = 0; + } + rv |= hppe_mac_rx_configuration_set(dev_id, port_id, &xgmac_rx_enable); + + return rv; +} + +static sw_error_t +_adpt_gmac_port_rx_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv = SW_OK; + union mac_enable_u gmac_rx_enable; + + memset(&gmac_rx_enable, 0, sizeof(gmac_rx_enable)); + port_id = HPPE_TO_GMAC_PORT_ID(port_id); + rv |= hppe_mac_enable_get(dev_id, port_id, &gmac_rx_enable); + if (A_TRUE == enable) + gmac_rx_enable.bf.rxmac_en = 1; + if (A_FALSE == enable) + gmac_rx_enable.bf.rxmac_en = 0; + rv |= hppe_mac_enable_set(dev_id, port_id, &gmac_rx_enable); + + return rv; +} +#ifndef IN_PORTCONTROL_MINI +static sw_error_t +_adpt_xgmac_port_tx_status_get(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t *port_txmac_status) +{ + sw_error_t rv = SW_OK; + union mac_tx_configuration_u xgmac_tx_enable; + + memset(&xgmac_tx_enable, 0, sizeof(xgmac_tx_enable)); + port_id = HPPE_TO_XGMAC_PORT_ID(port_id); + rv = hppe_mac_tx_configuration_get(dev_id, port_id, &xgmac_tx_enable); + if( rv != SW_OK ) + return rv; + *port_txmac_status = xgmac_tx_enable.bf.te; + + return SW_OK; +} + +static sw_error_t +_adpt_gmac_port_tx_status_get(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t *port_txmac_status) +{ + sw_error_t rv = SW_OK; + union mac_enable_u gmac_tx_enable; + + memset(&gmac_tx_enable, 0, sizeof(gmac_tx_enable)); + port_id = HPPE_TO_GMAC_PORT_ID(port_id); + rv = hppe_mac_enable_get(dev_id, port_id, &gmac_tx_enable); + if( rv != SW_OK ) + return rv; + *port_txmac_status = gmac_tx_enable.bf.txmac_en; + + return SW_OK; +} +#endif +static sw_error_t +_adpt_xgmac_port_tx_status_set (a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv = SW_OK; + union mac_tx_configuration_u xgmac_tx_enable; + + memset(&xgmac_tx_enable, 0, sizeof(xgmac_tx_enable)); + port_id = HPPE_TO_XGMAC_PORT_ID(port_id); + rv |=hppe_mac_tx_configuration_get(dev_id, port_id, &xgmac_tx_enable); + if (A_TRUE == enable) + xgmac_tx_enable.bf.te = 1; + if (A_FALSE == enable) + xgmac_tx_enable.bf.te = 0; + rv |= hppe_mac_tx_configuration_set(dev_id, port_id, &xgmac_tx_enable); + + return SW_OK; +} + +static sw_error_t +_adpt_gmac_port_tx_status_set (a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv = SW_OK; + union mac_enable_u gmac_tx_enable; + + memset(&gmac_tx_enable, 0, sizeof(gmac_tx_enable)); + port_id = HPPE_TO_GMAC_PORT_ID(port_id); + rv |= hppe_mac_enable_get(dev_id, port_id, &gmac_tx_enable); + if (A_TRUE == enable) + gmac_tx_enable.bf.txmac_en = 1; + if (A_FALSE == enable) + gmac_tx_enable.bf.txmac_en = 0; + rv |= hppe_mac_enable_set(dev_id, port_id, &gmac_tx_enable); + + return SW_OK; +} + +static sw_error_t +_adpt_xgmac_port_txfc_status_get(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t* txfc_status) +{ + sw_error_t rv = SW_OK; + union mac_q0_tx_flow_ctrl_u xgmac_txfc_enable; + + memset(&xgmac_txfc_enable, 0, sizeof(xgmac_txfc_enable)); + port_id = HPPE_TO_XGMAC_PORT_ID(port_id); + rv = hppe_mac_q0_tx_flow_ctrl_get(dev_id, port_id, &xgmac_txfc_enable); + if( rv != SW_OK ) + return rv; + *txfc_status = xgmac_txfc_enable.bf.tfe; + + return SW_OK; +} + +static sw_error_t +_adpt_gmac_port_txfc_status_get(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t* txfc_status) +{ + sw_error_t rv = SW_OK; + union mac_enable_u gmac_txfc_enable; + + memset(&gmac_txfc_enable, 0, sizeof(gmac_txfc_enable)); + port_id = HPPE_TO_GMAC_PORT_ID(port_id); + rv = hppe_mac_enable_get(dev_id, port_id, &gmac_txfc_enable); + if( rv != SW_OK ) + return rv; + *txfc_status = gmac_txfc_enable.bf.tx_flow_en; + + return SW_OK; +} + +static sw_error_t +_adpt_xgmac_port_txfc_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv = SW_OK; + union mac_q0_tx_flow_ctrl_u xgmac_txfc_enable; + + memset(&xgmac_txfc_enable, 0, sizeof(xgmac_txfc_enable)); + port_id = HPPE_TO_XGMAC_PORT_ID(port_id); + rv |= hppe_mac_q0_tx_flow_ctrl_get(dev_id, port_id, &xgmac_txfc_enable); + if (A_TRUE == enable) + { + xgmac_txfc_enable.bf.tfe = 1; + xgmac_txfc_enable.bf.pt = XGMAC_PAUSE_TIME; + } + if (A_FALSE == enable) + xgmac_txfc_enable.bf.tfe = 0; + rv |= hppe_mac_q0_tx_flow_ctrl_set(dev_id, port_id, &xgmac_txfc_enable); + + return SW_OK; +} + +static sw_error_t +_adpt_gmac_port_txfc_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv = SW_OK; + union mac_enable_u gmac_txfc_enable; + + memset(&gmac_txfc_enable, 0, sizeof(gmac_txfc_enable)); + port_id = HPPE_TO_GMAC_PORT_ID(port_id); + rv |= hppe_mac_enable_get(dev_id, port_id, &gmac_txfc_enable); + if (A_TRUE == enable) + gmac_txfc_enable.bf.tx_flow_en = 1; + if (A_FALSE == enable) + gmac_txfc_enable.bf.tx_flow_en = 0; + rv |= hppe_mac_enable_set(dev_id, port_id, &gmac_txfc_enable); + + return SW_OK; +} + +static sw_error_t +_adpt_xgmac_port_rxfc_status_get(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t* rxfc_status) +{ + sw_error_t rv = SW_OK; + union mac_rx_flow_ctrl_u xgmac_rxfc_enable; + + memset(&xgmac_rxfc_enable, 0, sizeof(xgmac_rxfc_enable)); + port_id = HPPE_TO_XGMAC_PORT_ID(port_id); + rv = hppe_mac_rx_flow_ctrl_get(dev_id, port_id, &xgmac_rxfc_enable); + if(rv != SW_OK) + return rv; + *rxfc_status = xgmac_rxfc_enable.bf.rfe; + + return SW_OK; +} + +static sw_error_t +_adpt_gmac_port_rxfc_status_get(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t* rxfc_status) +{ + sw_error_t rv = SW_OK; + union mac_enable_u gmac_rxfc_enable; + + memset(&gmac_rxfc_enable, 0, sizeof(gmac_rxfc_enable)); + port_id = HPPE_TO_GMAC_PORT_ID(port_id); + rv = hppe_mac_enable_get(dev_id, port_id, &gmac_rxfc_enable); + if( rv != SW_OK) + return rv; + *rxfc_status = gmac_rxfc_enable.bf.rx_flow_en; + + return SW_OK; +} + +static sw_error_t +_adpt_xgmac_port_rxfc_status_set(a_uint32_t dev_id,fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv = SW_OK; + union mac_rx_flow_ctrl_u xgmac_rxfc_enable; + + memset(&xgmac_rxfc_enable, 0, sizeof(xgmac_rxfc_enable)); + port_id = HPPE_TO_XGMAC_PORT_ID(port_id); + rv |= hppe_mac_rx_flow_ctrl_get(dev_id, port_id, &xgmac_rxfc_enable); + if (A_TRUE == enable) + xgmac_rxfc_enable.bf.rfe= 1; + if (A_FALSE == enable) + xgmac_rxfc_enable.bf.rfe = 0; + rv |= hppe_mac_rx_flow_ctrl_set(dev_id, port_id, &xgmac_rxfc_enable); + + return SW_OK; +} + +static sw_error_t +_adpt_gmac_port_rxfc_status_set(a_uint32_t dev_id,fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv = SW_OK; + union mac_enable_u gmac_rxfc_enable; + + memset(&gmac_rxfc_enable, 0, sizeof(gmac_rxfc_enable)); + port_id = HPPE_TO_GMAC_PORT_ID(port_id); + rv |= hppe_mac_enable_get(dev_id, port_id, &gmac_rxfc_enable); + if (A_TRUE == enable) + gmac_rxfc_enable.bf.rx_flow_en = 1; + if (A_FALSE == enable) + gmac_rxfc_enable.bf.rx_flow_en = 0; + rv |= hppe_mac_enable_set(dev_id, port_id, &gmac_rxfc_enable); + + return SW_OK; +} + +#ifndef IN_PORTCONTROL_MINI +sw_error_t +adpt_hppe_port_local_loopback_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_local_loopback_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_local_loopback_get (dev_id, phy_id, enable); + + return rv; + +} +#endif +sw_error_t +adpt_hppe_port_autoneg_restart(a_uint32_t dev_id, fal_port_t port_id) +{ + + sw_error_t rv = 0; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_restart_autoneg) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_restart_autoneg (dev_id, phy_id); + return rv; + +} +sw_error_t +adpt_hppe_port_duplex_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t duplex) +{ + union mac_enable_u mac_enable; + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + memset(&mac_enable, 0, sizeof(mac_enable)); + ADPT_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_duplex_set) + return SW_NOT_SUPPORTED; + + if (FAL_DUPLEX_BUTT <= duplex) + { + return SW_BAD_PARAM; + } + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_duplex_set (dev_id, phy_id, duplex); + SW_RTN_ON_ERROR (rv); + +#if 0 + port_id = port_id - 1; + hppe_mac_enable_get(dev_id, port_id, &mac_enable); + + if (FAL_HALF_DUPLEX == duplex) + mac_enable.bf.duplex = 0; + if (FAL_FULL_DUPLEX == duplex) + mac_enable.bf.duplex = 1; + + hppe_mac_enable_set(dev_id, port_id, &mac_enable); + +#endif + + return rv; +} +#ifndef IN_PORTCONTROL_MINI +sw_error_t +adpt_hppe_port_rxmac_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv = SW_OK; + a_uint32_t port_rxmac_status = 0, port_mac_type; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + + port_mac_type = qca_hppe_port_mac_type_get(dev_id, port_id); + if (port_mac_type == PORT_XGMAC_TYPE) + _adpt_xgmac_port_rx_status_get( dev_id, port_id, &port_rxmac_status); + else if (port_mac_type == PORT_GMAC_TYPE) + _adpt_gmac_port_rx_status_get( dev_id, port_id, &port_rxmac_status); + else + return SW_BAD_VALUE; + + if (port_rxmac_status) + *enable = A_TRUE; + else + *enable = A_FALSE; + + return rv; +} + +sw_error_t +adpt_hppe_port_cdt(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mdi_pair, fal_cable_status_t * cable_status, + a_uint32_t * cable_len) +{ + + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cable_status); + ADPT_NULL_POINT_CHECK(cable_len); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_cdt) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_cdt (dev_id, phy_id, mdi_pair, cable_status, cable_len); + + return rv; + +} +#endif +sw_error_t +adpt_hppe_port_txmac_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t port_mac_type; + + ADPT_DEV_ID_CHECK(dev_id); + + port_mac_type =qca_hppe_port_mac_type_get(dev_id, port_id); + if (port_mac_type == PORT_XGMAC_TYPE) + _adpt_xgmac_port_tx_status_set( dev_id, port_id, enable); + else if (port_mac_type == PORT_GMAC_TYPE) + _adpt_gmac_port_tx_status_set( dev_id, port_id, enable); + else + return SW_BAD_VALUE; + + return SW_OK; +} +#ifndef IN_PORTCONTROL_MINI +sw_error_t +adpt_hppe_port_combo_fiber_mode_set(a_uint32_t dev_id, + a_uint32_t port_id, + fal_port_fiber_mode_t mode) +{ + + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_combo_fiber_mode_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_combo_fiber_mode_set (dev_id, phy_id, mode); + + return rv; + +} +sw_error_t +adpt_hppe_port_combo_medium_status_get(a_uint32_t dev_id, + a_uint32_t port_id, + fal_port_medium_t * + medium) +{ + + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(medium); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_combo_medium_status_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_combo_medium_status_get (dev_id, phy_id, medium); + + return rv; + +} + +sw_error_t +adpt_hppe_port_magic_frame_mac_set(a_uint32_t dev_id, fal_port_t port_id, + fal_mac_addr_t * mac) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(mac); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_magic_frame_mac_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_magic_frame_mac_set (dev_id, phy_id,mac); + + return rv; + +} +sw_error_t +adpt_hppe_port_powersave_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_powersave_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_powersave_set (dev_id, phy_id, enable); + + return rv; + +} +sw_error_t +adpt_hppe_port_hibernate_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_hibernation_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_hibernation_set (dev_id, phy_id, enable); + + return rv; + +} + +sw_error_t +adpt_hppe_port_mru_set(a_uint32_t dev_id, fal_port_t port_id, + fal_mru_ctrl_t *ctrl) +{ + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(ctrl); + + hppe_mru_mtu_ctrl_tbl_mru_set(dev_id, port_id, ctrl->mru_size); + hppe_mru_mtu_ctrl_tbl_mru_cmd_set(dev_id, port_id, (a_uint32_t)ctrl->action); + + return SW_OK; +} + +sw_error_t +adpt_ppe_port_mru_set(a_uint32_t dev_id, fal_port_t port_id, + fal_mru_ctrl_t *ctrl) +{ + a_uint32_t chip_ver = 0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(ctrl); + + chip_ver = adpt_hppe_chip_revision_get(dev_id); + if (chip_ver == CPPE_REVISION) { +#if defined(CPPE) + return adpt_cppe_port_mru_set(dev_id, port_id, ctrl); +#endif + } else { + return adpt_hppe_port_mru_set(dev_id, port_id, ctrl); + } + + return SW_NOT_SUPPORTED; +} + +sw_error_t +adpt_hppe_port_mtu_set(a_uint32_t dev_id, fal_port_t port_id, + fal_mtu_ctrl_t *ctrl) +{ + union mru_mtu_ctrl_tbl_u mru_mtu_ctrl_tbl; + + memset(&mru_mtu_ctrl_tbl, 0, sizeof(mru_mtu_ctrl_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(ctrl); + + hppe_mru_mtu_ctrl_tbl_get(dev_id, port_id, &mru_mtu_ctrl_tbl); + mru_mtu_ctrl_tbl.bf.mtu = ctrl->mtu_size; + mru_mtu_ctrl_tbl.bf.mtu_cmd = (a_uint32_t)ctrl->action; + hppe_mru_mtu_ctrl_tbl_set(dev_id, port_id, &mru_mtu_ctrl_tbl); + + if ((port_id >= SSDK_PHYSICAL_PORT0) && (port_id <= SSDK_PHYSICAL_PORT7)) + { + hppe_mc_mtu_ctrl_tbl_mtu_set(dev_id, port_id, ctrl->mtu_size); + hppe_mc_mtu_ctrl_tbl_mtu_cmd_set(dev_id, port_id, (a_uint32_t)ctrl->action); + } + + return SW_OK; +} + +sw_error_t +adpt_ppe_port_mtu_set(a_uint32_t dev_id, fal_port_t port_id, + fal_mtu_ctrl_t *ctrl) +{ + a_uint32_t chip_ver = 0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(ctrl); + + chip_ver = adpt_hppe_chip_revision_get(dev_id); + if (chip_ver == CPPE_REVISION) { +#if defined(CPPE) + return adpt_cppe_port_mtu_set(dev_id, port_id, ctrl); +#endif + } else { + return adpt_hppe_port_mtu_set(dev_id, port_id, ctrl); + } + + return SW_NOT_SUPPORTED; +} +#endif + +sw_error_t +adpt_hppe_port_max_frame_size_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t max_frame) +{ + a_uint32_t port_mac_type = 0; + sw_error_t rv = SW_OK; + + ADPT_DEV_ID_CHECK(dev_id); + + if (max_frame > SSDK_MAX_FRAME_SIZE) { + return SW_BAD_VALUE; + } + + port_mac_type =qca_hppe_port_mac_type_get(dev_id, port_id); + if (port_mac_type == PORT_XGMAC_TYPE) + rv |= _adpt_xgmac_port_max_frame_size_set( dev_id, port_id, max_frame); + else if (port_mac_type == PORT_GMAC_TYPE) + { + /*for gmac, rxtoolong have counters when package length is longer than jumbo size and shorter than max frame size, + when package length is longer than max frame size, the rxbadbyte have counters.*/ + rv |= _adpt_hppe_port_jumbo_size_set(dev_id, port_id, max_frame); + rv |= _adpt_gmac_port_max_frame_size_set( dev_id, port_id, max_frame); + } + else + return SW_BAD_VALUE; + + return rv; +} + +sw_error_t +adpt_ppe_port_max_frame_size_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t max_frame) +{ +#ifdef CPPE + if (adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION && + port_id == SSDK_PHYSICAL_PORT6) + { + return adpt_cppe_lpbk_max_frame_size_set(dev_id, port_id, max_frame); + } +#endif + return adpt_hppe_port_max_frame_size_set(dev_id, port_id, max_frame); +} + +#ifndef IN_PORTCONTROL_MINI +sw_error_t +adpt_hppe_port_8023az_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_8023az_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_8023az_get (dev_id, phy_id, enable); + + return rv; + +} +#endif +sw_error_t +adpt_hppe_port_rxfc_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv = SW_OK; + a_uint32_t rxfc_status = 0, port_mac_type; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + + port_mac_type =qca_hppe_port_mac_type_get(dev_id, port_id); + if (port_mac_type == PORT_XGMAC_TYPE) + _adpt_xgmac_port_rxfc_status_get( dev_id, port_id, &rxfc_status); + else if (port_mac_type == PORT_GMAC_TYPE) + _adpt_gmac_port_rxfc_status_get( dev_id, port_id, &rxfc_status); + else + return SW_BAD_VALUE; + + if (rxfc_status) + *enable = A_TRUE; + else + *enable = A_FALSE; + + return rv; +} + +sw_error_t +adpt_hppe_port_txfc_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + a_uint32_t txfc_status = 0, port_mac_type; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + + port_mac_type =qca_hppe_port_mac_type_get(dev_id, port_id); + if (port_mac_type == PORT_XGMAC_TYPE) + _adpt_xgmac_port_txfc_status_get( dev_id, port_id, &txfc_status); + else if (port_mac_type == PORT_GMAC_TYPE) + _adpt_gmac_port_txfc_status_get( dev_id, port_id, &txfc_status); + else + return SW_BAD_VALUE; + + if (txfc_status) + *enable = A_TRUE; + else + *enable = A_FALSE; + + return SW_OK; +} +#ifndef IN_PORTCONTROL_MINI +sw_error_t +adpt_hppe_port_remote_loopback_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_remote_loopback_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_remote_loopback_set (dev_id, phy_id, enable); + + return rv; + +} +#endif +sw_error_t +adpt_hppe_port_autoneg_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status) +{ + + a_uint32_t phy_id = 0; + sw_error_t rv = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(status); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_autoneg_status_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + *status = phy_drv->phy_autoneg_status_get (dev_id, phy_id); + + return SW_OK; + +} +#ifndef IN_PORTCONTROL_MINI +sw_error_t +adpt_hppe_port_txmac_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv = SW_OK; + a_uint32_t port_txmac_status = 0, port_mac_type; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + + port_mac_type =qca_hppe_port_mac_type_get(dev_id, port_id); + if (port_mac_type == PORT_XGMAC_TYPE) + _adpt_xgmac_port_tx_status_get( dev_id, port_id, &port_txmac_status); + else if (port_mac_type == PORT_GMAC_TYPE) + _adpt_gmac_port_tx_status_get( dev_id, port_id, &port_txmac_status); + else + return SW_BAD_VALUE; + + if (port_txmac_status) + *enable = A_TRUE; + else + *enable = A_FALSE; + + return rv; +} + +sw_error_t +adpt_hppe_port_mdix_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_mdix_mode_t * mode) +{ + + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(mode); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_mdix_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_mdix_get (dev_id, phy_id, mode); + + return rv; + +} + +sw_error_t +adpt_hppe_ports_link_status_get(a_uint32_t dev_id, a_uint32_t * status) +{ + + sw_error_t rv = 0; + a_uint32_t port_id; + a_uint32_t phy_id; + hsl_dev_t *pdev = NULL; + hsl_phy_ops_t *phy_drv; + struct port_phy_status phy_status = {0}; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(status); + + pdev = hsl_dev_ptr_get(dev_id); + if (pdev == NULL) + return SW_NOT_INITIALIZED; + + *status = 0x0; + for (port_id = 0; port_id < SW_MAX_NR_PORT; port_id++) + { + /* for those ports without PHY device should be sfp port */ + if (A_FALSE == _adpt_hppe_port_phy_connected(dev_id, port_id)) + { + if (hsl_port_prop_check(dev_id, port_id, HSL_PP_CPU) || + hsl_port_prop_check(dev_id, port_id, HSL_PP_INNER)) + { + *status |= (0x1 << port_id); + } + else + { + if(!hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + continue; + } + rv = _adpt_phy_status_get_from_ppe(dev_id, + port_id, &phy_status); + SW_RTN_ON_ERROR (rv); + + if (phy_status.link_status == PORT_LINK_UP) + { + *status |= (0x1 << port_id); + } + else + { + *status &= ~(0x1 << port_id); + } + } + } + else + { + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_link_status_get) + { + return SW_NOT_SUPPORTED; + } + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == phy_drv->phy_link_status_get (dev_id, phy_id)) + { + *status |= (0x1 << port_id); + } + else + { + *status &= ~(0x1 << port_id); + } + } + } + return SW_OK; + +} + +sw_error_t +adpt_hppe_port_mac_loopback_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv = SW_OK; + a_uint32_t port_mac_type = 0; + + ADPT_DEV_ID_CHECK(dev_id); + port_mac_type = qca_hppe_port_mac_type_get(dev_id, port_id); + if (port_mac_type == PORT_XGMAC_TYPE) + rv = _adpt_hppe_port_xgmac_loopback_set( dev_id, port_id, enable); + else if(port_mac_type == PORT_GMAC_TYPE) + rv = _adpt_hppe_port_gmac_loopback_set( dev_id, port_id, enable); + else + return SW_BAD_VALUE; + + return rv; +} + +sw_error_t +adpt_hppe_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 = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + a_uint32_t phy_data; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(org_id); + ADPT_NULL_POINT_CHECK(rev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_id_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_id_get (dev_id, phy_id, &phy_data); + SW_RTN_ON_ERROR (rv); + + *org_id = (phy_data >> 16) & 0xffff; + *rev_id = phy_data & 0xffff; + + return rv; + +} +sw_error_t +adpt_hppe_port_mru_get(a_uint32_t dev_id, fal_port_t port_id, + fal_mru_ctrl_t *ctrl) +{ + sw_error_t rv = SW_OK; + union mru_mtu_ctrl_tbl_u mru_mtu_ctrl_tbl; + + memset(&mru_mtu_ctrl_tbl, 0, sizeof(mru_mtu_ctrl_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(ctrl); + + rv = hppe_mru_mtu_ctrl_tbl_get(dev_id, port_id, &mru_mtu_ctrl_tbl); + + if( rv != SW_OK ) + return rv; + + ctrl->mru_size = mru_mtu_ctrl_tbl.bf.mru; + ctrl->action = (fal_fwd_cmd_t)mru_mtu_ctrl_tbl.bf.mru_cmd; + + return SW_OK; +} + +sw_error_t +adpt_ppe_port_mru_get(a_uint32_t dev_id, fal_port_t port_id, + fal_mru_ctrl_t *ctrl) +{ + a_uint32_t chip_ver = 0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(ctrl); + + chip_ver = adpt_hppe_chip_revision_get(dev_id); + if (chip_ver == CPPE_REVISION) { +#if defined(CPPE) + return adpt_cppe_port_mru_get(dev_id, port_id, ctrl); +#endif + } else { + return adpt_hppe_port_mru_get(dev_id, port_id, ctrl); + } + + return SW_NOT_SUPPORTED; +} +#endif + +sw_error_t +adpt_hppe_port_power_on(a_uint32_t dev_id, fal_port_t port_id) +{ + + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_power_on) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_power_on(dev_id, phy_id); + + return rv; + +} +sw_error_t +adpt_hppe_port_speed_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t speed) +{ + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_speed_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_speed_set (dev_id, phy_id, speed); + SW_RTN_ON_ERROR (rv); + + return rv; +} +sw_error_t +adpt_hppe_port_interface_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_interface_mode_t * mode) +{ + sw_error_t rv = 0; + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + *mode = port_interface_mode[dev_id][port_id]; + + return rv; +} + +sw_error_t +adpt_hppe_port_duplex_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t * pduplex) +{ + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + struct port_phy_status phy_status = {0}; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(pduplex); + + if (port_id == SSDK_PHYSICAL_PORT0 || port_id == SSDK_PHYSICAL_PORT7) + { + *pduplex = FAL_FULL_DUPLEX; + return SW_OK; + } + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + /* for those ports without PHY device should be sfp port */ + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + { + + rv = _adpt_phy_status_get_from_ppe(dev_id, + port_id, &phy_status); + SW_RTN_ON_ERROR (rv); + *pduplex = phy_status.duplex; + + } + else + { + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_duplex_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + rv = phy_drv->phy_duplex_get (dev_id, phy_id, pduplex); + SW_RTN_ON_ERROR (rv); + } + + return rv; +} + +sw_error_t +adpt_hppe_port_autoneg_adv_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * autoadv) +{ + + sw_error_t rv = 0; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(autoadv); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_autoneg_adv_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + *autoadv = 0; + rv = phy_drv->phy_autoneg_adv_get (dev_id, phy_id, autoadv); + SW_RTN_ON_ERROR (rv); + + return SW_OK; + +} +#ifndef IN_PORTCONTROL_MINI +sw_error_t +adpt_hppe_port_mdix_status_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_mdix_status_t * mode) +{ + + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(mode); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_mdix_status_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_mdix_status_get (dev_id, phy_id, mode); + + return rv; + +} +#endif +sw_error_t +adpt_hppe_port_link_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status) +{ + + sw_error_t rv = 0; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + struct port_phy_status phy_status = {0}; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(status); + + if (port_id == SSDK_PHYSICAL_PORT0 || port_id == SSDK_PHYSICAL_PORT7) + { + *status = A_TRUE; + return SW_OK; + } + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + /* for those ports without PHY device should be sfp port */ + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + { + rv = _adpt_phy_status_get_from_ppe(dev_id, + port_id, &phy_status); + SW_RTN_ON_ERROR (rv); + *status = (a_bool_t) phy_status.link_status; + } + else + { + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_link_status_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + if (A_TRUE == phy_drv->phy_link_status_get (dev_id, phy_id)) + { + *status = A_TRUE; + } + else + { + *status = A_FALSE; + } + } + + return SW_OK; + +} +#ifndef IN_PORTCONTROL_MINI +sw_error_t +adpt_hppe_port_8023az_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_8023az_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_8023az_set (dev_id, phy_id, enable); + + return rv; + +} +sw_error_t +adpt_hppe_port_powersave_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_powersave_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_powersave_get (dev_id, phy_id, enable); + + return rv; + +} + +sw_error_t +adpt_hppe_port_combo_prefer_medium_get(a_uint32_t dev_id, + a_uint32_t port_id, + fal_port_medium_t * + medium) +{ + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(medium); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_combo_prefer_medium_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_combo_prefer_medium_get (dev_id, phy_id, medium); + + return rv; + +} +#endif +sw_error_t +adpt_hppe_port_max_frame_size_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t *max_frame) +{ + sw_error_t rv = SW_OK; + a_uint32_t port_mac_type = 0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(max_frame); + + port_mac_type =qca_hppe_port_mac_type_get(dev_id, port_id); + if (port_mac_type == PORT_XGMAC_TYPE) + { + rv = _adpt_xgmac_port_max_frame_size_get( dev_id, port_id, max_frame); + } + else if (port_mac_type == PORT_GMAC_TYPE) + { + rv = _adpt_gmac_port_max_frame_size_get( dev_id, port_id, max_frame); + } + else + { + return SW_BAD_VALUE; + } + + return rv; +} + +sw_error_t +adpt_ppe_port_max_frame_size_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t *max_frame) +{ +#ifdef CPPE + if (adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION && + port_id == SSDK_PHYSICAL_PORT6) + { + return adpt_cppe_lpbk_max_frame_size_get(dev_id, port_id, max_frame); + } +#endif + return adpt_hppe_port_max_frame_size_get(dev_id, port_id, max_frame); + +} + +#ifndef IN_PORTCONTROL_MINI +sw_error_t +adpt_hppe_port_combo_prefer_medium_set(a_uint32_t dev_id, + a_uint32_t port_id, + fal_port_medium_t medium) +{ + + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_combo_prefer_medium_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_combo_prefer_medium_set (dev_id, phy_id, medium); + + return rv; + +} +#endif +sw_error_t +adpt_hppe_port_power_off(a_uint32_t dev_id, fal_port_t port_id) +{ + + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_power_off) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_power_off(dev_id, phy_id); + + return rv; + +} +sw_error_t +adpt_hppe_port_txfc_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv = SW_OK; + a_uint32_t port_mac_type; + struct qca_phy_priv *priv = ssdk_phy_priv_data_get(dev_id); + adpt_api_t *p_adpt_api; + + ADPT_DEV_ID_CHECK(dev_id); + + if (!priv) + return SW_FAIL; + + if ((port_id < SSDK_PHYSICAL_PORT1) || (port_id > SSDK_PHYSICAL_PORT6)) + return SW_BAD_VALUE; + + port_mac_type =qca_hppe_port_mac_type_get(dev_id, port_id); + if (port_mac_type == PORT_XGMAC_TYPE) + rv = _adpt_xgmac_port_txfc_status_set( dev_id, port_id, enable); + else if (port_mac_type == PORT_GMAC_TYPE) + rv = _adpt_gmac_port_txfc_status_set( dev_id, port_id, enable); + else + return SW_BAD_VALUE; + + if (rv != SW_OK) + return rv; + + priv->port_old_tx_flowctrl[port_id - 1] = enable; + + /*keep bm status same with port*/ + p_adpt_api = adpt_api_ptr_get(dev_id); + if (p_adpt_api && p_adpt_api->adpt_port_bm_ctrl_set) + rv = p_adpt_api->adpt_port_bm_ctrl_set(dev_id, + PHY_PORT_TO_BM_PORT(port_id), + enable); + + return rv; +} +#ifndef IN_PORTCONTROL_MINI +sw_error_t +adpt_hppe_port_counter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_counter_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_counter_set (dev_id, phy_id, enable); + + return rv; +} +sw_error_t +adpt_hppe_port_combo_fiber_mode_get(a_uint32_t dev_id, + a_uint32_t port_id, + fal_port_fiber_mode_t * mode) +{ + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(mode); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_combo_fiber_mode_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_combo_fiber_mode_get (dev_id, phy_id, mode); + + return rv; + +} + +sw_error_t +adpt_hppe_port_local_loopback_set(a_uint32_t dev_id, + fal_port_t port_id, + a_bool_t enable) +{ + + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_local_loopback_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_local_loopback_set (dev_id, phy_id, enable); + + return rv; + +} +sw_error_t +adpt_hppe_port_wol_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_wol_status_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_wol_status_set (dev_id, phy_id, enable); + + return rv; + + +} +sw_error_t +adpt_hppe_port_magic_frame_mac_get(a_uint32_t dev_id, fal_port_t port_id, + fal_mac_addr_t * mac) +{ + + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(mac); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_magic_frame_mac_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_magic_frame_mac_get (dev_id, phy_id,mac); + + return rv; + +} + +sw_error_t +adpt_hppe_port_flowctrl_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv = SW_OK; + a_bool_t txfc_enable, rxfc_enable; + +#if defined(CPPE) + if ((adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) && + (port_id == SSDK_PHYSICAL_PORT6)) { + return adpt_cppe_switch_port_loopback_flowctrl_get(dev_id, + port_id, enable); + } +#endif + rv = adpt_hppe_port_txfc_status_get(dev_id, port_id, &txfc_enable); + rv |= adpt_hppe_port_rxfc_status_get(dev_id, port_id, &rxfc_enable); + if(rv != SW_OK) + return rv; + *enable = txfc_enable & rxfc_enable; + + return SW_OK; +} +#endif +sw_error_t +adpt_hppe_port_rxmac_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t port_mac_type; + + ADPT_DEV_ID_CHECK(dev_id); + + port_mac_type =qca_hppe_port_mac_type_get(dev_id, port_id); + if (port_mac_type == PORT_XGMAC_TYPE) + _adpt_xgmac_port_rx_status_set(dev_id, port_id, enable); + else if (port_mac_type == PORT_GMAC_TYPE) + _adpt_gmac_port_rx_status_set(dev_id, port_id, enable); + else + return SW_BAD_VALUE; + + return SW_OK; +} +#ifndef IN_PORTCONTROL_MINI +sw_error_t +adpt_hppe_port_counter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_counter_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_counter_get (dev_id, phy_id, enable); + + return rv; + +} +#endif + +static sw_error_t +_adpt_hppe_port_interface_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_interface_mode_t mode) +{ + sw_error_t rv = SW_OK; + + ADPT_DEV_ID_CHECK(dev_id); + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_EXCL_CPU) && + mode != PORT_INTERFACE_MODE_MAX) + { + return SW_BAD_PARAM; + } + + port_interface_mode[dev_id][port_id] = mode; + + return rv; +} + +sw_error_t +adpt_hppe_port_interface_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_interface_mode_t mode) +{ + sw_error_t rv = SW_OK; + struct qca_phy_priv *priv; + + priv = ssdk_phy_priv_data_get(dev_id); + SW_RTN_ON_NULL(priv); + qca_mac_sw_sync_work_stop(priv); + + rv = _adpt_hppe_port_interface_mode_set(dev_id, port_id, mode); + + return rv; +} + +static sw_error_t +_adpt_hppe_gmac_speed_set(a_uint32_t dev_id, a_uint32_t port_id, fal_port_speed_t speed) +{ + sw_error_t rv = SW_OK; + union mac_speed_u mac_speed; + + memset(&mac_speed, 0, sizeof(mac_speed)); + ADPT_DEV_ID_CHECK(dev_id); + + port_id = HPPE_TO_GMAC_PORT_ID(port_id); + hppe_mac_speed_get(dev_id, port_id, &mac_speed); + + if(FAL_SPEED_10 == speed) + mac_speed.bf.mac_speed = MAC_SPEED_10M; + else if(FAL_SPEED_100 == speed) + mac_speed.bf.mac_speed = MAC_SPEED_100M; + else if(FAL_SPEED_1000 == speed || FAL_SPEED_2500 == speed) + mac_speed.bf.mac_speed = MAC_SPEED_1000M; + + rv = hppe_mac_speed_set(dev_id, port_id, &mac_speed); + + return rv; +} + +static sw_error_t +_adpt_hppe_xgmac_speed_set(a_uint32_t dev_id, a_uint32_t port_id, fal_port_speed_t speed) +{ + sw_error_t rv = SW_OK; + union mac_tx_configuration_u mac_tx_configuration; + a_uint32_t mode = 0; + + memset(&mac_tx_configuration, 0, sizeof(mac_tx_configuration)); + ADPT_DEV_ID_CHECK(dev_id); + + port_id = HPPE_TO_XGMAC_PORT_ID(port_id); + hppe_mac_tx_configuration_get(dev_id, port_id, &mac_tx_configuration); + + if(FAL_SPEED_1000 == speed) + { + mac_tx_configuration.bf.uss= XGMAC_USXGMII_CLEAR; + mac_tx_configuration.bf.ss= XGMAC_SPEED_SELECT_1000M; + } + else if(FAL_SPEED_10000 == speed) + { + if (port_id == SSDK_PHYSICAL_PORT0) + { + mode = ssdk_dt_global_get_mac_mode(dev_id, SSDK_UNIPHY_INSTANCE1); + } + else + { + mode = ssdk_dt_global_get_mac_mode(dev_id, SSDK_UNIPHY_INSTANCE2); + } + if (mode == PORT_WRAPPER_USXGMII) + { + mac_tx_configuration.bf.uss= XGMAC_USXGMII_ENABLE; + mac_tx_configuration.bf.ss= XGMAC_SPEED_SELECT_10000M; + } + else + { + mac_tx_configuration.bf.uss= XGMAC_USXGMII_CLEAR; + mac_tx_configuration.bf.ss= XGMAC_SPEED_SELECT_10000M; + } + } + else if(FAL_SPEED_5000 == speed) + { + mac_tx_configuration.bf.uss= XGMAC_USXGMII_ENABLE; + mac_tx_configuration.bf.ss= XGMAC_SPEED_SELECT_5000M; + } + else if(FAL_SPEED_2500 == speed) + { + if (port_id == SSDK_PHYSICAL_PORT0) + { + mode = ssdk_dt_global_get_mac_mode(dev_id, SSDK_UNIPHY_INSTANCE1); + } + else + { + mode = ssdk_dt_global_get_mac_mode(dev_id, SSDK_UNIPHY_INSTANCE2); + } + if (mode == PORT_WRAPPER_USXGMII) + { + mac_tx_configuration.bf.uss= XGMAC_USXGMII_ENABLE; + mac_tx_configuration.bf.ss= XGMAC_SPEED_SELECT_2500M; + } + else + { + mac_tx_configuration.bf.uss= XGMAC_USXGMII_CLEAR; + mac_tx_configuration.bf.ss= XGMAC_SPEED_SELECT_2500M; + } + } + else if(FAL_SPEED_100 == speed) + { + mac_tx_configuration.bf.uss= XGMAC_USXGMII_CLEAR; + mac_tx_configuration.bf.ss= XGMAC_SPEED_SELECT_1000M; + } + else if(FAL_SPEED_10 == speed) + { + mac_tx_configuration.bf.uss= XGMAC_USXGMII_CLEAR; + mac_tx_configuration.bf.ss= XGMAC_SPEED_SELECT_1000M; + } + + rv = hppe_mac_tx_configuration_set(dev_id, port_id, &mac_tx_configuration); + + return rv; +} + +static sw_error_t +_adpt_hppe_gmac_duplex_set(a_uint32_t dev_id, a_uint32_t port_id, fal_port_duplex_t duplex) +{ + sw_error_t rv = SW_OK; + union mac_enable_u mac_enable; + + memset(&mac_enable, 0, sizeof(mac_enable)); + ADPT_DEV_ID_CHECK(dev_id); + + port_id = HPPE_TO_GMAC_PORT_ID(port_id); + hppe_mac_enable_get(dev_id, port_id, &mac_enable); + + if (FAL_FULL_DUPLEX == duplex) + mac_enable.bf.duplex = 1; + else + mac_enable.bf.duplex = 0; + + rv = hppe_mac_enable_set(dev_id, port_id, &mac_enable); + + return rv; +} + +sw_error_t +adpt_hppe_port_mac_duplex_set(a_uint32_t dev_id, a_uint32_t port_id, fal_port_duplex_t duplex) +{ + sw_error_t rv = SW_OK; + a_uint32_t port_mac_type; + + port_mac_type = qca_hppe_port_mac_type_get(dev_id, port_id); + if (port_mac_type == PORT_XGMAC_TYPE) + { + return rv; + } + else if (port_mac_type == PORT_GMAC_TYPE) + { + rv = _adpt_hppe_gmac_duplex_set(dev_id, port_id, duplex); + } + else + { + return SW_BAD_VALUE; + } + + return rv; +} + +static sw_error_t +_adpt_hppe_port_mux_mac_set(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t port_type) +{ + sw_error_t rv = SW_OK; + union port_mux_ctrl_u port_mux_ctrl; + a_uint32_t mode0, mode1; + + memset(&port_mux_ctrl, 0, sizeof(port_mux_ctrl)); + ADPT_DEV_ID_CHECK(dev_id); + + rv = hppe_port_mux_ctrl_get(dev_id, &port_mux_ctrl); + port_mux_ctrl.bf.port4_pcs_sel = PORT4_PCS_SEL_GMII_FROM_PCS0; + + if (port_id == HPPE_MUX_PORT1) + { + if (port_type == PORT_GMAC_TYPE) + { + mode0 = ssdk_dt_global_get_mac_mode(dev_id, SSDK_UNIPHY_INSTANCE0); + mode1 = ssdk_dt_global_get_mac_mode(dev_id, SSDK_UNIPHY_INSTANCE1); + if ((mode0 == PORT_WRAPPER_PSGMII) || + (mode0 == PORT_WRAPPER_PSGMII_FIBER) || + (mode0 == PORT_WRAPPER_SGMII4_RGMII4) || + (mode0 == PORT_WRAPPER_SGMII_CHANNEL4)) + { + port_mux_ctrl.bf.port5_pcs_sel = PORT5_PCS_SEL_GMII_FROM_PCS0; + port_mux_ctrl.bf.port5_gmac_sel = PORT5_GMAC_SEL_GMAC; + } + if (mode1 == PORT_WRAPPER_SGMII0_RGMII4 || + mode1 == PORT_WRAPPER_SGMII_CHANNEL0 || + mode1 == PORT_WRAPPER_SGMII_PLUS || + mode1 == PORT_WRAPPER_SGMII_FIBER) + { + port_mux_ctrl.bf.port5_pcs_sel = PORT5_PCS_SEL_GMII_FROM_PCS1; + port_mux_ctrl.bf.port5_gmac_sel = PORT5_GMAC_SEL_GMAC; + } + } + else if (port_type == PORT_XGMAC_TYPE) + { + port_mux_ctrl.bf.port5_pcs_sel = PORT5_PCS_SEL_GMII_FROM_PCS1; + port_mux_ctrl.bf.port5_gmac_sel = PORT5_GMAC_SEL_XGMAC; + } + else + return SW_NOT_SUPPORTED; + } + else if (port_id == HPPE_MUX_PORT2) + { + if (port_type == PORT_GMAC_TYPE) + { + port_mux_ctrl.bf.port6_pcs_sel = PORT6_PCS_SEL_GMII_FROM_PCS2; + port_mux_ctrl.bf.port6_gmac_sel = PORT6_GMAC_SEL_GMAC; + } + else if (port_type == PORT_XGMAC_TYPE) + { + port_mux_ctrl.bf.port6_pcs_sel = PORT6_PCS_SEL_GMII_FROM_PCS2; + port_mux_ctrl.bf.port6_gmac_sel = PORT6_GMAC_SEL_XGMAC; + } + else + return SW_NOT_SUPPORTED; + } + else + return SW_OK; + + rv = hppe_port_mux_ctrl_set(dev_id, &port_mux_ctrl); + + return rv; +} + +static sw_error_t +adpt_hppe_port_xgmac_promiscuous_mode_set(a_uint32_t dev_id, + a_uint32_t port_id) +{ + sw_error_t rv = 0; + + port_id = HPPE_TO_XGMAC_PORT_ID(port_id); + + rv = hppe_mac_packet_filter_pr_set(dev_id, port_id, PROMISCUOUS_MODE); + + SW_RTN_ON_ERROR (rv); + + rv = hppe_mac_packet_filter_pcf_set(dev_id, port_id, PASS_CONTROL_PACKET); + + return rv; +} +static sw_error_t +adpt_hppe_port_speed_change_mac_reset(a_uint32_t dev_id, a_uint32_t port_id) +{ + a_uint32_t uniphy_index = 0, mode = 0; + a_uint32_t rxfc_status = 0, txfc_status = 0; + sw_error_t rv = 0; + + if (port_id == HPPE_MUX_PORT1) { + uniphy_index = SSDK_UNIPHY_INSTANCE1; + } else if (port_id == HPPE_MUX_PORT2) { + uniphy_index = SSDK_UNIPHY_INSTANCE2; + } else { + return SW_OK; + } + mode = ssdk_dt_global_get_mac_mode(dev_id, uniphy_index); + if (mode == PORT_WRAPPER_USXGMII) { + ssdk_port_mac_clock_reset(dev_id, port_id); + /*restore xgmac's pr and pcf setting after reset operation*/ + rv = adpt_hppe_port_xgmac_promiscuous_mode_set(dev_id, + port_id); + SW_RTN_ON_ERROR(rv); + /*flowctrl need to be configured when reset XGMAC*/ + rv = _adpt_xgmac_port_rxfc_status_get(dev_id, port_id, + &rxfc_status); + SW_RTN_ON_ERROR(rv); + rv = _adpt_xgmac_port_rxfc_status_set(dev_id, port_id, + rxfc_status); + SW_RTN_ON_ERROR(rv); + + rv = _adpt_xgmac_port_txfc_status_get(dev_id, port_id, + &txfc_status); + SW_RTN_ON_ERROR(rv); + rv = _adpt_xgmac_port_txfc_status_set(dev_id, port_id, + txfc_status); + } + return rv; +} +static sw_error_t +adpt_hppe_port_interface_mode_switch_mac_reset(a_uint32_t dev_id, + a_uint32_t port_id) +{ + a_uint32_t uniphy_index = 0, mode = 0; + sw_error_t rv = 0; + phy_type_t phy_type; + a_uint32_t port_mac_type; + + phy_type = hsl_phy_type_get(dev_id, port_id); + if (phy_type != AQUANTIA_PHY_CHIP && phy_type != SFP_PHY_CHIP) { + return SW_OK; + } + + if (port_id == HPPE_MUX_PORT1) { + uniphy_index = SSDK_UNIPHY_INSTANCE1; + } else if (port_id == HPPE_MUX_PORT2) { + uniphy_index = SSDK_UNIPHY_INSTANCE2; + } else { + return SW_OK; + } + + mode = ssdk_dt_global_get_mac_mode(dev_id, uniphy_index); + if ((mode == PORT_WRAPPER_USXGMII) || + (mode == PORT_WRAPPER_SGMII_CHANNEL0) || + (mode == PORT_WRAPPER_SGMII0_RGMII4) || + (mode == PORT_WRAPPER_SGMII_FIBER) || + (mode == PORT_WRAPPER_10GBASE_R)) { + ssdk_port_mac_clock_reset(dev_id, port_id); + port_mac_type = qca_hppe_port_mac_type_get(dev_id, port_id); + if (port_mac_type == PORT_XGMAC_TYPE) { + /*restore xgmac's pr and pcf setting after reset operation*/ + rv = adpt_hppe_port_xgmac_promiscuous_mode_set(dev_id, + port_id); + } + } + return rv; +} + +sw_error_t +adpt_hppe_port_mac_speed_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_port_speed_t speed) +{ + sw_error_t rv = SW_OK; + a_uint32_t port_mac_type; + + port_mac_type = qca_hppe_port_mac_type_get(dev_id, port_id); + if (port_mac_type == PORT_XGMAC_TYPE) + { + rv = _adpt_hppe_xgmac_speed_set(dev_id, port_id, speed); + + } + else if (port_mac_type == PORT_GMAC_TYPE) + { + rv = _adpt_hppe_gmac_speed_set(dev_id, port_id, speed); + } + else + { + return SW_BAD_VALUE; + } + return rv; +} +static sw_error_t +_adpt_hppe_port_mux_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mode1, a_uint32_t mode2) +{ + a_uint32_t mode = 0, port_type; + sw_error_t rv = SW_OK; + + port_type = qca_hppe_port_mac_type_get(dev_id, port_id); + if (port_type == PORT_GMAC_TYPE) + { + rv = adpt_hppe_port_mac_speed_set(dev_id, port_id, FAL_SPEED_1000); + rv = adpt_hppe_port_mac_duplex_set(dev_id, port_id, FAL_FULL_DUPLEX); + } + else if (port_type == PORT_XGMAC_TYPE) + { + if (port_id == HPPE_MUX_PORT1) + mode = mode1; + else if (port_id == HPPE_MUX_PORT2) + mode = mode2; + else + return SW_NOT_SUPPORTED; + if (mode == PORT_WRAPPER_SGMII_PLUS) + { + rv = adpt_hppe_port_mac_speed_set(dev_id, port_id, FAL_SPEED_2500); + rv = adpt_hppe_port_mac_duplex_set(dev_id, port_id, FAL_FULL_DUPLEX); + } + else + { + rv = adpt_hppe_port_mac_speed_set(dev_id, port_id, FAL_SPEED_10000); + rv = adpt_hppe_port_mac_duplex_set(dev_id, port_id, FAL_FULL_DUPLEX); + } + } + if ((port_type == PORT_GMAC_TYPE) ||(port_type == PORT_XGMAC_TYPE)) { + if (adpt_hppe_chip_revision_get(dev_id) == HPPE_REVISION) { + rv = _adpt_hppe_port_mux_mac_set(dev_id, port_id, port_type); + } else if (adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) { +#if defined(CPPE) + rv = _adpt_cppe_port_mux_mac_set(dev_id, port_id, port_type); +#endif + } + } + + if (port_id >= HPPE_MUX_PORT1) { + if (port_type == PORT_GMAC_TYPE) { + rv = _adpt_xgmac_port_txfc_status_set( dev_id, port_id, A_FALSE); + SW_RTN_ON_ERROR(rv); + rv = _adpt_xgmac_port_rxfc_status_set( dev_id, port_id, A_FALSE); + SW_RTN_ON_ERROR(rv); + } else if (port_type == PORT_XGMAC_TYPE) { + rv = _adpt_gmac_port_txfc_status_set( dev_id, port_id, A_FALSE); + SW_RTN_ON_ERROR(rv); + rv = _adpt_gmac_port_rxfc_status_set( dev_id, port_id, A_FALSE); + SW_RTN_ON_ERROR(rv); + } else { + return SW_NOT_SUPPORTED; + } + rv = adpt_hppe_port_interface_mode_switch_mac_reset(dev_id, port_id); + } + + return rv; +} + +sw_error_t +adpt_hppe_port_mux_mac_type_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mode0, a_uint32_t mode1, a_uint32_t mode2) +{ + sw_error_t rv = SW_OK; + a_uint32_t mode_tmp; + + /*init the port interface mode before set it according to three mac modes*/ + rv = _adpt_hppe_port_interface_mode_set(dev_id, port_id, PORT_INTERFACE_MODE_MAX); + SW_RTN_ON_ERROR(rv); + + switch (mode0) { + case PORT_WRAPPER_PSGMII_FIBER: + if(port_id >= SSDK_PHYSICAL_PORT1 && port_id <= SSDK_PHYSICAL_PORT5) + { + qca_hppe_port_mac_type_set(dev_id, port_id, PORT_GMAC_TYPE); + if (port_id == SSDK_PHYSICAL_PORT5) { + _adpt_hppe_port_interface_mode_set(dev_id, + SSDK_PHYSICAL_PORT5, PHY_PSGMII_FIBER); + } else { + _adpt_hppe_port_interface_mode_set(dev_id, + port_id, PHY_PSGMII_BASET); + } + } + break; + case PORT_WRAPPER_PSGMII: + if((port_id >= SSDK_PHYSICAL_PORT1 && port_id <= SSDK_PHYSICAL_PORT4) || + (port_id == SSDK_PHYSICAL_PORT5 && + mode1 == PORT_WRAPPER_MAX)) + { + qca_hppe_port_mac_type_set(dev_id, port_id, PORT_GMAC_TYPE); + _adpt_hppe_port_interface_mode_set(dev_id, port_id, PHY_PSGMII_BASET); + } + break; + case PORT_WRAPPER_QSGMII: + if(port_id >= SSDK_PHYSICAL_PORT1 && port_id <= SSDK_PHYSICAL_PORT4) + { + qca_hppe_port_mac_type_set(dev_id, port_id, PORT_GMAC_TYPE); + _adpt_hppe_port_interface_mode_set(dev_id, port_id, PORT_QSGMII); + } + break; + case PORT_WRAPPER_SGMII0_RGMII4: + case PORT_WRAPPER_SGMII_CHANNEL0: + case PORT_WRAPPER_SGMII_FIBER: +#ifdef CPPE + case PORT_WRAPPER_SGMII_PLUS: + if(adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION + && port_id == SSDK_PHYSICAL_PORT4) + { + qca_hppe_port_mac_type_set(dev_id, port_id, + PORT_GMAC_TYPE); + if((mode0 == PORT_WRAPPER_SGMII0_RGMII4 || + mode0 == PORT_WRAPPER_SGMII_CHANNEL0)) + { + if(hsl_port_prop_check (dev_id, port_id, + HSL_PP_EXCL_CPU)) + { + _adpt_hppe_port_interface_mode_set(dev_id, port_id, + PHY_SGMII_BASET); + } + else + { + SSDK_ERROR("Port bitmap is incorrect when port 4" + "support sgmii for CPPE\n"); + return SW_NOT_SUPPORTED; + } + } + else if(mode0 == PORT_WRAPPER_SGMII_PLUS) + { + _adpt_hppe_port_interface_mode_set(dev_id, port_id, + PORT_SGMII_PLUS); + } + else + { + SSDK_ERROR("CPPE doesn't support mode0 : %x\n", + mode0); + return SW_NOT_SUPPORTED; + } + break; + } +#endif + if(port_id == SSDK_PHYSICAL_PORT1) + { + qca_hppe_port_mac_type_set(dev_id, SSDK_PHYSICAL_PORT1, + PORT_GMAC_TYPE); + if(mode0 == PORT_WRAPPER_SGMII_FIBER) + { + _adpt_hppe_port_interface_mode_set(dev_id, + SSDK_PHYSICAL_PORT1, PORT_SGMII_FIBER); + } + else + { + _adpt_hppe_port_interface_mode_set(dev_id, + SSDK_PHYSICAL_PORT1, PHY_SGMII_BASET); + } + } + break; + case PORT_WRAPPER_SGMII1_RGMII4: + case PORT_WRAPPER_SGMII_CHANNEL1: + if(port_id == SSDK_PHYSICAL_PORT2) + { + qca_hppe_port_mac_type_set(dev_id, SSDK_PHYSICAL_PORT2, + PORT_GMAC_TYPE); + _adpt_hppe_port_interface_mode_set(dev_id, + SSDK_PHYSICAL_PORT2, PHY_SGMII_BASET); + } + break; + case PORT_WRAPPER_SGMII4_RGMII4: + case PORT_WRAPPER_SGMII_CHANNEL4: + if(port_id == SSDK_PHYSICAL_PORT5) + { + qca_hppe_port_mac_type_set(dev_id, SSDK_PHYSICAL_PORT5, + PORT_GMAC_TYPE); + _adpt_hppe_port_interface_mode_set(dev_id, + SSDK_PHYSICAL_PORT5, PHY_SGMII_BASET); + } + break; + default: + break; + } + if(port_id == SSDK_PHYSICAL_PORT5 ||port_id == SSDK_PHYSICAL_PORT6) + { + if(port_id == SSDK_PHYSICAL_PORT5) + mode_tmp = mode1; + else + mode_tmp = mode2; + + switch(mode_tmp) + { + case PORT_WRAPPER_SGMII_CHANNEL0: + case PORT_WRAPPER_SGMII0_RGMII4: + case PORT_WRAPPER_SGMII_FIBER: + qca_hppe_port_mac_type_set(dev_id, port_id, PORT_GMAC_TYPE); + if(mode_tmp == PORT_WRAPPER_SGMII_FIBER) + { + _adpt_hppe_port_interface_mode_set(dev_id, port_id, + PORT_SGMII_FIBER); + } + else + { + _adpt_hppe_port_interface_mode_set(dev_id, port_id, + PHY_SGMII_BASET); + } + break; + case PORT_WRAPPER_SGMII_PLUS: + if (ssdk_port_feature_get(dev_id, port_id, PHY_F_QGMAC)) { + qca_hppe_port_mac_type_set(dev_id, port_id, + PORT_GMAC_TYPE); + } else { + qca_hppe_port_mac_type_set(dev_id, port_id, + PORT_XGMAC_TYPE); + } + _adpt_hppe_port_interface_mode_set(dev_id, port_id, PORT_SGMII_PLUS); + break; + case PORT_WRAPPER_USXGMII: + qca_hppe_port_mac_type_set(dev_id, port_id, PORT_XGMAC_TYPE); + _adpt_hppe_port_interface_mode_set(dev_id, port_id, PORT_USXGMII); + break; + case PORT_WRAPPER_10GBASE_R: + qca_hppe_port_mac_type_set(dev_id, port_id, PORT_XGMAC_TYPE); + _adpt_hppe_port_interface_mode_set(dev_id, port_id, PORT_10GBASE_R); + break; + default: + break; + } + } + + rv = _adpt_hppe_port_mux_set(dev_id, port_id,mode1, mode2); + + return rv; +} + +static sw_error_t +_adpt_hppe_instance0_mode_get(a_uint32_t dev_id, a_uint32_t *mode0) +{ + a_uint32_t port_id = 0; + + for(port_id = SSDK_PHYSICAL_PORT1; port_id <= SSDK_PHYSICAL_PORT5; port_id++) + { + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_EXCL_CPU)) + { + continue; + } + SSDK_DEBUG("port_id:%d, port_interface_mode:%d\n", port_id, + port_interface_mode[dev_id][port_id]); + if(port_interface_mode[dev_id][port_id] == PHY_PSGMII_BASET) + { + if(*mode0 != PORT_WRAPPER_MAX && *mode0 != PORT_WRAPPER_PSGMII) + { + SSDK_ERROR("when the port_interface_mode of port %d is %d, " + "mode0:%d cannot be supported\n", + port_id, port_interface_mode[dev_id][port_id], *mode0); + return SW_NOT_SUPPORTED; + } + *mode0 = PORT_WRAPPER_PSGMII; + } + + if(port_interface_mode[dev_id][port_id] == PHY_PSGMII_FIBER && + port_id == SSDK_PHYSICAL_PORT5) + { + *mode0 = PORT_WRAPPER_PSGMII_FIBER; + } + + if(port_interface_mode[dev_id][port_id] == PORT_QSGMII) + { + if((*mode0 != PORT_WRAPPER_MAX && *mode0 != PORT_WRAPPER_QSGMII) || + port_id == SSDK_PHYSICAL_PORT5) + { + SSDK_ERROR("when the port_interface_mode of port %d is %d, " + "mode0:%d cannot be supported\n", + port_id, port_interface_mode[dev_id][port_id], *mode0); + return SW_NOT_SUPPORTED; + } + *mode0 = PORT_WRAPPER_QSGMII; + } + + if(port_interface_mode[dev_id][port_id] == PHY_SGMII_BASET || + port_interface_mode[dev_id][port_id] == PORT_SGMII_FIBER) + { + if(*mode0 !=PORT_WRAPPER_MAX) + { + if(port_id != SSDK_PHYSICAL_PORT5) + { + SSDK_ERROR("when the port_interface_mode of port %d is %d, " + "mode0:%d cannot be supported\n", + port_id, port_interface_mode[dev_id][port_id], + *mode0); + return SW_NOT_SUPPORTED; + } + else + { + return SW_OK; + } + } + switch(port_id) + { + case SSDK_PHYSICAL_PORT1: + if(port_interface_mode[dev_id][port_id] == PORT_SGMII_FIBER) + { + *mode0 = PORT_WRAPPER_SGMII_FIBER; + } + else + { + *mode0 = PORT_WRAPPER_SGMII_CHANNEL0; + } + break; + case SSDK_PHYSICAL_PORT2: + *mode0 = PORT_WRAPPER_SGMII_CHANNEL1; + break; +#ifdef CPPE + case SSDK_PHYSICAL_PORT4: + if(adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) + { + *mode0 = PORT_WRAPPER_SGMII_CHANNEL0; + } + break; +#endif + case SSDK_PHYSICAL_PORT5: + *mode0 = PORT_WRAPPER_SGMII_CHANNEL4; + break; + default: + SSDK_ERROR("port %d doesn't support " + "port_interface_mode %d\n", + port_id, port_interface_mode[dev_id][port_id]); + return SW_NOT_SUPPORTED; + } + } + if(port_id != SSDK_PHYSICAL_PORT5 && + (port_interface_mode[dev_id][port_id] == PORT_SGMII_PLUS || + port_interface_mode[dev_id][port_id] ==PORT_USXGMII || + port_interface_mode[dev_id][port_id] == PORT_10GBASE_R)) + { +#ifdef CPPE + if(port_interface_mode[dev_id][port_id] == PORT_SGMII_PLUS + && adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION + && port_id == SSDK_PHYSICAL_PORT4) + { + *mode0 = PORT_WRAPPER_SGMII_PLUS; + continue; + } +#endif + SSDK_ERROR("port %d doesn't support port_interface_mode %d\n", + port_id, port_interface_mode[dev_id][port_id]); + return SW_NOT_SUPPORTED; + } + } + + return SW_OK; +} + +static sw_error_t +_adpt_hppe_instance1_mode_get(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t *mode) +{ + if ((A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_EXCL_CPU)) || + A_TRUE == hsl_port_prop_check (dev_id, port_id, HSL_PP_INNER)) + { + return SW_OK; + } + SSDK_DEBUG("port_id:%x: %x\n", port_id, port_interface_mode[dev_id][port_id]); + switch(port_interface_mode[dev_id][port_id]) + { + case PHY_SGMII_BASET: + *mode = PORT_WRAPPER_SGMII_CHANNEL0; + break; + case PORT_SGMII_PLUS: + *mode = PORT_WRAPPER_SGMII_PLUS; + break; + case PORT_USXGMII: + *mode = PORT_WRAPPER_USXGMII; + break; + case PORT_10GBASE_R: + *mode = PORT_WRAPPER_10GBASE_R; + break; + case PORT_SGMII_FIBER: + *mode = PORT_WRAPPER_SGMII_FIBER; + break; + case PHY_PSGMII_BASET: + case PHY_PSGMII_FIBER: + if(port_id == SSDK_PHYSICAL_PORT6) + { + SSDK_ERROR("port %d doesn't support port_interface_mode %d\n", + port_id, port_interface_mode[dev_id][port_id]); + return SW_NOT_SUPPORTED; + } + *mode = PORT_INTERFACE_MODE_MAX; + break; + case PORT_INTERFACE_MODE_MAX: + break; + default: + SSDK_ERROR("port %d doesn't support port_interface_mode %d\n", + port_id, port_interface_mode[dev_id][port_id]); + return SW_NOT_SUPPORTED; + } + + return SW_OK; +} + +static sw_error_t +_adpt_hppe_instance_mode_get(a_uint32_t dev_id, a_uint32_t uniphy_index, + a_uint32_t *interface_mode) +{ + sw_error_t rv = SW_OK; + + switch(uniphy_index) + { + case SSDK_UNIPHY_INSTANCE0: + rv = _adpt_hppe_instance0_mode_get(dev_id, interface_mode); + SW_RTN_ON_ERROR(rv); + break; + case SSDK_UNIPHY_INSTANCE1: + rv =_adpt_hppe_instance1_mode_get(dev_id, SSDK_PHYSICAL_PORT5, + interface_mode); + SW_RTN_ON_ERROR(rv); + break; + case SSDK_UNIPHY_INSTANCE2: + rv =_adpt_hppe_instance1_mode_get(dev_id, SSDK_PHYSICAL_PORT6, + interface_mode); + SW_RTN_ON_ERROR(rv); + break; + default: + return SW_NOT_SUPPORTED; + } + + return rv; +} + +extern sw_error_t +adpt_hppe_uniphy_mode_set(a_uint32_t dev_id, a_uint32_t index, a_uint32_t mode); + +static sw_error_t +_adpt_hppe_port_interface_mode_phy_config(a_uint32_t dev_id, a_uint32_t port_id, + fal_port_interface_mode_t mode) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + SSDK_ERROR("port %d is not in bitmap\n", port_id); + return SW_BAD_PARAM; + } + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_interface_mode_set) + { + SSDK_ERROR("the phy_interface_mode_set api is null for port %d\n", + port_id); + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + SSDK_DEBUG("port_id:%d, phy_id:%d, mode:%d\n", port_id, phy_id, mode); + rv = phy_drv->phy_interface_mode_set (dev_id, phy_id,mode); + + return rv; +} + +static sw_error_t _adpt_hppe_port_mac_set(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t enable) +{ + sw_error_t rv = SW_OK; + + rv = adpt_hppe_port_txmac_status_set(dev_id, port_id, enable); + SW_RTN_ON_ERROR(rv); + rv = adpt_hppe_port_rxmac_status_set(dev_id, port_id, enable); + + return rv; +} + +static sw_error_t +_adpt_hppe_port_phyaddr_update(a_uint32_t dev_id, a_uint32_t port_id, + a_uint32_t mode) +{ + sw_error_t rv = SW_OK; + a_uint32_t phy_addr = 0, mode0 = PORT_WRAPPER_MAX; + ssdk_port_phyinfo *port_phyinfo = NULL; + + if(port_id != SSDK_PHYSICAL_PORT5) + { + return rv; + } + if(mode == PORT_WRAPPER_10GBASE_R) + { + port_phyinfo = ssdk_port_phyinfo_get(dev_id, port_id); + if (!port_phyinfo) + { + SSDK_ERROR("port_phyinfo of port%d is null\n", port_id); + return SW_FAIL; + } + phy_addr = port_phyinfo->phy_addr; + qca_ssdk_phy_address_set(dev_id, port_id, phy_addr); + hsl_port_phy_access_type_set(dev_id, port_id, PHY_I2C_ACCESS); + SSDK_DEBUG("port %x phy_addr is %x\n", port_id, phy_addr); + } + else + { + mode0 = ssdk_dt_global_get_mac_mode(dev_id, SSDK_UNIPHY_INSTANCE0); + if((mode0 == PORT_WRAPPER_PSGMII || mode0 == PORT_WRAPPER_PSGMII_FIBER) && + mode == PORT_WRAPPER_MAX) + { + rv = hsl_port_prop_get_phyid (dev_id, SSDK_PHYSICAL_PORT4, &phy_addr); + SW_RTN_ON_ERROR (rv); + phy_addr++; + qca_ssdk_phy_address_set(dev_id, port_id, phy_addr); + hsl_port_phy_access_type_set(dev_id, port_id, PHY_MDIO_ACCESS); + SSDK_DEBUG("port %x phy_addr is %x\n", port_id, phy_addr); + } + } + + return rv; +} + +static sw_error_t +_adpt_hppe_sfp_copper_phydriver_switch(a_uint32_t dev_id, a_uint32_t port_id, + a_uint32_t mode) +{ + sw_error_t rv = SW_OK; + + rv = _adpt_hppe_port_phyaddr_update(dev_id, port_id, mode); + SW_RTN_ON_ERROR(rv); + rv = hsl_phydriver_update(dev_id, port_id, mode); + + return rv; +} + +static sw_error_t +_adpt_hppe_port_phy_config(a_uint32_t dev_id, a_uint32_t index, a_uint32_t mode) +{ + sw_error_t rv = SW_OK; + + switch(mode) + { + case PORT_WRAPPER_PSGMII: + /*interface mode changed form psgmii+usxgmii to psgmii+10gbase-r+usxgmii, cannot + use port 5 to configure malibu*/ + rv = _adpt_hppe_port_interface_mode_phy_config(dev_id, + SSDK_PHYSICAL_PORT4, PHY_PSGMII_BASET); + break; + case PORT_WRAPPER_PSGMII_FIBER: + rv = _adpt_hppe_port_interface_mode_phy_config(dev_id, + SSDK_PHYSICAL_PORT4, PHY_PSGMII_FIBER); + break; + case PORT_WRAPPER_SGMII_CHANNEL4: + rv = _adpt_hppe_port_interface_mode_phy_config(dev_id, + SSDK_PHYSICAL_PORT5, PHY_SGMII_BASET); + break; + case PORT_WRAPPER_QSGMII: + rv = _adpt_hppe_port_interface_mode_phy_config(dev_id, + SSDK_PHYSICAL_PORT4, PORT_QSGMII); + break; + case PORT_WRAPPER_SGMII_CHANNEL0: +#ifdef CPPE + if(index == SSDK_UNIPHY_INSTANCE0 && + adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION && + (hsl_port_prop_check (dev_id, SSDK_PHYSICAL_PORT4, + HSL_PP_EXCL_CPU))) + { + rv = _adpt_hppe_port_interface_mode_phy_config(dev_id, + SSDK_PHYSICAL_PORT4, PHY_SGMII_BASET); + } +#endif + if(index == SSDK_UNIPHY_INSTANCE1) + { + rv = _adpt_hppe_port_interface_mode_phy_config(dev_id, + SSDK_PHYSICAL_PORT5, PHY_SGMII_BASET); + } + if(index == SSDK_UNIPHY_INSTANCE2) + { + rv = _adpt_hppe_port_interface_mode_phy_config(dev_id, + SSDK_PHYSICAL_PORT6, PHY_SGMII_BASET); + } + break; + case PORT_WRAPPER_USXGMII: + if(index == SSDK_UNIPHY_INSTANCE1) + { + rv = _adpt_hppe_port_interface_mode_phy_config(dev_id, + SSDK_PHYSICAL_PORT5, PORT_USXGMII); + } + if(index == SSDK_UNIPHY_INSTANCE2) + { + rv = _adpt_hppe_port_interface_mode_phy_config(dev_id, + SSDK_PHYSICAL_PORT6, PORT_USXGMII); + } + break; + case PORT_WRAPPER_SGMII_PLUS: +#ifdef CPPE + if(index == SSDK_UNIPHY_INSTANCE0 && + adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) + { + rv = _adpt_hppe_port_interface_mode_phy_config(dev_id, + SSDK_PHYSICAL_PORT4, PORT_SGMII_PLUS); + } +#endif + if(index == SSDK_UNIPHY_INSTANCE1) + { + rv = _adpt_hppe_port_interface_mode_phy_config(dev_id, + SSDK_PHYSICAL_PORT5, PORT_SGMII_PLUS); + } + if(index == SSDK_UNIPHY_INSTANCE2) + { + rv = _adpt_hppe_port_interface_mode_phy_config(dev_id, + SSDK_PHYSICAL_PORT6, PORT_SGMII_PLUS); + } + break; + default: + break; + } + + return rv; +} + +static sw_error_t +adpt_hppe_port_mac_uniphy_phy_config(a_uint32_t dev_id, a_uint32_t mode_index, + a_uint32_t mode[], a_bool_t force_switch) +{ + sw_error_t rv = SW_OK; + a_uint32_t port_id = 0, port_id_from = 0, port_id_end = 0; + + if(mode_index == SSDK_UNIPHY_INSTANCE0) + { + switch (mode[SSDK_UNIPHY_INSTANCE0]) + { + case PORT_WRAPPER_PSGMII: + case PORT_WRAPPER_PSGMII_FIBER: + port_id_from = SSDK_PHYSICAL_PORT1; + /*qsgmii+10gbase-r+usxgmii --> psgmii+10gbase-r+usxgmii*/ + if(mode[SSDK_UNIPHY_INSTANCE1] != PORT_WRAPPER_MAX) + { + port_id_end = SSDK_PHYSICAL_PORT4; + } + else + { + port_id_end = SSDK_PHYSICAL_PORT5; + } + break; + case PORT_WRAPPER_QSGMII: + port_id_from = SSDK_PHYSICAL_PORT1; + port_id_end = SSDK_PHYSICAL_PORT4; + break; + case PORT_WRAPPER_SGMII0_RGMII4: + case PORT_WRAPPER_SGMII_CHANNEL0: + case PORT_WRAPPER_SGMII_FIBER: +#ifdef CPPE + case PORT_WRAPPER_SGMII_PLUS: + if(adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) + { + a_uint32_t mode_tmp = 0; + mode_tmp = mode[SSDK_UNIPHY_INSTANCE0]; + if (mode_tmp == PORT_WRAPPER_SGMII_PLUS || + ((mode_tmp == PORT_WRAPPER_SGMII0_RGMII4 || + mode_tmp == PORT_WRAPPER_SGMII_CHANNEL0) && + (hsl_port_prop_check (dev_id, SSDK_PHYSICAL_PORT4, + HSL_PP_EXCL_CPU)))) + { + port_id_from = SSDK_PHYSICAL_PORT4; + port_id_end = SSDK_PHYSICAL_PORT4; + break; + } + } +#endif + port_id_from = SSDK_PHYSICAL_PORT1; + port_id_end = SSDK_PHYSICAL_PORT1; + break; + case PORT_WRAPPER_SGMII1_RGMII4: + case PORT_WRAPPER_SGMII_CHANNEL1: + port_id_from = SSDK_PHYSICAL_PORT2; + port_id_end = SSDK_PHYSICAL_PORT2; + break; + case PORT_WRAPPER_SGMII4_RGMII4: + case PORT_WRAPPER_SGMII_CHANNEL4: + port_id_from = SSDK_PHYSICAL_PORT5; + port_id_end = SSDK_PHYSICAL_PORT5; + break; + default: + break; + } + } + else if(mode_index == SSDK_UNIPHY_INSTANCE1) + { + port_id_from = SSDK_PHYSICAL_PORT5; + port_id_end = SSDK_PHYSICAL_PORT5; + } + else if(mode_index == SSDK_UNIPHY_INSTANCE2) + { + port_id_from = SSDK_PHYSICAL_PORT6; + port_id_end = SSDK_PHYSICAL_PORT6; + } + else + { + return SW_NOT_SUPPORTED; + } + /*disable mac tx and rx for special ports*/ + for(port_id = port_id_from; port_id <= port_id_end; port_id++) + { + rv = _adpt_hppe_port_mac_set(dev_id, port_id, A_FALSE); + } + + /*configure the uniphy*/ + rv = adpt_hppe_uniphy_mode_set(dev_id, mode_index, mode[mode_index]); + SSDK_DEBUG("configure uniphy mode_index:%x, mode:%x, rv:%x\n", + mode_index, mode[mode_index], rv); + SW_RTN_ON_ERROR(rv); + + /*configure the mac*/ + for(port_id = port_id_from; port_id <= port_id_end; port_id++) + { + rv = adpt_hppe_port_mux_mac_type_set(dev_id, port_id, mode[SSDK_UNIPHY_INSTANCE0], + mode[SSDK_UNIPHY_INSTANCE1], mode[SSDK_UNIPHY_INSTANCE2]); + SSDK_DEBUG("configure mac, port_id is %x,mode0:%x,mode1:%x,mode2:%x, rv:%x\n", + port_id, mode[SSDK_UNIPHY_INSTANCE0], mode[SSDK_UNIPHY_INSTANCE1], + mode[SSDK_UNIPHY_INSTANCE2], rv); + SW_RTN_ON_ERROR(rv); + } + + /*configure the phy*/ + if(SSDK_PHYSICAL_PORT5 >= port_id_from && SSDK_PHYSICAL_PORT5 <= port_id_end) + { + rv = _adpt_hppe_sfp_copper_phydriver_switch(dev_id, SSDK_PHYSICAL_PORT5, + mode[SSDK_UNIPHY_INSTANCE1]); + } + SW_RTN_ON_ERROR(rv); + if (force_switch != A_FALSE) { + rv = _adpt_hppe_port_phy_config(dev_id, mode_index, mode[mode_index]); + SSDK_DEBUG("configure phy, mode_index:%x,interface_mode:%x, rv:%x\n", + mode_index, mode[mode_index], rv); + } + + /*init port status for special ports to triger polling*/ + for(port_id = port_id_from; port_id <= port_id_end; port_id++) + { + qca_mac_port_status_init(dev_id, port_id); + } + + return rv; +} + +sw_error_t +_adpt_hppe_port_interface_mode_apply(a_uint32_t dev_id, a_bool_t force_switch) +{ + sw_error_t rv = SW_OK; + a_uint32_t mode_index = 0, mode_old[3] = {0}; + a_uint32_t mode_new[3] = {PORT_WRAPPER_MAX,PORT_WRAPPER_MAX,PORT_WRAPPER_MAX}; + + /*get three intances mode, include old mode and new mode*/ + for(mode_index = SSDK_UNIPHY_INSTANCE0; mode_index <= SSDK_UNIPHY_INSTANCE2; mode_index++) + { + mode_old[mode_index] = ssdk_dt_global_get_mac_mode(dev_id, mode_index); + if(mode_index == SSDK_UNIPHY_INSTANCE1 && + mode_new[SSDK_UNIPHY_INSTANCE0] == PORT_WRAPPER_SGMII_CHANNEL4) + { + mode_new[SSDK_UNIPHY_INSTANCE1] = PORT_WRAPPER_MAX; + } + else + { + rv = _adpt_hppe_instance_mode_get(dev_id, mode_index, &mode_new[mode_index]); + SW_RTN_ON_ERROR(rv); + } + } + SSDK_DEBUG("mode0_old: %x, mode1_old:%x, mode2_old:%x\n", + mode_old[0], mode_old[1], mode_old[2]); + SSDK_DEBUG("mode0_new: %x, mode1_new:%x, mode2_new:%x\n", + mode_new[0], mode_new[1], mode_new[2]); + /*set three new intances mode*/ + for(mode_index = SSDK_UNIPHY_INSTANCE0; mode_index <= SSDK_UNIPHY_INSTANCE2; mode_index++) + { + ssdk_dt_global_set_mac_mode(dev_id, mode_index, mode_new[mode_index]); + } + /*configure the mode according to mode_new*/ + for(mode_index = SSDK_UNIPHY_INSTANCE0; mode_index <= SSDK_UNIPHY_INSTANCE2; mode_index++) + { + if(mode_new[mode_index] != mode_old[mode_index]) + { + SSDK_DEBUG("need to configure instance%x\n", mode_index); + rv = adpt_hppe_port_mac_uniphy_phy_config(dev_id, + mode_index, mode_new, force_switch); + if(rv) + { + SSDK_ERROR("config instance%x, rv:%x faild\n", mode_index,rv); + return rv; + } + } + } + + return rv; +} +#ifndef IN_PORTCONTROL_MINI +sw_error_t +adpt_hppe_port_interface_mode_apply(a_uint32_t dev_id) +{ + struct qca_phy_priv *priv; + sw_error_t rv = SW_OK; + + ADPT_DEV_ID_CHECK(dev_id); + priv = ssdk_phy_priv_data_get(dev_id); + if (!priv) + { + return SW_FAIL; + } + + mutex_lock(&priv->mac_sw_sync_lock); + rv = _adpt_hppe_port_interface_mode_apply(dev_id, A_TRUE); + mutex_unlock(&priv->mac_sw_sync_lock); + + qca_mac_sw_sync_work_resume(priv); + + return rv; +} + +sw_error_t +adpt_hppe_port_mac_loopback_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv = SW_OK; + a_uint32_t port_mac_type = 0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + + port_mac_type = qca_hppe_port_mac_type_get(dev_id, port_id); + if (port_mac_type == PORT_XGMAC_TYPE) + rv = _adpt_hppe_port_xgmac_loopback_get( dev_id, port_id, enable); + else if (port_mac_type == PORT_GMAC_TYPE) + rv = _adpt_hppe_port_gmac_loopback_get( dev_id, port_id, enable); + else + return SW_BAD_VALUE; + + return rv; +} + +sw_error_t +adpt_hppe_port_hibernate_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_hibernation_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_hibernation_get (dev_id, phy_id, enable); + + return rv; + +} +#endif +sw_error_t +adpt_hppe_port_autoneg_adv_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t autoadv) +{ + sw_error_t rv = 0; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_autoneg_adv_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_autoneg_adv_set (dev_id, phy_id, autoadv); + SW_RTN_ON_ERROR (rv); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)) + rv = hsl_port_phydev_adv_update (dev_id, port_id, autoadv); + SW_RTN_ON_ERROR (rv); +#endif + + return SW_OK; + +} +#ifndef IN_PORTCONTROL_MINI +sw_error_t +adpt_hppe_port_remote_loopback_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_remote_loopback_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_remote_loopback_get (dev_id, phy_id, enable); + + return rv; + +} + +sw_error_t +adpt_hppe_port_counter_show(a_uint32_t dev_id, fal_port_t port_id, + fal_port_counter_info_t * counter_info) +{ + + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(counter_info); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_counter_show) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_counter_show (dev_id, phy_id,counter_info); + + return rv; + +} +sw_error_t +adpt_hppe_port_mtu_get(a_uint32_t dev_id, fal_port_t port_id, + fal_mtu_ctrl_t *ctrl) +{ + sw_error_t rv = SW_OK; + union mru_mtu_ctrl_tbl_u mru_mtu_ctrl_tbl; + + memset(&mru_mtu_ctrl_tbl, 0, sizeof(mru_mtu_ctrl_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(ctrl); + + rv = hppe_mru_mtu_ctrl_tbl_get(dev_id, port_id, &mru_mtu_ctrl_tbl); + + if( rv != SW_OK ) + return rv; + + ctrl->mtu_size = mru_mtu_ctrl_tbl.bf.mtu; + ctrl->action = (fal_fwd_cmd_t)mru_mtu_ctrl_tbl.bf.mtu_cmd; + + return SW_OK; +} + +#endif +sw_error_t +adpt_hppe_port_autoneg_enable(a_uint32_t dev_id, fal_port_t port_id) +{ + + sw_error_t rv = 0; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_autoneg_enable_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_autoneg_enable_set (dev_id, phy_id); + return rv; + +} + +#ifndef IN_PORTCONTROL_MINI +sw_error_t +adpt_ppe_port_mtu_get(a_uint32_t dev_id, fal_port_t port_id, + fal_mtu_ctrl_t *ctrl) +{ + a_uint32_t chip_ver = 0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(ctrl); + + chip_ver = adpt_hppe_chip_revision_get(dev_id); + if (chip_ver == CPPE_REVISION) { +#if defined(CPPE) + return adpt_cppe_port_mtu_get(dev_id, port_id, ctrl); +#endif + } else { + return adpt_hppe_port_mtu_get(dev_id, port_id, ctrl); + } + + return SW_NOT_SUPPORTED; +} +#endif + +sw_error_t +adpt_hppe_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 = SW_OK; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(mode); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + /* for those ports without PHY device should be sfp port */ + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) { + rv = sfp_phy_interface_get_mode_status(dev_id, port_id, mode); + SW_RTN_ON_ERROR (rv); + } else { + SW_RTN_ON_NULL(phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_interface_mode_status_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_interface_mode_status_get (dev_id, phy_id,mode); + } + return rv; +} +#ifndef IN_PORTCONTROL_MINI +sw_error_t +adpt_hppe_port_reset(a_uint32_t dev_id, fal_port_t port_id) +{ + + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_reset) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_reset(dev_id, phy_id); + + return rv; + +} +#endif +sw_error_t +adpt_hppe_port_rxfc_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv = SW_OK; + a_uint32_t port_mac_type; + struct qca_phy_priv *priv = ssdk_phy_priv_data_get(dev_id); + + ADPT_DEV_ID_CHECK(dev_id); + + if (!priv) + return SW_FAIL; + + if ((port_id < SSDK_PHYSICAL_PORT1) || (port_id > SSDK_PHYSICAL_PORT6)) + return SW_BAD_VALUE; + + port_mac_type =qca_hppe_port_mac_type_get(dev_id, port_id); + if(port_mac_type == PORT_XGMAC_TYPE) + rv = _adpt_xgmac_port_rxfc_status_set( dev_id, port_id, enable); + else if (port_mac_type == PORT_GMAC_TYPE) + rv = _adpt_gmac_port_rxfc_status_set( dev_id, port_id, enable); + else + return SW_BAD_VALUE; + + if (rv != SW_OK) + return rv; + + priv->port_old_rx_flowctrl[port_id - 1] = enable; + + return SW_OK; +} +sw_error_t +adpt_hppe_port_flowctrl_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv = SW_OK; + struct qca_phy_priv *priv = ssdk_phy_priv_data_get(dev_id); + + if (!priv) + return SW_FAIL; + + if ((port_id < SSDK_PHYSICAL_PORT1) || (port_id > SSDK_PHYSICAL_PORT6)) + return SW_BAD_VALUE; +#if defined(CPPE) + if ((adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) && + (port_id == SSDK_PHYSICAL_PORT6)) { + return adpt_cppe_switch_port_loopback_flowctrl_set(dev_id, + port_id, enable); + } +#endif + rv = adpt_hppe_port_txfc_status_set(dev_id, port_id, enable); + rv |= adpt_hppe_port_rxfc_status_set(dev_id, port_id, enable); + + if(rv != SW_OK) + return rv; + + priv->port_old_tx_flowctrl[port_id - 1] = enable; + priv->port_old_rx_flowctrl[port_id - 1] = enable; + + return SW_OK; +} +sw_error_t +adpt_hppe_port_speed_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t * pspeed) +{ + sw_error_t rv = 0; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + struct port_phy_status phy_status = {0}; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(pspeed); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + /* for those ports without PHY device should be sfp port */ + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + { + if (port_id == SSDK_PHYSICAL_PORT0) + *pspeed = FAL_SPEED_10000; + else { + rv = _adpt_phy_status_get_from_ppe(dev_id, + port_id, &phy_status); + SW_RTN_ON_ERROR (rv); + *pspeed= phy_status.speed; + } + } + else + { + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_speed_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + rv = phy_drv->phy_speed_get (dev_id, phy_id, pspeed); + SW_RTN_ON_ERROR (rv); + } + + return rv; +} +#ifndef IN_PORTCONTROL_MINI +sw_error_t +adpt_hppe_port_mdix_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_mdix_mode_t mode) +{ + + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_mdix_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_mdix_set (dev_id, phy_id, mode); + + return rv; + +} +sw_error_t +adpt_hppe_port_wol_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_wol_status_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_wol_status_get (dev_id, phy_id, enable); + + return rv; + +} + +sw_error_t +adpt_hppe_port_source_filter_get(a_uint32_t dev_id, + fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv = SW_OK; + union port_in_forward_u port_in_forward = {0}; + + ADPT_DEV_ID_CHECK(dev_id); + + rv = hppe_port_in_forward_get(dev_id, port_id, &port_in_forward); + + if (rv != SW_OK) + return rv; + + if (port_in_forward.bf.source_filtering_bypass == A_TRUE) + *enable = A_FALSE; + else + *enable = A_TRUE; + + return SW_OK; +} + +sw_error_t +adpt_hppe_port_source_filter_set(a_uint32_t dev_id, + fal_port_t port_id, a_bool_t enable) +{ + union port_in_forward_u port_in_forward = {0}; + + ADPT_DEV_ID_CHECK(dev_id); + + if (enable == A_TRUE) + port_in_forward.bf.source_filtering_bypass = A_FALSE; + else + port_in_forward.bf.source_filtering_bypass = A_TRUE; + + return hppe_port_in_forward_set(dev_id, port_id, &port_in_forward); +} + +sw_error_t +adpt_ppe_port_source_filter_get(a_uint32_t dev_id, + fal_port_t port_id, a_bool_t * enable) +{ + ADPT_DEV_ID_CHECK(dev_id); +#ifdef CPPE + if (adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) { + return adpt_cppe_port_source_filter_get(dev_id, port_id, enable); + } +#endif + return adpt_hppe_port_source_filter_get(dev_id, port_id, enable); +} + +sw_error_t +adpt_ppe_port_source_filter_set(a_uint32_t dev_id, + fal_port_t port_id, a_bool_t enable) + +{ + ADPT_DEV_ID_CHECK(dev_id); +#ifdef CPPE + if (adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) { + return adpt_cppe_port_source_filter_set(dev_id, port_id, enable); + } +#endif + return adpt_hppe_port_source_filter_set(dev_id, port_id, enable); +} + +sw_error_t +adpt_ppe_port_source_filter_config_get(a_uint32_t dev_id, + fal_port_t port_id, fal_src_filter_config_t* src_filter_config) +{ + ADPT_DEV_ID_CHECK(dev_id); +#ifdef CPPE + if (adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) { + return adpt_cppe_port_source_filter_config_get(dev_id, port_id, + src_filter_config); + } +#endif + return SW_NOT_SUPPORTED; +} + +sw_error_t +adpt_ppe_port_source_filter_config_set(a_uint32_t dev_id, + fal_port_t port_id, fal_src_filter_config_t *src_filter_config) + +{ + ADPT_DEV_ID_CHECK(dev_id); +#ifdef CPPE + if (adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) { + return adpt_cppe_port_source_filter_config_set(dev_id, port_id, src_filter_config); + } +#endif + return SW_NOT_SUPPORTED; +} + +static sw_error_t +adpt_hppe_port_interface_3az_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv = 0; + union lpi_enable_u lpi_enable = {0}; + union lpi_port_timer_u lpi_port_timer = {0}; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL(phy_drv = hsl_phy_api_ops_get(dev_id, port_id)); + if (NULL == phy_drv->phy_8023az_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_8023az_set(dev_id, phy_id, enable); + SW_RTN_ON_ERROR (rv); + + hppe_lpi_enable_get(dev_id, port_id, &lpi_enable); + + lpi_enable.val &= ~(0x1 << (port_id - 1)); + lpi_enable.val |= (((a_uint32_t)enable) << (port_id - 1)); + hppe_lpi_enable_set(dev_id, port_id, &lpi_enable); + + lpi_port_timer.bf.lpi_port_wakeup_timer = LPI_WAKEUP_TIMER; + lpi_port_timer.bf.lpi_port_sleep_timer = LPI_SLEEP_TIMER; + hppe_lpi_timer_set(dev_id, port_id, &lpi_port_timer); + + return SW_OK; +} +static sw_error_t +adpt_hppe_port_interface_3az_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable) +{ + sw_error_t rv = 0; + union lpi_enable_u lpi_enable = {0}; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + a_bool_t phy_status = 0, mac_status = 0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) + return SW_NOT_SUPPORTED; + + SW_RTN_ON_NULL (phy_drv =hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_8023az_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_8023az_get(dev_id, phy_id, &phy_status); + SW_RTN_ON_ERROR (rv); + + rv = hppe_lpi_enable_get(dev_id, port_id, &lpi_enable); + + if(((lpi_enable.val >> (port_id - 1)) & 0x1) == A_TRUE) + mac_status = A_TRUE; + else + mac_status = A_FALSE; + + *enable = (phy_status & mac_status); + + return SW_OK; +} + +sw_error_t +adpt_hppe_port_promisc_mode_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable) +{ + sw_error_t rv = SW_OK; + union port_bridge_ctrl_u port_bridge_ctrl = {0}; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + + rv = hppe_port_bridge_ctrl_get(dev_id, port_id, &port_bridge_ctrl); + + if( rv != SW_OK ) + return rv; + + *enable = port_bridge_ctrl.bf.promisc_en; + + return SW_OK; +} +#endif + +sw_error_t +adpt_hppe_port_promisc_mode_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv = SW_OK; + union port_bridge_ctrl_u port_bridge_ctrl = {0}; + + ADPT_DEV_ID_CHECK(dev_id); + + rv = hppe_port_bridge_ctrl_get(dev_id, port_id, &port_bridge_ctrl); + + if( rv != SW_OK ) + return rv; + + port_bridge_ctrl.bf.promisc_en = enable; + + return hppe_port_bridge_ctrl_set(dev_id, port_id, &port_bridge_ctrl); +} + +static sw_error_t +adpt_hppe_port_bridge_txmac_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv = SW_OK; + union port_bridge_ctrl_u port_bridge_ctrl = {0}; + + ADPT_DEV_ID_CHECK(dev_id); + + rv = hppe_port_bridge_ctrl_get(dev_id, port_id, &port_bridge_ctrl); + + if( rv != SW_OK ) + return rv; + + if(enable == A_TRUE) + port_bridge_ctrl.bf.txmac_en= 1; + else + port_bridge_ctrl.bf.txmac_en= 0; + + return hppe_port_bridge_ctrl_set(dev_id, port_id, &port_bridge_ctrl); +} + +sw_error_t +adpt_hppe_port_mux_set(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t port_type) +{ + sw_error_t rv = SW_OK; + union port_mux_ctrl_u port_mux_ctrl; + a_uint32_t mode, mode1; + + memset(&port_mux_ctrl, 0, sizeof(port_mux_ctrl)); + ADPT_DEV_ID_CHECK(dev_id); + + rv = hppe_port_mux_ctrl_get(dev_id, &port_mux_ctrl); + port_mux_ctrl.bf.port4_pcs_sel = 1; + + if (port_id == HPPE_MUX_PORT1) + { + if (port_type == PORT_GMAC_TYPE) + { + mode = ssdk_dt_global_get_mac_mode(dev_id, SSDK_UNIPHY_INSTANCE0); + mode1 = ssdk_dt_global_get_mac_mode(dev_id, SSDK_UNIPHY_INSTANCE1); + if ((((mode == PORT_WRAPPER_PSGMII) || + (mode == PORT_WRAPPER_PSGMII_FIBER)) && + (mode1 == PORT_WRAPPER_MAX)) || + ((mode == PORT_WRAPPER_SGMII4_RGMII4) && (mode1 == PORT_WRAPPER_MAX))) + { + port_mux_ctrl.bf.port5_pcs_sel = 1; + port_mux_ctrl.bf.port5_gmac_sel = 1; + } + else if (mode1 == PORT_WRAPPER_SGMII0_RGMII4 || + mode1 == PORT_WRAPPER_SGMII_CHANNEL0 || + mode1 == PORT_WRAPPER_SGMII_FIBER) + { + port_mux_ctrl.bf.port5_pcs_sel = 2; + port_mux_ctrl.bf.port5_gmac_sel = 1; + } + } + else if (port_type == PORT_XGMAC_TYPE) + { + port_mux_ctrl.bf.port5_pcs_sel = 2; + port_mux_ctrl.bf.port5_gmac_sel = 0; + } + } + else if (port_id == HPPE_MUX_PORT2) + { + if (port_type == PORT_GMAC_TYPE) + { + port_mux_ctrl.bf.port6_pcs_sel = 1; + port_mux_ctrl.bf.port6_gmac_sel = 1; + } + else if (port_type == PORT_XGMAC_TYPE) + { + port_mux_ctrl.bf.port6_pcs_sel = 1; + port_mux_ctrl.bf.port6_gmac_sel = 0; + } + } + else + { + return SW_OK; + } + rv = hppe_port_mux_ctrl_set(dev_id, &port_mux_ctrl); + + return rv; +} + +static sw_error_t +adpt_hppe_port_flowctrl_forcemode_set(a_uint32_t dev_id, + fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv = SW_OK; + struct qca_phy_priv *priv = ssdk_phy_priv_data_get(dev_id); + + ADPT_DEV_ID_CHECK(dev_id); + + if (!priv) + return SW_FAIL; + + if ((port_id < SSDK_PHYSICAL_PORT1) || (port_id > SSDK_PHYSICAL_PORT6)) + return SW_BAD_VALUE; + + priv->port_tx_flowctrl_forcemode[port_id - 1] = enable; + priv->port_rx_flowctrl_forcemode[port_id - 1] = enable; + + return rv; +} +#ifndef IN_PORTCONTROL_MINI +static sw_error_t +adpt_hppe_port_flowctrl_forcemode_get(a_uint32_t dev_id, + fal_port_t port_id, a_bool_t *enable) +{ + sw_error_t rv = SW_OK; + struct qca_phy_priv *priv = ssdk_phy_priv_data_get(dev_id); + + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + + if ((port_id < SSDK_PHYSICAL_PORT1) || (port_id > SSDK_PHYSICAL_PORT6)) + return SW_BAD_VALUE; + + if (!priv) + return SW_FAIL; + + *enable = (priv->port_tx_flowctrl_forcemode[port_id - 1] & + priv->port_rx_flowctrl_forcemode[port_id - 1]); + + return rv; +} +#endif +static a_uint32_t port_lpi_sleep_timer[SW_MAX_NR_DEV][SSDK_PHYSICAL_PORT6] = { + {218, 218, 218, 218, 218, 218}, + {218, 218, 218, 218, 218, 218}, + {218, 218, 218, 218, 218, 218}, +}; /* unit is us*/ +static a_uint32_t port_lpi_wakeup_timer[SW_MAX_NR_DEV][SSDK_PHYSICAL_PORT6] = { + {27, 27, 27, 27, 27, 27}, + {27, 27, 27, 27, 27, 27}, + {27, 27, 27, 27, 27, 27}, +}; /* unit is us*/ +static sw_error_t +adpt_hppe_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 = 0; + union lpi_enable_u lpi_enable = {0}; + union lpi_port_timer_u lpi_port_timer = {0}; + a_uint32_t phy_id = 0; + a_uint32_t adv, enable; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + + if ((port_id < SSDK_PHYSICAL_PORT1) || (port_id > SSDK_PHYSICAL_PORT6)) { + return SW_BAD_PARAM; + } + if (port_eee_cfg->enable) { + adv = port_eee_cfg->advertisement; + } else { + adv = 0; + } + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) { + return SW_NOT_SUPPORTED; + } + + SW_RTN_ON_NULL(phy_drv = hsl_phy_api_ops_get(dev_id, port_id)); + if (NULL == phy_drv->phy_eee_adv_set) { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_eee_adv_set(dev_id, phy_id, adv); + SW_RTN_ON_ERROR (rv); + + hppe_lpi_enable_get(dev_id, port_id, &lpi_enable); + + enable = port_eee_cfg->lpi_tx_enable; + lpi_enable.val &= ~(0x1 << (port_id - 1)); + lpi_enable.val |= (enable << (port_id - 1)); + hppe_lpi_enable_set(dev_id, port_id, &lpi_enable); + + lpi_port_timer.bf.lpi_port_wakeup_timer = + (port_eee_cfg->lpi_wakeup_timer * LPI_EEE_TIMER_FREQUENCY) /LPI_EEE_TIMER_UNIT; + lpi_port_timer.bf.lpi_port_sleep_timer = + (port_eee_cfg->lpi_sleep_timer * LPI_EEE_TIMER_FREQUENCY) /LPI_EEE_TIMER_UNIT; + rv = hppe_lpi_timer_set(dev_id, port_id, &lpi_port_timer); + SW_RTN_ON_ERROR (rv); + port_lpi_wakeup_timer[dev_id][port_id - 1] = port_eee_cfg->lpi_wakeup_timer; + port_lpi_sleep_timer[dev_id][port_id - 1] = port_eee_cfg->lpi_sleep_timer; + + return rv; +} +static sw_error_t +adpt_hppe_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 = 0; + union lpi_enable_u lpi_enable = {0}; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + a_uint32_t adv, lp_adv, cap, status; + + if ((port_id < SSDK_PHYSICAL_PORT1) || (port_id > SSDK_PHYSICAL_PORT6)) { + return SW_BAD_PARAM; + } + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(port_eee_cfg); + memset(port_eee_cfg, 0, sizeof(*port_eee_cfg)); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) { + return SW_BAD_PARAM; + } + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) { + return SW_NOT_SUPPORTED; + } + + SW_RTN_ON_NULL (phy_drv =hsl_phy_api_ops_get (dev_id, port_id)); + if ((NULL == phy_drv->phy_eee_adv_get) || (NULL == phy_drv->phy_eee_partner_adv_get) || + (NULL == phy_drv->phy_eee_cap_get) || (NULL == phy_drv->phy_eee_status_get)) { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_eee_adv_get(dev_id, phy_id, &adv); + SW_RTN_ON_ERROR (rv); + port_eee_cfg->advertisement = adv; + rv = phy_drv->phy_eee_partner_adv_get(dev_id, phy_id, &lp_adv); + SW_RTN_ON_ERROR (rv); + port_eee_cfg->link_partner_advertisement = lp_adv; + rv = phy_drv->phy_eee_cap_get(dev_id, phy_id, &cap); + SW_RTN_ON_ERROR (rv); + port_eee_cfg->capability = cap; + rv = phy_drv->phy_eee_status_get(dev_id, phy_id, &status); + SW_RTN_ON_ERROR (rv); + port_eee_cfg->eee_status = status; + + if (port_eee_cfg->advertisement) { + port_eee_cfg->enable = A_TRUE; + } else { + port_eee_cfg->enable = A_FALSE; + } + rv = hppe_lpi_enable_get(dev_id, port_id, &lpi_enable); + SW_RTN_ON_ERROR (rv); + + if(((lpi_enable.val >> (port_id - 1)) & 0x1) == A_TRUE) { + port_eee_cfg->lpi_tx_enable = A_TRUE; + } else { + port_eee_cfg->lpi_tx_enable = A_FALSE; + } + port_eee_cfg->lpi_wakeup_timer = port_lpi_wakeup_timer[dev_id][port_id - 1]; + port_eee_cfg->lpi_sleep_timer = port_lpi_sleep_timer[dev_id][port_id - 1]; + + return rv; +} + +static sw_error_t +adpt_hppe_port_phy_status_get(a_uint32_t dev_id, a_uint32_t port_id, + struct port_phy_status *phy_status) +{ + sw_error_t rv = 0; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(phy_status); + + /* for those ports without PHY device should be sfp port or a internal port*/ + if (A_FALSE == _adpt_hppe_port_phy_connected (dev_id, port_id)) { + if (port_id != SSDK_PHYSICAL_PORT0) { + rv = _adpt_phy_status_get_from_ppe(dev_id, + port_id, phy_status); + SW_RTN_ON_ERROR (rv); + } else { + return SW_NOT_SUPPORTED; + } + } else { + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_get_status) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + rv = phy_drv->phy_get_status (dev_id, phy_id, phy_status); + SW_RTN_ON_ERROR (rv); + } + + return rv; + +} +static void +adpt_hppe_uniphy_psgmii_port_reset(a_uint32_t dev_id, a_uint32_t uniphy_index, + a_uint32_t port_id) +{ + union uniphy_channel0_input_output_4_u uniphy_channel0_input_output_4; + union uniphy_channel1_input_output_4_u uniphy_channel1_input_output_4; + union uniphy_channel2_input_output_4_u uniphy_channel2_input_output_4; + union uniphy_channel3_input_output_4_u uniphy_channel3_input_output_4; + union uniphy_channel4_input_output_4_u uniphy_channel4_input_output_4; + + memset(&uniphy_channel0_input_output_4, 0, sizeof(uniphy_channel0_input_output_4)); + memset(&uniphy_channel1_input_output_4, 0, sizeof(uniphy_channel1_input_output_4)); + memset(&uniphy_channel2_input_output_4, 0, sizeof(uniphy_channel2_input_output_4)); + memset(&uniphy_channel3_input_output_4, 0, sizeof(uniphy_channel3_input_output_4)); + memset(&uniphy_channel4_input_output_4, 0, sizeof(uniphy_channel4_input_output_4)); + + if (port_id == SSDK_PHYSICAL_PORT1) + { + hppe_uniphy_channel0_input_output_4_get(dev_id, uniphy_index, + &uniphy_channel0_input_output_4); + uniphy_channel0_input_output_4.bf.newaddedfromhere_ch0_adp_sw_rstn = 0; + hppe_uniphy_channel0_input_output_4_set(dev_id, uniphy_index, + &uniphy_channel0_input_output_4); + uniphy_channel0_input_output_4.bf.newaddedfromhere_ch0_adp_sw_rstn = 1; + hppe_uniphy_channel0_input_output_4_set(dev_id, uniphy_index, + &uniphy_channel0_input_output_4); + } + else if (port_id == SSDK_PHYSICAL_PORT2) + { + hppe_uniphy_channel1_input_output_4_get(dev_id, uniphy_index, + &uniphy_channel1_input_output_4); + uniphy_channel1_input_output_4.bf.newaddedfromhere_ch1_adp_sw_rstn = 0; + hppe_uniphy_channel1_input_output_4_set(dev_id, uniphy_index, + &uniphy_channel1_input_output_4); + uniphy_channel1_input_output_4.bf.newaddedfromhere_ch1_adp_sw_rstn = 1; + hppe_uniphy_channel1_input_output_4_set(dev_id, uniphy_index, + &uniphy_channel1_input_output_4); + } + else if (port_id == SSDK_PHYSICAL_PORT3) + { + hppe_uniphy_channel2_input_output_4_get(dev_id, uniphy_index, + &uniphy_channel2_input_output_4); + uniphy_channel2_input_output_4.bf.newaddedfromhere_ch2_adp_sw_rstn = 0; + hppe_uniphy_channel2_input_output_4_set(dev_id, uniphy_index, + &uniphy_channel2_input_output_4); + uniphy_channel2_input_output_4.bf.newaddedfromhere_ch2_adp_sw_rstn = 1; + hppe_uniphy_channel2_input_output_4_set(dev_id, uniphy_index, + &uniphy_channel2_input_output_4); + } + else if (port_id == SSDK_PHYSICAL_PORT4) + { + hppe_uniphy_channel3_input_output_4_get(dev_id, uniphy_index, + &uniphy_channel3_input_output_4); + uniphy_channel3_input_output_4.bf.newaddedfromhere_ch3_adp_sw_rstn = 0; + hppe_uniphy_channel3_input_output_4_set(dev_id, uniphy_index, + &uniphy_channel3_input_output_4); + uniphy_channel3_input_output_4.bf.newaddedfromhere_ch3_adp_sw_rstn = 1; + hppe_uniphy_channel3_input_output_4_set(dev_id, uniphy_index, + &uniphy_channel3_input_output_4); + } + else if (port_id == SSDK_PHYSICAL_PORT5) + { + hppe_uniphy_channel4_input_output_4_get(dev_id, uniphy_index, + &uniphy_channel4_input_output_4); + uniphy_channel4_input_output_4.bf.newaddedfromhere_ch4_adp_sw_rstn = 0; + hppe_uniphy_channel4_input_output_4_set(dev_id, uniphy_index, + &uniphy_channel4_input_output_4); + uniphy_channel4_input_output_4.bf.newaddedfromhere_ch4_adp_sw_rstn = 1; + hppe_uniphy_channel4_input_output_4_set(dev_id, uniphy_index, + &uniphy_channel4_input_output_4); + } + + return; +} +static void +adpt_hppe_uniphy_usxgmii_port_reset(a_uint32_t dev_id, a_uint32_t uniphy_index, + a_uint32_t port_id) +{ + union vr_xs_pcs_dig_ctrl1_u vr_xs_pcs_dig_ctrl1; + + memset(&vr_xs_pcs_dig_ctrl1, 0, sizeof(vr_xs_pcs_dig_ctrl1)); + + hppe_vr_xs_pcs_dig_ctrl1_get(dev_id, uniphy_index, &vr_xs_pcs_dig_ctrl1); + vr_xs_pcs_dig_ctrl1.bf.usra_rst = 1; + hppe_vr_xs_pcs_dig_ctrl1_set(dev_id, uniphy_index, &vr_xs_pcs_dig_ctrl1); + + return; +} + +static void +adpt_hppe_uniphy_port_adapter_reset(a_uint32_t dev_id, a_uint32_t port_id) +{ + a_uint32_t uniphy_index, mode, mode1; +#if defined(CPPE) + a_uint32_t channel_id = 0; +#endif + + if (port_id < HPPE_MUX_PORT1) + { + uniphy_index = SSDK_UNIPHY_INSTANCE0; +#if defined(CPPE) + adpt_cppe_port_to_channel_convert(dev_id, port_id, + &channel_id); + port_id = channel_id; +#endif + adpt_hppe_uniphy_psgmii_port_reset(dev_id, uniphy_index, + port_id); + } + else + { + if (port_id == HPPE_MUX_PORT1) + { + mode = ssdk_dt_global_get_mac_mode(dev_id, SSDK_UNIPHY_INSTANCE0); + mode1 = ssdk_dt_global_get_mac_mode(dev_id, SSDK_UNIPHY_INSTANCE1); + if ((((mode == PORT_WRAPPER_PSGMII) || + (mode == PORT_WRAPPER_PSGMII_FIBER)) && + (mode1 == PORT_WRAPPER_MAX)) || + ((mode == PORT_WRAPPER_SGMII4_RGMII4) && (mode1 == PORT_WRAPPER_MAX))) + { + uniphy_index = SSDK_UNIPHY_INSTANCE0; + adpt_hppe_uniphy_psgmii_port_reset(dev_id, uniphy_index, + port_id); + return; + } + else + uniphy_index = SSDK_UNIPHY_INSTANCE1; + } + else + uniphy_index = SSDK_UNIPHY_INSTANCE2; + + mode = ssdk_dt_global_get_mac_mode(dev_id, uniphy_index); + + if ((mode == PORT_WRAPPER_SGMII_PLUS) || (mode == PORT_WRAPPER_SGMII0_RGMII4) + || (mode == PORT_WRAPPER_SGMII_CHANNEL0) + || (mode == PORT_WRAPPER_SGMII_FIBER)) + { + /* only reset channel 0 */ + adpt_hppe_uniphy_psgmii_port_reset(dev_id, uniphy_index, 1); + } + else if (mode == PORT_WRAPPER_USXGMII) + { + adpt_hppe_uniphy_usxgmii_port_reset(dev_id, uniphy_index, + port_id); + } + } + + return; +} +static void +adpt_hppe_uniphy_usxgmii_speed_set(a_uint32_t dev_id, a_uint32_t uniphy_index, + fal_port_speed_t speed) +{ + union sr_mii_ctrl_u sr_mii_ctrl; + memset(&sr_mii_ctrl, 0, sizeof(sr_mii_ctrl)); + + hppe_sr_mii_ctrl_get(0, uniphy_index, &sr_mii_ctrl); + sr_mii_ctrl.bf.duplex_mode = 1; + if (speed == FAL_SPEED_10) + { + sr_mii_ctrl.bf.ss5 = 0; + sr_mii_ctrl.bf.ss6 = 0; + sr_mii_ctrl.bf.ss13 = 0; + } + else if (speed == FAL_SPEED_100) + { + sr_mii_ctrl.bf.ss5 = 0; + sr_mii_ctrl.bf.ss6 = 0; + sr_mii_ctrl.bf.ss13 = 1; + } + else if (speed == FAL_SPEED_1000) + { + sr_mii_ctrl.bf.ss5 = 0; + sr_mii_ctrl.bf.ss6 = 1; + sr_mii_ctrl.bf.ss13 = 0; + } + else if (speed == FAL_SPEED_10000) + { + sr_mii_ctrl.bf.ss5 = 0; + sr_mii_ctrl.bf.ss6 = 1; + sr_mii_ctrl.bf.ss13 = 1; + } + else if (speed == FAL_SPEED_2500) + { + sr_mii_ctrl.bf.ss5 = 1; + sr_mii_ctrl.bf.ss6 = 0; + sr_mii_ctrl.bf.ss13 = 0; + } + else if (speed == FAL_SPEED_5000) + { + sr_mii_ctrl.bf.ss5 = 1; + sr_mii_ctrl.bf.ss6 = 0; + sr_mii_ctrl.bf.ss13 = 1; + } + hppe_sr_mii_ctrl_set(0, uniphy_index, &sr_mii_ctrl); + + return; +} +static void +adpt_hppe_uniphy_usxgmii_duplex_set(a_uint32_t dev_id, a_uint32_t uniphy_index, + fal_port_duplex_t duplex) +{ + union sr_mii_ctrl_u sr_mii_ctrl; + memset(&sr_mii_ctrl, 0, sizeof(sr_mii_ctrl)); + + hppe_sr_mii_ctrl_get(dev_id, uniphy_index, &sr_mii_ctrl); + + if (duplex == FAL_FULL_DUPLEX) + sr_mii_ctrl.bf.duplex_mode = 1; + else + sr_mii_ctrl.bf.duplex_mode = 0; + + hppe_sr_mii_ctrl_set(dev_id, uniphy_index, &sr_mii_ctrl); + + return; +} +sw_error_t +adpt_hppe_uniphy_usxgmii_autoneg_completed(a_uint32_t dev_id, + a_uint32_t uniphy_index) +{ + a_uint32_t autoneg_complete = 0, retries = 100; + union vr_mii_an_intr_sts_u vr_mii_an_intr_sts; + + memset(&vr_mii_an_intr_sts, 0, sizeof(vr_mii_an_intr_sts)); + + // swith uniphy xpcs auto-neg complete and clear interrupt + while (autoneg_complete != 0x1) { + mdelay(1); + if (retries-- == 0) + { + printk("uniphy autoneg time out!\n"); + return SW_TIMEOUT; + } + hppe_vr_mii_an_intr_sts_get(dev_id, uniphy_index, &vr_mii_an_intr_sts); + autoneg_complete = vr_mii_an_intr_sts.bf.cl37_ancmplt_intr; + } + + vr_mii_an_intr_sts.bf.cl37_ancmplt_intr = 0; + hppe_vr_mii_an_intr_sts_set(dev_id, uniphy_index, &vr_mii_an_intr_sts); + + return SW_OK; +} +static void +adpt_hppe_uniphy_speed_set(a_uint32_t dev_id, a_uint32_t port_id, fal_port_speed_t speed) +{ + a_uint32_t uniphy_index = 0, mode = 0; + + if (port_id == HPPE_MUX_PORT1) + uniphy_index = SSDK_UNIPHY_INSTANCE1; + else if (port_id == HPPE_MUX_PORT2) + uniphy_index = SSDK_UNIPHY_INSTANCE2; + + mode = ssdk_dt_global_get_mac_mode(dev_id, uniphy_index); + if (mode == PORT_WRAPPER_USXGMII) + { + /* adpt_hppe_uniphy_usxgmii_autoneg_completed(dev_id,uniphy_index); */ + /* configure xpcs speed at usxgmii mode */ + adpt_hppe_uniphy_usxgmii_speed_set(dev_id, uniphy_index, speed); + } + + return; +} +static void +adpt_hppe_uniphy_duplex_set(a_uint32_t dev_id, a_uint32_t port_id, fal_port_duplex_t duplex) +{ + a_uint32_t uniphy_index = 0, mode = 0; + + if (port_id == HPPE_MUX_PORT1) + uniphy_index = SSDK_UNIPHY_INSTANCE1; + else if (port_id == HPPE_MUX_PORT2) + uniphy_index = SSDK_UNIPHY_INSTANCE2; + + mode = ssdk_dt_global_get_mac_mode(dev_id, uniphy_index); + if (mode == PORT_WRAPPER_USXGMII) + { + /* adpt_hppe_uniphy_usxgmii_autoneg_completed(0,uniphy_index); */ + /* configure xpcs duplex at usxgmii mode */ + adpt_hppe_uniphy_usxgmii_duplex_set(dev_id, uniphy_index, duplex); + } + + return; +} +static void +adpt_hppe_uniphy_autoneg_status_check(a_uint32_t dev_id, a_uint32_t port_id) +{ + a_uint32_t uniphy_index = 0, mode = 0; + + if (port_id == HPPE_MUX_PORT1) + uniphy_index = SSDK_UNIPHY_INSTANCE1; + else if (port_id == HPPE_MUX_PORT2) + uniphy_index = SSDK_UNIPHY_INSTANCE2; + + mode = ssdk_dt_global_get_mac_mode(dev_id, uniphy_index); + if (mode == PORT_WRAPPER_USXGMII) + { + adpt_hppe_uniphy_usxgmii_autoneg_completed(dev_id,uniphy_index);; + } + return; +} + +static void +adpt_hppe_sgmii_speed_clock_set( + a_uint32_t dev_id, + a_uint32_t port_id, + fal_port_speed_t phy_speed) +{ + switch (phy_speed) { + case FAL_SPEED_10: + ssdk_port_speed_clock_set(dev_id, + port_id, SGMII_SPEED_10M_CLK); + break; + case FAL_SPEED_100: + ssdk_port_speed_clock_set(dev_id, + port_id, SGMII_SPEED_100M_CLK); + break; + case FAL_SPEED_1000: + ssdk_port_speed_clock_set(dev_id, + port_id, SGMII_SPEED_1000M_CLK); + break; + default: + break; + } +} +static void +adpt_hppe_pqsgmii_speed_clock_set( + a_uint32_t dev_id, + a_uint32_t port_id, + fal_port_speed_t phy_speed) +{ + switch (phy_speed) { + case FAL_SPEED_10: + ssdk_port_speed_clock_set(dev_id, + port_id, PQSGMII_SPEED_10M_CLK); + break; + case FAL_SPEED_100: + ssdk_port_speed_clock_set(dev_id, + port_id, PQSGMII_SPEED_100M_CLK); + break; + case FAL_SPEED_1000: + ssdk_port_speed_clock_set(dev_id, + port_id, PQSGMII_SPEED_1000M_CLK); + break; + default: + break; + } +} + +static void +adpt_hppe_usxgmii_speed_clock_set( + a_uint32_t dev_id, + a_uint32_t port_id, + fal_port_speed_t phy_speed) +{ + switch (phy_speed) { + case FAL_SPEED_10: + ssdk_port_speed_clock_set(dev_id, + port_id, USXGMII_SPEED_10M_CLK); + break; + case FAL_SPEED_100: + ssdk_port_speed_clock_set(dev_id, + port_id, USXGMII_SPEED_100M_CLK); + break; + case FAL_SPEED_1000: + ssdk_port_speed_clock_set(dev_id, + port_id, USXGMII_SPEED_1000M_CLK); + break; + case FAL_SPEED_2500: + ssdk_port_speed_clock_set(dev_id, + port_id, USXGMII_SPEED_2500M_CLK); + break; + case FAL_SPEED_5000: + ssdk_port_speed_clock_set(dev_id, + port_id, USXGMII_SPEED_5000M_CLK); + break; + case FAL_SPEED_10000: + ssdk_port_speed_clock_set(dev_id, + port_id, USXGMII_SPEED_10000M_CLK); + break; + default: + break; + } + +} + +static void +adpt_hppe_sgmiiplus_speed_clock_set( + a_uint32_t dev_id, + a_uint32_t port_id, + fal_port_speed_t phy_speed) +{ + ssdk_port_speed_clock_set(dev_id, port_id, SGMII_PLUS_SPEED_2500M_CLK); +} + + +void +adpt_hppe_gcc_port_speed_clock_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_port_speed_t phy_speed) +{ + a_uint32_t mode = 0, uniphy_index = 0, mode1 = 0; + + if (port_id < HPPE_MUX_PORT1) + { +#if defined(CPPE) + if (port_id == SSDK_PHYSICAL_PORT4) { + mode = ssdk_dt_global_get_mac_mode(dev_id, SSDK_UNIPHY_INSTANCE0); + if (mode == PORT_WRAPPER_SGMII_PLUS) { + adpt_hppe_sgmiiplus_speed_clock_set(dev_id, port_id, phy_speed); + return; + } + } +#endif + adpt_hppe_pqsgmii_speed_clock_set(dev_id, port_id, phy_speed); + } + else + { + if (port_id == HPPE_MUX_PORT1) + { + uniphy_index = SSDK_UNIPHY_INSTANCE0; + mode = ssdk_dt_global_get_mac_mode(dev_id, uniphy_index); + mode1 = ssdk_dt_global_get_mac_mode(dev_id, SSDK_UNIPHY_INSTANCE1); + if ((((mode == PORT_WRAPPER_PSGMII) || + (mode == PORT_WRAPPER_PSGMII_FIBER)) && + (mode1 == PORT_WRAPPER_MAX)) || + ((mode == PORT_WRAPPER_SGMII4_RGMII4) && (mode1 == PORT_WRAPPER_MAX))) + { + adpt_hppe_pqsgmii_speed_clock_set(dev_id, port_id, phy_speed); + return; + } + } + if (port_id == HPPE_MUX_PORT1) + uniphy_index = SSDK_UNIPHY_INSTANCE1; + else + uniphy_index = SSDK_UNIPHY_INSTANCE2; + + mode = ssdk_dt_global_get_mac_mode(dev_id, uniphy_index); + if (mode == PORT_WRAPPER_SGMII0_RGMII4 || mode == PORT_WRAPPER_SGMII_CHANNEL0 + || mode == PORT_WRAPPER_SGMII_FIBER) + adpt_hppe_sgmii_speed_clock_set(dev_id, port_id, phy_speed); + else if (mode == PORT_WRAPPER_SGMII_PLUS) + adpt_hppe_sgmiiplus_speed_clock_set(dev_id, port_id, phy_speed); + else if ((mode == PORT_WRAPPER_USXGMII) || (mode == PORT_WRAPPER_10GBASE_R)) + adpt_hppe_usxgmii_speed_clock_set(dev_id,port_id, phy_speed); + } + return; +} + +void +adpt_hppe_gcc_uniphy_clock_status_set(a_uint32_t dev_id, a_uint32_t port_id, + a_bool_t enable) +{ + a_uint32_t mode = 0, uniphy_index = 0, mode1 = 0; +#if defined(CPPE) + a_uint32_t channel_id = 0; +#endif + + if (port_id < HPPE_MUX_PORT1) + { + uniphy_index = SSDK_UNIPHY_INSTANCE0; +#if defined(CPPE) + adpt_cppe_port_to_channel_convert(dev_id, port_id, + &channel_id); + port_id = channel_id; +#endif + qca_gcc_uniphy_port_clock_set(dev_id, uniphy_index, + port_id, enable); + } + else + { + if (port_id == HPPE_MUX_PORT1) + { + uniphy_index = SSDK_UNIPHY_INSTANCE0; + mode = ssdk_dt_global_get_mac_mode(dev_id, uniphy_index); + mode1 = ssdk_dt_global_get_mac_mode(dev_id, SSDK_UNIPHY_INSTANCE1); + if ((((mode == PORT_WRAPPER_PSGMII) || + (mode == PORT_WRAPPER_PSGMII_FIBER)) && + (mode1 == PORT_WRAPPER_MAX)) || + ((mode == PORT_WRAPPER_SGMII4_RGMII4) && (mode1 == PORT_WRAPPER_MAX))) + { + qca_gcc_uniphy_port_clock_set(dev_id, uniphy_index, + port_id, enable); + return; + } + } + if (port_id == HPPE_MUX_PORT1) + uniphy_index = SSDK_UNIPHY_INSTANCE1; + else + uniphy_index = SSDK_UNIPHY_INSTANCE2; + + qca_gcc_uniphy_port_clock_set(dev_id, uniphy_index, + 1, enable); + } + return; +} + +static sw_error_t +adpt_hppe_sfp_interface_mode_switch(a_uint32_t dev_id, + a_uint32_t port_id) +{ + sw_error_t rv = SW_OK; + fal_port_interface_mode_t port_mode_old = PORT_INTERFACE_MODE_MAX, + port_mode_new= PORT_INTERFACE_MODE_MAX; + + if (A_FALSE == _adpt_hppe_port_phy_connected(dev_id, port_id)) + { + rv = adpt_hppe_port_interface_mode_get(dev_id, port_id, &port_mode_old); + SW_RTN_ON_ERROR(rv); + rv = adpt_hppe_port_interface_mode_status_get(dev_id, port_id, + &port_mode_new); + SW_RTN_ON_ERROR (rv); + if(port_mode_old != port_mode_new) + { + SSDK_DEBUG("Port %d change interface mode to %d from %d\n", port_id, + port_mode_new, port_mode_old); + rv = _adpt_hppe_port_interface_mode_set(dev_id, port_id, port_mode_new); + SW_RTN_ON_ERROR(rv); + rv = _adpt_hppe_port_interface_mode_apply(dev_id, A_FALSE); + SW_RTN_ON_ERROR(rv); + } + } + + return rv; +} + +static sw_error_t +adpt_hppe_port_interface_mode_switch(a_uint32_t dev_id, a_uint32_t port_id) +{ + sw_error_t rv = SW_OK; + fal_port_interface_mode_t port_mode_old = PORT_INTERFACE_MODE_MAX; + fal_port_interface_mode_t port_mode_new = PORT_INTERFACE_MODE_MAX; + + rv = adpt_hppe_port_interface_mode_status_get(dev_id, + port_id, &port_mode_new); + SW_RTN_ON_ERROR(rv); + + rv = adpt_hppe_port_interface_mode_get(dev_id, port_id, &port_mode_old); + SW_RTN_ON_ERROR(rv); + + if (port_mode_new != port_mode_old) { + rv = _adpt_hppe_port_interface_mode_set(dev_id, + port_id, port_mode_new); + SW_RTN_ON_ERROR(rv); + rv = _adpt_hppe_port_interface_mode_apply(dev_id, A_FALSE); + } + return rv; +} + +void +adpt_hppe_gcc_mac_clock_status_set(a_uint32_t dev_id, a_uint32_t port_id, + a_bool_t enable) +{ + + qca_gcc_mac_port_clock_set(dev_id, port_id, enable); + + return; +} +a_bool_t +adpt_hppe_port_phy_status_change(struct qca_phy_priv *priv, a_uint32_t port_id, + struct port_phy_status phy_status) +{ + if ((a_uint32_t)phy_status.speed != priv->port_old_speed[port_id - 1]) + return A_TRUE; + if ((a_uint32_t)phy_status.duplex != priv->port_old_duplex[port_id - 1]) + return A_TRUE; + if (phy_status.tx_flowctrl != priv->port_old_tx_flowctrl[port_id - 1]) + return A_TRUE; + if (phy_status.rx_flowctrl != priv->port_old_rx_flowctrl[port_id - 1]) + return A_TRUE; + return A_FALSE; +} +sw_error_t +qca_hppe_mac_sw_sync_task(struct qca_phy_priv *priv) +{ + a_uint32_t port_id; + struct port_phy_status phy_status = {0}; + a_bool_t status; + a_uint32_t portbmp[SW_MAX_NR_DEV] = {0}; + sw_error_t rv = SW_OK; + + portbmp[priv->device_id] = qca_ssdk_port_bmp_get(priv->device_id); + + for (port_id = 1; port_id < SW_MAX_NR_PORT; port_id ++) { + + if(!(portbmp[priv->device_id] & (0x1 << port_id))) + continue; + + rv = adpt_hppe_port_phy_status_get(priv->device_id, + port_id, &phy_status); + if (rv != SW_OK) { + SSDK_DEBUG("failed to get port %d status return value is %d\n", + port_id, rv); + continue; + } + rv = adpt_hppe_sfp_interface_mode_switch(priv->device_id, port_id); + if(rv) { + SSDK_DEBUG("port %d sfp interface mode change failed\n", port_id); + } + SSDK_DEBUG("polling task external phy %d link status is %d and speed is %d\n", + port_id, phy_status.link_status, phy_status.speed); + /* link status from up to down */ + if ((phy_status.link_status == PORT_LINK_DOWN) && + (priv->port_old_link[port_id - 1] == PORT_LINK_UP)) + { + SSDK_DEBUG("Port %d change to link down status\n", port_id); + /* disable ppe port bridge txmac */ + adpt_hppe_port_bridge_txmac_set(priv->device_id, port_id, A_FALSE); + /* disable rx mac */ + adpt_hppe_port_rxmac_status_set(priv->device_id, port_id, A_FALSE); + priv->port_old_link[port_id - 1] = phy_status.link_status; + /* switch interface mode if necessary */ + if (adpt_hppe_port_interface_mode_switch(priv->device_id, + port_id) == SW_OK) { + SSDK_DEBUG("Port %d the interface mode switched\n", + port_id); + } +#ifdef IN_FDB + adpt_hppe_fdb_del_by_port(priv->device_id, port_id, !(FAL_FDB_DEL_STATIC)); +#endif + continue; + } + /* link status from down to up*/ + if ((phy_status.link_status == PORT_LINK_UP) && + (priv->port_old_link[port_id - 1] == PORT_LINK_DOWN)) + { + SSDK_DEBUG("Port %d change to link up status\n", port_id); + status = adpt_hppe_port_phy_status_change(priv, port_id, phy_status); + /*disable tx mac*/ + adpt_hppe_port_txmac_status_set(priv->device_id, port_id, A_FALSE); + /* switch interface mode if necessary */ + if (adpt_hppe_port_interface_mode_switch(priv->device_id, + port_id) == SW_OK) { + SSDK_DEBUG("Port %d the interface mode switched\n", + port_id); + } + /* first check uniphy auto-neg complete interrupt to usxgmii */ + adpt_hppe_uniphy_autoneg_status_check(priv->device_id, port_id); + if (status == A_TRUE) + { + adpt_hppe_gcc_uniphy_clock_status_set(priv->device_id, + port_id, A_FALSE); + if ((a_uint32_t)phy_status.speed != + priv->port_old_speed[port_id - 1]) + { + /* configure gcc speed clock according to current speed */ + adpt_hppe_gcc_port_speed_clock_set(priv->device_id, port_id, + phy_status.speed); + + /* config uniphy speed to usxgmii mode */ + adpt_hppe_uniphy_speed_set(priv->device_id, port_id, + phy_status.speed); + + /* reset port mac when speed change under usxgmii mode */ + adpt_hppe_port_speed_change_mac_reset(priv->device_id, port_id); + + /* config mac speed */ + adpt_hppe_port_mac_speed_set(priv->device_id, port_id, + phy_status.speed); + priv->port_old_speed[port_id - 1] = + (a_uint32_t)phy_status.speed; + + SSDK_DEBUG("Port %d is link up and speed change to %d\n", + port_id, priv->port_old_speed[port_id - 1]); + } + if ((a_uint32_t)phy_status.duplex != + priv->port_old_duplex[port_id - 1]) + { + adpt_hppe_uniphy_duplex_set(priv->device_id, port_id, + phy_status.duplex); + adpt_hppe_port_mac_duplex_set(priv->device_id, port_id, + phy_status.duplex); + priv->port_old_duplex[port_id - 1] = + (a_uint32_t)phy_status.duplex; + + SSDK_DEBUG("Port %d is link up and duplex change to %d\n", + port_id, + priv->port_old_duplex[port_id - 1]); + } + if (priv->port_tx_flowctrl_forcemode[port_id - 1] != A_TRUE) + { + if (phy_status.duplex == FAL_HALF_DUPLEX) + { + phy_status.tx_flowctrl = A_TRUE; + } + if (phy_status.tx_flowctrl != + priv->port_old_tx_flowctrl[port_id - 1]) + { + adpt_hppe_port_txfc_status_set(priv->device_id, + port_id, phy_status.tx_flowctrl); + priv->port_old_tx_flowctrl[port_id - 1] = + phy_status.tx_flowctrl; + + SSDK_DEBUG("Port %d is link up and tx flowctrl" + " change to %d\n", port_id, + priv->port_old_tx_flowctrl[port_id - 1]); + } + } + if (priv->port_rx_flowctrl_forcemode[port_id - 1] != A_TRUE) + { + if (phy_status.duplex == FAL_HALF_DUPLEX) + { + phy_status.rx_flowctrl = A_TRUE; + } + if (phy_status.rx_flowctrl != + priv->port_old_rx_flowctrl[port_id - 1]) + { + adpt_hppe_port_rxfc_status_set(priv->device_id, + port_id, phy_status.rx_flowctrl); + priv->port_old_rx_flowctrl[port_id - 1] = + phy_status.rx_flowctrl; + + SSDK_DEBUG("Port %d is link up and rx flowctrl" + " change to %d\n", port_id, + priv->port_old_rx_flowctrl[port_id-1]); + } + } + adpt_hppe_gcc_uniphy_clock_status_set(priv->device_id, + port_id, A_TRUE); + adpt_hppe_uniphy_port_adapter_reset(priv->device_id, port_id); + } + /* enable mac and ppe txmac*/ + adpt_hppe_port_txmac_status_set(priv->device_id, port_id, A_TRUE); + adpt_hppe_port_rxmac_status_set(priv->device_id, port_id, A_TRUE); + adpt_hppe_port_bridge_txmac_set(priv->device_id, port_id, A_TRUE); + priv->port_old_link[port_id - 1] = phy_status.link_status; + } + SSDK_DEBUG("polling task PPE port %d link status is %d and speed is %d\n", + port_id, priv->port_old_link[port_id - 1], + priv->port_old_speed[port_id - 1]); + } + return 0; +} + +void adpt_hppe_port_ctrl_func_bitmap_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_port_ctrl_func_bitmap[0] = \ + ((1 << FUNC_ADPT_PORT_LOCAL_LOOPBACK_GET)| + (1 << FUNC_ADPT_PORT_AUTONEG_RESTART)| + (1 << FUNC_ADPT_PORT_DUPLEX_SET)| + (1 << FUNC_ADPT_PORT_RXMAC_STATUS_GET)| + (1 << FUNC_ADPT_PORT_CDT)| + (1 << FUNC_ADPT_PORT_TXMAC_STATUS_SET)| + (1 << FUNC_ADPT_PORT_COMBO_FIBER_MODE_SET)| + (1 << FUNC_ADPT_PORT_COMBO_MEDIUM_STATUS_GET)| + (1 << FUNC_ADPT_PORT_MAGIC_FRAME_MAC_SET)| + (1 << FUNC_ADPT_PORT_POWERSAVE_SET)| + (1 << FUNC_ADPT_PORT_HIBERNATE_SET)| + (1 << FUNC_ADPT_PORT_8023AZ_GET)| + (1 << FUNC_ADPT_PORT_RXFC_STATUS_GET)| + (1 << FUNC_ADPT_PORT_TXFC_STATUS_GET)| + (1 << FUNC_ADPT_PORT_REMOTE_LOOPBACK_SET)| + (1 << FUNC_ADPT_PORT_FLOWCTRL_SET)| + (1 << FUNC_ADPT_PORT_MRU_SET)| + (1 << FUNC_ADPT_PORT_AUTONEG_STATUS_GET)| + (1 << FUNC_ADPT_PORT_TXMAC_STATUS_GET)| + (1 << FUNC_ADPT_PORT_MDIX_GET)| + (1 << FUNC_ADPT_PORTS_LINK_STATUS_GET)| + (1 << FUNC_ADPT_PORT_MAC_LOOPBACK_SET)| + (1 << FUNC_ADPT_PORT_PHY_ID_GET)| + (1 << FUNC_ADPT_PORT_MRU_GET)| + (1 << FUNC_ADPT_PORT_POWER_ON)| + (1 << FUNC_ADPT_PORT_SPEED_SET)| + (1 << FUNC_ADPT_PORT_INTERFACE_MODE_GET)| + (1 << FUNC_ADPT_PORT_DUPLEX_GET)| + (1 << FUNC_ADPT_PORT_AUTONEG_ADV_GET)| + (1 << FUNC_ADPT_PORT_MDIX_STATUS_GET)| + (1 << FUNC_ADPT_PORT_MTU_SET)| + (1 << FUNC_ADPT_PORT_LINK_STATUS_GET)); + + p_adpt_api->adpt_port_ctrl_func_bitmap[1] = \ + ((1 << (FUNC_ADPT_PORT_8023AZ_SET % 32))| + (1 << (FUNC_ADPT_PORT_POWERSAVE_GET % 32))| + (1 << (FUNC_ADPT_PORT_COMBO_PREFER_MEDIUM_GET % 32))| + (1 << (FUNC_ADPT_PORT_COMBO_PREFER_MEDIUM_SET % 32))| + (1 << (FUNC_ADPT_PORT_POWER_OFF % 32))| + (1 << (FUNC_ADPT_PORT_TXFC_STATUS_SET % 32))| + (1 << (FUNC_ADPT_PORT_COUNTER_SET % 32))| + (1 << (FUNC_ADPT_PORT_COMBO_FIBER_MODE_GET % 32))| + (1 << (FUNC_ADPT_PORT_LOCAL_LOOPBACK_SET % 32))| + (1 << (FUNC_ADPT_PORT_WOL_STATUS_SET % 32))| + (1 << (FUNC_ADPT_PORT_MAGIC_FRAME_MAC_GET % 32))| + (1 << (FUNC_ADPT_PORT_FLOWCTRL_GET % 32))| + (1 << (FUNC_ADPT_PORT_RXMAC_STATUS_SET % 32))| + (1 << (FUNC_ADPT_PORT_COUNTER_GET % 32))| + (1 << (FUNC_ADPT_PORT_INTERFACE_MODE_SET % 32))| + (1 << (FUNC_ADPT_PORT_MAC_LOOPBACK_GET % 32))| + (1 << (FUNC_ADPT_PORT_HIBERNATE_GET % 32))| + (1 << (FUNC_ADPT_PORT_AUTONEG_ADV_SET % 32))| + (1 << (FUNC_ADPT_PORT_REMOTE_LOOPBACK_GET % 32))| + (1 << (FUNC_ADPT_PORT_COUNTER_SHOW % 32))| + (1 << (FUNC_ADPT_PORT_AUTONEG_ENABLE % 32))| + (1 << (FUNC_ADPT_PORT_MTU_GET % 32))| + (1 << (FUNC_ADPT_PORT_INTERFACE_MODE_STATUS_GET % 32))| + (1 << (FUNC_ADPT_PORT_RESET % 32))| + (1 << (FUNC_ADPT_PORT_RXFC_STATUS_SET % 32))| + (1 << (FUNC_ADPT_PORT_SPEED_GET % 32))| + (1 << (FUNC_ADPT_PORT_MDIX_SET % 32))| + (1 << (FUNC_ADPT_PORT_WOL_STATUS_GET % 32))| + (1 << (FUNC_ADPT_PORT_MAX_FRAME_SIZE_SET % 32))| + (1 << (FUNC_ADPT_PORT_MAX_FRAME_SIZE_GET % 32))| + (1 << (FUNC_ADPT_PORT_SOURCE_FILTER_GET % 32))| + (1 << (FUNC_ADPT_PORT_SOURCE_FILTER_SET % 32))); + + p_adpt_api->adpt_port_ctrl_func_bitmap[2] = \ + ((1 << (FUNC_ADPT_PORT_INTERFACE_MODE_APPLY% 32))| + (1 << (FUNC_ADPT_PORT_INTERFACE_3AZ_STATUS_SET% 32))| + (1 << (FUNC_ADPT_PORT_INTERFACE_3AZ_STATUS_GET% 32))| + (1 << (FUNC_ADPT_PORT_PROMISC_MODE_SET% 32))| + (1 << (FUNC_ADPT_PORT_PROMISC_MODE_GET% 32))| + (1 << (FUNC_ADPT_PORT_FLOWCTRL_FORCEMODE_SET% 32))| + (1 << (FUNC_ADPT_PORT_FLOWCTRL_FORCEMODE_GET% 32))); + + return; + +} + +static void adpt_hppe_port_ctrl_func_unregister(a_uint32_t dev_id, adpt_api_t *p_adpt_api) +{ + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_port_local_loopback_get = NULL; + p_adpt_api->adpt_port_autoneg_restart = NULL; + p_adpt_api->adpt_port_duplex_set = NULL; + p_adpt_api->adpt_port_rxmac_status_get = NULL; + p_adpt_api->adpt_port_cdt = NULL; + p_adpt_api->adpt_port_txmac_status_set = NULL; + p_adpt_api->adpt_port_combo_fiber_mode_set = NULL; + p_adpt_api->adpt_port_combo_medium_status_get = NULL; + p_adpt_api->adpt_port_magic_frame_mac_set = NULL; + p_adpt_api->adpt_port_powersave_set = NULL; + p_adpt_api->adpt_port_hibernate_set = NULL; + p_adpt_api->adpt_port_8023az_get = NULL; + p_adpt_api->adpt_port_rxfc_status_get = NULL; + p_adpt_api->adpt_port_txfc_status_get = NULL; + p_adpt_api->adpt_port_remote_loopback_set = NULL; + p_adpt_api->adpt_port_flowctrl_set = NULL; + p_adpt_api->adpt_port_mru_set = NULL; + p_adpt_api->adpt_port_autoneg_status_get = NULL; + p_adpt_api->adpt_port_txmac_status_get = NULL; + p_adpt_api->adpt_port_mdix_get = NULL; + p_adpt_api->adpt_ports_link_status_get = NULL; + p_adpt_api->adpt_port_mac_loopback_set = NULL; + p_adpt_api->adpt_port_phy_id_get = NULL; + p_adpt_api->adpt_port_mru_get = NULL; + p_adpt_api->adpt_port_power_on = NULL; + p_adpt_api->adpt_port_speed_set = NULL; + p_adpt_api->adpt_port_interface_mode_get = NULL; + p_adpt_api->adpt_port_duplex_get = NULL; + p_adpt_api->adpt_port_autoneg_adv_get = NULL; + p_adpt_api->adpt_port_mdix_status_get = NULL; + p_adpt_api->adpt_port_mtu_set = NULL; + p_adpt_api->adpt_port_link_status_get = NULL; + p_adpt_api->adpt_port_8023az_set = NULL; + p_adpt_api->adpt_port_powersave_get = NULL; + p_adpt_api->adpt_port_combo_prefer_medium_get = NULL; + p_adpt_api->adpt_port_combo_prefer_medium_set = NULL; + p_adpt_api->adpt_port_power_off = NULL; + p_adpt_api->adpt_port_txfc_status_set = NULL; + p_adpt_api->adpt_port_counter_set = NULL; + p_adpt_api->adpt_port_combo_fiber_mode_get = NULL; + p_adpt_api->adpt_port_local_loopback_set = NULL; + p_adpt_api->adpt_port_wol_status_set = NULL; + p_adpt_api->adpt_port_magic_frame_mac_get = NULL; + p_adpt_api->adpt_port_flowctrl_get = NULL; + p_adpt_api->adpt_port_rxmac_status_set = NULL; + p_adpt_api->adpt_port_counter_get = NULL; + p_adpt_api->adpt_port_interface_mode_set = NULL; + p_adpt_api->adpt_port_interface_mode_apply = NULL; + p_adpt_api->adpt_port_mac_loopback_get = NULL; + p_adpt_api->adpt_port_hibernate_get = NULL; + p_adpt_api->adpt_port_autoneg_adv_set = NULL; + p_adpt_api->adpt_port_remote_loopback_get = NULL; + p_adpt_api->adpt_port_counter_show = NULL; + p_adpt_api->adpt_port_autoneg_enable = NULL; + p_adpt_api->adpt_port_mtu_get = NULL; + p_adpt_api->adpt_port_interface_mode_status_get = NULL; + p_adpt_api->adpt_port_reset = NULL; + p_adpt_api->adpt_port_rxfc_status_set = NULL; + p_adpt_api->adpt_port_speed_get = NULL; + p_adpt_api->adpt_port_mdix_set = NULL; + p_adpt_api->adpt_port_wol_status_get = NULL; + p_adpt_api->adpt_port_max_frame_size_set = NULL; + p_adpt_api->adpt_port_max_frame_size_get = NULL; + p_adpt_api->adpt_port_source_filter_get = NULL; + p_adpt_api->adpt_port_source_filter_set = NULL; + p_adpt_api->adpt_port_interface_3az_status_set = NULL; + p_adpt_api->adpt_port_interface_3az_status_get = NULL; + p_adpt_api->adpt_port_promisc_mode_set = NULL; + p_adpt_api->adpt_port_promisc_mode_get = NULL; + p_adpt_api->adpt_port_flowctrl_forcemode_set = NULL; + p_adpt_api->adpt_port_flowctrl_forcemode_get = NULL; + + return; + +} + +sw_error_t adpt_hppe_port_ctrl_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return SW_FAIL; + + adpt_hppe_port_ctrl_func_unregister(dev_id, p_adpt_api); +#ifndef IN_PORTCONTROL_MINI + if(p_adpt_api->adpt_port_ctrl_func_bitmap[0] & (1 << FUNC_ADPT_PORT_LOCAL_LOOPBACK_GET)) + { + p_adpt_api->adpt_port_local_loopback_get = adpt_hppe_port_local_loopback_get; + } +#endif + if(p_adpt_api->adpt_port_ctrl_func_bitmap[0] & (1 << FUNC_ADPT_PORT_AUTONEG_RESTART)) + { + p_adpt_api->adpt_port_autoneg_restart = adpt_hppe_port_autoneg_restart; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[0] & (1 << FUNC_ADPT_PORT_DUPLEX_SET)) + { + p_adpt_api->adpt_port_duplex_set = adpt_hppe_port_duplex_set; + } +#ifndef IN_PORTCONTROL_MINI + if(p_adpt_api->adpt_port_ctrl_func_bitmap[0] & (1 << FUNC_ADPT_PORT_RXMAC_STATUS_GET)) + { + p_adpt_api->adpt_port_rxmac_status_get = adpt_hppe_port_rxmac_status_get; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[0] & (1 << FUNC_ADPT_PORT_CDT)) + { + p_adpt_api->adpt_port_cdt = adpt_hppe_port_cdt; + } +#endif + if(p_adpt_api->adpt_port_ctrl_func_bitmap[0] & (1 << FUNC_ADPT_PORT_TXMAC_STATUS_SET)) + { + p_adpt_api->adpt_port_txmac_status_set = adpt_hppe_port_txmac_status_set; + } +#ifndef IN_PORTCONTROL_MINI + if(p_adpt_api->adpt_port_ctrl_func_bitmap[0] & (1 << FUNC_ADPT_PORT_COMBO_FIBER_MODE_SET)) + { + p_adpt_api->adpt_port_combo_fiber_mode_set = adpt_hppe_port_combo_fiber_mode_set; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[0] & + (1 << FUNC_ADPT_PORT_COMBO_MEDIUM_STATUS_GET)) + { + p_adpt_api->adpt_port_combo_medium_status_get = + adpt_hppe_port_combo_medium_status_get; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[0] & (1 << FUNC_ADPT_PORT_MAGIC_FRAME_MAC_SET)) + { + p_adpt_api->adpt_port_magic_frame_mac_set = adpt_hppe_port_magic_frame_mac_set; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[0] & (1 << FUNC_ADPT_PORT_POWERSAVE_SET)) + { + p_adpt_api->adpt_port_powersave_set = adpt_hppe_port_powersave_set; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[0] & (1 << FUNC_ADPT_PORT_HIBERNATE_SET)) + { + p_adpt_api->adpt_port_hibernate_set = adpt_hppe_port_hibernate_set; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[0] & (1 << FUNC_ADPT_PORT_8023AZ_GET)) + { + p_adpt_api->adpt_port_8023az_get = adpt_hppe_port_8023az_get; + } +#endif + if(p_adpt_api->adpt_port_ctrl_func_bitmap[0] & (1 << FUNC_ADPT_PORT_RXFC_STATUS_GET)) + { + p_adpt_api->adpt_port_rxfc_status_get = adpt_hppe_port_rxfc_status_get; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[0] & (1 << FUNC_ADPT_PORT_TXFC_STATUS_GET)) + { + p_adpt_api->adpt_port_txfc_status_get = adpt_hppe_port_txfc_status_get; + } +#ifndef IN_PORTCONTROL_MINI + if(p_adpt_api->adpt_port_ctrl_func_bitmap[0] & (1 << FUNC_ADPT_PORT_REMOTE_LOOPBACK_SET)) + { + p_adpt_api->adpt_port_remote_loopback_set = adpt_hppe_port_remote_loopback_set; + } +#endif + if(p_adpt_api->adpt_port_ctrl_func_bitmap[0] & (1 << FUNC_ADPT_PORT_FLOWCTRL_SET)) + { + p_adpt_api->adpt_port_flowctrl_set = adpt_hppe_port_flowctrl_set; + } +#ifndef IN_PORTCONTROL_MINI + if(p_adpt_api->adpt_port_ctrl_func_bitmap[0] & (1 << FUNC_ADPT_PORT_MRU_SET)) + { + p_adpt_api->adpt_port_mru_set = adpt_ppe_port_mru_set; + } +#endif + if(p_adpt_api->adpt_port_ctrl_func_bitmap[0] & (1 << FUNC_ADPT_PORT_AUTONEG_STATUS_GET)) + { + p_adpt_api->adpt_port_autoneg_status_get = adpt_hppe_port_autoneg_status_get; + } +#ifndef IN_PORTCONTROL_MINI + if(p_adpt_api->adpt_port_ctrl_func_bitmap[0] & (1 << FUNC_ADPT_PORT_TXMAC_STATUS_GET)) + { + p_adpt_api->adpt_port_txmac_status_get = adpt_hppe_port_txmac_status_get; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[0] & (1 << FUNC_ADPT_PORT_MDIX_GET)) + { + p_adpt_api->adpt_port_mdix_get = adpt_hppe_port_mdix_get; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[0] & (1 << FUNC_ADPT_PORTS_LINK_STATUS_GET)) + { + p_adpt_api->adpt_ports_link_status_get = adpt_hppe_ports_link_status_get; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[0] & (1 << FUNC_ADPT_PORT_MAC_LOOPBACK_SET)) + { + p_adpt_api->adpt_port_mac_loopback_set = adpt_hppe_port_mac_loopback_set; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[0] & (1 << FUNC_ADPT_PORT_PHY_ID_GET)) + { + p_adpt_api->adpt_port_phy_id_get = adpt_hppe_port_phy_id_get; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[0] & (1 << FUNC_ADPT_PORT_MRU_GET)) + { + p_adpt_api->adpt_port_mru_get = adpt_ppe_port_mru_get; + } +#endif + if(p_adpt_api->adpt_port_ctrl_func_bitmap[0] & (1 << FUNC_ADPT_PORT_POWER_ON)) + { + p_adpt_api->adpt_port_power_on = adpt_hppe_port_power_on; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[0] & (1 << FUNC_ADPT_PORT_SPEED_SET)) + { + p_adpt_api->adpt_port_speed_set = adpt_hppe_port_speed_set; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[0] & (1 << FUNC_ADPT_PORT_INTERFACE_MODE_GET)) + { + p_adpt_api->adpt_port_interface_mode_get = adpt_hppe_port_interface_mode_get; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[0] & (1 << FUNC_ADPT_PORT_DUPLEX_GET)) + { + p_adpt_api->adpt_port_duplex_get = adpt_hppe_port_duplex_get; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[0] & (1 << FUNC_ADPT_PORT_AUTONEG_ADV_GET)) + { + p_adpt_api->adpt_port_autoneg_adv_get = adpt_hppe_port_autoneg_adv_get; + } +#ifndef IN_PORTCONTROL_MINI + if(p_adpt_api->adpt_port_ctrl_func_bitmap[0] & (1 << FUNC_ADPT_PORT_MDIX_STATUS_GET)) + { + p_adpt_api->adpt_port_mdix_status_get = adpt_hppe_port_mdix_status_get; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[0] & (1 << FUNC_ADPT_PORT_MTU_SET)) + { + p_adpt_api->adpt_port_mtu_set = adpt_ppe_port_mtu_set; + } +#endif + if(p_adpt_api->adpt_port_ctrl_func_bitmap[0] & (1 << FUNC_ADPT_PORT_LINK_STATUS_GET)) + { + p_adpt_api->adpt_port_link_status_get = adpt_hppe_port_link_status_get; + } +#ifndef IN_PORTCONTROL_MINI + if(p_adpt_api->adpt_port_ctrl_func_bitmap[1] & (1 << (FUNC_ADPT_PORT_8023AZ_SET % 32))) + { + p_adpt_api->adpt_port_8023az_set = adpt_hppe_port_8023az_set; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[1] & (1 << (FUNC_ADPT_PORT_POWERSAVE_GET % 32))) + { + p_adpt_api->adpt_port_powersave_get = adpt_hppe_port_powersave_get; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[1] & + (1 << (FUNC_ADPT_PORT_COMBO_PREFER_MEDIUM_GET % 32))) + { + p_adpt_api->adpt_port_combo_prefer_medium_get = + adpt_hppe_port_combo_prefer_medium_get; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[1] & + (1 << (FUNC_ADPT_PORT_COMBO_PREFER_MEDIUM_SET % 32))) + { + p_adpt_api->adpt_port_combo_prefer_medium_set = + adpt_hppe_port_combo_prefer_medium_set; + } +#endif + if(p_adpt_api->adpt_port_ctrl_func_bitmap[1] & (1 << (FUNC_ADPT_PORT_POWER_OFF % 32))) + { + p_adpt_api->adpt_port_power_off = adpt_hppe_port_power_off; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[1] & + (1 << (FUNC_ADPT_PORT_TXFC_STATUS_SET % 32))) + { + p_adpt_api->adpt_port_txfc_status_set = adpt_hppe_port_txfc_status_set; + } +#ifndef IN_PORTCONTROL_MINI + if(p_adpt_api->adpt_port_ctrl_func_bitmap[1] & (1 << (FUNC_ADPT_PORT_COUNTER_SET % 32))) + { + p_adpt_api->adpt_port_counter_set = adpt_hppe_port_counter_set; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[1] & + (1 << (FUNC_ADPT_PORT_COMBO_FIBER_MODE_GET % 32))) + { + p_adpt_api->adpt_port_combo_fiber_mode_get = adpt_hppe_port_combo_fiber_mode_get; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[1] & + (1 << (FUNC_ADPT_PORT_LOCAL_LOOPBACK_SET % 32))) + { + p_adpt_api->adpt_port_local_loopback_set = adpt_hppe_port_local_loopback_set; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[1] & (1 << (FUNC_ADPT_PORT_WOL_STATUS_SET % 32))) + { + p_adpt_api->adpt_port_wol_status_set = adpt_hppe_port_wol_status_set; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[1] & + (1 << (FUNC_ADPT_PORT_MAGIC_FRAME_MAC_GET % 32))) + { + p_adpt_api->adpt_port_magic_frame_mac_get = adpt_hppe_port_magic_frame_mac_get; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[1] & (1 << (FUNC_ADPT_PORT_FLOWCTRL_GET % 32))) + { + p_adpt_api->adpt_port_flowctrl_get = adpt_hppe_port_flowctrl_get; + } +#endif + if(p_adpt_api->adpt_port_ctrl_func_bitmap[1] & + (1 << (FUNC_ADPT_PORT_RXMAC_STATUS_SET % 32))) + { + p_adpt_api->adpt_port_rxmac_status_set = adpt_hppe_port_rxmac_status_set; + } +#ifndef IN_PORTCONTROL_MINI + if(p_adpt_api->adpt_port_ctrl_func_bitmap[1] & (1 << (FUNC_ADPT_PORT_COUNTER_GET % 32))) + { + p_adpt_api->adpt_port_counter_get = adpt_hppe_port_counter_get; + } +#endif + if(p_adpt_api->adpt_port_ctrl_func_bitmap[1] & + (1 << (FUNC_ADPT_PORT_INTERFACE_MODE_SET % 32))) + { + p_adpt_api->adpt_port_interface_mode_set = adpt_hppe_port_interface_mode_set; + } +#ifndef IN_PORTCONTROL_MINI + if(p_adpt_api->adpt_port_ctrl_func_bitmap[1] & + (1 << (FUNC_ADPT_PORT_MAC_LOOPBACK_GET % 32))) + { + p_adpt_api->adpt_port_mac_loopback_get = adpt_hppe_port_mac_loopback_get; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[1] & (1 << (FUNC_ADPT_PORT_HIBERNATE_GET % 32))) + { + p_adpt_api->adpt_port_hibernate_get = adpt_hppe_port_hibernate_get; + } +#endif + if(p_adpt_api->adpt_port_ctrl_func_bitmap[1] & + (1 << (FUNC_ADPT_PORT_AUTONEG_ADV_SET % 32))) + { + p_adpt_api->adpt_port_autoneg_adv_set = adpt_hppe_port_autoneg_adv_set; + } +#ifndef IN_PORTCONTROL_MINI + if(p_adpt_api->adpt_port_ctrl_func_bitmap[1] & + (1 << (FUNC_ADPT_PORT_REMOTE_LOOPBACK_GET % 32))) + { + p_adpt_api->adpt_port_remote_loopback_get = adpt_hppe_port_remote_loopback_get; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[1] & (1 << (FUNC_ADPT_PORT_COUNTER_SHOW % 32))) + { + p_adpt_api->adpt_port_counter_show = adpt_hppe_port_counter_show; + } +#endif + if(p_adpt_api->adpt_port_ctrl_func_bitmap[1] & (1 << (FUNC_ADPT_PORT_AUTONEG_ENABLE % 32))) + { + p_adpt_api->adpt_port_autoneg_enable = adpt_hppe_port_autoneg_enable; + } +#ifndef IN_PORTCONTROL_MINI + if(p_adpt_api->adpt_port_ctrl_func_bitmap[1] & (1 << (FUNC_ADPT_PORT_MTU_GET % 32))) + { + p_adpt_api->adpt_port_mtu_get = adpt_ppe_port_mtu_get; + } +#endif + if(p_adpt_api->adpt_port_ctrl_func_bitmap[1] & + (1 << (FUNC_ADPT_PORT_INTERFACE_MODE_STATUS_GET % 32))) + { + p_adpt_api->adpt_port_interface_mode_status_get = + adpt_hppe_port_interface_mode_status_get; + } +#ifndef IN_PORTCONTROL_MINI + if(p_adpt_api->adpt_port_ctrl_func_bitmap[1] & (1 << (FUNC_ADPT_PORT_RESET % 32))) + { + p_adpt_api->adpt_port_reset = adpt_hppe_port_reset; + } +#endif + if(p_adpt_api->adpt_port_ctrl_func_bitmap[1] & + (1 << (FUNC_ADPT_PORT_RXFC_STATUS_SET % 32))) + { + p_adpt_api->adpt_port_rxfc_status_set = adpt_hppe_port_rxfc_status_set; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[1] & (1 << (FUNC_ADPT_PORT_SPEED_GET % 32))) + { + p_adpt_api->adpt_port_speed_get = adpt_hppe_port_speed_get; + } +#ifndef IN_PORTCONTROL_MINI + if(p_adpt_api->adpt_port_ctrl_func_bitmap[1] & (1 << (FUNC_ADPT_PORT_MDIX_SET % 32))) + { + p_adpt_api->adpt_port_mdix_set = adpt_hppe_port_mdix_set; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[1] & (1 << (FUNC_ADPT_PORT_WOL_STATUS_GET % 32))) + { + p_adpt_api->adpt_port_wol_status_get = adpt_hppe_port_wol_status_get; + } +#endif + if(p_adpt_api->adpt_port_ctrl_func_bitmap[1] & + (1 << (FUNC_ADPT_PORT_MAX_FRAME_SIZE_SET % 32))) + { + p_adpt_api->adpt_port_max_frame_size_set = adpt_ppe_port_max_frame_size_set; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[1] & + (1 << (FUNC_ADPT_PORT_MAX_FRAME_SIZE_GET % 32))) + { + p_adpt_api->adpt_port_max_frame_size_get = adpt_ppe_port_max_frame_size_get; + } +#ifndef IN_PORTCONTROL_MINI + if(p_adpt_api->adpt_port_ctrl_func_bitmap[1] & + (1 << (FUNC_ADPT_PORT_SOURCE_FILTER_GET % 32))) + { + p_adpt_api->adpt_port_source_filter_get = adpt_ppe_port_source_filter_get; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[1] & + (1 << (FUNC_ADPT_PORT_SOURCE_FILTER_SET % 32))) + { + p_adpt_api->adpt_port_source_filter_set = adpt_ppe_port_source_filter_set; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[2] & + (1 << (FUNC_ADPT_PORT_INTERFACE_MODE_APPLY% 32))) + { + p_adpt_api->adpt_port_interface_mode_apply = adpt_hppe_port_interface_mode_apply; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[2] & + (1 << (FUNC_ADPT_PORT_INTERFACE_3AZ_STATUS_SET% 32))) + { + p_adpt_api->adpt_port_interface_3az_status_set = adpt_hppe_port_interface_3az_set; + } + if(p_adpt_api->adpt_port_ctrl_func_bitmap[2] & + (1 << (FUNC_ADPT_PORT_INTERFACE_3AZ_STATUS_GET% 32))) + { + p_adpt_api->adpt_port_interface_3az_status_get = adpt_hppe_port_interface_3az_get; + } +#endif + if(p_adpt_api->adpt_port_ctrl_func_bitmap[2] & + (1 << (FUNC_ADPT_PORT_PROMISC_MODE_SET% 32))) + { + p_adpt_api->adpt_port_promisc_mode_set = adpt_hppe_port_promisc_mode_set; + } +#ifndef IN_PORTCONTROL_MINI + + if(p_adpt_api->adpt_port_ctrl_func_bitmap[2] & + (1 << (FUNC_ADPT_PORT_PROMISC_MODE_GET% 32))) + { + p_adpt_api->adpt_port_promisc_mode_get = adpt_hppe_port_promisc_mode_get; + } +#endif + if(p_adpt_api->adpt_port_ctrl_func_bitmap[2] & + (1 << (FUNC_ADPT_PORT_FLOWCTRL_FORCEMODE_SET% 32))) + { + p_adpt_api->adpt_port_flowctrl_forcemode_set = + adpt_hppe_port_flowctrl_forcemode_set; + } +#ifndef IN_PORTCONTROL_MINI + if(p_adpt_api->adpt_port_ctrl_func_bitmap[2] & + (1 << (FUNC_ADPT_PORT_FLOWCTRL_FORCEMODE_GET% 32))) + { + p_adpt_api->adpt_port_flowctrl_forcemode_get = + adpt_hppe_port_flowctrl_forcemode_get; + } + p_adpt_api->adpt_port_source_filter_config_get = adpt_ppe_port_source_filter_config_get; + p_adpt_api->adpt_port_source_filter_config_set = adpt_ppe_port_source_filter_config_set; +#endif + p_adpt_api->adpt_port_mux_mac_type_set = adpt_hppe_port_mux_mac_type_set; + p_adpt_api->adpt_port_mac_speed_set = adpt_hppe_port_mac_speed_set; + p_adpt_api->adpt_port_mac_duplex_set = adpt_hppe_port_mac_duplex_set; + p_adpt_api->adpt_port_polling_sw_sync_set = qca_hppe_mac_sw_sync_task; + p_adpt_api->adpt_port_bridge_txmac_set = adpt_hppe_port_bridge_txmac_set; + p_adpt_api->adpt_port_interface_eee_cfg_set = adpt_hppe_port_interface_eee_cfg_set; + p_adpt_api->adpt_port_interface_eee_cfg_get = adpt_hppe_port_interface_eee_cfg_get; + p_adpt_api->adpt_port_phy_status_get = adpt_hppe_port_phy_status_get; +#if defined(CPPE) + if (adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) { + p_adpt_api->adpt_switch_port_loopback_set = adpt_cppe_switch_port_loopback_set; + p_adpt_api->adpt_switch_port_loopback_get = adpt_cppe_switch_port_loopback_get; + } +#endif + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_portvlan.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_portvlan.c new file mode 100755 index 000000000..85186d1ff --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_portvlan.c @@ -0,0 +1,2212 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hppe_portvlan_reg.h" +#include "hppe_portvlan.h" +#include "hppe_portctrl_reg.h" +#include "hppe_portctrl.h" +#include "hppe_policer_reg.h" +#include "hppe_policer.h" +#include "hppe_fdb_reg.h" +#include "hppe_fdb.h" +#include "adpt.h" + +#ifndef IN_PORTVLAN_MINI +a_uint32_t +_get_port_vlan_ingress_trans_by_index(a_uint32_t dev_id, + a_uint32_t index, fal_vlan_trans_entry_t *entry) +{ + union xlt_rule_tbl_u in_vlan_xlt_rule; + union xlt_action_tbl_u in_vlan_xlt_action; + + /*rule part*/ + SW_RTN_ON_ERROR(hppe_xlt_rule_tbl_get(dev_id, index, &in_vlan_xlt_rule)); + if (!in_vlan_xlt_rule.bf.valid) { + memset(&in_vlan_xlt_rule, 0, sizeof(struct xlt_rule_tbl)); + } + + entry->trans_direction = 0; + entry->frmtype_enable = in_vlan_xlt_rule.bf.frm_type_incl; + entry->frmtype = in_vlan_xlt_rule.bf.frm_type; + entry->protocol_enable = in_vlan_xlt_rule.bf.prot_incl; + entry->protocol = ((in_vlan_xlt_rule.bf.prot_value_1 << 7) | + (in_vlan_xlt_rule.bf.prot_value_0)); + + entry->port_bitmap = in_vlan_xlt_rule.bf.port_bitmap; + entry->c_tagged = in_vlan_xlt_rule.bf.ckey_fmt_0 | (in_vlan_xlt_rule.bf.ckey_fmt_1 << 1); + entry->s_tagged = in_vlan_xlt_rule.bf.skey_fmt; + + entry->c_vid_enable = in_vlan_xlt_rule.bf.ckey_vid_incl; + entry->c_vid = in_vlan_xlt_rule.bf.ckey_vid; + entry->c_pcp_enable = in_vlan_xlt_rule.bf.ckey_pcp_incl; + entry->c_pcp = in_vlan_xlt_rule.bf.ckey_pcp; + entry->c_dei_enable = in_vlan_xlt_rule.bf.ckey_dei_incl; + entry->c_dei = in_vlan_xlt_rule.bf.ckey_dei; + + entry->s_vid_enable = in_vlan_xlt_rule.bf.skey_vid_incl; + entry->s_vid = in_vlan_xlt_rule.bf.skey_vid; + entry->s_pcp_enable = in_vlan_xlt_rule.bf.skey_pcp_incl; + entry->s_pcp = in_vlan_xlt_rule.bf.skey_pcp; + entry->s_dei_enable = in_vlan_xlt_rule.bf.skey_dei_incl; + entry->s_dei = in_vlan_xlt_rule.bf.skey_dei; + + /*action part*/ + SW_RTN_ON_ERROR(hppe_xlt_action_tbl_get(dev_id, index, &in_vlan_xlt_action)); + if (!in_vlan_xlt_rule.bf.valid) { + memset(&in_vlan_xlt_action, 0, sizeof(struct xlt_action_tbl)); + } + + entry->counter_enable = in_vlan_xlt_action.bf.counter_en; + entry->counter_id = in_vlan_xlt_action.bf.counter_id; + entry->vsi_action_enable = in_vlan_xlt_action.bf.vsi_cmd; + entry->vsi_action = in_vlan_xlt_action.bf.vsi; + + entry->cdei_xlt_enable = in_vlan_xlt_action.bf.xlt_cdei_cmd; + entry->cdei_xlt = in_vlan_xlt_action.bf.xlt_cdei; + entry->sdei_xlt_enable = in_vlan_xlt_action.bf.xlt_sdei_cmd; + entry->sdei_xlt = in_vlan_xlt_action.bf.xlt_sdei; + entry->swap_sdei_cdei = in_vlan_xlt_action.bf.dei_swap_cmd; + + entry->cpcp_xlt_enable = in_vlan_xlt_action.bf.xlt_cpcp_cmd; + entry->cpcp_xlt = in_vlan_xlt_action.bf.xlt_cpcp; + entry->spcp_xlt_enable = in_vlan_xlt_action.bf.xlt_spcp_cmd; + entry->spcp_xlt = (in_vlan_xlt_action.bf.xlt_spcp_0 | + (in_vlan_xlt_action.bf.xlt_spcp_1 << 1)); + entry->swap_spcp_cpcp = in_vlan_xlt_action.bf.pcp_swap_cmd; + + entry->cvid_xlt_cmd = in_vlan_xlt_action.bf.xlt_cvid_cmd; + entry->cvid_xlt = in_vlan_xlt_action.bf.xlt_cvid; + entry->svid_xlt_cmd = in_vlan_xlt_action.bf.xlt_svid_cmd; + entry->svid_xlt = in_vlan_xlt_action.bf.xlt_svid; + entry->swap_svid_cvid = in_vlan_xlt_action.bf.vid_swap_cmd; + + return in_vlan_xlt_rule.bf.valid; +} + +a_uint32_t +_get_port_vlan_egress_trans_by_index(a_uint32_t dev_id, + a_uint32_t index, fal_vlan_trans_entry_t *entry) +{ + union eg_vlan_xlt_rule_u eg_vlan_xlt_rule; + union eg_vlan_xlt_action_u eg_vlan_xlt_action; + + /*rule part*/ + SW_RTN_ON_ERROR(hppe_eg_vlan_xlt_rule_get(dev_id, index, &eg_vlan_xlt_rule)); + if (!eg_vlan_xlt_rule.bf.valid) { + memset(&eg_vlan_xlt_rule, 0, sizeof(struct eg_vlan_xlt_rule)); + } + + entry->trans_direction = 1; + + entry->port_bitmap = eg_vlan_xlt_rule.bf.port_bitmap; + + entry->vsi_enable = eg_vlan_xlt_rule.bf.vsi_incl; + entry->vsi = eg_vlan_xlt_rule.bf.vsi; + entry->vsi_valid = eg_vlan_xlt_rule.bf.vsi_valid; + + entry->c_tagged = eg_vlan_xlt_rule.bf.ckey_fmt; + entry->s_tagged = eg_vlan_xlt_rule.bf.skey_fmt; + + entry->c_vid_enable = eg_vlan_xlt_rule.bf.ckey_vid_incl; + entry->c_vid = eg_vlan_xlt_rule.bf.ckey_vid; + entry->c_pcp_enable = eg_vlan_xlt_rule.bf.ckey_pcp_incl; + entry->c_pcp = eg_vlan_xlt_rule.bf.ckey_pcp; + entry->c_dei_enable = eg_vlan_xlt_rule.bf.ckey_dei_incl; + entry->c_dei = eg_vlan_xlt_rule.bf.ckey_dei; + + entry->s_vid_enable = eg_vlan_xlt_rule.bf.skey_vid_incl; + entry->s_vid = eg_vlan_xlt_rule.bf.skey_vid; + entry->s_pcp_enable = eg_vlan_xlt_rule.bf.skey_pcp_incl; + entry->s_pcp = eg_vlan_xlt_rule.bf.skey_pcp; + entry->s_dei_enable = eg_vlan_xlt_rule.bf.skey_dei_incl; + entry->s_dei = eg_vlan_xlt_rule.bf.skey_dei; + + /*action part*/ + SW_RTN_ON_ERROR(hppe_eg_vlan_xlt_action_get(dev_id, index, &eg_vlan_xlt_action)); + if (!eg_vlan_xlt_rule.bf.valid) { + memset(&eg_vlan_xlt_action, 0, sizeof(struct eg_vlan_xlt_action)); + } + + entry->counter_enable = eg_vlan_xlt_action.bf.counter_en; + entry->counter_id = eg_vlan_xlt_action.bf.counter_id; + + entry->cdei_xlt_enable = eg_vlan_xlt_action.bf.xlt_cdei_cmd; + entry->cdei_xlt = eg_vlan_xlt_action.bf.xlt_cdei; + entry->sdei_xlt_enable = eg_vlan_xlt_action.bf.xlt_sdei_cmd; + entry->sdei_xlt = eg_vlan_xlt_action.bf.xlt_sdei; + entry->swap_sdei_cdei = eg_vlan_xlt_action.bf.dei_swap_cmd; + + entry->cpcp_xlt_enable = eg_vlan_xlt_action.bf.xlt_cpcp_cmd; + entry->cpcp_xlt = eg_vlan_xlt_action.bf.xlt_cpcp; + entry->spcp_xlt_enable = eg_vlan_xlt_action.bf.xlt_spcp_cmd; + entry->spcp_xlt = (eg_vlan_xlt_action.bf.xlt_spcp_0 | + (eg_vlan_xlt_action.bf.xlt_spcp_1 << 1)); + entry->swap_spcp_cpcp = eg_vlan_xlt_action.bf.pcp_swap_cmd; + + entry->cvid_xlt_cmd = eg_vlan_xlt_action.bf.xlt_cvid_cmd; + entry->cvid_xlt = eg_vlan_xlt_action.bf.xlt_cvid; + entry->svid_xlt_cmd = eg_vlan_xlt_action.bf.xlt_svid_cmd; + entry->svid_xlt = eg_vlan_xlt_action.bf.xlt_svid; + entry->swap_svid_cvid = eg_vlan_xlt_action.bf.vid_swap_cmd; + + return eg_vlan_xlt_rule.bf.valid; +} +#endif + +a_uint32_t +_get_port_vlan_trans_adv_rule_by_index(a_uint32_t dev_id, + a_uint32_t index, fal_port_vlan_direction_t direction, + fal_vlan_trans_adv_rule_t *rule, fal_vlan_trans_adv_action_t * action) +{ + union xlt_rule_tbl_u in_vlan_xlt_rule; + union xlt_action_tbl_u in_vlan_xlt_action; + union eg_vlan_xlt_rule_u eg_vlan_xlt_rule; + union eg_vlan_xlt_action_u eg_vlan_xlt_action; + + if (direction == FAL_PORT_VLAN_INGRESS) { + /*rule part*/ + SW_RTN_ON_ERROR(hppe_xlt_rule_tbl_get(dev_id, index, &in_vlan_xlt_rule)); + if (!in_vlan_xlt_rule.bf.valid) { + memset(&in_vlan_xlt_rule, 0, sizeof(struct xlt_rule_tbl)); + } + + rule->port_bitmap = in_vlan_xlt_rule.bf.port_bitmap; + + rule->s_tagged = in_vlan_xlt_rule.bf.skey_fmt; + rule->s_vid_enable = in_vlan_xlt_rule.bf.skey_vid_incl; + rule->s_vid = in_vlan_xlt_rule.bf.skey_vid; + rule->s_pcp_enable = in_vlan_xlt_rule.bf.skey_pcp_incl; + rule->s_pcp = in_vlan_xlt_rule.bf.skey_pcp; + rule->s_dei_enable = in_vlan_xlt_rule.bf.skey_dei_incl; + rule->s_dei = in_vlan_xlt_rule.bf.skey_dei; + + rule->c_tagged = in_vlan_xlt_rule.bf.ckey_fmt_0 | + (in_vlan_xlt_rule.bf.ckey_fmt_1 << 1); + rule->c_vid_enable = in_vlan_xlt_rule.bf.ckey_vid_incl; + rule->c_vid = in_vlan_xlt_rule.bf.ckey_vid; + rule->c_pcp_enable = in_vlan_xlt_rule.bf.ckey_pcp_incl; + rule->c_pcp = in_vlan_xlt_rule.bf.ckey_pcp; + rule->c_dei_enable = in_vlan_xlt_rule.bf.ckey_dei_incl; + rule->c_dei = in_vlan_xlt_rule.bf.ckey_dei; + + rule->frmtype_enable = in_vlan_xlt_rule.bf.frm_type_incl; + rule->frmtype = in_vlan_xlt_rule.bf.frm_type; + rule->protocol_enable = in_vlan_xlt_rule.bf.prot_incl; + rule->protocol = ((in_vlan_xlt_rule.bf.prot_value_1 << 7) | + (in_vlan_xlt_rule.bf.prot_value_0)); + + /*action part*/ + SW_RTN_ON_ERROR(hppe_xlt_action_tbl_get(dev_id, index, &in_vlan_xlt_action)); + if (!in_vlan_xlt_rule.bf.valid) { + memset(&in_vlan_xlt_action, 0, sizeof(struct xlt_action_tbl)); + } + + action->swap_svid_cvid = in_vlan_xlt_action.bf.vid_swap_cmd; + action->svid_xlt_cmd = in_vlan_xlt_action.bf.xlt_svid_cmd; + action->svid_xlt = in_vlan_xlt_action.bf.xlt_svid; + action->cvid_xlt_cmd = in_vlan_xlt_action.bf.xlt_cvid_cmd; + action->cvid_xlt = in_vlan_xlt_action.bf.xlt_cvid; + + action->swap_spcp_cpcp = in_vlan_xlt_action.bf.pcp_swap_cmd; + action->spcp_xlt_enable = in_vlan_xlt_action.bf.xlt_spcp_cmd; + action->spcp_xlt = (in_vlan_xlt_action.bf.xlt_spcp_0 | + (in_vlan_xlt_action.bf.xlt_spcp_1 << 1)); + action->cpcp_xlt_enable = in_vlan_xlt_action.bf.xlt_cpcp_cmd; + action->cpcp_xlt = in_vlan_xlt_action.bf.xlt_cpcp; + + action->swap_sdei_cdei = in_vlan_xlt_action.bf.dei_swap_cmd; + action->sdei_xlt_enable = in_vlan_xlt_action.bf.xlt_sdei_cmd; + action->sdei_xlt = in_vlan_xlt_action.bf.xlt_sdei; + action->cdei_xlt_enable = in_vlan_xlt_action.bf.xlt_cdei_cmd; + action->cdei_xlt = in_vlan_xlt_action.bf.xlt_cdei; + + action->counter_enable = in_vlan_xlt_action.bf.counter_en; + action->counter_id = in_vlan_xlt_action.bf.counter_id; + action->vsi_xlt_enable = in_vlan_xlt_action.bf.vsi_cmd; + action->vsi_xlt = in_vlan_xlt_action.bf.vsi; + + return in_vlan_xlt_rule.bf.valid; + } + else + { + /*rule part*/ + SW_RTN_ON_ERROR(hppe_eg_vlan_xlt_rule_get(dev_id, index, &eg_vlan_xlt_rule)); + if (!eg_vlan_xlt_rule.bf.valid) { + memset(&eg_vlan_xlt_rule, 0, sizeof(struct eg_vlan_xlt_rule)); + } + + rule->port_bitmap = eg_vlan_xlt_rule.bf.port_bitmap; + + rule->s_tagged = eg_vlan_xlt_rule.bf.skey_fmt; + rule->s_vid_enable = eg_vlan_xlt_rule.bf.skey_vid_incl; + rule->s_vid = eg_vlan_xlt_rule.bf.skey_vid; + rule->s_pcp_enable = eg_vlan_xlt_rule.bf.skey_pcp_incl; + rule->s_pcp = eg_vlan_xlt_rule.bf.skey_pcp; + rule->s_dei_enable = eg_vlan_xlt_rule.bf.skey_dei_incl; + rule->s_dei = eg_vlan_xlt_rule.bf.skey_dei; + + rule->c_tagged = eg_vlan_xlt_rule.bf.ckey_fmt; + rule->c_vid_enable = eg_vlan_xlt_rule.bf.ckey_vid_incl; + rule->c_vid = eg_vlan_xlt_rule.bf.ckey_vid; + rule->c_pcp_enable = eg_vlan_xlt_rule.bf.ckey_pcp_incl; + rule->c_pcp = eg_vlan_xlt_rule.bf.ckey_pcp; + rule->c_dei_enable = eg_vlan_xlt_rule.bf.ckey_dei_incl; + rule->c_dei = eg_vlan_xlt_rule.bf.ckey_dei; + + rule->vsi_valid = eg_vlan_xlt_rule.bf.vsi_valid; + rule->vsi_enable = eg_vlan_xlt_rule.bf.vsi_incl; + rule->vsi = eg_vlan_xlt_rule.bf.vsi; + + /*action part*/ + SW_RTN_ON_ERROR(hppe_eg_vlan_xlt_action_get(dev_id, index, &eg_vlan_xlt_action)); + if (!eg_vlan_xlt_rule.bf.valid) { + memset(&eg_vlan_xlt_action, 0, sizeof(struct eg_vlan_xlt_action)); + } + + action->swap_svid_cvid = eg_vlan_xlt_action.bf.vid_swap_cmd; + action->svid_xlt_cmd = eg_vlan_xlt_action.bf.xlt_svid_cmd; + action->svid_xlt = eg_vlan_xlt_action.bf.xlt_svid; + action->cvid_xlt_cmd = eg_vlan_xlt_action.bf.xlt_cvid_cmd; + action->cvid_xlt = eg_vlan_xlt_action.bf.xlt_cvid; + + action->swap_spcp_cpcp = eg_vlan_xlt_action.bf.pcp_swap_cmd; + action->spcp_xlt_enable = eg_vlan_xlt_action.bf.xlt_spcp_cmd; + action->spcp_xlt = (eg_vlan_xlt_action.bf.xlt_spcp_0 | + (eg_vlan_xlt_action.bf.xlt_spcp_1 << 1)); + action->cpcp_xlt_enable = eg_vlan_xlt_action.bf.xlt_cpcp_cmd; + action->cpcp_xlt = eg_vlan_xlt_action.bf.xlt_cpcp; + + action->swap_sdei_cdei = eg_vlan_xlt_action.bf.dei_swap_cmd; + action->sdei_xlt_enable = eg_vlan_xlt_action.bf.xlt_sdei_cmd; + action->sdei_xlt = eg_vlan_xlt_action.bf.xlt_sdei; + action->cdei_xlt_enable = eg_vlan_xlt_action.bf.xlt_cdei_cmd; + action->cdei_xlt = eg_vlan_xlt_action.bf.xlt_cdei; + + action->counter_enable = eg_vlan_xlt_action.bf.counter_en; + action->counter_id = eg_vlan_xlt_action.bf.counter_id; + + return eg_vlan_xlt_rule.bf.valid; + } +} + +a_uint32_t +_check_if_rule_equal(fal_port_vlan_direction_t direction, fal_vlan_trans_adv_rule_t * rule1, + fal_vlan_trans_adv_rule_t * rule2) +{ + if (!(rule1->s_tagged == rule2->s_tagged && + rule1->s_vid_enable == rule2->s_vid_enable && rule1->s_vid == rule2->s_vid && + rule1->s_pcp_enable == rule2->s_pcp_enable && rule1->s_pcp == rule2->s_pcp && + rule1->s_dei_enable == rule2->s_dei_enable && rule1->s_dei == rule2->s_dei && + rule1->c_tagged == rule2->c_tagged && + rule1->c_vid_enable == rule2->c_vid_enable && rule1->c_vid == rule2->c_vid && + rule1->c_pcp_enable == rule2->c_pcp_enable && rule1->c_pcp == rule2->c_pcp && + rule1->c_dei_enable == rule2->c_dei_enable && rule1->c_dei == rule2->c_dei)) + return 1; + + if (direction == FAL_PORT_VLAN_INGRESS) + { + if (!(rule1->frmtype_enable == rule2->frmtype_enable && + rule1->frmtype == rule2->frmtype && + rule1->protocol_enable == rule2->protocol_enable && + rule1->protocol == rule2->protocol)) + return 1; + } + else + { + if (!(rule1->vsi_valid == rule2->vsi_valid && + rule1->vsi_enable == rule2->vsi_enable && + rule1->vsi == rule2->vsi)) + return 1; + } + + return 0; +} + +a_uint32_t +_check_if_action_equal(fal_port_vlan_direction_t direction, fal_vlan_trans_adv_action_t * action1, + fal_vlan_trans_adv_action_t * action2) +{ + if (!(action1->swap_svid_cvid == action2->swap_svid_cvid && + action1->svid_xlt_cmd == action2->svid_xlt_cmd && + action1->svid_xlt == action2->svid_xlt && + action1->cvid_xlt_cmd == action2->cvid_xlt_cmd && + action1->cvid_xlt == action2->cvid_xlt && + action1->swap_sdei_cdei == action2->swap_sdei_cdei && + action1->sdei_xlt_enable == action2->sdei_xlt_enable && + action1->sdei_xlt == action2->sdei_xlt && + action1->cdei_xlt_enable == action2->cdei_xlt_enable && + action1->cdei_xlt == action2->cdei_xlt && + action1->swap_spcp_cpcp == action2->swap_spcp_cpcp && + action1->spcp_xlt_enable == action2->spcp_xlt_enable && + action1->spcp_xlt == action2->spcp_xlt && + action1->cpcp_xlt_enable == action2->cpcp_xlt_enable && + action1->cpcp_xlt == action2->cpcp_xlt && + action1->counter_enable == action2->counter_enable && + action1->counter_id == action2->counter_id)) + return 1; + + if (direction == FAL_PORT_VLAN_INGRESS) + { + if (!(action1->vsi_xlt_enable == action2->vsi_xlt_enable && + action1->vsi_xlt == action2->vsi_xlt)) + return 1; + } + + return 0; +} + +a_uint32_t +_insert_vlan_trans_adv_rule_action(a_uint32_t dev_id, a_uint32_t index, + fal_port_vlan_direction_t direction, + fal_vlan_trans_adv_rule_t * rule, fal_vlan_trans_adv_action_t * action) +{ + a_uint32_t rtn = SW_OK; + union xlt_rule_tbl_u in_vlan_xlt_rule; + union eg_vlan_xlt_rule_u eg_vlan_xlt_rule; + union xlt_action_tbl_u in_vlan_xlt_action; + union eg_vlan_xlt_action_u eg_vlan_xlt_action; + + if (direction == FAL_PORT_VLAN_INGRESS) + { + in_vlan_xlt_rule.bf.valid = A_TRUE; + in_vlan_xlt_rule.bf.port_bitmap = rule->port_bitmap; + + in_vlan_xlt_rule.bf.skey_fmt = rule->s_tagged; + in_vlan_xlt_rule.bf.skey_vid_incl = rule->s_vid_enable; + in_vlan_xlt_rule.bf.skey_vid = rule->s_vid; + in_vlan_xlt_rule.bf.skey_pcp_incl = rule->s_pcp_enable; + in_vlan_xlt_rule.bf.skey_pcp = rule->s_pcp; + in_vlan_xlt_rule.bf.skey_dei_incl = rule->s_dei_enable; + in_vlan_xlt_rule.bf.skey_dei = rule->s_dei; + + in_vlan_xlt_rule.bf.ckey_fmt_0 = (rule->c_tagged & 0x1); + in_vlan_xlt_rule.bf.ckey_fmt_1 = (rule->c_tagged >> 1); + in_vlan_xlt_rule.bf.ckey_vid_incl = rule->c_vid_enable; + in_vlan_xlt_rule.bf.ckey_vid = rule->c_vid; + in_vlan_xlt_rule.bf.ckey_pcp_incl = rule->c_pcp_enable; + in_vlan_xlt_rule.bf.ckey_pcp = rule->c_pcp; + in_vlan_xlt_rule.bf.ckey_dei_incl = rule->c_dei_enable; + in_vlan_xlt_rule.bf.ckey_dei = rule->c_dei; + + in_vlan_xlt_rule.bf.prot_incl = rule->protocol_enable; + in_vlan_xlt_rule.bf.prot_value_0 = (rule->protocol & 0x7f); + in_vlan_xlt_rule.bf.prot_value_1 = (rule->protocol >> 7); + in_vlan_xlt_rule.bf.frm_type_incl = rule->frmtype_enable; + in_vlan_xlt_rule.bf.frm_type = rule->frmtype; + + SW_RTN_ON_ERROR(hppe_xlt_rule_tbl_set(dev_id, index, &in_vlan_xlt_rule)); + + /*action part*/ + in_vlan_xlt_action.bf.vid_swap_cmd = action->swap_svid_cvid; + in_vlan_xlt_action.bf.xlt_svid_cmd = action->svid_xlt_cmd; + in_vlan_xlt_action.bf.xlt_svid = action->svid_xlt; + in_vlan_xlt_action.bf.xlt_cvid_cmd = action->cvid_xlt_cmd; + in_vlan_xlt_action.bf.xlt_cvid = action->cvid_xlt; + + in_vlan_xlt_action.bf.pcp_swap_cmd = action->swap_spcp_cpcp; + in_vlan_xlt_action.bf.xlt_spcp_cmd = action->spcp_xlt_enable; + in_vlan_xlt_action.bf.xlt_spcp_0 = (action->spcp_xlt & 0x1); + in_vlan_xlt_action.bf.xlt_spcp_1 = (action->spcp_xlt >> 1); + in_vlan_xlt_action.bf.xlt_cpcp_cmd = action->cpcp_xlt_enable; + in_vlan_xlt_action.bf.xlt_cpcp = action->cpcp_xlt; + + in_vlan_xlt_action.bf.dei_swap_cmd = action->swap_sdei_cdei; + in_vlan_xlt_action.bf.xlt_cdei_cmd = action->cdei_xlt_enable; + in_vlan_xlt_action.bf.xlt_cdei = action->cdei_xlt; + in_vlan_xlt_action.bf.xlt_sdei_cmd = action->sdei_xlt_enable; + in_vlan_xlt_action.bf.xlt_sdei = action->sdei_xlt; + + in_vlan_xlt_action.bf.counter_en = action->counter_enable; + in_vlan_xlt_action.bf.counter_id = action->counter_id; + in_vlan_xlt_action.bf.vsi_cmd = action->vsi_xlt_enable; + in_vlan_xlt_action.bf.vsi = action->vsi_xlt; + + SW_RTN_ON_ERROR(hppe_xlt_action_tbl_set(dev_id, index, &in_vlan_xlt_action)); + } + else + { + eg_vlan_xlt_rule.bf.valid = A_TRUE; + eg_vlan_xlt_rule.bf.port_bitmap = rule->port_bitmap; + + eg_vlan_xlt_rule.bf.skey_fmt = rule->s_tagged; + eg_vlan_xlt_rule.bf.skey_vid_incl = rule->s_vid_enable; + eg_vlan_xlt_rule.bf.skey_vid = rule->s_vid; + eg_vlan_xlt_rule.bf.skey_pcp_incl = rule->s_pcp_enable; + eg_vlan_xlt_rule.bf.skey_pcp = rule->s_pcp; + eg_vlan_xlt_rule.bf.skey_dei_incl = rule->s_dei_enable; + eg_vlan_xlt_rule.bf.skey_dei = rule->s_dei; + + eg_vlan_xlt_rule.bf.ckey_fmt = rule->c_tagged; + eg_vlan_xlt_rule.bf.ckey_vid_incl = rule->c_vid_enable; + eg_vlan_xlt_rule.bf.ckey_vid = rule->c_vid; + eg_vlan_xlt_rule.bf.ckey_pcp_incl = rule->c_pcp_enable; + eg_vlan_xlt_rule.bf.ckey_pcp = rule->c_pcp; + eg_vlan_xlt_rule.bf.ckey_dei_incl = rule->c_dei_enable; + eg_vlan_xlt_rule.bf.ckey_dei = rule->c_dei; + + eg_vlan_xlt_rule.bf.vsi_valid = rule->vsi_valid; + eg_vlan_xlt_rule.bf.vsi_incl = rule->vsi_enable; + eg_vlan_xlt_rule.bf.vsi = rule->vsi; + + SW_RTN_ON_ERROR(hppe_eg_vlan_xlt_rule_set(dev_id, index, &eg_vlan_xlt_rule)); + + /*action part*/ + eg_vlan_xlt_action.bf.vid_swap_cmd = action->swap_svid_cvid; + eg_vlan_xlt_action.bf.xlt_svid_cmd = action->svid_xlt_cmd; + eg_vlan_xlt_action.bf.xlt_svid = action->svid_xlt; + eg_vlan_xlt_action.bf.xlt_cvid_cmd = action->cvid_xlt_cmd; + eg_vlan_xlt_action.bf.xlt_cvid = action->cvid_xlt; + + eg_vlan_xlt_action.bf.pcp_swap_cmd = action->swap_spcp_cpcp; + eg_vlan_xlt_action.bf.xlt_spcp_cmd = action->spcp_xlt_enable; + eg_vlan_xlt_action.bf.xlt_spcp_0 = (action->spcp_xlt & 0x1); + eg_vlan_xlt_action.bf.xlt_spcp_1 = (action->spcp_xlt >> 1); + eg_vlan_xlt_action.bf.xlt_cpcp_cmd = action->cpcp_xlt_enable; + eg_vlan_xlt_action.bf.xlt_cpcp = action->cpcp_xlt; + + eg_vlan_xlt_action.bf.dei_swap_cmd = action->swap_sdei_cdei; + eg_vlan_xlt_action.bf.xlt_sdei_cmd = action->sdei_xlt_enable; + eg_vlan_xlt_action.bf.xlt_sdei = action->sdei_xlt; + eg_vlan_xlt_action.bf.xlt_cdei_cmd = action->cdei_xlt_enable; + eg_vlan_xlt_action.bf.xlt_cdei = action->cdei_xlt; + + eg_vlan_xlt_action.bf.counter_en = action->counter_enable; + eg_vlan_xlt_action.bf.counter_id = action->counter_id; + + SW_RTN_ON_ERROR(hppe_eg_vlan_xlt_action_set(dev_id, index, &eg_vlan_xlt_action)); + } + + return rtn; +} + +sw_error_t +adpt_hppe_global_qinq_mode_set(a_uint32_t dev_id, fal_global_qinq_mode_t *mode) +{ + sw_error_t rtn = SW_OK; + + ADPT_DEV_ID_CHECK(dev_id); + + if (FAL_FLG_TST(mode->mask, FAL_GLOBAL_QINQ_MODE_INGRESS_EN)) { + SW_RTN_ON_ERROR(hppe_bridge_config_bridge_type_set(dev_id, + (a_uint32_t)mode->ingress_mode)); + } + + if (FAL_FLG_TST(mode->mask, FAL_GLOBAL_QINQ_MODE_EGRESS_EN)) { + SW_RTN_ON_ERROR(hppe_eg_bridge_config_bridge_type_set(dev_id, + (a_uint32_t)mode->egress_mode)); + } + + return rtn; +} + +sw_error_t +adpt_hppe_global_qinq_mode_get(a_uint32_t dev_id, fal_global_qinq_mode_t *mode) +{ + sw_error_t rtn = SW_OK; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(mode); + + SW_RTN_ON_ERROR(hppe_bridge_config_bridge_type_get(dev_id, + (a_uint32_t *)&mode->ingress_mode)); + + SW_RTN_ON_ERROR(hppe_eg_bridge_config_bridge_type_get(dev_id, + (a_uint32_t *)&mode->egress_mode)); + + return rtn; +} + +sw_error_t +adpt_hppe_port_qinq_mode_set(a_uint32_t dev_id, fal_port_t port_id, fal_port_qinq_role_t *mode) +{ + sw_error_t rtn = SW_OK; + + ADPT_DEV_ID_CHECK(dev_id); + + if (FAL_FLG_TST(mode->mask, FAL_PORT_QINQ_ROLE_INGRESS_EN)) { + SW_RTN_ON_ERROR(hppe_port_parsing_reg_port_role_set(dev_id, port_id, + (a_uint32_t)mode->ingress_port_role)); + } + + if (FAL_FLG_TST(mode->mask, FAL_PORT_QINQ_ROLE_EGRESS_EN)) { + SW_RTN_ON_ERROR(hppe_port_eg_vlan_port_vlan_type_set(dev_id, port_id, + (a_uint32_t)mode->egress_port_role)); + } + + return rtn; +} + +sw_error_t +adpt_hppe_port_qinq_mode_get(a_uint32_t dev_id, fal_port_t port_id, fal_port_qinq_role_t *mode) +{ + sw_error_t rtn = SW_OK; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(mode); + + SW_RTN_ON_ERROR(hppe_port_parsing_reg_port_role_get(dev_id, port_id, + (a_uint32_t *)&mode->ingress_port_role)); + + SW_RTN_ON_ERROR(hppe_port_eg_vlan_port_vlan_type_get(dev_id, port_id, + (a_uint32_t *)&mode->egress_port_role)); + + return rtn; +} + +sw_error_t +adpt_hppe_tpid_set(a_uint32_t dev_id, fal_tpid_t *tpid) +{ + sw_error_t rtn = SW_OK; + + ADPT_DEV_ID_CHECK(dev_id); + + if (FAL_FLG_TST(tpid->mask, FAL_TPID_CTAG_EN)) { + SW_RTN_ON_ERROR(hppe_vlan_tpid_reg_ctag_tpid_set(dev_id, + (a_uint32_t)tpid->ctpid)); + } + + if (FAL_FLG_TST(tpid->mask, FAL_TPID_STAG_EN)) { + SW_RTN_ON_ERROR(hppe_vlan_tpid_reg_stag_tpid_set(dev_id, + (a_uint32_t)tpid->stpid)); + } + + return rtn; +} + +sw_error_t +adpt_hppe_tpid_get(a_uint32_t dev_id, fal_tpid_t *tpid) +{ + sw_error_t rtn = SW_OK; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(tpid); + + SW_RTN_ON_ERROR(hppe_vlan_tpid_reg_ctag_tpid_get(dev_id, + (a_uint32_t *)&tpid->ctpid)); + + SW_RTN_ON_ERROR(hppe_vlan_tpid_reg_stag_tpid_get(dev_id, + (a_uint32_t *)&tpid->stpid)); + + return rtn; +} + +sw_error_t +adpt_hppe_egress_tpid_set(a_uint32_t dev_id, fal_tpid_t *tpid) +{ + sw_error_t rtn = SW_OK; + + ADPT_DEV_ID_CHECK(dev_id); + + if (FAL_FLG_TST(tpid->mask, FAL_TPID_CTAG_EN)) { + SW_RTN_ON_ERROR(hppe_eg_vlan_tpid_ctpid_set(dev_id, + (a_uint32_t)tpid->ctpid)); + } + + if (FAL_FLG_TST(tpid->mask, FAL_TPID_STAG_EN)) { + SW_RTN_ON_ERROR(hppe_eg_vlan_tpid_stpid_set(dev_id, + (a_uint32_t)tpid->stpid)); + } + + return rtn; +} + +sw_error_t +adpt_hppe_egress_tpid_get(a_uint32_t dev_id, fal_tpid_t *tpid) +{ + sw_error_t rtn = SW_OK; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(tpid); + + SW_RTN_ON_ERROR(hppe_eg_vlan_tpid_ctpid_get(dev_id, + (a_uint32_t *)&tpid->ctpid)); + + SW_RTN_ON_ERROR(hppe_eg_vlan_tpid_stpid_get(dev_id, + (a_uint32_t *)&tpid->stpid)); + + return rtn; +} + +sw_error_t +adpt_hppe_port_ingress_vlan_filter_set(a_uint32_t dev_id, fal_port_t port_id, + fal_ingress_vlan_filter_t *filter) +{ + sw_error_t rtn = SW_OK; + + ADPT_DEV_ID_CHECK(dev_id); + + SW_RTN_ON_ERROR(hppe_port_vlan_config_port_in_vlan_fltr_cmd_set(dev_id, + port_id, (a_uint32_t)filter->membership_filter)); + SW_RTN_ON_ERROR(hppe_port_vlan_config_port_untag_fltr_cmd_set(dev_id, + port_id, (a_uint32_t)filter->untagged_filter)); + SW_RTN_ON_ERROR(hppe_port_vlan_config_port_tag_fltr_cmd_set(dev_id, + port_id, (a_uint32_t)filter->tagged_filter)); + SW_RTN_ON_ERROR(hppe_port_vlan_config_port_pri_tag_fltr_cmd_set(dev_id, + port_id, (a_uint32_t)filter->priority_filter)); + + return rtn; +} + +sw_error_t +adpt_hppe_port_ingress_vlan_filter_get(a_uint32_t dev_id, fal_port_t port_id, + fal_ingress_vlan_filter_t *filter) +{ + sw_error_t rtn = SW_OK; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(filter); + + SW_RTN_ON_ERROR(hppe_port_vlan_config_port_in_vlan_fltr_cmd_get(dev_id, + port_id, (a_uint32_t *)&filter->membership_filter)); + SW_RTN_ON_ERROR(hppe_port_vlan_config_port_untag_fltr_cmd_get(dev_id, + port_id, (a_uint32_t *)&filter->untagged_filter)); + SW_RTN_ON_ERROR(hppe_port_vlan_config_port_tag_fltr_cmd_get(dev_id, + port_id, (a_uint32_t *)&filter->tagged_filter)); + SW_RTN_ON_ERROR(hppe_port_vlan_config_port_pri_tag_fltr_cmd_get(dev_id, + port_id, (a_uint32_t *)&filter->priority_filter)); + + return rtn; +} + +sw_error_t +adpt_hppe_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 rtn = SW_OK; + + ADPT_DEV_ID_CHECK(dev_id); + + if (direction == FAL_PORT_VLAN_EGRESS) + { + if (!FAL_FLG_TST(default_tag->mask, FAL_PORT_VLAN_TAG_CVID_EN) && + !FAL_FLG_TST(default_tag->mask, FAL_PORT_VLAN_TAG_SVID_EN)) + return SW_NOT_SUPPORTED; + } + + if (direction == FAL_PORT_VLAN_ALL || direction == FAL_PORT_VLAN_INGRESS) + { + SW_RTN_ON_ERROR(hppe_port_def_vid_port_def_cvid_en_set(dev_id, port_id, + (a_uint32_t)default_vid_en->default_cvid_en)); + SW_RTN_ON_ERROR(hppe_port_def_vid_port_def_svid_en_set(dev_id, port_id, + (a_uint32_t)default_vid_en->default_svid_en)); + + if (FAL_FLG_TST(default_tag->mask, FAL_PORT_VLAN_TAG_CVID_EN)) { + SW_RTN_ON_ERROR(hppe_port_def_vid_port_def_cvid_set(dev_id, port_id, + (a_uint32_t)default_tag->cvid)); + } + + if (FAL_FLG_TST(default_tag->mask, FAL_PORT_VLAN_TAG_SVID_EN)) { + SW_RTN_ON_ERROR(hppe_port_def_vid_port_def_svid_set(dev_id, port_id, + (a_uint32_t)default_tag->svid)); + } + + if (FAL_FLG_TST(default_tag->mask, FAL_PORT_VLAN_TAG_CPCP_EN)) { + SW_RTN_ON_ERROR(hppe_port_def_pcp_port_def_cpcp_set(dev_id, port_id, + (a_uint32_t)default_tag->cpri)); + } + + if (FAL_FLG_TST(default_tag->mask, FAL_PORT_VLAN_TAG_SPCP_EN)) { + SW_RTN_ON_ERROR(hppe_port_def_pcp_port_def_spcp_set(dev_id, port_id, + (a_uint32_t)default_tag->spri)); + } + + if (FAL_FLG_TST(default_tag->mask, FAL_PORT_VLAN_TAG_CDEI_EN)) { + SW_RTN_ON_ERROR(hppe_port_def_pcp_port_def_cdei_set(dev_id, port_id, + (a_uint32_t)default_tag->cdei)); + } + + if (FAL_FLG_TST(default_tag->mask, FAL_PORT_VLAN_TAG_SDEI_EN)) { + SW_RTN_ON_ERROR(hppe_port_def_pcp_port_def_sdei_set(dev_id, port_id, + (a_uint32_t)default_tag->sdei)); + } + } + + if (direction == FAL_PORT_VLAN_ALL || direction == FAL_PORT_VLAN_EGRESS) + { + SW_RTN_ON_ERROR(hppe_port_eg_def_vid_port_def_cvid_en_set(dev_id, + port_id, (a_uint32_t)default_vid_en->default_cvid_en)); + SW_RTN_ON_ERROR(hppe_port_eg_def_vid_port_def_svid_en_set(dev_id, + port_id, (a_uint32_t)default_vid_en->default_svid_en)); + + if (FAL_FLG_TST(default_tag->mask, FAL_PORT_VLAN_TAG_CVID_EN)) { + SW_RTN_ON_ERROR(hppe_port_eg_def_vid_port_def_cvid_set(dev_id, port_id, + (a_uint32_t)default_tag->cvid)); + } + + if (FAL_FLG_TST(default_tag->mask, FAL_PORT_VLAN_TAG_SVID_EN)) { + SW_RTN_ON_ERROR(hppe_port_eg_def_vid_port_def_svid_set(dev_id, port_id, + (a_uint32_t)default_tag->svid)); + } + } + + return rtn; +} + +sw_error_t +adpt_hppe_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 rtn = SW_OK; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(default_vid_en); + ADPT_NULL_POINT_CHECK(default_tag); + + if (direction == FAL_PORT_VLAN_ALL) + return SW_NOT_SUPPORTED; + + if (direction == FAL_PORT_VLAN_INGRESS) { + SW_RTN_ON_ERROR(hppe_port_def_vid_port_def_cvid_en_get(dev_id, port_id, + (a_uint32_t *)&default_vid_en->default_cvid_en)); + + SW_RTN_ON_ERROR(hppe_port_def_vid_port_def_svid_en_get(dev_id, port_id, + (a_uint32_t *)&default_vid_en->default_svid_en)); + + SW_RTN_ON_ERROR(hppe_port_def_vid_port_def_cvid_get(dev_id, port_id, + (a_uint32_t *)&default_tag->cvid)); + + SW_RTN_ON_ERROR(hppe_port_def_vid_port_def_svid_get(dev_id, port_id, + (a_uint32_t *)&default_tag->svid)); + + SW_RTN_ON_ERROR(hppe_port_def_pcp_port_def_cpcp_get(dev_id, port_id, + (a_uint32_t *)&default_tag->cpri)); + + SW_RTN_ON_ERROR(hppe_port_def_pcp_port_def_spcp_get(dev_id, port_id, + (a_uint32_t *)&default_tag->spri)); + + SW_RTN_ON_ERROR(hppe_port_def_pcp_port_def_cdei_get(dev_id, port_id, + (a_uint32_t *)&default_tag->cdei)); + + SW_RTN_ON_ERROR(hppe_port_def_pcp_port_def_sdei_get(dev_id, port_id, + (a_uint32_t *)&default_tag->sdei)); + } + else if (direction == FAL_PORT_VLAN_EGRESS) { + SW_RTN_ON_ERROR(hppe_port_eg_def_vid_port_def_cvid_en_get(dev_id, port_id, + (a_uint32_t *)&default_vid_en->default_cvid_en)); + + SW_RTN_ON_ERROR(hppe_port_eg_def_vid_port_def_svid_en_get(dev_id, port_id, + (a_uint32_t *)&default_vid_en->default_svid_en)); + + SW_RTN_ON_ERROR(hppe_port_eg_def_vid_port_def_cvid_get(dev_id, port_id, + (a_uint32_t *)&default_tag->cvid)); + + SW_RTN_ON_ERROR(hppe_port_eg_def_vid_port_def_svid_get(dev_id, port_id, + (a_uint32_t *)&default_tag->svid)); + + } + else + return SW_NOT_SUPPORTED; + + return rtn; +} + +sw_error_t +adpt_hppe_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 rtn = SW_OK; + a_uint32_t value_pcp, value_dei = 0; + + ADPT_DEV_ID_CHECK(dev_id); + + if (prop->pri_propagation == FAL_VLAN_PROPAGATION_DISABLE) + value_pcp = 0; + else if (prop->pri_propagation == FAL_VLAN_PROPAGATION_CLONE) + value_pcp = 1; + else + return SW_NOT_SUPPORTED; + + if (prop->dei_propagation == FAL_VLAN_PROPAGATION_DISABLE) + value_dei = 0; + else if (prop->dei_propagation == FAL_VLAN_PROPAGATION_CLONE) + value_dei = 1; + else + return SW_NOT_SUPPORTED; + + if (direction == FAL_PORT_VLAN_ALL || direction == FAL_PORT_VLAN_INGRESS) + { + if (FAL_FLG_TST(prop->mask, FAL_PORT_PROPAGATION_PCP_EN)) { + SW_RTN_ON_ERROR(hppe_port_vlan_config_port_in_pcp_prop_cmd_set(dev_id, + port_id, value_pcp)); + } + if (FAL_FLG_TST(prop->mask, FAL_PORT_PROPAGATION_DEI_EN)) { + SW_RTN_ON_ERROR(hppe_port_vlan_config_port_in_dei_prop_cmd_set(dev_id, + port_id, value_dei)); + } + } + + if (direction == FAL_PORT_VLAN_ALL || direction == FAL_PORT_VLAN_EGRESS) + { + if (FAL_FLG_TST(prop->mask, FAL_PORT_PROPAGATION_PCP_EN)) { + SW_RTN_ON_ERROR(hppe_port_eg_vlan_port_eg_pcp_prop_cmd_set(dev_id, + port_id, value_pcp)); + } + if (FAL_FLG_TST(prop->mask, FAL_PORT_PROPAGATION_DEI_EN)) { + SW_RTN_ON_ERROR(hppe_port_eg_vlan_port_eg_dei_prop_cmd_set(dev_id, + port_id, value_dei)); + } + } + + return rtn; +} + +sw_error_t +adpt_hppe_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 rtn = SW_OK; + a_uint32_t value_pcp = 0, value_dei = 0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(prop); + + if (direction == FAL_PORT_VLAN_ALL) + return SW_NOT_SUPPORTED; + + if (direction == FAL_PORT_VLAN_INGRESS) { + SW_RTN_ON_ERROR(hppe_port_vlan_config_port_in_pcp_prop_cmd_get(dev_id, + port_id, &value_pcp)); + + SW_RTN_ON_ERROR(hppe_port_vlan_config_port_in_dei_prop_cmd_get(dev_id, + port_id, &value_dei)); + } + else if (direction == FAL_PORT_VLAN_EGRESS) { + SW_RTN_ON_ERROR(hppe_port_eg_vlan_port_eg_pcp_prop_cmd_get(dev_id, + port_id, &value_pcp)); + + SW_RTN_ON_ERROR(hppe_port_eg_vlan_port_eg_dei_prop_cmd_get(dev_id, + port_id, &value_dei)); + } + else + return SW_NOT_SUPPORTED; + + if (value_pcp == 0) + prop->pri_propagation = FAL_VLAN_PROPAGATION_DISABLE; + else if (value_pcp == 1) + prop->pri_propagation = FAL_VLAN_PROPAGATION_CLONE; + else + return SW_FAIL; + + if (value_dei == 0) + prop->dei_propagation = FAL_VLAN_PROPAGATION_DISABLE; + else if (value_dei == 1) + prop->dei_propagation = FAL_VLAN_PROPAGATION_CLONE; + else + return SW_FAIL; + + + return rtn; +} + +sw_error_t +adpt_hppe_port_vlantag_egmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_vlantag_egress_mode_t *port_egvlanmode) +{ + sw_error_t rtn = SW_OK; + a_uint32_t value = 0; + + ADPT_DEV_ID_CHECK(dev_id); + + if (FAL_FLG_TST(port_egvlanmode->mask, FAL_EGRESSMODE_CTAG_EN)) { + if (port_egvlanmode->ctag_mode == FAL_EG_UNMODIFIED) { + value = 2; + } else if (port_egvlanmode->ctag_mode == FAL_EG_UNTOUCHED) { + value = 3; + } else if (port_egvlanmode->ctag_mode == FAL_EG_UNTAGGED) { + value = 0; + } else if (port_egvlanmode->ctag_mode == FAL_EG_TAGGED) { + value = 1; + } else { + return SW_FAIL; + } + + SW_RTN_ON_ERROR(hppe_port_eg_vlan_port_eg_vlan_ctag_mode_set(dev_id, + port_id, value)); + } + + if (FAL_FLG_TST(port_egvlanmode->mask, FAL_EGRESSMODE_STAG_EN)) { + if (port_egvlanmode->stag_mode == FAL_EG_UNMODIFIED) { + value = 2; + } else if (port_egvlanmode->stag_mode == FAL_EG_UNTOUCHED) { + value = 3; + } else if (port_egvlanmode->stag_mode == FAL_EG_UNTAGGED) { + value = 0; + } else if (port_egvlanmode->stag_mode == FAL_EG_TAGGED) { + value = 1; + } else { + return SW_FAIL; + } + + SW_RTN_ON_ERROR(hppe_port_eg_vlan_port_eg_vlan_stag_mode_set(dev_id, + port_id, value)); + } + + return rtn; +} + +sw_error_t +adpt_hppe_port_vlantag_egmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_vlantag_egress_mode_t *port_egvlanmode) +{ + sw_error_t rtn = SW_OK; + a_uint32_t value = 0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(port_egvlanmode); + + + SW_RTN_ON_ERROR(hppe_port_eg_vlan_port_eg_vlan_ctag_mode_get(dev_id, + port_id, &value)); + + if (value == 2) { + port_egvlanmode->ctag_mode = FAL_EG_UNMODIFIED; + } else if (value == 3) { + port_egvlanmode->ctag_mode = FAL_EG_UNTOUCHED; + } else if (value == 0) { + port_egvlanmode->ctag_mode = FAL_EG_UNTAGGED; + } else if (value == 1) { + port_egvlanmode->ctag_mode = FAL_EG_TAGGED; + } else { + return SW_FAIL; + } + + SW_RTN_ON_ERROR(hppe_port_eg_vlan_port_eg_vlan_stag_mode_get(dev_id, + port_id, &value)); + + if (value == 2) { + port_egvlanmode->stag_mode = FAL_EG_UNMODIFIED; + } else if (value == 3) { + port_egvlanmode->stag_mode = FAL_EG_UNTOUCHED; + } else if (value == 0) { + port_egvlanmode->stag_mode = FAL_EG_UNTAGGED; + } else if (value == 1) { + port_egvlanmode->stag_mode = FAL_EG_TAGGED; + } else { + return SW_FAIL; + } + + return rtn; +} + +sw_error_t +adpt_hppe_port_vlan_xlt_miss_cmd_set(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t cmd) +{ + sw_error_t rtn = SW_OK; + a_uint32_t value = 0; + + ADPT_DEV_ID_CHECK(dev_id); + + if (cmd == FAL_MAC_FRWRD) { + value = 0; + } else if (cmd == FAL_MAC_DROP) { + value = 1; + } else if (cmd == FAL_MAC_CPY_TO_CPU) { + value = 2; + } else if (cmd == FAL_MAC_RDT_TO_CPU) { + value = 3; + } else { + return SW_FAIL; + } + + SW_RTN_ON_ERROR(hppe_port_vlan_config_port_vlan_xlt_miss_fwd_cmd_set(dev_id, + port_id, value)); + + return rtn; +} + +sw_error_t +adpt_hppe_port_vlan_xlt_miss_cmd_get(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t *cmd) +{ + sw_error_t rtn = SW_OK; + a_uint32_t value = 0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cmd); + + SW_RTN_ON_ERROR(hppe_port_vlan_config_port_vlan_xlt_miss_fwd_cmd_get(dev_id, + port_id, &value)); + + if (value == 0) { + *cmd = FAL_MAC_FRWRD; + } else if (value == 1) { + *cmd = FAL_MAC_DROP; + } else if (value == 2) { + *cmd = FAL_MAC_CPY_TO_CPU; + } else if (value == 3) { + *cmd = FAL_MAC_RDT_TO_CPU; + } else { + return SW_FAIL; + } + + return rtn; +} + +#ifndef IN_PORTVLAN_MINI +sw_error_t +adpt_hppe_port_vlan_trans_iterate(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * iterator, fal_vlan_trans_entry_t *entry) +{ + a_uint32_t idx, eg_tbl_num, rule_valid; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(iterator); + ADPT_NULL_POINT_CHECK(entry); + + eg_tbl_num = XLT_RULE_TBL_NUM * 2; + + if (*iterator < XLT_RULE_TBL_NUM) { + for (idx = *iterator; idx < XLT_RULE_TBL_NUM; idx++) { + aos_mem_zero(entry, sizeof (fal_vlan_trans_entry_t)); + rule_valid = _get_port_vlan_ingress_trans_by_index(dev_id, idx, entry); + if (rule_valid == 1) { + if (SW_IS_PBMP_MEMBER(entry->port_bitmap, port_id)) + break; + } + } + + if (idx == XLT_RULE_TBL_NUM) + return SW_NO_MORE; + } + else if (*iterator < eg_tbl_num) { + for (idx = *iterator; idx < eg_tbl_num; idx++) { + aos_mem_zero(entry, sizeof (fal_vlan_trans_entry_t)); + rule_valid = _get_port_vlan_egress_trans_by_index(dev_id, + idx - XLT_RULE_TBL_NUM, entry); + if (rule_valid == 1) { + if (SW_IS_PBMP_MEMBER(entry->port_bitmap, port_id)) + break; + } + } + + if (idx == eg_tbl_num) + return SW_NO_MORE; + } + else { + return SW_OUT_OF_RANGE; + } + + *iterator = idx + 1; + + return SW_OK; +} + +sw_error_t +adpt_hppe_port_vlan_trans_add(a_uint32_t dev_id, fal_port_t port_id, fal_vlan_trans_entry_t *entry) +{ + sw_error_t rtn = SW_OK; + union xlt_rule_tbl_u in_vlan_xlt_rule; + union eg_vlan_xlt_rule_u eg_vlan_xlt_rule; + union xlt_action_tbl_u in_vlan_xlt_action; + union eg_vlan_xlt_action_u eg_vlan_xlt_action; + a_uint32_t idx, entry_idx, entry_sign, rule_valid; + fal_vlan_trans_entry_t temp; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(entry); + + entry_idx = 0; + + if (entry->trans_direction == 0) { + /*rule part*/ + entry_sign = 0; + for (idx = 0; idx < XLT_RULE_TBL_NUM; idx++) { + aos_mem_zero(&temp, sizeof (fal_vlan_trans_entry_t)); + rule_valid = _get_port_vlan_ingress_trans_by_index(dev_id, idx, &temp); + if (rule_valid == 1) { + if (!aos_mem_cmp(entry, &temp, sizeof (fal_vlan_trans_entry_t))) { + if (SW_IS_PBMP_MEMBER(temp.port_bitmap, port_id)) + return SW_ALREADY_EXIST; + entry_idx = idx; + entry_sign = 1; + break; + } + } + else { + if (entry_sign == 0) { + entry_idx = idx; + entry_sign = 1; + } + } + } + + if (entry_sign == 0) + return SW_NO_RESOURCE; + + in_vlan_xlt_rule.bf.valid = A_TRUE; + in_vlan_xlt_rule.bf.port_bitmap = entry->port_bitmap | (0x1 << port_id); + + in_vlan_xlt_rule.bf.prot_incl = entry->protocol_enable; + in_vlan_xlt_rule.bf.prot_value_0 = (entry->protocol & 0x7f); + in_vlan_xlt_rule.bf.prot_value_1 = (entry->protocol >> 7); + in_vlan_xlt_rule.bf.frm_type_incl = entry->frmtype_enable; + in_vlan_xlt_rule.bf.frm_type = entry->frmtype; + + in_vlan_xlt_rule.bf.ckey_fmt_0 = (entry->c_tagged & 0x1); + in_vlan_xlt_rule.bf.ckey_fmt_1 = (entry->c_tagged >> 1); + in_vlan_xlt_rule.bf.skey_fmt = entry->s_tagged; + + in_vlan_xlt_rule.bf.ckey_vid_incl = entry->c_vid_enable; + in_vlan_xlt_rule.bf.ckey_vid = entry->c_vid; + in_vlan_xlt_rule.bf.ckey_pcp_incl = entry->c_pcp_enable; + in_vlan_xlt_rule.bf.ckey_pcp = entry->c_pcp; + in_vlan_xlt_rule.bf.ckey_dei_incl = entry->c_dei_enable; + in_vlan_xlt_rule.bf.ckey_dei = entry->c_dei; + + in_vlan_xlt_rule.bf.skey_vid_incl = entry->s_vid_enable; + in_vlan_xlt_rule.bf.skey_vid = entry->s_vid; + in_vlan_xlt_rule.bf.skey_pcp_incl = entry->s_pcp_enable; + in_vlan_xlt_rule.bf.skey_pcp = entry->s_pcp; + in_vlan_xlt_rule.bf.skey_dei_incl = entry->s_dei_enable; + in_vlan_xlt_rule.bf.skey_dei = entry->s_dei; + + SW_RTN_ON_ERROR(hppe_xlt_rule_tbl_set(dev_id, entry_idx, &in_vlan_xlt_rule)); + + /*action part*/ + in_vlan_xlt_action.bf.counter_en = entry->counter_enable; + in_vlan_xlt_action.bf.counter_id = entry->counter_id; + in_vlan_xlt_action.bf.vsi_cmd = entry->vsi_action_enable; + in_vlan_xlt_action.bf.vsi = entry->vsi_action; + + in_vlan_xlt_action.bf.xlt_cdei_cmd = entry->cdei_xlt_enable; + in_vlan_xlt_action.bf.xlt_cdei = entry->cdei_xlt; + in_vlan_xlt_action.bf.xlt_sdei_cmd = entry->sdei_xlt_enable; + in_vlan_xlt_action.bf.xlt_sdei = entry->sdei_xlt; + in_vlan_xlt_action.bf.dei_swap_cmd = entry->swap_sdei_cdei; + + in_vlan_xlt_action.bf.xlt_cpcp_cmd = entry->cpcp_xlt_enable; + in_vlan_xlt_action.bf.xlt_cpcp = entry->cpcp_xlt; + in_vlan_xlt_action.bf.xlt_spcp_cmd = entry->spcp_xlt_enable; + in_vlan_xlt_action.bf.xlt_spcp_0 = (entry->spcp_xlt & 0x1); + in_vlan_xlt_action.bf.xlt_spcp_1 = (entry->spcp_xlt >> 1); + in_vlan_xlt_action.bf.pcp_swap_cmd = entry->swap_spcp_cpcp; + + in_vlan_xlt_action.bf.xlt_cvid_cmd = entry->cvid_xlt_cmd; + in_vlan_xlt_action.bf.xlt_cvid = entry->cvid_xlt; + in_vlan_xlt_action.bf.xlt_svid_cmd = entry->svid_xlt_cmd; + in_vlan_xlt_action.bf.xlt_svid = entry->svid_xlt; + in_vlan_xlt_action.bf.vid_swap_cmd = entry->swap_svid_cvid; + + SW_RTN_ON_ERROR(hppe_xlt_action_tbl_set(dev_id, entry_idx, &in_vlan_xlt_action)); + } + else { + /*rule part*/ + entry_sign = 0; + for (idx = 0; idx < XLT_RULE_TBL_NUM; idx++) { + aos_mem_zero(&temp, sizeof (fal_vlan_trans_entry_t)); + rule_valid = _get_port_vlan_egress_trans_by_index(dev_id, idx, &temp); + if (rule_valid == 1) { + if (!aos_mem_cmp(entry, &temp, sizeof (fal_vlan_trans_entry_t))) { + if (SW_IS_PBMP_MEMBER(temp.port_bitmap, port_id)) + return SW_ALREADY_EXIST; + entry_idx = idx; + entry_sign = 1; + break; + } + } + else { + if (entry_sign == 0) { + entry_idx = idx; + entry_sign = 1; + } + } + } + + if (entry_sign == 0) + return SW_NO_RESOURCE; + + eg_vlan_xlt_rule.bf.valid = A_TRUE; + eg_vlan_xlt_rule.bf.port_bitmap = entry->port_bitmap | (0x1 << port_id); + + eg_vlan_xlt_rule.bf.vsi_incl = entry->vsi_enable; + eg_vlan_xlt_rule.bf.vsi = entry->vsi; + eg_vlan_xlt_rule.bf.vsi_valid = entry->vsi_valid; + + eg_vlan_xlt_rule.bf.ckey_fmt = entry->c_tagged; + eg_vlan_xlt_rule.bf.skey_fmt = entry->s_tagged; + + eg_vlan_xlt_rule.bf.ckey_vid_incl = entry->c_vid_enable; + eg_vlan_xlt_rule.bf.ckey_vid = entry->c_vid; + eg_vlan_xlt_rule.bf.ckey_pcp_incl = entry->c_pcp_enable; + eg_vlan_xlt_rule.bf.ckey_pcp = entry->c_pcp; + eg_vlan_xlt_rule.bf.ckey_dei_incl = entry->c_dei_enable; + eg_vlan_xlt_rule.bf.ckey_dei = entry->c_dei; + + eg_vlan_xlt_rule.bf.skey_vid_incl = entry->s_vid_enable; + eg_vlan_xlt_rule.bf.skey_vid = entry->s_vid; + eg_vlan_xlt_rule.bf.skey_pcp_incl = entry->s_pcp_enable; + eg_vlan_xlt_rule.bf.skey_pcp = entry->s_pcp; + eg_vlan_xlt_rule.bf.skey_dei_incl = entry->s_dei_enable; + eg_vlan_xlt_rule.bf.skey_dei = entry->s_dei; + + SW_RTN_ON_ERROR(hppe_eg_vlan_xlt_rule_set(dev_id, entry_idx, &eg_vlan_xlt_rule)); + + /*action part*/ + eg_vlan_xlt_action.bf.counter_en = entry->counter_enable; + eg_vlan_xlt_action.bf.counter_id = entry->counter_id; + + eg_vlan_xlt_action.bf.xlt_cdei_cmd = entry->cdei_xlt_enable; + eg_vlan_xlt_action.bf.xlt_cdei = entry->cdei_xlt; + eg_vlan_xlt_action.bf.xlt_sdei_cmd = entry->sdei_xlt_enable; + eg_vlan_xlt_action.bf.xlt_sdei = entry->sdei_xlt; + eg_vlan_xlt_action.bf.dei_swap_cmd = entry->swap_sdei_cdei; + + eg_vlan_xlt_action.bf.xlt_cpcp_cmd = entry->cpcp_xlt_enable; + eg_vlan_xlt_action.bf.xlt_cpcp = entry->cpcp_xlt; + eg_vlan_xlt_action.bf.xlt_spcp_cmd = entry->spcp_xlt_enable; + eg_vlan_xlt_action.bf.xlt_spcp_0 = (entry->spcp_xlt & 0x1); + eg_vlan_xlt_action.bf.xlt_spcp_1 = (entry->spcp_xlt >> 1); + eg_vlan_xlt_action.bf.pcp_swap_cmd = entry->swap_spcp_cpcp; + + eg_vlan_xlt_action.bf.xlt_cvid_cmd = entry->cvid_xlt_cmd; + eg_vlan_xlt_action.bf.xlt_cvid = entry->cvid_xlt; + eg_vlan_xlt_action.bf.xlt_svid_cmd = entry->svid_xlt_cmd; + eg_vlan_xlt_action.bf.xlt_svid = entry->svid_xlt; + eg_vlan_xlt_action.bf.vid_swap_cmd = entry->swap_svid_cvid; + + SW_RTN_ON_ERROR(hppe_eg_vlan_xlt_action_set(dev_id, + entry_idx, &eg_vlan_xlt_action)); + } + + return rtn; +} + +sw_error_t +adpt_hppe_port_vlan_trans_get(a_uint32_t dev_id, fal_port_t port_id, fal_vlan_trans_entry_t *entry) +{ + a_uint32_t idx, rule_valid; + fal_vlan_trans_entry_t temp; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(entry); + + if (entry->trans_direction == 0) { + for (idx = 0; idx < XLT_RULE_TBL_NUM; idx++) { + aos_mem_zero(&temp, sizeof (fal_vlan_trans_entry_t)); + rule_valid = _get_port_vlan_ingress_trans_by_index(dev_id, idx, &temp); + if (rule_valid == 1) { + if (!aos_mem_cmp(entry, &temp, sizeof(fal_vlan_trans_entry_t))) { + if (SW_IS_PBMP_MEMBER(temp.port_bitmap, port_id)) { + aos_mem_copy(entry, &temp, + sizeof(fal_vlan_trans_entry_t)); + return SW_OK; + } + } + } + } + } + else { + for (idx = 0; idx < XLT_RULE_TBL_NUM; idx++) { + aos_mem_zero(&temp, sizeof (fal_vlan_trans_entry_t)); + rule_valid = _get_port_vlan_egress_trans_by_index(dev_id, idx, &temp); + if (rule_valid == 1) { + if (!aos_mem_cmp(entry, &temp, sizeof(fal_vlan_trans_entry_t))) { + if (SW_IS_PBMP_MEMBER(temp.port_bitmap, port_id)) { + aos_mem_copy(entry, &temp, + sizeof(fal_vlan_trans_entry_t)); + return SW_OK; + } + } + } + } + } + + return SW_NOT_FOUND; +} + +sw_error_t +adpt_hppe_port_vlan_trans_del(a_uint32_t dev_id, fal_port_t port_id, fal_vlan_trans_entry_t *entry) +{ + a_uint32_t idx, rule_valid; + fal_vlan_trans_entry_t temp; + + union xlt_rule_tbl_u in_vlan_xlt_rule; + union eg_vlan_xlt_rule_u eg_vlan_xlt_rule; + union xlt_action_tbl_u in_vlan_xlt_action; + union eg_vlan_xlt_action_u eg_vlan_xlt_action; + + memset(&in_vlan_xlt_rule, 0, sizeof(struct xlt_rule_tbl)); + memset(&eg_vlan_xlt_rule, 0, sizeof(struct eg_vlan_xlt_rule)); + memset(&in_vlan_xlt_action, 0, sizeof(struct xlt_action_tbl)); + memset(&eg_vlan_xlt_action, 0, sizeof(struct eg_vlan_xlt_action)); + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(entry); + + if (entry->trans_direction == 0) { + for (idx = 0; idx < XLT_RULE_TBL_NUM; idx++) { + aos_mem_zero(&temp, sizeof (fal_vlan_trans_entry_t)); + rule_valid = _get_port_vlan_ingress_trans_by_index(dev_id, idx, &temp); + if (rule_valid == 1) { + if (!aos_mem_cmp(entry, &temp, sizeof (fal_vlan_trans_entry_t))) { + if (SW_IS_PBMP_MEMBER(temp.port_bitmap, port_id)) { + SW_RTN_ON_ERROR(hppe_xlt_rule_tbl_set(dev_id, + idx, &in_vlan_xlt_rule)); + SW_RTN_ON_ERROR(hppe_xlt_action_tbl_set(dev_id, + idx, &in_vlan_xlt_action)); + return SW_OK; + } + } + } + } + } + else { + for (idx = 0; idx < XLT_RULE_TBL_NUM; idx++) { + aos_mem_zero(&temp, sizeof (fal_vlan_trans_entry_t)); + rule_valid = _get_port_vlan_egress_trans_by_index(dev_id, idx, &temp); + if (rule_valid == 1) { + if (!aos_mem_cmp(entry, &temp, sizeof (fal_vlan_trans_entry_t))) { + if (SW_IS_PBMP_MEMBER(temp.port_bitmap, port_id)) { + SW_RTN_ON_ERROR(hppe_eg_vlan_xlt_rule_set(dev_id, + idx, &eg_vlan_xlt_rule)); + SW_RTN_ON_ERROR(hppe_eg_vlan_xlt_action_set(dev_id, + idx, &eg_vlan_xlt_action)); + return SW_OK; + } + } + } + } + } + + return SW_NOT_FOUND; +} +#endif + +sw_error_t +adpt_hppe_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 rtn = SW_OK; + a_uint32_t value, tag_value; + + ADPT_DEV_ID_CHECK(dev_id); + + + if (egmode == FAL_EG_UNMODIFIED) { + value = 2; + } else if (egmode == FAL_EG_UNTOUCHED) { + value = 3; + } else if (egmode == FAL_EG_UNTAGGED) { + value = 0; + } else if (egmode == FAL_EG_TAGGED) { + value = 1; + } else { + return SW_FAIL; + } + + SW_RTN_ON_ERROR(hppe_eg_vsi_tag_tagged_mode_port_bitmap_get(dev_id, vsi, &tag_value)); + + tag_value &= ~(0x3 << (port_id * 2)); + tag_value |= (value << (port_id * 2)); + + SW_RTN_ON_ERROR(hppe_eg_vsi_tag_tagged_mode_port_bitmap_set(dev_id, vsi, tag_value)); + + return rtn; +} + +sw_error_t +adpt_hppe_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 rtn = SW_OK; + a_uint32_t value, tag_value; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(egmode); + + SW_RTN_ON_ERROR(hppe_eg_vsi_tag_tagged_mode_port_bitmap_get(dev_id, vsi, &tag_value)); + + value = (tag_value >> (port_id * 2)) & 0x3; + + if (value == 0) + *egmode = FAL_EG_UNTAGGED; + else if (value == 1) + *egmode = FAL_EG_TAGGED; + else if (value == 2) + *egmode = FAL_EG_UNMODIFIED; + else if (value == 3) + *egmode = FAL_EG_UNTOUCHED; + else + return SW_FAIL; + + return rtn; +} + +sw_error_t +adpt_hppe_port_vlantag_vsi_egmode_enable_set(a_uint32_t dev_id, + fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rtn = SW_OK; + + ADPT_DEV_ID_CHECK(dev_id); + + SW_RTN_ON_ERROR(hppe_port_eg_vlan_vsi_tag_mode_en_set(dev_id, port_id, enable)); + + return rtn; +} + +sw_error_t +adpt_hppe_port_vlantag_vsi_egmode_enable_get(a_uint32_t dev_id, + fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rtn = SW_OK; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + + SW_RTN_ON_ERROR(hppe_port_eg_vlan_vsi_tag_mode_en_get(dev_id, port_id, enable)); + + return rtn; +} + +#ifndef IN_PORTVLAN_MINI +sw_error_t +adpt_hppe_qinq_mode_set(a_uint32_t dev_id, fal_qinq_mode_t mode) +{ + sw_error_t rtn = SW_OK; + fal_global_qinq_mode_t global_mode; + + ADPT_DEV_ID_CHECK(dev_id); + + global_mode.mask = 0x3; + global_mode.ingress_mode = mode; + global_mode.egress_mode = mode; + adpt_hppe_global_qinq_mode_set(dev_id, &global_mode); + + return rtn; +} + +sw_error_t +adpt_hppe_qinq_mode_get(a_uint32_t dev_id, fal_qinq_mode_t * mode) +{ + sw_error_t rtn = SW_OK; + fal_global_qinq_mode_t global_mode; + + ADPT_DEV_ID_CHECK(dev_id); + + adpt_hppe_global_qinq_mode_get(dev_id, &global_mode); + + if (global_mode.ingress_mode == global_mode.egress_mode) + *mode = global_mode.ingress_mode; + else + return SW_FAIL; + + return rtn; +} + +sw_error_t +adpt_hppe_port_qinq_role_set(a_uint32_t dev_id, fal_port_t port_id, fal_qinq_port_role_t role) +{ + sw_error_t rtn = SW_OK; + fal_port_qinq_role_t port_role; + + ADPT_DEV_ID_CHECK(dev_id); + + port_role.mask = 0x3; + port_role.ingress_port_role = role; + port_role.egress_port_role = role; + adpt_hppe_port_qinq_mode_set(dev_id, port_id, &port_role); + + return rtn; +} + +sw_error_t +adpt_hppe_port_qinq_role_get(a_uint32_t dev_id, fal_port_t port_id, fal_qinq_port_role_t * role) +{ + sw_error_t rtn = SW_OK; + fal_port_qinq_role_t port_role; + + ADPT_DEV_ID_CHECK(dev_id); + + adpt_hppe_port_qinq_mode_get(dev_id, port_id, &port_role); + + if (port_role.ingress_port_role == port_role.egress_port_role) + *role = port_role.ingress_port_role; + else + return SW_FAIL; + + return rtn; +} +#endif + +sw_error_t +adpt_hppe_port_invlan_mode_set(a_uint32_t dev_id, fal_port_t port_id, fal_pt_invlan_mode_t mode) +{ + sw_error_t rtn = SW_OK; + fal_ingress_vlan_filter_t filter; + + ADPT_DEV_ID_CHECK(dev_id); + + if (mode == FAL_INVLAN_ADMIT_ALL) + { + filter.tagged_filter = A_FALSE; + filter.untagged_filter = A_FALSE; + filter.priority_filter = A_FALSE; + } + else if (mode == FAL_INVLAN_ADMIT_TAGGED) + { + filter.tagged_filter = A_FALSE; + filter.untagged_filter = A_TRUE; + filter.priority_filter = A_TRUE; + } + else if (mode == FAL_INVLAN_ADMIT_UNTAGGED) + { + filter.tagged_filter = A_TRUE; + filter.untagged_filter = A_FALSE; + filter.priority_filter = A_FALSE; + } + else + return SW_FAIL; + + adpt_hppe_port_ingress_vlan_filter_set(dev_id, port_id, &filter); + + return rtn; +} + +#ifndef IN_PORTVLAN_MINI +sw_error_t +adpt_hppe_port_invlan_mode_get(a_uint32_t dev_id, fal_port_t port_id, fal_pt_invlan_mode_t * mode) +{ + sw_error_t rtn = SW_OK; + fal_ingress_vlan_filter_t filter; + + ADPT_DEV_ID_CHECK(dev_id); + + adpt_hppe_port_ingress_vlan_filter_get(dev_id, port_id, &filter); + + if (filter.tagged_filter == A_FALSE && filter.untagged_filter == A_FALSE && + filter.priority_filter == A_FALSE) + *mode = FAL_INVLAN_ADMIT_ALL; + else if (filter.tagged_filter == A_FALSE && filter.untagged_filter == A_TRUE && + filter.priority_filter == A_TRUE) + *mode = FAL_INVLAN_ADMIT_TAGGED; + else if (filter.tagged_filter == A_TRUE && filter.untagged_filter == A_FALSE && + filter.priority_filter == A_FALSE) + *mode = FAL_INVLAN_ADMIT_UNTAGGED; + else + return SW_FAIL; + + return rtn; +} +#endif + +sw_error_t +adpt_hppe_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 rtn = SW_OK; + a_uint32_t entry_idx, entry_sign, rule_valid; + a_int32_t idx; + fal_vlan_trans_adv_rule_t temp_rule; + fal_vlan_trans_adv_action_t temp_action; + + ADPT_DEV_ID_CHECK(dev_id); + + if (direction == FAL_PORT_VLAN_ALL) + return SW_FAIL; + + entry_sign = 0; + for (idx = XLT_RULE_TBL_NUM - 1; idx >= 0; idx--) { + aos_mem_zero(&temp_rule, sizeof (fal_vlan_trans_adv_rule_t)); + aos_mem_zero(&temp_action, sizeof (fal_vlan_trans_adv_action_t)); + rule_valid = _get_port_vlan_trans_adv_rule_by_index(dev_id, + idx, direction, &temp_rule, &temp_action); + if (rule_valid == 1) + { /* existing rule */ + if (!_check_if_rule_equal(direction, &temp_rule, rule)) + { /* rule equal */ + if (!_check_if_action_equal(direction, &temp_action, action)) + { /* action equal */ + if (SW_IS_PBMP_MEMBER(temp_rule.port_bitmap, port_id)) + { /* current port_bitmap includes this port_id, + nothing need to do */ + return SW_ALREADY_EXIST; + } + else + { /* current port_bitmap doesn't include this port_id, + add this port_id */ + temp_rule.port_bitmap |= (0x1 << port_id); + _insert_vlan_trans_adv_rule_action(dev_id, + idx, direction, &temp_rule, + &temp_action); + return SW_OK; + } + } + else + { /* action not equal */ + if (temp_rule.port_bitmap == (0x1 << port_id)) + { /* port equal, need update action */ + _insert_vlan_trans_adv_rule_action(dev_id, + idx, direction, &temp_rule, + action); + return SW_OK; + } + else + { /* port not equal, need remove port from existing rule + bitmap, insert new rule and action later */ + temp_rule.port_bitmap &= ~(0x1 << port_id); + _insert_vlan_trans_adv_rule_action(dev_id, idx, + direction, &temp_rule, + &temp_action); + } + } + } + else + { /* rule not equal, nothing need to do */ + ; + } + } + else + { /* nonexist rule */ + if (entry_sign == 0) { + entry_idx = idx; + entry_sign = 1; + } + } + } + + if (entry_sign == 0) + return SW_NO_RESOURCE; + + /* insert new rule and action */ + rule->port_bitmap |= (0x1 << port_id); + _insert_vlan_trans_adv_rule_action(dev_id, entry_idx, direction, rule, action); + + return rtn; +} + +sw_error_t +adpt_hppe_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 rtn = SW_OK; + a_uint32_t idx, rule_valid; + fal_vlan_trans_adv_rule_t temp_rule; + fal_vlan_trans_adv_action_t temp_action; + union xlt_rule_tbl_u in_vlan_xlt_rule; + union eg_vlan_xlt_rule_u eg_vlan_xlt_rule; + union xlt_action_tbl_u in_vlan_xlt_action; + union eg_vlan_xlt_action_u eg_vlan_xlt_action; + + memset(&in_vlan_xlt_rule, 0, sizeof(struct xlt_rule_tbl)); + memset(&eg_vlan_xlt_rule, 0, sizeof(struct eg_vlan_xlt_rule)); + memset(&in_vlan_xlt_action, 0, sizeof(struct xlt_action_tbl)); + memset(&eg_vlan_xlt_action, 0, sizeof(struct eg_vlan_xlt_action)); + + ADPT_DEV_ID_CHECK(dev_id); + + if (direction == FAL_PORT_VLAN_ALL) + return SW_FAIL; + + for (idx = 0; idx < XLT_RULE_TBL_NUM; idx++) { + aos_mem_zero(&temp_rule, sizeof (fal_vlan_trans_adv_rule_t)); + aos_mem_zero(&temp_action, sizeof (fal_vlan_trans_adv_action_t)); + rule_valid = _get_port_vlan_trans_adv_rule_by_index(dev_id, + idx, direction, &temp_rule, &temp_action); + if (rule_valid == 1) + { /* existing rule */ + if (!_check_if_rule_equal(direction, &temp_rule, rule)) + { /* rule equal */ + if (!_check_if_action_equal(direction, &temp_action, action)) + { /* action equal */ + if (temp_rule.port_bitmap == (0x1 << port_id)) + { /* port equal, need delete existing rule and action */ + if (direction == FAL_PORT_VLAN_INGRESS) + { + rtn = hppe_xlt_rule_tbl_set(dev_id, + idx, &in_vlan_xlt_rule); + SW_RTN_ON_ERROR(rtn); + rtn = hppe_xlt_action_tbl_set(dev_id, + idx, &in_vlan_xlt_action); + SW_RTN_ON_ERROR(rtn); + } + else + { + rtn = hppe_eg_vlan_xlt_rule_set(dev_id, + idx, &eg_vlan_xlt_rule); + SW_RTN_ON_ERROR(rtn); + rtn = hppe_eg_vlan_xlt_action_set(dev_id, + idx, &eg_vlan_xlt_action); + SW_RTN_ON_ERROR(rtn); + } + } + else if (SW_IS_PBMP_MEMBER(temp_rule.port_bitmap, port_id)) + { /* current port_bitmap includes this port_id, + remove port from port_bitmap and update rule + and action */ + temp_rule.port_bitmap &= ~(0x1 << port_id); + _insert_vlan_trans_adv_rule_action(dev_id, + idx, direction, &temp_rule, + &temp_action); + } + else + { /* current port_bitmap doesn't include port_id, + return SW_NOT_FOUND */ + return SW_NOT_FOUND; + } + break; + } + } + } + } + + if (idx == XLT_RULE_TBL_NUM) + return SW_NOT_FOUND; + + return rtn; +} + +sw_error_t +adpt_hppe_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 rtn = SW_OK; + a_uint32_t idx, rule_valid; + fal_vlan_trans_adv_rule_t temp_rule; + fal_vlan_trans_adv_action_t temp_action; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(rule); + ADPT_NULL_POINT_CHECK(action); + + if (direction == FAL_PORT_VLAN_ALL) + return SW_FAIL; + + for (idx = 0; idx < XLT_RULE_TBL_NUM; idx++) { + aos_mem_zero(&temp_rule, sizeof (fal_vlan_trans_adv_rule_t)); + aos_mem_zero(&temp_action, sizeof (fal_vlan_trans_adv_action_t)); + rule_valid = _get_port_vlan_trans_adv_rule_by_index(dev_id, + idx, direction, &temp_rule, &temp_action); + if (rule_valid == 1 && SW_IS_PBMP_MEMBER(temp_rule.port_bitmap, port_id)) + { + aos_mem_copy(rule, &temp_rule, sizeof (fal_vlan_trans_adv_rule_t)); + aos_mem_copy(action, &temp_action, sizeof (fal_vlan_trans_adv_action_t)); + break; + } + } + + if (idx == XLT_RULE_TBL_NUM) + return SW_NOT_FOUND; + + return rtn; +} + +sw_error_t +adpt_hppe_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 rtn = SW_OK, sign_tag = 0; + a_uint32_t idx, rule_valid; + fal_vlan_trans_adv_rule_t temp_rule; + fal_vlan_trans_adv_action_t temp_action; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(rule); + ADPT_NULL_POINT_CHECK(action); + + if (direction == FAL_PORT_VLAN_ALL) + return SW_FAIL; + + for (idx = 0; idx < XLT_RULE_TBL_NUM; idx++) { + aos_mem_zero(&temp_rule, sizeof (fal_vlan_trans_adv_rule_t)); + aos_mem_zero(&temp_action, sizeof (fal_vlan_trans_adv_action_t)); + rule_valid = _get_port_vlan_trans_adv_rule_by_index(dev_id, idx, + direction, &temp_rule, &temp_action); + if (rule_valid == 1) + { /* existing rule */ + if (sign_tag == 1 && SW_IS_PBMP_MEMBER(temp_rule.port_bitmap, port_id)) + { + aos_mem_copy(rule, &temp_rule, + sizeof (fal_vlan_trans_adv_rule_t)); + aos_mem_copy(action, &temp_action, + sizeof (fal_vlan_trans_adv_action_t)); + break; + } + if (!_check_if_rule_equal(direction, &temp_rule, rule)) + { /* rule equal */ + if (!_check_if_action_equal(direction, &temp_action, action)) + { /* action equal */ + if (SW_IS_PBMP_MEMBER(temp_rule.port_bitmap, port_id)) + sign_tag = 1; + } + } + } + } + + if (idx == XLT_RULE_TBL_NUM) + return SW_NOT_FOUND; + + return rtn; +} + +sw_error_t +adpt_hppe_port_vlan_counter_get(a_uint32_t dev_id, + a_uint32_t cnt_index, fal_port_vlan_counter_t * counter) +{ + union vlan_dev_cnt_tbl_u vlan_dev_cnt_tbl; + union vlan_dev_tx_counter_tbl_u vlan_dev_tx_counter_tbl; + + SW_RTN_ON_ERROR(hppe_vlan_dev_cnt_tbl_get(dev_id, cnt_index, &vlan_dev_cnt_tbl)); + SW_RTN_ON_ERROR(hppe_vlan_dev_tx_counter_tbl_get(dev_id, + cnt_index, &vlan_dev_tx_counter_tbl)); + + counter->rx_packet_counter = vlan_dev_cnt_tbl.bf.rx_pkt_cnt; + counter->rx_byte_counter = ((a_uint64_t)vlan_dev_cnt_tbl.bf.rx_byte_cnt_1 << 32) | + vlan_dev_cnt_tbl.bf.rx_byte_cnt_0; + counter->tx_packet_counter = vlan_dev_tx_counter_tbl.bf.tx_pkt_cnt; + counter->tx_byte_counter = ((a_uint64_t)vlan_dev_tx_counter_tbl.bf.tx_byte_cnt_1 << 32) | + vlan_dev_tx_counter_tbl.bf.tx_byte_cnt_0; + + return SW_OK; +} + +sw_error_t +adpt_hppe_port_vlan_counter_cleanup(a_uint32_t dev_id, a_uint32_t cnt_index) +{ + union vlan_dev_cnt_tbl_u vlan_dev_cnt_tbl; + union vlan_dev_tx_counter_tbl_u vlan_dev_tx_counter_tbl; + + memset(&vlan_dev_cnt_tbl, 0, sizeof(union vlan_dev_cnt_tbl_u)); + memset(&vlan_dev_tx_counter_tbl, 0, sizeof(union vlan_dev_tx_counter_tbl_u)); + + SW_RTN_ON_ERROR(hppe_vlan_dev_cnt_tbl_set(dev_id, cnt_index, &vlan_dev_cnt_tbl)); + SW_RTN_ON_ERROR(hppe_vlan_dev_tx_counter_tbl_set(dev_id, + cnt_index, &vlan_dev_tx_counter_tbl)); + + return SW_OK; +} + +sw_error_t +adpt_hppe_portvlan_member_add(a_uint32_t dev_id, fal_port_t port_id, fal_port_t mem_port_id) +{ + union port_bridge_ctrl_u port_bridge_ctrl; + + port_id = FAL_PORT_ID_VALUE(port_id); + mem_port_id = FAL_PORT_ID_VALUE(mem_port_id); + + memset(&port_bridge_ctrl, 0, sizeof(port_bridge_ctrl)); + ADPT_DEV_ID_CHECK(dev_id); + + hppe_port_bridge_ctrl_get(dev_id, port_id, &port_bridge_ctrl); + + port_bridge_ctrl.bf.port_isolation_bitmap |= (0x1 << mem_port_id); + + SW_RTN_ON_ERROR(hppe_port_bridge_ctrl_set(dev_id, port_id, &port_bridge_ctrl)); + + return SW_OK; +} + +sw_error_t +adpt_hppe_portvlan_member_del(a_uint32_t dev_id, fal_port_t port_id, fal_port_t mem_port_id) +{ + union port_bridge_ctrl_u port_bridge_ctrl; + + port_id = FAL_PORT_ID_VALUE(port_id); + mem_port_id = FAL_PORT_ID_VALUE(mem_port_id); + + memset(&port_bridge_ctrl, 0, sizeof(port_bridge_ctrl)); + ADPT_DEV_ID_CHECK(dev_id); + + hppe_port_bridge_ctrl_get(dev_id, port_id, &port_bridge_ctrl); + + port_bridge_ctrl.bf.port_isolation_bitmap &= ~(0x1 << mem_port_id); + + SW_RTN_ON_ERROR(hppe_port_bridge_ctrl_set(dev_id, port_id, &port_bridge_ctrl)); + + return SW_OK; +} + +sw_error_t +adpt_hppe_portvlan_member_update(a_uint32_t dev_id, fal_port_t port_id, fal_pbmp_t mem_port_map) +{ + union port_bridge_ctrl_u port_bridge_ctrl; + + port_id = FAL_PORT_ID_VALUE(port_id); + + memset(&port_bridge_ctrl, 0, sizeof(port_bridge_ctrl)); + ADPT_DEV_ID_CHECK(dev_id); + + hppe_port_bridge_ctrl_get(dev_id, port_id, &port_bridge_ctrl); + + port_bridge_ctrl.bf.port_isolation_bitmap = mem_port_map; + + SW_RTN_ON_ERROR(hppe_port_bridge_ctrl_set(dev_id, port_id, &port_bridge_ctrl)); + + return SW_OK; +} + +sw_error_t +adpt_hppe_portvlan_member_get(a_uint32_t dev_id, fal_port_t port_id, fal_pbmp_t * mem_port_map) +{ + union port_bridge_ctrl_u port_bridge_ctrl; + + port_id = FAL_PORT_ID_VALUE(port_id); + + memset(&port_bridge_ctrl, 0, sizeof(port_bridge_ctrl)); + ADPT_DEV_ID_CHECK(dev_id); + + hppe_port_bridge_ctrl_get(dev_id, port_id, &port_bridge_ctrl); + + *mem_port_map = port_bridge_ctrl.bf.port_isolation_bitmap; + + return SW_OK; +} + +void adpt_hppe_portvlan_func_bitmap_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_portvlan_func_bitmap[0] = ((1 << FUNC_PORT_INVLAN_MODE_SET) | + (1 << FUNC_PORT_INVLAN_MODE_GET) | + (1 << FUNC_PORT_VLAN_TRANS_ADD) | + (1 << FUNC_PORT_VLAN_TRANS_DEL) | + (1 << FUNC_PORT_VLAN_TRANS_GET) | + (1 << FUNC_QINQ_MODE_SET) | + (1 << FUNC_QINQ_MODE_GET) | + (1 << FUNC_PORT_QINQ_ROLE_SET) | + (1 << FUNC_PORT_QINQ_ROLE_GET) | + (1 << FUNC_PORT_VLAN_TRANS_ITERATE) | + (1 << FUNC_GLOBAL_QINQ_MODE_SET) | + (1 << FUNC_GLOBAL_QINQ_MODE_GET) | + (1 << FUNC_PORT_QINQ_MODE_SET) | + (1 << FUNC_PORT_QINQ_MODE_GET) | + (1 << FUNC_INGRESS_TPID_SET) | + (1 << FUNC_INGRESS_TPID_GET) | + (1 << FUNC_EGRESS_TPID_SET) | + (1 << FUNC_EGRESS_TPID_GET) | + (1 << FUNC_PORT_INGRESS_VLAN_FILTER_SET) | + (1 << FUNC_PORT_INGRESS_VLAN_FILTER_GET) | + (1 << FUNC_PORT_DEFAULT_VLANTAG_SET) | + (1 << FUNC_PORT_DEFAULT_VLANTAG_GET) | + (1 << FUNC_PORT_TAG_PROPAGATION_SET) | + (1 << FUNC_PORT_TAG_PROPAGATION_GET) | + (1 << FUNC_PORT_VLANTAG_EGMODE_SET) | + (1 << FUNC_PORT_VLANTAG_EGMODE_GET) | + (1 << FUNC_PORT_VLAN_XLT_MISS_CMD_SET) | + (1 << FUNC_PORT_VLAN_XLT_MISS_CMD_GET) | + (1 << FUNC_PORT_VSI_EGMODE_SET) | + (1 << FUNC_PORT_VSI_EGMODE_GET) | + (1 << FUNC_PORT_VLANTAG_VSI_EGMODE_ENABLE_SET) | + (1 << FUNC_PORT_VLANTAG_VSI_EGMODE_ENABLE_GET)); + + p_adpt_api->adpt_portvlan_func_bitmap[1] = ((1 << (FUNC_PORT_VLAN_TRANS_ADV_ADD % 32)) | + (1 << (FUNC_PORT_VLAN_TRANS_ADV_DEL % 32)) | + (1 << (FUNC_PORT_VLAN_TRANS_ADV_GETFIRST % 32)) | + (1 << (FUNC_PORT_VLAN_TRANS_ADV_GETNEXT % 32)) | + (1 << (FUNC_PORT_VLAN_COUNTER_GET % 32)) | + (1 << (FUNC_PORT_VLAN_COUNTER_CLEANUP % 32)) | + (1 << (FUNC_PORT_VLAN_MEMBER_ADD % 32)) | + (1 << (FUNC_PORT_VLAN_MEMBER_DEL % 32)) | + (1 << (FUNC_PORT_VLAN_MEMBER_UPDATE % 32)) | + (1 << (FUNC_PORT_VLAN_MEMBER_GET % 32))); + + return; +} + +static void adpt_hppe_portvlan_func_unregister(a_uint32_t dev_id, adpt_api_t *p_adpt_api) +{ + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_global_qinq_mode_set = NULL; + p_adpt_api->adpt_global_qinq_mode_get = NULL; + p_adpt_api->adpt_port_qinq_mode_set = NULL; + p_adpt_api->adpt_port_qinq_mode_get = NULL; + p_adpt_api->adpt_tpid_set = NULL; + p_adpt_api->adpt_tpid_get = NULL; + p_adpt_api->adpt_egress_tpid_set = NULL; + p_adpt_api->adpt_egress_tpid_get = NULL; + p_adpt_api->adpt_port_ingress_vlan_filter_set = NULL; + p_adpt_api->adpt_port_ingress_vlan_filter_get = NULL; + p_adpt_api->adpt_port_default_vlantag_set = NULL; + p_adpt_api->adpt_port_default_vlantag_get = NULL; + p_adpt_api->adpt_port_tag_propagation_set = NULL; + p_adpt_api->adpt_port_tag_propagation_get = NULL; + p_adpt_api->adpt_port_vlantag_egmode_set = NULL; + p_adpt_api->adpt_port_vlantag_egmode_get = NULL; + p_adpt_api->adpt_port_vlan_xlt_miss_cmd_set = NULL; + p_adpt_api->adpt_port_vlan_xlt_miss_cmd_get = NULL; + p_adpt_api->adpt_port_vlan_trans_iterate = NULL; + p_adpt_api->adpt_port_vlan_trans_add = NULL; + p_adpt_api->adpt_port_vlan_trans_get = NULL; + p_adpt_api->adpt_port_vlan_trans_del = NULL; + + p_adpt_api->adpt_port_vsi_egmode_set = NULL; + p_adpt_api->adpt_port_vsi_egmode_get = NULL; + p_adpt_api->adpt_port_vlantag_vsi_egmode_enable_set = NULL; + p_adpt_api->adpt_port_vlantag_vsi_egmode_enable_get = NULL; + + p_adpt_api->adpt_qinq_mode_set = NULL; + p_adpt_api->adpt_qinq_mode_get = NULL; + p_adpt_api->adpt_port_qinq_role_set = NULL; + p_adpt_api->adpt_port_qinq_role_get = NULL; + p_adpt_api->adpt_port_invlan_mode_set = NULL; + p_adpt_api->adpt_port_invlan_mode_get = NULL; + + p_adpt_api->adpt_port_vlan_trans_adv_add = NULL; + p_adpt_api->adpt_port_vlan_trans_adv_del = NULL; + p_adpt_api->adpt_port_vlan_trans_adv_getfirst = NULL; + p_adpt_api->adpt_port_vlan_trans_adv_getnext = NULL; + + p_adpt_api->adpt_port_vlan_counter_get = NULL; + p_adpt_api->adpt_port_vlan_counter_cleanup = NULL; + + p_adpt_api->adpt_portvlan_member_add = NULL; + p_adpt_api->adpt_portvlan_member_del = NULL; + p_adpt_api->adpt_portvlan_member_update = NULL; + p_adpt_api->adpt_portvlan_member_get = NULL; + + return; +} + +sw_error_t adpt_hppe_portvlan_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return SW_FAIL; + + adpt_hppe_portvlan_func_unregister(dev_id, p_adpt_api); + + if (p_adpt_api->adpt_portvlan_func_bitmap[0] & (1 << FUNC_GLOBAL_QINQ_MODE_SET)) + p_adpt_api->adpt_global_qinq_mode_set = adpt_hppe_global_qinq_mode_set; + if (p_adpt_api->adpt_portvlan_func_bitmap[0] & (1 << FUNC_GLOBAL_QINQ_MODE_GET)) + p_adpt_api->adpt_global_qinq_mode_get = adpt_hppe_global_qinq_mode_get; + if (p_adpt_api->adpt_portvlan_func_bitmap[0] & (1 << FUNC_PORT_QINQ_MODE_SET)) + p_adpt_api->adpt_port_qinq_mode_set = adpt_hppe_port_qinq_mode_set; + if (p_adpt_api->adpt_portvlan_func_bitmap[0] & (1 << FUNC_PORT_QINQ_MODE_GET)) + p_adpt_api->adpt_port_qinq_mode_get = adpt_hppe_port_qinq_mode_get; + if (p_adpt_api->adpt_portvlan_func_bitmap[0] & (1 << FUNC_INGRESS_TPID_SET)) + p_adpt_api->adpt_tpid_set = adpt_hppe_tpid_set; + if (p_adpt_api->adpt_portvlan_func_bitmap[0] & (1 << FUNC_INGRESS_TPID_GET)) + p_adpt_api->adpt_tpid_get = adpt_hppe_tpid_get; + if (p_adpt_api->adpt_portvlan_func_bitmap[0] & (1 << FUNC_EGRESS_TPID_SET)) + p_adpt_api->adpt_egress_tpid_set = adpt_hppe_egress_tpid_set; + if (p_adpt_api->adpt_portvlan_func_bitmap[0] & (1 << FUNC_EGRESS_TPID_GET)) + p_adpt_api->adpt_egress_tpid_get = adpt_hppe_egress_tpid_get; + if (p_adpt_api->adpt_portvlan_func_bitmap[0] & (1 << FUNC_PORT_INGRESS_VLAN_FILTER_SET)) + p_adpt_api->adpt_port_ingress_vlan_filter_set = + adpt_hppe_port_ingress_vlan_filter_set; + if (p_adpt_api->adpt_portvlan_func_bitmap[0] & (1 << FUNC_PORT_INGRESS_VLAN_FILTER_GET)) + p_adpt_api->adpt_port_ingress_vlan_filter_get = + adpt_hppe_port_ingress_vlan_filter_get; + if (p_adpt_api->adpt_portvlan_func_bitmap[0] & (1 << FUNC_PORT_DEFAULT_VLANTAG_SET)) + p_adpt_api->adpt_port_default_vlantag_set = adpt_hppe_port_default_vlantag_set; + if (p_adpt_api->adpt_portvlan_func_bitmap[0] & (1 << FUNC_PORT_DEFAULT_VLANTAG_GET)) + p_adpt_api->adpt_port_default_vlantag_get = adpt_hppe_port_default_vlantag_get; + if (p_adpt_api->adpt_portvlan_func_bitmap[0] & (1 << FUNC_PORT_TAG_PROPAGATION_SET)) + p_adpt_api->adpt_port_tag_propagation_set = adpt_hppe_port_tag_propagation_set; + if (p_adpt_api->adpt_portvlan_func_bitmap[0] & (1 << FUNC_PORT_TAG_PROPAGATION_GET)) + p_adpt_api->adpt_port_tag_propagation_get = adpt_hppe_port_tag_propagation_get; + if (p_adpt_api->adpt_portvlan_func_bitmap[0] & (1 << FUNC_PORT_VLANTAG_EGMODE_SET)) + p_adpt_api->adpt_port_vlantag_egmode_set = adpt_hppe_port_vlantag_egmode_set; + if (p_adpt_api->adpt_portvlan_func_bitmap[0] & (1 << FUNC_PORT_VLANTAG_EGMODE_GET)) + p_adpt_api->adpt_port_vlantag_egmode_get = adpt_hppe_port_vlantag_egmode_get; + if (p_adpt_api->adpt_portvlan_func_bitmap[0] & (1 << FUNC_PORT_VLAN_XLT_MISS_CMD_SET)) + p_adpt_api->adpt_port_vlan_xlt_miss_cmd_set = adpt_hppe_port_vlan_xlt_miss_cmd_set; + if (p_adpt_api->adpt_portvlan_func_bitmap[0] & (1 << FUNC_PORT_VLAN_XLT_MISS_CMD_GET)) + p_adpt_api->adpt_port_vlan_xlt_miss_cmd_get = adpt_hppe_port_vlan_xlt_miss_cmd_get; +#ifndef IN_PORTVLAN_MINI + if (p_adpt_api->adpt_portvlan_func_bitmap[0] & (1 << FUNC_PORT_VLAN_TRANS_ITERATE)) + p_adpt_api->adpt_port_vlan_trans_iterate = adpt_hppe_port_vlan_trans_iterate; + if (p_adpt_api->adpt_portvlan_func_bitmap[0] & (1 << FUNC_PORT_VLAN_TRANS_ADD)) + p_adpt_api->adpt_port_vlan_trans_add = adpt_hppe_port_vlan_trans_add; + if (p_adpt_api->adpt_portvlan_func_bitmap[0] & (1 << FUNC_PORT_VLAN_TRANS_GET)) + p_adpt_api->adpt_port_vlan_trans_get = adpt_hppe_port_vlan_trans_get; + if (p_adpt_api->adpt_portvlan_func_bitmap[0] & (1 << FUNC_PORT_VLAN_TRANS_DEL)) + p_adpt_api->adpt_port_vlan_trans_del = adpt_hppe_port_vlan_trans_del; +#endif + + if (p_adpt_api->adpt_portvlan_func_bitmap[0] & (1 << FUNC_PORT_VSI_EGMODE_SET)) + p_adpt_api->adpt_port_vsi_egmode_set = adpt_hppe_port_vsi_egmode_set; + if (p_adpt_api->adpt_portvlan_func_bitmap[0] & (1 << FUNC_PORT_VSI_EGMODE_GET)) + p_adpt_api->adpt_port_vsi_egmode_get = adpt_hppe_port_vsi_egmode_get; + if (p_adpt_api->adpt_portvlan_func_bitmap[0] & + (1 << FUNC_PORT_VLANTAG_VSI_EGMODE_ENABLE_SET)) + p_adpt_api->adpt_port_vlantag_vsi_egmode_enable_set = + adpt_hppe_port_vlantag_vsi_egmode_enable_set; + if (p_adpt_api->adpt_portvlan_func_bitmap[0] & + (1 << FUNC_PORT_VLANTAG_VSI_EGMODE_ENABLE_GET)) + p_adpt_api->adpt_port_vlantag_vsi_egmode_enable_get = + adpt_hppe_port_vlantag_vsi_egmode_enable_get; +#ifndef IN_PORTVLAN_MINI + if (p_adpt_api->adpt_portvlan_func_bitmap[0] & (1 << FUNC_QINQ_MODE_SET)) + p_adpt_api->adpt_qinq_mode_set = adpt_hppe_qinq_mode_set; + if (p_adpt_api->adpt_portvlan_func_bitmap[0] & (1 << FUNC_QINQ_MODE_GET)) + p_adpt_api->adpt_qinq_mode_get = adpt_hppe_qinq_mode_get; + if (p_adpt_api->adpt_portvlan_func_bitmap[0] & (1 << FUNC_PORT_QINQ_ROLE_SET)) + p_adpt_api->adpt_port_qinq_role_set = adpt_hppe_port_qinq_role_set; + if (p_adpt_api->adpt_portvlan_func_bitmap[0] & (1 << FUNC_PORT_QINQ_ROLE_GET)) + p_adpt_api->adpt_port_qinq_role_get = adpt_hppe_port_qinq_role_get; + if (p_adpt_api->adpt_portvlan_func_bitmap[0] & (1 << FUNC_PORT_INVLAN_MODE_GET)) + p_adpt_api->adpt_port_invlan_mode_get = adpt_hppe_port_invlan_mode_get; +#endif + if (p_adpt_api->adpt_portvlan_func_bitmap[0] & (1 << FUNC_PORT_INVLAN_MODE_SET)) + p_adpt_api->adpt_port_invlan_mode_set = adpt_hppe_port_invlan_mode_set; + + if (p_adpt_api->adpt_portvlan_func_bitmap[1] & (1 << (FUNC_PORT_VLAN_TRANS_ADV_ADD % 32))) + p_adpt_api->adpt_port_vlan_trans_adv_add = adpt_hppe_port_vlan_trans_adv_add; + if (p_adpt_api->adpt_portvlan_func_bitmap[1] & (1 << (FUNC_PORT_VLAN_TRANS_ADV_DEL % 32))) + p_adpt_api->adpt_port_vlan_trans_adv_del = adpt_hppe_port_vlan_trans_adv_del; + if (p_adpt_api->adpt_portvlan_func_bitmap[1] & + (1 << (FUNC_PORT_VLAN_TRANS_ADV_GETFIRST % 32))) + p_adpt_api->adpt_port_vlan_trans_adv_getfirst = + adpt_hppe_port_vlan_trans_adv_getfirst; + if (p_adpt_api->adpt_portvlan_func_bitmap[1] & + (1 << (FUNC_PORT_VLAN_TRANS_ADV_GETNEXT % 32))) + p_adpt_api->adpt_port_vlan_trans_adv_getnext = + adpt_hppe_port_vlan_trans_adv_getnext; + + if (p_adpt_api->adpt_portvlan_func_bitmap[1] & (1 << (FUNC_PORT_VLAN_COUNTER_GET % 32))) + p_adpt_api->adpt_port_vlan_counter_get = adpt_hppe_port_vlan_counter_get; + if (p_adpt_api->adpt_portvlan_func_bitmap[1] & + (1 << (FUNC_PORT_VLAN_COUNTER_CLEANUP % 32))) + p_adpt_api->adpt_port_vlan_counter_cleanup = adpt_hppe_port_vlan_counter_cleanup; + if (p_adpt_api->adpt_portvlan_func_bitmap[1] & (1 << (FUNC_PORT_VLAN_MEMBER_ADD % 32))) + p_adpt_api->adpt_portvlan_member_add = adpt_hppe_portvlan_member_add; + if (p_adpt_api->adpt_portvlan_func_bitmap[1] & (1 << (FUNC_PORT_VLAN_MEMBER_DEL % 32))) + p_adpt_api->adpt_portvlan_member_del = adpt_hppe_portvlan_member_del; + if (p_adpt_api->adpt_portvlan_func_bitmap[1] & (1 << (FUNC_PORT_VLAN_MEMBER_UPDATE % 32))) + p_adpt_api->adpt_portvlan_member_update = adpt_hppe_portvlan_member_update; + if (p_adpt_api->adpt_portvlan_func_bitmap[1] & (1 << (FUNC_PORT_VLAN_MEMBER_GET % 32))) + p_adpt_api->adpt_portvlan_member_get = adpt_hppe_portvlan_member_get; + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_pppoe.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_pppoe.c new file mode 100755 index 000000000..059cae6d7 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_pppoe.c @@ -0,0 +1,330 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hppe_pppoe_reg.h" +#include "hppe_pppoe.h" +#include "hppe_ip_reg.h" +#include "hppe_ip.h" +#include "adpt.h" + +#define MAX_SESSION_ID 0xffff + +sw_error_t +adpt_hppe_pppoe_session_table_add(a_uint32_t dev_id, fal_pppoe_session_t * session_tbl) +{ + sw_error_t rv = SW_OK; + union pppoe_session_u pppoe_session = {0}; + union pppoe_session_ext_u pppoe_session_ext = {0}; + union pppoe_session_ext1_u pppoe_session_ext1 = {0}; + union eg_l3_if_tbl_u eg_l3_if_tbl = {0}; + a_uint32_t num, index, entry_idx = PPPOE_SESSION_MAX_ENTRY; + a_uint16_t smac_ext = 0; + a_uint32_t smac_ext1 = 0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(session_tbl); + + if (session_tbl->session_id > MAX_SESSION_ID) + return SW_BAD_PARAM; + if (session_tbl->multi_session == A_FALSE && session_tbl->uni_session == A_FALSE) + return SW_BAD_PARAM; + if (session_tbl->l3_if_index >= IN_L3_IF_TBL_MAX_ENTRY) + return SW_BAD_PARAM; + for (num = 0; num < PPPOE_SESSION_MAX_ENTRY; num++) + { + hppe_pppoe_session_get(dev_id, num, &pppoe_session); + hppe_pppoe_session_ext_get(dev_id, num, &pppoe_session_ext); + hppe_pppoe_session_ext1_get(dev_id, num, &pppoe_session_ext1); + + for (index = 0; index <= 3; index++) { + smac_ext1 = (smac_ext1 << 8) + session_tbl->smac_addr.uc[index]; + + } + for (index = 4; index <= 5; index++) { + smac_ext = (smac_ext << 8) + session_tbl->smac_addr.uc[index]; + } + + if (pppoe_session_ext.bf.mc_valid == A_FALSE && + pppoe_session_ext.bf.uc_valid == A_FALSE) + { + if (entry_idx == PPPOE_SESSION_MAX_ENTRY) + entry_idx = num; + } + else if (pppoe_session.bf.session_id == session_tbl->session_id && + pppoe_session_ext.bf.smac_valid == session_tbl->smac_valid) { + if (session_tbl->smac_valid == A_FALSE || + (session_tbl->smac_valid == A_TRUE && + smac_ext == pppoe_session_ext.bf.smac && + smac_ext1 == pppoe_session_ext1.bf.smac)) { + return SW_ALREADY_EXIST; + } + } + } + if (entry_idx == PPPOE_SESSION_MAX_ENTRY) + return SW_NO_RESOURCE; + + pppoe_session.bf.session_id = session_tbl->session_id; + pppoe_session.bf.port_bitmap = session_tbl->port_bitmap; + pppoe_session.bf.l3_if_index = session_tbl->l3_if_index; + + pppoe_session_ext.bf.l3_if_valid = session_tbl->l3_if_valid; + pppoe_session_ext.bf.mc_valid = session_tbl->multi_session; + pppoe_session_ext.bf.uc_valid = session_tbl->uni_session; + pppoe_session_ext.bf.smac_valid = session_tbl->smac_valid; + + pppoe_session_ext.bf.smac = smac_ext; + pppoe_session_ext1.bf.smac = smac_ext1; + + hppe_pppoe_session_set(dev_id, entry_idx, &pppoe_session); + hppe_pppoe_session_ext_set(dev_id, entry_idx, &pppoe_session_ext); + hppe_pppoe_session_ext1_set(dev_id, entry_idx, &pppoe_session_ext1); + + rv = hppe_eg_l3_if_tbl_get(dev_id, session_tbl->l3_if_index, &eg_l3_if_tbl); + SW_RTN_ON_ERROR(rv); + + eg_l3_if_tbl.bf.session_id = session_tbl->session_id; + rv = hppe_eg_l3_if_tbl_set(dev_id, session_tbl->l3_if_index, &eg_l3_if_tbl); + SW_RTN_ON_ERROR(rv); + + session_tbl->entry_id = entry_idx; + + return rv; +} + +sw_error_t +adpt_hppe_pppoe_session_table_del(a_uint32_t dev_id, fal_pppoe_session_t * session_tbl) +{ + sw_error_t rv = SW_OK; + union pppoe_session_u pppoe_session = {0}; + union pppoe_session_ext_u pppoe_session_ext = {0}; + union pppoe_session_ext1_u pppoe_session_ext1 = {0}; + union pppoe_session_u pppoe_session_zero = {0}; + union pppoe_session_ext_u pppoe_session_ext_zero = {0}; + union pppoe_session_ext1_u pppoe_session_ext1_zero = {0}; + union eg_l3_if_tbl_u eg_l3_if_tbl = {0}; + a_uint16_t smac_ext = 0; + a_uint32_t smac_ext1 = 0; + a_uint32_t num, index; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(session_tbl); + + if (session_tbl->session_id > MAX_SESSION_ID) + return SW_BAD_PARAM; + + for (num = 0; num < PPPOE_SESSION_MAX_ENTRY; num++) + { + hppe_pppoe_session_get(dev_id, num, &pppoe_session); + hppe_pppoe_session_ext_get(dev_id, num, &pppoe_session_ext); + hppe_pppoe_session_ext1_get(dev_id, num, &pppoe_session_ext1); + + for (index = 0; index <= 3; index++) { + smac_ext1 = (smac_ext1 << 8) + session_tbl->smac_addr.uc[index]; + } + for (index = 4; index <= 5; index++) { + smac_ext = (smac_ext << 8) + session_tbl->smac_addr.uc[index]; + } + + if ((pppoe_session_ext.bf.mc_valid == A_TRUE || + pppoe_session_ext.bf.uc_valid == A_TRUE) && + (pppoe_session.bf.session_id == session_tbl->session_id && + pppoe_session_ext.bf.smac_valid == session_tbl->smac_valid && + (session_tbl->smac_valid == A_FALSE || + (session_tbl->smac_valid == A_TRUE && + smac_ext == pppoe_session_ext.bf.smac && + smac_ext1 == pppoe_session_ext1.bf.smac)))) + { + hppe_pppoe_session_set(dev_id, num, &pppoe_session_zero); + hppe_pppoe_session_ext_set(dev_id, num, &pppoe_session_ext_zero); + hppe_pppoe_session_ext1_set(dev_id, num, &pppoe_session_ext1_zero); + + rv = hppe_eg_l3_if_tbl_get(dev_id, + pppoe_session.bf.l3_if_index, &eg_l3_if_tbl); + SW_RTN_ON_ERROR(rv); + + eg_l3_if_tbl.bf.session_id = 0; + rv = hppe_eg_l3_if_tbl_set(dev_id, + pppoe_session.bf.l3_if_index, &eg_l3_if_tbl); + + return rv; + } + } + + return SW_NOT_FOUND; +} + +sw_error_t +adpt_hppe_pppoe_session_table_get(a_uint32_t dev_id, fal_pppoe_session_t * session_tbl) +{ + union pppoe_session_u pppoe_session = {0}; + union pppoe_session_ext_u pppoe_session_ext = {0}; + union pppoe_session_ext1_u pppoe_session_ext1 = {0}; + a_uint16_t smac_ext = 0; + a_uint32_t smac_ext1 = 0; + a_uint32_t num, index; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(session_tbl); + + if (session_tbl->session_id > MAX_SESSION_ID) + return SW_BAD_PARAM; + + for (num = 0; num < PPPOE_SESSION_MAX_ENTRY; num++) + { + hppe_pppoe_session_get(dev_id, num, &pppoe_session); + hppe_pppoe_session_ext_get(dev_id, num, &pppoe_session_ext); + hppe_pppoe_session_ext1_get(dev_id, num, &pppoe_session_ext1); + + for (index = 0; index <= 3; index++) { + smac_ext1 = (smac_ext1 << 8) + session_tbl->smac_addr.uc[index]; + } + for (index = 4; index <= 5; index++) { + smac_ext = (smac_ext << 8) + session_tbl->smac_addr.uc[index]; + } + if ((pppoe_session_ext.bf.mc_valid == A_TRUE || + pppoe_session_ext.bf.uc_valid == A_TRUE) && + (pppoe_session.bf.session_id == session_tbl->session_id && + pppoe_session_ext.bf.smac_valid == session_tbl->smac_valid && + (session_tbl->smac_valid == A_FALSE || + (session_tbl->smac_valid == A_TRUE && + smac_ext == pppoe_session_ext.bf.smac && + smac_ext1 == pppoe_session_ext1.bf.smac)))) + { + session_tbl->entry_id = num; + session_tbl->session_id = pppoe_session.bf.session_id; + session_tbl->port_bitmap = pppoe_session.bf.port_bitmap; + session_tbl->l3_if_index = pppoe_session.bf.l3_if_index; + session_tbl->l3_if_valid = pppoe_session_ext.bf.l3_if_valid; + session_tbl->multi_session = pppoe_session_ext.bf.mc_valid; + session_tbl->uni_session = pppoe_session_ext.bf.uc_valid; + session_tbl->smac_valid = pppoe_session_ext.bf.smac_valid; + session_tbl->smac_addr.uc[0] = (pppoe_session_ext1.bf.smac >> 24) & 0xff; + session_tbl->smac_addr.uc[1] = (pppoe_session_ext1.bf.smac >> 16) & 0xff; + session_tbl->smac_addr.uc[2] = (pppoe_session_ext1.bf.smac >> 8) & 0xff; + session_tbl->smac_addr.uc[3] = pppoe_session_ext1.bf.smac & 0xff; + session_tbl->smac_addr.uc[4] = (pppoe_session_ext.bf.smac >> 8) & 0xff; + session_tbl->smac_addr.uc[5] = pppoe_session_ext.bf.smac & 0xff; + return SW_OK; + } + } + + return SW_NOT_FOUND; +} + +sw_error_t +adpt_hppe_pppoe_en_set(a_uint32_t dev_id, a_uint32_t l3_if, a_uint32_t enable) +{ + sw_error_t rv = SW_OK; + union in_l3_if_tbl_u in_l3_if_tbl = {0}; + union eg_l3_if_tbl_u eg_l3_if_tbl = {0}; + + ADPT_DEV_ID_CHECK(dev_id); + + rv = hppe_in_l3_if_tbl_get(dev_id, l3_if, &in_l3_if_tbl); + SW_RTN_ON_ERROR(rv); + + rv = hppe_eg_l3_if_tbl_get(dev_id, l3_if, &eg_l3_if_tbl); + SW_RTN_ON_ERROR(rv); + + in_l3_if_tbl.bf.pppoe_en = enable; + eg_l3_if_tbl.bf.pppoe_en = enable; + + rv = hppe_in_l3_if_tbl_set(dev_id, l3_if, &in_l3_if_tbl); + SW_RTN_ON_ERROR(rv); + + rv = hppe_eg_l3_if_tbl_set(dev_id, l3_if, &eg_l3_if_tbl); + + return rv; +} + +sw_error_t +adpt_hppe_pppoe_en_get(a_uint32_t dev_id, a_uint32_t l3_if, a_uint32_t *enable) +{ + sw_error_t rv = SW_OK; + union in_l3_if_tbl_u in_l3_if_tbl = {0}; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + + rv = hppe_in_l3_if_tbl_get(dev_id, l3_if, &in_l3_if_tbl); + SW_RTN_ON_ERROR(rv); + + *enable = in_l3_if_tbl.bf.pppoe_en; + + return rv; +} + +void adpt_hppe_pppoe_func_bitmap_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_pppoe_func_bitmap = 0x0; + + return; +} + +static void adpt_hppe_pppoe_func_unregister(a_uint32_t dev_id, adpt_api_t *p_adpt_api) +{ + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_pppoe_session_table_add = NULL; + p_adpt_api->adpt_pppoe_session_table_del = NULL; + p_adpt_api->adpt_pppoe_session_table_get = NULL; + p_adpt_api->adpt_pppoe_en_set = NULL; + p_adpt_api->adpt_pppoe_en_get = NULL; + + return; +} + +sw_error_t adpt_hppe_pppoe_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return SW_FAIL; + + adpt_hppe_pppoe_func_unregister(dev_id, p_adpt_api); + + if (p_adpt_api->adpt_pppoe_func_bitmap & (1 << FUNC_PPPOE_SESSION_TABLE_ADD)) + p_adpt_api->adpt_pppoe_session_table_add = adpt_hppe_pppoe_session_table_add; + if (p_adpt_api->adpt_pppoe_func_bitmap & (1 << FUNC_PPPOE_SESSION_TABLE_DEL)) + p_adpt_api->adpt_pppoe_session_table_del = adpt_hppe_pppoe_session_table_del; + if (p_adpt_api->adpt_pppoe_func_bitmap & (1 << FUNC_PPPOE_SESSION_TABLE_GET)) + p_adpt_api->adpt_pppoe_session_table_get = adpt_hppe_pppoe_session_table_get; + if (p_adpt_api->adpt_pppoe_func_bitmap & (1 << FUNC_PPPOE_EN_SET)) + p_adpt_api->adpt_pppoe_en_set = adpt_hppe_pppoe_en_set; + if (p_adpt_api->adpt_pppoe_func_bitmap & (1 << FUNC_PPPOE_EN_GET)) + p_adpt_api->adpt_pppoe_en_get = adpt_hppe_pppoe_en_get; + + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_ptp.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_ptp.c new file mode 100755 index 000000000..6e86261e4 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_ptp.c @@ -0,0 +1,1382 @@ +/* + * 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. + */ + + +/** + * @defgroup + * @{ + */ +#include "sw.h" +#include "adpt.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "hsl_phy.h" + +sw_error_t +adpt_hppe_ptp_config_set(a_uint32_t dev_id, a_uint32_t port_id, fal_ptp_config_t *config) +{ + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(config); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_config_set) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_config_set(dev_id, phy_id, config); + + return rv; +} + +sw_error_t +adpt_hppe_ptp_config_get(a_uint32_t dev_id, a_uint32_t port_id, fal_ptp_config_t *config) +{ + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(config); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_config_get) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_config_get(dev_id, phy_id, config); + + return rv; +} + +sw_error_t +adpt_hppe_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 = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_reference_clock_set) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_reference_clock_set(dev_id, phy_id, ref_clock); + + return rv; +} + +sw_error_t +adpt_hppe_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 = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(ref_clock); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_reference_clock_get) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_reference_clock_get(dev_id, phy_id, ref_clock); + + return rv; +} + +sw_error_t +adpt_hppe_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 = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_rx_timestamp_mode_set) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_rx_timestamp_mode_set(dev_id, phy_id, ts_mode); + + return rv; +} + +sw_error_t +adpt_hppe_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 = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(ts_mode); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_rx_timestamp_mode_get) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_rx_timestamp_mode_get(dev_id, phy_id, ts_mode); + + return rv; +} + +sw_error_t +adpt_hppe_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 = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(time); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_timestamp_get) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_timestamp_get(dev_id, phy_id, direction, pkt_info, time); + + return rv; +} + +sw_error_t +adpt_hppe_ptp_pkt_timestamp_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_time_t *time) +{ + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(time); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_pkt_timestamp_set) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_pkt_timestamp_set(dev_id, phy_id, time); + + return rv; +} + +sw_error_t +adpt_hppe_ptp_pkt_timestamp_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_time_t *time) +{ + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(time); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_pkt_timestamp_get) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_pkt_timestamp_get(dev_id, phy_id, time); + + return rv; +} + +sw_error_t +adpt_hppe_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 = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(gm_mode); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_grandmaster_mode_set) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_grandmaster_mode_set(dev_id, phy_id, gm_mode); + + return rv; +} + +sw_error_t +adpt_hppe_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 = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(gm_mode); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_grandmaster_mode_get) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_grandmaster_mode_get(dev_id, phy_id, gm_mode); + + return rv; +} + +sw_error_t +adpt_hppe_ptp_rtc_time_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_time_t *time) +{ + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(time); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_rtc_time_get) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_rtc_time_get(dev_id, phy_id, time); + + return rv; +} + +sw_error_t +adpt_hppe_ptp_rtc_time_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_time_t *time) +{ + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(time); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_rtc_time_set) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_rtc_time_set(dev_id, phy_id, time); + + return rv; +} + +sw_error_t +adpt_hppe_ptp_rtc_time_clear(a_uint32_t dev_id, a_uint32_t port_id) +{ + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_rtc_time_clear) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_rtc_time_clear(dev_id, phy_id); + + return rv; +} + +sw_error_t +adpt_hppe_ptp_rtc_adjtime_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_time_t *time) +{ + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(time); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_rtc_adjtime_set) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_rtc_adjtime_set(dev_id, phy_id, time); + + return rv; +} + +sw_error_t +adpt_hppe_ptp_rtc_adjfreq_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_time_t *time) +{ + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(time); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_rtc_adjfreq_set) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_rtc_adjfreq_set(dev_id, phy_id, time); + + return rv; +} + +sw_error_t +adpt_hppe_ptp_rtc_adjfreq_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_time_t *time) +{ + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(time); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_rtc_adjfreq_get) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_rtc_adjfreq_get(dev_id, phy_id, time); + + return rv; +} + +sw_error_t +adpt_hppe_ptp_link_delay_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_time_t *time) +{ + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(time); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_link_delay_set) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_link_delay_set(dev_id, phy_id, time); + + return rv; +} + +sw_error_t +adpt_hppe_ptp_link_delay_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_time_t *time) +{ + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(time); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_link_delay_get) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_link_delay_get(dev_id, phy_id, time); + + return rv; +} + +sw_error_t +adpt_hppe_ptp_security_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_security_t *sec) +{ + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(sec); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_security_set) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_security_set(dev_id, phy_id, sec); + + return rv; +} + +sw_error_t +adpt_hppe_ptp_security_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_security_t *sec) +{ + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(sec); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_security_get) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_security_get(dev_id, phy_id, sec); + + return rv; +} + +sw_error_t +adpt_hppe_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 = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(sig_control); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_pps_signal_control_set) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_pps_signal_control_set(dev_id, phy_id, sig_control); + + return rv; +} + +sw_error_t +adpt_hppe_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 = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(sig_control); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_pps_signal_control_get) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_pps_signal_control_get(dev_id, phy_id, sig_control); + + return rv; +} + +sw_error_t +adpt_hppe_ptp_rx_crc_recalc_enable(a_uint32_t dev_id, a_uint32_t port_id, + a_bool_t status) +{ + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_rx_crc_recalc_enable) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_rx_crc_recalc_enable(dev_id, phy_id, status); + + return rv; +} + +sw_error_t +adpt_hppe_ptp_rx_crc_recalc_status_get(a_uint32_t dev_id, + a_uint32_t port_id, a_bool_t *status) +{ + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(status); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_rx_crc_recalc_status_get) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_rx_crc_recalc_status_get(dev_id, phy_id, status); + + return rv; +} + +sw_error_t +adpt_hppe_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 = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(asym_cf); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_asym_correction_set) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_asym_correction_set(dev_id, phy_id, asym_cf); + + return rv; +} + +sw_error_t +adpt_hppe_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 = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(asym_cf); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_asym_correction_get) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_asym_correction_get(dev_id, phy_id, asym_cf); + + return rv; +} + +sw_error_t +adpt_hppe_ptp_output_waveform_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_output_waveform_t *waveform) +{ + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(waveform); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_output_waveform_set) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_output_waveform_set(dev_id, phy_id, waveform); + + return rv; +} + +sw_error_t +adpt_hppe_ptp_output_waveform_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_output_waveform_t *waveform) +{ + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(waveform); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_output_waveform_get) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_output_waveform_get(dev_id, phy_id, waveform); + + return rv; +} + +sw_error_t +adpt_hppe_ptp_rtc_time_snapshot_enable(a_uint32_t dev_id, + a_uint32_t port_id, a_bool_t status) +{ + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_rtc_time_snapshot_enable) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_rtc_time_snapshot_enable(dev_id, phy_id, status); + + return rv; +} + +sw_error_t +adpt_hppe_ptp_rtc_time_snapshot_status_get(a_uint32_t dev_id, + a_uint32_t port_id, a_bool_t *status) +{ + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(status); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_rtc_time_snapshot_status_get) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_rtc_time_snapshot_status_get(dev_id, phy_id, status); + + return rv; +} + +sw_error_t +adpt_hppe_ptp_increment_sync_from_clock_enable(a_uint32_t dev_id, + a_uint32_t port_id, a_bool_t status) +{ + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_increment_sync_from_clock_enable) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_increment_sync_from_clock_enable(dev_id, phy_id, status); + + return rv; +} + +sw_error_t +adpt_hppe_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 = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(status); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_increment_sync_from_clock_status_get) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_increment_sync_from_clock_status_get(dev_id, + phy_id, status); + + return rv; +} + +sw_error_t +adpt_hppe_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 = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(tod_uart); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_tod_uart_set) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_tod_uart_set(dev_id, phy_id, tod_uart); + + return rv; +} + +sw_error_t +adpt_hppe_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 = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(tod_uart); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_tod_uart_get) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_tod_uart_get(dev_id, phy_id, tod_uart); + + return rv; +} + +sw_error_t +adpt_hppe_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 = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(ts_engine); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_enhanced_timestamp_engine_set) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_enhanced_timestamp_engine_set(dev_id, + phy_id, direction, ts_engine); + + return rv; +} + +sw_error_t +adpt_hppe_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 = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(ts_engine); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_enhanced_timestamp_engine_get) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_enhanced_timestamp_engine_get(dev_id, + phy_id, direction, ts_engine); + + return rv; +} + +sw_error_t +adpt_hppe_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 = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(triger); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_trigger_set) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_trigger_set(dev_id, phy_id, trigger_id, triger); + + return rv; +} + +sw_error_t +adpt_hppe_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 = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(triger); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_trigger_get) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_trigger_get(dev_id, phy_id, trigger_id, triger); + + return rv; +} + +sw_error_t +adpt_hppe_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 = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(capture); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_capture_set) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_capture_set(dev_id, phy_id, capture_id, capture); + + return rv; +} + +sw_error_t +adpt_hppe_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 = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(capture); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_capture_get) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_capture_get(dev_id, phy_id, capture_id, capture); + + return rv; +} + +sw_error_t +adpt_hppe_ptp_interrupt_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_interrupt_t *interrupt) +{ + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(interrupt); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_interrupt_set) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_interrupt_set(dev_id, phy_id, interrupt); + + return rv; +} + +sw_error_t +adpt_hppe_ptp_interrupt_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_interrupt_t *interrupt) +{ + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(interrupt); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_ptp_ops.phy_ptp_interrupt_get) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_ptp_ops.phy_ptp_interrupt_get(dev_id, phy_id, interrupt); + + return rv; +} + +sw_error_t adpt_hppe_ptp_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + { + return SW_FAIL; + } + + p_adpt_api->adpt_ptp_config_set = adpt_hppe_ptp_config_set; + p_adpt_api->adpt_ptp_config_get = adpt_hppe_ptp_config_get; + p_adpt_api->adpt_ptp_reference_clock_set = adpt_hppe_ptp_reference_clock_set; + p_adpt_api->adpt_ptp_reference_clock_get = adpt_hppe_ptp_reference_clock_get; + p_adpt_api->adpt_ptp_rx_timestamp_mode_set = adpt_hppe_ptp_rx_timestamp_mode_set; + p_adpt_api->adpt_ptp_rx_timestamp_mode_get = adpt_hppe_ptp_rx_timestamp_mode_get; + p_adpt_api->adpt_ptp_timestamp_get = adpt_hppe_ptp_timestamp_get; + p_adpt_api->adpt_ptp_pkt_timestamp_set = adpt_hppe_ptp_pkt_timestamp_set; + p_adpt_api->adpt_ptp_pkt_timestamp_get = adpt_hppe_ptp_pkt_timestamp_get; + p_adpt_api->adpt_ptp_grandmaster_mode_set = adpt_hppe_ptp_grandmaster_mode_set; + p_adpt_api->adpt_ptp_grandmaster_mode_get = adpt_hppe_ptp_grandmaster_mode_get; + p_adpt_api->adpt_ptp_rtc_time_set = adpt_hppe_ptp_rtc_time_set; + p_adpt_api->adpt_ptp_rtc_time_get = adpt_hppe_ptp_rtc_time_get; + p_adpt_api->adpt_ptp_rtc_time_clear = adpt_hppe_ptp_rtc_time_clear; + p_adpt_api->adpt_ptp_rtc_adjtime_set = adpt_hppe_ptp_rtc_adjtime_set; + p_adpt_api->adpt_ptp_rtc_adjfreq_set = adpt_hppe_ptp_rtc_adjfreq_set; + p_adpt_api->adpt_ptp_rtc_adjfreq_get = adpt_hppe_ptp_rtc_adjfreq_get; + p_adpt_api->adpt_ptp_link_delay_set = adpt_hppe_ptp_link_delay_set; + p_adpt_api->adpt_ptp_link_delay_get = adpt_hppe_ptp_link_delay_get; + p_adpt_api->adpt_ptp_security_set = adpt_hppe_ptp_security_set; + p_adpt_api->adpt_ptp_security_get = adpt_hppe_ptp_security_get; + p_adpt_api->adpt_ptp_pps_signal_control_set = adpt_hppe_ptp_pps_signal_control_set; + p_adpt_api->adpt_ptp_pps_signal_control_get = adpt_hppe_ptp_pps_signal_control_get; + p_adpt_api->adpt_ptp_rx_crc_recalc_enable = adpt_hppe_ptp_rx_crc_recalc_enable; + p_adpt_api->adpt_ptp_rx_crc_recalc_status_get = adpt_hppe_ptp_rx_crc_recalc_status_get; + p_adpt_api->adpt_ptp_asym_correction_set = adpt_hppe_ptp_asym_correction_set; + p_adpt_api->adpt_ptp_asym_correction_get = adpt_hppe_ptp_asym_correction_get; + p_adpt_api->adpt_ptp_output_waveform_set = adpt_hppe_ptp_output_waveform_set; + p_adpt_api->adpt_ptp_output_waveform_get = adpt_hppe_ptp_output_waveform_get; + p_adpt_api->adpt_ptp_rtc_time_snapshot_enable = adpt_hppe_ptp_rtc_time_snapshot_enable; + p_adpt_api->adpt_ptp_tod_uart_set = adpt_hppe_ptp_tod_uart_set; + p_adpt_api->adpt_ptp_tod_uart_get = adpt_hppe_ptp_tod_uart_get; + p_adpt_api->adpt_ptp_trigger_set = adpt_hppe_ptp_trigger_set; + p_adpt_api->adpt_ptp_trigger_get = adpt_hppe_ptp_trigger_get; + p_adpt_api->adpt_ptp_capture_set = adpt_hppe_ptp_capture_set; + p_adpt_api->adpt_ptp_capture_get = adpt_hppe_ptp_capture_get; + p_adpt_api->adpt_ptp_interrupt_set = adpt_hppe_ptp_interrupt_set; + p_adpt_api->adpt_ptp_interrupt_get = adpt_hppe_ptp_interrupt_get; + p_adpt_api->adpt_ptp_rtc_time_snapshot_status_get = + adpt_hppe_ptp_rtc_time_snapshot_status_get; + p_adpt_api->adpt_ptp_increment_sync_from_clock_enable = + adpt_hppe_ptp_increment_sync_from_clock_enable; + p_adpt_api->adpt_ptp_increment_sync_from_clock_status_get = + adpt_hppe_ptp_increment_sync_from_clock_status_get; + p_adpt_api->adpt_ptp_enhanced_timestamp_engine_set = + adpt_hppe_ptp_enhanced_timestamp_engine_set; + p_adpt_api->adpt_ptp_enhanced_timestamp_engine_get = + adpt_hppe_ptp_enhanced_timestamp_engine_get; + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_qm.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_qm.c new file mode 100755 index 000000000..9c33c1946 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_qm.c @@ -0,0 +1,1413 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "fal_qm.h" +#include "hppe_reg_access.h" +#include "hppe_qm_reg.h" +#include "hppe_qm.h" +#include "hppe_qos_reg.h" +#include "hppe_qos.h" +#include "hppe_portvlan_reg.h" +#include "hppe_portvlan.h" +#include "hppe_portctrl_reg.h" +#include "hppe_portctrl.h" +#include "adpt.h" +#include "adpt_hppe.h" +#if defined(CPPE) +#include "adpt_cppe_qm.h" +#endif + +#define SERVICE_CODE_QUEUE_OFFSET 2048 +#define CPU_CODE_QUEUE_OFFSET 1024 +#define VP_PORT_QUEUE_OFFSET 0 + +#define UCAST_QUEUE_ID_MAX 256 +#define ALL_QUEUE_ID_MAX 300 +#define MCAST_QUEUE_PORT7_START 296 +#define MCAST_QUEUE_PORT6_START 292 +#define MCAST_QUEUE_PORT5_START 288 +#define MCAST_QUEUE_PORT4_START 284 +#define MCAST_QUEUE_PORT3_START 280 +#define MCAST_QUEUE_PORT2_START 276 +#define MCAST_QUEUE_PORT1_START 272 +#define MCAST_QUEUE_PORT0_START 256 +#define MCAST_QUEUE_OFFSET (3*0x10) +#define UCAST_QUEUE_ITEMS 6 +#define MCAST_QUEUE_ITEMS 3 +#define DROP_INC 0x10 + +#ifndef IN_QM_MINI +sw_error_t +adpt_hppe_ucast_hash_map_set( + a_uint32_t dev_id, + a_uint8_t profile, + a_uint8_t rss_hash, + a_int8_t queue_hash) +{ + union ucast_hash_map_tbl_u ucast_hash_map_tbl; + a_uint32_t index = 0; + + memset(&ucast_hash_map_tbl, 0, sizeof(ucast_hash_map_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + + index = profile << 8 | rss_hash; + ucast_hash_map_tbl.bf.hash = queue_hash; + + return hppe_ucast_hash_map_tbl_set(dev_id, index, &ucast_hash_map_tbl); +} + +sw_error_t +adpt_hppe_ac_dynamic_threshold_get( + a_uint32_t dev_id, + a_uint32_t queue_id, + fal_ac_dynamic_threshold_t *cfg) +{ + sw_error_t rv = SW_OK; + union ac_uni_queue_cfg_tbl_u ac_uni_queue_cfg_tbl; + + memset(&ac_uni_queue_cfg_tbl, 0, sizeof(ac_uni_queue_cfg_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cfg); + + rv = hppe_ac_uni_queue_cfg_tbl_get(dev_id, queue_id, &ac_uni_queue_cfg_tbl); + if( rv != SW_OK ) + return rv; + + cfg->wred_enable = ac_uni_queue_cfg_tbl.bf.ac_cfg_wred_en; + cfg->color_enable = ac_uni_queue_cfg_tbl.bf.ac_cfg_color_aware; + cfg->shared_weight = ac_uni_queue_cfg_tbl.bf.ac_cfg_shared_weight; + cfg->green_min_off = ac_uni_queue_cfg_tbl.bf.ac_cfg_gap_grn_grn_min; + cfg->yel_max_off = ac_uni_queue_cfg_tbl.bf.ac_cfg_gap_grn_yel_max; + cfg->yel_min_off = ac_uni_queue_cfg_tbl.bf.ac_cfg_gap_grn_yel_min_0 | \ + ac_uni_queue_cfg_tbl.bf.ac_cfg_gap_grn_yel_min_1 << 10; + cfg->red_max_off = ac_uni_queue_cfg_tbl.bf.ac_cfg_gap_grn_red_max; + cfg->red_min_off = ac_uni_queue_cfg_tbl.bf.ac_cfg_gap_grn_red_min; + cfg->green_resume_off = ac_uni_queue_cfg_tbl.bf.ac_cfg_grn_resume_offset; + cfg->yel_resume_off = ac_uni_queue_cfg_tbl.bf.ac_cfg_yel_resume_offset; + cfg->red_resume_off = ac_uni_queue_cfg_tbl.bf.ac_cfg_red_resume_offset_0 | \ + ac_uni_queue_cfg_tbl.bf.ac_cfg_red_resume_offset_1 << 9; + cfg->ceiling = ac_uni_queue_cfg_tbl.bf.ac_cfg_shared_ceiling; + + return SW_OK; +} + +sw_error_t +adpt_hppe_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 = SW_OK; + union ucast_queue_map_tbl_u ucast_queue_map_tbl; + a_uint32_t index = 0; + + memset(&ucast_queue_map_tbl, 0, sizeof(ucast_queue_map_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(queue_dest); + ADPT_NULL_POINT_CHECK(queue_base); + ADPT_NULL_POINT_CHECK(profile); + + if (queue_dest ->service_code_en) { + index = SERVICE_CODE_QUEUE_OFFSET + (queue_dest->src_profile << 8) \ + + queue_dest->service_code; + } else if (queue_dest ->cpu_code_en) { + index = CPU_CODE_QUEUE_OFFSET + (queue_dest->src_profile << 8) \ + + queue_dest->cpu_code; + } else { + index = VP_PORT_QUEUE_OFFSET + (queue_dest->src_profile << 8) \ + + queue_dest->dst_port; + } + + rv = hppe_ucast_queue_map_tbl_get(dev_id, index, &ucast_queue_map_tbl); + if (rv) + return rv; + *queue_base = ucast_queue_map_tbl.bf.queue_id; + *profile = ucast_queue_map_tbl.bf.profile_id; + + return SW_OK; +} + +sw_error_t +adpt_hppe_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 = SW_OK; + union mcast_priority_map0_u mcast_priority_map0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(queue_class); + + + if (port == 0){ + rv = hppe_mcast_priority_map0_get(dev_id, priority, &mcast_priority_map0); + } else if (port == 1) { + rv = hppe_mcast_priority_map1_get(dev_id, priority, + (union mcast_priority_map1_u *)&mcast_priority_map0); + } else if (port == 2) { + rv = hppe_mcast_priority_map2_get(dev_id, priority, + (union mcast_priority_map2_u *)&mcast_priority_map0); + } else if (port == 3) { + rv = hppe_mcast_priority_map3_get(dev_id, priority, + (union mcast_priority_map3_u *)&mcast_priority_map0); + } else if (port == 4) { + rv = hppe_mcast_priority_map4_get(dev_id, priority, + (union mcast_priority_map4_u *)&mcast_priority_map0); + } else if (port == 5) { + rv = hppe_mcast_priority_map5_get(dev_id, priority, + (union mcast_priority_map5_u *)&mcast_priority_map0); + } else if (port == 6) { + rv = hppe_mcast_priority_map6_get(dev_id, priority, + (union mcast_priority_map6_u *)&mcast_priority_map0); + } else if (port == 7) { + rv = hppe_mcast_priority_map7_get(dev_id, priority, + (union mcast_priority_map7_u *)&mcast_priority_map0); + } + + if( rv != SW_OK ) + return rv; + + *queue_class = mcast_priority_map0.bf.class; + return SW_OK; +} +#endif + +sw_error_t +adpt_hppe_ac_dynamic_threshold_set( + a_uint32_t dev_id, + a_uint32_t queue_id, + fal_ac_dynamic_threshold_t *cfg) +{ + sw_error_t rv = SW_OK; + union ac_uni_queue_cfg_tbl_u ac_uni_queue_cfg_tbl; + + memset(&ac_uni_queue_cfg_tbl, 0, sizeof(ac_uni_queue_cfg_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cfg); + + rv = hppe_ac_uni_queue_cfg_tbl_get(dev_id, queue_id, &ac_uni_queue_cfg_tbl); + if( rv != SW_OK ) + return rv; + + ac_uni_queue_cfg_tbl.bf.ac_cfg_wred_en = cfg->wred_enable; + ac_uni_queue_cfg_tbl.bf.ac_cfg_color_aware = cfg->color_enable; + ac_uni_queue_cfg_tbl.bf.ac_cfg_shared_dynamic = 1; + ac_uni_queue_cfg_tbl.bf.ac_cfg_gap_grn_grn_min = cfg->green_min_off; + ac_uni_queue_cfg_tbl.bf.ac_cfg_gap_grn_yel_max = cfg->yel_max_off; + ac_uni_queue_cfg_tbl.bf.ac_cfg_gap_grn_yel_min_0 = cfg->yel_min_off; + ac_uni_queue_cfg_tbl.bf.ac_cfg_gap_grn_yel_min_1 = cfg->yel_min_off >> 20; + ac_uni_queue_cfg_tbl.bf.ac_cfg_gap_grn_red_max = cfg->red_max_off; + ac_uni_queue_cfg_tbl.bf.ac_cfg_gap_grn_red_min = cfg->red_min_off; + ac_uni_queue_cfg_tbl.bf.ac_cfg_grn_resume_offset = cfg->green_resume_off; + ac_uni_queue_cfg_tbl.bf.ac_cfg_yel_resume_offset = cfg->yel_resume_off; + ac_uni_queue_cfg_tbl.bf.ac_cfg_red_resume_offset_0 = cfg->red_resume_off; + ac_uni_queue_cfg_tbl.bf.ac_cfg_red_resume_offset_1 = cfg->red_resume_off >> 9; + ac_uni_queue_cfg_tbl.bf.ac_cfg_shared_weight = cfg->shared_weight; + ac_uni_queue_cfg_tbl.bf.ac_cfg_shared_ceiling = cfg->ceiling; + + return hppe_ac_uni_queue_cfg_tbl_set(dev_id, queue_id, &ac_uni_queue_cfg_tbl); +} + +sw_error_t +adpt_hppe_ac_prealloc_buffer_set( + a_uint32_t dev_id, + fal_ac_obj_t *obj, + a_uint16_t num) +{ + ADPT_DEV_ID_CHECK(dev_id); + + if (obj->type == FAL_AC_GROUP) { + union ac_grp_cfg_tbl_u ac_grp_cfg_tbl; + + memset(&ac_grp_cfg_tbl, 0, sizeof(ac_grp_cfg_tbl)); + hppe_ac_grp_cfg_tbl_get(dev_id, obj->obj_id, &ac_grp_cfg_tbl); + + ac_grp_cfg_tbl.bf.ac_grp_palloc_limit = num; + + return hppe_ac_grp_cfg_tbl_set(dev_id, obj->obj_id, &ac_grp_cfg_tbl); + + } else if (obj->type == FAL_AC_QUEUE) { + if (obj->obj_id < UCAST_QUEUE_ID_MAX) { + union ac_uni_queue_cfg_tbl_u ac_uni_queue_cfg_tbl; + hppe_ac_uni_queue_cfg_tbl_get(dev_id, + obj->obj_id, + &ac_uni_queue_cfg_tbl); + ac_uni_queue_cfg_tbl.bf.ac_cfg_pre_alloc_limit = num; + return hppe_ac_uni_queue_cfg_tbl_set(dev_id, + obj->obj_id, + &ac_uni_queue_cfg_tbl);; + + } else { + union ac_mul_queue_cfg_tbl_u ac_mul_queue_cfg_tbl; + hppe_ac_mul_queue_cfg_tbl_get(dev_id, + obj->obj_id - UCAST_QUEUE_ID_MAX, + &ac_mul_queue_cfg_tbl); + ac_mul_queue_cfg_tbl.bf.ac_cfg_pre_alloc_limit = num; + return hppe_ac_mul_queue_cfg_tbl_set(dev_id, + obj->obj_id -UCAST_QUEUE_ID_MAX, + &ac_mul_queue_cfg_tbl); + } + } else + return SW_FAIL; +} +#ifndef IN_QM_MINI +sw_error_t +adpt_hppe_ucast_default_hash_get( + a_uint32_t dev_id, + a_uint8_t *hash_value) +{ + sw_error_t rv = SW_OK; + union ucast_default_hash_u ucast_default_hash; + + memset(&ucast_default_hash, 0, sizeof(ucast_default_hash)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(hash_value); + + rv = hppe_ucast_default_hash_get(dev_id, &ucast_default_hash); + if( rv != SW_OK ) + return rv; + + *hash_value = ucast_default_hash.bf.hash; + return SW_OK; +} + +sw_error_t +adpt_hppe_ucast_default_hash_set( + a_uint32_t dev_id, + a_uint8_t hash_value) +{ + sw_error_t rv = SW_OK; + union ucast_default_hash_u ucast_default_hash; + + memset(&ucast_default_hash, 0, sizeof(ucast_default_hash)); + ADPT_DEV_ID_CHECK(dev_id); + + ucast_default_hash.bf.hash = hash_value; + rv = hppe_ucast_default_hash_set(dev_id, &ucast_default_hash); + + return rv; +} + +sw_error_t +adpt_hppe_ac_queue_group_get( + a_uint32_t dev_id, + a_uint32_t queue_id, + a_uint8_t *group_id) +{ + sw_error_t rv = SW_OK; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(group_id); + + + if (queue_id < UCAST_QUEUE_ID_MAX) { + union ac_uni_queue_cfg_tbl_u ac_uni_queue_cfg_tbl; + rv = hppe_ac_uni_queue_cfg_tbl_get(dev_id, + queue_id, + &ac_uni_queue_cfg_tbl); + *group_id = ac_uni_queue_cfg_tbl.bf.ac_cfg_grp_id; + + } else { + union ac_mul_queue_cfg_tbl_u ac_mul_queue_cfg_tbl; + rv = hppe_ac_mul_queue_cfg_tbl_get(dev_id, + queue_id - UCAST_QUEUE_ID_MAX, + &ac_mul_queue_cfg_tbl); + *group_id = ac_mul_queue_cfg_tbl.bf.ac_cfg_grp_id; + } + + return rv; +} + +sw_error_t +adpt_hppe_ac_ctrl_get( + a_uint32_t dev_id, + fal_ac_obj_t *obj, + fal_ac_ctrl_t *cfg) +{ + sw_error_t rv = SW_OK; + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cfg); + + if (obj->type == FAL_AC_GROUP) { + union ac_grp_cfg_tbl_u ac_grp_cfg_tbl; + + memset(&ac_grp_cfg_tbl, 0, sizeof(ac_grp_cfg_tbl)); + rv = hppe_ac_grp_cfg_tbl_get(dev_id, obj->obj_id, &ac_grp_cfg_tbl); + + cfg->ac_en = ac_grp_cfg_tbl.bf.ac_cfg_ac_en; + cfg->ac_fc_en = ac_grp_cfg_tbl.bf.ac_cfg_force_ac_en; + } else if (obj->type == FAL_AC_QUEUE) { + if (obj->obj_id < UCAST_QUEUE_ID_MAX) { + union ac_uni_queue_cfg_tbl_u ac_uni_queue_cfg_tbl; + rv = hppe_ac_uni_queue_cfg_tbl_get(dev_id, + obj->obj_id, + &ac_uni_queue_cfg_tbl); + cfg->ac_en = ac_uni_queue_cfg_tbl.bf.ac_cfg_ac_en; + cfg->ac_fc_en = ac_uni_queue_cfg_tbl.bf.ac_cfg_force_ac_en; + + } else { + union ac_mul_queue_cfg_tbl_u ac_mul_queue_cfg_tbl; + rv = hppe_ac_mul_queue_cfg_tbl_get(dev_id, + obj->obj_id - UCAST_QUEUE_ID_MAX, + &ac_mul_queue_cfg_tbl); + cfg->ac_en = ac_mul_queue_cfg_tbl.bf.ac_cfg_ac_en; + cfg->ac_fc_en = ac_mul_queue_cfg_tbl.bf.ac_cfg_force_ac_en; + } + } else + return SW_FAIL; + + return rv; +} + +sw_error_t +adpt_hppe_ac_prealloc_buffer_get( + a_uint32_t dev_id, + fal_ac_obj_t *obj, + a_uint16_t *num) +{ + sw_error_t rv = SW_OK; + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(num); + + if (obj->type == FAL_AC_GROUP) { + union ac_grp_cfg_tbl_u ac_grp_cfg_tbl; + + rv = hppe_ac_grp_cfg_tbl_get(dev_id, obj->obj_id, &ac_grp_cfg_tbl); + + *num = ac_grp_cfg_tbl.bf.ac_grp_palloc_limit; + + return rv; + + } else if (obj->type == FAL_AC_QUEUE) { + if (obj->obj_id < UCAST_QUEUE_ID_MAX) { + union ac_uni_queue_cfg_tbl_u ac_uni_queue_cfg_tbl; + rv = hppe_ac_uni_queue_cfg_tbl_get(dev_id, + obj->obj_id, + &ac_uni_queue_cfg_tbl); + *num = ac_uni_queue_cfg_tbl.bf.ac_cfg_pre_alloc_limit; + } else { + union ac_mul_queue_cfg_tbl_u ac_mul_queue_cfg_tbl; + rv = hppe_ac_mul_queue_cfg_tbl_get(dev_id, + obj->obj_id - UCAST_QUEUE_ID_MAX, + &ac_mul_queue_cfg_tbl); + *num = ac_mul_queue_cfg_tbl.bf.ac_cfg_pre_alloc_limit; + } + return rv; + } else + return SW_FAIL; +} + +sw_error_t +adpt_hppe_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 = SW_OK; + union mcast_priority_map0_u mcast_priority_map0; + + ADPT_DEV_ID_CHECK(dev_id); + + mcast_priority_map0.bf.class = queue_class; + + if (port == 0){ + rv = hppe_mcast_priority_map0_set(dev_id, priority, &mcast_priority_map0); + } else if (port == 1) { + rv = hppe_mcast_priority_map1_set(dev_id, priority, + (union mcast_priority_map1_u *)&mcast_priority_map0); + } else if (port == 2) { + rv = hppe_mcast_priority_map2_set(dev_id, priority, + (union mcast_priority_map2_u *)&mcast_priority_map0); + } else if (port == 3) { + rv = hppe_mcast_priority_map3_set(dev_id, priority, + (union mcast_priority_map3_u *)&mcast_priority_map0); + } else if (port == 4) { + rv = hppe_mcast_priority_map4_set(dev_id, priority, + (union mcast_priority_map4_u *)&mcast_priority_map0); + } else if (port == 5) { + rv = hppe_mcast_priority_map5_set(dev_id, priority, + (union mcast_priority_map5_u *)&mcast_priority_map0); + } else if (port == 6) { + rv = hppe_mcast_priority_map6_set(dev_id, priority, + (union mcast_priority_map6_u *)&mcast_priority_map0); + } else if (port == 7) { + rv = hppe_mcast_priority_map7_set(dev_id, priority, + (union mcast_priority_map7_u *)&mcast_priority_map0); + } + + return rv; +} + +sw_error_t +adpt_hppe_ucast_hash_map_get( + a_uint32_t dev_id, + a_uint8_t profile, + a_uint8_t rss_hash, + a_int8_t *queue_hash) +{ + union ucast_hash_map_tbl_u ucast_hash_map_tbl; + sw_error_t rv = SW_OK; + a_uint32_t index = 0; + + memset(&ucast_hash_map_tbl, 0, sizeof(ucast_hash_map_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + + index = profile << 8 | rss_hash; + + rv = hppe_ucast_hash_map_tbl_get(dev_id, index, &ucast_hash_map_tbl); + if (rv) + return rv; + + *queue_hash = ucast_hash_map_tbl.bf.hash; + return rv; +} +#endif + +sw_error_t +adpt_hppe_ac_static_threshold_set( + a_uint32_t dev_id, + fal_ac_obj_t *obj, + fal_ac_static_threshold_t *cfg) +{ + ADPT_DEV_ID_CHECK(dev_id); + + if (obj->type == FAL_AC_GROUP) { + union ac_grp_cfg_tbl_u ac_grp_cfg_tbl; + + hppe_ac_grp_cfg_tbl_get(dev_id, obj->obj_id, &ac_grp_cfg_tbl); + + ac_grp_cfg_tbl.bf.ac_cfg_color_aware = cfg->color_enable; + ac_grp_cfg_tbl.bf.ac_grp_dp_thrd_0 = cfg->green_max; + ac_grp_cfg_tbl.bf.ac_grp_dp_thrd_1 = cfg->green_max >> 7; + ac_grp_cfg_tbl.bf.ac_grp_gap_grn_yel = cfg->yel_max_off; + ac_grp_cfg_tbl.bf.ac_grp_gap_grn_red = cfg->red_max_off; + ac_grp_cfg_tbl.bf.ac_grp_grn_resume_offset = cfg->green_resume_off; + ac_grp_cfg_tbl.bf.ac_grp_yel_resume_offset_0 = cfg->yel_resume_off; + ac_grp_cfg_tbl.bf.ac_grp_yel_resume_offset_1 = cfg->yel_resume_off >> 6; + ac_grp_cfg_tbl.bf.ac_grp_red_resume_offset = cfg->red_resume_off; + + return hppe_ac_grp_cfg_tbl_set(dev_id, obj->obj_id, &ac_grp_cfg_tbl); + + } else if (obj->type == FAL_AC_QUEUE) { + if (obj->obj_id < UCAST_QUEUE_ID_MAX) { + union ac_uni_queue_cfg_tbl_u ac_uni_queue_cfg_tbl; + hppe_ac_uni_queue_cfg_tbl_get(dev_id, + obj->obj_id, + &ac_uni_queue_cfg_tbl); + ac_uni_queue_cfg_tbl.bf.ac_cfg_wred_en = cfg->wred_enable; + ac_uni_queue_cfg_tbl.bf.ac_cfg_color_aware = cfg->color_enable; + ac_uni_queue_cfg_tbl.bf.ac_cfg_shared_dynamic = 0; + ac_uni_queue_cfg_tbl.bf.ac_cfg_gap_grn_grn_min = cfg->green_min_off; + ac_uni_queue_cfg_tbl.bf.ac_cfg_gap_grn_yel_max = cfg->yel_max_off; + ac_uni_queue_cfg_tbl.bf.ac_cfg_gap_grn_yel_min_0 = cfg->yel_min_off; + ac_uni_queue_cfg_tbl.bf.ac_cfg_gap_grn_yel_min_1 = cfg->yel_min_off >> 10; + ac_uni_queue_cfg_tbl.bf.ac_cfg_gap_grn_red_max = cfg->red_max_off; + ac_uni_queue_cfg_tbl.bf.ac_cfg_gap_grn_red_min = cfg->red_min_off; + ac_uni_queue_cfg_tbl.bf.ac_cfg_grn_resume_offset = cfg->green_resume_off; + ac_uni_queue_cfg_tbl.bf.ac_cfg_yel_resume_offset = cfg->yel_resume_off; + ac_uni_queue_cfg_tbl.bf.ac_cfg_red_resume_offset_0 = cfg->red_resume_off; + ac_uni_queue_cfg_tbl.bf.ac_cfg_red_resume_offset_1 = cfg->red_resume_off >> 9; + ac_uni_queue_cfg_tbl.bf.ac_cfg_shared_ceiling = cfg->green_max; + return hppe_ac_uni_queue_cfg_tbl_set(dev_id, + obj->obj_id, + &ac_uni_queue_cfg_tbl);; + + } else { + union ac_mul_queue_cfg_tbl_u ac_mul_queue_cfg_tbl; + hppe_ac_mul_queue_cfg_tbl_get(dev_id, + obj->obj_id - UCAST_QUEUE_ID_MAX, + &ac_mul_queue_cfg_tbl); + ac_mul_queue_cfg_tbl.bf.ac_cfg_color_aware = cfg->color_enable; + ac_mul_queue_cfg_tbl.bf.ac_cfg_grn_resume_offset = cfg->green_resume_off; + ac_mul_queue_cfg_tbl.bf.ac_cfg_yel_resume_offset_0 = cfg->yel_resume_off; + ac_mul_queue_cfg_tbl.bf.ac_cfg_yel_resume_offset_1 = cfg->yel_resume_off >> 4; + ac_mul_queue_cfg_tbl.bf.ac_cfg_red_resume_offset = cfg->red_resume_off; + ac_mul_queue_cfg_tbl.bf.ac_cfg_gap_grn_red = cfg->red_max_off; + ac_mul_queue_cfg_tbl.bf.ac_cfg_gap_grn_yel_0 = cfg->yel_max_off; + ac_mul_queue_cfg_tbl.bf.ac_cfg_gap_grn_yel_1 = cfg->yel_max_off >> 5; + ac_mul_queue_cfg_tbl.bf.ac_cfg_shared_ceiling = cfg->green_max; + return hppe_ac_mul_queue_cfg_tbl_set(dev_id, + obj->obj_id -UCAST_QUEUE_ID_MAX, + &ac_mul_queue_cfg_tbl); + } + } else + return SW_FAIL; +} + +sw_error_t +adpt_hppe_ac_queue_group_set( + a_uint32_t dev_id, + a_uint32_t queue_id, + a_uint8_t group_id) +{ + sw_error_t rv = SW_OK; + + ADPT_DEV_ID_CHECK(dev_id); + + + if (queue_id < UCAST_QUEUE_ID_MAX) { + union ac_uni_queue_cfg_tbl_u ac_uni_queue_cfg_tbl; + hppe_ac_uni_queue_cfg_tbl_get(dev_id, + queue_id, + &ac_uni_queue_cfg_tbl); + ac_uni_queue_cfg_tbl.bf.ac_cfg_grp_id = group_id; + return hppe_ac_uni_queue_cfg_tbl_set(dev_id, + queue_id, + &ac_uni_queue_cfg_tbl); + + } else { + union ac_mul_queue_cfg_tbl_u ac_mul_queue_cfg_tbl; + hppe_ac_mul_queue_cfg_tbl_get(dev_id, + queue_id - UCAST_QUEUE_ID_MAX, + &ac_mul_queue_cfg_tbl); + ac_mul_queue_cfg_tbl.bf.ac_cfg_grp_id = group_id; + return hppe_ac_mul_queue_cfg_tbl_set(dev_id, + queue_id - UCAST_QUEUE_ID_MAX, + &ac_mul_queue_cfg_tbl); + } + + return rv; +} + +#ifndef IN_QM_MINI +sw_error_t +adpt_hppe_ac_group_buffer_get( + a_uint32_t dev_id, + a_uint8_t group_id, + fal_ac_group_buffer_t *cfg) +{ + sw_error_t rv = SW_OK; + union ac_grp_cfg_tbl_u ac_grp_cfg_tbl; + + memset(&ac_grp_cfg_tbl, 0, sizeof(ac_grp_cfg_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cfg); + + rv = hppe_ac_grp_cfg_tbl_get(dev_id, group_id, &ac_grp_cfg_tbl); + if( rv != SW_OK ) + return rv; + + cfg->prealloc_buffer = ac_grp_cfg_tbl.bf.ac_grp_palloc_limit; + cfg->total_buffer = ac_grp_cfg_tbl.bf.ac_grp_limit; + + return SW_OK; +} + +sw_error_t +adpt_hppe_mcast_cpu_code_class_get( + a_uint32_t dev_id, + a_uint8_t cpu_code, + a_uint8_t *queue_class) +{ + sw_error_t rv = SW_OK; + union mcast_queue_map_tbl_u mcast_queue_map_tbl; + + memset(&mcast_queue_map_tbl, 0, sizeof(mcast_queue_map_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(queue_class); + + rv = hppe_mcast_queue_map_tbl_get(dev_id, cpu_code, &mcast_queue_map_tbl); + if( rv != SW_OK ) + return rv; + + *queue_class = mcast_queue_map_tbl.bf.class; + + return SW_OK; +} +#endif + +sw_error_t +adpt_hppe_ac_ctrl_set( + a_uint32_t dev_id, + fal_ac_obj_t *obj, + fal_ac_ctrl_t *cfg) +{ + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cfg); + + if (obj->type == FAL_AC_GROUP) { + union ac_grp_cfg_tbl_u ac_grp_cfg_tbl; + + memset(&ac_grp_cfg_tbl, 0, sizeof(ac_grp_cfg_tbl)); + hppe_ac_grp_cfg_tbl_get(dev_id, obj->obj_id, &ac_grp_cfg_tbl); + + ac_grp_cfg_tbl.bf.ac_cfg_ac_en = cfg->ac_en; + ac_grp_cfg_tbl.bf.ac_cfg_force_ac_en = cfg->ac_fc_en; + return hppe_ac_grp_cfg_tbl_set(dev_id, obj->obj_id, &ac_grp_cfg_tbl); + } else if (obj->type == FAL_AC_QUEUE) { + if (obj->obj_id < UCAST_QUEUE_ID_MAX) { + union ac_uni_queue_cfg_tbl_u ac_uni_queue_cfg_tbl; + hppe_ac_uni_queue_cfg_tbl_get(dev_id, + obj->obj_id, + &ac_uni_queue_cfg_tbl); + ac_uni_queue_cfg_tbl.bf.ac_cfg_ac_en = cfg->ac_en; + ac_uni_queue_cfg_tbl.bf.ac_cfg_force_ac_en = cfg->ac_fc_en; + return hppe_ac_uni_queue_cfg_tbl_set(dev_id, + obj->obj_id, + &ac_uni_queue_cfg_tbl); + + } else { + union ac_mul_queue_cfg_tbl_u ac_mul_queue_cfg_tbl; + hppe_ac_mul_queue_cfg_tbl_get(dev_id, + obj->obj_id - UCAST_QUEUE_ID_MAX, + &ac_mul_queue_cfg_tbl); + ac_mul_queue_cfg_tbl.bf.ac_cfg_ac_en = cfg->ac_en; + ac_mul_queue_cfg_tbl.bf.ac_cfg_force_ac_en = cfg->ac_fc_en; + return hppe_ac_mul_queue_cfg_tbl_set(dev_id, + obj->obj_id - UCAST_QUEUE_ID_MAX, + &ac_mul_queue_cfg_tbl); + } + } else + return SW_FAIL; + +} + +#ifndef IN_QM_MINI +sw_error_t +adpt_hppe_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 = SW_OK; + union ucast_priority_map_tbl_u ucast_priority_map_tbl; + a_uint32_t index = 0; + + memset(&ucast_priority_map_tbl, 0, sizeof(ucast_priority_map_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(class); + + index = profile << 4 | priority; + rv = hppe_ucast_priority_map_tbl_get(dev_id, index, &ucast_priority_map_tbl); + + if( rv != SW_OK ) + return rv; + + *class = ucast_priority_map_tbl.bf.class; + return rv; +} +#endif + +sw_error_t +adpt_hppe_queue_flush( + a_uint32_t dev_id, + fal_port_t port, + a_uint16_t queue_id) +{ + union flush_cfg_u flush_cfg; + a_uint32_t i = 0x100; + sw_error_t rv; + + memset(&flush_cfg, 0, sizeof(flush_cfg)); + ADPT_DEV_ID_CHECK(dev_id); + + #if 0 + /* disable queue firstly */ + if (queue_id == 0xffff) { + /* all queue in this port */ + a_uint32_t i, j, k, tmp; + enq.bf.enq_disable = 1; + deq.bf.deq_dis = 1; + p_api = adpt_api_ptr_get(0); + if (!p_api || !p_api->adpt_port_queues_get) + return SW_FAIL; + p_api->adpt_port_queues_get(dev_id, port, &queue_bmp); + for (i = 0; i < ALL_QUEUE_ID_MAX; i++) { + j = i / 32; + k = i % 32; + tmp = queue_bmp.bmp[j]; + if ((tmp & (1 << k)) == 0) + continue; + hppe_oq_enq_opr_tbl_set(dev_id, i, &enq); + hppe_deq_dis_tbl_set(dev_id, i, &deq); + } + } else { + /* single queue in this port */ + enq.bf.enq_disable = 1; + deq.bf.deq_dis = 1; + if (queue_id >= ALL_QUEUE_ID_MAX) + return SW_BAD_VALUE; + hppe_oq_enq_opr_tbl_set(dev_id, queue_id, &enq); + hppe_deq_dis_tbl_set(dev_id, queue_id, &deq); + } + #endif + + hppe_flush_cfg_get(dev_id, &flush_cfg); + + if (queue_id == 0xffff) { + flush_cfg.bf.flush_all_queues = 1; + flush_cfg.bf.flush_qid = 0; + i = 0x1000; + } + else { + flush_cfg.bf.flush_all_queues = 0; + flush_cfg.bf.flush_qid = queue_id; + } + flush_cfg.bf.flush_dst_port = port; + flush_cfg.bf.flush_busy = 1; + + hppe_flush_cfg_set(dev_id, &flush_cfg); + rv = hppe_flush_cfg_get(dev_id, &flush_cfg); + if (SW_OK != rv) + return rv; + while (flush_cfg.bf.flush_busy && --i) { + hppe_flush_cfg_get(dev_id, &flush_cfg); + } + if (i == 0) + return SW_BUSY; + if (!flush_cfg.bf.flush_status) + return SW_FAIL; + + #if 0 + /* enable queue again */ + if (queue_id == 0xffff) { + /* all queue in this port */ + a_uint32_t i, j, k, tmp; + enq.bf.enq_disable = 0; + deq.bf.deq_dis = 0; + for (i = 0; i < ALL_QUEUE_ID_MAX; i++) { + j = i / 32; + k = i % 32; + tmp = queue_bmp.bmp[j]; + if ((tmp & (1 << k)) == 0) + continue; + hppe_oq_enq_opr_tbl_set(dev_id, i, &enq); + hppe_deq_dis_tbl_set(dev_id, i, &deq); + } + } else { + /* single queue in this port */ + enq.bf.enq_disable = 0; + deq.bf.deq_dis = 0; + hppe_oq_enq_opr_tbl_set(dev_id, queue_id, &enq); + hppe_deq_dis_tbl_set(dev_id, queue_id, &deq); + } + #endif + return SW_OK; +} + +#ifndef IN_QM_MINI +sw_error_t +adpt_hppe_mcast_cpu_code_class_set( + a_uint32_t dev_id, + a_uint8_t cpu_code, + a_uint8_t queue_class) +{ + union mcast_queue_map_tbl_u mcast_queue_map_tbl; + + memset(&mcast_queue_map_tbl, 0, sizeof(mcast_queue_map_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + + mcast_queue_map_tbl.bf.class = queue_class; + return hppe_mcast_queue_map_tbl_set(dev_id, cpu_code, &mcast_queue_map_tbl); +} + +sw_error_t +adpt_hppe_ucast_priority_class_set( + a_uint32_t dev_id, + a_uint8_t profile, + a_uint8_t priority, + a_uint8_t class) +{ + union ucast_priority_map_tbl_u ucast_priority_map_tbl; + a_int32_t index = 0; + + memset(&ucast_priority_map_tbl, 0, sizeof(ucast_priority_map_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + + index = profile << 4 | priority; + ucast_priority_map_tbl.bf.class = class; + + return hppe_ucast_priority_map_tbl_set(dev_id, index, &ucast_priority_map_tbl); +} + +sw_error_t +adpt_hppe_ac_static_threshold_get( + a_uint32_t dev_id, + fal_ac_obj_t *obj, + fal_ac_static_threshold_t *cfg) +{ + sw_error_t rv; + ADPT_DEV_ID_CHECK(dev_id); + + if (obj->type == FAL_AC_GROUP) { + union ac_grp_cfg_tbl_u ac_grp_cfg_tbl; + + rv = hppe_ac_grp_cfg_tbl_get(dev_id, obj->obj_id, &ac_grp_cfg_tbl); + + cfg->color_enable = ac_grp_cfg_tbl.bf.ac_cfg_color_aware; + cfg->green_max = ac_grp_cfg_tbl.bf.ac_grp_dp_thrd_0 | + ac_grp_cfg_tbl.bf.ac_grp_dp_thrd_1 << 7; + cfg->yel_max_off = ac_grp_cfg_tbl.bf.ac_grp_gap_grn_yel; + cfg->red_max_off = ac_grp_cfg_tbl.bf.ac_grp_gap_grn_red; + cfg->green_resume_off = ac_grp_cfg_tbl.bf.ac_grp_grn_resume_offset; + cfg->yel_resume_off = ac_grp_cfg_tbl.bf.ac_grp_yel_resume_offset_0 | + ac_grp_cfg_tbl.bf.ac_grp_yel_resume_offset_1 << 6; + cfg->red_resume_off = ac_grp_cfg_tbl.bf.ac_grp_red_resume_offset; + + return rv; + + } else if (obj->type == FAL_AC_QUEUE) { + if (obj->obj_id < UCAST_QUEUE_ID_MAX) { + union ac_uni_queue_cfg_tbl_u ac_uni_queue_cfg_tbl; + rv = hppe_ac_uni_queue_cfg_tbl_get(dev_id, + obj->obj_id, + &ac_uni_queue_cfg_tbl); + cfg->wred_enable = ac_uni_queue_cfg_tbl.bf.ac_cfg_wred_en; + cfg->color_enable = ac_uni_queue_cfg_tbl.bf.ac_cfg_color_aware; + cfg->green_min_off = ac_uni_queue_cfg_tbl.bf.ac_cfg_gap_grn_grn_min; + cfg->yel_max_off = ac_uni_queue_cfg_tbl.bf.ac_cfg_gap_grn_yel_max; + cfg->yel_min_off = ac_uni_queue_cfg_tbl.bf.ac_cfg_gap_grn_yel_min_0 | + ac_uni_queue_cfg_tbl.bf.ac_cfg_gap_grn_yel_min_1 << 10; + cfg->red_max_off = ac_uni_queue_cfg_tbl.bf.ac_cfg_gap_grn_red_max; + cfg->red_min_off = ac_uni_queue_cfg_tbl.bf.ac_cfg_gap_grn_red_min; + cfg->green_resume_off = ac_uni_queue_cfg_tbl.bf.ac_cfg_grn_resume_offset; + cfg->yel_resume_off = ac_uni_queue_cfg_tbl.bf.ac_cfg_yel_resume_offset; + cfg->red_resume_off = ac_uni_queue_cfg_tbl.bf.ac_cfg_red_resume_offset_0 | + ac_uni_queue_cfg_tbl.bf.ac_cfg_red_resume_offset_1 << 9; + cfg->green_max = ac_uni_queue_cfg_tbl.bf.ac_cfg_shared_ceiling; + return rv; + + } else { + union ac_mul_queue_cfg_tbl_u ac_mul_queue_cfg_tbl; + rv = hppe_ac_mul_queue_cfg_tbl_get(dev_id, + obj->obj_id - UCAST_QUEUE_ID_MAX, + &ac_mul_queue_cfg_tbl); + cfg->color_enable = ac_mul_queue_cfg_tbl.bf.ac_cfg_color_aware; + cfg->green_max = ac_mul_queue_cfg_tbl.bf.ac_cfg_shared_ceiling; + cfg->red_max_off = ac_mul_queue_cfg_tbl.bf.ac_cfg_gap_grn_red; + cfg->yel_max_off= ac_mul_queue_cfg_tbl.bf.ac_cfg_gap_grn_yel_0 | + ac_mul_queue_cfg_tbl.bf.ac_cfg_gap_grn_yel_1 << 5; + cfg->green_resume_off = ac_mul_queue_cfg_tbl.bf.ac_cfg_grn_resume_offset; + cfg->yel_resume_off = ac_mul_queue_cfg_tbl.bf.ac_cfg_yel_resume_offset_0 | + ac_mul_queue_cfg_tbl.bf.ac_cfg_yel_resume_offset_1 << 4; + cfg->red_resume_off = ac_mul_queue_cfg_tbl.bf.ac_cfg_red_resume_offset; + + return rv; + } + } else + return SW_FAIL; +} +#endif + +sw_error_t +adpt_hppe_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) +{ + union ucast_queue_map_tbl_u ucast_queue_map_tbl; + a_uint32_t index = 0; + + memset(&ucast_queue_map_tbl, 0, sizeof(ucast_queue_map_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(queue_dest); + + if (queue_dest ->service_code_en) { + index = SERVICE_CODE_QUEUE_OFFSET + (queue_dest->src_profile << 8) \ + + queue_dest->service_code; + } else if (queue_dest ->cpu_code_en) { + index = CPU_CODE_QUEUE_OFFSET + (queue_dest->src_profile << 8) \ + + queue_dest->cpu_code; + } else { + index = VP_PORT_QUEUE_OFFSET + (queue_dest->src_profile << 8) \ + + queue_dest->dst_port; + } + + ucast_queue_map_tbl.bf.queue_id = queue_base; + ucast_queue_map_tbl.bf.profile_id = profile; + + return hppe_ucast_queue_map_tbl_set(dev_id, index, &ucast_queue_map_tbl); +} + +sw_error_t +adpt_hppe_ac_group_buffer_set( + a_uint32_t dev_id, + a_uint8_t group_id, + fal_ac_group_buffer_t *cfg) +{ + sw_error_t rv = SW_OK; + union ac_grp_cfg_tbl_u ac_grp_cfg_tbl; + + memset(&ac_grp_cfg_tbl, 0, sizeof(ac_grp_cfg_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cfg); + + rv = hppe_ac_grp_cfg_tbl_get(dev_id, group_id, &ac_grp_cfg_tbl); + if( rv != SW_OK ) + return rv; + + ac_grp_cfg_tbl.bf.ac_grp_palloc_limit = cfg->prealloc_buffer; + ac_grp_cfg_tbl.bf.ac_grp_limit = cfg->total_buffer; + + return hppe_ac_grp_cfg_tbl_set(dev_id, group_id, &ac_grp_cfg_tbl);; +} + +#ifndef IN_QM_MINI +static a_uint32_t +adpt_hppe_mcast_queue_dropcnt_start_addr_get(a_uint32_t queue_id) +{ + a_uint32_t start_addr = QUEUE_MANAGER_BASE_ADDR; + + if (queue_id >= MCAST_QUEUE_PORT7_START) { + start_addr += MUL_P7_DROP_CNT_TBL_ADDRESS; + start_addr += (queue_id - MCAST_QUEUE_PORT7_START)*MCAST_QUEUE_OFFSET; + } else if (queue_id >= MCAST_QUEUE_PORT6_START) { + start_addr += MUL_P6_DROP_CNT_TBL_ADDRESS; + start_addr += (queue_id - MCAST_QUEUE_PORT6_START)*MCAST_QUEUE_OFFSET; + } else if (queue_id >= MCAST_QUEUE_PORT5_START) { + start_addr += MUL_P5_DROP_CNT_TBL_ADDRESS; + start_addr += (queue_id - MCAST_QUEUE_PORT5_START)*MCAST_QUEUE_OFFSET; + } else if (queue_id >= MCAST_QUEUE_PORT4_START) { + start_addr += MUL_P4_DROP_CNT_TBL_ADDRESS; + start_addr += (queue_id - MCAST_QUEUE_PORT4_START)*MCAST_QUEUE_OFFSET; + } else if (queue_id >= MCAST_QUEUE_PORT3_START) { + start_addr += MUL_P3_DROP_CNT_TBL_ADDRESS; + start_addr += (queue_id - MCAST_QUEUE_PORT3_START)*MCAST_QUEUE_OFFSET; + } else if (queue_id >= MCAST_QUEUE_PORT2_START) { + start_addr += MUL_P2_DROP_CNT_TBL_ADDRESS; + start_addr += (queue_id - MCAST_QUEUE_PORT2_START)*MCAST_QUEUE_OFFSET; + } else if (queue_id >= MCAST_QUEUE_PORT1_START) { + start_addr += MUL_P1_DROP_CNT_TBL_ADDRESS; + start_addr += (queue_id - MCAST_QUEUE_PORT1_START)*MCAST_QUEUE_OFFSET; + } else if (queue_id >= MCAST_QUEUE_PORT0_START) { + start_addr += MUL_P0_DROP_CNT_TBL_ADDRESS; + start_addr += (queue_id - MCAST_QUEUE_PORT0_START)*MCAST_QUEUE_OFFSET; + } + + return start_addr; +} + +sw_error_t +adpt_hppe_queue_counter_cleanup(a_uint32_t dev_id, a_uint32_t queue_id) +{ + union queue_tx_counter_tbl_u tx_cnt; + a_uint32_t i = 0; + a_uint32_t val[3] = {0}; + + ADPT_DEV_ID_CHECK(dev_id); + + if (queue_id >= ALL_QUEUE_ID_MAX) + return SW_BAD_VALUE; + + tx_cnt.bf.tx_packets = 0; + tx_cnt.bf.tx_bytes_0 = 0; + tx_cnt.bf.tx_bytes_1 = 0; + + hppe_queue_tx_counter_tbl_set(dev_id, queue_id, &tx_cnt); + + if (queue_id >= UCAST_QUEUE_ID_MAX) { + a_uint32_t start_addr = 0; + + start_addr = adpt_hppe_mcast_queue_dropcnt_start_addr_get(queue_id); + for (i = 0; i < MCAST_QUEUE_ITEMS; i++) { + hppe_reg_tbl_set(dev_id, start_addr + i*DROP_INC, val, 3); + } + } else { + union uni_drop_cnt_tbl_u uni_drop_cnt; + + memset(&uni_drop_cnt, 0, sizeof(uni_drop_cnt)); + for (i = 0; i < UCAST_QUEUE_ITEMS; i++) { + hppe_uni_drop_cnt_tbl_set(dev_id, queue_id*UCAST_QUEUE_ITEMS+i, &uni_drop_cnt); + } + } + + return SW_OK; +} +sw_error_t +adpt_hppe_queue_counter_get(a_uint32_t dev_id, a_uint32_t queue_id, fal_queue_stats_t *info) +{ + sw_error_t rv = SW_OK; + union queue_tx_counter_tbl_u tx_cnt; + union ac_mul_queue_cnt_tbl_u mul_cnt; + union ac_uni_queue_cnt_tbl_u uni_cnt; + a_uint32_t i = 0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(info); + + if (queue_id >= ALL_QUEUE_ID_MAX) + return SW_BAD_VALUE; + + rv = hppe_queue_tx_counter_tbl_get(dev_id, queue_id, &tx_cnt); + if( rv != SW_OK ) + return rv; + if (queue_id >= UCAST_QUEUE_ID_MAX) { + a_uint32_t start_addr = 0; + union mul_p7_drop_cnt_tbl_u drop_cnt; + + rv = hppe_ac_mul_queue_cnt_tbl_get(dev_id, + queue_id - UCAST_QUEUE_ID_MAX, &mul_cnt); + if( rv != SW_OK ) + return rv; + info->pending_buff_num = mul_cnt.bf.ac_mul_queue_cnt; + start_addr = adpt_hppe_mcast_queue_dropcnt_start_addr_get(queue_id); + for (i = 0; i < MCAST_QUEUE_ITEMS; i++) { + hppe_reg_tbl_get(dev_id, start_addr + i*DROP_INC, drop_cnt.val, 3); + info->drop_packets[i+3] = drop_cnt.bf.mul_p7_drop_pkt; + info->drop_bytes[i+3] = (a_uint64_t)drop_cnt.bf.mul_p7_drop_byte_0 | + (a_uint64_t)drop_cnt.bf.mul_p7_drop_byte_1 <<32; + } + } else { + union uni_drop_cnt_tbl_u uni_drop_cnt; + + rv = hppe_ac_uni_queue_cnt_tbl_get(dev_id, queue_id, &uni_cnt); + if( rv != SW_OK ) + return rv; + info->pending_buff_num = uni_cnt.bf.ac_uni_queue_cnt; + for (i = 0; i < UCAST_QUEUE_ITEMS; i++) { + hppe_uni_drop_cnt_tbl_get(dev_id, queue_id*UCAST_QUEUE_ITEMS+i, &uni_drop_cnt); + info->drop_packets[i] = uni_drop_cnt.bf.uni_drop_pkt; + info->drop_bytes[i] = (a_uint64_t)uni_drop_cnt.bf.uni_drop_byte_0 | + (a_uint64_t)uni_drop_cnt.bf.uni_drop_byte_1 <<32; + } + } + info->tx_packets = tx_cnt.bf.tx_packets; + info->tx_bytes = (a_uint64_t)tx_cnt.bf.tx_bytes_0 | (a_uint64_t)tx_cnt.bf.tx_bytes_1 << 32; + + return SW_OK; +} + +sw_error_t +adpt_hppe_queue_counter_ctrl_get(a_uint32_t dev_id, a_bool_t *cnt_en) +{ + sw_error_t rv = SW_OK; + union eg_bridge_config_u eg_bridge_config; + + memset(&eg_bridge_config, 0, sizeof(eg_bridge_config)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cnt_en); + + rv = hppe_eg_bridge_config_get(dev_id, &eg_bridge_config); + if( rv != SW_OK ) + return rv; + + *cnt_en = eg_bridge_config.bf.queue_cnt_en; + + return SW_OK; +} + +sw_error_t +adpt_hppe_queue_counter_ctrl_set(a_uint32_t dev_id, a_bool_t cnt_en) +{ + sw_error_t rv = SW_OK; + union eg_bridge_config_u eg_bridge_config; + + memset(&eg_bridge_config, 0, sizeof(eg_bridge_config)); + ADPT_DEV_ID_CHECK(dev_id); + + + rv = hppe_eg_bridge_config_get(dev_id, &eg_bridge_config); + if( rv != SW_OK ) + return rv; + + eg_bridge_config.bf.queue_cnt_en = cnt_en; + return hppe_eg_bridge_config_set(dev_id, &eg_bridge_config); +} +#endif + +sw_error_t +adpt_hppe_qm_enqueue_ctrl_set( + a_uint32_t dev_id, + a_uint32_t queue_id, + a_bool_t enable) +{ + union oq_enq_opr_tbl_u enq; + + ADPT_DEV_ID_CHECK(dev_id); + memset(&enq, 0, sizeof(enq)); + + enq.bf.enq_disable = !enable; + return hppe_oq_enq_opr_tbl_set(dev_id, queue_id, &enq); +} + +#ifndef IN_QM_MINI +sw_error_t +adpt_hppe_qm_enqueue_ctrl_get( + a_uint32_t dev_id, + a_uint32_t queue_id, + a_bool_t *enable) +{ + sw_error_t rv = SW_OK; + union oq_enq_opr_tbl_u enq; + + ADPT_DEV_ID_CHECK(dev_id); + memset(&enq, 0, sizeof(enq)); + + rv = hppe_oq_enq_opr_tbl_get(dev_id, queue_id, &enq); + if( rv != SW_OK ) + return rv; + + *enable = !(enq.bf.enq_disable); + + return SW_OK; +} + +static sw_error_t +adpt_hppe_qm_port_source_profile_set( + a_uint32_t dev_id, fal_port_t port, a_uint32_t src_profile) +{ + union mru_mtu_ctrl_tbl_u mru_mtu_ctrl_tbl; + a_uint32_t index = FAL_PORT_ID_VALUE(port); + + ADPT_DEV_ID_CHECK(dev_id); + memset(&mru_mtu_ctrl_tbl, 0, sizeof(mru_mtu_ctrl_tbl)); + + + return hppe_mru_mtu_ctrl_tbl_src_profile_set(dev_id, index, + src_profile); +} + +sw_error_t +adpt_ppe_qm_port_source_profile_set( + a_uint32_t dev_id, fal_port_t port, a_uint32_t src_profile) +{ + a_uint32_t chip_ver = 0; + + chip_ver = adpt_hppe_chip_revision_get(dev_id); + if (chip_ver == CPPE_REVISION) { +#if defined(CPPE) + return adpt_cppe_qm_port_source_profile_set(dev_id, port, + src_profile); +#endif + } else { + return adpt_hppe_qm_port_source_profile_set(dev_id, port, + src_profile); + } + + return SW_NOT_SUPPORTED; +} + +static sw_error_t +adpt_hppe_qm_port_source_profile_get( + a_uint32_t dev_id, fal_port_t port, a_uint32_t *src_profile) +{ + union mru_mtu_ctrl_tbl_u mru_mtu_ctrl_tbl; + a_uint32_t index = FAL_PORT_ID_VALUE(port); + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(src_profile); + memset(&mru_mtu_ctrl_tbl, 0, sizeof(mru_mtu_ctrl_tbl)); + + return hppe_mru_mtu_ctrl_tbl_src_profile_get(dev_id, index, + src_profile); +} + +sw_error_t +adpt_ppe_qm_port_source_profile_get( + a_uint32_t dev_id, fal_port_t port, a_uint32_t *src_profile) +{ + a_uint32_t chip_ver = 0; + + chip_ver = adpt_hppe_chip_revision_get(dev_id); + if (chip_ver == CPPE_REVISION) { +#if defined(CPPE) + return adpt_cppe_qm_port_source_profile_get(dev_id, port, + src_profile); +#endif + } else { + return adpt_hppe_qm_port_source_profile_get(dev_id, port, + src_profile); + } + + return SW_NOT_SUPPORTED; +} +#endif + +void adpt_hppe_qm_func_bitmap_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_qm_func_bitmap[0] = ((1 << FUNC_UCAST_HASH_MAP_SET) | + (1 << FUNC_AC_DYNAMIC_THRESHOLD_GET) | + (1 << FUNC_UCAST_QUEUE_BASE_PROFILE_GET) | + (1 << FUNC_PORT_MCAST_PRIORITY_CLASS_GET) | + (1 << FUNC_AC_DYNAMIC_THRESHOLD_SET) | + (1 << FUNC_AC_PREALLOC_BUFFER_SET) | + (1 << FUNC_UCAST_DEFAULT_HASH_GET) | + (1 << FUNC_UCAST_DEFAULT_HASH_SET) | + (1 << FUNC_AC_QUEUE_GROUP_GET) | + (1 << FUNC_AC_CTRL_GET) | + (1 << FUNC_AC_PREALLOC_BUFFER_GET) | + (1 << FUNC_PORT_MCAST_PRIORITY_CLASS_SET) | + (1 << FUNC_UCAST_HASH_MAP_GET) | + (1 << FUNC_AC_STATIC_THRESHOLD_SET) | + (1 << FUNC_AC_QUEUE_GROUP_SET) | + (1 << FUNC_AC_GROUP_BUFFER_GET) | + (1 << FUNC_MCAST_CPU_CODE_CLASS_GET) | + (1 << FUNC_AC_CTRL_SET) | + (1 << FUNC_UCAST_PRIORITY_CLASS_GET) | + (1 << FUNC_QUEUE_FLUSH) | + (1 << FUNC_MCAST_CPU_CODE_CLASS_SET) | + (1 << FUNC_UCAST_PRIORITY_CLASS_SET) | + (1 << FUNC_AC_STATIC_THRESHOLD_GET) | + (1 << FUNC_UCAST_QUEUE_BASE_PROFILE_SET) | + (1 << FUNC_AC_GROUP_BUFFER_SET) | + (1 << FUNC_QUEUE_COUNTER_CLEANUP) | + (1 << FUNC_QUEUE_COUNTER_GET) | + (1 << FUNC_QUEUE_COUNTER_CTRL_GET) | + (1 << FUNC_QUEUE_COUNTER_CTRL_SET) | + (1 << FUNC_QM_ENQUEUE_CTRL_GET) | + (1 << FUNC_QM_ENQUEUE_CTRL_SET) | + (1 << FUNC_QM_PORT_SRCPROFILE_GET)); + p_adpt_api->adpt_qm_func_bitmap[1] = 1 << (FUNC_QM_PORT_SRCPROFILE_SET % 32); + return; +} + +static void adpt_hppe_qm_func_unregister(a_uint32_t dev_id, adpt_api_t *p_adpt_api) +{ + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_ucast_hash_map_set = NULL; + p_adpt_api->adpt_ac_dynamic_threshold_get = NULL; + p_adpt_api->adpt_ucast_queue_base_profile_get = NULL; + p_adpt_api->adpt_port_mcast_priority_class_get = NULL; + p_adpt_api->adpt_ac_dynamic_threshold_set = NULL; + p_adpt_api->adpt_ac_prealloc_buffer_set = NULL; + p_adpt_api->adpt_ucast_default_hash_get = NULL; + p_adpt_api->adpt_ucast_default_hash_set = NULL; + p_adpt_api->adpt_ac_queue_group_get = NULL; + p_adpt_api->adpt_ac_ctrl_get = NULL; + p_adpt_api->adpt_ac_prealloc_buffer_get = NULL; + p_adpt_api->adpt_port_mcast_priority_class_set = NULL; + p_adpt_api->adpt_ucast_hash_map_get = NULL; + p_adpt_api->adpt_ac_static_threshold_set = NULL; + p_adpt_api->adpt_ac_queue_group_set = NULL; + p_adpt_api->adpt_ac_group_buffer_get = NULL; + p_adpt_api->adpt_mcast_cpu_code_class_get = NULL; + p_adpt_api->adpt_ac_ctrl_set = NULL; + p_adpt_api->adpt_ucast_priority_class_get = NULL; + p_adpt_api->adpt_queue_flush = NULL; + p_adpt_api->adpt_mcast_cpu_code_class_set = NULL; + p_adpt_api->adpt_ucast_priority_class_set = NULL; + p_adpt_api->adpt_ac_static_threshold_get = NULL; + p_adpt_api->adpt_ucast_queue_base_profile_set = NULL; + p_adpt_api->adpt_ac_group_buffer_set = NULL; + p_adpt_api->adpt_queue_counter_cleanup = NULL; + p_adpt_api->adpt_queue_counter_get = NULL; + p_adpt_api->adpt_queue_counter_ctrl_get = NULL; + p_adpt_api->adpt_queue_counter_ctrl_set = NULL; + p_adpt_api->adpt_qm_enqueue_ctrl_set = NULL; + p_adpt_api->adpt_qm_enqueue_ctrl_get = NULL; + p_adpt_api->adpt_qm_port_source_profile_get = NULL; + p_adpt_api->adpt_qm_port_source_profile_set = NULL; + + return; +} + +sw_error_t adpt_hppe_qm_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return SW_FAIL; + + adpt_hppe_qm_func_unregister(dev_id, p_adpt_api); + + if (p_adpt_api->adpt_qm_func_bitmap[0] & (1 << FUNC_AC_CTRL_SET)) + p_adpt_api->adpt_ac_ctrl_set = adpt_hppe_ac_ctrl_set; + if (p_adpt_api->adpt_qm_func_bitmap[0] & (1 << FUNC_AC_PREALLOC_BUFFER_SET)) + p_adpt_api->adpt_ac_prealloc_buffer_set = adpt_hppe_ac_prealloc_buffer_set; + if (p_adpt_api->adpt_qm_func_bitmap[0] & (1 << FUNC_AC_QUEUE_GROUP_SET)) + p_adpt_api->adpt_ac_queue_group_set = adpt_hppe_ac_queue_group_set; + if (p_adpt_api->adpt_qm_func_bitmap[0] & (1 << FUNC_AC_STATIC_THRESHOLD_SET)) + p_adpt_api->adpt_ac_static_threshold_set = adpt_hppe_ac_static_threshold_set; + if (p_adpt_api->adpt_qm_func_bitmap[0] & (1 << FUNC_AC_DYNAMIC_THRESHOLD_SET)) + p_adpt_api->adpt_ac_dynamic_threshold_set = adpt_hppe_ac_dynamic_threshold_set; + if (p_adpt_api->adpt_qm_func_bitmap[0] & (1 << FUNC_AC_GROUP_BUFFER_SET)) + p_adpt_api->adpt_ac_group_buffer_set = adpt_hppe_ac_group_buffer_set; + if (p_adpt_api->adpt_qm_func_bitmap[0] & (1 << FUNC_UCAST_QUEUE_BASE_PROFILE_SET)) + p_adpt_api->adpt_ucast_queue_base_profile_set = + adpt_hppe_ucast_queue_base_profile_set; + if (p_adpt_api->adpt_qm_func_bitmap[0] & (1 << FUNC_QUEUE_FLUSH)) + p_adpt_api->adpt_queue_flush = adpt_hppe_queue_flush; + if (p_adpt_api->adpt_qm_func_bitmap[0] & (1 << FUNC_QM_ENQUEUE_CTRL_SET)) + p_adpt_api->adpt_qm_enqueue_ctrl_set = adpt_hppe_qm_enqueue_ctrl_set; +#ifndef IN_QM_MINI + if (p_adpt_api->adpt_qm_func_bitmap[0] & (1 << FUNC_UCAST_HASH_MAP_SET)) + p_adpt_api->adpt_ucast_hash_map_set = adpt_hppe_ucast_hash_map_set; + if (p_adpt_api->adpt_qm_func_bitmap[0] & (1 << FUNC_AC_DYNAMIC_THRESHOLD_GET)) + p_adpt_api->adpt_ac_dynamic_threshold_get = adpt_hppe_ac_dynamic_threshold_get; + if (p_adpt_api->adpt_qm_func_bitmap[0] & (1 << FUNC_UCAST_QUEUE_BASE_PROFILE_GET)) + p_adpt_api->adpt_ucast_queue_base_profile_get = + adpt_hppe_ucast_queue_base_profile_get; + if (p_adpt_api->adpt_qm_func_bitmap[0] & (1 << FUNC_PORT_MCAST_PRIORITY_CLASS_GET)) + p_adpt_api->adpt_port_mcast_priority_class_get = + adpt_hppe_port_mcast_priority_class_get; + if (p_adpt_api->adpt_qm_func_bitmap[0] & (1 << FUNC_UCAST_DEFAULT_HASH_GET)) + p_adpt_api->adpt_ucast_default_hash_get = adpt_hppe_ucast_default_hash_get; + if (p_adpt_api->adpt_qm_func_bitmap[0] & (1 << FUNC_UCAST_DEFAULT_HASH_SET)) + p_adpt_api->adpt_ucast_default_hash_set = adpt_hppe_ucast_default_hash_set; + if (p_adpt_api->adpt_qm_func_bitmap[0] & (1 << FUNC_AC_QUEUE_GROUP_GET)) + p_adpt_api->adpt_ac_queue_group_get = adpt_hppe_ac_queue_group_get; + if (p_adpt_api->adpt_qm_func_bitmap[0] & (1 << FUNC_AC_CTRL_GET)) + p_adpt_api->adpt_ac_ctrl_get = adpt_hppe_ac_ctrl_get; + if (p_adpt_api->adpt_qm_func_bitmap[0] & (1 << FUNC_AC_PREALLOC_BUFFER_GET)) + p_adpt_api->adpt_ac_prealloc_buffer_get = adpt_hppe_ac_prealloc_buffer_get; + if (p_adpt_api->adpt_qm_func_bitmap[0] & (1 << FUNC_PORT_MCAST_PRIORITY_CLASS_SET)) + p_adpt_api->adpt_port_mcast_priority_class_set = + adpt_hppe_port_mcast_priority_class_set; + if (p_adpt_api->adpt_qm_func_bitmap[0] & (1 << FUNC_UCAST_HASH_MAP_GET)) + p_adpt_api->adpt_ucast_hash_map_get = adpt_hppe_ucast_hash_map_get; + if (p_adpt_api->adpt_qm_func_bitmap[0] & (1 << FUNC_AC_GROUP_BUFFER_GET)) + p_adpt_api->adpt_ac_group_buffer_get = adpt_hppe_ac_group_buffer_get; + if (p_adpt_api->adpt_qm_func_bitmap[0] & (1 << FUNC_MCAST_CPU_CODE_CLASS_GET)) + p_adpt_api->adpt_mcast_cpu_code_class_get = adpt_hppe_mcast_cpu_code_class_get; + if (p_adpt_api->adpt_qm_func_bitmap[0] & (1 << FUNC_UCAST_PRIORITY_CLASS_GET)) + p_adpt_api->adpt_ucast_priority_class_get = adpt_hppe_ucast_priority_class_get; + if (p_adpt_api->adpt_qm_func_bitmap[0] & (1 << FUNC_MCAST_CPU_CODE_CLASS_SET)) + p_adpt_api->adpt_mcast_cpu_code_class_set = adpt_hppe_mcast_cpu_code_class_set; + if (p_adpt_api->adpt_qm_func_bitmap[0] & (1 << FUNC_UCAST_PRIORITY_CLASS_SET)) + p_adpt_api->adpt_ucast_priority_class_set = adpt_hppe_ucast_priority_class_set; + if (p_adpt_api->adpt_qm_func_bitmap[0] & (1 << FUNC_AC_STATIC_THRESHOLD_GET)) + p_adpt_api->adpt_ac_static_threshold_get = adpt_hppe_ac_static_threshold_get; + if (p_adpt_api->adpt_qm_func_bitmap[0] & (1 << FUNC_QUEUE_COUNTER_CLEANUP)) + p_adpt_api->adpt_queue_counter_cleanup = adpt_hppe_queue_counter_cleanup; + if (p_adpt_api->adpt_qm_func_bitmap[0] & (1 << FUNC_QUEUE_COUNTER_GET)) + p_adpt_api->adpt_queue_counter_get = adpt_hppe_queue_counter_get; + if (p_adpt_api->adpt_qm_func_bitmap[0] & (1 << FUNC_QUEUE_COUNTER_CTRL_GET)) + p_adpt_api->adpt_queue_counter_ctrl_get = adpt_hppe_queue_counter_ctrl_get; + if (p_adpt_api->adpt_qm_func_bitmap[0] & (1 << FUNC_QUEUE_COUNTER_CTRL_SET)) + p_adpt_api->adpt_queue_counter_ctrl_set = adpt_hppe_queue_counter_ctrl_set; + if (p_adpt_api->adpt_qm_func_bitmap[0] & (1 << FUNC_QM_ENQUEUE_CTRL_GET)) + p_adpt_api->adpt_qm_enqueue_ctrl_get = adpt_hppe_qm_enqueue_ctrl_get; + if (p_adpt_api->adpt_qm_func_bitmap[0] & (1 << FUNC_QM_PORT_SRCPROFILE_GET)) + p_adpt_api->adpt_qm_port_source_profile_get = adpt_ppe_qm_port_source_profile_get; + if (p_adpt_api->adpt_qm_func_bitmap[1] & (1 << (FUNC_QM_PORT_SRCPROFILE_SET % 32))) + p_adpt_api->adpt_qm_port_source_profile_set = adpt_ppe_qm_port_source_profile_set; +#endif + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_qos.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_qos.c new file mode 100644 index 000000000..ca48de653 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_qos.c @@ -0,0 +1,1235 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "ssdk_dts.h" +#include "fal_qos.h" +#include "hppe_qos_reg.h" +#include "hppe_qos.h" +#include "hppe_shaper_reg.h" +#include "hppe_shaper.h" +#include "adpt.h" +#include "adpt_hppe.h" +#if defined(CPPE) +#include "adpt_cppe_qos.h" +#endif + +static fal_queue_bmp_t port_queue_map[8] = {0}; + +sw_error_t +adpt_hppe_l1_flow_map_get(a_uint32_t dev_id, + a_uint32_t node_id, + fal_port_t *port_id, + fal_qos_scheduler_cfg_t *scheduler_cfg) +{ + union l1_flow_map_tbl_u l1_flow_map_tbl; + union l1_c_sp_cfg_tbl_u l1_c_sp_cfg_tbl; + union l1_e_sp_cfg_tbl_u l1_e_sp_cfg_tbl; + union l1_flow_port_map_tbl_u port_map; + union l1_comp_cfg_tbl_u l1_comp_cfg_tbl; + a_uint32_t c_sp_id, e_sp_id; + + memset(&l1_flow_map_tbl, 0, sizeof(l1_flow_map_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(scheduler_cfg); + if (node_id >= L1_FLOW_MAP_TBL_MAX_ENTRY) + return SW_BAD_PARAM; + + hppe_l1_flow_map_tbl_get(dev_id, node_id, &l1_flow_map_tbl); + scheduler_cfg->e_drr_wt = l1_flow_map_tbl.bf.e_drr_wt; + scheduler_cfg->c_drr_wt = l1_flow_map_tbl.bf.c_drr_wt; + scheduler_cfg->e_pri = l1_flow_map_tbl.bf.e_pri; + scheduler_cfg->c_pri = l1_flow_map_tbl.bf.c_pri; + scheduler_cfg->sp_id = l1_flow_map_tbl.bf.sp_id; + + c_sp_id = scheduler_cfg->sp_id * 8 + scheduler_cfg->c_pri; + hppe_l1_c_sp_cfg_tbl_get(dev_id, c_sp_id, &l1_c_sp_cfg_tbl); + scheduler_cfg->c_drr_unit = l1_c_sp_cfg_tbl.bf.drr_credit_unit; + scheduler_cfg->c_drr_id = l1_c_sp_cfg_tbl.bf.drr_id; + + e_sp_id = scheduler_cfg->sp_id * 8 + scheduler_cfg->e_pri; + hppe_l1_e_sp_cfg_tbl_get(dev_id, e_sp_id, &l1_e_sp_cfg_tbl); + scheduler_cfg->e_drr_unit = l1_e_sp_cfg_tbl.bf.drr_credit_unit; + scheduler_cfg->e_drr_id = l1_e_sp_cfg_tbl.bf.drr_id; + + hppe_l1_flow_port_map_tbl_get(dev_id, node_id, &port_map); + *port_id = port_map.bf.port_num; + + hppe_l1_comp_cfg_tbl_get(dev_id, node_id, &l1_comp_cfg_tbl); + scheduler_cfg->drr_frame_mode = l1_comp_cfg_tbl.bf.drr_meter_len; + + return SW_OK; +} +#ifndef IN_QOS_MINI +sw_error_t +adpt_hppe_qos_port_mode_pri_set(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_uint32_t pri) +{ + union port_qos_ctrl_u port_qos_ctrl; + + memset(&port_qos_ctrl, 0, sizeof(port_qos_ctrl)); + ADPT_DEV_ID_CHECK(dev_id); + + hppe_port_qos_ctrl_get(dev_id, port_id, &port_qos_ctrl); + + if (mode == FAL_QOS_UP_MODE) + port_qos_ctrl.bf.port_pcp_qos_pri = pri; + else if (mode == FAL_QOS_DSCP_MODE) + port_qos_ctrl.bf.port_dscp_qos_pri = pri; + else if (mode == FAL_QOS_FLOW_MODE) + port_qos_ctrl.bf.port_flow_qos_pri = pri; + else + return SW_NOT_SUPPORTED; + + return hppe_port_qos_ctrl_set(dev_id, port_id, &port_qos_ctrl); +} + +sw_error_t +adpt_hppe_qos_port_mode_pri_get(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_uint32_t *pri) +{ + union port_qos_ctrl_u port_qos_ctrl; + + memset(&port_qos_ctrl, 0, sizeof(port_qos_ctrl)); + ADPT_DEV_ID_CHECK(dev_id); + + hppe_port_qos_ctrl_get(dev_id, port_id, &port_qos_ctrl); + + if (mode == FAL_QOS_UP_MODE) + *pri = port_qos_ctrl.bf.port_pcp_qos_pri; + else if (mode == FAL_QOS_DSCP_MODE) + *pri = port_qos_ctrl.bf.port_dscp_qos_pri; + else if (mode == FAL_QOS_FLOW_MODE) + *pri = port_qos_ctrl.bf.port_flow_qos_pri; + else + return SW_NOT_SUPPORTED; + + return SW_OK; +} +#endif + +static sw_error_t +adpt_hppe_qos_port_pri_set(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_pri_precedence_t *pri) +{ + union port_qos_ctrl_u port_qos_ctrl; + + memset(&port_qos_ctrl, 0, sizeof(port_qos_ctrl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(pri); + + hppe_port_qos_ctrl_get(dev_id, port_id, &port_qos_ctrl); + + port_qos_ctrl.bf.port_pcp_qos_pri = pri->pcp_pri; + port_qos_ctrl.bf.port_dscp_qos_pri = pri->dscp_pri; + port_qos_ctrl.bf.port_preheader_qos_pri = pri->preheader_pri; + port_qos_ctrl.bf.port_flow_qos_pri = pri->flow_pri; + port_qos_ctrl.bf.port_acl_qos_pri = pri->acl_pri; + + return hppe_port_qos_ctrl_set(dev_id, port_id, &port_qos_ctrl); +} + +sw_error_t +adpt_ppe_qos_port_pri_set(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_pri_precedence_t *pri) +{ + a_uint32_t chip_ver = 0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(pri); + + chip_ver = adpt_hppe_chip_revision_get(dev_id); + if (chip_ver == CPPE_REVISION) { +#if defined(CPPE) + return adpt_cppe_qos_port_pri_set(dev_id, port_id, pri); +#endif + } else { + return adpt_hppe_qos_port_pri_set(dev_id, port_id, pri); + } + + return SW_NOT_SUPPORTED; +} + +static sw_error_t +adpt_hppe_qos_port_pri_get(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_pri_precedence_t *pri) +{ + sw_error_t rv = SW_OK; + union port_qos_ctrl_u port_qos_ctrl; + + memset(&port_qos_ctrl, 0, sizeof(port_qos_ctrl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(pri); + + rv = hppe_port_qos_ctrl_get(dev_id, port_id, &port_qos_ctrl); + if( rv != SW_OK ) + return rv; + + pri->pcp_pri = port_qos_ctrl.bf.port_pcp_qos_pri; + pri->dscp_pri = port_qos_ctrl.bf.port_dscp_qos_pri; + pri->preheader_pri = port_qos_ctrl.bf.port_preheader_qos_pri; + pri->flow_pri = port_qos_ctrl.bf.port_flow_qos_pri; + pri->acl_pri = port_qos_ctrl.bf.port_acl_qos_pri; + + return SW_OK; +} + +sw_error_t +adpt_ppe_qos_port_pri_get(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_pri_precedence_t *pri) +{ + a_uint32_t chip_ver = 0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(pri); + + chip_ver = adpt_hppe_chip_revision_get(dev_id); + if (chip_ver == CPPE_REVISION) { +#if defined(CPPE) + return adpt_cppe_qos_port_pri_get(dev_id, port_id, pri); +#endif + } else { + return adpt_hppe_qos_port_pri_get(dev_id, port_id, pri); + } + + return SW_NOT_SUPPORTED; +} + +static sw_error_t +adpt_hppe_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 = SW_OK; + union pcp_qos_group_0_u pcp_qos_group_0; + union pcp_qos_group_1_u pcp_qos_group_1; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cosmap); + + if (pcp >= PCP_QOS_GROUP_0_MAX_ENTRY) + return SW_BAD_PARAM; + + if (group_id == 0) { + rv = hppe_pcp_qos_group_0_get(dev_id, pcp, &pcp_qos_group_0); + if( rv != SW_OK ) + return rv; + cosmap->internal_pcp = pcp_qos_group_0.bf.qos_info & 7; + cosmap->internal_dei = (pcp_qos_group_0.bf.qos_info >> 3) & 1; + cosmap->internal_pri = (pcp_qos_group_0.bf.qos_info >> 4) & 0xf; + cosmap->internal_dscp = (pcp_qos_group_0.bf.qos_info >> 8) & 0x3f; + cosmap->internal_dp = (pcp_qos_group_0.bf.qos_info >> 14) & 0x3; + } else if (group_id == 1) { + rv = hppe_pcp_qos_group_1_get(dev_id, pcp, &pcp_qos_group_1); + if( rv != SW_OK ) + return rv; + cosmap->internal_pcp = pcp_qos_group_1.bf.qos_info & 7; + cosmap->internal_dei = (pcp_qos_group_1.bf.qos_info >> 3) & 1; + cosmap->internal_pri = (pcp_qos_group_1.bf.qos_info >> 4) & 0xf; + cosmap->internal_dscp = (pcp_qos_group_1.bf.qos_info >> 8) & 0x3f; + cosmap->internal_dp = (pcp_qos_group_1.bf.qos_info >> 14) & 0x3; + } else + return SW_BAD_PARAM; + + return SW_OK; +} + +sw_error_t +adpt_ppe_qos_cosmap_pcp_get(a_uint32_t dev_id, a_uint8_t group_id, + a_uint8_t pcp, fal_qos_cosmap_t *cosmap) +{ + a_uint32_t chip_ver = 0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cosmap); + + chip_ver = adpt_hppe_chip_revision_get(dev_id); + if (chip_ver == CPPE_REVISION) { +#if defined(CPPE) + return adpt_cppe_qos_cosmap_pcp_get(dev_id, group_id, + pcp, cosmap); +#endif + } else { + return adpt_hppe_qos_cosmap_pcp_get(dev_id, group_id, + pcp, cosmap); + } + + return SW_NOT_SUPPORTED; +} + +sw_error_t +adpt_hppe_l0_queue_map_set(a_uint32_t dev_id, + a_uint32_t node_id, + fal_port_t port_id, + fal_qos_scheduler_cfg_t *scheduler_cfg) +{ + union l0_flow_map_tbl_u l0_flow_map_tbl; + union l0_c_sp_cfg_tbl_u l0_c_sp_cfg_tbl; + union l0_e_sp_cfg_tbl_u l0_e_sp_cfg_tbl; + union l0_flow_port_map_tbl_u l0_flow_port_map_tbl; + union l0_comp_cfg_tbl_u l0_comp_cfg_tbl; + a_uint32_t c_sp_id, e_sp_id; + a_uint32_t i, j, k; + + memset(&l0_flow_map_tbl, 0, sizeof(l0_flow_map_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(scheduler_cfg); + if (node_id >= L0_FLOW_MAP_TBL_MAX_ENTRY) + return SW_BAD_PARAM; + + l0_flow_map_tbl.bf.e_drr_wt= scheduler_cfg->e_drr_wt; + l0_flow_map_tbl.bf.c_drr_wt = scheduler_cfg->c_drr_wt; + l0_flow_map_tbl.bf.e_pri = scheduler_cfg->e_pri; + l0_flow_map_tbl.bf.c_pri = scheduler_cfg->c_pri; + l0_flow_map_tbl.bf.sp_id = scheduler_cfg->sp_id; + hppe_l0_flow_map_tbl_set(dev_id, node_id, &l0_flow_map_tbl); + + c_sp_id = scheduler_cfg->sp_id * 8 + scheduler_cfg->c_pri; + l0_c_sp_cfg_tbl.bf.drr_credit_unit = scheduler_cfg->c_drr_unit; + l0_c_sp_cfg_tbl.bf.drr_id = scheduler_cfg->c_drr_id; + hppe_l0_c_sp_cfg_tbl_set(dev_id, c_sp_id, &l0_c_sp_cfg_tbl); + + e_sp_id = scheduler_cfg->sp_id * 8 + scheduler_cfg->e_pri; + l0_e_sp_cfg_tbl.bf.drr_credit_unit = scheduler_cfg->e_drr_unit; + l0_e_sp_cfg_tbl.bf.drr_id = scheduler_cfg->e_drr_id; + hppe_l0_e_sp_cfg_tbl_set(dev_id, e_sp_id, &l0_e_sp_cfg_tbl); + + l0_flow_port_map_tbl.bf.port_num = port_id; + hppe_l0_flow_port_map_tbl_set(dev_id, node_id, &l0_flow_port_map_tbl); + + hppe_l0_comp_cfg_tbl_get(dev_id, node_id, &l0_comp_cfg_tbl); + l0_comp_cfg_tbl.bf.drr_meter_len = scheduler_cfg->drr_frame_mode; + hppe_l0_comp_cfg_tbl_set(dev_id, node_id, &l0_comp_cfg_tbl); + + i = node_id / 32; + j = node_id % 32; + port_queue_map[port_id].bmp[i] |= 1 << j; + for (k = 0; k < 8; k++) { + if (k != port_id) { + port_queue_map[k].bmp[i] &= ~(1 << j); + } + } + + return SW_OK; +} + +sw_error_t +adpt_hppe_l0_queue_map_get(a_uint32_t dev_id, + a_uint32_t node_id, + fal_port_t *port_id, + fal_qos_scheduler_cfg_t *scheduler_cfg) +{ + union l0_flow_map_tbl_u l0_flow_map_tbl; + union l0_c_sp_cfg_tbl_u l0_c_sp_cfg_tbl; + union l0_e_sp_cfg_tbl_u l0_e_sp_cfg_tbl; + union l0_flow_port_map_tbl_u l0_flow_port_map_tbl; + union l0_comp_cfg_tbl_u l0_comp_cfg_tbl; + a_uint32_t c_sp_id, e_sp_id; + + memset(&l0_flow_map_tbl, 0, sizeof(l0_flow_map_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(scheduler_cfg); + if (node_id >= L0_FLOW_MAP_TBL_MAX_ENTRY) + return SW_BAD_PARAM; + + hppe_l0_flow_map_tbl_get(dev_id, node_id, &l0_flow_map_tbl); + scheduler_cfg->e_drr_wt = l0_flow_map_tbl.bf.e_drr_wt; + scheduler_cfg->c_drr_wt = l0_flow_map_tbl.bf.c_drr_wt; + scheduler_cfg->e_pri = l0_flow_map_tbl.bf.e_pri; + scheduler_cfg->c_pri = l0_flow_map_tbl.bf.c_pri; + scheduler_cfg->sp_id = l0_flow_map_tbl.bf.sp_id; + + c_sp_id = scheduler_cfg->sp_id * 8 + scheduler_cfg->c_pri; + hppe_l0_c_sp_cfg_tbl_get(dev_id, c_sp_id, &l0_c_sp_cfg_tbl); + scheduler_cfg->c_drr_unit = l0_c_sp_cfg_tbl.bf.drr_credit_unit; + scheduler_cfg->c_drr_id = l0_c_sp_cfg_tbl.bf.drr_id; + + e_sp_id = scheduler_cfg->sp_id * 8 + scheduler_cfg->e_pri; + hppe_l0_e_sp_cfg_tbl_get(dev_id, e_sp_id, &l0_e_sp_cfg_tbl); + scheduler_cfg->e_drr_unit = l0_e_sp_cfg_tbl.bf.drr_credit_unit; + scheduler_cfg->e_drr_id = l0_e_sp_cfg_tbl.bf.drr_id; + + hppe_l0_flow_port_map_tbl_get(dev_id, node_id, &l0_flow_port_map_tbl); + *port_id = l0_flow_port_map_tbl.bf.port_num; + + hppe_l0_comp_cfg_tbl_get(dev_id, node_id, &l0_comp_cfg_tbl); + scheduler_cfg->drr_frame_mode = l0_comp_cfg_tbl.bf.drr_meter_len; + + return SW_OK; +} + +static sw_error_t +adpt_hppe_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 = SW_OK; + union pcp_qos_group_0_u pcp_qos_group_0; + union pcp_qos_group_1_u pcp_qos_group_1; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cosmap); + + if (pcp >= PCP_QOS_GROUP_0_MAX_ENTRY) + return SW_BAD_PARAM; + + if (group_id == 0) { + pcp_qos_group_0.bf.qos_info = cosmap->internal_pcp | \ + (cosmap->internal_dei << 3) | \ + (cosmap->internal_pri << 4) | \ + (cosmap->internal_dscp << 8) | \ + (cosmap->internal_dp << 14); + rv = hppe_pcp_qos_group_0_set(dev_id, pcp, &pcp_qos_group_0); + } else if (group_id == 1) { + pcp_qos_group_1.bf.qos_info = cosmap->internal_pcp | \ + (cosmap->internal_dei << 3) | \ + (cosmap->internal_pri << 4) | \ + (cosmap->internal_dscp << 8) | \ + (cosmap->internal_dp << 14); + rv = hppe_pcp_qos_group_1_set(dev_id, pcp, &pcp_qos_group_1); + } else + return SW_BAD_PARAM; + + return rv; +} + +sw_error_t +adpt_ppe_qos_cosmap_pcp_set(a_uint32_t dev_id, a_uint8_t group_id, + a_uint8_t pcp, fal_qos_cosmap_t *cosmap) +{ + a_uint32_t chip_ver = 0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cosmap); + + chip_ver = adpt_hppe_chip_revision_get(dev_id); + if (chip_ver == CPPE_REVISION) { +#if defined(CPPE) + return adpt_cppe_qos_cosmap_pcp_set(dev_id, group_id, + pcp, cosmap); +#endif + } else { + return adpt_hppe_qos_cosmap_pcp_set(dev_id, group_id, + pcp, cosmap); + } + + return SW_NOT_SUPPORTED;; +} +sw_error_t +adpt_hppe_qos_port_remark_get(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_remark_enable_t *remark) +{ + sw_error_t rv = SW_OK; + union port_qos_ctrl_u port_qos_ctrl; + + memset(&port_qos_ctrl, 0, sizeof(port_qos_ctrl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(remark); + + rv = hppe_port_qos_ctrl_get(dev_id, port_id, &port_qos_ctrl); + + if( rv != SW_OK ) + return rv; + + remark->pcp_change_en = port_qos_ctrl.bf.port_pcp_change_en; + remark->dei_chage_en = port_qos_ctrl.bf.port_dei_change_en; + remark->dscp_change_en = port_qos_ctrl.bf.port_dscp_change_en; + + return SW_OK; +} + +static sw_error_t +adpt_hppe_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 = SW_OK; + union dscp_qos_group_0_u dscp_qos_group_0; + union dscp_qos_group_1_u dscp_qos_group_1; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cosmap); + + if (dscp >= DSCP_QOS_GROUP_0_MAX_ENTRY) + return SW_BAD_PARAM; + + if (group_id == 0) { + rv = hppe_dscp_qos_group_0_get(dev_id, dscp, &dscp_qos_group_0); + if( rv != SW_OK ) + return rv; + cosmap->internal_pcp = dscp_qos_group_0.bf.qos_info & 7; + cosmap->internal_dei = (dscp_qos_group_0.bf.qos_info >> 3) & 1; + cosmap->internal_pri = (dscp_qos_group_0.bf.qos_info >> 4) & 0xf; + cosmap->internal_dscp = (dscp_qos_group_0.bf.qos_info >> 8) & 0x3f; + cosmap->internal_dp = (dscp_qos_group_0.bf.qos_info >> 14) & 0x3; + } else if (group_id == 1) { + rv = hppe_dscp_qos_group_1_get(dev_id, dscp, &dscp_qos_group_1); + if( rv != SW_OK ) + return rv; + cosmap->internal_pcp = dscp_qos_group_1.bf.qos_info & 7; + cosmap->internal_dei = (dscp_qos_group_1.bf.qos_info >> 3) & 1; + cosmap->internal_pri = (dscp_qos_group_1.bf.qos_info >> 4) & 0xf; + cosmap->internal_dscp = (dscp_qos_group_1.bf.qos_info >> 8) & 0x3f; + cosmap->internal_dp = (dscp_qos_group_1.bf.qos_info >> 14) & 0x3; + } else + return SW_BAD_PARAM; + + return SW_OK; +} + +sw_error_t +adpt_ppe_qos_cosmap_dscp_get(a_uint32_t dev_id, a_uint8_t group_id, + a_uint8_t dscp, fal_qos_cosmap_t *cosmap) +{ + a_uint32_t chip_ver = 0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cosmap); + + chip_ver = adpt_hppe_chip_revision_get(dev_id); + if (chip_ver == CPPE_REVISION) { +#if defined(CPPE) + return adpt_cppe_qos_cosmap_dscp_get(dev_id, group_id, + dscp, cosmap); +#endif + } else { + return adpt_hppe_qos_cosmap_dscp_get(dev_id, group_id, + dscp, cosmap); + } + + return SW_NOT_SUPPORTED; +} + +static sw_error_t +adpt_hppe_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 = SW_OK; + union flow_qos_group_0_u flow_qos_group_0; + union flow_qos_group_1_u flow_qos_group_1; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cosmap); + + if (flow >= FLOW_QOS_GROUP_0_MAX_ENTRY) + return SW_BAD_PARAM; + + if (group_id == 0) { + flow_qos_group_0.bf.qos_info = cosmap->internal_pcp | \ + (cosmap->internal_dei << 3) | \ + (cosmap->internal_pri << 4) | \ + (cosmap->internal_dscp << 8) | \ + (cosmap->internal_dp << 14); + rv = hppe_flow_qos_group_0_set(dev_id, flow, &flow_qos_group_0); + } else if (group_id == 1) { + flow_qos_group_1.bf.qos_info = cosmap->internal_pcp | \ + (cosmap->internal_dei << 3) | \ + (cosmap->internal_pri << 4) | \ + (cosmap->internal_dscp << 8) | \ + (cosmap->internal_dp << 14); + rv = hppe_flow_qos_group_1_set(dev_id, flow, &flow_qos_group_1); + } else + return SW_BAD_PARAM; + + return rv; +} + +sw_error_t +adpt_ppe_qos_cosmap_flow_set(a_uint32_t dev_id, a_uint8_t group_id, + a_uint16_t flow, fal_qos_cosmap_t *cosmap) +{ + a_uint32_t chip_ver = 0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cosmap); + + chip_ver = adpt_hppe_chip_revision_get(dev_id); + if (chip_ver == CPPE_REVISION) { +#if defined(CPPE) + return adpt_cppe_qos_cosmap_flow_set(dev_id, group_id, + flow, cosmap); +#endif + } else { + return adpt_hppe_qos_cosmap_flow_set(dev_id, group_id, + flow, cosmap); + } + + return SW_NOT_SUPPORTED; +} + +static sw_error_t +adpt_hppe_qos_port_group_set(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_group_t *group) +{ + union port_qos_ctrl_u port_qos_ctrl; + + memset(&port_qos_ctrl, 0, sizeof(port_qos_ctrl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(group); + + hppe_port_qos_ctrl_get(dev_id, port_id, &port_qos_ctrl); + + port_qos_ctrl.bf.pcp_qos_group_id = group->pcp_group; + port_qos_ctrl.bf.dscp_qos_group_id = group->dscp_group; + port_qos_ctrl.bf.flow_qos_group_id = group->flow_group; + + return hppe_port_qos_ctrl_set(dev_id, port_id, &port_qos_ctrl); +} + +sw_error_t +adpt_ppe_qos_port_group_set(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_group_t *group) +{ + a_uint32_t chip_ver = 0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(group); + + chip_ver = adpt_hppe_chip_revision_get(dev_id); + if (chip_ver == CPPE_REVISION) { +#if defined(CPPE) + return adpt_cppe_qos_port_group_set(dev_id, port_id, group); +#endif + } else { + return adpt_hppe_qos_port_group_set(dev_id, port_id, group); + } + + return SW_NOT_SUPPORTED; +} + +sw_error_t +adpt_hppe_ring_queue_map_set(a_uint32_t dev_id, + a_uint32_t ring_id, fal_queue_bmp_t *queue_bmp) +{ + union ring_q_map_tbl_u ring_q_map_tbl; + + memset(&ring_q_map_tbl, 0, sizeof(ring_q_map_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(queue_bmp); + if (ring_id >= RING_Q_MAP_TBL_MAX_ENTRY) + return SW_BAD_PARAM; + + memcpy(ring_q_map_tbl.val, queue_bmp->bmp, sizeof(ring_q_map_tbl.val)); + return hppe_ring_q_map_tbl_set(dev_id, ring_id, &ring_q_map_tbl); +} + +static sw_error_t +adpt_hppe_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 = SW_OK; + union dscp_qos_group_0_u dscp_qos_group_0; + union dscp_qos_group_1_u dscp_qos_group_1; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cosmap); + + if (dscp >= DSCP_QOS_GROUP_0_MAX_ENTRY) + return SW_BAD_PARAM; + + if (group_id == 0) { + dscp_qos_group_0.bf.qos_info = cosmap->internal_pcp | \ + (cosmap->internal_dei << 3) | \ + (cosmap->internal_pri << 4) | \ + (cosmap->internal_dscp << 8) | \ + (cosmap->internal_dp << 14); + rv = hppe_dscp_qos_group_0_set(dev_id, dscp, &dscp_qos_group_0); + } else if (group_id == 1) { + dscp_qos_group_1.bf.qos_info = cosmap->internal_pcp | \ + (cosmap->internal_dei << 3) | \ + (cosmap->internal_pri << 4) | \ + (cosmap->internal_dscp << 8) | \ + (cosmap->internal_dp << 14); + rv = hppe_dscp_qos_group_1_set(dev_id, dscp, &dscp_qos_group_1); + } else + return SW_BAD_PARAM; + + return rv; +} + +sw_error_t +adpt_ppe_qos_cosmap_dscp_set(a_uint32_t dev_id, a_uint8_t group_id, + a_uint8_t dscp, fal_qos_cosmap_t *cosmap) +{ + a_uint32_t chip_ver = 0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cosmap); + + chip_ver = adpt_hppe_chip_revision_get(dev_id); + if (chip_ver == CPPE_REVISION) { +#if defined(CPPE) + return adpt_cppe_qos_cosmap_dscp_set(dev_id, group_id, + dscp, cosmap); +#endif + } else { + return adpt_hppe_qos_cosmap_dscp_set(dev_id, group_id, + dscp, cosmap); + } + + return SW_NOT_SUPPORTED; +} + +sw_error_t +adpt_hppe_qos_port_remark_set(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_remark_enable_t *remark) +{ + union port_qos_ctrl_u port_qos_ctrl; + + memset(&port_qos_ctrl, 0, sizeof(port_qos_ctrl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(remark); + + hppe_port_qos_ctrl_get(dev_id, port_id, &port_qos_ctrl); + + port_qos_ctrl.bf.port_pcp_change_en = remark->pcp_change_en; + port_qos_ctrl.bf.port_dei_change_en = remark->dei_chage_en; + port_qos_ctrl.bf.port_dscp_change_en = remark->dscp_change_en; + + return hppe_port_qos_ctrl_set(dev_id, port_id, &port_qos_ctrl); +} +sw_error_t +adpt_hppe_l1_flow_map_set(a_uint32_t dev_id, + a_uint32_t node_id, + fal_port_t port_id, + fal_qos_scheduler_cfg_t *scheduler_cfg) +{ + union l1_flow_map_tbl_u l1_flow_map_tbl; + union l1_c_sp_cfg_tbl_u l1_c_sp_cfg_tbl; + union l1_e_sp_cfg_tbl_u l1_e_sp_cfg_tbl; + union l1_flow_port_map_tbl_u l1_flow_port_map_tbl; + union l1_comp_cfg_tbl_u l1_comp_cfg_tbl; + a_uint32_t c_sp_id, e_sp_id; + + memset(&l1_flow_map_tbl, 0, sizeof(l1_flow_map_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(scheduler_cfg); + if (node_id >= L1_FLOW_MAP_TBL_MAX_ENTRY) + return SW_BAD_PARAM; + + l1_flow_map_tbl.bf.e_drr_wt= scheduler_cfg->e_drr_wt; + l1_flow_map_tbl.bf.c_drr_wt = scheduler_cfg->c_drr_wt; + l1_flow_map_tbl.bf.e_pri = scheduler_cfg->e_pri; + l1_flow_map_tbl.bf.c_pri = scheduler_cfg->c_pri; + l1_flow_map_tbl.bf.sp_id = scheduler_cfg->sp_id; + hppe_l1_flow_map_tbl_set(dev_id, node_id, &l1_flow_map_tbl); + + c_sp_id = scheduler_cfg->sp_id * 8 + scheduler_cfg->c_pri; + l1_c_sp_cfg_tbl.bf.drr_credit_unit = scheduler_cfg->c_drr_unit; + l1_c_sp_cfg_tbl.bf.drr_id = scheduler_cfg->c_drr_id; + hppe_l1_c_sp_cfg_tbl_set(dev_id, c_sp_id, &l1_c_sp_cfg_tbl); + + e_sp_id = scheduler_cfg->sp_id * 8 + scheduler_cfg->e_pri; + l1_e_sp_cfg_tbl.bf.drr_credit_unit = scheduler_cfg->e_drr_unit; + l1_e_sp_cfg_tbl.bf.drr_id = scheduler_cfg->e_drr_id; + hppe_l1_e_sp_cfg_tbl_set(dev_id, e_sp_id, &l1_e_sp_cfg_tbl); + + l1_flow_port_map_tbl.bf.port_num = port_id; + hppe_l1_flow_port_map_tbl_set(dev_id, node_id, &l1_flow_port_map_tbl); + + hppe_l1_comp_cfg_tbl_get(dev_id, node_id, &l1_comp_cfg_tbl); + l1_comp_cfg_tbl.bf.drr_meter_len = scheduler_cfg->drr_frame_mode; + hppe_l1_comp_cfg_tbl_set(dev_id, node_id, &l1_comp_cfg_tbl); + + return SW_OK; +} + +sw_error_t +adpt_hppe_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) +{ + if (level == FAL_QUEUE_SCHEDULER_LEVEL0) + return adpt_hppe_l0_queue_map_set(dev_id, node_id, port_id, scheduler_cfg); + else if ((level == FAL_QUEUE_SCHEDULER_LEVEL1)) + return adpt_hppe_l1_flow_map_set(dev_id, node_id, port_id, scheduler_cfg); + else + return SW_FAIL; +} + +sw_error_t +adpt_hppe_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) +{ + if (level == FAL_QUEUE_SCHEDULER_LEVEL0) + return adpt_hppe_l0_queue_map_get(dev_id, node_id, port_id, scheduler_cfg); + else if ((level == FAL_QUEUE_SCHEDULER_LEVEL1)) + return adpt_hppe_l1_flow_map_get(dev_id, node_id, port_id, scheduler_cfg); + else + return SW_FAIL; +} + +static sw_error_t +adpt_hppe_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 = SW_OK; + union flow_qos_group_0_u flow_qos_group_0; + union flow_qos_group_1_u flow_qos_group_1; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cosmap); + + if (flow >= FLOW_QOS_GROUP_0_MAX_ENTRY) + return SW_BAD_PARAM; + + if (group_id == 0) { + rv = hppe_flow_qos_group_0_get(dev_id, flow, &flow_qos_group_0); + if( rv != SW_OK ) + return rv; + cosmap->internal_pcp = flow_qos_group_0.bf.qos_info & 7; + cosmap->internal_dei = (flow_qos_group_0.bf.qos_info >> 3) & 1; + cosmap->internal_pri = (flow_qos_group_0.bf.qos_info >> 4) & 0xf; + cosmap->internal_dscp = (flow_qos_group_0.bf.qos_info >> 8) & 0x3f; + cosmap->internal_dp = (flow_qos_group_0.bf.qos_info >> 14) & 0x3; + } else if (group_id == 1) { + rv = hppe_flow_qos_group_1_get(dev_id, flow, &flow_qos_group_1); + if( rv != SW_OK ) + return rv; + cosmap->internal_pcp = flow_qos_group_1.bf.qos_info & 7; + cosmap->internal_dei = (flow_qos_group_1.bf.qos_info >> 3) & 1; + cosmap->internal_pri = (flow_qos_group_1.bf.qos_info >> 4) & 0xf; + cosmap->internal_dscp = (flow_qos_group_1.bf.qos_info >> 8) & 0x3f; + cosmap->internal_dp = (flow_qos_group_1.bf.qos_info >> 14) & 0x3; + } else + return SW_BAD_PARAM; + + return SW_OK; +} + +sw_error_t +adpt_ppe_qos_cosmap_flow_get(a_uint32_t dev_id, a_uint8_t group_id, + a_uint16_t flow, fal_qos_cosmap_t *cosmap) +{ + a_uint32_t chip_ver = 0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cosmap); + + chip_ver = adpt_hppe_chip_revision_get(dev_id); + if (chip_ver == CPPE_REVISION) { +#if defined(CPPE) + return adpt_cppe_qos_cosmap_flow_get(dev_id, group_id, + flow, cosmap); +#endif + } else { + return adpt_hppe_qos_cosmap_flow_get(dev_id, group_id, + flow, cosmap); + } + + return SW_NOT_SUPPORTED; +} + +static sw_error_t +adpt_hppe_qos_port_group_get(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_group_t *group) +{ + sw_error_t rv = SW_OK; + union port_qos_ctrl_u port_qos_ctrl; + + memset(&port_qos_ctrl, 0, sizeof(port_qos_ctrl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(group); + + rv = hppe_port_qos_ctrl_get(dev_id, port_id, &port_qos_ctrl); + if( rv != SW_OK ) + return rv; + + group->pcp_group = port_qos_ctrl.bf.pcp_qos_group_id; + group->dscp_group = port_qos_ctrl.bf.dscp_qos_group_id; + group->flow_group = port_qos_ctrl.bf.flow_qos_group_id; + + return SW_OK; +} + +sw_error_t +adpt_ppe_qos_port_group_get(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_group_t *group) +{ + a_uint32_t chip_ver = 0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(group); + + chip_ver = adpt_hppe_chip_revision_get(dev_id); + if (chip_ver == CPPE_REVISION) { +#if defined(CPPE) + return adpt_cppe_qos_port_group_get(dev_id, port_id, group); +#endif + } else { + return adpt_hppe_qos_port_group_get(dev_id, port_id, group); + } + + return SW_NOT_SUPPORTED; +} + +sw_error_t +adpt_hppe_ring_queue_map_get(a_uint32_t dev_id, + a_uint32_t ring_id, fal_queue_bmp_t *queue_bmp) +{ + union ring_q_map_tbl_u ring_q_map_tbl; + + memset(&ring_q_map_tbl, 0, sizeof(ring_q_map_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(queue_bmp); + if (ring_id >= RING_Q_MAP_TBL_MAX_ENTRY) + return SW_BAD_PARAM; + + hppe_ring_q_map_tbl_get(dev_id, ring_id, &ring_q_map_tbl); + memcpy(queue_bmp->bmp, ring_q_map_tbl.val, sizeof(ring_q_map_tbl.val)); + return SW_OK; +} + +sw_error_t +adpt_hppe_port_queues_get(a_uint32_t dev_id, + fal_port_t port_id, fal_queue_bmp_t *queue_bmp) +{ + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(queue_bmp); + + *queue_bmp = port_queue_map[port_id]; + + return SW_OK; +} + +sw_error_t +adpt_hppe_tdm_tick_num_set(a_uint32_t dev_id, a_uint32_t tick_num) +{ + union tdm_depth_cfg_u tdm_depth_cfg; + + ADPT_DEV_ID_CHECK(dev_id); + + tdm_depth_cfg.bf.tdm_depth = tick_num; + return hppe_tdm_depth_cfg_set(dev_id, &tdm_depth_cfg); +} +#ifndef IN_QOS_MINI +sw_error_t +adpt_hppe_tdm_tick_num_get(a_uint32_t dev_id, a_uint32_t *tick_num) +{ + union tdm_depth_cfg_u tdm_depth_cfg; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(tick_num); + + hppe_tdm_depth_cfg_get(dev_id, &tdm_depth_cfg); + *tick_num = tdm_depth_cfg.bf.tdm_depth; + + return SW_OK; +} +#endif +sw_error_t +adpt_hppe_port_scheduler_cfg_reset(a_uint32_t dev_id, + fal_port_t port_id) +{ + ssdk_dt_scheduler_cfg *dt_cfg; + fal_qos_scheduler_cfg_t cfg; + a_uint32_t i; + + dt_cfg = ssdk_bootup_shceduler_cfg_get(dev_id); + if (!dt_cfg) + return SW_FAIL; + + /* L1 shceduler */ + for (i = 0; i < SSDK_L1SCHEDULER_CFG_MAX; i++) { + if (dt_cfg->l1cfg[i].valid && dt_cfg->l1cfg[i].port_id == port_id) { + cfg.sp_id = dt_cfg->l1cfg[i].port_id; + cfg.c_pri = dt_cfg->l1cfg[i].cpri; + cfg.e_pri = dt_cfg->l1cfg[i].epri; + cfg.c_drr_id = dt_cfg->l1cfg[i].cdrr_id; + cfg.e_drr_id = dt_cfg->l1cfg[i].edrr_id; + cfg.c_drr_wt = 1; + cfg.e_drr_wt = 1; + adpt_hppe_queue_scheduler_set(dev_id, i, 1, + dt_cfg->l1cfg[i].port_id, &cfg); + } + } + + /* L0 shceduler */ + for (i = 0; i < SSDK_L0SCHEDULER_CFG_MAX; i++) { + if (dt_cfg->l0cfg[i].valid && dt_cfg->l0cfg[i].port_id == port_id) { + cfg.sp_id = dt_cfg->l0cfg[i].sp_id; + cfg.c_pri = dt_cfg->l0cfg[i].cpri; + cfg.e_pri = dt_cfg->l0cfg[i].epri; + cfg.c_drr_id = dt_cfg->l0cfg[i].cdrr_id; + cfg.e_drr_id = dt_cfg->l0cfg[i].edrr_id; + cfg.c_drr_wt = 1; + cfg.e_drr_wt = 1; + adpt_hppe_queue_scheduler_set(dev_id, i, + 0, dt_cfg->l0cfg[i].port_id, &cfg); + } + } + + return SW_OK; +} + +sw_error_t +adpt_hppe_port_scheduler_cfg_set(a_uint32_t dev_id, + a_uint32_t tick_index, + fal_port_scheduler_cfg_t *cfg) +{ + union psch_tdm_cfg_tbl_u psch_tdm_cfg; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cfg); + + psch_tdm_cfg.bf.ens_port_bitmap = cfg->en_scheduler_port_bmp; + psch_tdm_cfg.bf.ens_port = cfg->en_scheduler_port; + psch_tdm_cfg.bf.des_port = cfg->de_scheduler_port; + return hppe_psch_tdm_cfg_tbl_set(dev_id, tick_index, &psch_tdm_cfg); +} +#ifndef IN_QOS_MINI +sw_error_t +adpt_hppe_port_scheduler_cfg_get(a_uint32_t dev_id, + a_uint32_t tick_index, + fal_port_scheduler_cfg_t *cfg) +{ + union psch_tdm_cfg_tbl_u psch_tdm_cfg; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cfg); + + hppe_psch_tdm_cfg_tbl_get(dev_id, tick_index, &psch_tdm_cfg); + cfg->en_scheduler_port_bmp = psch_tdm_cfg.bf.ens_port_bitmap; + cfg->en_scheduler_port = psch_tdm_cfg.bf.ens_port; + cfg->de_scheduler_port = psch_tdm_cfg.bf.des_port; + + return SW_OK; +} +#endif +sw_error_t +adpt_hppe_scheduler_dequeue_ctrl_get(a_uint32_t dev_id, + a_uint32_t queue_id, + a_bool_t *enable) +{ + union deq_dis_tbl_u deq; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + + hppe_deq_dis_tbl_get(dev_id, queue_id, &deq); + *enable = !(deq.bf.deq_dis); + + return SW_OK; +} + +sw_error_t +adpt_hppe_scheduler_dequeue_ctrl_set(a_uint32_t dev_id, + a_uint32_t queue_id, + a_bool_t enable) +{ + union deq_dis_tbl_u deq; + + ADPT_DEV_ID_CHECK(dev_id); + + deq.bf.deq_dis = !enable; + return hppe_deq_dis_tbl_set(dev_id, queue_id, &deq); +} + +sw_error_t +adpt_hppe_port_scheduler_resource_get(a_uint32_t dev_id, + fal_port_t port_id, + fal_portscheduler_resource_t *cfg) +{ + ssdk_dt_scheduler_cfg *dt_cfg; + ssdk_dt_portscheduler_cfg *port_resource; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(cfg); + + if (port_id >= SSDK_MAX_PORT_NUM) + return SW_BAD_PARAM; + + dt_cfg = ssdk_bootup_shceduler_cfg_get(dev_id); + if (!dt_cfg) + return SW_NOT_SUPPORTED; + + port_resource = &dt_cfg->pool[port_id]; + cfg->ucastq_start = port_resource->ucastq_start; + cfg->ucastq_num = port_resource->ucastq_end - port_resource->ucastq_start + 1; + cfg->mcastq_start = port_resource->mcastq_start; + cfg->mcastq_num = port_resource->mcastq_end - port_resource->mcastq_start + 1; + cfg->l0sp_start = port_resource->l0sp_start; + cfg->l0sp_num = port_resource->l0sp_end - port_resource->l0sp_start + 1; + cfg->l0cdrr_start = port_resource->l0cdrr_start; + cfg->l0cdrr_num = port_resource->l0cdrr_end - port_resource->l0cdrr_start + 1; + cfg->l0edrr_start = port_resource->l0edrr_start; + cfg->l0edrr_num = port_resource->l0edrr_end - port_resource->l0edrr_start + 1; + cfg->l1sp_start = port_id; + cfg->l1sp_num = 1; + cfg->l1cdrr_start = port_resource->l1cdrr_start; + cfg->l1cdrr_num = port_resource->l1cdrr_end - port_resource->l1cdrr_start + 1; + cfg->l1edrr_start = port_resource->l1edrr_start; + cfg->l1edrr_num = port_resource->l1edrr_end - port_resource->l1edrr_start + 1; + + return SW_OK; +} + +void adpt_hppe_qos_func_bitmap_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_qos_func_bitmap = ((1 << FUNC_QOS_PORT_PRI_SET) | + (1 << FUNC_QOS_PORT_PRI_GET) | + (1 << FUNC_QOS_COSMAP_PCP_GET) | + (1 << FUNC_QUEUE_SCHEDULER_SET) | + (1 << FUNC_QUEUE_SCHEDULER_GET) | + (1 << FUNC_PORT_QUEUES_GET) | + (1 << FUNC_QOS_COSMAP_PCP_SET) | + (1 << FUNC_QOS_PORT_REMARK_GET) | + (1 << FUNC_QOS_COSMAP_DSCP_GET) | + (1 << FUNC_QOS_COSMAP_FLOW_SET) | + (1 << FUNC_QOS_PORT_GROUP_SET) | + (1 << FUNC_RING_QUEUE_MAP_SET) | + (1 << FUNC_QOS_COSMAP_DSCP_SET) | + (1 << FUNC_QOS_PORT_REMARK_SET) | + (1 << FUNC_QOS_COSMAP_FLOW_GET) | + (1 << FUNC_QOS_PORT_GROUP_GET) | + (1 << FUNC_RING_QUEUE_MAP_GET) | + (1 << FUNC_TDM_TICK_NUM_SET) | + (1 << FUNC_TDM_TICK_NUM_GET) | + (1 << FUNC_PORT_SCHEDULER_CFG_SET) | + (1 << FUNC_PORT_SCHEDULER_CFG_GET) | + (1 << FUNC_SCHEDULER_DEQUEUE_CTRL_GET) | + (1 << FUNC_SCHEDULER_DEQUEUE_CTRL_SET) | + (1 << FUNC_QOS_PORT_MODE_PRI_GET) | + (1 << FUNC_QOS_PORT_MODE_PRI_SET) | + (1 << FUNC_QOS_PORT_SCHEDULER_CFG_RESET) | + (1 << FUNC_QOS_PORT_SCHEDULER_RESOURCE_GET)); + return; +} + +static void adpt_hppe_qos_func_unregister(a_uint32_t dev_id, adpt_api_t *p_adpt_api) +{ + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_qos_port_pri_set = NULL; + p_adpt_api->adpt_qos_port_pri_get = NULL; + p_adpt_api->adpt_qos_cosmap_pcp_get = NULL; + p_adpt_api->adpt_queue_scheduler_set = NULL; + p_adpt_api->adpt_queue_scheduler_get = NULL; + p_adpt_api->adpt_port_queues_get = NULL; + p_adpt_api->adpt_qos_cosmap_pcp_set = NULL; + p_adpt_api->adpt_qos_port_remark_get = NULL; + p_adpt_api->adpt_qos_cosmap_dscp_get = NULL; + p_adpt_api->adpt_qos_cosmap_flow_set = NULL; + p_adpt_api->adpt_qos_port_group_set = NULL; + p_adpt_api->adpt_ring_queue_map_set = NULL; + p_adpt_api->adpt_qos_cosmap_dscp_set = NULL; + p_adpt_api->adpt_qos_port_remark_set = NULL; + p_adpt_api->adpt_qos_cosmap_flow_get = NULL; + p_adpt_api->adpt_qos_port_group_get = NULL; + p_adpt_api->adpt_ring_queue_map_get = NULL; + p_adpt_api->adpt_tdm_tick_num_set = NULL; + p_adpt_api->adpt_tdm_tick_num_get = NULL; + p_adpt_api->adpt_port_scheduler_cfg_set = NULL; + p_adpt_api->adpt_port_scheduler_cfg_get = NULL; + p_adpt_api->adpt_scheduler_dequeue_ctrl_get = NULL; + p_adpt_api->adpt_scheduler_dequeue_ctrl_set = NULL; + p_adpt_api->adpt_qos_port_mode_pri_get = NULL; + p_adpt_api->adpt_qos_port_mode_pri_set = NULL; + p_adpt_api->adpt_port_scheduler_cfg_reset = NULL; + p_adpt_api->adpt_port_scheduler_resource_get = NULL; + + return; +} + +sw_error_t adpt_hppe_qos_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return SW_FAIL; + + adpt_hppe_qos_func_unregister(dev_id, p_adpt_api); + + if (p_adpt_api->adpt_qos_func_bitmap & (1 << FUNC_QOS_PORT_PRI_SET)) + p_adpt_api->adpt_qos_port_pri_set = adpt_ppe_qos_port_pri_set; + if (p_adpt_api->adpt_qos_func_bitmap & (1 << FUNC_QOS_PORT_PRI_GET)) + p_adpt_api->adpt_qos_port_pri_get = adpt_ppe_qos_port_pri_get; + if (p_adpt_api->adpt_qos_func_bitmap & (1 << FUNC_QOS_COSMAP_PCP_GET)) + p_adpt_api->adpt_qos_cosmap_pcp_get = adpt_ppe_qos_cosmap_pcp_get; + if (p_adpt_api->adpt_qos_func_bitmap & (1 << FUNC_QUEUE_SCHEDULER_SET)) + p_adpt_api->adpt_queue_scheduler_set = adpt_hppe_queue_scheduler_set; + if (p_adpt_api->adpt_qos_func_bitmap & (1 << FUNC_QUEUE_SCHEDULER_GET)) + p_adpt_api->adpt_queue_scheduler_get = adpt_hppe_queue_scheduler_get; + if (p_adpt_api->adpt_qos_func_bitmap & (1 << FUNC_PORT_QUEUES_GET)) + p_adpt_api->adpt_port_queues_get = adpt_hppe_port_queues_get; + if (p_adpt_api->adpt_qos_func_bitmap & (1 << FUNC_QOS_COSMAP_PCP_SET)) + p_adpt_api->adpt_qos_cosmap_pcp_set = adpt_ppe_qos_cosmap_pcp_set; + if (p_adpt_api->adpt_qos_func_bitmap & (1 << FUNC_QOS_PORT_REMARK_GET)) + p_adpt_api->adpt_qos_port_remark_get = adpt_hppe_qos_port_remark_get; + if (p_adpt_api->adpt_qos_func_bitmap & (1 << FUNC_QOS_COSMAP_DSCP_GET)) + p_adpt_api->adpt_qos_cosmap_dscp_get = adpt_ppe_qos_cosmap_dscp_get; + if (p_adpt_api->adpt_qos_func_bitmap & (1 << FUNC_QOS_COSMAP_FLOW_SET)) + p_adpt_api->adpt_qos_cosmap_flow_set = adpt_ppe_qos_cosmap_flow_set; + if (p_adpt_api->adpt_qos_func_bitmap & (1 << FUNC_QOS_PORT_GROUP_SET)) + p_adpt_api->adpt_qos_port_group_set = adpt_ppe_qos_port_group_set; + if (p_adpt_api->adpt_qos_func_bitmap & (1 << FUNC_RING_QUEUE_MAP_SET)) + p_adpt_api->adpt_ring_queue_map_set = adpt_hppe_ring_queue_map_set; + if (p_adpt_api->adpt_qos_func_bitmap & (1 << FUNC_QOS_COSMAP_DSCP_SET)) + p_adpt_api->adpt_qos_cosmap_dscp_set = adpt_ppe_qos_cosmap_dscp_set; + if (p_adpt_api->adpt_qos_func_bitmap & (1 << FUNC_QOS_PORT_REMARK_SET)) + p_adpt_api->adpt_qos_port_remark_set = adpt_hppe_qos_port_remark_set; + if (p_adpt_api->adpt_qos_func_bitmap & (1 << FUNC_QOS_COSMAP_FLOW_GET)) + p_adpt_api->adpt_qos_cosmap_flow_get = adpt_ppe_qos_cosmap_flow_get; + if (p_adpt_api->adpt_qos_func_bitmap & (1 << FUNC_QOS_PORT_GROUP_GET)) + p_adpt_api->adpt_qos_port_group_get = adpt_ppe_qos_port_group_get; + if (p_adpt_api->adpt_qos_func_bitmap & (1 << FUNC_RING_QUEUE_MAP_GET)) + p_adpt_api->adpt_ring_queue_map_get = adpt_hppe_ring_queue_map_get; + if (p_adpt_api->adpt_qos_func_bitmap & (1 << FUNC_TDM_TICK_NUM_SET)) + p_adpt_api->adpt_tdm_tick_num_set = adpt_hppe_tdm_tick_num_set; +#ifndef IN_QOS_MINI + if (p_adpt_api->adpt_qos_func_bitmap & (1 << FUNC_TDM_TICK_NUM_GET)) + p_adpt_api->adpt_tdm_tick_num_get = adpt_hppe_tdm_tick_num_get; +#endif + if (p_adpt_api->adpt_qos_func_bitmap & (1 << FUNC_PORT_SCHEDULER_CFG_SET)) + p_adpt_api->adpt_port_scheduler_cfg_set = adpt_hppe_port_scheduler_cfg_set; +#ifndef IN_QOS_MINI + if (p_adpt_api->adpt_qos_func_bitmap & (1 << FUNC_PORT_SCHEDULER_CFG_GET)) + p_adpt_api->adpt_port_scheduler_cfg_get = adpt_hppe_port_scheduler_cfg_get; +#endif + if (p_adpt_api->adpt_qos_func_bitmap & (1 << FUNC_SCHEDULER_DEQUEUE_CTRL_GET)) + p_adpt_api->adpt_scheduler_dequeue_ctrl_get = adpt_hppe_scheduler_dequeue_ctrl_get; + if (p_adpt_api->adpt_qos_func_bitmap & (1 << FUNC_SCHEDULER_DEQUEUE_CTRL_SET)) + p_adpt_api->adpt_scheduler_dequeue_ctrl_set = adpt_hppe_scheduler_dequeue_ctrl_set; +#ifndef IN_QOS_MINI + if (p_adpt_api->adpt_qos_func_bitmap & (1 << FUNC_QOS_PORT_MODE_PRI_GET)) + p_adpt_api->adpt_qos_port_mode_pri_get = adpt_hppe_qos_port_mode_pri_get; + if (p_adpt_api->adpt_qos_func_bitmap & (1 << FUNC_QOS_PORT_MODE_PRI_SET)) + p_adpt_api->adpt_qos_port_mode_pri_set = adpt_hppe_qos_port_mode_pri_set; +#endif + if (p_adpt_api->adpt_qos_func_bitmap & (1 << FUNC_QOS_PORT_SCHEDULER_CFG_RESET)) + p_adpt_api->adpt_port_scheduler_cfg_reset = adpt_hppe_port_scheduler_cfg_reset; + if (p_adpt_api->adpt_qos_func_bitmap & (1 << FUNC_QOS_PORT_SCHEDULER_RESOURCE_GET)) + p_adpt_api->adpt_port_scheduler_resource_get = adpt_hppe_port_scheduler_resource_get; + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_rss_hash.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_rss_hash.c new file mode 100755 index 000000000..1834b3950 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_rss_hash.c @@ -0,0 +1,296 @@ +/* + * 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. + */ + + +/** + * @defgroup + * @{ + */ +#include "sw.h" +#include "hppe_rss_reg.h" +#include "hppe_rss.h" +#include "adpt.h" + +sw_error_t +adpt_hppe_rss_hash_config_set(a_uint32_t dev_id, fal_rss_hash_mode_t mode, + fal_rss_hash_config_t * config) +{ + a_uint32_t index; + union rss_hash_mask_reg_u rss_hash_mask_ipv6 = {0}; + union rss_hash_seed_reg_u rss_hash_seed_ipv6 = {0}; + union rss_hash_mix_reg_u rss_hash_mix_ipv6[11] = {0}; + union rss_hash_fin_reg_u rss_hash_fin_ipv6[5] = {0}; + union rss_hash_mask_ipv4_reg_u rss_hash_mask_ipv4 = {0}; + union rss_hash_seed_ipv4_reg_u rss_hash_seed_ipv4 = {0}; + union rss_hash_mix_ipv4_reg_u rss_hash_mix_ipv4[5] = {0}; + union rss_hash_fin_ipv4_reg_u rss_hash_fin_ipv4[5] = {0}; + + ADPT_DEV_ID_CHECK(dev_id); + + if (mode == FAL_RSS_HASH_IPV4V6 || mode == FAL_RSS_HASH_IPV4ONLY) + { + rss_hash_mask_ipv4.bf.mask = config->hash_mask & 0x1fffff; + rss_hash_mask_ipv4.bf.fragment = config->hash_fragment_mode; + + rss_hash_seed_ipv4.bf.seed = config->hash_seed; + + rss_hash_mix_ipv4[0].bf.hash_mix = config->hash_sip_mix & 0x1f; + rss_hash_mix_ipv4[1].bf.hash_mix = config->hash_dip_mix & 0x1f; + rss_hash_mix_ipv4[2].bf.hash_mix = config->hash_protocol_mix & 0x1f; + rss_hash_mix_ipv4[3].bf.hash_mix = config->hash_dport_mix & 0x1f; + rss_hash_mix_ipv4[4].bf.hash_mix = config->hash_sport_mix & 0x1f; + + rss_hash_fin_ipv4[0].bf.fin_inner = config->hash_fin_inner & 0x1f; + rss_hash_fin_ipv4[0].bf.fin_outer = config->hash_fin_outer & 0x1f; + rss_hash_fin_ipv4[1].bf.fin_inner = (config->hash_fin_inner >> 0x5) & 0x1f; + rss_hash_fin_ipv4[1].bf.fin_outer = (config->hash_fin_outer >> 0x5) & 0x1f; + rss_hash_fin_ipv4[2].bf.fin_inner = (config->hash_fin_inner >> 0xa) & 0x1f; + rss_hash_fin_ipv4[2].bf.fin_outer = (config->hash_fin_outer >> 0xa) & 0x1f; + rss_hash_fin_ipv4[3].bf.fin_inner = (config->hash_fin_inner >> 0xf) & 0x1f; + rss_hash_fin_ipv4[3].bf.fin_outer = (config->hash_fin_outer >> 0xf) & 0x1f; + rss_hash_fin_ipv4[4].bf.fin_inner = (config->hash_fin_inner >> 0x14) & 0x1f; + rss_hash_fin_ipv4[4].bf.fin_outer = (config->hash_fin_outer >> 0x14) & 0x1f; + + SW_RTN_ON_ERROR(hppe_rss_hash_mask_ipv4_reg_set(dev_id, &rss_hash_mask_ipv4)); + SW_RTN_ON_ERROR(hppe_rss_hash_seed_ipv4_reg_set(dev_id, &rss_hash_seed_ipv4)); + for (index = 0; index < 5; index++) + SW_RTN_ON_ERROR(hppe_rss_hash_mix_ipv4_reg_set(dev_id, index, &rss_hash_mix_ipv4[index])); + for (index = 0; index < 5; index++) + SW_RTN_ON_ERROR(hppe_rss_hash_fin_ipv4_reg_set(dev_id, index, &rss_hash_fin_ipv4[index])); + } + + if (mode == FAL_RSS_HASH_IPV4V6 || mode == FAL_RSS_HASH_IPV6ONLY) + { + rss_hash_mask_ipv6.bf.mask = config->hash_mask & 0x1fffff; + rss_hash_mask_ipv6.bf.fragment = config->hash_fragment_mode; + + rss_hash_seed_ipv6.bf.seed = config->hash_seed; + + rss_hash_mix_ipv6[0].bf.hash_mix = config->hash_sip_mix & 0x1f; + rss_hash_mix_ipv6[1].bf.hash_mix = (config->hash_sip_mix >> 0x5) & 0x1f; + rss_hash_mix_ipv6[2].bf.hash_mix = (config->hash_sip_mix >> 0xa) & 0x1f; + rss_hash_mix_ipv6[3].bf.hash_mix = (config->hash_sip_mix >> 0xf) & 0x1f; + + rss_hash_mix_ipv6[4].bf.hash_mix = config->hash_dip_mix & 0x1f; + rss_hash_mix_ipv6[5].bf.hash_mix = (config->hash_dip_mix >> 0x5) & 0x1f; + rss_hash_mix_ipv6[6].bf.hash_mix = (config->hash_dip_mix >> 0xa) & 0x1f; + rss_hash_mix_ipv6[7].bf.hash_mix = (config->hash_dip_mix >> 0xf) & 0x1f; + + rss_hash_mix_ipv6[8].bf.hash_mix = config->hash_protocol_mix & 0x1f; + rss_hash_mix_ipv6[9].bf.hash_mix = config->hash_dport_mix & 0x1f; + rss_hash_mix_ipv6[10].bf.hash_mix = config->hash_sport_mix & 0x1f; + + rss_hash_fin_ipv6[0].bf.fin_inner = config->hash_fin_inner & 0x1f; + rss_hash_fin_ipv6[0].bf.fin_outer = config->hash_fin_outer & 0x1f; + rss_hash_fin_ipv6[1].bf.fin_inner = (config->hash_fin_inner >> 0x5) & 0x1f; + rss_hash_fin_ipv6[1].bf.fin_outer = (config->hash_fin_outer >> 0x5) & 0x1f; + rss_hash_fin_ipv6[2].bf.fin_inner = (config->hash_fin_inner >> 0xa) & 0x1f; + rss_hash_fin_ipv6[2].bf.fin_outer = (config->hash_fin_outer >> 0xa) & 0x1f; + rss_hash_fin_ipv6[3].bf.fin_inner = (config->hash_fin_inner >> 0xf) & 0x1f; + rss_hash_fin_ipv6[3].bf.fin_outer = (config->hash_fin_outer >> 0xf) & 0x1f; + rss_hash_fin_ipv6[4].bf.fin_inner = (config->hash_fin_inner >> 0x14) & 0x1f; + rss_hash_fin_ipv6[4].bf.fin_outer = (config->hash_fin_outer >> 0x14) & 0x1f; + + SW_RTN_ON_ERROR(hppe_rss_hash_mask_reg_set(dev_id, &rss_hash_mask_ipv6)); + SW_RTN_ON_ERROR(hppe_rss_hash_seed_reg_set(dev_id, &rss_hash_seed_ipv6)); + for (index = 0; index < 11; index++) + SW_RTN_ON_ERROR(hppe_rss_hash_mix_reg_set(dev_id, index, &rss_hash_mix_ipv6[index])); + for (index = 0; index < 5; index++) + SW_RTN_ON_ERROR(hppe_rss_hash_fin_reg_set(dev_id, index, &rss_hash_fin_ipv6[index])); + } + + return SW_OK; +} + +sw_error_t +adpt_hppe_rss_hash_config_get(a_uint32_t dev_id, fal_rss_hash_mode_t mode, + fal_rss_hash_config_t * config) +{ + a_uint32_t index; + union rss_hash_mask_reg_u rss_hash_mask_ipv6 = {0}; + union rss_hash_seed_reg_u rss_hash_seed_ipv6 = {0}; + union rss_hash_mix_reg_u rss_hash_mix_ipv6[11] = {0}; + union rss_hash_fin_reg_u rss_hash_fin_ipv6[5] = {0}; + union rss_hash_mask_ipv4_reg_u rss_hash_mask_ipv4 = {0}; + union rss_hash_seed_ipv4_reg_u rss_hash_seed_ipv4 = {0}; + union rss_hash_mix_ipv4_reg_u rss_hash_mix_ipv4[5] = {0}; + union rss_hash_fin_ipv4_reg_u rss_hash_fin_ipv4[5] = {0}; + + ADPT_DEV_ID_CHECK(dev_id); + + SW_RTN_ON_ERROR(hppe_rss_hash_mask_ipv4_reg_get(dev_id, &rss_hash_mask_ipv4)); + SW_RTN_ON_ERROR(hppe_rss_hash_seed_ipv4_reg_get(dev_id, &rss_hash_seed_ipv4)); + for (index = 0; index < 5; index++) + SW_RTN_ON_ERROR(hppe_rss_hash_mix_ipv4_reg_get(dev_id, index, &rss_hash_mix_ipv4[index])); + for (index = 0; index < 5; index++) + SW_RTN_ON_ERROR(hppe_rss_hash_fin_ipv4_reg_get(dev_id, index, &rss_hash_fin_ipv4[index])); + + SW_RTN_ON_ERROR(hppe_rss_hash_mask_reg_get(dev_id, &rss_hash_mask_ipv6)); + SW_RTN_ON_ERROR(hppe_rss_hash_seed_reg_get(dev_id, &rss_hash_seed_ipv6)); + for (index = 0; index < 11; index++) + SW_RTN_ON_ERROR(hppe_rss_hash_mix_reg_get(dev_id, index, &rss_hash_mix_ipv6[index])); + for (index = 0; index < 5; index++) + SW_RTN_ON_ERROR(hppe_rss_hash_fin_reg_get(dev_id, index, &rss_hash_fin_ipv6[index])); + + if (mode == FAL_RSS_HASH_IPV4ONLY) + { + config->hash_mask = rss_hash_mask_ipv4.bf.mask; + config->hash_fragment_mode = rss_hash_mask_ipv4.bf.fragment; + config->hash_seed = rss_hash_seed_ipv4.bf.seed; + config->hash_sip_mix = rss_hash_mix_ipv4[0].bf.hash_mix; + config->hash_dip_mix = rss_hash_mix_ipv4[1].bf.hash_mix; + config->hash_protocol_mix = rss_hash_mix_ipv4[2].bf.hash_mix; + config->hash_dport_mix = rss_hash_mix_ipv4[3].bf.hash_mix; + config->hash_sport_mix = rss_hash_mix_ipv4[4].bf.hash_mix; + config->hash_fin_inner = rss_hash_fin_ipv4[0].bf.fin_inner + + (rss_hash_fin_ipv4[1].bf.fin_inner << 0x5) + + (rss_hash_fin_ipv4[2].bf.fin_inner << 0xa) + + (rss_hash_fin_ipv4[3].bf.fin_inner << 0xf) + + (rss_hash_fin_ipv4[4].bf.fin_inner << 0x14); + config->hash_fin_outer = rss_hash_fin_ipv4[0].bf.fin_outer + + (rss_hash_fin_ipv4[1].bf.fin_outer << 0x5) + + (rss_hash_fin_ipv4[2].bf.fin_outer << 0xa) + + (rss_hash_fin_ipv4[3].bf.fin_outer << 0xf) + + (rss_hash_fin_ipv4[4].bf.fin_outer << 0x14); + } + else if (mode == FAL_RSS_HASH_IPV6ONLY) + { + config->hash_mask = rss_hash_mask_ipv6.bf.mask; + config->hash_fragment_mode = rss_hash_mask_ipv6.bf.fragment; + config->hash_seed = rss_hash_seed_ipv6.bf.seed; + config->hash_sip_mix = rss_hash_mix_ipv6[0].bf.hash_mix + + (rss_hash_mix_ipv6[1].bf.hash_mix << 0x5) + + (rss_hash_mix_ipv6[2].bf.hash_mix << 0xa) + + (rss_hash_mix_ipv6[3].bf.hash_mix << 0xf); + config->hash_dip_mix = rss_hash_mix_ipv6[4].bf.hash_mix + + (rss_hash_mix_ipv6[5].bf.hash_mix << 0x5) + + (rss_hash_mix_ipv6[6].bf.hash_mix << 0xa) + + (rss_hash_mix_ipv6[7].bf.hash_mix << 0xf); + config->hash_protocol_mix = rss_hash_mix_ipv6[8].bf.hash_mix; + config->hash_dport_mix = rss_hash_mix_ipv6[9].bf.hash_mix; + config->hash_sport_mix = rss_hash_mix_ipv6[10].bf.hash_mix; + config->hash_fin_inner = rss_hash_fin_ipv6[0].bf.fin_inner + + (rss_hash_fin_ipv6[1].bf.fin_inner << 0x5) + + (rss_hash_fin_ipv6[2].bf.fin_inner << 0xa) + + (rss_hash_fin_ipv6[3].bf.fin_inner << 0xf) + + (rss_hash_fin_ipv6[4].bf.fin_inner << 0x14); + config->hash_fin_outer = rss_hash_fin_ipv6[0].bf.fin_outer + + (rss_hash_fin_ipv6[1].bf.fin_outer << 0x5) + + (rss_hash_fin_ipv6[2].bf.fin_outer << 0xa) + + (rss_hash_fin_ipv6[3].bf.fin_outer << 0xf) + + (rss_hash_fin_ipv6[4].bf.fin_outer << 0x14); + } + else + { + if ((rss_hash_mask_ipv4.bf.mask == rss_hash_mask_ipv6.bf.mask) && + (rss_hash_mask_ipv4.bf.fragment == rss_hash_mask_ipv6.bf.fragment) && + (rss_hash_seed_ipv4.bf.seed == rss_hash_seed_ipv6.bf.seed) && + (rss_hash_mix_ipv4[0].bf.hash_mix == rss_hash_mix_ipv6[0].bf.hash_mix) && + (rss_hash_mix_ipv4[1].bf.hash_mix == rss_hash_mix_ipv6[4].bf.hash_mix) && + (rss_hash_mix_ipv4[2].bf.hash_mix == rss_hash_mix_ipv6[8].bf.hash_mix) && + (rss_hash_mix_ipv4[3].bf.hash_mix == rss_hash_mix_ipv6[9].bf.hash_mix) && + (rss_hash_mix_ipv4[4].bf.hash_mix == rss_hash_mix_ipv6[10].bf.hash_mix) && + (rss_hash_fin_ipv4[0].bf.fin_inner == rss_hash_fin_ipv6[0].bf.fin_inner) && + (rss_hash_fin_ipv4[1].bf.fin_inner == rss_hash_fin_ipv6[1].bf.fin_inner) && + (rss_hash_fin_ipv4[2].bf.fin_inner == rss_hash_fin_ipv6[2].bf.fin_inner) && + (rss_hash_fin_ipv4[3].bf.fin_inner == rss_hash_fin_ipv6[3].bf.fin_inner) && + (rss_hash_fin_ipv4[4].bf.fin_inner == rss_hash_fin_ipv6[4].bf.fin_inner) && + (rss_hash_fin_ipv4[0].bf.fin_outer == rss_hash_fin_ipv6[0].bf.fin_outer) && + (rss_hash_fin_ipv4[1].bf.fin_outer == rss_hash_fin_ipv6[1].bf.fin_outer) && + (rss_hash_fin_ipv4[2].bf.fin_outer == rss_hash_fin_ipv6[2].bf.fin_outer) && + (rss_hash_fin_ipv4[3].bf.fin_outer == rss_hash_fin_ipv6[3].bf.fin_outer) && + (rss_hash_fin_ipv4[4].bf.fin_outer == rss_hash_fin_ipv6[4].bf.fin_outer)) + { + config->hash_mask = rss_hash_mask_ipv6.bf.mask; + config->hash_fragment_mode = rss_hash_mask_ipv6.bf.fragment; + config->hash_seed = rss_hash_seed_ipv6.bf.seed; + config->hash_sip_mix = rss_hash_mix_ipv6[0].bf.hash_mix + + (rss_hash_mix_ipv6[1].bf.hash_mix << 0x5) + + (rss_hash_mix_ipv6[2].bf.hash_mix << 0xa) + + (rss_hash_mix_ipv6[3].bf.hash_mix << 0xf); + config->hash_dip_mix = rss_hash_mix_ipv6[4].bf.hash_mix + + (rss_hash_mix_ipv6[5].bf.hash_mix << 0x5) + + (rss_hash_mix_ipv6[6].bf.hash_mix << 0xa) + + (rss_hash_mix_ipv6[7].bf.hash_mix << 0xf); + config->hash_protocol_mix = rss_hash_mix_ipv6[8].bf.hash_mix; + config->hash_dport_mix = rss_hash_mix_ipv6[9].bf.hash_mix; + config->hash_sport_mix = rss_hash_mix_ipv6[10].bf.hash_mix; + config->hash_fin_inner = rss_hash_fin_ipv6[0].bf.fin_inner + + (rss_hash_fin_ipv6[1].bf.fin_inner << 0x5) + + (rss_hash_fin_ipv6[2].bf.fin_inner << 0xa) + + (rss_hash_fin_ipv6[3].bf.fin_inner << 0xf) + + (rss_hash_fin_ipv6[4].bf.fin_inner << 0x14); + config->hash_fin_outer = rss_hash_fin_ipv6[0].bf.fin_outer + + (rss_hash_fin_ipv6[1].bf.fin_outer << 0x5) + + (rss_hash_fin_ipv6[2].bf.fin_outer << 0xa) + + (rss_hash_fin_ipv6[3].bf.fin_outer << 0xf) + + (rss_hash_fin_ipv6[4].bf.fin_outer << 0x14); + } + else + return SW_FAIL; + } + + return SW_OK; +} + +void adpt_hppe_rss_hash_func_bitmap_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_rss_hash_func_bitmap = ((1 << FUNC_RSS_HASH_CONFIG_SET) | + (1 << FUNC_RSS_HASH_CONFIG_GET)); + + return; +} + +static void adpt_hppe_rss_hash_func_unregister(a_uint32_t dev_id, adpt_api_t *p_adpt_api) +{ + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_rss_hash_config_set = NULL; + p_adpt_api->adpt_rss_hash_config_get = NULL; + + return; +} + +sw_error_t adpt_hppe_rss_hash_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return SW_FAIL; + + adpt_hppe_rss_hash_func_unregister(dev_id, p_adpt_api); + + if(p_adpt_api->adpt_rss_hash_func_bitmap & (1<adpt_rss_hash_config_set = adpt_hppe_rss_hash_config_set; + if(p_adpt_api->adpt_rss_hash_func_bitmap & (1<adpt_rss_hash_config_get = adpt_hppe_rss_hash_config_get; + + return SW_OK; +} + +/** + * @} + */ + + diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_sec.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_sec.c new file mode 100755 index 000000000..e8f599117 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_sec.c @@ -0,0 +1,261 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "fal_sec.h" +#include "hppe_sec_reg.h" +#include "hppe_sec.h" +#include "adpt.h" + +sw_error_t +adpt_hppe_sec_l3_excep_parser_ctrl_set(a_uint32_t dev_id, fal_l3_excep_parser_ctrl *ctrl) +{ + union l3_exception_parsing_ctrl_reg_u l3_exception_parsing_ctrl; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(ctrl); + + memset(&l3_exception_parsing_ctrl, 0, sizeof(l3_exception_parsing_ctrl)); + + l3_exception_parsing_ctrl.bf.small_ttl = ctrl->small_ip4ttl; + l3_exception_parsing_ctrl.bf.small_hop_limit = ctrl->small_ip6hoplimit; + + return hppe_l3_exception_parsing_ctrl_reg_set(dev_id, &l3_exception_parsing_ctrl); +} +sw_error_t +adpt_hppe_sec_l3_excep_ctrl_get(a_uint32_t dev_id, a_uint32_t excep_type, fal_l3_excep_ctrl_t *ctrl) +{ + union l3_exception_cmd_u l3_exception_cmd; + union l3_exp_l3_only_ctrl_u l3_only_ctrl; + union l3_exp_l2_only_ctrl_u l2_only_ctrl; + union l3_exp_l2_flow_ctrl_u l2_flow_ctrl; + union l3_exp_l3_flow_ctrl_u l3_flow_ctrl; + union l3_exp_multicast_ctrl_u multicast_ctrl; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(ctrl); + if (excep_type >= L3_EXCEPTION_CMD_MAX_ENTRY) + return SW_BAD_VALUE; + + hppe_l3_exception_cmd_get(dev_id, excep_type, &l3_exception_cmd); + hppe_l3_exp_l3_only_ctrl_get(dev_id, excep_type, &l3_only_ctrl); + hppe_l3_exp_l2_only_ctrl_get(dev_id, excep_type, &l2_only_ctrl); + hppe_l3_exp_l3_flow_ctrl_get(dev_id, excep_type, &l3_flow_ctrl); + hppe_l3_exp_l2_flow_ctrl_get(dev_id, excep_type, &l2_flow_ctrl); + hppe_l3_exp_multicast_ctrl_get(dev_id, excep_type, &multicast_ctrl); + + ctrl->cmd = l3_exception_cmd.bf.l3_excep_cmd; + ctrl->deacclr_en = l3_exception_cmd.bf.de_acce; + ctrl->l3route_only_en = l3_only_ctrl.bf.excep_en; + ctrl->l2fwd_only_en = l2_only_ctrl.bf.excep_en; + ctrl->l3flow_en = l3_flow_ctrl.bf.excep_en; + ctrl->l2flow_en = l2_flow_ctrl.bf.excep_en; + ctrl->multicast_en = multicast_ctrl.bf.excep_en; + + return SW_OK; +} + +sw_error_t +adpt_hppe_sec_l3_excep_parser_ctrl_get(a_uint32_t dev_id, fal_l3_excep_parser_ctrl *ctrl) +{ + sw_error_t rv = SW_OK; + union l3_exception_parsing_ctrl_reg_u l3_exception_parsing_ctrl; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(ctrl); + + rv = hppe_l3_exception_parsing_ctrl_reg_get(dev_id, &l3_exception_parsing_ctrl); + if( rv != SW_OK ) + return rv; + + ctrl->small_ip4ttl = l3_exception_parsing_ctrl.bf.small_ttl; + ctrl->small_ip6hoplimit = l3_exception_parsing_ctrl.bf.small_hop_limit; + + return SW_OK; +} + +sw_error_t +adpt_hppe_sec_l4_excep_parser_ctrl_set(a_uint32_t dev_id, fal_l4_excep_parser_ctrl *ctrl) +{ + union l4_exception_parsing_ctrl_0_reg_u l4_exception_parsing_ctrl_0; + union l4_exception_parsing_ctrl_1_reg_u l4_exception_parsing_ctrl_1; + union l4_exception_parsing_ctrl_2_reg_u l4_exception_parsing_ctrl_2; + union l4_exception_parsing_ctrl_3_reg_u l4_exception_parsing_ctrl_3; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(ctrl); + + + l4_exception_parsing_ctrl_0.bf.tcp_flags0 = ctrl->tcp_flags[0]; + l4_exception_parsing_ctrl_0.bf.tcp_flags0_mask = ctrl->tcp_flags_mask[0]; + l4_exception_parsing_ctrl_0.bf.tcp_flags1 = ctrl->tcp_flags[1]; + l4_exception_parsing_ctrl_0.bf.tcp_flags1_mask = ctrl->tcp_flags_mask[1]; + l4_exception_parsing_ctrl_1.bf.tcp_flags2 = ctrl->tcp_flags[2]; + l4_exception_parsing_ctrl_1.bf.tcp_flags2_mask = ctrl->tcp_flags_mask[2]; + l4_exception_parsing_ctrl_1.bf.tcp_flags3 = ctrl->tcp_flags[3]; + l4_exception_parsing_ctrl_1.bf.tcp_flags3_mask = ctrl->tcp_flags_mask[3]; + l4_exception_parsing_ctrl_2.bf.tcp_flags4 = ctrl->tcp_flags[4]; + l4_exception_parsing_ctrl_2.bf.tcp_flags4_mask = ctrl->tcp_flags_mask[4]; + l4_exception_parsing_ctrl_2.bf.tcp_flags5 = ctrl->tcp_flags[5]; + l4_exception_parsing_ctrl_2.bf.tcp_flags5_mask = ctrl->tcp_flags_mask[5]; + l4_exception_parsing_ctrl_3.bf.tcp_flags6 = ctrl->tcp_flags[6]; + l4_exception_parsing_ctrl_3.bf.tcp_flags6_mask = ctrl->tcp_flags_mask[6]; + l4_exception_parsing_ctrl_3.bf.tcp_flags7 = ctrl->tcp_flags[7]; + l4_exception_parsing_ctrl_3.bf.tcp_flags7_mask = ctrl->tcp_flags_mask[7]; + + hppe_l4_exception_parsing_ctrl_0_reg_set(dev_id, &l4_exception_parsing_ctrl_0); + hppe_l4_exception_parsing_ctrl_1_reg_set(dev_id, &l4_exception_parsing_ctrl_1); + hppe_l4_exception_parsing_ctrl_2_reg_set(dev_id, &l4_exception_parsing_ctrl_2); + hppe_l4_exception_parsing_ctrl_3_reg_set(dev_id, &l4_exception_parsing_ctrl_3); + return SW_OK; +} +sw_error_t +adpt_hppe_sec_l3_excep_ctrl_set(a_uint32_t dev_id, a_uint32_t excep_type, fal_l3_excep_ctrl_t *ctrl) +{ + union l3_exception_cmd_u l3_exception_cmd; + union l3_exp_l3_only_ctrl_u l3_only_ctrl; + union l3_exp_l2_only_ctrl_u l2_only_ctrl; + union l3_exp_l2_flow_ctrl_u l2_flow_ctrl; + union l3_exp_l3_flow_ctrl_u l3_flow_ctrl; + union l3_exp_multicast_ctrl_u multicast_ctrl; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(ctrl); + if (excep_type >= L3_EXCEPTION_CMD_MAX_ENTRY) + return SW_BAD_VALUE; + + l3_exception_cmd.bf.l3_excep_cmd= ctrl->cmd; + l3_exception_cmd.bf.de_acce= ctrl->deacclr_en; + l3_only_ctrl.bf.excep_en = ctrl->l3route_only_en; + l2_only_ctrl.bf.excep_en = ctrl->l2fwd_only_en; + l3_flow_ctrl.bf.excep_en = ctrl->l3flow_en; + l2_flow_ctrl.bf.excep_en = ctrl->l2flow_en; + multicast_ctrl.bf.excep_en = ctrl->multicast_en; + + hppe_l3_exception_cmd_set(dev_id, excep_type, &l3_exception_cmd); + hppe_l3_exp_l3_only_ctrl_set(dev_id, excep_type, &l3_only_ctrl); + hppe_l3_exp_l2_only_ctrl_set(dev_id, excep_type, &l2_only_ctrl); + hppe_l3_exp_l3_flow_ctrl_set(dev_id, excep_type, &l3_flow_ctrl); + hppe_l3_exp_l2_flow_ctrl_set(dev_id, excep_type, &l2_flow_ctrl); + hppe_l3_exp_multicast_ctrl_set(dev_id, excep_type, &multicast_ctrl); + + return SW_OK; +} + +sw_error_t +adpt_hppe_sec_l4_excep_parser_ctrl_get(a_uint32_t dev_id, fal_l4_excep_parser_ctrl *ctrl) +{ + union l4_exception_parsing_ctrl_0_reg_u l4_exception_parsing_ctrl_0; + union l4_exception_parsing_ctrl_1_reg_u l4_exception_parsing_ctrl_1; + union l4_exception_parsing_ctrl_2_reg_u l4_exception_parsing_ctrl_2; + union l4_exception_parsing_ctrl_3_reg_u l4_exception_parsing_ctrl_3; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(ctrl); + + hppe_l4_exception_parsing_ctrl_0_reg_get(dev_id, &l4_exception_parsing_ctrl_0); + hppe_l4_exception_parsing_ctrl_1_reg_get(dev_id, &l4_exception_parsing_ctrl_1); + hppe_l4_exception_parsing_ctrl_2_reg_get(dev_id, &l4_exception_parsing_ctrl_2); + hppe_l4_exception_parsing_ctrl_3_reg_get(dev_id, &l4_exception_parsing_ctrl_3); + + ctrl->tcp_flags[0] = l4_exception_parsing_ctrl_0.bf.tcp_flags0; + ctrl->tcp_flags_mask[0] = l4_exception_parsing_ctrl_0.bf.tcp_flags0_mask; + ctrl->tcp_flags[1] = l4_exception_parsing_ctrl_0.bf.tcp_flags1; + ctrl->tcp_flags_mask[1] = l4_exception_parsing_ctrl_0.bf.tcp_flags1_mask; + ctrl->tcp_flags[2] = l4_exception_parsing_ctrl_1.bf.tcp_flags2; + ctrl->tcp_flags_mask[2] = l4_exception_parsing_ctrl_1.bf.tcp_flags2_mask; + ctrl->tcp_flags[3] = l4_exception_parsing_ctrl_1.bf.tcp_flags3; + ctrl->tcp_flags_mask[3] = l4_exception_parsing_ctrl_1.bf.tcp_flags3_mask; + ctrl->tcp_flags[4] = l4_exception_parsing_ctrl_2.bf.tcp_flags4; + ctrl->tcp_flags_mask[4] = l4_exception_parsing_ctrl_2.bf.tcp_flags4_mask; + ctrl->tcp_flags[5] = l4_exception_parsing_ctrl_2.bf.tcp_flags5; + ctrl->tcp_flags_mask[5] = l4_exception_parsing_ctrl_2.bf.tcp_flags5_mask; + ctrl->tcp_flags[6] = l4_exception_parsing_ctrl_3.bf.tcp_flags6; + ctrl->tcp_flags_mask[6] = l4_exception_parsing_ctrl_3.bf.tcp_flags6_mask; + ctrl->tcp_flags[7] = l4_exception_parsing_ctrl_3.bf.tcp_flags7; + ctrl->tcp_flags_mask[7] = l4_exception_parsing_ctrl_3.bf.tcp_flags7_mask; + + return SW_OK; +} + +void adpt_hppe_sec_func_bitmap_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_sec_func_bitmap = ((1 << FUNC_SEC_L3_EXCEP_CTRL_SET) | + (1 << FUNC_SEC_L3_EXCEP_CTRL_GET) | + (1 << FUNC_SEC_L3_EXCEP_PARSER_CTRL_SET) | + (1 << FUNC_SEC_L3_EXCEP_PARSER_CTRL_GET) | + (1 << FUNC_SEC_L4_EXCEP_PARSER_CTRL_SET) | + (1 << FUNC_SEC_L4_EXCEP_PARSER_CTRL_GET)); + + return; +} + +static void adpt_hppe_sec_func_unregister(a_uint32_t dev_id, adpt_api_t *p_adpt_api) +{ + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_sec_l3_excep_parser_ctrl_set = NULL; + p_adpt_api->adpt_sec_l3_excep_ctrl_get = NULL; + p_adpt_api->adpt_sec_l3_excep_parser_ctrl_get = NULL; + p_adpt_api->adpt_sec_l4_excep_parser_ctrl_set = NULL; + p_adpt_api->adpt_sec_l3_excep_ctrl_set = NULL; + p_adpt_api->adpt_sec_l4_excep_parser_ctrl_get = NULL; + + return; +} + +sw_error_t adpt_hppe_sec_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return SW_FAIL; + + adpt_hppe_sec_func_unregister(dev_id, p_adpt_api); + + if (p_adpt_api->adpt_sec_func_bitmap & (1 << FUNC_SEC_L3_EXCEP_PARSER_CTRL_SET)) + p_adpt_api->adpt_sec_l3_excep_parser_ctrl_set = adpt_hppe_sec_l3_excep_parser_ctrl_set; + if (p_adpt_api->adpt_sec_func_bitmap & (1 << FUNC_SEC_L3_EXCEP_CTRL_GET)) + p_adpt_api->adpt_sec_l3_excep_ctrl_get = adpt_hppe_sec_l3_excep_ctrl_get; + if (p_adpt_api->adpt_sec_func_bitmap & (1 << FUNC_SEC_L3_EXCEP_PARSER_CTRL_GET)) + p_adpt_api->adpt_sec_l3_excep_parser_ctrl_get = adpt_hppe_sec_l3_excep_parser_ctrl_get; + if (p_adpt_api->adpt_sec_func_bitmap & (1 << FUNC_SEC_L4_EXCEP_PARSER_CTRL_SET)) + p_adpt_api->adpt_sec_l4_excep_parser_ctrl_set = adpt_hppe_sec_l4_excep_parser_ctrl_set; + if (p_adpt_api->adpt_sec_func_bitmap & (1 << FUNC_SEC_L3_EXCEP_CTRL_SET)) + p_adpt_api->adpt_sec_l3_excep_ctrl_set = adpt_hppe_sec_l3_excep_ctrl_set; + if (p_adpt_api->adpt_sec_func_bitmap & (1 << FUNC_SEC_L4_EXCEP_PARSER_CTRL_GET)) + p_adpt_api->adpt_sec_l4_excep_parser_ctrl_get = adpt_hppe_sec_l4_excep_parser_ctrl_get; + + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_servcode.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_servcode.c new file mode 100755 index 000000000..2696356cb --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_servcode.c @@ -0,0 +1,172 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hppe_servcode_reg.h" +#include "hppe_servcode.h" +#include "hppe_fdb_reg.h" +#include "hppe_fdb.h" +#include "adpt.h" + +#define MAX_PHYSICAL_PORT 8 + +sw_error_t adpt_hppe_servcode_config_set(a_uint32_t dev_id, a_uint32_t servcode_index, + fal_servcode_config_t *entry) +{ + union in_l2_service_tbl_u in_l2_service_tbl; + union service_tbl_u service_tbl; + union eg_service_tbl_u eg_service_tbl; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(entry); + + if (servcode_index >= IN_L2_SERVICE_TBL_MAX_ENTRY || entry->dest_port_id >= MAX_PHYSICAL_PORT) + return SW_OUT_OF_RANGE; + + in_l2_service_tbl.bf.dst_port_id_valid = entry->dest_port_valid; + in_l2_service_tbl.bf.dst_port_id = entry->dest_port_id; + in_l2_service_tbl.bf.direction = entry->direction; + in_l2_service_tbl.bf.bypass_bitmap = entry->bypass_bitmap[1]; + in_l2_service_tbl.bf.rx_cnt_en = (entry->bypass_bitmap[2] >> 1) & 0x1; + in_l2_service_tbl.bf.tx_cnt_en = (entry->bypass_bitmap[2] >> 3) & 0x1; + SW_RTN_ON_ERROR(hppe_in_l2_service_tbl_set(dev_id, servcode_index, &in_l2_service_tbl)); + + service_tbl.bf.bypass_bitmap = entry->bypass_bitmap[0]; + service_tbl.bf.rx_counting_en = entry->bypass_bitmap[2] & 0x1; + SW_RTN_ON_ERROR(hppe_service_tbl_set(dev_id, servcode_index, &service_tbl)); + + eg_service_tbl.bf.field_update_action = entry->field_update_bitmap; + eg_service_tbl.bf.next_service_code = entry->next_service_code; + eg_service_tbl.bf.hw_services = entry->hw_services; + eg_service_tbl.bf.offset_sel = entry->offset_sel; + eg_service_tbl.bf.tx_counting_en = (entry->bypass_bitmap[2] >> 2) & 0x1; + SW_RTN_ON_ERROR(hppe_eg_service_tbl_set(dev_id, servcode_index, &eg_service_tbl)); + + return SW_OK; +} + +sw_error_t adpt_hppe_servcode_config_get(a_uint32_t dev_id, a_uint32_t servcode_index, + fal_servcode_config_t *entry) +{ + union in_l2_service_tbl_u in_l2_service_tbl; + union service_tbl_u service_tbl; + union eg_service_tbl_u eg_service_tbl; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(entry); + + if (servcode_index >= IN_L2_SERVICE_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + + SW_RTN_ON_ERROR(hppe_in_l2_service_tbl_get(dev_id, servcode_index, &in_l2_service_tbl)); + entry->dest_port_valid = in_l2_service_tbl.bf.dst_port_id_valid; + entry->dest_port_id = in_l2_service_tbl.bf.dst_port_id; + entry->direction = in_l2_service_tbl.bf.direction; + entry->bypass_bitmap[1] = in_l2_service_tbl.bf.bypass_bitmap; + entry->bypass_bitmap[2] |= in_l2_service_tbl.bf.rx_cnt_en << 1; + entry->bypass_bitmap[2] |= in_l2_service_tbl.bf.tx_cnt_en << 3; + + SW_RTN_ON_ERROR(hppe_service_tbl_get(dev_id, servcode_index, &service_tbl)); + entry->bypass_bitmap[0] = service_tbl.bf.bypass_bitmap; + entry->bypass_bitmap[2] |= service_tbl.bf.rx_counting_en; + + SW_RTN_ON_ERROR(hppe_eg_service_tbl_get(dev_id, servcode_index, &eg_service_tbl)); + entry->field_update_bitmap = eg_service_tbl.bf.field_update_action; + entry->next_service_code = eg_service_tbl.bf.next_service_code; + entry->hw_services = eg_service_tbl.bf.hw_services; + entry->offset_sel = eg_service_tbl.bf.offset_sel; + entry->bypass_bitmap[2] |= eg_service_tbl.bf.tx_counting_en << 2; + + return SW_OK; +} + +sw_error_t adpt_hppe_servcode_loopcheck_en(a_uint32_t dev_id, a_bool_t enable) +{ + ADPT_DEV_ID_CHECK(dev_id); +#ifndef IN_FDB_MINI + SW_RTN_ON_ERROR(hppe_l2_global_conf_service_code_loop_set(dev_id, enable)); +#endif + return SW_OK; +} + +sw_error_t adpt_hppe_servcode_loopcheck_status_get(a_uint32_t dev_id, a_bool_t *enable) +{ + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); +#ifndef IN_FDB_MINI + SW_RTN_ON_ERROR(hppe_l2_global_conf_service_code_loop_get(dev_id, enable)); +#endif + return SW_OK; +} + +void adpt_hppe_servcode_func_bitmap_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_servcode_func_bitmap = 0x0; + + return; +} + +static void adpt_hppe_servcode_func_unregister(a_uint32_t dev_id, adpt_api_t *p_adpt_api) +{ + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_servcode_config_set = NULL; + p_adpt_api->adpt_servcode_config_get = NULL; + p_adpt_api->adpt_servcode_loopcheck_en = NULL; + p_adpt_api->adpt_servcode_loopcheck_status_get = NULL; + + return; +} + +sw_error_t adpt_hppe_servcode_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return SW_FAIL; + + adpt_hppe_servcode_func_unregister(dev_id, p_adpt_api); + + if(p_adpt_api->adpt_servcode_func_bitmap & (1<adpt_servcode_config_set = adpt_hppe_servcode_config_set; + if(p_adpt_api->adpt_servcode_func_bitmap & (1<adpt_servcode_config_get = adpt_hppe_servcode_config_get; + if(p_adpt_api->adpt_servcode_func_bitmap & (1<adpt_servcode_loopcheck_en = adpt_hppe_servcode_loopcheck_en; + if(p_adpt_api->adpt_servcode_func_bitmap & (1<adpt_servcode_loopcheck_status_get = adpt_hppe_servcode_loopcheck_status_get; + + return SW_OK; +} + +/** + * @} + */ + + diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_shaper.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_shaper.c new file mode 100755 index 000000000..af88d165e --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_shaper.c @@ -0,0 +1,1591 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hppe_shaper_reg.h" +#include "hppe_shaper.h" +#include "adpt.h" + +#define NR_ADPT_HPPE_SHAPER_METER_UNIT 2 +#define NR_ADPT_HPPE_SHAPER_METER_TOKEN_UNIT 8 +#define ADPT_HPPE_SHAPER_METER_UNIT_BYTE 0 +#define ADPT_HPPE_SHAPER_METER_UNIT_FRAME 1 +#define ADPT_HPPE_FREQUENCY 300 /*MHZ*/ +#define ADPT_HPPE_SHAPER_BURST_SIZE_UNIT 65536 +#define ADPT_HPPE_SHAPER_REFRESH_BITS 18 +#define ADPT_HPPE_SHAPER_BUCKET_SIZE_BITS 14 +#define ADPT_HPPE_SHAPER_REFRESH_MAX ((1 << ADPT_HPPE_SHAPER_REFRESH_BITS) - 1) +#define ADPT_HPPE_SHAPER_BUCKET_SIZE_MAX ((1 << ADPT_HPPE_SHAPER_BUCKET_SIZE_BITS) - 1) +#define ADPT_HPPE_PORT_SHAPER 0 +#define ADPT_HPPE_FLOW_SHAPER 1 +#define ADPT_HPPE_QUEUE_SHAPER 2 +#define BYTE_SHAPER_MAX_RATE 10000000 +#define BYTE_SHAPER_MIN_RATE 64 +#define FRAME_SHAPER_MAX_RATE 14881000 +#define FRAME_SHAPER_MIN_RATE 6 + + + +static a_uint32_t hppe_shaper_token_unit[NR_ADPT_HPPE_SHAPER_METER_UNIT] + [NR_ADPT_HPPE_SHAPER_METER_TOKEN_UNIT] = {{2048 * 8, + 512 * 8,128 * 8,32 * 8,8 * 8,2 * 8, 4, 1}, + {2097152,524288,131072,32768,8192,2048,512,128}}; + +typedef struct +{ + a_uint64_t rate_1bit; + a_uint64_t rate_max; +} adpt_hppe_shaper_rate_t; + +typedef struct +{ + a_uint64_t burst_size_1bit; + a_uint64_t burst_size_max; +} adpt_hppe_shaper_burst_size_t; + +static adpt_hppe_shaper_rate_t +hppe_port_shaper_rate[NR_ADPT_HPPE_SHAPER_METER_UNIT][NR_ADPT_HPPE_SHAPER_METER_TOKEN_UNIT] = +{ + /* byte based*/ + { + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + }, + + /*frame based */ + { + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + }, +}; + +static adpt_hppe_shaper_rate_t +hppe_flow_shaper_rate[NR_ADPT_HPPE_SHAPER_METER_UNIT][NR_ADPT_HPPE_SHAPER_METER_TOKEN_UNIT] = +{ + /* byte based*/ + { + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + }, + + /*frame based */ + { + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + }, +}; + +static adpt_hppe_shaper_rate_t +hppe_queue_shaper_rate[NR_ADPT_HPPE_SHAPER_METER_UNIT][NR_ADPT_HPPE_SHAPER_METER_TOKEN_UNIT] = +{ + /* byte based*/ + { + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + }, + + /*frame based */ + { + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + {0,0}, + }, +}; + +static adpt_hppe_shaper_burst_size_t +hppe_shaper_burst_size[NR_ADPT_HPPE_SHAPER_METER_UNIT][NR_ADPT_HPPE_SHAPER_METER_TOKEN_UNIT] = +{ + { {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}, + }, +}; + +static sw_error_t +__adpt_hppe_port_shaper_max_rate(a_uint32_t time_slot) +{ + a_uint32_t i = 0, j = 0; + a_uint32_t time_cycle; + a_uint64_t temp, temp1,temp2; + + /* time_cycle is ns*/ + time_cycle = ( time_slot * 8); + + for (j = 0; j < 8; j++) + { + /*max rate unit is bps*/ + temp1 = (a_uint64_t)(ADPT_HPPE_SHAPER_REFRESH_MAX * 1000 * 8) * (a_uint64_t)(ADPT_HPPE_FREQUENCY * 1000); + temp2 = hppe_shaper_token_unit[i][j] * time_cycle; + + do_div(temp1, temp2); + hppe_port_shaper_rate[i][j].rate_max = temp1; + + temp = temp1; + do_div(temp, ADPT_HPPE_SHAPER_REFRESH_MAX); + hppe_port_shaper_rate[i][j].rate_1bit = temp; + + //printk("port shaper hppe_max_rate generating =%llu\n", hppe_port_shaper_rate[i][j].rate_max); + //printk("port shaper byte step rate =%llu\n", hppe_port_shaper_rate[i][j].rate_1bit); + } + + i = i + 1; + for (j = 0; j < 8; j++) + { + /* max rate unit is 1/1000 pps*/ + temp1 = (a_uint64_t)(ADPT_HPPE_SHAPER_REFRESH_MAX * 1000) * 1000 * (a_uint64_t)(ADPT_HPPE_FREQUENCY * 1000); + temp2 = (a_uint64_t)hppe_shaper_token_unit[i][j] * time_cycle; + + do_div(temp1, temp2); + hppe_port_shaper_rate[i][j].rate_max = temp1; + + temp = temp1; + do_div(temp, ADPT_HPPE_SHAPER_REFRESH_MAX); + hppe_port_shaper_rate[i][j].rate_1bit = temp; + + //printk("port shaper hppe_max_rate generating =%llu\n", hppe_port_shaper_rate[i][j].rate_max); + //printk("port shaper frame step rate =%llu\n", hppe_port_shaper_rate[i][j].rate_1bit); + } + + return SW_OK; +} + +static sw_error_t +__adpt_hppe_flow_shaper_max_rate(a_uint32_t time_slot) +{ + a_uint32_t i = 0, j = 0; + a_uint32_t time_cycle; + a_uint64_t temp, temp1,temp2; + + /* time_cycle is ns*/ + time_cycle = ( time_slot * 8); + + for (j = 0; j < 8; j++) + { + /*max rate unit is bps*/ + temp1 = (a_uint64_t)(ADPT_HPPE_SHAPER_REFRESH_MAX * 1000 * 8) * (a_uint64_t)(ADPT_HPPE_FREQUENCY * 1000); + temp2 = hppe_shaper_token_unit[i][j] * time_cycle; + + do_div(temp1, temp2); + hppe_flow_shaper_rate[i][j].rate_max = temp1; + + temp = temp1; + do_div(temp, ADPT_HPPE_SHAPER_REFRESH_MAX); + hppe_flow_shaper_rate[i][j].rate_1bit = temp; + + //printk("flow shaper hppe_max_rate generating =%llu\n", hppe_flow_shaper_rate[i][j].rate_max); + //printk("flow shaper byte step rate =%llu\n", hppe_flow_shaper_rate[i][j].rate_1bit); + } + + i = i + 1; + for (j = 0; j < 8; j++) + { + /* max rate unit is 1/1000 pps*/ + temp1 = (a_uint64_t)(ADPT_HPPE_SHAPER_REFRESH_MAX * 1000) * 1000 * (a_uint64_t)(ADPT_HPPE_FREQUENCY * 1000); + temp2 = (a_uint64_t)hppe_shaper_token_unit[i][j] * time_cycle; + + do_div(temp1, temp2); + hppe_flow_shaper_rate[i][j].rate_max = temp1; + + temp = temp1; + do_div(temp, ADPT_HPPE_SHAPER_REFRESH_MAX); + hppe_flow_shaper_rate[i][j].rate_1bit = temp; + + //printk("flow shaper hppe_max_rate generating =%llu\n", hppe_flow_shaper_rate[i][j].rate_max); + //printk("flow shaper frame step rate =%llu\n", hppe_flow_shaper_rate[i][j].rate_1bit); + } + + return SW_OK; +} + +static sw_error_t +__adpt_hppe_queue_shaper_max_rate(a_uint32_t time_slot) +{ + a_uint32_t i = 0, j = 0; + a_uint32_t time_cycle; + a_uint64_t temp, temp1,temp2; + + + /* time_cycle is ns*/ + time_cycle = ( time_slot * 8) /ADPT_HPPE_FREQUENCY; + + for (j = 0; j < 8; j++) + { + /*max rate unit is bps*/ + temp1 = (a_uint64_t)(ADPT_HPPE_SHAPER_REFRESH_MAX * 1000 * 8) * 1000; + temp2 = hppe_shaper_token_unit[i][j] * time_cycle; + + do_div(temp1, temp2); + hppe_queue_shaper_rate[i][j].rate_max = temp1; + + temp = temp1; + do_div(temp, ADPT_HPPE_SHAPER_REFRESH_MAX); + hppe_queue_shaper_rate[i][j].rate_1bit = temp; + + //printk("queue shaper hppe_max_rate generating =%llu\n", hppe_queue_shaper_rate[i][j].rate_max); + //printk("queue shaper byte step rate =%llu\n", hppe_queue_shaper_rate[i][j].rate_1bit); + } + + i = i + 1; + for (j = 0; j < 8; j++) + { + /* max rate unit is 1/1000 pps*/ + temp1 = (a_uint64_t)(ADPT_HPPE_SHAPER_REFRESH_MAX * 1000) * 1000 * 1000; + temp2 = (a_uint64_t)hppe_shaper_token_unit[i][j] * time_cycle; + + do_div(temp1, temp2); + hppe_queue_shaper_rate[i][j].rate_max = temp1; + + temp = temp1; + do_div(temp, ADPT_HPPE_SHAPER_REFRESH_MAX); + hppe_queue_shaper_rate[i][j].rate_1bit = temp; + + //printk("queue shaper hppe_max_rate generating =%llu\n", hppe_queue_shaper_rate[i][j].rate_max); + //printk("queue shaper frame step rate =%llu\n", hppe_queue_shaper_rate[i][j].rate_1bit); + } + + return SW_OK; +} + +static sw_error_t +__adpt_hppe_shaper_max_burst_size(void) +{ + a_uint32_t i = 0, j = 0; + a_uint64_t temp = 0, temp1 = 0; + + for (j = 0; j < 8; j++) + { + /*max size unit is 1/1000 byte based*/ + temp = (a_uint64_t)(ADPT_HPPE_SHAPER_BURST_SIZE_UNIT * ADPT_HPPE_SHAPER_BUCKET_SIZE_MAX); + do_div(temp, hppe_shaper_token_unit[i][j]); + hppe_shaper_burst_size[i][j].burst_size_max = (a_uint64_t)(temp * 1000); + + temp1 = hppe_shaper_burst_size[i][j].burst_size_max; + do_div(temp1, ADPT_HPPE_SHAPER_BUCKET_SIZE_MAX); + hppe_shaper_burst_size[i][j].burst_size_1bit = temp1; + + //printk("shpaer byte hppe_max_burst_size generating =%llu\n", hppe_shaper_burst_size[i][j].burst_size_max); + //printk("shpaer byte hppe_max_burst_size step =%llu\n", hppe_shaper_burst_size[i][j].burst_size_1bit); + } + + i = i + 1; + for (j = 0; j < 8; j++) + { + /* max size unit is 1/1000 frame based */ + temp = (a_uint64_t)(ADPT_HPPE_SHAPER_BURST_SIZE_UNIT * ADPT_HPPE_SHAPER_BUCKET_SIZE_MAX); + do_div(temp, hppe_shaper_token_unit[i][j]); + hppe_shaper_burst_size[i][j].burst_size_max = (a_uint64_t)(temp * 1000); + + temp1 = hppe_shaper_burst_size[i][j].burst_size_max; + do_div(temp1, ADPT_HPPE_SHAPER_BUCKET_SIZE_MAX); + hppe_shaper_burst_size[i][j].burst_size_1bit = temp1; + + //printk("shaper frame hppe_max_burst_size generating =%llu\n", hppe_shaper_burst_size[i][j].burst_size_max); + //printk("shpaer frame hppe_max_burst_size step =%llu\n", hppe_shaper_burst_size[i][j].burst_size_1bit); + } + + return SW_OK; +} + +static sw_error_t +__adpt_hppe_shaper_one_bucket_parameter_select(a_uint32_t shaper_type, + a_uint64_t c_rate, + a_uint64_t c_burst_size, + a_uint32_t meter_unit, + a_uint32_t *token_unit) +{ + a_uint32_t temp_token_unit = 0; + a_uint32_t match = A_FALSE; + a_uint64_t max_rate =0; + + for (temp_token_unit = 0; temp_token_unit < 8; temp_token_unit++) + { + if (ADPT_HPPE_PORT_SHAPER == shaper_type) + max_rate = hppe_port_shaper_rate[meter_unit][temp_token_unit].rate_max; + + if (ADPT_HPPE_FLOW_SHAPER == shaper_type) + max_rate = hppe_flow_shaper_rate[meter_unit][temp_token_unit].rate_max; + + if (ADPT_HPPE_QUEUE_SHAPER == shaper_type) + max_rate = hppe_queue_shaper_rate[meter_unit][temp_token_unit].rate_max; + + if (c_rate > max_rate) + { + continue; + } + else if (c_burst_size <= hppe_shaper_burst_size[meter_unit][temp_token_unit].burst_size_max) + { + *token_unit = temp_token_unit; + match = A_TRUE; + break; + } + } + + if (match == A_FALSE) + { + printk("Not match shaper C token bucket parameter rate configuration\n"); + return SW_BAD_PARAM; + } + + return SW_OK; +} + +static sw_error_t +__adpt_hppe_shaper_two_bucket_parameter_select(a_uint32_t shaper_type, + a_uint64_t c_rate, + a_uint64_t c_burst_size, + a_uint64_t e_rate, + a_uint64_t e_burst_size, + a_uint32_t meter_unit, + a_uint32_t *token_unit) +{ + a_uint32_t temp_token_unit; + a_uint32_t match = A_FALSE; + a_uint64_t max_rate = 0, temp_rate = 0, temp_burst_size = 0; + + if(c_rate > e_rate) + temp_rate = c_rate; + else + temp_rate = e_rate; + + if(c_burst_size > e_burst_size) + temp_burst_size = c_burst_size; + else + temp_burst_size = e_burst_size; + + for (temp_token_unit = 0; temp_token_unit < 8; temp_token_unit++) + { + if (ADPT_HPPE_PORT_SHAPER == shaper_type) + max_rate = hppe_port_shaper_rate[meter_unit][temp_token_unit].rate_max; + + if (ADPT_HPPE_FLOW_SHAPER == shaper_type) + max_rate = hppe_flow_shaper_rate[meter_unit][temp_token_unit].rate_max; + + if (ADPT_HPPE_QUEUE_SHAPER == shaper_type) + max_rate = hppe_queue_shaper_rate[meter_unit][temp_token_unit].rate_max; + + if (temp_rate > max_rate) + { + continue; + } + else if(temp_burst_size <= hppe_shaper_burst_size[meter_unit][temp_token_unit].burst_size_max) + { + *token_unit = temp_token_unit; + match = A_TRUE; + break; + } + } + + if (match == A_FALSE) + { + printk("Not match shaper C and E token bucket parameter rate configuration \n"); + return SW_BAD_PARAM; + } + + return SW_OK; +} + +static sw_error_t +__adpt_hppe_shaper_rate_to_refresh(a_uint32_t shaper_type, + a_uint32_t rate, + a_uint32_t *refresh, + a_bool_t meter_unit, + a_uint32_t token_unit) +{ + a_uint32_t temp_refresh; + a_uint64_t temp_rate, temp_rate_1bit; + + temp_rate_1bit = 0; + + if (ADPT_HPPE_PORT_SHAPER == shaper_type) + { + temp_rate_1bit = hppe_port_shaper_rate[meter_unit][token_unit].rate_1bit; + } + + if (ADPT_HPPE_FLOW_SHAPER == shaper_type) + { + temp_rate_1bit = hppe_flow_shaper_rate[meter_unit][token_unit].rate_1bit; + } + + if (ADPT_HPPE_QUEUE_SHAPER == shaper_type) + { + temp_rate_1bit = hppe_queue_shaper_rate[meter_unit][token_unit].rate_1bit; + } + + if(temp_rate_1bit > 0) + { + temp_rate = ((a_uint64_t)rate) * 1000; + do_div(temp_rate, temp_rate_1bit); + temp_refresh = temp_rate; + } + else + { + return SW_BAD_PARAM; + } + + if (temp_refresh > ADPT_HPPE_SHAPER_REFRESH_MAX) + { + temp_refresh = ADPT_HPPE_SHAPER_REFRESH_MAX; + } + + *refresh = temp_refresh; + + return SW_OK; +} + +static sw_error_t +__adpt_hppe_shaper_burst_size_to_bucket_size(a_uint32_t burst_size, + a_uint32_t *bucket_size, + a_bool_t meter_unit, + a_uint32_t token_unit) +{ + a_uint32_t temp_bucket_size; + a_uint64_t temp_burst_size; + + if(hppe_shaper_burst_size[meter_unit][token_unit].burst_size_1bit > 0) + { + temp_burst_size = ((a_uint64_t)burst_size) * 1000; + do_div(temp_burst_size, hppe_shaper_burst_size[meter_unit][token_unit].burst_size_1bit); + temp_bucket_size = temp_burst_size; + } + else + { + return SW_BAD_PARAM; + } + + if(temp_bucket_size > ADPT_HPPE_SHAPER_BUCKET_SIZE_MAX) + { + temp_bucket_size = ADPT_HPPE_SHAPER_BUCKET_SIZE_MAX; + } + + *bucket_size = temp_bucket_size; + + return SW_OK; +} + +static sw_error_t +__adpt_hppe_shaper_refresh_to_rate(a_uint32_t shaper_type, + a_uint32_t refresh, + a_uint32_t *rate, + a_bool_t meter_unit, + a_uint32_t token_unit) +{ + a_uint32_t temp_rate; + a_uint64_t temp_refresh, temp_rate_1bit; + + temp_rate_1bit = 0; + + if (ADPT_HPPE_PORT_SHAPER == shaper_type) + { + temp_rate_1bit = hppe_port_shaper_rate[meter_unit][token_unit].rate_1bit; + } + + if (ADPT_HPPE_FLOW_SHAPER == shaper_type) + { + temp_rate_1bit = hppe_flow_shaper_rate[meter_unit][token_unit].rate_1bit; + } + + if (ADPT_HPPE_QUEUE_SHAPER == shaper_type) + { + temp_rate_1bit = hppe_queue_shaper_rate[meter_unit][token_unit].rate_1bit; + } + + if(temp_rate_1bit > 0) + { + temp_refresh = ((a_uint64_t)refresh) * temp_rate_1bit; + do_div(temp_refresh, 1000); + temp_rate = temp_refresh; + } + else + { + return SW_BAD_PARAM; + } + + *rate = temp_rate; + + return SW_OK; +} +static sw_error_t +__adpt_hppe_shaper_bucket_size_to_burst_size(a_uint32_t bucket_size, + a_uint32_t *burst_size, + a_bool_t meter_unit, + a_uint32_t token_unit) +{ + a_uint32_t temp_burst_size; + a_uint64_t temp_bucket_size; + + if(hppe_shaper_burst_size[meter_unit][token_unit].burst_size_1bit > 0) + { + temp_bucket_size = ((a_uint64_t)bucket_size) * hppe_shaper_burst_size[meter_unit][token_unit].burst_size_1bit; + do_div(temp_bucket_size, 1000); + temp_burst_size = temp_bucket_size; + } + else + { + return SW_BAD_PARAM; + } + + *burst_size = temp_burst_size; + + return SW_OK; +} + +sw_error_t +adpt_hppe_queue_shaper_get(a_uint32_t dev_id, a_uint32_t queue_id, + fal_shaper_config_t * shaper) +{ + sw_error_t rv = SW_OK; + union l0_shp_cfg_tbl_u l0_shp_cfg_tbl; + union l0_comp_cfg_tbl_u l0_comp_cfg_tbl; + a_uint32_t hppe_cir =0, hppe_cbs = 0, hppe_eir = 0, hppe_ebs = 0; + + memset(&l0_shp_cfg_tbl, 0, sizeof(l0_shp_cfg_tbl)); + memset(&l0_comp_cfg_tbl, 0, sizeof(l0_comp_cfg_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(shaper); + + if ((queue_id < 0) || (queue_id > 299)) + return SW_BAD_PARAM; + + hppe_l0_comp_cfg_tbl_get(dev_id, queue_id, &l0_comp_cfg_tbl); + + + rv = hppe_l0_shp_cfg_tbl_get(dev_id, queue_id, &l0_shp_cfg_tbl); + + if( rv != SW_OK ) + return rv; + + hppe_cir = l0_shp_cfg_tbl.bf.cir; + hppe_cbs = l0_shp_cfg_tbl.bf.cbs; + hppe_eir = l0_shp_cfg_tbl.bf.eir; + hppe_ebs = l0_shp_cfg_tbl.bf.ebs; + + __adpt_hppe_shaper_refresh_to_rate(ADPT_HPPE_QUEUE_SHAPER, + hppe_cir, + &shaper->cir, + l0_shp_cfg_tbl.bf.meter_unit, + l0_shp_cfg_tbl.bf.token_unit); + + __adpt_hppe_shaper_refresh_to_rate(ADPT_HPPE_QUEUE_SHAPER, + hppe_eir, + &shaper->eir, + l0_shp_cfg_tbl.bf.meter_unit, + l0_shp_cfg_tbl.bf.token_unit); + + + __adpt_hppe_shaper_bucket_size_to_burst_size(hppe_cbs, + &shaper->cbs, + l0_shp_cfg_tbl.bf.meter_unit, + l0_shp_cfg_tbl.bf.token_unit); + + __adpt_hppe_shaper_bucket_size_to_burst_size(hppe_ebs, + &shaper->ebs, + l0_shp_cfg_tbl.bf.meter_unit, + l0_shp_cfg_tbl.bf.token_unit); + + + shaper->couple_en = l0_shp_cfg_tbl.bf.cf; + shaper->meter_unit = l0_shp_cfg_tbl.bf.meter_unit; + shaper->c_shaper_en = l0_shp_cfg_tbl.bf.c_shaper_enable; + shaper->e_shaper_en = l0_shp_cfg_tbl.bf.e_shaper_enable; + shaper->shaper_frame_mode = l0_comp_cfg_tbl.bf.shaper_meter_len; + + return SW_OK; +} + +sw_error_t +adpt_hppe_queue_shaper_token_number_set(a_uint32_t dev_id,a_uint32_t queue_id, + fal_shaper_token_number_t *token_number) +{ + union l0_shp_credit_tbl_u l0_shp_credit_tbl; + + memset(&l0_shp_credit_tbl, 0, sizeof(l0_shp_credit_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(token_number); + + if ((queue_id < 0) || (queue_id > 299)) + return SW_BAD_PARAM; + + hppe_l0_shp_credit_tbl_get(dev_id, queue_id, &l0_shp_credit_tbl); + + + l0_shp_credit_tbl.bf.c_shaper_credit_neg = token_number->c_token_number_negative_en; + l0_shp_credit_tbl.bf.c_shaper_credit = token_number->c_token_number; + l0_shp_credit_tbl.bf.e_shaper_credit_neg = token_number->e_token_number_negative_en; + l0_shp_credit_tbl.bf.e_shaper_credit_0 = token_number->e_token_number & 0x1; + l0_shp_credit_tbl.bf.e_shaper_credit_1 = token_number->e_token_number >> 1; + + hppe_l0_shp_credit_tbl_set(dev_id, queue_id, &l0_shp_credit_tbl); + + return SW_OK; +} +#ifndef IN_SHAPER_MINI +sw_error_t +adpt_hppe_port_shaper_get(a_uint32_t dev_id, fal_port_t port_id, + fal_shaper_config_t * shaper) +{ + union psch_shp_cfg_tbl_u psch_shp_cfg_tbl; + union psch_comp_cfg_tbl_u psch_comp_cfg_tbl; + a_uint32_t hppe_cir =0, hppe_cbs = 0; + + memset(&psch_shp_cfg_tbl, 0, sizeof(psch_shp_cfg_tbl)); + memset(&psch_comp_cfg_tbl, 0, sizeof(psch_comp_cfg_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(shaper); + + if (port_id < 0 || port_id > 7) + return SW_BAD_PARAM; + + hppe_psch_shp_cfg_tbl_get(dev_id, port_id, &psch_shp_cfg_tbl); + + hppe_cir = psch_shp_cfg_tbl.bf.cir; + hppe_cbs = psch_shp_cfg_tbl.bf.cbs; + + hppe_psch_comp_cfg_tbl_get(dev_id, port_id, &psch_comp_cfg_tbl); + + + __adpt_hppe_shaper_refresh_to_rate(ADPT_HPPE_PORT_SHAPER, + hppe_cir, + &shaper->cir, + psch_shp_cfg_tbl.bf.meter_unit, + psch_shp_cfg_tbl.bf.token_unit); + + + __adpt_hppe_shaper_bucket_size_to_burst_size(hppe_cbs, + &shaper->cbs, + psch_shp_cfg_tbl.bf.meter_unit, + psch_shp_cfg_tbl.bf.token_unit); + + shaper->meter_unit = psch_shp_cfg_tbl.bf.meter_unit; + shaper->c_shaper_en = psch_shp_cfg_tbl.bf.shaper_enable; + + shaper->shaper_frame_mode = psch_comp_cfg_tbl.bf.shaper_meter_len; + + return SW_OK; +} + +sw_error_t +adpt_hppe_flow_shaper_time_slot_get(a_uint32_t dev_id, a_uint32_t *time_slot) +{ + sw_error_t rv = SW_OK; + union shp_slot_cfg_l1_u shp_slot_cfg_l1; + + memset(&shp_slot_cfg_l1, 0, sizeof(shp_slot_cfg_l1)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(time_slot); + + + rv = hppe_shp_slot_cfg_l1_get(dev_id, &shp_slot_cfg_l1); + + if( rv != SW_OK ) + return rv; + + *time_slot = shp_slot_cfg_l1.bf.l1_shp_slot_time; + + return SW_OK; +} + +sw_error_t +adpt_hppe_port_shaper_time_slot_get(a_uint32_t dev_id, a_uint32_t *time_slot) +{ + sw_error_t rv = SW_OK; + union shp_slot_cfg_port_u shp_slot_cfg_port; + + memset(&shp_slot_cfg_port, 0, sizeof(shp_slot_cfg_port)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(time_slot); + + rv = hppe_shp_slot_cfg_port_get(dev_id, &shp_slot_cfg_port); + + if( rv != SW_OK ) + return rv; + + *time_slot = shp_slot_cfg_port.bf.port_shp_slot_time; + + return SW_OK; +} +#endif + +sw_error_t +adpt_hppe_flow_shaper_time_slot_set(a_uint32_t dev_id, a_uint32_t time_slot) +{ + union shp_slot_cfg_l1_u shp_slot_cfg_l1; + sw_error_t rv = SW_OK; + + memset(&shp_slot_cfg_l1, 0, sizeof(shp_slot_cfg_l1)); + ADPT_DEV_ID_CHECK(dev_id); + + if ((time_slot < 0x40) || (time_slot > 0xfff)) + return SW_BAD_PARAM; + + rv = hppe_shp_slot_cfg_l1_get(dev_id, &shp_slot_cfg_l1); + + if( rv != SW_OK ) + return rv; + + shp_slot_cfg_l1.bf.l1_shp_slot_time = time_slot; + hppe_shp_slot_cfg_l1_set(dev_id, &shp_slot_cfg_l1); + + __adpt_hppe_flow_shaper_max_rate(time_slot); + + return SW_OK; + +} +sw_error_t +adpt_hppe_port_shaper_token_number_set(a_uint32_t dev_id, fal_port_t port_id, + fal_shaper_token_number_t *token_number) +{ + union psch_shp_credit_tbl_u psch_shp_credit_tbl; + union psch_shp_sign_tbl_u psch_shp_sign_tbl; + + memset(&psch_shp_credit_tbl, 0, sizeof(psch_shp_credit_tbl)); + memset(&psch_shp_sign_tbl, 0, sizeof(psch_shp_sign_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(token_number); + + if (port_id < 0 || port_id > 7) + return SW_BAD_PARAM; + + hppe_psch_shp_credit_tbl_get(dev_id, port_id, &psch_shp_credit_tbl); + hppe_psch_shp_sign_tbl_get(dev_id, port_id, &psch_shp_sign_tbl); + + + psch_shp_sign_tbl.bf.shaper_credit_neg = token_number->c_token_number_negative_en; + + psch_shp_credit_tbl.bf.shaper_credit = token_number->c_token_number; + + hppe_psch_shp_credit_tbl_set(dev_id, port_id, &psch_shp_credit_tbl); + + hppe_psch_shp_sign_tbl_set(dev_id, port_id, &psch_shp_sign_tbl); + + return SW_OK; +} +#ifndef IN_SHAPER_MINI +sw_error_t +adpt_hppe_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 = SW_OK; + union l0_shp_credit_tbl_u l0_shp_credit_tbl; + + memset(&l0_shp_credit_tbl, 0, sizeof(l0_shp_credit_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(token_number); + + if ((queue_id < 0) || (queue_id > 299)) + return SW_BAD_PARAM; + + rv = hppe_l0_shp_credit_tbl_get(dev_id, queue_id, &l0_shp_credit_tbl); + + if( rv != SW_OK ) + return rv; + + token_number->c_token_number_negative_en = l0_shp_credit_tbl.bf.c_shaper_credit_neg; + token_number->c_token_number = l0_shp_credit_tbl.bf.c_shaper_credit; + token_number->e_token_number_negative_en = l0_shp_credit_tbl.bf.e_shaper_credit_neg; + token_number->e_token_number = l0_shp_credit_tbl.bf.e_shaper_credit_0 | (l0_shp_credit_tbl.bf.e_shaper_credit_1 << 1); + + + return SW_OK; +} + +sw_error_t +adpt_hppe_queue_shaper_time_slot_get(a_uint32_t dev_id, a_uint32_t *time_slot) +{ + sw_error_t rv = SW_OK; + union shp_slot_cfg_l0_u shp_slot_cfg_l0; + + memset(&shp_slot_cfg_l0, 0, sizeof(shp_slot_cfg_l0)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(time_slot); + + + rv = hppe_shp_slot_cfg_l0_get(dev_id, &shp_slot_cfg_l0); + + if( rv != SW_OK ) + return rv; + + *time_slot = shp_slot_cfg_l0.bf.l0_shp_slot_time; + + return SW_OK; +} + +sw_error_t +adpt_hppe_port_shaper_token_number_get(a_uint32_t dev_id, fal_port_t port_id, + fal_shaper_token_number_t *token_number) +{ + union psch_shp_credit_tbl_u psch_shp_credit_tbl; + union psch_shp_sign_tbl_u psch_shp_sign_tbl; + + memset(&psch_shp_credit_tbl, 0, sizeof(psch_shp_credit_tbl)); + memset(&psch_shp_sign_tbl, 0, sizeof(psch_shp_sign_tbl)); + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(token_number); + + if (port_id < 0 || port_id > 7) + return SW_BAD_PARAM; + + hppe_psch_shp_credit_tbl_get(dev_id, port_id, &psch_shp_credit_tbl); + + hppe_psch_shp_sign_tbl_get(dev_id, port_id, &psch_shp_sign_tbl); + + + token_number->c_token_number_negative_en = psch_shp_sign_tbl.bf.shaper_credit_neg; + token_number->c_token_number = psch_shp_credit_tbl.bf.shaper_credit; + + return SW_OK; +} +#endif + +sw_error_t +adpt_hppe_flow_shaper_token_number_set(a_uint32_t dev_id, a_uint32_t flow_id, + fal_shaper_token_number_t *token_number) +{ + union l1_shp_credit_tbl_u l1_shp_credit_tbl; + + memset(&l1_shp_credit_tbl, 0, sizeof(l1_shp_credit_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(token_number); + + if ((flow_id < 0) || (flow_id > 63)) + return SW_BAD_PARAM; + + + l1_shp_credit_tbl.bf.c_shaper_credit_neg = token_number->c_token_number_negative_en; + l1_shp_credit_tbl.bf.c_shaper_credit = token_number->c_token_number; + l1_shp_credit_tbl.bf.e_shaper_credit_neg = token_number->e_token_number_negative_en; + l1_shp_credit_tbl.bf.e_shaper_credit_0 = token_number->e_token_number & 0x1; + l1_shp_credit_tbl.bf.e_shaper_credit_1 = token_number->e_token_number >> 1; + + hppe_l1_shp_credit_tbl_set(dev_id, flow_id, &l1_shp_credit_tbl); + + return SW_OK; +} +#ifndef IN_SHAPER_MINI +sw_error_t +adpt_hppe_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 = SW_OK; + union l1_shp_credit_tbl_u l1_shp_credit_tbl; + + memset(&l1_shp_credit_tbl, 0, sizeof(l1_shp_credit_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(token_number); + + if ((flow_id < 0) || (flow_id > 63)) + return SW_BAD_PARAM; + + rv = hppe_l1_shp_credit_tbl_get(dev_id, flow_id, &l1_shp_credit_tbl); + + if( rv != SW_OK ) + return rv; + + token_number->c_token_number_negative_en = l1_shp_credit_tbl.bf.c_shaper_credit_neg; + token_number->c_token_number = l1_shp_credit_tbl.bf.c_shaper_credit; + token_number->e_token_number_negative_en = l1_shp_credit_tbl.bf.e_shaper_credit_neg; + token_number->e_token_number = l1_shp_credit_tbl.bf.e_shaper_credit_0 | + (l1_shp_credit_tbl.bf.e_shaper_credit_1 << 1); + + return SW_OK; +} +#endif + +sw_error_t +adpt_hppe_flow_shaper_set(a_uint32_t dev_id, a_uint32_t flow_id, + fal_shaper_config_t * shaper) +{ + sw_error_t rv = SW_OK; + union l1_shp_cfg_tbl_u l1_shp_cfg_tbl; + union l1_comp_cfg_tbl_u l1_comp_cfg_tbl; + a_uint32_t hppe_cir = 0, hppe_cbs = 0, hppe_eir= 0, hppe_ebs = 0; + a_uint64_t temp_cir = 0, temp_eir =0, temp_cbs =0, temp_ebs = 0; + a_uint32_t token_unit = 0; + fal_shaper_token_number_t token_number; + + memset(&l1_shp_cfg_tbl, 0, sizeof(l1_shp_cfg_tbl)); + memset(&l1_comp_cfg_tbl, 0, sizeof(l1_comp_cfg_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(shaper); + + if ((flow_id < 0) || (flow_id > 63)) + return SW_BAD_PARAM; + + if(ADPT_HPPE_SHAPER_METER_UNIT_BYTE == shaper->meter_unit) + { + if ((shaper->cir > BYTE_SHAPER_MAX_RATE) || (shaper->eir > BYTE_SHAPER_MAX_RATE)) + return SW_BAD_PARAM; + if ((shaper->cir < BYTE_SHAPER_MIN_RATE) && (shaper->cir != 0)) + return SW_BAD_PARAM; + if ((shaper->eir < BYTE_SHAPER_MIN_RATE) && (shaper->eir != 0)) + return SW_BAD_PARAM; + } + if(ADPT_HPPE_SHAPER_METER_UNIT_FRAME == shaper->meter_unit) + { + if ((shaper->cir > FRAME_SHAPER_MAX_RATE) || (shaper->eir > FRAME_SHAPER_MAX_RATE)) + return SW_BAD_PARAM; + if ((shaper->cir < FRAME_SHAPER_MIN_RATE) && (shaper->cir != 0)) + return SW_BAD_PARAM; + if ((shaper->eir < FRAME_SHAPER_MIN_RATE) && (shaper->eir != 0)) + return SW_BAD_PARAM; + } + + hppe_l1_comp_cfg_tbl_get(dev_id, flow_id, &l1_comp_cfg_tbl); + + temp_cir = ((a_uint64_t)shaper->cir) * 1000; + temp_cbs = ((a_uint64_t)shaper->cbs) * 1000; + temp_eir = ((a_uint64_t)shaper->eir) * 1000; + temp_ebs = ((a_uint64_t)shaper->ebs) * 1000; + + rv = __adpt_hppe_shaper_two_bucket_parameter_select(ADPT_HPPE_FLOW_SHAPER, + temp_cir, + temp_cbs, + temp_eir, + temp_ebs, + shaper->meter_unit, + &token_unit); + if( rv != SW_OK ) + return rv; + //printk("flow shaper meter unit is = %d\n", shaper->meter_unit); + //printk("flow shaper token unit is = %d\n", token_unit); + + __adpt_hppe_shaper_rate_to_refresh(ADPT_HPPE_FLOW_SHAPER, + shaper->cir, + &hppe_cir, + shaper->meter_unit, + token_unit); + + __adpt_hppe_shaper_rate_to_refresh(ADPT_HPPE_FLOW_SHAPER, + shaper->eir, + &hppe_eir, + shaper->meter_unit, + token_unit); + + __adpt_hppe_shaper_burst_size_to_bucket_size(shaper->cbs, + &hppe_cbs, + shaper->meter_unit, + token_unit); + + __adpt_hppe_shaper_burst_size_to_bucket_size(shaper->ebs, + &hppe_ebs, + shaper->meter_unit, + token_unit); + + l1_shp_cfg_tbl.bf.cf = shaper->couple_en; + l1_shp_cfg_tbl.bf.meter_unit = shaper->meter_unit; + l1_shp_cfg_tbl.bf.c_shaper_enable = shaper->c_shaper_en; + l1_shp_cfg_tbl.bf.cbs = hppe_cbs; + l1_shp_cfg_tbl.bf.cir = hppe_cir; + l1_shp_cfg_tbl.bf.e_shaper_enable = shaper->e_shaper_en; + l1_shp_cfg_tbl.bf.ebs = hppe_ebs; + l1_shp_cfg_tbl.bf.eir = hppe_eir; + l1_shp_cfg_tbl.bf.token_unit = token_unit; + l1_comp_cfg_tbl.bf.shaper_meter_len = shaper->shaper_frame_mode; + + hppe_l1_shp_cfg_tbl_set(dev_id, flow_id, &l1_shp_cfg_tbl); + + hppe_l1_comp_cfg_tbl_set(dev_id, flow_id, &l1_comp_cfg_tbl); + + if( A_FALSE == shaper->c_shaper_en) + { + token_number.c_token_number_negative_en = 0; + token_number.c_token_number = 0; + adpt_hppe_flow_shaper_token_number_set(dev_id, flow_id, &token_number); + } + if( A_FALSE == shaper->e_shaper_en) + { + token_number.e_token_number_negative_en = 0; + token_number.e_token_number = 0; + adpt_hppe_flow_shaper_token_number_set(dev_id, flow_id, &token_number); + } + + return SW_OK; +} +sw_error_t +adpt_hppe_port_shaper_set(a_uint32_t dev_id, fal_port_t port_id, + fal_shaper_config_t * shaper) +{ + sw_error_t rv = SW_OK; + union psch_shp_cfg_tbl_u psch_shp_cfg_tbl; + union psch_comp_cfg_tbl_u psch_comp_cfg_tbl; + a_uint64_t temp_cir = 0,temp_cbs; + a_uint32_t hppe_cir = 0, hppe_cbs = 0; + a_uint32_t token_unit = 0; + fal_shaper_token_number_t token_number; + + memset(&psch_shp_cfg_tbl, 0, sizeof(psch_shp_cfg_tbl)); + memset(&psch_comp_cfg_tbl, 0, sizeof(psch_comp_cfg_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(shaper); + + if (port_id < 0 || port_id > 7) + return SW_BAD_PARAM; + + if(ADPT_HPPE_SHAPER_METER_UNIT_BYTE == shaper->meter_unit) + { + if (shaper->cir > BYTE_SHAPER_MAX_RATE) + return SW_BAD_PARAM; + if ((shaper->cir < BYTE_SHAPER_MIN_RATE) && (shaper->cir != 0)) + return SW_BAD_PARAM; + } + if(ADPT_HPPE_SHAPER_METER_UNIT_FRAME == shaper->meter_unit) + { + if (shaper->cir > FRAME_SHAPER_MAX_RATE) + return SW_BAD_PARAM; + if ((shaper->cir < FRAME_SHAPER_MIN_RATE) && (shaper->cir != 0)) + return SW_BAD_PARAM; + } + + temp_cir = ((a_uint64_t)shaper->cir) * 1000; + temp_cbs = ((a_uint64_t)shaper->cbs) * 1000; + + rv = __adpt_hppe_shaper_one_bucket_parameter_select(ADPT_HPPE_PORT_SHAPER, + temp_cir, + temp_cbs, + shaper->meter_unit, + &token_unit); + if( rv != SW_OK ) + return rv; + + // printk("current shaper meter unit is = %d\n", shaper->meter_unit); + // printk("current shaper token unit is = %d\n", token_unit); + + __adpt_hppe_shaper_rate_to_refresh(ADPT_HPPE_PORT_SHAPER, + shaper->cir, + &hppe_cir, + shaper->meter_unit, + token_unit); + + __adpt_hppe_shaper_burst_size_to_bucket_size(shaper->cbs, + &hppe_cbs, + shaper->meter_unit, + token_unit); + + psch_shp_cfg_tbl.bf.meter_unit = shaper->meter_unit; + psch_shp_cfg_tbl.bf.shaper_enable = shaper->c_shaper_en; + psch_shp_cfg_tbl.bf.cbs = hppe_cbs; + psch_shp_cfg_tbl.bf.cir = hppe_cir; + psch_shp_cfg_tbl.bf.token_unit = token_unit; + + psch_comp_cfg_tbl.bf.shaper_meter_len = shaper->shaper_frame_mode; + + hppe_psch_shp_cfg_tbl_set(dev_id, port_id, &psch_shp_cfg_tbl); + + hppe_psch_comp_cfg_tbl_set(dev_id, port_id, &psch_comp_cfg_tbl); + + if( A_FALSE == shaper->c_shaper_en) + { + token_number.c_token_number_negative_en = 0; + token_number.c_token_number = 0; + adpt_hppe_port_shaper_token_number_set(dev_id, port_id, &token_number); + } + + return SW_OK; +} +sw_error_t +adpt_hppe_port_shaper_time_slot_set(a_uint32_t dev_id, a_uint32_t time_slot) +{ + sw_error_t rv = SW_OK; + union shp_slot_cfg_port_u shp_slot_cfg_port; + + memset(&shp_slot_cfg_port, 0, sizeof(shp_slot_cfg_port)); + ADPT_DEV_ID_CHECK(dev_id); + + if ((time_slot < 0x8) || (time_slot > 0xfff)) + return SW_BAD_PARAM; + + rv = hppe_shp_slot_cfg_port_get(dev_id, &shp_slot_cfg_port); + + if( rv != SW_OK ) + return rv; + + shp_slot_cfg_port.bf.port_shp_slot_time = time_slot; + hppe_shp_slot_cfg_port_set(dev_id, &shp_slot_cfg_port); + + __adpt_hppe_port_shaper_max_rate(time_slot); + + __adpt_hppe_shaper_max_burst_size(); + + return SW_OK; + +} +#ifndef IN_SHAPER_MINI +sw_error_t +adpt_hppe_flow_shaper_get(a_uint32_t dev_id, a_uint32_t flow_id, + fal_shaper_config_t * shaper) +{ + sw_error_t rv = SW_OK; + union l1_shp_cfg_tbl_u l1_shp_cfg_tbl; + union l1_comp_cfg_tbl_u l1_comp_cfg_tbl; + a_uint32_t hppe_cir =0, hppe_cbs = 0, hppe_eir = 0, hppe_ebs = 0; + + memset(&l1_shp_cfg_tbl, 0, sizeof(l1_shp_cfg_tbl)); + memset(&l1_comp_cfg_tbl, 0, sizeof(l1_comp_cfg_tbl)); + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(shaper); + + if (flow_id < 0 || flow_id > 63) + return SW_BAD_PARAM; + + hppe_l1_comp_cfg_tbl_get(dev_id, flow_id, &l1_comp_cfg_tbl); + + rv = hppe_l1_shp_cfg_tbl_get(dev_id, flow_id, &l1_shp_cfg_tbl); + + if( rv != SW_OK ) + return rv; + + hppe_cir = l1_shp_cfg_tbl.bf.cir; + hppe_cbs = l1_shp_cfg_tbl.bf.cbs; + hppe_eir = l1_shp_cfg_tbl.bf.eir; + hppe_ebs= l1_shp_cfg_tbl.bf.ebs; + + __adpt_hppe_shaper_refresh_to_rate(ADPT_HPPE_FLOW_SHAPER, + hppe_cir, + &shaper->cir, + l1_shp_cfg_tbl.bf.meter_unit, + l1_shp_cfg_tbl.bf.token_unit); + + __adpt_hppe_shaper_refresh_to_rate(ADPT_HPPE_FLOW_SHAPER, + hppe_eir, + &shaper->eir, + l1_shp_cfg_tbl.bf.meter_unit, + l1_shp_cfg_tbl.bf.token_unit); + + + __adpt_hppe_shaper_bucket_size_to_burst_size(hppe_cbs, + &shaper->cbs, + l1_shp_cfg_tbl.bf.meter_unit, + l1_shp_cfg_tbl.bf.token_unit); + + __adpt_hppe_shaper_bucket_size_to_burst_size(hppe_ebs, + &shaper->ebs, + l1_shp_cfg_tbl.bf.meter_unit, + l1_shp_cfg_tbl.bf.token_unit); + + shaper->couple_en = l1_shp_cfg_tbl.bf.cf; + shaper->meter_unit = l1_shp_cfg_tbl.bf.meter_unit; + shaper->c_shaper_en = l1_shp_cfg_tbl.bf.c_shaper_enable; + shaper->e_shaper_en = l1_shp_cfg_tbl.bf.e_shaper_enable; + + shaper->shaper_frame_mode = l1_comp_cfg_tbl.bf.shaper_meter_len; + + return SW_OK; +} +#endif + +sw_error_t +adpt_hppe_queue_shaper_set(a_uint32_t dev_id,a_uint32_t queue_id, + fal_shaper_config_t * shaper) +{ + sw_error_t rv = SW_OK; + union l0_shp_cfg_tbl_u l0_shp_cfg_tbl; + union l0_comp_cfg_tbl_u l0_comp_cfg_tbl; + a_uint32_t hppe_cir = 0, hppe_cbs = 0, hppe_eir= 0, hppe_ebs = 0; + a_uint32_t token_unit = 0; + a_uint64_t temp_cir = 0, temp_eir =0, temp_cbs =0, temp_ebs = 0; + fal_shaper_token_number_t token_number; + + memset(&l0_shp_cfg_tbl, 0, sizeof(l0_shp_cfg_tbl)); + memset(&l0_comp_cfg_tbl, 0, sizeof(l0_comp_cfg_tbl)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(shaper); + + if (queue_id < 0 || queue_id > 299) + return SW_BAD_PARAM; + + if(ADPT_HPPE_SHAPER_METER_UNIT_BYTE == shaper->meter_unit) + { + if ((shaper->cir > BYTE_SHAPER_MAX_RATE) || (shaper->eir > BYTE_SHAPER_MAX_RATE)) + return SW_BAD_PARAM; + if ((shaper->cir < BYTE_SHAPER_MIN_RATE) && (shaper->cir != 0)) + return SW_BAD_PARAM; + if ((shaper->eir < BYTE_SHAPER_MIN_RATE) && (shaper->eir != 0)) + return SW_BAD_PARAM; + } + if(ADPT_HPPE_SHAPER_METER_UNIT_FRAME == shaper->meter_unit) + { + if ((shaper->cir > FRAME_SHAPER_MAX_RATE) || (shaper->eir > FRAME_SHAPER_MAX_RATE)) + return SW_BAD_PARAM; + if ((shaper->cir < FRAME_SHAPER_MIN_RATE) && (shaper->cir != 0)) + return SW_BAD_PARAM; + if ((shaper->eir < FRAME_SHAPER_MIN_RATE) && (shaper->eir != 0)) + return SW_BAD_PARAM; + } + + hppe_l0_comp_cfg_tbl_get(dev_id, queue_id, &l0_comp_cfg_tbl); + + temp_cir = ((a_uint64_t)shaper->cir) * 1000; + temp_cbs = ((a_uint64_t)shaper->cbs) * 1000; + temp_eir = ((a_uint64_t)shaper->eir) * 1000; + temp_ebs = ((a_uint64_t)shaper->ebs) * 1000; + + rv = __adpt_hppe_shaper_two_bucket_parameter_select(ADPT_HPPE_QUEUE_SHAPER, + temp_cir, + temp_cbs, + temp_eir, + temp_ebs, + shaper->meter_unit, + &token_unit); + if( rv != SW_OK ) + return rv; + //printk("queue shaper meter unit is = %d\n", shaper->meter_unit); + //printk("queue shaper token unit is = %d\n", token_unit); + + __adpt_hppe_shaper_rate_to_refresh(ADPT_HPPE_QUEUE_SHAPER, + shaper->cir, + &hppe_cir, + shaper->meter_unit, + token_unit); + + __adpt_hppe_shaper_rate_to_refresh(ADPT_HPPE_QUEUE_SHAPER, + shaper->eir, + &hppe_eir, + shaper->meter_unit, + token_unit); + + __adpt_hppe_shaper_burst_size_to_bucket_size(shaper->cbs, + &hppe_cbs, + shaper->meter_unit, + token_unit); + + __adpt_hppe_shaper_burst_size_to_bucket_size(shaper->ebs, + &hppe_ebs, + shaper->meter_unit, + token_unit); + + l0_shp_cfg_tbl.bf.cf = shaper->couple_en; + l0_shp_cfg_tbl.bf.meter_unit = shaper->meter_unit; + l0_shp_cfg_tbl.bf.c_shaper_enable = shaper->c_shaper_en; + l0_shp_cfg_tbl.bf.cbs = hppe_cbs; + l0_shp_cfg_tbl.bf.cir = hppe_cir; + l0_shp_cfg_tbl.bf.e_shaper_enable = shaper->e_shaper_en; + l0_shp_cfg_tbl.bf.ebs = hppe_ebs; + l0_shp_cfg_tbl.bf.eir = hppe_eir; + l0_shp_cfg_tbl.bf.token_unit = token_unit; + l0_comp_cfg_tbl.bf.shaper_meter_len = shaper->shaper_frame_mode; + + hppe_l0_shp_cfg_tbl_set(dev_id, queue_id, &l0_shp_cfg_tbl); + + hppe_l0_comp_cfg_tbl_set(dev_id, queue_id, &l0_comp_cfg_tbl); + + if( A_FALSE == shaper->c_shaper_en) + { + token_number.c_token_number_negative_en = 0; + token_number.c_token_number = 0; + adpt_hppe_queue_shaper_token_number_set(dev_id, queue_id, &token_number); + } + if( A_FALSE == shaper->e_shaper_en) + { + token_number.e_token_number_negative_en = 0; + token_number.e_token_number = 0; + adpt_hppe_queue_shaper_token_number_set(dev_id, queue_id, &token_number); + } + + return SW_OK; + +} +sw_error_t +adpt_hppe_queue_shaper_time_slot_set(a_uint32_t dev_id, a_uint32_t time_slot) +{ + union shp_slot_cfg_l0_u shp_slot_cfg_l0; + sw_error_t rv = SW_OK; + + memset(&shp_slot_cfg_l0, 0, sizeof(shp_slot_cfg_l0)); + ADPT_DEV_ID_CHECK(dev_id); + + if ((time_slot < 0x12c) || (time_slot > 0xfff)) + return SW_BAD_PARAM; + + rv = hppe_shp_slot_cfg_l0_get(dev_id, &shp_slot_cfg_l0); + + if( rv != SW_OK ) + return rv; + + shp_slot_cfg_l0.bf.l0_shp_slot_time = time_slot; + hppe_shp_slot_cfg_l0_set(dev_id, &shp_slot_cfg_l0); + + __adpt_hppe_queue_shaper_max_rate(time_slot); + + return SW_OK; + +} + +sw_error_t +adpt_hppe_shaper_ipg_preamble_length_set(a_uint32_t dev_id, a_uint32_t ipg_pre_length) +{ + union ipg_pre_len_cfg_u ipg_pre_len_cfg; + + memset(&ipg_pre_len_cfg, 0, sizeof(ipg_pre_len_cfg)); + ADPT_DEV_ID_CHECK(dev_id); + + if (ipg_pre_length > 0x1f) + return SW_BAD_PARAM; + + hppe_ipg_pre_len_cfg_get(dev_id, &ipg_pre_len_cfg); + ipg_pre_len_cfg.bf.ipg_pre_len = ipg_pre_length; + + hppe_ipg_pre_len_cfg_set(dev_id, &ipg_pre_len_cfg); + + return SW_OK; +} + +#ifndef IN_SHAPER_MINI +sw_error_t +adpt_hppe_shaper_ipg_preamble_length_get(a_uint32_t dev_id, a_uint32_t *ipg_pre_length) +{ + sw_error_t rv = SW_OK; + union ipg_pre_len_cfg_u ipg_pre_len_cfg; + + memset(&ipg_pre_len_cfg, 0, sizeof(ipg_pre_len_cfg)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(ipg_pre_length); + + rv = hppe_ipg_pre_len_cfg_get(dev_id, &ipg_pre_len_cfg); + + if( rv != SW_OK ) + return rv; + + *ipg_pre_length = ipg_pre_len_cfg.bf.ipg_pre_len; + + return SW_OK; +} +#endif + +void adpt_hppe_shaper_func_bitmap_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_shaper_func_bitmap = ((1 << FUNC_ADPT_FLOW_SHAPER_SET)| + (1 << FUNC_ADPT_QUEUE_SHAPER_GET)| + (1 << FUNC_ADPT_QUEUE_SHAPER_TOKEN_NUMBER_SET)| + (1 << FUNC_ADPT_PORT_SHAPER_GET)| + (1 << FUNC_ADPT_FLOW_SHAPER_TIME_SLOT_GET)| + (1 << FUNC_ADPT_PORT_SHAPER_TIME_SLOT_GET)| + (1 << FUNC_ADPT_FLOW_SHAPER_TIME_SLOT_SET)| + (1 << FUNC_ADPT_PORT_SHAPER_TOKEN_NUMBER_SET)| + (1 << FUNC_ADPT_QUEUE_SHAPER_TOKEN_NUMBER_GET)| + (1 << FUNC_ADPT_QUEUE_SHAPER_TIME_SLOT_GET)| + (1 << FUNC_ADPT_PORT_SHAPER_TOKEN_NUMBER_GET)| + (1 << FUNC_ADPT_FLOW_SHAPER_TOKEN_NUMBER_SET)| + (1 << FUNC_ADPT_FLOW_SHAPER_TOKEN_NUMBER_GET)| + (1 << FUNC_ADPT_PORT_SHAPER_SET)| + (1 << FUNC_ADPT_PORT_SHAPER_TIME_SLOT_SET)| + (1 << FUNC_ADPT_FLOW_SHAPER_GET)| + (1 << FUNC_ADPT_QUEUE_SHAPER_SET)| + (1 << FUNC_ADPT_QUEUE_SHAPER_TIME_SLOT_SET)| + (1 << FUNC_ADPT_SHAPER_IPG_PREAMBLE_LENGTH_SET)| + (1 << FUNC_ADPT_SHAPER_IPG_PREAMBLE_LENGTH_GET)); + + return; + +} + +static void adpt_hppe_shaper_func_unregister(a_uint32_t dev_id, adpt_api_t *p_adpt_api) +{ + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_flow_shaper_set = NULL; + p_adpt_api->adpt_queue_shaper_get = NULL; + p_adpt_api->adpt_queue_shaper_token_number_set = NULL; + p_adpt_api->adpt_port_shaper_get = NULL; + p_adpt_api->adpt_flow_shaper_time_slot_get = NULL; + p_adpt_api->adpt_port_shaper_time_slot_get = NULL; + p_adpt_api->adpt_flow_shaper_time_slot_set = NULL; + p_adpt_api->adpt_port_shaper_token_number_set = NULL; + p_adpt_api->adpt_queue_shaper_token_number_get = NULL; + p_adpt_api->adpt_queue_shaper_time_slot_get = NULL; + p_adpt_api->adpt_port_shaper_token_number_get = NULL; + p_adpt_api->adpt_flow_shaper_token_number_set = NULL; + p_adpt_api->adpt_flow_shaper_token_number_get = NULL; + p_adpt_api->adpt_port_shaper_set = NULL; + p_adpt_api->adpt_port_shaper_time_slot_set = NULL; + p_adpt_api->adpt_flow_shaper_get = NULL; + p_adpt_api->adpt_queue_shaper_set = NULL; + p_adpt_api->adpt_queue_shaper_time_slot_set = NULL; + p_adpt_api->adpt_shaper_ipg_preamble_length_set = NULL; + p_adpt_api->adpt_shaper_ipg_preamble_length_get = NULL; + + return; + +} + +sw_error_t adpt_hppe_shaper_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return SW_FAIL; + + adpt_hppe_shaper_func_unregister(dev_id, p_adpt_api); + +#ifndef IN_SHAPER_MINI + if(p_adpt_api->adpt_shaper_func_bitmap & (1 << FUNC_ADPT_PORT_SHAPER_GET)) + { + p_adpt_api->adpt_port_shaper_get = adpt_hppe_port_shaper_get; + } + if(p_adpt_api->adpt_shaper_func_bitmap & (1 << FUNC_ADPT_FLOW_SHAPER_TIME_SLOT_GET)) + { + p_adpt_api->adpt_flow_shaper_time_slot_get = adpt_hppe_flow_shaper_time_slot_get; + } + if(p_adpt_api->adpt_shaper_func_bitmap & (1 << FUNC_ADPT_PORT_SHAPER_TIME_SLOT_GET)) + { + p_adpt_api->adpt_port_shaper_time_slot_get = adpt_hppe_port_shaper_time_slot_get; + } + if(p_adpt_api->adpt_shaper_func_bitmap & (1 << FUNC_ADPT_QUEUE_SHAPER_TOKEN_NUMBER_GET)) + { + p_adpt_api->adpt_queue_shaper_token_number_get = + adpt_hppe_queue_shaper_token_number_get; + } + if(p_adpt_api->adpt_shaper_func_bitmap & (1 << FUNC_ADPT_QUEUE_SHAPER_TIME_SLOT_GET)) + { + p_adpt_api->adpt_queue_shaper_time_slot_get = adpt_hppe_queue_shaper_time_slot_get; + } + if(p_adpt_api->adpt_shaper_func_bitmap & (1 << FUNC_ADPT_PORT_SHAPER_TOKEN_NUMBER_GET)) + { + p_adpt_api->adpt_port_shaper_token_number_get = + adpt_hppe_port_shaper_token_number_get; + } + if(p_adpt_api->adpt_shaper_func_bitmap & (1 << FUNC_ADPT_FLOW_SHAPER_TOKEN_NUMBER_GET)) + { + p_adpt_api->adpt_flow_shaper_token_number_get = + adpt_hppe_flow_shaper_token_number_get; + } + if(p_adpt_api->adpt_shaper_func_bitmap & (1 << FUNC_ADPT_FLOW_SHAPER_GET)) + { + p_adpt_api->adpt_flow_shaper_get = adpt_hppe_flow_shaper_get; + } + if(p_adpt_api->adpt_shaper_func_bitmap & (1 << FUNC_ADPT_SHAPER_IPG_PREAMBLE_LENGTH_GET)) + { + p_adpt_api->adpt_shaper_ipg_preamble_length_get = + adpt_hppe_shaper_ipg_preamble_length_get; + } +#endif + if(p_adpt_api->adpt_shaper_func_bitmap & (1 << FUNC_ADPT_FLOW_SHAPER_SET)) + { + p_adpt_api->adpt_flow_shaper_set = adpt_hppe_flow_shaper_set; + } + if(p_adpt_api->adpt_shaper_func_bitmap & (1 << FUNC_ADPT_QUEUE_SHAPER_SET)) + { + p_adpt_api->adpt_queue_shaper_set = adpt_hppe_queue_shaper_set; + } + if(p_adpt_api->adpt_shaper_func_bitmap & (1 << FUNC_ADPT_QUEUE_SHAPER_GET)) + { + p_adpt_api->adpt_queue_shaper_get = adpt_hppe_queue_shaper_get; + } + if(p_adpt_api->adpt_shaper_func_bitmap & (1 << FUNC_ADPT_PORT_SHAPER_SET)) + { + p_adpt_api->adpt_port_shaper_set = adpt_hppe_port_shaper_set; + } + if(p_adpt_api->adpt_shaper_func_bitmap & (1 << FUNC_ADPT_SHAPER_IPG_PREAMBLE_LENGTH_SET)) + { + p_adpt_api->adpt_shaper_ipg_preamble_length_set = + adpt_hppe_shaper_ipg_preamble_length_set; + } + if(p_adpt_api->adpt_shaper_func_bitmap & (1 << FUNC_ADPT_QUEUE_SHAPER_TOKEN_NUMBER_SET)) + { + p_adpt_api->adpt_queue_shaper_token_number_set = + adpt_hppe_queue_shaper_token_number_set; + } + if(p_adpt_api->adpt_shaper_func_bitmap & (1 << FUNC_ADPT_PORT_SHAPER_TOKEN_NUMBER_SET)) + { + p_adpt_api->adpt_port_shaper_token_number_set = + adpt_hppe_port_shaper_token_number_set; + } + if(p_adpt_api->adpt_shaper_func_bitmap & (1 << FUNC_ADPT_FLOW_SHAPER_TOKEN_NUMBER_SET)) + { + p_adpt_api->adpt_flow_shaper_token_number_set = + adpt_hppe_flow_shaper_token_number_set; + } + if(p_adpt_api->adpt_shaper_func_bitmap & (1 << FUNC_ADPT_PORT_SHAPER_TIME_SLOT_SET)) + { + p_adpt_api->adpt_port_shaper_time_slot_set = adpt_hppe_port_shaper_time_slot_set; + } + if(p_adpt_api->adpt_shaper_func_bitmap & (1 << FUNC_ADPT_FLOW_SHAPER_TIME_SLOT_SET)) + { + p_adpt_api->adpt_flow_shaper_time_slot_set = adpt_hppe_flow_shaper_time_slot_set; + } + if(p_adpt_api->adpt_shaper_func_bitmap & (1 << FUNC_ADPT_QUEUE_SHAPER_TIME_SLOT_SET)) + { + p_adpt_api->adpt_queue_shaper_time_slot_set = adpt_hppe_queue_shaper_time_slot_set; + } + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_stp.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_stp.c new file mode 100755 index 000000000..634c3c4f6 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_stp.c @@ -0,0 +1,135 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hppe_stp_reg.h" +#include "hppe_stp.h" +#include "adpt.h" + +sw_error_t +adpt_hppe_stp_port_state_get(a_uint32_t dev_id, a_uint32_t st_id, + fal_port_t port_id, fal_stp_state_t * state) +{ + union cst_state_u cst_state; + + memset(&cst_state, 0, sizeof(cst_state)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(state); + if (FAL_SINGLE_STP_ID != st_id) + return SW_BAD_PARAM; + + SW_RTN_ON_ERROR(hppe_cst_state_get(dev_id, port_id, &cst_state)); + + if (cst_state.bf.port_state == 0) + *state = FAL_STP_DISABLED; + else if (cst_state.bf.port_state == 1) + *state = FAL_STP_BLOKING; + else if (cst_state.bf.port_state == 2) + *state = FAL_STP_LEARNING; + else if (cst_state.bf.port_state == 3) + *state = FAL_STP_FARWARDING; + else + *state = FAL_STP_STATE_BUTT; + + return SW_OK; +} + +sw_error_t +adpt_hppe_stp_port_state_set(a_uint32_t dev_id, a_uint32_t st_id, + fal_port_t port_id, fal_stp_state_t state) +{ + union cst_state_u cst_state; + + memset(&cst_state, 0, sizeof(cst_state)); + + /* stp port_id just support physical port, not support trunk and virtual port */ + if (FAL_PORT_ID_TYPE(port_id) != 0) + return SW_BAD_PARAM; + + if (port_id >= CST_STATE_MAX_ENTRY) + return SW_OUT_OF_RANGE; + + ADPT_DEV_ID_CHECK(dev_id); + if (FAL_SINGLE_STP_ID != st_id) + return SW_BAD_PARAM; + + if (state == FAL_STP_DISABLED) + cst_state.bf.port_state = 0; + else if (state == FAL_STP_BLOKING || state == FAL_STP_LISTENING) + cst_state.bf.port_state = 1; + else if (state == FAL_STP_LEARNING) + cst_state.bf.port_state = 2; + else if (state == FAL_STP_FARWARDING) + cst_state.bf.port_state = 3; + + SW_RTN_ON_ERROR(hppe_cst_state_set(dev_id, port_id, &cst_state)); + + return SW_OK; +} + +void adpt_hppe_stp_func_bitmap_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_stp_func_bitmap = ((1 << FUNC_STP_PORT_STATE_SET) | + (1 << FUNC_STP_PORT_STATE_GET)); + + return; +} + +static void adpt_hppe_stp_func_unregister(a_uint32_t dev_id, adpt_api_t *p_adpt_api) +{ + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_stp_port_state_get = NULL; + p_adpt_api->adpt_stp_port_state_set = NULL; + + return; +} + +sw_error_t +adpt_hppe_stp_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return SW_FAIL; + + adpt_hppe_stp_func_unregister(dev_id, p_adpt_api); + + if (p_adpt_api->adpt_stp_func_bitmap & (1 << FUNC_STP_PORT_STATE_GET)) + p_adpt_api->adpt_stp_port_state_get = adpt_hppe_stp_port_state_get; + if (p_adpt_api->adpt_stp_func_bitmap & (1 << FUNC_STP_PORT_STATE_SET)) + p_adpt_api->adpt_stp_port_state_set = adpt_hppe_stp_port_state_set; + + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_trunk.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_trunk.c new file mode 100755 index 000000000..0a7834f11 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_trunk.c @@ -0,0 +1,369 @@ +/* + * 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 + * @{ + */ +#include "sw.h" + +#include "hppe_trunk_reg.h" +#include "hppe_trunk.h" +#include "adpt.h" +#include "hppe_fdb_reg.h" +#include "hppe_fdb.h" + +sw_error_t +adpt_hppe_trunk_fail_over_en_get(a_uint32_t dev_id, a_bool_t * fail_over) +{ + union l2_global_conf_u l2_global_conf; + + memset(&l2_global_conf, 0, sizeof(l2_global_conf)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(fail_over); + + SW_RTN_ON_ERROR(hppe_l2_global_conf_get(dev_id, &l2_global_conf)); + + *fail_over = l2_global_conf.bf.failover_en; + + return SW_OK; +} + +sw_error_t +adpt_hppe_trunk_hash_mode_get(a_uint32_t dev_id, a_uint32_t * hash_mode) +{ + union trunk_hash_field_reg_u trunk_hash_field; + + memset(&trunk_hash_field, 0, sizeof(trunk_hash_field)); + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(hash_mode); + + SW_RTN_ON_ERROR(hppe_trunk_hash_field_reg_get(dev_id, &trunk_hash_field)); + + *hash_mode = 0; + + if (trunk_hash_field.bf.mac_da_incl) + *hash_mode |= FAL_TRUNK_HASH_KEY_DA; + + if (trunk_hash_field.bf.mac_sa_incl) + *hash_mode |= FAL_TRUNK_HASH_KEY_SA; + + if (trunk_hash_field.bf.src_ip_incl) + *hash_mode |= FAL_TRUNK_HASH_KEY_SIP; + + if (trunk_hash_field.bf.dst_ip_incl) + *hash_mode |= FAL_TRUNK_HASH_KEY_DIP; + + if (trunk_hash_field.bf.src_port_incl) + *hash_mode |= FAL_TRUNK_HASH_KEY_SRC_PORT; + + if (trunk_hash_field.bf.l4_src_port_incl) + *hash_mode |= FAL_TRUNK_HASH_KEY_L4_SRC_PORT; + + if (trunk_hash_field.bf.l4_dst_port_incl) + *hash_mode |= FAL_TRUNK_HASH_KEY_L4_DST_PORT; + + if (trunk_hash_field.bf.udf0_incl) + *hash_mode |= FAL_TRUNK_HASH_KEY_UDF0; + + if (trunk_hash_field.bf.udf1_incl) + *hash_mode |= FAL_TRUNK_HASH_KEY_UDF1; + + if (trunk_hash_field.bf.udf2_incl) + *hash_mode |= FAL_TRUNK_HASH_KEY_UDF2; + + if (trunk_hash_field.bf.udf3_incl) + *hash_mode |= FAL_TRUNK_HASH_KEY_UDF3; + + return SW_OK; +} + +sw_error_t +adpt_hppe_trunk_group_get(a_uint32_t dev_id, a_uint32_t trunk_id, + a_bool_t * enable, fal_pbmp_t * member) +{ + union trunk_filter_u trunk_filter; + union port_trunk_id_u port_trunk_id; + a_uint32_t port_id; + + memset(&trunk_filter, 0, sizeof(trunk_filter)); + memset(&port_trunk_id, 0, sizeof(port_trunk_id)); + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + ADPT_NULL_POINT_CHECK(member); + + *enable = A_FALSE; + for (port_id = 0; port_id < FAL_MAX_PORT_NUMBER; port_id ++) + { + SW_RTN_ON_ERROR(hppe_port_trunk_id_get(dev_id, port_id, &port_trunk_id)); + if ((trunk_id == port_trunk_id.bf.trunk_id) && (A_TRUE == port_trunk_id.bf.trunk_en)) + { + *enable = A_TRUE; + break; + } + } + + SW_RTN_ON_ERROR(hppe_trunk_filter_get(dev_id, trunk_id, &trunk_filter)); + + *member = trunk_filter.bf.mem_bitmap; + + return SW_OK; +} + +sw_error_t +adpt_hppe_trunk_group_set(a_uint32_t dev_id, a_uint32_t trunk_id, + a_bool_t enable, fal_pbmp_t member) +{ + union trunk_filter_u trunk_filter; + union port_trunk_id_u port_trunk_id; + union trunk_member_u trunk_member; + a_uint32_t i, j, cnt = 0, data[4] = {0,0,0,0}; + + memset(&trunk_filter, 0, sizeof(trunk_filter)); + memset(&port_trunk_id, 0, sizeof(port_trunk_id)); + memset(&trunk_member, 0, sizeof(trunk_member)); + + ADPT_DEV_ID_CHECK(dev_id); + + if (trunk_id >= TRUNK_FILTER_MAX_ENTRY) + { + return SW_OUT_OF_RANGE; + } + + if(enable == A_TRUE && member == 0) + { + SSDK_ERROR("trunk member cannot be 0 when trunk group was enabled\n"); + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + for (i = 0; i < FAL_MAX_PORT_NUMBER; i++) + { + if (member & (0x1 << i)) + { + if (FAL_TRUNK_GROUP_MAX_MEMEBER <= cnt) + { + return SW_BAD_PARAM; + } + data[cnt] = i; + cnt++; + } + } + } + + for (i = 0; i < FAL_MAX_PORT_NUMBER; i++) + { + SW_RTN_ON_ERROR(hppe_port_trunk_id_get(dev_id, i, &port_trunk_id)); + if (port_trunk_id.bf.trunk_id == trunk_id) { + port_trunk_id.bf.trunk_en = A_FALSE; + SW_RTN_ON_ERROR(hppe_port_trunk_id_set(dev_id, i, &port_trunk_id)); + } + } + + for (j = 0; j < FAL_MAX_PORT_NUMBER; j++) + { + if (member & (0x1 << j)) + { + port_trunk_id.bf.trunk_en = enable; + port_trunk_id.bf.trunk_id = trunk_id; + SW_RTN_ON_ERROR(hppe_port_trunk_id_set(dev_id, j, &port_trunk_id)); + } + } + + if (A_TRUE == enable) + trunk_filter.bf.mem_bitmap = member; + else + trunk_filter.bf.mem_bitmap = 0; + + SW_RTN_ON_ERROR(hppe_trunk_filter_set(dev_id, trunk_id, &trunk_filter)); + + if (A_TRUE == enable) + { + switch (cnt) { + case 1: + trunk_member.bf.member_0_port_id = data[0]; + trunk_member.bf.member_1_port_id = data[0]; + trunk_member.bf.member_2_port_id = data[0]; + trunk_member.bf.member_3_port_id = data[0]; + trunk_member.bf.member_4_port_id = data[0]; + trunk_member.bf.member_5_port_id = data[0]; + trunk_member.bf.member_6_port_id = data[0]; + trunk_member.bf.member_7_port_id = data[0]; + break; + case 2: + trunk_member.bf.member_0_port_id = data[0]; + trunk_member.bf.member_1_port_id = data[1]; + trunk_member.bf.member_2_port_id = data[0]; + trunk_member.bf.member_3_port_id = data[1]; + trunk_member.bf.member_4_port_id = data[0]; + trunk_member.bf.member_5_port_id = data[1]; + trunk_member.bf.member_6_port_id = data[0]; + trunk_member.bf.member_7_port_id = data[1]; + break; + case 3: + trunk_member.bf.member_0_port_id = data[0]; + trunk_member.bf.member_1_port_id = data[1]; + trunk_member.bf.member_2_port_id = data[2]; + trunk_member.bf.member_3_port_id = data[0]; + trunk_member.bf.member_4_port_id = data[1]; + trunk_member.bf.member_5_port_id = data[2]; + trunk_member.bf.member_6_port_id = data[0]; + trunk_member.bf.member_7_port_id = data[1]; + break; + case 4: + trunk_member.bf.member_0_port_id = data[0]; + trunk_member.bf.member_1_port_id = data[1]; + trunk_member.bf.member_2_port_id = data[2]; + trunk_member.bf.member_3_port_id = data[3]; + trunk_member.bf.member_4_port_id = data[0]; + trunk_member.bf.member_5_port_id = data[1]; + trunk_member.bf.member_6_port_id = data[2]; + trunk_member.bf.member_7_port_id = data[3]; + break; + } + } + + SW_RTN_ON_ERROR(hppe_trunk_member_set(dev_id, trunk_id, &trunk_member)); + + return SW_OK; +} +sw_error_t +adpt_hppe_trunk_fail_over_en_set(a_uint32_t dev_id, a_bool_t fail_over) +{ + union l2_global_conf_u l2_global_conf; + + memset(&l2_global_conf, 0, sizeof(l2_global_conf)); + ADPT_DEV_ID_CHECK(dev_id); + + SW_RTN_ON_ERROR(hppe_l2_global_conf_get(dev_id, &l2_global_conf)); + + l2_global_conf.bf.failover_en = fail_over; + + SW_RTN_ON_ERROR(hppe_l2_global_conf_set(dev_id, &l2_global_conf)); + + return SW_OK; +} +sw_error_t +adpt_hppe_trunk_hash_mode_set(a_uint32_t dev_id, a_uint32_t hash_mode) +{ + union trunk_hash_field_reg_u trunk_hash_field; + + memset(&trunk_hash_field, 0, sizeof(trunk_hash_field)); + ADPT_DEV_ID_CHECK(dev_id); + + if (FAL_TRUNK_HASH_KEY_DA & hash_mode) + trunk_hash_field.bf.mac_da_incl = 1; + + if (FAL_TRUNK_HASH_KEY_SA & hash_mode) + trunk_hash_field.bf.mac_sa_incl = 1; + + if (FAL_TRUNK_HASH_KEY_DIP & hash_mode) + trunk_hash_field.bf.dst_ip_incl = 1; + + if (FAL_TRUNK_HASH_KEY_SIP & hash_mode) + trunk_hash_field.bf.src_ip_incl = 1; + + if (FAL_TRUNK_HASH_KEY_SRC_PORT & hash_mode) + trunk_hash_field.bf.src_port_incl = 1; + + if (FAL_TRUNK_HASH_KEY_L4_SRC_PORT & hash_mode) + trunk_hash_field.bf.l4_src_port_incl = 1; + + if (FAL_TRUNK_HASH_KEY_L4_DST_PORT & hash_mode) + trunk_hash_field.bf.l4_dst_port_incl = 1; + + if (FAL_TRUNK_HASH_KEY_UDF0 & hash_mode) + trunk_hash_field.bf.udf0_incl = 1; + + if (FAL_TRUNK_HASH_KEY_UDF1 & hash_mode) + trunk_hash_field.bf.udf1_incl = 1; + + if (FAL_TRUNK_HASH_KEY_UDF2 & hash_mode) + trunk_hash_field.bf.udf2_incl = 1; + + if (FAL_TRUNK_HASH_KEY_UDF3 & hash_mode) + trunk_hash_field.bf.udf3_incl = 1; + + SW_RTN_ON_ERROR(hppe_trunk_hash_field_reg_set(dev_id, &trunk_hash_field)); + + return SW_OK; +} + +void adpt_hppe_trunk_func_bitmap_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_trunk_func_bitmap = ((1 << FUNC_TRUNK_GROUP_SET) | + (1 << FUNC_TRUNK_GROUP_GET) | + (1 << FUNC_TRUNK_HASH_MODE_SET) | + (1 << FUNC_TRUNK_HASH_MODE_GET) | + (1 << FUNC_TRUNK_FAILOVER_ENABLE) | + (1 << FUNC_TRUNK_FAILOVER_STATUS_GET)); + + return; +} + +static void adpt_hppe_trunk_func_unregister(a_uint32_t dev_id, adpt_api_t *p_adpt_api) +{ + if(p_adpt_api == NULL) + return; + + p_adpt_api->adpt_trunk_fail_over_en_get = NULL; + p_adpt_api->adpt_trunk_hash_mode_get = NULL; + p_adpt_api->adpt_trunk_group_get = NULL; + p_adpt_api->adpt_trunk_group_set = NULL; + p_adpt_api->adpt_trunk_fail_over_en_set = NULL; + p_adpt_api->adpt_trunk_hash_mode_set = NULL; + + return; +} + +sw_error_t adpt_hppe_trunk_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return SW_FAIL; + + adpt_hppe_trunk_func_unregister(dev_id, p_adpt_api); + + if (p_adpt_api->adpt_trunk_func_bitmap & (1 << FUNC_TRUNK_FAILOVER_STATUS_GET)) + p_adpt_api->adpt_trunk_fail_over_en_get = adpt_hppe_trunk_fail_over_en_get; + if (p_adpt_api->adpt_trunk_func_bitmap & (1 << FUNC_TRUNK_HASH_MODE_GET)) + p_adpt_api->adpt_trunk_hash_mode_get = adpt_hppe_trunk_hash_mode_get; + if (p_adpt_api->adpt_trunk_func_bitmap & (1 << FUNC_TRUNK_GROUP_GET)) + p_adpt_api->adpt_trunk_group_get = adpt_hppe_trunk_group_get; + if (p_adpt_api->adpt_trunk_func_bitmap & (1 << FUNC_TRUNK_GROUP_SET)) + p_adpt_api->adpt_trunk_group_set = adpt_hppe_trunk_group_set; + if (p_adpt_api->adpt_trunk_func_bitmap & (1 << FUNC_TRUNK_FAILOVER_ENABLE)) + p_adpt_api->adpt_trunk_fail_over_en_set = adpt_hppe_trunk_fail_over_en_set; + if (p_adpt_api->adpt_trunk_func_bitmap & (1 << FUNC_TRUNK_HASH_MODE_SET)) + p_adpt_api->adpt_trunk_hash_mode_set = adpt_hppe_trunk_hash_mode_set; + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_uniphy.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_uniphy.c new file mode 100755 index 000000000..959e4a4d0 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_uniphy.c @@ -0,0 +1,791 @@ +/* + * 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. + */ + + +/** + * @defgroup + * @{ + */ +#include "sw.h" +#include "hppe_uniphy_reg.h" +#include "hppe_uniphy.h" +#include "hppe_init.h" +#include "ssdk_init.h" +#include "ssdk_clk.h" +#include "ssdk_dts.h" +#include "adpt.h" +#include "hppe_reg_access.h" +#include "hsl_phy.h" +#include "hsl_port_prop.h" +#include "adpt_hppe.h" +#if defined(CPPE) +#include "adpt_cppe_uniphy.h" +#include "adpt_cppe_portctrl.h" +#endif + +extern void adpt_hppe_gcc_port_speed_clock_set(a_uint32_t dev_id, + a_uint32_t port_id, fal_port_speed_t phy_speed); + +void +__adpt_hppe_gcc_uniphy_sys_set(a_uint32_t dev_id, a_uint32_t uniphy_index, + a_bool_t enable) +{ + enum unphy_rst_type rst_type; + + if (uniphy_index == SSDK_UNIPHY_INSTANCE0) { + rst_type = UNIPHY0_SOFT_RESET_E; + } else if (uniphy_index == SSDK_UNIPHY_INSTANCE1) { + rst_type = UNIPHY1_SOFT_RESET_E; + } else { + rst_type = UNIPHY2_SOFT_RESET_E; + } + + if (enable == A_TRUE) { + ssdk_uniphy_reset(dev_id, rst_type, SSDK_RESET_DEASSERT); + } else { + ssdk_uniphy_reset(dev_id, rst_type, SSDK_RESET_ASSERT); + } + + return; +} + +static sw_error_t +__adpt_hppe_uniphy_10g_r_linkup(a_uint32_t dev_id, a_uint32_t uniphy_index) +{ + a_uint32_t reg_value = 0; + a_uint32_t retries = 100, linkup = 0; + + union sr_xs_pcs_kr_sts1_u sr_xs_pcs_kr_sts1; + + memset(&sr_xs_pcs_kr_sts1, 0, sizeof(sr_xs_pcs_kr_sts1)); + ADPT_DEV_ID_CHECK(dev_id); + + /* wait 10G_R link up to uniphy */ + while (linkup != UNIPHY_10GR_LINKUP) { + mdelay(1); + if (retries-- == 0) + return SW_TIMEOUT; + reg_value = 0; + hppe_sr_xs_pcs_kr_sts1_get(dev_id, uniphy_index, &sr_xs_pcs_kr_sts1); + reg_value = sr_xs_pcs_kr_sts1.bf.plu; + linkup = (reg_value & UNIPHY_10GR_LINKUP); + } + + return SW_OK; +} + +sw_error_t +__adpt_hppe_uniphy_calibrate(a_uint32_t dev_id, a_uint32_t uniphy_index) +{ + a_uint32_t reg_value = 0; + a_uint32_t retries = 100, calibration_done = 0; + + union uniphy_offset_calib_4_u uniphy_offset_calib_4; + + memset(&uniphy_offset_calib_4, 0, sizeof(uniphy_offset_calib_4)); + ADPT_DEV_ID_CHECK(dev_id); + + /* wait calibration done to uniphy */ + while (calibration_done != UNIPHY_CALIBRATION_DONE) { + mdelay(1); + if (retries-- == 0) + { + SSDK_ERROR("uniphy callibration time out!\n"); + return SW_TIMEOUT; + } + reg_value = 0; + hppe_uniphy_offset_calib_4_get(dev_id, uniphy_index, &uniphy_offset_calib_4); + reg_value = uniphy_offset_calib_4.bf.mmd1_reg_calibration_done_reg; + + calibration_done = (reg_value & UNIPHY_CALIBRATION_DONE); + } + + return SW_OK; +} + +void +__adpt_hppe_gcc_uniphy_xpcs_reset(a_uint32_t dev_id, a_uint32_t uniphy_index, a_bool_t enable) +{ + enum unphy_rst_type rst_type; + enum ssdk_rst_action rst_action; + + if (uniphy_index == SSDK_UNIPHY_INSTANCE0) + rst_type = UNIPHY0_XPCS_RESET_E; + else if (uniphy_index == SSDK_UNIPHY_INSTANCE1) + rst_type = UNIPHY1_XPCS_RESET_E; + else + rst_type = UNIPHY2_XPCS_RESET_E; + + if (enable == A_TRUE) + rst_action = SSDK_RESET_ASSERT; + else + rst_action = SSDK_RESET_DEASSERT; + + ssdk_uniphy_reset(dev_id, rst_type, rst_action); + + return; +} + +void +__adpt_hppe_gcc_uniphy_software_reset(a_uint32_t dev_id, a_uint32_t uniphy_index) +{ + + enum unphy_rst_type rst_type; + + if (uniphy_index == SSDK_UNIPHY_INSTANCE0) + rst_type = UNIPHY0_SOFT_RESET_E; + else if (uniphy_index == SSDK_UNIPHY_INSTANCE1) + rst_type = UNIPHY1_SOFT_RESET_E; + else + rst_type = UNIPHY2_SOFT_RESET_E; + + ssdk_uniphy_reset(dev_id, rst_type, SSDK_RESET_ASSERT); + + msleep(100); + + ssdk_uniphy_reset(dev_id, rst_type, SSDK_RESET_DEASSERT); + + return; +} + +static sw_error_t +__adpt_hppe_uniphy_usxgmii_mode_set(a_uint32_t dev_id, a_uint32_t uniphy_index) +{ + sw_error_t rv = SW_OK; + + union uniphy_mode_ctrl_u uniphy_mode_ctrl; + union vr_xs_pcs_dig_ctrl1_u vr_xs_pcs_dig_ctrl1; + union vr_mii_an_ctrl_u vr_mii_an_ctrl; + union sr_mii_ctrl_u sr_mii_ctrl; + + memset(&uniphy_mode_ctrl, 0, sizeof(uniphy_mode_ctrl)); + memset(&vr_xs_pcs_dig_ctrl1, 0, sizeof(vr_xs_pcs_dig_ctrl1)); + memset(&vr_mii_an_ctrl, 0, sizeof(vr_mii_an_ctrl)); + memset(&sr_mii_ctrl, 0, sizeof(sr_mii_ctrl)); + ADPT_DEV_ID_CHECK(dev_id); + + hppe_uniphy_reg_set(dev_id, UNIPHY_MISC2_REG_OFFSET, + uniphy_index, UNIPHY_MISC2_REG_VALUE); + /*reset uniphy*/ + hppe_uniphy_reg_set(dev_id, UNIPHY_PLL_RESET_REG_OFFSET, + uniphy_index, UNIPHY_PLL_RESET_REG_VALUE); + msleep(500); + hppe_uniphy_reg_set(dev_id, UNIPHY_PLL_RESET_REG_OFFSET, + uniphy_index, UNIPHY_PLL_RESET_REG_DEFAULT_VALUE); + msleep(500); + + /* disable instance clock */ + qca_gcc_uniphy_port_clock_set(dev_id, uniphy_index, + 1, A_FALSE); + + /* keep xpcs to reset status */ + __adpt_hppe_gcc_uniphy_xpcs_reset(dev_id, uniphy_index, A_TRUE); + + /* configure uniphy to usxgmii mode */ + hppe_uniphy_mode_ctrl_get(dev_id, uniphy_index, &uniphy_mode_ctrl); + uniphy_mode_ctrl.bf.newaddedfromhere_ch0_psgmii_qsgmii = + UNIPHY_CH0_QSGMII_SGMII_MODE; + uniphy_mode_ctrl.bf.newaddedfromhere_ch0_qsgmii_sgmii = + UNIPHY_CH0_SGMII_MODE; + uniphy_mode_ctrl.bf.newaddedfromhere_sg_mode = + UNIPHY_SGMII_MODE_DISABLE; + uniphy_mode_ctrl.bf.newaddedfromhere_sgplus_mode = + UNIPHY_SGMIIPLUS_MODE_DISABLE; + uniphy_mode_ctrl.bf.newaddedfromhere_xpcs_mode = + UNIPHY_XPCS_MODE_ENABLE; + hppe_uniphy_mode_ctrl_set(dev_id, uniphy_index, &uniphy_mode_ctrl); + + /* configure uniphy usxgmii gcc software reset */ + if (adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) { +#if defined(CPPE) + __adpt_cppe_gcc_uniphy_software_reset(dev_id, uniphy_index); +#endif + } else { + __adpt_hppe_gcc_uniphy_software_reset(dev_id, uniphy_index); + } + + msleep(100); + + /* wait calibration done to uniphy */ + __adpt_hppe_uniphy_calibrate(dev_id, uniphy_index); + + /* enable instance clock */ + qca_gcc_uniphy_port_clock_set(dev_id, uniphy_index, + 1, A_TRUE); + + /* release xpcs reset status */ + __adpt_hppe_gcc_uniphy_xpcs_reset(dev_id, uniphy_index, A_FALSE); + + /* wait 10g base_r link up */ + __adpt_hppe_uniphy_10g_r_linkup(dev_id, uniphy_index); + + /* enable uniphy usxgmii */ + hppe_vr_xs_pcs_dig_ctrl1_get(dev_id, uniphy_index, &vr_xs_pcs_dig_ctrl1); + vr_xs_pcs_dig_ctrl1.bf.usxg_en = 1; + hppe_vr_xs_pcs_dig_ctrl1_set(dev_id, uniphy_index, &vr_xs_pcs_dig_ctrl1); + + /* enable uniphy autoneg complete interrupt and 10M/100M 8-bits MII width */ + hppe_vr_mii_an_ctrl_get(dev_id, uniphy_index, &vr_mii_an_ctrl); + vr_mii_an_ctrl.bf.mii_an_intr_en = 1; + vr_mii_an_ctrl.bf.mii_ctrl = 1; + hppe_vr_mii_an_ctrl_set(dev_id, uniphy_index, &vr_mii_an_ctrl); + + /* enable uniphy autoneg ability and usxgmii 10g speed and full duplex */ + hppe_sr_mii_ctrl_get(dev_id, uniphy_index, &sr_mii_ctrl); + sr_mii_ctrl.bf.an_enable = 1; + sr_mii_ctrl.bf.ss5 = 0; + sr_mii_ctrl.bf.ss6 = 1; + sr_mii_ctrl.bf.ss13 = 1; + sr_mii_ctrl.bf.duplex_mode = 1; + hppe_sr_mii_ctrl_set(dev_id, uniphy_index, &sr_mii_ctrl); + + return rv; +} + +static sw_error_t +__adpt_hppe_uniphy_10g_r_mode_set(a_uint32_t dev_id, a_uint32_t uniphy_index) +{ + a_uint32_t port_id = 0; + sw_error_t rv = SW_OK; + + union uniphy_mode_ctrl_u uniphy_mode_ctrl; + union uniphy_instance_link_detect_u uniphy_instance_link_detect; + + memset(&uniphy_mode_ctrl, 0, sizeof(uniphy_mode_ctrl)); + memset(&uniphy_instance_link_detect, 0, sizeof(uniphy_instance_link_detect)); + ADPT_DEV_ID_CHECK(dev_id); + + /* keep xpcs to reset status */ + __adpt_hppe_gcc_uniphy_xpcs_reset(dev_id, uniphy_index, A_TRUE); + + /* disable instance clock */ + qca_gcc_uniphy_port_clock_set(dev_id, uniphy_index, + 1, A_FALSE); + + /* configure uniphy to 10g_r mode */ + hppe_uniphy_mode_ctrl_get(dev_id, uniphy_index, &uniphy_mode_ctrl); + + uniphy_mode_ctrl.bf.newaddedfromhere_ch0_psgmii_qsgmii = + UNIPHY_CH0_QSGMII_SGMII_MODE; + uniphy_mode_ctrl.bf.newaddedfromhere_ch0_qsgmii_sgmii = + UNIPHY_CH0_SGMII_MODE; + uniphy_mode_ctrl.bf.newaddedfromhere_sg_mode = + UNIPHY_SGMII_MODE_DISABLE; + uniphy_mode_ctrl.bf.newaddedfromhere_sgplus_mode = + UNIPHY_SGMIIPLUS_MODE_DISABLE; + uniphy_mode_ctrl.bf.newaddedfromhere_xpcs_mode = + UNIPHY_XPCS_MODE_ENABLE; + + hppe_uniphy_mode_ctrl_set(dev_id, uniphy_index, &uniphy_mode_ctrl); + + hppe_uniphy_instance_link_detect_get(dev_id, uniphy_index, &uniphy_instance_link_detect); + uniphy_instance_link_detect.bf.detect_los_from_sfp = UNIPHY_10GR_LINK_LOSS; + hppe_uniphy_instance_link_detect_set(dev_id, uniphy_index, &uniphy_instance_link_detect); + + /* configure uniphy gcc software reset */ + __adpt_hppe_gcc_uniphy_software_reset(dev_id, uniphy_index); + + /* wait uniphy calibration done */ + rv = __adpt_hppe_uniphy_calibrate(dev_id, uniphy_index); + + /* configure gcc speed clock to 10g r mode*/ + if (uniphy_index == SSDK_UNIPHY_INSTANCE1) + port_id = HPPE_MUX_PORT1; + else if (uniphy_index == SSDK_UNIPHY_INSTANCE2) + port_id = HPPE_MUX_PORT2; + adpt_hppe_gcc_port_speed_clock_set(dev_id, port_id, FAL_SPEED_10000); + + /* enable instance clock */ + qca_gcc_uniphy_port_clock_set(dev_id, uniphy_index, + 1, A_TRUE); + + /* release xpcs reset status */ + __adpt_hppe_gcc_uniphy_xpcs_reset(dev_id, uniphy_index, A_FALSE); + + return rv; +} + +static sw_error_t +__adpt_hppe_uniphy_sgmiiplus_mode_set(a_uint32_t dev_id, a_uint32_t uniphy_index) +{ + sw_error_t rv = SW_OK; + + union uniphy_mode_ctrl_u uniphy_mode_ctrl; + + memset(&uniphy_mode_ctrl, 0, sizeof(uniphy_mode_ctrl)); + ADPT_DEV_ID_CHECK(dev_id); + + SSDK_DEBUG("uniphy %d is sgmiiplus mode\n", uniphy_index); +#if defined(CPPE) + if ((adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) + && (uniphy_index == SSDK_UNIPHY_INSTANCE0)) { + SSDK_DEBUG("cypress uniphy %d is sgmiiplus mode\n", uniphy_index); + rv = __adpt_cppe_uniphy_mode_set(dev_id, uniphy_index, + PORT_WRAPPER_SGMII_PLUS); + return rv; + } +#endif + + hppe_uniphy_reg_set(dev_id, UNIPHY_MISC2_REG_OFFSET, + uniphy_index, UNIPHY_MISC2_REG_SGMII_PLUS_MODE); + /*reset uniphy*/ + hppe_uniphy_reg_set(dev_id, UNIPHY_PLL_RESET_REG_OFFSET, + uniphy_index, UNIPHY_PLL_RESET_REG_VALUE); + msleep(500); + hppe_uniphy_reg_set(dev_id, UNIPHY_PLL_RESET_REG_OFFSET, + uniphy_index, UNIPHY_PLL_RESET_REG_DEFAULT_VALUE); + msleep(500); + + /* keep xpcs to reset status */ + __adpt_hppe_gcc_uniphy_xpcs_reset(dev_id, uniphy_index, A_TRUE); + + /* disable instance clock */ + qca_gcc_uniphy_port_clock_set(dev_id, uniphy_index, + 1, A_FALSE); + + /* configure uniphy to Athr mode and sgmiiplus mode */ + hppe_uniphy_mode_ctrl_get(dev_id, uniphy_index, &uniphy_mode_ctrl); + + uniphy_mode_ctrl.bf.newaddedfromhere_ch0_autoneg_mode = + UNIPHY_ATHEROS_NEGOTIATION; + uniphy_mode_ctrl.bf.newaddedfromhere_ch0_psgmii_qsgmii = + UNIPHY_CH0_QSGMII_SGMII_MODE; + uniphy_mode_ctrl.bf.newaddedfromhere_ch0_qsgmii_sgmii = + UNIPHY_CH0_SGMII_MODE; + uniphy_mode_ctrl.bf.newaddedfromhere_sg_mode = + UNIPHY_SGMII_MODE_DISABLE; + uniphy_mode_ctrl.bf.newaddedfromhere_sgplus_mode = + UNIPHY_SGMIIPLUS_MODE_ENABLE; + uniphy_mode_ctrl.bf.newaddedfromhere_xpcs_mode = + UNIPHY_XPCS_MODE_DISABLE; + + hppe_uniphy_mode_ctrl_set(dev_id, uniphy_index, &uniphy_mode_ctrl); + + /* configure uniphy gcc software reset */ + if (adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) { +#if defined(CPPE) + __adpt_cppe_gcc_uniphy_software_reset(dev_id, uniphy_index); +#endif + } else { + __adpt_hppe_gcc_uniphy_software_reset(dev_id, uniphy_index); + } + + /* wait uniphy calibration done */ + rv = __adpt_hppe_uniphy_calibrate(dev_id, uniphy_index); + + /* enable instance clock */ + qca_gcc_uniphy_port_clock_set(dev_id, uniphy_index, + 1, A_TRUE); + return rv; +} + +static sw_error_t +__adpt_hppe_uniphy_sgmii_mode_set(a_uint32_t dev_id, a_uint32_t uniphy_index, a_uint32_t channel) +{ + a_uint32_t i, max_port, mode, ssdk_port; + sw_error_t rv = SW_OK; + + union uniphy_mode_ctrl_u uniphy_mode_ctrl; + a_bool_t force_port = 0; + + memset(&uniphy_mode_ctrl, 0, sizeof(uniphy_mode_ctrl)); + ADPT_DEV_ID_CHECK(dev_id); + + SSDK_DEBUG("uniphy %d is sgmii mode\n", uniphy_index); +#if defined(CPPE) + if ((uniphy_index == SSDK_UNIPHY_INSTANCE0) && + (channel == SSDK_UNIPHY_CHANNEL0)) { + if (adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) { + if (hsl_port_prop_check(dev_id, SSDK_PHYSICAL_PORT4, + HSL_PP_EXCL_CPU) == A_TRUE) { + SSDK_DEBUG("cypress uniphy %d is sgmii mode\n", uniphy_index); + rv = __adpt_cppe_uniphy_mode_set(dev_id, + uniphy_index, PORT_WRAPPER_SGMII_CHANNEL0); + return rv; + } + } + } +#endif + + /*set the PHY mode to SGMII*/ + hppe_uniphy_reg_set(dev_id, UNIPHY_MISC2_REG_OFFSET, + uniphy_index, UNIPHY_MISC2_REG_SGMII_MODE); + /*reset uniphy*/ + hppe_uniphy_reg_set(dev_id, UNIPHY_PLL_RESET_REG_OFFSET, + uniphy_index, UNIPHY_PLL_RESET_REG_VALUE); + msleep(500); + hppe_uniphy_reg_set(dev_id, UNIPHY_PLL_RESET_REG_OFFSET, + uniphy_index, UNIPHY_PLL_RESET_REG_DEFAULT_VALUE); + msleep(500); + + /* keep xpcs to reset status */ + __adpt_hppe_gcc_uniphy_xpcs_reset(dev_id, uniphy_index, A_TRUE); + + /* disable instance clock */ + if (uniphy_index == SSDK_UNIPHY_INSTANCE0) + max_port = SSDK_PHYSICAL_PORT5; + else + max_port = SSDK_PHYSICAL_PORT1; + + for (i = SSDK_PHYSICAL_PORT1; i <= max_port; i++) + { + qca_gcc_uniphy_port_clock_set(dev_id, uniphy_index, + i, A_FALSE); + } + +#if defined(CPPE) + if ((adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) && + (uniphy_index == SSDK_UNIPHY_INSTANCE0)) { + SSDK_DEBUG("uniphy %d sgmii channel selection\n", uniphy_index); + rv = __adpt_cppe_uniphy_channel_selection_set(dev_id, + CPPE_PCS0_CHANNEL0_SEL_PSGMII, + CPPE_PCS0_CHANNEL4_SEL_PORT5_CLOCK); + SW_RTN_ON_ERROR (rv); + } +#endif + + /* configure uniphy to Athr mode and sgmii mode */ + hppe_uniphy_mode_ctrl_get(dev_id, uniphy_index, &uniphy_mode_ctrl); + mode = ssdk_dt_global_get_mac_mode(dev_id, uniphy_index); + if(mode == PORT_WRAPPER_SGMII_FIBER) + { + uniphy_mode_ctrl.bf.newaddedfromhere_ch0_mode_ctrl_25m = 0; + } + uniphy_mode_ctrl.bf.newaddedfromhere_ch0_autoneg_mode = + UNIPHY_ATHEROS_NEGOTIATION; + uniphy_mode_ctrl.bf.newaddedfromhere_ch0_psgmii_qsgmii = + UNIPHY_CH0_QSGMII_SGMII_MODE; + uniphy_mode_ctrl.bf.newaddedfromhere_ch0_qsgmii_sgmii = + UNIPHY_CH0_SGMII_MODE; + uniphy_mode_ctrl.bf.newaddedfromhere_sgplus_mode = + UNIPHY_SGMIIPLUS_MODE_DISABLE; + uniphy_mode_ctrl.bf.newaddedfromhere_xpcs_mode = + UNIPHY_XPCS_MODE_DISABLE; + if (uniphy_index == SSDK_UNIPHY_INSTANCE0) { + uniphy_mode_ctrl.bf.newaddedfromhere_sg_mode = + UNIPHY_SGMII_MODE_DISABLE; + /* select channel as a sgmii interface */ + if (channel == SSDK_UNIPHY_CHANNEL0) + { + uniphy_mode_ctrl.bf.newaddedfromhere_ch1_ch0_sgmii = + UNIPHY_SGMII_CHANNEL1_DISABLE; + uniphy_mode_ctrl.bf.newaddedfromhere_ch4_ch1_0_sgmii = + UNIPHY_SGMII_CHANNEL4_DISABLE; + } + else if (channel == SSDK_UNIPHY_CHANNEL1) + { + uniphy_mode_ctrl.bf.newaddedfromhere_ch1_ch0_sgmii = + UNIPHY_SGMII_CHANNEL1_ENABLE; + uniphy_mode_ctrl.bf.newaddedfromhere_ch4_ch1_0_sgmii = + UNIPHY_SGMII_CHANNEL4_DISABLE; + } + else if (channel == SSDK_UNIPHY_CHANNEL4) + { + uniphy_mode_ctrl.bf.newaddedfromhere_ch1_ch0_sgmii = + UNIPHY_SGMII_CHANNEL1_DISABLE; + uniphy_mode_ctrl.bf.newaddedfromhere_ch4_ch1_0_sgmii = + UNIPHY_SGMII_CHANNEL4_ENABLE; + } + } + else + { + uniphy_mode_ctrl.bf.newaddedfromhere_sg_mode = + UNIPHY_SGMII_MODE_ENABLE; + } + hppe_uniphy_mode_ctrl_set(dev_id, uniphy_index, &uniphy_mode_ctrl); + + if (uniphy_index != SSDK_UNIPHY_INSTANCE0) { + if (uniphy_index == SSDK_UNIPHY_INSTANCE1) { + ssdk_port = SSDK_PHYSICAL_PORT5; + } else { + ssdk_port = SSDK_PHYSICAL_PORT6; + } + force_port = ssdk_port_feature_get(dev_id, + ssdk_port, PHY_F_FORCE); + if (force_port == A_TRUE) { + rv = hppe_uniphy_channel0_force_speed_mode_set(dev_id, + uniphy_index, UNIPHY_FORCE_SPEED_MODE_ENABLE); + SW_RTN_ON_ERROR (rv); + SSDK_INFO("ssdk uniphy %d connects force port\n", + uniphy_index); + } + } + /* configure uniphy gcc software reset */ + if (adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) { +#if defined(CPPE) + __adpt_cppe_gcc_uniphy_software_reset(dev_id, uniphy_index); +#endif + } else { + __adpt_hppe_gcc_uniphy_software_reset(dev_id, uniphy_index); + } + + /* wait uniphy calibration done */ + rv = __adpt_hppe_uniphy_calibrate(dev_id, uniphy_index); + + /* enable instance clock */ + if (uniphy_index == SSDK_UNIPHY_INSTANCE0) + max_port = SSDK_PHYSICAL_PORT5; + else + max_port = SSDK_PHYSICAL_PORT1; + + for (i = SSDK_PHYSICAL_PORT1; i <= max_port; i++) + { + qca_gcc_uniphy_port_clock_set(dev_id, uniphy_index, + i, A_TRUE); + } + + return rv; +} + +static sw_error_t +__adpt_hppe_uniphy_qsgmii_mode_set(a_uint32_t dev_id, a_uint32_t uniphy_index) +{ + a_uint32_t i; + sw_error_t rv = SW_OK; + + union uniphy_mode_ctrl_u uniphy_mode_ctrl; + + memset(&uniphy_mode_ctrl, 0, sizeof(uniphy_mode_ctrl)); + ADPT_DEV_ID_CHECK(dev_id); + + /* configure malibu phy to qsgmii mode*/ + rv = hsl_port_phy_mode_set(dev_id, PORT_QSGMII); + SW_RTN_ON_ERROR (rv); + + /* keep xpcs to reset status */ + __adpt_hppe_gcc_uniphy_xpcs_reset(dev_id, uniphy_index, A_TRUE); + + /* disable instance0 clock */ + for (i = SSDK_PHYSICAL_PORT1; i < SSDK_PHYSICAL_PORT6; i++) + { + qca_gcc_uniphy_port_clock_set(dev_id, uniphy_index, + i, A_FALSE); + } + + /* configure uniphy to Athr mode and qsgmii mode */ + hppe_uniphy_mode_ctrl_get(dev_id, uniphy_index, &uniphy_mode_ctrl); + uniphy_mode_ctrl.bf.newaddedfromhere_ch0_autoneg_mode = + UNIPHY_ATHEROS_NEGOTIATION; + uniphy_mode_ctrl.bf.newaddedfromhere_ch0_psgmii_qsgmii = + UNIPHY_CH0_QSGMII_SGMII_MODE; + uniphy_mode_ctrl.bf.newaddedfromhere_ch0_qsgmii_sgmii = + UNIPHY_CH0_QSGMII_MODE; + uniphy_mode_ctrl.bf.newaddedfromhere_sg_mode = + UNIPHY_SGMII_MODE_DISABLE; + uniphy_mode_ctrl.bf.newaddedfromhere_sgplus_mode = + UNIPHY_SGMII_MODE_DISABLE; + uniphy_mode_ctrl.bf.newaddedfromhere_xpcs_mode = + UNIPHY_XPCS_MODE_DISABLE; + hppe_uniphy_mode_ctrl_set(dev_id, uniphy_index, &uniphy_mode_ctrl); + + /* configure uniphy gcc software reset */ + if (adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) { +#if defined(CPPE) + __adpt_cppe_gcc_uniphy_software_reset(dev_id, uniphy_index); +#endif + } else { + __adpt_hppe_gcc_uniphy_software_reset(dev_id, uniphy_index); + } + + /* wait uniphy calibration done */ + rv = __adpt_hppe_uniphy_calibrate(dev_id, uniphy_index); + + rv = hsl_port_phy_serdes_reset(dev_id); + SW_RTN_ON_ERROR (rv); + + /* enable instance0 clock */ + for (i = SSDK_PHYSICAL_PORT1; i < SSDK_PHYSICAL_PORT6; i++) + { + qca_gcc_uniphy_port_clock_set(dev_id, uniphy_index, + i, A_TRUE); + } + + return rv; +} + +static sw_error_t +__adpt_hppe_uniphy_psgmii_mode_set(a_uint32_t dev_id, a_uint32_t uniphy_index) +{ + a_uint32_t i; + sw_error_t rv = SW_OK; +#if defined(CPPE) + a_uint32_t phy_type = 0; +#endif + + union uniphy_mode_ctrl_u uniphy_mode_ctrl; + + memset(&uniphy_mode_ctrl, 0, sizeof(uniphy_mode_ctrl)); + ADPT_DEV_ID_CHECK(dev_id); + + SSDK_DEBUG("uniphy %d is psgmii mode\n", uniphy_index); +#if defined(CPPE) + if (adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) { + phy_type = hsl_port_phyid_get(dev_id, + SSDK_PHYSICAL_PORT3); + if (phy_type == MALIBU2PORT_PHY) { + SSDK_INFO("cypress uniphy %d is qca8072 psgmii mode\n", uniphy_index); + rv = __adpt_cppe_uniphy_mode_set(dev_id, uniphy_index, + PORT_WRAPPER_PSGMII); + return rv; + } + } +#endif + + /* keep xpcs to reset status */ + __adpt_hppe_gcc_uniphy_xpcs_reset(dev_id, uniphy_index, A_TRUE); + + /* disable instance0 clock */ + for (i = SSDK_PHYSICAL_PORT1; i < SSDK_PHYSICAL_PORT6; i++) + { + qca_gcc_uniphy_port_clock_set(dev_id, uniphy_index, + i, A_FALSE); + } + +#if defined(CPPE) + if ((adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) && + (uniphy_index == SSDK_UNIPHY_INSTANCE0)) { + SSDK_INFO("uniphy %d psgmii channel selection\n", uniphy_index); + rv = __adpt_cppe_uniphy_channel_selection_set(dev_id, + CPPE_PCS0_CHANNEL0_SEL_PSGMII, + CPPE_PCS0_CHANNEL4_SEL_PORT5_CLOCK); + SW_RTN_ON_ERROR (rv); + } +#endif + + /* configure uniphy to Athr mode and psgmii mode */ + hppe_uniphy_mode_ctrl_get(dev_id, uniphy_index, &uniphy_mode_ctrl); + uniphy_mode_ctrl.bf.newaddedfromhere_ch0_autoneg_mode = + UNIPHY_ATHEROS_NEGOTIATION; + uniphy_mode_ctrl.bf.newaddedfromhere_ch0_psgmii_qsgmii = + UNIPHY_CH0_PSGMII_MODE; + uniphy_mode_ctrl.bf.newaddedfromhere_ch0_qsgmii_sgmii = + UNIPHY_CH0_SGMII_MODE; + uniphy_mode_ctrl.bf.newaddedfromhere_sg_mode = + UNIPHY_SGMII_MODE_DISABLE; + uniphy_mode_ctrl.bf.newaddedfromhere_sgplus_mode = + UNIPHY_SGMIIPLUS_MODE_DISABLE; + uniphy_mode_ctrl.bf.newaddedfromhere_xpcs_mode = + UNIPHY_XPCS_MODE_DISABLE; + hppe_uniphy_mode_ctrl_set(dev_id, uniphy_index, &uniphy_mode_ctrl); + + /* configure uniphy gcc software reset */ + if (adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) { +#if defined(CPPE) + __adpt_cppe_gcc_uniphy_software_reset(dev_id, uniphy_index); +#endif + } else { + + __adpt_hppe_gcc_uniphy_software_reset(dev_id, uniphy_index); + } + + /* wait uniphy calibration done */ + rv = __adpt_hppe_uniphy_calibrate(dev_id, uniphy_index); + + rv = hsl_port_phy_serdes_reset(dev_id); + SW_RTN_ON_ERROR (rv); + + /* enable instance0 clock */ + for (i = SSDK_PHYSICAL_PORT1; i < SSDK_PHYSICAL_PORT6; i++) + { + qca_gcc_uniphy_port_clock_set(dev_id, uniphy_index, + i, A_TRUE); + } + + return rv; +} + +sw_error_t +adpt_hppe_uniphy_mode_set(a_uint32_t dev_id, a_uint32_t index, a_uint32_t mode) +{ + sw_error_t rv = SW_OK; + a_uint32_t clock = UNIPHY_CLK_RATE_125M; + + if (mode == PORT_WRAPPER_MAX) { + ssdk_uniphy_raw_clock_reset(index); + __adpt_hppe_gcc_uniphy_sys_set(dev_id, index, A_FALSE); + return SW_OK; + } else { + __adpt_hppe_gcc_uniphy_sys_set(dev_id, index, A_TRUE); + } + + switch(mode) { + case PORT_WRAPPER_PSGMII: + case PORT_WRAPPER_PSGMII_FIBER: + rv = __adpt_hppe_uniphy_psgmii_mode_set(dev_id, index); + break; + + case PORT_WRAPPER_QSGMII: + rv = __adpt_hppe_uniphy_qsgmii_mode_set(dev_id, index); + break; + + case PORT_WRAPPER_SGMII0_RGMII4: + case PORT_WRAPPER_SGMII_CHANNEL0: + case PORT_WRAPPER_SGMII_FIBER: + rv = __adpt_hppe_uniphy_sgmii_mode_set(dev_id, index, + SSDK_UNIPHY_CHANNEL0); + break; + + case PORT_WRAPPER_SGMII1_RGMII4: + case PORT_WRAPPER_SGMII_CHANNEL1: + rv = __adpt_hppe_uniphy_sgmii_mode_set(dev_id, index, + SSDK_UNIPHY_CHANNEL1); + break; + + case PORT_WRAPPER_SGMII4_RGMII4: + case PORT_WRAPPER_SGMII_CHANNEL4: + rv = __adpt_hppe_uniphy_sgmii_mode_set(dev_id, index, + SSDK_UNIPHY_CHANNEL4); + break; + + case PORT_WRAPPER_SGMII_PLUS: + rv = __adpt_hppe_uniphy_sgmiiplus_mode_set(dev_id, index); + clock = UNIPHY_CLK_RATE_312M; + break; + + case PORT_WRAPPER_10GBASE_R: + rv = __adpt_hppe_uniphy_10g_r_mode_set(dev_id, index); + clock = UNIPHY_CLK_RATE_312M; + break; + + case PORT_WRAPPER_USXGMII: + rv = __adpt_hppe_uniphy_usxgmii_mode_set(dev_id, index); + clock = UNIPHY_CLK_RATE_312M; + break; + + default: + rv = SW_FAIL; + } + if (SW_OK == rv) { + ssdk_uniphy_raw_clock_set(index, UNIPHY_RX, clock); + ssdk_uniphy_raw_clock_set(index, UNIPHY_TX, clock); + } + return rv; +} +sw_error_t adpt_hppe_uniphy_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return SW_FAIL; + + p_adpt_api->adpt_uniphy_mode_set = adpt_hppe_uniphy_mode_set; + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_vsi.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_vsi.c new file mode 100755 index 000000000..a81f32677 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/hppe/adpt_hppe_vsi.c @@ -0,0 +1,637 @@ +/* + * 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. + */ + + +/** + * @defgroup + * @{ + */ +#include "sw.h" +#include "fal_type.h" +#include "adpt.h" +#include "hppe_vsi_reg.h" +#include "hppe_vsi.h" +#include "hppe_portvlan_reg.h" +#include "hppe_portvlan.h" +#include "hppe_ip_reg.h" +#include "hppe_ip.h" + +#define ADPT_VSI_MAX FAL_VSI_MAX +#define ADPT_VSI_STRIP_VLAN_TAG 2 + +enum{ + ADPT_VSI_ADD, + ADPT_VSI_DEL +}; + +static a_bool_t _adpt_hppe_vsi_xlt_match(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t stag_vid, a_uint32_t ctag_vid, union xlt_rule_tbl_u *xlt_rule) +{ + if(stag_vid != FAL_VLAN_INVALID) + { + if((xlt_rule->bf.skey_vid_incl) && + (xlt_rule->bf.skey_vid == stag_vid)) + { + if(ctag_vid != FAL_VLAN_INVALID) + { + if((xlt_rule->bf.ckey_vid_incl) && + (xlt_rule->bf.ckey_vid == ctag_vid)) + { + return A_TRUE; + } + } + else + { + if(!(xlt_rule->bf.ckey_vid_incl)) + { + return A_TRUE; + } + } + } + } + else + { + if(!(xlt_rule->bf.skey_vid_incl)) + { + if(ctag_vid != FAL_VLAN_INVALID) + { + if((xlt_rule->bf.ckey_vid_incl) && + (xlt_rule->bf.ckey_vid == ctag_vid)) + { + return A_TRUE; + } + } + else + { + if(!(xlt_rule->bf.ckey_vid_incl)) + { + return A_TRUE; + } + } + } + } + return A_FALSE; +} + +static sw_error_t _adpt_hppe_vsi_xlt_update(a_uint32_t dev_id, + a_uint32_t vsi_id, a_uint32_t port_id, + a_uint32_t stag_vid, a_uint32_t ctag_vid, + a_uint32_t op) +{ + a_int32_t index = 0; + a_uint32_t new_entry = 0; + sw_error_t rv; + union xlt_rule_tbl_u xlt_rule; + union xlt_action_tbl_u xlt_action; + + /*printk("%s,%d: port_id 0x%x svlan %d cvlan %d vsi %d op %d\n", + __FUNCTION__, __LINE__, port_id, stag_vid, ctag_vid, vsi_id, op);*/ + + for(index = XLT_RULE_TBL_NUM - 1; index >= 0; index--) + { + rv = hppe_xlt_rule_tbl_get(dev_id, index, &xlt_rule); + if( rv != SW_OK ) + return rv; + rv = hppe_xlt_action_tbl_get(dev_id, index, &xlt_action); + if( rv != SW_OK ) + return rv; + if(xlt_rule.bf.valid == A_FALSE && index >= new_entry) + { + new_entry = index; + } + if(xlt_rule.bf.valid == A_TRUE) + { + if(_adpt_hppe_vsi_xlt_match(dev_id, port_id, + stag_vid, ctag_vid, &xlt_rule)) + { + if((xlt_action.bf.vsi_cmd == A_TRUE) && + (xlt_action.bf.vsi == vsi_id)) + break; + } + } + } + + if(index >= 0) /*found*/ + { + if(op == ADPT_VSI_DEL)/*Delete*/ + { + /*printk("%s,%d: port_id 0x%x svlan %d cvlan %d vsi %d op %d\n", + __FUNCTION__, __LINE__, port_id, stag_vid, ctag_vid, vsi_id, op);*/ + if(!(xlt_rule.bf.port_bitmap & (1<= XLT_RULE_TBL_NUM) + { + printk("%s,%d: port_id 0x%x svlan %d cvlan %d vsi %d xlt table is full\n", + __FUNCTION__, __LINE__, port_id, stag_vid, ctag_vid, vsi_id); + return SW_NO_RESOURCE; + } + else/*new entry exist*/ + { + aos_mem_zero(&xlt_rule, sizeof(union xlt_rule_tbl_u)); + /*printk("%s,%d: port_id 0x%x svlan %d cvlan %d vsi %d xlt table add index %d\n", + __FUNCTION__, __LINE__, port_id, stag_vid, ctag_vid, vsi_id, new_entry);*/ + xlt_rule.bf.valid = A_TRUE; + if(ctag_vid != FAL_VLAN_INVALID) + { + xlt_rule.bf.ckey_vid_incl = A_TRUE; + xlt_rule.bf.ckey_vid = ctag_vid; + if(ctag_vid == 0) + xlt_rule.bf.ckey_fmt_1 = 0x1; + else + xlt_rule.bf.ckey_fmt_1 = 0x2; + } + else + xlt_rule.bf.ckey_fmt_0 = 0x1; + if(stag_vid != FAL_VLAN_INVALID) + { + xlt_rule.bf.skey_vid_incl = A_TRUE; + xlt_rule.bf.skey_vid = stag_vid; + if(stag_vid == 0) + xlt_rule.bf.skey_fmt = 0x2; + else + xlt_rule.bf.skey_fmt = 0x4; + } + else + xlt_rule.bf.skey_fmt = 0x1; + xlt_rule.bf.port_bitmap = (1< FAL_VLAN_MAX)|| + (ctag_vid != FAL_VLAN_INVALID && ctag_vid > FAL_VLAN_MAX)) + return SW_OUT_OF_RANGE; + + adpt_hppe_port_vlan_vsi_get(dev_id, port_id, stag_vid, ctag_vid, &org_vsi); + + if(org_vsi == vsi_id) + return SW_OK; + + if(FAL_VSI_INVALID == vsi_id || org_vsi != FAL_VSI_INVALID) + { + rv = _adpt_hppe_vsi_xlt_update(dev_id, org_vsi, port_id, + stag_vid, ctag_vid, ADPT_VSI_DEL); + if(rv != SW_OK) + return rv; + } + if(vsi_id != FAL_VSI_INVALID) + { + rv = _adpt_hppe_vsi_xlt_update(dev_id, vsi_id, port_id, + stag_vid, ctag_vid, ADPT_VSI_ADD); + } + + return rv; +} + + +#ifndef IN_VSI_MINI +sw_error_t +adpt_hppe_port_vsi_get(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t *vsi_id) +{ + union l3_vp_port_tbl_u l3_vp_port_tbl; + sw_error_t rv; + + ADPT_DEV_ID_CHECK(dev_id); + //printk("%s, %d: port %d, vsi %d\n", __FUNCTION__, __LINE__, port_id, vsi_id); + if(!(FAL_IS_PPORT(port_id)) && !(FAL_IS_VPORT(port_id))) + return SW_BAD_VALUE; + + rv = hppe_l3_vp_port_tbl_get(dev_id, FAL_PORT_ID_VALUE(port_id), &l3_vp_port_tbl); + if (SW_OK != rv) + return rv; + if(l3_vp_port_tbl.bf.vsi_valid) + *vsi_id = l3_vp_port_tbl.bf.vsi; + else + *vsi_id = FAL_VSI_INVALID; + + return rv; +} +#endif + +sw_error_t +adpt_hppe_port_vsi_set(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t vsi_id) +{ + union l3_vp_port_tbl_u l3_vp_port_tbl; + sw_error_t rv; + + ADPT_DEV_ID_CHECK(dev_id); + //printk("%s, %d: port %d, vsi %d\n", __FUNCTION__, __LINE__, port_id, vsi_id); + if(!(FAL_IS_PPORT(port_id)) && !(FAL_IS_VPORT(port_id))) + return SW_BAD_VALUE; + + rv = hppe_l3_vp_port_tbl_get(dev_id, FAL_PORT_ID_VALUE(port_id), &l3_vp_port_tbl); + if (SW_OK != rv) + return rv; + if(FAL_VSI_INVALID == vsi_id) + { + l3_vp_port_tbl.bf.vsi_valid = A_FALSE; + l3_vp_port_tbl.bf.vsi = 0; + } + else + { + l3_vp_port_tbl.bf.vsi_valid = A_TRUE; + l3_vp_port_tbl.bf.vsi = vsi_id; + } + rv = hppe_l3_vp_port_tbl_set(dev_id, FAL_PORT_ID_VALUE(port_id), &l3_vp_port_tbl); + if( rv != SW_OK ) + return rv; + //printk("%s, %d: port %d, vsi %d\n", __FUNCTION__, __LINE__, port_id, vsi_id); + + return rv; +} + +sw_error_t +adpt_hppe_vsi_stamove_set(a_uint32_t dev_id, a_uint32_t vsi_id, fal_vsi_stamove_t *stamove) +{ + sw_error_t rv; + union vsi_tbl_u vsi_tbl; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(stamove); + + rv = hppe_vsi_tbl_get( dev_id, vsi_id, &vsi_tbl); + if( rv != SW_OK ) + return rv; + + vsi_tbl.bf.station_move_lrn_en = stamove->stamove_en; + vsi_tbl.bf.station_move_fwd_cmd = stamove->action; + + rv = hppe_vsi_tbl_set( dev_id, vsi_id, &vsi_tbl); + if( rv != SW_OK ) + return rv; + + return SW_OK; +} +#ifndef IN_VSI_MINI +sw_error_t +adpt_hppe_vsi_stamove_get(a_uint32_t dev_id, a_uint32_t vsi_id, fal_vsi_stamove_t *stamove) +{ + sw_error_t rv; + union vsi_tbl_u vsi_tbl; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(stamove); + + rv = hppe_vsi_tbl_get( dev_id, vsi_id, &vsi_tbl); + if( rv != SW_OK ) + return rv; + + stamove->stamove_en = vsi_tbl.bf.station_move_lrn_en; + stamove->action = vsi_tbl.bf.station_move_fwd_cmd; + + return SW_OK; +} + +sw_error_t +adpt_hppe_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; + union vsi_tbl_u vsi_tbl; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(newaddr_lrn); + + rv = hppe_vsi_tbl_get( dev_id, vsi_id, &vsi_tbl); + if( rv != SW_OK ) + return rv; + + newaddr_lrn->lrn_en = vsi_tbl.bf.new_addr_lrn_en; + newaddr_lrn->action = vsi_tbl.bf.new_addr_fwd_cmd; + + return SW_OK; +} +#endif + +sw_error_t +adpt_hppe_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; + union vsi_tbl_u vsi_tbl; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(newaddr_lrn); + + rv = hppe_vsi_tbl_get( dev_id, vsi_id, &vsi_tbl); + if( rv != SW_OK ) + return rv; + + vsi_tbl.bf.new_addr_lrn_en = newaddr_lrn->lrn_en; + vsi_tbl.bf.new_addr_fwd_cmd = newaddr_lrn->action; + + rv = hppe_vsi_tbl_set( dev_id, vsi_id, &vsi_tbl); + if( rv != SW_OK ) + return rv; + + return SW_OK; +} + +sw_error_t +adpt_hppe_vsi_member_set(a_uint32_t dev_id, a_uint32_t vsi_id, fal_vsi_member_t *vsi_member) +{ + sw_error_t rv; + union vsi_tbl_u vsi_tbl; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(vsi_member); + + rv = hppe_vsi_tbl_get( dev_id, vsi_id, &vsi_tbl); + if( rv != SW_OK ) + return rv; + + vsi_tbl.bf.bc_bitmap = vsi_member->bc_ports & 0xff; + vsi_tbl.bf.member_port_bitmap = vsi_member->member_ports & 0xff; + vsi_tbl.bf.umc_bitmap = vsi_member->umc_ports & 0xff; + vsi_tbl.bf.uuc_bitmap = vsi_member->uuc_ports & 0xff; + + rv = hppe_vsi_tbl_set(dev_id, vsi_id, &vsi_tbl); + if( rv != SW_OK ) + return rv; + + return SW_OK; + +} + +sw_error_t +adpt_hppe_vsi_member_get(a_uint32_t dev_id, a_uint32_t vsi_id, fal_vsi_member_t *vsi_member) +{ + sw_error_t rv; + union vsi_tbl_u vsi_tbl; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(vsi_member); + + rv = hppe_vsi_tbl_get( dev_id, vsi_id, &vsi_tbl); + if( rv != SW_OK ) + return rv; + + vsi_member->bc_ports = vsi_tbl.bf.bc_bitmap; + vsi_member->member_ports = vsi_tbl.bf.member_port_bitmap; + vsi_member->umc_ports = vsi_tbl.bf.umc_bitmap; + vsi_member->uuc_ports = vsi_tbl.bf.uuc_bitmap; + + rv = hppe_vsi_tbl_set(dev_id, vsi_id, &vsi_tbl); + if( rv != SW_OK ) + return rv; + + return SW_OK; + +} + +#ifndef IN_VSI_MINI +sw_error_t +adpt_hppe_vsi_counter_get(a_uint32_t dev_id, a_uint32_t vsi_id, fal_vsi_counter_t *counter) +{ + sw_error_t rv; + union vlan_cnt_tbl_u in_cnt; + union eg_vsi_counter_tbl_u eg_cnt; + union pre_l2_cnt_tbl_u pre_l2_cnt; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(counter); + + rv = hppe_vlan_cnt_tbl_get(dev_id, vsi_id, &in_cnt); + if( rv != SW_OK ) + return rv; + + counter->rx_packet_counter = in_cnt.bf.rx_pkt_cnt; + counter->rx_byte_counter = in_cnt.bf.rx_byte_cnt_1; + counter->rx_byte_counter = (counter->rx_byte_counter<<32)|in_cnt.bf.rx_byte_cnt_0; + + rv = hppe_eg_vsi_counter_tbl_get(dev_id, vsi_id, &eg_cnt); + if( rv != SW_OK ) + return rv; + + counter->tx_packet_counter = eg_cnt.bf.tx_packets; + counter->tx_byte_counter = eg_cnt.bf.tx_bytes_1; + counter->tx_byte_counter = (counter->tx_byte_counter<<32)|eg_cnt.bf.tx_bytes_0; + + rv = hppe_pre_l2_cnt_tbl_get(dev_id, vsi_id, &pre_l2_cnt); + if( rv != SW_OK ) + return rv; + + counter->fwd_packet_counter = pre_l2_cnt.bf.rx_pkt_cnt; + counter->fwd_byte_counter = pre_l2_cnt.bf.rx_byte_cnt_1; + counter->fwd_byte_counter = (counter->fwd_byte_counter<<32)|pre_l2_cnt.bf.rx_byte_cnt_0; + counter->drop_packet_counter = pre_l2_cnt.bf.rx_drop_pkt_cnt_1<<24|pre_l2_cnt.bf.rx_drop_pkt_cnt_0; + counter->drop_byte_counter = pre_l2_cnt.bf.rx_drop_byte_cnt_1; + counter->drop_byte_counter = (counter->drop_byte_counter<<24)|pre_l2_cnt.bf.rx_drop_byte_cnt_0; + + return SW_OK; +} + +sw_error_t +adpt_hppe_vsi_counter_cleanup(a_uint32_t dev_id, a_uint32_t vsi_id) +{ + sw_error_t rv; + union vlan_cnt_tbl_u in_cnt; + union eg_vsi_counter_tbl_u eg_cnt; + union pre_l2_cnt_tbl_u pre_l2_cnt; + + ADPT_DEV_ID_CHECK(dev_id); + + memset(&in_cnt, 0, sizeof(in_cnt)); + rv = hppe_vlan_cnt_tbl_set(dev_id, vsi_id, &in_cnt); + if( rv != SW_OK ) + return rv; + + memset(&eg_cnt, 0, sizeof(eg_cnt)); + rv = hppe_eg_vsi_counter_tbl_set(dev_id, vsi_id, &eg_cnt); + if( rv != SW_OK ) + return rv; + + memset(&pre_l2_cnt, 0, sizeof(pre_l2_cnt)); + rv = hppe_pre_l2_cnt_tbl_set(dev_id, vsi_id, &pre_l2_cnt); + if( rv != SW_OK ) + return rv; + + return SW_OK; +} +#endif + + +void adpt_hppe_vsi_func_bitmap_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return; + + + p_adpt_api->adpt_vsi_func_bitmap = ((1<adpt_port_vlan_vsi_set = NULL; + p_adpt_api->adpt_port_vlan_vsi_get = NULL; + p_adpt_api->adpt_port_vsi_set = NULL; + p_adpt_api->adpt_port_vsi_get = NULL; + p_adpt_api->adpt_vsi_stamove_set = NULL; + p_adpt_api->adpt_vsi_stamove_get = NULL; + p_adpt_api->adpt_vsi_newaddr_lrn_get = NULL; + p_adpt_api->adpt_vsi_newaddr_lrn_set = NULL; + p_adpt_api->adpt_vsi_member_set = NULL; + p_adpt_api->adpt_vsi_member_get = NULL; + p_adpt_api->adpt_vsi_counter_get = NULL; + p_adpt_api->adpt_vsi_counter_cleanup = NULL; + + return; +} + + +sw_error_t adpt_hppe_vsi_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return SW_FAIL; + + adpt_hppe_vsi_func_unregister(dev_id, p_adpt_api); + +#ifndef IN_VSI_MINI + if(p_adpt_api->adpt_vsi_func_bitmap & (1<adpt_port_vsi_get = adpt_hppe_port_vsi_get; + if(p_adpt_api->adpt_vsi_func_bitmap & (1<adpt_vsi_stamove_get = adpt_hppe_vsi_stamove_get; + if(p_adpt_api->adpt_vsi_func_bitmap & (1<adpt_vsi_newaddr_lrn_get = adpt_hppe_vsi_newaddr_lrn_get; + if(p_adpt_api->adpt_vsi_func_bitmap & (1<adpt_vsi_counter_get = adpt_hppe_vsi_counter_get; + if(p_adpt_api->adpt_vsi_func_bitmap & (1<adpt_vsi_counter_cleanup = adpt_hppe_vsi_counter_cleanup; +#endif + if(p_adpt_api->adpt_vsi_func_bitmap & (1<adpt_port_vlan_vsi_set = adpt_hppe_port_vlan_vsi_set; + if(p_adpt_api->adpt_vsi_func_bitmap & (1<adpt_port_vlan_vsi_get = adpt_hppe_port_vlan_vsi_get; + if(p_adpt_api->adpt_vsi_func_bitmap & (1<adpt_port_vsi_set = adpt_hppe_port_vsi_set; + if(p_adpt_api->adpt_vsi_func_bitmap & (1<adpt_vsi_stamove_set = adpt_hppe_vsi_stamove_set; + if(p_adpt_api->adpt_vsi_func_bitmap & (1<adpt_vsi_newaddr_lrn_set = adpt_hppe_vsi_newaddr_lrn_set; + if(p_adpt_api->adpt_vsi_func_bitmap & (1<adpt_vsi_member_set = adpt_hppe_vsi_member_set; + if(p_adpt_api->adpt_vsi_func_bitmap & (1<adpt_vsi_member_get = adpt_hppe_vsi_member_get; + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/mp/Makefile b/feeds/ipq807x/qca-ssdk/src/src/adpt/mp/Makefile new file mode 100644 index 000000000..df13503d5 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/mp/Makefile @@ -0,0 +1,32 @@ +LOC_DIR=src/adpt/mp +LIB=ADPT + +include $(PRJ_PATH)/make/config.mk + +SRC_LIST=adpt_mp_interrupt.c + +ifeq (TRUE, $(IN_MIB)) + SRC_LIST += adpt_mp_mib.c +endif + +ifeq (TRUE, $(IN_PORTCONTROL)) + SRC_LIST += adpt_mp_portctrl.c +endif + +ifeq (TRUE, $(IN_UNIPHY)) + SRC_LIST += adpt_mp_uniphy.c +endif + +ifeq (TRUE, $(IN_LED)) + SRC_LIST += adpt_mp_led.c +endif + +ifeq (, $(filter MP, $(SUPPORT_CHIP))) + SRC_LIST= +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/src/src/adpt/mp/adpt_mp_interrupt.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/mp/adpt_mp_interrupt.c new file mode 100755 index 000000000..3e8ca50c2 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/mp/adpt_mp_interrupt.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 "sw.h" +#include "adpt.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_phy.h" +#include "hsl_port_prop.h" +#include "adpt_mp.h" + +static sw_error_t +adpt_mp_intr_port_link_mask_set(a_uint32_t dev_id, a_uint32_t port_id, + a_uint32_t intr_mask_flag) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + SW_RTN_ON_NULL (phy_drv->phy_intr_mask_set); + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_intr_mask_set(dev_id, phy_id, intr_mask_flag); + + return rv; +} + +static sw_error_t +adpt_mp_intr_port_link_mask_get(a_uint32_t dev_id, a_uint32_t port_id, + a_uint32_t * intr_mask_flag) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + SW_RTN_ON_NULL (phy_drv->phy_intr_mask_get); + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_intr_mask_get(dev_id, phy_id, intr_mask_flag); + + return rv; +} + +static sw_error_t +adpt_mp_intr_port_link_status_get(a_uint32_t dev_id, a_uint32_t port_id, + a_uint32_t * intr_status) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + SW_RTN_ON_NULL (phy_drv->phy_intr_status_get); + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_intr_status_get(dev_id, phy_id, intr_status); + + return rv; +} + +sw_error_t adpt_mp_intr_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + SW_RTN_ON_NULL (p_adpt_api); + + p_adpt_api->adpt_intr_port_link_mask_set = adpt_mp_intr_port_link_mask_set; + p_adpt_api->adpt_intr_port_link_mask_get = adpt_mp_intr_port_link_mask_get; + p_adpt_api->adpt_intr_port_link_status_get = adpt_mp_intr_port_link_status_get; + + return SW_OK; +} +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/mp/adpt_mp_led.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/mp/adpt_mp_led.c new file mode 100644 index 000000000..335d2ce09 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/mp/adpt_mp_led.c @@ -0,0 +1,138 @@ +/* + * 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 "sw.h" +#include "adpt.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_phy.h" +#include "hsl_port_prop.h" +#include "adpt_mp.h" + +static sw_error_t +adpt_mp_led_ctrl_pattern_set(a_uint32_t dev_id, led_pattern_group_t group, + led_pattern_id_t led_pattern_id, led_ctrl_pattern_t * pattern) +{ + sw_error_t rv; + a_uint32_t phy_addr, port_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if(group != LED_LAN_PORT_GROUP && group != LED_WAN_PORT_GROUP) + { + SSDK_ERROR("group %x is not supported\n", group); + return SW_NOT_SUPPORTED; + } + port_id = led_pattern_id; + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + SW_RTN_ON_NULL (phy_drv->phy_led_ctrl_pattern_set); + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_addr); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_led_ctrl_pattern_set(dev_id, phy_addr, pattern); + + return rv; +} + +static sw_error_t +adpt_mp_led_ctrl_pattern_get(a_uint32_t dev_id, led_pattern_group_t group, + led_pattern_id_t led_pattern_id, led_ctrl_pattern_t * pattern) +{ + sw_error_t rv; + a_uint32_t phy_addr, port_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if(group != LED_LAN_PORT_GROUP && group != LED_WAN_PORT_GROUP) + { + SSDK_ERROR("group %x is not supported\n", group); + return SW_NOT_SUPPORTED; + } + + port_id = led_pattern_id; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + SW_RTN_ON_NULL (phy_drv->phy_led_ctrl_pattern_get); + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_addr); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_led_ctrl_pattern_get(dev_id, phy_addr, pattern); + + return rv; +} + +static sw_error_t +adpt_mp_led_ctrl_source_set(a_uint32_t dev_id, a_uint32_t source_id, + led_ctrl_pattern_t *pattern) +{ + sw_error_t rv; + a_uint32_t phy_addr, port_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + /*one port can support max three led source*/ + port_id = source_id/PORT_LED_SOURCE_MAX+1; + source_id = source_id%PORT_LED_SOURCE_MAX; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + SW_RTN_ON_NULL (phy_drv->phy_led_ctrl_source_set); + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_addr); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_led_ctrl_source_set(dev_id, phy_addr, source_id, + pattern); + + return rv; +} + +sw_error_t adpt_mp_led_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + SW_RTN_ON_NULL (p_adpt_api); + + p_adpt_api->adpt_led_ctrl_pattern_set = adpt_mp_led_ctrl_pattern_set; + p_adpt_api->adpt_led_ctrl_pattern_get = adpt_mp_led_ctrl_pattern_get; + p_adpt_api->adpt_led_ctrl_source_set = adpt_mp_led_ctrl_source_set; + + return SW_OK; +} +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/mp/adpt_mp_mib.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/mp/adpt_mp_mib.c new file mode 100755 index 000000000..8aa84d01e --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/mp/adpt_mp_mib.c @@ -0,0 +1,360 @@ +/* + * 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 "sw.h" +#include "mp_mib_reg.h" +#include "mp_mib.h" +#include "adpt.h" +#include "adpt_mp.h" + +sw_error_t +adpt_mp_mib_cpukeep_get(a_uint32_t dev_id, a_bool_t *enable) +{ + sw_error_t rv = SW_OK; + union mmc_control_u mmc_control; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + + rv = mp_mmc_control_get(dev_id, MP_GMAC0, &mmc_control); + SW_RTN_ON_ERROR(rv); + if(mmc_control.bf.rstonrd) + { + *enable = A_FALSE; + } + else + { + *enable = A_TRUE; + } + + return rv; +} + +sw_error_t +adpt_mp_mib_cpukeep_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv = SW_OK; + a_uint32_t gmac_id = 0, status = 0; + union mmc_control_u mmc_control; + + ADPT_DEV_ID_CHECK(dev_id); + + if (enable == A_TRUE) + { + status = A_FALSE; + } + else + { + status = A_TRUE; + } + for(gmac_id = MP_GMAC0; gmac_id <= MP_GMAC1; gmac_id++) + { + rv = mp_mmc_control_get(dev_id, gmac_id, &mmc_control); + SW_RTN_ON_ERROR(rv); + mmc_control.bf.rstonrd = status; + rv = mp_mmc_control_set(dev_id, gmac_id, &mmc_control); + SW_RTN_ON_ERROR(rv); + } + + return rv; +} + +sw_error_t +adpt_mp_mib_status_get(a_uint32_t dev_id, a_bool_t *enable) +{ + sw_error_t rv = SW_OK; + union mmc_control_u mmc_control; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(enable); + + rv = mp_mmc_control_get(dev_id, MP_GMAC0, &mmc_control); + SW_RTN_ON_ERROR(rv); + if(mmc_control.bf.cntfreez) + { + *enable = A_FALSE; + } + else + { + *enable = A_TRUE; + } + + return rv; +} + +sw_error_t +adpt_mp_mib_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv = SW_OK; + a_uint32_t gmac_id = 0, status = 0; + union mmc_control_u mmc_control; + + ADPT_DEV_ID_CHECK(dev_id); + + if (enable == A_TRUE) + { + status = A_FALSE; + } + else + { + status = A_TRUE; + } + for(gmac_id = MP_GMAC0; gmac_id <= MP_GMAC1; gmac_id++) + { + rv = mp_mmc_control_get(dev_id, gmac_id, &mmc_control); + SW_RTN_ON_ERROR(rv); + mmc_control.bf.cntfreez = status; + rv = mp_mmc_control_set(dev_id, gmac_id, &mmc_control); + SW_RTN_ON_ERROR(rv); + } + + return rv; +} + +sw_error_t +adpt_mp_mib_port_flush_counters(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv = SW_OK; + a_uint32_t gmac_id = 0; + union mmc_control_u mmc_control; + + ADPT_DEV_ID_CHECK(dev_id); + MP_PORT_ID_CHECK(port_id); + + gmac_id = MP_PORT_TO_GMAC_ID(port_id); + rv = mp_mmc_control_get(dev_id, gmac_id, &mmc_control); + SW_RTN_ON_ERROR(rv); + mmc_control.bf.cntrst = A_TRUE; + rv = mp_mmc_control_set(dev_id, gmac_id, &mmc_control); + + return rv; +} + +static sw_error_t +adpt_mp_get_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info) +{ + a_uint32_t gmac_id = 0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(mib_info); + MP_PORT_ID_CHECK(port_id); + memset(mib_info, 0, sizeof(fal_mib_info_t)); + + gmac_id = MP_PORT_TO_GMAC_ID(port_id); + mp_tx_broadcast_frames_good_get(dev_id, gmac_id, + (union tx_broadcast_frames_good_u *)&mib_info->TxBroad); + mp_tx_multicast_frames_good_get(dev_id, gmac_id, + (union tx_multicast_frames_good_u *)&mib_info->TxMulti); + mp_tx_64octets_frames_good_bad_get(dev_id, gmac_id, + (union tx_64octets_frames_good_bad_u *)&mib_info->Tx64Byte); + mp_tx_65to127octets_frames_good_bad_get(dev_id, gmac_id, + (union tx_65to127octets_frames_good_bad_u *)&mib_info->Tx128Byte); + mp_tx_128to255octets_frames_good_bad_get(dev_id, gmac_id, + (union tx_128to255octets_frames_good_bad_u *)&mib_info->Tx256Byte); + mp_tx_256to511octets_frames_good_bad_get(dev_id, gmac_id, + (union tx_256to511octets_frames_good_bad_u *)&mib_info->Tx512Byte); + mp_tx_512to1023octets_frames_good_bad_get(dev_id, gmac_id, + (union tx_512to1023octets_frames_good_bad_u *)&mib_info->Tx1024Byte); + mp_tx_1024tomaxoctets_frames_good_bad_get(dev_id, gmac_id, + (union tx_1024tomaxoctets_frames_good_bad_u *)&mib_info->TxMaxByte); + mp_tx_unicast_frames_good_bad_get(dev_id, gmac_id, + (union tx_unicast_frames_good_bad_u *)&mib_info->TxUniCast); + mp_tx_underflow_error_frames_get(dev_id, gmac_id, + (union tx_underflow_error_frames_u *)&mib_info->TxUnderRun); + mp_tx_single_col_good_frames_get(dev_id, gmac_id, + (union tx_single_collision_good_frames_u *)&mib_info->TxSingalCol); + mp_t_multi_col_good_frames_get(dev_id, gmac_id, + (union tx_multiple_collision_good_frames_u *)&mib_info->TxMultiCol); + mp_tx_defer_frames_get(dev_id, gmac_id, + (union tx_deferred_frames_u *)&mib_info->TxDefer); + mp_tx_late_col_frames_get(dev_id, gmac_id, + (union tx_late_collision_frames_u *)&mib_info->TxLateCol); + mp_tx_excessive_col_frames_get(dev_id, gmac_id, + (union tx_excessive_collision_frames_u *)&mib_info->TxExcDefer); + mp_tx_octet_count_good_get(dev_id, gmac_id, + (union tx_octet_count_good_u *) &mib_info->TxByte_lo); + mp_tx_pause_frames_get(dev_id, gmac_id, + (union tx_pause_frames_u *)&mib_info->TxPause); + mp_tx_osize_frames_good_get(dev_id, gmac_id, + (union tx_osize_frames_good_u *)&mib_info->TxOverSize); + + mp_rx_octet_count_good_get(dev_id, gmac_id, + (union rx_octet_count_good_u *)&mib_info->RxGoodByte_lo); + mp_rx_broadcast_frames_good_get(dev_id, gmac_id, + (union rx_broadcast_frames_good_u *)&mib_info->RxBroad); + mp_rx_multicast_frames_good_get(dev_id, gmac_id, + (union rx_multicast_frames_good_u *)&mib_info->RxMulti); + mp_rx_crc_error_frames_get(dev_id, gmac_id, + (union rx_crc_error_frames_u *)&mib_info->RxFcsErr); + mp_rx_alignment_error_frames_get(dev_id, gmac_id, + (union rx_crc_error_frames_u *)&mib_info->RxAllignErr); + mp_rx_runt_error_frames_get(dev_id, gmac_id, + (union rx_runt_error_frames_u *)&mib_info->RxFragment); + mp_rx_jabber_error_frames_get(dev_id, gmac_id, + (union rx_jabber_error_frames_u *)&mib_info->RxJumboFcsErr); + mp_rx_undersize_frames_good_get(dev_id, gmac_id, + (union rx_undersize_frames_good_u *)&mib_info->RxRunt); + mp_rx_oversize_frames_good_get(dev_id, gmac_id, + (union rx_oversize_frames_good_u *)&mib_info->RxTooLong); + mp_rx_64octets_frames_good_bad_get(dev_id, gmac_id, + (union rx_64octets_frames_good_bad_u *)&mib_info->Rx64Byte); + mp_rx_65to127octets_frames_good_bad_get(dev_id,gmac_id, + (union rx_65to127octets_frames_good_bad_u *)&mib_info->Rx128Byte); + mp_rx_128to255octets_frames_good_bad_get(dev_id, gmac_id, + (union rx_128to255octets_frames_good_bad_u *)&mib_info->Rx256Byte); + mp_rx_256to511octets_frames_good_bad_get(dev_id, gmac_id, + (union rx_256to511octets_frames_good_bad_u *)&mib_info->Rx512Byte); + mp_rx_512to1023octets_frames_good_bad_get(dev_id, gmac_id, + (union rx_512to1023octets_frames_good_bad_u *)&mib_info->Rx1024Byte); + mp_rx_1024tomaxoctets_frames_good_bad_get(dev_id, gmac_id, + (union rx_1024tomaxoctets_frames_good_bad_u *)&mib_info->RxMaxByte); + mp_rx_unicast_frames_good_get(dev_id, gmac_id, + (union rx_unicast_frames_good_u *)&mib_info->RxUniCast); + mp_rx_pause_frames_get(dev_id, gmac_id, + (union rx_pause_frames_u *)&mib_info->RxPause); + mp_rx_fifo_over_flow_frames_get(dev_id, gmac_id, + (union rx_fifo_over_flow_frames_u *)&mib_info->RxOverFlow); + + return SW_OK; +} + +sw_error_t +adpt_mp_get_tx_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info) +{ + a_uint32_t gmac_id = 0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(mib_info); + MP_PORT_ID_CHECK(port_id); + memset(mib_info, 0, sizeof(fal_mib_info_t)); + + gmac_id = MP_PORT_TO_GMAC_ID(port_id); + mp_tx_broadcast_frames_good_get(dev_id, gmac_id, + (union tx_broadcast_frames_good_u *)&mib_info->TxBroad); + mp_tx_multicast_frames_good_get(dev_id, gmac_id, + (union tx_multicast_frames_good_u *)&mib_info->TxMulti); + mp_tx_64octets_frames_good_bad_get(dev_id, gmac_id, + (union tx_64octets_frames_good_bad_u *)&mib_info->Tx64Byte); + mp_tx_65to127octets_frames_good_bad_get(dev_id, gmac_id, + (union tx_65to127octets_frames_good_bad_u *)&mib_info->Tx128Byte); + mp_tx_128to255octets_frames_good_bad_get(dev_id, gmac_id, + (union tx_128to255octets_frames_good_bad_u *)&mib_info->Tx256Byte); + mp_tx_256to511octets_frames_good_bad_get(dev_id, gmac_id, + (union tx_256to511octets_frames_good_bad_u *)&mib_info->Tx512Byte); + mp_tx_512to1023octets_frames_good_bad_get(dev_id, gmac_id, + (union tx_512to1023octets_frames_good_bad_u *)&mib_info->Tx1024Byte); + mp_tx_1024tomaxoctets_frames_good_bad_get(dev_id, gmac_id, + (union tx_1024tomaxoctets_frames_good_bad_u *)&mib_info->TxMaxByte); + mp_tx_unicast_frames_good_bad_get(dev_id, gmac_id, + (union tx_unicast_frames_good_bad_u *)&mib_info->TxUniCast); + mp_tx_underflow_error_frames_get(dev_id, gmac_id, + (union tx_underflow_error_frames_u *)&mib_info->TxUnderRun); + mp_tx_single_col_good_frames_get(dev_id, gmac_id, + (union tx_single_collision_good_frames_u *)&mib_info->TxSingalCol); + mp_t_multi_col_good_frames_get(dev_id, gmac_id, + (union tx_multiple_collision_good_frames_u *)&mib_info->TxMultiCol); + mp_tx_defer_frames_get(dev_id, gmac_id, + (union tx_deferred_frames_u *)&mib_info->TxDefer); + mp_tx_late_col_frames_get(dev_id, gmac_id, + (union tx_late_collision_frames_u *)&mib_info->TxLateCol); + mp_tx_excessive_col_frames_get(dev_id, gmac_id, + (union tx_excessive_collision_frames_u *)&mib_info->TxExcDefer); + mp_tx_octet_count_good_get(dev_id, gmac_id, + (union tx_octet_count_good_u *) &mib_info->TxByte_lo); + mp_tx_pause_frames_get(dev_id, gmac_id, + (union tx_pause_frames_u *)&mib_info->TxPause); + mp_tx_osize_frames_good_get(dev_id, gmac_id, + (union tx_osize_frames_good_u *)&mib_info->TxOverSize); + + return SW_OK; +} + +sw_error_t +adpt_mp_get_rx_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info ) +{ + a_uint32_t gmac_id = 0; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(mib_info); + MP_PORT_ID_CHECK(port_id); + memset(mib_info, 0, sizeof(fal_mib_info_t)); + + gmac_id = MP_PORT_TO_GMAC_ID(port_id); + mp_rx_octet_count_good_get(dev_id, gmac_id, + (union rx_octet_count_good_u *)&mib_info->RxGoodByte_lo); + mp_rx_broadcast_frames_good_get(dev_id, gmac_id, + (union rx_broadcast_frames_good_u *)&mib_info->RxBroad); + mp_rx_multicast_frames_good_get(dev_id, gmac_id, + (union rx_multicast_frames_good_u *)&mib_info->RxMulti); + mp_rx_crc_error_frames_get(dev_id, gmac_id, + (union rx_crc_error_frames_u *)&mib_info->RxFcsErr); + mp_rx_alignment_error_frames_get(dev_id, gmac_id, + (union rx_crc_error_frames_u *)&mib_info->RxAllignErr); + mp_rx_runt_error_frames_get(dev_id, gmac_id, + (union rx_runt_error_frames_u *)&mib_info->RxFragment); + mp_rx_jabber_error_frames_get(dev_id, gmac_id, + (union rx_jabber_error_frames_u *)&mib_info->RxJumboFcsErr); + mp_rx_undersize_frames_good_get(dev_id, gmac_id, + (union rx_undersize_frames_good_u *)&mib_info->RxRunt); + mp_rx_oversize_frames_good_get(dev_id, gmac_id, + (union rx_oversize_frames_good_u *)&mib_info->RxTooLong); + mp_rx_64octets_frames_good_bad_get(dev_id, gmac_id, + (union rx_64octets_frames_good_bad_u *)&mib_info->Rx64Byte); + mp_rx_65to127octets_frames_good_bad_get(dev_id,gmac_id, + (union rx_65to127octets_frames_good_bad_u *)&mib_info->Rx128Byte); + mp_rx_128to255octets_frames_good_bad_get(dev_id, gmac_id, + (union rx_128to255octets_frames_good_bad_u *)&mib_info->Rx256Byte); + mp_rx_256to511octets_frames_good_bad_get(dev_id, gmac_id, + (union rx_256to511octets_frames_good_bad_u *)&mib_info->Rx512Byte); + mp_rx_512to1023octets_frames_good_bad_get(dev_id, gmac_id, + (union rx_512to1023octets_frames_good_bad_u *)&mib_info->Rx1024Byte); + mp_rx_1024tomaxoctets_frames_good_bad_get(dev_id, gmac_id, + (union rx_1024tomaxoctets_frames_good_bad_u *)&mib_info->RxMaxByte); + mp_rx_unicast_frames_good_get(dev_id, gmac_id, + (union rx_unicast_frames_good_u *)&mib_info->RxUniCast); + mp_rx_pause_frames_get(dev_id, gmac_id, + (union rx_pause_frames_u *)&mib_info->RxPause); + mp_rx_fifo_over_flow_frames_get(dev_id, gmac_id, + (union rx_fifo_over_flow_frames_u *)&mib_info->RxOverFlow); + + return SW_OK; +} + +sw_error_t adpt_mp_mib_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + SW_RTN_ON_NULL(p_adpt_api); + + p_adpt_api->adpt_mib_cpukeep_get = adpt_mp_mib_cpukeep_get; + p_adpt_api->adpt_mib_cpukeep_set = adpt_mp_mib_cpukeep_set; + p_adpt_api->adpt_mib_status_get = adpt_mp_mib_status_get; + p_adpt_api->adpt_mib_status_set = adpt_mp_mib_status_set; + p_adpt_api->adpt_mib_port_flush_counters = adpt_mp_mib_port_flush_counters; + p_adpt_api->adpt_get_mib_info = adpt_mp_get_mib_info; + p_adpt_api->adpt_get_tx_mib_info = adpt_mp_get_tx_mib_info; + p_adpt_api->adpt_get_rx_mib_info = adpt_mp_get_rx_mib_info; + + return SW_OK; +} +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/mp/adpt_mp_portctrl.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/mp/adpt_mp_portctrl.c new file mode 100755 index 000000000..dd464c586 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/mp/adpt_mp_portctrl.c @@ -0,0 +1,1337 @@ +/* + * 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 "sw.h" +#include "mp_portctrl_reg.h" +#include "mp_portctrl.h" +#include "adpt.h" +#include "adpt_mp.h" +#include "adpt_mp_portctrl.h" +#include "adpt_mp_uniphy.h" +#include "hsl_port_prop.h" +#include "hsl_phy.h" +#include "ssdk_dts.h" +#include "ssdk_clk.h" + +static a_uint32_t port_lpi_status[SW_MAX_NR_DEV] = {0}; + +static sw_error_t +_adpt_mp_gcc_mac_clock_set(a_uint32_t dev_id, + a_uint32_t port_id, a_bool_t enable) +{ + sw_error_t rv = 0; + + qca_gcc_mac_port_clock_set(dev_id, port_id, enable); + + return rv; +} + +static a_bool_t +_adpt_mp_port_phy_connected (a_uint32_t dev_id, fal_port_t port_id) +{ + a_bool_t force_port = 0; + + ADPT_DEV_ID_CHECK(dev_id); + + /* force port which connect s17c or other device chip*/ + force_port = ssdk_port_feature_get(dev_id, port_id, PHY_F_FORCE); + if (force_port == A_TRUE) { + SSDK_DEBUG("port_id %d is a force port!\n", port_id); + return A_FALSE; + } else { + return A_TRUE; + } +} + +static sw_error_t +_adpt_mp_port_gcc_speed_clock_set( + a_uint32_t dev_id, + a_uint32_t port_id, + fal_port_speed_t phy_speed) +{ + sw_error_t rv = 0; + + switch (phy_speed) { + case FAL_SPEED_10: + ssdk_port_speed_clock_set(dev_id, + port_id, SGMII_SPEED_10M_CLK); + break; + case FAL_SPEED_100: + ssdk_port_speed_clock_set(dev_id, + port_id, SGMII_SPEED_100M_CLK); + break; + case FAL_SPEED_1000: + ssdk_port_speed_clock_set(dev_id, + port_id, SGMII_SPEED_1000M_CLK); + break; + case FAL_SPEED_2500: + ssdk_port_speed_clock_set(dev_id, + port_id, SGMII_PLUS_SPEED_2500M_CLK); + break; + default: + break; + } + + return rv; +} + +static sw_error_t +adpt_mp_port_reset_set(a_uint32_t dev_id, a_uint32_t port_id) +{ + sw_error_t rv = 0; + a_uint32_t phy_addr; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + + if (port_id == SSDK_PHYSICAL_PORT1) { + /*internal gephy reset*/ + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get(dev_id, + port_id)); + if (NULL == phy_drv->phy_function_reset) + return SW_NOT_SUPPORTED; + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_addr); + SW_RTN_ON_ERROR (rv); + rv = phy_drv->phy_function_reset(dev_id, phy_addr, PHY_FIFO_RESET); + SW_RTN_ON_ERROR (rv); + } else if (port_id == SSDK_PHYSICAL_PORT2) { + rv = adpt_mp_uniphy_adapter_port_reset(dev_id, port_id); + } else { + return SW_NOT_SUPPORTED; + } + + return rv; +} + +static sw_error_t +adpt_mp_port_txmac_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv = SW_OK; + a_uint32_t gmac_id = 0; + union mac_configuration_u configuration; + + ADPT_DEV_ID_CHECK(dev_id); + MP_PORT_ID_CHECK(port_id); + + memset(&configuration, 0, sizeof(configuration)); + gmac_id = MP_PORT_TO_GMAC_ID(port_id); + + rv = mp_mac_configuration_get(dev_id, gmac_id, &configuration); + SW_RTN_ON_ERROR(rv); + + configuration.bf.tx_enable = enable; + rv = mp_mac_configuration_set(dev_id, gmac_id, &configuration); + + return rv; +} + +#ifndef IN_PORTCONTROL_MINI +static sw_error_t +adpt_mp_port_txmac_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv = SW_OK; + a_uint32_t gmac_id = 0; + union mac_configuration_u configuration; + + ADPT_DEV_ID_CHECK(dev_id); + MP_PORT_ID_CHECK(port_id); + ADPT_NULL_POINT_CHECK(enable); + + memset(&configuration, 0, sizeof(configuration)); + gmac_id = MP_PORT_TO_GMAC_ID(port_id); + + rv = mp_mac_configuration_get(dev_id, gmac_id, &configuration); + SW_RTN_ON_ERROR(rv); + + *enable = configuration.bf.tx_enable; + + return rv; +} +#endif + +static sw_error_t +adpt_mp_port_rxmac_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv = SW_OK; + a_uint32_t gmac_id = 0; + union mac_configuration_u configuration; + + ADPT_DEV_ID_CHECK(dev_id); + MP_PORT_ID_CHECK(port_id); + + memset(&configuration, 0, sizeof(configuration)); + gmac_id = MP_PORT_TO_GMAC_ID(port_id); + + rv = mp_mac_configuration_get(dev_id, gmac_id, &configuration); + SW_RTN_ON_ERROR(rv); + + configuration.bf.rx_enable = enable; + rv = mp_mac_configuration_set(dev_id, gmac_id, &configuration); + + return rv; +} + +#ifndef IN_PORTCONTROL_MINI +static sw_error_t +adpt_mp_port_rxmac_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv = SW_OK; + a_uint32_t gmac_id = 0; + union mac_configuration_u configuration; + + ADPT_DEV_ID_CHECK(dev_id); + MP_PORT_ID_CHECK(port_id); + ADPT_NULL_POINT_CHECK(enable); + + memset(&configuration, 0, sizeof(configuration)); + gmac_id = MP_PORT_TO_GMAC_ID(port_id); + + rv = mp_mac_configuration_get(dev_id, gmac_id, &configuration); + SW_RTN_ON_ERROR(rv); + + *enable = configuration.bf.rx_enable; + + return rv; +} +#endif + +static sw_error_t +adpt_mp_port_txfc_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv = SW_OK; + a_uint32_t gmac_id = 0; + union mac_flow_ctrl_u mac_flow_ctrl; + struct qca_phy_priv *priv = ssdk_phy_priv_data_get(dev_id); + union mac_operation_mode_ctrl_u mac_operation_mode_ctrl; + + ADPT_DEV_ID_CHECK(dev_id); + MP_PORT_ID_CHECK(port_id); + ADPT_NULL_POINT_CHECK(priv); + + memset(&mac_flow_ctrl, 0, sizeof(mac_flow_ctrl)); + memset(&mac_operation_mode_ctrl, 0, sizeof(mac_operation_mode_ctrl)); + gmac_id = MP_PORT_TO_GMAC_ID(port_id); + + rv = mp_mac_flowctrl_get(dev_id, gmac_id, &mac_flow_ctrl); + SW_RTN_ON_ERROR(rv); + + rv = mp_mac_operation_mode_ctrl_get(dev_id, gmac_id, + &mac_operation_mode_ctrl); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) { + mac_flow_ctrl.bf.flowctrl_tx_enable = 1; + mac_flow_ctrl.bf.pause_time = GMAC_PAUSE_TIME; + mac_flow_ctrl.bf.disable_zero_quanta_pause = + GMAC_PAUSE_ZERO_QUANTA_ENABLE; + mac_operation_mode_ctrl.bf.enable_hw_flowctrl = + GMAC_HW_FLOWCTRL_ENABLE; + } else { + mac_flow_ctrl.bf.flowctrl_tx_enable = 0; + mac_operation_mode_ctrl.bf.enable_hw_flowctrl = + GMAC_HW_FLOWCTRL_DISABLE; + } + + rv = mp_mac_operation_mode_ctrl_set(dev_id, gmac_id, + &mac_operation_mode_ctrl); + SW_RTN_ON_ERROR(rv); + + rv = mp_mac_flowctrl_set(dev_id, gmac_id, &mac_flow_ctrl); + SW_RTN_ON_ERROR(rv); + + priv->port_old_tx_flowctrl[port_id - 1] = enable; + + return rv; +} + +#ifndef IN_PORTCONTROL_MINI +static sw_error_t +adpt_mp_port_txfc_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv = SW_OK; + a_uint32_t gmac_id = 0; + union mac_flow_ctrl_u mac_flow_ctrl; + + ADPT_DEV_ID_CHECK(dev_id); + MP_PORT_ID_CHECK(port_id); + ADPT_NULL_POINT_CHECK(enable); + + memset(&mac_flow_ctrl, 0, sizeof(mac_flow_ctrl)); + gmac_id = MP_PORT_TO_GMAC_ID(port_id); + + rv = mp_mac_flowctrl_get(dev_id, gmac_id, &mac_flow_ctrl); + SW_RTN_ON_ERROR(rv); + + if (mac_flow_ctrl.bf.flowctrl_tx_enable) { + *enable = A_TRUE; + } else { + *enable = A_FALSE; + } + + return rv; +} +#endif + +static sw_error_t +adpt_mp_port_rxfc_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv = SW_OK; + a_uint32_t gmac_id = 0; + union mac_flow_ctrl_u mac_flow_ctrl; + struct qca_phy_priv *priv = ssdk_phy_priv_data_get(dev_id); + + ADPT_DEV_ID_CHECK(dev_id); + MP_PORT_ID_CHECK(port_id); + ADPT_NULL_POINT_CHECK(priv); + + memset(&mac_flow_ctrl, 0, sizeof(mac_flow_ctrl)); + gmac_id = MP_PORT_TO_GMAC_ID(port_id); + + rv = mp_mac_flowctrl_get(dev_id, gmac_id, &mac_flow_ctrl); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) { + mac_flow_ctrl.bf.flowctrl_rx_enable = 1; + } else { + mac_flow_ctrl.bf.flowctrl_rx_enable = 0; + } + + rv = mp_mac_flowctrl_set(dev_id, gmac_id, &mac_flow_ctrl); + + priv->port_old_rx_flowctrl[port_id - 1] = enable; + + return rv; +} + +#ifndef IN_PORTCONTROL_MINI +static sw_error_t +adpt_mp_port_rxfc_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv = SW_OK; + a_uint32_t gmac_id = 0; + union mac_flow_ctrl_u mac_flow_ctrl; + + ADPT_DEV_ID_CHECK(dev_id); + MP_PORT_ID_CHECK(port_id); + ADPT_NULL_POINT_CHECK(enable); + + memset(&mac_flow_ctrl, 0, sizeof(mac_flow_ctrl)); + gmac_id = MP_PORT_TO_GMAC_ID(port_id); + + rv = mp_mac_flowctrl_get(dev_id, gmac_id, &mac_flow_ctrl); + SW_RTN_ON_ERROR(rv); + + if (mac_flow_ctrl.bf.flowctrl_rx_enable) { + *enable = A_TRUE; + } else { + *enable = A_FALSE; + } + + return rv; +} +#endif + +static sw_error_t +adpt_mp_port_flowctrl_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv = SW_OK; + struct qca_phy_priv *priv = ssdk_phy_priv_data_get(dev_id); + + ADPT_DEV_ID_CHECK(dev_id); + MP_PORT_ID_CHECK(port_id); + ADPT_NULL_POINT_CHECK(priv); + + rv = adpt_mp_port_txfc_status_set(dev_id, port_id, enable); + SW_RTN_ON_ERROR(rv); + + rv = adpt_mp_port_rxfc_status_set(dev_id, port_id, enable); + SW_RTN_ON_ERROR(rv); + + priv->port_old_tx_flowctrl[port_id - 1] = enable; + priv->port_old_rx_flowctrl[port_id - 1] = enable; + + return rv; +} + +#ifndef IN_PORTCONTROL_MINI +static sw_error_t +adpt_mp_port_flowctrl_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv = SW_OK; + a_bool_t txfc_enable, rxfc_enable; + + ADPT_DEV_ID_CHECK(dev_id); + MP_PORT_ID_CHECK(port_id); + ADPT_NULL_POINT_CHECK(enable); + + rv = adpt_mp_port_txfc_status_get(dev_id, port_id, &txfc_enable); + SW_RTN_ON_ERROR(rv); + rv = adpt_mp_port_rxfc_status_get(dev_id, port_id, &rxfc_enable); + SW_RTN_ON_ERROR(rv); + + *enable = txfc_enable & rxfc_enable; + + return rv; +} +#endif + +static sw_error_t +adpt_mp_port_flowctrl_forcemode_set(a_uint32_t dev_id, + fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv = SW_OK; + struct qca_phy_priv *priv = ssdk_phy_priv_data_get(dev_id); + + ADPT_DEV_ID_CHECK(dev_id); + MP_PORT_ID_CHECK(port_id); + ADPT_NULL_POINT_CHECK(priv); + + priv->port_tx_flowctrl_forcemode[port_id - 1] = enable; + priv->port_rx_flowctrl_forcemode[port_id - 1] = enable; + + return rv; +} + +#ifndef IN_PORTCONTROL_MINI +static sw_error_t +adpt_mp_port_flowctrl_forcemode_get(a_uint32_t dev_id, + fal_port_t port_id, a_bool_t *enable) +{ + sw_error_t rv = SW_OK; + struct qca_phy_priv *priv = ssdk_phy_priv_data_get(dev_id); + + + ADPT_DEV_ID_CHECK(dev_id); + MP_PORT_ID_CHECK(port_id); + ADPT_NULL_POINT_CHECK(enable); + ADPT_NULL_POINT_CHECK(priv); + + *enable = (priv->port_tx_flowctrl_forcemode[port_id - 1] & + priv->port_rx_flowctrl_forcemode[port_id - 1]); + + return rv; +} +#endif + +static sw_error_t +adpt_mp_port_mac_status_get(a_uint32_t dev_id, a_uint32_t port_id, + struct port_phy_status *port_mac_status) +{ + sw_error_t rv = SW_OK; + a_uint32_t gmac_id = 0; + union mac_configuration_u configuration; + + ADPT_DEV_ID_CHECK(dev_id); + MP_PORT_ID_CHECK(port_id); + ADPT_NULL_POINT_CHECK(port_mac_status); + + memset(&configuration, 0, sizeof(configuration)); + gmac_id = MP_PORT_TO_GMAC_ID(port_id); + + rv = mp_mac_configuration_get(dev_id, gmac_id, &configuration); + SW_RTN_ON_ERROR(rv); + + if (configuration.bf.port_select == GMAC_SPEED_1000M) { + port_mac_status->speed = FAL_SPEED_1000; + } else { + if (configuration.bf.mii_speed == GMAC_SPEED_100M) { + port_mac_status->speed = FAL_SPEED_100; + } else { + port_mac_status->speed = FAL_SPEED_10; + } + } + + if (configuration.bf.duplex == GMAC_FULL_DUPLEX) { + port_mac_status->duplex = FAL_FULL_DUPLEX; + } else { + port_mac_status->duplex = FAL_HALF_DUPLEX; + } + + return rv; + +} + +static sw_error_t +adpt_mp_port_mac_speed_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_port_speed_t speed) +{ + sw_error_t rv = SW_OK; + a_uint32_t gmac_id = 0; + union mac_configuration_u configuration; + a_bool_t force_port; + + ADPT_DEV_ID_CHECK(dev_id); + MP_PORT_ID_CHECK(port_id); + + memset(&configuration, 0, sizeof(configuration)); + gmac_id = MP_PORT_TO_GMAC_ID(port_id); + + rv = mp_mac_configuration_get(dev_id, gmac_id, &configuration); + SW_RTN_ON_ERROR(rv); + + if ((FAL_SPEED_1000 == speed) || (FAL_SPEED_2500 == speed)) { + configuration.bf.port_select = GMAC_SPEED_1000M; + } else if (FAL_SPEED_100 == speed) { + configuration.bf.port_select = (~GMAC_SPEED_1000M) & 0x1; + configuration.bf.mii_speed = GMAC_SPEED_100M; + } else if (FAL_SPEED_10== speed) { + configuration.bf.port_select = (~GMAC_SPEED_1000M) & 0x1; + configuration.bf.mii_speed = GMAC_SPEED_10M; + } + + rv = mp_mac_configuration_set(dev_id, gmac_id, &configuration); + SW_RTN_ON_ERROR(rv); + + force_port = ssdk_port_feature_get(dev_id, port_id, PHY_F_FORCE); + /* enable force port configuration */ + if (force_port == A_TRUE) { + rv = _adpt_mp_port_gcc_speed_clock_set(dev_id, + port_id, speed); + SW_RTN_ON_ERROR(rv); + rv = adpt_mp_gcc_uniphy_port_clock_set(dev_id, + port_id, A_TRUE); + SW_RTN_ON_ERROR(rv); + rv = _adpt_mp_gcc_mac_clock_set(dev_id, + port_id, A_TRUE); + SW_RTN_ON_ERROR(rv); + rv = adpt_mp_port_reset_set(dev_id, port_id); + SW_RTN_ON_ERROR(rv); + } + return rv; + +} + +static sw_error_t +adpt_mp_port_mac_duplex_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_port_duplex_t duplex) +{ + sw_error_t rv = SW_OK; + a_uint32_t gmac_id = 0; + union mac_configuration_u configuration; + + ADPT_DEV_ID_CHECK(dev_id); + MP_PORT_ID_CHECK(port_id); + + memset(&configuration, 0, sizeof(configuration)); + gmac_id = MP_PORT_TO_GMAC_ID(port_id); + + rv = mp_mac_configuration_get(dev_id, gmac_id, &configuration); + SW_RTN_ON_ERROR(rv); + + if (FAL_FULL_DUPLEX == duplex) { + configuration.bf.duplex = GMAC_FULL_DUPLEX; + } else { + configuration.bf.duplex = GMAC_HALF_DUPLEX; + } + + rv = mp_mac_configuration_set(dev_id, gmac_id, &configuration); + + return rv; +} + +static sw_error_t +adpt_mp_port_promisc_mode_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv = SW_OK; + a_uint32_t gmac_id = 0; + union mac_frame_filter_u mac_frame_filter; + + ADPT_DEV_ID_CHECK(dev_id); + MP_PORT_ID_CHECK(port_id); + + memset(&mac_frame_filter, 0, sizeof(mac_frame_filter)); + gmac_id = MP_PORT_TO_GMAC_ID(port_id); + + rv = mp_mac_frame_filter_get(dev_id, gmac_id, &mac_frame_filter); + SW_RTN_ON_ERROR(rv); + + mac_frame_filter.bf.promiscuous_mode = enable; + + rv = mp_mac_frame_filter_set(dev_id, gmac_id, &mac_frame_filter); + + return rv; +} + +#ifndef IN_PORTCONTROL_MINI +static sw_error_t +adpt_mp_port_promisc_mode_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv = SW_OK; + a_uint32_t gmac_id = 0; + union mac_frame_filter_u mac_frame_filter; + + ADPT_DEV_ID_CHECK(dev_id); + MP_PORT_ID_CHECK(port_id); + ADPT_NULL_POINT_CHECK(enable); + + memset(&mac_frame_filter, 0, sizeof(mac_frame_filter)); + gmac_id = MP_PORT_TO_GMAC_ID(port_id); + + rv = mp_mac_frame_filter_get(dev_id, gmac_id, &mac_frame_filter); + SW_RTN_ON_ERROR(rv); + + *enable = mac_frame_filter.bf.promiscuous_mode; + + return rv; +} +#endif + +static sw_error_t +adpt_mp_port_max_frame_size_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t max_frame) +{ + sw_error_t rv = SW_OK; + a_uint32_t gmac_id = 0; + union mac_max_frame_ctrl_u mac_max_frame_ctrl; + union mac_configuration_u configuration; + union mac_operation_mode_ctrl_u mac_operation_mode_ctrl; + + ADPT_DEV_ID_CHECK(dev_id); + MP_PORT_ID_CHECK(port_id); + + memset(&configuration, 0, sizeof(configuration)); + memset(&mac_max_frame_ctrl, 0, sizeof(mac_max_frame_ctrl)); + memset(&mac_operation_mode_ctrl, 0, sizeof(mac_operation_mode_ctrl)); + gmac_id = MP_PORT_TO_GMAC_ID(port_id); + + rv = mp_mac_max_frame_ctrl_get(dev_id, gmac_id, &mac_max_frame_ctrl); + SW_RTN_ON_ERROR(rv); + rv = mp_mac_configuration_get(dev_id, gmac_id, &configuration); + SW_RTN_ON_ERROR(rv); + + configuration.bf.jabber_disable = GMAC_JD_ENABLE; + configuration.bf.watchdog_disable = GMAC_WD_DISABLE; + configuration.bf.jumbo_frame_enable = GMAC_JUMBO_FRAME_ENABLE; + configuration.bf.frame_burst_enable = GMAC_FRAME_BURST_ENABLE; + rv = mp_mac_configuration_set(dev_id, gmac_id, &configuration); + SW_RTN_ON_ERROR(rv); + + mac_max_frame_ctrl.bf.max_frame_ctrl_enable = GMAC_MAX_FRAME_CTRL_ENABLE; + mac_max_frame_ctrl.bf.max_frame_ctrl = max_frame; + rv = mp_mac_max_frame_ctrl_set(dev_id, gmac_id, &mac_max_frame_ctrl); + + rv = mp_mac_operation_mode_ctrl_get(dev_id, gmac_id, + &mac_operation_mode_ctrl); + mac_operation_mode_ctrl.bf.receive_store_and_foward = + GMAC_RX_STORE_FORWAD_ENABLE; + mac_operation_mode_ctrl.bf.transmit_store_and_foward = + GMAC_TX_STORE_FORWAD_ENABLE; + mac_operation_mode_ctrl.bf.forward_error_frame = + GMAC_FORWARD_ERROR_FRAME_DISABLE; + mac_operation_mode_ctrl.bf.drop_gaint_frame = + GMAC_DROP_GAINT_FRAME_DISABLE; + rv = mp_mac_operation_mode_ctrl_set(dev_id, gmac_id, + &mac_operation_mode_ctrl); + + return rv; +} + +static sw_error_t +adpt_mp_port_max_frame_size_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t *max_frame) +{ + sw_error_t rv = SW_OK; + a_uint32_t gmac_id = 0; + union mac_max_frame_ctrl_u mac_max_frame_ctrl; + + ADPT_DEV_ID_CHECK(dev_id); + MP_PORT_ID_CHECK(port_id); + ADPT_NULL_POINT_CHECK(max_frame); + + memset(&mac_max_frame_ctrl, 0, sizeof(mac_max_frame_ctrl)); + gmac_id = MP_PORT_TO_GMAC_ID(port_id); + + rv = mp_mac_max_frame_ctrl_get(dev_id, gmac_id, &mac_max_frame_ctrl); + SW_RTN_ON_ERROR(rv); + + *max_frame = mac_max_frame_ctrl.bf.max_frame_ctrl; + + return rv; +} + +static sw_error_t +adpt_mp_port_mac_eee_enable_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv = 0; + a_uint32_t gmac_id = 0; + union mac_lpi_ctrl_status_u mac_lpi_ctrl_status; + + ADPT_DEV_ID_CHECK(dev_id); + MP_PORT_ID_CHECK(port_id); + + memset(&mac_lpi_ctrl_status, 0, sizeof(mac_lpi_ctrl_status)); + gmac_id = MP_PORT_TO_GMAC_ID(port_id); + + rv = mp_mac_lpi_ctrl_status_get(dev_id, gmac_id, &mac_lpi_ctrl_status); + SW_RTN_ON_ERROR(rv); + mac_lpi_ctrl_status.bf.lpi_enable = enable; + + rv = mp_mac_lpi_ctrl_status_set(dev_id, gmac_id, &mac_lpi_ctrl_status); + + return rv; +} + +#ifndef IN_PORTCONTROL_MINI +static sw_error_t +adpt_mp_port_mac_eee_enable_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv = 0; + a_uint32_t gmac_id = 0; + union mac_lpi_ctrl_status_u mac_lpi_ctrl_status; + + ADPT_DEV_ID_CHECK(dev_id); + MP_PORT_ID_CHECK(port_id); + ADPT_NULL_POINT_CHECK(enable); + + memset(&mac_lpi_ctrl_status, 0, sizeof(mac_lpi_ctrl_status)); + gmac_id = MP_PORT_TO_GMAC_ID(port_id); + + rv = mp_mac_lpi_ctrl_status_get(dev_id, gmac_id, &mac_lpi_ctrl_status); + SW_RTN_ON_ERROR(rv); + + *enable = mac_lpi_ctrl_status.bf.lpi_enable; + + return rv; + +} +#endif + +static sw_error_t +adpt_mp_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 = 0; + union mac_lpi_timer_ctrl_u mac_lpi_timer_ctrl; + union mac_lpi_ctrl_status_u mac_lpi_ctrl_status; + + a_uint32_t phy_addr = 0, gmac_id = 0; + a_uint32_t adv; + hsl_phy_ops_t *phy_drv; + struct qca_phy_priv *priv; + + ADPT_DEV_ID_CHECK(dev_id); + MP_PORT_ID_CHECK(port_id); + + memset(&mac_lpi_timer_ctrl, 0, sizeof(mac_lpi_timer_ctrl)); + memset(&mac_lpi_ctrl_status, 0, sizeof(mac_lpi_ctrl_status)); + gmac_id = MP_PORT_TO_GMAC_ID(port_id); + + priv = ssdk_phy_priv_data_get(dev_id); + SW_RTN_ON_NULL(priv); + + if (port_eee_cfg->enable) { + adv = port_eee_cfg->advertisement; + } else { + adv = 0; + } + + if (port_eee_cfg->lpi_tx_enable) { + port_lpi_status[dev_id] |= BIT(port_id-1); + } else { + port_lpi_status[dev_id] &= ~BIT(port_id-1); + } + + SW_RTN_ON_NULL(phy_drv = hsl_phy_api_ops_get(dev_id, port_id)); + if (NULL == phy_drv->phy_eee_adv_set) { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_addr); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_eee_adv_set(dev_id, phy_addr, adv); + SW_RTN_ON_ERROR (rv); + + rv = mp_mac_lpi_timer_ctrl_get(dev_id, gmac_id, &mac_lpi_timer_ctrl); + SW_RTN_ON_ERROR (rv); + mac_lpi_timer_ctrl.bf.lpi_tw_timer = port_eee_cfg->lpi_wakeup_timer; + rv = mp_mac_lpi_timer_ctrl_set(dev_id, gmac_id, &mac_lpi_timer_ctrl); + SW_RTN_ON_ERROR (rv); + + rv = mp_mac_lpi_ctrl_status_get(dev_id, gmac_id, &mac_lpi_ctrl_status); + SW_RTN_ON_ERROR (rv); + mac_lpi_ctrl_status.bf.lpi_tx_auto_enable = GMAC_LPI_AUTO_MODE; + mac_lpi_ctrl_status.bf.link_status = GMAC_LPI_LINK_UP; + mac_lpi_ctrl_status.bf.lpi_enable = port_eee_cfg->lpi_tx_enable; + rv = mp_mac_lpi_ctrl_status_set(dev_id, gmac_id, &mac_lpi_ctrl_status); + SW_RTN_ON_ERROR (rv); + + if (port_lpi_status[dev_id] & PORT_LPI_ENABLE_STATUS) { + if (!(port_lpi_status[dev_id] & PORT_LPI_TASK_RUNNING)) { + if (!(port_lpi_status[dev_id] & PORT_LPI_TASK_START)) { + qca_mac_sw_sync_work_start(priv); + port_lpi_status[dev_id] |= PORT_LPI_TASK_START; + } else { + qca_mac_sw_sync_work_resume(priv); + } + port_lpi_status[dev_id] |= PORT_LPI_TASK_RUNNING; + } + } else { + qca_mac_sw_sync_work_stop(priv); + port_lpi_status[dev_id] &= ~PORT_LPI_TASK_RUNNING; + } + + return rv; +} +static sw_error_t +adpt_mp_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 = 0; + union mac_lpi_timer_ctrl_u mac_lpi_timer_ctrl; + union mac_lpi_ctrl_status_u mac_lpi_ctrl_status; + a_uint32_t phy_addr = 0, gmac_id = 0; + a_uint32_t adv, lp_adv, cap, status; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + MP_PORT_ID_CHECK(port_id); + ADPT_NULL_POINT_CHECK(port_eee_cfg); + + memset(&mac_lpi_timer_ctrl, 0, sizeof(mac_lpi_timer_ctrl)); + memset(&mac_lpi_ctrl_status, 0, sizeof(mac_lpi_ctrl_status)); + memset(port_eee_cfg, 0, sizeof(*port_eee_cfg)); + gmac_id = MP_PORT_TO_GMAC_ID(port_id); + + SW_RTN_ON_NULL(phy_drv =hsl_phy_api_ops_get (dev_id, port_id)); + if ((NULL == phy_drv->phy_eee_adv_get) || + (NULL == phy_drv->phy_eee_partner_adv_get) || + (NULL == phy_drv->phy_eee_cap_get) || + (NULL == phy_drv->phy_eee_status_get)) { + return SW_NOT_SUPPORTED; + } + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_addr); + SW_RTN_ON_ERROR (rv); + rv = phy_drv->phy_eee_adv_get(dev_id, phy_addr, &adv); + SW_RTN_ON_ERROR (rv); + port_eee_cfg->advertisement = adv; + rv = phy_drv->phy_eee_partner_adv_get(dev_id, phy_addr, &lp_adv); + SW_RTN_ON_ERROR (rv); + port_eee_cfg->link_partner_advertisement = lp_adv; + rv = phy_drv->phy_eee_cap_get(dev_id, phy_addr, &cap); + SW_RTN_ON_ERROR (rv); + port_eee_cfg->capability = cap; + rv = phy_drv->phy_eee_status_get(dev_id, phy_addr, &status); + SW_RTN_ON_ERROR (rv); + port_eee_cfg->eee_status = status; + + if (port_eee_cfg->advertisement) { + port_eee_cfg->enable = A_TRUE; + } else { + port_eee_cfg->enable = A_FALSE; + } + rv = mp_mac_lpi_ctrl_status_get(dev_id, gmac_id, &mac_lpi_ctrl_status); + SW_RTN_ON_ERROR (rv); + port_eee_cfg->lpi_tx_enable = mac_lpi_ctrl_status.bf.lpi_enable; + + rv = mp_mac_lpi_timer_ctrl_get(dev_id, gmac_id, &mac_lpi_timer_ctrl); + SW_RTN_ON_ERROR (rv); + port_eee_cfg->lpi_wakeup_timer = mac_lpi_timer_ctrl.bf.lpi_tw_timer; + + return rv; +} + +static sw_error_t +adpt_mp_port_interface_mode_status_get(a_uint32_t dev_id, + a_uint32_t port_id, fal_port_interface_mode_t * mode) +{ + sw_error_t rv = SW_OK; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(mode); + + SW_RTN_ON_NULL(phy_drv = hsl_phy_api_ops_get(dev_id, port_id)); + SW_RTN_ON_NULL(phy_drv->phy_interface_mode_status_get); + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_interface_mode_status_get(dev_id, phy_id,mode); + + return rv; +} + +static sw_error_t +adpt_mp_port_interface_mode_switch(a_uint32_t dev_id, a_uint32_t port_id) +{ + sw_error_t rv = SW_OK; + fal_port_interface_mode_t port_mode_new = PORT_INTERFACE_MODE_MAX; + a_uint32_t uniphy_mode_old = PORT_WRAPPER_MAX; + a_uint32_t uniphy_mode_new = PORT_WRAPPER_MAX; + a_bool_t force_port; + + force_port = ssdk_port_feature_get(dev_id, port_id, PHY_F_FORCE); + if ((port_id == SSDK_PHYSICAL_PORT1) || (force_port == A_TRUE)) { + return SW_OK; + } + rv = adpt_mp_port_interface_mode_status_get(dev_id, + port_id, &port_mode_new); + SW_RTN_ON_ERROR(rv); + + if (port_mode_new == PHY_SGMII_BASET) { + uniphy_mode_new = PORT_WRAPPER_SGMII_CHANNEL0; + } else if (port_mode_new == PORT_SGMII_PLUS) { + uniphy_mode_new = PORT_WRAPPER_SGMII_PLUS; + } else { + return SW_NOT_SUPPORTED; + } + uniphy_mode_old = ssdk_dt_global_get_mac_mode(dev_id, + SSDK_UNIPHY_INSTANCE0); + if (uniphy_mode_new != uniphy_mode_old) { + rv = adpt_mp_uniphy_mode_configure(dev_id, + SSDK_UNIPHY_INSTANCE0, uniphy_mode_new); + SW_RTN_ON_ERROR(rv); + ssdk_dt_global_set_mac_mode(dev_id, + SSDK_UNIPHY_INSTANCE0, uniphy_mode_new); + } + + return rv; +} + +static sw_error_t +_adpt_mp_port_phy_status_get(a_uint32_t dev_id, a_uint32_t port_id, + struct port_phy_status *phy_status) +{ + sw_error_t rv = 0; + a_uint32_t phy_addr; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(phy_status); + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + SW_RTN_ON_NULL (phy_drv->phy_get_status); + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_addr); + SW_RTN_ON_ERROR (rv); + rv = phy_drv->phy_get_status (dev_id, phy_addr, phy_status); + SW_RTN_ON_ERROR (rv); + + return rv; +} + +static sw_error_t +_adpt_mp_port_link_down_update(struct qca_phy_priv *priv, + a_uint32_t port_id) +{ + sw_error_t rv = 0; + + /* disable rx mac, gcc uniphy port and gcc mac port status */ + rv = adpt_mp_port_rxmac_status_set(priv->device_id, port_id, A_FALSE); + SW_RTN_ON_ERROR (rv); + rv = adpt_mp_gcc_uniphy_port_clock_set(priv->device_id, port_id, A_FALSE); + SW_RTN_ON_ERROR (rv); + _adpt_mp_gcc_mac_clock_set(priv->device_id, port_id, A_FALSE); + SW_RTN_ON_ERROR (rv); + + /* switch interface mode if necessary under link down*/ + rv = adpt_mp_port_interface_mode_switch(priv->device_id, port_id); + SW_RTN_ON_ERROR (rv); + SSDK_DEBUG("MP port %d interface mode switch under link down!\n", + port_id); + return rv; +} + +static a_bool_t +_adpt_mp_port_status_change(struct qca_phy_priv *priv, a_uint32_t port_id, + struct port_phy_status phy_status) +{ + if ((a_uint32_t)phy_status.speed != priv->port_old_speed[port_id - 1]) + return A_TRUE; + if ((a_uint32_t)phy_status.duplex != priv->port_old_duplex[port_id - 1]) + return A_TRUE; + if (phy_status.tx_flowctrl != priv->port_old_tx_flowctrl[port_id - 1]) + return A_TRUE; + if (phy_status.rx_flowctrl != priv->port_old_rx_flowctrl[port_id - 1]) + return A_TRUE; + return A_FALSE; +} + +sw_error_t +adpt_mp_port_link_up_change_update(struct qca_phy_priv *priv, + a_uint32_t port_id, struct port_phy_status phy_status) +{ + sw_error_t rv = 0; + + if ((a_uint32_t)phy_status.speed != + priv->port_old_speed[port_id - 1]) { + + /* configure gcc speed clock frequency */ + rv = _adpt_mp_port_gcc_speed_clock_set(priv->device_id, + port_id, phy_status.speed); + SW_RTN_ON_ERROR (rv); + + /* config mac speed */ + rv = adpt_mp_port_mac_speed_set(priv->device_id, + port_id, phy_status.speed); + SW_RTN_ON_ERROR (rv); + + priv->port_old_speed[port_id - 1] = + (a_uint32_t)phy_status.speed; + + SSDK_DEBUG("Port %d up and speed is %d\n", port_id, + priv->port_old_speed[port_id - 1]); + } + /* link up duplex change configuration */ + if ((a_uint32_t)phy_status.duplex != + priv->port_old_duplex[port_id - 1]) { + + rv = adpt_mp_port_mac_duplex_set(priv->device_id, + port_id, phy_status.duplex); + + priv->port_old_duplex[port_id - 1] = + (a_uint32_t)phy_status.duplex; + SW_RTN_ON_ERROR (rv); + + SSDK_DEBUG("Port %d up and duplex is %d\n", port_id, + priv->port_old_duplex[port_id - 1]); + } + /* tx flowctrl configuration*/ + if (priv->port_tx_flowctrl_forcemode[port_id - 1] != A_TRUE) { + if (phy_status.duplex == FAL_HALF_DUPLEX) { + phy_status.tx_flowctrl = A_TRUE; + } + if (phy_status.tx_flowctrl != + priv->port_old_tx_flowctrl[port_id - 1]) { + rv = adpt_mp_port_txfc_status_set(priv->device_id, + port_id, phy_status.tx_flowctrl); + SW_RTN_ON_ERROR (rv); + priv->port_old_tx_flowctrl[port_id - 1] = + phy_status.tx_flowctrl; + + SSDK_DEBUG("Port %d up and tx flowctrl is %d\n", + port_id, + priv->port_old_tx_flowctrl[port_id - 1]); + } + } + /*rx flowctrl configuration*/ + if (priv->port_rx_flowctrl_forcemode[port_id - 1] != A_TRUE) { + if (phy_status.duplex == FAL_HALF_DUPLEX) { + phy_status.rx_flowctrl = A_TRUE; + } + if (phy_status.rx_flowctrl != + priv->port_old_rx_flowctrl[port_id - 1]) { + rv = adpt_mp_port_rxfc_status_set(priv->device_id, + port_id, phy_status.rx_flowctrl); + SW_RTN_ON_ERROR (rv); + priv->port_old_rx_flowctrl[port_id - 1] = + phy_status.rx_flowctrl; + + SSDK_DEBUG("Port %d up and rx flowctrl is %d\n", + port_id, + priv->port_old_rx_flowctrl[port_id-1]); + } + } + + return rv; +} + +sw_error_t +adpt_mp_port_link_up_update(struct qca_phy_priv *priv, + a_uint32_t port_id, struct port_phy_status phy_status) +{ + sw_error_t rv = 0; + a_bool_t change; + + /* port phy status change check*/ + change = _adpt_mp_port_status_change(priv, port_id, + phy_status); + + rv = adpt_mp_port_txmac_status_set(priv->device_id, port_id, + A_FALSE); + SW_RTN_ON_ERROR (rv); + + /* switch interface mode if necessary under link up */ + rv = adpt_mp_port_interface_mode_switch(priv->device_id, port_id); + SW_RTN_ON_ERROR (rv); + SSDK_DEBUG("MP port %d interface mode switch under link up!\n", + port_id); + /* link up status change*/ + if (change == A_TRUE) { + rv = adpt_mp_port_link_up_change_update(priv, + port_id, phy_status); + SW_RTN_ON_ERROR (rv); + } + + rv = adpt_mp_gcc_uniphy_port_clock_set(priv->device_id, + port_id, A_TRUE); + SW_RTN_ON_ERROR (rv); + rv =_adpt_mp_gcc_mac_clock_set(priv->device_id, + port_id, A_TRUE); + SW_RTN_ON_ERROR (rv); + + msleep(50); + + if (change == A_TRUE) { + rv = adpt_mp_port_reset_set(priv->device_id, port_id); + SW_RTN_ON_ERROR (rv); + } + rv = adpt_mp_port_txmac_status_set(priv->device_id, + port_id, A_TRUE); + SW_RTN_ON_ERROR (rv); + rv = adpt_mp_port_rxmac_status_set(priv->device_id, + port_id, A_TRUE); + SW_RTN_ON_ERROR (rv); + + return rv; +} + +sw_error_t +adpt_mp_port_netdev_change_notify(struct qca_phy_priv *priv, + a_uint32_t port_id) +{ + sw_error_t rv = 0; + struct port_phy_status phy_status = {0}; + a_uint32_t portbmp[SW_MAX_NR_DEV] = {0}; + + portbmp[priv->device_id] = qca_ssdk_port_bmp_get(priv->device_id); + + if(!(portbmp[priv->device_id] & (0x1 << port_id))) { + SSDK_ERROR("netdev change notify with incorrect port %d\n", + port_id); + return SW_BAD_VALUE; + } + + rv = _adpt_mp_port_phy_status_get(priv->device_id, port_id, + &phy_status); + if (rv != SW_OK) { + SSDK_ERROR("failed to get port %d status return value is %d\n", + port_id, rv); + return rv; + } + /* link status from up to down*/ + if ((phy_status.link_status == PORT_LINK_DOWN) && + (priv->port_old_link[port_id - 1] == PORT_LINK_UP)) { + SSDK_DEBUG("MP port %d change to link down status\n", port_id); + /* link down configuration*/ + rv = _adpt_mp_port_link_down_update(priv, port_id); + SW_RTN_ON_ERROR (rv); + priv->port_old_link[port_id - 1] = phy_status.link_status ; + } + /* link status from down to up */ + if ((phy_status.link_status == PORT_LINK_UP) && + (priv->port_old_link[port_id - 1] == PORT_LINK_DOWN)) { + SSDK_DEBUG("Port %d change to link up status\n", port_id); + rv = adpt_mp_port_link_up_update(priv, port_id, phy_status); + SW_RTN_ON_ERROR (rv); + priv->port_old_link[port_id - 1] = phy_status.link_status; + } + SSDK_DEBUG("MP port %d link is %d speed is %d duplex is %d" + " tx_flowctrl is %d rx_flowctrl is %d\n", + port_id, priv->port_old_link[port_id - 1], + priv->port_old_speed[port_id - 1], + priv->port_old_duplex[port_id - 1], + priv->port_old_tx_flowctrl[port_id - 1], + priv->port_old_rx_flowctrl[port_id - 1]); + + return rv; +} + +static sw_error_t +adpt_mp_port_lpi_polling_task(struct qca_phy_priv *priv) +{ + a_uint32_t port_id; + a_uint32_t portbmp[SW_MAX_NR_DEV] = {0}; + sw_error_t rv = SW_OK; + + portbmp[priv->device_id] = qca_ssdk_port_bmp_get(priv->device_id); + + for (port_id = SSDK_PHYSICAL_PORT1; port_id < SW_MAX_NR_PORT; port_id ++) { + + if(!(portbmp[priv->device_id] & BIT(port_id))) + continue; + if (port_lpi_status[priv->device_id] & BIT(port_id-1)) { + rv = adpt_mp_port_mac_eee_enable_set(priv->device_id, + port_id, A_TRUE); + SW_RTN_ON_ERROR(rv); + } + } + return SW_OK; +} + +static sw_error_t +adpt_mp_port_speed_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t * pspeed) +{ + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + struct port_phy_status port_mac_status = {0}; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(pspeed); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) { + return SW_BAD_PARAM; + } + + /* for those ports without PHY device should be s17c port */ + if (A_FALSE == _adpt_mp_port_phy_connected (dev_id, port_id)) { + rv = adpt_mp_port_mac_status_get(dev_id, port_id, &port_mac_status); + SW_RTN_ON_ERROR (rv); + *pspeed= port_mac_status.speed; + } else { + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, + port_id)); + if (NULL == phy_drv->phy_speed_get) { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + rv = phy_drv->phy_speed_get (dev_id, phy_id, pspeed); + SW_RTN_ON_ERROR (rv); + } + + return rv; +} + +static sw_error_t +adpt_mp_port_duplex_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t * pduplex) +{ + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + struct port_phy_status port_mac_status = {0}; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(pduplex); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) { + return SW_BAD_PARAM; + } + + /* for those ports without PHY device should be s17c port */ + if (A_FALSE == _adpt_mp_port_phy_connected (dev_id, port_id)) { + rv = adpt_mp_port_mac_status_get(dev_id, port_id, &port_mac_status); + SW_RTN_ON_ERROR (rv); + *pduplex = port_mac_status.duplex; + } else { + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, + port_id)); + if (NULL == phy_drv->phy_duplex_get) { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + rv = phy_drv->phy_duplex_get (dev_id, phy_id, pduplex); + SW_RTN_ON_ERROR (rv); + } + + return rv; +} + +static sw_error_t +adpt_mp_port_link_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status) +{ + sw_error_t rv = 0; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_NULL_POINT_CHECK(status); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) { + return SW_BAD_PARAM; + } + + /* for those ports without PHY device should be s17c port */ + if (A_FALSE == _adpt_mp_port_phy_connected (dev_id, port_id)) { + *status = A_TRUE; + } else { + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, + port_id)); + if (NULL == phy_drv->phy_link_status_get) { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + *status = phy_drv->phy_link_status_get (dev_id, phy_id); + } + + return SW_OK; + +} + +sw_error_t +adpt_mp_portctrl_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + { + return SW_FAIL; + } +#ifndef IN_PORTCONTROL_MINI + p_adpt_api->adpt_port_txmac_status_get = adpt_mp_port_txmac_status_get; + p_adpt_api->adpt_port_rxmac_status_get = adpt_mp_port_rxmac_status_get; + p_adpt_api->adpt_port_rxfc_status_get = adpt_mp_port_rxfc_status_get; + p_adpt_api->adpt_port_txfc_status_get = adpt_mp_port_txfc_status_get; + p_adpt_api->adpt_port_flowctrl_get = adpt_mp_port_flowctrl_get; + p_adpt_api->adpt_port_flowctrl_forcemode_get = + adpt_mp_port_flowctrl_forcemode_get; + p_adpt_api->adpt_port_promisc_mode_get = adpt_mp_port_promisc_mode_get; + p_adpt_api->adpt_port_interface_3az_status_get = adpt_mp_port_mac_eee_enable_get; +#endif + p_adpt_api->adpt_port_txmac_status_set = adpt_mp_port_txmac_status_set; + p_adpt_api->adpt_port_rxmac_status_set = adpt_mp_port_rxmac_status_set; + p_adpt_api->adpt_port_rxfc_status_set = adpt_mp_port_rxfc_status_set; + p_adpt_api->adpt_port_txfc_status_set = adpt_mp_port_txfc_status_set; + p_adpt_api->adpt_port_flowctrl_set = adpt_mp_port_flowctrl_set; + p_adpt_api->adpt_port_flowctrl_forcemode_set = + adpt_mp_port_flowctrl_forcemode_set; + p_adpt_api->adpt_port_max_frame_size_set = adpt_mp_port_max_frame_size_set; + p_adpt_api->adpt_port_max_frame_size_get = adpt_mp_port_max_frame_size_get; + p_adpt_api->adpt_port_promisc_mode_set = adpt_mp_port_promisc_mode_set; + p_adpt_api->adpt_port_mac_speed_set = adpt_mp_port_mac_speed_set; + p_adpt_api->adpt_port_speed_get = adpt_mp_port_speed_get; + p_adpt_api->adpt_port_mac_duplex_set = adpt_mp_port_mac_duplex_set; + p_adpt_api->adpt_port_duplex_get = adpt_mp_port_duplex_get; + p_adpt_api->adpt_port_link_status_get = adpt_mp_port_link_status_get; + p_adpt_api->adpt_port_interface_3az_status_set = adpt_mp_port_mac_eee_enable_set; + p_adpt_api->adpt_port_interface_eee_cfg_set = adpt_mp_port_interface_eee_cfg_set; + p_adpt_api->adpt_port_interface_eee_cfg_get = adpt_mp_port_interface_eee_cfg_get; + p_adpt_api->adpt_port_netdev_notify_set = adpt_mp_port_netdev_change_notify; + p_adpt_api->adpt_port_polling_sw_sync_set = adpt_mp_port_lpi_polling_task; + + return SW_OK; +} +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/mp/adpt_mp_uniphy.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/mp/adpt_mp_uniphy.c new file mode 100644 index 000000000..77acad02b --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/mp/adpt_mp_uniphy.c @@ -0,0 +1,398 @@ +/* + * 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. + */ + +/** + * @defgroup + * @{ + */ +#include "sw.h" +#include "hppe_uniphy_reg.h" +#include "hppe_uniphy.h" +#include "hppe_init.h" +#include "ssdk_init.h" +#include "ssdk_clk.h" +#include "ssdk_dts.h" +#include "adpt.h" +#include "mp_uniphy_reg.h" +#include "mp_uniphy.h" +#include "hsl_phy.h" + +static sw_error_t +_adpt_mp_uniphy_calibrate(a_uint32_t dev_id, a_uint32_t uniphy_index) +{ + a_uint32_t reg_value = 0; + a_uint32_t retries = 100, calibration_done = 0; + union uniphy_offset_calib_4_u uniphy_offset_calib_4; + + memset(&uniphy_offset_calib_4, 0, sizeof(uniphy_offset_calib_4)); + ADPT_DEV_ID_CHECK(dev_id); + + if(ssdk_is_emulation(dev_id)){ + SSDK_INFO("uniphy_index %d on emulation platform\n", uniphy_index); + return SW_OK; + } + /*wait calibration done to uniphy*/ + while (calibration_done != UNIPHY_CALIBRATION_DONE) { + mdelay(1); + if (retries-- == 0) + { + SSDK_ERROR("uniphy callibration time out!\n"); + return SW_TIMEOUT; + } + reg_value = 0; + hppe_uniphy_offset_calib_4_get(dev_id, uniphy_index, &uniphy_offset_calib_4); + reg_value = uniphy_offset_calib_4.bf.mmd1_reg_calibration_done_reg; + + calibration_done = (reg_value & UNIPHY_CALIBRATION_DONE); + } + + return SW_OK; +} + +sw_error_t +adpt_mp_uniphy_adapter_port_reset(a_uint32_t dev_id, + a_uint32_t port_id) +{ + sw_error_t rv = SW_OK; + a_uint32_t uniphy_index = 0; + union uniphy_channel0_input_output_4_u uniphy_channel0_input_output_4; + + memset(&uniphy_channel0_input_output_4, 0, sizeof(uniphy_channel0_input_output_4)); + + if (port_id == SSDK_PHYSICAL_PORT2) { + uniphy_index = SSDK_UNIPHY_INSTANCE0; + } else { + SSDK_ERROR("uniphy adapter reset port_id is %d\n", port_id); + return SW_BAD_VALUE; + } + + rv = hppe_uniphy_channel0_input_output_4_get(dev_id, uniphy_index, + &uniphy_channel0_input_output_4); + SW_RTN_ON_ERROR (rv); + uniphy_channel0_input_output_4.bf.newaddedfromhere_ch0_adp_sw_rstn = 0; + rv = hppe_uniphy_channel0_input_output_4_set(dev_id, uniphy_index, + &uniphy_channel0_input_output_4); + SW_RTN_ON_ERROR (rv); + uniphy_channel0_input_output_4.bf.newaddedfromhere_ch0_adp_sw_rstn = 1; + rv = hppe_uniphy_channel0_input_output_4_set(dev_id, uniphy_index, + &uniphy_channel0_input_output_4); + SW_RTN_ON_ERROR (rv); + + return rv; +} + +sw_error_t +adpt_mp_gcc_uniphy_port_clock_set(a_uint32_t dev_id, a_uint32_t port_id, + a_bool_t enable) +{ + sw_error_t rv = SW_OK; + + if (port_id == SSDK_PHYSICAL_PORT1) { + qca_gcc_uniphy_port_clock_set(dev_id, SSDK_UNIPHY_INSTANCE0, + port_id, enable); + } else if (port_id == SSDK_PHYSICAL_PORT2) { + qca_gcc_uniphy_port_clock_set(dev_id, SSDK_UNIPHY_INSTANCE1, + port_id, enable); + } else { + return SW_BAD_VALUE; + } + + return rv; +} + +void +adpt_mp_gcc_uniphy_port_set(a_uint32_t dev_id, a_uint32_t port_id, + a_bool_t enable) +{ + enum unphy_rst_type rst_type; + + if (port_id == SSDK_PHYSICAL_PORT2) { + rst_type = UNIPHY1_SOFT_RESET_E; + } else { + return; + } + + if (enable == A_TRUE) { + ssdk_uniphy_reset(dev_id, rst_type, SSDK_RESET_DEASSERT); + } else { + ssdk_uniphy_reset(dev_id, rst_type, SSDK_RESET_ASSERT); + } + + return; +} + +void +adpt_mp_gcc_uniphy_port_reset(a_uint32_t dev_id, a_uint32_t port_id) +{ + adpt_mp_gcc_uniphy_port_set(dev_id, port_id, A_FALSE); + + msleep(100); + + adpt_mp_gcc_uniphy_port_set(dev_id, port_id, A_TRUE); + + return; +} + +static sw_error_t +adpt_mp_uniphy_reset(a_uint32_t dev_id, a_uint32_t uniphy_index) +{ + sw_error_t rv = SW_OK; + union pll_power_on_and_reset_u pll_software_reset; + + memset(&pll_software_reset, 0, sizeof(pll_software_reset)); + ADPT_DEV_ID_CHECK(dev_id); + + rv = hppe_uniphy_pll_reset_ctrl_get(dev_id, uniphy_index, + &pll_software_reset); + SW_RTN_ON_ERROR (rv); + pll_software_reset.bf.software_reset_analog_reset = 0; + rv = hppe_uniphy_pll_reset_ctrl_set(dev_id, uniphy_index, + &pll_software_reset); + SW_RTN_ON_ERROR (rv); + msleep(500); + pll_software_reset.bf.software_reset_analog_reset = 1; + rv = hppe_uniphy_pll_reset_ctrl_set(dev_id, uniphy_index, + &pll_software_reset); + SW_RTN_ON_ERROR (rv); + msleep(500); + + return SW_OK; +} + +static sw_error_t +adpt_mp_uniphy_mode_ctrl_set(a_uint32_t dev_id, + a_uint32_t uniphy_index, a_uint32_t mode) +{ + sw_error_t rv = SW_OK; + union uniphy_mode_ctrl_u uniphy_mode_ctrl; + union uniphy_channel0_input_output_4_u uniphy_force_ctrl; + a_bool_t force_port = 0; + + memset(&uniphy_mode_ctrl, 0, sizeof(uniphy_mode_ctrl)); + memset(&uniphy_force_ctrl, 0, sizeof(uniphy_force_ctrl)); + + force_port = ssdk_port_feature_get(dev_id, SSDK_PHYSICAL_PORT2, + PHY_F_FORCE); + /* configure uniphy mode ctrl to sgmii/sgmiiplus */ + rv = hppe_uniphy_mode_ctrl_get(dev_id, uniphy_index, &uniphy_mode_ctrl); + SW_RTN_ON_ERROR (rv); + if (mode == PORT_WRAPPER_SGMII_CHANNEL0) { + uniphy_mode_ctrl.bf.newaddedfromhere_sg_mode = + UNIPHY_SGMII_MODE_ENABLE; + uniphy_mode_ctrl.bf.newaddedfromhere_sgplus_mode = + UNIPHY_SGMIIPLUS_MODE_DISABLE; + if (force_port == A_TRUE) { + rv = hppe_uniphy_channel0_input_output_4_get(dev_id, + uniphy_index, &uniphy_force_ctrl); + SW_RTN_ON_ERROR (rv); + uniphy_force_ctrl.bf.newaddedfromhere_ch0_force_speed_25m = + UNIPHY_FORCE_SPEED_ENABLE; + rv = hppe_uniphy_channel0_input_output_4_set(dev_id, + uniphy_index, &uniphy_force_ctrl); + SW_RTN_ON_ERROR (rv); + } + } else { + uniphy_mode_ctrl.bf.newaddedfromhere_sg_mode = + UNIPHY_SGMII_MODE_DISABLE; + uniphy_mode_ctrl.bf.newaddedfromhere_sgplus_mode = + UNIPHY_SGMIIPLUS_MODE_ENABLE; + } + uniphy_mode_ctrl.bf.newaddedfromhere_ch0_autoneg_mode = + UNIPHY_ATHEROS_NEGOTIATION; + uniphy_mode_ctrl.bf.newaddedfromhere_ch0_psgmii_qsgmii = + UNIPHY_CH0_QSGMII_SGMII_MODE; + uniphy_mode_ctrl.bf.newaddedfromhere_ch0_qsgmii_sgmii = + UNIPHY_CH0_SGMII_MODE; + uniphy_mode_ctrl.bf.newaddedfromhere_xpcs_mode = + UNIPHY_XPCS_MODE_DISABLE; + rv = hppe_uniphy_mode_ctrl_set(dev_id, uniphy_index, &uniphy_mode_ctrl); + + return rv; +} + +static sw_error_t +_adpt_mp_uniphy_clk_output_ctrl_set(a_uint32_t dev_id, a_uint32_t index, + a_uint32_t clk_rate) +{ + sw_error_t rv = SW_OK; + union uniphy_clock_output_control_u clock_output; + + memset(&clock_output, 0, sizeof(union uniphy_clock_output_control_u)); + clock_output.bf.ref_clk_output_drv = UNIPHY_CLK_DRV_1; + clock_output.bf.ref_clk_output_en = A_TRUE; + SSDK_INFO("uniphy will output clock as %dHz\n", clk_rate); + if(clk_rate == UNIPHY_CLK_RATE_25M) + { + clock_output.bf.ref_clk_output_div = UNIPHY_CLK_DIV_25M; + } + else if(clk_rate == UNIPHY_CLK_RATE_50M) + { + clock_output.bf.ref_clk_output_div = UNIPHY_CLK_DIV_50M; + } + else + { + return SW_NOT_SUPPORTED; + } + rv = mp_uniphy_clock_output_control_set(dev_id, index, + &clock_output); + + return rv; +} + +static void +_adpt_mp_uniphy_clk_output_set(a_uint32_t dev_id, a_uint32_t index) +{ + a_uint32_t phy_id =0; + a_bool_t force_port = A_FALSE; + a_uint32_t force_speed = 0; + + /*when MP connect s17c or qca803x, need to reconfigure reference clock + as 25M for port 2*/ + force_port = ssdk_port_feature_get(dev_id, SSDK_PHYSICAL_PORT2, PHY_F_FORCE); + force_speed = ssdk_port_force_speed_get(dev_id, SSDK_PHYSICAL_PORT2); + + if ((force_port) && (force_speed == FAL_SPEED_1000)) + { + _adpt_mp_uniphy_clk_output_ctrl_set(dev_id, index, UNIPHY_CLK_RATE_25M); + } + phy_id = hsl_port_phyid_get(dev_id, SSDK_PHYSICAL_PORT2); + if (phy_id == QCA8030_PHY || phy_id == QCA8033_PHY || phy_id == QCA8035_PHY) + { + _adpt_mp_uniphy_clk_output_ctrl_set(dev_id, index, UNIPHY_CLK_RATE_25M); + } + + return; +} + +sw_error_t +adpt_mp_uniphy_mode_configure(a_uint32_t dev_id, a_uint32_t index, a_uint32_t mode) +{ + sw_error_t rv = SW_OK; + a_uint32_t clock = UNIPHY_CLK_RATE_125M; + + union uniphy_misc2_phy_mode_u uniphy_misc2_phy_mode; + + memset(&uniphy_misc2_phy_mode, 0, sizeof(uniphy_misc2_phy_mode)); + + ADPT_DEV_ID_CHECK(dev_id); + + if (index != SSDK_UNIPHY_INSTANCE0) { + SSDK_ERROR("uniphy index is %d\n", index); + return SW_BAD_VALUE; + } + + if (mode == PORT_WRAPPER_MAX) { + adpt_mp_gcc_uniphy_port_set(dev_id, SSDK_PHYSICAL_PORT2, + A_FALSE); + return SW_OK; + } else if ((mode == PORT_WRAPPER_SGMII_CHANNEL0) || + (mode == PORT_WRAPPER_SGMII_PLUS)) { + adpt_mp_gcc_uniphy_port_set(dev_id, SSDK_PHYSICAL_PORT2, + A_TRUE); + } else { + return SW_NOT_SUPPORTED; + } + + /*set the PHY mode to SGMII or SGMIIPLUS*/ + rv = hppe_uniphy_phy_mode_ctrl_get(dev_id, index, + &uniphy_misc2_phy_mode); + SW_RTN_ON_ERROR (rv); + if (mode == PORT_WRAPPER_SGMII_CHANNEL0) { + uniphy_misc2_phy_mode.bf.phy_mode = + UNIPHY_PHY_SGMII_MODE; + clock = UNIPHY_CLK_RATE_125M; + } else { + uniphy_misc2_phy_mode.bf.phy_mode = + UNIPHY_PHY_SGMIIPLUS_MODE; + clock = UNIPHY_CLK_RATE_312M; + } + rv = hppe_uniphy_phy_mode_ctrl_set(dev_id, index, + &uniphy_misc2_phy_mode); + SW_RTN_ON_ERROR (rv); + + /* reset uniphy */ + rv = adpt_mp_uniphy_reset(dev_id, index); + SW_RTN_ON_ERROR (rv); + + /* disable uniphy port clock */ + rv = adpt_mp_gcc_uniphy_port_clock_set(dev_id, SSDK_PHYSICAL_PORT2, + A_FALSE); + SW_RTN_ON_ERROR (rv); + + rv = adpt_mp_uniphy_mode_ctrl_set(dev_id, index, mode); + SW_RTN_ON_ERROR (rv); + + adpt_mp_gcc_uniphy_port_reset(dev_id, SSDK_PHYSICAL_PORT2); + + /* wait uniphy calibration done */ + rv = _adpt_mp_uniphy_calibrate(dev_id, index); + SW_RTN_ON_ERROR (rv); + + /* enable instance clock */ + rv = adpt_mp_gcc_uniphy_port_clock_set(dev_id, SSDK_PHYSICAL_PORT2, + A_TRUE); + SW_RTN_ON_ERROR (rv); + + if (SW_OK == rv) { + /* index + 1 point to mp uniphy clock */ + ssdk_mp_raw_clock_set(index + 1, UNIPHY_RX, clock); + ssdk_mp_raw_clock_set(index + 1, UNIPHY_TX, clock); + } + + if (mode == PORT_WRAPPER_SGMII_CHANNEL0) { + SSDK_DEBUG("mp uniphy %d sgmii configuration is done!\n", index); + } else { + SSDK_DEBUG("mp uniphy %d sgmiiplus configuration is done!\n", index); + } + + return rv; +} + +sw_error_t +adpt_mp_uniphy_mode_set(a_uint32_t dev_id, a_uint32_t index, a_uint32_t mode) +{ + sw_error_t rv = SW_OK; + + rv = adpt_mp_uniphy_mode_configure(dev_id, index, mode); + SW_RTN_ON_ERROR(rv); + _adpt_mp_uniphy_clk_output_set(dev_id, index); + + /*port2 is connected with PHY, need gpio reset*/ + if(!ssdk_port_feature_get(dev_id, SSDK_PHYSICAL_PORT2, PHY_F_FORCE)) + { + hsl_port_phy_gpio_reset(dev_id, SSDK_PHYSICAL_PORT2); + msleep(100); + hsl_port_phy_hw_init(dev_id, SSDK_PHYSICAL_PORT2); + } + + return rv; +} + +sw_error_t adpt_mp_uniphy_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + ADPT_DEV_ID_CHECK(dev_id); + SW_RTN_ON_NULL(p_adpt_api = adpt_api_ptr_get(dev_id)); + + p_adpt_api->adpt_uniphy_mode_set = adpt_mp_uniphy_mode_set; + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/adpt/sfp/Makefile b/feeds/ipq807x/qca-ssdk/src/src/adpt/sfp/Makefile new file mode 100755 index 000000000..fdf2ab6b2 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/sfp/Makefile @@ -0,0 +1,16 @@ +LOC_DIR=src/adpt/sfp +LIB=ADPT + +include $(PRJ_PATH)/make/config.mk + +SRC_LIST= + +ifeq (TRUE, $(IN_SFP)) + SRC_LIST += adpt_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/src/src/adpt/sfp/adpt_sfp.c b/feeds/ipq807x/qca-ssdk/src/src/adpt/sfp/adpt_sfp.c new file mode 100755 index 000000000..f55512790 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/adpt/sfp/adpt_sfp.c @@ -0,0 +1,668 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "adpt.h" +#include "sfp_reg.h" +#include "sfp.h" +#include "hsl_phy.h" + + +#define ADPT_RTN_ON_INVALID_DATA_OFFSET(offset) \ + do { if (offset > 0xff) return(SW_BAD_PARAM); } while(0); + +#define ADPT_PORT_I2C_CAP_CHECK(dev_id, port_id) \ + do { if (PHY_I2C_ACCESS != hsl_port_phy_access_type_get(dev_id, port_id)) \ + return(SW_NOT_SUPPORTED); } while(0); + +sw_error_t +adpt_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 = SW_OK; + union sfp_diag_optional_ctrl_status_u sfp_diag_optional_ctrl_status; + union sfp_diag_extended_ctrl_status_u sfp_diag_extended_ctrl_status; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_PORT_I2C_CAP_CHECK(dev_id, port_id); + ADPT_NULL_POINT_CHECK(ctrl_status); + + memset(&sfp_diag_optional_ctrl_status, 0, sizeof(sfp_diag_optional_ctrl_status)); + memset(&sfp_diag_extended_ctrl_status, 0, sizeof(sfp_diag_extended_ctrl_status)); + + rv = sfp_diag_optional_ctrl_status_get(dev_id, + port_id, &sfp_diag_optional_ctrl_status); + SW_RTN_ON_ERROR(rv); + + rv = sfp_diag_extended_ctrl_status_get(dev_id, + port_id, &sfp_diag_extended_ctrl_status); + SW_RTN_ON_ERROR(rv); + + ctrl_status->data_ready = sfp_diag_optional_ctrl_status.bf.data_ready; + ctrl_status->rx_los = sfp_diag_optional_ctrl_status.bf.rx_los; + ctrl_status->tx_fault = sfp_diag_optional_ctrl_status.bf.tx_fault; + ctrl_status->soft_rate_sel = sfp_diag_optional_ctrl_status.bf.soft_rate_sel; + ctrl_status->rate_sel = sfp_diag_optional_ctrl_status.bf.rate_sel; + ctrl_status->rs_state = sfp_diag_optional_ctrl_status.bf.rs; + ctrl_status->soft_tx_disable = sfp_diag_optional_ctrl_status.bf.soft_tx_disable_sel; + ctrl_status->tx_disable = sfp_diag_optional_ctrl_status.bf.tx_disable; + + ctrl_status->pwr_level_sel = sfp_diag_extended_ctrl_status.bf.pwr_level_sel; + ctrl_status->pwr_level_op_state = sfp_diag_extended_ctrl_status.bf.pwr_level_op_state; + ctrl_status->soft_rs_sel = sfp_diag_extended_ctrl_status.bf.soft_rs_sel; + + return SW_OK; +} + +sw_error_t +adpt_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 = SW_OK; + union sfp_diag_cal_const_u sfp_diag_cal_const; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_PORT_I2C_CAP_CHECK(dev_id, port_id); + ADPT_NULL_POINT_CHECK(cal_const); + + memset(&sfp_diag_cal_const, 0, sizeof(sfp_diag_cal_const)); + + rv = sfp_diag_cal_const_get(dev_id, port_id, &sfp_diag_cal_const); + SW_RTN_ON_ERROR(rv); + + cal_const->rx_power4 = sfp_diag_cal_const.bf.rx_pwr_4_0 << 24 + | sfp_diag_cal_const.bf.rx_pwr_4_1 << 16 + | sfp_diag_cal_const.bf.rx_pwr_4_2 << 8 + | sfp_diag_cal_const.bf.rx_pwr_4_3; + cal_const->rx_power3 = sfp_diag_cal_const.bf.rx_pwr_3_0 << 24 + | sfp_diag_cal_const.bf.rx_pwr_3_1 << 16 + | sfp_diag_cal_const.bf.rx_pwr_3_2 << 8 + | sfp_diag_cal_const.bf.rx_pwr_3_3; + cal_const->rx_power2 = sfp_diag_cal_const.bf.rx_pwr_2_0 << 24 + | sfp_diag_cal_const.bf.rx_pwr_2_1 << 16 + | sfp_diag_cal_const.bf.rx_pwr_2_2 << 8 + | sfp_diag_cal_const.bf.rx_pwr_2_3; + cal_const->rx_power1 = sfp_diag_cal_const.bf.rx_pwr_1_0 << 24 + | sfp_diag_cal_const.bf.rx_pwr_1_1 << 16 + | sfp_diag_cal_const.bf.rx_pwr_1_2 << 8 + | sfp_diag_cal_const.bf.rx_pwr_1_3; + cal_const->rx_power0 = sfp_diag_cal_const.bf.rx_pwr_0_0 << 24 + | sfp_diag_cal_const.bf.rx_pwr_0_1 << 16 + | sfp_diag_cal_const.bf.rx_pwr_0_2 << 8 + | sfp_diag_cal_const.bf.rx_pwr_0_3; + + cal_const->tx_bias_slope = sfp_diag_cal_const.bf.tx_i_slope_0 << 8 + | sfp_diag_cal_const.bf.tx_i_slope_1; + cal_const->tx_bias_offset = sfp_diag_cal_const.bf.tx_i_offset_0 << 8 + | sfp_diag_cal_const.bf.tx_i_offset_1; + + cal_const->tx_power_slope = sfp_diag_cal_const.bf.tx_pwr_slope_0 << 8 + | sfp_diag_cal_const.bf.tx_pwr_slope_1; + cal_const->tx_power_offset = sfp_diag_cal_const.bf.tx_pwr_offset_0 << 8 + | sfp_diag_cal_const.bf.tx_pwr_offset_1; + + cal_const->temp_slope = sfp_diag_cal_const.bf.t_slope_0 << 8 + | sfp_diag_cal_const.bf.t_slope_1; + cal_const->temp_offset = sfp_diag_cal_const.bf.t_offset_0 << 8 + | sfp_diag_cal_const.bf.t_offset_1; + + cal_const->vol_slope = sfp_diag_cal_const.bf.v_slope_0 << 8 + | sfp_diag_cal_const.bf.v_slope_1; + cal_const->vol_offset = sfp_diag_cal_const.bf.v_offset_0 << 8 + | sfp_diag_cal_const.bf.v_offset_1; + + return SW_OK; +} + +sw_error_t +adpt_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 = SW_OK; + union sfp_link_len_u sfp_link_len; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_PORT_I2C_CAP_CHECK(dev_id, port_id); + ADPT_NULL_POINT_CHECK(link_len); + + memset(&sfp_link_len, 0, sizeof(sfp_link_len)); + + rv = sfp_link_len_get(dev_id, port_id, &sfp_link_len); + SW_RTN_ON_ERROR(rv); + + link_len->single_mode_length_km = sfp_link_len.bf.single_mode_km; + link_len->single_mode_length_100m = sfp_link_len.bf.single_mode_100m; + link_len->om2_mode_length_10m = sfp_link_len.bf.om2_mode_10m; + link_len->om1_mode_length_10m = sfp_link_len.bf.om1_mode_10m; + link_len->copper_mode_length_1m = sfp_link_len.bf.copper_mode_1m; + link_len->om3_mode_length_1m = sfp_link_len.bf.om3_mode_1m; + + return SW_OK; +} + +sw_error_t +adpt_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 = SW_OK; + union sfp_diag_threshold_u sfp_diag_threshold; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_PORT_I2C_CAP_CHECK(dev_id, port_id); + ADPT_NULL_POINT_CHECK(threshold); + + memset(&sfp_diag_threshold, 0, sizeof(sfp_diag_threshold)); + + rv = sfp_diag_threshold_get(dev_id, port_id, &sfp_diag_threshold); + SW_RTN_ON_ERROR(rv); + + threshold->temp_high_alarm = sfp_diag_threshold.bf.temp_high_alarm_0 << 8 + | sfp_diag_threshold.bf.temp_high_alarm_1; + threshold->temp_low_alarm = sfp_diag_threshold.bf.temp_low_alarm_0 << 8 + | sfp_diag_threshold.bf.temp_low_alarm_1; + threshold->temp_high_warning = sfp_diag_threshold.bf.temp_high_warning_0 << 8 + | sfp_diag_threshold.bf.temp_high_warning_1; + threshold->temp_low_warning = sfp_diag_threshold.bf.temp_low_warning_0 << 8 + | sfp_diag_threshold.bf.temp_low_warning_1; + threshold->vol_high_alarm = sfp_diag_threshold.bf.vol_high_alarm_0 << 8 + | sfp_diag_threshold.bf.vol_high_alarm_1; + threshold->vol_low_alarm = sfp_diag_threshold.bf.vol_low_alarm_0 << 8 + | sfp_diag_threshold.bf.vol_low_alarm_1; + threshold->vol_high_warning = sfp_diag_threshold.bf.vol_high_warning_0 << 8 + | sfp_diag_threshold.bf.vol_high_warning_1; + threshold->vol_low_warning = sfp_diag_threshold.bf.vol_low_warning_0 << 8 + | sfp_diag_threshold.bf.vol_low_warning_1; + threshold->bias_high_alarm = sfp_diag_threshold.bf.bias_high_alarm_0 << 8 + | sfp_diag_threshold.bf.bias_high_alarm_1; + threshold->bias_low_alarm = sfp_diag_threshold.bf.bias_low_alarm_0 << 8 + | sfp_diag_threshold.bf.bias_low_alarm_1; + threshold->bias_high_warning = sfp_diag_threshold.bf.bias_high_warning_0 << 8 + | sfp_diag_threshold.bf.bias_high_warning_1; + threshold->bias_low_warning = sfp_diag_threshold.bf.bias_low_warning_0 << 8 + | sfp_diag_threshold.bf.bias_low_warning_1; + threshold->tx_power_high_alarm = sfp_diag_threshold.bf.tx_pwr_high_alarm_0 << 8 + | sfp_diag_threshold.bf.tx_pwr_high_alarm_1; + threshold->tx_power_low_alarm = sfp_diag_threshold.bf.tx_pwr_low_alarm_0 << 8 + | sfp_diag_threshold.bf.tx_pwr_low_alarm_1; + threshold->tx_power_high_warning = sfp_diag_threshold.bf.tx_pwr_high_warning_0 << 8 + | sfp_diag_threshold.bf.tx_pwr_high_warning_1; + threshold->tx_power_low_warning = sfp_diag_threshold.bf.tx_pwr_low_warning_0 << 8 + | sfp_diag_threshold.bf.tx_pwr_low_warning_1; + threshold->rx_power_high_alarm = sfp_diag_threshold.bf.rx_pwr_high_alarm_0 << 8 + | sfp_diag_threshold.bf.rx_pwr_high_alarm_1; + threshold->rx_power_low_alarm = sfp_diag_threshold.bf.rx_pwr_low_alarm_0 << 8 + | sfp_diag_threshold.bf.rx_pwr_low_alarm_1; + threshold->rx_power_high_warning = sfp_diag_threshold.bf.rx_pwr_high_warning_0 << 8 + | sfp_diag_threshold.bf.rx_pwr_high_warning_1; + threshold->rx_power_low_warning = sfp_diag_threshold.bf.rx_pwr_low_warning_0 << 8 + | sfp_diag_threshold.bf.rx_pwr_low_warning_1; + + return SW_OK; +} + +sw_error_t +adpt_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 = SW_OK; + union sfp_diag_realtime_u sfp_diag_realtime; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_PORT_I2C_CAP_CHECK(dev_id, port_id); + ADPT_NULL_POINT_CHECK(real_diag); + + memset(&sfp_diag_realtime, 0, sizeof(sfp_diag_realtime)); + + rv = sfp_diag_realtime_get(dev_id, port_id, &sfp_diag_realtime); + SW_RTN_ON_ERROR(rv); + + real_diag->cur_temp = sfp_diag_realtime.bf.tmp_0 << 8 + | sfp_diag_realtime.bf.tmp_1; + real_diag->cur_vol = sfp_diag_realtime.bf.vcc_0 << 8 + | sfp_diag_realtime.bf.vcc_1; + real_diag->tx_cur_bias = sfp_diag_realtime.bf.tx_bias_0 << 8 + | sfp_diag_realtime.bf.tx_bias_1; + real_diag->tx_cur_power = sfp_diag_realtime.bf.tx_pwr_0 << 8 + | sfp_diag_realtime.bf.tx_pwr_1; + real_diag->rx_cur_power = sfp_diag_realtime.bf.rx_pwr_0 << 8 + | sfp_diag_realtime.bf.rx_pwr_1; + + return SW_OK; +} + +sw_error_t +adpt_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 = SW_OK; + union sfp_laser_u sfp_laser; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_PORT_I2C_CAP_CHECK(dev_id, port_id); + ADPT_NULL_POINT_CHECK(laser_wavelen); + + memset(&sfp_laser, 0, sizeof(sfp_laser)); + + rv = sfp_laser_get(dev_id, port_id, &sfp_laser); + SW_RTN_ON_ERROR(rv); + + laser_wavelen->laser_wavelength = sfp_laser.bf.wavelength_0 << 8 + | sfp_laser.bf.wavelength_1; + + return SW_OK; +} + +sw_error_t +adpt_sfp_option_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_sfp_option_t *option) +{ + sw_error_t rv = SW_OK; + union sfp_option_u sfp_option; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_PORT_I2C_CAP_CHECK(dev_id, port_id); + ADPT_NULL_POINT_CHECK(option); + + memset(&sfp_option, 0, sizeof(sfp_option)); + + rv = sfp_option_get(dev_id, port_id, &sfp_option); + SW_RTN_ON_ERROR(rv); + + option->linear_recv_output = sfp_option.bf.linear_recv_output; + option->pwr_level_declar = sfp_option.bf.pwr_level_declar; + option->cool_transc_declar = sfp_option.bf.cool_transc_declar; + option->loss_signal = sfp_option.bf.loss_signal; + option->loss_invert_signal = sfp_option.bf.loss_invert_signal; + option->tx_fault_signal = sfp_option.bf.tx_fault_signal; + option->tx_disable = sfp_option.bf.tx_disable; + option->rate_sel = sfp_option.bf.rate_sel; + + return SW_OK; +} + +sw_error_t +adpt_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 = SW_OK; + union sfp_base_u sfp_base; + union sfp_ext_u sfp_ext; + union sfp_diag_dmi_u sfp_dmi; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_PORT_I2C_CAP_CHECK(dev_id, port_id); + ADPT_NULL_POINT_CHECK(ccode); + + memset(&sfp_base, 0, sizeof(sfp_base)); + memset(&sfp_ext, 0, sizeof(sfp_ext)); + memset(&sfp_dmi, 0, sizeof(sfp_dmi)); + + switch (cc_type) { + case FAL_SFP_CC_BASE: + rv = sfp_base_get(dev_id, port_id, &sfp_base); + SW_RTN_ON_ERROR(rv); + *ccode = sfp_base.bf.check_code; + break; + case FAL_SFP_CC_EXT: + rv = sfp_ext_get(dev_id, port_id, &sfp_ext); + SW_RTN_ON_ERROR(rv); + *ccode = sfp_ext.bf.check_code; + break; + case FAL_SFP_CC_DMI: + rv = sfp_diag_dmi_get(dev_id, + port_id, &sfp_dmi); + SW_RTN_ON_ERROR(rv); + *ccode = sfp_dmi.bf.check_code; + break; + default: + return SW_BAD_PARAM; + } + + return SW_OK; +} + +sw_error_t +adpt_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 = SW_OK; + union sfp_diag_flag_u sfp_diag_flag; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_PORT_I2C_CAP_CHECK(dev_id, port_id); + ADPT_NULL_POINT_CHECK(alarm_warn_flag); + + memset(&sfp_diag_flag, 0, sizeof(sfp_diag_flag)); + + rv = sfp_diag_flag_get(dev_id, port_id, &sfp_diag_flag); + SW_RTN_ON_ERROR(rv); + + alarm_warn_flag->tx_pwr_low_alarm = sfp_diag_flag.bf.tx_pwr_low_alarm; + alarm_warn_flag->tx_pwr_high_alarm = sfp_diag_flag.bf.tx_pwr_high_alarm; + alarm_warn_flag->tx_bias_low_alarm = sfp_diag_flag.bf.tx_bias_low_alarm; + alarm_warn_flag->tx_bias_high_alarm = sfp_diag_flag.bf.tx_bias_high_alarm; + alarm_warn_flag->vcc_low_alarm = sfp_diag_flag.bf.vcc_low_alarm; + alarm_warn_flag->vcc_high_alarm = sfp_diag_flag.bf.vcc_high_alarm; + alarm_warn_flag->tmp_low_alarm = sfp_diag_flag.bf.tmp_low_alarm; + alarm_warn_flag->tmp_high_alarm = sfp_diag_flag.bf.tmp_high_alarm; + alarm_warn_flag->rx_pwr_low_alarm = sfp_diag_flag.bf.rx_pwr_low_alarm; + alarm_warn_flag->rx_pwr_high_alarm = sfp_diag_flag.bf.rx_pwr_high_alarm; + + alarm_warn_flag->tx_pwr_low_warning = sfp_diag_flag.bf.tx_pwr_low_warning; + alarm_warn_flag->tx_pwr_high_warning = sfp_diag_flag.bf.tx_pwr_high_warning; + alarm_warn_flag->tx_bias_low_warning = sfp_diag_flag.bf.tx_bias_low_warning; + alarm_warn_flag->tx_bias_high_warning = sfp_diag_flag.bf.tx_bias_high_warning; + alarm_warn_flag->vcc_low_warning = sfp_diag_flag.bf.vcc_low_warning; + alarm_warn_flag->vcc_high_warning = sfp_diag_flag.bf.vcc_high_warning; + alarm_warn_flag->tmp_low_warning = sfp_diag_flag.bf.tmp_low_warning; + alarm_warn_flag->tmp_high_warning = sfp_diag_flag.bf.tmp_high_warning; + alarm_warn_flag->rx_pwr_low_warning = sfp_diag_flag.bf.rx_pwr_low_warning; + alarm_warn_flag->rx_pwr_high_warning = sfp_diag_flag.bf.rx_pwr_high_warning; + + return SW_OK; +} + +sw_error_t +adpt_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 = SW_OK; + union sfp_dev_type_u sfp_dev_type; + union sfp_dev_type_ext_u sfp_dev_type_ext; + union sfp_dev_connector_type_u sfp_dev_connector_type; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_PORT_I2C_CAP_CHECK(dev_id, port_id); + ADPT_NULL_POINT_CHECK(sfp_id); + + memset(&sfp_dev_type, 0, sizeof(sfp_dev_type)); + memset(&sfp_dev_type_ext, 0, sizeof(sfp_dev_type_ext)); + memset(&sfp_dev_connector_type, 0, sizeof(sfp_dev_connector_type)); + + rv = sfp_dev_type_get(dev_id, port_id, &sfp_dev_type); + SW_RTN_ON_ERROR(rv); + + rv = sfp_dev_type_ext_get(dev_id, port_id, &sfp_dev_type_ext); + SW_RTN_ON_ERROR(rv); + + rv = sfp_dev_connector_type_get(dev_id, port_id, &sfp_dev_connector_type); + SW_RTN_ON_ERROR(rv); + + sfp_id->identifier = sfp_dev_type.bf.id; + sfp_id->ext_indentifier = sfp_dev_type_ext.bf.id; + sfp_id->connector_type = sfp_dev_connector_type.bf.code; + + return SW_OK; +} + +sw_error_t +adpt_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 = SW_OK; + a_uint32_t index, i; + union sfp_vendor_u sfp_vendor; + union sfp_vendor_ext_u sfp_vendor_ext; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_PORT_I2C_CAP_CHECK(dev_id, port_id); + ADPT_NULL_POINT_CHECK(vender_info); + + memset(&sfp_vendor, 0, sizeof(sfp_vendor)); + memset(&sfp_vendor_ext, 0, sizeof(sfp_vendor_ext)); + + rv = sfp_vendor_get(dev_id, port_id, &sfp_vendor); + SW_RTN_ON_ERROR(rv); + + rv = sfp_vendor_ext_get(dev_id, port_id, &sfp_vendor_ext); + SW_RTN_ON_ERROR(rv); + + /* vendor basic info */ + for (index = 0, i = 0; i < sizeof(vender_info->vendor_name); index++) { + vender_info->vendor_name[i++] = *(sfp_vendor.val + index); + } + + /* skip Transceiver Code for electronic or optical compatibility */ + index++; + + for (i = 0; i < sizeof(vender_info->vendor_oui); index++) { + vender_info->vendor_oui[i++] = *(sfp_vendor.val + index); + } + + for (i = 0; i < sizeof(vender_info->vendor_pn); index++) { + vender_info->vendor_pn[i++] = *(sfp_vendor.val + index); + } + + for (i = 0; i < sizeof(vender_info->vendor_rev); index++) { + vender_info->vendor_rev[i++] = *(sfp_vendor.val + index); + } + + /* vendor extended info */ + for (index = 0, i = 0; i < sizeof(vender_info->vendor_sn); index++) { + vender_info->vendor_sn[i++] = *(sfp_vendor_ext.val + index); + } + + for (i = 0; i < sizeof(vender_info->vendor_date_code); index++) { + vender_info->vendor_date_code[i++] = *(sfp_vendor_ext.val + index); + } + + return SW_OK; +} + +sw_error_t +adpt_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 = SW_OK; + union sfp_transc_u sfp_transc; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_PORT_I2C_CAP_CHECK(dev_id, port_id); + ADPT_NULL_POINT_CHECK(transc_code); + + memset(&sfp_transc, 0, sizeof(sfp_transc)); + + rv = sfp_transc_get(dev_id, port_id, &sfp_transc); + SW_RTN_ON_ERROR(rv); + + transc_code->eth_10g_ccode = sfp_transc.bf.eth_10g_ccode; + transc_code->infiniband_ccode = sfp_transc.bf.infiniband_ccode; + transc_code->escon_ccode = sfp_transc.bf.escon_ccode; + transc_code->sonet_ccode = sfp_transc.bf.sonet_ccode_1 << 8 + | sfp_transc.bf.sonet_ccode_2; + transc_code->eth_ccode = sfp_transc.bf.eth_ccode; + transc_code->fibre_chan_link_length = sfp_transc.bf.fiber_ch_link_len; + transc_code->fibre_chan_tech = sfp_transc.bf.fiber_ch_tech_1 << 4 + | sfp_transc.bf.fiber_ch_tech_2; + transc_code->sfp_cable_tech = sfp_transc.bf.cable_tech; + transc_code->fibre_chan_trans_md = sfp_transc.bf.fiber_chan_tm_media; + transc_code->fibre_chan_speed = sfp_transc.bf.fiber_ch_speed; + + return SW_OK; +} + +sw_error_t +adpt_sfp_ctrl_rate_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_sfp_rate_t *rate_limit) +{ + sw_error_t rv = SW_OK; + union sfp_rate_ctrl_u sfp_rate_ctrl; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_PORT_I2C_CAP_CHECK(dev_id, port_id); + ADPT_NULL_POINT_CHECK(rate_limit); + + memset(&sfp_rate_ctrl, 0, sizeof(sfp_rate_ctrl)); + + rv = sfp_rate_ctrl_get(dev_id, port_id, &sfp_rate_ctrl); + SW_RTN_ON_ERROR(rv); + + rate_limit->upper_rate_limit = sfp_rate_ctrl.bf.upper; + rate_limit->lower_rate_limit = sfp_rate_ctrl.bf.lower; + + return SW_OK; +} + +sw_error_t +adpt_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 = SW_OK; + union sfp_enhanced_u sfp_enhanced; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_PORT_I2C_CAP_CHECK(dev_id, port_id); + ADPT_NULL_POINT_CHECK(enhanced_feature); + + memset(&sfp_enhanced, 0, sizeof(sfp_enhanced)); + + rv = sfp_enhanced_get(dev_id, port_id, &sfp_enhanced); + SW_RTN_ON_ERROR(rv); + + enhanced_feature->addr_mode = sfp_enhanced.bf.addr_mode; + enhanced_feature->rec_pwr_type = sfp_enhanced.bf.re_pwr_type; + enhanced_feature->external_cal = sfp_enhanced.bf.external_cal; + enhanced_feature->internal_cal = sfp_enhanced.bf.internal_cal; + enhanced_feature->diag_mon_flag = sfp_enhanced.bf.diag_mon_flag; + enhanced_feature->legacy_type = sfp_enhanced.bf.legacy_type; + + enhanced_feature->soft_rate_sel_op = sfp_enhanced.bf.soft_rate_sel_op; + enhanced_feature->app_sel_op = sfp_enhanced.bf.app_sel_op; + enhanced_feature->soft_rate_ctrl_op = sfp_enhanced.bf.soft_rate_ctrl_op; + enhanced_feature->rx_los_op = sfp_enhanced.bf.rx_los_op; + enhanced_feature->tx_fault_op = sfp_enhanced.bf.tx_fault_op; + enhanced_feature-> tx_disable_ctrl_op = sfp_enhanced.bf.tx_disable_ctrl_op; + enhanced_feature->alarm_warning_flag_op = sfp_enhanced.bf.alarm_warning_flag_op; + + enhanced_feature->compliance_feature = sfp_enhanced.bf.cmpl_feature; + + return SW_OK; +} + +sw_error_t +adpt_sfp_rate_encode_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_sfp_rate_encode_t *encode) +{ + sw_error_t rv = SW_OK; + union sfp_encoding_u sfp_encoding; + union sfp_br_u sfp_br; + union sfp_rate_u sfp_rate; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_PORT_I2C_CAP_CHECK(dev_id, port_id); + ADPT_NULL_POINT_CHECK(encode); + + memset(&sfp_encoding, 0, sizeof(sfp_encoding)); + memset(&sfp_br, 0, sizeof(sfp_br)); + memset(&sfp_rate, 0, sizeof(sfp_rate)); + + rv = sfp_encoding_get(dev_id, port_id, &sfp_encoding); + SW_RTN_ON_ERROR(rv); + + rv = sfp_br_get(dev_id, port_id, &sfp_br); + SW_RTN_ON_ERROR(rv); + + rv = sfp_rate_get(dev_id, port_id, &sfp_rate); + SW_RTN_ON_ERROR(rv); + + encode->encode = sfp_encoding.bf.code; + encode->nominal_bit_rate = sfp_br.bf.bit; + encode->rate_id = sfp_rate.bf.id; + + return SW_OK; +} + +sw_error_t +adpt_sfp_eeprom_data_get(a_uint32_t dev_id, a_uint32_t port_id, fal_sfp_data_t *entry) +{ + sw_error_t rv = SW_OK; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_PORT_I2C_CAP_CHECK(dev_id, port_id); + ADPT_NULL_POINT_CHECK(entry); + + ADPT_RTN_ON_INVALID_DATA_OFFSET(entry->offset + entry->count); + + rv = sfp_eeprom_data_get(dev_id, port_id, entry->addr, + entry->offset, entry->data, entry->count); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +sw_error_t +adpt_sfp_eeprom_data_set(a_uint32_t dev_id, a_uint32_t port_id, fal_sfp_data_t *entry) +{ + sw_error_t rv = SW_OK; + + ADPT_DEV_ID_CHECK(dev_id); + ADPT_PORT_I2C_CAP_CHECK(dev_id, port_id); + ADPT_NULL_POINT_CHECK(entry); + + ADPT_RTN_ON_INVALID_DATA_OFFSET(entry->offset + entry->count); + + rv = sfp_eeprom_data_set(dev_id, port_id, entry->addr, + entry->offset, entry->data, entry->count); + SW_RTN_ON_ERROR(rv); + + /* retrieve the data */ + rv = sfp_eeprom_data_get(dev_id, port_id, entry->addr, + entry->offset, entry->data, entry->count); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +sw_error_t adpt_sfp_init(a_uint32_t dev_id) +{ + adpt_api_t *p_adpt_api = NULL; + + p_adpt_api = adpt_api_ptr_get(dev_id); + + if(p_adpt_api == NULL) + return SW_FAIL; + + p_adpt_api->adpt_sfp_diag_ctrl_status_get = adpt_sfp_diag_ctrl_status_get; + p_adpt_api->adpt_sfp_diag_extenal_calibration_const_get = + adpt_sfp_diag_extenal_calibration_const_get; + p_adpt_api->adpt_sfp_link_length_get = adpt_sfp_link_length_get; + p_adpt_api->adpt_sfp_diag_internal_threshold_get = + adpt_sfp_diag_internal_threshold_get; + p_adpt_api->adpt_sfp_diag_realtime_get = adpt_sfp_diag_realtime_get; + p_adpt_api->adpt_sfp_laser_wavelength_get = adpt_sfp_laser_wavelength_get; + p_adpt_api->adpt_sfp_option_get = adpt_sfp_option_get; + p_adpt_api->adpt_sfp_checkcode_get = adpt_sfp_checkcode_get; + p_adpt_api->adpt_sfp_diag_alarm_warning_flag_get = + adpt_sfp_diag_alarm_warning_flag_get; + p_adpt_api->adpt_sfp_device_type_get = adpt_sfp_device_type_get; + p_adpt_api->adpt_sfp_vendor_info_get = adpt_sfp_vendor_info_get; + p_adpt_api->adpt_sfp_transceiver_code_get = adpt_sfp_transceiver_code_get; + p_adpt_api->adpt_sfp_ctrl_rate_get = adpt_sfp_ctrl_rate_get; + p_adpt_api->adpt_sfp_enhanced_cfg_get = adpt_sfp_enhanced_cfg_get; + p_adpt_api->adpt_sfp_rate_encode_get = adpt_sfp_rate_encode_get; + p_adpt_api->adpt_sfp_eeprom_data_get = adpt_sfp_eeprom_data_get; + p_adpt_api->adpt_sfp_eeprom_data_set = adpt_sfp_eeprom_data_set; + + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/api/Makefile b/feeds/ipq807x/qca-ssdk/src/src/api/Makefile new file mode 100755 index 000000000..25c788a90 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/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/src/src/api/api_access.c b/feeds/ipq807x/qca-ssdk/src/src/api/api_access.c new file mode 100755 index 000000000..3fd2fc2e6 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/api/api_access.c @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2012, 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*/ +#include "sw.h" +#include "fal.h" +#include "hsl.h" +#include "hsl_dev.h" + +#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 +#include "ref_vsi.h" +#include "ref_vlan.h" + +/*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/src/src/fal/Makefile b/feeds/ipq807x/qca-ssdk/src/src/fal/Makefile new file mode 100755 index 000000000..9e711e677 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/Makefile @@ -0,0 +1,140 @@ +LOC_DIR=src/fal +LIB=FAL + +include $(PRJ_PATH)/make/config.mk + +SRC_LIST=fal_init.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_FLOW)) + SRC_LIST += fal_flow.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_VSI)) + SRC_LIST += fal_vsi.c +endif + +ifeq (TRUE, $(IN_INTERFACECONTROL)) + SRC_LIST += fal_interface_ctrl.c +endif + +ifeq (TRUE, $(IN_QM)) + SRC_LIST += fal_qm.c +endif + +ifeq (TRUE, $(IN_BM)) + SRC_LIST += fal_bm.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_PPPOE)) + SRC_LIST += fal_pppoe.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/src/src/fal/fal_acl.c b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_acl.c new file mode 100755 index 000000000..22fbeb145 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_acl.c @@ -0,0 +1,741 @@ +/* + * Copyright (c) 2012, 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 + * @{ + */ +#include "sw.h" +#include "fal_acl.h" +#include "hsl_api.h" +#include "adpt.h" + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_acl_list_creat) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_acl_list_creat(dev_id, list_id, prio); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->acl_list_creat) + return SW_NOT_SUPPORTED; + + rv = p_api->acl_list_creat(dev_id, list_id, prio); + return rv; +} + +static sw_error_t +_fal_acl_list_destroy(a_uint32_t dev_id, a_uint32_t list_id) +{ + sw_error_t rv; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_acl_list_destroy) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_acl_list_destroy(dev_id, list_id); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->acl_list_destroy) + return SW_NOT_SUPPORTED; + + rv = p_api->acl_list_destroy(dev_id, list_id); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_acl_rule_add) + return SW_NOT_SUPPORTED; + rv = p_adpt_api->adpt_acl_rule_add(dev_id, list_id, rule_id, rule_nr, rule); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->acl_rule_add) + return SW_NOT_SUPPORTED; + + rv = p_api->acl_rule_add(dev_id, list_id, rule_id, rule_nr, rule); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_acl_rule_delete) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_acl_rule_delete(dev_id, list_id, rule_id, rule_nr); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->acl_rule_delete) + return SW_NOT_SUPPORTED; + + rv = p_api->acl_rule_delete(dev_id, list_id, rule_id, rule_nr); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_acl_rule_query) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_acl_rule_query(dev_id, list_id, rule_id, rule); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->acl_rule_query) + return SW_NOT_SUPPORTED; + + rv = p_api->acl_rule_query(dev_id, list_id, rule_id, rule); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_acl_list_bind) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_acl_list_bind(dev_id, list_id, direc, obj_t, obj_idx); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->acl_list_bind) + return SW_NOT_SUPPORTED; + + rv = p_api->acl_list_bind(dev_id, list_id, direc, obj_t, obj_idx); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_acl_list_unbind) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_acl_list_unbind(dev_id, list_id, direc, obj_t, obj_idx); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->acl_list_unbind) + return SW_NOT_SUPPORTED; + + rv = p_api->acl_list_unbind(dev_id, list_id, direc, obj_t, obj_idx); + return rv; +} + +static sw_error_t +_fal_acl_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->acl_status_set) + return SW_NOT_SUPPORTED; + + rv = p_api->acl_status_set(dev_id, enable); + return rv; +} + +static sw_error_t +_fal_acl_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->acl_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->acl_status_get(dev_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->acl_port_udf_profile_set) + return SW_NOT_SUPPORTED; + + rv = p_api->acl_port_udf_profile_set(dev_id, port_id, udf_type, offset, length); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->acl_port_udf_profile_get) + return SW_NOT_SUPPORTED; + + rv = p_api->acl_port_udf_profile_get(dev_id, port_id, udf_type, offset, length); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->acl_rule_active) + return SW_NOT_SUPPORTED; + + rv = p_api->acl_rule_active(dev_id, list_id, rule_id, rule_nr); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->acl_rule_deactive) + return SW_NOT_SUPPORTED; + + rv = p_api->acl_rule_deactive(dev_id, list_id, rule_id, rule_nr); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->acl_rule_src_filter_sts_set) + return SW_NOT_SUPPORTED; + + rv = p_api->acl_rule_src_filter_sts_set(dev_id, rule_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->acl_rule_src_filter_sts_get) + return SW_NOT_SUPPORTED; + + rv = p_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_acl_udf_profile_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_acl_udf_profile_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_acl_udf_profile_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_acl_udf_profile_get(dev_id, pkt_type, udf_idx, udf_type, offset); + return rv; +} +/*insert flag for inner fal, don't remove it*/ + +sw_error_t +fal_acl_list_dump(a_uint32_t dev_id) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->acl_list_dump) + return SW_NOT_SUPPORTED; + + rv = p_api->acl_list_dump(dev_id); + return rv; +} + +sw_error_t +fal_acl_rule_dump(a_uint32_t dev_id) +{ + sw_error_t rv; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_acl_rule_dump) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_acl_rule_dump(dev_id); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->acl_rule_dump) + return SW_NOT_SUPPORTED; + + rv = p_api->acl_rule_dump(dev_id); + return rv; +} + +/** + * @brief Creat an acl list + * @details Comments: + * If the priority of a list is more small then the priority is more high, + * that means the list could be first matched. + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] list_pri acl list priority + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_acl_list_creat(dev_id, list_id, prio); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Destroy an acl list + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @return SW_OK or error code + */ +sw_error_t +fal_acl_list_destroy(a_uint32_t dev_id, a_uint32_t list_id) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_acl_list_destroy(dev_id, list_id); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Add one rule or more rules to an existing acl list + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] rule_id first rule id of this adding operation in list + * @param[in] rule_nr rule number of this adding operation + * @param[in] rule rules content of this adding operation + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_acl_rule_add(dev_id, list_id, rule_id, rule_nr, rule); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete one rule or more rules from an existing acl list + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] rule_id first rule id of this deleteing operation in list + * @param[in] rule_nr rule number of this deleteing operation + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_acl_rule_delete(dev_id, list_id, rule_id, rule_nr); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Query one particular rule in a particular acl list + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] rule_id first rule id of this deleteing operation in list + * @param[out] rule rule content of this operation + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_acl_rule_query(dev_id, list_id, rule_id, rule); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Bind an acl list to a particular object + * @details Comments: + * If obj_t equals FAL_ACL_BIND_PORT then obj_idx means port id + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] direc direction of this binding operation + * @param[in] obj_t object type of this binding operation + * @param[in] obj_idx object index of this binding operation + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_acl_list_bind(dev_id, list_id, direc, obj_t, obj_idx); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Unbind an acl list from a particular object + * @details Comments: + * If obj_t equals FAL_ACL_BIND_PORT then obj_idx means port id + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] direc direction of this unbinding operation + * @param[in] obj_t object type of this unbinding operation + * @param[in] obj_idx object index of this unbinding operation + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_acl_list_unbind(dev_id, list_id, direc, obj_t, obj_idx); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set working status of ACL engine on a particular device + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_acl_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_acl_status_set(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get working status of ACL engine on a particular device + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_acl_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_acl_status_get(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set user define fields profile on a particular port + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] udf_type udf type + * @param[in] offset udf offset + * @param[in] length udf length + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_acl_port_udf_profile_set(dev_id, port_id, udf_type, offset, + length); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get user define fields profile on a particular port + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] udf_type udf type + * @param[out] offset udf offset + * @param[out] length udf length + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_acl_port_udf_profile_get(dev_id, port_id, udf_type, offset, + length); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Active one or more rules in an existing acl list + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] rule_id first rule id of this deactive operation in list + * @param[in] rule_nr rule number of this deactive operation + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_acl_rule_active(dev_id, list_id, rule_id, rule_nr); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Deactive one or more rules in an existing acl list + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] rule_id first rule id of this deactive operation in list + * @param[in] rule_nr rule number of this deactive operation + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_acl_rule_deactive(dev_id, list_id, rule_id, rule_nr); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief set status of one rule source filter + * @param[in] dev_id device id + * @param[in] rule_id first rule id of this deactive operation in list + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_acl_rule_src_filter_sts_set(dev_id, rule_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief get status of one rule source filter + * @param[in] dev_id device id + * @param[in] rule_id first rule id of this deactive operation in list + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_acl_rule_src_filter_sts_get(dev_id, rule_id, enable); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_acl_udf_profile_set(dev_id, pkt_type, udf_idx, udf_type, offset); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_acl_udf_profile_get(dev_id, pkt_type, udf_idx, udf_type, offset); + FAL_API_UNLOCK; + return rv; +} + +/*insert flag for outter fal, don't remove it*/ + +EXPORT_SYMBOL(fal_acl_list_creat); +EXPORT_SYMBOL(fal_acl_list_destroy); +EXPORT_SYMBOL(fal_acl_rule_add); +EXPORT_SYMBOL(fal_acl_rule_delete); +EXPORT_SYMBOL(fal_acl_rule_query); +EXPORT_SYMBOL(fal_acl_list_bind); +EXPORT_SYMBOL(fal_acl_list_unbind); +EXPORT_SYMBOL(fal_acl_status_set); +EXPORT_SYMBOL(fal_acl_status_get); +EXPORT_SYMBOL(fal_acl_port_udf_profile_set); +EXPORT_SYMBOL(fal_acl_port_udf_profile_get); +EXPORT_SYMBOL(fal_acl_rule_active); +EXPORT_SYMBOL(fal_acl_rule_deactive); +EXPORT_SYMBOL(fal_acl_rule_src_filter_sts_set); +EXPORT_SYMBOL(fal_acl_rule_src_filter_sts_get); +EXPORT_SYMBOL(fal_acl_udf_profile_set); +EXPORT_SYMBOL(fal_acl_udf_profile_get); + diff --git a/feeds/ipq807x/qca-ssdk/src/src/fal/fal_bm.c b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_bm.c new file mode 100755 index 000000000..dc2373477 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_bm.c @@ -0,0 +1,422 @@ +/* + * 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_qm FAL_BM + * @{ + */ +#include "sw.h" +#include "fal_bm.h" +#include "hsl_api.h" +#include "adpt.h" + +#ifndef IN_BM_MINI +sw_error_t +_fal_port_bufgroup_map_get(a_uint32_t dev_id, fal_port_t port, + a_uint8_t *group) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_bufgroup_map_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_bufgroup_map_get(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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_bm_port_reserved_buffer_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_bm_port_reserved_buffer_get(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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_bm_bufgroup_buffer_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_bm_bufgroup_buffer_get(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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_bm_port_dynamic_thresh_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_bm_port_dynamic_thresh_get(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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_bm_ctrl_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_bm_ctrl_get(dev_id, port, enable); + return rv; +} +#endif +sw_error_t +_fal_bm_bufgroup_buffer_set(a_uint32_t dev_id, a_uint8_t group, + a_uint16_t buff_num) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_bm_bufgroup_buffer_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_bm_bufgroup_buffer_set(dev_id, group, buff_num); + return rv; +} +sw_error_t +_fal_port_bufgroup_map_set(a_uint32_t dev_id, fal_port_t port, + a_uint8_t group) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_bufgroup_map_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_bufgroup_map_set(dev_id, port, group); + return rv; +} +#ifndef IN_BM_MINI +sw_error_t +_fal_bm_port_static_thresh_get(a_uint32_t dev_id, fal_port_t port, + fal_bm_static_cfg_t *cfg) +{ + adpt_api_t *p_api; + hsl_api_t *p_hsl_api; + sw_error_t rv = SW_OK; + + if((p_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_api->adpt_bm_port_static_thresh_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_bm_port_static_thresh_get(dev_id, port, cfg); + return rv; + } + + SW_RTN_ON_NULL(p_hsl_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_hsl_api->port_static_thresh_get) + return SW_NOT_SUPPORTED; + + rv = p_hsl_api->port_static_thresh_get(dev_id, port, cfg); + return rv; +} +#endif +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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_bm_port_reserved_buffer_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_bm_port_reserved_buffer_set(dev_id, port, prealloc_buff, react_buff); + 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) +{ + adpt_api_t *p_api; + hsl_api_t *p_hsl_api; + sw_error_t rv = SW_OK; + + if((p_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_api->adpt_bm_port_static_thresh_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_bm_port_static_thresh_set(dev_id, port, cfg); + return rv; + } + + SW_RTN_ON_NULL(p_hsl_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_hsl_api->port_static_thresh_set) + return SW_NOT_SUPPORTED; + + rv = p_hsl_api->port_static_thresh_set(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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_bm_port_dynamic_thresh_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_bm_port_dynamic_thresh_set(dev_id, port, cfg); + return rv; +} +sw_error_t +_fal_port_bm_ctrl_set(a_uint32_t dev_id, fal_port_t port, a_bool_t enable) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_bm_ctrl_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_bm_ctrl_set(dev_id, port, enable); + return rv; +} + +#ifndef IN_BM_MINI +sw_error_t +_fal_bm_port_counter_get(a_uint32_t dev_id, fal_port_t port, + fal_bm_port_counter_t *counter) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_bm_port_counter_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_bm_port_counter_get(dev_id, port, counter); + return rv; +} +/*insert flag for inner fal, don't remove it*/ + +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_bufgroup_map_get(dev_id, port, group); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_bm_port_reserved_buffer_get(dev_id, port, prealloc_buff, react_buff); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_bm_bufgroup_buffer_get(dev_id, group, buff_num); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_bm_port_dynamic_thresh_get(dev_id, port, cfg); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_bm_ctrl_get(dev_id, port, enable); + FAL_API_UNLOCK; + return rv; +} +#endif + +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_bm_bufgroup_buffer_set(dev_id, group, buff_num); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_bufgroup_map_set(dev_id, port, group); + FAL_API_UNLOCK; + return rv; +} +#ifndef IN_BM_MINI +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_bm_port_static_thresh_get(dev_id, port, cfg); + FAL_API_UNLOCK; + return rv; +} +#endif +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_bm_port_reserved_buffer_set(dev_id, port, prealloc_buff, react_buff); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_bm_port_static_thresh_set(dev_id, port, cfg); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_bm_port_dynamic_thresh_set(dev_id, port, cfg); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_bm_ctrl_set(dev_id, port, enable); + FAL_API_UNLOCK; + return rv; +} + +#ifndef IN_BM_MINI +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_bm_port_counter_get(dev_id, port, counter); + FAL_API_UNLOCK; + return rv; +} +#endif + +EXPORT_SYMBOL(fal_port_bm_ctrl_set); + +EXPORT_SYMBOL(fal_port_bufgroup_map_set); + +EXPORT_SYMBOL(fal_bm_bufgroup_buffer_set); + +EXPORT_SYMBOL(fal_bm_port_reserved_buffer_set); + +EXPORT_SYMBOL(fal_bm_port_dynamic_thresh_set); + +#ifndef IN_BM_MINI +EXPORT_SYMBOL(fal_port_bm_ctrl_get); + +EXPORT_SYMBOL(fal_port_bufgroup_map_get); + +EXPORT_SYMBOL(fal_bm_bufgroup_buffer_get); + +EXPORT_SYMBOL(fal_bm_port_reserved_buffer_get); + +EXPORT_SYMBOL(fal_bm_port_static_thresh_set); + +EXPORT_SYMBOL(fal_bm_port_static_thresh_get); + +EXPORT_SYMBOL(fal_bm_port_dynamic_thresh_get); + +EXPORT_SYMBOL(fal_bm_port_counter_get); +#endif + +/*insert flag for outter fal, don't remove it*/ diff --git a/feeds/ipq807x/qca-ssdk/src/src/fal/fal_cosmap.c b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_cosmap.c new file mode 100755 index 000000000..4d7d84ffa --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_cosmap.c @@ -0,0 +1,783 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 + * @{ + */ +#include "sw.h" +#include "fal_cosmap.h" +#include "hsl_api.h" + +#ifndef IN_COSMAP_MINI +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->cosmap_dscp_to_pri_set) + return SW_NOT_SUPPORTED; + + rv = p_api->cosmap_dscp_to_pri_set(dev_id, dscp, pri); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->cosmap_dscp_to_pri_get) + return SW_NOT_SUPPORTED; + + rv = p_api->cosmap_dscp_to_pri_get(dev_id, dscp, pri); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->cosmap_dscp_to_dp_set) + return SW_NOT_SUPPORTED; + + rv = p_api->cosmap_dscp_to_dp_set(dev_id, dscp, dp); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->cosmap_dscp_to_dp_get) + return SW_NOT_SUPPORTED; + + rv = p_api->cosmap_dscp_to_dp_get(dev_id, dscp, dp); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->cosmap_up_to_pri_set) + return SW_NOT_SUPPORTED; + + rv = p_api->cosmap_up_to_pri_set(dev_id, up, pri); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->cosmap_up_to_pri_get) + return SW_NOT_SUPPORTED; + + rv = p_api->cosmap_up_to_pri_get(dev_id, up, pri); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->cosmap_up_to_dp_set) + return SW_NOT_SUPPORTED; + + rv = p_api->cosmap_up_to_dp_set(dev_id, up, dp); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->cosmap_up_to_dp_get) + return SW_NOT_SUPPORTED; + + rv = p_api->cosmap_up_to_dp_get(dev_id, up, dp); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->cosmap_dscp_to_ehpri_set) + return SW_NOT_SUPPORTED; + + rv = p_api->cosmap_dscp_to_ehpri_set(dev_id, dscp, pri); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->cosmap_dscp_to_ehpri_get) + return SW_NOT_SUPPORTED; + + rv = p_api->cosmap_dscp_to_ehpri_get(dev_id, dscp, pri); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->cosmap_dscp_to_ehdp_set) + return SW_NOT_SUPPORTED; + + rv = p_api->cosmap_dscp_to_ehdp_set(dev_id, dscp, dp); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->cosmap_dscp_to_ehdp_get) + return SW_NOT_SUPPORTED; + + rv = p_api->cosmap_dscp_to_ehdp_get(dev_id, dscp, dp); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->cosmap_up_to_ehpri_set) + return SW_NOT_SUPPORTED; + + rv = p_api->cosmap_up_to_ehpri_set(dev_id, up, pri); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->cosmap_up_to_ehpri_get) + return SW_NOT_SUPPORTED; + + rv = p_api->cosmap_up_to_ehpri_get(dev_id, up, pri); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->cosmap_up_to_ehdp_set) + return SW_NOT_SUPPORTED; + + rv = p_api->cosmap_up_to_ehdp_set(dev_id, up, dp); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->cosmap_up_to_ehdp_get) + return SW_NOT_SUPPORTED; + + rv = p_api->cosmap_up_to_ehdp_get(dev_id, up, dp); + return rv; +} +#endif + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->cosmap_pri_to_queue_set) + return SW_NOT_SUPPORTED; + + rv = p_api->cosmap_pri_to_queue_set(dev_id, pri, queue); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->cosmap_pri_to_ehqueue_set) + return SW_NOT_SUPPORTED; + + rv = p_api->cosmap_pri_to_ehqueue_set(dev_id, pri, queue); + return rv; +} + +#ifndef IN_COSMAP_MINI +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->cosmap_pri_to_queue_get) + return SW_NOT_SUPPORTED; + + rv = p_api->cosmap_pri_to_queue_get(dev_id, pri, queue); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->cosmap_pri_to_ehqueue_get) + return SW_NOT_SUPPORTED; + + rv = p_api->cosmap_pri_to_ehqueue_get(dev_id, pri, queue); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->cosmap_egress_remark_set) + return SW_NOT_SUPPORTED; + + rv = p_api->cosmap_egress_remark_set(dev_id, tbl_id, tbl); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->cosmap_egress_remark_get) + return SW_NOT_SUPPORTED; + + rv = p_api->cosmap_egress_remark_get(dev_id, tbl_id, tbl); + return rv; +} + +/** + * @brief Set dscp to internal priority mapping on one particular device. + * @param[in] dev_id device id + * @param[in] dscp dscp + * @param[in] pri internal priority + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_cosmap_dscp_to_pri_set(dev_id, dscp, pri); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dscp to internal priority mapping on one particular device. + * @param[in] dev_id device id + * @param[in] dscp dscp + * @param[out] pri internal priority + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_cosmap_dscp_to_pri_get(dev_id, dscp, pri); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dscp to internal drop precedence mapping on one particular device. + * @param[in] dev_id device id + * @param[in] dscp dscp + * @param[in] dp internal drop precedence + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_cosmap_dscp_to_dp_set(dev_id, dscp, dp); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dscp to internal drop precedence mapping on one particular device. + * @param[in] dev_id device id + * @param[in] dscp dscp + * @param[out] dp internal drop precedence + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_cosmap_dscp_to_dp_get(dev_id, dscp, dp); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dot1p to internal priority mapping on one particular device. + * @param[in] dev_id device id + * @param[in] up dot1p + * @param[in] pri internal priority + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_cosmap_up_to_pri_set(dev_id, up, pri); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dot1p to internal priority mapping on one particular device. + * @param[in] dev_id device id + * @param[in] up dot1p + * @param[out] pri internal priority + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_cosmap_up_to_pri_get(dev_id, up, pri); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dot1p to internal drop precedence mapping on one particular device. + * @param[in] dev_id device id + * @param[in] up dot1p + * @param[in] dp internal drop precedence + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_cosmap_up_to_dp_set(dev_id, up, dp); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dot1p to internal drop precedence mapping on one particular device. + * @param[in] dev_id device id + * @param[in] up dot1p + * @param[in] dp internal drop precedence + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_cosmap_up_to_dp_get(dev_id, up, dp); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dscp to internal priority mapping on one particular device for WAN port. + * @param[in] dev_id device id + * @param[in] dscp dscp + * @param[in] pri internal priority + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_cosmap_dscp_to_ehpri_set(dev_id, dscp, pri); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dscp to internal priority mapping on one particular device for WAN port. + * @param[in] dev_id device id + * @param[in] dscp dscp + * @param[out] pri internal priority + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_cosmap_dscp_to_ehpri_get(dev_id, dscp, pri); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dscp to internal drop precedence mapping on one particular device for WAN port. + * @param[in] dev_id device id + * @param[in] dscp dscp + * @param[in] dp internal drop precedence + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_cosmap_dscp_to_ehdp_set(dev_id, dscp, dp); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dscp to internal drop precedence mapping on one particular device for WAN port. + * @param[in] dev_id device id + * @param[in] dscp dscp + * @param[out] dp internal drop precedence + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_cosmap_dscp_to_ehdp_get(dev_id, dscp, dp); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dot1p to internal priority mapping on one particular device for WAN port. + * @param[in] dev_id device id + * @param[in] up dot1p + * @param[in] pri internal priority + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_cosmap_up_to_ehpri_set(dev_id, up, pri); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dot1p to internal priority mapping on one particular device for WAN port. + * @param[in] dev_id device id + * @param[in] up dot1p + * @param[out] pri internal priority + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_cosmap_up_to_ehpri_get(dev_id, up, pri); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dot1p to internal drop precedence mapping on one particular device for WAN port. + * @param[in] dev_id device id + * @param[in] up dot1p + * @param[in] dp internal drop precedence + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_cosmap_up_to_ehdp_set(dev_id, up, dp); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dot1p to internal drop precedence mapping on one particular device for WAN port. + * @param[in] dev_id device id + * @param[in] up dot1p + * @param[in] dp internal drop precedence + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_cosmap_up_to_ehdp_get(dev_id, up, dp); + FAL_API_UNLOCK; + return rv; +} +#endif + +/** + * @brief Set internal priority to queue mapping on one particular device. + * @details Comments: + * This function is for port 1/2/3/4 which have four egress queues + * @param[in] dev_id device id + * @param[in] pri internal priority + * @param[in] queue queue id + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_cosmap_pri_to_queue_set(dev_id, pri, queue); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set internal priority to queue mapping on one particular device. + * @details Comments: + * This function is for port 0/5/6 which have six egress queues + * @param[in] dev_id device id + * @param[in] pri internal priority + * @param[in] queue queue id + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_cosmap_pri_to_ehqueue_set(dev_id, pri, queue); + FAL_API_UNLOCK; + return rv; +} + +#ifndef IN_COSMAP_MINI +/** + * @brief Get internal priority to queue mapping on one particular device. + * @details Comments: + * This function is for port 1/2/3/4 which have four egress queues + * @param[in] dev_id device id + * @param[in] pri internal priority + * @param[out] queue queue id + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_cosmap_pri_to_queue_get(dev_id, pri, queue); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get internal priority to queue mapping on one particular device. + * @details Comments: + * This function is for port 0/5/6 which have six egress queues + * @param[in] dev_id device id + * @param[in] pri internal priority + * @param[in] queue queue id + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_cosmap_pri_to_ehqueue_get(dev_id, pri, queue); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set egress queue based CoS remap table on one particular device. + * @param[in] dev_id device id + * @param[in] tbl_id CoS remap table id + * @param[in] tbl CoS remap table + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_cosmap_egress_remark_set(dev_id, tbl_id, tbl); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get egress queue based CoS remap table on one particular device. + * @param[in] dev_id device id + * @param[in] tbl_id CoS remap table id + * @param[out] tbl CoS remap table + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_cosmap_egress_remark_get(dev_id, tbl_id, tbl); + FAL_API_UNLOCK; + return rv; +} +#endif + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/fal/fal_ctrlpkt.c b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_ctrlpkt.c new file mode 100755 index 000000000..cfcf5a245 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_ctrlpkt.c @@ -0,0 +1,248 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "fal_ctrlpkt.h" +#include "hsl_api.h" +#include "adpt.h" + +#include +#include + + +/** + * @} + */ +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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_mgmtctrl_ethtype_profile_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_mgmtctrl_ethtype_profile_set(dev_id, profile_id, 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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_mgmtctrl_ethtype_profile_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_mgmtctrl_rfdb_profile_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_mgmtctrl_rfdb_profile_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_mgmtctrl_ctrlpkt_profile_add) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_mgmtctrl_ctrlpkt_profile_del) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_mgmtctrl_ctrlpkt_profile_getfirst) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_mgmtctrl_ctrlpkt_profile_getnext) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_mgmtctrl_ctrlpkt_profile_getnext(dev_id, ctrlpkt); + return rv; +} + +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 = SW_OK; + + FAL_CTRLPKT_API_LOCK; + rv = _fal_mgmtctrl_ethtype_profile_set(dev_id, profile_id, ethtype); + FAL_CTRLPKT_API_UNLOCK; + 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 = SW_OK; + + FAL_CTRLPKT_API_LOCK; + rv = _fal_mgmtctrl_ethtype_profile_get(dev_id, profile_id, ethtype); + FAL_CTRLPKT_API_UNLOCK; + 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 = SW_OK; + + FAL_CTRLPKT_API_LOCK; + rv = _fal_mgmtctrl_rfdb_profile_set(dev_id, profile_id, addr); + FAL_CTRLPKT_API_UNLOCK; + 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 = SW_OK; + + FAL_CTRLPKT_API_LOCK; + rv = _fal_mgmtctrl_rfdb_profile_get(dev_id, profile_id, addr); + FAL_CTRLPKT_API_UNLOCK; + return rv; +} + +sw_error_t +fal_mgmtctrl_ctrlpkt_profile_add(a_uint32_t dev_id, fal_ctrlpkt_profile_t *ctrlpkt) +{ + sw_error_t rv = SW_OK; + + FAL_CTRLPKT_API_LOCK; + rv = _fal_mgmtctrl_ctrlpkt_profile_add(dev_id, ctrlpkt); + FAL_CTRLPKT_API_UNLOCK; + return rv; +} + +sw_error_t +fal_mgmtctrl_ctrlpkt_profile_del(a_uint32_t dev_id, fal_ctrlpkt_profile_t *ctrlpkt) +{ + sw_error_t rv = SW_OK; + + FAL_CTRLPKT_API_LOCK; + rv = _fal_mgmtctrl_ctrlpkt_profile_del(dev_id, ctrlpkt); + FAL_CTRLPKT_API_UNLOCK; + return rv; +} + +sw_error_t +fal_mgmtctrl_ctrlpkt_profile_getfirst(a_uint32_t dev_id, fal_ctrlpkt_profile_t *ctrlpkt) +{ + sw_error_t rv = SW_OK; + + FAL_CTRLPKT_API_LOCK; + rv = _fal_mgmtctrl_ctrlpkt_profile_getfirst(dev_id, ctrlpkt); + FAL_CTRLPKT_API_UNLOCK; + return rv; +} + +sw_error_t +fal_mgmtctrl_ctrlpkt_profile_getnext(a_uint32_t dev_id, fal_ctrlpkt_profile_t *ctrlpkt) +{ + sw_error_t rv = SW_OK; + + FAL_CTRLPKT_API_LOCK; + rv = _fal_mgmtctrl_ctrlpkt_profile_getnext(dev_id, ctrlpkt); + FAL_CTRLPKT_API_UNLOCK; + return rv; +} + +EXPORT_SYMBOL(fal_mgmtctrl_ethtype_profile_set); +EXPORT_SYMBOL(fal_mgmtctrl_ethtype_profile_get); +EXPORT_SYMBOL(fal_mgmtctrl_rfdb_profile_set); +EXPORT_SYMBOL(fal_mgmtctrl_rfdb_profile_get); +EXPORT_SYMBOL(fal_mgmtctrl_ctrlpkt_profile_add); +EXPORT_SYMBOL(fal_mgmtctrl_ctrlpkt_profile_del); +EXPORT_SYMBOL(fal_mgmtctrl_ctrlpkt_profile_getfirst); +EXPORT_SYMBOL(fal_mgmtctrl_ctrlpkt_profile_getnext); + diff --git a/feeds/ipq807x/qca-ssdk/src/src/fal/fal_fdb.c b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_fdb.c new file mode 100755 index 000000000..02dc74a4f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_fdb.c @@ -0,0 +1,1942 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup fal_fdb FAL_FDB + * @{ + */ +#include "sw.h" +#include "fal_fdb.h" +#include "hsl_api.h" +#include "adpt.h" + +#include +#include + + +#ifndef IN_FDB_MINI +static sw_error_t +_fal_fdb_entry_add(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_fdb_add) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_fdb_add(dev_id, entry); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->fdb_add) + return SW_NOT_SUPPORTED; + + rv = p_api->fdb_add(dev_id, entry); + return rv; +} +#endif + +static sw_error_t +_fal_fdb_entry_flush(a_uint32_t dev_id, a_uint32_t flag) +{ + sw_error_t rv; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_fdb_del_all) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_fdb_del_all(dev_id, flag); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->fdb_del_all) + return SW_NOT_SUPPORTED; + + rv = p_api->fdb_del_all(dev_id, flag); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_fdb_del_by_port) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_fdb_del_by_port(dev_id, port_id, flag); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->fdb_del_by_port) + return SW_NOT_SUPPORTED; + + rv = p_api->fdb_del_by_port(dev_id, port_id, flag); + return rv; +} + + +static sw_error_t +_fal_fdb_entry_del_bymac(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_fdb_del_by_mac) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_fdb_del_by_mac(dev_id, entry); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->fdb_del_by_mac) + return SW_NOT_SUPPORTED; + + rv = p_api->fdb_del_by_mac(dev_id, entry); + return rv; +} + +static sw_error_t +_fal_fdb_entry_getfirst(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_fdb_first) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_fdb_first(dev_id, entry); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->fdb_first) + return SW_NOT_SUPPORTED; + + rv = p_api->fdb_first(dev_id, entry); + return rv; +} + +#ifndef IN_FDB_MINI +static sw_error_t +_fal_fdb_entry_getnext(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_fdb_next) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_fdb_next(dev_id, entry); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->fdb_next) + return SW_NOT_SUPPORTED; + + rv = p_api->fdb_next(dev_id, entry); + return rv; +} +#endif + +static sw_error_t +_fal_fdb_entry_search(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_fdb_find) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_fdb_find(dev_id, entry); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->fdb_find) + return SW_NOT_SUPPORTED; + + rv = p_api->fdb_find(dev_id, entry); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_fdb_port_learn_set) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_fdb_port_learn_set(dev_id, port_id, enable); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_learn_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_learn_set(dev_id, port_id, enable); + return rv; +} + +#ifndef IN_FDB_MINI +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_fdb_port_learn_get) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_fdb_port_learn_get(dev_id, port_id, enable); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_learn_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_learn_get(dev_id, port_id, enable); + return rv; +} +#endif + +static 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_fdb_port_newaddr_lrn_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_fdb_port_newaddr_lrn_set(dev_id, port_id, enable, cmd); + return rv; +} + +#ifndef IN_FDB_MINI +static 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_fdb_port_newaddr_lrn_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_fdb_port_newaddr_lrn_get(dev_id, port_id, enable, cmd); + return rv; +} +#endif + +static 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_fdb_port_stamove_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_fdb_port_stamove_set(dev_id, port_id, enable, cmd); + return rv; +} + +#ifndef IN_FDB_MINI +static 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_fdb_port_stamove_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_fdb_port_stamove_get(dev_id, port_id, enable, cmd); + return rv; +} +#endif + +static sw_error_t +_fal_fdb_aging_ctrl_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_fdb_age_ctrl_set) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_fdb_age_ctrl_set(dev_id, enable); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->age_ctrl_set) + return SW_NOT_SUPPORTED; + + rv = p_api->age_ctrl_set(dev_id, enable); + return rv; +} + +#ifndef IN_FDB_MINI +static sw_error_t +_fal_fdb_aging_ctrl_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_fdb_age_ctrl_get) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_fdb_age_ctrl_get(dev_id, enable); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->age_ctrl_get) + return SW_NOT_SUPPORTED; + + rv = p_api->age_ctrl_get(dev_id, enable); + return rv; +} + +static sw_error_t +_fal_fdb_vlan_ivl_svl_set(a_uint32_t dev_id, fal_fdb_smode smode) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->vlan_ivl_svl_set) + return SW_NOT_SUPPORTED; + + rv = p_api->vlan_ivl_svl_set(dev_id, smode); + return rv; +} + +static sw_error_t +_fal_fdb_vlan_ivl_svl_get(a_uint32_t dev_id, fal_fdb_smode* smode) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->vlan_ivl_svl_get) + return SW_NOT_SUPPORTED; + + rv = p_api->vlan_ivl_svl_get(dev_id, smode); + return rv; +} + +static sw_error_t +_fal_fdb_aging_time_set(a_uint32_t dev_id, a_uint32_t * time) +{ + sw_error_t rv; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_fdb_age_time_set) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_fdb_age_time_set(dev_id, time); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->age_time_set) + return SW_NOT_SUPPORTED; + + rv = p_api->age_time_set(dev_id, time); + return rv; +} + + +static sw_error_t +_fal_fdb_aging_time_get(a_uint32_t dev_id, a_uint32_t * time) +{ + sw_error_t rv; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_fdb_age_time_get) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_fdb_age_time_get(dev_id, time); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->age_time_get) + return SW_NOT_SUPPORTED; + + rv = p_api->age_time_get(dev_id, time); + return rv; +} +#endif + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_fdb_iterate) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_fdb_iterate(dev_id, iterator, entry); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->fdb_iterate) + return SW_NOT_SUPPORTED; + + rv = p_api->fdb_iterate(dev_id, iterator, entry); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_fdb_extend_next) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_fdb_extend_next(dev_id, option, entry); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->fdb_extend_next) + return SW_NOT_SUPPORTED; + + rv = p_api->fdb_extend_next(dev_id, option, entry); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_fdb_extend_first) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_fdb_extend_first(dev_id, option, entry); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->fdb_extend_first) + return SW_NOT_SUPPORTED; + + rv = p_api->fdb_extend_first(dev_id, option, entry); + return rv; +} + +#ifndef IN_FDB_MINI +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_fdb_transfer) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_fdb_transfer(dev_id, old_port, new_port, fid, option); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->fdb_transfer) + return SW_NOT_SUPPORTED; + + rv = p_api->fdb_transfer(dev_id, old_port, new_port, fid, option); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_port_fdb_learn_limit_set) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_port_fdb_learn_limit_set(dev_id, port_id, enable, cnt); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_fdb_learn_limit_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_fdb_learn_limit_set(dev_id, port_id, enable, cnt); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_port_fdb_learn_limit_get) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_port_fdb_learn_limit_get(dev_id, port_id, enable, cnt); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_fdb_learn_limit_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_fdb_learn_limit_get(dev_id, port_id, enable, cnt); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_port_fdb_learn_exceed_cmd_set) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_port_fdb_learn_exceed_cmd_set(dev_id, port_id, cmd); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_fdb_learn_exceed_cmd_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_fdb_learn_exceed_cmd_set(dev_id, port_id, cmd); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_port_fdb_learn_exceed_cmd_get) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_port_fdb_learn_exceed_cmd_get(dev_id, port_id, cmd); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_fdb_learn_exceed_cmd_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_fdb_learn_exceed_cmd_get(dev_id, port_id, cmd); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->fdb_learn_limit_set) + return SW_NOT_SUPPORTED; + + rv = p_api->fdb_learn_limit_set(dev_id, enable, cnt); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->fdb_learn_limit_get) + return SW_NOT_SUPPORTED; + + rv = p_api->fdb_learn_limit_get(dev_id, enable, cnt); + return rv; +} + +static sw_error_t +_fal_fdb_learn_exceed_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->fdb_learn_exceed_cmd_set) + return SW_NOT_SUPPORTED; + + rv = p_api->fdb_learn_exceed_cmd_set(dev_id, cmd); + return rv; +} + +static sw_error_t +_fal_fdb_learn_exceed_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->fdb_learn_exceed_cmd_get) + return SW_NOT_SUPPORTED; + + rv = p_api->fdb_learn_exceed_cmd_get(dev_id, cmd); + return rv; +} + +static sw_error_t +_fal_fdb_resv_add(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->fdb_resv_add) + return SW_NOT_SUPPORTED; + + rv = p_api->fdb_resv_add(dev_id, entry); + return rv; +} + +static sw_error_t +_fal_fdb_resv_del(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->fdb_resv_del) + return SW_NOT_SUPPORTED; + + rv = p_api->fdb_resv_del(dev_id, entry); + return rv; +} + +static sw_error_t +_fal_fdb_resv_find(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->fdb_resv_find) + return SW_NOT_SUPPORTED; + + rv = p_api->fdb_resv_find(dev_id, entry); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->fdb_resv_iterate) + return SW_NOT_SUPPORTED; + + rv = p_api->fdb_resv_iterate(dev_id, iterator, entry); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->fdb_port_learn_static_set) + return SW_NOT_SUPPORTED; + + rv = p_api->fdb_port_learn_static_set(dev_id, port_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->fdb_port_learn_static_get) + return SW_NOT_SUPPORTED; + + rv = p_api->fdb_port_learn_static_get(dev_id, port_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_fdb_port_add) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_fdb_port_add(dev_id, fid, addr, port_id); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->fdb_port_add) + return SW_NOT_SUPPORTED; + + rv = p_api->fdb_port_add(dev_id, fid, addr, port_id); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_fdb_port_del) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_fdb_port_del(dev_id, fid, addr, port_id); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->fdb_port_del) + return SW_NOT_SUPPORTED; + + rv = p_api->fdb_port_del(dev_id, fid, addr, port_id); + return rv; +} + +sw_error_t +_fal_fdb_rfs_set(a_uint32_t dev_id, const fal_fdb_rfs_t * entry) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->fdb_rfs_set) + return SW_NOT_SUPPORTED; + + rv = p_api->fdb_rfs_set(dev_id, entry); + return rv; +} + +sw_error_t +_fal_fdb_rfs_del(a_uint32_t dev_id, const fal_fdb_rfs_t * entry) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->fdb_rfs_del) + return SW_NOT_SUPPORTED; + + rv = p_api->fdb_rfs_del(dev_id, entry); + return rv; +} +#endif + +sw_error_t +_fal_fdb_learning_ctrl_set(a_uint32_t dev_id, a_bool_t enable) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_fdb_learn_ctrl_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_fdb_learn_ctrl_set(dev_id, enable); + return rv; +} + +#ifndef IN_FDB_MINI +sw_error_t +_fal_fdb_learning_ctrl_get(a_uint32_t dev_id, a_bool_t * enable) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_fdb_learn_ctrl_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_fdb_learn_ctrl_get(dev_id, enable); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_fdb_learn_counter_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_fdb_learn_counter_get(dev_id, port_id, cnt); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_fdb_port_maclimit_ctrl_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_fdb_port_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_fdb_port_maclimit_ctrl_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_fdb_port_maclimit_ctrl_get(dev_id, port_id, maclimit_ctrl); + return rv; +} +#endif +sw_error_t +_fal_fdb_entry_del_byfid(a_uint32_t dev_id, a_uint16_t fid, a_uint32_t flag) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_fdb_del_by_fid) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_fdb_del_by_fid(dev_id, fid, flag); + return rv; +} +#ifndef IN_FDB_MINI +/*insert flag for inner fal, don't remove it*/ + +/** + * @brief Add a Fdb entry + * @param[in] dev_id device id + * @param[in] entry fdb entry + * @return SW_OK or error code + */ +sw_error_t +fal_fdb_entry_add(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_fdb_entry_add(dev_id, entry); + FAL_API_UNLOCK; + return rv; +} +#endif + +/** + * @brief Delete all Fdb entries + * @details Comments: + * If set FAL_FDB_DEL_STATIC bit in flag which means delete all fdb + * entries otherwise only delete dynamic entries. + * @param[in] dev_id device id + * @param[in] flag delete operation option + * @return SW_OK or error code + */ +sw_error_t +fal_fdb_entry_flush(a_uint32_t dev_id, a_uint32_t flag) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_fdb_entry_flush(dev_id, flag); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete Fdb entries on a particular port + * @details Comments: + * If set FAL_FDB_DEL_STATIC bit in flag which means delete all fdb + * entries otherwise only delete dynamic entries. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] flag delete operation option + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_fdb_entry_del_byport(dev_id, port_id, flag); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a particular Fdb entry through mac address + * @details Comments: + * Only addr field in entry is meaning. For IVL learning vid or fid field + * also is meaning. + * @param[in] dev_id device id + * @param[in] entry fdb entry + * @return SW_OK or error code + */ +sw_error_t +fal_fdb_entry_del_bymac(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_fdb_entry_del_bymac(dev_id, entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get first Fdb entry from particular device + * @param[in] dev_id device id + * @param[out] entry fdb entry + * @return SW_OK or error code + */ +sw_error_t +fal_fdb_entry_getfirst(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_fdb_entry_getfirst(dev_id, entry); + FAL_API_UNLOCK; + return rv; +} + +#ifndef IN_FDB_MINI +/** + * @brief Get next Fdb entry from particular device + * @details Comments: + For input parameter only addr field in entry is meaning. + * @param[in] dev_id device id + * @param entry fdb entry + * @return SW_OK or error code + */ +sw_error_t +fal_fdb_entry_getnext(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_fdb_entry_getnext(dev_id, entry); + FAL_API_UNLOCK; + return rv; +} +#endif + +/** + * @brief Find a particular Fdb entry from device through mac address. + * @details Comments: + For input parameter only addr field in entry is meaning. + * @param[in] dev_id device id + * @param[in] entry fdb entry + * @param[out] entry fdb entry + * @return SW_OK or error code + */ +sw_error_t +fal_fdb_entry_search(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_fdb_entry_search(dev_id, entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dynamic address and station move learning status on a particular port. + * @details Comments: + * This operation will enable or disable dynamic address and + * station move learning feature on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable enable or disable + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_fdb_port_learn_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +#ifndef IN_FDB_MINI +/** + * @brief Get dynamic address and station move learning status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_fdb_port_learn_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} +#endif + +/** + * @brief Set dynamic address learning and forward command on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] learning status + * @param[in] forward command + * @return SW_OK or error code + */ +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_fdb_port_learning_ctrl_set(dev_id, port_id, enable, cmd); + FAL_API_UNLOCK; + return rv; +} + +#ifndef IN_FDB_MINI +/** + * @brief Get dynamic address learning and forward command on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] learning status + * @param[out] forward command + * @return SW_OK or error code + */ +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_fdb_port_learning_ctrl_get(dev_id, port_id, enable, cmd); + FAL_API_UNLOCK; + return rv; +} +#endif + +/** + * @brief Set station move learning and forward command on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] learning status + * @param[in] forward command + * @return SW_OK or error code + */ +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_fdb_port_stamove_ctrl_set(dev_id, port_id, enable, cmd); + FAL_API_UNLOCK; + return rv; +} + +#ifndef IN_FDB_MINI +/** + * @brief Get station move learning and forward command on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] learning status + * @param[out] forward command + * @return SW_OK or error code + */ +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_fdb_port_stamove_ctrl_get(dev_id, port_id, enable, cmd); + FAL_API_UNLOCK; + return rv; +} +#endif + +/** + * @brief Set dynamic address aging status on particular device. + * @details Comments: + * This operation will enable or disable dynamic address aging + * feature on particular device. + * @param[in] dev_id device id + * @param[in] enable enable or disable + * @return SW_OK or error code + */ +sw_error_t +fal_fdb_aging_ctrl_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_fdb_aging_ctrl_set(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +#ifndef IN_FDB_MINI +/** + * @brief Get dynamic address aging status on particular device. + * @param[in] dev_id device id + * @param[in] enable enable or disable + * @return SW_OK or error code + */ +sw_error_t +fal_fdb_aging_ctrl_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_fdb_aging_ctrl_get(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief set arl search mode as ivl or svl when vlan invalid. + * @param[in] dev_id device id + * @param[in] smode INVALID_VLAN_IVL or INVALID_VLAN_SVL + * @return SW_OK or error code + */ +sw_error_t +fal_fdb_vlan_ivl_svl_set(a_uint32_t dev_id, fal_fdb_smode smode) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_fdb_vlan_ivl_svl_set(dev_id, smode); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief get arl search mode when vlan invalid. + * @param[in] dev_id device id + * @param[out] smode INVALID_VLAN_IVL or INVALID_VLAN_SVL + * @return SW_OK or error code + */ +sw_error_t +fal_fdb_vlan_ivl_svl_get(a_uint32_t dev_id, fal_fdb_smode* smode) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_fdb_vlan_ivl_svl_get(dev_id, smode); + FAL_API_UNLOCK; + return rv; +} + + + + +/** + * @brief Set dynamic address aging time on a particular device. + * @details Comments: + * This operation will set dynamic address aging time on a particular device. + * The unit of time is second. Because different device has differnet + * hardware granularity function will return actual time in hardware. + * @param[in] dev_id device id + * @param time aging time + * @return SW_OK or error code + */ +sw_error_t +fal_fdb_aging_time_set(a_uint32_t dev_id, a_uint32_t * time) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_fdb_aging_time_set(dev_id, time); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dynamic address aging time on a particular device. + * @param[in] dev_id device id + * @param[out] time aging time + * @return SW_OK or error code + */ +sw_error_t +fal_fdb_aging_time_get(a_uint32_t dev_id, a_uint32_t * time) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_fdb_aging_time_get(dev_id, time); + FAL_API_UNLOCK; + return rv; +} +#endif + +/** + * @brief Iterate all fdb entries on a particular device. + * @param[in] dev_id device id + * @param[in] iterator fdb entry index if it's zero means get the first entry + * @param[out] iterator next valid fdb entry index + * @param[out] entry fdb entry + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_fdb_entry_getnext_byindex(dev_id, iterator, entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get next Fdb entry from a particular device + * @param[in] dev_id device id + * @param[in] option next operation options + * @param[out] entry fdb entry + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_fdb_entry_extend_getnext(dev_id, option, entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get first Fdb entry from a particular device + * @param[in] dev_id device id + * @param[in] option first operation options + * @param[out] entry fdb entry + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_fdb_entry_extend_getfirst(dev_id, option, entry); + FAL_API_UNLOCK; + return rv; +} + +#ifndef IN_FDB_MINI +/** + * @brief Transfer fdb entries port information on a particular device. + * @param[in] dev_id device id + * @param[in] old_port source port id + * @param[in] new_port destination port id + * @param[in] fid filter database id + * @param[in] option transfer operation options + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_fdb_entry_update_byport(dev_id, old_port, new_port, fid, option); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dynamic address learning count limit on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] cnt limit count + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_fdb_learn_limit_set(dev_id, port_id, enable, cnt); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dynamic address learning count limit on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @param[out] cnt limit count + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_fdb_learn_limit_get(dev_id, port_id, enable, cnt); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dynamic address learning count exceed command on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_fdb_learn_exceed_cmd_set(dev_id, port_id, cmd); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dynamic address learning count exceed command on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_fdb_learn_exceed_cmd_get(dev_id, port_id, cmd); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dynamic address learning count limit on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] cnt limit count + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_fdb_learn_limit_set(dev_id, enable, cnt); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dynamic address learning count limit on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] cnt limit count + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_fdb_learn_limit_get(dev_id, enable, cnt); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dynamic address learning count exceed command on a particular device. + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +sw_error_t +fal_fdb_learn_exceed_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_fdb_learn_exceed_cmd_set(dev_id, cmd); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dynamic address learning count exceed command on a particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +sw_error_t +fal_fdb_learn_exceed_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_fdb_learn_exceed_cmd_get(dev_id, cmd); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Add a particular reserve Fdb entry + * @param[in] dev_id device id + * @param[in] entry reserve fdb entry + * @return SW_OK or error code + */ +sw_error_t +fal_fdb_resv_add(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_fdb_resv_add(dev_id, entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a particular reserve Fdb entry through mac address + * @param[in] dev_id device id + * @param[in] entry reserve fdb entry + * @return SW_OK or error code + */ +sw_error_t +fal_fdb_resv_del(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_fdb_resv_del(dev_id, entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Find a particular reserve Fdb entry through mac address + * @param[in] dev_id device id + * @param[in] entry reserve fdb entry + * @param[out] entry reserve fdb entry + * @return SW_OK or error code + */ +sw_error_t +fal_fdb_resv_find(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_fdb_resv_find(dev_id, entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Iterate all reserve fdb entries on a particular device. + * @param[in] dev_id device id + * @param[in] iterator reserve fdb entry index if it's zero means get the first entry + * @param[out] iterator next valid fdb entry index + * @param[out] entry reserve fdb entry + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_fdb_resv_iterate(dev_id, iterator, entry); + FAL_API_UNLOCK; + 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; + + FAL_API_LOCK; + rv = _fal_fdb_port_learn_static_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + 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; + + FAL_API_LOCK; + rv = _fal_fdb_port_learn_static_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Add a port to an exsiting entry + * @param[in] dev_id device id + * @param[in] fid filtering database id + * @param[in] addr MAC address + * @param[in] port_id port id + * @return SW_OK or error code, If entry not exist will return error. + */ +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; + + FAL_API_LOCK; + rv = _fal_fdb_port_add(dev_id, fid, addr, port_id); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a port from an exsiting entry + * @param[in] dev_id device id + * @param[in] fid filtering database id + * @param[in] addr MAC address + * @param[in] port_id port id + * @return SW_OK or error code, If entry not exist will return error. + */ +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; + + FAL_API_LOCK; + rv = _fal_fdb_port_del(dev_id, fid, addr, port_id); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Add a Fdb rfs entry + * @param[in] dev_id device id + * @param[in] entry fdb entry + * @return SW_OK or error code + */ +sw_error_t +fal_fdb_rfs_set(a_uint32_t dev_id, const fal_fdb_rfs_t * entry) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_fdb_rfs_set(dev_id, entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Del a Fdb rfs entry + * @param[in] dev_id device id + * @param[in] entry fdb entry + * @return SW_OK or error code + */ +sw_error_t +fal_fdb_rfs_del(a_uint32_t dev_id, const fal_fdb_rfs_t * entry) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_fdb_rfs_del(dev_id, entry); + FAL_API_UNLOCK; + return rv; +} + +int ssdk_rfs_mac_rule_set(u16 vid, u8* mac, u8 ldb, int is_set) +{ + fal_fdb_rfs_t entry; + memcpy(&entry.addr, mac, 6); + entry.fid = vid; + entry.load_balance = ldb; + if(is_set) + return fal_fdb_rfs_set(0, &entry); + else + return fal_fdb_rfs_del(0, &entry); +} +#endif + +#if 0 +int ssdk_rfs_mac_rule_set(ssdk_fdb_rfs_t *rfs) +{ + fal_fdb_rfs_t entry; + memcpy(&entry.addr, rfs->addr, 6); + entry.fid = rfs->fid; + entry.load_balance = rfs->load_balance; + return fal_fdb_rfs_set(0, &entry); +} + +int ssdk_rfs_mac_rule_del(ssdk_fdb_rfs_t *rfs) +{ + fal_fdb_rfs_t entry; + memcpy(&entry.addr, rfs->addr, 6); + entry.fid = rfs->fid; + entry.load_balance = rfs->load_balance; + return fal_fdb_rfs_del(0, &entry); +} + + +EXPORT_SYMBOL(ssdk_rfs_mac_rule_set); +EXPORT_SYMBOL(ssdk_rfs_mac_rule_del); +#endif + +sw_error_t +fal_fdb_learning_ctrl_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _fal_fdb_learning_ctrl_set(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +#ifndef IN_FDB_MINI +sw_error_t +fal_fdb_learning_ctrl_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _fal_fdb_learning_ctrl_get(dev_id, enable); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_fdb_port_learned_mac_counter_get(dev_id, port_id, cnt); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_fdb_port_maclimit_ctrl_set(dev_id, port_id, maclimit_ctrl); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_fdb_port_maclimit_ctrl_get(dev_id, port_id, maclimit_ctrl); + FAL_API_UNLOCK; + return rv; +} +#endif +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_fdb_entry_del_byfid(dev_id, fid, flag); + FAL_API_UNLOCK; + return rv; +} + +#ifndef IN_FDB_MINI + + EXPORT_SYMBOL(fal_fdb_entry_add); + +#endif + + EXPORT_SYMBOL(fal_fdb_entry_del_byport); + + + EXPORT_SYMBOL(fal_fdb_entry_del_bymac); + + + EXPORT_SYMBOL(fal_fdb_entry_search); + +#ifndef IN_FDB_MINI + + EXPORT_SYMBOL(fal_fdb_port_learn_get); + +#endif + + EXPORT_SYMBOL(fal_fdb_port_learning_ctrl_set); + + EXPORT_SYMBOL(fal_fdb_entry_flush); + + EXPORT_SYMBOL(fal_fdb_entry_getfirst); + +#ifndef IN_FDB_MINI + + EXPORT_SYMBOL(fal_fdb_entry_getnext); + +#endif + + EXPORT_SYMBOL(fal_fdb_port_learn_set); + + EXPORT_SYMBOL(fal_fdb_learning_ctrl_set); + +#ifndef IN_FDB_MINI + + EXPORT_SYMBOL(fal_fdb_learning_ctrl_get); + +#endif + + EXPORT_SYMBOL(fal_fdb_entry_getnext_byindex); + + EXPORT_SYMBOL(fal_fdb_entry_extend_getnext); + + EXPORT_SYMBOL(fal_fdb_entry_extend_getfirst); + +#ifndef IN_FDB_MINI + + EXPORT_SYMBOL(fal_fdb_port_learning_ctrl_get); + +#endif + + EXPORT_SYMBOL(fal_fdb_port_stamove_ctrl_set); + +#ifndef IN_FDB_MINI + + EXPORT_SYMBOL(fal_fdb_port_stamove_ctrl_get); + +#endif + + EXPORT_SYMBOL(fal_fdb_aging_ctrl_set); + +#ifndef IN_FDB_MINI + + EXPORT_SYMBOL(fal_fdb_aging_ctrl_get); + + EXPORT_SYMBOL(fal_fdb_aging_time_set); + + EXPORT_SYMBOL(fal_fdb_aging_time_get); + + EXPORT_SYMBOL(fal_fdb_entry_update_byport); + + EXPORT_SYMBOL(fal_port_fdb_learn_limit_set); + + EXPORT_SYMBOL(fal_port_fdb_learn_limit_get); + + EXPORT_SYMBOL(fal_port_fdb_learn_exceed_cmd_set); + + EXPORT_SYMBOL(fal_port_fdb_learn_exceed_cmd_get); + + EXPORT_SYMBOL(fal_fdb_port_add); + + EXPORT_SYMBOL(fal_fdb_port_del); + + EXPORT_SYMBOL(fal_fdb_port_maclimit_ctrl_set); + + EXPORT_SYMBOL(fal_fdb_port_maclimit_ctrl_get); + +#endif + + EXPORT_SYMBOL(fal_fdb_entry_del_byfid); + +#ifndef IN_FDB_MINI + + EXPORT_SYMBOL(fal_fdb_port_learned_mac_counter_get); + +#endif + +/*insert flag for outter fal, don't remove it*/ + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/fal/fal_flow.c b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_flow.c new file mode 100755 index 000000000..4178e7d12 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_flow.c @@ -0,0 +1,467 @@ +/* + * 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 FAL_FLOW + * @{ + */ +#include "sw.h" +#include "fal_flow.h" +#include "hsl_api.h" +#include "adpt.h" + +#ifndef IN_FLOW_MINI +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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_flow_host_add) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_flow_host_add(dev_id, add_mode, flow_host_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_flow_entry_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_flow_entry_get(dev_id, get_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_flow_entry_del) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_flow_entry_next) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_flow_entry_next(dev_id, next_mode, flow_entry); + return rv; +} +sw_error_t +_fal_flow_status_get(a_uint32_t dev_id, a_bool_t *enable) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_flow_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_flow_status_get(dev_id, enable); + return rv; +} +#endif +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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_flow_ctrl_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_flow_ctrl_set(dev_id, type, dir, mgmt); + return rv; +} +#ifndef IN_FLOW_MINI +sw_error_t +_fal_flow_age_timer_get(a_uint32_t dev_id, fal_flow_age_timer_t *age_timer) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_flow_age_timer_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_flow_age_timer_get(dev_id, age_timer); + return rv; +} +sw_error_t +_fal_flow_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_flow_status_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_flow_status_set(dev_id, enable); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_flow_host_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_flow_host_get(dev_id, get_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_flow_host_del) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_flow_host_del(dev_id, del_mode, flow_host_entry); + return rv; +} +#endif +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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_flow_ctrl_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_flow_ctrl_get(dev_id, type, dir, mgmt); + return rv; +} +#ifndef IN_FLOW_MINI +sw_error_t +_fal_flow_age_timer_set(a_uint32_t dev_id, fal_flow_age_timer_t *age_timer) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_flow_age_timer_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_flow_age_timer_set(dev_id, age_timer); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_flow_entry_add) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_flow_entry_add(dev_id, add_mode, flow_entry); + return rv; +} + +sw_error_t +_fal_flow_global_cfg_get( + a_uint32_t dev_id, + fal_flow_global_cfg_t *cfg) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_flow_global_cfg_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_flow_global_cfg_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_flow_global_cfg_set(dev_id, cfg); + return rv; +} +/*insert flag for inner fal, don't remove it*/ + +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 rv = SW_OK; + + FAL_API_LOCK; + rv = _fal_flow_host_add(dev_id, add_mode, flow_host_entry); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_flow_entry_get(dev_id, get_mode, flow_entry); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_flow_entry_del(dev_id, del_mode, flow_entry); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_flow_entry_next(dev_id, next_mode, flow_entry); + FAL_API_UNLOCK; + return rv; +} +sw_error_t +fal_flow_status_get(a_uint32_t dev_id, a_bool_t *enable) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _fal_flow_status_get(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} +#endif +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_flow_mgmt_set(dev_id, type, dir, mgmt); + FAL_API_UNLOCK; + return rv; +} +#ifndef IN_FLOW_MINI +sw_error_t +fal_flow_age_timer_get(a_uint32_t dev_id, fal_flow_age_timer_t *age_timer) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _fal_flow_age_timer_get(dev_id, age_timer); + FAL_API_UNLOCK; + return rv; +} +sw_error_t +fal_flow_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _fal_flow_status_set(dev_id, enable); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_flow_host_get(dev_id, get_mode, flow_host_entry); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_flow_host_del(dev_id, del_mode, flow_host_entry); + FAL_API_UNLOCK; + return rv; +} +#endif +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_flow_mgmt_get(dev_id, type, dir, mgmt); + FAL_API_UNLOCK; + return rv; +} +#ifndef IN_FLOW_MINI +sw_error_t +fal_flow_age_timer_set(a_uint32_t dev_id, fal_flow_age_timer_t *age_timer) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _fal_flow_age_timer_set(dev_id, age_timer); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_flow_entry_add(dev_id, add_mode, flow_entry); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_flow_global_cfg_get(dev_id, cfg); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_flow_global_cfg_set(dev_id, cfg); + FAL_API_UNLOCK; + return rv; +} +#endif +/*insert flag for outter fal, don't remove it*/ diff --git a/feeds/ipq807x/qca-ssdk/src/src/fal/fal_igmp.c b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_igmp.c new file mode 100755 index 000000000..c861fc879 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_igmp.c @@ -0,0 +1,961 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 +* @{ +*/ +#include "sw.h" +#include "fal_igmp.h" +#include "hsl_api.h" + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_igmps_status_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_igmps_status_set(dev_id, port_id, enable); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_igmps_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_igmps_status_get(dev_id, port_id, enable); + return rv; +} + + +static sw_error_t +_fal_igmp_mld_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->igmp_mld_cmd_set) + return SW_NOT_SUPPORTED; + + rv = p_api->igmp_mld_cmd_set(dev_id, cmd); + return rv; +} + + +static sw_error_t +_fal_igmp_mld_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->igmp_mld_cmd_get) + return SW_NOT_SUPPORTED; + + rv = p_api->igmp_mld_cmd_get(dev_id, cmd); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_igmp_join_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_igmp_join_set(dev_id, port_id, enable); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_igmp_join_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_igmp_join_get(dev_id, port_id, enable); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_igmp_leave_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_igmp_leave_set(dev_id, port_id, enable); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_igmp_leave_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_igmp_leave_get(dev_id, port_id, enable); + return rv; +} + + +static sw_error_t +_fal_igmp_mld_rp_set(a_uint32_t dev_id, fal_pbmp_t pts) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->igmp_rp_set) + return SW_NOT_SUPPORTED; + + rv = p_api->igmp_rp_set(dev_id, pts); + return rv; +} + + +static sw_error_t +_fal_igmp_mld_rp_get(a_uint32_t dev_id, fal_pbmp_t * pts) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->igmp_rp_get) + return SW_NOT_SUPPORTED; + + rv = p_api->igmp_rp_get(dev_id, pts); + return rv; +} + + +static sw_error_t +_fal_igmp_mld_entry_creat_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->igmp_entry_creat_set) + return SW_NOT_SUPPORTED; + + rv = p_api->igmp_entry_creat_set(dev_id, enable); + return rv; +} + + +static sw_error_t +_fal_igmp_mld_entry_creat_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->igmp_entry_creat_get) + return SW_NOT_SUPPORTED; + + rv = p_api->igmp_entry_creat_get(dev_id, enable); + return rv; +} + +static sw_error_t +_fal_igmp_mld_entry_static_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->igmp_entry_static_set) + return SW_NOT_SUPPORTED; + + rv = p_api->igmp_entry_static_set(dev_id, enable); + return rv; +} + +static sw_error_t +_fal_igmp_mld_entry_static_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->igmp_entry_static_get) + return SW_NOT_SUPPORTED; + + rv = p_api->igmp_entry_static_get(dev_id, enable); + return rv; +} + +static sw_error_t +_fal_igmp_mld_entry_leaky_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->igmp_entry_leaky_set) + return SW_NOT_SUPPORTED; + + rv = p_api->igmp_entry_leaky_set(dev_id, enable); + return rv; +} + +static sw_error_t +_fal_igmp_mld_entry_leaky_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->igmp_entry_leaky_get) + return SW_NOT_SUPPORTED; + + rv = p_api->igmp_entry_leaky_get(dev_id, enable); + return rv; +} + +static sw_error_t +_fal_igmp_mld_entry_v3_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->igmp_entry_v3_set) + return SW_NOT_SUPPORTED; + + rv = p_api->igmp_entry_v3_set(dev_id, enable); + return rv; +} + +static sw_error_t +_fal_igmp_mld_entry_v3_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->igmp_entry_v3_get) + return SW_NOT_SUPPORTED; + + rv = p_api->igmp_entry_v3_get(dev_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->igmp_entry_queue_set) + return SW_NOT_SUPPORTED; + + rv = p_api->igmp_entry_queue_set(dev_id, enable, queue); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->igmp_entry_queue_get) + return SW_NOT_SUPPORTED; + + rv = p_api->igmp_entry_queue_get(dev_id, enable, queue); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_igmp_mld_learn_limit_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_igmp_mld_learn_limit_set(dev_id, port_id, enable, cnt); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_igmp_mld_learn_limit_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_igmp_mld_learn_limit_get(dev_id, port_id, enable, cnt); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_igmp_mld_learn_exceed_cmd_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_igmp_mld_learn_exceed_cmd_set(dev_id, port_id, cmd); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_igmp_mld_learn_exceed_cmd_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_igmp_mld_learn_exceed_cmd_get(dev_id, port_id, cmd); + return rv; +} + +static sw_error_t +_fal_igmp_sg_entry_set(a_uint32_t dev_id, fal_igmp_sg_entry_t * entry) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->igmp_sg_entry_set) + return SW_NOT_SUPPORTED; + + rv = p_api->igmp_sg_entry_set(dev_id, entry); + return rv; +} +static sw_error_t +_fal_igmp_sg_entry_clear(a_uint32_t dev_id, fal_igmp_sg_entry_t * entry) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->igmp_sg_entry_clear) + return SW_NOT_SUPPORTED; + + rv = p_api->igmp_sg_entry_clear(dev_id, entry); + return rv; +} +static sw_error_t +_fal_igmp_sg_entry_show(a_uint32_t dev_id) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->igmp_sg_entry_show) + return SW_NOT_SUPPORTED; + + rv = p_api->igmp_sg_entry_show(dev_id); + return rv; +} +static sw_error_t +_fal_igmp_sg_entry_query(a_uint32_t dev_id, fal_igmp_sg_info_t * info) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->igmp_sg_entry_query) + return SW_NOT_SUPPORTED; + + rv = p_api->igmp_sg_entry_query(dev_id, info); + return rv; +} +/** + * @brief Set igmp/mld packets snooping status on a particular port. + * @details Comments: + * After enabling igmp/mld snooping feature on a particular port all kinds + * igmp/mld packets received on this port would be acknowledged by hardware. + * Particular forwarding decision could be setted by fal_igmp_mld_cmd_set. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_igmps_status_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld packets snooping status on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_igmps_status_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmp/mld packets forwarding command on a particular device. + * @details Comments: + * Particular device may only support parts of forwarding commands. + * This operation will take effect only after enabling igmp/mld snooping + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +sw_error_t +fal_igmp_mld_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_igmp_mld_cmd_set(dev_id, cmd); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld packets forwarding command on a particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +sw_error_t +fal_igmp_mld_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_igmp_mld_cmd_get(dev_id, cmd); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmp/mld join packets hardware acknowledgement status on particular port. + * @details Comments: + * After enabling igmp/mld join feature on a particular port hardware will + * dynamic learning or changing multicast entry. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_igmp_mld_join_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld join packets hardware acknowledgement status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_igmp_mld_join_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmp/mld leave packets hardware acknowledgement status on a particular port. + * @details Comments: + * After enabling igmp join feature on a particular port hardware will dynamic + * deleting or changing multicast entry. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_igmp_mld_leave_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld leave packets hardware acknowledgement status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_igmp_mld_leave_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmp/mld router ports on a particular device. + * @details Comments: + * After enabling igmp/mld join/leave feature on a particular port igmp/mld + * join/leave packets received on this port will be forwarded to router ports. + * @param[in] dev_id device id + * @param[in] pts dedicates ports + * @return SW_OK or error code + */ +sw_error_t +fal_igmp_mld_rp_set(a_uint32_t dev_id, fal_pbmp_t pts) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_igmp_mld_rp_set(dev_id, pts); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld router ports on a particular device. + * @param[in] dev_id device id + * @param[out] pts dedicates ports + * @return SW_OK or error code + */ +sw_error_t +fal_igmp_mld_rp_get(a_uint32_t dev_id, fal_pbmp_t * pts) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_igmp_mld_rp_get(dev_id, pts); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set the status of creating multicast entry during igmp/mld join/leave procedure. + * @details Comments: + * After enabling igmp/mld join/leave feature on a particular port if enable + * entry creat hardware will dynamic creat and delete multicast entry, + * otherwise hardware only can change destination ports of existing muticast entry. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_igmp_mld_entry_creat_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_igmp_mld_entry_creat_set(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get the status of creating multicast entry during igmp/mld join/leave procedure. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_igmp_mld_entry_creat_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_igmp_mld_entry_creat_get(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set the static status of multicast entry which learned by hardware. + * @details Comments: + * After enabling igmp/mld join/leave feature on a particular port if enable + * static status hardware will not age out multicast entry which leardned by hardware, + * otherwise hardware will age out multicast entry which leardned by hardware. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_igmp_mld_entry_static_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_igmp_mld_entry_static_set(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get the static status of multicast entry which learned by hardware. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_igmp_mld_entry_static_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_igmp_mld_entry_static_get(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set the leaky status of multicast entry which learned by hardware. + * @details Comments: + * After enabling igmp/mld join/leave feature on a particular port if enable + * leaky status hardware will set leaky flag of multicast entry which leardned by hardware, + * otherwise hardware will not set leaky flag of multicast entry which leardned by hardware. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_igmp_mld_entry_leaky_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_igmp_mld_entry_leaky_set(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get the leaky status of multicast entry which learned by hardware. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_igmp_mld_entry_leaky_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_igmp_mld_entry_leaky_get(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmpv3/mldv2 packets hardware acknowledgement status on a particular device. + * @details Comments: + * After enabling igmp join/leave feature on a particular port hardware will dynamic + * creating or changing multicast entry after receiving igmpv3/mldv2 packets. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_igmp_mld_entry_v3_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_igmp_mld_entry_v3_set(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmpv3/mldv2 packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_igmp_mld_entry_v3_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_igmp_mld_entry_v3_get(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set the queue status of multicast entry which learned by hardware. + * @details Comments: + * After enabling igmp/mld join/leave feature on a particular port if enable + * leaky status hardware will set queue flag of multicast entry which leardned by hardware, + * otherwise hardware will not set queue flag of multicast entry which leardned by hardware. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] queue queue id + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_igmp_mld_entry_queue_set(dev_id, enable, queue); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get the queue status of multicast entry which learned by hardware. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @param[out] queue queue id + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_igmp_mld_entry_queue_get(dev_id, enable, queue); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set IGMP hardware learning count limit on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] cnt limit count + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_igmp_mld_learn_limit_set(dev_id, port_id, enable, cnt); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IGMP hardware learning count limit on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @param[out] cnt limit count + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_igmp_mld_learn_limit_get(dev_id, port_id, enable, cnt); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set IGMP hardware learning count exceed command on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_igmp_mld_learn_exceed_cmd_set(dev_id, port_id, cmd); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IGMP hardware learning count exceed command on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_igmp_mld_learn_exceed_cmd_get(dev_id, port_id, cmd); + FAL_API_UNLOCK; + 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; + + FAL_API_LOCK; + rv = _fal_igmp_sg_entry_set(dev_id, entry); + FAL_API_UNLOCK; + 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; + + FAL_API_LOCK; + rv = _fal_igmp_sg_entry_clear(dev_id, entry); + FAL_API_UNLOCK; + return rv; +} +sw_error_t +fal_igmp_sg_entry_show(a_uint32_t dev_id) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_igmp_sg_entry_show(dev_id); + FAL_API_UNLOCK; + 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; + + FAL_API_LOCK; + rv = _fal_igmp_sg_entry_query(dev_id, info); + FAL_API_UNLOCK; + return rv; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/fal/fal_init.c b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_init.c new file mode 100755 index 000000000..16882a1fa --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_init.c @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2012, 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 + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_api.h" +/*qca808x_end*/ +#include "fal_vlan.h" +#include "adpt.h" +/*qca808x_start*/ +/** + * @brief Init fal layer. + * @details Comments: + * This operation will init fal layer and hsl layer + * @param[in] dev_id device id + * @param[in] cfg configuration for initialization + * @return SW_OK or error code + */ +sw_error_t +fal_init(a_uint32_t dev_id, ssdk_init_cfg *cfg) +{ + sw_error_t rv; + HSL_DEV_ID_CHECK(dev_id); + + rv = hsl_api_init(dev_id); + SW_RTN_ON_ERROR(rv); + + rv = hsl_dev_init(dev_id, cfg); + SW_RTN_ON_ERROR(rv); +/*qca808x_end*/ +#ifdef IN_VLAN + rv = fal_vlan_init(dev_id); + SW_RTN_ON_ERROR(rv); +#endif + + rv = adpt_init(dev_id, cfg); + SW_RTN_ON_ERROR(rv); +/*qca808x_start*/ + + return rv; +} +/*qca808x_end*/ + +static sw_error_t +_fal_reset(a_uint32_t dev_id) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->dev_reset) + return SW_NOT_SUPPORTED; + +#ifdef IN_VLAN + rv = fal_vlan_reset(dev_id); + SW_RTN_ON_ERROR(rv); +#endif + + rv = p_api->dev_reset(dev_id); + return rv; +} + +static sw_error_t +_fal_ssdk_cfg(a_uint32_t dev_id, ssdk_cfg_t *ssdk_cfg) +{ + sw_error_t rv; + HSL_DEV_ID_CHECK(dev_id); + + rv = hsl_ssdk_cfg(dev_id, ssdk_cfg); + + return rv; +} + +static sw_error_t +_fal_module_func_ctrl_set(a_uint32_t dev_id, a_uint32_t module, fal_func_ctrl_t *func_ctrl) +{ + return adpt_module_func_ctrl_set(dev_id, module, func_ctrl); +} + +static sw_error_t +_fal_module_func_ctrl_get(a_uint32_t dev_id, a_uint32_t module, fal_func_ctrl_t *func_ctrl) +{ + return adpt_module_func_ctrl_get(dev_id, module, func_ctrl); +} +/*qca808x_start*/ +sw_error_t +fal_cleanup(void) +{ + sw_error_t rv; + + rv = hsl_dev_cleanup(); + SW_RTN_ON_ERROR(rv); +/*qca808x_end*/ +#ifdef IN_VLAN + rv = fal_vlan_cleanup(); + SW_RTN_ON_ERROR(rv); +#endif +/*qca808x_start*/ + return SW_OK; +} +/*qca808x_end*/ +/** + * @brief Reset fal layer. + * @details Comments: + * This operation will reset fal layer and hsl layer + * @param[in] dev_id device id + * @return SW_OK or error code + */ +sw_error_t +fal_reset(a_uint32_t dev_id) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_reset(dev_id); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get SSDK config infomation. + * @param[in] dev_id device id + * @param[out] ssdk_cfg SSDK config infomation + * @return SW_OK or error code + */ +sw_error_t +fal_ssdk_cfg(a_uint32_t dev_id, ssdk_cfg_t *ssdk_cfg) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_ssdk_cfg(dev_id, ssdk_cfg); + FAL_API_UNLOCK; + return rv; +} + +sw_error_t +fal_switch_devid_get(ssdk_chip_type chip_type, a_uint32_t *pdev_id) +{ + sw_error_t rv = SW_OK; + ssdk_cfg_t cfg = {0}; + a_uint32_t dev_id = 0; + + for(dev_id = 0; dev_id < SW_MAX_NR_DEV; dev_id++) { + rv = _fal_ssdk_cfg(dev_id, &cfg); + if(rv == SW_OK && cfg.init_cfg.chip_type == chip_type) { + *pdev_id = dev_id; + return rv; + } + } + return SW_FAIL; +} + +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; + + FAL_API_LOCK; + rv = _fal_module_func_ctrl_set(dev_id, module, func_ctrl); + FAL_API_UNLOCK; + 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; + + FAL_API_LOCK; + rv = _fal_module_func_ctrl_get(dev_id, module, func_ctrl); + FAL_API_UNLOCK; + return rv; +} + +sw_error_t +fal_module_func_init(a_uint32_t dev_id, ssdk_init_cfg *cfg) +{ + sw_error_t rv; + HSL_DEV_ID_CHECK(dev_id); + + rv = adpt_module_func_init(dev_id, cfg); + SW_RTN_ON_ERROR(rv); + + return rv; +} + +EXPORT_SYMBOL(fal_switch_devid_get); +EXPORT_SYMBOL(fal_module_func_ctrl_set); +EXPORT_SYMBOL(fal_module_func_ctrl_get); + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/fal/fal_interface_ctrl.c b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_interface_ctrl.c new file mode 100755 index 000000000..85cc1008e --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_interface_ctrl.c @@ -0,0 +1,386 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 + * @{ + */ +#include "sw.h" +#include "fal_interface_ctrl.h" +#include "hsl_api.h" + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_3az_status_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_3az_status_set(dev_id, port_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_3az_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_3az_status_get(dev_id, port_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->interface_mac_mode_set) + return SW_NOT_SUPPORTED; + + rv = p_api->interface_mac_mode_set(dev_id, port_id, config); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->interface_mac_mode_get) + return SW_NOT_SUPPORTED; + + rv = p_api->interface_mac_mode_get(dev_id, port_id, config); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->interface_phy_mode_set) + return SW_NOT_SUPPORTED; + + rv = p_api->interface_phy_mode_set(dev_id, phy_id, config); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->interface_phy_mode_get) + return SW_NOT_SUPPORTED; + + rv = p_api->interface_phy_mode_get(dev_id, phy_id, config); + return rv; +} + +static sw_error_t +_fal_interface_fx100_ctrl_set(a_uint32_t dev_id, fal_fx100_ctrl_config_t * config) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->interface_fx100_ctrl_set) + return SW_NOT_SUPPORTED; + + rv = p_api->interface_fx100_ctrl_set(dev_id, config); + return rv; +} + +static sw_error_t +_fal_interface_fx100_ctrl_get(a_uint32_t dev_id, fal_fx100_ctrl_config_t * config) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->interface_fx100_ctrl_get) + return SW_NOT_SUPPORTED; + + rv = p_api->interface_fx100_ctrl_get(dev_id, config); + return rv; +} + +static sw_error_t +_fal_interface_fx100_status_get(a_uint32_t dev_id, a_uint32_t* status) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->interface_fx100_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->interface_fx100_status_get(dev_id, status); + return rv; +} + +static sw_error_t +_fal_interface_mac06_exch_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->interface_mac06_exch_set) + return SW_NOT_SUPPORTED; + + rv = p_api->interface_mac06_exch_set(dev_id, enable); + return rv; +} + +static sw_error_t +_fal_interface_mac06_exch_get(a_uint32_t dev_id, a_bool_t* enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->interface_mac06_exch_get) + return SW_NOT_SUPPORTED; + + rv = p_api->interface_mac06_exch_get(dev_id, enable); + return rv; +} + +/** + * @brief Set 802.3az status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_3az_status_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get 802.3az status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_3az_status_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set interface mode on a particular MAC device. + * @param[in] dev_id device id + * @param[in] mca_id MAC device ID + * @param[in] config interface configuration + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_interface_mac_mode_set(dev_id, port_id, config); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get interface mode on a particular MAC device. + * @param[in] dev_id device id + * @param[in] mca_id MAC device ID + * @param[out] config interface configuration + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_interface_mac_mode_get(dev_id, port_id, config); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set interface phy mode on a particular PHY device. + * @param[in] dev_id device id + * @param[in] phy_id PHY device ID + * @param[in] config interface configuration + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_interface_phy_mode_set(dev_id, phy_id, config); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get interface phy mode on a particular PHY device. + * @param[in] dev_id device id + * @param[in] phy_id PHY device ID + * @param[out] config interface configuration + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_interface_phy_mode_get(dev_id, phy_id, config); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set fx100 control configuration. + * @param[in] dev_id device id + * @param[in] config fx100 control configuration + * @return SW_OK or error code + */ +sw_error_t +fal_interface_fx100_ctrl_set(a_uint32_t dev_id, fal_fx100_ctrl_config_t * config) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_interface_fx100_ctrl_set(dev_id, config); + FAL_API_UNLOCK; + return rv; +} + + +/** + * @brief Get fx100 control configuration. + * @param[in] dev_id device id + * @param[out] config fx100 control configuration + * @return SW_OK or error code + */ +sw_error_t +fal_interface_fx100_ctrl_get(a_uint32_t dev_id, fal_fx100_ctrl_config_t * config) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_interface_fx100_ctrl_get(dev_id, config); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get fx100 control configuration. + * @param[in] dev_id device id + * @param[out] fx100 status + * @return SW_OK or error code + */ +sw_error_t +fal_interface_fx100_status_get(a_uint32_t dev_id, a_uint32_t* status) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_interface_fx100_status_get(dev_id, status); + FAL_API_UNLOCK; + return rv; +} + + +/** + * @brief Set mac0 and mac6 exchange status. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_interface_mac06_exch_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_interface_mac06_exch_set(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mac0 and mac6 exchange status. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_interface_mac06_exch_get(a_uint32_t dev_id, a_bool_t* enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_interface_mac06_exch_get(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/fal/fal_ip.c b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_ip.c new file mode 100755 index 000000000..917d31232 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_ip.c @@ -0,0 +1,2370 @@ +/* + * Copyright (c) 2012, 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 + * @{ + */ +#include "sw.h" +#include "fal_ip.h" +#include "hsl_api.h" +#include "adpt.h" + +#include +#include + +#ifndef IN_IP_MINI +static sw_error_t +_fal_ip_host_add(a_uint32_t dev_id, fal_host_entry_t * host_entry) +{ + sw_error_t rv; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_ip_host_add) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_ip_host_add(dev_id, host_entry); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_host_add) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_host_add(dev_id, host_entry); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_ip_host_del) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_ip_host_del(dev_id, del_mode, host_entry); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_host_del) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_host_del(dev_id, del_mode, host_entry); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_ip_host_get) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_ip_host_get(dev_id, get_mode, host_entry); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_host_get) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_host_get(dev_id, get_mode, host_entry); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_ip_host_next) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_ip_host_next(dev_id, next_mode, host_entry); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_host_next) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_host_next(dev_id, next_mode, host_entry); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_host_counter_bind) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_host_counter_bind(dev_id, entry_id, cnt_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_host_pppoe_bind) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_host_pppoe_bind(dev_id, entry_id, pppoe_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_pt_arp_learn_set) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_pt_arp_learn_set(dev_id, port_id, flags); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_pt_arp_learn_get) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_pt_arp_learn_get(dev_id, port_id, flags); + return rv; +} + +static sw_error_t +_fal_ip_arp_learn_set(a_uint32_t dev_id, fal_arp_learn_mode_t mode) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_arp_learn_set) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_arp_learn_set(dev_id, mode); + return rv; +} + +static sw_error_t +_fal_ip_arp_learn_get(a_uint32_t dev_id, fal_arp_learn_mode_t * mode) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_arp_learn_get) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_arp_learn_get(dev_id, mode); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_source_guard_set) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_source_guard_set(dev_id, port_id, mode); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_source_guard_get) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_source_guard_get(dev_id, port_id, mode); + return rv; +} + +static sw_error_t +_fal_ip_unk_source_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_unk_source_cmd_set) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_unk_source_cmd_set(dev_id, cmd); + return rv; +} + +static sw_error_t +_fal_ip_unk_source_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_unk_source_cmd_get) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_unk_source_cmd_get(dev_id, cmd); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_arp_guard_set) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_arp_guard_set(dev_id, port_id, mode); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_arp_guard_get) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_arp_guard_get(dev_id, port_id, mode); + return rv; +} + +static sw_error_t +_fal_arp_unk_source_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->arp_unk_source_cmd_set) + return SW_NOT_SUPPORTED; + + rv = p_api->arp_unk_source_cmd_set(dev_id, cmd); + return rv; +} + +static sw_error_t +_fal_arp_unk_source_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->arp_unk_source_cmd_get) + return SW_NOT_SUPPORTED; + + rv = p_api->arp_unk_source_cmd_get(dev_id, cmd); + return rv; +} + +static sw_error_t +_fal_ip_route_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_route_status_set) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_route_status_set(dev_id, enable); + return rv; +} + +static sw_error_t +_fal_ip_route_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_route_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_route_status_get(dev_id, enable); + return rv; +} + +static sw_error_t +_fal_ip_intf_entry_add(a_uint32_t dev_id, fal_intf_mac_entry_t * entry) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_intf_entry_add) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_intf_entry_add(dev_id, entry); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_intf_entry_del) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_intf_entry_del(dev_id, del_mode, entry); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_intf_entry_next) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_intf_entry_next(dev_id, next_mode, entry); + return rv; +} + +static sw_error_t +_fal_ip_age_time_set(a_uint32_t dev_id, a_uint32_t * time) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_age_time_set) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_age_time_set(dev_id, time); + return rv; +} + +static sw_error_t +_fal_ip_age_time_get(a_uint32_t dev_id, a_uint32_t * time) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_age_time_get) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_age_time_get(dev_id, time); + return rv; +} + +static sw_error_t +_fal_ip_wcmp_hash_mode_set(a_uint32_t dev_id, a_uint32_t hash_mode) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_wcmp_hash_mode_set) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_wcmp_hash_mode_set(dev_id, hash_mode); + return rv; +} + +static sw_error_t +_fal_ip_wcmp_hash_mode_get(a_uint32_t dev_id, a_uint32_t * hash_mode) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_wcmp_hash_mode_get) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_wcmp_hash_mode_get(dev_id, hash_mode); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_vrf_base_addr_set) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_vrf_base_addr_set(dev_id, vrf_id, addr); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_vrf_base_addr_get) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_vrf_base_addr_get(dev_id, vrf_id, addr); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_vrf_base_mask_set) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_vrf_base_mask_set(dev_id, vrf_id, addr); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_vrf_base_mask_get) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_vrf_base_mask_get(dev_id, vrf_id, addr); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_default_route_set) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_default_route_set(dev_id, droute_id, entry); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_default_route_get) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_default_route_get(dev_id, droute_id, entry); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_host_route_set) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_host_route_set(dev_id, hroute_id, entry); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_host_route_get) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_host_route_get(dev_id, hroute_id, entry); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_wcmp_entry_set) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_wcmp_entry_set(dev_id, wcmp_id, wcmp); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_wcmp_entry_get) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_wcmp_entry_get(dev_id, wcmp_id, wcmp); + return rv; +} + +static sw_error_t +_fal_ip_rfs_ip4_rule_set(a_uint32_t dev_id, fal_ip4_rfs_t * rfs) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_rfs_ip4_set) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_rfs_ip4_set(dev_id, rfs); + return rv; +} + +static sw_error_t +_fal_ip_rfs_ip6_rule_set(a_uint32_t dev_id, fal_ip6_rfs_t * rfs) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_rfs_ip6_set) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_rfs_ip6_set(dev_id, rfs); + return rv; +} + +static sw_error_t +_fal_ip_rfs_ip4_rule_del(a_uint32_t dev_id, fal_ip4_rfs_t * rfs) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_rfs_ip4_del) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_rfs_ip4_del(dev_id, rfs); + return rv; +} + +static sw_error_t +_fal_ip_rfs_ip6_rule_del(a_uint32_t dev_id, fal_ip6_rfs_t * rfs) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_rfs_ip6_del) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_rfs_ip6_del(dev_id, rfs); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_default_flow_cmd_set) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_default_flow_cmd_set(dev_id, vrf_id, type, 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_default_flow_cmd_get) + return SW_NOT_SUPPORTED; + + rv = p_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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_default_rt_flow_cmd_set) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_default_rt_flow_cmd_set(dev_id, vrf_id, type, 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ip_default_rt_flow_cmd_get) + return SW_NOT_SUPPORTED; + + rv = p_api->ip_default_rt_flow_cmd_get(dev_id, vrf_id, type, cmd); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ip_network_route_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ip_network_route_get(dev_id, index, type, entry); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ip_vsi_sg_cfg_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ip_vsi_sg_cfg_get(dev_id, vsi, sg_cfg); + return rv; +} + +sw_error_t +_fal_ip_network_route_del(a_uint32_t dev_id, + a_uint32_t index, a_uint8_t type) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ip_network_route_del) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ip_network_route_del(dev_id, index, type); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ip_port_sg_cfg_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ip_port_sg_cfg_set(dev_id, port_id, sg_cfg); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ip_port_intf_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ip_port_intf_get(dev_id, port_id, id); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ip_vsi_arp_sg_cfg_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ip_vsi_arp_sg_cfg_set(dev_id, vsi, arp_sg_cfg); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ip_pub_addr_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ip_pub_addr_get(dev_id, index, entry); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ip_port_intf_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ip_port_intf_set(dev_id, port_id, id); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ip_vsi_sg_cfg_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ip_vsi_sg_cfg_set(dev_id, vsi, sg_cfg); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ip_port_macaddr_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ip_port_macaddr_set(dev_id, port_id, macaddr); + return rv; +} +sw_error_t +_fal_ip_vsi_intf_get(a_uint32_t dev_id, a_uint32_t vsi, fal_intf_id_t *id) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ip_vsi_intf_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ip_vsi_intf_get(dev_id, vsi, id); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ip_network_route_add) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ip_network_route_add(dev_id, index, entry); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ip_port_sg_cfg_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ip_port_sg_cfg_get(dev_id, port_id, sg_cfg); + return rv; +} +sw_error_t +_fal_ip_intf_get( + a_uint32_t dev_id, + a_uint32_t index, + fal_intf_entry_t *entry) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ip_intf_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ip_intf_get(dev_id, index, entry); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ip_pub_addr_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ip_pub_addr_set(dev_id, index, entry); + return rv; +} +sw_error_t +_fal_ip_route_mismatch_get(a_uint32_t dev_id, fal_fwd_cmd_t *cmd) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ip_route_mismatch_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ip_route_mismatch_get(dev_id, cmd); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ip_vsi_arp_sg_cfg_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ip_vsi_arp_sg_cfg_get(dev_id, vsi, arp_sg_cfg); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ip_port_arp_sg_cfg_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ip_port_arp_sg_cfg_set(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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ip_vsi_mc_mode_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ip_vsi_mc_mode_set(dev_id, vsi, cfg); + return rv; +} +sw_error_t +_fal_ip_vsi_intf_set(a_uint32_t dev_id, a_uint32_t vsi, fal_intf_id_t *id) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ip_vsi_intf_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ip_vsi_intf_set(dev_id, vsi, id); + return rv; +} +sw_error_t +_fal_ip_nexthop_get(a_uint32_t dev_id, a_uint32_t index, fal_ip_nexthop_t *entry) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ip_nexthop_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ip_nexthop_get(dev_id, index, entry); + return rv; +} +sw_error_t +_fal_ip_route_mismatch_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ip_route_mismatch_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ip_route_mismatch_set(dev_id, cmd); + return rv; +} +sw_error_t +_fal_ip_intf_set( + a_uint32_t dev_id, + a_uint32_t index, + fal_intf_entry_t *entry) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ip_intf_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ip_intf_set(dev_id, index, entry); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ip_vsi_mc_mode_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ip_vsi_mc_mode_get(dev_id, vsi, cfg); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ip_port_macaddr_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ip_port_macaddr_get(dev_id, port_id, macaddr); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ip_port_arp_sg_cfg_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ip_port_arp_sg_cfg_get(dev_id, port_id, arp_sg_cfg); + return rv; +} +sw_error_t +_fal_ip_nexthop_set(a_uint32_t dev_id, + a_uint32_t index, fal_ip_nexthop_t *entry) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ip_nexthop_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ip_nexthop_set(dev_id, index, entry); + return rv; +} + +sw_error_t +_fal_ip_global_ctrl_set(a_uint32_t dev_id, fal_ip_global_cfg_t *cfg) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ip_global_ctrl_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ip_global_ctrl_set(dev_id, cfg); + return rv; +} + +sw_error_t +_fal_ip_global_ctrl_get(a_uint32_t dev_id, fal_ip_global_cfg_t *cfg) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ip_global_ctrl_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ip_global_ctrl_get(dev_id, cfg); + return rv; +} + +/*insert flag for inner fal, don't remove it*/ + +/** + * @brief Add one host entry to one particular device. + * @details Comments: + * For ISIS the intf_id parameter in host_entry means vlan id. + Before host entry added related interface entry and ip6 base address + must be set at first. + Hardware entry id will be returned. + * @param[in] dev_id device id + * @param[in] host_entry host entry parameter + * @return SW_OK or error code + */ +sw_error_t +fal_ip_host_add(a_uint32_t dev_id, fal_host_entry_t * host_entry) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_ip_host_add(dev_id, host_entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete one host entry from one particular device. + * @details Comments: + * For ISIS the intf_id parameter in host_entry means vlan id. + Before host entry deleted related interface entry and ip6 base address + must be set atfirst. + For del_mode please refer IP entry operation flags. + * @param[in] dev_id device id + * @param[in] del_mode delete operation mode + * @param[in] host_entry host entry parameter + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_ip_host_del(dev_id, del_mode, host_entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get one host entry from one particular device. + * @details Comments: + * For ISIS the intf_id parameter in host_entry means vlan id. + Before host entry deleted related interface entry and ip6 base address + must be set atfirst. + For get_mode please refer IP entry operation flags. + * @param[in] dev_id device id + * @param[in] get_mode get operation mode + * @param[out] host_entry host entry parameter + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_ip_host_get(dev_id, get_mode, host_entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Next one host entry from one particular device. + * @details Comments: + * For ISIS the intf_id parameter in host_entry means vlan id. + Before host entry deleted related interface entry and ip6 base address + must be set atfirst. + For next_mode please refer IP entry operation flags. + For get the first entry please set entry id as FAL_NEXT_ENTRY_FIRST_ID + * @param[in] dev_id device id + * @param[in] next_mode next operation mode + * @param[out] host_entry host entry parameter + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_ip_host_next(dev_id, next_mode, host_entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Bind one counter entry to one host entry on one particular device. + * @param[in] dev_id device id + * @param[in] entry_id host entry id + * @param[in] cnt_id counter entry id + * @param[in] enable A_TRUE means bind, A_FALSE means unbind + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_ip_host_counter_bind(dev_id, entry_id, cnt_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Bind one pppoe session entry to one host entry on one particular device. + * @param[in] dev_id device id + * @param[in] entry_id host entry id + * @param[in] pppoe_id pppoe session entry id + * @param[in] enable A_TRUE means bind, A_FALSE means unbind + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_ip_host_pppoe_bind(dev_id, entry_id, pppoe_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set arp packets type to learn on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] flags arp type FAL_ARP_LEARN_REQ and/or FAL_ARP_LEARN_ACK + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_ip_pt_arp_learn_set(dev_id, port_id, flags); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp packets type to learn on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] flags arp type FAL_ARP_LEARN_REQ and/or FAL_ARP_LEARN_ACK + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_ip_pt_arp_learn_get(dev_id, port_id, flags); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set arp packets type to learn on one particular device. + * @param[in] dev_id device id + * @param[in] mode learning mode + * @return SW_OK or error code + */ +sw_error_t +fal_ip_arp_learn_set(a_uint32_t dev_id, fal_arp_learn_mode_t mode) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_ip_arp_learn_set(dev_id, mode); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp packets type to learn on one particular device. + * @param[in] dev_id device id + * @param[out] mode learning mode + * @return SW_OK or error code + */ +sw_error_t +fal_ip_arp_learn_get(a_uint32_t dev_id, fal_arp_learn_mode_t * mode) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_ip_arp_learn_get(dev_id, mode); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set ip packets source guarding mode on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode source guarding mode + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_ip_source_guard_set(dev_id, port_id, mode); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get ip packets source guarding mode on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mode source guarding mode + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_ip_source_guard_get(dev_id, port_id, mode); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set unkonw source ip packets forwarding command on one particular device. + * @details Comments: + * This settin is no meaning when ip source guard not enable + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +sw_error_t +fal_ip_unk_source_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_ip_unk_source_cmd_set(dev_id, cmd); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get unkonw source ip packets forwarding command on one particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +sw_error_t +fal_ip_unk_source_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_ip_unk_source_cmd_get(dev_id, cmd); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set arp packets source guarding mode on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode source guarding mode + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_ip_arp_guard_set(dev_id, port_id, mode); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp packets source guarding mode on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mode source guarding mode + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_ip_arp_guard_get(dev_id, port_id, mode); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set unkonw source arp packets forwarding command on one particular device. + * @details Comments: + * This settin is no meaning when arp source guard not enable + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +sw_error_t +fal_arp_unk_source_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_arp_unk_source_cmd_set(dev_id, cmd); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get unkonw source arp packets forwarding command on one particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +sw_error_t +fal_arp_unk_source_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_arp_unk_source_cmd_get(dev_id, cmd); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set IP unicast routing status on one particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_ip_route_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_ip_route_status_set(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IP unicast routing status on one particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_ip_route_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_ip_route_status_get(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Add one interface entry to one particular device. + * @param[in] dev_id device id + * @param[in] entry interface entry + * @return SW_OK or error code + */ +sw_error_t +fal_ip_intf_entry_add(a_uint32_t dev_id, fal_intf_mac_entry_t * entry) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_ip_intf_entry_add(dev_id, entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete one interface entry from one particular device. + * @param[in] dev_id device id + * @param[in] del_mode delete operation mode + * @param[in] entry interface entry + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_ip_intf_entry_del(dev_id, del_mode, entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Next one interface entry from one particular device. + * @param[in] dev_id device id + * @param[in] next_mode next operation mode + * @param[out] entry interface entry + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_ip_intf_entry_next(dev_id, next_mode, entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set IP host entry aging time on one particular device. + * @details Comments: + * This operation will set dynamic entry aging time on a particular device. + * The unit of time is second. Because different device has differnet + * hardware granularity function will return actual time in hardware. + * @param[in] dev_id device id + * @param[in] time aging time + * @param[out] time actual aging time + * @return SW_OK or error code + */ +sw_error_t +fal_ip_age_time_set(a_uint32_t dev_id, a_uint32_t * time) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_ip_age_time_set(dev_id, time); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IP host entry aging time on one particular device. + * @param[in] dev_id device id + * @param[out] time aging time + * @return SW_OK or error code + */ +sw_error_t +fal_ip_age_time_get(a_uint32_t dev_id, a_uint32_t * time) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_ip_age_time_get(dev_id, time); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set IP WCMP hash key mode. + * @param[in] dev_id device id + * @param[in] hash_mode hash mode + * @return SW_OK or error code + */ +sw_error_t +fal_ip_wcmp_hash_mode_set(a_uint32_t dev_id, a_uint32_t hash_mode) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_ip_wcmp_hash_mode_set(dev_id, hash_mode); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IP WCMP hash key mode. + * @param[in] dev_id device id + * @param[out] hash_mode hash mode + * @return SW_OK or error code + */ +sw_error_t +fal_ip_wcmp_hash_mode_get(a_uint32_t dev_id, a_uint32_t * hash_mode) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_ip_wcmp_hash_mode_get(dev_id, hash_mode); + FAL_API_UNLOCK; + 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; + + FAL_API_LOCK; + rv = _fal_ip_vrf_base_addr_set(dev_id, vrf_id, addr); + FAL_API_UNLOCK; + 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; + + FAL_API_LOCK; + rv = _fal_ip_vrf_base_addr_get(dev_id, vrf_id, addr); + FAL_API_UNLOCK; + 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; + + FAL_API_LOCK; + rv = _fal_ip_vrf_base_mask_set(dev_id, vrf_id, addr); + FAL_API_UNLOCK; + 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; + + FAL_API_LOCK; + rv = _fal_ip_vrf_base_mask_get(dev_id, vrf_id, addr); + FAL_API_UNLOCK; + 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; + + FAL_API_LOCK; + rv = _fal_ip_default_route_set(dev_id, droute_id, entry); + FAL_API_UNLOCK; + 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; + + FAL_API_LOCK; + rv = _fal_ip_default_route_get(dev_id, droute_id, entry); + FAL_API_UNLOCK; + 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; + + FAL_API_LOCK; + rv = _fal_ip_host_route_set(dev_id, hroute_id, entry); + FAL_API_UNLOCK; + 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; + + FAL_API_LOCK; + rv = _fal_ip_host_route_get(dev_id, hroute_id, entry); + FAL_API_UNLOCK; + 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; + + FAL_API_LOCK; + rv = _fal_ip_wcmp_entry_set(dev_id, wcmp_id, wcmp); + FAL_API_UNLOCK; + 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; + + FAL_API_LOCK; + rv = _fal_ip_wcmp_entry_get(dev_id, wcmp_id, wcmp); + FAL_API_UNLOCK; + 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; + + FAL_API_LOCK; + rv = _fal_ip_rfs_ip4_rule_set(dev_id, rfs); + FAL_API_UNLOCK; + 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; + + FAL_API_LOCK; + rv = _fal_ip_rfs_ip6_rule_set(dev_id, rfs); + FAL_API_UNLOCK; + 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; + + FAL_API_LOCK; + rv = _fal_ip_rfs_ip4_rule_del(dev_id, rfs); + FAL_API_UNLOCK; + 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; + + FAL_API_LOCK; + rv = _fal_ip_rfs_ip6_rule_del(dev_id, rfs); + FAL_API_UNLOCK; + return rv; +} + +int ssdk_rfs_ip4_rule_set(u16 vid, u32 ip, u8* mac, u8 ldb, int is_set) +{ + fal_ip4_rfs_t entry; + memcpy(&entry.mac_addr, mac, 6); + entry.ip4_addr = ip; + entry.load_balance = ldb; + entry.vid = vid; + if(is_set) + return fal_ip_rfs_ip4_rule_set(0, &entry); + else + return fal_ip_rfs_ip4_rule_del(0, &entry); +} + +int ssdk_rfs_ip6_rule_set(u16 vid, u8* ip, u8* mac, u8 ldb, int is_set) +{ + fal_ip6_rfs_t entry; + memcpy(&entry.mac_addr, mac, 6); + memcpy(&entry.ip6_addr, ip, sizeof(entry.ip6_addr)); + entry.load_balance = ldb; + entry.vid = vid; + if(is_set) + return fal_ip_rfs_ip6_rule_set(0, &entry); + else + return fal_ip_rfs_ip6_rule_del(0, &entry); +} + + +#if 0 +int +ssdk_ip_rfs_ip4_rule_set(ssdk_ip4_rfs_t * rfs) +{ + fal_ip4_rfs_t entry; + memcpy(&entry.mac_addr, rfs->mac_addr, 6); + entry.ip4_addr = rfs->ip4_addr; + entry.load_balance = rfs->load_balance; + entry.vid = rfs->vid; + return fal_ip_rfs_ip4_rule_set(0, &entry); +} + +int +ssdk_ip_rfs_ip4_rule_del(ssdk_ip4_rfs_t * rfs) +{ + fal_ip4_rfs_t entry; + memcpy(&entry.mac_addr, rfs->mac_addr, 6); + entry.ip4_addr = rfs->ip4_addr; + entry.load_balance = rfs->load_balance; + entry.vid = rfs->vid; + return fal_ip_rfs_ip4_rule_del(0, &entry); +} + +int +ssdk_ip_rfs_ip6_rule_set(ssdk_ip6_rfs_t * rfs) +{ + fal_ip6_rfs_t entry; + memcpy(&entry.mac_addr, rfs->mac_addr, 6); + memcpy(&entry.ip6_addr, rfs->ip6_addr, sizeof(rfs->ip6_addr)); + entry.load_balance = rfs->load_balance; + entry.vid = rfs->vid; + return fal_ip_rfs_ip6_rule_set(0, &entry); +} + +int +ssdk_ip_rfs_ip6_rule_del(ssdk_ip6_rfs_t * rfs) +{ + fal_ip6_rfs_t entry; + memcpy(&entry.mac_addr, rfs->mac_addr, 6); + memcpy(&entry.ip6_addr, rfs->ip6_addr, sizeof(rfs->ip6_addr)); + entry.load_balance = rfs->load_balance; + entry.vid = rfs->vid; + return fal_ip_rfs_ip6_rule_del(0, &entry); +} + + + +EXPORT_SYMBOL(ssdk_ip_rfs_ip4_rule_set); +EXPORT_SYMBOL(ssdk_ip_rfs_ip4_rule_del); +EXPORT_SYMBOL(ssdk_ip_rfs_ip6_rule_set); +EXPORT_SYMBOL(ssdk_ip_rfs_ip6_rule_del); +#endif +/** + * @brief Set default flow forward command + * @param[in] dev_id device id + * @param[in] vrf_id VRF route index, from 0~7 + * @param[in] type traffic flow type pass through switch core + * @param[in] fal_default_flow_cmd_t default flow forward command when flow table mismatch + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_default_flow_cmd_set(dev_id, vrf_id, type, cmd); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get flow type traffic default forward command. + * @param[in] dev_id device id + * @param[in] vrf_id VRF route index, from 0~7 + * @param[in] type traffic flow type pass through switch core + * @param[out] fal_default_flow_cmd_t default flow forward command when flow table mismatch + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_default_flow_cmd_get(dev_id, vrf_id, type, cmd); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set default route flow forward command + * @param[in] dev_id device id + * @param[in] vrf_id VRF route index, from 0~7 + * @param[in] type traffic flow type pass through switch core + * @param[in] fal_default_flow_cmd_t default route flow forward command when flow table mismatch + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_default_rt_flow_cmd_set(dev_id, vrf_id, type, cmd); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get flow type traffic default forward command. + * @param[in] dev_id device id + * @param[in] vrf_id VRF route index, from 0~7 + * @param[in] type traffic flow type pass through switch core + * @param[out] fal_default_flow_cmd_t default route flow forward command when flow table mismatch + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_default_rt_flow_cmd_get(dev_id, vrf_id, type, cmd); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ip_network_route_get(dev_id, index, type, entry); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ip_vsi_sg_cfg_get(dev_id, vsi, sg_cfg); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ip_network_route_del(dev_id, index, type); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ip_port_sg_cfg_set(dev_id, port_id, sg_cfg); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ip_port_intf_get(dev_id, port_id, id); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ip_vsi_arp_sg_cfg_set(dev_id, vsi, arp_sg_cfg); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ip_pub_addr_get(dev_id, index, entry); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ip_port_intf_set(dev_id, port_id, id); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ip_vsi_sg_cfg_set(dev_id, vsi, sg_cfg); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ip_port_macaddr_set(dev_id, port_id, macaddr); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ip_vsi_intf_get(dev_id, vsi, id); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ip_network_route_add(dev_id, index, entry); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ip_port_sg_cfg_get(dev_id, port_id, sg_cfg); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ip_intf_get(dev_id, index, entry); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ip_pub_addr_set(dev_id, index, entry); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ip_route_mismatch_get(dev_id, action); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ip_vsi_arp_sg_cfg_get(dev_id, vsi, arp_sg_cfg); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ip_port_arp_sg_cfg_set(dev_id, port_id, arp_sg_cfg); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ip_vsi_mc_mode_set(dev_id, vsi, cfg); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ip_vsi_intf_set(dev_id, vsi, id); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ip_nexthop_get(dev_id, index, entry); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ip_route_mismatch_set(dev_id, action); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ip_intf_set(dev_id, index, entry); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ip_vsi_mc_mode_get(dev_id, vsi, cfg); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ip_port_macaddr_get(dev_id, port_id, macaddr); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ip_port_arp_sg_cfg_get(dev_id, port_id, arp_sg_cfg); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ip_nexthop_set(dev_id, index, entry); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ip_global_ctrl_set(dev_id, cfg); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ip_global_ctrl_get(dev_id, cfg); + FAL_API_UNLOCK; + return rv; +} +#endif +/*insert flag for outter fal, don't remove it*/ + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/fal/fal_leaky.c b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_leaky.c new file mode 100755 index 000000000..db4321281 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_leaky.c @@ -0,0 +1,353 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 + * @{ + */ +#include "sw.h" +#include "fal_leaky.h" +#include "hsl_api.h" + +static sw_error_t +_fal_uc_leaky_mode_set(a_uint32_t dev_id, fal_leaky_ctrl_mode_t ctrl_mode) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->uc_leaky_mode_set) + return SW_NOT_SUPPORTED; + + rv = p_api->uc_leaky_mode_set(dev_id, ctrl_mode); + return rv; +} + +static sw_error_t +_fal_uc_leaky_mode_get(a_uint32_t dev_id, fal_leaky_ctrl_mode_t * ctrl_mode) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->uc_leaky_mode_get) + return SW_NOT_SUPPORTED; + + rv = p_api->uc_leaky_mode_get(dev_id, ctrl_mode); + return rv; +} + + +static sw_error_t +_fal_mc_leaky_mode_set(a_uint32_t dev_id, fal_leaky_ctrl_mode_t ctrl_mode) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->mc_leaky_mode_set) + return SW_NOT_SUPPORTED; + + rv = p_api->mc_leaky_mode_set(dev_id, ctrl_mode); + return rv; +} + + +static sw_error_t +_fal_mc_leaky_mode_get(a_uint32_t dev_id, fal_leaky_ctrl_mode_t * ctrl_mode) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->mc_leaky_mode_get) + return SW_NOT_SUPPORTED; + + rv = p_api->mc_leaky_mode_get(dev_id, ctrl_mode); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_arp_leaky_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_arp_leaky_set(dev_id, port_id, enable); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_arp_leaky_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_arp_leaky_get(dev_id, port_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_uc_leaky_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_uc_leaky_set(dev_id, port_id, enable); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_uc_leaky_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_uc_leaky_get(dev_id, port_id, enable); + return rv; +} + + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_mc_leaky_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_mc_leaky_set(dev_id, port_id, enable); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_mc_leaky_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_mc_leaky_get(dev_id, port_id, enable); + return rv; +} +/** +* @brief Set unicast packets leaky control mode on a particular device. +* @param[in] dev_id device id +* @param[in] ctrl_mode leaky control mode +* @return SW_OK or error code +*/ +sw_error_t +fal_uc_leaky_mode_set(a_uint32_t dev_id, fal_leaky_ctrl_mode_t ctrl_mode) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_uc_leaky_mode_set(dev_id, ctrl_mode); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get unicast packets leaky control mode on a particular device. + * @param[in] dev_id device id + * @param[out] ctrl_mode leaky control mode + * @return SW_OK or error code + */ +sw_error_t +fal_uc_leaky_mode_get(a_uint32_t dev_id, fal_leaky_ctrl_mode_t * ctrl_mode) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_uc_leaky_mode_get(dev_id, ctrl_mode); + FAL_API_UNLOCK; + return rv; +} + +/** +* @brief Set multicast packets leaky control mode on a particular device. +* @param[in] dev_id device id +* @param[in] ctrl_mode leaky control mode +* @return SW_OK or error code +*/ +sw_error_t +fal_mc_leaky_mode_set(a_uint32_t dev_id, fal_leaky_ctrl_mode_t ctrl_mode) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_mc_leaky_mode_set(dev_id, ctrl_mode); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get multicast packets leaky control mode on a particular device. + * @param[in] dev_id device id + * @param[out] ctrl_mode leaky control mode + * @return SW_OK or error code + */ +sw_error_t +fal_mc_leaky_mode_get(a_uint32_t dev_id, fal_leaky_ctrl_mode_t * ctrl_mode) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_mc_leaky_mode_get(dev_id, ctrl_mode); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set arp packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_arp_leaky_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_arp_leaky_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set unicast packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_uc_leaky_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get unicast packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_uc_leaky_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set multicast packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_mc_leaky_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get multicast packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_mc_leaky_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/fal/fal_led.c b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_led.c new file mode 100644 index 000000000..c11587572 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_led.c @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2012, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 + * @{ + */ + +#include "sw.h" +#include "fal_led.h" +#include "hsl_api.h" +#include "adpt.h" + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_led_ctrl_pattern_set != NULL) { + rv = p_adpt_api->adpt_led_ctrl_pattern_set(dev_id, group, id, pattern); + return rv; + } + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->led_ctrl_pattern_set) + return SW_NOT_SUPPORTED; + + rv = p_api->led_ctrl_pattern_set(dev_id, group, id, pattern); + return rv; +} + + + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_led_ctrl_pattern_get != NULL) { + rv = p_adpt_api->adpt_led_ctrl_pattern_get(dev_id, group, id, pattern); + return rv; + } + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->led_ctrl_pattern_get) + return SW_NOT_SUPPORTED; + + rv = p_api->led_ctrl_pattern_get(dev_id, group, id, pattern); + return rv; +} + +static sw_error_t +_fal_led_source_pattern_set(a_uint32_t dev_id, a_uint32_t source_id, + led_ctrl_pattern_t * pattern) +{ + sw_error_t rv; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_led_ctrl_source_set != NULL) { + rv = p_adpt_api->adpt_led_ctrl_source_set(dev_id, source_id, pattern); + return rv; + } + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->led_ctrl_source_set) + return SW_NOT_SUPPORTED; + + rv = p_api->led_ctrl_source_set(dev_id, source_id, pattern); + return rv; +} + + +/** +* @brief Set led control pattern on a particular device. +* @param[in] dev_id device id +* @param[in] group pattern group, lan or wan +* @param[in] id pattern id +* @param[in] pattern led control pattern +* @return SW_OK or error code +*/ +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; + + FAL_API_LOCK; + rv = _fal_led_ctrl_pattern_set(dev_id, group, id, pattern); + FAL_API_UNLOCK; + return rv; +} + +/** +* @brief Get led control pattern on a particular device. +* @param[in] dev_id device id +* @param[in] group pattern group, lan or wan +* @param[in] id pattern id +* @param[out] pattern led control pattern +* @return SW_OK or error code +*/ +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; + + FAL_API_LOCK; + rv = _fal_led_ctrl_pattern_get(dev_id, group, id, pattern); + FAL_API_UNLOCK; + return rv; +} + +/** +* @brief Set led control source on a particular device. +* @param[in] dev_id device id +* @param[in] source id +* @param[in] id pattern id +* @param[in] pattern led control pattern +* @return SW_OK or error code +*/ +sw_error_t +fal_led_source_pattern_set(a_uint32_t dev_id, a_uint32_t source_id, + led_ctrl_pattern_t * pattern) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_led_source_pattern_set(dev_id, source_id, pattern); + FAL_API_UNLOCK; + return rv; +} + + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/fal/fal_mib.c b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_mib.c new file mode 100755 index 000000000..0e8b39e4f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_mib.c @@ -0,0 +1,688 @@ +/* + * Copyright (c) 2012, 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 + * @{ + */ + +#include "sw.h" +#include "fal_mib.h" +#include "hsl_api.h" +#include "adpt.h" + +#include +#include + + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_get_mib_info) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_get_mib_info(dev_id, port_id, mib_Info); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->get_mib_info) + return SW_NOT_SUPPORTED; + + rv = p_api->get_mib_info(dev_id, port_id, mib_Info); + return rv; +} + +static sw_error_t +_fal_get_rx_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_Info) +{ + sw_error_t rv; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_get_rx_mib_info) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_get_rx_mib_info(dev_id, port_id, mib_Info); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->get_rx_mib_info) + return SW_NOT_SUPPORTED; + + rv = p_api->get_rx_mib_info(dev_id, port_id, mib_Info); + return rv; +} + +static sw_error_t +_fal_get_tx_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_Info) +{ + sw_error_t rv; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_get_tx_mib_info) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_get_tx_mib_info(dev_id, port_id, mib_Info); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->get_tx_mib_info) + return SW_NOT_SUPPORTED; + + rv = p_api->get_tx_mib_info(dev_id, port_id, mib_Info); + return rv; +} + +static sw_error_t +_fal_mib_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_mib_status_set) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_mib_status_set(dev_id, enable); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->mib_status_set) + return SW_NOT_SUPPORTED; + + rv = p_api->mib_status_set(dev_id, enable); + return rv; +} + + +static sw_error_t +_fal_mib_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_mib_status_get) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_mib_status_get(dev_id, enable); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->mib_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->mib_status_get(dev_id, enable); + return rv; +} + +static sw_error_t +_fal_mib_port_flush_counters(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_mib_port_flush_counters) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_mib_port_flush_counters(dev_id, port_id); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->mib_port_flush_counters) + return SW_NOT_SUPPORTED; + + rv = p_api->mib_port_flush_counters(dev_id, port_id); + return rv; +} + +static sw_error_t +_fal_mib_cpukeep_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_mib_cpukeep_set) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_mib_cpukeep_set(dev_id, enable); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->mib_cpukeep_set) + return SW_NOT_SUPPORTED; + + rv = p_api->mib_cpukeep_set(dev_id, enable); + return rv; +} + + +static sw_error_t +_fal_mib_cpukeep_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_mib_cpukeep_get) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_mib_cpukeep_get(dev_id, enable); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->mib_cpukeep_get) + return SW_NOT_SUPPORTED; + + rv = p_api->mib_cpukeep_get(dev_id, enable); + return rv; +} +static 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 = SW_OK; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_get_xgmib_info) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_get_xgmib_info(dev_id, port_id, mib_Info); + return rv; +} + +static sw_error_t +_fal_get_rx_xgmib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_xgmib_info_t * mib_Info) +{ + sw_error_t rv = SW_OK; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_get_rx_xgmib_info) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_get_rx_xgmib_info(dev_id, port_id, mib_Info); + return rv; +} + +static sw_error_t +_fal_get_tx_xgmib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_xgmib_info_t * mib_Info) +{ + sw_error_t rv = SW_OK; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_get_tx_xgmib_info) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_get_tx_xgmib_info(dev_id, port_id, mib_Info); + return rv; +} + +static fal_mib_counter_t *g_mibcounter[SW_MAX_NR_DEV]; + +sw_error_t +fal_mib_counter_alloc(a_uint32_t dev_id, a_uint64_t **p_mibcounter) +{ + *p_mibcounter = kzalloc(SW_MAX_NR_PORT * sizeof(fal_mib_counter_t), + GFP_KERNEL); + + if(NULL == *p_mibcounter) + return SW_OUT_OF_MEM; + + g_mibcounter[dev_id] = (fal_mib_counter_t*)*p_mibcounter; + + return SW_OK; +} + +static void _fal_rx_mib_update(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_Info) +{ + if(NULL == g_mibcounter[dev_id]) + return; + + g_mibcounter[dev_id][port_id].RxBroad += mib_Info->RxBroad; + g_mibcounter[dev_id][port_id].RxPause += mib_Info->RxPause; + g_mibcounter[dev_id][port_id].RxMulti += mib_Info->RxMulti; + g_mibcounter[dev_id][port_id].RxFcsErr += mib_Info->RxFcsErr; + g_mibcounter[dev_id][port_id].RxAllignErr += mib_Info->RxAllignErr; + g_mibcounter[dev_id][port_id].RxRunt += mib_Info->RxRunt; + g_mibcounter[dev_id][port_id].RxFragment += mib_Info->RxFragment; + g_mibcounter[dev_id][port_id].Rx64Byte += mib_Info->Rx64Byte; + g_mibcounter[dev_id][port_id].Rx128Byte += mib_Info->Rx128Byte; + g_mibcounter[dev_id][port_id].Rx256Byte += mib_Info->Rx256Byte; + g_mibcounter[dev_id][port_id].Rx512Byte += mib_Info->Rx512Byte; + g_mibcounter[dev_id][port_id].Rx1024Byte += mib_Info->Rx1024Byte; + g_mibcounter[dev_id][port_id].Rx1518Byte += mib_Info->Rx1518Byte; + g_mibcounter[dev_id][port_id].RxMaxByte += mib_Info->RxMaxByte; + g_mibcounter[dev_id][port_id].RxTooLong += mib_Info->RxTooLong; + g_mibcounter[dev_id][port_id].RxGoodByte += + (((u64)mib_Info->RxGoodByte_hi) << 32) | mib_Info->RxGoodByte_lo; + g_mibcounter[dev_id][port_id].RxBadByte += + (((u64)mib_Info->RxBadByte_hi) << 32) | mib_Info->RxBadByte_lo; + g_mibcounter[dev_id][port_id].RxOverFlow += mib_Info->RxOverFlow; + g_mibcounter[dev_id][port_id].Filtered += mib_Info->Filtered; + g_mibcounter[dev_id][port_id].RxUniCast += mib_Info->RxUniCast; + g_mibcounter[dev_id][port_id].RxTooLongByte += + (((u64)mib_Info->RxTooLongByte_hi) << 32) | mib_Info->RxTooLongByte_lo; + g_mibcounter[dev_id][port_id].RxRuntByte += + (((u64)mib_Info->RxRuntByte_hi) << 32) | mib_Info->RxRuntByte_lo; + g_mibcounter[dev_id][port_id].Rx14To63 += mib_Info->Rx14To63; + + return; +} + +static void _fal_tx_mib_update(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_Info) +{ + if(NULL == g_mibcounter[dev_id]) + return; + + g_mibcounter[dev_id][port_id].TxBroad += mib_Info->TxBroad; + g_mibcounter[dev_id][port_id].TxPause += mib_Info->TxPause; + g_mibcounter[dev_id][port_id].TxMulti += mib_Info->TxMulti; + g_mibcounter[dev_id][port_id].TxUnderRun += mib_Info->TxUnderRun; + g_mibcounter[dev_id][port_id].Tx64Byte += mib_Info->Tx64Byte; + g_mibcounter[dev_id][port_id].Tx128Byte += mib_Info->Tx128Byte; + g_mibcounter[dev_id][port_id].Tx256Byte += mib_Info->Tx256Byte; + g_mibcounter[dev_id][port_id].Tx512Byte += mib_Info->Tx512Byte; + g_mibcounter[dev_id][port_id].Tx1024Byte += mib_Info->Tx1024Byte; + g_mibcounter[dev_id][port_id].Tx1518Byte += mib_Info->Tx1518Byte; + g_mibcounter[dev_id][port_id].TxMaxByte += mib_Info->TxMaxByte; + g_mibcounter[dev_id][port_id].TxOverSize += mib_Info->TxOverSize; + g_mibcounter[dev_id][port_id].TxByte += + (((u64)mib_Info->TxByte_hi) << 32) | mib_Info->TxByte_lo; + g_mibcounter[dev_id][port_id].TxCollision += mib_Info->TxCollision; + g_mibcounter[dev_id][port_id].TxAbortCol += mib_Info->TxAbortCol; + g_mibcounter[dev_id][port_id].TxMultiCol += mib_Info->TxMultiCol; + g_mibcounter[dev_id][port_id].TxSingalCol += mib_Info->TxSingalCol; + g_mibcounter[dev_id][port_id].TxExcDefer += mib_Info->TxExcDefer; + g_mibcounter[dev_id][port_id].TxDefer += mib_Info->TxDefer; + g_mibcounter[dev_id][port_id].TxLateCol += mib_Info->TxLateCol; + g_mibcounter[dev_id][port_id].TxUniCast += mib_Info->TxUniCast; + + return; +} + +/*insert flag for inner fal, don't remove it*/ +/** + * @brief Get mib infomation on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mib_info mib infomation + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_get_mib_info(dev_id, port_id, mib_Info); + _fal_rx_mib_update(dev_id, port_id, mib_Info); + _fal_tx_mib_update(dev_id, port_id, mib_Info); + FAL_API_UNLOCK; + return rv; +} + +sw_error_t +fal_mib_counter_get(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_counter_t *mib_counter) +{ + sw_error_t rv; + fal_mib_info_t mib_info = {0}; + + if(NULL == g_mibcounter[dev_id]) + return SW_BAD_PTR; + + rv = fal_get_mib_info(dev_id, port_id, &mib_info); + + if(rv != SW_OK) + return rv; + + mib_counter->RxBroad = g_mibcounter[dev_id][port_id].RxBroad; + mib_counter->RxPause = g_mibcounter[dev_id][port_id].RxPause; + mib_counter->RxMulti = g_mibcounter[dev_id][port_id].RxMulti; + mib_counter->RxFcsErr = g_mibcounter[dev_id][port_id].RxFcsErr; + mib_counter->RxAllignErr = g_mibcounter[dev_id][port_id].RxAllignErr; + mib_counter->RxRunt = g_mibcounter[dev_id][port_id].RxRunt; + mib_counter->RxFragment = g_mibcounter[dev_id][port_id].RxFragment ; + mib_counter->Rx64Byte = g_mibcounter[dev_id][port_id].Rx64Byte ; + mib_counter->Rx128Byte = g_mibcounter[dev_id][port_id].Rx128Byte; + mib_counter->Rx256Byte = g_mibcounter[dev_id][port_id].Rx256Byte; + mib_counter->Rx512Byte = g_mibcounter[dev_id][port_id].Rx512Byte; + mib_counter->Rx1024Byte = g_mibcounter[dev_id][port_id].Rx1024Byte; + mib_counter->Rx1518Byte = g_mibcounter[dev_id][port_id].Rx1518Byte; + mib_counter->RxMaxByte = g_mibcounter[dev_id][port_id].RxMaxByte; + mib_counter->RxTooLong = g_mibcounter[dev_id][port_id].RxTooLong; + mib_counter->RxGoodByte = g_mibcounter[dev_id][port_id].RxGoodByte; + mib_counter->RxBadByte = g_mibcounter[dev_id][port_id].RxBadByte; + mib_counter->RxOverFlow = g_mibcounter[dev_id][port_id].RxOverFlow; + mib_counter->Filtered = g_mibcounter[dev_id][port_id].Filtered; + mib_counter->TxBroad = g_mibcounter[dev_id][port_id].TxBroad; + mib_counter->TxPause = g_mibcounter[dev_id][port_id].TxPause; + mib_counter->TxMulti = g_mibcounter[dev_id][port_id].TxMulti; + mib_counter->TxUnderRun = g_mibcounter[dev_id][port_id].TxUnderRun; + mib_counter->Tx64Byte = g_mibcounter[dev_id][port_id].Tx64Byte; + mib_counter->Tx128Byte = g_mibcounter[dev_id][port_id].Tx128Byte; + mib_counter->Tx256Byte = g_mibcounter[dev_id][port_id].Tx256Byte; + mib_counter->Tx512Byte = g_mibcounter[dev_id][port_id].Tx512Byte; + mib_counter->Tx1024Byte = g_mibcounter[dev_id][port_id].Tx1024Byte; + mib_counter->Tx1518Byte = g_mibcounter[dev_id][port_id].Tx1518Byte; + mib_counter->TxMaxByte = g_mibcounter[dev_id][port_id].TxMaxByte; + mib_counter->TxOverSize = g_mibcounter[dev_id][port_id].TxOverSize; + mib_counter->TxByte = g_mibcounter[dev_id][port_id].TxByte; + mib_counter->TxCollision = g_mibcounter[dev_id][port_id].TxCollision; + mib_counter->TxAbortCol = g_mibcounter[dev_id][port_id].TxAbortCol; + mib_counter->TxMultiCol = g_mibcounter[dev_id][port_id].TxMultiCol; + mib_counter->TxSingalCol = g_mibcounter[dev_id][port_id].TxSingalCol; + mib_counter->TxExcDefer = g_mibcounter[dev_id][port_id].TxExcDefer; + mib_counter->TxDefer = g_mibcounter[dev_id][port_id].TxDefer; + mib_counter->TxLateCol = g_mibcounter[dev_id][port_id].TxLateCol; + mib_counter->RxUniCast = g_mibcounter[dev_id][port_id].RxUniCast; + mib_counter->TxUniCast = g_mibcounter[dev_id][port_id].TxUniCast; + mib_counter->Rx14To63 = g_mibcounter[dev_id][port_id].Rx14To63; + mib_counter->RxTooLongByte = g_mibcounter[dev_id][port_id].RxTooLongByte; + mib_counter->RxRuntByte = g_mibcounter[dev_id][port_id].RxRuntByte; + + return SW_OK; +} + +/** + * @brief Get RX mib infomation on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mib_info mib infomation + * @return SW_OK or error code + */ +sw_error_t +fal_get_rx_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_Info) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_get_rx_mib_info(dev_id, port_id, mib_Info); + _fal_rx_mib_update(dev_id, port_id, mib_Info); + FAL_API_UNLOCK; + + return rv; +} + +/** + * @brief Get TX mib infomation on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mib_info mib infomation + * @return SW_OK or error code + */ +sw_error_t +fal_get_tx_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_Info) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_get_tx_mib_info(dev_id, port_id, mib_Info); + _fal_tx_mib_update(dev_id, port_id, mib_Info); + FAL_API_UNLOCK; + + return rv; +} + +/** + * @brief Set mib status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_mib_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_mib_status_set(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mib status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_mib_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_mib_status_get(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Flush mib counters on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @return SW_OK or error code + */ +sw_error_t +fal_mib_port_flush_counters(a_uint32_t dev_id, fal_port_t port_id ) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_mib_port_flush_counters(dev_id, port_id); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set mib status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_mib_cpukeep_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_mib_cpukeep_set(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mib status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_mib_cpukeep_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_mib_cpukeep_get(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get xgmacmib infomation on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mib_info mib infomation + * @return SW_OK or error code + */ +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; + fal_mib_counter_t gmac_mib = { 0 }; + + FAL_API_LOCK; + rv = _fal_get_xgmib_info(dev_id, port_id, mib_Info); + FAL_API_UNLOCK; + SW_RTN_ON_ERROR(rv); + + rv = fal_mib_counter_get(dev_id, port_id, &gmac_mib); + SW_RTN_ON_ERROR(rv); + + mib_Info->RxFrame += (gmac_mib.RxBroad + + gmac_mib.RxMulti + gmac_mib.RxUniCast); + mib_Info->RxByte += (gmac_mib.RxGoodByte+gmac_mib.RxBadByte); + mib_Info->RxByteGood += gmac_mib.RxGoodByte; + mib_Info->RxBroadGood += gmac_mib.RxBroad; + mib_Info->RxMultiGood += gmac_mib.RxMulti; + mib_Info->RxFcsErr += gmac_mib.RxFcsErr; + mib_Info->RxRuntErr += gmac_mib.RxRunt; + mib_Info->Rx64Byte += gmac_mib.Rx64Byte; + mib_Info->Rx128Byte += gmac_mib.Rx128Byte; + mib_Info->Rx256Byte += gmac_mib.Rx256Byte; + mib_Info->Rx512Byte += gmac_mib.Rx512Byte; + mib_Info->Rx1024Byte += gmac_mib.Rx1024Byte; + mib_Info->RxMaxByte += (gmac_mib.Rx1518Byte + gmac_mib.RxMaxByte); + mib_Info->RxUnicastGood += gmac_mib.RxUniCast; + mib_Info->RxLengthError += gmac_mib.RxTooLong; + mib_Info->RxPause += gmac_mib.RxPause; + mib_Info->RxOverFlow += gmac_mib.RxOverFlow; + + mib_Info->TxByte += gmac_mib.TxByte; + mib_Info->TxFrame += (gmac_mib.TxBroad + + gmac_mib.TxMulti + gmac_mib.TxUniCast); + mib_Info->TxBroadGood += gmac_mib.TxBroad; + mib_Info->TxMultiGood += gmac_mib.TxMulti; + mib_Info->Tx64Byte += gmac_mib.Tx64Byte; + mib_Info->Tx128Byte += gmac_mib.Tx128Byte; + mib_Info->Tx256Byte += gmac_mib.Tx256Byte; + mib_Info->Tx512Byte += gmac_mib.Tx512Byte; + mib_Info->Tx1024Byte += gmac_mib.Tx1024Byte; + mib_Info->TxMaxByte += (gmac_mib.Tx1518Byte + gmac_mib.TxMaxByte); + mib_Info->TxUnicast += gmac_mib.TxUniCast; + mib_Info->TxMulti += gmac_mib.TxMulti; + mib_Info->TxBroad += gmac_mib.TxBroad; + mib_Info->TxByteGood += gmac_mib.TxByte; + mib_Info->TxFrameGood += (gmac_mib.TxBroad + + gmac_mib.TxMulti + gmac_mib.TxUniCast); + mib_Info->TxPause += gmac_mib.TxPause; + + return rv; +} + +/** + * @brief Get RX xgmacmib infomation on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mib_info mib infomation + * @return SW_OK or error code + */ +sw_error_t +fal_get_rx_xgmib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_xgmib_info_t * mib_Info) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_get_rx_xgmib_info(dev_id, port_id, mib_Info); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get TX xgmacmib infomation on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mib_info mib infomation + * @return SW_OK or error code + */ +sw_error_t +fal_get_tx_xgmib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_xgmib_info_t * mib_Info) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_get_tx_xgmib_info(dev_id, port_id, mib_Info); + FAL_API_UNLOCK; + return rv; +} + +EXPORT_SYMBOL(fal_get_mib_info); +EXPORT_SYMBOL(fal_get_rx_mib_info); +EXPORT_SYMBOL(fal_get_tx_mib_info); +EXPORT_SYMBOL(fal_get_xgmib_info); +EXPORT_SYMBOL(fal_get_rx_xgmib_info); +EXPORT_SYMBOL(fal_get_tx_xgmib_info); +EXPORT_SYMBOL(fal_mib_status_set); +EXPORT_SYMBOL(fal_mib_status_get); +EXPORT_SYMBOL(fal_mib_port_flush_counters); +EXPORT_SYMBOL(fal_mib_cpukeep_set); +EXPORT_SYMBOL(fal_mib_cpukeep_get); +EXPORT_SYMBOL(fal_mib_counter_get); + +/*insert flag for outter fal, don't remove it*/ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/fal/fal_mirror.c b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_mirror.c new file mode 100755 index 000000000..21856a39b --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_mirror.c @@ -0,0 +1,344 @@ +/* + * Copyright (c) 2012, 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 + * @{ + */ +#include "sw.h" +#include "fal_mirror.h" +#include "hsl_api.h" +#include "adpt.h" + +#include +#include + + + +static sw_error_t +_fal_mirr_analysis_port_set(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_mirr_analysis_port_set) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_mirr_analysis_port_set(dev_id, port_id); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->mirr_analysis_port_set) + return SW_NOT_SUPPORTED; + + rv = p_api->mirr_analysis_port_set(dev_id, port_id); + return rv; +} + +static sw_error_t +_fal_mirr_analysis_port_get(a_uint32_t dev_id, fal_port_t * port_id) +{ + sw_error_t rv; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_mirr_analysis_port_get) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_mirr_analysis_port_get(dev_id, port_id); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->mirr_analysis_port_get) + return SW_NOT_SUPPORTED; + + rv = p_api->mirr_analysis_port_get(dev_id, port_id); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_mirr_port_in_set) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_mirr_port_in_set(dev_id, port_id, enable); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->mirr_port_in_set) + return SW_NOT_SUPPORTED; + + rv = p_api->mirr_port_in_set(dev_id, port_id, enable); + return rv; +} + + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_mirr_port_in_get) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_mirr_port_in_get(dev_id, port_id, enable); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->mirr_port_in_get) + return SW_NOT_SUPPORTED; + + rv = p_api->mirr_port_in_get(dev_id, port_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_mirr_port_eg_set) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_mirr_port_eg_set(dev_id, port_id, enable); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->mirr_port_eg_set) + return SW_NOT_SUPPORTED; + + rv = p_api->mirr_port_eg_set(dev_id, port_id, enable); + return rv; +} + + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_mirr_port_eg_get) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_mirr_port_eg_get(dev_id, port_id, enable); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->mirr_port_eg_get) + return SW_NOT_SUPPORTED; + + rv = p_api->mirr_port_eg_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_mirr_analysis_config_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_mirr_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_mirr_analysis_config_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_mirr_analysis_config_get(dev_id, direction, config); + return rv; +} +/*insert flag for inner fal, don't remove it*/ +/** + * @details Comments: + * The analysis port works for both ingress and egress mirror. + * @brief Set mirror analyzer port on particular a device. + * @param[in] dev_id device id + * @param[in] port_id port id + * @return SW_OK or error code + */ +sw_error_t +fal_mirr_analysis_port_set(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_mirr_analysis_port_set(dev_id, port_id); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mirror analysis port on particular a device. + * @param[in] dev_id device id + * @param[out] port_id port id + * @return SW_OK or error code + */ +sw_error_t +fal_mirr_analysis_port_get(a_uint32_t dev_id, fal_port_t * port_id) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_mirr_analysis_port_get(dev_id, port_id); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set ingress mirror status on particular a port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_mirr_port_in_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get ingress mirror status on particular a port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_mirr_port_in_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set egress mirror status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_mirr_port_eg_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get egress mirror status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_mirr_port_eg_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_mirr_analysis_config_set(dev_id, direction, config); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_mirr_analysis_config_get(dev_id, direction, config); + FAL_API_UNLOCK; + return rv; +} +/*insert flag for outter fal, don't remove it*/ + +EXPORT_SYMBOL(fal_mirr_analysis_port_set); +EXPORT_SYMBOL(fal_mirr_analysis_port_get); +EXPORT_SYMBOL(fal_mirr_port_in_set); +EXPORT_SYMBOL(fal_mirr_port_in_get); +EXPORT_SYMBOL(fal_mirr_port_eg_set); +EXPORT_SYMBOL(fal_mirr_port_eg_get); +EXPORT_SYMBOL(fal_mirr_analysis_config_set); +EXPORT_SYMBOL(fal_mirr_analysis_config_get); + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/fal/fal_misc.c b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_misc.c new file mode 100755 index 000000000..66623a8b4 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_misc.c @@ -0,0 +1,1772 @@ +/* + * Copyright (c) 2012, 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. + */ + + + +/** +* @defgroup fal_gen FAL_MISC +* @{ +*/ +#include "sw.h" +#include "fal_misc.h" +#include "hsl_api.h" +#include "adpt.h" + +#ifndef IN_MISC_MINI +static sw_error_t +_fal_arp_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->arp_status_set) + return SW_NOT_SUPPORTED; + + rv = p_api->arp_status_set(dev_id, enable); + return rv; +} + + +static sw_error_t +_fal_arp_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->arp_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->arp_status_get(dev_id, enable); + return rv; +} +#endif + +static sw_error_t +_fal_frame_max_size_set(a_uint32_t dev_id, a_uint32_t size) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->frame_max_size_set) + return SW_NOT_SUPPORTED; + + rv = p_api->frame_max_size_set(dev_id, size); + return rv; +} + + +static sw_error_t +_fal_frame_max_size_get(a_uint32_t dev_id, a_uint32_t * size) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->frame_max_size_get) + return SW_NOT_SUPPORTED; + + rv = p_api->frame_max_size_get(dev_id, size); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_unk_sa_cmd_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_unk_sa_cmd_set(dev_id, port_id, cmd); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_unk_uc_filter_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_unk_uc_filter_set(dev_id, port_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_unk_mc_filter_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_unk_mc_filter_set(dev_id, port_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_bc_filter_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_bc_filter_set(dev_id, port_id, enable); + return rv; +} + +static sw_error_t +_fal_cpu_port_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->cpu_port_status_set) + return SW_NOT_SUPPORTED; + + rv = p_api->cpu_port_status_set(dev_id, enable); + return rv; +} + +#ifndef IN_MISC_MINI +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_unk_sa_cmd_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_unk_sa_cmd_get(dev_id, port_id, cmd); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_unk_uc_filter_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_unk_uc_filter_get(dev_id, port_id, enable); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_unk_mc_filter_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_unk_mc_filter_get(dev_id, port_id, enable); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_bc_filter_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_bc_filter_get(dev_id, port_id, enable); + return rv; +} + +static sw_error_t +_fal_cpu_port_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->cpu_port_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->cpu_port_status_get(dev_id, enable); + return rv; +} + + +static sw_error_t +_fal_bc_to_cpu_port_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->bc_to_cpu_port_set) + return SW_NOT_SUPPORTED; + + rv = p_api->bc_to_cpu_port_set(dev_id, enable); + return rv; +} + + +static sw_error_t +_fal_bc_to_cpu_port_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->bc_to_cpu_port_get) + return SW_NOT_SUPPORTED; + + rv = p_api->bc_to_cpu_port_get(dev_id, enable); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_dhcp_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_dhcp_set(dev_id, port_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_dhcp_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_dhcp_get(dev_id, port_id, enable); + return rv; +} + +static sw_error_t +_fal_arp_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->arp_cmd_set) + return SW_NOT_SUPPORTED; + + rv = p_api->arp_cmd_set(dev_id, cmd); + return rv; +} + +static sw_error_t +_fal_arp_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->arp_cmd_get) + return SW_NOT_SUPPORTED; + + rv = p_api->arp_cmd_get(dev_id, cmd); + return rv; +} +#endif + +static sw_error_t +_fal_eapol_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->eapol_cmd_set) + return SW_NOT_SUPPORTED; + + rv = p_api->eapol_cmd_set(dev_id, cmd); + return rv; +} + +#ifndef IN_MISC_MINI +static sw_error_t +_fal_eapol_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->eapol_cmd_get) + return SW_NOT_SUPPORTED; + + rv = p_api->eapol_cmd_get(dev_id, cmd); + return rv; +} +#endif + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->eapol_status_set) + return SW_NOT_SUPPORTED; + + rv = p_api->eapol_status_set(dev_id, port_id, enable); + return rv; +} + +#ifndef IN_MISC_MINI +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->eapol_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->eapol_status_get(dev_id, port_id, enable); + return rv; +} + +static sw_error_t +_fal_ripv1_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ripv1_status_set) + return SW_NOT_SUPPORTED; + + rv = p_api->ripv1_status_set(dev_id, enable); + return rv; +} + +static sw_error_t +_fal_ripv1_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->ripv1_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->ripv1_status_get(dev_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_arp_req_status_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_arp_req_status_set(dev_id, port_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_arp_req_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_arp_req_status_get(dev_id, port_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_arp_ack_status_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_arp_ack_status_set(dev_id, port_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_arp_ack_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_arp_ack_status_get(dev_id, port_id, enable); + return rv; +} + +static sw_error_t +_fal_intr_mask_set(a_uint32_t dev_id, a_uint32_t intr_mask) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->intr_mask_set) + return SW_NOT_SUPPORTED; + + rv = p_api->intr_mask_set(dev_id, intr_mask); + return rv; +} + +static sw_error_t +_fal_intr_mask_get(a_uint32_t dev_id, a_uint32_t * intr_mask) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->intr_mask_get) + return SW_NOT_SUPPORTED; + + rv = p_api->intr_mask_get(dev_id, intr_mask); + return rv; +} + +static sw_error_t +_fal_intr_status_get(a_uint32_t dev_id, a_uint32_t * intr_status) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->intr_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->intr_status_get(dev_id, intr_status); + return rv; +} + +static sw_error_t +_fal_intr_status_clear(a_uint32_t dev_id, a_uint32_t intr_status) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->intr_status_clear) + return SW_NOT_SUPPORTED; + + rv = p_api->intr_status_clear(dev_id, intr_status); + return rv; +} + +static sw_error_t +_fal_intr_port_link_mask_set(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t intr_mask) +{ + sw_error_t rv; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_intr_port_link_mask_set != NULL) { + rv = p_adpt_api->adpt_intr_port_link_mask_set(dev_id, port_id, intr_mask); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->intr_port_link_mask_set) + return SW_NOT_SUPPORTED; + + rv = p_api->intr_port_link_mask_set(dev_id, port_id, intr_mask); + return rv; +} + +static sw_error_t +_fal_intr_port_link_mask_get(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t * intr_mask) +{ + sw_error_t rv; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_intr_port_link_mask_get != NULL) { + rv = p_adpt_api->adpt_intr_port_link_mask_get(dev_id, port_id, intr_mask); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->intr_port_link_mask_get) + return SW_NOT_SUPPORTED; + + rv = p_api->intr_port_link_mask_get(dev_id, port_id, intr_mask); + return rv; +} + +static sw_error_t +_fal_intr_port_link_status_get(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t * intr_mask) +{ + sw_error_t rv; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_intr_port_link_status_get != NULL) { + rv = p_adpt_api->adpt_intr_port_link_status_get(dev_id, port_id, intr_mask); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->intr_port_link_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->intr_port_link_status_get(dev_id, port_id, intr_mask); + return rv; +} + + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->intr_mask_mac_linkchg_set) + return SW_NOT_SUPPORTED; + + rv = p_api->intr_mask_mac_linkchg_set(dev_id, port_id, enable); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->intr_mask_mac_linkchg_get) + return SW_NOT_SUPPORTED; + + rv = p_api->intr_mask_mac_linkchg_get(dev_id, port_id, enable); + return rv; +} + + +static sw_error_t +_fal_intr_status_mac_linkchg_get(a_uint32_t dev_id, fal_pbmp_t* port_bitmap) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->intr_status_mac_linkchg_get) + return SW_NOT_SUPPORTED; + + rv = p_api->intr_status_mac_linkchg_get(dev_id, port_bitmap); + return rv; +} + +static sw_error_t +_fal_cpu_vid_en_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->cpu_vid_en_set) + return SW_NOT_SUPPORTED; + + rv = p_api->cpu_vid_en_set(dev_id, enable); + return rv; +} + + +static sw_error_t +_fal_cpu_vid_en_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->cpu_vid_en_get) + return SW_NOT_SUPPORTED; + + rv = p_api->cpu_vid_en_get(dev_id, enable); + return rv; +} + +static sw_error_t +_fal_intr_status_mac_linkchg_clear(a_uint32_t dev_id) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->intr_status_mac_linkchg_clear) + return SW_NOT_SUPPORTED; + + rv = p_api->intr_status_mac_linkchg_clear(dev_id); + return rv; +} + + +static sw_error_t +_fal_global_macaddr_set(a_uint32_t dev_id, fal_mac_addr_t * addr) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->global_macaddr_set) + return SW_NOT_SUPPORTED; + + rv = p_api->global_macaddr_set(dev_id, addr); + return rv; +} + +static sw_error_t +_fal_global_macaddr_get(a_uint32_t dev_id, fal_mac_addr_t * addr) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->global_macaddr_get) + return SW_NOT_SUPPORTED; + + rv = p_api->global_macaddr_get(dev_id, addr); + return rv; +} + +static sw_error_t +_fal_lldp_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->lldp_status_set) + return SW_NOT_SUPPORTED; + + rv = p_api->lldp_status_set(dev_id, enable); + return rv; +} + +static sw_error_t +_fal_lldp_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->lldp_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->lldp_status_get(dev_id, enable); + return rv; +} + +static sw_error_t +_fal_frame_crc_reserve_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->frame_crc_reserve_set) + return SW_NOT_SUPPORTED; + + rv = p_api->frame_crc_reserve_set(dev_id, enable); + return rv; +} + +static sw_error_t +_fal_frame_crc_reserve_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->frame_crc_reserve_get) + return SW_NOT_SUPPORTED; + + rv = p_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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_debug_port_counter_enable) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_debug_port_counter_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_debug_port_counter_status_get(dev_id, port_id, cnt_en); + return rv; +} + +/** + * @brief Set arp packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_arp_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_arp_status_set(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_arp_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_arp_status_get(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} +#endif + +/** + * @brief Set max frame size which device can received on a particular device. + * @details Comments: + * The granularity of packets size is byte. + * @param[in] dev_id device id + * @param[in] size packet size + * @return SW_OK or error code + */ +sw_error_t +fal_frame_max_size_set(a_uint32_t dev_id, a_uint32_t size) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_frame_max_size_set(dev_id, size); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get max frame size which device can received on a particular device. + * @details Comments: + * The unit of packets size is byte. + * @param[in] dev_id device id + * @param[out] size packet size + * @return SW_OK or error code + */ +sw_error_t +fal_frame_max_size_get(a_uint32_t dev_id, a_uint32_t * size) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_frame_max_size_get(dev_id, size); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set forwarding command for packets which source address is unknown on a particular port. + * @details Comments: + * Particular device may only support parts of forwarding commands. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_unk_sa_cmd_set(dev_id, port_id, cmd); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flooding status of unknown unicast packets on a particular port. + * @details Comments: + * If enable unknown unicast packets filter on one port then unknown + * unicast packets can't flood out from this port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_unk_uc_filter_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flooding status of unknown multicast packets on a particular port. + * @details Comments: + * If enable unknown multicast packets filter on one port then unknown + * multicast packets can't flood out from this port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_unk_mc_filter_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flooding status of broadcast packets on a particular port. + * @details Comments: + * If enable unknown multicast packets filter on one port then unknown + * multicast packets can't flood out from this port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_bc_filter_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set cpu port status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_cpu_port_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_cpu_port_status_set(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +#ifndef IN_MISC_MINI +/** + * @brief Get forwarding command for packets which source address is unknown on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_unk_sa_cmd_get(dev_id, port_id, cmd); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get flooding status of unknown unicast packets on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_unk_uc_filter_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + + + +/** + * @brief Get flooding status of unknown multicast packets on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_unk_mc_filter_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + + + +/** + * @brief Get flooding status of broadcast packets on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_bc_filter_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get cpu port status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_cpu_port_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_cpu_port_status_get(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of braodcast packets broadcasting to cpu on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_bc_to_cpu_port_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_bc_to_cpu_port_set(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get status of braodcast packets broadcasting to cpu on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_bc_to_cpu_port_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_bc_to_cpu_port_get(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dhcp packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_dhcp_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dhcp packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_dhcp_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set arp packets forwarding command on a particular device. + * @details Comments: + * Particular device may only support parts of forwarding commands. + * This operation will take effect only after enabling arp + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +sw_error_t +fal_arp_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_arp_cmd_set(dev_id, cmd); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp packets forwarding command on a particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +sw_error_t +fal_arp_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_arp_cmd_get(dev_id, cmd); + FAL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Set eapol packets forwarding command on a particular device. + * @details Comments: + * Particular device may only support parts of forwarding commands. + * This operation will take effect only after enabling eapol + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +sw_error_t +fal_eapol_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_eapol_cmd_set(dev_id, cmd); + FAL_API_UNLOCK; + return rv; +} + +#ifndef IN_MISC_MINI +/** + * @brief Get eapol packets forwarding command on a particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +sw_error_t +fal_eapol_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_eapol_cmd_get(dev_id, cmd); + FAL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Set eapol packets hardware acknowledgement on a particular port. + * @details Comments: + * Particular device may only support parts of forwarding commands. + * This operation will take effect only after enabling eapol + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_eapol_status_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} +#ifndef IN_MISC_MINI +/** + * @brief Get eapol packets hardware acknowledgement on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_eapol_status_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set ripv1 packets hardware acknowledgement on a particular port. + * @details Comments: + * Particular device may only support parts of forwarding commands. + * This operation will take effect only after enabling eapol + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_ripv1_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_ripv1_status_set(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get ripv1 packets hardware acknowledgement on a particular port. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_ripv1_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_ripv1_status_get(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set arp req packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_arp_req_status_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp req packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_arp_req_status_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set arp ack packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_arp_ack_status_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp ack packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_arp_ack_status_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set switch interrupt mask on one particular device. + * @param[in] dev_id device id + * @param[in] intr_mask mask + * @return SW_OK or error code + */ +sw_error_t +fal_intr_mask_set(a_uint32_t dev_id, a_uint32_t intr_mask) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_intr_mask_set(dev_id, intr_mask); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get switch interrupt mask on one particular device. + * @param[in] dev_id device id + * @param[in] intr_mask mask + * @return SW_OK or error code + */ +sw_error_t +fal_intr_mask_get(a_uint32_t dev_id, a_uint32_t * intr_mask) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_intr_mask_get(dev_id, intr_mask); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get switch interrupt status on one particular device. + * @param[in] dev_id device id + * @param[in] intr_status status + * @return SW_OK or error code + */ +sw_error_t +fal_intr_status_get(a_uint32_t dev_id, a_uint32_t * intr_status) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_intr_status_get(dev_id, intr_status); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Clear switch interrupt status on one particular device. + * @param[in] dev_id device id + * @param[in] intr_status status + * @return SW_OK or error code + */ +sw_error_t +fal_intr_status_clear(a_uint32_t dev_id, a_uint32_t intr_status) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_intr_status_clear(dev_id, intr_status); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set link interrupt mask on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] intr_mask_flag interrupt mask + * @return SW_OK or error code + */ +sw_error_t +fal_intr_port_link_mask_set(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t intr_mask_flag) +{ + sw_error_t rv; + FAL_API_LOCK; + rv = _fal_intr_port_link_mask_set(dev_id, port_id, intr_mask_flag); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get link interrupt mask on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] intr_mask_flag interrupt mask + * @return SW_OK or error code + */ +sw_error_t +fal_intr_port_link_mask_get(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t * intr_mask_flag) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_intr_port_link_mask_get(dev_id, port_id, intr_mask_flag); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get link interrupt status on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] intr_mask_flag interrupt mask + * @return SW_OK or error code + */ +sw_error_t +fal_intr_port_link_status_get(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t * intr_mask_flag) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_intr_port_link_status_get(dev_id, port_id, intr_mask_flag); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set mac link change interrupt mask on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable ports intr mask enabled + * @return SW_OK or error code + */ +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; + FAL_API_LOCK; + rv = _fal_intr_mask_mac_linkchg_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mac link change interrupt mask on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] port interrupt mask or not + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_intr_mask_mac_linkchg_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get link change interrupt status for all ports. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] ports bitmap which generates interrupt + * @return SW_OK or error code + */ +sw_error_t +fal_intr_status_mac_linkchg_get(a_uint32_t dev_id, fal_pbmp_t* port_bitmap) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_intr_status_mac_linkchg_get(dev_id, port_bitmap); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set to cpu vid enable status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_cpu_vid_en_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_cpu_vid_en_set(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get to cpu vid enable status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_cpu_vid_en_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_cpu_vid_en_get(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mac link change interrupt mask on particular port. + * @param[in] dev_id device id + * @return SW_OK or error code + */ +sw_error_t +fal_intr_status_mac_linkchg_clear(a_uint32_t dev_id) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_intr_status_mac_linkchg_clear(dev_id); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set global macaddr on particular device. + * @param[in] dev_id device id + * @param[in] addr addr + * @return SW_OK or error code + */ +sw_error_t +fal_global_macaddr_set(a_uint32_t dev_id, fal_mac_addr_t * addr) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_global_macaddr_set(dev_id, addr); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get global macaddr on particular device. + * @param[in] dev_id device id + * @param[out] addr addr + * @return SW_OK or error code + */ +sw_error_t +fal_global_macaddr_get(a_uint32_t dev_id, fal_mac_addr_t * addr) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_global_macaddr_get(dev_id, addr); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set lldp packets hardware acknowledgement status on particular device. + * @details comments: + * Particular device may only support parts of pppoe packets. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_lldp_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_lldp_status_set(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get lldp packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_lldp_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_lldp_status_get(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set frame crc reserve enable on particular device. + * @details comments: + * CRC reseve enable. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_frame_crc_reserve_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_frame_crc_reserve_set(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get frame crc reserve enable on particular device. + * @details comments: + * CRC reseve enable. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_frame_crc_reserve_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_frame_crc_reserve_get(dev_id, enable); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_debug_port_counter_enable(dev_id, port_id, cnt_en); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_debug_port_counter_status_get(dev_id, port_id, cnt_en); + FAL_API_UNLOCK; + return rv; +} +#endif + + + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/fal/fal_nat.c b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_nat.c new file mode 100755 index 000000000..6110628b3 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_nat.c @@ -0,0 +1,1341 @@ +/* + * Copyright (c) 2012, 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 + * @{ + */ + +#include "sw.h" +#include "fal_nat.h" +#include "hsl_api.h" + +#include +#include + +int nf_athrs17_hnat_sync_counter_en = 0; + +static sw_error_t +_fal_nat_add(a_uint32_t dev_id, fal_nat_entry_t * nat_entry) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->nat_add) + return SW_NOT_SUPPORTED; + + rv = p_api->nat_add(dev_id, nat_entry); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->nat_del) + return SW_NOT_SUPPORTED; + + rv = p_api->nat_del(dev_id, del_mode, nat_entry); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->nat_get) + return SW_NOT_SUPPORTED; + + rv = p_api->nat_get(dev_id, get_mode, nat_entry); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->nat_next) + return SW_NOT_SUPPORTED; + + rv = p_api->nat_next(dev_id, next_mode, nat_entry); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->nat_counter_bind) + return SW_NOT_SUPPORTED; + + rv = p_api->nat_counter_bind(dev_id, entry_id, cnt_id, enable); + return rv; +} + +static sw_error_t +_fal_napt_add(a_uint32_t dev_id, fal_napt_entry_t * napt_entry) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->napt_add) + return SW_NOT_SUPPORTED; + + rv = p_api->napt_add(dev_id, napt_entry); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->napt_del) + return SW_NOT_SUPPORTED; + + rv = p_api->napt_del(dev_id, del_mode, napt_entry); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->napt_get) + return SW_NOT_SUPPORTED; + + rv = p_api->napt_get(dev_id, get_mode, napt_entry); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->napt_next) + return SW_NOT_SUPPORTED; + + rv = p_api->napt_next(dev_id, next_mode, napt_entry); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->napt_counter_bind) + return SW_NOT_SUPPORTED; + + rv = p_api->napt_counter_bind(dev_id, entry_id, cnt_id, enable); + return rv; +} + +static sw_error_t +_fal_flow_add(a_uint32_t dev_id, fal_napt_entry_t * napt_entry) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->flow_add) + return SW_NOT_SUPPORTED; + + rv = p_api->flow_add(dev_id, napt_entry); + return rv; +} + +static sw_error_t + +_fal_flow_cookie_set(a_uint32_t dev_id, fal_flow_cookie_t * flow_cookie) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->flow_cookie_set) + return SW_NOT_SUPPORTED; + + rv = p_api->flow_cookie_set(dev_id, flow_cookie); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->flow_rfs_set) + return SW_NOT_SUPPORTED; + + rv = p_api->flow_rfs_set(dev_id, action, rfs); + return rv; +} + + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->flow_del) + return SW_NOT_SUPPORTED; + + rv = p_api->flow_del(dev_id, del_mode, napt_entry); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->flow_get) + return SW_NOT_SUPPORTED; + + rv = p_api->flow_get(dev_id, get_mode, napt_entry); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->flow_next) + return SW_NOT_SUPPORTED; + + rv = p_api->flow_next(dev_id, next_mode, napt_entry); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->flow_counter_bind) + return SW_NOT_SUPPORTED; + + rv = p_api->flow_counter_bind(dev_id, entry_id, cnt_id, enable); + return rv; +} + +static sw_error_t +_fal_nat_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->nat_status_set) + return SW_NOT_SUPPORTED; + + rv = p_api->nat_status_set(dev_id, enable); + return rv; +} + +static sw_error_t +_fal_nat_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->nat_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->nat_status_get(dev_id, enable); + return rv; +} + +static sw_error_t +_fal_nat_hash_mode_set(a_uint32_t dev_id, a_uint32_t mode) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->nat_hash_mode_set) + return SW_NOT_SUPPORTED; + + rv = p_api->nat_hash_mode_set(dev_id, mode); + return rv; +} + +static sw_error_t +_fal_nat_hash_mode_get(a_uint32_t dev_id, a_uint32_t * mode) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->nat_hash_mode_get) + return SW_NOT_SUPPORTED; + + rv = p_api->nat_hash_mode_get(dev_id, mode); + return rv; +} + +static sw_error_t +_fal_napt_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->napt_status_set) + return SW_NOT_SUPPORTED; + + rv = p_api->napt_status_set(dev_id, enable); + return rv; +} + +static sw_error_t +_fal_napt_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->napt_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->napt_status_get(dev_id, enable); + return rv; +} + +static sw_error_t +_fal_napt_mode_set(a_uint32_t dev_id, fal_napt_mode_t mode) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->napt_mode_set) + return SW_NOT_SUPPORTED; + + rv = p_api->napt_mode_set(dev_id, mode); + return rv; +} + +static sw_error_t +_fal_napt_mode_get(a_uint32_t dev_id, fal_napt_mode_t * mode) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->napt_mode_get) + return SW_NOT_SUPPORTED; + + rv = p_api->napt_mode_get(dev_id, mode); + return rv; +} + +static sw_error_t +_fal_nat_prv_base_addr_set(a_uint32_t dev_id, fal_ip4_addr_t addr) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->nat_prv_base_addr_set) + return SW_NOT_SUPPORTED; + + rv = p_api->nat_prv_base_addr_set(dev_id, addr); + return rv; +} + +static sw_error_t +_fal_nat_prv_base_addr_get(a_uint32_t dev_id, fal_ip4_addr_t * addr) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->nat_prv_base_addr_get) + return SW_NOT_SUPPORTED; + + rv = p_api->nat_prv_base_addr_get(dev_id, addr); + return rv; +} + +static sw_error_t +_fal_nat_prv_base_mask_set(a_uint32_t dev_id, fal_ip4_addr_t addr) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->nat_prv_base_mask_set) + return SW_NOT_SUPPORTED; + + rv = p_api->nat_prv_base_mask_set(dev_id, addr); + return rv; +} + +static sw_error_t +_fal_nat_prv_base_mask_get(a_uint32_t dev_id, fal_ip4_addr_t * addr) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->nat_prv_base_mask_get) + return SW_NOT_SUPPORTED; + + rv = p_api->nat_prv_base_mask_get(dev_id, addr); + return rv; +} + +static sw_error_t +_fal_nat_prv_addr_mode_set(a_uint32_t dev_id, a_bool_t map_en) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->nat_prv_addr_mode_set) + return SW_NOT_SUPPORTED; + + rv = p_api->nat_prv_addr_mode_set(dev_id, map_en); + return rv; +} + +static sw_error_t +_fal_nat_prv_addr_mode_get(a_uint32_t dev_id, a_bool_t * map_en) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->nat_prv_addr_mode_get) + return SW_NOT_SUPPORTED; + + rv = p_api->nat_prv_addr_mode_get(dev_id, map_en); + return rv; +} + +static sw_error_t +_fal_nat_pub_addr_add(a_uint32_t dev_id, fal_nat_pub_addr_t * entry) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->nat_pub_addr_add) + return SW_NOT_SUPPORTED; + + rv = p_api->nat_pub_addr_add(dev_id, entry); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->nat_pub_addr_del) + return SW_NOT_SUPPORTED; + + rv = p_api->nat_pub_addr_del(dev_id, del_mode, entry); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->nat_pub_addr_next) + return SW_NOT_SUPPORTED; + + rv = p_api->nat_pub_addr_next(dev_id, next_mode, entry); + return rv; +} + +static sw_error_t +_fal_nat_unk_session_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->nat_unk_session_cmd_set) + return SW_NOT_SUPPORTED; + + rv = p_api->nat_unk_session_cmd_set(dev_id, cmd); + return rv; +} + +static sw_error_t +_fal_nat_unk_session_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->nat_unk_session_cmd_get) + return SW_NOT_SUPPORTED; + + rv = p_api->nat_unk_session_cmd_get(dev_id, cmd); + return rv; +} + +static sw_error_t +_fal_nat_global_set(a_uint32_t dev_id, a_bool_t enable, a_uint32_t portbmp) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->nat_global_set) + return SW_NOT_SUPPORTED; + + rv = p_api->nat_global_set(dev_id, enable, portbmp); + return rv; +} + +/** + * @brief Add one NAT entry to one particular device. + * @details Comments: + Before NAT entry added ip4 private base address must be set + at first. + In parameter nat_entry entry flags must be set + Hardware entry id will be returned. + * @param[in] dev_id device id + * @param[in] nat_entry NAT entry parameter + * @return SW_OK or error code + */ +sw_error_t +fal_nat_add(a_uint32_t dev_id, fal_nat_entry_t * nat_entry) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_nat_add(dev_id, nat_entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Del NAT entries from one particular device. + * @param[in] dev_id device id + * @param[in] del_mode NAT entry delete operation mode + * @param[in] nat_entry NAT entry parameter + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_nat_del(dev_id, del_mode, nat_entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get one NAT entry from one particular device. + * @param[in] dev_id device id + * @param[in] get_mode NAT entry get operation mode + * @param[in] nat_entry NAT entry parameter + * @param[out] nat_entry NAT entry parameter + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_nat_get(dev_id, get_mode, nat_entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Next NAT entries from one particular device. + * @param[in] dev_id device id + * @param[in] next_mode NAT entry next operation mode + * @param[in] nat_entry NAT entry parameter + * @param[out] nat_entry NAT entry parameter + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_nat_next(dev_id, next_mode, nat_entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Bind one counter entry to one NAT entry to one particular device. + * @param[in] dev_id device id + * @param[in] entry_id NAT entry id + * @param[in] cnt_id counter entry id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_nat_counter_bind(dev_id, entry_id, cnt_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Add one NAPT entry to one particular device. + * @details Comments: + Before NAPT entry added related ip4 private base address must be set + at first. + In parameter napt_entry related entry flags must be set + Hardware entry id will be returned. + * @param[in] dev_id device id + * @param[in] napt_entry NAPT entry parameter + * @return SW_OK or error code + */ +sw_error_t +fal_napt_add(a_uint32_t dev_id, fal_napt_entry_t * napt_entry) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_napt_add(dev_id, napt_entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Del NAPT entries from one particular device. + * @param[in] dev_id device id + * @param[in] del_mode NAPT entry delete operation mode + * @param[in] napt_entry NAPT entry parameter + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_napt_del(dev_id, del_mode, napt_entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get one NAPT entry from one particular device. + * @param[in] dev_id device id + * @param[in] get_mode NAPT entry get operation mode + * @param[in] nat_entry NAPT entry parameter + * @param[out] nat_entry NAPT entry parameter + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_napt_get(dev_id, get_mode, napt_entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Next NAPT entries from one particular device. + * @param[in] dev_id device id + * @param[in] next_mode NAPT entry next operation mode + * @param[in] napt_entry NAPT entry parameter + * @param[out] napt_entry NAPT entry parameter + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_napt_next(dev_id, next_mode, napt_entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Bind one counter entry to one NAPT entry to one particular device. + * @param[in] dev_id device id + * @param[in] entry_id NAPT entry id + * @param[in] cnt_id counter entry id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_napt_counter_bind(dev_id, entry_id, cnt_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Add one FLOW entry to one particular device. + * @details Comments: + Before FLOW entry added related ip4 private base address must be set + at first. + In parameter napt_entry related entry flags must be set + Hardware entry id will be returned. + * @param[in] dev_id device id + * @param[in] napt_entry FLOW entry parameter + * @return SW_OK or error code + */ +sw_error_t +fal_flow_add(a_uint32_t dev_id, fal_napt_entry_t * napt_entry) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_flow_add(dev_id, napt_entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Del FLOW entries from one particular device. + * @param[in] dev_id device id + * @param[in] del_mode NAPT entry delete operation mode + * @param[in] napt_entry NAPT entry parameter + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_flow_del(dev_id, del_mode, napt_entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get one FLOW entry from one particular device. + * @param[in] dev_id device id + * @param[in] get_mode FLOW entry get operation mode + * @param[in] nat_entry FLOW entry parameter + * @param[out] nat_entry FLOW entry parameter + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_flow_get(dev_id, get_mode, napt_entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Next FLOW entries from one particular device. + * @param[in] dev_id device id + * @param[in] next_mode FLOW entry next operation mode + * @param[in] napt_entry FLOW entry parameter + * @param[out] napt_entry FLOW entry parameter + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_flow_next(dev_id, next_mode, napt_entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Bind one counter entry to one FLOW entry to one particular device. + * @param[in] dev_id device id + * @param[in] entry_id FLOW entry id + * @param[in] cnt_id counter entry id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_flow_counter_bind(dev_id, entry_id, cnt_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set working status of NAT engine on a particular device + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_nat_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_nat_status_set(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get working status of NAT engine on a particular device + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_nat_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_nat_status_get(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set NAT hash mode on a particular device + * @param[in] dev_id device id + * @param[in] mode NAT hash mode + * @return SW_OK or error code + */ +sw_error_t +fal_nat_hash_mode_set(a_uint32_t dev_id, a_uint32_t mode) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_nat_hash_mode_set(dev_id, mode); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get NAT hash mode on a particular device + * @param[in] dev_id device id + * @param[out] mode NAT hash mode + * @return SW_OK or error code + */ +sw_error_t +fal_nat_hash_mode_get(a_uint32_t dev_id, a_uint32_t * mode) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_nat_hash_mode_get(dev_id, mode); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set working status of NAPT engine on a particular device + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_napt_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_napt_status_set(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get working status of NAPT engine on a particular device + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_napt_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_napt_status_get(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set working mode of NAPT engine on a particular device + * @param[in] dev_id device id + * @param[in] mode NAPT mode + * @return SW_OK or error code + */ +sw_error_t +fal_napt_mode_set(a_uint32_t dev_id, fal_napt_mode_t mode) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_napt_mode_set(dev_id, mode); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get working mode of NAPT engine on a particular device + * @param[in] dev_id device id + * @param[out] mode NAPT mode + * @return SW_OK or error code + */ +sw_error_t +fal_napt_mode_get(a_uint32_t dev_id, fal_napt_mode_t * mode) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_napt_mode_get(dev_id, mode); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set IP4 private base address on a particular device + * @details Comments: + Only 20bits is meaning which 20bits is determined by private address mode. + * @param[in] dev_id device id + * @param[in] addr private base address + * @return SW_OK or error code + */ +sw_error_t +fal_nat_prv_base_addr_set(a_uint32_t dev_id, fal_ip4_addr_t addr) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_nat_prv_base_addr_set(dev_id, addr); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IP4 private base address on a particular device + * @param[in] dev_id device id + * @param[out] addr private base address + * @return SW_OK or error code + */ +sw_error_t +fal_nat_prv_base_addr_get(a_uint32_t dev_id, fal_ip4_addr_t * addr) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_nat_prv_base_addr_get(dev_id, addr); + FAL_API_UNLOCK; + 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; + + FAL_API_LOCK; + rv = _fal_nat_prv_base_mask_set(dev_id, addr); + FAL_API_UNLOCK; + 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; + + FAL_API_LOCK; + rv = _fal_nat_prv_base_mask_get(dev_id, addr); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set IP4 private base address mode on a particular device + * @details Comments: + If map_en equal true means bits31-20 bits15-8 are base address + else bits31-12 are base address. + * @param[in] dev_id device id + * @param[in] map_en private base mapping mode + * @return SW_OK or error code + */ +sw_error_t +fal_nat_prv_addr_mode_set(a_uint32_t dev_id, a_bool_t map_en) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_nat_prv_addr_mode_set(dev_id, map_en); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IP4 private base address mode on a particular device + * @param[in] dev_id device id + * @param[out] map_en private base mapping mode + * @return SW_OK or error code + */ +sw_error_t +fal_nat_prv_addr_mode_get(a_uint32_t dev_id, a_bool_t * map_en) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_nat_prv_addr_mode_get(dev_id, map_en); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Add one public address entry to one particular device. + * @details Comments: + Hardware entry id will be returned. + * @param[in] dev_id device id + * @param[in] entry public address entry parameter + * @return SW_OK or error code + */ +sw_error_t +fal_nat_pub_addr_add(a_uint32_t dev_id, fal_nat_pub_addr_t * entry) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_nat_pub_addr_add(dev_id, entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete one public address entry from one particular device. + * @param[in] dev_id device id + * @param[in] del_mode delete operaton mode + * @param[in] entry public address entry parameter + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_nat_pub_addr_del(dev_id, del_mode, entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Next public address entries from one particular device. + * @param[in] dev_id device id + * @param[in] next_mode next operaton mode + * @param[out] entry public address entry parameter + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_nat_pub_addr_next(dev_id, next_mode, entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set forwarding command for those packets miss NAT entries on a particular device. + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +sw_error_t +fal_nat_unk_session_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_nat_unk_session_cmd_set(dev_id, cmd); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get forwarding command for those packets miss NAT entries on a particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +sw_error_t +fal_nat_unk_session_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_nat_unk_session_cmd_get(dev_id, cmd); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set working status of NAPT engine on a particular device + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] sync_cnt_enable A_TRUE or A_FALSE + * @param[in] portbmp port bitmap + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + nf_athrs17_hnat_sync_counter_en = (int)sync_cnt_enable; + rv = _fal_nat_global_set(dev_id, enable, portbmp); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Add/del one FLOW cookie entry to one particular device. + * @details Comments: + Before FLOW entry added related ip4 private base address must be set + at first. + In parameter napt_entry related entry flags must be set + Hardware entry id will be returned. + * @param[in] dev_id device id + * @param[in] napt_entry FLOW entry parameter + * @return SW_OK or error code + */ +sw_error_t +fal_flow_cookie_set(a_uint32_t dev_id, fal_flow_cookie_t * flow_cookie) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_flow_cookie_set(dev_id, flow_cookie); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Add/del one FLOW rfs entry to one particular device. + * @details Comments: + Before FLOW entry added related ip4 private base address must be set + at first. + In parameter napt_entry related entry flags must be set + Hardware entry id will be returned. + * @param[in] dev_id device id + * @param[in] napt_entry FLOW entry parameter + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_flow_rfs_set(dev_id, action, rfs); + FAL_API_UNLOCK; + return rv; +} + + +int ssdk_flow_cookie_set( + u32 protocol, __be32 src_ip, + __be16 src_port, __be32 dst_ip, + __be16 dst_port, u16 flowcookie) +{ + fal_flow_cookie_t flow_cookie; + if(protocol == 17) { + flow_cookie.proto = 0x2; + } else { + flow_cookie.proto = 0x1; + } + flow_cookie.src_addr = ntohl(src_ip); + flow_cookie.dst_addr = ntohl(dst_ip); + flow_cookie.src_port = ntohs(src_port); + flow_cookie.dst_port = ntohs(dst_port); + flow_cookie.flow_cookie = flowcookie; + return fal_flow_cookie_set(0, &flow_cookie); +} + +int ssdk_rfs_ipct_rule_set( + __be32 ip_src, __be32 ip_dst, + __be16 sport, __be16 dport, uint8_t proto, + u16 loadbalance, bool action) +{ + fal_flow_rfs_t rfs; + if(proto == 17) { + rfs.proto = 0x2; + } else { + rfs.proto = 0x1; + } + rfs.src_addr = ntohl(ip_src); + rfs.dst_addr = ntohl(ip_dst); + rfs.src_port = ntohs(sport); + rfs.dst_port = ntohs(dport); + rfs.load_balance = loadbalance; + if(fal_flow_rfs_set(0, action, &rfs)) + return -1; + return 0; +} + +#if 0 +EXPORT_SYMBOL(ssdk_flow_cookie_set); +EXPORT_SYMBOL(ssdk_rfs_ipct_rule_set); +#endif + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/fal/fal_policer.c b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_policer.c new file mode 100755 index 000000000..0e100bc84 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_policer.c @@ -0,0 +1,343 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "fal_policer.h" +#include "hsl_api.h" +#include "adpt.h" + +#include +#include + + +#ifndef IN_POLICER_MINI +sw_error_t +_fal_acl_policer_counter_get(a_uint32_t dev_id, a_uint32_t index, + fal_policer_counter_t *counter) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_acl_policer_counter_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_acl_policer_counter_get(dev_id, index, counter); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_policer_counter_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_policer_counter_get(dev_id, port_id, counter); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_policer_entry_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_policer_entry_get(dev_id, port_id, policer, action); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_policer_entry_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_policer_entry_set(dev_id, port_id, 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_acl_policer_entry_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_acl_policer_entry_get(dev_id, index, 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_acl_policer_entry_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_acl_policer_entry_set(dev_id, index, policer, action); + return rv; +} +sw_error_t +_fal_policer_timeslot_get(a_uint32_t dev_id, a_uint32_t *timeslot) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_policer_time_slot_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_policer_time_slot_get(dev_id, timeslot); + return rv; +} +#endif +sw_error_t +_fal_policer_timeslot_set(a_uint32_t dev_id, a_uint32_t timeslot) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_policer_time_slot_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_policer_time_slot_set(dev_id, timeslot); + return rv; +} + +#ifndef IN_POLICER_MINI +sw_error_t +_fal_port_policer_compensation_byte_get(a_uint32_t dev_id, a_uint32_t port_id, + a_uint32_t *length) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_compensation_byte_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_compensation_byte_get(dev_id, port_id, length); + return rv; +} +#endif +sw_error_t +_fal_port_policer_compensation_byte_set(a_uint32_t dev_id, a_uint32_t port_id, + a_uint32_t length) + +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_compensation_byte_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_compensation_byte_set(dev_id, port_id, length); + return rv; +} + +#ifndef IN_POLICER_MINI +sw_error_t +_fal_policer_global_counter_get(a_uint32_t dev_id, + fal_policer_global_counter_t *counter) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_policer_global_counter_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_policer_global_counter_get(dev_id, counter); + return rv; +} + +/*insert flag for inner fal, don't remove it*/ + +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_acl_policer_counter_get(dev_id, index, counter); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_policer_counter_get(dev_id, port_id, counter); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_policer_entry_get(dev_id, port_id, policer, action); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_policer_entry_set(dev_id, port_id, policer, action); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_acl_policer_entry_get(dev_id, index, policer, action); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_acl_policer_entry_set(dev_id, index, policer, action); + FAL_API_UNLOCK; + return rv; +} +sw_error_t +fal_policer_timeslot_get(a_uint32_t dev_id, a_uint32_t *timeslot) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _fal_policer_timeslot_get(dev_id, timeslot); + FAL_API_UNLOCK; + return rv; +} +#endif +sw_error_t +fal_policer_timeslot_set(a_uint32_t dev_id, a_uint32_t timeslot) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _fal_policer_timeslot_set(dev_id, timeslot); + FAL_API_UNLOCK; + return rv; +} + +#ifndef IN_POLICER_MINI +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_policer_compensation_byte_get(dev_id, port_id, length); + FAL_API_UNLOCK; + return rv; +} +#endif +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_policer_compensation_byte_set(dev_id, port_id, length); + FAL_API_UNLOCK; + return rv; +} +#ifndef IN_POLICER_MINI +sw_error_t +fal_policer_global_counter_get(a_uint32_t dev_id, + fal_policer_global_counter_t *counter) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _fal_policer_global_counter_get(dev_id, counter); + FAL_API_UNLOCK; + return rv; +} +#endif + +#ifndef IN_POLICER_MINI +EXPORT_SYMBOL(fal_acl_policer_counter_get); +EXPORT_SYMBOL(fal_port_policer_counter_get); +EXPORT_SYMBOL(fal_port_policer_entry_get); +EXPORT_SYMBOL(fal_port_policer_entry_set); +EXPORT_SYMBOL(fal_acl_policer_entry_get); +EXPORT_SYMBOL(fal_acl_policer_entry_set); +EXPORT_SYMBOL(fal_policer_timeslot_get); +EXPORT_SYMBOL(fal_port_policer_compensation_byte_get); +EXPORT_SYMBOL(fal_policer_global_counter_get); +#endif +EXPORT_SYMBOL(fal_policer_timeslot_set); +EXPORT_SYMBOL(fal_port_policer_compensation_byte_set); + +/*insert flag for outter fal, don't remove it*/ diff --git a/feeds/ipq807x/qca-ssdk/src/src/fal/fal_port_ctrl.c b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_port_ctrl.c new file mode 100644 index 000000000..8f3d92a66 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_port_ctrl.c @@ -0,0 +1,3728 @@ +/* + * Copyright (c) 2012, 2015-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 + * @{ + */ +#include "sw.h" +#include "fal_port_ctrl.h" +#include "hsl_api.h" +/*qca808x_end*/ +#include "adpt.h" + +#include +#include +/*qca808x_start*/ +static 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; + hsl_api_t *p_api; +/*qca808x_end*/ + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_duplex_set != NULL) { + rv = p_adpt_api->adpt_port_duplex_set(dev_id, port_id, duplex); + return rv; + } +/*qca808x_start*/ + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_duplex_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_duplex_set (dev_id, port_id, duplex); + return rv; +} + +static 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; + hsl_api_t *p_api; +/*qca808x_end*/ + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_speed_set != NULL) { + rv = p_adpt_api->adpt_port_speed_set(dev_id, port_id, speed); + return rv; + } +/*qca808x_start*/ + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_speed_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_speed_set (dev_id, port_id, speed); + return rv; +} +/*qca808x_end*/ +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_port_flowctrl_set) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_port_flowctrl_set(dev_id, port_id, enable); + return rv; + } + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_flowctrl_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_flowctrl_set (dev_id, port_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_port_flowctrl_forcemode_set) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_port_flowctrl_forcemode_set(dev_id, port_id, enable); + return rv; + } + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_flowctrl_forcemode_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_flowctrl_forcemode_set (dev_id, port_id, enable); + return rv; +} +/*qca808x_start*/ +static 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; + hsl_api_t *p_api; +/*qca808x_end*/ + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_speed_get != NULL) { + rv = p_adpt_api->adpt_port_speed_get(dev_id, port_id, pspeed); + return rv; + } +/*qca808x_start*/ + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_speed_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_speed_get (dev_id, port_id, pspeed); + return rv; +} + +static 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; + hsl_api_t *p_api; +/*qca808x_end*/ + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_duplex_get != NULL) { + rv = p_adpt_api->adpt_port_duplex_get(dev_id, port_id, pduplex); + return rv; + } +/*qca808x_start*/ + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_duplex_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_duplex_get (dev_id, port_id, pduplex); + return rv; +} + +static sw_error_t +_fal_port_autoneg_enable (a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + hsl_api_t *p_api; +/*qca808x_end*/ + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_autoneg_enable != NULL) { + rv = p_adpt_api->adpt_port_autoneg_enable(dev_id, port_id); + return rv; + } +/*qca808x_start*/ + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_autoneg_enable) + return SW_NOT_SUPPORTED; + + rv = p_api->port_autoneg_enable (dev_id, port_id); + return rv; +} + +static sw_error_t +_fal_port_autoneg_restart (a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + hsl_api_t *p_api; +/*qca808x_end*/ + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_autoneg_restart != NULL) { + rv = p_adpt_api->adpt_port_autoneg_restart(dev_id, port_id); + return rv; + } +/*qca808x_start*/ + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_autoneg_restart) + return SW_NOT_SUPPORTED; + + rv = p_api->port_autoneg_restart (dev_id, port_id); + return rv; +} + + +static 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; + hsl_api_t *p_api; +/*qca808x_end*/ + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_autoneg_adv_set != NULL) { + rv = p_adpt_api->adpt_port_autoneg_adv_set(dev_id, port_id, autoadv); + return rv; + } +/*qca808x_start*/ + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_autoneg_adv_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_autoneg_adv_set (dev_id, port_id, autoadv); + return rv; +} + +static 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; + hsl_api_t *p_api; +/*qca808x_end*/ + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_autoneg_status_get != NULL) { + rv = p_adpt_api->adpt_port_autoneg_status_get(dev_id, port_id, status); + return rv; + } +/*qca808x_start*/ + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_autoneg_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_autoneg_status_get (dev_id, port_id, status); + return rv; +} + +static 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; + hsl_api_t *p_api; +/*qca808x_end*/ + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_autoneg_adv_get != NULL) { + rv = p_adpt_api->adpt_port_autoneg_adv_get(dev_id, port_id, autoadv); + return rv; + } +/*qca808x_start*/ + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_autoneg_adv_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_autoneg_adv_get (dev_id, port_id, autoadv); + return rv; +} +/*qca808x_end*/ +#ifndef IN_PORTCONTROL_MINI +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_hdr_status_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_hdr_status_set (dev_id, port_id, enable); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_hdr_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_hdr_status_get (dev_id, port_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_port_flowctrl_get) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_port_flowctrl_get(dev_id, port_id, enable); + return rv; + } + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_flowctrl_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_flowctrl_get (dev_id, port_id, enable); + return rv; +} + + + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_port_flowctrl_forcemode_get) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_port_flowctrl_forcemode_get(dev_id, port_id, enable); + return rv; + } + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_flowctrl_forcemode_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_flowctrl_forcemode_get (dev_id, port_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_powersave_set != NULL) { + rv = p_adpt_api->adpt_port_powersave_set(dev_id, port_id, enable); + return rv; + } + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_powersave_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_powersave_set (dev_id, port_id, enable); + return rv; +} + + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_powersave_get != NULL) { + rv = p_adpt_api->adpt_port_powersave_get(dev_id, port_id, enable); + return rv; + } + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_powersave_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_powersave_get (dev_id, port_id, enable); + return rv; +} +/*qca808x_start*/ +static 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; + hsl_api_t *p_api; +/*qca808x_end*/ + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_hibernate_set != NULL) { + rv = p_adpt_api->adpt_port_hibernate_set(dev_id, port_id, enable); + return rv; + } +/*qca808x_start*/ + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_hibernate_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_hibernate_set (dev_id, port_id, enable); + return rv; +} + + +static 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; + hsl_api_t *p_api; +/*qca808x_end*/ + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_hibernate_get != NULL) { + rv = p_adpt_api->adpt_port_hibernate_get(dev_id, port_id, enable); + return rv; + } +/*qca808x_start*/ + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_hibernate_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_hibernate_get (dev_id, port_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; +/*qca808x_end*/ + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_cdt != NULL) { + rv = p_adpt_api->adpt_port_cdt(dev_id, port_id, mdi_pair, cable_status, cable_len); + return rv; + } +/*qca808x_start*/ + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_cdt) + return SW_NOT_SUPPORTED; + + rv = p_api->port_cdt (dev_id, port_id, mdi_pair, cable_status, cable_len); + return rv; +} +/*qca808x_end*/ +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_rxhdr_mode_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_rxhdr_mode_get (dev_id, port_id, mode); + return rv; +} +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_txhdr_mode_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_txhdr_mode_get (dev_id, port_id, mode); + return rv; +} +static sw_error_t +_fal_header_type_get (a_uint32_t dev_id, a_bool_t * enable, a_uint32_t * type) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->header_type_get) + return SW_NOT_SUPPORTED; + + rv = p_api->header_type_get (dev_id, enable, type); + return rv; +} +#endif +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_rxhdr_mode_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_rxhdr_mode_set (dev_id, port_id, mode); + return rv; +} + + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_txhdr_mode_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_txhdr_mode_set (dev_id, port_id, mode); + return rv; +} + + + +static sw_error_t +_fal_header_type_set (a_uint32_t dev_id, a_bool_t enable, a_uint32_t type) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->header_type_set) + return SW_NOT_SUPPORTED; + + rv = p_api->header_type_set (dev_id, enable, type); + return rv; +} + + + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_port_txmac_status_set) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_port_txmac_status_set(dev_id, port_id, enable); + return rv; + } + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_txmac_status_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_txmac_status_set (dev_id, port_id, enable); + return rv; +} + + + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_port_rxmac_status_set) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_port_rxmac_status_set(dev_id, port_id, enable); + return rv; + } + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_rxmac_status_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_rxmac_status_set (dev_id, port_id, enable); + return rv; +} + + + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_port_txfc_status_set) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_port_txfc_status_set(dev_id, port_id, enable); + return rv; + } + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_txfc_status_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_txfc_status_set (dev_id, port_id, enable); + return rv; +} + + + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_port_rxfc_status_set) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_port_rxfc_status_set(dev_id, port_id, enable); + return rv; + } + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_rxfc_status_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_rxfc_status_set (dev_id, port_id, enable); + return rv; +} +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_port_txfc_status_get) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_port_txfc_status_get(dev_id, port_id, enable); + return rv; + } + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_txfc_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_txfc_status_get (dev_id, port_id, enable); + return rv; +} +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_port_rxfc_status_get) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_port_rxfc_status_get(dev_id, port_id, enable); + return rv; + } + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_rxfc_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_rxfc_status_get (dev_id, port_id, enable); + return rv; +} +/*qca808x_start*/ +static 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; + hsl_api_t *p_api; +/*qca808x_end*/ + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_link_status_get != NULL) { + rv = p_adpt_api->adpt_port_link_status_get(dev_id, port_id, status); + return rv; + } +/*qca808x_start*/ + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_link_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_link_status_get (dev_id, port_id, status); + return rv; +} + +static sw_error_t +_fal_port_power_off (a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + hsl_api_t *p_api; +/*qca808x_end*/ + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_power_off != NULL) { + rv = p_adpt_api->adpt_port_power_off(dev_id, port_id); + return rv; + } +/*qca808x_start*/ + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_power_off) + return SW_NOT_SUPPORTED; + + rv = p_api->port_power_off (dev_id, port_id); + return rv; +} + +static sw_error_t +_fal_port_power_on (a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + hsl_api_t *p_api; +/*qca808x_end*/ + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_power_on != NULL) { + rv = p_adpt_api->adpt_port_power_on(dev_id, port_id); + return rv; + } +/*qca808x_start*/ + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_power_on) + return SW_NOT_SUPPORTED; + + rv = p_api->port_power_on (dev_id, port_id); + return rv; +} +/*qca808x_end*/ +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_link_forcemode_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_link_forcemode_set (dev_id, port_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_link_forcemode_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_link_forcemode_get (dev_id, port_id, enable); + return rv; +} +#ifndef IN_PORTCONTROL_MINI +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_port_txmac_status_get) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_port_txmac_status_get(dev_id, port_id, enable); + return rv; + } + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_txmac_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_txmac_status_get (dev_id, port_id, enable); + return rv; +} +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_port_rxmac_status_get) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_port_rxmac_status_get(dev_id, port_id, enable); + return rv; + } + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_rxmac_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_rxmac_status_get (dev_id, port_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_bp_status_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_bp_status_set (dev_id, port_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_bp_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_bp_status_get (dev_id, port_id, enable); + return rv; +} + +static sw_error_t +_fal_ports_link_status_get (a_uint32_t dev_id, a_uint32_t * status) +{ + sw_error_t rv; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_ports_link_status_get != NULL) { + rv = p_adpt_api->adpt_ports_link_status_get(dev_id, status); + return rv; + } + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->ports_link_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->ports_link_status_get (dev_id, status); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_port_mac_loopback_set) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_port_mac_loopback_set(dev_id, port_id, enable); + return rv; + } + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_mac_loopback_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_mac_loopback_set (dev_id, port_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_port_mac_loopback_get) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_port_mac_loopback_get(dev_id, port_id, enable); + return rv; + } + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_mac_loopback_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_mac_loopback_get (dev_id, port_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_congestion_drop_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_congestion_drop_set (dev_id, port_id, queue_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_congestion_drop_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_congestion_drop_get (dev_id, port_id, queue_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->ring_flow_ctrl_thres_set) + return SW_NOT_SUPPORTED; + + rv = p_api->ring_flow_ctrl_thres_set (dev_id, ring_id, on_thres, off_thres); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->ring_flow_ctrl_thres_get) + return SW_NOT_SUPPORTED; + + rv = p_api->ring_flow_ctrl_thres_get (dev_id, ring_id, on_thres, off_thres); + return rv; +} +/*qca808x_start*/ +static 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; + hsl_api_t *p_api; +/*qca808x_end*/ + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_8023az_set != NULL) { + rv = p_adpt_api->adpt_port_8023az_set(dev_id, port_id, enable); + return rv; + } +/*qca808x_start*/ + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_8023az_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_8023az_set (dev_id, port_id, enable); + return rv; +} + + +static 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; + hsl_api_t *p_api; +/*qca808x_end*/ + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_8023az_get != NULL) { + rv = p_adpt_api->adpt_port_8023az_get(dev_id, port_id, enable); + return rv; + } +/*qca808x_start*/ + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_8023az_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_8023az_get (dev_id, port_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; +/*qca808x_end*/ + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_mdix_set != NULL) { + rv = p_adpt_api->adpt_port_mdix_set(dev_id, port_id, mode); + return rv; + } +/*qca808x_start*/ + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_mdix_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_mdix_set (dev_id, port_id, mode); + return rv; +} + +static 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; + hsl_api_t *p_api; +/*qca808x_end*/ + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_mdix_get != NULL) { + rv = p_adpt_api->adpt_port_mdix_get(dev_id, port_id, mode); + return rv; + } +/*qca808x_start*/ + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_mdix_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_mdix_get (dev_id, port_id, mode); + return rv; +} + +static 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; + hsl_api_t *p_api; +/*qca808x_end*/ + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_mdix_status_get != NULL) { + rv = p_adpt_api->adpt_port_mdix_status_get(dev_id, port_id, mode); + return rv; + } +/*qca808x_start*/ + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_mdix_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_mdix_status_get (dev_id, port_id, mode); + return rv; +} +/*qca808x_end*/ +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_combo_prefer_medium_set != NULL) { + rv = p_adpt_api->adpt_port_combo_prefer_medium_set(dev_id, port_id, medium); + return rv; + } + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_combo_prefer_medium_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_combo_prefer_medium_set (dev_id, port_id, medium); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_combo_prefer_medium_get != NULL) { + rv = p_adpt_api->adpt_port_combo_prefer_medium_get(dev_id, port_id, medium); + return rv; + } + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_combo_prefer_medium_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_combo_prefer_medium_get (dev_id, port_id, medium); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_combo_medium_status_get != NULL) { + rv = p_adpt_api->adpt_port_combo_medium_status_get(dev_id, port_id, medium); + return rv; + } + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_combo_medium_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_combo_medium_status_get (dev_id, port_id, medium); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_combo_fiber_mode_set != NULL) { + rv = p_adpt_api->adpt_port_combo_fiber_mode_set(dev_id, port_id, mode); + return rv; + } + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_combo_fiber_mode_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_combo_fiber_mode_set (dev_id, port_id, mode); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_combo_fiber_mode_get != NULL) { + rv = p_adpt_api->adpt_port_combo_fiber_mode_get(dev_id, port_id, mode); + return rv; + } + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_combo_fiber_mode_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_combo_fiber_mode_get (dev_id, port_id, mode); + return rv; +} +/*qca808x_start*/ +static 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; + hsl_api_t *p_api; +/*qca808x_end*/ + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_local_loopback_set != NULL) { + rv = p_adpt_api->adpt_port_local_loopback_set(dev_id, port_id, enable); + return rv; + } +/*qca808x_start*/ + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_local_loopback_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_local_loopback_set (dev_id, port_id, enable); + return rv; +} + + +static 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; + hsl_api_t *p_api; +/*qca808x_end*/ + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_local_loopback_get != NULL) { + rv = p_adpt_api->adpt_port_local_loopback_get(dev_id, port_id, enable); + return rv; + } +/*qca808x_start*/ + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_local_loopback_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_local_loopback_get (dev_id, port_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; +/*qca808x_end*/ + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_remote_loopback_set != NULL) { + rv = p_adpt_api->adpt_port_remote_loopback_set(dev_id, port_id, enable); + return rv; + } +/*qca808x_start*/ + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_remote_loopback_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_remote_loopback_set (dev_id, port_id, enable); + return rv; +} + + +static 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; + hsl_api_t *p_api; +/*qca808x_end*/ + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_remote_loopback_get!= NULL) { + rv = p_adpt_api->adpt_port_remote_loopback_get(dev_id, port_id, enable); + return rv; + } +/*qca808x_start*/ + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_remote_loopback_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_remote_loopback_get (dev_id, port_id, enable); + return rv; +} + +static sw_error_t +_fal_port_reset (a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + hsl_api_t *p_api; +/*qca808x_end*/ + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_reset != NULL) { + rv = p_adpt_api->adpt_port_reset(dev_id, port_id); + return rv; + } +/*qca808x_start*/ + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_reset) + return SW_NOT_SUPPORTED; + + rv = p_api->port_reset (dev_id, port_id); + return rv; +} + + +static 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; + hsl_api_t *p_api; +/*qca808x_end*/ + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_phy_id_get != NULL) { + rv = p_adpt_api->adpt_port_phy_id_get(dev_id, port_id, org_id, rev_id); + return rv; + } +/*qca808x_start*/ + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_phy_id_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_phy_id_get (dev_id, port_id,org_id,rev_id); + return rv; +} + +static 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; + hsl_api_t *p_api; +/*qca808x_end*/ + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_wol_status_set != NULL) { + rv = p_adpt_api->adpt_port_wol_status_set(dev_id, port_id, enable); + return rv; + } +/*qca808x_start*/ + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_wol_status_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_wol_status_set (dev_id, port_id,enable); + return rv; +} + +static 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; + hsl_api_t *p_api; +/*qca808x_end*/ + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_wol_status_get != NULL) { + rv = p_adpt_api->adpt_port_wol_status_get(dev_id, port_id, enable); + return rv; + } +/*qca808x_start*/ + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_wol_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_wol_status_get (dev_id, port_id,enable); + return rv; +} + +static 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; + hsl_api_t *p_api; +/*qca808x_end*/ + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_magic_frame_mac_set != NULL) { + rv = p_adpt_api->adpt_port_magic_frame_mac_set(dev_id, port_id, mac); + return rv; + } +/*qca808x_start*/ + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_magic_frame_mac_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_magic_frame_mac_set (dev_id, port_id, mac); + return rv; +} + +static 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; + hsl_api_t *p_api; +/*qca808x_end*/ + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_magic_frame_mac_get != NULL) { + rv = p_adpt_api->adpt_port_magic_frame_mac_get(dev_id, port_id, mac); + return rv; + } +/*qca808x_start*/ + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_magic_frame_mac_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_magic_frame_mac_get (dev_id, port_id, mac); + return rv; +} +/*qca808x_end*/ +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_interface_mode_set != NULL) { + rv = p_adpt_api->adpt_port_interface_mode_set(dev_id, port_id, mode); + return rv; + } + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_interface_mode_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_interface_mode_set (dev_id, port_id, mode); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_interface_mode_get != NULL) { + rv = p_adpt_api->adpt_port_interface_mode_get(dev_id, port_id, mode); + return rv; + } + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_interface_mode_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_interface_mode_get (dev_id, port_id, mode); + return rv; +} +/*qca808x_start*/ +static 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; + hsl_api_t *p_api; +/*qca808x_end*/ + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_interface_mode_status_get != NULL) { + rv = p_adpt_api->adpt_port_interface_mode_status_get(dev_id, port_id, mode); + return rv; + } +/*qca808x_start*/ + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_interface_mode_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_interface_mode_status_get (dev_id, port_id, mode); + return rv; +} + +static sw_error_t +_fal_port_counter_set (a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + hsl_api_t *p_api; +/*qca808x_end*/ + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_counter_set != NULL) { + rv = p_adpt_api->adpt_port_counter_set(dev_id, port_id, enable); + return rv; + } +/*qca808x_start*/ + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_counter_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_counter_set (dev_id, port_id, enable); + return rv; +} + + +static sw_error_t +_fal_port_counter_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + hsl_api_t *p_api; +/*qca808x_end*/ + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_counter_get != NULL) { + rv = p_adpt_api->adpt_port_counter_get(dev_id, port_id, enable); + return rv; + } +/*qca808x_start*/ + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_counter_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_counter_get (dev_id, port_id, enable); + return rv; +} + +static sw_error_t +_fal_port_counter_show (a_uint32_t dev_id, fal_port_t port_id, fal_port_counter_info_t * counter_info) +{ + sw_error_t rv; + hsl_api_t *p_api; +/*qca808x_end*/ + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL && + p_adpt_api->adpt_port_counter_show != NULL) { + rv = p_adpt_api->adpt_port_counter_show(dev_id, port_id, counter_info); + return rv; + } +/*qca808x_start*/ + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + if (NULL == p_api->port_counter_show) + return SW_NOT_SUPPORTED; + + rv = p_api->port_counter_show (dev_id, port_id, counter_info); + return rv; +} +/*qca808x_end*/ +#endif + +sw_error_t +_fal_port_max_frame_size_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t max_frame) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_max_frame_size_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_max_frame_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_max_frame_size_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_max_frame_size_get(dev_id, port_id, max_frame); + return rv; +} + +#ifndef IN_PORTCONTROL_MINI +sw_error_t +_fal_port_mru_set(a_uint32_t dev_id, fal_port_t port_id, + fal_mru_ctrl_t *ctrl) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_mru_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_mru_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_mru_get(dev_id, port_id, ctrl); + return rv; +} +sw_error_t +_fal_port_mtu_set(a_uint32_t dev_id, fal_port_t port_id, + fal_mtu_ctrl_t *ctrl) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_mtu_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_mtu_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_mtu_get(dev_id, port_id, ctrl); + return rv; +} + +sw_error_t +_fal_port_source_filter_get(a_uint32_t dev_id, + fal_port_t port_id, a_bool_t * enable) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_source_filter_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_source_filter_get(dev_id, port_id, enable); + return rv; +} + +sw_error_t +_fal_port_source_filter_set(a_uint32_t dev_id, + fal_port_t port_id, a_bool_t enable) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_source_filter_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_source_filter_set(dev_id, port_id, enable); + return rv; +} + +static 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_source_filter_config_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_source_filter_config_set(dev_id, port_id, + src_filter_config); + return rv; +} + +static 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_source_filter_config_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_source_filter_config_get(dev_id, port_id, + src_filter_config); + return rv; +} + +static sw_error_t +_fal_port_interface_3az_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_interface_3az_status_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_interface_3az_status_set(dev_id, port_id, enable); + return rv; + +} + +static sw_error_t +_fal_port_interface_3az_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_interface_3az_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_interface_3az_status_get(dev_id, port_id, enable); + return rv; + +} + +static 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 = SW_OK; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_port_promisc_mode_get) { + return SW_NOT_SUPPORTED; + } + + rv = p_adpt_api->adpt_port_promisc_mode_get(dev_id, port_id, enable); + return rv; + } + + return rv; +} +#endif + +static 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 = SW_OK; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_port_promisc_mode_set) { + return SW_NOT_SUPPORTED; + } + + rv = p_adpt_api->adpt_port_promisc_mode_set(dev_id, port_id, enable); + return rv; + } + + return rv; +} + +static 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) +{ + + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_interface_eee_cfg_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_interface_eee_cfg_set(dev_id, port_id, port_eee_cfg); + return rv; + +} + +static 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_interface_eee_cfg_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_interface_eee_cfg_get(dev_id, port_id, port_eee_cfg); + return rv; + +} +static sw_error_t +_fal_switch_port_loopback_set(a_uint32_t dev_id, fal_port_t port_id, + fal_loopback_config_t *loopback_cfg) +{ + + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_switch_port_loopback_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_switch_port_loopback_set(dev_id, port_id, loopback_cfg); + return rv; + +} + +static sw_error_t +_fal_switch_port_loopback_get(a_uint32_t dev_id, fal_port_t port_id, + fal_loopback_config_t *loopback_cfg) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + if (NULL == p_api->adpt_switch_port_loopback_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_switch_port_loopback_get(dev_id, port_id, loopback_cfg); + return rv; + +} + +/*qca808x_start*/ +/*insert flag for inner fal, don't remove it*/ +/** + * @brief Set duplex mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] duplex duplex mode + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_duplex_set (dev_id, port_id, duplex); + FAL_API_UNLOCK; + return rv; +} + + + +/** + * @brief Set speed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] speed port speed + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_speed_set (dev_id, port_id, speed); + FAL_API_UNLOCK; + return rv; +} +/** + * @brief Get duplex mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] duplex duplex mode + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_duplex_get (dev_id, port_id, pduplex); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get speed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] speed port speed + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_speed_get (dev_id, port_id, pspeed); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Enable auto negotiation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @return SW_OK or error code + */ +sw_error_t +fal_port_autoneg_enable (a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_port_autoneg_enable (dev_id, port_id); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Restart auto negotiation procedule on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @return SW_OK or error code + */ +sw_error_t +fal_port_autoneg_restart (a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_port_autoneg_restart (dev_id, port_id); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set auto negotiation advtisement ability on a particular port. + * @details Comments: + * auto negotiation advtisement ability is defined by macro such as + * FAL_PHY_ADV_10T_HD, FAL_PHY_ADV_PAUSE... + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] autoadv auto negotiation advtisement ability bit map + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_autoneg_adv_set (dev_id, port_id, autoadv); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get auto negotiation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] status A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_autoneg_status_get (dev_id, port_id, status); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get auto negotiation advtisement ability on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] autoadv auto negotiation advtisement ability bit map + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_autoneg_adv_get (dev_id, port_id, autoadv); + FAL_API_UNLOCK; + return rv; +} +/*qca808x_end*/ +#ifndef IN_PORTCONTROL_MINI +/** + * @brief Set status of Atheros header packets parsed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_hdr_status_set (dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get status of Atheros header packets parsed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_hdr_status_get (dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + + +/** + * @brief Get flow control status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_flowctrl_get (dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + + + +/** + * @brief Get flow control force mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_flowctrl_forcemode_get (dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set powersaving status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_powersave_set (dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get powersaving status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_powersave_get (dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} +/*qca808x_start*/ +/** + * @brief Set hibernate status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_hibernate_set (dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get hibernate status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_hibernate_get (dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief cable diagnostic test. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mdi_pair mdi pair id + * @param[out] cable_status cable status + * @param[out] cable_len cable len + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_cdt (dev_id, port_id, mdi_pair, cable_status, cable_len); + FAL_API_UNLOCK; + return rv; +} +/*qca808x_end*/ +/** + * @brief Get status of Atheros header packets parsed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_rxhdr_mode_get (dev_id, port_id, mode); + FAL_API_UNLOCK; + return rv; +} +/** + * @brief Get status of Atheros header packets parsed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_txhdr_mode_get (dev_id, port_id, mode); + FAL_API_UNLOCK; + return rv; +} +/** + * @brief Get status of Atheros header type value on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @param[out] type header type value + * @return SW_OK or error code + */ +sw_error_t +fal_header_type_get (a_uint32_t dev_id, a_bool_t * enable, a_uint32_t * type) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_header_type_get (dev_id, enable, type); + FAL_API_UNLOCK; + return rv; +} +/** + * @brief Get status of txmac on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_txmac_status_get (dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} +/** + * @brief Get status of rxmac on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_rxmac_status_get (dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Set flow control status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_flowctrl_set (dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flow control force mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_flowctrl_forcemode_set (dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of Atheros header packets parsed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_rxhdr_mode_set (dev_id, port_id, mode); + FAL_API_UNLOCK; + return rv; +} + + + +/** + * @brief Set status of Atheros header packets parsed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_txhdr_mode_set (dev_id, port_id, mode); + FAL_API_UNLOCK; + return rv; +} + + + +/** + * @brief Set status of Atheros header type value on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] type header type value + * @return SW_OK or error code + */ +sw_error_t +fal_header_type_set (a_uint32_t dev_id, a_bool_t enable, a_uint32_t type) +{ + sw_error_t rv; + FAL_API_LOCK; + rv = _fal_header_type_set (dev_id, enable, type); + FAL_API_UNLOCK; + return rv; +} + + + +/** + * @brief Set status of txmac on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + FAL_API_LOCK; + rv = _fal_port_txmac_status_set (dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + + + +/** + * @brief Set status of rxmac on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + FAL_API_LOCK; + rv = _fal_port_rxmac_status_set (dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + + + +/** + * @brief Set status of tx flow control on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + FAL_API_LOCK; + rv = _fal_port_txfc_status_set (dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + + + +/** + * @brief Set status of rx flow control on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_rxfc_status_set (dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} +/** + * @brief Set status of rx flow control on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_rxfc_status_get (dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} +/** + * @brief Get status of tx flow control on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_txfc_status_get (dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} +/*qca808x_start*/ +/** + * @brief Get link status on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] status link status up (A_TRUE) or down (A_FALSE) + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_link_status_get (dev_id, port_id, status); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief power off on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] + * @return SW_OK or error code + */ +sw_error_t +fal_port_power_off (a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_port_power_off (dev_id, port_id); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief power on on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] + * @return SW_OK or error code + */ +sw_error_t +fal_port_power_on (a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_port_power_on (dev_id, port_id); + FAL_API_UNLOCK; + return rv; +} +/*qca808x_end*/ +/** + * @brief Set link force mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_link_forcemode_set (dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get link force mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_link_forcemode_get (dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} +#ifndef IN_PORTCONTROL_MINI +/** + * @brief Set status of back pressure on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_bp_status_set (dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of back pressure on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_bp_status_get (dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get link status on all ports. + * @param[in] dev_id device id + * @param[out] status link status bitmap and bit 0 for port 0, bit 1 for port 1, ...etc. + * @return SW_OK or error code + */ +sw_error_t +fal_ports_link_status_get (a_uint32_t dev_id, a_uint32_t * status) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_ports_link_status_get (dev_id, status); + FAL_API_UNLOCK; + return rv; +} + + +/** + * @brief Set loopback on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_mac_loopback_set (dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get link force mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_mac_loopback_get (dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set congestion drop on a particular port queue. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_congestion_drop_set (dev_id, port_id, queue_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get congestion drop on a particular port queue. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] queue_id queue_id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_congestion_drop_get (dev_id, port_id, queue_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flow control threshold on a DMA ring. + * @param[in] dev_id device id + * @param[in] ring_id ring_id + * @param[in] on_thres on_thres + * @param[in] off_thres on_thres + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_ring_flow_ctrl_thres_set (dev_id, ring_id, on_thres, off_thres); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get flow control threshold on a DMA ring. + * @param[in] dev_id device id + * @param[in] ring_id ring_id + * @param[out] on_thres on_thres + * @param[out] off_thres on_thres + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_ring_flow_ctrl_thres_get (dev_id, ring_id, on_thres, off_thres); + FAL_API_UNLOCK; + return rv; +} +/*qca808x_start*/ +/** + * @brief Set 8023az status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_8023az_set (dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get 8023az status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_8023az_get (dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set mdix mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] set mdix mode [mdx , mdix or auto] + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_mdix_set (dev_id, port_id, mode); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mdix on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] set mdx ,mdix or auto + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_mdix_get (dev_id, port_id, mode); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mdix status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] set mdx ,mdix + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_mdix_status_get (dev_id, port_id, mode); + FAL_API_UNLOCK; + return rv; +} +/*qca808x_end*/ +/** + * @brief Set combo prefer medium on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] set combo prefer medium [fiber for copper] + * @return SW_OK or error code + */ +sw_error_t +fal_port_combo_prefer_medium_set (a_uint32_t dev_id, a_uint32_t port_id, + fal_port_medium_t medium) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_port_combo_prefer_medium_set (dev_id, port_id, medium); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get combo prefer medium on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] set combo prefer medium [fiber for copper] + * @return SW_OK or error code + */ +sw_error_t +fal_port_combo_prefer_medium_get (a_uint32_t dev_id, a_uint32_t port_id, + fal_port_medium_t * medium) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_port_combo_prefer_medium_get (dev_id, port_id, medium); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get combo medium status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] get combo [fiber for copper] + * @return SW_OK or error code + */ +sw_error_t +fal_port_combo_medium_status_get (a_uint32_t dev_id, a_uint32_t port_id, + fal_port_medium_t * medium) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_port_combo_medium_status_get (dev_id, port_id, medium); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set combo fiber mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] get combo fiber mode [1000bx or 100fx] + * @return SW_OK or error code + */ +sw_error_t +fal_port_combo_fiber_mode_set (a_uint32_t dev_id, a_uint32_t port_id, + fal_port_fiber_mode_t mode) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_port_combo_fiber_mode_set (dev_id, port_id, mode); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get combo fiber mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] get combo fiber mode [1000bx or 100fx] + * @return SW_OK or error code + */ +sw_error_t +fal_port_combo_fiber_mode_get (a_uint32_t dev_id, a_uint32_t port_id, + fal_port_fiber_mode_t * mode) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_port_combo_fiber_mode_get (dev_id, port_id, mode); + FAL_API_UNLOCK; + return rv; +} +/*qca808x_start*/ +/** + * @brief Set local loopback on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_local_loopback_set (dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get local loopback status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_local_loopback_get (dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set remote loopback on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_remote_loopback_set (dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get remote loopback status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_remote_loopback_get (dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief software reset on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] + * @return SW_OK or error code + */ +sw_error_t +fal_port_reset (a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_port_reset (dev_id, port_id); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief phy id on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_phy_id_get (dev_id, port_id,org_id,rev_id); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief wol status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_wol_status_set (dev_id, port_id,enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief wol status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_wol_status_get (dev_id, port_id,enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief magic frame mac on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_magic_frame_mac_set (dev_id, port_id,mac); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief magic frame mac on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_magic_frame_mac_get (dev_id, port_id,mac); + FAL_API_UNLOCK; + return rv; +} +/*qca808x_end*/ +/** + * @brief interface mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_interface_mode_set (dev_id, port_id,mode); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief interface mode on a particular port. + * @param[in] dev_id device id + * @return SW_OK or error code + */ + static sw_error_t +_fal_port_interface_mode_apply (a_uint32_t dev_id) +{ + sw_error_t rv = SW_OK; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_port_interface_mode_apply) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_port_interface_mode_apply(dev_id); + return rv; + } + + return rv; +} + +sw_error_t +fal_port_interface_mode_apply (a_uint32_t dev_id) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_interface_mode_apply (dev_id); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief interface mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] + * @return SW_OK or error code + */ +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_interface_mode_get (dev_id, port_id,mode); + FAL_API_UNLOCK; + return rv; +} +/*qca808x_start*/ +/** + * @brief interface mode status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_interface_mode_status_get (dev_id, port_id,mode); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set counter status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_counter_set (dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get counter status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_counter_get (dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get counter statistics on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] counter frame number + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_counter_show (dev_id, port_id, port_counter_info); + FAL_API_UNLOCK; + return rv; +} +/*qca808x_end*/ +#endif + +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_max_frame_size_set(dev_id, port_id, max_frame); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_max_frame_size_get(dev_id, port_id, max_frame); + FAL_API_UNLOCK; + return rv; +} + +#ifndef IN_PORTCONTROL_MINI +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_mru_set(dev_id, port_id, ctrl); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_mru_get(dev_id, port_id, ctrl); + FAL_API_UNLOCK; + return rv; +} +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_mtu_set(dev_id, port_id, ctrl); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_mtu_get(dev_id, port_id, ctrl); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_source_filter_get(dev_id, + port_id, enable); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_source_filter_set(dev_id, + port_id, enable); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_source_filter_config_set(dev_id, port_id, src_filter_config); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_source_filter_config_get(dev_id, port_id, src_filter_config); + FAL_API_UNLOCK; + 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; + + FAL_API_LOCK; + rv = _fal_port_interface_3az_status_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + 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; + + FAL_API_LOCK; + rv = _fal_port_interface_3az_status_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_promisc_mode_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} +#endif + +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_promisc_mode_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_interface_eee_cfg_set(dev_id, port_id, port_eee_cfg); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_interface_eee_cfg_get(dev_id, port_id, port_eee_cfg); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_switch_port_loopback_set(dev_id, port_id, loopback_cfg); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_switch_port_loopback_get(dev_id, port_id, loopback_cfg); + FAL_API_UNLOCK; + return rv; +} + +/*insert flag for outter fal, don't remove it*/ +/** + * @} + */ + #ifndef IN_PORTCONTROL_MINI +EXPORT_SYMBOL(fal_port_mtu_set); +EXPORT_SYMBOL(fal_port_mtu_get); +EXPORT_SYMBOL(fal_port_mru_set); +EXPORT_SYMBOL(fal_port_mru_get); +#endif +EXPORT_SYMBOL(fal_port_duplex_set); +EXPORT_SYMBOL(fal_port_duplex_get); +EXPORT_SYMBOL(fal_port_speed_set); +EXPORT_SYMBOL(fal_port_speed_get); +EXPORT_SYMBOL(fal_port_autoneg_status_get); +EXPORT_SYMBOL(fal_port_autoneg_enable); +EXPORT_SYMBOL(fal_port_autoneg_restart); +EXPORT_SYMBOL(fal_port_autoneg_adv_set); +EXPORT_SYMBOL(fal_port_autoneg_adv_get); +EXPORT_SYMBOL(fal_port_flowctrl_set); +#ifndef IN_PORTCONTROL_MINI +EXPORT_SYMBOL(fal_port_flowctrl_get); +EXPORT_SYMBOL(fal_port_powersave_set); +EXPORT_SYMBOL(fal_port_powersave_get); +EXPORT_SYMBOL(fal_port_hibernate_set); +EXPORT_SYMBOL(fal_port_hibernate_get); +EXPORT_SYMBOL(fal_port_cdt); +EXPORT_SYMBOL(fal_port_txmac_status_get); +#endif +EXPORT_SYMBOL(fal_port_txmac_status_set); +EXPORT_SYMBOL(fal_port_rxmac_status_set); +#ifndef IN_PORTCONTROL_MINI +EXPORT_SYMBOL(fal_port_rxmac_status_get); +#endif +EXPORT_SYMBOL(fal_port_txfc_status_set); +EXPORT_SYMBOL(fal_port_txfc_status_get); +EXPORT_SYMBOL(fal_port_rxfc_status_set); +EXPORT_SYMBOL(fal_port_rxfc_status_get); +#ifndef IN_PORTCONTROL_MINI +EXPORT_SYMBOL(fal_port_bp_status_set); +EXPORT_SYMBOL(fal_port_bp_status_get); +#endif +EXPORT_SYMBOL(fal_port_link_status_get); +#ifndef IN_PORTCONTROL_MINI +EXPORT_SYMBOL(fal_ports_link_status_get); +EXPORT_SYMBOL(fal_port_mac_loopback_set); +EXPORT_SYMBOL(fal_port_mac_loopback_get); +EXPORT_SYMBOL(fal_port_8023az_set); +EXPORT_SYMBOL(fal_port_8023az_get); +EXPORT_SYMBOL(fal_port_mdix_set); +EXPORT_SYMBOL(fal_port_mdix_get); +EXPORT_SYMBOL(fal_port_mdix_status_get); +EXPORT_SYMBOL(fal_port_combo_prefer_medium_set); +EXPORT_SYMBOL(fal_port_combo_prefer_medium_get); +EXPORT_SYMBOL(fal_port_combo_medium_status_get); +EXPORT_SYMBOL(fal_port_combo_fiber_mode_set); +EXPORT_SYMBOL(fal_port_combo_fiber_mode_get); +EXPORT_SYMBOL(fal_port_local_loopback_set); +EXPORT_SYMBOL(fal_port_local_loopback_get); +EXPORT_SYMBOL(fal_port_remote_loopback_set); +EXPORT_SYMBOL(fal_port_remote_loopback_get); +EXPORT_SYMBOL(fal_port_reset); +#endif +EXPORT_SYMBOL(fal_port_power_off); +EXPORT_SYMBOL(fal_port_power_on); +#ifndef IN_PORTCONTROL_MINI +EXPORT_SYMBOL(fal_port_magic_frame_mac_set ); +EXPORT_SYMBOL(fal_port_magic_frame_mac_get ); +EXPORT_SYMBOL(fal_port_phy_id_get ); +EXPORT_SYMBOL(fal_port_wol_status_set ); +EXPORT_SYMBOL(fal_port_wol_status_get ); +EXPORT_SYMBOL(fal_port_interface_mode_set); +EXPORT_SYMBOL(fal_port_interface_mode_apply); + +EXPORT_SYMBOL(fal_port_interface_mode_get ); +EXPORT_SYMBOL(fal_port_interface_mode_status_get ); +EXPORT_SYMBOL(fal_port_source_filter_enable); +EXPORT_SYMBOL(fal_port_source_filter_status_get); +EXPORT_SYMBOL(fal_port_source_filter_config_get); +EXPORT_SYMBOL(fal_port_source_filter_config_set); +#endif +EXPORT_SYMBOL(fal_port_max_frame_size_set); +EXPORT_SYMBOL(fal_port_max_frame_size_get); +#ifndef IN_PORTCONTROL_MINI +EXPORT_SYMBOL(fal_port_interface_3az_status_set); +EXPORT_SYMBOL(fal_port_interface_3az_status_get); +#endif +EXPORT_SYMBOL(fal_port_flowctrl_forcemode_set); +#ifndef IN_PORTCONTROL_MINI +EXPORT_SYMBOL(fal_port_flowctrl_forcemode_get); +EXPORT_SYMBOL(fal_port_promisc_mode_set); +EXPORT_SYMBOL(fal_port_promisc_mode_get); +#endif +EXPORT_SYMBOL(fal_port_interface_eee_cfg_set); +EXPORT_SYMBOL(fal_port_interface_eee_cfg_get); +EXPORT_SYMBOL(fal_switch_port_loopback_set); +EXPORT_SYMBOL(fal_switch_port_loopback_get); + diff --git a/feeds/ipq807x/qca-ssdk/src/src/fal/fal_portvlan.c b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_portvlan.c new file mode 100755 index 000000000..c12493bb2 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_portvlan.c @@ -0,0 +1,2538 @@ +/* + * Copyright (c) 2012, 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_port_vlan FAL_PORT_VLAN + * @{ + */ +#include "sw.h" +#include "fal_portvlan.h" +#include "hsl_api.h" +#include "adpt.h" + +#include +#include + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_1qmode_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_1qmode_set(dev_id, port_id, port_1qmode); + return rv; +} + + + + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_egvlanmode_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_egvlanmode_set(dev_id, port_id, port_egvlanmode); + return rv; +} + + + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_portvlan_member_add) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_portvlan_member_add(dev_id, port_id, mem_port_id); + return rv; + } + + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->portvlan_member_add) + return SW_NOT_SUPPORTED; + + rv = p_api->portvlan_member_add(dev_id, port_id, mem_port_id); + return rv; +} + + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_portvlan_member_del) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_portvlan_member_del(dev_id, port_id, mem_port_id); + return rv; + } + + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->portvlan_member_del) + return SW_NOT_SUPPORTED; + + rv = p_api->portvlan_member_del(dev_id, port_id, mem_port_id); + return rv; +} + + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_portvlan_member_update) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_portvlan_member_update(dev_id, port_id, mem_port_map); + return rv; + } + + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->portvlan_member_update) + return SW_NOT_SUPPORTED; + + rv = p_api->portvlan_member_update(dev_id, port_id, mem_port_map); + return rv; +} + + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_default_vid_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_default_vid_set(dev_id, port_id, vid); + return rv; +} + + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_force_default_vid_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_force_default_vid_set(dev_id, port_id, enable); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_force_portvlan_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_force_portvlan_set(dev_id, port_id, enable); + return rv; +} + + + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_nestvlan_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_nestvlan_set(dev_id, port_id, enable); + return rv; +} + + + + + +static sw_error_t +_fal_nestvlan_tpid_set(a_uint32_t dev_id, a_uint32_t tpid) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->nestvlan_tpid_set) + return SW_NOT_SUPPORTED; + + rv = p_api->nestvlan_tpid_set(dev_id, tpid); + return rv; +} + + + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_port_invlan_mode_set) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_port_invlan_mode_set(dev_id, port_id, mode); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_invlan_mode_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_invlan_mode_set(dev_id, port_id, mode); + return rv; +} +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_tls_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_tls_set(dev_id, port_id, enable); + return rv; +} + +#ifndef IN_PORTVLAN_MINI +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_port_invlan_mode_get) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_port_invlan_mode_get(dev_id, port_id, mode); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_invlan_mode_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_invlan_mode_get(dev_id, port_id, mode); + return rv; +} +static sw_error_t +_fal_nestvlan_tpid_get(a_uint32_t dev_id, a_uint32_t * tpid) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->nestvlan_tpid_get) + return SW_NOT_SUPPORTED; + + rv = p_api->nestvlan_tpid_get(dev_id, tpid); + return rv; +} +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_nestvlan_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_nestvlan_get(dev_id, port_id, enable); + return rv; +} +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_force_portvlan_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_force_portvlan_get(dev_id, port_id, enable); + return rv; +} +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_force_default_vid_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_force_default_vid_get(dev_id, port_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_default_vid_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_default_vid_get(dev_id, port_id, vid); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_1qmode_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_1qmode_get(dev_id, port_id, pport_1qmode); + return rv; +} +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_egvlanmode_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_egvlanmode_get(dev_id, port_id, pport_egvlanmode); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_portvlan_member_get) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_portvlan_member_get(dev_id, port_id, mem_port_map); + return rv; + } + + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->portvlan_member_get) + return SW_NOT_SUPPORTED; + + rv = p_api->portvlan_member_get(dev_id, port_id, mem_port_map); + return rv; +} + + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_tls_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_tls_get(dev_id, port_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_pri_propagation_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_pri_propagation_set(dev_id, port_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_pri_propagation_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_pri_propagation_get(dev_id, port_id, enable); + return rv; +} +#endif +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_default_svid_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_default_svid_set(dev_id, port_id, vid); + return rv; +} + + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_default_cvid_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_default_cvid_set(dev_id, port_id, vid); + return rv; +} + + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_vlan_propagation_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_vlan_propagation_set(dev_id, port_id, mode); + return rv; +} +#ifndef IN_PORTVLAN_MINI +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_default_cvid_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_default_cvid_get(dev_id, port_id, vid); + return rv; +} +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_default_svid_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_default_svid_get(dev_id, port_id, vid); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_vlan_propagation_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_vlan_propagation_get(dev_id, port_id, mode); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_port_vlan_trans_add) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_port_vlan_trans_add(dev_id, port_id, entry); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_vlan_trans_add) + return SW_NOT_SUPPORTED; + + rv = p_api->port_vlan_trans_add(dev_id, port_id, entry); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_port_vlan_trans_del) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_port_vlan_trans_del(dev_id, port_id, entry); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_vlan_trans_del) + return SW_NOT_SUPPORTED; + + rv = p_api->port_vlan_trans_del(dev_id, port_id, entry); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_port_vlan_trans_get) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_port_vlan_trans_get(dev_id, port_id, entry); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_vlan_trans_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_vlan_trans_get(dev_id, port_id, entry); + return rv; +} + +static sw_error_t +_fal_qinq_mode_set(a_uint32_t dev_id, fal_qinq_mode_t mode) +{ + sw_error_t rv; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_qinq_mode_set) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_qinq_mode_set(dev_id, mode); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->qinq_mode_set) + return SW_NOT_SUPPORTED; + + rv = p_api->qinq_mode_set(dev_id, mode); + return rv; +} + +static sw_error_t +_fal_qinq_mode_get(a_uint32_t dev_id, fal_qinq_mode_t * mode) +{ + sw_error_t rv; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_qinq_mode_get) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_qinq_mode_get(dev_id, mode); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->qinq_mode_get) + return SW_NOT_SUPPORTED; + + rv = p_api->qinq_mode_get(dev_id, mode); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_port_qinq_role_set) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_port_qinq_role_set(dev_id, port_id, role); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_qinq_role_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_qinq_role_set(dev_id, port_id, role); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_port_qinq_role_get) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_port_qinq_role_get(dev_id, port_id, role); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_qinq_role_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_qinq_role_get(dev_id, port_id, role); + return rv; +} + +static 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; + adpt_api_t *p_adpt_api; + hsl_api_t *p_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_port_vlan_trans_iterate) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_port_vlan_trans_iterate(dev_id, port_id, iterator, entry); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_vlan_trans_iterate) + return SW_NOT_SUPPORTED; + + rv = p_api->port_vlan_trans_iterate(dev_id, port_id, iterator, entry); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_mac_vlan_xlt_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_mac_vlan_xlt_set(dev_id, port_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_mac_vlan_xlt_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_mac_vlan_xlt_get(dev_id, port_id, enable); + return rv; +} + +static sw_error_t +_fal_netisolate_set(a_uint32_t dev_id, a_uint32_t enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->netisolate_set) + return SW_NOT_SUPPORTED; + + rv = p_api->netisolate_set(dev_id, enable); + return rv; +} + +static sw_error_t +_fal_netisolate_get(a_uint32_t dev_id, a_uint32_t * enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->netisolate_get) + return SW_NOT_SUPPORTED; + + rv = p_api->netisolate_get(dev_id, enable); + return rv; +} + +static sw_error_t +_fal_eg_trans_filter_bypass_en_set(a_uint32_t dev_id, a_uint32_t enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->eg_trans_filter_bypass_en_set) + return SW_NOT_SUPPORTED; + + rv = p_api->eg_trans_filter_bypass_en_set(dev_id, enable); + return rv; +} + +static sw_error_t +_fal_eg_trans_filter_bypass_en_get(a_uint32_t dev_id, a_uint32_t* enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->eg_trans_filter_bypass_en_set) + return SW_NOT_SUPPORTED; + + rv = p_api->eg_trans_filter_bypass_en_get(dev_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_vrf_id_set) + return SW_NOT_SUPPORTED; + + rv = p_api->port_vrf_id_set(dev_id, port_id, vrf_id); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->port_vrf_id_get) + return SW_NOT_SUPPORTED; + + rv = p_api->port_vrf_id_get(dev_id, port_id, vrf_id); + return rv; +} +#endif +/** + * @brief Set 802.1q work mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] port_1qmode 802.1q work mode + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_1qmode_set(dev_id, port_id, port_1qmode); + FAL_API_UNLOCK; + return rv; +} +#ifndef IN_PORTVLAN_MINI +/** + * @brief Get 802.1q work mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] port_1qmode 802.1q work mode + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_1qmode_get(dev_id, port_id, pport_1qmode); + FAL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Set packets transmitted out vlan tagged mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] port_egvlanmode packets transmitted out vlan tagged mode + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_egvlanmode_set(dev_id, port_id, port_egvlanmode); + FAL_API_UNLOCK; + return rv; +} +#ifndef IN_PORTVLAN_MINI +/** + * @brief Get packets transmitted out vlan tagged mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] port_egvlanmode packets transmitted out vlan tagged mode + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_egvlanmode_get(dev_id, port_id, pport_egvlanmode); + FAL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Add member of port based vlan on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mem_port_id port member + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_portvlan_member_add(dev_id, port_id, mem_port_id); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete member of port based vlan on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mem_port_id port member + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_portvlan_member_del(dev_id, port_id, mem_port_id); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Update member of port based vlan on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mem_port_map port members + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_portvlan_member_update(dev_id, port_id, mem_port_map); + FAL_API_UNLOCK; + return rv; +} +#ifndef IN_PORTVLAN_MINI +/** + * @brief Get member of port based vlan on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mem_port_map port members + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_portvlan_member_get(dev_id, port_id, mem_port_map); + FAL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Set default vlan id on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] vid default vlan id + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_default_vid_set(dev_id, port_id, vid); + FAL_API_UNLOCK; + return rv; +} +#ifndef IN_PORTVLAN_MINI +/** + * @brief Get default vlan id on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] vid default vlan id + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_default_vid_get(dev_id, port_id, vid); + FAL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Set force default vlan id status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_force_default_vid_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} +#ifndef IN_PORTVLAN_MINI +/** + * @brief Get force default vlan id status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_force_default_vid_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Set force port based vlan status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_force_portvlan_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} +#ifndef IN_PORTVLAN_MINI +/** + * @brief Get force port based vlan status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_force_portvlan_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Set nest vlan feature status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_nestvlan_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} +#ifndef IN_PORTVLAN_MINI +/** + * @brief Get nest vlan feature status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_nestvlan_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Set nest vlan tpid on a particular device. + * @param[in] dev_id device id + * @param[in] tpid tag protocol identification + * @return SW_OK or error code + */ +sw_error_t +fal_nestvlan_tpid_set(a_uint32_t dev_id, a_uint32_t tpid) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_nestvlan_tpid_set(dev_id, tpid); + FAL_API_UNLOCK; + return rv; +} +#ifndef IN_PORTVLAN_MINI +/** + * @brief Get nest vlan tpid on a particular device. + * @param[in] dev_id device id + * @param[out] tpid tag protocol identification + * @return SW_OK or error code + */ +sw_error_t +fal_nestvlan_tpid_get(a_uint32_t dev_id, a_uint32_t * tpid) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_nestvlan_tpid_get(dev_id, tpid); + FAL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Set ingress vlan mode mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode ingress vlan mode + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_invlan_mode_set(dev_id, port_id, mode); + FAL_API_UNLOCK; + return rv; +} +#ifndef IN_PORTVLAN_MINI +/** + * @brief Get ingress vlan mode mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mode ingress vlan mode + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_invlan_mode_get(dev_id, port_id, mode); + FAL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Set tls status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_tls_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} +#ifndef IN_PORTVLAN_MINI + + +/** + * @brief Get tls status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_tls_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set priority propagation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_pri_propagation_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get priority propagation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_pri_propagation_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Set default s-vid on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] vid s-vid + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_default_svid_set(dev_id, port_id, vid); + FAL_API_UNLOCK; + return rv; +} +#ifndef IN_PORTVLAN_MINI +/** + * @brief Get default s-vid on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] vid s-vid + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_default_svid_get(dev_id, port_id, vid); + FAL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Set default c-vid on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] vid c-vid + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_default_cvid_set(dev_id, port_id, vid); + FAL_API_UNLOCK; + return rv; +} +#ifndef IN_PORTVLAN_MINI +/** + * @brief Get default c-vid on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] vid c-vid + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_default_cvid_get(dev_id, port_id, vid); + FAL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Set vlan propagation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode vlan propagation mode + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_vlan_propagation_set(dev_id, port_id, mode); + FAL_API_UNLOCK; + return rv; +} +#ifndef IN_PORTVLAN_MINI + + +/** + * @brief Get vlan propagation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mode vlan propagation mode + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_vlan_propagation_get(dev_id, port_id, mode); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Add a vlan translation entry to a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param entry vlan translation entry + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_vlan_trans_add(dev_id, port_id, entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a vlan translation entry from a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param entry vlan translation entry + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_vlan_trans_del(dev_id, port_id, entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get a vlan translation entry from a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param entry vlan translation entry + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_vlan_trans_get(dev_id, port_id, entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set switch qinq work mode on a particular device. + * @param[in] dev_id device id + * @param[in] mode qinq work mode + * @return SW_OK or error code + */ +sw_error_t +fal_qinq_mode_set(a_uint32_t dev_id, fal_qinq_mode_t mode) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_qinq_mode_set(dev_id, mode); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get switch qinq work mode on a particular device. + * @param[in] dev_id device id + * @param[out] mode qinq work mode + * @return SW_OK or error code + */ +sw_error_t +fal_qinq_mode_get(a_uint32_t dev_id, fal_qinq_mode_t * mode) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_qinq_mode_get(dev_id, mode); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set qinq role on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] role port role + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_qinq_role_set(dev_id, port_id, role); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get qinq role on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] role port role + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_qinq_role_get(dev_id, port_id, role); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Iterate all vlan translation entries from a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] iterator translation entry index if it's zero means get the first entry + * @param[out] iterator next valid translation entry index + * @param[out] entry vlan translation entry + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_vlan_trans_iterate(dev_id, port_id, iterator, entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set MAC_VLAN_XLT status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] role port role + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_mac_vlan_xlt_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get MAC_VLAN_XLT status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] role port role + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_mac_vlan_xlt_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set net isolate function. + * @param[in] dev_id device id + * @param[in] enable tag protocol identification + * @return SW_OK or error code + */ +sw_error_t +fal_netisolate_set(a_uint32_t dev_id, a_uint32_t enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_netisolate_set(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get net isolate status. + * @param[in] dev_id device id + * @param[out] enable tag protocol identification + * @return SW_OK or error code + */ +sw_error_t +fal_netisolate_get(a_uint32_t dev_id, a_uint32_t * enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_netisolate_get(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + + +/** + * @brief Set egress translation filter bypass enable + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_eg_trans_filter_bypass_en_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_eg_trans_filter_bypass_en_set(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get egress translation filter bypass enable + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_eg_trans_filter_bypass_en_get(a_uint32_t dev_id, a_bool_t* enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_eg_trans_filter_bypass_en_get(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set VRF id on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] vrf_id VRF id + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_vrf_id_set(dev_id, port_id, vrf_id); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get VRF id on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] vrf_id VRF id + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_port_vrf_id_get(dev_id, port_id, vrf_id); + FAL_API_UNLOCK; + return rv; +} +#endif + +/** + * @} + */ +sw_error_t +_fal_global_qinq_mode_set(a_uint32_t dev_id, fal_global_qinq_mode_t *mode) +{ + sw_error_t rv; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_global_qinq_mode_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_global_qinq_mode_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_qinq_mode_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_qinq_mode_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_tpid_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_tpid_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_egress_tpid_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_egress_tpid_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_ingress_vlan_filter_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_ingress_vlan_filter_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_default_vlantag_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_default_vlantag_set(dev_id, port_id, 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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_default_vlantag_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_default_vlantag_get(dev_id, port_id, 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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_tag_propagation_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_tag_propagation_set(dev_id, port_id, 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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_tag_propagation_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_tag_propagation_get(dev_id, port_id, direction, prop); + 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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_vlantag_egmode_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_vlantag_egmode_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_vlantag_egmode_get(dev_id, port_id, port_egvlanmode); + 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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_vlan_xlt_miss_cmd_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_vlan_xlt_miss_cmd_set(dev_id, port_id, 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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_vlan_xlt_miss_cmd_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_vlan_xlt_miss_cmd_get(dev_id, port_id, cmd); + 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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_vsi_egmode_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_vsi_egmode_set(dev_id, vsi, port_id, 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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_vsi_egmode_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_vlantag_vsi_egmode_enable_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_vlantag_vsi_egmode_enable_set(dev_id, port_id, 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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_vlantag_vsi_egmode_enable_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_vlantag_vsi_egmode_enable_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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_vlan_trans_adv_add) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_vlan_trans_adv_add(dev_id, port_id, 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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_vlan_trans_adv_del) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_vlan_trans_adv_del(dev_id, port_id, 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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_vlan_trans_adv_getfirst) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_vlan_trans_adv_getfirst(dev_id, port_id, 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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_vlan_trans_adv_getnext) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_vlan_trans_adv_getnext(dev_id, port_id, 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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_vlan_counter_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_vlan_counter_cleanup) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_vlan_counter_cleanup(dev_id, cnt_index); + 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 = SW_OK; + + FAL_PORTVLAN_API_LOCK; + rv = _fal_global_qinq_mode_set(dev_id, mode); + FAL_PORTVLAN_API_UNLOCK; + 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 = SW_OK; + + FAL_PORTVLAN_API_LOCK; + rv = _fal_global_qinq_mode_get(dev_id, mode); + FAL_PORTVLAN_API_UNLOCK; + 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 = SW_OK; + + FAL_PORTVLAN_API_LOCK; + rv = _fal_port_qinq_mode_set(dev_id, port_id, mode); + FAL_PORTVLAN_API_UNLOCK; + 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 = SW_OK; + + FAL_PORTVLAN_API_LOCK; + rv = _fal_port_qinq_mode_get(dev_id, port_id, mode); + FAL_PORTVLAN_API_UNLOCK; + return rv; +} + +sw_error_t +fal_ingress_tpid_set(a_uint32_t dev_id, fal_tpid_t *tpid) +{ + sw_error_t rv = SW_OK; + + FAL_PORTVLAN_API_LOCK; + rv = _fal_ingress_tpid_set(dev_id, tpid); + FAL_PORTVLAN_API_UNLOCK; + return rv; +} + +sw_error_t +fal_ingress_tpid_get(a_uint32_t dev_id, fal_tpid_t * tpid) +{ + sw_error_t rv = SW_OK; + + FAL_PORTVLAN_API_LOCK; + rv = _fal_ingress_tpid_get(dev_id, tpid); + FAL_PORTVLAN_API_UNLOCK; + return rv; +} + +sw_error_t +fal_egress_tpid_set(a_uint32_t dev_id, fal_tpid_t *tpid) +{ + sw_error_t rv = SW_OK; + + FAL_PORTVLAN_API_LOCK; + rv = _fal_egress_tpid_set(dev_id, tpid); + FAL_PORTVLAN_API_UNLOCK; + return rv; +} + +sw_error_t +fal_egress_tpid_get(a_uint32_t dev_id, fal_tpid_t * tpid) +{ + sw_error_t rv = SW_OK; + + FAL_PORTVLAN_API_LOCK; + rv = _fal_egress_tpid_get(dev_id, tpid); + FAL_PORTVLAN_API_UNLOCK; + 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 = SW_OK; + + FAL_PORTVLAN_API_LOCK; + rv = _fal_port_ingress_vlan_filter_set(dev_id, port_id, filter); + FAL_PORTVLAN_API_UNLOCK; + 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 = SW_OK; + + FAL_PORTVLAN_API_LOCK; + rv = _fal_port_ingress_vlan_filter_get(dev_id, port_id, filter); + FAL_PORTVLAN_API_UNLOCK; + 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 = SW_OK; + + FAL_PORTVLAN_API_LOCK; + rv = _fal_port_default_vlantag_set(dev_id, port_id, direction, default_vid_en, default_tag); + FAL_PORTVLAN_API_UNLOCK; + 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 = SW_OK; + + FAL_PORTVLAN_API_LOCK; + rv = _fal_port_default_vlantag_get(dev_id, port_id, direction, default_vid_en, default_tag); + FAL_PORTVLAN_API_UNLOCK; + 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 = SW_OK; + + FAL_PORTVLAN_API_LOCK; + rv = _fal_port_tag_propagation_set(dev_id, port_id, direction, prop); + FAL_PORTVLAN_API_UNLOCK; + 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 = SW_OK; + + FAL_PORTVLAN_API_LOCK; + rv = _fal_port_tag_propagation_get(dev_id, port_id, direction, prop); + FAL_PORTVLAN_API_UNLOCK; + 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 = SW_OK; + + FAL_PORTVLAN_API_LOCK; + rv = _fal_port_vlantag_egmode_set(dev_id, port_id, port_egvlanmode); + FAL_PORTVLAN_API_UNLOCK; + 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 = SW_OK; + + FAL_PORTVLAN_API_LOCK; + rv = _fal_port_vlantag_egmode_get(dev_id, port_id, port_egvlanmode); + FAL_PORTVLAN_API_UNLOCK; + 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 = SW_OK; + + FAL_PORTVLAN_API_LOCK; + rv = _fal_port_vlan_xlt_miss_cmd_set(dev_id, port_id, cmd); + FAL_PORTVLAN_API_UNLOCK; + 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 = SW_OK; + + FAL_PORTVLAN_API_LOCK; + rv = _fal_port_vlan_xlt_miss_cmd_get(dev_id, port_id, cmd); + FAL_PORTVLAN_API_UNLOCK; + 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 = SW_OK; + + FAL_PORTVLAN_API_LOCK; + rv = _fal_port_vsi_egmode_set(dev_id, vsi, port_id, egmode); + FAL_PORTVLAN_API_UNLOCK; + 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 = SW_OK; + + FAL_PORTVLAN_API_LOCK; + rv = _fal_port_vsi_egmode_get(dev_id, vsi, port_id, egmode); + FAL_PORTVLAN_API_UNLOCK; + 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 = SW_OK; + + FAL_PORTVLAN_API_LOCK; + rv = _fal_port_vlantag_vsi_egmode_enable(dev_id, port_id, enable); + FAL_PORTVLAN_API_UNLOCK; + 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 = SW_OK; + + FAL_PORTVLAN_API_LOCK; + rv = _fal_port_vlantag_vsi_egmode_status_get(dev_id, port_id, enable); + FAL_PORTVLAN_API_UNLOCK; + 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 = SW_OK; + + FAL_PORTVLAN_API_LOCK; + rv = _fal_port_vlan_trans_adv_add(dev_id, port_id, direction, rule, action); + FAL_PORTVLAN_API_UNLOCK; + 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 = SW_OK; + + FAL_PORTVLAN_API_LOCK; + rv = _fal_port_vlan_trans_adv_del(dev_id, port_id, direction, rule, action); + FAL_PORTVLAN_API_UNLOCK; + 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 = SW_OK; + + FAL_PORTVLAN_API_LOCK; + rv = _fal_port_vlan_trans_adv_getfirst(dev_id, port_id, direction, rule, action); + FAL_PORTVLAN_API_UNLOCK; + 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 = SW_OK; + + FAL_PORTVLAN_API_LOCK; + rv = _fal_port_vlan_trans_adv_getnext(dev_id, port_id, direction, rule, action); + FAL_PORTVLAN_API_UNLOCK; + 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 = SW_OK; + + FAL_PORTVLAN_API_LOCK; + rv = _fal_port_vlan_counter_get(dev_id, cnt_index, counter); + FAL_PORTVLAN_API_UNLOCK; + return rv; +} +sw_error_t +fal_port_vlan_counter_cleanup(a_uint32_t dev_id, a_uint32_t cnt_index) +{ + sw_error_t rv = SW_OK; + + FAL_PORTVLAN_API_LOCK; + rv = _fal_port_vlan_counter_cleanup(dev_id, cnt_index); + FAL_PORTVLAN_API_UNLOCK; + return rv; +} + +EXPORT_SYMBOL(fal_port_invlan_mode_set); +EXPORT_SYMBOL(fal_global_qinq_mode_set); +EXPORT_SYMBOL(fal_global_qinq_mode_get); +EXPORT_SYMBOL(fal_port_qinq_mode_set); +EXPORT_SYMBOL(fal_port_qinq_mode_get); +EXPORT_SYMBOL(fal_ingress_tpid_set); +EXPORT_SYMBOL(fal_ingress_tpid_get); +EXPORT_SYMBOL(fal_egress_tpid_set); +EXPORT_SYMBOL(fal_egress_tpid_get); +EXPORT_SYMBOL(fal_port_ingress_vlan_filter_set); +EXPORT_SYMBOL(fal_port_ingress_vlan_filter_get); +EXPORT_SYMBOL(fal_port_default_vlantag_set); +EXPORT_SYMBOL(fal_port_default_vlantag_get); +EXPORT_SYMBOL(fal_port_tag_propagation_set); +EXPORT_SYMBOL(fal_port_tag_propagation_get); +EXPORT_SYMBOL(fal_port_vlantag_egmode_set); +EXPORT_SYMBOL(fal_port_vlantag_egmode_get); +EXPORT_SYMBOL(fal_port_vlan_xlt_miss_cmd_set); +EXPORT_SYMBOL(fal_port_vlan_xlt_miss_cmd_get); +EXPORT_SYMBOL(fal_port_vsi_egmode_set); +EXPORT_SYMBOL(fal_port_vsi_egmode_get); +EXPORT_SYMBOL(fal_port_vlantag_vsi_egmode_enable); +EXPORT_SYMBOL(fal_port_vlantag_vsi_egmode_status_get); +EXPORT_SYMBOL(fal_port_vlan_trans_adv_add); +EXPORT_SYMBOL(fal_port_vlan_trans_adv_del); +EXPORT_SYMBOL(fal_port_vlan_trans_adv_getfirst); +EXPORT_SYMBOL(fal_port_vlan_trans_adv_getnext); +EXPORT_SYMBOL(fal_port_vlan_counter_get); +EXPORT_SYMBOL(fal_port_vlan_counter_cleanup); +EXPORT_SYMBOL(fal_portvlan_member_add); +EXPORT_SYMBOL(fal_portvlan_member_del); +EXPORT_SYMBOL(fal_portvlan_member_update); +#ifndef IN_PORTVLAN_MINI +EXPORT_SYMBOL(fal_qinq_mode_set); +EXPORT_SYMBOL(fal_qinq_mode_get); +EXPORT_SYMBOL(fal_port_qinq_role_set); +EXPORT_SYMBOL(fal_port_qinq_role_get); +EXPORT_SYMBOL(fal_port_vlan_trans_iterate); +EXPORT_SYMBOL(fal_port_vlan_trans_add); +EXPORT_SYMBOL(fal_port_vlan_trans_del); +EXPORT_SYMBOL(fal_port_vlan_trans_get); +EXPORT_SYMBOL(fal_portvlan_member_get); +EXPORT_SYMBOL(fal_port_invlan_mode_get); +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/src/fal/fal_pppoe.c b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_pppoe.c new file mode 100755 index 000000000..1552b8cbf --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_pppoe.c @@ -0,0 +1,609 @@ +/* + * Copyright (c) 2012, 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_pppoe FAL_PPPOE + * @{ + */ +#include "sw.h" +#include "fal_pppoe.h" +#include "hsl_api.h" +#include "adpt.h" + +#include +#include + + +static sw_error_t +_fal_pppoe_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->pppoe_cmd_set) + return SW_NOT_SUPPORTED; + + rv = p_api->pppoe_cmd_set(dev_id, cmd); + return rv; +} + + +static sw_error_t +_fal_pppoe_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->pppoe_cmd_get) + return SW_NOT_SUPPORTED; + + rv = p_api->pppoe_cmd_get(dev_id, cmd); + return rv; +} + + +static sw_error_t +_fal_pppoe_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->pppoe_status_set) + return SW_NOT_SUPPORTED; + + rv = p_api->pppoe_status_set(dev_id, enable); + return rv; +} + + +static sw_error_t +_fal_pppoe_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->pppoe_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->pppoe_status_get(dev_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->pppoe_session_add) + return SW_NOT_SUPPORTED; + + rv = p_api->pppoe_session_add(dev_id, session_id, strip_hdr); + return rv; +} + +static sw_error_t +_fal_pppoe_session_del(a_uint32_t dev_id, a_uint32_t session_id) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->pppoe_session_del) + return SW_NOT_SUPPORTED; + + rv = p_api->pppoe_session_del(dev_id, session_id); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->pppoe_session_get) + return SW_NOT_SUPPORTED; + + rv = p_api->pppoe_session_get(dev_id, session_id, strip_hdr); + return rv; +} + +static sw_error_t +_fal_pppoe_session_table_add(a_uint32_t dev_id, + fal_pppoe_session_t * session_tbl) +{ + sw_error_t rv; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_pppoe_session_table_add) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_pppoe_session_table_add(dev_id, session_tbl); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->pppoe_session_table_add) + return SW_NOT_SUPPORTED; + + rv = p_api->pppoe_session_table_add(dev_id, session_tbl); + return rv; +} + + +static sw_error_t +_fal_pppoe_session_table_del(a_uint32_t dev_id, + fal_pppoe_session_t * session_tbl) +{ + sw_error_t rv; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_pppoe_session_table_del) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_pppoe_session_table_del(dev_id, session_tbl); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->pppoe_session_table_del) + return SW_NOT_SUPPORTED; + + rv = p_api->pppoe_session_table_del(dev_id, session_tbl); + return rv; +} + +static sw_error_t +_fal_pppoe_session_table_get(a_uint32_t dev_id, + fal_pppoe_session_t * session_tbl) +{ + sw_error_t rv; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_pppoe_session_table_get) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_pppoe_session_table_get(dev_id, session_tbl); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->pppoe_session_table_get) + return SW_NOT_SUPPORTED; + + rv = p_api->pppoe_session_table_get(dev_id, session_tbl); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->pppoe_session_id_set) + return SW_NOT_SUPPORTED; + + rv = p_api->pppoe_session_id_set(dev_id, index, id); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->pppoe_session_id_get) + return SW_NOT_SUPPORTED; + + rv = p_api->pppoe_session_id_get(dev_id, index, id); + return rv; +} + +static sw_error_t +_fal_rtd_pppoe_en_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->rtd_pppoe_en_set) + return SW_NOT_SUPPORTED; + + rv = p_api->rtd_pppoe_en_set(dev_id, enable); + return rv; +} + + +static sw_error_t +_fal_rtd_pppoe_en_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->rtd_pppoe_en_get) + return SW_NOT_SUPPORTED; + + rv = p_api->rtd_pppoe_en_get(dev_id, enable); + return rv; +} + +static sw_error_t +_fal_pppoe_l3intf_status_get(a_uint32_t dev_id, a_uint32_t l3_if, a_uint32_t *enable) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_pppoe_en_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_pppoe_en_get(dev_id, l3_if, enable); + return rv; +} + +static sw_error_t +_fal_pppoe_l3intf_enable(a_uint32_t dev_id, a_uint32_t l3_if, a_uint32_t enable) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_pppoe_en_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_pppoe_en_set(dev_id, l3_if, enable); + return rv; +} +/*insert flag for inner fal, don't remove it*/ + +/** + * @brief Set pppoe packets forwarding command on a particular device. + * @details comments: + * Particular device may only support parts of forwarding commands. + * Ihis operation will take effect only after enabling pppoe packets + * hardware acknowledgement + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +sw_error_t +fal_pppoe_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_pppoe_cmd_set(dev_id, cmd); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get pppoe packets forwarding command on a particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +sw_error_t +fal_pppoe_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_pppoe_cmd_get(dev_id, cmd); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set pppoe packets hardware acknowledgement status on particular device. + * @details comments: + * Particular device may only support parts of pppoe packets. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_pppoe_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_pppoe_status_set(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get pppoe packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_pppoe_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_pppoe_status_get(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Add a pppoe session entry to a particular device. + * @param[in] dev_id device id + * @param[in] session_id pppoe session id + * @param[in] strip_hdr strip or not strip pppoe header + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_pppoe_session_add(dev_id, session_id, strip_hdr); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a pppoe session entry from a particular device. + * @param[in] dev_id device id + * @param[in] session_id pppoe session id + * @return SW_OK or error code + */ +sw_error_t +fal_pppoe_session_del(a_uint32_t dev_id, a_uint32_t session_id) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_pppoe_session_del(dev_id, session_id); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get a pppoe session entry from a particular device. + * @param[in] dev_id device id + * @param[in] session_id pppoe session id + * @param[out] strip_hdr strip or not strip pppoe header + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_pppoe_session_get(dev_id, session_id, strip_hdr); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Add a pppoe session entry to a particular device. + * The entry only for pppoe/ppp header remove. + * @param[in] dev_id device id + * @param[in] session_tbl pppoe session table + * @return SW_OK or error code + */ +sw_error_t +fal_pppoe_session_table_add(a_uint32_t dev_id, + fal_pppoe_session_t * session_tbl) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_pppoe_session_table_add(dev_id, session_tbl); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a pppoe session entry from a particular device. + * The entry only for pppoe/ppp header remove. + * @param[in] dev_id device id + * @param[in] session_tbl pppoe session table + * @return SW_OK or error code + */ +sw_error_t +fal_pppoe_session_table_del(a_uint32_t dev_id, + fal_pppoe_session_t * session_tbl) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_pppoe_session_table_del(dev_id, session_tbl); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get a pppoe session entry from a particular device. + * The entry only for pppoe/ppp header remove. + * @param[in] dev_id device id + * @param[out] session_tbl pppoe session table + * @return SW_OK or error code + */ +sw_error_t +fal_pppoe_session_table_get(a_uint32_t dev_id, + fal_pppoe_session_t * session_tbl) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_pppoe_session_table_get(dev_id, session_tbl); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set a pppoe session id entry to a particular device. + * The entry only for pppoe/ppp header add. + * @param[in] dev_id device id + * @param[in] session_tbl pppoe session table + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_pppoe_session_id_set(dev_id, index, id); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get a pppoe session id entry to a particular device. + * The entry only for pppoe/ppp header add. + * @param[in] dev_id device id + * @param[out] session_tbl pppoe session table + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_pppoe_session_id_get(dev_id, index, id); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set RM_RTD_PPPOE_EN status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_rtd_pppoe_en_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_rtd_pppoe_en_set(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get RM_RTD_PPPOE_EN status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +fal_rtd_pppoe_en_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_rtd_pppoe_en_get(dev_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set a l3 interface pppoe status + * @param[in] dev_id device id + * @param[in] l3 interface name + * @param[in] pppoe status enable or disable + * @return SW_OK or error code + */ +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_pppoe_l3intf_status_get(dev_id, l3_if, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get a l3 interface pppoe status + * @param[in] dev_id device id + * @param[in] l3 interface name + * @param[out] pppoe status enable or disable + * @return SW_OK or error code + */ +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_pppoe_l3intf_enable(dev_id, l3_if, enable); + FAL_API_UNLOCK; + return rv; +} +/*insert flag for outter fal, don't remove it*/ + +EXPORT_SYMBOL(fal_pppoe_session_table_add); +EXPORT_SYMBOL(fal_pppoe_session_table_del); +EXPORT_SYMBOL(fal_pppoe_session_table_get); +EXPORT_SYMBOL(fal_pppoe_l3intf_status_get); +EXPORT_SYMBOL(fal_pppoe_l3intf_enable); + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/fal/fal_ptp.c b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_ptp.c new file mode 100755 index 000000000..c00df9a29 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_ptp.c @@ -0,0 +1,1208 @@ +/* + * 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. + */ + + +/** + * @defgroup fal_ptp FAL_PTP + * @{ + */ +#include "sw.h" +#include "fal_ptp.h" +#include "hsl_api.h" +#include "adpt.h" + +#include +#include + +sw_error_t +_fal_ptp_security_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_security_t *sec) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_security_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_security_set(dev_id, port_id, sec); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_link_delay_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_link_delay_set(dev_id, port_id, time); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_rx_crc_recalc_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_rx_crc_recalc_status_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_tod_uart_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_tod_uart_set(dev_id, port_id, tod_uart); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_enhanced_timestamp_engine_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_enhanced_timestamp_engine_get(dev_id, port_id, direction, ts_engine); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_pps_signal_control_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_pps_signal_control_set(dev_id, port_id, sig_control); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_timestamp_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_timestamp_get(dev_id, port_id, direction, pkt_info, time); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_asym_correction_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_asym_correction_get(dev_id, port_id, asym_cf); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_rtc_time_snapshot_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_rtc_time_snapshot_status_get(dev_id, port_id, status); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_capture_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_capture_set(dev_id, port_id, capture_id, capture); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_rtc_adjfreq_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_rtc_adjfreq_set(dev_id, port_id, time); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_asym_correction_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_asym_correction_set(dev_id, port_id, asym_cf); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_pkt_timestamp_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_pkt_timestamp_set(dev_id, port_id, time); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_rtc_time_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_rtc_time_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_rtc_time_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_pkt_timestamp_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_pkt_timestamp_get(dev_id, port_id, time); + return rv; +} +sw_error_t +_fal_ptp_interrupt_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_interrupt_t *interrupt) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_interrupt_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_interrupt_set(dev_id, port_id, interrupt); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_trigger_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_trigger_set(dev_id, port_id, trigger_id, triger); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_pps_signal_control_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_pps_signal_control_get(dev_id, port_id, sig_control); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_capture_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_capture_get(dev_id, port_id, capture_id, capture); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_rx_crc_recalc_enable) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_rx_crc_recalc_enable(dev_id, port_id, status); + return rv; +} +sw_error_t +_fal_ptp_security_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_security_t *sec) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_security_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_security_get(dev_id, port_id, sec); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_increment_sync_from_clock_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_increment_sync_from_clock_status_get(dev_id, port_id, status); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_tod_uart_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_enhanced_timestamp_engine_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_enhanced_timestamp_engine_set(dev_id, port_id, direction, ts_engine); + return rv; +} +sw_error_t +_fal_ptp_rtc_time_clear(a_uint32_t dev_id, a_uint32_t port_id) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_rtc_time_clear) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_rtc_time_clear(dev_id, port_id); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_reference_clock_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_reference_clock_set(dev_id, port_id, ref_clock); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_output_waveform_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_output_waveform_set(dev_id, port_id, waveform); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_rx_timestamp_mode_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_rx_timestamp_mode_set(dev_id, port_id, ts_mode); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_grandmaster_mode_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_grandmaster_mode_set(dev_id, port_id, gm_mode); + return rv; +} +sw_error_t +_fal_ptp_config_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_config_t *config) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_config_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_config_set(dev_id, port_id, config); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_trigger_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_trigger_get(dev_id, port_id, trigger_id, triger); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_rtc_adjfreq_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_rtc_adjfreq_get(dev_id, port_id, time); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_grandmaster_mode_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_grandmaster_mode_get(dev_id, port_id, gm_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_rx_timestamp_mode_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_rx_timestamp_mode_get(dev_id, port_id, ts_mode); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_rtc_adjtime_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_rtc_adjtime_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_link_delay_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_link_delay_get(dev_id, port_id, time); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_increment_sync_from_clock_enable) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_increment_sync_from_clock_enable(dev_id, port_id, status); + return rv; +} +sw_error_t +_fal_ptp_config_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_config_t *config) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_config_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_config_get(dev_id, port_id, config); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_output_waveform_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_output_waveform_get(dev_id, port_id, waveform); + return rv; +} +sw_error_t +_fal_ptp_interrupt_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_interrupt_t *interrupt) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_interrupt_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_interrupt_get(dev_id, port_id, interrupt); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_rtc_time_snapshot_enable) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_rtc_time_snapshot_enable(dev_id, port_id, status); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ptp_reference_clock_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ptp_reference_clock_get(dev_id, port_id, ref_clock); + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_security_set(dev_id, port_id, sec); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_link_delay_set(dev_id, port_id, time); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_rx_crc_recalc_status_get(dev_id, port_id, status); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_tod_uart_set(dev_id, port_id, tod_uart); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_enhanced_timestamp_engine_get(dev_id, port_id, direction, ts_engine); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_pps_signal_control_set(dev_id, port_id, sig_control); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_timestamp_get(dev_id, port_id, direction, pkt_info, time); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_asym_correction_get(dev_id, port_id, asym_cf); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_rtc_time_snapshot_status_get(dev_id, port_id, status); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_capture_set(dev_id, port_id, capture_id, capture); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_rtc_adjfreq_set(dev_id, port_id, time); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_asym_correction_set(dev_id, port_id, asym_cf); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_pkt_timestamp_set(dev_id, port_id, time); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_rtc_time_get(dev_id, port_id, time); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_rtc_time_set(dev_id, port_id, time); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_pkt_timestamp_get(dev_id, port_id, time); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_interrupt_set(dev_id, port_id, interrupt); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_trigger_set(dev_id, port_id, trigger_id, triger); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_pps_signal_control_get(dev_id, port_id, sig_control); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_capture_get(dev_id, port_id, capture_id, capture); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_rx_crc_recalc_enable(dev_id, port_id, status); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_security_get(dev_id, port_id, sec); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_increment_sync_from_clock_status_get(dev_id, port_id, status); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_tod_uart_get(dev_id, port_id, tod_uart); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_enhanced_timestamp_engine_set(dev_id, port_id, direction, ts_engine); + FAL_API_UNLOCK; + return rv; +} + sw_error_t +fal_ptp_rtc_time_clear(a_uint32_t dev_id, a_uint32_t port_id) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_rtc_time_clear(dev_id, port_id); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_reference_clock_set(dev_id, port_id, ref_clock); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_output_waveform_set(dev_id, port_id, waveform); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_rx_timestamp_mode_set(dev_id, port_id, ts_mode); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_grandmaster_mode_set(dev_id, port_id, gm_mode); + FAL_API_UNLOCK; + return rv; +} +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_config_set(dev_id, port_id, config); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_trigger_get(dev_id, port_id, trigger_id, triger); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_rtc_adjfreq_get(dev_id, port_id, time); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_grandmaster_mode_get(dev_id, port_id, gm_mode); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_rx_timestamp_mode_get(dev_id, port_id, ts_mode); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_rtc_adjtime_set(dev_id, port_id, time); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_link_delay_get(dev_id, port_id, time); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_increment_sync_from_clock_enable(dev_id, port_id, status); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_config_get(dev_id, port_id, config); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_output_waveform_get(dev_id, port_id, waveform); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_interrupt_get(dev_id, port_id, interrupt); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_rtc_time_snapshot_enable(dev_id, port_id, status); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ptp_reference_clock_get(dev_id, port_id, ref_clock); + FAL_API_UNLOCK; + return rv; +} + +EXPORT_SYMBOL(fal_ptp_config_set); +EXPORT_SYMBOL(fal_ptp_config_get); +EXPORT_SYMBOL(fal_ptp_reference_clock_set); +EXPORT_SYMBOL(fal_ptp_reference_clock_get); +EXPORT_SYMBOL(fal_ptp_rx_timestamp_mode_set); +EXPORT_SYMBOL(fal_ptp_rx_timestamp_mode_get); +EXPORT_SYMBOL(fal_ptp_timestamp_get); +EXPORT_SYMBOL(fal_ptp_pkt_timestamp_set); +EXPORT_SYMBOL(fal_ptp_pkt_timestamp_get); +EXPORT_SYMBOL(fal_ptp_grandmaster_mode_set); +EXPORT_SYMBOL(fal_ptp_grandmaster_mode_get); +EXPORT_SYMBOL(fal_ptp_rtc_time_get); +EXPORT_SYMBOL(fal_ptp_rtc_time_set); +EXPORT_SYMBOL(fal_ptp_rtc_time_clear); +EXPORT_SYMBOL(fal_ptp_rtc_adjtime_set); +EXPORT_SYMBOL(fal_ptp_rtc_adjfreq_set); +EXPORT_SYMBOL(fal_ptp_rtc_adjfreq_get); +EXPORT_SYMBOL(fal_ptp_link_delay_set); +EXPORT_SYMBOL(fal_ptp_link_delay_get); +EXPORT_SYMBOL(fal_ptp_security_set); +EXPORT_SYMBOL(fal_ptp_security_get); +EXPORT_SYMBOL(fal_ptp_pps_signal_control_set); +EXPORT_SYMBOL(fal_ptp_pps_signal_control_get); +EXPORT_SYMBOL(fal_ptp_rx_crc_recalc_enable); +EXPORT_SYMBOL(fal_ptp_rx_crc_recalc_status_get); +EXPORT_SYMBOL(fal_ptp_asym_correction_set); +EXPORT_SYMBOL(fal_ptp_asym_correction_get); +EXPORT_SYMBOL(fal_ptp_output_waveform_set); +EXPORT_SYMBOL(fal_ptp_output_waveform_get); +EXPORT_SYMBOL(fal_ptp_rtc_time_snapshot_enable); +EXPORT_SYMBOL(fal_ptp_rtc_time_snapshot_status_get); +EXPORT_SYMBOL(fal_ptp_increment_sync_from_clock_enable); +EXPORT_SYMBOL(fal_ptp_increment_sync_from_clock_status_get); +EXPORT_SYMBOL(fal_ptp_tod_uart_set); +EXPORT_SYMBOL(fal_ptp_tod_uart_get); +EXPORT_SYMBOL(fal_ptp_enhanced_timestamp_engine_set); +EXPORT_SYMBOL(fal_ptp_enhanced_timestamp_engine_get); +EXPORT_SYMBOL(fal_ptp_trigger_set); +EXPORT_SYMBOL(fal_ptp_trigger_get); +EXPORT_SYMBOL(fal_ptp_capture_set); +EXPORT_SYMBOL(fal_ptp_capture_get); +EXPORT_SYMBOL(fal_ptp_interrupt_set); +EXPORT_SYMBOL(fal_ptp_interrupt_get); + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/fal/fal_qm.c b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_qm.c new file mode 100755 index 000000000..e2f1dc768 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_qm.c @@ -0,0 +1,1089 @@ +/* + * 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_qm FAL_QM + * @{ + */ +#include "sw.h" +#include "fal_qm.h" +#include "hsl_api.h" +#include "adpt.h" + +#ifndef IN_QM_MINI +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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ucast_hash_map_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ucast_hash_map_set(dev_id, profile, rss_hash, queue_hash); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ac_dynamic_threshold_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ac_dynamic_threshold_get(dev_id, queue_id, cfg); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ucast_queue_base_profile_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ucast_queue_base_profile_get(dev_id, queue_dest, queue_base, profile); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_mcast_priority_class_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_mcast_priority_class_get(dev_id, port, priority, queue_class); + return rv; +} +#endif +sw_error_t +_fal_ac_dynamic_threshold_set( + a_uint32_t dev_id, + a_uint32_t queue_id, + fal_ac_dynamic_threshold_t *cfg) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ac_dynamic_threshold_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ac_dynamic_threshold_set(dev_id, queue_id, 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ac_prealloc_buffer_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ac_prealloc_buffer_set(dev_id, obj, num); + return rv; +} +#ifndef IN_QM_MINI +sw_error_t +_fal_ucast_default_hash_get( + a_uint32_t dev_id, + a_uint8_t *hash_value) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ucast_default_hash_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ucast_default_hash_get(dev_id, hash_value); + return rv; +} +sw_error_t +_fal_ucast_default_hash_set( + a_uint32_t dev_id, + a_uint8_t hash_value) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ucast_default_hash_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ucast_default_hash_set(dev_id, hash_value); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ac_queue_group_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ac_queue_group_get(dev_id, queue_id, group_id); + return rv; +} +sw_error_t +_fal_ac_ctrl_get( + a_uint32_t dev_id, + fal_ac_obj_t *obj, + fal_ac_ctrl_t *cfg) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ac_ctrl_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ac_ctrl_get(dev_id, obj, cfg); + return rv; +} +sw_error_t +_fal_ac_prealloc_buffer_get( + a_uint32_t dev_id, + fal_ac_obj_t *obj, + a_uint16_t *num) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ac_prealloc_buffer_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ac_prealloc_buffer_get(dev_id, obj, num); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_mcast_priority_class_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_mcast_priority_class_set(dev_id, port, priority, queue_class); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ucast_hash_map_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ucast_hash_map_get(dev_id, profile, rss_hash, queue_hash); + return rv; +} +#endif +sw_error_t +_fal_ac_static_threshold_set( + a_uint32_t dev_id, + fal_ac_obj_t *obj, + fal_ac_static_threshold_t *cfg) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ac_static_threshold_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ac_static_threshold_set(dev_id, obj, cfg); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ac_queue_group_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ac_queue_group_set(dev_id, queue_id, group_id); + return rv; +} +#ifndef IN_QM_MINI +sw_error_t +_fal_ac_group_buffer_get( + a_uint32_t dev_id, + a_uint8_t group_id, + fal_ac_group_buffer_t *cfg) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ac_group_buffer_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ac_group_buffer_get(dev_id, group_id, cfg); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_mcast_cpu_code_class_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_mcast_cpu_code_class_get(dev_id, cpu_code, queue_class); + return rv; +} +#endif +sw_error_t +_fal_ac_ctrl_set( + a_uint32_t dev_id, + fal_ac_obj_t *obj, + fal_ac_ctrl_t *cfg) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ac_ctrl_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ac_ctrl_set(dev_id, obj, cfg); + return rv; +} +#ifndef IN_QM_MINI +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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ucast_priority_class_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ucast_priority_class_get(dev_id, profile, priority, class); + return rv; +} +#endif +sw_error_t +_fal_queue_flush( + a_uint32_t dev_id, + fal_port_t port, + a_uint16_t queue_id) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_queue_flush) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_queue_flush(dev_id, port, queue_id); + return rv; +} +#ifndef IN_QM_MINI +sw_error_t +_fal_mcast_cpu_code_class_set( + a_uint32_t dev_id, + a_uint8_t cpu_code, + a_uint8_t queue_class) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_mcast_cpu_code_class_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_mcast_cpu_code_class_set(dev_id, cpu_code, queue_class); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ucast_priority_class_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ucast_priority_class_set(dev_id, profile, priority, class); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ac_static_threshold_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ac_static_threshold_get(dev_id, obj, cfg); + return rv; +} +#endif +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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ucast_queue_base_profile_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ucast_queue_base_profile_set(dev_id, queue_dest, queue_base, profile); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ac_group_buffer_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ac_group_buffer_set(dev_id, group_id, cfg); + return rv; +} + +#ifndef IN_QM_MINI +sw_error_t +_fal_queue_counter_ctrl_set(a_uint32_t dev_id, a_bool_t cnt_en) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_queue_counter_ctrl_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_queue_counter_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_queue_counter_ctrl_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_queue_counter_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_queue_counter_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_queue_counter_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_queue_counter_cleanup) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_queue_counter_cleanup(dev_id, queue_id); + return rv; +} +#endif + +sw_error_t +_fal_qm_enqueue_ctrl_set(a_uint32_t dev_id, a_uint32_t queue_id, a_bool_t enable) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_qm_enqueue_ctrl_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_qm_enqueue_ctrl_set(dev_id, queue_id, enable); + return rv; +} + +#ifndef IN_QM_MINI +sw_error_t +_fal_qm_enqueue_ctrl_get(a_uint32_t dev_id, a_uint32_t queue_id, a_bool_t *enable) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_qm_enqueue_ctrl_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_qm_port_source_profile_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_qm_port_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_qm_port_source_profile_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_qm_port_source_profile_get(dev_id, port, src_profile); + return rv; +} + +/*insert flag for inner fal, don't remove it*/ + +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ucast_hash_map_set(dev_id, profile, rss_hash, queue_hash); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ac_dynamic_threshold_get(dev_id, queue_id, cfg); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ucast_queue_base_profile_get(dev_id, queue_dest, queue_base, profile); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_mcast_priority_class_get(dev_id, port, priority, queue_class); + FAL_API_UNLOCK; + return rv; +} +#endif +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ac_dynamic_threshold_set(dev_id, queue_id, cfg); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ac_prealloc_buffer_set(dev_id, obj, num); + FAL_API_UNLOCK; + return rv; +} +#ifndef IN_QM_MINI +sw_error_t +fal_ucast_default_hash_get( + a_uint32_t dev_id, + a_uint8_t *hash_value) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _fal_ucast_default_hash_get(dev_id, hash_value); + FAL_API_UNLOCK; + return rv; +} +sw_error_t +fal_ucast_default_hash_set( + a_uint32_t dev_id, + a_uint8_t hash_value) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _fal_ucast_default_hash_set(dev_id, hash_value); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ac_queue_group_get(dev_id, queue_id, group_id); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ac_ctrl_get(dev_id, obj, cfg); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ac_prealloc_buffer_get(dev_id, obj, num); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_mcast_priority_class_set(dev_id, port, priority, queue_class); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ucast_hash_map_get(dev_id, profile, rss_hash, queue_hash); + FAL_API_UNLOCK; + return rv; +} +#endif +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ac_static_threshold_set(dev_id, obj, cfg); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ac_queue_group_set(dev_id, queue_id, group_id); + FAL_API_UNLOCK; + return rv; +} +#ifndef IN_QM_MINI +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ac_group_buffer_get(dev_id, group_id, cfg); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_mcast_cpu_code_class_get(dev_id, cpu_code, queue_class); + FAL_API_UNLOCK; + return rv; +} +#endif +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ac_ctrl_set(dev_id, obj, cfg); + FAL_API_UNLOCK; + return rv; +} +#ifndef IN_QM_MINI +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ucast_priority_class_get(dev_id, profile, priority, class); + FAL_API_UNLOCK; + return rv; +} +#endif +sw_error_t +fal_queue_flush( + a_uint32_t dev_id, + fal_port_t port, + a_uint16_t queue_id) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _fal_queue_flush(dev_id, port, queue_id); + FAL_API_UNLOCK; + return rv; +} +#ifndef IN_QM_MINI +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_mcast_cpu_code_class_set(dev_id, cpu_code, queue_class); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ucast_priority_class_set(dev_id, profile, priority, class); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ac_static_threshold_get(dev_id, obj, cfg); + FAL_API_UNLOCK; + return rv; +} +#endif +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ucast_queue_base_profile_set(dev_id, queue_dest, queue_base, profile); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_ac_group_buffer_set(dev_id, group_id, cfg); + FAL_API_UNLOCK; + return rv; +} + +#ifndef IN_QM_MINI +sw_error_t +fal_queue_counter_ctrl_set(a_uint32_t dev_id, a_bool_t cnt_en) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _fal_queue_counter_ctrl_set(dev_id, cnt_en); + FAL_API_UNLOCK; + return rv; +} + +sw_error_t +fal_queue_counter_ctrl_get(a_uint32_t dev_id, a_bool_t *cnt_en) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _fal_queue_counter_ctrl_get(dev_id, cnt_en); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_queue_counter_get(dev_id, queue_id, info); + FAL_API_UNLOCK; + return rv; +} + +sw_error_t +fal_queue_counter_cleanup(a_uint32_t dev_id, a_uint32_t queue_id) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _fal_queue_counter_cleanup(dev_id, queue_id); + FAL_API_UNLOCK; + return rv; +} +#endif + +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_qm_enqueue_ctrl_set(dev_id, queue_id, enable); + FAL_API_UNLOCK; + return rv; +} + +#ifndef IN_QM_MINI +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_qm_enqueue_ctrl_get(dev_id, queue_id, enable); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_qm_port_source_profile_set(dev_id, port, src_profile); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_qm_port_source_profile_get(dev_id, port, src_profile); + FAL_API_UNLOCK; + return rv; +} +#endif + +EXPORT_SYMBOL(fal_ac_ctrl_set); + +EXPORT_SYMBOL(fal_ac_prealloc_buffer_set); + +EXPORT_SYMBOL(fal_ac_queue_group_set); + +EXPORT_SYMBOL(fal_ac_static_threshold_set); + +EXPORT_SYMBOL(fal_ac_dynamic_threshold_set); + +EXPORT_SYMBOL(fal_ac_group_buffer_set); + +EXPORT_SYMBOL(fal_ucast_queue_base_profile_set); + +EXPORT_SYMBOL(fal_queue_flush); + +EXPORT_SYMBOL(fal_qm_enqueue_ctrl_set); + +#ifndef IN_QM_MINI +EXPORT_SYMBOL(fal_qm_port_source_profile_set); + +EXPORT_SYMBOL(fal_qm_port_source_profile_get); + +EXPORT_SYMBOL(fal_qm_enqueue_ctrl_get); + +EXPORT_SYMBOL(fal_ac_ctrl_get); + +EXPORT_SYMBOL(fal_ac_prealloc_buffer_get); + +EXPORT_SYMBOL(fal_ac_queue_group_get); + +EXPORT_SYMBOL(fal_ac_static_threshold_get); + +EXPORT_SYMBOL(fal_ac_dynamic_threshold_get); + +EXPORT_SYMBOL(fal_ac_group_buffer_get); + +EXPORT_SYMBOL(fal_ucast_queue_base_profile_get); + +EXPORT_SYMBOL(fal_ucast_priority_class_set); + +EXPORT_SYMBOL(fal_ucast_priority_class_get); + +EXPORT_SYMBOL(fal_ucast_hash_map_set); + +EXPORT_SYMBOL(fal_ucast_hash_map_get); + +EXPORT_SYMBOL(fal_mcast_cpu_code_class_set); + +EXPORT_SYMBOL(fal_mcast_cpu_code_class_get); + +EXPORT_SYMBOL(fal_port_mcast_priority_class_set); + +EXPORT_SYMBOL(fal_port_mcast_priority_class_get); + +EXPORT_SYMBOL(fal_queue_counter_ctrl_set); + +EXPORT_SYMBOL(fal_queue_counter_ctrl_get); + +EXPORT_SYMBOL(fal_queue_counter_get); + +EXPORT_SYMBOL(fal_queue_counter_cleanup); +#endif + +/*insert flag for outter fal, don't remove it*/ diff --git a/feeds/ipq807x/qca-ssdk/src/src/fal/fal_qos.c b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_qos.c new file mode 100644 index 000000000..fcb8dc760 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_qos.c @@ -0,0 +1,2000 @@ +/* + * Copyright (c) 2012, 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_QOS + * @{ + */ +#include "sw.h" +#include "fal_qos.h" +#include "hsl_api.h" +#include "adpt.h" + +#ifndef IN_QOS_MINI +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->qos_sch_mode_set) + return SW_NOT_SUPPORTED; + + rv = p_api->qos_sch_mode_set(dev_id, mode, weight); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->qos_sch_mode_get) + return SW_NOT_SUPPORTED; + + rv = p_api->qos_sch_mode_get(dev_id, mode, weight); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->qos_queue_tx_buf_status_set) + return SW_NOT_SUPPORTED; + + rv = p_api->qos_queue_tx_buf_status_set(dev_id, port_id, enable); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->qos_queue_tx_buf_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->qos_queue_tx_buf_status_get(dev_id, port_id, enable); + return rv; +} + + + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->qos_queue_tx_buf_nr_get) + return SW_NOT_SUPPORTED; + + rv = p_api->qos_queue_tx_buf_nr_get(dev_id, port_id, queue_id, number); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->qos_port_tx_buf_status_set) + return SW_NOT_SUPPORTED; + + rv = p_api->qos_port_tx_buf_status_set(dev_id, port_id, enable); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->qos_port_tx_buf_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->qos_port_tx_buf_status_get(dev_id, port_id, enable); + return rv; +} + + + + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->qos_port_red_en_get) + return SW_NOT_SUPPORTED; + + rv = p_api->qos_port_red_en_get(dev_id, port_id, enable); + return rv; +} + + + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->qos_port_tx_buf_nr_get) + return SW_NOT_SUPPORTED; + + rv = p_api->qos_port_tx_buf_nr_get(dev_id, port_id, number); + return rv; +} + + + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->qos_port_rx_buf_nr_get) + return SW_NOT_SUPPORTED; + + rv = p_api->qos_port_rx_buf_nr_get(dev_id, port_id, number); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->cosmap_up_queue_set) + return SW_NOT_SUPPORTED; + + rv = p_api->cosmap_up_queue_set(dev_id, up, queue); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->cosmap_up_queue_get) + return SW_NOT_SUPPORTED; + + rv = p_api->cosmap_up_queue_get(dev_id, up, queue); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->cosmap_dscp_queue_set) + return SW_NOT_SUPPORTED; + + rv = p_api->cosmap_dscp_queue_set(dev_id, dscp, queue); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->cosmap_dscp_queue_get) + return SW_NOT_SUPPORTED; + + rv = p_api->cosmap_dscp_queue_get(dev_id, dscp, queue); + return rv; +} +#endif +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->qos_port_red_en_set) + return SW_NOT_SUPPORTED; + + rv = p_api->qos_port_red_en_set(dev_id, port_id, enable); + return rv; +} +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->qos_queue_tx_buf_nr_set) + return SW_NOT_SUPPORTED; + + rv = p_api->qos_queue_tx_buf_nr_set(dev_id, port_id, queue_id, number); + return rv; +} +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->qos_port_rx_buf_nr_set) + return SW_NOT_SUPPORTED; + + rv = p_api->qos_port_rx_buf_nr_set(dev_id, port_id, number); + return rv; +} +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->qos_port_tx_buf_nr_set) + return SW_NOT_SUPPORTED; + + rv = p_api->qos_port_tx_buf_nr_set(dev_id, port_id, number); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->qos_port_mode_set) + return SW_NOT_SUPPORTED; + + rv = p_api->qos_port_mode_set(dev_id, port_id, mode, enable); + return rv; +} + + + + +#ifndef IN_QOS_MINI +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->qos_port_mode_get) + return SW_NOT_SUPPORTED; + + rv = p_api->qos_port_mode_get(dev_id, port_id, mode, enable); + return rv; +} +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_qos_port_mode_pri_set) + return SW_NOT_SUPPORTED; + rv = p_adpt_api->adpt_qos_port_mode_pri_set(dev_id, port_id, mode, pri); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->qos_port_mode_pri_set) + return SW_NOT_SUPPORTED; + + rv = p_api->qos_port_mode_pri_set(dev_id, port_id, mode, pri); + return rv; +} + + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_qos_port_mode_pri_get) + return SW_NOT_SUPPORTED; + rv = p_adpt_api->adpt_qos_port_mode_pri_get(dev_id, port_id, mode, pri); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->qos_port_mode_pri_get) + return SW_NOT_SUPPORTED; + + rv = p_api->qos_port_mode_pri_get(dev_id, port_id, mode, pri); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->qos_port_default_up_set) + return SW_NOT_SUPPORTED; + + rv = p_api->qos_port_default_up_set(dev_id, port_id, up); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->qos_port_default_up_get) + return SW_NOT_SUPPORTED; + + rv = p_api->qos_port_default_up_get(dev_id, port_id, up); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->qos_port_sch_mode_set) + return SW_NOT_SUPPORTED; + + rv = p_api->qos_port_sch_mode_set(dev_id, port_id, mode, weight); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->qos_port_sch_mode_get) + return SW_NOT_SUPPORTED; + + rv = p_api->qos_port_sch_mode_get(dev_id, port_id, mode, weight); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->qos_port_default_spri_set) + return SW_NOT_SUPPORTED; + + rv = p_api->qos_port_default_spri_set(dev_id, port_id, spri); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->qos_port_default_spri_get) + return SW_NOT_SUPPORTED; + + rv = p_api->qos_port_default_spri_get(dev_id, port_id, spri); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->qos_port_default_cpri_set) + return SW_NOT_SUPPORTED; + + rv = p_api->qos_port_default_cpri_set(dev_id, port_id, cpri); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->qos_port_default_cpri_get) + return SW_NOT_SUPPORTED; + + rv = p_api->qos_port_default_cpri_get(dev_id, port_id, cpri); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->qos_port_force_spri_status_set) + return SW_NOT_SUPPORTED; + + rv = p_api->qos_port_force_spri_status_set(dev_id, port_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->qos_port_force_spri_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->qos_port_force_spri_status_get(dev_id, port_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->qos_port_force_cpri_status_set) + return SW_NOT_SUPPORTED; + + rv = p_api->qos_port_force_cpri_status_set(dev_id, port_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->qos_port_force_cpri_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->qos_port_force_cpri_status_get(dev_id, port_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->qos_queue_remark_table_set) + return SW_NOT_SUPPORTED; + + rv = p_api->qos_queue_remark_table_set(dev_id, port_id, queue_id, tbl_id, enable); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->qos_queue_remark_table_get) + return SW_NOT_SUPPORTED; + + rv = p_api->qos_queue_remark_table_get(dev_id, port_id, queue_id, tbl_id, enable); + return rv; +} +#endif + +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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_qos_port_pri_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_qos_port_pri_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_qos_port_pri_get(dev_id, port_id, pri); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_qos_cosmap_pcp_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_qos_cosmap_pcp_get(dev_id, group_id, pcp, 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_queue_scheduler_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_queue_scheduler_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_queue_scheduler_get(dev_id, node_id, + level, port_id, scheduler_cfg); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_qos_cosmap_pcp_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_qos_cosmap_pcp_set(dev_id, group_id, pcp, cosmap); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_qos_port_remark_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_qos_port_remark_get(dev_id, port_id, remark); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_qos_cosmap_dscp_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_qos_cosmap_dscp_get(dev_id, group_id, dscp, 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_qos_cosmap_flow_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_qos_cosmap_flow_set(dev_id, group_id, flow, cosmap); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_qos_port_group_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_qos_port_group_set(dev_id, port_id, group); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ring_queue_map_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_ring_queue_map_set(dev_id, ring_id, queue_bmp); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_qos_cosmap_dscp_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_qos_cosmap_dscp_set(dev_id, group_id, dscp, cosmap); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_qos_port_remark_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_qos_port_remark_set(dev_id, port_id, remark); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_qos_cosmap_flow_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_qos_cosmap_flow_get(dev_id, group_id, flow, cosmap); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_qos_port_group_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_qos_port_group_get(dev_id, port_id, group); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_ring_queue_map_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_queues_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_scheduler_dequeue_ctrl_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_scheduler_dequeue_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_scheduler_dequeue_ctrl_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_scheduler_dequeue_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_scheduler_cfg_reset) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_scheduler_resource_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_scheduler_resource_get(dev_id, port_id, cfg); + return rv; +} +#ifndef IN_QOS_MINI +/*insert flag for inner fal, don't remove it*/ + +/** + * @brief Set traffic scheduling mode on particular one device. + * @details Comments: + * Particular device may only support parts of input options. Such as + * GARUDA doesn't support variable weight in wrr mode. + * When scheduling mode is sp the weight is meaningless usually it's zero + * @param[in] dev_id device id + * @param[in] fal_sch_mode_t traffic scheduling mode + * @param[in] weight[] weight value for each queue when in wrr mode + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_qos_sch_mode_set(dev_id, mode, weight); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get traffic scheduling mode on particular device. + * @param[in] dev_id device id + * @param[in] fal_sch_mode_t traffic scheduling mode + * @param[out] weight weight value for wrr mode + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_qos_sch_mode_get(dev_id, mode, weight); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set buffer aggsinment status of transmitting queue on one particular port. + * @details Comments: + * If enable queue tx buffer on one port that means each queue of this port + * will have fixed number buffers when transmitting packets. Otherwise they + * share the whole buffers with other queues in device. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_qos_queue_tx_buf_status_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get buffer aggsinment status of transmitting queue on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_qos_queue_tx_buf_status_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + + + +/** + * @brief Get max occupied buffer number of transmitting queue on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param[out] number buffer number + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_qos_queue_tx_buf_nr_get(dev_id, port_id, queue_id, number); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set buffer aggsinment status of transmitting port on one particular port. + * @details Comments: + * If enable tx buffer on one port that means this port will have fixed + * number buffers when transmitting packets. Otherwise they will + * share the whole buffers with other ports in device. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_qos_port_tx_buf_status_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get buffer aggsinment status of transmitting port on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_qos_port_tx_buf_status_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + + + +/** + * @brief Set status of port red on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_qos_port_red_en_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + + + + +/** + * @brief Get max occupied buffer number of transmitting port on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] number buffer number + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_qos_port_tx_buf_nr_get(dev_id, port_id, number); + FAL_API_UNLOCK; + return rv; +} + + + +/** + * @brief Get max reserved buffer number of receiving port on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] number buffer number + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_qos_port_rx_buf_nr_get(dev_id, port_id, number); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set user priority to queue mapping. + * @param[in] dev_id device id + * @param[in] up 802.1p + * @param[in] queue queue id + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_cosmap_up_queue_set(dev_id, up, queue); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get user priority to queue mapping. + * @param[in] dev_id device id + * @param[in] dot1p 802.1p + * @param[out] queue queue id + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_cosmap_up_queue_get(dev_id, up, queue); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set cos map dscp_2_queue item on one particular device. + * @param[in] dev_id device id + * @param[in] dscp dscp + * @param[in] queue queue id + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_cosmap_dscp_queue_set(dev_id, dscp, queue); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get cos map dscp_2_queue item on one particular device. + * @param[in] dev_id device id + * @param[in] dscp dscp + * @param[out] queue queue id + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_cosmap_dscp_queue_get(dev_id, dscp, queue); + FAL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Set max occupied buffer number of transmitting queue on one particular port. + * @details Comments: + * Because different device has differnet hardware granularity + * function will return actual buffer numbers in hardware. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param number buffer number + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_qos_queue_tx_buf_nr_set(dev_id, port_id, queue_id, number); + FAL_API_UNLOCK; + return rv; +} +/** + * @brief Set status of port red on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_qos_port_red_en_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} +/** + * @brief Set max occupied buffer number of transmitting port on one particular port. + * @details Comments: + * Because different device has differnet hardware granularity + * function will return actual buffer number in hardware. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param number buffer number + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_qos_port_tx_buf_nr_set(dev_id, port_id, number); + FAL_API_UNLOCK; + return rv; +} +/** + * @brief Set max reserved buffer number of receiving port on one particular port. + * @details Comments: + * Because different device has differnet hardware granularity + * function will return actual buffer number in hardware. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param number buffer number + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_qos_port_rx_buf_nr_set(dev_id, port_id, number); + FAL_API_UNLOCK; + return rv; +} +/** + * @brief Set port qos mode on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode qos mode + * @param[in] enable A_TRUE of A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_qos_port_mode_set(dev_id, port_id, mode, enable); + FAL_API_UNLOCK; + return rv; +} + + +#ifndef IN_QOS_MINI +/** + * @brief Get port qos mode on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode qos mode + * @param[out] enable A_TRUE of A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_qos_port_mode_get(dev_id, port_id, mode, enable); + FAL_API_UNLOCK; + return rv; +} +/** + * @brief Set priority of one particular qos mode on one particular port. + * @details Comments: + * If the priority of a mode is more small then the priority is more high. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode qos mode + * @param[in] pri priority of one particular qos mode + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_qos_port_mode_pri_set(dev_id, port_id, mode, pri); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get priority of one particular qos mode on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode qos mode + * @param[out] pri priority of one particular qos mode + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_qos_port_mode_pri_get(dev_id, port_id, mode, pri); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set default user priority on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] up 802.1p + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_qos_port_default_up_set(dev_id, port_id, up); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get default user priority on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] up 802.1p + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_qos_port_default_up_get(dev_id, port_id, up); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set traffic scheduling mode on particular one port. + * @details Comments: + * Particular device may only support parts of input options. Such as + * GARUDA doesn't support variable weight in wrr mode. + * When scheduling mode is sp the weight is meaningless usually it's zero + * @param[in] dev_id device id + * @param[in] fal_sch_mode_t traffic scheduling mode + * @param[in] weight[] weight value for each queue when in wrr mode + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_qos_port_sch_mode_set(dev_id, port_id, mode, weight); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get traffic scheduling mode on particular port. + * @param[in] dev_id device id + * @param[in] fal_sch_mode_t traffic scheduling mode + * @param[out] weight weight value for wrr mode + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_qos_port_sch_mode_get(dev_id, port_id, mode, weight); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set default stag priority on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] spri vlan priority + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_qos_port_default_spri_set(dev_id, port_id, spri); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get default stag priority on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] spri vlan priority + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_qos_port_default_spri_get(dev_id, port_id, spri); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set default ctag priority on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] cpri vlan priority + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_qos_port_default_cpri_set(dev_id, port_id, cpri); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get default ctag priority on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] cpri vlan priority + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_qos_port_default_cpri_get(dev_id, port_id, cpri); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set force stag priority flag on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_qos_port_force_spri_status_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + + +/** + * @brief Get force stag priority flag on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_qos_port_force_spri_status_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set force ctag priority flag on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_qos_port_force_cpri_status_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get force ctag priority flag on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_qos_port_force_cpri_status_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set egress queue based CoS remark on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param[in] tbl_id CoS remark table id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_qos_queue_remark_table_set(dev_id, port_id, queue_id, tbl_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get egress queue based CoS remark on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param[out] tbl_id CoS remark table id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ + +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; + + FAL_API_LOCK; + rv = _fal_qos_queue_remark_table_get(dev_id, port_id, queue_id, tbl_id, enable); + FAL_API_UNLOCK; + return rv; +} +#endif + +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_qos_port_pri_precedence_set(dev_id, port_id, pri); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_qos_port_pri_precedence_get(dev_id, port_id, pri); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_qos_cosmap_pcp_get(dev_id, group_id, pcp, cosmap); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_queue_scheduler_set(dev_id, node_id, level, port_id, scheduler_cfg); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_queue_scheduler_get(dev_id, node_id, level, port_id, scheduler_cfg); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_qos_cosmap_pcp_set(dev_id, group_id, pcp, cosmap); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_qos_port_remark_get(dev_id, port_id, remark); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_qos_cosmap_dscp_get(dev_id, group_id, dscp, cosmap); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_qos_cosmap_flow_set(dev_id, group_id, flow, cosmap); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_qos_port_group_set(dev_id, port_id, group); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_edma_ring_queue_map_set(dev_id, ring_id, queue_bmp); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_qos_cosmap_dscp_set(dev_id, group_id, dscp, cosmap); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_qos_port_remark_set(dev_id, port_id, remark); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_qos_cosmap_flow_get(dev_id, group_id, flow, cosmap); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_qos_port_group_get(dev_id, port_id, group); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_edma_ring_queue_map_get(dev_id, ring_id, queue_bmp); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_queues_get(dev_id, port_id, queue_bmp); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_scheduler_dequeue_ctrl_set(dev_id, queue_id, enable); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_scheduler_dequeue_ctrl_get(dev_id, queue_id, enable); + FAL_API_UNLOCK; + return rv; +} + +sw_error_t +fal_port_scheduler_cfg_reset( + a_uint32_t dev_id, + fal_port_t port_id) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_scheduler_cfg_reset(dev_id, port_id); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_scheduler_resource_get(dev_id, port_id, cfg); + FAL_API_UNLOCK; + return rv; +} + +EXPORT_SYMBOL(fal_scheduler_dequeue_ctrl_get); + +EXPORT_SYMBOL(fal_scheduler_dequeue_ctrl_set); + +EXPORT_SYMBOL(fal_queue_scheduler_set); + +EXPORT_SYMBOL(fal_queue_scheduler_get); + +EXPORT_SYMBOL(fal_port_queues_get); + +EXPORT_SYMBOL(fal_qos_port_pri_precedence_set); + +EXPORT_SYMBOL(fal_qos_port_pri_precedence_get); + +EXPORT_SYMBOL(fal_qos_port_group_set); + +EXPORT_SYMBOL(fal_qos_port_group_get); + +EXPORT_SYMBOL(fal_qos_cosmap_pcp_set); + +EXPORT_SYMBOL(fal_qos_cosmap_pcp_get); + +EXPORT_SYMBOL(fal_qos_cosmap_dscp_set); + +EXPORT_SYMBOL(fal_qos_cosmap_dscp_get); + +EXPORT_SYMBOL(fal_qos_cosmap_flow_set); + +EXPORT_SYMBOL(fal_qos_port_remark_set); + +EXPORT_SYMBOL(fal_qos_port_remark_get); + +EXPORT_SYMBOL(fal_edma_ring_queue_map_set); + +EXPORT_SYMBOL(fal_edma_ring_queue_map_get); + +EXPORT_SYMBOL(fal_port_scheduler_cfg_reset); + +EXPORT_SYMBOL(fal_port_scheduler_resource_get); + +/*insert flag for outter fal, don't remove it*/ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/fal/fal_rate.c b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_rate.c new file mode 100755 index 000000000..1298837ac --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_rate.c @@ -0,0 +1,840 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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_rate FAL_RATE + * @{ + */ +#include "sw.h" +#include "fal_rate.h" +#include "hsl_api.h" + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->rate_queue_egrl_set) + return SW_NOT_SUPPORTED; + + rv = p_api->rate_queue_egrl_set(dev_id, port_id, queue_id, speed, enable); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->rate_queue_egrl_get) + return SW_NOT_SUPPORTED; + + rv = p_api->rate_queue_egrl_get(dev_id, port_id, queue_id, speed, enable); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->rate_port_egrl_set) + return SW_NOT_SUPPORTED; + + rv = p_api->rate_port_egrl_set(dev_id, port_id, speed, enable); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->rate_port_egrl_get) + return SW_NOT_SUPPORTED; + + rv = p_api->rate_port_egrl_get(dev_id, port_id, speed, enable); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->rate_port_inrl_set) + return SW_NOT_SUPPORTED; + + rv = p_api->rate_port_inrl_set(dev_id, port_id, speed, enable); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->rate_port_inrl_get) + return SW_NOT_SUPPORTED; + + rv = p_api->rate_port_inrl_get(dev_id, port_id, speed, enable); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->storm_ctrl_frame_set) + return SW_NOT_SUPPORTED; + + rv = p_api->storm_ctrl_frame_set(dev_id, port_id, frame_type, enable); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->storm_ctrl_frame_get) + return SW_NOT_SUPPORTED; + + rv = p_api->storm_ctrl_frame_get(dev_id, port_id, frame_type, enable); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->storm_ctrl_rate_set) + return SW_NOT_SUPPORTED; + + rv = p_api->storm_ctrl_rate_set(dev_id, port_id, rate); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->storm_ctrl_rate_get) + return SW_NOT_SUPPORTED; + + rv = p_api->storm_ctrl_rate_get(dev_id, port_id, rate); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->rate_port_policer_set) + return SW_NOT_SUPPORTED; + + rv = p_api->rate_port_policer_set(dev_id, port_id, policer); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->rate_port_policer_get) + return SW_NOT_SUPPORTED; + + rv = p_api->rate_port_policer_get(dev_id, port_id, policer); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->rate_port_shaper_set) + return SW_NOT_SUPPORTED; + + rv = p_api->rate_port_shaper_set(dev_id, port_id, enable, shaper); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->rate_port_shaper_get) + return SW_NOT_SUPPORTED; + + rv = p_api->rate_port_shaper_get(dev_id, port_id, enable, shaper); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->rate_queue_shaper_set) + return SW_NOT_SUPPORTED; + + rv = p_api->rate_queue_shaper_set(dev_id, port_id, queue_id, enable, shaper); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->rate_queue_shaper_get) + return SW_NOT_SUPPORTED; + + rv = p_api->rate_queue_shaper_get(dev_id, port_id, queue_id, enable, shaper); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->rate_acl_policer_set) + return SW_NOT_SUPPORTED; + + rv = p_api->rate_acl_policer_set(dev_id, policer_id, policer); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->rate_acl_policer_get) + return SW_NOT_SUPPORTED; + + rv = p_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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->rate_port_add_rate_byte_set) + return SW_NOT_SUPPORTED; + + rv = p_api->rate_port_add_rate_byte_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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->rate_port_add_rate_byte_set) + return SW_NOT_SUPPORTED; + + rv = p_api->rate_port_add_rate_byte_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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->rate_port_gol_flow_en_set) + return SW_NOT_SUPPORTED; + + rv = p_api->rate_port_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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->rate_port_gol_flow_en_get) + return SW_NOT_SUPPORTED; + + rv = p_api->rate_port_gol_flow_en_get(dev_id, port_id, enable); + return rv; +} + + + +/** + * @brief Set queue egress rate limit status on one particular port and queue. + * @details Comments: + * The granularity of speed is bps. + * Because different device has differnet hardware granularity function + * will return actual speed in hardware. + * When disable queue egress rate limit input parameter speed is meaningless. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param speed rate limit speed + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_rate_queue_egrl_set(dev_id, port_id, queue_id, speed, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get queue egress rate limit status on one particular port and queue. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param[out] speed rate limit speed + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_rate_queue_egrl_get(dev_id, port_id, queue_id, speed, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set port egress rate limit status on one particular port. + * @details Comments: + * The granularity of speed is bps. + * Because different device has differnet hardware granularity function + * will return actual speed in hardware. + * When disable port egress rate limit input parameter speed is meaningless. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param speed rate limit speed + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_rate_port_egrl_set(dev_id, port_id, speed, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get port egress rate limit status on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] speed rate limit speed + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_rate_port_egrl_get(dev_id, port_id, speed, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set port ingress rate limit status on one particular port. + * @details Comments: + * The granularity of speed is bps. + * Because different device has differnet hardware granularity function + * will return actual speed in hardware. + * When disable port ingress rate limit input parameter speed is meaningless. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param speed rate limit speed + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_rate_port_inrl_set(dev_id, port_id, speed, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get port ingress rate limit status on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] speed rate limit speed + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_rate_port_inrl_get(dev_id, port_id, speed, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set particular type storm control status on one particular port. + * @details Comments: + * When enable one particular packets type storm control this type packets + * speed will be calculated in storm control. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] frame_type packets type which causes storm + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_storm_ctrl_frame_set(dev_id, port_id, frame_type, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get particular type storm control status on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] frame_type packets type which causes storm + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_storm_ctrl_frame_get(dev_id, port_id, frame_type, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set storm control speed on one particular port. + * @details Comments: + * The granularity of speed is packets per second. + * Because different device has differnet hardware granularity function + * will return actual speed in hardware. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param speed storm control speed + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_storm_ctrl_rate_set(dev_id, port_id, rate); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get storm control speed on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] speed storm control speed + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_storm_ctrl_rate_get(dev_id, port_id, rate); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set port ingress policer parameters on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] policer port ingress policer parameter + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_rate_port_policer_set(dev_id, port_id, policer); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get port ingress policer parameters on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] policer port ingress policer parameter + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_rate_port_policer_get(dev_id, port_id, policer); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set port egress shaper parameters on one particular port. + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] shaper port egress shaper parameter + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_rate_port_shaper_set(dev_id, port_id, enable, shaper); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get port egress shaper parameters on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @param[out] shaper port egress shaper parameter + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_rate_port_shaper_get(dev_id, port_id, enable, shaper); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set queue egress shaper parameters on one particular port. + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] shaper port egress shaper parameter + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_rate_queue_shaper_set(dev_id, port_id, queue_id, enable, shaper); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get queue egress shaper parameters on one particular port. + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param[out] enable A_TRUE or A_FALSE + * @param[out] shaper port egress shaper parameter + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_rate_queue_shaper_get(dev_id, port_id, queue_id, enable, shaper); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set ACL ingress policer parameters. + * @param[in] dev_id device id + * @param[in] policer_id ACL policer id + * @param[in] policer ACL ingress policer parameters + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_rate_acl_policer_set(dev_id, policer_id, policer); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get ACL ingress policer parameters. + * @param[in] dev_id device id + * @param[in] policer_id ACL policer id + * @param[in] policer ACL ingress policer parameters + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_rate_acl_policer_get(dev_id, policer_id, policer); + FAL_API_UNLOCK; + 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; + + FAL_API_LOCK; + rv = _fal_rate_port_add_rate_byte_set(dev_id, port_id, number); + FAL_API_UNLOCK; + 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; + + FAL_API_LOCK; + rv = _fal_rate_port_add_rate_byte_get(dev_id, port_id, number); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of port global flow control when global threshold is reached. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_rate_port_gol_flow_en_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief get status of port global flow control when global threshold is reached. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_rate_port_gol_flow_en_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + + + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/fal/fal_reg_access.c b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_reg_access.c new file mode 100755 index 000000000..c578def79 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_reg_access.c @@ -0,0 +1,570 @@ +/* + * Copyright (c) 2012, 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*/ +/** + * @defgroup fal_reg_access FAL_REG_ACCESS + * @{ + */ +#include "sw.h" +#include "fal_reg_access.h" +#include "hsl_api.h" +#include "hsl_phy.h" + +static 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; + hsl_api_t *p_api; + a_uint8_t phy_addr_type; + hsl_phy_get phy_get_func; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + /* the MSB first byte of phy_addr marks the type of + * phy address, such as the i2c address, the value of + * MSB first byte should be 1 */ + phy_addr_type = (phy_addr & 0xff000000) >> 24; + phy_addr = phy_addr & 0xff; + switch (phy_addr_type) { + case PHY_I2C_ACCESS: + phy_get_func = p_api->phy_i2c_get; + break; + default: + phy_get_func = p_api->phy_get; + break; + } + + if (NULL == phy_get_func) { + return SW_NOT_SUPPORTED; + } + + rv = phy_get_func(dev_id, phy_addr, reg, value); + return rv; +} + +static 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; + hsl_api_t *p_api; + a_uint8_t phy_addr_type; + hsl_phy_set phy_set_func; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + /* the MSB first byte of phy_addr marks the type of + * phy address, such as the i2c address, the value of + * MSB first byte should be 1 */ + phy_addr_type = (phy_addr & 0xff000000) >> 24; + phy_addr = phy_addr & 0xff; + switch (phy_addr_type) { + case PHY_I2C_ACCESS: + phy_set_func = p_api->phy_i2c_set; + break; + default: + phy_set_func = p_api->phy_set; + break; + } + + if (NULL == phy_set_func) { + return SW_NOT_SUPPORTED; + } + + rv = phy_set_func(dev_id, phy_addr, reg, value); + return rv; +} +/*qca808x_end*/ +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->reg_get) + return SW_NOT_SUPPORTED; + + rv = p_api->reg_get(dev_id, reg_addr, value, value_len); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->reg_set) + return SW_NOT_SUPPORTED; + + rv = p_api->reg_set(dev_id, reg_addr, value, value_len); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->psgmii_reg_get) + return SW_NOT_SUPPORTED; + + rv = p_api->psgmii_reg_get(dev_id, reg_addr, value, value_len); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->psgmii_reg_set) + return SW_NOT_SUPPORTED; + + rv = p_api->psgmii_reg_set(dev_id, reg_addr, value, value_len); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->reg_field_get) + return SW_NOT_SUPPORTED; + + rv = p_api->reg_field_get(dev_id, reg_addr, bit_offset, field_len, value, value_len); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->reg_field_set) + return SW_NOT_SUPPORTED; + + rv = p_api->reg_field_set(dev_id, reg_addr, bit_offset, field_len, value, value_len); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->register_dump) + return SW_NOT_SUPPORTED; + + rv = p_api->register_dump(dev_id, reg_idx,reg_dump); + return rv; +} + + +static sw_error_t +_fal_debug_reg_dump(a_uint32_t dev_id, fal_debug_reg_dump_t *reg_dump) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->debug_register_dump) + return SW_NOT_SUPPORTED; + + rv = p_api->debug_register_dump(dev_id, reg_dump); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->debug_psgmii_self_test) + return SW_NOT_SUPPORTED; + + rv = p_api->debug_psgmii_self_test(dev_id, enable, times, result); + return rv; +} + +static sw_error_t +_fal_phy_dump(a_uint32_t dev_id, a_uint32_t phy_addr, a_uint32_t idx,fal_phy_dump_t *phy_dump) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->phy_dump) + return SW_NOT_SUPPORTED; + + rv = p_api->phy_dump(dev_id, phy_addr,idx,phy_dump); + return rv; +} +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->uniphy_reg_get) + return SW_NOT_SUPPORTED; + + rv = p_api->uniphy_reg_get(dev_id, index, reg_addr, value, value_len); + return rv; +} + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->uniphy_reg_set) + return SW_NOT_SUPPORTED; + + rv = p_api->uniphy_reg_set(dev_id, index, reg_addr, value, value_len); + return rv; +} +/*qca808x_start*/ +/** + * fal_phy_get - get value of specific phy device + * @phy_addr: id of the phy device + * @reg: register id of phy device + * @value: pointer to the memory storing the value. + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_phy_get(dev_id, phy_addr, reg, value); + FAL_API_UNLOCK; + return rv; +} + +/** + * fal_phy_set - set value of specific phy device + * @phy_addr: id of the phy device + * @reg: register id of phy device + * @value: register value. + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_phy_set(dev_id, phy_addr, reg, value); + FAL_API_UNLOCK; + return rv; +} +/*qca808x_end*/ +/** + * fal_reg_get - get value of specific register + * @reg_addr: address of the register + * @value: pointer to the memory storing the value. + * @value_len: length of the value. + * + * Get the value of a specific register field with related parameter + */ +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; + + FAL_API_LOCK; + rv = _fal_reg_get(dev_id, reg_addr, value, value_len); + FAL_API_UNLOCK; + return rv; +} + +/** + * fal_reg_set - set value of specific register + * @reg_addr: address of the register + * @value: pointer to the memory storing the value. + * @value_len: length of the value. + * + * Get the value of a specific register field with related parameter + */ +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; + + FAL_API_LOCK; + rv = _fal_reg_set(dev_id, reg_addr, value, value_len); + FAL_API_UNLOCK; + return rv; +} + +/** + * fal_psgmii_reg_get - get value of specific register in psgmii module + * @reg_addr: address of the register + * @value: pointer to the memory storing the value. + * @value_len: length of the value. + * + * Get the value of a specific register field with related parameter + */ +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; + + FAL_API_LOCK; + rv = _fal_psgmii_reg_get(dev_id, reg_addr, value, value_len); + FAL_API_UNLOCK; + return rv; +} + +/** + * fal_psgmii_reg_set - set value of specific register in psgmii module + * @reg_addr: address of the register + * @value: pointer to the memory storing the value. + * @value_len: length of the value. + * + * Get the value of a specific register field with related parameter + */ +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; + + FAL_API_LOCK; + rv = _fal_psgmii_reg_set(dev_id, reg_addr, value, value_len); + FAL_API_UNLOCK; + return rv; +} + +/** + * fal_reg_field_get - get value of specific register field + * @reg_addr: address of the register + * @bit_offset: position of the field in bit + * @field_len: length of the field in bit + * @value: pointer to the memory storing the value. + * @value_len: length of the value. + * + * Get the value of a specific register field with related parameter + */ +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; + + FAL_API_LOCK; + rv = _fal_reg_field_get(dev_id, reg_addr, bit_offset, field_len, value, value_len); + FAL_API_UNLOCK; + return rv; +} + +/** + * fal_reg_field_set - set value of specific register field + * @reg_addr: address of the register + * @bit_offset: position of the field in bit + * @field_len: length of the field in bit + * @value: pointer to the memory storing the value. + * @value_len: length of the value. + * + * Set the value of a specific register field with related parameter + */ +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; + + FAL_API_LOCK; + rv = _fal_reg_field_set(dev_id, reg_addr, bit_offset, field_len, value, value_len); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief dump device register group + * @details Comments: + * The unit of packets size is byte. + * @param[in] dev_id device id + * @param[out] reg_dump dump out register group + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_reg_dump(dev_id, reg_idx,reg_dump); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief dump device debug register + * @details Comments: + * The unit of packets size is byte. + * @param[in] dev_id device id + * @param[out] reg_dump dump out debub register + * @return SW_OK or error code + */ +sw_error_t +fal_debug_reg_dump(a_uint32_t dev_id, fal_debug_reg_dump_t *reg_dump) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_debug_reg_dump(dev_id,reg_dump); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief psgmii self test + * @details Comments: + * The unit of packets size is byte. + * @param[in] dev_id device id, enable, times + * @param[out] status + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_debug_psgmii_self_test(dev_id, enable, times, result); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief phy dump + * @details Comments: + * The unit of packets size is byte. + * @param[in] dev_id device id, phy addr, phy reg group + * @param[out] reg value + * @return SW_OK or error code + */ +sw_error_t +fal_phy_dump(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t idx, fal_phy_dump_t * phy_dump) + +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_phy_dump(dev_id, phy_addr, idx, phy_dump); + FAL_API_UNLOCK; + return rv; +} + +/** + * fal_uniphy_reg_get - get value of specific register in uniphy module + * @reg_addr: address of the register + * @uniphy_index: index of uniphy + * @value: pointer to the memory storing the value. + * @value_len: length of the value. + * + * Get the value of a specific register field with related parameter + */ +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; + + FAL_API_LOCK; + rv = _fal_uniphy_reg_get(dev_id, index, reg_addr, value, value_len); + FAL_API_UNLOCK; + return rv; +} + +/** + * fal_uniphy_reg_set - set value of specific register in uniphy module + * @reg_addr: address of the register + * @uniphy_index: index of uniphy + * @value: pointer to the memory storing the value. + * @value_len: length of the value. + * + * Get the value of a specific register field with related parameter + */ +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; + + FAL_API_LOCK; + rv = _fal_uniphy_reg_set(dev_id, index, reg_addr, value, value_len); + FAL_API_UNLOCK; + return rv; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/fal/fal_rss_hash.c b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_rss_hash.c new file mode 100755 index 000000000..8b2eca87a --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_rss_hash.c @@ -0,0 +1,85 @@ +/* + * 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. + */ + + +/** + * @defgroup fal_rss_hash FAL_RSS_HASH + * @{ + */ +#include "sw.h" +#include "fal_rss_hash.h" +#include "hsl_api.h" +#include "adpt.h" + +#include +#include + + +/** + * @} + */ +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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_rss_hash_config_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_rss_hash_config_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_rss_hash_config_get(dev_id, mode, config); + return rv; +} + +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 = SW_OK; + + FAL_RSS_HASH_API_LOCK; + rv = _fal_rss_hash_config_set(dev_id, mode, config); + FAL_RSS_HASH_API_UNLOCK; + 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 = SW_OK; + + FAL_RSS_HASH_API_LOCK; + rv = _fal_rss_hash_config_get(dev_id, mode, config); + FAL_RSS_HASH_API_UNLOCK; + return rv; +} + +EXPORT_SYMBOL(fal_rss_hash_config_set); +EXPORT_SYMBOL(fal_rss_hash_config_get); diff --git a/feeds/ipq807x/qca-ssdk/src/src/fal/fal_sec.c b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_sec.c new file mode 100755 index 000000000..32071e4b1 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_sec.c @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2012, 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_sec FAL_SEC + * @{ + */ +#include "sw.h" +#include "fal_sec.h" +#include "hsl_api.h" +#include "adpt.h" + +static sw_error_t +_fal_sec_norm_item_set(a_uint32_t dev_id, fal_norm_item_t item, void *value) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->sec_norm_item_set) + return SW_NOT_SUPPORTED; + + rv = p_api->sec_norm_item_set(dev_id, item, value); + return rv; +} + +static sw_error_t +_fal_sec_norm_item_get(a_uint32_t dev_id, fal_norm_item_t item, void *value) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->sec_norm_item_get) + return SW_NOT_SUPPORTED; + + rv = p_api->sec_norm_item_get(dev_id, item, value); + return rv; +} + +sw_error_t +_fal_sec_l3_excep_parser_ctrl_set(a_uint32_t dev_id, fal_l3_excep_parser_ctrl *ctrl) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_sec_l3_excep_parser_ctrl_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_sec_l3_excep_parser_ctrl_set(dev_id, 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_sec_l3_excep_ctrl_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_sec_l3_excep_ctrl_get(dev_id, excep_type, ctrl); + return rv; +} +sw_error_t +_fal_sec_l3_excep_parser_ctrl_get(a_uint32_t dev_id, fal_l3_excep_parser_ctrl *ctrl) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_sec_l3_excep_parser_ctrl_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_sec_l3_excep_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_sec_l4_excep_parser_ctrl_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_sec_l4_excep_parser_ctrl_set(dev_id, ctrl); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_sec_l3_excep_ctrl_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_sec_l3_excep_ctrl_set(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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_sec_l4_excep_parser_ctrl_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_sec_l4_excep_parser_ctrl_get(dev_id, ctrl); + return rv; +} +/*insert flag for inner fal, don't remove it*/ + +/** + * @brief Set normalization particular item types value. + * @details Comments: + * This operation will set normalization item values on a particular device. + * The prototye of value based on the item type. + * @param[in] dev_id device id + * @param[in] item normalizaton item type + * @param[in] value normalizaton item value + * @return SW_OK or error code + */ +sw_error_t +fal_sec_norm_item_set(a_uint32_t dev_id, fal_norm_item_t item, void *value) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_sec_norm_item_set(dev_id, item, value); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get normalization particular item types value. + * @details Comments: + * This operation will set normalization item values on a particular device. + * The prototye of value based on the item type. + * @param[in] dev_id device id + * @param[in] item normalizaton item type + * @param[out] value normalizaton item value + * @return SW_OK or error code + */ +sw_error_t +fal_sec_norm_item_get(a_uint32_t dev_id, fal_norm_item_t item, void *value) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_sec_norm_item_get(dev_id, item, value); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_sec_l3_excep_parser_ctrl_set(dev_id, ctrl); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_sec_l3_excep_ctrl_get(dev_id, excep_type, ctrl); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_sec_l3_excep_parser_ctrl_get(dev_id, ctrl); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_sec_l4_excep_parser_ctrl_set(dev_id, ctrl); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_sec_l3_excep_ctrl_set(dev_id, excep_type, ctrl); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_sec_l4_excep_parser_ctrl_get(dev_id, ctrl); + FAL_API_UNLOCK; + return rv; +} +/*insert flag for outter fal, don't remove it*/ + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/fal/fal_servcode.c b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_servcode.c new file mode 100755 index 000000000..dda3deb96 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_servcode.c @@ -0,0 +1,143 @@ +/* + * 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_SERVCODE + * @{ + */ +#include "sw.h" +#include "fal_servcode.h" +#include "hsl_api.h" +#include "adpt.h" + +#include +#include + + +/** + * @} + */ +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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_servcode_config_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_servcode_config_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_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; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_servcode_loopcheck_en) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_servcode_loopcheck_en(dev_id, enable); + return rv; +} + +sw_error_t +_fal_servcode_loopcheck_status_get(a_uint32_t dev_id, a_bool_t *enable) +{ + sw_error_t rv; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_servcode_loopcheck_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_servcode_loopcheck_status_get(dev_id, enable); + return rv; +} + +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 = SW_OK; + + FAL_SERVCODE_API_LOCK; + rv = _fal_servcode_config_set(dev_id, servcode_index, entry); + FAL_SERVCODE_API_UNLOCK; + 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 = SW_OK; + + FAL_SERVCODE_API_LOCK; + rv = _fal_servcode_config_get(dev_id, servcode_index, entry); + FAL_SERVCODE_API_UNLOCK; + return rv; +} + +sw_error_t +fal_servcode_loopcheck_en(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv = SW_OK; + + FAL_SERVCODE_API_LOCK; + rv = _fal_servcode_loopcheck_en(dev_id, enable); + FAL_SERVCODE_API_UNLOCK; + return rv; +} + +sw_error_t +fal_servcode_loopcheck_status_get(a_uint32_t dev_id, a_bool_t *enable) +{ + sw_error_t rv = SW_OK; + + FAL_SERVCODE_API_LOCK; + rv = _fal_servcode_loopcheck_status_get(dev_id, enable); + FAL_SERVCODE_API_UNLOCK; + return rv; +} + +EXPORT_SYMBOL(fal_servcode_config_set); +EXPORT_SYMBOL(fal_servcode_config_get); +EXPORT_SYMBOL(fal_servcode_loopcheck_en); +EXPORT_SYMBOL(fal_servcode_loopcheck_status_get); diff --git a/feeds/ipq807x/qca-ssdk/src/src/fal/fal_sfp.c b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_sfp.c new file mode 100755 index 000000000..c3fe063ab --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_sfp.c @@ -0,0 +1,508 @@ +/* + * 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 "fal_sfp.h" +#include "adpt.h" +#include "hsl_api.h" + +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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_sfp_diag_ctrl_status_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_sfp_diag_ctrl_status_get(dev_id, port_id, ctrl_status); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_sfp_diag_extenal_calibration_const_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_sfp_diag_extenal_calibration_const_get(dev_id, port_id, cal_const); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_sfp_link_length_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_sfp_link_length_get(dev_id, port_id, link_len); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_sfp_diag_internal_threshold_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_sfp_diag_internal_threshold_get(dev_id, port_id, threshold); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_sfp_diag_realtime_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_sfp_diag_realtime_get(dev_id, port_id, real_diag); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_sfp_laser_wavelength_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_sfp_option_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_sfp_option_get(dev_id, port_id, option); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_sfp_checkcode_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_sfp_checkcode_get(dev_id, port_id, cc_type, ccode); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_sfp_diag_alarm_warning_flag_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_sfp_diag_alarm_warning_flag_get(dev_id, port_id, alarm_warn_flag); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_sfp_device_type_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_sfp_device_type_get(dev_id, port_id, sfp_id); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_sfp_vendor_info_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_sfp_vendor_info_get(dev_id, port_id, vender_info); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_sfp_transceiver_code_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_sfp_transceiver_code_get(dev_id, port_id, transc_code); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_sfp_ctrl_rate_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_sfp_enhanced_cfg_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_sfp_enhanced_cfg_get(dev_id, port_id, enhanced_feature); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_sfp_rate_encode_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_sfp_rate_encode_get(dev_id, port_id, encode); + return rv; +} + +sw_error_t +_fal_sfp_eeprom_data_get(a_uint32_t dev_id, a_uint32_t port_id, fal_sfp_data_t *entry) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_sfp_eeprom_data_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_sfp_eeprom_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_sfp_eeprom_data_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_sfp_eeprom_data_set(dev_id, port_id, entry); + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_sfp_diag_ctrl_status_get(dev_id, port_id, ctrl_status); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_sfp_diag_extenal_calibration_const_get(dev_id, port_id, cal_const); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_sfp_link_length_get(dev_id, port_id, link_len); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_sfp_diag_internal_threshold_get(dev_id, port_id, threshold); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_sfp_diag_realtime_get(dev_id, port_id, real_diag); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_sfp_laser_wavelength_get(dev_id, port_id, laser_wavelen); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_sfp_option_get(dev_id, port_id, option); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_sfp_checkcode_get(dev_id, port_id, cc_type, ccode); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_sfp_diag_alarm_warning_flag_get(dev_id, port_id, alarm_warn_flag); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_sfp_device_type_get(dev_id, port_id, sfp_id); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_sfp_vendor_info_get(dev_id, port_id, vender_info); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_sfp_transceiver_code_get(dev_id, port_id, transc_code); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_sfp_ctrl_rate_get(dev_id, port_id, rate_limit); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_sfp_enhanced_cfg_get(dev_id, port_id, enhanced_feature); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_sfp_rate_encode_get(dev_id, port_id, encode); + FAL_API_UNLOCK; + return rv; +} + +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_sfp_eeprom_data_get(dev_id, port_id, entry); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_sfp_eeprom_data_set(dev_id, port_id, entry); + FAL_API_UNLOCK; + return rv; +} + +EXPORT_SYMBOL(fal_sfp_diag_ctrl_status_get); +EXPORT_SYMBOL(fal_sfp_diag_extenal_calibration_const_get); +EXPORT_SYMBOL(fal_sfp_link_length_get); +EXPORT_SYMBOL(fal_sfp_diag_internal_threshold_get); +EXPORT_SYMBOL(fal_sfp_diag_realtime_get); +EXPORT_SYMBOL(fal_sfp_laser_wavelength_get); +EXPORT_SYMBOL(fal_sfp_option_get); +EXPORT_SYMBOL(fal_sfp_checkcode_get); +EXPORT_SYMBOL(fal_sfp_diag_alarm_warning_flag_get); +EXPORT_SYMBOL(fal_sfp_device_type_get); +EXPORT_SYMBOL(fal_sfp_vendor_info_get); +EXPORT_SYMBOL(fal_sfp_transceiver_code_get); +EXPORT_SYMBOL(fal_sfp_ctrl_rate_get); +EXPORT_SYMBOL(fal_sfp_enhanced_cfg_get); +EXPORT_SYMBOL(fal_sfp_rate_encode_get); +EXPORT_SYMBOL(fal_sfp_eeprom_data_get); +EXPORT_SYMBOL(fal_sfp_eeprom_data_set); diff --git a/feeds/ipq807x/qca-ssdk/src/src/fal/fal_shaper.c b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_shaper.c new file mode 100755 index 000000000..addb0f3c7 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_shaper.c @@ -0,0 +1,601 @@ +/* + * 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_shaper FAL_SHAPER + * @{ + */ +#include "sw.h" +#include "fal_shaper.h" +#include "hsl_api.h" +#include "adpt.h" + +#include +#include + +sw_error_t +_fal_flow_shaper_set(a_uint32_t dev_id, a_uint32_t flow_id, + fal_shaper_config_t * shaper) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_flow_shaper_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_flow_shaper_set(dev_id, flow_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_queue_shaper_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_queue_shaper_get(dev_id, queue_id, shaper); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_queue_shaper_token_number_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_queue_shaper_token_number_set(dev_id, queue_id, token_number); + return rv; +} +#ifndef IN_SHAPER_MINI +sw_error_t +_fal_port_shaper_get(a_uint32_t dev_id, fal_port_t port_id, + fal_shaper_config_t * shaper) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_shaper_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_shaper_get(dev_id, port_id, shaper); + return rv; +} +sw_error_t +_fal_flow_shaper_timeslot_get(a_uint32_t dev_id, a_uint32_t *timeslot) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_flow_shaper_time_slot_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_flow_shaper_time_slot_get(dev_id, timeslot); + return rv; +} +sw_error_t +_fal_port_shaper_timeslot_get(a_uint32_t dev_id, a_uint32_t *timeslot) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_shaper_time_slot_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_shaper_time_slot_get(dev_id, timeslot); + return rv; +} +#endif +sw_error_t +_fal_flow_shaper_timeslot_set(a_uint32_t dev_id, a_uint32_t timeslot) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_flow_shaper_time_slot_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_flow_shaper_time_slot_set(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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_shaper_token_number_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_shaper_token_number_set(dev_id, port_id, token_number); + return rv; +} +#ifndef IN_SHAPER_MINI +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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_queue_shaper_token_number_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_queue_shaper_token_number_get(dev_id, queue_id, token_number); + return rv; +} +sw_error_t +_fal_queue_shaper_timeslot_get(a_uint32_t dev_id, a_uint32_t *timeslot) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_queue_shaper_time_slot_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_queue_shaper_time_slot_get(dev_id, timeslot); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_shaper_token_number_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_shaper_token_number_get(dev_id, port_id, token_number); + return rv; +} +#endif +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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_flow_shaper_token_number_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_flow_shaper_token_number_set(dev_id, flow_id, token_number); + return rv; +} +#ifndef IN_SHAPER_MINI +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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_flow_shaper_token_number_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_flow_shaper_token_number_get(dev_id, flow_id, token_number); + return rv; +} +#endif +sw_error_t +_fal_port_shaper_set(a_uint32_t dev_id, fal_port_t port_id, + fal_shaper_config_t * shaper) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_shaper_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_shaper_set(dev_id, port_id, shaper); + return rv; +} +sw_error_t +_fal_port_shaper_timeslot_set(a_uint32_t dev_id, a_uint32_t timeslot) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_shaper_time_slot_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_shaper_time_slot_set(dev_id, timeslot); + return rv; +} +#ifndef IN_SHAPER_MINI +sw_error_t +_fal_flow_shaper_get(a_uint32_t dev_id, a_uint32_t flow_id, + fal_shaper_config_t * shaper) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_flow_shaper_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_flow_shaper_get(dev_id, flow_id, shaper); + return rv; +} +#endif +sw_error_t +_fal_queue_shaper_set(a_uint32_t dev_id,a_uint32_t queue_id, + fal_shaper_config_t * shaper) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_queue_shaper_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_queue_shaper_set(dev_id, queue_id, shaper); + return rv; +} +sw_error_t +_fal_queue_shaper_timeslot_set(a_uint32_t dev_id, a_uint32_t timeslot) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_queue_shaper_time_slot_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_queue_shaper_time_slot_set(dev_id, timeslot); + return rv; +} + +sw_error_t +_fal_shaper_ipg_preamble_length_set(a_uint32_t dev_id, a_uint32_t ipg_pre_length) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_shaper_ipg_preamble_length_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_shaper_ipg_preamble_length_set(dev_id, ipg_pre_length); + return rv; +} + +#ifndef IN_SHAPER_MINI +sw_error_t +_fal_shaper_ipg_preamble_length_get(a_uint32_t dev_id, a_uint32_t *ipg_pre_length) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_shaper_ipg_preamble_length_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_shaper_ipg_preamble_length_get(dev_id, ipg_pre_length); + return rv; +} +#endif + +/*insert flag for inner fal, don't remove it*/ + +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_flow_shaper_set(dev_id, flow_id, shaper); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_queue_shaper_get(dev_id, queue_id, shaper); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_queue_shaper_token_number_set(dev_id, queue_id, token_number); + FAL_API_UNLOCK; + return rv; +} +#ifndef IN_SHAPER_MINI +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_shaper_get(dev_id, port_id, shaper); + FAL_API_UNLOCK; + return rv; +} +sw_error_t +fal_flow_shaper_timeslot_get(a_uint32_t dev_id, a_uint32_t *timeslot) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _fal_flow_shaper_timeslot_get(dev_id, timeslot); + FAL_API_UNLOCK; + return rv; +} +sw_error_t +fal_port_shaper_timeslot_get(a_uint32_t dev_id, a_uint32_t *timeslot) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_shaper_timeslot_get(dev_id, timeslot); + FAL_API_UNLOCK; + return rv; +} +#endif +sw_error_t +fal_flow_shaper_timeslot_set(a_uint32_t dev_id, a_uint32_t timeslot) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _fal_flow_shaper_timeslot_set(dev_id, timeslot); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_shaper_token_number_set(dev_id, port_id, token_number); + FAL_API_UNLOCK; + return rv; +} +#ifndef IN_SHAPER_MINI +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_queue_shaper_token_number_get(dev_id, queue_id, token_number); + FAL_API_UNLOCK; + return rv; +} +sw_error_t +fal_queue_shaper_timeslot_get(a_uint32_t dev_id, a_uint32_t *timeslot) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _fal_queue_shaper_timeslot_get(dev_id, timeslot); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_shaper_token_number_get(dev_id, port_id, token_number); + FAL_API_UNLOCK; + return rv; +} +#endif +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_flow_shaper_token_number_set(dev_id, flow_id, token_number); + FAL_API_UNLOCK; + return rv; +} +#ifndef IN_SHAPER_MINI +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_flow_shaper_token_number_get(dev_id, flow_id, token_number); + FAL_API_UNLOCK; + return rv; +} +#endif +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_shaper_set(dev_id, port_id, shaper); + FAL_API_UNLOCK; + return rv; +} +sw_error_t +fal_port_shaper_timeslot_set(a_uint32_t dev_id, a_uint32_t timeslot) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_shaper_timeslot_set(dev_id, timeslot); + FAL_API_UNLOCK; + return rv; +} +#ifndef IN_SHAPER_MINI +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_flow_shaper_get(dev_id, flow_id, shaper); + FAL_API_UNLOCK; + return rv; +} +#endif +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_queue_shaper_set(dev_id, queue_id, shaper); + FAL_API_UNLOCK; + return rv; +} +sw_error_t +fal_queue_shaper_timeslot_set(a_uint32_t dev_id, a_uint32_t timeslot) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _fal_queue_shaper_timeslot_set(dev_id, timeslot); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_shaper_ipg_preamble_length_set(dev_id, ipg_pre_length); + FAL_API_UNLOCK; + return rv; +} +#ifndef IN_SHAPER_MINI +sw_error_t +fal_shaper_ipg_preamble_length_get(a_uint32_t dev_id, a_uint32_t *ipg_pre_length) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _fal_shaper_ipg_preamble_length_get(dev_id, ipg_pre_length); + FAL_API_UNLOCK; + return rv; +} +#endif + +EXPORT_SYMBOL(fal_flow_shaper_token_number_set); + +EXPORT_SYMBOL(fal_queue_shaper_token_number_set); + +EXPORT_SYMBOL(fal_port_shaper_token_number_set); + +EXPORT_SYMBOL(fal_port_shaper_timeslot_set); + +EXPORT_SYMBOL(fal_flow_shaper_timeslot_set); + +EXPORT_SYMBOL(fal_queue_shaper_timeslot_set); + +EXPORT_SYMBOL(fal_shaper_ipg_preamble_length_set); + +EXPORT_SYMBOL(fal_port_shaper_set); + +EXPORT_SYMBOL(fal_queue_shaper_get); + +EXPORT_SYMBOL(fal_queue_shaper_set); + +EXPORT_SYMBOL(fal_flow_shaper_set); + +#ifndef IN_SHAPER_MINI + +EXPORT_SYMBOL(fal_port_shaper_get); + +EXPORT_SYMBOL(fal_flow_shaper_get); + +EXPORT_SYMBOL(fal_queue_shaper_token_number_get); + +EXPORT_SYMBOL(fal_flow_shaper_token_number_get); + +EXPORT_SYMBOL(fal_port_shaper_token_number_get); + +EXPORT_SYMBOL(fal_port_shaper_timeslot_get); + +EXPORT_SYMBOL(fal_queue_shaper_timeslot_get); + +EXPORT_SYMBOL(fal_flow_shaper_timeslot_get); + +EXPORT_SYMBOL(fal_shaper_ipg_preamble_length_get); +#endif + +/*insert flag for outter fal, don't remove it*/ diff --git a/feeds/ipq807x/qca-ssdk/src/src/fal/fal_stp.c b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_stp.c new file mode 100755 index 000000000..882112016 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_stp.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2012, 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_STP + * @{ + */ +#include "sw.h" +#include "fal_stp.h" +#include "hsl_api.h" +#include "adpt.h" + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_stp_port_state_set) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_stp_port_state_set(dev_id, st_id, port_id, state); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->stp_port_state_set) + return SW_NOT_SUPPORTED; + + rv = p_api->stp_port_state_set(dev_id, st_id, port_id, state); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_stp_port_state_get) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_stp_port_state_get(dev_id, st_id, port_id, state); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->stp_port_state_get) + return SW_NOT_SUPPORTED; + + rv = p_api->stp_port_state_get(dev_id, st_id, port_id, state); + return rv; +} + +/*insert flag for inner fal, don't remove it*/ + +/** + * @brief Set port stp state on a particular spanning tree and port. + * @details Comments: + * For those devices which only support single spanning tree st_id should + * be FAL_SINGLE_STP_ID that is zero. + * @param[in] dev_id device id + * @param[in] st_id spanning tree id + * @param[in] port_id port id + * @param[in] state port state for spanning tree + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_stp_port_state_set(dev_id, st_id, port_id, state); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get port stp state on a particular spanning tree and port. + * @details Comments: + * For those devices which only support single spanning tree st_id should + * be FAL_SINGLE_STP_ID that is zero. + * @param[in] dev_id device id + * @param[in] st_id spanning tree id + * @param[in] port_id port id + * @param[out] state port state for spanning tree + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_stp_port_state_get(dev_id, st_id, port_id, state); + FAL_API_UNLOCK; + return rv; +} + +/*insert flag for outter fal, don't remove it*/ + +EXPORT_SYMBOL(fal_stp_port_state_set); +EXPORT_SYMBOL(fal_stp_port_state_get); + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/fal/fal_trunk.c b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_trunk.c new file mode 100755 index 000000000..b66909658 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_trunk.c @@ -0,0 +1,324 @@ +/* + * Copyright (c) 2012, 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_trunk FAL_TRUNK + * @{ + */ +#include "sw.h" +#include "fal_trunk.h" +#include "hsl_api.h" +#include "adpt.h" + +#include +#include + + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_trunk_group_set) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_trunk_group_set(dev_id, trunk_id, enable, member); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->trunk_group_set) + return SW_NOT_SUPPORTED; + + rv = p_api->trunk_group_set(dev_id, trunk_id, enable, member); + return rv; +} + +static 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; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_trunk_group_get) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_trunk_group_get(dev_id, trunk_id, enable, member); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->trunk_group_get) + return SW_NOT_SUPPORTED; + + rv = p_api->trunk_group_get(dev_id, trunk_id, enable, member); + return rv; +} + +static sw_error_t +_fal_trunk_hash_mode_set(a_uint32_t dev_id, a_uint32_t hash_mode) +{ + sw_error_t rv; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_trunk_hash_mode_set) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_trunk_hash_mode_set(dev_id, hash_mode); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->trunk_hash_mode_set) + return SW_NOT_SUPPORTED; + + rv = p_api->trunk_hash_mode_set(dev_id, hash_mode); + return rv; +} + +static sw_error_t +_fal_trunk_hash_mode_get(a_uint32_t dev_id, a_uint32_t * hash_mode) +{ + sw_error_t rv; + hsl_api_t *p_api; + adpt_api_t *p_adpt_api; + + if((p_adpt_api = adpt_api_ptr_get(dev_id)) != NULL) { + if (NULL == p_adpt_api->adpt_trunk_hash_mode_get) + return SW_NOT_SUPPORTED; + + rv = p_adpt_api->adpt_trunk_hash_mode_get(dev_id, hash_mode); + return rv; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->trunk_hash_mode_get) + return SW_NOT_SUPPORTED; + + rv = p_api->trunk_hash_mode_get(dev_id, hash_mode); + return rv; +} + +static sw_error_t +_fal_trunk_manipulate_sa_set(a_uint32_t dev_id, fal_mac_addr_t * addr) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->trunk_manipulate_sa_set) + return SW_NOT_SUPPORTED; + + rv = p_api->trunk_manipulate_sa_set(dev_id, addr); + return rv; +} + +static sw_error_t +_fal_trunk_manipulate_sa_get(a_uint32_t dev_id, fal_mac_addr_t * addr) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->trunk_manipulate_sa_get) + return SW_NOT_SUPPORTED; + + rv = p_api->trunk_manipulate_sa_get(dev_id, addr); + return rv; +} +sw_error_t +_fal_trunk_failover_status_get(a_uint32_t dev_id, a_bool_t * failover) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_trunk_fail_over_en_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_trunk_fail_over_en_get(dev_id, failover); + return rv; +} +sw_error_t +_fal_trunk_failover_enable(a_uint32_t dev_id, a_bool_t failover) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_trunk_fail_over_en_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_trunk_fail_over_en_set(dev_id, failover); + return rv; +} + +/*insert flag for inner fal, don't remove it*/ +/** + * @brief Set particular trunk group information on particular device. + * @param[in] dev_id device id + * @param[in] trunk_id trunk group id + * @param[in] enable trunk group status, enable or disable + * @param[in] member port member information + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_trunk_group_set(dev_id, trunk_id, enable, member); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get particular trunk group information on particular device. + * @param[in] dev_id device id + * @param[in] trunk_id trunk group id + * @param[out] enable trunk group status, enable or disable + * @param[out] member port member information + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_trunk_group_get(dev_id, trunk_id, enable, member); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set trunk hash mode on particular device. + * @param[in] dev_id device id + * @param[in] hash_mode trunk hash mode + * @return SW_OK or error code + */ +sw_error_t +fal_trunk_hash_mode_set(a_uint32_t dev_id, a_uint32_t hash_mode) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_trunk_hash_mode_set(dev_id, hash_mode); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get trunk hash mode on particular device. + * @param[in] dev_id device id + * @param[out] hash_mode trunk hash mode + * @return SW_OK or error code + */ +sw_error_t +fal_trunk_hash_mode_get(a_uint32_t dev_id, a_uint32_t * hash_mode) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_trunk_hash_mode_get(dev_id, hash_mode); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set trunk manipulate SA on particular device. + * @param[in] dev_id device id + * @param[in] addr manipulate SA + * @return SW_OK or error code + */ +sw_error_t +fal_trunk_manipulate_sa_set(a_uint32_t dev_id, fal_mac_addr_t * addr) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_trunk_manipulate_sa_set(dev_id, addr); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get trunk manipulate SA on particular device. + * @param[in] dev_id device id + * @param[out] addr manipulate SA + * @return SW_OK or error code + */ +sw_error_t +fal_trunk_manipulate_sa_get(a_uint32_t dev_id, fal_mac_addr_t * addr) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_trunk_manipulate_sa_get(dev_id, addr); + FAL_API_UNLOCK; + return rv; +} +sw_error_t +fal_trunk_failover_status_get(a_uint32_t dev_id, a_bool_t * failover) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _fal_trunk_failover_status_get(dev_id, failover); + FAL_API_UNLOCK; + return rv; +} +sw_error_t +fal_trunk_failover_enable(a_uint32_t dev_id, a_bool_t failover) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _fal_trunk_failover_enable(dev_id, failover); + FAL_API_UNLOCK; + return rv; +} +/*insert flag for outter fal, don't remove it*/ + +EXPORT_SYMBOL(fal_trunk_group_set); +EXPORT_SYMBOL(fal_trunk_group_get); +EXPORT_SYMBOL(fal_trunk_hash_mode_set); +EXPORT_SYMBOL(fal_trunk_hash_mode_get); +EXPORT_SYMBOL(fal_trunk_failover_status_get); +EXPORT_SYMBOL(fal_trunk_failover_enable); + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/fal/fal_vlan.c b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_vlan.c new file mode 100755 index 000000000..b5c37fb46 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_vlan.c @@ -0,0 +1,933 @@ +/* + * Copyright (c) 2012, 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. + */ + + + +/** + * @defgroup fal_vlan FAL_VLAN + * @{ + */ + +#include "sw.h" +#include "util.h" +#include "fal_vlan.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_api.h" + +typedef struct +{ + a_uint32_t idx; + fal_vlan_t entry; +} v_array_t; + +static v_array_t * vlan_db[SW_MAX_NR_DEV] = { 0 }; +static sid_pool_t * vlan_pool[SW_MAX_NR_DEV] = { 0 }; +static sll_head_t * vlan_list[SW_MAX_NR_DEV] = { 0 }; + + +static sw_error_t +_fal_vlan_search(a_uint32_t dev_id, fal_vlan_t * vlan_entry) +{ + a_ulong_t iterator; + v_array_t v_tbl; + v_array_t * p_tbl; + hsl_dev_t * p_dev = NULL; + + p_dev = hsl_dev_ptr_get(dev_id); + SW_RTN_ON_NULL(p_dev); + + if (A_TRUE == p_dev->hw_vlan_query) + { + return SW_NOT_FOUND; + } + + v_tbl.entry = * vlan_entry; + p_tbl = sll_nd_find(vlan_list[dev_id], &v_tbl, &iterator); + + if (NULL == p_tbl) + { + return SW_NOT_FOUND; + } + else + { + * vlan_entry = p_tbl->entry; + return SW_OK; + } +} + +static sw_error_t +_fal_vlan_following(a_uint32_t dev_id, fal_vlan_t * vlan_entry) +{ + a_ulong_t iterator = 0; + v_array_t v_tbl; + v_array_t * p_tbl; + hsl_dev_t * p_dev = NULL; + + p_dev = hsl_dev_ptr_get(dev_id); + SW_RTN_ON_NULL(p_dev); + + if (A_TRUE == p_dev->hw_vlan_query) + { + return SW_OK; + } + + sll_lock(vlan_list[dev_id]); + + v_tbl.entry = *vlan_entry; + + if (0 == v_tbl.entry.vid) + { + p_tbl = sll_nd_next(vlan_list[dev_id], &iterator); + } + else + { + p_tbl = sll_nd_find(vlan_list[dev_id], &v_tbl, &iterator); + if (NULL == p_tbl) + { + sll_unlock(vlan_list[dev_id]); + return SW_NO_MORE; + } + + p_tbl = sll_nd_next(vlan_list[dev_id], &iterator); + } + + if (NULL == p_tbl) + { + sll_unlock(vlan_list[dev_id]); + return SW_NO_MORE; + } + + * vlan_entry = p_tbl->entry; + sll_unlock(vlan_list[dev_id]); + return SW_OK; +} + +static sw_error_t +_fal_vlan_del(a_uint32_t dev_id, a_uint16_t vlan_id) +{ + v_array_t * p_tbl; + v_array_t ent; + sw_error_t rv; + a_ulong_t iterator; + a_uint32_t id; + hsl_dev_t * p_dev = NULL; + + p_dev = hsl_dev_ptr_get(dev_id); + SW_RTN_ON_NULL(p_dev); + + if (A_TRUE == p_dev->hw_vlan_query) + { + return SW_OK; + } + + ent.entry.vid = vlan_id; + p_tbl = sll_nd_find(vlan_list[dev_id], &ent, &iterator); + if (NULL == p_tbl) + { + return SW_NOT_FOUND; + } + id = p_tbl->idx; + + rv = sll_nd_delete(vlan_list[dev_id], p_tbl); + SW_RTN_ON_ERROR(rv); + + rv = sid_pool_id_free(vlan_pool[dev_id], id); + return rv; +} + +static sw_error_t +_fal_vlan_creat(a_uint32_t dev_id, const fal_vlan_t * vlan_entry) +{ + v_array_t * v_tbl; + sw_error_t rv; + a_uint32_t id; + hsl_dev_t * p_dev = NULL; + + p_dev = hsl_dev_ptr_get(dev_id); + SW_RTN_ON_NULL(p_dev); + + if (A_TRUE == p_dev->hw_vlan_query) + { + return SW_OK; + } + + rv = sid_pool_id_alloc(vlan_pool[dev_id], &id); + SW_RTN_ON_ERROR(rv); + + v_tbl = &vlan_db[dev_id][id]; + v_tbl->idx = id; + v_tbl->entry = *vlan_entry; + rv = sll_nd_insert(vlan_list[dev_id], v_tbl); + return rv; +} + +static sw_error_t +_fal_vlan_update(a_uint32_t dev_id, const fal_vlan_t * vlan_entry) +{ + a_ulong_t iterator; + v_array_t v_tbl; + v_array_t * p_tbl; + hsl_dev_t * p_dev = NULL; + + p_dev = hsl_dev_ptr_get(dev_id); + SW_RTN_ON_NULL(p_dev); + + if (A_TRUE == p_dev->hw_vlan_query) + { + return SW_OK; + } + + sll_lock(vlan_list[dev_id]); + v_tbl.entry = *vlan_entry; + p_tbl = sll_nd_find(vlan_list[dev_id], &v_tbl, &iterator); + + if (NULL == p_tbl) + { + sll_unlock(vlan_list[dev_id]); + return SW_NOT_FOUND; + } + + p_tbl->entry = * vlan_entry; + sll_unlock(vlan_list[dev_id]); + return SW_OK; +} + +static ll_cmp_rslt_t +_fal_vlan_entry_cmp(void * src, void * dest) +{ + v_array_t * src_nd, * dest_nd; + + src_nd = (v_array_t*)src; + dest_nd = (v_array_t*)dest; + + if (src_nd->entry.vid == dest_nd->entry.vid) + { + return LL_CMP_EQUAL; + } + else if (src_nd->entry.vid > dest_nd->entry.vid) + { + return LL_CMP_GREATER; + } + else + { + return LL_CMP_SMALLER; + } +} + +static void +_fal_vlan_entry_dump(void * data) +{ + v_array_t * nd; + + nd = (v_array_t*)data; + aos_printk("vid = %d member = 0x%x\n", nd->entry.vid, nd->entry.mem_ports); +} + + +static sw_error_t +_fal_vlan_entry_append(a_uint32_t dev_id, fal_vlan_t * vlan_entry) +{ + sw_error_t rv; + hsl_api_t *p_api; + + rv = _fal_vlan_search(dev_id, vlan_entry); + if (SW_OK == rv) + { + return SW_ALREADY_EXIST; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + if (NULL == p_api->vlan_entry_append) + return SW_NOT_SUPPORTED; + + rv = p_api->vlan_entry_append(dev_id, vlan_entry); + SW_RTN_ON_ERROR(rv); + + rv = _fal_vlan_creat(dev_id, vlan_entry); + return rv; +} + + +static sw_error_t +_fal_vlan_create(a_uint32_t dev_id, a_uint32_t vlan_id) +{ + sw_error_t rv; + fal_vlan_t entry; + hsl_api_t *p_api; + + aos_mem_zero(&(entry), sizeof(fal_vlan_t)); + entry.vid = vlan_id; + rv = _fal_vlan_search(dev_id, &entry); + if (SW_OK == rv) + { + return SW_ALREADY_EXIST; + } + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + if (NULL == p_api->vlan_creat) + return SW_NOT_SUPPORTED; + + rv = p_api->vlan_creat(dev_id, vlan_id); + SW_RTN_ON_ERROR(rv); + + rv = _fal_vlan_creat(dev_id, &entry); + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->vlan_next) + { + p_vlan->vid = vlan_id; + rv = _fal_vlan_following(dev_id, p_vlan); + } + else + { + rv = p_api->vlan_next(dev_id, vlan_id, p_vlan); + } + return rv; +} + + +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->vlan_find) + { + p_vlan->vid = vlan_id; + rv = _fal_vlan_search(dev_id, p_vlan); + } + else + { + rv = p_api->vlan_find(dev_id, vlan_id, p_vlan); + } + return rv; +} + + +static 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; + fal_vlan_t vlan_entry = {0}; + hsl_api_t *p_api; + hsl_dev_t *p_dev = NULL; + + p_dev = hsl_dev_ptr_get(dev_id); + SW_RTN_ON_NULL(p_dev); + + if (A_FALSE == p_dev->hw_vlan_query) + { + vlan_entry.vid = vlan_id; + rv = _fal_vlan_search(dev_id, &vlan_entry); + SW_RTN_ON_ERROR(rv); + } + + vlan_entry.mem_ports = member; + vlan_entry.u_ports = u_member; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + if (NULL == p_api->vlan_member_update) + { + if ((NULL == p_api->vlan_entry_append) + || (NULL == p_api->vlan_delete)) + { + return SW_NOT_SUPPORTED; + } + + p_api->vlan_delete(dev_id, vlan_id); + + vlan_entry.vid = vlan_id; + vlan_entry.fid = vlan_id; + + vlan_entry.untagged_ports = u_member; + vlan_entry.tagged_ports = member & ~u_member; + + rv = p_api->vlan_entry_append(dev_id, &vlan_entry); + SW_RTN_ON_ERROR(rv); + } + else + { + + rv = p_api->vlan_member_update(dev_id, vlan_id, member, u_member); + SW_RTN_ON_ERROR(rv); + } + rv = _fal_vlan_update(dev_id, &vlan_entry); + return rv; +} + + +static sw_error_t +_fal_vlan_delete(a_uint32_t dev_id, a_uint32_t vlan_id) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->vlan_delete) + return SW_NOT_SUPPORTED; + + rv = p_api->vlan_delete(dev_id, vlan_id); + SW_RTN_ON_ERROR(rv); + + rv = _fal_vlan_del(dev_id, vlan_id); + return rv; +} + +static sw_error_t +_fal_vlan_flush(a_uint32_t dev_id) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->vlan_flush) + return SW_NOT_SUPPORTED; + + rv = p_api->vlan_flush(dev_id); + SW_RTN_ON_ERROR(rv); + + rv = fal_vlan_reset(dev_id); + return rv; +} + +/** + * @brief Set FID of a paticular vlan entry on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[in] fid FDB id + * @return SW_OK or error code + */ +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->vlan_fid_set) + return SW_NOT_SUPPORTED; + + rv = p_api->vlan_fid_set(dev_id, vlan_id, fid); + return rv; +} + +/** + * @brief Get FID of a paticular vlan entry on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[out] fid FDB id + * @return SW_OK or error code + */ +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->vlan_fid_get) + return SW_NOT_SUPPORTED; + + rv = p_api->vlan_fid_get(dev_id, vlan_id, fid); + return rv; +} + +/** + * @brief Add a port member to a paticular vlan entry on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[in] port_id port id + * @param[in] port_info port tag information + * @return SW_OK or error code + */ +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->vlan_member_add) + return SW_NOT_SUPPORTED; + + rv = p_api->vlan_member_add(dev_id, vlan_id, port_id, port_info); + return rv; +} + +/** + * @brief Del a port member from a paticular vlan entry on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[in] port_id port id + * @return SW_OK or error code + */ +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->vlan_member_del) + return SW_NOT_SUPPORTED; + + rv = p_api->vlan_member_del(dev_id, vlan_id, port_id); + return rv; +} + +/** + * @brief Set FDB learning status of a paticular vlan entry on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->vlan_learning_state_set) + return SW_NOT_SUPPORTED; + + rv = p_api->vlan_learning_state_set(dev_id, vlan_id, enable); + return rv; +} + +/** + * @brief Get FDB learning status of a paticular vlan entry on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +static 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; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + if (NULL == p_api->vlan_learning_state_get) + return SW_NOT_SUPPORTED; + + rv = p_api->vlan_learning_state_get(dev_id, vlan_id, enable); + return rv; +} + +/** + * @brief Reset fal vlan module on a paticular device. + * @param[in] dev_id device id + * @return SW_OK or error code + */ +sw_error_t +fal_vlan_reset(a_uint32_t dev_id) +{ + a_uint32_t entry_nr; + hsl_dev_t *p_dev = NULL; + + p_dev = hsl_dev_ptr_get(dev_id); + SW_RTN_ON_NULL(p_dev); + + if (A_TRUE == p_dev->hw_vlan_query) + { + return SW_OK; + } + + entry_nr = p_dev->nr_vlans; + if ((0 == entry_nr) || (4096 < entry_nr)) + { + return SW_FAIL; + } + + if (NULL != vlan_pool[dev_id]) + { + sid_pool_destroy(vlan_pool[dev_id]); + vlan_pool[dev_id] = NULL; + } + + if (NULL != vlan_list[dev_id]) + { + sll_destroy(vlan_list[dev_id]); + vlan_list[dev_id] = NULL; + } + + aos_mem_zero(vlan_db[dev_id], entry_nr * (sizeof (v_array_t))); + + vlan_pool[dev_id] = sid_pool_creat(entry_nr, 0); + if (NULL == vlan_pool[dev_id]) + { + return SW_FAIL; + } + + vlan_list[dev_id] = sll_creat(_fal_vlan_entry_cmp, _fal_vlan_entry_dump, + LL_FIX_NDNR | LL_IN_ORDER, entry_nr); + if (NULL == vlan_list[dev_id]) + { + return SW_FAIL; + } + + return SW_OK; +} + + +/** + * @brief Init fal vlan module on a paticular device. + * @param[in] dev_id device id + * @return SW_OK or error code + */ +sw_error_t +fal_vlan_init(a_uint32_t dev_id) +{ + a_uint32_t entry_nr; + hsl_dev_t *p_dev = NULL; + + p_dev = hsl_dev_ptr_get(dev_id); + SW_RTN_ON_NULL(p_dev); + + if (A_TRUE == p_dev->hw_vlan_query) + { + return SW_OK; + } + + entry_nr = p_dev->nr_vlans; + if ((0 == entry_nr) || (4096 < entry_nr)) + { + return SW_FAIL; + } + + vlan_pool[dev_id] = sid_pool_creat(entry_nr, 0); + if (NULL == vlan_pool[dev_id]) + { + return SW_FAIL; + } + + /* allocate memory for vlan entry */ + vlan_db[dev_id] = aos_mem_alloc(entry_nr * (sizeof (v_array_t))); + if (NULL == vlan_db[dev_id]) + { + return SW_OUT_OF_MEM; + } + aos_mem_zero(vlan_db[dev_id], entry_nr * (sizeof (v_array_t))); + + vlan_list[dev_id] = sll_creat(_fal_vlan_entry_cmp, _fal_vlan_entry_dump, + LL_FIX_NDNR | LL_IN_ORDER, entry_nr); + + if (NULL == vlan_list[dev_id]) + { + return SW_FAIL; + } + + return SW_OK; +} + +sw_error_t +fal_vlan_cleanup(void) +{ + a_uint32_t dev_id; + + for (dev_id = 0; dev_id < SW_MAX_NR_DEV; dev_id++) + { + if (vlan_db[dev_id]) + { + aos_mem_free(vlan_db[dev_id]); + vlan_db[dev_id] = NULL; + } + + if (vlan_pool[dev_id]) + { + sid_pool_destroy(vlan_pool[dev_id]); + vlan_pool[dev_id] = NULL; + } + + if (vlan_list[dev_id]) + { + sll_destroy(vlan_list[dev_id]); + vlan_list[dev_id] = NULL; + } + } + + return SW_OK; +} + +/** + * @brief Append a vlan entry on paticular device. + * @param[in] dev_id device id + * @param[in] vlan_entry vlan entry + * @return SW_OK or error code + */ +sw_error_t +fal_vlan_entry_append(a_uint32_t dev_id, fal_vlan_t * vlan_entry) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_vlan_entry_append(dev_id, vlan_entry); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Creat a vlan entry through vlan id on a paticular device. + * @details Comments: + * After this operation the member ports of the created vlan entry are null. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @return SW_OK or error code + */ +sw_error_t +fal_vlan_create(a_uint32_t dev_id, a_uint32_t vlan_id) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_vlan_create(dev_id, vlan_id); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Next a vlan entry through vlan id on a paticular device. + * @details Comments: + * If the value of vid is zero this operation will get the first entry. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[out] p_vlan vlan entry + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_vlan_next(dev_id, vlan_id, p_vlan); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Find a vlan entry through vlan id on paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[out] p_vlan vlan entry + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_vlan_find(dev_id, vlan_id, p_vlan); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Update a vlan entry member port through vlan id on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[in] member member ports + * @param[in] u_member tagged or untagged infomation for member ports + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_vlan_member_update(dev_id, vlan_id, member, u_member); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a vlan entry through vlan id on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @return SW_OK or error code + */ +sw_error_t +fal_vlan_delete(a_uint32_t dev_id, a_uint32_t vlan_id) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_vlan_delete(dev_id, vlan_id); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Flush all vlan entries on a paticular device. + * @param[in] dev_id device id + * @return SW_OK or error code + */ +sw_error_t +fal_vlan_flush(a_uint32_t dev_id) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _fal_vlan_flush(dev_id); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set FID of a paticular vlan entry on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[in] fid FDB id + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_vlan_fid_set(dev_id, vlan_id, fid); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get FID of a paticular vlan entry on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[out] fid FDB id + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_vlan_fid_get(dev_id, vlan_id, fid); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Add a port member to a paticular vlan entry on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[in] port_id port id + * @param[in] port_info port tag information + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_vlan_member_add(dev_id, vlan_id, port_id, port_info); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Del a port member from a paticular vlan entry on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[in] port_id port id + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_vlan_member_del(dev_id, vlan_id, port_id); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set FDB learning status of a paticular vlan entry on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_vlan_learning_state_set(dev_id, vlan_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get FDB learning status of a paticular vlan entry on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +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; + + FAL_API_LOCK; + rv = _fal_vlan_learning_state_get(dev_id, vlan_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/fal/fal_vsi.c b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_vsi.c new file mode 100755 index 000000000..a40acd5e7 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/fal/fal_vsi.c @@ -0,0 +1,343 @@ +/* + * 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 "fal_vsi.h" +#include "adpt.h" +#include "hsl_api.h" + +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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_vlan_vsi_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_vlan_vsi_set(dev_id, port_id, stag_vid, ctag_vid, vsi_id); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_vlan_vsi_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_vsi_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_vsi_set(dev_id, port_id, vsi_id); + return rv; +} +#ifndef IN_VSI_MINI +sw_error_t +_fal_port_vsi_get(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t *vsi_id) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_port_vsi_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_port_vsi_get(dev_id, port_id, vsi_id); + return rv; +} +#endif +sw_error_t +_fal_vsi_stamove_set(a_uint32_t dev_id, a_uint32_t vsi_id, fal_vsi_stamove_t *stamove) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_vsi_stamove_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_vsi_stamove_set(dev_id, vsi_id, stamove); + return rv; +} +#ifndef IN_VSI_MINI +sw_error_t +_fal_vsi_stamove_get(a_uint32_t dev_id, a_uint32_t vsi_id, fal_vsi_stamove_t *stamove) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_vsi_stamove_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_vsi_newaddr_lrn_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_vsi_newaddr_lrn_get(dev_id, vsi_id, newaddr_lrn); + return rv; +} +#endif +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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_vsi_newaddr_lrn_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_vsi_newaddr_lrn_set(dev_id, vsi_id, newaddr_lrn); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_vsi_member_set) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_vsi_member_set(dev_id, vsi_id, vsi_member); + 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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_vsi_member_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_vsi_member_get(dev_id, vsi_id, vsi_member); + return rv; +} + +#ifndef IN_VSI_MINI +sw_error_t +_fal_vsi_counter_get(a_uint32_t dev_id, a_uint32_t vsi_id, fal_vsi_counter_t *counter) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_vsi_counter_get) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_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) +{ + adpt_api_t *p_api; + sw_error_t rv = SW_OK; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + + if (NULL == p_api->adpt_vsi_counter_cleanup) + return SW_NOT_SUPPORTED; + + rv = p_api->adpt_vsi_counter_cleanup(dev_id, vsi_id); + return rv; +} +#endif + +/*insert flag for inner fal, don't remove it*/ + +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_vlan_vsi_set(dev_id, port_id, stag_vid, ctag_vid, vsi_id); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_vlan_vsi_get(dev_id, port_id, stag_vid, ctag_vid, vsi_id); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_vsi_set(dev_id, port_id, vsi_id); + FAL_API_UNLOCK; + return rv; +} +#ifndef IN_VSI_MINI +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_port_vsi_get(dev_id, port_id, vsi_id); + FAL_API_UNLOCK; + return rv; +} +#endif + +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_vsi_stamove_set(dev_id, vsi_id, stamove); + FAL_API_UNLOCK; + return rv; +} +#ifndef IN_VSI_MINI +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_vsi_stamove_get(dev_id, vsi_id, stamove); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_vsi_newaddr_lrn_get(dev_id, vsi_id, newaddr_lrn); + FAL_API_UNLOCK; + return rv; +} +#endif +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_vsi_newaddr_lrn_set(dev_id, vsi_id, newaddr_lrn); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_vsi_member_set(dev_id, vsi_id, vsi_member); + FAL_API_UNLOCK; + 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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_vsi_member_get(dev_id, vsi_id, vsi_member); + FAL_API_UNLOCK; + return rv; +} + +#ifndef IN_VSI_MINI +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 = SW_OK; + + FAL_API_LOCK; + rv = _fal_vsi_counter_get(dev_id, vsi_id, counter); + FAL_API_UNLOCK; + return rv; +} + +sw_error_t +fal_vsi_counter_cleanup(a_uint32_t dev_id, a_uint32_t vsi_id) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _fal_vsi_counter_cleanup(dev_id, vsi_id); + FAL_API_UNLOCK; + return rv; +} +#endif +/*insert flag for outter fal, don't remove it*/ + +#ifndef IN_VSI_MINI +EXPORT_SYMBOL(fal_port_vsi_get); +EXPORT_SYMBOL(fal_vsi_stamove_get); +EXPORT_SYMBOL(fal_vsi_newaddr_lrn_get); +EXPORT_SYMBOL(fal_vsi_counter_get); +EXPORT_SYMBOL(fal_vsi_counter_cleanup); +#endif +EXPORT_SYMBOL(fal_port_vlan_vsi_set); +EXPORT_SYMBOL(fal_port_vlan_vsi_get); +EXPORT_SYMBOL(fal_port_vsi_set); +EXPORT_SYMBOL(fal_vsi_stamove_set); +EXPORT_SYMBOL(fal_vsi_newaddr_lrn_set); +EXPORT_SYMBOL(fal_vsi_member_set); +EXPORT_SYMBOL(fal_vsi_member_get); diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/Makefile b/feeds/ipq807x/qca-ssdk/src/src/hsl/Makefile new file mode 100755 index 000000000..8fabf4c4d --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/Makefile @@ -0,0 +1,39 @@ +LOC_DIR=/src/hsl +LIB=HSL + +include $(PRJ_PATH)/make/config.mk + +SRC_LIST=hsl_dev.c hsl_port_prop.c hsl_api.c + +ifeq (TRUE, $(IN_ACL)) + ifeq (SHIVA, $(CHIP_TYPE)) + SRC_LIST += hsl_acl.c + endif + ifeq (GARUDA, $(CHIP_TYPE)) + SRC_LIST += hsl_acl.c + endif + ifeq (ALL_CHIP, $(CHIP_TYPE)) + SRC_LIST += hsl_acl.c + endif + ifeq (NONHK_CHIP, $(CHIP_TYPE)) + SRC_LIST += hsl_acl.c + endif +endif + +ifeq (linux, $(OS)) + ifeq (KSLIB, $(MODULE_TYPE)) + ifneq (TRUE, $(KERNEL_MODE)) + SRC_LIST=hsl_dev.c hsl_api.c + endif + endif +endif + +ifeq (TRUE, $(API_LOCK)) + SRC_LIST += hsl_lock.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/src/src/hsl/athena/Makefile b/feeds/ipq807x/qca-ssdk/src/src/hsl/athena/Makefile new file mode 100755 index 000000000..7cce5d220 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/athena/Makefile @@ -0,0 +1,44 @@ +LOC_DIR=src/hsl/athena +LIB=HSL + +include $(PRJ_PATH)/make/config.mk + +SRC_LIST=athena_reg_access.c athena_init.c + +ifeq (TRUE, $(IN_FDB)) + SRC_LIST += athena_fdb.c +endif + +ifeq (TRUE, $(IN_MIB)) + SRC_LIST += athena_mib.c +endif + +ifeq (TRUE, $(IN_PORTCONTROL)) + SRC_LIST += athena_port_ctrl.c +endif + +ifeq (TRUE, $(IN_PORTVLAN)) + SRC_LIST += athena_portvlan.c +endif + +ifeq (TRUE, $(IN_VLAN)) + SRC_LIST += athena_vlan.c +endif + +ifeq (linux, $(OS)) + ifeq (KSLIB, $(MODULE_TYPE)) + ifneq (TRUE, $(KERNEL_MODE)) + SRC_LIST=athena_reg_access.c athena_init.c + endif + endif +endif + +ifeq (, $(findstring ATHENA, $(SUPPORT_CHIP))) + SRC_LIST= +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/src/src/hsl/athena/athena_fdb.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/athena/athena_fdb.c new file mode 100755 index 000000000..5b0fc528e --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/athena/athena_fdb.c @@ -0,0 +1,639 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 athena_fdb ATHENA_FDB + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "athena_fdb.h" +#include "athena_reg.h" + +#define ARL_FLUSH_ALL 1 +#define ARL_LOAD_ENTRY 2 +#define ARL_PURGE_ENTRY 3 +#define ARL_FLUSH_ALL_UNLOCK 4 +#define ARL_FLUSH_PORT_UNICAST 5 +#define ARL_NEXT_ENTRY 6 + +#define ARL_FIRST_ENTRY 1001 + +static a_bool_t +athena_fdb_is_zeroaddr(fal_mac_addr_t addr) +{ + a_uint32_t i; + + for (i = 0; i < 6; i++) + { + if (addr.uc[i]) + { + return A_FALSE; + } + } + + return A_TRUE; +} + +static void +athena_fdb_fill_addr(fal_mac_addr_t addr, a_uint32_t * reg0, a_uint32_t * reg1) +{ + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_ADDR_BYTE0, addr.uc[0], *reg1); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_ADDR_BYTE1, addr.uc[1], *reg1); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_ADDR_BYTE2, addr.uc[2], *reg1); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_ADDR_BYTE3, addr.uc[3], *reg1); + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_ADDR_BYTE4, addr.uc[4], *reg0); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_ADDR_BYTE5, addr.uc[5], *reg0); + + return; +} + +static sw_error_t +athena_atu_sw_to_hw(a_uint32_t dev_id, const fal_fdb_entry_t * entry, + a_uint32_t reg[]) +{ + a_uint32_t port; + + if (A_FALSE == entry->portmap_en) + { + if (A_TRUE != + hsl_port_prop_check(dev_id, entry->port.id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + port = 0x1UL << entry->port.id; + } + else + { + if (A_FALSE == + hsl_mports_prop_check(dev_id, entry->port.map, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + port = entry->port.map; + } + + if (FAL_MAC_CPY_TO_CPU == entry->dacmd) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, COPY_TO_CPU, 1, reg[2]); + } + else if (FAL_MAC_RDT_TO_CPU == entry->dacmd) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, REDRCT_TO_CPU, 1, reg[2]); + } + else if (FAL_MAC_FRWRD != entry->dacmd) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_MAC_DROP == entry->sacmd) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, SA_DROP_EN, 1, reg[2]); + } + else if (FAL_MAC_FRWRD != entry->sacmd) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == entry->leaky_en) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == entry->static_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_STATUS, 1, reg[2]); + } + else + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_STATUS, 2, reg[2]); + } + + if (A_TRUE == entry->mirror_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, MIRROR_EN, 1, reg[2]); + } + + if (A_TRUE == entry->da_pri_en) + { + hsl_dev_t *p_dev; + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_PRI_EN, 1, reg[2]); + + SW_RTN_ON_NULL(p_dev = hsl_dev_ptr_get(dev_id)); + + if (entry->da_queue > (p_dev->nr_queue - 1)) + return SW_BAD_PARAM; + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_PRI, entry->da_queue, reg[2]); + } + + if (A_TRUE == entry->cross_pt_state) + { + return SW_NOT_SUPPORTED; + } + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, DES_PORT, port, reg[2]); + athena_fdb_fill_addr(entry->addr, ®[0], ®[1]); + + return SW_OK; +} + +static void +athena_atu_hw_to_sw(const a_uint32_t reg[], fal_fdb_entry_t * entry) +{ + a_uint32_t i, data; + + aos_mem_zero(entry, sizeof (fal_fdb_entry_t)); + + entry->dacmd = FAL_MAC_FRWRD; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, COPY_TO_CPU, data, reg[2]); + if (1 == data) + { + entry->dacmd = FAL_MAC_CPY_TO_CPU; + } + + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, REDRCT_TO_CPU, data, reg[2]); + if (1 == data) + { + entry->dacmd = FAL_MAC_RDT_TO_CPU; + } + + entry->sacmd = FAL_MAC_FRWRD; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, SA_DROP_EN, data, reg[2]); + if (1 == data) + { + entry->sacmd = FAL_MAC_DROP; + } + + entry->static_en = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, AT_STATUS, data, reg[2]); + if (1 == data) + { + entry->static_en = A_TRUE; + } + + entry->mirror_en = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, MIRROR_EN, data, reg[2]); + if (1 == data) + { + entry->mirror_en = A_TRUE; + } + + entry->da_pri_en = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, AT_PRI_EN, data, reg[2]); + if (1 == data) + { + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, AT_PRI, data, reg[2]); + entry->da_pri_en = A_TRUE; + entry->da_queue = data & 0x3; + } + + entry->cross_pt_state = A_FALSE; + + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, DES_PORT, data, reg[2]); + + entry->portmap_en = A_TRUE; + entry->port.map = data; + + for (i = 0; i < 4; i++) + { + entry->addr.uc[i] = (reg[1] >> ((3 - i) << 3)) & 0xff; + } + + for (i = 4; i < 6; i++) + { + entry->addr.uc[i] = (reg[0] >> ((7 - i) << 3)) & 0xff; + } + + return; +} + +static sw_error_t +athena_fdb_commit(a_uint32_t dev_id, a_uint32_t op) +{ + sw_error_t rv; + a_uint32_t busy = 1; + a_uint32_t full_vio; + a_uint32_t i = 1000; + a_uint32_t entry; + + while (busy && --i) + { + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_FUNC0, 0, AT_BUSY, + (a_uint8_t *) (&busy), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + aos_udelay(5); + } + + if (0 == i) + { + return SW_BUSY; + } + + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC0, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_BUSY, 1, entry); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_FUNC, op, entry); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC0, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + busy = 1; + i = 1000; + while (busy && --i) + { + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_FUNC0, 0, AT_BUSY, + (a_uint8_t *) (&busy), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + aos_udelay(5); + } + + if (0 == i) + { + return SW_FAIL; + } + + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_FUNC0, 0, AT_FULL_VIO, + (a_uint8_t *) (&full_vio), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (full_vio) + { + if (ARL_LOAD_ENTRY == op) + { + return SW_FULL; + } + else if ((ARL_PURGE_ENTRY == op) + || (ARL_FLUSH_PORT_UNICAST == op)) + { + return SW_NOT_FOUND; + } + else + { + return SW_FAIL; + } + } + + return SW_OK; +} + +static sw_error_t +athena_atu_get(a_uint32_t dev_id, fal_fdb_entry_t * entry, a_uint32_t op) +{ + sw_error_t rv; + a_uint32_t reg[3] = { 0 }; + a_uint32_t destport = 0; + a_uint32_t hwop = op; + + if (ARL_NEXT_ENTRY == op) + { + athena_fdb_fill_addr(entry->addr, ®[0], ®[1]); + } + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* set destport not zero */ + if (ARL_NEXT_ENTRY == op) + { + reg[2] = 0xf; + } + + if (ARL_FIRST_ENTRY == op) + { + hwop = ARL_NEXT_ENTRY; + } + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC2, 0, + (a_uint8_t *) (®[2]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = athena_fdb_commit(dev_id, hwop); + SW_RTN_ON_ERROR(rv); + + /* get hardware enrety */ + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC2, 0, + (a_uint8_t *) (®[2]), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, DES_PORT, destport, reg[2]); + + athena_atu_hw_to_sw(reg, entry); + + /* If hardware return back with address and status all zero, + that means no other next valid entry in fdb table */ + if ((A_TRUE == athena_fdb_is_zeroaddr(entry->addr)) + && (0 == destport) + && (ARL_NEXT_ENTRY == hwop)) + { + return SW_NO_MORE; + } + else + { + return SW_OK; + } +} + +static sw_error_t +_athena_fdb_add(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t reg[3] = { 0, 0, 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + if ((A_TRUE == athena_fdb_is_zeroaddr(entry->addr)) + && (0 == entry->port.map) + && (0 == entry->port.id)) + { + return SW_BAD_PARAM; + } + + rv = athena_atu_sw_to_hw(dev_id, entry, reg); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC2, 0, + (a_uint8_t *) (®[2]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC1, 0, (a_uint8_t *) (®[1]), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC0, 0, (a_uint8_t *) (®[0]), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = athena_fdb_commit(dev_id, ARL_LOAD_ENTRY); + return rv; +} + +static sw_error_t +_athena_fdb_del_all(a_uint32_t dev_id, a_uint32_t flag) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_FDB_DEL_STATIC & flag) + { + rv = athena_fdb_commit(dev_id, ARL_FLUSH_ALL); + } + else + { + rv = athena_fdb_commit(dev_id, ARL_FLUSH_ALL_UNLOCK); + } + + return rv; +} + +static sw_error_t +_athena_fdb_del_by_port(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t flag) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_PORT_NUM, port_id, reg); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC0, 0, (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_FDB_DEL_STATIC & flag) + { + rv = athena_fdb_commit(dev_id, ARL_FLUSH_PORT_UNICAST); + } + else + { + return SW_NOT_SUPPORTED; + } + + return rv; +} + +static sw_error_t +_athena_fdb_del_by_mac(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t reg0 = 0, reg1 = 0; + + HSL_DEV_ID_CHECK(dev_id); + + athena_fdb_fill_addr(entry->addr, ®0, ®1); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC1, 0, (a_uint8_t *) (®1), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC0, 0, (a_uint8_t *) (®0), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = athena_fdb_commit(dev_id, ARL_PURGE_ENTRY); + return rv; +} + +static sw_error_t +_athena_fdb_first(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + rv = athena_atu_get(dev_id, entry, ARL_FIRST_ENTRY); + return rv; +} + +static sw_error_t +_athena_fdb_next(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + rv = athena_atu_get(dev_id, entry, ARL_NEXT_ENTRY); + return rv; +} + +/** + * @brief Add a Fdb entry + * @param[in] dev_id device id + * @param[in] entry fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_fdb_add(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_fdb_add(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete all Fdb entries + * @details Comments: + * If set FAL_FDB_DEL_STATIC bit in flag which means delete all fdb + * entries otherwise only delete dynamic entries. + * @param[in] dev_id device id + * @param[in] flag delete operation option + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_fdb_del_all(a_uint32_t dev_id, a_uint32_t flag) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_fdb_del_all(dev_id, flag); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete Fdb entries on a particular port + * @details Comments: + * Athena doesn't support flag option, flag should be setted as zero. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] flag delete operation option + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_fdb_del_by_port(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t flag) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_fdb_del_by_port(dev_id, port_id, flag); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a particular Fdb entry through mac address + * @details Comments: + * Only addr field in entry is meaning. For IVL learning vid or fid field + * also is meaning. + * @param[in] dev_id device id + * @param[in] entry fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_fdb_del_by_mac(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_fdb_del_by_mac(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get first Fdb entry from particular device + * @param[in] dev_id device id + * @param[out] entry fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_fdb_first(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_fdb_first(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get next Fdb entry from particular device + * @details Comments: + * For input parameter only addr field in entry is meaning. + * @param[in] dev_id device id + * @param entry fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_fdb_next(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_fdb_next(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +athena_fdb_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + hsl_api_t *p_api; + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get(dev_id)); + + p_api->fdb_add = athena_fdb_add; + p_api->fdb_del_all = athena_fdb_del_all; + p_api->fdb_del_by_port = athena_fdb_del_by_port; + p_api->fdb_del_by_mac = athena_fdb_del_by_mac; + p_api->fdb_first = athena_fdb_first; + p_api->fdb_next = athena_fdb_next; +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/athena/athena_init.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/athena/athena_init.c new file mode 100755 index 000000000..9e7c84d08 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/athena/athena_init.c @@ -0,0 +1,290 @@ +/* + * Copyright (c) 2012, 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 athena_init ATHENA_INIT + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "athena_mib.h" +#include "athena_port_ctrl.h" +#include "athena_portvlan.h" +#include "athena_vlan.h" +#include "athena_fdb.h" +#include "athena_reg_access.h" +#include "athena_reg.h" +#include "athena_init.h" + +static ssdk_init_cfg * athena_cfg[SW_MAX_NR_DEV] = { 0 }; + +#if !(defined(KERNEL_MODULE) && defined(USER_MODE)) +static sw_error_t +athena_portproperty_init(a_uint32_t dev_id, hsl_init_mode mode) +{ + hsl_port_prop_t p_type; + hsl_dev_t *pdev = NULL; + fal_port_t port_id; + + pdev = hsl_dev_ptr_get(dev_id); + if (pdev == NULL) + return SW_NOT_INITIALIZED; + + for (port_id = 0; port_id < pdev->nr_ports; port_id++) + { + hsl_port_prop_portmap_set(dev_id, port_id); + + for (p_type = HSL_PP_PHY; p_type < HSL_PP_BUTT; p_type++) + { + if (HSL_NO_CPU == mode) + { + SW_RTN_ON_ERROR(hsl_port_prop_set(dev_id, port_id, p_type)); + continue; + } + + switch (p_type) + { + case HSL_PP_PHY: + if (HSL_CPU_1_PLUS == mode) + { + if ((port_id != pdev->cpu_port_nr) + && (port_id != (pdev->nr_ports -1))) + { + SW_RTN_ON_ERROR(hsl_port_prop_set(dev_id, port_id, p_type)); + } + } + else + { + if (port_id != pdev->cpu_port_nr) + { + SW_RTN_ON_ERROR(hsl_port_prop_set(dev_id, port_id, p_type)); + } + } + break; + + case HSL_PP_INCL_CPU: + /* include cpu port but exclude wan port in some cases */ + if (!((HSL_CPU_2 == mode) && (port_id == (pdev->nr_ports - 1)))) + SW_RTN_ON_ERROR(hsl_port_prop_set(dev_id, port_id, p_type)); + + break; + + case HSL_PP_EXCL_CPU: + /* exclude cpu port and wan port in some cases */ + if ((port_id != pdev->cpu_port_nr) + && (!((HSL_CPU_2 == mode) && (port_id == (pdev->nr_ports - 1))))) + SW_RTN_ON_ERROR(hsl_port_prop_set(dev_id, port_id, p_type)); + break; + + default: + break; + } + } + + if (HSL_NO_CPU == mode) + { + SW_RTN_ON_ERROR(hsl_port_prop_set_phyid + (dev_id, port_id, port_id + 1)); + } + else + { + if (port_id != pdev->cpu_port_nr) + { + SW_RTN_ON_ERROR(hsl_port_prop_set_phyid + (dev_id, port_id, port_id - 1)); + } + } + } + + return SW_OK; +} + +static sw_error_t +athena_hw_init(a_uint32_t dev_id) +{ + hsl_dev_t *pdev = NULL; + a_uint32_t port_id, data; + sw_error_t rv; + + pdev = hsl_dev_ptr_get(dev_id); + if (NULL == pdev) + { + return SW_NOT_INITIALIZED; + } + + for (port_id = 0; port_id < pdev->nr_ports; port_id++) + { + if (port_id == pdev->cpu_port_nr) + { + continue; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 1, data); + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + + +#endif + +static sw_error_t +athena_dev_init(a_uint32_t dev_id) +{ + hsl_dev_t *pdev = NULL; + + pdev = hsl_dev_ptr_get(dev_id); + if (pdev == NULL) + return SW_NOT_INITIALIZED; + + pdev->nr_ports = 6; + pdev->nr_phy = 5; + pdev->cpu_port_nr = 0; + pdev->nr_vlans = 16; + pdev->hw_vlan_query = A_FALSE; + pdev->nr_queue = 4; + + return SW_OK; +} + +static sw_error_t +_athena_reset(a_uint32_t dev_id) +{ +#if !(defined(KERNEL_MODULE) && defined(USER_MODE)) + a_uint32_t val; + sw_error_t rv; + + val = 0x1; + HSL_REG_FIELD_SET(rv, dev_id, MASK_CTL, 0, SOFT_RST, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + ATHENA_VLAN_RESET(rv, dev_id); + + rv = athena_hw_init(dev_id); + SW_RTN_ON_ERROR(rv); +#endif + + return SW_OK; +} + +sw_error_t +athena_cleanup(a_uint32_t dev_id) +{ + if (athena_cfg[dev_id]) + { + aos_mem_free(athena_cfg[dev_id]); + athena_cfg[dev_id] = NULL; + } + +#if !(defined(KERNEL_MODULE) && defined(USER_MODE)) + { + sw_error_t rv; + ATHENA_VLAN_CLEANUP(rv, dev_id); + } +#endif + + return SW_OK; +} + +/** + * @brief Reset Athena module. + * @details Comments: + * This operation will reset athena. + * @param[in] dev_id device id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_reset(a_uint32_t dev_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_reset(dev_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Init Athena module. + * @details Comments: + * This operation will init athena. + * @param[in] dev_id device id + * @param[in] cfg configuration for initialization + * @return SW_OK or error code + */ +sw_error_t +athena_init(a_uint32_t dev_id, ssdk_init_cfg * cfg) +{ + HSL_DEV_ID_CHECK(dev_id); + + if (NULL == athena_cfg[dev_id]) + { + athena_cfg[dev_id] = (ssdk_init_cfg *)aos_mem_alloc(sizeof (ssdk_init_cfg)); + } + + if (NULL == athena_cfg[dev_id]) + { + return SW_OUT_OF_MEM; + } + + aos_mem_copy(athena_cfg[dev_id], cfg, sizeof (ssdk_init_cfg)); + + SW_RTN_ON_ERROR(athena_reg_access_init(dev_id, cfg->reg_mode)); + + SW_RTN_ON_ERROR(athena_dev_init(dev_id)); + +#if !(defined(KERNEL_MODULE) && defined(USER_MODE)) + { + sw_error_t rv; + SW_RTN_ON_ERROR(hsl_port_prop_init(dev_id)); + SW_RTN_ON_ERROR(hsl_port_prop_init_by_dev(dev_id)); + SW_RTN_ON_ERROR(athena_portproperty_init(dev_id, cfg->cpu_mode)); + + ATHENA_MIB_INIT(rv, dev_id); + ATHENA_PORT_CTRL_INIT(rv, dev_id); + ATHENA_PORTVLAN_INIT(rv, dev_id); + ATHENA_VLAN_INIT(rv, dev_id); + ATHENA_FDB_INIT(rv, dev_id); + + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->dev_reset = athena_reset; + p_api->dev_clean = athena_cleanup; + } + + SW_RTN_ON_ERROR(athena_hw_init(dev_id)); + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/athena/athena_mib.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/athena/athena_mib.c new file mode 100755 index 000000000..c71cbc3e2 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/athena/athena_mib.c @@ -0,0 +1,406 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 athena_mib ATHENA_MIB + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "athena_mib.h" +#include "athena_reg.h" + +static sw_error_t +_athena_get_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info) +{ + a_uint32_t val0 = 0, val1 = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_OUT_OF_RANGE; + } + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBROAD, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBROAD_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxBroad = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXPAUSE, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXPAUSE_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxPause = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXMULTI, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXMULTI_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxMulti = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXFCSERR, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXFCSERR_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxFcsErr = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXALLIGNERR, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXALLIGNERR_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxAllignErr = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXRUNT, port_id, (a_uint8_t *) (&val0), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXRUNT_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxRunt = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXFRAGMENT, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXFRAGMENT_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxFragment = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX64BYTE, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX64BYTE_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx64Byte = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX128BYTE, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX128BYTE_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx128Byte = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX256BYTE, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX256BYTE_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx256Byte = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX512BYTE, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX512BYTE_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx512Byte = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX1024BYTE, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX1024BYTE_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx1024Byte = val0 + val1; + + mib_info->Rx1518Byte = 0; //reserved for s16 + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXMAXBYTE, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXMAXBYTE_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxMaxByte = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXTOOLONG, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXTOOLONG_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxTooLong = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXGOODBYTE_LO, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXGOODBYTE_LO_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxGoodByte_lo = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXGOODBYTE_HI, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXGOODBYTE_HI_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxGoodByte_hi = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBADBYTE_LO, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBADBYTE_LO_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxBadByte_lo = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBADBYTE_HI, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBADBYTE_HI_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxBadByte_hi = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXOVERFLOW, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXOVERFLOW_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxOverFlow = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_FILTERED, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_FILTERED_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Filtered = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBROAD, port_id, (a_uint8_t *) (&val0), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBROAD_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxBroad = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXPAUSE, port_id, (a_uint8_t *) (&val0), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXPAUSE_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxPause = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMULTI, port_id, (a_uint8_t *) (&val0), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMULTI_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxMulti = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXUNDERRUN, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXUNDERRUN_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxUnderRun = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX64BYTE, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX64BYTE_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx64Byte = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX128BYTE, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX128BYTE_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx128Byte = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX256BYTE, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX256BYTE_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx256Byte = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX512BYTE, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX512BYTE_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx512Byte = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX1024BYTE, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX1024BYTE_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx1024Byte = val0 + val1; + + mib_info->Tx1518Byte = 0; //reserved for s16 + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMAXBYTE, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMAXBYTE_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxMaxByte = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXOVERSIZE, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXOVERSIZE_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxOverSize = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBYTE_LO, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBYTE_LO_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxByte_lo = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBYTE_HI, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBYTE_HI_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxByte_hi = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXCOLLISION, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXCOLLISION_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxCollision = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXABORTCOL, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXABORTCOL_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxAbortCol = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMULTICOL, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMULTICOL_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxMultiCol = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXSINGALCOL, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXSINGALCOL_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxSingalCol = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXEXCDEFER, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXEXCDEFER_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxExcDefer = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXDEFER, port_id, (a_uint8_t *) (&val0), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXDEFER_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxDefer = val0 + val1; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXLATECOL, port_id, + (a_uint8_t *) (&val0), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXLATECOL_2, port_id, + (a_uint8_t *) (&val1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxLateCol = val0 + val1; + + return SW_OK; +} + +/** + * @brief Get mib infomation on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mib_info mib infomation + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_get_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_get_mib_info(dev_id, port_id, mib_info); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +athena_mib_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + hsl_api_t *p_api; + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get(dev_id)); + + p_api->get_mib_info = athena_get_mib_info; +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/athena/athena_port_ctrl.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/athena/athena_port_ctrl.c new file mode 100755 index 000000000..136168486 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/athena/athena_port_ctrl.c @@ -0,0 +1,811 @@ +/* + * Copyright (c) 2012, 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 athena_port_ctrl ATHENA_PORT_CTRL + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "athena_port_ctrl.h" +#include "athena_reg.h" +#include "hsl_phy.h" + + + +static sw_error_t +_athena_port_duplex_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t duplex) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + a_uint32_t reg_save = 0; + a_uint32_t reg_val = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_duplex_set) + return SW_NOT_SUPPORTED; + + + if (FAL_DUPLEX_BUTT <= duplex) + { + return SW_BAD_PARAM; + } + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + //save reg value + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_val), sizeof (a_uint32_t)); + reg_save = reg_val; + + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 0, reg_val); + SW_SET_REG_BY_FIELD(PORT_STATUS, RXMAC_EN, 0, reg_val); + SW_SET_REG_BY_FIELD(PORT_STATUS, TXMAC_EN, 0, reg_val); + + //set mac be config by sw and turn off RX TX MAC_EN + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_val), sizeof (a_uint32_t)); + + rv = phy_drv->phy_duplex_set(dev_id, phy_id, duplex); + + //retore reg value + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_save), sizeof (a_uint32_t)); + + return rv; +} + + +static sw_error_t +_athena_port_duplex_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t * pduplex) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_duplex_get) + return SW_NOT_SUPPORTED; + + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_duplex_get(dev_id, phy_id, pduplex); + return rv; +} + + +static sw_error_t +_athena_port_speed_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t speed) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_speed_set) + return SW_NOT_SUPPORTED; + + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_SPEED_100 < speed) + { + return SW_BAD_PARAM; + } + + rv = phy_drv->phy_speed_set(dev_id, phy_id, speed); + + return rv; +} + + +static sw_error_t +_athena_port_speed_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t * pspeed) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_speed_get) + return SW_NOT_SUPPORTED; + + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_speed_get(dev_id, phy_id, pspeed); + + return rv; +} + + +static sw_error_t +_athena_port_autoneg_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_autoneg_status_get) + return SW_NOT_SUPPORTED; + + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + *status = phy_drv->phy_autoneg_status_get(dev_id, phy_id); + + return SW_OK; +} + + +static sw_error_t +_athena_port_autoneg_enable(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_autoneg_enable_set) + return SW_NOT_SUPPORTED; + + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_autoneg_enable_set(dev_id, phy_id); + return rv; +} + + +static sw_error_t +_athena_port_autoneg_restart(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_restart_autoneg) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_restart_autoneg(dev_id, phy_id); + return rv; +} + + +static sw_error_t +_athena_port_autoneg_adv_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t autoadv) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_autoneg_adv_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_autoneg_adv_set(dev_id, phy_id, autoadv); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + + +static sw_error_t +_athena_port_autoneg_adv_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * autoadv) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_autoneg_adv_get) + return SW_NOT_SUPPORTED; + + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + *autoadv = 0; + rv = phy_drv->phy_autoneg_adv_get(dev_id, phy_id, autoadv); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + + +static sw_error_t +_athena_port_igmps_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, IGMP_MLD_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + return rv; +} + + +static sw_error_t +_athena_port_igmps_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, IGMP_MLD_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_athena_port_powersave_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_powersave_set) + return SW_NOT_SUPPORTED; + + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_powersave_set(dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_athena_port_powersave_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_powersave_get) + return SW_NOT_SUPPORTED; + + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_powersave_get(dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_athena_port_hibernate_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_hibernation_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_hibernation_set(dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_athena_port_hibernate_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_hibernation_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_hibernation_get(dev_id, phy_id, enable); + + return rv; +} + +/** + * @brief Set duplex mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] duplex duplex mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_port_duplex_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t duplex) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_port_duplex_set(dev_id, port_id, duplex); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get duplex mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] duplex duplex mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_port_duplex_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t * pduplex) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_port_duplex_get(dev_id, port_id, pduplex); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set speed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] speed port speed + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_port_speed_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t speed) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_port_speed_set(dev_id, port_id, speed); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get speed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] speed port speed + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_port_speed_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t * pspeed) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_port_speed_get(dev_id, port_id, pspeed); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get auto negotiation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] status A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_port_autoneg_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_port_autoneg_status_get(dev_id, port_id, status); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Enable auto negotiation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_port_autoneg_enable(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_port_autoneg_enable(dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Restart auto negotiation procedule on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_port_autoneg_restart(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_port_autoneg_restart(dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set auto negotiation advtisement ability on a particular port. + * @details Comments: + * Auto negotiation advtisement ability is defined by macro such as + * FAL_PHY_ADV_10T_HD, FAL_PHY_ADV_PAUSE... + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] autoadv auto negotiation advtisement ability bit map + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_port_autoneg_adv_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t autoadv) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_port_autoneg_adv_set(dev_id, port_id, autoadv); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get auto negotiation advtisement ability on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] autoadv auto negotiation advtisement ability bit map + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_port_autoneg_adv_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * autoadv) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_port_autoneg_adv_get(dev_id, port_id, autoadv); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmp/mld packets snooping status on a particular port. + * @details Comments: + * After enabling igmp snooping feature on a particular port all kinds + * igmp packets received on this port would be acknowledged by hardware. + * Athena only supports igmp packets, it doesn't support mld packets. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_port_igmps_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_port_igmps_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp packets snooping status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_port_igmps_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_port_igmps_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set powersaving status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_port_powersave_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_port_powersave_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get powersaving status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_port_powersave_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_port_powersave_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set hibernate status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_port_hibernate_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_port_hibernate_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get hibernate status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_port_hibernate_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_port_hibernate_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +athena_port_ctrl_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->port_duplex_get = athena_port_duplex_get; + p_api->port_duplex_set = athena_port_duplex_set; + p_api->port_speed_get = athena_port_speed_get; + p_api->port_speed_set = athena_port_speed_set; + p_api->port_autoneg_status_get = athena_port_autoneg_status_get; + p_api->port_autoneg_enable = athena_port_autoneg_enable; + p_api->port_autoneg_restart = athena_port_autoneg_restart; + p_api->port_autoneg_adv_get = athena_port_autoneg_adv_get; + p_api->port_autoneg_adv_set = athena_port_autoneg_adv_set; + p_api->port_igmps_status_set = athena_port_igmps_status_set; + p_api->port_igmps_status_get = athena_port_igmps_status_get; + p_api->port_powersave_set = athena_port_powersave_set; + p_api->port_powersave_get = athena_port_powersave_get; + p_api->port_hibernate_set = athena_port_hibernate_set; + p_api->port_hibernate_get = athena_port_hibernate_get; +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/athena/athena_portvlan.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/athena/athena_portvlan.c new file mode 100755 index 000000000..74fdc3e02 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/athena/athena_portvlan.c @@ -0,0 +1,451 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 athena_port_vlan ATHENA_PORT_VLAN + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "athena_portvlan.h" +#include "athena_reg.h" + + +static sw_error_t +_athena_port_1qmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t port_1qmode) +{ + sw_error_t rv; + a_uint32_t regval[FAL_1Q_MODE_BUTT] = { 0, 3, 2, 1 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_1Q_MODE_BUTT <= port_1qmode) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_BASE_VLAN, port_id, DOT1Q_MODE, + (a_uint8_t *) (®val[port_1qmode]), + sizeof (a_uint32_t)); + + return rv; + +} + + +static sw_error_t +_athena_port_1qmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t * pport_1qmode) +{ + sw_error_t rv; + a_uint32_t regval = 0; + fal_pt_1qmode_t retval[4] = { FAL_1Q_DISABLE, FAL_1Q_FALLBACK, + FAL_1Q_CHECK, FAL_1Q_SECURE + }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL(pport_1qmode); + + HSL_REG_FIELD_GET(rv, dev_id, PORT_BASE_VLAN, port_id, DOT1Q_MODE, + (a_uint8_t *) (®val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + *pport_1qmode = retval[regval & 0x3]; + + return SW_OK; + +} + + +static sw_error_t +_athena_port_egvlanmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t port_egvlanmode) +{ + sw_error_t rv; + a_uint32_t regval[FAL_EG_MODE_BUTT] = { 0, 1, 2, 3}; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_EG_MODE_BUTT <= port_egvlanmode) + { + return SW_BAD_PARAM; + } + + if ((FAL_EG_TAGGED == port_egvlanmode) || (FAL_EG_HYBRID == port_egvlanmode)) + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, EG_VLAN_MODE, + (a_uint8_t *) (®val[port_egvlanmode]), + sizeof (a_uint32_t)); + + return rv; + +} + + +static sw_error_t +_athena_port_egvlanmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t * pport_egvlanmode) +{ + sw_error_t rv; + a_uint32_t regval = 0; + fal_pt_1q_egmode_t retval[3] = { FAL_EG_UNMODIFIED, FAL_EG_UNTAGGED, + FAL_EG_TAGGED + }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL(pport_egvlanmode); + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, EG_VLAN_MODE, + (a_uint8_t *) (®val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + *pport_egvlanmode = retval[regval & 0x3]; + + return SW_OK; + +} + + +static sw_error_t +_athena_portvlan_member_add(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id) +{ + sw_error_t rv; + a_uint32_t regval = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_FALSE == hsl_port_prop_check(dev_id, mem_port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_BASE_VLAN, port_id, + PORT_VID_MEM, (a_uint8_t *) (®val), + sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + regval |= (0x1UL << mem_port_id); + + HSL_REG_FIELD_SET(rv, dev_id, PORT_BASE_VLAN, port_id, + PORT_VID_MEM, (a_uint8_t *) (®val), + sizeof (a_uint32_t)); + + return rv; + +} + + +static sw_error_t +_athena_portvlan_member_del(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id) +{ + sw_error_t rv; + a_uint32_t regval = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_FALSE == hsl_port_prop_check(dev_id, mem_port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_BASE_VLAN, port_id, + PORT_VID_MEM, (a_uint8_t *) (®val), + sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + regval &= (~(0x1UL << mem_port_id)); + + HSL_REG_FIELD_SET(rv, dev_id, PORT_BASE_VLAN, port_id, + PORT_VID_MEM, (a_uint8_t *) (®val), + sizeof (a_uint32_t)); + + return rv; + +} + + +static sw_error_t +_athena_portvlan_member_update(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t mem_port_map) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_FALSE == + hsl_mports_prop_check(dev_id, mem_port_map, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_BASE_VLAN, port_id, + PORT_VID_MEM, (a_uint8_t *) (&mem_port_map), + sizeof (a_uint32_t)); + + return rv; +} + + +static sw_error_t +_athena_portvlan_member_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t * mem_port_map) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + *mem_port_map = 0; + HSL_REG_FIELD_GET(rv, dev_id, PORT_BASE_VLAN, port_id, + PORT_VID_MEM, (a_uint8_t *) mem_port_map, + sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +/** + * @brief Set 802.1q work mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] port_1qmode 802.1q work mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_port_1qmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t port_1qmode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_port_1qmode_set(dev_id, port_id, port_1qmode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get 802.1q work mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] port_1qmode 802.1q work mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_port_1qmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t * pport_1qmode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_port_1qmode_get(dev_id, port_id, pport_1qmode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set packets transmitted out vlan tagged mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] port_egvlanmode packets transmitted out vlan tagged mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_port_egvlanmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t port_egvlanmode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_port_egvlanmode_set(dev_id, port_id, port_egvlanmode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get packets transmitted out vlan tagged mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] port_egvlanmode packets transmitted out vlan tagged mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_port_egvlanmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t * pport_egvlanmode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_port_egvlanmode_get(dev_id, port_id, pport_egvlanmode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add member of port based vlan on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mem_port_id port member + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_portvlan_member_add(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_portvlan_member_add(dev_id, port_id, mem_port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete member of port based vlan on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mem_port_id port member + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_portvlan_member_del(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_portvlan_member_del(dev_id, port_id, mem_port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Update member of port based vlan on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mem_port_map port members + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_portvlan_member_update(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t mem_port_map) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_portvlan_member_update(dev_id, port_id, mem_port_map); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get member of port based vlan on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mem_port_map port members + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_portvlan_member_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t * mem_port_map) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_portvlan_member_get(dev_id, port_id, mem_port_map); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +athena_portvlan_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + hsl_api_t *p_api; + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get(dev_id)); + + p_api->port_1qmode_get = athena_port_1qmode_get; + p_api->port_1qmode_set = athena_port_1qmode_set; + p_api->port_egvlanmode_get = athena_port_egvlanmode_get; + p_api->port_egvlanmode_set = athena_port_egvlanmode_set; + p_api->portvlan_member_add = athena_portvlan_member_add; + p_api->portvlan_member_del = athena_portvlan_member_del; + p_api->portvlan_member_update = athena_portvlan_member_update; + p_api->portvlan_member_get = athena_portvlan_member_get; +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/athena/athena_reg_access.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/athena/athena_reg_access.c new file mode 100755 index 000000000..be4ae4610 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/athena/athena_reg_access.c @@ -0,0 +1,272 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 "hsl.h" +#include "hsl_dev.h" +#include "sd.h" +#include "athena_reg_access.h" + +static hsl_access_mode reg_mode; + +#if defined(API_LOCK) +static aos_lock_t mdio_lock; +#define MDIO_LOCKER_INIT aos_lock_init(&mdio_lock) +#define MDIO_LOCKER_LOCK aos_lock(&mdio_lock) +#define MDIO_LOCKER_UNLOCK aos_unlock(&mdio_lock) +#else +#define MDIO_LOCKER_INIT +#define MDIO_LOCKER_LOCK +#define MDIO_LOCKER_UNLOCK +#endif + +static sw_error_t +_athena_mdio_reg_get(a_uint32_t dev_id, a_uint32_t reg_addr, + a_uint8_t value[], a_uint32_t value_len) +{ + a_uint32_t reg_word_addr; + a_uint32_t phy_addr, reg_val; + a_uint16_t phy_val, tmp_val; + a_uint8_t phy_reg; + sw_error_t rv; + + if (value_len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + + /* change reg_addr to 16-bit word address, 32-bit aligned */ + reg_word_addr = (reg_addr & 0xfffffffc) >> 1; + + /* configure register high address */ + phy_addr = 0x18; + phy_reg = 0x0; + phy_val = (a_uint16_t) ((reg_word_addr >> 8) & 0x3ff); /* bit16-8 of reg address */ + + rv = sd_reg_mdio_set(dev_id, phy_addr, phy_reg, phy_val); + SW_RTN_ON_ERROR(rv); + + /* For some registers such as MIBs, since it is read/clear, we should */ + /* read the lower 16-bit register then the higher one */ + + /* read register in lower address */ + phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */ + phy_reg = (a_uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */ + rv = sd_reg_mdio_get(dev_id, phy_addr, phy_reg, &tmp_val); + SW_RTN_ON_ERROR(rv); + reg_val = tmp_val; + + /* read register in higher address */ + reg_word_addr++; + phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */ + phy_reg = (a_uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */ + rv = sd_reg_mdio_get(dev_id, phy_addr, phy_reg, &tmp_val); + SW_RTN_ON_ERROR(rv); + reg_val |= (((a_uint32_t)tmp_val) << 16); + + aos_mem_copy(value, ®_val, sizeof (a_uint32_t)); + + return SW_OK; +} + +static sw_error_t +_athena_mdio_reg_set(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t value[], + a_uint32_t value_len) +{ + a_uint32_t reg_word_addr; + a_uint32_t phy_addr, reg_val; + a_uint16_t phy_val; + a_uint8_t phy_reg; + sw_error_t rv; + + if (value_len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + + aos_mem_copy(®_val, value, sizeof (a_uint32_t)); + + /* change reg_addr to 16-bit word address, 32-bit aligned */ + reg_word_addr = (reg_addr & 0xfffffffc) >> 1; + + /* configure register high address */ + phy_addr = 0x18; + phy_reg = 0x0; + phy_val = (a_uint16_t) ((reg_word_addr >> 8) & 0x3ff); /* bit16-8 of reg address */ + + rv = sd_reg_mdio_set(dev_id, phy_addr, phy_reg, phy_val); + SW_RTN_ON_ERROR(rv); + + /* For some registers such as ARL and VLAN, since they include BUSY bit */ + /* in lower address, we should write the higher 16-bit register then the */ + /* lower one */ + + /* write register in higher address */ + reg_word_addr++; + phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */ + phy_reg = (a_uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */ + phy_val = (a_uint16_t) ((reg_val >> 16) & 0xffff); + rv = sd_reg_mdio_set(dev_id, phy_addr, phy_reg, phy_val); + SW_RTN_ON_ERROR(rv); + + /* write register in lower address */ + reg_word_addr--; + phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */ + phy_reg = (a_uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */ + phy_val = (a_uint16_t) (reg_val & 0xffff); + rv = sd_reg_mdio_set(dev_id, phy_addr, phy_reg, phy_val); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +sw_error_t +athena_phy_get(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t * value) +{ + sw_error_t rv; + + MDIO_LOCKER_LOCK; + rv = sd_reg_mdio_get(dev_id, phy_addr, reg, value); + MDIO_LOCKER_UNLOCK; + + return rv; +} + +sw_error_t +athena_phy_set(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t value) +{ + sw_error_t rv; + + MDIO_LOCKER_LOCK; + rv = sd_reg_mdio_set(dev_id, phy_addr, reg, value); + MDIO_LOCKER_UNLOCK; + + return rv; +} + +sw_error_t +athena_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; + a_uint32_t flags; + + MDIO_LOCKER_LOCK; + if (HSL_MDIO == reg_mode) + { + aos_irq_save(flags); + rv = _athena_mdio_reg_get(dev_id, reg_addr, value, value_len); + aos_irq_restore(flags); + } + else + { + rv = sd_reg_hdr_get(dev_id, reg_addr, value, value_len); + } + MDIO_LOCKER_UNLOCK; + + return rv; +} + +sw_error_t +athena_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; + a_uint32_t flags; + + MDIO_LOCKER_LOCK; + if (HSL_MDIO == reg_mode) + { + aos_irq_save(flags); + rv = _athena_mdio_reg_set(dev_id, reg_addr, value, value_len); + aos_irq_restore(flags); + } + else + { + rv = sd_reg_hdr_set(dev_id, reg_addr, value, value_len); + } + MDIO_LOCKER_UNLOCK; + + return rv; +} + +sw_error_t +athena_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) +{ + a_uint32_t reg_val = 0; + + if ((bit_offset >= 32 || (field_len > 32)) || (field_len == 0)) + return SW_OUT_OF_RANGE; + + if (value_len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + + SW_RTN_ON_ERROR(athena_reg_get(dev_id, reg_addr, (a_uint8_t *) & reg_val, sizeof (a_uint32_t))); + + *((a_uint32_t *) value) = SW_REG_2_FIELD(reg_val, bit_offset, field_len); + return SW_OK; +} + +sw_error_t +athena_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) +{ + a_uint32_t reg_val; + a_uint32_t field_val = *((a_uint32_t *) value); + + if ((bit_offset >= 32 || (field_len > 32)) || (field_len == 0)) + return SW_OUT_OF_RANGE; + + if (value_len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + + SW_RTN_ON_ERROR(athena_reg_get(dev_id, reg_addr, (a_uint8_t *) & reg_val, sizeof (a_uint32_t))); + + SW_REG_SET_BY_FIELD_U32(reg_val, field_val, bit_offset, field_len); + + SW_RTN_ON_ERROR(athena_reg_set(dev_id, reg_addr, (a_uint8_t *) & reg_val, sizeof (a_uint32_t))); + + return SW_OK; +} + +sw_error_t +athena_reg_access_init(a_uint32_t dev_id, hsl_access_mode mode) +{ + hsl_api_t *p_api; + + MDIO_LOCKER_INIT; + reg_mode = mode; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->phy_get = athena_phy_get; + p_api->phy_set = athena_phy_set; + p_api->reg_get = athena_reg_get; + p_api->reg_set = athena_reg_set; + p_api->reg_field_get = athena_reg_field_get; + p_api->reg_field_set = athena_reg_field_set; + p_api->dev_access_set= athena_access_mode_set; + + return SW_OK; +} + +sw_error_t +athena_access_mode_set(a_uint32_t dev_id, hsl_access_mode mode) +{ + reg_mode = mode; + return SW_OK; + +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/athena/athena_vlan.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/athena/athena_vlan.c new file mode 100755 index 000000000..a4f48f5d2 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/athena/athena_vlan.c @@ -0,0 +1,622 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 athena_vlan ATHENA_VLAN + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "athena_vlan.h" +#include "athena_reg.h" + +#define MAX_VLAN_ENTRY 16 +#define MAX_VLAN_ID 4094 + +#define VLAN_FLUSH 1 +#define VLAN_LOAD_ENTRY 2 +#define VLAN_PURGE_ENTRY 3 +#define VLAN_REMOVE_PORT 4 + +typedef struct +{ + fal_vlan_t vlan_entry; + a_bool_t active; +} v_array_t; + +static v_array_t *p_vlan_table[SW_MAX_NR_DEV] = { 0 }; + +static sw_error_t +athena_vlan_commit(a_uint32_t dev_id, a_uint32_t op) +{ + a_uint32_t vt_busy = 1, i = 0x1000, vt_full, val; + sw_error_t rv; + + while (vt_busy && --i) + { + HSL_REG_FIELD_GET(rv, dev_id, VLAN_TABLE_FUNC0, 0, VT_BUSY, + (a_uint8_t *) (&vt_busy), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + aos_udelay(5); + } + + if (i == 0) + return SW_BUSY; + + HSL_REG_ENTRY_GET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_FUNC, op, val); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_BUSY, 1, val); + + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, VLAN_TABLE_FUNC0, 0, VT_FULL_VIO, + (a_uint8_t *) (&vt_full), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (vt_full) + { + val = 0x10; + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + if (VLAN_LOAD_ENTRY == op) + { + return SW_FULL; + } + else if (VLAN_PURGE_ENTRY == op) + { + return SW_NOT_FOUND; + } + } + + return SW_OK; +} + +static sw_error_t +athena_vlan_table_location(a_uint32_t dev_id, a_uint16_t vlan_id, + a_int16_t * loc) +{ + a_int16_t i = 0; + v_array_t *p_v_array; + + if (p_vlan_table[dev_id] == NULL) + return SW_NOT_INITIALIZED; + + p_v_array = p_vlan_table[dev_id]; + + for (i = 0; i < MAX_VLAN_ENTRY; i++) + { + if ((p_v_array[i].active == A_TRUE) + && (p_v_array[i].vlan_entry.vid == vlan_id)) + break; + } + + if (i == MAX_VLAN_ENTRY) + return SW_NOT_FOUND; + + *loc = i; + + return SW_OK; +} + +static sw_error_t +athena_vlan_sw_to_hw(const fal_vlan_t * vlan_entry, a_uint32_t reg[]) +{ + if (A_TRUE == vlan_entry->vid_pri_en) + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_PRI_EN, 1, reg[0]); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_PRI, vlan_entry->vid_pri, reg[0]); + } + else + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_PRI_EN, 0, reg[0]); + } + + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VLAN_ID, vlan_entry->vid, reg[0]); + + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC1, VT_VALID, 1, reg[1]); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC1, VID_MEM, vlan_entry->mem_ports, reg[1]); + + if (0 != vlan_entry->u_ports) + { + return SW_BAD_VALUE; + } + + return SW_OK; +} + +static sw_error_t +_athena_vlan_entry_append(a_uint32_t dev_id, const fal_vlan_t * vlan_entry) +{ + sw_error_t rv; + a_uint32_t reg[2] = { 0 }; +#ifdef HSL_STANDALONG + a_int16_t i, loc = MAX_VLAN_ENTRY; + v_array_t *p_v_array; +#endif + + HSL_DEV_ID_CHECK(dev_id); + + if ((vlan_entry->vid == 0) || (vlan_entry->vid > MAX_VLAN_ID)) + return SW_OUT_OF_RANGE; + + if (A_FALSE == hsl_mports_prop_check(dev_id, vlan_entry->mem_ports, HSL_PP_INCL_CPU)) + return SW_BAD_PARAM; + +#ifdef HSL_STANDALONG + if ((p_v_array = p_vlan_table[dev_id]) == NULL) + return SW_NOT_INITIALIZED; + + for (i = 0; i < MAX_VLAN_ENTRY; i++) + { + if (p_v_array[i].active == A_FALSE) + { + loc = i; + } + else if (p_v_array[i].vlan_entry.vid == vlan_entry->vid) + { + return SW_ALREADY_EXIST; + } + } + + if (loc == MAX_VLAN_ENTRY) + return SW_FULL; +#endif + + rv = athena_vlan_sw_to_hw(vlan_entry, reg); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = athena_vlan_commit(dev_id, VLAN_LOAD_ENTRY); + SW_RTN_ON_ERROR(rv); + +#ifdef HSL_STANDALONG + p_v_array[loc].vlan_entry = *vlan_entry; + p_v_array[loc].active = A_TRUE; +#endif + + return SW_OK; +} + + +static sw_error_t +_athena_vlan_create(a_uint32_t dev_id, a_uint32_t vlan_id) +{ + sw_error_t rv; + a_uint32_t vtable_entry = 0; +#ifdef HSL_STANDALONG + a_int16_t i, loc = MAX_VLAN_ENTRY; + v_array_t *p_v_array; +#endif + + HSL_DEV_ID_CHECK(dev_id); + + if ((vlan_id == 0) || (vlan_id > MAX_VLAN_ID)) + return SW_OUT_OF_RANGE; + +#ifdef HSL_STANDALONG + if ((p_v_array = p_vlan_table[dev_id]) == NULL) + return SW_NOT_INITIALIZED; + + for (i = 0; i < MAX_VLAN_ENTRY; i++) + { + if (p_v_array[i].active == A_FALSE) + { + loc = i; + } + else if (p_v_array[i].vlan_entry.vid == vlan_id) + { + return SW_ALREADY_EXIST; + } + } + + if (loc == MAX_VLAN_ENTRY) + return SW_FULL; +#endif + + /* set default value for VLAN_TABLE_FUNC0, all 0 except vid */ + vtable_entry = 0; + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VLAN_ID, vlan_id, vtable_entry); + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (&vtable_entry), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + /* set default value for VLAN_TABLE_FUNC1, all 0 */ + vtable_entry = 0; + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC1, VT_VALID, 1, vtable_entry); + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (&vtable_entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = athena_vlan_commit(dev_id, VLAN_LOAD_ENTRY); + SW_RTN_ON_ERROR(rv); + +#ifdef HSL_STANDALONG + p_v_array[loc].vlan_entry.vid = vlan_id; + p_v_array[loc].vlan_entry.mem_ports = 0; + p_v_array[loc].vlan_entry.u_ports = 0; + p_v_array[loc].vlan_entry.vid_pri_en = A_FALSE; + p_v_array[loc].vlan_entry.vid_pri = 0; + p_v_array[loc].active = A_TRUE; +#endif + + return SW_OK; +} + + +static sw_error_t +_athena_vlan_next(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan) +{ +#ifdef HSL_STANDALONG + a_uint16_t i = 0, loc = MAX_VLAN_ENTRY; + a_uint16_t tmp_vid = MAX_VLAN_ID + 1; + v_array_t *p_v_array; + + HSL_DEV_ID_CHECK(dev_id); + + if (vlan_id > MAX_VLAN_ID) + return SW_OUT_OF_RANGE; + + if ((p_v_array = p_vlan_table[dev_id]) == NULL) + return SW_NOT_INITIALIZED; + + for (i = 0; i < MAX_VLAN_ENTRY; i++) + { + if ((p_v_array[i].active == A_TRUE) + && (p_v_array[i].vlan_entry.vid > vlan_id)) + { + if (tmp_vid > p_v_array[i].vlan_entry.vid) + { + loc = i; + tmp_vid = p_v_array[i].vlan_entry.vid; + } + } + } + + if (loc == MAX_VLAN_ENTRY) + return SW_NO_MORE; + + *p_vlan = p_v_array[loc].vlan_entry; + + return SW_OK; +#else + return SW_NOT_SUPPORTED; +#endif +} + + +static sw_error_t +_athena_vlan_find(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan) +{ +#ifdef HSL_STANDALONG + a_int16_t loc; + v_array_t *p_v_array; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if ((vlan_id == 0) || (vlan_id > MAX_VLAN_ID)) + return SW_OUT_OF_RANGE; + + if ((p_v_array = p_vlan_table[dev_id]) == NULL) + return SW_NOT_INITIALIZED; + + rv = athena_vlan_table_location(dev_id, vlan_id, &loc); + SW_RTN_ON_ERROR(rv); + *p_vlan = p_v_array[loc].vlan_entry; + + return SW_OK; +#else + return SW_NOT_SUPPORTED; +#endif +} + + +static sw_error_t +_athena_vlan_member_update(a_uint32_t dev_id, a_uint32_t vlan_id, + fal_pbmp_t member, fal_pbmp_t u_member) +{ +#ifdef HSL_STANDALONG + sw_error_t rv; + a_int16_t loc; + a_uint32_t reg_tmp; + v_array_t *p_v_array; + fal_vlan_t *p_sw_vlan; + + HSL_DEV_ID_CHECK(dev_id); + + if ((vlan_id == 0) || (vlan_id > MAX_VLAN_ID)) + return SW_OUT_OF_RANGE; + + if (A_FALSE == hsl_mports_prop_check(dev_id, member, HSL_PP_INCL_CPU)) + return SW_BAD_PARAM; + + if (u_member != 0) + return SW_BAD_PARAM; + + if ((p_v_array = p_vlan_table[dev_id]) == NULL) + return SW_NOT_INITIALIZED; + + rv = athena_vlan_table_location(dev_id, vlan_id, &loc); + SW_RTN_ON_ERROR(rv); + p_sw_vlan = &p_v_array[loc].vlan_entry; + + /* set value for VLAN_TABLE_FUNC0, all 0 except vid */ + reg_tmp = 0; + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VLAN_ID, vlan_id, reg_tmp); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_PRI_EN, + (a_int32_t)p_sw_vlan->vid_pri_en, reg_tmp); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_PRI, p_sw_vlan->vid_pri, reg_tmp); + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (®_tmp), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* set vlan member for VLAN_TABLE_FUNC1 */ + HSL_REG_FIELD_SET(rv, dev_id, VLAN_TABLE_FUNC1, 0, VID_MEM, + (a_uint8_t *) (&member), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = athena_vlan_commit(dev_id, VLAN_LOAD_ENTRY); + SW_RTN_ON_ERROR(rv); + + p_v_array[loc].vlan_entry.mem_ports = member; + + return SW_OK; +#else + return SW_NOT_SUPPORTED; +#endif +} + + +static sw_error_t +_athena_vlan_delete(a_uint32_t dev_id, a_uint32_t vlan_id) +{ + sw_error_t rv; + a_int16_t loc; + a_uint32_t reg_tmp; +#ifdef HSL_STANDALONG + v_array_t *p_v_array; +#endif + + HSL_DEV_ID_CHECK(dev_id); + + if ((vlan_id == 0) || (vlan_id > MAX_VLAN_ID)) + return SW_OUT_OF_RANGE; + +#ifdef HSL_STANDALONG + if ((p_v_array = p_vlan_table[dev_id]) == NULL) + return SW_NOT_INITIALIZED; + + rv = athena_vlan_table_location(dev_id, vlan_id, &loc); + SW_RTN_ON_ERROR(rv); +#endif + + reg_tmp = (a_int32_t) vlan_id; + HSL_REG_FIELD_SET(rv, dev_id, VLAN_TABLE_FUNC0, 0, VLAN_ID, + (a_uint8_t *) (®_tmp), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = athena_vlan_commit(dev_id, VLAN_PURGE_ENTRY); + SW_RTN_ON_ERROR(rv); + +#ifdef HSL_STANDALONG + p_v_array[loc].active = A_FALSE; +#endif + + return SW_OK; +} + +sw_error_t +athena_vlan_reset(a_uint32_t dev_id) +{ +#ifdef HSL_STANDALONG + a_int16_t i; + v_array_t *p_v_array; + + HSL_DEV_ID_CHECK(dev_id); + + aos_mem_zero(p_vlan_table[dev_id], MAX_VLAN_ENTRY * (sizeof (v_array_t))); + + p_v_array = p_vlan_table[dev_id]; + for (i = 0; i < MAX_VLAN_ENTRY; i++) + { + p_v_array[i].active = A_FALSE; + } +#endif + + return SW_OK; +} + +sw_error_t +athena_vlan_cleanup(a_uint32_t dev_id) +{ + if (p_vlan_table[dev_id]) + { + aos_mem_free(p_vlan_table[dev_id]); + p_vlan_table[dev_id] = NULL; + } + + return SW_OK; +} + +/** + * @brief Append a vlan entry on paticular device. + * @param[in] dev_id device id + * @param[in] vlan_entry vlan entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_vlan_entry_append(a_uint32_t dev_id, const fal_vlan_t * vlan_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_vlan_entry_append(dev_id, vlan_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Creat a vlan entry through vlan id on a paticular device. + * @details Comments: + * After this operation the member ports of the created vlan entry are null. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_vlan_create(a_uint32_t dev_id, a_uint32_t vlan_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_vlan_create(dev_id, vlan_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Next a vlan entry through vlan id on a paticular device. + * @details Comments: + * If the value of vid is zero this operation will get the first entry. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[out] p_vlan vlan entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_vlan_next(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_vlan_next(dev_id, vlan_id, p_vlan); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Find a vlan entry through vlan id on paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[out] p_vlan vlan entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_vlan_find(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_vlan_find(dev_id, vlan_id, p_vlan); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Update a vlan entry member port through vlan id on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[in] member member ports + * @param[in] u_member tagged or untagged infomation for member ports + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_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; + + HSL_API_LOCK; + rv = _athena_vlan_member_update(dev_id, vlan_id, member, u_member); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a vlan entry through vlan id on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +athena_vlan_delete(a_uint32_t dev_id, a_uint32_t vlan_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _athena_vlan_delete(dev_id, vlan_id); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +athena_vlan_init(a_uint32_t dev_id) +{ +#ifdef HSL_STANDALONG + a_int16_t i; + v_array_t *p_v_array; + v_array_t *p_mem; + + HSL_DEV_ID_CHECK(dev_id); + + /* allocate memory for vlan info */ + p_mem = aos_mem_alloc(MAX_VLAN_ENTRY * (sizeof (v_array_t))); + if (p_mem == NULL) + return SW_OUT_OF_MEM; + + aos_mem_zero(p_mem, MAX_VLAN_ENTRY * (sizeof (v_array_t))); + + /* start address for vlan info */ + p_vlan_table[dev_id] = p_v_array = p_mem; + + for (i = 0; i < MAX_VLAN_ENTRY; i++) + { + p_v_array[i].active = A_FALSE; + } +#endif + +#ifndef HSL_STANDALONG + hsl_api_t *p_api; + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get(dev_id)); + + p_api->vlan_entry_append = athena_vlan_entry_append; + p_api->vlan_creat = athena_vlan_create; + p_api->vlan_delete = athena_vlan_delete; +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/cppe/Makefile b/feeds/ipq807x/qca-ssdk/src/src/hsl/cppe/Makefile new file mode 100755 index 000000000..73c4dd620 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/cppe/Makefile @@ -0,0 +1,23 @@ +LOC_DIR=src/hsl/cppe +LIB=HSL + +include $(PRJ_PATH)/make/config.mk + +ifeq (TRUE, $(IN_PORTCONTROL)) + SRC_LIST+=cppe_portctrl.c + SRC_LIST+=cppe_loopback.c +endif + +ifeq (TRUE, $(IN_QOS)) + SRC_LIST+=cppe_qos.c +endif + +ifeq (, $(findstring CPPE, $(SUPPORT_CHIP))) + SRC_LIST= +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/src/src/hsl/cppe/cppe_loopback.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/cppe/cppe_loopback.c new file mode 100755 index 000000000..49795aecf --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/cppe/cppe_loopback.c @@ -0,0 +1,440 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hppe_reg_access.h" +#include "cppe_loopback_reg.h" +#include "cppe_loopback.h" + +sw_error_t +cppe_lpbk_enable_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbk_enable_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + LPBK_ENABLE_ADDRESS + \ + index * LPBK_ENABLEL_INC, + &value->val); +} + +sw_error_t +cppe_lpbk_enable_set( + a_uint32_t dev_id, + a_uint32_t index, + union lpbk_enable_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_MAC_CSR_BASE_ADDR + LPBK_ENABLE_ADDRESS + \ + index * LPBK_ENABLEL_INC, + value->val); +} + +sw_error_t +cppe_lpbk_fifo_1_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbk_fifo_1_ctrl_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + LPBK_FIFO_1_CTRL_ADDRESS + \ + index * LPBK_FIFO_1_CTRL_INC, + &value->val); +} + +sw_error_t +cppe_lpbk_fifo_1_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union lpbk_fifo_1_ctrl_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_MAC_CSR_BASE_ADDR + LPBK_FIFO_1_CTRL_ADDRESS + \ + index * LPBK_FIFO_1_CTRL_INC, + value->val); +} + +sw_error_t +cppe_lpbk_fifo_2_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbk_fifo_2_ctrl_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + LPBK_FIFO_2_CTRL_ADDRESS + \ + index * LPBK_FIFO_2_CTRL_INC, + &value->val); +} + + +sw_error_t +cppe_lpbk_fifo_2_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union lpbk_fifo_2_ctrl_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_MAC_CSR_BASE_ADDR + LPBK_FIFO_2_CTRL_ADDRESS + \ + index * LPBK_FIFO_2_CTRL_INC, + value->val); +} + +sw_error_t +cppe_lpbk_pps_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbk_pps_ctrl_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + LPBK_PPS_CTRL_ADDRESS + \ + index * LPBK_PPS_CTRL_INC, + &value->val); +} + +sw_error_t +cppe_lpbk_pps_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union lpbk_pps_ctrl_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_MAC_CSR_BASE_ADDR + LPBK_PPS_CTRL_ADDRESS + \ + index * LPBK_PPS_CTRL_INC, + value->val); +} + +sw_error_t +cppe_lpbk_mac_junmo_size_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbk_mac_junmo_size_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + LPBK_MAC_JUNMO_SIZE_ADDRESS + \ + index * LPBK_MAC_JUNMO_SIZE_INC, + &value->val); +} + +sw_error_t +cppe_lpbk_mac_junmo_size_set( + a_uint32_t dev_id, + a_uint32_t index, + union lpbk_mac_junmo_size_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_MAC_CSR_BASE_ADDR + LPBK_MAC_JUNMO_SIZE_ADDRESS + \ + index * LPBK_MAC_JUNMO_SIZE_INC, + value->val); +} + +sw_error_t +cppe_lpbk_mib_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbk_mib_ctrl_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + LPBK_MIB_CTRL_ADDRESS + \ + index * LPBK_MIB_CTRL_INC, + &value->val); +} + +sw_error_t +cppe_lpbk_mib_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union lpbk_mib_ctrl_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_MAC_CSR_BASE_ADDR + LPBK_MIB_CTRL_ADDRESS + \ + index * LPBK_MIB_CTRL_INC, + value->val); +} + +sw_error_t +cppe_lpbk_mib_uni_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbkuni_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + LPBKUNI_ADDRESS + \ + index * LPBKUNI_INC, + &value->val); +} + +sw_error_t +cppe_lpbk_mib_multi_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbkmulti_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + LPBKMULTI_ADDRESS + \ + index * LPBKMULTI_INC, + &value->val); +} + +sw_error_t +cppe_lpbk_mib_broad_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbkbroad_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + LPBKBROAD_ADDRESS + \ + index * LPBKBROAD_INC, + &value->val); +} + +sw_error_t +cppe_lpbk_mib_pkt64_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbkpkt64_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + LPBKPKT64_ADDRESS + \ + index * LPBKPKT64_INC, + &value->val); + +} + +sw_error_t +cppe_lpbk_mib_pkt65to127_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbkpkt65to127_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + LPBKPKT65TO127_ADDRESS + \ + index * LPBKPKT65TO127_INC, + &value->val); +} + +sw_error_t +cppe_lpbk_mib_pkt128to255_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbkpkt128to255_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + LPBKPKT128TO255_ADDRESS + \ + index * LPBKPKT128TO255_INC, + &value->val); +} + +sw_error_t +cppe_lpbk_mib_pkt256to511_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbkpkt256to511_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + LPBKPKT256TO511_ADDRESS + \ + index * LPBKPKT256TO511_INC, + &value->val); +} + +sw_error_t +cppe_lpbk_mib_pkt512to1023_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbkpkt512to1023_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + LPBKPKT512TO1023_ADDRESS + \ + index * LPBKPKT512TO1023_INC, + &value->val); +} + +sw_error_t +cppe_lpbk_mib_pkt1024to1518_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbkpkt1024to1518_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + LPBKPKT1024TO1518_ADDRESS + \ + index * LPBKPKT1024TO1518_INC, + &value->val); +} + +sw_error_t +cppe_lpbk_mib_pkt1519tox_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbkpkt1519tox_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + LPBKPKT1519TOX_ADDRESS + \ + index * LPBKPKT1519TOX_INC, + &value->val); +} + +sw_error_t +cppe_lpbk_mib_toolong_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbkpkttoolong_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + LPBKPKTTOOLONG_ADDRESS + \ + index * LPBKPKTTOOLONG_INC, + &value->val); +} + +sw_error_t +cppe_lpbk_mib_byte_l_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbkbyte_l_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + LPBKBYTE_L_ADDRESS + \ + index * LPBKBYTE_L_INC, + &value->val); +} + +sw_error_t +cppe_lpbk_mib_byte_h_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbkbyte_h_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + LPBKBYTE_H_ADDRESS + \ + index * LPBKBYTE_H_INC, + &value->val); +} + +sw_error_t +cppe_lpbk_mib_drop_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbkdropcounter_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + LPBKDROPCOUNTER_ADDRESS + \ + index * LPBKDROPCOUNTER_INC, + &value->val); +} + +sw_error_t +cppe_lpbk_mib_tooshort_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbkpkttooshort_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + LPBKPKTTOOSHORT_ADDRESS + \ + index * LPBKPKTTOOSHORT_INC, + &value->val); +} + +sw_error_t +cppe_lpbk_mib_pkt14to63_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbkpkt14to63_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + LPBKPKT14TO63_ADDRESS + \ + index * LPBKPKT14TO63_INC, + &value->val); +} + +sw_error_t +cppe_lpbk_mib_toolongbyte_l_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbktoolongbyte_l_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + LPBKTOOLONGBYTE_L_ADDRESS + \ + index * LPBKTOOLONGBYTE_L_INC, + &value->val); +} + +sw_error_t +cppe_lpbk_mib_toolongbyte_h_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbktoolongbyte_h_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + LPBKTOOLONGBYTE_H_ADDRESS + \ + index * LPBKTOOLONGBYTE_H_INC, + &value->val); +} + +sw_error_t +cppe_lpbk_mib_tooshortbyte_l_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbktooshortbyte_l_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + LPBKTOOSHORTBYTE_L_ADDRESS + \ + index * LPBKTOOSHORTBYTE_L_INC, + &value->val); +} + +sw_error_t +cppe_lpbk_mib_tooshortbyte_h_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpbktooshortbyte_h_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + LPBKTOOSHORTBYTE_H_ADDRESS + \ + index * LPBKTOOSHORTBYTE_H_INC, + &value->val); +} diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/cppe/cppe_portctrl.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/cppe/cppe_portctrl.c new file mode 100755 index 000000000..31ffb24d0 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/cppe/cppe_portctrl.c @@ -0,0 +1,488 @@ +/* + * 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. + */ + + +/** + * @defgroup + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hppe_reg_access.h" +#include "hppe_global_reg.h" +#include "cppe_portctrl_reg.h" +#include "cppe_portctrl.h" + +sw_error_t +cppe_mru_mtu_ctrl_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union cppe_mru_mtu_ctrl_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + IPE_L2_BASE_ADDR + CPPE_MRU_MTU_CTRL_TBL_ADDRESS + \ + index * CPPE_MRU_MTU_CTRL_TBL_INC, + value->val, + 2); +} + +sw_error_t +cppe_mru_mtu_ctrl_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union cppe_mru_mtu_ctrl_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + IPE_L2_BASE_ADDR + CPPE_MRU_MTU_CTRL_TBL_ADDRESS + \ + index * CPPE_MRU_MTU_CTRL_TBL_INC, + value->val, + 2); +} + +sw_error_t +cppe_mru_mtu_ctrl_tbl_dscp_res_prec_force_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union cppe_mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.dscp_res_prec_force; + return ret; +} + +sw_error_t +cppe_mru_mtu_ctrl_tbl_dscp_res_prec_force_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union cppe_mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.dscp_res_prec_force = value; + ret = cppe_mru_mtu_ctrl_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +cppe_mru_mtu_ctrl_tbl_pcp_res_prec_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union cppe_mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.pcp_res_prec; + return ret; +} + +sw_error_t +cppe_mru_mtu_ctrl_tbl_pcp_res_prec_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union cppe_mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pcp_res_prec = value; + ret = cppe_mru_mtu_ctrl_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +cppe_mru_mtu_ctrl_tbl_pcp_qos_group_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union cppe_mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.pcp_qos_group_id; + return ret; +} + +sw_error_t +cppe_mru_mtu_ctrl_tbl_pcp_qos_group_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union cppe_mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pcp_qos_group_id = value; + ret = cppe_mru_mtu_ctrl_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +cppe_mru_mtu_ctrl_tbl_pcp_res_prec_force_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union cppe_mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.pcp_res_prec_force; + return ret; +} + +sw_error_t +cppe_mru_mtu_ctrl_tbl_pcp_res_prec_force_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union cppe_mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pcp_res_prec_force = value; + ret = cppe_mru_mtu_ctrl_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +cppe_mru_mtu_ctrl_tbl_post_acl_res_prec_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union cppe_mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.post_acl_res_prec; + return ret; +} + +sw_error_t +cppe_mru_mtu_ctrl_tbl_post_acl_res_prec_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union cppe_mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.post_acl_res_prec = value; + ret = cppe_mru_mtu_ctrl_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +cppe_mru_mtu_ctrl_tbl_preheader_res_prec_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union cppe_mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.preheader_res_prec; + return ret; +} + +sw_error_t +cppe_mru_mtu_ctrl_tbl_preheader_res_prec_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union cppe_mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.preheader_res_prec = value; + ret = cppe_mru_mtu_ctrl_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +cppe_mru_mtu_ctrl_tbl_dscp_res_prec_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union cppe_mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.dscp_res_prec; + return ret; +} + +sw_error_t +cppe_mru_mtu_ctrl_tbl_dscp_res_prec_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union cppe_mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.dscp_res_prec = value; + ret = cppe_mru_mtu_ctrl_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +cppe_mru_mtu_ctrl_tbl_pre_acl_res_prec_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union cppe_mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.pre_acl_res_prec; + return ret; +} + +sw_error_t +cppe_mru_mtu_ctrl_tbl_pre_acl_res_prec_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union cppe_mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pre_acl_res_prec = value; + ret = cppe_mru_mtu_ctrl_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +cppe_mru_mtu_ctrl_tbl_flow_res_prec_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union cppe_mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.flow_res_prec; + return ret; +} + +sw_error_t +cppe_mru_mtu_ctrl_tbl_flow_res_prec_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union cppe_mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_res_prec = value; + ret = cppe_mru_mtu_ctrl_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +cppe_mru_mtu_ctrl_tbl_dscp_qos_group_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union cppe_mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.dscp_qos_group_id; + return ret; +} + +sw_error_t +cppe_mru_mtu_ctrl_tbl_dscp_qos_group_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union cppe_mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.dscp_qos_group_id = value; + ret = cppe_mru_mtu_ctrl_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +cppe_mru_mtu_ctrl_tbl_src_profile_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union cppe_mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.src_profile; + return ret; +} + +sw_error_t +cppe_mru_mtu_ctrl_tbl_src_profile_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union cppe_mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.src_profile = value; + ret = cppe_mru_mtu_ctrl_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +cppe_mru_mtu_ctrl_tbl_source_filter_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union cppe_mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + { + return ret; + } + reg_val.bf.source_filtering_bypass = value; + ret = cppe_mru_mtu_ctrl_tbl_set(dev_id, index, ®_val); + + return ret; +} + +sw_error_t +cppe_mru_mtu_ctrl_tbl_source_filter_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union cppe_mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.source_filtering_bypass; + + return ret; +} + +sw_error_t +cppe_mru_mtu_ctrl_tbl_source_filter_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union cppe_mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + { + return ret; + } + reg_val.bf.source_filtering_mode = value; + ret = cppe_mru_mtu_ctrl_tbl_set(dev_id, index, ®_val); + + return ret; +} + +sw_error_t +cppe_mru_mtu_ctrl_tbl_source_filter_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union cppe_mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.source_filtering_mode; + + return ret; +} + +sw_error_t +cppe_port_phy_status_1_get( + a_uint32_t dev_id, + union cppe_port_phy_status_1_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_GLOBAL_BASE_ADDR + PORT_PHY_STATUS_1_ADDRESS, + &value->val); +} + +sw_error_t +cppe_port5_pcs1_phy_status_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union cppe_port_phy_status_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_port_phy_status_1_get(dev_id, ®_val); + *value = reg_val.bf.port5_pcs1_phy_status; + return ret; +} diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/cppe/cppe_qos.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/cppe/cppe_qos.c new file mode 100755 index 000000000..a91919226 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/cppe/cppe_qos.c @@ -0,0 +1,428 @@ +/* + * 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. + */ + + +/** + * @defgroup + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hppe_reg_access.h" +#include "hppe_qos_reg.h" +#include "hppe_qos.h" +#include "cppe_qos_reg.h" + + +sw_error_t +cppe_qos_mapping_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union qos_mapping_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + IPE_L2_BASE_ADDR + QOS_MAPPING_TBL_ADDRESS + \ + index * QOS_MAPPING_TBL_INC, + value->val, + 2); +} + +sw_error_t +cppe_qos_mapping_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union qos_mapping_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + IPE_L2_BASE_ADDR + QOS_MAPPING_TBL_ADDRESS + \ + index * QOS_MAPPING_TBL_INC, + value->val, + 2); +} + +sw_error_t +cppe_qos_mapping_tbl_int_pcp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union qos_mapping_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_qos_mapping_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.int_pcp; + return ret; +} + +sw_error_t +cppe_qos_mapping_tbl_int_pcp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union qos_mapping_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_qos_mapping_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.int_pcp = value; + ret = cppe_qos_mapping_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +cppe_qos_mapping_tbl_int_dei_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union qos_mapping_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_qos_mapping_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.int_dei; + return ret; +} + +sw_error_t +cppe_qos_mapping_tbl_int_dei_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union qos_mapping_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_qos_mapping_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.int_dei = value; + ret = cppe_qos_mapping_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +cppe_qos_mapping_tbl_int_dei_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union qos_mapping_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_qos_mapping_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.int_dei_en; + return ret; +} + +sw_error_t +cppe_qos_mapping_tbl_int_dei_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union qos_mapping_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_qos_mapping_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.int_dei_en = value; + ret = cppe_qos_mapping_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +cppe_qos_mapping_tbl_dscp_tc_mask_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union qos_mapping_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_qos_mapping_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.dscp_tc_mask; + return ret; +} + +sw_error_t +cppe_qos_mapping_tbl_dscp_tc_mask_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union qos_mapping_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_qos_mapping_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.dscp_tc_mask = value; + ret = cppe_qos_mapping_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +cppe_qos_mapping_tbl_int_dscp_tc_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union qos_mapping_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_qos_mapping_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.int_dscp_tc; + return ret; +} + +sw_error_t +cppe_qos_mapping_tbl_int_dscp_tc_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union qos_mapping_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_qos_mapping_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.int_dscp_tc = value; + ret = cppe_qos_mapping_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +cppe_qos_mapping_tbl_int_dp_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union qos_mapping_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_qos_mapping_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.int_dp_en; + return ret; +} + +sw_error_t +cppe_qos_mapping_tbl_int_dp_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union qos_mapping_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_qos_mapping_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.int_dp_en = value; + ret = cppe_qos_mapping_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +cppe_qos_mapping_tbl_int_dp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union qos_mapping_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_qos_mapping_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.int_dp; + return ret; +} + +sw_error_t +cppe_qos_mapping_tbl_int_dp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union qos_mapping_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_qos_mapping_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.int_dp = value; + ret = cppe_qos_mapping_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +cppe_qos_mapping_tbl_int_pri_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union qos_mapping_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_qos_mapping_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.int_pri_en; + return ret; +} + +sw_error_t +cppe_qos_mapping_tbl_int_pri_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union qos_mapping_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_qos_mapping_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.int_pri_en = value; + ret = cppe_qos_mapping_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +cppe_qos_mapping_tbl_qos_res_prec_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union qos_mapping_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_qos_mapping_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.qos_res_prec_1 << 1 | \ + reg_val.bf.qos_res_prec_0; + return ret; +} + +sw_error_t +cppe_qos_mapping_tbl_qos_res_prec_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union qos_mapping_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_qos_mapping_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.qos_res_prec_1 = value >> 1; + reg_val.bf.qos_res_prec_0 = value & (((a_uint64_t)1<<1)-1); + ret = cppe_qos_mapping_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +cppe_qos_mapping_tbl_int_pcp_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union qos_mapping_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_qos_mapping_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.int_pcp_en; + return ret; +} + +sw_error_t +cppe_qos_mapping_tbl_int_pcp_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union qos_mapping_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_qos_mapping_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.int_pcp_en = value; + ret = cppe_qos_mapping_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +cppe_qos_mapping_tbl_int_pri_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union qos_mapping_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_qos_mapping_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.int_pri; + return ret; +} + +sw_error_t +cppe_qos_mapping_tbl_int_pri_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union qos_mapping_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_qos_mapping_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.int_pri = value; + ret = cppe_qos_mapping_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +cppe_qos_mapping_tbl_int_dscp_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union qos_mapping_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_qos_mapping_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.int_dscp_en; + return ret; +} + +sw_error_t +cppe_qos_mapping_tbl_int_dscp_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union qos_mapping_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = cppe_qos_mapping_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.int_dscp_en = value; + ret = cppe_qos_mapping_tbl_set(dev_id, index, ®_val); + return ret; +} \ No newline at end of file diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/Makefile b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/Makefile new file mode 100755 index 000000000..c79a503e0 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/Makefile @@ -0,0 +1,114 @@ +LOC_DIR=src/hsl/dess +LIB=HSL + +include $(PRJ_PATH)/make/config.mk + +SRC_LIST=dess_reg_access.c dess_init.c + +ifeq (TRUE, $(IN_ACL)) + SRC_LIST += dess_acl.c dess_acl_parse.c dess_multicast_acl.c +endif + +ifeq (TRUE, $(IN_FDB)) + SRC_LIST += dess_fdb.c +endif + +ifeq (TRUE, $(IN_IGMP)) + SRC_LIST += dess_igmp.c +endif + +ifeq (TRUE, $(IN_LEAKY)) + SRC_LIST += dess_leaky.c +endif + +ifeq (TRUE, $(IN_LED)) + SRC_LIST += dess_led.c +endif + +ifeq (TRUE, $(IN_MIB)) + SRC_LIST += dess_mib.c +endif + +ifeq (TRUE, $(IN_MIRROR)) + SRC_LIST += dess_mirror.c +endif + +ifeq (TRUE, $(IN_MISC)) + SRC_LIST += dess_misc.c +endif + +ifeq (TRUE, $(IN_PORTCONTROL)) + SRC_LIST += dess_port_ctrl.c +endif + +ifeq (TRUE, $(IN_PORTVLAN)) + SRC_LIST += dess_portvlan.c +endif + +ifeq (TRUE, $(IN_QOS)) + SRC_LIST += dess_qos.c +endif + +ifeq (TRUE, $(IN_RATE)) + SRC_LIST += dess_rate.c +endif + +ifeq (TRUE, $(IN_STP)) + SRC_LIST += dess_stp.c +endif + +ifeq (TRUE, $(IN_VLAN)) + SRC_LIST += dess_vlan.c +endif + +ifeq (TRUE, $(IN_COSMAP)) + SRC_LIST += dess_cosmap.c +endif + +ifeq (TRUE, $(IN_IP)) + SRC_LIST += dess_ip.c +endif + +ifeq (TRUE, $(IN_NAT)) + SRC_LIST += dess_nat.c +endif + +ifeq (TRUE, $(IN_NAT_HELPER)) + SRC_LIST += nat_helper_dt.c + SRC_LIST += nat_helper_hsl.c + SRC_LIST += nat_ipt_helper.c + SRC_LIST += napt_helper.c + SRC_LIST += host_helper.c + SRC_LIST += nat_helper.c + SRC_LIST += napt_acl.c +endif + +ifeq (TRUE, $(IN_TRUNK)) + SRC_LIST += dess_trunk.c +endif + +ifeq (TRUE, $(IN_SEC)) + SRC_LIST += dess_sec.c +endif + +ifeq (TRUE, $(IN_INTERFACECONTROL)) + SRC_LIST += dess_interface_ctrl.c dess_psgmii.c +endif + +ifeq (linux, $(OS)) + ifeq (KSLIB, $(MODULE_TYPE)) + ifneq (TRUE, $(KERNEL_MODE)) + SRC_LIST=dess_reg_access.c dess_init.c + endif + endif +endif + +ifeq (, $(findstring DESS, $(SUPPORT_CHIP))) + SRC_LIST= +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/src/src/hsl/dess/dess_acl.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_acl.c new file mode 100755 index 000000000..9783ac4ad --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_acl.c @@ -0,0 +1,2039 @@ +/* + * 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. + */ + + +/** + * @defgroup dess_acl DESS_ACL + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_acl.h" +#include "dess_acl.h" +#include "dess_reg.h" +#include "dess_acl_prv.h" + +//#define DESS_ACL_DEBUG +//#define DESS_SW_ENTRY +#define DESS_HW_ENTRY + +static dess_acl_list_t *sw_list_ent[SW_MAX_NR_DEV]; +static dess_acl_rule_t *sw_rule_ent[SW_MAX_NR_DEV]; + +static dess_acl_rule_t *sw_rule_tmp[SW_MAX_NR_DEV]; +static dess_acl_rule_t *hw_rule_tmp[SW_MAX_NR_DEV]; +#ifdef DESS_SW_ENTRY +static a_uint8_t *sw_filter_mem = NULL; +#endif + +static sw_error_t +_dess_filter_valid_set(a_uint32_t dev_id, a_uint32_t flt_idx, a_uint32_t flag); + +#ifndef DESS_SW_ENTRY +#ifndef DESS_HW_ENTRY +static sw_error_t +_dess_filter_ports_bind(a_uint32_t dev_id, a_uint32_t flt_idx, + a_uint32_t ports); + +static sw_error_t +_dess_filter_write(a_uint32_t dev_id, a_uint32_t reg[], a_uint32_t flt_idx, + a_uint32_t op); +#endif +#endif + +//static sw_error_t +//_dess_filter_read(a_uint32_t dev_id, a_uint32_t reg[], a_uint32_t flt_idx, +// a_uint32_t op); + +static sw_error_t +_dess_filter_down_to_hw(a_uint32_t dev_id, hw_filter_t * filter, + a_uint32_t flt_idx); + +static sw_error_t +_dess_filter_up_to_sw(a_uint32_t dev_id, hw_filter_t * filter, + a_uint32_t flt_idx); + +static sw_error_t +_dess_acl_rule_src_filter_sts_set(a_uint32_t dev_id, + a_uint32_t rule_id, a_bool_t enable); + +static void +_dess_acl_list_dump(a_uint32_t dev_id) +{ + a_uint32_t i; + dess_acl_list_t *sw_list; + + aos_printk("\ndev_id=%d list control infomation:", dev_id); + for (i = 0; i < DESS_MAX_FILTER; i++) + { + sw_list = &(sw_list_ent[dev_id][i]); + if (ENT_USED & sw_list->status) + { + aos_printk + ("\nlist_id=%02d list_pri=%02d rule_nr=%02d [pts_map]:0x%02x idx=%02d ", + sw_list->list_id, sw_list->list_pri, sw_list->rule_nr, + sw_list->bind_pts, i); + } + } + aos_printk("\n"); +} + +static void +_dess_acl_sw_rule_dump(char *info, dess_acl_rule_t * sw_rule) +{ +#ifdef DESS_ACL_DEBUG + a_uint32_t flt_idx, i; + + aos_printk("\n%s", info); + for (flt_idx = 0; flt_idx < DESS_MAX_FILTER; flt_idx++) + { + aos_printk("\n%d software filter:", flt_idx); + aos_printk("\nact:"); + for (i = 0; i < 3; i++) + { + aos_printk("%08x ", sw_rule[flt_idx].filter.act[i]); + } + + aos_printk("\nvlu:"); + for (i = 0; i < 5; i++) + { + aos_printk("%08x ", sw_rule[flt_idx].filter.vlu[i]); + } + + aos_printk("\nmsk:"); + for (i = 0; i < 5; i++) + { + aos_printk("%08x ", sw_rule[flt_idx].filter.msk[i]); + } + + aos_printk("\nctl:status[%02d] list_id[%02d] rule_id[%02d]", + sw_rule[flt_idx].status, + sw_rule[flt_idx].list_id, sw_rule[flt_idx].rule_id); + + aos_printk("\n\n"); + } +#else + return; +#endif +} + +static dess_acl_list_t * +_dess_acl_list_loc(a_uint32_t dev_id, a_uint32_t list_id) +{ + a_uint32_t i; + + for (i = 0; i < DESS_MAX_FILTER; i++) + { + if ((ENT_USED & sw_list_ent[dev_id][i].status) + && (list_id == sw_list_ent[dev_id][i].list_id)) + { + return &(sw_list_ent[dev_id][i]); + } + } + return NULL; +} + +static sw_error_t +_dess_filter_valid_set(a_uint32_t dev_id, a_uint32_t flt_idx, a_uint32_t flag) +{ +#ifdef DESS_SW_ENTRY + hw_filter_t filter; + + _dess_filter_up_to_sw(dev_id, &filter, flt_idx); + + filter.msk[4] &= 0xfffffff8; + filter.msk[4] |= (flag & 0x7); + + _dess_filter_down_to_hw(dev_id, &filter, flt_idx); + + return SW_OK; +#else +#ifdef DESS_HW_ENTRY + hw_filter_t filter; + + filter = sw_rule_ent[dev_id][flt_idx].filter; + + filter.msk[4] &= 0xfffffff8; + filter.msk[4] |= (flag & 0x7); + + _dess_filter_down_to_hw(dev_id, &filter, flt_idx); + return SW_OK; +#else + sw_error_t rv; + a_uint32_t addr, data = 0; + + /* read filter mask at first */ + addr = DESS_RULE_FUNC_ADDR; + data = (flt_idx & 0x7f) | (0x1 << 8) | (0x1 << 10) | (0x1 << 31); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* get filter mask and modify it */ + addr = DESS_RULE_FUNC_ADDR + 20; + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data &= 0xfffffff8; + data |= (flag & 0x7); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* write back filter mask */ + addr = DESS_RULE_FUNC_ADDR; + data = (flt_idx & 0x7f) | (0x1 << 8) | (0x1 << 31); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +#endif +#endif +} + +static sw_error_t +_dess_filter_ports_bind(a_uint32_t dev_id, a_uint32_t flt_idx, a_uint32_t ports) +{ +#ifdef DESS_SW_ENTRY + hw_filter_t filter; + + _dess_filter_up_to_sw(dev_id, &filter, flt_idx); + + filter.vlu[4] &= 0xffffff80; + filter.vlu[4] |= (ports & 0x7f); + + _dess_filter_down_to_hw(dev_id, &filter, flt_idx); + + return SW_OK; +#else +#ifdef DESS_HW_ENTRY + hw_filter_t filter; + + filter = sw_rule_ent[dev_id][flt_idx].filter; + + filter.vlu[4] &= 0xffffff80; + filter.vlu[4] |= (ports & 0x7f); + + _dess_filter_down_to_hw(dev_id, &filter, flt_idx); + + return SW_OK; +#else + sw_error_t rv; + a_uint32_t addr, data; + + /* read filter value at first */ + addr = DESS_RULE_FUNC_ADDR; + data = (flt_idx & 0x7f) | (0x1 << 10) | (0x1 << 31); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* get filter value and modify it */ + addr = DESS_RULE_FUNC_ADDR + 20; + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data &= 0xffffff80; + data |= (ports & 0x7f); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* write back filter value */ + addr = DESS_RULE_FUNC_ADDR; + data = (flt_idx & 0x7f) | (0x1 << 31); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +#endif +#endif +} + +#ifndef DESS_SW_ENTRY +#ifndef DESS_HW_ENTRY +static sw_error_t +_dess_filter_write(a_uint32_t dev_id, a_uint32_t reg[], a_uint32_t flt_idx, + a_uint32_t op) +{ + a_uint32_t i, addr, data, idx = 6; + sw_error_t rv; + + if (DESS_FILTER_ACT_OP == op) + { + idx = 4; + } + + for (i = 1; i < idx; i++) + { + addr = DESS_RULE_FUNC_ADDR + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(reg[i - 1])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + addr = DESS_RULE_FUNC_ADDR; + data = (flt_idx & 0x7f) | (op << 8) | (0x1 << 31); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_dess_filter_read(a_uint32_t dev_id, a_uint32_t reg[], a_uint32_t flt_idx, + a_uint32_t op) +{ + a_uint32_t i, addr, data, idx = 6; + sw_error_t rv; + + addr = DESS_RULE_FUNC_ADDR; + data = (flt_idx & 0x7f) | (op << 8) | (0x1 << 10) | (0x1 << 31); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (DESS_FILTER_ACT_OP == op) + { + idx = 4; + } + + for (i = 1; i < idx; i++) + { + addr = DESS_RULE_FUNC_ADDR + (i << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(reg[i - 1])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} +#endif +#endif + +static sw_error_t +_dess_filter_down_to_hw(a_uint32_t dev_id, hw_filter_t * filter, + a_uint32_t flt_idx) +{ +#ifdef DESS_SW_ENTRY + a_uint8_t *tbl = sw_filter_mem + sizeof (hw_filter_t) * flt_idx; + + aos_mem_copy(tbl, filter, sizeof (hw_filter_t)); +#else +#ifdef DESS_HW_ENTRY + sw_error_t rv; + a_uint32_t i, base, addr; + + base = DESS_FILTER_ACT_ADDR + (flt_idx << 4); + for (i = 0; i < 3; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(filter->act[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + base = DESS_FILTER_VLU_ADDR + (flt_idx << 5); + for (i = 0; i < 5; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(filter->vlu[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + base = DESS_FILTER_MSK_ADDR + (flt_idx << 5); + for (i = 0; i < 5; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(filter->msk[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } +#else + sw_error_t rv; + + rv = _dess_filter_write(dev_id, &(filter->act[0]), flt_idx, + DESS_FILTER_ACT_OP); + SW_RTN_ON_ERROR(rv); + + rv = _dess_filter_write(dev_id, &(filter->vlu[0]), flt_idx, + DESS_FILTER_VLU_OP); + SW_RTN_ON_ERROR(rv); + + rv = _dess_filter_write(dev_id, &(filter->msk[0]), flt_idx, + DESS_FILTER_MSK_OP); + SW_RTN_ON_ERROR(rv); +#endif +#endif + + return SW_OK; +} + +static sw_error_t +_dess_filter_up_to_sw(a_uint32_t dev_id, hw_filter_t * filter, + a_uint32_t flt_idx) +{ +#ifdef DESS_SW_ENTRY + a_uint8_t *tbl = sw_filter_mem + sizeof (hw_filter_t) * flt_idx; + + aos_mem_copy(filter, tbl, sizeof (hw_filter_t)); +#else +#ifdef DESS_HW_ENTRY + sw_error_t rv; + a_uint32_t i, base, addr; + + base = DESS_FILTER_VLU_ADDR + (flt_idx << 5); + for (i = 0; i < 5; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(filter->vlu[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + base = DESS_FILTER_MSK_ADDR + (flt_idx << 5); + for (i = 0; i < 5; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(filter->msk[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + base = DESS_FILTER_ACT_ADDR + (flt_idx << 4); + for (i = 0; i < 3; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(filter->act[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } +#else + sw_error_t rv; + + rv = _dess_filter_read(dev_id, &(filter->vlu[0]), flt_idx, + DESS_FILTER_VLU_OP); + SW_RTN_ON_ERROR(rv); + + rv = _dess_filter_read(dev_id, &(filter->msk[0]), flt_idx, + DESS_FILTER_MSK_OP); + SW_RTN_ON_ERROR(rv); + + rv = _dess_filter_read(dev_id, &(filter->act[0]), flt_idx, + DESS_FILTER_ACT_OP); + SW_RTN_ON_ERROR(rv); +#endif +#endif + + return SW_OK; +} + +static sw_error_t +_dess_acl_list_insert(a_uint32_t dev_id, a_uint32_t * src_idx, + a_uint32_t * dst_idx, dess_acl_rule_t * src_rule, + dess_acl_rule_t * dst_rule) +{ + a_uint32_t i, data, rule_id, list_id, list_pri; + + rule_id = 0; + list_id = src_rule[*src_idx].list_id; + list_pri = src_rule[*src_idx].list_pri; + + for (i = *src_idx; i < DESS_MAX_FILTER; i++) + { + if (!(ENT_USED & src_rule[i].status)) + { + continue; // was: break; + } + + if (src_rule[i].list_id != list_id) + { + break; + } + + SW_GET_FIELD_BY_REG(MAC_RUL_M4, RULE_TYP, data, + src_rule[i].filter.msk[4]); + if (!data) + { + continue; + } + + if (DESS_MAX_FILTER <= *dst_idx) + { + return SW_NO_RESOURCE; + } + + if (ENT_USED & dst_rule[*dst_idx].status) + { + return SW_NO_RESOURCE; + } + + SW_GET_FIELD_BY_REG(MAC_RUL_M4, RULE_VALID, data, + src_rule[i].filter.msk[4]); + if ((FLT_START == data) && (*dst_idx % 2)) + { + if (*src_idx != i) + { + dst_rule[*dst_idx].src_flt_dis = src_rule[i].src_flt_dis; + dst_rule[*dst_idx].list_id = list_id; + dst_rule[*dst_idx].list_pri = list_pri; + dst_rule[*dst_idx].rule_id = rule_id - 1; + dst_rule[*dst_idx].status |= ENT_USED; + } + + (*dst_idx)++; + if (DESS_MAX_FILTER <= *dst_idx) + { + return SW_NO_RESOURCE; + } + + if (ENT_USED & dst_rule[*dst_idx].status) + { + return SW_NO_RESOURCE; + } + } + + aos_mem_copy(&(dst_rule[*dst_idx].filter), &(src_rule[i].filter), + sizeof (hw_filter_t)); + dst_rule[*dst_idx].src_flt_dis = src_rule[i].src_flt_dis; + dst_rule[*dst_idx].list_id = list_id; + dst_rule[*dst_idx].list_pri = list_pri; + dst_rule[*dst_idx].rule_id = rule_id; + dst_rule[*dst_idx].status |= ENT_USED; + if (ENT_DEACTIVE & src_rule[i].status) + { + dst_rule[*dst_idx].status |= ENT_DEACTIVE; + } + (*dst_idx)++; + + if ((FLT_END == data) && (*dst_idx % 2)) + { + if (DESS_MAX_FILTER > *dst_idx) + { + dst_rule[*dst_idx].src_flt_dis = src_rule[i].src_flt_dis; + dst_rule[*dst_idx].list_id = list_id; + dst_rule[*dst_idx].list_pri = list_pri; + dst_rule[*dst_idx].rule_id = rule_id; + dst_rule[*dst_idx].status |= ENT_USED; + (*dst_idx)++; + } + } + + if ((FLT_END == data) || (FLT_STARTEND == data)) + { + rule_id++; + } + } + + *src_idx = i; + return SW_OK; +} + +static sw_error_t +_dess_acl_rule_alloc(a_uint32_t dev_id, dess_acl_list_t * sw_list, + a_uint32_t filter_nr) +{ + a_uint32_t free_flt_nr, load_idx, begin_idx, start_idx, end_idx, i; + a_uint32_t largest_nr, largest_idx; + sw_error_t rv; + + /* calculate the proper location, [start_idx, end_idx) */ + start_idx = 0; + end_idx = DESS_MAX_FILTER; + for (i = 0; i < DESS_MAX_FILTER; i++) + { + if (ENT_USED & sw_rule_ent[dev_id][i].status) + { + if (sw_rule_ent[dev_id][i].list_pri < sw_list->list_pri) + { + start_idx = i + 1; + } + else if (sw_rule_ent[dev_id][i].list_pri > sw_list->list_pri) + { + end_idx = i; + break; + } + } + } + + /* find the larget free filters block */ + largest_nr = 0; + largest_idx = 0; + free_flt_nr = 0; + begin_idx = start_idx; + for (i = start_idx; i < end_idx; i++) + { + if (!(ENT_USED & sw_rule_ent[dev_id][i].status)) + { + free_flt_nr++; + } + else + { + if (free_flt_nr > largest_nr) + { + largest_nr = free_flt_nr; + largest_idx = begin_idx; + } + free_flt_nr = 0; + begin_idx = i + 1; + } + } + + if (free_flt_nr > largest_nr) + { + largest_nr = free_flt_nr; + largest_idx = begin_idx; + } + + if ((!largest_nr) || ((largest_nr + 1) < filter_nr)) + { + return SW_NO_RESOURCE; + } + + for (i = 0; i < DESS_MAX_FILTER; i++) + { + if (ENT_USED & sw_rule_ent[dev_id][i].status) + { + aos_mem_copy(&(sw_rule_tmp[dev_id][i]), &(sw_rule_ent[dev_id][i]), + sizeof (dess_acl_rule_t)); + } + } + + begin_idx = 0; + load_idx = largest_idx; + rv = _dess_acl_list_insert(dev_id, &begin_idx, &load_idx, + hw_rule_tmp[dev_id], sw_rule_tmp[dev_id]); + return rv; +} + +static sw_error_t +_dess_acl_rule_reorder(a_uint32_t dev_id, dess_acl_list_t * sw_list) +{ + a_uint32_t i, src_idx, dst_idx; + sw_error_t rv; + + dst_idx = 0; + for (i = 0; i < DESS_MAX_FILTER;) + { + if (ENT_USED & sw_rule_ent[dev_id][i].status) + { + if (sw_rule_ent[dev_id][i].list_pri <= sw_list->list_pri) + { + rv = _dess_acl_list_insert(dev_id, &i, &dst_idx, + sw_rule_ent[dev_id], + sw_rule_tmp[dev_id]); + SW_RTN_ON_ERROR(rv); + } + else + { + break; + } + } + else + { + i++; + } + } + + src_idx = 0; + rv = _dess_acl_list_insert(dev_id, &src_idx, &dst_idx, hw_rule_tmp[dev_id], + sw_rule_tmp[dev_id]); + SW_RTN_ON_ERROR(rv); + + for (; i < DESS_MAX_FILTER;) + { + if (ENT_USED & sw_rule_ent[dev_id][i].status) + { + rv = _dess_acl_list_insert(dev_id, &i, &dst_idx, + sw_rule_ent[dev_id], + sw_rule_tmp[dev_id]); + SW_RTN_ON_ERROR(rv); + } + else + { + i++; + } + } + + return SW_OK; +} + +static void +_dess_acl_rule_sync(a_uint32_t dev_id, a_uint32_t flt_idx, a_uint32_t flt_nr) +{ + a_uint32_t i, data; + + for (i = flt_idx; i < (flt_idx + flt_nr); i++) + { + if (aos_mem_cmp + (&(sw_rule_ent[dev_id][i]), &(sw_rule_tmp[dev_id][i]), + sizeof (dess_acl_rule_t))) + { + SW_GET_FIELD_BY_REG(MAC_RUL_M4, RULE_TYP, data, + sw_rule_tmp[dev_id][i].filter.msk[4]); + if (data) + { + _dess_filter_down_to_hw(dev_id, + &(sw_rule_tmp[dev_id][i].filter), i); + } + else + { + _dess_filter_valid_set(dev_id, i, 0); + } + + aos_mem_copy(&(sw_rule_ent[dev_id][i]), &(sw_rule_tmp[dev_id][i]), + sizeof (dess_acl_rule_t)); + _dess_acl_rule_src_filter_sts_set(dev_id, i, + !sw_rule_tmp[dev_id][i].src_flt_dis); + } + } +} + +static sw_error_t +_dess_acl_list_creat(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t list_pri) +{ + a_uint32_t i, loc = DESS_MAX_FILTER; + dess_acl_list_t *sw_list; + + HSL_DEV_ID_CHECK(dev_id); + + if ((DESS_MAX_LIST_ID < list_id) || (DESS_MAX_LIST_PRI < list_pri)) + { + return SW_NOT_SUPPORTED; + } + + for (i = 0; i < DESS_MAX_FILTER; i++) + { + sw_list = &(sw_list_ent[dev_id][i]); + if (ENT_USED & sw_list->status) + { + if (list_id == sw_list->list_id) + { + return SW_ALREADY_EXIST; + } + } + else + { + loc = i; + } + } + + if (DESS_MAX_FILTER == loc) + { + return SW_NO_RESOURCE; + } + + sw_list = &(sw_list_ent[dev_id][loc]); + aos_mem_zero(sw_list, sizeof (dess_acl_list_t)); + sw_list->list_id = list_id; + sw_list->list_pri = list_pri; + sw_list->status |= ENT_USED; + return SW_OK; +} + +static sw_error_t +_dess_acl_list_destroy(a_uint32_t dev_id, a_uint32_t list_id) +{ + dess_acl_list_t *sw_list; + + HSL_DEV_ID_CHECK(dev_id); + + if (DESS_MAX_LIST_ID < list_id) + { + return SW_NOT_SUPPORTED; + } + + sw_list = _dess_acl_list_loc(dev_id, list_id); + if (NULL == sw_list) + { + return SW_NOT_FOUND; + } + + if (0 != sw_list->bind_pts) + { + return SW_NOT_SUPPORTED; + } + + if (0 != sw_list->rule_nr) + { + return SW_NOT_SUPPORTED; + } + + aos_mem_zero(sw_list, sizeof (dess_acl_list_t)); + return SW_OK; +} + +static sw_error_t +_dess_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; + dess_acl_list_t *sw_list; + dess_acl_rule_t *sw_rule; + a_uint32_t i, free_flt_nr, old_flt_nr, old_flt_idx, new_flt_nr, bind_pts; + + HSL_DEV_ID_CHECK(dev_id); + + if (DESS_MAX_LIST_ID < list_id) + { + return SW_NOT_SUPPORTED; + } + + if ((0 == rule_nr) || (NULL == rule)) + { + return SW_BAD_PARAM; + } + + sw_list = _dess_acl_list_loc(dev_id, list_id); + if (NULL == sw_list) + { + return SW_NOT_FOUND; + } + + if (rule_id != sw_list->rule_nr) + { + return SW_BAD_PARAM; + } + + old_flt_idx = 0; + old_flt_nr = 0; + free_flt_nr = 0; + aos_mem_zero(hw_rule_tmp[dev_id], + DESS_HW_RULE_TMP_CNT * sizeof (dess_acl_rule_t)); + aos_mem_zero(sw_rule_tmp[dev_id], + DESS_MAX_FILTER * sizeof (dess_acl_rule_t)); + for (i = 0; i < DESS_MAX_FILTER; i++) + { + sw_rule = &(sw_rule_ent[dev_id][i]); + if (ENT_USED & sw_rule->status) + { + if (sw_rule->list_id == sw_list->list_id) + { + aos_mem_copy(&(hw_rule_tmp[dev_id][old_flt_nr]), sw_rule, + sizeof (dess_acl_rule_t)); + if (!old_flt_nr) + { + old_flt_idx = i; + } + old_flt_nr++; + } + } + else + { + free_flt_nr++; + } + } + + if (!free_flt_nr) + { + return SW_NO_RESOURCE; + } + + /* parse rule entry and alloc rule resource */ + new_flt_nr = old_flt_nr; + for (i = 0; i < rule_nr; i++) + { + rv = _dess_acl_rule_sw_to_hw(dev_id, &rule[i], hw_rule_tmp[dev_id], + &new_flt_nr); + SW_RTN_ON_ERROR(rv); + } + + if (free_flt_nr < (new_flt_nr - old_flt_nr)) + { + return SW_NO_RESOURCE; + } + + for (i = old_flt_nr; i < new_flt_nr; i++) + { + hw_rule_tmp[dev_id][i].status |= ENT_USED; + hw_rule_tmp[dev_id][i].list_id = sw_list->list_id; + hw_rule_tmp[dev_id][i].list_pri = sw_list->list_pri; + bind_pts = sw_list->bind_pts; + SW_SET_REG_BY_FIELD(MAC_RUL_V4, SRC_PT, bind_pts, + (hw_rule_tmp[dev_id][i].filter.vlu[4])); + } + + for (i = 0; i < old_flt_nr; i++) + { + sw_rule = &(sw_rule_ent[dev_id][old_flt_idx + i]); + sw_rule->status &= (~ENT_USED); + sw_rule->status |= (ENT_TMP); + } + + rv = _dess_acl_rule_alloc(dev_id, sw_list, new_flt_nr); + if (SW_OK != rv) + { + aos_mem_zero(sw_rule_tmp[dev_id], + DESS_MAX_FILTER * sizeof (dess_acl_rule_t)); + rv = _dess_acl_rule_reorder(dev_id, sw_list); + } + + for (i = 0; i < old_flt_nr; i++) + { + sw_rule = &(sw_rule_ent[dev_id][i + old_flt_idx]); + sw_rule->status |= (ENT_USED); + sw_rule->status &= (~ENT_TMP); + } + SW_RTN_ON_ERROR(rv); + + _dess_acl_rule_sync(dev_id, 0, DESS_MAX_FILTER); + sw_list->rule_nr += rule_nr; + + _dess_acl_sw_rule_dump("sw rule after add", sw_rule_ent[dev_id]); + return SW_OK; +} + +static sw_error_t +_dess_acl_rule_delete(a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t rule_id, a_uint32_t rule_nr) +{ + dess_acl_rule_t *sw_rule; + dess_acl_list_t *sw_list; + a_uint32_t i, flt_idx = 0, src_idx, dst_idx, del_nr = 0, flt_nr = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (DESS_MAX_LIST_ID < list_id) + { + return SW_NOT_SUPPORTED; + } + + sw_list = _dess_acl_list_loc(dev_id, list_id); + if (NULL == sw_list) + { + return SW_NOT_FOUND; + } + + if (sw_list->rule_nr < (rule_id + rule_nr)) + { + return SW_BAD_PARAM; + } + + aos_mem_zero(hw_rule_tmp[dev_id], + DESS_HW_RULE_TMP_CNT * sizeof (dess_acl_rule_t)); + aos_mem_zero(sw_rule_tmp[dev_id], + DESS_MAX_FILTER * sizeof (dess_acl_rule_t)); + + for (i = 0; i < DESS_MAX_FILTER; i++) + { + sw_rule = &(sw_rule_ent[dev_id][i]); + if ((ENT_USED & sw_rule->status) && (sw_rule->list_id == list_id)) + { + if (!flt_nr) + { + flt_idx = i; + } + + if ((sw_rule->rule_id >= rule_id) + && (sw_rule->rule_id < (rule_id + rule_nr))) + { + del_nr++; + } + else + { + aos_mem_copy(&(hw_rule_tmp[dev_id][flt_idx + flt_nr]), sw_rule, + sizeof (dess_acl_rule_t)); + } + flt_nr++; + } + } + + if (!del_nr) + { + return SW_NOT_FOUND; + } + + _dess_acl_sw_rule_dump("hw rule before del", hw_rule_tmp[dev_id]); + + for (i = 0; i < flt_nr; i++) + { + sw_rule = &(hw_rule_tmp[dev_id][flt_idx + i]); + if (ENT_USED & sw_rule->status) + { + break; + } + } + + if (i != flt_nr) + { + src_idx = flt_idx + i; + dst_idx = flt_idx; + rv = _dess_acl_list_insert(dev_id, &src_idx, &dst_idx, + hw_rule_tmp[dev_id], sw_rule_tmp[dev_id]); + SW_RTN_ON_ERROR(rv); + } + + _dess_acl_rule_sync(dev_id, flt_idx, flt_nr); + sw_list->rule_nr -= rule_nr; + + _dess_acl_sw_rule_dump("sw rule after del", sw_rule_ent[dev_id]); + return SW_OK; +} + +static sw_error_t +_dess_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; + dess_acl_rule_t *sw_rule; + a_uint32_t flt_nr = 0, i; + + HSL_DEV_ID_CHECK(dev_id); + + if (DESS_MAX_LIST_ID < list_id) + { + return SW_NOT_SUPPORTED; + } + + aos_mem_zero(hw_rule_tmp[dev_id], + DESS_HW_RULE_TMP_CNT * sizeof (dess_acl_rule_t)); + for (i = 0; i < DESS_MAX_FILTER; i++) + { + sw_rule = &(sw_rule_ent[dev_id][i]); + if (ENT_USED & sw_rule->status) + { + if ((sw_rule->list_id == list_id) && (sw_rule->rule_id == rule_id)) + { + aos_mem_copy(&(hw_rule_tmp[dev_id][flt_nr]), sw_rule, + sizeof (dess_acl_rule_t)); + flt_nr++; + } + } + } + + if (!flt_nr) + { + return SW_NOT_FOUND; + } + + aos_mem_zero(rule, sizeof (fal_acl_rule_t)); + rv = _dess_acl_rule_hw_to_sw(dev_id, rule, hw_rule_tmp[dev_id], 0, flt_nr); + return rv; +} + +static sw_error_t +_dess_acl_rule_bind(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t ports) +{ + sw_error_t rv; + a_uint32_t i; + dess_acl_rule_t *sw_rule; + + for (i = 0; i < DESS_MAX_FILTER; i++) + { + sw_rule = &(sw_rule_ent[dev_id][i]); + + if ((ENT_USED & sw_rule->status) + && (list_id == sw_rule->list_id) + && (!(ENT_DEACTIVE & sw_rule->status))) + { + rv = _dess_filter_ports_bind(dev_id, i, ports); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(MAC_RUL_V4, SRC_PT, ports, + (sw_rule->filter.vlu[4])); + } + } + + return SW_OK; +} + +static sw_error_t +_dess_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; + a_uint32_t ports; + dess_acl_list_t *sw_list; + + HSL_DEV_ID_CHECK(dev_id); + + if (DESS_MAX_LIST_ID < list_id) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_ACL_DIREC_IN != direc) + { + return SW_NOT_SUPPORTED; + } + + sw_list = _dess_acl_list_loc(dev_id, list_id); + if (NULL == sw_list) + { + return SW_NOT_FOUND; + } + + if (FAL_ACL_BIND_PORT == obj_t) + { + ports = (sw_list->bind_pts) | (0x1 << obj_idx); + } + else if (FAL_ACL_BIND_PORTBITMAP == obj_t) + { + ports = (sw_list->bind_pts) | obj_idx; + } + else + { + return SW_NOT_SUPPORTED; + } + + rv = _dess_acl_rule_bind(dev_id, list_id, ports); + SW_RTN_ON_ERROR(rv); + + sw_list->bind_pts = ports; + return SW_OK; +} + +static sw_error_t +_dess_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; + a_uint32_t ports; + dess_acl_list_t *sw_list; + + HSL_DEV_ID_CHECK(dev_id); + + if (DESS_MAX_LIST_ID < list_id) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_ACL_DIREC_IN != direc) + { + return SW_NOT_SUPPORTED; + } + + sw_list = _dess_acl_list_loc(dev_id, list_id); + if (NULL == sw_list) + { + return SW_NOT_FOUND; + } + + if (FAL_ACL_BIND_PORT == obj_t) + { + ports = (sw_list->bind_pts) & (~(0x1UL << obj_idx)); + } + else if (FAL_ACL_BIND_PORTBITMAP == obj_t) + { + ports = (sw_list->bind_pts) & (~obj_idx); + } + else + { + return SW_NOT_SUPPORTED; + } + + rv = _dess_acl_rule_bind(dev_id, list_id, ports); + SW_RTN_ON_ERROR(rv); + + sw_list->bind_pts = ports; + return SW_OK; +} + +static sw_error_t +_dess_acl_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, MOD_ENABLE, 0, ACL_EN, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_acl_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, MOD_ENABLE, 0, ACL_EN, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_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; + a_uint32_t reg = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (DESS_UDF_MAX_OFFSET < offset) + { + return SW_BAD_PARAM; + } + + if (DESS_UDF_MAX_OFFSET < length) + { + return SW_BAD_PARAM; + } + + if ((FAL_ACL_UDF_TYPE_L2_SNAP == udf_type) + || (FAL_ACL_UDF_TYPE_L3_PLUS == udf_type)) + { + HSL_REG_ENTRY_GET(rv, dev_id, WIN_RULE_CTL1, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + HSL_REG_ENTRY_GET(rv, dev_id, WIN_RULE_CTL0, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + SW_RTN_ON_ERROR(rv); + + switch (udf_type) + { + case FAL_ACL_UDF_TYPE_L2: + SW_SET_REG_BY_FIELD(WIN_RULE_CTL0, L2_OFFSET, offset, reg); + SW_SET_REG_BY_FIELD(WIN_RULE_CTL0, L2_LENGTH, length, reg); + break; + case FAL_ACL_UDF_TYPE_L3: + SW_SET_REG_BY_FIELD(WIN_RULE_CTL0, L3_OFFSET, offset, reg); + SW_SET_REG_BY_FIELD(WIN_RULE_CTL0, L3_LENGTH, length, reg); + break; + case FAL_ACL_UDF_TYPE_L4: + SW_SET_REG_BY_FIELD(WIN_RULE_CTL0, L4_OFFSET, offset, reg); + SW_SET_REG_BY_FIELD(WIN_RULE_CTL0, L4_LENGTH, length, reg); + break; + case FAL_ACL_UDF_TYPE_L2_SNAP: + SW_SET_REG_BY_FIELD(WIN_RULE_CTL1, L2S_OFFSET, offset, reg); + SW_SET_REG_BY_FIELD(WIN_RULE_CTL1, L2S_LENGTH, length, reg); + break; + case FAL_ACL_UDF_TYPE_L3_PLUS: + SW_SET_REG_BY_FIELD(WIN_RULE_CTL1, L3P_OFFSET, offset, reg); + SW_SET_REG_BY_FIELD(WIN_RULE_CTL1, L3P_LENGTH, length, reg); + break; + default: + return SW_BAD_PARAM; + } + + if ((FAL_ACL_UDF_TYPE_L2_SNAP == udf_type) + || (FAL_ACL_UDF_TYPE_L3_PLUS == udf_type)) + { + HSL_REG_ENTRY_SET(rv, dev_id, WIN_RULE_CTL1, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + HSL_REG_ENTRY_SET(rv, dev_id, WIN_RULE_CTL0, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + + return rv; +} + +static sw_error_t +_dess_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; + a_uint32_t reg = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if ((FAL_ACL_UDF_TYPE_L2_SNAP == udf_type) + || (FAL_ACL_UDF_TYPE_L3_PLUS == udf_type)) + { + HSL_REG_ENTRY_GET(rv, dev_id, WIN_RULE_CTL1, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + HSL_REG_ENTRY_GET(rv, dev_id, WIN_RULE_CTL0, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + SW_RTN_ON_ERROR(rv); + + switch (udf_type) + { + case FAL_ACL_UDF_TYPE_L2: + SW_GET_FIELD_BY_REG(WIN_RULE_CTL0, L2_OFFSET, (*offset), reg); + SW_GET_FIELD_BY_REG(WIN_RULE_CTL0, L2_LENGTH, (*length), reg); + break; + case FAL_ACL_UDF_TYPE_L3: + SW_GET_FIELD_BY_REG(WIN_RULE_CTL0, L3_OFFSET, (*offset), reg); + SW_GET_FIELD_BY_REG(WIN_RULE_CTL0, L3_LENGTH, (*length), reg); + break; + case FAL_ACL_UDF_TYPE_L4: + SW_GET_FIELD_BY_REG(WIN_RULE_CTL0, L4_OFFSET, (*offset), reg); + SW_GET_FIELD_BY_REG(WIN_RULE_CTL0, L4_LENGTH, (*length), reg); + break; + case FAL_ACL_UDF_TYPE_L2_SNAP: + SW_GET_FIELD_BY_REG(WIN_RULE_CTL1, L2S_OFFSET, (*offset), reg); + SW_GET_FIELD_BY_REG(WIN_RULE_CTL1, L2S_LENGTH, (*length), reg); + break; + case FAL_ACL_UDF_TYPE_L3_PLUS: + SW_GET_FIELD_BY_REG(WIN_RULE_CTL1, L3P_OFFSET, (*offset), reg); + SW_GET_FIELD_BY_REG(WIN_RULE_CTL1, L3P_LENGTH, (*length), reg); + break; + default: + return SW_BAD_PARAM; + } + + return SW_OK; +} + +static sw_error_t +_dess_acl_rule_active(a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t rule_id, a_uint32_t rule_nr, a_bool_t active) +{ + sw_error_t rv; + a_uint32_t i, ports; + dess_acl_list_t *sw_list; + dess_acl_rule_t *sw_rule; + + HSL_DEV_ID_CHECK(dev_id); + + sw_list = _dess_acl_list_loc(dev_id, list_id); + if (NULL == sw_list) + { + return SW_NOT_FOUND; + } + + if (sw_list->rule_nr < (rule_id + rule_nr)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == active) + { + ports = (sw_list->bind_pts); + } + else + { + ports = 0; + } + + for (i = 0; i < DESS_MAX_FILTER; i++) + { + sw_rule = &(sw_rule_ent[dev_id][i]); + + if ((ENT_USED & sw_rule->status) + && (list_id == sw_rule->list_id) + && (rule_id <= sw_rule->rule_id) + && ((rule_id + rule_nr) > sw_rule->rule_id)) + { + rv = _dess_filter_ports_bind(dev_id, i, ports); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(MAC_RUL_V4, SRC_PT, ports, + (sw_rule->filter.vlu[4])); + + if (A_TRUE == active) + { + sw_rule->status &= (~ENT_DEACTIVE); + } + else + { + sw_rule->status |= (ENT_DEACTIVE); + } + } + } + + return SW_OK; +} + +static sw_error_t +_dess_acl_rule_src_filter_sts_set(a_uint32_t dev_id, + a_uint32_t rule_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t reg = 0, regIdx; + dess_acl_rule_t *sw_rule; + + HSL_DEV_ID_CHECK(dev_id); + + sw_rule = &sw_rule_ent[dev_id][rule_id]; + if (!(ENT_USED & sw_rule->status)) + { + return SW_NOT_FOUND; + } + + regIdx = rule_id >> 5; + + HSL_REG_ENTRY_GET(rv, dev_id, ACL_FWD_SRC_FILTER_CTL0, regIdx, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + reg |= (0x1 << (rule_id & 0x1F)); + sw_rule->src_flt_dis = 0; + } + else if (A_FALSE == enable) + { + reg &= ~(0x1 << (rule_id & 0x1F)); + sw_rule->src_flt_dis = 1; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_SET(rv, dev_id, ACL_FWD_SRC_FILTER_CTL0, regIdx, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_dess_acl_rule_src_filter_sts_get(a_uint32_t dev_id, + a_uint32_t rule_id, a_bool_t* enable) +{ + sw_error_t rv; + a_uint32_t reg = 0, regIdx; + dess_acl_rule_t *sw_rule; + + HSL_DEV_ID_CHECK(dev_id); + + sw_rule = &sw_rule_ent[dev_id][rule_id]; + if (!(ENT_USED & sw_rule->status)) + { + return SW_NOT_FOUND; + } + + regIdx = rule_id >> 5; + + HSL_REG_ENTRY_GET(rv, dev_id, ACL_FWD_SRC_FILTER_CTL0, regIdx, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (reg & (0x1 << (rule_id & 0x1F))) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return rv; +} + + +HSL_LOCAL sw_error_t +dess_acl_list_dump(a_uint32_t dev_id) +{ + _dess_acl_list_dump(dev_id); + return SW_OK; +} + +HSL_LOCAL sw_error_t +dess_acl_rule_dump(a_uint32_t dev_id) +{ + a_uint32_t flt_idx, i; + sw_error_t rv; + hw_filter_t filter; + + aos_printk("\ndess_acl_rule_dump:\n"); + + for (flt_idx = 0; flt_idx < DESS_MAX_FILTER; flt_idx++) + { + aos_mem_zero(&filter, sizeof (hw_filter_t)); + + rv = _dess_filter_up_to_sw(dev_id, &filter, flt_idx); + if (SW_OK != rv) + { + continue; + } + + aos_printk("\n%d filter dump:", flt_idx); + + aos_printk("\nhardware content:"); + aos_printk("\nact:"); + for (i = 0; i < (sizeof (filter.act) / sizeof (a_uint32_t)); i++) + { + aos_printk("%08x ", filter.act[i]); + } + + aos_printk("\nvlu:"); + for (i = 0; i < (sizeof (filter.vlu) / sizeof (a_uint32_t)); i++) + { + aos_printk("%08x ", filter.vlu[i]); + } + + aos_printk("\nmsk:"); + for (i = 0; i < (sizeof (filter.msk) / sizeof (a_uint32_t)); i++) + { + aos_printk("%08x ", filter.msk[i]); + } + + aos_printk("\nsoftware content:"); + aos_printk("\nact:"); + for (i = 0; i < (sizeof (filter.act) / sizeof (a_uint32_t)); i++) + { + aos_printk("%08x ", sw_rule_ent[dev_id][flt_idx].filter.act[i]); + } + + aos_printk("\nvlu:"); + for (i = 0; i < (sizeof (filter.vlu) / sizeof (a_uint32_t)); i++) + { + aos_printk("%08x ", sw_rule_ent[dev_id][flt_idx].filter.vlu[i]); + } + + aos_printk("\nmsk:"); + for (i = 0; i < (sizeof (filter.msk) / sizeof (a_uint32_t)); i++) + { + aos_printk("%08x ", sw_rule_ent[dev_id][flt_idx].filter.msk[i]); + } + + aos_printk("\nctl:status[%02d] list_id[%02d] rule_id[%02d] src_flt_dis[%02d]", + sw_rule_ent[dev_id][flt_idx].status, + sw_rule_ent[dev_id][flt_idx].list_id, + sw_rule_ent[dev_id][flt_idx].rule_id, + sw_rule_ent[dev_id][flt_idx].src_flt_dis); + + aos_printk("\n\n"); + } + + return SW_OK; +} + +sw_error_t +dess_acl_reset(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + + aos_mem_zero(sw_list_ent[dev_id], + DESS_MAX_FILTER * sizeof (dess_acl_list_t)); + + aos_mem_zero(sw_rule_ent[dev_id], + DESS_MAX_FILTER * sizeof (dess_acl_rule_t)); + + return SW_OK; +} + +/** + * @brief Creat an acl list + * @details Comments: + * If the value of list_pri is more small then the priority is more high, + * that means the list could be first matched. + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] list_pri acl list priority + * @return SW_OK or error code + */ +sw_error_t +dess_acl_list_creat(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t list_pri) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_acl_list_creat(dev_id, list_id, list_pri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Destroy an acl list + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_acl_list_destroy(a_uint32_t dev_id, a_uint32_t list_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_acl_list_destroy(dev_id, list_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add one rule or more rules to an existing acl list + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] rule_id first rule id of this adding operation in list + * @param[in] rule_nr rule number of this adding operation + * @param[in] rule rules content of this adding operation + * @return SW_OK or error code + */ +sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_acl_rule_add(dev_id, list_id, rule_id, rule_nr, rule); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete one rule or more rules from an existing acl list + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] rule_id first rule id of this deleteing operation in list + * @param[in] rule_nr rule number of this deleteing operation + * @return SW_OK or error code + */ +sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_acl_rule_delete(dev_id, list_id, rule_id, rule_nr); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Query one particular rule in a particular acl list + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] rule_id first rule id of this deleteing operation in list + * @param[out] rule rule content of this operation + * @return SW_OK or error code + */ +sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_acl_rule_query(dev_id, list_id, rule_id, rule); + HSL_API_UNLOCK; + return rv; +} + +a_uint32_t +dess_acl_rule_get_offset(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t rule_id) +{ + a_uint32_t i, pos=0; + dess_acl_rule_t *sw_rule; + + for (i = 0; i < DESS_MAX_FILTER; i++) + { + sw_rule = &(sw_rule_ent[0][i]); + + if ((ENT_USED & sw_rule->status) + && (list_id == sw_rule->list_id) && (sw_rule->rule_id == rule_id) + && (!(ENT_DEACTIVE & sw_rule->status))) + { + pos = i; + break; + + } + } + + return pos; +} + + +sw_error_t +dess_acl_rule_sync_multi_portmap(a_uint32_t dev_id, a_uint32_t pos, a_uint32_t *act) +{ + + HSL_DEV_ID_CHECK(dev_id); + + if (DESS_MAX_LIST_ID < pos) + { + return SW_NOT_SUPPORTED; + } + + sw_rule_ent[dev_id][pos].filter.act[1] = act[1]; + sw_rule_ent[dev_id][pos].filter.act[2] = act[2]; + + sw_rule_tmp[dev_id][pos].filter.act[1] = act[1]; + sw_rule_tmp[dev_id][pos].filter.act[2] = act[2]; + + hw_rule_tmp[dev_id][pos].filter.act[1] = act[1]; + hw_rule_tmp[dev_id][pos].filter.act[2] = act[2]; + + + return SW_OK; +} + +/** + * @brief Bind an acl list to a particular object + * @details Comments: + * If obj_t equals FAL_ACL_BIND_PORT then obj_idx means port id + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] direc direction of this binding operation + * @param[in] obj_t object type of this binding operation + * @param[in] obj_idx object index of this binding operation + * @return SW_OK or error code + */ +sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_acl_list_bind(dev_id, list_id, direc, obj_t, obj_idx); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Unbind an acl list from a particular object + * @details Comments: + * If obj_t equals FAL_ACL_BIND_PORT then obj_idx means port id + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] direc direction of this unbinding operation + * @param[in] obj_t object type of this unbinding operation + * @param[in] obj_idx object index of this unbinding operation + * @return SW_OK or error code + */ +sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_acl_list_unbind(dev_id, list_id, direc, obj_t, obj_idx); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set working status of ACL engine on a particular device + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +dess_acl_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_acl_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get working status of ACL engine on a particular device + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_acl_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_acl_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set user define fields profile on a particular port + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] udf_type udf type + * @param[in] offset udf offset + * @param[in] length udf length + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_acl_port_udf_profile_set(dev_id, port_id, udf_type, offset, + length); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get user define fields profile on a particular port + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] udf_type udf type + * @param[out] offset udf offset + * @param[out] length udf length + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_acl_port_udf_profile_get(dev_id, port_id, udf_type, offset, + length); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Active one or more rules in an existing acl list + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] rule_id first rule id of this deactive operation in list + * @param[in] rule_nr rule number of this deactive operation + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_acl_rule_active(dev_id, list_id, rule_id, rule_nr, A_TRUE); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Deactive one or more rules in an existing acl list + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] rule_id first rule id of this deactive operation in list + * @param[in] rule_nr rule number of this deactive operation + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_acl_rule_active(dev_id, list_id, rule_id, rule_nr, A_FALSE); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief enable acl forward source filter of one rule. + * @param[in] dev_id device id + * @param[in] rule_id first rule id of this deactive operation in list + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_acl_rule_src_filter_sts_set(a_uint32_t dev_id, + a_uint32_t rule_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_acl_rule_src_filter_sts_set(dev_id, rule_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief get the status of acl forward source filter of one rule. + * @param[in] dev_id device id + * @param[in] rule_id first rule id of this deactive operation in list + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_acl_rule_src_filter_sts_get(a_uint32_t dev_id, + a_uint32_t rule_id, a_bool_t* enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_acl_rule_src_filter_sts_get(dev_id, rule_id, enable); + HSL_API_UNLOCK; + return rv; +} + + + +sw_error_t +dess_acl_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + + sw_list_ent[dev_id] = + (dess_acl_list_t *) aos_mem_alloc(DESS_MAX_FILTER * + sizeof (dess_acl_list_t)); + if (NULL == sw_list_ent[dev_id]) + { + return SW_NO_RESOURCE; + } + aos_mem_zero(sw_list_ent[dev_id], + DESS_MAX_FILTER * sizeof (dess_acl_list_t)); + + sw_rule_ent[dev_id] = + (dess_acl_rule_t *) aos_mem_alloc(DESS_MAX_FILTER * + sizeof (dess_acl_rule_t)); + if (NULL == sw_rule_ent[dev_id]) + { + return SW_NO_RESOURCE; + } + aos_mem_zero(sw_rule_ent[dev_id], + DESS_MAX_FILTER * sizeof (dess_acl_rule_t)); + + hw_rule_tmp[dev_id] = + (dess_acl_rule_t *) aos_mem_alloc(DESS_HW_RULE_TMP_CNT * + sizeof (dess_acl_rule_t)); + if (NULL == hw_rule_tmp[dev_id]) + { + return SW_NO_RESOURCE; + } + + sw_rule_tmp[dev_id] = + (dess_acl_rule_t *) aos_mem_alloc(DESS_MAX_FILTER * + sizeof (dess_acl_rule_t)); + if (NULL == sw_rule_tmp[dev_id]) + { + return SW_NO_RESOURCE; + } +#ifdef DESS_SW_ENTRY + sw_filter_mem = aos_mem_alloc(DESS_MAX_FILTER * sizeof (hw_filter_t)); + if (NULL == sw_filter_mem) + { + return SW_NO_RESOURCE; + } + aos_mem_zero(sw_filter_mem, DESS_MAX_FILTER * sizeof (hw_filter_t)); +#endif + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->acl_list_creat = dess_acl_list_creat; + p_api->acl_list_destroy = dess_acl_list_destroy; + p_api->acl_list_bind = dess_acl_list_bind; + p_api->acl_list_unbind = dess_acl_list_unbind; + p_api->acl_rule_add = dess_acl_rule_add; + p_api->acl_rule_delete = dess_acl_rule_delete; + p_api->acl_rule_query = dess_acl_rule_query; + p_api->acl_status_set = dess_acl_status_set; + p_api->acl_status_get = dess_acl_status_get; + p_api->acl_list_dump = dess_acl_list_dump; + p_api->acl_rule_dump = dess_acl_rule_dump; + p_api->acl_port_udf_profile_set = dess_acl_port_udf_profile_set; + p_api->acl_port_udf_profile_get = dess_acl_port_udf_profile_get; + p_api->acl_rule_active = dess_acl_rule_active; + p_api->acl_rule_deactive = dess_acl_rule_deactive; + p_api->acl_rule_src_filter_sts_set = dess_acl_rule_src_filter_sts_set; + p_api->acl_rule_src_filter_sts_get = dess_acl_rule_src_filter_sts_get; + p_api->acl_rule_get_offset = dess_acl_rule_get_offset; + p_api->acl_rule_sync_multi_portmap = dess_acl_rule_sync_multi_portmap; + } +#endif + + return SW_OK; +} + +sw_error_t +dess_acl_cleanup(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + + if (NULL != sw_list_ent[dev_id]) + { + aos_mem_free(sw_list_ent[dev_id]); + } + + if (NULL != sw_rule_ent[dev_id]) + { + aos_mem_free(sw_rule_ent[dev_id]); + } + + if (NULL != hw_rule_tmp[dev_id]) + { + aos_mem_free(hw_rule_tmp[dev_id]); + } + + if (NULL != sw_rule_tmp[dev_id]) + { + aos_mem_free(sw_rule_tmp[dev_id]); + } +#ifdef DESS_SW_ENTRY + if (NULL != sw_filter_mem) + { + aos_mem_free(sw_filter_mem); + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_acl_parse.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_acl_parse.c new file mode 100755 index 000000000..f38219b55 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_acl_parse.c @@ -0,0 +1,2452 @@ +/* + * 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 "hsl.h" +#include "hsl_dev.h" +#include "hsl_acl.h" +#include "dess_acl.h" +#include "dess_reg.h" +#include "dess_acl_prv.h" + +#define DAH 0x1 +#define SAH 0x2 +#define TAG 0x4 +#define STAG 0x8 +#define CTAG 0x10 + +typedef sw_error_t(*parse_func_t) (fal_acl_rule_t * sw, + hw_filter_t * hw_filter_snap, + a_bool_t * b_care); + +static a_bool_t +_dess_acl_zero_addr(const fal_mac_addr_t addr) +{ + a_uint32_t i; + + for (i = 0; i < 6; i++) + { + if (addr.uc[i]) + { + return A_FALSE; + } + } + return A_TRUE; +} + +static a_bool_t +_dess_acl_field_care(fal_acl_field_op_t op, a_uint32_t val, a_uint32_t mask, + a_uint32_t chkvlu) +{ + if (FAL_ACL_FIELD_MASK == op) + { + if (0 == mask) + return A_FALSE; + } + else if (FAL_ACL_FIELD_RANGE == op) + { + if ((0 == val) && (chkvlu == mask)) + return A_FALSE; + } + else if (FAL_ACL_FIELD_LE == op) + { + if (chkvlu == val) + return A_FALSE; + } + else if (FAL_ACL_FIELD_GE == op) + { + if (0 == val) + return A_FALSE; + } + else if (FAL_ACL_FIELD_NE == op) + { + return A_TRUE; + } + + return A_TRUE; +} + +static sw_error_t +_dess_acl_rule_bmac_parse(fal_acl_rule_t * sw, + hw_filter_t * hw, a_bool_t * b_care) +{ + a_uint32_t i; + + *b_care = A_FALSE; + aos_mem_zero(&(hw->vlu[0]), sizeof (hw->vlu)); + aos_mem_zero(&(hw->msk[0]), sizeof (hw->msk)); + + FIELD_SET_MASK(MAC_RUL_M4, RULE_TYP, DESS_MAC_FILTER); + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_DA)) + { + if (A_TRUE != _dess_acl_zero_addr(sw->dest_mac_mask)) + { + *b_care = A_TRUE; + } + + for (i = 0; i < 6; i++) + { + sw->dest_mac_val.uc[i] &= sw->dest_mac_mask.uc[i]; + } + + FIELD_SET(MAC_RUL_V0, DAV_BYTE2, sw->dest_mac_val.uc[2]); + FIELD_SET(MAC_RUL_V0, DAV_BYTE3, sw->dest_mac_val.uc[3]); + FIELD_SET(MAC_RUL_V0, DAV_BYTE4, sw->dest_mac_val.uc[4]); + FIELD_SET(MAC_RUL_V0, DAV_BYTE5, sw->dest_mac_val.uc[5]); + FIELD_SET(MAC_RUL_V1, DAV_BYTE0, sw->dest_mac_val.uc[0]); + FIELD_SET(MAC_RUL_V1, DAV_BYTE1, sw->dest_mac_val.uc[1]); + + FIELD_SET_MASK(MAC_RUL_M0, DAM_BYTE2, sw->dest_mac_mask.uc[2]); + FIELD_SET_MASK(MAC_RUL_M0, DAM_BYTE3, sw->dest_mac_mask.uc[3]); + FIELD_SET_MASK(MAC_RUL_M0, DAM_BYTE4, sw->dest_mac_mask.uc[4]); + FIELD_SET_MASK(MAC_RUL_M0, DAM_BYTE5, sw->dest_mac_mask.uc[5]); + FIELD_SET_MASK(MAC_RUL_M1, DAM_BYTE0, sw->dest_mac_mask.uc[0]); + FIELD_SET_MASK(MAC_RUL_M1, DAM_BYTE1, sw->dest_mac_mask.uc[1]); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_SA)) + { + if (A_TRUE != _dess_acl_zero_addr(sw->src_mac_mask)) + { + *b_care = A_TRUE; + } + + for (i = 0; i < 6; i++) + { + sw->src_mac_val.uc[i] &= sw->src_mac_mask.uc[i]; + } + + FIELD_SET(MAC_RUL_V1, SAV_BYTE4, sw->src_mac_val.uc[4]); + FIELD_SET(MAC_RUL_V1, SAV_BYTE5, sw->src_mac_val.uc[5]); + FIELD_SET(MAC_RUL_V2, SAV_BYTE0, sw->src_mac_val.uc[0]); + FIELD_SET(MAC_RUL_V2, SAV_BYTE1, sw->src_mac_val.uc[1]); + FIELD_SET(MAC_RUL_V2, SAV_BYTE2, sw->src_mac_val.uc[2]); + FIELD_SET(MAC_RUL_V2, SAV_BYTE3, sw->src_mac_val.uc[3]); + + FIELD_SET_MASK(MAC_RUL_M1, SAM_BYTE4, sw->src_mac_mask.uc[4]); + FIELD_SET_MASK(MAC_RUL_M1, SAM_BYTE5, sw->src_mac_mask.uc[5]); + FIELD_SET_MASK(MAC_RUL_M2, SAM_BYTE0, sw->src_mac_mask.uc[0]); + FIELD_SET_MASK(MAC_RUL_M2, SAM_BYTE1, sw->src_mac_mask.uc[1]); + FIELD_SET_MASK(MAC_RUL_M2, SAM_BYTE2, sw->src_mac_mask.uc[2]); + FIELD_SET_MASK(MAC_RUL_M2, SAM_BYTE3, sw->src_mac_mask.uc[3]); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_ETHTYPE)) + { + if (0x0 != sw->ethtype_mask) + { + *b_care = A_TRUE; + } + + sw->ethtype_val &= sw->ethtype_mask; + FIELD_SET(MAC_RUL_V3, ETHTYPV, sw->ethtype_val); + FIELD_SET_MASK(MAC_RUL_M3, ETHTYPM, sw->ethtype_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_TAGGED)) + { + if (0x0 != sw->tagged_mask) + { + *b_care = A_TRUE; + } + + sw->tagged_val &= sw->tagged_mask; + FIELD_SET_MASK(MAC_RUL_M4, TAGGEDV, sw->tagged_val); + FIELD_SET_MASK(MAC_RUL_M4, TAGGEDM, sw->tagged_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_UP)) + { + if (0x0 != sw->up_mask) + { + *b_care = A_TRUE; + } + + sw->up_val &= sw->up_mask; + FIELD_SET(MAC_RUL_V3, VLANPRIV, sw->up_val); + FIELD_SET_MASK(MAC_RUL_M3, VLANPRIM, sw->up_mask); + } + + FIELD_SET_MASK(MAC_RUL_M4, VIDMSK, 1); + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_VID)) + { + if ((FAL_ACL_FIELD_MASK != sw->vid_op) + && (FAL_ACL_FIELD_RANGE != sw->vid_op) + && (FAL_ACL_FIELD_LE != sw->vid_op) + && (FAL_ACL_FIELD_GE != sw->vid_op)) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == + _dess_acl_field_care(sw->vid_op, sw->vid_val, sw->vid_mask, + 0xfff)) + { + *b_care = A_TRUE; + } + + FIELD_SET_MASK(MAC_RUL_M4, VIDMSK, 0); + if (FAL_ACL_FIELD_MASK == sw->vid_op) + { + sw->vid_val &= sw->vid_mask; + FIELD_SET(MAC_RUL_V3, VLANIDV, sw->vid_val); + FIELD_SET_MASK(MAC_RUL_M3, VLANIDM, sw->vid_mask); + FIELD_SET_MASK(MAC_RUL_M4, VIDMSK, 1); + } + else if (FAL_ACL_FIELD_RANGE == sw->vid_op) + { + FIELD_SET(MAC_RUL_V3, VLANIDV, sw->vid_val); + FIELD_SET_MASK(MAC_RUL_M3, VLANIDM, sw->vid_mask); + } + else if (FAL_ACL_FIELD_LE == sw->vid_op) + { + FIELD_SET(MAC_RUL_V3, VLANIDV, 0); + FIELD_SET_MASK(MAC_RUL_M3, VLANIDM, sw->vid_val); + } + else + { + FIELD_SET(MAC_RUL_V3, VLANIDV, sw->vid_val); + FIELD_SET_MASK(MAC_RUL_M3, VLANIDM, 0xfff); + } + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_CFI)) + { + if (0x0 != sw->cfi_mask) + { + *b_care = A_TRUE; + } + + sw->cfi_val &= sw->cfi_mask; + FIELD_SET(MAC_RUL_V3, VLANCFIV, sw->cfi_val); + FIELD_SET_MASK(MAC_RUL_M3, VLANCFIM, sw->cfi_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL)) + { + FIELD_SET(MAC_RUL_V4, RULE_INV, 1); + } + + return SW_OK; +} + +static sw_error_t +_dess_acl_rule_ehmac_parse(fal_acl_rule_t * sw, + hw_filter_t * hw, a_bool_t * b_care) +{ + a_uint32_t i; + a_bool_t da_h = A_FALSE, sa_h = A_FALSE; + + *b_care = A_FALSE; + aos_mem_zero(&(hw->vlu[0]), sizeof (hw->vlu)); + aos_mem_zero(&(hw->msk[0]), sizeof (hw->msk)); + + FIELD_SET_MASK(MAC_RUL_M4, RULE_TYP, DESS_EHMAC_FILTER); + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_DA)) + { + for (i = 0; i < 3; i++) + { + if (sw->dest_mac_mask.uc[i]) + { + da_h = A_TRUE; + break; + } + } + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_SA)) + { + for (i = 0; i < 3; i++) + { + if (sw->src_mac_mask.uc[i]) + { + sa_h = A_TRUE; + break; + } + } + } + + /* if sa_h and da_h both are true need't process mac address fileds */ + if ((A_TRUE == da_h) && ((A_TRUE == sa_h))) + { + da_h = A_FALSE; + sa_h = A_FALSE; + } + + if (A_TRUE == da_h) + { + FIELD_SET(EHMAC_RUL_V3, DA_EN, 1); + + if (A_TRUE != _dess_acl_zero_addr(sw->dest_mac_mask)) + { + *b_care = A_TRUE; + } + + for (i = 0; i < 6; i++) + { + sw->dest_mac_val.uc[i] &= sw->dest_mac_mask.uc[i]; + } + + FIELD_SET(EHMAC_RUL_V0, DAV_BYTE2, sw->dest_mac_val.uc[2]); + FIELD_SET(EHMAC_RUL_V0, DAV_BYTE3, sw->dest_mac_val.uc[3]); + FIELD_SET(EHMAC_RUL_V0, DAV_BYTE4, sw->dest_mac_val.uc[4]); + FIELD_SET(EHMAC_RUL_V0, DAV_BYTE5, sw->dest_mac_val.uc[5]); + FIELD_SET(EHMAC_RUL_V1, DAV_BYTE0, sw->dest_mac_val.uc[0]); + FIELD_SET(EHMAC_RUL_V1, DAV_BYTE1, sw->dest_mac_val.uc[1]); + + FIELD_SET_MASK(EHMAC_RUL_M0, DAM_BYTE2, sw->dest_mac_mask.uc[2]); + FIELD_SET_MASK(EHMAC_RUL_M0, DAM_BYTE3, sw->dest_mac_mask.uc[3]); + FIELD_SET_MASK(EHMAC_RUL_M0, DAM_BYTE4, sw->dest_mac_mask.uc[4]); + FIELD_SET_MASK(EHMAC_RUL_M0, DAM_BYTE5, sw->dest_mac_mask.uc[5]); + FIELD_SET_MASK(EHMAC_RUL_M1, DAM_BYTE0, sw->dest_mac_mask.uc[0]); + FIELD_SET_MASK(EHMAC_RUL_M1, DAM_BYTE1, sw->dest_mac_mask.uc[1]); + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_SA)) + { + if (A_TRUE != _dess_acl_zero_addr(sw->src_mac_mask)) + { + *b_care = A_TRUE; + } + + for (i = 0; i < 6; i++) + { + sw->src_mac_val.uc[i] &= sw->src_mac_mask.uc[i]; + } + + FIELD_SET(EHMAC_RUL_V2, SAV_BYTE3, sw->src_mac_val.uc[3]); + FIELD_SET(EHMAC_RUL_V1, SAV_BYTE4, sw->src_mac_val.uc[4]); + FIELD_SET(EHMAC_RUL_V1, SAV_BYTE5, sw->src_mac_val.uc[5]); + + FIELD_SET_MASK(EHMAC_RUL_M2, SAM_BYTE3, sw->src_mac_mask.uc[3]); + FIELD_SET_MASK(EHMAC_RUL_M1, SAM_BYTE4, sw->src_mac_mask.uc[4]); + FIELD_SET_MASK(EHMAC_RUL_M1, SAM_BYTE5, sw->src_mac_mask.uc[5]); + } + } + + if (A_TRUE == sa_h) + { + if (A_TRUE != _dess_acl_zero_addr(sw->src_mac_mask)) + { + *b_care = A_TRUE; + } + + for (i = 0; i < 6; i++) + { + sw->src_mac_val.uc[i] &= sw->src_mac_mask.uc[i]; + } + + FIELD_SET(EHMAC_RUL_V0, DAV_BYTE2, sw->src_mac_val.uc[2]); + FIELD_SET(EHMAC_RUL_V0, DAV_BYTE3, sw->src_mac_val.uc[3]); + FIELD_SET(EHMAC_RUL_V0, DAV_BYTE4, sw->src_mac_val.uc[4]); + FIELD_SET(EHMAC_RUL_V0, DAV_BYTE5, sw->src_mac_val.uc[5]); + FIELD_SET(EHMAC_RUL_V1, DAV_BYTE0, sw->src_mac_val.uc[0]); + FIELD_SET(EHMAC_RUL_V1, DAV_BYTE1, sw->src_mac_val.uc[1]); + + FIELD_SET_MASK(EHMAC_RUL_M0, DAM_BYTE2, sw->src_mac_mask.uc[2]); + FIELD_SET_MASK(EHMAC_RUL_M0, DAM_BYTE3, sw->src_mac_mask.uc[3]); + FIELD_SET_MASK(EHMAC_RUL_M0, DAM_BYTE4, sw->src_mac_mask.uc[4]); + FIELD_SET_MASK(EHMAC_RUL_M0, DAM_BYTE5, sw->src_mac_mask.uc[5]); + FIELD_SET_MASK(EHMAC_RUL_M1, DAM_BYTE0, sw->src_mac_mask.uc[0]); + FIELD_SET_MASK(EHMAC_RUL_M1, DAM_BYTE1, sw->src_mac_mask.uc[1]); + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_DA)) + { + if (A_TRUE != _dess_acl_zero_addr(sw->dest_mac_mask)) + { + *b_care = A_TRUE; + } + + for (i = 0; i < 6; i++) + { + sw->dest_mac_val.uc[i] &= sw->dest_mac_mask.uc[i]; + } + + FIELD_SET(EHMAC_RUL_V2, SAV_BYTE3, sw->dest_mac_val.uc[3]); + FIELD_SET(EHMAC_RUL_V1, SAV_BYTE4, sw->dest_mac_val.uc[4]); + FIELD_SET(EHMAC_RUL_V1, SAV_BYTE5, sw->dest_mac_val.uc[5]); + + FIELD_SET_MASK(EHMAC_RUL_M2, SAM_BYTE3, sw->dest_mac_mask.uc[3]); + FIELD_SET_MASK(EHMAC_RUL_M1, SAM_BYTE4, sw->dest_mac_mask.uc[4]); + FIELD_SET_MASK(EHMAC_RUL_M1, SAM_BYTE5, sw->dest_mac_mask.uc[5]); + } + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_ETHTYPE)) + { + if (0x0 != sw->ethtype_mask) + { + *b_care = A_TRUE; + } + + sw->ethtype_val &= sw->ethtype_mask; + FIELD_SET(EHMAC_RUL_V3, ETHTYPV, sw->ethtype_val); + FIELD_SET_MASK(EHMAC_RUL_M3, ETHTYPM, sw->ethtype_mask); + } + + /* Process Stag Fields */ + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_STAGGED)) + { + if (0x0 != sw->stagged_mask) + { + *b_care = A_TRUE; + } + + sw->stagged_val &= sw->stagged_mask; + FIELD_SET(EHMAC_RUL_V3, STAGGEDV, sw->stagged_val); + FIELD_SET(EHMAC_RUL_V3, STAGGEDM, sw->stagged_mask); + } + + FIELD_SET(EHMAC_RUL_V3, SVIDMSK, 1); + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_STAG_VID)) + { + if ((FAL_ACL_FIELD_MASK != sw->stag_vid_op) + && (FAL_ACL_FIELD_RANGE != sw->stag_vid_op) + && (FAL_ACL_FIELD_LE != sw->stag_vid_op) + && (FAL_ACL_FIELD_GE != sw->stag_vid_op)) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == + _dess_acl_field_care(sw->stag_vid_op, sw->stag_vid_val, + sw->stag_vid_mask, 0xfff)) + { + *b_care = A_TRUE; + } + + FIELD_SET(EHMAC_RUL_V3, SVIDMSK, 0); + if (FAL_ACL_FIELD_MASK == sw->stag_vid_op) + { + sw->stag_vid_val &= sw->stag_vid_mask; + FIELD_SET(EHMAC_RUL_V2, STAG_VIDV, sw->stag_vid_val); + FIELD_SET_MASK(EHMAC_RUL_M2, STAG_VIDM, sw->stag_vid_mask); + FIELD_SET(EHMAC_RUL_V3, SVIDMSK, 1); + + } + else if (FAL_ACL_FIELD_RANGE == sw->stag_vid_op) + { + FIELD_SET(EHMAC_RUL_V2, STAG_VIDV, sw->stag_vid_val); + FIELD_SET_MASK(EHMAC_RUL_M2, STAG_VIDM, sw->stag_vid_mask); + + } + else if (FAL_ACL_FIELD_LE == sw->stag_vid_op) + { + FIELD_SET(EHMAC_RUL_V2, STAG_VIDV, 0); + FIELD_SET_MASK(EHMAC_RUL_M2, STAG_VIDM, sw->stag_vid_val); + + } + else + { + FIELD_SET(EHMAC_RUL_V2, STAG_VIDV, sw->stag_vid_val); + FIELD_SET_MASK(EHMAC_RUL_M2, STAG_VIDM, 0xfff); + } + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_STAG_PRI)) + { + if (0x0 != sw->stag_pri_mask) + { + *b_care = A_TRUE; + } + + sw->stag_pri_val &= sw->stag_pri_mask; + FIELD_SET(EHMAC_RUL_V2, STAG_PRIV, sw->stag_pri_val); + FIELD_SET_MASK(EHMAC_RUL_M2, STAG_PRIM, sw->stag_pri_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_STAG_DEI)) + { + if (0x0 != sw->stag_dei_mask) + { + *b_care = A_TRUE; + } + + sw->stag_dei_val &= sw->stag_dei_mask; + FIELD_SET(EHMAC_RUL_V2, STAG_DEIV, sw->stag_dei_val); + FIELD_SET_MASK(EHMAC_RUL_M2, STAG_DEIM, sw->stag_dei_mask); + } + + /* Process Ctag Fields */ + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_CTAGGED)) + { + if (0x0 != sw->ctagged_mask) + { + *b_care = A_TRUE; + } + + sw->ctagged_val &= sw->ctagged_mask; + FIELD_SET_MASK(EHMAC_RUL_M4, CTAGGEDV, sw->ctagged_val); + FIELD_SET_MASK(EHMAC_RUL_M4, CTAGGEDM, sw->ctagged_mask); + } + + FIELD_SET_MASK(EHMAC_RUL_M4, CVIDMSK, 1); + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_CTAG_VID)) + { + if ((FAL_ACL_FIELD_MASK != sw->ctag_vid_op) + && (FAL_ACL_FIELD_RANGE != sw->ctag_vid_op) + && (FAL_ACL_FIELD_LE != sw->ctag_vid_op) + && (FAL_ACL_FIELD_GE != sw->ctag_vid_op)) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == + _dess_acl_field_care(sw->ctag_vid_op, sw->ctag_vid_val, + sw->ctag_vid_mask, 0xfff)) + { + *b_care = A_TRUE; + } + + FIELD_SET_MASK(EHMAC_RUL_M4, CVIDMSK, 0); + if (FAL_ACL_FIELD_MASK == sw->ctag_vid_op) + { + sw->ctag_vid_val &= sw->ctag_vid_mask; + FIELD_SET(EHMAC_RUL_V2, CTAG_VIDLV, sw->ctag_vid_val); + FIELD_SET(EHMAC_RUL_V3, CTAG_VIDHV, (sw->ctag_vid_val >> 8)); + FIELD_SET_MASK(EHMAC_RUL_M2, CTAG_VIDLM, sw->ctag_vid_mask); + FIELD_SET_MASK(EHMAC_RUL_M3, CTAG_VIDHM, (sw->ctag_vid_mask >> 8)); + FIELD_SET_MASK(EHMAC_RUL_M4, CVIDMSK, 1); + + } + else if (FAL_ACL_FIELD_RANGE == sw->ctag_vid_op) + { + FIELD_SET(EHMAC_RUL_V2, CTAG_VIDLV, sw->ctag_vid_val); + FIELD_SET(EHMAC_RUL_V3, CTAG_VIDHV, (sw->ctag_vid_val >> 8)); + FIELD_SET_MASK(EHMAC_RUL_M2, CTAG_VIDLM, sw->ctag_vid_mask); + FIELD_SET_MASK(EHMAC_RUL_M3, CTAG_VIDHM, (sw->ctag_vid_mask >> 8)); + + } + else if (FAL_ACL_FIELD_LE == sw->ctag_vid_op) + { + FIELD_SET(EHMAC_RUL_V2, CTAG_VIDLV, 0); + FIELD_SET(EHMAC_RUL_V3, CTAG_VIDHV, 0); + FIELD_SET_MASK(EHMAC_RUL_M2, CTAG_VIDLM, sw->ctag_vid_val); + FIELD_SET_MASK(EHMAC_RUL_M3, CTAG_VIDHM, (sw->ctag_vid_val >> 8)); + + } + else + { + FIELD_SET(EHMAC_RUL_V2, CTAG_VIDLV, sw->ctag_vid_val); + FIELD_SET(EHMAC_RUL_V3, CTAG_VIDHV, (sw->ctag_vid_val >> 8)); + FIELD_SET_MASK(EHMAC_RUL_M2, CTAG_VIDLM, 0xff); + FIELD_SET_MASK(EHMAC_RUL_M3, CTAG_VIDHM, 0xf); + } + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_CTAG_PRI)) + { + if (0x0 != sw->ctag_pri_mask) + { + *b_care = A_TRUE; + } + + sw->ctag_pri_val &= sw->ctag_pri_mask; + FIELD_SET(EHMAC_RUL_V3, CTAG_PRIV, sw->ctag_pri_val); + FIELD_SET_MASK(EHMAC_RUL_M3, CTAG_PRIM, sw->ctag_pri_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_CTAG_CFI)) + { + if (0x0 != sw->ctag_cfi_mask) + { + *b_care = A_TRUE; + } + + sw->ctag_cfi_val &= sw->ctag_cfi_mask; + FIELD_SET(EHMAC_RUL_V3, CTAG_CFIV, sw->ctag_cfi_val); + FIELD_SET_MASK(EHMAC_RUL_M3, CTAG_CFIM, sw->ctag_cfi_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL)) + { + FIELD_SET(MAC_RUL_V4, RULE_INV, 1); + } + + return SW_OK; +} + +static void +_dess_acl_rule_mac_preparse(fal_acl_rule_t * sw, a_bool_t * b_mac, + a_bool_t * eh_mac) +{ + a_uint32_t bm = 0, i, tmp; + + *b_mac = A_FALSE; + *eh_mac = A_FALSE; + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_DA)) + { + for (i = 0; i < 3; i++) + { + if (sw->dest_mac_mask.uc[i]) + { + bm |= DAH; + break; + } + } + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_SA)) + { + for (i = 0; i < 3; i++) + { + if (sw->src_mac_mask.uc[i]) + { + bm |= SAH; + break; + } + } + } + + tmp = 0; + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_TAGGED)) + { + tmp |= ((sw->tagged_mask & 0x1) << 16); + } + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_UP)) + { + tmp |= ((sw->up_mask & 0x7) << 13); + } + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_CFI)) + { + tmp |= ((sw->cfi_mask & 0x1) << 12); + } + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_VID)) + { + if (A_TRUE == + _dess_acl_field_care(sw->vid_op, sw->vid_val, sw->vid_mask, + 0xfff)) + { + tmp |= 0xfff; + } + } + if (tmp) + { + bm |= TAG; + } + + tmp = 0; + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_STAGGED)) + { + tmp |= ((sw->stagged_mask & 0x1) << 16); + } + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_STAG_PRI)) + { + tmp |= ((sw->stag_pri_mask & 0x7) << 13); + } + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_STAG_DEI)) + { + tmp |= ((sw->stag_dei_mask & 0x1) << 12); + } + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_STAG_VID)) + { + if (A_TRUE == + _dess_acl_field_care(sw->stag_vid_op, sw->stag_vid_val, + sw->stag_vid_mask, 0xfff)) + { + tmp |= 0xfff; + } + } + if (tmp) + { + bm |= STAG; + } + + tmp = 0; + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_CTAGGED)) + { + tmp |= ((sw->ctagged_mask & 0x1) << 16); + } + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_CTAG_PRI)) + { + tmp |= ((sw->ctag_pri_mask & 0x7) << 13); + } + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_CTAG_CFI)) + { + tmp |= ((sw->ctag_cfi_mask & 0x1) << 12); + } + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_CTAG_VID)) + { + if (A_TRUE == + _dess_acl_field_care(sw->ctag_vid_op, sw->ctag_vid_val, + sw->ctag_vid_mask, 0xfff)) + { + tmp |= 0xfff; + } + } + if (tmp) + { + bm |= CTAG; + } + + if ((bm & CTAG) || (bm & STAG)) + { + *eh_mac = A_TRUE; + } + + if ((bm & TAG) || ((bm & DAH) && (bm & SAH))) + { + *b_mac = A_TRUE; + } +} + +static sw_error_t +_dess_acl_rule_ip4_parse(fal_acl_rule_t * sw, + hw_filter_t * hw, a_bool_t * b_care) +{ + *b_care = A_FALSE; + aos_mem_zero(&(hw->vlu[0]), sizeof (hw->vlu)); + aos_mem_zero(&(hw->msk[0]), sizeof (hw->msk)); + + FIELD_SET_MASK(MAC_RUL_M4, RULE_TYP, DESS_IP4_FILTER); + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP_DSCP)) + { + if (0x0 != sw->ip_dscp_mask) + { + *b_care = A_TRUE; + } + + sw->ip_dscp_val &= sw->ip_dscp_mask; + FIELD_SET(IP4_RUL_V2, IP4DSCPV, sw->ip_dscp_val); + FIELD_SET_MASK(IP4_RUL_M2, IP4DSCPM, sw->ip_dscp_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP_PROTO)) + { + if (0x0 != sw->ip_proto_mask) + { + *b_care = A_TRUE; + } + + sw->ip_proto_val &= sw->ip_proto_mask; + FIELD_SET(IP4_RUL_V2, IP4PROTV, sw->ip_proto_val); + FIELD_SET_MASK(IP4_RUL_M2, IP4PROTM, sw->ip_proto_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP4_SIP)) + { + if (0x0 != sw->src_ip4_mask) + { + *b_care = A_TRUE; + } + sw->src_ip4_val &= sw->src_ip4_mask; + hw->vlu[1] = sw->src_ip4_val; + hw->msk[1] = sw->src_ip4_mask; + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP4_DIP)) + { + if (0x0 != sw->dest_ip4_mask) + { + *b_care = A_TRUE; + } + sw->dest_ip4_val &= sw->dest_ip4_mask; + hw->vlu[0] = sw->dest_ip4_val; + hw->msk[0] = sw->dest_ip4_mask; + } + + if ((FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_L4_SPORT)) + && ((FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_ICMP_TYPE)) + || (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_ICMP_CODE)))) + { + return SW_BAD_PARAM; + } + + FIELD_SET_MASK(IP4_RUL_M3, IP4SPORTM_EN, 1); + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_L4_SPORT)) + { + if ((FAL_ACL_FIELD_MASK != sw->src_l4port_op) + && (FAL_ACL_FIELD_RANGE != sw->src_l4port_op) + && (FAL_ACL_FIELD_LE != sw->src_l4port_op) + && (FAL_ACL_FIELD_GE != sw->src_l4port_op)) + { + return SW_NOT_SUPPORTED; + } + + if (A_FALSE == + _dess_acl_field_care(sw->src_l4port_op, sw->src_l4port_val, + sw->src_l4port_mask, 0xffff)) + { + if (FAL_ACL_FIELD_MASK == sw->src_l4port_op) + { + sw->src_l4port_op = FAL_ACL_FIELD_RANGE; + sw->src_l4port_val = 0; + sw->src_l4port_mask = 0xffff; + } + } + *b_care = A_TRUE; + + FIELD_SET_MASK(IP4_RUL_M3, IP4SPORTM_EN, 0); + if (FAL_ACL_FIELD_MASK == sw->src_l4port_op) + { + sw->src_l4port_val &= sw->src_l4port_mask; + FIELD_SET(IP4_RUL_V3, IP4SPORTV, sw->src_l4port_val); + FIELD_SET_MASK(IP4_RUL_M3, IP4SPORTM, sw->src_l4port_mask); + FIELD_SET_MASK(IP4_RUL_M3, IP4SPORTM_EN, 1); + } + else if (FAL_ACL_FIELD_RANGE == sw->src_l4port_op) + { + FIELD_SET(IP4_RUL_V3, IP4SPORTV, sw->src_l4port_val); + FIELD_SET_MASK(IP4_RUL_M3, IP4SPORTM, sw->src_l4port_mask); + } + else if (FAL_ACL_FIELD_LE == sw->src_l4port_op) + { + FIELD_SET(IP4_RUL_V3, IP4SPORTV, 0); + FIELD_SET_MASK(IP4_RUL_M3, IP4SPORTM, sw->src_l4port_val); + } + else + { + FIELD_SET(IP4_RUL_V3, IP4SPORTV, sw->src_l4port_val); + FIELD_SET_MASK(IP4_RUL_M3, IP4SPORTM, 0xffff); + } + } + + FIELD_SET_MASK(IP4_RUL_M3, IP4DPORTM_EN, 1); + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_L4_DPORT)) + { + if ((FAL_ACL_FIELD_MASK != sw->dest_l4port_op) + && (FAL_ACL_FIELD_RANGE != sw->dest_l4port_op) + && (FAL_ACL_FIELD_LE != sw->dest_l4port_op) + && (FAL_ACL_FIELD_GE != sw->dest_l4port_op)) + { + return SW_NOT_SUPPORTED; + } + + if (A_FALSE == + _dess_acl_field_care(sw->dest_l4port_op, sw->dest_l4port_val, + sw->dest_l4port_mask, 0xffff)) + { + if (FAL_ACL_FIELD_MASK == sw->dest_l4port_op) + { + sw->dest_l4port_op = FAL_ACL_FIELD_RANGE; + sw->dest_l4port_val = 0; + sw->dest_l4port_mask = 0xffff; + } + } + *b_care = A_TRUE; + + FIELD_SET_MASK(IP4_RUL_M3, IP4DPORTM_EN, 0); + if (FAL_ACL_FIELD_MASK == sw->dest_l4port_op) + { + sw->dest_l4port_val &= sw->dest_l4port_mask; + FIELD_SET(IP4_RUL_V2, IP4DPORTV, sw->dest_l4port_val); + FIELD_SET_MASK(IP4_RUL_M2, IP4DPORTM, sw->dest_l4port_mask); + FIELD_SET_MASK(IP4_RUL_M3, IP4DPORTM_EN, 1); + } + else if (FAL_ACL_FIELD_RANGE == sw->dest_l4port_op) + { + FIELD_SET(IP4_RUL_V2, IP4DPORTV, sw->dest_l4port_val); + FIELD_SET_MASK(IP4_RUL_M2, IP4DPORTM, sw->dest_l4port_mask); + } + else if (FAL_ACL_FIELD_LE == sw->dest_l4port_op) + { + FIELD_SET(IP4_RUL_V2, IP4DPORTV, 0); + FIELD_SET_MASK(IP4_RUL_M2, IP4DPORTM, sw->dest_l4port_val); + } + else + { + FIELD_SET(IP4_RUL_V2, IP4DPORTV, sw->dest_l4port_val); + FIELD_SET_MASK(IP4_RUL_M2, IP4DPORTM, 0xffff); + } + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_ICMP_TYPE)) + { + if (0x0 != sw->icmp_type_mask) + { + *b_care = A_TRUE; + } + FIELD_SET(IP4_RUL_V3, ICMP_EN, 1); + + sw->icmp_type_val &= sw->icmp_type_mask; + FIELD_SET(IP4_RUL_V3, IP4ICMPTYPV, sw->icmp_type_val); + FIELD_SET_MASK(IP4_RUL_M3, IP4ICMPTYPM, sw->icmp_type_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_ICMP_CODE)) + { + if (0x0 != sw->icmp_code_mask) + { + *b_care = A_TRUE; + } + FIELD_SET(IP4_RUL_V3, ICMP_EN, 1); + + sw->icmp_code_val &= sw->icmp_code_mask; + FIELD_SET(IP4_RUL_V3, IP4ICMPCODEV, sw->icmp_code_val); + FIELD_SET_MASK(IP4_RUL_M3, IP4ICMPCODEM, sw->icmp_code_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_TCP_FLAG)) + { + if (0x0 != sw->tcp_flag_mask) + { + *b_care = A_TRUE; + } + + sw->tcp_flag_val &= sw->tcp_flag_mask; + FIELD_SET(IP4_RUL_V3, IP4TCPFLAGV, sw->tcp_flag_val); + FIELD_SET_MASK(IP4_RUL_M3, IP4TCPFLAGM, sw->tcp_flag_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_RIPV1)) + { + if (0x0 != sw->ripv1_mask) + { + *b_care = A_TRUE; + } + + sw->ripv1_val &= sw->ripv1_mask; + FIELD_SET(IP4_RUL_V3, IP4RIPV, sw->ripv1_val); + FIELD_SET_MASK(IP4_RUL_M3, IP4RIPM, sw->ripv1_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_DHCPV4)) + { + if (0x0 != sw->dhcpv4_mask) + { + *b_care = A_TRUE; + } + + sw->dhcpv4_val &= sw->dhcpv4_mask; + FIELD_SET(IP4_RUL_V3, IP4DHCPV, sw->dhcpv4_val); + FIELD_SET_MASK(IP4_RUL_M3, IP4DHCPM, sw->dhcpv4_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL)) + { + FIELD_SET(MAC_RUL_V4, RULE_INV, 1); + } + + return SW_OK; +} + +static sw_error_t +_dess_acl_rule_ip6r1_parse(fal_acl_rule_t * sw, + hw_filter_t * hw, a_bool_t * b_care) +{ + a_uint32_t i; + + *b_care = A_FALSE; + aos_mem_zero(&(hw->vlu[0]), sizeof (hw->vlu)); + aos_mem_zero(&(hw->msk[0]), sizeof (hw->msk)); + + FIELD_SET_MASK(MAC_RUL_M4, RULE_TYP, DESS_IP6R1_FILTER); + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP6_DIP)) + { + for (i = 0; i < 4; i++) + { + if (0x0 != sw->dest_ip6_mask.ul[i]) + { + *b_care = A_TRUE; + } + + sw->dest_ip6_val.ul[3 - i] &= sw->dest_ip6_mask.ul[3 - i]; + hw->vlu[i] = sw->dest_ip6_val.ul[3 - i]; + hw->msk[i] = sw->dest_ip6_mask.ul[3 - i]; + } + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL)) + { + FIELD_SET(MAC_RUL_V4, RULE_INV, 1); + } + + return SW_OK; +} + +static sw_error_t +_dess_acl_rule_ip6r2_parse(fal_acl_rule_t * sw, + hw_filter_t * hw, a_bool_t * b_care) +{ + a_uint32_t i; + + *b_care = A_FALSE; + aos_mem_zero(&(hw->vlu[0]), sizeof (hw->vlu)); + aos_mem_zero(&(hw->msk[0]), sizeof (hw->msk)); + + FIELD_SET_MASK(MAC_RUL_M4, RULE_TYP, DESS_IP6R2_FILTER); + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP6_SIP)) + { + for (i = 0; i < 4; i++) + { + if (0x0 != sw->src_ip6_mask.ul[i]) + { + *b_care = A_TRUE; + } + + sw->src_ip6_val.ul[3 - i] &= sw->src_ip6_mask.ul[3 - i]; + hw->vlu[i] = sw->src_ip6_val.ul[3 - i]; + hw->msk[i] = sw->src_ip6_mask.ul[3 - i]; + } + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL)) + { + FIELD_SET(MAC_RUL_V4, RULE_INV, 1); + } + + return SW_OK; +} + +static sw_error_t +_dess_acl_rule_ip6r3_parse(fal_acl_rule_t * sw, + hw_filter_t * hw, a_bool_t * b_care) +{ + *b_care = A_FALSE; + aos_mem_zero(&(hw->vlu[0]), sizeof (hw->vlu)); + aos_mem_zero(&(hw->msk[0]), sizeof (hw->msk)); + + FIELD_SET_MASK(MAC_RUL_M4, RULE_TYP, DESS_IP6R3_FILTER); + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP6_LABEL)) + { + if (0x0 != sw->ip6_lable_mask) + { + *b_care = A_TRUE; + } + + sw->ip6_lable_val &= sw->ip6_lable_mask; + FIELD_SET(IP6_RUL3_V1, IP6LABEL1V, sw->ip6_lable_val); + FIELD_SET_MASK(IP6_RUL3_M1, IP6LABEL1M, sw->ip6_lable_mask); + + FIELD_SET(IP6_RUL3_V2, IP6LABEL2V, (sw->ip6_lable_val >> 16)); + FIELD_SET_MASK(IP6_RUL3_M2, IP6LABEL2M, (sw->ip6_lable_mask >> 16)); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP_PROTO)) + { + if (0x0 != sw->ip_proto_mask) + { + *b_care = A_TRUE; + } + + sw->ip_proto_val &= sw->ip_proto_mask; + FIELD_SET(IP6_RUL3_V0, IP6PROTV, sw->ip_proto_val); + FIELD_SET_MASK(IP6_RUL3_M0, IP6PROTM, sw->ip_proto_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP_DSCP)) + { + if (0x0 != sw->ip_dscp_mask) + { + *b_care = A_TRUE; + } + + sw->ip_dscp_val &= sw->ip_dscp_mask; + FIELD_SET(IP6_RUL3_V0, IP6DSCPV, sw->ip_dscp_val); + FIELD_SET_MASK(IP6_RUL3_M0, IP6DSCPM, sw->ip_dscp_mask); + } + + if ((FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_L4_SPORT)) + && ((FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_ICMP_TYPE)) + || (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_ICMP_CODE)))) + { + return SW_BAD_PARAM; + } + + FIELD_SET_MASK(IP6_RUL3_M3, IP6SPORTM_EN, 1); + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_L4_SPORT)) + { + if ((FAL_ACL_FIELD_MASK != sw->src_l4port_op) + && (FAL_ACL_FIELD_RANGE != sw->src_l4port_op) + && (FAL_ACL_FIELD_LE != sw->src_l4port_op) + && (FAL_ACL_FIELD_GE != sw->src_l4port_op)) + { + return SW_NOT_SUPPORTED; + } + + if (A_FALSE == + _dess_acl_field_care(sw->src_l4port_op, sw->src_l4port_val, + sw->src_l4port_mask, 0xffff)) + { + if (FAL_ACL_FIELD_MASK == sw->src_l4port_op) + { + sw->src_l4port_op = FAL_ACL_FIELD_RANGE; + sw->src_l4port_val = 0; + sw->src_l4port_mask = 0xffff; + } + } + *b_care = A_TRUE; + + FIELD_SET_MASK(IP6_RUL3_M3, IP6SPORTM_EN, 0); + if (FAL_ACL_FIELD_MASK == sw->src_l4port_op) + { + sw->src_l4port_val &= sw->src_l4port_mask; + FIELD_SET(IP6_RUL3_V3, IP6SPORTV, sw->src_l4port_val); + FIELD_SET_MASK(IP6_RUL3_M3, IP6SPORTM, sw->src_l4port_mask); + FIELD_SET_MASK(IP6_RUL3_M3, IP6SPORTM_EN, 1); + + } + else if (FAL_ACL_FIELD_RANGE == sw->src_l4port_op) + { + FIELD_SET(IP6_RUL3_V3, IP6SPORTV, sw->src_l4port_val); + FIELD_SET_MASK(IP6_RUL3_M3, IP6SPORTM, sw->src_l4port_mask); + + } + else if (FAL_ACL_FIELD_LE == sw->src_l4port_op) + { + FIELD_SET(IP6_RUL3_V3, IP6SPORTV, 0); + FIELD_SET_MASK(IP6_RUL3_M3, IP6SPORTM, sw->src_l4port_val); + + } + else + { + FIELD_SET(IP6_RUL3_V3, IP6SPORTV, sw->src_l4port_val); + FIELD_SET_MASK(IP6_RUL3_M3, IP6SPORTM, 0xffff); + } + } + + FIELD_SET_MASK(IP6_RUL3_M3, IP6DPORTM_EN, 1); + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_L4_DPORT)) + { + if ((FAL_ACL_FIELD_MASK != sw->dest_l4port_op) + && (FAL_ACL_FIELD_RANGE != sw->dest_l4port_op) + && (FAL_ACL_FIELD_LE != sw->dest_l4port_op) + && (FAL_ACL_FIELD_GE != sw->dest_l4port_op)) + { + return SW_NOT_SUPPORTED; + } + + if (A_FALSE == + _dess_acl_field_care(sw->dest_l4port_op, sw->dest_l4port_val, + sw->dest_l4port_mask, 0xffff)) + { + if (FAL_ACL_FIELD_MASK == sw->dest_l4port_op) + { + sw->dest_l4port_op = FAL_ACL_FIELD_RANGE; + sw->dest_l4port_val = 0; + sw->dest_l4port_mask = 0xffff; + } + } + *b_care = A_TRUE; + + FIELD_SET_MASK(IP6_RUL3_M3, IP6DPORTM_EN, 0); + if (FAL_ACL_FIELD_MASK == sw->dest_l4port_op) + { + sw->dest_l4port_val &= sw->dest_l4port_mask; + FIELD_SET(IP6_RUL3_V2, IP6DPORTV, sw->dest_l4port_val); + FIELD_SET_MASK(IP6_RUL3_M2, IP6DPORTM, sw->dest_l4port_mask); + FIELD_SET_MASK(IP6_RUL3_M3, IP6DPORTM_EN, 1); + } + else if (FAL_ACL_FIELD_RANGE == sw->dest_l4port_op) + { + FIELD_SET(IP6_RUL3_V2, IP6DPORTV, sw->dest_l4port_val); + FIELD_SET_MASK(IP6_RUL3_M2, IP6DPORTM, sw->dest_l4port_mask); + } + else if (FAL_ACL_FIELD_LE == sw->dest_l4port_op) + { + FIELD_SET(IP6_RUL3_V2, IP6DPORTV, 0); + FIELD_SET_MASK(IP6_RUL3_M2, IP6DPORTM, sw->dest_l4port_val); + } + else + { + FIELD_SET(IP6_RUL3_V2, IP6DPORTV, sw->dest_l4port_val); + FIELD_SET_MASK(IP6_RUL3_M2, IP6DPORTM, 0xffff); + } + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_ICMP_TYPE)) + { + if (0x0 != sw->icmp_type_mask) + { + *b_care = A_TRUE; + } + FIELD_SET(IP6_RUL3_V3, ICMP6_EN, 1); + + sw->icmp_type_val &= sw->icmp_type_mask; + FIELD_SET(IP6_RUL3_V3, IP6ICMPTYPV, sw->icmp_type_val); + FIELD_SET_MASK(IP6_RUL3_M3, IP6ICMPTYPM, sw->icmp_type_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_ICMP_CODE)) + { + if (0x0 != sw->icmp_code_mask) + { + *b_care = A_TRUE; + } + FIELD_SET(IP6_RUL3_V3, ICMP6_EN, 1); + + sw->icmp_code_val &= sw->icmp_code_mask; + FIELD_SET(IP6_RUL3_V3, IP6ICMPCODEV, sw->icmp_code_val); + FIELD_SET_MASK(IP6_RUL3_M3, IP6ICMPCODEM, sw->icmp_code_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_TCP_FLAG)) + { + if (0x0 != sw->tcp_flag_mask) + { + *b_care = A_TRUE; + } + + sw->tcp_flag_val &= sw->tcp_flag_mask; + FIELD_SET(IP6_RUL3_V3, IP6TCPFLAGV, sw->tcp_flag_val); + FIELD_SET_MASK(IP6_RUL3_M3, IP6TCPFLAGM, sw->tcp_flag_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_DHCPV6)) + { + if (0x0 != sw->dhcpv6_mask) + { + *b_care = A_TRUE; + } + + sw->dhcpv6_val &= sw->dhcpv6_mask; + FIELD_SET(IP6_RUL3_V3, IP6DHCPV, sw->dhcpv6_val); + FIELD_SET_MASK(IP6_RUL3_M3, IP6DHCPM, sw->dhcpv6_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL)) + { + FIELD_SET(MAC_RUL_V4, RULE_INV, 1); + } + + return SW_OK; +} + +static sw_error_t +_dess_acl_rule_udf_parse(fal_acl_rule_t * sw, + hw_filter_t * hw, a_bool_t * b_care) +{ + a_uint32_t i; + + *b_care = A_FALSE; + aos_mem_zero(&(hw->vlu[0]), sizeof (hw->vlu)); + aos_mem_zero(&(hw->msk[0]), sizeof (hw->msk)); + + FIELD_SET_MASK(MAC_RUL_M4, RULE_TYP, DESS_UDF_FILTER); + + if (!FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_UDF)) + { + if (FAL_ACL_RULE_UDF == sw->rule_type) + { + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL)) + { + FIELD_SET(MAC_RUL_V4, RULE_INV, 1); + } + *b_care = A_TRUE; + } + return SW_OK; + } + + if (DESS_MAX_UDF_LENGTH < sw->udf_len) + { + return SW_NOT_SUPPORTED; + } + + *b_care = A_TRUE; + for (i = 0; i < sw->udf_len; i++) + { + hw->vlu[3 - i / 4] |= + ((sw->udf_mask[i] & sw->udf_val[i]) << (24 - 8 * (i % 4))); + hw->msk[3 - i / 4] |= ((sw->udf_mask[i]) << (24 - 8 * (i % 4))); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL)) + { + FIELD_SET(MAC_RUL_V4, RULE_INV, 1); + } + + return SW_OK; +} + +static sw_error_t +_dess_acl_action_parse(a_uint32_t dev_id, const fal_acl_rule_t * sw, + hw_filter_t * hw) +{ + fal_pbmp_t des_pts; + + aos_mem_zero(&(hw->act[0]), sizeof (hw->act)); + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_MATCH_TRIGGER_INTR)) + { + FIELD_SET_ACTION(ACL_RSLT2, TRIGGER_INTR, 1); + } + + /* FAL_ACL_ACTION_PERMIT need't process */ + + if ((FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_RDTCPU)) + && (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_CPYCPU))) + { + return SW_BAD_PARAM; + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_RDTCPU)) + { + FIELD_SET_ACTION(ACL_RSLT2, FWD_CMD, 0x3); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_CPYCPU)) + { + FIELD_SET_ACTION(ACL_RSLT2, FWD_CMD, 0x1); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_DENY)) + { + FIELD_SET_ACTION(ACL_RSLT2, FWD_CMD, 0x7); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_MIRROR)) + { + FIELD_SET_ACTION(ACL_RSLT2, MIRR_EN, 1); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REDPT)) + { + FIELD_SET_ACTION(ACL_RSLT2, DES_PORT_EN, 1); + + des_pts = (sw->ports >> 3) & 0xf; + FIELD_SET_ACTION(ACL_RSLT2, DES_PORT1, des_pts); + + des_pts = sw->ports & 0x7; + FIELD_SET_ACTION(ACL_RSLT1, DES_PORT0, des_pts); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REMARK_UP)) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REMARK_QUEUE)) + { + FIELD_SET_ACTION(ACL_RSLT1, PRI_QU_EN, 1); + FIELD_SET_ACTION(ACL_RSLT1, PRI_QU, sw->queue); + } + + if ((FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_MODIFY_VLAN)) + || (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_NEST_VLAN))) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REMARK_DSCP)) + { + FIELD_SET_ACTION(ACL_RSLT1, DSCPV, sw->dscp); + FIELD_SET_ACTION(ACL_RSLT1, DSCP_REMAP, 1); + } + + FIELD_SET_ACTION(ACL_RSLT0, STAGVID, sw->stag_vid); + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REMARK_STAG_VID)) + { + FIELD_SET_ACTION(ACL_RSLT1, TRANS_SVID_CHG, 1); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REMARK_STAG_PRI)) + { + FIELD_SET_ACTION(ACL_RSLT0, STAGPRI, sw->stag_pri); + FIELD_SET_ACTION(ACL_RSLT1, STAG_PRI_REMAP, 1); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REMARK_STAG_DEI)) + { + FIELD_SET_ACTION(ACL_RSLT0, STAGDEI, sw->stag_dei); + FIELD_SET_ACTION(ACL_RSLT1, STAG_DEI_CHG, 1); + } + + FIELD_SET_ACTION(ACL_RSLT0, CTAGVID, sw->ctag_vid); + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REMARK_CTAG_VID)) + { + FIELD_SET_ACTION(ACL_RSLT1, TRANS_CVID_CHG, 1); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REMARK_CTAG_PRI)) + { + FIELD_SET_ACTION(ACL_RSLT0, CTAGPRI, sw->ctag_pri); + FIELD_SET_ACTION(ACL_RSLT1, CTAG_PRI_REMAP, 1); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REMARK_CTAG_CFI)) + { + FIELD_SET_ACTION(ACL_RSLT0, CTAGCFI, sw->ctag_cfi); + FIELD_SET_ACTION(ACL_RSLT1, CTAG_CFI_CHG, 1); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REMARK_LOOKUP_VID)) + { + FIELD_SET_ACTION(ACL_RSLT1, LOOK_VID_CHG, 1); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_POLICER_EN)) + { + FIELD_SET_ACTION(ACL_RSLT2, POLICER_PTR, sw->policer_ptr); + FIELD_SET_ACTION(ACL_RSLT2, POLICER_EN, 1); + } + + if ((FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_ARP_EN)) + && (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_WCMP_EN))) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_ARP_EN)) + { + FIELD_SET_ACTION(ACL_RSLT1, ARP_PTR, sw->arp_ptr); + FIELD_SET_ACTION(ACL_RSLT1, ARP_PTR_EN, 1); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_WCMP_EN)) + { + FIELD_SET_ACTION(ACL_RSLT1, ARP_PTR, sw->wcmp_ptr); + FIELD_SET_ACTION(ACL_RSLT1, WCMP_EN, 1); + FIELD_SET_ACTION(ACL_RSLT1, ARP_PTR_EN, 1); + } + + FIELD_SET_ACTION(ACL_RSLT1, FORCE_L3_MODE, 0x0); + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_POLICY_FORWARD_EN)) + { + if (FAL_ACL_POLICY_ROUTE == sw->policy_fwd) + { + return SW_NOT_SUPPORTED; + } + else if (FAL_ACL_POLICY_SNAT == sw->policy_fwd) + { + FIELD_SET_ACTION(ACL_RSLT1, FORCE_L3_MODE, 0x1); + } + else if (FAL_ACL_POLICY_DNAT == sw->policy_fwd) + { + FIELD_SET_ACTION(ACL_RSLT1, FORCE_L3_MODE, 0x2); + } + else if (FAL_ACL_POLICY_RESERVE == sw->policy_fwd) + { + FIELD_SET_ACTION(ACL_RSLT1, FORCE_L3_MODE, 0x3); + } + else + { + return SW_BAD_PARAM; + } + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_BYPASS_EGRESS_TRANS)) + { + FIELD_SET_ACTION(ACL_RSLT2, EG_BYPASS, 1); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_MATCH_TRIGGER_INTR)) + { + FIELD_SET_ACTION(ACL_RSLT2, TRIGGER_INTR, 1); + } + + return SW_OK; +} + +static sw_error_t +_dess_acl_rule_bmac_reparse(fal_acl_rule_t * sw, const hw_filter_t * hw) +{ + a_uint32_t mask_en; + + /* destnation mac address */ + FIELD_GET(MAC_RUL_V0, DAV_BYTE2, sw->dest_mac_val.uc[2]); + FIELD_GET(MAC_RUL_V0, DAV_BYTE3, sw->dest_mac_val.uc[3]); + FIELD_GET(MAC_RUL_V0, DAV_BYTE4, sw->dest_mac_val.uc[4]); + FIELD_GET(MAC_RUL_V0, DAV_BYTE5, sw->dest_mac_val.uc[5]); + FIELD_GET(MAC_RUL_V1, DAV_BYTE0, sw->dest_mac_val.uc[0]); + FIELD_GET(MAC_RUL_V1, DAV_BYTE1, sw->dest_mac_val.uc[1]); + + FIELD_GET_MASK(MAC_RUL_M0, DAM_BYTE2, sw->dest_mac_mask.uc[2]); + FIELD_GET_MASK(MAC_RUL_M0, DAM_BYTE3, sw->dest_mac_mask.uc[3]); + FIELD_GET_MASK(MAC_RUL_M0, DAM_BYTE4, sw->dest_mac_mask.uc[4]); + FIELD_GET_MASK(MAC_RUL_M0, DAM_BYTE5, sw->dest_mac_mask.uc[5]); + FIELD_GET_MASK(MAC_RUL_M1, DAM_BYTE0, sw->dest_mac_mask.uc[0]); + FIELD_GET_MASK(MAC_RUL_M1, DAM_BYTE1, sw->dest_mac_mask.uc[1]); + if (A_FALSE == _dess_acl_zero_addr(sw->dest_mac_mask)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_DA); + } + + /* source mac address */ + FIELD_GET(MAC_RUL_V2, SAV_BYTE0, sw->src_mac_val.uc[0]); + FIELD_GET(MAC_RUL_V2, SAV_BYTE1, sw->src_mac_val.uc[1]); + FIELD_GET(MAC_RUL_V2, SAV_BYTE2, sw->src_mac_val.uc[2]); + FIELD_GET(MAC_RUL_V2, SAV_BYTE3, sw->src_mac_val.uc[3]); + FIELD_GET(MAC_RUL_V1, SAV_BYTE4, sw->src_mac_val.uc[4]); + FIELD_GET(MAC_RUL_V1, SAV_BYTE5, sw->src_mac_val.uc[5]); + + FIELD_GET_MASK(MAC_RUL_M2, SAM_BYTE0, sw->src_mac_mask.uc[0]); + FIELD_GET_MASK(MAC_RUL_M2, SAM_BYTE1, sw->src_mac_mask.uc[1]); + FIELD_GET_MASK(MAC_RUL_M2, SAM_BYTE2, sw->src_mac_mask.uc[2]); + FIELD_GET_MASK(MAC_RUL_M2, SAM_BYTE3, sw->src_mac_mask.uc[3]); + FIELD_GET_MASK(MAC_RUL_M1, SAM_BYTE4, sw->src_mac_mask.uc[4]); + FIELD_GET_MASK(MAC_RUL_M1, SAM_BYTE5, sw->src_mac_mask.uc[5]); + if (A_FALSE == _dess_acl_zero_addr(sw->src_mac_mask)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_SA); + } + + /* ethernet type */ + FIELD_GET(MAC_RUL_V3, ETHTYPV, sw->ethtype_val); + FIELD_GET_MASK(MAC_RUL_M3, ETHTYPM, sw->ethtype_mask); + if (0x0 != sw->ethtype_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_ETHTYPE); + } + + /* packet tagged */ + FIELD_GET_MASK(MAC_RUL_M4, TAGGEDV, sw->tagged_val); + FIELD_GET_MASK(MAC_RUL_M4, TAGGEDM, sw->tagged_mask); + if (0x0 != sw->tagged_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_TAGGED); + } + + /* vlan priority */ + FIELD_GET(MAC_RUL_V3, VLANPRIV, sw->up_val); + FIELD_GET_MASK(MAC_RUL_M3, VLANPRIM, sw->up_mask); + if (0x0 != sw->up_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_UP); + } + + /* vlanid */ + FIELD_GET(MAC_RUL_V3, VLANIDV, sw->vid_val); + FIELD_GET_MASK(MAC_RUL_M3, VLANIDM, sw->vid_mask); + FIELD_GET_MASK(MAC_RUL_M4, VIDMSK, mask_en); + if (mask_en) + { + sw->vid_op = FAL_ACL_FIELD_MASK; + } + else + { + sw->vid_op = FAL_ACL_FIELD_RANGE; + } + + if (A_TRUE == + _dess_acl_field_care(sw->vid_op, (a_uint32_t) sw->vid_val, + (a_uint32_t) sw->vid_mask, 0xfff)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_VID); + } + + /* vlan cfi */ + FIELD_GET(MAC_RUL_V3, VLANCFIV, sw->cfi_val); + FIELD_GET_MASK(MAC_RUL_M3, VLANCFIM, sw->cfi_mask); + if (0x0 != sw->cfi_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_CFI); + } + + FIELD_GET(MAC_RUL_V4, RULE_INV, mask_en); + if (mask_en) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL); + } + + return SW_OK; +} + +static sw_error_t +_dess_acl_rule_ehmac_reparse(fal_acl_rule_t * sw, const hw_filter_t * hw) +{ + a_uint32_t i, mask_en, data; + + FIELD_GET(EHMAC_RUL_V3, DA_EN, data); + if (data) + { + for (i = 2; i < 6; i++) + { + sw->dest_mac_val.uc[i] = ((hw->vlu[0]) >> ((5 - i) << 3)) & 0xff; + sw->dest_mac_mask.uc[i] = ((hw->msk[0]) >> ((5 - i) << 3)) & 0xff; + } + + for (i = 0; i < 2; i++) + { + sw->dest_mac_val.uc[i] = ((hw->vlu[1]) >> ((1 - i) << 3)) & 0xff; + sw->dest_mac_mask.uc[i] = ((hw->msk[1]) >> ((1 - i) << 3)) & 0xff; + } + + if (A_FALSE == _dess_acl_zero_addr(sw->dest_mac_mask)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_DA); + } + + FIELD_GET(EHMAC_RUL_V2, SAV_BYTE3, sw->src_mac_val.uc[3]); + FIELD_GET(EHMAC_RUL_V1, SAV_BYTE4, sw->src_mac_val.uc[4]); + FIELD_GET(EHMAC_RUL_V1, SAV_BYTE5, sw->src_mac_val.uc[5]); + + FIELD_GET_MASK(EHMAC_RUL_M2, SAM_BYTE3, sw->src_mac_mask.uc[3]); + FIELD_GET_MASK(EHMAC_RUL_M1, SAM_BYTE4, sw->src_mac_mask.uc[4]); + FIELD_GET_MASK(EHMAC_RUL_M1, SAM_BYTE5, sw->src_mac_mask.uc[5]); + + if (A_FALSE == _dess_acl_zero_addr(sw->src_mac_mask)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_SA); + } + } + else + { + for (i = 2; i < 6; i++) + { + sw->src_mac_val.uc[i] = ((hw->vlu[0]) >> ((5 - i) << 3)) & 0xff; + sw->src_mac_mask.uc[i] = ((hw->msk[0]) >> ((5 - i) << 3)) & 0xff; + } + + for (i = 0; i < 2; i++) + { + sw->src_mac_val.uc[i] = ((hw->vlu[1]) >> ((1 - i) << 3)) & 0xff; + sw->src_mac_mask.uc[i] = ((hw->msk[1]) >> ((1 - i) << 3)) & 0xff; + } + + if (A_FALSE == _dess_acl_zero_addr(sw->src_mac_mask)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_SA); + } + + FIELD_GET(EHMAC_RUL_V2, SAV_BYTE3, sw->dest_mac_val.uc[3]); + FIELD_GET(EHMAC_RUL_V1, SAV_BYTE4, sw->dest_mac_val.uc[4]); + FIELD_GET(EHMAC_RUL_V1, SAV_BYTE5, sw->dest_mac_val.uc[5]); + + FIELD_GET_MASK(EHMAC_RUL_M2, SAM_BYTE3, sw->dest_mac_mask.uc[3]); + FIELD_GET_MASK(EHMAC_RUL_M1, SAM_BYTE4, sw->dest_mac_mask.uc[4]); + FIELD_GET_MASK(EHMAC_RUL_M1, SAM_BYTE5, sw->dest_mac_mask.uc[5]); + if (A_FALSE == _dess_acl_zero_addr(sw->dest_mac_mask)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_DA); + } + } + + /* ethernet type */ + FIELD_GET(EHMAC_RUL_V3, ETHTYPV, sw->ethtype_val); + FIELD_GET_MASK(EHMAC_RUL_M3, ETHTYPM, sw->ethtype_mask); + if (0x0 != sw->ethtype_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_ETHTYPE); + } + + /* packet stagged */ + FIELD_GET(EHMAC_RUL_V3, STAGGEDV, sw->stagged_val); + FIELD_GET(EHMAC_RUL_V3, STAGGEDM, sw->stagged_mask); + if (0x0 != sw->stagged_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_STAGGED); + } + + /* stag vid */ + FIELD_GET(EHMAC_RUL_V2, STAG_VIDV, sw->stag_vid_val); + FIELD_GET_MASK(EHMAC_RUL_M2, STAG_VIDM, sw->stag_vid_mask); + FIELD_GET(EHMAC_RUL_V3, SVIDMSK, mask_en); + if (mask_en) + { + sw->stag_vid_op = FAL_ACL_FIELD_MASK; + } + else + { + sw->stag_vid_op = FAL_ACL_FIELD_RANGE; + } + + if (A_TRUE == + _dess_acl_field_care(sw->stag_vid_op, (a_uint32_t) sw->stag_vid_val, + (a_uint32_t) sw->stag_vid_mask, 0xfff)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_STAG_VID); + } + + /* stag priority */ + FIELD_GET(EHMAC_RUL_V2, STAG_PRIV, sw->stag_pri_val); + FIELD_GET_MASK(EHMAC_RUL_M2, STAG_PRIM, sw->stag_pri_mask); + if (0x0 != sw->stag_pri_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_STAG_PRI); + } + + /* stag dei */ + FIELD_GET(EHMAC_RUL_V2, STAG_DEIV, sw->stag_dei_val); + FIELD_GET_MASK(EHMAC_RUL_M2, STAG_DEIM, sw->stag_dei_mask); + if (0x0 != sw->stag_dei_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_STAG_DEI); + } + + /* packet ctagged */ + FIELD_GET_MASK(EHMAC_RUL_M4, CTAGGEDV, sw->ctagged_val); + FIELD_GET_MASK(EHMAC_RUL_M4, CTAGGEDM, sw->ctagged_mask); + if (0x0 != sw->ctagged_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_CTAGGED); + } + + /* ctag vid */ + FIELD_GET(EHMAC_RUL_V2, CTAG_VIDLV, sw->ctag_vid_val); + FIELD_GET(EHMAC_RUL_V3, CTAG_VIDHV, data); + sw->ctag_vid_val |= (data << 8); + FIELD_GET_MASK(EHMAC_RUL_M2, CTAG_VIDLM, sw->ctag_vid_mask); + FIELD_GET_MASK(EHMAC_RUL_M3, CTAG_VIDHM, data); + sw->ctag_vid_mask |= (data << 8); + + FIELD_GET_MASK(EHMAC_RUL_M4, CVIDMSK, mask_en); + if (mask_en) + { + sw->ctag_vid_op = FAL_ACL_FIELD_MASK; + } + else + { + sw->ctag_vid_op = FAL_ACL_FIELD_RANGE; + } + + if (A_TRUE == + _dess_acl_field_care(sw->ctag_vid_op, (a_uint32_t) sw->ctag_vid_val, + (a_uint32_t) sw->ctag_vid_mask, 0xfff)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_CTAG_VID); + } + + /* ctag priority */ + FIELD_GET(EHMAC_RUL_V3, CTAG_PRIV, sw->ctag_pri_val); + FIELD_GET_MASK(EHMAC_RUL_M3, CTAG_PRIM, sw->ctag_pri_mask); + if (0x0 != sw->ctag_pri_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_CTAG_PRI); + } + + /* ctag dei */ + FIELD_GET(EHMAC_RUL_V3, CTAG_CFIV, sw->ctag_cfi_val); + FIELD_GET_MASK(EHMAC_RUL_M3, CTAG_CFIM, sw->ctag_cfi_mask); + if (0x0 != sw->ctag_cfi_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_CTAG_CFI); + } + + FIELD_GET(MAC_RUL_V4, RULE_INV, mask_en); + if (mask_en) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL); + } + + return SW_OK; +} + +static sw_error_t +_dess_acl_rule_ip4_reparse(fal_acl_rule_t * sw, const hw_filter_t * hw) +{ + a_uint32_t mask_en, icmp_en; + + sw->dest_ip4_val = hw->vlu[0]; + sw->dest_ip4_mask = hw->msk[0]; + if (0x0 != sw->dest_ip4_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP4_DIP); + } + + sw->src_ip4_val = hw->vlu[1]; + sw->src_ip4_mask = hw->msk[1]; + if (0x0 != sw->src_ip4_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP4_SIP); + } + + FIELD_GET(IP4_RUL_V2, IP4PROTV, sw->ip_proto_val); + FIELD_GET_MASK(IP4_RUL_M2, IP4PROTM, sw->ip_proto_mask); + if (0x0 != sw->ip_proto_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP_PROTO); + } + + FIELD_GET(IP4_RUL_V2, IP4DSCPV, sw->ip_dscp_val); + FIELD_GET_MASK(IP4_RUL_M2, IP4DSCPM, sw->ip_dscp_mask); + if (0x0 != sw->ip_dscp_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP_DSCP); + } + + FIELD_GET(IP4_RUL_V2, IP4DPORTV, sw->dest_l4port_val); + FIELD_GET_MASK(IP4_RUL_M2, IP4DPORTM, sw->dest_l4port_mask); + FIELD_GET_MASK(IP4_RUL_M3, IP4DPORTM_EN, mask_en); + if (mask_en) + { + sw->dest_l4port_op = FAL_ACL_FIELD_MASK; + } + else + { + sw->dest_l4port_op = FAL_ACL_FIELD_RANGE; + } + + if (A_TRUE == + _dess_acl_field_care(sw->dest_l4port_op, + (a_uint32_t) sw->dest_l4port_val, + (a_uint32_t) sw->dest_l4port_mask, 0xffff)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_DPORT); + } + else if (FAL_ACL_FIELD_RANGE == sw->dest_l4port_op) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_DPORT); + } + + FIELD_GET(IP4_RUL_V3, ICMP_EN, icmp_en); + if (icmp_en) + { + FIELD_GET(IP4_RUL_V3, IP4ICMPTYPV, sw->icmp_type_val); + FIELD_GET_MASK(IP4_RUL_M3, IP4ICMPTYPM, sw->icmp_type_mask); + if (0x0 != sw->icmp_type_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_ICMP_TYPE); + } + + FIELD_GET(IP4_RUL_V3, IP4ICMPCODEV, sw->icmp_code_val); + FIELD_GET_MASK(IP4_RUL_M3, IP4ICMPCODEM, sw->icmp_code_mask); + if (0x0 != sw->icmp_code_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_ICMP_CODE); + } + } + else + { + FIELD_GET(IP4_RUL_V3, IP4SPORTV, sw->src_l4port_val); + FIELD_GET_MASK(IP4_RUL_M3, IP4SPORTM, sw->src_l4port_mask); + FIELD_GET_MASK(IP4_RUL_M3, IP4SPORTM_EN, mask_en); + if (mask_en) + { + sw->src_l4port_op = FAL_ACL_FIELD_MASK; + } + else + { + sw->src_l4port_op = FAL_ACL_FIELD_RANGE; + } + + if (A_TRUE == + _dess_acl_field_care(sw->src_l4port_op, + (a_uint32_t) sw->src_l4port_val, + (a_uint32_t) sw->src_l4port_mask, 0xffff)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_SPORT); + } + else if (FAL_ACL_FIELD_RANGE == sw->src_l4port_op) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_SPORT); + } + } + + FIELD_GET(IP4_RUL_V3, IP4TCPFLAGV, sw->tcp_flag_val); + FIELD_GET_MASK(IP4_RUL_M3, IP4TCPFLAGM, sw->tcp_flag_mask); + if (0x0 != sw->tcp_flag_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_TCP_FLAG); + } + + FIELD_GET(IP4_RUL_V3, IP4RIPV, sw->ripv1_val); + FIELD_GET_MASK(IP4_RUL_M3, IP4RIPM, sw->ripv1_mask); + if (0x0 != sw->ripv1_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_RIPV1); + } + + FIELD_GET(IP4_RUL_V3, IP4DHCPV, sw->dhcpv4_val); + FIELD_GET_MASK(IP4_RUL_M3, IP4DHCPM, sw->dhcpv4_mask); + if (0x0 != sw->dhcpv4_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_DHCPV4); + } + + FIELD_GET(MAC_RUL_V4, RULE_INV, mask_en); + if (mask_en) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL); + } + + return SW_OK; +} + +static sw_error_t +_dess_acl_rule_ip6r1_reparse(fal_acl_rule_t * sw, const hw_filter_t * hw) +{ + a_uint32_t i; + + for (i = 0; i < 4; i++) + { + sw->dest_ip6_val.ul[i] = hw->vlu[3 - i]; + sw->dest_ip6_mask.ul[i] = hw->msk[3 - i]; + if (0x0 != sw->dest_ip6_mask.ul[i]) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP6_DIP); + } + } + + FIELD_GET(MAC_RUL_V4, RULE_INV, i); + if (i) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL); + } + + return SW_OK; +} + +static sw_error_t +_dess_acl_rule_ip6r2_reparse(fal_acl_rule_t * sw, const hw_filter_t * hw) +{ + a_uint32_t i; + + for (i = 0; i < 4; i++) + { + sw->src_ip6_val.ul[i] = hw->vlu[3 - i]; + sw->src_ip6_mask.ul[i] = hw->msk[3 - i]; + if (0x0 != sw->src_ip6_mask.ul[i]) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP6_SIP); + } + } + + FIELD_GET(MAC_RUL_V4, RULE_INV, i); + if (i) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL); + } + + return SW_OK; +} + +static sw_error_t +_dess_acl_rule_ip6r3_reparse(fal_acl_rule_t * sw, const hw_filter_t * hw) +{ + a_uint32_t mask_en, icmp6_en, tmp; + + FIELD_GET(IP6_RUL3_V0, IP6PROTV, sw->ip_proto_val); + FIELD_GET_MASK(IP6_RUL3_M0, IP6PROTM, sw->ip_proto_mask); + if (0x0 != sw->ip_proto_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP_PROTO); + } + + FIELD_GET(IP6_RUL3_V0, IP6DSCPV, sw->ip_dscp_val); + FIELD_GET_MASK(IP6_RUL3_M0, IP6DSCPM, sw->ip_dscp_mask); + if (0x0 != sw->ip_dscp_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP_DSCP); + } + + FIELD_GET(IP6_RUL3_V2, IP6DPORTV, sw->dest_l4port_val); + FIELD_GET_MASK(IP6_RUL3_M2, IP6DPORTM, sw->dest_l4port_mask); + FIELD_GET_MASK(IP6_RUL3_M3, IP6DPORTM_EN, mask_en); + if (mask_en) + { + sw->dest_l4port_op = FAL_ACL_FIELD_MASK; + } + else + { + sw->dest_l4port_op = FAL_ACL_FIELD_RANGE; + } + + if (A_TRUE == + _dess_acl_field_care(sw->dest_l4port_op, + (a_uint32_t) sw->dest_l4port_val, + (a_uint32_t) sw->dest_l4port_mask, 0xffff)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_DPORT); + } + else if (FAL_ACL_FIELD_RANGE == sw->dest_l4port_op) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_DPORT); + } + + FIELD_GET(IP6_RUL3_V3, ICMP6_EN, icmp6_en); + if (icmp6_en) + { + FIELD_GET(IP6_RUL3_V3, IP6ICMPTYPV, sw->icmp_type_val); + FIELD_GET_MASK(IP6_RUL3_M3, IP6ICMPTYPM, sw->icmp_type_mask); + if (0x0 != sw->icmp_type_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_ICMP_TYPE); + } + + FIELD_GET(IP6_RUL3_V3, IP6ICMPCODEV, sw->icmp_code_val); + FIELD_GET_MASK(IP6_RUL3_M3, IP6ICMPCODEM, sw->icmp_code_mask); + if (0x0 != sw->icmp_code_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_ICMP_CODE); + } + } + else + { + FIELD_GET(IP6_RUL3_V3, IP6SPORTV, sw->src_l4port_val); + FIELD_GET_MASK(IP6_RUL3_M3, IP6SPORTM, sw->src_l4port_mask); + FIELD_GET_MASK(IP6_RUL3_M3, IP6SPORTM_EN, mask_en); + if (mask_en) + { + sw->src_l4port_op = FAL_ACL_FIELD_MASK; + } + else + { + sw->src_l4port_op = FAL_ACL_FIELD_RANGE; + } + + if (A_TRUE == + _dess_acl_field_care(sw->src_l4port_op, + (a_uint32_t) sw->src_l4port_val, + (a_uint32_t) sw->src_l4port_mask, 0xffff)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_SPORT); + } + else if (FAL_ACL_FIELD_RANGE == sw->src_l4port_op) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_SPORT); + } + } + + FIELD_GET(IP6_RUL3_V1, IP6LABEL1V, sw->ip6_lable_val); + FIELD_GET_MASK(IP6_RUL3_M1, IP6LABEL1M, sw->ip6_lable_mask); + + FIELD_GET(IP6_RUL3_V2, IP6LABEL2V, tmp); + sw->ip6_lable_val |= (tmp << 16); + FIELD_GET_MASK(IP6_RUL3_M2, IP6LABEL2M, tmp); + sw->ip6_lable_mask |= (tmp << 16); + + if (0x0 != sw->ip6_lable_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP6_LABEL); + } + + FIELD_GET(IP6_RUL3_V3, IP6TCPFLAGV, sw->tcp_flag_val); + FIELD_GET_MASK(IP6_RUL3_M3, IP6TCPFLAGM, sw->tcp_flag_mask); + if (0x0 != sw->tcp_flag_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_TCP_FLAG); + } + + FIELD_GET(IP6_RUL3_V3, IP6DHCPV, sw->dhcpv6_val); + FIELD_GET_MASK(IP6_RUL3_M3, IP6DHCPM, sw->dhcpv6_mask); + if (0x0 != sw->dhcpv6_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_DHCPV6); + } + + FIELD_GET(MAC_RUL_V4, RULE_INV, mask_en); + if (mask_en) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL); + } + + return SW_OK; +} + +static sw_error_t +_dess_acl_rule_udf_reparse(fal_acl_rule_t * sw, const hw_filter_t * hw) +{ + a_uint32_t i; + + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_UDF); + + /* for ISIS UDF type, length and offset no meanging in rules, just set default value */ + sw->udf_type = FAL_ACL_UDF_TYPE_L2; + sw->udf_len = 16; + sw->udf_offset = 0; + + for (i = 0; i < DESS_MAX_UDF_LENGTH; i++) + { + sw->udf_val[i] = ((hw->vlu[3 - i / 4]) >> (24 - 8 * (i % 4))) & 0xff; + sw->udf_mask[i] = ((hw->msk[3 - i / 4]) >> (24 - 8 * (i % 4))) & 0xff; + } + + FIELD_GET(MAC_RUL_V4, RULE_INV, i); + if (i) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL); + } + + return SW_OK; +} + +static sw_error_t +_dess_acl_rule_action_reparse(fal_acl_rule_t * sw, const hw_filter_t * hw) +{ + a_uint32_t data; + + sw->action_flg = 0; + + FIELD_GET_ACTION(ACL_RSLT2, DES_PORT_EN, data); + if (1 == data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REDPT); + FIELD_GET_ACTION(ACL_RSLT1, DES_PORT0, sw->ports); + FIELD_GET_ACTION(ACL_RSLT2, DES_PORT1, data); + sw->ports |= (data << 3); + } + + FIELD_GET_ACTION(ACL_RSLT2, FWD_CMD, data); + if (0x7 == data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_DENY); + } + else if (0x3 == data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_RDTCPU); + } + else if (0x1 == data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_CPYCPU); + } + else + { + /* need't set permit action */ + } + + FIELD_GET_ACTION(ACL_RSLT2, MIRR_EN, data); + if (1 == data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_MIRROR); + } + + FIELD_GET_ACTION(ACL_RSLT1, PRI_QU_EN, data); + if (1 == data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REMARK_QUEUE); + FIELD_GET_ACTION(ACL_RSLT1, PRI_QU, sw->queue); + } + + FIELD_GET_ACTION(ACL_RSLT1, DSCP_REMAP, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REMARK_DSCP); + FIELD_GET_ACTION(ACL_RSLT1, DSCPV, sw->dscp); + } + + FIELD_GET_ACTION(ACL_RSLT0, STAGVID, sw->stag_vid); + + FIELD_GET_ACTION(ACL_RSLT1, TRANS_SVID_CHG, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REMARK_STAG_VID); + } + + FIELD_GET_ACTION(ACL_RSLT1, STAG_PRI_REMAP, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REMARK_STAG_PRI); + FIELD_GET_ACTION(ACL_RSLT0, STAGPRI, sw->stag_pri); + } + + FIELD_GET_ACTION(ACL_RSLT1, STAG_DEI_CHG, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REMARK_STAG_DEI); + FIELD_GET_ACTION(ACL_RSLT0, STAGDEI, sw->stag_dei); + } + + FIELD_GET_ACTION(ACL_RSLT0, CTAGVID, sw->ctag_vid); + + FIELD_GET_ACTION(ACL_RSLT1, TRANS_CVID_CHG, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REMARK_CTAG_VID); + } + + FIELD_GET_ACTION(ACL_RSLT1, CTAG_PRI_REMAP, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REMARK_CTAG_PRI); + FIELD_GET_ACTION(ACL_RSLT0, CTAGPRI, sw->ctag_pri); + } + + FIELD_GET_ACTION(ACL_RSLT1, CTAG_CFI_CHG, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REMARK_CTAG_CFI); + FIELD_GET_ACTION(ACL_RSLT0, CTAGCFI, sw->ctag_cfi); + } + + FIELD_GET_ACTION(ACL_RSLT1, LOOK_VID_CHG, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REMARK_LOOKUP_VID); + } + + FIELD_GET_ACTION(ACL_RSLT2, POLICER_EN, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_POLICER_EN); + FIELD_GET_ACTION(ACL_RSLT2, POLICER_PTR, sw->policer_ptr); + } + + FIELD_GET_ACTION(ACL_RSLT1, ARP_PTR_EN, data); + if (data) + { + FIELD_GET_ACTION(ACL_RSLT1, WCMP_EN, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_WCMP_EN); + FIELD_GET_ACTION(ACL_RSLT1, ARP_PTR, sw->wcmp_ptr); + } + else + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_ARP_EN); + FIELD_GET_ACTION(ACL_RSLT1, ARP_PTR, sw->arp_ptr); + } + } + + FIELD_GET_ACTION(ACL_RSLT1, FORCE_L3_MODE, data); + if ((0 != data) && (3 != data)) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_POLICY_FORWARD_EN); + if (0x1 == data) + { + sw->policy_fwd = FAL_ACL_POLICY_SNAT; + } + else + { + sw->policy_fwd = FAL_ACL_POLICY_DNAT; + } + } + + FIELD_GET_ACTION(ACL_RSLT2, EG_BYPASS, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_BYPASS_EGRESS_TRANS); + } + + FIELD_GET_ACTION(ACL_RSLT2, TRIGGER_INTR, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_MATCH_TRIGGER_INTR); + } + + return SW_OK; +} + +sw_error_t +_dess_acl_rule_sw_to_hw(a_uint32_t dev_id, fal_acl_rule_t * sw, + dess_acl_rule_t * hw_rule_snap, a_uint32_t * idx) +{ + sw_error_t rv; + a_uint32_t tmp_idx, i, b_rule[7] = { 0 }; + parse_func_t ptr[7] = { NULL }; + a_bool_t b_care, b_mac, eh_mac; + + rv = _dess_acl_action_parse(dev_id, sw, &(hw_rule_snap[*idx].filter)); + SW_RTN_ON_ERROR(rv); + + ptr[0] = _dess_acl_rule_udf_parse; + _dess_acl_rule_mac_preparse(sw, &b_mac, &eh_mac); + + /* ehmac rule must be parsed bofore mac rule. + it's important for reparse process */ + if (A_TRUE == eh_mac) + { + ptr[1] = _dess_acl_rule_ehmac_parse; + } + + if (A_TRUE == b_mac) + { + ptr[2] = _dess_acl_rule_bmac_parse; + } + + if ((A_FALSE == b_mac) && (A_FALSE == eh_mac)) + { + ptr[2] = _dess_acl_rule_bmac_parse; + } + + if (FAL_ACL_RULE_MAC == sw->rule_type) + { + } + else if (FAL_ACL_RULE_IP4 == sw->rule_type) + { + ptr[3] = _dess_acl_rule_ip4_parse; + } + else if (FAL_ACL_RULE_IP6 == sw->rule_type) + { + ptr[4] = _dess_acl_rule_ip6r1_parse; + ptr[5] = _dess_acl_rule_ip6r2_parse; + ptr[6] = _dess_acl_rule_ip6r3_parse; + } + else if (FAL_ACL_RULE_UDF == sw->rule_type) + { + ptr[1] = NULL; + ptr[2] = NULL; + } + else + { + return SW_NOT_SUPPORTED; + } + + tmp_idx = *idx; + for (i = 0; i < 7; i++) + { + if (ptr[i]) + { + if (DESS_HW_RULE_TMP_CNT <= tmp_idx) + { + return SW_NO_RESOURCE; + } + + rv = ptr[i] (sw, &(hw_rule_snap[tmp_idx].filter), &b_care); + SW_RTN_ON_ERROR(rv); + if (A_TRUE == b_care) + { + tmp_idx++; + b_rule[i] = 1; + } + } + } + + if (FAL_ACL_RULE_IP6 == sw->rule_type) + { + if ((!b_rule[4]) && (!b_rule[5]) && (!b_rule[6])) + { + tmp_idx++; + } + } + + if (FAL_ACL_RULE_IP4 == sw->rule_type) + { + if (!b_rule[3]) + { + tmp_idx++; + } + } + + if (tmp_idx == *idx) + { + /* set type start & end */ + SW_SET_REG_BY_FIELD(MAC_RUL_M4, RULE_VALID, FLT_STARTEND, + (hw_rule_snap[*idx].filter.msk[4])); + (*idx)++; + } + else + { + if (1 == (tmp_idx - *idx)) + { + if (FAL_ACL_COMBINED_START == sw->combined) + { + SW_SET_REG_BY_FIELD(MAC_RUL_M4, RULE_VALID, FLT_START, + (hw_rule_snap[*idx].filter.msk[4])); + } + else if (FAL_ACL_COMBINED_CONTINUE == sw->combined) + { + SW_SET_REG_BY_FIELD(MAC_RUL_M4, RULE_VALID, FLT_CONTINUE, + (hw_rule_snap[*idx].filter.msk[4])); + } + else if (FAL_ACL_COMBINED_END == sw->combined) + { + SW_SET_REG_BY_FIELD(MAC_RUL_M4, RULE_VALID, FLT_END, + (hw_rule_snap[*idx].filter.msk[4])); + } + else + { + SW_SET_REG_BY_FIELD(MAC_RUL_M4, RULE_VALID, FLT_STARTEND, + (hw_rule_snap[*idx].filter.msk[4])); + } + } + else + { + for (i = *idx; i < tmp_idx; i++) + { + if (i == *idx) + { + SW_SET_REG_BY_FIELD(MAC_RUL_M4, RULE_VALID, FLT_START, + (hw_rule_snap[i].filter.msk[4])); + } + else if (i == (tmp_idx - 1)) + { + SW_SET_REG_BY_FIELD(MAC_RUL_M4, RULE_VALID, FLT_END, + (hw_rule_snap[i].filter.msk[4])); + } + else + { + SW_SET_REG_BY_FIELD(MAC_RUL_M4, RULE_VALID, FLT_CONTINUE, + (hw_rule_snap[i].filter.msk[4])); + } + aos_mem_copy(&(hw_rule_snap[i].filter.act[0]), + &(hw_rule_snap[*idx].filter.act[0]), + sizeof (hw_rule_snap[*idx].filter.act)); + } + } + *idx = tmp_idx; + } + + return SW_OK; +} + +sw_error_t +_dess_acl_rule_hw_to_sw(a_uint32_t dev_id, fal_acl_rule_t * sw, + dess_acl_rule_t * hw_rule_snap, a_uint32_t idx, + a_uint32_t ent_nr) +{ + a_bool_t b_mac = A_FALSE, b_ip4 = A_FALSE, b_ip6 = A_FALSE; + sw_error_t rv; + a_uint32_t i, flt_typ; + hw_filter_t *hw; + + rv = _dess_acl_rule_action_reparse(sw, &(hw_rule_snap[idx].filter)); + SW_RTN_ON_ERROR(rv); + + sw->rule_type = FAL_ACL_RULE_UDF; + for (i = 0; i < ent_nr; i++) + { + hw = &(hw_rule_snap[idx + i].filter); + FIELD_GET_MASK(MAC_RUL_M4, RULE_TYP, flt_typ); + + if (DESS_UDF_FILTER == flt_typ) + { + rv = _dess_acl_rule_udf_reparse(sw, hw); + SW_RTN_ON_ERROR(rv); + } + else if (DESS_MAC_FILTER == flt_typ) + { + rv = _dess_acl_rule_bmac_reparse(sw, hw); + SW_RTN_ON_ERROR(rv); + b_mac = A_TRUE; + } + else if (DESS_EHMAC_FILTER == flt_typ) + { + rv = _dess_acl_rule_ehmac_reparse(sw, hw); + SW_RTN_ON_ERROR(rv); + b_mac = A_TRUE; + } + else if (DESS_IP4_FILTER == flt_typ) + { + rv = _dess_acl_rule_ip4_reparse(sw, hw); + SW_RTN_ON_ERROR(rv); + b_ip4 = A_TRUE; + } + else if (DESS_IP6R1_FILTER == flt_typ) + { + rv = _dess_acl_rule_ip6r1_reparse(sw, hw); + SW_RTN_ON_ERROR(rv); + b_ip6 = A_TRUE; + } + else if (DESS_IP6R2_FILTER == flt_typ) + { + rv = _dess_acl_rule_ip6r2_reparse(sw, hw); + SW_RTN_ON_ERROR(rv); + b_ip6 = A_TRUE; + } + else if (DESS_IP6R3_FILTER == flt_typ) + { + rv = _dess_acl_rule_ip6r3_reparse(sw, hw); + SW_RTN_ON_ERROR(rv); + b_ip6 = A_TRUE; + } + else + { + /* ignore fill gap filters */ + } + } + + if (A_TRUE == b_mac) + { + sw->rule_type = FAL_ACL_RULE_MAC; + } + + if (A_TRUE == b_ip4) + { + sw->rule_type = FAL_ACL_RULE_IP4; + } + + if (A_TRUE == b_ip6) + { + sw->rule_type = FAL_ACL_RULE_IP6; + } + + return SW_OK; +} diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_acl_prv.h b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_acl_prv.h new file mode 100755 index 000000000..83a7d40a5 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_acl_prv.h @@ -0,0 +1,126 @@ +/* + * 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. + */ + + + +typedef struct +{ + a_uint8_t status; + a_uint8_t list_id; + a_uint8_t list_pri; + a_uint8_t rule_nr; + fal_pbmp_t bind_pts; +} dess_acl_list_t; + + +typedef struct +{ + a_uint32_t vlu[5]; + a_uint32_t msk[5]; + a_uint32_t act[3]; +} hw_filter_t; + + +typedef struct +{ + a_uint8_t status; + a_uint8_t list_id; + a_uint8_t list_pri; + a_uint8_t rule_id; + hw_filter_t filter; + a_uint32_t src_flt_dis; /* src filter disabled */ +} dess_acl_rule_t; + + +#define ENT_USED 0x1 +#define ENT_TMP 0x2 +#define ENT_DEACTIVE 0x4 + +#define FLT_START 0x0 +#define FLT_CONTINUE 0x1 +#define FLT_END 0x2 +#define FLT_STARTEND 0x3 + + +#define DESS_MAC_FILTER 1 +#define DESS_IP4_FILTER 2 +#define DESS_IP6R1_FILTER 3 +#define DESS_IP6R2_FILTER 4 +#define DESS_IP6R3_FILTER 5 +#define DESS_UDF_FILTER 6 +#define DESS_EHMAC_FILTER 7 + + +#define DESS_MAX_UDF_OFFSET 31 +#define DESS_MAX_UDF_LENGTH 16 + + +#define DESS_FILTER_VLU_OP 0x0 +#define DESS_FILTER_MSK_OP 0x1 +#define DESS_FILTER_ACT_OP 0x2 + + + +//#define DESS_MAX_FILTER 8 +#define DESS_MAX_FILTER 96 +#define DESS_RULE_FUNC_ADDR 0x0400 +#define DESS_HW_RULE_TMP_CNT (DESS_MAX_FILTER + 4) + +#define DESS_MAX_LIST_ID 255 +#define DESS_MAX_LIST_PRI 255 + +#define DESS_UDF_MAX_LENGTH 15 +#define DESS_UDF_MAX_OFFSET 31 + +#define WIN_RULE_CTL0_ADDR 0x218 +#define WIN_RULE_CTL1_ADDR 0x234 + + +#define DESS_FILTER_VLU_ADDR 0x58000 +#define DESS_FILTER_MSK_ADDR 0x59000 +#define DESS_FILTER_ACT_ADDR 0x5a000 + + +#define FIELD_SET(reg, field, val) \ + SW_REG_SET_BY_FIELD_U32(hw->vlu[reg], val, reg##_##field##_BOFFSET, \ + reg##_##field##_BLEN) + +#define FIELD_GET(reg, field, val) \ + SW_FIELD_GET_BY_REG_U32(hw->vlu[reg], val, reg##_##field##_BOFFSET, \ + reg##_##field##_BLEN) + +#define FIELD_SET_MASK(reg, field, val) \ + SW_REG_SET_BY_FIELD_U32(hw->msk[reg-5], val, reg##_##field##_BOFFSET, \ + reg##_##field##_BLEN) + +#define FIELD_GET_MASK(reg, field, val) \ + SW_FIELD_GET_BY_REG_U32(hw->msk[reg-5], val, reg##_##field##_BOFFSET, \ + reg##_##field##_BLEN) + +#define FIELD_SET_ACTION(reg, field, val) \ + SW_REG_SET_BY_FIELD_U32(hw->act[reg-10], val, reg##_##field##_BOFFSET, \ + reg##_##field##_BLEN) + +#define FIELD_GET_ACTION(reg, field, val) \ + SW_FIELD_GET_BY_REG_U32(hw->act[reg-10], val, reg##_##field##_BOFFSET, \ + reg##_##field##_BLEN) + +sw_error_t +_dess_acl_rule_sw_to_hw(a_uint32_t dev_id, fal_acl_rule_t * sw, dess_acl_rule_t * hw_filter_snap, a_uint32_t * idx); + + +sw_error_t +_dess_acl_rule_hw_to_sw(a_uint32_t dev_id, fal_acl_rule_t * sw, dess_acl_rule_t * hw_filter_snap, a_uint32_t idx, a_uint32_t ent_nr); + + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_cosmap.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_cosmap.c new file mode 100755 index 000000000..593c57382 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_cosmap.c @@ -0,0 +1,945 @@ +/* + * Copyright (c) 2014, 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. + */ + + +/** + * @defgroup dess_cosmap DESS_COSMAP + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "dess_cosmap.h" +#include "dess_reg.h" + +#define DESS_MAX_DSCP 63 +#define DESS_MAX_UP 7 +#define DESS_MAX_PRI 7 +#define DESS_MAX_DP 1 +#define DESS_MAX_QUEUE 3 +#define DESS_MAX_EH_QUEUE 5 + +#define DESS_DSCP_TO_PRI 0 +#define DESS_DSCP_TO_DP 1 +#define DESS_UP_TO_PRI 2 +#define DESS_UP_TO_DP 3 + +#define DESS_EGRESS_REAMRK_ADDR 0x5ae00 +#define DESS_EGRESS_REAMRK_NUM 16 + +static sw_error_t +_dess_cosmap_dscp_to_pri_dp_set(a_uint32_t dev_id, a_uint32_t mode, + a_uint32_t dscp, a_uint32_t val) +{ + sw_error_t rv; + a_uint32_t index, data = 0; + + if (DESS_MAX_DSCP < dscp) + { + return SW_BAD_PARAM; + } + + index = dscp >> 3; + HSL_REG_ENTRY_GET(rv, dev_id, DSCP_TO_PRI, index, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (DESS_DSCP_TO_PRI == mode) + { + if (DESS_MAX_PRI < val) + { + return SW_BAD_PARAM; + } + + data &= (~(0x7 << ((dscp & 0x7) << 2))); + data |= (val << ((dscp & 0x7) << 2)); + } + else + { + if (DESS_MAX_DP < val) + { + return SW_BAD_PARAM; + } + + data &= (~(0x1 << (((dscp & 0x7) << 2) + 3))); + data |= (val << (((dscp & 0x7) << 2) + 3)); + } + + HSL_REG_ENTRY_SET(rv, dev_id, DSCP_TO_PRI, index, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_cosmap_dscp_to_pri_dp_get(a_uint32_t dev_id, a_uint32_t mode, + a_uint32_t dscp, a_uint32_t * val) +{ + sw_error_t rv; + a_uint32_t index, data = 0; + + if (DESS_MAX_DSCP < dscp) + { + return SW_BAD_PARAM; + } + + index = dscp >> 3; + HSL_REG_ENTRY_GET(rv, dev_id, DSCP_TO_PRI, index, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data = (data >> ((dscp & 0x7) << 2)) & 0xf; + if (DESS_DSCP_TO_PRI == mode) + { + *val = data & 0x7; + } + else + { + *val = (data & 0x8) >> 3; + } + + return SW_OK; +} + +static sw_error_t +_dess_cosmap_up_to_pri_dp_set(a_uint32_t dev_id, a_uint32_t mode, a_uint32_t up, + a_uint32_t val) +{ + sw_error_t rv; + a_uint32_t data = 0; + + if (DESS_MAX_UP < up) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, UP_TO_PRI, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (DESS_UP_TO_PRI == mode) + { + if (DESS_MAX_PRI < val) + { + return SW_BAD_PARAM; + } + + data &= (~(0x7 << (up << 2))); + data |= (val << (up << 2)); + } + else + { + if (DESS_MAX_DP < val) + { + return SW_BAD_PARAM; + } + + data &= (~(0x1 << ((up << 2) + 3))); + data |= (val << ((up << 2) + 3)); + } + + HSL_REG_ENTRY_SET(rv, dev_id, UP_TO_PRI, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_cosmap_up_to_pri_dp_get(a_uint32_t dev_id, a_uint32_t mode, a_uint32_t up, + a_uint32_t * val) +{ + sw_error_t rv; + a_uint32_t data = 0; + + if (DESS_MAX_UP < up) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, UP_TO_PRI, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data = (data >> (up << 2)) & 0xf; + + if (DESS_UP_TO_PRI == mode) + { + *val = (data & 0x7); + } + else + { + *val = (data & 0x8) >> 3; + } + + return SW_OK; +} + +static sw_error_t +_dess_cosmap_dscp_to_ehpri_dp_set(a_uint32_t dev_id, a_uint32_t mode, + a_uint32_t dscp, a_uint32_t val) +{ + sw_error_t rv; + a_uint32_t index, data = 0; + + if (DESS_MAX_DSCP < dscp) + { + return SW_BAD_PARAM; + } + + index = dscp >> 3; + HSL_REG_ENTRY_GET(rv, dev_id, DSCP_TO_EHPRI, index, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (DESS_DSCP_TO_PRI == mode) + { + if (DESS_MAX_PRI < val) + { + return SW_BAD_PARAM; + } + + data &= (~(0x7 << ((dscp & 0x7) << 2))); + data |= (val << ((dscp & 0x7) << 2)); + } + else + { + if (DESS_MAX_DP < val) + { + return SW_BAD_PARAM; + } + + data &= (~(0x1 << (((dscp & 0x7) << 2) + 3))); + data |= (val << (((dscp & 0x7) << 2) + 3)); + } + + HSL_REG_ENTRY_SET(rv, dev_id, DSCP_TO_EHPRI, index, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_cosmap_dscp_to_ehpri_dp_get(a_uint32_t dev_id, a_uint32_t mode, + a_uint32_t dscp, a_uint32_t * val) +{ + sw_error_t rv; + a_uint32_t index, data = 0; + + if (DESS_MAX_DSCP < dscp) + { + return SW_BAD_PARAM; + } + + index = dscp >> 3; + HSL_REG_ENTRY_GET(rv, dev_id, DSCP_TO_EHPRI, index, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data = (data >> ((dscp & 0x7) << 2)) & 0xf; + if (DESS_DSCP_TO_PRI == mode) + { + *val = data & 0x7; + } + else + { + *val = (data & 0x8) >> 3; + } + + return SW_OK; +} + +static sw_error_t +_dess_cosmap_up_to_ehpri_dp_set(a_uint32_t dev_id, a_uint32_t mode, a_uint32_t up, + a_uint32_t val) +{ + sw_error_t rv; + a_uint32_t data = 0; + + if (DESS_MAX_UP < up) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, UP_TO_EHPRI, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (DESS_UP_TO_PRI == mode) + { + if (DESS_MAX_PRI < val) + { + return SW_BAD_PARAM; + } + + data &= (~(0x7 << (up << 2))); + data |= (val << (up << 2)); + } + else + { + if (DESS_MAX_DP < val) + { + return SW_BAD_PARAM; + } + + data &= (~(0x1 << ((up << 2) + 3))); + data |= (val << ((up << 2) + 3)); + } + + HSL_REG_ENTRY_SET(rv, dev_id, UP_TO_EHPRI, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_cosmap_up_to_ehpri_dp_get(a_uint32_t dev_id, a_uint32_t mode, a_uint32_t up, + a_uint32_t * val) +{ + sw_error_t rv; + a_uint32_t data = 0; + + if (DESS_MAX_UP < up) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, UP_TO_EHPRI, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data = (data >> (up << 2)) & 0xf; + + if (DESS_UP_TO_PRI == mode) + { + *val = (data & 0x7); + } + else + { + *val = (data & 0x8) >> 3; + } + + return SW_OK; +} + +static sw_error_t +_dess_cosmap_pri_to_queue_set(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t queue) +{ + sw_error_t rv; + a_uint32_t data = 0; + + if ((DESS_MAX_PRI < pri) || (DESS_MAX_QUEUE < queue)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PRI_TO_QUEUE, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data &= (~(0x3 << (pri << 2))); + data |= (queue << (pri << 2)); + + HSL_REG_ENTRY_SET(rv, dev_id, PRI_TO_QUEUE, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_cosmap_pri_to_queue_get(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t * queue) +{ + sw_error_t rv; + a_uint32_t data = 0; + + if (DESS_MAX_PRI < pri) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PRI_TO_QUEUE, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *queue = (data >> (pri << 2)) & 0x3; + return SW_OK; +} + +static sw_error_t +_dess_cosmap_pri_to_ehqueue_set(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t queue) +{ + sw_error_t rv; + a_uint32_t data = 0; + + if ((DESS_MAX_PRI < pri) || (DESS_MAX_EH_QUEUE < queue)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PRI_TO_EHQUEUE, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data &= (~(0x7 << (pri << 2))); + data |= (queue << (pri << 2)); + + HSL_REG_ENTRY_SET(rv, dev_id, PRI_TO_EHQUEUE, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_cosmap_pri_to_ehqueue_get(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t * queue) +{ + sw_error_t rv; + a_uint32_t data = 0; + + if (DESS_MAX_PRI < pri) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PRI_TO_EHQUEUE, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *queue = (data >> (pri << 2)) & 0x7; + return SW_OK; +} + +static sw_error_t +_dess_cosmap_egress_remark_set(a_uint32_t dev_id, a_uint32_t tbl_id, + fal_egress_remark_table_t * tbl) +{ + sw_error_t rv; + a_uint32_t data, addr; + + if (DESS_EGRESS_REAMRK_NUM <= tbl_id) + { + return SW_BAD_PARAM; + } + + data = (tbl->y_up & 0x7) + | ((tbl->y_dei & 0x1) << 3) + | ((tbl->g_up & 0x7) << 4) + | ((tbl->y_dscp & 0x3f) << 8) + | ((tbl->g_dei & 0x1) << 14) + | ((tbl->g_dscp & 0x3f) << 16) + | ((tbl->remark_dscp & 0x1) << 23) + | ((tbl->remark_up & 0x1) << 22) + | ((tbl->remark_dei & 0x1) << 7); + + addr = DESS_EGRESS_REAMRK_ADDR + (tbl_id << 4); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_cosmap_egress_remark_get(a_uint32_t dev_id, a_uint32_t tbl_id, + fal_egress_remark_table_t * tbl) +{ + sw_error_t rv; + a_uint32_t data = 0, addr; + + if (DESS_EGRESS_REAMRK_NUM <= tbl_id) + { + return SW_BAD_PARAM; + } + + aos_mem_zero(tbl, sizeof (fal_egress_remark_table_t)); + + addr = DESS_EGRESS_REAMRK_ADDR + (tbl_id << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data & (0x1 << 23)) + { + tbl->remark_dscp = A_TRUE; + tbl->y_dscp = (data >> 8) & 0x3f; + tbl->g_dscp = (data >> 16) & 0x3f; + } + + if (data & (0x1 << 22)) + { + tbl->remark_up = A_TRUE; + tbl->y_up = data & 0x7; + tbl->g_up = (data >> 4) & 0x7; + } + + if (data & (0x1 << 7)) + { + tbl->remark_dei = A_TRUE; + tbl->y_dei = (data >> 3) & 0x1; + tbl->g_dei = (data >> 14) & 0x1; + } + + return SW_OK; +} + +/** + * @brief Set dscp to internal priority mapping on one particular device. + * @param[in] dev_id device id + * @param[in] dscp dscp + * @param[in] pri internal priority + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_cosmap_dscp_to_pri_set(a_uint32_t dev_id, a_uint32_t dscp, a_uint32_t pri) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_cosmap_dscp_to_pri_dp_set(dev_id, DESS_DSCP_TO_PRI, dscp, pri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dscp to internal priority mapping on one particular device. + * @param[in] dev_id device id + * @param[in] dscp dscp + * @param[out] pri internal priority + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_cosmap_dscp_to_pri_get(a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t * pri) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_cosmap_dscp_to_pri_dp_get(dev_id, DESS_DSCP_TO_PRI, dscp, pri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dscp to internal drop precedence mapping on one particular device. + * @param[in] dev_id device id + * @param[in] dscp dscp + * @param[in] dp internal drop precedence + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_cosmap_dscp_to_dp_set(a_uint32_t dev_id, a_uint32_t dscp, a_uint32_t dp) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_cosmap_dscp_to_pri_dp_set(dev_id, DESS_DSCP_TO_DP, dscp, dp); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dscp to internal drop precedence mapping on one particular device. + * @param[in] dev_id device id + * @param[in] dscp dscp + * @param[out] dp internal drop precedence + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_cosmap_dscp_to_dp_get(a_uint32_t dev_id, a_uint32_t dscp, a_uint32_t * dp) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_cosmap_dscp_to_pri_dp_get(dev_id, DESS_DSCP_TO_DP, dscp, dp); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dot1p to internal priority mapping on one particular device. + * @param[in] dev_id device id + * @param[in] up dot1p + * @param[in] pri internal priority + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_cosmap_up_to_pri_set(a_uint32_t dev_id, a_uint32_t up, a_uint32_t pri) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_cosmap_up_to_pri_dp_set(dev_id, DESS_UP_TO_PRI, up, pri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dot1p to internal priority mapping on one particular device. + * @param[in] dev_id device id + * @param[in] up dot1p + * @param[out] pri internal priority + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_cosmap_up_to_pri_get(a_uint32_t dev_id, a_uint32_t up, a_uint32_t * pri) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_cosmap_up_to_pri_dp_get(dev_id, DESS_UP_TO_PRI, up, pri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dot1p to internal drop precedence mapping on one particular device. + * @param[in] dev_id device id + * @param[in] up dot1p + * @param[in] dp internal drop precedence + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_cosmap_up_to_dp_set(a_uint32_t dev_id, a_uint32_t up, a_uint32_t dp) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_cosmap_up_to_pri_dp_set(dev_id, DESS_UP_TO_DP, up, dp); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dot1p to internal drop precedence mapping on one particular device. + * @param[in] dev_id device id + * @param[in] up dot1p + * @param[in] dp internal drop precedence + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_cosmap_up_to_dp_get(a_uint32_t dev_id, a_uint32_t up, a_uint32_t * dp) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_cosmap_up_to_pri_dp_get(dev_id, DESS_UP_TO_DP, up, dp); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dscp to internal priority mapping on one particular device for WAN port. + * @param[in] dev_id device id + * @param[in] dscp dscp + * @param[in] pri internal priority + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_cosmap_dscp_to_ehpri_set(a_uint32_t dev_id, a_uint32_t dscp, a_uint32_t pri) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_cosmap_dscp_to_ehpri_dp_set(dev_id, DESS_DSCP_TO_PRI, dscp, pri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dscp to internal priority mapping on one particular device for WAN port. + * @param[in] dev_id device id + * @param[in] dscp dscp + * @param[out] pri internal priority + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_cosmap_dscp_to_ehpri_get(a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t * pri) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_cosmap_dscp_to_ehpri_dp_get(dev_id, DESS_DSCP_TO_PRI, dscp, pri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dscp to internal drop precedence mapping on one particular device for WAN port. + * @param[in] dev_id device id + * @param[in] dscp dscp + * @param[in] dp internal drop precedence + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_cosmap_dscp_to_ehdp_set(a_uint32_t dev_id, a_uint32_t dscp, a_uint32_t dp) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_cosmap_dscp_to_ehpri_dp_set(dev_id, DESS_DSCP_TO_DP, dscp, dp); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dscp to internal drop precedence mapping on one particular device for WAN port. + * @param[in] dev_id device id + * @param[in] dscp dscp + * @param[out] dp internal drop precedence + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_cosmap_dscp_to_ehdp_get(a_uint32_t dev_id, a_uint32_t dscp, a_uint32_t * dp) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_cosmap_dscp_to_ehpri_dp_get(dev_id, DESS_DSCP_TO_DP, dscp, dp); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dot1p to internal priority mapping on one particular device for WAN port. + * @param[in] dev_id device id + * @param[in] up dot1p + * @param[in] pri internal priority + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_cosmap_up_to_ehpri_set(a_uint32_t dev_id, a_uint32_t up, a_uint32_t pri) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_cosmap_up_to_ehpri_dp_set(dev_id, DESS_UP_TO_PRI, up, pri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dot1p to internal priority mapping on one particular device for WAN port. + * @param[in] dev_id device id + * @param[in] up dot1p + * @param[out] pri internal priority + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_cosmap_up_to_ehpri_get(a_uint32_t dev_id, a_uint32_t up, a_uint32_t * pri) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_cosmap_up_to_ehpri_dp_get(dev_id, DESS_UP_TO_PRI, up, pri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dot1p to internal drop precedence mapping on one particular device for WAN port. + * @param[in] dev_id device id + * @param[in] up dot1p + * @param[in] dp internal drop precedence + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_cosmap_up_to_ehdp_set(a_uint32_t dev_id, a_uint32_t up, a_uint32_t dp) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_cosmap_up_to_ehpri_dp_set(dev_id, DESS_UP_TO_DP, up, dp); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dot1p to internal drop precedence mapping on one particular device for WAN port. + * @param[in] dev_id device id + * @param[in] up dot1p + * @param[in] dp internal drop precedence + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_cosmap_up_to_ehdp_get(a_uint32_t dev_id, a_uint32_t up, a_uint32_t * dp) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_cosmap_up_to_ehpri_dp_get(dev_id, DESS_UP_TO_DP, up, dp); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set internal priority to queue mapping on one particular device. + * @details Comments: + * This function is for port 1/2/3/4 which have four egress queues + * @param[in] dev_id device id + * @param[in] pri internal priority + * @param[in] queue queue id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_cosmap_pri_to_queue_set(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t queue) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_cosmap_pri_to_queue_set(dev_id, pri, queue); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get internal priority to queue mapping on one particular device. + * @details Comments: + * This function is for port 1/2/3/4 which have four egress queues + * @param[in] dev_id device id + * @param[in] pri internal priority + * @param[out] queue queue id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_cosmap_pri_to_queue_get(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t * queue) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_cosmap_pri_to_queue_get(dev_id, pri, queue); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set internal priority to queue mapping on one particular device. + * @details Comments: + * This function is for port 0/5/6 which have six egress queues + * @param[in] dev_id device id + * @param[in] pri internal priority + * @param[in] queue queue id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_cosmap_pri_to_ehqueue_set(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t queue) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_cosmap_pri_to_ehqueue_set(dev_id, pri, queue); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get internal priority to queue mapping on one particular device. + * @details Comments: + * This function is for port 0/5/6 which have six egress queues + * @param[in] dev_id device id + * @param[in] pri internal priority + * @param[in] queue queue id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_cosmap_pri_to_ehqueue_get(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t * queue) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_cosmap_pri_to_ehqueue_get(dev_id, pri, queue); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set egress queue based CoS remap table on one particular device. + * @param[in] dev_id device id + * @param[in] tbl_id CoS remap table id + * @param[in] tbl CoS remap table + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_cosmap_egress_remark_set(a_uint32_t dev_id, a_uint32_t tbl_id, + fal_egress_remark_table_t * tbl) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_cosmap_egress_remark_set(dev_id, tbl_id, tbl); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get egress queue based CoS remap table on one particular device. + * @param[in] dev_id device id + * @param[in] tbl_id CoS remap table id + * @param[out] tbl CoS remap table + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_cosmap_egress_remark_get(a_uint32_t dev_id, a_uint32_t tbl_id, + fal_egress_remark_table_t * tbl) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_cosmap_egress_remark_get(dev_id, tbl_id, tbl); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +dess_cosmap_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->cosmap_dscp_to_pri_set = dess_cosmap_dscp_to_pri_set; + p_api->cosmap_dscp_to_pri_get = dess_cosmap_dscp_to_pri_get; + p_api->cosmap_dscp_to_dp_set = dess_cosmap_dscp_to_dp_set; + p_api->cosmap_dscp_to_dp_get = dess_cosmap_dscp_to_dp_get; + p_api->cosmap_up_to_pri_set = dess_cosmap_up_to_pri_set; + p_api->cosmap_up_to_pri_get = dess_cosmap_up_to_pri_get; + p_api->cosmap_up_to_dp_set = dess_cosmap_up_to_dp_set; + p_api->cosmap_up_to_dp_get = dess_cosmap_up_to_dp_get; + p_api->cosmap_dscp_to_ehpri_set = dess_cosmap_dscp_to_ehpri_set; + p_api->cosmap_dscp_to_ehpri_get = dess_cosmap_dscp_to_ehpri_get; + p_api->cosmap_dscp_to_ehdp_set = dess_cosmap_dscp_to_ehdp_set; + p_api->cosmap_dscp_to_ehdp_get = dess_cosmap_dscp_to_ehdp_get; + p_api->cosmap_up_to_ehpri_set = dess_cosmap_up_to_ehpri_set; + p_api->cosmap_up_to_ehpri_get = dess_cosmap_up_to_ehpri_get; + p_api->cosmap_up_to_ehdp_set = dess_cosmap_up_to_ehdp_set; + p_api->cosmap_up_to_ehdp_get = dess_cosmap_up_to_ehdp_get; + p_api->cosmap_pri_to_queue_set = dess_cosmap_pri_to_queue_set; + p_api->cosmap_pri_to_queue_get = dess_cosmap_pri_to_queue_get; + p_api->cosmap_pri_to_ehqueue_set = dess_cosmap_pri_to_ehqueue_set; + p_api->cosmap_pri_to_ehqueue_get = dess_cosmap_pri_to_ehqueue_get; + p_api->cosmap_egress_remark_set = dess_cosmap_egress_remark_set; + p_api->cosmap_egress_remark_get = dess_cosmap_egress_remark_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_fdb.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_fdb.c new file mode 100755 index 000000000..c92899e71 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_fdb.c @@ -0,0 +1,2431 @@ +/* + * Copyright (c) 2014-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. + */ + + +/** + * @defgroup dess_fdb DESS_FDB + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "dess_fdb.h" +#include "dess_reg.h" +#include "dess_fdb_prv.h" + +static aos_lock_t dess_fdb_lock; +static sw_error_t +_dess_wl_feature_check(a_uint32_t dev_id) +{ + sw_error_t rv; + a_uint32_t entry = 0; + + HSL_REG_FIELD_GET(rv, dev_id, MASK_CTL, 0, DEVICE_ID, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (DESS_DEVICE_ID == entry) + { + return SW_OK; + } + else + { + return SW_NOT_SUPPORTED; + } +} + +static a_bool_t +_dess_fdb_is_zeroaddr(fal_mac_addr_t addr) +{ + a_uint32_t i; + + for (i = 0; i < 6; i++) + { + if (addr.uc[i]) + { + return A_FALSE; + } + } + + return A_TRUE; +} + +static void +_dess_fdb_fill_addr(fal_mac_addr_t addr, a_uint32_t * reg0, a_uint32_t * reg1) +{ + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_ADDR_BYTE0, addr.uc[0], *reg1); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_ADDR_BYTE1, addr.uc[1], *reg1); + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_ADDR_BYTE2, addr.uc[2], *reg0); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_ADDR_BYTE3, addr.uc[3], *reg0); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_ADDR_BYTE4, addr.uc[4], *reg0); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_ADDR_BYTE5, addr.uc[5], *reg0); + + return; +} + +static sw_error_t +_dess_atu_sw_to_hw(a_uint32_t dev_id, const fal_fdb_entry_t * entry, + a_uint32_t reg[]) +{ + a_uint32_t port; + sw_error_t rv; + + if (A_TRUE == entry->white_list_en) + { + rv = _dess_wl_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, WL_EN, 1, reg[2]); + } + + if (FAL_SVL_FID == entry->fid) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_VID, 0, reg[2]); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_SVL_EN, 1, reg[1]); + } + else if (DESS_MAX_FID >= entry->fid) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_VID, (entry->fid), reg[2]); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_SVL_EN, 0, reg[1]); + } + else + { + return SW_BAD_PARAM; + } + + if (A_FALSE == entry->portmap_en) + { + if (A_TRUE != + hsl_port_prop_check(dev_id, entry->port.id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + port = 0x1UL << entry->port.id; + } + else + { + if (A_FALSE == + hsl_mports_prop_check(dev_id, entry->port.map, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + port = entry->port.map; + } + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, DES_PORT, port, reg[1]); + + if (FAL_MAC_CPY_TO_CPU == entry->dacmd) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, COPY_TO_CPU, 1, reg[2]); + } + else if (FAL_MAC_RDT_TO_CPU == entry->dacmd) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, REDRCT_TO_CPU, 1, reg[2]); + } + else if (FAL_MAC_FRWRD != entry->dacmd) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == entry->leaky_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, LEAKY_EN, 1, reg[2]); + } + else + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, LEAKY_EN, 0, reg[2]); + } + + if (A_TRUE == entry->static_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_STATUS, 15, reg[2]); + } + else + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_STATUS, 7, reg[2]); + } + + if (FAL_MAC_DROP == entry->sacmd) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, SA_DROP_EN, 1, reg[1]); + } + else if (FAL_MAC_FRWRD != entry->sacmd) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == entry->mirror_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, MIRROR_EN, 1, reg[1]); + } + + if (A_TRUE == entry->cross_pt_state) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, CROSS_PT, 1, reg[1]); + } + else + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, CROSS_PT, 0, reg[1]); + } + + if (A_TRUE == entry->da_pri_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_PRI_EN, 1, reg[1]); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_PRI, (entry->da_queue & 0x7), + reg[1]); + } + else + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_PRI_EN, 0, reg[1]); + } + + if (A_TRUE == entry->load_balance_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, LOAD_BALANCE_EN, 1, reg[2]); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, LOAD_BALANCE, + (entry->load_balance & 0x3), reg[2]); + } + else + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, LOAD_BALANCE_EN, 0, reg[2]); + } + + _dess_fdb_fill_addr(entry->addr, ®[0], ®[1]); + return SW_OK; +} + +static void +_dess_atu_hw_to_sw(const a_uint32_t reg[], fal_fdb_entry_t * entry) +{ + a_uint32_t i, data; + + aos_mem_zero(entry, sizeof (fal_fdb_entry_t)); + + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC1, AT_SVL_EN, data, reg[1]); + if (data) + { + entry->fid = FAL_SVL_FID; + } + else + { + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, AT_VID, data, reg[2]); + entry->fid = data; + } + + entry->dacmd = FAL_MAC_FRWRD; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, COPY_TO_CPU, data, reg[2]); + if (1 == data) + { + entry->dacmd = FAL_MAC_CPY_TO_CPU; + } + + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, REDRCT_TO_CPU, data, reg[2]); + if (1 == data) + { + entry->dacmd = FAL_MAC_RDT_TO_CPU; + } + + entry->sacmd = FAL_MAC_FRWRD; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC1, SA_DROP_EN, data, reg[1]); + if (1 == data) + { + entry->sacmd = FAL_MAC_DROP; + } + + entry->leaky_en = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, LEAKY_EN, data, reg[2]); + if (1 == data) + { + entry->leaky_en = A_TRUE; + } + + entry->static_en = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, AT_STATUS, data, reg[2]); + if (0xf == data) + { + entry->static_en = A_TRUE; + } + + entry->mirror_en = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC1, MIRROR_EN, data, reg[1]); + if (1 == data) + { + entry->mirror_en = A_TRUE; + } + + entry->da_pri_en = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC1, AT_PRI_EN, data, reg[1]); + if (1 == data) + { + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC1, AT_PRI, data, reg[1]); + entry->da_pri_en = A_TRUE; + entry->da_queue = data & 0x7; + } + + entry->cross_pt_state = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC1, CROSS_PT, data, reg[1]); + if (1 == data) + { + entry->cross_pt_state = A_TRUE; + } + + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC1, DES_PORT, data, reg[1]); + entry->portmap_en = A_TRUE; + entry->port.map = data; + + for (i = 2; i < 6; i++) + { + entry->addr.uc[i] = (reg[0] >> ((5 - i) << 3)) & 0xff; + } + + for (i = 0; i < 2; i++) + { + entry->addr.uc[i] = (reg[1] >> ((1 - i) << 3)) & 0xff; + } + + entry->white_list_en = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, WL_EN, data, reg[2]); + if (1 == data) + { + entry->white_list_en = A_TRUE; + } + + entry->load_balance_en = A_FALSE; + entry->load_balance = 0; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, LOAD_BALANCE_EN, data, reg[2]); + if (1 == data) + { + entry->load_balance_en = A_TRUE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, LOAD_BALANCE, data, reg[2]); + entry->load_balance = data; + } + + return; +} + +static sw_error_t +_dess_atu_down_to_hw(a_uint32_t dev_id, a_uint32_t reg[]) +{ + sw_error_t rv; + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC2, 0, + (a_uint8_t *) (®[2]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC3, 0, + (a_uint8_t *) (®[3]), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_atu_up_to_sw(a_uint32_t dev_id, a_uint32_t reg[]) +{ + sw_error_t rv; + + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC2, 0, + (a_uint8_t *) (®[2]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC3, 0, + (a_uint8_t *) (®[3]), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_fdb_commit(a_uint32_t dev_id, a_uint32_t op) +{ + sw_error_t rv; + a_uint32_t busy = 1; + a_uint32_t full_vio; + a_uint32_t i = 2000; + a_uint32_t entry = 0; + a_uint32_t hwop = op; + + while (busy && --i) + { + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC3, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC3, AT_BUSY, busy, entry); + } + + if (0 == i) + { + return SW_BUSY; + } + + if (ARL_FIRST_ENTRY == op) + { + hwop = ARL_NEXT_ENTRY; + } + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_BUSY, 1, entry); + + if (ARL_FLUSH_PORT_AND_STATIC == hwop) + { + hwop = ARL_FLUSH_PORT_UNICAST; + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, FLUSH_ST_EN, 1, entry); + } + + if (ARL_FLUSH_PORT_NO_STATIC == hwop) + { + hwop = ARL_FLUSH_PORT_UNICAST; + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, FLUSH_ST_EN, 0, entry); + } + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_FUNC, hwop, entry); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC3, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + busy = 1; + i = 2000; + while (busy && --i) + { + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC3, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC3, AT_BUSY, busy, entry); + } + + if (0 == i) + { + return SW_FAIL; + } + + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC3, AT_FULL_VIO, full_vio, entry); + + if (full_vio) + { + /* must clear AT_FULL_VOI bit */ + entry = 0x1000; + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC3, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (ARL_LOAD_ENTRY == hwop) + { + return SW_FULL; + } + else if ((ARL_PURGE_ENTRY == hwop) + || (ARL_FLUSH_PORT_UNICAST == hwop)) + { + return SW_NOT_FOUND; + } + else + { + return SW_FAIL; + } + } + + return SW_OK; +} + +static sw_error_t +_dess_fdb_get(a_uint32_t dev_id, fal_fdb_op_t * option, fal_fdb_entry_t * entry, + a_uint32_t hwop) +{ + sw_error_t rv; + a_uint32_t i, port = 0, status, reg[4] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == option->port_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_PORT_EN, 1, reg[3]); + if (A_FALSE == entry->portmap_en) + { + if (A_TRUE != + hsl_port_prop_check(dev_id, entry->port.id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + port = entry->port.id; + } + else + { + if (A_FALSE == + hsl_mports_prop_check(dev_id, entry->port.map, + HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + status = 0; + for (i = 0; i < SW_MAX_NR_PORT; i++) + { + if ((entry->port.map) & (0x1UL << i)) + { + if (status) + { + return SW_BAD_PARAM; + } + port = i; + status = 1; + } + } + } + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_PORT_NUM, port, reg[3]); + } + + if (A_TRUE == option->fid_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_VID_EN, 1, reg[3]); + } + + if (A_TRUE == option->multicast_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_MULTI_EN, 1, reg[3]); + } + + if (FAL_SVL_FID == entry->fid) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_VID, 0, reg[2]); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_SVL_EN, 1, reg[1]); + } + else if (DESS_MAX_FID >= entry->fid) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_VID, entry->fid, reg[2]); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_SVL_EN, 0, reg[1]); + } + else + { + return SW_BAD_PARAM; + } + + if (ARL_FIRST_ENTRY != hwop) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_STATUS, 0xf, reg[2]); + } + + _dess_fdb_fill_addr(entry->addr, ®[0], ®[1]); + + rv = _dess_atu_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _dess_fdb_commit(dev_id, hwop); + SW_RTN_ON_ERROR(rv); + + rv = _dess_atu_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + _dess_atu_hw_to_sw(reg, entry); + + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, AT_STATUS, status, reg[2]); + if ((A_TRUE == _dess_fdb_is_zeroaddr(entry->addr)) + && (0 == status)) + { + if (ARL_NEXT_ENTRY == hwop) + { + return SW_NO_MORE; + } + else + { + return SW_NOT_FOUND; + } + } + else + { + return SW_OK; + } + + return SW_OK; +} + +static sw_error_t +_dess_fdb_add(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t reg[4] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_atu_sw_to_hw(dev_id, entry, reg); + SW_RTN_ON_ERROR(rv); + + rv = _dess_atu_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _dess_fdb_commit(dev_id, ARL_LOAD_ENTRY); + return rv; +} + +static sw_error_t +_dess_fdb_del_all(a_uint32_t dev_id, a_uint32_t flag) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_FDB_DEL_STATIC & flag) + { + rv = _dess_fdb_commit(dev_id, ARL_FLUSH_ALL); + } + else + { + rv = _dess_fdb_commit(dev_id, ARL_FLUSH_ALL_UNLOCK); + } + + return rv; +} + +static sw_error_t +_dess_fdb_del_by_port(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t flag) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_PORT_NUM, port_id, reg); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC3, 0, (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_FDB_DEL_STATIC & flag) + { + rv = _dess_fdb_commit(dev_id, ARL_FLUSH_PORT_AND_STATIC); + } + else + { + rv = _dess_fdb_commit(dev_id, ARL_FLUSH_PORT_NO_STATIC); + } + + return rv; +} + +static sw_error_t +_dess_fdb_del_by_mac(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t reg0 = 0, reg1 = 0, reg2 = 0; + + HSL_DEV_ID_CHECK(dev_id); + + _dess_fdb_fill_addr(entry->addr, ®0, ®1); + + if (FAL_SVL_FID == entry->fid) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_VID, 0, reg2); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_SVL_EN, 1, reg1); + } + else if (DESS_MAX_FID >= entry->fid) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_VID, (entry->fid), reg2); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_SVL_EN, 0, reg1); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC2, 0, (a_uint8_t *) (®2), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC1, 0, (a_uint8_t *) (®1), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC0, 0, (a_uint8_t *) (®0), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = _dess_fdb_commit(dev_id, ARL_PURGE_ENTRY); + return rv; +} + +static sw_error_t +_dess_fdb_find(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + fal_fdb_op_t option; + + aos_mem_zero(&option, sizeof (fal_fdb_op_t)); + rv = _dess_fdb_get(dev_id, &option, entry, ARL_FIND_ENTRY); + return rv; +} + +static sw_error_t +_dess_fdb_extend_next(a_uint32_t dev_id, fal_fdb_op_t * option, + fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + rv = _dess_fdb_get(dev_id, option, entry, ARL_NEXT_ENTRY); + return rv; +} + +static sw_error_t +_dess_fdb_extend_first(a_uint32_t dev_id, fal_fdb_op_t * option, + fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + rv = _dess_fdb_get(dev_id, option, entry, ARL_FIRST_ENTRY); + return rv; +} + +static sw_error_t +_dess_fdb_transfer(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; + a_uint32_t reg[4] = { 0 }; + + if (A_TRUE == option->port_en) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == option->fid_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_VID_EN, 1, reg[3]); + } + + if (A_TRUE == option->multicast_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_MULTI_EN, 1, reg[3]); + } + + if (FAL_SVL_FID == fid) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_VID, 0, reg[2]); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_SVL_EN, 1, reg[1]); + } + else if (DESS_MAX_FID >= fid) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_VID, fid, reg[2]); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_SVL_EN, 0, reg[1]); + } + else + { + return SW_BAD_PARAM; + } + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_PORT_NUM, old_port, reg[3]); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, NEW_PORT_NUM, new_port, reg[3]); + + rv = _dess_atu_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _dess_fdb_commit(dev_id, ARL_TRANSFER_ENTRY); + return rv; +} + +static sw_error_t +_dess_fdb_port_learn_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LOOKUP_CTL, port_id, LEARN_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_fdb_port_learn_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LOOKUP_CTL, port_id, LEARN_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_fdb_age_ctrl_set(a_uint32_t dev_id, a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, ADDR_TABLE_CTL, 0, AGE_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_fdb_vlan_ivl_svl_set(a_uint32_t dev_id, fal_fdb_smode smode) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + data = smode; + + HSL_REG_FIELD_SET(rv, dev_id, ADDR_TABLE_CTL, 0, ARL_INI_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_fdb_vlan_ivl_svl_get(a_uint32_t dev_id, fal_fdb_smode* smode) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_CTL, 0, ARL_INI_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + + *smode = data; + + return rv; +} + + + +static sw_error_t +_dess_fdb_age_ctrl_get(a_uint32_t dev_id, a_bool_t * enable) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_CTL, 0, AGE_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_fdb_age_time_set(a_uint32_t dev_id, a_uint32_t * time) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if ((65535 * 7 < *time) || (7 > *time)) + { + return SW_BAD_PARAM; + } + data = *time / 7; + *time = data * 7; + HSL_REG_FIELD_SET(rv, dev_id, ADDR_TABLE_CTL, 0, AGE_TIME, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_fdb_age_time_get(a_uint32_t dev_id, a_uint32_t * time) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_CTL, 0, AGE_TIME, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *time = data * 7; + return SW_OK; +} + +static sw_error_t +_dess_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; + a_uint32_t reg = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + if (DESS_MAX_PORT_LEARN_LIMIT_CNT < cnt) + { + return SW_BAD_PARAM; + } + SW_SET_REG_BY_FIELD(PORT_LEARN_LIMIT_CTL, SA_LEARN_LIMIT_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_LEARN_LIMIT_CTL, SA_LEARN_CNT, cnt, reg); + } + else if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(PORT_LEARN_LIMIT_CTL, SA_LEARN_LIMIT_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_LEARN_LIMIT_CTL, SA_LEARN_CNT, 0, reg); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_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; + a_uint32_t data, reg = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_LEARN_LIMIT_CTL, SA_LEARN_LIMIT_EN, data, reg); + if (data) + { + SW_GET_FIELD_BY_REG(PORT_LEARN_LIMIT_CTL, SA_LEARN_CNT, data, reg); + *enable = A_TRUE; + *cnt = data; + } + else + { + *enable = A_FALSE; + *cnt = 0; + } + + return SW_OK; +} + +static sw_error_t +_dess_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; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_MAC_DROP == cmd) + { + data = 1; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + data = 0; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + SA_LEARN_LIMIT_DROP_EN, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_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; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + SA_LEARN_LIMIT_DROP_EN, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data) + { + *cmd = FAL_MAC_DROP; + } + else + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + + return SW_OK; +} + +static sw_error_t +_dess_fdb_learn_limit_set(a_uint32_t dev_id, a_bool_t enable, a_uint32_t cnt) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + HSL_REG_ENTRY_GET(rv, dev_id, GLOBAL_LEARN_LIMIT_CTL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + if (DESS_MAX_LEARN_LIMIT_CNT < cnt) + { + return SW_BAD_PARAM; + } + SW_SET_REG_BY_FIELD(GLOBAL_LEARN_LIMIT_CTL, GOL_SA_LEARN_LIMIT_EN, 1, + reg); + SW_SET_REG_BY_FIELD(GLOBAL_LEARN_LIMIT_CTL, GOL_SA_LEARN_CNT, cnt, reg); + } + else if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(GLOBAL_LEARN_LIMIT_CTL, GOL_SA_LEARN_LIMIT_EN, 0, + reg); + SW_SET_REG_BY_FIELD(GLOBAL_LEARN_LIMIT_CTL, GOL_SA_LEARN_CNT, 0, reg); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_SET(rv, dev_id, GLOBAL_LEARN_LIMIT_CTL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_fdb_learn_limit_get(a_uint32_t dev_id, a_bool_t * enable, + a_uint32_t * cnt) +{ + sw_error_t rv; + a_uint32_t data, reg = 0; + + HSL_REG_ENTRY_GET(rv, dev_id, GLOBAL_LEARN_LIMIT_CTL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(GLOBAL_LEARN_LIMIT_CTL, GOL_SA_LEARN_LIMIT_EN, data, + reg); + if (data) + { + SW_GET_FIELD_BY_REG(GLOBAL_LEARN_LIMIT_CTL, GOL_SA_LEARN_CNT, data, + reg); + *enable = A_TRUE; + *cnt = data; + } + else + { + *enable = A_FALSE; + *cnt = 0; + } + + return SW_OK; +} + +static sw_error_t +_dess_fdb_learn_exceed_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_MAC_DROP == cmd) + { + data = 1; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + data = 0; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, GLOBAL_LEARN_LIMIT_CTL, 0, + GOL_SA_LEARN_LIMIT_DROP_EN, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_fdb_learn_exceed_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, GLOBAL_LEARN_LIMIT_CTL, 0, + GOL_SA_LEARN_LIMIT_DROP_EN, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data) + { + *cmd = FAL_MAC_DROP; + } + else + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + + return SW_OK; +} + +#define DESS_RESV_ADDR_NUM 32 +#define RESV_ADDR_TBL0_ADDR 0x3c000 +#define RESV_ADDR_TBL1_ADDR 0x3c004 +#define RESV_ADDR_TBL2_ADDR 0x3c008 + +static void +_dess_resv_addr_parse(const a_uint32_t reg[], fal_mac_addr_t * addr) +{ + a_uint32_t i; + + for (i = 2; i < 6; i++) + { + addr->uc[i] = (reg[0] >> ((5 - i) << 3)) & 0xff; + } + + for (i = 0; i < 2; i++) + { + addr->uc[i] = (reg[1] >> ((1 - i) << 3)) & 0xff; + } +} + +static sw_error_t +_dess_resv_atu_sw_to_hw(a_uint32_t dev_id, fal_fdb_entry_t * entry, + a_uint32_t reg[]) +{ + a_uint32_t port; + + if (A_FALSE == entry->portmap_en) + { + if (A_TRUE != + hsl_port_prop_check(dev_id, entry->port.id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + port = 0x1UL << entry->port.id; + } + else + { + if (A_FALSE == + hsl_mports_prop_check(dev_id, entry->port.map, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + port = entry->port.map; + } + SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_DES_PORT, port, reg[1]); + + if (FAL_MAC_CPY_TO_CPU == entry->dacmd) + { + SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_COPY_TO_CPU, 1, reg[1]); + } + else if (FAL_MAC_RDT_TO_CPU == entry->dacmd) + { + SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_REDRCT_TO_CPU, 1, reg[1]); + } + else if (FAL_MAC_FRWRD != entry->dacmd) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_MAC_FRWRD != entry->sacmd) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == entry->leaky_en) + { + SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_LEAKY_EN, 1, reg[1]); + } + else + { + SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_LEAKY_EN, 0, reg[1]); + } + + if (A_TRUE != entry->static_en) + { + return SW_NOT_SUPPORTED; + } + SW_SET_REG_BY_FIELD(RESV_ADDR_TBL2, RESV_STATUS, 1, reg[2]); + + if (A_TRUE == entry->mirror_en) + { + SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_MIRROR_EN, 1, reg[1]); + } + + if (A_TRUE == entry->cross_pt_state) + { + SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_CROSS_PT, 1, reg[1]); + } + + if (A_TRUE == entry->da_pri_en) + { + SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_PRI_EN, 1, reg[1]); + SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_PRI, (entry->da_queue & 0x7), + reg[1]); + } + + _dess_fdb_fill_addr(entry->addr, ®[0], ®[1]); + return SW_OK; +} + +static void +_dess_resv_atu_hw_to_sw(const a_uint32_t reg[], fal_fdb_entry_t * entry) +{ + a_uint32_t data; + + aos_mem_zero(entry, sizeof (fal_fdb_entry_t)); + + entry->fid = FAL_SVL_FID; + + entry->dacmd = FAL_MAC_FRWRD; + SW_GET_FIELD_BY_REG(RESV_ADDR_TBL1, RESV_COPY_TO_CPU, data, reg[1]); + if (1 == data) + { + entry->dacmd = FAL_MAC_CPY_TO_CPU; + } + + SW_GET_FIELD_BY_REG(RESV_ADDR_TBL1, RESV_REDRCT_TO_CPU, data, reg[1]); + if (1 == data) + { + entry->dacmd = FAL_MAC_RDT_TO_CPU; + } + + entry->sacmd = FAL_MAC_FRWRD; + + entry->leaky_en = A_FALSE; + SW_GET_FIELD_BY_REG(RESV_ADDR_TBL1, RESV_LEAKY_EN, data, reg[1]); + if (1 == data) + { + entry->leaky_en = A_TRUE; + } + + entry->static_en = A_TRUE; + + entry->mirror_en = A_FALSE; + SW_GET_FIELD_BY_REG(RESV_ADDR_TBL1, RESV_MIRROR_EN, data, reg[1]); + if (1 == data) + { + entry->mirror_en = A_TRUE; + } + + entry->da_pri_en = A_FALSE; + SW_GET_FIELD_BY_REG(RESV_ADDR_TBL1, RESV_PRI_EN, data, reg[1]); + if (1 == data) + { + SW_GET_FIELD_BY_REG(RESV_ADDR_TBL1, RESV_PRI, data, reg[1]); + entry->da_pri_en = A_TRUE; + entry->da_queue = data & 0x7; + } + + entry->cross_pt_state = A_FALSE; + SW_GET_FIELD_BY_REG(RESV_ADDR_TBL1, RESV_CROSS_PT, data, reg[1]); + if (1 == data) + { + entry->cross_pt_state = A_TRUE; + } + + SW_GET_FIELD_BY_REG(RESV_ADDR_TBL1, RESV_DES_PORT, data, reg[1]); + entry->portmap_en = A_TRUE; + entry->port.map = data; + + _dess_resv_addr_parse(reg, &(entry->addr)); + return; +} + +static sw_error_t +_dess_fdb_resv_commit(a_uint32_t dev_id, fal_fdb_entry_t * entry, a_uint32_t op, + a_uint32_t * empty) +{ + a_uint32_t index, addr, data, tbl[3] = { 0 }; + sw_error_t rv; + fal_mac_addr_t mac_tmp; + + *empty = DESS_RESV_ADDR_NUM; + for (index = 0; index < DESS_RESV_ADDR_NUM; index++) + { + addr = RESV_ADDR_TBL2_ADDR + (index << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[2])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(RESV_ADDR_TBL2, RESV_STATUS, data, tbl[2]); + if (data) + { + addr = RESV_ADDR_TBL0_ADDR + (index << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[0])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + addr = RESV_ADDR_TBL1_ADDR + (index << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[1])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + _dess_resv_addr_parse(tbl, &mac_tmp); + if (!aos_mem_cmp + ((void *) &(entry->addr), (void *) &mac_tmp, + sizeof (fal_mac_addr_t))) + { + if (ARL_PURGE_ENTRY == op) + { + addr = RESV_ADDR_TBL2_ADDR + (index << 4); + tbl[2] = 0; + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[2])), + sizeof (a_uint32_t)); + return rv; + } + else if (ARL_LOAD_ENTRY == op) + { + return SW_ALREADY_EXIST; + } + else if (ARL_FIND_ENTRY == op) + { + _dess_resv_atu_hw_to_sw(tbl, entry); + return SW_OK; + } + } + } + else + { + *empty = index; + } + } + + return SW_NOT_FOUND; +} + +static sw_error_t +_dess_fdb_resv_add(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t i, empty, addr, tbl[3] = { 0 }; + + rv = _dess_resv_atu_sw_to_hw(dev_id, entry, tbl); + SW_RTN_ON_ERROR(rv); + + rv = _dess_fdb_resv_commit(dev_id, entry, ARL_LOAD_ENTRY, &empty); + if (SW_ALREADY_EXIST == rv) + { + return rv; + } + + if (DESS_RESV_ADDR_NUM == empty) + { + return SW_NO_RESOURCE; + } + + for (i = 0; i < 3; i++) + { + addr = RESV_ADDR_TBL0_ADDR + (empty << 4) + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[i])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +static sw_error_t +_dess_fdb_resv_del(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t empty; + + rv = _dess_fdb_resv_commit(dev_id, entry, ARL_PURGE_ENTRY, &empty); + return rv; +} + +static sw_error_t +_dess_fdb_resv_find(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t empty; + + rv = _dess_fdb_resv_commit(dev_id, entry, ARL_FIND_ENTRY, &empty); + return rv; +} + +static sw_error_t +_dess_fdb_resv_iterate(a_uint32_t dev_id, a_uint32_t * iterator, + fal_fdb_entry_t * entry) +{ + a_uint32_t index, addr, data, tbl[3] = { 0 }; + sw_error_t rv; + + if ((NULL == iterator) || (NULL == entry)) + { + return SW_BAD_PTR; + } + + if (DESS_RESV_ADDR_NUM < *iterator) + { + return SW_BAD_PARAM; + } + + for (index = *iterator; index < DESS_RESV_ADDR_NUM; index++) + { + addr = RESV_ADDR_TBL2_ADDR + (index << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[2])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(RESV_ADDR_TBL2, RESV_STATUS, data, tbl[2]); + if (data) + { + addr = RESV_ADDR_TBL0_ADDR + (index << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[0])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + addr = RESV_ADDR_TBL1_ADDR + (index << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[1])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + _dess_resv_atu_hw_to_sw(tbl, entry); + break; + } + } + + if (DESS_RESV_ADDR_NUM == index) + { + return SW_NO_MORE; + } + + *iterator = index + 1; + return SW_OK; +} + +static sw_error_t +_dess_fdb_port_learn_static_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 0xf; + } + else if (A_FALSE == enable) + { + data = 0x7; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + SA_LEARN_STATUS, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_fdb_port_learn_static_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + SA_LEARN_STATUS, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0xf == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_fdb_port_update(a_uint32_t dev_id, a_uint32_t fid, fal_mac_addr_t * addr, fal_port_t port_id, a_uint32_t op) +{ + sw_error_t rv; + fal_fdb_entry_t entry; + fal_fdb_op_t option; + a_uint32_t reg, port; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_SVL_FID < fid) + { + return SW_BAD_PARAM; + } + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + aos_mem_zero(&option, sizeof(fal_fdb_op_t)); + aos_mem_copy(&(entry.addr), addr, sizeof(fal_mac_addr_t)); + entry.fid = fid & 0xffff; + rv = _dess_fdb_get(dev_id, &option, &entry, ARL_FIND_ENTRY); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC1, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC1, DES_PORT, port, reg); + if (op) + { + port |= (0x1 << port_id); + } + else + { + port &= (~(0x1 << port_id)); + } + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, DES_PORT, port, reg); + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC1, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + rv = _dess_fdb_commit(dev_id, ARL_LOAD_ENTRY); + return rv; +} +#define FDB_RFS_ADD 1 +#define FDB_RFS_DEL 2 +static sw_error_t +_dess_fdb_rfs_update(const fal_fdb_rfs_t *rfs, fal_fdb_entry_t *entry, char op) +{ + _dess_fdb_del_by_mac(0, entry); + if(FDB_RFS_ADD == op) { + entry->static_en = 1; + entry->load_balance_en = 1; + entry->load_balance = rfs->load_balance; + entry->port.map = 1; + entry->portmap_en = 1; + } else { + entry->static_en = 0; + entry->load_balance_en = 0; + } + return _dess_fdb_add(0, entry); +} + + +static sw_error_t +_dess_fdb_rfs_set(a_uint32_t dev_id, const fal_fdb_rfs_t *rfs) +{ + + fal_fdb_entry_t entry; + sw_error_t ret; + + memset(&entry, 0, sizeof(entry)); + + entry.addr = rfs->addr; + entry.fid = rfs->fid; + ret = _dess_fdb_find(0, &entry); + if(!ret) { + return _dess_fdb_rfs_update(rfs, &entry, FDB_RFS_ADD); + } else { + entry.addr = rfs->addr; + entry.fid = rfs->fid; + entry.load_balance_en = 1; + entry.load_balance = rfs->load_balance; + entry.static_en = 1; + entry.port.map = 1; + entry.portmap_en = 1; + return _dess_fdb_add(0, &entry); + } +} + +static sw_error_t +_dess_fdb_rfs_del(a_uint32_t dev_id, const fal_fdb_rfs_t *rfs) +{ + + fal_fdb_entry_t entry; + sw_error_t ret; + + memset(&entry, 0, sizeof(entry)); + entry.addr = rfs->addr; + entry.fid = rfs->fid; + ret = _dess_fdb_find(0, &entry); + if(!ret) { + return _dess_fdb_rfs_update(rfs, &entry, FDB_RFS_DEL); + } else { + return ret; + } +} + + + +sw_error_t +inter_dess_fdb_flush(a_uint32_t dev_id, a_uint32_t flag) +{ + if (FAL_FDB_DEL_STATIC & flag) + { + return _dess_fdb_commit(dev_id, ARL_FLUSH_ALL); + } + else + { + return _dess_fdb_commit(dev_id, ARL_FLUSH_ALL_UNLOCK); + } +} + +/** + * @brief Add a Fdb entry + * @param[in] dev_id device id + * @param[in] entry fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_fdb_add(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + aos_lock_bh(&dess_fdb_lock); + rv = _dess_fdb_add(dev_id, entry); + aos_unlock_bh(&dess_fdb_lock); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete all Fdb entries + * @details Comments: + * If set FAL_FDB_DEL_STATIC bit in flag which means delete all fdb + * entries otherwise only delete dynamic entries. + * @param[in] dev_id device id + * @param[in] flag delete operation option + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_fdb_del_all(a_uint32_t dev_id, a_uint32_t flag) +{ + sw_error_t rv; + + HSL_API_LOCK; + aos_lock_bh(&dess_fdb_lock); + rv = _dess_fdb_del_all(dev_id, flag); + aos_unlock_bh(&dess_fdb_lock); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete Fdb entries on a particular port + * @details Comments: + * If set FAL_FDB_DEL_STATIC bit in flag which means delete all fdb + * entries otherwise only delete dynamic entries. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] flag delete operation option + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_fdb_del_by_port(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t flag) +{ + sw_error_t rv; + + HSL_API_LOCK; + aos_lock_bh(&dess_fdb_lock); + rv = _dess_fdb_del_by_port(dev_id, port_id, flag); + aos_unlock_bh(&dess_fdb_lock); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a particular Fdb entry through mac address + * @details Comments: + * Only addr field in entry is meaning. For IVL learning vid or fid field + * also is meaning. + * @param[in] dev_id device id + * @param[in] entry fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_fdb_del_by_mac(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + aos_lock_bh(&dess_fdb_lock); + rv = _dess_fdb_del_by_mac(dev_id, entry); + aos_unlock_bh(&dess_fdb_lock); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Find a particular Fdb entry from device through mac address. + * @details Comments: + For input parameter only addr field in entry is meaning. + * @param[in] dev_id device id + * @param[in] entry fdb entry + * @param[out] entry fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_fdb_find(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + aos_lock_bh(&dess_fdb_lock); + rv = _dess_fdb_find(dev_id, entry); + aos_unlock_bh(&dess_fdb_lock); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get next Fdb entry from a particular device + * @param[in] dev_id device id + * @param[in] option next operation options + * @param[out] entry fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_fdb_extend_next(a_uint32_t dev_id, fal_fdb_op_t * option, + fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + aos_lock_bh(&dess_fdb_lock); + rv = _dess_fdb_extend_next(dev_id, option, entry); + aos_unlock_bh(&dess_fdb_lock); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get first Fdb entry from a particular device + * @param[in] dev_id device id + * @param[in] option first operation options + * @param[out] entry fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_fdb_extend_first(a_uint32_t dev_id, fal_fdb_op_t * option, + fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + aos_lock_bh(&dess_fdb_lock); + rv = _dess_fdb_extend_first(dev_id, option, entry); + aos_unlock_bh(&dess_fdb_lock); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Transfer fdb entries port information on a particular device. + * @param[in] dev_id device id + * @param[in] old_port source port id + * @param[in] new_port destination port id + * @param[in] fid filter database id + * @param[in] option transfer operation options + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_fdb_transfer(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; + + HSL_API_LOCK; + aos_lock_bh(&dess_fdb_lock); + rv = _dess_fdb_transfer(dev_id, old_port, new_port, fid, option); + aos_unlock_bh(&dess_fdb_lock); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dynamic address learning status on a particular port. + * @details Comments: + * This operation will enable or disable dynamic address learning + * feature on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable enable or disable + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_fdb_port_learn_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_fdb_port_learn_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dynamic address learning status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_fdb_port_learn_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_fdb_port_learn_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dynamic address aging status on particular device. + * @details Comments: + * This operation will enable or disable dynamic address aging + * feature on particular device. + * @param[in] dev_id device id + * @param[in] enable enable or disable + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_fdb_age_ctrl_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_fdb_age_ctrl_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dynamic address aging status on particular device. + * @param[in] dev_id device id + * @param[in] enable enable or disable + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_fdb_age_ctrl_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_fdb_age_ctrl_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief set arl search mode as ivl or svl when vlan invalid. + * @param[in] dev_id device id + * @param[in] smode INVALID_VLAN_IVL or INVALID_VLAN_SVL + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_fdb_vlan_ivl_svl_set(a_uint32_t dev_id, fal_fdb_smode smode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_fdb_vlan_ivl_svl_set(dev_id, smode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief get arl search mode when vlan invalid. + * @param[in] dev_id device id + * @param[out] smode INVALID_VLAN_IVL or INVALID_VLAN_SVL + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_fdb_vlan_ivl_svl_get(a_uint32_t dev_id, fal_fdb_smode* smode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_fdb_vlan_ivl_svl_get(dev_id, smode); + HSL_API_UNLOCK; + return rv; +} + + + +/** + * @brief Set dynamic address aging time on a particular device. + * @details Comments: + * This operation will set dynamic address aging time on a particular device. + * The unit of time is second. Because different device has differnet + * hardware granularity function will return actual time in hardware. + * @param[in] dev_id device id + * @param time aging time + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_fdb_age_time_set(a_uint32_t dev_id, a_uint32_t * time) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_fdb_age_time_set(dev_id, time); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dynamic address aging time on a particular device. + * @param[in] dev_id device id + * @param[out] time aging time + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_fdb_age_time_get(a_uint32_t dev_id, a_uint32_t * time) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_fdb_age_time_get(dev_id, time); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dynamic address learning count limit on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] cnt limit count + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_port_fdb_learn_limit_set(dev_id, port_id, enable, cnt); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dynamic address learning count limit on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @param[out] cnt limit count + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_port_fdb_learn_limit_get(dev_id, port_id, enable, cnt); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dynamic address learning count exceed command on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_port_fdb_learn_exceed_cmd_set(dev_id, port_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dynamic address learning count exceed command on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_port_fdb_learn_exceed_cmd_get(dev_id, port_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dynamic address learning count limit on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] cnt limit count + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_fdb_learn_limit_set(a_uint32_t dev_id, a_bool_t enable, a_uint32_t cnt) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_fdb_learn_limit_set(dev_id, enable, cnt); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dynamic address learning count limit on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] cnt limit count + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_fdb_learn_limit_get(a_uint32_t dev_id, a_bool_t * enable, a_uint32_t * cnt) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_fdb_learn_limit_get(dev_id, enable, cnt); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dynamic address learning count exceed command on a particular device. + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_fdb_learn_exceed_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_fdb_learn_exceed_cmd_set(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dynamic address learning count exceed command on a particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_fdb_learn_exceed_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_fdb_learn_exceed_cmd_get(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add a particular reserve Fdb entry + * @param[in] dev_id device id + * @param[in] entry reserve fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_fdb_resv_add(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_fdb_resv_add(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a particular reserve Fdb entry through mac address + * @param[in] dev_id device id + * @param[in] entry reserve fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_fdb_resv_del(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_fdb_resv_del(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Find a particular reserve Fdb entry through mac address + * @param[in] dev_id device id + * @param[in] entry reserve fdb entry + * @param[out] entry reserve fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_fdb_resv_find(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_fdb_resv_find(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Iterate all reserve fdb entries on a particular device. + * @param[in] dev_id device id + * @param[in] iterator reserve fdb entry index if it's zero means get the first entry + * @param[out] iterator next valid fdb entry index + * @param[out] entry reserve fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_fdb_resv_iterate(a_uint32_t dev_id, a_uint32_t * iterator, + fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_fdb_resv_iterate(dev_id, iterator, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set the static status of fdb entries which learned by hardware on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_fdb_port_learn_static_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_fdb_port_learn_static_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get the static status of fdb entries which learned by hardware on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_fdb_port_learn_static_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_fdb_port_learn_static_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add a port to an exsiting entry + * @param[in] dev_id device id + * @param[in] fid filtering database id + * @param[in] addr MAC address + * @param[in] port_id port id + * @return SW_OK or error code, If entry not exist will return error. + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + aos_lock_bh(&dess_fdb_lock); + rv = _dess_fdb_port_update(dev_id, fid, addr, port_id, 1); + aos_unlock_bh(&dess_fdb_lock); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a port from an exsiting entry + * @param[in] dev_id device id + * @param[in] fid filtering database id + * @param[in] addr MAC address + * @param[in] port_id port id + * @return SW_OK or error code, If entry not exist will return error. + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + aos_lock_bh(&dess_fdb_lock); + rv = _dess_fdb_port_update(dev_id, fid, addr, port_id, 0); + aos_unlock_bh(&dess_fdb_lock); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief set a fdb rfs entry + * @param[in] dev_id device id + * @param[in] rfs entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_fdb_rfs_set(a_uint32_t dev_id, const fal_fdb_rfs_t *rfs) +{ + sw_error_t rv; + + HSL_API_LOCK; + aos_lock_bh(&dess_fdb_lock); + rv = _dess_fdb_rfs_set(dev_id, rfs); + aos_unlock_bh(&dess_fdb_lock); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief del a fdb rfs entry + * @param[in] dev_id device id + * @param[in] rfs entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_fdb_rfs_del(a_uint32_t dev_id, const fal_fdb_rfs_t *rfs) +{ + sw_error_t rv; + + HSL_API_LOCK; + aos_lock_bh(&dess_fdb_lock); + rv = _dess_fdb_rfs_del(dev_id, rfs); + aos_unlock_bh(&dess_fdb_lock); + HSL_API_UNLOCK; + return rv; +} + + +sw_error_t +dess_fdb_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->fdb_add = dess_fdb_add; + p_api->fdb_del_all = dess_fdb_del_all; + p_api->fdb_del_by_port = dess_fdb_del_by_port; + p_api->fdb_del_by_mac = dess_fdb_del_by_mac; + p_api->fdb_find = dess_fdb_find; + p_api->port_learn_set = dess_fdb_port_learn_set; + p_api->port_learn_get = dess_fdb_port_learn_get; + p_api->age_ctrl_set = dess_fdb_age_ctrl_set; + p_api->age_ctrl_get = dess_fdb_age_ctrl_get; + p_api->vlan_ivl_svl_set = dess_fdb_vlan_ivl_svl_set; + p_api->vlan_ivl_svl_get = dess_fdb_vlan_ivl_svl_get; + p_api->age_time_set = dess_fdb_age_time_set; + p_api->age_time_get = dess_fdb_age_time_get; + p_api->fdb_extend_next = dess_fdb_extend_next; + p_api->fdb_extend_first = dess_fdb_extend_first; + p_api->fdb_transfer = dess_fdb_transfer; + p_api->port_fdb_learn_limit_set = dess_port_fdb_learn_limit_set; + p_api->port_fdb_learn_limit_get = dess_port_fdb_learn_limit_get; + p_api->port_fdb_learn_exceed_cmd_set = dess_port_fdb_learn_exceed_cmd_set; + p_api->port_fdb_learn_exceed_cmd_get = dess_port_fdb_learn_exceed_cmd_get; + p_api->fdb_learn_limit_set = dess_fdb_learn_limit_set; + p_api->fdb_learn_limit_get = dess_fdb_learn_limit_get; + p_api->fdb_learn_exceed_cmd_set = dess_fdb_learn_exceed_cmd_set; + p_api->fdb_learn_exceed_cmd_get = dess_fdb_learn_exceed_cmd_get; + p_api->fdb_resv_add = dess_fdb_resv_add; + p_api->fdb_resv_del = dess_fdb_resv_del; + p_api->fdb_resv_find = dess_fdb_resv_find; + p_api->fdb_resv_iterate = dess_fdb_resv_iterate; + p_api->fdb_port_learn_static_set = dess_fdb_port_learn_static_set; + p_api->fdb_port_learn_static_get = dess_fdb_port_learn_static_get; + p_api->fdb_port_add = dess_fdb_port_add; + p_api->fdb_port_del = dess_fdb_port_del; + p_api->fdb_rfs_set = dess_fdb_rfs_set; + p_api->fdb_rfs_del = dess_fdb_rfs_del; + } +#endif + + aos_lock_init(&dess_fdb_lock); + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_igmp.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_igmp.c new file mode 100755 index 000000000..5ca8a6fed --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_igmp.c @@ -0,0 +1,1147 @@ +/* + * Copyright (c) 2014, 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. + */ + + +/** + * @defgroup dess_igmp DESS_IGMP + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "dess_igmp.h" +#include "dess_reg.h" + +#define LEAVE_EN_OFFSET 2 +#define JOIN_EN_OFFSET 1 +#define IGMP_MLD_EN_OFFSET 0 + +#define DESS_MAX_PORT_LEARN_LIMIT_CNT 1024 + +extern sw_error_t +dess_igmp_sg_entry_set(a_uint32_t dev_id, fal_igmp_sg_entry_t * entry); + +extern sw_error_t +dess_igmp_sg_entry_clear(a_uint32_t dev_id, fal_igmp_sg_entry_t * entry); + +extern sw_error_t +dess_igmp_sg_entry_show(a_uint32_t dev_id); + +extern sw_error_t +dess_igmp_sg_entry_query(a_uint32_t dev_id, fal_igmp_sg_info_t * info); + +static sw_error_t +_dess_port_igmp_property_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable, a_uint32_t item) +{ + sw_error_t rv; + a_uint32_t reg = 0, val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + if (3 >= port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, FRAME_ACK_CTL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + reg &= ~(0x1UL << ((port_id << 3) + item)); + reg |= (val << ((port_id << 3) + item)); + + HSL_REG_ENTRY_SET(rv, dev_id, FRAME_ACK_CTL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + HSL_REG_ENTRY_GET(rv, dev_id, FRAME_ACK_CTL1, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + reg &= ~(0x1UL << (((port_id - 4) << 3) + item)); + reg |= (val << (((port_id - 4) << 3) + item)); + + HSL_REG_ENTRY_SET(rv, dev_id, FRAME_ACK_CTL1, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + return rv; +} + +static sw_error_t +_dess_port_igmp_property_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable, a_uint32_t item) +{ + sw_error_t rv; + a_uint32_t reg = 0, val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (3 >= port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, FRAME_ACK_CTL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + val = (reg >> ((port_id << 3) + item)) & 0x1UL; + } + else + { + HSL_REG_ENTRY_GET(rv, dev_id, FRAME_ACK_CTL1, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + val = (reg >> (((port_id - 4) << 3) + item)) & 0x1UL; + } + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_igmp_mld_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_MAC_CPY_TO_CPU == cmd) + { + val = 1; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + val = 0; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, IGMP_COPY_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_igmp_mld_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, IGMP_COPY_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *cmd = FAL_MAC_CPY_TO_CPU; + } + else + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + + return SW_OK; +} + +static sw_error_t +_dess_igmp_mld_rp_set(a_uint32_t dev_id, fal_pbmp_t pts) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_mports_validity_check(dev_id, pts)) + { + return SW_BAD_PARAM; + } + val = pts; + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL1, 0, IGMP_DP, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_igmp_mld_rp_get(a_uint32_t dev_id, fal_pbmp_t * pts) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL1, 0, IGMP_DP, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *pts = val; + return SW_OK; +} + +static sw_error_t +_dess_igmp_mld_entry_creat_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, ADDR_TABLE_CTL, 0, IGMP_CREAT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_igmp_mld_entry_creat_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_CTL, 0, IGMP_CREAT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_igmp_mld_entry_static_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 0xf; + } + else if (A_FALSE == enable) + { + val = 0xe; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, ADDR_TABLE_CTL, 0, IGMP_JOIN_STATIC, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_igmp_mld_entry_static_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_CTL, 0, IGMP_JOIN_STATIC, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0xf == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_igmp_mld_entry_leaky_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, ADDR_TABLE_CTL, 0, IGMP_JOIN_LEAKY, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_igmp_mld_entry_leaky_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_CTL, 0, IGMP_JOIN_LEAKY, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_igmp_mld_entry_v3_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FRAME_ACK_CTL1, 0, IGMP_V3_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_igmp_mld_entry_v3_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FRAME_ACK_CTL1, 0, IGMP_V3_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_igmp_mld_entry_queue_set(a_uint32_t dev_id, a_bool_t enable, + a_uint32_t queue) +{ + sw_error_t rv; + a_uint32_t entry = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_CTL, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_CTL, IGMP_PRI_EN, 1, entry); + SW_SET_REG_BY_FIELD(ADDR_TABLE_CTL, IGMP_PRI, queue, entry); + } + else if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_CTL, IGMP_PRI_EN, 0, entry); + SW_SET_REG_BY_FIELD(ADDR_TABLE_CTL, IGMP_PRI, 0, entry); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_CTL, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_igmp_mld_entry_queue_get(a_uint32_t dev_id, a_bool_t * enable, + a_uint32_t * queue) +{ + sw_error_t rv; + a_uint32_t entry = 0, data; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_CTL, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(ADDR_TABLE_CTL, IGMP_PRI_EN, data, entry); + if (data) + { + *enable = A_TRUE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_CTL, IGMP_PRI, data, entry); + *queue = data; + } + else + { + *enable = A_FALSE; + *queue = 0; + } + + return SW_OK; +} + +static sw_error_t +_dess_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; + a_uint32_t reg = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + if (DESS_MAX_PORT_LEARN_LIMIT_CNT < cnt) + { + return SW_BAD_PARAM; + } + SW_SET_REG_BY_FIELD(PORT_LEARN_LIMIT_CTL, IGMP_JOIN_LIMIT_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_LEARN_LIMIT_CTL, IGMP_JOIN_CNT, cnt, reg); + } + else if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(PORT_LEARN_LIMIT_CTL, IGMP_JOIN_LIMIT_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_LEARN_LIMIT_CTL, IGMP_JOIN_CNT, 0, reg); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_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; + a_uint32_t data, reg = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_LEARN_LIMIT_CTL, IGMP_JOIN_LIMIT_EN, data, reg); + if (data) + { + SW_GET_FIELD_BY_REG(PORT_LEARN_LIMIT_CTL, IGMP_JOIN_CNT, data, reg); + *enable = A_TRUE; + *cnt = data; + } + else + { + *enable = A_FALSE; + *cnt = data; + } + + return SW_OK; +} + +static sw_error_t +_dess_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; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_MAC_DROP == cmd) + { + data = 1; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + data = 0; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + IGMP_JOIN_LIMIT_DROP_EN, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_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; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + IGMP_JOIN_LIMIT_DROP_EN, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data) + { + *cmd = FAL_MAC_DROP; + } + else + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + + return SW_OK; +} + +/** + * @brief Set igmp/mld packets snooping status on a particular port. + * @details Comments: + * After enabling igmp/mld snooping feature on a particular port all kinds + * igmp/mld packets received on this port would be acknowledged by hardware. + * Particular forwarding decision could be setted by fal_igmp_mld_cmd_set. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_igmps_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_igmp_property_set(dev_id, port_id, enable, + IGMP_MLD_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld packets snooping status on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_igmps_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_igmp_property_get(dev_id, port_id, enable, + IGMP_MLD_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmp/mld packets forwarding command on a particular device. + * @details Comments: + * Particular device may only support parts of forwarding commands. + * This operation will take effect only after enabling igmp/mld snooping + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_igmp_mld_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_igmp_mld_cmd_set(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld packets forwarding command on a particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_igmp_mld_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_igmp_mld_cmd_get(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmp/mld join packets hardware acknowledgement status on particular port. + * @details Comments: + * After enabling igmp/mld join feature on a particular port hardware will + * dynamic learning or changing multicast entry. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_igmp_mld_join_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_igmp_property_set(dev_id, port_id, enable, JOIN_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld join packets hardware acknowledgement status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_igmp_mld_join_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_igmp_property_get(dev_id, port_id, enable, JOIN_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmp/mld leave packets hardware acknowledgement status on a particular port. + * @details Comments: + * After enabling igmp leave feature on a particular port hardware will dynamic + * deleting or changing multicast entry. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_igmp_mld_leave_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_igmp_property_set(dev_id, port_id, enable, LEAVE_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld leave packets hardware acknowledgement status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_igmp_mld_leave_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_igmp_property_get(dev_id, port_id, enable, LEAVE_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmp/mld router ports on a particular device. + * @details Comments: + * After enabling igmp/mld join/leave feature on a particular port igmp/mld + * join/leave packets received on this port will be forwarded to router ports. + * @param[in] dev_id device id + * @param[in] pts dedicates ports + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_igmp_mld_rp_set(a_uint32_t dev_id, fal_pbmp_t pts) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_igmp_mld_rp_set(dev_id, pts); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld router ports on a particular device. + * @param[in] dev_id device id + * @param[out] pts dedicates ports + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_igmp_mld_rp_get(a_uint32_t dev_id, fal_pbmp_t * pts) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_igmp_mld_rp_get(dev_id, pts); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set the status of creating multicast entry during igmp/mld join/leave procedure. + * @details Comments: + * After enabling igmp/mld join/leave feature on a particular port if enable + * entry creat hardware will dynamic creat and delete multicast entry, + * otherwise hardware only can change destination ports of existing muticast entry. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_igmp_mld_entry_creat_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_igmp_mld_entry_creat_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get the status of creating multicast entry during igmp/mld join/leave procedure. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_igmp_mld_entry_creat_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_igmp_mld_entry_creat_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set the static status of multicast entry which learned by hardware. + * @details Comments: + * After enabling igmp/mld join/leave feature on a particular port if enable + * static status hardware will not age out multicast entry which leardned by hardware, + * otherwise hardware will age out multicast entry which leardned by hardware. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_igmp_mld_entry_static_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_igmp_mld_entry_static_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get the static status of multicast entry which learned by hardware. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_igmp_mld_entry_static_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_igmp_mld_entry_static_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set the leaky status of multicast entry which learned by hardware. + * @details Comments: + * After enabling igmp/mld join/leave feature on a particular port if enable + * leaky status hardware will set leaky flag of multicast entry which leardned by hardware, + * otherwise hardware will not set leaky flag of multicast entry which leardned by hardware. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_igmp_mld_entry_leaky_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_igmp_mld_entry_leaky_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get the leaky status of multicast entry which learned by hardware. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_igmp_mld_entry_leaky_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_igmp_mld_entry_leaky_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmpv3/mldv2 packets hardware acknowledgement status on a particular device. + * @details Comments: + * After enabling igmp join/leave feature on a particular port hardware will dynamic + * creating or changing multicast entry after receiving igmpv3/mldv2 packets. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_igmp_mld_entry_v3_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_igmp_mld_entry_v3_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmpv3/mldv2 packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_igmp_mld_entry_v3_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_igmp_mld_entry_v3_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set the queue status of multicast entry which learned by hardware. + * @details Comments: + * After enabling igmp/mld join/leave feature on a particular port if enable + * leaky status hardware will set queue flag of multicast entry which leardned by hardware, + * otherwise hardware will not set queue flag of multicast entry which leardned by hardware. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] queue queue id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_igmp_mld_entry_queue_set(a_uint32_t dev_id, a_bool_t enable, + a_uint32_t queue) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_igmp_mld_entry_queue_set(dev_id, enable, queue); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get the queue status of multicast entry which learned by hardware. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @param[out] queue queue id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_igmp_mld_entry_queue_get(a_uint32_t dev_id, a_bool_t * enable, + a_uint32_t * queue) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_igmp_mld_entry_queue_get(dev_id, enable, queue); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set IGMP hardware learning count limit on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] cnt limit count + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_port_igmp_mld_learn_limit_set(dev_id, port_id, enable, cnt); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IGMP hardware learning count limit on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @param[out] cnt limit count + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_port_igmp_mld_learn_limit_get(dev_id, port_id, enable, cnt); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set IGMP hardware learning count exceed command on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_port_igmp_mld_learn_exceed_cmd_set(dev_id, port_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IGMP hardware learning count exceed command on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_port_igmp_mld_learn_exceed_cmd_get(dev_id, port_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +dess_igmp_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->port_igmps_status_set = dess_port_igmps_status_set; + p_api->port_igmps_status_get = dess_port_igmps_status_get; + p_api->igmp_mld_cmd_set = dess_igmp_mld_cmd_set; + p_api->igmp_mld_cmd_get = dess_igmp_mld_cmd_get; + p_api->port_igmp_join_set = dess_port_igmp_mld_join_set; + p_api->port_igmp_join_get = dess_port_igmp_mld_join_get; + p_api->port_igmp_leave_set = dess_port_igmp_mld_leave_set; + p_api->port_igmp_leave_get = dess_port_igmp_mld_leave_get; + p_api->igmp_rp_set = dess_igmp_mld_rp_set; + p_api->igmp_rp_get = dess_igmp_mld_rp_get; + p_api->igmp_entry_creat_set = dess_igmp_mld_entry_creat_set; + p_api->igmp_entry_creat_get = dess_igmp_mld_entry_creat_get; + p_api->igmp_entry_static_set = dess_igmp_mld_entry_static_set; + p_api->igmp_entry_static_get = dess_igmp_mld_entry_static_get; + p_api->igmp_entry_leaky_set = dess_igmp_mld_entry_leaky_set; + p_api->igmp_entry_leaky_get = dess_igmp_mld_entry_leaky_get; + p_api->igmp_entry_v3_set = dess_igmp_mld_entry_v3_set; + p_api->igmp_entry_v3_get = dess_igmp_mld_entry_v3_get; + p_api->igmp_entry_queue_set = dess_igmp_mld_entry_queue_set; + p_api->igmp_entry_queue_get = dess_igmp_mld_entry_queue_get; + p_api->port_igmp_mld_learn_limit_set = dess_port_igmp_mld_learn_limit_set; + p_api->port_igmp_mld_learn_limit_get = dess_port_igmp_mld_learn_limit_get; + p_api->port_igmp_mld_learn_exceed_cmd_set = dess_port_igmp_mld_learn_exceed_cmd_set; + p_api->port_igmp_mld_learn_exceed_cmd_get = dess_port_igmp_mld_learn_exceed_cmd_get; + p_api->igmp_sg_entry_set = dess_igmp_sg_entry_set; + p_api->igmp_sg_entry_clear = dess_igmp_sg_entry_clear; + p_api->igmp_sg_entry_show = dess_igmp_sg_entry_show; + p_api->igmp_sg_entry_query = dess_igmp_sg_entry_query; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_init.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_init.c new file mode 100644 index 000000000..53eae17bb --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_init.c @@ -0,0 +1,343 @@ +/* + * 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 dess_init DESS_INIT + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "dess_mib.h" +#include "dess_port_ctrl.h" +#include "dess_portvlan.h" +#include "dess_vlan.h" +#include "dess_fdb.h" +#include "dess_qos.h" +#include "dess_mirror.h" +#include "dess_stp.h" +#include "dess_rate.h" +#include "dess_misc.h" +#include "dess_leaky.h" +#include "dess_igmp.h" +#include "dess_acl.h" +#include "dess_led.h" +#include "dess_cosmap.h" +#include "dess_ip.h" +#include "dess_nat.h" +#if defined(IN_NAT_HELPER) +#include "dess_nat_helper.h" +#endif +#include "dess_sec.h" +#include "dess_trunk.h" +#include "dess_interface_ctrl.h" +#include "dess_reg_access.h" +#include "dess_reg.h" +#include "dess_init.h" +#include + + +static ssdk_init_cfg * dess_cfg[SW_MAX_NR_DEV] = { 0 }; +a_uint32_t dess_nat_global_status = 0; + +#if !(defined(KERNEL_MODULE) && defined(USER_MODE)) +/* For isis there are five internal PHY devices and seven MAC devices. + PORT0 always connect to external DMA device. + MAC1..MAC4 connect to internal PHY0..PHY3. +*/ + + +a_uint32_t dess_pbmp_5[PORT_WRAPPER_MAX] = { + ((1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5)), /*PORT_WRAPPER_PSGMII*/ + ((1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5)), /*PORT_WRAPPER_PSGMII_RGMII5*/ + ((1<<1) | (1<<5)), /*PORT_WRAPPER_SGMII0_RGMII5*/ + ((1<<2) | (1<<5)), /*PORT_WRAPPER_SGMII1_RGMII5*/ + ((1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5)), /*PORT_WRAPPER_PSGMII_RMII0*/ + ((1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5)), /*PORT_WRAPPER_PSGMII_RMII1*/ + ((1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5)), /*PORT_WRAPPER_PSGMII_RMII0_RMII1*/ + ((1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5)), /*PORT_WRAPPER_SGMII_RGMII4*/ + ((1<<1) | (1<<4)), /*PORT_WRAPPER_SGMII0_RGMII4*/ + ((1<<2) | (1<<4)), /*PORT_WRAPPER_SGMII1_RGMII4*/ + ((1<<5) | (1<<4)), /*PORT_WRAPPER_SGMII4_RGMII4*/ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ((1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5)), /*PORT_WRAPPER_PSGMII_FIBER*/ + }; + +a_uint32_t dess_pbmp_2[PORT_WRAPPER_MAX] = { + ((1<<4) | (1<<5)), /*PORT_WRAPPER_PSGMII*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ((1<<4) | (1<<5)), /*PORT_WRAPPER_PSGMII_FIBER*/ + }; + +a_uint32_t dess_get_port_phy_id(void) +{ + return dess_cfg[0]->phy_id; +} + +enum ssdk_port_wrapper_cfg dess_get_port_config(void) +{ + return dess_cfg[0]->mac_mode; +} + +a_bool_t dess_mac_port_valid_check(fal_port_t port_id) +{ + a_uint32_t bitmap = 0; + enum ssdk_port_wrapper_cfg cfg; + a_uint32_t phy_id; + + cfg = dess_get_port_config(); + phy_id = dess_get_port_phy_id(); + + if (phy_id == MALIBU_1_1_2PORT) + bitmap = dess_pbmp_2[cfg]; + else { + bitmap = dess_pbmp_5[cfg]; + } + return SW_IS_PBMP_MEMBER(bitmap, port_id); + +} + +static sw_error_t +dess_portproperty_init(a_uint32_t dev_id) +{ + hsl_port_prop_t p_type; + hsl_dev_t *pdev = NULL; + fal_port_t port_id; + enum ssdk_port_wrapper_cfg cfg; + a_uint32_t bitmap = 0; + + pdev = hsl_dev_ptr_get(dev_id); + if (pdev == NULL) + return SW_NOT_INITIALIZED; + + cfg = dess_get_port_config(); + bitmap = dess_pbmp_5[cfg]; + + /* for port property set, SSDK should not generate some limitations */ + for (port_id = 0; port_id < SW_MAX_NR_PORT; port_id++) + { + if((!SW_IS_PBMP_MEMBER(bitmap, port_id)) && (port_id != pdev->cpu_port_nr)) + continue; + + hsl_port_prop_portmap_set(dev_id, port_id); + + for (p_type = HSL_PP_PHY; p_type < HSL_PP_BUTT; p_type++) + { + + switch (p_type) + { + case HSL_PP_PHY: + /* Only port0 without PHY device */ + if (port_id != pdev->cpu_port_nr) + { + if(SW_IS_PBMP_MEMBER(bitmap, port_id)) + SW_RTN_ON_ERROR(hsl_port_prop_set(dev_id, port_id, p_type)); + } + break; + + case HSL_PP_INCL_CPU: + /* include cpu port but exclude wan port in some cases */ + /* but which port is wan port, we are no meaning */ + if (port_id == pdev->cpu_port_nr) + SW_RTN_ON_ERROR(hsl_port_prop_set(dev_id, port_id, p_type)); + if(SW_IS_PBMP_MEMBER(bitmap, port_id)) + SW_RTN_ON_ERROR(hsl_port_prop_set(dev_id, port_id, p_type)); + break; + + case HSL_PP_EXCL_CPU: + /* exclude cpu port and wan port in some cases */ + /* which port is wan port, we are no meaning but port0 is + always CPU port */ + if (port_id != pdev->cpu_port_nr) + { + if(SW_IS_PBMP_MEMBER(bitmap, port_id)) + SW_RTN_ON_ERROR(hsl_port_prop_set(dev_id, port_id, p_type)); + } + break; + + default: + break; + } + } + + if (port_id != pdev->cpu_port_nr) + { + SW_RTN_ON_ERROR(hsl_port_prop_set_phyid + (dev_id, port_id, port_id - 1)); + } + } + + return SW_OK; +} +#endif + +static sw_error_t +dess_dev_init(a_uint32_t dev_id, ssdk_init_cfg *cfg) +{ + a_uint32_t entry = 0; + sw_error_t rv; + hsl_dev_t *pdev = NULL; + + pdev = hsl_dev_ptr_get(dev_id); + if (pdev == NULL) + return SW_NOT_INITIALIZED; + + HSL_REG_FIELD_GET(rv, dev_id, MASK_CTL, 0, DEVICE_ID, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (DESS_DEVICE_ID == entry) + { + a_uint32_t i = 0, port_nr = 0, tmp = 0; + tmp = cfg->port_cfg.lan_bmp | cfg->port_cfg.wan_bmp; + for(i = 0; i < SW_MAX_NR_PORT; i++) { + if(tmp & (1 << i)) { + port_nr++; + } + } + pdev->nr_phy = port_nr; + for(i = 0; i < SW_MAX_NR_PORT; i++) { + if(cfg->port_cfg.cpu_bmp & (1 << i)) { + port_nr++; + pdev->cpu_port_nr = i; + break; + } + } + if(i >= SW_MAX_NR_PORT) + return SW_BAD_VALUE; + pdev->nr_ports = port_nr; + pdev->nr_vlans = 4096; + pdev->hw_vlan_query = A_TRUE; + pdev->nr_queue = port_nr; + pdev->cpu_mode = cfg->cpu_mode; + pdev->wan_bmp = cfg->port_cfg.wan_bmp; + } + + return SW_OK; +} + +sw_error_t +dess_cleanup(a_uint32_t dev_id) +{ + sw_error_t rv; + + if (dess_cfg[dev_id]) + { +#if defined(IN_NAT_HELPER) + if(dess_nat_global_status) + DESS_NAT_HELPER_CLEANUP(rv, dev_id); +#endif + + DESS_ACL_CLEANUP(rv, dev_id); + + SW_RTN_ON_ERROR(hsl_port_prop_cleanup_by_dev(dev_id)); + + aos_mem_free(dess_cfg[dev_id]); + dess_cfg[dev_id] = NULL; + } + + return SW_OK; +} + +/** + * @brief Init hsl layer. + * @details Comments: + * This operation will init hsl layer and hsl layer + * @param[in] dev_id device id + * @param[in] cfg configuration for initialization + * @return SW_OK or error code + */ +sw_error_t +dess_init(a_uint32_t dev_id, ssdk_init_cfg *cfg) +{ + HSL_DEV_ID_CHECK(dev_id); + + if (NULL == dess_cfg[dev_id]) + { + dess_cfg[dev_id] = aos_mem_alloc(sizeof (ssdk_init_cfg)); + } + + if (NULL == dess_cfg[dev_id]) + { + return SW_OUT_OF_MEM; + } + + aos_mem_copy(dess_cfg[dev_id], cfg, sizeof (ssdk_init_cfg)); + + SW_RTN_ON_ERROR(dess_reg_access_init(dev_id, cfg->reg_mode)); + + SW_RTN_ON_ERROR(dess_dev_init(dev_id, cfg)); + +#if !(defined(KERNEL_MODULE) && defined(USER_MODE)) + { + sw_error_t rv; + + SW_RTN_ON_ERROR(hsl_port_prop_init(dev_id)); + SW_RTN_ON_ERROR(hsl_port_prop_init_by_dev(dev_id)); + SW_RTN_ON_ERROR(dess_portproperty_init(dev_id)); + + DESS_MIB_INIT(rv, dev_id); + DESS_PORT_CTRL_INIT(rv, dev_id); + DESS_PORTVLAN_INIT(rv, dev_id); + DESS_VLAN_INIT(rv, dev_id); + DESS_FDB_INIT(rv, dev_id); + DESS_QOS_INIT(rv, dev_id); + DESS_STP_INIT(rv, dev_id); + DESS_MIRR_INIT(rv, dev_id); + DESS_RATE_INIT(rv, dev_id); + DESS_MISC_INIT(rv, dev_id); + DESS_LEAKY_INIT(rv, dev_id); + DESS_IGMP_INIT(rv, dev_id); + DESS_ACL_INIT(rv, dev_id); + DESS_LED_INIT(rv, dev_id); + DESS_COSMAP_INIT(rv, dev_id); + DESS_IP_INIT(rv, dev_id); + DESS_NAT_INIT(rv, dev_id); + DESS_TRUNK_INIT(rv, dev_id); + DESS_SEC_INIT(rv, dev_id); + DESS_INTERFACE_CTRL_INIT(rv, dev_id); + + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->dev_clean = dess_cleanup; + } +#if 0 +#if defined(IN_NAT_HELPER) + if(!dess_nat_global_status) { + DESS_NAT_HELPER_INIT(rv, dev_id); + dess_nat_global_status = 1; + } +#endif +#endif + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_interface_ctrl.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_interface_ctrl.c new file mode 100755 index 000000000..f6396f943 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_interface_ctrl.c @@ -0,0 +1,299 @@ +/* + * Copyright (c) 2014, 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. + */ + + +/** + * @defgroup dess_interface_ctrl DESS_INTERFACE_CONTROL + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "dess_interface_ctrl.h" +#include "dess_reg.h" + + +#define DESS_PHY_MODE_PHY_ID 4 +#define DESS_LPI_PORT1_OFFSET 4 +#define DESS_LPI_BIT_STEP 2 +#define DESS_LPI_ENABLE 3 + +#define DESS_MAC4 4 +#define DESS_MAC5 5 + +static sw_error_t +_dess_port_3az_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv = SW_OK; + a_uint32_t reg = 0, field, offset, device_id; + + HSL_REG_ENTRY_GET(rv, dev_id, MASK_CTL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(MASK_CTL, DEVICE_ID, device_id, reg); + if (DESS_DEVICE_ID != device_id) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, EEE_CTL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + field = DESS_LPI_ENABLE; + } + else if (A_FALSE == enable) + { + field = 0; + } + else + { + return SW_BAD_PARAM; + } + + offset = (port_id - 1) * DESS_LPI_BIT_STEP + DESS_LPI_PORT1_OFFSET; + reg &= (~(DESS_LPI_ENABLE << offset)); + reg |= (field << offset); + + HSL_REG_ENTRY_SET(rv, dev_id, EEE_CTL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_port_3az_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv = SW_OK; + a_uint32_t reg = 0, field, offset, device_id; + + HSL_REG_ENTRY_GET(rv, dev_id, MASK_CTL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(MASK_CTL, DEVICE_ID, device_id, reg); + if (DESS_DEVICE_ID != device_id) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, EEE_CTL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + offset = (port_id - 1) * DESS_LPI_BIT_STEP + DESS_LPI_PORT1_OFFSET; + field = (reg >> offset) & 0x3; + + if (field == DESS_LPI_ENABLE) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_interface_mac_mode_set(a_uint32_t dev_id, fal_port_t port_id, fal_mac_config_t * config) +{ + sw_error_t rv = SW_OK; + a_uint32_t reg = 0, field; + + HSL_DEV_ID_CHECK(dev_id); + + + if (FAL_MAC_MODE_RMII == config->mac_mode) + { + HSL_REG_ENTRY_GET(rv, dev_id, RGMII_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + if (port_id == DESS_MAC4) { + SW_GET_FIELD_BY_REG(RGMII_CTRL, RMII1_MASTER_EN, field, reg); + if(field == config->config.rmii.master_mode) + return rv; + SW_SET_REG_BY_FIELD(RGMII_CTRL, RMII1_MASTER_EN, config->config.rmii.master_mode, reg); + } + else if (port_id == DESS_MAC5) { + SW_GET_FIELD_BY_REG(RGMII_CTRL, RMII0_MASTER_EN, field, reg); + if(field == config->config.rmii.master_mode) + return rv; + SW_SET_REG_BY_FIELD(RGMII_CTRL, RMII1_MASTER_EN, config->config.rmii.master_mode, reg); + } + else + { + return SW_BAD_PARAM; + } + HSL_REG_ENTRY_SET(rv, dev_id, RGMII_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + + return rv; +} + +static sw_error_t +_dess_interface_mac_mode_get(a_uint32_t dev_id, fal_port_t port_id, fal_mac_config_t * config) +{ + sw_error_t rv = SW_OK; + a_uint32_t reg = 0, field; + + HSL_DEV_ID_CHECK(dev_id); + + + if (FAL_MAC_MODE_RMII == config->mac_mode) + { + HSL_REG_ENTRY_GET(rv, dev_id, RGMII_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + if (port_id == DESS_MAC4) { + SW_GET_FIELD_BY_REG(RGMII_CTRL, RMII1_MASTER_EN, field, reg); + config->config.rmii.master_mode = field; + } + else if (port_id == DESS_MAC5) { + SW_GET_FIELD_BY_REG(RGMII_CTRL, RMII0_MASTER_EN, field, reg); + config->config.rmii.master_mode = field; + } + else + { + return SW_BAD_PARAM; + } + } + else + { + return SW_BAD_PARAM; + } + + return rv; +} + + +/** + * @brief Set 802.3az status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_3az_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_3az_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get 802.3az status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_3az_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_3az_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + + +/** + * @brief Set interface mode on RGMII/RMII. + * @param[in] dev_id device id + * @param[in] delay + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_interface_mac_mode_set(a_uint32_t dev_id, fal_port_t port_id, fal_mac_config_t * config) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_interface_mac_mode_set(dev_id, port_id, config); + HSL_API_UNLOCK; + return rv; +} + + +/** + * @brief Get interface mode on RGMII/RMII. + * @param[in] dev_id device id + * @param[in] mca_id MAC device ID + * @param[out] config interface configuration + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_interface_mac_mode_get(a_uint32_t dev_id, fal_port_t port_id, fal_mac_config_t * config) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_interface_mac_mode_get(dev_id, port_id, config); + HSL_API_UNLOCK; + return rv; +} + + + + +sw_error_t +dess_interface_ctrl_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->port_3az_status_set = dess_port_3az_status_set; + p_api->port_3az_status_get = dess_port_3az_status_get; + p_api->interface_mac_mode_set = dess_interface_mac_mode_set; + p_api->interface_mac_mode_get = dess_interface_mac_mode_get; + + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_ip.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_ip.c new file mode 100755 index 000000000..5e636a311 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_ip.c @@ -0,0 +1,3668 @@ +/* + * Copyright (c) 2014-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. + */ + + +/** + * @defgroup dess_ip DESS_IP + * @{ + */ + +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "dess_ip.h" +#include "dess_reg.h" + +#define DESS_HOST_ENTRY_DATA0_ADDR 0x0e80 +#define DESS_HOST_ENTRY_DATA1_ADDR 0x0e84 +#define DESS_HOST_ENTRY_DATA2_ADDR 0x0e88 +#define DESS_HOST_ENTRY_DATA3_ADDR 0x0e8c +#define DESS_HOST_ENTRY_DATA4_ADDR 0x0e90 +#define DESS_HOST_ENTRY_DATA5_ADDR 0x0e94 +#define DESS_HOST_ENTRY_DATA6_ADDR 0x0e98 +#define DESS_HOST_ENTRY_DATA7_ADDR 0x0e58 + +#define DESS_HOST_ENTRY_REG_NUM 8 + +#define DESS_HOST_ENTRY_FLUSH 1 +#define DESS_HOST_ENTRY_ADD 2 +#define DESS_HOST_ENTRY_DEL 3 +#define DESS_HOST_ENTRY_NEXT 4 +#define DESS_HOST_ENTRY_SEARCH 5 + +#define DESS_ENTRY_ARP 3 + +#define DESS_INTF_MAC_ADDR_NUM 8 +#define DESS_INTF_MAC_TBL0_ADDR 0x5a900 +#define DESS_INTF_MAC_TBL1_ADDR 0x5a904 +#define DESS_INTF_MAC_TBL2_ADDR 0x5a908 +#define DESS_INTF_MAC_EDIT0_ADDR 0x02000 +#define DESS_INTF_MAC_EDIT1_ADDR 0x02004 +#define DESS_INTF_MAC_EDIT2_ADDR 0x02008 + +#define DESS_IP6_BASE_ADDR 0x0470 + +#define DESS_HOST_ENTRY_NUM 128 + +#define DESS_IP_COUTER_ADDR 0x2b000 + +#define DESS_DEFAULT_ROUTE_NUM 8 +#define DESS_IP4_DEFAULT_ROUTE_TBL_ADDR 0x004c4 +#define DESS_IP6_DEFAULT_ROUTE_TBL_ADDR 0x004e4 +#define DESS_HOST_ROUTE_NUM 16 +#define DESS_IP4_HOST_ROUTE_TBL0_ADDR 0x5b000 +#define DESS_IP4_HOST_ROUTE_TBL1_ADDR 0x5b004 +#define DESS_IP6_HOST_ROUTE_TBL0_ADDR 0x5b100 +#define DESS_IP6_HOST_ROUTE_TBL1_ADDR 0x5b104 +#define DESS_IP6_HOST_ROUTE_TBL2_ADDR 0x5b108 +#define DESS_IP6_HOST_ROUTE_TBL3_ADDR 0x5b10c +#define DESS_IP6_HOST_ROUTE_TBL4_ADDR 0x5b110 + + +static a_uint32_t dess_mac_snap[SW_MAX_NR_DEV] = { 0 }; +static fal_intf_mac_entry_t dess_intf_snap[SW_MAX_NR_DEV][DESS_INTF_MAC_ADDR_NUM]; + +extern aos_lock_t dess_nat_lock; + + +static void +_dess_ip_pt_learn_save(a_uint32_t dev_id, a_uint32_t * status) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_PTCTRL2, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + if (SW_OK != rv) + { + return; + } + + *status = (data & 0x7f7f); + + data &= 0xffff8080; + HSL_REG_ENTRY_SET(rv, dev_id, ROUTER_PTCTRL2, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return; +} + +static void +_dess_ip_pt_learn_restore(a_uint32_t dev_id, a_uint32_t status) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_PTCTRL2, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + if (SW_OK != rv) + { + return; + } + + data &= 0xffff8080; + data |= (status & 0x7f7f); + + HSL_REG_ENTRY_SET(rv, dev_id, ROUTER_PTCTRL2, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return; +} + +static sw_error_t +_dess_ip_feature_check(a_uint32_t dev_id) +{ + sw_error_t rv; + a_uint32_t entry = 0; + + HSL_REG_FIELD_GET(rv, dev_id, MASK_CTL, 0, DEVICE_ID, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (DESS_DEVICE_ID == entry) + { + return SW_OK; + } + else + { + return SW_NOT_SUPPORTED; + } +} + +static sw_error_t +_dess_ip_counter_get(a_uint32_t dev_id, a_uint32_t cnt_id, + a_uint32_t counter[2]) +{ + sw_error_t rv; + a_uint32_t i, addr; + + addr = DESS_IP_COUTER_ADDR + (cnt_id << 3); + for (i = 0; i < 2; i++) + { + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(counter[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + addr += 4; + } + + return SW_OK; +} + +static sw_error_t +_dess_host_entry_commit(a_uint32_t dev_id, a_uint32_t entry_type, a_uint32_t op) +{ + a_uint32_t busy = 1, i = 0x9000000, entry = 0, j, try_num; + a_uint32_t learn_status = 0, data = 0; + sw_error_t rv; + + while (busy && --i) + { + HSL_REG_ENTRY_GET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (&entry), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + //printk("IP first entry is 0x%x\r\n", entry); + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_BUSY, busy, entry); + } + + if (i == 0) + { + printk("host entry busy!\n"); + return SW_BUSY; + } + + + /* hardware requirements, we should disable ARP learn at first */ + /* and maybe we should try several times... */ + _dess_ip_pt_learn_save(dev_id, &learn_status); + + //printk("data0=0x%x\n", data); + if(learn_status) { + aos_mdelay(800); + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_PTCTRL2, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + //printk("data1=0x%x\n", data); + + + SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_BUSY, 1, entry); + SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_SEL, entry_type, entry); + SW_SET_REG_BY_FIELD(HOST_ENTRY7, ENTRY_FUNC, op, entry); + + HSL_REG_ENTRY_SET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (&entry), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (learn_status) + { + try_num = 300; + } + else + { + try_num = 1; + } + + for (j = 0; j < try_num; j++) + { + busy = 1; + i = 0x9000000; + while (busy && --i) + { + HSL_REG_ENTRY_GET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (&entry), + sizeof (a_uint32_t)); + //printk("IP second entry is 0x%x\r\n", entry); + if (SW_OK != rv) + { + _dess_ip_pt_learn_restore(dev_id, learn_status); + return rv; + } + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_BUSY, busy, entry); + } + + if (i == 0) + { + _dess_ip_pt_learn_restore(dev_id, learn_status); + return SW_BUSY; + } + + /* hardware requirement, we should read again... */ + HSL_REG_ENTRY_GET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (&entry), + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + _dess_ip_pt_learn_restore(dev_id, learn_status); + return rv; + } + + /* operation success...... */ + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_STAUS, busy, entry); + if (busy) + { + _dess_ip_pt_learn_restore(dev_id, learn_status); + return SW_OK; + } + } + + _dess_ip_pt_learn_restore(dev_id, learn_status); + if (DESS_HOST_ENTRY_NEXT == op) + { + return SW_NO_MORE; + } + else if (DESS_HOST_ENTRY_SEARCH == op) + { + return SW_NOT_FOUND; + } + else if (DESS_HOST_ENTRY_DEL == op) + { + return SW_NOT_FOUND; + } + else + { + return SW_FAIL; + } +} + +static sw_error_t +_dess_ip_intf_sw_to_hw(a_uint32_t dev_id, fal_host_entry_t * entry, + a_uint32_t * hw_intf) +{ + sw_error_t rv; + a_uint32_t addr, lvid, hvid, tbl[3] = {0}, i; + a_uint32_t sw_intf = entry->intf_id; + a_uint32_t vid_offset; + + for (i = 0; i < DESS_INTF_MAC_ADDR_NUM; i++) + { + if (dess_mac_snap[dev_id] & (0x1 << i)) + { + addr = DESS_INTF_MAC_TBL0_ADDR + (i << 4) + 4; + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[1])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + addr = DESS_INTF_MAC_TBL0_ADDR + (i << 4) + 8; + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[2])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY1, VID_HIGH0, hvid, tbl[1]); + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY2, VID_HIGH1, lvid, tbl[2]); + hvid |= ((lvid & 0xff) << 4); + + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY1, VID_LOW, lvid, tbl[1]); + + if ((lvid <= sw_intf) && (hvid >= sw_intf)) + { + vid_offset = entry->expect_vid ? (entry->expect_vid - lvid) : (sw_intf - lvid); + *hw_intf = (vid_offset << 3) | i; + return SW_OK; + } + } + } + + return SW_BAD_PARAM; +} + +static sw_error_t +_dess_ip_intf_hw_to_sw(a_uint32_t dev_id, a_uint32_t hw_intf, + a_uint32_t * sw_intf) +{ + sw_error_t rv; + a_uint32_t addr, lvid, tbl = 0, i; + + i = hw_intf & 0x7; + + addr = DESS_INTF_MAC_TBL0_ADDR + (i << 4) + 4; + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&tbl), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY1, VID_LOW, lvid, tbl); + *sw_intf = lvid + (hw_intf >> 3); + + return SW_OK; +} + +static sw_error_t +_dess_ip_age_time_set(a_uint32_t dev_id, a_uint32_t * time) +{ + sw_error_t rv; + a_uint32_t data; + + if (255 < ((*time + 5) / 6)) + { + return SW_BAD_PARAM; + } + + data = ((*time + 5) / 6); + *time = data * 6; + + HSL_REG_FIELD_SET(rv, dev_id, ROUTER_CTRL, 0, ARP_AGE_TIME, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_ip_age_time_get(a_uint32_t dev_id, a_uint32_t * time) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_REG_FIELD_GET(rv, dev_id, ROUTER_CTRL, 0, ARP_AGE_TIME, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *time = data * 6; + return SW_OK; +} + +static sw_error_t +_dess_host_sw_to_hw(a_uint32_t dev_id, fal_host_entry_t * entry, + a_uint32_t reg[]) +{ + sw_error_t rv; + a_uint32_t data; + + if (FAL_IP_IP4_ADDR & entry->flags) + { + reg[0] = entry->ip4_addr; + SW_SET_REG_BY_FIELD(HOST_ENTRY6, IP_VER, 0, reg[6]); + } + + if (FAL_IP_IP6_ADDR & entry->flags) + { + reg[0] = entry->ip6_addr.ul[3]; + reg[1] = entry->ip6_addr.ul[2]; + reg[2] = entry->ip6_addr.ul[1]; + reg[3] = entry->ip6_addr.ul[0]; + SW_SET_REG_BY_FIELD(HOST_ENTRY6, IP_VER, 1, reg[6]); + } + + SW_SET_REG_BY_FIELD(HOST_ENTRY4, MAC_ADDR2, entry->mac_addr.uc[2], reg[4]); + SW_SET_REG_BY_FIELD(HOST_ENTRY4, MAC_ADDR3, entry->mac_addr.uc[3], reg[4]); + SW_SET_REG_BY_FIELD(HOST_ENTRY4, MAC_ADDR4, entry->mac_addr.uc[4], reg[4]); + SW_SET_REG_BY_FIELD(HOST_ENTRY4, MAC_ADDR5, entry->mac_addr.uc[5], reg[4]); + SW_SET_REG_BY_FIELD(HOST_ENTRY5, MAC_ADDR0, entry->mac_addr.uc[0], reg[5]); + SW_SET_REG_BY_FIELD(HOST_ENTRY5, MAC_ADDR1, entry->mac_addr.uc[1], reg[5]); + + rv = _dess_ip_intf_sw_to_hw(dev_id, entry/*was:->intf_id*/, &data); + + SW_RTN_ON_ERROR(rv); + SW_SET_REG_BY_FIELD(HOST_ENTRY5, INTF_ID, data, reg[5]); + +#if 0 + if (A_TRUE != hsl_port_prop_check(dev_id, entry->port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } +#endif + + SW_SET_REG_BY_FIELD(HOST_ENTRY5, SRC_PORT, entry->port_id, reg[5]); + + if (FAL_IP_CPU_ADDR & entry->flags) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY5, CPU_ADDR, 1, reg[5]); + } + + SW_SET_REG_BY_FIELD(HOST_ENTRY6, AGE_FLAG, entry->status, reg[6]); + SW_SET_REG_BY_FIELD(HOST_ENTRY6, VRF_ID, entry->vrf_id, reg[6]); + SW_SET_REG_BY_FIELD(HOST_ENTRY6, LB_BIT, entry->lb_num, reg[6]); + + if ((A_TRUE == entry->mirror_en) && (FAL_MAC_FRWRD != entry->action)) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == entry->counter_en) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY6, CNT_EN, 1, reg[6]); + SW_SET_REG_BY_FIELD(HOST_ENTRY6, CNT_IDX, entry->counter_id, reg[6]); + } + + if (FAL_MAC_DROP == entry->action) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY5, SRC_PORT, 7, reg[5]); + SW_SET_REG_BY_FIELD(HOST_ENTRY6, ACTION, 3, reg[6]); + } + else if (FAL_MAC_RDT_TO_CPU == entry->action) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY6, ACTION, 1, reg[6]); + } + else if (FAL_MAC_CPY_TO_CPU == entry->action) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY6, ACTION, 2, reg[6]); + } + else + { + if (A_TRUE == entry->mirror_en) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY6, ACTION, 0, reg[6]); + } + else + { + SW_SET_REG_BY_FIELD(HOST_ENTRY6, ACTION, 3, reg[6]); + } + } + + return SW_OK; +} + +static sw_error_t +_dess_host_hw_to_sw(a_uint32_t dev_id, a_uint32_t reg[], + fal_host_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t data = 0, cnt[2] = {0}; + + SW_GET_FIELD_BY_REG(HOST_ENTRY6, IP_VER, data, reg[6]); + if (data) + { + entry->ip6_addr.ul[0] = reg[3]; + entry->ip6_addr.ul[1] = reg[2]; + entry->ip6_addr.ul[2] = reg[1]; + entry->ip6_addr.ul[3] = reg[0]; + entry->flags |= FAL_IP_IP6_ADDR; + } + else + { + entry->ip4_addr = reg[0]; + entry->flags |= FAL_IP_IP4_ADDR; + } + + SW_GET_FIELD_BY_REG(HOST_ENTRY4, MAC_ADDR2, entry->mac_addr.uc[2], reg[4]); + SW_GET_FIELD_BY_REG(HOST_ENTRY4, MAC_ADDR3, entry->mac_addr.uc[3], reg[4]); + SW_GET_FIELD_BY_REG(HOST_ENTRY4, MAC_ADDR4, entry->mac_addr.uc[4], reg[4]); + SW_GET_FIELD_BY_REG(HOST_ENTRY4, MAC_ADDR5, entry->mac_addr.uc[5], reg[4]); + SW_GET_FIELD_BY_REG(HOST_ENTRY5, MAC_ADDR0, entry->mac_addr.uc[0], reg[5]); + SW_GET_FIELD_BY_REG(HOST_ENTRY5, MAC_ADDR1, entry->mac_addr.uc[1], reg[5]); + + SW_GET_FIELD_BY_REG(HOST_ENTRY5, INTF_ID, data, reg[5]); + rv = _dess_ip_intf_hw_to_sw(dev_id, data, &(entry->intf_id)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(HOST_ENTRY5, SRC_PORT, entry->port_id, reg[5]); + + SW_GET_FIELD_BY_REG(HOST_ENTRY5, CPU_ADDR, data, reg[5]); + if (data) + { + entry->flags |= FAL_IP_CPU_ADDR; + } + + SW_GET_FIELD_BY_REG(HOST_ENTRY6, AGE_FLAG, entry->status, reg[6]); + SW_GET_FIELD_BY_REG(HOST_ENTRY6, VRF_ID, entry->vrf_id, reg[6]); + SW_GET_FIELD_BY_REG(HOST_ENTRY6, LB_BIT, entry->lb_num, reg[6]); + + SW_GET_FIELD_BY_REG(HOST_ENTRY6, CNT_EN, data, reg[6]); + if (data) + { + entry->counter_en = A_TRUE; + SW_GET_FIELD_BY_REG(HOST_ENTRY6, CNT_IDX, entry->counter_id, reg[6]); + + rv = _dess_ip_counter_get(dev_id, entry->counter_id, cnt); + SW_RTN_ON_ERROR(rv); + + entry->packet = cnt[0]; + entry->byte = cnt[1]; + } + else + { + entry->counter_en = A_FALSE; + } + + SW_GET_FIELD_BY_REG(HOST_ENTRY6, PPPOE_EN, data, reg[6]); + if (data) + { + entry->pppoe_en = A_TRUE; + SW_GET_FIELD_BY_REG(HOST_ENTRY6, PPPOE_IDX, data, reg[6]); + entry->pppoe_id = data; + } + else + { + entry->pppoe_en = A_FALSE; + } + + if (7 == entry->port_id) + { + entry->port_id = 0; + entry->action = FAL_MAC_DROP; + } + else + { + SW_GET_FIELD_BY_REG(HOST_ENTRY6, ACTION, data, reg[6]); + entry->action = FAL_MAC_FRWRD; + if (0 == data) + { + entry->mirror_en = A_TRUE; + } + else if (1 == data) + { + entry->action = FAL_MAC_RDT_TO_CPU; + } + else if (2 == data) + { + entry->action = FAL_MAC_CPY_TO_CPU; + } + } + + return SW_OK; +} + +static sw_error_t +_dess_host_down_to_hw(a_uint32_t dev_id, a_uint32_t reg[]) +{ + sw_error_t rv; + a_uint32_t i, addr; + + for (i = 0; i < DESS_HOST_ENTRY_REG_NUM; i++) + { + if((DESS_HOST_ENTRY_REG_NUM - 1) == i) + { + addr = DESS_HOST_ENTRY_DATA7_ADDR; + } + else + { + addr = DESS_HOST_ENTRY_DATA0_ADDR + (i << 2); + } + + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®[i]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +static sw_error_t +_dess_host_up_to_sw(a_uint32_t dev_id, a_uint32_t reg[]) +{ + sw_error_t rv; + a_uint32_t i, addr; + + for (i = 0; i < DESS_HOST_ENTRY_REG_NUM; i++) + { + if((DESS_HOST_ENTRY_REG_NUM - 1) == i) + { + addr = DESS_HOST_ENTRY_DATA7_ADDR; + } + else + { + addr = DESS_HOST_ENTRY_DATA0_ADDR + (i << 2); + } + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®[i]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +static sw_error_t +_dess_ip_host_add(a_uint32_t dev_id, fal_host_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t reg[DESS_HOST_ENTRY_REG_NUM] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + rv = _dess_host_sw_to_hw(dev_id, entry, reg); + SW_RTN_ON_ERROR(rv); + + aos_lock_bh(&dess_nat_lock); + rv = _dess_host_down_to_hw(dev_id, reg); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + rv = _dess_host_entry_commit(dev_id, DESS_ENTRY_ARP, DESS_HOST_ENTRY_ADD); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + HSL_REG_ENTRY_GET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (®[7]), + sizeof (a_uint32_t)); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + aos_unlock_bh(&dess_nat_lock); + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_IDX, entry->entry_id, reg[7]); + + return SW_OK; +} + +static sw_error_t +_dess_ip_host_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_host_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t data, reg[DESS_HOST_ENTRY_REG_NUM] = { 0 }, op = DESS_HOST_ENTRY_FLUSH; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_IP_ENTRY_ID_EN & del_mode) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_IP_ENTRY_IPADDR_EN & del_mode) + { + op = DESS_HOST_ENTRY_DEL; + if (FAL_IP_IP4_ADDR & entry->flags) + { + reg[0] = entry->ip4_addr; + } + + if (FAL_IP_IP6_ADDR & entry->flags) + { + reg[0] = entry->ip6_addr.ul[3]; + reg[1] = entry->ip6_addr.ul[2]; + reg[2] = entry->ip6_addr.ul[1]; + reg[3] = entry->ip6_addr.ul[0]; + SW_SET_REG_BY_FIELD(HOST_ENTRY6, IP_VER, 1, reg[6]); + } + } + + if (FAL_IP_ENTRY_INTF_EN & del_mode) + { + rv = _dess_ip_intf_sw_to_hw(dev_id, entry/*was:->intf_id*/, &data); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_VID, 1, reg[7]); + SW_SET_REG_BY_FIELD(HOST_ENTRY5, INTF_ID, data, reg[5]); + } + + if (FAL_IP_ENTRY_PORT_EN & del_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_SP, 1, reg[7]); + SW_SET_REG_BY_FIELD(HOST_ENTRY5, SRC_PORT, entry->port_id, reg[5]); + } + + if (FAL_IP_ENTRY_STATUS_EN & del_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_STATUS, 1, reg[7]); + SW_SET_REG_BY_FIELD(HOST_ENTRY6, AGE_FLAG, entry->status, reg[6]); + } + aos_lock_bh(&dess_nat_lock); + rv = _dess_host_down_to_hw(dev_id, reg); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + rv = _dess_host_entry_commit(dev_id, DESS_ENTRY_ARP, op); + aos_unlock_bh(&dess_nat_lock); + + return rv; +} + +static sw_error_t +_dess_ip_host_get(a_uint32_t dev_id, a_uint32_t get_mode, + fal_host_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t reg[DESS_HOST_ENTRY_REG_NUM] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_IP_ENTRY_IPADDR_EN != get_mode) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_IP_IP4_ADDR & entry->flags) + { + reg[0] = entry->ip4_addr; + } + else + { + reg[0] = entry->ip6_addr.ul[3]; + reg[1] = entry->ip6_addr.ul[2]; + reg[2] = entry->ip6_addr.ul[1]; + reg[3] = entry->ip6_addr.ul[0]; + SW_SET_REG_BY_FIELD(HOST_ENTRY6, IP_VER, 1, reg[6]); + } + aos_lock_bh(&dess_nat_lock); + rv = _dess_host_down_to_hw(dev_id, reg); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + rv = _dess_host_entry_commit(dev_id, DESS_ENTRY_ARP, + DESS_HOST_ENTRY_SEARCH); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + rv = _dess_host_up_to_sw(dev_id, reg); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + aos_mem_zero(entry, sizeof (fal_host_entry_t)); + + rv = _dess_host_hw_to_sw(dev_id, reg, entry); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + if (!(entry->status)) + { + aos_unlock_bh(&dess_nat_lock); + return SW_NOT_FOUND; + } + + HSL_REG_ENTRY_GET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (®[7]), + sizeof (a_uint32_t)); + aos_unlock_bh(&dess_nat_lock); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_IDX, entry->entry_id, reg[7]); + return SW_OK; +} + +static sw_error_t +_dess_ip_host_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_host_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t idx, data, reg[DESS_HOST_ENTRY_REG_NUM] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_NEXT_ENTRY_FIRST_ID == entry->entry_id) + { + idx = DESS_HOST_ENTRY_NUM - 1; + } + else + { + if ((DESS_HOST_ENTRY_NUM - 1) == entry->entry_id) + { + return SW_NO_MORE; + } + else + { + idx = entry->entry_id; + } + } + + SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_IDX, idx, reg[7]); + + if (FAL_IP_ENTRY_INTF_EN & next_mode) + { + rv = _dess_ip_intf_sw_to_hw(dev_id, entry/*was:->intf_id*/, &data); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_VID, 1, reg[7]); + SW_SET_REG_BY_FIELD(HOST_ENTRY5, INTF_ID, data, reg[5]); + } + + if (FAL_IP_ENTRY_PORT_EN & next_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_SP, 1, reg[7]); + SW_SET_REG_BY_FIELD(HOST_ENTRY5, SRC_PORT, entry->port_id, reg[5]); + } + + if (FAL_IP_ENTRY_STATUS_EN & next_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_STATUS, 1, reg[7]); + SW_SET_REG_BY_FIELD(HOST_ENTRY6, AGE_FLAG, entry->status, reg[6]); + } + + SW_SET_REG_BY_FIELD(HOST_ENTRY6, VRF_ID, entry->vrf_id, reg[6]); + aos_lock_bh(&dess_nat_lock); + rv = _dess_host_down_to_hw(dev_id, reg); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + rv = _dess_host_entry_commit(dev_id, DESS_ENTRY_ARP, DESS_HOST_ENTRY_NEXT); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + rv = _dess_host_up_to_sw(dev_id, reg); + aos_unlock_bh(&dess_nat_lock); + SW_RTN_ON_ERROR(rv); + + aos_mem_zero(entry, sizeof (fal_host_entry_t)); + + rv = _dess_host_hw_to_sw(dev_id, reg, entry); + SW_RTN_ON_ERROR(rv); + + if (!(entry->status)) + { + return SW_NO_MORE; + } + + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_IDX, entry->entry_id, reg[7]); + return SW_OK; +} + +static sw_error_t +_dess_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; + a_uint32_t reg[DESS_HOST_ENTRY_REG_NUM] = { 0 }, tbl[DESS_HOST_ENTRY_REG_NUM] = { 0 }, tbl_idx; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + tbl_idx = (entry_id - 1) & 0x7f; + SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_IDX, tbl_idx, reg[7]); + + rv = _dess_host_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _dess_host_entry_commit(dev_id, DESS_ENTRY_ARP, DESS_HOST_ENTRY_NEXT); + if (SW_OK != rv) + { + return SW_NOT_FOUND; + } + + rv = _dess_host_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_IDX, tbl_idx, reg[7]); + if (entry_id != tbl_idx) + { + return SW_NOT_FOUND; + } + + tbl[0] = reg[0]; + tbl[1] = reg[1]; + tbl[2] = reg[2]; + tbl[3] = reg[3]; + tbl[6] = (reg[6] >> 15) << 15; + rv = _dess_host_down_to_hw(dev_id, tbl); + SW_RTN_ON_ERROR(rv); + + rv = _dess_host_entry_commit(dev_id, DESS_ENTRY_ARP, DESS_HOST_ENTRY_DEL); + SW_RTN_ON_ERROR(rv); + + if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY6, CNT_EN, 0, reg[6]); + } + else if (A_TRUE == enable) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY6, CNT_EN, 1, reg[6]); + SW_SET_REG_BY_FIELD(HOST_ENTRY6, CNT_IDX, cnt_id, reg[6]); + } + else + { + return SW_BAD_PARAM; + } + + reg[7] = 0x0; + rv = _dess_host_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _dess_host_entry_commit(dev_id, DESS_ENTRY_ARP, DESS_HOST_ENTRY_ADD); + return rv; +} + +static sw_error_t +_dess_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; + a_uint32_t reg[DESS_HOST_ENTRY_REG_NUM] = { 0 }, tbl[DESS_HOST_ENTRY_REG_NUM] = { 0 }, tbl_idx; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + tbl_idx = (entry_id - 1) & 0x7f; + SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_IDX, tbl_idx, reg[7]); + aos_lock_bh(&dess_nat_lock); + rv = _dess_host_down_to_hw(dev_id, reg); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + rv = _dess_host_entry_commit(dev_id, DESS_ENTRY_ARP, DESS_HOST_ENTRY_NEXT); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + rv = _dess_host_up_to_sw(dev_id, reg); + aos_unlock_bh(&dess_nat_lock); + if (SW_OK != rv) + { + return SW_NOT_FOUND; + } + + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_IDX, tbl_idx, reg[7]); + if (entry_id != tbl_idx) + { + return SW_NOT_FOUND; + } + + if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY6, PPPOE_EN, 0, reg[6]); + } + else if (A_TRUE == enable) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY6, PPPOE_EN, 1, reg[6]); + SW_SET_REG_BY_FIELD(HOST_ENTRY6, PPPOE_IDX, pppoe_id, reg[6]); + } + else + { + return SW_BAD_PARAM; + } + + tbl[0] = reg[0]; + tbl[1] = reg[1]; + tbl[2] = reg[2]; + tbl[3] = reg[3]; + tbl[6] = (reg[6] >> 15) << 15; + aos_lock_bh(&dess_nat_lock); + rv = _dess_host_down_to_hw(dev_id, tbl); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + rv = _dess_host_entry_commit(dev_id, DESS_ENTRY_ARP, DESS_HOST_ENTRY_DEL); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + reg[7] = 0x0; + rv = _dess_host_down_to_hw(dev_id, reg); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + rv = _dess_host_entry_commit(dev_id, DESS_ENTRY_ARP, DESS_HOST_ENTRY_ADD); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + rv = _dess_host_up_to_sw(dev_id, reg); + aos_unlock_bh(&dess_nat_lock); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +static sw_error_t +_dess_ip_pt_arp_learn_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t flags) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_PTCTRL2, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_ARP_LEARN_REQ & flags) + { + data |= (0x1 << port_id); + } + else + { + data &= (~(0x1 << port_id)); + } + + if (FAL_ARP_LEARN_ACK & flags) + { + data |= (0x1 << (ROUTER_PTCTRL2_ARP_LEARN_ACK_BOFFSET + port_id)); + } + else + { + data &= (~(0x1 << (ROUTER_PTCTRL2_ARP_LEARN_ACK_BOFFSET + port_id))); + } + + HSL_REG_ENTRY_SET(rv, dev_id, ROUTER_PTCTRL2, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_ip_pt_arp_learn_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * flags) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + *flags = 0; + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_PTCTRL2, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data & (0x1 << port_id)) + { + *flags |= FAL_ARP_LEARN_REQ; + } + + if (data & (0x1 << (ROUTER_PTCTRL2_ARP_LEARN_ACK_BOFFSET + port_id))) + { + *flags |= FAL_ARP_LEARN_ACK; + } + + return SW_OK; +} + +static sw_error_t +_dess_ip_arp_learn_set(a_uint32_t dev_id, fal_arp_learn_mode_t mode) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_ARP_LEARN_ALL == mode) + { + data = 1; + } + else if (FAL_ARP_LEARN_LOCAL == mode) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, ROUTER_CTRL, 0, ARP_LEARN_MODE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_ip_arp_learn_get(a_uint32_t dev_id, fal_arp_learn_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, ROUTER_CTRL, 0, ARP_LEARN_MODE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data) + { + *mode = FAL_ARP_LEARN_ALL; + } + else + { + *mode = FAL_ARP_LEARN_LOCAL; + } + + return SW_OK; +} + +static sw_error_t +_dess_ip_source_guard_set(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t mode) +{ + sw_error_t rv; + a_uint32_t reg = 0, data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_PTCTRL1, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_NO_SOURCE_GUARD < mode) + { + return SW_BAD_PARAM; + } + + data = 0; + if (FAL_MAC_IP_GUARD == mode) + { + data = 1; + } + else if (FAL_MAC_IP_PORT_GUARD == mode) + { + data = 2; + } + else if (FAL_MAC_IP_VLAN_GUARD == mode) + { + data = 3; + } + else if (FAL_MAC_IP_PORT_VLAN_GUARD == mode) + { + data = 4; + } + reg &= (~(0x7 << (port_id * 3))); + reg |= ((data & 0x7) << (port_id * 3)); + + HSL_REG_ENTRY_SET(rv, dev_id, ROUTER_PTCTRL1, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data = 1; + if (FAL_NO_SOURCE_GUARD == mode) + { + data = 0; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN1, port_id, SP_CHECK_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_ip_source_guard_get(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t reg = 0, data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_PTCTRL1, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data = (reg >> (port_id * 3)) & 0x7; + + *mode = FAL_NO_SOURCE_GUARD; + if (1 == data) + { + *mode = FAL_MAC_IP_GUARD; + } + else if (2 == data) + { + *mode = FAL_MAC_IP_PORT_GUARD; + } + else if (3 == data) + { + *mode = FAL_MAC_IP_VLAN_GUARD; + } + else if (4 == data) + { + *mode = FAL_MAC_IP_PORT_VLAN_GUARD; + } + + return SW_OK; +} + +static sw_error_t +_dess_ip_unk_source_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_MAC_FRWRD == cmd) + { + data = 0; + } + else if (FAL_MAC_DROP == cmd) + { + data = 1; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + data = 2; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, IP_NOT_FOUND, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_ip_unk_source_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, IP_NOT_FOUND, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0 == data) + { + *cmd = FAL_MAC_FRWRD; + } + else if (1 == data) + { + *cmd = FAL_MAC_DROP; + } + else + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + + return SW_OK; +} + +static sw_error_t +_dess_ip_arp_guard_set(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t mode) +{ + sw_error_t rv; + a_uint32_t reg = 0, data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_PTCTRL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_NO_SOURCE_GUARD < mode) + { + return SW_BAD_PARAM; + } + + data = 0; + if (FAL_MAC_IP_GUARD == mode) + { + data = 1; + } + else if (FAL_MAC_IP_PORT_GUARD == mode) + { + data = 2; + } + else if (FAL_MAC_IP_VLAN_GUARD == mode) + { + data = 3; + } + else if (FAL_MAC_IP_PORT_VLAN_GUARD == mode) + { + data = 4; + } + reg &= (~(0x7 << (port_id * 3))); + reg |= ((data & 0x7) << (port_id * 3)); + + HSL_REG_ENTRY_SET(rv, dev_id, ROUTER_PTCTRL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_ip_arp_guard_get(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t reg = 0, data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_PTCTRL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data = (reg >> (port_id * 3)) & 0x7; + + *mode = FAL_NO_SOURCE_GUARD; + if (1 == data) + { + *mode = FAL_MAC_IP_GUARD; + } + else if (2 == data) + { + *mode = FAL_MAC_IP_PORT_GUARD; + } + else if (3 == data) + { + *mode = FAL_MAC_IP_VLAN_GUARD; + } + else if (4 == data) + { + *mode = FAL_MAC_IP_PORT_VLAN_GUARD; + } + + return SW_OK; +} + +static sw_error_t +_dess_arp_unk_source_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_MAC_FRWRD == cmd) + { + data = 0; + } + else if (FAL_MAC_DROP == cmd) + { + data = 1; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + data = 2; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, ARP_NOT_FOUND, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_arp_unk_source_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, ARP_NOT_FOUND, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0 == data) + { + *cmd = FAL_MAC_FRWRD; + } + else if (1 == data) + { + *cmd = FAL_MAC_DROP; + } + else + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + + return SW_OK; +} + +static sw_error_t +_dess_ip_route_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, ROUTER_CTRL, 0, ROUTER_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, MOD_ENABLE, 0, L3_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_ip_route_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t route_en = 0, l3_en = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, ROUTER_CTRL, 0, ROUTER_EN, + (a_uint8_t *) (&route_en), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, MOD_ENABLE, 0, L3_EN, + (a_uint8_t *) (&l3_en), sizeof (a_uint32_t)) + SW_RTN_ON_ERROR(rv); + + if (route_en && l3_en) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return rv; +} + +static sw_error_t +_dess_ip_intf_entry_add(a_uint32_t dev_id, fal_intf_mac_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t i, j, found = 0, addr, tbl[3] = { 0 }; + fal_intf_mac_entry_t * intf_entry = NULL; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + for (i = 0; i < DESS_INTF_MAC_ADDR_NUM; i++) + { + if (dess_mac_snap[dev_id] & (0x1 << i)) + { + intf_entry = &(dess_intf_snap[dev_id][i]); + if ((entry->vid_low == intf_entry->vid_low) + && (entry->vid_high == intf_entry->vid_high)) + { + /* all same, return OK directly */ + if (!aos_mem_cmp(intf_entry, entry, sizeof(fal_intf_mac_entry_t))) + { + return SW_OK; + } + else + { + /* update entry */ + found = 1; + break; + } + } + else + { + /* entry VID cross border, not support */ + if ((entry->vid_low >= intf_entry->vid_low) && (entry->vid_low <= intf_entry->vid_high)) + { + return SW_BAD_PARAM; + } + + /* entry VID cross border, not support */ + if ((entry->vid_high >= intf_entry->vid_low) && (entry->vid_low <= intf_entry->vid_high)) + { + return SW_BAD_PARAM; + } + } + } + } + + if (!found) + { + for (i = 0; i < DESS_INTF_MAC_ADDR_NUM; i++) + { + if (!(dess_mac_snap[dev_id] & (0x1 << i))) + { + intf_entry = &(dess_intf_snap[dev_id][i]); + break; + } + } + } + + if (DESS_INTF_MAC_ADDR_NUM == i) + { + return SW_NO_RESOURCE; + } + + if ((A_FALSE == entry->ip4_route) && (A_FALSE == entry->ip6_route)) + { + return SW_NOT_SUPPORTED; + } + + if (512 <= (entry->vid_high - entry->vid_low)) + { + return SW_BAD_PARAM; + } + + SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY0, MAC_ADDR2, entry->mac_addr.uc[2], + tbl[0]); + SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY0, MAC_ADDR3, entry->mac_addr.uc[3], + tbl[0]); + SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY0, MAC_ADDR4, entry->mac_addr.uc[4], + tbl[0]); + SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY0, MAC_ADDR5, entry->mac_addr.uc[5], + tbl[0]); + SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY1, MAC_ADDR0, entry->mac_addr.uc[0], + tbl[1]); + SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY1, MAC_ADDR1, entry->mac_addr.uc[1], + tbl[1]); + + SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY1, VID_LOW, entry->vid_low, tbl[1]); + SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY1, VID_HIGH0, (entry->vid_high & 0xf), + tbl[1]); + SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY2, VID_HIGH1, (entry->vid_high >> 4), + tbl[2]); + + if (A_TRUE == entry->ip4_route) + { + SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY2, IP4_ROUTE, 1, tbl[2]); + } + + if (A_TRUE == entry->ip6_route) + { + SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY2, IP6_ROUTE, 1, tbl[2]); + } + + SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY2, VRF_ID, entry->vrf_id, tbl[2]); + + for (j = 0; j < 2; j++) + { + addr = DESS_INTF_MAC_EDIT0_ADDR + (i << 4) + (j << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[j])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + for (j = 0; j < 3; j++) + { + addr = DESS_INTF_MAC_TBL0_ADDR + (i << 4) + (j << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[j])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + dess_mac_snap[dev_id] |= (0x1 << i); + *intf_entry = *entry; + entry->entry_id = i; + return SW_OK; +} + +static sw_error_t +_dess_ip_intf_entry_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_intf_mac_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t addr, tbl[3] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (!(FAL_IP_ENTRY_ID_EN & del_mode)) + { + return SW_NOT_SUPPORTED; + } + + if (DESS_INTF_MAC_ADDR_NUM <= entry->entry_id) + { + return SW_BAD_PARAM; + } + + /* clear valid bits */ + addr = DESS_INTF_MAC_TBL2_ADDR + (entry->entry_id << 4); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[2])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + dess_mac_snap[dev_id] &= (~(0x1 << entry->entry_id)); + return SW_OK; +} + +static sw_error_t +_dess_ip_intf_entry_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_intf_mac_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t i, j, idx, addr, tbl[3] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_NEXT_ENTRY_FIRST_ID == entry->entry_id) + { + idx = 0; + } + else + { + if ((DESS_INTF_MAC_ADDR_NUM - 1) == entry->entry_id) + { + return SW_NO_MORE; + } + else + { + idx = entry->entry_id + 1; + } + } + + for (i = idx; i < DESS_INTF_MAC_ADDR_NUM; i++) + { + if (dess_mac_snap[dev_id] & (0x1 << i)) + { + break; + } + } + + if (DESS_INTF_MAC_ADDR_NUM == i) + { + return SW_NO_MORE; + } + + for (j = 0; j < 3; j++) + { + addr = DESS_INTF_MAC_TBL0_ADDR + (i << 4) + (j << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[j])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + aos_mem_zero(entry, sizeof (fal_intf_mac_entry_t)); + + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY0, MAC_ADDR2, entry->mac_addr.uc[2], + tbl[0]); + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY0, MAC_ADDR3, entry->mac_addr.uc[3], + tbl[0]); + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY0, MAC_ADDR4, entry->mac_addr.uc[4], + tbl[0]); + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY0, MAC_ADDR5, entry->mac_addr.uc[5], + tbl[0]); + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY1, MAC_ADDR0, entry->mac_addr.uc[0], + tbl[1]); + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY1, MAC_ADDR1, entry->mac_addr.uc[1], + tbl[1]); + + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY1, VID_LOW, entry->vid_low, tbl[1]); + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY1, VID_HIGH0, j, tbl[1]); + entry->vid_high = j & 0xf; + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY2, VID_HIGH1, j, tbl[2]); + entry->vid_high |= ((j & 0xff) << 4); + + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY2, IP4_ROUTE, j, tbl[2]); + if (j) + { + entry->ip4_route = A_TRUE; + } + + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY2, IP6_ROUTE, j, tbl[2]); + if (j) + { + entry->ip6_route = A_TRUE; + } + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY2, VRF_ID, entry->vrf_id, tbl[2]); + + entry->entry_id = i; + return SW_OK; +} + +#define DESS_WCMP_ENTRY_MAX_ID 3 +#define DESS_WCMP_HASH_MAX_NUM 16 +#define DESS_IP_ENTRY_MAX_ID 127 + +#define DESS_WCMP_HASH_TBL_ADDR 0x0e10 +#define DESS_WCMP_NHOP_TBL_ADDR 0x0e20 + +static sw_error_t +_dess_ip_wcmp_entry_set(a_uint32_t dev_id, a_uint32_t wcmp_id, fal_ip_wcmp_t * wcmp) +{ + sw_error_t rv; + a_uint32_t i, j, addr, data; + a_uint8_t idx, ptr[4] = { 0 }, pos[16] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (DESS_WCMP_ENTRY_MAX_ID < wcmp_id) + { + return SW_BAD_PARAM; + } + + if (DESS_WCMP_HASH_MAX_NUM < wcmp->nh_nr) + { + return SW_BAD_PARAM; + } + + for (i = 0; i < wcmp->nh_nr; i++) + { + if (DESS_IP_ENTRY_MAX_ID < wcmp->nh_id[i]) + { + return SW_BAD_PARAM; + } + + idx = 4; + for (j = 0; j < 4; j++) + { + if (ptr[j] & 0x80) + { + if ((ptr[j] & 0x7f) == wcmp->nh_id[i]) + { + idx = j; + break; + } + } + else + { + idx = j; + } + } + + if (4 == idx) + { + return SW_BAD_PARAM; + } + else + { + ptr[idx] = (wcmp->nh_id[i] & 0x7f) | 0x80; + pos[i] = idx; + } + } + + data = 0; + for (j = 0; j < 4; j++) + { + data |= (ptr[j] << (j << 3)); + } + + addr = DESS_WCMP_NHOP_TBL_ADDR + (wcmp_id << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data = 0; + for (j = 0; j < 16; j++) + { + data |= (pos[j] << (j << 1)); + } + + addr = DESS_WCMP_HASH_TBL_ADDR + (wcmp_id << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +static sw_error_t +_dess_ip_wcmp_entry_get(a_uint32_t dev_id, a_uint32_t wcmp_id, fal_ip_wcmp_t * wcmp) +{ + sw_error_t rv; + a_uint32_t i, addr, data = 0; + a_uint8_t ptr[4] = { 0 }, pos[16] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (DESS_WCMP_ENTRY_MAX_ID < wcmp_id) + { + return SW_BAD_PARAM; + } + + wcmp->nh_nr = DESS_WCMP_HASH_MAX_NUM; + + addr = DESS_WCMP_NHOP_TBL_ADDR + (wcmp_id << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + for (i = 0; i < 4; i++) + { + ptr[i] = (data >> (i << 3)) & 0x7f; + } + + addr = DESS_WCMP_HASH_TBL_ADDR + (wcmp_id << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + for (i = 0; i < 16; i++) + { + pos[i] = (data >> (i << 1)) & 0x3; + } + + for (i = 0; i < 16; i++) + { + wcmp->nh_id[i] = ptr[pos[i]]; + } + + return SW_OK; +} + +static sw_error_t +_dess_ip_wcmp_hash_mode_set(a_uint32_t dev_id, a_uint32_t hash_mode) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_CTRL, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_WCMP_HASH_KEY_SIP & hash_mode) + { + SW_SET_REG_BY_FIELD(ROUTER_CTRL, WCMP_HAHS_SIP, 1, data); + } + else + { + SW_SET_REG_BY_FIELD(ROUTER_CTRL, WCMP_HAHS_SIP, 0, data); + } + + if (FAL_WCMP_HASH_KEY_DIP & hash_mode) + { + SW_SET_REG_BY_FIELD(ROUTER_CTRL, WCMP_HAHS_DIP, 1, data); + } + else + { + SW_SET_REG_BY_FIELD(ROUTER_CTRL, WCMP_HAHS_DIP, 0, data); + } + + if (FAL_WCMP_HASH_KEY_SPORT & hash_mode) + { + SW_SET_REG_BY_FIELD(ROUTER_CTRL, WCMP_HAHS_SP, 1, data); + } + else + { + SW_SET_REG_BY_FIELD(ROUTER_CTRL, WCMP_HAHS_SP, 0, data); + } + + if (FAL_WCMP_HASH_KEY_DPORT & hash_mode) + { + SW_SET_REG_BY_FIELD(ROUTER_CTRL, WCMP_HAHS_DP, 1, data); + } + else + { + SW_SET_REG_BY_FIELD(ROUTER_CTRL, WCMP_HAHS_DP, 0, data); + } + + + HSL_REG_ENTRY_SET(rv, dev_id, ROUTER_CTRL, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_ip_wcmp_hash_mode_get(a_uint32_t dev_id, a_uint32_t * hash_mode) +{ + sw_error_t rv; + a_uint32_t data = 0, field; + + *hash_mode = 0; + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_CTRL, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(ROUTER_CTRL, WCMP_HAHS_SIP, field, data); + if (field) + { + *hash_mode |= FAL_WCMP_HASH_KEY_SIP; + } + + SW_GET_FIELD_BY_REG(ROUTER_CTRL, WCMP_HAHS_DIP, field, data); + if (field) + { + *hash_mode |= FAL_WCMP_HASH_KEY_DIP; + } + + SW_GET_FIELD_BY_REG(ROUTER_CTRL, WCMP_HAHS_SP, field, data); + if (field) + { + *hash_mode |= FAL_WCMP_HASH_KEY_SPORT; + } + + SW_GET_FIELD_BY_REG(ROUTER_CTRL, WCMP_HAHS_DP, field, data); + if (field) + { + *hash_mode |= FAL_WCMP_HASH_KEY_DPORT; + } + + return SW_OK; +} + +#define DESS_VRF_ENTRY_MAX_ID 7 + +#define DESS_VRF_ENTRY_TBL_ADDR 0x0484 +#define DESS_VRF_ENTRY_MASK_ADDR 0x0488 + +static sw_error_t +_dess_ip_vrf_base_addr_set(a_uint32_t dev_id, a_uint32_t vrf_id, fal_ip4_addr_t addr) +{ + sw_error_t rv; + a_uint32_t reg_addr; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (DESS_VRF_ENTRY_MAX_ID < vrf_id) + { + return SW_BAD_PARAM; + } + + reg_addr = DESS_VRF_ENTRY_TBL_ADDR + (vrf_id << 3); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, reg_addr, sizeof (a_uint32_t), + (a_uint8_t *) (&addr), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return rv; +} + +static sw_error_t +_dess_ip_vrf_base_addr_get(a_uint32_t dev_id, a_uint32_t vrf_id, fal_ip4_addr_t * addr) +{ + sw_error_t rv; + a_uint32_t reg_addr; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (DESS_VRF_ENTRY_MAX_ID < vrf_id) + { + return SW_BAD_PARAM; + } + + reg_addr = DESS_VRF_ENTRY_TBL_ADDR + (vrf_id << 3); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, reg_addr, sizeof (a_uint32_t), + (a_uint8_t *) (addr), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +static sw_error_t +_dess_ip_vrf_base_mask_set(a_uint32_t dev_id, a_uint32_t vrf_id, fal_ip4_addr_t addr) +{ + sw_error_t rv; + a_uint32_t reg_addr; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (DESS_VRF_ENTRY_MAX_ID < vrf_id) + { + return SW_BAD_PARAM; + } + + reg_addr = DESS_VRF_ENTRY_MASK_ADDR + (vrf_id << 3); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, reg_addr, sizeof (a_uint32_t), + (a_uint8_t *) (&addr), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return rv; +} + +static sw_error_t +_dess_ip_vrf_base_mask_get(a_uint32_t dev_id, a_uint32_t vrf_id, fal_ip4_addr_t * addr) +{ + sw_error_t rv; + a_uint32_t reg_addr; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (DESS_VRF_ENTRY_MAX_ID < vrf_id) + { + return SW_BAD_PARAM; + } + + reg_addr = DESS_VRF_ENTRY_MASK_ADDR + (vrf_id << 3); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, reg_addr, sizeof (a_uint32_t), + (a_uint8_t *) (addr), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +static sw_error_t +_dess_ip_default_route_set(a_uint32_t dev_id, a_uint32_t droute_id, fal_default_route_t * entry) +{ + sw_error_t rv; + a_uint32_t data = 0; + a_uint32_t addr; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (entry->ip_version == FAL_ADDR_IPV4) + { + SW_SET_REG_BY_FIELD(IP4_DEFAULT_ROUTE_ENTRY, VALID, entry->valid, data); + SW_SET_REG_BY_FIELD(IP4_DEFAULT_ROUTE_ENTRY, VRF, entry->vrf_id, data); + SW_SET_REG_BY_FIELD(IP4_DEFAULT_ROUTE_ENTRY, ARP_WCMP_TYPE, entry->droute_type, data); + SW_SET_REG_BY_FIELD(IP4_DEFAULT_ROUTE_ENTRY, ARP_WCMP_INDEX, entry->index, data); + + addr = DESS_IP4_DEFAULT_ROUTE_TBL_ADDR + (droute_id << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else + { + SW_SET_REG_BY_FIELD(IP6_DEFAULT_ROUTE_ENTRY, VALID, entry->valid, data); + SW_SET_REG_BY_FIELD(IP6_DEFAULT_ROUTE_ENTRY, VRF, entry->vrf_id, data); + SW_SET_REG_BY_FIELD(IP6_DEFAULT_ROUTE_ENTRY, ARP_WCMP_TYPE, entry->droute_type, data); + SW_SET_REG_BY_FIELD(IP6_DEFAULT_ROUTE_ENTRY, ARP_WCMP_INDEX, entry->index, data); + + addr = DESS_IP6_DEFAULT_ROUTE_TBL_ADDR + (droute_id << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + + return rv; +} + +static sw_error_t +_dess_ip_default_route_get(a_uint32_t dev_id, a_uint32_t droute_id, fal_default_route_t * entry) +{ + sw_error_t rv; + a_uint32_t data = 0; + a_uint32_t addr; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (entry->ip_version == FAL_ADDR_IPV4) + { + addr = DESS_IP4_DEFAULT_ROUTE_TBL_ADDR + (droute_id << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + + SW_GET_FIELD_BY_REG(IP4_DEFAULT_ROUTE_ENTRY, VALID, entry->valid, data); + SW_GET_FIELD_BY_REG(IP4_DEFAULT_ROUTE_ENTRY, VRF, entry->vrf_id, data); + SW_GET_FIELD_BY_REG(IP4_DEFAULT_ROUTE_ENTRY, ARP_WCMP_TYPE, entry->droute_type, data); + SW_GET_FIELD_BY_REG(IP4_DEFAULT_ROUTE_ENTRY, ARP_WCMP_INDEX, entry->index, data); + } + else + { + addr = DESS_IP6_DEFAULT_ROUTE_TBL_ADDR + (droute_id << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + + SW_GET_FIELD_BY_REG(IP6_DEFAULT_ROUTE_ENTRY, VALID, entry->valid, data); + SW_GET_FIELD_BY_REG(IP6_DEFAULT_ROUTE_ENTRY, VRF, entry->vrf_id, data); + SW_GET_FIELD_BY_REG(IP6_DEFAULT_ROUTE_ENTRY, ARP_WCMP_TYPE, entry->droute_type, data); + SW_GET_FIELD_BY_REG(IP6_DEFAULT_ROUTE_ENTRY, ARP_WCMP_INDEX, entry->index, data); + } + + return SW_OK; +} + +static sw_error_t +_dess_ip_host_route_set(a_uint32_t dev_id, a_uint32_t hroute_id, fal_host_route_t * entry) +{ + sw_error_t rv; + a_uint32_t j, addr, tbl[5] = { 0 }; + a_uint32_t addr0_low, addr0_high, addr1_low, addr1_high, + addr2_low, addr2_high, addr3_low, addr3_high; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (entry->ip_version == FAL_ADDR_IPV4) + { + addr0_low = entry->route_addr.ip4_addr & 0x7ffffff; + addr0_high = entry->route_addr.ip4_addr >> 27; + SW_SET_REG_BY_FIELD(IP4_HOST_ROUTE_ENTRY0, PREFIX_LENGTH, entry->prefix_length, + tbl[0]); + SW_SET_REG_BY_FIELD(IP4_HOST_ROUTE_ENTRY0, IP4_ADDRL, addr0_low, tbl[0]); + SW_SET_REG_BY_FIELD(IP4_HOST_ROUTE_ENTRY1, IP4_ADDRH, addr0_high, tbl[1]); + SW_SET_REG_BY_FIELD(IP4_HOST_ROUTE_ENTRY1, VALID, entry->valid, + tbl[1]); + SW_SET_REG_BY_FIELD(IP4_HOST_ROUTE_ENTRY1, VRF, entry->vrf_id, + tbl[1]); + for (j = 0; j < 2; j++) + { + addr = DESS_IP4_HOST_ROUTE_TBL0_ADDR + (hroute_id << 4) + (j << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[j])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + } + else + { + addr0_low = entry->route_addr.ip6_addr.ul[3] & 0x1ffffff; + addr0_high = (entry->route_addr.ip6_addr.ul[3] >> 25) & 0x7f; + addr1_low = entry->route_addr.ip6_addr.ul[2] & 0x1ffffff; + addr1_high = (entry->route_addr.ip6_addr.ul[2] >> 25) & 0x7f; + addr2_low = entry->route_addr.ip6_addr.ul[1] & 0x1ffffff; + addr2_high = (entry->route_addr.ip6_addr.ul[1] >> 25) & 0x7f; + addr3_low = entry->route_addr.ip6_addr.ul[0] & 0x1ffffff; + addr3_high = (entry->route_addr.ip6_addr.ul[0] >> 25) & 0x7f; + + SW_SET_REG_BY_FIELD(IP6_HOST_ROUTE_ENTRY0, IP6_ADDR0L, addr0_low, tbl[0]); + SW_SET_REG_BY_FIELD(IP6_HOST_ROUTE_ENTRY0, PREFIX_LENGTH, entry->prefix_length, tbl[0]); + + SW_SET_REG_BY_FIELD(IP6_HOST_ROUTE_ENTRY1, IP6_ADDR1L, addr1_low, tbl[1]); + SW_SET_REG_BY_FIELD(IP6_HOST_ROUTE_ENTRY1, IP6_ADDR0H, addr0_high, tbl[1]); + + SW_SET_REG_BY_FIELD(IP6_HOST_ROUTE_ENTRY2, IP6_ADDR2L, addr2_low, tbl[2]); + SW_SET_REG_BY_FIELD(IP6_HOST_ROUTE_ENTRY2, IP6_ADDR1H, addr1_high, tbl[2]); + + SW_SET_REG_BY_FIELD(IP6_HOST_ROUTE_ENTRY3, IP6_ADDR3L, addr3_low, tbl[3]); + SW_SET_REG_BY_FIELD(IP6_HOST_ROUTE_ENTRY3, IP6_ADDR2H, addr2_high, tbl[3]); + + SW_SET_REG_BY_FIELD(IP6_HOST_ROUTE_ENTRY4, VALID, entry->valid, tbl[4]); + SW_SET_REG_BY_FIELD(IP6_HOST_ROUTE_ENTRY4, VRF, entry->vrf_id, tbl[4]); + SW_SET_REG_BY_FIELD(IP6_HOST_ROUTE_ENTRY4, IP6_ADDR3H, addr3_high, tbl[4]); + + for (j = 0; j < 5; j++) + { + addr = DESS_IP6_HOST_ROUTE_TBL0_ADDR + (hroute_id << 5) + (j << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[j])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + } + + return SW_OK; +} + +static sw_error_t +_dess_ip_host_route_get(a_uint32_t dev_id, a_uint32_t hroute_id, fal_host_route_t * entry) +{ + sw_error_t rv; + a_uint32_t j, addr, tbl[5] = { 0 }; + a_uint32_t addr0_low, addr0_high, addr1_low, addr1_high, + addr2_low, addr2_high, addr3_low, addr3_high; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (entry->ip_version == FAL_ADDR_IPV4) + { + for (j = 0; j < 2; j++) + { + addr = DESS_IP4_HOST_ROUTE_TBL0_ADDR + (hroute_id << 4) + (j << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[j])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + SW_GET_FIELD_BY_REG(IP4_HOST_ROUTE_ENTRY0, PREFIX_LENGTH, entry->prefix_length, + tbl[0]); + SW_GET_FIELD_BY_REG(IP4_HOST_ROUTE_ENTRY0, IP4_ADDRL, addr0_low, + tbl[0]); + SW_GET_FIELD_BY_REG(IP4_HOST_ROUTE_ENTRY1, IP4_ADDRH, addr0_high, + tbl[1]); + SW_GET_FIELD_BY_REG(IP4_HOST_ROUTE_ENTRY1, VALID, entry->valid, + tbl[1]); + SW_GET_FIELD_BY_REG(IP4_HOST_ROUTE_ENTRY1, VRF, entry->vrf_id, + tbl[1]); + entry->route_addr.ip4_addr = addr0_low | (addr0_high << 27); + } + else + { + for (j = 0; j < 5; j++) + { + addr = DESS_IP6_HOST_ROUTE_TBL0_ADDR + (hroute_id << 5) + (j << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[j])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + SW_GET_FIELD_BY_REG(IP6_HOST_ROUTE_ENTRY0, IP6_ADDR0L, addr0_low, tbl[0]); + SW_GET_FIELD_BY_REG(IP6_HOST_ROUTE_ENTRY0, PREFIX_LENGTH, entry->prefix_length, tbl[0]); + SW_GET_FIELD_BY_REG(IP6_HOST_ROUTE_ENTRY1, IP6_ADDR1L, addr1_low, tbl[1]); + SW_GET_FIELD_BY_REG(IP6_HOST_ROUTE_ENTRY1, IP6_ADDR0H, addr0_high, tbl[1]); + SW_GET_FIELD_BY_REG(IP6_HOST_ROUTE_ENTRY2, IP6_ADDR2L, addr2_low, tbl[2]); + SW_GET_FIELD_BY_REG(IP6_HOST_ROUTE_ENTRY2, IP6_ADDR1H, addr1_high, tbl[2]); + SW_GET_FIELD_BY_REG(IP6_HOST_ROUTE_ENTRY3, IP6_ADDR3L, addr3_low, tbl[3]); + SW_GET_FIELD_BY_REG(IP6_HOST_ROUTE_ENTRY3, IP6_ADDR2H, addr2_high, tbl[3]); + SW_GET_FIELD_BY_REG(IP6_HOST_ROUTE_ENTRY4, VRF, entry->vrf_id, tbl[4]); + SW_GET_FIELD_BY_REG(IP6_HOST_ROUTE_ENTRY4, IP6_ADDR3H, addr3_high, tbl[4]); + SW_GET_FIELD_BY_REG(IP6_HOST_ROUTE_ENTRY4, VALID, entry->valid, tbl[4]); + entry->route_addr.ip6_addr.ul[3] = (addr0_high << 25) | addr0_low; + entry->route_addr.ip6_addr.ul[2] = (addr1_high << 25) | addr1_low; + entry->route_addr.ip6_addr.ul[1] = (addr2_high << 25) | addr2_low; + entry->route_addr.ip6_addr.ul[0] = (addr3_high << 25) | addr3_low; + } + + return SW_OK; +} + +#define RFS_ADD_OP 1 +#define RFS_DEL_OP 2 +static sw_error_t +_dess_ip_rfs_ip4_update( + a_uint32_t dev_id, + fal_host_entry_t *entry, + fal_ip4_rfs_t * rfs, + char op) +{ + fal_host_entry_t tmp = *entry; + + _dess_ip_host_del(dev_id, FAL_IP_ENTRY_IPADDR_EN, entry); + if(RFS_ADD_OP == op) { + tmp.lb_num = rfs->load_balance | 0x4; + tmp.status = 0x7; + } + else { + tmp.lb_num = 0; + tmp.status = 0x6; + } + return _dess_ip_host_add(dev_id, &tmp); +} + +static sw_error_t +_dess_ip_rfs_ip6_update( + a_uint32_t dev_id, + fal_host_entry_t *entry, + fal_ip6_rfs_t * rfs, + char op) +{ + fal_host_entry_t tmp = *entry; + + _dess_ip_host_del(dev_id, FAL_IP_ENTRY_IPADDR_EN, entry); + if(RFS_ADD_OP == op) { + tmp.lb_num = rfs->load_balance | 0x4; + tmp.status = 0x7; + } + else { + tmp.lb_num = 0; + tmp.status = 0x6; + } + return _dess_ip_host_add(dev_id, &tmp); +} + +static sw_error_t +_dess_ip_rfs_ip4_set(a_uint32_t dev_id, fal_ip4_rfs_t * rfs) +{ + fal_host_entry_t entry; + + memset(&entry, 0, sizeof(entry)); + entry.flags = FAL_IP_IP4_ADDR; + entry.ip4_addr = rfs->ip4_addr; + if(SW_OK == _dess_ip_host_get(dev_id, 0x10, &entry)) { + return _dess_ip_rfs_ip4_update(dev_id, &entry, rfs, RFS_ADD_OP); + } + /*add a new one*/ + entry.status = 0x7; + entry.flags = FAL_IP_IP4_ADDR; + entry.ip4_addr = rfs->ip4_addr; + memcpy(&entry.mac_addr, &rfs->mac_addr, 6); + entry.intf_id = rfs->vid; + entry.port_id = 0; + entry.lb_num = rfs->load_balance | 0x4; + entry.action = FAL_MAC_RDT_TO_CPU; + return _dess_ip_host_add(dev_id, &entry); +} + +static sw_error_t +_dess_ip_rfs_ip6_set(a_uint32_t dev_id, fal_ip6_rfs_t * rfs) +{ + fal_host_entry_t entry; + + memset(&entry, 0, sizeof(entry)); + entry.flags = FAL_IP_IP6_ADDR; + entry.ip6_addr = rfs->ip6_addr; + if(SW_OK == _dess_ip_host_get(dev_id, 0x10, &entry)) { + return _dess_ip_rfs_ip6_update(dev_id, &entry, rfs, RFS_ADD_OP); + } + /*add a new one*/ + entry.status = 0x7; + entry.flags = FAL_IP_IP6_ADDR; + entry.ip6_addr = rfs->ip6_addr; + memcpy(&entry.mac_addr, &rfs->mac_addr, 6); + entry.intf_id = rfs->vid; + entry.port_id = 0; + entry.lb_num = rfs->load_balance | 0x4; + entry.action = FAL_MAC_RDT_TO_CPU; + return _dess_ip_host_add(dev_id, &entry); +} + +static sw_error_t +_dess_ip_rfs_ip4_del(a_uint32_t dev_id, fal_ip4_rfs_t * rfs) +{ + fal_host_entry_t entry; + sw_error_t ret; + + memset(&entry, 0, sizeof(entry)); + entry.flags = FAL_IP_IP4_ADDR; + entry.ip4_addr = rfs->ip4_addr; + if(SW_OK == (ret = _dess_ip_host_get(dev_id, 0x10, &entry))) { + return _dess_ip_rfs_ip4_update(dev_id, &entry, rfs, RFS_DEL_OP); + } + return ret; +} + +static sw_error_t +_dess_ip_rfs_ip6_del(a_uint32_t dev_id, fal_ip6_rfs_t * rfs) +{ + fal_host_entry_t entry; + sw_error_t ret; + + memset(&entry, 0, sizeof(entry)); + entry.flags = FAL_IP_IP6_ADDR; + entry.ip6_addr = rfs->ip6_addr; + if(SW_OK == (ret = _dess_ip_host_get(dev_id, 0x10, &entry))) { + return _dess_ip_rfs_ip6_update(dev_id, &entry, rfs, RFS_DEL_OP); + } + return ret; +} + +static sw_error_t +_dess_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; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_DEFAULT_FLOW_FORWARD == cmd) + { + data = 0; + } + else if (FAL_DEFAULT_FLOW_DROP == cmd) + { + data = 1; + } + else if (FAL_DEFAULT_FLOW_RDT_TO_CPU == cmd) + { + data = 2; + } + else if (FAL_DEFAULT_FLOW_ADMIT_ALL == cmd) + { + data = 3; + } + else + { + return SW_NOT_SUPPORTED; + } + + if (FAL_FLOW_LAN_TO_LAN == type) + { + HSL_REG_FIELD_SET(rv, dev_id, FlOW_CMD_CTL, vrf_id, LAN_2_LAN_DEFAULT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else if (FAL_FLOW_WAN_TO_LAN == type) + { + HSL_REG_FIELD_SET(rv, dev_id, FlOW_CMD_CTL, vrf_id, WAN_2_LAN_DEFAULT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else if (FAL_FLOW_LAN_TO_WAN == type) + { + HSL_REG_FIELD_SET(rv, dev_id, FlOW_CMD_CTL, vrf_id, LAN_2_WAN_DEFAULT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else if (FAL_FLOW_WAN_TO_WAN == type) + { + HSL_REG_FIELD_SET(rv, dev_id, FlOW_CMD_CTL, vrf_id, WAN_2_WAN_DEFAULT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else + { + return SW_NOT_SUPPORTED; + } + + return rv; +} + +static sw_error_t +_dess_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; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_FLOW_LAN_TO_LAN == type) + { + HSL_REG_FIELD_GET(rv, dev_id, FlOW_CMD_CTL, vrf_id, LAN_2_LAN_DEFAULT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else if (FAL_FLOW_WAN_TO_LAN == type) + { + HSL_REG_FIELD_GET(rv, dev_id, FlOW_CMD_CTL, vrf_id, WAN_2_LAN_DEFAULT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else if (FAL_FLOW_LAN_TO_WAN == type) + { + HSL_REG_FIELD_GET(rv, dev_id, FlOW_CMD_CTL, vrf_id, LAN_2_WAN_DEFAULT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else if (FAL_FLOW_WAN_TO_WAN == type) + { + HSL_REG_FIELD_GET(rv, dev_id, FlOW_CMD_CTL, vrf_id, WAN_2_WAN_DEFAULT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else + { + return SW_NOT_SUPPORTED; + } + SW_RTN_ON_ERROR(rv); + + if (0 == data) + { + *cmd = FAL_DEFAULT_FLOW_FORWARD; + } + else if (1 == data) + { + *cmd = FAL_DEFAULT_FLOW_DROP; + } + else if (2 == data) + { + *cmd = FAL_DEFAULT_FLOW_RDT_TO_CPU; + } + else if (3 == data) + { + *cmd = FAL_DEFAULT_FLOW_ADMIT_ALL; + } + + return SW_OK; +} + +static sw_error_t +_dess_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; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_DEFAULT_FLOW_FORWARD == cmd) + { + data = 0; + } + else if (FAL_DEFAULT_FLOW_DROP == cmd) + { + data = 1; + } + else if (FAL_DEFAULT_FLOW_RDT_TO_CPU == cmd) + { + data = 2; + } + else if (FAL_DEFAULT_FLOW_ADMIT_ALL == cmd) + { + data = 3; + } + else + { + return SW_NOT_SUPPORTED; + } + + if (FAL_FLOW_LAN_TO_LAN == type) + { + HSL_REG_FIELD_SET(rv, dev_id, FlOW_RT_CMD_CTL, vrf_id, LAN_2_LAN_DEFAULT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else if (FAL_FLOW_WAN_TO_LAN == type) + { + HSL_REG_FIELD_SET(rv, dev_id, FlOW_RT_CMD_CTL, vrf_id, WAN_2_LAN_DEFAULT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else if (FAL_FLOW_LAN_TO_WAN == type) + { + HSL_REG_FIELD_SET(rv, dev_id, FlOW_RT_CMD_CTL, vrf_id, LAN_2_WAN_DEFAULT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else if (FAL_FLOW_WAN_TO_WAN == type) + { + HSL_REG_FIELD_SET(rv, dev_id, FlOW_RT_CMD_CTL, vrf_id, WAN_2_WAN_DEFAULT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else + { + return SW_NOT_SUPPORTED; + } + + return rv; +} + +static sw_error_t +_dess_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; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_FLOW_LAN_TO_LAN == type) + { + HSL_REG_FIELD_GET(rv, dev_id, FlOW_RT_CMD_CTL, vrf_id, LAN_2_LAN_DEFAULT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else if (FAL_FLOW_WAN_TO_LAN == type) + { + HSL_REG_FIELD_GET(rv, dev_id, FlOW_RT_CMD_CTL, vrf_id, WAN_2_LAN_DEFAULT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else if (FAL_FLOW_LAN_TO_WAN == type) + { + HSL_REG_FIELD_GET(rv, dev_id, FlOW_RT_CMD_CTL, vrf_id, LAN_2_WAN_DEFAULT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else if (FAL_FLOW_WAN_TO_WAN == type) + { + HSL_REG_FIELD_GET(rv, dev_id, FlOW_RT_CMD_CTL, vrf_id, WAN_2_WAN_DEFAULT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else + { + return SW_NOT_SUPPORTED; + } + SW_RTN_ON_ERROR(rv); + + if (0 == data) + { + *cmd = FAL_DEFAULT_FLOW_FORWARD; + } + else if (1 == data) + { + *cmd = FAL_DEFAULT_FLOW_DROP; + } + else if (2 == data) + { + *cmd = FAL_DEFAULT_FLOW_RDT_TO_CPU; + } + else if (3 == data) + { + *cmd = FAL_DEFAULT_FLOW_ADMIT_ALL; + } + + return SW_OK; +} + +static sw_error_t +_dess_ip_glb_lock_time_set(a_uint32_t dev_id, fal_glb_lock_time_t lock_time) +{ + sw_error_t rv; + a_uint32_t data = lock_time; + + HSL_REG_FIELD_SET(rv, dev_id, ROUTER_CTRL, 0, GLB_LOCKTIME, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +sw_error_t +dess_ip_reset(a_uint32_t dev_id) +{ + sw_error_t rv; + a_uint32_t i, addr, data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = _dess_host_entry_commit(dev_id, DESS_ENTRY_ARP, DESS_HOST_ENTRY_FLUSH); + SW_RTN_ON_ERROR(rv); + + dess_mac_snap[dev_id] = 0; + for (i = 0; i < DESS_INTF_MAC_ADDR_NUM; i++) + { + addr = DESS_INTF_MAC_TBL2_ADDR + (i << 4); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +/** + * @brief Add one host entry to one particular device. + * @details Comments: + * For ISIS the intf_id parameter in host_entry means vlan id. + Before host entry added related interface entry and ip6 base address + must be set at first. + Hardware entry id will be returned. + * @param[in] dev_id device id + * @param[in] host_entry host entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_host_add(a_uint32_t dev_id, fal_host_entry_t * host_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_host_add(dev_id, host_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete one host entry from one particular device. + * @details Comments: + * For ISIS the intf_id parameter in host_entry means vlan id. + Before host entry deleted related interface entry and ip6 base address + must be set atfirst. + For del_mode please refer IP entry operation flags. + * @param[in] dev_id device id + * @param[in] del_mode delete operation mode + * @param[in] host_entry host entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_host_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_host_entry_t * host_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_host_del(dev_id, del_mode, host_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get one host entry from one particular device. + * @details Comments: + * For ISIS the intf_id parameter in host_entry means vlan id. + Before host entry deleted related interface entry and ip6 base address + must be set atfirst. + For get_mode please refer IP entry operation flags. + * @param[in] dev_id device id + * @param[in] get_mode get operation mode + * @param[out] host_entry host entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_host_get(a_uint32_t dev_id, a_uint32_t get_mode, + fal_host_entry_t * host_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_host_get(dev_id, get_mode, host_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Next one host entry from one particular device. + * @details Comments: + * For ISIS the intf_id parameter in host_entry means vlan id. + Before host entry deleted related interface entry and ip6 base address + must be set atfirst. + For next_mode please refer IP entry operation flags. + For get the first entry please set entry id as FAL_NEXT_ENTRY_FIRST_ID + * @param[in] dev_id device id + * @param[in] next_mode next operation mode + * @param[out] host_entry host entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_host_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_host_entry_t * host_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_host_next(dev_id, next_mode, host_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Bind one counter entry to one host entry on one particular device. + * @param[in] dev_id device id + * @param[in] entry_id host entry id + * @param[in] cnt_id counter entry id + * @param[in] enable A_TRUE means bind, A_FALSE means unbind + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_ip_host_counter_bind(dev_id, entry_id, cnt_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Bind one pppoe session entry to one host entry on one particular device. + * @param[in] dev_id device id + * @param[in] entry_id host entry id + * @param[in] pppoe_id pppoe session entry id + * @param[in] enable A_TRUE means bind, A_FALSE means unbind + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_ip_host_pppoe_bind(dev_id, entry_id, pppoe_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set arp packets type to learn on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] flags arp type FAL_ARP_LEARN_REQ and/or FAL_ARP_LEARN_ACK + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_pt_arp_learn_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t flags) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_pt_arp_learn_set(dev_id, port_id, flags); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp packets type to learn on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] flags arp type FAL_ARP_LEARN_REQ and/or FAL_ARP_LEARN_ACK + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_pt_arp_learn_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * flags) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_pt_arp_learn_get(dev_id, port_id, flags); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set arp packets type to learn on one particular device. + * @param[in] dev_id device id + * @param[in] mode learning mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_arp_learn_set(a_uint32_t dev_id, fal_arp_learn_mode_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_arp_learn_set(dev_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp packets type to learn on one particular device. + * @param[in] dev_id device id + * @param[out] mode learning mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_arp_learn_get(a_uint32_t dev_id, fal_arp_learn_mode_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_arp_learn_get(dev_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set ip packets source guarding mode on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode source guarding mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_source_guard_set(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_source_guard_set(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get ip packets source guarding mode on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mode source guarding mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_source_guard_get(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_source_guard_get(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set unkonw source ip packets forwarding command on one particular device. + * @details Comments: + * This settin is no meaning when ip source guard not enable + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_unk_source_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_unk_source_cmd_set(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get unkonw source ip packets forwarding command on one particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_unk_source_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_unk_source_cmd_get(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set arp packets source guarding mode on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode source guarding mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_arp_guard_set(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_arp_guard_set(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp packets source guarding mode on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mode source guarding mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_arp_guard_get(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_arp_guard_get(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set unkonw source arp packets forwarding command on one particular device. + * @details Comments: + * This settin is no meaning when arp source guard not enable + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_arp_unk_source_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_arp_unk_source_cmd_set(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get unkonw source arp packets forwarding command on one particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_arp_unk_source_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_arp_unk_source_cmd_get(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set IP unicast routing status on one particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_route_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_route_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IP unicast routing status on one particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_route_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_route_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add one interface entry to one particular device. + * @param[in] dev_id device id + * @param[in] entry interface entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_intf_entry_add(a_uint32_t dev_id, fal_intf_mac_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_intf_entry_add(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete one interface entry from one particular device. + * @param[in] dev_id device id + * @param[in] del_mode delete operation mode + * @param[in] entry interface entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_intf_entry_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_intf_mac_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_intf_entry_del(dev_id, del_mode, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Next one interface entry from one particular device. + * @param[in] dev_id device id + * @param[in] next_mode next operation mode + * @param[out] entry interface entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_intf_entry_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_intf_mac_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_intf_entry_next(dev_id, next_mode, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set IP host entry aging time on one particular device. + * @details Comments: + * This operation will set dynamic entry aging time on a particular device. + * The unit of time is second. Because different device has differnet + * hardware granularity function will return actual time in hardware. + * @param[in] dev_id device id + * @param[in] time aging time + * @param[out] time actual aging time + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_age_time_set(a_uint32_t dev_id, a_uint32_t * time) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_age_time_set(dev_id, time); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IP host entry aging time on one particular device. + * @param[in] dev_id device id + * @param[out] time aging time + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_age_time_get(a_uint32_t dev_id, a_uint32_t * time) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_age_time_get(dev_id, time); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set IP WCMP table one particular device. + * @details Comments: + * Hardware only support 0 - 15 hash values and 4 different host tables. + * @param[in] dev_id device id + * @param[in] wcmp_id wcmp entry id + * @param[in] wcmp wcmp entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_wcmp_entry_set(a_uint32_t dev_id, a_uint32_t wcmp_id, fal_ip_wcmp_t * wcmp) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_wcmp_entry_set(dev_id, wcmp_id, wcmp); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IP WCMP table one particular device. + * @details Comments: + * Hardware only support 0 - 15 hash values and 4 different host tables. + * @param[in] dev_id device id + * @param[in] wcmp_id wcmp entry id + * @param[out] wcmp wcmp entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_wcmp_entry_get(a_uint32_t dev_id, a_uint32_t wcmp_id, fal_ip_wcmp_t * wcmp) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_wcmp_entry_get(dev_id, wcmp_id, wcmp); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set IP WCMP hash key mode. + * @param[in] dev_id device id + * @param[in] hash_mode hash mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_wcmp_hash_mode_set(a_uint32_t dev_id, a_uint32_t hash_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_wcmp_hash_mode_set(dev_id, hash_mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IP WCMP hash key mode. + * @param[in] dev_id device id + * @param[out] hash_mode hash mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_wcmp_hash_mode_get(a_uint32_t dev_id, a_uint32_t * hash_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_wcmp_hash_mode_get(dev_id, hash_mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set IP VRF base IP address. + * @param[in] dev_id device id + * @param[in] vrf_id VRF route index, from 0~7 + * @param[in] fal_ip4_addr_t IPv4 address for this VRF route + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_vrf_base_addr_set(a_uint32_t dev_id, a_uint32_t vrf_id, fal_ip4_addr_t addr) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_vrf_base_addr_set(dev_id, vrf_id, addr); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IP VRF base IP address. + * @param[in] dev_id device id + * @param[in] vrf_id VRF route index, from 0~7 + * @param[out] fal_ip4_addr_t IPv4 address for this VRF route + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_vrf_base_addr_get(a_uint32_t dev_id, a_uint32_t vrf_id, fal_ip4_addr_t * addr) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_vrf_base_addr_get(dev_id, vrf_id, addr); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set IP VRF base IP address mask. + * @param[in] dev_id device id + * @param[in] vrf_id VRF route index, from 0~7 + * @param[in] fal_ip4_addr_t IPv4 address mask for this VRF route + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_vrf_base_mask_set(a_uint32_t dev_id, a_uint32_t vrf_id, fal_ip4_addr_t addr) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_vrf_base_mask_set(dev_id, vrf_id, addr); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IP VRF base IP address mask. + * @param[in] dev_id device id + * @param[in] vrf_id VRF route index, from 0~7 + * @param[out] fal_ip4_addr_t IPv4 address mask for this VRF route + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_vrf_base_mask_get(a_uint32_t dev_id, a_uint32_t vrf_id, fal_ip4_addr_t * addr) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_vrf_base_mask_get(dev_id, vrf_id, addr); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set IP default route entry with special default route id. + * @param[in] dev_id device id + * @param[in] droute_id default route index, from 0~7 + * @param[in] fal_default_route_t default route entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_default_route_set(a_uint32_t dev_id, a_uint32_t droute_id, fal_default_route_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_default_route_set(dev_id, droute_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IP default route entry with special default route id. + * @param[in] dev_id device id + * @param[in] droute_id default route index, from 0~7 + * @param[in] fal_default_route_t default route entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_default_route_get(a_uint32_t dev_id, a_uint32_t droute_id, fal_default_route_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_default_route_get(dev_id, droute_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set IP host route entry with special default route id. + * @param[in] dev_id device id + * @param[in] hroute_id default route index, from 0~15 + * @param[in] fal_host_route_t host route entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_host_route_set(a_uint32_t dev_id, a_uint32_t hroute_id, fal_host_route_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_host_route_set(dev_id, hroute_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IP host route entry with special default route id. + * @param[in] dev_id device id + * @param[in] hroute_id default route index, from 0~15 + * @param[in] fal_host_route_t host route entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_host_route_get(a_uint32_t dev_id, a_uint32_t hroute_id, fal_host_route_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_host_route_get(dev_id, hroute_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set IP host route load balance. + * @param[in] dev_id device id + * @param[in] fal_ip4_rfs_t host route entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_rfs_ip4_set(a_uint32_t dev_id, fal_ip4_rfs_t * rfs) +{ + sw_error_t rv; + fal_intf_mac_entry_t mac_entry; + + HSL_API_LOCK; + memset(&mac_entry, 0, sizeof(mac_entry)); + mac_entry.ip4_route = A_TRUE; + mac_entry.ip6_route = A_TRUE; + mac_entry.vid_low = rfs->vid; + mac_entry.vid_high = rfs->vid; + mac_entry.mac_addr = rfs->mac_addr; + rv = _dess_ip_intf_entry_add(dev_id, &mac_entry); + if(!rv) + rv = _dess_ip_rfs_ip4_set(dev_id, rfs); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set IP6 host route load balance. + * @param[in] dev_id device id + * @param[in] fal_ip6_rfs_t host route entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_rfs_ip6_set(a_uint32_t dev_id, fal_ip6_rfs_t * rfs) +{ + sw_error_t rv; + fal_intf_mac_entry_t mac_entry; + + HSL_API_LOCK; + memset(&mac_entry, 0, sizeof(mac_entry)); + mac_entry.ip4_route = A_TRUE; + mac_entry.ip6_route = A_TRUE; + mac_entry.vid_low = rfs->vid; + mac_entry.vid_high = rfs->vid; + mac_entry.mac_addr = rfs->mac_addr; + rv = _dess_ip_intf_entry_add(dev_id, &mac_entry); + if(!rv) + rv = _dess_ip_rfs_ip6_set(dev_id, rfs); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief del IP host route load balance. + * @param[in] dev_id device id + * @param[in] fal_ip4_rfs_t host route entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_rfs_ip4_del(a_uint32_t dev_id, fal_ip4_rfs_t * rfs) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_rfs_ip4_del(dev_id, rfs); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief del IP6 host route load balance. + * @param[in] dev_id device id + * @param[in] fal_ip6_rfs_t host route entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_rfs_ip6_del(a_uint32_t dev_id, fal_ip6_rfs_t * rfs) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_rfs_ip6_del(dev_id, rfs); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flow type traffic default forward command. + * @param[in] dev_id device id + * @param[in] vrf_id VRF route index, from 0~7 + * @param[in] type traffic flow type pass through switch core + * @param[in] fal_default_flow_cmd_mode_t default flow forward command when flow table mismatch + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_default_flow_cmd_set(dev_id, vrf_id, type, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get flow type traffic default forward command. + * @param[in] dev_id device id + * @param[in] vrf_id VRF route index, from 0~7 + * @param[in] type traffic flow type pass through switch core + * @param[out] fal_default_flow_cmd_mode_t default flow forward command when flow table mismatch + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_default_flow_cmd_get(dev_id, vrf_id, type, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flow&route type traffic default forward command. + * @param[in] dev_id device id + * @param[in] vrf_id VRF route index, from 0~7 + * @param[in] type traffic flow type pass through switch core + * @param[in] fal_default_flow_cmd_mode_t default flow&route forward command when route mac match but flow table mismatch + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_default_rt_flow_cmd_set(dev_id, vrf_id, type, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get flow&route type traffic default forward command. + * @param[in] dev_id device id + * @param[in] vrf_id VRF route index, from 0~7 + * @param[in] type traffic flow type pass through switch core + * @param[in] fal_default_flow_cmd_mode_t default flow&route forward command when route mac match but flow table mismatch + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_default_rt_flow_cmd_get(dev_id, vrf_id, type, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set blobal lock time. + * @param[in] dev_id device id + * @param[in] fal_glb_lock_time_t lock time + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ip_glb_lock_time_set(a_uint32_t dev_id, fal_glb_lock_time_t lock_time) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ip_glb_lock_time_set(dev_id, lock_time); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +dess_ip_init(a_uint32_t dev_id) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + rv = dess_ip_reset(dev_id); + SW_RTN_ON_ERROR(rv); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->ip_host_add = dess_ip_host_add; + p_api->ip_host_del = dess_ip_host_del; + p_api->ip_host_get = dess_ip_host_get; + p_api->ip_host_next = dess_ip_host_next; + p_api->ip_host_counter_bind = dess_ip_host_counter_bind; + p_api->ip_host_pppoe_bind = dess_ip_host_pppoe_bind; + p_api->ip_pt_arp_learn_set = dess_ip_pt_arp_learn_set; + p_api->ip_pt_arp_learn_get = dess_ip_pt_arp_learn_get; + p_api->ip_arp_learn_set = dess_ip_arp_learn_set; + p_api->ip_arp_learn_get = dess_ip_arp_learn_get; + p_api->ip_source_guard_set = dess_ip_source_guard_set; + p_api->ip_source_guard_get = dess_ip_source_guard_get; + p_api->ip_unk_source_cmd_set = dess_ip_unk_source_cmd_set; + p_api->ip_unk_source_cmd_get = dess_ip_unk_source_cmd_get; + p_api->ip_arp_guard_set = dess_ip_arp_guard_set; + p_api->ip_arp_guard_get = dess_ip_arp_guard_get; + p_api->arp_unk_source_cmd_set = dess_arp_unk_source_cmd_set; + p_api->arp_unk_source_cmd_get = dess_arp_unk_source_cmd_get; + p_api->ip_route_status_set = dess_ip_route_status_set; + p_api->ip_route_status_get = dess_ip_route_status_get; + p_api->ip_intf_entry_add = dess_ip_intf_entry_add; + p_api->ip_intf_entry_del = dess_ip_intf_entry_del; + p_api->ip_intf_entry_next = dess_ip_intf_entry_next; + p_api->ip_age_time_set = dess_ip_age_time_set; + p_api->ip_age_time_get = dess_ip_age_time_get; + p_api->ip_wcmp_hash_mode_set = dess_ip_wcmp_hash_mode_set; + p_api->ip_wcmp_hash_mode_get = dess_ip_wcmp_hash_mode_get; + p_api->ip_vrf_base_addr_set = dess_ip_vrf_base_addr_set; + p_api->ip_vrf_base_addr_get = dess_ip_vrf_base_addr_get; + p_api->ip_vrf_base_mask_set = dess_ip_vrf_base_mask_set; + p_api->ip_vrf_base_mask_get = dess_ip_vrf_base_mask_get; + p_api->ip_default_route_set = dess_ip_default_route_set; + p_api->ip_default_route_get = dess_ip_default_route_get; + p_api->ip_host_route_set = dess_ip_host_route_set; + p_api->ip_host_route_get = dess_ip_host_route_get; + p_api->ip_wcmp_entry_set = dess_ip_wcmp_entry_set; + p_api->ip_wcmp_entry_get = dess_ip_wcmp_entry_get; + p_api->ip_rfs_ip4_set = dess_ip_rfs_ip4_set; + p_api->ip_rfs_ip6_set = dess_ip_rfs_ip6_set; + p_api->ip_rfs_ip4_del = dess_ip_rfs_ip4_del; + p_api->ip_rfs_ip6_del = dess_ip_rfs_ip6_del; + p_api->ip_default_flow_cmd_set = dess_default_flow_cmd_set; + p_api->ip_default_flow_cmd_get = dess_default_flow_cmd_get; + p_api->ip_default_rt_flow_cmd_set = dess_default_rt_flow_cmd_set; + p_api->ip_default_rt_flow_cmd_get = dess_default_rt_flow_cmd_get; + p_api->ip_glb_lock_time_set = dess_ip_glb_lock_time_set; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_leaky.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_leaky.c new file mode 100755 index 000000000..6aef5d58d --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_leaky.c @@ -0,0 +1,526 @@ +/* + * Copyright (c) 2014, 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. + */ + + +/** + * @defgroup dess_leaky DESS_LEAKY + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "dess_leaky.h" +#include "dess_reg.h" + +static sw_error_t +_dess_uc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_LEAKY_PORT_CTRL == ctrl_mode) + { + data = 0; + } + else if (FAL_LEAKY_FDB_CTRL == ctrl_mode) + { + data = 1; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, ARL_UNI_LEAKY, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_uc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t *ctrl_mode) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, ARL_UNI_LEAKY, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *ctrl_mode = FAL_LEAKY_FDB_CTRL; + } + else + { + *ctrl_mode = FAL_LEAKY_PORT_CTRL; + } + + return SW_OK; +} + +static sw_error_t +_dess_mc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_LEAKY_PORT_CTRL == ctrl_mode) + { + data = 0; + } + else if (FAL_LEAKY_FDB_CTRL == ctrl_mode) + { + data = 1; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, ARL_MUL_LEAKY, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_mc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t *ctrl_mode) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, ARL_MUL_LEAKY, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *ctrl_mode = FAL_LEAKY_FDB_CTRL; + } + else + { + *ctrl_mode = FAL_LEAKY_PORT_CTRL; + } + + return SW_OK; +} + +static sw_error_t +_dess_port_arp_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LOOKUP_CTL, port_id, ARP_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_port_arp_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LOOKUP_CTL, port_id, ARP_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_port_uc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LOOKUP_CTL, port_id, UNI_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_port_uc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LOOKUP_CTL, port_id, UNI_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_port_mc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LOOKUP_CTL, port_id, MUL_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_port_mc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LOOKUP_CTL, port_id, MUL_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +/** +* @brief Set unicast packets leaky control mode on a particular device. +* @param[in] dev_id device id +* @param[in] ctrl_mode leaky control mode +* @return SW_OK or error code +*/ +HSL_LOCAL sw_error_t +dess_uc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_uc_leaky_mode_set(dev_id, ctrl_mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get unicast packets leaky control mode on a particular device. + * @param[in] dev_id device id + * @param[out] ctrl_mode leaky control mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_uc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t *ctrl_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_uc_leaky_mode_get(dev_id, ctrl_mode); + HSL_API_UNLOCK; + return rv; +} + +/** +* @brief Set multicast packets leaky control mode on a particular device. +* @param[in] dev_id device id +* @param[in] ctrl_mode leaky control mode +* @return SW_OK or error code +*/ +HSL_LOCAL sw_error_t +dess_mc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_mc_leaky_mode_set(dev_id, ctrl_mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get multicast packets leaky control mode on a particular device. + * @param[in] dev_id device id + * @param[out] ctrl_mode leaky control mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_mc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t *ctrl_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_mc_leaky_mode_get(dev_id, ctrl_mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set arp packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_arp_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_arp_leaky_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_arp_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_arp_leaky_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set unicast packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_uc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_uc_leaky_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get unicast packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_uc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_uc_leaky_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set multicast packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_mc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_mc_leaky_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get multicast packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_mc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_mc_leaky_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +dess_leaky_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->uc_leaky_mode_set = dess_uc_leaky_mode_set; + p_api->uc_leaky_mode_get = dess_uc_leaky_mode_get; + p_api->mc_leaky_mode_set = dess_mc_leaky_mode_set; + p_api->mc_leaky_mode_get = dess_mc_leaky_mode_get; + p_api->port_arp_leaky_set = dess_port_arp_leaky_set; + p_api->port_arp_leaky_get = dess_port_arp_leaky_get; + p_api->port_uc_leaky_set = dess_port_uc_leaky_set; + p_api->port_uc_leaky_get = dess_port_uc_leaky_get; + p_api->port_mc_leaky_set = dess_port_mc_leaky_set; + p_api->port_mc_leaky_get = dess_port_mc_leaky_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_led.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_led.c new file mode 100755 index 000000000..6f2b2ace7 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_led.c @@ -0,0 +1,670 @@ +/* + * Copyright (c) 2014, 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. + */ + + +/** + * @defgroup dess_led DESS_LED + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "dess_led.h" +#include "dess_reg.h" + +#define MAX_LED_PATTERN_ID 2 +#define LED_PATTERN_ADDR 0x50 + +static sw_error_t +_dess_led_ctrl_pattern_set(a_uint32_t dev_id, led_pattern_group_t group, + led_pattern_id_t id, led_ctrl_pattern_t * pattern) +{ + a_uint32_t data = 0, reg = 0, mode; + a_uint32_t addr; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if ((LED_WAN_PORT_GROUP != group) && (LED_LAN_PORT_GROUP != group)) + { + return SW_BAD_PARAM; + } + + if (id > MAX_LED_PATTERN_ID) + { + return SW_BAD_PARAM; + } + + addr = LED_PATTERN_ADDR + (id << 2); + + if (LED_ALWAYS_OFF == pattern->mode) + { + mode = 0; + } + else if (LED_ALWAYS_BLINK == pattern->mode) + { + mode = 1; + } + else if (LED_ALWAYS_ON == pattern->mode) + { + mode = 2; + } + else if (LED_PATTERN_MAP_EN == pattern->mode) + { + mode = 3; + } + else + { + return SW_BAD_PARAM; + } + SW_SET_REG_BY_FIELD(LED_CTRL, PATTERN_EN, mode, data); + + if (pattern->map & (1 << FULL_DUPLEX_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, FULL_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << HALF_DUPLEX_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, HALF_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << POWER_ON_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, POWERON_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << LINK_1000M_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, GE_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << LINK_100M_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, FE_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << LINK_10M_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, ETH_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << COLLISION_BLINK_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, COL_BLINK_EN, 1, data); + } + + if (pattern->map & (1 << RX_TRAFFIC_BLINK_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, RX_BLINK_EN, 1, data); + } + + if (pattern->map & (1 << TX_TRAFFIC_BLINK_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, TX_BLINK_EN, 1, data); + } + + if (pattern->map & (1 << LINKUP_OVERRIDE_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, LINKUP_OVER_EN, 1, data); + } + else + { + SW_SET_REG_BY_FIELD(LED_CTRL, LINKUP_OVER_EN, 0, data); + } + + if (LED_BLINK_2HZ == pattern->freq) + { + SW_SET_REG_BY_FIELD(LED_CTRL, BLINK_FREQ, 0, data); + } + else if (LED_BLINK_4HZ == pattern->freq) + { + SW_SET_REG_BY_FIELD(LED_CTRL, BLINK_FREQ, 1, data); + } + else if (LED_BLINK_8HZ == pattern->freq) + { + SW_SET_REG_BY_FIELD(LED_CTRL, BLINK_FREQ, 2, data); + } + else if (LED_BLINK_TXRX == pattern->freq) + { + SW_SET_REG_BY_FIELD(LED_CTRL, BLINK_FREQ, 3, data); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (LED_WAN_PORT_GROUP == group) + { + reg &= 0xffff; + reg |= (data << 16); + } + else + { + reg &= 0xffff0000; + reg |= data; + } + + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (LED_WAN_PORT_GROUP == group) + { + return SW_OK; + } + + HSL_REG_ENTRY_GET(rv, dev_id, LED_PATTERN, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (LED_LAN_PORT_GROUP == group) + { + if (0 == id) + { + SW_SET_REG_BY_FIELD(LED_PATTERN, P3L0_MODE, mode, data); + SW_SET_REG_BY_FIELD(LED_PATTERN, P2L0_MODE, mode, data); + SW_SET_REG_BY_FIELD(LED_PATTERN, P1L0_MODE, mode, data); + } + else if (1 == id) + { + SW_SET_REG_BY_FIELD(LED_PATTERN, P3L1_MODE, mode, data); + SW_SET_REG_BY_FIELD(LED_PATTERN, P2L1_MODE, mode, data); + SW_SET_REG_BY_FIELD(LED_PATTERN, P1L1_MODE, mode, data); + } + else + { + SW_SET_REG_BY_FIELD(LED_PATTERN, P3L2_MODE, mode, data); + SW_SET_REG_BY_FIELD(LED_PATTERN, P2L2_MODE, mode, data); + SW_SET_REG_BY_FIELD(LED_PATTERN, P1L2_MODE, mode, data); + } + } + + HSL_REG_ENTRY_SET(rv, dev_id, LED_PATTERN, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +static sw_error_t +_dess_led_ctrl_pattern_get(a_uint32_t dev_id, led_pattern_group_t group, + led_pattern_id_t id, led_ctrl_pattern_t * pattern) +{ + a_uint32_t data = 0, reg = 0, tmp; + a_uint32_t addr; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if ((LED_WAN_PORT_GROUP != group) && (LED_LAN_PORT_GROUP != group)) + { + return SW_BAD_PARAM; + } + + if (id > MAX_LED_PATTERN_ID) + { + return SW_BAD_PARAM; + } + + aos_mem_zero(pattern, sizeof(led_ctrl_pattern_t)); + + addr = LED_PATTERN_ADDR + (id << 2); + + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (LED_WAN_PORT_GROUP == group) + { + data = (reg >> 16) & 0xffff; + } + else + { + data = reg & 0xffff; + } + + SW_GET_FIELD_BY_REG(LED_CTRL, PATTERN_EN, tmp, data); + if (0 == tmp) + { + pattern->mode = LED_ALWAYS_OFF; + } + else if (1 == tmp) + { + pattern->mode = LED_ALWAYS_BLINK; + } + else if (2 == tmp) + { + pattern->mode = LED_ALWAYS_ON; + } + else + { + pattern->mode = LED_PATTERN_MAP_EN; + } + + SW_GET_FIELD_BY_REG(LED_CTRL, FULL_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << FULL_DUPLEX_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, HALF_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << HALF_DUPLEX_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, POWERON_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << POWER_ON_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, GE_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << LINK_1000M_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, FE_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << LINK_100M_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, ETH_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << LINK_10M_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, COL_BLINK_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << COLLISION_BLINK_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, RX_BLINK_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << RX_TRAFFIC_BLINK_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, TX_BLINK_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << TX_TRAFFIC_BLINK_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, LINKUP_OVER_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << LINKUP_OVERRIDE_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, BLINK_FREQ, tmp, data); + if (0 == tmp) + { + pattern->freq = LED_BLINK_2HZ; + } + else if (1 == tmp) + { + pattern->freq = LED_BLINK_4HZ; + } + else if (2 == tmp) + { + pattern->freq = LED_BLINK_8HZ; + } + else + { + pattern->freq = LED_BLINK_TXRX; + } + + return SW_OK; +} + +static sw_error_t +_dess_led_source_pattern_set(a_uint32_t dev_id, a_uint32_t source_id, led_ctrl_pattern_t * pattern) +{ + a_uint32_t data = 0, data1 = 0, reg = 0, mode; + sw_error_t rv; + a_uint32_t addr; + + HSL_DEV_ID_CHECK(dev_id); + + if (LED_ALWAYS_OFF == pattern->mode) + { + mode = 0; + } + else if (LED_ALWAYS_BLINK == pattern->mode) + { + mode = 1; + } + else if (LED_ALWAYS_ON == pattern->mode) + { + mode = 2; + } + else if (LED_PATTERN_MAP_EN == pattern->mode) + { + mode = 3; + } + else + { + return SW_BAD_PARAM; + } + + SW_SET_REG_BY_FIELD(LED_CTRL, PATTERN_EN, mode, data); + + if (pattern->map & (1 << FULL_DUPLEX_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, FULL_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << HALF_DUPLEX_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, HALF_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << POWER_ON_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, POWERON_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << LINK_1000M_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, GE_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << LINK_100M_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, FE_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << LINK_10M_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, ETH_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << COLLISION_BLINK_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, COL_BLINK_EN, 1, data); + } + + if (pattern->map & (1 << RX_TRAFFIC_BLINK_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, RX_BLINK_EN, 1, data); + } + + if (pattern->map & (1 << TX_TRAFFIC_BLINK_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, TX_BLINK_EN, 1, data); + } + + if (pattern->map & (1 << LINKUP_OVERRIDE_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, LINKUP_OVER_EN, 1, data); + } + else + { + SW_SET_REG_BY_FIELD(LED_CTRL, LINKUP_OVER_EN, 0, data); + } + + if (LED_BLINK_2HZ == pattern->freq) + { + SW_SET_REG_BY_FIELD(LED_CTRL, BLINK_FREQ, 0, data); + } + else if (LED_BLINK_4HZ == pattern->freq) + { + SW_SET_REG_BY_FIELD(LED_CTRL, BLINK_FREQ, 1, data); + } + else if (LED_BLINK_8HZ == pattern->freq) + { + SW_SET_REG_BY_FIELD(LED_CTRL, BLINK_FREQ, 2, data); + } + else if (LED_BLINK_TXRX == pattern->freq) + { + SW_SET_REG_BY_FIELD(LED_CTRL, BLINK_FREQ, 3, data); + } + else + { + return SW_BAD_PARAM; + } + + if (source_id == 1) + { + + addr = LED_PATTERN_ADDR; + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), + sizeof (a_uint32_t)); + reg &= 0xffff0000; + reg |= data; + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + } + else if (source_id == 2) + { + addr = LED_PATTERN_ADDR + (1 << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), + sizeof (a_uint32_t)); + reg &= 0xffff0000; + reg |= data; + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + } + else if (source_id == 3) + { + addr = LED_PATTERN_ADDR + (2 << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), + sizeof (a_uint32_t)); + reg &= 0xffff0000; + reg |= data; + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + } + if (source_id == 13) + { + addr = LED_PATTERN_ADDR; + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), + sizeof (a_uint32_t)); + reg &= 0xffff; + reg |= (data << 16); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + } + else if (source_id == 14) + { + addr = LED_PATTERN_ADDR + (1 << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), + sizeof (a_uint32_t)); + reg &= 0xffff; + reg |= (data << 16); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + } + else if (source_id == 15) + { + addr = LED_PATTERN_ADDR + (2 << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), + sizeof (a_uint32_t)); + reg &= 0xffff; + reg |= (data << 16); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + } + else if ((source_id) >= 4 && (source_id <= 12)) + { + HSL_REG_ENTRY_GET(rv, dev_id, LED_PATTERN, 0, + (a_uint8_t *) (&data1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (source_id == 4) + { + SW_SET_REG_BY_FIELD(LED_PATTERN, P1L0_MODE, mode, data1); + } + if (source_id == 5) + { + SW_SET_REG_BY_FIELD(LED_PATTERN, P1L1_MODE, mode, data1); + } + if (source_id == 6) + { + SW_SET_REG_BY_FIELD(LED_PATTERN, P1L2_MODE, mode, data1); + } + if (source_id == 7) + { + SW_SET_REG_BY_FIELD(LED_PATTERN, P2L0_MODE, mode, data1); + } + if (source_id == 8) + { + SW_SET_REG_BY_FIELD(LED_PATTERN, P2L1_MODE, mode, data1); + } + if (source_id == 9) + { + SW_SET_REG_BY_FIELD(LED_PATTERN, P2L2_MODE, mode, data1); + } + if (source_id == 10) + { + SW_SET_REG_BY_FIELD(LED_PATTERN, P3L0_MODE, mode, data1); + } + if (source_id == 11) + { + SW_SET_REG_BY_FIELD(LED_PATTERN, P3L1_MODE, mode, data1); + } + if (source_id == 12) + { + SW_SET_REG_BY_FIELD(LED_PATTERN, P3L2_MODE, mode, data1); + } + + HSL_REG_ENTRY_SET(rv, dev_id, LED_PATTERN, 0, + (a_uint8_t *) (&data1), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + } + + return SW_OK; + +} + +/** +* @brief Set led control pattern on a particular device. +* @param[in] dev_id device id +* @param[in] group pattern group, lan or wan +* @param[in] id pattern id +* @param[in] pattern led control pattern +* @return SW_OK or error code +*/ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_led_ctrl_pattern_set(dev_id, group, id, pattern); + HSL_API_UNLOCK; + return rv; +} + +/** +* @brief Get led control pattern on a particular device. +* @param[in] dev_id device id +* @param[in] group pattern group, lan or wan +* @param[in] id pattern id +* @param[out] pattern led control pattern +* @return SW_OK or error code +*/ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_led_ctrl_pattern_get(dev_id, group, id, pattern); + HSL_API_UNLOCK; + return rv; +} + +/** +* @brief Set led source pattern on a particular device. +* @param[in] dev_id device id +* @param[in] source id +* @param[in] id pattern id +* @param[in] pattern led control pattern +* @return SW_OK or error code +*/ +HSL_LOCAL sw_error_t +dess_led_source_pattern_set(a_uint32_t dev_id, a_uint32_t source_id, led_ctrl_pattern_t * pattern) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_led_source_pattern_set(dev_id, source_id, pattern); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +dess_led_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->led_ctrl_pattern_set = dess_led_ctrl_pattern_set; + p_api->led_ctrl_pattern_get = dess_led_ctrl_pattern_get; + p_api->led_ctrl_source_set = dess_led_source_pattern_set; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_mib.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_mib.c new file mode 100755 index 000000000..4cc6ed7b2 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_mib.c @@ -0,0 +1,861 @@ +/* + * Copyright (c) 2014, 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. + */ + + +/** + * @defgroup dess_mib DESS_MIB + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "dess_mib.h" +#include "dess_reg.h" + + +#define MIB_FLUSH_ALL_PORTS 0x1 +#define MIB_FLUSH_ONE_PORT 0x2 +#define MIB_AUTOCAST_ALL_PORTS 0x3 + +static sw_error_t +_dess_mib_op_commit(a_uint32_t dev_id, a_uint32_t op) +{ + a_uint32_t mib_busy = 1, i = 0x1000, val; + sw_error_t rv; + + while (mib_busy && --i) + { + HSL_REG_FIELD_GET(rv, dev_id, MIB_FUNC, 0, MIB_BUSY, + (a_uint8_t *) (&mib_busy), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + aos_udelay(5); + } + + if (i == 0) + return SW_BUSY; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_FUNC, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_SET_REG_BY_FIELD(MIB_FUNC, MIB_FUN, op, val); + SW_SET_REG_BY_FIELD(MIB_FUNC, MIB_BUSY, 1, val); + + HSL_REG_ENTRY_SET(rv, dev_id, MIB_FUNC, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + mib_busy = 1; + i = 0x1000; + while (mib_busy && --i) + { + HSL_REG_FIELD_GET(rv, dev_id, MIB_FUNC, 0, MIB_BUSY, + (a_uint8_t *) (&mib_busy), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + aos_udelay(5); + } + + if (i == 0) + return SW_FAIL; + + return SW_OK; +} + +static sw_error_t +_dess_get_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info) +{ + a_uint32_t val = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_OUT_OF_RANGE; + } + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBROAD, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxBroad = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXPAUSE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxPause = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXMULTI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxMulti = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXFCSERR, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxFcsErr = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXALLIGNERR, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxAllignErr = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXRUNT, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxRunt = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXFRAGMENT, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxFragment = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX64BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx64Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX128BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx128Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX256BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx256Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX512BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx512Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX1024BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx1024Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX1518BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx1518Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXMAXBYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxMaxByte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXTOOLONG, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxTooLong = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXGOODBYTE_LO, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxGoodByte_lo = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXGOODBYTE_HI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxGoodByte_hi = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBADBYTE_LO, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxBadByte_lo = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBADBYTE_HI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxBadByte_hi = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXOVERFLOW, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxOverFlow = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_FILTERED, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Filtered = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBROAD, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxBroad = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXPAUSE, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxPause = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMULTI, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxMulti = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXUNDERRUN, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxUnderRun = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX64BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx64Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX128BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx128Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX256BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx256Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX512BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx512Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX1024BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx1024Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX1518BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx1518Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMAXBYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxMaxByte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXOVERSIZE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxOverSize = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBYTE_LO, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxByte_lo = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBYTE_HI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxByte_hi = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXCOLLISION, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxCollision = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXABORTCOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxAbortCol = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMULTICOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxMultiCol = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXSINGALCOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxSingalCol = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXEXCDEFER, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxExcDefer = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXDEFER, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxDefer = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXLATECOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxLateCol = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXUNICAST, port_id, + (a_uint8_t *) (&val), sizeof + (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxUniCast = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXUNICAST, port_id, + (a_uint8_t *) (&val), sizeof + (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxUniCast = val; + + return SW_OK; +} + +static sw_error_t +_dess_get_rx_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info) +{ + a_uint32_t val = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_OUT_OF_RANGE; + } + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBROAD, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxBroad = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXPAUSE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxPause = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXMULTI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxMulti = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXFCSERR, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxFcsErr = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXALLIGNERR, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxAllignErr = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXRUNT, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxRunt = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXFRAGMENT, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxFragment = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX64BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx64Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX128BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx128Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX256BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx256Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX512BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx512Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX1024BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx1024Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX1518BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx1518Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXMAXBYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxMaxByte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXTOOLONG, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxTooLong = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXGOODBYTE_LO, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxGoodByte_lo = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXGOODBYTE_HI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxGoodByte_hi = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBADBYTE_LO, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxBadByte_lo = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBADBYTE_HI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxBadByte_hi = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXOVERFLOW, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxOverFlow = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_FILTERED, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Filtered = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXUNICAST, port_id, + (a_uint8_t *) (&val), sizeof + (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxUniCast = val; + + return SW_OK; +} + +static sw_error_t +_dess_get_tx_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info) +{ + a_uint32_t val = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_OUT_OF_RANGE; + } + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBROAD, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxBroad = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXPAUSE, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxPause = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMULTI, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxMulti = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXUNDERRUN, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxUnderRun = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX64BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx64Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX128BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx128Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX256BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx256Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX512BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx512Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX1024BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx1024Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX1518BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx1518Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMAXBYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxMaxByte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXOVERSIZE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxOverSize = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBYTE_LO, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxByte_lo = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBYTE_HI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxByte_hi = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXCOLLISION, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxCollision = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXABORTCOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxAbortCol = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMULTICOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxMultiCol = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXSINGALCOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxSingalCol = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXEXCDEFER, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxExcDefer = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXDEFER, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxDefer = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXLATECOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxLateCol = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXUNICAST, port_id, + (a_uint8_t *) (&val), sizeof + (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxUniCast = val; + + return SW_OK; +} + +static sw_error_t +_dess_mib_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, MOD_ENABLE, 0, MIB_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_mib_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, MOD_ENABLE, 0, MIB_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_mib_cpukeep_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, MIB_FUNC, 0, MIB_CPU_KEEP, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return rv; +} + +static sw_error_t +_dess_mib_cpukeep_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, MIB_FUNC, 0, MIB_CPU_KEEP, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_mib_port_flush_counters(a_uint32_t dev_id, fal_port_t port_id) +{ + a_uint32_t val; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_OUT_OF_RANGE; + } + + if (port_id>7) + return SW_BAD_PARAM; + + val = port_id; + HSL_REG_FIELD_SET(rv, dev_id, MIB_FUNC, 0, MIB_FLUSH_PORT, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + rv = _dess_mib_op_commit( dev_id, MIB_FLUSH_ONE_PORT); + + return rv; +} + +/** + * @brief Get mib infomation on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mib_info mib infomation + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_get_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_get_mib_info(dev_id, port_id, mib_info); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get RX mib infomation on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mib_info mib infomation + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_get_rx_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_get_rx_mib_info(dev_id, port_id, mib_info); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get TX mib infomation on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mib_info mib infomation + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_get_tx_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_get_tx_mib_info(dev_id, port_id, mib_info); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set mib status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_mib_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_mib_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mib status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_mib_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_mib_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +HSL_LOCAL sw_error_t +dess_mib_port_flush_counters(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_mib_port_flush_counters(dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set mib cpu keep bit on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_mib_cpukeep_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_mib_cpukeep_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mib keep bit on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_mib_cpukeep_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_mib_cpukeep_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +dess_mib_init(a_uint32_t dev_id) +{ + +#ifndef HSL_STANDALONG + hsl_api_t *p_api; +#endif + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->get_mib_info = dess_get_mib_info; + p_api->get_rx_mib_info = dess_get_rx_mib_info; + p_api->get_tx_mib_info = dess_get_tx_mib_info; + p_api->mib_status_set = dess_mib_status_set; + p_api->mib_status_get = dess_mib_status_get; + p_api->mib_port_flush_counters = dess_mib_port_flush_counters; + p_api->mib_cpukeep_set = dess_mib_cpukeep_set; + p_api->mib_cpukeep_get = dess_mib_cpukeep_get; +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_mirror.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_mirror.c new file mode 100755 index 000000000..9edb85fa4 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_mirror.c @@ -0,0 +1,316 @@ +/* + * Copyright (c) 2014, 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. + */ + + +/** + * @defgroup dess_mirror DESS_MIRROR + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "dess_mirror.h" +#include "dess_reg.h" + +static sw_error_t +_dess_mirr_analysis_port_set(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (port_id != MIRROR_ANALYZER_NONE) { + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) { + return SW_BAD_PARAM; + } + } + val = port_id; + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, MIRROR_PORT_NUM, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_mirr_analysis_port_get(a_uint32_t dev_id, fal_port_t * port_id) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, MIRROR_PORT_NUM, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *port_id = val; + return SW_OK; +} + +static sw_error_t +_dess_mirr_port_in_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LOOKUP_CTL, port_id, ING_MIRROR_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_mirr_port_in_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LOOKUP_CTL, port_id, ING_MIRROR_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_mirr_port_eg_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_HOL_CTL1, port_id, EG_MIRROR_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_mirr_port_eg_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_HOL_CTL1, port_id, EG_MIRROR_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +/** + * @details Comments: + * The analysis port works for both ingress and egress mirror. + * @brief Set mirror analyzer port on particular a device. + * @param[in] dev_id device id + * @param[in] port_id port id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_mirr_analysis_port_set(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_mirr_analysis_port_set(dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mirror analysis port on particular a device. + * @param[in] dev_id device id + * @param[out] port_id port id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_mirr_analysis_port_get(a_uint32_t dev_id, fal_port_t * port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_mirr_analysis_port_get(dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set ingress mirror status on particular a port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_mirr_port_in_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_mirr_port_in_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get ingress mirror status on particular a port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_mirr_port_in_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_mirr_port_in_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set egress mirror status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_mirr_port_eg_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_mirr_port_eg_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get egress mirror status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_mirr_port_eg_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_mirr_port_eg_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +dess_mirr_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->mirr_analysis_port_set = dess_mirr_analysis_port_set; + p_api->mirr_analysis_port_get = dess_mirr_analysis_port_get; + p_api->mirr_port_in_set = dess_mirr_port_in_set; + p_api->mirr_port_in_get = dess_mirr_port_in_get; + p_api->mirr_port_eg_set = dess_mirr_port_eg_set; + p_api->mirr_port_eg_get = dess_mirr_port_eg_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_misc.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_misc.c new file mode 100755 index 000000000..9db084dcb --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_misc.c @@ -0,0 +1,2450 @@ +/* + * 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 dess_misc DESS_MISC + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "dess_misc.h" +#include "dess_reg.h" +#include "hsl_phy.h" + +#define DESS_MAX_FRMAE_SIZE 9216 + +#define ARP_REQ_EN_OFFSET 6 +#define ARP_ACK_EN_OFFSET 5 +#define DHCP_EN_OFFSET 4 +#define EAPOL_EN_OFFSET 3 + +#define DESS_SWITCH_INT_PHY_INT 0x8000 + + +static sw_error_t +_dess_port_misc_property_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable, a_uint32_t item) +{ + sw_error_t rv; + a_uint32_t reg = 0, val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + if (3 >= port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, FRAME_ACK_CTL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + reg &= ~(0x1UL << ((port_id << 3) + item)); + reg |= (val << ((port_id << 3) + item)); + + HSL_REG_ENTRY_SET(rv, dev_id, FRAME_ACK_CTL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + HSL_REG_ENTRY_GET(rv, dev_id, FRAME_ACK_CTL1, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + reg &= ~(0x1UL << (((port_id - 4) << 3) + item)); + reg |= (val << (((port_id - 4) << 3) + item)); + + HSL_REG_ENTRY_SET(rv, dev_id, FRAME_ACK_CTL1, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + return rv; +} + +static sw_error_t +_dess_port_misc_property_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable, a_uint32_t item) +{ + sw_error_t rv; + a_uint32_t reg = 0, val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (3 >= port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, FRAME_ACK_CTL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + val = (reg >> ((port_id << 3) + item)) & 0x1UL; + } + else + { + HSL_REG_ENTRY_GET(rv, dev_id, FRAME_ACK_CTL1, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + val = (reg >> (((port_id - 4) << 3) + item)) & 0x1UL; + } + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_frame_max_size_set(a_uint32_t dev_id, a_uint32_t size) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (DESS_MAX_FRMAE_SIZE < size) + { + return SW_BAD_PARAM; + } + + data = size; + HSL_REG_FIELD_SET(rv, dev_id, MAX_SIZE, 0, MAX_FRAME_SIZE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_frame_max_size_get(a_uint32_t dev_id, a_uint32_t * size) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, MAX_SIZE, 0, MAX_FRAME_SIZE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *size = data; + return SW_OK; +} + +static sw_error_t +_dess_port_unk_uc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL1, 0, UNI_FLOOD_DP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + data &= (~((a_uint32_t) 0x1 << port_id)); + } + else if (A_FALSE == enable) + { + data |= (0x1 << port_id); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL1, 0, UNI_FLOOD_DP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_port_unk_uc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t reg = 0, field; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL1, 0, UNI_FLOOD_DP, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + field = reg & (0x1 << port_id); + if (field) + { + *enable = A_FALSE; + } + else + { + *enable = A_TRUE; + } + + return SW_OK; +} + +static sw_error_t +_dess_port_unk_mc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL1, 0, MUL_FLOOD_DP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + data &= (~((a_uint32_t) 0x1 << port_id)); + } + else if (A_FALSE == enable) + { + data |= (0x1 << port_id); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL1, 0, MUL_FLOOD_DP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_port_unk_mc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t reg = 0, field; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL1, 0, MUL_FLOOD_DP, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + field = reg & (0x1 << port_id); + if (field) + { + *enable = A_FALSE; + } + else + { + *enable = A_TRUE; + } + + return SW_OK; +} + +static sw_error_t +_dess_port_bc_filter_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL1, 0, BC_FLOOD_DP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + data &= (~((a_uint32_t) 0x1 << port_id)); + } + else if (A_FALSE == enable) + { + data |= (0x1 << port_id); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL1, 0, BC_FLOOD_DP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_port_bc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t reg = 0, field; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL1, 0, BC_FLOOD_DP, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + field = reg & (0x1 << port_id); + if (field) + { + *enable = A_FALSE; + } + else + { + *enable = A_TRUE; + } + + return SW_OK; +} + +static sw_error_t +_dess_cpu_port_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, CPU_PORT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_cpu_port_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, CPU_PORT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_cpu_vid_en_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PKT_CTRL, 0, CPU_VID_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_cpu_vid_en_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, PKT_CTRL, 0, CPU_VID_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_rtd_pppoe_en_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PKT_CTRL, 0, RTD_PPPOE_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_rtd_pppoe_en_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, PKT_CTRL, 0, RTD_PPPOE_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + + +static sw_error_t +_dess_pppoe_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_MAC_FRWRD == cmd) + { + val = 0; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + val = 1; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, PPPOE_RDT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_pppoe_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, PPPOE_RDT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + else + { + *cmd = FAL_MAC_FRWRD; + } + + return SW_OK; +} + +static sw_error_t +_dess_pppoe_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FRAME_ACK_CTL1, 0, PPPOE_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_pppoe_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FRAME_ACK_CTL1, 0, PPPOE_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_arp_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_MAC_CPY_TO_CPU == cmd) + { + val = 1; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + val = 0; + } + else if (FAL_MAC_FRWRD == cmd) + { + val = 2; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, ARP_CMD, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_arp_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, ARP_CMD, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *cmd = FAL_MAC_CPY_TO_CPU; + } + else if (0 == val) + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + else + { + *cmd = FAL_MAC_FRWRD; + } + + return SW_OK; +} + +static sw_error_t +_dess_eapol_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_MAC_CPY_TO_CPU == cmd) + { + val = 0; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + val = 1; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, EAPOL_CMD, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_eapol_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, EAPOL_CMD, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0 == val) + { + *cmd = FAL_MAC_CPY_TO_CPU; + } + else + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + + return SW_OK; +} + +#define DESS_MAX_PPPOE_SESSION 16 +#define DESS_MAX_SESSION_ID 0xffff + +static sw_error_t +_dess_pppoe_session_add(a_uint32_t dev_id, fal_pppoe_session_t * session_tbl) +{ + sw_error_t rv; + a_uint32_t reg = 0, i, valid, id, entry_idx = DESS_MAX_PPPOE_SESSION; + + HSL_DEV_ID_CHECK(dev_id); + + if (session_tbl->session_id > DESS_MAX_SESSION_ID) + { + return SW_BAD_PARAM; + } + + if ((A_FALSE == session_tbl->multi_session) + && (A_TRUE == session_tbl->uni_session)) + { + return SW_BAD_PARAM; + } + + if ((A_FALSE == session_tbl->multi_session) + && (A_FALSE == session_tbl->uni_session)) + { + return SW_BAD_PARAM; + } + + if(session_tbl->vrf_id > FAL_MAX_VRF_ID) + { + return SW_BAD_PARAM; + } + + for (i = 0; i < DESS_MAX_PPPOE_SESSION; i++) + { + HSL_REG_ENTRY_GET(rv, dev_id, PPPOE_SESSION, i, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PPPOE_SESSION, ENTRY_VALID, valid, reg); + SW_GET_FIELD_BY_REG(PPPOE_SESSION, SEESION_ID, id, reg); + + if (!valid) + { + entry_idx = i; + } + else if (id == session_tbl->session_id) + { + return SW_ALREADY_EXIST; + } + } + + if (DESS_MAX_PPPOE_SESSION == entry_idx) + { + return SW_NO_RESOURCE; + } + + if (A_TRUE == session_tbl->uni_session) + { + SW_SET_REG_BY_FIELD(PPPOE_SESSION, ENTRY_VALID, 2, reg); + } + else + { + SW_SET_REG_BY_FIELD(PPPOE_SESSION, ENTRY_VALID, 1, reg); + } + + SW_SET_REG_BY_FIELD(PPPOE_SESSION, SEESION_ID, session_tbl->session_id, + reg); + SW_SET_REG_BY_FIELD(PPPOE_SESSION, VRF_ID, session_tbl->vrf_id, + reg); + + HSL_REG_ENTRY_SET(rv, dev_id, PPPOE_SESSION, entry_idx, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + session_tbl->entry_id = entry_idx; + return SW_OK; +} + +static sw_error_t +_dess_pppoe_session_del(a_uint32_t dev_id, fal_pppoe_session_t * session_tbl) +{ + sw_error_t rv; + a_uint32_t reg = 0, i, valid, id; + + HSL_DEV_ID_CHECK(dev_id); + + if (session_tbl->session_id > DESS_MAX_SESSION_ID) + { + return SW_BAD_PARAM; + } + + for (i = 0; i < DESS_MAX_PPPOE_SESSION; i++) + { + HSL_REG_ENTRY_GET(rv, dev_id, PPPOE_SESSION, i, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PPPOE_SESSION, ENTRY_VALID, valid, reg); + SW_GET_FIELD_BY_REG(PPPOE_SESSION, SEESION_ID, id, reg); + + if (((1 == valid) || (2 == valid)) && (id == session_tbl->session_id)) + { + SW_SET_REG_BY_FIELD(PPPOE_SESSION, ENTRY_VALID, 0, reg); + SW_SET_REG_BY_FIELD(PPPOE_SESSION, SEESION_ID, 0, reg); + SW_SET_REG_BY_FIELD(PPPOE_SESSION, VRF_ID, 0, reg); + HSL_REG_ENTRY_SET(rv, dev_id, PPPOE_SESSION, i, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; + } + } + + return SW_NOT_FOUND; +} + +static sw_error_t +_dess_pppoe_session_get(a_uint32_t dev_id, fal_pppoe_session_t * session_tbl) +{ + sw_error_t rv; + a_uint32_t reg = 0, i, valid, id, vrf_id; + + HSL_DEV_ID_CHECK(dev_id); + + if (session_tbl->session_id > DESS_MAX_SESSION_ID) + { + return SW_BAD_PARAM; + } + + for (i = 0; i < DESS_MAX_PPPOE_SESSION; i++) + { + HSL_REG_ENTRY_GET(rv, dev_id, PPPOE_SESSION, i, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PPPOE_SESSION, ENTRY_VALID, valid, reg); + SW_GET_FIELD_BY_REG(PPPOE_SESSION, SEESION_ID, id, reg); + SW_GET_FIELD_BY_REG(PPPOE_SESSION, VRF_ID, vrf_id, reg); + + if (((1 == valid) || (2 == valid)) && (id == session_tbl->session_id)) + { + if (1 == valid) + { + session_tbl->multi_session = A_TRUE; + session_tbl->uni_session = A_FALSE; + } + else + { + session_tbl->multi_session = A_TRUE; + session_tbl->uni_session = A_TRUE; + } + + session_tbl->entry_id = i; + session_tbl->vrf_id = vrf_id; + return SW_OK; + } + } + + return SW_NOT_FOUND; +} + +static sw_error_t +_dess_pppoe_session_id_set(a_uint32_t dev_id, a_uint32_t index, + a_uint32_t id) +{ + sw_error_t rv; + a_uint32_t reg; + + if (DESS_MAX_PPPOE_SESSION <= index) + { + return SW_BAD_PARAM; + } + + if (DESS_MAX_SESSION_ID < id) + { + return SW_BAD_PARAM; + } + + reg = 0; + SW_SET_REG_BY_FIELD(PPPOE_EDIT, EDIT_ID, id, reg); + HSL_REG_ENTRY_SET(rv, dev_id, PPPOE_EDIT, index, (a_uint8_t *) (®), + sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_dess_pppoe_session_id_get(a_uint32_t dev_id, a_uint32_t index, + a_uint32_t * id) +{ + sw_error_t rv; + a_uint32_t reg = 0, tmp; + + if (DESS_MAX_PPPOE_SESSION <= index) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PPPOE_EDIT, index, (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + tmp = 0; + SW_GET_FIELD_BY_REG(PPPOE_EDIT, EDIT_ID, tmp, reg); + *id = tmp; + return SW_OK; +} + +static sw_error_t +_dess_ripv1_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, 0, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, RIP_CPY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_ripv1_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, 0, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, RIP_CPY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_intr_mask_set(a_uint32_t dev_id, a_uint32_t intr_mask) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + HSL_REG_ENTRY_GET(rv, dev_id, GBL_INT_MASK1, 0, (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (intr_mask & FAL_SWITCH_INTR_LINK_STATUS) + { + reg |= DESS_SWITCH_INT_PHY_INT; + } + else + { + reg &= (~DESS_SWITCH_INT_PHY_INT); + } + + HSL_REG_ENTRY_SET(rv, dev_id, GBL_INT_MASK1, 0, (a_uint8_t *) (®), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_intr_mask_get(a_uint32_t dev_id, a_uint32_t * intr_mask) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + *intr_mask = 0; + HSL_REG_ENTRY_GET(rv, dev_id, GBL_INT_MASK1, 0, (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (reg & DESS_SWITCH_INT_PHY_INT) + { + *intr_mask |= FAL_SWITCH_INTR_LINK_STATUS; + } + + return SW_OK; +} + +static sw_error_t +_dess_intr_status_get(a_uint32_t dev_id, a_uint32_t * intr_status) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + *intr_status = 0; + HSL_REG_ENTRY_GET(rv, dev_id, GBL_INT_STATUS1, 0, (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (reg & DESS_SWITCH_INT_PHY_INT) + { + *intr_status |= FAL_SWITCH_INTR_LINK_STATUS; + } + + return SW_OK; +} + +static sw_error_t +_dess_intr_status_clear(a_uint32_t dev_id, a_uint32_t intr_status) +{ + sw_error_t rv; + a_uint32_t reg; + + reg = 0; + if (intr_status & FAL_SWITCH_INTR_LINK_STATUS) + { + reg |= DESS_SWITCH_INT_PHY_INT; + } + + HSL_REG_ENTRY_SET(rv, dev_id, GBL_INT_STATUS1, 0, (a_uint8_t *) (®), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_port_link_intr_mask_set(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t intr_mask_flag) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + + if (NULL == phy_drv->phy_intr_mask_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_intr_mask_set(dev_id, phy_id, intr_mask_flag); + return rv; +} + +static sw_error_t +_dess_port_link_intr_mask_get(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t * intr_mask_flag) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + + if (NULL == phy_drv->phy_intr_mask_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_intr_mask_get(dev_id, phy_id, intr_mask_flag); + + return rv; +} + +static sw_error_t +_dess_port_link_intr_status_get(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t * intr_mask_flag) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + + if (NULL == phy_drv->phy_intr_status_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_intr_status_get(dev_id, phy_id, intr_mask_flag); + return rv; +} + +static sw_error_t +_dess_intr_mask_mac_linkchg_set(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, GBL_INT_MASK1, 0, LINK_CHG_INT_M, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_FALSE == enable) + { + data &= (~((a_uint32_t) 0x1 << port_id)); + } + else if (A_TRUE == enable) + { + data |= (0x1 << port_id); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, GBL_INT_MASK1, 0, LINK_CHG_INT_M, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + + return rv; +} + + +static sw_error_t +_dess_intr_mask_mac_linkchg_get(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t reg = 0, field; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, GBL_INT_MASK1, 0, LINK_CHG_INT_M, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + field = reg & (0x1 << port_id); + if (field) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + + +static sw_error_t +_dess_intr_status_mac_linkchg_get(a_uint32_t dev_id, fal_pbmp_t* port_bitmap) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, GBL_INT_STATUS1, 0, LINK_CHG_INT_S, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + *port_bitmap = reg; + + return rv; + +} + +static sw_error_t +_dess_intr_status_mac_linkchg_clear(a_uint32_t dev_id) +{ + sw_error_t rv; + a_uint32_t reg; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, GBL_INT_STATUS1, 0, LINK_CHG_INT_S, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + HSL_REG_FIELD_SET(rv, dev_id, GBL_INT_STATUS1, 0, LINK_CHG_INT_S, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + return rv; + +} + +static sw_error_t +_dess_global_macaddr_set(a_uint32_t dev_id, fal_mac_addr_t * addr) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + + HSL_DEV_ID_CHECK(dev_id); + + reg = (addr->uc[4] << 8) | addr->uc[5]; + HSL_REG_ENTRY_SET(rv, dev_id, GLOBAL_MAC_ADDR0, 0, (a_uint8_t *) (®), sizeof (a_uint32_t)); + reg = (addr->uc[0] << 24) | (addr->uc[1] << 16) | (addr->uc[2] << 8) | addr->uc[3]; + HSL_REG_ENTRY_SET(rv, dev_id, GLOBAL_MAC_ADDR1, 0, (a_uint8_t *) (®), sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_dess_global_macaddr_get(a_uint32_t dev_id, fal_mac_addr_t * addr) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + + HSL_DEV_ID_CHECK(dev_id); + HSL_REG_ENTRY_GET(rv, dev_id, GLOBAL_MAC_ADDR0, 0, (a_uint8_t *) (®), sizeof (a_uint32_t)); + addr->uc[4] = (reg >> 8) & 0xff; + addr->uc[5] = reg & 0xff; + HSL_REG_ENTRY_GET(rv, dev_id, GLOBAL_MAC_ADDR1, 0, (a_uint8_t *) (®), sizeof (a_uint32_t)); + addr->uc[0] = (reg >> 24) & 0xff; + addr->uc[1] = (reg >> 16) & 0xff; + addr->uc[2] = (reg >> 8) & 0xff; + addr->uc[3] = reg; + + return rv; +} + +static sw_error_t +_dess_lldp_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FRAME_ACK_CTL1, 0, LLDP_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_lldp_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FRAME_ACK_CTL1, 0, LLDP_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_frame_crc_reserve_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, MAX_SIZE, 0, CRC_RESERVE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_frame_crc_reserve_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, MAX_SIZE, 0, CRC_RESERVE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + + +/** + * @brief Set max frame size which device can received on a particular device. + * @details Comments: + * The granularity of packets size is byte. + * @param[in] dev_id device id + * @param[in] size packet size + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_frame_max_size_set(a_uint32_t dev_id, a_uint32_t size) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_frame_max_size_set(dev_id, size); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get max frame size which device can received on a particular device. + * @details Comments: + * The unit of packets size is byte. + * @param[in] dev_id device id + * @param[out] size packet size + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_frame_max_size_get(a_uint32_t dev_id, a_uint32_t * size) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_frame_max_size_get(dev_id, size); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flooding status of unknown unicast packets on a particular port. + * @details Comments: + * If enable unknown unicast packets filter on one port then unknown + * unicast packets can't flood out from this port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_unk_uc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_unk_uc_filter_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get flooding status of unknown unicast packets on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_unk_uc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_unk_uc_filter_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flooding status of unknown multicast packets on a particular port. + * @details Comments: + * If enable unknown multicast packets filter on one port then unknown + * multicast packets can't flood out from this port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_unk_mc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_unk_mc_filter_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** @brief Get flooding status of unknown multicast packets on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_unk_mc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_unk_mc_filter_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flooding status of broadcast packets on a particular port. + * @details Comments: + * If enable unknown multicast packets filter on one port then unknown + * multicast packets can't flood out from this port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_bc_filter_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_bc_filter_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** @brief Get flooding status of broadcast packets on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_bc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_bc_filter_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set cpu port status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_cpu_port_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_cpu_port_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get cpu port status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_cpu_port_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_cpu_port_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set pppoe packets forwarding command on a particular device. + * @details comments: + * Particular device may only support parts of forwarding commands. + * Ihis operation will take effect only after enabling pppoe packets + * hardware acknowledgement + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_pppoe_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_pppoe_cmd_set(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get pppoe packets forwarding command on a particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_pppoe_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_pppoe_cmd_get(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set pppoe packets hardware acknowledgement status on particular device. + * @details comments: + * Particular device may only support parts of pppoe packets. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_pppoe_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_pppoe_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get pppoe packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_pppoe_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_pppoe_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dhcp packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_dhcp_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_misc_property_set(dev_id, port_id, enable, DHCP_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dhcp packets hardware acknowledgement status on particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_dhcp_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_misc_property_get(dev_id, port_id, enable, DHCP_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set arp packets forwarding command on a particular device. + * @details comments: + * Particular device may only support parts of forwarding commands. + * Ihis operation will take effect only after enabling arp packets + * hardware acknowledgement + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_arp_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_arp_cmd_set(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp packets forwarding command on a particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_arp_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_arp_cmd_get(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set eapol packets forwarding command on a particular device. + * @details comments: + * Particular device may only support parts of forwarding commands. + * Ihis operation will take effect only after enabling eapol packets + * hardware acknowledgement + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_eapol_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_eapol_cmd_set(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get eapol packets forwarding command on a particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_eapol_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_eapol_cmd_get(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add a pppoe session entry to a particular device. + * The entry only for pppoe/ppp header remove. + * @param[in] dev_id device id + * @param[in] session_tbl pppoe session table + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_pppoe_session_table_add(a_uint32_t dev_id, + fal_pppoe_session_t * session_tbl) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_pppoe_session_add(dev_id, session_tbl); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a pppoe session entry from a particular device. + * The entry only for pppoe/ppp header remove. + * @param[in] dev_id device id + * @param[in] session_tbl pppoe session table + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_pppoe_session_table_del(a_uint32_t dev_id, + fal_pppoe_session_t * session_tbl) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_pppoe_session_del(dev_id, session_tbl); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get a pppoe session entry from a particular device. + * The entry only for pppoe/ppp header remove. + * @param[in] dev_id device id + * @param[out] session_tbl pppoe session table + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_pppoe_session_table_get(a_uint32_t dev_id, + fal_pppoe_session_t * session_tbl) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_pppoe_session_get(dev_id, session_tbl); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set a pppoe session id entry to a particular device. + * The entry only for pppoe/ppp header add. + * @param[in] dev_id device id + * @param[in] session_tbl pppoe session table + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_pppoe_session_id_set(a_uint32_t dev_id, a_uint32_t index, + a_uint32_t id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_pppoe_session_id_set(dev_id, index, id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get a pppoe session id entry from a particular device. + * The entry only for pppoe/ppp header add. + * @param[in] dev_id device id + * @param[out] session_tbl pppoe session table + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_pppoe_session_id_get(a_uint32_t dev_id, a_uint32_t index, + a_uint32_t * id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_pppoe_session_id_get(dev_id, index, id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set eapol packets hardware acknowledgement status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_eapol_status_set(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_misc_property_set(dev_id, port_id, enable, EAPOL_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get eapol packets hardware acknowledgement status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_eapol_status_get(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_misc_property_get(dev_id, port_id, enable, EAPOL_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set rip v1 packets hardware acknowledgement status on a particular port. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ripv1_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ripv1_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get rip v1 packets hardware acknowledgement status on a particular port. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ripv1_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ripv1_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set arp req packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_arp_req_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_misc_property_set(dev_id, port_id, enable, + ARP_REQ_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp req packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_arp_req_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_misc_property_get(dev_id, port_id, enable, + ARP_REQ_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set arp ack packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_arp_ack_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_misc_property_set(dev_id, port_id, enable, + ARP_ACK_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp ack packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_arp_ack_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_misc_property_get(dev_id, port_id, enable, + ARP_ACK_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set switch interrupt mask on one particular device. + * @param[in] dev_id device id + * @param[in] intr_mask mask + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_intr_mask_set(a_uint32_t dev_id, a_uint32_t intr_mask) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_intr_mask_set(dev_id, intr_mask); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get switch interrupt mask on one particular device. + * @param[in] dev_id device id + * @param[in] intr_mask mask + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_intr_mask_get(a_uint32_t dev_id, a_uint32_t * intr_mask) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_intr_mask_get(dev_id, intr_mask); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get switch interrupt status on one particular device. + * @param[in] dev_id device id + * @param[in] intr_status status + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_intr_status_get(a_uint32_t dev_id, a_uint32_t * intr_status) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_intr_status_get(dev_id, intr_status); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Clear switch interrupt status on one particular device. + * @param[in] dev_id device id + * @param[in] intr_status status + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_intr_status_clear(a_uint32_t dev_id, a_uint32_t intr_status) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_intr_status_clear(dev_id, intr_status); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set link interrupt mask on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] intr_mask_flag interrupt mask + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_intr_port_link_mask_set(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t intr_mask_flag) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _dess_port_link_intr_mask_set(dev_id, port_id, intr_mask_flag); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get link interrupt mask on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] intr_mask_flag interrupt mask + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_intr_port_link_mask_get(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t * intr_mask_flag) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_link_intr_mask_get(dev_id, port_id, intr_mask_flag); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get link interrupt status on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] intr_mask_flag interrupt mask + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_intr_port_link_status_get(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t * intr_mask_flag) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_link_intr_status_get(dev_id, port_id, intr_mask_flag); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set mac link change interrupt mask on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable ports intr mask enabled + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_intr_mask_mac_linkchg_set(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t enable) +{ + sw_error_t rv; + FAL_API_LOCK; + rv = _dess_intr_mask_mac_linkchg_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mac link change interrupt mask on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] port interrupt mask or not + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_intr_mask_mac_linkchg_get(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _dess_intr_mask_mac_linkchg_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get link change interrupt status for all ports. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] ports bitmap which generates interrupt + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_intr_status_mac_linkchg_get(a_uint32_t dev_id, fal_pbmp_t* port_bitmap) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _dess_intr_status_mac_linkchg_get(dev_id, port_bitmap); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set cpu vid enable status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_cpu_vid_en_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_cpu_vid_en_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get cpu vid enable status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_cpu_vid_en_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_cpu_vid_en_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set RM_RTD_PPPOE_EN status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_rtd_pppoe_en_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_rtd_pppoe_en_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get RM_RTD_PPPOE_EN status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_rtd_pppoe_en_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_rtd_pppoe_en_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Clear link change interrupt status for all ports. + * @param[in] dev_id device id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_intr_status_mac_linkchg_clear(a_uint32_t dev_id) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _dess_intr_status_mac_linkchg_clear(dev_id); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set global macaddr on particular device. + * @param[in] dev_id device id + * @param[in] addr addr + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_global_macaddr_set(a_uint32_t dev_id, fal_mac_addr_t * addr) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_global_macaddr_set(dev_id, addr); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get global macaddr on particular device. + * @param[in] dev_id device id + * @param[out] addr addr + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_global_macaddr_get(a_uint32_t dev_id, fal_mac_addr_t * addr) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_global_macaddr_get(dev_id, addr); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set lldp packets hardware acknowledgement status on particular device. + * @details comments: + * Particular device may only support parts of pppoe packets. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_lldp_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_lldp_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get lldp packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_lldp_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_lldp_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set frame crc reserve enable on particular device. + * @details comments: + * Particular device may only support parts of pppoe packets. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_frame_crc_reserve_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_frame_crc_reserve_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get frame crc reserve enable on particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_frame_crc_reserve_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_frame_crc_reserve_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + + +sw_error_t +dess_misc_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->frame_max_size_set = dess_frame_max_size_set; + p_api->frame_max_size_get = dess_frame_max_size_get; + p_api->port_unk_uc_filter_set = dess_port_unk_uc_filter_set; + p_api->port_unk_uc_filter_get = dess_port_unk_uc_filter_get; + p_api->port_unk_mc_filter_set = dess_port_unk_mc_filter_set; + p_api->port_unk_mc_filter_get = dess_port_unk_mc_filter_get; + p_api->port_bc_filter_set = dess_port_bc_filter_set; + p_api->port_bc_filter_get = dess_port_bc_filter_get; + p_api->cpu_port_status_set = dess_cpu_port_status_set; + p_api->cpu_port_status_get = dess_cpu_port_status_get; + p_api->pppoe_cmd_set = dess_pppoe_cmd_set; + p_api->pppoe_cmd_get = dess_pppoe_cmd_get; + p_api->pppoe_status_set = dess_pppoe_status_set; + p_api->pppoe_status_get = dess_pppoe_status_get; + p_api->port_dhcp_set = dess_port_dhcp_set; + p_api->port_dhcp_get = dess_port_dhcp_get; + p_api->arp_cmd_set = dess_arp_cmd_set; + p_api->arp_cmd_get = dess_arp_cmd_get; + p_api->eapol_cmd_set = dess_eapol_cmd_set; + p_api->eapol_cmd_get = dess_eapol_cmd_get; + p_api->pppoe_session_table_add = dess_pppoe_session_table_add; + p_api->pppoe_session_table_del = dess_pppoe_session_table_del; + p_api->pppoe_session_table_get = dess_pppoe_session_table_get; + p_api->pppoe_session_id_set = dess_pppoe_session_id_set; + p_api->pppoe_session_id_get = dess_pppoe_session_id_get; + p_api->eapol_status_set = dess_eapol_status_set; + p_api->eapol_status_get = dess_eapol_status_get; + p_api->ripv1_status_set = dess_ripv1_status_set; + p_api->ripv1_status_get = dess_ripv1_status_get; + p_api->port_arp_req_status_set = dess_port_arp_req_status_set; + p_api->port_arp_req_status_get = dess_port_arp_req_status_get; + p_api->port_arp_ack_status_set = dess_port_arp_ack_status_set; + p_api->port_arp_ack_status_get = dess_port_arp_ack_status_get; + p_api->intr_mask_set = dess_intr_mask_set; + p_api->intr_mask_get = dess_intr_mask_get; + p_api->intr_status_get = dess_intr_status_get; + p_api->intr_status_clear = dess_intr_status_clear; + p_api->intr_port_link_mask_set = dess_intr_port_link_mask_set; + p_api->intr_port_link_mask_get = dess_intr_port_link_mask_get; + p_api->intr_port_link_status_get = dess_intr_port_link_status_get; + p_api->intr_mask_mac_linkchg_set = dess_intr_mask_mac_linkchg_set; + p_api->intr_mask_mac_linkchg_get = dess_intr_mask_mac_linkchg_get; + p_api->intr_status_mac_linkchg_get = dess_intr_status_mac_linkchg_get; + p_api->cpu_vid_en_set = dess_cpu_vid_en_set; + p_api->cpu_vid_en_get = dess_cpu_vid_en_get; + p_api->rtd_pppoe_en_set = dess_rtd_pppoe_en_set; + p_api->rtd_pppoe_en_get = dess_rtd_pppoe_en_get; + p_api->intr_status_mac_linkchg_clear = dess_intr_status_mac_linkchg_clear; + p_api->global_macaddr_set = dess_global_macaddr_set; + p_api->global_macaddr_get = dess_global_macaddr_get; + p_api->lldp_status_set = dess_lldp_status_set; + p_api->lldp_status_get = dess_lldp_status_get; + p_api->frame_crc_reserve_set = dess_frame_crc_reserve_set; + p_api->frame_crc_reserve_get = dess_frame_crc_reserve_get; + + } +#endif + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_multicast_acl.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_multicast_acl.c new file mode 100755 index 000000000..087395c67 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_multicast_acl.c @@ -0,0 +1,1030 @@ +/* + * Copyright (c) 2014, 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. + */ + + + +#include "fal_nat.h" +#include "fal_ip.h" +#include "hsl_api.h" +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "dess_igmp.h" +#include "dess_reg.h" +#include "dess_acl.h" +#include "fal_multi.h" +#include "sal/os/aos_lock.h" + +#if 0 +/** + * I/F prototype for complete igmpv3 & mldv2 support + */ + +/*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; +} fal_igmp_sg_entry_t; + +/** + * @brief set PortMap of IGMP sg entry. + * search entry according to source/group address, + * update PortMap if SG entry is found, otherwise create a new sg entry. + * @param[in] dev_id device id + * @param[in-out] entry SG entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_igmp_sg_entry_set(a_uint32_t dev_id, fal_igmp_sg_entry_t * entry); + +/** + * @brief clear PortMap of IGMP sg entry. + * search entry according to source/group address, + * update PortMap if SG entry is found, delete the entry in case PortMap was 0. + * SW_NOT_FOUND will be returned in case search failed. + * @param[in] dev_id device id + * @param[in-out] entry SG entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_igmp_sg_entry_clear(a_uint32_t dev_id, fal_igmp_sg_entry_t * entry); + +#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 1 +#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; +#endif + +static a_uint32_t mul_rule_nr=1; + +void +dess_multicast_init(a_uint32_t dev_id); + +HSL_LOCAL sw_error_t multi_portmap_aclreg_set(a_uint32_t pos, fal_igmp_sg_entry_t * entry); + +static multi_acl_info_t multi_acl_info[FAL_IGMP_SG_ENTRY_MAX]; +static multi_acl_info_t multi_acl_group[FAL_IGMP_SG_ENTRY_MAX]; + +static int ip6_addr_is_null(fal_ip6_addr_t *ip6) +{ + if (NULL == ip6) + { + aos_printk("Invalid ip6 address\n"); + return -1; + } + if(0 == ip6->ul[0] && 0 == ip6->ul[1] && 0 == ip6->ul[2] && 0 == ip6->ul[3]) + return 1; + else + return 0; +} +static int multi_source_is_null(fal_igmp_sg_addr_t *s) +{ + if (NULL == s) + { + aos_printk("Invalid source address\n"); + return -1; + } + if(0 == s->type && 0==s->u.ip4_addr) + return 1; + if(1 == s->type && 1 == ip6_addr_is_null(&(s->u.ip6_addr))) + return 1; + + return 0; +} + +HSL_LOCAL int iterate_multicast_acl_rule(int list_id, int start_n) +{ + a_uint32_t dev_id=0; + a_uint32_t rule_id; + sw_error_t ret; + fal_acl_rule_t rule= {0}; + + if(start_n>=FAL_IGMP_SG_ENTRY_MAX || start_n < 0) + { + return -1; + } + + for(rule_id=0; rule_id=FAL_IGMP_SG_ENTRY_MAX) + { + return -1; + } + + multi_acl_info[rule_id+start_n].index = rule_id; // consider here... index is NOT related start_n + //MULTI_DEBUG("normal query1: rule dest_ip4_val=%x, src ip4=%x, dst_ip6=%x, ports=%x\n", + //rule.dest_ip4_val, rule.src_ip4_val, rule.dest_ip6_val.ul[0], rule.ports); + + if(rule.dest_ip4_val !=0 && ip6_addr_is_null(&rule.dest_ip6_val)) //only ip4 + { + multi_acl_info[rule_id+start_n].entry.group.type = FAL_ADDR_IPV4; + multi_acl_info[rule_id+start_n].entry.source.type = FAL_ADDR_IPV4; + multi_acl_info[rule_id+start_n].entry.group.u.ip4_addr = rule.dest_ip4_val; + multi_acl_info[rule_id+start_n].entry.source.u.ip4_addr = rule.src_ip4_val; + multi_acl_info[rule_id+start_n].entry.port_map= rule.ports; + } + else if(rule.dest_ip4_val ==0 && !ip6_addr_is_null(&rule.dest_ip6_val)) //only ip6 + { + multi_acl_info[rule_id+start_n].entry.group.type = FAL_ADDR_IPV6; + multi_acl_info[rule_id+start_n].entry.source.type = FAL_ADDR_IPV6; + memcpy(&(multi_acl_info[rule_id+start_n].entry.group.u.ip6_addr), &(rule.dest_ip6_val), sizeof(rule.dest_ip6_val)); + memcpy(&(multi_acl_info[rule_id+start_n].entry.source.u.ip6_addr), &(rule.src_ip6_val), sizeof(rule.src_ip6_val)); + multi_acl_info[rule_id+start_n].entry.port_map= rule.ports; + } + if (FAL_FIELD_FLG_TST(rule.field_flg, FAL_ACL_FIELD_MAC_VID)) + { + multi_acl_info[rule_id+start_n].entry.vlan_id = rule.vid_val; + } + else + { + multi_acl_info[rule_id+start_n].entry.vlan_id = 0xffff; + } + } + + return rule_id+start_n; +} +/* +** Iterate the total 32 multicast ACL entries. + After the function completes: + 1. Stores all multicast related ACL rules in multi_acl_info[32] + 2. return the number of multicast related ACL rules +*/ +HSL_LOCAL a_uint32_t dess_multicast_acl_query(void) +{ + int start_n; + int total_n; + //a_uint32_t i; + + start_n = iterate_multicast_acl_rule(FAL_ACL_LIST_MULTICAST, 0); + if(-1 == start_n) + aos_printk("ACL rule1 is FULL\n"); + total_n = iterate_multicast_acl_rule(FAL_ACL_LIST_MULTICAST+1, start_n); + if(-1 == total_n) + aos_printk("ACL rule2 is FULL\n"); + + MULTI_DEBUG("KKK, the total ACL rule number is %d, (G,S) number=%d\n", total_n, start_n); + /* + for(i=0;i>6)&0x3) == 0x3) || (((msk_valid>>6)&0x3) == 0x2)) + { + rv = multi_portmap_aclreg_set(i, entry); + break; + } + else if ((((msk_valid>>6)&0x3)) == 0x0 || (((msk_valid>>6)&0x3) == 0x1)) + { + rv = multi_portmap_aclreg_set(i, entry); + continue; + } + else + { + aos_printk("The rule valid bit:6 7 is wrong!!!"); + break; + } + } + return rv; +} +HSL_LOCAL sw_error_t multi_portmap_aclreg_set(a_uint32_t pos, fal_igmp_sg_entry_t * entry) +{ + a_uint32_t i, base, addr; + a_uint32_t dev_id=0; + sw_error_t rv; + a_uint32_t act[3]= {0}; + fal_pbmp_t pm; + + pm = entry->port_map; + + base = DESS_FILTER_ACT_ADDR + (pos << 4); + for (i = 0; i < 3; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&act[i]), + sizeof (a_uint32_t)); + //MULTI_DEBUG("2:Get register value 0x%x =%x\n", addr, act[i]); + SW_RTN_ON_ERROR(rv); + } + + act[1] &= ~(0x7<<29); // clear the high 3 bits + act[1] |= (pm&0x7)<<29; //the low 3 bits of pm means redirect port 0,1,2 + + /* New modification: update acl ACTION register from DENY to redirect */ + if (((act[2]>>6)&0x7) == 0x7) //DENY mode + { + if(pm) + { + act[2] &= ~(0x7<<6);//clear DENY bits + act[2] |= (0x1<<4); //DES_PORT_EN set 1, enable + } + } + else if (((act[2]>>4)&0x1) == 0x1) //redirect mode + { + if(pm==0) + { + act[2] &= ~(0x1<<4);//clear redirect bits + act[2] |= (0x7<<6); //set to DENY + } + } + + act[2] &= ~0xf; //clear the low 4 bits of port 3,4,5,6 + act[2] |= (pm>>3)&0xf; + + addr = base + (1<<2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&act[1]), sizeof (a_uint32_t)); + addr = base + (2<<2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&act[2]), sizeof (a_uint32_t)); + MULTI_DEBUG("pos=%d, before sync portmap, the new act=%x %x\n", pos, act[1],act[2]); + if((rv = dess_acl_rule_sync_multi_portmap(dev_id, pos, act)) < 0) + aos_printk("Sync multicast portmap error\n"); + return rv; +} + +HSL_LOCAL int multi_get_dp(void) +{ + a_uint32_t addr; + a_uint32_t dev_id=0; + sw_error_t rv; + int val=0; + + addr = 0x624;//GLOBAL_FW_CTRL1 + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + if (rv != SW_OK) + aos_printk("Get entry value error\n"); + + val = (val>>24)&0x7f; //30:24, IGMP_JOIN_LEAVE_DP + + return val; +} +static int old_bind_p=-1; +HSL_LOCAL int multi_acl_bind(void) +{ + int bind_p; + int i; + + bind_p = multi_get_dp(); + if(bind_p == old_bind_p) + return 0; + old_bind_p = bind_p; + + for(i=0; i<7; i++) + { + dess_acl_list_unbind(0, FAL_ACL_LIST_MULTICAST, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, i); + dess_acl_list_unbind(0, FAL_ACL_LIST_MULTICAST+1, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, i); + } + + if(bind_p==0) + { + for(i=0; i<7; i++) + { + dess_acl_list_bind(0, FAL_ACL_LIST_MULTICAST, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, i); + dess_acl_list_bind(0, FAL_ACL_LIST_MULTICAST+1, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, i); + } + } + else + { + for(i=0; i<7; i++) + if((bind_p>>i) &0x1) + { + dess_acl_list_bind(0, FAL_ACL_LIST_MULTICAST, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, i); + dess_acl_list_bind(0, FAL_ACL_LIST_MULTICAST+1, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, i); + } + else + continue; + } + return 0; +} +/* +** Only update the related portmap from the privious input. +*/ +HSL_LOCAL sw_error_t dess_multicast_acl_update( int list_id, int acl_index, fal_igmp_sg_entry_t * entry, int action) +{ + a_uint32_t dev_id=0; + a_uint32_t rule_pos; + sw_error_t rv = SW_OK; + + if(acl_index<0) + { + aos_printk("Something is wrong...\n"); + return SW_FAIL; + } + + rule_pos = dess_acl_rule_get_offset(dev_id, list_id, multi_acl_group[acl_index].index); + if(MULT_ACTION_SET == action) + { + multi_acl_group[acl_index].entry.port_map |= entry->port_map; + if(entry->port_map == 0) + { + multi_acl_group[acl_index].entry.port_map = 0; + } + } + else if(MULT_ACTION_CLEAR == action) + multi_acl_group[acl_index].entry.port_map &= ~(entry->port_map); + + rv = multi_portmap_aclreg_set_all(rule_pos, &multi_acl_group[acl_index].entry); + + multi_acl_bind(); //Here need extra bind since IGMP join/leave would happen + return rv; +} + +HSL_LOCAL sw_error_t dess_multicast_acl_del(int list_id, int index) +{ + sw_error_t rv; + int rule_id; + + rule_id = multi_acl_group[index].index; + + rv = dess_acl_rule_delete(0, list_id, rule_id, 1); + multi_acl_bind(); //Here need extra bind since IGMP join/leave would happen + return rv; +} + +/* +** Add new acl rule with parameters: DIP, SIP, redirect port. +*/ +HSL_LOCAL sw_error_t dess_multicast_acl_add(int list_id, fal_igmp_sg_entry_t * entry) +{ + sw_error_t val; + a_uint32_t pos; + fal_acl_rule_t acl= {0}; + + /* IPv4 multicast */ + if( entry->group.type == FAL_ADDR_IPV4 ) + { + MULTI_DEBUG("KKK1, group[%d][%x], source[%d][%x]\n",entry->group.type, + entry->group.u.ip4_addr, entry->source.type, entry->source.u.ip4_addr); + + acl.rule_type = FAL_ACL_RULE_IP4; + + if(entry->group.u.ip4_addr!= 0) + { + acl.dest_ip4_val = entry->group.u.ip4_addr; + acl.dest_ip4_mask = 0xffffffff;//e->ip.dmsk.s_addr; + FAL_FIELD_FLG_SET(acl.field_flg, FAL_ACL_FIELD_IP4_DIP); + } + if(entry->source.u.ip4_addr!= 0) + { + acl.src_ip4_val = entry->source.u.ip4_addr; + acl.src_ip4_mask = 0xffffffff;//e->ip.smsk.s_addr; + FAL_FIELD_FLG_SET(acl.field_flg, FAL_ACL_FIELD_IP4_SIP); + } + if( entry->port_map==0 ) + FAL_ACTION_FLG_SET ( acl.action_flg, FAL_ACL_ACTION_DENY); + else + //FAL_FIELD_FLG_SET(acl.field_flg, FAL_ACL_FIELD_INVERSE_ALL); + FAL_ACTION_FLG_SET ( acl.action_flg, FAL_ACL_ACTION_PERMIT ); + + /* Be careful, _dess_acl_action_parse() will block FAL_ACL_ACTION_DENY action, So we change it. */ + if( entry->port_map ) + { + FAL_ACTION_FLG_SET(acl.action_flg, FAL_ACL_ACTION_REDPT); + acl.ports = entry->port_map; + } + } + else if( entry->group.type == FAL_ADDR_IPV6 ) + { + MULTI_DEBUG("KKK2, group[%d][%x], source[%d][%x], pm=%x\n",entry->group.type, + entry->group.u.ip6_addr.ul[0], entry->source.type, entry->source.u.ip6_addr.ul[0], entry->port_map); + + acl.rule_type = FAL_ACL_RULE_IP6; + + if(!ip6_addr_is_null(&(entry->group.u.ip6_addr))) + { + memcpy(&acl.dest_ip6_val, &(entry->group.u.ip6_addr), sizeof(entry->group.u.ip6_addr)); + acl.dest_ip6_mask.ul[0] = 0xffffffff; + acl.dest_ip6_mask.ul[1] = 0xffffffff; + acl.dest_ip6_mask.ul[2] = 0xffffffff; + acl.dest_ip6_mask.ul[3] = 0xffffffff; + FAL_FIELD_FLG_SET(acl.field_flg, FAL_ACL_FIELD_IP6_DIP); + } + if(!ip6_addr_is_null(&(entry->source.u.ip6_addr))) + { + memcpy(&acl.src_ip6_val, &(entry->source.u.ip6_addr), sizeof(entry->source.u.ip6_addr)); + acl.src_ip6_mask.ul[0] = 0xffffffff; + acl.src_ip6_mask.ul[1] = 0xffffffff; + acl.src_ip6_mask.ul[2] = 0xffffffff; + acl.src_ip6_mask.ul[3] = 0xffffffff; + FAL_FIELD_FLG_SET(acl.field_flg, FAL_ACL_FIELD_IP6_SIP); + } + + if( entry->port_map==0 ) + FAL_ACTION_FLG_SET ( acl.action_flg, FAL_ACL_ACTION_DENY); + else + //FAL_FIELD_FLG_SET(acl.field_flg, FAL_ACL_FIELD_INVERSE_ALL); + FAL_ACTION_FLG_SET ( acl.action_flg, FAL_ACL_ACTION_PERMIT ); + + /* Be careful, _dess_acl_action_parse() will block FAL_ACL_ACTION_DENY action, So we change it. */ + if( entry->port_map ) + { + FAL_ACTION_FLG_SET(acl.action_flg, FAL_ACL_ACTION_REDPT); + acl.ports = entry->port_map; + } + } + + if (entry->vlan_id < 4096) + { + FAL_FIELD_FLG_SET(acl.field_flg, FAL_ACL_FIELD_MAC_VID); + acl.vid_val = entry->vlan_id; + acl.vid_op = FAL_ACL_FIELD_MASK; + acl.vid_mask = 0xfff; + } + + pos = dess_multicast_acl_total_n(list_id); + + MULTI_DEBUG("In dess_multicast_acl_add, list_id=%d, rule_id=%d\n", list_id, pos); + val = dess_acl_rule_add(0, list_id, pos, mul_rule_nr, &acl); + + multi_acl_bind(); + + return val; +} + + +HSL_LOCAL int iterate_multicast_acl_group(a_uint32_t number, fal_igmp_sg_entry_t * entry) +{ + int count=0; + int i; + + if (number == 0) + return 0; //no any ACL rules based the query + + for(i=0; igroup.type, entry->group.u.ip6_addr.ul[0], entry->port_map);*/ + + if(0 == memcmp(&(multi_acl_info[i].entry.group), &(entry->group), sizeof(entry->group))) + { + memcpy(&multi_acl_group[count], &multi_acl_info[i], sizeof(multi_acl_info[i])); + count++;//return the real number of multi_acl_group[] + MULTI_DEBUG("in iterate_multicast_acl_group, count=%d, i=%d\n", count, i); + } + } + + return count; +} + +HSL_LOCAL int mult_acl_has_entry(fal_igmp_sg_addr_t * group, fal_igmp_sg_addr_t *source) +{ + int rule_id; + int ret = 0; +#if 0 + if(source != NULL) + { + MULTI_DEBUG("new group[%d]= %x %x %x %x, new source[%d]=%x %x %x %x\n", + group->type, group->u.ip6_addr.ul[0], group->u.ip6_addr.ul[1], group->u.ip6_addr.ul[2], group->u.ip6_addr.ul[3], + source->type, source->u.ip6_addr.ul[0], source->u.ip6_addr.ul[1], source->u.ip6_addr.ul[2], source->u.ip6_addr.ul[3]); + + MULTI_DEBUG("old group[%d]= %x %x %x %x, old source[%d]=%x %x %x %x\n", + multi_acl_group[0].entry.group.type, multi_acl_group[0].entry.group.u.ip6_addr.ul[0], + multi_acl_group[0].entry.group.u.ip6_addr.ul[1], multi_acl_group[0].entry.group.u.ip6_addr.ul[2], multi_acl_group[0].entry.group.u.ip6_addr.ul[3], + multi_acl_group[0].entry.source.type, multi_acl_group[0].entry.source.u.ip6_addr.ul[0], + multi_acl_group[0].entry.source.u.ip6_addr.ul[1], multi_acl_group[0].entry.source.u.ip6_addr.ul[2], multi_acl_group[0].entry.source.u.ip6_addr.ul[3]); + } +#endif + if(source == NULL) + { + for(rule_id=0; rule_idport_map, g_source->source.u.ip4_addr, g_source->group.u.ip4_addr, + g_star->port_map, g_star->source.u.ip4_addr,g_star->group.u.ip4_addr);*/ + + if(multi_source_is_null(&(g_star->source))) + { + if((g_source->port_map|g_star->port_map) == g_star->port_map) + { + return 0; + } + } + + return 1; +} + + +HSL_LOCAL int portmap_clear_type(int count, int index, fal_pbmp_t portmap) +{ + if(count>=0 && index0; this means there're (G,*) and (G,S) + { + //if the new clear portmap will cause (G,S)=(G,*), Delete the (G,S) + if((multi_acl_group[index].entry.port_map & (~portmap)) == multi_acl_group[count].entry.port_map) + return 1; //delete + + + //The following means there must be at least one bit clear wrong. Clear the (G,*) portmap. + if( ((multi_acl_group[index].entry.port_map & (~portmap)) & (multi_acl_group[count].entry.port_map)) + != (multi_acl_group[count].entry.port_map)) + return 0; + + return 2; //Normal update + } + return 0; +} +sw_error_t dess_igmp_sg_entry_set(a_uint32_t dev_id, fal_igmp_sg_entry_t * entry) +{ + int number, count; + int new_index=0; + sw_error_t rv; + int action = MULT_ACTION_SET; + int i=0; + + HSL_API_LOCK; + (void)dess_multicast_init(0); + aos_mem_zero(multi_acl_info, FAL_IGMP_SG_ENTRY_MAX * sizeof (multi_acl_info_t)); + aos_mem_zero(multi_acl_group, FAL_IGMP_SG_ENTRY_MAX * sizeof (multi_acl_info_t)); + MULTI_DEBUG("Before query: group=%x, source=%x, portmap=%x\n", entry->group.u.ip4_addr, entry->source.u.ip4_addr, entry->port_map); + //number is the total multicast ACL rules amount, stores in multi_acl_info[]; + number = dess_multicast_acl_query(); + + if(number > FAL_IGMP_SG_ENTRY_MAX) + return SW_FAIL; + //count the total specific multicast group ACL rules, stores in multi_acl_group[]; count <=number + count = iterate_multicast_acl_group(number, entry); + //new_index-1 is the found entry index in multi_acl_group[], the real index is [new_index-1], 0 means no entry + new_index = mult_acl_has_entry(&entry->group, &entry->source); + + MULTI_DEBUG("Start entry set: number=%d, count=%d, new_index=%d, pm=%x\n", number, count, new_index, entry->port_map); + if( 0==multi_source_is_null(&entry->source) ) // new entry is (G, S) + { + MULTI_DEBUG("the new entry is (G,S)\n"); + if(count>0 && 0 == portmap_valid(entry, &(multi_acl_group[count-1].entry))) //specfic group entry exist,(G,S) or (G,*) + { + //return SW_NO_CHANGE; // The new portmap is Not valid + MULTI_DEBUG("KKK, modified 1 !!!\n"); + } + + if(0 == new_index) //new entry, need add + { +#if 0 + /*The method: + 1. predict if the portmap should be modified. + 2. add new acl rule with new portmap value. + */ + if((tmp_index = mult_acl_has_entry(&entry->group, NULL))>0) // (G, *) entry exist + { + /*Here the update should new (G, S) OR orignal (G,*) portmap, + be careful, entry's portmap value will be modified, so I use tmp_entry. + */ + memcpy(tmp_entry, entry, sizeof(fal_igmp_sg_entry_t)); + MULTI_DEBUG("Here, (G,*) exist! tmp_index=%d\n", tmp_index); + sw_multicast_acl_update(FAL_ACL_LIST_MULTICAST+1, tmp_index-1, tmp_entry, action); + + dess_multicast_acl_add(FAL_ACL_LIST_MULTICAST, tmp_entry); + return SW_OK; + } +#endif + dess_multicast_acl_add(FAL_ACL_LIST_MULTICAST, entry); + MULTI_DEBUG("Here, need add (G, S), portmap=%x\n", entry->port_map); + return SW_OK; + } + else + { + //Here update Just: the old exist entry portmap OR the new entry portmap + dess_multicast_acl_update(FAL_ACL_LIST_MULTICAST, new_index-1, entry, action); + return SW_OK; + } + } //end of memcmp + else // new entry is (G, *) + { + if(0 == new_index) //new entry, need add + { + dess_multicast_acl_add(FAL_ACL_LIST_MULTICAST+1, entry); + rv = SW_OK; + } + else if(new_index > 0) // (G, *) entry exist? + { + //Update exist (G, *) portmap with new portmap + MULTI_DEBUG("(G,*) exist, before update, new_index=%d\n", new_index ); + dess_multicast_acl_update(FAL_ACL_LIST_MULTICAST+1, new_index-1, entry, action); + rv = SW_OK; + } + + if(new_index>0&&count>1) //(G,S*) and (G,*) exist, new entry is (G,*) + { + for(i=count-2; i>=0&&i0) //only exist (G,S*) orignally + { + for(i=count-1; i>=0&&iport_map); + dess_multicast_acl_del(FAL_ACL_LIST_MULTICAST, i); + rv = SW_NO_MORE; + } + else + { + MULTI_DEBUG("2:Start update all (G,S),i=%d, portmap=%x\n", i, entry->port_map); + //Update all (G,S) entry portmap with new(G, *) portmap + dess_multicast_acl_update(FAL_ACL_LIST_MULTICAST, i, entry, action); + rv = SW_OK; + } + } + } + } + HSL_API_UNLOCK; + return rv; +} + +sw_error_t dess_igmp_sg_entry_clear(a_uint32_t dev_id, fal_igmp_sg_entry_t * entry) +{ + a_uint32_t number, count; + int new_index=0; + sw_error_t rv = SW_OK; + int action= MULT_ACTION_CLEAR; + int i=0; + int pm_type; + + HSL_API_LOCK; + (void)dess_multicast_init(0); + aos_mem_zero(multi_acl_info, FAL_IGMP_SG_ENTRY_MAX * sizeof (multi_acl_info_t)); + aos_mem_zero(multi_acl_group, FAL_IGMP_SG_ENTRY_MAX * sizeof (multi_acl_info_t)); + //number is the total multicast ACL rules amount, stores in multi_acl_info[]; + number = dess_multicast_acl_query(); + if(number > FAL_IGMP_SG_ENTRY_MAX) + return SW_FAIL; + //count the total specific multicast group ACL rules, stores in multi_acl_group[]; count <=number + count = iterate_multicast_acl_group(number, entry); + if(count == 0) + return SW_OK; + //new_index-1 is the found entry index in multi_acl_group[] + new_index = mult_acl_has_entry(&entry->group, &entry->source); + + MULTI_DEBUG("Start entry clear: number=%d, count=%d, new_index=%d\n", number, count, new_index); + if(0 == new_index || new_index > FAL_IGMP_SG_ENTRY_MAX || count > FAL_IGMP_SG_ENTRY_MAX) //new entry, the user command is wrong + { + return SW_NO_SUCH; + } + + if( 0==multi_source_is_null(&entry->source) ) // new entry is (G, S) + { + if (portmap_null(new_index-1, entry->port_map)) + { + MULTI_DEBUG("KKK entry clear, new(G,S), with null portmap. \n"); + dess_multicast_acl_del(FAL_ACL_LIST_MULTICAST, new_index-1); + return SW_NO_MORE; + } + else + { + MULTI_DEBUG("KKK entry clear, new(G,S), with NOT null portmap. \n"); + /* If (G,*) doesn't exist, [count-1] is the last specfic group, maybe(G,*) */ + if(0 == multi_source_is_null(&(multi_acl_group[count-1].entry.source))) + { + dess_multicast_acl_update(FAL_ACL_LIST_MULTICAST, new_index-1, entry, action); + } + else //(G,*) exist + { + pm_type = portmap_clear_type(count-1, new_index-1, entry->port_map); + if(pm_type == 0) + return SW_NO_CHANGE; + else if(pm_type == 1) + { + dess_multicast_acl_del(FAL_ACL_LIST_MULTICAST, new_index-1); + return SW_NO_MORE; + } + else + { + //normal update; consider here...wangson + dess_multicast_acl_update(FAL_ACL_LIST_MULTICAST, new_index-1, entry, action); + } + } + } + return SW_OK; + } + else //clear entry is (G,*) + { + MULTI_DEBUG("Here, new_index[%d]>=0, new portmap to clear is %x\n", new_index, entry->port_map); + if (portmap_null(new_index-1, entry->port_map)) + { + dess_multicast_acl_del(FAL_ACL_LIST_MULTICAST+1, new_index-1); + rv = SW_NO_MORE; + } + else + { + MULTI_DEBUG("Update (G,*)!, new_index=%d, pm=%x\n", new_index, entry->port_map); + dess_multicast_acl_update(FAL_ACL_LIST_MULTICAST+1, new_index-1, entry, action); + } + MULTI_DEBUG("KKK, ready clear (G, S*), count=%d\n", count); +#if 0 + if(count>1) // (G, S*) entry exist, if count=1 here, only exist(G,*)entry + { + //count must >=2 + for(i=count-2; i>=0; i--) + { + if(portmap_null(i, entry->port_map)) + { + MULTI_DEBUG("portmap_null, i=%d\n", i); + dess_multicast_acl_del(FAL_ACL_LIST_MULTICAST, i); + rv = SW_NO_MORE; + } + else + { + //Update all (G,S) entry portmap with new(G, *) portmap + dess_multicast_acl_update(FAL_ACL_LIST_MULTICAST, i, entry, action); + rv = SW_OK; + } + } + } +#else + if(count>1) // (G, S*) entry exist, if count=1 here, only exist(G,*)entry + { + //count must >=2 + for(i=count-2; i>=0&&iport_map))) == + multi_acl_group[i].entry.port_map) + dess_multicast_acl_del(FAL_ACL_LIST_MULTICAST, i); + else + //Update all (G,S) entry portmap with new(G, *) portmap + dess_multicast_acl_update(FAL_ACL_LIST_MULTICAST, i, entry, action); + rv = SW_OK; + } + } +#endif + } + HSL_API_UNLOCK; + return rv; +} + +static void +print_ip4addr(char * param_name, a_uint32_t * buf, + a_uint32_t size) +{ + a_uint32_t i; + fal_ip4_addr_t ip4; + + ip4 = *((fal_ip4_addr_t *) buf); + aos_printk("%s", param_name); + for (i = 0; i < 3; i++) + { + aos_printk("%d.", (ip4 >> (24 - i * 8)) & 0xff); + } + aos_printk("%d", (ip4 & 0xff)); +} +static void +print_ip6addr(char * param_name, a_uint32_t * buf, + a_uint32_t size) +{ + a_uint32_t i; + fal_ip6_addr_t ip6; + + ip6 = *(fal_ip6_addr_t *) buf; + aos_printk("%s", param_name); + for (i = 0; i < 3; i++) + { + aos_printk("%x:%x:", (ip6.ul[i] >> 16) & 0xffff, ip6.ul[i] & 0xffff); + } + aos_printk("%x:%x", (ip6.ul[3] >> 16) & 0xffff, ip6.ul[3] & 0xffff); +} +sw_error_t dess_igmp_sg_entry_show(a_uint32_t dev_id) +{ + a_uint32_t number; + int i; + + HSL_API_LOCK; + (void)dess_multicast_init(0); + aos_mem_zero(multi_acl_info, FAL_IGMP_SG_ENTRY_MAX * sizeof (multi_acl_info_t)); + aos_mem_zero(multi_acl_group, FAL_IGMP_SG_ENTRY_MAX * sizeof (multi_acl_info_t)); + //number is the total multicast ACL rules amount, stores in multi_acl_info[]; + number = dess_multicast_acl_query(); + + for(i=0; i FAL_IGMP_SG_ENTRY_MAX) + { + HSL_API_UNLOCK; + return SW_FAIL; + } + info->cnt = number; + + for(i=0; iacl_info[i]), &(multi_acl_info[i]), sizeof(multi_acl_info_t)); + } + HSL_API_UNLOCK; + + return SW_OK; +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_nat.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_nat.c new file mode 100755 index 000000000..cbe9d5788 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_nat.c @@ -0,0 +1,3213 @@ +/* + * Copyright (c) 2014-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. + */ + + +/** + * @defgroup dess_ip DESS_NAT + * @{ + */ + +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "dess_nat.h" +#include "dess_reg.h" +#if defined(IN_NAT_HELPER) +#include "dess_nat_helper.h" +#endif + +#define DESS_HOST_ENTRY_DATA0_ADDR 0x0e80 +#define DESS_HOST_ENTRY_DATA1_ADDR 0x0e84 +#define DESS_HOST_ENTRY_DATA2_ADDR 0x0e88 +#define DESS_HOST_ENTRY_DATA3_ADDR 0x0e8c +#define DESS_HOST_ENTRY_DATA4_ADDR 0x0e90 +#define DESS_HOST_ENTRY_DATA5_ADDR 0x0e94 +#define DESS_HOST_ENTRY_DATA6_ADDR 0x0e98 +#define DESS_HOST_ENTRY_DATA7_ADDR 0x0e58 + +#define DESS_HOST_ENTRY_REG_NUM 8 + +#define DESS_NAT_ENTRY_FLUSH 1 +#define DESS_NAT_ENTRY_ADD 2 +#define DESS_NAT_ENTRY_DEL 3 +#define DESS_NAT_ENTRY_NEXT 4 +#define DESS_NAT_ENTRY_SEARCH 5 + +#define DESS_ENTRY_NAPT 0 +#define DESS_ENTRY_FLOW 1 +#define DESS_ENTRY_NAT 2 +#define DESS_ENTRY_ARP 3 + +#define DESS_PUB_ADDR_NUM 16 +#define DESS_PUB_ADDR_TBL0_ADDR 0x5aa00 +#define DESS_PUB_ADDR_TBL1_ADDR 0x5aa04 +#define DESS_PUB_ADDR_EDIT0_ADDR 0x02100 +#define DESS_PUB_ADDR_EDIT1_ADDR 0x02104 +#define DESS_PUB_ADDR_OFFLOAD_ADDR 0x2f000 +#define DESS_PUB_ADDR_VALID_ADDR 0x2f040 + +#define DESS_NAT_ENTRY_NUM 32 +#define DESS_NAPT_ENTRY_NUM 1024 + +#define DESS_NAT_COUTER_ADDR 0x2b000 + +#define DESS_NAT_PORT_NUM 255 + +aos_lock_t dess_nat_lock; +static a_uint32_t dess_nat_snap[SW_MAX_NR_DEV] = { 0 }; +extern a_uint32_t dess_nat_global_status; + +#if defined(IN_NAT_HELPER) +extern void nat_helper_cookie_del(a_uint32_t hw_index); +#endif + +static sw_error_t +_dess_nat_feature_check(a_uint32_t dev_id) +{ + sw_error_t rv; + a_uint32_t entry = 0; + + HSL_REG_FIELD_GET(rv, dev_id, MASK_CTL, 0, DEVICE_ID, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (DESS_DEVICE_ID == entry) + { + return SW_OK; + } + else + { + return SW_NOT_SUPPORTED; + } +} + +static sw_error_t +_dess_ip_prvaddr_sw_to_hw(a_uint32_t dev_id, fal_ip4_addr_t sw_addr, + a_uint32_t * hw_addr) +{ + /* + sw_error_t rv; + a_uint32_t data; + + HSL_REG_FIELD_GET(rv, dev_id, PRVIP_CTL, 0, BASEADDR_SEL, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data) { + *hw_addr = (sw_addr & 0xff) | (((sw_addr >> 16) & 0xf) << 8); + } else { + *hw_addr = sw_addr & 0xfff; + } + */ + *hw_addr = sw_addr; + return SW_OK; +} + +static sw_error_t +_dess_ip_prvaddr_hw_to_sw(a_uint32_t dev_id, a_uint32_t hw_addr, + fal_ip4_addr_t * sw_addr) +{ + /* + sw_error_t rv; + a_uint32_t data, addr; + + HSL_REG_FIELD_GET(rv, dev_id, PRVIP_CTL, 0, BASEADDR_SEL, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, PRVIP_CTL, 0, IP4_BASEADDR, + (a_uint8_t *) (&addr), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data) { + *sw_addr = ((addr & 0xff) << 8) | (((addr >> 8) & 0xfff) << 8) + | (hw_addr & 0xff) | (((hw_addr >> 8) & 0xf) << 16); + } else { + *sw_addr = (addr << 12) | (hw_addr & 0xfff); + } + */ + *sw_addr = hw_addr; + + return SW_OK; +} + +static sw_error_t +_dess_nat_counter_get(a_uint32_t dev_id, a_uint32_t cnt_id, + a_uint32_t counter[4]) +{ + sw_error_t rv; + a_uint32_t i, addr; + + addr = DESS_NAT_COUTER_ADDR + (cnt_id << 4); + for (i = 0; i < 4; i++) + { + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(counter[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + addr += 4; + } + + return SW_OK; +} + +static sw_error_t +_dess_nat_entry_commit(a_uint32_t dev_id, a_uint32_t entry_type, a_uint32_t op) +{ + a_uint32_t busy = 1, i = 0x9000000, entry = 0; + sw_error_t rv; + + + while (busy && --i) + { + HSL_REG_ENTRY_GET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (&entry), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_BUSY, busy, entry); + } + + if (i == 0) + { + printk("busy 1\n"); + return SW_BUSY; + } + + SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_BUSY, 1, entry); + SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_SEL, entry_type, entry); + SW_SET_REG_BY_FIELD(HOST_ENTRY7, ENTRY_FUNC, op, entry); + + HSL_REG_ENTRY_SET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (&entry), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + busy = 1; + i = 0x90000000; + while (busy && --i) + { + HSL_REG_ENTRY_GET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (&entry), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_BUSY, busy, entry); +#if 1 + if(DESS_NAT_ENTRY_SEARCH == op && busy) break; +#endif + } + + if (i == 0) + { + printk("busy 2\n"); + return SW_BUSY; + } + + /* hardware requirement, we should delay... */ + if ((DESS_NAT_ENTRY_FLUSH == op) && ((DESS_ENTRY_NAPT == entry_type) || + (DESS_ENTRY_FLOW == entry_type))) + { + aos_mdelay(10); + } + + /* hardware requirement, we should read again... */ + HSL_REG_ENTRY_GET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (&entry), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_STAUS, busy, entry); + if (!busy) + { + if (DESS_NAT_ENTRY_NEXT == op) + { + return SW_NO_MORE; + } + else if (DESS_NAT_ENTRY_SEARCH == op) + { + return SW_NOT_FOUND; + } + else + { + return SW_FAIL; + } + } + + return SW_OK; +} + +static sw_error_t +_dess_nat_sw_to_hw(a_uint32_t dev_id, fal_nat_entry_t * entry, a_uint32_t reg[]) +{ + sw_error_t rv; + a_uint32_t data; + + if (FAL_NAT_ENTRY_TRANS_IPADDR_INDEX & entry->flags) + { + return SW_BAD_PARAM; + } + + reg[0] = entry->trans_addr; + + if (FAL_NAT_ENTRY_PORT_CHECK & entry->flags) + { + SW_SET_REG_BY_FIELD(NAT_ENTRY3, PORT_EN, 1, reg[3]); + SW_SET_REG_BY_FIELD(NAT_ENTRY1, PORT_RANGE, entry->port_range, reg[1]); + if (DESS_NAT_PORT_NUM < entry->port_range) + { + return SW_BAD_PARAM; + } + SW_SET_REG_BY_FIELD(NAT_ENTRY1, PORT_NUM, entry->port_num, reg[1]); + } + else + { + SW_SET_REG_BY_FIELD(NAT_ENTRY3, PORT_EN, 0, reg[3]); + } + + rv = _dess_ip_prvaddr_sw_to_hw(dev_id, entry->src_addr, &data); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(NAT_ENTRY1, PRV_IPADDR0, data, reg[1]); + SW_SET_REG_BY_FIELD(NAT_ENTRY2, PRV_IPADDR1, (data >> 8), reg[2]); + + if (FAL_MAC_FRWRD == entry->action) + { + if (A_TRUE == entry->mirror_en) + { + SW_SET_REG_BY_FIELD(NAT_ENTRY2, ACTION, 0, reg[2]); + } + else + { + SW_SET_REG_BY_FIELD(NAT_ENTRY2, ACTION, 3, reg[2]); + } + } + else if (FAL_MAC_CPY_TO_CPU == entry->action) + { + SW_SET_REG_BY_FIELD(NAT_ENTRY2, ACTION, 2, reg[2]); + } + else if (FAL_MAC_RDT_TO_CPU == entry->action) + { + SW_SET_REG_BY_FIELD(NAT_ENTRY2, ACTION, 1, reg[2]); + } + else + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == entry->counter_en) + { + SW_SET_REG_BY_FIELD(NAT_ENTRY2, CNT_EN, 1, reg[2]); + SW_SET_REG_BY_FIELD(NAT_ENTRY2, CNT_IDX, entry->counter_id, reg[2]); + } + + if (FAL_NAT_ENTRY_PROTOCOL_ANY & entry->flags) + { + data = 3; + } + else if ((FAL_NAT_ENTRY_PROTOCOL_TCP & entry->flags) + && (FAL_NAT_ENTRY_PROTOCOL_UDP & entry->flags)) + { + data = 2; + } + else if (FAL_NAT_ENTRY_PROTOCOL_TCP & entry->flags) + { + data = 0; + } + else if (FAL_NAT_ENTRY_PROTOCOL_UDP & entry->flags) + { + data = 1; + } + else + { + return SW_BAD_PARAM; + } + + SW_SET_REG_BY_FIELD(NAT_ENTRY3, PRO_TYP, data, reg[3]); + SW_SET_REG_BY_FIELD(NAT_ENTRY3, VRF_ID, entry->vrf_id, reg[3]); + + SW_SET_REG_BY_FIELD(NAT_ENTRY2, HASH_KEY, entry->slct_idx, reg[2]); + + SW_SET_REG_BY_FIELD(NAT_ENTRY3, ENTRY_VALID, 1, reg[3]); + SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_IDX, entry->entry_id, reg[7]); + return SW_OK; +} + +static sw_error_t +_dess_nat_hw_to_sw(a_uint32_t dev_id, a_uint32_t reg[], fal_nat_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t data, cnt[4] = {0}; + + entry->trans_addr = reg[0]; + + SW_GET_FIELD_BY_REG(NAT_ENTRY3, PORT_EN, data, reg[3]); + if (data) + { + entry->flags |= FAL_NAT_ENTRY_PORT_CHECK; + SW_GET_FIELD_BY_REG(NAT_ENTRY1, PORT_RANGE, data, reg[1]); + entry->port_range = data; + SW_GET_FIELD_BY_REG(NAT_ENTRY1, PORT_NUM, data, reg[1]); + entry->port_num = data; + } + + SW_GET_FIELD_BY_REG(NAT_ENTRY1, PRV_IPADDR0, data, reg[1]); + entry->src_addr = data; + SW_GET_FIELD_BY_REG(NAT_ENTRY2, PRV_IPADDR1, data, reg[2]); + data = (entry->src_addr & 0xff) | (data << 8); + + rv = _dess_ip_prvaddr_hw_to_sw(dev_id, data, &(entry->src_addr)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(NAT_ENTRY2, ACTION, data, reg[2]); + entry->action = FAL_MAC_FRWRD; + if (0 == data) + { + entry->mirror_en = A_TRUE; + } + else if (2 == data) + { + entry->action = FAL_MAC_CPY_TO_CPU; + } + else if (1 == data) + { + entry->action = FAL_MAC_RDT_TO_CPU; + } + + SW_GET_FIELD_BY_REG(NAT_ENTRY2, CNT_EN, data, reg[2]); + if (data) + { + entry->counter_en = A_TRUE; + SW_GET_FIELD_BY_REG(NAT_ENTRY2, CNT_IDX, entry->counter_id, reg[2]); + + rv = _dess_nat_counter_get(dev_id, entry->counter_id, cnt); + SW_RTN_ON_ERROR(rv); + + entry->ingress_packet = cnt[0]; + entry->ingress_byte = cnt[1]; + entry->egress_packet = cnt[2]; + entry->egress_byte = cnt[3]; + } + else + { + entry->counter_en = A_FALSE; + } + + SW_GET_FIELD_BY_REG(NAT_ENTRY3, PRO_TYP, data, reg[3]); + + if (3 == data) + { + entry->flags |= FAL_NAT_ENTRY_PROTOCOL_ANY; + } + else if (2 == data) + { + entry->flags |= FAL_NAT_ENTRY_PROTOCOL_TCP; + entry->flags |= FAL_NAT_ENTRY_PROTOCOL_UDP; + } + else if (1 == data) + { + entry->flags |= FAL_NAT_ENTRY_PROTOCOL_UDP; + } + else if (0 == data) + { + entry->flags |= FAL_NAT_ENTRY_PROTOCOL_TCP; + } + + SW_GET_FIELD_BY_REG(NAT_ENTRY3, VRF_ID, data, reg[3]); + entry->vrf_id = data; + + SW_GET_FIELD_BY_REG(NAT_ENTRY2, HASH_KEY, data, reg[2]); + entry->slct_idx = data; + + return SW_OK; +} + +static sw_error_t +_dess_napt_sw_to_hw(a_uint32_t dev_id, fal_napt_entry_t * entry, + a_uint32_t reg[]) +{ + sw_error_t rv; + a_uint32_t data; + + reg[0] = entry->dst_addr; + + SW_SET_REG_BY_FIELD(NAPT_ENTRY1, DST_PORT, entry->dst_port, reg[1]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY1, SRC_PORT, entry->src_port, reg[1]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY2, TRANS_PORT, entry->trans_port, reg[2]); + + rv = _dess_ip_prvaddr_sw_to_hw(dev_id, entry->src_addr, &data); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(NAPT_ENTRY2, SRC_IPADDR0, (data & 0xfff), reg[2]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, SRC_IPADDR1, (data >> 12), reg[3]); + + SW_SET_REG_BY_FIELD(NAPT_ENTRY2, TRANS_IPADDR, entry->trans_addr, reg[2]); + + if (FAL_MAC_FRWRD == entry->action) + { + if (A_TRUE == entry->mirror_en) + { + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, ACTION, 0, reg[3]); + } + else + { + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, ACTION, 3, reg[3]); + } + } + else if (FAL_MAC_CPY_TO_CPU == entry->action) + { + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, ACTION, 2, reg[3]); + } + else if (FAL_MAC_RDT_TO_CPU == entry->action) + { + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, ACTION, 1, reg[3]); + } + else + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == entry->counter_en) + { + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, CNT_EN, 1, reg[3]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, CNT_IDX, entry->counter_id, reg[3]); + } + + if (A_TRUE == entry->priority_en) + { + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, PRIORITY_EN, 1, reg[3]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, PRIORITY_VAL, entry->priority_val, reg[3]); + } + + data = 2; + if (FAL_NAT_ENTRY_PROTOCOL_TCP & entry->flags) + { + data = 0; + } + else if (FAL_NAT_ENTRY_PROTOCOL_UDP & entry->flags) + { + data = 1; + } + else if (FAL_NAT_ENTRY_PROTOCOL_PPTP & entry->flags) + { + data = 3; + } + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, PROT_TYP, data, reg[3]); + + SW_SET_REG_BY_FIELD(NAPT_ENTRY4, AGE_FLAG, entry->status, reg[4]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY4, AGE_SYNC, entry->aging_sync, reg[4]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY4, VRF_ID, entry->vrf_id, reg[4]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY4, FLOW_COOKIE, entry->flow_cookie, reg[4]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY4, LOAD_BALANCE, entry->load_balance, reg[4]); + return SW_OK; +} + +static sw_error_t +_dess_napt_hw_to_sw(a_uint32_t dev_id, a_uint32_t reg[], + fal_napt_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t data, cnt[4] = {0}; + + entry->dst_addr = reg[0]; + + SW_GET_FIELD_BY_REG(NAPT_ENTRY1, DST_PORT, entry->dst_port, reg[1]); + SW_GET_FIELD_BY_REG(NAPT_ENTRY1, SRC_PORT, entry->src_port, reg[1]); + SW_GET_FIELD_BY_REG(NAPT_ENTRY2, TRANS_PORT, entry->trans_port, reg[2]); + + SW_GET_FIELD_BY_REG(NAPT_ENTRY2, SRC_IPADDR0, data, reg[2]); + entry->src_addr = data; + SW_GET_FIELD_BY_REG(NAPT_ENTRY3, SRC_IPADDR1, data, reg[3]); + data = (entry->src_addr & 0xfff) | (data << 12); + rv = _dess_ip_prvaddr_hw_to_sw(dev_id, data, &(entry->src_addr)); + SW_RTN_ON_ERROR(rv); + + entry->flags |= FAL_NAT_ENTRY_TRANS_IPADDR_INDEX; + SW_GET_FIELD_BY_REG(NAPT_ENTRY2, TRANS_IPADDR, entry->trans_addr, reg[2]); + + SW_GET_FIELD_BY_REG(NAPT_ENTRY3, ACTION, data, reg[3]); + entry->action = FAL_MAC_FRWRD; + if (0 == data) + { + entry->mirror_en = A_TRUE; + } + else if (2 == data) + { + entry->action = FAL_MAC_CPY_TO_CPU; + } + else if (1 == data) + { + entry->action = FAL_MAC_RDT_TO_CPU; + } + + SW_GET_FIELD_BY_REG(NAPT_ENTRY3, CNT_EN, data, reg[3]); + if (data) + { + entry->counter_en = A_TRUE; + SW_GET_FIELD_BY_REG(NAPT_ENTRY3, CNT_IDX, entry->counter_id, reg[3]); + + rv = _dess_nat_counter_get(dev_id, entry->counter_id, cnt); + SW_RTN_ON_ERROR(rv); + + entry->ingress_packet = cnt[0]; + entry->ingress_byte = cnt[1]; + entry->egress_packet = cnt[2]; + entry->egress_byte = cnt[3]; + } + else + { + entry->counter_en = A_FALSE; + } + + SW_GET_FIELD_BY_REG(NAPT_ENTRY3, PRIORITY_EN, data, reg[3]); + if (data) + { + entry->priority_en = A_TRUE; + SW_GET_FIELD_BY_REG(NAPT_ENTRY3, PRIORITY_VAL, entry->priority_val, reg[3]); + } + else + { + entry->priority_en = A_FALSE; + } + + SW_GET_FIELD_BY_REG(NAPT_ENTRY3, PROT_TYP, data, reg[3]); + if (0 == data) + { + entry->flags |= FAL_NAT_ENTRY_PROTOCOL_TCP; + } + else if (1 == data) + { + entry->flags |= FAL_NAT_ENTRY_PROTOCOL_UDP; + } + else if (3 == data) + { + entry->flags |= FAL_NAT_ENTRY_PROTOCOL_PPTP; + } + + SW_GET_FIELD_BY_REG(NAPT_ENTRY4, AGE_FLAG, entry->status, reg[4]); + SW_GET_FIELD_BY_REG(NAPT_ENTRY4, AGE_SYNC, entry->aging_sync, reg[4]); + SW_GET_FIELD_BY_REG(NAPT_ENTRY4, VRF_ID, entry->vrf_id, reg[4]); + SW_GET_FIELD_BY_REG(NAPT_ENTRY4, FLOW_COOKIE, entry->flow_cookie, reg[4]); + SW_GET_FIELD_BY_REG(NAPT_ENTRY4, LOAD_BALANCE, entry->load_balance, reg[4]); + return SW_OK; +} + +static sw_error_t +_dess_nat_down_to_hw(a_uint32_t dev_id, a_uint32_t reg[]) +{ + sw_error_t rv; + a_uint32_t i, addr; + + for (i = 0; i < DESS_HOST_ENTRY_REG_NUM; i++) + { + if((DESS_HOST_ENTRY_REG_NUM - 1) == i) + { + addr = DESS_HOST_ENTRY_DATA7_ADDR; + } + else + { + addr = DESS_HOST_ENTRY_DATA0_ADDR + (i << 2); + } + + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®[i]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +static sw_error_t +_dess_nat_up_to_sw(a_uint32_t dev_id, a_uint32_t reg[]) +{ + sw_error_t rv; + a_uint32_t i, addr; + + for (i = 0; i < DESS_HOST_ENTRY_REG_NUM; i++) + { + if((DESS_HOST_ENTRY_REG_NUM -1) == i) + { + addr = DESS_HOST_ENTRY_DATA7_ADDR; + } + else + { + addr = DESS_HOST_ENTRY_DATA0_ADDR + (i << 2); + } + + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®[i]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +static sw_error_t +_dess_nat_add(a_uint32_t dev_id, fal_nat_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t i, reg[DESS_HOST_ENTRY_REG_NUM] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + for (i = 0; i < DESS_NAT_ENTRY_NUM; i++) + { + if (!(dess_nat_snap[dev_id] & (0x1 << i))) + { + break; + } + } + + if (DESS_NAT_ENTRY_NUM == i) + { + return SW_NO_RESOURCE; + } + + entry->entry_id = i; + + rv = _dess_nat_sw_to_hw(dev_id, entry, reg); + SW_RTN_ON_ERROR(rv); + + rv = _dess_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _dess_nat_entry_commit(dev_id, DESS_ENTRY_NAT, DESS_NAT_ENTRY_ADD); + SW_RTN_ON_ERROR(rv); + + dess_nat_snap[dev_id] |= (0x1 << i); + entry->entry_id = i; + return SW_OK; +} + +static sw_error_t +_dess_nat_del(a_uint32_t dev_id, a_uint32_t del_mode, fal_nat_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t reg[DESS_HOST_ENTRY_REG_NUM] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_NAT_ENTRY_ID_EN & del_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY7, ENTRY_FUNC, DESS_NAT_ENTRY_DEL, reg[7]); + SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_IDX, entry->entry_id, reg[7]); + + rv = _dess_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _dess_nat_entry_commit(dev_id, DESS_ENTRY_NAT, DESS_NAT_ENTRY_DEL); + SW_RTN_ON_ERROR(rv); + + dess_nat_snap[dev_id] &= (~(0x1 << entry->entry_id)); + } + else + { + rv = _dess_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _dess_nat_entry_commit(dev_id, DESS_ENTRY_NAT, DESS_NAT_ENTRY_FLUSH); + SW_RTN_ON_ERROR(rv); + + dess_nat_snap[dev_id] = 0; + } + + return SW_OK; +} + +static sw_error_t +_dess_nat_get(a_uint32_t dev_id, a_uint32_t get_mode, fal_nat_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t reg[DESS_HOST_ENTRY_REG_NUM] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_NAT_ENTRY_ID_EN != get_mode) + { + return SW_NOT_SUPPORTED; + } + + if (!(dess_nat_snap[dev_id] & (0x1 << entry->entry_id))) + { + return SW_NOT_FOUND; + } + + SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_IDX, entry->entry_id, reg[7]); + + rv = _dess_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _dess_nat_entry_commit(dev_id, DESS_ENTRY_NAT, DESS_NAT_ENTRY_SEARCH); + SW_RTN_ON_ERROR(rv); + + rv = _dess_nat_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _dess_nat_hw_to_sw(dev_id, reg, entry); + return rv; +} + +static sw_error_t +_dess_nat_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_nat_entry_t * nat_entry) +{ + a_uint32_t i, idx, reg[DESS_HOST_ENTRY_REG_NUM] = { 0 }; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_NEXT_ENTRY_FIRST_ID == nat_entry->entry_id) + { + idx = 0; + } + else + { + if ((DESS_NAT_ENTRY_NUM - 1) == nat_entry->entry_id) + { + return SW_NO_MORE; + } + else + { + idx = nat_entry->entry_id + 1; + } + } + + for (i = idx; i < DESS_NAT_ENTRY_NUM; i++) + { + if (dess_nat_snap[dev_id] & (0x1 << i)) + { + break; + } + } + + if (DESS_NAT_ENTRY_NUM == i) + { + return SW_NO_MORE; + } + + SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_IDX, i, reg[7]); + + rv = _dess_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _dess_nat_entry_commit(dev_id, DESS_ENTRY_NAT, DESS_NAT_ENTRY_SEARCH); + SW_RTN_ON_ERROR(rv); + + rv = _dess_nat_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + aos_mem_zero(nat_entry, sizeof (fal_nat_entry_t)); + + rv = _dess_nat_hw_to_sw(dev_id, reg, nat_entry); + SW_RTN_ON_ERROR(rv); + + nat_entry->entry_id = i; + return SW_OK; +} + +static sw_error_t +_dess_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; + a_uint32_t reg[DESS_HOST_ENTRY_REG_NUM] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (!(dess_nat_snap[dev_id] & (0x1 << entry_id))) + { + return SW_NOT_FOUND; + } + + SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_IDX, entry_id, reg[7]); + + rv = _dess_nat_entry_commit(dev_id, DESS_ENTRY_NAT, DESS_NAT_ENTRY_SEARCH); + SW_RTN_ON_ERROR(rv); + + rv = _dess_nat_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(NAT_ENTRY2, CNT_EN, 0, reg[2]); + } + else if (A_TRUE == enable) + { + SW_SET_REG_BY_FIELD(NAT_ENTRY2, CNT_EN, 1, reg[2]); + SW_SET_REG_BY_FIELD(NAT_ENTRY2, CNT_IDX, cnt_id, reg[2]); + } + else + { + return SW_BAD_PARAM; + } + + /* needn't set TBL_IDX, keep hardware register value */ + + rv = _dess_nat_entry_commit(dev_id, DESS_ENTRY_NAT, DESS_NAT_ENTRY_DEL); + SW_RTN_ON_ERROR(rv); + + rv = _dess_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + /* needn't set TBL_IDX, keep hardware register value */ + + rv = _dess_nat_entry_commit(dev_id, DESS_ENTRY_NAT, DESS_NAT_ENTRY_ADD); + return rv; +} + +static sw_error_t +_dess_napt_add(a_uint32_t dev_id, fal_napt_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t reg[DESS_HOST_ENTRY_REG_NUM] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_napt_sw_to_hw(dev_id, entry, reg); + SW_RTN_ON_ERROR(rv); + + aos_lock_bh(&dess_nat_lock); + rv = _dess_nat_down_to_hw(dev_id, reg); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + rv = _dess_nat_entry_commit(dev_id, DESS_ENTRY_NAPT, DESS_NAT_ENTRY_ADD); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + rv = _dess_nat_up_to_sw(dev_id, reg); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_IDX, entry->entry_id, reg[7]); + aos_unlock_bh(&dess_nat_lock); + return SW_OK; +} + +static sw_error_t +_dess_napt_del(a_uint32_t dev_id, a_uint32_t del_mode, fal_napt_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t data, reg[DESS_HOST_ENTRY_REG_NUM] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_NAT_ENTRY_ID_EN & del_mode) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_NAT_ENTRY_KEY_EN & del_mode) + { + rv = _dess_napt_sw_to_hw(dev_id, entry, reg); + SW_RTN_ON_ERROR(rv); + + aos_lock_bh(&dess_nat_lock); + rv = _dess_nat_down_to_hw(dev_id, reg); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + rv = _dess_nat_entry_commit(dev_id, DESS_ENTRY_NAPT, DESS_NAT_ENTRY_DEL); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + rv = _dess_nat_up_to_sw(dev_id, reg); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_IDX, entry->entry_id, reg[7]); + aos_unlock_bh(&dess_nat_lock); + return SW_OK; + } + else + { + if (FAL_NAT_ENTRY_PUBLIC_IP_EN & del_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_PIP, 1, reg[7]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY2, TRANS_IPADDR, entry->trans_addr, reg[2]); + } + + if (FAL_NAT_ENTRY_SOURCE_IP_EN & del_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_SIP, 1, reg[7]); + rv = _dess_ip_prvaddr_sw_to_hw(dev_id, entry->src_addr, &data); + SW_RTN_ON_ERROR(rv); + SW_SET_REG_BY_FIELD(NAPT_ENTRY2, SRC_IPADDR0, (data & 0xfff), reg[2]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, SRC_IPADDR1, (data >> 12), reg[3]); + } + + if (FAL_NAT_ENTRY_AGE_EN & del_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_STATUS, 1, reg[7]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY4, AGE_FLAG, entry->status, reg[4]); + } + + aos_lock_bh(&dess_nat_lock); + rv = _dess_nat_down_to_hw(dev_id, reg); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + rv = _dess_nat_entry_commit(dev_id, DESS_ENTRY_NAPT, DESS_NAT_ENTRY_FLUSH); + aos_unlock_bh(&dess_nat_lock); + return rv; + } +} + +static sw_error_t +_dess_napt_get(a_uint32_t dev_id, a_uint32_t get_mode, fal_napt_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t found, age, reg[DESS_HOST_ENTRY_REG_NUM] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + +#if 0 + if (FAL_NAT_ENTRY_ID_EN != get_mode) + { + return SW_NOT_SUPPORTED; + } + + SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_IDX, entry->entry_id, reg[7]); +#else + rv = _dess_napt_sw_to_hw(dev_id, entry, reg); + SW_RTN_ON_ERROR(rv); +#endif + + aos_lock_bh(&dess_nat_lock); + rv = _dess_nat_down_to_hw(dev_id, reg); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + rv = _dess_nat_entry_commit(dev_id, DESS_ENTRY_NAPT, DESS_NAT_ENTRY_SEARCH); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + rv = _dess_nat_up_to_sw(dev_id, reg); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + aos_unlock_bh(&dess_nat_lock); + + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_STAUS, found, reg[7]); + SW_GET_FIELD_BY_REG(NAPT_ENTRY4, AGE_FLAG, age, reg[4]); + if (found && age) + { + found = 1; + } + else + { + found = 0; + } + + rv = _dess_napt_hw_to_sw(dev_id, reg, entry); + SW_RTN_ON_ERROR(rv); + + if (!found) + { + return SW_NOT_FOUND; + } + + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_IDX, entry->entry_id, reg[7]); + return SW_OK; +} + +static sw_error_t +_dess_napt_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_napt_entry_t * napt_entry) +{ + a_uint32_t data, idx, reg[DESS_HOST_ENTRY_REG_NUM] = { 0 }; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_NEXT_ENTRY_FIRST_ID == napt_entry->entry_id) + { + idx = DESS_NAPT_ENTRY_NUM - 1; + } + else + { + if ((DESS_NAPT_ENTRY_NUM - 1) == napt_entry->entry_id) + { + return SW_NO_MORE; + } + else + { + idx = napt_entry->entry_id; + } + } + + if (FAL_NAT_ENTRY_PUBLIC_IP_EN & next_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_PIP, 1, reg[7]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY2, TRANS_IPADDR, napt_entry->trans_addr, reg[2]); + } + + if (FAL_NAT_ENTRY_SOURCE_IP_EN & next_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_SIP, 1, reg[7]); + rv = _dess_ip_prvaddr_sw_to_hw(dev_id, napt_entry->src_addr, &data); + SW_RTN_ON_ERROR(rv); + SW_SET_REG_BY_FIELD(NAPT_ENTRY2, SRC_IPADDR0, (data & 0xfff), reg[2]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, SRC_IPADDR1, (data >> 12), reg[3]); + } + + if (FAL_NAT_ENTRY_AGE_EN & next_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_STATUS, 1, reg[7]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY4, AGE_FLAG, napt_entry->status, reg[4]); + } + + if (FAL_NAT_ENTRY_SYNC_EN & next_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_SYNC, 1, reg[7]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY4, AGE_SYNC, napt_entry->aging_sync, reg[4]); + } + + SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_IDX, idx, reg[7]); + + aos_lock_bh(&dess_nat_lock); + rv = _dess_nat_down_to_hw(dev_id, reg); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + rv = _dess_nat_entry_commit(dev_id, DESS_ENTRY_NAPT, DESS_NAT_ENTRY_NEXT); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + rv = _dess_nat_up_to_sw(dev_id, reg); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + aos_unlock_bh(&dess_nat_lock); + + aos_mem_zero(napt_entry, sizeof (fal_nat_entry_t)); + + rv = _dess_napt_hw_to_sw(dev_id, reg, napt_entry); + SW_RTN_ON_ERROR(rv); + +#if 0 + a_uint32_t temp=0, complete=0; + + HSL_REG_ENTRY_GET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (&temp), + sizeof (a_uint32_t)); + + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_STAUS, complete, temp); + + if (!complete) + { + return SW_NO_MORE; + } +#endif + + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_IDX, napt_entry->entry_id, reg[7]); + return SW_OK; +} + +static sw_error_t +_dess_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; + a_uint32_t reg[DESS_HOST_ENTRY_REG_NUM] = { 0 }, tbl_idx; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + tbl_idx = (entry_id - 1) & 0x3ff; + SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_IDX, tbl_idx, reg[7]); + + rv = _dess_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _dess_nat_entry_commit(dev_id, DESS_ENTRY_NAPT, DESS_NAT_ENTRY_NEXT); + if (SW_OK != rv) + { + return SW_NOT_FOUND; + } + + rv = _dess_nat_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_IDX, tbl_idx, reg[7]); + if (entry_id != tbl_idx) + { + return SW_NOT_FOUND; + } + + if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, CNT_EN, 0, reg[3]); + } + else if (A_TRUE == enable) + { + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, CNT_EN, 1, reg[3]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, CNT_IDX, cnt_id, reg[3]); + } + else + { + return SW_BAD_PARAM; + } + + rv = _dess_nat_entry_commit(dev_id, DESS_ENTRY_NAPT, DESS_NAT_ENTRY_DEL); + SW_RTN_ON_ERROR(rv); + + rv = _dess_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _dess_nat_entry_commit(dev_id, DESS_ENTRY_NAPT, DESS_NAT_ENTRY_ADD); + return rv; +} + +static sw_error_t +_dess_flow_add(a_uint32_t dev_id, fal_napt_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t reg[DESS_HOST_ENTRY_REG_NUM] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_napt_sw_to_hw(dev_id, entry, reg); + SW_RTN_ON_ERROR(rv); + + aos_lock_bh(&dess_nat_lock); + rv = _dess_nat_down_to_hw(dev_id, reg); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + rv = _dess_nat_entry_commit(dev_id, DESS_ENTRY_FLOW, DESS_NAT_ENTRY_ADD); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + rv = _dess_nat_up_to_sw(dev_id, reg); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_IDX, entry->entry_id, reg[7]); + aos_unlock_bh(&dess_nat_lock); + return SW_OK; +} + +static sw_error_t +_dess_flow_del(a_uint32_t dev_id, a_uint32_t del_mode, fal_napt_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t data, reg[DESS_HOST_ENTRY_REG_NUM] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_NAT_ENTRY_ID_EN & del_mode) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_NAT_ENTRY_KEY_EN & del_mode) + { + rv = _dess_napt_sw_to_hw(dev_id, entry, reg); + SW_RTN_ON_ERROR(rv); + + aos_lock_bh(&dess_nat_lock); + rv = _dess_nat_down_to_hw(dev_id, reg); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + rv = _dess_nat_entry_commit(dev_id, DESS_ENTRY_FLOW, DESS_NAT_ENTRY_DEL); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + rv = _dess_nat_up_to_sw(dev_id, reg); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_IDX, entry->entry_id, reg[7]); + aos_unlock_bh(&dess_nat_lock); + return SW_OK; + } + else + { + if (FAL_NAT_ENTRY_PUBLIC_IP_EN & del_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_PIP, 1, reg[7]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY2, TRANS_IPADDR, entry->trans_addr, reg[2]); + } + + if (FAL_NAT_ENTRY_SOURCE_IP_EN & del_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_SIP, 1, reg[7]); + rv = _dess_ip_prvaddr_sw_to_hw(dev_id, entry->src_addr, &data); + SW_RTN_ON_ERROR(rv); + SW_SET_REG_BY_FIELD(NAPT_ENTRY2, SRC_IPADDR0, (data & 0xfff), reg[2]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, SRC_IPADDR1, (data >> 12), reg[3]); + } + + if (FAL_NAT_ENTRY_AGE_EN & del_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_STATUS, 1, reg[7]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY4, AGE_FLAG, entry->status, reg[4]); + } + + aos_lock_bh(&dess_nat_lock); + rv = _dess_nat_down_to_hw(dev_id, reg); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + rv = _dess_nat_entry_commit(dev_id, DESS_ENTRY_FLOW, DESS_NAT_ENTRY_FLUSH); + aos_unlock_bh(&dess_nat_lock); + return rv; + } +} + +static sw_error_t +_dess_flow_get(a_uint32_t dev_id, a_uint32_t get_mode, fal_napt_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t found, age, reg[DESS_HOST_ENTRY_REG_NUM] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + +#if 0 + if (FAL_NAT_ENTRY_ID_EN != get_mode) + { + return SW_NOT_SUPPORTED; + } + + SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_IDX, entry->entry_id, reg[7]); +#else + rv = _dess_napt_sw_to_hw(dev_id, entry, reg); + SW_RTN_ON_ERROR(rv); +#endif + + aos_lock_bh(&dess_nat_lock); + rv = _dess_nat_down_to_hw(dev_id, reg); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + rv = _dess_nat_entry_commit(dev_id, DESS_ENTRY_FLOW, DESS_NAT_ENTRY_SEARCH); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + rv = _dess_nat_up_to_sw(dev_id, reg); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + aos_unlock_bh(&dess_nat_lock); + + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_STAUS, found, reg[7]); + SW_GET_FIELD_BY_REG(NAPT_ENTRY4, AGE_FLAG, age, reg[4]); + if (found && age) + { + found = 1; + } + else + { + found = 0; + } + + rv = _dess_napt_hw_to_sw(dev_id, reg, entry); + SW_RTN_ON_ERROR(rv); + + if (!found) + { + return SW_NOT_FOUND; + } + + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_IDX, entry->entry_id, reg[7]); + return SW_OK; +} + +static sw_error_t +_dess_flow_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_napt_entry_t * napt_entry) +{ + a_uint32_t data, idx, reg[DESS_HOST_ENTRY_REG_NUM] = { 0 }; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_NEXT_ENTRY_FIRST_ID == napt_entry->entry_id) + { + idx = DESS_NAPT_ENTRY_NUM - 1; + } + else + { + if ((DESS_NAPT_ENTRY_NUM - 1) == napt_entry->entry_id) + { + return SW_NO_MORE; + } + else + { + idx = napt_entry->entry_id; + } + } + + if (FAL_NAT_ENTRY_PUBLIC_IP_EN & next_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_PIP, 1, reg[7]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY2, TRANS_IPADDR, napt_entry->trans_addr, reg[2]); + } + + if (FAL_NAT_ENTRY_SOURCE_IP_EN & next_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_SIP, 1, reg[7]); + rv = _dess_ip_prvaddr_sw_to_hw(dev_id, napt_entry->src_addr, &data); + SW_RTN_ON_ERROR(rv); + SW_SET_REG_BY_FIELD(NAPT_ENTRY2, SRC_IPADDR0, (data & 0xfff), reg[2]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, SRC_IPADDR1, (data >> 12), reg[3]); + } + + if (FAL_NAT_ENTRY_AGE_EN & next_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_STATUS, 1, reg[7]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY4, AGE_FLAG, napt_entry->status, reg[4]); + } + + if (FAL_NAT_ENTRY_SYNC_EN & next_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_SYNC, 1, reg[7]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY4, AGE_SYNC, napt_entry->status, reg[4]); + } + + SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_IDX, idx, reg[7]); + + aos_lock_bh(&dess_nat_lock); + rv = _dess_nat_down_to_hw(dev_id, reg); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + rv = _dess_nat_entry_commit(dev_id, DESS_ENTRY_FLOW, DESS_NAT_ENTRY_NEXT); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + + rv = _dess_nat_up_to_sw(dev_id, reg); + if (rv != SW_OK) { + aos_unlock_bh(&dess_nat_lock); + return rv; + } + aos_unlock_bh(&dess_nat_lock); + + aos_mem_zero(napt_entry, sizeof (fal_nat_entry_t)); + + rv = _dess_napt_hw_to_sw(dev_id, reg, napt_entry); + SW_RTN_ON_ERROR(rv); + +#if 0 + a_uint32_t temp=0, complete=0; + + HSL_REG_ENTRY_GET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (&temp), + sizeof (a_uint32_t)); + + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_STAUS, complete, temp); + + if (!complete) + { + return SW_NO_MORE; + } +#endif + + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_IDX, napt_entry->entry_id, reg[7]); + return SW_OK; +} + +static sw_error_t +_dess_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; + a_uint32_t reg[DESS_HOST_ENTRY_REG_NUM] = { 0 }, tbl_idx; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + tbl_idx = (entry_id - 1) & 0x3ff; + SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_IDX, tbl_idx, reg[7]); + + rv = _dess_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _dess_nat_entry_commit(dev_id, DESS_ENTRY_FLOW, DESS_NAT_ENTRY_NEXT); + if (SW_OK != rv) + { + return SW_NOT_FOUND; + } + + rv = _dess_nat_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_IDX, tbl_idx, reg[7]); + if (entry_id != tbl_idx) + { + return SW_NOT_FOUND; + } + + if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, CNT_EN, 0, reg[3]); + } + else if (A_TRUE == enable) + { + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, CNT_EN, 1, reg[3]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, CNT_IDX, cnt_id, reg[3]); + } + else + { + return SW_BAD_PARAM; + } + + rv = _dess_nat_entry_commit(dev_id, DESS_ENTRY_FLOW, DESS_NAT_ENTRY_DEL); + SW_RTN_ON_ERROR(rv); + + rv = _dess_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _dess_nat_entry_commit(dev_id, DESS_ENTRY_FLOW, DESS_NAT_ENTRY_ADD); + return rv; +} + +static sw_error_t +_dess_nat_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, NAT_CTRL, 0, NAT_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_nat_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, NAT_CTRL, 0, NAT_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return rv; +} + +static sw_error_t +_dess_napt_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, NAT_CTRL, 0, NAPT_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_napt_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, NAT_CTRL, 0, NAPT_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return rv; +} + +static sw_error_t +_dess_napt_mode_set(a_uint32_t dev_id, fal_napt_mode_t mode) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_NAPT_FULL_CONE == mode) + { + data = 0; + } + else if (FAL_NAPT_STRICT_CONE == mode) + { + data = 1; + } + else if ((FAL_NAPT_PORT_STRICT == mode) + || (FAL_NAPT_SYNMETRIC == mode)) + { + data = 2; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, NAT_CTRL, 0, NAPT_MODE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_napt_mode_get(a_uint32_t dev_id, fal_napt_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, NAT_CTRL, 0, NAPT_MODE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0 == data) + { + *mode = FAL_NAPT_FULL_CONE; + } + else if (1 == data) + { + *mode = FAL_NAPT_STRICT_CONE; + } + else + { + *mode = FAL_NAPT_PORT_STRICT; + } + + return SW_OK; +} + +static sw_error_t +_dess_nat_hash_mode_set(a_uint32_t dev_id, a_uint32_t mode) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if ((FAL_NAT_HASH_KEY_PORT & mode) + && (FAL_NAT_HASH_KEY_IPADDR & mode)) + { + data = 2; + } + else if (FAL_NAT_HASH_KEY_PORT & mode) + { + data = 0; + } + else if (FAL_NAT_HASH_KEY_IPADDR & mode) + { + data = 1; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, NAT_CTRL, 0, NAT_HASH_MODE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_nat_hash_mode_get(a_uint32_t dev_id, a_uint32_t * mode) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, NAT_CTRL, 0, NAT_HASH_MODE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *mode = 0; + if (0 == data) + { + *mode = FAL_NAT_HASH_KEY_PORT; + } + else if (1 == data) + { + *mode = FAL_NAT_HASH_KEY_IPADDR; + } + else if (2 == data) + { + *mode = FAL_NAT_HASH_KEY_PORT; + *mode |= FAL_NAT_HASH_KEY_IPADDR; + } + + return SW_OK; +} + +static sw_error_t +_dess_nat_prv_base_addr_set(a_uint32_t dev_id, fal_ip4_addr_t addr) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + data = addr; + HSL_REG_FIELD_SET(rv, dev_id, PRVIP_ADDR, 0, IP4_BASEADDR, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_nat_prv_base_addr_get(a_uint32_t dev_id, fal_ip4_addr_t * addr) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, PRVIP_ADDR, 0, IP4_BASEADDR, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + *addr = data; + + return SW_OK; +} + +static sw_error_t +_dess_nat_prv_base_mask_set(a_uint32_t dev_id, fal_ip4_addr_t mask) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + data = mask; + HSL_REG_FIELD_SET(rv, dev_id, PRVIP_MASK, 0, IP4_BASEMASK, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_nat_prv_base_mask_get(a_uint32_t dev_id, fal_ip4_addr_t * mask) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, PRVIP_MASK, 0, IP4_BASEMASK, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *mask = data; + return SW_OK; +} + +static sw_error_t +_dess_nat_pub_addr_commit(a_uint32_t dev_id, fal_nat_pub_addr_t * entry, + a_uint32_t op, a_uint32_t * empty) +{ + a_uint32_t index, addr, data, tbl[2] = { 0 }; + sw_error_t rv; + + *empty = DESS_PUB_ADDR_NUM; + for (index = 0; index < DESS_PUB_ADDR_NUM; index++) + { + addr = DESS_PUB_ADDR_TBL1_ADDR + (index << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[1])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PUB_ADDR1, ADDR_VALID, data, tbl[1]); + if (data) + { + addr = DESS_PUB_ADDR_TBL0_ADDR + (index << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[0])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (!aos_mem_cmp + ((void *) &(entry->pub_addr), (void *) &(tbl[0]), + sizeof (fal_ip4_addr_t))) + { + if (DESS_NAT_ENTRY_DEL == op) + { + addr = DESS_PUB_ADDR_TBL1_ADDR + (index << 4); + tbl[1] = 0; + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[1])), + sizeof (a_uint32_t)); + *empty = index; + return rv; + } + else if (DESS_NAT_ENTRY_ADD == op) + { + entry->entry_id = index; + return SW_ALREADY_EXIST; + } + } + } + else + { + *empty = index; + } + } + + return SW_NOT_FOUND; +} + +static sw_error_t +_dess_nat_pub_addr_add(a_uint32_t dev_id, fal_nat_pub_addr_t * entry) +{ + sw_error_t rv; + a_uint32_t i, empty, addr, data = 0, tbl[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + tbl[0] = entry->pub_addr; + tbl[1] = 1; + + rv = _dess_nat_pub_addr_commit(dev_id, entry, DESS_NAT_ENTRY_ADD, &empty); + if (SW_ALREADY_EXIST == rv) + { + return rv; + } + + if (DESS_PUB_ADDR_NUM == empty) + { + return SW_NO_RESOURCE; + } + + for (i = 0; i < 1; i++) + { + addr = DESS_PUB_ADDR_EDIT0_ADDR + (empty << 4) + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[i])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + addr = DESS_PUB_ADDR_OFFLOAD_ADDR + (empty << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[0])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + addr = DESS_PUB_ADDR_VALID_ADDR; + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data |= (0x1 << empty); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + for (i = 0; i < 2; i++) + { + addr = DESS_PUB_ADDR_TBL0_ADDR + (empty << 4) + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[i])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + entry->entry_id = empty; + return SW_OK; +} + +static sw_error_t +_dess_nat_pub_addr_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_nat_pub_addr_t * entry) +{ + sw_error_t rv; + a_uint32_t empty, addr, data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + rv = _dess_nat_pub_addr_commit(dev_id, entry, DESS_NAT_ENTRY_DEL, &empty); + SW_RTN_ON_ERROR(rv); + + addr = DESS_PUB_ADDR_VALID_ADDR; + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data &= (~(0x1 << empty)); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_dess_nat_pub_addr_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_nat_pub_addr_t * entry) +{ + sw_error_t rv; + a_uint32_t data, addr, idx, index, tbl[2] = {0}; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_NEXT_ENTRY_FIRST_ID == entry->entry_id) + { + idx = 0; + } + else + { + if ((DESS_PUB_ADDR_NUM - 1) == entry->entry_id) + { + return SW_NO_MORE; + } + else + { + idx = entry->entry_id + 1; + } + } + + for (index = idx; index < DESS_PUB_ADDR_NUM; index++) + { + addr = DESS_PUB_ADDR_TBL1_ADDR + (index << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[1])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PUB_ADDR1, ADDR_VALID, data, tbl[1]); + if (data) + { + break; + } + } + + if (DESS_PUB_ADDR_NUM == index) + { + return SW_NO_MORE; + } + + addr = DESS_PUB_ADDR_TBL0_ADDR + (index << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[0])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + entry->entry_id = index; + entry->pub_addr = tbl[0]; + + return SW_OK; +} + +static sw_error_t +_dess_nat_unk_session_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_MAC_DROP == cmd) + { + data = 1; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + data = 0; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, NAT_NOT_FOUND_DROP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_nat_unk_session_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, NAT_NOT_FOUND_DROP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0 == data) + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + else + { + *cmd = FAL_MAC_DROP; + } + + return SW_OK; +} + +#define DESS_NAT_VRF_ENTRY_TBL_ADDR 0x0484 +#define DESS_NAT_VRF_ENTRY_MASK_ADDR 0x0488 + +a_uint8_t _dess_snat_matched(a_uint32_t dev_id, fal_ip4_addr_t addr) +{ + a_bool_t nat_enable = 0, napt_enable = 0; + fal_ip4_addr_t mask = 0, base = 0; + a_uint32_t reg_addr; + sw_error_t rv; + + _dess_nat_status_get(dev_id, &nat_enable); + _dess_napt_status_get(dev_id, &napt_enable); + if(!(nat_enable & napt_enable)) + return 0; + + /*check for private base ip*/ + reg_addr = DESS_NAT_VRF_ENTRY_MASK_ADDR; + HSL_REG_ENTRY_GEN_GET(rv, dev_id, reg_addr, sizeof (a_uint32_t), + (a_uint8_t *) (&mask), sizeof (a_uint32_t)); + + reg_addr = DESS_NAT_VRF_ENTRY_TBL_ADDR; + HSL_REG_ENTRY_GEN_GET(rv, dev_id, reg_addr, sizeof (a_uint32_t), + (a_uint8_t *) (&base), sizeof (a_uint32_t)); + if (rv) + return 0; + if((mask&addr) == (mask&base)) { + return 1; + } + + return 0; +} + +a_uint8_t _dess_dnat_matched( + a_uint32_t dev_id, + fal_ip4_addr_t addr, + a_uint8_t *index) +{ + a_bool_t nat_enable = 0, napt_enable = 0; + fal_nat_pub_addr_t entry; + sw_error_t ret; + + _dess_nat_status_get(dev_id, &nat_enable); + _dess_napt_status_get(dev_id, &napt_enable); + if(!(nat_enable & napt_enable)) + return 0; + + /*check for public ip*/ + memset(&entry, 0, sizeof(entry)); + entry.entry_id = FAL_NEXT_ENTRY_FIRST_ID; + while(1) { + ret = _dess_nat_pub_addr_next(dev_id, 0, &entry); + if(ret) { + break; + } + if(entry.pub_addr == addr) { + *index = entry.entry_id; + return 1; + } + } + return 0; +} + + + +static sw_error_t +_dess_flow_cookie_snat_set(a_uint32_t dev_id, fal_flow_cookie_t * flow_cookie) +{ + fal_napt_entry_t entry; + sw_error_t ret; + + memset(&entry, 0, sizeof(entry)); + entry.flags = FAL_NAT_ENTRY_TRANS_IPADDR_INDEX | flow_cookie->proto; + entry.status = 0xf; + entry.src_addr = flow_cookie->src_addr; + entry.dst_addr = flow_cookie->dst_addr; + entry.src_port = flow_cookie->src_port; + entry.dst_port = flow_cookie->dst_port; + entry.trans_port = flow_cookie->src_port; + entry.action = FAL_MAC_RDT_TO_CPU; + ret = _dess_napt_get(dev_id, 0, &entry); + if(ret) { + if(flow_cookie->flow_cookie == 0) + return SW_OK; + } + if(flow_cookie->flow_cookie == 0) { + if(entry.flow_cookie == 0) { + ret = _dess_napt_del(dev_id, FAL_NAT_ENTRY_KEY_EN, &entry); + #if defined(IN_NAT_HELPER) + #if 0 + napt_cookie[entry.entry_id*2+1] = 0; + #endif + if (dess_nat_global_status) + nat_helper_cookie_del(entry.entry_id); + #endif + return ret; + } + ret = _dess_napt_del(dev_id, FAL_NAT_ENTRY_KEY_EN, &entry); + } else { + entry.flow_cookie = flow_cookie->flow_cookie; + ret = _dess_napt_add(dev_id, &entry); + } + + return ret; +} + +static sw_error_t +_dess_flow_cookie_dnat_set( + a_uint32_t dev_id, + fal_flow_cookie_t * flow_cookie, + a_uint8_t index) +{ + fal_napt_entry_t entry; + sw_error_t ret = 0; + + memset(&entry, 0, sizeof(entry)); + entry.flags = FAL_NAT_ENTRY_TRANS_IPADDR_INDEX | flow_cookie->proto; + entry.status = 0xf; + entry.trans_addr = index; + entry.trans_port = flow_cookie->dst_port; + entry.dst_addr = flow_cookie->src_addr; + entry.dst_port = flow_cookie->src_port; + entry.src_port = flow_cookie->dst_port; + entry.action = FAL_MAC_RDT_TO_CPU; + ret = _dess_napt_get(dev_id, 0, &entry); + if(ret) { + if(flow_cookie->flow_cookie == 0) { + return SW_OK; + } else { + /*add a fresh flowcookie*/ + entry.flow_cookie = flow_cookie->flow_cookie; + ret = _dess_napt_add(dev_id, &entry); + return ret; + } + } + if(flow_cookie->flow_cookie == 0) { + /*del flow cookie*/ + if(entry.flow_cookie == 0) { + ret = _dess_napt_del(dev_id, FAL_NAT_ENTRY_KEY_EN, &entry); + #if defined(IN_NAT_HELPER) + #if 0 + napt_cookie[entry.entry_id*2] = 0; + #endif + if (dess_nat_global_status) + nat_helper_cookie_del(entry.entry_id); + #endif + return ret; + } + ret = _dess_napt_del(dev_id, FAL_NAT_ENTRY_KEY_EN, &entry); + if(entry.load_balance & 4) { + /*keep rfs*/ + entry.flow_cookie = 0; + ret = _dess_napt_add(dev_id, &entry); + return ret; + } + } else { + /*add flow cookie*/ + ret = _dess_napt_del(dev_id, FAL_NAT_ENTRY_KEY_EN, &entry); + entry.flow_cookie = flow_cookie->flow_cookie; + ret = _dess_napt_add(dev_id, &entry); + return ret; + } + return ret; + +} + +static sw_error_t +_dess_flow_rfs_dnat_set( + a_uint32_t dev_id, + a_uint8_t action, + fal_flow_rfs_t * rfs, + a_uint8_t index) +{ + fal_napt_entry_t entry; + sw_error_t ret = 0; + + memset(&entry, 0, sizeof(entry)); + entry.flags = FAL_NAT_ENTRY_TRANS_IPADDR_INDEX | rfs->proto; + entry.status = 0xf; + entry.trans_addr = index; + entry.trans_port = rfs->dst_port; + entry.dst_addr = rfs->src_addr; + entry.dst_port = rfs->src_port; + entry.src_port = rfs->dst_port; + entry.action = FAL_MAC_RDT_TO_CPU; + ret = _dess_napt_get(dev_id, 0, &entry); + if(ret) { + if(action == 0) { + return SW_FAIL; + } else { + /*add a fresh rfs*/ + entry.load_balance = rfs->load_balance | 4; + ret = _dess_napt_add(dev_id, &entry); + return ret; + } + } + if(action == 0) { + /*del flow rfs*/ + ret = _dess_napt_del(dev_id, FAL_NAT_ENTRY_KEY_EN, &entry); + if(entry.flow_cookie != 0) { + /*keep cookie*/ + entry.load_balance = 0; + ret = _dess_napt_add(dev_id, &entry); + return ret; + } + } else { + /*add flow rfs*/ + ret = _dess_napt_del(dev_id, FAL_NAT_ENTRY_KEY_EN, &entry); + entry.load_balance = rfs->load_balance | 4; + ret = _dess_napt_add(dev_id, &entry); + return ret; + } + return ret; + +} + + +static sw_error_t +_dess_flow_cookie_set(a_uint32_t dev_id, fal_flow_cookie_t * flow_cookie) +{ + fal_napt_entry_t entry; + sw_error_t ret; + a_uint8_t index; + + if(_dess_dnat_matched(dev_id, flow_cookie->dst_addr, &index)) + return _dess_flow_cookie_dnat_set(dev_id, flow_cookie, index); + if(_dess_snat_matched(dev_id, flow_cookie->src_addr)) + return _dess_flow_cookie_snat_set(dev_id, flow_cookie); + + /*normal flow*/ + memset(&entry, 0, sizeof(entry)); + entry.flags = flow_cookie->proto; + entry.src_addr = flow_cookie->src_addr; + entry.dst_addr = flow_cookie->dst_addr; + entry.src_port = flow_cookie->src_port; + entry.dst_port = flow_cookie->dst_port; + ret = _dess_flow_get(0, 0, &entry); + if(SW_OK != ret && flow_cookie->flow_cookie == 0) + return ret; + if(flow_cookie->flow_cookie == 0) { + /*del*/ + _dess_flow_del(0, FAL_NAT_ENTRY_KEY_EN, &entry); + if(entry.load_balance & 4) { + entry.status = 0xf; + entry.flow_cookie = 0; + return _dess_flow_add(0, &entry); + } + } else { + /*add*/ + if(ret == SW_OK) + _dess_flow_del(0, FAL_NAT_ENTRY_KEY_EN, &entry); + entry.status = 0xf; + entry.flow_cookie = flow_cookie->flow_cookie; + return _dess_flow_add(0, &entry); + } + return SW_OK; +} + +static sw_error_t +_dess_flow_rfs_set(a_uint32_t dev_id, a_uint8_t action, fal_flow_rfs_t * rfs) +{ + fal_napt_entry_t entry; + sw_error_t ret; + a_uint8_t index; + + if(_dess_dnat_matched(dev_id, rfs->dst_addr, &index)) + return _dess_flow_rfs_dnat_set(dev_id, action, rfs, index); + + memset(&entry, 0, sizeof(entry)); + entry.flags = rfs->proto; + entry.src_addr = rfs->src_addr; + entry.dst_addr = rfs->dst_addr; + entry.src_port = rfs->src_port; + entry.dst_port = rfs->dst_port; + ret = _dess_flow_get(0, 0, &entry); + if(SW_OK != ret && action == 0) + return ret; + if(action == 0) { + /*del*/ + _dess_flow_del(0, FAL_NAT_ENTRY_KEY_EN, &entry); + if(entry.flow_cookie != 0) { + entry.load_balance = 0; + return _dess_flow_add(0, &entry); + } + } else { + /*add*/ + if(ret == SW_OK) + _dess_flow_del(0, FAL_NAT_ENTRY_KEY_EN, &entry); + entry.status = 0xf; + entry.load_balance = rfs->load_balance | 0x4; + return _dess_flow_add(0, &entry); + } + return SW_OK; +} + + + +sw_error_t +dess_nat_reset(a_uint32_t dev_id) +{ + sw_error_t rv; + a_uint32_t index, addr, data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + dess_nat_snap[dev_id] = 0; + + HSL_REG_ENTRY_SET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = _dess_nat_entry_commit(dev_id, DESS_ENTRY_NAT, DESS_NAT_ENTRY_FLUSH); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = _dess_nat_entry_commit(dev_id, DESS_ENTRY_NAPT, DESS_NAT_ENTRY_FLUSH); + SW_RTN_ON_ERROR(rv); + + rv = _dess_nat_entry_commit(dev_id, DESS_ENTRY_FLOW, DESS_NAT_ENTRY_FLUSH); + SW_RTN_ON_ERROR(rv); + + for (index = 0; index < DESS_PUB_ADDR_NUM; index++) + { + addr = DESS_PUB_ADDR_TBL1_ADDR + (index << 4); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +/** + * @brief Add one NAT entry to one particular device. + * @details Comments: + Before NAT entry added ip4 private base address must be set + at first. + In parameter nat_entry entry flags must be set + Hardware entry id will be returned. + * @param[in] dev_id device id + * @param[in] nat_entry NAT entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_nat_add(a_uint32_t dev_id, fal_nat_entry_t * nat_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_nat_add(dev_id, nat_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Del NAT entries from one particular device. + * @param[in] dev_id device id + * @param[in] del_mode NAT entry delete operation mode + * @param[in] nat_entry NAT entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_nat_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_nat_entry_t * nat_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_nat_del(dev_id, del_mode, nat_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get one NAT entry from one particular device. + * @param[in] dev_id device id + * @param[in] get_mode NAT entry get operation mode + * @param[in] nat_entry NAT entry parameter + * @param[out] nat_entry NAT entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_nat_get(a_uint32_t dev_id, a_uint32_t get_mode, + fal_nat_entry_t * nat_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_nat_get(dev_id, get_mode, nat_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Next NAT entries from one particular device. + * @param[in] dev_id device id + * @param[in] next_mode NAT entry next operation mode + * @param[in] nat_entry NAT entry parameter + * @param[out] nat_entry NAT entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_nat_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_nat_entry_t * nat_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_nat_next(dev_id, next_mode, nat_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Bind one counter entry to one NAT entry to one particular device. + * @param[in] dev_id device id + * @param[in] entry_id NAT entry id + * @param[in] cnt_id counter entry id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_nat_counter_bind(dev_id, entry_id, cnt_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add one NAPT entry to one particular device. + * @details Comments: + Before NAPT entry added related ip4 private base address must be set + at first. + In parameter napt_entry related entry flags must be set + Hardware entry id will be returned. + * @param[in] dev_id device id + * @param[in] napt_entry NAPT entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_napt_add(a_uint32_t dev_id, fal_napt_entry_t * napt_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_napt_add(dev_id, napt_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Del NAPT entries from one particular device. + * @param[in] dev_id device id + * @param[in] del_mode NAPT entry delete operation mode + * @param[in] napt_entry NAPT entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_napt_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_napt_entry_t * napt_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_napt_del(dev_id, del_mode, napt_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get one NAPT entry from one particular device. + * @param[in] dev_id device id + * @param[in] get_mode NAPT entry get operation mode + * @param[in] nat_entry NAPT entry parameter + * @param[out] nat_entry NAPT entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_napt_get(a_uint32_t dev_id, a_uint32_t get_mode, + fal_napt_entry_t * napt_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_napt_get(dev_id, get_mode, napt_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Next NAPT entries from one particular device. + * @param[in] dev_id device id + * @param[in] next_mode NAPT entry next operation mode + * @param[in] napt_entry NAPT entry parameter + * @param[out] napt_entry NAPT entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_napt_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_napt_entry_t * napt_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_napt_next(dev_id, next_mode, napt_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Bind one counter entry to one NAPT entry to one particular device. + * @param[in] dev_id device id + * @param[in] entry_id NAPT entry id + * @param[in] cnt_id counter entry id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_napt_counter_bind(dev_id, entry_id, cnt_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add one FLOW entry to one particular device. + * @details Comments: + Before FLOW entry added related ip4 private base address must be set + at first. + In parameter napt_entry related entry flags must be set + Hardware entry id will be returned. + * @param[in] dev_id device id + * @param[in] napt_entry FLOW entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_flow_add(a_uint32_t dev_id, fal_napt_entry_t * napt_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_flow_add(dev_id, napt_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Del FLOW entries from one particular device. + * @param[in] dev_id device id + * @param[in] del_mode FLOW entry delete operation mode + * @param[in] napt_entry FLOW entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_flow_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_napt_entry_t * napt_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_flow_del(dev_id, del_mode, napt_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get one FLOW entry from one particular device. + * @param[in] dev_id device id + * @param[in] get_mode FLOW entry get operation mode + * @param[in] nat_entry FLOW entry parameter + * @param[out] nat_entry FLOW entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_flow_get(a_uint32_t dev_id, a_uint32_t get_mode, + fal_napt_entry_t * napt_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_flow_get(dev_id, get_mode, napt_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Next FLOW entries from one particular device. + * @param[in] dev_id device id + * @param[in] next_mode FLOW entry next operation mode + * @param[in] napt_entry FLOW entry parameter + * @param[out] napt_entry FLOW entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_flow_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_napt_entry_t * napt_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_flow_next(dev_id, next_mode, napt_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Bind one counter entry to one FLOW entry to one particular device. + * @param[in] dev_id device id + * @param[in] entry_id FLOW entry id + * @param[in] cnt_id counter entry id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_flow_counter_bind(dev_id, entry_id, cnt_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set working status of NAT engine on a particular device + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_nat_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_nat_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get working status of NAT engine on a particular device + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_nat_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_nat_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set NAT hash mode on a particular device + * @param[in] dev_id device id + * @param[in] mode NAT hash mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_nat_hash_mode_set(a_uint32_t dev_id, a_uint32_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_nat_hash_mode_set(dev_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get NAT hash mode on a particular device + * @param[in] dev_id device id + * @param[out] mode NAT hash mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_nat_hash_mode_get(a_uint32_t dev_id, a_uint32_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_nat_hash_mode_get(dev_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set working status of NAPT engine on a particular device + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_napt_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_napt_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get working status of NAPT engine on a particular device + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_napt_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_napt_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set working mode of NAPT engine on a particular device + * @param[in] dev_id device id + * @param[in] mode NAPT mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_napt_mode_set(a_uint32_t dev_id, fal_napt_mode_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_napt_mode_set(dev_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get working mode of NAPT engine on a particular device + * @param[in] dev_id device id + * @param[out] mode NAPT mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_napt_mode_get(a_uint32_t dev_id, fal_napt_mode_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_napt_mode_get(dev_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set IP4 private base address on a particular device + * @details Comments: + Only 20bits is meaning which 20bits is determined by private address mode. + * @param[in] dev_id device id + * @param[in] addr private base address + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_nat_prv_base_addr_set(a_uint32_t dev_id, fal_ip4_addr_t addr) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_nat_prv_base_addr_set(dev_id, addr); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IP4 private base address on a particular device + * @param[in] dev_id device id + * @param[out] addr private base address + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_nat_prv_base_addr_get(a_uint32_t dev_id, fal_ip4_addr_t * addr) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_nat_prv_base_addr_get(dev_id, addr); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set IP4 private base address on a particular device + * @param[in] dev_id device id + * @param[in] mask private base mask + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_nat_prv_base_mask_set(a_uint32_t dev_id, fal_ip4_addr_t mask) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_nat_prv_base_mask_set(dev_id, mask); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IP4 private base address on a particular device + * @param[in] dev_id device id + * @param[out] mask private base mask + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_nat_prv_base_mask_get(a_uint32_t dev_id, fal_ip4_addr_t * mask) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_nat_prv_base_mask_get(dev_id, mask); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add one public address entry to one particular device. + * @details Comments: + Hardware entry id will be returned. + * @param[in] dev_id device id + * @param[in] entry public address entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_nat_pub_addr_add(a_uint32_t dev_id, fal_nat_pub_addr_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_nat_pub_addr_add(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete one public address entry from one particular device. + * @param[in] dev_id device id + * @param[in] del_mode delete operaton mode + * @param[in] entry public address entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_nat_pub_addr_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_nat_pub_addr_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_nat_pub_addr_del(dev_id, del_mode, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Next public address entries from one particular device. + * @param[in] dev_id device id + * @param[in] next_mode next operaton mode + * @param[out] entry public address entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_nat_pub_addr_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_nat_pub_addr_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_nat_pub_addr_next(dev_id, next_mode, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set forwarding command for those packets miss NAT entries on a particular device. + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_nat_unk_session_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_nat_unk_session_cmd_set(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get forwarding command for those packets miss NAT entries on a particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_nat_unk_session_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_nat_unk_session_cmd_get(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set working status of NAT engine on a particular device + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] portbmp port bitmap + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_nat_global_set(a_uint32_t dev_id, a_bool_t enable, a_uint32_t portbmp) +{ + sw_error_t rv = SW_OK; + + HSL_API_LOCK; + printk("enable:%d\n", enable); + if(enable) { + if(dess_nat_global_status == 0) { + dess_nat_global_status = 1; +#if defined(IN_NAT_HELPER) + DESS_NAT_HELPER_INIT(rv, dev_id, portbmp); +#endif + } + } else { + if(dess_nat_global_status == 1) { + dess_nat_global_status = 0; +#if defined(IN_NAT_HELPER) + DESS_NAT_HELPER_CLEANUP(rv, dev_id); +#endif + } + } + //rv = SW_OK; + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add/del one FLOW cookie entry to one particular device. + * @details Comments: + Before FLOW entry added related ip4 private base address must be set + at first. + In parameter napt_entry related entry flags must be set + Hardware entry id will be returned. + * @param[in] dev_id device id + * @param[in] FLOW cookie entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_flow_cookie_set(a_uint32_t dev_id, fal_flow_cookie_t * flow_cookie) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_flow_cookie_set(dev_id, flow_cookie); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add/del one FLOW rfs entry to one particular device. + * @details Comments: + Before FLOW entry added related ip4 private base address must be set + at first. + In parameter napt_entry related entry flags must be set + Hardware entry id will be returned. + * @param[in] dev_id device id + * @param[in] FLOW cookie entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_flow_rfs_set(a_uint32_t dev_id, a_uint8_t action, fal_flow_rfs_t * rfs) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_flow_rfs_set(dev_id, action, rfs); + HSL_API_UNLOCK; + return rv; +} + + + +sw_error_t +dess_nat_init(a_uint32_t dev_id) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + aos_lock_init(&dess_nat_lock); + + rv = dess_nat_reset(dev_id); + SW_RTN_ON_ERROR(rv); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->nat_add = dess_nat_add; + p_api->nat_del = dess_nat_del; + p_api->nat_get = dess_nat_get; + p_api->nat_next = dess_nat_next; + p_api->nat_counter_bind = dess_nat_counter_bind; + p_api->napt_add = dess_napt_add; + p_api->napt_del = dess_napt_del; + p_api->napt_get = dess_napt_get; + p_api->napt_next = dess_napt_next; + p_api->napt_counter_bind = dess_napt_counter_bind; + p_api->flow_add = dess_flow_add; + p_api->flow_del = dess_flow_del; + p_api->flow_get = dess_flow_get; + p_api->flow_next = dess_flow_next; + p_api->flow_counter_bind = dess_flow_counter_bind; + p_api->nat_status_set = dess_nat_status_set; + p_api->nat_status_get = dess_nat_status_get; + p_api->nat_hash_mode_set = dess_nat_hash_mode_set; + p_api->nat_hash_mode_get = dess_nat_hash_mode_get; + p_api->napt_status_set = dess_napt_status_set; + p_api->napt_status_get = dess_napt_status_get; + p_api->napt_mode_set = dess_napt_mode_set; + p_api->napt_mode_get = dess_napt_mode_get; + p_api->nat_pub_addr_add = dess_nat_pub_addr_add; + p_api->nat_pub_addr_del = dess_nat_pub_addr_del; + p_api->nat_pub_addr_next = dess_nat_pub_addr_next; + p_api->nat_unk_session_cmd_set = dess_nat_unk_session_cmd_set; + p_api->nat_unk_session_cmd_get = dess_nat_unk_session_cmd_get; + p_api->nat_prv_base_addr_set = dess_nat_prv_base_addr_set; + p_api->nat_prv_base_addr_get = dess_nat_prv_base_addr_get; + p_api->nat_prv_base_mask_set = dess_nat_prv_base_mask_set; + p_api->nat_prv_base_mask_get = dess_nat_prv_base_mask_get; + p_api->nat_global_set = dess_nat_global_set; + p_api->flow_cookie_set = dess_flow_cookie_set; + p_api->flow_rfs_set = dess_flow_rfs_set; + } +#endif + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_port_ctrl.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_port_ctrl.c new file mode 100755 index 000000000..f038ee9ff --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_port_ctrl.c @@ -0,0 +1,3983 @@ +/* + * 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 dess_port_ctrl DESS_PORT_CONTROL + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "dess_port_ctrl.h" +#include "dess_reg.h" +#include "hsl_phy.h" + +#define DMA_MAX_VIRT_RING 8 +extern a_bool_t dess_mac_port_valid_check (fal_port_t port_id); + +/* +PORT0 egress 6 queues +PORT1~4 egress 4 queues +PORT5 egress 6 queues +*/ +static a_uint32_t port_queue[6] = { 6, 4, 4, 4, 4, 6 }; + + +static a_bool_t +_dess_port_phy_connected (a_uint32_t dev_id, fal_port_t port_id) +{ + if (0 == port_id) + { + return A_FALSE; + } + else + { + + return dess_mac_port_valid_check (port_id); + } +} + +static sw_error_t +_dess_port_duplex_set (a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t duplex) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_duplex_set) + return SW_NOT_SUPPORTED; + + if (FAL_DUPLEX_BUTT <= duplex) + { + return SW_BAD_PARAM; + } + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_duplex_set (dev_id, phy_id, duplex); + SW_RTN_ON_ERROR (rv); +#if 0 + HSL_REG_ENTRY_GET (rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_val), sizeof (a_uint32_t)); + + /* for those ports without PHY device we set MAC register */ + if (A_FALSE == _dess_port_phy_connected (dev_id, port_id)) + { + SW_SET_REG_BY_FIELD (PORT_STATUS, LINK_EN, 0, reg_val); + if (FAL_HALF_DUPLEX == duplex) + { + SW_SET_REG_BY_FIELD (PORT_STATUS, DUPLEX_MODE, 0, reg_val); + } + else + { + SW_SET_REG_BY_FIELD (PORT_STATUS, DUPLEX_MODE, 1, reg_val); + } + reg_save = reg_val; + } + else + { + /* hardware requirement: set mac be config by sw and turn off RX/TX MAC */ + reg_save = reg_val; + SW_SET_REG_BY_FIELD (PORT_STATUS, LINK_EN, 0, reg_val); + SW_SET_REG_BY_FIELD (PORT_STATUS, RXMAC_EN, 0, reg_val); + SW_SET_REG_BY_FIELD (PORT_STATUS, TXMAC_EN, 0, reg_val); + + HSL_REG_ENTRY_SET (rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_val), sizeof (a_uint32_t)); + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_duplex_set (dev_id, phy_id, duplex); + SW_RTN_ON_ERROR (rv); + + /* If MAC not in sync with PHY mode, the behavior is undefine. + You must be careful... */ + SW_GET_FIELD_BY_REG (PORT_STATUS, LINK_EN, force, reg_save); + if (!force) + { + if (FAL_HALF_DUPLEX == duplex) + { + SW_SET_REG_BY_FIELD (PORT_STATUS, DUPLEX_MODE, 0, reg_save); + } + else + { + SW_SET_REG_BY_FIELD (PORT_STATUS, DUPLEX_MODE, 1, reg_save); + } + } + } + + HSL_REG_ENTRY_SET (rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_save), sizeof (a_uint32_t)); + #endif + return rv; +} + +static sw_error_t +_dess_port_duplex_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t * pduplex) +{ + sw_error_t rv = SW_OK; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + /* for those ports without PHY device supposed always full duplex */ + if (A_FALSE == _dess_port_phy_connected (dev_id, port_id)) + { + *pduplex = FAL_FULL_DUPLEX; + } + else + { + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_duplex_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_duplex_get (dev_id, phy_id, pduplex); + SW_RTN_ON_ERROR (rv); + } +#if 0 + HSL_REG_ENTRY_GET (rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_GET_FIELD_BY_REG (PORT_STATUS, DUPLEX_MODE, field, reg); + if (field) + { + *pduplex = FAL_FULL_DUPLEX; + } + else + { + *pduplex = FAL_HALF_DUPLEX; + } + +#endif + + return rv; +} + +static sw_error_t +_dess_port_speed_set (a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t speed) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_speed_set) + return SW_NOT_SUPPORTED; + + if (FAL_SPEED_1000 < speed) + { + return SW_BAD_PARAM; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_speed_set (dev_id, phy_id, speed); + SW_RTN_ON_ERROR (rv); +#if 0 + HSL_REG_ENTRY_GET (rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_val), sizeof (a_uint32_t)); + + /* for those ports without PHY device we set MAC register */ + if (A_FALSE == _dess_port_phy_connected (dev_id, port_id)) + { + SW_SET_REG_BY_FIELD (PORT_STATUS, LINK_EN, 0, reg_val); + if (FAL_SPEED_10 == speed) + { + SW_SET_REG_BY_FIELD (PORT_STATUS, SPEED_MODE, 0, reg_val); + } + else if (FAL_SPEED_100 == speed) + { + SW_SET_REG_BY_FIELD (PORT_STATUS, SPEED_MODE, 1, reg_val); + } + else + { + SW_SET_REG_BY_FIELD (PORT_STATUS, SPEED_MODE, 2, reg_val); + } + reg_save = reg_val; + + } + else + { + /* hardware requirement: set mac be config by sw and turn off RX/TX MAC */ + reg_save = reg_val; + SW_SET_REG_BY_FIELD (PORT_STATUS, LINK_EN, 0, reg_val); + SW_SET_REG_BY_FIELD (PORT_STATUS, RXMAC_EN, 0, reg_val); + SW_SET_REG_BY_FIELD (PORT_STATUS, TXMAC_EN, 0, reg_val); + + HSL_REG_ENTRY_SET (rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_val), sizeof (a_uint32_t)); + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_speed_set (dev_id, phy_id, speed); + SW_RTN_ON_ERROR (rv); + + /* If MAC not in sync with PHY mode, the behavior is undefine. + You must be careful... */ + SW_GET_FIELD_BY_REG (PORT_STATUS, LINK_EN, force, reg_save); + if (!force) + { + if (FAL_SPEED_10 == speed) + { + SW_SET_REG_BY_FIELD (PORT_STATUS, SPEED_MODE, 0, reg_save); + } + else if (FAL_SPEED_100 == speed) + { + SW_SET_REG_BY_FIELD (PORT_STATUS, SPEED_MODE, 1, reg_save); + } + else + { + SW_SET_REG_BY_FIELD (PORT_STATUS, SPEED_MODE, 2, reg_save); + } + } + } + + HSL_REG_ENTRY_SET (rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_save), sizeof (a_uint32_t)); + #endif + return rv; +} + +static sw_error_t +_dess_port_speed_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t * pspeed) +{ + sw_error_t rv = SW_OK; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + /* for those ports without PHY device supposed always 1000Mbps */ + if (A_FALSE == _dess_port_phy_connected (dev_id, port_id)) + { + *pspeed = FAL_SPEED_1000; + } + else + { + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_speed_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + rv = phy_drv->phy_speed_get (dev_id, phy_id, pspeed); + SW_RTN_ON_ERROR (rv); + } +#if 0 + HSL_REG_ENTRY_GET (rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR (rv); + + SW_GET_FIELD_BY_REG (PORT_STATUS, SPEED_MODE, field, reg); + if (0 == field) + { + *pspeed = FAL_SPEED_10; + } + else if (1 == field) + { + *pspeed = FAL_SPEED_100; + } + else if (2 == field) + { + *pspeed = FAL_SPEED_1000; + } + else + { + *pspeed = FAL_SPEED_BUTT; + rv = SW_READ_ERROR; + } +#endif + + return rv; +} + +static sw_error_t +_dess_port_autoneg_status_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status) +{ + a_uint32_t phy_id; + sw_error_t rv; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_autoneg_status_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + *status = phy_drv->phy_autoneg_status_get (dev_id, phy_id); + + return SW_OK; +} + +static sw_error_t +_dess_port_autoneg_enable (a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_autoneg_enable_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_autoneg_enable_set (dev_id, phy_id); + return rv; +} + +static sw_error_t +_dess_port_autoneg_restart (a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_restart_autoneg) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_restart_autoneg (dev_id, phy_id); + return rv; +} + +static sw_error_t +_dess_port_autoneg_adv_set (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t autoadv) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_autoneg_adv_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_autoneg_adv_set (dev_id, phy_id, autoadv); + SW_RTN_ON_ERROR (rv); + + return SW_OK; +} + +static sw_error_t +_dess_port_autoneg_adv_get (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * autoadv) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_autoneg_adv_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + *autoadv = 0; + rv = phy_drv->phy_autoneg_adv_get (dev_id, phy_id, autoadv); + SW_RTN_ON_ERROR (rv); + + return SW_OK; +} + +static sw_error_t +_dess_port_flowctrl_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val, force, reg = 0, tmp; + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET (rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR (rv); + + SW_GET_FIELD_BY_REG (PORT_STATUS, FLOW_LINK_EN, force, reg); + if (force) + { + /* flow control isn't in force mode so can't set */ + return SW_DISABLE; + } + tmp = reg; + + SW_SET_REG_BY_FIELD (PORT_STATUS, RX_FLOW_EN, val, reg); + SW_SET_REG_BY_FIELD (PORT_STATUS, TX_FLOW_EN, val, reg); + SW_SET_REG_BY_FIELD (PORT_STATUS, TX_HALF_FLOW_EN, val, reg); + if (reg == tmp) + return SW_OK; + + HSL_REG_ENTRY_SET (rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_port_flowctrl_thresh_set (a_uint32_t dev_id, fal_port_t port_id, + a_uint8_t on, a_uint8_t off) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + reg = (on << 16) | off; + HSL_REG_ENTRY_SET (rv, dev_id, PORT_FLOC_CTRL_THRESH, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_port_flowctrl_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t rx, reg = 0; + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET (rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR (rv); + + SW_GET_FIELD_BY_REG (PORT_STATUS, RX_FLOW_EN, rx, reg); + + if (1 == rx) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_port_flowctrl_forcemode_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t reg = 0, tmp; + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET (rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR (rv); + SW_GET_FIELD_BY_REG(PORT_STATUS, FLOW_LINK_EN, tmp, reg); + + if (A_TRUE == enable) + { + if (tmp== 0) + return SW_OK; + SW_SET_REG_BY_FIELD (PORT_STATUS, FLOW_LINK_EN, 0, reg); + } + else if (A_FALSE == enable) + { + /* for those ports without PHY, it can't sync flow control status */ + if (A_FALSE == _dess_port_phy_connected (dev_id, port_id)) + { + return SW_DISABLE; + } + if (tmp == 1) + return SW_OK; + SW_SET_REG_BY_FIELD (PORT_STATUS, FLOW_LINK_EN, 1, reg); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_SET (rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_port_flowctrl_forcemode_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t force, reg; + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET (rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR (rv); + + SW_GET_FIELD_BY_REG (PORT_STATUS, FLOW_LINK_EN, force, reg); + if (0 == force) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_port_powersave_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_powersave_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_powersave_set (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_dess_port_powersave_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_powersave_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_powersave_get (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_dess_port_hibernate_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_hibernation_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_hibernation_set (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_dess_port_hibernate_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_hibernation_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_hibernation_get (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_dess_port_cdt (a_uint32_t dev_id, fal_port_t port_id, a_uint32_t mdi_pair, + fal_cable_status_t * cable_status, a_uint32_t * cable_len) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_cdt) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_cdt (dev_id, phy_id, mdi_pair, cable_status, cable_len); + + return rv; +} + +static sw_error_t +_dess_port_rxhdr_mode_set (a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t mode) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_NO_HEADER_EN == mode) + { + val = 0; + } + else if (FAL_ONLY_MANAGE_FRAME_EN == mode && port_id != 0) + { + val = 1; + } + else if (FAL_ALL_TYPE_FRAME_EN == mode) + { + val = 2; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET (rv, dev_id, PORT_HDR_CTL, port_id, RXHDR_MODE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_port_rxhdr_mode_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET (rv, dev_id, PORT_HDR_CTL, port_id, RXHDR_MODE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR (rv); + + if (1 == val) + { + *mode = FAL_ONLY_MANAGE_FRAME_EN; + } + else if (2 == val) + { + *mode = FAL_ALL_TYPE_FRAME_EN; + } + else + { + *mode = FAL_NO_HEADER_EN; + } + + return SW_OK; +} + +static sw_error_t +_dess_port_txhdr_mode_set (a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t mode) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_NO_HEADER_EN == mode) + { + val = 0; + } + else if (FAL_ONLY_MANAGE_FRAME_EN == mode) + { + val = 1; + } + else if (FAL_ALL_TYPE_FRAME_EN == mode) + { + val = 2; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET (rv, dev_id, PORT_HDR_CTL, port_id, TXHDR_MODE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_port_txhdr_mode_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET (rv, dev_id, PORT_HDR_CTL, port_id, TXHDR_MODE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR (rv); + + if (1 == val) + { + *mode = FAL_ONLY_MANAGE_FRAME_EN; + } + else if (2 == val) + { + *mode = FAL_ALL_TYPE_FRAME_EN; + } + else + { + *mode = FAL_NO_HEADER_EN; + } + + return SW_OK; +} + +static sw_error_t +_dess_header_type_set (a_uint32_t dev_id, a_bool_t enable, a_uint32_t type) +{ + a_uint32_t reg = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK (dev_id); + + HSL_REG_ENTRY_GET (rv, dev_id, HEADER_CTL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR (rv); + + if (A_TRUE == enable) + { + if (0xffff < type) + { + return SW_BAD_PARAM; + } + SW_SET_REG_BY_FIELD (HEADER_CTL, TYPE_LEN, 1, reg); + SW_SET_REG_BY_FIELD (HEADER_CTL, TYPE_VAL, type, reg); + } + else if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD (HEADER_CTL, TYPE_LEN, 0, reg); + SW_SET_REG_BY_FIELD (HEADER_CTL, TYPE_VAL, 0, reg); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_SET (rv, dev_id, HEADER_CTL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_header_type_get (a_uint32_t dev_id, a_bool_t * enable, + a_uint32_t * type) +{ + a_uint32_t data, reg = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK (dev_id); + + HSL_REG_ENTRY_GET (rv, dev_id, HEADER_CTL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR (rv); + + SW_GET_FIELD_BY_REG (HEADER_CTL, TYPE_LEN, data, reg); + if (data) + { + SW_GET_FIELD_BY_REG (HEADER_CTL, TYPE_VAL, data, reg); + *enable = A_TRUE; + *type = data; + } + else + { + *enable = A_FALSE; + *type = 0; + } + + return SW_OK; +} + +static sw_error_t +_dess_port_txmac_status_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t reg, force, val = 0, tmp; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET (rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR (rv); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + tmp = reg; + + /* for those ports without PHY device we set MAC register */ + if (A_FALSE == _dess_port_phy_connected (dev_id, port_id)) + { + SW_SET_REG_BY_FIELD (PORT_STATUS, LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD (PORT_STATUS, TXMAC_EN, val, reg); + } + else + { + SW_GET_FIELD_BY_REG (PORT_STATUS, LINK_EN, force, reg); + if (force) + { + /* link isn't in force mode so can't set */ + return SW_DISABLE; + } + else + { + SW_SET_REG_BY_FIELD (PORT_STATUS, TXMAC_EN, val, reg); + } + } + if (tmp == reg) + return SW_OK; + HSL_REG_ENTRY_SET (rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_port_txmac_status_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET (rv, dev_id, PORT_STATUS, port_id, TXMAC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR (rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_port_rxmac_status_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t reg = 0, force, val = 0, tmp = 0; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET (rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR (rv); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + tmp = reg; + + /* for those ports without PHY device we set MAC register */ + if (A_FALSE == _dess_port_phy_connected (dev_id, port_id)) + { + SW_SET_REG_BY_FIELD (PORT_STATUS, LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD (PORT_STATUS, RXMAC_EN, val, reg); + } + else + { + SW_GET_FIELD_BY_REG (PORT_STATUS, LINK_EN, force, reg); + if (force) + { + /* link isn't in force mode so can't set */ + return SW_DISABLE; + } + else + { + SW_SET_REG_BY_FIELD (PORT_STATUS, RXMAC_EN, val, reg); + } + } + if (tmp == reg) + return SW_OK; + HSL_REG_ENTRY_SET (rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_port_rxmac_status_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET (rv, dev_id, PORT_STATUS, port_id, RXMAC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR (rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_port_txfc_status_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val = 0, reg = 0, force, tmp; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET (rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR (rv); + tmp = reg; + + /* for those ports without PHY device we set MAC register */ + if (A_FALSE == _dess_port_phy_connected (dev_id, port_id)) + { + SW_SET_REG_BY_FIELD (PORT_STATUS, FLOW_LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD (PORT_STATUS, TX_FLOW_EN, val, reg); + } + else + { + SW_GET_FIELD_BY_REG (PORT_STATUS, FLOW_LINK_EN, force, reg); + if (force) + { + /* flow control isn't in force mode so can't set */ + return SW_DISABLE; + } + else + { + SW_SET_REG_BY_FIELD (PORT_STATUS, TX_FLOW_EN, val, reg); + } + } + if (tmp == reg) + return SW_OK; + HSL_REG_ENTRY_SET (rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_port_txfc_status_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET (rv, dev_id, PORT_STATUS, port_id, TX_FLOW_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR (rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_port_rxfc_status_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val = 0, reg, force, tmp; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET (rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR (rv); + tmp = reg; + + /* for those ports without PHY device we set MAC register */ + if (A_FALSE == _dess_port_phy_connected (dev_id, port_id)) + { + SW_SET_REG_BY_FIELD (PORT_STATUS, FLOW_LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD (PORT_STATUS, RX_FLOW_EN, val, reg); + } + else + { + SW_GET_FIELD_BY_REG (PORT_STATUS, FLOW_LINK_EN, force, reg); + if (force) + { + /* flow control isn't in force mode so can't set */ + return SW_DISABLE; + } + else + { + SW_SET_REG_BY_FIELD (PORT_STATUS, RX_FLOW_EN, val, reg); + } + } + if (tmp == reg) + return SW_OK; + HSL_REG_ENTRY_SET (rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_port_rxfc_status_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET (rv, dev_id, PORT_STATUS, port_id, RX_FLOW_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR (rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_port_bp_status_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val = 0, tmp = 0; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + HSL_REG_FIELD_GET (rv, dev_id, PORT_STATUS, port_id, TX_HALF_FLOW_EN, + (a_uint8_t *) (&tmp), sizeof (a_uint32_t)); + if (tmp == val) + return SW_OK; + + HSL_REG_FIELD_SET (rv, dev_id, PORT_STATUS, port_id, TX_HALF_FLOW_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_port_bp_status_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET (rv, dev_id, PORT_STATUS, port_id, TX_HALF_FLOW_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR (rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_port_link_forcemode_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t reg = 0, tmp = 0; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET (rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR (rv); + SW_GET_FIELD_BY_REG(PORT_STATUS, LINK_EN, tmp, reg); + + if (A_TRUE == enable) + { + if(tmp == 0) + return SW_OK; + SW_SET_REG_BY_FIELD (PORT_STATUS, LINK_EN, 0, reg); + } + else if (A_FALSE == enable) + { + if(tmp == 1) + return SW_OK; + /* for those ports without PHY, it can't sync link status */ + if (A_FALSE == _dess_port_phy_connected (dev_id, port_id)) + { + return SW_DISABLE; + } + SW_SET_REG_BY_FIELD (PORT_STATUS, LINK_EN, 1, reg); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_SET (rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_port_link_forcemode_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET (rv, dev_id, PORT_STATUS, port_id, LINK_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR (rv); + + if (0 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_port_link_status_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + /* for those ports without PHY device supposed always link up */ + if (A_FALSE == _dess_port_phy_connected (dev_id, port_id)) + { + *status = A_TRUE; + } + else + { + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_link_status_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + if (A_TRUE == phy_drv->phy_link_status_get (dev_id, phy_id)) + { + *status = A_TRUE; + } + else + { + *status = A_FALSE; + } + } + + return SW_OK; +} + +static sw_error_t +_dess_ports_link_status_get(a_uint32_t dev_id, a_uint32_t * status) +{ + sw_error_t rv; + a_uint32_t port_id; + a_uint32_t phy_id; + hsl_dev_t *pdev = NULL; + hsl_phy_ops_t *phy_drv; + a_uint32_t port_bmp[SW_MAX_NR_DEV] = {0}; + + HSL_DEV_ID_CHECK(dev_id); + + pdev = hsl_dev_ptr_get(dev_id); + if (pdev == NULL) + return SW_NOT_INITIALIZED; + + port_bmp[dev_id] = qca_ssdk_phy_type_port_bmp_get(dev_id, MALIBU_PHY_CHIP); + + *status = 0x0; + for (port_id = 0; port_id < pdev->nr_ports; port_id++) + { + if (port_id >= SW_MAX_NR_PORT) + break; + /* for those ports without PHY device supposed always link up */ + if (A_FALSE == _dess_port_phy_connected(dev_id, port_id)) + { + *status |= (0x1 << port_id); + } + else + { + if(port_bmp[dev_id] & (0x1 << port_id)) + { + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_link_status_get) + return SW_NOT_SUPPORTED; + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == phy_drv->phy_link_status_get (dev_id, phy_id)) + { + *status |= (0x1 << port_id); + } + else + { + *status &= ~(0x1 << port_id); + } + } + } + } + return SW_OK; +} + +static sw_error_t +_dess_port_mac_loopback_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv = SW_OK; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET (rv, dev_id, PORT_HDR_CTL, port_id, LOOPBACK_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_port_mac_loopback_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET (rv, dev_id, PORT_HDR_CTL, port_id, LOOPBACK_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR (rv); + + if (0 == val) + { + *enable = A_FALSE; + } + else + { + *enable = A_TRUE; + } + + return SW_OK; +} + + +static sw_error_t +_dess_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 = SW_OK; + a_uint32_t val = 0, offset = 0, field = 0; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (queue_id >= port_queue[port_id]) + { + return SW_BAD_PARAM; + } + + if (port_id != 0) + offset = port_id * 4 + 2; + offset += queue_id; + + if (A_TRUE == enable) + { + field = 1 << offset; + } + else if (A_FALSE == enable) + { + field = ~(1 << offset); + } + else + { + return SW_BAD_PARAM; + } + + + + HSL_REG_ENTRY_GET (rv, dev_id, FLOW_CONGE_DROP_CTRL0, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + if (A_TRUE == enable) + { + val = val | field; + } + else + { + val = val & field; + } + + HSL_REG_ENTRY_SET (rv, dev_id, FLOW_CONGE_DROP_CTRL0, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + + +static sw_error_t +_dess_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 = SW_OK; + a_uint32_t val, offset = 0; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (queue_id >= port_queue[port_id]) + { + return SW_BAD_PARAM; + } + + if (port_id != 0) + offset = port_id * 4 + 2; + offset += queue_id; + + HSL_REG_ENTRY_GET (rv, dev_id, FLOW_CONGE_DROP_CTRL0, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + val = (val >> offset) & 0x1; + if (val == 0) + { + *enable = A_FALSE; + } + else if (val == 1) + { + *enable = A_TRUE; + } + return rv; +} + +static sw_error_t +_dess_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; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK (dev_id); + + if (ring_id >= DMA_MAX_VIRT_RING) + { + return SW_BAD_PARAM; + } + + if (on_thres > off_thres || on_thres == 0) + { + return SW_BAD_PARAM; + } + + SW_SET_REG_BY_FIELD (RING_FLOW_CTRL_THRES, XON, on_thres, val); + SW_SET_REG_BY_FIELD (RING_FLOW_CTRL_THRES, XOFF, off_thres, val); + HSL_REG_ENTRY_SET (rv, dev_id, RING_FLOW_CTRL_THRES, ring_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + + return rv; +} + + +static sw_error_t +_dess_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; + a_uint32_t val = 0; + a_uint8_t hthres, lthres; + + HSL_DEV_ID_CHECK (dev_id); + + if (ring_id >= DMA_MAX_VIRT_RING) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET (rv, dev_id, RING_FLOW_CTRL_THRES, ring_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + SW_GET_FIELD_BY_REG (RING_FLOW_CTRL_THRES, XON, hthres, val); + SW_GET_FIELD_BY_REG (RING_FLOW_CTRL_THRES, XOFF, lthres, val); + + *on_thres = hthres; + *off_thres = lthres; + + return rv; +} + +static sw_error_t +_dess_port_8023az_set (a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_8023az_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_8023az_set (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_dess_port_8023az_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_8023az_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_8023az_get (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_dess_port_mdix_set (a_uint32_t dev_id, fal_port_t port_id, + fal_port_mdix_mode_t mode) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_mdix_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_mdix_set (dev_id, phy_id, mode); + + return rv; +} + +static sw_error_t +_dess_port_mdix_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_mdix_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_mdix_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_mdix_get (dev_id, phy_id, mode); + + return rv; +} + +static sw_error_t +_dess_port_mdix_status_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_mdix_status_t * mode) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_mdix_status_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_mdix_status_get (dev_id, phy_id, mode); + + return rv; +} + +static sw_error_t +_dess_port_combo_prefer_medium_set (a_uint32_t dev_id, fal_port_t port_id, + fal_port_medium_t phy_medium) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_combo_prefer_medium_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_combo_prefer_medium_set (dev_id, phy_id, phy_medium); + + return rv; +} + +static sw_error_t +_dess_port_combo_prefer_medium_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_medium_t * phy_medium) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_combo_prefer_medium_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_combo_prefer_medium_get (dev_id, phy_id, phy_medium); + + return rv; +} + +static sw_error_t +_dess_port_combo_medium_status_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_medium_t * phy_medium) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_combo_medium_status_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_combo_medium_status_get (dev_id, phy_id, phy_medium); + + return rv; +} + +static sw_error_t +_dess_port_combo_fiber_mode_set (a_uint32_t dev_id, fal_port_t port_id, + fal_port_fiber_mode_t fiber_mode) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_combo_fiber_mode_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_combo_fiber_mode_set (dev_id, phy_id, fiber_mode); + + return rv; +} + +static sw_error_t +_dess_port_combo_fiber_mode_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_fiber_mode_t * fiber_mode) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_combo_fiber_mode_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_combo_fiber_mode_get (dev_id, phy_id, fiber_mode); + + return rv; +} + +static sw_error_t +_dess_port_local_loopback_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_local_loopback_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_local_loopback_set (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_dess_port_local_loopback_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_local_loopback_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_local_loopback_get (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_dess_port_remote_loopback_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_remote_loopback_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_remote_loopback_set (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_dess_port_remote_loopback_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_remote_loopback_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_remote_loopback_get (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_dess_port_reset (a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_reset) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_reset(dev_id, phy_id); + + return rv; +} + +static sw_error_t +_dess_port_power_off (a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_power_off) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_power_off(dev_id, phy_id); + + return rv; +} + +static sw_error_t +_dess_port_power_on (a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_power_on) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_power_on(dev_id, phy_id); + + return rv; +} + +static sw_error_t +_dess_port_wol_status_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_wol_status_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_wol_status_set (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_dess_port_wol_status_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_wol_status_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_wol_status_get (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_dess_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; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + a_uint32_t phy_data; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_id_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_id_get (dev_id, phy_id, &phy_data); + SW_RTN_ON_ERROR (rv); + + *org_id = (phy_data >> 16) & 0xffff; + *rev_id = phy_data & 0xffff; + + return rv; +} + +static sw_error_t +_dess_port_magic_frame_mac_set (a_uint32_t dev_id, fal_port_t port_id, + fal_mac_addr_t * mac) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_magic_frame_mac_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_magic_frame_mac_set (dev_id, phy_id,mac); + + return rv; +} + +static sw_error_t +_dess_port_magic_frame_mac_get (a_uint32_t dev_id, fal_port_t port_id, + fal_mac_addr_t * mac) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_magic_frame_mac_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_magic_frame_mac_get (dev_id, phy_id,mac); + + return rv; +} + +static sw_error_t +_dess_port_interface_mode_set (a_uint32_t dev_id, fal_port_t port_id, + fal_port_interface_mode_t mode) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_interface_mode_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_interface_mode_set (dev_id, phy_id,mode); + + return rv; +} + +static sw_error_t +_dess_port_interface_mode_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_interface_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_interface_mode_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_interface_mode_get (dev_id, phy_id,mode); + + return rv; +} + +static sw_error_t +_dess_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; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_interface_mode_status_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_interface_mode_status_get (dev_id, phy_id,mode); + + return rv; +} + +static sw_error_t +_dess_port_counter_set (a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_counter_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_counter_set (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_dess_port_counter_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_counter_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_counter_get (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_dess_port_counter_show (a_uint32_t dev_id, fal_port_t port_id, + fal_port_counter_info_t * counter_info) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_counter_show) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_counter_show (dev_id, phy_id,counter_info); + + return rv; +} + +/** + * @brief Set duplex mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] duplex duplex mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_duplex_set (a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t duplex) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_duplex_set (dev_id, port_id, duplex); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get duplex mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] duplex duplex mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_duplex_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t * pduplex) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_duplex_get (dev_id, port_id, pduplex); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set speed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] speed port speed + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_speed_set (a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t speed) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_speed_set (dev_id, port_id, speed); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get speed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] speed port speed + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_speed_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t * pspeed) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_speed_get (dev_id, port_id, pspeed); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get auto negotiation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] status A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_autoneg_status_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_autoneg_status_get (dev_id, port_id, status); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Enable auto negotiation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_autoneg_enable (a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_autoneg_enable (dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Restart auto negotiation procedule on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_autoneg_restart (a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_autoneg_restart (dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set auto negotiation advtisement ability on a particular port. + * @details Comments: + * auto negotiation advtisement ability is defined by macro such as + * FAL_PHY_ADV_10T_HD, FAL_PHY_ADV_PAUSE... + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] autoadv auto negotiation advtisement ability bit map + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_autoneg_adv_set (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t autoadv) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_autoneg_adv_set (dev_id, port_id, autoadv); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get auto negotiation advtisement ability on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] autoadv auto negotiation advtisement ability bit map + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_autoneg_adv_get (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * autoadv) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_autoneg_adv_get (dev_id, port_id, autoadv); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flow control(rx/tx/bp) status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_flowctrl_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_flowctrl_set (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flow control(rx/tx/bp) threshold on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] on on threshold + * @param[in] off off threshold + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_flowctrl_thresh_set (a_uint32_t dev_id, fal_port_t port_id, + a_uint8_t on, a_uint8_t off) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_flowctrl_thresh_set (dev_id, port_id, on, off); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get flow control status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_flowctrl_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_flowctrl_get (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flow control force mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_flowctrl_forcemode_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_flowctrl_forcemode_set (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get flow control force mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_flowctrl_forcemode_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_flowctrl_forcemode_get (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set powersaving status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_powersave_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_powersave_set (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get powersaving status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_powersave_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_powersave_get (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set hibernate status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_hibernate_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_hibernate_set (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get hibernate status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_hibernate_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_hibernate_get (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Run cable diagnostic test on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mdi_pair mdi pair id + * @param[out] cable_status cable status + * @param[out] cable_len cable len + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_cdt (a_uint32_t dev_id, fal_port_t port_id, a_uint32_t mdi_pair, + fal_cable_status_t * cable_status, a_uint32_t * cable_len) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_cdt (dev_id, port_id, mdi_pair, cable_status, cable_len); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of Atheros header packets parsed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_rxhdr_mode_set (a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_rxhdr_mode_set (dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get status of Atheros header packets parsed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_rxhdr_mode_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_rxhdr_mode_get (dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of Atheros header packets parsed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_txhdr_mode_set (a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_txhdr_mode_set (dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get status of Atheros header packets parsed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_txhdr_mode_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_txhdr_mode_get (dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of Atheros header type value on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] type header type value + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_header_type_set (a_uint32_t dev_id, a_bool_t enable, a_uint32_t type) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _dess_header_type_set (dev_id, enable, type); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get status of Atheros header type value on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @param[out] type header type value + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_header_type_get (a_uint32_t dev_id, a_bool_t * enable, a_uint32_t * type) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_header_type_get (dev_id, enable, type); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of txmac on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_txmac_status_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _dess_port_txmac_status_set (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get status of txmac on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_txmac_status_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_txmac_status_get (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of rxmac on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_rxmac_status_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _dess_port_rxmac_status_set (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get status of rxmac on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_rxmac_status_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_rxmac_status_get (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of tx flow control on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_txfc_status_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _dess_port_txfc_status_set (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get status of tx flow control on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_txfc_status_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_txfc_status_get (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of rx flow control on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_rxfc_status_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _dess_port_rxfc_status_set (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of rx flow control on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_rxfc_status_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_rxfc_status_get (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of back pressure on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_bp_status_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _dess_port_bp_status_set (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of back pressure on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_bp_status_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_bp_status_get (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set link force mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_link_forcemode_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _dess_port_link_forcemode_set (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get link force mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_link_forcemode_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_link_forcemode_get (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get link status on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] status link status up (A_TRUE) or down (A_FALSE) + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_link_status_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_link_status_get (dev_id, port_id, status); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get link status on all ports. + * @param[in] dev_id device id + * @param[out] status link status bitmap and bit 0 for port 0, bi 1 for port 1, ..., etc. + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_ports_link_status_get(a_uint32_t dev_id, a_uint32_t * status) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_ports_link_status_get(dev_id, status); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set mac loop back on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_mac_loopback_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _dess_port_mac_loopback_set (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mac loop back on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_mac_loopback_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_mac_loopback_get (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flow congestion drop on a particular port queue. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + HSL_API_LOCK; + rv = _dess_port_congestion_drop_set (dev_id, port_id, queue_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flow congestion drop on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_port_congestion_drop_get (dev_id, port_id, queue_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flow ctrl thres on a particular DMA ring. + * @param[in] dev_id device id + * @param[in] ring_id ring id + * @param[in] on_thres on_thres + * @param[in] off_thres off_thres + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + HSL_API_LOCK; + rv = _dess_ring_flow_ctrl_thres_set (dev_id, ring_id, on_thres, off_thres); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flow ctrl thres on a particular DMA ring. + * @param[in] dev_id device id + * @param[in] ring_id ring id + * @param[out] on_thres on_thres + * @param[out] off_thres off_thres + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_ring_flow_ctrl_thres_get (dev_id, ring_id, on_thres, off_thres); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set 802.3az status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_8023az_set (a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_8023az_set (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get 8023az status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_8023az_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_8023az_get (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set mdix on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_mdix_set (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_mdix_mode_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_mdix_set (dev_id, phy_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mdix configuration on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mode + * @return SW_OK or error code + */ + +HSL_LOCAL sw_error_t +dess_port_mdix_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_mdix_mode_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_mdix_get (dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mdix status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mode + * @return SW_OK or error code + */ + +HSL_LOCAL sw_error_t +dess_port_mdix_status_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_mdix_status_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_mdix_status_get (dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set combo prefer medium on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] phy_medium [fiber or copper] + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_combo_prefer_medium_set (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_medium_t phy_medium) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_combo_prefer_medium_set (dev_id, phy_id, phy_medium); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get combo prefer medium on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] phy_medium [fiber or copper] + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_combo_prefer_medium_get (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_medium_t * phy_medium) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_combo_prefer_medium_get (dev_id, phy_id, phy_medium); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get current combo medium status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] phy_medium [fiber or copper] + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_combo_medium_status_get (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_medium_t * phy_medium) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_combo_medium_status_get (dev_id, phy_id, phy_medium); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set fiber mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] fiber mode [1000bx or 100fx] + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_combo_fiber_mode_set (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_fiber_mode_t fiber_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_combo_fiber_mode_set (dev_id, phy_id, fiber_mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get fiber mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] fiber mode [1000bx or 100fx] + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_combo_fiber_mode_get (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_fiber_mode_t * fiber_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_combo_fiber_mode_get (dev_id, phy_id, fiber_mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set phy local loop back on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_local_loopback_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _dess_port_local_loopback_set (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get phy local loop back on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_local_loopback_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_local_loopback_get (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set phy remote loop back on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_remote_loopback_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _dess_port_remote_loopback_set (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get phy remote loop back on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_remote_loopback_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_remote_loopback_get (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief software reset on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_reset (a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _dess_port_reset (dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief phy power off on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_power_off (a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _dess_port_power_off (dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief phy power on on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_power_on (a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _dess_port_power_on (dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set phy wol enable on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_wol_status_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _dess_port_wol_status_set (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get phy wol status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_wol_status_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_wol_status_get (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get phy id on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] org_id and rev_id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_port_phy_id_get (dev_id, port_id, org_id,rev_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set phy magic frame mac on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mac address + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_magic_frame_mac_set (a_uint32_t dev_id, fal_port_t port_id, + fal_mac_addr_t * mac) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _dess_port_magic_frame_mac_set (dev_id, port_id, mac); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get phy magic frame mac on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mac address + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_magic_frame_mac_get (a_uint32_t dev_id, fal_port_t port_id, + fal_mac_addr_t * mac) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _dess_port_magic_frame_mac_get (dev_id, port_id, mac); + HSL_API_UNLOCK; + return rv; +} + + +/** + * @brief Set phy interface mode. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] interface mode.. + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_interface_mode_set (a_uint32_t dev_id, fal_port_t port_id, + fal_port_interface_mode_t mode) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _dess_port_interface_mode_set (dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set phy interface mode. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] interface mode.. + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_interface_mode_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_interface_mode_t * mode) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _dess_port_interface_mode_get (dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set phy interface mode status. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] interface mode.. + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + HSL_API_LOCK; + rv = _dess_port_interface_mode_status_get (dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set counter status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_counter_set (a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_counter_set (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get counter status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_counter_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_counter_get (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get counter statistics on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] frame counter statistics + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_counter_show(a_uint32_t dev_id, fal_port_t port_id, + fal_port_counter_info_t * counter_info) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_counter_show (dev_id, port_id, counter_info); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +dess_port_ctrl_init (a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK (dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get (dev_id)); + + p_api->port_duplex_get = dess_port_duplex_get; + p_api->port_duplex_set = dess_port_duplex_set; + p_api->port_speed_get = dess_port_speed_get; + p_api->port_speed_set = dess_port_speed_set; + p_api->port_autoneg_status_get = dess_port_autoneg_status_get; + p_api->port_autoneg_enable = dess_port_autoneg_enable; + p_api->port_autoneg_restart = dess_port_autoneg_restart; + p_api->port_autoneg_adv_get = dess_port_autoneg_adv_get; + p_api->port_autoneg_adv_set = dess_port_autoneg_adv_set; + p_api->port_flowctrl_set = dess_port_flowctrl_set; + p_api->port_flowctrl_get = dess_port_flowctrl_get; + p_api->port_flowctrl_thresh_set = dess_port_flowctrl_thresh_set; + p_api->port_flowctrl_forcemode_set = dess_port_flowctrl_forcemode_set; + p_api->port_flowctrl_forcemode_get = dess_port_flowctrl_forcemode_get; + p_api->port_powersave_set = dess_port_powersave_set; + p_api->port_powersave_get = dess_port_powersave_get; + p_api->port_hibernate_set = dess_port_hibernate_set; + p_api->port_hibernate_get = dess_port_hibernate_get; + p_api->port_cdt = dess_port_cdt; + p_api->port_rxhdr_mode_set = dess_port_rxhdr_mode_set; + p_api->port_rxhdr_mode_get = dess_port_rxhdr_mode_get; + p_api->port_txhdr_mode_set = dess_port_txhdr_mode_set; + p_api->port_txhdr_mode_get = dess_port_txhdr_mode_get; + p_api->header_type_set = dess_header_type_set; + p_api->header_type_get = dess_header_type_get; + p_api->port_txmac_status_set = dess_port_txmac_status_set; + p_api->port_txmac_status_get = dess_port_txmac_status_get; + p_api->port_rxmac_status_set = dess_port_rxmac_status_set; + p_api->port_rxmac_status_get = dess_port_rxmac_status_get; + p_api->port_txfc_status_set = dess_port_txfc_status_set; + p_api->port_txfc_status_get = dess_port_txfc_status_get; + p_api->port_rxfc_status_set = dess_port_rxfc_status_set; + p_api->port_rxfc_status_get = dess_port_rxfc_status_get; + p_api->port_bp_status_set = dess_port_bp_status_set; + p_api->port_bp_status_get = dess_port_bp_status_get; + p_api->port_link_forcemode_set = dess_port_link_forcemode_set; + p_api->port_link_forcemode_get = dess_port_link_forcemode_get; + p_api->port_link_status_get = dess_port_link_status_get; + p_api->ports_link_status_get = dess_ports_link_status_get; + p_api->port_mac_loopback_set = dess_port_mac_loopback_set; + p_api->port_mac_loopback_get = dess_port_mac_loopback_get; + p_api->port_congestion_drop_set = dess_port_congestion_drop_set; + p_api->port_congestion_drop_get = dess_port_congestion_drop_get; + p_api->ring_flow_ctrl_thres_set = dess_ring_flow_ctrl_thres_set; + p_api->ring_flow_ctrl_thres_get = dess_ring_flow_ctrl_thres_get; + p_api->port_8023az_set = dess_port_8023az_set; + p_api->port_8023az_get = dess_port_8023az_get; + p_api->port_mdix_set = dess_port_mdix_set; + p_api->port_mdix_get = dess_port_mdix_get; + p_api->port_mdix_status_get = dess_port_mdix_status_get; + p_api->port_combo_prefer_medium_set = dess_port_combo_prefer_medium_set; + p_api->port_combo_prefer_medium_get = dess_port_combo_prefer_medium_get; + p_api->port_combo_medium_status_get = dess_port_combo_medium_status_get; + p_api->port_combo_fiber_mode_set = dess_port_combo_fiber_mode_set; + p_api->port_combo_fiber_mode_get = dess_port_combo_fiber_mode_get; + p_api->port_local_loopback_set = dess_port_local_loopback_set; + p_api->port_local_loopback_get = dess_port_local_loopback_get; + p_api->port_remote_loopback_set = dess_port_remote_loopback_set; + p_api->port_remote_loopback_get = dess_port_remote_loopback_get; + p_api->port_reset = dess_port_reset; + p_api->port_power_off = dess_port_power_off; + p_api->port_power_on = dess_port_power_on; + p_api->port_phy_id_get = dess_port_phy_id_get; + p_api->port_wol_status_set = dess_port_wol_status_set; + p_api->port_wol_status_get = dess_port_wol_status_get; + p_api->port_magic_frame_mac_set = dess_port_magic_frame_mac_set; + p_api->port_magic_frame_mac_get = dess_port_magic_frame_mac_get; + p_api->port_interface_mode_set = dess_port_interface_mode_set; + p_api->port_interface_mode_get = dess_port_interface_mode_get; + p_api->port_interface_mode_status_get = dess_port_interface_mode_status_get; + p_api->port_counter_set = dess_port_counter_set; + p_api->port_counter_get = dess_port_counter_get; + p_api->port_counter_show = dess_port_counter_show; + } +#endif + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_portvlan.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_portvlan.c new file mode 100755 index 000000000..bab6228e8 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_portvlan.c @@ -0,0 +1,2336 @@ +/* + * Copyright (c) 2014, 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. + */ + + +/** + * @defgroup dess_port_vlan DESS_PORT_VLAN + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "dess_portvlan.h" +#include "dess_reg.h" + +#define MAX_VLAN_ID 4095 +#define DESS_MAX_VLAN_TRANS 64 +#define DESS_VLAN_TRANS_ADDR 0x5ac00 + + +static sw_error_t +_dess_port_route_defv_set(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t data = 0, reg = 0; + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN1, port_id, + COREP_EN, (a_uint8_t *) (&data), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (data) + { + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN0, port_id, + DEF_SVID, (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else + { + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN0, port_id, + DEF_CVID, (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_DEFV, (port_id / 2), + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (port_id % 2) + { + reg &= 0xffff; + reg |= ((data & 0xfff) << 16); + } + else + { + reg &= 0xffff0000; + reg |= (data & 0xfff); + } + + HSL_REG_ENTRY_SET(rv, dev_id, ROUTER_DEFV, (port_id / 2), + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_port_1qmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t port_1qmode) +{ + sw_error_t rv; + a_uint32_t data, regval[FAL_1Q_MODE_BUTT] = { 0, 3, 2, 1 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_1Q_MODE_BUTT <= port_1qmode) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LOOKUP_CTL, port_id, DOT1Q_MODE, + (a_uint8_t *) (®val[port_1qmode]), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_1Q_DISABLE == port_1qmode) + { + data = 1; + } + else + { + data = 0; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN1, port_id, VLAN_DIS, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_port_1qmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t * pport_1qmode) +{ + sw_error_t rv; + a_uint32_t regval = 0; + fal_pt_1qmode_t retval[4] = { FAL_1Q_DISABLE, FAL_1Q_FALLBACK, + FAL_1Q_CHECK, FAL_1Q_SECURE + }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL(pport_1qmode); + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LOOKUP_CTL, port_id, DOT1Q_MODE, + (a_uint8_t *) (®val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + *pport_1qmode = retval[regval & 0x3]; + + return SW_OK; +} + +static sw_error_t +_dess_port_egvlanmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t port_egvlanmode) +{ + sw_error_t rv; + a_uint32_t regval[FAL_EG_MODE_BUTT] = { 0, 1, 2, 3, 3 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if ((FAL_EG_MODE_BUTT <= port_egvlanmode) + || (FAL_EG_HYBRID == port_egvlanmode)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN1, port_id, EG_VLAN_MODE, + (a_uint8_t *) (®val[port_egvlanmode]), + sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + return rv; +} + +static sw_error_t +_dess_port_egvlanmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t * pport_egvlanmode) +{ + sw_error_t rv; + a_uint32_t regval = 0; + fal_pt_1q_egmode_t retval[4] = { FAL_EG_UNMODIFIED, FAL_EG_UNTAGGED, + FAL_EG_TAGGED, FAL_EG_UNTOUCHED + }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL(pport_egvlanmode); + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN1, port_id, EG_VLAN_MODE, + (a_uint8_t *) (®val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + *pport_egvlanmode = retval[regval & 0x3]; + + return SW_OK; +} + +static sw_error_t +_dess_portvlan_member_add(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id) +{ + sw_error_t rv; + a_uint32_t regval = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_FALSE == hsl_port_prop_check(dev_id, mem_port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LOOKUP_CTL, port_id, + PORT_VID_MEM, (a_uint8_t *) (®val), + sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + regval |= (0x1UL << mem_port_id); + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LOOKUP_CTL, port_id, + PORT_VID_MEM, (a_uint8_t *) (®val), + sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_dess_portvlan_member_del(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id) +{ + sw_error_t rv; + a_uint32_t regval = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_FALSE == hsl_port_prop_check(dev_id, mem_port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LOOKUP_CTL, port_id, + PORT_VID_MEM, (a_uint8_t *) (®val), + sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + regval &= (~(0x1UL << mem_port_id)); + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LOOKUP_CTL, port_id, + PORT_VID_MEM, (a_uint8_t *) (®val), + sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_dess_portvlan_member_update(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t mem_port_map) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_FALSE == hsl_mports_prop_check(dev_id, mem_port_map, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LOOKUP_CTL, port_id, + PORT_VID_MEM, (a_uint8_t *) (&mem_port_map), + sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_dess_portvlan_member_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t * mem_port_map) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + *mem_port_map = 0; + HSL_REG_FIELD_GET(rv, dev_id, PORT_LOOKUP_CTL, port_id, + PORT_VID_MEM, (a_uint8_t *) mem_port_map, + sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +static sw_error_t +_dess_port_force_default_vid_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN1, port_id, + FORCE_DEF_VID, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_port_force_default_vid_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN1, port_id, + FORCE_DEF_VID, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_port_force_portvlan_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LOOKUP_CTL, port_id, + FORCE_PVLAN, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_port_force_portvlan_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LOOKUP_CTL, port_id, + FORCE_PVLAN, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_nestvlan_tpid_set(a_uint32_t dev_id, a_uint32_t tpid) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + val = tpid; + HSL_REG_FIELD_SET(rv, dev_id, SERVICE_TAG, 0, + TAG_VALUE, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_nestvlan_tpid_get(a_uint32_t dev_id, a_uint32_t * tpid) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, SERVICE_TAG, 0, + TAG_VALUE, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *tpid = val; + return SW_OK; +} + +static sw_error_t +_dess_port_invlan_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_invlan_mode_t mode) +{ + sw_error_t rv; + a_uint32_t regval[FAL_INVLAN_MODE_BUTT] = { 0, 1, 2 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_INVLAN_MODE_BUTT <= mode) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN1, port_id, IN_VLAN_MODE, + (a_uint8_t *) (®val[mode]), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_port_invlan_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_invlan_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t regval = 0; + fal_pt_invlan_mode_t retval[FAL_INVLAN_MODE_BUTT] = { FAL_INVLAN_ADMIT_ALL, + FAL_INVLAN_ADMIT_TAGGED, FAL_INVLAN_ADMIT_UNTAGGED + }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL(mode); + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN1, port_id, IN_VLAN_MODE, + (a_uint8_t *) (®val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (regval >= 3) + { + return SW_FAIL; + } + *mode = retval[regval & 0x3]; + + return rv; +} + +static sw_error_t +_dess_port_tls_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN1, port_id, + TLS_EN, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_port_tls_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN1, port_id, + TLS_EN, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_port_pri_propagation_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN1, port_id, + PRI_PROPAGATION, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_port_pri_propagation_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN1, port_id, + PRI_PROPAGATION, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_port_default_svid_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vid) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (vid > MAX_VLAN_ID) + { + return SW_BAD_PARAM; + } + + val = vid; + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN0, port_id, + DEF_SVID, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + rv = _dess_port_route_defv_set(dev_id, port_id); + return rv; +} + +static sw_error_t +_dess_port_default_svid_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vid) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN0, port_id, + DEF_SVID, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + *vid = val & 0xfff; + return rv; +} + +static sw_error_t +_dess_port_default_cvid_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vid) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (vid > MAX_VLAN_ID) + { + return SW_BAD_PARAM; + } + + val = vid; + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN0, port_id, + DEF_CVID, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + rv = _dess_port_route_defv_set(dev_id, port_id); + return rv; +} + +static sw_error_t +_dess_port_default_cvid_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vid) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN0, port_id, + DEF_CVID, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + *vid = val & 0xfff; + return rv; +} + +static sw_error_t +_dess_port_vlan_propagation_set(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_propagation_mode_t mode) +{ + sw_error_t rv; + a_uint32_t reg = 0, p, c; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_VLAN_PROPAGATION_DISABLE == mode) + { + p = 0; + c = 0; + } + else if (FAL_VLAN_PROPAGATION_CLONE == mode) + { + p = 1; + c = 1; + } + else if (FAL_VLAN_PROPAGATION_REPLACE == mode) + { + p = 1; + c = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_VLAN1, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(PORT_VLAN1, PROPAGATION_EN, p, reg); + SW_SET_REG_BY_FIELD(PORT_VLAN1, CLONE, c, reg); + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_VLAN1, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_port_vlan_propagation_get(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_propagation_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t reg = 0, p, c; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_VLAN1, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_VLAN1, PROPAGATION_EN, p, reg); + SW_GET_FIELD_BY_REG(PORT_VLAN1, CLONE, c, reg); + + if (p) + { + if (c) + { + *mode = FAL_VLAN_PROPAGATION_CLONE; + } + else + { + *mode = FAL_VLAN_PROPAGATION_REPLACE; + } + } + else + { + *mode = FAL_VLAN_PROPAGATION_DISABLE; + } + + return SW_OK; +} + +static sw_error_t +_dess_vlan_trans_read(a_uint32_t dev_id, a_uint32_t entry_idx, + fal_pbmp_t * pbmp, fal_vlan_trans_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t i, addr, dir, table[2] = {0}; + + *pbmp = 0; + aos_mem_zero(entry, sizeof (fal_vlan_trans_entry_t)); + + addr = DESS_VLAN_TRANS_ADDR + (entry_idx << 3); + /* get vlan trans table */ + for (i = 0; i < 2; i++) + { + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr + (i << 2), sizeof (a_uint32_t), + (a_uint8_t *) (&(table[i])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + dir = 0x3 & (table[1] >> 4); + if (!dir) + { + return SW_EMPTY; + } + + entry->o_vid = table[0] & 0xfff; + *pbmp = (table[1] >> 6) & 0x7f; + + if (3 == dir) + { + entry->bi_dir = A_TRUE; + entry->forward_dir = A_TRUE; + entry->reverse_dir = A_TRUE; + } + else if (1 == dir) + { + entry->bi_dir = A_FALSE; + entry->forward_dir = A_TRUE; + entry->reverse_dir = A_FALSE; + } + else + { + entry->bi_dir = A_FALSE; + entry->forward_dir = A_FALSE; + entry->reverse_dir = A_TRUE; + } + + entry->o_vid_is_cvid = (table[1] >> 13) & 0x1UL; + entry->one_2_one_vlan = (table[1] >> 16) & 0x1UL; + entry->s_vid_enable = (table[1] >> 14) & 0x1UL; + entry->c_vid_enable = (table[1] >> 15) & 0x1UL; + + if (A_TRUE == entry->s_vid_enable) + { + entry->s_vid = (table[0] >> 12) & 0xfff; + } + + if (A_TRUE == entry->c_vid_enable) + { + entry->c_vid = ((table[0] >> 24) & 0xff) | ((table[1] & 0xf) << 8); + } + + return SW_OK; +} + +static sw_error_t +_dess_vlan_trans_write(a_uint32_t dev_id, a_uint32_t entry_idx, fal_pbmp_t pbmp, + fal_vlan_trans_entry_t entry) +{ + sw_error_t rv; + a_uint32_t i, addr, table[2] = { 0 }; + + addr = DESS_VLAN_TRANS_ADDR + (entry_idx << 3); + + if (0 != pbmp) + { + table[0] = entry.o_vid & 0xfff; + table[0] |= ((entry.s_vid & 0xfff) << 12); + table[0] |= ((entry.c_vid & 0xff) << 24); + table[1] = (entry.c_vid >> 8) & 0xf; + + if (A_TRUE == entry.bi_dir) + { + table[1] |= (0x3 << 4); + } + + if (A_TRUE == entry.forward_dir) + { + table[1] |= (0x1 << 4); + } + + if (A_TRUE == entry.reverse_dir) + { + table[1] |= (0x1 << 5); + } + + table[1] |= (pbmp << 6); + table[1] |= ((0x1UL & entry.o_vid_is_cvid) << 13); + table[1] |= ((0x1UL & entry.s_vid_enable) << 14); + table[1] |= ((0x1UL & entry.c_vid_enable) << 15); + table[1] |= ((0x1UL & entry.one_2_one_vlan) << 16); + } + + /* set vlan trans table */ + for (i = 0; i < 2; i++) + { + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr + (i << 2), sizeof (a_uint32_t), + (a_uint8_t *) (&(table[i])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +static sw_error_t +_dess_port_vlan_trans_convert(fal_vlan_trans_entry_t * entry, + fal_vlan_trans_entry_t * local) +{ + aos_mem_copy(local, entry, sizeof (fal_vlan_trans_entry_t)); + + if ((A_TRUE == local->bi_dir) + || ((A_TRUE == local->forward_dir) + && (A_TRUE == local->reverse_dir))) + { + local->bi_dir = A_TRUE; + local->forward_dir = A_TRUE; + local->reverse_dir = A_TRUE; + } + + if (A_FALSE == local->s_vid_enable) + { + local->s_vid = 0; + } + + if (A_FALSE == local->c_vid_enable) + { + local->c_vid = 0; + } + + return SW_OK; +} + +static sw_error_t +_dess_port_vlan_trans_add(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_trans_entry_t * entry) +{ + sw_error_t rv; + fal_pbmp_t t_pbmp; + a_uint32_t idx, entry_idx = DESS_MAX_VLAN_TRANS; + fal_vlan_trans_entry_t temp, local; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (NULL == entry) + { + return SW_BAD_PTR; + } + aos_mem_zero(&local, sizeof (fal_vlan_trans_entry_t)); + rv = _dess_port_vlan_trans_convert(entry, &local); + SW_RTN_ON_ERROR(rv); + + for (idx = 0; idx < DESS_MAX_VLAN_TRANS; idx++) + { + rv = _dess_vlan_trans_read(dev_id, idx, &t_pbmp, &temp); + if (SW_EMPTY == rv) + { + entry_idx = idx; + continue; + } + SW_RTN_ON_ERROR(rv); + + if (!aos_mem_cmp(&local, &temp, sizeof (fal_vlan_trans_entry_t))) + { + if (SW_IS_PBMP_MEMBER(t_pbmp, port_id)) + { + return SW_ALREADY_EXIST; + } + entry_idx = idx; + break; + } + else + { + t_pbmp = 0; + } + } + + if (DESS_MAX_VLAN_TRANS != entry_idx) + { + t_pbmp |= (0x1 << port_id); + } + else + { + return SW_NO_RESOURCE; + } + + return _dess_vlan_trans_write(dev_id, entry_idx, t_pbmp, local); +} + +static sw_error_t +_dess_port_vlan_trans_del(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_trans_entry_t * entry) +{ + sw_error_t rv; + fal_pbmp_t t_pbmp; + a_uint32_t idx, entry_idx = DESS_MAX_VLAN_TRANS; + fal_vlan_trans_entry_t temp, local; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (NULL == entry) + { + return SW_BAD_PTR; + } + aos_mem_zero(&local, sizeof (fal_vlan_trans_entry_t)); + rv = _dess_port_vlan_trans_convert(entry, &local); + SW_RTN_ON_ERROR(rv); + + for (idx = 0; idx < DESS_MAX_VLAN_TRANS; idx++) + { + rv = _dess_vlan_trans_read(dev_id, idx, &t_pbmp, &temp); + if (SW_EMPTY == rv) + { + continue; + } + SW_RTN_ON_ERROR(rv); + + if (!aos_mem_cmp(&temp, &local, sizeof (fal_vlan_trans_entry_t))) + { + if (SW_IS_PBMP_MEMBER(t_pbmp, port_id)) + { + entry_idx = idx; + break; + } + } + } + + if (DESS_MAX_VLAN_TRANS != entry_idx) + { + t_pbmp &= (~(0x1 << port_id)); + } + else + { + return SW_NOT_FOUND; + } + + return _dess_vlan_trans_write(dev_id, entry_idx, t_pbmp, local); +} + +static sw_error_t +_dess_port_vlan_trans_get(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_trans_entry_t * entry) +{ + sw_error_t rv; + fal_pbmp_t t_pbmp; + a_uint32_t idx; + fal_vlan_trans_entry_t temp, local; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (NULL == entry) + { + return SW_BAD_PTR; + } + aos_mem_zero(&local, sizeof (fal_vlan_trans_entry_t)); + rv = _dess_port_vlan_trans_convert(entry, &local); + SW_RTN_ON_ERROR(rv); + + for (idx = 0; idx < DESS_MAX_VLAN_TRANS; idx++) + { + rv = _dess_vlan_trans_read(dev_id, idx, &t_pbmp, &temp); + if (SW_EMPTY == rv) + { + continue; + } + SW_RTN_ON_ERROR(rv); + + if (!aos_mem_cmp(&temp, &local, sizeof (fal_vlan_trans_entry_t))) + { + if (SW_IS_PBMP_MEMBER(t_pbmp, port_id)) + { + return SW_OK; + } + } + } + + return SW_NOT_FOUND; +} + +static sw_error_t +_dess_port_vlan_trans_iterate(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * iterator, + fal_vlan_trans_entry_t * entry) +{ + a_uint32_t index; + sw_error_t rv; + fal_vlan_trans_entry_t entry_t; + fal_pbmp_t pbmp_t; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if ((NULL == iterator) || (NULL == entry)) + { + return SW_BAD_PTR; + } + + if (DESS_MAX_VLAN_TRANS < *iterator) + { + return SW_BAD_PARAM; + } + + for (index = *iterator; index < DESS_MAX_VLAN_TRANS; index++) + { + rv = _dess_vlan_trans_read(dev_id, index, &pbmp_t, &entry_t); + if (SW_EMPTY == rv) + { + continue; + } + + if (SW_IS_PBMP_MEMBER(pbmp_t, port_id)) + { + aos_mem_copy(entry, &entry_t, sizeof (fal_vlan_trans_entry_t)); + break; + } + } + + if (DESS_MAX_VLAN_TRANS == index) + { + return SW_NO_MORE; + } + + *iterator = index + 1; + return SW_OK; +} + +static sw_error_t +_dess_qinq_mode_set(a_uint32_t dev_id, fal_qinq_mode_t mode) +{ + sw_error_t rv; + a_uint32_t stag = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_QINQ_MODE_BUTT <= mode) + { + return SW_BAD_PARAM; + } + + if (FAL_QINQ_STAG_MODE == mode) + { + stag = 1; + } + + HSL_REG_FIELD_SET(rv, dev_id, SERVICE_TAG, 0, + STAG_MODE, (a_uint8_t *) (&stag), sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_dess_qinq_mode_get(a_uint32_t dev_id, fal_qinq_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t stag = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, SERVICE_TAG, 0, + STAG_MODE, (a_uint8_t *) (&stag), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (stag) + { + *mode = FAL_QINQ_STAG_MODE; + } + else + { + *mode = FAL_QINQ_CTAG_MODE; + } + + return SW_OK; +} + +static sw_error_t +_dess_port_qinq_role_set(a_uint32_t dev_id, fal_port_t port_id, + fal_qinq_port_role_t role) +{ + sw_error_t rv; + a_uint32_t core = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_QINQ_PORT_ROLE_BUTT <= role) + { + return SW_BAD_PARAM; + } + + if (FAL_QINQ_CORE_PORT == role) + { + core = 1; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN1, port_id, + COREP_EN, (a_uint8_t *) (&core), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + rv = _dess_port_route_defv_set(dev_id, port_id); + return rv; +} + +static sw_error_t +_dess_port_qinq_role_get(a_uint32_t dev_id, fal_port_t port_id, + fal_qinq_port_role_t * role) +{ + sw_error_t rv; + a_uint32_t core = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN1, port_id, + COREP_EN, (a_uint8_t *) (&core), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (core) + { + *role = FAL_QINQ_CORE_PORT; + } + else + { + *role = FAL_QINQ_EDGE_PORT; + } + + return SW_OK; +} + +static sw_error_t +_dess_port_mac_vlan_xlt_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PRI_CTL, port_id, + EG_MAC_BASE_VLAN_EN, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; + +} + +static sw_error_t +_dess_port_mac_vlan_xlt_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PRI_CTL, port_id, + EG_MAC_BASE_VLAN_EN, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_netisolate_set(a_uint32_t dev_id, a_uint32_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + val = enable; + HSL_REG_FIELD_SET(rv, dev_id, VLAN_TRANS, 0, + NET_ISO, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_netisolate_get(a_uint32_t dev_id, a_uint32_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, VLAN_TRANS, 0, + NET_ISO, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *enable = val; + return SW_OK; +} + +static sw_error_t +_dess_eg_trans_filter_bypass_en_set(a_uint32_t dev_id, a_uint32_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + val = enable; + HSL_REG_FIELD_SET(rv, dev_id, VLAN_TRANS, 0, + EG_FLTR_BYPASS_EN, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_eg_trans_filter_bypass_en_get(a_uint32_t dev_id, a_uint32_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, VLAN_TRANS, 0, + EG_FLTR_BYPASS_EN, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *enable = val; + return SW_OK; +} + +static sw_error_t +_dess_port_vrf_id_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vrf_id) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN1, port_id, + VRF_ID, (a_uint8_t *) (&vrf_id), + sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + return rv; +} + +static sw_error_t +_dess_port_vrf_id_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vrf_id) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN1, port_id, + VRF_ID, (a_uint8_t *) (vrf_id), + sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + return rv; +} + + +/** + * @brief Set 802.1q work mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] port_1qmode 802.1q work mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_1qmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t port_1qmode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_1qmode_set(dev_id, port_id, port_1qmode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get 802.1q work mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] port_1qmode 802.1q work mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_1qmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t * pport_1qmode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_1qmode_get(dev_id, port_id, pport_1qmode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set packets transmitted out vlan tagged mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] port_egvlanmode packets transmitted out vlan tagged mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_egvlanmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t port_egvlanmode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_egvlanmode_set(dev_id, port_id, port_egvlanmode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get packets transmitted out vlan tagged mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] port_egvlanmode packets transmitted out vlan tagged mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_egvlanmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t * pport_egvlanmode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_egvlanmode_get(dev_id, port_id, pport_egvlanmode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add member of port based vlan on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mem_port_id port member + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_portvlan_member_add(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_portvlan_member_add(dev_id, port_id, mem_port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete member of port based vlan on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mem_port_id port member + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_portvlan_member_del(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_portvlan_member_del(dev_id, port_id, mem_port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Update member of port based vlan on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mem_port_map port members + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_portvlan_member_update(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t mem_port_map) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_portvlan_member_update(dev_id, port_id, mem_port_map); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get member of port based vlan on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mem_port_map port members + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_portvlan_member_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t * mem_port_map) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_portvlan_member_get(dev_id, port_id, mem_port_map); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set force default vlan id status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_force_default_vid_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_force_default_vid_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get force default vlan id status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_force_default_vid_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_force_default_vid_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set force port based vlan status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_force_portvlan_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_force_portvlan_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get force port based vlan status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_force_portvlan_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_force_portvlan_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set nest vlan tpid on a particular device. + * @param[in] dev_id device id + * @param[in] tpid tag protocol identification + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_nestvlan_tpid_set(a_uint32_t dev_id, a_uint32_t tpid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_nestvlan_tpid_set(dev_id, tpid); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get nest vlan tpid on a particular device. + * @param[in] dev_id device id + * @param[out] tpid tag protocol identification + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_nestvlan_tpid_get(a_uint32_t dev_id, a_uint32_t * tpid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_nestvlan_tpid_get(dev_id, tpid); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set ingress vlan mode mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode ingress vlan mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_invlan_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_invlan_mode_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_invlan_mode_set(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get ingress vlan mode mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mode ingress vlan mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_invlan_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_invlan_mode_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_invlan_mode_get(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set tls status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_tls_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_tls_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get tls status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_tls_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_tls_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set priority propagation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_pri_propagation_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_pri_propagation_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get priority propagation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_pri_propagation_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_pri_propagation_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set default s-vid on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] vid s-vid + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_default_svid_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_default_svid_set(dev_id, port_id, vid); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get default s-vid on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] vid s-vid + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_default_svid_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_default_svid_get(dev_id, port_id, vid); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set default c-vid on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] vid c-vid + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_default_cvid_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_default_cvid_set(dev_id, port_id, vid); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get default c-vid on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] vid c-vid + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_default_cvid_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_default_cvid_get(dev_id, port_id, vid); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set vlan propagation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode vlan propagation mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_vlan_propagation_set(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_propagation_mode_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_vlan_propagation_set(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get vlan propagation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mode vlan propagation mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_vlan_propagation_get(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_propagation_mode_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_vlan_propagation_get(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add a vlan translation entry to a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param entry vlan translation entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_vlan_trans_add(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_trans_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_vlan_trans_add(dev_id, port_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a vlan translation entry from a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param entry vlan translation entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_vlan_trans_del(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_trans_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_vlan_trans_del(dev_id, port_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get a vlan translation entry from a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param entry vlan translation entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_vlan_trans_get(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_trans_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_vlan_trans_get(dev_id, port_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Iterate all vlan translation entries from a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] iterator translation entry index if it's zero means get the first entry + * @param[out] iterator next valid translation entry index + * @param[out] entry vlan translation entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_port_vlan_trans_iterate(dev_id, port_id, iterator, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set switch qinq work mode on a particular device. + * @param[in] dev_id device id + * @param[in] mode qinq work mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_qinq_mode_set(a_uint32_t dev_id, fal_qinq_mode_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_qinq_mode_set(dev_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get switch qinq work mode on a particular device. + * @param[in] dev_id device id + * @param[out] mode qinq work mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_qinq_mode_get(a_uint32_t dev_id, fal_qinq_mode_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_qinq_mode_get(dev_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set qinq role on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] role port role + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_qinq_role_set(a_uint32_t dev_id, fal_port_t port_id, + fal_qinq_port_role_t role) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_qinq_role_set(dev_id, port_id, role); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get qinq role on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] role port role + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_qinq_role_get(a_uint32_t dev_id, fal_port_t port_id, + fal_qinq_port_role_t * role) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_qinq_role_get(dev_id, port_id, role); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set MAC_VLAN_XLT status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] role port role + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_mac_vlan_xlt_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_mac_vlan_xlt_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get MAC_VLAN_XLT status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] role port role + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_mac_vlan_xlt_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_mac_vlan_xlt_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} +#if 0 +HSL_LOCAL sw_error_t +dess_port_route_defv_set(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv =_dess_port_route_defv_set(dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Set NET_ISOLATE_EN + * @param[in] dev_id device id + * @param[in] role port role + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_netisolate_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_netisolate_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get NET_ISOLATE_EN status + * @param[in] dev_id device id + * @param[out] role port role + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_netisolate_get(a_uint32_t dev_id, a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_netisolate_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set egress translation filter bypass enable + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_eg_trans_filter_bypass_en_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_eg_trans_filter_bypass_en_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get egress translation filter bypass enable + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_eg_trans_filter_bypass_en_get(a_uint32_t dev_id, a_bool_t* enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_eg_trans_filter_bypass_en_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set VRF id on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] vrf_id VRF id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_vrf_id_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vrf_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_vrf_id_set(dev_id, port_id, vrf_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get VRF id on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] vrf_id VRF id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_port_vrf_id_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vrf_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_port_vrf_id_get(dev_id, port_id, vrf_id); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +dess_portvlan_init(a_uint32_t dev_id) +{ + a_uint32_t i; + sw_error_t rv; + fal_vlan_trans_entry_t entry_init; + hsl_api_t *p_api; + + HSL_DEV_ID_CHECK(dev_id); + + aos_mem_set(&entry_init, 0, sizeof (fal_vlan_trans_entry_t)); + + for (i = 0; i < DESS_MAX_VLAN_TRANS; i++) + { + rv = _dess_vlan_trans_write(dev_id, i, 0, entry_init); + SW_RTN_ON_ERROR(rv); + } + +#ifndef HSL_STANDALONG + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->port_1qmode_get = dess_port_1qmode_get; + p_api->port_1qmode_set = dess_port_1qmode_set; + p_api->port_egvlanmode_get = dess_port_egvlanmode_get; + p_api->port_egvlanmode_set = dess_port_egvlanmode_set; + p_api->portvlan_member_add = dess_portvlan_member_add; + p_api->portvlan_member_del = dess_portvlan_member_del; + p_api->portvlan_member_update = dess_portvlan_member_update; + p_api->portvlan_member_get = dess_portvlan_member_get; + p_api->port_force_default_vid_set = dess_port_force_default_vid_set; + p_api->port_force_default_vid_get = dess_port_force_default_vid_get; + p_api->port_force_portvlan_set = dess_port_force_portvlan_set; + p_api->port_force_portvlan_get = dess_port_force_portvlan_get; + p_api->nestvlan_tpid_set = dess_nestvlan_tpid_set; + p_api->nestvlan_tpid_get = dess_nestvlan_tpid_get; + p_api->port_invlan_mode_set = dess_port_invlan_mode_set; + p_api->port_invlan_mode_get = dess_port_invlan_mode_get; + p_api->port_tls_set = dess_port_tls_set; + p_api->port_tls_get = dess_port_tls_get; + p_api->port_pri_propagation_set = dess_port_pri_propagation_set; + p_api->port_pri_propagation_get = dess_port_pri_propagation_get; + p_api->port_default_svid_set = dess_port_default_svid_set; + p_api->port_default_svid_get = dess_port_default_svid_get; + p_api->port_default_cvid_set = dess_port_default_cvid_set; + p_api->port_default_cvid_get = dess_port_default_cvid_get; + p_api->port_vlan_propagation_set = dess_port_vlan_propagation_set; + p_api->port_vlan_propagation_get = dess_port_vlan_propagation_get; + p_api->port_vlan_trans_add = dess_port_vlan_trans_add; + p_api->port_vlan_trans_del = dess_port_vlan_trans_del; + p_api->port_vlan_trans_get = dess_port_vlan_trans_get; + p_api->qinq_mode_set = dess_qinq_mode_set; + p_api->qinq_mode_get = dess_qinq_mode_get; + p_api->port_qinq_role_set = dess_port_qinq_role_set; + p_api->port_qinq_role_get = dess_port_qinq_role_get; + p_api->port_vlan_trans_iterate = dess_port_vlan_trans_iterate; + p_api->port_mac_vlan_xlt_set = dess_port_mac_vlan_xlt_set; + p_api->port_mac_vlan_xlt_get = dess_port_mac_vlan_xlt_get; + p_api->netisolate_set = dess_netisolate_set; + p_api->netisolate_get = dess_netisolate_get; + p_api->eg_trans_filter_bypass_en_set = dess_eg_trans_filter_bypass_en_set; + p_api->eg_trans_filter_bypass_en_get = dess_eg_trans_filter_bypass_en_get; + p_api->port_vrf_id_set = dess_port_vrf_id_set; + p_api->port_vrf_id_get = dess_port_vrf_id_get; +#endif + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_psgmii.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_psgmii.c new file mode 100755 index 000000000..aab36d24e --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_psgmii.c @@ -0,0 +1,722 @@ +/* + * 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. + */ + + + +#include "sw.h" +#include "fal_port_ctrl.h" +#include "hsl_api.h" +#include "hsl.h" +#include "sd.h" +#include "dess_psgmii.h" +#include "aos_timer.h" + +static psgmii_interface_mac_mode_t psgmii_mac_mode = {0}; +static a_uint32_t sgmii_ch_id = 0; + +sw_error_t +dess_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 = sd_reg_psgmii_get(dev_id, reg_addr, value, value_len); + return rv; +} + +sw_error_t +dess_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 = sd_reg_psgmii_set(dev_id, reg_addr, value, value_len); + return rv; +} + +sw_error_t +dess_psgmii_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) +{ + a_uint32_t reg_val = 0; + + if ((bit_offset >= 32 || (field_len > 32)) || (field_len == 0)) + return SW_OUT_OF_RANGE; + + if (value_len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + + SW_RTN_ON_ERROR(dess_psgmii_reg_get(dev_id, reg_addr, (a_uint8_t *) & reg_val, sizeof (a_uint32_t))); + + + if(32 == field_len) + { + *((a_uint32_t *) value) = reg_val; + } + else + { + *((a_uint32_t *) value) = SW_REG_2_FIELD(reg_val, bit_offset, field_len); + } + return SW_OK; +} + +sw_error_t +dess_psgmii_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) +{ + a_uint32_t reg_val = 0; + a_uint32_t field_val = *((a_uint32_t *) value); + + if ((bit_offset >= 32 || (field_len > 32)) || (field_len == 0)) + return SW_OUT_OF_RANGE; + + if (value_len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + + SW_RTN_ON_ERROR(dess_psgmii_reg_get(dev_id, reg_addr, (a_uint8_t *) & reg_val, sizeof (a_uint32_t))); + + if(32 == field_len) + { + reg_val = field_val; + } + else + { + SW_REG_SET_BY_FIELD_U32(reg_val, field_val, bit_offset, field_len); + } + + SW_RTN_ON_ERROR(dess_psgmii_reg_set(dev_id, reg_addr, (a_uint8_t *) & reg_val, sizeof (a_uint32_t))); + + return SW_OK; +} + + +/****************************************************************************** +* +* psgmii_set_powersave - set power saving status +* +* set power saving status +*/ +sw_error_t +dess_psgmii_set_lpi(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t data = 0; + + if (phy_id == 0) + { + rv = dess_psgmii_reg_get(dev_id, PSGMIIPHY_EEE_CH0_5, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else + { + rv = dess_psgmii_reg_get(dev_id, PSGMIIPHY_EEE_CH1_1 + phy_id * 0xc, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + if (enable) + { + data &= ~(PSGMIIPHY_EEE_DIS_LPI); + data |= PSGMIIPHY_EEE_EN_LPI; + } + else + { + data |= PSGMIIPHY_EEE_DIS_LPI; + data &= ~(PSGMIIPHY_EEE_EN_LPI); + } + + if (phy_id == 0) + { + rv = dess_psgmii_reg_set(dev_id, PSGMIIPHY_EEE_CH0_5, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else + { + rv = dess_psgmii_reg_set(dev_id, PSGMIIPHY_EEE_CH1_1 + phy_id * 0xc, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +/****************************************************************************** +* +*psgmii_get_powersave - get power saving status +* +* set power saving status +*/ +sw_error_t +dess_psgmii_get_lpi(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t *enable) +{ + sw_error_t rv; + a_uint32_t data = 0; + + if (phy_id == 0) + { + rv = dess_psgmii_reg_get(dev_id, PSGMIIPHY_EEE_CH0_5, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else + { + rv = dess_psgmii_reg_get(dev_id, PSGMIIPHY_EEE_CH1_1 + phy_id * 0xc, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + if (!(data & PSGMIIPHY_EEE_DIS_LPI) && (data & PSGMIIPHY_EEE_EN_LPI)) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +/****************************************************************************** +* +*psgmii_set_hibernate - set hibernate status +* +* set hibernate status +*/ +sw_error_t +dess_psgmii_set_interface_type(a_uint32_t dev_id, a_uint32_t phy_id, + psgmii_interface_mac_mode_t mode) +{ + sw_error_t rv; + a_uint32_t data = 0; + + rv = dess_psgmii_reg_get(dev_id, PSGMIIPHY_MODE_CONTROL, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + switch(mode) + { + case PSGMII_MAC_MODE_PSGMII: + { + data |= PSGMIIPHY_MODE_CH0_PSGMII_QSGMII; + data &= (~PSGMIIPHY_MODE_CH0_QSGMII_SGMII); + data &= (~PSGMIIPHY_MODE_CH4_CH1_0_SGMII); + data &= (~PSGMIIPHY_MODE_CH1_CH0_SGMII); + break; + } + case PSGMII_MAC_MODE_QSGMII: + { + data &= (~PSGMIIPHY_MODE_CH0_PSGMII_QSGMII); + data |= PSGMIIPHY_MODE_CH0_QSGMII_SGMII; + if (phy_id == 0) + { + data &= (~PSGMIIPHY_MODE_CH4_CH1_0_SGMII); + data &= (~PSGMIIPHY_MODE_CH1_CH0_SGMII); + } + else if (phy_id == 1) + { + data &= (~PSGMIIPHY_MODE_CH4_CH1_0_SGMII); + data |= PSGMIIPHY_MODE_CH1_CH0_SGMII; + } + else if (phy_id == 4) + { + data |= PSGMIIPHY_MODE_CH4_CH1_0_SGMII; + data &= (~PSGMIIPHY_MODE_CH1_CH0_SGMII); + } + else + { + return SW_NOT_SUPPORTED; + } + + break; + } + case PSGMII_MAC_MODE_SGMII: + { + data &= (~PSGMIIPHY_MODE_CH0_PSGMII_QSGMII); + data &= (~PSGMIIPHY_MODE_CH0_QSGMII_SGMII); + if (phy_id == 0) + { + data &= (~PSGMIIPHY_MODE_CH4_CH1_0_SGMII); + data &= (~PSGMIIPHY_MODE_CH1_CH0_SGMII); + } + else if (phy_id == 1) + { + data &= (~PSGMIIPHY_MODE_CH4_CH1_0_SGMII); + data |= PSGMIIPHY_MODE_CH1_CH0_SGMII; + } + else if (phy_id == 4) + { + data |= PSGMIIPHY_MODE_CH4_CH1_0_SGMII; + data &= (~PSGMIIPHY_MODE_CH1_CH0_SGMII); + } + else + { + return SW_NOT_SUPPORTED; + } + + break; + } + default: + break; + } + + rv = dess_psgmii_reg_set(dev_id, PSGMIIPHY_MODE_CONTROL, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + psgmii_mac_mode = mode; + sgmii_ch_id = phy_id; + + return SW_OK; +} + +/****************************************************************************** +* +* psgmii_get_hibernate - get hibernate status +* +* get hibernate status +*/ +sw_error_t +dess_psgmii_get_interface_type(a_uint32_t dev_id, a_uint32_t * phy_id, + psgmii_interface_mac_mode_t * mode) +{ + *phy_id = sgmii_ch_id; + *mode = psgmii_mac_mode; + + return SW_OK; +} + +/****************************************************************************** +* +* psgmii_autoneg_done +* +*psgmii_autoneg_done +*/ +a_bool_t +dess_psgmii_autoneg_done(a_uint32_t dev_id, a_uint32_t phy_id) +{ + sw_error_t rv; + a_uint32_t data = 0; + + rv = dess_psgmii_reg_get(dev_id, PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_1 + phy_id * 0x18, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data & PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_1_MR_AN_COMPLETE) + return A_TRUE; + else + return A_FALSE; + + return A_TRUE; +} + +/****************************************************************************** +* +*psgmii_reset - reset the psgmii +* +* reset the psgmii +*/ +sw_error_t +dess_psgmii_reset(a_uint32_t dev_id, a_uint32_t phy_id) +{ + sw_error_t rv; + a_uint32_t data = 0; + + rv = dess_psgmii_reg_get(dev_id, PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4 + phy_id * 0x18, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data |= PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4_MR_MAIN_RESET_25M; + + rv = dess_psgmii_reg_set(dev_id, PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4 + phy_id * 0x18, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +/****************************************************************************** +* +* psgmii_off - power off the psgmii to change its speed +* +* Power off the psgmii +*/ +sw_error_t +dess_psgmii_poweroff(a_uint32_t dev_id, a_uint32_t phy_id) +{ + sw_error_t rv; + a_uint32_t data = 0; + + rv = dess_psgmii_reg_get(dev_id, PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4 + phy_id * 0x18, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data &= (~PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4_POWER_ON_25M); + + rv = dess_psgmii_reg_set(dev_id, PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4 + phy_id * 0x18, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +/****************************************************************************** +* +* psgmii_on - power on the psgmii after speed changed +* +* Power on the psgmii +*/ +sw_error_t +dess_psgmii_poweron(a_uint32_t dev_id, a_uint32_t phy_id) +{ + sw_error_t rv; + a_uint32_t data = 0; + + rv = dess_psgmii_reg_get(dev_id, PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4 + phy_id * 0x18, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data |= PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4_POWER_ON_25M; + + rv = dess_psgmii_reg_set(dev_id, PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4 + phy_id * 0x18, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +/****************************************************************************** +* +* psgmii_status - test to see if the specified psgmii link is alive +* +* RETURNS: +* A_TRUE --> link is alive +* A_FALSE --> link is down +*/ +a_bool_t +dess_psgmii_get_link_status(a_uint32_t dev_id, a_uint32_t phy_id) +{ + sw_error_t rv; + a_uint32_t data = 0; + + rv = dess_psgmii_reg_get(dev_id, PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_5 + phy_id * 0x18, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data & PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_5_LINK_25M) + return A_TRUE; + else + return A_FALSE; + + return SW_OK; +} + +/****************************************************************************** +* +* psgmii_set_loopback - set the psgmii loopback +* +*/ +sw_error_t +dess_psgmii_set_loopback(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t data = 0; + + rv = dess_psgmii_reg_get(dev_id, PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4 + phy_id * 0x18, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (enable) + data |= PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4_MR_MR_LOOPBACK_25M; + else + data &= (~PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4_MR_MR_LOOPBACK_25M); + + rv = dess_psgmii_reg_set(dev_id, PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4 + phy_id * 0x18, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +/****************************************************************************** +* +* psgmii_get_loopback - get the psgmii loopback +* +*/ +sw_error_t +dess_psgmii_get_loopback(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t data = 0; + + rv = dess_psgmii_reg_get(dev_id, PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4 + phy_id * 0x18, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data & PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4_MR_MR_LOOPBACK_25M) + *enable = A_TRUE; + else + *enable = A_FALSE; + + return SW_OK; +} + +/****************************************************************************** +* +* psgmii_enable_autonego - power off the psgmii to change its speed +* +* Power off the phy +*/ +a_bool_t +dess_psgmii_autoneg_status(a_uint32_t dev_id, a_uint32_t phy_id) +{ + + return A_FALSE; +} + +/****************************************************************************** +* +* psgmii_restart_autoneg - restart the psgmii autoneg +* +*/ +sw_error_t +dess_psgmii_restart_autoneg(a_uint32_t dev_id, a_uint32_t phy_id) +{ + sw_error_t rv; + a_uint32_t data = 0; + + rv = dess_psgmii_reg_get(dev_id, PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4 + phy_id * 0x18, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data |= PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4_MR_RESTART_AN_25M; + + rv = dess_psgmii_reg_set(dev_id, PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4 + phy_id * 0x18, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +/****************************************************************************** +* +* psgmii_enable_autonego - power off the psgmii to change its speed +* +* Power off the phy +*/ +sw_error_t +dess_psgmii_enable_autoneg(a_uint32_t dev_id, a_uint32_t phy_id) +{ + sw_error_t rv; + a_uint32_t data = 0; + + rv = dess_psgmii_reg_get(dev_id, PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4 + phy_id * 0x18, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data |= PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4_MR_AN_ENABLE_25M; + + rv = dess_psgmii_reg_set(dev_id, PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4 + phy_id * 0x18, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + + +/****************************************************************************** +* +* psgmii_get_speed - Determines the speed of psgmii ports associated with the +* specified device. +*/ + +sw_error_t +dess_psgmii_get_speed(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_speed_t * speed) +{ + sw_error_t rv; + a_uint32_t data = 0; + + rv = dess_psgmii_reg_get(dev_id, PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4 + phy_id * 0x18, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /*Force speed mode*/ + if (data & PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4_FORCE_SPEED_25M) + { + switch (data & PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_4_SPEED_25M_MASK) + { + case PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_4_SPEED_25M_1000M: + *speed = FAL_SPEED_1000; + break; + case PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_4_SPEED_25M_100M: + *speed = FAL_SPEED_100; + break; + case PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_4_SPEED_25M_10M: + *speed = FAL_SPEED_10; + break; + default: + return SW_READ_ERROR; + } + } + else + { + rv = dess_psgmii_reg_get(dev_id, PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_5 + phy_id * 0x18, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + switch (data & PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_5_SPEED_MODE_25M) + { + case PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_5_SPEED_25M_1000M: + *speed = FAL_SPEED_1000; + break; + case PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_5_SPEED_25M_100M: + *speed = FAL_SPEED_100; + break; + case PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_5_SPEED_25M_10M: + *speed = FAL_SPEED_10; + break; + default: + return SW_READ_ERROR; + } + } + + return SW_OK; +} + +/****************************************************************************** +* +* psgmii_set_speed - Determines the speed of psgmii ports associated with the +* specified device. +*/ +sw_error_t +dess_psgmii_set_speed(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_speed_t speed) +{ + sw_error_t rv; + a_uint32_t data = 0; + + rv = dess_psgmii_reg_get(dev_id, PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4 + phy_id * 0x18, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data |= PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4_FORCE_SPEED_25M; + data &= ~(PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_4_SPEED_25M_MASK); + + if (FAL_SPEED_1000 == speed) + { + data |= PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_4_SPEED_25M_1000M; + } + else if (FAL_SPEED_100 == speed) + { + data |= PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_4_SPEED_25M_100M; + } + else if (FAL_SPEED_10 == speed) + { + data |= PSGMIIPHY_CHANNEL_3_INPUT_OUTPUT_4_SPEED_25M_10M; + } + else + { + return SW_BAD_PARAM; + } + + rv = dess_psgmii_reg_set(dev_id, PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_4 + phy_id * 0x18, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return SW_OK; + +} + +/****************************************************************************** +* +* psgmii_get_duplex - Determines the speed of psgmii ports associated with the +* specified device. +*/ +sw_error_t +dess_psgmii_get_duplex(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_duplex_t * duplex) +{ + sw_error_t rv; + a_uint32_t data = 0; + + rv = dess_psgmii_reg_get(dev_id, PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_5 + phy_id * 0x18, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /*Force speed mode*/ + if (data & PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_5_DUPLEX_MODE_25M) + { + *duplex = FAL_FULL_DUPLEX; + } + else + { + *duplex = FAL_HALF_DUPLEX; + } + + + return SW_OK; +} + +/****************************************************************************** +* +*psgmii_set_duplex - Determines the speed of psgmii ports associated with the +* specified device. +*/ +sw_error_t +dess_psgmii_set_duplex(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_duplex_t duplex) +{ + sw_error_t rv; + a_uint32_t data = 0; + + rv = dess_psgmii_reg_get(dev_id, PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_5 + phy_id * 0x18, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_FULL_DUPLEX == duplex) + { + data |= PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_5_FULL_DUPLEX_25M; + data &= (~PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_5_HALF_DUPLEX_25M); + } + else + { + data |= PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_5_HALF_DUPLEX_25M; + data &= (~PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_5_FULL_DUPLEX_25M); + } + + rv = dess_psgmii_reg_set(dev_id, PSGMIIPHY_CHANNEL_0_INPUT_OUTPUT_5 + phy_id * 0x18, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +/****************************************************************************** +* +* psgmii_init - +* +*/ +a_bool_t +dess_psgmii_init(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint16_t org_id, a_uint16_t rev_id) +{ + + return SW_OK; +} diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_qos.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_qos.c new file mode 100755 index 000000000..80039f5b2 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_qos.c @@ -0,0 +1,1562 @@ +/* + * Copyright (c) 2014, 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. + */ + + +/** + * @defgroup dess_qos DESS_QOS + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "dess_qos.h" +#include "dess_reg.h" + +#define DESS_QOS_QUEUE_TX_BUFFER_MAX 120 +#define DESS_QOS_PORT_TX_BUFFER_MAX 504 +#define DESS_QOS_PORT_RX_BUFFER_MAX 120 + +#define DESS_QOS_HOL_STEP 8 +#define DESS_QOS_HOL_MOD 3 + +//#define DESS_MIN_QOS_MODE_PRI 0 +#define DESS_MAX_QOS_MODE_PRI 3 +#define DESS_MAX_PRI 7 +#define DESS_MAX_QUEUE 3 +#define DESS_MAX_EH_QUEUE 5 + +static sw_error_t +_dess_qos_queue_tx_buf_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_HOL_CTL1, port_id, QUEUE_DESC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_qos_queue_tx_buf_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_HOL_CTL1, port_id, QUEUE_DESC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_qos_port_tx_buf_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_HOL_CTL1, port_id, PORT_DESC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_qos_port_tx_buf_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_HOL_CTL1, port_id, PORT_DESC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_qos_port_red_en_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_HOL_CTL1, port_id, PORT_RED_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + + + +static sw_error_t +_dess_qos_port_red_en_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_HOL_CTL1, port_id, PORT_RED_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + + + +static sw_error_t +_dess_qos_port_queue_check(fal_port_t port_id, fal_queue_t queue_id) +{ + if ((0 == port_id) || (5 == port_id) || (6 == port_id)) + { + if (DESS_MAX_EH_QUEUE < queue_id) + { + return SW_BAD_PARAM; + } + } + else + { + if (DESS_MAX_QUEUE < queue_id) + { + return SW_BAD_PARAM; + } + } + + return SW_OK; +} + +static sw_error_t +_dess_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) +{ + a_uint32_t data = 0, val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (DESS_QOS_QUEUE_TX_BUFFER_MAX < *number) + { + return SW_BAD_PARAM; + } + + rv = _dess_qos_port_queue_check(port_id, queue_id); + SW_RTN_ON_ERROR(rv); + + val = *number / DESS_QOS_HOL_STEP; + *number = val << DESS_QOS_HOL_MOD; + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_HOL_CTL0, port_id, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data &= (~(0xf << (queue_id << 2))); + data |= (val << (queue_id << 2)); + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_HOL_CTL0, port_id, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return rv; +} + +static sw_error_t +_dess_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) +{ + a_uint32_t data = 0, val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + rv = _dess_qos_port_queue_check(port_id, queue_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_HOL_CTL0, port_id, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + val = (data >> (queue_id << 2)) & 0xf; + *number = val << DESS_QOS_HOL_MOD; + return SW_OK; +} + +static sw_error_t +_dess_qos_port_tx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (DESS_QOS_PORT_TX_BUFFER_MAX < *number) + { + return SW_BAD_PARAM; + } + + val = *number / DESS_QOS_HOL_STEP; + *number = val << DESS_QOS_HOL_MOD; + HSL_REG_FIELD_SET(rv, dev_id, PORT_HOL_CTL0, port_id, PORT_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_qos_port_tx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_HOL_CTL0, port_id, PORT_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *number = val << DESS_QOS_HOL_MOD; + return SW_OK; +} + +static sw_error_t +_dess_qos_port_rx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (DESS_QOS_PORT_RX_BUFFER_MAX < *number) + { + return SW_BAD_PARAM; + } + + val = *number / DESS_QOS_HOL_STEP; + *number = val << DESS_QOS_HOL_MOD; + HSL_REG_FIELD_SET(rv, dev_id, PORT_HOL_CTL1, port_id, PORT_IN_DESC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_qos_port_rx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_HOL_CTL1, port_id, PORT_IN_DESC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *number = val << DESS_QOS_HOL_MOD; + return SW_OK; +} + +static sw_error_t +_dess_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; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + if (FAL_QOS_DA_MODE == mode) + { + HSL_REG_FIELD_SET(rv, dev_id, PRI_CTL, port_id, DA_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (FAL_QOS_UP_MODE == mode) + { + HSL_REG_FIELD_SET(rv, dev_id, PRI_CTL, port_id, VLAN_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (FAL_QOS_DSCP_MODE == mode) + { + HSL_REG_FIELD_SET(rv, dev_id, PRI_CTL, port_id, IP_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (FAL_QOS_FLOW_MODE == mode) + { + HSL_REG_FIELD_SET(rv, dev_id, PRI_CTL, port_id, FLOW_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + + return rv; +} + +static sw_error_t +_dess_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; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_QOS_DA_MODE == mode) + { + HSL_REG_FIELD_GET(rv, dev_id, PRI_CTL, port_id, DA_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (FAL_QOS_UP_MODE == mode) + { + HSL_REG_FIELD_GET(rv, dev_id, PRI_CTL, port_id, VLAN_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (FAL_QOS_DSCP_MODE == mode) + { + HSL_REG_FIELD_GET(rv, dev_id, PRI_CTL, port_id, IP_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (FAL_QOS_FLOW_MODE == mode) + { + HSL_REG_FIELD_GET(rv, dev_id, PRI_CTL, port_id, FLOW_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_dess_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; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (DESS_MAX_QOS_MODE_PRI < pri) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PRI_CTL, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_QOS_DA_MODE == mode) + { + SW_SET_REG_BY_FIELD(PRI_CTL, DA_PRI_SEL, pri, val); + } + else if (FAL_QOS_UP_MODE == mode) + { + SW_SET_REG_BY_FIELD(PRI_CTL, VLAN_PRI_SEL, pri, val); + } + else if (FAL_QOS_DSCP_MODE == mode) + { + SW_SET_REG_BY_FIELD(PRI_CTL, IP_PRI_SEL, pri, val); + } + else if (FAL_QOS_FLOW_MODE == mode) + { + SW_SET_REG_BY_FIELD(PRI_CTL, FLOW_PRI_SEL, pri, val); + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_ENTRY_SET(rv, dev_id, PRI_CTL, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_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; + a_uint32_t entry = 0, f_val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PRI_CTL, port_id, (a_uint8_t *) (&entry), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_QOS_DA_MODE == mode) + { + SW_GET_FIELD_BY_REG(PRI_CTL, DA_PRI_SEL, f_val, entry); + } + else if (FAL_QOS_UP_MODE == mode) + { + SW_GET_FIELD_BY_REG(PRI_CTL, VLAN_PRI_SEL, f_val, entry); + } + else if (FAL_QOS_DSCP_MODE == mode) + { + SW_GET_FIELD_BY_REG(PRI_CTL, IP_PRI_SEL, f_val, entry); + } + else if (FAL_QOS_FLOW_MODE == mode) + { + SW_GET_FIELD_BY_REG(PRI_CTL, FLOW_PRI_SEL, f_val, entry); + } + else + { + return SW_NOT_SUPPORTED; + } + + *pri = f_val; + return SW_OK; +} + +static sw_error_t +_dess_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; + a_uint32_t reg = 0, val, w[6] = { 0 }; + a_int32_t i, _index; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_SCH_SP_MODE == mode) + { + val = 0; + _index = -1; + } + else if (FAL_SCH_WRR_MODE == mode) + { + val = 3; + _index = 5; + } + else if (FAL_SCH_MIX_MODE == mode) + { + val = 1; + _index = 4; + } + else if (FAL_SCH_MIX_PLUS_MODE == mode) + { + val = 2; + _index = 3; + } + else + { + return SW_NOT_SUPPORTED; + } + + for (i = _index; i >= 0; i--) + { + if (weight[i] > 0x1f) + { + return SW_BAD_PARAM; + } + w[i] = weight[i]; + } + + HSL_REG_ENTRY_GET(rv, dev_id, WRR_CTRL, port_id, (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(WRR_CTRL, SCH_MODE, val, reg); + SW_SET_REG_BY_FIELD(WRR_CTRL, Q5_W, w[5], reg); + SW_SET_REG_BY_FIELD(WRR_CTRL, Q4_W, w[4], reg); + SW_SET_REG_BY_FIELD(WRR_CTRL, Q3_W, w[3], reg); + SW_SET_REG_BY_FIELD(WRR_CTRL, Q2_W, w[2], reg); + SW_SET_REG_BY_FIELD(WRR_CTRL, Q1_W, w[1], reg); + SW_SET_REG_BY_FIELD(WRR_CTRL, Q0_W, w[0], reg); + + HSL_REG_ENTRY_SET(rv, dev_id, WRR_CTRL, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_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; + a_uint32_t val = 0, sch, w[6], i; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_ENTRY_GET(rv, dev_id, WRR_CTRL, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(WRR_CTRL, SCH_MODE, sch, val); + SW_GET_FIELD_BY_REG(WRR_CTRL, Q5_W, w[5], val); + SW_GET_FIELD_BY_REG(WRR_CTRL, Q4_W, w[4], val); + SW_GET_FIELD_BY_REG(WRR_CTRL, Q3_W, w[3], val); + SW_GET_FIELD_BY_REG(WRR_CTRL, Q2_W, w[2], val); + SW_GET_FIELD_BY_REG(WRR_CTRL, Q1_W, w[1], val); + SW_GET_FIELD_BY_REG(WRR_CTRL, Q0_W, w[0], val); + + if (0 == sch) + { + *mode = FAL_SCH_SP_MODE; + } + else if (1 == sch) + { + *mode = FAL_SCH_MIX_MODE; + } + else if (2 == sch) + { + *mode = FAL_SCH_MIX_PLUS_MODE; + } + else + { + *mode = FAL_SCH_WRR_MODE; + } + + for (i = 0; i < 6; i++) + { + weight[i] = w[i]; + } + + return SW_OK; +} + +static sw_error_t +_dess_qos_port_default_spri_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t spri) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (DESS_MAX_PRI < spri) + { + return SW_BAD_PARAM; + } + + val = spri; + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN0, port_id, + ING_SPRI, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_dess_qos_port_default_spri_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * spri) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN0, port_id, + ING_SPRI, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + *spri = val & 0x7; + return rv; +} + +static sw_error_t +_dess_qos_port_default_cpri_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t cpri) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (DESS_MAX_PRI < cpri) + { + return SW_BAD_PARAM; + } + + val = cpri; + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN0, port_id, + ING_CPRI, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + return rv; +} + +HSL_LOCAL sw_error_t +_dess_qos_port_default_cpri_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * cpri) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN0, port_id, + ING_CPRI, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + *cpri = val & 0x7; + return rv; +} + +HSL_LOCAL sw_error_t +_dess_qos_port_force_spri_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN0, port_id, + ING_FORCE_SPRI, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +HSL_LOCAL sw_error_t +_dess_qos_port_force_spri_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t* enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN0, port_id, + ING_FORCE_SPRI, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return rv; +} + +HSL_LOCAL sw_error_t +_dess_qos_port_force_cpri_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + val = enable ? 1 : 0; + + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN0, port_id, + ING_FORCE_CPRI, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + return rv; +} + +HSL_LOCAL sw_error_t +_dess_qos_port_force_cpri_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t* enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN0, port_id, + ING_FORCE_CPRI, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return rv; +} + +static sw_error_t +_dess_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; + a_uint32_t addr, data = 0; + a_uint32_t base[7] = {0x0c40, 0x0c48, 0x0c4c, 0x0c50, 0x0c54, 0x0c58, 0x0c60}; + + rv = _dess_qos_port_queue_check(port_id, queue_id); + SW_RTN_ON_ERROR(rv); + + addr = base[port_id] + ((queue_id / 4) << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data &= (~(0xff << ((queue_id % 4) << 3))); + data |= (((enable << 7 ) | (tbl_id & 0xf)) << ((queue_id % 4) << 3)); + + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +HSL_LOCAL sw_error_t +_dess_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; + a_uint32_t addr, data = 0; + a_uint32_t base[7] = {0x0c40, 0x0c48, 0x0c4c, 0x0c50, 0x0c54, 0x0c58, 0x0c60}; + + rv = _dess_qos_port_queue_check(port_id, queue_id); + SW_RTN_ON_ERROR(rv); + + addr = base[port_id] + ((queue_id / 4) << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *tbl_id = (data >> ((queue_id % 4) << 3)) & 0xf; + *enable = ((data >> ((queue_id % 4) << 3)) & 0x80) >> 7; + return SW_OK; +} + +/** + * @brief Set buffer aggsinment status of transmitting queue on one particular port. + * @details Comments: + * If enable queue tx buffer on one port that means each queue of this port + * will have fixed number buffers when transmitting packets. Otherwise they + * share the whole buffers with other queues in device. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_qos_queue_tx_buf_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_qos_queue_tx_buf_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get buffer aggsinment status of transmitting queue on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_qos_queue_tx_buf_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_qos_queue_tx_buf_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set buffer aggsinment status of transmitting port on one particular port. + * @details Comments: + If enable tx buffer on one port that means this port will have fixed + number buffers when transmitting packets. Otherwise they will + share the whole buffers with other ports in device. + * function will return actual buffer numbers in hardware. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_qos_port_tx_buf_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_qos_port_tx_buf_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get buffer aggsinment status of transmitting port on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_qos_port_tx_buf_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_qos_port_tx_buf_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of port red on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_qos_port_red_en_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_qos_port_red_en_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of port red on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_qos_port_red_en_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t* enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_qos_port_red_en_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + + +/** + * @brief Set max occupied buffer number of transmitting queue on one particular port. + * @details Comments: + The step of buffer number in Garuda is 4, function will return actual + buffer numbers in hardware. + The buffer number range for queue is 4 to 60. + * share the whole buffers with other ports in device. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param number buffer number + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_qos_queue_tx_buf_nr_set(dev_id, port_id, queue_id, number); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get max occupied buffer number of transmitting queue on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param[out] number buffer number + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_qos_queue_tx_buf_nr_get(dev_id, port_id, queue_id, number); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set max occupied buffer number of transmitting port on one particular port. + * @details Comments: + The step of buffer number in Garuda is four, function will return actual + buffer numbers in hardware. + The buffer number range for transmitting port is 4 to 124. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param number buffer number + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_qos_port_tx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_qos_port_tx_buf_nr_set(dev_id, port_id, number); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get max occupied buffer number of transmitting port on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] number buffer number + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_qos_port_tx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_qos_port_tx_buf_nr_get(dev_id, port_id, number); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set max occupied buffer number of receiving port on one particular port. + * @details Comments: + The step of buffer number in Shiva is four, function will return actual + buffer numbers in hardware. + The buffer number range for receiving port is 4 to 60. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param number buffer number + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_qos_port_rx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_qos_port_rx_buf_nr_set(dev_id, port_id, number); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get max occupied buffer number of receiving port on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] number buffer number + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_qos_port_rx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_qos_port_rx_buf_nr_get(dev_id, port_id, number); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set port qos mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode qos mode + * @param[in] enable A_TRUE of A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_qos_port_mode_set(dev_id, port_id, mode, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get port qos mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode qos mode + * @param[out] enable A_TRUE of A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_qos_port_mode_get(dev_id, port_id, mode, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set priority of one particular qos mode on one particular port. + * @details Comments: + If the priority of a mode is more small then the priority is more high. + Differnet mode should have differnet priority. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode qos mode + * @param[in] pri priority of one particular qos mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_qos_port_mode_pri_set(dev_id, port_id, mode, pri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get priority of one particular qos mode on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode qos mode + * @param[out] pri priority of one particular qos mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_qos_port_mode_pri_get(dev_id, port_id, mode, pri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set traffic scheduling mode on particular one port. + * @details Comments: + * When scheduling mode is sp the weight is meaningless usually it's zero + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] fal_sch_mode_t traffic scheduling mode + * @param[in] weight[] weight value for each queue when in wrr mode, + the max value supported by ISIS is 0x1f. + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_qos_port_sch_mode_set(dev_id, port_id, mode, weight); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get traffic scheduling mode on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] fal_sch_mode_t traffic scheduling mode + * @param[out] weight weight value for wrr mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_qos_port_sch_mode_get(dev_id, port_id, mode, weight); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set default stag priority on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] spri vlan priority + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_qos_port_default_spri_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t spri) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_qos_port_default_spri_set(dev_id, port_id, spri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get default stag priority on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] spri vlan priority + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_qos_port_default_spri_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * spri) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_qos_port_default_spri_get(dev_id, port_id, spri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set default ctag priority on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] cpri vlan priority + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_qos_port_default_cpri_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t cpri) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_qos_port_default_cpri_set(dev_id, port_id, cpri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get default ctag priority on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] cpri vlan priority + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_qos_port_default_cpri_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * cpri) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_qos_port_default_cpri_get(dev_id, port_id, cpri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set port force stag priority enable flag one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_qos_port_force_spri_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_qos_port_force_spri_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get port force stag priority enable flag one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_qos_port_force_spri_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t* enable) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _dess_qos_port_force_spri_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set port force ctag priority enable flag one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_qos_port_force_cpri_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_qos_port_force_cpri_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get port force ctag priority enable flag one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_qos_port_force_cpri_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t* enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_qos_port_force_cpri_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set egress queue based CoS remark on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param[in] tbl_id CoS remark table id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_qos_queue_remark_table_set(dev_id, port_id, queue_id, tbl_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get egress queue based CoS remark on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param[out] tbl_id CoS remark table id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_qos_queue_remark_table_get(dev_id, port_id, queue_id, tbl_id, enable); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +dess_qos_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->qos_queue_tx_buf_status_set = dess_qos_queue_tx_buf_status_set; + p_api->qos_queue_tx_buf_status_get = dess_qos_queue_tx_buf_status_get; + p_api->qos_port_tx_buf_status_set = dess_qos_port_tx_buf_status_set; + p_api->qos_port_tx_buf_status_get = dess_qos_port_tx_buf_status_get; + p_api->qos_port_red_en_set = dess_qos_port_red_en_set; + p_api->qos_port_red_en_get = dess_qos_port_red_en_get; + p_api->qos_queue_tx_buf_nr_set = dess_qos_queue_tx_buf_nr_set; + p_api->qos_queue_tx_buf_nr_get = dess_qos_queue_tx_buf_nr_get; + p_api->qos_port_tx_buf_nr_set = dess_qos_port_tx_buf_nr_set; + p_api->qos_port_tx_buf_nr_get = dess_qos_port_tx_buf_nr_get; + p_api->qos_port_rx_buf_nr_set = dess_qos_port_rx_buf_nr_set; + p_api->qos_port_rx_buf_nr_get = dess_qos_port_rx_buf_nr_get; + p_api->qos_port_mode_set = dess_qos_port_mode_set; + p_api->qos_port_mode_get = dess_qos_port_mode_get; + p_api->qos_port_mode_pri_set = dess_qos_port_mode_pri_set; + p_api->qos_port_mode_pri_get = dess_qos_port_mode_pri_get; + p_api->qos_port_sch_mode_set = dess_qos_port_sch_mode_set; + p_api->qos_port_sch_mode_get = dess_qos_port_sch_mode_get; + p_api->qos_port_default_spri_set = dess_qos_port_default_spri_set; + p_api->qos_port_default_spri_get = dess_qos_port_default_spri_get; + p_api->qos_port_default_cpri_set = dess_qos_port_default_cpri_set; + p_api->qos_port_default_cpri_get = dess_qos_port_default_cpri_get; + p_api->qos_port_force_spri_status_set = dess_qos_port_force_spri_status_set; + p_api->qos_port_force_spri_status_get = dess_qos_port_force_spri_status_get; + p_api->qos_port_force_cpri_status_set = dess_qos_port_force_cpri_status_set; + p_api->qos_port_force_cpri_status_get = dess_qos_port_force_cpri_status_get; + p_api->qos_queue_remark_table_set = dess_qos_queue_remark_table_set; + p_api->qos_queue_remark_table_get = dess_qos_queue_remark_table_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_rate.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_rate.c new file mode 100755 index 000000000..44cd36a80 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_rate.c @@ -0,0 +1,1672 @@ +/* + * Copyright (c) 2014,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. + */ + + +/** + * @defgroup dess_rate DESS_RATE + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "dess_rate.h" +#include "dess_reg.h" + +#define DESS_MAX_POLICER_ID 31 +#define DESS_MAX_QUEUE 3 +#define DESS_MAX_EH_QUEUE 5 + +#define ACL_POLICER_CNT_SEL_ADDR 0x09f0 +#define ACL_POLICER_CNT_MODE_ADDR 0x09f4 +#define ACL_POLICER_CNT_RST_ADDR 0x09f8 + +static sw_error_t +_dess_rate_port_queue_check(fal_port_t port_id, fal_queue_t queue_id) +{ + if ((0 == port_id) || (5 == port_id) || (6 == port_id)) + { + if (DESS_MAX_EH_QUEUE < queue_id) + { + return SW_BAD_PARAM; + } + } + else + { + if (DESS_MAX_QUEUE < queue_id) + { + return SW_BAD_PARAM; + } + } + + return SW_OK; +} + +static void +_dess_egress_bs_byte_sw_to_hw(a_uint32_t sw_bs, a_uint32_t * hw_bs) +{ + a_int32_t i; + a_uint32_t data[8] = + { + 0, 2 * 1024, 4 * 1024, 8 * 1024, 16 * 1024, 32 * 1024, 128 * 1024, + 512 * 1024 + }; + + for (i = 7; i >= 0; i--) + { + if (sw_bs >= data[i]) + { + *hw_bs = i; + break; + } + } +} + +static void +_dess_egress_bs_byte_hw_to_sw(a_uint32_t hw_bs, a_uint32_t * sw_bs) +{ + a_uint32_t data[8] = + { + 0, 2 * 1024, 4 * 1024, 8 * 1024, 16 * 1024, 32 * 1024, 128 * 1024, + 512 * 1024 + }; + + *sw_bs = data[hw_bs & 0x7]; +} + +static void +_dess_egress_bs_frame_sw_to_hw(a_uint32_t sw_bs, a_uint32_t * hw_bs) +{ + a_uint32_t data[8] = { 0, 2, 4, 16, 64, 256, 512, 1024 }; + a_int32_t i; + + for (i = 7; i >= 0; i--) + { + if (sw_bs >= data[i]) + { + *hw_bs = i; + break; + } + } +} + +static void +_dess_egress_bs_frame_hw_to_sw(a_uint32_t hw_bs, a_uint32_t * sw_bs) +{ + a_uint32_t data[8] = { 0, 2, 4, 16, 64, 256, 512, 1024 }; + + *sw_bs = data[hw_bs & 0x7]; +} + +static void +_dess_ingress_bs_byte_sw_to_hw(a_uint32_t sw_bs, a_uint32_t * hw_bs) +{ + a_int32_t i; + a_uint32_t data[8] = + { + 0, 4 * 1024, 32 * 1024, 128 * 1024, 512 * 1024, 2 * 1024 * 1024, + 8 * 1024 * 1024, 32 * 1024 * 1024 + }; + + for (i = 7; i >= 0; i--) + { + if (sw_bs >= data[i]) + { + *hw_bs = i; + break; + } + } +} + +static void +_dess_ingress_bs_byte_hw_to_sw(a_uint32_t hw_bs, a_uint32_t * sw_bs) +{ + a_uint32_t data[8] = + { + 0, 4 * 1024, 32 * 1024, 128 * 1024, 512 * 1024, 2 * 1024 * 1024, + 8 * 1024 * 1024, 32 * 1024 * 1024 + }; + + *sw_bs = data[hw_bs & 0x7]; +} + +static void +_dess_ingress_bs_frame_sw_to_hw(a_uint32_t sw_bs, a_uint32_t * hw_bs) +{ + a_uint32_t data[8] = { 0, 4, 16, 64, 256, 1024, 4096, 16384 }; + a_int32_t i; + + for (i = 7; i >= 0; i--) + { + if (sw_bs >= data[i]) + { + *hw_bs = i; + break; + } + } +} + +static void +_dess_ingress_bs_frame_hw_to_sw(a_uint32_t hw_bs, a_uint32_t * sw_bs) +{ + a_uint32_t data[8] = { 0, 4, 16, 64, 256, 1024, 4096, 16384 }; + + *sw_bs = data[hw_bs & 0x7]; +} + +static void +_dess_rate_flag_parse(a_uint32_t sw_flag, a_uint32_t * hw_flag) +{ + *hw_flag = 0; + + if (FAL_INGRESS_POLICING_TCP_CTRL & sw_flag) + { + *hw_flag |= (0x1 << 1); + } + + if (FAL_INGRESS_POLICING_MANAGEMENT & sw_flag) + { + *hw_flag |= (0x1 << 2); + } + + if (FAL_INGRESS_POLICING_BROAD & sw_flag) + { + *hw_flag |= (0x1 << 3); + } + + if (FAL_INGRESS_POLICING_UNK_UNI & sw_flag) + { + *hw_flag |= (0x1 << 4); + } + + if (FAL_INGRESS_POLICING_UNK_MUL & sw_flag) + { + *hw_flag |= (0x1 << 5); + } + + if (FAL_INGRESS_POLICING_UNI & sw_flag) + { + *hw_flag |= (0x1 << 6); + } + + if (FAL_INGRESS_POLICING_MUL & sw_flag) + { + *hw_flag |= (0x1 << 7); + } +} + +static void +_dess_rate_flag_reparse(a_uint32_t hw_flag, a_uint32_t * sw_flag) +{ + *sw_flag = 0; + + if (hw_flag & 0x2) + { + *sw_flag |= FAL_INGRESS_POLICING_TCP_CTRL; + } + + if (hw_flag & 0x4) + { + *sw_flag |= FAL_INGRESS_POLICING_MANAGEMENT; + } + + if (hw_flag & 0x8) + { + *sw_flag |= FAL_INGRESS_POLICING_BROAD; + } + + if (hw_flag & 0x10) + { + *sw_flag |= FAL_INGRESS_POLICING_UNK_UNI; + } + + if (hw_flag & 0x20) + { + *sw_flag |= FAL_INGRESS_POLICING_UNK_MUL; + } + + if (hw_flag & 0x40) + { + *sw_flag |= FAL_INGRESS_POLICING_UNI; + } + + if (hw_flag & 0x80) + { + *sw_flag |= FAL_INGRESS_POLICING_MUL; + } +} + +static void +_dess_rate_ts_parse(fal_rate_mt_t sw, a_uint32_t * hw) +{ + if (FAL_RATE_MI_100US == sw) + { + *hw = 0; + } + else if (FAL_RATE_MI_1MS == sw) + { + *hw = 1; + } + else if (FAL_RATE_MI_10MS == sw) + { + *hw = 2; + } + else if (FAL_RATE_MI_100MS) + { + *hw = 3; + } + else + { + *hw = 0; + } +} + +static void +_dess_rate_ts_reparse(a_uint32_t hw, fal_rate_mt_t * sw) +{ + if (0 == hw) + { + *sw = FAL_RATE_MI_100US; + } + else if (1 == hw) + { + *sw = FAL_RATE_MI_1MS; + } + else if (2 == hw) + { + *sw = FAL_RATE_MI_10MS; + } + else + { + *sw = FAL_RATE_MI_100MS; + } +} + +static sw_error_t +_dess_rate_port_policer_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_policer_t * policer) +{ + sw_error_t rv; + a_uint32_t cir = 0x7fff, eir = 0x7fff, cbs = 0, ebs = 0, tmp, data[3] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + data[0] = 0x18000000; + if (FAL_BYTE_BASED == policer->meter_unit) + { + if (A_TRUE == policer->c_enable) + { + cir = policer->cir >> 5; + policer->cir = cir << 5; + _dess_ingress_bs_byte_sw_to_hw(policer->cbs, &cbs); + _dess_ingress_bs_byte_hw_to_sw(cbs, &(policer->cbs)); + } + + if (A_TRUE == policer->e_enable) + { + eir = policer->eir >> 5; + policer->eir = eir << 5; + _dess_ingress_bs_byte_sw_to_hw(policer->ebs, &ebs); + _dess_ingress_bs_byte_hw_to_sw(ebs, &(policer->ebs)); + } + + SW_SET_REG_BY_FIELD(INGRESS_POLICER1, INGRESS_UNIT, 0, data[1]); + } + else if (FAL_FRAME_BASED == policer->meter_unit) + { + if (A_TRUE == policer->c_enable) + { + cir = (policer->cir * 2) / 125; + policer->cir = cir / 2 * 125 + cir % 2 * 63; + _dess_ingress_bs_frame_sw_to_hw(policer->cbs, &cbs); + _dess_ingress_bs_frame_hw_to_sw(cbs, &(policer->cbs)); + } + + if (A_TRUE == policer->e_enable) + { + eir = (policer->eir * 2) / 125; + policer->eir = eir / 2 * 125 + eir % 2 * 63; + _dess_ingress_bs_frame_sw_to_hw(policer->ebs, &ebs); + _dess_ingress_bs_frame_hw_to_sw(ebs, &(policer->ebs)); + } + + SW_SET_REG_BY_FIELD(INGRESS_POLICER1, INGRESS_UNIT, 1, data[1]); + } + else + { + return SW_BAD_PARAM; + } + + SW_SET_REG_BY_FIELD(INGRESS_POLICER0, INGRESS_CIR, cir, data[0]); + SW_SET_REG_BY_FIELD(INGRESS_POLICER0, INGRESS_CBS, cbs, data[0]); + SW_SET_REG_BY_FIELD(INGRESS_POLICER1, INGRESS_EIR, eir, data[1]); + SW_SET_REG_BY_FIELD(INGRESS_POLICER1, INGRESS_EBS, ebs, data[1]); + + if (A_TRUE == policer->combine_mode) + { + SW_SET_REG_BY_FIELD(INGRESS_POLICER0, RATE_MODE, 1, data[0]); + } + + if (A_TRUE == policer->deficit_en) + { + SW_SET_REG_BY_FIELD(INGRESS_POLICER1, INGRESS_BORROW, 1, data[1]); + } + + if (A_TRUE == policer->color_mode) + { + SW_SET_REG_BY_FIELD(INGRESS_POLICER1, INGRESS_CM, 1, data[1]); + } + + if (A_TRUE == policer->couple_flag) + { + SW_SET_REG_BY_FIELD(INGRESS_POLICER1, INGRESS_CF, 1, data[1]); + } + + _dess_rate_ts_parse(policer->c_meter_interval, &tmp); + SW_SET_REG_BY_FIELD(INGRESS_POLICER0, C_ING_TS, tmp, data[0]); + + _dess_rate_ts_parse(policer->e_meter_interval, &tmp); + SW_SET_REG_BY_FIELD(INGRESS_POLICER1, E_ING_TS, tmp, data[1]); + + _dess_rate_flag_parse(policer->c_rate_flag, &tmp); + data[2] = (tmp << 8) & 0xff00; + + _dess_rate_flag_parse(policer->e_rate_flag, &tmp); + data[2] |= (tmp & 0xff); + + HSL_REG_ENTRY_SET(rv, dev_id, INGRESS_POLICER0, port_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, INGRESS_POLICER1, port_id, + (a_uint8_t *) (&data[1]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, INGRESS_POLICER2, port_id, + (a_uint8_t *) (&data[2]), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_rate_port_policer_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_policer_t * policer) +{ + sw_error_t rv; + a_uint32_t unit, ts, cir, eir, cbs, ebs, data[3] = {0}; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, INGRESS_POLICER0, port_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, INGRESS_POLICER1, port_id, + (a_uint8_t *) (&data[1]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, INGRESS_POLICER2, port_id, + (a_uint8_t *) (&data[2]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(INGRESS_POLICER0, INGRESS_CIR, cir, data[0]); + SW_GET_FIELD_BY_REG(INGRESS_POLICER0, INGRESS_CBS, cbs, data[0]); + SW_GET_FIELD_BY_REG(INGRESS_POLICER1, INGRESS_EIR, eir, data[1]); + SW_GET_FIELD_BY_REG(INGRESS_POLICER1, INGRESS_EBS, ebs, data[1]); + SW_GET_FIELD_BY_REG(INGRESS_POLICER1, INGRESS_UNIT, unit, data[1]); + + policer->c_enable = A_TRUE; + if (0x7fff == cir) + { + policer->c_enable = A_FALSE; + cir = 0; + } + + policer->e_enable = A_TRUE; + if (0x7fff == eir) + { + policer->e_enable = A_FALSE; + eir = 0; + } + + if (unit) + { + policer->meter_unit = FAL_FRAME_BASED; + policer->cir = cir / 2 * 125 + cir % 2 * 63; + policer->eir = eir / 2 * 125 + eir % 2 * 63; + _dess_ingress_bs_frame_hw_to_sw(cbs, &(policer->cbs)); + _dess_ingress_bs_frame_hw_to_sw(ebs, &(policer->ebs)); + } + else + { + policer->meter_unit = FAL_BYTE_BASED; + policer->cir = cir << 5; + policer->eir = eir << 5; + _dess_ingress_bs_byte_hw_to_sw(cbs, &(policer->cbs)); + _dess_ingress_bs_byte_hw_to_sw(ebs, &(policer->ebs)); + } + + SW_GET_FIELD_BY_REG(INGRESS_POLICER0, RATE_MODE, policer->combine_mode, + data[0]); + SW_GET_FIELD_BY_REG(INGRESS_POLICER1, INGRESS_BORROW, policer->deficit_en, + data[1]); + SW_GET_FIELD_BY_REG(INGRESS_POLICER1, INGRESS_CF, policer->couple_flag, + data[1]); + SW_GET_FIELD_BY_REG(INGRESS_POLICER1, INGRESS_CM, policer->color_mode, + data[1]); + + ts = (data[2] >> 8) & 0xff; + _dess_rate_flag_reparse(ts, &(policer->c_rate_flag)); + + ts = data[2] & 0xff; + _dess_rate_flag_reparse(ts, &(policer->e_rate_flag)); + + SW_GET_FIELD_BY_REG(INGRESS_POLICER0, C_ING_TS, ts, data[0]); + _dess_rate_ts_reparse(ts, &(policer->c_meter_interval)); + + SW_GET_FIELD_BY_REG(INGRESS_POLICER1, E_ING_TS, ts, data[1]); + _dess_rate_ts_reparse(ts, &(policer->e_meter_interval)); + + return SW_OK; +} + +static sw_error_t +_dess_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; + a_uint32_t data, cir, eir, cbs = 0, ebs = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_FALSE == enable) + { + aos_mem_zero(shaper, sizeof (fal_egress_shaper_t)); + + cir = 0x7fff; + eir = 0x7fff; + } + else + { + if (FAL_BYTE_BASED == shaper->meter_unit) + { + cir = shaper->cir >> 5; + shaper->cir = cir << 5; + + eir = shaper->eir >> 5; + shaper->eir = eir << 5; + + _dess_egress_bs_byte_sw_to_hw(shaper->cbs, &cbs); + _dess_egress_bs_byte_hw_to_sw(cbs, &(shaper->cbs)); + + _dess_egress_bs_byte_sw_to_hw(shaper->ebs, &ebs); + _dess_egress_bs_byte_hw_to_sw(ebs, &(shaper->ebs)); + + data = 0; + } + else if (FAL_FRAME_BASED == shaper->meter_unit) + { + cir = (shaper->cir * 2) / 125; + shaper->cir = cir / 2 * 125 + cir % 2 * 63; + + eir = (shaper->eir * 2) / 125; + shaper->eir = eir / 2 * 125 + eir % 2 * 63; + + _dess_egress_bs_frame_sw_to_hw(shaper->cbs, &cbs); + _dess_egress_bs_frame_hw_to_sw(cbs, &(shaper->cbs)); + + _dess_egress_bs_frame_sw_to_hw(shaper->ebs, &ebs); + _dess_egress_bs_frame_hw_to_sw(ebs, &(shaper->ebs)); + + data = 1; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q0_UNIT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data = 1; + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_PT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data = 0; + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_TS, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER0, port_id, EG_Q0_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER3, port_id, EG_Q0_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q0_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q0_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_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; + a_uint32_t data = 0, cir = 0, eir = 0, cbs = 0, ebs = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + aos_mem_zero(shaper, sizeof (fal_egress_shaper_t)); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_PT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (!data) + { + *enable = A_FALSE; + return SW_OK; + } + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER0, port_id, EG_Q0_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER3, port_id, EG_Q0_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q0_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q0_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if ((0x7fff == cir) && (0x7fff == eir)) + { + *enable = A_FALSE; + return SW_OK; + } + + *enable = A_TRUE; + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q0_UNIT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data) + { + shaper->meter_unit = FAL_FRAME_BASED; + shaper->cir = cir / 2 * 125 + cir % 2 * 63; + shaper->eir = eir / 2 * 125 + eir % 2 * 63; + _dess_egress_bs_frame_hw_to_sw(cbs, &(shaper->cbs)); + _dess_egress_bs_frame_hw_to_sw(ebs, &(shaper->ebs)); + } + else + { + shaper->meter_unit = FAL_BYTE_BASED; + shaper->cir = cir << 5; + shaper->eir = eir << 5; + _dess_egress_bs_byte_hw_to_sw(cbs, &(shaper->cbs)); + _dess_egress_bs_byte_hw_to_sw(ebs, &(shaper->ebs)); + } + + return SW_OK; +} + +static sw_error_t +_dess_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; + a_uint32_t unit = 0, data, cir, eir, cbs = 0, ebs = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + rv = _dess_rate_port_queue_check(port_id, queue_id); + SW_RTN_ON_ERROR(rv); + + if (A_FALSE == enable) + { + aos_mem_zero(shaper, sizeof (fal_egress_shaper_t)); + + cir = 0x7fff; + eir = 0x7fff; + } + else + { + if (FAL_BYTE_BASED == shaper->meter_unit) + { + cir = shaper->cir >> 5; + shaper->cir = cir << 5; + + eir = shaper->eir >> 5; + shaper->eir = eir << 5; + + _dess_egress_bs_byte_sw_to_hw(shaper->cbs, &cbs); + _dess_egress_bs_byte_hw_to_sw(cbs, &(shaper->cbs)); + + _dess_egress_bs_byte_sw_to_hw(shaper->ebs, &ebs); + _dess_egress_bs_byte_hw_to_sw(ebs, &(shaper->ebs)); + + unit = 0; + } + else if (FAL_FRAME_BASED == shaper->meter_unit) + { + cir = (shaper->cir * 2) / 125; + shaper->cir = cir / 2 * 125 + cir % 2 * 63; + + eir = (shaper->eir * 2) / 125; + shaper->eir = eir / 2 * 125 + eir % 2 * 63; + + _dess_egress_bs_frame_sw_to_hw(shaper->cbs, &cbs); + _dess_egress_bs_frame_hw_to_sw(cbs, &(shaper->cbs)); + + _dess_egress_bs_frame_sw_to_hw(shaper->ebs, &ebs); + _dess_egress_bs_frame_hw_to_sw(ebs, &(shaper->ebs)); + + unit = 1; + } + + data = 0; + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_PT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data = 0; + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_TS, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + if (0 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER0, port_id, EG_Q0_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER3, port_id, EG_Q0_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q0_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q0_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q0_UNIT, + (a_uint8_t *) (&unit), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else if (1 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER0, port_id, EG_Q1_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER3, port_id, EG_Q1_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q1_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q1_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q1_UNIT, + (a_uint8_t *) (&unit), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else if (2 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER1, port_id, EG_Q2_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER4, port_id, EG_Q2_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q2_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q2_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q2_UNIT, + (a_uint8_t *) (&unit), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else if (3 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER1, port_id, EG_Q3_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER4, port_id, EG_Q3_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q3_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q3_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q3_UNIT, + (a_uint8_t *) (&unit), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else if (4 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER2, port_id, EG_Q4_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER5, port_id, EG_Q4_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q4_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q4_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q4_UNIT, + (a_uint8_t *) (&unit), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else + { + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER2, port_id, EG_Q5_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER5, port_id, EG_Q5_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q5_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q5_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q5_UNIT, + (a_uint8_t *) (&unit), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +static sw_error_t +_dess_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; + a_uint32_t data = 0, cir = 0, eir = 0, cbs = 0, ebs = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + rv = _dess_rate_port_queue_check(port_id, queue_id); + SW_RTN_ON_ERROR(rv); + + aos_mem_zero(shaper, sizeof (fal_egress_shaper_t)); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_PT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data) + { + *enable = A_FALSE; + return SW_OK; + } + + if (0 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER0, port_id, EG_Q0_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER3, port_id, EG_Q0_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q0_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q0_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q0_UNIT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else if (1 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER0, port_id, EG_Q1_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER3, port_id, EG_Q1_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q1_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q1_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q1_UNIT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else if (2 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER1, port_id, EG_Q2_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER4, port_id, EG_Q2_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q2_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q2_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q2_UNIT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else if (3 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER1, port_id, EG_Q3_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER4, port_id, EG_Q3_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q3_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q3_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q3_UNIT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else if (4 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER2, port_id, EG_Q4_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER5, port_id, EG_Q4_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q4_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q4_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q4_UNIT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else + { + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER2, port_id, EG_Q5_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER5, port_id, EG_Q5_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q5_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q5_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q5_UNIT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + if ((0x7fff == cir) && (0x7fff == eir)) + { + *enable = A_FALSE; + return SW_OK; + } + + *enable = A_TRUE; + if (data) + { + shaper->meter_unit = FAL_FRAME_BASED; + shaper->cir = cir / 2 * 125 + cir % 2 * 63; + shaper->eir = eir / 2 * 125 + eir % 2 * 63; + _dess_egress_bs_frame_hw_to_sw(cbs, &(shaper->cbs)); + _dess_egress_bs_frame_hw_to_sw(ebs, &(shaper->ebs)); + } + else + { + shaper->meter_unit = FAL_BYTE_BASED; + shaper->cir = cir << 5; + shaper->eir = eir << 5; + _dess_egress_bs_byte_hw_to_sw(cbs, &(shaper->cbs)); + _dess_egress_bs_byte_hw_to_sw(ebs, &(shaper->ebs)); + } + + return SW_OK; +} + +static sw_error_t +_dess_rate_acl_policer_set(a_uint32_t dev_id, a_uint32_t policer_id, + fal_acl_policer_t * policer) +{ + sw_error_t rv; + a_uint32_t ts, cir, eir, cbs = 0, ebs = 0, addr, data[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (DESS_MAX_POLICER_ID < policer_id) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == policer->counter_mode) + { + addr = ACL_POLICER_CNT_SEL_ADDR; + data[0] = 0x1; + HSL_REG_FIELD_GEN_SET(rv, dev_id, addr, 1, policer_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + addr = ACL_POLICER_CNT_MODE_ADDR; + if (FAL_FRAME_BASED == policer->meter_unit) + { + data[0] = 0x0; + } + else + { + data[0] = 0x1; + } + HSL_REG_FIELD_GEN_SET(rv, dev_id, addr, 1, policer_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + addr = ACL_POLICER_CNT_RST_ADDR; + data[0] = 0x1; + HSL_REG_FIELD_GEN_SET(rv, dev_id, addr, 1, policer_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data[0] = 0x0; + HSL_REG_FIELD_GEN_SET(rv, dev_id, addr, 1, policer_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + return rv; + } + + addr = ACL_POLICER_CNT_SEL_ADDR; + data[0] = 0x0; + HSL_REG_FIELD_GEN_SET(rv, dev_id, addr, 1, policer_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_BYTE_BASED == policer->meter_unit) + { + cir = policer->cir >> 5; + policer->cir = cir << 5; + + eir = policer->eir >> 5; + policer->eir = eir << 5; + + _dess_ingress_bs_byte_sw_to_hw(policer->cbs, &cbs); + _dess_ingress_bs_byte_hw_to_sw(cbs, &(policer->cbs)); + + _dess_ingress_bs_byte_sw_to_hw(policer->ebs, &ebs); + _dess_ingress_bs_byte_hw_to_sw(ebs, &(policer->ebs)); + + SW_SET_REG_BY_FIELD(ACL_POLICER1, ACL_UNIT, 0, data[1]); + } + else if (FAL_FRAME_BASED == policer->meter_unit) + { + cir = (policer->cir * 2) / 125; + policer->cir = cir / 2 * 125 + cir % 2 * 63; + + eir = (policer->eir * 2) / 125; + policer->eir = eir / 2 * 125 + eir % 2 * 63; + + _dess_ingress_bs_frame_sw_to_hw(policer->cbs, &cbs); + _dess_ingress_bs_frame_hw_to_sw(cbs, &(policer->cbs)); + + _dess_ingress_bs_frame_sw_to_hw(policer->ebs, &ebs); + _dess_ingress_bs_frame_hw_to_sw(ebs, &(policer->ebs)); + + SW_SET_REG_BY_FIELD(ACL_POLICER1, ACL_UNIT, 1, data[1]); + } + else + { + return SW_BAD_PARAM; + } + + SW_SET_REG_BY_FIELD(ACL_POLICER0, ACL_CIR, cir, data[0]); + SW_SET_REG_BY_FIELD(ACL_POLICER0, ACL_CBS, cbs, data[0]); + SW_SET_REG_BY_FIELD(ACL_POLICER1, ACL_EIR, eir, data[1]); + SW_SET_REG_BY_FIELD(ACL_POLICER1, ACL_EBS, ebs, data[1]); + + if (A_TRUE == policer->deficit_en) + { + SW_SET_REG_BY_FIELD(ACL_POLICER1, ACL_BORROW, 1, data[1]); + } + + if (A_TRUE == policer->color_mode) + { + SW_SET_REG_BY_FIELD(ACL_POLICER1, ACL_CM, 1, data[1]); + } + + if (A_TRUE == policer->couple_flag) + { + SW_SET_REG_BY_FIELD(ACL_POLICER1, ACL_CF, 1, data[1]); + } + + _dess_rate_ts_parse(policer->meter_interval, &ts); + SW_SET_REG_BY_FIELD(ACL_POLICER1, ACL_TS, ts, data[1]); + + HSL_REG_ENTRY_SET(rv, dev_id, ACL_POLICER0, policer_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ACL_POLICER1, policer_id, + (a_uint8_t *) (&data[1]), sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_dess_rate_acl_policer_get(a_uint32_t dev_id, a_uint32_t policer_id, + fal_acl_policer_t * policer) +{ + sw_error_t rv; + a_uint32_t unit, ts, cir, eir, cbs, ebs, addr, data[2] = {0}; + + HSL_DEV_ID_CHECK(dev_id); + + if (DESS_MAX_POLICER_ID < policer_id) + { + return SW_BAD_PARAM; + } + + aos_mem_zero(policer, sizeof (policer)); + + addr = ACL_POLICER_CNT_SEL_ADDR; + HSL_REG_FIELD_GEN_GET(rv, dev_id, addr, 1, policer_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data[0]) + { + policer->counter_mode = A_TRUE; + + addr = ACL_POLICER_CNT_MODE_ADDR; + HSL_REG_FIELD_GEN_GET(rv, dev_id, addr, 1, policer_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data[0]) + { + policer->meter_unit = FAL_BYTE_BASED; + } + else + { + policer->meter_unit = FAL_FRAME_BASED; + } + + HSL_REG_ENTRY_GET(rv, dev_id, ACL_COUNTER0, policer_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ACL_COUNTER1, policer_id, + (a_uint8_t *) (&data[1]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + policer->counter_low = data[0]; + policer->counter_high = data[1]; + + return SW_OK; + } + + HSL_REG_ENTRY_GET(rv, dev_id, ACL_POLICER0, policer_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ACL_POLICER1, policer_id, + (a_uint8_t *) (&data[1]), sizeof (a_uint32_t)); + + SW_GET_FIELD_BY_REG(ACL_POLICER0, ACL_CIR, cir, data[0]); + SW_GET_FIELD_BY_REG(ACL_POLICER0, ACL_CBS, cbs, data[0]); + SW_GET_FIELD_BY_REG(ACL_POLICER1, ACL_EIR, eir, data[1]); + SW_GET_FIELD_BY_REG(ACL_POLICER1, ACL_EBS, ebs, data[1]); + SW_GET_FIELD_BY_REG(ACL_POLICER1, ACL_UNIT, unit, data[1]); + if (unit) + { + policer->meter_unit = FAL_FRAME_BASED; + policer->cir = cir / 2 * 125 + cir % 2 * 63; + policer->eir = eir / 2 * 125 + eir % 2 * 63; + _dess_ingress_bs_frame_hw_to_sw(cbs, &(policer->cbs)); + _dess_ingress_bs_frame_hw_to_sw(ebs, &(policer->ebs)); + + } + else + { + policer->meter_unit = FAL_BYTE_BASED; + policer->cir = cir << 5; + policer->eir = eir << 5; + _dess_ingress_bs_byte_hw_to_sw(cbs, &(policer->cbs)); + _dess_ingress_bs_byte_hw_to_sw(ebs, &(policer->ebs)); + } + + SW_GET_FIELD_BY_REG(ACL_POLICER1, ACL_BORROW, policer->deficit_en, + data[1]); + SW_GET_FIELD_BY_REG(ACL_POLICER1, ACL_CF, policer->couple_flag, data[1]); + SW_GET_FIELD_BY_REG(ACL_POLICER1, ACL_CM, policer->color_mode, data[1]); + + SW_GET_FIELD_BY_REG(ACL_POLICER1, ACL_TS, ts, data[1]); + _dess_rate_ts_reparse(ts, &(policer->meter_interval)); + + return SW_OK; +} + +sw_error_t +_dess_rate_port_add_rate_byte_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t number) +{ + a_uint32_t val = number; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (val>255) + return SW_BAD_PARAM; + + HSL_REG_FIELD_SET(rv, dev_id, INGRESS_POLICER0, port_id, ADD_RATE_BYTE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + return rv; +} + +sw_error_t +_dess_rate_port_add_rate_byte_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t *number) +{ + a_uint32_t val = 0; + sw_error_t rv = SW_OK; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + + HSL_REG_FIELD_GET(rv, dev_id, INGRESS_POLICER0, port_id, ADD_RATE_BYTE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + *number = val; + + return rv; +} + +sw_error_t +_dess_rate_port_gol_flow_en_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t val = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, QM_CTRL_REG, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + + if (A_TRUE == enable) + { + val |= (0x1<<(16+port_id)); + } + else if (A_FALSE == enable) + { + val &= ~(0x1<<(16+port_id)); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_SET(rv, dev_id, QM_CTRL_REG, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + return rv; +} + +sw_error_t +_dess_rate_port_gol_flow_en_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t* enable) +{ + a_uint32_t val = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, QM_CTRL_REG, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (val&(0x1<<(16+port_id))) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return rv; +} + + + +/** + * @brief Set port ingress policer parameters on one particular port. + * @details Comments: + The granularity of speed is 32kbps or 62.5fps. + Because of hardware granularity function will return actual speed in hardware. + When disable port ingress policer input parameter speed is meaningless. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] policer port ingress policer parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_rate_port_policer_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_policer_t * policer) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_rate_port_policer_set(dev_id, port_id, policer); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get port ingress policer parameters on one particular port. + * @details Comments: + The granularity of speed is 32kbps or 62.5fps. + Because of hardware granularity function will return actual speed in hardware. + When disable port ingress policer input parameter speed is meaningless. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] policer port ingress policer parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_rate_port_policer_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_policer_t * policer) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_rate_port_policer_get(dev_id, port_id, policer); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set port egress shaper parameters on one particular port. + * @details Comments: + The granularity of speed is 32kbps or 62.5fps. + Because of hardware granularity function will return actual speed in hardware. + When disable port egress shaper parameters is meaningless. + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] shaper port egress shaper parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_rate_port_shaper_set(dev_id, port_id, enable, shaper); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get port egress shaper parameters on one particular port. + * @details Comments: + The granularity of speed is 32kbps or 62.5fps. + Because of hardware granularity function will return actual speed in hardware. + When disable port egress shaper parameters is meaningless. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @param[out] shaper port egress shaper parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_rate_port_shaper_get(dev_id, port_id, enable, shaper); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set queue egress shaper parameters on one particular port. + * @details Comments: + The granularity of speed is 32kbps or 62.5fps. + Because of hardware granularity function will return actual speed in hardware. + When disable queue egress shaper parameters is meaningless. + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] shaper port egress shaper parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_rate_queue_shaper_set(dev_id, port_id, queue_id, enable, shaper); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get queue egress shaper parameters on one particular port. + * @details Comments: + The granularity of speed is 32kbps or 62.5fps. + Because of hardware granularity function will return actual speed in hardware. + When disable queue egress shaper parameters is meaningless. + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param[out] enable A_TRUE or A_FALSE + * @param[out] shaper port egress shaper parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_rate_queue_shaper_get(dev_id, port_id, queue_id, enable, shaper); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set ACL ingress policer parameters. + * @details Comments: + The granularity of speed is 32kbps or 62.5fps. + Because of hardware granularity function will return actual speed in hardware. + * @param[in] dev_id device id + * @param[in] policer_id ACL policer id + * @param[in] policer ACL ingress policer parameters + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_rate_acl_policer_set(a_uint32_t dev_id, a_uint32_t policer_id, + fal_acl_policer_t * policer) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_rate_acl_policer_set(dev_id, policer_id, policer); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get ACL ingress policer parameters. + * @details Comments: + The granularity of speed is 32kbps or 62.5fps. + Because of hardware granularity function will return actual speed in hardware. + * @param[in] dev_id device id + * @param[in] policer_id ACL policer id + * @param[in] policer ACL ingress policer parameters + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_rate_acl_policer_get(a_uint32_t dev_id, a_uint32_t policer_id, + fal_acl_policer_t * policer) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_rate_acl_policer_get(dev_id, policer_id, policer); + HSL_API_UNLOCK; + return rv; +} + +HSL_LOCAL sw_error_t +dess_rate_port_add_rate_byte_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t number) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_rate_port_add_rate_byte_set(dev_id, port_id, number); + HSL_API_UNLOCK; + return rv; +} + +HSL_LOCAL sw_error_t +dess_rate_port_add_rate_byte_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t *number) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_rate_port_add_rate_byte_get(dev_id, port_id, number); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of port global flow control when global threshold is reached. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_rate_port_gol_flow_en_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_rate_port_gol_flow_en_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief get status of port global flow control when global threshold is reached. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_rate_port_gol_flow_en_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t* enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_rate_port_gol_flow_en_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + + + +sw_error_t +dess_rate_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->rate_port_policer_set = dess_rate_port_policer_set; + p_api->rate_port_policer_get = dess_rate_port_policer_get; + p_api->rate_port_shaper_set = dess_rate_port_shaper_set; + p_api->rate_port_shaper_get = dess_rate_port_shaper_get; + p_api->rate_queue_shaper_set = dess_rate_queue_shaper_set; + p_api->rate_queue_shaper_get = dess_rate_queue_shaper_get; + p_api->rate_acl_policer_set = dess_rate_acl_policer_set; + p_api->rate_acl_policer_get = dess_rate_acl_policer_get; + p_api->rate_port_gol_flow_en_set = dess_rate_port_gol_flow_en_set; + p_api->rate_port_gol_flow_en_get = dess_rate_port_gol_flow_en_get; + p_api->rate_port_add_rate_byte_set=dess_rate_port_add_rate_byte_set; + p_api->rate_port_add_rate_byte_get=dess_rate_port_add_rate_byte_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_reg_access.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_reg_access.c new file mode 100755 index 000000000..734b2e73a --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_reg_access.c @@ -0,0 +1,644 @@ +/* + * 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 "hsl.h" +#include "hsl_dev.h" +#include "sd.h" +#include "dess_reg_access.h" +#include "dess_psgmii.h" + +#if 0 +#include +#include +#include +#include +#include +#endif + +static hsl_access_mode reg_mode; + +#if defined(API_LOCK) +static aos_lock_t mdio_lock; +#define MDIO_LOCKER_INIT aos_lock_init(&mdio_lock) +#define MDIO_LOCKER_LOCK aos_lock(&mdio_lock) +#define MDIO_LOCKER_UNLOCK aos_unlock(&mdio_lock) +#else +#define MDIO_LOCKER_INIT +#define MDIO_LOCKER_LOCK +#define MDIO_LOCKER_UNLOCK +#endif + +#if defined(REG_ACCESS_SPEEDUP) +static a_uint32_t mdio_base_addr = 0xffffffff; +#endif + +extern void ssdk_psgmii_self_test(a_uint32_t dev_id, a_bool_t enable, a_uint32_t times, a_uint32_t *result); +extern void clear_self_test_config(a_uint32_t dev_id); + +static sw_error_t +_dess_mdio_reg_get(a_uint32_t dev_id, a_uint32_t reg_addr, + a_uint8_t value[], a_uint32_t value_len) +{ +#if 0 + a_uint32_t reg_word_addr; + a_uint32_t phy_addr, reg_val; + a_uint16_t phy_val, tmp_val; + a_uint8_t phy_reg; + sw_error_t rv; +#else + a_uint32_t reg_val; +#endif + + if (value_len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + +#if 0 + /* change reg_addr to 16-bit word address, 32-bit aligned */ + reg_word_addr = (reg_addr & 0xfffffffc) >> 1; + + /* configure register high address */ + phy_addr = 0x18; + phy_reg = 0x0; + phy_val = (a_uint16_t) ((reg_word_addr >> 8) & 0x3ff); /* bit16-8 of reg address */ + +#if defined(REG_ACCESS_SPEEDUP) + if (phy_val != mdio_base_addr) + { + rv = sd_reg_mdio_set(dev_id, phy_addr, phy_reg, phy_val); + SW_RTN_ON_ERROR(rv); + + mdio_base_addr = phy_val; + } +#else + rv = sd_reg_mdio_set(dev_id, phy_addr, phy_reg, phy_val); + SW_RTN_ON_ERROR(rv); +#endif + + /* For some registers such as MIBs, since it is read/clear, we should */ + /* read the lower 16-bit register then the higher one */ + + /* read register in lower address */ + phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */ + phy_reg = (a_uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */ + rv = sd_reg_mdio_get(dev_id, phy_addr, phy_reg, &tmp_val); + SW_RTN_ON_ERROR(rv); + reg_val = tmp_val; + + /* read register in higher address */ + reg_word_addr++; + phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */ + phy_reg = (a_uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */ + rv = sd_reg_mdio_get(dev_id, phy_addr, phy_reg, &tmp_val); + SW_RTN_ON_ERROR(rv); + reg_val |= (((a_uint32_t)tmp_val) << 16); +#else + reg_val = sd_reg_mii_get(dev_id, reg_addr); +#endif + aos_mem_copy(value, ®_val, sizeof (a_uint32_t)); + + return SW_OK; +} + +static sw_error_t +_dess_mdio_reg_set(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t value[], + a_uint32_t value_len) +{ +#if 0 + a_uint32_t reg_word_addr; + a_uint32_t phy_addr, reg_val; + a_uint16_t phy_val; + a_uint8_t phy_reg; + sw_error_t rv; +#else + a_uint32_t reg_val = 0; +#endif + + + if (value_len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + + aos_mem_copy(®_val, value, sizeof (a_uint32_t)); + +#if 0 + /* change reg_addr to 16-bit word address, 32-bit aligned */ + reg_word_addr = (reg_addr & 0xfffffffc) >> 1; + + /* configure register high address */ + phy_addr = 0x18; + phy_reg = 0x0; + phy_val = (a_uint16_t) ((reg_word_addr >> 8) & 0x3ff); /* bit16-8 of reg address */ + +#if defined(REG_ACCESS_SPEEDUP) + if (phy_val != mdio_base_addr) + { + rv = sd_reg_mdio_set(dev_id, phy_addr, phy_reg, phy_val); + SW_RTN_ON_ERROR(rv); + + mdio_base_addr = phy_val; + } +#else + rv = sd_reg_mdio_set(dev_id, phy_addr, phy_reg, phy_val); + SW_RTN_ON_ERROR(rv); +#endif + + /* For some registers such as ARL and VLAN, since they include BUSY bit */ + /* in higher address, we should write the lower 16-bit register then the */ + /* higher one */ + + /* write register in lower address */ + phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */ + phy_reg = (a_uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */ + phy_val = (a_uint16_t) (reg_val & 0xffff); + rv = sd_reg_mdio_set(dev_id, phy_addr, phy_reg, phy_val); + SW_RTN_ON_ERROR(rv); + + /* write register in higher address */ + reg_word_addr++; + phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */ + phy_reg = (a_uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */ + phy_val = (a_uint16_t) ((reg_val >> 16) & 0xffff); + rv = sd_reg_mdio_set(dev_id, phy_addr, phy_reg, phy_val); + SW_RTN_ON_ERROR(rv); +#else + sd_reg_mii_set(dev_id, reg_addr, reg_val); +#endif + return SW_OK; +} + +sw_error_t +dess_phy_get(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t * value) +{ + sw_error_t rv; + + MDIO_LOCKER_LOCK; + rv = sd_reg_mdio_get(dev_id, phy_addr, reg, value); + MDIO_LOCKER_UNLOCK; + return rv; +} + +sw_error_t +dess_phy_set(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t value) +{ + sw_error_t rv; + + MDIO_LOCKER_LOCK; + rv = sd_reg_mdio_set(dev_id, phy_addr, reg, value); + MDIO_LOCKER_UNLOCK; + return rv; +} + +sw_error_t +dess_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; + + MDIO_LOCKER_LOCK; + if (HSL_MDIO == reg_mode) + { + rv = _dess_mdio_reg_get(dev_id, reg_addr, value, value_len); + } + else + { + rv = sd_reg_hdr_get(dev_id, reg_addr, value, value_len); + } + MDIO_LOCKER_UNLOCK; + + return rv; +} + +sw_error_t +dess_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; +#if 0 + unsigned long flags; + + struct file *filp; + // mm_segment_t fs; + a_uint32_t rt_value = 0; + a_uint32_t write_flag = 0; + char s[20]= {0}; + a_uint32_t tmp_val = *((a_uint32_t *) value); +#else + a_uint32_t rt_value = 0; +#endif + + /*get MODULE_EN reg rsv */ + SW_RTN_ON_ERROR(dess_reg_get(dev_id, 0x30,(void *)&rt_value,4)); +// write_flag = (rt_value>>15) & 0x1; + + MDIO_LOCKER_LOCK; + if (HSL_MDIO == reg_mode) + { + rv = _dess_mdio_reg_set(dev_id, reg_addr, value, value_len); + } + else + { + rv = sd_reg_hdr_set(dev_id, reg_addr, value, value_len); + } + MDIO_LOCKER_UNLOCK; + +#if 0 + if(write_flag) + { + filp = filp_open("/tmp/asic_output", O_RDWR|O_APPEND, 0644); + if(IS_ERR(filp)) + { + printk("open error...\n"); + return; + } + + fs=get_fs(); + + set_fs(KERNEL_DS); + sprintf(s,"%08x %08x\n",reg_addr,tmp_val); + filp->f_op->write(filp, s, strlen(s),&filp->f_pos); + + set_fs(fs); + + filp_close(filp,NULL); + } +#endif + + return rv; +} + +sw_error_t +dess_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) +{ + a_uint32_t reg_val = 0; + + if ((bit_offset >= 32 || (field_len > 32)) || (field_len == 0)) + return SW_OUT_OF_RANGE; + + if (value_len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + + SW_RTN_ON_ERROR(dess_reg_get(dev_id, reg_addr, (a_uint8_t *) & reg_val, sizeof (a_uint32_t))); + + + if(32 == field_len) + { + *((a_uint32_t *) value) = reg_val; + } + else + { + *((a_uint32_t *) value) = SW_REG_2_FIELD(reg_val, bit_offset, field_len); + } + return SW_OK; +} + +sw_error_t +dess_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) +{ + a_uint32_t reg_val = 0; + a_uint32_t field_val = *((a_uint32_t *) value); + + if ((bit_offset >= 32 || (field_len > 32)) || (field_len == 0)) + return SW_OUT_OF_RANGE; + + if (value_len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + + SW_RTN_ON_ERROR(dess_reg_get(dev_id, reg_addr, (a_uint8_t *) & reg_val, sizeof (a_uint32_t))); + + if(32 == field_len) + { + reg_val = field_val; + } + else + { + SW_REG_SET_BY_FIELD_U32(reg_val, field_val, bit_offset, field_len); + } + + + SW_RTN_ON_ERROR(dess_reg_set(dev_id, reg_addr, (a_uint8_t *) & reg_val, sizeof (a_uint32_t))); + + return SW_OK; +} + +static sw_error_t +_dess_regsiter_dump(a_uint32_t dev_id,a_uint32_t register_idx, fal_reg_dump_t * reg_dump) +{ + sw_error_t rv = SW_OK; + typedef struct { + a_uint32_t reg_base; + a_uint32_t reg_end; + char name[30]; + } regdump; + + regdump reg_dumps[8] = + { + {0x0, 0xE4, "0.Global control registers"}, + {0x100, 0x168, "1.EEE control registers"}, + {0x200, 0x270, "2.Parser control registers"}, + {0x400, 0x474, "3.ACL control registers"}, + {0x600, 0x718, "4.Lookup control registers"}, + {0x800, 0xb70, "5.QM control registers"}, + {0xc00, 0xc80, "6.PKT edit control registers"}, + {0x820, 0x820, "7.QM debug registers"} + }; + + a_uint32_t dump_addr, reg_count, reg_val = 0; + switch (register_idx) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + reg_count = 0; + for (dump_addr = reg_dumps[register_idx].reg_base; dump_addr <= reg_dumps[register_idx].reg_end; reg_count++) + { + rv = dess_reg_get(dev_id, dump_addr, (a_uint8_t *) & reg_val, sizeof (a_uint32_t)); + reg_dump->reg_value[reg_count] = reg_val; + dump_addr += 4; + } + reg_dump->reg_count = reg_count; + reg_dump->reg_base = reg_dumps[register_idx].reg_base; + reg_dump->reg_end = reg_dumps[register_idx].reg_end; + snprintf((char *)reg_dump->reg_name,sizeof(reg_dump->reg_name),"%s",reg_dumps[register_idx].name); + break; + default: + return SW_BAD_PARAM; + } + + return rv; +} + +static sw_error_t +_dess_debug_regsiter_dump(a_uint32_t dev_id,fal_debug_reg_dump_t * dbg_reg_dump) +{ + sw_error_t rv = SW_OK; + a_uint32_t reg; + a_uint32_t reg_count, reg_val = 0; + + reg_count = 0; + + for(reg=0;reg<=0x1F;reg++) + { + dess_reg_set(dev_id, 0x820, (a_uint8_t *) & reg, sizeof (a_uint32_t)); + rv = dess_reg_get(dev_id, 0x824, (a_uint8_t *) & reg_val, sizeof (a_uint32_t)); + dbg_reg_dump->reg_value[reg_count] = reg_val; + dbg_reg_dump->reg_addr[reg_count] = reg; + reg_count++; + } + dbg_reg_dump->reg_count = reg_count; + + snprintf((char *)dbg_reg_dump->reg_name,sizeof(dbg_reg_dump->reg_name),"QM debug registers"); + return rv; +} +static sw_error_t +_dess_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 = SW_OK; + ssdk_psgmii_self_test(dev_id, enable, times, result); + clear_self_test_config(dev_id); + + return rv; +} + +static sw_error_t +_dess_phy_dump(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t idx, fal_phy_dump_t * phy_dump) +{ + sw_error_t rv = SW_OK; + typedef struct { + a_uint32_t phy_base; + a_uint32_t phy_end; + char name[30]; + } phydump; + + phydump dump[2] = + { + {0x0, 0x1f, "0.mii registers"}, + {0x0, 0x3f, "1.debug registers"}, + }; + + a_uint32_t mmd1[] = {0x0,0x5,0x8,0x1800,0x1801,0x1802,0x1803,0x1804, + 0x1805,0x1806,0x1807,0x1808,0x9000,0x9001,0x9002,0x9003, + 0x9004,0x9905,0x9006,0x9007,0x9008,0x9009,0x900a,0x900b}; + char mmd1name[30] = {"2.mmd1 register"}; + + a_uint32_t mmd3[] = {0x0,0x1,0x5,0x8,0x14,0x16,0x8001,0x8002, + 0x8003,0x8004,0x8005,0x8006,0x8007,0x8008,0x8009,0x800a, + 0x8045,0x8046,0x8047,0x8048,0x8049,0x804a,0x804b,0x804c, + 0x804d,0x804e,0x804f}; + char mmd3name[30] = {"3.mmd3 register"}; + + a_uint32_t mmd7[] = {0x0,0x1,0x5,0x16,0x17,0x18,0x19,0x1a,0x1b, + 0x3c,0x3d,0x8000,0x801a}; + char mmd7name[30] = {"4.mmd7 register"}; + + a_uint32_t reg = 0, phy_count = 0,i = 0; + a_uint16_t phy_val = 0; + switch (idx) + { + case 0: + for (reg = dump[idx].phy_base; reg <= dump[idx].phy_end; reg++) + { + rv = dess_phy_get(dev_id, phy_addr, reg, &phy_val); + phy_dump->phy_value[phy_count] = phy_val; + phy_count ++; + } + phy_dump->phy_count = phy_count; + phy_dump->phy_base = dump[idx].phy_base; + phy_dump->phy_end = dump[idx].phy_end; + snprintf((char *)phy_dump->phy_name, + sizeof(phy_dump->phy_name),"%s",dump[idx].name); + break; + case 1: + for (reg = dump[idx].phy_base; reg <= dump[idx].phy_end; reg++) + { + rv = dess_phy_set(dev_id, phy_addr, 0x1d, (a_uint16_t)reg); + rv = dess_phy_get(dev_id, phy_addr, 0x1e, &phy_val); + phy_dump->phy_value[phy_count] = phy_val; + phy_count ++; + } + phy_dump->phy_count = phy_count; + phy_dump->phy_base = dump[idx].phy_base; + phy_dump->phy_end = dump[idx].phy_end; + snprintf((char *)phy_dump->phy_name, + sizeof(phy_dump->phy_name),"%s",dump[idx].name); + break; + case 2: + phy_count = sizeof (mmd1)/sizeof(a_uint32_t); + for (i = 0; i < phy_count; i++ ) + { + rv = dess_phy_set(dev_id, phy_addr, 0xd, 1); + rv = dess_phy_set(dev_id, phy_addr, 0xe, (a_uint16_t)mmd1[i]); + rv = dess_phy_set(dev_id, phy_addr, 0xd, 0x4001); + rv = dess_phy_get(dev_id, phy_addr, 0xe, &phy_val); + phy_dump->phy_value[i] = phy_val; + } + phy_dump->phy_count = phy_count - 1; + phy_dump->phy_base = mmd1[0]; + phy_dump->phy_end = mmd1[phy_count - 1]; + snprintf((char *)phy_dump->phy_name, + sizeof(phy_dump->phy_name),"%s",mmd1name); + break; + case 3: + phy_count = sizeof (mmd3)/sizeof(a_uint32_t); + for (i = 0; i < phy_count; i++ ) + { + rv = dess_phy_set(dev_id, phy_addr, 0xd, 3); + rv = dess_phy_set(dev_id, phy_addr, 0xe, (a_uint16_t)mmd3[i]); + rv = dess_phy_set(dev_id, phy_addr, 0xd, 0x4003); + rv = dess_phy_get(dev_id, phy_addr, 0xe, &phy_val); + phy_dump->phy_value[i] = phy_val; + } + phy_dump->phy_count = phy_count - 1; + phy_dump->phy_base = mmd3[0]; + phy_dump->phy_end = mmd3[phy_count - 1]; + snprintf((char *)phy_dump->phy_name, + sizeof(phy_dump->phy_name),"%s",mmd3name); + break; + case 4: + phy_count = sizeof (mmd7)/sizeof(a_uint32_t); + for (i = 0; i < phy_count; i++ ) + { + rv = dess_phy_set(dev_id, phy_addr, 0xd, 7); + rv = dess_phy_set(dev_id, phy_addr, 0xe, (a_uint16_t)mmd7[i]); + rv = dess_phy_set(dev_id, phy_addr, 0xd, 0x4007); + rv = dess_phy_get(dev_id, phy_addr, 0xe, &phy_val); + phy_dump->phy_value[i] = phy_val; + } + phy_dump->phy_count = phy_count - 1; + phy_dump->phy_base = mmd7[0]; + phy_dump->phy_end = mmd7[phy_count - 1]; + snprintf((char *)phy_dump->phy_name, + sizeof(phy_dump->phy_name),"%s",mmd7name); + break; + default: + return SW_BAD_PARAM; + } + + return rv; +} + +/** + * @brief dump registers. + * @param[in] dev_id device id + * @param[in] register_idx register group id + * @param[out] reg_dump register dump result + * @return SW_OK or error code + */ +sw_error_t +dess_regsiter_dump(a_uint32_t dev_id,a_uint32_t register_idx, fal_reg_dump_t * reg_dump) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _dess_regsiter_dump(dev_id,register_idx,reg_dump); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief dump registers. + * @param[in] dev_id device id + * @param[out] reg_dump debug register dump + * @return SW_OK or error code + */ +sw_error_t +dess_debug_regsiter_dump(a_uint32_t dev_id, fal_debug_reg_dump_t * dbg_reg_dump) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _dess_debug_regsiter_dump(dev_id,dbg_reg_dump); + FAL_API_UNLOCK; + return rv; +} + + +/** + * @brief debug psgmii self test. + * @param[in] dev_id, enable, times + * @param[out] status + * @return SW_OK or error code + */ +sw_error_t +dess_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 = SW_OK; + + FAL_API_LOCK; + rv = _dess_debug_psgmii_self_test(dev_id, enable, times, result); + FAL_API_UNLOCK; + return rv; +} + +sw_error_t +dess_phy_dump(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t idx, fal_phy_dump_t * phy_dump) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _dess_phy_dump(dev_id, phy_addr, idx, phy_dump); + FAL_API_UNLOCK; + return rv; +} +sw_error_t +dess_reg_access_init(a_uint32_t dev_id, hsl_access_mode mode) +{ + hsl_api_t *p_api; + + MDIO_LOCKER_INIT; + reg_mode = mode; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->phy_get = dess_phy_get; + p_api->phy_set = dess_phy_set; + p_api->reg_get = dess_reg_get; + p_api->reg_set = dess_reg_set; + p_api->reg_field_get = dess_reg_field_get; + p_api->reg_field_set = dess_reg_field_set; + #ifdef IN_INTERFACECONTROL + p_api->psgmii_reg_get = dess_psgmii_reg_get; + p_api->psgmii_reg_set = dess_psgmii_reg_set; + #endif + p_api->register_dump = dess_regsiter_dump; + p_api->debug_register_dump = dess_debug_regsiter_dump; + p_api->debug_psgmii_self_test = dess_debug_psgmii_self_test; + p_api->phy_dump = dess_phy_dump; + + + return SW_OK; +} + +sw_error_t +dess_access_mode_set(a_uint32_t dev_id, hsl_access_mode mode) +{ + reg_mode = mode; + return SW_OK; + +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_sec.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_sec.c new file mode 100755 index 000000000..61c7588d1 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_sec.c @@ -0,0 +1,787 @@ +/* + * Copyright (c) 2014, 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. + */ + + +/** + * @defgroup dess_sec DESS_SEC + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "dess_sec.h" +#include "dess_reg.h" + +#define NORM_CTRL0_ADDR 0x0200 +#define NORM_CTRL1_ADDR 0x0204 +#define NORM_CTRL2_ADDR 0x0208 +#define NORM_CTRL3_ADDR 0x0c00 + +static sw_error_t +_dess_sec_norm_item_set(a_uint32_t dev_id, fal_norm_item_t item, void *value) +{ + sw_error_t rv; + fal_fwd_cmd_t cmd; + a_bool_t enable; + a_uint32_t addr, offset, len, reg = 0, val; + + HSL_DEV_ID_CHECK(dev_id); + + cmd = *((fal_fwd_cmd_t *) value); + enable = *((a_bool_t *) value); + val = *((a_uint32_t *) value); + + len = 1; + switch (item) + { + case FAL_NORM_MAC_RESV_VID_CMD: + addr = NORM_CTRL0_ADDR; + offset = 0; + goto cmd_chk; + + case FAL_NORM_MAC_INVALID_SRC_ADDR_CMD: + addr = NORM_CTRL1_ADDR; + offset = 20; + goto cmd_chk; + + case FAL_NORM_IP_INVALID_VER_CMD: + addr = NORM_CTRL0_ADDR; + offset = 1; + goto cmd_chk; + + case FAL_NROM_IP_SAME_ADDR_CMD: + addr = NORM_CTRL0_ADDR; + offset = 2; + goto cmd_chk; + break; + + case FAL_NROM_IP_TTL_CHANGE_STATUS: + addr = NORM_CTRL3_ADDR; + offset = 11; + goto sts_chk; + + case FAL_NROM_IP_TTL_VALUE: + addr = NORM_CTRL3_ADDR; + offset = 12; + len = 8; + goto set_reg; + + case FAL_NROM_IP4_INVALID_HL_CMD: + addr = NORM_CTRL0_ADDR; + offset = 3; + goto cmd_chk; + + case FAL_NROM_IP4_HDR_OPTIONS_CMD: + addr = NORM_CTRL0_ADDR; + offset = 4; + len = 2; + goto s_cmd_chk; + + case FAL_NROM_IP4_INVALID_DF_CMD: + addr = NORM_CTRL0_ADDR; + offset = 7; + goto cmd_chk; + + case FAL_NROM_IP4_FRAG_OFFSET_MIN_LEN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 8; + goto cmd_chk; + + case FAL_NROM_IP4_FRAG_OFFSET_MIN_SIZE: + addr = NORM_CTRL1_ADDR; + offset = 24; + len = 8; + goto set_reg; + + case FAL_NROM_IP4_FRAG_OFFSET_MAX_LEN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 9; + goto cmd_chk; + + case FAL_NROM_IP4_INVALID_FRAG_OFFSET_CMD: + addr = NORM_CTRL0_ADDR; + offset = 10; + goto cmd_chk; + + case FAL_NROM_IP4_INVALID_SIP_CMD: + addr = NORM_CTRL0_ADDR; + offset = 11; + len = 1; + goto cmd_chk; + + case FAL_NROM_IP4_INVALID_DIP_CMD: + addr = NORM_CTRL0_ADDR; + offset = 12; + goto cmd_chk; + + case FAL_NROM_IP4_INVALID_CHKSUM_CMD: + addr = NORM_CTRL0_ADDR; + offset = 13; + goto cmd_chk; + + case FAL_NROM_IP4_INVALID_PL_CMD: + addr = NORM_CTRL1_ADDR; + offset = 19; + goto cmd_chk; + + case FAL_NROM_IP4_DF_CLEAR_STATUS: + addr = NORM_CTRL3_ADDR; + offset = 9; + goto sts_chk; + + case FAL_NROM_IP4_IPID_RANDOM_STATUS: + addr = NORM_CTRL3_ADDR; + offset = 10; + goto sts_chk; + + case FAL_NROM_IP6_INVALID_DIP_CMD: + addr = NORM_CTRL1_ADDR; + offset = 16; + goto cmd_chk; + + case FAL_NROM_IP6_INVALID_SIP_CMD: + addr = NORM_CTRL1_ADDR; + offset = 17; + goto cmd_chk; + + case FAL_NROM_IP6_INVALID_PL_CMD: + addr = NORM_CTRL1_ADDR; + offset = 18; + goto cmd_chk; + + case FAL_NROM_TCP_BLAT_CMD: + addr = NORM_CTRL0_ADDR; + offset = 14; + goto cmd_chk; + + case FAL_NROM_TCP_INVALID_HL_CMD: + addr = NORM_CTRL0_ADDR; + offset = 15; + goto cmd_chk; + + case FAL_NROM_TCP_MIN_HDR_SIZE: + addr = NORM_CTRL1_ADDR; + offset = 12; + len = 4; + goto set_reg; + + case FAL_NROM_TCP_INVALID_SYN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 16; + goto cmd_chk; + break; + + case FAL_NROM_TCP_SU_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 17; + goto cmd_chk; + + case FAL_NROM_TCP_SP_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 18; + goto cmd_chk; + + case FAL_NROM_TCP_SAP_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 19; + goto cmd_chk; + + case FAL_NROM_TCP_XMAS_SCAN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 20; + goto cmd_chk; + + case FAL_NROM_TCP_NULL_SCAN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 21; + goto cmd_chk; + + case FAL_NROM_TCP_SR_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 22; + goto cmd_chk; + + case FAL_NROM_TCP_SF_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 23; + goto cmd_chk; + + case FAL_NROM_TCP_SAR_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 24; + goto cmd_chk; + + case FAL_NROM_TCP_RST_SCAN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 25; + goto cmd_chk; + + case FAL_NROM_TCP_SYN_WITH_DATA_CMD: + addr = NORM_CTRL0_ADDR; + offset = 26; + goto cmd_chk; + + case FAL_NROM_TCP_RST_WITH_DATA_CMD: + addr = NORM_CTRL0_ADDR; + offset = 27; + goto cmd_chk; + + case FAL_NROM_TCP_FA_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 28; + goto cmd_chk; + + case FAL_NROM_TCP_PA_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 29; + goto cmd_chk; + + case FAL_NROM_TCP_UA_BLOCK_CMD: + addr = NORM_CTRL1_ADDR; + offset = 0; + goto cmd_chk; + + case FAL_NROM_TCP_INVALID_CHKSUM_CMD: + addr = NORM_CTRL1_ADDR; + offset = 1; + goto cmd_chk; + + case FAL_NROM_TCP_INVALID_URGPTR_CMD: + addr = NORM_CTRL1_ADDR; + offset = 2; + goto cmd_chk; + + case FAL_NROM_TCP_INVALID_OPTIONS_CMD: + addr = NORM_CTRL1_ADDR; + offset = 3; + goto cmd_chk; + + case FAL_NROM_UDP_BLAT_CMD: + addr = NORM_CTRL1_ADDR; + offset = 4; + goto cmd_chk; + + case FAL_NROM_UDP_INVALID_LEN_CMD: + addr = NORM_CTRL1_ADDR; + offset = 5; + goto cmd_chk; + + case FAL_NROM_UDP_INVALID_CHKSUM_CMD: + addr = NORM_CTRL1_ADDR; + offset = 6; + goto cmd_chk; + + case FAL_NROM_ICMP4_PING_PL_EXCEED_CMD: + addr = NORM_CTRL1_ADDR; + offset = 7; + goto cmd_chk; + + case FAL_NROM_ICMP6_PING_PL_EXCEED_CMD: + addr = NORM_CTRL1_ADDR; + offset = 8; + goto cmd_chk; + + case FAL_NROM_ICMP4_PING_FRAG_CMD: + addr = NORM_CTRL1_ADDR; + offset = 9; + goto cmd_chk; + + case FAL_NROM_ICMP6_PING_FRAG_CMD: + addr = NORM_CTRL1_ADDR; + offset = 10; + goto cmd_chk; + + case FAL_NROM_ICMP4_PING_MAX_PL_VALUE: + addr = NORM_CTRL2_ADDR; + offset = 0; + len = 14; + goto set_reg; + + case FAL_NROM_ICMP6_PING_MAX_PL_VALUE: + addr = NORM_CTRL2_ADDR; + offset = 16; + len = 14; + goto set_reg; + + default: + return SW_BAD_PARAM; + } + +sts_chk: + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + goto set_reg; + +s_cmd_chk: + if (FAL_MAC_FRWRD == cmd) + { + val = 0; + } + else if (FAL_MAC_DROP == cmd) + { + val = 3; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + val = 2; + } + else + { + return SW_BAD_PARAM; + } + goto set_reg; + +cmd_chk: + if (FAL_MAC_FRWRD == cmd) + { + val = 0; + } + else if (FAL_MAC_DROP == cmd) + { + val = 1; + } + else + { + return SW_BAD_PARAM; + } + +set_reg: + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_REG_SET_BY_FIELD_U32(reg, val, offset, len); + + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_sec_norm_item_get(a_uint32_t dev_id, fal_norm_item_t item, void *value) +{ + sw_error_t rv; + a_uint32_t addr, offset, len, reg = 0, val; + a_uint32_t status_chk = 0, val_chk = 0, scmd_chk = 0; + + HSL_DEV_ID_CHECK(dev_id); + + len = 1; + switch (item) + { + case FAL_NORM_MAC_RESV_VID_CMD: + addr = NORM_CTRL0_ADDR; + offset = 0; + break; + + case FAL_NORM_MAC_INVALID_SRC_ADDR_CMD: + addr = NORM_CTRL1_ADDR; + offset = 20; + break; + + case FAL_NORM_IP_INVALID_VER_CMD: + addr = NORM_CTRL0_ADDR; + offset = 1; + break; + + case FAL_NROM_IP_SAME_ADDR_CMD: + addr = NORM_CTRL0_ADDR; + offset = 2; + break; + + case FAL_NROM_IP_TTL_CHANGE_STATUS: + addr = NORM_CTRL3_ADDR; + offset = 11; + status_chk = 1; + break; + + case FAL_NROM_IP_TTL_VALUE: + addr = NORM_CTRL3_ADDR; + offset = 12; + len = 8; + val_chk = 1; + break; + + case FAL_NROM_IP4_INVALID_HL_CMD: + addr = NORM_CTRL0_ADDR; + offset = 3; + break; + + case FAL_NROM_IP4_HDR_OPTIONS_CMD: + addr = NORM_CTRL0_ADDR; + offset = 4; + len = 2; + scmd_chk = 1; + break; + + case FAL_NROM_IP4_INVALID_DF_CMD: + addr = NORM_CTRL0_ADDR; + offset = 7; + break; + + case FAL_NROM_IP4_FRAG_OFFSET_MIN_LEN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 8; + break; + + case FAL_NROM_IP4_FRAG_OFFSET_MIN_SIZE: + addr = NORM_CTRL1_ADDR; + offset = 24; + len = 8; + val_chk = 1; + break; + + case FAL_NROM_IP4_FRAG_OFFSET_MAX_LEN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 9; + break; + + case FAL_NROM_IP4_INVALID_FRAG_OFFSET_CMD: + addr = NORM_CTRL0_ADDR; + offset = 10; + break; + + case FAL_NROM_IP4_INVALID_SIP_CMD: + addr = NORM_CTRL0_ADDR; + offset = 11; + len = 1; + break; + + case FAL_NROM_IP4_INVALID_DIP_CMD: + addr = NORM_CTRL0_ADDR; + offset = 12; + break; + + case FAL_NROM_IP4_INVALID_CHKSUM_CMD: + addr = NORM_CTRL0_ADDR; + offset = 13; + break; + + case FAL_NROM_IP4_INVALID_PL_CMD: + addr = NORM_CTRL1_ADDR; + offset = 19; + break; + + case FAL_NROM_IP4_DF_CLEAR_STATUS: + addr = NORM_CTRL3_ADDR; + offset = 9; + status_chk = 1; + break; + + case FAL_NROM_IP4_IPID_RANDOM_STATUS: + addr = NORM_CTRL3_ADDR; + offset = 10; + status_chk = 1; + break; + + case FAL_NROM_IP6_INVALID_DIP_CMD: + addr = NORM_CTRL1_ADDR; + offset = 16; + break; + + case FAL_NROM_IP6_INVALID_SIP_CMD: + addr = NORM_CTRL1_ADDR; + offset = 17; + break; + + case FAL_NROM_IP6_INVALID_PL_CMD: + addr = NORM_CTRL1_ADDR; + offset = 18; + break; + + case FAL_NROM_TCP_BLAT_CMD: + addr = NORM_CTRL0_ADDR; + offset = 14; + break; + + case FAL_NROM_TCP_INVALID_HL_CMD: + addr = NORM_CTRL0_ADDR; + offset = 15; + break; + + case FAL_NROM_TCP_MIN_HDR_SIZE: + addr = NORM_CTRL1_ADDR; + offset = 12; + len = 4; + val_chk = 1; + break; + + case FAL_NROM_TCP_INVALID_SYN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 16; + break; + + case FAL_NROM_TCP_SU_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 17; + break; + + case FAL_NROM_TCP_SP_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 18; + break; + + case FAL_NROM_TCP_SAP_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 19; + break; + + case FAL_NROM_TCP_XMAS_SCAN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 20; + break; + + case FAL_NROM_TCP_NULL_SCAN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 21; + break; + + case FAL_NROM_TCP_SR_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 22; + break; + + case FAL_NROM_TCP_SF_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 23; + break; + + case FAL_NROM_TCP_SAR_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 24; + break; + + case FAL_NROM_TCP_RST_SCAN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 25; + break; + + case FAL_NROM_TCP_SYN_WITH_DATA_CMD: + addr = NORM_CTRL0_ADDR; + offset = 26; + break; + + case FAL_NROM_TCP_RST_WITH_DATA_CMD: + addr = NORM_CTRL0_ADDR; + offset = 27; + break; + + case FAL_NROM_TCP_FA_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 28; + break; + + case FAL_NROM_TCP_PA_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 29; + break; + + case FAL_NROM_TCP_UA_BLOCK_CMD: + addr = NORM_CTRL1_ADDR; + offset = 0; + break; + + case FAL_NROM_TCP_INVALID_CHKSUM_CMD: + addr = NORM_CTRL1_ADDR; + offset = 1; + break; + + case FAL_NROM_TCP_INVALID_URGPTR_CMD: + addr = NORM_CTRL1_ADDR; + offset = 2; + break; + + case FAL_NROM_TCP_INVALID_OPTIONS_CMD: + addr = NORM_CTRL1_ADDR; + offset = 3; + break; + + case FAL_NROM_UDP_BLAT_CMD: + addr = NORM_CTRL1_ADDR; + offset = 4; + break; + + case FAL_NROM_UDP_INVALID_LEN_CMD: + addr = NORM_CTRL1_ADDR; + offset = 5; + break; + + case FAL_NROM_UDP_INVALID_CHKSUM_CMD: + addr = NORM_CTRL1_ADDR; + offset = 6; + break; + + case FAL_NROM_ICMP4_PING_PL_EXCEED_CMD: + addr = NORM_CTRL1_ADDR; + offset = 7; + break; + + case FAL_NROM_ICMP6_PING_PL_EXCEED_CMD: + addr = NORM_CTRL1_ADDR; + offset = 8; + break; + + case FAL_NROM_ICMP4_PING_FRAG_CMD: + addr = NORM_CTRL1_ADDR; + offset = 9; + break; + + case FAL_NROM_ICMP6_PING_FRAG_CMD: + addr = NORM_CTRL1_ADDR; + offset = 10; + break; + + case FAL_NROM_ICMP4_PING_MAX_PL_VALUE: + addr = NORM_CTRL2_ADDR; + offset = 0; + len = 14; + val_chk = 1; + break; + + case FAL_NROM_ICMP6_PING_MAX_PL_VALUE: + addr = NORM_CTRL2_ADDR; + offset = 16; + len = 14; + val_chk = 1; + break; + + default: + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_FIELD_GET_BY_REG_U32(reg, val, offset, len); + + if (val_chk) + { + *((a_uint32_t *) value) = val; + } + else if (status_chk) + { + if (val) + { + *((a_bool_t *) value) = A_TRUE; + } + else + { + *((a_bool_t *) value) = A_FALSE; + } + } + else if (scmd_chk) + { + if (2 == val) + { + *((fal_fwd_cmd_t *) value) = FAL_MAC_RDT_TO_CPU; + } + else if (3 == val) + { + *((fal_fwd_cmd_t *) value) = FAL_MAC_DROP; + } + else + { + *((fal_fwd_cmd_t *) value) = FAL_MAC_FRWRD; + } + } + else + { + if (val) + { + *((fal_fwd_cmd_t *) value) = FAL_MAC_DROP; + } + else + { + *((fal_fwd_cmd_t *) value) = FAL_MAC_FRWRD; + } + } + + return SW_OK; +} + +/** + * @brief Set normalization particular item types value. + * @details Comments: + * This operation will set normalization item values on a particular device. + * The prototye of value based on the item type. + * @param[in] dev_id device id + * @param[in] item normalizaton item type + * @param[in] value normalizaton item value + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_sec_norm_item_set(a_uint32_t dev_id, fal_norm_item_t item, void *value) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_sec_norm_item_set(dev_id, item, value); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get normalization particular item types value. + * @details Comments: + * This operation will set normalization item values on a particular device. + * The prototye of value based on the item type. + * @param[in] dev_id device id + * @param[in] item normalizaton item type + * @param[out] value normalizaton item value + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_sec_norm_item_get(a_uint32_t dev_id, fal_norm_item_t item, void *value) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_sec_norm_item_get(dev_id, item, value); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +dess_sec_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->sec_norm_item_set = dess_sec_norm_item_set; + p_api->sec_norm_item_get = dess_sec_norm_item_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_stp.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_stp.c new file mode 100755 index 000000000..6537241de --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_stp.c @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2014, 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. + */ + + +/** + * @defgroup dess_stp DESS_STP + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "dess_stp.h" +#include "dess_reg.h" + +#define DESS_PORT_DISABLED 0 +#define DESS_STP_BLOCKING 1 +#define DESS_STP_LISTENING 2 +#define DESS_STP_LEARNING 3 +#define DESS_STP_FARWARDING 4 + +static sw_error_t +_dess_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; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_SINGLE_STP_ID != st_id) + { + return SW_BAD_PARAM; + } + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + switch (state) + { + case FAL_STP_BLOKING: + val = DESS_STP_BLOCKING; + break; + case FAL_STP_LISTENING: + val = DESS_STP_LISTENING; + break; + case FAL_STP_LEARNING: + val = DESS_STP_LEARNING; + break; + case FAL_STP_FARWARDING: + val = DESS_STP_FARWARDING; + break; + case FAL_STP_DISABLED: + val = DESS_PORT_DISABLED; + break; + default: + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LOOKUP_CTL, port_id, PORT_STATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_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; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_SINGLE_STP_ID != st_id) + { + return SW_BAD_PARAM; + } + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LOOKUP_CTL, port_id, PORT_STATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + switch (val) + { + case DESS_STP_BLOCKING: + *state = FAL_STP_BLOKING; + break; + case DESS_STP_LISTENING: + *state = FAL_STP_LISTENING; + break; + case DESS_STP_LEARNING: + *state = FAL_STP_LEARNING; + break; + case DESS_STP_FARWARDING: + *state = FAL_STP_FARWARDING; + break; + case DESS_PORT_DISABLED: + *state = FAL_STP_DISABLED; + break; + default: + return SW_FAIL; + } + + return SW_OK; +} + +/** + * @brief Set port stp state on a particular spanning tree and port. + * @details Comments: + Garuda only support single spanning tree so st_id should be + FAL_SINGLE_STP_ID that is zero. + * @param[in] dev_id device id + * @param[in] st_id spanning tree id + * @param[in] port_id port id + * @param[in] state port state for spanning tree + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_stp_port_state_set(dev_id, st_id, port_id, state); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get port stp state on a particular spanning tree and port. + * @details Comments: + Garuda only support single spanning tree so st_id should be + FAL_SINGLE_STP_ID that is zero. + * @param[in] dev_id device id + * @param[in] st_id spanning tree id + * @param[in] port_id port id + * @param[out] state port state for spanning tree + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_stp_port_state_get(dev_id, st_id, port_id, state); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +dess_stp_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->stp_port_state_set = dess_stp_port_state_set; + p_api->stp_port_state_get = dess_stp_port_state_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_trunk.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_trunk.c new file mode 100755 index 000000000..e57eb0d25 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_trunk.c @@ -0,0 +1,327 @@ +/* + * Copyright (c) 2014, 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. + */ + + + +/** + * @defgroup dess_trunk DESS_TRUNK + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "dess_trunk.h" +#include "dess_reg.h" + +#define DESS_MAX_TRUNK_ID 3 + +enum dess_trunk_reg_id +{ + DESS_TRUNK_HASH_EN = 0, /*0x270*/ + DESS_TRUNK_CTRL_0, /*0x700*/ + DESS_TRUNK_CTRL_1, /*0x704*/ + DESS_TRUNK_CTRL_2, /*0x708*/ + DESS_TRUNK_REG_MAX +}; + +static a_uint32_t dess_trunk_regs[DESS_TRUNK_REG_MAX] = +{ + 0xf, 0x0, 0x0, 0x0 +}; + +static sw_error_t +_dess_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; + a_uint32_t i, reg = 0, cnt = 0, data0 = 0, data1 = 0; + + if (DESS_MAX_TRUNK_ID < trunk_id) + { + return SW_BAD_PARAM; + } + + if (A_FALSE == hsl_mports_prop_check(dev_id, member, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data0 = (0x1 << 7) | member; + + for (i = 0; i < 7; i++) + { + if (member & (0x1 << i)) + { + if (4 <= cnt) + { + return SW_BAD_PARAM; + } + + data1 |= (i << (cnt << 2)); + data1 |= (1 << (3 + (cnt << 2))); + cnt++; + } + } + } + else if (A_FALSE == enable) + { + + } + else + { + return SW_BAD_PARAM; + } + + /* set trunk port member bitmap info */ + HSL_REG_ENTRY_GET(rv, dev_id, GOL_TRUNK_CTL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + reg &= (~(0xff << (trunk_id << 3))); + reg |= (data0 << (trunk_id << 3)); + + HSL_REG_ENTRY_SET(rv, dev_id, GOL_TRUNK_CTL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + dess_trunk_regs[DESS_TRUNK_CTRL_0] = reg; + + /* set trunk port member id info */ + HSL_REG_ENTRY_GET(rv, dev_id, GOL_TRUNK_CTL1, (trunk_id >> 1), + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + reg &= (~(0xffff << ((trunk_id % 2) << 4))); + reg |= (data1 << ((trunk_id % 2) << 4)); + + HSL_REG_ENTRY_SET(rv, dev_id, GOL_TRUNK_CTL1, (trunk_id >> 1), + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + dess_trunk_regs[DESS_TRUNK_CTRL_1 + (trunk_id >> 1)] = reg; + + return SW_OK; +} + +static sw_error_t +_dess_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; + a_uint32_t data, reg = 0; + + if (DESS_MAX_TRUNK_ID < trunk_id) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, GOL_TRUNK_CTL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data = (reg >> (trunk_id << 3)) & 0xff; + if (0x80 & data) + { + *enable = A_TRUE; + *member = data & 0x7f; + } + else + { + *enable = A_FALSE; + *member = 0; + } + + return SW_OK; +} + +static sw_error_t +_dess_trunk_hash_mode_set(a_uint32_t dev_id, a_uint32_t hash_mode) +{ + sw_error_t rv; + a_uint32_t data = 0; + + if (FAL_TRUNK_HASH_KEY_DA & hash_mode) + { + SW_SET_REG_BY_FIELD(TRUNK_HASH_MODE, DA_EN, 1, data); + } + + if (FAL_TRUNK_HASH_KEY_SA & hash_mode) + { + SW_SET_REG_BY_FIELD(TRUNK_HASH_MODE, SA_EN, 1, data); + } + + if (FAL_TRUNK_HASH_KEY_DIP & hash_mode) + { + SW_SET_REG_BY_FIELD(TRUNK_HASH_MODE, DIP_EN, 1, data); + } + + if (FAL_TRUNK_HASH_KEY_SIP & hash_mode) + { + SW_SET_REG_BY_FIELD(TRUNK_HASH_MODE, SIP_EN, 1, data); + } + + HSL_REG_ENTRY_SET(rv, dev_id, TRUNK_HASH_MODE, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + dess_trunk_regs[DESS_TRUNK_HASH_EN] = data; + + return rv; +} + +static sw_error_t +_dess_trunk_hash_mode_get(a_uint32_t dev_id, a_uint32_t * hash_mode) +{ + sw_error_t rv; + a_uint32_t reg = 0, data = 0; + + HSL_REG_ENTRY_GET(rv, dev_id, TRUNK_HASH_MODE, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *hash_mode = 0; + + SW_GET_FIELD_BY_REG(TRUNK_HASH_MODE, DA_EN, data, reg); + if (data) + { + *hash_mode |= FAL_TRUNK_HASH_KEY_DA; + } + + SW_GET_FIELD_BY_REG(TRUNK_HASH_MODE, SA_EN, data, reg); + if (data) + { + *hash_mode |= FAL_TRUNK_HASH_KEY_SA; + } + + SW_GET_FIELD_BY_REG(TRUNK_HASH_MODE, DIP_EN, data, reg); + if (data) + { + *hash_mode |= FAL_TRUNK_HASH_KEY_DIP; + } + + SW_GET_FIELD_BY_REG(TRUNK_HASH_MODE, SIP_EN, data, reg); + if (data) + { + *hash_mode |= FAL_TRUNK_HASH_KEY_SIP; + } + + return SW_OK; +} + + +/** + * @brief Set particular trunk group information on particular device. + * @param[in] dev_id device id + * @param[in] trunk_id trunk group id + * @param[in] enable trunk group status, enable or disable + * @param[in] member port member information + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_trunk_group_set(dev_id, trunk_id, enable, member); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get particular trunk group information on particular device. + * @param[in] dev_id device id + * @param[in] trunk_id trunk group id + * @param[out] enable trunk group status, enable or disable + * @param[out] member port member information + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_trunk_group_get(dev_id, trunk_id, enable, member); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set trunk hash mode on particular device. + * @details Comments: + hash mode is listed below + FAL_TRUNK_HASH_KEY_DA, FAL_TRUNK_HASH_KEY_SA, FAL_TRUNK_HASH_KEY_DIP and FAL_TRUNK_HASH_KEY_SIP + * @param[in] dev_id device id + * @param[in] hash_mode trunk hash mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_trunk_hash_mode_set(a_uint32_t dev_id, a_uint32_t hash_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_trunk_hash_mode_set(dev_id, hash_mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get trunk hash mode on particular device. + * @param[in] dev_id device id + * @param[out] hash_mode trunk hash mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_trunk_hash_mode_get(a_uint32_t dev_id, a_uint32_t * hash_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_trunk_hash_mode_get(dev_id, hash_mode); + HSL_API_UNLOCK; + return rv; +} + + +sw_error_t +dess_trunk_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->trunk_group_set = dess_trunk_group_set; + p_api->trunk_group_get = dess_trunk_group_get; + p_api->trunk_hash_mode_set = dess_trunk_hash_mode_set; + p_api->trunk_hash_mode_get = dess_trunk_hash_mode_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_vlan.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_vlan.c new file mode 100755 index 000000000..2923cb34e --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/dess/dess_vlan.c @@ -0,0 +1,906 @@ +/* + * 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 dess_vlan DESS_VLAN + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "dess_vlan.h" +#include "dess_reg.h" + +#define MAX_VLAN_ID 4095 + +#define VLAN_FLUSH 1 +#define VLAN_LOAD_ENTRY 2 +#define VLAN_PURGE_ENTRY 3 +#define VLAN_REMOVE_PORT 4 +#define VLAN_NEXT_ENTRY 5 +#define VLAN_FIND_ENTRY 6 + +static void +_dess_vlan_hw_to_sw(a_uint32_t reg[], fal_vlan_t * vlan_entry) +{ + a_uint32_t i, data, tmp; + + aos_mem_zero(vlan_entry, sizeof (fal_vlan_t)); + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC1, VLAN_ID, data, reg[1]); + vlan_entry->vid = data & 0xfff; + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC0, IVL_EN, data, reg[0]); + if (1 == data) + { + vlan_entry->fid = vlan_entry->vid; + } + else + { + vlan_entry->fid = FAL_SVL_FID; + } + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC0, LEARN_DIS, data, reg[0]); + if (1 == data) + { + vlan_entry->learn_dis = A_TRUE; + } + else + { + vlan_entry->learn_dis = A_FALSE; + } + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC0, VT_PRI_EN, data, reg[0]); + if (1 == data) + { + vlan_entry->vid_pri_en = A_TRUE; + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC0, VT_PRI, data, reg[0]); + vlan_entry->vid_pri = data & 0xff; + } + else + { + vlan_entry->vid_pri_en = A_FALSE; + } + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC0, VID_MEM, data, reg[0]); + for (i = 0; i < 7; i++) + { + tmp = (data >> (i << 1)) & 0x3UL; + if (0 == tmp) + { + vlan_entry->mem_ports |= (0x1UL << i); + vlan_entry->unmodify_ports |= (0x1UL << i); + } + else if (1 == tmp) + { + vlan_entry->mem_ports |= (0x1UL << i); + vlan_entry->untagged_ports |= (0x1UL << i); + } + else if (2 == tmp) + { + vlan_entry->mem_ports |= (0x1UL << i); + vlan_entry->tagged_ports |= (0x1UL << i); + } + } + + return; +} + +static sw_error_t +_dess_vlan_sw_to_hw(a_uint32_t dev_id, const fal_vlan_t * vlan_entry, + a_uint32_t reg[]) +{ + a_uint32_t i, tag, untag, unmodify, member = 0; + + if (vlan_entry->vid > MAX_VLAN_ID) + { + return SW_OUT_OF_RANGE; + } + + if (A_FALSE == + hsl_mports_prop_check(dev_id, vlan_entry->mem_ports, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_VALID, 1, reg[0]); + + if (FAL_SVL_FID == vlan_entry->fid) + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, IVL_EN, 0, reg[0]); + } + else if (vlan_entry->vid == vlan_entry->fid) + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, IVL_EN, 1, reg[0]); + } + else + { + return SW_BAD_VALUE; + } + + if (A_TRUE == vlan_entry->learn_dis) + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, LEARN_DIS, 1, reg[0]); + } + else + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, LEARN_DIS, 0, reg[0]); + } + + for (i = 0; i < 7; i++) + { + if ((vlan_entry->mem_ports >> i) & 0x1UL) + { + tag = (vlan_entry->tagged_ports >> i) & 0x1UL; + untag = (vlan_entry->untagged_ports >> i) & 0x1UL; + unmodify = (vlan_entry->unmodify_ports >> i) & 0x1UL; + + if ((0 == (tag + untag + unmodify)) + || (1 < (tag + untag + unmodify))) + { + return SW_BAD_VALUE; + } + + if (tag) + { + member |= (2 << (i << 1)); + } + else if (untag) + { + member |= (1 << (i << 1)); + } + } + else + { + member |= (3 << (i << 1)); + } + } + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VID_MEM, member, reg[0]); + + if (A_TRUE == vlan_entry->vid_pri_en) + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_PRI_EN, 1, reg[0]); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_PRI, vlan_entry->vid_pri, + reg[0]); + } + else + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_PRI_EN, 0, reg[0]); + } + + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC1, VLAN_ID, vlan_entry->vid, reg[1]); + + return SW_OK; +} + +static sw_error_t +_dess_vlan_down_to_hw(a_uint32_t dev_id, a_uint32_t reg[]) +{ + sw_error_t rv; + + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_vlan_up_to_sw(a_uint32_t dev_id, a_uint32_t reg[]) +{ + sw_error_t rv; + + HSL_REG_ENTRY_GET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_dess_vlan_commit(a_uint32_t dev_id, a_uint32_t op) +{ + a_uint32_t vt_busy = 1, i = 0x1000, vt_full, val; + sw_error_t rv; + + while (vt_busy && --i) + { + HSL_REG_FIELD_GET(rv, dev_id, VLAN_TABLE_FUNC1, 0, VT_BUSY, + (a_uint8_t *) (&vt_busy), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + aos_udelay(5); + } + + if (i == 0) + return SW_BUSY; + + HSL_REG_ENTRY_GET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC1, VT_FUNC, op, val); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC1, VT_BUSY, 1, val); + + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + vt_busy = 1; + i = 0x1000; + while (vt_busy && --i) + { + HSL_REG_FIELD_GET(rv, dev_id, VLAN_TABLE_FUNC1, 0, VT_BUSY, + (a_uint8_t *) (&vt_busy), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + aos_udelay(5); + } + + if (i == 0) + return SW_FAIL; + + HSL_REG_FIELD_GET(rv, dev_id, VLAN_TABLE_FUNC1, 0, VT_FULL_VIO, + (a_uint8_t *) (&vt_full), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (vt_full) + { + val = 0x10; + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + if (VLAN_LOAD_ENTRY == op) + { + return SW_FULL; + } + else if (VLAN_PURGE_ENTRY == op) + { + return SW_NOT_FOUND; + } + } + + HSL_REG_FIELD_GET(rv, dev_id, VLAN_TABLE_FUNC0, 0, VT_VALID, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (!val) + { + if (VLAN_FIND_ENTRY == op) + return SW_NOT_FOUND; + + if (VLAN_NEXT_ENTRY == op) + return SW_NO_MORE; + } + + return SW_OK; +} + +static sw_error_t +_dess_vlan_hwentry_get(a_uint32_t dev_id, a_uint32_t vlan_id, a_uint32_t reg[]) +{ + sw_error_t rv; + + if (vlan_id > MAX_VLAN_ID) + { + return SW_OUT_OF_RANGE; + } + + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC1, VLAN_ID, vlan_id, reg[1]); + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = _dess_vlan_commit(dev_id, VLAN_FIND_ENTRY); + SW_RTN_ON_ERROR(rv); + + rv = _dess_vlan_up_to_sw(dev_id, reg); + return rv; +} + +static sw_error_t +_dess_vlan_entry_append(a_uint32_t dev_id, const fal_vlan_t * vlan_entry) +{ + sw_error_t rv; + a_uint32_t reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_vlan_sw_to_hw(dev_id, vlan_entry, reg); + SW_RTN_ON_ERROR(rv); + + rv = _dess_vlan_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _dess_vlan_commit(dev_id, VLAN_LOAD_ENTRY); + return rv; +} + +static sw_error_t +_dess_vlan_create(a_uint32_t dev_id, a_uint32_t vlan_id) +{ + sw_error_t rv; + a_uint32_t reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (vlan_id > MAX_VLAN_ID) + { + return SW_OUT_OF_RANGE; + } + + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_VALID, 1, reg[0]); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, IVL_EN, 1, reg[0]); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, LEARN_DIS, 0, reg[0]); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VID_MEM, 0x3fff, reg[0]); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC1, VLAN_ID, vlan_id, reg[1]); + + rv = _dess_vlan_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _dess_vlan_commit(dev_id, VLAN_LOAD_ENTRY); + return rv; +} + +static sw_error_t +_dess_vlan_next(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan) +{ + sw_error_t rv; + a_uint32_t reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_NEXT_ENTRY_FIRST_ID == vlan_id) + { + rv = _dess_vlan_hwentry_get(dev_id, 0, reg); + + if (SW_OK == rv) + { + _dess_vlan_hw_to_sw(reg, p_vlan); + return SW_OK; + } + else + { + vlan_id = 0; + } + } + + if (vlan_id > MAX_VLAN_ID) + return SW_OUT_OF_RANGE; + + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC1, VLAN_ID, vlan_id, reg[1]); + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + rv = _dess_vlan_commit(dev_id, VLAN_NEXT_ENTRY); + SW_RTN_ON_ERROR(rv); + + rv = _dess_vlan_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + _dess_vlan_hw_to_sw(reg, p_vlan); + + if (0 == p_vlan->vid) + { + return SW_NO_MORE; + } + else + { + return SW_OK; + } +} + +static sw_error_t +_dess_vlan_find(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan) +{ + sw_error_t rv; + a_uint32_t reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_vlan_hwentry_get(dev_id, vlan_id, reg); + SW_RTN_ON_ERROR(rv); + + _dess_vlan_hw_to_sw(reg, p_vlan); + return SW_OK; +} + +static sw_error_t +_dess_vlan_delete(a_uint32_t dev_id, a_uint32_t vlan_id) +{ + sw_error_t rv; + a_uint32_t reg; + + HSL_DEV_ID_CHECK(dev_id); + + if (vlan_id > MAX_VLAN_ID) + { + return SW_OUT_OF_RANGE; + } + + reg = (a_int32_t) vlan_id; + HSL_REG_FIELD_SET(rv, dev_id, VLAN_TABLE_FUNC1, 0, VLAN_ID, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = _dess_vlan_commit(dev_id, VLAN_PURGE_ENTRY); + return rv; +} + +static sw_error_t +_dess_vlan_flush(a_uint32_t dev_id) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_vlan_commit(dev_id, VLAN_FLUSH); + return rv; +} + +static sw_error_t +_dess_vlan_fid_set(a_uint32_t dev_id, a_uint32_t vlan_id, a_uint32_t fid) +{ + sw_error_t rv; + a_uint32_t reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + if ((MAX_VLAN_ID < fid) && (FAL_SVL_FID != fid)) + { + return SW_BAD_PARAM; + } + + if ((MAX_VLAN_ID >= fid) && (vlan_id != fid)) + { + return SW_BAD_PARAM; + } + + rv = _dess_vlan_hwentry_get(dev_id, vlan_id, reg); + SW_RTN_ON_ERROR(rv); + + if (FAL_SVL_FID == fid) + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, IVL_EN, 0, reg[0]); + } + else + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, IVL_EN, 1, reg[0]); + } + + rv = _dess_vlan_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _dess_vlan_commit(dev_id, VLAN_LOAD_ENTRY); + if (SW_FULL == rv) + { + rv = SW_OK; + } + return rv; +} + +static sw_error_t +_dess_vlan_fid_get(a_uint32_t dev_id, a_uint32_t vlan_id, a_uint32_t * fid) +{ + sw_error_t rv; + a_uint32_t data, reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_vlan_hwentry_get(dev_id, vlan_id, reg); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC0, IVL_EN, data, reg[0]); + if (data) + { + *fid = vlan_id; + } + else + { + *fid = FAL_SVL_FID; + } + return SW_OK; +} + +static sw_error_t +_dess_vlan_member_update(a_uint32_t dev_id, a_uint32_t vlan_id, + fal_port_t port_id, a_uint32_t port_info) +{ + sw_error_t rv; + a_uint32_t data, reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + rv = _dess_vlan_hwentry_get(dev_id, vlan_id, reg); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC0, VID_MEM, data, reg[0]); + data &= (~(0x3 << (port_id << 1))); + data |= ((port_info & 0x3) << (port_id << 1)); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VID_MEM, data, reg[0]); + + rv = _dess_vlan_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _dess_vlan_commit(dev_id, VLAN_LOAD_ENTRY); + if (SW_FULL == rv) + { + rv = SW_OK; + } + return rv; +} + +static sw_error_t +_dess_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; + a_uint32_t info = 0; + + if (FAL_EG_UNMODIFIED == port_info) + { + info = 0; + } + else if (FAL_EG_TAGGED == port_info) + { + info = 0x2; + } + else if (FAL_EG_UNTAGGED == port_info) + { + info = 0x1; + } + else + { + return SW_BAD_PARAM; + } + + rv = _dess_vlan_member_update(dev_id, vlan_id, port_id, info); + return rv; +} + +static sw_error_t +_dess_vlan_member_del(a_uint32_t dev_id, a_uint32_t vlan_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t info = 0x3; + + rv = _dess_vlan_member_update(dev_id, vlan_id, port_id, info); + return rv; +} + +static sw_error_t +_dess_vlan_learning_state_set(a_uint32_t dev_id, a_uint32_t vlan_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_vlan_hwentry_get(dev_id, vlan_id, reg); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, LEARN_DIS, 0, reg[0]); + } + else if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, LEARN_DIS, 1, reg[0]); + } + else + { + return SW_BAD_PARAM; + } + + rv = _dess_vlan_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _dess_vlan_commit(dev_id, VLAN_LOAD_ENTRY); + if (SW_FULL == rv) + { + rv = SW_OK; + } + return rv; +} + +static sw_error_t +_dess_vlan_learning_state_get(a_uint32_t dev_id, a_uint32_t vlan_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t data, reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _dess_vlan_hwentry_get(dev_id, vlan_id, reg); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC0, LEARN_DIS, data, reg[0]); + if (data) + { + *enable = A_FALSE; + } + else + { + *enable = A_TRUE; + } + return SW_OK; +} + +/** + * @brief Append a vlan entry on paticular device. + * @param[in] dev_id device id + * @param[in] vlan_entry vlan entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_vlan_entry_append(a_uint32_t dev_id, const fal_vlan_t * vlan_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_vlan_entry_append(dev_id, vlan_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Creat a vlan entry through vlan id on a paticular device. + * @details Comments: + * After this operation the member ports of the created vlan entry are null. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_vlan_create(a_uint32_t dev_id, a_uint32_t vlan_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_vlan_create(dev_id, vlan_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Next a vlan entry through vlan id on a paticular device. + * @details Comments: + * If the value of vid is zero this operation will get the first entry. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[out] p_vlan vlan entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_vlan_next(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_vlan_next(dev_id, vlan_id, p_vlan); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Find a vlan entry through vlan id on paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[out] p_vlan vlan entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_vlan_find(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_vlan_find(dev_id, vlan_id, p_vlan); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a vlan entry through vlan id on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_vlan_delete(a_uint32_t dev_id, a_uint32_t vlan_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_vlan_delete(dev_id, vlan_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Flush all vlan entries on a paticular device. + * @param[in] dev_id device id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_vlan_flush(a_uint32_t dev_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_vlan_flush(dev_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set FID of a paticular vlan entry on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[in] fid FDB id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_vlan_fid_set(a_uint32_t dev_id, a_uint32_t vlan_id, a_uint32_t fid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_vlan_fid_set(dev_id, vlan_id, fid); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get FID of a paticular vlan entry on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[out] fid FDB id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_vlan_fid_get(a_uint32_t dev_id, a_uint32_t vlan_id, a_uint32_t * fid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_vlan_fid_get(dev_id, vlan_id, fid); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add a port member to a paticular vlan entry on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[in] port_id port id + * @param[in] port_info port tag information + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_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; + + HSL_API_LOCK; + rv = _dess_vlan_member_add(dev_id, vlan_id, port_id, port_info); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Del a port member from a paticular vlan entry on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[in] port_id port id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_vlan_member_del(a_uint32_t dev_id, a_uint32_t vlan_id, fal_port_t port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_vlan_member_del(dev_id, vlan_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set FDB learning status of a paticular vlan entry on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_vlan_learning_state_set(a_uint32_t dev_id, a_uint32_t vlan_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_vlan_learning_state_set(dev_id, vlan_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get FDB learning status of a paticular vlan entry on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +dess_vlan_learning_state_get(a_uint32_t dev_id, a_uint32_t vlan_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _dess_vlan_learning_state_get(dev_id, vlan_id, enable); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +dess_vlan_init(a_uint32_t dev_id) +{ + hsl_api_t *p_api; + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->vlan_entry_append = dess_vlan_entry_append; + p_api->vlan_creat = dess_vlan_create; + p_api->vlan_delete = dess_vlan_delete; + p_api->vlan_next = dess_vlan_next; + p_api->vlan_find = dess_vlan_find; + p_api->vlan_flush = dess_vlan_flush; + p_api->vlan_fid_set = dess_vlan_fid_set; + p_api->vlan_fid_get = dess_vlan_fid_get; + p_api->vlan_member_add = dess_vlan_member_add; + p_api->vlan_member_del = dess_vlan_member_del; + p_api->vlan_learning_state_set = dess_vlan_learning_state_set; + p_api->vlan_learning_state_get = dess_vlan_learning_state_get; + + +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/Makefile b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/Makefile new file mode 100755 index 000000000..67ebb1247 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/Makefile @@ -0,0 +1,84 @@ +LOC_DIR=src/hsl/garuda +LIB=HSL + +include $(PRJ_PATH)/make/config.mk + +SRC_LIST=garuda_reg_access.c garuda_init.c + +ifeq (TRUE, $(IN_ACL)) + SRC_LIST += garuda_acl.c +endif + +ifeq (TRUE, $(IN_FDB)) + SRC_LIST += garuda_fdb.c +endif + +ifeq (TRUE, $(IN_IGMP)) + SRC_LIST += garuda_igmp.c +endif + +ifeq (TRUE, $(IN_LEAKY)) + SRC_LIST += garuda_leaky.c +endif + +ifeq (TRUE, $(IN_LED)) + SRC_LIST += garuda_led.c +endif + +ifeq (TRUE, $(IN_MIB)) + SRC_LIST += garuda_mib.c +endif + +ifeq (TRUE, $(IN_MIRROR)) + SRC_LIST += garuda_mirror.c +endif + +ifeq (TRUE, $(IN_MISC)) + SRC_LIST += garuda_misc.c +endif + +ifeq (TRUE, $(IN_PORTCONTROL)) + SRC_LIST += garuda_port_ctrl.c +endif + +ifeq (TRUE, $(IN_PORTVLAN)) + SRC_LIST += garuda_portvlan.c +endif + +ifeq (TRUE, $(IN_QOS)) + SRC_LIST += garuda_qos.c +endif + +ifeq (TRUE, $(IN_RATE)) + SRC_LIST += garuda_rate.c +endif + +ifeq (TRUE, $(IN_STP)) + SRC_LIST += garuda_stp.c +endif + +ifeq (TRUE, $(IN_VLAN)) + SRC_LIST += garuda_vlan.c +endif + +ifeq (TRUE, $(IN_REDUCED_ACL)) + SRC_LIST += garuda_reduced_acl.c +endif + +ifeq (linux, $(OS)) + ifeq (KSLIB, $(MODULE_TYPE)) + ifneq (TRUE, $(KERNEL_MODE)) + SRC_LIST=garuda_reg_access.c garuda_init.c + endif + endif +endif + +ifeq (, $(findstring GARUDA, $(SUPPORT_CHIP))) + SRC_LIST= +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/src/src/hsl/garuda/garuda_acl.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_acl.c new file mode 100755 index 000000000..216468fc0 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_acl.c @@ -0,0 +1,3034 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 garuda_acl GARUDA_ACL + * @{ + */ + +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_acl.h" +#include "hsl_port_prop.h" +#include "garuda_acl.h" +#include "garuda_reg.h" + +//#define GARUDA_ACL_DEBUG +//#define GARUDA_SW_ENTRY +//#define GARUDA_ENTRY_DUMP + +typedef struct +{ + a_uint32_t list_id; + a_uint32_t list_pri; + a_uint32_t addr; + a_uint32_t size; + a_uint32_t status; + fal_pbmp_t bind_pts; +} garuda_acl_list_t; + +typedef struct +{ + a_uint32_t slct[8]; + a_uint32_t vlu[5]; + a_uint32_t msk[5]; + a_uint32_t typ; + a_uint32_t act; +} garuda_acl_hw_rule_t; + +static garuda_acl_list_t *list_ent[SW_MAX_NR_DEV]; +static garuda_acl_hw_rule_t *hw_rule_ent; + +static a_uint32_t filter[SW_MAX_NR_DEV]; +static a_uint32_t filter_snap[SW_MAX_NR_DEV]; + +#define GARUDA_MAX_LIST 32 +#define GARUDA_MAX_RULE 32 + +#define ENT_FREE 0x1 +#define ENT_USED 0x2 + +#define GARUDA_RULE_VLU_ADDR 0x58400 +#define GARUDA_RULE_MSK_ADDR 0x58c00 +#define GARUDA_RULE_TYP_ADDR 0x5881c +#define GARUDA_RULE_ACT_ADDR 0x58000 +#define GARUDA_RULE_SLCT_ADDR 0x58800 + +#define GARUDA_MAC_FILTER 1 +#define GARUDA_IP4_FILTER 2 +#define GARUDA_IP6R1_FILTER 3 +#define GARUDA_IP6R2_FILTER 4 +#define GARUDA_IP6R3_FILTER 5 + +#ifdef GARUDA_SW_ENTRY +static char *flt_vlu_mem = NULL; +static char *flt_msk_mem = NULL; +static char *flt_typ_mem = NULL; +static char *act_mem = NULL; +static char *slct_mem = NULL; +#endif + +static a_bool_t _garuda_acl_zero_addr(const fal_mac_addr_t addr); + +static a_bool_t +_garuda_acl_field_care(fal_acl_field_op_t op, a_uint32_t val, a_uint32_t mask, + a_uint32_t chkvlu); + +static sw_error_t +_garuda_acl_list_loc(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t * idx); + +static sw_error_t +_garuda_acl_filter_map_get(const garuda_acl_hw_rule_t * rule, + a_uint32_t flt_idx[], a_uint32_t * flt_nr); + +static sw_error_t +_garuda_acl_rule_mac_parse(fal_acl_rule_t * sw, fal_pbmp_t bind_pts, + garuda_acl_hw_rule_t * hw, a_bool_t * b_care, + a_uint32_t * len); + +static sw_error_t +_garuda_acl_rule_ip4_parse(fal_acl_rule_t * sw, fal_pbmp_t bind_pts, + garuda_acl_hw_rule_t * hw, a_bool_t * b_care, + a_uint32_t * len); + +static sw_error_t +_garuda_acl_rule_ip6r1_parse(fal_acl_rule_t * sw, fal_pbmp_t bind_pts, + garuda_acl_hw_rule_t * hw, a_bool_t * b_care, + a_uint32_t * len); + +static sw_error_t +_garuda_acl_rule_ip6r2_parse(fal_acl_rule_t * sw, fal_pbmp_t bind_pts, + garuda_acl_hw_rule_t * hw, a_bool_t * b_care, + a_uint32_t * len); + +static sw_error_t +_garuda_acl_rule_ip6r3_parse(fal_acl_rule_t * sw, fal_pbmp_t bind_pts, + garuda_acl_hw_rule_t * hw, a_bool_t * b_care, + a_uint32_t * len); + +static sw_error_t +_garuda_acl_action_parse(a_uint32_t dev_id, const fal_acl_rule_t * sw, + garuda_acl_hw_rule_t * hw); + +static sw_error_t +_garuda_acl_rule_mac_reparse(fal_acl_rule_t * sw, + const garuda_acl_hw_rule_t * hw); + +static sw_error_t +_garuda_acl_rule_ip4_reparse(fal_acl_rule_t * sw, + const garuda_acl_hw_rule_t * hw); + +static sw_error_t +_garuda_acl_rule_ip6r1_reparse(fal_acl_rule_t * sw, + const garuda_acl_hw_rule_t * hw); + +static sw_error_t +_garuda_acl_rule_ip6r2_reparse(fal_acl_rule_t * sw, + const garuda_acl_hw_rule_t * hw); + +static sw_error_t +_garuda_acl_rule_ip6r3_reparse(fal_acl_rule_t * sw, + const garuda_acl_hw_rule_t * hw); + +static sw_error_t +_garuda_acl_rule_action_reparse(fal_acl_rule_t * sw, + const garuda_acl_hw_rule_t * hw); + +static sw_error_t +_garuda_acl_filter_alloc(a_uint32_t dev_id, a_uint32_t * idx); + +static void +_garuda_acl_filter_free(a_uint32_t dev_id, a_uint32_t idx); + +static void +_garuda_acl_filter_snap(a_uint32_t dev_id); + +static void +_garuda_acl_filter_commit(a_uint32_t dev_id); + +static sw_error_t +_garuda_acl_slct_update(garuda_acl_hw_rule_t * hw, a_uint32_t offset, + a_uint32_t flt_idx); + +static sw_error_t +_garuda_acl_filter_write(a_uint32_t dev_id, const garuda_acl_hw_rule_t * rule, + a_uint32_t flt_idx); + +static sw_error_t +_garuda_acl_action_write(a_uint32_t dev_id, const garuda_acl_hw_rule_t * rule, + a_uint32_t act_idx); + +static sw_error_t +_garuda_acl_slct_write(a_uint32_t dev_id, const garuda_acl_hw_rule_t * rule, + a_uint32_t slct_idx); + +static sw_error_t +_garuda_acl_filter_read(a_uint32_t dev_id, garuda_acl_hw_rule_t * rule, + a_uint32_t flt_idx); + +static sw_error_t +_garuda_acl_action_read(a_uint32_t dev_id, garuda_acl_hw_rule_t * rule, + a_uint32_t act_idx); + +static sw_error_t +_garuda_acl_slct_read(a_uint32_t dev_id, garuda_acl_hw_rule_t * rule, + a_uint32_t slct_idx); + +static sw_error_t +_garuda_acl_rule_set(a_uint32_t dev_id, a_uint32_t base_addr, + const garuda_acl_hw_rule_t * hw_rule_ent, + a_uint32_t rule_nr); + +static sw_error_t +_garuda_acl_rule_get(a_uint32_t dev_id, garuda_acl_hw_rule_t * rule, + a_uint32_t * ent_idx, a_uint32_t rule_idx); + +static sw_error_t +_garuda_acl_rule_sw_to_hw(a_uint32_t dev_id, fal_acl_rule_t * sw, + fal_pbmp_t bind_pts, garuda_acl_hw_rule_t * hw, + a_uint32_t * idx, a_uint32_t * flt_len); + +static sw_error_t +_garuda_acl_rule_hw_to_sw(fal_acl_rule_t * sw, const garuda_acl_hw_rule_t * hw, + a_uint32_t ent_idx, a_uint32_t ent_nr); + +static sw_error_t +_garuda_acl_rule_copy(a_uint32_t dev_id, a_uint32_t src_slct_idx, + a_uint32_t dst_slct_idx, a_uint32_t size); + +static sw_error_t +_garuda_acl_rule_invalid(a_uint32_t dev_id, a_uint32_t rule_idx, + a_uint32_t size); + +static sw_error_t +_garuda_acl_rule_valid(a_uint32_t dev_id, a_uint32_t rule_idx, a_uint32_t size, + a_uint32_t flag); + +static sw_error_t +_garuda_acl_addr_update(a_uint32_t dev_id, a_uint32_t old_addr, + a_uint32_t new_addr, a_uint32_t list_id); + +static sw_error_t +_garuda_acl_rule_bind(a_uint32_t dev_id, a_uint32_t rule_idx, a_uint32_t ports); + +#ifdef GARUDA_ACL_DEBUG +static void +_garuda_acl_list_dump(a_uint32_t dev_id) +{ + a_uint32_t i; + + aos_printk("\ndev_id=%d list control infomation", dev_id); + for (i = 0; i < GARUDA_MAX_LIST; i++) + { + if (ENT_USED == list_ent[dev_id][i].status) + { + aos_printk("\nlist_id=%d list_pri=%d addr=%d size=%d idx=%d ", + list_ent[dev_id][i].list_id, + list_ent[dev_id][i].list_pri, + list_ent[dev_id][i].addr, list_ent[dev_id][i].size, i); + } + } + aos_printk("\n"); +} +#else +#define _garuda_acl_list_dump(dev_id) +#endif + +static a_bool_t +_garuda_acl_zero_addr(const fal_mac_addr_t addr) +{ + a_uint32_t i; + + for (i = 0; i < 6; i++) + { + if (addr.uc[i]) + { + return A_FALSE; + } + } + return A_TRUE; +} + +static a_bool_t +_garuda_acl_field_care(fal_acl_field_op_t op, a_uint32_t val, a_uint32_t mask, + a_uint32_t chkvlu) +{ + if (FAL_ACL_FIELD_MASK == op) + { + if (0 == mask) + return A_FALSE; + } + else if (FAL_ACL_FIELD_RANGE == op) + { + if ((0 == val) && (chkvlu == mask)) + return A_FALSE; + } + else if (FAL_ACL_FIELD_LE == op) + { + if (chkvlu == val) + return A_FALSE; + } + else if (FAL_ACL_FIELD_GE == op) + { + if (0 == val) + return A_FALSE; + } + else if (FAL_ACL_FIELD_NE == op) + { + return A_TRUE; + } + + return A_TRUE; +} + +static sw_error_t +_garuda_acl_list_loc(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t * idx) +{ + a_uint32_t i; + + for (i = 0; i < GARUDA_MAX_LIST; i++) + { + if ((ENT_USED == list_ent[dev_id][i].status) + && (list_id == list_ent[dev_id][i].list_id)) + { + *idx = i; + return SW_OK; + } + } + return SW_NOT_FOUND; +} + +static sw_error_t +_garuda_acl_filter_map_get(const garuda_acl_hw_rule_t * rule, + a_uint32_t flt_idx[], a_uint32_t * flt_nr) +{ + a_uint32_t flt_en, idx, i = 0; + + SW_GET_FIELD_BY_REG(RUL_SLCT0, ADDR0_EN, flt_en, (rule->slct[0])); + if (flt_en) + { + SW_GET_FIELD_BY_REG(RUL_SLCT1, ADDR0, idx, (rule->slct[1])); + flt_idx[i] = idx; + i++; + } + + SW_GET_FIELD_BY_REG(RUL_SLCT0, ADDR1_EN, flt_en, (rule->slct[0])); + if (flt_en) + { + SW_GET_FIELD_BY_REG(RUL_SLCT2, ADDR1, idx, (rule->slct[2])); + flt_idx[i] = idx; + i++; + } + + SW_GET_FIELD_BY_REG(RUL_SLCT0, ADDR2_EN, flt_en, (rule->slct[0])); + if (flt_en) + { + SW_GET_FIELD_BY_REG(RUL_SLCT3, ADDR2, idx, (rule->slct[3])); + flt_idx[i] = idx; + i++; + } + + SW_GET_FIELD_BY_REG(RUL_SLCT0, ADDR3_EN, flt_en, (rule->slct[0])); + if (flt_en) + { + SW_GET_FIELD_BY_REG(RUL_SLCT4, ADDR3, idx, (rule->slct[4])); + flt_idx[i] = idx; + i++; + } + + *flt_nr = i; + return SW_OK; +} + +static sw_error_t +_garuda_acl_rule_mac_parse(fal_acl_rule_t * sw, fal_pbmp_t bind_pts, + garuda_acl_hw_rule_t * hw, a_bool_t * b_care, + a_uint32_t * len) +{ + a_uint32_t i; + + *b_care = A_FALSE; + *len = 0; + + aos_mem_zero(&(hw->vlu[0]), sizeof (hw->vlu)); + aos_mem_zero(&(hw->msk[0]), sizeof (hw->msk)); + aos_mem_zero(&(hw->typ), sizeof (hw->typ)); + + SW_SET_REG_BY_FIELD(MAC_RUL_V4, MAC_INPT, bind_pts, hw->vlu[4]); + SW_SET_REG_BY_FIELD(RUL_TYPE, TYP, GARUDA_MAC_FILTER, hw->typ); + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_DA)) + { + if (A_TRUE != _garuda_acl_zero_addr(sw->dest_mac_mask)) + { + *b_care = A_TRUE; + *len = 6; + } + + for (i = 0; i < 6; i++) + { + sw->dest_mac_val.uc[i] &= sw->dest_mac_mask.uc[i]; + } + + SW_SET_REG_BY_FIELD(MAC_RUL_V0, DAV_BYTE2, sw->dest_mac_val.uc[2], + hw->vlu[0]); + SW_SET_REG_BY_FIELD(MAC_RUL_V0, DAV_BYTE3, sw->dest_mac_val.uc[3], + hw->vlu[0]); + SW_SET_REG_BY_FIELD(MAC_RUL_V0, DAV_BYTE4, sw->dest_mac_val.uc[4], + hw->vlu[0]); + SW_SET_REG_BY_FIELD(MAC_RUL_V0, DAV_BYTE5, sw->dest_mac_val.uc[5], + hw->vlu[0]); + SW_SET_REG_BY_FIELD(MAC_RUL_V1, DAV_BYTE0, sw->dest_mac_val.uc[0], + hw->vlu[1]); + SW_SET_REG_BY_FIELD(MAC_RUL_V1, DAV_BYTE1, sw->dest_mac_val.uc[1], + hw->vlu[1]); + + SW_SET_REG_BY_FIELD(MAC_RUL_M0, DAM_BYTE2, sw->dest_mac_mask.uc[2], + hw->msk[0]); + SW_SET_REG_BY_FIELD(MAC_RUL_M0, DAM_BYTE3, sw->dest_mac_mask.uc[3], + hw->msk[0]); + SW_SET_REG_BY_FIELD(MAC_RUL_M0, DAM_BYTE4, sw->dest_mac_mask.uc[4], + hw->msk[0]); + SW_SET_REG_BY_FIELD(MAC_RUL_M0, DAM_BYTE5, sw->dest_mac_mask.uc[5], + hw->msk[0]); + SW_SET_REG_BY_FIELD(MAC_RUL_M1, DAM_BYTE0, sw->dest_mac_mask.uc[0], + hw->msk[1]); + SW_SET_REG_BY_FIELD(MAC_RUL_M1, DAM_BYTE1, sw->dest_mac_mask.uc[1], + hw->msk[1]); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_SA)) + { + if (A_TRUE != _garuda_acl_zero_addr(sw->src_mac_mask)) + { + *b_care = A_TRUE; + *len = 12; + } + + for (i = 0; i < 6; i++) + { + sw->src_mac_val.uc[i] &= sw->src_mac_mask.uc[i]; + } + + SW_SET_REG_BY_FIELD(MAC_RUL_V1, SAV_BYTE4, sw->src_mac_val.uc[4], + hw->vlu[1]); + SW_SET_REG_BY_FIELD(MAC_RUL_V1, SAV_BYTE5, sw->src_mac_val.uc[5], + hw->vlu[1]); + SW_SET_REG_BY_FIELD(MAC_RUL_V2, SAV_BYTE0, sw->src_mac_val.uc[0], + hw->vlu[2]); + SW_SET_REG_BY_FIELD(MAC_RUL_V2, SAV_BYTE1, sw->src_mac_val.uc[1], + hw->vlu[2]); + SW_SET_REG_BY_FIELD(MAC_RUL_V2, SAV_BYTE2, sw->src_mac_val.uc[2], + hw->vlu[2]); + SW_SET_REG_BY_FIELD(MAC_RUL_V2, SAV_BYTE3, sw->src_mac_val.uc[3], + hw->vlu[2]); + + SW_SET_REG_BY_FIELD(MAC_RUL_M1, SAM_BYTE4, sw->src_mac_mask.uc[4], + hw->msk[1]); + SW_SET_REG_BY_FIELD(MAC_RUL_M1, SAM_BYTE5, sw->src_mac_mask.uc[5], + hw->msk[1]); + SW_SET_REG_BY_FIELD(MAC_RUL_M2, SAM_BYTE0, sw->src_mac_mask.uc[0], + hw->msk[2]); + SW_SET_REG_BY_FIELD(MAC_RUL_M2, SAM_BYTE1, sw->src_mac_mask.uc[1], + hw->msk[2]); + SW_SET_REG_BY_FIELD(MAC_RUL_M2, SAM_BYTE2, sw->src_mac_mask.uc[2], + hw->msk[2]); + SW_SET_REG_BY_FIELD(MAC_RUL_M2, SAM_BYTE3, sw->src_mac_mask.uc[3], + hw->msk[2]); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_ETHTYPE)) + { + if (0x0 != sw->ethtype_mask) + { + *b_care = A_TRUE; + *len = 14; + } + + sw->ethtype_val &= sw->ethtype_mask; + SW_SET_REG_BY_FIELD(MAC_RUL_V3, ETHTYPV, sw->ethtype_val, hw->vlu[3]); + SW_SET_REG_BY_FIELD(MAC_RUL_M3, ETHTYPM, sw->ethtype_mask, hw->msk[3]); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_TAGGED)) + { + if (0x0 != sw->tagged_mask) + { + *b_care = A_TRUE; + } + + sw->tagged_val &= sw->tagged_mask; + SW_SET_REG_BY_FIELD(MAC_RUL_V4, TAGGEDV, sw->tagged_val, hw->vlu[4]); + SW_SET_REG_BY_FIELD(MAC_RUL_V4, TAGGEDM, sw->tagged_mask, hw->vlu[4]); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_UP)) + { + if (0x0 != sw->up_mask) + { + *b_care = A_TRUE; + } + + sw->up_val &= sw->up_mask; + SW_SET_REG_BY_FIELD(MAC_RUL_V3, VLANPRIV, sw->up_val, hw->vlu[3]); + SW_SET_REG_BY_FIELD(MAC_RUL_M3, VLANPRIM, sw->up_mask, hw->msk[3]); + } + + SW_SET_REG_BY_FIELD(MAC_RUL_M3, VIDMSK, 1, hw->msk[3]); + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_VID)) + { + if ((FAL_ACL_FIELD_MASK != sw->vid_op) + && (FAL_ACL_FIELD_RANGE != sw->vid_op) + && (FAL_ACL_FIELD_LE != sw->vid_op) + && (FAL_ACL_FIELD_GE != sw->vid_op)) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == + _garuda_acl_field_care(sw->vid_op, sw->vid_val, sw->vid_mask, + 0xfff)) + { + *b_care = A_TRUE; + } + + SW_SET_REG_BY_FIELD(MAC_RUL_M3, VIDMSK, 0, hw->msk[3]); + if (FAL_ACL_FIELD_MASK == sw->vid_op) + { + sw->vid_val &= sw->vid_mask; + SW_SET_REG_BY_FIELD(MAC_RUL_V3, VLANIDV, sw->vid_val, hw->vlu[3]); + SW_SET_REG_BY_FIELD(MAC_RUL_M3, VLANIDM, sw->vid_mask, hw->msk[3]); + SW_SET_REG_BY_FIELD(MAC_RUL_M3, VIDMSK, 1, hw->msk[3]); + } + else if (FAL_ACL_FIELD_RANGE == sw->vid_op) + { + SW_SET_REG_BY_FIELD(MAC_RUL_V3, VLANIDV, sw->vid_val, hw->vlu[3]); + SW_SET_REG_BY_FIELD(MAC_RUL_M3, VLANIDM, sw->vid_mask, hw->msk[3]); + } + else if (FAL_ACL_FIELD_LE == sw->vid_op) + { + SW_SET_REG_BY_FIELD(MAC_RUL_V3, VLANIDV, 0, hw->vlu[3]); + SW_SET_REG_BY_FIELD(MAC_RUL_M3, VLANIDM, sw->vid_val, hw->msk[3]); + } + else + { + SW_SET_REG_BY_FIELD(MAC_RUL_V3, VLANIDV, sw->vid_val, hw->vlu[3]); + SW_SET_REG_BY_FIELD(MAC_RUL_M3, VLANIDM, 0xfff, hw->msk[3]); + } + } + + return SW_OK; +} + +static sw_error_t +_garuda_acl_rule_ip4_parse(fal_acl_rule_t * sw, fal_pbmp_t bind_pts, + garuda_acl_hw_rule_t * hw, a_bool_t * b_care, + a_uint32_t * len) +{ + *b_care = A_FALSE; + *len = 0; + + aos_mem_zero(&(hw->vlu[0]), sizeof (hw->vlu)); + aos_mem_zero(&(hw->msk[0]), sizeof (hw->msk)); + aos_mem_zero(&(hw->typ), sizeof (hw->typ)); + + SW_SET_REG_BY_FIELD(IP4_RUL_V4, IP4_INPT, bind_pts, hw->vlu[4]); + SW_SET_REG_BY_FIELD(RUL_TYPE, TYP, GARUDA_IP4_FILTER, hw->typ); + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP_DSCP)) + { + if (0x0 != sw->ip_dscp_mask) + { + *b_care = A_TRUE; + *len = 16; + } + + sw->ip_dscp_val &= sw->ip_dscp_mask; + SW_SET_REG_BY_FIELD(IP4_RUL_V2, IP4DSCPV, sw->ip_dscp_val, hw->vlu[2]); + SW_SET_REG_BY_FIELD(IP4_RUL_M2, IP4DSCPM, sw->ip_dscp_mask, hw->msk[2]); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP_PROTO)) + { + if (0x0 != sw->ip_proto_mask) + { + *b_care = A_TRUE; + *len = 24; + } + + sw->ip_proto_val &= sw->ip_proto_mask; + SW_SET_REG_BY_FIELD(IP4_RUL_V2, IP4PROTV, sw->ip_proto_val, hw->vlu[2]); + SW_SET_REG_BY_FIELD(IP4_RUL_M2, IP4PROTM, sw->ip_proto_mask, + hw->msk[2]); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP4_SIP)) + { + if (0x0 != sw->src_ip4_mask) + { + *b_care = A_TRUE; + *len = 30; + } + sw->src_ip4_val &= sw->src_ip4_mask; + hw->vlu[1] = sw->src_ip4_val; + hw->msk[1] = sw->src_ip4_mask; + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP4_DIP)) + { + if (0x0 != sw->dest_ip4_mask) + { + *b_care = A_TRUE; + *len = 34; + } + sw->dest_ip4_val &= sw->dest_ip4_mask; + hw->vlu[0] = sw->dest_ip4_val; + hw->msk[0] = sw->dest_ip4_mask; + } + + SW_SET_REG_BY_FIELD(IP4_RUL_M3, IP4SPORTM_EN, 1, hw->msk[3]); + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_L4_SPORT)) + { + if ((FAL_ACL_FIELD_MASK != sw->src_l4port_op) + && (FAL_ACL_FIELD_RANGE != sw->src_l4port_op) + && (FAL_ACL_FIELD_LE != sw->src_l4port_op) + && (FAL_ACL_FIELD_GE != sw->src_l4port_op)) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == + _garuda_acl_field_care(sw->src_l4port_op, sw->src_l4port_val, + sw->src_l4port_mask, 0xffff)) + { + *b_care = A_TRUE; + *len = 36; + } + + SW_SET_REG_BY_FIELD(IP4_RUL_M3, IP4SPORTM_EN, 0, hw->msk[3]); + if (FAL_ACL_FIELD_MASK == sw->src_l4port_op) + { + sw->src_l4port_val &= sw->src_l4port_mask; + SW_SET_REG_BY_FIELD(IP4_RUL_V3, IP4SPORTV, sw->src_l4port_val, + hw->vlu[3]); + SW_SET_REG_BY_FIELD(IP4_RUL_M3, IP4SPORTM, sw->src_l4port_mask, + hw->msk[3]); + SW_SET_REG_BY_FIELD(IP4_RUL_M3, IP4SPORTM_EN, 1, hw->msk[3]); + } + else if (FAL_ACL_FIELD_RANGE == sw->src_l4port_op) + { + SW_SET_REG_BY_FIELD(IP4_RUL_V3, IP4SPORTV, sw->src_l4port_val, + hw->vlu[3]); + SW_SET_REG_BY_FIELD(IP4_RUL_M3, IP4SPORTM, sw->src_l4port_mask, + hw->msk[3]); + } + else if (FAL_ACL_FIELD_LE == sw->src_l4port_op) + { + SW_SET_REG_BY_FIELD(IP4_RUL_V3, IP4SPORTV, 0, hw->vlu[3]); + SW_SET_REG_BY_FIELD(IP4_RUL_M3, IP4SPORTM, sw->src_l4port_val, + hw->msk[3]); + } + else + { + SW_SET_REG_BY_FIELD(IP4_RUL_V3, IP4SPORTV, sw->src_l4port_val, + hw->vlu[3]); + SW_SET_REG_BY_FIELD(IP4_RUL_M3, IP4SPORTM, 0xffff, hw->msk[3]); + } + } + + SW_SET_REG_BY_FIELD(IP4_RUL_M3, IP4DPORTM_EN, 1, hw->msk[3]); + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_L4_DPORT)) + { + if ((FAL_ACL_FIELD_MASK != sw->dest_l4port_op) + && (FAL_ACL_FIELD_RANGE != sw->dest_l4port_op) + && (FAL_ACL_FIELD_LE != sw->dest_l4port_op) + && (FAL_ACL_FIELD_GE != sw->dest_l4port_op)) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == + _garuda_acl_field_care(sw->dest_l4port_op, sw->dest_l4port_val, + sw->dest_l4port_mask, 0xffff)) + { + *b_care = A_TRUE; + *len = 38; + } + + SW_SET_REG_BY_FIELD(IP4_RUL_M3, IP4DPORTM_EN, 0, hw->msk[3]); + if (FAL_ACL_FIELD_MASK == sw->dest_l4port_op) + { + sw->dest_l4port_val &= sw->dest_l4port_mask; + SW_SET_REG_BY_FIELD(IP4_RUL_V2, IP4DPORTV, sw->dest_l4port_val, + hw->vlu[2]); + SW_SET_REG_BY_FIELD(IP4_RUL_M2, IP4DPORTM, sw->dest_l4port_mask, + hw->msk[2]); + SW_SET_REG_BY_FIELD(IP4_RUL_M3, IP4DPORTM_EN, 1, hw->msk[3]); + } + else if (FAL_ACL_FIELD_RANGE == sw->dest_l4port_op) + { + SW_SET_REG_BY_FIELD(IP4_RUL_V2, IP4DPORTV, sw->dest_l4port_val, + hw->vlu[2]); + SW_SET_REG_BY_FIELD(IP4_RUL_M2, IP4DPORTM, sw->dest_l4port_mask, + hw->msk[2]); + } + else if (FAL_ACL_FIELD_LE == sw->dest_l4port_op) + { + SW_SET_REG_BY_FIELD(IP4_RUL_V2, IP4DPORTV, 0, hw->vlu[2]); + SW_SET_REG_BY_FIELD(IP4_RUL_M2, IP4DPORTM, sw->dest_l4port_val, + hw->msk[2]); + } + else + { + SW_SET_REG_BY_FIELD(IP4_RUL_V2, IP4DPORTV, sw->dest_l4port_val, + hw->vlu[2]); + SW_SET_REG_BY_FIELD(IP4_RUL_M2, IP4DPORTM, 0xffff, hw->msk[2]); + } + } + + return SW_OK; +} + +static sw_error_t +_garuda_acl_rule_ip6r1_parse(fal_acl_rule_t * sw, fal_pbmp_t bind_pts, + garuda_acl_hw_rule_t * hw, a_bool_t * b_care, + a_uint32_t * len) +{ + a_uint32_t i; + + *b_care = A_FALSE; + *len = 0; + + aos_mem_zero(&(hw->vlu[0]), sizeof (hw->vlu)); + aos_mem_zero(&(hw->msk[0]), sizeof (hw->msk)); + aos_mem_zero(&(hw->typ), sizeof (hw->typ)); + + SW_SET_REG_BY_FIELD(IP6_RUL1_V4, IP6_RUL1_INPT, bind_pts, hw->vlu[4]); + SW_SET_REG_BY_FIELD(RUL_TYPE, TYP, GARUDA_IP6R1_FILTER, hw->typ); + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP6_DIP)) + { + for (i = 0; i < 4; i++) + { + if (0x0 != sw->dest_ip6_mask.ul[i]) + { + *b_care = A_TRUE; + *len = 54; + } + + sw->dest_ip6_val.ul[3 - i] &= sw->dest_ip6_mask.ul[3 - i]; + hw->vlu[i] = sw->dest_ip6_val.ul[3 - i]; + hw->msk[i] = sw->dest_ip6_mask.ul[3 - i]; + } + } + + return SW_OK; +} + +static sw_error_t +_garuda_acl_rule_ip6r2_parse(fal_acl_rule_t * sw, fal_pbmp_t bind_pts, + garuda_acl_hw_rule_t * hw, a_bool_t * b_care, + a_uint32_t * len) +{ + a_uint32_t i; + + *b_care = A_FALSE; + *len = 0; + + aos_mem_zero(&(hw->vlu[0]), sizeof (hw->vlu)); + aos_mem_zero(&(hw->msk[0]), sizeof (hw->msk)); + aos_mem_zero(&(hw->typ), sizeof (hw->typ)); + + SW_SET_REG_BY_FIELD(IP6_RUL2_V4, IP6_RUL2_INPT, bind_pts, hw->vlu[4]); + SW_SET_REG_BY_FIELD(RUL_TYPE, TYP, GARUDA_IP6R2_FILTER, hw->typ); + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP6_SIP)) + { + for (i = 0; i < 4; i++) + { + if (0x0 != sw->src_ip6_mask.ul[i]) + { + *b_care = A_TRUE; + *len = 38; + } + + sw->src_ip6_val.ul[3 - i] &= sw->src_ip6_mask.ul[3 - i]; + hw->vlu[i] = sw->src_ip6_val.ul[3 - i]; + hw->msk[i] = sw->src_ip6_mask.ul[3 - i]; + } + } + + return SW_OK; +} + +static sw_error_t +_garuda_acl_rule_ip6r3_parse(fal_acl_rule_t * sw, fal_pbmp_t bind_pts, + garuda_acl_hw_rule_t * hw, a_bool_t * b_care, + a_uint32_t * len) +{ + *b_care = A_FALSE; + *len = 0; + + aos_mem_zero(&(hw->vlu[0]), sizeof (hw->vlu)); + aos_mem_zero(&(hw->msk[0]), sizeof (hw->msk)); + aos_mem_zero(&(hw->typ), sizeof (hw->typ)); + + SW_SET_REG_BY_FIELD(IP6_RUL3_V4, IP6_RUL3_INPT, bind_pts, hw->vlu[4]); + SW_SET_REG_BY_FIELD(RUL_TYPE, TYP, GARUDA_IP6R3_FILTER, hw->typ); + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP_DSCP)) + { + if (0x0 != sw->ip_dscp_mask) + { + *b_care = A_TRUE; + *len = 38; + } + + sw->ip_dscp_val &= sw->ip_dscp_mask; + SW_SET_REG_BY_FIELD(IP6_RUL3_V0, IP6DSCPV, sw->ip_dscp_val, hw->vlu[0]); + SW_SET_REG_BY_FIELD(IP6_RUL3_M0, IP6DSCPM, sw->ip_dscp_mask, + hw->msk[0]); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP6_LABEL)) + { + if (0x0 != sw->ip6_lable_mask) + { + *b_care = A_TRUE; + *len = 18; + } + + sw->ip6_lable_val &= sw->ip6_lable_mask; + SW_SET_REG_BY_FIELD(IP6_RUL3_V1, IP6LABEL1V, sw->ip6_lable_val, + hw->vlu[1]); + SW_SET_REG_BY_FIELD(IP6_RUL3_M1, IP6LABEL1M, sw->ip6_lable_mask, + hw->msk[1]); + + SW_SET_REG_BY_FIELD(IP6_RUL3_V2, IP6LABEL2V, (sw->ip6_lable_val >> 16), + hw->vlu[2]); + SW_SET_REG_BY_FIELD(IP6_RUL3_M2, IP6LABEL2M, (sw->ip6_lable_mask >> 16), + hw->msk[2]); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP_PROTO)) + { + if (0x0 != sw->ip_proto_mask) + { + *b_care = A_TRUE; + *len = 21; + } + + sw->ip_proto_val &= sw->ip_proto_mask; + SW_SET_REG_BY_FIELD(IP6_RUL3_V0, IP6PROTV, sw->ip_proto_val, + hw->vlu[0]); + SW_SET_REG_BY_FIELD(IP6_RUL3_M0, IP6PROTM, sw->ip_proto_mask, + hw->msk[0]); + } + + SW_SET_REG_BY_FIELD(IP6_RUL3_M3, IP6SPORTM_EN, 1, hw->msk[3]); + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_L4_SPORT)) + { + if ((FAL_ACL_FIELD_MASK != sw->src_l4port_op) + && (FAL_ACL_FIELD_RANGE != sw->src_l4port_op) + && (FAL_ACL_FIELD_LE != sw->src_l4port_op) + && (FAL_ACL_FIELD_GE != sw->src_l4port_op)) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == + _garuda_acl_field_care(sw->src_l4port_op, sw->src_l4port_val, + sw->src_l4port_mask, 0xffff)) + { + *b_care = A_TRUE; + *len = 56; + } + + SW_SET_REG_BY_FIELD(IP6_RUL3_M3, IP6SPORTM_EN, 0, hw->msk[3]); + if (FAL_ACL_FIELD_MASK == sw->src_l4port_op) + { + sw->src_l4port_val &= sw->src_l4port_mask; + SW_SET_REG_BY_FIELD(IP6_RUL3_V1, IP6SPORTV, sw->src_l4port_val, + hw->vlu[1]); + SW_SET_REG_BY_FIELD(IP6_RUL3_M1, IP6SPORTM, sw->src_l4port_mask, + hw->msk[1]); + SW_SET_REG_BY_FIELD(IP6_RUL3_M3, IP6SPORTM_EN, 1, hw->msk[3]); + } + else if (FAL_ACL_FIELD_RANGE == sw->src_l4port_op) + { + SW_SET_REG_BY_FIELD(IP6_RUL3_V1, IP6SPORTV, sw->src_l4port_val, + hw->vlu[1]); + SW_SET_REG_BY_FIELD(IP6_RUL3_M1, IP6SPORTM, sw->src_l4port_mask, + hw->msk[1]); + } + else if (FAL_ACL_FIELD_LE == sw->src_l4port_op) + { + SW_SET_REG_BY_FIELD(IP6_RUL3_V1, IP6SPORTV, 0, hw->vlu[1]); + SW_SET_REG_BY_FIELD(IP6_RUL3_M1, IP6SPORTM, sw->src_l4port_val, + hw->msk[1]); + } + else + { + SW_SET_REG_BY_FIELD(IP6_RUL3_V1, IP6SPORTV, sw->src_l4port_val, + hw->vlu[1]); + SW_SET_REG_BY_FIELD(IP6_RUL3_M1, IP6SPORTM, 0xffff, hw->msk[1]); + } + } + + SW_SET_REG_BY_FIELD(IP6_RUL3_M3, IP6DPORTM_EN, 1, hw->msk[3]); + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_L4_DPORT)) + { + if ((FAL_ACL_FIELD_MASK != sw->dest_l4port_op) + && (FAL_ACL_FIELD_RANGE != sw->dest_l4port_op) + && (FAL_ACL_FIELD_LE != sw->dest_l4port_op) + && (FAL_ACL_FIELD_GE != sw->dest_l4port_op)) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == + _garuda_acl_field_care(sw->dest_l4port_op, sw->dest_l4port_val, + sw->dest_l4port_mask, 0xffff)) + { + *b_care = A_TRUE; + *len = 58; + } + + SW_SET_REG_BY_FIELD(IP6_RUL3_M3, IP6DPORTM_EN, 0, hw->msk[3]); + if (FAL_ACL_FIELD_MASK == sw->dest_l4port_op) + { + sw->dest_l4port_val &= sw->dest_l4port_mask; + SW_SET_REG_BY_FIELD(IP6_RUL3_V0, IP6DPORTV, sw->dest_l4port_val, + hw->vlu[0]); + SW_SET_REG_BY_FIELD(IP6_RUL3_M0, IP6DPORTM, sw->dest_l4port_mask, + hw->msk[0]); + SW_SET_REG_BY_FIELD(IP6_RUL3_M3, IP6DPORTM_EN, 1, hw->msk[3]); + } + else if (FAL_ACL_FIELD_RANGE == sw->dest_l4port_op) + { + SW_SET_REG_BY_FIELD(IP6_RUL3_V0, IP6DPORTV, sw->dest_l4port_val, + hw->vlu[0]); + SW_SET_REG_BY_FIELD(IP6_RUL3_M0, IP6DPORTM, sw->dest_l4port_mask, + hw->msk[0]); + } + else if (FAL_ACL_FIELD_LE == sw->dest_l4port_op) + { + SW_SET_REG_BY_FIELD(IP6_RUL3_V0, IP6DPORTV, 0, hw->vlu[0]); + SW_SET_REG_BY_FIELD(IP6_RUL3_M0, IP6DPORTM, sw->dest_l4port_val, + hw->msk[0]); + } + else + { + SW_SET_REG_BY_FIELD(IP6_RUL3_V0, IP6DPORTV, sw->dest_l4port_val, + hw->vlu[0]); + SW_SET_REG_BY_FIELD(IP6_RUL3_M0, IP6DPORTM, 0xffff, hw->msk[0]); + } + } + + return SW_OK; +} + +static sw_error_t +_garuda_acl_action_parse(a_uint32_t dev_id, const fal_acl_rule_t * sw, + garuda_acl_hw_rule_t * hw) +{ + hw->act = 0; + if ((FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_MODIFY_VLAN)) + && (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_NEST_VLAN))) + { + return SW_NOT_SUPPORTED; + } + + /* FAL_ACL_ACTION_PERMIT need't process */ + + /* we should ignore any other action flags when DENY bit is settd. */ + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_DENY)) + { + SW_SET_REG_BY_FIELD(ACL_RSLT, DES_PORT_EN, 1, hw->act); + SW_SET_REG_BY_FIELD(ACL_RSLT, PORT_MEM, 0, hw->act); + return SW_OK; + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_RDTCPU)) + { + SW_SET_REG_BY_FIELD(ACL_RSLT, RDTCPU, 1, hw->act); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_CPYCPU)) + { + SW_SET_REG_BY_FIELD(ACL_RSLT, CPYCPU, 1, hw->act); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_MIRROR)) + { + SW_SET_REG_BY_FIELD(ACL_RSLT, MIRR_EN, 1, hw->act); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REDPT)) + { + SW_SET_REG_BY_FIELD(ACL_RSLT, DES_PORT_EN, 1, hw->act); + SW_SET_REG_BY_FIELD(ACL_RSLT, PORT_MEM, sw->ports, hw->act); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REMARK_UP)) + { + SW_SET_REG_BY_FIELD(ACL_RSLT, REMARK_DOT1P, 1, hw->act); + SW_SET_REG_BY_FIELD(ACL_RSLT, DOT1P, sw->up, hw->act); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REMARK_QUEUE)) + { + SW_SET_REG_BY_FIELD(ACL_RSLT, REMARK_PRI_QU, 1, hw->act); + SW_SET_REG_BY_FIELD(ACL_RSLT, PRI_QU, sw->queue, hw->act); + } + + if ((FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_MODIFY_VLAN)) + || (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_NEST_VLAN))) + { + + SW_SET_REG_BY_FIELD(ACL_RSLT, CHG_VID_EN, 1, hw->act); + SW_SET_REG_BY_FIELD(ACL_RSLT, VID, sw->vid, hw->act); + SW_SET_REG_BY_FIELD(ACL_RSLT, STAG_CHG_EN, 1, hw->act); + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_MODIFY_VLAN)) + { + SW_SET_REG_BY_FIELD(ACL_RSLT, STAG_CHG_EN, 0, hw->act); + + if (!FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REDPT)) + { + SW_SET_REG_BY_FIELD(ACL_RSLT, VID_MEM_EN, 1, hw->act); + SW_SET_REG_BY_FIELD(ACL_RSLT, PORT_MEM, sw->ports, hw->act); + } + } + } + + return SW_OK; +} + +static sw_error_t +_garuda_acl_rule_mac_reparse(fal_acl_rule_t * sw, + const garuda_acl_hw_rule_t * hw) +{ + a_uint32_t mask_en; + + /* destnation mac address */ + SW_GET_FIELD_BY_REG(MAC_RUL_V0, DAV_BYTE2, sw->dest_mac_val.uc[2], + hw->vlu[0]); + SW_GET_FIELD_BY_REG(MAC_RUL_V0, DAV_BYTE3, sw->dest_mac_val.uc[3], + hw->vlu[0]); + SW_GET_FIELD_BY_REG(MAC_RUL_V0, DAV_BYTE4, sw->dest_mac_val.uc[4], + hw->vlu[0]); + SW_GET_FIELD_BY_REG(MAC_RUL_V0, DAV_BYTE5, sw->dest_mac_val.uc[5], + hw->vlu[0]); + SW_GET_FIELD_BY_REG(MAC_RUL_V1, DAV_BYTE0, sw->dest_mac_val.uc[0], + hw->vlu[1]); + SW_GET_FIELD_BY_REG(MAC_RUL_V1, DAV_BYTE1, sw->dest_mac_val.uc[1], + hw->vlu[1]); + + SW_GET_FIELD_BY_REG(MAC_RUL_M0, DAM_BYTE2, sw->dest_mac_mask.uc[2], + hw->msk[0]); + SW_GET_FIELD_BY_REG(MAC_RUL_M0, DAM_BYTE3, sw->dest_mac_mask.uc[3], + hw->msk[0]); + SW_GET_FIELD_BY_REG(MAC_RUL_M0, DAM_BYTE4, sw->dest_mac_mask.uc[4], + hw->msk[0]); + SW_GET_FIELD_BY_REG(MAC_RUL_M0, DAM_BYTE5, sw->dest_mac_mask.uc[5], + hw->msk[0]); + SW_GET_FIELD_BY_REG(MAC_RUL_M1, DAM_BYTE0, sw->dest_mac_mask.uc[0], + hw->msk[1]); + SW_GET_FIELD_BY_REG(MAC_RUL_M1, DAM_BYTE1, sw->dest_mac_mask.uc[1], + hw->msk[1]); + if (A_FALSE == _garuda_acl_zero_addr(sw->dest_mac_mask)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_DA); + } + + /* source mac address */ + SW_GET_FIELD_BY_REG(MAC_RUL_V2, SAV_BYTE0, sw->src_mac_val.uc[0], + hw->vlu[2]); + SW_GET_FIELD_BY_REG(MAC_RUL_V2, SAV_BYTE1, sw->src_mac_val.uc[1], + hw->vlu[2]); + SW_GET_FIELD_BY_REG(MAC_RUL_V2, SAV_BYTE2, sw->src_mac_val.uc[2], + hw->vlu[2]); + SW_GET_FIELD_BY_REG(MAC_RUL_V2, SAV_BYTE3, sw->src_mac_val.uc[3], + hw->vlu[2]); + SW_GET_FIELD_BY_REG(MAC_RUL_V1, SAV_BYTE4, sw->src_mac_val.uc[4], + hw->vlu[1]); + SW_GET_FIELD_BY_REG(MAC_RUL_V1, SAV_BYTE5, sw->src_mac_val.uc[5], + hw->vlu[1]); + + SW_GET_FIELD_BY_REG(MAC_RUL_M2, SAM_BYTE0, sw->src_mac_mask.uc[0], + hw->msk[2]); + SW_GET_FIELD_BY_REG(MAC_RUL_M2, SAM_BYTE1, sw->src_mac_mask.uc[1], + hw->msk[2]); + SW_GET_FIELD_BY_REG(MAC_RUL_M2, SAM_BYTE2, sw->src_mac_mask.uc[2], + hw->msk[2]); + SW_GET_FIELD_BY_REG(MAC_RUL_M2, SAM_BYTE3, sw->src_mac_mask.uc[3], + hw->msk[2]); + SW_GET_FIELD_BY_REG(MAC_RUL_M1, SAM_BYTE4, sw->src_mac_mask.uc[4], + hw->msk[1]); + SW_GET_FIELD_BY_REG(MAC_RUL_M1, SAM_BYTE5, sw->src_mac_mask.uc[5], + hw->msk[1]); + if (A_FALSE == _garuda_acl_zero_addr(sw->src_mac_mask)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_SA); + } + + /* ethernet type */ + SW_GET_FIELD_BY_REG(MAC_RUL_V3, ETHTYPV, sw->ethtype_val, hw->vlu[3]); + SW_GET_FIELD_BY_REG(MAC_RUL_M3, ETHTYPM, sw->ethtype_mask, hw->msk[3]); + if (0x0 != sw->ethtype_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_ETHTYPE); + } + + /* packet tagged */ + SW_GET_FIELD_BY_REG(MAC_RUL_V4, TAGGEDV, sw->tagged_val, hw->vlu[4]); + SW_GET_FIELD_BY_REG(MAC_RUL_V4, TAGGEDM, sw->tagged_mask, hw->vlu[4]); + if (0x0 != sw->tagged_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_TAGGED); + } + + /* vlan priority */ + SW_GET_FIELD_BY_REG(MAC_RUL_V3, VLANPRIV, sw->up_val, hw->vlu[3]); + SW_GET_FIELD_BY_REG(MAC_RUL_M3, VLANPRIM, sw->up_mask, hw->msk[3]); + if (0x0 != sw->up_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_UP); + } + + /* vlanid */ + SW_GET_FIELD_BY_REG(MAC_RUL_V3, VLANIDV, sw->vid_val, hw->vlu[3]); + SW_GET_FIELD_BY_REG(MAC_RUL_M3, VLANIDM, sw->vid_mask, hw->msk[3]); + SW_GET_FIELD_BY_REG(MAC_RUL_M3, VIDMSK, mask_en, hw->msk[3]); + if (mask_en) + { + sw->vid_op = FAL_ACL_FIELD_MASK; + } + else + { + sw->vid_op = FAL_ACL_FIELD_RANGE; + } + + if (A_TRUE == + _garuda_acl_field_care(sw->vid_op, (a_uint32_t) sw->vid_val, + (a_uint32_t) sw->vid_mask, 0xfff)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_VID); + } + + return SW_OK; +} + +static sw_error_t +_garuda_acl_rule_ip4_reparse(fal_acl_rule_t * sw, + const garuda_acl_hw_rule_t * hw) +{ + a_uint32_t mask_en; + + sw->dest_ip4_val = hw->vlu[0]; + sw->dest_ip4_mask = hw->msk[0]; + if (0x0 != sw->dest_ip4_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP4_DIP); + } + + sw->src_ip4_val = hw->vlu[1]; + sw->src_ip4_mask = hw->msk[1]; + if (0x0 != sw->src_ip4_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP4_SIP); + } + + SW_GET_FIELD_BY_REG(IP4_RUL_V2, IP4PROTV, sw->ip_proto_val, hw->vlu[2]); + SW_GET_FIELD_BY_REG(IP4_RUL_M2, IP4PROTM, sw->ip_proto_mask, hw->msk[2]); + if (0x0 != sw->ip_proto_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP_PROTO); + } + + SW_GET_FIELD_BY_REG(IP4_RUL_V2, IP4DSCPV, sw->ip_dscp_val, hw->vlu[2]); + SW_GET_FIELD_BY_REG(IP4_RUL_M2, IP4DSCPM, sw->ip_dscp_mask, hw->msk[2]); + if (0x0 != sw->ip_dscp_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP_DSCP); + } + + SW_GET_FIELD_BY_REG(IP4_RUL_V2, IP4DPORTV, sw->dest_l4port_val, hw->vlu[2]); + SW_GET_FIELD_BY_REG(IP4_RUL_M2, IP4DPORTM, sw->dest_l4port_mask, + hw->msk[2]); + SW_GET_FIELD_BY_REG(IP4_RUL_M3, IP4DPORTM_EN, mask_en, hw->msk[3]); + if (mask_en) + { + sw->dest_l4port_op = FAL_ACL_FIELD_MASK; + } + else + { + sw->dest_l4port_op = FAL_ACL_FIELD_RANGE; + } + + if (A_TRUE == + _garuda_acl_field_care(sw->dest_l4port_op, + (a_uint32_t) sw->dest_l4port_val, + (a_uint32_t) sw->dest_l4port_mask, 0xffff)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_DPORT); + } + + SW_GET_FIELD_BY_REG(IP4_RUL_V3, IP4SPORTV, sw->src_l4port_val, hw->vlu[3]); + SW_GET_FIELD_BY_REG(IP4_RUL_M3, IP4SPORTM, sw->src_l4port_mask, hw->msk[3]); + SW_GET_FIELD_BY_REG(IP4_RUL_M3, IP4SPORTM_EN, mask_en, hw->msk[3]); + if (mask_en) + { + sw->src_l4port_op = FAL_ACL_FIELD_MASK; + } + else + { + sw->src_l4port_op = FAL_ACL_FIELD_RANGE; + } + + if (A_TRUE == + _garuda_acl_field_care(sw->src_l4port_op, + (a_uint32_t) sw->src_l4port_val, + (a_uint32_t) sw->src_l4port_mask, 0xffff)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_SPORT); + } + + return SW_OK; +} + +static sw_error_t +_garuda_acl_rule_ip6r1_reparse(fal_acl_rule_t * sw, + const garuda_acl_hw_rule_t * hw) +{ + a_uint32_t i; + + for (i = 0; i < 4; i++) + { + sw->dest_ip6_val.ul[i] = hw->vlu[3 - i]; + sw->dest_ip6_mask.ul[i] = hw->msk[3 - i]; + if (0x0 != sw->dest_ip6_mask.ul[i]) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP6_DIP); + } + } + return SW_OK; +} + +static sw_error_t +_garuda_acl_rule_ip6r2_reparse(fal_acl_rule_t * sw, + const garuda_acl_hw_rule_t * hw) +{ + a_uint32_t i; + + for (i = 0; i < 4; i++) + { + sw->src_ip6_val.ul[i] = hw->vlu[3 - i]; + sw->src_ip6_mask.ul[i] = hw->msk[3 - i]; + if (0x0 != sw->src_ip6_mask.ul[i]) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP6_SIP); + } + } + return SW_OK; +} + +static sw_error_t +_garuda_acl_rule_ip6r3_reparse(fal_acl_rule_t * sw, + const garuda_acl_hw_rule_t * hw) +{ + a_uint32_t mask_en; + a_uint32_t tmp; + + SW_GET_FIELD_BY_REG(IP6_RUL3_V0, IP6PROTV, sw->ip_proto_val, hw->vlu[0]); + SW_GET_FIELD_BY_REG(IP6_RUL3_M0, IP6PROTM, sw->ip_proto_mask, hw->msk[0]); + if (0x0 != sw->ip_proto_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP_PROTO); + } + + SW_GET_FIELD_BY_REG(IP6_RUL3_V0, IP6DSCPV, sw->ip_dscp_val, hw->vlu[0]); + SW_GET_FIELD_BY_REG(IP6_RUL3_M0, IP6DSCPM, sw->ip_dscp_mask, hw->msk[0]); + if (0x0 != sw->ip_dscp_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP_DSCP); + } + + SW_GET_FIELD_BY_REG(IP6_RUL3_V0, IP6DPORTV, sw->dest_l4port_val, + hw->vlu[0]); + SW_GET_FIELD_BY_REG(IP6_RUL3_M0, IP6DPORTM, sw->dest_l4port_mask, + hw->msk[0]); + SW_GET_FIELD_BY_REG(IP6_RUL3_M3, IP6DPORTM_EN, mask_en, hw->msk[3]); + if (mask_en) + { + sw->dest_l4port_op = FAL_ACL_FIELD_MASK; + } + else + { + sw->dest_l4port_op = FAL_ACL_FIELD_RANGE; + } + + if (A_TRUE == + _garuda_acl_field_care(sw->dest_l4port_op, + (a_uint32_t) sw->dest_l4port_val, + (a_uint32_t) sw->dest_l4port_mask, 0xffff)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_DPORT); + } + + SW_GET_FIELD_BY_REG(IP6_RUL3_V1, IP6SPORTV, sw->src_l4port_val, hw->vlu[1]); + SW_GET_FIELD_BY_REG(IP6_RUL3_M1, IP6SPORTM, sw->src_l4port_mask, + hw->msk[1]); + SW_GET_FIELD_BY_REG(IP6_RUL3_M3, IP6SPORTM_EN, mask_en, hw->msk[3]); + if (mask_en) + { + sw->src_l4port_op = FAL_ACL_FIELD_MASK; + } + else + { + sw->src_l4port_op = FAL_ACL_FIELD_RANGE; + } + + if (A_TRUE == + _garuda_acl_field_care(sw->src_l4port_op, + (a_uint32_t) sw->src_l4port_val, + (a_uint32_t) sw->src_l4port_mask, 0xffff)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_SPORT); + } + + SW_GET_FIELD_BY_REG(IP6_RUL3_V1, IP6LABEL1V, sw->ip6_lable_val, hw->vlu[1]); + SW_GET_FIELD_BY_REG(IP6_RUL3_M1, IP6LABEL1M, sw->ip6_lable_mask, + hw->msk[1]); + + SW_GET_FIELD_BY_REG(IP6_RUL3_V2, IP6LABEL2V, tmp, hw->vlu[2]); + sw->ip6_lable_val |= (tmp << 16); + SW_GET_FIELD_BY_REG(IP6_RUL3_M2, IP6LABEL2M, tmp, hw->msk[2]); + sw->ip6_lable_mask |= (tmp << 16); + + if (0x0 != sw->ip6_lable_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP6_LABEL); + } + + return SW_OK; +} + +static sw_error_t +_garuda_acl_rule_action_reparse(fal_acl_rule_t * sw, + const garuda_acl_hw_rule_t * hw) +{ + a_uint32_t data; + + sw->action_flg = 0; + SW_GET_FIELD_BY_REG(ACL_RSLT, DES_PORT_EN, data, (hw->act)); + if (1 == data) + { + SW_GET_FIELD_BY_REG(ACL_RSLT, PORT_MEM, data, (hw->act)); + sw->ports = data; + + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REDPT); + } + + SW_GET_FIELD_BY_REG(ACL_RSLT, RDTCPU, data, (hw->act)); + if (1 == data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_RDTCPU); + } + + SW_GET_FIELD_BY_REG(ACL_RSLT, CPYCPU, data, (hw->act)); + if (1 == data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_CPYCPU); + } + + SW_GET_FIELD_BY_REG(ACL_RSLT, MIRR_EN, data, (hw->act)); + if (1 == data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_MIRROR); + } + + SW_GET_FIELD_BY_REG(ACL_RSLT, REMARK_DOT1P, data, (hw->act)); + if (1 == data) + { + SW_GET_FIELD_BY_REG(ACL_RSLT, DOT1P, data, (hw->act)); + sw->up = data & 0x7; + + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REMARK_UP); + } + + SW_GET_FIELD_BY_REG(ACL_RSLT, REMARK_PRI_QU, data, (hw->act)); + if (1 == data) + { + SW_GET_FIELD_BY_REG(ACL_RSLT, PRI_QU, data, (hw->act)); + sw->queue = data & 0x3; + + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REMARK_QUEUE); + } + + SW_GET_FIELD_BY_REG(ACL_RSLT, CHG_VID_EN, data, (hw->act)); + if (1 == data) + { + SW_GET_FIELD_BY_REG(ACL_RSLT, STAG_CHG_EN, data, (hw->act)); + if (1 == data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_NEST_VLAN); + } + else + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_MODIFY_VLAN); + SW_GET_FIELD_BY_REG(ACL_RSLT, PORT_MEM, data, (hw->act)); + sw->ports = data; + } + } + + SW_GET_FIELD_BY_REG(ACL_RSLT, VID, data, (hw->act)); + sw->vid = data & 0xfff; + + return SW_OK; +} + +static sw_error_t +_garuda_acl_filter_alloc(a_uint32_t dev_id, a_uint32_t * idx) +{ + a_uint32_t i; + + for (i = 0; i < GARUDA_MAX_RULE; i++) + { + if (0 == (filter_snap[dev_id] & (0x1UL << i))) + { + filter_snap[dev_id] |= (0x1UL << i); + *idx = i; + return SW_OK; + } + } + return SW_NO_RESOURCE; +} + +static void +_garuda_acl_filter_free(a_uint32_t dev_id, a_uint32_t idx) +{ + filter_snap[dev_id] &= (~(0x1UL << idx)); +} + +static void +_garuda_acl_filter_snap(a_uint32_t dev_id) +{ + filter_snap[dev_id] = filter[dev_id]; + return; +} + +static void +_garuda_acl_filter_commit(a_uint32_t dev_id) +{ + filter[dev_id] = filter_snap[dev_id]; + return; +} + +static sw_error_t +_garuda_acl_slct_update(garuda_acl_hw_rule_t * hw, a_uint32_t offset, + a_uint32_t flt_idx) +{ + switch (offset) + { + case 0: + SW_SET_REG_BY_FIELD(RUL_SLCT0, ADDR0_EN, 1, hw->slct[0]); + SW_SET_REG_BY_FIELD(RUL_SLCT1, ADDR0, flt_idx, hw->slct[1]); + break; + + case 1: + SW_SET_REG_BY_FIELD(RUL_SLCT0, ADDR1_EN, 1, hw->slct[0]); + SW_SET_REG_BY_FIELD(RUL_SLCT2, ADDR1, flt_idx, hw->slct[2]); + break; + + case 2: + SW_SET_REG_BY_FIELD(RUL_SLCT0, ADDR2_EN, 1, hw->slct[0]); + SW_SET_REG_BY_FIELD(RUL_SLCT3, ADDR2, flt_idx, hw->slct[3]); + break; + + case 3: + SW_SET_REG_BY_FIELD(RUL_SLCT0, ADDR3_EN, 1, hw->slct[0]); + SW_SET_REG_BY_FIELD(RUL_SLCT4, ADDR3, flt_idx, hw->slct[4]); + break; + + default: + return SW_FAIL; + } + return SW_OK; +} + +static sw_error_t +_garuda_acl_filter_write(a_uint32_t dev_id, const garuda_acl_hw_rule_t * rule, + a_uint32_t flt_idx) +{ +#ifdef GARUDA_SW_ENTRY + char *memaddr; + a_uint32_t i; + + memaddr = flt_vlu_mem + (flt_idx << 5); + aos_mem_copy(memaddr, (char *) &(rule->vlu[0]), 20); + + memaddr = flt_msk_mem + (flt_idx << 5); + aos_mem_copy(memaddr, (char *) &(rule->msk[0]), 20); + + memaddr = flt_typ_mem + (flt_idx << 5); + aos_mem_copy(memaddr, (char *) &(rule->typ), 4); + +#else + sw_error_t rv; + a_uint32_t i, base, addr; + + /* set filter value */ + base = GARUDA_RULE_VLU_ADDR + (flt_idx << 5); + for (i = 0; i < 5; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(rule->vlu[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + /* set filter mask */ + base = GARUDA_RULE_MSK_ADDR + (flt_idx << 5); + for (i = 0; i < 5; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(rule->msk[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + /* set filter type */ + addr = GARUDA_RULE_TYP_ADDR + (flt_idx << 5); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(rule->typ)), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); +#endif + +#ifdef GARUDA_ENTRY_DUMP + aos_printk("\n_garuda_acl_filter_write flt_idx = %d\n", flt_idx); + for (i = 0; i < 5; i++) + { + aos_printk("%08x ", rule->vlu[i]); + } + aos_printk("\n"); + for (i = 0; i < 5; i++) + { + aos_printk("%08x ", rule->msk[i]); + } +#endif + + return SW_OK; +} + +static sw_error_t +_garuda_acl_action_write(a_uint32_t dev_id, const garuda_acl_hw_rule_t * rule, + a_uint32_t act_idx) +{ +#ifdef GARUDA_SW_ENTRY + char *memaddr; + + memaddr = act_mem + (act_idx << 5); + aos_mem_copy(memaddr, (char *) &(rule->act), 4); + +#else + sw_error_t rv; + a_uint32_t addr; + + /* set rule action */ + addr = GARUDA_RULE_ACT_ADDR + (act_idx << 5); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(rule->act)), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); +#endif + +#ifdef GARUDA_ENTRY_DUMP + aos_printk("\n_garuda_acl_action_write act_idx = %d ", act_idx); + aos_printk("%08x ", rule->act); +#endif + + return SW_OK; +} + +static sw_error_t +_garuda_acl_slct_write(a_uint32_t dev_id, const garuda_acl_hw_rule_t * rule, + a_uint32_t slct_idx) +{ +#ifdef GARUDA_SW_ENTRY + char *memaddr; + a_uint32_t i; + + memaddr = slct_mem + (slct_idx << 5); + aos_mem_copy(memaddr, (char *) &(rule->slct[0]), 32); + +#else + sw_error_t rv; + a_uint32_t base, addr; + a_uint32_t i; + + base = GARUDA_RULE_SLCT_ADDR + (slct_idx << 5); + + /* set filter length */ + HSL_REG_ENTRY_GEN_SET(rv, dev_id, (base + 24), sizeof (a_uint32_t), + (a_uint8_t *) (&(rule->slct[6])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* set filter address */ + for (i = 1; i < 5; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(rule->slct[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + /* set filter enable */ + HSL_REG_ENTRY_GEN_SET(rv, dev_id, base, sizeof (a_uint32_t), + (a_uint8_t *) (&(rule->slct[0])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); +#endif + +#ifdef GARUDA_ENTRY_DUMP + aos_printk("\n_garuda_acl_slct_write slct_idx = %d\n", slct_idx); + for (i = 0; i < 8; i++) + { + aos_printk("%08x ", rule->slct[i]); + } +#endif + + return SW_OK; +} + +static sw_error_t +_garuda_acl_filter_read(a_uint32_t dev_id, garuda_acl_hw_rule_t * rule, + a_uint32_t flt_idx) +{ +#ifdef GARUDA_SW_ENTRY + char *memaddr; + a_uint32_t i; + + memaddr = flt_vlu_mem + (flt_idx << 5); + aos_mem_copy((char *) &(rule->vlu[0]), memaddr, 20); + + memaddr = flt_msk_mem + (flt_idx << 5); + aos_mem_copy((char *) &(rule->msk[0]), memaddr, 20); + + memaddr = flt_typ_mem + (flt_idx << 5); + aos_mem_copy((char *) &(rule->typ), memaddr, 4); + +#else + sw_error_t rv; + a_uint32_t i, base, addr; + + /* get filter value */ + base = GARUDA_RULE_VLU_ADDR + (flt_idx << 5); + for (i = 0; i < 5; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(rule->vlu[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + /* get filter mask */ + base = GARUDA_RULE_MSK_ADDR + (flt_idx << 5); + for (i = 0; i < 5; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(rule->msk[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + /* get filter type */ + addr = GARUDA_RULE_TYP_ADDR + (flt_idx << 5); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(rule->typ)), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); +#endif + +#ifdef GARUDA_ENTRY_DUMP + aos_printk("\n_garuda_acl_filter_read flt_idx = %d\n", flt_idx); + for (i = 0; i < 5; i++) + { + aos_printk("%08x ", rule->vlu[i]); + } + aos_printk("\n"); + for (i = 0; i < 5; i++) + { + aos_printk("%08x ", rule->msk[i]); + } +#endif + + return SW_OK; +} + +static sw_error_t +_garuda_acl_action_read(a_uint32_t dev_id, garuda_acl_hw_rule_t * rule, + a_uint32_t act_idx) +{ +#ifdef GARUDA_SW_ENTRY + char *memaddr; + + memaddr = act_mem + (act_idx << 5); + aos_mem_copy((char *) &(rule->act), memaddr, 4); + +#else + sw_error_t rv; + a_uint32_t addr; + + /* get rule action */ + addr = GARUDA_RULE_ACT_ADDR + (act_idx << 5); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(rule->act)), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); +#endif + +#ifdef GARUDA_ENTRY_DUMP + aos_printk("\n_garuda_acl_action_read act_idx = %d ", act_idx); + aos_printk("%08x ", rule->act); +#endif + + return SW_OK; +} + +static sw_error_t +_garuda_acl_slct_read(a_uint32_t dev_id, garuda_acl_hw_rule_t * rule, + a_uint32_t slct_idx) +{ +#ifdef GARUDA_SW_ENTRY + char *memaddr; + a_uint32_t i; + + memaddr = slct_mem + (slct_idx << 5); + aos_mem_copy((char *) &(rule->slct[0]), memaddr, 32); + +#else + sw_error_t rv; + a_uint32_t i, base, addr; + + base = GARUDA_RULE_SLCT_ADDR + (slct_idx << 5); + + /* get filter type */ + HSL_REG_ENTRY_GEN_GET(rv, dev_id, (base + 28), sizeof (a_uint32_t), + (a_uint8_t *) (&(rule->slct[7])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* get filter length */ + HSL_REG_ENTRY_GEN_GET(rv, dev_id, (base + 24), sizeof (a_uint32_t), + (a_uint8_t *) (&(rule->slct[6])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* get filter address and enable */ + for (i = 0; i < 5; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(rule->slct[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } +#endif + +#ifdef GARUDA_ENTRY_DUMP + aos_printk("\n_garuda_acl_slct_read slct_idx = %d\n", slct_idx); + for (i = 0; i < 8; i++) + { + aos_printk("%08x ", rule->slct[i]); + } +#endif + + return SW_OK; +} + +static sw_error_t +_garuda_acl_rule_set(a_uint32_t dev_id, a_uint32_t base_addr, + const garuda_acl_hw_rule_t * rule, a_uint32_t rule_nr) +{ + sw_error_t rv; + a_uint32_t ent_idx, tmp_ent_idx; + a_uint32_t i, flt_nr, flt_idx[4]; + a_uint32_t act_idx, slct_idx; + + act_idx = base_addr; + slct_idx = base_addr; + ent_idx = 0; + for (i = 0; i < rule_nr; i++) + { + tmp_ent_idx = ent_idx; + + rv = _garuda_acl_filter_map_get(&rule[ent_idx], flt_idx, &flt_nr); + SW_RTN_ON_ERROR(rv); + + if (!flt_nr) + { + return SW_FAIL; + } + + for (i = 0; i < flt_nr; i++) + { + rv = _garuda_acl_filter_write(dev_id, &(rule[ent_idx]), flt_idx[i]); + ent_idx++; + } + + rv = _garuda_acl_action_write(dev_id, &(rule[tmp_ent_idx]), act_idx); + SW_RTN_ON_ERROR(rv); + + rv = _garuda_acl_slct_write(dev_id, &(rule[tmp_ent_idx]), slct_idx); + SW_RTN_ON_ERROR(rv); + + act_idx++; + slct_idx++; + } + return SW_OK; +} + +static sw_error_t +_garuda_acl_rule_get(a_uint32_t dev_id, garuda_acl_hw_rule_t * rule, + a_uint32_t * ent_idx, a_uint32_t rule_idx) +{ + sw_error_t rv; + a_uint32_t i, tmp_idx, flt_nr, flt_idx[4]; + + tmp_idx = *ent_idx; + + rv = _garuda_acl_slct_read(dev_id, &rule[tmp_idx], rule_idx); + SW_RTN_ON_ERROR(rv); + + rv = _garuda_acl_action_read(dev_id, &rule[tmp_idx], rule_idx); + SW_RTN_ON_ERROR(rv); + + rv = _garuda_acl_filter_map_get(&rule[tmp_idx], flt_idx, &flt_nr); + SW_RTN_ON_ERROR(rv); + + for (i = 0; i < flt_nr; i++) + { + rv = _garuda_acl_filter_read(dev_id, &rule[tmp_idx], flt_idx[i]); + SW_RTN_ON_ERROR(rv); + + tmp_idx++; + } + + *ent_idx = tmp_idx; + return SW_OK; +} + +static sw_error_t +_garuda_acl_rule_sw_to_hw(a_uint32_t dev_id, fal_acl_rule_t * sw, + fal_pbmp_t bind_pts, garuda_acl_hw_rule_t * hw, + a_uint32_t * idx, a_uint32_t * flt_len) +{ + sw_error_t rv; + a_bool_t b_care; + a_bool_t b_valid = A_FALSE; + a_uint32_t tmp_idx; + a_uint32_t len1 = 0, len2 = 0, len3 = 0, maxlen = 0; + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_UDF)) + { + return SW_NOT_SUPPORTED; + } + + tmp_idx = *idx; + if (FAL_ACL_RULE_MAC == sw->rule_type) + { + rv = _garuda_acl_rule_mac_parse(sw, bind_pts, &hw[tmp_idx], &b_care, + &len1); + SW_RTN_ON_ERROR(rv); + tmp_idx++; + + if (0 == len1) + { + *flt_len = 14; + } + else + { + *flt_len = len1; + } + } + else if (FAL_ACL_RULE_IP4 == sw->rule_type) + { + rv = _garuda_acl_rule_mac_parse(sw, bind_pts, &hw[tmp_idx], &b_care, + &len1); + SW_RTN_ON_ERROR(rv); + if (A_TRUE == b_care) + { + tmp_idx++; + } + + rv = _garuda_acl_rule_ip4_parse(sw, bind_pts, &hw[tmp_idx], &b_care, + &len1); + SW_RTN_ON_ERROR(rv); + tmp_idx++; + + if (0 == len1) + { + *flt_len = 34; + } + else + { + *flt_len = len1; + } + } + else if (FAL_ACL_RULE_IP6 == sw->rule_type) + { + rv = _garuda_acl_rule_mac_parse(sw, bind_pts, &hw[tmp_idx], &b_care, + &len1); + SW_RTN_ON_ERROR(rv); + if (A_TRUE == b_care) + { + tmp_idx++; + } + + rv = _garuda_acl_rule_ip6r1_parse(sw, bind_pts, &hw[tmp_idx], &b_care, + &len1); + SW_RTN_ON_ERROR(rv); + if (A_TRUE == b_care) + { + tmp_idx++; + b_valid = A_TRUE; + } + + rv = _garuda_acl_rule_ip6r2_parse(sw, bind_pts, &hw[tmp_idx], &b_care, + &len2); + SW_RTN_ON_ERROR(rv); + if (A_TRUE == b_care) + { + tmp_idx++; + b_valid = A_TRUE; + } + + rv = _garuda_acl_rule_ip6r3_parse(sw, bind_pts, &hw[tmp_idx], &b_care, + &len3); + SW_RTN_ON_ERROR(rv); + if ((A_TRUE == b_care) || (A_FALSE == b_valid)) + { + tmp_idx++; + } + + if (len1 >= len2) + { + if (len1 >= len3) + { + maxlen = len1; + } + else + { + maxlen = len3; + } + } + else + { + if (len2 >= len3) + { + maxlen = len2; + } + else + { + maxlen = len3; + } + } + + if (0 == maxlen) + { + *flt_len = 54; + } + else + { + *flt_len = maxlen; + } + } + else + { + return SW_NOT_SUPPORTED; + } + + rv = _garuda_acl_action_parse(dev_id, sw, &(hw_rule_ent[*idx])); + SW_RTN_ON_ERROR(rv); + + *idx = tmp_idx; + return SW_OK; +} + +static sw_error_t +_garuda_acl_rule_hw_to_sw(fal_acl_rule_t * sw, const garuda_acl_hw_rule_t * hw, + a_uint32_t ent_idx, a_uint32_t ent_nr) +{ + sw_error_t rv; + a_uint32_t i, flt_typ; + a_bool_t b_ip4 = A_FALSE, b_ip6 = A_FALSE; + + rv = _garuda_acl_rule_action_reparse(sw, &hw[ent_idx]); + SW_RTN_ON_ERROR(rv); + + sw->rule_type = FAL_ACL_RULE_MAC; + for (i = 0; i < ent_nr; i++) + { + SW_GET_FIELD_BY_REG(RUL_TYPE, TYP, flt_typ, hw[ent_idx + i].typ); + + if (GARUDA_MAC_FILTER == flt_typ) + { + rv = _garuda_acl_rule_mac_reparse(sw, &hw[ent_idx + i]); + SW_RTN_ON_ERROR(rv); + } + else if (GARUDA_IP4_FILTER == flt_typ) + { + rv = _garuda_acl_rule_ip4_reparse(sw, &hw[ent_idx + i]); + SW_RTN_ON_ERROR(rv); + b_ip4 = A_TRUE; + } + else if (GARUDA_IP6R1_FILTER == flt_typ) + { + rv = _garuda_acl_rule_ip6r1_reparse(sw, &hw[ent_idx + i]); + SW_RTN_ON_ERROR(rv); + b_ip6 = A_TRUE; + } + else if (GARUDA_IP6R2_FILTER == flt_typ) + { + rv = _garuda_acl_rule_ip6r2_reparse(sw, &hw[ent_idx + i]); + SW_RTN_ON_ERROR(rv); + b_ip6 = A_TRUE; + } + else if (GARUDA_IP6R3_FILTER == flt_typ) + { + rv = _garuda_acl_rule_ip6r3_reparse(sw, &hw[ent_idx + i]); + SW_RTN_ON_ERROR(rv); + b_ip6 = A_TRUE; + } + else + { + return SW_FAIL; + } + } + + if (A_TRUE == b_ip4) + { + sw->rule_type = FAL_ACL_RULE_IP4; + } + + if (A_TRUE == b_ip6) + { + sw->rule_type = FAL_ACL_RULE_IP6; + } + + return SW_OK; +} + +static sw_error_t +_garuda_acl_rule_copy(a_uint32_t dev_id, a_uint32_t src_slct_idx, + a_uint32_t dst_slct_idx, a_uint32_t size) +{ + sw_error_t rv; + a_uint32_t i; + a_int32_t step, src_idx, dst_idx; + garuda_acl_hw_rule_t rule; + + if (dst_slct_idx <= src_slct_idx) + { + src_idx = src_slct_idx & 0x7fffffff; + dst_idx = dst_slct_idx & 0x7fffffff; + step = 1; + } + else + { + src_idx = (src_slct_idx + size - 1) & 0x7fffffff; + dst_idx = (dst_slct_idx + size - 1) & 0x7fffffff; + step = -1; + } + + aos_mem_zero(&rule, sizeof (garuda_acl_hw_rule_t)); + for (i = 0; i < size; i++) + { + rv = _garuda_acl_rule_invalid(dev_id, (a_uint32_t) dst_idx, 1); + SW_RTN_ON_ERROR(rv); + + rv = _garuda_acl_action_read(dev_id, &rule, (a_uint32_t) src_idx); + SW_RTN_ON_ERROR(rv); + + rv = _garuda_acl_action_write(dev_id, &rule, (a_uint32_t) dst_idx); + SW_RTN_ON_ERROR(rv); + + rv = _garuda_acl_slct_read(dev_id, &rule, (a_uint32_t) src_idx); + SW_RTN_ON_ERROR(rv); + + rv = _garuda_acl_slct_write(dev_id, &rule, (a_uint32_t) dst_idx); + SW_RTN_ON_ERROR(rv); + + rv = _garuda_acl_rule_invalid(dev_id, (a_uint32_t) src_idx, 1); + SW_RTN_ON_ERROR(rv); + + src_idx += step; + dst_idx += step; + } + + return SW_OK; +} + +static sw_error_t +_garuda_acl_rule_invalid(a_uint32_t dev_id, a_uint32_t rule_idx, + a_uint32_t size) +{ + sw_error_t rv; + a_uint32_t base, flag, i; + + flag = 0; + for (i = 0; i < size; i++) + { + base = GARUDA_RULE_SLCT_ADDR + ((rule_idx + i) << 5); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, base, sizeof (a_uint32_t), + (a_uint8_t *) (&flag), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + return SW_OK; +} + +static sw_error_t +_garuda_acl_rule_valid(a_uint32_t dev_id, a_uint32_t rule_idx, a_uint32_t size, + a_uint32_t flag) +{ + sw_error_t rv; + a_uint32_t base, i; + + for (i = 0; i < size; i++) + { + base = GARUDA_RULE_SLCT_ADDR + ((rule_idx + i) << 5); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, base, sizeof (a_uint32_t), + (a_uint8_t *) (&flag), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + return SW_OK; +} + +static sw_error_t +_garuda_acl_addr_update(a_uint32_t dev_id, a_uint32_t old_addr, + a_uint32_t new_addr, a_uint32_t list_id) +{ + sw_error_t rv; + a_uint32_t idx; + + rv = _garuda_acl_list_loc(dev_id, list_id, &idx); + SW_RTN_ON_ERROR(rv); + + if (old_addr != list_ent[dev_id][idx].addr) + { + return SW_FAIL; + } + + list_ent[dev_id][idx].addr = new_addr; + return SW_OK; +} + +static sw_error_t +_garuda_acl_rule_bind(a_uint32_t dev_id, a_uint32_t rule_idx, a_uint32_t ports) +{ + sw_error_t rv; + a_uint32_t flt_idx[4], flt_nr; + a_uint32_t bind_pts = 0, addr, i, ret = 0; + garuda_acl_hw_rule_t rule; + + aos_mem_zero(&rule, sizeof (garuda_acl_hw_rule_t)); + + rv = _garuda_acl_slct_read(dev_id, &rule, rule_idx); + SW_RTN_ON_ERROR(rv); + + rv = _garuda_acl_filter_map_get(&rule, flt_idx, &flt_nr); + SW_RTN_ON_ERROR(rv); + + rv = _garuda_acl_rule_invalid(dev_id, rule_idx, 1); + SW_RTN_ON_ERROR(rv); + + for (i = 0; i < flt_nr; i++) + { + addr = GARUDA_RULE_VLU_ADDR + (flt_idx[i] << 5) + 16; + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&bind_pts), sizeof (a_uint32_t)); + + /* source port field in different type rules has the same + hardware bit position */ + SW_SET_REG_BY_FIELD(MAC_RUL_V4, MAC_INPT, ports, bind_pts); + + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&bind_pts), sizeof (a_uint32_t)); + ret += rv; + } + + rv = _garuda_acl_rule_valid(dev_id, rule_idx, 1, rule.slct[0]); + ret += rv; + if (0 != ret) + { + return SW_FAIL; + } + + return SW_OK; +} + +static sw_error_t +_garuda_acl_list_creat(a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t list_pri) +{ + a_uint32_t i, loc = GARUDA_MAX_LIST; + + HSL_DEV_ID_CHECK(dev_id); + + for (i = 0; i < GARUDA_MAX_LIST; i++) + { + if ((ENT_USED == list_ent[dev_id][i].status) + && (list_id == list_ent[dev_id][i].list_id)) + { + return SW_ALREADY_EXIST; + } + + if (ENT_FREE == list_ent[dev_id][i].status) + { + loc = i; + } + } + + if (GARUDA_MAX_LIST == loc) + { + return SW_NO_RESOURCE; + } + + aos_mem_zero(&(list_ent[dev_id][loc]), sizeof (garuda_acl_list_t)); + list_ent[dev_id][loc].list_id = list_id; + list_ent[dev_id][loc].list_pri = list_pri; + list_ent[dev_id][loc].status = ENT_USED; + _garuda_acl_list_dump(dev_id); + return SW_OK; +} + + +static sw_error_t +_garuda_acl_list_destroy(a_uint32_t dev_id, a_uint32_t list_id) +{ + a_uint32_t list_idx; + + HSL_DEV_ID_CHECK(dev_id); + + for (list_idx = 0; list_idx < GARUDA_MAX_LIST; list_idx++) + { + if ((ENT_USED == list_ent[dev_id][list_idx].status) + && (list_id == list_ent[dev_id][list_idx].list_id)) + { + break; + } + } + + if (list_idx >= GARUDA_MAX_LIST) + { + return SW_NOT_FOUND; + } + + if (0 != list_ent[dev_id][list_idx].bind_pts) + { + return SW_NOT_SUPPORTED; + } + + if (0 != list_ent[dev_id][list_idx].size) + { + return SW_NOT_SUPPORTED; + } + + aos_mem_zero(&(list_ent[dev_id][list_idx]), sizeof (garuda_acl_list_t)); + list_ent[dev_id][list_idx].status = ENT_FREE; + _garuda_acl_list_dump(dev_id); + return SW_OK; +} + + +static sw_error_t +_garuda_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; + a_uint32_t hsl_f_rsc, list_new_size, list_addr; + a_uint32_t list_pri, list_idx, load_addr, bind_pts; + + HSL_DEV_ID_CHECK(dev_id); + + if ((0 == rule_nr) || (NULL == rule)) + { + return SW_BAD_PARAM; + } + + rv = hsl_acl_free_rsc_get(dev_id, &hsl_f_rsc); + SW_RTN_ON_ERROR(rv); + if (hsl_f_rsc < rule_nr) + { + return SW_NO_RESOURCE; + } + + rv = _garuda_acl_list_loc(dev_id, list_id, &list_idx); + SW_RTN_ON_ERROR(rv); + + if (rule_id != list_ent[dev_id][list_idx].size) + { + return SW_ALREADY_EXIST; + } + bind_pts = list_ent[dev_id][list_idx].bind_pts; + + _garuda_acl_filter_snap(dev_id); + + /* parse rule entry and alloc rule resource */ + { + a_uint32_t i, j; + a_uint32_t ent_idx, tmp_ent_idx, flt_idx, flt_len; + + aos_mem_zero(hw_rule_ent, + GARUDA_MAX_RULE * sizeof (garuda_acl_hw_rule_t)); + + ent_idx = 0; + for (i = 0; i < rule_nr; i++) + { + tmp_ent_idx = ent_idx; + rv = _garuda_acl_rule_sw_to_hw(dev_id, &rule[i], bind_pts, + &hw_rule_ent[ent_idx], &ent_idx, + &flt_len); + SW_RTN_ON_ERROR(rv); + + for (j = tmp_ent_idx; j < ent_idx; j++) + { + rv = _garuda_acl_filter_alloc(dev_id, &flt_idx); + SW_RTN_ON_ERROR(rv); + + rv = _garuda_acl_slct_update(&hw_rule_ent[tmp_ent_idx], + j - tmp_ent_idx, flt_idx); + SW_RTN_ON_ERROR(rv); + } + SW_SET_REG_BY_FIELD(RUL_SLCT6, RULE_LEN, flt_len, + hw_rule_ent[tmp_ent_idx].slct[6]); + } + } + + /* alloc hardware select entry resource */ + if (0 == list_ent[dev_id][list_idx].size) + { + list_new_size = rule_nr; + list_pri = list_ent[dev_id][list_idx].list_pri; + + rv = hsl_acl_blk_alloc(dev_id, list_pri, list_new_size, list_id, + &list_addr); + SW_RTN_ON_ERROR(rv); + + load_addr = list_addr; + } + else + { + list_new_size = list_ent[dev_id][list_idx].size + rule_nr; + list_addr = list_ent[dev_id][list_idx].addr; + + rv = hsl_acl_blk_resize(dev_id, list_addr, list_new_size); + SW_RTN_ON_ERROR(rv); + + /* must be careful resize opration maybe change list base address */ + list_addr = list_ent[dev_id][list_idx].addr; + load_addr = list_ent[dev_id][list_idx].size + list_addr; + } + + /* load acl rule to hardware */ + rv = _garuda_acl_rule_set(dev_id, load_addr, hw_rule_ent, rule_nr); + if (SW_OK != rv) + { + (void) hsl_acl_blk_resize(dev_id, list_addr, + list_ent[dev_id][list_idx].size); + return rv; + } + + /* update software list control information */ + list_ent[dev_id][list_idx].size = list_new_size; + list_ent[dev_id][list_idx].addr = list_addr; + + /* update hardware acl rule resource information */ + _garuda_acl_filter_commit(dev_id); + _garuda_acl_list_dump(dev_id); + return SW_OK; +} + + +static sw_error_t +_garuda_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; + a_uint32_t flt_idx[4]; + a_uint32_t i, j, flt_nr; + a_uint32_t list_idx, addr, size, rule_idx, cnt; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _garuda_acl_list_loc(dev_id, list_id, &list_idx); + SW_RTN_ON_ERROR(rv); + + if (0 == rule_nr) + { + return SW_BAD_PARAM; + } + + if ((rule_id + rule_nr) > list_ent[dev_id][list_idx].size) + { + return SW_NOT_FOUND; + } + + _garuda_acl_filter_snap(dev_id); + + /* free hardware filter resource */ + addr = list_ent[dev_id][list_idx].addr + rule_id; + for (i = 0; i < rule_nr; i++) + { + rv = _garuda_acl_slct_read(dev_id, &hw_rule_ent[0], i + addr); + SW_RTN_ON_ERROR(rv); + + rv = _garuda_acl_filter_map_get(&hw_rule_ent[0], flt_idx, &flt_nr); + SW_RTN_ON_ERROR(rv); + + for (j = 0; j < flt_nr; j++) + { + _garuda_acl_filter_free(dev_id, flt_idx[j]); + } + } + + cnt = list_ent[dev_id][list_idx].size - (rule_id + rule_nr); + rule_idx = list_ent[dev_id][list_idx].addr + (rule_id + rule_nr); + rv = _garuda_acl_rule_copy(dev_id, rule_idx, rule_idx - rule_nr, cnt); + SW_RTN_ON_ERROR(rv); + + addr = list_ent[dev_id][list_idx].addr; + size = list_ent[dev_id][list_idx].size; + rv = hsl_acl_blk_resize(dev_id, addr, size - rule_nr); + SW_RTN_ON_ERROR(rv); + + list_ent[dev_id][list_idx].size -= rule_nr; + _garuda_acl_filter_commit(dev_id); + _garuda_acl_list_dump(dev_id); + return SW_OK; +} + + +static sw_error_t +_garuda_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; + a_uint32_t list_idx, ent_idx, tmp_ent_idx, rule_idx; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _garuda_acl_list_loc(dev_id, list_id, &list_idx); + SW_RTN_ON_ERROR(rv); + + if (rule_id >= list_ent[dev_id][list_idx].size) + { + return SW_NOT_FOUND; + } + + aos_mem_zero(rule, sizeof (fal_acl_rule_t)); + + ent_idx = 0; + tmp_ent_idx = 0; + rule_idx = list_ent[dev_id][list_idx].addr + rule_id; + rv = _garuda_acl_rule_get(dev_id, hw_rule_ent, &tmp_ent_idx, rule_idx); + SW_RTN_ON_ERROR(rv); + + rv = _garuda_acl_rule_hw_to_sw(rule, hw_rule_ent, ent_idx, + tmp_ent_idx - ent_idx); + return rv; +} + + +static sw_error_t +_garuda_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; + a_uint32_t i, list_idx, rule_idx, base, ports; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_ACL_DIREC_IN != direc) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_ACL_BIND_PORT != obj_t) + { + return SW_NOT_SUPPORTED; + } + + rv = _garuda_acl_list_loc(dev_id, list_id, &list_idx); + SW_RTN_ON_ERROR(rv); + + if (list_ent[dev_id][list_idx].bind_pts & (0x1 << obj_idx)) + { + return SW_ALREADY_EXIST; + } + + base = list_ent[dev_id][list_idx].addr; + ports = list_ent[dev_id][list_idx].bind_pts | (0x1 << obj_idx); + for (i = 0; i < list_ent[dev_id][list_idx].size; i++) + { + rule_idx = base + i; + rv = _garuda_acl_rule_bind(dev_id, rule_idx, ports); + SW_RTN_ON_ERROR(rv); + } + + list_ent[dev_id][list_idx].bind_pts = ports; + return SW_OK; +} + + + +static sw_error_t +_garuda_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; + a_uint32_t i, list_idx, rule_idx, base, ports; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_ACL_DIREC_IN != direc) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_ACL_BIND_PORT != obj_t) + { + return SW_NOT_SUPPORTED; + } + + rv = _garuda_acl_list_loc(dev_id, list_id, &list_idx); + SW_RTN_ON_ERROR(rv); + + if (!(list_ent[dev_id][list_idx].bind_pts & (0x1 << obj_idx))) + { + return SW_NOT_FOUND; + } + + base = list_ent[dev_id][list_idx].addr; + ports = list_ent[dev_id][list_idx].bind_pts & (~(0x1UL << obj_idx)); + for (i = 0; i < list_ent[dev_id][list_idx].size; i++) + { + rule_idx = base + i; + rv = _garuda_acl_rule_bind(dev_id, rule_idx, ports); + SW_RTN_ON_ERROR(rv); + } + + list_ent[dev_id][list_idx].bind_pts = ports; + return SW_OK; +} + + +static sw_error_t +_garuda_acl_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, QM_CTL, 0, ACL_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + + +static sw_error_t +_garuda_acl_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, QM_CTL, 0, ACL_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +HSL_LOCAL sw_error_t +garuda_acl_list_dump(a_uint32_t dev_id) +{ + a_uint32_t idx; + + aos_printk("\ngaruda_acl_list_dump:\n"); + for (idx = 0; idx < GARUDA_MAX_LIST; idx++) + { + if (ENT_USED == list_ent[dev_id][idx].status) + { + aos_printk + ("\n[id]:%02d [pri]:%02d [size]:%02d [addr]:%02d [pts_map]:0x%02x", + list_ent[dev_id][idx].list_id, list_ent[dev_id][idx].list_pri, + list_ent[dev_id][idx].size, list_ent[dev_id][idx].addr, + list_ent[dev_id][idx].bind_pts); + } + } + aos_printk("\n"); + + return SW_OK; +} + +HSL_LOCAL sw_error_t +garuda_acl_rule_dump(a_uint32_t dev_id) +{ + a_uint32_t slt_idx, flt_nr, i, j; + a_uint32_t flt_idx[4]; + sw_error_t rv; + garuda_acl_hw_rule_t rule; + + aos_printk("\ngaruda_acl_rule_dump:\n"); + + aos_printk("\nfilter_bitmap:0x%x", filter[dev_id]); + for (slt_idx = 0; slt_idx < GARUDA_MAX_RULE; slt_idx++) + { + aos_mem_zero(&rule, sizeof (garuda_acl_hw_rule_t)); + + rv = _garuda_acl_slct_read(dev_id, &rule, slt_idx); + if (SW_OK != rv) + { + continue; + } + + rv = _garuda_acl_filter_map_get(&rule, flt_idx, &flt_nr); + if (SW_OK != rv) + { + continue; + } + + aos_printk("\nslct_idx=%d ", slt_idx); + for (i = 0; i < flt_nr; i++) + { + aos_printk("flt%d_idx=%d ", i, flt_idx[i]); + } + + aos_printk("\nslt:"); + for (i = 0; i < 8; i++) + { + aos_printk("%08x ", rule.slct[i]); + } + + if (flt_nr) + { + rv = _garuda_acl_action_read(dev_id, &rule, slt_idx); + if (SW_OK != rv) + { + continue; + } + aos_printk("\nact:%08x ", rule.act); + + for (i = 0; i < flt_nr; i++) + { + rv = _garuda_acl_filter_read(dev_id, &rule, flt_idx[i]); + if (SW_OK != rv) + { + continue; + } + + aos_printk("\ntyp:%08x ", rule.typ); + aos_printk("\nvlu:"); + for (j = 0; j < 5; j++) + { + aos_printk("%08x ", rule.vlu[j]); + } + + aos_printk("\nmsk:"); + for (j = 0; j < 5; j++) + { + aos_printk("%08x ", rule.msk[j]); + } + aos_printk("\n"); + } + } + aos_printk("\n"); + } + + return SW_OK; +} + +sw_error_t +garuda_acl_reset(a_uint32_t dev_id) +{ + sw_error_t rv; + a_uint32_t i; + + HSL_DEV_ID_CHECK(dev_id); + + aos_mem_zero(hw_rule_ent, + (GARUDA_MAX_RULE + 3) * sizeof (garuda_acl_hw_rule_t)); + + aos_mem_zero(list_ent[dev_id], + GARUDA_MAX_LIST * sizeof (garuda_acl_list_t)); + + for (i = 0; i < GARUDA_MAX_LIST; i++) + { + list_ent[dev_id][i].status = ENT_FREE; + } + + filter[dev_id] = 0; + filter_snap[dev_id] = 0; + + rv = hsl_acl_pool_destroy(dev_id); + SW_RTN_ON_ERROR(rv); + + rv = hsl_acl_pool_creat(dev_id, GARUDA_MAX_LIST, GARUDA_MAX_RULE); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +/** + * @brief Creat an acl list + * @details Comments: + * If the priority of a list is more small then the priority is more high, + * that means the list could be first matched. + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] list_pri acl list priority + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_acl_list_creat(a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t list_pri) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_acl_list_creat(dev_id, list_id, list_pri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Destroy an acl list + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_acl_list_destroy(a_uint32_t dev_id, a_uint32_t list_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_acl_list_destroy(dev_id, list_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add one rule or more rules to an existing acl list + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] rule_id first rule id of this adding operation in list + * @param[in] rule_nr rule number of this adding operation + * @param[in] rule rules content of this adding operation + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_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; + + HSL_API_LOCK; + rv = _garuda_acl_rule_add(dev_id, list_id, rule_id, rule_nr, rule); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete one rule or more rules from an existing acl list + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] rule_id first rule id of this deleteing operation in list + * @param[in] rule_nr rule number of this deleteing operation + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_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; + + HSL_API_LOCK; + rv = _garuda_acl_rule_delete(dev_id, list_id, rule_id, rule_nr); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Query one particular rule in a particular acl list + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] rule_id first rule id of this deleteing operation in list + * @param[out] rule rule content of this operation + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_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; + + HSL_API_LOCK; + rv = _garuda_acl_rule_query(dev_id, list_id, rule_id, rule); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Bind an acl list to a particular object + * @details Comments: + * If obj_t equals FAL_ACL_BIND_PORT then obj_idx means port id + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] direc direction of this binding operation + * @param[in] obj_t object type of this binding operation + * @param[in] obj_idx object index of this binding operation + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_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; + + HSL_API_LOCK; + rv = _garuda_acl_list_bind(dev_id, list_id, direc, obj_t, obj_idx); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Unbind an acl list from a particular object + * @details Comments: + * If obj_t equals FAL_ACL_BIND_PORT then obj_idx means port id + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] direc direction of this unbinding operation + * @param[in] obj_t object type of this unbinding operation + * @param[in] obj_idx object index of this unbinding operation + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_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; + + HSL_API_LOCK; + rv = _garuda_acl_list_unbind(dev_id, list_id, direc, obj_t, obj_idx); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set working status of ACL engine on a particular device + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_acl_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_acl_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get working status of ACL engine on a particular device + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_acl_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_acl_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +garuda_acl_init(a_uint32_t dev_id) +{ + static a_bool_t b_hw_rule = A_FALSE; + hsl_acl_func_t *acl_func; + garuda_acl_hw_rule_t rule; + sw_error_t rv; + a_uint32_t i; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == b_hw_rule) + { + hw_rule_ent = (garuda_acl_hw_rule_t *) + aos_mem_alloc((GARUDA_MAX_RULE + + 3) * sizeof (garuda_acl_hw_rule_t)); + if (NULL == hw_rule_ent) + { + return SW_NO_RESOURCE; + } + aos_mem_zero(hw_rule_ent, + (GARUDA_MAX_RULE + 3) * sizeof (garuda_acl_hw_rule_t)); + b_hw_rule = A_TRUE; + } + + list_ent[dev_id] = (garuda_acl_list_t *) + aos_mem_alloc(GARUDA_MAX_LIST * sizeof (garuda_acl_list_t)); + if (NULL == list_ent[dev_id]) + { + return SW_NO_RESOURCE; + } + aos_mem_zero(list_ent[dev_id], + GARUDA_MAX_LIST * sizeof (garuda_acl_list_t)); + + for (i = 0; i < GARUDA_MAX_LIST; i++) + { + list_ent[dev_id][i].status = ENT_FREE; + } + + filter[dev_id] = 0; + filter_snap[dev_id] = 0; + + rv = hsl_acl_pool_creat(dev_id, GARUDA_MAX_LIST, GARUDA_MAX_RULE); + SW_RTN_ON_ERROR(rv); + + acl_func = hsl_acl_ptr_get(dev_id); + SW_RTN_ON_NULL(acl_func); + + acl_func->acl_rule_copy = _garuda_acl_rule_copy; + acl_func->acl_rule_invalid = _garuda_acl_rule_invalid; + acl_func->acl_addr_update = _garuda_acl_addr_update; + + /* zero acl hardware memory */ + aos_mem_zero(&rule, sizeof (garuda_acl_hw_rule_t)); + for (i = 0; i < GARUDA_MAX_RULE; i++) + { + rv = _garuda_acl_slct_write(dev_id, &rule, i); + SW_RTN_ON_ERROR(rv); + } + +#ifdef GARUDA_SW_ENTRY + flt_vlu_mem = aos_mem_alloc(GARUDA_MAX_RULE * 32); + if (NULL == flt_vlu_mem) + { + return SW_NO_RESOURCE; + } + aos_mem_zero(flt_vlu_mem, GARUDA_MAX_RULE * 32); + + flt_msk_mem = aos_mem_alloc(GARUDA_MAX_RULE * 32); + if (NULL == flt_msk_mem) + { + return SW_NO_RESOURCE; + } + aos_mem_zero(flt_msk_mem, GARUDA_MAX_RULE * 32); + + flt_typ_mem = aos_mem_alloc(GARUDA_MAX_RULE * 4); + if (NULL == flt_typ_mem) + { + return SW_NO_RESOURCE; + } + aos_mem_zero(flt_typ_mem, GARUDA_MAX_RULE * 4); + + act_mem = aos_mem_alloc(GARUDA_MAX_RULE * 32); + if (NULL == act_mem) + { + return SW_NO_RESOURCE; + } + aos_mem_zero(act_mem, GARUDA_MAX_RULE * 32); + + slct_mem = aos_mem_alloc(GARUDA_MAX_RULE * 32); + if (NULL == slct_mem) + { + return SW_NO_RESOURCE; + } + aos_mem_zero(slct_mem, GARUDA_MAX_RULE * 32); +#endif + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->acl_list_creat = garuda_acl_list_creat; + p_api->acl_list_destroy = garuda_acl_list_destroy; + p_api->acl_list_bind = garuda_acl_list_bind; + p_api->acl_list_unbind = garuda_acl_list_unbind; + p_api->acl_rule_add = garuda_acl_rule_add; + p_api->acl_rule_delete = garuda_acl_rule_delete; + p_api->acl_rule_query = garuda_acl_rule_query; + p_api->acl_status_set = garuda_acl_status_set; + p_api->acl_status_get = garuda_acl_status_get; + p_api->acl_list_dump = garuda_acl_list_dump; + p_api->acl_rule_dump = garuda_acl_rule_dump; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_fdb.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_fdb.c new file mode 100755 index 000000000..1904396dc --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_fdb.c @@ -0,0 +1,1007 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 garuda_fdb GARUDA_FDB + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "garuda_fdb.h" +#include "garuda_reg.h" + +#define ARL_FLUSH_ALL 1 +#define ARL_LOAD_ENTRY 2 +#define ARL_PURGE_ENTRY 3 +#define ARL_FLUSH_ALL_UNLOCK 4 +#define ARL_FLUSH_PORT_UNICAST 5 +#define ARL_NEXT_ENTRY 6 +#define ARL_FIND_ENTRY 7 + +#define ARL_FIRST_ENTRY 1001 +#define ARL_FLUSH_PORT_NO_STATIC 1002 +#define ARL_FLUSH_PORT_AND_STATIC 1003 + +static a_bool_t +garuda_fdb_is_zeroaddr(fal_mac_addr_t addr) +{ + a_uint32_t i; + + for (i = 0; i < 6; i++) + { + if (addr.uc[i]) + { + return A_FALSE; + } + } + + return A_TRUE; +} + +static void +garuda_fdb_fill_addr(fal_mac_addr_t addr, a_uint32_t * reg0, a_uint32_t * reg1) +{ + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_ADDR_BYTE0, addr.uc[0], *reg1); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_ADDR_BYTE1, addr.uc[1], *reg1); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_ADDR_BYTE2, addr.uc[2], *reg1); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_ADDR_BYTE3, addr.uc[3], *reg1); + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_ADDR_BYTE4, addr.uc[4], *reg0); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_ADDR_BYTE5, addr.uc[5], *reg0); + + return; +} + +static sw_error_t +garuda_atu_sw_to_hw(a_uint32_t dev_id, const fal_fdb_entry_t * entry, + a_uint32_t reg[]) +{ + a_uint32_t port; + + if (A_FALSE == entry->portmap_en) + { + if (A_TRUE != + hsl_port_prop_check(dev_id, entry->port.id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + port = 0x1UL << entry->port.id; + } + else + { + if (A_FALSE == + hsl_mports_prop_check(dev_id, entry->port.map, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + port = entry->port.map; + } + + if (FAL_MAC_CPY_TO_CPU == entry->dacmd) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, COPY_TO_CPU, 1, reg[2]); + } + else if (FAL_MAC_RDT_TO_CPU == entry->dacmd) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, REDRCT_TO_CPU, 1, reg[2]); + } + else if (FAL_MAC_FRWRD != entry->dacmd) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_MAC_DROP == entry->sacmd) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, SA_DROP_EN, 1, reg[2]); + } + else if (FAL_MAC_FRWRD != entry->sacmd) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == entry->leaky_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, LEAKY_EN, 1, reg[2]); + } + else + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, LEAKY_EN, 0, reg[2]); + } + + if (A_TRUE == entry->static_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_STATUS, 15, reg[2]); + } + else + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_STATUS, 7, reg[2]); + } + + if (A_TRUE == entry->mirror_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, MIRROR_EN, 1, reg[2]); + } + + if (A_TRUE == entry->clone_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, CLONE_EN, 1, reg[2]); + } + + if (A_TRUE == entry->da_pri_en) + { + hsl_dev_t *p_dev; + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_PRI_EN, 1, reg[2]); + + SW_RTN_ON_NULL(p_dev = hsl_dev_ptr_get(dev_id)); + + if (entry->da_queue > (p_dev->nr_queue - 1)) + return SW_BAD_PARAM; + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_PRI, entry->da_queue, reg[2]); + } + + if (A_TRUE == entry->cross_pt_state) + { + return SW_NOT_SUPPORTED; + } + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, DES_PORT, port, reg[2]); + garuda_fdb_fill_addr(entry->addr, ®[0], ®[1]); + + return SW_OK; +} + +static void +garuda_atu_hw_to_sw(const a_uint32_t reg[], fal_fdb_entry_t * entry) +{ + a_uint32_t i, data; + + aos_mem_zero(entry, sizeof (fal_fdb_entry_t)); + + entry->dacmd = FAL_MAC_FRWRD; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, COPY_TO_CPU, data, reg[2]); + if (1 == data) + { + entry->dacmd = FAL_MAC_CPY_TO_CPU; + } + + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, REDRCT_TO_CPU, data, reg[2]); + if (1 == data) + { + entry->dacmd = FAL_MAC_RDT_TO_CPU; + } + + entry->sacmd = FAL_MAC_FRWRD; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, SA_DROP_EN, data, reg[2]); + if (1 == data) + { + entry->sacmd = FAL_MAC_DROP; + } + + entry->leaky_en = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, LEAKY_EN, data, reg[2]); + if (1 == data) + { + entry->leaky_en = A_TRUE; + } + + entry->static_en = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, AT_STATUS, data, reg[2]); + if (0xf == data) + { + entry->static_en = A_TRUE; + } + + entry->mirror_en = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, MIRROR_EN, data, reg[2]); + if (1 == data) + { + entry->mirror_en = A_TRUE; + } + + entry->clone_en = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, CLONE_EN, data, reg[2]); + if (1 == data) + { + entry->clone_en = A_TRUE; + } + + entry->da_pri_en = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, AT_PRI_EN, data, reg[2]); + if (1 == data) + { + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, AT_PRI, data, reg[2]); + entry->da_pri_en = A_TRUE; + entry->da_queue = data & 0x3; + } + + entry->cross_pt_state = A_FALSE; + + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, DES_PORT, data, reg[2]); + + entry->portmap_en = A_TRUE; + entry->port.map = data; + + for (i = 0; i < 4; i++) + { + entry->addr.uc[i] = (reg[1] >> ((3 - i) << 3)) & 0xff; + } + + for (i = 4; i < 6; i++) + { + entry->addr.uc[i] = (reg[0] >> ((7 - i) << 3)) & 0xff; + } + + return; +} + +static sw_error_t +garuda_fdb_commit(a_uint32_t dev_id, a_uint32_t op) +{ + sw_error_t rv; + a_uint32_t busy = 1; + a_uint32_t full_vio; + a_uint32_t i = 1000; + a_uint32_t entry; + a_uint32_t hwop = op; + + while (busy && --i) + { + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_FUNC0, 0, AT_BUSY, + (a_uint8_t *) (&busy), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + aos_udelay(5); + } + + if (0 == i) + { + return SW_BUSY; + } + + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC0, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_BUSY, 1, entry); + + if (ARL_FLUSH_PORT_AND_STATIC == hwop) + { + hwop = ARL_FLUSH_PORT_UNICAST; + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, FLUSH_ST_EN, 1, entry); + } + + if (ARL_FLUSH_PORT_NO_STATIC == hwop) + { + hwop = ARL_FLUSH_PORT_UNICAST; + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, FLUSH_ST_EN, 0, entry); + } + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_FUNC, hwop, entry); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC0, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + busy = 1; + i = 1000; + while (busy && --i) + { + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_FUNC0, 0, AT_BUSY, + (a_uint8_t *) (&busy), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + aos_udelay(5); + } + + if (0 == i) + { + return SW_FAIL; + } + + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_FUNC0, 0, AT_FULL_VIO, + (a_uint8_t *) (&full_vio), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (full_vio) + { + /* must clear AT_FULL_VOI bit */ + entry = 0x1000; + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC0, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (ARL_LOAD_ENTRY == hwop) + { + return SW_FULL; + } + else if ((ARL_PURGE_ENTRY == hwop) + || (ARL_FLUSH_PORT_UNICAST == hwop)) + { + return SW_NOT_FOUND; + } + else + { + return SW_FAIL; + } + } + + return SW_OK; +} + +static sw_error_t +garuda_atu_get(a_uint32_t dev_id, fal_fdb_entry_t * entry, a_uint32_t op) +{ + sw_error_t rv; + a_uint32_t reg[3] = { 0 }; + a_uint32_t status = 0; + a_uint32_t hwop = op; + + if ((ARL_NEXT_ENTRY == op) + || (ARL_FIND_ENTRY == op)) + { + garuda_fdb_fill_addr(entry->addr, ®[0], ®[1]); + } + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* set status not zero */ + if (ARL_NEXT_ENTRY == op) + { + reg[2] = 0xf0000; + } + + if (ARL_FIRST_ENTRY == op) + { + hwop = ARL_NEXT_ENTRY; + } + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC2, 0, + (a_uint8_t *) (®[2]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = garuda_fdb_commit(dev_id, hwop); + SW_RTN_ON_ERROR(rv); + + /* get hardware enrety */ + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC2, 0, + (a_uint8_t *) (®[2]), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, AT_STATUS, status, reg[2]); + + garuda_atu_hw_to_sw(reg, entry); + + /* If hardware return back with address and status all zero, + that means no other next valid entry in fdb table */ + if ((A_TRUE == garuda_fdb_is_zeroaddr(entry->addr)) + && (0 == status)) + { + if (ARL_NEXT_ENTRY == op) + { + return SW_NO_MORE; + } + else if ((ARL_FIND_ENTRY == op) + || (ARL_FIRST_ENTRY == op)) + { + return SW_NOT_FOUND; + } + else + { + return SW_FAIL; + } + } + else + { + return SW_OK; + } +} + +static sw_error_t +_garuda_fdb_add(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t reg[3] = { 0, 0, 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = garuda_atu_sw_to_hw(dev_id, entry, reg); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC2, 0, + (a_uint8_t *) (®[2]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC1, 0, (a_uint8_t *) (®[1]), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC0, 0, (a_uint8_t *) (®[0]), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = garuda_fdb_commit(dev_id, ARL_LOAD_ENTRY); + + return rv; +} + + +static sw_error_t +_garuda_fdb_del_all(a_uint32_t dev_id, a_uint32_t flag) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_FDB_DEL_STATIC & flag) + { + rv = garuda_fdb_commit(dev_id, ARL_FLUSH_ALL); + } + else + { + rv = garuda_fdb_commit(dev_id, ARL_FLUSH_ALL_UNLOCK); + } + + return rv; +} + + +static sw_error_t +_garuda_fdb_del_by_port(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t flag) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_PORT_NUM, port_id, reg); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC0, 0, (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_FDB_DEL_STATIC & flag) + { + rv = garuda_fdb_commit(dev_id, ARL_FLUSH_PORT_AND_STATIC); + } + else + { + rv = garuda_fdb_commit(dev_id, ARL_FLUSH_PORT_NO_STATIC); + } + + return rv; +} + + +static sw_error_t +_garuda_fdb_del_by_mac(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t reg0 = 0, reg1 = 0; + + HSL_DEV_ID_CHECK(dev_id); + + garuda_fdb_fill_addr(entry->addr, ®0, ®1); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC1, 0, (a_uint8_t *) (®1), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC0, 0, (a_uint8_t *) (®0), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = garuda_fdb_commit(dev_id, ARL_PURGE_ENTRY); + return rv; +} + + +static sw_error_t +_garuda_fdb_next(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + rv = garuda_atu_get(dev_id, entry, ARL_NEXT_ENTRY); + return rv; +} + + +static sw_error_t +_garuda_fdb_first(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + rv = garuda_atu_get(dev_id, entry, ARL_FIRST_ENTRY); + return rv; +} + + +static sw_error_t +_garuda_fdb_find(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + rv = garuda_atu_get(dev_id, entry, ARL_FIND_ENTRY); + return rv; +} + + +static sw_error_t +_garuda_fdb_port_learn_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, LEARN_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + + +static sw_error_t +_garuda_fdb_port_learn_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, LEARN_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_garuda_fdb_age_ctrl_set(a_uint32_t dev_id, a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, ADDR_TABLE_CTL, 0, AGE_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + + +static sw_error_t +_garuda_fdb_age_ctrl_get(a_uint32_t dev_id, a_bool_t *enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_CTL, 0, AGE_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + + +static sw_error_t +_garuda_fdb_age_time_set(a_uint32_t dev_id, a_uint32_t * time) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if ((65535 * 7 < *time) || (7 > *time)) + { + return SW_BAD_PARAM; + } + data = *time / 7; + *time = data * 7; + HSL_REG_FIELD_SET(rv, dev_id, ADDR_TABLE_CTL, 0, AGE_TIME, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + + +static sw_error_t +_garuda_fdb_age_time_get(a_uint32_t dev_id, a_uint32_t *time) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_CTL, 0, AGE_TIME, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *time = data * 7; + return SW_OK; +} + +/** + * @brief Add a Fdb entry + * @param[in] dev_id device id + * @param[in] entry fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_fdb_add(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_fdb_add(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete all Fdb entries + * @details Comments: + * If set FAL_FDB_DEL_STATIC bit in flag which means delete all fdb + * entries otherwise only delete dynamic entries. + * @param[in] dev_id device id + * @param[in] flag delete operation option + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_fdb_del_all(a_uint32_t dev_id, a_uint32_t flag) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_fdb_del_all(dev_id, flag); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete Fdb entries on a particular port + * @details Comments: + * If set FAL_FDB_DEL_STATIC bit in flag which means delete all fdb + * entries otherwise only delete dynamic entries. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] flag delete operation option + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_fdb_del_by_port(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t flag) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_fdb_del_by_port(dev_id, port_id, flag); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a particular Fdb entry through mac address + * @details Comments: + * Only addr field in entry is meaning. For IVL learning vid or fid field + * also is meaning. + * @param[in] dev_id device id + * @param[in] entry fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_fdb_del_by_mac(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_fdb_del_by_mac(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get next Fdb entry from particular device + * @details Comments: + * For input parameter only addr field in entry is meaning. + * @param[in] dev_id device id + * @param entry fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_fdb_next(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_fdb_next(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get first Fdb entry from particular device + * @param[in] dev_id device id + * @param[out] entry fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_fdb_first(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_fdb_first(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Find a particular Fdb entry from device through mac address. + * @details Comments: + For input parameter only addr field in entry is meaning. + * @param[in] dev_id device id + * @param[in] entry fdb entry + * @param[out] entry fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_fdb_find(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_fdb_find(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dynamic address learning status on a particular port. + * @details Comments: + * This operation will enable or disable dynamic address learning + * feature on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable enable or disable + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_fdb_port_learn_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_fdb_port_learn_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dynamic address learning status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_fdb_port_learn_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_fdb_port_learn_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dynamic address aging status on particular device. + * @details Comments: + * This operation will enable or disable dynamic address aging + * feature on particular device. + * @param[in] dev_id device id + * @param[in] enable enable or disable + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_fdb_age_ctrl_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_fdb_age_ctrl_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dynamic address aging status on particular device. + * @param[in] dev_id device id + * @param[in] enable enable or disable + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_fdb_age_ctrl_get(a_uint32_t dev_id, a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_fdb_age_ctrl_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dynamic address aging time on a particular device. + * @details Comments: + * This operation will set dynamic address aging time on a particular device. + * The unit of time is second. Because different device has differnet + * hardware granularity function will return actual time in hardware. + * @param[in] dev_id device id + * @param time aging time + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_fdb_age_time_set(a_uint32_t dev_id, a_uint32_t * time) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_fdb_age_time_set(dev_id, time); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dynamic address aging time on a particular device. + * @param[in] dev_id device id + * @param[out] time aging time + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_fdb_age_time_get(a_uint32_t dev_id, a_uint32_t *time) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_fdb_age_time_get(dev_id, time); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +garuda_fdb_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->fdb_add = garuda_fdb_add; + p_api->fdb_del_all = garuda_fdb_del_all; + p_api->fdb_del_by_port = garuda_fdb_del_by_port; + p_api->fdb_del_by_mac = garuda_fdb_del_by_mac; + p_api->fdb_first = garuda_fdb_first; + p_api->fdb_next = garuda_fdb_next; + p_api->fdb_find = garuda_fdb_find; + p_api->port_learn_set = garuda_fdb_port_learn_set; + p_api->port_learn_get = garuda_fdb_port_learn_get; + p_api->age_ctrl_set = garuda_fdb_age_ctrl_set; + p_api->age_ctrl_get = garuda_fdb_age_ctrl_get; + p_api->age_time_set = garuda_fdb_age_time_set; + p_api->age_time_get = garuda_fdb_age_time_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_igmp.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_igmp.c new file mode 100755 index 000000000..5f95f70c8 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_igmp.c @@ -0,0 +1,610 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 garuda_igmp GARUDA_IGMP + * @{ + */ + +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "garuda_igmp.h" +#include "garuda_reg.h" + +static sw_error_t +_garuda_port_igmps_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, IGMP_MLD_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_garuda_port_igmps_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, IGMP_MLD_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_garuda_igmp_mld_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_MAC_CPY_TO_CPU == cmd) + { + val = 1; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + val = 0; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, QM_CTL, 0, IGMP_COPY_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_garuda_igmp_mld_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, QM_CTL, 0, IGMP_COPY_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *cmd = FAL_MAC_CPY_TO_CPU; + } + else + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + + return SW_OK; +} + +static sw_error_t +_garuda_port_igmp_mld_join_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, JOIN_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + + +static sw_error_t +_garuda_port_igmp_mld_join_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, JOIN_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + + +static sw_error_t +_garuda_port_igmp_mld_leave_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, LEAVE_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + + +static sw_error_t +_garuda_port_igmp_mld_leave_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, LEAVE_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + + +static sw_error_t +_garuda_igmp_mld_rp_set(a_uint32_t dev_id, fal_pbmp_t pts) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_mports_validity_check(dev_id, pts)) + { + return SW_BAD_PARAM; + } + val = pts; + HSL_REG_FIELD_SET(rv, dev_id, FLOOD_MASK, 0, IGMP_DP, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + + +static sw_error_t +_garuda_igmp_mld_rp_get(a_uint32_t dev_id, fal_pbmp_t * pts) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FLOOD_MASK, 0, IGMP_DP, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *pts = val; + return SW_OK; +} + + +static sw_error_t +_garuda_igmp_mld_entry_creat_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, QM_CTL, 0, IGMP_CREAT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_garuda_igmp_mld_entry_creat_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, QM_CTL, 0, IGMP_CREAT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +/** + * @brief Set igmp/mld packets snooping status on a particular port. + * @details Comments: + * After enabling igmp/mld snooping feature on a particular port all kinds + * igmp/mld packets received on this port would be acknowledged by hardware. + * Particular forwarding decision could be setted by fal_igmp_mld_cmd_set. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_igmps_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_igmps_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld packets snooping status on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_igmps_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_igmps_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmp/mld packets forwarding command on a particular device. + * @details Comments: + * Particular device may only support parts of forwarding commands. + * This operation will take effect only after enabling igmp/mld snooping + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_igmp_mld_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_igmp_mld_cmd_set(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld packets forwarding command on a particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_igmp_mld_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_igmp_mld_cmd_get(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmp/mld join packets hardware acknowledgement status on particular port. + * @details Comments: + * After enabling igmp/mld join feature on a particular port hardware will + * dynamic learning or changing multicast entry. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_igmp_mld_join_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_igmp_mld_join_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld join packets hardware acknowledgement status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_igmp_mld_join_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_igmp_mld_join_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmp/mld leave packets hardware acknowledgement status on a particular port. + * @details Comments: + * After enabling igmp join feature on a particular port hardware will dynamic + * deleting or changing multicast entry. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_igmp_mld_leave_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_igmp_mld_leave_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld leave packets hardware acknowledgement status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_igmp_mld_leave_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_igmp_mld_leave_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmp/mld router ports on a particular device. + * @details Comments: + * After enabling igmp/mld join/leave feature on a particular port igmp/mld + * join/leave packets received on this port will be forwarded to router ports. + * @param[in] dev_id device id + * @param[in] pts dedicates ports + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_igmp_mld_rp_set(a_uint32_t dev_id, fal_pbmp_t pts) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_igmp_mld_rp_set(dev_id, pts); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld router ports on a particular device. + * @param[in] dev_id device id + * @param[out] pts dedicates ports + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_igmp_mld_rp_get(a_uint32_t dev_id, fal_pbmp_t * pts) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_igmp_mld_rp_get(dev_id, pts); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set the status of creating multicast entry during igmp/mld join/leave procedure. + * @details Comments: + * After enabling igmp/mld join/leave feature on a particular port if enable + * entry creat hardware will dynamic creat and delete multicast entry, + * otherwise hardware only can change destination ports of existing muticast entry. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_igmp_mld_entry_creat_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_igmp_mld_entry_creat_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get the status of creating multicast entry during igmp/mld join/leave procedure. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_igmp_mld_entry_creat_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_igmp_mld_entry_creat_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +garuda_igmp_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->port_igmps_status_set = garuda_port_igmps_status_set; + p_api->port_igmps_status_get = garuda_port_igmps_status_get; + p_api->igmp_mld_cmd_set = garuda_igmp_mld_cmd_set; + p_api->igmp_mld_cmd_get = garuda_igmp_mld_cmd_get; + p_api->port_igmp_join_set = garuda_port_igmp_mld_join_set; + p_api->port_igmp_join_get = garuda_port_igmp_mld_join_get; + p_api->port_igmp_leave_set = garuda_port_igmp_mld_leave_set; + p_api->port_igmp_leave_get = garuda_port_igmp_mld_leave_get; + p_api->igmp_rp_set = garuda_igmp_mld_rp_set; + p_api->igmp_rp_get = garuda_igmp_mld_rp_get; + p_api->igmp_entry_creat_set = garuda_igmp_mld_entry_creat_set; + p_api->igmp_entry_creat_get = garuda_igmp_mld_entry_creat_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_init.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_init.c new file mode 100755 index 000000000..eeef514c5 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_init.c @@ -0,0 +1,642 @@ +/* + * Copyright (c) 2012, 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 garuda_init GARUDA_INIT + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "garuda_mib.h" +#include "garuda_port_ctrl.h" +#include "garuda_portvlan.h" +#include "garuda_vlan.h" +#include "garuda_fdb.h" +#include "garuda_qos.h" +#include "garuda_mirror.h" +#include "garuda_stp.h" +#include "garuda_rate.h" +#include "garuda_misc.h" +#include "garuda_leaky.h" +#include "garuda_igmp.h" +#include "garuda_acl.h" +#include "garuda_led.h" +#include "garuda_reg_access.h" +#include "garuda_reg.h" +#include "garuda_init.h" +#include "f1_phy.h" + +static ssdk_init_cfg * garuda_cfg[SW_MAX_NR_DEV] = { 0 }; + +#if !(defined(KERNEL_MODULE) && defined(USER_MODE)) +static sw_error_t +garuda_portproperty_init(a_uint32_t dev_id, hsl_init_mode mode) +{ + hsl_port_prop_t p_type; + hsl_dev_t *pdev = NULL; + fal_port_t port_id; + + pdev = hsl_dev_ptr_get(dev_id); + if (pdev == NULL) + return SW_NOT_INITIALIZED; + + for (port_id = 0; port_id < pdev->nr_ports; port_id++) + { + hsl_port_prop_portmap_set(dev_id, port_id); + + for (p_type = HSL_PP_PHY; p_type < HSL_PP_BUTT; p_type++) + { + if (HSL_NO_CPU == mode) + { + SW_RTN_ON_ERROR(hsl_port_prop_set(dev_id, port_id, p_type)); + continue; + } + + switch (p_type) + { + case HSL_PP_PHY: + if (HSL_CPU_1 != mode) + { + if ((port_id != pdev->cpu_port_nr) + && (port_id != (pdev->nr_ports -1))) + { + SW_RTN_ON_ERROR(hsl_port_prop_set(dev_id, port_id, p_type)); + } + } + else + { + if (port_id != pdev->cpu_port_nr) + { + SW_RTN_ON_ERROR(hsl_port_prop_set(dev_id, port_id, p_type)); + } + } + break; + + case HSL_PP_INCL_CPU: + /* include cpu port but exclude wan port in some cases */ + if (!((HSL_CPU_2 == mode) && (port_id == (pdev->nr_ports - 1)))) + SW_RTN_ON_ERROR(hsl_port_prop_set(dev_id, port_id, p_type)); + + break; + + case HSL_PP_EXCL_CPU: + /* exclude cpu port and wan port in some cases */ + if ((port_id != pdev->cpu_port_nr) + && (!((HSL_CPU_2 == mode) && (port_id == (pdev->nr_ports - 1))))) + SW_RTN_ON_ERROR(hsl_port_prop_set(dev_id, port_id, p_type)); + break; + + default: + break; + } + } + + if (HSL_NO_CPU == mode) + { + SW_RTN_ON_ERROR(hsl_port_prop_set_phyid + (dev_id, port_id, port_id + 1)); + } + else + { + if (port_id != pdev->cpu_port_nr) + { + SW_RTN_ON_ERROR(hsl_port_prop_set_phyid + (dev_id, port_id, port_id - 1)); + } + } + } + + return SW_OK; +} + +static void +phy_dport_set(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t dport_addr, a_uint16_t val_mask) +{ + a_uint16_t phy_data; + sw_error_t rv; + + HSL_PHY_SET(rv, dev_id, phy_id, F1_DEBUG_PORT_ADDRESS, dport_addr); + HSL_PHY_GET(rv, dev_id, phy_id, F1_DEBUG_PORT_DATA, &phy_data); + phy_data |= val_mask; + HSL_PHY_SET(rv, dev_id, phy_id, F1_DEBUG_PORT_DATA, phy_data); +} + +static void +phy_dport_clear(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t dport_addr, a_uint16_t val_mask) +{ + a_uint16_t phy_data; + sw_error_t rv; + + HSL_PHY_SET(rv, dev_id, phy_id, F1_DEBUG_PORT_ADDRESS, dport_addr); + HSL_PHY_GET(rv, dev_id, phy_id, F1_DEBUG_PORT_DATA, &phy_data); + phy_data &= ~val_mask; + HSL_PHY_SET(rv, dev_id, phy_id, F1_DEBUG_PORT_DATA, phy_data); +} + +static sw_error_t +garuda_hw_init(a_uint32_t dev_id, ssdk_init_cfg *cfg) +{ + garuda_init_spec_cfg *garuda_init_cfg = NULL; + hsl_dev_t *pdev = NULL; + hsl_init_mode cpu_mode; + a_uint32_t port_id; + a_uint32_t data; + sw_error_t rv; + + pdev = hsl_dev_ptr_get(dev_id); + if (NULL == pdev) + { + return SW_NOT_INITIALIZED; + } + cpu_mode = cfg->cpu_mode; + + HSL_REG_ENTRY_GET(rv, dev_id, POSTRIP, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* phy pll on */ + SW_SET_REG_BY_FIELD(POSTRIP, PHY_PLL_ON, 1, data); + + garuda_init_cfg = (garuda_init_spec_cfg* )(cfg->chip_spec_cfg); + if (!garuda_init_cfg) + { + return SW_BAD_PARAM; + } + + /* delay */ + if (A_TRUE == garuda_init_cfg->rx_delay_s1) + { + SW_SET_REG_BY_FIELD(POSTRIP, RXDELAY_S1, 1, data); + } + else + { + SW_SET_REG_BY_FIELD(POSTRIP, RXDELAY_S1, 0, data); + } + + if (A_TRUE == garuda_init_cfg->rx_delay_s0) + { + SW_SET_REG_BY_FIELD(POSTRIP, RXDELAY_S0, 1, data); + } + else + { + SW_SET_REG_BY_FIELD(POSTRIP, RXDELAY_S0, 0, data); + } + + if (A_TRUE == garuda_init_cfg->tx_delay_s1) + { + SW_SET_REG_BY_FIELD(POSTRIP, TXDELAY_S1, 1, data); + } + else + { + SW_SET_REG_BY_FIELD(POSTRIP, TXDELAY_S1, 0, data); + } + + if (A_TRUE == garuda_init_cfg->tx_delay_s0) + { + SW_SET_REG_BY_FIELD(POSTRIP, TXDELAY_S0, 1, data); + } + else + { + SW_SET_REG_BY_FIELD(POSTRIP, TXDELAY_S0, 0, data); + } + + /* tx/rx delay enable */ + if (A_TRUE == garuda_init_cfg->rgmii_txclk_delay) + { + SW_SET_REG_BY_FIELD(POSTRIP, RGMII_TXCLK_DELAY_EN, 1, data); + } + else + { + SW_SET_REG_BY_FIELD(POSTRIP, RGMII_TXCLK_DELAY_EN, 0, data); + } + + /* tx/rx delay enable */ + if (A_TRUE == garuda_init_cfg->rgmii_rxclk_delay) + { + SW_SET_REG_BY_FIELD(POSTRIP, RGMII_RXCLK_DELAY_EN, 1, data); + } + else + { + SW_SET_REG_BY_FIELD(POSTRIP, RGMII_RXCLK_DELAY_EN, 0, data); + } + + /* mac5 default mode */ + /*SW_SET_REG_BY_FIELD(POSTRIP, MAC5_PHY_MODE, 0, data); + SW_SET_REG_BY_FIELD(POSTRIP, MAC5_MAC_MODE, 0, data);*/ + + /* mac0 default phy mode */ + SW_SET_REG_BY_FIELD(POSTRIP, MAC0_MAC_MODE, 0, data); + + /* mac0 default rgmii mode */ + SW_SET_REG_BY_FIELD(POSTRIP, MAC0_RGMII_EN, 1, data); + SW_SET_REG_BY_FIELD(POSTRIP, MAC0_GMII_EN, 0, data); + + /* mac5 default disable mode */ + SW_SET_REG_BY_FIELD(POSTRIP, MAC5_PHY_MODE, 0, data); + SW_SET_REG_BY_FIELD(POSTRIP, MAC5_MAC_MODE, 0, data); + + /* phy default mode */ + SW_SET_REG_BY_FIELD(POSTRIP, PHY4_RGMII_EN, 0, data); + SW_SET_REG_BY_FIELD(POSTRIP, PHY4_GMII_EN, 0, data); + + /* modify default mode */ + if (A_FALSE == garuda_init_cfg->mac0_rgmii) + { + SW_SET_REG_BY_FIELD(POSTRIP, MAC0_RGMII_EN, 0, data); + SW_SET_REG_BY_FIELD(POSTRIP, MAC0_GMII_EN, 1, data); + + /*invert clock output for port0 gmii pad.*/ + a_uint32_t temp; + HSL_REG_ENTRY_GET(rv, dev_id, MASK_CTL, 0, + (a_uint8_t *) (&temp), sizeof (a_uint32_t)); + temp |= 1<mac5_rgmii) + { + + SW_SET_REG_BY_FIELD(POSTRIP, PHY4_RGMII_EN, 1, data); + SW_SET_REG_BY_FIELD(POSTRIP, PHY4_GMII_EN, 0, data); + + a_uint32_t phy_id = 4; + /* phy4 rgmii mode enable */ + phy_dport_set(dev_id, phy_id, F1_DEBUG_PORT_RGMII_MODE, F1_DEBUG_PORT_RGMII_MODE_EN); + + /* Rx delay enable */ + if (A_TRUE == garuda_init_cfg->phy4_rx_delay) + { + phy_dport_set(dev_id, phy_id, F1_DEBUG_PORT_RX_DELAY, F1_DEBUG_PORT_RX_DELAY_EN); + } + else + { + phy_dport_clear(dev_id, phy_id, F1_DEBUG_PORT_RX_DELAY, F1_DEBUG_PORT_RX_DELAY_EN); + } + + /* Tx delay enable */ + if (A_TRUE == garuda_init_cfg->phy4_tx_delay) + { + phy_dport_set(dev_id, phy_id, F1_DEBUG_PORT_TX_DELAY, F1_DEBUG_PORT_TX_DELAY_EN); + } + else + { + phy_dport_clear(dev_id, phy_id, F1_DEBUG_PORT_TX_DELAY, F1_DEBUG_PORT_TX_DELAY_EN); + } + + } + else + { + SW_SET_REG_BY_FIELD(POSTRIP, PHY4_RGMII_EN, 0, data); + SW_SET_REG_BY_FIELD(POSTRIP, PHY4_GMII_EN, 1, data); + } + } + else if (HSL_CPU_1 == cpu_mode) + { + //SW_SET_REG_BY_FIELD(POSTRIP, TXDELAY_S0, 0, data); + + } + else if (HSL_CPU_1_PLUS == cpu_mode) + { + SW_SET_REG_BY_FIELD(POSTRIP, MAC5_MAC_MODE, 1, data); + + } + else if (HSL_NO_CPU == cpu_mode) + { + + } + + HSL_REG_ENTRY_SET(rv, dev_id, POSTRIP, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + for (port_id = 0; port_id < pdev->nr_ports; port_id++) + { + if (port_id == pdev->cpu_port_nr) + { + continue; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 1, data); + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +static sw_error_t +garuda_bist_test(a_uint32_t dev_id) +{ + a_uint32_t entry, data, i; + sw_error_t rv; + + data = 1; + i = 0x1000; + while (data && --i) + { + HSL_REG_ENTRY_GET(rv, dev_id, BIST_CTRL, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + SW_GET_FIELD_BY_REG(BIST_CTRL, BIST_BUSY, data, entry); + aos_udelay(5); + } + + if (0 == i) + { + return SW_INIT_ERROR; + } + + entry = 0; + SW_SET_REG_BY_FIELD(BIST_CTRL, BIST_BUSY, 1, entry); + SW_SET_REG_BY_FIELD(BIST_CTRL, PTN_EN2, 1, entry); + SW_SET_REG_BY_FIELD(BIST_CTRL, PTN_EN1, 1, entry); + SW_SET_REG_BY_FIELD(BIST_CTRL, PTN_EN0, 1, entry); + + HSL_REG_ENTRY_SET(rv, dev_id, BIST_CTRL, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data = 1; + i = 0x1000; + while (data && --i) + { + HSL_REG_ENTRY_GET(rv, dev_id, BIST_CTRL, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + SW_GET_FIELD_BY_REG(BIST_CTRL, BIST_BUSY, data, entry); + aos_udelay(5); + } + + if (0 == i) + { + return SW_INIT_ERROR; + } + + SW_GET_FIELD_BY_REG(BIST_CTRL, ERR_CNT, data, entry); + if (data) + { + SW_GET_FIELD_BY_REG(BIST_CTRL, ONE_ERR, data, entry); + if (!data) + { + return SW_INIT_ERROR; + } + + SW_GET_FIELD_BY_REG(BIST_CTRL, ERR_ADDR, data, entry); + + entry = 0; + SW_SET_REG_BY_FIELD(BIST_RCV, RCV_EN, 1, entry); + SW_SET_REG_BY_FIELD(BIST_RCV, RCV_ADDR, data, entry); + HSL_REG_ENTRY_SET(rv, dev_id, BIST_RCV, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else + { + return SW_OK; + } + + entry = 0; + SW_SET_REG_BY_FIELD(BIST_CTRL, BIST_BUSY, 1, entry); + SW_SET_REG_BY_FIELD(BIST_CTRL, PTN_EN2, 1, entry); + SW_SET_REG_BY_FIELD(BIST_CTRL, PTN_EN1, 1, entry); + SW_SET_REG_BY_FIELD(BIST_CTRL, PTN_EN0, 1, entry); + + HSL_REG_ENTRY_SET(rv, dev_id, BIST_CTRL, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data = 1; + i = 0x1000; + while (data && --i) + { + HSL_REG_ENTRY_GET(rv, dev_id, BIST_CTRL, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + SW_GET_FIELD_BY_REG(BIST_CTRL, BIST_BUSY, data, entry); + aos_udelay(5); + } + + if (0 == i) + { + return SW_INIT_ERROR; + } + + SW_GET_FIELD_BY_REG(BIST_CTRL, ERR_CNT, data, entry); + if (data) + { + return SW_INIT_ERROR; + } + + return SW_OK; +} + + +#endif + +static sw_error_t +garuda_dev_init(a_uint32_t dev_id, hsl_init_mode cpu_mode) +{ + hsl_dev_t *pdev = NULL; + + pdev = hsl_dev_ptr_get(dev_id); + if (pdev == NULL) + return SW_NOT_INITIALIZED; + + pdev->nr_ports = 6; + pdev->nr_phy = 5; + pdev->cpu_port_nr = 0; + pdev->nr_vlans = 4096; + pdev->hw_vlan_query = A_TRUE; + pdev->nr_queue = 4; + pdev->cpu_mode = cpu_mode; + + return SW_OK; +} + +static sw_error_t +_garuda_reset(a_uint32_t dev_id) +{ +#if !(defined(KERNEL_MODULE) && defined(USER_MODE)) + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + val = 0x1; + HSL_REG_FIELD_SET(rv, dev_id, MASK_CTL, 0, SOFT_RST, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = garuda_hw_init(dev_id, garuda_cfg[dev_id]); + SW_RTN_ON_ERROR(rv); + + GARUDA_ACL_RESET(rv, dev_id); +#endif + + return SW_OK; +} + +sw_error_t +garuda_cleanup(a_uint32_t dev_id) +{ + if (garuda_cfg[dev_id]) + { + aos_mem_free(garuda_cfg[dev_id]); + garuda_cfg[dev_id] = NULL; + } + + return SW_OK; +} + +/** + * @brief reset hsl layer. + * @details Comments: + * This operation will reset hsl layer + * @param[in] dev_id device id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_reset(a_uint32_t dev_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_reset(dev_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Init hsl layer. + * @details Comments: + * This operation will init hsl layer and hsl layer + * @param[in] dev_id device id + * @param[in] cfg configuration for initialization + * @return SW_OK or error code + */ +sw_error_t +garuda_init(a_uint32_t dev_id, ssdk_init_cfg *cfg) +{ + a_uint8_t *p_mem; + + HSL_DEV_ID_CHECK(dev_id); + + p_mem = (a_uint8_t *)garuda_cfg[dev_id]; + if (NULL == p_mem) + { + p_mem = aos_mem_alloc(sizeof (ssdk_init_cfg) + + sizeof(garuda_init_spec_cfg)); + garuda_cfg[dev_id] = (ssdk_init_cfg *)p_mem; + garuda_cfg[dev_id]->chip_spec_cfg = (garuda_init_spec_cfg *) + (p_mem + sizeof (ssdk_init_cfg)); + } + + if (NULL == p_mem) + { + return SW_OUT_OF_MEM; + } + + aos_mem_copy(garuda_cfg[dev_id]->chip_spec_cfg, + cfg->chip_spec_cfg, sizeof (garuda_init_spec_cfg)); + aos_mem_copy(garuda_cfg[dev_id], cfg, sizeof (ssdk_init_cfg)); + garuda_cfg[dev_id]->chip_spec_cfg = (garuda_init_spec_cfg *) + (p_mem + sizeof (ssdk_init_cfg)); + + SW_RTN_ON_ERROR(garuda_reg_access_init(dev_id, cfg->reg_mode)); + + SW_RTN_ON_ERROR(garuda_dev_init(dev_id, cfg->cpu_mode)); + +#if !(defined(KERNEL_MODULE) && defined(USER_MODE)) + { + a_uint32_t i, entry; + sw_error_t rv; + + if(HSL_MDIO == cfg->reg_mode) + { + SW_RTN_ON_ERROR(garuda_bist_test(dev_id)); + + entry = 0x1; + HSL_REG_FIELD_SET(rv, dev_id, MASK_CTL, 0, SOFT_RST, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + i = 0x10; + do + { + HSL_REG_FIELD_GET(rv, dev_id, MASK_CTL, 0, SOFT_RST, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + aos_mdelay(10); + } + while (entry && --i); + + if (0 == i) + { + return SW_INIT_ERROR; + } + } + SW_RTN_ON_ERROR(hsl_port_prop_init(dev_id)); + SW_RTN_ON_ERROR(hsl_port_prop_init_by_dev(dev_id)); + SW_RTN_ON_ERROR(garuda_portproperty_init(dev_id, cfg->cpu_mode)); + + GARUDA_MIB_INIT(rv, dev_id); + GARUDA_PORT_CTRL_INIT(rv, dev_id); + GARUDA_PORTVLAN_INIT(rv, dev_id); + GARUDA_VLAN_INIT(rv, dev_id); + GARUDA_FDB_INIT(rv, dev_id); + GARUDA_QOS_INIT(rv, dev_id); + GARUDA_STP_INIT(rv, dev_id); + GARUDA_MIRR_INIT(rv, dev_id); + GARUDA_RATE_INIT(rv, dev_id); + GARUDA_MISC_INIT(rv, dev_id); + GARUDA_LEAKY_INIT(rv, dev_id); + GARUDA_IGMP_INIT(rv, dev_id); + GARUDA_ACL_INIT(rv, dev_id); + GARUDA_LED_INIT(rv, dev_id); + + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->dev_reset = garuda_reset; + p_api->dev_clean = garuda_cleanup; + } + + if(cfg->reg_mode == HSL_MDIO) + { + SW_RTN_ON_ERROR(garuda_hw_init(dev_id, cfg)); + } + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_leaky.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_leaky.c new file mode 100755 index 000000000..5969fa189 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_leaky.c @@ -0,0 +1,531 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 garuda_leaky GARUDA_LEAKY + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "garuda_leaky.h" +#include "garuda_reg.h" + +static sw_error_t +_garuda_uc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_LEAKY_PORT_CTRL == ctrl_mode) + { + data = 0; + } + else if (FAL_LEAKY_FDB_CTRL == ctrl_mode) + { + data = 1; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FLOOD_MASK, 0, ARL_UNI_LEAKY, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_garuda_uc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t *ctrl_mode) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FLOOD_MASK, 0, ARL_UNI_LEAKY, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *ctrl_mode = FAL_LEAKY_FDB_CTRL; + } + else + { + *ctrl_mode = FAL_LEAKY_PORT_CTRL; + } + + return SW_OK; +} + +static sw_error_t +_garuda_mc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_LEAKY_PORT_CTRL == ctrl_mode) + { + data = 0; + } + else if (FAL_LEAKY_FDB_CTRL == ctrl_mode) + { + data = 1; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FLOOD_MASK, 0, ARL_MUL_LEAKY, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + + + +static sw_error_t +_garuda_mc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t *ctrl_mode) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FLOOD_MASK, 0, ARL_MUL_LEAKY, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *ctrl_mode = FAL_LEAKY_FDB_CTRL; + } + else + { + *ctrl_mode = FAL_LEAKY_PORT_CTRL; + } + + return SW_OK; +} + + +static sw_error_t +_garuda_port_arp_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_BASE_VLAN, port_id, ARP_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + + +static sw_error_t +_garuda_port_arp_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_BASE_VLAN, port_id, ARP_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_garuda_port_uc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_BASE_VLAN, port_id, UNI_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_garuda_port_uc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_BASE_VLAN, port_id, UNI_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_garuda_port_mc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_BASE_VLAN, port_id, MUL_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_garuda_port_mc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_BASE_VLAN, port_id, MUL_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +/** +* @brief Set unicast packets leaky control mode on a particular device. +* @param[in] dev_id device id +* @param[in] ctrl_mode leaky control mode +* @return SW_OK or error code +*/ +HSL_LOCAL sw_error_t +garuda_uc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_uc_leaky_mode_set(dev_id, ctrl_mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get unicast packets leaky control mode on a particular device. + * @param[in] dev_id device id + * @param[out] ctrl_mode leaky control mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_uc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t *ctrl_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_uc_leaky_mode_get(dev_id, ctrl_mode); + HSL_API_UNLOCK; + return rv; +} + +/** +* @brief Set multicast packets leaky control mode on a particular device. +* @param[in] dev_id device id +* @param[in] ctrl_mode leaky control mode +* @return SW_OK or error code +*/ +HSL_LOCAL sw_error_t +garuda_mc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_mc_leaky_mode_set(dev_id, ctrl_mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get multicast packets leaky control mode on a particular device. + * @param[in] dev_id device id + * @param[out] ctrl_mode leaky control mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_mc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t *ctrl_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_mc_leaky_mode_get(dev_id, ctrl_mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set arp packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_arp_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_arp_leaky_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_arp_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_arp_leaky_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set unicast packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_uc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_uc_leaky_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get unicast packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_uc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_uc_leaky_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set multicast packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_mc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_mc_leaky_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get multicast packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_mc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_mc_leaky_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +garuda_leaky_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->uc_leaky_mode_set = garuda_uc_leaky_mode_set; + p_api->uc_leaky_mode_get = garuda_uc_leaky_mode_get; + p_api->mc_leaky_mode_set = garuda_mc_leaky_mode_set; + p_api->mc_leaky_mode_get = garuda_mc_leaky_mode_get; + p_api->port_arp_leaky_set = garuda_port_arp_leaky_set; + p_api->port_arp_leaky_get = garuda_port_arp_leaky_get; + p_api->port_uc_leaky_set = garuda_port_uc_leaky_set; + p_api->port_uc_leaky_get = garuda_port_uc_leaky_get; + p_api->port_mc_leaky_set = garuda_port_mc_leaky_set; + p_api->port_mc_leaky_get = garuda_port_mc_leaky_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_led.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_led.c new file mode 100755 index 000000000..f69b2a97b --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_led.c @@ -0,0 +1,370 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 garuda_led GARUDA_LED + * @{ + */ + +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "garuda_led.h" +#include "garuda_reg.h" + +#define MAX_LED_PATTERN_ID 2 +#define LED_PATTERN_ADDR 0xB0 + + +static sw_error_t +_garuda_led_ctrl_pattern_set(a_uint32_t dev_id, led_pattern_group_t group, + led_pattern_id_t id, led_ctrl_pattern_t * pattern) +{ + a_uint32_t data = 0, reg; + a_uint32_t addr; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if ((LED_LAN_PORT_GROUP != group) && (LED_WAN_PORT_GROUP != group)) + { + return SW_NOT_SUPPORTED; + } + + if (id > MAX_LED_PATTERN_ID) + { + return SW_BAD_PARAM; + } + + addr = LED_PATTERN_ADDR + (id << 2); + + if (LED_ALWAYS_OFF == pattern->mode) + { + SW_SET_REG_BY_FIELD(LED_CTRL, PATTERN_EN, 0, data); + } + else if (LED_ALWAYS_BLINK == pattern->mode) + { + SW_SET_REG_BY_FIELD(LED_CTRL, PATTERN_EN, 1, data); + } + else if (LED_ALWAYS_ON == pattern->mode) + { + SW_SET_REG_BY_FIELD(LED_CTRL, PATTERN_EN, 2, data); + } + else if (LED_PATTERN_MAP_EN == pattern->mode) + { + SW_SET_REG_BY_FIELD(LED_CTRL, PATTERN_EN, 3, data); + } + else + { + return SW_BAD_PARAM; + } + + if (pattern->map & (1 << FULL_DUPLEX_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, FULL_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << HALF_DUPLEX_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, HALF_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << POWER_ON_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, POWERON_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << LINK_1000M_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, GE_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << LINK_100M_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, FE_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << LINK_10M_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, ETH_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << COLLISION_BLINK_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, COL_BLINK_EN, 1, data); + } + + if (pattern->map & (1 << RX_TRAFFIC_BLINK_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, RX_BLINK_EN, 1, data); + } + + if (pattern->map & (1 << TX_TRAFFIC_BLINK_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, TX_BLINK_EN, 1, data); + } + + if (pattern->map & (1 << LINKUP_OVERRIDE_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, LINKUP_OVER_EN, 1, data); + } + else + { + SW_SET_REG_BY_FIELD(LED_CTRL, LINKUP_OVER_EN, 0, data); + } + + if (LED_BLINK_2HZ == pattern->freq) + { + SW_SET_REG_BY_FIELD(LED_CTRL, BLINK_FREQ, 0, data); + } + else if (LED_BLINK_4HZ == pattern->freq) + { + SW_SET_REG_BY_FIELD(LED_CTRL, BLINK_FREQ, 1, data); + } + else if (LED_BLINK_8HZ == pattern->freq) + { + SW_SET_REG_BY_FIELD(LED_CTRL, BLINK_FREQ, 2, data); + } + else if (LED_BLINK_TXRX == pattern->freq) + { + SW_SET_REG_BY_FIELD(LED_CTRL, BLINK_FREQ, 3, data); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (LED_LAN_PORT_GROUP == group) + { + reg &= 0xffff0000; + reg |= data; + } + else + { + reg &= 0xffff; + reg |= (data << 16); + } + + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_garuda_led_ctrl_pattern_get(a_uint32_t dev_id, led_pattern_group_t group, + led_pattern_id_t id, led_ctrl_pattern_t * pattern) +{ + a_uint32_t data = 0, reg, tmp; + a_uint32_t addr; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (group >= LED_GROUP_BUTT) + { + return SW_BAD_PARAM; + } + + if (id > MAX_LED_PATTERN_ID) + { + return SW_BAD_PARAM; + } + + aos_mem_zero(pattern, sizeof(led_ctrl_pattern_t)); + + addr = LED_PATTERN_ADDR + (id << 2); + + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (LED_LAN_PORT_GROUP == group) + { + data = reg & 0xffff; + } + else + { + data = (reg >> 16) & 0xffff; + } + + SW_GET_FIELD_BY_REG(LED_CTRL, PATTERN_EN, tmp, data); + if (0 == tmp) + { + pattern->mode = LED_ALWAYS_OFF; + } + else if (1 == tmp) + { + pattern->mode = LED_ALWAYS_BLINK; + } + else if (2 == tmp) + { + pattern->mode = LED_ALWAYS_ON; + } + else + { + pattern->mode = LED_PATTERN_MAP_EN; + } + + SW_GET_FIELD_BY_REG(LED_CTRL, FULL_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << FULL_DUPLEX_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, HALF_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << HALF_DUPLEX_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, POWERON_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << POWER_ON_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, GE_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << LINK_1000M_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, FE_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << LINK_100M_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, ETH_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << LINK_10M_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, COL_BLINK_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << COLLISION_BLINK_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, RX_BLINK_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << RX_TRAFFIC_BLINK_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, TX_BLINK_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << TX_TRAFFIC_BLINK_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, LINKUP_OVER_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << LINKUP_OVERRIDE_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, BLINK_FREQ, tmp, data); + if (0 == tmp) + { + pattern->freq = LED_BLINK_2HZ; + } + else if (1 == tmp) + { + pattern->freq = LED_BLINK_4HZ; + } + else if (2 == tmp) + { + pattern->freq = LED_BLINK_8HZ; + } + else + { + pattern->freq = LED_BLINK_TXRX; + } + + return SW_OK; +} + +/** +* @brief Set led control pattern on a particular device. +* @param[in] dev_id device id +* @param[in] group pattern group, lan or wan +* @param[in] id pattern id +* @param[in] pattern led control pattern +* @return SW_OK or error code +*/ +HSL_LOCAL sw_error_t +garuda_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; + + HSL_API_LOCK; + rv = _garuda_led_ctrl_pattern_set(dev_id, group, id, pattern); + HSL_API_UNLOCK; + return rv; +} + +/** +* @brief Get led control pattern on a particular device. +* @param[in] dev_id device id +* @param[in] group pattern group, lan or wan +* @param[in] id pattern id +* @param[out] pattern led control pattern +* @return SW_OK or error code +*/ +HSL_LOCAL sw_error_t +garuda_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; + + HSL_API_LOCK; + rv = _garuda_led_ctrl_pattern_get(dev_id, group, id, pattern); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +garuda_led_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->led_ctrl_pattern_set = garuda_led_ctrl_pattern_set; + p_api->led_ctrl_pattern_get = garuda_led_ctrl_pattern_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_mib.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_mib.c new file mode 100755 index 000000000..9e1fe747b --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_mib.c @@ -0,0 +1,378 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 garuda_mib GARUDA_MIB + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "garuda_mib.h" +#include "garuda_reg.h" + +static sw_error_t +_garuda_get_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info) +{ + a_uint32_t val; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_OUT_OF_RANGE; + } + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBROAD, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxBroad = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXPAUSE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxPause = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXMULTI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxMulti = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXFCSERR, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxFcsErr = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXALLIGNERR, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxAllignErr = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXRUNT, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxRunt = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXFRAGMENT, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxFragment = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX64BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx64Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX128BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx128Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX256BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx256Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX512BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx512Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX1024BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx1024Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX1518BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx1518Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXMAXBYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxMaxByte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXTOOLONG, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxTooLong = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXGOODBYTE_LO, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxGoodByte_lo = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXGOODBYTE_HI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxGoodByte_hi = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBADBYTE_LO, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxBadByte_lo = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBADBYTE_HI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxBadByte_hi = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXOVERFLOW, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxOverFlow = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_FILTERED, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Filtered = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBROAD, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxBroad = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXPAUSE, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxPause = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMULTI, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxMulti = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXUNDERRUN, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxUnderRun = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX64BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx64Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX128BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx128Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX256BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx256Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX512BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx512Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX1024BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx1024Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX1518BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx1518Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMAXBYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxMaxByte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXOVERSIZE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxOverSize = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBYTE_LO, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxByte_lo = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBYTE_HI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxByte_hi = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXCOLLISION, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxCollision = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXABORTCOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxAbortCol = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMULTICOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxMultiCol = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXSINGALCOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxSingalCol = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXEXCDEFER, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxExcDefer = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXDEFER, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxDefer = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXLATECOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxLateCol = val; + + return SW_OK; +} + +static sw_error_t +_garuda_mib_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, MIB_FUNC, 0, MIB_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_garuda_mib_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, MIB_FUNC, 0, MIB_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +/** + * @brief Get mib infomation on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mib_info mib infomation + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_get_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_get_mib_info(dev_id, port_id, mib_info); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set mib status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_mib_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_mib_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mib status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_mib_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_mib_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +garuda_mib_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->get_mib_info = garuda_get_mib_info; + p_api->mib_status_set = garuda_mib_status_set; + p_api->mib_status_get = garuda_mib_status_get; +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_mirror.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_mirror.c new file mode 100755 index 000000000..88b78f184 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_mirror.c @@ -0,0 +1,318 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 garuda_mirror GARUDA_MIRROR + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "garuda_mirror.h" +#include "garuda_reg.h" + +static sw_error_t +_garuda_mirr_analysis_port_set(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + val = port_id; + HSL_REG_FIELD_SET(rv, dev_id, CPU_PORT, 0, MIRROR_PORT_NUM, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_garuda_mirr_analysis_port_get(a_uint32_t dev_id, fal_port_t * port_id) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, CPU_PORT, 0, MIRROR_PORT_NUM, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *port_id = val; + return SW_OK; +} + +static sw_error_t +_garuda_mirr_port_in_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, ING_MIRROR_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_garuda_mirr_port_in_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, ING_MIRROR_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_garuda_mirr_port_eg_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, EG_MIRROR_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_garuda_mirr_port_eg_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, EG_MIRROR_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +/** + * @details Comments: + * The analysis port works for both ingress and egress mirror. + * @brief Set mirror analyzer port on particular a device. + * @param[in] dev_id device id + * @param[in] port_id port id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_mirr_analysis_port_set(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_mirr_analysis_port_set(dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mirror analysis port on particular a device. + * @param[in] dev_id device id + * @param[out] port_id port id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_mirr_analysis_port_get(a_uint32_t dev_id, fal_port_t * port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_mirr_analysis_port_get(dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set ingress mirror status on particular a port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_mirr_port_in_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_mirr_port_in_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get ingress mirror status on particular a port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_mirr_port_in_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_mirr_port_in_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set egress mirror status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_mirr_port_eg_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_mirr_port_eg_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get egress mirror status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_mirr_port_eg_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_mirr_port_eg_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +garuda_mirr_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->mirr_analysis_port_set = garuda_mirr_analysis_port_set; + p_api->mirr_analysis_port_get = garuda_mirr_analysis_port_get; + p_api->mirr_port_in_set = garuda_mirr_port_in_set; + p_api->mirr_port_in_get = garuda_mirr_port_in_get; + p_api->mirr_port_eg_set = garuda_mirr_port_eg_set; + p_api->mirr_port_eg_get = garuda_mirr_port_eg_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_misc.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_misc.c new file mode 100755 index 000000000..73ba5ef88 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_misc.c @@ -0,0 +1,1009 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 garuda_misc GARUDA_MISC + * @{ + */ + +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "garuda_misc.h" +#include "garuda_reg.h" + +#define GARUDA_MAX_FRMAE_SIZE 9216 + + +static sw_error_t +_garuda_arp_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, ADDR_TABLE_CTL, 0, ARP_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + + +static sw_error_t +_garuda_arp_status_get(a_uint32_t dev_id, a_bool_t *enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_CTL, 0, ARP_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + + +static sw_error_t +_garuda_frame_max_size_set(a_uint32_t dev_id, a_uint32_t size) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (GARUDA_MAX_FRMAE_SIZE < size) + { + return SW_BAD_PARAM; + } + + data = size; + HSL_REG_FIELD_SET(rv, dev_id, GLOBAL_CTL, 0, MAX_FRAME_SIZE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + + +static sw_error_t +_garuda_frame_max_size_get(a_uint32_t dev_id, a_uint32_t *size) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, GLOBAL_CTL, 0, MAX_FRAME_SIZE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *size = data; + return SW_OK; +} + +static sw_error_t +_garuda_port_unk_sa_cmd_set(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_CTL, port_id, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_MAC_FRWRD == cmd) + { + SW_SET_REG_BY_FIELD(PORT_CTL, PORT_LOCK_EN, 0, data); + } + else if (FAL_MAC_DROP == cmd) + { + SW_SET_REG_BY_FIELD(PORT_CTL, PORT_LOCK_EN, 1, data); + SW_SET_REG_BY_FIELD(PORT_CTL, LOCK_DROP_EN, 1, data); + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + SW_SET_REG_BY_FIELD(PORT_CTL, PORT_LOCK_EN, 1, data); + SW_SET_REG_BY_FIELD(PORT_CTL, LOCK_DROP_EN, 0, data); + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_CTL, port_id, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_garuda_port_unk_sa_cmd_get(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t * action) +{ + sw_error_t rv; + a_uint32_t data; + a_uint32_t port_lock_en, port_drop_en; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_CTL, port_id, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_CTL, PORT_LOCK_EN, port_lock_en, data); + SW_GET_FIELD_BY_REG(PORT_CTL, LOCK_DROP_EN, port_drop_en, data); + + if (1 == port_lock_en) + { + if (1 == port_drop_en) + { + *action = FAL_MAC_DROP; + } + else + { + *action = FAL_MAC_RDT_TO_CPU; + } + } + else + { + *action = FAL_MAC_FRWRD; + } + + return SW_OK; +} + +static sw_error_t +_garuda_port_unk_uc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FLOOD_MASK, 0, UNI_FLOOD_DP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + data &= (~((a_uint32_t)0x1 << port_id)); + } + else if (A_FALSE == enable) + { + data |= (0x1 << port_id); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FLOOD_MASK, 0, UNI_FLOOD_DP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_garuda_port_unk_uc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t reg, field; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FLOOD_MASK, 0, UNI_FLOOD_DP, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + field = reg & (0x1 << port_id); + if (field) + { + *enable = A_FALSE; + } + else + { + *enable = A_TRUE; + } + + return SW_OK; +} + +static sw_error_t +_garuda_port_unk_mc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FLOOD_MASK, 0, MUL_FLOOD_DP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + data &= (~((a_uint32_t)0x1 << port_id)); + } + else if (A_FALSE == enable) + { + data |= (0x1 << port_id); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FLOOD_MASK, 0, MUL_FLOOD_DP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_garuda_port_unk_mc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t reg, field; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FLOOD_MASK, 0, MUL_FLOOD_DP, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + field = reg & (0x1 << port_id); + if (field) + { + *enable = A_FALSE; + } + else + { + *enable = A_TRUE; + } + + return SW_OK; +} + +static sw_error_t +_garuda_cpu_port_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, CPU_PORT, 0, CPU_PORT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_garuda_cpu_port_status_get(a_uint32_t dev_id, a_bool_t *enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, CPU_PORT, 0, CPU_PORT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + + +static sw_error_t +_garuda_bc_to_cpu_port_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FLOOD_MASK, 0, BROAD_TO_CPU, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + + +static sw_error_t +_garuda_bc_to_cpu_port_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_REG_FIELD_GET(rv, dev_id, FLOOD_MASK, 0, BROAD_TO_CPU, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_garuda_pppoe_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_MAC_FRWRD == cmd) + { + val = 0; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + val = 1; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, QM_CTL, 0, PPPOE_RDT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + + +static sw_error_t +_garuda_pppoe_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, QM_CTL, 0, PPPOE_RDT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + else + { + *cmd = FAL_MAC_FRWRD; + } + + return SW_OK; +} + + +static sw_error_t +_garuda_pppoe_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, QM_CTL, 0, PPPOE_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_garuda_pppoe_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, QM_CTL, 0, PPPOE_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + + + +static sw_error_t +_garuda_port_dhcp_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, DHCP_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_garuda_port_dhcp_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, DHCP_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +/** + * @brief Set arp packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_arp_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_arp_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_arp_status_get(a_uint32_t dev_id, a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_arp_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set max frame size which device can received on a particular device. + * @details Comments: + * The granularity of packets size is byte. + * @param[in] dev_id device id + * @param[in] size packet size + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_frame_max_size_set(a_uint32_t dev_id, a_uint32_t size) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_frame_max_size_set(dev_id, size); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get max frame size which device can received on a particular device. + * @details Comments: + * The unit of packets size is byte. + * @param[in] dev_id device id + * @param[out] size packet size + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_frame_max_size_get(a_uint32_t dev_id, a_uint32_t *size) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_frame_max_size_get(dev_id, size); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set forwarding command for packets which source address is unknown on a particular port. + * @details Comments: + * Particular device may only support parts of forwarding commands. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_unk_sa_cmd_set(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_unk_sa_cmd_set(dev_id, port_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get forwarding command for packets which source address is unknown on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_unk_sa_cmd_get(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t * action) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_unk_sa_cmd_get(dev_id, port_id, action); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flooding status of unknown unicast packets on a particular port. + * @details Comments: + * If enable unknown unicast packets filter on one port then unknown + * unicast packets can't flood out from this port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_unk_uc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_unk_uc_filter_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get flooding status of unknown unicast packets on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_unk_uc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_unk_uc_filter_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flooding status of unknown multicast packets on a particular port. + * @details Comments: + * If enable unknown multicast packets filter on one port then unknown + * multicast packets can't flood out from this port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_unk_mc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_unk_mc_filter_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** @brief Get flooding status of unknown multicast packets on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_unk_mc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_unk_mc_filter_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set cpu port status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_cpu_port_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_cpu_port_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get cpu port status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_cpu_port_status_get(a_uint32_t dev_id, a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_cpu_port_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of braodcast packets broadcasting to cpu on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_bc_to_cpu_port_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_bc_to_cpu_port_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get status of braodcast packets broadcasting to cpu on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_bc_to_cpu_port_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_bc_to_cpu_port_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set pppoe packets forwarding command on a particular device. + * @details comments: + * Particular device may only support parts of forwarding commands. + * Ihis operation will take effect only after enabling pppoe packets + * hardware acknowledgement + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_pppoe_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_pppoe_cmd_set(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get pppoe packets forwarding command on a particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_pppoe_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_pppoe_cmd_get(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set pppoe packets hardware acknowledgement status on particular device. + * @details comments: + * Particular device may only support parts of pppoe packets. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_pppoe_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_pppoe_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get pppoe packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_pppoe_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_pppoe_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dhcp packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_dhcp_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_dhcp_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dhcp packets hardware acknowledgement status on particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_dhcp_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_dhcp_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +garuda_misc_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->arp_status_set = garuda_arp_status_set; + p_api->arp_status_get = garuda_arp_status_get; + p_api->frame_max_size_set = garuda_frame_max_size_set; + p_api->frame_max_size_get = garuda_frame_max_size_get; + p_api->port_unk_sa_cmd_set = garuda_port_unk_sa_cmd_set; + p_api->port_unk_sa_cmd_get = garuda_port_unk_sa_cmd_get; + p_api->port_unk_uc_filter_set = garuda_port_unk_uc_filter_set; + p_api->port_unk_uc_filter_get = garuda_port_unk_uc_filter_get; + p_api->port_unk_mc_filter_set = garuda_port_unk_mc_filter_set; + p_api->port_unk_mc_filter_get = garuda_port_unk_mc_filter_get; + p_api->cpu_port_status_set = garuda_cpu_port_status_set; + p_api->cpu_port_status_get = garuda_cpu_port_status_get; + p_api->bc_to_cpu_port_set = garuda_bc_to_cpu_port_set; + p_api->bc_to_cpu_port_get = garuda_bc_to_cpu_port_get; + p_api->pppoe_cmd_set = garuda_pppoe_cmd_set; + p_api->pppoe_cmd_get = garuda_pppoe_cmd_get; + p_api->pppoe_status_set = garuda_pppoe_status_set; + p_api->pppoe_status_get = garuda_pppoe_status_get; + p_api->port_dhcp_set = garuda_port_dhcp_set; + p_api->port_dhcp_get = garuda_port_dhcp_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_port_ctrl.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_port_ctrl.c new file mode 100755 index 000000000..839db8c0b --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_port_ctrl.c @@ -0,0 +1,1069 @@ +/* + * Copyright (c) 2012, 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 garuda_port_ctrl GARUDA_PORT_CONTROL + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "garuda_port_ctrl.h" +#include "garuda_reg.h" +#include "hsl_phy.h" + +static sw_error_t +_garuda_port_duplex_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t duplex) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + a_uint32_t reg_save = 0; + a_uint32_t reg_val = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_duplex_set) + return SW_NOT_SUPPORTED; + + if (FAL_DUPLEX_BUTT <= duplex) + { + return SW_BAD_PARAM; + } + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + //save reg value + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_val), sizeof (a_uint32_t)); + reg_save = reg_val; + + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 0, reg_val); + SW_SET_REG_BY_FIELD(PORT_STATUS, RXMAC_EN, 0, reg_val); + SW_SET_REG_BY_FIELD(PORT_STATUS, TXMAC_EN, 0, reg_val); + + //set mac be config by sw and turn off RX TX MAC_EN + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_val), sizeof (a_uint32_t)); + + rv = phy_drv->phy_duplex_set(dev_id, phy_id, duplex); + + //retore reg value + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_save), sizeof (a_uint32_t)); + + return rv; +} + + +static sw_error_t +_garuda_port_duplex_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t * pduplex) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_duplex_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_duplex_get(dev_id, phy_id, pduplex); + return rv; +} + +static sw_error_t +_garuda_port_speed_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t speed) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_speed_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_SPEED_1000 < speed) + { + return SW_BAD_PARAM; + } + + rv = phy_drv->phy_speed_set(dev_id, phy_id, speed); + + return rv; +} + + +static sw_error_t +_garuda_port_speed_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t * pspeed) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_speed_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_speed_get(dev_id, phy_id, pspeed); + + return rv; +} + +static sw_error_t +_garuda_port_autoneg_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status) +{ + a_uint32_t phy_id; + sw_error_t rv; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_autoneg_status_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + *status = phy_drv->phy_autoneg_status_get (dev_id, phy_id); + + return SW_OK; +} + +static sw_error_t +_garuda_port_autoneg_enable(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_autoneg_enable_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_autoneg_enable_set(dev_id, phy_id); + return rv; +} + +static sw_error_t +_garuda_port_autoneg_restart(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_restart_autoneg) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_restart_autoneg(dev_id, phy_id); + return rv; +} + + +static sw_error_t +_garuda_port_autoneg_adv_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t autoadv) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_autoneg_adv_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_autoneg_adv_set(dev_id, phy_id, autoadv); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + + +static sw_error_t +_garuda_port_autoneg_adv_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * autoadv) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_autoneg_adv_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + *autoadv = 0; + rv = phy_drv->phy_autoneg_adv_get(dev_id, phy_id, autoadv); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +static sw_error_t +_garuda_port_hdr_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, HEAD_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_garuda_port_hdr_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, HEAD_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return rv; +} + +static sw_error_t +_garuda_port_flowctrl_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val, force, reg; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_STATUS, FLOW_LINK_EN, force, reg); + if (force) + { + /* flow control isn't in force mode so can't set */ + return SW_DISABLE; + } + + SW_SET_REG_BY_FIELD(PORT_STATUS, RX_FLOW_EN, val, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TX_FLOW_EN, val, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TX_HALF_FLOW_EN, val, reg); + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + + +static sw_error_t +_garuda_port_flowctrl_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t tx, rx, reg; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_STATUS, RX_FLOW_EN, rx, reg); + SW_GET_FIELD_BY_REG(PORT_STATUS, TX_FLOW_EN, tx, reg); + + if (1 == rx) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_garuda_port_flowctrl_forcemode_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t force, reg; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_STATUS, FLOW_LINK_EN, force, reg); + if (force != (a_uint32_t) enable) + { + return SW_OK; + } + + if (A_TRUE == enable) + { + SW_SET_REG_BY_FIELD(PORT_STATUS, FLOW_LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TX_FLOW_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, RX_FLOW_EN, 0, reg); + } + else if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(PORT_STATUS, FLOW_LINK_EN, 1, reg); + } + else + { + return SW_BAD_PARAM; + } + SW_SET_REG_BY_FIELD(PORT_STATUS, TX_HALF_FLOW_EN, 0, reg); + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_garuda_port_flowctrl_forcemode_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t force, reg; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_STATUS, FLOW_LINK_EN, force, reg); + if (0 == force) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_garuda_port_powersave_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_powersave_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_powersave_set(dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_garuda_port_powersave_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_powersave_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_powersave_get(dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_garuda_port_hibernate_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_hibernation_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_hibernation_set(dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_garuda_port_hibernate_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_hibernation_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_hibernation_get(dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_garuda_port_cdt(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t mdi_pair, + fal_cable_status_t *cable_status, a_uint32_t *cable_len) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_cdt) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_cdt(dev_id, phy_id, mdi_pair, cable_status, cable_len); + + return rv; +} + +/** + * @brief Set duplex mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] duplex duplex mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_duplex_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t duplex) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_duplex_set(dev_id, port_id, duplex); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get duplex mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] duplex duplex mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_duplex_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t * pduplex) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_duplex_get(dev_id, port_id, pduplex); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set speed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] speed port speed + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_speed_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t speed) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_speed_set(dev_id, port_id, speed); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get speed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] speed port speed + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_speed_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t * pspeed) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_speed_get(dev_id, port_id, pspeed); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get auto negotiation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] status A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_autoneg_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_autoneg_status_get(dev_id, port_id, status); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Enable auto negotiation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_autoneg_enable(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_autoneg_enable(dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Restart auto negotiation procedule on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_autoneg_restart(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_autoneg_restart(dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set auto negotiation advtisement ability on a particular port. + * @details Comments: + * auto negotiation advtisement ability is defined by macro such as + * FAL_PHY_ADV_10T_HD, FAL_PHY_ADV_PAUSE... + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] autoadv auto negotiation advtisement ability bit map + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_autoneg_adv_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t autoadv) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_autoneg_adv_set(dev_id, port_id, autoadv); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get auto negotiation advtisement ability on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] autoadv auto negotiation advtisement ability bit map + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_autoneg_adv_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * autoadv) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_autoneg_adv_get(dev_id, port_id, autoadv); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of Atheros header packets parsed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_hdr_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_hdr_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get status of Atheros header packets parsed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_hdr_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_hdr_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flow control status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_flowctrl_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_flowctrl_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get flow control status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_flowctrl_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_flowctrl_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flow control force mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_flowctrl_forcemode_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_flowctrl_forcemode_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get flow control force mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_flowctrl_forcemode_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_flowctrl_forcemode_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set powersaving status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_powersave_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_powersave_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get powersaving status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_powersave_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_powersave_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set hibernate status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_hibernate_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_hibernate_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get hibernate status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_hibernate_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_hibernate_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Run cable diagnostic test on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mdi_pair mdi pair id + * @param[out] cable_status cable status + * @param[out] cable_len cable len + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_cdt(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t mdi_pair, + fal_cable_status_t *cable_status, a_uint32_t *cable_len) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_cdt(dev_id, port_id, mdi_pair, cable_status, cable_len); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +garuda_port_ctrl_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->port_duplex_get = garuda_port_duplex_get; + p_api->port_duplex_set = garuda_port_duplex_set; + p_api->port_speed_get = garuda_port_speed_get; + p_api->port_speed_set = garuda_port_speed_set; + p_api->port_autoneg_status_get = garuda_port_autoneg_status_get; + p_api->port_autoneg_enable = garuda_port_autoneg_enable; + p_api->port_autoneg_restart = garuda_port_autoneg_restart; + p_api->port_autoneg_adv_get = garuda_port_autoneg_adv_get; + p_api->port_autoneg_adv_set = garuda_port_autoneg_adv_set; + p_api->port_hdr_status_set = garuda_port_hdr_status_set; + p_api->port_hdr_status_get = garuda_port_hdr_status_get; + p_api->port_flowctrl_set = garuda_port_flowctrl_set; + p_api->port_flowctrl_get = garuda_port_flowctrl_get; + p_api->port_flowctrl_forcemode_set = garuda_port_flowctrl_forcemode_set; + p_api->port_flowctrl_forcemode_get = garuda_port_flowctrl_forcemode_get; + p_api->port_powersave_set = garuda_port_powersave_set; + p_api->port_powersave_get = garuda_port_powersave_get; + p_api->port_hibernate_set = garuda_port_hibernate_set; + p_api->port_hibernate_get = garuda_port_hibernate_get; + p_api->port_cdt = garuda_port_cdt; + + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_portvlan.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_portvlan.c new file mode 100755 index 000000000..38986bcac --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_portvlan.c @@ -0,0 +1,912 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 garuda_port_vlan GARUDA_PORT_VLAN + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "garuda_portvlan.h" +#include "garuda_reg.h" + +#define MAX_VLAN_ID 4095 + + +static sw_error_t +_garuda_port_1qmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t port_1qmode) +{ + sw_error_t rv; + a_uint32_t regval[FAL_1Q_MODE_BUTT] = { 0, 3, 2, 1 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_1Q_MODE_BUTT <= port_1qmode) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_BASE_VLAN, port_id, DOT1Q_MODE, + (a_uint8_t *) (®val[port_1qmode]), + sizeof (a_uint32_t)); + + return rv; + +} + + +static sw_error_t +_garuda_port_1qmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t * pport_1qmode) +{ + sw_error_t rv; + a_uint32_t regval = 0; + fal_pt_1qmode_t retval[4] = { FAL_1Q_DISABLE, FAL_1Q_FALLBACK, + FAL_1Q_CHECK, FAL_1Q_SECURE + }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL(pport_1qmode); + + HSL_REG_FIELD_GET(rv, dev_id, PORT_BASE_VLAN, port_id, DOT1Q_MODE, + (a_uint8_t *) (®val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + *pport_1qmode = retval[regval & 0x3]; + + return SW_OK; + +} + + +static sw_error_t +_garuda_port_egvlanmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t port_egvlanmode) +{ + sw_error_t rv; + a_uint32_t regval[FAL_EG_MODE_BUTT] = { 0, 1, 2, 3 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_EG_MODE_BUTT <= port_egvlanmode) + { + return SW_BAD_PARAM; + } + + if (FAL_EG_HYBRID == port_egvlanmode) + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, EG_VLAN_MODE, + (a_uint8_t *) (®val[port_egvlanmode]), + sizeof (a_uint32_t)); + + return rv; + +} + + +static sw_error_t +_garuda_port_egvlanmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t * pport_egvlanmode) +{ + sw_error_t rv; + a_uint32_t regval = 0; + fal_pt_1q_egmode_t retval[3] = { FAL_EG_UNMODIFIED, FAL_EG_UNTAGGED, + FAL_EG_TAGGED + }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL(pport_egvlanmode); + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, EG_VLAN_MODE, + (a_uint8_t *) (®val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + *pport_egvlanmode = retval[regval & 0x3]; + + return SW_OK; + +} + + +static sw_error_t +_garuda_portvlan_member_add(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id) +{ + sw_error_t rv; + a_uint32_t regval = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_FALSE == hsl_port_prop_check(dev_id, mem_port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_BASE_VLAN, port_id, + PORT_VID_MEM, (a_uint8_t *) (®val), + sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + regval |= (0x1UL << mem_port_id); + + HSL_REG_FIELD_SET(rv, dev_id, PORT_BASE_VLAN, port_id, + PORT_VID_MEM, (a_uint8_t *) (®val), + sizeof (a_uint32_t)); + + return rv; + +} + +static sw_error_t +_garuda_portvlan_member_del(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id) +{ + sw_error_t rv; + a_uint32_t regval = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_FALSE == hsl_port_prop_check(dev_id, mem_port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_BASE_VLAN, port_id, + PORT_VID_MEM, (a_uint8_t *) (®val), + sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + regval &= (~(0x1UL << mem_port_id)); + + HSL_REG_FIELD_SET(rv, dev_id, PORT_BASE_VLAN, port_id, + PORT_VID_MEM, (a_uint8_t *) (®val), + sizeof (a_uint32_t)); + + return rv; + +} + + +static sw_error_t +_garuda_portvlan_member_update(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t mem_port_map) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_FALSE == + hsl_mports_prop_check(dev_id, mem_port_map, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_BASE_VLAN, port_id, + PORT_VID_MEM, (a_uint8_t *) (&mem_port_map), + sizeof (a_uint32_t)); + + return rv; +} + + +static sw_error_t +_garuda_portvlan_member_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t * mem_port_map) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + *mem_port_map = 0; + HSL_REG_FIELD_GET(rv, dev_id, PORT_BASE_VLAN, port_id, + PORT_VID_MEM, (a_uint8_t *) mem_port_map, + sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +static sw_error_t +_garuda_port_default_vid_set(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t vid) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if ((0 == vid) || (vid > MAX_VLAN_ID)) + { + return SW_BAD_PARAM; + } + + val = vid; + HSL_REG_FIELD_SET(rv, dev_id, PORT_BASE_VLAN, port_id, + PORT_VID, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + + return rv; +} + + +static sw_error_t +_garuda_port_default_vid_get(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t *vid) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_BASE_VLAN, port_id, + PORT_VID, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + + *vid = val & 0xfff; + return rv; +} + +static sw_error_t +_garuda_port_force_default_vid_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_BASE_VLAN, port_id, + FORCE_DEF_VID, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_garuda_port_force_default_vid_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_BASE_VLAN, port_id, + FORCE_DEF_VID, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + + +static sw_error_t +_garuda_port_force_portvlan_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_BASE_VLAN, port_id, + FORCE_PVLAN, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + return rv; +} + + +static sw_error_t +_garuda_port_force_portvlan_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_BASE_VLAN, port_id, + FORCE_PVLAN, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_garuda_port_nestvlan_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, + DTAG_EN, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + return rv; +} + + +static sw_error_t +_garuda_port_nestvlan_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, + DTAG_EN, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + + +static sw_error_t +_garuda_nestvlan_tpid_set(a_uint32_t dev_id, a_uint32_t tpid) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + val = tpid; + HSL_REG_FIELD_SET(rv, dev_id, SERVICE_TAG, 0, + TAG_VALUE, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + return rv; +} + + +static sw_error_t +_garuda_nestvlan_tpid_get(a_uint32_t dev_id, a_uint32_t *tpid) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, SERVICE_TAG, 0, + TAG_VALUE, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *tpid = val; + return SW_OK; +} + +/** + * @brief Set 802.1q work mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] port_1qmode 802.1q work mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_1qmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t port_1qmode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_1qmode_set(dev_id, port_id, port_1qmode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get 802.1q work mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] port_1qmode 802.1q work mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_1qmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t * pport_1qmode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_1qmode_get(dev_id, port_id, pport_1qmode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set packets transmitted out vlan tagged mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] port_egvlanmode packets transmitted out vlan tagged mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_egvlanmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t port_egvlanmode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_egvlanmode_set(dev_id, port_id, port_egvlanmode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get packets transmitted out vlan tagged mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] port_egvlanmode packets transmitted out vlan tagged mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_egvlanmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t * pport_egvlanmode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_egvlanmode_get(dev_id, port_id, pport_egvlanmode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add member of port based vlan on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mem_port_id port member + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_portvlan_member_add(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_portvlan_member_add(dev_id, port_id, mem_port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete member of port based vlan on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mem_port_id port member + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_portvlan_member_del(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_portvlan_member_del(dev_id, port_id, mem_port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Update member of port based vlan on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mem_port_map port members + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_portvlan_member_update(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t mem_port_map) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_portvlan_member_update(dev_id, port_id, mem_port_map); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get member of port based vlan on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mem_port_map port members + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_portvlan_member_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t * mem_port_map) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_portvlan_member_get(dev_id, port_id, mem_port_map); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set default vlan id on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] vid default vlan id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_default_vid_set(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t vid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_default_vid_set(dev_id, port_id, vid); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get default vlan id on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] vid default vlan id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_default_vid_get(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t *vid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_default_vid_get(dev_id, port_id, vid); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set force default vlan id status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_force_default_vid_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_force_default_vid_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get force default vlan id status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_force_default_vid_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_force_default_vid_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set force port based vlan status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_force_portvlan_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_force_portvlan_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get force port based vlan status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_force_portvlan_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_force_portvlan_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set nest vlan feature status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_nestvlan_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_nestvlan_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get nest vlan feature status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_port_nestvlan_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_port_nestvlan_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set nest vlan tpid on a particular device. + * @param[in] dev_id device id + * @param[in] tpid tag protocol identification + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_nestvlan_tpid_set(a_uint32_t dev_id, a_uint32_t tpid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_nestvlan_tpid_set(dev_id, tpid); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get nest vlan tpid on a particular device. + * @param[in] dev_id device id + * @param[out] tpid tag protocol identification + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_nestvlan_tpid_get(a_uint32_t dev_id, a_uint32_t *tpid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_nestvlan_tpid_get(dev_id, tpid); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +garuda_portvlan_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + hsl_api_t *p_api; + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get(dev_id)); + + p_api->port_1qmode_get = garuda_port_1qmode_get; + p_api->port_1qmode_set = garuda_port_1qmode_set; + p_api->port_egvlanmode_get = garuda_port_egvlanmode_get; + p_api->port_egvlanmode_set = garuda_port_egvlanmode_set; + p_api->portvlan_member_add = garuda_portvlan_member_add; + p_api->portvlan_member_del = garuda_portvlan_member_del; + p_api->portvlan_member_update = garuda_portvlan_member_update; + p_api->portvlan_member_get = garuda_portvlan_member_get; + p_api->port_default_vid_set = garuda_port_default_vid_set; + p_api->port_default_vid_get = garuda_port_default_vid_get; + p_api->port_force_default_vid_set = garuda_port_force_default_vid_set; + p_api->port_force_default_vid_get = garuda_port_force_default_vid_get; + p_api->port_force_portvlan_set = garuda_port_force_portvlan_set; + p_api->port_force_portvlan_get = garuda_port_force_portvlan_get; + p_api->port_nestvlan_set = garuda_port_nestvlan_set; + p_api->port_nestvlan_get = garuda_port_nestvlan_get; + p_api->nestvlan_tpid_set = garuda_nestvlan_tpid_set; + p_api->nestvlan_tpid_get = garuda_nestvlan_tpid_get; +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_qos.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_qos.c new file mode 100755 index 000000000..f1c367a14 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_qos.c @@ -0,0 +1,1191 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 garuda_qos GARUDA_QOS + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "garuda_qos.h" +#include "garuda_reg.h" + +#define GARUDA_QOS_QUEUE_TX_BUFFER_MAX 60 +#define GARUDA_QOS_PORT_TX_BUFFER_MAX 252 + +//#define GARUDA_MIN_QOS_MODE_PRI 0 +#define GARUDA_MAX_QOS_MODE_PRI 3 + +static sw_error_t +_garuda_qos_sch_mode_set(a_uint32_t dev_id, + fal_sch_mode_t mode, const a_uint32_t weight[]) +{ + sw_error_t rv; + a_uint32_t val, wrr, mix; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_SCH_SP_MODE == mode) + { + wrr = 0; + mix = 0; + } + else if (FAL_SCH_WRR_MODE == mode) + { + wrr = 1; + mix = 0; + } + else if (FAL_SCH_MIX_MODE == mode) + { + wrr = 1; + mix = 1; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_ENTRY_GET(rv, dev_id, GLOBAL_CTL, 0, (a_uint32_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(GLOBAL_CTL, WEIGHT_PRIORITY, wrr, val); + SW_SET_REG_BY_FIELD(GLOBAL_CTL, MIX_PRIORITY, mix, val); + + HSL_REG_ENTRY_SET(rv, dev_id, GLOBAL_CTL, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_garuda_qos_sch_mode_get(a_uint32_t dev_id, + fal_sch_mode_t * mode, a_uint32_t weight[]) +{ + sw_error_t rv; + a_uint32_t idx, val, wrr, mix; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_ENTRY_GET(rv, dev_id, GLOBAL_CTL, 0, (a_uint32_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(GLOBAL_CTL, WEIGHT_PRIORITY, wrr, val); + SW_GET_FIELD_BY_REG(GLOBAL_CTL, MIX_PRIORITY, mix, val); + + if (0 == wrr) + { + *mode = FAL_SCH_SP_MODE; + for (idx = 0; idx < 4; idx++) + { + weight[idx] = 0; + } + } + else + { + if (0 == mix) + { + *mode = FAL_SCH_WRR_MODE; + weight[0] = 1; + for (idx = 1; idx < 4; idx++) + { + weight[idx] = weight[idx - 1] << 1; + } + } + else + { + *mode = FAL_SCH_MIX_MODE; + weight[3] = 0; + weight[2] = 4; + weight[1] = 2; + weight[0] = 1; + } + } + + return SW_OK; +} + +static sw_error_t +_garuda_qos_queue_tx_buf_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, QUEUE_CTL, port_id, QUEUE_DESC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + + +static sw_error_t +_garuda_qos_queue_tx_buf_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, QUEUE_CTL, port_id, QUEUE_DESC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + + +static sw_error_t +_garuda_qos_port_tx_buf_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, QUEUE_CTL, port_id, PORT_DESC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + + +static sw_error_t +_garuda_qos_port_tx_buf_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, QUEUE_CTL, port_id, PORT_DESC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + + +static sw_error_t +_garuda_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) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (GARUDA_QOS_QUEUE_TX_BUFFER_MAX < *number) + { + return SW_BAD_PARAM; + } + + val = *number / 4; + *number = val << 2; + + if (0 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, QUEUE_CTL, port_id, QUEUE0_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (1 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, QUEUE_CTL, port_id, QUEUE1_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (2 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, QUEUE_CTL, port_id, QUEUE2_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (3 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, QUEUE_CTL, port_id, QUEUE3_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + + return rv; +} + + +static sw_error_t +_garuda_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) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (0 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, QUEUE_CTL, port_id, QUEUE0_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (1 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, QUEUE_CTL, port_id, QUEUE1_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (2 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, QUEUE_CTL, port_id, QUEUE2_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (3 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, QUEUE_CTL, port_id, QUEUE3_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + *number = val << 2; + return SW_OK; +} + + +static sw_error_t +_garuda_qos_port_tx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (GARUDA_QOS_PORT_TX_BUFFER_MAX < *number) + { + return SW_BAD_PARAM; + } + + val = *number / 4; + *number = val << 2; + HSL_REG_FIELD_SET(rv, dev_id, QUEUE_CTL, port_id, PORT_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_garuda_qos_port_tx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, QUEUE_CTL, port_id, PORT_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *number = val << 2; + return SW_OK; +} + +static sw_error_t +_garuda_cosmap_up_queue_set(a_uint32_t dev_id, a_uint32_t up, + fal_queue_t queue) +{ + sw_error_t rv; + a_uint32_t val; + hsl_dev_t *p_dev = NULL; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_DOT1P_MAX < up) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL(p_dev = hsl_dev_ptr_get(dev_id)); + if (p_dev->nr_queue <= queue) + { + return SW_BAD_PARAM; + } + + val = queue; + HSL_REG_FIELD_GEN_SET(rv, dev_id, TAG_PRI_MAPPING_OFFSET, 2, + (a_uint16_t) (up << 1), (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + return rv; +} + + +static sw_error_t +_garuda_cosmap_up_queue_get(a_uint32_t dev_id, a_uint32_t up, + fal_queue_t * queue) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_DOT1P_MAX < up) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GEN_GET(rv, dev_id, TAG_PRI_MAPPING_OFFSET, 2, + (a_uint16_t) (up << 1), (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *queue = val; + return SW_OK; +} + +static sw_error_t +_garuda_cosmap_dscp_queue_set(a_uint32_t dev_id, a_uint32_t dscp, + fal_queue_t queue) +{ + sw_error_t rv; + a_uint32_t val; + a_uint32_t offsetaddr; + a_uint16_t fieldoffset; + hsl_dev_t *p_dev = NULL; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_DSCP_MAX < dscp) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL(p_dev = hsl_dev_ptr_get(dev_id)); + if (p_dev->nr_queue <= queue) + { + return SW_BAD_PARAM; + } + + offsetaddr = (dscp >> 4) << 2; + fieldoffset = (dscp & 0xf) << 1; + + val = queue; + HSL_REG_FIELD_GEN_SET(rv, dev_id, (IP_PRI_MAPPING_OFFSET + offsetaddr), + 2, fieldoffset, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_garuda_cosmap_dscp_queue_get(a_uint32_t dev_id, a_uint32_t dscp, + fal_queue_t * queue) +{ + sw_error_t rv; + a_uint32_t val; + a_uint32_t offsetaddr; + a_uint16_t fieldoffset; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_DSCP_MAX < dscp) + { + return SW_BAD_PARAM; + } + + offsetaddr = (dscp / 16) << 2; + fieldoffset = (dscp & 0xf) << 1; + + HSL_REG_FIELD_GEN_GET(rv, dev_id, (IP_PRI_MAPPING_OFFSET + offsetaddr), + 2, fieldoffset, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *queue = val; + return SW_OK; +} + + +static sw_error_t +_garuda_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; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + if (FAL_QOS_DA_MODE == mode) + { + HSL_REG_FIELD_SET(rv, dev_id, PRI_CTL, port_id, DA_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (FAL_QOS_UP_MODE == mode) + { + HSL_REG_FIELD_SET(rv, dev_id, PRI_CTL, port_id, VLAN_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (FAL_QOS_DSCP_MODE == mode) + { + HSL_REG_FIELD_SET(rv, dev_id, PRI_CTL, port_id, IP_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (FAL_QOS_PORT_MODE == mode) + { + HSL_REG_FIELD_SET(rv, dev_id, PRI_CTL, port_id, PORT_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + + return rv; +} + + +static sw_error_t +_garuda_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; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_QOS_DA_MODE == mode) + { + HSL_REG_FIELD_GET(rv, dev_id, PRI_CTL, port_id, DA_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (FAL_QOS_UP_MODE == mode) + { + HSL_REG_FIELD_GET(rv, dev_id, PRI_CTL, port_id, VLAN_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (FAL_QOS_DSCP_MODE == mode) + { + HSL_REG_FIELD_GET(rv, dev_id, PRI_CTL, port_id, IP_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (FAL_QOS_PORT_MODE == mode) + { + HSL_REG_FIELD_GET(rv, dev_id, PRI_CTL, port_id, PORT_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_garuda_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; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (GARUDA_MAX_QOS_MODE_PRI < pri) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PRI_CTL, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_QOS_DA_MODE == mode) + { + SW_SET_REG_BY_FIELD(PRI_CTL, DA_PRI_SEL, pri, val); + } + else if (FAL_QOS_UP_MODE == mode) + { + SW_SET_REG_BY_FIELD(PRI_CTL, VLAN_PRI_SEL, pri, val); + } + else if (FAL_QOS_DSCP_MODE == mode) + { + SW_SET_REG_BY_FIELD(PRI_CTL, IP_PRI_SEL, pri, val); + } + else if (FAL_QOS_PORT_MODE == mode) + { + SW_SET_REG_BY_FIELD(PRI_CTL, PORT_PRI_SEL, pri, val); + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_ENTRY_SET(rv, dev_id, PRI_CTL, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + return rv; +} + + +static sw_error_t +_garuda_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; + a_uint32_t entry, f_val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PRI_CTL, port_id, (a_uint8_t *) (&entry), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_QOS_DA_MODE == mode) + { + SW_GET_FIELD_BY_REG(PRI_CTL, DA_PRI_SEL, f_val, entry); + } + else if (FAL_QOS_UP_MODE == mode) + { + SW_GET_FIELD_BY_REG(PRI_CTL, VLAN_PRI_SEL, f_val, entry); + } + else if (FAL_QOS_DSCP_MODE == mode) + { + SW_GET_FIELD_BY_REG(PRI_CTL, IP_PRI_SEL, f_val, entry); + } + else if (FAL_QOS_PORT_MODE == mode) + { + SW_GET_FIELD_BY_REG(PRI_CTL, PORT_PRI_SEL, f_val, entry); + } + else + { + return SW_NOT_SUPPORTED; + } + + *pri = f_val; + return SW_OK; +} + + +static sw_error_t +_garuda_qos_port_default_up_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t up) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_DOT1P_MAX < up) + { + return SW_BAD_PARAM; + } + + val = up; + HSL_REG_FIELD_SET(rv, dev_id, PORT_BASE_VLAN, port_id, ING_PRI, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_garuda_qos_port_default_up_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * up) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_BASE_VLAN, port_id, ING_PRI, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *up = val; + return SW_OK; +} + +/** + * @brief Set traffic scheduling mode on particular one device. + * @details Comments: + * GARUDA doesn't support variable weight in wrr mode, the weight for four queues + * are 8:4:2:1. + * When scheduling mode is sp the weight is meaningless usually it's zero + * When scheduling mode is sp the weight for four queues are 0:4:2:1 + * @param[in] dev_id device id + * @param[in] fal_sch_mode_t traffic scheduling mode + * @param[in] weight[] weight value for each queue when in wrr mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_qos_sch_mode_set(a_uint32_t dev_id, + fal_sch_mode_t mode, const a_uint32_t weight[]) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_qos_sch_mode_set(dev_id, mode, weight); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get traffic scheduling mode on particular device. + * @param[in] dev_id device id + * @param[in] fal_sch_mode_t traffic scheduling mode + * @param[out] weight weight value for wrr mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_qos_sch_mode_get(a_uint32_t dev_id, + fal_sch_mode_t * mode, a_uint32_t weight[]) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_qos_sch_mode_get(dev_id, mode, weight); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set buffer aggsinment status of transmitting queue on one particular port. + * @details Comments: + * If enable queue tx buffer on one port that means each queue of this port + * will have fixed number buffers when transmitting packets. Otherwise they + * share the whole buffers with other queues in device. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_qos_queue_tx_buf_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_qos_queue_tx_buf_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get buffer aggsinment status of transmitting queue on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_qos_queue_tx_buf_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_qos_queue_tx_buf_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set buffer aggsinment status of transmitting port on one particular port. + * @details Comments: + If enable tx buffer on one port that means this port will have fixed + number buffers when transmitting packets. Otherwise they will + share the whole buffers with other ports in device. + * function will return actual buffer numbers in hardware. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_qos_port_tx_buf_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_qos_port_tx_buf_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get buffer aggsinment status of transmitting port on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_qos_port_tx_buf_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_qos_port_tx_buf_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set max occupied buffer number of transmitting queue on one particular port. + * @details Comments: + The step of buffer number in GARUDA is 4, function will return actual + buffer numbers in hardware. + The buffer number range for queue is 4 to 60. + * share the whole buffers with other ports in device. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param number buffer number + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_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; + + HSL_API_LOCK; + rv = _garuda_qos_queue_tx_buf_nr_set(dev_id, port_id, queue_id, number); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get max occupied buffer number of transmitting queue on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param[out] number buffer number + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_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; + + HSL_API_LOCK; + rv = _garuda_qos_queue_tx_buf_nr_get(dev_id, port_id, queue_id, number); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set max occupied buffer number of transmitting port on one particular port. + * @details Comments: + The step of buffer number in GARUDA is four, function will return actual + buffer numbers in hardware. + The buffer number range for transmitting port is 4 to 124. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param number buffer number + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_qos_port_tx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_qos_port_tx_buf_nr_set(dev_id, port_id, number); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get max occupied buffer number of transmitting port on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] number buffer number + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_qos_port_tx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_qos_port_tx_buf_nr_get(dev_id, port_id, number); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set user priority to mapping on one particular device. + * @param[in] dev_id device id + * @param[in] dot1p 802.1p + * @param[in] queue queue id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_cosmap_up_queue_set(a_uint32_t dev_id, a_uint32_t up, + fal_queue_t queue) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_cosmap_up_queue_set(dev_id, up, queue); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get user priority to mapping on one particular device. + * @param[in] dev_id device id + * @param[in] dot1p 802.1p + * @param[out] queue queue id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_cosmap_up_queue_get(a_uint32_t dev_id, a_uint32_t up, + fal_queue_t * queue) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_cosmap_up_queue_get(dev_id, up, queue); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set cos map dscp_2_queue item on one particular device. + * @param[in] dev_id device id + * @param[in] dscp dscp + * @param[in] queue queue id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_cosmap_dscp_queue_set(a_uint32_t dev_id, a_uint32_t dscp, + fal_queue_t queue) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_cosmap_dscp_queue_set(dev_id, dscp, queue); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get cos map dscp_2_queue item on one particular device. + * @param[in] dev_id device id + * @param[in] dscp dscp + * @param[out] queue queue id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_cosmap_dscp_queue_get(a_uint32_t dev_id, a_uint32_t dscp, + fal_queue_t * queue) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_cosmap_dscp_queue_get(dev_id, dscp, queue); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set port qos mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode qos mode + * @param[in] enable A_TRUE of A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_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; + + HSL_API_LOCK; + rv = _garuda_qos_port_mode_set(dev_id, port_id, mode, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get port qos mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode qos mode + * @param[out] enable A_TRUE of A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_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; + + HSL_API_LOCK; + rv = _garuda_qos_port_mode_get(dev_id, port_id, mode, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set priority of one particular qos mode on one particular port. + * @details Comments: + If the priority of a mode is more small then the priority is more high. + Differnet mode should have differnet priority. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode qos mode + * @param[in] pri priority of one particular qos mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_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; + + HSL_API_LOCK; + rv = _garuda_qos_port_mode_pri_set(dev_id, port_id, mode, pri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get priority of one particular qos mode on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode qos mode + * @param[out] pri priority of one particular qos mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_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; + + HSL_API_LOCK; + rv = _garuda_qos_port_mode_pri_get(dev_id, port_id, mode, pri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set default user priority on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] up 802.1p + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_qos_port_default_up_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t up) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_qos_port_default_up_set(dev_id, port_id, up); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get default user priority on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] up 802.1p + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_qos_port_default_up_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * up) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_qos_port_default_up_get(dev_id, port_id, up); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +garuda_qos_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->qos_sch_mode_set = garuda_qos_sch_mode_set; + p_api->qos_sch_mode_get = garuda_qos_sch_mode_get; + p_api->qos_queue_tx_buf_status_set = garuda_qos_queue_tx_buf_status_set; + p_api->qos_queue_tx_buf_status_get = garuda_qos_queue_tx_buf_status_get; + p_api->qos_port_tx_buf_status_set = garuda_qos_port_tx_buf_status_set; + p_api->qos_port_tx_buf_status_get = garuda_qos_port_tx_buf_status_get; + p_api->qos_queue_tx_buf_nr_set = garuda_qos_queue_tx_buf_nr_set; + p_api->qos_queue_tx_buf_nr_get = garuda_qos_queue_tx_buf_nr_get; + p_api->qos_port_tx_buf_nr_set = garuda_qos_port_tx_buf_nr_set; + p_api->qos_port_tx_buf_nr_get = garuda_qos_port_tx_buf_nr_get; + p_api->cosmap_up_queue_set = garuda_cosmap_up_queue_set; + p_api->cosmap_up_queue_get = garuda_cosmap_up_queue_get; + p_api->cosmap_dscp_queue_set = garuda_cosmap_dscp_queue_set; + p_api->cosmap_dscp_queue_get = garuda_cosmap_dscp_queue_get; + p_api->qos_port_mode_set = garuda_qos_port_mode_set; + p_api->qos_port_mode_get = garuda_qos_port_mode_get; + p_api->qos_port_mode_pri_set = garuda_qos_port_mode_pri_set; + p_api->qos_port_mode_pri_get = garuda_qos_port_mode_pri_get; + p_api->qos_port_default_up_set = garuda_qos_port_default_up_set; + p_api->qos_port_default_up_get = garuda_qos_port_default_up_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_rate.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_rate.c new file mode 100755 index 000000000..8bd9cac65 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_rate.c @@ -0,0 +1,851 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 garuda_rate GARUDA_RATE + * @{ + */ + +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "garuda_rate.h" +#include "garuda_reg.h" + +#define GARUDA_STORM_MIN_RATE_PPS 1000 +#define GARUDA_STORM_MAX_RATE_PPS (1024 * 1000) + +static sw_error_t +garuda_stormrate_sw_to_hw(a_uint32_t swrate, a_uint32_t * hwrate) +{ + a_uint32_t shrnr = 0; + a_uint32_t tmp = swrate / 1000; + + if ((GARUDA_STORM_MIN_RATE_PPS > swrate) + || (GARUDA_STORM_MAX_RATE_PPS < swrate)) + { + return SW_BAD_PARAM; + } + + while ((tmp != 0) && (shrnr < 12)) + { + tmp = tmp >> 1; + shrnr++; + } + + if (12 == shrnr) + { + return SW_BAD_PARAM; + } + + *hwrate = shrnr; + return SW_OK; +} + +static sw_error_t +garuda_stormrate_hw_to_sw(a_uint32_t hwrate, a_uint32_t * swrate) +{ + if (0 == hwrate) + { + hwrate = 1; + } + + if ((1 > hwrate) || (11 < hwrate)) + { + return SW_BAD_PARAM; + } + + *swrate = (1 << (hwrate - 1)) * 1000; + return SW_OK; +} + + +static sw_error_t +_garuda_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; + a_uint32_t val; + a_uint32_t portrl; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, RATE_LIMIT0, port_id, EG_RATE_EN, + (a_uint8_t *) (&portrl), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + if (1 == portrl) + { + /* already enable port egress rate limit, queue and port + egress rate limit can't coexist */ + return SW_NOT_SUPPORTED; + } + + if ((0x7ffe << 5) < *speed) + { + return SW_BAD_PARAM; + } + val = *speed >> 5; + *speed = val << 5; + } + else if (A_FALSE == enable) + { + val = 0x7fff; + *speed = 0; + if (1 == portrl) + { + /* already enable port egress rate limit */ + return SW_OK; + } + } + else + { + return SW_BAD_PARAM; + } + + if (0 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, RATE_LIMIT1, port_id, EG_Q0_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (1 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, RATE_LIMIT1, port_id, EG_Q1_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (2 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, RATE_LIMIT2, port_id, EG_Q2_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (3 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, RATE_LIMIT2, port_id, EG_Q3_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + + return rv; +} + +static sw_error_t +_garuda_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; + a_uint32_t val; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, RATE_LIMIT0, port_id, EG_RATE_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + /* already enable port egress rate limit */ + *speed = 0; + *enable = A_FALSE; + + return SW_OK; + } + + if (0 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, RATE_LIMIT1, port_id, EG_Q0_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (1 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, RATE_LIMIT1, port_id, EG_Q1_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (2 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, RATE_LIMIT2, port_id, EG_Q2_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (3 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, RATE_LIMIT2, port_id, EG_Q3_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_ERROR(rv); + + if (0x7fff == val) + { + *enable = A_FALSE; + } + else + { + *enable = A_TRUE; + *speed = val << 5; + } + + return SW_OK; +} + + +static sw_error_t +_garuda_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; + a_uint32_t val; + a_uint32_t portrl; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, RATE_LIMIT0, port_id, EG_RATE_EN, + (a_uint8_t *) (&portrl), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_FALSE == enable) + { + *speed = 0; + + /* if port egress rate limit current enable then disable */ + if (1 == portrl) + { + val = 0; + HSL_REG_FIELD_SET(rv, dev_id, RATE_LIMIT0, port_id, EG_RATE_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + val = 0x7fff; + HSL_REG_FIELD_SET(rv, dev_id, RATE_LIMIT2, port_id, EG_Q3_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + rv = SW_OK; + } + else + { + if ((0x7ffe << 5) < *speed) + { + return SW_BAD_PARAM; + } + + /* not enable egress port rate limit */ + if (0 == portrl) + { + HSL_REG_FIELD_GET(rv, dev_id, RATE_LIMIT1, port_id, EG_Q0_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0x7fff != val) + { + /* already enable egress queue0 rate limit, queue and port + egress rate limit can't coexist */ + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_GET(rv, dev_id, RATE_LIMIT1, port_id, EG_Q1_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0x7fff != val) + { + /* already enable egress queue1 rate limit, queue and port + egress rate limit can't coexist */ + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_GET(rv, dev_id, RATE_LIMIT2, port_id, EG_Q2_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0x7fff != val) + { + /* already enable egress queue2 rate limit, queue and port + egress rate limit can't coexist */ + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_GET(rv, dev_id, RATE_LIMIT2, port_id, EG_Q3_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0x7fff != val) + { + /* already enable egress queue3 rate limit, queue and port + egress rate limit can't coexist */ + return SW_NOT_SUPPORTED; + } + + val = 1; + HSL_REG_FIELD_SET(rv, dev_id, RATE_LIMIT0, port_id, EG_RATE_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + val = *speed >> 5; + *speed = val << 5; + HSL_REG_FIELD_SET(rv, dev_id, RATE_LIMIT2, port_id, EG_Q3_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + + return rv; +} + +static sw_error_t +_garuda_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; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, RATE_LIMIT0, port_id, EG_RATE_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0 == val) + { + *speed = 0; + *enable = A_FALSE; + return SW_OK; + } + + HSL_REG_FIELD_GET(rv, dev_id, RATE_LIMIT2, port_id, EG_Q3_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + *enable = A_TRUE; + *speed = val << 5; + + return SW_OK; +} + +static sw_error_t +_garuda_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; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + if ((0x7ffe << 5) < *speed) + { + return SW_BAD_PARAM; + } + val = *speed >> 5; + *speed = val << 5; + } + else if (A_FALSE == enable) + { + val = 0x7fff; + *speed = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, RATE_LIMIT0, port_id, ING_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_garuda_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; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, RATE_LIMIT0, port_id, ING_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0x7fff == val) + { + *enable = A_FALSE; + *speed = 0; + } + else + { + *enable = A_TRUE; + *speed = val << 5; + } + + return SW_OK; +} + +static sw_error_t +_garuda_storm_ctrl_frame_set(a_uint32_t dev_id, fal_port_t port_id, + fal_storm_type_t storm_type, a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + if (FAL_UNICAST_STORM == storm_type) + { + HSL_REG_FIELD_SET(rv, dev_id, STORM_CTL, port_id, UNI_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else if (FAL_MULTICAST_STORM == storm_type) + { + HSL_REG_FIELD_SET(rv, dev_id, STORM_CTL, port_id, MUL_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else if (FAL_BROADCAST_STORM == storm_type) + { + HSL_REG_FIELD_SET(rv, dev_id, STORM_CTL, port_id, BRO_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, STORM_CTL, port_id, RATE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0 == data) + { + data = 1; + HSL_REG_FIELD_SET(rv, dev_id, STORM_CTL, port_id, RATE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +static sw_error_t +_garuda_storm_ctrl_frame_get(a_uint32_t dev_id, fal_port_t port_id, + fal_storm_type_t storm_type, a_bool_t * enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_UNICAST_STORM == storm_type) + { + HSL_REG_FIELD_GET(rv, dev_id, STORM_CTL, port_id, UNI_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else if (FAL_MULTICAST_STORM == storm_type) + { + HSL_REG_FIELD_GET(rv, dev_id, STORM_CTL, port_id, MUL_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else if (FAL_BROADCAST_STORM == storm_type) + { + HSL_REG_FIELD_GET(rv, dev_id, STORM_CTL, port_id, BRO_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + data = 1; + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_garuda_storm_ctrl_rate_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * rate_in_pps) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + rv = garuda_stormrate_sw_to_hw(*rate_in_pps, &data); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, STORM_CTL, port_id, RATE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = garuda_stormrate_hw_to_sw(data, rate_in_pps); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +static sw_error_t +_garuda_storm_ctrl_rate_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * rate_in_pps) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, STORM_CTL, port_id, RATE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = garuda_stormrate_hw_to_sw(data, rate_in_pps); + return rv; +} + +/** + * @brief Set queue egress rate limit status on one particular port and queue. + * @details Comments: + The granularity of speed is bps. + Because of hardware granularity function will return actual speed in hardware. + When disable queue egress rate limit input parameter speed is meaningless. + Egress queue rate limit can't coexist with port egress rate limit. + The step of speed is 32kbps. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param speed rate limit speed + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_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; + + HSL_API_LOCK; + rv = _garuda_rate_queue_egrl_set(dev_id, port_id, queue_id, speed, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get queue egress rate limit status on one particular port and queue. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param[out] speed rate limit speed + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_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; + + HSL_API_LOCK; + rv = _garuda_rate_queue_egrl_get(dev_id, port_id, queue_id, speed, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set port egress rate limit status on one particular port. + * @details Comments: + The granularity of speed is bps. + Because of hardware granularity function will return actual speed in hardware. + When disable port egress rate limit input parameter speed is meaningless. + Egress port rate limit can't coexist with queue egress rate limit. + The step of speed is 32kbps. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param speed rate limit speed + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_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; + + HSL_API_LOCK; + rv = _garuda_rate_port_egrl_set(dev_id, port_id, speed, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get port egress rate limit status on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] speed rate limit speed + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_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; + + HSL_API_LOCK; + rv = _garuda_rate_port_egrl_get(dev_id, port_id, speed, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set port ingress rate limit status on one particular port. + * @details Comments: + The granularity of speed is bps. + Because of hardware granularity function will return actual speed in hardware. + When disable port ingress rate limit input parameter speed is meaningless. + The step of speed is 32kbps. + * When disable port ingress rate limit input parameter speed is meaningless. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param speed rate limit speed + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_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; + + HSL_API_LOCK; + rv = _garuda_rate_port_inrl_set(dev_id, port_id, speed, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get port ingress rate limit status on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] speed rate limit speed + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_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; + + HSL_API_LOCK; + rv = _garuda_rate_port_inrl_get(dev_id, port_id, speed, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set particular type storm control status on one particular port. + * @details Comments: + * When enable one particular packets type storm control this type packets + * speed will be calculated in storm control. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] frame_type packets type which causes storm + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_storm_ctrl_frame_set(a_uint32_t dev_id, fal_port_t port_id, + fal_storm_type_t storm_type, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_storm_ctrl_frame_set(dev_id, port_id, storm_type, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get particular type storm control status on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] frame_type packets type which causes storm + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_storm_ctrl_frame_get(a_uint32_t dev_id, fal_port_t port_id, + fal_storm_type_t storm_type, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_storm_ctrl_frame_get(dev_id, port_id, storm_type, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set storm control speed on one particular port. + * @details Comments: + Because of hardware granularity function will return actual speed in hardware. + The step of speed is kpps. + The speed range is from 1k to 1M + * @param[in] dev_id device id + * @param[in] port_id port id + * @param speed storm control speed + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_storm_ctrl_rate_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * rate_in_pps) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_storm_ctrl_rate_set(dev_id, port_id, rate_in_pps); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get storm control speed on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] speed storm control speed + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_storm_ctrl_rate_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * rate_in_pps) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_storm_ctrl_rate_get(dev_id, port_id, rate_in_pps); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +garuda_rate_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->rate_queue_egrl_set = garuda_rate_queue_egrl_set; + p_api->rate_queue_egrl_get = garuda_rate_queue_egrl_get; + p_api->rate_port_egrl_set = garuda_rate_port_egrl_set; + p_api->rate_port_egrl_get = garuda_rate_port_egrl_get; + p_api->rate_port_inrl_set = garuda_rate_port_inrl_set; + p_api->rate_port_inrl_get = garuda_rate_port_inrl_get; + p_api->storm_ctrl_frame_set = garuda_storm_ctrl_frame_set; + p_api->storm_ctrl_frame_get = garuda_storm_ctrl_frame_get; + p_api->storm_ctrl_rate_set = garuda_storm_ctrl_rate_set; + p_api->storm_ctrl_rate_get = garuda_storm_ctrl_rate_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_reduced_acl.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_reduced_acl.c new file mode 100755 index 000000000..73d2a5aa3 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_reduced_acl.c @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 "garuda_reduced_acl.h" +#include "hsl.h" + +#define GARUDA_RULE_VLU_ADDR 0x58400 +#define GARUDA_RULE_MSK_ADDR 0x58c00 +#define GARUDA_RULE_ACT_ADDR 0x58000 +#define GARUDA_RULE_SLCT_ADDR 0x58800 + +sw_error_t +garuda_acl_rule_write(a_uint32_t dev_id, a_uint32_t rule_idx, a_uint32_t vlu[8], + a_uint32_t msk[8]) +{ + sw_error_t rv; + a_uint32_t i, base, addr; + + /* set rule value */ + base = GARUDA_RULE_VLU_ADDR + (rule_idx << 5); + for (i = 0; i < 5; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(vlu[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + /* set rule mask */ + base = GARUDA_RULE_MSK_ADDR + (rule_idx << 5); + for (i = 0; i < 5; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(msk[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +sw_error_t +garuda_acl_action_write(a_uint32_t dev_id, a_uint32_t act_idx, + a_uint32_t act) +{ + sw_error_t rv; + a_uint32_t addr; + + /* set rule action */ + addr = GARUDA_RULE_ACT_ADDR + (act_idx << 5); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&act), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +sw_error_t +garuda_acl_slct_write(a_uint32_t dev_id, a_uint32_t slct_idx, + a_uint32_t slct[8]) +{ + sw_error_t rv; + a_uint32_t base, addr; + a_uint32_t i; + + base = GARUDA_RULE_SLCT_ADDR + (slct_idx << 5); + + /* set rule address */ + for (i = 1; i < 7; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(slct[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + /* set rule enable */ + HSL_REG_ENTRY_GEN_SET(rv, dev_id, base, sizeof (a_uint32_t), + (a_uint8_t *) (&(slct[0])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +sw_error_t +garuda_acl_rule_read(a_uint32_t dev_id, a_uint32_t rule_idx, a_uint32_t vlu[8], + a_uint32_t msk[8]) +{ + sw_error_t rv; + a_uint32_t i, base, addr; + + /* get rule value */ + base = GARUDA_RULE_VLU_ADDR + (rule_idx << 5); + for (i = 0; i < 5; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(vlu[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + /* get rule mask */ + base = GARUDA_RULE_MSK_ADDR + (rule_idx << 5); + for (i = 0; i < 5; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(msk[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +sw_error_t +garuda_acl_action_read(a_uint32_t dev_id, a_uint32_t act_idx, + a_uint32_t * act) +{ + sw_error_t rv; + a_uint32_t addr; + + /* get rule action */ + addr = GARUDA_RULE_ACT_ADDR + (act_idx << 5); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) act, sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +sw_error_t +garuda_acl_slct_read(a_uint32_t dev_id, a_uint32_t slct_idx, + a_uint32_t slct[8]) +{ + sw_error_t rv; + a_uint32_t i, base, addr; + + base = GARUDA_RULE_SLCT_ADDR + (slct_idx << 5); + + /* get filter address and enable */ + for (i = 0; i < 7; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(slct[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_reg_access.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_reg_access.c new file mode 100755 index 000000000..2fb078429 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_reg_access.c @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 "hsl.h" +#include "hsl_dev.h" +#include "sd.h" +#include "garuda_reg_access.h" + +static hsl_access_mode reg_mode; + +#if defined(API_LOCK) +static aos_lock_t mdio_lock; +#define MDIO_LOCKER_INIT aos_lock_init(&mdio_lock) +#define MDIO_LOCKER_LOCK aos_lock(&mdio_lock) +#define MDIO_LOCKER_UNLOCK aos_unlock(&mdio_lock) +#else +#define MDIO_LOCKER_INIT +#define MDIO_LOCKER_LOCK +#define MDIO_LOCKER_UNLOCK +#endif + +static sw_error_t +_garuda_mdio_reg_get(a_uint32_t dev_id, a_uint32_t reg_addr, + a_uint8_t value[], a_uint32_t value_len) +{ + a_uint32_t reg_word_addr; + a_uint32_t phy_addr, reg_val; + a_uint16_t phy_val, tmp_val; + a_uint8_t phy_reg; + sw_error_t rv; + + if (value_len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + + /* change reg_addr to 16-bit word address, 32-bit aligned */ + reg_word_addr = (reg_addr & 0xfffffffc) >> 1; + + /* configure register high address */ + phy_addr = 0x18; + phy_reg = 0x0; + phy_val = (a_uint16_t) ((reg_word_addr >> 8) & 0x3ff); /* bit16-8 of reg address */ + + rv = sd_reg_mdio_set(dev_id, phy_addr, phy_reg, phy_val); + SW_RTN_ON_ERROR(rv); + + /* For some registers such as MIBs, since it is read/clear, we should */ + /* read the lower 16-bit register then the higher one */ + + /* read register in lower address */ + phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */ + phy_reg = (a_uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */ + rv = sd_reg_mdio_get(dev_id, phy_addr, phy_reg, &tmp_val); + SW_RTN_ON_ERROR(rv); + reg_val = tmp_val; + + /* read register in higher address */ + reg_word_addr++; + phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */ + phy_reg = (a_uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */ + rv = sd_reg_mdio_get(dev_id, phy_addr, phy_reg, &tmp_val); + SW_RTN_ON_ERROR(rv); + reg_val |= (((a_uint32_t)tmp_val) << 16); + + aos_mem_copy(value, ®_val, sizeof (a_uint32_t)); + + return SW_OK; +} + +static sw_error_t +_garuda_mdio_reg_set(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t value[], + a_uint32_t value_len) +{ + a_uint32_t reg_word_addr; + a_uint32_t phy_addr, reg_val; + a_uint16_t phy_val; + a_uint8_t phy_reg; + sw_error_t rv; + + if (value_len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + + aos_mem_copy(®_val, value, sizeof (a_uint32_t)); + + /* change reg_addr to 16-bit word address, 32-bit aligned */ + reg_word_addr = (reg_addr & 0xfffffffc) >> 1; + + /* configure register high address */ + phy_addr = 0x18; + phy_reg = 0x0; + phy_val = (a_uint16_t) ((reg_word_addr >> 8) & 0x3ff); /* bit16-8 of reg address */ + + rv = sd_reg_mdio_set(dev_id, phy_addr, phy_reg, phy_val); + SW_RTN_ON_ERROR(rv); + + /* For some registers such as ARL and VLAN, since they include BUSY bit */ + /* in lower address, we should write the higher 16-bit register then the */ + /* lower one */ + + /* write register in higher address */ + reg_word_addr++; + phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */ + phy_reg = (a_uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */ + phy_val = (a_uint16_t) ((reg_val >> 16) & 0xffff); + rv = sd_reg_mdio_set(dev_id, phy_addr, phy_reg, phy_val); + SW_RTN_ON_ERROR(rv); + + /* write register in lower address */ + reg_word_addr--; + phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */ + phy_reg = (a_uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */ + phy_val = (a_uint16_t) (reg_val & 0xffff); + rv = sd_reg_mdio_set(dev_id, phy_addr, phy_reg, phy_val); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +sw_error_t +garuda_phy_get(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t * value) +{ + sw_error_t rv; + + MDIO_LOCKER_LOCK; + rv = sd_reg_mdio_get(dev_id, phy_addr, reg, value); + MDIO_LOCKER_UNLOCK; + + return rv; +} + +sw_error_t +garuda_phy_set(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t value) +{ + sw_error_t rv; + + MDIO_LOCKER_LOCK; + rv = sd_reg_mdio_set(dev_id, phy_addr, reg, value); + MDIO_LOCKER_UNLOCK; + + return rv; +} + +sw_error_t +garuda_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; + a_uint32_t flags; + + MDIO_LOCKER_LOCK; + if (HSL_MDIO == reg_mode) + { + aos_irq_save(flags); + rv = _garuda_mdio_reg_get(dev_id, reg_addr, value, value_len); + aos_irq_restore(flags); + } + else + { + rv = sd_reg_hdr_get(dev_id, reg_addr, value, value_len); + } + MDIO_LOCKER_UNLOCK; + + return rv; +} + +sw_error_t +garuda_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; + a_uint32_t flags; + + MDIO_LOCKER_LOCK; + if (HSL_MDIO == reg_mode) + { + aos_irq_save(flags); + rv = _garuda_mdio_reg_set(dev_id, reg_addr, value, value_len); + aos_irq_restore(flags); + } + else + { + rv = sd_reg_hdr_set(dev_id, reg_addr, value, value_len); + } + MDIO_LOCKER_UNLOCK; + + return rv; +} + +sw_error_t +garuda_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) +{ + a_uint32_t reg_val = 0; + + if ((bit_offset >= 32 || (field_len > 32)) || (field_len == 0)) + return SW_OUT_OF_RANGE; + + if (value_len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + + SW_RTN_ON_ERROR(garuda_reg_get(dev_id, reg_addr, (a_uint8_t *) & reg_val, sizeof (a_uint32_t))); + + *((a_uint32_t *) value) = SW_REG_2_FIELD(reg_val, bit_offset, field_len); + return SW_OK; +} + +sw_error_t +garuda_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) +{ + a_uint32_t reg_val; + a_uint32_t field_val = *((a_uint32_t *) value); + + if ((bit_offset >= 32 || (field_len > 32)) || (field_len == 0)) + return SW_OUT_OF_RANGE; + + if (value_len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + + SW_RTN_ON_ERROR(garuda_reg_get(dev_id, reg_addr, (a_uint8_t *) & reg_val, sizeof (a_uint32_t))); + + SW_REG_SET_BY_FIELD_U32(reg_val, field_val, bit_offset, field_len); + + SW_RTN_ON_ERROR(garuda_reg_set(dev_id, reg_addr, (a_uint8_t *) & reg_val, sizeof (a_uint32_t))); + + return SW_OK; +} + +sw_error_t +garuda_reg_access_init(a_uint32_t dev_id, hsl_access_mode mode) +{ + hsl_api_t *p_api; + + MDIO_LOCKER_INIT; + reg_mode = mode; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->phy_get = garuda_phy_get; + p_api->phy_set = garuda_phy_set; + p_api->reg_get = garuda_reg_get; + p_api->reg_set = garuda_reg_set; + p_api->reg_field_get = garuda_reg_field_get; + p_api->reg_field_set = garuda_reg_field_set; + p_api->dev_access_set= garuda_access_mode_set; + + return SW_OK; +} + +sw_error_t +garuda_access_mode_set(a_uint32_t dev_id, hsl_access_mode mode) +{ + reg_mode = mode; + return SW_OK; + +} diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_stp.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_stp.c new file mode 100755 index 000000000..b05435c05 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_stp.c @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 garuda_stp GARUDA_STP + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "garuda_stp.h" +#include "garuda_reg.h" + +#define GARUDA_PORT_DISABLED 0 +#define GARUDA_STP_BLOCKING 1 +#define GARUDA_STP_LISTENING 2 +#define GARUDA_STP_LEARNING 3 +#define GARUDA_STP_FARWARDING 4 + +static sw_error_t +_garuda_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; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_SINGLE_STP_ID != st_id) + { + return SW_BAD_PARAM; + } + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + switch (state) + { + case FAL_STP_BLOKING: + val = GARUDA_STP_BLOCKING; + break; + case FAL_STP_LISTENING: + val = GARUDA_STP_LISTENING; + break; + case FAL_STP_LEARNING: + val = GARUDA_STP_LEARNING; + break; + case FAL_STP_FARWARDING: + val = GARUDA_STP_FARWARDING; + break; + case FAL_STP_DISABLED: + val = GARUDA_PORT_DISABLED; + break; + default: + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, PORT_STATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_garuda_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; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_SINGLE_STP_ID != st_id) + { + return SW_BAD_PARAM; + } + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, PORT_STATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + switch (val) + { + case GARUDA_STP_BLOCKING: + *state = FAL_STP_BLOKING; + break; + case GARUDA_STP_LISTENING: + *state = FAL_STP_LISTENING; + break; + case GARUDA_STP_LEARNING: + *state = FAL_STP_LEARNING; + break; + case GARUDA_STP_FARWARDING: + *state = FAL_STP_FARWARDING; + break; + case GARUDA_PORT_DISABLED: + *state = FAL_STP_DISABLED; + break; + default: + return SW_FAIL; + } + + return SW_OK; +} + +/** + * @brief Set port stp state on a particular spanning tree and port. + * @details Comments: + GARUDA only support single spanning tree so st_id should be + FAL_SINGLE_STP_ID that is zero. + * @param[in] dev_id device id + * @param[in] st_id spanning tree id + * @param[in] port_id port id + * @param[in] state port state for spanning tree + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_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; + + HSL_API_LOCK; + rv = _garuda_stp_port_state_set(dev_id, st_id, port_id, state); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get port stp state on a particular spanning tree and port. + * @details Comments: + GARUDA only support single spanning tree so st_id should be + FAL_SINGLE_STP_ID that is zero. + * @param[in] dev_id device id + * @param[in] st_id spanning tree id + * @param[in] port_id port id + * @param[out] state port state for spanning tree + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_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; + + HSL_API_LOCK; + rv = _garuda_stp_port_state_get(dev_id, st_id, port_id, state); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +garuda_stp_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->stp_port_state_set = garuda_stp_port_state_set; + p_api->stp_port_state_get = garuda_stp_port_state_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_vlan.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_vlan.c new file mode 100755 index 000000000..5f001d5c9 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/garuda/garuda_vlan.c @@ -0,0 +1,498 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 garuda_vlan GARUDA_VLAN + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "garuda_vlan.h" +#include "garuda_reg.h" + +#define MAX_VLAN_ID 4095 + +#define VLAN_FLUSH 1 +#define VLAN_LOAD_ENTRY 2 +#define VLAN_PURGE_ENTRY 3 +#define VLAN_REMOVE_PORT 4 +#define VLAN_NEXT_ENTRY 5 +#define VLAN_FIND_ENTRY 6 + +static void +garuda_vlan_hw_to_sw(const a_uint32_t reg[], fal_vlan_t * vlan_entry) +{ + a_uint32_t data; + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC0, VT_PRI_EN, data, reg[0]); + if (1 == data) + { + vlan_entry->vid_pri_en = A_TRUE; + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC0, VT_PRI, data, reg[0]); + vlan_entry->vid_pri = data & 0xff; + } + else + { + vlan_entry->vid_pri_en = A_FALSE; + } + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC0, VLAN_ID, data, reg[0]); + vlan_entry->vid = data & 0xffff; + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC1, VID_MEM, data, reg[1]); + vlan_entry->mem_ports = data; + + return; +} + +static sw_error_t +garuda_vlan_sw_to_hw(const fal_vlan_t * vlan_entry, a_uint32_t reg[]) +{ + if (A_TRUE == vlan_entry->vid_pri_en) + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_PRI_EN, 1, reg[0]); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_PRI, vlan_entry->vid_pri, reg[0]); + } + else + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_PRI_EN, 0, reg[0]); + } + + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VLAN_ID, vlan_entry->vid, reg[0]); + + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC1, VT_VALID, 1, reg[1]); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC1, VID_MEM, vlan_entry->mem_ports, reg[1]); + + if (0 != vlan_entry->u_ports) + { + return SW_BAD_VALUE; + } + + return SW_OK; +} + +static sw_error_t +garuda_vlan_commit(a_uint32_t dev_id, a_uint32_t op) +{ + a_uint32_t vt_busy = 1, i = 0x1000, vt_full, val; + sw_error_t rv; + + while (vt_busy && --i) + { + HSL_REG_FIELD_GET(rv, dev_id, VLAN_TABLE_FUNC0, 0, VT_BUSY, + (a_uint8_t *) (&vt_busy), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + aos_udelay(5); + } + + if (i == 0) + return SW_BUSY; + + HSL_REG_ENTRY_GET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_FUNC, op, val); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_BUSY, 1, val); + + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + vt_busy = 1; + i = 0x1000; + while (vt_busy && --i) + { + HSL_REG_FIELD_GET(rv, dev_id, VLAN_TABLE_FUNC0, 0, VT_BUSY, + (a_uint8_t *) (&vt_busy), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + aos_udelay(5); + } + + if (i == 0) + return SW_FAIL; + + HSL_REG_FIELD_GET(rv, dev_id, VLAN_TABLE_FUNC0, 0, VT_FULL_VIO, + (a_uint8_t *) (&vt_full), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (vt_full) + { + val = 0x10; + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + if (VLAN_LOAD_ENTRY == op) + { + return SW_FULL; + } + else if (VLAN_PURGE_ENTRY == op) + { + return SW_NOT_FOUND; + } + } + + HSL_REG_FIELD_GET(rv, dev_id, VLAN_TABLE_FUNC1, 0, VT_VALID, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (!val) + { + if (VLAN_FIND_ENTRY == op) + return SW_NOT_FOUND; + + if (VLAN_NEXT_ENTRY == op) + return SW_NO_MORE; + } + + return SW_OK; +} + +static sw_error_t +_garuda_vlan_entry_append(a_uint32_t dev_id, const fal_vlan_t * vlan_entry) +{ + sw_error_t rv; + a_uint32_t reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + if ((vlan_entry->vid == 0) || (vlan_entry->vid > MAX_VLAN_ID)) + return SW_OUT_OF_RANGE; + + if (A_FALSE == hsl_mports_prop_check(dev_id, vlan_entry->mem_ports, HSL_PP_INCL_CPU)) + return SW_BAD_PARAM; + + rv = garuda_vlan_sw_to_hw(vlan_entry, reg); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = garuda_vlan_commit(dev_id, VLAN_LOAD_ENTRY); + return rv; +} + +static sw_error_t +_garuda_vlan_create(a_uint32_t dev_id, a_uint32_t vlan_id) +{ + sw_error_t rv; + a_uint32_t entry = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if ((vlan_id == 0) || (vlan_id > MAX_VLAN_ID)) + return SW_OUT_OF_RANGE; + + /* set default value for VLAN_TABLE_FUNC0, all 0 except vid */ + entry = 0; + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VLAN_ID, vlan_id, entry); + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + /* set default value for VLAN_TABLE_FUNC1, all 0 */ + entry = 0; + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC1, VT_VALID, 1, entry); + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = garuda_vlan_commit(dev_id, VLAN_LOAD_ENTRY); + return rv; +} + +static sw_error_t +_garuda_vlan_next(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan) +{ + sw_error_t rv; + a_uint32_t reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (vlan_id > MAX_VLAN_ID) + return SW_OUT_OF_RANGE; + + aos_mem_zero(p_vlan, sizeof (fal_vlan_t)); + + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VLAN_ID, vlan_id, reg[0]); + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + rv = garuda_vlan_commit(dev_id, VLAN_NEXT_ENTRY); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + garuda_vlan_hw_to_sw(reg, p_vlan); + + if (0 == p_vlan->vid) + return SW_NO_MORE; + else + return SW_OK; +} + +static sw_error_t +_garuda_vlan_find(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan) +{ + sw_error_t rv; + a_uint32_t reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + if ((vlan_id == 0) || (vlan_id > MAX_VLAN_ID)) + return SW_OUT_OF_RANGE; + + aos_mem_zero(p_vlan, sizeof (fal_vlan_t)); + + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VLAN_ID, vlan_id, reg[0]); + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + rv = garuda_vlan_commit(dev_id, VLAN_FIND_ENTRY); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + garuda_vlan_hw_to_sw(reg, p_vlan); + + return SW_OK; +} + +static sw_error_t +_garuda_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; + a_uint32_t reg = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if ((vlan_id == 0) || (vlan_id > MAX_VLAN_ID)) + return SW_OUT_OF_RANGE; + + if (A_FALSE == hsl_mports_prop_check(dev_id, member, HSL_PP_INCL_CPU)) + return SW_BAD_PARAM; + + if (u_member != 0) + return SW_BAD_PARAM; + + /* get vlan entry first */ + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VLAN_ID, vlan_id, reg); + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + rv = garuda_vlan_commit(dev_id, VLAN_FIND_ENTRY); + SW_RTN_ON_ERROR(rv); + + /* set vlan member for VLAN_TABLE_FUNC1 */ + HSL_REG_FIELD_SET(rv, dev_id, VLAN_TABLE_FUNC1, 0, VID_MEM, + (a_uint8_t *) (&member), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = garuda_vlan_commit(dev_id, VLAN_LOAD_ENTRY); + /* when update port member through LOAD opration, hardware will + return VT_FULL_VIO, we should ignore it */ + if (SW_FULL == rv) + rv = SW_OK; + + return rv; +} + + +static sw_error_t +_garuda_vlan_delete(a_uint32_t dev_id, a_uint32_t vlan_id) +{ + sw_error_t rv; + a_uint32_t reg; + + HSL_DEV_ID_CHECK(dev_id); + + if ((vlan_id == 0) || (vlan_id > MAX_VLAN_ID)) + return SW_OUT_OF_RANGE; + + reg = (a_int32_t) vlan_id; + HSL_REG_FIELD_SET(rv, dev_id, VLAN_TABLE_FUNC0, 0, VLAN_ID, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = garuda_vlan_commit(dev_id, VLAN_PURGE_ENTRY); + return rv; +} + +/** + * @brief Append a vlan entry on paticular device. + * @param[in] dev_id device id + * @param[in] vlan_entry vlan entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_vlan_entry_append(a_uint32_t dev_id, const fal_vlan_t * vlan_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_vlan_entry_append(dev_id, vlan_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Creat a vlan entry through vlan id on a paticular device. + * @details Comments: + * After this operation the member ports of the created vlan entry are null. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_vlan_create(a_uint32_t dev_id, a_uint32_t vlan_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_vlan_create(dev_id, vlan_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Next a vlan entry through vlan id on a paticular device. + * @details Comments: + * If the value of vid is zero this operation will get the first entry. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[out] p_vlan vlan entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_vlan_next(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_vlan_next(dev_id, vlan_id, p_vlan); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Find a vlan entry through vlan id on paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[out] p_vlan vlan entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_vlan_find(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_vlan_find(dev_id, vlan_id, p_vlan); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Update a vlan entry member port through vlan id on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[in] member member ports + * @param[in] u_member tagged or untagged infomation for member ports + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_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; + + HSL_API_LOCK; + rv = _garuda_vlan_member_update(dev_id, vlan_id, member, u_member); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a vlan entry through vlan id on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +garuda_vlan_delete(a_uint32_t dev_id, a_uint32_t vlan_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _garuda_vlan_delete(dev_id, vlan_id); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +garuda_vlan_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->vlan_entry_append = garuda_vlan_entry_append; + p_api->vlan_creat = garuda_vlan_create; + p_api->vlan_member_update = garuda_vlan_member_update; + p_api->vlan_delete = garuda_vlan_delete; + p_api->vlan_next = garuda_vlan_next; + p_api->vlan_find = garuda_vlan_find; + +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/Makefile b/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/Makefile new file mode 100755 index 000000000..bdbd6c0b2 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/Makefile @@ -0,0 +1,80 @@ +LOC_DIR=src/hsl/horus +LIB=HSL + +include $(PRJ_PATH)/make/config.mk + +SRC_LIST=horus_reg_access.c horus_init.c + +ifeq (TRUE, $(IN_FDB)) + SRC_LIST += horus_fdb.c +endif + +ifeq (TRUE, $(IN_IGMP)) + SRC_LIST += horus_igmp.c +endif + +ifeq (TRUE, $(IN_LEAKY)) + SRC_LIST += horus_leaky.c +endif + +ifeq (TRUE, $(IN_LED)) + SRC_LIST += horus_led.c +endif + +ifeq (TRUE, $(IN_MIB)) + SRC_LIST += horus_mib.c +endif + +ifeq (TRUE, $(IN_MIRROR)) + SRC_LIST += horus_mirror.c +endif + +ifeq (TRUE, $(IN_MISC)) + SRC_LIST += horus_misc.c +endif + +ifeq (TRUE, $(IN_PORTCONTROL)) + SRC_LIST += horus_port_ctrl.c +endif + +ifeq (TRUE, $(IN_PORTVLAN)) + SRC_LIST += horus_portvlan.c +endif + +ifeq (TRUE, $(IN_QOS)) + SRC_LIST += horus_qos.c +endif + +ifeq (TRUE, $(IN_RATE)) + SRC_LIST += horus_rate.c +endif + +ifeq (TRUE, $(IN_STP)) + SRC_LIST += horus_stp.c +endif + +ifeq (TRUE, $(IN_VLAN)) + SRC_LIST += horus_vlan.c +endif + +ifeq (TRUE, $(IN_REDUCED_ACL)) + SRC_LIST += horus_reduced_acl.c +endif + +ifeq (linux, $(OS)) + ifeq (KSLIB, $(MODULE_TYPE)) + ifneq (TRUE, $(KERNEL_MODE)) + SRC_LIST=horus_reg_access.c horus_init.c + endif + endif +endif + +ifeq (, $(findstring HORUS, $(SUPPORT_CHIP))) + SRC_LIST= +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/src/src/hsl/horus/horus_fdb.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_fdb.c new file mode 100755 index 000000000..6ca18e032 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_fdb.c @@ -0,0 +1,999 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 horus_fdb HORUS_FDB + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "horus_fdb.h" +#include "horus_reg.h" + +#define ARL_FLUSH_ALL 1 +#define ARL_LOAD_ENTRY 2 +#define ARL_PURGE_ENTRY 3 +#define ARL_FLUSH_ALL_UNLOCK 4 +#define ARL_FLUSH_PORT_UNICAST 5 +#define ARL_NEXT_ENTRY 6 +#define ARL_FIND_ENTRY 7 + +#define ARL_FIRST_ENTRY 1001 +#define ARL_FLUSH_PORT_NO_STATIC 1002 +#define ARL_FLUSH_PORT_AND_STATIC 1003 + +static a_bool_t +horus_fdb_is_zeroaddr(fal_mac_addr_t addr) +{ + a_uint32_t i; + + for (i = 0; i < 6; i++) + { + if (addr.uc[i]) + { + return A_FALSE; + } + } + + return A_TRUE; +} + +static void +horus_fdb_fill_addr(fal_mac_addr_t addr, a_uint32_t * reg0, a_uint32_t * reg1) +{ + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_ADDR_BYTE0, addr.uc[0], *reg1); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_ADDR_BYTE1, addr.uc[1], *reg1); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_ADDR_BYTE2, addr.uc[2], *reg1); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_ADDR_BYTE3, addr.uc[3], *reg1); + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_ADDR_BYTE4, addr.uc[4], *reg0); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_ADDR_BYTE5, addr.uc[5], *reg0); + + return; +} + +static sw_error_t +horus_atu_sw_to_hw(a_uint32_t dev_id, const fal_fdb_entry_t * entry, + a_uint32_t reg[]) +{ + a_uint32_t port; + + if (A_FALSE == entry->portmap_en) + { + if (A_TRUE != + hsl_port_prop_check(dev_id, entry->port.id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + port = 0x1UL << entry->port.id; + } + else + { + if (A_FALSE == + hsl_mports_prop_check(dev_id, entry->port.map, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + port = entry->port.map; + } + + if (FAL_MAC_CPY_TO_CPU == entry->dacmd) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, COPY_TO_CPU, 1, reg[2]); + } + else if (FAL_MAC_RDT_TO_CPU == entry->dacmd) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, REDRCT_TO_CPU, 1, reg[2]); + } + else if (FAL_MAC_FRWRD != entry->dacmd) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_MAC_DROP == entry->sacmd) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, SA_DROP_EN, 1, reg[2]); + } + else if (FAL_MAC_FRWRD != entry->sacmd) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == entry->leaky_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, LEAKY_EN, 1, reg[2]); + } + else + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, LEAKY_EN, 0, reg[2]); + } + + if (A_TRUE == entry->static_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_STATUS, 15, reg[2]); + } + else + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_STATUS, 7, reg[2]); + } + + if (A_TRUE == entry->mirror_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, MIRROR_EN, 1, reg[2]); + } + + if (A_TRUE == entry->clone_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, CLONE_EN, 1, reg[2]); + } + + if (A_TRUE == entry->cross_pt_state) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, CROSS_PT, 1, reg[2]); + } + + if (A_TRUE == entry->da_pri_en) + { + hsl_dev_t *p_dev; + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_PRI_EN, 1, reg[2]); + + SW_RTN_ON_NULL(p_dev = hsl_dev_ptr_get(dev_id)); + + if (entry->da_queue > (p_dev->nr_queue - 1)) + return SW_BAD_PARAM; + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_PRI, entry->da_queue, reg[2]); + } + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, DES_PORT, port, reg[2]); + horus_fdb_fill_addr(entry->addr, ®[0], ®[1]); + + return SW_OK; +} + +static void +horus_atu_hw_to_sw(const a_uint32_t reg[], fal_fdb_entry_t * entry) +{ + a_uint32_t i, data; + + aos_mem_zero(entry, sizeof (fal_fdb_entry_t)); + + entry->dacmd = FAL_MAC_FRWRD; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, COPY_TO_CPU, data, reg[2]); + if (1 == data) + { + entry->dacmd = FAL_MAC_CPY_TO_CPU; + } + + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, REDRCT_TO_CPU, data, reg[2]); + if (1 == data) + { + entry->dacmd = FAL_MAC_RDT_TO_CPU; + } + + entry->sacmd = FAL_MAC_FRWRD; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, SA_DROP_EN, data, reg[2]); + if (1 == data) + { + entry->sacmd = FAL_MAC_DROP; + } + + entry->leaky_en = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, LEAKY_EN, data, reg[2]); + if (1 == data) + { + entry->leaky_en = A_TRUE; + } + + entry->static_en = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, AT_STATUS, data, reg[2]); + if (0xf == data) + { + entry->static_en = A_TRUE; + } + + entry->mirror_en = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, MIRROR_EN, data, reg[2]); + if (1 == data) + { + entry->mirror_en = A_TRUE; + } + + entry->clone_en = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, CLONE_EN, data, reg[2]); + if (1 == data) + { + entry->clone_en = A_TRUE; + } + + entry->da_pri_en = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, AT_PRI_EN, data, reg[2]); + if (1 == data) + { + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, AT_PRI, data, reg[2]); + entry->da_pri_en = A_TRUE; + entry->da_queue = data & 0x3; + } + + entry->cross_pt_state = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, CROSS_PT, data, reg[2]); + if (1 == data) + { + entry->cross_pt_state = A_TRUE; + } + + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, DES_PORT, data, reg[2]); + + entry->portmap_en = A_TRUE; + entry->port.map = data; + + for (i = 0; i < 4; i++) + { + entry->addr.uc[i] = (reg[1] >> ((3 - i) << 3)) & 0xff; + } + + for (i = 4; i < 6; i++) + { + entry->addr.uc[i] = (reg[0] >> ((7 - i) << 3)) & 0xff; + } + + return; +} + +static sw_error_t +horus_fdb_commit(a_uint32_t dev_id, a_uint32_t op) +{ + sw_error_t rv; + a_uint32_t busy = 1; + a_uint32_t full_vio; + a_uint32_t i = 1000; + a_uint32_t entry; + a_uint32_t hwop = op; + + while (busy && --i) + { + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_FUNC0, 0, AT_BUSY, + (a_uint8_t *) (&busy), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + aos_udelay(5); + } + + if (0 == i) + { + return SW_BUSY; + } + + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC0, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_BUSY, 1, entry); + + if (ARL_FLUSH_PORT_AND_STATIC == hwop) + { + hwop = ARL_FLUSH_PORT_UNICAST; + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, FLUSH_ST_EN, 1, entry); + } + + if (ARL_FLUSH_PORT_NO_STATIC == hwop) + { + hwop = ARL_FLUSH_PORT_UNICAST; + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, FLUSH_ST_EN, 0, entry); + } + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_FUNC, hwop, entry); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC0, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + busy = 1; + i = 1000; + while (busy && --i) + { + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_FUNC0, 0, AT_BUSY, + (a_uint8_t *) (&busy), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + aos_udelay(5); + } + + if (0 == i) + { + return SW_FAIL; + } + + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_FUNC0, 0, AT_FULL_VIO, + (a_uint8_t *) (&full_vio), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (full_vio) + { + /* must clear AT_FULL_VOI bit */ + entry = 0x1000; + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC0, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (ARL_LOAD_ENTRY == hwop) + { + return SW_FULL; + } + else if ((ARL_PURGE_ENTRY == hwop) + || (ARL_FLUSH_PORT_UNICAST == hwop)) + { + return SW_NOT_FOUND; + } + else + { + return SW_FAIL; + } + } + + return SW_OK; +} + +static sw_error_t +horus_atu_get(a_uint32_t dev_id, fal_fdb_entry_t * entry, a_uint32_t op) +{ + sw_error_t rv; + a_uint32_t reg[3] = { 0 }; + a_uint32_t status = 0; + a_uint32_t hwop = op; + + if ((ARL_NEXT_ENTRY == op) + || (ARL_FIND_ENTRY == op)) + { + horus_fdb_fill_addr(entry->addr, ®[0], ®[1]); + } + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* set status not zero */ + if (ARL_NEXT_ENTRY == op) + { + reg[2] = 0xf0000; + } + + if (ARL_FIRST_ENTRY == op) + { + hwop = ARL_NEXT_ENTRY; + } + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC2, 0, + (a_uint8_t *) (®[2]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = horus_fdb_commit(dev_id, hwop); + SW_RTN_ON_ERROR(rv); + + /* get hardware enrety */ + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC2, 0, + (a_uint8_t *) (®[2]), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, AT_STATUS, status, reg[2]); + + horus_atu_hw_to_sw(reg, entry); + + /* If hardware return back with address and status all zero, + that means no other next valid entry in fdb table */ + if ((A_TRUE == horus_fdb_is_zeroaddr(entry->addr)) + && (0 == status)) + { + if (ARL_NEXT_ENTRY == op) + { + return SW_NO_MORE; + } + else if ((ARL_FIND_ENTRY == op) + || (ARL_FIRST_ENTRY == op)) + { + return SW_NOT_FOUND; + } + else + { + return SW_FAIL; + } + } + else + { + return SW_OK; + } +} + +static sw_error_t +_horus_fdb_add(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t reg[3] = { 0, 0, 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = horus_atu_sw_to_hw(dev_id, entry, reg); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC2, 0, + (a_uint8_t *) (®[2]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC1, 0, (a_uint8_t *) (®[1]), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC0, 0, (a_uint8_t *) (®[0]), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = horus_fdb_commit(dev_id, ARL_LOAD_ENTRY); + + return rv; +} + +static sw_error_t +_horus_fdb_del_all(a_uint32_t dev_id, a_uint32_t flag) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_FDB_DEL_STATIC & flag) + { + rv = horus_fdb_commit(dev_id, ARL_FLUSH_ALL); + } + else + { + rv = horus_fdb_commit(dev_id, ARL_FLUSH_ALL_UNLOCK); + } + + return rv; +} + +static sw_error_t +_horus_fdb_del_by_port(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t flag) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_PORT_NUM, port_id, reg); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC0, 0, (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_FDB_DEL_STATIC & flag) + { + rv = horus_fdb_commit(dev_id, ARL_FLUSH_PORT_AND_STATIC); + } + else + { + rv = horus_fdb_commit(dev_id, ARL_FLUSH_PORT_NO_STATIC); + } + + return rv; +} + +static sw_error_t +_horus_fdb_del_by_mac(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t reg0 = 0, reg1 = 0; + + HSL_DEV_ID_CHECK(dev_id); + + horus_fdb_fill_addr(entry->addr, ®0, ®1); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC1, 0, (a_uint8_t *) (®1), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC0, 0, (a_uint8_t *) (®0), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = horus_fdb_commit(dev_id, ARL_PURGE_ENTRY); + return rv; +} + +static sw_error_t +_horus_fdb_next(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + rv = horus_atu_get(dev_id, entry, ARL_NEXT_ENTRY); + return rv; +} + +static sw_error_t +_horus_fdb_first(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + rv = horus_atu_get(dev_id, entry, ARL_FIRST_ENTRY); + return rv; +} + +static sw_error_t +_horus_fdb_find(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + rv = horus_atu_get(dev_id, entry, ARL_FIND_ENTRY); + return rv; +} + +static sw_error_t +_horus_fdb_port_learn_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, LEARN_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_fdb_port_learn_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, LEARN_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_horus_fdb_age_ctrl_set(a_uint32_t dev_id, a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, ADDR_TABLE_CTL, 0, AGE_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_fdb_age_ctrl_get(a_uint32_t dev_id, a_bool_t *enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_CTL, 0, AGE_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_horus_fdb_age_time_set(a_uint32_t dev_id, a_uint32_t * time) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if ((65535 * 7 < *time) || (7 > *time)) + { + return SW_BAD_PARAM; + } + data = *time / 7; + *time = data * 7; + HSL_REG_FIELD_SET(rv, dev_id, ADDR_TABLE_CTL, 0, AGE_TIME, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_fdb_age_time_get(a_uint32_t dev_id, a_uint32_t *time) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_CTL, 0, AGE_TIME, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *time = data * 7; + return SW_OK; +} + +/** + * @brief Add a Fdb entry + * @param[in] dev_id device id + * @param[in] entry fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_fdb_add(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_fdb_add(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete all Fdb entries + * @details Comments: + * If set FAL_FDB_DEL_STATIC bit in flag which means delete all fdb + * entries otherwise only delete dynamic entries. + * @param[in] dev_id device id + * @param[in] flag delete operation option + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_fdb_del_all(a_uint32_t dev_id, a_uint32_t flag) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_fdb_del_all(dev_id, flag); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete Fdb entries on a particular port + * @details Comments: + * If set FAL_FDB_DEL_STATIC bit in flag which means delete all fdb + * entries otherwise only delete dynamic entries. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] flag delete operation option + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_fdb_del_by_port(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t flag) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_fdb_del_by_port(dev_id, port_id, flag); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a particular Fdb entry through mac address + * @details Comments: + * Only addr field in entry is meaning. For IVL learning vid or fid field + * also is meaning. + * @param[in] dev_id device id + * @param[in] entry fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_fdb_del_by_mac(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_fdb_del_by_mac(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get next Fdb entry from particular device + * @details Comments: + * For input parameter only addr field in entry is meaning. + * @param[in] dev_id device id + * @param entry fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_fdb_next(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_fdb_next(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get first Fdb entry from particular device + * @param[in] dev_id device id + * @param[out] entry fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_fdb_first(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_fdb_first(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Find a particular Fdb entry from device through mac address. + * @details Comments: + For input parameter only addr field in entry is meaning. + * @param[in] dev_id device id + * @param[in] entry fdb entry + * @param[out] entry fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_fdb_find(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_fdb_find(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dynamic address learning status on a particular port. + * @details Comments: + * This operation will enable or disable dynamic address learning + * feature on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable enable or disable + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_fdb_port_learn_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_fdb_port_learn_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dynamic address learning status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_fdb_port_learn_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_fdb_port_learn_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dynamic address aging status on particular device. + * @details Comments: + * This operation will enable or disable dynamic address aging + * feature on particular device. + * @param[in] dev_id device id + * @param[in] enable enable or disable + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_fdb_age_ctrl_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_fdb_age_ctrl_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dynamic address aging status on particular device. + * @param[in] dev_id device id + * @param[in] enable enable or disable + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_fdb_age_ctrl_get(a_uint32_t dev_id, a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_fdb_age_ctrl_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dynamic address aging time on a particular device. + * @details Comments: + * This operation will set dynamic address aging time on a particular device. + * The unit of time is second. Because different device has differnet + * hardware granularity function will return actual time in hardware. + * @param[in] dev_id device id + * @param time aging time + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_fdb_age_time_set(a_uint32_t dev_id, a_uint32_t * time) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_fdb_age_time_set(dev_id, time); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dynamic address aging time on a particular device. + * @param[in] dev_id device id + * @param[out] time aging time + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_fdb_age_time_get(a_uint32_t dev_id, a_uint32_t *time) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_fdb_age_time_get(dev_id, time); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +horus_fdb_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->fdb_add = horus_fdb_add; + p_api->fdb_del_all = horus_fdb_del_all; + p_api->fdb_del_by_port = horus_fdb_del_by_port; + p_api->fdb_del_by_mac = horus_fdb_del_by_mac; + p_api->fdb_first = horus_fdb_first; + p_api->fdb_next = horus_fdb_next; + p_api->fdb_find = horus_fdb_find; + p_api->port_learn_set = horus_fdb_port_learn_set; + p_api->port_learn_get = horus_fdb_port_learn_get; + p_api->age_ctrl_set = horus_fdb_age_ctrl_set; + p_api->age_ctrl_get = horus_fdb_age_ctrl_get; + p_api->age_time_set = horus_fdb_age_time_set; + p_api->age_time_get = horus_fdb_age_time_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_igmp.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_igmp.c new file mode 100755 index 000000000..4f42ed2d8 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_igmp.c @@ -0,0 +1,979 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 horus_igmp HORUS_IGMP + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "horus_igmp.h" +#include "horus_reg.h" + +static sw_error_t +_horus_port_igmps_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, IGMP_MLD_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_port_igmps_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, IGMP_MLD_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_horus_igmp_mld_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_MAC_CPY_TO_CPU == cmd) + { + val = 1; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + val = 0; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, QM_CTL, 0, IGMP_COPY_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_igmp_mld_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, QM_CTL, 0, IGMP_COPY_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *cmd = FAL_MAC_CPY_TO_CPU; + } + else + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + + return SW_OK; +} + +static sw_error_t +_horus_port_igmp_mld_join_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, JOIN_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_port_igmp_mld_join_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, JOIN_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_horus_port_igmp_mld_leave_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, LEAVE_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_port_igmp_mld_leave_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, LEAVE_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_horus_igmp_mld_rp_set(a_uint32_t dev_id, fal_pbmp_t pts) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_mports_validity_check(dev_id, pts)) + { + return SW_BAD_PARAM; + } + val = pts; + HSL_REG_FIELD_SET(rv, dev_id, FLOOD_MASK, 0, IGMP_DP, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_igmp_mld_rp_get(a_uint32_t dev_id, fal_pbmp_t * pts) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FLOOD_MASK, 0, IGMP_DP, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *pts = val; + return SW_OK; +} + +static sw_error_t +_horus_igmp_mld_entry_creat_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, QM_CTL, 0, IGMP_CREAT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_igmp_mld_entry_creat_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, QM_CTL, 0, IGMP_CREAT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_horus_igmp_mld_entry_static_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 0xf; + } + else if (A_FALSE == enable) + { + val = 0xe; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, QM_CTL, 0, IGMP_JOIN_STATIC, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_igmp_mld_entry_static_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, QM_CTL, 0, IGMP_JOIN_STATIC, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0xf == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_horus_igmp_mld_entry_leaky_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, QM_CTL, 0, IGMP_JOIN_LEAKY, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_igmp_mld_entry_leaky_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, QM_CTL, 0, IGMP_JOIN_LEAKY, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_horus_igmp_mld_entry_v3_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, QM_CTL, 0, IGMP_V3_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_igmp_mld_entry_v3_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, QM_CTL, 0, IGMP_V3_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_horus_igmp_mld_entry_queue_set(a_uint32_t dev_id, a_bool_t enable, a_uint32_t queue) +{ + sw_error_t rv; + a_uint32_t entry; + hsl_dev_t *p_dev; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_ENTRY_GET(rv, dev_id, QM_CTL, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + SW_SET_REG_BY_FIELD(QM_CTL, IGMP_PRI_EN, 1, entry); + SW_RTN_ON_NULL(p_dev = hsl_dev_ptr_get(dev_id)); + if (queue >= p_dev->nr_queue) + { + return SW_BAD_PARAM; + } + SW_SET_REG_BY_FIELD(QM_CTL, IGMP_PRI, queue, entry); + } + else if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(QM_CTL, IGMP_PRI_EN, 0, entry); + SW_SET_REG_BY_FIELD(QM_CTL, IGMP_PRI, 0, entry); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_SET(rv, dev_id, QM_CTL, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_igmp_mld_entry_queue_get(a_uint32_t dev_id, a_bool_t * enable, a_uint32_t * queue) +{ + sw_error_t rv; + a_uint32_t entry, data; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_ENTRY_GET(rv, dev_id, QM_CTL, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(QM_CTL, IGMP_PRI_EN, data, entry); + if (data) + { + *enable = A_TRUE; + SW_GET_FIELD_BY_REG(QM_CTL, IGMP_PRI, data, entry); + *queue = data; + } + else + { + *enable = A_FALSE; + *queue = 0; + } + + return SW_OK; +} + +/** + * @brief Set igmp/mld packets snooping status on a particular port. + * @details Comments: + * After enabling igmp/mld snooping feature on a particular port all kinds + * igmp/mld packets received on this port would be acknowledged by hardware. + * Particular forwarding decision could be setted by fal_igmp_mld_cmd_set. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_igmps_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_igmps_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld packets snooping status on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_igmps_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_igmps_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmp/mld packets forwarding command on a particular device. + * @details Comments: + * Particular device may only support parts of forwarding commands. + * This operation will take effect only after enabling igmp/mld snooping + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_igmp_mld_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_igmp_mld_cmd_set(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld packets forwarding command on a particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_igmp_mld_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_igmp_mld_cmd_get(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmp/mld join packets hardware acknowledgement status on particular port. + * @details Comments: + * After enabling igmp/mld join feature on a particular port hardware will + * dynamic learning or changing multicast entry. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_igmp_mld_join_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_igmp_mld_join_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld join packets hardware acknowledgement status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_igmp_mld_join_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_igmp_mld_join_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmp/mld leave packets hardware acknowledgement status on a particular port. + * @details Comments: + * After enabling igmp leave feature on a particular port hardware will dynamic + * deleting or changing multicast entry. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_igmp_mld_leave_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_igmp_mld_leave_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld leave packets hardware acknowledgement status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_igmp_mld_leave_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_igmp_mld_leave_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmp/mld router ports on a particular device. + * @details Comments: + * After enabling igmp/mld join/leave feature on a particular port igmp/mld + * join/leave packets received on this port will be forwarded to router ports. + * @param[in] dev_id device id + * @param[in] pts dedicates ports + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_igmp_mld_rp_set(a_uint32_t dev_id, fal_pbmp_t pts) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_igmp_mld_rp_set(dev_id, pts); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld router ports on a particular device. + * @param[in] dev_id device id + * @param[out] pts dedicates ports + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_igmp_mld_rp_get(a_uint32_t dev_id, fal_pbmp_t * pts) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_igmp_mld_rp_get(dev_id, pts); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set the status of creating multicast entry during igmp/mld join/leave procedure. + * @details Comments: + * After enabling igmp/mld join/leave feature on a particular port if enable + * entry creat hardware will dynamic creat and delete multicast entry, + * otherwise hardware only can change destination ports of existing muticast entry. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_igmp_mld_entry_creat_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_igmp_mld_entry_creat_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get the status of creating multicast entry during igmp/mld join/leave procedure. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_igmp_mld_entry_creat_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_igmp_mld_entry_creat_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set the static status of multicast entry which learned by hardware. + * @details Comments: + * After enabling igmp/mld join/leave feature on a particular port if enable + * static status hardware will not age out multicast entry which leardned by hardware, + * otherwise hardware will age out multicast entry which leardned by hardware. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_igmp_mld_entry_static_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_igmp_mld_entry_static_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get the static status of multicast entry which learned by hardware. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_igmp_mld_entry_static_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_igmp_mld_entry_static_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set the leaky status of multicast entry which learned by hardware. + * @details Comments: + * After enabling igmp/mld join/leave feature on a particular port if enable + * leaky status hardware will set leaky flag of multicast entry which leardned by hardware, + * otherwise hardware will not set leaky flag of multicast entry which leardned by hardware. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_igmp_mld_entry_leaky_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_igmp_mld_entry_leaky_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get the leaky status of multicast entry which learned by hardware. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_igmp_mld_entry_leaky_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_igmp_mld_entry_leaky_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmpv3/mldv2 packets hardware acknowledgement status on a particular device. + * @details Comments: + * After enabling igmp join/leave feature on a particular port hardware will dynamic + * creating or changing multicast entry after receiving igmpv3/mldv2 packets. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_igmp_mld_entry_v3_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_igmp_mld_entry_v3_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmpv3/mldv2 packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_igmp_mld_entry_v3_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_igmp_mld_entry_v3_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set the queue status of multicast entry which learned by hardware. + * @details Comments: + * After enabling igmp/mld join/leave feature on a particular port if enable + * leaky status hardware will set queue flag of multicast entry which leardned by hardware, + * otherwise hardware will not set queue flag of multicast entry which leardned by hardware. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] queue queue id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_igmp_mld_entry_queue_set(a_uint32_t dev_id, a_bool_t enable, a_uint32_t queue) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_igmp_mld_entry_queue_set(dev_id, enable, queue); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get the queue status of multicast entry which learned by hardware. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @param[out] queue queue id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_igmp_mld_entry_queue_get(a_uint32_t dev_id, a_bool_t * enable, a_uint32_t * queue) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_igmp_mld_entry_queue_get(dev_id, enable, queue); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +horus_igmp_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->port_igmps_status_set = horus_port_igmps_status_set; + p_api->port_igmps_status_get = horus_port_igmps_status_get; + p_api->igmp_mld_cmd_set = horus_igmp_mld_cmd_set; + p_api->igmp_mld_cmd_get = horus_igmp_mld_cmd_get; + p_api->port_igmp_join_set = horus_port_igmp_mld_join_set; + p_api->port_igmp_join_get = horus_port_igmp_mld_join_get; + p_api->port_igmp_leave_set = horus_port_igmp_mld_leave_set; + p_api->port_igmp_leave_get = horus_port_igmp_mld_leave_get; + p_api->igmp_rp_set = horus_igmp_mld_rp_set; + p_api->igmp_rp_get = horus_igmp_mld_rp_get; + p_api->igmp_entry_creat_set = horus_igmp_mld_entry_creat_set; + p_api->igmp_entry_creat_get = horus_igmp_mld_entry_creat_get; + p_api->igmp_entry_static_set = horus_igmp_mld_entry_static_set; + p_api->igmp_entry_static_get = horus_igmp_mld_entry_static_get; + p_api->igmp_entry_leaky_set = horus_igmp_mld_entry_leaky_set; + p_api->igmp_entry_leaky_get = horus_igmp_mld_entry_leaky_get; + p_api->igmp_entry_v3_set = horus_igmp_mld_entry_v3_set; + p_api->igmp_entry_v3_get = horus_igmp_mld_entry_v3_get; + p_api->igmp_entry_queue_set = horus_igmp_mld_entry_queue_set; + p_api->igmp_entry_queue_get = horus_igmp_mld_entry_queue_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_init.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_init.c new file mode 100755 index 000000000..d22fe8667 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_init.c @@ -0,0 +1,432 @@ +/* + * Copyright (c) 2012, 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 horus_init HORUS_INIT + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "horus_mib.h" +#include "horus_port_ctrl.h" +#include "horus_portvlan.h" +#include "horus_vlan.h" +#include "horus_fdb.h" +#include "horus_qos.h" +#include "horus_mirror.h" +#include "horus_stp.h" +#include "horus_rate.h" +#include "horus_misc.h" +#include "horus_leaky.h" +#include "horus_igmp.h" +#include "horus_led.h" +#include "horus_reg_access.h" +#include "horus_reg.h" +#include "f2_phy.h" + +static ssdk_init_cfg * horus_cfg[SW_MAX_NR_DEV] = { 0 }; + +#if !(defined(KERNEL_MODULE) && defined(USER_MODE)) +static sw_error_t +horus_portproperty_init(a_uint32_t dev_id, hsl_init_mode mode) +{ + hsl_port_prop_t p_type; + hsl_dev_t *pdev = NULL; + fal_port_t port_id; + + pdev = hsl_dev_ptr_get(dev_id); + if (pdev == NULL) + return SW_NOT_INITIALIZED; + + for (port_id = 0; port_id < pdev->nr_ports; port_id++) + { + hsl_port_prop_portmap_set(dev_id, port_id); + + for (p_type = HSL_PP_PHY; p_type < HSL_PP_BUTT; p_type++) + { + if (HSL_NO_CPU == mode) + { + SW_RTN_ON_ERROR(hsl_port_prop_set(dev_id, port_id, p_type)); + continue; + } + + switch (p_type) + { + case HSL_PP_PHY: + if (HSL_CPU_1 != mode) + { + if ((port_id != pdev->cpu_port_nr) + && (port_id != (pdev->nr_ports -1))) + { + SW_RTN_ON_ERROR(hsl_port_prop_set(dev_id, port_id, p_type)); + } + } + else + { + if (port_id != pdev->cpu_port_nr) + { + SW_RTN_ON_ERROR(hsl_port_prop_set(dev_id, port_id, p_type)); + } + } + break; + + case HSL_PP_INCL_CPU: + /* include cpu port and wan port in some cases */ + if (!((HSL_CPU_2 == mode) && (port_id == (pdev->nr_ports - 1)))) + SW_RTN_ON_ERROR(hsl_port_prop_set(dev_id, port_id, p_type)); + + break; + + case HSL_PP_EXCL_CPU: + /* exclude cpu port and wan port in some cases */ + if ((port_id != pdev->cpu_port_nr) + && (!((HSL_CPU_2 == mode) && (port_id == (pdev->nr_ports - 1))))) + SW_RTN_ON_ERROR(hsl_port_prop_set(dev_id, port_id, p_type)); + break; + + default: + break; + } + } + + if (HSL_NO_CPU == mode) + { + SW_RTN_ON_ERROR(hsl_port_prop_set_phyid + (dev_id, port_id, port_id + 1)); + } + else + { + if (port_id != pdev->cpu_port_nr) + { + SW_RTN_ON_ERROR(hsl_port_prop_set_phyid + (dev_id, port_id, port_id - 1)); + } + } + } + + return SW_OK; +} + +static sw_error_t +horus_hw_init(a_uint32_t dev_id, ssdk_init_cfg *cfg) +{ + hsl_dev_t *pdev = NULL; + a_uint32_t port_id; + a_uint32_t data; + sw_error_t rv; + + pdev = hsl_dev_ptr_get(dev_id); + if (NULL == pdev) + { + return SW_NOT_INITIALIZED; + } + + for (port_id = 0; port_id < pdev->nr_ports; port_id++) + { + if (port_id == pdev->cpu_port_nr) + { + continue; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 1, data); + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +static sw_error_t +horus_bist_test(a_uint32_t dev_id) +{ + a_uint32_t entry, data, i; + sw_error_t rv; + + data = 1; + i = 0x1000; + while (data && --i) + { + HSL_REG_ENTRY_GET(rv, dev_id, BIST_CTRL, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + SW_GET_FIELD_BY_REG(BIST_CTRL, BIST_BUSY, data, entry); + aos_udelay(5); + } + + if (0 == i) + { + return SW_INIT_ERROR; + } + + entry = 0; + SW_SET_REG_BY_FIELD(BIST_CTRL, BIST_BUSY, 1, entry); + SW_SET_REG_BY_FIELD(BIST_CTRL, PTN_EN2, 1, entry); + SW_SET_REG_BY_FIELD(BIST_CTRL, PTN_EN1, 1, entry); + SW_SET_REG_BY_FIELD(BIST_CTRL, PTN_EN0, 1, entry); + + HSL_REG_ENTRY_SET(rv, dev_id, BIST_CTRL, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data = 1; + i = 0x1000; + while (data && --i) + { + HSL_REG_ENTRY_GET(rv, dev_id, BIST_CTRL, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + SW_GET_FIELD_BY_REG(BIST_CTRL, BIST_BUSY, data, entry); + aos_udelay(5); + } + + if (0 == i) + { + return SW_INIT_ERROR; + } + + SW_GET_FIELD_BY_REG(BIST_CTRL, ERR_CNT, data, entry); + if (data) + { + SW_GET_FIELD_BY_REG(BIST_CTRL, ONE_ERR, data, entry); + if (!data) + { + return SW_INIT_ERROR; + } + + SW_GET_FIELD_BY_REG(BIST_CTRL, ERR_ADDR, data, entry); + + entry = 0; + SW_SET_REG_BY_FIELD(BIST_RCV, RCV_EN, 1, entry); + SW_SET_REG_BY_FIELD(BIST_RCV, RCV_ADDR, data, entry); + HSL_REG_ENTRY_SET(rv, dev_id, BIST_RCV, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else + { + return SW_OK; + } + + entry = 0; + SW_SET_REG_BY_FIELD(BIST_CTRL, BIST_BUSY, 1, entry); + SW_SET_REG_BY_FIELD(BIST_CTRL, PTN_EN2, 1, entry); + SW_SET_REG_BY_FIELD(BIST_CTRL, PTN_EN1, 1, entry); + SW_SET_REG_BY_FIELD(BIST_CTRL, PTN_EN0, 1, entry); + + HSL_REG_ENTRY_SET(rv, dev_id, BIST_CTRL, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data = 1; + i = 0x1000; + while (data && --i) + { + HSL_REG_ENTRY_GET(rv, dev_id, BIST_CTRL, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + SW_GET_FIELD_BY_REG(BIST_CTRL, BIST_BUSY, data, entry); + aos_udelay(5); + } + + if (0 == i) + { + return SW_INIT_ERROR; + } + + SW_GET_FIELD_BY_REG(BIST_CTRL, ERR_CNT, data, entry); + if (data) + { + return SW_INIT_ERROR; + } + + return SW_OK; +} +#endif + +static sw_error_t +horus_dev_init(a_uint32_t dev_id, hsl_init_mode cpu_mode) +{ + hsl_dev_t *pdev = NULL; + + pdev = hsl_dev_ptr_get(dev_id); + if (pdev == NULL) + return SW_NOT_INITIALIZED; + + pdev->nr_ports = 6; + pdev->nr_phy = 5; + pdev->cpu_port_nr = 0; + pdev->nr_vlans = 16; + pdev->hw_vlan_query = A_TRUE; + pdev->nr_queue = 4; + pdev->cpu_mode = cpu_mode; + + return SW_OK; +} + +static sw_error_t +_horus_reset(a_uint32_t dev_id) +{ +#if !(defined(KERNEL_MODULE) && defined(USER_MODE)) + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + val = 0x1; + HSL_REG_FIELD_SET(rv, dev_id, MASK_CTL, 0, SOFT_RST, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = horus_hw_init(dev_id, horus_cfg[dev_id]); + SW_RTN_ON_ERROR(rv); +#endif + + return SW_OK; +} + + +sw_error_t +horus_cleanup(a_uint32_t dev_id) +{ + + if (horus_cfg[dev_id]) + { + aos_mem_free(horus_cfg[dev_id]); + horus_cfg[dev_id] = NULL; + } + + return SW_OK; +} + +/** + * @brief reset hsl layer. + * @details Comments: + * This operation will reset hsl layer + * @param[in] dev_id device id + * @return SW_OK or error code + */ +sw_error_t +horus_reset(a_uint32_t dev_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_reset(dev_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Init hsl layer. + * @details Comments: + * This operation will init hsl layer and hsl layer + * @param[in] dev_id device id + * @param[in] cfg configuration for initialization + * @return SW_OK or error code + */ +sw_error_t +horus_init(a_uint32_t dev_id, ssdk_init_cfg *cfg) +{ + HSL_DEV_ID_CHECK(dev_id); + + if (NULL == horus_cfg[dev_id]) + { + horus_cfg[dev_id] = aos_mem_alloc(sizeof (ssdk_init_cfg)); + } + + if (NULL == horus_cfg[dev_id]) + { + return SW_OUT_OF_MEM; + } + + aos_mem_copy(horus_cfg[dev_id], cfg, sizeof (ssdk_init_cfg)); + + SW_RTN_ON_ERROR(horus_reg_access_init(dev_id, cfg->reg_mode)); + + SW_RTN_ON_ERROR(horus_dev_init(dev_id, cfg->cpu_mode)); + +#if !(defined(KERNEL_MODULE) && defined(USER_MODE)) + { + a_uint32_t i, entry; + sw_error_t rv; + + SW_RTN_ON_ERROR(horus_bist_test(dev_id)); + + entry = 0x1; + HSL_REG_FIELD_SET(rv, dev_id, MASK_CTL, 0, SOFT_RST, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + i = 0x10; + do + { + HSL_REG_FIELD_GET(rv, dev_id, MASK_CTL, 0, SOFT_RST, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + aos_mdelay(10); + } + while (entry && --i); + + if (0 == i) + { + return SW_INIT_ERROR; + } + + SW_RTN_ON_ERROR(hsl_port_prop_init(dev_id)); + SW_RTN_ON_ERROR(hsl_port_prop_init_by_dev(dev_id)); + SW_RTN_ON_ERROR(horus_portproperty_init(dev_id, cfg->cpu_mode)); + + HORUS_MIB_INIT(rv, dev_id); + HORUS_PORT_CTRL_INIT(rv, dev_id); + HORUS_PORTVLAN_INIT(rv, dev_id); + HORUS_VLAN_INIT(rv, dev_id); + HORUS_FDB_INIT(rv, dev_id); + HORUS_QOS_INIT(rv, dev_id); + HORUS_STP_INIT(rv, dev_id); + HORUS_MIRR_INIT(rv, dev_id); + HORUS_RATE_INIT(rv, dev_id); + HORUS_MISC_INIT(rv, dev_id); + HORUS_LEAKY_INIT(rv, dev_id); + HORUS_IGMP_INIT(rv, dev_id); + HORUS_LED_INIT(rv, dev_id); + + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->dev_reset = horus_reset; + p_api->dev_clean = horus_cleanup; + } + + SW_RTN_ON_ERROR(horus_hw_init(dev_id, cfg)); + } +#endif + + return SW_OK; +} + + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_leaky.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_leaky.c new file mode 100755 index 000000000..d3973be1f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_leaky.c @@ -0,0 +1,525 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 horus_leaky HORUS_LEAKY + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "horus_leaky.h" +#include "horus_reg.h" + +static sw_error_t +_horus_uc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_LEAKY_PORT_CTRL == ctrl_mode) + { + data = 0; + } + else if (FAL_LEAKY_FDB_CTRL == ctrl_mode) + { + data = 1; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FLOOD_MASK, 0, ARL_UNI_LEAKY, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_uc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t *ctrl_mode) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FLOOD_MASK, 0, ARL_UNI_LEAKY, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *ctrl_mode = FAL_LEAKY_FDB_CTRL; + } + else + { + *ctrl_mode = FAL_LEAKY_PORT_CTRL; + } + + return SW_OK; +} + +static sw_error_t +_horus_mc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_LEAKY_PORT_CTRL == ctrl_mode) + { + data = 0; + } + else if (FAL_LEAKY_FDB_CTRL == ctrl_mode) + { + data = 1; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FLOOD_MASK, 0, ARL_MUL_LEAKY, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_mc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t *ctrl_mode) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FLOOD_MASK, 0, ARL_MUL_LEAKY, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *ctrl_mode = FAL_LEAKY_FDB_CTRL; + } + else + { + *ctrl_mode = FAL_LEAKY_PORT_CTRL; + } + + return SW_OK; +} + +static sw_error_t +_horus_port_arp_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, ARP_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_port_arp_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, ARP_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_horus_port_uc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_BASE_VLAN, port_id, UNI_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_port_uc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_BASE_VLAN, port_id, UNI_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_horus_port_mc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_BASE_VLAN, port_id, MUL_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_port_mc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_BASE_VLAN, port_id, MUL_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +/** +* @brief Set unicast packets leaky control mode on a particular device. +* @param[in] dev_id device id +* @param[in] ctrl_mode leaky control mode +* @return SW_OK or error code +*/ +HSL_LOCAL sw_error_t +horus_uc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_uc_leaky_mode_set(dev_id, ctrl_mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get unicast packets leaky control mode on a particular device. + * @param[in] dev_id device id + * @param[out] ctrl_mode leaky control mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_uc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t *ctrl_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_uc_leaky_mode_get(dev_id, ctrl_mode); + HSL_API_UNLOCK; + return rv; +} + +/** +* @brief Set multicast packets leaky control mode on a particular device. +* @param[in] dev_id device id +* @param[in] ctrl_mode leaky control mode +* @return SW_OK or error code +*/ +HSL_LOCAL sw_error_t +horus_mc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_mc_leaky_mode_set(dev_id, ctrl_mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get multicast packets leaky control mode on a particular device. + * @param[in] dev_id device id + * @param[out] ctrl_mode leaky control mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_mc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t *ctrl_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_mc_leaky_mode_get(dev_id, ctrl_mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set arp packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_arp_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_arp_leaky_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_arp_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_arp_leaky_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set unicast packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_uc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_uc_leaky_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get unicast packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_uc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_uc_leaky_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set multicast packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_mc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_mc_leaky_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get multicast packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_mc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_mc_leaky_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +horus_leaky_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->uc_leaky_mode_set = horus_uc_leaky_mode_set; + p_api->uc_leaky_mode_get = horus_uc_leaky_mode_get; + p_api->mc_leaky_mode_set = horus_mc_leaky_mode_set; + p_api->mc_leaky_mode_get = horus_mc_leaky_mode_get; + p_api->port_arp_leaky_set = horus_port_arp_leaky_set; + p_api->port_arp_leaky_get = horus_port_arp_leaky_get; + p_api->port_uc_leaky_set = horus_port_uc_leaky_set; + p_api->port_uc_leaky_get = horus_port_uc_leaky_get; + p_api->port_mc_leaky_set = horus_port_mc_leaky_set; + p_api->port_mc_leaky_get = horus_port_mc_leaky_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_led.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_led.c new file mode 100755 index 000000000..db2765dbf --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_led.c @@ -0,0 +1,427 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 horus_led HORUS_LED + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "horus_led.h" +#include "horus_reg.h" + +#define MAX_LED_PATTERN_ID 1 +#define LED_PATTERN_ADDR 0xB0 + +static sw_error_t +_horus_led_ctrl_pattern_set(a_uint32_t dev_id, led_pattern_group_t group, + led_pattern_id_t id, led_ctrl_pattern_t * pattern) +{ + a_uint32_t data = 0, reg, mode; + a_uint32_t addr; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (group >= LED_GROUP_BUTT) + { + return SW_BAD_PARAM; + } + + if (id > MAX_LED_PATTERN_ID) + { + return SW_BAD_PARAM; + } + + if ((LED_MAC_PORT_GROUP == group) && (0 != id)) + { + return SW_BAD_PARAM; + } + + if (LED_MAC_PORT_GROUP == group) + { + addr = LED_PATTERN_ADDR + 8; + } + else + { + addr = LED_PATTERN_ADDR + (id << 2); + } + + if (LED_ALWAYS_OFF == pattern->mode) + { + mode = 0; + } + else if (LED_ALWAYS_BLINK == pattern->mode) + { + mode = 1; + } + else if (LED_ALWAYS_ON == pattern->mode) + { + mode = 2; + } + else if (LED_PATTERN_MAP_EN == pattern->mode) + { + mode = 3; + } + else + { + return SW_BAD_PARAM; + } + SW_SET_REG_BY_FIELD(LED_CTRL, PATTERN_EN, mode, data); + + if (pattern->map & (1 << FULL_DUPLEX_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, FULL_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << HALF_DUPLEX_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, HALF_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << POWER_ON_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, POWERON_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << LINK_1000M_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, GE_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << LINK_100M_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, FE_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << LINK_10M_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, ETH_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << COLLISION_BLINK_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, COL_BLINK_EN, 1, data); + } + + if (pattern->map & (1 << RX_TRAFFIC_BLINK_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, RX_BLINK_EN, 1, data); + } + + if (pattern->map & (1 << TX_TRAFFIC_BLINK_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, TX_BLINK_EN, 1, data); + } + + if (pattern->map & (1 << LINKUP_OVERRIDE_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, LINKUP_OVER_EN, 1, data); + } + else + { + SW_SET_REG_BY_FIELD(LED_CTRL, LINKUP_OVER_EN, 0, data); + } + + if (LED_BLINK_2HZ == pattern->freq) + { + SW_SET_REG_BY_FIELD(LED_CTRL, BLINK_FREQ, 0, data); + } + else if (LED_BLINK_4HZ == pattern->freq) + { + SW_SET_REG_BY_FIELD(LED_CTRL, BLINK_FREQ, 1, data); + } + else if (LED_BLINK_8HZ == pattern->freq) + { + SW_SET_REG_BY_FIELD(LED_CTRL, BLINK_FREQ, 2, data); + } + else if (LED_BLINK_TXRX == pattern->freq) + { + SW_SET_REG_BY_FIELD(LED_CTRL, BLINK_FREQ, 3, data); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (LED_WAN_PORT_GROUP == group) + { + reg &= 0xffff; + reg |= (data << 16); + } + else + { + reg &= 0xffff0000; + reg |= data; + } + + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (LED_WAN_PORT_GROUP == group) + { + return SW_OK; + } + + HSL_REG_ENTRY_GET(rv, dev_id, LED_PATTERN, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (LED_LAN_PORT_GROUP == group) + { + if (id) + { + SW_SET_REG_BY_FIELD(LED_PATTERN, P3L1_MODE, mode, data); + SW_SET_REG_BY_FIELD(LED_PATTERN, P2L1_MODE, mode, data); + SW_SET_REG_BY_FIELD(LED_PATTERN, P1L1_MODE, mode, data); + } + else + { + SW_SET_REG_BY_FIELD(LED_PATTERN, P3L0_MODE, mode, data); + SW_SET_REG_BY_FIELD(LED_PATTERN, P2L0_MODE, mode, data); + SW_SET_REG_BY_FIELD(LED_PATTERN, P1L0_MODE, mode, data); + } + } + else + { + SW_SET_REG_BY_FIELD(LED_PATTERN, M5_MODE, mode, data); + } + + HSL_REG_ENTRY_SET(rv, dev_id, LED_PATTERN, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +static sw_error_t +_horus_led_ctrl_pattern_get(a_uint32_t dev_id, led_pattern_group_t group, + led_pattern_id_t id, led_ctrl_pattern_t * pattern) +{ + a_uint32_t data = 0, reg, tmp; + a_uint32_t addr; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (group >= LED_GROUP_BUTT) + { + return SW_BAD_PARAM; + } + + if (id > MAX_LED_PATTERN_ID) + { + return SW_BAD_PARAM; + } + + if ((LED_MAC_PORT_GROUP == group) && (0 != id)) + { + return SW_BAD_PARAM; + } + + aos_mem_zero(pattern, sizeof(led_ctrl_pattern_t)); + + if (LED_MAC_PORT_GROUP == group) + { + addr = LED_PATTERN_ADDR + 8; + } + else + { + addr = LED_PATTERN_ADDR + (id << 2); + } + + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (LED_WAN_PORT_GROUP == group) + { + data = (reg >> 16) & 0xffff; + } + else + { + data = reg & 0xffff; + } + + SW_GET_FIELD_BY_REG(LED_CTRL, PATTERN_EN, tmp, data); + if (0 == tmp) + { + pattern->mode = LED_ALWAYS_OFF; + } + else if (1 == tmp) + { + pattern->mode = LED_ALWAYS_BLINK; + } + else if (2 == tmp) + { + pattern->mode = LED_ALWAYS_ON; + } + else + { + pattern->mode = LED_PATTERN_MAP_EN; + } + + SW_GET_FIELD_BY_REG(LED_CTRL, FULL_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << FULL_DUPLEX_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, HALF_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << HALF_DUPLEX_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, POWERON_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << POWER_ON_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, GE_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << LINK_1000M_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, FE_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << LINK_100M_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, ETH_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << LINK_10M_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, COL_BLINK_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << COLLISION_BLINK_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, RX_BLINK_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << RX_TRAFFIC_BLINK_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, TX_BLINK_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << TX_TRAFFIC_BLINK_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, LINKUP_OVER_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << LINKUP_OVERRIDE_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, BLINK_FREQ, tmp, data); + if (0 == tmp) + { + pattern->freq = LED_BLINK_2HZ; + } + else if (1 == tmp) + { + pattern->freq = LED_BLINK_4HZ; + } + else if (2 == tmp) + { + pattern->freq = LED_BLINK_8HZ; + } + else + { + pattern->freq = LED_BLINK_TXRX; + } + + return SW_OK; +} + +/** +* @brief Set led control pattern on a particular device. +* @param[in] dev_id device id +* @param[in] group pattern group, lan or wan +* @param[in] id pattern id +* @param[in] pattern led control pattern +* @return SW_OK or error code +*/ +HSL_LOCAL sw_error_t +horus_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; + + HSL_API_LOCK; + rv = _horus_led_ctrl_pattern_set(dev_id, group, id, pattern); + HSL_API_UNLOCK; + return rv; +} + +/** +* @brief Get led control pattern on a particular device. +* @param[in] dev_id device id +* @param[in] group pattern group, lan or wan +* @param[in] id pattern id +* @param[out] pattern led control pattern +* @return SW_OK or error code +*/ +HSL_LOCAL sw_error_t +horus_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; + + HSL_API_LOCK; + rv = _horus_led_ctrl_pattern_get(dev_id, group, id, pattern); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +horus_led_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->led_ctrl_pattern_set = horus_led_ctrl_pattern_set; + p_api->led_ctrl_pattern_get = horus_led_ctrl_pattern_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_mib.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_mib.c new file mode 100755 index 000000000..4c800011b --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_mib.c @@ -0,0 +1,377 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 horus_mib HORUS_MIB + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "horus_mib.h" +#include "horus_reg.h" + +static sw_error_t +_horus_get_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info) +{ + a_uint32_t val; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_OUT_OF_RANGE; + } + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBROAD, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxBroad = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXPAUSE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxPause = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXMULTI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxMulti = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXFCSERR, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxFcsErr = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXALLIGNERR, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxAllignErr = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXRUNT, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxRunt = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXFRAGMENT, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxFragment = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX64BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx64Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX128BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx128Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX256BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx256Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX512BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx512Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX1024BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx1024Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX1518BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx1518Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXMAXBYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxMaxByte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXTOOLONG, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxTooLong = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXGOODBYTE_LO, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxGoodByte_lo = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXGOODBYTE_HI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxGoodByte_hi = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBADBYTE_LO, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxBadByte_lo = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBADBYTE_HI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxBadByte_hi = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXOVERFLOW, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxOverFlow = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_FILTERED, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Filtered = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBROAD, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxBroad = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXPAUSE, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxPause = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMULTI, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxMulti = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXUNDERRUN, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxUnderRun = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX64BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx64Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX128BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx128Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX256BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx256Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX512BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx512Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX1024BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx1024Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX1518BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx1518Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMAXBYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxMaxByte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXOVERSIZE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxOverSize = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBYTE_LO, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxByte_lo = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBYTE_HI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxByte_hi = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXCOLLISION, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxCollision = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXABORTCOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxAbortCol = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMULTICOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxMultiCol = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXSINGALCOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxSingalCol = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXEXCDEFER, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxExcDefer = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXDEFER, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxDefer = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXLATECOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxLateCol = val; + + return SW_OK; +} + +static sw_error_t +_horus_mib_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, MIB_FUNC, 0, MIB_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_mib_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, MIB_FUNC, 0, MIB_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +/** + * @brief Get mib infomation on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mib_info mib infomation + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_get_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_get_mib_info(dev_id, port_id, mib_info); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set mib status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_mib_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_mib_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mib status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_mib_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_mib_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +horus_mib_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->get_mib_info = horus_get_mib_info; + p_api->mib_status_set = horus_mib_status_set; + p_api->mib_status_get = horus_mib_status_get; +#endif + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_mirror.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_mirror.c new file mode 100755 index 000000000..bc929808a --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_mirror.c @@ -0,0 +1,317 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 horus_mirror HORUS_MIRROR + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "horus_mirror.h" +#include "horus_reg.h" + +static sw_error_t +_horus_mirr_analysis_port_set(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + val = port_id; + HSL_REG_FIELD_SET(rv, dev_id, CPU_PORT, 0, MIRROR_PORT_NUM, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_mirr_analysis_port_get(a_uint32_t dev_id, fal_port_t * port_id) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, CPU_PORT, 0, MIRROR_PORT_NUM, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *port_id = val; + return SW_OK; +} + +static sw_error_t +_horus_mirr_port_in_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, ING_MIRROR_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_mirr_port_in_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, ING_MIRROR_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_horus_mirr_port_eg_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, EG_MIRROR_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_mirr_port_eg_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, EG_MIRROR_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +/** + * @details Comments: + * The analysis port works for both ingress and egress mirror. + * @brief Set mirror analyzer port on particular a device. + * @param[in] dev_id device id + * @param[in] port_id port id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_mirr_analysis_port_set(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_mirr_analysis_port_set(dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mirror analysis port on particular a device. + * @param[in] dev_id device id + * @param[out] port_id port id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_mirr_analysis_port_get(a_uint32_t dev_id, fal_port_t * port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_mirr_analysis_port_get(dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set ingress mirror status on particular a port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_mirr_port_in_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_mirr_port_in_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get ingress mirror status on particular a port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_mirr_port_in_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_mirr_port_in_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set egress mirror status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_mirr_port_eg_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_mirr_port_eg_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get egress mirror status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_mirr_port_eg_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_mirr_port_eg_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +horus_mirr_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->mirr_analysis_port_set = horus_mirr_analysis_port_set; + p_api->mirr_analysis_port_get = horus_mirr_analysis_port_get; + p_api->mirr_port_in_set = horus_mirr_port_in_set; + p_api->mirr_port_in_get = horus_mirr_port_in_get; + p_api->mirr_port_eg_set = horus_mirr_port_eg_set; + p_api->mirr_port_eg_get = horus_mirr_port_eg_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_misc.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_misc.c new file mode 100755 index 000000000..1c13ff704 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_misc.c @@ -0,0 +1,1396 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 horus_misc HORUS_MISC + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "horus_misc.h" +#include "horus_reg.h" + +#define HORUS_MAX_FRMAE_SIZE 9216 + +static sw_error_t +_horus_arp_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, QM_CTL, 0, ARP_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_arp_status_get(a_uint32_t dev_id, a_bool_t *enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, QM_CTL, 0, ARP_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_horus_frame_max_size_set(a_uint32_t dev_id, a_uint32_t size) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (HORUS_MAX_FRMAE_SIZE < size) + { + return SW_BAD_PARAM; + } + + data = size; + HSL_REG_FIELD_SET(rv, dev_id, GLOBAL_CTL, 0, MAX_FRAME_SIZE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_frame_max_size_get(a_uint32_t dev_id, a_uint32_t *size) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, GLOBAL_CTL, 0, MAX_FRAME_SIZE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *size = data; + return SW_OK; +} + +static sw_error_t +_horus_port_unk_sa_cmd_set(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_CTL, port_id, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_MAC_FRWRD == cmd) + { + SW_SET_REG_BY_FIELD(PORT_CTL, PORT_LOCK_EN, 0, data); + } + else if (FAL_MAC_DROP == cmd) + { + SW_SET_REG_BY_FIELD(PORT_CTL, PORT_LOCK_EN, 1, data); + SW_SET_REG_BY_FIELD(PORT_CTL, LOCK_DROP_EN, 1, data); + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + SW_SET_REG_BY_FIELD(PORT_CTL, PORT_LOCK_EN, 1, data); + SW_SET_REG_BY_FIELD(PORT_CTL, LOCK_DROP_EN, 0, data); + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_CTL, port_id, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_port_unk_sa_cmd_get(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t * action) +{ + sw_error_t rv; + a_uint32_t data; + a_uint32_t port_lock_en, port_drop_en; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_CTL, port_id, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_CTL, PORT_LOCK_EN, port_lock_en, data); + SW_GET_FIELD_BY_REG(PORT_CTL, LOCK_DROP_EN, port_drop_en, data); + + if (1 == port_lock_en) + { + if (1 == port_drop_en) + { + *action = FAL_MAC_DROP; + } + else + { + *action = FAL_MAC_RDT_TO_CPU; + } + } + else + { + *action = FAL_MAC_FRWRD; + } + + return SW_OK; +} + +static sw_error_t +_horus_port_unk_uc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FLOOD_MASK, 0, UNI_FLOOD_DP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + data &= (~((a_uint32_t)0x1 << port_id)); + } + else if (A_FALSE == enable) + { + data |= (0x1 << port_id); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FLOOD_MASK, 0, UNI_FLOOD_DP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_port_unk_uc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t reg, field; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FLOOD_MASK, 0, UNI_FLOOD_DP, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + field = reg & (0x1 << port_id); + if (field) + { + *enable = A_FALSE; + } + else + { + *enable = A_TRUE; + } + + return SW_OK; +} + +static sw_error_t +_horus_port_unk_mc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FLOOD_MASK, 0, MUL_FLOOD_DP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + data &= (~((a_uint32_t)0x1 << port_id)); + } + else if (A_FALSE == enable) + { + data |= (0x1 << port_id); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FLOOD_MASK, 0, MUL_FLOOD_DP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_port_unk_mc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t reg, field; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FLOOD_MASK, 0, MUL_FLOOD_DP, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + field = reg & (0x1 << port_id); + if (field) + { + *enable = A_FALSE; + } + else + { + *enable = A_TRUE; + } + + return SW_OK; +} + +static sw_error_t +_horus_port_bc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FLOOD_MASK, 0, BC_FLOOD_DP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + data &= (~((a_uint32_t)0x1 << port_id)); + } + else if (A_FALSE == enable) + { + data |= (0x1 << port_id); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FLOOD_MASK, 0, BC_FLOOD_DP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_port_bc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t reg, field; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FLOOD_MASK, 0, BC_FLOOD_DP, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + field = reg & (0x1 << port_id); + if (field) + { + *enable = A_FALSE; + } + else + { + *enable = A_TRUE; + } + + return SW_OK; +} + +static sw_error_t +_horus_cpu_port_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, CPU_PORT, 0, CPU_PORT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_cpu_port_status_get(a_uint32_t dev_id, a_bool_t *enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, CPU_PORT, 0, CPU_PORT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_horus_pppoe_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_MAC_FRWRD == cmd) + { + val = 0; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + val = 1; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, QM_CTL, 0, PPPOE_RDT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_pppoe_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, QM_CTL, 0, PPPOE_RDT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + else + { + *cmd = FAL_MAC_FRWRD; + } + + return SW_OK; +} + +static sw_error_t +_horus_pppoe_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, QM_CTL, 0, PPPOE_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_pppoe_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, QM_CTL, 0, PPPOE_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_horus_port_dhcp_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, DHCP_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_port_dhcp_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, DHCP_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_horus_arp_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_MAC_CPY_TO_CPU == cmd) + { + val = 0; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + val = 1; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, QM_CTL, 0, ARP_CMD, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_arp_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, QM_CTL, 0, ARP_CMD, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0 == val) + { + *cmd = FAL_MAC_CPY_TO_CPU; + } + else + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + + return SW_OK; +} + +static sw_error_t +_horus_eapol_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_MAC_CPY_TO_CPU == cmd) + { + val = 0; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + val = 1; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, QM_CTL, 0, EAPOL_CMD, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_eapol_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, QM_CTL, 0, EAPOL_CMD, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0 == val) + { + *cmd = FAL_MAC_CPY_TO_CPU; + } + else + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + + return SW_OK; +} + +static sw_error_t +_horus_eapol_status_set(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, EAPOL_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_eapol_status_get(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t *enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, EAPOL_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_horus_ripv1_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, 0, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, QM_CTL, 0, RIP_CPY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_ripv1_status_get(a_uint32_t dev_id, a_bool_t *enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, 0, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, QM_CTL, 0, RIP_CPY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +/** + * @brief Set arp packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_arp_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_arp_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_arp_status_get(a_uint32_t dev_id, a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_arp_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set max frame size which device can received on a particular device. + * @details Comments: + * The granularity of packets size is byte. + * @param[in] dev_id device id + * @param[in] size packet size + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_frame_max_size_set(a_uint32_t dev_id, a_uint32_t size) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_frame_max_size_set(dev_id, size); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get max frame size which device can received on a particular device. + * @details Comments: + * The unit of packets size is byte. + * @param[in] dev_id device id + * @param[out] size packet size + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_frame_max_size_get(a_uint32_t dev_id, a_uint32_t *size) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_frame_max_size_get(dev_id, size); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set forwarding command for packets which source address is unknown on a particular port. + * @details Comments: + * Particular device may only support parts of forwarding commands. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_unk_sa_cmd_set(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_unk_sa_cmd_set(dev_id, port_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get forwarding command for packets which source address is unknown on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_unk_sa_cmd_get(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t * action) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_unk_sa_cmd_get(dev_id, port_id, action); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flooding status of unknown unicast packets on a particular port. + * @details Comments: + * If enable unknown unicast packets filter on one port then unknown + * unicast packets can't flood out from this port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_unk_uc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_unk_uc_filter_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get flooding status of unknown unicast packets on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_unk_uc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_unk_uc_filter_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flooding status of unknown multicast packets on a particular port. + * @details Comments: + * If enable unknown multicast packets filter on one port then unknown + * multicast packets can't flood out from this port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_unk_mc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_unk_mc_filter_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** @brief Get flooding status of unknown multicast packets on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_unk_mc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_unk_mc_filter_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flooding status of broadcast packets on a particular port. + * @details Comments: + * If enable unknown multicast packets filter on one port then unknown + * multicast packets can't flood out from this port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_bc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_bc_filter_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** @brief Get flooding status of broadcast packets on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_bc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_bc_filter_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set cpu port status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_cpu_port_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_cpu_port_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get cpu port status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_cpu_port_status_get(a_uint32_t dev_id, a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_cpu_port_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set pppoe packets forwarding command on a particular device. + * @details comments: + * Particular device may only support parts of forwarding commands. + * Ihis operation will take effect only after enabling pppoe packets + * hardware acknowledgement + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_pppoe_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_pppoe_cmd_set(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get pppoe packets forwarding command on a particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_pppoe_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_pppoe_cmd_get(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set pppoe packets hardware acknowledgement status on particular device. + * @details comments: + * Particular device may only support parts of pppoe packets. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_pppoe_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_pppoe_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get pppoe packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_pppoe_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_pppoe_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dhcp packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_dhcp_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_dhcp_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dhcp packets hardware acknowledgement status on particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_dhcp_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_dhcp_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set arp packets forwarding command on a particular device. + * @details comments: + * Particular device may only support parts of forwarding commands. + * Ihis operation will take effect only after enabling arp packets + * hardware acknowledgement + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_arp_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_arp_cmd_set(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp packets forwarding command on a particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_arp_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_arp_cmd_get(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set eapol packets forwarding command on a particular device. + * @details comments: + * Particular device may only support parts of forwarding commands. + * Ihis operation will take effect only after enabling eapol packets + * hardware acknowledgement + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_eapol_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_eapol_cmd_set(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get eapol packets forwarding command on a particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_eapol_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_eapol_cmd_get(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set eapol packets hardware acknowledgement status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_eapol_status_set(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_eapol_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get eapol packets hardware acknowledgement status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_eapol_status_get(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_eapol_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set rip v1 packets hardware acknowledgement status on a particular port. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_ripv1_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_ripv1_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get rip v1 packets hardware acknowledgement status on a particular port. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_ripv1_status_get(a_uint32_t dev_id, a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_ripv1_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +horus_misc_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->arp_status_set = horus_arp_status_set; + p_api->arp_status_get = horus_arp_status_get; + p_api->frame_max_size_set = horus_frame_max_size_set; + p_api->frame_max_size_get = horus_frame_max_size_get; + p_api->port_unk_sa_cmd_set = horus_port_unk_sa_cmd_set; + p_api->port_unk_sa_cmd_get = horus_port_unk_sa_cmd_get; + p_api->port_unk_uc_filter_set = horus_port_unk_uc_filter_set; + p_api->port_unk_uc_filter_get = horus_port_unk_uc_filter_get; + p_api->port_unk_mc_filter_set = horus_port_unk_mc_filter_set; + p_api->port_unk_mc_filter_get = horus_port_unk_mc_filter_get; + p_api->port_bc_filter_set = horus_port_bc_filter_set; + p_api->port_bc_filter_get = horus_port_bc_filter_get; + p_api->cpu_port_status_set = horus_cpu_port_status_set; + p_api->cpu_port_status_get = horus_cpu_port_status_get; + p_api->pppoe_cmd_set = horus_pppoe_cmd_set; + p_api->pppoe_cmd_get = horus_pppoe_cmd_get; + p_api->pppoe_status_set = horus_pppoe_status_set; + p_api->pppoe_status_get = horus_pppoe_status_get; + p_api->port_dhcp_set = horus_port_dhcp_set; + p_api->port_dhcp_get = horus_port_dhcp_get; + p_api->arp_cmd_set = horus_arp_cmd_set; + p_api->arp_cmd_get = horus_arp_cmd_get; + p_api->eapol_cmd_set = horus_eapol_cmd_set; + p_api->eapol_cmd_get = horus_eapol_cmd_get; + p_api->eapol_status_set = horus_eapol_status_set; + p_api->eapol_status_get = horus_eapol_status_get; + p_api->ripv1_status_set = horus_ripv1_status_set; + p_api->ripv1_status_get = horus_ripv1_status_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_port_ctrl.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_port_ctrl.c new file mode 100755 index 000000000..75fcee817 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_port_ctrl.c @@ -0,0 +1,1061 @@ +/* + * Copyright (c) 2012, 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 horus_port_ctrl HORUS_PORT_CONTROL + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "horus_port_ctrl.h" +#include "horus_reg.h" +#include "hsl_phy.h" + +static sw_error_t +_horus_port_duplex_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t duplex) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + a_uint32_t reg_save = 0; + a_uint32_t reg_val = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_duplex_set) + return SW_NOT_SUPPORTED; + + if (FAL_DUPLEX_BUTT <= duplex) + { + return SW_BAD_PARAM; + } + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + //save reg value + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_val), sizeof (a_uint32_t)); + reg_save = reg_val; + + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 0, reg_val); + SW_SET_REG_BY_FIELD(PORT_STATUS, RXMAC_EN, 0, reg_val); + SW_SET_REG_BY_FIELD(PORT_STATUS, TXMAC_EN, 0, reg_val); + + //set mac be config by sw and turn off RX TX MAC_EN + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_val), sizeof (a_uint32_t)); + + rv = phy_drv->phy_duplex_set(dev_id, phy_id, duplex); + + //retore reg value + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_save), sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_horus_port_duplex_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t * pduplex) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_duplex_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_duplex_get(dev_id, phy_id, pduplex); + return rv; +} + +static sw_error_t +_horus_port_speed_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t speed) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_speed_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_SPEED_100 < speed) + { + return SW_BAD_PARAM; + } + + rv = phy_drv->phy_speed_set(dev_id, phy_id, speed); + + return rv; +} + +static sw_error_t +_horus_port_speed_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t * pspeed) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_speed_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_speed_get(dev_id, phy_id, pspeed); + + return rv; +} + +static sw_error_t +_horus_port_autoneg_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status) +{ + a_uint32_t phy_id; + sw_error_t rv; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_autoneg_status_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + *status = phy_drv->phy_autoneg_status_get(dev_id, phy_id); + + return SW_OK; +} + +static sw_error_t +_horus_port_autoneg_enable(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_autoneg_enable_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_autoneg_enable_set(dev_id, phy_id); + return rv; +} + +static sw_error_t +_horus_port_autoneg_restart(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_restart_autoneg) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_restart_autoneg(dev_id, phy_id); + return rv; +} + +static sw_error_t +_horus_port_autoneg_adv_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t autoadv) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_autoneg_adv_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_autoneg_adv_set(dev_id, phy_id, autoadv); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +static sw_error_t +_horus_port_autoneg_adv_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * autoadv) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_autoneg_adv_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + *autoadv = 0; + rv = phy_drv->phy_autoneg_adv_get(dev_id, phy_id, autoadv); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +static sw_error_t +_horus_port_hdr_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, HEAD_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_horus_port_hdr_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, HEAD_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return rv; +} + +static sw_error_t +_horus_port_flowctrl_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val, force, reg; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_STATUS, FLOW_LINK_EN, force, reg); + if (force) + { + /* flow control isn't in force mode so can't set */ + return SW_DISABLE; + } + + SW_SET_REG_BY_FIELD(PORT_STATUS, RX_FLOW_EN, val, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TX_FLOW_EN, val, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TX_HALF_FLOW_EN, val, reg); + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_port_flowctrl_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t tx, rx, reg; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_STATUS, RX_FLOW_EN, rx, reg); + SW_GET_FIELD_BY_REG(PORT_STATUS, TX_FLOW_EN, tx, reg); + + if (1 == rx) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_horus_port_flowctrl_forcemode_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t force, reg; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_STATUS, FLOW_LINK_EN, force, reg); + if (force != (a_uint32_t) enable) + { + return SW_OK; + } + + if (A_TRUE == enable) + { + SW_SET_REG_BY_FIELD(PORT_STATUS, FLOW_LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TX_FLOW_EN, 0, reg); + } + else if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(PORT_STATUS, FLOW_LINK_EN, 1, reg); + } + else + { + return SW_BAD_PARAM; + } + SW_SET_REG_BY_FIELD(PORT_STATUS, TX_HALF_FLOW_EN, 0, reg); + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_port_flowctrl_forcemode_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t force, reg; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_STATUS, FLOW_LINK_EN, force, reg); + if (0 == force) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_horus_port_powersave_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_powersave_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_powersave_set(dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_horus_port_powersave_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_powersave_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_powersave_get(dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_horus_port_hibernate_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_hibernation_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_hibernation_set(dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_horus_port_hibernate_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_hibernation_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_hibernation_get(dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_horus_port_cdt(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t mdi_pair, + fal_cable_status_t *cable_status, a_uint32_t *cable_len) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id)); + if (NULL == phy_drv->phy_cdt) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_cdt(dev_id, phy_id, mdi_pair, cable_status, cable_len); + + return rv; +} + +/** + * @brief Set duplex mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] duplex duplex mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_duplex_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t duplex) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_duplex_set(dev_id, port_id, duplex); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get duplex mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] duplex duplex mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_duplex_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t * pduplex) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_duplex_get(dev_id, port_id, pduplex); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set speed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] speed port speed + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_speed_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t speed) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_speed_set(dev_id, port_id, speed); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get speed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] speed port speed + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_speed_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t * pspeed) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_speed_get(dev_id, port_id, pspeed); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get auto negotiation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] status A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_autoneg_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_autoneg_status_get(dev_id, port_id, status); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Enable auto negotiation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_autoneg_enable(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_autoneg_enable(dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Restart auto negotiation procedule on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_autoneg_restart(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_autoneg_restart(dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set auto negotiation advtisement ability on a particular port. + * @details Comments: + * auto negotiation advtisement ability is defined by macro such as + * FAL_PHY_ADV_10T_HD, FAL_PHY_ADV_PAUSE... + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] autoadv auto negotiation advtisement ability bit map + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_autoneg_adv_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t autoadv) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_autoneg_adv_set(dev_id, port_id, autoadv); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get auto negotiation advtisement ability on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] autoadv auto negotiation advtisement ability bit map + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_autoneg_adv_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * autoadv) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_autoneg_adv_get(dev_id, port_id, autoadv); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of Atheros header packets parsed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_hdr_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_hdr_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get status of Atheros header packets parsed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_hdr_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_hdr_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flow control status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_flowctrl_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_flowctrl_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get flow control status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_flowctrl_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_flowctrl_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flow control force mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_flowctrl_forcemode_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_flowctrl_forcemode_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get flow control force mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_flowctrl_forcemode_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_flowctrl_forcemode_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set powersaving status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_powersave_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_powersave_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get powersaving status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_powersave_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_powersave_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set hibernate status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_hibernate_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_hibernate_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get hibernate status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_hibernate_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_hibernate_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Run cable diagnostic test on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mdi_pair mdi pair id + * @param[out] cable_status cable status + * @param[out] cable_len cable len + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_cdt(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t mdi_pair, + fal_cable_status_t *cable_status, a_uint32_t *cable_len) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_cdt(dev_id, port_id, mdi_pair, cable_status, cable_len); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +horus_port_ctrl_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->port_duplex_get = horus_port_duplex_get; + p_api->port_duplex_set = horus_port_duplex_set; + p_api->port_speed_get = horus_port_speed_get; + p_api->port_speed_set = horus_port_speed_set; + p_api->port_autoneg_status_get = horus_port_autoneg_status_get; + p_api->port_autoneg_enable = horus_port_autoneg_enable; + p_api->port_autoneg_restart = horus_port_autoneg_restart; + p_api->port_autoneg_adv_get = horus_port_autoneg_adv_get; + p_api->port_autoneg_adv_set = horus_port_autoneg_adv_set; + p_api->port_hdr_status_set = horus_port_hdr_status_set; + p_api->port_hdr_status_get = horus_port_hdr_status_get; + p_api->port_flowctrl_set = horus_port_flowctrl_set; + p_api->port_flowctrl_get = horus_port_flowctrl_get; + p_api->port_flowctrl_forcemode_set = horus_port_flowctrl_forcemode_set; + p_api->port_flowctrl_forcemode_get = horus_port_flowctrl_forcemode_get; + p_api->port_powersave_set = horus_port_powersave_set; + p_api->port_powersave_get = horus_port_powersave_get; + p_api->port_hibernate_set = horus_port_hibernate_set; + p_api->port_hibernate_get = horus_port_hibernate_get; + p_api->port_cdt = horus_port_cdt; + } +#endif + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_portvlan.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_portvlan.c new file mode 100755 index 000000000..1bf9f9822 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_portvlan.c @@ -0,0 +1,1184 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 horus_port_vlan HORUS_PORT_VLAN + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "horus_portvlan.h" +#include "horus_reg.h" + +#define MAX_VLAN_ID 4095 + +static sw_error_t +_horus_port_1qmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t port_1qmode) +{ + sw_error_t rv; + a_uint32_t regval[FAL_1Q_MODE_BUTT] = { 0, 3, 2, 1 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_1Q_MODE_BUTT <= port_1qmode) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_BASE_VLAN, port_id, DOT1Q_MODE, + (a_uint8_t *) (®val[port_1qmode]), + sizeof (a_uint32_t)); + + return rv; + +} + +static sw_error_t +_horus_port_1qmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t * pport_1qmode) +{ + sw_error_t rv; + a_uint32_t regval = 0; + fal_pt_1qmode_t retval[4] = { FAL_1Q_DISABLE, FAL_1Q_FALLBACK, + FAL_1Q_CHECK, FAL_1Q_SECURE + }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL(pport_1qmode); + + HSL_REG_FIELD_GET(rv, dev_id, PORT_BASE_VLAN, port_id, DOT1Q_MODE, + (a_uint8_t *) (®val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + *pport_1qmode = retval[regval & 0x3]; + + return SW_OK; + +} + +static sw_error_t +_horus_port_egvlanmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t port_egvlanmode) +{ + sw_error_t rv; + a_uint32_t regval[FAL_EG_MODE_BUTT] = { 0, 1, 2, 3}; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_EG_MODE_BUTT <= port_egvlanmode) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, EG_VLAN_MODE, + (a_uint8_t *) (®val[port_egvlanmode]), + sizeof (a_uint32_t)); + + return rv; + +} + +static sw_error_t +_horus_port_egvlanmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t * pport_egvlanmode) +{ + sw_error_t rv; + a_uint32_t regval = 0; + fal_pt_1q_egmode_t retval[4] = { FAL_EG_UNMODIFIED, FAL_EG_UNTAGGED, + FAL_EG_TAGGED, FAL_EG_HYBRID + }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL(pport_egvlanmode); + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, EG_VLAN_MODE, + (a_uint8_t *) (®val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + *pport_egvlanmode = retval[regval & 0x3]; + + return SW_OK; + +} + +static sw_error_t +_horus_portvlan_member_add(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id) +{ + sw_error_t rv; + a_uint32_t regval = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_FALSE == hsl_port_prop_check(dev_id, mem_port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_BASE_VLAN, port_id, + PORT_VID_MEM, (a_uint8_t *) (®val), + sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + regval |= (0x1UL << mem_port_id); + + HSL_REG_FIELD_SET(rv, dev_id, PORT_BASE_VLAN, port_id, + PORT_VID_MEM, (a_uint8_t *) (®val), + sizeof (a_uint32_t)); + + return rv; + +} + +static sw_error_t +_horus_portvlan_member_del(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id) +{ + sw_error_t rv; + a_uint32_t regval = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_FALSE == hsl_port_prop_check(dev_id, mem_port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_BASE_VLAN, port_id, + PORT_VID_MEM, (a_uint8_t *) (®val), + sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + regval &= (~(0x1UL << mem_port_id)); + + HSL_REG_FIELD_SET(rv, dev_id, PORT_BASE_VLAN, port_id, + PORT_VID_MEM, (a_uint8_t *) (®val), + sizeof (a_uint32_t)); + + return rv; + +} + +static sw_error_t +_horus_portvlan_member_update(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t mem_port_map) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_FALSE == + hsl_mports_prop_check(dev_id, mem_port_map, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_BASE_VLAN, port_id, + PORT_VID_MEM, (a_uint8_t *) (&mem_port_map), + sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_horus_portvlan_member_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t * mem_port_map) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + *mem_port_map = 0; + HSL_REG_FIELD_GET(rv, dev_id, PORT_BASE_VLAN, port_id, + PORT_VID_MEM, (a_uint8_t *) mem_port_map, + sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +static sw_error_t +_horus_port_default_vid_set(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t vid) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if ((0 == vid) || (vid > MAX_VLAN_ID)) + { + return SW_BAD_PARAM; + } + + val = vid; + HSL_REG_FIELD_SET(rv, dev_id, PORT_DOT1Q, port_id, + DEF_VID, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + + return rv; +} + + +static sw_error_t +_horus_port_default_vid_get(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t *vid) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_DOT1Q, port_id, + DEF_VID, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + + *vid = val & 0xfff; + return rv; +} + + +static sw_error_t +_horus_port_force_default_vid_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_DOT1Q, port_id, + FORCE_DEF_VID, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_port_force_default_vid_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_DOT1Q, port_id, + FORCE_DEF_VID, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_horus_port_force_portvlan_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_DOT1Q, port_id, + FORCE_PVLAN, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_port_force_portvlan_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_DOT1Q, port_id, + FORCE_PVLAN, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_horus_nestvlan_tpid_set(a_uint32_t dev_id, a_uint32_t tpid) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + val = tpid; + HSL_REG_FIELD_SET(rv, dev_id, SERVICE_TAG, 0, + TAG_VALUE, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_nestvlan_tpid_get(a_uint32_t dev_id, a_uint32_t *tpid) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, SERVICE_TAG, 0, + TAG_VALUE, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *tpid = val; + return SW_OK; +} + +static sw_error_t +_horus_port_invlan_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_invlan_mode_t mode) +{ + sw_error_t rv; + a_uint32_t regval[FAL_INVLAN_MODE_BUTT] = { 0, 1, 2}; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_INVLAN_MODE_BUTT <= mode) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_BASE_VLAN, port_id, IN_VLAN_MODE, + (a_uint8_t *) (®val[mode]), + sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_horus_port_invlan_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_invlan_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t regval = 0; + fal_pt_invlan_mode_t retval[FAL_INVLAN_MODE_BUTT] = { FAL_INVLAN_ADMIT_ALL, + FAL_INVLAN_ADMIT_TAGGED, FAL_INVLAN_ADMIT_UNTAGGED + }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL(mode); + + HSL_REG_FIELD_GET(rv, dev_id, PORT_BASE_VLAN, port_id, IN_VLAN_MODE, + (a_uint8_t *) (®val), + sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (regval >= 3) + { + return SW_FAIL; + } + *mode = retval[regval & 0x3]; + + return rv; +} + +static sw_error_t +_horus_port_pri_propagation_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_BASE_VLAN, port_id, + PRI_PROPAGATION, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_port_pri_propagation_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_BASE_VLAN, port_id, + PRI_PROPAGATION, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_horus_qinq_mode_set(a_uint32_t dev_id, fal_qinq_mode_t mode) +{ + sw_error_t rv; + a_uint32_t stag = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_QINQ_MODE_BUTT <= mode) + { + return SW_BAD_PARAM; + } + + if (FAL_QINQ_STAG_MODE == mode) + { + stag = 1; + } + + HSL_REG_FIELD_SET(rv, dev_id, ADDR_TABLE_CTL, 0, + STAG_MODE, (a_uint8_t *) (&stag), + sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_horus_qinq_mode_get(a_uint32_t dev_id, fal_qinq_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t stag = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_CTL, 0, + STAG_MODE, (a_uint8_t *) (&stag), + sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (stag) + { + *mode = FAL_QINQ_STAG_MODE; + } + else + { + *mode = FAL_QINQ_CTAG_MODE; + } + + return SW_OK; +} + +static sw_error_t +_horus_port_qinq_role_set(a_uint32_t dev_id, fal_port_t port_id, fal_qinq_port_role_t role) +{ + sw_error_t rv; + a_uint32_t core = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_QINQ_PORT_ROLE_BUTT <= role) + { + return SW_BAD_PARAM; + } + + if (FAL_QINQ_CORE_PORT == role) + { + core = 1; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_BASE_VLAN, port_id, + COREP_EN, (a_uint8_t *) (&core), + sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_horus_port_qinq_role_get(a_uint32_t dev_id, fal_port_t port_id, fal_qinq_port_role_t * role) +{ + sw_error_t rv; + a_uint32_t core = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_BASE_VLAN, port_id, + COREP_EN, (a_uint8_t *) (&core), + sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (core) + { + *role = FAL_QINQ_CORE_PORT; + } + else + { + *role = FAL_QINQ_EDGE_PORT; + } + + return SW_OK; +} + +/** + * @brief Set 802.1q work mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] port_1qmode 802.1q work mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_1qmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t port_1qmode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_1qmode_set(dev_id, port_id, port_1qmode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get 802.1q work mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] port_1qmode 802.1q work mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_1qmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t * pport_1qmode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_1qmode_get(dev_id, port_id, pport_1qmode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set packets transmitted out vlan tagged mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] port_egvlanmode packets transmitted out vlan tagged mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_egvlanmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t port_egvlanmode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_egvlanmode_set(dev_id, port_id, port_egvlanmode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get packets transmitted out vlan tagged mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] port_egvlanmode packets transmitted out vlan tagged mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_egvlanmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t * pport_egvlanmode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_egvlanmode_get(dev_id, port_id, pport_egvlanmode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add member of port based vlan on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mem_port_id port member + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_portvlan_member_add(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_portvlan_member_add(dev_id, port_id, mem_port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete member of port based vlan on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mem_port_id port member + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_portvlan_member_del(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_portvlan_member_del(dev_id, port_id, mem_port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Update member of port based vlan on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mem_port_map port members + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_portvlan_member_update(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t mem_port_map) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_portvlan_member_update(dev_id, port_id, mem_port_map); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get member of port based vlan on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mem_port_map port members + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_portvlan_member_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t * mem_port_map) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_portvlan_member_get(dev_id, port_id, mem_port_map); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set default vlan id on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] vid default vlan id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_default_vid_set(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t vid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_default_vid_set(dev_id, port_id, vid); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get default vlan id on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] vid default vlan id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_default_vid_get(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t *vid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_default_vid_get(dev_id, port_id, vid); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set force default vlan id status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_force_default_vid_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_force_default_vid_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get force default vlan id status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_force_default_vid_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_force_default_vid_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set force port based vlan status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_force_portvlan_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_force_portvlan_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get force port based vlan status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_force_portvlan_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_force_portvlan_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set nest vlan tpid on a particular device. + * @param[in] dev_id device id + * @param[in] tpid tag protocol identification + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_nestvlan_tpid_set(a_uint32_t dev_id, a_uint32_t tpid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_nestvlan_tpid_set(dev_id, tpid); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get nest vlan tpid on a particular device. + * @param[in] dev_id device id + * @param[out] tpid tag protocol identification + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_nestvlan_tpid_get(a_uint32_t dev_id, a_uint32_t *tpid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_nestvlan_tpid_get(dev_id, tpid); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set ingress vlan mode mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode ingress vlan mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_invlan_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_invlan_mode_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_invlan_mode_set(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get ingress vlan mode mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mode ingress vlan mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_invlan_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_invlan_mode_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_invlan_mode_get(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set priority propagation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_pri_propagation_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_pri_propagation_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get priority propagation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_pri_propagation_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_pri_propagation_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set switch qinq work mode on a particular device. + * @param[in] dev_id device id + * @param[in] mode qinq work mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_qinq_mode_set(a_uint32_t dev_id, fal_qinq_mode_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_qinq_mode_set(dev_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get switch qinq work mode on a particular device. + * @param[in] dev_id device id + * @param[out] mode qinq work mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_qinq_mode_get(a_uint32_t dev_id, fal_qinq_mode_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_qinq_mode_get(dev_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set qinq role on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] role port role + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_qinq_role_set(a_uint32_t dev_id, fal_port_t port_id, fal_qinq_port_role_t role) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_qinq_role_set(dev_id, port_id, role); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get qinq role on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] role port role + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_port_qinq_role_get(a_uint32_t dev_id, fal_port_t port_id, fal_qinq_port_role_t * role) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_port_qinq_role_get(dev_id, port_id, role); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +horus_portvlan_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + hsl_api_t *p_api; + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get(dev_id)); + + p_api->port_1qmode_get = horus_port_1qmode_get; + p_api->port_1qmode_set = horus_port_1qmode_set; + p_api->port_egvlanmode_get = horus_port_egvlanmode_get; + p_api->port_egvlanmode_set = horus_port_egvlanmode_set; + p_api->portvlan_member_add = horus_portvlan_member_add; + p_api->portvlan_member_del = horus_portvlan_member_del; + p_api->portvlan_member_update = horus_portvlan_member_update; + p_api->portvlan_member_get = horus_portvlan_member_get; + p_api->port_default_vid_set = horus_port_default_vid_set; + p_api->port_default_vid_get = horus_port_default_vid_get; + p_api->port_force_default_vid_set = horus_port_force_default_vid_set; + p_api->port_force_default_vid_get = horus_port_force_default_vid_get; + p_api->port_force_portvlan_set = horus_port_force_portvlan_set; + p_api->port_force_portvlan_get = horus_port_force_portvlan_get; + p_api->nestvlan_tpid_set = horus_nestvlan_tpid_set; + p_api->nestvlan_tpid_get = horus_nestvlan_tpid_get; + p_api->port_invlan_mode_set = horus_port_invlan_mode_set; + p_api->port_invlan_mode_get = horus_port_invlan_mode_get; + p_api->port_pri_propagation_set = horus_port_pri_propagation_set; + p_api->port_pri_propagation_get = horus_port_pri_propagation_get; + p_api->qinq_mode_set = horus_qinq_mode_set; + p_api->qinq_mode_get = horus_qinq_mode_get; + p_api->port_qinq_role_set = horus_port_qinq_role_set; + p_api->port_qinq_role_get = horus_port_qinq_role_get; +#endif + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_qos.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_qos.c new file mode 100755 index 000000000..b2c6398e5 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_qos.c @@ -0,0 +1,1260 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 horus_qos HORUS_QOS + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "horus_qos.h" +#include "horus_reg.h" + +#define HORUS_QOS_QUEUE_TX_BUFFER_MAX 60 +#define HORUS_QOS_PORT_TX_BUFFER_MAX 252 +#define HORUS_QOS_PORT_RX_BUFFER_MAX 60 + +//#define HORUS_MIN_QOS_MODE_PRI 0 +#define HORUS_MAX_QOS_MODE_PRI 3 + +static sw_error_t +_horus_qos_queue_tx_buf_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, QUEUE_CTL, port_id, QUEUE_DESC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_qos_queue_tx_buf_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, QUEUE_CTL, port_id, QUEUE_DESC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_horus_qos_port_tx_buf_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, QUEUE_CTL, port_id, PORT_DESC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_qos_port_tx_buf_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, QUEUE_CTL, port_id, PORT_DESC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_horus_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) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (HORUS_QOS_QUEUE_TX_BUFFER_MAX < *number) + { + return SW_BAD_PARAM; + } + + val = *number / 4; + *number = val << 2; + + if (0 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, QUEUE_CTL, port_id, QUEUE0_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (1 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, QUEUE_CTL, port_id, QUEUE1_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (2 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, QUEUE_CTL, port_id, QUEUE2_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (3 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, QUEUE_CTL, port_id, QUEUE3_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + + return rv; +} + +static sw_error_t +_horus_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) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (0 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, QUEUE_CTL, port_id, QUEUE0_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (1 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, QUEUE_CTL, port_id, QUEUE1_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (2 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, QUEUE_CTL, port_id, QUEUE2_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (3 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, QUEUE_CTL, port_id, QUEUE3_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + *number = val << 2; + return SW_OK; +} + +static sw_error_t +_horus_qos_port_tx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (HORUS_QOS_PORT_TX_BUFFER_MAX < *number) + { + return SW_BAD_PARAM; + } + + val = *number / 4; + *number = val << 2; + HSL_REG_FIELD_SET(rv, dev_id, QUEUE_CTL, port_id, PORT_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_qos_port_tx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, QUEUE_CTL, port_id, PORT_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *number = val << 2; + return SW_OK; +} + +static sw_error_t +_horus_qos_port_rx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (HORUS_QOS_PORT_RX_BUFFER_MAX < *number) + { + return SW_BAD_PARAM; + } + + val = *number / 4; + *number = val << 2; + HSL_REG_FIELD_SET(rv, dev_id, QUEUE_CTL, port_id, PORT_IN_DESC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_qos_port_rx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, QUEUE_CTL, port_id, PORT_IN_DESC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *number = val << 2; + return SW_OK; +} + +static sw_error_t +_horus_cosmap_up_queue_set(a_uint32_t dev_id, a_uint32_t up, + fal_queue_t queue) +{ + sw_error_t rv; + a_uint32_t val; + hsl_dev_t *p_dev = NULL; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_DOT1P_MAX < up) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL(p_dev = hsl_dev_ptr_get(dev_id)); + if (p_dev->nr_queue <= queue) + { + return SW_BAD_PARAM; + } + + val = queue; + HSL_REG_FIELD_GEN_SET(rv, dev_id, TAG_PRI_MAPPING_OFFSET, 2, + (a_uint16_t) (up << 1), (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_cosmap_up_queue_get(a_uint32_t dev_id, a_uint32_t up, + fal_queue_t * queue) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_DOT1P_MAX < up) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GEN_GET(rv, dev_id, TAG_PRI_MAPPING_OFFSET, 2, + (a_uint16_t) (up << 1), (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *queue = val; + return SW_OK; +} + +static sw_error_t +_horus_cosmap_dscp_queue_set(a_uint32_t dev_id, a_uint32_t dscp, + fal_queue_t queue) +{ + sw_error_t rv; + a_uint32_t val; + a_uint32_t offsetaddr; + a_uint16_t fieldoffset; + hsl_dev_t *p_dev = NULL; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_DSCP_MAX < dscp) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL(p_dev = hsl_dev_ptr_get(dev_id)); + if (p_dev->nr_queue <= queue) + { + return SW_BAD_PARAM; + } + + offsetaddr = (dscp >> 4) << 2; + fieldoffset = (dscp & 0xf) << 1; + + val = queue; + HSL_REG_FIELD_GEN_SET(rv, dev_id, (IP_PRI_MAPPING_OFFSET + offsetaddr), + 2, fieldoffset, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_cosmap_dscp_queue_get(a_uint32_t dev_id, a_uint32_t dscp, + fal_queue_t * queue) +{ + sw_error_t rv; + a_uint32_t val; + a_uint32_t offsetaddr; + a_uint16_t fieldoffset; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_DSCP_MAX < dscp) + { + return SW_BAD_PARAM; + } + + offsetaddr = (dscp / 16) << 2; + fieldoffset = (dscp & 0xf) << 1; + + HSL_REG_FIELD_GEN_GET(rv, dev_id, (IP_PRI_MAPPING_OFFSET + offsetaddr), + 2, fieldoffset, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *queue = val; + return SW_OK; +} + +static sw_error_t +_horus_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; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + if (FAL_QOS_DA_MODE == mode) + { + HSL_REG_FIELD_SET(rv, dev_id, PRI_CTL, port_id, DA_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (FAL_QOS_UP_MODE == mode) + { + HSL_REG_FIELD_SET(rv, dev_id, PRI_CTL, port_id, VLAN_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (FAL_QOS_DSCP_MODE == mode) + { + HSL_REG_FIELD_SET(rv, dev_id, PRI_CTL, port_id, IP_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (FAL_QOS_PORT_MODE == mode) + { + HSL_REG_FIELD_SET(rv, dev_id, PRI_CTL, port_id, PORT_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + + return rv; +} + +static sw_error_t +_horus_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; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_QOS_DA_MODE == mode) + { + HSL_REG_FIELD_GET(rv, dev_id, PRI_CTL, port_id, DA_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (FAL_QOS_UP_MODE == mode) + { + HSL_REG_FIELD_GET(rv, dev_id, PRI_CTL, port_id, VLAN_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (FAL_QOS_DSCP_MODE == mode) + { + HSL_REG_FIELD_GET(rv, dev_id, PRI_CTL, port_id, IP_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (FAL_QOS_PORT_MODE == mode) + { + HSL_REG_FIELD_GET(rv, dev_id, PRI_CTL, port_id, PORT_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_horus_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; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (HORUS_MAX_QOS_MODE_PRI < pri) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PRI_CTL, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_QOS_DA_MODE == mode) + { + SW_SET_REG_BY_FIELD(PRI_CTL, DA_PRI_SEL, pri, val); + } + else if (FAL_QOS_UP_MODE == mode) + { + SW_SET_REG_BY_FIELD(PRI_CTL, VLAN_PRI_SEL, pri, val); + } + else if (FAL_QOS_DSCP_MODE == mode) + { + SW_SET_REG_BY_FIELD(PRI_CTL, IP_PRI_SEL, pri, val); + } + else if (FAL_QOS_PORT_MODE == mode) + { + SW_SET_REG_BY_FIELD(PRI_CTL, PORT_PRI_SEL, pri, val); + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_ENTRY_SET(rv, dev_id, PRI_CTL, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_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; + a_uint32_t entry, f_val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PRI_CTL, port_id, (a_uint8_t *) (&entry), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_QOS_DA_MODE == mode) + { + SW_GET_FIELD_BY_REG(PRI_CTL, DA_PRI_SEL, f_val, entry); + } + else if (FAL_QOS_UP_MODE == mode) + { + SW_GET_FIELD_BY_REG(PRI_CTL, VLAN_PRI_SEL, f_val, entry); + } + else if (FAL_QOS_DSCP_MODE == mode) + { + SW_GET_FIELD_BY_REG(PRI_CTL, IP_PRI_SEL, f_val, entry); + } + else if (FAL_QOS_PORT_MODE == mode) + { + SW_GET_FIELD_BY_REG(PRI_CTL, PORT_PRI_SEL, f_val, entry); + } + else + { + return SW_NOT_SUPPORTED; + } + + *pri = f_val; + return SW_OK; +} + +static sw_error_t +_horus_qos_port_default_up_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t up) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_DOT1P_MAX < up) + { + return SW_BAD_PARAM; + } + + val = up; + HSL_REG_FIELD_SET(rv, dev_id, PORT_DOT1Q, port_id, ING_PRI, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_qos_port_default_up_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * up) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_DOT1Q, port_id, ING_PRI, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *up = val; + return SW_OK; +} + +static sw_error_t +_horus_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; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_SCH_SP_MODE == mode) + { + val = 0; + } + else if (FAL_SCH_WRR_MODE == mode) + { + val = 3; + } + else if (FAL_SCH_MIX_MODE == mode) + { + val = 1; + } + else if (FAL_SCH_MIX_PLUS_MODE == mode) + { + val = 2; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, WRR_CTRL, port_id, SCH_MODE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_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; + a_uint32_t sch, i; + a_uint32_t w[4] = {1, 2, 4, 8}; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, WRR_CTRL, port_id, SCH_MODE, + (a_uint8_t *) (&sch), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0 == sch) + { + *mode = FAL_SCH_SP_MODE; + for (i = 0; i < 4; i++) + { + w[i] = 0; + } + } + else if (1 == sch) + { + *mode = FAL_SCH_MIX_MODE; + w[3] = 0; + } + else if (2 == sch) + { + *mode = FAL_SCH_MIX_PLUS_MODE; + w[3] = 0; + w[2] = 0; + } + else + { + *mode = FAL_SCH_WRR_MODE; + } + + for (i = 0; i < 4; i++) + { + weight[i] = w[i]; + } + + return SW_OK; +} + +/** + * @brief Set buffer aggsinment status of transmitting queue on one particular port. + * @details Comments: + * If enable queue tx buffer on one port that means each queue of this port + * will have fixed number buffers when transmitting packets. Otherwise they + * share the whole buffers with other queues in device. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_qos_queue_tx_buf_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_qos_queue_tx_buf_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get buffer aggsinment status of transmitting queue on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_qos_queue_tx_buf_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_qos_queue_tx_buf_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set buffer aggsinment status of transmitting port on one particular port. + * @details Comments: + If enable tx buffer on one port that means this port will have fixed + number buffers when transmitting packets. Otherwise they will + share the whole buffers with other ports in device. + * function will return actual buffer numbers in hardware. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_qos_port_tx_buf_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_qos_port_tx_buf_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get buffer aggsinment status of transmitting port on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_qos_port_tx_buf_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_qos_port_tx_buf_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set max occupied buffer number of transmitting queue on one particular port. + * @details Comments: + The step of buffer number in Garuda is 4, function will return actual + buffer numbers in hardware. + The buffer number range for queue is 4 to 60. + * share the whole buffers with other ports in device. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param number buffer number + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_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; + + HSL_API_LOCK; + rv = _horus_qos_queue_tx_buf_nr_set(dev_id, port_id, queue_id, number); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get max occupied buffer number of transmitting queue on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param[out] number buffer number + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_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; + + HSL_API_LOCK; + rv = _horus_qos_queue_tx_buf_nr_get(dev_id, port_id, queue_id, number); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set max occupied buffer number of transmitting port on one particular port. + * @details Comments: + The step of buffer number in Garuda is four, function will return actual + buffer numbers in hardware. + The buffer number range for transmitting port is 4 to 124. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param number buffer number + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_qos_port_tx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_qos_port_tx_buf_nr_set(dev_id, port_id, number); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get max occupied buffer number of transmitting port on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] number buffer number + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_qos_port_tx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_qos_port_tx_buf_nr_get(dev_id, port_id, number); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set max occupied buffer number of receiving port on one particular port. + * @details Comments: + The step of buffer number in Horus is four, function will return actual + buffer numbers in hardware. + The buffer number range for receiving port is 4 to 60. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param number buffer number + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_qos_port_rx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_qos_port_rx_buf_nr_set(dev_id, port_id, number); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get max occupied buffer number of receiving port on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] number buffer number + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_qos_port_rx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_qos_port_rx_buf_nr_get(dev_id, port_id, number); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set user priority to mapping on one particular device. + * @param[in] dev_id device id + * @param[in] dot1p 802.1p + * @param[in] queue queue id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_cosmap_up_queue_set(a_uint32_t dev_id, a_uint32_t up, + fal_queue_t queue) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_cosmap_up_queue_set(dev_id, up, queue); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get user priority to mapping on one particular device. + * @param[in] dev_id device id + * @param[in] dot1p 802.1p + * @param[out] queue queue id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_cosmap_up_queue_get(a_uint32_t dev_id, a_uint32_t up, + fal_queue_t * queue) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_cosmap_up_queue_get(dev_id, up, queue); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set cos map dscp_2_queue item on one particular device. + * @param[in] dev_id device id + * @param[in] dscp dscp + * @param[in] queue queue id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_cosmap_dscp_queue_set(a_uint32_t dev_id, a_uint32_t dscp, + fal_queue_t queue) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_cosmap_dscp_queue_set(dev_id, dscp, queue); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get cos map dscp_2_queue item on one particular device. + * @param[in] dev_id device id + * @param[in] dscp dscp + * @param[out] queue queue id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_cosmap_dscp_queue_get(a_uint32_t dev_id, a_uint32_t dscp, + fal_queue_t * queue) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_cosmap_dscp_queue_get(dev_id, dscp, queue); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set port qos mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode qos mode + * @param[in] enable A_TRUE of A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_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; + + HSL_API_LOCK; + rv = _horus_qos_port_mode_set(dev_id, port_id, mode, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get port qos mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode qos mode + * @param[out] enable A_TRUE of A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_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; + + HSL_API_LOCK; + rv = _horus_qos_port_mode_get(dev_id, port_id, mode, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set priority of one particular qos mode on one particular port. + * @details Comments: + If the priority of a mode is more small then the priority is more high. + Differnet mode should have differnet priority. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode qos mode + * @param[in] pri priority of one particular qos mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_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; + + HSL_API_LOCK; + rv = _horus_qos_port_mode_pri_set(dev_id, port_id, mode, pri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get priority of one particular qos mode on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode qos mode + * @param[out] pri priority of one particular qos mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_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; + + HSL_API_LOCK; + rv = _horus_qos_port_mode_pri_get(dev_id, port_id, mode, pri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set default user priority on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] up 802.1p + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_qos_port_default_up_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t up) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_qos_port_default_up_set(dev_id, port_id, up); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get default user priority on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] up 802.1p + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_qos_port_default_up_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * up) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_qos_port_default_up_get(dev_id, port_id, up); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set traffic scheduling mode on particular one port. + * @details Comments: + * When scheduling mode is sp the weight is meaningless usually it's zero + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] fal_sch_mode_t traffic scheduling mode + * @param[in] weight[] weight value for each queue when in wrr mode, + Horus only support fixed weight 1:2:4:8 for four queues. + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_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; + + HSL_API_LOCK; + rv = _horus_qos_port_sch_mode_set(dev_id, port_id, mode, weight); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get traffic scheduling mode on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] fal_sch_mode_t traffic scheduling mode + * @param[out] weight weight value for wrr mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_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; + + HSL_API_LOCK; + rv = _horus_qos_port_sch_mode_get(dev_id, port_id, mode, weight); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +horus_qos_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->qos_queue_tx_buf_status_set = horus_qos_queue_tx_buf_status_set; + p_api->qos_queue_tx_buf_status_get = horus_qos_queue_tx_buf_status_get; + p_api->qos_port_tx_buf_status_set = horus_qos_port_tx_buf_status_set; + p_api->qos_port_tx_buf_status_get = horus_qos_port_tx_buf_status_get; + p_api->qos_queue_tx_buf_nr_set = horus_qos_queue_tx_buf_nr_set; + p_api->qos_queue_tx_buf_nr_get = horus_qos_queue_tx_buf_nr_get; + p_api->qos_port_tx_buf_nr_set = horus_qos_port_tx_buf_nr_set; + p_api->qos_port_tx_buf_nr_get = horus_qos_port_tx_buf_nr_get; + p_api->qos_port_rx_buf_nr_set = horus_qos_port_rx_buf_nr_set; + p_api->qos_port_rx_buf_nr_get = horus_qos_port_rx_buf_nr_get; + p_api->cosmap_up_queue_set = horus_cosmap_up_queue_set; + p_api->cosmap_up_queue_get = horus_cosmap_up_queue_get; + p_api->cosmap_dscp_queue_set = horus_cosmap_dscp_queue_set; + p_api->cosmap_dscp_queue_get = horus_cosmap_dscp_queue_get; + p_api->qos_port_mode_set = horus_qos_port_mode_set; + p_api->qos_port_mode_get = horus_qos_port_mode_get; + p_api->qos_port_mode_pri_set = horus_qos_port_mode_pri_set; + p_api->qos_port_mode_pri_get = horus_qos_port_mode_pri_get; + p_api->qos_port_default_up_set = horus_qos_port_default_up_set; + p_api->qos_port_default_up_get = horus_qos_port_default_up_get; + p_api->qos_port_sch_mode_set = horus_qos_port_sch_mode_set; + p_api->qos_port_sch_mode_get = horus_qos_port_sch_mode_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_rate.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_rate.c new file mode 100755 index 000000000..acb1fb0c1 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_rate.c @@ -0,0 +1,578 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 horus_rate HORUS_RATE + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "horus_rate.h" +#include "horus_reg.h" + +#define HORUS_STORM_MIN_RATE_PPS 1000 +#define HORUS_STORM_MAX_RATE_PPS (1024 * 1000) + +static sw_error_t +horus_stormrate_sw_to_hw(a_uint32_t swrate, a_uint32_t * hwrate) +{ + a_uint32_t shrnr = 0; + a_uint32_t tmp = swrate / 1000; + + if ((HORUS_STORM_MIN_RATE_PPS > swrate) + || (HORUS_STORM_MAX_RATE_PPS < swrate)) + { + return SW_BAD_PARAM; + } + + while ((tmp != 0) && (shrnr < 12)) + { + tmp = tmp >> 1; + shrnr++; + } + + if (12 == shrnr) + { + return SW_BAD_PARAM; + } + + *hwrate = shrnr; + return SW_OK; +} + +static sw_error_t +horus_stormrate_hw_to_sw(a_uint32_t hwrate, a_uint32_t * swrate) +{ + if (0 == hwrate) + { + hwrate = 1; + } + + if ((1 > hwrate) || (11 < hwrate)) + { + return SW_BAD_PARAM; + } + + *swrate = (1 << (hwrate - 1)) * 1000; + return SW_OK; +} + +static sw_error_t +_horus_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; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_FALSE == enable) + { + *speed = 0; + + val = 0x1fff; + HSL_REG_FIELD_SET(rv, dev_id, RATE_LIMIT1, port_id, EG_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else + { + if ((0x1ffe << 5) < *speed) + { + return SW_BAD_PARAM; + } + + val = *speed >> 5; + *speed = val << 5; + HSL_REG_FIELD_SET(rv, dev_id, RATE_LIMIT1, port_id, EG_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + + return rv; +} + +static sw_error_t +_horus_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; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, RATE_LIMIT1, port_id, EG_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0x1fff == val) + { + *speed = 0; + *enable = A_FALSE; + } + else + { + *enable = A_TRUE; + *speed = val << 5; + } + + return SW_OK; +} + +static sw_error_t +_horus_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; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + if ((0x7ffe << 5) < *speed) + { + return SW_BAD_PARAM; + } + val = *speed >> 5; + *speed = val << 5; + } + else if (A_FALSE == enable) + { + val = 0x7fff; + *speed = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, RATE_LIMIT0, port_id, ING_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_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; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, RATE_LIMIT0, port_id, ING_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0x7fff == val) + { + *enable = A_FALSE; + *speed = 0; + } + else + { + *enable = A_TRUE; + *speed = val << 5; + } + + return SW_OK; +} + +static sw_error_t +_horus_storm_ctrl_frame_set(a_uint32_t dev_id, fal_port_t port_id, + fal_storm_type_t storm_type, a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + if (FAL_UNICAST_STORM == storm_type) + { + HSL_REG_FIELD_SET(rv, dev_id, STORM_CTL, port_id, UNI_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else if (FAL_MULTICAST_STORM == storm_type) + { + HSL_REG_FIELD_SET(rv, dev_id, STORM_CTL, port_id, MUL_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else if (FAL_BROADCAST_STORM == storm_type) + { + HSL_REG_FIELD_SET(rv, dev_id, STORM_CTL, port_id, BRO_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, STORM_CTL, port_id, RATE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0 == data) + { + data = 1; + HSL_REG_FIELD_SET(rv, dev_id, STORM_CTL, port_id, RATE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +static sw_error_t +_horus_storm_ctrl_frame_get(a_uint32_t dev_id, fal_port_t port_id, + fal_storm_type_t storm_type, a_bool_t * enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_UNICAST_STORM == storm_type) + { + HSL_REG_FIELD_GET(rv, dev_id, STORM_CTL, port_id, UNI_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else if (FAL_MULTICAST_STORM == storm_type) + { + HSL_REG_FIELD_GET(rv, dev_id, STORM_CTL, port_id, MUL_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else if (FAL_BROADCAST_STORM == storm_type) + { + HSL_REG_FIELD_GET(rv, dev_id, STORM_CTL, port_id, BRO_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + data = 1; + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_horus_storm_ctrl_rate_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * rate_in_pps) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + rv = horus_stormrate_sw_to_hw(*rate_in_pps, &data); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, STORM_CTL, port_id, RATE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = horus_stormrate_hw_to_sw(data, rate_in_pps); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +static sw_error_t +_horus_storm_ctrl_rate_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * rate_in_pps) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, STORM_CTL, port_id, RATE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = horus_stormrate_hw_to_sw(data, rate_in_pps); + return rv; +} + +/** + * @brief Set port egress rate limit status on one particular port. + * @details Comments: + The granularity of speed is bps. + Because of hardware granularity function will return actual speed in hardware. + When disable port egress rate limit input parameter speed is meaningless. + The step of speed is 32kbps. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param speed rate limit speed + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_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; + + HSL_API_LOCK; + rv = _horus_rate_port_egrl_set(dev_id, port_id, speed, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get port egress rate limit status on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] speed rate limit speed + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_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; + + HSL_API_LOCK; + rv = _horus_rate_port_egrl_get(dev_id, port_id, speed, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set port ingress rate limit status on one particular port. + * @details Comments: + The granularity of speed is bps. + Because of hardware granularity function will return actual speed in hardware. + When disable port ingress rate limit input parameter speed is meaningless. + The step of speed is 32kbps. + * When disable port ingress rate limit input parameter speed is meaningless. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param speed rate limit speed + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_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; + + HSL_API_LOCK; + rv = _horus_rate_port_inrl_set(dev_id, port_id, speed, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get port ingress rate limit status on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] speed rate limit speed + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_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; + + HSL_API_LOCK; + rv = _horus_rate_port_inrl_get(dev_id, port_id, speed, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set particular type storm control status on one particular port. + * @details Comments: + * When enable one particular packets type storm control this type packets + * speed will be calculated in storm control. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] frame_type packets type which causes storm + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_storm_ctrl_frame_set(a_uint32_t dev_id, fal_port_t port_id, + fal_storm_type_t storm_type, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_storm_ctrl_frame_set(dev_id, port_id, storm_type, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get particular type storm control status on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] frame_type packets type which causes storm + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_storm_ctrl_frame_get(a_uint32_t dev_id, fal_port_t port_id, + fal_storm_type_t storm_type, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_storm_ctrl_frame_get(dev_id, port_id, storm_type, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set storm control speed on one particular port. + * @details Comments: + Because of hardware granularity function will return actual speed in hardware. + The step of speed is kpps. + The speed range is from 1k to 1M + * @param[in] dev_id device id + * @param[in] port_id port id + * @param speed storm control speed + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_storm_ctrl_rate_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * rate_in_pps) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_storm_ctrl_rate_set(dev_id, port_id, rate_in_pps); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get storm control speed on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] speed storm control speed + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_storm_ctrl_rate_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * rate_in_pps) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_storm_ctrl_rate_get(dev_id, port_id, rate_in_pps); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +horus_rate_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->rate_port_egrl_set = horus_rate_port_egrl_set; + p_api->rate_port_egrl_get = horus_rate_port_egrl_get; + p_api->rate_port_inrl_set = horus_rate_port_inrl_set; + p_api->rate_port_inrl_get = horus_rate_port_inrl_get; + p_api->storm_ctrl_frame_set = horus_storm_ctrl_frame_set; + p_api->storm_ctrl_frame_get = horus_storm_ctrl_frame_get; + p_api->storm_ctrl_rate_set = horus_storm_ctrl_rate_set; + p_api->storm_ctrl_rate_get = horus_storm_ctrl_rate_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_reg_access.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_reg_access.c new file mode 100755 index 000000000..f8d4fae20 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_reg_access.c @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 "hsl.h" +#include "hsl_dev.h" +#include "sd.h" +#include "horus_reg_access.h" + +static hsl_access_mode reg_mode; + +#if defined(API_LOCK) +static aos_lock_t mdio_lock; +#define MDIO_LOCKER_INIT aos_lock_init(&mdio_lock) +#define MDIO_LOCKER_LOCK aos_lock(&mdio_lock) +#define MDIO_LOCKER_UNLOCK aos_unlock(&mdio_lock) +#else +#define MDIO_LOCKER_INIT +#define MDIO_LOCKER_LOCK +#define MDIO_LOCKER_UNLOCK +#endif + +static sw_error_t +_horus_mdio_reg_get(a_uint32_t dev_id, a_uint32_t reg_addr, + a_uint8_t value[], a_uint32_t value_len) +{ + a_uint32_t reg_word_addr; + a_uint32_t phy_addr, reg_val; + a_uint16_t phy_val, tmp_val; + a_uint8_t phy_reg; + sw_error_t rv; + + if (value_len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + + /* change reg_addr to 16-bit word address, 32-bit aligned */ + reg_word_addr = (reg_addr & 0xfffffffc) >> 1; + + /* configure register high address */ + phy_addr = 0x18; + phy_reg = 0x0; + phy_val = (a_uint16_t) ((reg_word_addr >> 8) & 0x3ff); /* bit16-8 of reg address */ + + rv = sd_reg_mdio_set(dev_id, phy_addr, phy_reg, phy_val); + SW_RTN_ON_ERROR(rv); + + /* For some registers such as MIBs, since it is read/clear, we should */ + /* read the lower 16-bit register then the higher one */ + + /* read register in lower address */ + phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */ + phy_reg = (a_uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */ + rv = sd_reg_mdio_get(dev_id, phy_addr, phy_reg, &tmp_val); + SW_RTN_ON_ERROR(rv); + reg_val = tmp_val; + + /* read register in higher address */ + reg_word_addr++; + phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */ + phy_reg = (a_uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */ + rv = sd_reg_mdio_get(dev_id, phy_addr, phy_reg, &tmp_val); + SW_RTN_ON_ERROR(rv); + reg_val |= (((a_uint32_t)tmp_val) << 16); + + aos_mem_copy(value, ®_val, sizeof (a_uint32_t)); + + return SW_OK; +} + +static sw_error_t +_horus_mdio_reg_set(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t value[], + a_uint32_t value_len) +{ + a_uint32_t reg_word_addr; + a_uint32_t phy_addr, reg_val; + a_uint16_t phy_val; + a_uint8_t phy_reg; + sw_error_t rv; + + if (value_len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + + aos_mem_copy(®_val, value, sizeof (a_uint32_t)); + + /* change reg_addr to 16-bit word address, 32-bit aligned */ + reg_word_addr = (reg_addr & 0xfffffffc) >> 1; + + /* configure register high address */ + phy_addr = 0x18; + phy_reg = 0x0; + phy_val = (a_uint16_t) ((reg_word_addr >> 8) & 0x3ff); /* bit16-8 of reg address */ + + rv = sd_reg_mdio_set(dev_id, phy_addr, phy_reg, phy_val); + SW_RTN_ON_ERROR(rv); + + /* For some registers such as ARL and VLAN, since they include BUSY bit */ + /* in lower address, we should write the higher 16-bit register then the */ + /* lower one */ + + /* write register in higher address */ + reg_word_addr++; + phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */ + phy_reg = (a_uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */ + phy_val = (a_uint16_t) ((reg_val >> 16) & 0xffff); + rv = sd_reg_mdio_set(dev_id, phy_addr, phy_reg, phy_val); + SW_RTN_ON_ERROR(rv); + + /* write register in lower address */ + reg_word_addr--; + phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */ + phy_reg = (a_uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */ + phy_val = (a_uint16_t) (reg_val & 0xffff); + rv = sd_reg_mdio_set(dev_id, phy_addr, phy_reg, phy_val); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +sw_error_t +horus_phy_get(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t * value) +{ + sw_error_t rv; + + MDIO_LOCKER_LOCK; + rv = sd_reg_mdio_get(dev_id, phy_addr, reg, value); + MDIO_LOCKER_UNLOCK; + + return rv; +} + +sw_error_t +horus_phy_set(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t value) +{ + sw_error_t rv; + + MDIO_LOCKER_LOCK; + rv = sd_reg_mdio_set(dev_id, phy_addr, reg, value); + MDIO_LOCKER_UNLOCK; + + return rv; +} + +sw_error_t +horus_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; + a_uint32_t flags; + + MDIO_LOCKER_LOCK; + if (HSL_MDIO == reg_mode) + { + aos_irq_save(flags); + rv = _horus_mdio_reg_get(dev_id, reg_addr, value, value_len); + aos_irq_restore(flags); + } + else + { + rv = sd_reg_hdr_get(dev_id, reg_addr, value, value_len); + } + MDIO_LOCKER_UNLOCK; + + return rv; +} + +sw_error_t +horus_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; + a_uint32_t flags; + + MDIO_LOCKER_LOCK; + if (HSL_MDIO == reg_mode) + { + aos_irq_save(flags); + rv = _horus_mdio_reg_set(dev_id, reg_addr, value, value_len); + aos_irq_restore(flags); + } + else + { + rv = sd_reg_hdr_set(dev_id, reg_addr, value, value_len); + } + MDIO_LOCKER_UNLOCK; + + return rv; +} + +sw_error_t +horus_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) +{ + a_uint32_t reg_val = 0; + + if ((bit_offset >= 32 || (field_len > 32)) || (field_len == 0)) + return SW_OUT_OF_RANGE; + + if (value_len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + + SW_RTN_ON_ERROR(horus_reg_get(dev_id, reg_addr, (a_uint8_t *) & reg_val, sizeof (a_uint32_t))); + + *((a_uint32_t *) value) = SW_REG_2_FIELD(reg_val, bit_offset, field_len); + return SW_OK; +} + +sw_error_t +horus_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) +{ + a_uint32_t reg_val; + a_uint32_t field_val = *((a_uint32_t *) value); + + if ((bit_offset >= 32 || (field_len > 32)) || (field_len == 0)) + return SW_OUT_OF_RANGE; + + if (value_len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + + SW_RTN_ON_ERROR(horus_reg_get(dev_id, reg_addr, (a_uint8_t *) & reg_val, sizeof (a_uint32_t))); + + SW_REG_SET_BY_FIELD_U32(reg_val, field_val, bit_offset, field_len); + + SW_RTN_ON_ERROR(horus_reg_set(dev_id, reg_addr, (a_uint8_t *) & reg_val, sizeof (a_uint32_t))); + + return SW_OK; +} + +sw_error_t +horus_reg_access_init(a_uint32_t dev_id, hsl_access_mode mode) +{ + hsl_api_t *p_api; + + MDIO_LOCKER_INIT; + reg_mode = mode; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->phy_get = horus_phy_get; + p_api->phy_set = horus_phy_set; + p_api->reg_get = horus_reg_get; + p_api->reg_set = horus_reg_set; + p_api->reg_field_get = horus_reg_field_get; + p_api->reg_field_set = horus_reg_field_set; + p_api->dev_access_set= horus_access_mode_set; + + return SW_OK; +} + +sw_error_t +horus_access_mode_set(a_uint32_t dev_id, hsl_access_mode mode) +{ + reg_mode = mode; + return SW_OK; + +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_stp.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_stp.c new file mode 100755 index 000000000..0f4a97367 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_stp.c @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 horus_stp HORUS_STP + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "horus_stp.h" +#include "horus_reg.h" + +#define HORUS_PORT_DISABLED 0 +#define HORUS_STP_BLOCKING 1 +#define HORUS_STP_LISTENING 2 +#define HORUS_STP_LEARNING 3 +#define HORUS_STP_FARWARDING 4 + +static sw_error_t +_horus_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; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_SINGLE_STP_ID != st_id) + { + return SW_BAD_PARAM; + } + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + switch (state) + { + case FAL_STP_BLOKING: + val = HORUS_STP_BLOCKING; + break; + case FAL_STP_LISTENING: + val = HORUS_STP_LISTENING; + break; + case FAL_STP_LEARNING: + val = HORUS_STP_LEARNING; + break; + case FAL_STP_FARWARDING: + val = HORUS_STP_FARWARDING; + break; + case FAL_STP_DISABLED: + val = HORUS_PORT_DISABLED; + break; + default: + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, PORT_STATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_horus_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; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_SINGLE_STP_ID != st_id) + { + return SW_BAD_PARAM; + } + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, PORT_STATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + switch (val) + { + case HORUS_STP_BLOCKING: + *state = FAL_STP_BLOKING; + break; + case HORUS_STP_LISTENING: + *state = FAL_STP_LISTENING; + break; + case HORUS_STP_LEARNING: + *state = FAL_STP_LEARNING; + break; + case HORUS_STP_FARWARDING: + *state = FAL_STP_FARWARDING; + break; + case HORUS_PORT_DISABLED: + *state = FAL_STP_DISABLED; + break; + default: + return SW_FAIL; + } + + return SW_OK; +} + +/** + * @brief Set port stp state on a particular spanning tree and port. + * @details Comments: + Garuda only support single spanning tree so st_id should be + FAL_SINGLE_STP_ID that is zero. + * @param[in] dev_id device id + * @param[in] st_id spanning tree id + * @param[in] port_id port id + * @param[in] state port state for spanning tree + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_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; + + HSL_API_LOCK; + rv = _horus_stp_port_state_set(dev_id, st_id, port_id, state); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get port stp state on a particular spanning tree and port. + * @details Comments: + Garuda only support single spanning tree so st_id should be + FAL_SINGLE_STP_ID that is zero. + * @param[in] dev_id device id + * @param[in] st_id spanning tree id + * @param[in] port_id port id + * @param[out] state port state for spanning tree + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_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; + + HSL_API_LOCK; + rv = _horus_stp_port_state_get(dev_id, st_id, port_id, state); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +horus_stp_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->stp_port_state_set = horus_stp_port_state_set; + p_api->stp_port_state_get = horus_stp_port_state_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_vlan.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_vlan.c new file mode 100755 index 000000000..754194ffa --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/horus/horus_vlan.c @@ -0,0 +1,518 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 horus_vlan HORUS_VLAN + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "horus_vlan.h" +#include "horus_reg.h" + +#define MAX_VLAN_ID 4095 + +#define VLAN_FLUSH 1 +#define VLAN_LOAD_ENTRY 2 +#define VLAN_PURGE_ENTRY 3 +#define VLAN_REMOVE_PORT 4 +#define VLAN_NEXT_ENTRY 5 +#define VLAN_FIND_ENTRY 6 + +static void +horus_vlan_hw_to_sw(const a_uint32_t reg[], fal_vlan_t * vlan_entry) +{ + a_uint32_t data; + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC0, VT_PRI_EN, data, reg[0]); + if (1 == data) + { + vlan_entry->vid_pri_en = A_TRUE; + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC0, VT_PRI, data, reg[0]); + vlan_entry->vid_pri = data & 0xff; + } + else + { + vlan_entry->vid_pri_en = A_FALSE; + } + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC0, VLAN_ID, data, reg[0]); + vlan_entry->vid = data & 0xffff; + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC1, VID_MEM, data, reg[1]); + vlan_entry->mem_ports = data; + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC1, LEARN_DIS, data, reg[1]); + if (1 == data) + { + vlan_entry->learn_dis = A_TRUE; + } + else + { + vlan_entry->learn_dis = A_FALSE; + } + + return; +} + +static sw_error_t +horus_vlan_sw_to_hw(const fal_vlan_t * vlan_entry, a_uint32_t reg[]) +{ + if (A_TRUE == vlan_entry->vid_pri_en) + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_PRI_EN, 1, reg[0]); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_PRI, vlan_entry->vid_pri, reg[0]); + } + else + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_PRI_EN, 0, reg[0]); + } + + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VLAN_ID, vlan_entry->vid, reg[0]); + + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC1, VT_VALID, 1, reg[1]); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC1, VID_MEM, vlan_entry->mem_ports, reg[1]); + + if (A_TRUE == vlan_entry->learn_dis) + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC1, LEARN_DIS, 1, reg[1]); + } + else + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC1, LEARN_DIS, 0, reg[1]); + } + + if (0 != vlan_entry->u_ports) + { + return SW_BAD_VALUE; + } + + return SW_OK; +} + +static sw_error_t +horus_vlan_commit(a_uint32_t dev_id, a_uint32_t op) +{ + a_uint32_t vt_busy = 1, i = 0x1000, vt_full, val; + sw_error_t rv; + + while (vt_busy && --i) + { + HSL_REG_FIELD_GET(rv, dev_id, VLAN_TABLE_FUNC0, 0, VT_BUSY, + (a_uint8_t *) (&vt_busy), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + aos_udelay(5); + } + + if (i == 0) + return SW_BUSY; + + HSL_REG_ENTRY_GET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_FUNC, op, val); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_BUSY, 1, val); + + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + vt_busy = 1; + i = 0x1000; + while (vt_busy && --i) + { + HSL_REG_FIELD_GET(rv, dev_id, VLAN_TABLE_FUNC0, 0, VT_BUSY, + (a_uint8_t *) (&vt_busy), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + aos_udelay(5); + } + + if (i == 0) + return SW_FAIL; + + HSL_REG_FIELD_GET(rv, dev_id, VLAN_TABLE_FUNC0, 0, VT_FULL_VIO, + (a_uint8_t *) (&vt_full), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (vt_full) + { + val = 0x10; + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + if (VLAN_LOAD_ENTRY == op) + { + return SW_FULL; + } + else if (VLAN_PURGE_ENTRY == op) + { + return SW_NOT_FOUND; + } + } + + HSL_REG_FIELD_GET(rv, dev_id, VLAN_TABLE_FUNC1, 0, VT_VALID, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (!val) + { + if (VLAN_FIND_ENTRY == op) + return SW_NOT_FOUND; + + if (VLAN_NEXT_ENTRY == op) + return SW_NO_MORE; + } + + return SW_OK; +} + +static sw_error_t +_horus_vlan_entry_append(a_uint32_t dev_id, const fal_vlan_t * vlan_entry) +{ + sw_error_t rv; + a_uint32_t reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + if ((vlan_entry->vid == 0) || (vlan_entry->vid > MAX_VLAN_ID)) + return SW_OUT_OF_RANGE; + + if (A_FALSE == hsl_mports_prop_check(dev_id, vlan_entry->mem_ports, HSL_PP_INCL_CPU)) + return SW_BAD_PARAM; + + rv = horus_vlan_sw_to_hw(vlan_entry, reg); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = horus_vlan_commit(dev_id, VLAN_LOAD_ENTRY); + return rv; +} + +static sw_error_t +_horus_vlan_create(a_uint32_t dev_id, a_uint16_t vlan_id) +{ + sw_error_t rv; + a_uint32_t entry = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if ((vlan_id == 0) || (vlan_id > MAX_VLAN_ID)) + return SW_OUT_OF_RANGE; + + /* set default value for VLAN_TABLE_FUNC0, all 0 except vid */ + entry = 0; + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VLAN_ID, vlan_id, entry); + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + /* set default value for VLAN_TABLE_FUNC1, all 0 */ + entry = 0; + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC1, VT_VALID, 1, entry); + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = horus_vlan_commit(dev_id, VLAN_LOAD_ENTRY); + return rv; +} + +static sw_error_t +_horus_vlan_next(a_uint32_t dev_id, a_uint16_t vlan_id, fal_vlan_t * p_vlan) +{ + sw_error_t rv; + a_uint32_t reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (vlan_id > MAX_VLAN_ID) + return SW_OUT_OF_RANGE; + + aos_mem_zero(p_vlan, sizeof (fal_vlan_t)); + + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VLAN_ID, vlan_id, reg[0]); + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = horus_vlan_commit(dev_id, VLAN_NEXT_ENTRY); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + horus_vlan_hw_to_sw(reg, p_vlan); + + if (0 == p_vlan->vid) + return SW_NO_MORE; + else + return SW_OK; +} + +static sw_error_t +_horus_vlan_find(a_uint32_t dev_id, a_uint16_t vlan_id, fal_vlan_t * p_vlan) +{ + sw_error_t rv; + a_uint32_t reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + if ((vlan_id == 0) || (vlan_id > MAX_VLAN_ID)) + return SW_OUT_OF_RANGE; + + aos_mem_zero(p_vlan, sizeof (fal_vlan_t)); + + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VLAN_ID, vlan_id, reg[0]); + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + rv = horus_vlan_commit(dev_id, VLAN_FIND_ENTRY); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + horus_vlan_hw_to_sw(reg, p_vlan); + + return SW_OK; +} + +static sw_error_t +_horus_vlan_member_update(a_uint32_t dev_id, a_uint16_t vlan_id, + fal_pbmp_t member, fal_pbmp_t u_member) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if ((vlan_id == 0) || (vlan_id > MAX_VLAN_ID)) + return SW_OUT_OF_RANGE; + + if (A_FALSE == hsl_mports_prop_check(dev_id, member, HSL_PP_INCL_CPU)) + return SW_BAD_PARAM; + + if (u_member != 0) + return SW_BAD_PARAM; + + /* get vlan entry first */ + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VLAN_ID, vlan_id, reg); + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + rv = horus_vlan_commit(dev_id, VLAN_FIND_ENTRY); + SW_RTN_ON_ERROR(rv); + + /* set vlan member for VLAN_TABLE_FUNC1 */ + HSL_REG_FIELD_SET(rv, dev_id, VLAN_TABLE_FUNC1, 0, VID_MEM, + (a_uint8_t *) (&member), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = horus_vlan_commit(dev_id, VLAN_LOAD_ENTRY); + /* when update port member through LOAD opration, hardware will + return VT_FULL_VIO, we should ignore it */ + if (SW_FULL == rv) + rv = SW_OK; + + return rv; +} + +static sw_error_t +_horus_vlan_delete(a_uint32_t dev_id, a_uint16_t vlan_id) +{ + sw_error_t rv; + a_uint32_t reg; + + HSL_DEV_ID_CHECK(dev_id); + + if ((vlan_id == 0) || (vlan_id > MAX_VLAN_ID)) + return SW_OUT_OF_RANGE; + + reg = (a_int32_t) vlan_id; + HSL_REG_FIELD_SET(rv, dev_id, VLAN_TABLE_FUNC0, 0, VLAN_ID, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = horus_vlan_commit(dev_id, VLAN_PURGE_ENTRY); + return rv; +} + +/** + * @brief Append a vlan entry on paticular device. + * @param[in] dev_id device id + * @param[in] vlan_entry vlan entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_vlan_entry_append(a_uint32_t dev_id, const fal_vlan_t * vlan_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_vlan_entry_append(dev_id, vlan_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Creat a vlan entry through vlan id on a paticular device. + * @details Comments: + * After this operation the member ports of the created vlan entry are null. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_vlan_create(a_uint32_t dev_id, a_uint32_t vlan_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_vlan_create(dev_id, vlan_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Next a vlan entry through vlan id on a paticular device. + * @details Comments: + * If the value of vid is zero this operation will get the first entry. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[out] p_vlan vlan entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_vlan_next(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_vlan_next(dev_id, vlan_id, p_vlan); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Find a vlan entry through vlan id on paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[out] p_vlan vlan entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_vlan_find(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_vlan_find(dev_id, vlan_id, p_vlan); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Update a vlan entry member port through vlan id on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[in] member member ports + * @param[in] u_member tagged or untagged infomation for member ports + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_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; + + HSL_API_LOCK; + rv = _horus_vlan_member_update(dev_id, vlan_id, member, u_member); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a vlan entry through vlan id on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +horus_vlan_delete(a_uint32_t dev_id, a_uint32_t vlan_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _horus_vlan_delete(dev_id, vlan_id); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +horus_vlan_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->vlan_entry_append = horus_vlan_entry_append; + p_api->vlan_creat = horus_vlan_create; + p_api->vlan_member_update = horus_vlan_member_update; + p_api->vlan_delete = horus_vlan_delete; + p_api->vlan_next = horus_vlan_next; + p_api->vlan_find = horus_vlan_find; + +#endif + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/Makefile b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/Makefile new file mode 100755 index 000000000..453b55dcd --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/Makefile @@ -0,0 +1,110 @@ +LOC_DIR=src/hsl/hppe +LIB=HSL + +include $(PRJ_PATH)/make/config.mk + +SRC_LIST=hppe_init.c hppe_reg_access.c hppe_global.c + +ifeq (TRUE, $(IN_FLOW)) + SRC_LIST+=hppe_flow.c +endif + +ifeq (TRUE, $(IN_IP)) + SRC_LIST+=hppe_ip.c +endif + +ifeq (TRUE, $(IN_QOS)) + SRC_LIST+=hppe_qos.c +endif + +ifeq (TRUE, $(IN_FDB)) + SRC_LIST+=hppe_fdb.c +endif + +ifeq (TRUE, $(IN_PORTVLAN)) + SRC_LIST+=hppe_portvlan.c +endif + +ifeq (TRUE, $(IN_STP)) + SRC_LIST+=hppe_stp.c +endif + +ifeq (TRUE, $(IN_QM)) + SRC_LIST+=hppe_qm.c +endif + +ifeq (TRUE, $(IN_VSI)) + SRC_LIST+=hppe_vsi.c +endif + +ifeq (TRUE, $(IN_SEC)) + SRC_LIST+=hppe_sec.c +endif + +ifeq (TRUE, $(IN_BM)) + SRC_LIST+=hppe_bm.c +endif + +ifeq (TRUE, $(IN_MIB)) + SRC_LIST+=hppe_mib.c hppe_xgmacmib.c +endif + +ifeq (TRUE, $(IN_SERVCODE)) + SRC_LIST+=hppe_servcode.c +endif + +ifeq (TRUE, $(IN_CTRLPKT)) + SRC_LIST+=hppe_ctrlpkt.c +endif + +ifeq (TRUE, $(IN_RSS_HASH)) + SRC_LIST+=hppe_rss.c +endif + +ifeq (TRUE, $(IN_PPPOE)) + SRC_LIST+=hppe_pppoe.c +endif + +ifeq (TRUE, $(IN_PORTCONTROL)) + SRC_LIST+=hppe_portctrl.c hppe_xgportctrl.c +endif + +ifeq (TRUE, $(IN_MIRROR)) + SRC_LIST+=hppe_mirror.c +endif + +ifeq (TRUE, $(IN_TRUNK)) + SRC_LIST+=hppe_trunk.c +endif + +ifeq (TRUE, $(IN_ACL)) + SRC_LIST+=hppe_acl.c +endif + +ifeq (TRUE, $(IN_POLICER)) + SRC_LIST+=hppe_policer.c +endif + +ifeq (TRUE, $(IN_SHAPER)) + SRC_LIST+=hppe_shaper.c +endif + +ifeq (TRUE, $(IN_UNIPHY)) + SRC_LIST+=hppe_uniphy.c +endif + +ifeq (, $(findstring HPPE, $(SUPPORT_CHIP))) + SRC_LIST= +ifneq (, $(filter MP, $(SUPPORT_CHIP))) + SRC_LIST=hppe_reg_access.c +ifeq (TRUE, $(IN_UNIPHY)) + SRC_LIST+=hppe_uniphy.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 diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_acl.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_acl.c new file mode 100755 index 000000000..6df9253c9 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_acl.c @@ -0,0 +1,3164 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hppe_reg_access.h" +#include "hppe_acl_reg.h" +#include "hppe_acl.h" + +sw_error_t +hppe_non_ip_udf0_ctrl_reg_get( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value) +{ + return hppe_reg_get( + dev_id, + IPR_CSR_BASE_ADDR + NON_IP_UDF0_CTRL_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_non_ip_udf0_ctrl_reg_set( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPR_CSR_BASE_ADDR + NON_IP_UDF0_CTRL_REG_ADDRESS, + value->val); +} + +sw_error_t +hppe_non_ip_udf1_ctrl_reg_get( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value) +{ + return hppe_reg_get( + dev_id, + IPR_CSR_BASE_ADDR + NON_IP_UDF1_CTRL_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_non_ip_udf1_ctrl_reg_set( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPR_CSR_BASE_ADDR + NON_IP_UDF1_CTRL_REG_ADDRESS, + value->val); +} + +sw_error_t +hppe_non_ip_udf2_ctrl_reg_get( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value) +{ + return hppe_reg_get( + dev_id, + IPR_CSR_BASE_ADDR + NON_IP_UDF2_CTRL_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_non_ip_udf2_ctrl_reg_set( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPR_CSR_BASE_ADDR + NON_IP_UDF2_CTRL_REG_ADDRESS, + value->val); +} + +sw_error_t +hppe_non_ip_udf3_ctrl_reg_get( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value) +{ + return hppe_reg_get( + dev_id, + IPR_CSR_BASE_ADDR + NON_IP_UDF3_CTRL_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_non_ip_udf3_ctrl_reg_set( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPR_CSR_BASE_ADDR + NON_IP_UDF3_CTRL_REG_ADDRESS, + value->val); +} + +sw_error_t +hppe_ipv4_udf0_ctrl_reg_get( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value) +{ + return hppe_reg_get( + dev_id, + IPR_CSR_BASE_ADDR + IPV4_UDF0_CTRL_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_ipv4_udf0_ctrl_reg_set( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPR_CSR_BASE_ADDR + IPV4_UDF0_CTRL_REG_ADDRESS, + value->val); +} + +sw_error_t +hppe_ipv4_udf1_ctrl_reg_get( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value) +{ + return hppe_reg_get( + dev_id, + IPR_CSR_BASE_ADDR + IPV4_UDF1_CTRL_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_ipv4_udf1_ctrl_reg_set( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPR_CSR_BASE_ADDR + IPV4_UDF1_CTRL_REG_ADDRESS, + value->val); +} + +sw_error_t +hppe_ipv4_udf2_ctrl_reg_get( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value) +{ + return hppe_reg_get( + dev_id, + IPR_CSR_BASE_ADDR + IPV4_UDF2_CTRL_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_ipv4_udf2_ctrl_reg_set( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPR_CSR_BASE_ADDR + IPV4_UDF2_CTRL_REG_ADDRESS, + value->val); +} + +sw_error_t +hppe_ipv4_udf3_ctrl_reg_get( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value) +{ + return hppe_reg_get( + dev_id, + IPR_CSR_BASE_ADDR + IPV4_UDF3_CTRL_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_ipv4_udf3_ctrl_reg_set( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPR_CSR_BASE_ADDR + IPV4_UDF3_CTRL_REG_ADDRESS, + value->val); +} + +sw_error_t +hppe_ipv6_udf0_ctrl_reg_get( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value) +{ + return hppe_reg_get( + dev_id, + IPR_CSR_BASE_ADDR + IPV6_UDF0_CTRL_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_ipv6_udf0_ctrl_reg_set( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPR_CSR_BASE_ADDR + IPV6_UDF0_CTRL_REG_ADDRESS, + value->val); +} + +sw_error_t +hppe_ipv6_udf1_ctrl_reg_get( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value) +{ + return hppe_reg_get( + dev_id, + IPR_CSR_BASE_ADDR + IPV6_UDF1_CTRL_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_ipv6_udf1_ctrl_reg_set( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPR_CSR_BASE_ADDR + IPV6_UDF1_CTRL_REG_ADDRESS, + value->val); +} + +sw_error_t +hppe_ipv6_udf2_ctrl_reg_get( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value) +{ + return hppe_reg_get( + dev_id, + IPR_CSR_BASE_ADDR + IPV6_UDF2_CTRL_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_ipv6_udf2_ctrl_reg_set( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPR_CSR_BASE_ADDR + IPV6_UDF2_CTRL_REG_ADDRESS, + value->val); +} + +sw_error_t +hppe_ipv6_udf3_ctrl_reg_get( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value) +{ + return hppe_reg_get( + dev_id, + IPR_CSR_BASE_ADDR + IPV6_UDF3_CTRL_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_ipv6_udf3_ctrl_reg_set( + a_uint32_t dev_id, + union udf_ctrl_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPR_CSR_BASE_ADDR + IPV6_UDF3_CTRL_REG_ADDRESS, + value->val); +} + +sw_error_t +hppe_non_ip_udf0_ctrl_reg_udf0_base_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_non_ip_udf0_ctrl_reg_get(dev_id, ®_val); + *value = reg_val.bf.udf_base; + return ret; +} + +sw_error_t +hppe_non_ip_udf0_ctrl_reg_udf0_base_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_non_ip_udf0_ctrl_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udf_base = value; + ret = hppe_non_ip_udf0_ctrl_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_non_ip_udf0_ctrl_reg_udf0_offset_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_non_ip_udf0_ctrl_reg_get(dev_id, ®_val); + *value = reg_val.bf.udf_offset; + return ret; +} + +sw_error_t +hppe_non_ip_udf0_ctrl_reg_udf0_offset_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_non_ip_udf0_ctrl_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udf_offset = value; + ret = hppe_non_ip_udf0_ctrl_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_non_ip_udf1_ctrl_reg_udf1_base_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_non_ip_udf1_ctrl_reg_get(dev_id, ®_val); + *value = reg_val.bf.udf_base; + return ret; +} + +sw_error_t +hppe_non_ip_udf1_ctrl_reg_udf1_base_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_non_ip_udf1_ctrl_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udf_base = value; + ret = hppe_non_ip_udf1_ctrl_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_non_ip_udf1_ctrl_reg_udf1_offset_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_non_ip_udf1_ctrl_reg_get(dev_id, ®_val); + *value = reg_val.bf.udf_offset; + return ret; +} + +sw_error_t +hppe_non_ip_udf1_ctrl_reg_udf1_offset_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_non_ip_udf1_ctrl_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udf_offset = value; + ret = hppe_non_ip_udf1_ctrl_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_non_ip_udf2_ctrl_reg_udf2_offset_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_non_ip_udf2_ctrl_reg_get(dev_id, ®_val); + *value = reg_val.bf.udf_offset; + return ret; +} + +sw_error_t +hppe_non_ip_udf2_ctrl_reg_udf2_offset_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_non_ip_udf2_ctrl_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udf_offset = value; + ret = hppe_non_ip_udf2_ctrl_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_non_ip_udf2_ctrl_reg_udf2_base_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_non_ip_udf2_ctrl_reg_get(dev_id, ®_val); + *value = reg_val.bf.udf_base; + return ret; +} + +sw_error_t +hppe_non_ip_udf2_ctrl_reg_udf2_base_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_non_ip_udf2_ctrl_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udf_base = value; + ret = hppe_non_ip_udf2_ctrl_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_non_ip_udf3_ctrl_reg_udf3_base_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_non_ip_udf3_ctrl_reg_get(dev_id, ®_val); + *value = reg_val.bf.udf_base; + return ret; +} + +sw_error_t +hppe_non_ip_udf3_ctrl_reg_udf3_base_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_non_ip_udf3_ctrl_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udf_base = value; + ret = hppe_non_ip_udf3_ctrl_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_non_ip_udf3_ctrl_reg_udf3_offset_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_non_ip_udf3_ctrl_reg_get(dev_id, ®_val); + *value = reg_val.bf.udf_offset; + return ret; +} + +sw_error_t +hppe_non_ip_udf3_ctrl_reg_udf3_offset_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_non_ip_udf3_ctrl_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udf_offset = value; + ret = hppe_non_ip_udf3_ctrl_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_ipv4_udf0_ctrl_reg_udf0_base_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipv4_udf0_ctrl_reg_get(dev_id, ®_val); + *value = reg_val.bf.udf_base; + return ret; +} + +sw_error_t +hppe_ipv4_udf0_ctrl_reg_udf0_base_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipv4_udf0_ctrl_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udf_base = value; + ret = hppe_ipv4_udf0_ctrl_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_ipv4_udf0_ctrl_reg_udf0_offset_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipv4_udf0_ctrl_reg_get(dev_id, ®_val); + *value = reg_val.bf.udf_offset; + return ret; +} + +sw_error_t +hppe_ipv4_udf0_ctrl_reg_udf0_offset_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipv4_udf0_ctrl_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udf_offset = value; + ret = hppe_ipv4_udf0_ctrl_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_ipv4_udf1_ctrl_reg_udf1_base_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipv4_udf1_ctrl_reg_get(dev_id, ®_val); + *value = reg_val.bf.udf_base; + return ret; +} + +sw_error_t +hppe_ipv4_udf1_ctrl_reg_udf1_base_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipv4_udf1_ctrl_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udf_base = value; + ret = hppe_ipv4_udf1_ctrl_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_ipv4_udf1_ctrl_reg_udf1_offset_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipv4_udf1_ctrl_reg_get(dev_id, ®_val); + *value = reg_val.bf.udf_offset; + return ret; +} + +sw_error_t +hppe_ipv4_udf1_ctrl_reg_udf1_offset_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipv4_udf1_ctrl_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udf_offset = value; + ret = hppe_ipv4_udf1_ctrl_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_ipv4_udf2_ctrl_reg_udf2_offset_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipv4_udf2_ctrl_reg_get(dev_id, ®_val); + *value = reg_val.bf.udf_offset; + return ret; +} + +sw_error_t +hppe_ipv4_udf2_ctrl_reg_udf2_offset_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipv4_udf2_ctrl_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udf_offset = value; + ret = hppe_ipv4_udf2_ctrl_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_ipv4_udf2_ctrl_reg_udf2_base_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipv4_udf2_ctrl_reg_get(dev_id, ®_val); + *value = reg_val.bf.udf_base; + return ret; +} + +sw_error_t +hppe_ipv4_udf2_ctrl_reg_udf2_base_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipv4_udf2_ctrl_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udf_base = value; + ret = hppe_ipv4_udf2_ctrl_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_ipv4_udf3_ctrl_reg_udf3_base_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipv4_udf3_ctrl_reg_get(dev_id, ®_val); + *value = reg_val.bf.udf_base; + return ret; +} + +sw_error_t +hppe_ipv4_udf3_ctrl_reg_udf3_base_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipv4_udf3_ctrl_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udf_base = value; + ret = hppe_ipv4_udf3_ctrl_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_ipv4_udf3_ctrl_reg_udf3_offset_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipv4_udf3_ctrl_reg_get(dev_id, ®_val); + *value = reg_val.bf.udf_offset; + return ret; +} + +sw_error_t +hppe_ipv4_udf3_ctrl_reg_udf3_offset_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipv4_udf3_ctrl_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udf_offset = value; + ret = hppe_ipv4_udf3_ctrl_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_ipv6_udf0_ctrl_reg_udf0_base_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipv6_udf0_ctrl_reg_get(dev_id, ®_val); + *value = reg_val.bf.udf_base; + return ret; +} + +sw_error_t +hppe_ipv6_udf0_ctrl_reg_udf0_base_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipv6_udf0_ctrl_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udf_base = value; + ret = hppe_ipv6_udf0_ctrl_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_ipv6_udf0_ctrl_reg_udf0_offset_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipv6_udf0_ctrl_reg_get(dev_id, ®_val); + *value = reg_val.bf.udf_offset; + return ret; +} + +sw_error_t +hppe_ipv6_udf0_ctrl_reg_udf0_offset_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipv6_udf0_ctrl_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udf_offset = value; + ret = hppe_ipv6_udf0_ctrl_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_ipv6_udf1_ctrl_reg_udf1_base_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipv6_udf1_ctrl_reg_get(dev_id, ®_val); + *value = reg_val.bf.udf_base; + return ret; +} + +sw_error_t +hppe_ipv6_udf1_ctrl_reg_udf1_base_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipv6_udf1_ctrl_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udf_base = value; + ret = hppe_ipv6_udf1_ctrl_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_ipv6_udf1_ctrl_reg_udf1_offset_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipv6_udf1_ctrl_reg_get(dev_id, ®_val); + *value = reg_val.bf.udf_offset; + return ret; +} + +sw_error_t +hppe_ipv6_udf1_ctrl_reg_udf1_offset_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipv6_udf1_ctrl_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udf_offset = value; + ret = hppe_ipv6_udf1_ctrl_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_ipv6_udf2_ctrl_reg_udf2_offset_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipv6_udf2_ctrl_reg_get(dev_id, ®_val); + *value = reg_val.bf.udf_offset; + return ret; +} + +sw_error_t +hppe_ipv6_udf2_ctrl_reg_udf2_offset_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipv6_udf2_ctrl_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udf_offset = value; + ret = hppe_ipv6_udf2_ctrl_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_ipv6_udf2_ctrl_reg_udf2_base_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipv6_udf2_ctrl_reg_get(dev_id, ®_val); + *value = reg_val.bf.udf_base; + return ret; +} + +sw_error_t +hppe_ipv6_udf2_ctrl_reg_udf2_base_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipv6_udf2_ctrl_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udf_base = value; + ret = hppe_ipv6_udf2_ctrl_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_ipv6_udf3_ctrl_reg_udf3_base_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipv6_udf3_ctrl_reg_get(dev_id, ®_val); + *value = reg_val.bf.udf_base; + return ret; +} + +sw_error_t +hppe_ipv6_udf3_ctrl_reg_udf3_base_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipv6_udf3_ctrl_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udf_base = value; + ret = hppe_ipv6_udf3_ctrl_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_ipv6_udf3_ctrl_reg_udf3_offset_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipv6_udf3_ctrl_reg_get(dev_id, ®_val); + *value = reg_val.bf.udf_offset; + return ret; +} + +sw_error_t +hppe_ipv6_udf3_ctrl_reg_udf3_offset_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union udf_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipv6_udf3_ctrl_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udf_offset = value; + ret = hppe_ipv6_udf3_ctrl_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_rule_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + union ipo_rule_reg_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + IPO_CSR_BASE_ADDR + IPO_RULE_REG_ADDRESS + \ + index * IPO_RULE_REG_INC, + value->val, + 3); +} + +sw_error_t +hppe_ipo_rule_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + union ipo_rule_reg_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + IPO_CSR_BASE_ADDR + IPO_RULE_REG_ADDRESS + \ + index * IPO_RULE_REG_INC, + value->val, + 3); +} + +sw_error_t +hppe_ipo_mask_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + union ipo_mask_reg_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + IPO_CSR_BASE_ADDR + IPO_MASK_REG_ADDRESS + \ + index * IPO_MASK_REG_INC, + value->val, + 2); +} + +sw_error_t +hppe_ipo_mask_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + union ipo_mask_reg_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + IPO_CSR_BASE_ADDR + IPO_MASK_REG_ADDRESS + \ + index * IPO_MASK_REG_INC, + value->val, + 2); +} + +sw_error_t +hppe_rule_ext_1_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + union rule_ext_1_reg_u *value) +{ + if (index >= RULE_EXT_1_REG_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPO_CSR_BASE_ADDR + RULE_EXT_1_REG_ADDRESS + \ + index * RULE_EXT_1_REG_INC, + &value->val); +} + +sw_error_t +hppe_rule_ext_1_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + union rule_ext_1_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPO_CSR_BASE_ADDR + RULE_EXT_1_REG_ADDRESS + \ + index * RULE_EXT_1_REG_INC, + value->val); +} + +sw_error_t +hppe_rule_ext_2_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + union rule_ext_2_reg_u *value) +{ + if (index >= RULE_EXT_2_REG_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPO_CSR_BASE_ADDR + RULE_EXT_2_REG_ADDRESS + \ + index * RULE_EXT_2_REG_INC, + &value->val); +} + +sw_error_t +hppe_rule_ext_2_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + union rule_ext_2_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPO_CSR_BASE_ADDR + RULE_EXT_2_REG_ADDRESS + \ + index * RULE_EXT_2_REG_INC, + value->val); +} + +sw_error_t +hppe_rule_ext_4_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + union rule_ext_4_reg_u *value) +{ + if (index >= RULE_EXT_4_REG_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPO_CSR_BASE_ADDR + RULE_EXT_4_REG_ADDRESS + \ + index * RULE_EXT_4_REG_INC, + &value->val); +} + +sw_error_t +hppe_rule_ext_4_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + union rule_ext_4_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPO_CSR_BASE_ADDR + RULE_EXT_4_REG_ADDRESS + \ + index * RULE_EXT_4_REG_INC, + value->val); +} + +sw_error_t +hppe_ipo_dbg_addr_reg_get( + a_uint32_t dev_id, + union ipo_dbg_addr_reg_u *value) +{ + return hppe_reg_get( + dev_id, + IPO_CSR_BASE_ADDR + IPO_DBG_ADDR_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_ipo_dbg_addr_reg_set( + a_uint32_t dev_id, + union ipo_dbg_addr_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPO_CSR_BASE_ADDR + IPO_DBG_ADDR_REG_ADDRESS, + value->val); +} + +sw_error_t +hppe_ipo_dbg_data_reg_get( + a_uint32_t dev_id, + union ipo_dbg_data_reg_u *value) +{ + return hppe_reg_get( + dev_id, + IPO_CSR_BASE_ADDR + IPO_DBG_DATA_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_ipo_dbg_data_reg_set( + a_uint32_t dev_id, + union ipo_dbg_data_reg_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_ipo_spare_reg_reg_get( + a_uint32_t dev_id, + union ipo_spare_reg_reg_u *value) +{ + return hppe_reg_get( + dev_id, + IPO_CSR_BASE_ADDR + IPO_SPARE_REG_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_ipo_spare_reg_reg_set( + a_uint32_t dev_id, + union ipo_spare_reg_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPO_CSR_BASE_ADDR + IPO_SPARE_REG_REG_ADDRESS, + value->val); +} + +sw_error_t +hppe_ipo_glb_hit_counter_reg_get( + a_uint32_t dev_id, + union ipo_glb_hit_counter_reg_u *value) +{ + return hppe_reg_get( + dev_id, + IPO_CSR_BASE_ADDR + IPO_GLB_HIT_COUNTER_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_ipo_glb_hit_counter_reg_set( + a_uint32_t dev_id, + union ipo_glb_hit_counter_reg_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_ipo_glb_miss_counter_reg_get( + a_uint32_t dev_id, + union ipo_glb_miss_counter_reg_u *value) +{ + return hppe_reg_get( + dev_id, + IPO_CSR_BASE_ADDR + IPO_GLB_MISS_COUNTER_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_ipo_glb_miss_counter_reg_set( + a_uint32_t dev_id, + union ipo_glb_miss_counter_reg_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_ipo_glb_bypass_counter_reg_get( + a_uint32_t dev_id, + union ipo_glb_bypass_counter_reg_u *value) +{ + return hppe_reg_get( + dev_id, + IPO_CSR_BASE_ADDR + IPO_GLB_BYPASS_COUNTER_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_ipo_glb_bypass_counter_reg_set( + a_uint32_t dev_id, + union ipo_glb_bypass_counter_reg_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_ipo_rule_reg_src_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_rule_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_rule_reg_get(dev_id, index, ®_val); + *value = reg_val.bf.src_1 << 3 | \ + reg_val.bf.src_0; + return ret; +} + +sw_error_t +hppe_ipo_rule_reg_src_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_rule_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_rule_reg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.src_1 = value >> 3; + reg_val.bf.src_0 = value & (((a_uint64_t)1<<3)-1); + ret = hppe_ipo_rule_reg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_rule_reg_inverse_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_rule_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_rule_reg_get(dev_id, index, ®_val); + *value = reg_val.bf.inverse_en; + return ret; +} + +sw_error_t +hppe_ipo_rule_reg_inverse_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_rule_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_rule_reg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.inverse_en = value; + ret = hppe_ipo_rule_reg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_rule_reg_rule_type_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_rule_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_rule_reg_get(dev_id, index, ®_val); + *value = reg_val.bf.rule_type; + return ret; +} + +sw_error_t +hppe_ipo_rule_reg_rule_type_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_rule_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_rule_reg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rule_type = value; + ret = hppe_ipo_rule_reg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_rule_reg_src_type_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_rule_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_rule_reg_get(dev_id, index, ®_val); + *value = reg_val.bf.src_type; + return ret; +} + +sw_error_t +hppe_ipo_rule_reg_src_type_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_rule_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_rule_reg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.src_type = value; + ret = hppe_ipo_rule_reg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_rule_reg_range_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_rule_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_rule_reg_get(dev_id, index, ®_val); + *value = reg_val.bf.range_en; + return ret; +} + +sw_error_t +hppe_ipo_rule_reg_range_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_rule_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_rule_reg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.range_en = value; + ret = hppe_ipo_rule_reg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_rule_reg_post_routing_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_rule_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_rule_reg_get(dev_id, index, ®_val); + *value = reg_val.bf.post_routing_en; + return ret; +} + +sw_error_t +hppe_ipo_rule_reg_post_routing_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_rule_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_rule_reg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.post_routing_en = value; + ret = hppe_ipo_rule_reg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_rule_reg_fake_mac_header_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_rule_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_rule_reg_get(dev_id, index, ®_val); + *value = reg_val.bf.fake_mac_header; + return ret; +} + +sw_error_t +hppe_ipo_rule_reg_fake_mac_header_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_rule_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_rule_reg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.fake_mac_header = value; + ret = hppe_ipo_rule_reg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_rule_reg_res_chain_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_rule_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_rule_reg_get(dev_id, index, ®_val); + *value = reg_val.bf.res_chain; + return ret; +} + +sw_error_t +hppe_ipo_rule_reg_res_chain_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_rule_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_rule_reg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.res_chain = value; + ret = hppe_ipo_rule_reg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_rule_reg_pri_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_rule_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_rule_reg_get(dev_id, index, ®_val); + *value = reg_val.bf.pri; + return ret; +} + +sw_error_t +hppe_ipo_rule_reg_pri_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_rule_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_rule_reg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pri = value; + ret = hppe_ipo_rule_reg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_rule_reg_rule_field_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union ipo_rule_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_rule_reg_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.rule_field_1 << 32 | \ + reg_val.bf.rule_field_0; + return ret; +} + +sw_error_t +hppe_ipo_rule_reg_rule_field_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union ipo_rule_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_rule_reg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rule_field_1 = value >> 32; + reg_val.bf.rule_field_0 = value & (((a_uint64_t)1<<32)-1); + ret = hppe_ipo_rule_reg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_mask_reg_maskfield_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union ipo_mask_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_mask_reg_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.maskfield_1 << 32 | \ + reg_val.bf.maskfield_0; + return ret; +} + +sw_error_t +hppe_ipo_mask_reg_maskfield_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union ipo_mask_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_mask_reg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.maskfield_1 = value >> 32; + reg_val.bf.maskfield_0 = value & (((a_uint64_t)1<<32)-1); + ret = hppe_ipo_mask_reg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_rule_ext_1_reg_ext2_2_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rule_ext_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rule_ext_1_reg_get(dev_id, index, ®_val); + *value = reg_val.bf.ext2_2; + return ret; +} + +sw_error_t +hppe_rule_ext_1_reg_ext2_2_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union rule_ext_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rule_ext_1_reg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ext2_2 = value; + ret = hppe_rule_ext_1_reg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_rule_ext_1_reg_ext2_0_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rule_ext_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rule_ext_1_reg_get(dev_id, index, ®_val); + *value = reg_val.bf.ext2_0; + return ret; +} + +sw_error_t +hppe_rule_ext_1_reg_ext2_0_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union rule_ext_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rule_ext_1_reg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ext2_0 = value; + ret = hppe_rule_ext_1_reg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_rule_ext_1_reg_ext2_3_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rule_ext_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rule_ext_1_reg_get(dev_id, index, ®_val); + *value = reg_val.bf.ext2_3; + return ret; +} + +sw_error_t +hppe_rule_ext_1_reg_ext2_3_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union rule_ext_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rule_ext_1_reg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ext2_3 = value; + ret = hppe_rule_ext_1_reg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_rule_ext_1_reg_ext2_1_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rule_ext_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rule_ext_1_reg_get(dev_id, index, ®_val); + *value = reg_val.bf.ext2_1; + return ret; +} + +sw_error_t +hppe_rule_ext_1_reg_ext2_1_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union rule_ext_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rule_ext_1_reg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ext2_1 = value; + ret = hppe_rule_ext_1_reg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_rule_ext_2_reg_ext4_0_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rule_ext_2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rule_ext_2_reg_get(dev_id, index, ®_val); + *value = reg_val.bf.ext4_0; + return ret; +} + +sw_error_t +hppe_rule_ext_2_reg_ext4_0_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union rule_ext_2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rule_ext_2_reg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ext4_0 = value; + ret = hppe_rule_ext_2_reg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_rule_ext_2_reg_ext4_1_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rule_ext_2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rule_ext_2_reg_get(dev_id, index, ®_val); + *value = reg_val.bf.ext4_1; + return ret; +} + +sw_error_t +hppe_rule_ext_2_reg_ext4_1_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union rule_ext_2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rule_ext_2_reg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ext4_1 = value; + ret = hppe_rule_ext_2_reg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_rule_ext_4_reg_ext8_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rule_ext_4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rule_ext_4_reg_get(dev_id, index, ®_val); + *value = reg_val.bf.ext8; + return ret; +} + +sw_error_t +hppe_rule_ext_4_reg_ext8_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union rule_ext_4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rule_ext_4_reg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ext8 = value; + ret = hppe_rule_ext_4_reg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_dbg_addr_reg_ipo_dbg_addr_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union ipo_dbg_addr_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_dbg_addr_reg_get(dev_id, ®_val); + *value = reg_val.bf.ipo_dbg_addr; + return ret; +} + +sw_error_t +hppe_ipo_dbg_addr_reg_ipo_dbg_addr_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union ipo_dbg_addr_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_dbg_addr_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipo_dbg_addr = value; + ret = hppe_ipo_dbg_addr_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_dbg_data_reg_ipo_dbg_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union ipo_dbg_data_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_dbg_data_reg_get(dev_id, ®_val); + *value = reg_val.bf.ipo_dbg_data; + return ret; +} + +sw_error_t +hppe_ipo_dbg_data_reg_ipo_dbg_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_ipo_spare_reg_reg_spare_reg_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union ipo_spare_reg_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_spare_reg_reg_get(dev_id, ®_val); + *value = reg_val.bf.spare_reg; + return ret; +} + +sw_error_t +hppe_ipo_spare_reg_reg_spare_reg_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union ipo_spare_reg_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_spare_reg_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.spare_reg = value; + ret = hppe_ipo_spare_reg_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_glb_hit_counter_reg_hit_count_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union ipo_glb_hit_counter_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_glb_hit_counter_reg_get(dev_id, ®_val); + *value = reg_val.bf.hit_count; + return ret; +} + +sw_error_t +hppe_ipo_glb_hit_counter_reg_hit_count_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_ipo_glb_miss_counter_reg_miss_count_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union ipo_glb_miss_counter_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_glb_miss_counter_reg_get(dev_id, ®_val); + *value = reg_val.bf.miss_count; + return ret; +} + +sw_error_t +hppe_ipo_glb_miss_counter_reg_miss_count_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_ipo_glb_bypass_counter_reg_bypass_count_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union ipo_glb_bypass_counter_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_glb_bypass_counter_reg_get(dev_id, ®_val); + *value = reg_val.bf.bypass_count; + return ret; +} + +sw_error_t +hppe_ipo_glb_bypass_counter_reg_bypass_count_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + + +sw_error_t +hppe_ipo_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union ipo_cnt_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + INGRESS_POLICER_BASE_ADDR + IPO_CNT_TBL_ADDRESS + \ + index * IPO_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_ipo_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union ipo_cnt_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + INGRESS_POLICER_BASE_ADDR + IPO_CNT_TBL_ADDRESS + \ + index * IPO_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_ipo_cnt_tbl_hit_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union ipo_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_cnt_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.hit_byte_cnt_1 << 32 | \ + reg_val.bf.hit_byte_cnt_0; + return ret; +} + +sw_error_t +hppe_ipo_cnt_tbl_hit_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union ipo_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.hit_byte_cnt_1 = value >> 32; + reg_val.bf.hit_byte_cnt_0 = value & (((a_uint64_t)1<<32)-1); + ret = hppe_ipo_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_cnt_tbl_hit_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_cnt_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.hit_pkt_cnt; + return ret; +} + +sw_error_t +hppe_ipo_cnt_tbl_hit_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.hit_pkt_cnt = value; + ret = hppe_ipo_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + + +sw_error_t +hppe_ipo_action_get( + a_uint32_t dev_id, + a_uint32_t index, + union ipo_action_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + IPE_L2_BASE_ADDR + IPO_ACTION_ADDRESS + \ + index * IPO_ACTION_INC, + value->val, + 5); +} + +sw_error_t +hppe_ipo_action_set( + a_uint32_t dev_id, + a_uint32_t index, + union ipo_action_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + IPE_L2_BASE_ADDR + IPO_ACTION_ADDRESS + \ + index * IPO_ACTION_INC, + value->val, + 5); +} + +sw_error_t +hppe_ipo_action_mirror_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.mirror_en; + return ret; +} + +sw_error_t +hppe_ipo_action_mirror_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mirror_en = value; + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_action_ctag_pcp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.ctag_pcp_1 << 2 | \ + reg_val.bf.ctag_pcp_0; + return ret; +} + +sw_error_t +hppe_ipo_action_ctag_pcp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ctag_pcp_1 = value >> 2; + reg_val.bf.ctag_pcp_0 = value & (((a_uint64_t)1<<2)-1); + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_action_int_dp_change_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.int_dp_change_en; + return ret; +} + +sw_error_t +hppe_ipo_action_int_dp_change_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.int_dp_change_en = value; + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_action_enqueue_pri_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.enqueue_pri; + return ret; +} + +sw_error_t +hppe_ipo_action_enqueue_pri_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.enqueue_pri = value; + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_action_stag_pcp_change_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.stag_pcp_change_en; + return ret; +} + +sw_error_t +hppe_ipo_action_stag_pcp_change_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.stag_pcp_change_en = value; + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_action_dscp_tc_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.dscp_tc; + return ret; +} + +sw_error_t +hppe_ipo_action_dscp_tc_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.dscp_tc = value; + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_action_cpu_code_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.cpu_code_en; + return ret; +} + +sw_error_t +hppe_ipo_action_cpu_code_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cpu_code_en = value; + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_action_stag_dei_change_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.stag_dei_change_en; + return ret; +} + +sw_error_t +hppe_ipo_action_stag_dei_change_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.stag_dei_change_en = value; + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_action_ctag_fmt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.ctag_fmt; + return ret; +} + +sw_error_t +hppe_ipo_action_ctag_fmt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ctag_fmt = value; + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_action_dest_info_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.dest_info; + return ret; +} + +sw_error_t +hppe_ipo_action_dest_info_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.dest_info = value; + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_action_svid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.svid; + return ret; +} + +sw_error_t +hppe_ipo_action_svid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.svid = value; + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_action_dest_info_change_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.dest_info_change_en; + return ret; +} + +sw_error_t +hppe_ipo_action_dest_info_change_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.dest_info_change_en = value; + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_action_policer_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.policer_en; + return ret; +} + +sw_error_t +hppe_ipo_action_policer_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.policer_en = value; + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_action_int_dp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.int_dp; + return ret; +} + +sw_error_t +hppe_ipo_action_int_dp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.int_dp = value; + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_action_ctag_pcp_change_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.ctag_pcp_change_en; + return ret; +} + +sw_error_t +hppe_ipo_action_ctag_pcp_change_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ctag_pcp_change_en = value; + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_action_metadata_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.metadata_en; + return ret; +} + +sw_error_t +hppe_ipo_action_metadata_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.metadata_en = value; + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_action_enqueue_pri_change_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.enqueue_pri_change_en; + return ret; +} + +sw_error_t +hppe_ipo_action_enqueue_pri_change_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.enqueue_pri_change_en = value; + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_action_stag_dei_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.stag_dei; + return ret; +} + +sw_error_t +hppe_ipo_action_stag_dei_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.stag_dei = value; + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_action_fwd_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.fwd_cmd; + return ret; +} + +sw_error_t +hppe_ipo_action_fwd_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.fwd_cmd = value; + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_action_bypass_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.bypass_bitmap_1 << 14 | \ + reg_val.bf.bypass_bitmap_0; + return ret; +} + +sw_error_t +hppe_ipo_action_bypass_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.bypass_bitmap_1 = value >> 14; + reg_val.bf.bypass_bitmap_0 = value & (((a_uint64_t)1<<14)-1); + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_action_ctag_dei_change_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.ctag_dei_change_en; + return ret; +} + +sw_error_t +hppe_ipo_action_ctag_dei_change_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ctag_dei_change_en = value; + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_action_policer_index_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.policer_index; + return ret; +} + +sw_error_t +hppe_ipo_action_policer_index_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.policer_index = value; + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_action_ctag_dei_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.ctag_dei; + return ret; +} + +sw_error_t +hppe_ipo_action_ctag_dei_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ctag_dei = value; + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_action_stag_pcp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.stag_pcp; + return ret; +} + +sw_error_t +hppe_ipo_action_stag_pcp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.stag_pcp = value; + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_action_syn_toggle_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.syn_toggle; + return ret; +} + +sw_error_t +hppe_ipo_action_syn_toggle_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.syn_toggle = value; + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_action_service_code_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.service_code_en; + return ret; +} + +sw_error_t +hppe_ipo_action_service_code_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.service_code_en = value; + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_action_qid_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.qid_en; + return ret; +} + +sw_error_t +hppe_ipo_action_qid_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.qid_en = value; + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_action_service_code_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.service_code_1 << 1 | \ + reg_val.bf.service_code_0; + return ret; +} + +sw_error_t +hppe_ipo_action_service_code_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.service_code_1 = value >> 1; + reg_val.bf.service_code_0 = value & (((a_uint64_t)1<<1)-1); + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_action_cvid_change_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.cvid_change_en; + return ret; +} + +sw_error_t +hppe_ipo_action_cvid_change_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cvid_change_en = value; + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_action_cvid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.cvid; + return ret; +} + +sw_error_t +hppe_ipo_action_cvid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cvid = value; + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_action_svid_change_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.svid_change_en; + return ret; +} + +sw_error_t +hppe_ipo_action_svid_change_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.svid_change_en = value; + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_action_cpu_code_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.cpu_code; + return ret; +} + +sw_error_t +hppe_ipo_action_cpu_code_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cpu_code = value; + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_action_dscp_tc_change_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.dscp_tc_change_en; + return ret; +} + +sw_error_t +hppe_ipo_action_dscp_tc_change_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.dscp_tc_change_en = value; + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_action_qid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.qid; + return ret; +} + +sw_error_t +hppe_ipo_action_qid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.qid = value; + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipo_action_stag_fmt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + *value = reg_val.bf.stag_fmt; + return ret; +} + +sw_error_t +hppe_ipo_action_stag_fmt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipo_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipo_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.stag_fmt = value; + ret = hppe_ipo_action_set(dev_id, index, ®_val); + return ret; +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_bm.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_bm.c new file mode 100755 index 000000000..989275f77 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_bm.c @@ -0,0 +1,3027 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hppe_reg_access.h" +#include "hppe_bm_reg.h" +#include "hppe_bm.h" + +#ifndef IN_BM_MINI +sw_error_t +hppe_fb_fifo_cfg_get( + a_uint32_t dev_id, + union fb_fifo_cfg_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_BM_CSR_BASE_ADDR + FB_FIFO_CFG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_fb_fifo_cfg_set( + a_uint32_t dev_id, + union fb_fifo_cfg_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_BM_CSR_BASE_ADDR + FB_FIFO_CFG_ADDRESS, + value->val); +} + +sw_error_t +hppe_fp_fifo_cfg_get( + a_uint32_t dev_id, + union fp_fifo_cfg_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_BM_CSR_BASE_ADDR + FP_FIFO_CFG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_fp_fifo_cfg_set( + a_uint32_t dev_id, + union fp_fifo_cfg_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_BM_CSR_BASE_ADDR + FP_FIFO_CFG_ADDRESS, + value->val); +} + +sw_error_t +hppe_deq_fifo_cfg_get( + a_uint32_t dev_id, + a_uint32_t index, + union deq_fifo_cfg_u *value) +{ + if (index >= DEQ_FIFO_CFG_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_BM_CSR_BASE_ADDR + DEQ_FIFO_CFG_ADDRESS + \ + index * DEQ_FIFO_CFG_INC, + &value->val); +} + +sw_error_t +hppe_deq_fifo_cfg_set( + a_uint32_t dev_id, + a_uint32_t index, + union deq_fifo_cfg_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_BM_CSR_BASE_ADDR + DEQ_FIFO_CFG_ADDRESS + \ + index * DEQ_FIFO_CFG_INC, + value->val); +} + +sw_error_t +hppe_tick_dly_cfg_get( + a_uint32_t dev_id, + union tick_dly_cfg_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_BM_CSR_BASE_ADDR + TICK_DLY_CFG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_tick_dly_cfg_set( + a_uint32_t dev_id, + union tick_dly_cfg_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_BM_CSR_BASE_ADDR + TICK_DLY_CFG_ADDRESS, + value->val); +} + +sw_error_t +hppe_bm_rsv_0_get( + a_uint32_t dev_id, + union bm_rsv_0_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_BM_CSR_BASE_ADDR + BM_RSV_0_ADDRESS, + &value->val); +} + +sw_error_t +hppe_bm_rsv_0_set( + a_uint32_t dev_id, + union bm_rsv_0_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_BM_CSR_BASE_ADDR + BM_RSV_0_ADDRESS, + value->val); +} + +sw_error_t +hppe_bm_rsv_1_get( + a_uint32_t dev_id, + union bm_rsv_1_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_BM_CSR_BASE_ADDR + BM_RSV_1_ADDRESS, + &value->val); +} + +sw_error_t +hppe_bm_rsv_1_set( + a_uint32_t dev_id, + union bm_rsv_1_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_BM_CSR_BASE_ADDR + BM_RSV_1_ADDRESS, + value->val); +} + +sw_error_t +hppe_bm_dbg_addr_get( + a_uint32_t dev_id, + union bm_dbg_addr_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_BM_CSR_BASE_ADDR + BM_DBG_ADDR_ADDRESS, + &value->val); +} + +sw_error_t +hppe_bm_dbg_addr_set( + a_uint32_t dev_id, + union bm_dbg_addr_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_BM_CSR_BASE_ADDR + BM_DBG_ADDR_ADDRESS, + value->val); +} + +sw_error_t +hppe_bm_dbg_data_get( + a_uint32_t dev_id, + union bm_dbg_data_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_BM_CSR_BASE_ADDR + BM_DBG_DATA_ADDRESS, + &value->val); +} + +sw_error_t +hppe_bm_dbg_data_set( + a_uint32_t dev_id, + union bm_dbg_data_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_port_fc_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_fc_mode_u *value) +{ + if (index >= PORT_FC_MODE_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_BM_CSR_BASE_ADDR + PORT_FC_MODE_ADDRESS + \ + index * PORT_FC_MODE_INC, + &value->val); +} +#endif + +sw_error_t +hppe_port_fc_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_fc_mode_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_BM_CSR_BASE_ADDR + PORT_FC_MODE_ADDRESS + \ + index * PORT_FC_MODE_INC, + value->val); +} + +#ifndef IN_BM_MINI +sw_error_t +hppe_port_fc_status_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_fc_status_u *value) +{ + if (index >= PORT_FC_STATUS_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_BM_CSR_BASE_ADDR + PORT_FC_STATUS_ADDRESS + \ + index * PORT_FC_STATUS_INC, + &value->val); +} + +sw_error_t +hppe_port_fc_status_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_fc_status_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_port_group_id_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_group_id_u *value) +{ + if (index >= PORT_GROUP_ID_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_BM_CSR_BASE_ADDR + PORT_GROUP_ID_ADDRESS + \ + index * PORT_GROUP_ID_INC, + &value->val); +} +#endif + +sw_error_t +hppe_port_group_id_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_group_id_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_BM_CSR_BASE_ADDR + PORT_GROUP_ID_ADDRESS + \ + index * PORT_GROUP_ID_INC, + value->val); +} + +#ifndef IN_BM_MINI +sw_error_t +hppe_port_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_cnt_u *value) +{ + if (index >= PORT_CNT_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_BM_CSR_BASE_ADDR + PORT_CNT_ADDRESS + \ + index * PORT_CNT_INC, + &value->val); +} + +sw_error_t +hppe_port_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_cnt_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_port_reacted_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_reacted_cnt_u *value) +{ + if (index >= PORT_REACTED_CNT_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_BM_CSR_BASE_ADDR + PORT_REACTED_CNT_ADDRESS + \ + index * PORT_REACTED_CNT_INC, + &value->val); +} + +sw_error_t +hppe_port_reacted_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_reacted_cnt_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_shared_group_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + union shared_group_cnt_u *value) +{ + if (index >= SHARED_GROUP_CNT_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_BM_CSR_BASE_ADDR + SHARED_GROUP_CNT_ADDRESS + \ + index * SHARED_GROUP_CNT_INC, + &value->val); +} + +sw_error_t +hppe_shared_group_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + union shared_group_cnt_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_shared_group_cfg_get( + a_uint32_t dev_id, + a_uint32_t index, + union shared_group_cfg_u *value) +{ + if (index >= SHARED_GROUP_CFG_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_BM_CSR_BASE_ADDR + SHARED_GROUP_CFG_ADDRESS + \ + index * SHARED_GROUP_CFG_INC, + &value->val); +} +#endif + +sw_error_t +hppe_shared_group_cfg_set( + a_uint32_t dev_id, + a_uint32_t index, + union shared_group_cfg_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_BM_CSR_BASE_ADDR + SHARED_GROUP_CFG_ADDRESS + \ + index * SHARED_GROUP_CFG_INC, + value->val); +} + +#ifndef IN_BM_MINI +sw_error_t +hppe_port_profile_cnt_en_get( + a_uint32_t dev_id, + union port_profile_cnt_en_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_BM_CSR_BASE_ADDR + PORT_PROFILE_CNT_EN_ADDRESS, + &value->val); +} + +sw_error_t +hppe_port_profile_cnt_en_set( + a_uint32_t dev_id, + union port_profile_cnt_en_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_BM_CSR_BASE_ADDR + PORT_PROFILE_CNT_EN_ADDRESS, + value->val); +} + +sw_error_t +hppe_grp_profile_cnt_en_get( + a_uint32_t dev_id, + union grp_profile_cnt_en_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_BM_CSR_BASE_ADDR + GRP_PROFILE_CNT_EN_ADDRESS, + &value->val); +} + +sw_error_t +hppe_grp_profile_cnt_en_set( + a_uint32_t dev_id, + union grp_profile_cnt_en_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_BM_CSR_BASE_ADDR + GRP_PROFILE_CNT_EN_ADDRESS, + value->val); +} + +sw_error_t +hppe_port_profile_th_cfg_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_profile_th_cfg_u *value) +{ + if (index >= PORT_PROFILE_TH_CFG_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_BM_CSR_BASE_ADDR + PORT_PROFILE_TH_CFG_ADDRESS + \ + index * PORT_PROFILE_TH_CFG_INC, + &value->val); +} + +sw_error_t +hppe_port_profile_th_cfg_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_profile_th_cfg_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_BM_CSR_BASE_ADDR + PORT_PROFILE_TH_CFG_ADDRESS + \ + index * PORT_PROFILE_TH_CFG_INC, + value->val); +} + +sw_error_t +hppe_react_profile_th_cfg_get( + a_uint32_t dev_id, + a_uint32_t index, + union react_profile_th_cfg_u *value) +{ + if (index >= REACT_PROFILE_TH_CFG_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_BM_CSR_BASE_ADDR + REACT_PROFILE_TH_CFG_ADDRESS + \ + index * REACT_PROFILE_TH_CFG_INC, + &value->val); +} + +sw_error_t +hppe_react_profile_th_cfg_set( + a_uint32_t dev_id, + a_uint32_t index, + union react_profile_th_cfg_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_BM_CSR_BASE_ADDR + REACT_PROFILE_TH_CFG_ADDRESS + \ + index * REACT_PROFILE_TH_CFG_INC, + value->val); +} + +sw_error_t +hppe_grp_profile_th_cfg_get( + a_uint32_t dev_id, + a_uint32_t index, + union grp_profile_th_cfg_u *value) +{ + if (index >= GRP_PROFILE_TH_CFG_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_BM_CSR_BASE_ADDR + GRP_PROFILE_TH_CFG_ADDRESS + \ + index * GRP_PROFILE_TH_CFG_INC, + &value->val); +} + +sw_error_t +hppe_grp_profile_th_cfg_set( + a_uint32_t dev_id, + a_uint32_t index, + union grp_profile_th_cfg_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_BM_CSR_BASE_ADDR + GRP_PROFILE_TH_CFG_ADDRESS + \ + index * GRP_PROFILE_TH_CFG_INC, + value->val); +} + +sw_error_t +hppe_tot_react_profile_th_cfg_get( + a_uint32_t dev_id, + union tot_react_profile_th_cfg_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_BM_CSR_BASE_ADDR + TOT_REACT_PROFILE_TH_CFG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_tot_react_profile_th_cfg_set( + a_uint32_t dev_id, + union tot_react_profile_th_cfg_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_BM_CSR_BASE_ADDR + TOT_REACT_PROFILE_TH_CFG_ADDRESS, + value->val); +} + +sw_error_t +hppe_port_out_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_out_profile_cnt_u *value) +{ + if (index >= PORT_OUT_PROFILE_CNT_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_BM_CSR_BASE_ADDR + PORT_OUT_PROFILE_CNT_ADDRESS + \ + index * PORT_OUT_PROFILE_CNT_INC, + &value->val); +} + +sw_error_t +hppe_port_out_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_out_profile_cnt_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_BM_CSR_BASE_ADDR + PORT_OUT_PROFILE_CNT_ADDRESS + \ + index * PORT_OUT_PROFILE_CNT_INC, + value->val); +} + +sw_error_t +hppe_port_in_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_in_profile_cnt_u *value) +{ + if (index >= PORT_IN_PROFILE_CNT_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_BM_CSR_BASE_ADDR + PORT_IN_PROFILE_CNT_ADDRESS + \ + index * PORT_IN_PROFILE_CNT_INC, + &value->val); +} + +sw_error_t +hppe_port_in_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_in_profile_cnt_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_BM_CSR_BASE_ADDR + PORT_IN_PROFILE_CNT_ADDRESS + \ + index * PORT_IN_PROFILE_CNT_INC, + value->val); +} + +sw_error_t +hppe_react_out_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + union react_out_profile_cnt_u *value) +{ + if (index >= REACT_OUT_PROFILE_CNT_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_BM_CSR_BASE_ADDR + REACT_OUT_PROFILE_CNT_ADDRESS + \ + index * REACT_OUT_PROFILE_CNT_INC, + &value->val); +} + +sw_error_t +hppe_react_out_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + union react_out_profile_cnt_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_BM_CSR_BASE_ADDR + REACT_OUT_PROFILE_CNT_ADDRESS + \ + index * REACT_OUT_PROFILE_CNT_INC, + value->val); +} + +sw_error_t +hppe_react_in_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + union react_in_profile_cnt_u *value) +{ + if (index >= REACT_IN_PROFILE_CNT_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_BM_CSR_BASE_ADDR + REACT_IN_PROFILE_CNT_ADDRESS + \ + index * REACT_IN_PROFILE_CNT_INC, + &value->val); +} + +sw_error_t +hppe_react_in_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + union react_in_profile_cnt_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_BM_CSR_BASE_ADDR + REACT_IN_PROFILE_CNT_ADDRESS + \ + index * REACT_IN_PROFILE_CNT_INC, + value->val); +} + +sw_error_t +hppe_grp_out_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + union grp_out_profile_cnt_u *value) +{ + if (index >= GRP_OUT_PROFILE_CNT_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_BM_CSR_BASE_ADDR + GRP_OUT_PROFILE_CNT_ADDRESS + \ + index * GRP_OUT_PROFILE_CNT_INC, + &value->val); +} + +sw_error_t +hppe_grp_out_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + union grp_out_profile_cnt_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_BM_CSR_BASE_ADDR + GRP_OUT_PROFILE_CNT_ADDRESS + \ + index * GRP_OUT_PROFILE_CNT_INC, + value->val); +} + +sw_error_t +hppe_grp_in_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + union grp_in_profile_cnt_u *value) +{ + if (index >= GRP_IN_PROFILE_CNT_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_BM_CSR_BASE_ADDR + GRP_IN_PROFILE_CNT_ADDRESS + \ + index * GRP_IN_PROFILE_CNT_INC, + &value->val); +} + +sw_error_t +hppe_grp_in_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + union grp_in_profile_cnt_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_BM_CSR_BASE_ADDR + GRP_IN_PROFILE_CNT_ADDRESS + \ + index * GRP_IN_PROFILE_CNT_INC, + value->val); +} + +sw_error_t +hppe_tot_react_out_profile_cnt_get( + a_uint32_t dev_id, + union tot_react_out_profile_cnt_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_BM_CSR_BASE_ADDR + TOT_REACT_OUT_PROFILE_CNT_ADDRESS, + &value->val); +} + +sw_error_t +hppe_tot_react_out_profile_cnt_set( + a_uint32_t dev_id, + union tot_react_out_profile_cnt_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_BM_CSR_BASE_ADDR + TOT_REACT_OUT_PROFILE_CNT_ADDRESS, + value->val); +} + +sw_error_t +hppe_tot_react_in_profile_cnt_get( + a_uint32_t dev_id, + union tot_react_in_profile_cnt_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_BM_CSR_BASE_ADDR + TOT_REACT_IN_PROFILE_CNT_ADDRESS, + &value->val); +} + +sw_error_t +hppe_tot_react_in_profile_cnt_set( + a_uint32_t dev_id, + union tot_react_in_profile_cnt_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_BM_CSR_BASE_ADDR + TOT_REACT_IN_PROFILE_CNT_ADDRESS, + value->val); +} +#endif + +sw_error_t +hppe_port_fc_cfg_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_fc_cfg_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + NSS_BM_CSR_BASE_ADDR + PORT_FC_CFG_ADDRESS + \ + index * PORT_FC_CFG_INC, + value->val, + 2); +} + +sw_error_t +hppe_port_fc_cfg_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_fc_cfg_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + NSS_BM_CSR_BASE_ADDR + PORT_FC_CFG_ADDRESS + \ + index * PORT_FC_CFG_INC, + value->val, + 2); +} + +#ifndef IN_BM_MINI +sw_error_t +hppe_llm_get( + a_uint32_t dev_id, + a_uint32_t index, + union llm_u *value) +{ + if (index >= LLM_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_BM_CSR_BASE_ADDR + LLM_ADDRESS + \ + index * LLM_INC, + &value->val); +} + +sw_error_t +hppe_llm_set( + a_uint32_t dev_id, + a_uint32_t index, + union llm_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_BM_CSR_BASE_ADDR + LLM_ADDRESS + \ + index * LLM_INC, + value->val); +} + +sw_error_t +hppe_rcm_get( + a_uint32_t dev_id, + a_uint32_t index, + union rcm_u *value) +{ + if (index >= RCM_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_BM_CSR_BASE_ADDR + RCM_ADDRESS + \ + index * RCM_INC, + &value->val); +} + +sw_error_t +hppe_rcm_set( + a_uint32_t dev_id, + a_uint32_t index, + union rcm_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_BM_CSR_BASE_ADDR + RCM_ADDRESS + \ + index * RCM_INC, + value->val); +} + +sw_error_t +hppe_dm_get( + a_uint32_t dev_id, + a_uint32_t index, + union dm_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + NSS_BM_CSR_BASE_ADDR + DM_ADDRESS + \ + index * DM_INC, + value->val, + 16); +} + +sw_error_t +hppe_dm_set( + a_uint32_t dev_id, + a_uint32_t index, + union dm_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + NSS_BM_CSR_BASE_ADDR + DM_ADDRESS + \ + index * DM_INC, + value->val, + 16); +} + +sw_error_t +hppe_fb_fifo_cfg_fb_fifo_thres_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union fb_fifo_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fb_fifo_cfg_get(dev_id, ®_val); + *value = reg_val.bf.fb_fifo_thres; + return ret; +} + +sw_error_t +hppe_fb_fifo_cfg_fb_fifo_thres_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union fb_fifo_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fb_fifo_cfg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.fb_fifo_thres = value; + ret = hppe_fb_fifo_cfg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_fp_fifo_cfg_fp_fifo_thres_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union fp_fifo_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fp_fifo_cfg_get(dev_id, ®_val); + *value = reg_val.bf.fp_fifo_thres; + return ret; +} + +sw_error_t +hppe_fp_fifo_cfg_fp_fifo_thres_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union fp_fifo_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fp_fifo_cfg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.fp_fifo_thres = value; + ret = hppe_fp_fifo_cfg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_deq_fifo_cfg_deq_fifo_thres_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union deq_fifo_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_deq_fifo_cfg_get(dev_id, index, ®_val); + *value = reg_val.bf.deq_fifo_thres; + return ret; +} + +sw_error_t +hppe_deq_fifo_cfg_deq_fifo_thres_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union deq_fifo_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_deq_fifo_cfg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.deq_fifo_thres = value; + ret = hppe_deq_fifo_cfg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_tick_dly_cfg_tick_dly_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union tick_dly_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tick_dly_cfg_get(dev_id, ®_val); + *value = reg_val.bf.tick_dly; + return ret; +} + +sw_error_t +hppe_tick_dly_cfg_tick_dly_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union tick_dly_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tick_dly_cfg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tick_dly = value; + ret = hppe_tick_dly_cfg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_bm_rsv_0_rsv_0_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union bm_rsv_0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_bm_rsv_0_get(dev_id, ®_val); + *value = reg_val.bf.rsv_0; + return ret; +} + +sw_error_t +hppe_bm_rsv_0_rsv_0_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union bm_rsv_0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_bm_rsv_0_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rsv_0 = value; + ret = hppe_bm_rsv_0_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_bm_rsv_1_rsv_1_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union bm_rsv_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_bm_rsv_1_get(dev_id, ®_val); + *value = reg_val.bf.rsv_1; + return ret; +} + +sw_error_t +hppe_bm_rsv_1_rsv_1_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union bm_rsv_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_bm_rsv_1_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rsv_1 = value; + ret = hppe_bm_rsv_1_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_bm_dbg_addr_dbg_addr_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union bm_dbg_addr_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_bm_dbg_addr_get(dev_id, ®_val); + *value = reg_val.bf.dbg_addr; + return ret; +} + +sw_error_t +hppe_bm_dbg_addr_dbg_addr_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union bm_dbg_addr_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_bm_dbg_addr_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.dbg_addr = value; + ret = hppe_bm_dbg_addr_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_bm_dbg_data_dbg_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union bm_dbg_data_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_bm_dbg_data_get(dev_id, ®_val); + *value = reg_val.bf.dbg_data; + return ret; +} + +sw_error_t +hppe_bm_dbg_data_dbg_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_port_fc_mode_fc_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_fc_mode_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_fc_mode_get(dev_id, index, ®_val); + *value = reg_val.bf.fc_en; + return ret; +} + +sw_error_t +hppe_port_fc_mode_fc_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_fc_mode_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_fc_mode_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.fc_en = value; + ret = hppe_port_fc_mode_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_fc_status_port_fc_status_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_fc_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_fc_status_get(dev_id, index, ®_val); + *value = reg_val.bf.port_fc_status; + return ret; +} + +sw_error_t +hppe_port_fc_status_port_fc_status_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_port_fc_status_port_xon_th_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_fc_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_fc_status_get(dev_id, index, ®_val); + *value = reg_val.bf.port_xon_th; + return ret; +} + +sw_error_t +hppe_port_fc_status_port_xon_th_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_port_group_id_port_shared_group_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_group_id_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_group_id_get(dev_id, index, ®_val); + *value = reg_val.bf.port_shared_group_id; + return ret; +} + +sw_error_t +hppe_port_group_id_port_shared_group_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_group_id_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_group_id_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_shared_group_id = value; + ret = hppe_port_group_id_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_cnt_port_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_cnt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_cnt_get(dev_id, index, ®_val); + *value = reg_val.bf.port_cnt; + return ret; +} + +sw_error_t +hppe_port_cnt_port_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_port_reacted_cnt_port_reacted_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_reacted_cnt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_reacted_cnt_get(dev_id, index, ®_val); + *value = reg_val.bf.port_reacted_cnt; + return ret; +} + +sw_error_t +hppe_port_reacted_cnt_port_reacted_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_shared_group_cnt_shared_group_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union shared_group_cnt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_shared_group_cnt_get(dev_id, index, ®_val); + *value = reg_val.bf.shared_group_cnt; + return ret; +} + +sw_error_t +hppe_shared_group_cnt_shared_group_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_shared_group_cfg_shared_group_limit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union shared_group_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_shared_group_cfg_get(dev_id, index, ®_val); + *value = reg_val.bf.shared_group_limit; + return ret; +} + +sw_error_t +hppe_shared_group_cfg_shared_group_limit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union shared_group_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_shared_group_cfg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.shared_group_limit = value; + ret = hppe_shared_group_cfg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_8_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.react_cnt_en_8; + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_8_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.react_cnt_en_8 = value; + ret = hppe_port_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_7_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.react_cnt_en_7; + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_7_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.react_cnt_en_7 = value; + ret = hppe_port_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_6_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.port_cnt_en_6; + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_6_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_cnt_en_6 = value; + ret = hppe_port_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_2_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.react_cnt_en_2; + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_2_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.react_cnt_en_2 = value; + ret = hppe_port_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_8_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.port_cnt_en_8; + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_8_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_cnt_en_8 = value; + ret = hppe_port_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_5_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.port_cnt_en_5; + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_5_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_cnt_en_5 = value; + ret = hppe_port_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_12_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.port_cnt_en_12; + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_12_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_cnt_en_12 = value; + ret = hppe_port_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_4_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.react_cnt_en_4; + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_4_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.react_cnt_en_4 = value; + ret = hppe_port_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_3_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.port_cnt_en_3; + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_3_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_cnt_en_3 = value; + ret = hppe_port_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_10_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.port_cnt_en_10; + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_10_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_cnt_en_10 = value; + ret = hppe_port_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_4_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.port_cnt_en_4; + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_4_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_cnt_en_4 = value; + ret = hppe_port_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_5_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.react_cnt_en_5; + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_5_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.react_cnt_en_5 = value; + ret = hppe_port_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_14_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.port_cnt_en_14; + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_14_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_cnt_en_14 = value; + ret = hppe_port_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_14_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.react_cnt_en_14; + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_14_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.react_cnt_en_14 = value; + ret = hppe_port_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_3_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.react_cnt_en_3; + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_3_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.react_cnt_en_3 = value; + ret = hppe_port_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_1_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.port_cnt_en_1; + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_1_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_cnt_en_1 = value; + ret = hppe_port_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_0_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.port_cnt_en_0; + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_0_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_cnt_en_0 = value; + ret = hppe_port_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_7_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.port_cnt_en_7; + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_7_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_cnt_en_7 = value; + ret = hppe_port_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_13_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.port_cnt_en_13; + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_13_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_cnt_en_13 = value; + ret = hppe_port_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_6_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.react_cnt_en_6; + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_6_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.react_cnt_en_6 = value; + ret = hppe_port_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_0_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.react_cnt_en_0; + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_0_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.react_cnt_en_0 = value; + ret = hppe_port_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_13_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.react_cnt_en_13; + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_13_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.react_cnt_en_13 = value; + ret = hppe_port_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_11_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.port_cnt_en_11; + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_11_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_cnt_en_11 = value; + ret = hppe_port_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_1_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.react_cnt_en_1; + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_1_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.react_cnt_en_1 = value; + ret = hppe_port_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_12_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.react_cnt_en_12; + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_12_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.react_cnt_en_12 = value; + ret = hppe_port_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_11_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.react_cnt_en_11; + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_11_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.react_cnt_en_11 = value; + ret = hppe_port_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_10_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.react_cnt_en_10; + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_10_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.react_cnt_en_10 = value; + ret = hppe_port_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_9_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.port_cnt_en_9; + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_9_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_cnt_en_9 = value; + ret = hppe_port_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_2_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.port_cnt_en_2; + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_port_cnt_en_2_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_cnt_en_2 = value; + ret = hppe_port_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_9_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.react_cnt_en_9; + return ret; +} + +sw_error_t +hppe_port_profile_cnt_en_react_cnt_en_9_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.react_cnt_en_9 = value; + ret = hppe_port_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_grp_profile_cnt_en_grp_cnt_en_3_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union grp_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_grp_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.grp_cnt_en_3; + return ret; +} + +sw_error_t +hppe_grp_profile_cnt_en_grp_cnt_en_3_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union grp_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_grp_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.grp_cnt_en_3 = value; + ret = hppe_grp_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_grp_profile_cnt_en_tot_rect_cnt_en_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union grp_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_grp_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.tot_rect_cnt_en; + return ret; +} + +sw_error_t +hppe_grp_profile_cnt_en_tot_rect_cnt_en_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union grp_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_grp_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tot_rect_cnt_en = value; + ret = hppe_grp_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_grp_profile_cnt_en_grp_cnt_en_1_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union grp_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_grp_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.grp_cnt_en_1; + return ret; +} + +sw_error_t +hppe_grp_profile_cnt_en_grp_cnt_en_1_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union grp_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_grp_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.grp_cnt_en_1 = value; + ret = hppe_grp_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_grp_profile_cnt_en_grp_cnt_en_0_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union grp_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_grp_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.grp_cnt_en_0; + return ret; +} + +sw_error_t +hppe_grp_profile_cnt_en_grp_cnt_en_0_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union grp_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_grp_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.grp_cnt_en_0 = value; + ret = hppe_grp_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_grp_profile_cnt_en_grp_cnt_en_2_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union grp_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_grp_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.grp_cnt_en_2; + return ret; +} + +sw_error_t +hppe_grp_profile_cnt_en_grp_cnt_en_2_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union grp_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_grp_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.grp_cnt_en_2 = value; + ret = hppe_grp_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_profile_th_cfg_port_profile_th_cfg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_profile_th_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_th_cfg_get(dev_id, index, ®_val); + *value = reg_val.bf.port_profile_th_cfg; + return ret; +} + +sw_error_t +hppe_port_profile_th_cfg_port_profile_th_cfg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_profile_th_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_profile_th_cfg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_profile_th_cfg = value; + ret = hppe_port_profile_th_cfg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_react_profile_th_cfg_react_profile_th_cfg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union react_profile_th_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_react_profile_th_cfg_get(dev_id, index, ®_val); + *value = reg_val.bf.react_profile_th_cfg; + return ret; +} + +sw_error_t +hppe_react_profile_th_cfg_react_profile_th_cfg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union react_profile_th_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_react_profile_th_cfg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.react_profile_th_cfg = value; + ret = hppe_react_profile_th_cfg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_grp_profile_th_cfg_grp_profile_th_cfg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union grp_profile_th_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_grp_profile_th_cfg_get(dev_id, index, ®_val); + *value = reg_val.bf.grp_profile_th_cfg; + return ret; +} + +sw_error_t +hppe_grp_profile_th_cfg_grp_profile_th_cfg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union grp_profile_th_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_grp_profile_th_cfg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.grp_profile_th_cfg = value; + ret = hppe_grp_profile_th_cfg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_tot_react_profile_th_cfg_tot_react_profile_th_cfg_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union tot_react_profile_th_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tot_react_profile_th_cfg_get(dev_id, ®_val); + *value = reg_val.bf.tot_react_profile_th_cfg; + return ret; +} + +sw_error_t +hppe_tot_react_profile_th_cfg_tot_react_profile_th_cfg_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union tot_react_profile_th_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tot_react_profile_th_cfg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tot_react_profile_th_cfg = value; + ret = hppe_tot_react_profile_th_cfg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_out_profile_cnt_port_out_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_out_profile_cnt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_out_profile_cnt_get(dev_id, index, ®_val); + *value = reg_val.bf.port_out_profile_cnt; + return ret; +} + +sw_error_t +hppe_port_out_profile_cnt_port_out_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_out_profile_cnt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_out_profile_cnt_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_out_profile_cnt = value; + ret = hppe_port_out_profile_cnt_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_in_profile_cnt_port_in_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_in_profile_cnt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_in_profile_cnt_get(dev_id, index, ®_val); + *value = reg_val.bf.port_in_profile_cnt; + return ret; +} + +sw_error_t +hppe_port_in_profile_cnt_port_in_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_in_profile_cnt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_in_profile_cnt_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_in_profile_cnt = value; + ret = hppe_port_in_profile_cnt_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_react_out_profile_cnt_react_out_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union react_out_profile_cnt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_react_out_profile_cnt_get(dev_id, index, ®_val); + *value = reg_val.bf.react_out_profile_cnt; + return ret; +} + +sw_error_t +hppe_react_out_profile_cnt_react_out_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union react_out_profile_cnt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_react_out_profile_cnt_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.react_out_profile_cnt = value; + ret = hppe_react_out_profile_cnt_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_react_in_profile_cnt_react_in_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union react_in_profile_cnt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_react_in_profile_cnt_get(dev_id, index, ®_val); + *value = reg_val.bf.react_in_profile_cnt; + return ret; +} + +sw_error_t +hppe_react_in_profile_cnt_react_in_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union react_in_profile_cnt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_react_in_profile_cnt_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.react_in_profile_cnt = value; + ret = hppe_react_in_profile_cnt_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_grp_out_profile_cnt_grp_out_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union grp_out_profile_cnt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_grp_out_profile_cnt_get(dev_id, index, ®_val); + *value = reg_val.bf.grp_out_profile_cnt; + return ret; +} + +sw_error_t +hppe_grp_out_profile_cnt_grp_out_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union grp_out_profile_cnt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_grp_out_profile_cnt_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.grp_out_profile_cnt = value; + ret = hppe_grp_out_profile_cnt_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_grp_in_profile_cnt_grp_in_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union grp_in_profile_cnt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_grp_in_profile_cnt_get(dev_id, index, ®_val); + *value = reg_val.bf.grp_in_profile_cnt; + return ret; +} + +sw_error_t +hppe_grp_in_profile_cnt_grp_in_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union grp_in_profile_cnt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_grp_in_profile_cnt_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.grp_in_profile_cnt = value; + ret = hppe_grp_in_profile_cnt_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_tot_react_out_profile_cnt_tot_react_out_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union tot_react_out_profile_cnt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tot_react_out_profile_cnt_get(dev_id, ®_val); + *value = reg_val.bf.tot_react_out_profile_cnt; + return ret; +} + +sw_error_t +hppe_tot_react_out_profile_cnt_tot_react_out_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union tot_react_out_profile_cnt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tot_react_out_profile_cnt_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tot_react_out_profile_cnt = value; + ret = hppe_tot_react_out_profile_cnt_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_tot_react_in_profile_cnt_tot_react_in_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union tot_react_in_profile_cnt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tot_react_in_profile_cnt_get(dev_id, ®_val); + *value = reg_val.bf.tot_react_in_profile_cnt; + return ret; +} + +sw_error_t +hppe_tot_react_in_profile_cnt_tot_react_in_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union tot_react_in_profile_cnt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tot_react_in_profile_cnt_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tot_react_in_profile_cnt = value; + ret = hppe_tot_react_in_profile_cnt_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_fc_cfg_port_pre_alloc_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_fc_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_fc_cfg_get(dev_id, index, ®_val); + *value = reg_val.bf.port_pre_alloc; + return ret; +} + +sw_error_t +hppe_port_fc_cfg_port_pre_alloc_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_fc_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_fc_cfg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_pre_alloc = value; + ret = hppe_port_fc_cfg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_fc_cfg_port_resume_offset_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_fc_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_fc_cfg_get(dev_id, index, ®_val); + *value = reg_val.bf.port_resume_offset; + return ret; +} + +sw_error_t +hppe_port_fc_cfg_port_resume_offset_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_fc_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_fc_cfg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_resume_offset = value; + ret = hppe_port_fc_cfg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_fc_cfg_port_shared_dynamic_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_fc_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_fc_cfg_get(dev_id, index, ®_val); + *value = reg_val.bf.port_shared_dynamic; + return ret; +} + +sw_error_t +hppe_port_fc_cfg_port_shared_dynamic_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_fc_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_fc_cfg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_shared_dynamic = value; + ret = hppe_port_fc_cfg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_fc_cfg_port_shared_weight_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_fc_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_fc_cfg_get(dev_id, index, ®_val); + *value = reg_val.bf.port_shared_weight; + return ret; +} + +sw_error_t +hppe_port_fc_cfg_port_shared_weight_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_fc_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_fc_cfg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_shared_weight = value; + ret = hppe_port_fc_cfg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_fc_cfg_port_resume_floor_th_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_fc_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_fc_cfg_get(dev_id, index, ®_val); + *value = reg_val.bf.port_resume_floor_th; + return ret; +} + +sw_error_t +hppe_port_fc_cfg_port_resume_floor_th_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_fc_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_fc_cfg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_resume_floor_th = value; + ret = hppe_port_fc_cfg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_fc_cfg_port_react_limit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_fc_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_fc_cfg_get(dev_id, index, ®_val); + *value = reg_val.bf.port_react_limit; + return ret; +} + +sw_error_t +hppe_port_fc_cfg_port_react_limit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_fc_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_fc_cfg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_react_limit = value; + ret = hppe_port_fc_cfg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_fc_cfg_port_shared_ceiling_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_fc_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_fc_cfg_get(dev_id, index, ®_val); + *value = reg_val.bf.port_shared_ceiling_1 << 3 | \ + reg_val.bf.port_shared_ceiling_0; + return ret; +} + +sw_error_t +hppe_port_fc_cfg_port_shared_ceiling_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_fc_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_fc_cfg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_shared_ceiling_1 = value >> 3; + reg_val.bf.port_shared_ceiling_0 = value & (((a_uint64_t)1<<3)-1); + ret = hppe_port_fc_cfg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_llm_eop_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union llm_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_llm_get(dev_id, index, ®_val); + *value = reg_val.bf.eop; + return ret; +} + +sw_error_t +hppe_llm_eop_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union llm_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_llm_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.eop = value; + ret = hppe_llm_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_llm_nxt_ptr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union llm_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_llm_get(dev_id, index, ®_val); + *value = reg_val.bf.nxt_ptr; + return ret; +} + +sw_error_t +hppe_llm_nxt_ptr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union llm_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_llm_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.nxt_ptr = value; + ret = hppe_llm_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_rcm_ref_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rcm_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rcm_get(dev_id, index, ®_val); + *value = reg_val.bf.ref_cnt; + return ret; +} + +sw_error_t +hppe_rcm_ref_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union rcm_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rcm_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ref_cnt = value; + ret = hppe_rcm_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_dm_pkt_data_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union dm_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_dm_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.pkt_data_1 << 32 | \ + reg_val.bf.pkt_data_0; + return ret; +} + +sw_error_t +hppe_dm_pkt_data_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union dm_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_dm_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pkt_data_1 = value >> 32; + reg_val.bf.pkt_data_0 = value & (((a_uint64_t)1<<32)-1); + ret = hppe_dm_set(dev_id, index, ®_val); + return ret; +} +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_ctrlpkt.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_ctrlpkt.c new file mode 100755 index 000000000..a3ff31440 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_ctrlpkt.c @@ -0,0 +1,581 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hppe_reg_access.h" +#include "hppe_ctrlpkt_reg.h" +#include "hppe_ctrlpkt.h" + +sw_error_t +hppe_ethertype_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union ethertype_ctrl_u *value) +{ + if (index >= ETHERTYPE_CTRL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + ETHERTYPE_CTRL_ADDRESS + \ + index * ETHERTYPE_CTRL_INC, + &value->val); +} + +sw_error_t +hppe_ethertype_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union ethertype_ctrl_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L2_BASE_ADDR + ETHERTYPE_CTRL_ADDRESS + \ + index * ETHERTYPE_CTRL_INC, + value->val); +} + +sw_error_t +hppe_app_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union app_ctrl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + IPE_L2_BASE_ADDR + APP_CTRL_ADDRESS + \ + index * APP_CTRL_INC, + value->val, + 3); +} + +sw_error_t +hppe_app_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union app_ctrl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + IPE_L2_BASE_ADDR + APP_CTRL_ADDRESS + \ + index * APP_CTRL_INC, + value->val, + 3); +} + +sw_error_t +hppe_ethertype_ctrl_ethertype_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ethertype_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ethertype_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.ethertype; + return ret; +} + +sw_error_t +hppe_ethertype_ctrl_ethertype_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ethertype_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ethertype_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ethertype = value; + ret = hppe_ethertype_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ethertype_ctrl_ethertype_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ethertype_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ethertype_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.ethertype_en; + return ret; +} + +sw_error_t +hppe_ethertype_ctrl_ethertype_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ethertype_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ethertype_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ethertype_en = value; + ret = hppe_ethertype_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_app_ctrl_portbitmap_include_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union app_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_app_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.portbitmap_include; + return ret; +} + +sw_error_t +hppe_app_ctrl_portbitmap_include_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union app_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_app_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.portbitmap_include = value; + ret = hppe_app_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_app_ctrl_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union app_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_app_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.cmd; + return ret; +} + +sw_error_t +hppe_app_ctrl_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union app_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_app_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmd = value; + ret = hppe_app_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_app_ctrl_portbitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union app_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_app_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.portbitmap; + return ret; +} + +sw_error_t +hppe_app_ctrl_portbitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union app_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_app_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.portbitmap = value; + ret = hppe_app_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_app_ctrl_rfdb_index_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union app_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_app_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.rfdb_index_bitmap_1 << 30 | \ + reg_val.bf.rfdb_index_bitmap_0; + return ret; +} + +sw_error_t +hppe_app_ctrl_rfdb_index_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union app_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_app_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rfdb_index_bitmap_1 = value >> 30; + reg_val.bf.rfdb_index_bitmap_0 = value & (((a_uint64_t)1<<30)-1); + ret = hppe_app_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_app_ctrl_protocol_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union app_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_app_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.protocol_bitmap; + return ret; +} + +sw_error_t +hppe_app_ctrl_protocol_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union app_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_app_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.protocol_bitmap = value; + ret = hppe_app_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_app_ctrl_in_stg_byp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union app_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_app_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.in_stg_byp; + return ret; +} + +sw_error_t +hppe_app_ctrl_in_stg_byp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union app_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_app_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.in_stg_byp = value; + ret = hppe_app_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_app_ctrl_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union app_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_app_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.valid; + return ret; +} + +sw_error_t +hppe_app_ctrl_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union app_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_app_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.valid = value; + ret = hppe_app_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_app_ctrl_l2_sec_byp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union app_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_app_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.l2_sec_byp; + return ret; +} + +sw_error_t +hppe_app_ctrl_l2_sec_byp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union app_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_app_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l2_sec_byp = value; + ret = hppe_app_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_app_ctrl_protocol_include_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union app_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_app_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.protocol_include; + return ret; +} + +sw_error_t +hppe_app_ctrl_protocol_include_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union app_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_app_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.protocol_include = value; + ret = hppe_app_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_app_ctrl_ethertype_include_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union app_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_app_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.ethertype_include; + return ret; +} + +sw_error_t +hppe_app_ctrl_ethertype_include_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union app_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_app_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ethertype_include = value; + ret = hppe_app_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_app_ctrl_sg_byp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union app_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_app_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.sg_byp; + return ret; +} + +sw_error_t +hppe_app_ctrl_sg_byp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union app_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_app_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.sg_byp = value; + ret = hppe_app_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_app_ctrl_rfdb_include_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union app_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_app_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.rfdb_include; + return ret; +} + +sw_error_t +hppe_app_ctrl_rfdb_include_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union app_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_app_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rfdb_include = value; + ret = hppe_app_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_app_ctrl_ethertype_index_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union app_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_app_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.ethertype_index_bitmap_1 << 2 | \ + reg_val.bf.ethertype_index_bitmap_0; + return ret; +} + +sw_error_t +hppe_app_ctrl_ethertype_index_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union app_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_app_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ethertype_index_bitmap_1 = value >> 2; + reg_val.bf.ethertype_index_bitmap_0 = value & (((a_uint64_t)1<<2)-1); + ret = hppe_app_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_app_ctrl_in_vlan_fltr_byp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union app_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_app_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.in_vlan_fltr_byp; + return ret; +} + +sw_error_t +hppe_app_ctrl_in_vlan_fltr_byp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union app_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_app_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.in_vlan_fltr_byp = value; + ret = hppe_app_ctrl_set(dev_id, index, ®_val); + return ret; +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_fdb.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_fdb.c new file mode 100755 index 000000000..43481d071 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_fdb.c @@ -0,0 +1,2178 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hppe_reg_access.h" +#include "hppe_fdb_reg.h" +#include "hppe_fdb.h" +#ifndef IN_FDB_MINI +sw_error_t +hppe_l2_dbg_addr_get( + a_uint32_t dev_id, + union l2_dbg_addr_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + L2_DBG_ADDR_ADDRESS, + &value->val); +} + +sw_error_t +hppe_l2_dbg_addr_set( + a_uint32_t dev_id, + union l2_dbg_addr_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L2_BASE_ADDR + L2_DBG_ADDR_ADDRESS, + value->val); +} + +sw_error_t +hppe_l2_dbg_data_get( + a_uint32_t dev_id, + union l2_dbg_data_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + L2_DBG_DATA_ADDRESS, + &value->val); +} + +sw_error_t +hppe_l2_dbg_data_set( + a_uint32_t dev_id, + union l2_dbg_data_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_fdb_tbl_op_get( + a_uint32_t dev_id, + union fdb_tbl_op_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + FDB_TBL_OP_ADDRESS, + &value->val); +} +#endif +sw_error_t +hppe_fdb_tbl_op_set( + a_uint32_t dev_id, + union fdb_tbl_op_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L2_BASE_ADDR + FDB_TBL_OP_ADDRESS, + value->val); +} +#ifndef IN_FDB_MINI +sw_error_t +hppe_fdb_tbl_rd_op_get( + a_uint32_t dev_id, + union fdb_tbl_rd_op_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + FDB_TBL_RD_OP_ADDRESS, + &value->val); +} +#endif +sw_error_t +hppe_fdb_tbl_rd_op_set( + a_uint32_t dev_id, + union fdb_tbl_rd_op_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L2_BASE_ADDR + FDB_TBL_RD_OP_ADDRESS, + value->val); +} + +sw_error_t +hppe_fdb_tbl_op_rslt_get( + a_uint32_t dev_id, + union fdb_tbl_op_rslt_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + FDB_TBL_OP_RSLT_ADDRESS, + &value->val); +} +#ifndef IN_FDB_MINI +sw_error_t +hppe_fdb_tbl_op_rslt_set( + a_uint32_t dev_id, + union fdb_tbl_op_rslt_u *value) +{ + return SW_NOT_SUPPORTED; +} +#endif +sw_error_t +hppe_fdb_tbl_rd_op_rslt_get( + a_uint32_t dev_id, + union fdb_tbl_rd_op_rslt_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + FDB_TBL_RD_OP_RSLT_ADDRESS, + &value->val); +} +#ifndef IN_FDB_MINI +sw_error_t +hppe_fdb_tbl_rd_op_rslt_set( + a_uint32_t dev_id, + union fdb_tbl_rd_op_rslt_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_age_timer_get( + a_uint32_t dev_id, + union age_timer_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + AGE_TIMER_ADDRESS, + &value->val); +} + +sw_error_t +hppe_age_timer_set( + a_uint32_t dev_id, + union age_timer_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L2_BASE_ADDR + AGE_TIMER_ADDRESS, + value->val); +} +#endif +sw_error_t +hppe_l2_global_conf_get( + a_uint32_t dev_id, + union l2_global_conf_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + L2_GLOBAL_CONF_ADDRESS, + &value->val); +} + +sw_error_t +hppe_l2_global_conf_set( + a_uint32_t dev_id, + union l2_global_conf_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L2_BASE_ADDR + L2_GLOBAL_CONF_ADDRESS, + value->val); +} +#ifndef IN_FDB_MINI +sw_error_t +hppe_l2_dbgcnt_cmd_get( + a_uint32_t dev_id, + union l2_dbgcnt_cmd_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + L2_DBGCNT_CMD_ADDRESS, + &value->val); +} + +sw_error_t +hppe_l2_dbgcnt_cmd_set( + a_uint32_t dev_id, + union l2_dbgcnt_cmd_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L2_BASE_ADDR + L2_DBGCNT_CMD_ADDRESS, + value->val); +} + +sw_error_t +hppe_l2_dbgcnt_rdata_get( + a_uint32_t dev_id, + union l2_dbgcnt_rdata_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + L2_DBGCNT_RDATA_ADDRESS, + &value->val); +} + +sw_error_t +hppe_l2_dbgcnt_rdata_set( + a_uint32_t dev_id, + union l2_dbgcnt_rdata_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l2_dbgcnt_wdata_get( + a_uint32_t dev_id, + union l2_dbgcnt_wdata_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + L2_DBGCNT_WDATA_ADDRESS, + &value->val); +} + +sw_error_t +hppe_l2_dbgcnt_wdata_set( + a_uint32_t dev_id, + union l2_dbgcnt_wdata_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L2_BASE_ADDR + L2_DBGCNT_WDATA_ADDRESS, + value->val); +} +#endif +sw_error_t +hppe_fdb_tbl_rd_op_rslt_data0_get( + a_uint32_t dev_id, + union fdb_tbl_rd_op_rslt_data0_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + FDB_TBL_RD_OP_RSLT_DATA0_ADDRESS, + &value->val); +} + +sw_error_t +hppe_fdb_tbl_rd_op_rslt_data0_set( + a_uint32_t dev_id, + union fdb_tbl_rd_op_rslt_data0_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_fdb_tbl_rd_op_rslt_data1_get( + a_uint32_t dev_id, + union fdb_tbl_rd_op_rslt_data1_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + FDB_TBL_RD_OP_RSLT_DATA1_ADDRESS, + &value->val); +} +#ifndef IN_FDB_MINI +sw_error_t +hppe_fdb_tbl_rd_op_rslt_data1_set( + a_uint32_t dev_id, + union fdb_tbl_rd_op_rslt_data1_u *value) +{ + return SW_NOT_SUPPORTED; +} +#endif +sw_error_t +hppe_fdb_tbl_rd_op_rslt_data2_get( + a_uint32_t dev_id, + union fdb_tbl_rd_op_rslt_data2_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + FDB_TBL_RD_OP_RSLT_DATA2_ADDRESS, + &value->val); +} +#ifndef IN_FDB_MINI +sw_error_t +hppe_fdb_tbl_rd_op_rslt_data2_set( + a_uint32_t dev_id, + union fdb_tbl_rd_op_rslt_data2_u *value) +{ + return SW_NOT_SUPPORTED; +} +#endif +sw_error_t +hppe_fdb_tbl_op_data0_get( + a_uint32_t dev_id, + union fdb_tbl_op_data0_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + FDB_TBL_OP_DATA0_ADDRESS, + &value->val); +} + +sw_error_t +hppe_fdb_tbl_op_data0_set( + a_uint32_t dev_id, + union fdb_tbl_op_data0_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L2_BASE_ADDR + FDB_TBL_OP_DATA0_ADDRESS, + value->val); +} + +sw_error_t +hppe_fdb_tbl_op_data1_get( + a_uint32_t dev_id, + union fdb_tbl_op_data1_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + FDB_TBL_OP_DATA1_ADDRESS, + &value->val); +} + +sw_error_t +hppe_fdb_tbl_op_data1_set( + a_uint32_t dev_id, + union fdb_tbl_op_data1_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L2_BASE_ADDR + FDB_TBL_OP_DATA1_ADDRESS, + value->val); +} + +sw_error_t +hppe_fdb_tbl_op_data2_get( + a_uint32_t dev_id, + union fdb_tbl_op_data2_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + FDB_TBL_OP_DATA2_ADDRESS, + &value->val); +} + +sw_error_t +hppe_fdb_tbl_op_data2_set( + a_uint32_t dev_id, + union fdb_tbl_op_data2_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L2_BASE_ADDR + FDB_TBL_OP_DATA2_ADDRESS, + value->val); +} + +sw_error_t +hppe_fdb_tbl_rd_op_data0_get( + a_uint32_t dev_id, + union fdb_tbl_rd_op_data0_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + FDB_TBL_RD_OP_DATA0_ADDRESS, + &value->val); +} + +sw_error_t +hppe_fdb_tbl_rd_op_data0_set( + a_uint32_t dev_id, + union fdb_tbl_rd_op_data0_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L2_BASE_ADDR + FDB_TBL_RD_OP_DATA0_ADDRESS, + value->val); +} + +sw_error_t +hppe_fdb_tbl_rd_op_data1_get( + a_uint32_t dev_id, + union fdb_tbl_rd_op_data1_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + FDB_TBL_RD_OP_DATA1_ADDRESS, + &value->val); +} + +sw_error_t +hppe_fdb_tbl_rd_op_data1_set( + a_uint32_t dev_id, + union fdb_tbl_rd_op_data1_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L2_BASE_ADDR + FDB_TBL_RD_OP_DATA1_ADDRESS, + value->val); +} + +sw_error_t +hppe_fdb_tbl_rd_op_data2_get( + a_uint32_t dev_id, + union fdb_tbl_rd_op_data2_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + FDB_TBL_RD_OP_DATA2_ADDRESS, + &value->val); +} + +sw_error_t +hppe_fdb_tbl_rd_op_data2_set( + a_uint32_t dev_id, + union fdb_tbl_rd_op_data2_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L2_BASE_ADDR + FDB_TBL_RD_OP_DATA2_ADDRESS, + value->val); +} + +sw_error_t +hppe_port_bridge_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_bridge_ctrl_u *value) +{ + if (index >= PORT_BRIDGE_CTRL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + PORT_BRIDGE_CTRL_ADDRESS + \ + index * PORT_BRIDGE_CTRL_INC, + &value->val); +} + +sw_error_t +hppe_port_bridge_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_bridge_ctrl_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L2_BASE_ADDR + PORT_BRIDGE_CTRL_ADDRESS + \ + index * PORT_BRIDGE_CTRL_INC, + value->val); +} +#ifndef IN_FDB_MINI +sw_error_t +hppe_port_lrn_limit_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_lrn_limit_ctrl_u *value) +{ + if (index >= PORT_LRN_LIMIT_CTRL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + PORT_LRN_LIMIT_CTRL_ADDRESS + \ + index * PORT_LRN_LIMIT_CTRL_INC, + &value->val); +} + +sw_error_t +hppe_port_lrn_limit_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_lrn_limit_ctrl_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L2_BASE_ADDR + PORT_LRN_LIMIT_CTRL_ADDRESS + \ + index * PORT_LRN_LIMIT_CTRL_INC, + value->val); +} + +sw_error_t +hppe_port_lrn_limit_counter_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_lrn_limit_counter_u *value) +{ + if (index >= PORT_LRN_LIMIT_COUNTER_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + PORT_LRN_LIMIT_COUNTER_ADDRESS + \ + index * PORT_LRN_LIMIT_COUNTER_INC, + &value->val); +} + +sw_error_t +hppe_port_lrn_limit_counter_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_lrn_limit_counter_u *value) +{ + return SW_NOT_SUPPORTED; +} +#endif +sw_error_t +hppe_rfdb_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union rfdb_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + IPE_L2_BASE_ADDR + RFDB_TBL_ADDRESS + \ + index * RFDB_TBL_INC, + value->val, + 2); +} + +sw_error_t +hppe_rfdb_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union rfdb_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + IPE_L2_BASE_ADDR + RFDB_TBL_ADDRESS + \ + index * RFDB_TBL_INC, + value->val, + 2); +} +#ifndef IN_FDB_MINI +sw_error_t +hppe_fdb_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union fdb_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + IPE_L2_BASE_ADDR + FDB_TBL_ADDRESS + \ + index * FDB_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_fdb_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union fdb_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + IPE_L2_BASE_ADDR + FDB_TBL_ADDRESS + \ + index * FDB_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_l2_dbg_addr_l2_dbg_addr_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l2_dbg_addr_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l2_dbg_addr_get(dev_id, ®_val); + *value = reg_val.bf.l2_dbg_addr; + return ret; +} + +sw_error_t +hppe_l2_dbg_addr_l2_dbg_addr_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l2_dbg_addr_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l2_dbg_addr_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l2_dbg_addr = value; + ret = hppe_l2_dbg_addr_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l2_dbg_data_l2_dbg_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l2_dbg_data_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l2_dbg_data_get(dev_id, ®_val); + *value = reg_val.bf.l2_dbg_data; + return ret; +} + +sw_error_t +hppe_l2_dbg_data_l2_dbg_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_fdb_tbl_op_op_mode_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union fdb_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_op_get(dev_id, ®_val); + *value = reg_val.bf.op_mode; + return ret; +} + +sw_error_t +hppe_fdb_tbl_op_op_mode_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union fdb_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.op_mode = value; + ret = hppe_fdb_tbl_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_fdb_tbl_op_op_type_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union fdb_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_op_get(dev_id, ®_val); + *value = reg_val.bf.op_type; + return ret; +} + +sw_error_t +hppe_fdb_tbl_op_op_type_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union fdb_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.op_type = value; + ret = hppe_fdb_tbl_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_fdb_tbl_op_entry_index_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union fdb_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_op_get(dev_id, ®_val); + *value = reg_val.bf.entry_index; + return ret; +} + +sw_error_t +hppe_fdb_tbl_op_entry_index_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union fdb_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.entry_index = value; + ret = hppe_fdb_tbl_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_fdb_tbl_op_cmd_id_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union fdb_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_op_get(dev_id, ®_val); + *value = reg_val.bf.cmd_id; + return ret; +} + +sw_error_t +hppe_fdb_tbl_op_cmd_id_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union fdb_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmd_id = value; + ret = hppe_fdb_tbl_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_fdb_tbl_op_hash_block_bitmap_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union fdb_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_op_get(dev_id, ®_val); + *value = reg_val.bf.hash_block_bitmap; + return ret; +} + +sw_error_t +hppe_fdb_tbl_op_hash_block_bitmap_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union fdb_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.hash_block_bitmap = value; + ret = hppe_fdb_tbl_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_fdb_tbl_op_byp_rslt_en_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union fdb_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_op_get(dev_id, ®_val); + *value = reg_val.bf.byp_rslt_en; + return ret; +} + +sw_error_t +hppe_fdb_tbl_op_byp_rslt_en_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union fdb_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.byp_rslt_en = value; + ret = hppe_fdb_tbl_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_fdb_tbl_rd_op_op_mode_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union fdb_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_rd_op_get(dev_id, ®_val); + *value = reg_val.bf.op_mode; + return ret; +} + +sw_error_t +hppe_fdb_tbl_rd_op_op_mode_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union fdb_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_rd_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.op_mode = value; + ret = hppe_fdb_tbl_rd_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_fdb_tbl_rd_op_op_type_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union fdb_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_rd_op_get(dev_id, ®_val); + *value = reg_val.bf.op_type; + return ret; +} + +sw_error_t +hppe_fdb_tbl_rd_op_op_type_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union fdb_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_rd_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.op_type = value; + ret = hppe_fdb_tbl_rd_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_fdb_tbl_rd_op_entry_index_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union fdb_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_rd_op_get(dev_id, ®_val); + *value = reg_val.bf.entry_index; + return ret; +} + +sw_error_t +hppe_fdb_tbl_rd_op_entry_index_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union fdb_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_rd_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.entry_index = value; + ret = hppe_fdb_tbl_rd_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_fdb_tbl_rd_op_cmd_id_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union fdb_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_rd_op_get(dev_id, ®_val); + *value = reg_val.bf.cmd_id; + return ret; +} + +sw_error_t +hppe_fdb_tbl_rd_op_cmd_id_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union fdb_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_rd_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmd_id = value; + ret = hppe_fdb_tbl_rd_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_fdb_tbl_rd_op_hash_block_bitmap_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union fdb_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_rd_op_get(dev_id, ®_val); + *value = reg_val.bf.hash_block_bitmap; + return ret; +} + +sw_error_t +hppe_fdb_tbl_rd_op_hash_block_bitmap_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union fdb_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_rd_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.hash_block_bitmap = value; + ret = hppe_fdb_tbl_rd_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_fdb_tbl_rd_op_byp_rslt_en_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union fdb_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_rd_op_get(dev_id, ®_val); + *value = reg_val.bf.byp_rslt_en; + return ret; +} + +sw_error_t +hppe_fdb_tbl_rd_op_byp_rslt_en_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union fdb_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_rd_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.byp_rslt_en = value; + ret = hppe_fdb_tbl_rd_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_fdb_tbl_op_rslt_op_rslt_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union fdb_tbl_op_rslt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_op_rslt_get(dev_id, ®_val); + *value = reg_val.bf.op_rslt; + return ret; +} + +sw_error_t +hppe_fdb_tbl_op_rslt_op_rslt_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_fdb_tbl_op_rslt_valid_cnt_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union fdb_tbl_op_rslt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_op_rslt_get(dev_id, ®_val); + *value = reg_val.bf.valid_cnt; + return ret; +} + +sw_error_t +hppe_fdb_tbl_op_rslt_valid_cnt_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_fdb_tbl_op_rslt_entry_index_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union fdb_tbl_op_rslt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_op_rslt_get(dev_id, ®_val); + *value = reg_val.bf.entry_index; + return ret; +} + +sw_error_t +hppe_fdb_tbl_op_rslt_entry_index_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_fdb_tbl_op_rslt_cmd_id_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union fdb_tbl_op_rslt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_op_rslt_get(dev_id, ®_val); + *value = reg_val.bf.cmd_id; + return ret; +} + +sw_error_t +hppe_fdb_tbl_op_rslt_cmd_id_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_fdb_tbl_rd_op_rslt_op_rslt_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union fdb_tbl_rd_op_rslt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_rd_op_rslt_get(dev_id, ®_val); + *value = reg_val.bf.op_rslt; + return ret; +} + +sw_error_t +hppe_fdb_tbl_rd_op_rslt_op_rslt_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_fdb_tbl_rd_op_rslt_valid_cnt_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union fdb_tbl_rd_op_rslt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_rd_op_rslt_get(dev_id, ®_val); + *value = reg_val.bf.valid_cnt; + return ret; +} + +sw_error_t +hppe_fdb_tbl_rd_op_rslt_valid_cnt_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_fdb_tbl_rd_op_rslt_entry_index_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union fdb_tbl_rd_op_rslt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_rd_op_rslt_get(dev_id, ®_val); + *value = reg_val.bf.entry_index; + return ret; +} + +sw_error_t +hppe_fdb_tbl_rd_op_rslt_entry_index_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_fdb_tbl_rd_op_rslt_cmd_id_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union fdb_tbl_rd_op_rslt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_rd_op_rslt_get(dev_id, ®_val); + *value = reg_val.bf.cmd_id; + return ret; +} + +sw_error_t +hppe_fdb_tbl_rd_op_rslt_cmd_id_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_age_timer_age_val_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union age_timer_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_age_timer_get(dev_id, ®_val); + *value = reg_val.bf.age_val; + return ret; +} + +sw_error_t +hppe_age_timer_age_val_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union age_timer_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_age_timer_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.age_val = value; + ret = hppe_age_timer_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l2_global_conf_fdb_hash_full_fwd_cmd_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l2_global_conf_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l2_global_conf_get(dev_id, ®_val); + *value = reg_val.bf.fdb_hash_full_fwd_cmd; + return ret; +} + +sw_error_t +hppe_l2_global_conf_fdb_hash_full_fwd_cmd_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l2_global_conf_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l2_global_conf_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.fdb_hash_full_fwd_cmd = value; + ret = hppe_l2_global_conf_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l2_global_conf_failover_en_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l2_global_conf_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l2_global_conf_get(dev_id, ®_val); + *value = reg_val.bf.failover_en; + return ret; +} + +sw_error_t +hppe_l2_global_conf_failover_en_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l2_global_conf_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l2_global_conf_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.failover_en = value; + ret = hppe_l2_global_conf_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l2_global_conf_lrn_ctrl_mode_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l2_global_conf_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l2_global_conf_get(dev_id, ®_val); + *value = reg_val.bf.lrn_ctrl_mode; + return ret; +} + +sw_error_t +hppe_l2_global_conf_lrn_ctrl_mode_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l2_global_conf_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l2_global_conf_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.lrn_ctrl_mode = value; + ret = hppe_l2_global_conf_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l2_global_conf_age_en_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l2_global_conf_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l2_global_conf_get(dev_id, ®_val); + *value = reg_val.bf.age_en; + return ret; +} + +sw_error_t +hppe_l2_global_conf_age_en_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l2_global_conf_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l2_global_conf_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.age_en = value; + ret = hppe_l2_global_conf_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l2_global_conf_fdb_hash_mode_1_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l2_global_conf_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l2_global_conf_get(dev_id, ®_val); + *value = reg_val.bf.fdb_hash_mode_1; + return ret; +} + +sw_error_t +hppe_l2_global_conf_fdb_hash_mode_1_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l2_global_conf_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l2_global_conf_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.fdb_hash_mode_1 = value; + ret = hppe_l2_global_conf_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l2_global_conf_lrn_en_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l2_global_conf_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l2_global_conf_get(dev_id, ®_val); + *value = reg_val.bf.lrn_en; + return ret; +} + +sw_error_t +hppe_l2_global_conf_lrn_en_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l2_global_conf_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l2_global_conf_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.lrn_en = value; + ret = hppe_l2_global_conf_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l2_global_conf_fdb_hash_mode_0_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l2_global_conf_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l2_global_conf_get(dev_id, ®_val); + *value = reg_val.bf.fdb_hash_mode_0; + return ret; +} + +sw_error_t +hppe_l2_global_conf_fdb_hash_mode_0_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l2_global_conf_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l2_global_conf_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.fdb_hash_mode_0 = value; + ret = hppe_l2_global_conf_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l2_global_conf_age_ctrl_mode_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l2_global_conf_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l2_global_conf_get(dev_id, ®_val); + *value = reg_val.bf.age_ctrl_mode; + return ret; +} + +sw_error_t +hppe_l2_global_conf_age_ctrl_mode_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l2_global_conf_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l2_global_conf_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.age_ctrl_mode = value; + ret = hppe_l2_global_conf_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l2_global_conf_service_code_loop_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l2_global_conf_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l2_global_conf_get(dev_id, ®_val); + *value = reg_val.bf.service_code_loop; + return ret; +} + +sw_error_t +hppe_l2_global_conf_service_code_loop_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l2_global_conf_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l2_global_conf_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.service_code_loop = value; + ret = hppe_l2_global_conf_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l2_dbgcnt_cmd_type_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l2_dbgcnt_cmd_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l2_dbgcnt_cmd_get(dev_id, ®_val); + *value = reg_val.bf.type; + return ret; +} + +sw_error_t +hppe_l2_dbgcnt_cmd_type_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l2_dbgcnt_cmd_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l2_dbgcnt_cmd_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.type = value; + ret = hppe_l2_dbgcnt_cmd_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l2_dbgcnt_cmd_addr_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l2_dbgcnt_cmd_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l2_dbgcnt_cmd_get(dev_id, ®_val); + *value = reg_val.bf.addr; + return ret; +} + +sw_error_t +hppe_l2_dbgcnt_cmd_addr_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l2_dbgcnt_cmd_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l2_dbgcnt_cmd_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.addr = value; + ret = hppe_l2_dbgcnt_cmd_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l2_dbgcnt_rdata_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l2_dbgcnt_rdata_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l2_dbgcnt_rdata_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_l2_dbgcnt_rdata_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l2_dbgcnt_wdata_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l2_dbgcnt_wdata_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l2_dbgcnt_wdata_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_l2_dbgcnt_wdata_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l2_dbgcnt_wdata_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l2_dbgcnt_wdata_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_l2_dbgcnt_wdata_set(dev_id, ®_val); + return ret; +} +#endif +sw_error_t +hppe_fdb_tbl_rd_op_rslt_data0_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union fdb_tbl_rd_op_rslt_data0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_rd_op_rslt_data0_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} +#ifndef IN_FDB_MINI +sw_error_t +hppe_fdb_tbl_rd_op_rslt_data0_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} +#endif +sw_error_t +hppe_fdb_tbl_rd_op_rslt_data1_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union fdb_tbl_rd_op_rslt_data1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_rd_op_rslt_data1_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} +#ifndef IN_FDB_MINI +sw_error_t +hppe_fdb_tbl_rd_op_rslt_data1_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} +#endif +sw_error_t +hppe_fdb_tbl_rd_op_rslt_data2_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union fdb_tbl_rd_op_rslt_data2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_rd_op_rslt_data2_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} +#ifndef IN_FDB_MINI +sw_error_t +hppe_fdb_tbl_rd_op_rslt_data2_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_fdb_tbl_op_data0_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union fdb_tbl_op_data0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_op_data0_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} +#endif +sw_error_t +hppe_fdb_tbl_op_data0_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union fdb_tbl_op_data0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_op_data0_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_fdb_tbl_op_data0_set(dev_id, ®_val); + return ret; +} +#ifndef IN_FDB_MINI +sw_error_t +hppe_fdb_tbl_op_data1_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union fdb_tbl_op_data1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_op_data1_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} +#endif +sw_error_t +hppe_fdb_tbl_op_data1_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union fdb_tbl_op_data1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_op_data1_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_fdb_tbl_op_data1_set(dev_id, ®_val); + return ret; +} +#ifndef IN_FDB_MINI +sw_error_t +hppe_fdb_tbl_op_data2_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union fdb_tbl_op_data2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_op_data2_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} +#endif +sw_error_t +hppe_fdb_tbl_op_data2_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union fdb_tbl_op_data2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_op_data2_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_fdb_tbl_op_data2_set(dev_id, ®_val); + return ret; +} +#ifndef IN_FDB_MINI +sw_error_t +hppe_fdb_tbl_rd_op_data0_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union fdb_tbl_rd_op_data0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_rd_op_data0_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} +#endif +sw_error_t +hppe_fdb_tbl_rd_op_data0_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union fdb_tbl_rd_op_data0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_rd_op_data0_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_fdb_tbl_rd_op_data0_set(dev_id, ®_val); + return ret; +} +#ifndef IN_FDB_MINI +sw_error_t +hppe_fdb_tbl_rd_op_data1_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union fdb_tbl_rd_op_data1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_rd_op_data1_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} +#endif +sw_error_t +hppe_fdb_tbl_rd_op_data1_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union fdb_tbl_rd_op_data1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_rd_op_data1_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_fdb_tbl_rd_op_data1_set(dev_id, ®_val); + return ret; +} +#ifndef IN_FDB_MINI +sw_error_t +hppe_fdb_tbl_rd_op_data2_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union fdb_tbl_rd_op_data2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_rd_op_data2_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} +#endif +sw_error_t +hppe_fdb_tbl_rd_op_data2_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union fdb_tbl_rd_op_data2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_fdb_tbl_rd_op_data2_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_fdb_tbl_rd_op_data2_set(dev_id, ®_val); + return ret; +} +#ifndef IN_FDB_MINI +sw_error_t +hppe_port_bridge_ctrl_txmac_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_bridge_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_bridge_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.txmac_en; + return ret; +} + +sw_error_t +hppe_port_bridge_ctrl_txmac_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_bridge_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_bridge_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.txmac_en = value; + ret = hppe_port_bridge_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_bridge_ctrl_port_isolation_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_bridge_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_bridge_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.port_isolation_bitmap; + return ret; +} + +sw_error_t +hppe_port_bridge_ctrl_port_isolation_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_bridge_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_bridge_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_isolation_bitmap = value; + ret = hppe_port_bridge_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_bridge_ctrl_station_move_lrn_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_bridge_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_bridge_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.station_move_lrn_en; + return ret; +} + +sw_error_t +hppe_port_bridge_ctrl_station_move_lrn_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_bridge_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_bridge_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.station_move_lrn_en = value; + ret = hppe_port_bridge_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_bridge_ctrl_new_addr_fwd_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_bridge_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_bridge_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.new_addr_fwd_cmd; + return ret; +} + +sw_error_t +hppe_port_bridge_ctrl_new_addr_fwd_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_bridge_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_bridge_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.new_addr_fwd_cmd = value; + ret = hppe_port_bridge_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_bridge_ctrl_promisc_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_bridge_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_bridge_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.promisc_en; + return ret; +} + +sw_error_t +hppe_port_bridge_ctrl_promisc_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_bridge_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_bridge_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.promisc_en = value; + ret = hppe_port_bridge_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_bridge_ctrl_new_addr_lrn_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_bridge_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_bridge_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.new_addr_lrn_en; + return ret; +} + +sw_error_t +hppe_port_bridge_ctrl_new_addr_lrn_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_bridge_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_bridge_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.new_addr_lrn_en = value; + ret = hppe_port_bridge_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_bridge_ctrl_station_move_fwd_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_bridge_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_bridge_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.station_move_fwd_cmd; + return ret; +} + +sw_error_t +hppe_port_bridge_ctrl_station_move_fwd_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_bridge_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_bridge_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.station_move_fwd_cmd = value; + ret = hppe_port_bridge_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_lrn_limit_ctrl_lrn_lmt_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_lrn_limit_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_lrn_limit_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.lrn_lmt_en; + return ret; +} + +sw_error_t +hppe_port_lrn_limit_ctrl_lrn_lmt_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_lrn_limit_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_lrn_limit_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.lrn_lmt_en = value; + ret = hppe_port_lrn_limit_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_lrn_limit_ctrl_lrn_lmt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_lrn_limit_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_lrn_limit_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.lrn_lmt_cnt; + return ret; +} + +sw_error_t +hppe_port_lrn_limit_ctrl_lrn_lmt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_lrn_limit_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_lrn_limit_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.lrn_lmt_cnt = value; + ret = hppe_port_lrn_limit_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_lrn_limit_ctrl_lrn_lmt_exceed_fwd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_lrn_limit_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_lrn_limit_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.lrn_lmt_exceed_fwd; + return ret; +} + +sw_error_t +hppe_port_lrn_limit_ctrl_lrn_lmt_exceed_fwd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_lrn_limit_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_lrn_limit_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.lrn_lmt_exceed_fwd = value; + ret = hppe_port_lrn_limit_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_lrn_limit_counter_lrn_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_lrn_limit_counter_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_lrn_limit_counter_get(dev_id, index, ®_val); + *value = reg_val.bf.lrn_cnt; + return ret; +} + +sw_error_t +hppe_port_lrn_limit_counter_lrn_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} +#endif +sw_error_t +hppe_rfdb_tbl_mac_addr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union rfdb_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rfdb_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.mac_addr_1 << 32 | \ + reg_val.bf.mac_addr_0; + return ret; +} + +sw_error_t +hppe_rfdb_tbl_mac_addr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union rfdb_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rfdb_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_addr_1 = value >> 32; + reg_val.bf.mac_addr_0 = value & (((a_uint64_t)1<<32)-1); + ret = hppe_rfdb_tbl_set(dev_id, index, ®_val); + return ret; +} +#ifndef IN_FDB_MINI +sw_error_t +hppe_rfdb_tbl_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rfdb_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rfdb_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.valid; + return ret; +} +#endif +sw_error_t +hppe_rfdb_tbl_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union rfdb_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rfdb_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.valid = value; + ret = hppe_rfdb_tbl_set(dev_id, index, ®_val); + return ret; +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_flow.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_flow.c new file mode 100755 index 000000000..f2fabba02 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_flow.c @@ -0,0 +1,5814 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hppe_reg_access.h" +#include "hppe_flow_reg.h" +#include "hppe_flow.h" +#include "hppe_ip_reg.h" +#include "hppe_ip.h" + +#ifndef IN_FLOW_MINI +static a_uint32_t flow_cmd_id = 0; +static a_uint32_t flow_host_cmd_id = 0; + +sw_error_t +hppe_in_flow_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union in_flow_cnt_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + INGRESS_POLICER_BASE_ADDR + IN_FLOW_CNT_TBL_ADDRESS + \ + index * IN_FLOW_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_in_flow_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union in_flow_cnt_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + INGRESS_POLICER_BASE_ADDR + IN_FLOW_CNT_TBL_ADDRESS + \ + index * IN_FLOW_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_flow_ctrl0_get( + a_uint32_t dev_id, + union flow_ctrl0_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + FLOW_CTRL0_ADDRESS, + &value->val); +} + +sw_error_t +hppe_flow_ctrl0_set( + a_uint32_t dev_id, + union flow_ctrl0_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + FLOW_CTRL0_ADDRESS, + value->val); +} +#endif + +sw_error_t +hppe_flow_ctrl1_get( + a_uint32_t dev_id, + a_uint32_t index, + union flow_ctrl1_u *value) +{ + if (index >= FLOW_CTRL1_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + FLOW_CTRL1_ADDRESS + \ + index * FLOW_CTRL1_INC, + &value->val); +} + +sw_error_t +hppe_flow_ctrl1_set( + a_uint32_t dev_id, + a_uint32_t index, + union flow_ctrl1_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + FLOW_CTRL1_ADDRESS + \ + index * FLOW_CTRL1_INC, + value->val); +} + +#ifndef IN_FLOW_MINI +sw_error_t +hppe_in_flow_tbl_op_get( + a_uint32_t dev_id, + union in_flow_tbl_op_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_OP_ADDRESS, + &value->val); +} + +sw_error_t +hppe_in_flow_tbl_op_set( + a_uint32_t dev_id, + union in_flow_tbl_op_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_OP_ADDRESS, + value->val); +} + +sw_error_t +hppe_in_flow_host_tbl_op_get( + a_uint32_t dev_id, + union in_flow_host_tbl_op_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_HOST_TBL_OP_ADDRESS, + &value->val); +} + +sw_error_t +hppe_in_flow_host_tbl_op_set( + a_uint32_t dev_id, + union in_flow_host_tbl_op_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_HOST_TBL_OP_ADDRESS, + value->val); +} + +sw_error_t +hppe_in_flow_tbl_op_data0_get( + a_uint32_t dev_id, + union in_flow_tbl_op_data0_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_OP_DATA0_ADDRESS, + &value->val); +} + +sw_error_t +hppe_in_flow_tbl_op_data0_set( + a_uint32_t dev_id, + union in_flow_tbl_op_data0_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_OP_DATA0_ADDRESS, + value->val); +} + +sw_error_t +hppe_in_flow_tbl_op_data1_get( + a_uint32_t dev_id, + union in_flow_tbl_op_data1_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_OP_DATA1_ADDRESS, + &value->val); +} + +sw_error_t +hppe_in_flow_tbl_op_data1_set( + a_uint32_t dev_id, + union in_flow_tbl_op_data1_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_OP_DATA1_ADDRESS, + value->val); +} + +sw_error_t +hppe_in_flow_tbl_op_data2_get( + a_uint32_t dev_id, + union in_flow_tbl_op_data2_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_OP_DATA2_ADDRESS, + &value->val); +} + +sw_error_t +hppe_in_flow_tbl_op_data2_set( + a_uint32_t dev_id, + union in_flow_tbl_op_data2_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_OP_DATA2_ADDRESS, + value->val); +} + +sw_error_t +hppe_in_flow_tbl_op_data3_get( + a_uint32_t dev_id, + union in_flow_tbl_op_data3_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_OP_DATA3_ADDRESS, + &value->val); +} + +sw_error_t +hppe_in_flow_tbl_op_data3_set( + a_uint32_t dev_id, + union in_flow_tbl_op_data3_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_OP_DATA3_ADDRESS, + value->val); +} + +sw_error_t +hppe_in_flow_tbl_op_data4_get( + a_uint32_t dev_id, + union in_flow_tbl_op_data4_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_OP_DATA4_ADDRESS, + &value->val); +} + +sw_error_t +hppe_in_flow_tbl_op_data4_set( + a_uint32_t dev_id, + union in_flow_tbl_op_data4_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_OP_DATA4_ADDRESS, + value->val); +} + +sw_error_t +hppe_in_flow_tbl_op_data5_get( + a_uint32_t dev_id, + union in_flow_tbl_op_data5_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_OP_DATA5_ADDRESS, + &value->val); +} + +sw_error_t +hppe_in_flow_tbl_op_data5_set( + a_uint32_t dev_id, + union in_flow_tbl_op_data5_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_OP_DATA5_ADDRESS, + value->val); +} + +sw_error_t +hppe_in_flow_tbl_op_data6_get( + a_uint32_t dev_id, + union in_flow_tbl_op_data6_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_OP_DATA6_ADDRESS, + &value->val); +} + +sw_error_t +hppe_in_flow_tbl_op_data6_set( + a_uint32_t dev_id, + union in_flow_tbl_op_data6_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_OP_DATA6_ADDRESS, + value->val); +} + +sw_error_t +hppe_in_flow_tbl_op_data7_get( + a_uint32_t dev_id, + union in_flow_tbl_op_data7_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_OP_DATA7_ADDRESS, + &value->val); +} + +sw_error_t +hppe_in_flow_tbl_op_data7_set( + a_uint32_t dev_id, + union in_flow_tbl_op_data7_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_OP_DATA7_ADDRESS, + value->val); +} + +sw_error_t +hppe_in_flow_tbl_op_data8_get( + a_uint32_t dev_id, + union in_flow_tbl_op_data8_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_OP_DATA8_ADDRESS, + &value->val); +} + +sw_error_t +hppe_in_flow_tbl_op_data8_set( + a_uint32_t dev_id, + union in_flow_tbl_op_data8_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_OP_DATA8_ADDRESS, + value->val); +} + +sw_error_t +hppe_flow_host_tbl_op_data0_get( + a_uint32_t dev_id, + union flow_host_tbl_op_data0_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_OP_DATA0_ADDRESS, + &value->val); +} + +sw_error_t +hppe_flow_host_tbl_op_data0_set( + a_uint32_t dev_id, + union flow_host_tbl_op_data0_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_OP_DATA0_ADDRESS, + value->val); +} + +sw_error_t +hppe_flow_host_tbl_op_data1_get( + a_uint32_t dev_id, + union flow_host_tbl_op_data1_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_OP_DATA1_ADDRESS, + &value->val); +} + +sw_error_t +hppe_flow_host_tbl_op_data1_set( + a_uint32_t dev_id, + union flow_host_tbl_op_data1_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_OP_DATA1_ADDRESS, + value->val); +} + +sw_error_t +hppe_flow_host_tbl_op_data2_get( + a_uint32_t dev_id, + union flow_host_tbl_op_data2_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_OP_DATA2_ADDRESS, + &value->val); +} + +sw_error_t +hppe_flow_host_tbl_op_data2_set( + a_uint32_t dev_id, + union flow_host_tbl_op_data2_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_OP_DATA2_ADDRESS, + value->val); +} + +sw_error_t +hppe_flow_host_tbl_op_data3_get( + a_uint32_t dev_id, + union flow_host_tbl_op_data3_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_OP_DATA3_ADDRESS, + &value->val); +} + +sw_error_t +hppe_flow_host_tbl_op_data3_set( + a_uint32_t dev_id, + union flow_host_tbl_op_data3_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_OP_DATA3_ADDRESS, + value->val); +} + +sw_error_t +hppe_flow_host_tbl_op_data4_get( + a_uint32_t dev_id, + union flow_host_tbl_op_data4_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_OP_DATA4_ADDRESS, + &value->val); +} + +sw_error_t +hppe_flow_host_tbl_op_data4_set( + a_uint32_t dev_id, + union flow_host_tbl_op_data4_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_OP_DATA4_ADDRESS, + value->val); +} + +sw_error_t +hppe_flow_host_tbl_op_data5_get( + a_uint32_t dev_id, + union flow_host_tbl_op_data5_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_OP_DATA5_ADDRESS, + &value->val); +} + +sw_error_t +hppe_flow_host_tbl_op_data5_set( + a_uint32_t dev_id, + union flow_host_tbl_op_data5_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_OP_DATA5_ADDRESS, + value->val); +} + +sw_error_t +hppe_flow_host_tbl_op_data6_get( + a_uint32_t dev_id, + union flow_host_tbl_op_data6_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_OP_DATA6_ADDRESS, + &value->val); +} + +sw_error_t +hppe_flow_host_tbl_op_data6_set( + a_uint32_t dev_id, + union flow_host_tbl_op_data6_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_OP_DATA6_ADDRESS, + value->val); +} + +sw_error_t +hppe_flow_host_tbl_op_data7_get( + a_uint32_t dev_id, + union flow_host_tbl_op_data7_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_OP_DATA7_ADDRESS, + &value->val); +} + +sw_error_t +hppe_flow_host_tbl_op_data7_set( + a_uint32_t dev_id, + union flow_host_tbl_op_data7_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_OP_DATA7_ADDRESS, + value->val); +} + +sw_error_t +hppe_flow_host_tbl_op_data8_get( + a_uint32_t dev_id, + union flow_host_tbl_op_data8_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_OP_DATA8_ADDRESS, + &value->val); +} + +sw_error_t +hppe_flow_host_tbl_op_data8_set( + a_uint32_t dev_id, + union flow_host_tbl_op_data8_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_OP_DATA8_ADDRESS, + value->val); +} + +sw_error_t +hppe_flow_host_tbl_op_data9_get( + a_uint32_t dev_id, + union flow_host_tbl_op_data9_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_OP_DATA9_ADDRESS, + &value->val); +} + +sw_error_t +hppe_flow_host_tbl_op_data9_set( + a_uint32_t dev_id, + union flow_host_tbl_op_data9_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_OP_DATA9_ADDRESS, + value->val); +} + +sw_error_t +hppe_in_flow_tbl_op_rslt_get( + a_uint32_t dev_id, + union in_flow_tbl_op_rslt_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_OP_RSLT_ADDRESS, + &value->val); +} + +sw_error_t +hppe_in_flow_tbl_op_rslt_set( + a_uint32_t dev_id, + union in_flow_tbl_op_rslt_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_flow_host_tbl_op_rslt_get( + a_uint32_t dev_id, + union flow_host_tbl_op_rslt_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_OP_RSLT_ADDRESS, + &value->val); +} + +sw_error_t +hppe_flow_host_tbl_op_rslt_set( + a_uint32_t dev_id, + union flow_host_tbl_op_rslt_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_RD_OP_ADDRESS, + &value->val); +} + +sw_error_t +hppe_in_flow_tbl_rd_op_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_RD_OP_ADDRESS, + value->val); +} + +sw_error_t +hppe_in_flow_host_tbl_rd_op_get( + a_uint32_t dev_id, + union in_flow_host_tbl_rd_op_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_HOST_TBL_RD_OP_ADDRESS, + &value->val); +} + +sw_error_t +hppe_in_flow_host_tbl_rd_op_set( + a_uint32_t dev_id, + union in_flow_host_tbl_rd_op_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_HOST_TBL_RD_OP_ADDRESS, + value->val); +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data0_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data0_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_RD_OP_DATA0_ADDRESS, + &value->val); +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data0_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data0_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_RD_OP_DATA0_ADDRESS, + value->val); +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data1_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data1_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_RD_OP_DATA1_ADDRESS, + &value->val); +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data1_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data1_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_RD_OP_DATA1_ADDRESS, + value->val); +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data2_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data2_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_RD_OP_DATA2_ADDRESS, + &value->val); +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data2_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data2_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_RD_OP_DATA2_ADDRESS, + value->val); +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data3_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data3_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_RD_OP_DATA3_ADDRESS, + &value->val); +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data3_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data3_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_RD_OP_DATA3_ADDRESS, + value->val); +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data4_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data4_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_RD_OP_DATA4_ADDRESS, + &value->val); +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data4_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data4_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_RD_OP_DATA4_ADDRESS, + value->val); +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data5_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data5_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_RD_OP_DATA5_ADDRESS, + &value->val); +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data5_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data5_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_RD_OP_DATA5_ADDRESS, + value->val); +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data6_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data6_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_RD_OP_DATA6_ADDRESS, + &value->val); +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data6_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data6_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_RD_OP_DATA6_ADDRESS, + value->val); +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data7_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data7_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_RD_OP_DATA7_ADDRESS, + &value->val); +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data7_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data7_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_RD_OP_DATA7_ADDRESS, + value->val); +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data8_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data8_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_RD_OP_DATA8_ADDRESS, + &value->val); +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data8_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_data8_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_RD_OP_DATA8_ADDRESS, + value->val); +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data0_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data0_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_RD_OP_DATA0_ADDRESS, + &value->val); +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data0_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data0_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_RD_OP_DATA0_ADDRESS, + value->val); +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data1_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data1_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_RD_OP_DATA1_ADDRESS, + &value->val); +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data1_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data1_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_RD_OP_DATA1_ADDRESS, + value->val); +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data2_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data2_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_RD_OP_DATA2_ADDRESS, + &value->val); +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data2_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data2_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_RD_OP_DATA2_ADDRESS, + value->val); +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data3_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data3_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_RD_OP_DATA3_ADDRESS, + &value->val); +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data3_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data3_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_RD_OP_DATA3_ADDRESS, + value->val); +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data4_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data4_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_RD_OP_DATA4_ADDRESS, + &value->val); +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data4_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data4_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_RD_OP_DATA4_ADDRESS, + value->val); +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data5_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data5_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_RD_OP_DATA5_ADDRESS, + &value->val); +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data5_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data5_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_RD_OP_DATA5_ADDRESS, + value->val); +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data6_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data6_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_RD_OP_DATA6_ADDRESS, + &value->val); +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data6_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data6_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_RD_OP_DATA6_ADDRESS, + value->val); +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data7_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data7_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_RD_OP_DATA7_ADDRESS, + &value->val); +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data7_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data7_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_RD_OP_DATA7_ADDRESS, + value->val); +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data8_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data8_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_RD_OP_DATA8_ADDRESS, + &value->val); +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data8_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data8_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_RD_OP_DATA8_ADDRESS, + value->val); +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data9_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data9_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_RD_OP_DATA9_ADDRESS, + &value->val); +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data9_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_data9_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_RD_OP_DATA9_ADDRESS, + value->val); +} + +sw_error_t +hppe_in_flow_tbl_rd_op_rslt_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_rslt_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_RD_OP_RSLT_ADDRESS, + &value->val); +} + +sw_error_t +hppe_in_flow_tbl_rd_op_rslt_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_op_rslt_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_flow_host_tbl_rd_op_rslt_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_rslt_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_RD_OP_RSLT_ADDRESS, + &value->val); +} + +sw_error_t +hppe_flow_host_tbl_rd_op_rslt_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_op_rslt_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data0_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data0_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_RD_RSLT_DATA0_ADDRESS, + &value->val); +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data0_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data0_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data1_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data1_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_RD_RSLT_DATA1_ADDRESS, + &value->val); +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data1_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data1_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data2_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data2_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_RD_RSLT_DATA2_ADDRESS, + &value->val); +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data2_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data2_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data3_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data3_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_RD_RSLT_DATA3_ADDRESS, + &value->val); +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data3_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data3_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data4_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data4_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_RD_RSLT_DATA4_ADDRESS, + &value->val); +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data4_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data4_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data5_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data5_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_RD_RSLT_DATA5_ADDRESS, + &value->val); +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data5_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data5_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data6_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data6_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_RD_RSLT_DATA6_ADDRESS, + &value->val); +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data6_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data6_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data7_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data7_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_RD_RSLT_DATA7_ADDRESS, + &value->val); +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data7_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data7_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data8_get( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data8_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_RD_RSLT_DATA8_ADDRESS, + &value->val); +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data8_set( + a_uint32_t dev_id, + union in_flow_tbl_rd_rslt_data8_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data0_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data0_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_RD_RSLT_DATA0_ADDRESS, + &value->val); +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data0_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data0_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data1_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data1_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_RD_RSLT_DATA1_ADDRESS, + &value->val); +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data1_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data1_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data2_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data2_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_RD_RSLT_DATA2_ADDRESS, + &value->val); +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data2_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data2_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data3_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data3_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_RD_RSLT_DATA3_ADDRESS, + &value->val); +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data3_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data3_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data4_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data4_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_RD_RSLT_DATA4_ADDRESS, + &value->val); +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data4_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data4_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data5_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data5_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_RD_RSLT_DATA5_ADDRESS, + &value->val); +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data5_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data5_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data6_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data6_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_RD_RSLT_DATA6_ADDRESS, + &value->val); +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data6_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data6_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data7_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data7_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_RD_RSLT_DATA7_ADDRESS, + &value->val); +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data7_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data7_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data8_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data8_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_RD_RSLT_DATA8_ADDRESS, + &value->val); +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data8_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data8_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data9_get( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data9_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + FLOW_HOST_TBL_RD_RSLT_DATA9_ADDRESS, + &value->val); +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data9_set( + a_uint32_t dev_id, + union flow_host_tbl_rd_rslt_data9_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_in_flow_3tuple_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union in_flow_3tuple_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_3TUPLE_TBL_ADDRESS + \ + index * IN_FLOW_3TUPLE_TBL_INC, + value->val, + 4); +} + +sw_error_t +hppe_in_flow_3tuple_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union in_flow_3tuple_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_3TUPLE_TBL_ADDRESS + \ + index * IN_FLOW_3TUPLE_TBL_INC, + value->val, + 4); +} + +sw_error_t +hppe_in_flow_ipv6_3tuple_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union in_flow_ipv6_3tuple_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_IPV6_3TUPLE_TBL_ADDRESS + \ + index * IN_FLOW_IPV6_3TUPLE_TBL_INC, + value->val, + 9); +} + +sw_error_t +hppe_in_flow_ipv6_3tuple_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union in_flow_ipv6_3tuple_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_IPV6_3TUPLE_TBL_ADDRESS + \ + index * IN_FLOW_IPV6_3TUPLE_TBL_INC, + value->val, + 9); +} + +sw_error_t +hppe_in_flow_ipv6_5tuple_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union in_flow_ipv6_5tuple_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_IPV6_5TUPLE_TBL_ADDRESS + \ + index * IN_FLOW_IPV6_5TUPLE_TBL_INC, + value->val, + 9); +} + +sw_error_t +hppe_in_flow_ipv6_5tuple_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union in_flow_ipv6_5tuple_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_IPV6_5TUPLE_TBL_ADDRESS + \ + index * IN_FLOW_IPV6_5TUPLE_TBL_INC, + value->val, + 9); +} + +sw_error_t +hppe_in_flow_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union in_flow_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_ADDRESS + \ + index * IN_FLOW_TBL_INC, + value->val, + 5); +} + +sw_error_t +hppe_in_flow_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union in_flow_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_ADDRESS + \ + index * IN_FLOW_TBL_INC, + value->val, + 5); +} + +sw_error_t +hppe_eg_flow_tree_map_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union eg_flow_tree_map_tbl_u *value) +{ + if (index >= EG_FLOW_TREE_MAP_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_PTX_CSR_BASE_ADDR + EG_FLOW_TREE_MAP_TBL_ADDRESS + \ + index * EG_FLOW_TREE_MAP_TBL_INC, + &value->val); +} + +sw_error_t +hppe_eg_flow_tree_map_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union eg_flow_tree_map_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_PTX_CSR_BASE_ADDR + EG_FLOW_TREE_MAP_TBL_ADDRESS + \ + index * EG_FLOW_TREE_MAP_TBL_INC, + value->val); +} + +sw_error_t +hppe_flow_ctrl0_flow_hash_mode_0_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_ctrl0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl0_get(dev_id, ®_val); + *value = reg_val.bf.flow_hash_mode_0; + return ret; +} + +sw_error_t +hppe_flow_ctrl0_flow_hash_mode_0_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union flow_ctrl0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl0_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_hash_mode_0 = value; + ret = hppe_flow_ctrl0_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_flow_ctrl0_flow_age_timer_unit_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_ctrl0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl0_get(dev_id, ®_val); + *value = reg_val.bf.flow_age_timer_unit; + return ret; +} + +sw_error_t +hppe_flow_ctrl0_flow_age_timer_unit_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union flow_ctrl0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl0_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_age_timer_unit = value; + ret = hppe_flow_ctrl0_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_flow_ctrl0_flow_hash_mode_1_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_ctrl0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl0_get(dev_id, ®_val); + *value = reg_val.bf.flow_hash_mode_1; + return ret; +} + +sw_error_t +hppe_flow_ctrl0_flow_hash_mode_1_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union flow_ctrl0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl0_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_hash_mode_1 = value; + ret = hppe_flow_ctrl0_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_flow_ctrl0_flow_age_timer_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_ctrl0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl0_get(dev_id, ®_val); + *value = reg_val.bf.flow_age_timer; + return ret; +} + +sw_error_t +hppe_flow_ctrl0_flow_age_timer_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union flow_ctrl0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl0_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_age_timer = value; + ret = hppe_flow_ctrl0_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_flow_ctrl0_flow_en_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_ctrl0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl0_get(dev_id, ®_val); + *value = reg_val.bf.flow_en; + return ret; +} + +sw_error_t +hppe_flow_ctrl0_flow_en_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union flow_ctrl0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl0_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_en = value; + ret = hppe_flow_ctrl0_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl1_frag_bypass_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.flow_ctl1_frag_bypass; + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl1_frag_bypass_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_ctl1_frag_bypass = value; + ret = hppe_flow_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl4_key_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.flow_ctl4_key_sel; + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl4_key_sel_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_ctl4_key_sel = value; + ret = hppe_flow_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl1_key_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.flow_ctl1_key_sel; + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl1_key_sel_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_ctl1_key_sel = value; + ret = hppe_flow_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl0_frag_bypass_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.flow_ctl0_frag_bypass; + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl0_frag_bypass_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_ctl0_frag_bypass = value; + ret = hppe_flow_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl0_miss_action_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.flow_ctl0_miss_action; + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl0_miss_action_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_ctl0_miss_action = value; + ret = hppe_flow_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl0_key_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.flow_ctl0_key_sel; + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl0_key_sel_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_ctl0_key_sel = value; + ret = hppe_flow_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl1_bypass_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.flow_ctl1_bypass; + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl1_bypass_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_ctl1_bypass = value; + ret = hppe_flow_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl0_bypass_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.flow_ctl0_bypass; + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl0_bypass_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_ctl0_bypass = value; + ret = hppe_flow_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl2_tcp_special_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.flow_ctl2_tcp_special; + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl2_tcp_special_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_ctl2_tcp_special = value; + ret = hppe_flow_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl4_tcp_special_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.flow_ctl4_tcp_special; + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl4_tcp_special_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_ctl4_tcp_special = value; + ret = hppe_flow_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl3_frag_bypass_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.flow_ctl3_frag_bypass; + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl3_frag_bypass_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_ctl3_frag_bypass = value; + ret = hppe_flow_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl3_bypass_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.flow_ctl3_bypass; + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl3_bypass_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_ctl3_bypass = value; + ret = hppe_flow_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl3_tcp_special_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.flow_ctl3_tcp_special; + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl3_tcp_special_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_ctl3_tcp_special = value; + ret = hppe_flow_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl1_miss_action_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.flow_ctl1_miss_action; + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl1_miss_action_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_ctl1_miss_action = value; + ret = hppe_flow_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl4_frag_bypass_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.flow_ctl4_frag_bypass; + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl4_frag_bypass_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_ctl4_frag_bypass = value; + ret = hppe_flow_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl1_tcp_special_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.flow_ctl1_tcp_special; + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl1_tcp_special_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_ctl1_tcp_special = value; + ret = hppe_flow_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl2_key_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.flow_ctl2_key_sel; + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl2_key_sel_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_ctl2_key_sel = value; + ret = hppe_flow_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl2_miss_action_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.flow_ctl2_miss_action; + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl2_miss_action_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_ctl2_miss_action = value; + ret = hppe_flow_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl2_bypass_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.flow_ctl2_bypass; + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl2_bypass_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_ctl2_bypass = value; + ret = hppe_flow_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl4_bypass_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.flow_ctl4_bypass; + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl4_bypass_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_ctl4_bypass = value; + ret = hppe_flow_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl3_key_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.flow_ctl3_key_sel; + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl3_key_sel_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_ctl3_key_sel = value; + ret = hppe_flow_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl0_tcp_special_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.flow_ctl0_tcp_special; + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl0_tcp_special_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_ctl0_tcp_special = value; + ret = hppe_flow_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl2_frag_bypass_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.flow_ctl2_frag_bypass; + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl2_frag_bypass_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_ctl2_frag_bypass = value; + ret = hppe_flow_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl3_miss_action_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.flow_ctl3_miss_action; + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl3_miss_action_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_ctl3_miss_action = value; + ret = hppe_flow_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl4_miss_action_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.flow_ctl4_miss_action; + return ret; +} + +sw_error_t +hppe_flow_ctrl1_flow_ctl4_miss_action_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union flow_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_ctl4_miss_action = value; + ret = hppe_flow_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_entry_index_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_get(dev_id, ®_val); + *value = reg_val.bf.entry_index; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_entry_index_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.entry_index = value; + ret = hppe_in_flow_tbl_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_cmd_id_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_get(dev_id, ®_val); + *value = reg_val.bf.cmd_id; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_cmd_id_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmd_id = value; + ret = hppe_in_flow_tbl_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_byp_rslt_en_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_get(dev_id, ®_val); + *value = reg_val.bf.byp_rslt_en; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_byp_rslt_en_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.byp_rslt_en = value; + ret = hppe_in_flow_tbl_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_op_mode_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_get(dev_id, ®_val); + *value = reg_val.bf.op_mode; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_op_mode_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.op_mode = value; + ret = hppe_in_flow_tbl_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_op_type_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_get(dev_id, ®_val); + *value = reg_val.bf.op_type; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_op_type_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.op_type = value; + ret = hppe_in_flow_tbl_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_op_host_en_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_get(dev_id, ®_val); + *value = reg_val.bf.op_host_en; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_op_host_en_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.op_host_en = value; + ret = hppe_in_flow_tbl_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_op_result_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_get(dev_id, ®_val); + *value = reg_val.bf.op_result; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_op_result_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.op_result = value; + ret = hppe_in_flow_tbl_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_busy_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_get(dev_id, ®_val); + *value = reg_val.bf.busy; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_busy_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.busy = value; + ret = hppe_in_flow_tbl_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_hash_block_bitmap_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_get(dev_id, ®_val); + *value = reg_val.bf.hash_block_bitmap; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_hash_block_bitmap_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.hash_block_bitmap = value; + ret = hppe_in_flow_tbl_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_host_tbl_op_host_entry_index_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_host_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_host_tbl_op_get(dev_id, ®_val); + *value = reg_val.bf.host_entry_index; + return ret; +} + +sw_error_t +hppe_in_flow_host_tbl_op_host_entry_index_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_host_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_host_tbl_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.host_entry_index = value; + ret = hppe_in_flow_host_tbl_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_host_tbl_op_hash_block_bitmap_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_host_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_host_tbl_op_get(dev_id, ®_val); + *value = reg_val.bf.hash_block_bitmap; + return ret; +} + +sw_error_t +hppe_in_flow_host_tbl_op_hash_block_bitmap_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_host_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_host_tbl_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.hash_block_bitmap = value; + ret = hppe_in_flow_host_tbl_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_data0_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_op_data0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_data0_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_data0_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_op_data0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_data0_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_in_flow_tbl_op_data0_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_data1_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_op_data1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_data1_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_data1_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_op_data1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_data1_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_in_flow_tbl_op_data1_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_data2_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_op_data2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_data2_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_data2_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_op_data2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_data2_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_in_flow_tbl_op_data2_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_data3_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_op_data3_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_data3_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_data3_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_op_data3_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_data3_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_in_flow_tbl_op_data3_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_data4_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_op_data4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_data4_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_data4_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_op_data4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_data4_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_in_flow_tbl_op_data4_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_data5_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_op_data5_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_data5_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_data5_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_op_data5_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_data5_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_in_flow_tbl_op_data5_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_data6_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_op_data6_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_data6_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_data6_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_op_data6_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_data6_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_in_flow_tbl_op_data6_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_data7_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_op_data7_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_data7_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_data7_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_op_data7_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_data7_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_in_flow_tbl_op_data7_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_data8_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_op_data8_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_data8_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_data8_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_op_data8_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_data8_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_in_flow_tbl_op_data8_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_flow_host_tbl_op_data0_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_host_tbl_op_data0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_op_data0_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_flow_host_tbl_op_data0_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union flow_host_tbl_op_data0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_op_data0_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_flow_host_tbl_op_data0_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_flow_host_tbl_op_data1_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_host_tbl_op_data1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_op_data1_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_flow_host_tbl_op_data1_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union flow_host_tbl_op_data1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_op_data1_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_flow_host_tbl_op_data1_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_flow_host_tbl_op_data2_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_host_tbl_op_data2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_op_data2_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_flow_host_tbl_op_data2_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union flow_host_tbl_op_data2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_op_data2_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_flow_host_tbl_op_data2_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_flow_host_tbl_op_data3_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_host_tbl_op_data3_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_op_data3_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_flow_host_tbl_op_data3_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union flow_host_tbl_op_data3_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_op_data3_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_flow_host_tbl_op_data3_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_flow_host_tbl_op_data4_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_host_tbl_op_data4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_op_data4_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_flow_host_tbl_op_data4_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union flow_host_tbl_op_data4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_op_data4_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_flow_host_tbl_op_data4_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_flow_host_tbl_op_data5_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_host_tbl_op_data5_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_op_data5_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_flow_host_tbl_op_data5_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union flow_host_tbl_op_data5_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_op_data5_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_flow_host_tbl_op_data5_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_flow_host_tbl_op_data6_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_host_tbl_op_data6_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_op_data6_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_flow_host_tbl_op_data6_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union flow_host_tbl_op_data6_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_op_data6_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_flow_host_tbl_op_data6_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_flow_host_tbl_op_data7_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_host_tbl_op_data7_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_op_data7_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_flow_host_tbl_op_data7_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union flow_host_tbl_op_data7_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_op_data7_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_flow_host_tbl_op_data7_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_flow_host_tbl_op_data8_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_host_tbl_op_data8_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_op_data8_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_flow_host_tbl_op_data8_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union flow_host_tbl_op_data8_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_op_data8_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_flow_host_tbl_op_data8_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_flow_host_tbl_op_data9_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_host_tbl_op_data9_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_op_data9_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_flow_host_tbl_op_data9_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union flow_host_tbl_op_data9_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_op_data9_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_flow_host_tbl_op_data9_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_rslt_op_rslt_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_op_rslt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_rslt_get(dev_id, ®_val); + *value = reg_val.bf.op_rslt; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_rslt_op_rslt_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_in_flow_tbl_op_rslt_valid_cnt_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_op_rslt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_rslt_get(dev_id, ®_val); + *value = reg_val.bf.valid_cnt; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_rslt_valid_cnt_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_in_flow_tbl_op_rslt_flow_entry_index_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_op_rslt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_rslt_get(dev_id, ®_val); + *value = reg_val.bf.flow_entry_index; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_rslt_flow_entry_index_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_in_flow_tbl_op_rslt_cmd_id_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_op_rslt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_op_rslt_get(dev_id, ®_val); + *value = reg_val.bf.cmd_id; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_op_rslt_cmd_id_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_flow_host_tbl_op_rslt_host_entry_index_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_host_tbl_op_rslt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_op_rslt_get(dev_id, ®_val); + *value = reg_val.bf.host_entry_index; + return ret; +} + +sw_error_t +hppe_flow_host_tbl_op_rslt_host_entry_index_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_entry_index_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_get(dev_id, ®_val); + *value = reg_val.bf.entry_index; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_entry_index_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.entry_index = value; + ret = hppe_in_flow_tbl_rd_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_cmd_id_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_get(dev_id, ®_val); + *value = reg_val.bf.cmd_id; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_cmd_id_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmd_id = value; + ret = hppe_in_flow_tbl_rd_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_byp_rslt_en_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_get(dev_id, ®_val); + *value = reg_val.bf.byp_rslt_en; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_byp_rslt_en_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.byp_rslt_en = value; + ret = hppe_in_flow_tbl_rd_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_op_mode_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_get(dev_id, ®_val); + *value = reg_val.bf.op_mode; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_op_mode_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.op_mode = value; + ret = hppe_in_flow_tbl_rd_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_op_type_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_get(dev_id, ®_val); + *value = reg_val.bf.op_type; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_op_type_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.op_type = value; + ret = hppe_in_flow_tbl_rd_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_op_host_en_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_get(dev_id, ®_val); + *value = reg_val.bf.op_host_en; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_op_host_en_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.op_host_en = value; + ret = hppe_in_flow_tbl_rd_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_op_result_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_get(dev_id, ®_val); + *value = reg_val.bf.op_result; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_op_result_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.op_result = value; + ret = hppe_in_flow_tbl_rd_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_busy_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_get(dev_id, ®_val); + *value = reg_val.bf.busy; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_busy_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.busy = value; + ret = hppe_in_flow_tbl_rd_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_hash_block_bitmap_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_get(dev_id, ®_val); + *value = reg_val.bf.hash_block_bitmap; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_hash_block_bitmap_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.hash_block_bitmap = value; + ret = hppe_in_flow_tbl_rd_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_host_tbl_rd_op_host_entry_index_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_host_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_host_tbl_rd_op_get(dev_id, ®_val); + *value = reg_val.bf.host_entry_index; + return ret; +} + +sw_error_t +hppe_in_flow_host_tbl_rd_op_host_entry_index_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_host_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_host_tbl_rd_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.host_entry_index = value; + ret = hppe_in_flow_host_tbl_rd_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_host_tbl_rd_op_hash_block_bitmap_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_host_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_host_tbl_rd_op_get(dev_id, ®_val); + *value = reg_val.bf.hash_block_bitmap; + return ret; +} + +sw_error_t +hppe_in_flow_host_tbl_rd_op_hash_block_bitmap_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_host_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_host_tbl_rd_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.hash_block_bitmap = value; + ret = hppe_in_flow_host_tbl_rd_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data0_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_rd_op_data0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_data0_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data0_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_rd_op_data0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_data0_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_in_flow_tbl_rd_op_data0_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data1_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_rd_op_data1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_data1_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data1_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_rd_op_data1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_data1_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_in_flow_tbl_rd_op_data1_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data2_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_rd_op_data2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_data2_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data2_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_rd_op_data2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_data2_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_in_flow_tbl_rd_op_data2_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data3_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_rd_op_data3_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_data3_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data3_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_rd_op_data3_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_data3_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_in_flow_tbl_rd_op_data3_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data4_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_rd_op_data4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_data4_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data4_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_rd_op_data4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_data4_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_in_flow_tbl_rd_op_data4_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data5_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_rd_op_data5_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_data5_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data5_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_rd_op_data5_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_data5_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_in_flow_tbl_rd_op_data5_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data6_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_rd_op_data6_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_data6_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data6_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_rd_op_data6_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_data6_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_in_flow_tbl_rd_op_data6_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data7_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_rd_op_data7_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_data7_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data7_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_rd_op_data7_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_data7_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_in_flow_tbl_rd_op_data7_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data8_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_rd_op_data8_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_data8_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_data8_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_flow_tbl_rd_op_data8_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_data8_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_in_flow_tbl_rd_op_data8_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data0_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_host_tbl_rd_op_data0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_rd_op_data0_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data0_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union flow_host_tbl_rd_op_data0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_rd_op_data0_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_flow_host_tbl_rd_op_data0_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data1_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_host_tbl_rd_op_data1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_rd_op_data1_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data1_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union flow_host_tbl_rd_op_data1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_rd_op_data1_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_flow_host_tbl_rd_op_data1_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data2_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_host_tbl_rd_op_data2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_rd_op_data2_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data2_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union flow_host_tbl_rd_op_data2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_rd_op_data2_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_flow_host_tbl_rd_op_data2_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data3_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_host_tbl_rd_op_data3_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_rd_op_data3_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data3_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union flow_host_tbl_rd_op_data3_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_rd_op_data3_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_flow_host_tbl_rd_op_data3_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data4_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_host_tbl_rd_op_data4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_rd_op_data4_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data4_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union flow_host_tbl_rd_op_data4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_rd_op_data4_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_flow_host_tbl_rd_op_data4_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data5_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_host_tbl_rd_op_data5_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_rd_op_data5_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data5_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union flow_host_tbl_rd_op_data5_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_rd_op_data5_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_flow_host_tbl_rd_op_data5_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data6_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_host_tbl_rd_op_data6_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_rd_op_data6_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data6_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union flow_host_tbl_rd_op_data6_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_rd_op_data6_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_flow_host_tbl_rd_op_data6_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data7_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_host_tbl_rd_op_data7_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_rd_op_data7_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data7_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union flow_host_tbl_rd_op_data7_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_rd_op_data7_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_flow_host_tbl_rd_op_data7_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data8_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_host_tbl_rd_op_data8_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_rd_op_data8_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data8_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union flow_host_tbl_rd_op_data8_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_rd_op_data8_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_flow_host_tbl_rd_op_data8_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data9_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_host_tbl_rd_op_data9_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_rd_op_data9_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_flow_host_tbl_rd_op_data9_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union flow_host_tbl_rd_op_data9_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_rd_op_data9_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_flow_host_tbl_rd_op_data9_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_rslt_op_rslt_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_rd_op_rslt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_rslt_get(dev_id, ®_val); + *value = reg_val.bf.op_rslt; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_rslt_op_rslt_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_rslt_valid_cnt_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_rd_op_rslt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_rslt_get(dev_id, ®_val); + *value = reg_val.bf.valid_cnt; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_rslt_valid_cnt_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_rslt_flow_entry_index_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_rd_op_rslt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_rslt_get(dev_id, ®_val); + *value = reg_val.bf.flow_entry_index; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_rslt_flow_entry_index_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_rslt_cmd_id_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_rd_op_rslt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_op_rslt_get(dev_id, ®_val); + *value = reg_val.bf.cmd_id; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_op_rslt_cmd_id_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_flow_host_tbl_rd_op_rslt_host_entry_index_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_host_tbl_rd_op_rslt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_rd_op_rslt_get(dev_id, ®_val); + *value = reg_val.bf.host_entry_index; + return ret; +} + +sw_error_t +hppe_flow_host_tbl_rd_op_rslt_host_entry_index_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data0_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_rd_rslt_data0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_rslt_data0_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data0_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data1_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_rd_rslt_data1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_rslt_data1_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data1_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data2_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_rd_rslt_data2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_rslt_data2_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data2_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data3_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_rd_rslt_data3_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_rslt_data3_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data3_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data4_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_rd_rslt_data4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_rslt_data4_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data4_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data5_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_rd_rslt_data5_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_rslt_data5_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data5_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data6_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_rd_rslt_data6_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_rslt_data6_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data6_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data7_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_rd_rslt_data7_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_rslt_data7_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data7_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data8_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_flow_tbl_rd_rslt_data8_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_tbl_rd_rslt_data8_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_in_flow_tbl_rd_rslt_data8_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data0_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_host_tbl_rd_rslt_data0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_rd_rslt_data0_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data0_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data1_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_host_tbl_rd_rslt_data1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_rd_rslt_data1_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data1_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data2_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_host_tbl_rd_rslt_data2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_rd_rslt_data2_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data2_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data3_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_host_tbl_rd_rslt_data3_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_rd_rslt_data3_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data3_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data4_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_host_tbl_rd_rslt_data4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_rd_rslt_data4_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data4_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data5_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_host_tbl_rd_rslt_data5_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_rd_rslt_data5_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data5_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data6_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_host_tbl_rd_rslt_data6_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_rd_rslt_data6_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data6_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data7_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_host_tbl_rd_rslt_data7_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_rd_rslt_data7_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data7_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data8_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_host_tbl_rd_rslt_data8_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_rd_rslt_data8_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data8_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data9_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flow_host_tbl_rd_rslt_data9_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_host_tbl_rd_rslt_data9_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_flow_host_tbl_rd_rslt_data9_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_eg_flow_tree_map_tbl_tree_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_flow_tree_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_flow_tree_map_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.tree_id; + return ret; +} + +sw_error_t +hppe_eg_flow_tree_map_tbl_tree_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_flow_tree_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_flow_tree_map_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tree_id = value; + ret = hppe_eg_flow_tree_map_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_cnt_tbl_hit_byte_counter_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union in_flow_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_cnt_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.hit_byte_counter_1 << 32 | \ + reg_val.bf.hit_byte_counter_0; + return ret; +} + +sw_error_t +hppe_in_flow_cnt_tbl_hit_byte_counter_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union in_flow_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.hit_byte_counter_1 = value >> 32; + reg_val.bf.hit_byte_counter_0 = value & (((a_uint64_t)1<<32)-1); + ret = hppe_in_flow_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_flow_cnt_tbl_hit_pkt_counter_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_flow_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_cnt_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.hit_pkt_counter; + return ret; +} + +sw_error_t +hppe_in_flow_cnt_tbl_hit_pkt_counter_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_flow_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_flow_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.hit_pkt_counter = value; + ret = hppe_in_flow_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + + +sw_error_t +hppe_flow_get_common( + a_uint32_t dev_id, + a_uint32_t op_mode, + a_uint32_t *index, + a_uint32_t *data, + a_uint32_t num) +{ + union in_flow_tbl_rd_op_u op; + union in_flow_tbl_rd_op_rslt_u result; + a_uint32_t i = 0x100; + sw_error_t rv; + + op.bf.cmd_id = flow_cmd_id; + flow_cmd_id++; + op.bf.byp_rslt_en = 0; + op.bf.op_type = 2; + op.bf.hash_block_bitmap = 3; + op.bf.op_mode = op_mode; + op.bf.entry_index = *index; + op.bf.op_host_en = 0; + + rv = hppe_in_flow_tbl_rd_op_set(dev_id, &op); + if (SW_OK != rv) + return rv; + rv = hppe_in_flow_tbl_rd_op_rslt_get(dev_id, &result); + if (SW_OK != rv) + return rv; + while (!result.bf.valid_cnt && --i) { + hppe_in_flow_tbl_rd_op_rslt_get(dev_id, &result); + } + if (i == 0) + return SW_BUSY; + if (result.bf.op_rslt == 0) { + hppe_reg_tbl_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_RD_RSLT_DATA0_ADDRESS, + data, num); + *index = result.bf.flow_entry_index; + return SW_OK; + } + else + return SW_FAIL; + +} + + +sw_error_t +hppe_flow_flush_common(a_uint32_t dev_id) +{ + union in_flow_tbl_op_u op; + union in_flow_tbl_op_rslt_u result; + a_uint32_t i = 0x100 * 50; + sw_error_t rv; + + op.bf.cmd_id = flow_cmd_id; + flow_cmd_id++; + op.bf.byp_rslt_en = 0; + op.bf.op_type = 3; + op.bf.hash_block_bitmap = 3; + op.bf.op_mode = 0; + op.bf.op_host_en = 0; + + rv = hppe_in_flow_tbl_op_set(dev_id, &op); + if (SW_OK != rv) + return rv; + rv = hppe_in_flow_tbl_op_rslt_get(dev_id, &result); + if (SW_OK != rv) + return rv; + while (!result.bf.valid_cnt && --i) { + hppe_in_flow_tbl_op_rslt_get(dev_id, &result); + } + if (i == 0) + return SW_BUSY; + if (result.bf.op_rslt == 0) + return SW_OK; + else + return SW_FAIL; + + +} + +sw_error_t +hppe_flow_op_common( + a_uint32_t dev_id, + a_uint32_t op_type, + a_uint32_t op_mode, + a_uint32_t *index) +{ + union in_flow_tbl_op_u op; + union in_flow_tbl_op_rslt_u result; + a_uint32_t i = 0x100; + sw_error_t rv; + + op.bf.cmd_id = flow_cmd_id; + flow_cmd_id++; + op.bf.byp_rslt_en = 0; + op.bf.op_type = op_type; + op.bf.hash_block_bitmap = 3; + op.bf.op_mode = op_mode; + op.bf.entry_index = *index; + op.bf.op_host_en = 0; + + rv = hppe_in_flow_tbl_op_set(dev_id, &op); + if (SW_OK != rv) + return rv; + rv = hppe_in_flow_tbl_op_rslt_get(dev_id, &result); + if (SW_OK != rv) + return rv; + while (!result.bf.valid_cnt && --i) { + hppe_in_flow_tbl_op_rslt_get(dev_id, &result); + } + if (i == 0) + return SW_BUSY; + if (result.bf.op_rslt == 0) { + *index = result.bf.flow_entry_index; + return SW_OK; + } + else + return SW_FAIL; + +} + +#include "hppe_ip_reg.h" + +sw_error_t +hppe_flow_host_get_common( + a_uint32_t dev_id, + a_uint32_t op_mode, + a_uint32_t *index, + a_uint32_t *data, + a_uint32_t num) +{ + union in_flow_tbl_rd_op_u op; + union in_flow_tbl_rd_op_rslt_u result; + a_uint32_t i = 0x100; + sw_error_t rv; + + op.bf.cmd_id = flow_host_cmd_id; + flow_host_cmd_id++; + op.bf.byp_rslt_en = 0; + op.bf.op_type = 2; + op.bf.hash_block_bitmap = 3; + op.bf.op_mode = op_mode; + op.bf.entry_index = *index; + op.bf.op_host_en = 1; + + rv = hppe_in_flow_tbl_rd_op_set(dev_id, &op); + if (SW_OK != rv) + return rv; + rv = hppe_in_flow_tbl_rd_op_rslt_get(dev_id, &result); + if (SW_OK != rv) + return rv; + while (!result.bf.valid_cnt && --i) { + hppe_in_flow_tbl_rd_op_rslt_get(dev_id, &result); + } + if (i == 0) + return SW_BUSY; + + if (result.bf.op_rslt == 0) { + hppe_reg_tbl_get( + dev_id, + IPE_L3_BASE_ADDR + IN_FLOW_TBL_RD_RSLT_DATA0_ADDRESS, + data, num); + *index = result.bf.flow_entry_index; + return SW_OK; + } + else + return SW_FAIL; +} + +sw_error_t +hppe_flow_host_flush_common(a_uint32_t dev_id) +{ + union in_flow_tbl_op_u op; + union in_flow_tbl_op_rslt_u result; + a_uint32_t i = 0x100 * 50; + sw_error_t rv; + + op.bf.cmd_id = flow_host_cmd_id; + flow_host_cmd_id++; + op.bf.byp_rslt_en = 0; + op.bf.op_type = 3; + op.bf.hash_block_bitmap = 3; + op.bf.op_mode = 0; + op.bf.op_host_en = 1; + + rv = hppe_in_flow_tbl_op_set(dev_id, &op); + if (SW_OK != rv) + return rv; + rv = hppe_in_flow_tbl_op_rslt_get(dev_id, &result); + if (SW_OK != rv) + return rv; + while (!result.bf.valid_cnt && --i) { + hppe_in_flow_tbl_op_rslt_get(dev_id, &result); + } + if (i == 0) + return SW_BUSY; + if (result.bf.op_rslt == 0) + return SW_OK; + else + return SW_FAIL; +} + +sw_error_t +hppe_flow_host_op_both_common( + a_uint32_t dev_id, + a_uint32_t op_type, + a_uint32_t op_mode, + a_uint32_t *index) +{ + union in_flow_tbl_op_u op; + union in_flow_tbl_op_rslt_u result; + a_uint32_t i = 0x100; + sw_error_t rv; + + op.bf.cmd_id = flow_host_cmd_id; + flow_host_cmd_id++; + op.bf.byp_rslt_en = 0; + op.bf.op_type = op_type; + op.bf.hash_block_bitmap = 3; + op.bf.op_mode = op_mode; + op.bf.entry_index = *index; + op.bf.op_host_en = 1; + + rv = hppe_in_flow_tbl_op_set(dev_id, &op); + if (SW_OK != rv) + return rv; + rv = hppe_in_flow_tbl_op_rslt_get(dev_id, &result); + if (SW_OK != rv) + return rv; + while (!result.bf.valid_cnt && --i) { + hppe_in_flow_tbl_op_rslt_get(dev_id, &result); + } + if (i == 0) + return SW_BUSY; + if (result.bf.op_rslt == 0) { + *index = result.bf.flow_entry_index; + return SW_OK; + } + else + return SW_FAIL; +} + +sw_error_t +hppe_flow_entry_host_op_ipv4_5tuple_add( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_tbl_u *entry) +{ + hppe_in_flow_tbl_op_data0_set(dev_id, (union in_flow_tbl_op_data0_u *)(&entry->val[0])); + hppe_in_flow_tbl_op_data1_set(dev_id, (union in_flow_tbl_op_data1_u *)(&entry->val[1])); + hppe_in_flow_tbl_op_data2_set(dev_id, (union in_flow_tbl_op_data2_u *)(&entry->val[2])); + hppe_in_flow_tbl_op_data3_set(dev_id, (union in_flow_tbl_op_data3_u *)(&entry->val[3])); + hppe_in_flow_tbl_op_data4_set(dev_id, (union in_flow_tbl_op_data4_u *)(&entry->val[4])); + return hppe_flow_host_op_both_common(dev_id, 0, op_mode, index); +} + +sw_error_t +hppe_flow_entry_host_op_ipv4_3tuple_add( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_3tuple_tbl_u *entry) +{ + hppe_in_flow_tbl_op_data0_set(dev_id, (union in_flow_tbl_op_data0_u *)(&entry->val[0])); + hppe_in_flow_tbl_op_data1_set(dev_id, (union in_flow_tbl_op_data1_u *)(&entry->val[1])); + hppe_in_flow_tbl_op_data2_set(dev_id, (union in_flow_tbl_op_data2_u *)(&entry->val[2])); + hppe_in_flow_tbl_op_data3_set(dev_id, (union in_flow_tbl_op_data3_u *)(&entry->val[3])); + hppe_in_flow_tbl_op_data4_set(dev_id, (union in_flow_tbl_op_data4_u *)(&entry->val[4])); + return hppe_flow_host_op_both_common(dev_id, 0, op_mode, index); +} + +sw_error_t +hppe_flow_entry_host_op_ipv6_5tuple_add( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_ipv6_5tuple_tbl_u *entry) +{ + hppe_in_flow_tbl_op_data0_set(dev_id, (union in_flow_tbl_op_data0_u *)(&entry->val[0])); + hppe_in_flow_tbl_op_data1_set(dev_id, (union in_flow_tbl_op_data1_u *)(&entry->val[1])); + hppe_in_flow_tbl_op_data2_set(dev_id, (union in_flow_tbl_op_data2_u *)(&entry->val[2])); + hppe_in_flow_tbl_op_data3_set(dev_id, (union in_flow_tbl_op_data3_u *)(&entry->val[3])); + hppe_in_flow_tbl_op_data4_set(dev_id, (union in_flow_tbl_op_data4_u *)(&entry->val[4])); + hppe_in_flow_tbl_op_data5_set(dev_id, (union in_flow_tbl_op_data5_u *)(&entry->val[5])); + hppe_in_flow_tbl_op_data6_set(dev_id, (union in_flow_tbl_op_data6_u *)(&entry->val[6])); + hppe_in_flow_tbl_op_data7_set(dev_id, (union in_flow_tbl_op_data7_u *)(&entry->val[7])); + hppe_in_flow_tbl_op_data8_set(dev_id, (union in_flow_tbl_op_data8_u *)(&entry->val[8])); + return hppe_flow_host_op_both_common(dev_id, 0, op_mode, index); +} + +sw_error_t +hppe_flow_entry_host_op_ipv6_3tuple_add( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_ipv6_3tuple_tbl_u *entry) +{ + hppe_in_flow_tbl_op_data0_set(dev_id, (union in_flow_tbl_op_data0_u *)(&entry->val[0])); + hppe_in_flow_tbl_op_data1_set(dev_id, (union in_flow_tbl_op_data1_u *)(&entry->val[1])); + hppe_in_flow_tbl_op_data2_set(dev_id, (union in_flow_tbl_op_data2_u *)(&entry->val[2])); + hppe_in_flow_tbl_op_data3_set(dev_id, (union in_flow_tbl_op_data3_u *)(&entry->val[3])); + hppe_in_flow_tbl_op_data4_set(dev_id, (union in_flow_tbl_op_data4_u *)(&entry->val[4])); + hppe_in_flow_tbl_op_data5_set(dev_id, (union in_flow_tbl_op_data5_u *)(&entry->val[5])); + hppe_in_flow_tbl_op_data6_set(dev_id, (union in_flow_tbl_op_data6_u *)(&entry->val[6])); + hppe_in_flow_tbl_op_data7_set(dev_id, (union in_flow_tbl_op_data7_u *)(&entry->val[7])); + hppe_in_flow_tbl_op_data8_set(dev_id, (union in_flow_tbl_op_data8_u *)(&entry->val[8])); + return hppe_flow_host_op_both_common(dev_id, 0, op_mode, index); +} + +sw_error_t +hppe_flow_entry_host_op_ipv4_5tuple_del( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_tbl_u *entry) +{ + if (op_mode == 0) { + hppe_in_flow_tbl_op_data0_set(dev_id, (union in_flow_tbl_op_data0_u *)(&entry->val[0])); + hppe_in_flow_tbl_op_data1_set(dev_id, (union in_flow_tbl_op_data1_u *)(&entry->val[1])); + hppe_in_flow_tbl_op_data2_set(dev_id, (union in_flow_tbl_op_data2_u *)(&entry->val[2])); + hppe_in_flow_tbl_op_data3_set(dev_id, (union in_flow_tbl_op_data3_u *)(&entry->val[3])); + hppe_in_flow_tbl_op_data4_set(dev_id, (union in_flow_tbl_op_data4_u *)(&entry->val[4])); + } + return hppe_flow_host_op_both_common(dev_id, 1, op_mode, index); +} + +sw_error_t +hppe_flow_entry_host_op_ipv4_3tuple_del( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_3tuple_tbl_u *entry) +{ + if (op_mode == 0) { + hppe_in_flow_tbl_op_data0_set(dev_id, (union in_flow_tbl_op_data0_u *)(&entry->val[0])); + hppe_in_flow_tbl_op_data1_set(dev_id, (union in_flow_tbl_op_data1_u *)(&entry->val[1])); + hppe_in_flow_tbl_op_data2_set(dev_id, (union in_flow_tbl_op_data2_u *)(&entry->val[2])); + hppe_in_flow_tbl_op_data3_set(dev_id, (union in_flow_tbl_op_data3_u *)(&entry->val[3])); + hppe_in_flow_tbl_op_data4_set(dev_id, (union in_flow_tbl_op_data4_u *)(&entry->val[4])); + } + return hppe_flow_host_op_both_common(dev_id, 1, op_mode, index); +} + +sw_error_t +hppe_flow_entry_host_op_ipv6_5tuple_del( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_ipv6_5tuple_tbl_u *entry) +{ + if (op_mode == 0) { + hppe_in_flow_tbl_op_data0_set(dev_id, (union in_flow_tbl_op_data0_u *)(&entry->val[0])); + hppe_in_flow_tbl_op_data1_set(dev_id, (union in_flow_tbl_op_data1_u *)(&entry->val[1])); + hppe_in_flow_tbl_op_data2_set(dev_id, (union in_flow_tbl_op_data2_u *)(&entry->val[2])); + hppe_in_flow_tbl_op_data3_set(dev_id, (union in_flow_tbl_op_data3_u *)(&entry->val[3])); + hppe_in_flow_tbl_op_data4_set(dev_id, (union in_flow_tbl_op_data4_u *)(&entry->val[4])); + hppe_in_flow_tbl_op_data5_set(dev_id, (union in_flow_tbl_op_data5_u *)(&entry->val[5])); + hppe_in_flow_tbl_op_data6_set(dev_id, (union in_flow_tbl_op_data6_u *)(&entry->val[6])); + hppe_in_flow_tbl_op_data7_set(dev_id, (union in_flow_tbl_op_data7_u *)(&entry->val[7])); + hppe_in_flow_tbl_op_data8_set(dev_id, (union in_flow_tbl_op_data8_u *)(&entry->val[8])); + } + return hppe_flow_host_op_both_common(dev_id, 1, op_mode, index); +} + +sw_error_t +hppe_flow_entry_host_op_ipv6_3tuple_del( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_ipv6_3tuple_tbl_u *entry) +{ + if (op_mode == 0) { + hppe_in_flow_tbl_op_data0_set(dev_id, (union in_flow_tbl_op_data0_u *)(&entry->val[0])); + hppe_in_flow_tbl_op_data1_set(dev_id, (union in_flow_tbl_op_data1_u *)(&entry->val[1])); + hppe_in_flow_tbl_op_data2_set(dev_id, (union in_flow_tbl_op_data2_u *)(&entry->val[2])); + hppe_in_flow_tbl_op_data3_set(dev_id, (union in_flow_tbl_op_data3_u *)(&entry->val[3])); + hppe_in_flow_tbl_op_data4_set(dev_id, (union in_flow_tbl_op_data4_u *)(&entry->val[4])); + hppe_in_flow_tbl_op_data5_set(dev_id, (union in_flow_tbl_op_data5_u *)(&entry->val[5])); + hppe_in_flow_tbl_op_data6_set(dev_id, (union in_flow_tbl_op_data6_u *)(&entry->val[6])); + hppe_in_flow_tbl_op_data7_set(dev_id, (union in_flow_tbl_op_data7_u *)(&entry->val[7])); + hppe_in_flow_tbl_op_data8_set(dev_id, (union in_flow_tbl_op_data8_u *)(&entry->val[8])); + } + return hppe_flow_host_op_both_common(dev_id, 1, op_mode, index); +} + +sw_error_t +hppe_flow_entry_host_op_ipv4_5tuple_get( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_tbl_u *entry) +{ + if (op_mode == 0) { + hppe_in_flow_tbl_rd_op_data0_set(dev_id, (union in_flow_tbl_rd_op_data0_u *)(&entry->val[0])); + hppe_in_flow_tbl_rd_op_data1_set(dev_id, (union in_flow_tbl_rd_op_data1_u *)(&entry->val[1])); + hppe_in_flow_tbl_rd_op_data2_set(dev_id, (union in_flow_tbl_rd_op_data2_u *)(&entry->val[2])); + hppe_in_flow_tbl_rd_op_data3_set(dev_id, (union in_flow_tbl_rd_op_data3_u *)(&entry->val[3])); + hppe_in_flow_tbl_rd_op_data4_set(dev_id, (union in_flow_tbl_rd_op_data4_u *)(&entry->val[4])); + } + return hppe_flow_host_get_common(dev_id, op_mode, index, (a_uint32_t *)entry, 5); +} + +sw_error_t +hppe_flow_entry_host_op_ipv4_3tuple_get( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_3tuple_tbl_u *entry) +{ + if (op_mode == 0) { + hppe_in_flow_tbl_rd_op_data0_set(dev_id, (union in_flow_tbl_rd_op_data0_u *)(&entry->val[0])); + hppe_in_flow_tbl_rd_op_data1_set(dev_id, (union in_flow_tbl_rd_op_data1_u *)(&entry->val[1])); + hppe_in_flow_tbl_rd_op_data2_set(dev_id, (union in_flow_tbl_rd_op_data2_u *)(&entry->val[2])); + hppe_in_flow_tbl_rd_op_data3_set(dev_id, (union in_flow_tbl_rd_op_data3_u *)(&entry->val[3])); + hppe_in_flow_tbl_rd_op_data4_set(dev_id, (union in_flow_tbl_rd_op_data4_u *)(&entry->val[4])); + } + return hppe_flow_host_get_common(dev_id, op_mode, index, (a_uint32_t *)entry, 5); +} + +sw_error_t +hppe_flow_entry_host_op_ipv6_5tuple_get( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_ipv6_5tuple_tbl_u *entry) +{ + if (op_mode == 0) { + hppe_in_flow_tbl_rd_op_data0_set(dev_id, (union in_flow_tbl_rd_op_data0_u *)(&entry->val[0])); + hppe_in_flow_tbl_rd_op_data1_set(dev_id, (union in_flow_tbl_rd_op_data1_u *)(&entry->val[1])); + hppe_in_flow_tbl_rd_op_data2_set(dev_id, (union in_flow_tbl_rd_op_data2_u *)(&entry->val[2])); + hppe_in_flow_tbl_rd_op_data3_set(dev_id, (union in_flow_tbl_rd_op_data3_u *)(&entry->val[3])); + hppe_in_flow_tbl_rd_op_data4_set(dev_id, (union in_flow_tbl_rd_op_data4_u *)(&entry->val[4])); + hppe_in_flow_tbl_rd_op_data5_set(dev_id, (union in_flow_tbl_rd_op_data5_u *)(&entry->val[5])); + hppe_in_flow_tbl_rd_op_data6_set(dev_id, (union in_flow_tbl_rd_op_data6_u *)(&entry->val[6])); + hppe_in_flow_tbl_rd_op_data7_set(dev_id, (union in_flow_tbl_rd_op_data7_u *)(&entry->val[7])); + hppe_in_flow_tbl_rd_op_data8_set(dev_id, (union in_flow_tbl_rd_op_data8_u *)(&entry->val[8])); + } + return hppe_flow_host_get_common(dev_id, op_mode, index, (a_uint32_t *)entry, 9); +} + +sw_error_t +hppe_flow_entry_host_op_ipv6_3tuple_get( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_ipv6_3tuple_tbl_u *entry) +{ + if (op_mode == 0) { + hppe_in_flow_tbl_rd_op_data0_set(dev_id, (union in_flow_tbl_rd_op_data0_u *)(&entry->val[0])); + hppe_in_flow_tbl_rd_op_data1_set(dev_id, (union in_flow_tbl_rd_op_data1_u *)(&entry->val[1])); + hppe_in_flow_tbl_rd_op_data2_set(dev_id, (union in_flow_tbl_rd_op_data2_u *)(&entry->val[2])); + hppe_in_flow_tbl_rd_op_data3_set(dev_id, (union in_flow_tbl_rd_op_data3_u *)(&entry->val[3])); + hppe_in_flow_tbl_rd_op_data4_set(dev_id, (union in_flow_tbl_rd_op_data4_u *)(&entry->val[4])); + hppe_in_flow_tbl_rd_op_data5_set(dev_id, (union in_flow_tbl_rd_op_data5_u *)(&entry->val[5])); + hppe_in_flow_tbl_rd_op_data6_set(dev_id, (union in_flow_tbl_rd_op_data6_u *)(&entry->val[6])); + hppe_in_flow_tbl_rd_op_data7_set(dev_id, (union in_flow_tbl_rd_op_data7_u *)(&entry->val[7])); + hppe_in_flow_tbl_rd_op_data8_set(dev_id, (union in_flow_tbl_rd_op_data8_u *)(&entry->val[8])); + } + return hppe_flow_host_get_common(dev_id, op_mode, index, (a_uint32_t *)entry, 9); +} + +sw_error_t +hppe_flow_host_data_op_common( + a_uint32_t dev_id, + a_uint32_t op_type, + a_uint32_t op_mode, + a_uint32_t *index) +{ + union in_flow_host_tbl_op_u op; + sw_error_t rv; + + op.bf.hash_block_bitmap = 3; + op.bf.host_entry_index = *index; + + rv = hppe_in_flow_host_tbl_op_set(dev_id, &op); + if (SW_OK != rv) + return rv; + + return SW_OK; +} + +sw_error_t +hppe_flow_host_data_rd_op_common( + a_uint32_t dev_id, + a_uint32_t op_type, + a_uint32_t op_mode, + a_uint32_t *index) +{ + union in_flow_host_tbl_rd_op_u op; + sw_error_t rv; + + op.bf.hash_block_bitmap = 3; + op.bf.host_entry_index = *index; + + rv = hppe_in_flow_host_tbl_rd_op_set(dev_id, &op); + if (SW_OK != rv) + return rv; + + return SW_OK; +} +sw_error_t +hppe_flow_host_ipv4_data_add( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_tbl_u *entry) +{ + hppe_flow_host_tbl_op_data0_set(dev_id, (union flow_host_tbl_op_data0_u *)(&entry->val[0])); + hppe_flow_host_tbl_op_data1_set(dev_id, (union flow_host_tbl_op_data1_u *)(&entry->val[1])); + hppe_flow_host_tbl_op_data2_set(dev_id, (union flow_host_tbl_op_data2_u *)(&entry->val[2])); + return hppe_flow_host_data_op_common(dev_id, 0, op_mode, index); +} + +sw_error_t +hppe_flow_host_ipv6_data_add( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_ipv6_tbl_u *entry) +{ + hppe_flow_host_tbl_op_data0_set(dev_id, (union flow_host_tbl_op_data0_u *)(&entry->val[0])); + hppe_flow_host_tbl_op_data1_set(dev_id, (union flow_host_tbl_op_data1_u *)(&entry->val[1])); + hppe_flow_host_tbl_op_data2_set(dev_id, (union flow_host_tbl_op_data2_u *)(&entry->val[2])); + hppe_flow_host_tbl_op_data3_set(dev_id, (union flow_host_tbl_op_data3_u *)(&entry->val[3])); + hppe_flow_host_tbl_op_data4_set(dev_id, (union flow_host_tbl_op_data4_u *)(&entry->val[4])); + return hppe_flow_host_data_op_common(dev_id, 0, op_mode, index); +} + +sw_error_t +hppe_flow_host_ipv4_data_rd_add( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_tbl_u *entry) +{ + hppe_flow_host_tbl_rd_op_data0_set(dev_id, (union flow_host_tbl_rd_op_data0_u *)(&entry->val[0])); + hppe_flow_host_tbl_rd_op_data1_set(dev_id, (union flow_host_tbl_rd_op_data1_u *)(&entry->val[1])); + hppe_flow_host_tbl_rd_op_data2_set(dev_id, (union flow_host_tbl_rd_op_data2_u*)(&entry->val[2])); + return hppe_flow_host_data_rd_op_common(dev_id, 0, op_mode, index); +} + +sw_error_t +hppe_flow_host_ipv6_data_rd_add( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_ipv6_tbl_u *entry) +{ + hppe_flow_host_tbl_rd_op_data0_set(dev_id, (union flow_host_tbl_rd_op_data0_u *)(&entry->val[0])); + hppe_flow_host_tbl_rd_op_data1_set(dev_id, (union flow_host_tbl_rd_op_data1_u *)(&entry->val[1])); + hppe_flow_host_tbl_rd_op_data2_set(dev_id, (union flow_host_tbl_rd_op_data2_u *)(&entry->val[2])); + hppe_flow_host_tbl_rd_op_data3_set(dev_id, (union flow_host_tbl_rd_op_data3_u *)(&entry->val[3])); + hppe_flow_host_tbl_rd_op_data4_set(dev_id, (union flow_host_tbl_rd_op_data4_u *)(&entry->val[4])); + return hppe_flow_host_data_rd_op_common(dev_id, 0, op_mode, index); +} + +sw_error_t +hppe_flow_host_ipv4_data_get( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_tbl_u *entry) +{ + if (1){//op_mode == 0) { + hppe_host_tbl_rd_op_data0_get(dev_id, (union host_tbl_rd_op_data0_u *)(&entry->val[0])); + hppe_host_tbl_rd_op_data1_get(dev_id, (union host_tbl_rd_op_data1_u *)(&entry->val[1])); + hppe_host_tbl_rd_op_data2_set(dev_id, (union host_tbl_rd_op_data2_u *)(&entry->val[2])); + } + return SW_OK; +} + +sw_error_t +hppe_flow_host_ipv6_data_get( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_ipv6_tbl_u *entry) +{ + if (1){//op_mode == 0) { + hppe_host_tbl_rd_op_data0_get(dev_id, (union host_tbl_rd_op_data0_u *)(&entry->val[0])); + hppe_host_tbl_rd_op_data1_get(dev_id, (union host_tbl_rd_op_data1_u *)(&entry->val[1])); + hppe_host_tbl_rd_op_data2_get(dev_id, (union host_tbl_rd_op_data2_u *)(&entry->val[2])); + hppe_host_tbl_rd_op_data3_get(dev_id, (union host_tbl_rd_op_data3_u *)(&entry->val[3])); + hppe_host_tbl_rd_op_data4_get(dev_id, (union host_tbl_rd_op_data4_u *)(&entry->val[4])); + } + return SW_OK; +} + +sw_error_t +hppe_flow_host_ipv4_data_del( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_tbl_u *entry) +{ + if (op_mode == 0) { + hppe_host_tbl_op_data0_set(dev_id, (union host_tbl_op_data0_u *)(&entry->val[0])); + hppe_host_tbl_op_data1_set(dev_id, (union host_tbl_op_data1_u *)(&entry->val[1])); + hppe_host_tbl_op_data2_set(dev_id, (union host_tbl_op_data2_u *)(&entry->val[2])); + } + return hppe_flow_host_data_op_common(dev_id, 1, op_mode, index); + +} + +sw_error_t +hppe_flow_host_ipv6_data_del( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_ipv6_tbl_u *entry) +{ + if (op_mode == 0) { + hppe_host_tbl_op_data0_set(dev_id, (union host_tbl_op_data0_u *)(&entry->val[0])); + hppe_host_tbl_op_data1_set(dev_id, (union host_tbl_op_data1_u *)(&entry->val[1])); + hppe_host_tbl_op_data2_set(dev_id, (union host_tbl_op_data2_u *)(&entry->val[2])); + hppe_host_tbl_op_data3_set(dev_id, (union host_tbl_op_data3_u *)(&entry->val[3])); + hppe_host_tbl_op_data4_set(dev_id, (union host_tbl_op_data4_u *)(&entry->val[4])); + } + return hppe_flow_host_data_op_common(dev_id, 1, op_mode, index); +} + + +sw_error_t +hppe_flow_ipv4_5tuple_add( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_tbl_u *entry) +{ + hppe_in_flow_tbl_op_data0_set(dev_id, (union in_flow_tbl_op_data0_u *)(&entry->val[0])); + hppe_in_flow_tbl_op_data1_set(dev_id, (union in_flow_tbl_op_data1_u *)(&entry->val[1])); + hppe_in_flow_tbl_op_data2_set(dev_id, (union in_flow_tbl_op_data2_u *)(&entry->val[2])); + hppe_in_flow_tbl_op_data3_set(dev_id, (union in_flow_tbl_op_data3_u *)(&entry->val[3])); + hppe_in_flow_tbl_op_data4_set(dev_id, (union in_flow_tbl_op_data4_u *)(&entry->val[4])); + return hppe_flow_op_common(dev_id, 0, op_mode, index); +} + +sw_error_t +hppe_flow_ipv4_3tuple_add( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_3tuple_tbl_u *entry) +{ + hppe_in_flow_tbl_op_data0_set(dev_id, (union in_flow_tbl_op_data0_u *)(&entry->val[0])); + hppe_in_flow_tbl_op_data1_set(dev_id, (union in_flow_tbl_op_data1_u *)(&entry->val[1])); + hppe_in_flow_tbl_op_data2_set(dev_id, (union in_flow_tbl_op_data2_u *)(&entry->val[2])); + hppe_in_flow_tbl_op_data3_set(dev_id, (union in_flow_tbl_op_data3_u *)(&entry->val[3])); + hppe_in_flow_tbl_op_data4_set(dev_id, (union in_flow_tbl_op_data4_u *)(&entry->val[4])); + return hppe_flow_op_common(dev_id, 0, op_mode, index); +} + +sw_error_t +hppe_flow_ipv6_5tuple_add( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_ipv6_5tuple_tbl_u *entry) +{ + hppe_in_flow_tbl_op_data0_set(dev_id, (union in_flow_tbl_op_data0_u *)(&entry->val[0])); + hppe_in_flow_tbl_op_data1_set(dev_id, (union in_flow_tbl_op_data1_u *)(&entry->val[1])); + hppe_in_flow_tbl_op_data2_set(dev_id, (union in_flow_tbl_op_data2_u *)(&entry->val[2])); + hppe_in_flow_tbl_op_data3_set(dev_id, (union in_flow_tbl_op_data3_u *)(&entry->val[3])); + hppe_in_flow_tbl_op_data4_set(dev_id, (union in_flow_tbl_op_data4_u *)(&entry->val[4])); + hppe_in_flow_tbl_op_data5_set(dev_id, (union in_flow_tbl_op_data5_u *)(&entry->val[5])); + hppe_in_flow_tbl_op_data6_set(dev_id, (union in_flow_tbl_op_data6_u *)(&entry->val[6])); + hppe_in_flow_tbl_op_data7_set(dev_id, (union in_flow_tbl_op_data7_u *)(&entry->val[7])); + hppe_in_flow_tbl_op_data8_set(dev_id, (union in_flow_tbl_op_data8_u *)(&entry->val[8])); + return hppe_flow_op_common(dev_id, 0, op_mode, index); +} + +sw_error_t +hppe_flow_ipv6_3tuple_add( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_ipv6_3tuple_tbl_u *entry) +{ + hppe_in_flow_tbl_op_data0_set(dev_id, (union in_flow_tbl_op_data0_u *)(&entry->val[0])); + hppe_in_flow_tbl_op_data1_set(dev_id, (union in_flow_tbl_op_data1_u *)(&entry->val[1])); + hppe_in_flow_tbl_op_data2_set(dev_id, (union in_flow_tbl_op_data2_u *)(&entry->val[2])); + hppe_in_flow_tbl_op_data3_set(dev_id, (union in_flow_tbl_op_data3_u *)(&entry->val[3])); + hppe_in_flow_tbl_op_data4_set(dev_id, (union in_flow_tbl_op_data4_u *)(&entry->val[4])); + hppe_in_flow_tbl_op_data5_set(dev_id, (union in_flow_tbl_op_data5_u *)(&entry->val[5])); + hppe_in_flow_tbl_op_data6_set(dev_id, (union in_flow_tbl_op_data6_u *)(&entry->val[6])); + hppe_in_flow_tbl_op_data7_set(dev_id, (union in_flow_tbl_op_data7_u *)(&entry->val[7])); + hppe_in_flow_tbl_op_data8_set(dev_id, (union in_flow_tbl_op_data8_u *)(&entry->val[8])); + return hppe_flow_op_common(dev_id, 0, op_mode, index); +} + +sw_error_t +hppe_flow_ipv4_5tuple_del( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_tbl_u *entry) +{ + if (op_mode == 0) { + hppe_in_flow_tbl_op_data0_set(dev_id, + (union in_flow_tbl_op_data0_u *)(&entry->val[0])); + hppe_in_flow_tbl_op_data1_set(dev_id, + (union in_flow_tbl_op_data1_u *)(&entry->val[1])); + hppe_in_flow_tbl_op_data2_set(dev_id, + (union in_flow_tbl_op_data2_u *)(&entry->val[2])); + hppe_in_flow_tbl_op_data3_set(dev_id, + (union in_flow_tbl_op_data3_u *)(&entry->val[3])); + hppe_in_flow_tbl_op_data4_set(dev_id, + (union in_flow_tbl_op_data4_u *)(&entry->val[4])); + } + return hppe_flow_op_common(dev_id, 1, op_mode, index); +} + +sw_error_t +hppe_flow_ipv4_3tuple_del( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_3tuple_tbl_u *entry) +{ + if (op_mode == 0) { + hppe_in_flow_tbl_op_data0_set(dev_id, + (union in_flow_tbl_op_data0_u *)(&entry->val[0])); + hppe_in_flow_tbl_op_data1_set(dev_id, + (union in_flow_tbl_op_data1_u *)(&entry->val[1])); + hppe_in_flow_tbl_op_data2_set(dev_id, + (union in_flow_tbl_op_data2_u *)(&entry->val[2])); + hppe_in_flow_tbl_op_data3_set(dev_id, + (union in_flow_tbl_op_data3_u *)(&entry->val[3])); + hppe_in_flow_tbl_op_data4_set(dev_id, + (union in_flow_tbl_op_data4_u *)(&entry->val[4])); + } + return hppe_flow_op_common(dev_id, 1, op_mode, index); +} + +sw_error_t +hppe_flow_ipv6_5tuple_del( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_ipv6_5tuple_tbl_u *entry) +{ + if (op_mode == 0) { + hppe_in_flow_tbl_op_data0_set(dev_id, + (union in_flow_tbl_op_data0_u *)(&entry->val[0])); + hppe_in_flow_tbl_op_data1_set(dev_id, + (union in_flow_tbl_op_data1_u *)(&entry->val[1])); + hppe_in_flow_tbl_op_data2_set(dev_id, + (union in_flow_tbl_op_data2_u *)(&entry->val[2])); + hppe_in_flow_tbl_op_data3_set(dev_id, + (union in_flow_tbl_op_data3_u *)(&entry->val[3])); + hppe_in_flow_tbl_op_data4_set(dev_id, + (union in_flow_tbl_op_data4_u *)(&entry->val[4])); + hppe_in_flow_tbl_op_data5_set(dev_id, + (union in_flow_tbl_op_data5_u *)(&entry->val[5])); + hppe_in_flow_tbl_op_data6_set(dev_id, + (union in_flow_tbl_op_data6_u *)(&entry->val[6])); + hppe_in_flow_tbl_op_data7_set(dev_id, + (union in_flow_tbl_op_data7_u *)(&entry->val[7])); + hppe_in_flow_tbl_op_data8_set(dev_id, + (union in_flow_tbl_op_data8_u *)(&entry->val[8])); + } + return hppe_flow_op_common(dev_id, 1, op_mode, index); +} + +sw_error_t +hppe_flow_ipv6_3tuple_del( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_ipv6_3tuple_tbl_u *entry) +{ + if (op_mode == 0) { + hppe_in_flow_tbl_op_data0_set(dev_id, + (union in_flow_tbl_op_data0_u *)(&entry->val[0])); + hppe_in_flow_tbl_op_data1_set(dev_id, + (union in_flow_tbl_op_data1_u *)(&entry->val[1])); + hppe_in_flow_tbl_op_data2_set(dev_id, + (union in_flow_tbl_op_data2_u *)(&entry->val[2])); + hppe_in_flow_tbl_op_data3_set(dev_id, + (union in_flow_tbl_op_data3_u *)(&entry->val[3])); + hppe_in_flow_tbl_op_data4_set(dev_id, + (union in_flow_tbl_op_data4_u *)(&entry->val[4])); + hppe_in_flow_tbl_op_data5_set(dev_id, + (union in_flow_tbl_op_data5_u *)(&entry->val[5])); + hppe_in_flow_tbl_op_data6_set(dev_id, + (union in_flow_tbl_op_data6_u *)(&entry->val[6])); + hppe_in_flow_tbl_op_data7_set(dev_id, + (union in_flow_tbl_op_data7_u *)(&entry->val[7])); + hppe_in_flow_tbl_op_data8_set(dev_id, + (union in_flow_tbl_op_data8_u *)(&entry->val[8])); + } + return hppe_flow_op_common(dev_id, 1, op_mode, index); +} + +sw_error_t +hppe_flow_ipv4_5tuple_get( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_tbl_u *entry) +{ + if (op_mode == 0) { + hppe_in_flow_tbl_rd_op_data0_set(dev_id, + (union in_flow_tbl_rd_op_data0_u *)(&entry->val[0])); + hppe_in_flow_tbl_rd_op_data1_set(dev_id, + (union in_flow_tbl_rd_op_data1_u *)(&entry->val[1])); + hppe_in_flow_tbl_rd_op_data2_set(dev_id, + (union in_flow_tbl_rd_op_data2_u *)(&entry->val[2])); + hppe_in_flow_tbl_rd_op_data3_set(dev_id, + (union in_flow_tbl_rd_op_data3_u *)(&entry->val[3])); + hppe_in_flow_tbl_rd_op_data4_set(dev_id, + (union in_flow_tbl_rd_op_data4_u *)(&entry->val[4])); + } + return hppe_flow_get_common(dev_id, op_mode, index, (a_uint32_t *)entry, 5); +} + +sw_error_t +hppe_flow_ipv4_3tuple_get( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_3tuple_tbl_u *entry) +{ + if (op_mode == 0) { + hppe_in_flow_tbl_rd_op_data0_set(dev_id, + (union in_flow_tbl_rd_op_data0_u *)(&entry->val[0])); + hppe_in_flow_tbl_rd_op_data1_set(dev_id, + (union in_flow_tbl_rd_op_data1_u *)(&entry->val[1])); + hppe_in_flow_tbl_rd_op_data2_set(dev_id, + (union in_flow_tbl_rd_op_data2_u *)(&entry->val[2])); + hppe_in_flow_tbl_rd_op_data3_set(dev_id, + (union in_flow_tbl_rd_op_data3_u *)(&entry->val[3])); + hppe_in_flow_tbl_rd_op_data4_set(dev_id, + (union in_flow_tbl_rd_op_data4_u *)(&entry->val[4])); + } + return hppe_flow_get_common(dev_id, op_mode, index, (a_uint32_t *)entry, 5); +} + +sw_error_t +hppe_flow_ipv6_5tuple_get( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_ipv6_5tuple_tbl_u *entry) +{ + if (op_mode == 0) { + hppe_in_flow_tbl_rd_op_data0_set(dev_id, + (union in_flow_tbl_rd_op_data0_u *)(&entry->val[0])); + hppe_in_flow_tbl_rd_op_data1_set(dev_id, + (union in_flow_tbl_rd_op_data1_u *)(&entry->val[1])); + hppe_in_flow_tbl_rd_op_data2_set(dev_id, + (union in_flow_tbl_rd_op_data2_u *)(&entry->val[2])); + hppe_in_flow_tbl_rd_op_data3_set(dev_id, + (union in_flow_tbl_rd_op_data3_u *)(&entry->val[3])); + hppe_in_flow_tbl_rd_op_data4_set(dev_id, + (union in_flow_tbl_rd_op_data4_u *)(&entry->val[4])); + hppe_in_flow_tbl_rd_op_data5_set(dev_id, + (union in_flow_tbl_rd_op_data5_u *)(&entry->val[5])); + hppe_in_flow_tbl_rd_op_data6_set(dev_id, + (union in_flow_tbl_rd_op_data6_u *)(&entry->val[6])); + hppe_in_flow_tbl_rd_op_data7_set(dev_id, + (union in_flow_tbl_rd_op_data7_u *)(&entry->val[7])); + hppe_in_flow_tbl_rd_op_data8_set(dev_id, + (union in_flow_tbl_rd_op_data8_u *)(&entry->val[8])); + } + return hppe_flow_get_common(dev_id, op_mode, index, (a_uint32_t *)entry, 9); +} + +sw_error_t +hppe_flow_ipv6_3tuple_get( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union in_flow_ipv6_3tuple_tbl_u *entry) +{ + if (op_mode == 0) { + hppe_in_flow_tbl_rd_op_data0_set(dev_id, + (union in_flow_tbl_rd_op_data0_u *)(&entry->val[0])); + hppe_in_flow_tbl_rd_op_data1_set(dev_id, + (union in_flow_tbl_rd_op_data1_u *)(&entry->val[1])); + hppe_in_flow_tbl_rd_op_data2_set(dev_id, + (union in_flow_tbl_rd_op_data2_u *)(&entry->val[2])); + hppe_in_flow_tbl_rd_op_data3_set(dev_id, + (union in_flow_tbl_rd_op_data3_u *)(&entry->val[3])); + hppe_in_flow_tbl_rd_op_data4_set(dev_id, + (union in_flow_tbl_rd_op_data4_u *)(&entry->val[4])); + hppe_in_flow_tbl_rd_op_data5_set(dev_id, + (union in_flow_tbl_rd_op_data5_u *)(&entry->val[5])); + hppe_in_flow_tbl_rd_op_data6_set(dev_id, + (union in_flow_tbl_rd_op_data6_u *)(&entry->val[6])); + hppe_in_flow_tbl_rd_op_data7_set(dev_id, + (union in_flow_tbl_rd_op_data7_u *)(&entry->val[7])); + hppe_in_flow_tbl_rd_op_data8_set(dev_id, + (union in_flow_tbl_rd_op_data8_u *)(&entry->val[8])); + } + return hppe_flow_get_common(dev_id, op_mode, index, (a_uint32_t *)entry, 9); +} +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_global.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_global.c new file mode 100755 index 000000000..85fbaaf53 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_global.c @@ -0,0 +1,3117 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hppe_reg_access.h" +#include "hppe_global_reg.h" +#include "hppe_global.h" + +sw_error_t +hppe_switch_id_get( + a_uint32_t dev_id, + union switch_id_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_GLOBAL_BASE_ADDR + SWITCH_ID_ADDRESS, + &value->val); +} + +sw_error_t +hppe_switch_id_set( + a_uint32_t dev_id, + union switch_id_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_GLOBAL_BASE_ADDR + SWITCH_ID_ADDRESS, + value->val); +} + +sw_error_t +hppe_rgmii_ctrl_get( + a_uint32_t dev_id, + union rgmii_ctrl_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_GLOBAL_BASE_ADDR + RGMII_CTRL_ADDRESS, + &value->val); +} + +sw_error_t +hppe_rgmii_ctrl_set( + a_uint32_t dev_id, + union rgmii_ctrl_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_GLOBAL_BASE_ADDR + RGMII_CTRL_ADDRESS, + value->val); +} + +sw_error_t +hppe_clk_gating_ctrl_get( + a_uint32_t dev_id, + union clk_gating_ctrl_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_GLOBAL_BASE_ADDR + CLK_GATING_CTRL_ADDRESS, + &value->val); +} + +sw_error_t +hppe_clk_gating_ctrl_set( + a_uint32_t dev_id, + union clk_gating_ctrl_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_GLOBAL_BASE_ADDR + CLK_GATING_CTRL_ADDRESS, + value->val); +} + +sw_error_t +hppe_port_mux_ctrl_get( + a_uint32_t dev_id, + union port_mux_ctrl_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_GLOBAL_BASE_ADDR + PORT_MUX_CTRL_ADDRESS, + &value->val); +} + +sw_error_t +hppe_port_mux_ctrl_set( + a_uint32_t dev_id, + union port_mux_ctrl_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_GLOBAL_BASE_ADDR + PORT_MUX_CTRL_ADDRESS, + value->val); +} + +sw_error_t +cppe_port_mux_ctrl_get( + a_uint32_t dev_id, + union cppe_port_mux_ctrl_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_GLOBAL_BASE_ADDR + PORT_MUX_CTRL_ADDRESS, + &value->val); +} +sw_error_t +cppe_port_mux_ctrl_set( + a_uint32_t dev_id, + union cppe_port_mux_ctrl_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_GLOBAL_BASE_ADDR + PORT_MUX_CTRL_ADDRESS, + value->val); +} +sw_error_t +hppe_module_ini_done_int_get( + a_uint32_t dev_id, + union module_ini_done_int_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_GLOBAL_BASE_ADDR + MODULE_INI_DONE_INT_ADDRESS, + &value->val); +} + +sw_error_t +hppe_module_ini_done_int_set( + a_uint32_t dev_id, + union module_ini_done_int_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_GLOBAL_BASE_ADDR + MODULE_INI_DONE_INT_ADDRESS, + value->val); +} + +sw_error_t +hppe_module_cpu_done_int_get( + a_uint32_t dev_id, + union module_cpu_done_int_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_GLOBAL_BASE_ADDR + MODULE_CPU_DONE_INT_ADDRESS, + &value->val); +} + +sw_error_t +hppe_module_cpu_done_int_set( + a_uint32_t dev_id, + union module_cpu_done_int_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_GLOBAL_BASE_ADDR + MODULE_CPU_DONE_INT_ADDRESS, + value->val); +} + +sw_error_t +hppe_port_link_int_get( + a_uint32_t dev_id, + union port_link_int_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_GLOBAL_BASE_ADDR + PORT_LINK_INT_ADDRESS, + &value->val); +} + +sw_error_t +hppe_port_link_int_set( + a_uint32_t dev_id, + union port_link_int_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_GLOBAL_BASE_ADDR + PORT_LINK_INT_ADDRESS, + value->val); +} + +sw_error_t +hppe_module_ini_done_int_mask_get( + a_uint32_t dev_id, + union module_ini_done_int_mask_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_GLOBAL_BASE_ADDR + MODULE_INI_DONE_INT_MASK_ADDRESS, + &value->val); +} + +sw_error_t +hppe_module_ini_done_int_mask_set( + a_uint32_t dev_id, + union module_ini_done_int_mask_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_GLOBAL_BASE_ADDR + MODULE_INI_DONE_INT_MASK_ADDRESS, + value->val); +} + +sw_error_t +hppe_module_cpu_done_int_mask_get( + a_uint32_t dev_id, + union module_cpu_done_int_mask_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_GLOBAL_BASE_ADDR + MODULE_CPU_DONE_INT_MASK_ADDRESS, + &value->val); +} + +sw_error_t +hppe_module_cpu_done_int_mask_set( + a_uint32_t dev_id, + union module_cpu_done_int_mask_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_GLOBAL_BASE_ADDR + MODULE_CPU_DONE_INT_MASK_ADDRESS, + value->val); +} + +sw_error_t +hppe_port_link_int_mask_get( + a_uint32_t dev_id, + union port_link_int_mask_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_GLOBAL_BASE_ADDR + PORT_LINK_INT_MASK_ADDRESS, + &value->val); +} + +sw_error_t +hppe_port_link_int_mask_set( + a_uint32_t dev_id, + union port_link_int_mask_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_GLOBAL_BASE_ADDR + PORT_LINK_INT_MASK_ADDRESS, + value->val); +} + +sw_error_t +hppe_port_phy_status_0_get( + a_uint32_t dev_id, + union port_phy_status_0_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_GLOBAL_BASE_ADDR + PORT_PHY_STATUS_0_ADDRESS, + &value->val); +} + +sw_error_t +hppe_port_phy_status_0_set( + a_uint32_t dev_id, + union port_phy_status_0_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_port_phy_status_1_get( + a_uint32_t dev_id, + union port_phy_status_1_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_GLOBAL_BASE_ADDR + PORT_PHY_STATUS_1_ADDRESS, + &value->val); +} + +sw_error_t +hppe_port_phy_status_1_set( + a_uint32_t dev_id, + union port_phy_status_1_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_port1_status_get( + a_uint32_t dev_id, + union port1_status_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_GLOBAL_BASE_ADDR + PORT1_STATUS_ADDRESS, + &value->val); +} + +sw_error_t +hppe_port1_status_set( + a_uint32_t dev_id, + union port1_status_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_port2_status_get( + a_uint32_t dev_id, + union port2_status_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_GLOBAL_BASE_ADDR + PORT2_STATUS_ADDRESS, + &value->val); +} + +sw_error_t +hppe_port2_status_set( + a_uint32_t dev_id, + union port2_status_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_port3_status_get( + a_uint32_t dev_id, + union port3_status_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_GLOBAL_BASE_ADDR + PORT3_STATUS_ADDRESS, + &value->val); +} + +sw_error_t +hppe_port3_status_set( + a_uint32_t dev_id, + union port3_status_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_port4_status_get( + a_uint32_t dev_id, + union port4_status_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_GLOBAL_BASE_ADDR + PORT4_STATUS_ADDRESS, + &value->val); +} + +sw_error_t +hppe_port4_status_set( + a_uint32_t dev_id, + union port4_status_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_port5_status_get( + a_uint32_t dev_id, + union port5_status_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_GLOBAL_BASE_ADDR + PORT5_STATUS_ADDRESS, + &value->val); +} + +sw_error_t +hppe_port5_status_set( + a_uint32_t dev_id, + union port5_status_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_port6_status_get( + a_uint32_t dev_id, + union port6_status_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_GLOBAL_BASE_ADDR + PORT6_STATUS_ADDRESS, + &value->val); +} + +sw_error_t +hppe_port6_status_set( + a_uint32_t dev_id, + union port6_status_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_reserved_regs_0_get( + a_uint32_t dev_id, + union reserved_regs_0_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_GLOBAL_BASE_ADDR + RESERVED_REGS_0_ADDRESS, + &value->val); +} + +sw_error_t +hppe_reserved_regs_0_set( + a_uint32_t dev_id, + union reserved_regs_0_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_GLOBAL_BASE_ADDR + RESERVED_REGS_0_ADDRESS, + value->val); +} + +sw_error_t +hppe_reserved_regs_1_get( + a_uint32_t dev_id, + union reserved_regs_1_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_GLOBAL_BASE_ADDR + RESERVED_REGS_1_ADDRESS, + &value->val); +} + +sw_error_t +hppe_reserved_regs_1_set( + a_uint32_t dev_id, + union reserved_regs_1_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_GLOBAL_BASE_ADDR + RESERVED_REGS_1_ADDRESS, + value->val); +} + +sw_error_t +hppe_reserved_regs_2_get( + a_uint32_t dev_id, + union reserved_regs_2_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_GLOBAL_BASE_ADDR + RESERVED_REGS_2_ADDRESS, + &value->val); +} + +sw_error_t +hppe_reserved_regs_2_set( + a_uint32_t dev_id, + union reserved_regs_2_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_GLOBAL_BASE_ADDR + RESERVED_REGS_2_ADDRESS, + value->val); +} + +sw_error_t +hppe_reserved_regs_3_get( + a_uint32_t dev_id, + union reserved_regs_3_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_GLOBAL_BASE_ADDR + RESERVED_REGS_3_ADDRESS, + &value->val); +} + +sw_error_t +hppe_reserved_regs_3_set( + a_uint32_t dev_id, + union reserved_regs_3_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_GLOBAL_BASE_ADDR + RESERVED_REGS_3_ADDRESS, + value->val); +} + +sw_error_t +hppe_dbg_data_sel_get( + a_uint32_t dev_id, + union dbg_data_sel_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_GLOBAL_BASE_ADDR + DBG_DATA_SEL_ADDRESS, + &value->val); +} + +sw_error_t +hppe_dbg_data_sel_set( + a_uint32_t dev_id, + union dbg_data_sel_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_GLOBAL_BASE_ADDR + DBG_DATA_SEL_ADDRESS, + value->val); +} + +sw_error_t +hppe_switch_id_dev_id_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union switch_id_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_switch_id_get(dev_id, ®_val); + *value = reg_val.bf.dev_id; + return ret; +} + +sw_error_t +hppe_switch_id_dev_id_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union switch_id_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_switch_id_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.dev_id = value; + ret = hppe_switch_id_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_switch_id_rev_id_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union switch_id_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_switch_id_get(dev_id, ®_val); + *value = reg_val.bf.rev_id; + return ret; +} + +sw_error_t +hppe_switch_id_rev_id_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union switch_id_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_switch_id_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rev_id = value; + ret = hppe_switch_id_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_rgmii_ctrl_rgmii_ctrl_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union rgmii_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rgmii_ctrl_get(dev_id, ®_val); + *value = reg_val.bf.rgmii_ctrl; + return ret; +} + +sw_error_t +hppe_rgmii_ctrl_rgmii_ctrl_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union rgmii_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rgmii_ctrl_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rgmii_ctrl = value; + ret = hppe_rgmii_ctrl_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_clk_gating_ctrl_clk_gating_ctrl_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union clk_gating_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_clk_gating_ctrl_get(dev_id, ®_val); + *value = reg_val.bf.clk_gating_ctrl; + return ret; +} + +sw_error_t +hppe_clk_gating_ctrl_clk_gating_ctrl_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union clk_gating_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_clk_gating_ctrl_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.clk_gating_ctrl = value; + ret = hppe_clk_gating_ctrl_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_mux_ctrl_port6_pcs_sel_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_mux_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_mux_ctrl_get(dev_id, ®_val); + *value = reg_val.bf.port6_pcs_sel; + return ret; +} + +sw_error_t +hppe_port_mux_ctrl_port6_pcs_sel_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_mux_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_mux_ctrl_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port6_pcs_sel = value; + ret = hppe_port_mux_ctrl_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_mux_ctrl_port5_gmac_sel_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_mux_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_mux_ctrl_get(dev_id, ®_val); + *value = reg_val.bf.port5_gmac_sel; + return ret; +} + +sw_error_t +hppe_port_mux_ctrl_port5_gmac_sel_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_mux_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_mux_ctrl_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port5_gmac_sel = value; + ret = hppe_port_mux_ctrl_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_mux_ctrl_port5_pcs_sel_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_mux_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_mux_ctrl_get(dev_id, ®_val); + *value = reg_val.bf.port5_pcs_sel; + return ret; +} + +sw_error_t +hppe_port_mux_ctrl_port5_pcs_sel_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_mux_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_mux_ctrl_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port5_pcs_sel = value; + ret = hppe_port_mux_ctrl_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_mux_ctrl_port4_pcs_sel_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_mux_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_mux_ctrl_get(dev_id, ®_val); + *value = reg_val.bf.port4_pcs_sel; + return ret; +} + +sw_error_t +hppe_port_mux_ctrl_port4_pcs_sel_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_mux_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_mux_ctrl_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port4_pcs_sel = value; + ret = hppe_port_mux_ctrl_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_mux_ctrl_port6_gmac_sel_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_mux_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_mux_ctrl_get(dev_id, ®_val); + *value = reg_val.bf.port6_gmac_sel; + return ret; +} + +sw_error_t +hppe_port_mux_ctrl_port6_gmac_sel_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_mux_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_mux_ctrl_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port6_gmac_sel = value; + ret = hppe_port_mux_ctrl_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_ini_done_int_iv_ini_done_int_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_ini_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_get(dev_id, ®_val); + *value = reg_val.bf.iv_ini_done_int; + return ret; +} + +sw_error_t +hppe_module_ini_done_int_iv_ini_done_int_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_ini_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.iv_ini_done_int = value; + ret = hppe_module_ini_done_int_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_ini_done_int_qm_ini_done_int_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_ini_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_get(dev_id, ®_val); + *value = reg_val.bf.qm_ini_done_int; + return ret; +} + +sw_error_t +hppe_module_ini_done_int_qm_ini_done_int_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_ini_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.qm_ini_done_int = value; + ret = hppe_module_ini_done_int_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_ini_done_int_l3_ini_done_int_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_ini_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_get(dev_id, ®_val); + *value = reg_val.bf.l3_ini_done_int; + return ret; +} + +sw_error_t +hppe_module_ini_done_int_l3_ini_done_int_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_ini_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l3_ini_done_int = value; + ret = hppe_module_ini_done_int_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_ini_done_int_bm_ini_done_int_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_ini_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_get(dev_id, ®_val); + *value = reg_val.bf.bm_ini_done_int; + return ret; +} + +sw_error_t +hppe_module_ini_done_int_bm_ini_done_int_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_ini_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.bm_ini_done_int = value; + ret = hppe_module_ini_done_int_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_ini_done_int_ptx_ini_done_int_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_ini_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_get(dev_id, ®_val); + *value = reg_val.bf.ptx_ini_done_int; + return ret; +} + +sw_error_t +hppe_module_ini_done_int_ptx_ini_done_int_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_ini_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptx_ini_done_int = value; + ret = hppe_module_ini_done_int_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_ini_done_int_tm_ini_done_int_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_ini_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_get(dev_id, ®_val); + *value = reg_val.bf.tm_ini_done_int; + return ret; +} + +sw_error_t +hppe_module_ini_done_int_tm_ini_done_int_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_ini_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tm_ini_done_int = value; + ret = hppe_module_ini_done_int_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_ini_done_int_l2_ini_done_int_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_ini_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_get(dev_id, ®_val); + *value = reg_val.bf.l2_ini_done_int; + return ret; +} + +sw_error_t +hppe_module_ini_done_int_l2_ini_done_int_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_ini_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l2_ini_done_int = value; + ret = hppe_module_ini_done_int_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_ini_done_int_acl_ini_done_int_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_ini_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_get(dev_id, ®_val); + *value = reg_val.bf.acl_ini_done_int; + return ret; +} + +sw_error_t +hppe_module_ini_done_int_acl_ini_done_int_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_ini_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.acl_ini_done_int = value; + ret = hppe_module_ini_done_int_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_ini_done_int_ing_rate_ini_done_int_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_ini_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_get(dev_id, ®_val); + *value = reg_val.bf.ing_rate_ini_done_int; + return ret; +} + +sw_error_t +hppe_module_ini_done_int_ing_rate_ini_done_int_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_ini_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ing_rate_ini_done_int = value; + ret = hppe_module_ini_done_int_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_l3_flow_wr_cmd_overflow_int_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_cpu_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_get(dev_id, ®_val); + *value = reg_val.bf.l3_flow_wr_cmd_overflow_int; + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_l3_flow_wr_cmd_overflow_int_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_cpu_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l3_flow_wr_cmd_overflow_int = value; + ret = hppe_module_cpu_done_int_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_l2_fdb_rd_cmd_overflow_int_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_cpu_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_get(dev_id, ®_val); + *value = reg_val.bf.l2_fdb_rd_cmd_overflow_int; + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_l2_fdb_rd_cmd_overflow_int_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_cpu_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l2_fdb_rd_cmd_overflow_int = value; + ret = hppe_module_cpu_done_int_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_qm_cpu_op_done_int_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_cpu_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_get(dev_id, ®_val); + *value = reg_val.bf.qm_cpu_op_done_int; + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_qm_cpu_op_done_int_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_cpu_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.qm_cpu_op_done_int = value; + ret = hppe_module_cpu_done_int_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_l3_flow_rd_cmd_overflow_int_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_cpu_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_get(dev_id, ®_val); + *value = reg_val.bf.l3_flow_rd_cmd_overflow_int; + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_l3_flow_rd_cmd_overflow_int_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_cpu_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l3_flow_rd_cmd_overflow_int = value; + ret = hppe_module_cpu_done_int_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_l2_fdb_wr_result_vld_int_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_cpu_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_get(dev_id, ®_val); + *value = reg_val.bf.l2_fdb_wr_result_vld_int; + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_l2_fdb_wr_result_vld_int_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_cpu_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l2_fdb_wr_result_vld_int = value; + ret = hppe_module_cpu_done_int_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_l2_fdb_rd_result_vld_int_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_cpu_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_get(dev_id, ®_val); + *value = reg_val.bf.l2_fdb_rd_result_vld_int; + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_l2_fdb_rd_result_vld_int_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_cpu_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l2_fdb_rd_result_vld_int = value; + ret = hppe_module_cpu_done_int_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_l2_fdb_wr_cmd_overflow_int_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_cpu_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_get(dev_id, ®_val); + *value = reg_val.bf.l2_fdb_wr_cmd_overflow_int; + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_l2_fdb_wr_cmd_overflow_int_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_cpu_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l2_fdb_wr_cmd_overflow_int = value; + ret = hppe_module_cpu_done_int_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_l3_flow_rd_result_vld_int_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_cpu_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_get(dev_id, ®_val); + *value = reg_val.bf.l3_flow_rd_result_vld_int; + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_l3_flow_rd_result_vld_int_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_cpu_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l3_flow_rd_result_vld_int = value; + ret = hppe_module_cpu_done_int_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_l3_host_wr_cmd_overflow_int_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_cpu_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_get(dev_id, ®_val); + *value = reg_val.bf.l3_host_wr_cmd_overflow_int; + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_l3_host_wr_cmd_overflow_int_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_cpu_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l3_host_wr_cmd_overflow_int = value; + ret = hppe_module_cpu_done_int_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_l3_host_rd_cmd_overflow_int_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_cpu_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_get(dev_id, ®_val); + *value = reg_val.bf.l3_host_rd_cmd_overflow_int; + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_l3_host_rd_cmd_overflow_int_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_cpu_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l3_host_rd_cmd_overflow_int = value; + ret = hppe_module_cpu_done_int_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_l3_host_rd_result_vld_int_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_cpu_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_get(dev_id, ®_val); + *value = reg_val.bf.l3_host_rd_result_vld_int; + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_l3_host_rd_result_vld_int_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_cpu_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l3_host_rd_result_vld_int = value; + ret = hppe_module_cpu_done_int_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_l3_host_wr_result_vld_int_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_cpu_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_get(dev_id, ®_val); + *value = reg_val.bf.l3_host_wr_result_vld_int; + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_l3_host_wr_result_vld_int_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_cpu_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l3_host_wr_result_vld_int = value; + ret = hppe_module_cpu_done_int_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_l3_flow_wr_result_vld_int_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_cpu_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_get(dev_id, ®_val); + *value = reg_val.bf.l3_flow_wr_result_vld_int; + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_l3_flow_wr_result_vld_int_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_cpu_done_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l3_flow_wr_result_vld_int = value; + ret = hppe_module_cpu_done_int_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_link_int_port6_link_chg_int_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_link_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_get(dev_id, ®_val); + *value = reg_val.bf.port6_link_chg_int; + return ret; +} + +sw_error_t +hppe_port_link_int_port6_link_chg_int_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_link_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port6_link_chg_int = value; + ret = hppe_port_link_int_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_link_int_xgmac0_an_done_int_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_link_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_get(dev_id, ®_val); + *value = reg_val.bf.xgmac0_an_done_int; + return ret; +} + +sw_error_t +hppe_port_link_int_xgmac0_an_done_int_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_link_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.xgmac0_an_done_int = value; + ret = hppe_port_link_int_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_link_int_port5_1_link_chg_int_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_link_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_get(dev_id, ®_val); + *value = reg_val.bf.port5_1_link_chg_int; + return ret; +} + +sw_error_t +hppe_port_link_int_port5_1_link_chg_int_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_link_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port5_1_link_chg_int = value; + ret = hppe_port_link_int_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_link_int_port5_0_link_chg_int_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_link_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_get(dev_id, ®_val); + *value = reg_val.bf.port5_0_link_chg_int; + return ret; +} + +sw_error_t +hppe_port_link_int_port5_0_link_chg_int_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_link_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port5_0_link_chg_int = value; + ret = hppe_port_link_int_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_link_int_port4_link_chg_int_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_link_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_get(dev_id, ®_val); + *value = reg_val.bf.port4_link_chg_int; + return ret; +} + +sw_error_t +hppe_port_link_int_port4_link_chg_int_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_link_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port4_link_chg_int = value; + ret = hppe_port_link_int_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_link_int_port3_link_chg_int_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_link_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_get(dev_id, ®_val); + *value = reg_val.bf.port3_link_chg_int; + return ret; +} + +sw_error_t +hppe_port_link_int_port3_link_chg_int_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_link_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port3_link_chg_int = value; + ret = hppe_port_link_int_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_link_int_port2_link_chg_int_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_link_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_get(dev_id, ®_val); + *value = reg_val.bf.port2_link_chg_int; + return ret; +} + +sw_error_t +hppe_port_link_int_port2_link_chg_int_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_link_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port2_link_chg_int = value; + ret = hppe_port_link_int_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_link_int_xgmac1_an_done_int_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_link_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_get(dev_id, ®_val); + *value = reg_val.bf.xgmac1_an_done_int; + return ret; +} + +sw_error_t +hppe_port_link_int_xgmac1_an_done_int_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_link_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.xgmac1_an_done_int = value; + ret = hppe_port_link_int_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_link_int_port1_link_chg_int_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_link_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_get(dev_id, ®_val); + *value = reg_val.bf.port1_link_chg_int; + return ret; +} + +sw_error_t +hppe_port_link_int_port1_link_chg_int_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_link_int_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port1_link_chg_int = value; + ret = hppe_port_link_int_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_ini_done_int_mask_tm_ini_done_int_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_ini_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_mask_get(dev_id, ®_val); + *value = reg_val.bf.tm_ini_done_int_mask; + return ret; +} + +sw_error_t +hppe_module_ini_done_int_mask_tm_ini_done_int_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_ini_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_mask_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tm_ini_done_int_mask = value; + ret = hppe_module_ini_done_int_mask_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_ini_done_int_mask_bm_ini_done_int_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_ini_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_mask_get(dev_id, ®_val); + *value = reg_val.bf.bm_ini_done_int_mask; + return ret; +} + +sw_error_t +hppe_module_ini_done_int_mask_bm_ini_done_int_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_ini_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_mask_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.bm_ini_done_int_mask = value; + ret = hppe_module_ini_done_int_mask_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_ini_done_int_mask_iv_ini_done_int_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_ini_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_mask_get(dev_id, ®_val); + *value = reg_val.bf.iv_ini_done_int_mask; + return ret; +} + +sw_error_t +hppe_module_ini_done_int_mask_iv_ini_done_int_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_ini_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_mask_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.iv_ini_done_int_mask = value; + ret = hppe_module_ini_done_int_mask_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_ini_done_int_mask_acl_ini_done_int_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_ini_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_mask_get(dev_id, ®_val); + *value = reg_val.bf.acl_ini_done_int_mask; + return ret; +} + +sw_error_t +hppe_module_ini_done_int_mask_acl_ini_done_int_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_ini_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_mask_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.acl_ini_done_int_mask = value; + ret = hppe_module_ini_done_int_mask_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_ini_done_int_mask_qm_ini_done_int_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_ini_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_mask_get(dev_id, ®_val); + *value = reg_val.bf.qm_ini_done_int_mask; + return ret; +} + +sw_error_t +hppe_module_ini_done_int_mask_qm_ini_done_int_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_ini_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_mask_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.qm_ini_done_int_mask = value; + ret = hppe_module_ini_done_int_mask_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_ini_done_int_mask_l2_ini_done_int_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_ini_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_mask_get(dev_id, ®_val); + *value = reg_val.bf.l2_ini_done_int_mask; + return ret; +} + +sw_error_t +hppe_module_ini_done_int_mask_l2_ini_done_int_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_ini_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_mask_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l2_ini_done_int_mask = value; + ret = hppe_module_ini_done_int_mask_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_ini_done_int_mask_ptx_ini_done_int_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_ini_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_mask_get(dev_id, ®_val); + *value = reg_val.bf.ptx_ini_done_int_mask; + return ret; +} + +sw_error_t +hppe_module_ini_done_int_mask_ptx_ini_done_int_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_ini_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_mask_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptx_ini_done_int_mask = value; + ret = hppe_module_ini_done_int_mask_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_ini_done_int_mask_ing_rate_ini_done_int_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_ini_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_mask_get(dev_id, ®_val); + *value = reg_val.bf.ing_rate_ini_done_int_mask; + return ret; +} + +sw_error_t +hppe_module_ini_done_int_mask_ing_rate_ini_done_int_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_ini_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_mask_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ing_rate_ini_done_int_mask = value; + ret = hppe_module_ini_done_int_mask_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_ini_done_int_mask_l3_ini_done_int_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_ini_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_mask_get(dev_id, ®_val); + *value = reg_val.bf.l3_ini_done_int_mask; + return ret; +} + +sw_error_t +hppe_module_ini_done_int_mask_l3_ini_done_int_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_ini_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_ini_done_int_mask_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l3_ini_done_int_mask = value; + ret = hppe_module_ini_done_int_mask_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_mask_l3_host_wr_result_vld_int_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_cpu_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_mask_get(dev_id, ®_val); + *value = reg_val.bf.l3_host_wr_result_vld_int_mask; + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_mask_l3_host_wr_result_vld_int_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_cpu_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_mask_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l3_host_wr_result_vld_int_mask = value; + ret = hppe_module_cpu_done_int_mask_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_mask_l3_flow_wr_result_vld_int_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_cpu_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_mask_get(dev_id, ®_val); + *value = reg_val.bf.l3_flow_wr_result_vld_int_mask; + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_mask_l3_flow_wr_result_vld_int_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_cpu_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_mask_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l3_flow_wr_result_vld_int_mask = value; + ret = hppe_module_cpu_done_int_mask_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_mask_l3_host_rd_cmd_overflow_int_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_cpu_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_mask_get(dev_id, ®_val); + *value = reg_val.bf.l3_host_rd_cmd_overflow_int_mask; + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_mask_l3_host_rd_cmd_overflow_int_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_cpu_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_mask_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l3_host_rd_cmd_overflow_int_mask = value; + ret = hppe_module_cpu_done_int_mask_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_mask_l3_flow_wr_cmd_overflow_int_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_cpu_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_mask_get(dev_id, ®_val); + *value = reg_val.bf.l3_flow_wr_cmd_overflow_int_mask; + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_mask_l3_flow_wr_cmd_overflow_int_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_cpu_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_mask_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l3_flow_wr_cmd_overflow_int_mask = value; + ret = hppe_module_cpu_done_int_mask_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_mask_l3_host_rd_result_vld_int_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_cpu_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_mask_get(dev_id, ®_val); + *value = reg_val.bf.l3_host_rd_result_vld_int_mask; + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_mask_l3_host_rd_result_vld_int_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_cpu_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_mask_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l3_host_rd_result_vld_int_mask = value; + ret = hppe_module_cpu_done_int_mask_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_mask_l2_fdb_rd_cmd_overflow_int_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_cpu_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_mask_get(dev_id, ®_val); + *value = reg_val.bf.l2_fdb_rd_cmd_overflow_int_mask; + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_mask_l2_fdb_rd_cmd_overflow_int_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_cpu_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_mask_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l2_fdb_rd_cmd_overflow_int_mask = value; + ret = hppe_module_cpu_done_int_mask_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_mask_l2_fdb_wr_cmd_overflow_int_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_cpu_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_mask_get(dev_id, ®_val); + *value = reg_val.bf.l2_fdb_wr_cmd_overflow_int_mask; + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_mask_l2_fdb_wr_cmd_overflow_int_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_cpu_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_mask_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l2_fdb_wr_cmd_overflow_int_mask = value; + ret = hppe_module_cpu_done_int_mask_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_mask_l3_host_wr_cmd_overflow_int_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_cpu_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_mask_get(dev_id, ®_val); + *value = reg_val.bf.l3_host_wr_cmd_overflow_int_mask; + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_mask_l3_host_wr_cmd_overflow_int_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_cpu_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_mask_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l3_host_wr_cmd_overflow_int_mask = value; + ret = hppe_module_cpu_done_int_mask_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_mask_l2_fdb_rd_result_vld_int_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_cpu_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_mask_get(dev_id, ®_val); + *value = reg_val.bf.l2_fdb_rd_result_vld_int_mask; + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_mask_l2_fdb_rd_result_vld_int_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_cpu_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_mask_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l2_fdb_rd_result_vld_int_mask = value; + ret = hppe_module_cpu_done_int_mask_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_mask_l2_fdb_wr_result_vld_int_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_cpu_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_mask_get(dev_id, ®_val); + *value = reg_val.bf.l2_fdb_wr_result_vld_int_mask; + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_mask_l2_fdb_wr_result_vld_int_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_cpu_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_mask_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l2_fdb_wr_result_vld_int_mask = value; + ret = hppe_module_cpu_done_int_mask_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_mask_qm_cpu_op_done_int_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_cpu_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_mask_get(dev_id, ®_val); + *value = reg_val.bf.qm_cpu_op_done_int_mask; + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_mask_qm_cpu_op_done_int_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_cpu_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_mask_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.qm_cpu_op_done_int_mask = value; + ret = hppe_module_cpu_done_int_mask_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_mask_l3_flow_rd_result_vld_int_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_cpu_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_mask_get(dev_id, ®_val); + *value = reg_val.bf.l3_flow_rd_result_vld_int_mask; + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_mask_l3_flow_rd_result_vld_int_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_cpu_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_mask_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l3_flow_rd_result_vld_int_mask = value; + ret = hppe_module_cpu_done_int_mask_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_mask_l3_flow_rd_cmd_overflow_int_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union module_cpu_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_mask_get(dev_id, ®_val); + *value = reg_val.bf.l3_flow_rd_cmd_overflow_int_mask; + return ret; +} + +sw_error_t +hppe_module_cpu_done_int_mask_l3_flow_rd_cmd_overflow_int_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union module_cpu_done_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_module_cpu_done_int_mask_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l3_flow_rd_cmd_overflow_int_mask = value; + ret = hppe_module_cpu_done_int_mask_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_link_int_mask_xgmac0_an_done_int_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_link_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_mask_get(dev_id, ®_val); + *value = reg_val.bf.xgmac0_an_done_int_mask; + return ret; +} + +sw_error_t +hppe_port_link_int_mask_xgmac0_an_done_int_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_link_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_mask_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.xgmac0_an_done_int_mask = value; + ret = hppe_port_link_int_mask_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_link_int_mask_port2_link_chg_int_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_link_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_mask_get(dev_id, ®_val); + *value = reg_val.bf.port2_link_chg_int_mask; + return ret; +} + +sw_error_t +hppe_port_link_int_mask_port2_link_chg_int_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_link_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_mask_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port2_link_chg_int_mask = value; + ret = hppe_port_link_int_mask_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_link_int_mask_port4_link_chg_int_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_link_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_mask_get(dev_id, ®_val); + *value = reg_val.bf.port4_link_chg_int_mask; + return ret; +} + +sw_error_t +hppe_port_link_int_mask_port4_link_chg_int_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_link_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_mask_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port4_link_chg_int_mask = value; + ret = hppe_port_link_int_mask_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_link_int_mask_port3_link_chg_int_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_link_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_mask_get(dev_id, ®_val); + *value = reg_val.bf.port3_link_chg_int_mask; + return ret; +} + +sw_error_t +hppe_port_link_int_mask_port3_link_chg_int_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_link_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_mask_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port3_link_chg_int_mask = value; + ret = hppe_port_link_int_mask_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_link_int_mask_port5_1_link_chg_int_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_link_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_mask_get(dev_id, ®_val); + *value = reg_val.bf.port5_1_link_chg_int_mask; + return ret; +} + +sw_error_t +hppe_port_link_int_mask_port5_1_link_chg_int_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_link_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_mask_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port5_1_link_chg_int_mask = value; + ret = hppe_port_link_int_mask_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_link_int_mask_xgmac1_an_done_int_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_link_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_mask_get(dev_id, ®_val); + *value = reg_val.bf.xgmac1_an_done_int_mask; + return ret; +} + +sw_error_t +hppe_port_link_int_mask_xgmac1_an_done_int_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_link_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_mask_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.xgmac1_an_done_int_mask = value; + ret = hppe_port_link_int_mask_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_link_int_mask_port1_link_chg_int_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_link_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_mask_get(dev_id, ®_val); + *value = reg_val.bf.port1_link_chg_int_mask; + return ret; +} + +sw_error_t +hppe_port_link_int_mask_port1_link_chg_int_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_link_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_mask_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port1_link_chg_int_mask = value; + ret = hppe_port_link_int_mask_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_link_int_mask_port5_0_link_chg_int_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_link_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_mask_get(dev_id, ®_val); + *value = reg_val.bf.port5_0_link_chg_int_mask; + return ret; +} + +sw_error_t +hppe_port_link_int_mask_port5_0_link_chg_int_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_link_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_mask_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port5_0_link_chg_int_mask = value; + ret = hppe_port_link_int_mask_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_link_int_mask_port6_link_chg_int_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_link_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_mask_get(dev_id, ®_val); + *value = reg_val.bf.port6_link_chg_int_mask; + return ret; +} + +sw_error_t +hppe_port_link_int_mask_port6_link_chg_int_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union port_link_int_mask_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_link_int_mask_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port6_link_chg_int_mask = value; + ret = hppe_port_link_int_mask_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_phy_status_0_port3_phy_status_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_phy_status_0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_phy_status_0_get(dev_id, ®_val); + *value = reg_val.bf.port3_phy_status; + return ret; +} + +sw_error_t +hppe_port_phy_status_0_port3_phy_status_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_port_phy_status_0_port4_phy_status_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_phy_status_0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_phy_status_0_get(dev_id, ®_val); + *value = reg_val.bf.port4_phy_status; + return ret; +} + +sw_error_t +hppe_port_phy_status_0_port4_phy_status_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_port_phy_status_0_port2_phy_status_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_phy_status_0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_phy_status_0_get(dev_id, ®_val); + *value = reg_val.bf.port2_phy_status; + return ret; +} + +sw_error_t +hppe_port_phy_status_0_port2_phy_status_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_port_phy_status_0_port1_phy_status_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_phy_status_0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_phy_status_0_get(dev_id, ®_val); + *value = reg_val.bf.port1_phy_status; + return ret; +} + +sw_error_t +hppe_port_phy_status_0_port1_phy_status_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_port_phy_status_1_port6_phy_status_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_phy_status_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_phy_status_1_get(dev_id, ®_val); + *value = reg_val.bf.port6_phy_status; + return ret; +} + +sw_error_t +hppe_port_phy_status_1_port6_phy_status_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_port_phy_status_1_port5_0_phy_status_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_phy_status_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_phy_status_1_get(dev_id, ®_val); + *value = reg_val.bf.port5_0_phy_status; + return ret; +} + +sw_error_t +hppe_port_phy_status_1_port5_0_phy_status_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_port_phy_status_1_port5_1_phy_status_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port_phy_status_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_phy_status_1_get(dev_id, ®_val); + *value = reg_val.bf.port5_1_phy_status; + return ret; +} + +sw_error_t +hppe_port_phy_status_1_port5_1_phy_status_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_port1_status_port1_status_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port1_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port1_status_get(dev_id, ®_val); + *value = reg_val.bf.port1_status; + return ret; +} + +sw_error_t +hppe_port1_status_port1_status_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_port2_status_port2_status_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port2_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port2_status_get(dev_id, ®_val); + *value = reg_val.bf.port2_status; + return ret; +} + +sw_error_t +hppe_port2_status_port2_status_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_port3_status_port3_status_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port3_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port3_status_get(dev_id, ®_val); + *value = reg_val.bf.port3_status; + return ret; +} + +sw_error_t +hppe_port3_status_port3_status_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_port4_status_port4_status_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port4_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port4_status_get(dev_id, ®_val); + *value = reg_val.bf.port4_status; + return ret; +} + +sw_error_t +hppe_port4_status_port4_status_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_port5_status_port3_mac_speed_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port5_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port5_status_get(dev_id, ®_val); + *value = reg_val.bf.port3_mac_speed; + return ret; +} + +sw_error_t +hppe_port5_status_port3_mac_speed_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_port5_status_port2_mac_speed_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port5_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port5_status_get(dev_id, ®_val); + *value = reg_val.bf.port2_mac_speed; + return ret; +} + +sw_error_t +hppe_port5_status_port2_mac_speed_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_port5_status_port1_mac_speed_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port5_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port5_status_get(dev_id, ®_val); + *value = reg_val.bf.port1_mac_speed; + return ret; +} + +sw_error_t +hppe_port5_status_port1_mac_speed_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_port5_status_port5_status_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port5_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port5_status_get(dev_id, ®_val); + *value = reg_val.bf.port5_status; + return ret; +} + +sw_error_t +hppe_port5_status_port5_status_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_port5_status_port4_mac_speed_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port5_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port5_status_get(dev_id, ®_val); + *value = reg_val.bf.port4_mac_speed; + return ret; +} + +sw_error_t +hppe_port5_status_port4_mac_speed_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_port6_status_port6_status_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union port6_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port6_status_get(dev_id, ®_val); + *value = reg_val.bf.port6_status; + return ret; +} + +sw_error_t +hppe_port6_status_port6_status_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_reserved_regs_0_spare_regs_0_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union reserved_regs_0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_reserved_regs_0_get(dev_id, ®_val); + *value = reg_val.bf.spare_regs_0; + return ret; +} + +sw_error_t +hppe_reserved_regs_0_spare_regs_0_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union reserved_regs_0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_reserved_regs_0_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.spare_regs_0 = value; + ret = hppe_reserved_regs_0_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_reserved_regs_1_spare_regs_1_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union reserved_regs_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_reserved_regs_1_get(dev_id, ®_val); + *value = reg_val.bf.spare_regs_1; + return ret; +} + +sw_error_t +hppe_reserved_regs_1_spare_regs_1_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union reserved_regs_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_reserved_regs_1_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.spare_regs_1 = value; + ret = hppe_reserved_regs_1_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_reserved_regs_2_spare_regs_2_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union reserved_regs_2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_reserved_regs_2_get(dev_id, ®_val); + *value = reg_val.bf.spare_regs_2; + return ret; +} + +sw_error_t +hppe_reserved_regs_2_spare_regs_2_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union reserved_regs_2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_reserved_regs_2_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.spare_regs_2 = value; + ret = hppe_reserved_regs_2_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_reserved_regs_3_spare_regs_3_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union reserved_regs_3_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_reserved_regs_3_get(dev_id, ®_val); + *value = reg_val.bf.spare_regs_3; + return ret; +} + +sw_error_t +hppe_reserved_regs_3_spare_regs_3_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union reserved_regs_3_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_reserved_regs_3_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.spare_regs_3 = value; + ret = hppe_reserved_regs_3_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_dbg_data_sel_dbg_data_sel_desp_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union dbg_data_sel_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_dbg_data_sel_get(dev_id, ®_val); + *value = reg_val.bf.dbg_data_sel_desp; + return ret; +} + +sw_error_t +hppe_dbg_data_sel_dbg_data_sel_desp_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union dbg_data_sel_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_dbg_data_sel_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.dbg_data_sel_desp = value; + ret = hppe_dbg_data_sel_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_dbg_data_sel_dbg_data_sel_switch_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union dbg_data_sel_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_dbg_data_sel_get(dev_id, ®_val); + *value = reg_val.bf.dbg_data_sel_switch; + return ret; +} + +sw_error_t +hppe_dbg_data_sel_dbg_data_sel_switch_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union dbg_data_sel_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_dbg_data_sel_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.dbg_data_sel_switch = value; + ret = hppe_dbg_data_sel_set(dev_id, ®_val); + return ret; +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_init.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_init.c new file mode 100755 index 000000000..1297d9c17 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_init.c @@ -0,0 +1,234 @@ +/* + * 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. + */ + + +/** + * @defgroup dess_init HPPE_INIT + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "sd.h" +#include "hsl_phy.h" + + +static ssdk_init_cfg * hppe_cfg[SW_MAX_NR_DEV] = { 0 }; + +a_bool_t hppe_xgmac_port_check(fal_port_t port_id) +{ + return ((port_id == 5) ||( port_id == 6)); +} +a_bool_t hppe_mac_port_valid_check(a_uint32_t dev_id, fal_port_t port_id) +{ + a_uint32_t bitmap = 0; + + bitmap = qca_ssdk_port_bmp_get(dev_id); + + return SW_IS_PBMP_MEMBER(bitmap, port_id); + +} + +static sw_error_t +hppe_portproperty_init(a_uint32_t dev_id) +{ + hsl_port_prop_t p_type; + hsl_dev_t *pdev = NULL; + fal_port_t port_id; + a_uint32_t bitmap = 0; + a_uint32_t inner_pbmp = 0; + + pdev = hsl_dev_ptr_get(dev_id); + if (pdev == NULL) + return SW_NOT_INITIALIZED; + + bitmap = qca_ssdk_port_bmp_get(dev_id); + inner_pbmp = hsl_dev_inner_ports_get(dev_id); + + /* for port property set, SSDK should not generate some limitations */ + for (port_id = 0; port_id < SW_MAX_NR_PORT; port_id++) + { + if ((port_id == pdev->cpu_port_nr) || + (bitmap & (0x1 << port_id)) || + (inner_pbmp & (0x1 << port_id))) + { + hsl_port_prop_portmap_set(dev_id, port_id); + + for (p_type = HSL_PP_PHY; p_type < HSL_PP_BUTT; p_type++) + { + switch (p_type) + { + case HSL_PP_PHY:/*front ports*/ + if (SW_IS_PBMP_MEMBER(bitmap, port_id)) + { + SW_RTN_ON_ERROR + (hsl_port_prop_set(dev_id, port_id,p_type)); + } + break; + + case HSL_PP_INNER:/*inner ports*/ + if (SW_IS_PBMP_MEMBER(inner_pbmp, port_id)) + { + SW_RTN_ON_ERROR + (hsl_port_prop_set(dev_id, port_id,p_type)); + } + break; + + case HSL_PP_INCL_CPU: + /*the ports include cpu port*/ + SW_RTN_ON_ERROR + (hsl_port_prop_set(dev_id, port_id, p_type)); + break; + + case HSL_PP_EXCL_CPU: + /*the ports exclude cpu port*/ + if (port_id != pdev->cpu_port_nr) + { + SW_RTN_ON_ERROR + (hsl_port_prop_set(dev_id, port_id,p_type)); + } + break; + + case HSL_PP_CPU:/*cpu port*/ + if (port_id == pdev->cpu_port_nr) + { + SW_RTN_ON_ERROR + (hsl_port_prop_set(dev_id, port_id,p_type)); + } + break; + + default: + break; + } + } + } + } + return SW_OK; +} + +static sw_error_t +hppe_dev_init(a_uint32_t dev_id, ssdk_init_cfg *cfg) +{ + hsl_dev_t *pdev = NULL; + a_uint32_t i = 0, port_nr = 0, tmp = 0; + + pdev = hsl_dev_ptr_get(dev_id); + if (pdev == NULL) + return SW_NOT_INITIALIZED; + + tmp = cfg->port_cfg.lan_bmp | cfg->port_cfg.wan_bmp; + for(i = 0; i < SW_MAX_NR_PORT; i++) { + if(tmp & (1 << i)) { + port_nr++; + } + } + pdev->nr_phy = port_nr; + + for(i = 0; i < SW_MAX_NR_PORT; i++) { + if(cfg->port_cfg.inner_bmp & (1 << i)) { + port_nr++; + } + } + + for(i = 0; i < SW_MAX_NR_PORT; i++) { + if(cfg->port_cfg.cpu_bmp & (1 << i)) { + port_nr++; + pdev->cpu_port_nr = i; + break; + } + } + if(i >= SW_MAX_NR_PORT) + return SW_BAD_VALUE; + pdev->nr_ports = port_nr; + pdev->nr_vlans = 4096; + pdev->hw_vlan_query = A_TRUE; + pdev->nr_queue = port_nr; + pdev->cpu_mode = cfg->cpu_mode; + pdev->wan_bmp = cfg->port_cfg.wan_bmp; + + return SW_OK; +} + +sw_error_t +hppe_cleanup(a_uint32_t dev_id) +{ + + if (hppe_cfg[dev_id]) + { + SW_RTN_ON_ERROR(hsl_port_prop_cleanup_by_dev(dev_id)); + + aos_mem_free(hppe_cfg[dev_id]); + hppe_cfg[dev_id] = NULL; + } + + return SW_OK; +} + +/** + * @brief Init hsl layer. + * @details Comments: + * This operation will init hsl layer and hsl layer + * @param[in] dev_id device id + * @param[in] cfg configuration for initialization + * @return SW_OK or error code + */ +sw_error_t hppe_init(a_uint32_t dev_id, ssdk_init_cfg *cfg) +{ + HSL_DEV_ID_CHECK(dev_id); + + printk("HPPE initializing...\n"); + if (NULL == hppe_cfg[dev_id]) + { + hppe_cfg[dev_id] = aos_mem_alloc(sizeof (ssdk_init_cfg)); + } + + if (NULL == hppe_cfg[dev_id]) + { + return SW_OUT_OF_MEM; + } + + aos_mem_copy(hppe_cfg[dev_id], cfg, sizeof (ssdk_init_cfg)); + + SW_RTN_ON_ERROR(hppe_dev_init(dev_id, cfg)); + +#if !(defined(KERNEL_MODULE) && defined(USER_MODE)) + { + hsl_api_t *p_api; + + SW_RTN_ON_ERROR(hsl_port_prop_init(dev_id)); + SW_RTN_ON_ERROR(hsl_port_prop_init_by_dev(dev_id)); + SW_RTN_ON_ERROR(hppe_portproperty_init(dev_id)); + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->dev_clean = hppe_cleanup; + p_api->reg_get = sd_reg_hdr_get; + p_api->reg_set = sd_reg_hdr_set; + p_api->phy_get = sd_reg_mdio_get; + p_api->phy_set = sd_reg_mdio_set; + p_api->phy_i2c_get = sd_reg_i2c_get; + p_api->phy_i2c_set = sd_reg_i2c_set; + p_api->uniphy_reg_get = sd_reg_uniphy_get; + p_api->uniphy_reg_set = sd_reg_uniphy_set; + + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_ip.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_ip.c new file mode 100755 index 000000000..81af477cb --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_ip.c @@ -0,0 +1,6892 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hppe_reg_access.h" +#include "hppe_ip_reg.h" +#include "hppe_ip.h" + +#ifndef IN_IP_MINI +static a_uint32_t host_cmd_id = 0; +sw_error_t +hppe_rt_interface_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union rt_interface_cnt_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + INGRESS_POLICER_BASE_ADDR + RT_INTERFACE_CNT_TBL_ADDRESS + \ + index * RT_INTERFACE_CNT_TBL_INC, + value->val, + 5); +} + +sw_error_t +hppe_rt_interface_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union rt_interface_cnt_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + INGRESS_POLICER_BASE_ADDR + RT_INTERFACE_CNT_TBL_ADDRESS + \ + index * RT_INTERFACE_CNT_TBL_INC, + value->val, + 5); +} + +sw_error_t +hppe_my_mac_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union my_mac_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + IPE_L3_BASE_ADDR + MY_MAC_TBL_ADDRESS + \ + index * MY_MAC_TBL_INC, + value->val, + 2); +} + +sw_error_t +hppe_my_mac_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union my_mac_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + IPE_L3_BASE_ADDR + MY_MAC_TBL_ADDRESS + \ + index * MY_MAC_TBL_INC, + value->val, + 2); +} + +sw_error_t +hppe_l3_vsi_get( + a_uint32_t dev_id, + a_uint32_t index, + union l3_vsi_u *value) +{ + if (index >= L3_VSI_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + L3_VSI_ADDRESS + \ + index * L3_VSI_INC, + &value->val); +} + +sw_error_t +hppe_l3_vsi_set( + a_uint32_t dev_id, + a_uint32_t index, + union l3_vsi_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + L3_VSI_ADDRESS + \ + index * L3_VSI_INC, + value->val); +} + +sw_error_t +hppe_l3_vsi_ext_get( + a_uint32_t dev_id, + a_uint32_t index, + union l3_vsi_ext_u *value) +{ + if (index >= L3_VSI_EXT_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + L3_VSI_EXT_ADDRESS + \ + index * L3_VSI_EXT_INC, + &value->val); +} + +sw_error_t +hppe_l3_vsi_ext_set( + a_uint32_t dev_id, + a_uint32_t index, + union l3_vsi_ext_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + L3_VSI_EXT_ADDRESS + \ + index * L3_VSI_EXT_INC, + value->val); +} + +sw_error_t +hppe_network_route_ip_get( + a_uint32_t dev_id, + a_uint32_t index, + union network_route_ip_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + IPE_L3_BASE_ADDR + NETWORK_ROUTE_IP_ADDRESS + \ + index * NETWORK_ROUTE_IP_INC, + value->val, + 2); +} + +sw_error_t +hppe_in_pub_ip_addr_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union in_pub_ip_addr_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + IN_PUB_IP_ADDR_TBL_ADDRESS + \ + index * IN_PUB_IP_ADDR_TBL_INC, + value->val); +} + + +sw_error_t +hppe_in_pub_ip_addr_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union in_pub_ip_addr_tbl_u *value) +{ + if (index >= IN_PUB_IP_ADDR_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + IN_PUB_IP_ADDR_TBL_ADDRESS + \ + index * IN_PUB_IP_ADDR_TBL_INC, + &value->val); +} + +sw_error_t +hppe_network_route_ip_set( + a_uint32_t dev_id, + a_uint32_t index, + union network_route_ip_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + IPE_L3_BASE_ADDR + NETWORK_ROUTE_IP_ADDRESS + \ + index * NETWORK_ROUTE_IP_INC, + value->val, + 2); +} + +sw_error_t +hppe_network_route_ip_ext_get( + a_uint32_t dev_id, + a_uint32_t index, + union network_route_ip_ext_u *value) +{ + if (index >= NETWORK_ROUTE_IP_EXT_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + NETWORK_ROUTE_IP_EXT_ADDRESS + \ + index * NETWORK_ROUTE_IP_EXT_INC, + &value->val); +} + +sw_error_t +hppe_network_route_ip_ext_set( + a_uint32_t dev_id, + a_uint32_t index, + union network_route_ip_ext_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + NETWORK_ROUTE_IP_EXT_ADDRESS + \ + index * NETWORK_ROUTE_IP_EXT_INC, + value->val); +} + +sw_error_t +hppe_network_route_action_get( + a_uint32_t dev_id, + a_uint32_t index, + union network_route_action_u *value) +{ + if (index >= NETWORK_ROUTE_ACTION_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + NETWORK_ROUTE_ACTION_ADDRESS + \ + index * NETWORK_ROUTE_ACTION_INC, + &value->val); +} + +sw_error_t +hppe_network_route_action_set( + a_uint32_t dev_id, + a_uint32_t index, + union network_route_action_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + NETWORK_ROUTE_ACTION_ADDRESS + \ + index * NETWORK_ROUTE_ACTION_INC, + value->val); +} +#endif +#if ((!defined IN_IP_MINI) || (!defined IN_FLOW_MINI)) +sw_error_t +hppe_l3_route_ctrl_get( + a_uint32_t dev_id, + union l3_route_ctrl_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + L3_ROUTE_CTRL_ADDRESS, + &value->val); +} + +sw_error_t +hppe_l3_route_ctrl_set( + a_uint32_t dev_id, + union l3_route_ctrl_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + L3_ROUTE_CTRL_ADDRESS, + value->val); +} + +sw_error_t +hppe_l3_route_ctrl_ext_get( + a_uint32_t dev_id, + union l3_route_ctrl_ext_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + L3_ROUTE_CTRL_EXT_ADDRESS, + &value->val); +} + +sw_error_t +hppe_l3_route_ctrl_ext_set( + a_uint32_t dev_id, + union l3_route_ctrl_ext_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + L3_ROUTE_CTRL_EXT_ADDRESS, + value->val); +} +#endif +#ifndef IN_IP_MINI +sw_error_t +hppe_host_tbl_op_get( + a_uint32_t dev_id, + union host_tbl_op_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_OP_ADDRESS, + &value->val); +} + +sw_error_t +hppe_host_tbl_op_set( + a_uint32_t dev_id, + union host_tbl_op_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_OP_ADDRESS, + value->val); +} +#endif +#if ((!defined IN_IP_MINI) || (!defined IN_FLOW_MINI)) +sw_error_t +hppe_host_tbl_op_data0_get( + a_uint32_t dev_id, + union host_tbl_op_data0_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_OP_DATA0_ADDRESS, + &value->val); +} + +sw_error_t +hppe_host_tbl_op_data0_set( + a_uint32_t dev_id, + union host_tbl_op_data0_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_OP_DATA0_ADDRESS, + value->val); +} + +sw_error_t +hppe_host_tbl_op_data1_get( + a_uint32_t dev_id, + union host_tbl_op_data1_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_OP_DATA1_ADDRESS, + &value->val); +} + +sw_error_t +hppe_host_tbl_op_data1_set( + a_uint32_t dev_id, + union host_tbl_op_data1_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_OP_DATA1_ADDRESS, + value->val); +} + +sw_error_t +hppe_host_tbl_op_data2_get( + a_uint32_t dev_id, + union host_tbl_op_data2_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_OP_DATA2_ADDRESS, + &value->val); +} + +sw_error_t +hppe_host_tbl_op_data2_set( + a_uint32_t dev_id, + union host_tbl_op_data2_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_OP_DATA2_ADDRESS, + value->val); +} + +sw_error_t +hppe_host_tbl_op_data3_get( + a_uint32_t dev_id, + union host_tbl_op_data3_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_OP_DATA3_ADDRESS, + &value->val); +} + +sw_error_t +hppe_host_tbl_op_data3_set( + a_uint32_t dev_id, + union host_tbl_op_data3_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_OP_DATA3_ADDRESS, + value->val); +} + +sw_error_t +hppe_host_tbl_op_data4_get( + a_uint32_t dev_id, + union host_tbl_op_data4_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_OP_DATA4_ADDRESS, + &value->val); +} + +sw_error_t +hppe_host_tbl_op_data4_set( + a_uint32_t dev_id, + union host_tbl_op_data4_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_OP_DATA4_ADDRESS, + value->val); +} +#endif +#ifndef IN_IP_MINI +sw_error_t +hppe_host_tbl_op_data5_get( + a_uint32_t dev_id, + union host_tbl_op_data5_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_OP_DATA5_ADDRESS, + &value->val); +} + +sw_error_t +hppe_host_tbl_op_data5_set( + a_uint32_t dev_id, + union host_tbl_op_data5_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_OP_DATA5_ADDRESS, + value->val); +} + +sw_error_t +hppe_host_tbl_op_data6_get( + a_uint32_t dev_id, + union host_tbl_op_data6_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_OP_DATA6_ADDRESS, + &value->val); +} + +sw_error_t +hppe_host_tbl_op_data6_set( + a_uint32_t dev_id, + union host_tbl_op_data6_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_OP_DATA6_ADDRESS, + value->val); +} + +sw_error_t +hppe_host_tbl_op_data7_get( + a_uint32_t dev_id, + union host_tbl_op_data7_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_OP_DATA7_ADDRESS, + &value->val); +} + +sw_error_t +hppe_host_tbl_op_data7_set( + a_uint32_t dev_id, + union host_tbl_op_data7_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_OP_DATA7_ADDRESS, + value->val); +} + +sw_error_t +hppe_host_tbl_op_data8_get( + a_uint32_t dev_id, + union host_tbl_op_data8_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_OP_DATA8_ADDRESS, + &value->val); +} + +sw_error_t +hppe_host_tbl_op_data8_set( + a_uint32_t dev_id, + union host_tbl_op_data8_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_OP_DATA8_ADDRESS, + value->val); +} + +sw_error_t +hppe_host_tbl_op_data9_get( + a_uint32_t dev_id, + union host_tbl_op_data9_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_OP_DATA9_ADDRESS, + &value->val); +} + +sw_error_t +hppe_host_tbl_op_data9_set( + a_uint32_t dev_id, + union host_tbl_op_data9_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_OP_DATA9_ADDRESS, + value->val); +} + +sw_error_t +hppe_host_tbl_op_rslt_get( + a_uint32_t dev_id, + union host_tbl_op_rslt_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_OP_RSLT_ADDRESS, + &value->val); +} + +sw_error_t +hppe_host_tbl_op_rslt_set( + a_uint32_t dev_id, + union host_tbl_op_rslt_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_host_tbl_rd_op_get( + a_uint32_t dev_id, + union host_tbl_rd_op_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_RD_OP_ADDRESS, + &value->val); +} + +sw_error_t +hppe_host_tbl_rd_op_set( + a_uint32_t dev_id, + union host_tbl_rd_op_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_RD_OP_ADDRESS, + value->val); +} +#endif +#if ((!defined IN_IP_MINI) || (!defined IN_FLOW_MINI)) +sw_error_t +hppe_host_tbl_rd_op_data0_get( + a_uint32_t dev_id, + union host_tbl_rd_op_data0_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_RD_OP_DATA0_ADDRESS, + &value->val); +} + +sw_error_t +hppe_host_tbl_rd_op_data0_set( + a_uint32_t dev_id, + union host_tbl_rd_op_data0_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_RD_OP_DATA0_ADDRESS, + value->val); +} + +sw_error_t +hppe_host_tbl_rd_op_data1_get( + a_uint32_t dev_id, + union host_tbl_rd_op_data1_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_RD_OP_DATA1_ADDRESS, + &value->val); +} + +sw_error_t +hppe_host_tbl_rd_op_data1_set( + a_uint32_t dev_id, + union host_tbl_rd_op_data1_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_RD_OP_DATA1_ADDRESS, + value->val); +} + +sw_error_t +hppe_host_tbl_rd_op_data2_get( + a_uint32_t dev_id, + union host_tbl_rd_op_data2_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_RD_OP_DATA2_ADDRESS, + &value->val); +} + +sw_error_t +hppe_host_tbl_rd_op_data2_set( + a_uint32_t dev_id, + union host_tbl_rd_op_data2_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_RD_OP_DATA2_ADDRESS, + value->val); +} + +sw_error_t +hppe_host_tbl_rd_op_data3_get( + a_uint32_t dev_id, + union host_tbl_rd_op_data3_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_RD_OP_DATA3_ADDRESS, + &value->val); +} + +sw_error_t +hppe_host_tbl_rd_op_data3_set( + a_uint32_t dev_id, + union host_tbl_rd_op_data3_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_RD_OP_DATA3_ADDRESS, + value->val); +} + +sw_error_t +hppe_host_tbl_rd_op_data4_get( + a_uint32_t dev_id, + union host_tbl_rd_op_data4_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_RD_OP_DATA4_ADDRESS, + &value->val); +} + +sw_error_t +hppe_host_tbl_rd_op_data4_set( + a_uint32_t dev_id, + union host_tbl_rd_op_data4_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_RD_OP_DATA4_ADDRESS, + value->val); +} +#endif +#ifndef IN_IP_MINI +sw_error_t +hppe_host_tbl_rd_op_data5_get( + a_uint32_t dev_id, + union host_tbl_rd_op_data5_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_RD_OP_DATA5_ADDRESS, + &value->val); +} + +sw_error_t +hppe_host_tbl_rd_op_data5_set( + a_uint32_t dev_id, + union host_tbl_rd_op_data5_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_RD_OP_DATA5_ADDRESS, + value->val); +} + +sw_error_t +hppe_host_tbl_rd_op_data6_get( + a_uint32_t dev_id, + union host_tbl_rd_op_data6_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_RD_OP_DATA6_ADDRESS, + &value->val); +} + +sw_error_t +hppe_host_tbl_rd_op_data6_set( + a_uint32_t dev_id, + union host_tbl_rd_op_data6_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_RD_OP_DATA6_ADDRESS, + value->val); +} + +sw_error_t +hppe_host_tbl_rd_op_data7_get( + a_uint32_t dev_id, + union host_tbl_rd_op_data7_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_RD_OP_DATA7_ADDRESS, + &value->val); +} + +sw_error_t +hppe_host_tbl_rd_op_data7_set( + a_uint32_t dev_id, + union host_tbl_rd_op_data7_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_RD_OP_DATA7_ADDRESS, + value->val); +} + +sw_error_t +hppe_host_tbl_rd_op_data8_get( + a_uint32_t dev_id, + union host_tbl_rd_op_data8_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_RD_OP_DATA8_ADDRESS, + &value->val); +} + +sw_error_t +hppe_host_tbl_rd_op_data8_set( + a_uint32_t dev_id, + union host_tbl_rd_op_data8_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_RD_OP_DATA8_ADDRESS, + value->val); +} + +sw_error_t +hppe_host_tbl_rd_op_data9_get( + a_uint32_t dev_id, + union host_tbl_rd_op_data9_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_RD_OP_DATA9_ADDRESS, + &value->val); +} + +sw_error_t +hppe_host_tbl_rd_op_data9_set( + a_uint32_t dev_id, + union host_tbl_rd_op_data9_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_RD_OP_DATA9_ADDRESS, + value->val); +} + +sw_error_t +hppe_host_tbl_rd_op_rslt_get( + a_uint32_t dev_id, + union host_tbl_rd_op_rslt_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_RD_OP_RSLT_ADDRESS, + &value->val); +} + +sw_error_t +hppe_host_tbl_rd_op_rslt_set( + a_uint32_t dev_id, + union host_tbl_rd_op_rslt_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_host_tbl_rd_rslt_data0_get( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data0_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_RD_RSLT_DATA0_ADDRESS, + &value->val); +} + +sw_error_t +hppe_host_tbl_rd_rslt_data0_set( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data0_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_host_tbl_rd_rslt_data1_get( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data1_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_RD_RSLT_DATA1_ADDRESS, + &value->val); +} + +sw_error_t +hppe_host_tbl_rd_rslt_data1_set( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data1_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_host_tbl_rd_rslt_data2_get( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data2_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_RD_RSLT_DATA2_ADDRESS, + &value->val); +} + +sw_error_t +hppe_host_tbl_rd_rslt_data2_set( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data2_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_host_tbl_rd_rslt_data3_get( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data3_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_RD_RSLT_DATA3_ADDRESS, + &value->val); +} + +sw_error_t +hppe_host_tbl_rd_rslt_data3_set( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data3_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_host_tbl_rd_rslt_data4_get( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data4_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_RD_RSLT_DATA4_ADDRESS, + &value->val); +} + +sw_error_t +hppe_host_tbl_rd_rslt_data4_set( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data4_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_host_tbl_rd_rslt_data5_get( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data5_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_RD_RSLT_DATA5_ADDRESS, + &value->val); +} + +sw_error_t +hppe_host_tbl_rd_rslt_data5_set( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data5_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_host_tbl_rd_rslt_data6_get( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data6_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_RD_RSLT_DATA6_ADDRESS, + &value->val); +} + +sw_error_t +hppe_host_tbl_rd_rslt_data6_set( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data6_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_host_tbl_rd_rslt_data7_get( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data7_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_RD_RSLT_DATA7_ADDRESS, + &value->val); +} + +sw_error_t +hppe_host_tbl_rd_rslt_data7_set( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data7_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_host_tbl_rd_rslt_data8_get( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data8_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_RD_RSLT_DATA8_ADDRESS, + &value->val); +} + +sw_error_t +hppe_host_tbl_rd_rslt_data8_set( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data8_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_host_tbl_rd_rslt_data9_get( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data9_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_RD_RSLT_DATA9_ADDRESS, + &value->val); +} + +sw_error_t +hppe_host_tbl_rd_rslt_data9_set( + a_uint32_t dev_id, + union host_tbl_rd_rslt_data9_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l3_dbg_cmd_get( + a_uint32_t dev_id, + union l3_dbg_cmd_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + L3_DBG_CMD_ADDRESS, + &value->val); +} + +sw_error_t +hppe_l3_dbg_cmd_set( + a_uint32_t dev_id, + union l3_dbg_cmd_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + L3_DBG_CMD_ADDRESS, + value->val); +} + +sw_error_t +hppe_l3_dbg_wr_data_get( + a_uint32_t dev_id, + union l3_dbg_wr_data_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + L3_DBG_WR_DATA_ADDRESS, + &value->val); +} + +sw_error_t +hppe_l3_dbg_wr_data_set( + a_uint32_t dev_id, + union l3_dbg_wr_data_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + L3_DBG_WR_DATA_ADDRESS, + value->val); +} + +sw_error_t +hppe_l3_dbg_rd_data_get( + a_uint32_t dev_id, + union l3_dbg_rd_data_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + L3_DBG_RD_DATA_ADDRESS, + &value->val); +} + +sw_error_t +hppe_l3_dbg_rd_data_set( + a_uint32_t dev_id, + union l3_dbg_rd_data_u *value) +{ + return SW_NOT_SUPPORTED; +} +#endif +sw_error_t +hppe_l3_vp_port_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l3_vp_port_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + IPE_L3_BASE_ADDR + L3_VP_PORT_TBL_ADDRESS + \ + index * L3_VP_PORT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_l3_vp_port_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l3_vp_port_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + IPE_L3_BASE_ADDR + L3_VP_PORT_TBL_ADDRESS + \ + index * L3_VP_PORT_TBL_INC, + value->val, + 3); +} +#if ((!defined IN_IP_MINI) || (defined IN_PPPOE)) +sw_error_t +hppe_in_l3_if_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union in_l3_if_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + IPE_L3_BASE_ADDR + IN_L3_IF_TBL_ADDRESS + \ + index * IN_L3_IF_TBL_INC, + value->val, + 2); +} + +sw_error_t +hppe_in_l3_if_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union in_l3_if_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + IPE_L3_BASE_ADDR + IN_L3_IF_TBL_ADDRESS + \ + index * IN_L3_IF_TBL_INC, + value->val, + 2); +} +#endif +#ifndef IN_IP_MINI +sw_error_t +hppe_host_ipv6_mcast_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union host_ipv6_mcast_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_IPV6_MCAST_TBL_ADDRESS + \ + index * HOST_IPV6_MCAST_TBL_INC, + value->val, + 10); +} + +sw_error_t +hppe_host_ipv6_mcast_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union host_ipv6_mcast_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + IPE_L3_BASE_ADDR + HOST_IPV6_MCAST_TBL_ADDRESS + \ + index * HOST_IPV6_MCAST_TBL_INC, + value->val, + 10); +} + +sw_error_t +hppe_host_ipv4_mcast_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union host_ipv4_mcast_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_IPV4_MCAST_TBL_ADDRESS + \ + index * HOST_IPV4_MCAST_TBL_INC, + value->val, + 5); +} + +sw_error_t +hppe_host_ipv4_mcast_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union host_ipv4_mcast_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + IPE_L3_BASE_ADDR + HOST_IPV4_MCAST_TBL_ADDRESS + \ + index * HOST_IPV4_MCAST_TBL_INC, + value->val, + 5); +} + +sw_error_t +hppe_host_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union host_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_ADDRESS + \ + index * HOST_TBL_INC, + value->val, + 2); +} + +sw_error_t +hppe_host_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union host_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_ADDRESS + \ + index * HOST_TBL_INC, + value->val, + 2); +} + +sw_error_t +hppe_host_ipv6_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union host_ipv6_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_IPV6_TBL_ADDRESS + \ + index * HOST_IPV6_TBL_INC, + value->val, + 5); +} + +sw_error_t +hppe_host_ipv6_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union host_ipv6_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + IPE_L3_BASE_ADDR + HOST_IPV6_TBL_ADDRESS + \ + index * HOST_IPV6_TBL_INC, + value->val, + 5); +} + +sw_error_t +hppe_in_nexthop_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union in_nexthop_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + IPE_L3_BASE_ADDR + IN_NEXTHOP_TBL_ADDRESS + \ + index * IN_NEXTHOP_TBL_INC, + value->val, + 4); +} + +sw_error_t +hppe_in_nexthop_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union in_nexthop_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + IPE_L3_BASE_ADDR + IN_NEXTHOP_TBL_ADDRESS + \ + index * IN_NEXTHOP_TBL_INC, + value->val, + 4); +} +#endif +#if ((!defined IN_IP_MINI) || (defined IN_PPPOE)) +sw_error_t +hppe_eg_l3_if_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union eg_l3_if_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + NSS_PTX_CSR_BASE_ADDR + EG_L3_IF_TBL_ADDRESS + \ + index * EG_L3_IF_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_eg_l3_if_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union eg_l3_if_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + NSS_PTX_CSR_BASE_ADDR + EG_L3_IF_TBL_ADDRESS + \ + index * EG_L3_IF_TBL_INC, + value->val, + 3); +} +#endif +#ifndef IN_IP_MINI +sw_error_t +hppe_my_mac_tbl_mac_da_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union my_mac_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_my_mac_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.mac_da_1 << 32 | \ + reg_val.bf.mac_da_0; + return ret; +} + +sw_error_t +hppe_my_mac_tbl_mac_da_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union my_mac_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_my_mac_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_da_1 = value >> 32; + reg_val.bf.mac_da_0 = value & (((a_uint64_t)1<<32)-1); + ret = hppe_my_mac_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_my_mac_tbl_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union my_mac_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_my_mac_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.valid; + return ret; +} + +sw_error_t +hppe_my_mac_tbl_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union my_mac_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_my_mac_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.valid = value; + ret = hppe_my_mac_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vsi_l3_if_index_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vsi_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_get(dev_id, index, ®_val); + *value = reg_val.bf.l3_if_index; + return ret; +} + +sw_error_t +hppe_l3_vsi_l3_if_index_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vsi_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l3_if_index = value; + ret = hppe_l3_vsi_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vsi_l2_ipv6_mc_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vsi_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_get(dev_id, index, ®_val); + *value = reg_val.bf.l2_ipv6_mc_mode; + return ret; +} + +sw_error_t +hppe_l3_vsi_l2_ipv6_mc_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vsi_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l2_ipv6_mc_mode = value; + ret = hppe_l3_vsi_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vsi_l3_if_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vsi_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_get(dev_id, index, ®_val); + *value = reg_val.bf.l3_if_valid; + return ret; +} + +sw_error_t +hppe_l3_vsi_l3_if_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vsi_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l3_if_valid = value; + ret = hppe_l3_vsi_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vsi_l2_ipv6_mc_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vsi_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_get(dev_id, index, ®_val); + *value = reg_val.bf.l2_ipv6_mc_en; + return ret; +} + +sw_error_t +hppe_l3_vsi_l2_ipv6_mc_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vsi_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l2_ipv6_mc_en = value; + ret = hppe_l3_vsi_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vsi_l2_ipv4_mc_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vsi_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_get(dev_id, index, ®_val); + *value = reg_val.bf.l2_ipv4_mc_en; + return ret; +} + +sw_error_t +hppe_l3_vsi_l2_ipv4_mc_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vsi_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l2_ipv4_mc_en = value; + ret = hppe_l3_vsi_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vsi_l2_ipv4_mc_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vsi_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_get(dev_id, index, ®_val); + *value = reg_val.bf.l2_ipv4_mc_mode; + return ret; +} + +sw_error_t +hppe_l3_vsi_l2_ipv4_mc_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vsi_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l2_ipv4_mc_mode = value; + ret = hppe_l3_vsi_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ip_arp_sg_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + *value = reg_val.bf.ip_arp_sg_en; + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ip_arp_sg_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_arp_sg_en = value; + ret = hppe_l3_vsi_ext_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ipv6_sg_svlan_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + *value = reg_val.bf.ipv6_sg_svlan_en; + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ipv6_sg_svlan_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv6_sg_svlan_en = value; + ret = hppe_l3_vsi_ext_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ip_nd_sg_cvlan_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + *value = reg_val.bf.ip_nd_sg_cvlan_en; + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ip_nd_sg_cvlan_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_nd_sg_cvlan_en = value; + ret = hppe_l3_vsi_ext_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ip_nd_sg_vio_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + *value = reg_val.bf.ip_nd_sg_vio_cmd; + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ip_nd_sg_vio_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_nd_sg_vio_cmd = value; + ret = hppe_l3_vsi_ext_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ipv4_sg_port_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + *value = reg_val.bf.ipv4_sg_port_en; + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ipv4_sg_port_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv4_sg_port_en = value; + ret = hppe_l3_vsi_ext_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ip_nd_sg_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + *value = reg_val.bf.ip_nd_sg_en; + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ip_nd_sg_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_nd_sg_en = value; + ret = hppe_l3_vsi_ext_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ipv4_sg_svlan_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + *value = reg_val.bf.ipv4_sg_svlan_en; + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ipv4_sg_svlan_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv4_sg_svlan_en = value; + ret = hppe_l3_vsi_ext_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ipv4_sg_cvlan_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + *value = reg_val.bf.ipv4_sg_cvlan_en; + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ipv4_sg_cvlan_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv4_sg_cvlan_en = value; + ret = hppe_l3_vsi_ext_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ip_arp_sg_svlan_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + *value = reg_val.bf.ip_arp_sg_svlan_en; + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ip_arp_sg_svlan_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_arp_sg_svlan_en = value; + ret = hppe_l3_vsi_ext_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ip_nd_sg_svlan_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + *value = reg_val.bf.ip_nd_sg_svlan_en; + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ip_nd_sg_svlan_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_nd_sg_svlan_en = value; + ret = hppe_l3_vsi_ext_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ipv6_sg_vio_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + *value = reg_val.bf.ipv6_sg_vio_cmd; + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ipv6_sg_vio_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv6_sg_vio_cmd = value; + ret = hppe_l3_vsi_ext_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ip_nd_sg_port_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + *value = reg_val.bf.ip_nd_sg_port_en; + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ip_nd_sg_port_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_nd_sg_port_en = value; + ret = hppe_l3_vsi_ext_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ip_arp_src_unk_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + *value = reg_val.bf.ip_arp_src_unk_cmd; + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ip_arp_src_unk_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_arp_src_unk_cmd = value; + ret = hppe_l3_vsi_ext_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ipv6_sg_port_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + *value = reg_val.bf.ipv6_sg_port_en; + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ipv6_sg_port_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv6_sg_port_en = value; + ret = hppe_l3_vsi_ext_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ipv4_src_unk_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + *value = reg_val.bf.ipv4_src_unk_cmd; + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ipv4_src_unk_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv4_src_unk_cmd = value; + ret = hppe_l3_vsi_ext_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ip_arp_sg_vio_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + *value = reg_val.bf.ip_arp_sg_vio_cmd; + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ip_arp_sg_vio_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_arp_sg_vio_cmd = value; + ret = hppe_l3_vsi_ext_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ip_arp_sg_port_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + *value = reg_val.bf.ip_arp_sg_port_en; + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ip_arp_sg_port_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_arp_sg_port_en = value; + ret = hppe_l3_vsi_ext_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ipv4_sg_vio_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + *value = reg_val.bf.ipv4_sg_vio_cmd; + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ipv4_sg_vio_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv4_sg_vio_cmd = value; + ret = hppe_l3_vsi_ext_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ipv6_src_unk_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + *value = reg_val.bf.ipv6_src_unk_cmd; + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ipv6_src_unk_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv6_src_unk_cmd = value; + ret = hppe_l3_vsi_ext_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ipv6_sg_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + *value = reg_val.bf.ipv6_sg_en; + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ipv6_sg_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv6_sg_en = value; + ret = hppe_l3_vsi_ext_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ip_arp_sg_cvlan_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + *value = reg_val.bf.ip_arp_sg_cvlan_en; + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ip_arp_sg_cvlan_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_arp_sg_cvlan_en = value; + ret = hppe_l3_vsi_ext_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ip_nd_src_unk_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + *value = reg_val.bf.ip_nd_src_unk_cmd; + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ip_nd_src_unk_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_nd_src_unk_cmd = value; + ret = hppe_l3_vsi_ext_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ipv4_sg_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + *value = reg_val.bf.ipv4_sg_en; + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ipv4_sg_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv4_sg_en = value; + ret = hppe_l3_vsi_ext_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ipv6_sg_cvlan_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + *value = reg_val.bf.ipv6_sg_cvlan_en; + return ret; +} + +sw_error_t +hppe_l3_vsi_ext_ipv6_sg_cvlan_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vsi_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vsi_ext_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv6_sg_cvlan_en = value; + ret = hppe_l3_vsi_ext_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_network_route_ip_ip_addr_mask_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union network_route_ip_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_network_route_ip_get(dev_id, index, ®_val); + *value = reg_val.bf.ip_addr_mask; + return ret; +} + +sw_error_t +hppe_network_route_ip_ip_addr_mask_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union network_route_ip_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_network_route_ip_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_addr_mask = value; + ret = hppe_network_route_ip_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_network_route_ip_ip_addr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union network_route_ip_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_network_route_ip_get(dev_id, index, ®_val); + *value = reg_val.bf.ip_addr; + return ret; +} + +sw_error_t +hppe_network_route_ip_ip_addr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union network_route_ip_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_network_route_ip_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_addr = value; + ret = hppe_network_route_ip_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_network_route_ip_ext_entry_type_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union network_route_ip_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_network_route_ip_ext_get(dev_id, index, ®_val); + *value = reg_val.bf.entry_type; + return ret; +} + +sw_error_t +hppe_network_route_ip_ext_entry_type_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union network_route_ip_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_network_route_ip_ext_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.entry_type = value; + ret = hppe_network_route_ip_ext_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_network_route_ip_ext_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union network_route_ip_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_network_route_ip_ext_get(dev_id, index, ®_val); + *value = reg_val.bf.valid; + return ret; +} + +sw_error_t +hppe_network_route_ip_ext_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union network_route_ip_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_network_route_ip_ext_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.valid = value; + ret = hppe_network_route_ip_ext_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_network_route_action_lan_wan_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union network_route_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_network_route_action_get(dev_id, index, ®_val); + *value = reg_val.bf.lan_wan; + return ret; +} + +sw_error_t +hppe_network_route_action_lan_wan_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union network_route_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_network_route_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.lan_wan = value; + ret = hppe_network_route_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_network_route_action_fwd_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union network_route_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_network_route_action_get(dev_id, index, ®_val); + *value = reg_val.bf.fwd_cmd; + return ret; +} + +sw_error_t +hppe_network_route_action_fwd_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union network_route_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_network_route_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.fwd_cmd = value; + ret = hppe_network_route_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_network_route_action_dst_info_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union network_route_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_network_route_action_get(dev_id, index, ®_val); + *value = reg_val.bf.dst_info; + return ret; +} + +sw_error_t +hppe_network_route_action_dst_info_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union network_route_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_network_route_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.dst_info = value; + ret = hppe_network_route_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_flow_src_if_check_de_acce_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + *value = reg_val.bf.flow_src_if_check_de_acce; + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_flow_src_if_check_de_acce_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_src_if_check_de_acce = value; + ret = hppe_l3_route_ctrl_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_pppoe_multicast_cmd_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + *value = reg_val.bf.pppoe_multicast_cmd; + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_pppoe_multicast_cmd_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pppoe_multicast_cmd = value; + ret = hppe_l3_route_ctrl_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_ip_mtu_fail_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + *value = reg_val.bf.ip_mtu_fail; + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_ip_mtu_fail_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_mtu_fail = value; + ret = hppe_l3_route_ctrl_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_flow_src_if_check_cmd_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + *value = reg_val.bf.flow_src_if_check_cmd; + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_flow_src_if_check_cmd_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_src_if_check_cmd = value; + ret = hppe_l3_route_ctrl_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_icmp_rdt_de_acce_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + *value = reg_val.bf.icmp_rdt_de_acce; + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_icmp_rdt_de_acce_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.icmp_rdt_de_acce = value; + ret = hppe_l3_route_ctrl_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_flow_de_acce_cmd_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + *value = reg_val.bf.flow_de_acce_cmd; + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_flow_de_acce_cmd_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_de_acce_cmd = value; + ret = hppe_l3_route_ctrl_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_ip_mtu_fail_de_acce_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + *value = reg_val.bf.ip_mtu_fail_de_acce; + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_ip_mtu_fail_de_acce_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_mtu_fail_de_acce = value; + ret = hppe_l3_route_ctrl_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_flow_sync_mismatch_cmd_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + *value = reg_val.bf.flow_sync_mismatch_cmd; + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_flow_sync_mismatch_cmd_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_sync_mismatch_cmd = value; + ret = hppe_l3_route_ctrl_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_flow_service_code_loop_de_acce_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + *value = reg_val.bf.flow_service_code_loop_de_acce; + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_flow_service_code_loop_de_acce_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_service_code_loop_de_acce = value; + ret = hppe_l3_route_ctrl_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_flow_sync_mismatch_de_acce_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + *value = reg_val.bf.flow_sync_mismatch_de_acce; + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_flow_sync_mismatch_de_acce_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_sync_mismatch_de_acce = value; + ret = hppe_l3_route_ctrl_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_ip_mtu_df_fail_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + *value = reg_val.bf.ip_mtu_df_fail; + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_ip_mtu_df_fail_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_mtu_df_fail = value; + ret = hppe_l3_route_ctrl_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_flow_service_code_loop_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + *value = reg_val.bf.flow_service_code_loop; + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_flow_service_code_loop_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_service_code_loop = value; + ret = hppe_l3_route_ctrl_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_ip_mru_check_fail_de_acce_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + *value = reg_val.bf.ip_mru_check_fail_de_acce; + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_ip_mru_check_fail_de_acce_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_mru_check_fail_de_acce = value; + ret = hppe_l3_route_ctrl_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_ip_prefix_bc_cmd_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + *value = reg_val.bf.ip_prefix_bc_cmd; + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_ip_prefix_bc_cmd_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_prefix_bc_cmd = value; + ret = hppe_l3_route_ctrl_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_ip_mtu_df_fail_de_acce_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + *value = reg_val.bf.ip_mtu_df_fail_de_acce; + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_ip_mtu_df_fail_de_acce_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_mtu_df_fail_de_acce = value; + ret = hppe_l3_route_ctrl_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_pppoe_multicast_de_acce_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + *value = reg_val.bf.pppoe_multicast_de_acce; + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_pppoe_multicast_de_acce_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pppoe_multicast_de_acce = value; + ret = hppe_l3_route_ctrl_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_ip_mru_check_fail_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + *value = reg_val.bf.ip_mru_check_fail; + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_ip_mru_check_fail_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_mru_check_fail = value; + ret = hppe_l3_route_ctrl_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_icmp_rdt_cmd_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + *value = reg_val.bf.icmp_rdt_cmd; + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_icmp_rdt_cmd_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.icmp_rdt_cmd = value; + ret = hppe_l3_route_ctrl_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_ip_prefix_bc_de_acce_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + *value = reg_val.bf.ip_prefix_bc_de_acce; + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_ip_prefix_bc_de_acce_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l3_route_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_prefix_bc_de_acce = value; + ret = hppe_l3_route_ctrl_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_ext_flow_service_code_loop_en_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l3_route_ctrl_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_ext_get(dev_id, ®_val); + *value = reg_val.bf.flow_service_code_loop_en; + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_ext_flow_service_code_loop_en_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l3_route_ctrl_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_ext_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_service_code_loop_en = value; + ret = hppe_l3_route_ctrl_ext_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_ext_host_hash_mode_0_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l3_route_ctrl_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_ext_get(dev_id, ®_val); + *value = reg_val.bf.host_hash_mode_0; + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_ext_host_hash_mode_0_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l3_route_ctrl_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_ext_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.host_hash_mode_0 = value; + ret = hppe_l3_route_ctrl_ext_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_ext_host_hash_mode_1_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l3_route_ctrl_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_ext_get(dev_id, ®_val); + *value = reg_val.bf.host_hash_mode_1; + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_ext_host_hash_mode_1_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l3_route_ctrl_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_ext_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.host_hash_mode_1 = value; + ret = hppe_l3_route_ctrl_ext_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_ext_ip_route_mismatch_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l3_route_ctrl_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_ext_get(dev_id, ®_val); + *value = reg_val.bf.ip_route_mismatch; + return ret; +} + +sw_error_t +hppe_l3_route_ctrl_ext_ip_route_mismatch_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l3_route_ctrl_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_route_ctrl_ext_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_route_mismatch = value; + ret = hppe_l3_route_ctrl_ext_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_op_entry_index_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_get(dev_id, ®_val); + *value = reg_val.bf.entry_index; + return ret; +} + +sw_error_t +hppe_host_tbl_op_entry_index_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.entry_index = value; + ret = hppe_host_tbl_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_op_cmd_id_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_get(dev_id, ®_val); + *value = reg_val.bf.cmd_id; + return ret; +} + +sw_error_t +hppe_host_tbl_op_cmd_id_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmd_id = value; + ret = hppe_host_tbl_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_op_byp_rslt_en_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_get(dev_id, ®_val); + *value = reg_val.bf.byp_rslt_en; + return ret; +} + +sw_error_t +hppe_host_tbl_op_byp_rslt_en_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.byp_rslt_en = value; + ret = hppe_host_tbl_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_op_op_mode_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_get(dev_id, ®_val); + *value = reg_val.bf.op_mode; + return ret; +} + +sw_error_t +hppe_host_tbl_op_op_mode_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.op_mode = value; + ret = hppe_host_tbl_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_op_op_type_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_get(dev_id, ®_val); + *value = reg_val.bf.op_type; + return ret; +} + +sw_error_t +hppe_host_tbl_op_op_type_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.op_type = value; + ret = hppe_host_tbl_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_op_op_result_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_get(dev_id, ®_val); + *value = reg_val.bf.op_result; + return ret; +} + +sw_error_t +hppe_host_tbl_op_op_result_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.op_result = value; + ret = hppe_host_tbl_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_op_busy_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_get(dev_id, ®_val); + *value = reg_val.bf.busy; + return ret; +} + +sw_error_t +hppe_host_tbl_op_busy_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.busy = value; + ret = hppe_host_tbl_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_op_hash_block_bitmap_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_get(dev_id, ®_val); + *value = reg_val.bf.hash_block_bitmap; + return ret; +} + +sw_error_t +hppe_host_tbl_op_hash_block_bitmap_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.hash_block_bitmap = value; + ret = hppe_host_tbl_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_op_data0_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_op_data0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_data0_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_host_tbl_op_data0_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_op_data0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_data0_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_host_tbl_op_data0_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_op_data1_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_op_data1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_data1_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_host_tbl_op_data1_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_op_data1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_data1_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_host_tbl_op_data1_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_op_data2_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_op_data2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_data2_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_host_tbl_op_data2_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_op_data2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_data2_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_host_tbl_op_data2_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_op_data3_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_op_data3_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_data3_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_host_tbl_op_data3_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_op_data3_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_data3_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_host_tbl_op_data3_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_op_data4_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_op_data4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_data4_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_host_tbl_op_data4_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_op_data4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_data4_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_host_tbl_op_data4_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_op_data5_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_op_data5_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_data5_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_host_tbl_op_data5_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_op_data5_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_data5_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_host_tbl_op_data5_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_op_data6_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_op_data6_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_data6_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_host_tbl_op_data6_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_op_data6_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_data6_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_host_tbl_op_data6_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_op_data7_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_op_data7_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_data7_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_host_tbl_op_data7_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_op_data7_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_data7_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_host_tbl_op_data7_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_op_data8_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_op_data8_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_data8_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_host_tbl_op_data8_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_op_data8_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_data8_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_host_tbl_op_data8_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_op_data9_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_op_data9_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_data9_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_host_tbl_op_data9_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_op_data9_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_data9_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_host_tbl_op_data9_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_op_rslt_op_rslt_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_op_rslt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_rslt_get(dev_id, ®_val); + *value = reg_val.bf.op_rslt; + return ret; +} + +sw_error_t +hppe_host_tbl_op_rslt_op_rslt_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_host_tbl_op_rslt_valid_cnt_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_op_rslt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_rslt_get(dev_id, ®_val); + *value = reg_val.bf.valid_cnt; + return ret; +} + +sw_error_t +hppe_host_tbl_op_rslt_valid_cnt_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_host_tbl_op_rslt_entry_index_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_op_rslt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_rslt_get(dev_id, ®_val); + *value = reg_val.bf.entry_index; + return ret; +} + +sw_error_t +hppe_host_tbl_op_rslt_entry_index_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_host_tbl_op_rslt_cmd_id_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_op_rslt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_op_rslt_get(dev_id, ®_val); + *value = reg_val.bf.cmd_id; + return ret; +} + +sw_error_t +hppe_host_tbl_op_rslt_cmd_id_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_host_tbl_rd_op_entry_index_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_get(dev_id, ®_val); + *value = reg_val.bf.entry_index; + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_entry_index_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.entry_index = value; + ret = hppe_host_tbl_rd_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_cmd_id_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_get(dev_id, ®_val); + *value = reg_val.bf.cmd_id; + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_cmd_id_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmd_id = value; + ret = hppe_host_tbl_rd_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_byp_rslt_en_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_get(dev_id, ®_val); + *value = reg_val.bf.byp_rslt_en; + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_byp_rslt_en_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.byp_rslt_en = value; + ret = hppe_host_tbl_rd_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_op_mode_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_get(dev_id, ®_val); + *value = reg_val.bf.op_mode; + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_op_mode_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.op_mode = value; + ret = hppe_host_tbl_rd_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_op_type_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_get(dev_id, ®_val); + *value = reg_val.bf.op_type; + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_op_type_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.op_type = value; + ret = hppe_host_tbl_rd_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_op_result_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_get(dev_id, ®_val); + *value = reg_val.bf.op_result; + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_op_result_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.op_result = value; + ret = hppe_host_tbl_rd_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_busy_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_get(dev_id, ®_val); + *value = reg_val.bf.busy; + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_busy_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.busy = value; + ret = hppe_host_tbl_rd_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_hash_block_bitmap_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_get(dev_id, ®_val); + *value = reg_val.bf.hash_block_bitmap; + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_hash_block_bitmap_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_rd_op_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.hash_block_bitmap = value; + ret = hppe_host_tbl_rd_op_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_data0_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_rd_op_data0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_data0_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_data0_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_rd_op_data0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_data0_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_host_tbl_rd_op_data0_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_data1_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_rd_op_data1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_data1_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_data1_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_rd_op_data1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_data1_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_host_tbl_rd_op_data1_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_data2_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_rd_op_data2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_data2_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_data2_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_rd_op_data2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_data2_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_host_tbl_rd_op_data2_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_data3_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_rd_op_data3_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_data3_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_data3_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_rd_op_data3_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_data3_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_host_tbl_rd_op_data3_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_data4_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_rd_op_data4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_data4_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_data4_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_rd_op_data4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_data4_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_host_tbl_rd_op_data4_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_data5_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_rd_op_data5_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_data5_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_data5_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_rd_op_data5_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_data5_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_host_tbl_rd_op_data5_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_data6_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_rd_op_data6_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_data6_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_data6_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_rd_op_data6_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_data6_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_host_tbl_rd_op_data6_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_data7_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_rd_op_data7_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_data7_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_data7_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_rd_op_data7_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_data7_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_host_tbl_rd_op_data7_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_data8_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_rd_op_data8_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_data8_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_data8_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_rd_op_data8_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_data8_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_host_tbl_rd_op_data8_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_data9_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_rd_op_data9_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_data9_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_data9_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union host_tbl_rd_op_data9_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_data9_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_host_tbl_rd_op_data9_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_rslt_op_rslt_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_rd_op_rslt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_rslt_get(dev_id, ®_val); + *value = reg_val.bf.op_rslt; + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_rslt_op_rslt_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_host_tbl_rd_op_rslt_valid_cnt_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_rd_op_rslt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_rslt_get(dev_id, ®_val); + *value = reg_val.bf.valid_cnt; + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_rslt_valid_cnt_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_host_tbl_rd_op_rslt_entry_index_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_rd_op_rslt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_rslt_get(dev_id, ®_val); + *value = reg_val.bf.entry_index; + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_rslt_entry_index_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_host_tbl_rd_op_rslt_cmd_id_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_rd_op_rslt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_op_rslt_get(dev_id, ®_val); + *value = reg_val.bf.cmd_id; + return ret; +} + +sw_error_t +hppe_host_tbl_rd_op_rslt_cmd_id_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_host_tbl_rd_rslt_data0_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_rd_rslt_data0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_rslt_data0_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_host_tbl_rd_rslt_data0_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_host_tbl_rd_rslt_data1_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_rd_rslt_data1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_rslt_data1_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_host_tbl_rd_rslt_data1_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_host_tbl_rd_rslt_data2_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_rd_rslt_data2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_rslt_data2_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_host_tbl_rd_rslt_data2_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_host_tbl_rd_rslt_data3_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_rd_rslt_data3_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_rslt_data3_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_host_tbl_rd_rslt_data3_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_host_tbl_rd_rslt_data4_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_rd_rslt_data4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_rslt_data4_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_host_tbl_rd_rslt_data4_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_host_tbl_rd_rslt_data5_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_rd_rslt_data5_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_rslt_data5_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_host_tbl_rd_rslt_data5_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_host_tbl_rd_rslt_data6_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_rd_rslt_data6_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_rslt_data6_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_host_tbl_rd_rslt_data6_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_host_tbl_rd_rslt_data7_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_rd_rslt_data7_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_rslt_data7_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_host_tbl_rd_rslt_data7_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_host_tbl_rd_rslt_data8_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_rd_rslt_data8_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_rslt_data8_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_host_tbl_rd_rslt_data8_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_host_tbl_rd_rslt_data9_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union host_tbl_rd_rslt_data9_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_host_tbl_rd_rslt_data9_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_host_tbl_rd_rslt_data9_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l3_dbg_cmd_type_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l3_dbg_cmd_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_dbg_cmd_get(dev_id, ®_val); + *value = reg_val.bf.type; + return ret; +} + +sw_error_t +hppe_l3_dbg_cmd_type_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l3_dbg_cmd_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_dbg_cmd_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.type = value; + ret = hppe_l3_dbg_cmd_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l3_dbg_cmd_addr_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l3_dbg_cmd_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_dbg_cmd_get(dev_id, ®_val); + *value = reg_val.bf.addr; + return ret; +} + +sw_error_t +hppe_l3_dbg_cmd_addr_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l3_dbg_cmd_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_dbg_cmd_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.addr = value; + ret = hppe_l3_dbg_cmd_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l3_dbg_wr_data_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l3_dbg_wr_data_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_dbg_wr_data_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_l3_dbg_wr_data_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l3_dbg_wr_data_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_dbg_wr_data_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.data = value; + ret = hppe_l3_dbg_wr_data_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l3_dbg_rd_data_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l3_dbg_rd_data_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_dbg_rd_data_get(dev_id, ®_val); + *value = reg_val.bf.data; + return ret; +} + +sw_error_t +hppe_l3_dbg_rd_data_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l3_vp_port_tbl_ip_arp_sg_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ip_arp_sg_en; + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ip_arp_sg_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_arp_sg_en = value; + ret = hppe_l3_vp_port_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ipv6_sg_svlan_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ipv6_sg_svlan_en; + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ipv6_sg_svlan_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv6_sg_svlan_en = value; + ret = hppe_l3_vp_port_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ip_nd_sg_cvlan_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ip_nd_sg_cvlan_en; + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ip_nd_sg_cvlan_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_nd_sg_cvlan_en = value; + ret = hppe_l3_vp_port_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_l3_if_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.l3_if_valid; + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_l3_if_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l3_if_valid = value; + ret = hppe_l3_vp_port_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ip_nd_sg_vio_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ip_nd_sg_vio_cmd; + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ip_nd_sg_vio_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_nd_sg_vio_cmd = value; + ret = hppe_l3_vp_port_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ipv4_sg_port_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ipv4_sg_port_en; + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ipv4_sg_port_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv4_sg_port_en = value; + ret = hppe_l3_vp_port_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ip_nd_sg_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ip_nd_sg_en; + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ip_nd_sg_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_nd_sg_en = value; + ret = hppe_l3_vp_port_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_l3_if_index_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.l3_if_index; + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_l3_if_index_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l3_if_index = value; + ret = hppe_l3_vp_port_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ipv4_sg_svlan_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ipv4_sg_svlan_en; + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ipv4_sg_svlan_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv4_sg_svlan_en = value; + ret = hppe_l3_vp_port_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ipv4_sg_cvlan_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ipv4_sg_cvlan_en; + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ipv4_sg_cvlan_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv4_sg_cvlan_en = value; + ret = hppe_l3_vp_port_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ip_arp_sg_svlan_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ip_arp_sg_svlan_en; + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ip_arp_sg_svlan_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_arp_sg_svlan_en = value; + ret = hppe_l3_vp_port_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_mac_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.mac_valid; + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_mac_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_valid = value; + ret = hppe_l3_vp_port_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ip_nd_sg_svlan_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ip_nd_sg_svlan_en; + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ip_nd_sg_svlan_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_nd_sg_svlan_en = value; + ret = hppe_l3_vp_port_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_vsi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.vsi; + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_vsi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.vsi = value; + ret = hppe_l3_vp_port_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_mac_da_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.mac_da_1 << 16 | \ + reg_val.bf.mac_da_0; + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_mac_da_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_da_1 = value >> 16; + reg_val.bf.mac_da_0 = value & (((a_uint64_t)1<<16)-1); + ret = hppe_l3_vp_port_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ipv6_sg_vio_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ipv6_sg_vio_cmd; + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ipv6_sg_vio_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv6_sg_vio_cmd = value; + ret = hppe_l3_vp_port_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ip_nd_sg_port_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ip_nd_sg_port_en; + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ip_nd_sg_port_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_nd_sg_port_en = value; + ret = hppe_l3_vp_port_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ip_arp_src_unk_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ip_arp_src_unk_cmd; + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ip_arp_src_unk_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_arp_src_unk_cmd = value; + ret = hppe_l3_vp_port_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ipv6_sg_port_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ipv6_sg_port_en; + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ipv6_sg_port_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv6_sg_port_en = value; + ret = hppe_l3_vp_port_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ipv4_src_unk_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ipv4_src_unk_cmd; + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ipv4_src_unk_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv4_src_unk_cmd = value; + ret = hppe_l3_vp_port_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ip_arp_sg_port_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ip_arp_sg_port_en; + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ip_arp_sg_port_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_arp_sg_port_en = value; + ret = hppe_l3_vp_port_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ip_arp_sg_vio_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ip_arp_sg_vio_cmd; + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ip_arp_sg_vio_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_arp_sg_vio_cmd = value; + ret = hppe_l3_vp_port_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ipv4_sg_vio_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ipv4_sg_vio_cmd; + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ipv4_sg_vio_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv4_sg_vio_cmd = value; + ret = hppe_l3_vp_port_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ipv6_src_unk_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ipv6_src_unk_cmd; + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ipv6_src_unk_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv6_src_unk_cmd = value; + ret = hppe_l3_vp_port_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ip_arp_sg_cvlan_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ip_arp_sg_cvlan_en; + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ip_arp_sg_cvlan_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_arp_sg_cvlan_en = value; + ret = hppe_l3_vp_port_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ipv6_sg_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ipv6_sg_en; + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ipv6_sg_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv6_sg_en = value; + ret = hppe_l3_vp_port_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_vsi_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.vsi_valid; + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_vsi_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.vsi_valid = value; + ret = hppe_l3_vp_port_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ip_nd_src_unk_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ip_nd_src_unk_cmd; + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ip_nd_src_unk_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_nd_src_unk_cmd = value; + ret = hppe_l3_vp_port_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ipv4_sg_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ipv4_sg_en; + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ipv4_sg_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv4_sg_en = value; + ret = hppe_l3_vp_port_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ipv6_sg_cvlan_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ipv6_sg_cvlan_en; + return ret; +} + +sw_error_t +hppe_l3_vp_port_tbl_ipv6_sg_cvlan_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_vp_port_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_vp_port_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv6_sg_cvlan_en = value; + ret = hppe_l3_vp_port_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_l3_if_tbl_ttl_dec_bypass_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_l3_if_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_l3_if_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ttl_dec_bypass; + return ret; +} + +sw_error_t +hppe_in_l3_if_tbl_ttl_dec_bypass_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_l3_if_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_l3_if_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ttl_dec_bypass = value; + ret = hppe_in_l3_if_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_l3_if_tbl_ttl_exceed_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_l3_if_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_l3_if_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ttl_exceed_cmd; + return ret; +} + +sw_error_t +hppe_in_l3_if_tbl_ttl_exceed_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_l3_if_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_l3_if_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ttl_exceed_cmd = value; + ret = hppe_in_l3_if_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_l3_if_tbl_mru_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_l3_if_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_l3_if_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.mru; + return ret; +} + +sw_error_t +hppe_in_l3_if_tbl_mru_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_l3_if_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_l3_if_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mru = value; + ret = hppe_in_l3_if_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_l3_if_tbl_ipv4_uc_route_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_l3_if_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_l3_if_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ipv4_uc_route_en; + return ret; +} + +sw_error_t +hppe_in_l3_if_tbl_ipv4_uc_route_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_l3_if_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_l3_if_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv4_uc_route_en = value; + ret = hppe_in_l3_if_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_l3_if_tbl_ipv6_uc_route_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_l3_if_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_l3_if_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ipv6_uc_route_en; + return ret; +} + +sw_error_t +hppe_in_l3_if_tbl_ipv6_uc_route_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_l3_if_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_l3_if_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv6_uc_route_en = value; + ret = hppe_in_l3_if_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_l3_if_tbl_ttl_exceed_de_acce_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_l3_if_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_l3_if_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ttl_exceed_de_acce; + return ret; +} + +sw_error_t +hppe_in_l3_if_tbl_ttl_exceed_de_acce_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_l3_if_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_l3_if_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ttl_exceed_de_acce = value; + ret = hppe_in_l3_if_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_l3_if_tbl_icmp_trigger_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_l3_if_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_l3_if_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.icmp_trigger_en; + return ret; +} + +sw_error_t +hppe_in_l3_if_tbl_icmp_trigger_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_l3_if_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_l3_if_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.icmp_trigger_en = value; + ret = hppe_in_l3_if_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_l3_if_tbl_mac_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_l3_if_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_l3_if_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.mac_bitmap; + return ret; +} + +sw_error_t +hppe_in_l3_if_tbl_mac_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_l3_if_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_l3_if_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_bitmap = value; + ret = hppe_in_l3_if_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_l3_if_tbl_pppoe_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_l3_if_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_l3_if_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.pppoe_en; + return ret; +} + +sw_error_t +hppe_in_l3_if_tbl_pppoe_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_l3_if_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_l3_if_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pppoe_en = value; + ret = hppe_in_l3_if_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_l3_if_tbl_mtu_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_l3_if_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_l3_if_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.mtu; + return ret; +} + +sw_error_t +hppe_in_l3_if_tbl_mtu_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_l3_if_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_l3_if_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mtu = value; + ret = hppe_in_l3_if_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_nexthop_tbl_ip_pub_addr_index_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_nexthop_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_nexthop_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.ip_pub_addr_index; + return ret; +} + +sw_error_t +hppe_in_nexthop_tbl_ip_pub_addr_index_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_nexthop_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_nexthop_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.ip_pub_addr_index = value; + ret = hppe_in_nexthop_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_nexthop_tbl_cvid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_nexthop_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_nexthop_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.cvid; + return ret; +} + +sw_error_t +hppe_in_nexthop_tbl_cvid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_nexthop_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_nexthop_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.cvid = value; + ret = hppe_in_nexthop_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_nexthop_tbl_post_l3_if_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_nexthop_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_nexthop_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.post_l3_if; + return ret; +} + +sw_error_t +hppe_in_nexthop_tbl_post_l3_if_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_nexthop_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_nexthop_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.post_l3_if = value; + ret = hppe_in_nexthop_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_nexthop_tbl_mac_addr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union in_nexthop_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_nexthop_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf1.mac_addr_1 << 16 | \ + reg_val.bf1.mac_addr_0; + return ret; +} + +sw_error_t +hppe_in_nexthop_tbl_mac_addr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union in_nexthop_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_nexthop_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.mac_addr_1 = value >> 16; + reg_val.bf1.mac_addr_0 = value & (((a_uint64_t)1<<16)-1); + ret = hppe_in_nexthop_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_nexthop_tbl_port_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_nexthop_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_nexthop_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf0.port; + return ret; +} + +sw_error_t +hppe_in_nexthop_tbl_port_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_nexthop_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_nexthop_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf0.port = value; + ret = hppe_in_nexthop_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_nexthop_tbl_ip_to_me_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_nexthop_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_nexthop_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.ip_to_me; + return ret; +} + +sw_error_t +hppe_in_nexthop_tbl_ip_to_me_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_nexthop_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_nexthop_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.ip_to_me = value; + ret = hppe_in_nexthop_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_nexthop_tbl_ip_addr_dnat_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_nexthop_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_nexthop_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.ip_addr_dnat; + return ret; +} + +sw_error_t +hppe_in_nexthop_tbl_ip_addr_dnat_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_nexthop_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_nexthop_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.ip_addr_dnat = value; + ret = hppe_in_nexthop_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_nexthop_tbl_type_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_nexthop_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_nexthop_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.type; + return ret; +} + +sw_error_t +hppe_in_nexthop_tbl_type_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_nexthop_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_nexthop_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.type = value; + ret = hppe_in_nexthop_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_nexthop_tbl_stag_fmt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_nexthop_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_nexthop_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.stag_fmt; + return ret; +} + +sw_error_t +hppe_in_nexthop_tbl_stag_fmt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_nexthop_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_nexthop_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.stag_fmt = value; + ret = hppe_in_nexthop_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_nexthop_tbl_vsi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_nexthop_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_nexthop_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.vsi; + return ret; +} + +sw_error_t +hppe_in_nexthop_tbl_vsi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_nexthop_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_nexthop_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.vsi = value; + ret = hppe_in_nexthop_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_nexthop_tbl_svid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_nexthop_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_nexthop_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.svid; + return ret; +} + +sw_error_t +hppe_in_nexthop_tbl_svid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_nexthop_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_nexthop_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.svid = value; + ret = hppe_in_nexthop_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_nexthop_tbl_ctag_fmt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_nexthop_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_nexthop_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.ctag_fmt; + return ret; +} + +sw_error_t +hppe_in_nexthop_tbl_ctag_fmt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_nexthop_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_nexthop_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.ctag_fmt = value; + ret = hppe_in_nexthop_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_l3_if_tbl_session_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_l3_if_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_l3_if_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.session_id; + return ret; +} + +sw_error_t +hppe_eg_l3_if_tbl_session_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_l3_if_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_l3_if_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.session_id = value; + ret = hppe_eg_l3_if_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_l3_if_tbl_mac_addr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union eg_l3_if_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_l3_if_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.mac_addr_1 << 32 | \ + reg_val.bf.mac_addr_0; + return ret; +} + +sw_error_t +hppe_eg_l3_if_tbl_mac_addr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union eg_l3_if_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_l3_if_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_addr_1 = value >> 32; + reg_val.bf.mac_addr_0 = value & (((a_uint64_t)1<<32)-1); + ret = hppe_eg_l3_if_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_l3_if_tbl_pppoe_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_l3_if_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_l3_if_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.pppoe_en; + return ret; +} + +sw_error_t +hppe_eg_l3_if_tbl_pppoe_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_l3_if_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_l3_if_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pppoe_en = value; + ret = hppe_eg_l3_if_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_pub_ip_addr_tbl_ip_addr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_pub_ip_addr_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_pub_ip_addr_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ip_addr; + return ret; +} + +sw_error_t +hppe_in_pub_ip_addr_tbl_ip_addr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_pub_ip_addr_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_pub_ip_addr_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_addr = value; + ret = hppe_in_pub_ip_addr_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_rt_interface_cnt_tbl_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union rt_interface_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rt_interface_cnt_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.byte_cnt_1 << 32 | \ + reg_val.bf.byte_cnt_0; + return ret; +} + +sw_error_t +hppe_rt_interface_cnt_tbl_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union rt_interface_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rt_interface_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.byte_cnt_1 = value >> 32; + reg_val.bf.byte_cnt_0 = value & (((a_uint64_t)1<<32)-1); + ret = hppe_rt_interface_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_rt_interface_cnt_tbl_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rt_interface_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rt_interface_cnt_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.pkt_cnt; + return ret; +} + +sw_error_t +hppe_rt_interface_cnt_tbl_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union rt_interface_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rt_interface_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pkt_cnt = value; + ret = hppe_rt_interface_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_rt_interface_cnt_tbl_drop_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union rt_interface_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rt_interface_cnt_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.drop_byte_cnt_1 << 24 | \ + reg_val.bf.drop_byte_cnt_0; + return ret; +} + +sw_error_t +hppe_rt_interface_cnt_tbl_drop_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union rt_interface_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rt_interface_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.drop_byte_cnt_1 = value >> 24; + reg_val.bf.drop_byte_cnt_0 = value & (((a_uint64_t)1<<24)-1); + ret = hppe_rt_interface_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_rt_interface_cnt_tbl_drop_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rt_interface_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rt_interface_cnt_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.drop_pkt_cnt_1 << 24 | \ + reg_val.bf.drop_pkt_cnt_0; + return ret; +} + +sw_error_t +hppe_rt_interface_cnt_tbl_drop_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union rt_interface_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rt_interface_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.drop_pkt_cnt_1 = value >> 24; + reg_val.bf.drop_pkt_cnt_0 = value & (((a_uint64_t)1<<24)-1); + ret = hppe_rt_interface_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + + +sw_error_t +hppe_host_op_common( + a_uint32_t dev_id, + a_uint32_t op_type, + a_uint32_t op_mode, + a_uint32_t *index) +{ + union host_tbl_op_u op; + union host_tbl_op_rslt_u result; + a_uint32_t i = 0x100; + sw_error_t rv; + + op.bf.cmd_id = host_cmd_id; + host_cmd_id++; + op.bf.byp_rslt_en = 0; + op.bf.op_type = op_type; + op.bf.hash_block_bitmap = 3; + op.bf.op_mode = op_mode; + op.bf.entry_index = *index; + + rv = hppe_host_tbl_op_set(dev_id, &op); + if (SW_OK != rv) + return rv; + rv = hppe_host_tbl_op_rslt_get(dev_id, &result); + if (SW_OK != rv) + return rv; + while (!result.bf.valid_cnt && --i) { + hppe_host_tbl_op_rslt_get(dev_id, &result); + } + if (i == 0) + return SW_BUSY; + if (result.bf.op_rslt == 0) { + *index = result.bf.entry_index; + return SW_OK; + } + else + return SW_FAIL; + +} + +sw_error_t +hppe_host_ipv4_add( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_tbl_u *entry) +{ + hppe_host_tbl_op_data0_set(dev_id, (union host_tbl_op_data0_u *)(&entry->val[0])); + hppe_host_tbl_op_data1_set(dev_id, (union host_tbl_op_data1_u *)(&entry->val[1])); + hppe_host_tbl_op_data2_set(dev_id, (union host_tbl_op_data2_u *)(&entry->val[2])); + return hppe_host_op_common(dev_id, 0, op_mode, index); +} + +sw_error_t +hppe_host_ipv6_add( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_ipv6_tbl_u *entry) +{ + hppe_host_tbl_op_data0_set(dev_id, (union host_tbl_op_data0_u *)(&entry->val[0])); + hppe_host_tbl_op_data1_set(dev_id, (union host_tbl_op_data1_u *)(&entry->val[1])); + hppe_host_tbl_op_data2_set(dev_id, (union host_tbl_op_data2_u *)(&entry->val[2])); + hppe_host_tbl_op_data3_set(dev_id, (union host_tbl_op_data3_u *)(&entry->val[3])); + hppe_host_tbl_op_data4_set(dev_id, (union host_tbl_op_data4_u *)(&entry->val[4])); + return hppe_host_op_common(dev_id, 0, op_mode, index); +} + +sw_error_t +hppe_host_ipv4_mcast_add( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_ipv4_mcast_tbl_u *entry) +{ + hppe_host_tbl_op_data0_set(dev_id, (union host_tbl_op_data0_u *)(&entry->val[0])); + hppe_host_tbl_op_data1_set(dev_id, (union host_tbl_op_data1_u *)(&entry->val[1])); + hppe_host_tbl_op_data2_set(dev_id, (union host_tbl_op_data2_u *)(&entry->val[2])); + hppe_host_tbl_op_data3_set(dev_id, (union host_tbl_op_data3_u *)(&entry->val[3])); + hppe_host_tbl_op_data4_set(dev_id, (union host_tbl_op_data4_u *)(&entry->val[4])); + return hppe_host_op_common(dev_id, 0, op_mode, index); +} + +sw_error_t +hppe_host_ipv6_mcast_add( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_ipv6_mcast_tbl_u *entry) +{ + hppe_host_tbl_op_data0_set(dev_id, (union host_tbl_op_data0_u *)(&entry->val[0])); + hppe_host_tbl_op_data1_set(dev_id, (union host_tbl_op_data1_u *)(&entry->val[1])); + hppe_host_tbl_op_data2_set(dev_id, (union host_tbl_op_data2_u *)(&entry->val[2])); + hppe_host_tbl_op_data3_set(dev_id, (union host_tbl_op_data3_u *)(&entry->val[3])); + hppe_host_tbl_op_data4_set(dev_id, (union host_tbl_op_data4_u *)(&entry->val[4])); + hppe_host_tbl_op_data5_set(dev_id, (union host_tbl_op_data5_u *)(&entry->val[5])); + hppe_host_tbl_op_data6_set(dev_id, (union host_tbl_op_data6_u *)(&entry->val[6])); + hppe_host_tbl_op_data7_set(dev_id, (union host_tbl_op_data7_u *)(&entry->val[7])); + hppe_host_tbl_op_data8_set(dev_id, (union host_tbl_op_data8_u *)(&entry->val[8])); + hppe_host_tbl_op_data9_set(dev_id, (union host_tbl_op_data9_u *)(&entry->val[9])); + return hppe_host_op_common(dev_id, 0, op_mode, index); +} + +sw_error_t +hppe_host_ipv4_del( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_tbl_u *entry) +{ + if (op_mode == 0) { + hppe_host_tbl_op_data0_set(dev_id, (union host_tbl_op_data0_u *)(&entry->val[0])); + hppe_host_tbl_op_data1_set(dev_id, (union host_tbl_op_data1_u *)(&entry->val[1])); + hppe_host_tbl_op_data2_set(dev_id, (union host_tbl_op_data2_u *)(&entry->val[2])); + } + return hppe_host_op_common(dev_id, 1, op_mode, index); + +} + +sw_error_t +hppe_host_ipv6_del( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_ipv6_tbl_u *entry) +{ + if (op_mode == 0) { + hppe_host_tbl_op_data0_set(dev_id, (union host_tbl_op_data0_u *)(&entry->val[0])); + hppe_host_tbl_op_data1_set(dev_id, (union host_tbl_op_data1_u *)(&entry->val[1])); + hppe_host_tbl_op_data2_set(dev_id, (union host_tbl_op_data2_u *)(&entry->val[2])); + hppe_host_tbl_op_data3_set(dev_id, (union host_tbl_op_data3_u *)(&entry->val[3])); + hppe_host_tbl_op_data4_set(dev_id, (union host_tbl_op_data4_u *)(&entry->val[4])); + } + return hppe_host_op_common(dev_id, 1, op_mode, index); +} + +sw_error_t +hppe_host_ipv4_mcast_del( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_ipv4_mcast_tbl_u *entry) +{ + if (op_mode == 0) { + hppe_host_tbl_op_data0_set(dev_id, (union host_tbl_op_data0_u *)(&entry->val[0])); + hppe_host_tbl_op_data1_set(dev_id, (union host_tbl_op_data1_u *)(&entry->val[1])); + hppe_host_tbl_op_data2_set(dev_id, (union host_tbl_op_data2_u *)(&entry->val[2])); + hppe_host_tbl_op_data3_set(dev_id, (union host_tbl_op_data3_u *)(&entry->val[3])); + hppe_host_tbl_op_data4_set(dev_id, (union host_tbl_op_data4_u *)(&entry->val[4])); + } + return hppe_host_op_common(dev_id, 1, op_mode, index); +} + +sw_error_t +hppe_host_ipv6_mcast_del( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_ipv6_mcast_tbl_u *entry) +{ + if (op_mode == 0) { + hppe_host_tbl_op_data0_set(dev_id, (union host_tbl_op_data0_u *)(&entry->val[0])); + hppe_host_tbl_op_data1_set(dev_id, (union host_tbl_op_data1_u *)(&entry->val[1])); + hppe_host_tbl_op_data2_set(dev_id, (union host_tbl_op_data2_u *)(&entry->val[2])); + hppe_host_tbl_op_data3_set(dev_id, (union host_tbl_op_data3_u *)(&entry->val[3])); + hppe_host_tbl_op_data4_set(dev_id, (union host_tbl_op_data4_u *)(&entry->val[4])); + hppe_host_tbl_op_data5_set(dev_id, (union host_tbl_op_data5_u *)(&entry->val[5])); + hppe_host_tbl_op_data6_set(dev_id, (union host_tbl_op_data6_u *)(&entry->val[6])); + hppe_host_tbl_op_data7_set(dev_id, (union host_tbl_op_data7_u *)(&entry->val[7])); + hppe_host_tbl_op_data8_set(dev_id, (union host_tbl_op_data8_u *)(&entry->val[8])); + hppe_host_tbl_op_data9_set(dev_id, (union host_tbl_op_data9_u *)(&entry->val[9])); + } + return hppe_host_op_common(dev_id, 1, op_mode, index); +} + +sw_error_t +hppe_host_get_common( + a_uint32_t dev_id, + a_uint32_t op_mode, + a_uint32_t *index, + a_uint32_t *data, + a_uint32_t num) +{ + union host_tbl_rd_op_u op; + union host_tbl_rd_op_rslt_u result; + a_uint32_t i = 0x100; + sw_error_t rv; + + op.bf.cmd_id = host_cmd_id; + host_cmd_id++; + op.bf.byp_rslt_en = 0; + op.bf.op_type = 2; + op.bf.hash_block_bitmap = 3; + op.bf.op_mode = op_mode; + op.bf.entry_index = *index; + + rv = hppe_host_tbl_rd_op_set(dev_id, &op); + if (SW_OK != rv) + return rv; + rv = hppe_host_tbl_rd_op_rslt_get(dev_id, &result); + if (SW_OK != rv) + return rv; + while (!result.bf.valid_cnt && --i) { + hppe_host_tbl_rd_op_rslt_get(dev_id, &result); + } + if (i == 0) + return SW_BUSY; + if (result.bf.op_rslt == 0) { + hppe_reg_tbl_get( + dev_id, + IPE_L3_BASE_ADDR + HOST_TBL_RD_RSLT_DATA0_ADDRESS, + data, num); + *index = result.bf.entry_index; + return SW_OK; + } + else + return SW_FAIL; + +} + + +sw_error_t +hppe_host_ipv4_get( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_tbl_u *entry) +{ + if (op_mode == 0) { + hppe_host_tbl_rd_op_data0_set(dev_id, (union host_tbl_rd_op_data0_u *)(&entry->val[0])); + hppe_host_tbl_rd_op_data1_set(dev_id, (union host_tbl_rd_op_data1_u *)(&entry->val[1])); + hppe_host_tbl_rd_op_data2_set(dev_id, (union host_tbl_rd_op_data2_u *)(&entry->val[2])); + } + return hppe_host_get_common(dev_id, op_mode, index, + (a_uint32_t *)entry, 3); + +} + +sw_error_t +hppe_host_ipv6_get( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_ipv6_tbl_u *entry) +{ + if (op_mode == 0) { + hppe_host_tbl_rd_op_data0_set(dev_id, (union host_tbl_rd_op_data0_u *)(&entry->val[0])); + hppe_host_tbl_rd_op_data1_set(dev_id, (union host_tbl_rd_op_data1_u *)(&entry->val[1])); + hppe_host_tbl_rd_op_data2_set(dev_id, (union host_tbl_rd_op_data2_u *)(&entry->val[2])); + hppe_host_tbl_rd_op_data3_set(dev_id, (union host_tbl_rd_op_data3_u *)(&entry->val[3])); + hppe_host_tbl_rd_op_data4_set(dev_id, (union host_tbl_rd_op_data4_u *)(&entry->val[4])); + } + return hppe_host_get_common(dev_id, op_mode, index, + (a_uint32_t *)entry, 5); +} + +sw_error_t +hppe_host_ipv4_mcast_get( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_ipv4_mcast_tbl_u *entry) +{ + if (op_mode == 0) { + hppe_host_tbl_rd_op_data0_set(dev_id, (union host_tbl_rd_op_data0_u *)(&entry->val[0])); + hppe_host_tbl_rd_op_data1_set(dev_id, (union host_tbl_rd_op_data1_u *)(&entry->val[1])); + hppe_host_tbl_rd_op_data2_set(dev_id, (union host_tbl_rd_op_data2_u *)(&entry->val[2])); + hppe_host_tbl_rd_op_data3_set(dev_id, (union host_tbl_rd_op_data3_u *)(&entry->val[3])); + hppe_host_tbl_rd_op_data4_set(dev_id, (union host_tbl_rd_op_data4_u *)(&entry->val[4])); + } + return hppe_host_get_common(dev_id, op_mode, index, + (a_uint32_t *)entry, 5); +} + +sw_error_t +hppe_host_ipv6_mcast_get( + a_uint32_t dev_id, a_uint32_t op_mode, + a_uint32_t *index, union host_ipv6_mcast_tbl_u *entry) +{ + if (op_mode == 0) { + hppe_host_tbl_rd_op_data0_set(dev_id, (union host_tbl_rd_op_data0_u *)(&entry->val[0])); + hppe_host_tbl_rd_op_data1_set(dev_id, (union host_tbl_rd_op_data1_u *)(&entry->val[1])); + hppe_host_tbl_rd_op_data2_set(dev_id, (union host_tbl_rd_op_data2_u *)(&entry->val[2])); + hppe_host_tbl_rd_op_data3_set(dev_id, (union host_tbl_rd_op_data3_u *)(&entry->val[3])); + hppe_host_tbl_rd_op_data4_set(dev_id, (union host_tbl_rd_op_data4_u *)(&entry->val[4])); + hppe_host_tbl_rd_op_data5_set(dev_id, (union host_tbl_rd_op_data5_u *)(&entry->val[5])); + hppe_host_tbl_rd_op_data6_set(dev_id, (union host_tbl_rd_op_data6_u *)(&entry->val[6])); + hppe_host_tbl_rd_op_data7_set(dev_id, (union host_tbl_rd_op_data7_u *)(&entry->val[7])); + hppe_host_tbl_rd_op_data8_set(dev_id, (union host_tbl_rd_op_data8_u *)(&entry->val[8])); + hppe_host_tbl_rd_op_data9_set(dev_id, (union host_tbl_rd_op_data9_u *)(&entry->val[9])); + } + return hppe_host_get_common(dev_id, op_mode, index, + (a_uint32_t *)entry, 10); +} + +sw_error_t +hppe_host_flush_common(a_uint32_t dev_id) +{ + union host_tbl_op_u op; + union host_tbl_op_rslt_u result; + a_uint32_t i = 0x100 * 50; + sw_error_t rv; + + op.bf.cmd_id = host_cmd_id; + host_cmd_id++; + op.bf.byp_rslt_en = 0; + op.bf.op_type = 3; + op.bf.hash_block_bitmap = 3; + op.bf.op_mode = 0; + + rv = hppe_host_tbl_op_set(dev_id, &op); + if (SW_OK != rv) + return rv; + rv = hppe_host_tbl_op_rslt_get(dev_id, &result); + if (SW_OK != rv) + return rv; + while (!result.bf.valid_cnt && --i) { + hppe_host_tbl_op_rslt_get(dev_id, &result); + } + if (i == 0) + return SW_BUSY; + if (result.bf.op_rslt == 0) + return SW_OK; + else + return SW_FAIL; + + +} +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_mib.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_mib.c new file mode 100755 index 000000000..34c66db6d --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_mib.c @@ -0,0 +1,2167 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hppe_reg_access.h" +#include "hppe_mib_reg.h" +#include "hppe_mib.h" + +sw_error_t +hppe_mac_mib_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_mib_ctrl_u *value) +{ + if (index >= MAC_MIB_CTRL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + MAC_MIB_CTRL_ADDRESS + \ + index * MAC_MIB_CTRL_INC, + &value->val); +} + +sw_error_t +hppe_mac_mib_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_mib_ctrl_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_MAC_CSR_BASE_ADDR + MAC_MIB_CTRL_ADDRESS + \ + index * MAC_MIB_CTRL_INC, + value->val); +} + +sw_error_t +hppe_rxbroad_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxbroad_u *value) +{ + if (index >= RXBROAD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + RXBROAD_ADDRESS + \ + index * RXBROAD_INC, + &value->val); +} + +sw_error_t +hppe_rxbroad_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxbroad_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxpause_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxpause_u *value) +{ + if (index >= RXPAUSE_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + RXPAUSE_ADDRESS + \ + index * RXPAUSE_INC, + &value->val); +} + +sw_error_t +hppe_rxpause_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxpause_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxmulti_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxmulti_u *value) +{ + if (index >= RXMULTI_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + RXMULTI_ADDRESS + \ + index * RXMULTI_INC, + &value->val); +} + +sw_error_t +hppe_rxmulti_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxmulti_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxfcserr_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxfcserr_u *value) +{ + if (index >= RXFCSERR_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + RXFCSERR_ADDRESS + \ + index * RXFCSERR_INC, + &value->val); +} + +sw_error_t +hppe_rxfcserr_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxfcserr_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxalignerr_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxalignerr_u *value) +{ + if (index >= RXALIGNERR_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + RXALIGNERR_ADDRESS + \ + index * RXALIGNERR_INC, + &value->val); +} + +sw_error_t +hppe_rxalignerr_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxalignerr_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxrunt_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxrunt_u *value) +{ + if (index >= RXRUNT_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + RXRUNT_ADDRESS + \ + index * RXRUNT_INC, + &value->val); +} + +sw_error_t +hppe_rxrunt_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxrunt_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxfrag_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxfrag_u *value) +{ + if (index >= RXFRAG_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + RXFRAG_ADDRESS + \ + index * RXFRAG_INC, + &value->val); +} + +sw_error_t +hppe_rxfrag_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxfrag_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxjumbofcserr_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxjumbofcserr_u *value) +{ + if (index >= RXJUMBOFCSERR_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + RXJUMBOFCSERR_ADDRESS + \ + index * RXJUMBOFCSERR_INC, + &value->val); +} + +sw_error_t +hppe_rxjumbofcserr_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxjumbofcserr_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxjumboalignerr_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxjumboalignerr_u *value) +{ + if (index >= RXJUMBOALIGNERR_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + RXJUMBOALIGNERR_ADDRESS + \ + index * RXJUMBOALIGNERR_INC, + &value->val); +} + +sw_error_t +hppe_rxjumboalignerr_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxjumboalignerr_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxpkt64_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxpkt64_u *value) +{ + if (index >= RXPKT64_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + RXPKT64_ADDRESS + \ + index * RXPKT64_INC, + &value->val); +} + +sw_error_t +hppe_rxpkt64_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxpkt64_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxpkt65to127_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxpkt65to127_u *value) +{ + if (index >= RXPKT65TO127_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + RXPKT65TO127_ADDRESS + \ + index * RXPKT65TO127_INC, + &value->val); +} + +sw_error_t +hppe_rxpkt65to127_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxpkt65to127_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxpkt128to255_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxpkt128to255_u *value) +{ + if (index >= RXPKT128TO255_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + RXPKT128TO255_ADDRESS + \ + index * RXPKT128TO255_INC, + &value->val); +} + +sw_error_t +hppe_rxpkt128to255_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxpkt128to255_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxpkt256to511_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxpkt256to511_u *value) +{ + if (index >= RXPKT256TO511_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + RXPKT256TO511_ADDRESS + \ + index * RXPKT256TO511_INC, + &value->val); +} + +sw_error_t +hppe_rxpkt256to511_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxpkt256to511_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxpkt512to1023_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxpkt512to1023_u *value) +{ + if (index >= RXPKT512TO1023_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + RXPKT512TO1023_ADDRESS + \ + index * RXPKT512TO1023_INC, + &value->val); +} + +sw_error_t +hppe_rxpkt512to1023_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxpkt512to1023_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxpkt1024to1518_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxpkt1024to1518_u *value) +{ + if (index >= RXPKT1024TO1518_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + RXPKT1024TO1518_ADDRESS + \ + index * RXPKT1024TO1518_INC, + &value->val); +} + +sw_error_t +hppe_rxpkt1024to1518_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxpkt1024to1518_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxpkt1519tox_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxpkt1519tox_u *value) +{ + if (index >= RXPKT1519TOX_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + RXPKT1519TOX_ADDRESS + \ + index * RXPKT1519TOX_INC, + &value->val); +} + +sw_error_t +hppe_rxpkt1519tox_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxpkt1519tox_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxtoolong_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxtoolong_u *value) +{ + if (index >= RXTOOLONG_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + RXTOOLONG_ADDRESS + \ + index * RXTOOLONG_INC, + &value->val); +} + +sw_error_t +hppe_rxtoolong_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxtoolong_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxgoodbyte_l_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxgoodbyte_l_u *value) +{ + if (index >= RXGOODBYTE_L_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + RXGOODBYTE_L_ADDRESS + \ + index * RXGOODBYTE_L_INC, + &value->val); +} + +sw_error_t +hppe_rxgoodbyte_l_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxgoodbyte_l_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxgoodbyte_h_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxgoodbyte_h_u *value) +{ + if (index >= RXGOODBYTE_H_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + RXGOODBYTE_H_ADDRESS + \ + index * RXGOODBYTE_H_INC, + &value->val); +} + +sw_error_t +hppe_rxgoodbyte_h_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxgoodbyte_h_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxbadbyte_l_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxbadbyte_l_u *value) +{ + if (index >= RXBADBYTE_L_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + RXBADBYTE_L_ADDRESS + \ + index * RXBADBYTE_L_INC, + &value->val); +} + +sw_error_t +hppe_rxbadbyte_l_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxbadbyte_l_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxbadbyte_h_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxbadbyte_h_u *value) +{ + if (index >= RXBADBYTE_H_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + RXBADBYTE_H_ADDRESS + \ + index * RXBADBYTE_H_INC, + &value->val); +} + +sw_error_t +hppe_rxbadbyte_h_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxbadbyte_h_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxuni_get( + a_uint32_t dev_id, + a_uint32_t index, + union rxuni_u *value) +{ + if (index >= RXUNI_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + RXUNI_ADDRESS + \ + index * RXUNI_INC, + &value->val); +} + +sw_error_t +hppe_rxuni_set( + a_uint32_t dev_id, + a_uint32_t index, + union rxuni_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txbroad_get( + a_uint32_t dev_id, + a_uint32_t index, + union txbroad_u *value) +{ + if (index >= TXBROAD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + TXBROAD_ADDRESS + \ + index * TXBROAD_INC, + &value->val); +} + +sw_error_t +hppe_txbroad_set( + a_uint32_t dev_id, + a_uint32_t index, + union txbroad_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txpause_get( + a_uint32_t dev_id, + a_uint32_t index, + union txpause_u *value) +{ + if (index >= TXPAUSE_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + TXPAUSE_ADDRESS + \ + index * TXPAUSE_INC, + &value->val); +} + +sw_error_t +hppe_txpause_set( + a_uint32_t dev_id, + a_uint32_t index, + union txpause_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txmulti_get( + a_uint32_t dev_id, + a_uint32_t index, + union txmulti_u *value) +{ + if (index >= TXMULTI_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + TXMULTI_ADDRESS + \ + index * TXMULTI_INC, + &value->val); +} + +sw_error_t +hppe_txmulti_set( + a_uint32_t dev_id, + a_uint32_t index, + union txmulti_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txunderrun_get( + a_uint32_t dev_id, + a_uint32_t index, + union txunderrun_u *value) +{ + if (index >= TXUNDERRUN_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + TXUNDERRUN_ADDRESS + \ + index * TXUNDERRUN_INC, + &value->val); +} + +sw_error_t +hppe_txunderrun_set( + a_uint32_t dev_id, + a_uint32_t index, + union txunderrun_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txpkt64_get( + a_uint32_t dev_id, + a_uint32_t index, + union txpkt64_u *value) +{ + if (index >= TXPKT64_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + TXPKT64_ADDRESS + \ + index * TXPKT64_INC, + &value->val); +} + +sw_error_t +hppe_txpkt64_set( + a_uint32_t dev_id, + a_uint32_t index, + union txpkt64_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txpkt65to127_get( + a_uint32_t dev_id, + a_uint32_t index, + union txpkt65to127_u *value) +{ + if (index >= TXPKT65TO127_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + TXPKT65TO127_ADDRESS + \ + index * TXPKT65TO127_INC, + &value->val); +} + +sw_error_t +hppe_txpkt65to127_set( + a_uint32_t dev_id, + a_uint32_t index, + union txpkt65to127_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txpkt128to255_get( + a_uint32_t dev_id, + a_uint32_t index, + union txpkt128to255_u *value) +{ + if (index >= TXPKT128TO255_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + TXPKT128TO255_ADDRESS + \ + index * TXPKT128TO255_INC, + &value->val); +} + +sw_error_t +hppe_txpkt128to255_set( + a_uint32_t dev_id, + a_uint32_t index, + union txpkt128to255_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txpkt256to511_get( + a_uint32_t dev_id, + a_uint32_t index, + union txpkt256to511_u *value) +{ + if (index >= TXPKT256TO511_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + TXPKT256TO511_ADDRESS + \ + index * TXPKT256TO511_INC, + &value->val); +} + +sw_error_t +hppe_txpkt256to511_set( + a_uint32_t dev_id, + a_uint32_t index, + union txpkt256to511_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txpkt512to1023_get( + a_uint32_t dev_id, + a_uint32_t index, + union txpkt512to1023_u *value) +{ + if (index >= TXPKT512TO1023_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + TXPKT512TO1023_ADDRESS + \ + index * TXPKT512TO1023_INC, + &value->val); +} + +sw_error_t +hppe_txpkt512to1023_set( + a_uint32_t dev_id, + a_uint32_t index, + union txpkt512to1023_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txpkt1024to1518_get( + a_uint32_t dev_id, + a_uint32_t index, + union txpkt1024to1518_u *value) +{ + if (index >= TXPKT1024TO1518_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + TXPKT1024TO1518_ADDRESS + \ + index * TXPKT1024TO1518_INC, + &value->val); +} + +sw_error_t +hppe_txpkt1024to1518_set( + a_uint32_t dev_id, + a_uint32_t index, + union txpkt1024to1518_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txpkt1519tox_get( + a_uint32_t dev_id, + a_uint32_t index, + union txpkt1519tox_u *value) +{ + if (index >= TXPKT1519TOX_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + TXPKT1519TOX_ADDRESS + \ + index * TXPKT1519TOX_INC, + &value->val); +} + +sw_error_t +hppe_txpkt1519tox_set( + a_uint32_t dev_id, + a_uint32_t index, + union txpkt1519tox_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txbyte_l_get( + a_uint32_t dev_id, + a_uint32_t index, + union txbyte_l_u *value) +{ + if (index >= TXBYTE_L_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + TXBYTE_L_ADDRESS + \ + index * TXBYTE_L_INC, + &value->val); +} + +sw_error_t +hppe_txbyte_l_set( + a_uint32_t dev_id, + a_uint32_t index, + union txbyte_l_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txbyte_h_get( + a_uint32_t dev_id, + a_uint32_t index, + union txbyte_h_u *value) +{ + if (index >= TXBYTE_H_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + TXBYTE_H_ADDRESS + \ + index * TXBYTE_H_INC, + &value->val); +} + +sw_error_t +hppe_txbyte_h_set( + a_uint32_t dev_id, + a_uint32_t index, + union txbyte_h_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txcollisions_get( + a_uint32_t dev_id, + a_uint32_t index, + union txcollisions_u *value) +{ + if (index >= TXCOLLISIONS_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + TXCOLLISIONS_ADDRESS + \ + index * TXCOLLISIONS_INC, + &value->val); +} + +sw_error_t +hppe_txcollisions_set( + a_uint32_t dev_id, + a_uint32_t index, + union txcollisions_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txabortcol_get( + a_uint32_t dev_id, + a_uint32_t index, + union txabortcol_u *value) +{ + if (index >= TXABORTCOL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + TXABORTCOL_ADDRESS + \ + index * TXABORTCOL_INC, + &value->val); +} + +sw_error_t +hppe_txabortcol_set( + a_uint32_t dev_id, + a_uint32_t index, + union txabortcol_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txmulticol_get( + a_uint32_t dev_id, + a_uint32_t index, + union txmulticol_u *value) +{ + if (index >= TXMULTICOL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + TXMULTICOL_ADDRESS + \ + index * TXMULTICOL_INC, + &value->val); +} + +sw_error_t +hppe_txmulticol_set( + a_uint32_t dev_id, + a_uint32_t index, + union txmulticol_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txsinglecol_get( + a_uint32_t dev_id, + a_uint32_t index, + union txsinglecol_u *value) +{ + if (index >= TXSINGLECOL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + TXSINGLECOL_ADDRESS + \ + index * TXSINGLECOL_INC, + &value->val); +} + +sw_error_t +hppe_txsinglecol_set( + a_uint32_t dev_id, + a_uint32_t index, + union txsinglecol_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txexcessivedefer_get( + a_uint32_t dev_id, + a_uint32_t index, + union txexcessivedefer_u *value) +{ + if (index >= TXEXCESSIVEDEFER_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + TXEXCESSIVEDEFER_ADDRESS + \ + index * TXEXCESSIVEDEFER_INC, + &value->val); +} + +sw_error_t +hppe_txexcessivedefer_set( + a_uint32_t dev_id, + a_uint32_t index, + union txexcessivedefer_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txdefer_get( + a_uint32_t dev_id, + a_uint32_t index, + union txdefer_u *value) +{ + if (index >= TXDEFER_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + TXDEFER_ADDRESS + \ + index * TXDEFER_INC, + &value->val); +} + +sw_error_t +hppe_txdefer_set( + a_uint32_t dev_id, + a_uint32_t index, + union txdefer_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txlatecol_get( + a_uint32_t dev_id, + a_uint32_t index, + union txlatecol_u *value) +{ + if (index >= TXLATECOL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + TXLATECOL_ADDRESS + \ + index * TXLATECOL_INC, + &value->val); +} + +sw_error_t +hppe_txlatecol_set( + a_uint32_t dev_id, + a_uint32_t index, + union txlatecol_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txuni_get( + a_uint32_t dev_id, + a_uint32_t index, + union txuni_u *value) +{ + if (index >= TXUNI_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + TXUNI_ADDRESS + \ + index * TXUNI_INC, + &value->val); +} + +sw_error_t +hppe_txuni_set( + a_uint32_t dev_id, + a_uint32_t index, + union txuni_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mac_mib_ctrl_mib_reset_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_mib_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_mib_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.mib_reset; + return ret; +} + +sw_error_t +hppe_mac_mib_ctrl_mib_reset_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_mib_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_mib_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mib_reset = value; + ret = hppe_mac_mib_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_mib_ctrl_mib_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_mib_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_mib_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.mib_en; + return ret; +} + +sw_error_t +hppe_mac_mib_ctrl_mib_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_mib_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_mib_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mib_en = value; + ret = hppe_mac_mib_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_mib_ctrl_mib_rd_clr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_mib_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_mib_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.mib_rd_clr; + return ret; +} + +sw_error_t +hppe_mac_mib_ctrl_mib_rd_clr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_mib_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_mib_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mib_rd_clr = value; + ret = hppe_mac_mib_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_rxbroad_rxbroad_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rxbroad_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rxbroad_get(dev_id, index, ®_val); + *value = reg_val.bf.rxbroad; + return ret; +} + +sw_error_t +hppe_rxbroad_rxbroad_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxpause_rxpause_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rxpause_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rxpause_get(dev_id, index, ®_val); + *value = reg_val.bf.rxpause; + return ret; +} + +sw_error_t +hppe_rxpause_rxpause_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxmulti_rxmulti_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rxmulti_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rxmulti_get(dev_id, index, ®_val); + *value = reg_val.bf.rxmulti; + return ret; +} + +sw_error_t +hppe_rxmulti_rxmulti_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxfcserr_rxfcserr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rxfcserr_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rxfcserr_get(dev_id, index, ®_val); + *value = reg_val.bf.rxfcserr; + return ret; +} + +sw_error_t +hppe_rxfcserr_rxfcserr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxalignerr_rxalignerr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rxalignerr_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rxalignerr_get(dev_id, index, ®_val); + *value = reg_val.bf.rxalignerr; + return ret; +} + +sw_error_t +hppe_rxalignerr_rxalignerr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxrunt_rxrunt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rxrunt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rxrunt_get(dev_id, index, ®_val); + *value = reg_val.bf.rxrunt; + return ret; +} + +sw_error_t +hppe_rxrunt_rxrunt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxfrag_rxfrag_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rxfrag_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rxfrag_get(dev_id, index, ®_val); + *value = reg_val.bf.rxfrag; + return ret; +} + +sw_error_t +hppe_rxfrag_rxfrag_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxjumbofcserr_rxjumbofcserr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rxjumbofcserr_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rxjumbofcserr_get(dev_id, index, ®_val); + *value = reg_val.bf.rxjumbofcserr; + return ret; +} + +sw_error_t +hppe_rxjumbofcserr_rxjumbofcserr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxjumboalignerr_rxjumboalignerr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rxjumboalignerr_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rxjumboalignerr_get(dev_id, index, ®_val); + *value = reg_val.bf.rxjumboalignerr; + return ret; +} + +sw_error_t +hppe_rxjumboalignerr_rxjumboalignerr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxpkt64_rxpkt64_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rxpkt64_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rxpkt64_get(dev_id, index, ®_val); + *value = reg_val.bf.rxpkt64; + return ret; +} + +sw_error_t +hppe_rxpkt64_rxpkt64_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxpkt65to127_rxpkt65to127_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rxpkt65to127_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rxpkt65to127_get(dev_id, index, ®_val); + *value = reg_val.bf.rxpkt65to127; + return ret; +} + +sw_error_t +hppe_rxpkt65to127_rxpkt65to127_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxpkt128to255_rxpkt128to255_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rxpkt128to255_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rxpkt128to255_get(dev_id, index, ®_val); + *value = reg_val.bf.rxpkt128to255; + return ret; +} + +sw_error_t +hppe_rxpkt128to255_rxpkt128to255_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxpkt256to511_rxpkt256to511_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rxpkt256to511_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rxpkt256to511_get(dev_id, index, ®_val); + *value = reg_val.bf.rxpkt256to511; + return ret; +} + +sw_error_t +hppe_rxpkt256to511_rxpkt256to511_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxpkt512to1023_rxpkt512to1023_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rxpkt512to1023_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rxpkt512to1023_get(dev_id, index, ®_val); + *value = reg_val.bf.rxpkt512to1023; + return ret; +} + +sw_error_t +hppe_rxpkt512to1023_rxpkt512to1023_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxpkt1024to1518_rxpkt1024to1518_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rxpkt1024to1518_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rxpkt1024to1518_get(dev_id, index, ®_val); + *value = reg_val.bf.rxpkt1024to1518; + return ret; +} + +sw_error_t +hppe_rxpkt1024to1518_rxpkt1024to1518_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxpkt1519tox_rxpkt1519tox_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rxpkt1519tox_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rxpkt1519tox_get(dev_id, index, ®_val); + *value = reg_val.bf.rxpkt1519tox; + return ret; +} + +sw_error_t +hppe_rxpkt1519tox_rxpkt1519tox_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxtoolong_rxtoolong_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rxtoolong_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rxtoolong_get(dev_id, index, ®_val); + *value = reg_val.bf.rxtoolong; + return ret; +} + +sw_error_t +hppe_rxtoolong_rxtoolong_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxgoodbyte_l_rxgoodbyte_l_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rxgoodbyte_l_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rxgoodbyte_l_get(dev_id, index, ®_val); + *value = reg_val.bf.rxgoodbyte_l; + return ret; +} + +sw_error_t +hppe_rxgoodbyte_l_rxgoodbyte_l_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxgoodbyte_h_rxgoodbyte_h_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rxgoodbyte_h_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rxgoodbyte_h_get(dev_id, index, ®_val); + *value = reg_val.bf.rxgoodbyte_h; + return ret; +} + +sw_error_t +hppe_rxgoodbyte_h_rxgoodbyte_h_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxbadbyte_l_rxbadbyte_l_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rxbadbyte_l_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rxbadbyte_l_get(dev_id, index, ®_val); + *value = reg_val.bf.rxbadbyte_l; + return ret; +} + +sw_error_t +hppe_rxbadbyte_l_rxbadbyte_l_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxbadbyte_h_rxbadbyte_h_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rxbadbyte_h_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rxbadbyte_h_get(dev_id, index, ®_val); + *value = reg_val.bf.rxbadbyte_h; + return ret; +} + +sw_error_t +hppe_rxbadbyte_h_rxbadbyte_h_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rxuni_rxuni_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rxuni_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rxuni_get(dev_id, index, ®_val); + *value = reg_val.bf.rxuni; + return ret; +} + +sw_error_t +hppe_rxuni_rxuni_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txbroad_txbroad_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union txbroad_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_txbroad_get(dev_id, index, ®_val); + *value = reg_val.bf.txbroad; + return ret; +} + +sw_error_t +hppe_txbroad_txbroad_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txpause_txpause_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union txpause_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_txpause_get(dev_id, index, ®_val); + *value = reg_val.bf.txpause; + return ret; +} + +sw_error_t +hppe_txpause_txpause_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txmulti_txmulti_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union txmulti_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_txmulti_get(dev_id, index, ®_val); + *value = reg_val.bf.txmulti; + return ret; +} + +sw_error_t +hppe_txmulti_txmulti_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txunderrun_txunderrun_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union txunderrun_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_txunderrun_get(dev_id, index, ®_val); + *value = reg_val.bf.txunderrun; + return ret; +} + +sw_error_t +hppe_txunderrun_txunderrun_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txpkt64_txpkt64_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union txpkt64_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_txpkt64_get(dev_id, index, ®_val); + *value = reg_val.bf.txpkt64; + return ret; +} + +sw_error_t +hppe_txpkt64_txpkt64_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txpkt65to127_txpkt65to127_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union txpkt65to127_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_txpkt65to127_get(dev_id, index, ®_val); + *value = reg_val.bf.txpkt65to127; + return ret; +} + +sw_error_t +hppe_txpkt65to127_txpkt65to127_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txpkt128to255_txpkt128to255_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union txpkt128to255_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_txpkt128to255_get(dev_id, index, ®_val); + *value = reg_val.bf.txpkt128to255; + return ret; +} + +sw_error_t +hppe_txpkt128to255_txpkt128to255_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txpkt256to511_txpkt256to511_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union txpkt256to511_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_txpkt256to511_get(dev_id, index, ®_val); + *value = reg_val.bf.txpkt256to511; + return ret; +} + +sw_error_t +hppe_txpkt256to511_txpkt256to511_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txpkt512to1023_txpkt512to1023_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union txpkt512to1023_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_txpkt512to1023_get(dev_id, index, ®_val); + *value = reg_val.bf.txpkt512to1023; + return ret; +} + +sw_error_t +hppe_txpkt512to1023_txpkt512to1023_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txpkt1024to1518_txpkt1024to1518_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union txpkt1024to1518_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_txpkt1024to1518_get(dev_id, index, ®_val); + *value = reg_val.bf.txpkt1024to1518; + return ret; +} + +sw_error_t +hppe_txpkt1024to1518_txpkt1024to1518_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txpkt1519tox_txpkt1519tox_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union txpkt1519tox_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_txpkt1519tox_get(dev_id, index, ®_val); + *value = reg_val.bf.txpkt1519tox; + return ret; +} + +sw_error_t +hppe_txpkt1519tox_txpkt1519tox_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txbyte_l_txbyte_l_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union txbyte_l_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_txbyte_l_get(dev_id, index, ®_val); + *value = reg_val.bf.txbyte_l; + return ret; +} + +sw_error_t +hppe_txbyte_l_txbyte_l_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txbyte_h_txbyte_h_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union txbyte_h_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_txbyte_h_get(dev_id, index, ®_val); + *value = reg_val.bf.txbyte_h; + return ret; +} + +sw_error_t +hppe_txbyte_h_txbyte_h_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txcollisions_txcollisions_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union txcollisions_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_txcollisions_get(dev_id, index, ®_val); + *value = reg_val.bf.txcollisions; + return ret; +} + +sw_error_t +hppe_txcollisions_txcollisions_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txabortcol_txabortcol_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union txabortcol_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_txabortcol_get(dev_id, index, ®_val); + *value = reg_val.bf.txabortcol; + return ret; +} + +sw_error_t +hppe_txabortcol_txabortcol_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txmulticol_txmulticol_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union txmulticol_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_txmulticol_get(dev_id, index, ®_val); + *value = reg_val.bf.txmulticol; + return ret; +} + +sw_error_t +hppe_txmulticol_txmulticol_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txsinglecol_txsinglecol_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union txsinglecol_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_txsinglecol_get(dev_id, index, ®_val); + *value = reg_val.bf.txsinglecol; + return ret; +} + +sw_error_t +hppe_txsinglecol_txsinglecol_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txexcessivedefer_txexcessivedefer_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union txexcessivedefer_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_txexcessivedefer_get(dev_id, index, ®_val); + *value = reg_val.bf.txexcessivedefer; + return ret; +} + +sw_error_t +hppe_txexcessivedefer_txexcessivedefer_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txdefer_txdefer_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union txdefer_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_txdefer_get(dev_id, index, ®_val); + *value = reg_val.bf.txdefer; + return ret; +} + +sw_error_t +hppe_txdefer_txdefer_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txlatecol_txlatecol_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union txlatecol_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_txlatecol_get(dev_id, index, ®_val); + *value = reg_val.bf.txlatecol; + return ret; +} + +sw_error_t +hppe_txlatecol_txlatecol_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_txuni_txuni_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union txuni_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_txuni_get(dev_id, index, ®_val); + *value = reg_val.bf.txuni; + return ret; +} + +sw_error_t +hppe_txuni_txuni_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_mirror.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_mirror.c new file mode 100755 index 000000000..531460a7f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_mirror.c @@ -0,0 +1,194 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hppe_reg_access.h" +#include "hppe_mirror_reg.h" +#include "hppe_mirror.h" + +sw_error_t +hppe_mirror_analyzer_get( + a_uint32_t dev_id, + union mirror_analyzer_u *value) +{ + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + MIRROR_ANALYZER_ADDRESS, + &value->val); +} + +sw_error_t +hppe_mirror_analyzer_set( + a_uint32_t dev_id, + union mirror_analyzer_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L2_BASE_ADDR + MIRROR_ANALYZER_ADDRESS, + value->val); +} + +sw_error_t +hppe_port_mirror_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_mirror_u *value) +{ + if (index >= PORT_MIRROR_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + PORT_MIRROR_ADDRESS + \ + index * PORT_MIRROR_INC, + &value->val); +} + +sw_error_t +hppe_port_mirror_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_mirror_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L2_BASE_ADDR + PORT_MIRROR_ADDRESS + \ + index * PORT_MIRROR_INC, + value->val); +} + +sw_error_t +hppe_mirror_analyzer_in_analyzer_port_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union mirror_analyzer_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mirror_analyzer_get(dev_id, ®_val); + *value = reg_val.bf.in_analyzer_port; + return ret; +} + +sw_error_t +hppe_mirror_analyzer_in_analyzer_port_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union mirror_analyzer_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mirror_analyzer_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.in_analyzer_port = value; + ret = hppe_mirror_analyzer_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_mirror_analyzer_eg_analyzer_port_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union mirror_analyzer_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mirror_analyzer_get(dev_id, ®_val); + *value = reg_val.bf.eg_analyzer_port; + return ret; +} + +sw_error_t +hppe_mirror_analyzer_eg_analyzer_port_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union mirror_analyzer_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mirror_analyzer_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.eg_analyzer_port = value; + ret = hppe_mirror_analyzer_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_mirror_in_mirr_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_mirror_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_mirror_get(dev_id, index, ®_val); + *value = reg_val.bf.in_mirr_en; + return ret; +} + +sw_error_t +hppe_port_mirror_in_mirr_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_mirror_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_mirror_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.in_mirr_en = value; + ret = hppe_port_mirror_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_mirror_eg_mirr_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_mirror_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_mirror_get(dev_id, index, ®_val); + *value = reg_val.bf.eg_mirr_en; + return ret; +} + +sw_error_t +hppe_port_mirror_eg_mirr_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_mirror_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_mirror_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.eg_mirr_en = value; + ret = hppe_port_mirror_set(dev_id, index, ®_val); + return ret; +} diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_policer.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_policer.c new file mode 100755 index 000000000..1c17bde47 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_policer.c @@ -0,0 +1,2928 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hppe_reg_access.h" +#include "hppe_policer_reg.h" +#include "hppe_policer.h" + +sw_error_t +hppe_meter_cmpst_length_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + union meter_cmpst_length_reg_u *value) +{ + if (index >= METER_CMPST_LENGTH_REG_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + INGRESS_POLICER_BASE_ADDR + METER_CMPST_LENGTH_REG_ADDRESS + \ + index * METER_CMPST_LENGTH_REG_INC, + &value->val); +} + +sw_error_t +hppe_meter_cmpst_length_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + union meter_cmpst_length_reg_u *value) +{ + return hppe_reg_set( + dev_id, + INGRESS_POLICER_BASE_ADDR + METER_CMPST_LENGTH_REG_ADDRESS + \ + index * METER_CMPST_LENGTH_REG_INC, + value->val); +} + +#ifndef IN_POLICER_MINI +sw_error_t +hppe_pc_drop_bypass_reg_get( + a_uint32_t dev_id, + union pc_drop_bypass_reg_u *value) +{ + return hppe_reg_get( + dev_id, + INGRESS_POLICER_BASE_ADDR + PC_DROP_BYPASS_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_pc_drop_bypass_reg_set( + a_uint32_t dev_id, + union pc_drop_bypass_reg_u *value) +{ + return hppe_reg_set( + dev_id, + INGRESS_POLICER_BASE_ADDR + PC_DROP_BYPASS_REG_ADDRESS, + value->val); +} + +sw_error_t +hppe_pc_spare_reg_get( + a_uint32_t dev_id, + union pc_spare_reg_u *value) +{ + return hppe_reg_get( + dev_id, + INGRESS_POLICER_BASE_ADDR + PC_SPARE_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_pc_spare_reg_set( + a_uint32_t dev_id, + union pc_spare_reg_u *value) +{ + return hppe_reg_set( + dev_id, + INGRESS_POLICER_BASE_ADDR + PC_SPARE_REG_ADDRESS, + value->val); +} + +sw_error_t +hppe_time_slot_reg_get( + a_uint32_t dev_id, + union time_slot_reg_u *value) +{ + return hppe_reg_get( + dev_id, + INGRESS_POLICER_BASE_ADDR + TIME_SLOT_REG_ADDRESS, + &value->val); +} +#endif + +sw_error_t +hppe_time_slot_reg_set( + a_uint32_t dev_id, + union time_slot_reg_u *value) +{ + return hppe_reg_set( + dev_id, + INGRESS_POLICER_BASE_ADDR + TIME_SLOT_REG_ADDRESS, + value->val); +} + +#ifndef IN_POLICER_MINI +sw_error_t +hppe_pc_dbg_addr_reg_get( + a_uint32_t dev_id, + union pc_dbg_addr_reg_u *value) +{ + return hppe_reg_get( + dev_id, + INGRESS_POLICER_BASE_ADDR + PC_DBG_ADDR_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_pc_dbg_addr_reg_set( + a_uint32_t dev_id, + union pc_dbg_addr_reg_u *value) +{ + return hppe_reg_set( + dev_id, + INGRESS_POLICER_BASE_ADDR + PC_DBG_ADDR_REG_ADDRESS, + value->val); +} + +sw_error_t +hppe_pc_dbg_data_reg_get( + a_uint32_t dev_id, + union pc_dbg_data_reg_u *value) +{ + return hppe_reg_get( + dev_id, + INGRESS_POLICER_BASE_ADDR + PC_DBG_DATA_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_pc_dbg_data_reg_set( + a_uint32_t dev_id, + union pc_dbg_data_reg_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union in_acl_meter_cfg_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + INGRESS_POLICER_BASE_ADDR + IN_ACL_METER_CFG_TBL_ADDRESS + \ + index * IN_ACL_METER_CFG_TBL_INC, + value->val, + 4); +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union in_acl_meter_cfg_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + INGRESS_POLICER_BASE_ADDR + IN_ACL_METER_CFG_TBL_ADDRESS + \ + index * IN_ACL_METER_CFG_TBL_INC, + value->val, + 4); +} + +sw_error_t +hppe_in_acl_meter_crdt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union in_acl_meter_crdt_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + INGRESS_POLICER_BASE_ADDR + IN_ACL_METER_CRDT_TBL_ADDRESS + \ + index * IN_ACL_METER_CRDT_TBL_INC, + value->val, + 2); +} + +sw_error_t +hppe_in_acl_meter_crdt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union in_acl_meter_crdt_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + INGRESS_POLICER_BASE_ADDR + IN_ACL_METER_CRDT_TBL_ADDRESS + \ + index * IN_ACL_METER_CRDT_TBL_INC, + value->val, + 2); +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union in_port_meter_cfg_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + INGRESS_POLICER_BASE_ADDR + IN_PORT_METER_CFG_TBL_ADDRESS + \ + index * IN_PORT_METER_CFG_TBL_INC, + value->val, + 4); +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union in_port_meter_cfg_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + INGRESS_POLICER_BASE_ADDR + IN_PORT_METER_CFG_TBL_ADDRESS + \ + index * IN_PORT_METER_CFG_TBL_INC, + value->val, + 4); +} + +sw_error_t +hppe_in_port_meter_crdt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union in_port_meter_crdt_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + INGRESS_POLICER_BASE_ADDR + IN_PORT_METER_CRDT_TBL_ADDRESS + \ + index * IN_PORT_METER_CRDT_TBL_INC, + value->val, + 2); +} + +sw_error_t +hppe_in_port_meter_crdt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union in_port_meter_crdt_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + INGRESS_POLICER_BASE_ADDR + IN_PORT_METER_CRDT_TBL_ADDRESS + \ + index * IN_PORT_METER_CRDT_TBL_INC, + value->val, + 2); +} + +sw_error_t +hppe_in_port_meter_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union in_port_meter_cnt_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + INGRESS_POLICER_BASE_ADDR + IN_PORT_METER_CNT_TBL_ADDRESS + \ + index * IN_PORT_METER_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_in_port_meter_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union in_port_meter_cnt_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + INGRESS_POLICER_BASE_ADDR + IN_PORT_METER_CNT_TBL_ADDRESS + \ + index * IN_PORT_METER_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_in_acl_meter_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union in_acl_meter_cnt_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + INGRESS_POLICER_BASE_ADDR + IN_ACL_METER_CNT_TBL_ADDRESS + \ + index * IN_ACL_METER_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_in_acl_meter_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union in_acl_meter_cnt_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + INGRESS_POLICER_BASE_ADDR + IN_ACL_METER_CNT_TBL_ADDRESS + \ + index * IN_ACL_METER_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_pc_global_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union pc_global_cnt_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + INGRESS_POLICER_BASE_ADDR + PC_GLOBAL_CNT_TBL_ADDRESS + \ + index * PC_GLOBAL_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_pc_global_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union pc_global_cnt_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + INGRESS_POLICER_BASE_ADDR + PC_GLOBAL_CNT_TBL_ADDRESS + \ + index * PC_GLOBAL_CNT_TBL_INC, + value->val, + 3); +} +#endif + +sw_error_t +hppe_drop_cpu_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union drop_cpu_cnt_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + INGRESS_POLICER_BASE_ADDR + DROP_CPU_CNT_TBL_ADDRESS + \ + index * DROP_CPU_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_drop_cpu_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union drop_cpu_cnt_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + INGRESS_POLICER_BASE_ADDR + DROP_CPU_CNT_TBL_ADDRESS + \ + index * DROP_CPU_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_port_tx_drop_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_tx_drop_cnt_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + INGRESS_POLICER_BASE_ADDR + PORT_TX_DROP_CNT_TBL_ADDRESS + \ + index * PORT_TX_DROP_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_port_tx_drop_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_tx_drop_cnt_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + INGRESS_POLICER_BASE_ADDR + PORT_TX_DROP_CNT_TBL_ADDRESS + \ + index * PORT_TX_DROP_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_vp_tx_drop_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union vp_tx_drop_cnt_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + INGRESS_POLICER_BASE_ADDR + VP_TX_DROP_CNT_TBL_ADDRESS + \ + index * VP_TX_DROP_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_vp_tx_drop_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union vp_tx_drop_cnt_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + INGRESS_POLICER_BASE_ADDR + VP_TX_DROP_CNT_TBL_ADDRESS + \ + index * VP_TX_DROP_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_vlan_dev_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union vlan_dev_cnt_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + INGRESS_POLICER_BASE_ADDR + VLAN_DEV_CNT_TBL_ADDRESS + \ + index * VLAN_DEV_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_vlan_dev_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union vlan_dev_cnt_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + INGRESS_POLICER_BASE_ADDR + VLAN_DEV_CNT_TBL_ADDRESS + \ + index * VLAN_DEV_CNT_TBL_INC, + value->val, + 3); +} + +#ifndef IN_POLICER_MINI +sw_error_t +hppe_meter_cmpst_length_reg_cmpst_length_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union meter_cmpst_length_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_meter_cmpst_length_reg_get(dev_id, index, ®_val); + *value = reg_val.bf.cmpst_length; + return ret; +} + +sw_error_t +hppe_meter_cmpst_length_reg_cmpst_length_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union meter_cmpst_length_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_meter_cmpst_length_reg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmpst_length = value; + ret = hppe_meter_cmpst_length_reg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pc_drop_bypass_reg_drop_bypass_en_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union pc_drop_bypass_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pc_drop_bypass_reg_get(dev_id, ®_val); + *value = reg_val.bf.drop_bypass_en; + return ret; +} + +sw_error_t +hppe_pc_drop_bypass_reg_drop_bypass_en_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union pc_drop_bypass_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pc_drop_bypass_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.drop_bypass_en = value; + ret = hppe_pc_drop_bypass_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_pc_spare_reg_spare_reg_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union pc_spare_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pc_spare_reg_get(dev_id, ®_val); + *value = reg_val.bf.spare_reg; + return ret; +} + +sw_error_t +hppe_pc_spare_reg_spare_reg_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union pc_spare_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pc_spare_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.spare_reg = value; + ret = hppe_pc_spare_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_time_slot_reg_time_slot_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union time_slot_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_time_slot_reg_get(dev_id, ®_val); + *value = reg_val.bf.time_slot; + return ret; +} + +sw_error_t +hppe_time_slot_reg_time_slot_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union time_slot_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_time_slot_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.time_slot = value; + ret = hppe_time_slot_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_pc_dbg_addr_reg_dbg_addr_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union pc_dbg_addr_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pc_dbg_addr_reg_get(dev_id, ®_val); + *value = reg_val.bf.dbg_addr; + return ret; +} + +sw_error_t +hppe_pc_dbg_addr_reg_dbg_addr_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union pc_dbg_addr_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pc_dbg_addr_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.dbg_addr = value; + ret = hppe_pc_dbg_addr_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_pc_dbg_data_reg_dbg_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union pc_dbg_data_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pc_dbg_data_reg_get(dev_id, ®_val); + *value = reg_val.bf.dbg_data; + return ret; +} + +sw_error_t +hppe_pc_dbg_data_reg_dbg_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_meter_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.meter_mode; + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_meter_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.meter_mode = value; + ret = hppe_in_acl_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_color_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.color_mode; + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_color_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.color_mode = value; + ret = hppe_in_acl_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_exceed_chg_pcp_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.exceed_chg_pcp_cmd; + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_exceed_chg_pcp_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.exceed_chg_pcp_cmd = value; + ret = hppe_in_acl_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_exceed_pri_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.exceed_pri; + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_exceed_pri_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.exceed_pri = value; + ret = hppe_in_acl_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_exceed_chg_pri_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.exceed_chg_pri_cmd; + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_exceed_chg_pri_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.exceed_chg_pri_cmd = value; + ret = hppe_in_acl_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_exceed_dp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.exceed_dp; + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_exceed_dp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.exceed_dp = value; + ret = hppe_in_acl_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_dp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.violate_dp; + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_dp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.violate_dp = value; + ret = hppe_in_acl_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_exceed_dei_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.exceed_dei; + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_exceed_dei_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.exceed_dei = value; + ret = hppe_in_acl_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_pri_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.violate_pri_1 << 1 | \ + reg_val.bf.violate_pri_0; + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_pri_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.violate_pri_1 = value >> 1; + reg_val.bf.violate_pri_0 = value & (((a_uint64_t)1<<1)-1); + ret = hppe_in_acl_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_cbs_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.cbs; + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_cbs_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cbs = value; + ret = hppe_in_acl_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_chg_dei_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.violate_chg_dei_cmd; + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_chg_dei_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.violate_chg_dei_cmd = value; + ret = hppe_in_acl_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_chg_pcp_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.violate_chg_pcp_cmd; + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_chg_pcp_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.violate_chg_pcp_cmd = value; + ret = hppe_in_acl_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_cir_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.cir_1 << 8 | \ + reg_val.bf.cir_0; + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_cir_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cir_1 = value >> 8; + reg_val.bf.cir_0 = value & (((a_uint64_t)1<<8)-1); + ret = hppe_in_acl_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_dei_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.violate_dei; + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_dei_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.violate_dei = value; + ret = hppe_in_acl_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_chg_pri_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.violate_chg_pri_cmd; + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_chg_pri_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.violate_chg_pri_cmd = value; + ret = hppe_in_acl_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_meter_unit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.meter_unit; + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_meter_unit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.meter_unit = value; + ret = hppe_in_acl_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_meter_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.meter_en; + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_meter_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.meter_en = value; + ret = hppe_in_acl_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.violate_cmd; + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.violate_cmd = value; + ret = hppe_in_acl_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_chg_dp_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.violate_chg_dp_cmd; + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_chg_dp_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.violate_chg_dp_cmd = value; + ret = hppe_in_acl_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_eir_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.eir_1 << 6 | \ + reg_val.bf.eir_0; + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_eir_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.eir_1 = value >> 6; + reg_val.bf.eir_0 = value & (((a_uint64_t)1<<6)-1); + ret = hppe_in_acl_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_exceed_chg_dp_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.exceed_chg_dp_cmd; + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_exceed_chg_dp_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.exceed_chg_dp_cmd = value; + ret = hppe_in_acl_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_exceed_chg_dei_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.exceed_chg_dei_cmd; + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_exceed_chg_dei_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.exceed_chg_dei_cmd = value; + ret = hppe_in_acl_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_exceed_pcp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.exceed_pcp; + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_exceed_pcp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.exceed_pcp = value; + ret = hppe_in_acl_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_pcp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.violate_pcp; + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_violate_pcp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.violate_pcp = value; + ret = hppe_in_acl_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_token_unit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.token_unit; + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_token_unit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.token_unit = value; + ret = hppe_in_acl_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_coupling_flag_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.coupling_flag; + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_coupling_flag_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.coupling_flag = value; + ret = hppe_in_acl_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_ebs_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ebs; + return ret; +} + +sw_error_t +hppe_in_acl_meter_cfg_tbl_ebs_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_acl_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ebs = value; + ret = hppe_in_acl_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_acl_meter_crdt_tbl_c_crdt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_acl_meter_crdt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_crdt_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.c_crdt; + return ret; +} + +sw_error_t +hppe_in_acl_meter_crdt_tbl_c_crdt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_acl_meter_crdt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_crdt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.c_crdt = value; + ret = hppe_in_acl_meter_crdt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_acl_meter_crdt_tbl_e_crdt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_acl_meter_crdt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_crdt_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.e_crdt; + return ret; +} + +sw_error_t +hppe_in_acl_meter_crdt_tbl_e_crdt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_acl_meter_crdt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_crdt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.e_crdt = value; + ret = hppe_in_acl_meter_crdt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_meter_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.meter_mode; + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_meter_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.meter_mode = value; + ret = hppe_in_port_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_color_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.color_mode; + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_color_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.color_mode = value; + ret = hppe_in_port_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_exceed_chg_pcp_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.exceed_chg_pcp_cmd; + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_exceed_chg_pcp_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.exceed_chg_pcp_cmd = value; + ret = hppe_in_port_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_exceed_pri_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.exceed_pri; + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_exceed_pri_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.exceed_pri = value; + ret = hppe_in_port_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_exceed_chg_pri_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.exceed_chg_pri_cmd; + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_exceed_chg_pri_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.exceed_chg_pri_cmd = value; + ret = hppe_in_port_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_exceed_dp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.exceed_dp; + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_exceed_dp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.exceed_dp = value; + ret = hppe_in_port_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_dp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.violate_dp; + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_dp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.violate_dp = value; + ret = hppe_in_port_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_exceed_dei_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.exceed_dei; + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_exceed_dei_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.exceed_dei = value; + ret = hppe_in_port_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_pri_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.violate_pri; + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_pri_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.violate_pri = value; + ret = hppe_in_port_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_cbs_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.cbs; + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_cbs_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cbs = value; + ret = hppe_in_port_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_chg_dei_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.violate_chg_dei_cmd; + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_chg_dei_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.violate_chg_dei_cmd = value; + ret = hppe_in_port_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_chg_pcp_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.violate_chg_pcp_cmd; + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_chg_pcp_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.violate_chg_pcp_cmd = value; + ret = hppe_in_port_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_cir_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.cir_1 << 3 | \ + reg_val.bf.cir_0; + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_cir_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cir_1 = value >> 3; + reg_val.bf.cir_0 = value & (((a_uint64_t)1<<3)-1); + ret = hppe_in_port_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_dei_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.violate_dei; + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_dei_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.violate_dei = value; + ret = hppe_in_port_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_chg_pri_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.violate_chg_pri_cmd; + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_chg_pri_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.violate_chg_pri_cmd = value; + ret = hppe_in_port_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_meter_unit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.meter_unit; + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_meter_unit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.meter_unit = value; + ret = hppe_in_port_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_meter_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.meter_en; + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_meter_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.meter_en = value; + ret = hppe_in_port_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.violate_cmd; + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.violate_cmd = value; + ret = hppe_in_port_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_chg_dp_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.violate_chg_dp_cmd; + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_chg_dp_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.violate_chg_dp_cmd = value; + ret = hppe_in_port_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_eir_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.eir_1 << 1 | \ + reg_val.bf.eir_0; + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_eir_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.eir_1 = value >> 1; + reg_val.bf.eir_0 = value & (((a_uint64_t)1<<1)-1); + ret = hppe_in_port_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_exceed_chg_dp_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.exceed_chg_dp_cmd; + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_exceed_chg_dp_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.exceed_chg_dp_cmd = value; + ret = hppe_in_port_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_exceed_chg_dei_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.exceed_chg_dei_cmd; + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_exceed_chg_dei_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.exceed_chg_dei_cmd = value; + ret = hppe_in_port_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_exceed_pcp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.exceed_pcp; + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_exceed_pcp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.exceed_pcp = value; + ret = hppe_in_port_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_pcp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.violate_pcp; + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_violate_pcp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.violate_pcp = value; + ret = hppe_in_port_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_token_unit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.token_unit; + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_token_unit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.token_unit = value; + ret = hppe_in_port_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_coupling_flag_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.coupling_flag; + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_coupling_flag_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.coupling_flag = value; + ret = hppe_in_port_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_meter_flag_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.meter_flag; + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_meter_flag_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.meter_flag = value; + ret = hppe_in_port_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_ebs_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ebs; + return ret; +} + +sw_error_t +hppe_in_port_meter_cfg_tbl_ebs_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_port_meter_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ebs = value; + ret = hppe_in_port_meter_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_port_meter_crdt_tbl_c_crdt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_port_meter_crdt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_crdt_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.c_crdt; + return ret; +} + +sw_error_t +hppe_in_port_meter_crdt_tbl_c_crdt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_port_meter_crdt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_crdt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.c_crdt = value; + ret = hppe_in_port_meter_crdt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_port_meter_crdt_tbl_e_crdt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_port_meter_crdt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_crdt_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.e_crdt; + return ret; +} + +sw_error_t +hppe_in_port_meter_crdt_tbl_e_crdt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_port_meter_crdt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_crdt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.e_crdt = value; + ret = hppe_in_port_meter_crdt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_port_meter_cnt_tbl_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union in_port_meter_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cnt_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.byte_cnt_1 << 32 | \ + reg_val.bf.byte_cnt_0; + return ret; +} + +sw_error_t +hppe_in_port_meter_cnt_tbl_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union in_port_meter_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.byte_cnt_1 = value >> 32; + reg_val.bf.byte_cnt_0 = value & (((a_uint64_t)1<<32)-1); + ret = hppe_in_port_meter_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_port_meter_cnt_tbl_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_port_meter_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cnt_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.pkt_cnt; + return ret; +} + +sw_error_t +hppe_in_port_meter_cnt_tbl_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_port_meter_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_port_meter_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pkt_cnt = value; + ret = hppe_in_port_meter_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_acl_meter_cnt_tbl_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union in_acl_meter_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cnt_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.byte_cnt_1 << 32 | \ + reg_val.bf.byte_cnt_0; + return ret; +} + +sw_error_t +hppe_in_acl_meter_cnt_tbl_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union in_acl_meter_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.byte_cnt_1 = value >> 32; + reg_val.bf.byte_cnt_0 = value & (((a_uint64_t)1<<32)-1); + ret = hppe_in_acl_meter_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_acl_meter_cnt_tbl_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_acl_meter_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cnt_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.pkt_cnt; + return ret; +} + +sw_error_t +hppe_in_acl_meter_cnt_tbl_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_acl_meter_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_acl_meter_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pkt_cnt = value; + ret = hppe_in_acl_meter_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pc_global_cnt_tbl_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union pc_global_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pc_global_cnt_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.byte_cnt_1 << 32 | \ + reg_val.bf.byte_cnt_0; + return ret; +} + +sw_error_t +hppe_pc_global_cnt_tbl_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union pc_global_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pc_global_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.byte_cnt_1 = value >> 32; + reg_val.bf.byte_cnt_0 = value & (((a_uint64_t)1<<32)-1); + ret = hppe_pc_global_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pc_global_cnt_tbl_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pc_global_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pc_global_cnt_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.pkt_cnt; + return ret; +} + +sw_error_t +hppe_pc_global_cnt_tbl_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pc_global_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pc_global_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pkt_cnt = value; + ret = hppe_pc_global_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_drop_cpu_cnt_tbl_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union drop_cpu_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_drop_cpu_cnt_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.byte_cnt_1 << 32 | \ + reg_val.bf.byte_cnt_0; + return ret; +} + +sw_error_t +hppe_drop_cpu_cnt_tbl_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union drop_cpu_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_drop_cpu_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.byte_cnt_1 = value >> 32; + reg_val.bf.byte_cnt_0 = value & (((a_uint64_t)1<<32)-1); + ret = hppe_drop_cpu_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_drop_cpu_cnt_tbl_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union drop_cpu_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_drop_cpu_cnt_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.pkt_cnt; + return ret; +} + +sw_error_t +hppe_drop_cpu_cnt_tbl_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union drop_cpu_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_drop_cpu_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pkt_cnt = value; + ret = hppe_drop_cpu_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_tx_drop_cnt_tbl_tx_drop_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union port_tx_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_tx_drop_cnt_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.tx_drop_byte_cnt_1 << 32 | \ + reg_val.bf.tx_drop_byte_cnt_0; + return ret; +} + +sw_error_t +hppe_port_tx_drop_cnt_tbl_tx_drop_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union port_tx_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_tx_drop_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_drop_byte_cnt_1 = value >> 32; + reg_val.bf.tx_drop_byte_cnt_0 = value & (((a_uint64_t)1<<32)-1); + ret = hppe_port_tx_drop_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_tx_drop_cnt_tbl_tx_drop_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_tx_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_tx_drop_cnt_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_drop_pkt_cnt; + return ret; +} + +sw_error_t +hppe_port_tx_drop_cnt_tbl_tx_drop_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_tx_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_tx_drop_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_drop_pkt_cnt = value; + ret = hppe_port_tx_drop_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vp_tx_drop_cnt_tbl_tx_drop_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union vp_tx_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vp_tx_drop_cnt_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.tx_drop_byte_cnt_1 << 32 | \ + reg_val.bf.tx_drop_byte_cnt_0; + return ret; +} + +sw_error_t +hppe_vp_tx_drop_cnt_tbl_tx_drop_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union vp_tx_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vp_tx_drop_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_drop_byte_cnt_1 = value >> 32; + reg_val.bf.tx_drop_byte_cnt_0 = value & (((a_uint64_t)1<<32)-1); + ret = hppe_vp_tx_drop_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vp_tx_drop_cnt_tbl_tx_drop_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vp_tx_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vp_tx_drop_cnt_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_drop_pkt_cnt; + return ret; +} + +sw_error_t +hppe_vp_tx_drop_cnt_tbl_tx_drop_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vp_tx_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vp_tx_drop_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_drop_pkt_cnt = value; + ret = hppe_vp_tx_drop_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vlan_dev_cnt_tbl_rx_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union vlan_dev_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vlan_dev_cnt_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.rx_byte_cnt_1 << 32 | \ + reg_val.bf.rx_byte_cnt_0; + return ret; +} + +sw_error_t +hppe_vlan_dev_cnt_tbl_rx_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union vlan_dev_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vlan_dev_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_byte_cnt_1 = value >> 32; + reg_val.bf.rx_byte_cnt_0 = value & (((a_uint64_t)1<<32)-1); + ret = hppe_vlan_dev_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vlan_dev_cnt_tbl_rx_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vlan_dev_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vlan_dev_cnt_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.rx_pkt_cnt; + return ret; +} + +sw_error_t +hppe_vlan_dev_cnt_tbl_rx_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vlan_dev_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vlan_dev_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_pkt_cnt = value; + ret = hppe_vlan_dev_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_portctrl.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_portctrl.c new file mode 100755 index 000000000..3771da908 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_portctrl.c @@ -0,0 +1,3441 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hppe_reg_access.h" +#include "hppe_portctrl_reg.h" +#include "hppe_portctrl.h" + +sw_error_t +hppe_mac_enable_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_enable_u *value) +{ + if (index >= MAC_ENABLE_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + MAC_ENABLE_ADDRESS + \ + index * MAC_ENABLE_INC, + &value->val); +} + +sw_error_t +hppe_mac_enable_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_enable_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_MAC_CSR_BASE_ADDR + MAC_ENABLE_ADDRESS + \ + index * MAC_ENABLE_INC, + value->val); +} + +sw_error_t +hppe_mac_speed_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_speed_u *value) +{ + if (index >= MAC_SPEED_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + MAC_SPEED_ADDRESS + \ + index * MAC_SPEED_INC, + &value->val); +} + +sw_error_t +hppe_mac_speed_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_speed_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_MAC_CSR_BASE_ADDR + MAC_SPEED_ADDRESS + \ + index * MAC_SPEED_INC, + value->val); +} +#ifndef IN_PORTCONTROL_MINI +sw_error_t +hppe_gol_mac_addr0_get( + a_uint32_t dev_id, + a_uint32_t index, + union gol_mac_addr0_u *value) +{ + if (index >= GOL_MAC_ADDR0_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + GOL_MAC_ADDR0_ADDRESS + \ + index * GOL_MAC_ADDR0_INC, + &value->val); +} + +sw_error_t +hppe_gol_mac_addr0_set( + a_uint32_t dev_id, + a_uint32_t index, + union gol_mac_addr0_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_MAC_CSR_BASE_ADDR + GOL_MAC_ADDR0_ADDRESS + \ + index * GOL_MAC_ADDR0_INC, + value->val); +} + +sw_error_t +hppe_gol_mac_addr1_get( + a_uint32_t dev_id, + a_uint32_t index, + union gol_mac_addr1_u *value) +{ + if (index >= GOL_MAC_ADDR1_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + GOL_MAC_ADDR1_ADDRESS + \ + index * GOL_MAC_ADDR1_INC, + &value->val); +} + +sw_error_t +hppe_gol_mac_addr1_set( + a_uint32_t dev_id, + a_uint32_t index, + union gol_mac_addr1_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_MAC_CSR_BASE_ADDR + GOL_MAC_ADDR1_ADDRESS + \ + index * GOL_MAC_ADDR1_INC, + value->val); +} + +sw_error_t +hppe_mac_ctrl0_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_ctrl0_u *value) +{ + if (index >= MAC_CTRL0_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + MAC_CTRL0_ADDRESS + \ + index * MAC_CTRL0_INC, + &value->val); +} + +sw_error_t +hppe_mac_ctrl0_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_ctrl0_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_MAC_CSR_BASE_ADDR + MAC_CTRL0_ADDRESS + \ + index * MAC_CTRL0_INC, + value->val); +} + +sw_error_t +hppe_mac_ctrl1_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_ctrl1_u *value) +{ + if (index >= MAC_CTRL1_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + MAC_CTRL1_ADDRESS + \ + index * MAC_CTRL1_INC, + &value->val); +} + +sw_error_t +hppe_mac_ctrl1_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_ctrl1_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_MAC_CSR_BASE_ADDR + MAC_CTRL1_ADDRESS + \ + index * MAC_CTRL1_INC, + value->val); +} +#endif +sw_error_t +hppe_mac_ctrl2_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_ctrl2_u *value) +{ + if (index >= MAC_CTRL2_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + MAC_CTRL2_ADDRESS + \ + index * MAC_CTRL2_INC, + &value->val); +} + +sw_error_t +hppe_mac_ctrl2_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_ctrl2_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_MAC_CSR_BASE_ADDR + MAC_CTRL2_ADDRESS + \ + index * MAC_CTRL2_INC, + value->val); +} + +sw_error_t +hppe_mac_dbg_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_dbg_ctrl_u *value) +{ + if (index >= MAC_DBG_CTRL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + MAC_DBG_CTRL_ADDRESS + \ + index * MAC_DBG_CTRL_INC, + &value->val); +} + +sw_error_t +hppe_mac_dbg_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_dbg_ctrl_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_MAC_CSR_BASE_ADDR + MAC_DBG_CTRL_ADDRESS + \ + index * MAC_DBG_CTRL_INC, + value->val); +} +#ifndef IN_PORTCONTROL_MINI +sw_error_t +hppe_mac_dbg_addr_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_dbg_addr_u *value) +{ + if (index >= MAC_DBG_ADDR_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + MAC_DBG_ADDR_ADDRESS + \ + index * MAC_DBG_ADDR_INC, + &value->val); +} + +sw_error_t +hppe_mac_dbg_addr_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_dbg_addr_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_MAC_CSR_BASE_ADDR + MAC_DBG_ADDR_ADDRESS + \ + index * MAC_DBG_ADDR_INC, + value->val); +} + +sw_error_t +hppe_mac_dbg_data_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_dbg_data_u *value) +{ + if (index >= MAC_DBG_DATA_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + MAC_DBG_DATA_ADDRESS + \ + index * MAC_DBG_DATA_INC, + &value->val); +} + +sw_error_t +hppe_mac_dbg_data_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_dbg_data_u *value) +{ + return SW_NOT_SUPPORTED; +} +#endif + +sw_error_t +hppe_mac_jumbo_size_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_jumbo_size_u *value) +{ + if (index >= MAC_JUMBO_SIZE_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_MAC_CSR_BASE_ADDR + MAC_JUMBO_SIZE_ADDRESS + \ + index * MAC_JUMBO_SIZE_INC, + &value->val); +} + +sw_error_t +hppe_mac_jumbo_size_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_jumbo_size_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_MAC_CSR_BASE_ADDR + MAC_JUMBO_SIZE_ADDRESS + \ + index * MAC_JUMBO_SIZE_INC, + value->val); +} + +sw_error_t +hppe_mru_mtu_ctrl_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mru_mtu_ctrl_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + IPE_L2_BASE_ADDR + MRU_MTU_CTRL_TBL_ADDRESS + \ + index * MRU_MTU_CTRL_TBL_INC, + value->val, + 2); +} + +sw_error_t +hppe_mru_mtu_ctrl_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mru_mtu_ctrl_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + IPE_L2_BASE_ADDR + MRU_MTU_CTRL_TBL_ADDRESS + \ + index * MRU_MTU_CTRL_TBL_INC, + value->val, + 2); +} + +#if ((!defined(IN_PORTCONTROL_MINI)) || (!defined(IN_MISC_MINI))) +sw_error_t +hppe_mc_mtu_ctrl_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mc_mtu_ctrl_tbl_u *value) +{ + if (index >= MC_MTU_CTRL_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + MC_MTU_CTRL_TBL_ADDRESS + \ + index * MC_MTU_CTRL_TBL_INC, + &value->val); +} + +sw_error_t +hppe_mc_mtu_ctrl_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mc_mtu_ctrl_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L2_BASE_ADDR + MC_MTU_CTRL_TBL_ADDRESS + \ + index * MC_MTU_CTRL_TBL_INC, + value->val); +} +#endif + +sw_error_t +hppe_tdm_ctrl_get( + a_uint32_t dev_id, + union tdm_ctrl_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_PRX_CSR_BASE_ADDR + TDM_CTRL_ADDRESS, + &value->val); +} + +sw_error_t +hppe_tdm_ctrl_set( + a_uint32_t dev_id, + union tdm_ctrl_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_PRX_CSR_BASE_ADDR + TDM_CTRL_ADDRESS, + value->val); +} +#ifndef IN_PORTCONTROL_MINI +sw_error_t +hppe_rx_fifo_cfg_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_fifo_cfg_u *value) +{ + if (index >= RX_FIFO_CFG_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_PRX_CSR_BASE_ADDR + RX_FIFO_CFG_ADDRESS + \ + index * RX_FIFO_CFG_INC, + &value->val); +} + +sw_error_t +hppe_rx_fifo_cfg_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_fifo_cfg_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_PRX_CSR_BASE_ADDR + RX_FIFO_CFG_ADDRESS + \ + index * RX_FIFO_CFG_INC, + value->val); +} + +sw_error_t +hppe_tdm_cfg_get( + a_uint32_t dev_id, + a_uint32_t index, + union tdm_cfg_u *value) +{ + if (index >= TDM_CFG_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_PRX_CSR_BASE_ADDR + TDM_CFG_ADDRESS + \ + index * TDM_CFG_INC, + &value->val); +} +#endif + +sw_error_t +hppe_tdm_cfg_set( + a_uint32_t dev_id, + a_uint32_t index, + union tdm_cfg_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_PRX_CSR_BASE_ADDR + TDM_CFG_ADDRESS + \ + index * TDM_CFG_INC, + value->val); +} + +sw_error_t +hppe_drop_stat_get( + a_uint32_t dev_id, + a_uint32_t index, + union drop_stat_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + NSS_PRX_CSR_BASE_ADDR + DROP_STAT_ADDRESS + \ + index * DROP_STAT_INC, + value->val, + 3); +} + +#ifndef IN_MISC_MINI +sw_error_t +hppe_drop_stat_set( + a_uint32_t dev_id, + a_uint32_t index, + union drop_stat_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + NSS_PRX_CSR_BASE_ADDR + DROP_STAT_ADDRESS + \ + index * DROP_STAT_INC, + value->val, + 3); +} +#endif + +#ifndef IN_PORTCONTROL_MINI +sw_error_t +hppe_mac_enable_txmac_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.txmac_en; + return ret; +} + +sw_error_t +hppe_mac_enable_txmac_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_enable_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.txmac_en = value; + ret = hppe_mac_enable_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_enable_rxmac_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.rxmac_en; + return ret; +} + +sw_error_t +hppe_mac_enable_rxmac_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_enable_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rxmac_en = value; + ret = hppe_mac_enable_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_enable_tx_flow_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_flow_en; + return ret; +} + +sw_error_t +hppe_mac_enable_tx_flow_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_enable_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_flow_en = value; + ret = hppe_mac_enable_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_enable_rx_flow_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.rx_flow_en; + return ret; +} + +sw_error_t +hppe_mac_enable_rx_flow_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_enable_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_flow_en = value; + ret = hppe_mac_enable_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_enable_duplex_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.duplex; + return ret; +} + +sw_error_t +hppe_mac_enable_duplex_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_enable_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.duplex = value; + ret = hppe_mac_enable_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_speed_mac_speed_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_speed_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_speed_get(dev_id, index, ®_val); + *value = reg_val.bf.mac_speed; + return ret; +} + +sw_error_t +hppe_mac_speed_mac_speed_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_speed_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_speed_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_speed = value; + ret = hppe_mac_speed_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_gol_mac_addr0_mac_addr_byte4_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union gol_mac_addr0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_gol_mac_addr0_get(dev_id, index, ®_val); + *value = reg_val.bf.mac_addr_byte4; + return ret; +} + +sw_error_t +hppe_gol_mac_addr0_mac_addr_byte4_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union gol_mac_addr0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_gol_mac_addr0_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_addr_byte4 = value; + ret = hppe_gol_mac_addr0_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_gol_mac_addr0_mac_addr_byte5_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union gol_mac_addr0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_gol_mac_addr0_get(dev_id, index, ®_val); + *value = reg_val.bf.mac_addr_byte5; + return ret; +} + +sw_error_t +hppe_gol_mac_addr0_mac_addr_byte5_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union gol_mac_addr0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_gol_mac_addr0_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_addr_byte5 = value; + ret = hppe_gol_mac_addr0_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_gol_mac_addr1_mac_addr_byte1_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union gol_mac_addr1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_gol_mac_addr1_get(dev_id, index, ®_val); + *value = reg_val.bf.mac_addr_byte1; + return ret; +} + +sw_error_t +hppe_gol_mac_addr1_mac_addr_byte1_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union gol_mac_addr1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_gol_mac_addr1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_addr_byte1 = value; + ret = hppe_gol_mac_addr1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_gol_mac_addr1_mac_addr_byte2_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union gol_mac_addr1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_gol_mac_addr1_get(dev_id, index, ®_val); + *value = reg_val.bf.mac_addr_byte2; + return ret; +} + +sw_error_t +hppe_gol_mac_addr1_mac_addr_byte2_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union gol_mac_addr1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_gol_mac_addr1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_addr_byte2 = value; + ret = hppe_gol_mac_addr1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_gol_mac_addr1_mac_addr_byte0_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union gol_mac_addr1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_gol_mac_addr1_get(dev_id, index, ®_val); + *value = reg_val.bf.mac_addr_byte0; + return ret; +} + +sw_error_t +hppe_gol_mac_addr1_mac_addr_byte0_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union gol_mac_addr1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_gol_mac_addr1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_addr_byte0 = value; + ret = hppe_gol_mac_addr1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_gol_mac_addr1_mac_addr_byte3_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union gol_mac_addr1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_gol_mac_addr1_get(dev_id, index, ®_val); + *value = reg_val.bf.mac_addr_byte3; + return ret; +} + +sw_error_t +hppe_gol_mac_addr1_mac_addr_byte3_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union gol_mac_addr1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_gol_mac_addr1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_addr_byte3 = value; + ret = hppe_gol_mac_addr1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_ctrl0_amaxc_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_ctrl0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl0_get(dev_id, index, ®_val); + *value = reg_val.bf.amaxc_en; + return ret; +} + +sw_error_t +hppe_mac_ctrl0_amaxc_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_ctrl0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl0_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.amaxc_en = value; + ret = hppe_mac_ctrl0_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_ctrl0_ipgt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_ctrl0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl0_get(dev_id, index, ®_val); + *value = reg_val.bf.ipgt; + return ret; +} + +sw_error_t +hppe_mac_ctrl0_ipgt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_ctrl0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl0_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipgt = value; + ret = hppe_mac_ctrl0_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_ctrl0_nobo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_ctrl0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl0_get(dev_id, index, ®_val); + *value = reg_val.bf.nobo; + return ret; +} + +sw_error_t +hppe_mac_ctrl0_nobo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_ctrl0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl0_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.nobo = value; + ret = hppe_mac_ctrl0_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_ctrl0_half_thdf_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_ctrl0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl0_get(dev_id, index, ®_val); + *value = reg_val.bf.half_thdf_ctrl; + return ret; +} + +sw_error_t +hppe_mac_ctrl0_half_thdf_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_ctrl0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl0_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.half_thdf_ctrl = value; + ret = hppe_mac_ctrl0_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_ctrl0_hugen_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_ctrl0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl0_get(dev_id, index, ®_val); + *value = reg_val.bf.hugen; + return ret; +} + +sw_error_t +hppe_mac_ctrl0_hugen_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_ctrl0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl0_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.hugen = value; + ret = hppe_mac_ctrl0_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_ctrl0_bpnb_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_ctrl0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl0_get(dev_id, index, ®_val); + *value = reg_val.bf.bpnb; + return ret; +} + +sw_error_t +hppe_mac_ctrl0_bpnb_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_ctrl0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl0_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.bpnb = value; + ret = hppe_mac_ctrl0_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_ctrl0_flchk_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_ctrl0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl0_get(dev_id, index, ®_val); + *value = reg_val.bf.flchk; + return ret; +} + +sw_error_t +hppe_mac_ctrl0_flchk_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_ctrl0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl0_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flchk = value; + ret = hppe_mac_ctrl0_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_ctrl0_ipgr2_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_ctrl0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl0_get(dev_id, index, ®_val); + *value = reg_val.bf.ipgr2; + return ret; +} + +sw_error_t +hppe_mac_ctrl0_ipgr2_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_ctrl0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl0_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipgr2 = value; + ret = hppe_mac_ctrl0_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_ctrl0_drbnib_rxok_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_ctrl0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl0_get(dev_id, index, ®_val); + *value = reg_val.bf.drbnib_rxok_en; + return ret; +} + +sw_error_t +hppe_mac_ctrl0_drbnib_rxok_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_ctrl0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl0_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.drbnib_rxok_en = value; + ret = hppe_mac_ctrl0_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_ctrl0_huge_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_ctrl0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl0_get(dev_id, index, ®_val); + *value = reg_val.bf.huge; + return ret; +} + +sw_error_t +hppe_mac_ctrl0_huge_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_ctrl0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl0_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.huge = value; + ret = hppe_mac_ctrl0_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_ctrl0_abebe_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_ctrl0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl0_get(dev_id, index, ®_val); + *value = reg_val.bf.abebe; + return ret; +} + +sw_error_t +hppe_mac_ctrl0_abebe_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_ctrl0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl0_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.abebe = value; + ret = hppe_mac_ctrl0_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_ctrl1_povr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.povr; + return ret; +} + +sw_error_t +hppe_mac_ctrl1_povr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.povr = value; + ret = hppe_mac_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_ctrl1_simr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.simr; + return ret; +} + +sw_error_t +hppe_mac_ctrl1_simr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.simr = value; + ret = hppe_mac_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_ctrl1_jam_ipg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.jam_ipg; + return ret; +} + +sw_error_t +hppe_mac_ctrl1_jam_ipg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.jam_ipg = value; + ret = hppe_mac_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_ctrl1_lcol_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.lcol; + return ret; +} + +sw_error_t +hppe_mac_ctrl1_lcol_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.lcol = value; + ret = hppe_mac_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_ctrl1_tctl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.tctl; + return ret; +} + +sw_error_t +hppe_mac_ctrl1_tctl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tctl = value; + ret = hppe_mac_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_ctrl1_retry_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.retry; + return ret; +} + +sw_error_t +hppe_mac_ctrl1_retry_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.retry = value; + ret = hppe_mac_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_ctrl1_prlen_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.prlen; + return ret; +} + +sw_error_t +hppe_mac_ctrl1_prlen_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.prlen = value; + ret = hppe_mac_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_ctrl1_ppad_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.ppad; + return ret; +} + +sw_error_t +hppe_mac_ctrl1_ppad_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ppad = value; + ret = hppe_mac_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_ctrl1_long_jam_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.long_jam_en; + return ret; +} + +sw_error_t +hppe_mac_ctrl1_long_jam_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.long_jam_en = value; + ret = hppe_mac_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_ctrl1_phug_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.phug; + return ret; +} + +sw_error_t +hppe_mac_ctrl1_phug_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.phug = value; + ret = hppe_mac_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_ctrl1_sstct_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.sstct; + return ret; +} + +sw_error_t +hppe_mac_ctrl1_sstct_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.sstct = value; + ret = hppe_mac_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_ctrl1_mbof_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.mbof; + return ret; +} + +sw_error_t +hppe_mac_ctrl1_mbof_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mbof = value; + ret = hppe_mac_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_ctrl1_tpause_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.tpause; + return ret; +} + +sw_error_t +hppe_mac_ctrl1_tpause_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tpause = value; + ret = hppe_mac_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_ctrl2_ipg_dec_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_ctrl2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl2_get(dev_id, index, ®_val); + *value = reg_val.bf.ipg_dec_en; + return ret; +} + +sw_error_t +hppe_mac_ctrl2_ipg_dec_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_ctrl2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl2_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipg_dec_en = value; + ret = hppe_mac_ctrl2_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_ctrl2_mac_rsv_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_ctrl2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl2_get(dev_id, index, ®_val); + *value = reg_val.bf.mac_rsv; + return ret; +} + +sw_error_t +hppe_mac_ctrl2_mac_rsv_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_ctrl2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl2_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_rsv = value; + ret = hppe_mac_ctrl2_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_ctrl2_mac_tx_thd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_ctrl2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl2_get(dev_id, index, ®_val); + *value = reg_val.bf.mac_tx_thd; + return ret; +} +#endif +sw_error_t +hppe_mac_ctrl2_mac_tx_thd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_ctrl2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl2_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_tx_thd = value; + ret = hppe_mac_ctrl2_set(dev_id, index, ®_val); + return ret; +} +#ifndef IN_PORTCONTROL_MINI +sw_error_t +hppe_mac_ctrl2_crc_rsv_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_ctrl2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl2_get(dev_id, index, ®_val); + *value = reg_val.bf.crc_rsv_en; + return ret; +} + +sw_error_t +hppe_mac_ctrl2_crc_rsv_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_ctrl2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl2_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.crc_rsv_en = value; + ret = hppe_mac_ctrl2_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_ctrl2_crs_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_ctrl2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl2_get(dev_id, index, ®_val); + *value = reg_val.bf.crs_sel; + return ret; +} +#endif +sw_error_t +hppe_mac_ctrl2_crs_sel_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_ctrl2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl2_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.crs_sel = value; + ret = hppe_mac_ctrl2_set(dev_id, index, ®_val); + return ret; +} +#ifndef IN_PORTCONTROL_MINI +sw_error_t +hppe_mac_ctrl2_ipg_dec_len_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_ctrl2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl2_get(dev_id, index, ®_val); + *value = reg_val.bf.ipg_dec_len; + return ret; +} + +sw_error_t +hppe_mac_ctrl2_ipg_dec_len_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_ctrl2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl2_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipg_dec_len = value; + ret = hppe_mac_ctrl2_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_ctrl2_maxfr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_ctrl2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl2_get(dev_id, index, ®_val); + *value = reg_val.bf.maxfr; + return ret; +} +#endif +sw_error_t +hppe_mac_ctrl2_maxfr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_ctrl2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl2_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.maxfr = value; + ret = hppe_mac_ctrl2_set(dev_id, index, ®_val); + return ret; +} +#ifndef IN_PORTCONTROL_MINI + +sw_error_t +hppe_mac_ctrl2_mac_lpi_tx_idle_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_ctrl2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl2_get(dev_id, index, ®_val); + *value = reg_val.bf.mac_lpi_tx_idle; + return ret; +} + +sw_error_t +hppe_mac_ctrl2_mac_lpi_tx_idle_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_ctrl2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl2_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_lpi_tx_idle = value; + ret = hppe_mac_ctrl2_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_ctrl2_mac_loop_back_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_ctrl2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl2_get(dev_id, index, ®_val); + *value = reg_val.bf.mac_loop_back; + return ret; +} + +sw_error_t +hppe_mac_ctrl2_mac_loop_back_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_ctrl2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl2_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_loop_back = value; + ret = hppe_mac_ctrl2_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_ctrl2_test_pause_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_ctrl2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl2_get(dev_id, index, ®_val); + *value = reg_val.bf.test_pause; + return ret; +} + +sw_error_t +hppe_mac_ctrl2_test_pause_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_ctrl2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_ctrl2_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.test_pause = value; + ret = hppe_mac_ctrl2_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_dbg_ctrl_edxsdfr_transmit_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_dbg_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_dbg_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.edxsdfr_transmit_en; + return ret; +} + +sw_error_t +hppe_mac_dbg_ctrl_edxsdfr_transmit_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_dbg_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_dbg_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.edxsdfr_transmit_en = value; + ret = hppe_mac_dbg_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_dbg_ctrl_hihg_ipg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_dbg_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_dbg_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.hihg_ipg; + return ret; +} +#endif +sw_error_t +hppe_mac_dbg_ctrl_hihg_ipg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_dbg_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_dbg_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.hihg_ipg = value; + ret = hppe_mac_dbg_ctrl_set(dev_id, index, ®_val); + return ret; +} +#ifndef IN_PORTCONTROL_MINI +sw_error_t +hppe_mac_dbg_ctrl_mac_ipg_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_dbg_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_dbg_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.mac_ipg_ctrl; + return ret; +} + +sw_error_t +hppe_mac_dbg_ctrl_mac_ipg_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_dbg_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_dbg_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_ipg_ctrl = value; + ret = hppe_mac_dbg_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_dbg_ctrl_mac_len_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_dbg_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_dbg_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.mac_len_ctrl; + return ret; +} + +sw_error_t +hppe_mac_dbg_ctrl_mac_len_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_dbg_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_dbg_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_len_ctrl = value; + ret = hppe_mac_dbg_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_dbg_ctrl_ipgr1_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_dbg_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_dbg_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.ipgr1; + return ret; +} + +sw_error_t +hppe_mac_dbg_ctrl_ipgr1_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_dbg_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_dbg_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipgr1 = value; + ret = hppe_mac_dbg_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_dbg_addr_mac_debug_addr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_dbg_addr_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_dbg_addr_get(dev_id, index, ®_val); + *value = reg_val.bf.mac_debug_addr; + return ret; +} + +sw_error_t +hppe_mac_dbg_addr_mac_debug_addr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_dbg_addr_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_dbg_addr_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_debug_addr = value; + ret = hppe_mac_dbg_addr_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_dbg_data_mac_debug_data_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_dbg_data_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_dbg_data_get(dev_id, index, ®_val); + *value = reg_val.bf.mac_debug_data; + return ret; +} + +sw_error_t +hppe_mac_dbg_data_mac_debug_data_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} +#endif +sw_error_t +hppe_mac_jumbo_size_mac_jumbo_size_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_jumbo_size_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_jumbo_size_get(dev_id, index, ®_val); + *value = reg_val.bf.mac_jumbo_size; + return ret; +} + +sw_error_t +hppe_mac_jumbo_size_mac_jumbo_size_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_jumbo_size_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_jumbo_size_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_jumbo_size = value; + ret = hppe_mac_jumbo_size_set(dev_id, index, ®_val); + return ret; +} +#ifndef IN_PORTCONTROL_MINI +sw_error_t +hppe_mru_mtu_ctrl_tbl_mtu_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.mtu_cmd; + return ret; +} + +sw_error_t +hppe_mru_mtu_ctrl_tbl_mtu_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mtu_cmd = value; + ret = hppe_mru_mtu_ctrl_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mru_mtu_ctrl_tbl_rx_cnt_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.rx_cnt_en; + return ret; +} + +sw_error_t +hppe_mru_mtu_ctrl_tbl_rx_cnt_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_cnt_en = value; + ret = hppe_mru_mtu_ctrl_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mru_mtu_ctrl_tbl_tx_cnt_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_cnt_en; + return ret; +} + +sw_error_t +hppe_mru_mtu_ctrl_tbl_tx_cnt_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_cnt_en = value; + ret = hppe_mru_mtu_ctrl_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mru_mtu_ctrl_tbl_mru_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.mru_cmd; + return ret; +} + +sw_error_t +hppe_mru_mtu_ctrl_tbl_mru_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mru_cmd = value; + ret = hppe_mru_mtu_ctrl_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mru_mtu_ctrl_tbl_mru_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.mru; + return ret; +} + +sw_error_t +hppe_mru_mtu_ctrl_tbl_mru_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mru = value; + ret = hppe_mru_mtu_ctrl_tbl_set(dev_id, index, ®_val); + return ret; +} +#endif + +sw_error_t +hppe_mru_mtu_ctrl_tbl_src_profile_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.src_profile; + return ret; +} + +sw_error_t +hppe_mru_mtu_ctrl_tbl_src_profile_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mru_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mru_mtu_ctrl_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.src_profile = value; + ret = hppe_mru_mtu_ctrl_tbl_set(dev_id, index, ®_val); + return ret; +} + +#ifndef IN_PORTCONTROL_MINI +sw_error_t +hppe_mc_mtu_ctrl_tbl_mtu_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mc_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mc_mtu_ctrl_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.mtu_cmd; + return ret; +} + +sw_error_t +hppe_mc_mtu_ctrl_tbl_mtu_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mc_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mc_mtu_ctrl_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mtu_cmd = value; + ret = hppe_mc_mtu_ctrl_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mc_mtu_ctrl_tbl_tx_cnt_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mc_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mc_mtu_ctrl_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_cnt_en; + return ret; +} + +sw_error_t +hppe_mc_mtu_ctrl_tbl_tx_cnt_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mc_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mc_mtu_ctrl_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_cnt_en = value; + ret = hppe_mc_mtu_ctrl_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mc_mtu_ctrl_tbl_mtu_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mc_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mc_mtu_ctrl_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.mtu; + return ret; +} + +sw_error_t +hppe_mc_mtu_ctrl_tbl_mtu_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mc_mtu_ctrl_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mc_mtu_ctrl_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mtu = value; + ret = hppe_mc_mtu_ctrl_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_tdm_ctrl_tdm_en_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union tdm_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tdm_ctrl_get(dev_id, ®_val); + *value = reg_val.bf.tdm_en; + return ret; +} + +sw_error_t +hppe_tdm_ctrl_tdm_en_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union tdm_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tdm_ctrl_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tdm_en = value; + ret = hppe_tdm_ctrl_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_tdm_ctrl_tdm_offset_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union tdm_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tdm_ctrl_get(dev_id, ®_val); + *value = reg_val.bf.tdm_offset; + return ret; +} + +sw_error_t +hppe_tdm_ctrl_tdm_offset_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union tdm_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tdm_ctrl_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tdm_offset = value; + ret = hppe_tdm_ctrl_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_tdm_ctrl_tdm_depth_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union tdm_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tdm_ctrl_get(dev_id, ®_val); + *value = reg_val.bf.tdm_depth; + return ret; +} + +sw_error_t +hppe_tdm_ctrl_tdm_depth_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union tdm_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tdm_ctrl_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tdm_depth = value; + ret = hppe_tdm_ctrl_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_rx_fifo_cfg_rx_fifo_thres_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_fifo_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_fifo_cfg_get(dev_id, index, ®_val); + *value = reg_val.bf.rx_fifo_thres; + return ret; +} + +sw_error_t +hppe_rx_fifo_cfg_rx_fifo_thres_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union rx_fifo_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_fifo_cfg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_fifo_thres = value; + ret = hppe_rx_fifo_cfg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_tdm_cfg_port_num_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tdm_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tdm_cfg_get(dev_id, index, ®_val); + *value = reg_val.bf.port_num; + return ret; +} + +sw_error_t +hppe_tdm_cfg_port_num_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union tdm_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tdm_cfg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_num = value; + ret = hppe_tdm_cfg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_tdm_cfg_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tdm_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tdm_cfg_get(dev_id, index, ®_val); + *value = reg_val.bf.valid; + return ret; +} + +sw_error_t +hppe_tdm_cfg_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union tdm_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tdm_cfg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.valid = value; + ret = hppe_tdm_cfg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_tdm_cfg_dir_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tdm_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tdm_cfg_get(dev_id, index, ®_val); + *value = reg_val.bf.dir; + return ret; +} + +sw_error_t +hppe_tdm_cfg_dir_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union tdm_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tdm_cfg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.dir = value; + ret = hppe_tdm_cfg_set(dev_id, index, ®_val); + return ret; +} +#endif +sw_error_t +hppe_port_in_forward_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_in_forward_u *value) +{ + if (index >= PORT_IN_FORWARD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + PORT_IN_FORWARD_ADDRESS + \ + index * PORT_IN_FORWARD_INC, + &value->val); +} + +sw_error_t +hppe_port_in_forward_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_in_forward_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L2_BASE_ADDR + PORT_IN_FORWARD_ADDRESS + \ + index * PORT_IN_FORWARD_INC, + value->val); +} +#ifndef IN_PORTCONTROL_MINI +sw_error_t +hppe_port_in_forward_source_filtering_bypass_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_in_forward_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_in_forward_get(dev_id, index, ®_val); + *value = reg_val.bf.source_filtering_bypass; + return ret; +} + +sw_error_t +hppe_port_in_forward_source_filtering_bypass_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_in_forward_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_in_forward_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.source_filtering_bypass = value; + ret = hppe_port_in_forward_set(dev_id, index, ®_val); + return ret; +} +#endif + +#ifndef IN_MISC_MINI +sw_error_t +hppe_drop_stat_bytes_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union drop_stat_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_drop_stat_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.bytes_1 << 32 | \ + reg_val.bf.bytes_0; + return ret; +} + +sw_error_t +hppe_drop_stat_bytes_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union drop_stat_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_drop_stat_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.bytes_1 = value >> 32; + reg_val.bf.bytes_0 = value & (((a_uint64_t)1<<32)-1); + ret = hppe_drop_stat_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_drop_stat_pkts_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union drop_stat_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_drop_stat_get(dev_id, index, ®_val); + *value = reg_val.bf.pkts; + return ret; +} + +sw_error_t +hppe_drop_stat_pkts_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union drop_stat_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_drop_stat_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pkts = value; + ret = hppe_drop_stat_set(dev_id, index, ®_val); + return ret; +} +#endif + +#if ((!defined(IN_PORTCONTROL_MINI)) || (!defined(IN_MISC_MINI))) +sw_error_t +hppe_port_tx_counter_tbl_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_tx_counter_tbl_reg_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + NSS_PTX_CSR_BASE_ADDR + PORT_TX_COUNTER_TBL_REG_ADDRESS + \ + index * PORT_TX_COUNTER_TBL_REG_INC, + value->val, + 3); +} + +sw_error_t +hppe_port_tx_counter_tbl_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_tx_counter_tbl_reg_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + NSS_PTX_CSR_BASE_ADDR + PORT_TX_COUNTER_TBL_REG_ADDRESS + \ + index * PORT_TX_COUNTER_TBL_REG_INC, + value->val, + 3); +} + +sw_error_t +hppe_vp_tx_counter_tbl_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + union vp_tx_counter_tbl_reg_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + NSS_PTX_CSR_BASE_ADDR + VP_TX_COUNTER_TBL_REG_ADDRESS + \ + index * VP_TX_COUNTER_TBL_REG_INC, + value->val, + 3); +} + +sw_error_t +hppe_vp_tx_counter_tbl_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + union vp_tx_counter_tbl_reg_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + NSS_PTX_CSR_BASE_ADDR + VP_TX_COUNTER_TBL_REG_ADDRESS + \ + index * VP_TX_COUNTER_TBL_REG_INC, + value->val, + 3); +} + +sw_error_t +hppe_epe_dbg_in_cnt_reg_get( + a_uint32_t dev_id, + union epe_dbg_in_cnt_reg_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_PTX_CSR_BASE_ADDR + EPE_DBG_IN_CNT_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_epe_dbg_in_cnt_reg_set( + a_uint32_t dev_id, + union epe_dbg_in_cnt_reg_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_PTX_CSR_BASE_ADDR + EPE_DBG_IN_CNT_REG_ADDRESS, + value->val); +} + +sw_error_t +hppe_epe_dbg_out_cnt_reg_set( + a_uint32_t dev_id, + union epe_dbg_out_cnt_reg_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_PTX_CSR_BASE_ADDR + EPE_DBG_OUT_CNT_REG_ADDRESS, + value->val); +} +#endif + +#ifndef IN_PORTCONTROL_MINI +sw_error_t +hppe_epe_dbg_out_cnt_reg_get( + a_uint32_t dev_id, + union epe_dbg_out_cnt_reg_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_PTX_CSR_BASE_ADDR + EPE_DBG_OUT_CNT_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_port_tx_counter_tbl_reg_tx_bytes_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union port_tx_counter_tbl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_tx_counter_tbl_reg_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.tx_bytes_1 << 32 | \ + reg_val.bf.tx_bytes_0; + return ret; +} + +sw_error_t +hppe_port_tx_counter_tbl_reg_tx_bytes_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union port_tx_counter_tbl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_tx_counter_tbl_reg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_bytes_1 = value >> 32; + reg_val.bf.tx_bytes_0 = value & (((a_uint64_t)1<<32)-1); + ret = hppe_port_tx_counter_tbl_reg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_tx_counter_tbl_reg_tx_packets_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_tx_counter_tbl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_tx_counter_tbl_reg_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_packets; + return ret; +} + +sw_error_t +hppe_port_tx_counter_tbl_reg_tx_packets_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_tx_counter_tbl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_tx_counter_tbl_reg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_packets = value; + ret = hppe_port_tx_counter_tbl_reg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vp_tx_counter_tbl_reg_tx_bytes_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union vp_tx_counter_tbl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vp_tx_counter_tbl_reg_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.tx_bytes_1 << 32 | \ + reg_val.bf.tx_bytes_0; + return ret; +} + +sw_error_t +hppe_vp_tx_counter_tbl_reg_tx_bytes_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union vp_tx_counter_tbl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vp_tx_counter_tbl_reg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_bytes_1 = value >> 32; + reg_val.bf.tx_bytes_0 = value & (((a_uint64_t)1<<32)-1); + ret = hppe_vp_tx_counter_tbl_reg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vp_tx_counter_tbl_reg_tx_packets_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vp_tx_counter_tbl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vp_tx_counter_tbl_reg_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_packets; + return ret; +} + +sw_error_t +hppe_vp_tx_counter_tbl_reg_tx_packets_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vp_tx_counter_tbl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vp_tx_counter_tbl_reg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_packets = value; + ret = hppe_vp_tx_counter_tbl_reg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_epe_dbg_in_cnt_reg_counter_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union epe_dbg_in_cnt_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_epe_dbg_in_cnt_reg_get(dev_id, ®_val); + *value = reg_val.bf.counter; + return ret; +} + +sw_error_t +hppe_epe_dbg_in_cnt_reg_counter_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union epe_dbg_in_cnt_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_epe_dbg_in_cnt_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.counter = value; + ret = hppe_epe_dbg_in_cnt_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_epe_dbg_out_cnt_reg_counter_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union epe_dbg_out_cnt_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_epe_dbg_out_cnt_reg_get(dev_id, ®_val); + *value = reg_val.bf.counter; + return ret; +} + +sw_error_t +hppe_epe_dbg_out_cnt_reg_counter_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union epe_dbg_out_cnt_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_epe_dbg_out_cnt_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.counter = value; + ret = hppe_epe_dbg_out_cnt_reg_set(dev_id, ®_val); + return ret; +} +#endif + +sw_error_t +hppe_lpi_enable_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpi_enable_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_LPI_BASE_ADDR + LPI_ENABLE_ADDRESS + \ + index * LPI_ENABLE_INC, + &value->val); +} + +sw_error_t +hppe_lpi_enable_set( + a_uint32_t dev_id, + a_uint32_t index, + union lpi_enable_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_LPI_BASE_ADDR + LPI_ENABLE_ADDRESS + \ + index * LPI_ENABLE_INC, + value->val); +} + +sw_error_t +hppe_lpi_timer_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpi_port_timer_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_LPI_BASE_ADDR + LPI_PORT_TIMER_ADDRESS + \ + index * LPI_PORT_TIMER_INC, + &value->val); +} + +sw_error_t +hppe_lpi_timer_set( + a_uint32_t dev_id, + a_uint32_t index, + union lpi_port_timer_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_LPI_BASE_ADDR + LPI_PORT_TIMER_ADDRESS + \ + index * LPI_PORT_TIMER_INC, + value->val); +} +#ifndef IN_PORTCONTROL_MINI +sw_error_t +hppe_lpi_dbg_addr_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpi_dbg_addr_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_LPI_BASE_ADDR + LPI_DBG_ADDR_ADDRESS + \ + index * LPI_DBG_ADDR_INC, + &value->val); +} + +sw_error_t +hppe_lpi_dbg_addr_set( + a_uint32_t dev_id, + a_uint32_t index, + union lpi_dbg_addr_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_LPI_BASE_ADDR + LPI_DBG_ADDR_ADDRESS + \ + index * LPI_DBG_ADDR_INC, + value->val); +} + +sw_error_t +hppe_lpi_dbg_data_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpi_dbg_data_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_LPI_BASE_ADDR + LPI_DBG_DATA_ADDRESS + \ + index * LPI_DBG_DATA_INC, + &value->val); +} + +sw_error_t +hppe_lpi_dbg_data_set( + a_uint32_t dev_id, + a_uint32_t index, + union lpi_dbg_addr_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_LPI_BASE_ADDR + LPI_DBG_DATA_ADDRESS + \ + index * LPI_DBG_DATA_INC, + value->val); +} +sw_error_t +hppe_lpi_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + union lpi_cnt_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_LPI_BASE_ADDR + LPI_CNT_ADDRESS + \ + index * LPI_CNT_INC, + &value->val); +} + +sw_error_t +hppe_lpi_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + union lpi_cnt_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_LPI_BASE_ADDR + LPI_CNT_ADDRESS + \ + index * LPI_CNT_INC, + value->val); +} +#endif + +#ifndef IN_MISC_MINI +sw_error_t +hppe_drop_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + union drop_cnt_u *value) +{ + if (index >= DROP_CNT_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_PRX_CSR_BASE_ADDR + DROP_CNT_ADDRESS + \ + index * DROP_CNT_INC, + &value->val); +} + +sw_error_t +hppe_drop_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + union drop_cnt_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_PRX_CSR_BASE_ADDR + DROP_CNT_ADDRESS + \ + index * DROP_CNT_INC, + value->val); +} + +sw_error_t +hppe_drop_cnt_drop_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union drop_cnt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_drop_cnt_get(dev_id, index, ®_val); + *value = reg_val.bf.drop_cnt; + return ret; +} + +sw_error_t +hppe_drop_cnt_drop_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union drop_cnt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_drop_cnt_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.drop_cnt = value; + ret = hppe_drop_cnt_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipr_pkt_num_tbl_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + union ipr_pkt_num_tbl_reg_u *value) +{ + if (index >= IPR_PKT_NUM_TBL_REG_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPR_CSR_BASE_ADDR + IPR_PKT_NUM_TBL_REG_ADDRESS + \ + index * IPR_PKT_NUM_TBL_REG_INC, + &value->val); +} + +sw_error_t +hppe_ipr_pkt_num_tbl_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + union ipr_pkt_num_tbl_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPR_CSR_BASE_ADDR + IPR_PKT_NUM_TBL_REG_ADDRESS + \ + index * IPR_PKT_NUM_TBL_REG_INC, + value->val); +} + +sw_error_t +hppe_ipr_byte_low_reg_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + union ipr_byte_low_reg_reg_u *value) +{ + if (index >= IPR_BYTE_LOW_REG_REG_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPR_CSR_BASE_ADDR + IPR_BYTE_LOW_REG_REG_ADDRESS + \ + index * IPR_BYTE_LOW_REG_REG_INC, + &value->val); +} + +sw_error_t +hppe_ipr_byte_low_reg_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + union ipr_byte_low_reg_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPR_CSR_BASE_ADDR + IPR_BYTE_LOW_REG_REG_ADDRESS + \ + index * IPR_BYTE_LOW_REG_REG_INC, + value->val); +} + +sw_error_t +hppe_ipr_byte_high_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + union ipr_byte_high_reg_u *value) +{ + if (index >= IPR_BYTE_HIGH_REG_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPR_CSR_BASE_ADDR + IPR_BYTE_HIGH_REG_ADDRESS + \ + index * IPR_BYTE_HIGH_REG_INC, + &value->val); +} + +sw_error_t +hppe_ipr_byte_high_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + union ipr_byte_high_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPR_CSR_BASE_ADDR + IPR_BYTE_HIGH_REG_ADDRESS + \ + index * IPR_BYTE_HIGH_REG_INC, + value->val); +} + +sw_error_t +hppe_ipr_pkt_num_tbl_reg_packets_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipr_pkt_num_tbl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipr_pkt_num_tbl_reg_get(dev_id, index, ®_val); + *value = reg_val.bf.packets; + return ret; +} + +sw_error_t +hppe_ipr_pkt_num_tbl_reg_packets_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipr_pkt_num_tbl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipr_pkt_num_tbl_reg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.packets = value; + ret = hppe_ipr_pkt_num_tbl_reg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipr_byte_low_reg_reg_bytes_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipr_byte_low_reg_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipr_byte_low_reg_reg_get(dev_id, index, ®_val); + *value = reg_val.bf.bytes; + return ret; +} + +sw_error_t +hppe_ipr_byte_low_reg_reg_bytes_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipr_byte_low_reg_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipr_byte_low_reg_reg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.bytes = value; + ret = hppe_ipr_byte_low_reg_reg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ipr_byte_high_reg_bytes_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ipr_byte_high_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipr_byte_high_reg_get(dev_id, index, ®_val); + *value = reg_val.bf.bytes; + return ret; +} + +sw_error_t +hppe_ipr_byte_high_reg_bytes_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ipr_byte_high_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipr_byte_high_reg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.bytes = value; + ret = hppe_ipr_byte_high_reg_set(dev_id, index, ®_val); + return ret; +} +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_portvlan.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_portvlan.c new file mode 100755 index 000000000..4b6ff8281 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_portvlan.c @@ -0,0 +1,4057 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hppe_reg_access.h" +#include "hppe_portvlan_reg.h" +#include "hppe_portvlan.h" + +sw_error_t +hppe_port_parsing_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_parsing_reg_u *value) +{ + if (index >= PORT_PARSING_REG_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPR_CSR_BASE_ADDR + PORT_PARSING_REG_ADDRESS + \ + index * PORT_PARSING_REG_INC, + &value->val); +} + +sw_error_t +hppe_port_parsing_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_parsing_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPR_CSR_BASE_ADDR + PORT_PARSING_REG_ADDRESS + \ + index * PORT_PARSING_REG_INC, + value->val); +} + +sw_error_t +hppe_vlan_tpid_reg_get( + a_uint32_t dev_id, + union vlan_tpid_reg_u *value) +{ + return hppe_reg_get( + dev_id, + IPR_CSR_BASE_ADDR + VLAN_TPID_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_vlan_tpid_reg_set( + a_uint32_t dev_id, + union vlan_tpid_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPR_CSR_BASE_ADDR + VLAN_TPID_REG_ADDRESS, + value->val); +} + +sw_error_t +hppe_port_parsing_reg_port_role_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_parsing_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_parsing_reg_get(dev_id, index, ®_val); + *value = reg_val.bf.port_role; + return ret; +} + +sw_error_t +hppe_port_parsing_reg_port_role_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_parsing_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_parsing_reg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_role = value; + ret = hppe_port_parsing_reg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vlan_tpid_reg_stag_tpid_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union vlan_tpid_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vlan_tpid_reg_get(dev_id, ®_val); + *value = reg_val.bf.stag_tpid; + return ret; +} + +sw_error_t +hppe_vlan_tpid_reg_stag_tpid_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union vlan_tpid_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vlan_tpid_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.stag_tpid = value; + ret = hppe_vlan_tpid_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_vlan_tpid_reg_ctag_tpid_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union vlan_tpid_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vlan_tpid_reg_get(dev_id, ®_val); + *value = reg_val.bf.ctag_tpid; + return ret; +} + +sw_error_t +hppe_vlan_tpid_reg_ctag_tpid_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union vlan_tpid_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vlan_tpid_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ctag_tpid = value; + ret = hppe_vlan_tpid_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_bridge_config_get( + a_uint32_t dev_id, + union bridge_config_u *value) +{ + return hppe_reg_get( + dev_id, + INGRESS_VLAN_BASE_ADDR + BRIDGE_CONFIG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_bridge_config_set( + a_uint32_t dev_id, + union bridge_config_u *value) +{ + return hppe_reg_set( + dev_id, + INGRESS_VLAN_BASE_ADDR + BRIDGE_CONFIG_ADDRESS, + value->val); +} + +sw_error_t +hppe_port_def_vid_get( + a_uint32_t dev_id, + a_uint32_t port_id, + union port_def_vid_u *value) +{ + return hppe_reg_get( + dev_id, + INGRESS_VLAN_BASE_ADDR + PORT_DEF_VID_ADDRESS + + port_id * PORT_DEF_VID_INC, + &value->val); +} + +sw_error_t +hppe_port_def_vid_set( + a_uint32_t dev_id, + a_uint32_t port_id, + union port_def_vid_u *value) +{ + return hppe_reg_set( + dev_id, + INGRESS_VLAN_BASE_ADDR + PORT_DEF_VID_ADDRESS + + port_id * PORT_DEF_VID_INC, + value->val); +} + +sw_error_t +hppe_port_def_pcp_get( + a_uint32_t dev_id, + a_uint32_t port_id, + union port_def_pcp_u *value) +{ + return hppe_reg_get( + dev_id, + INGRESS_VLAN_BASE_ADDR + PORT_DEF_PCP_ADDRESS + + port_id * PORT_DEF_PCP_INC, + &value->val); +} + +sw_error_t +hppe_port_def_pcp_set( + a_uint32_t dev_id, + a_uint32_t port_id, + union port_def_pcp_u *value) +{ + return hppe_reg_set( + dev_id, + INGRESS_VLAN_BASE_ADDR + PORT_DEF_PCP_ADDRESS + + port_id * PORT_DEF_PCP_INC, + value->val); +} + +sw_error_t +hppe_port_vlan_config_get( + a_uint32_t dev_id, + a_uint32_t port_id, + union port_vlan_config_u *value) +{ + return hppe_reg_get( + dev_id, + INGRESS_VLAN_BASE_ADDR + PORT_VLAN_CONFIG_ADDRESS + + port_id * PORT_VLAN_CONFIG_INC, + &value->val); +} + +sw_error_t +hppe_port_vlan_config_set( + a_uint32_t dev_id, + a_uint32_t port_id, + union port_vlan_config_u *value) +{ + return hppe_reg_set( + dev_id, + INGRESS_VLAN_BASE_ADDR + PORT_VLAN_CONFIG_ADDRESS + + port_id * PORT_VLAN_CONFIG_INC, + value->val); +} + +#ifndef IN_PORTVLAN_MINI +sw_error_t +hppe_iv_dbg_addr_get( + a_uint32_t dev_id, + union iv_dbg_addr_u *value) +{ + return hppe_reg_get( + dev_id, + INGRESS_VLAN_BASE_ADDR + IV_DBG_ADDR_ADDRESS, + &value->val); +} + +sw_error_t +hppe_iv_dbg_addr_set( + a_uint32_t dev_id, + union iv_dbg_addr_u *value) +{ + return hppe_reg_set( + dev_id, + INGRESS_VLAN_BASE_ADDR + IV_DBG_ADDR_ADDRESS, + value->val); +} + +sw_error_t +hppe_iv_dbg_data_get( + a_uint32_t dev_id, + union iv_dbg_data_u *value) +{ + return hppe_reg_get( + dev_id, + INGRESS_VLAN_BASE_ADDR + IV_DBG_DATA_ADDRESS, + &value->val); +} + +sw_error_t +hppe_iv_dbg_data_set( + a_uint32_t dev_id, + union iv_dbg_data_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_eco_reserve_get( + a_uint32_t dev_id, + union eco_reserve_u *value) +{ + return hppe_reg_get( + dev_id, + INGRESS_VLAN_BASE_ADDR + ECO_RESERVE_ADDRESS, + &value->val); +} + +sw_error_t +hppe_eco_reserve_set( + a_uint32_t dev_id, + union eco_reserve_u *value) +{ + return hppe_reg_set( + dev_id, + INGRESS_VLAN_BASE_ADDR + ECO_RESERVE_ADDRESS, + value->val); +} +#endif + +sw_error_t +hppe_xlt_rule_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union xlt_rule_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + INGRESS_VLAN_BASE_ADDR + XLT_RULE_TBL_ADDRESS + \ + index * XLT_RULE_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_xlt_rule_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union xlt_rule_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + INGRESS_VLAN_BASE_ADDR + XLT_RULE_TBL_ADDRESS + \ + index * XLT_RULE_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_xlt_action_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union xlt_action_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + INGRESS_VLAN_BASE_ADDR + XLT_ACTION_TBL_ADDRESS + \ + index * XLT_ACTION_TBL_INC, + value->val, + 2); +} + +sw_error_t +hppe_xlt_action_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union xlt_action_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + INGRESS_VLAN_BASE_ADDR + XLT_ACTION_TBL_ADDRESS + \ + index * XLT_ACTION_TBL_INC, + value->val, + 2); +} + +sw_error_t +hppe_bridge_config_bridge_type_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union bridge_config_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_bridge_config_get(dev_id, ®_val); + *value = reg_val.bf.bridge_type; + return ret; +} + +sw_error_t +hppe_bridge_config_bridge_type_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union bridge_config_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_bridge_config_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.bridge_type = value; + ret = hppe_bridge_config_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_def_vid_port_def_cvid_en_get( + a_uint32_t dev_id, + a_uint32_t port_id, + a_uint32_t *value) +{ + union port_def_vid_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_def_vid_get(dev_id, port_id, ®_val); + *value = reg_val.bf.port_def_cvid_en; + return ret; +} + +sw_error_t +hppe_port_def_vid_port_def_cvid_en_set( + a_uint32_t dev_id, + a_uint32_t port_id, + a_uint32_t value) +{ + union port_def_vid_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_def_vid_get(dev_id, port_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_def_cvid_en = value; + ret = hppe_port_def_vid_set(dev_id, port_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_def_vid_port_def_svid_en_get( + a_uint32_t dev_id, + a_uint32_t port_id, + a_uint32_t *value) +{ + union port_def_vid_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_def_vid_get(dev_id, port_id, ®_val); + *value = reg_val.bf.port_def_svid_en; + return ret; +} + +sw_error_t +hppe_port_def_vid_port_def_svid_en_set( + a_uint32_t dev_id, + a_uint32_t port_id, + a_uint32_t value) +{ + union port_def_vid_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_def_vid_get(dev_id, port_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_def_svid_en = value; + ret = hppe_port_def_vid_set(dev_id, port_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_def_vid_port_def_cvid_get( + a_uint32_t dev_id, + a_uint32_t port_id, + a_uint32_t *value) +{ + union port_def_vid_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_def_vid_get(dev_id, port_id, ®_val); + *value = reg_val.bf.port_def_cvid; + return ret; +} + +sw_error_t +hppe_port_def_vid_port_def_cvid_set( + a_uint32_t dev_id, + a_uint32_t port_id, + a_uint32_t value) +{ + union port_def_vid_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_def_vid_get(dev_id, port_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_def_cvid = value; + ret = hppe_port_def_vid_set(dev_id, port_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_def_vid_port_def_svid_get( + a_uint32_t dev_id, + a_uint32_t port_id, + a_uint32_t *value) +{ + union port_def_vid_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_def_vid_get(dev_id, port_id, ®_val); + *value = reg_val.bf.port_def_svid; + return ret; +} + +sw_error_t +hppe_port_def_vid_port_def_svid_set( + a_uint32_t dev_id, + a_uint32_t port_id, + a_uint32_t value) +{ + union port_def_vid_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_def_vid_get(dev_id, port_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_def_svid = value; + ret = hppe_port_def_vid_set(dev_id, port_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_def_pcp_port_def_sdei_get( + a_uint32_t dev_id, + a_uint32_t port_id, + a_uint32_t *value) +{ + union port_def_pcp_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_def_pcp_get(dev_id, port_id, ®_val); + *value = reg_val.bf.port_def_sdei; + return ret; +} + +sw_error_t +hppe_port_def_pcp_port_def_sdei_set( + a_uint32_t dev_id, + a_uint32_t port_id, + a_uint32_t value) +{ + union port_def_pcp_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_def_pcp_get(dev_id, port_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_def_sdei = value; + ret = hppe_port_def_pcp_set(dev_id, port_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_def_pcp_port_def_spcp_get( + a_uint32_t dev_id, + a_uint32_t port_id, + a_uint32_t *value) +{ + union port_def_pcp_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_def_pcp_get(dev_id, port_id, ®_val); + *value = reg_val.bf.port_def_spcp; + return ret; +} + +sw_error_t +hppe_port_def_pcp_port_def_spcp_set( + a_uint32_t dev_id, + a_uint32_t port_id, + a_uint32_t value) +{ + union port_def_pcp_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_def_pcp_get(dev_id, port_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_def_spcp = value; + ret = hppe_port_def_pcp_set(dev_id, port_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_def_pcp_port_def_cdei_get( + a_uint32_t dev_id, + a_uint32_t port_id, + a_uint32_t *value) +{ + union port_def_pcp_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_def_pcp_get(dev_id, port_id, ®_val); + *value = reg_val.bf.port_def_cdei; + return ret; +} + +sw_error_t +hppe_port_def_pcp_port_def_cdei_set( + a_uint32_t dev_id, + a_uint32_t port_id, + a_uint32_t value) +{ + union port_def_pcp_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_def_pcp_get(dev_id, port_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_def_cdei = value; + ret = hppe_port_def_pcp_set(dev_id, port_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_def_pcp_port_def_cpcp_get( + a_uint32_t dev_id, + a_uint32_t port_id, + a_uint32_t *value) +{ + union port_def_pcp_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_def_pcp_get(dev_id, port_id, ®_val); + *value = reg_val.bf.port_def_cpcp; + return ret; +} + +sw_error_t +hppe_port_def_pcp_port_def_cpcp_set( + a_uint32_t dev_id, + a_uint32_t port_id, + a_uint32_t value) +{ + union port_def_pcp_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_def_pcp_get(dev_id, port_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_def_cpcp = value; + ret = hppe_port_def_pcp_set(dev_id, port_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_vlan_config_port_in_dei_prop_cmd_get( + a_uint32_t dev_id, + a_uint32_t port_id, + a_uint32_t *value) +{ + union port_vlan_config_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_vlan_config_get(dev_id, port_id, ®_val); + *value = reg_val.bf.port_in_dei_prop_cmd; + return ret; +} + +sw_error_t +hppe_port_vlan_config_port_in_dei_prop_cmd_set( + a_uint32_t dev_id, + a_uint32_t port_id, + a_uint32_t value) +{ + union port_vlan_config_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_vlan_config_get(dev_id, port_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_in_dei_prop_cmd = value; + ret = hppe_port_vlan_config_set(dev_id, port_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_vlan_config_port_in_pcp_prop_cmd_get( + a_uint32_t dev_id, + a_uint32_t port_id, + a_uint32_t *value) +{ + union port_vlan_config_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_vlan_config_get(dev_id, port_id, ®_val); + *value = reg_val.bf.port_in_pcp_prop_cmd; + return ret; +} + +sw_error_t +hppe_port_vlan_config_port_in_pcp_prop_cmd_set( + a_uint32_t dev_id, + a_uint32_t port_id, + a_uint32_t value) +{ + union port_vlan_config_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_vlan_config_get(dev_id, port_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_in_pcp_prop_cmd = value; + ret = hppe_port_vlan_config_set(dev_id, port_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_vlan_config_port_untag_fltr_cmd_get( + a_uint32_t dev_id, + a_uint32_t port_id, + a_uint32_t *value) +{ + union port_vlan_config_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_vlan_config_get(dev_id, port_id, ®_val); + *value = reg_val.bf.port_untag_fltr_cmd; + return ret; +} + +sw_error_t +hppe_port_vlan_config_port_untag_fltr_cmd_set( + a_uint32_t dev_id, + a_uint32_t port_id, + a_uint32_t value) +{ + union port_vlan_config_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_vlan_config_get(dev_id, port_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_untag_fltr_cmd = value; + ret = hppe_port_vlan_config_set(dev_id, port_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_vlan_config_port_in_vlan_fltr_cmd_get( + a_uint32_t dev_id, + a_uint32_t port_id, + a_uint32_t *value) +{ + union port_vlan_config_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_vlan_config_get(dev_id, port_id, ®_val); + *value = reg_val.bf.port_in_vlan_fltr_cmd; + return ret; +} + +sw_error_t +hppe_port_vlan_config_port_in_vlan_fltr_cmd_set( + a_uint32_t dev_id, + a_uint32_t port_id, + a_uint32_t value) +{ + union port_vlan_config_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_vlan_config_get(dev_id, port_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_in_vlan_fltr_cmd = value; + ret = hppe_port_vlan_config_set(dev_id, port_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_vlan_config_port_pri_tag_fltr_cmd_get( + a_uint32_t dev_id, + a_uint32_t port_id, + a_uint32_t *value) +{ + union port_vlan_config_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_vlan_config_get(dev_id, port_id, ®_val); + *value = reg_val.bf.port_pri_tag_fltr_cmd; + return ret; +} + +sw_error_t +hppe_port_vlan_config_port_pri_tag_fltr_cmd_set( + a_uint32_t dev_id, + a_uint32_t port_id, + a_uint32_t value) +{ + union port_vlan_config_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_vlan_config_get(dev_id, port_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_pri_tag_fltr_cmd = value; + ret = hppe_port_vlan_config_set(dev_id, port_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_vlan_config_port_vlan_xlt_miss_fwd_cmd_get( + a_uint32_t dev_id, + a_uint32_t port_id, + a_uint32_t *value) +{ + union port_vlan_config_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_vlan_config_get(dev_id, port_id, ®_val); + *value = reg_val.bf.port_vlan_xlt_miss_fwd_cmd; + return ret; +} + +sw_error_t +hppe_port_vlan_config_port_vlan_xlt_miss_fwd_cmd_set( + a_uint32_t dev_id, + a_uint32_t port_id, + a_uint32_t value) +{ + union port_vlan_config_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_vlan_config_get(dev_id, port_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_vlan_xlt_miss_fwd_cmd = value; + ret = hppe_port_vlan_config_set(dev_id, port_id, ®_val); + return ret; +} + +sw_error_t +hppe_port_vlan_config_port_tag_fltr_cmd_get( + a_uint32_t dev_id, + a_uint32_t port_id, + a_uint32_t *value) +{ + union port_vlan_config_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_vlan_config_get(dev_id, port_id, ®_val); + *value = reg_val.bf.port_tag_fltr_cmd; + return ret; +} + +sw_error_t +hppe_port_vlan_config_port_tag_fltr_cmd_set( + a_uint32_t dev_id, + a_uint32_t port_id, + a_uint32_t value) +{ + union port_vlan_config_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_vlan_config_get(dev_id, port_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_tag_fltr_cmd = value; + ret = hppe_port_vlan_config_set(dev_id, port_id, ®_val); + return ret; +} + +#ifndef IN_PORTVLAN_MINI +sw_error_t +hppe_iv_dbg_addr_dbg_addr_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union iv_dbg_addr_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_iv_dbg_addr_get(dev_id, ®_val); + *value = reg_val.bf.dbg_addr; + return ret; +} + +sw_error_t +hppe_iv_dbg_addr_dbg_addr_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union iv_dbg_addr_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_iv_dbg_addr_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.dbg_addr = value; + ret = hppe_iv_dbg_addr_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_iv_dbg_data_dbg_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union iv_dbg_data_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_iv_dbg_data_get(dev_id, ®_val); + *value = reg_val.bf.dbg_data; + return ret; +} + +sw_error_t +hppe_iv_dbg_data_dbg_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_eco_reserve_eco_res_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union eco_reserve_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eco_reserve_get(dev_id, ®_val); + *value = reg_val.bf.eco_res; + return ret; +} + +sw_error_t +hppe_eco_reserve_eco_res_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union eco_reserve_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eco_reserve_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.eco_res = value; + ret = hppe_eco_reserve_set(dev_id, ®_val); + return ret; +} +#endif + +sw_error_t +hppe_xlt_rule_tbl_ckey_vid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ckey_vid; + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_ckey_vid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ckey_vid = value; + ret = hppe_xlt_rule_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_frm_type_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.frm_type; + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_frm_type_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.frm_type = value; + ret = hppe_xlt_rule_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_prot_value_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.prot_value_1 << 7 | \ + reg_val.bf.prot_value_0; + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_prot_value_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.prot_value_1 = value >> 7; + reg_val.bf.prot_value_0 = value & (((a_uint64_t)1<<7)-1); + ret = hppe_xlt_rule_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.valid; + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.valid = value; + ret = hppe_xlt_rule_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_frm_type_incl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.frm_type_incl; + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_frm_type_incl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.frm_type_incl = value; + ret = hppe_xlt_rule_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_ckey_dei_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ckey_dei; + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_ckey_dei_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ckey_dei = value; + ret = hppe_xlt_rule_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_skey_dei_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.skey_dei; + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_skey_dei_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.skey_dei = value; + ret = hppe_xlt_rule_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_skey_pcp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.skey_pcp; + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_skey_pcp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.skey_pcp = value; + ret = hppe_xlt_rule_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_ckey_pcp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ckey_pcp; + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_ckey_pcp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ckey_pcp = value; + ret = hppe_xlt_rule_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_ckey_vid_incl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ckey_vid_incl; + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_ckey_vid_incl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ckey_vid_incl = value; + ret = hppe_xlt_rule_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_ckey_dei_incl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ckey_dei_incl; + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_ckey_dei_incl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ckey_dei_incl = value; + ret = hppe_xlt_rule_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_port_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.port_bitmap; + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_port_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_bitmap = value; + ret = hppe_xlt_rule_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_prot_incl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.prot_incl; + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_prot_incl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.prot_incl = value; + ret = hppe_xlt_rule_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_skey_pcp_incl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.skey_pcp_incl; + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_skey_pcp_incl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.skey_pcp_incl = value; + ret = hppe_xlt_rule_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_ckey_fmt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ckey_fmt_1 << 1 | \ + reg_val.bf.ckey_fmt_0; + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_ckey_fmt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ckey_fmt_1 = value >> 1; + reg_val.bf.ckey_fmt_0 = value & (((a_uint64_t)1<<1)-1); + ret = hppe_xlt_rule_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_skey_vid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.skey_vid; + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_skey_vid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.skey_vid = value; + ret = hppe_xlt_rule_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_skey_fmt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.skey_fmt; + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_skey_fmt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.skey_fmt = value; + ret = hppe_xlt_rule_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_ckey_pcp_incl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ckey_pcp_incl; + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_ckey_pcp_incl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ckey_pcp_incl = value; + ret = hppe_xlt_rule_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_skey_dei_incl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.skey_dei_incl; + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_skey_dei_incl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.skey_dei_incl = value; + ret = hppe_xlt_rule_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_skey_vid_incl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.skey_vid_incl; + return ret; +} + +sw_error_t +hppe_xlt_rule_tbl_skey_vid_incl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_rule_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_rule_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.skey_vid_incl = value; + ret = hppe_xlt_rule_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_dei_swap_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.dei_swap_cmd; + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_dei_swap_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.dei_swap_cmd = value; + ret = hppe_xlt_action_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_xlt_cvid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.xlt_cvid; + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_xlt_cvid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.xlt_cvid = value; + ret = hppe_xlt_action_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_xlt_cpcp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.xlt_cpcp; + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_xlt_cpcp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.xlt_cpcp = value; + ret = hppe_xlt_action_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_xlt_spcp_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.xlt_spcp_cmd; + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_xlt_spcp_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.xlt_spcp_cmd = value; + ret = hppe_xlt_action_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_xlt_sdei_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.xlt_sdei_cmd; + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_xlt_sdei_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.xlt_sdei_cmd = value; + ret = hppe_xlt_action_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_xlt_cvid_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.xlt_cvid_cmd; + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_xlt_cvid_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.xlt_cvid_cmd = value; + ret = hppe_xlt_action_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_vsi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.vsi; + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_vsi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.vsi = value; + ret = hppe_xlt_action_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_xlt_spcp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.xlt_spcp_1 << 1 | \ + reg_val.bf.xlt_spcp_0; + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_xlt_spcp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.xlt_spcp_1 = value >> 1; + reg_val.bf.xlt_spcp_0 = value & (((a_uint64_t)1<<1)-1); + ret = hppe_xlt_action_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_counter_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.counter_id; + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_counter_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.counter_id = value; + ret = hppe_xlt_action_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_vid_swap_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.vid_swap_cmd; + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_vid_swap_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.vid_swap_cmd = value; + ret = hppe_xlt_action_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_xlt_sdei_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.xlt_sdei; + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_xlt_sdei_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.xlt_sdei = value; + ret = hppe_xlt_action_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_counter_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.counter_en; + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_counter_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.counter_en = value; + ret = hppe_xlt_action_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_xlt_svid_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.xlt_svid_cmd; + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_xlt_svid_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.xlt_svid_cmd = value; + ret = hppe_xlt_action_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_xlt_svid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.xlt_svid; + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_xlt_svid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.xlt_svid = value; + ret = hppe_xlt_action_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_vsi_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.vsi_cmd; + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_vsi_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.vsi_cmd = value; + ret = hppe_xlt_action_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_xlt_cpcp_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.xlt_cpcp_cmd; + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_xlt_cpcp_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.xlt_cpcp_cmd = value; + ret = hppe_xlt_action_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_xlt_cdei_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.xlt_cdei_cmd; + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_xlt_cdei_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.xlt_cdei_cmd = value; + ret = hppe_xlt_action_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_pcp_swap_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.pcp_swap_cmd; + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_pcp_swap_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pcp_swap_cmd = value; + ret = hppe_xlt_action_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_xlt_cdei_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.xlt_cdei; + return ret; +} + +sw_error_t +hppe_xlt_action_tbl_xlt_cdei_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union xlt_action_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_xlt_action_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.xlt_cdei = value; + ret = hppe_xlt_action_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_get( + a_uint32_t dev_id, + a_uint32_t index, + union eg_vlan_xlt_rule_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + NSS_PTX_CSR_BASE_ADDR + EG_VLAN_XLT_RULE_ADDRESS + \ + index * EG_VLAN_XLT_RULE_INC, + value->val, + 2); +} + +sw_error_t +hppe_eg_vlan_xlt_rule_set( + a_uint32_t dev_id, + a_uint32_t index, + union eg_vlan_xlt_rule_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + NSS_PTX_CSR_BASE_ADDR + EG_VLAN_XLT_RULE_ADDRESS + \ + index * EG_VLAN_XLT_RULE_INC, + value->val, + 2); +} + +sw_error_t +hppe_eg_vsi_tag_get( + a_uint32_t dev_id, + a_uint32_t index, + union eg_vsi_tag_u *value) +{ + if (index >= EG_VSI_TAG_NUM) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_PTX_CSR_BASE_ADDR + EG_VSI_TAG_ADDRESS + \ + index * EG_VSI_TAG_INC, + &value->val); +} + +sw_error_t +hppe_eg_vsi_tag_set( + a_uint32_t dev_id, + a_uint32_t index, + union eg_vsi_tag_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_PTX_CSR_BASE_ADDR + EG_VSI_TAG_ADDRESS + \ + index * EG_VSI_TAG_INC, + value->val); +} + +sw_error_t +hppe_port_eg_def_vid_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_eg_def_vid_u *value) +{ + if (index >= PORT_EG_DEF_VID_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_PTX_CSR_BASE_ADDR + PORT_EG_DEF_VID_ADDRESS + \ + index * PORT_EG_DEF_VID_INC, + &value->val); +} + +sw_error_t +hppe_port_eg_def_vid_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_eg_def_vid_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_PTX_CSR_BASE_ADDR + PORT_EG_DEF_VID_ADDRESS + \ + index * PORT_EG_DEF_VID_INC, + value->val); +} + +sw_error_t +hppe_port_eg_vlan_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_eg_vlan_u *value) +{ + if (index >= PORT_EG_VLAN_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_PTX_CSR_BASE_ADDR + PORT_EG_VLAN_ADDRESS + \ + index * PORT_EG_VLAN_INC, + &value->val); +} + +sw_error_t +hppe_port_eg_vlan_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_eg_vlan_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_PTX_CSR_BASE_ADDR + PORT_EG_VLAN_ADDRESS + \ + index * PORT_EG_VLAN_INC, + value->val); +} + +sw_error_t +hppe_eg_vlan_tpid_get( + a_uint32_t dev_id, + union eg_vlan_tpid_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_PTX_CSR_BASE_ADDR + EG_VLAN_TPID_ADDRESS, + &value->val); +} + +sw_error_t +hppe_eg_vlan_tpid_set( + a_uint32_t dev_id, + union eg_vlan_tpid_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_PTX_CSR_BASE_ADDR + EG_VLAN_TPID_ADDRESS, + value->val); +} + +sw_error_t +hppe_eg_bridge_config_get( + a_uint32_t dev_id, + union eg_bridge_config_u *value) +{ + return hppe_reg_get( + dev_id, + NSS_PTX_CSR_BASE_ADDR + EG_BRIDGE_CONFIG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_eg_bridge_config_set( + a_uint32_t dev_id, + union eg_bridge_config_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_PTX_CSR_BASE_ADDR + EG_BRIDGE_CONFIG_ADDRESS, + value->val); +} + +sw_error_t +hppe_eg_vlan_xlt_action_get( + a_uint32_t dev_id, + a_uint32_t index, + union eg_vlan_xlt_action_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + NSS_PTX_CSR_BASE_ADDR + EG_VLAN_XLT_ACTION_ADDRESS + \ + index * EG_VLAN_XLT_ACTION_INC, + value->val, + 2); +} + +sw_error_t +hppe_eg_vlan_xlt_action_set( + a_uint32_t dev_id, + a_uint32_t index, + union eg_vlan_xlt_action_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + NSS_PTX_CSR_BASE_ADDR + EG_VLAN_XLT_ACTION_ADDRESS + \ + index * EG_VLAN_XLT_ACTION_INC, + value->val, + 2); +} + +sw_error_t +hppe_eg_vlan_xlt_rule_ckey_vid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + *value = reg_val.bf.ckey_vid; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_ckey_vid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ckey_vid = value; + ret = hppe_eg_vlan_xlt_rule_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + *value = reg_val.bf.valid; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.valid = value; + ret = hppe_eg_vlan_xlt_rule_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_ckey_dei_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + *value = reg_val.bf.ckey_dei; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_ckey_dei_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ckey_dei = value; + ret = hppe_eg_vlan_xlt_rule_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_skey_dei_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + *value = reg_val.bf.skey_dei; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_skey_dei_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.skey_dei = value; + ret = hppe_eg_vlan_xlt_rule_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_skey_pcp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + *value = reg_val.bf.skey_pcp; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_skey_pcp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.skey_pcp = value; + ret = hppe_eg_vlan_xlt_rule_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_ckey_pcp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + *value = reg_val.bf.ckey_pcp; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_ckey_pcp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ckey_pcp = value; + ret = hppe_eg_vlan_xlt_rule_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_vsi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + *value = reg_val.bf.vsi; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_vsi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.vsi = value; + ret = hppe_eg_vlan_xlt_rule_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_ckey_vid_incl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + *value = reg_val.bf.ckey_vid_incl; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_ckey_vid_incl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ckey_vid_incl = value; + ret = hppe_eg_vlan_xlt_rule_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_ckey_dei_incl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + *value = reg_val.bf.ckey_dei_incl; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_ckey_dei_incl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ckey_dei_incl = value; + ret = hppe_eg_vlan_xlt_rule_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_vsi_incl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + *value = reg_val.bf.vsi_incl; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_vsi_incl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.vsi_incl = value; + ret = hppe_eg_vlan_xlt_rule_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_port_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + *value = reg_val.bf.port_bitmap; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_port_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_bitmap = value; + ret = hppe_eg_vlan_xlt_rule_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_skey_pcp_incl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + *value = reg_val.bf.skey_pcp_incl; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_skey_pcp_incl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.skey_pcp_incl = value; + ret = hppe_eg_vlan_xlt_rule_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_ckey_fmt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + *value = reg_val.bf.ckey_fmt; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_ckey_fmt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ckey_fmt = value; + ret = hppe_eg_vlan_xlt_rule_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_skey_vid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + *value = reg_val.bf.skey_vid; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_skey_vid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.skey_vid = value; + ret = hppe_eg_vlan_xlt_rule_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_skey_fmt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + *value = reg_val.bf.skey_fmt; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_skey_fmt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.skey_fmt = value; + ret = hppe_eg_vlan_xlt_rule_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_ckey_pcp_incl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + *value = reg_val.bf.ckey_pcp_incl; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_ckey_pcp_incl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ckey_pcp_incl = value; + ret = hppe_eg_vlan_xlt_rule_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_skey_vid_incl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + *value = reg_val.bf.skey_vid_incl; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_skey_vid_incl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.skey_vid_incl = value; + ret = hppe_eg_vlan_xlt_rule_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_skey_dei_incl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + *value = reg_val.bf.skey_dei_incl; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_skey_dei_incl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.skey_dei_incl = value; + ret = hppe_eg_vlan_xlt_rule_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_vsi_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + *value = reg_val.bf.vsi_valid; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_rule_vsi_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_rule_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_rule_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.vsi_valid = value; + ret = hppe_eg_vlan_xlt_rule_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vsi_tag_tagged_mode_port_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vsi_tag_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vsi_tag_get(dev_id, index, ®_val); + *value = reg_val.bf.tagged_mode_port_bitmap; + return ret; +} + +sw_error_t +hppe_eg_vsi_tag_tagged_mode_port_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vsi_tag_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vsi_tag_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tagged_mode_port_bitmap = value; + ret = hppe_eg_vsi_tag_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_eg_def_vid_port_def_svid_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_eg_def_vid_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_eg_def_vid_get(dev_id, index, ®_val); + *value = reg_val.bf.port_def_svid_en; + return ret; +} + +sw_error_t +hppe_port_eg_def_vid_port_def_svid_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_eg_def_vid_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_eg_def_vid_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_def_svid_en = value; + ret = hppe_port_eg_def_vid_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_eg_def_vid_port_def_svid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_eg_def_vid_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_eg_def_vid_get(dev_id, index, ®_val); + *value = reg_val.bf.port_def_svid; + return ret; +} + +sw_error_t +hppe_port_eg_def_vid_port_def_svid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_eg_def_vid_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_eg_def_vid_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_def_svid = value; + ret = hppe_port_eg_def_vid_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_eg_def_vid_port_def_cvid_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_eg_def_vid_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_eg_def_vid_get(dev_id, index, ®_val); + *value = reg_val.bf.port_def_cvid_en; + return ret; +} + +sw_error_t +hppe_port_eg_def_vid_port_def_cvid_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_eg_def_vid_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_eg_def_vid_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_def_cvid_en = value; + ret = hppe_port_eg_def_vid_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_eg_def_vid_port_def_cvid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_eg_def_vid_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_eg_def_vid_get(dev_id, index, ®_val); + *value = reg_val.bf.port_def_cvid; + return ret; +} + +sw_error_t +hppe_port_eg_def_vid_port_def_cvid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_eg_def_vid_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_eg_def_vid_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_def_cvid = value; + ret = hppe_port_eg_def_vid_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_eg_vlan_tx_counting_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_eg_vlan_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_eg_vlan_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_counting_en; + return ret; +} + +sw_error_t +hppe_port_eg_vlan_tx_counting_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_eg_vlan_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_eg_vlan_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_counting_en = value; + ret = hppe_port_eg_vlan_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_eg_vlan_port_eg_vlan_ctag_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_eg_vlan_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_eg_vlan_get(dev_id, index, ®_val); + *value = reg_val.bf.port_eg_vlan_ctag_mode; + return ret; +} + +sw_error_t +hppe_port_eg_vlan_port_eg_vlan_ctag_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_eg_vlan_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_eg_vlan_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_eg_vlan_ctag_mode = value; + ret = hppe_port_eg_vlan_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_eg_vlan_port_eg_pcp_prop_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_eg_vlan_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_eg_vlan_get(dev_id, index, ®_val); + *value = reg_val.bf.port_eg_pcp_prop_cmd; + return ret; +} + +sw_error_t +hppe_port_eg_vlan_port_eg_pcp_prop_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_eg_vlan_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_eg_vlan_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_eg_pcp_prop_cmd = value; + ret = hppe_port_eg_vlan_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_eg_vlan_vsi_tag_mode_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_eg_vlan_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_eg_vlan_get(dev_id, index, ®_val); + *value = reg_val.bf.vsi_tag_mode_en; + return ret; +} + +sw_error_t +hppe_port_eg_vlan_vsi_tag_mode_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_eg_vlan_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_eg_vlan_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.vsi_tag_mode_en = value; + ret = hppe_port_eg_vlan_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_eg_vlan_port_eg_vlan_stag_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_eg_vlan_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_eg_vlan_get(dev_id, index, ®_val); + *value = reg_val.bf.port_eg_vlan_stag_mode; + return ret; +} + +sw_error_t +hppe_port_eg_vlan_port_eg_vlan_stag_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_eg_vlan_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_eg_vlan_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_eg_vlan_stag_mode = value; + ret = hppe_port_eg_vlan_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_eg_vlan_port_eg_dei_prop_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_eg_vlan_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_eg_vlan_get(dev_id, index, ®_val); + *value = reg_val.bf.port_eg_dei_prop_cmd; + return ret; +} + +sw_error_t +hppe_port_eg_vlan_port_eg_dei_prop_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_eg_vlan_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_eg_vlan_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_eg_dei_prop_cmd = value; + ret = hppe_port_eg_vlan_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_eg_vlan_port_vlan_type_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_eg_vlan_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_eg_vlan_get(dev_id, index, ®_val); + *value = reg_val.bf.port_vlan_type; + return ret; +} + +sw_error_t +hppe_port_eg_vlan_port_vlan_type_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_eg_vlan_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_eg_vlan_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_vlan_type = value; + ret = hppe_port_eg_vlan_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_tpid_ctpid_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union eg_vlan_tpid_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_tpid_get(dev_id, ®_val); + *value = reg_val.bf.ctpid; + return ret; +} + +sw_error_t +hppe_eg_vlan_tpid_ctpid_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union eg_vlan_tpid_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_tpid_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ctpid = value; + ret = hppe_eg_vlan_tpid_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_tpid_stpid_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union eg_vlan_tpid_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_tpid_get(dev_id, ®_val); + *value = reg_val.bf.stpid; + return ret; +} + +sw_error_t +hppe_eg_vlan_tpid_stpid_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union eg_vlan_tpid_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_tpid_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.stpid = value; + ret = hppe_eg_vlan_tpid_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_eg_bridge_config_bridge_type_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union eg_bridge_config_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_bridge_config_get(dev_id, ®_val); + *value = reg_val.bf.bridge_type; + return ret; +} + +sw_error_t +hppe_eg_bridge_config_bridge_type_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union eg_bridge_config_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_bridge_config_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.bridge_type = value; + ret = hppe_eg_bridge_config_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_eg_bridge_config_queue_cnt_en_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union eg_bridge_config_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_bridge_config_get(dev_id, ®_val); + *value = reg_val.bf.queue_cnt_en; + return ret; +} + +sw_error_t +hppe_eg_bridge_config_queue_cnt_en_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union eg_bridge_config_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_bridge_config_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.queue_cnt_en = value; + ret = hppe_eg_bridge_config_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_action_dei_swap_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_action_get(dev_id, index, ®_val); + *value = reg_val.bf.dei_swap_cmd; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_action_dei_swap_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.dei_swap_cmd = value; + ret = hppe_eg_vlan_xlt_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_cvid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_action_get(dev_id, index, ®_val); + *value = reg_val.bf.xlt_cvid; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_cvid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.xlt_cvid = value; + ret = hppe_eg_vlan_xlt_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_cpcp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_action_get(dev_id, index, ®_val); + *value = reg_val.bf.xlt_cpcp; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_cpcp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.xlt_cpcp = value; + ret = hppe_eg_vlan_xlt_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_spcp_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_action_get(dev_id, index, ®_val); + *value = reg_val.bf.xlt_spcp_cmd; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_spcp_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.xlt_spcp_cmd = value; + ret = hppe_eg_vlan_xlt_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_sdei_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_action_get(dev_id, index, ®_val); + *value = reg_val.bf.xlt_sdei_cmd; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_sdei_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.xlt_sdei_cmd = value; + ret = hppe_eg_vlan_xlt_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_cvid_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_action_get(dev_id, index, ®_val); + *value = reg_val.bf.xlt_cvid_cmd; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_cvid_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.xlt_cvid_cmd = value; + ret = hppe_eg_vlan_xlt_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_spcp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_action_get(dev_id, index, ®_val); + *value = reg_val.bf.xlt_spcp_1 << 1 | \ + reg_val.bf.xlt_spcp_0; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_spcp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.xlt_spcp_1 = value >> 1; + reg_val.bf.xlt_spcp_0 = value & (((a_uint64_t)1<<1)-1); + ret = hppe_eg_vlan_xlt_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_action_counter_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_action_get(dev_id, index, ®_val); + *value = reg_val.bf.counter_id; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_action_counter_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.counter_id = value; + ret = hppe_eg_vlan_xlt_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_action_vid_swap_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_action_get(dev_id, index, ®_val); + *value = reg_val.bf.vid_swap_cmd; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_action_vid_swap_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.vid_swap_cmd = value; + ret = hppe_eg_vlan_xlt_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_sdei_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_action_get(dev_id, index, ®_val); + *value = reg_val.bf.xlt_sdei; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_sdei_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.xlt_sdei = value; + ret = hppe_eg_vlan_xlt_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_action_counter_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_action_get(dev_id, index, ®_val); + *value = reg_val.bf.counter_en; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_action_counter_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.counter_en = value; + ret = hppe_eg_vlan_xlt_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_svid_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_action_get(dev_id, index, ®_val); + *value = reg_val.bf.xlt_svid_cmd; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_svid_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.xlt_svid_cmd = value; + ret = hppe_eg_vlan_xlt_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_svid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_action_get(dev_id, index, ®_val); + *value = reg_val.bf.xlt_svid; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_svid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.xlt_svid = value; + ret = hppe_eg_vlan_xlt_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_cpcp_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_action_get(dev_id, index, ®_val); + *value = reg_val.bf.xlt_cpcp_cmd; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_cpcp_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.xlt_cpcp_cmd = value; + ret = hppe_eg_vlan_xlt_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_cdei_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_action_get(dev_id, index, ®_val); + *value = reg_val.bf.xlt_cdei_cmd; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_cdei_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.xlt_cdei_cmd = value; + ret = hppe_eg_vlan_xlt_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_action_pcp_swap_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_action_get(dev_id, index, ®_val); + *value = reg_val.bf.pcp_swap_cmd; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_action_pcp_swap_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pcp_swap_cmd = value; + ret = hppe_eg_vlan_xlt_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_cdei_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vlan_xlt_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_action_get(dev_id, index, ®_val); + *value = reg_val.bf.xlt_cdei; + return ret; +} + +sw_error_t +hppe_eg_vlan_xlt_action_xlt_cdei_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vlan_xlt_action_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vlan_xlt_action_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.xlt_cdei = value; + ret = hppe_eg_vlan_xlt_action_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vlan_dev_tx_counter_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union vlan_dev_tx_counter_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + NSS_PTX_CSR_BASE_ADDR + VLAN_DEV_TX_COUNTER_TBL_ADDRESS + \ + index * VLAN_DEV_TX_COUNTER_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_vlan_dev_tx_counter_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union vlan_dev_tx_counter_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + NSS_PTX_CSR_BASE_ADDR + VLAN_DEV_TX_COUNTER_TBL_ADDRESS + \ + index * VLAN_DEV_TX_COUNTER_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_vlan_dev_tx_counter_tbl_tx_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union vlan_dev_tx_counter_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vlan_dev_tx_counter_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.tx_byte_cnt_1 << 32 | \ + reg_val.bf.tx_byte_cnt_0; + return ret; +} + +sw_error_t +hppe_vlan_dev_tx_counter_tbl_tx_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union vlan_dev_tx_counter_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vlan_dev_tx_counter_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_byte_cnt_1 = value >> 32; + reg_val.bf.tx_byte_cnt_0 = value & (((a_uint64_t)1<<32)-1); + ret = hppe_vlan_dev_tx_counter_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vlan_dev_tx_counter_tbl_tx_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vlan_dev_tx_counter_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vlan_dev_tx_counter_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_pkt_cnt; + return ret; +} + +sw_error_t +hppe_vlan_dev_tx_counter_tbl_tx_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vlan_dev_tx_counter_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vlan_dev_tx_counter_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_pkt_cnt = value; + ret = hppe_vlan_dev_tx_counter_tbl_set(dev_id, index, ®_val); + return ret; +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_pppoe.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_pppoe.c new file mode 100755 index 000000000..481de4748 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_pppoe.c @@ -0,0 +1,388 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hppe_reg_access.h" +#include "hppe_pppoe_reg.h" +#include "hppe_pppoe.h" + +sw_error_t +hppe_pppoe_session_get( + a_uint32_t dev_id, + a_uint32_t index, + union pppoe_session_u *value) +{ + if (index >= PPPOE_SESSION_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + PPPOE_SESSION_ADDRESS + \ + index * PPPOE_SESSION_INC, + &value->val); +} + +sw_error_t +hppe_pppoe_session_set( + a_uint32_t dev_id, + a_uint32_t index, + union pppoe_session_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + PPPOE_SESSION_ADDRESS + \ + index * PPPOE_SESSION_INC, + value->val); +} + +sw_error_t +hppe_pppoe_session_ext_get( + a_uint32_t dev_id, + a_uint32_t index, + union pppoe_session_ext_u *value) +{ + if (index >= PPPOE_SESSION_EXT_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + PPPOE_SESSION_EXT_ADDRESS + \ + index * PPPOE_SESSION_EXT_INC, + &value->val); +} + +sw_error_t +hppe_pppoe_session_ext_set( + a_uint32_t dev_id, + a_uint32_t index, + union pppoe_session_ext_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + PPPOE_SESSION_EXT_ADDRESS + \ + index * PPPOE_SESSION_EXT_INC, + value->val); +} + +sw_error_t +hppe_pppoe_session_ext1_get( + a_uint32_t dev_id, + a_uint32_t index, + union pppoe_session_ext1_u *value) +{ + if (index >= PPPOE_SESSION_EXT1_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + PPPOE_SESSION_EXT1_ADDRESS + \ + index * PPPOE_SESSION_EXT1_INC, + &value->val); +} + +sw_error_t +hppe_pppoe_session_ext1_set( + a_uint32_t dev_id, + a_uint32_t index, + union pppoe_session_ext1_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + PPPOE_SESSION_EXT1_ADDRESS + \ + index * PPPOE_SESSION_EXT1_INC, + value->val); +} + +sw_error_t +hppe_pppoe_session_session_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pppoe_session_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pppoe_session_get(dev_id, index, ®_val); + *value = reg_val.bf.session_id; + return ret; +} + +sw_error_t +hppe_pppoe_session_session_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pppoe_session_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pppoe_session_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.session_id = value; + ret = hppe_pppoe_session_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pppoe_session_l3_if_index_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pppoe_session_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pppoe_session_get(dev_id, index, ®_val); + *value = reg_val.bf.l3_if_index; + return ret; +} + +sw_error_t +hppe_pppoe_session_l3_if_index_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pppoe_session_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pppoe_session_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l3_if_index = value; + ret = hppe_pppoe_session_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pppoe_session_port_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pppoe_session_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pppoe_session_get(dev_id, index, ®_val); + *value = reg_val.bf.port_bitmap; + return ret; +} + +sw_error_t +hppe_pppoe_session_port_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pppoe_session_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pppoe_session_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_bitmap = value; + ret = hppe_pppoe_session_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pppoe_session_ext_uc_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pppoe_session_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pppoe_session_ext_get(dev_id, index, ®_val); + *value = reg_val.bf.uc_valid; + return ret; +} + +sw_error_t +hppe_pppoe_session_ext_uc_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pppoe_session_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pppoe_session_ext_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.uc_valid = value; + ret = hppe_pppoe_session_ext_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pppoe_session_ext_mc_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pppoe_session_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pppoe_session_ext_get(dev_id, index, ®_val); + *value = reg_val.bf.mc_valid; + return ret; +} + +sw_error_t +hppe_pppoe_session_ext_mc_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pppoe_session_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pppoe_session_ext_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mc_valid = value; + ret = hppe_pppoe_session_ext_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pppoe_session_ext_smac_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pppoe_session_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pppoe_session_ext_get(dev_id, index, ®_val); + *value = reg_val.bf.smac_valid; + return ret; +} + +sw_error_t +hppe_pppoe_session_ext_smac_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pppoe_session_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pppoe_session_ext_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.smac_valid = value; + ret = hppe_pppoe_session_ext_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pppoe_session_ext_l3_if_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pppoe_session_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pppoe_session_ext_get(dev_id, index, ®_val); + *value = reg_val.bf.l3_if_valid; + return ret; +} + +sw_error_t +hppe_pppoe_session_ext_l3_if_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pppoe_session_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pppoe_session_ext_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l3_if_valid = value; + ret = hppe_pppoe_session_ext_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pppoe_session_ext_smac_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pppoe_session_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pppoe_session_ext_get(dev_id, index, ®_val); + *value = reg_val.bf.smac; + return ret; +} + +sw_error_t +hppe_pppoe_session_ext_smac_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pppoe_session_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pppoe_session_ext_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.smac = value; + ret = hppe_pppoe_session_ext_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pppoe_session_ext1_smac_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pppoe_session_ext1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pppoe_session_ext1_get(dev_id, index, ®_val); + *value = reg_val.bf.smac; + return ret; +} + +sw_error_t +hppe_pppoe_session_ext1_smac_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pppoe_session_ext1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pppoe_session_ext1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.smac = value; + ret = hppe_pppoe_session_ext1_set(dev_id, index, ®_val); + return ret; +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_qm.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_qm.c new file mode 100755 index 000000000..16e3cebdc --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_qm.c @@ -0,0 +1,9622 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hppe_reg_access.h" +#include "hppe_qm_reg.h" +#include "hppe_qm.h" + +sw_error_t +hppe_queue_tx_counter_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union queue_tx_counter_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + NSS_PTX_CSR_BASE_ADDR + QUEUE_TX_COUNTER_TBL_ADDRESS + \ + index * QUEUE_TX_COUNTER_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_queue_tx_counter_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union queue_tx_counter_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + NSS_PTX_CSR_BASE_ADDR + QUEUE_TX_COUNTER_TBL_ADDRESS + \ + index * QUEUE_TX_COUNTER_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_flush_cfg_get( + a_uint32_t dev_id, + union flush_cfg_u *value) +{ + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + FLUSH_CFG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_flush_cfg_set( + a_uint32_t dev_id, + union flush_cfg_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + FLUSH_CFG_ADDRESS, + value->val); +} + +sw_error_t +hppe_in_mirror_priority_ctrl_get( + a_uint32_t dev_id, + union in_mirror_priority_ctrl_u *value) +{ + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + IN_MIRROR_PRIORITY_CTRL_ADDRESS, + &value->val); +} + +sw_error_t +hppe_in_mirror_priority_ctrl_set( + a_uint32_t dev_id, + union in_mirror_priority_ctrl_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + IN_MIRROR_PRIORITY_CTRL_ADDRESS, + value->val); +} + +sw_error_t +hppe_eg_mirror_priority_ctrl_get( + a_uint32_t dev_id, + union eg_mirror_priority_ctrl_u *value) +{ + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + EG_MIRROR_PRIORITY_CTRL_ADDRESS, + &value->val); +} + +sw_error_t +hppe_eg_mirror_priority_ctrl_set( + a_uint32_t dev_id, + union eg_mirror_priority_ctrl_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + EG_MIRROR_PRIORITY_CTRL_ADDRESS, + value->val); +} + +#ifndef IN_QM_MINI +sw_error_t +hppe_ucast_default_hash_get( + a_uint32_t dev_id, + union ucast_default_hash_u *value) +{ + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + UCAST_DEFAULT_HASH_ADDRESS, + &value->val); +} + +sw_error_t +hppe_ucast_default_hash_set( + a_uint32_t dev_id, + union ucast_default_hash_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + UCAST_DEFAULT_HASH_ADDRESS, + value->val); +} + +sw_error_t +hppe_spare_reg0_get( + a_uint32_t dev_id, + union spare_reg0_u *value) +{ + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + SPARE_REG0_ADDRESS, + &value->val); +} + +sw_error_t +hppe_spare_reg0_set( + a_uint32_t dev_id, + union spare_reg0_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + SPARE_REG0_ADDRESS, + value->val); +} + +sw_error_t +hppe_spare_reg1_get( + a_uint32_t dev_id, + union spare_reg1_u *value) +{ + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + SPARE_REG1_ADDRESS, + &value->val); +} + +sw_error_t +hppe_spare_reg1_set( + a_uint32_t dev_id, + union spare_reg1_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + SPARE_REG1_ADDRESS, + value->val); +} + +sw_error_t +hppe_qm_dbg_addr_get( + a_uint32_t dev_id, + union qm_dbg_addr_u *value) +{ + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + QM_DBG_ADDR_ADDRESS, + &value->val); +} + +sw_error_t +hppe_qm_dbg_addr_set( + a_uint32_t dev_id, + union qm_dbg_addr_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + QM_DBG_ADDR_ADDRESS, + value->val); +} + +sw_error_t +hppe_qm_dbg_data_get( + a_uint32_t dev_id, + union qm_dbg_data_u *value) +{ + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + QM_DBG_DATA_ADDRESS, + &value->val); +} + +sw_error_t +hppe_qm_dbg_data_set( + a_uint32_t dev_id, + union qm_dbg_data_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mcast_priority_map0_get( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_priority_map0_u *value) +{ + if (index >= MCAST_PRIORITY_MAP0_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MCAST_PRIORITY_MAP0_ADDRESS + \ + index * MCAST_PRIORITY_MAP0_INC, + &value->val); +} + +sw_error_t +hppe_mcast_priority_map0_set( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_priority_map0_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MCAST_PRIORITY_MAP0_ADDRESS + \ + index * MCAST_PRIORITY_MAP0_INC, + value->val); +} + +sw_error_t +hppe_mcast_priority_map1_get( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_priority_map1_u *value) +{ + if (index >= MCAST_PRIORITY_MAP1_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MCAST_PRIORITY_MAP1_ADDRESS + \ + index * MCAST_PRIORITY_MAP1_INC, + &value->val); +} + +sw_error_t +hppe_mcast_priority_map1_set( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_priority_map1_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MCAST_PRIORITY_MAP1_ADDRESS + \ + index * MCAST_PRIORITY_MAP1_INC, + value->val); +} + +sw_error_t +hppe_mcast_priority_map2_get( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_priority_map2_u *value) +{ + if (index >= MCAST_PRIORITY_MAP2_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MCAST_PRIORITY_MAP2_ADDRESS + \ + index * MCAST_PRIORITY_MAP2_INC, + &value->val); +} + +sw_error_t +hppe_mcast_priority_map2_set( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_priority_map2_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MCAST_PRIORITY_MAP2_ADDRESS + \ + index * MCAST_PRIORITY_MAP2_INC, + value->val); +} + +sw_error_t +hppe_mcast_priority_map3_get( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_priority_map3_u *value) +{ + if (index >= MCAST_PRIORITY_MAP3_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MCAST_PRIORITY_MAP3_ADDRESS + \ + index * MCAST_PRIORITY_MAP3_INC, + &value->val); +} + +sw_error_t +hppe_mcast_priority_map3_set( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_priority_map3_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MCAST_PRIORITY_MAP3_ADDRESS + \ + index * MCAST_PRIORITY_MAP3_INC, + value->val); +} + +sw_error_t +hppe_mcast_priority_map4_get( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_priority_map4_u *value) +{ + if (index >= MCAST_PRIORITY_MAP4_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MCAST_PRIORITY_MAP4_ADDRESS + \ + index * MCAST_PRIORITY_MAP4_INC, + &value->val); +} + +sw_error_t +hppe_mcast_priority_map4_set( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_priority_map4_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MCAST_PRIORITY_MAP4_ADDRESS + \ + index * MCAST_PRIORITY_MAP4_INC, + value->val); +} + +sw_error_t +hppe_mcast_priority_map5_get( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_priority_map5_u *value) +{ + if (index >= MCAST_PRIORITY_MAP5_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MCAST_PRIORITY_MAP5_ADDRESS + \ + index * MCAST_PRIORITY_MAP5_INC, + &value->val); +} + +sw_error_t +hppe_mcast_priority_map5_set( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_priority_map5_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MCAST_PRIORITY_MAP5_ADDRESS + \ + index * MCAST_PRIORITY_MAP5_INC, + value->val); +} + +sw_error_t +hppe_mcast_priority_map6_get( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_priority_map6_u *value) +{ + if (index >= MCAST_PRIORITY_MAP6_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MCAST_PRIORITY_MAP6_ADDRESS + \ + index * MCAST_PRIORITY_MAP6_INC, + &value->val); +} + +sw_error_t +hppe_mcast_priority_map6_set( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_priority_map6_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MCAST_PRIORITY_MAP6_ADDRESS + \ + index * MCAST_PRIORITY_MAP6_INC, + value->val); +} + +sw_error_t +hppe_mcast_priority_map7_get( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_priority_map7_u *value) +{ + if (index >= MCAST_PRIORITY_MAP7_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MCAST_PRIORITY_MAP7_ADDRESS + \ + index * MCAST_PRIORITY_MAP7_INC, + &value->val); +} + +sw_error_t +hppe_mcast_priority_map7_set( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_priority_map7_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MCAST_PRIORITY_MAP7_ADDRESS + \ + index * MCAST_PRIORITY_MAP7_INC, + value->val); +} + +sw_error_t +hppe_agg_profile_cnt_en_get( + a_uint32_t dev_id, + union agg_profile_cnt_en_u *value) +{ + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + AGG_PROFILE_CNT_EN_ADDRESS, + &value->val); +} + +sw_error_t +hppe_agg_profile_cnt_en_set( + a_uint32_t dev_id, + union agg_profile_cnt_en_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + AGG_PROFILE_CNT_EN_ADDRESS, + value->val); +} + +sw_error_t +hppe_uq_agg_profile_cfg_get( + a_uint32_t dev_id, + a_uint32_t index, + union uq_agg_profile_cfg_u *value) +{ + if (index >= UQ_AGG_PROFILE_CFG_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + UQ_AGG_PROFILE_CFG_ADDRESS + \ + index * UQ_AGG_PROFILE_CFG_INC, + &value->val); +} + +sw_error_t +hppe_uq_agg_profile_cfg_set( + a_uint32_t dev_id, + a_uint32_t index, + union uq_agg_profile_cfg_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + UQ_AGG_PROFILE_CFG_ADDRESS + \ + index * UQ_AGG_PROFILE_CFG_INC, + value->val); +} + +sw_error_t +hppe_mq_agg_profile_cfg_get( + a_uint32_t dev_id, + a_uint32_t index, + union mq_agg_profile_cfg_u *value) +{ + if (index >= MQ_AGG_PROFILE_CFG_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MQ_AGG_PROFILE_CFG_ADDRESS + \ + index * MQ_AGG_PROFILE_CFG_INC, + &value->val); +} + +sw_error_t +hppe_mq_agg_profile_cfg_set( + a_uint32_t dev_id, + a_uint32_t index, + union mq_agg_profile_cfg_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MQ_AGG_PROFILE_CFG_ADDRESS + \ + index * MQ_AGG_PROFILE_CFG_INC, + value->val); +} + +sw_error_t +hppe_grp_agg_profile_cfg_get( + a_uint32_t dev_id, + a_uint32_t index, + union grp_agg_profile_cfg_u *value) +{ + if (index >= GRP_AGG_PROFILE_CFG_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + GRP_AGG_PROFILE_CFG_ADDRESS + \ + index * GRP_AGG_PROFILE_CFG_INC, + &value->val); +} + +sw_error_t +hppe_grp_agg_profile_cfg_set( + a_uint32_t dev_id, + a_uint32_t index, + union grp_agg_profile_cfg_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + GRP_AGG_PROFILE_CFG_ADDRESS + \ + index * GRP_AGG_PROFILE_CFG_INC, + value->val); +} + +sw_error_t +hppe_uq_agg_in_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + union uq_agg_in_profile_cnt_u *value) +{ + if (index >= UQ_AGG_IN_PROFILE_CNT_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + UQ_AGG_IN_PROFILE_CNT_ADDRESS + \ + index * UQ_AGG_IN_PROFILE_CNT_INC, + &value->val); +} + +sw_error_t +hppe_uq_agg_in_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + union uq_agg_in_profile_cnt_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + UQ_AGG_IN_PROFILE_CNT_ADDRESS + \ + index * UQ_AGG_IN_PROFILE_CNT_INC, + value->val); +} + +sw_error_t +hppe_uq_agg_out_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + union uq_agg_out_profile_cnt_u *value) +{ + if (index >= UQ_AGG_OUT_PROFILE_CNT_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + UQ_AGG_OUT_PROFILE_CNT_ADDRESS + \ + index * UQ_AGG_OUT_PROFILE_CNT_INC, + &value->val); +} + +sw_error_t +hppe_uq_agg_out_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + union uq_agg_out_profile_cnt_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + UQ_AGG_OUT_PROFILE_CNT_ADDRESS + \ + index * UQ_AGG_OUT_PROFILE_CNT_INC, + value->val); +} + +sw_error_t +hppe_mq_agg_in_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + union mq_agg_in_profile_cnt_u *value) +{ + if (index >= MQ_AGG_IN_PROFILE_CNT_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MQ_AGG_IN_PROFILE_CNT_ADDRESS + \ + index * MQ_AGG_IN_PROFILE_CNT_INC, + &value->val); +} + +sw_error_t +hppe_mq_agg_in_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + union mq_agg_in_profile_cnt_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MQ_AGG_IN_PROFILE_CNT_ADDRESS + \ + index * MQ_AGG_IN_PROFILE_CNT_INC, + value->val); +} + +sw_error_t +hppe_mq_agg_out_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + union mq_agg_out_profile_cnt_u *value) +{ + if (index >= MQ_AGG_OUT_PROFILE_CNT_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MQ_AGG_OUT_PROFILE_CNT_ADDRESS + \ + index * MQ_AGG_OUT_PROFILE_CNT_INC, + &value->val); +} + +sw_error_t +hppe_mq_agg_out_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + union mq_agg_out_profile_cnt_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MQ_AGG_OUT_PROFILE_CNT_ADDRESS + \ + index * MQ_AGG_OUT_PROFILE_CNT_INC, + value->val); +} + +sw_error_t +hppe_grp_agg_in_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + union grp_agg_in_profile_cnt_u *value) +{ + if (index >= GRP_AGG_IN_PROFILE_CNT_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + GRP_AGG_IN_PROFILE_CNT_ADDRESS + \ + index * GRP_AGG_IN_PROFILE_CNT_INC, + &value->val); +} + +sw_error_t +hppe_grp_agg_in_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + union grp_agg_in_profile_cnt_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + GRP_AGG_IN_PROFILE_CNT_ADDRESS + \ + index * GRP_AGG_IN_PROFILE_CNT_INC, + value->val); +} + +sw_error_t +hppe_grp_agg_out_profile_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + union grp_agg_out_profile_cnt_u *value) +{ + if (index >= GRP_AGG_OUT_PROFILE_CNT_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + GRP_AGG_OUT_PROFILE_CNT_ADDRESS + \ + index * GRP_AGG_OUT_PROFILE_CNT_INC, + &value->val); +} + +sw_error_t +hppe_grp_agg_out_profile_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + union grp_agg_out_profile_cnt_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + GRP_AGG_OUT_PROFILE_CNT_ADDRESS + \ + index * GRP_AGG_OUT_PROFILE_CNT_INC, + value->val); +} + +sw_error_t +hppe_ucast_queue_map_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union ucast_queue_map_tbl_u *value) +{ + if (index >= UCAST_QUEUE_MAP_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + UCAST_QUEUE_MAP_TBL_ADDRESS + \ + index * UCAST_QUEUE_MAP_TBL_INC, + &value->val); +} +#endif + +sw_error_t +hppe_ucast_queue_map_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union ucast_queue_map_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + UCAST_QUEUE_MAP_TBL_ADDRESS + \ + index * UCAST_QUEUE_MAP_TBL_INC, + value->val); +} + +#ifndef IN_QM_MINI +sw_error_t +hppe_ucast_hash_map_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union ucast_hash_map_tbl_u *value) +{ + if (index >= UCAST_HASH_MAP_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + UCAST_HASH_MAP_TBL_ADDRESS + \ + index * UCAST_HASH_MAP_TBL_INC, + &value->val); +} + +sw_error_t +hppe_ucast_hash_map_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union ucast_hash_map_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + UCAST_HASH_MAP_TBL_ADDRESS + \ + index * UCAST_HASH_MAP_TBL_INC, + value->val); +} + +sw_error_t +hppe_ucast_priority_map_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union ucast_priority_map_tbl_u *value) +{ + if (index >= UCAST_PRIORITY_MAP_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + UCAST_PRIORITY_MAP_TBL_ADDRESS + \ + index * UCAST_PRIORITY_MAP_TBL_INC, + &value->val); +} + +sw_error_t +hppe_ucast_priority_map_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union ucast_priority_map_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + UCAST_PRIORITY_MAP_TBL_ADDRESS + \ + index * UCAST_PRIORITY_MAP_TBL_INC, + value->val); +} + +sw_error_t +hppe_mcast_queue_map_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_queue_map_tbl_u *value) +{ + if (index >= MCAST_QUEUE_MAP_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MCAST_QUEUE_MAP_TBL_ADDRESS + \ + index * MCAST_QUEUE_MAP_TBL_INC, + &value->val); +} + +sw_error_t +hppe_mcast_queue_map_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mcast_queue_map_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MCAST_QUEUE_MAP_TBL_ADDRESS + \ + index * MCAST_QUEUE_MAP_TBL_INC, + value->val); +} + +sw_error_t +hppe_ac_mseq_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union ac_mseq_tbl_u *value) +{ + if (index >= AC_MSEQ_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + AC_MSEQ_TBL_ADDRESS + \ + index * AC_MSEQ_TBL_INC, + &value->val); +} + +sw_error_t +hppe_ac_mseq_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union ac_mseq_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + AC_MSEQ_TBL_ADDRESS + \ + index * AC_MSEQ_TBL_INC, + value->val); +} +#endif + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union ac_uni_queue_cfg_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + AC_UNI_QUEUE_CFG_TBL_ADDRESS + \ + index * AC_UNI_QUEUE_CFG_TBL_INC, + value->val, + 4); +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union ac_uni_queue_cfg_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + AC_UNI_QUEUE_CFG_TBL_ADDRESS + \ + index * AC_UNI_QUEUE_CFG_TBL_INC, + value->val, + 4); +} + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union ac_mul_queue_cfg_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + AC_MUL_QUEUE_CFG_TBL_ADDRESS + \ + index * AC_MUL_QUEUE_CFG_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union ac_mul_queue_cfg_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + AC_MUL_QUEUE_CFG_TBL_ADDRESS + \ + index * AC_MUL_QUEUE_CFG_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_ac_grp_cfg_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union ac_grp_cfg_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + AC_GRP_CFG_TBL_ADDRESS + \ + index * AC_GRP_CFG_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_ac_grp_cfg_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union ac_grp_cfg_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + AC_GRP_CFG_TBL_ADDRESS + \ + index * AC_GRP_CFG_TBL_INC, + value->val, + 3); +} + +#ifndef IN_QM_MINI +sw_error_t +hppe_ac_uni_queue_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union ac_uni_queue_cnt_tbl_u *value) +{ + if (index >= AC_UNI_QUEUE_CNT_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + AC_UNI_QUEUE_CNT_TBL_ADDRESS + \ + index * AC_UNI_QUEUE_CNT_TBL_INC, + &value->val); +} + +sw_error_t +hppe_ac_uni_queue_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union ac_uni_queue_cnt_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + AC_UNI_QUEUE_CNT_TBL_ADDRESS + \ + index * AC_UNI_QUEUE_CNT_TBL_INC, + value->val); +} + +sw_error_t +hppe_ac_mul_queue_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union ac_mul_queue_cnt_tbl_u *value) +{ + if (index >= AC_MUL_QUEUE_CNT_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + AC_MUL_QUEUE_CNT_TBL_ADDRESS + \ + index * AC_MUL_QUEUE_CNT_TBL_INC, + &value->val); +} + +sw_error_t +hppe_ac_mul_queue_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union ac_mul_queue_cnt_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + AC_MUL_QUEUE_CNT_TBL_ADDRESS + \ + index * AC_MUL_QUEUE_CNT_TBL_INC, + value->val); +} + +sw_error_t +hppe_ac_grp_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union ac_grp_cnt_tbl_u *value) +{ + if (index >= AC_GRP_CNT_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + AC_GRP_CNT_TBL_ADDRESS + \ + index * AC_GRP_CNT_TBL_INC, + &value->val); +} + +sw_error_t +hppe_ac_grp_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union ac_grp_cnt_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + AC_GRP_CNT_TBL_ADDRESS + \ + index * AC_GRP_CNT_TBL_INC, + value->val); +} + +sw_error_t +hppe_ac_uni_queue_drop_state_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union ac_uni_queue_drop_state_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + AC_UNI_QUEUE_DROP_STATE_TBL_ADDRESS + \ + index * AC_UNI_QUEUE_DROP_STATE_TBL_INC, + value->val, + 2); +} + +sw_error_t +hppe_ac_uni_queue_drop_state_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union ac_uni_queue_drop_state_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + AC_UNI_QUEUE_DROP_STATE_TBL_ADDRESS + \ + index * AC_UNI_QUEUE_DROP_STATE_TBL_INC, + value->val, + 2); +} + +sw_error_t +hppe_ac_mul_queue_drop_state_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union ac_mul_queue_drop_state_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + AC_MUL_QUEUE_DROP_STATE_TBL_ADDRESS + \ + index * AC_MUL_QUEUE_DROP_STATE_TBL_INC, + value->val, + 2); +} + +sw_error_t +hppe_ac_mul_queue_drop_state_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union ac_mul_queue_drop_state_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + AC_MUL_QUEUE_DROP_STATE_TBL_ADDRESS + \ + index * AC_MUL_QUEUE_DROP_STATE_TBL_INC, + value->val, + 2); +} + +sw_error_t +hppe_ac_grp_drop_state_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union ac_grp_drop_state_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + AC_GRP_DROP_STATE_TBL_ADDRESS + \ + index * AC_GRP_DROP_STATE_TBL_INC, + value->val, + 2); +} + +sw_error_t +hppe_ac_grp_drop_state_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union ac_grp_drop_state_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + AC_GRP_DROP_STATE_TBL_ADDRESS + \ + index * AC_GRP_DROP_STATE_TBL_INC, + value->val, + 2); +} + +sw_error_t +hppe_oq_enq_opr_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union oq_enq_opr_tbl_u *value) +{ + if (index >= OQ_ENQ_OPR_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + OQ_ENQ_OPR_TBL_ADDRESS + \ + index * OQ_ENQ_OPR_TBL_INC, + &value->val); +} +#endif + +sw_error_t +hppe_oq_enq_opr_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union oq_enq_opr_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + OQ_ENQ_OPR_TBL_ADDRESS + \ + index * OQ_ENQ_OPR_TBL_INC, + value->val); +} + +#ifndef IN_QM_MINI +sw_error_t +hppe_oq_deq_opr_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union oq_deq_opr_tbl_u *value) +{ + if (index >= OQ_DEQ_OPR_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + OQ_DEQ_OPR_TBL_ADDRESS + \ + index * OQ_DEQ_OPR_TBL_INC, + &value->val); +} + +sw_error_t +hppe_oq_deq_opr_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union oq_deq_opr_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + OQ_DEQ_OPR_TBL_ADDRESS + \ + index * OQ_DEQ_OPR_TBL_INC, + value->val); +} + +sw_error_t +hppe_oq_head_uni_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union oq_head_uni_tbl_u *value) +{ + if (index >= OQ_HEAD_UNI_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + OQ_HEAD_UNI_TBL_ADDRESS + \ + index * OQ_HEAD_UNI_TBL_INC, + &value->val); +} + +sw_error_t +hppe_oq_head_uni_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union oq_head_uni_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + OQ_HEAD_UNI_TBL_ADDRESS + \ + index * OQ_HEAD_UNI_TBL_INC, + value->val); +} + +sw_error_t +hppe_oq_head_mul_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union oq_head_mul_tbl_u *value) +{ + if (index >= OQ_HEAD_MUL_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + OQ_HEAD_MUL_TBL_ADDRESS + \ + index * OQ_HEAD_MUL_TBL_INC, + &value->val); +} + +sw_error_t +hppe_oq_head_mul_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union oq_head_mul_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + OQ_HEAD_MUL_TBL_ADDRESS + \ + index * OQ_HEAD_MUL_TBL_INC, + value->val); +} + +sw_error_t +hppe_oq_ll_uni_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_uni_tbl_u *value) +{ + if (index >= OQ_LL_UNI_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + OQ_LL_UNI_TBL_ADDRESS + \ + index * OQ_LL_UNI_TBL_INC, + &value->val); +} + +sw_error_t +hppe_oq_ll_uni_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_uni_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + OQ_LL_UNI_TBL_ADDRESS + \ + index * OQ_LL_UNI_TBL_INC, + value->val); +} + +sw_error_t +hppe_oq_ll_mul_p0_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_mul_p0_tbl_u *value) +{ + if (index >= OQ_LL_MUL_P0_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + OQ_LL_MUL_P0_TBL_ADDRESS + \ + index * OQ_LL_MUL_P0_TBL_INC, + &value->val); +} + +sw_error_t +hppe_oq_ll_mul_p0_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_mul_p0_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + OQ_LL_MUL_P0_TBL_ADDRESS + \ + index * OQ_LL_MUL_P0_TBL_INC, + value->val); +} + +sw_error_t +hppe_oq_ll_mul_p1_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_mul_p1_tbl_u *value) +{ + if (index >= OQ_LL_MUL_P1_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + OQ_LL_MUL_P1_TBL_ADDRESS + \ + index * OQ_LL_MUL_P1_TBL_INC, + &value->val); +} + +sw_error_t +hppe_oq_ll_mul_p1_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_mul_p1_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + OQ_LL_MUL_P1_TBL_ADDRESS + \ + index * OQ_LL_MUL_P1_TBL_INC, + value->val); +} + +sw_error_t +hppe_oq_ll_mul_p2_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_mul_p2_tbl_u *value) +{ + if (index >= OQ_LL_MUL_P2_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + OQ_LL_MUL_P2_TBL_ADDRESS + \ + index * OQ_LL_MUL_P2_TBL_INC, + &value->val); +} + +sw_error_t +hppe_oq_ll_mul_p2_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_mul_p2_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + OQ_LL_MUL_P2_TBL_ADDRESS + \ + index * OQ_LL_MUL_P2_TBL_INC, + value->val); +} + +sw_error_t +hppe_oq_ll_mul_p3_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_mul_p3_tbl_u *value) +{ + if (index >= OQ_LL_MUL_P3_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + OQ_LL_MUL_P3_TBL_ADDRESS + \ + index * OQ_LL_MUL_P3_TBL_INC, + &value->val); +} + +sw_error_t +hppe_oq_ll_mul_p3_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_mul_p3_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + OQ_LL_MUL_P3_TBL_ADDRESS + \ + index * OQ_LL_MUL_P3_TBL_INC, + value->val); +} + +sw_error_t +hppe_oq_ll_mul_p4_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_mul_p4_tbl_u *value) +{ + if (index >= OQ_LL_MUL_P4_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + OQ_LL_MUL_P4_TBL_ADDRESS + \ + index * OQ_LL_MUL_P4_TBL_INC, + &value->val); +} + +sw_error_t +hppe_oq_ll_mul_p4_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_mul_p4_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + OQ_LL_MUL_P4_TBL_ADDRESS + \ + index * OQ_LL_MUL_P4_TBL_INC, + value->val); +} + +sw_error_t +hppe_oq_ll_mul_p5_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_mul_p5_tbl_u *value) +{ + if (index >= OQ_LL_MUL_P5_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + OQ_LL_MUL_P5_TBL_ADDRESS + \ + index * OQ_LL_MUL_P5_TBL_INC, + &value->val); +} + +sw_error_t +hppe_oq_ll_mul_p5_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_mul_p5_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + OQ_LL_MUL_P5_TBL_ADDRESS + \ + index * OQ_LL_MUL_P5_TBL_INC, + value->val); +} + +sw_error_t +hppe_oq_ll_mul_p6_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_mul_p6_tbl_u *value) +{ + if (index >= OQ_LL_MUL_P6_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + OQ_LL_MUL_P6_TBL_ADDRESS + \ + index * OQ_LL_MUL_P6_TBL_INC, + &value->val); +} + +sw_error_t +hppe_oq_ll_mul_p6_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_mul_p6_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + OQ_LL_MUL_P6_TBL_ADDRESS + \ + index * OQ_LL_MUL_P6_TBL_INC, + value->val); +} + +sw_error_t +hppe_oq_ll_mul_p7_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_mul_p7_tbl_u *value) +{ + if (index >= OQ_LL_MUL_P7_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + OQ_LL_MUL_P7_TBL_ADDRESS + \ + index * OQ_LL_MUL_P7_TBL_INC, + &value->val); +} + +sw_error_t +hppe_oq_ll_mul_p7_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union oq_ll_mul_p7_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + OQ_LL_MUL_P7_TBL_ADDRESS + \ + index * OQ_LL_MUL_P7_TBL_INC, + value->val); +} + +sw_error_t +hppe_pkt_desp_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union pkt_desp_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + PKT_DESP_TBL_ADDRESS + \ + index * PKT_DESP_TBL_INC, + value->val, + 13); +} + +sw_error_t +hppe_pkt_desp_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union pkt_desp_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + PKT_DESP_TBL_ADDRESS + \ + index * PKT_DESP_TBL_INC, + value->val, + 13); +} + +sw_error_t +hppe_uni_drop_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union uni_drop_cnt_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + UNI_DROP_CNT_TBL_ADDRESS + \ + index * UNI_DROP_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_uni_drop_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union uni_drop_cnt_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + UNI_DROP_CNT_TBL_ADDRESS + \ + index * UNI_DROP_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_mul_p0_drop_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mul_p0_drop_cnt_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MUL_P0_DROP_CNT_TBL_ADDRESS + \ + index * MUL_P0_DROP_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_mul_p0_drop_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mul_p0_drop_cnt_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MUL_P0_DROP_CNT_TBL_ADDRESS + \ + index * MUL_P0_DROP_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_mul_p1_drop_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mul_p1_drop_cnt_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MUL_P1_DROP_CNT_TBL_ADDRESS + \ + index * MUL_P1_DROP_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_mul_p1_drop_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mul_p1_drop_cnt_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MUL_P1_DROP_CNT_TBL_ADDRESS + \ + index * MUL_P1_DROP_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_mul_p2_drop_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mul_p2_drop_cnt_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MUL_P2_DROP_CNT_TBL_ADDRESS + \ + index * MUL_P2_DROP_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_mul_p2_drop_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mul_p2_drop_cnt_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MUL_P2_DROP_CNT_TBL_ADDRESS + \ + index * MUL_P2_DROP_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_mul_p3_drop_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mul_p3_drop_cnt_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MUL_P3_DROP_CNT_TBL_ADDRESS + \ + index * MUL_P3_DROP_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_mul_p3_drop_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mul_p3_drop_cnt_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MUL_P3_DROP_CNT_TBL_ADDRESS + \ + index * MUL_P3_DROP_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_mul_p4_drop_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mul_p4_drop_cnt_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MUL_P4_DROP_CNT_TBL_ADDRESS + \ + index * MUL_P4_DROP_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_mul_p4_drop_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mul_p4_drop_cnt_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MUL_P4_DROP_CNT_TBL_ADDRESS + \ + index * MUL_P4_DROP_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_mul_p5_drop_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mul_p5_drop_cnt_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MUL_P5_DROP_CNT_TBL_ADDRESS + \ + index * MUL_P5_DROP_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_mul_p5_drop_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mul_p5_drop_cnt_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MUL_P5_DROP_CNT_TBL_ADDRESS + \ + index * MUL_P5_DROP_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_mul_p6_drop_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mul_p6_drop_cnt_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MUL_P6_DROP_CNT_TBL_ADDRESS + \ + index * MUL_P6_DROP_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_mul_p6_drop_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mul_p6_drop_cnt_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MUL_P6_DROP_CNT_TBL_ADDRESS + \ + index * MUL_P6_DROP_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_mul_p7_drop_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mul_p7_drop_cnt_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MUL_P7_DROP_CNT_TBL_ADDRESS + \ + index * MUL_P7_DROP_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_mul_p7_drop_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mul_p7_drop_cnt_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + MUL_P7_DROP_CNT_TBL_ADDRESS + \ + index * MUL_P7_DROP_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_uq_agg_profile_map_get( + a_uint32_t dev_id, + a_uint32_t index, + union uq_agg_profile_map_u *value) +{ + if (index >= UQ_AGG_PROFILE_MAP_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + QUEUE_MANAGER_BASE_ADDR + UQ_AGG_PROFILE_MAP_ADDRESS + \ + index * UQ_AGG_PROFILE_MAP_INC, + &value->val); +} + +sw_error_t +hppe_uq_agg_profile_map_set( + a_uint32_t dev_id, + a_uint32_t index, + union uq_agg_profile_map_u *value) +{ + return hppe_reg_set( + dev_id, + QUEUE_MANAGER_BASE_ADDR + UQ_AGG_PROFILE_MAP_ADDRESS + \ + index * UQ_AGG_PROFILE_MAP_INC, + value->val); +} + +sw_error_t +hppe_flush_cfg_flush_busy_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flush_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flush_cfg_get(dev_id, ®_val); + *value = reg_val.bf.flush_busy; + return ret; +} + +sw_error_t +hppe_flush_cfg_flush_busy_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union flush_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flush_cfg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flush_busy = value; + ret = hppe_flush_cfg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_flush_cfg_flush_qid_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flush_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flush_cfg_get(dev_id, ®_val); + *value = reg_val.bf.flush_qid; + return ret; +} + +sw_error_t +hppe_flush_cfg_flush_qid_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union flush_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flush_cfg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flush_qid = value; + ret = hppe_flush_cfg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_flush_cfg_flush_dst_port_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flush_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flush_cfg_get(dev_id, ®_val); + *value = reg_val.bf.flush_dst_port; + return ret; +} + +sw_error_t +hppe_flush_cfg_flush_dst_port_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union flush_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flush_cfg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flush_dst_port = value; + ret = hppe_flush_cfg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_flush_cfg_flush_all_queues_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flush_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flush_cfg_get(dev_id, ®_val); + *value = reg_val.bf.flush_all_queues; + return ret; +} + +sw_error_t +hppe_flush_cfg_flush_all_queues_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union flush_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flush_cfg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flush_all_queues = value; + ret = hppe_flush_cfg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_flush_cfg_flush_wt_time_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flush_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flush_cfg_get(dev_id, ®_val); + *value = reg_val.bf.flush_wt_time; + return ret; +} + +sw_error_t +hppe_flush_cfg_flush_wt_time_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union flush_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flush_cfg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flush_wt_time = value; + ret = hppe_flush_cfg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_flush_cfg_flush_status_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union flush_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flush_cfg_get(dev_id, ®_val); + *value = reg_val.bf.flush_status; + return ret; +} + +sw_error_t +hppe_flush_cfg_flush_status_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union flush_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flush_cfg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flush_status = value; + ret = hppe_flush_cfg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_in_mirror_priority_ctrl_priority_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union in_mirror_priority_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_mirror_priority_ctrl_get(dev_id, ®_val); + *value = reg_val.bf.priority; + return ret; +} + +sw_error_t +hppe_in_mirror_priority_ctrl_priority_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union in_mirror_priority_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_mirror_priority_ctrl_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.priority = value; + ret = hppe_in_mirror_priority_ctrl_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_eg_mirror_priority_ctrl_priority_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union eg_mirror_priority_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_mirror_priority_ctrl_get(dev_id, ®_val); + *value = reg_val.bf.priority; + return ret; +} + +sw_error_t +hppe_eg_mirror_priority_ctrl_priority_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union eg_mirror_priority_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_mirror_priority_ctrl_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.priority = value; + ret = hppe_eg_mirror_priority_ctrl_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_ucast_default_hash_hash_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union ucast_default_hash_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ucast_default_hash_get(dev_id, ®_val); + *value = reg_val.bf.hash; + return ret; +} + +sw_error_t +hppe_ucast_default_hash_hash_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union ucast_default_hash_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ucast_default_hash_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.hash = value; + ret = hppe_ucast_default_hash_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_spare_reg0_spare_reg0_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union spare_reg0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_spare_reg0_get(dev_id, ®_val); + *value = reg_val.bf.spare_reg0; + return ret; +} + +sw_error_t +hppe_spare_reg0_spare_reg0_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union spare_reg0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_spare_reg0_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.spare_reg0 = value; + ret = hppe_spare_reg0_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_spare_reg1_spare_reg1_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union spare_reg1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_spare_reg1_get(dev_id, ®_val); + *value = reg_val.bf.spare_reg1; + return ret; +} + +sw_error_t +hppe_spare_reg1_spare_reg1_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union spare_reg1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_spare_reg1_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.spare_reg1 = value; + ret = hppe_spare_reg1_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_qm_dbg_addr_dbg_addr_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union qm_dbg_addr_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_qm_dbg_addr_get(dev_id, ®_val); + *value = reg_val.bf.dbg_addr; + return ret; +} + +sw_error_t +hppe_qm_dbg_addr_dbg_addr_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union qm_dbg_addr_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_qm_dbg_addr_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.dbg_addr = value; + ret = hppe_qm_dbg_addr_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_qm_dbg_data_dbg_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union qm_dbg_data_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_qm_dbg_data_get(dev_id, ®_val); + *value = reg_val.bf.dbg_data; + return ret; +} + +sw_error_t +hppe_qm_dbg_data_dbg_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mcast_priority_map0_class_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mcast_priority_map0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mcast_priority_map0_get(dev_id, index, ®_val); + *value = reg_val.bf.class; + return ret; +} + +sw_error_t +hppe_mcast_priority_map0_class_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mcast_priority_map0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mcast_priority_map0_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.class = value; + ret = hppe_mcast_priority_map0_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mcast_priority_map1_class_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mcast_priority_map1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mcast_priority_map1_get(dev_id, index, ®_val); + *value = reg_val.bf.class; + return ret; +} + +sw_error_t +hppe_mcast_priority_map1_class_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mcast_priority_map1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mcast_priority_map1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.class = value; + ret = hppe_mcast_priority_map1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mcast_priority_map2_class_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mcast_priority_map2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mcast_priority_map2_get(dev_id, index, ®_val); + *value = reg_val.bf.class; + return ret; +} + +sw_error_t +hppe_mcast_priority_map2_class_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mcast_priority_map2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mcast_priority_map2_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.class = value; + ret = hppe_mcast_priority_map2_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mcast_priority_map3_class_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mcast_priority_map3_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mcast_priority_map3_get(dev_id, index, ®_val); + *value = reg_val.bf.class; + return ret; +} + +sw_error_t +hppe_mcast_priority_map3_class_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mcast_priority_map3_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mcast_priority_map3_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.class = value; + ret = hppe_mcast_priority_map3_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mcast_priority_map4_class_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mcast_priority_map4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mcast_priority_map4_get(dev_id, index, ®_val); + *value = reg_val.bf.class; + return ret; +} + +sw_error_t +hppe_mcast_priority_map4_class_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mcast_priority_map4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mcast_priority_map4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.class = value; + ret = hppe_mcast_priority_map4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mcast_priority_map5_class_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mcast_priority_map5_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mcast_priority_map5_get(dev_id, index, ®_val); + *value = reg_val.bf.class; + return ret; +} + +sw_error_t +hppe_mcast_priority_map5_class_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mcast_priority_map5_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mcast_priority_map5_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.class = value; + ret = hppe_mcast_priority_map5_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mcast_priority_map6_class_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mcast_priority_map6_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mcast_priority_map6_get(dev_id, index, ®_val); + *value = reg_val.bf.class; + return ret; +} + +sw_error_t +hppe_mcast_priority_map6_class_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mcast_priority_map6_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mcast_priority_map6_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.class = value; + ret = hppe_mcast_priority_map6_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mcast_priority_map7_class_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mcast_priority_map7_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mcast_priority_map7_get(dev_id, index, ®_val); + *value = reg_val.bf.class; + return ret; +} + +sw_error_t +hppe_mcast_priority_map7_class_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mcast_priority_map7_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mcast_priority_map7_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.class = value; + ret = hppe_mcast_priority_map7_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_mq_p2_en_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.mq_p2_en; + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_mq_p2_en_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mq_p2_en = value; + ret = hppe_agg_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_uq_en_1_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.uq_en_1; + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_uq_en_1_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.uq_en_1 = value; + ret = hppe_agg_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_mq_p0_en_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.mq_p0_en; + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_mq_p0_en_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mq_p0_en = value; + ret = hppe_agg_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_grp_1_en_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.grp_1_en; + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_grp_1_en_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.grp_1_en = value; + ret = hppe_agg_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_grp_0_en_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.grp_0_en; + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_grp_0_en_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.grp_0_en = value; + ret = hppe_agg_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_mq_p6_en_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.mq_p6_en; + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_mq_p6_en_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mq_p6_en = value; + ret = hppe_agg_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_uq_en_3_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.uq_en_3; + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_uq_en_3_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.uq_en_3 = value; + ret = hppe_agg_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_mq_p4_en_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.mq_p4_en; + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_mq_p4_en_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mq_p4_en = value; + ret = hppe_agg_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_uq_en_2_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.uq_en_2; + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_uq_en_2_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.uq_en_2 = value; + ret = hppe_agg_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_uq_en_5_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.uq_en_5; + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_uq_en_5_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.uq_en_5 = value; + ret = hppe_agg_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_uq_en_6_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.uq_en_6; + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_uq_en_6_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.uq_en_6 = value; + ret = hppe_agg_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_grp_3_en_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.grp_3_en; + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_grp_3_en_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.grp_3_en = value; + ret = hppe_agg_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_grp_2_en_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.grp_2_en; + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_grp_2_en_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.grp_2_en = value; + ret = hppe_agg_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_uq_en_4_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.uq_en_4; + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_uq_en_4_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.uq_en_4 = value; + ret = hppe_agg_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_mq_p7_en_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.mq_p7_en; + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_mq_p7_en_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mq_p7_en = value; + ret = hppe_agg_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_uq_en_7_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.uq_en_7; + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_uq_en_7_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.uq_en_7 = value; + ret = hppe_agg_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_global_en_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.global_en; + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_global_en_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.global_en = value; + ret = hppe_agg_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_mq_p5_en_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.mq_p5_en; + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_mq_p5_en_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mq_p5_en = value; + ret = hppe_agg_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_mq_p1_en_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.mq_p1_en; + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_mq_p1_en_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mq_p1_en = value; + ret = hppe_agg_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_uq_en_0_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.uq_en_0; + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_uq_en_0_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.uq_en_0 = value; + ret = hppe_agg_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_mq_p3_en_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + *value = reg_val.bf.mq_p3_en; + return ret; +} + +sw_error_t +hppe_agg_profile_cnt_en_mq_p3_en_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union agg_profile_cnt_en_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_agg_profile_cnt_en_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mq_p3_en = value; + ret = hppe_agg_profile_cnt_en_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_uq_agg_profile_cfg_th_cfg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uq_agg_profile_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uq_agg_profile_cfg_get(dev_id, index, ®_val); + *value = reg_val.bf.th_cfg; + return ret; +} + +sw_error_t +hppe_uq_agg_profile_cfg_th_cfg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uq_agg_profile_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uq_agg_profile_cfg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.th_cfg = value; + ret = hppe_uq_agg_profile_cfg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mq_agg_profile_cfg_th_cfg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mq_agg_profile_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mq_agg_profile_cfg_get(dev_id, index, ®_val); + *value = reg_val.bf.th_cfg; + return ret; +} + +sw_error_t +hppe_mq_agg_profile_cfg_th_cfg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mq_agg_profile_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mq_agg_profile_cfg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.th_cfg = value; + ret = hppe_mq_agg_profile_cfg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_grp_agg_profile_cfg_th_cfg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union grp_agg_profile_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_grp_agg_profile_cfg_get(dev_id, index, ®_val); + *value = reg_val.bf.th_cfg; + return ret; +} + +sw_error_t +hppe_grp_agg_profile_cfg_th_cfg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union grp_agg_profile_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_grp_agg_profile_cfg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.th_cfg = value; + ret = hppe_grp_agg_profile_cfg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uq_agg_in_profile_cnt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uq_agg_in_profile_cnt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uq_agg_in_profile_cnt_get(dev_id, index, ®_val); + *value = reg_val.bf.cnt; + return ret; +} + +sw_error_t +hppe_uq_agg_in_profile_cnt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uq_agg_in_profile_cnt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uq_agg_in_profile_cnt_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cnt = value; + ret = hppe_uq_agg_in_profile_cnt_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uq_agg_out_profile_cnt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uq_agg_out_profile_cnt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uq_agg_out_profile_cnt_get(dev_id, index, ®_val); + *value = reg_val.bf.cnt; + return ret; +} + +sw_error_t +hppe_uq_agg_out_profile_cnt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uq_agg_out_profile_cnt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uq_agg_out_profile_cnt_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cnt = value; + ret = hppe_uq_agg_out_profile_cnt_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mq_agg_in_profile_cnt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mq_agg_in_profile_cnt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mq_agg_in_profile_cnt_get(dev_id, index, ®_val); + *value = reg_val.bf.cnt; + return ret; +} + +sw_error_t +hppe_mq_agg_in_profile_cnt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mq_agg_in_profile_cnt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mq_agg_in_profile_cnt_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cnt = value; + ret = hppe_mq_agg_in_profile_cnt_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mq_agg_out_profile_cnt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mq_agg_out_profile_cnt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mq_agg_out_profile_cnt_get(dev_id, index, ®_val); + *value = reg_val.bf.cnt; + return ret; +} + +sw_error_t +hppe_mq_agg_out_profile_cnt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mq_agg_out_profile_cnt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mq_agg_out_profile_cnt_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cnt = value; + ret = hppe_mq_agg_out_profile_cnt_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_grp_agg_in_profile_cnt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union grp_agg_in_profile_cnt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_grp_agg_in_profile_cnt_get(dev_id, index, ®_val); + *value = reg_val.bf.cnt; + return ret; +} + +sw_error_t +hppe_grp_agg_in_profile_cnt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union grp_agg_in_profile_cnt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_grp_agg_in_profile_cnt_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cnt = value; + ret = hppe_grp_agg_in_profile_cnt_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_grp_agg_out_profile_cnt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union grp_agg_out_profile_cnt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_grp_agg_out_profile_cnt_get(dev_id, index, ®_val); + *value = reg_val.bf.cnt; + return ret; +} + +sw_error_t +hppe_grp_agg_out_profile_cnt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union grp_agg_out_profile_cnt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_grp_agg_out_profile_cnt_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cnt = value; + ret = hppe_grp_agg_out_profile_cnt_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ucast_queue_map_tbl_profile_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ucast_queue_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ucast_queue_map_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.profile_id; + return ret; +} + +sw_error_t +hppe_ucast_queue_map_tbl_profile_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ucast_queue_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ucast_queue_map_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.profile_id = value; + ret = hppe_ucast_queue_map_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ucast_queue_map_tbl_queue_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ucast_queue_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ucast_queue_map_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.queue_id; + return ret; +} + +sw_error_t +hppe_ucast_queue_map_tbl_queue_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ucast_queue_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ucast_queue_map_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.queue_id = value; + ret = hppe_ucast_queue_map_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ucast_hash_map_tbl_hash_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ucast_hash_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ucast_hash_map_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.hash; + return ret; +} + +sw_error_t +hppe_ucast_hash_map_tbl_hash_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ucast_hash_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ucast_hash_map_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.hash = value; + ret = hppe_ucast_hash_map_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ucast_priority_map_tbl_class_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ucast_priority_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ucast_priority_map_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.class; + return ret; +} + +sw_error_t +hppe_ucast_priority_map_tbl_class_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ucast_priority_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ucast_priority_map_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.class = value; + ret = hppe_ucast_priority_map_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mcast_queue_map_tbl_class_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mcast_queue_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mcast_queue_map_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.class; + return ret; +} + +sw_error_t +hppe_mcast_queue_map_tbl_class_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mcast_queue_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mcast_queue_map_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.class = value; + ret = hppe_mcast_queue_map_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_mseq_tbl_ac_mseq_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_mseq_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mseq_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_mseq; + return ret; +} + +sw_error_t +hppe_ac_mseq_tbl_ac_mseq_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_mseq_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mseq_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_mseq = value; + ret = hppe_ac_mseq_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_gap_grn_yel_max_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_uni_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_cfg_gap_grn_yel_max; + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_gap_grn_yel_max_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_uni_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_cfg_gap_grn_yel_max = value; + ret = hppe_ac_uni_queue_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_wred_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_uni_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_cfg_wred_en; + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_wred_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_uni_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_cfg_wred_en = value; + ret = hppe_ac_uni_queue_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_ac_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_uni_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_cfg_ac_en; + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_ac_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_uni_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_cfg_ac_en = value; + ret = hppe_ac_uni_queue_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_red_resume_offset_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_uni_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_cfg_red_resume_offset_1 << 9 | \ + reg_val.bf.ac_cfg_red_resume_offset_0; + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_red_resume_offset_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_uni_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_cfg_red_resume_offset_1 = value >> 9; + reg_val.bf.ac_cfg_red_resume_offset_0 = value & (((a_uint64_t)1<<9)-1); + ret = hppe_ac_uni_queue_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_grp_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_uni_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_cfg_grp_id; + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_grp_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_uni_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_cfg_grp_id = value; + ret = hppe_ac_uni_queue_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_color_aware_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_uni_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_cfg_color_aware; + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_color_aware_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_uni_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_cfg_color_aware = value; + ret = hppe_ac_uni_queue_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_yel_resume_offset_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_uni_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_cfg_yel_resume_offset; + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_yel_resume_offset_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_uni_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_cfg_yel_resume_offset = value; + ret = hppe_ac_uni_queue_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_gap_grn_yel_min_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_uni_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_cfg_gap_grn_yel_min_1 << 10 | \ + reg_val.bf.ac_cfg_gap_grn_yel_min_0; + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_gap_grn_yel_min_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_uni_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_cfg_gap_grn_yel_min_1 = value >> 10; + reg_val.bf.ac_cfg_gap_grn_yel_min_0 = value & (((a_uint64_t)1<<10)-1); + ret = hppe_ac_uni_queue_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_shared_weight_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_uni_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_cfg_shared_weight; + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_shared_weight_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_uni_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_cfg_shared_weight = value; + ret = hppe_ac_uni_queue_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_shared_dynamic_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_uni_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_cfg_shared_dynamic; + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_shared_dynamic_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_uni_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_cfg_shared_dynamic = value; + ret = hppe_ac_uni_queue_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_gap_grn_red_max_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_uni_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_cfg_gap_grn_red_max; + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_gap_grn_red_max_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_uni_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_cfg_gap_grn_red_max = value; + ret = hppe_ac_uni_queue_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_pre_alloc_limit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_uni_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_cfg_pre_alloc_limit; + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_pre_alloc_limit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_uni_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_cfg_pre_alloc_limit = value; + ret = hppe_ac_uni_queue_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_force_ac_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_uni_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_cfg_force_ac_en; + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_force_ac_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_uni_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_cfg_force_ac_en = value; + ret = hppe_ac_uni_queue_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_gap_grn_red_min_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_uni_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_cfg_gap_grn_red_min; + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_gap_grn_red_min_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_uni_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_cfg_gap_grn_red_min = value; + ret = hppe_ac_uni_queue_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_gap_grn_grn_min_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_uni_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_cfg_gap_grn_grn_min; + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_gap_grn_grn_min_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_uni_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_cfg_gap_grn_grn_min = value; + ret = hppe_ac_uni_queue_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_shared_ceiling_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_uni_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_cfg_shared_ceiling; + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_shared_ceiling_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_uni_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_cfg_shared_ceiling = value; + ret = hppe_ac_uni_queue_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_grn_resume_offset_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_uni_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_cfg_grn_resume_offset; + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cfg_tbl_ac_cfg_grn_resume_offset_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_uni_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_cfg_grn_resume_offset = value; + ret = hppe_ac_uni_queue_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_ac_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_mul_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_cfg_ac_en; + return ret; +} + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_ac_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_mul_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_cfg_ac_en = value; + ret = hppe_ac_mul_queue_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_red_resume_offset_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_mul_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_cfg_red_resume_offset; + return ret; +} + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_red_resume_offset_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_mul_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_cfg_red_resume_offset = value; + ret = hppe_ac_mul_queue_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_grp_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_mul_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_cfg_grp_id; + return ret; +} + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_grp_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_mul_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_cfg_grp_id = value; + ret = hppe_ac_mul_queue_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_color_aware_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_mul_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_cfg_color_aware; + return ret; +} + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_color_aware_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_mul_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_cfg_color_aware = value; + ret = hppe_ac_mul_queue_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_yel_resume_offset_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_mul_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_cfg_yel_resume_offset_1 << 4 | \ + reg_val.bf.ac_cfg_yel_resume_offset_0; + return ret; +} + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_yel_resume_offset_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_mul_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_cfg_yel_resume_offset_1 = value >> 4; + reg_val.bf.ac_cfg_yel_resume_offset_0 = value & (((a_uint64_t)1<<4)-1); + ret = hppe_ac_mul_queue_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_pre_alloc_limit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_mul_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_cfg_pre_alloc_limit; + return ret; +} + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_pre_alloc_limit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_mul_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_cfg_pre_alloc_limit = value; + ret = hppe_ac_mul_queue_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_force_ac_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_mul_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_cfg_force_ac_en; + return ret; +} + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_force_ac_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_mul_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_cfg_force_ac_en = value; + ret = hppe_ac_mul_queue_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_shared_ceiling_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_mul_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_cfg_shared_ceiling; + return ret; +} + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_shared_ceiling_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_mul_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_cfg_shared_ceiling = value; + ret = hppe_ac_mul_queue_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_grn_resume_offset_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_mul_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_cfg_grn_resume_offset; + return ret; +} + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_grn_resume_offset_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_mul_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_cfg_grn_resume_offset = value; + ret = hppe_ac_mul_queue_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_gap_grn_yel_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_mul_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_cfg_gap_grn_yel_1 << 5 | \ + reg_val.bf.ac_cfg_gap_grn_yel_0; + return ret; +} + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_gap_grn_yel_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_mul_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_cfg_gap_grn_yel_1 = value >> 5; + reg_val.bf.ac_cfg_gap_grn_yel_0 = value & (((a_uint64_t)1<<5)-1); + ret = hppe_ac_mul_queue_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_gap_grn_red_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_mul_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_cfg_gap_grn_red; + return ret; +} + +sw_error_t +hppe_ac_mul_queue_cfg_tbl_ac_cfg_gap_grn_red_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_mul_queue_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_cfg_gap_grn_red = value; + ret = hppe_ac_mul_queue_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_grp_grn_resume_offset_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_grp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_grp_grn_resume_offset; + return ret; +} + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_grp_grn_resume_offset_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_grp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_grp_grn_resume_offset = value; + ret = hppe_ac_grp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_grp_dp_thrd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_grp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_grp_dp_thrd_1 << 7 | \ + reg_val.bf.ac_grp_dp_thrd_0; + return ret; +} + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_grp_dp_thrd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_grp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_grp_dp_thrd_1 = value >> 7; + reg_val.bf.ac_grp_dp_thrd_0 = value & (((a_uint64_t)1<<7)-1); + ret = hppe_ac_grp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_cfg_ac_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_grp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_cfg_ac_en; + return ret; +} + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_cfg_ac_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_grp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_cfg_ac_en = value; + ret = hppe_ac_grp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_grp_palloc_limit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_grp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_grp_palloc_limit; + return ret; +} + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_grp_palloc_limit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_grp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_grp_palloc_limit = value; + ret = hppe_ac_grp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_cfg_color_aware_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_grp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_cfg_color_aware; + return ret; +} + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_cfg_color_aware_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_grp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_cfg_color_aware = value; + ret = hppe_ac_grp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_grp_red_resume_offset_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_grp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_grp_red_resume_offset; + return ret; +} + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_grp_red_resume_offset_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_grp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_grp_red_resume_offset = value; + ret = hppe_ac_grp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_grp_gap_grn_yel_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_grp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_grp_gap_grn_yel; + return ret; +} + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_grp_gap_grn_yel_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_grp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_grp_gap_grn_yel = value; + ret = hppe_ac_grp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_cfg_force_ac_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_grp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_cfg_force_ac_en; + return ret; +} + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_cfg_force_ac_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_grp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_cfg_force_ac_en = value; + ret = hppe_ac_grp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_grp_yel_resume_offset_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_grp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_grp_yel_resume_offset_1 << 6 | \ + reg_val.bf.ac_grp_yel_resume_offset_0; + return ret; +} + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_grp_yel_resume_offset_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_grp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_grp_yel_resume_offset_1 = value >> 6; + reg_val.bf.ac_grp_yel_resume_offset_0 = value & (((a_uint64_t)1<<6)-1); + ret = hppe_ac_grp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_grp_gap_grn_red_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_grp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_grp_gap_grn_red; + return ret; +} + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_grp_gap_grn_red_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_grp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_grp_gap_grn_red = value; + ret = hppe_ac_grp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_grp_limit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_grp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_grp_limit; + return ret; +} + +sw_error_t +hppe_ac_grp_cfg_tbl_ac_grp_limit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_grp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_grp_limit = value; + ret = hppe_ac_grp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cnt_tbl_ac_uni_queue_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_uni_queue_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cnt_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_uni_queue_cnt; + return ret; +} + +sw_error_t +hppe_ac_uni_queue_cnt_tbl_ac_uni_queue_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_uni_queue_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_uni_queue_cnt = value; + ret = hppe_ac_uni_queue_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_mul_queue_cnt_tbl_ac_mul_queue_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_mul_queue_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_cnt_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_mul_queue_cnt; + return ret; +} + +sw_error_t +hppe_ac_mul_queue_cnt_tbl_ac_mul_queue_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_mul_queue_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_mul_queue_cnt = value; + ret = hppe_ac_mul_queue_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_grp_cnt_tbl_ac_grp_alloc_used_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_grp_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_cnt_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_grp_alloc_used; + return ret; +} + +sw_error_t +hppe_ac_grp_cnt_tbl_ac_grp_alloc_used_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_grp_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_grp_alloc_used = value; + ret = hppe_ac_grp_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_grp_cnt_tbl_ac_grp_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_grp_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_cnt_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ac_grp_cnt; + return ret; +} + +sw_error_t +hppe_ac_grp_cnt_tbl_ac_grp_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_grp_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ac_grp_cnt = value; + ret = hppe_ac_grp_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_uni_queue_drop_state_tbl_red_resume_thrd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_uni_queue_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_drop_state_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.red_resume_thrd; + return ret; +} + +sw_error_t +hppe_ac_uni_queue_drop_state_tbl_red_resume_thrd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_uni_queue_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_drop_state_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.red_resume_thrd = value; + ret = hppe_ac_uni_queue_drop_state_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_uni_queue_drop_state_tbl_red_drop_state_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_uni_queue_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_drop_state_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.red_drop_state; + return ret; +} + +sw_error_t +hppe_ac_uni_queue_drop_state_tbl_red_drop_state_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_uni_queue_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_drop_state_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.red_drop_state = value; + ret = hppe_ac_uni_queue_drop_state_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_uni_queue_drop_state_tbl_yel_resume_thrd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_uni_queue_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_drop_state_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.yel_resume_thrd; + return ret; +} + +sw_error_t +hppe_ac_uni_queue_drop_state_tbl_yel_resume_thrd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_uni_queue_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_drop_state_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.yel_resume_thrd = value; + ret = hppe_ac_uni_queue_drop_state_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_uni_queue_drop_state_tbl_grn_drop_state_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_uni_queue_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_drop_state_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.grn_drop_state; + return ret; +} + +sw_error_t +hppe_ac_uni_queue_drop_state_tbl_grn_drop_state_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_uni_queue_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_drop_state_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.grn_drop_state = value; + ret = hppe_ac_uni_queue_drop_state_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_uni_queue_drop_state_tbl_yel_drop_state_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_uni_queue_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_drop_state_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.yel_drop_state; + return ret; +} + +sw_error_t +hppe_ac_uni_queue_drop_state_tbl_yel_drop_state_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_uni_queue_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_drop_state_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.yel_drop_state = value; + ret = hppe_ac_uni_queue_drop_state_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_uni_queue_drop_state_tbl_grn_resume_thrd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_uni_queue_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_drop_state_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.grn_resume_thrd_1 << 10 | \ + reg_val.bf.grn_resume_thrd_0; + return ret; +} + +sw_error_t +hppe_ac_uni_queue_drop_state_tbl_grn_resume_thrd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_uni_queue_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_uni_queue_drop_state_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.grn_resume_thrd_1 = value >> 10; + reg_val.bf.grn_resume_thrd_0 = value & (((a_uint64_t)1<<10)-1); + ret = hppe_ac_uni_queue_drop_state_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_mul_queue_drop_state_tbl_red_resume_thrd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_mul_queue_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_drop_state_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.red_resume_thrd; + return ret; +} + +sw_error_t +hppe_ac_mul_queue_drop_state_tbl_red_resume_thrd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_mul_queue_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_drop_state_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.red_resume_thrd = value; + ret = hppe_ac_mul_queue_drop_state_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_mul_queue_drop_state_tbl_red_drop_state_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_mul_queue_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_drop_state_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.red_drop_state; + return ret; +} + +sw_error_t +hppe_ac_mul_queue_drop_state_tbl_red_drop_state_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_mul_queue_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_drop_state_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.red_drop_state = value; + ret = hppe_ac_mul_queue_drop_state_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_mul_queue_drop_state_tbl_yel_resume_thrd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_mul_queue_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_drop_state_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.yel_resume_thrd; + return ret; +} + +sw_error_t +hppe_ac_mul_queue_drop_state_tbl_yel_resume_thrd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_mul_queue_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_drop_state_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.yel_resume_thrd = value; + ret = hppe_ac_mul_queue_drop_state_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_mul_queue_drop_state_tbl_grn_drop_state_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_mul_queue_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_drop_state_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.grn_drop_state; + return ret; +} + +sw_error_t +hppe_ac_mul_queue_drop_state_tbl_grn_drop_state_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_mul_queue_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_drop_state_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.grn_drop_state = value; + ret = hppe_ac_mul_queue_drop_state_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_mul_queue_drop_state_tbl_yel_drop_state_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_mul_queue_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_drop_state_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.yel_drop_state; + return ret; +} + +sw_error_t +hppe_ac_mul_queue_drop_state_tbl_yel_drop_state_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_mul_queue_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_drop_state_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.yel_drop_state = value; + ret = hppe_ac_mul_queue_drop_state_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_mul_queue_drop_state_tbl_grn_resume_thrd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_mul_queue_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_drop_state_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.grn_resume_thrd_1 << 10 | \ + reg_val.bf.grn_resume_thrd_0; + return ret; +} + +sw_error_t +hppe_ac_mul_queue_drop_state_tbl_grn_resume_thrd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_mul_queue_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_mul_queue_drop_state_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.grn_resume_thrd_1 = value >> 10; + reg_val.bf.grn_resume_thrd_0 = value & (((a_uint64_t)1<<10)-1); + ret = hppe_ac_mul_queue_drop_state_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_grp_drop_state_tbl_red_resume_thrd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_grp_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_drop_state_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.red_resume_thrd; + return ret; +} + +sw_error_t +hppe_ac_grp_drop_state_tbl_red_resume_thrd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_grp_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_drop_state_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.red_resume_thrd = value; + ret = hppe_ac_grp_drop_state_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_grp_drop_state_tbl_red_drop_state_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_grp_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_drop_state_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.red_drop_state; + return ret; +} + +sw_error_t +hppe_ac_grp_drop_state_tbl_red_drop_state_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_grp_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_drop_state_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.red_drop_state = value; + ret = hppe_ac_grp_drop_state_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_grp_drop_state_tbl_yel_resume_thrd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_grp_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_drop_state_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.yel_resume_thrd; + return ret; +} + +sw_error_t +hppe_ac_grp_drop_state_tbl_yel_resume_thrd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_grp_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_drop_state_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.yel_resume_thrd = value; + ret = hppe_ac_grp_drop_state_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_grp_drop_state_tbl_grn_drop_state_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_grp_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_drop_state_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.grn_drop_state; + return ret; +} + +sw_error_t +hppe_ac_grp_drop_state_tbl_grn_drop_state_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_grp_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_drop_state_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.grn_drop_state = value; + ret = hppe_ac_grp_drop_state_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_grp_drop_state_tbl_yel_drop_state_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_grp_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_drop_state_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.yel_drop_state; + return ret; +} + +sw_error_t +hppe_ac_grp_drop_state_tbl_yel_drop_state_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_grp_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_drop_state_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.yel_drop_state = value; + ret = hppe_ac_grp_drop_state_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ac_grp_drop_state_tbl_grn_resume_thrd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ac_grp_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_drop_state_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.grn_resume_thrd_1 << 10 | \ + reg_val.bf.grn_resume_thrd_0; + return ret; +} + +sw_error_t +hppe_ac_grp_drop_state_tbl_grn_resume_thrd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ac_grp_drop_state_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ac_grp_drop_state_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.grn_resume_thrd_1 = value >> 10; + reg_val.bf.grn_resume_thrd_0 = value & (((a_uint64_t)1<<10)-1); + ret = hppe_ac_grp_drop_state_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_enq_opr_tbl_enq_disable_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_enq_opr_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_enq_opr_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.enq_disable; + return ret; +} + +sw_error_t +hppe_oq_enq_opr_tbl_enq_disable_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_enq_opr_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_enq_opr_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.enq_disable = value; + ret = hppe_oq_enq_opr_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_deq_opr_tbl_deq_drop_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_deq_opr_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_deq_opr_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.deq_drop; + return ret; +} + +sw_error_t +hppe_oq_deq_opr_tbl_deq_drop_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_deq_opr_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_deq_opr_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.deq_drop = value; + ret = hppe_oq_deq_opr_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_head_uni_tbl_head_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_head_uni_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_head_uni_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.head; + return ret; +} + +sw_error_t +hppe_oq_head_uni_tbl_head_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_head_uni_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_head_uni_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.head = value; + ret = hppe_oq_head_uni_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_head_uni_tbl_tail_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_head_uni_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_head_uni_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.tail; + return ret; +} + +sw_error_t +hppe_oq_head_uni_tbl_tail_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_head_uni_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_head_uni_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tail = value; + ret = hppe_oq_head_uni_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_head_uni_tbl_empty_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_head_uni_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_head_uni_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.empty; + return ret; +} + +sw_error_t +hppe_oq_head_uni_tbl_empty_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_head_uni_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_head_uni_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.empty = value; + ret = hppe_oq_head_uni_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_head_mul_tbl_head_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_head_mul_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_head_mul_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.head; + return ret; +} + +sw_error_t +hppe_oq_head_mul_tbl_head_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_head_mul_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_head_mul_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.head = value; + ret = hppe_oq_head_mul_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_head_mul_tbl_tail_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_head_mul_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_head_mul_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.tail; + return ret; +} + +sw_error_t +hppe_oq_head_mul_tbl_tail_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_head_mul_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_head_mul_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tail = value; + ret = hppe_oq_head_mul_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_head_mul_tbl_ingress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_head_mul_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_head_mul_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ingress_mirr; + return ret; +} + +sw_error_t +hppe_oq_head_mul_tbl_ingress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_head_mul_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_head_mul_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ingress_mirr = value; + ret = hppe_oq_head_mul_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_head_mul_tbl_empty_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_head_mul_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_head_mul_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.empty; + return ret; +} + +sw_error_t +hppe_oq_head_mul_tbl_empty_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_head_mul_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_head_mul_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.empty = value; + ret = hppe_oq_head_mul_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_head_mul_tbl_egress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_head_mul_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_head_mul_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.egress_mirr; + return ret; +} + +sw_error_t +hppe_oq_head_mul_tbl_egress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_head_mul_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_head_mul_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.egress_mirr = value; + ret = hppe_oq_head_mul_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_head_mul_tbl_normal_fwd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_head_mul_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_head_mul_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.normal_fwd; + return ret; +} + +sw_error_t +hppe_oq_head_mul_tbl_normal_fwd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_head_mul_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_head_mul_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.normal_fwd = value; + ret = hppe_oq_head_mul_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_ll_uni_tbl_next_pointer_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_ll_uni_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_uni_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.next_pointer; + return ret; +} + +sw_error_t +hppe_oq_ll_uni_tbl_next_pointer_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_ll_uni_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_uni_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.next_pointer = value; + ret = hppe_oq_ll_uni_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p0_tbl_next_pointer_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_ll_mul_p0_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p0_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.next_pointer; + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p0_tbl_next_pointer_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_ll_mul_p0_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p0_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.next_pointer = value; + ret = hppe_oq_ll_mul_p0_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p0_tbl_ingress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_ll_mul_p0_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p0_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ingress_mirr; + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p0_tbl_ingress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_ll_mul_p0_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p0_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ingress_mirr = value; + ret = hppe_oq_ll_mul_p0_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p0_tbl_egress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_ll_mul_p0_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p0_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.egress_mirr; + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p0_tbl_egress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_ll_mul_p0_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p0_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.egress_mirr = value; + ret = hppe_oq_ll_mul_p0_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p0_tbl_normal_fwd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_ll_mul_p0_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p0_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.normal_fwd; + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p0_tbl_normal_fwd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_ll_mul_p0_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p0_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.normal_fwd = value; + ret = hppe_oq_ll_mul_p0_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p1_tbl_next_pointer_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_ll_mul_p1_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p1_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.next_pointer; + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p1_tbl_next_pointer_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_ll_mul_p1_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p1_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.next_pointer = value; + ret = hppe_oq_ll_mul_p1_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p1_tbl_ingress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_ll_mul_p1_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p1_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ingress_mirr; + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p1_tbl_ingress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_ll_mul_p1_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p1_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ingress_mirr = value; + ret = hppe_oq_ll_mul_p1_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p1_tbl_egress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_ll_mul_p1_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p1_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.egress_mirr; + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p1_tbl_egress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_ll_mul_p1_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p1_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.egress_mirr = value; + ret = hppe_oq_ll_mul_p1_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p1_tbl_normal_fwd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_ll_mul_p1_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p1_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.normal_fwd; + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p1_tbl_normal_fwd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_ll_mul_p1_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p1_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.normal_fwd = value; + ret = hppe_oq_ll_mul_p1_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p2_tbl_next_pointer_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_ll_mul_p2_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p2_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.next_pointer; + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p2_tbl_next_pointer_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_ll_mul_p2_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p2_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.next_pointer = value; + ret = hppe_oq_ll_mul_p2_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p2_tbl_ingress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_ll_mul_p2_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p2_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ingress_mirr; + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p2_tbl_ingress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_ll_mul_p2_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p2_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ingress_mirr = value; + ret = hppe_oq_ll_mul_p2_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p2_tbl_egress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_ll_mul_p2_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p2_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.egress_mirr; + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p2_tbl_egress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_ll_mul_p2_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p2_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.egress_mirr = value; + ret = hppe_oq_ll_mul_p2_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p2_tbl_normal_fwd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_ll_mul_p2_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p2_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.normal_fwd; + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p2_tbl_normal_fwd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_ll_mul_p2_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p2_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.normal_fwd = value; + ret = hppe_oq_ll_mul_p2_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p3_tbl_next_pointer_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_ll_mul_p3_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p3_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.next_pointer; + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p3_tbl_next_pointer_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_ll_mul_p3_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p3_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.next_pointer = value; + ret = hppe_oq_ll_mul_p3_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p3_tbl_ingress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_ll_mul_p3_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p3_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ingress_mirr; + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p3_tbl_ingress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_ll_mul_p3_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p3_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ingress_mirr = value; + ret = hppe_oq_ll_mul_p3_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p3_tbl_egress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_ll_mul_p3_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p3_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.egress_mirr; + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p3_tbl_egress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_ll_mul_p3_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p3_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.egress_mirr = value; + ret = hppe_oq_ll_mul_p3_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p3_tbl_normal_fwd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_ll_mul_p3_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p3_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.normal_fwd; + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p3_tbl_normal_fwd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_ll_mul_p3_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p3_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.normal_fwd = value; + ret = hppe_oq_ll_mul_p3_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p4_tbl_next_pointer_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_ll_mul_p4_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p4_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.next_pointer; + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p4_tbl_next_pointer_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_ll_mul_p4_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p4_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.next_pointer = value; + ret = hppe_oq_ll_mul_p4_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p4_tbl_ingress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_ll_mul_p4_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p4_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ingress_mirr; + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p4_tbl_ingress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_ll_mul_p4_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p4_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ingress_mirr = value; + ret = hppe_oq_ll_mul_p4_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p4_tbl_egress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_ll_mul_p4_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p4_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.egress_mirr; + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p4_tbl_egress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_ll_mul_p4_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p4_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.egress_mirr = value; + ret = hppe_oq_ll_mul_p4_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p4_tbl_normal_fwd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_ll_mul_p4_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p4_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.normal_fwd; + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p4_tbl_normal_fwd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_ll_mul_p4_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p4_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.normal_fwd = value; + ret = hppe_oq_ll_mul_p4_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p5_tbl_next_pointer_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_ll_mul_p5_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p5_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.next_pointer; + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p5_tbl_next_pointer_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_ll_mul_p5_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p5_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.next_pointer = value; + ret = hppe_oq_ll_mul_p5_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p5_tbl_ingress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_ll_mul_p5_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p5_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ingress_mirr; + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p5_tbl_ingress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_ll_mul_p5_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p5_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ingress_mirr = value; + ret = hppe_oq_ll_mul_p5_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p5_tbl_egress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_ll_mul_p5_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p5_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.egress_mirr; + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p5_tbl_egress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_ll_mul_p5_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p5_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.egress_mirr = value; + ret = hppe_oq_ll_mul_p5_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p5_tbl_normal_fwd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_ll_mul_p5_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p5_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.normal_fwd; + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p5_tbl_normal_fwd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_ll_mul_p5_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p5_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.normal_fwd = value; + ret = hppe_oq_ll_mul_p5_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p6_tbl_next_pointer_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_ll_mul_p6_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p6_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.next_pointer; + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p6_tbl_next_pointer_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_ll_mul_p6_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p6_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.next_pointer = value; + ret = hppe_oq_ll_mul_p6_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p6_tbl_ingress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_ll_mul_p6_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p6_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ingress_mirr; + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p6_tbl_ingress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_ll_mul_p6_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p6_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ingress_mirr = value; + ret = hppe_oq_ll_mul_p6_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p6_tbl_egress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_ll_mul_p6_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p6_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.egress_mirr; + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p6_tbl_egress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_ll_mul_p6_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p6_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.egress_mirr = value; + ret = hppe_oq_ll_mul_p6_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p6_tbl_normal_fwd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_ll_mul_p6_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p6_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.normal_fwd; + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p6_tbl_normal_fwd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_ll_mul_p6_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p6_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.normal_fwd = value; + ret = hppe_oq_ll_mul_p6_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p7_tbl_next_pointer_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_ll_mul_p7_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p7_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.next_pointer; + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p7_tbl_next_pointer_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_ll_mul_p7_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p7_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.next_pointer = value; + ret = hppe_oq_ll_mul_p7_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p7_tbl_ingress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_ll_mul_p7_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p7_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ingress_mirr; + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p7_tbl_ingress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_ll_mul_p7_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p7_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ingress_mirr = value; + ret = hppe_oq_ll_mul_p7_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p7_tbl_egress_mirr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_ll_mul_p7_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p7_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.egress_mirr; + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p7_tbl_egress_mirr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_ll_mul_p7_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p7_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.egress_mirr = value; + ret = hppe_oq_ll_mul_p7_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p7_tbl_normal_fwd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union oq_ll_mul_p7_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p7_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.normal_fwd; + return ret; +} + +sw_error_t +hppe_oq_ll_mul_p7_tbl_normal_fwd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union oq_ll_mul_p7_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_oq_ll_mul_p7_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.normal_fwd = value; + ret = hppe_oq_ll_mul_p7_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_ip_addr_index_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.ip_addr_index_valid; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_ip_addr_index_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.ip_addr_index_valid = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_route_flag_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.route_flag; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_route_flag_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.route_flag = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_int_cpcp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.int_cpcp; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_int_cpcp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.int_cpcp = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_pkt_l3_edit_bypass_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.pkt_l3_edit_bypass; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_pkt_l3_edit_bypass_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.pkt_l3_edit_bypass = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_int_ctag_fmt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.int_ctag_fmt; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_int_ctag_fmt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.int_ctag_fmt = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_fake_mac_header_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.fake_mac_header; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_fake_mac_header_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.fake_mac_header = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_acl_index_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.acl_index; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_acl_index_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.acl_index = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_l4_type_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.l4_type; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_l4_type_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.l4_type = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_int_svid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.int_svid; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_int_svid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.int_svid = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_int_sdei_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.int_sdei; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_int_sdei_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.int_sdei = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_fc_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.fc_en; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_fc_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.fc_en = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_packet_length_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.packet_length_1 << 8 | \ + reg_val.bf1.packet_length_0; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_packet_length_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.packet_length_1 = value >> 8; + reg_val.bf1.packet_length_0 = value & (((a_uint64_t)1<<8)-1); + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_rx_ts_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf1.rx_ts_1 << 24 | \ + reg_val.bf1.rx_ts_0; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_rx_ts_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.rx_ts_1 = value >> 24; + reg_val.bf1.rx_ts_0 = value & (((a_uint64_t)1<<24)-1); + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_ts_dir_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.ts_dir; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_ts_dir_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.ts_dir = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_chg_port_vp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.chg_port_vp; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_chg_port_vp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.chg_port_vp = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_int_pri_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.int_pri; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_int_pri_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.int_pri = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_one_enq_flag_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.one_enq_flag; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_one_enq_flag_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.one_enq_flag = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_fc_grp_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.fc_grp_id; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_fc_grp_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.fc_grp_id = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_fake_l2_prot_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.fake_l2_prot; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_fake_l2_prot_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.fake_l2_prot = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_org_src_port_vp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.org_src_port_vp; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_org_src_port_vp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.org_src_port_vp = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_hash_flag_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.hash_flag; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_hash_flag_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.hash_flag = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_int_stag_fmt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.int_stag_fmt; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_int_stag_fmt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.int_stag_fmt = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_service_code_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.service_code_1 << 2 | \ + reg_val.bf1.service_code_0; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_service_code_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.service_code_1 = value >> 2; + reg_val.bf1.service_code_0 = value & (((a_uint64_t)1<<2)-1); + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_rx_ptp_type_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.rx_ptp_type; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_rx_ptp_type_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.rx_ptp_type = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_mac_da_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf1.mac_da_1 << 18 | \ + reg_val.bf1.mac_da_0; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_mac_da_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.mac_da_1 = value >> 18; + reg_val.bf1.mac_da_0 = value & (((a_uint64_t)1<<18)-1); + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_cpu_code_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.cpu_code; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_cpu_code_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.cpu_code = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_eg_vlan_tag_fmt_bypass_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.eg_vlan_tag_fmt_bypass_en; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_eg_vlan_tag_fmt_bypass_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.eg_vlan_tag_fmt_bypass_en = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_ip_addr_index_type_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.ip_addr_index_type; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_ip_addr_index_type_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.ip_addr_index_type = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_int_cvid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.int_cvid_1 << 9 | \ + reg_val.bf1.int_cvid_0; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_int_cvid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.int_cvid_1 = value >> 9; + reg_val.bf1.int_cvid_0 = value & (((a_uint64_t)1<<9)-1); + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_eg_vlan_xlt_bypass_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.eg_vlan_xlt_bypass_en; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_eg_vlan_xlt_bypass_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.eg_vlan_xlt_bypass_en = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_hash_value_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.hash_value_1 << 5 | \ + reg_val.bf1.hash_value_0; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_hash_value_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.hash_value_1 = value >> 5; + reg_val.bf1.hash_value_0 = value & (((a_uint64_t)1<<5)-1); + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_stag_flag_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.stag_flag; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_stag_flag_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.stag_flag = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_dst_l3_if_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.dst_l3_if; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_dst_l3_if_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.dst_l3_if = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_int_cdei_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.int_cdei; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_int_cdei_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.int_cdei = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_edma_vp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.edma_vp; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_edma_vp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.edma_vp = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_ac_group_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.ac_group_bitmap; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_ac_group_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.ac_group_bitmap = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_vp_tx_cnt_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.vp_tx_cnt_en; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_vp_tx_cnt_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.vp_tx_cnt_en = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_src_port_vp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.src_port_vp; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_src_port_vp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.src_port_vp = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_nat_action_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.nat_action; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_nat_action_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.nat_action = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_dscp_update_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.dscp_update; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_dscp_update_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.dscp_update = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_pppoe_strip_flag_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.pppoe_strip_flag; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_pppoe_strip_flag_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.pppoe_strip_flag = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_snap_flag_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.snap_flag; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_snap_flag_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.snap_flag = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_vsi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.vsi; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_vsi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.vsi = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_pkt_l2_edit_bypass_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.pkt_l2_edit_bypass; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_pkt_l2_edit_bypass_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.pkt_l2_edit_bypass = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_tx_ptp_tag_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf0.tx_ptp_tag; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_tx_ptp_tag_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf0.tx_ptp_tag = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_ip_addr_index_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.ip_addr_index_1 << 1 | \ + reg_val.bf1.ip_addr_index_0; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_ip_addr_index_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.ip_addr_index_1 = value >> 1; + reg_val.bf1.ip_addr_index_0 = value & (((a_uint64_t)1<<1)-1); + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_int_dp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.int_dp; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_int_dp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.int_dp = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_src_pn_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.src_pn; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_src_pn_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.src_pn = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_tx_ts_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf0.tx_ts_en; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_tx_ts_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf0.tx_ts_en = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_l4_offset_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.l4_offset_1 << 6 | \ + reg_val.bf1.l4_offset_0; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_l4_offset_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.l4_offset_1 = value >> 6; + reg_val.bf1.l4_offset_0 = value & (((a_uint64_t)1<<6)-1); + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_ttl_update_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.ttl_update; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_ttl_update_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.ttl_update = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_napt_port_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.napt_port; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_napt_port_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.napt_port = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_napt_addr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.napt_addr_1 << 13 | \ + reg_val.bf1.napt_addr_0; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_napt_addr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.napt_addr_1 = value >> 13; + reg_val.bf1.napt_addr_0 = value & (((a_uint64_t)1<<13)-1); + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_copy_cpu_flag_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.copy_cpu_flag; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_copy_cpu_flag_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.copy_cpu_flag = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_ttl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.ttl_1 << 3 | \ + reg_val.bf1.ttl_0; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_ttl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.ttl_1 = value >> 3; + reg_val.bf1.ttl_0 = value & (((a_uint64_t)1<<3)-1); + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_l3_offset_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.l3_offset; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_l3_offset_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.l3_offset = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_rsv0_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.rsv0_1 << 3 | \ + reg_val.bf1.rsv0_0; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_rsv0_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.rsv0_1 = value >> 3; + reg_val.bf1.rsv0_0 = value & (((a_uint64_t)1<<3)-1); + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_next_header_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.next_header; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_next_header_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.next_header = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_acl_index_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.acl_index_valid; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_acl_index_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.acl_index_valid = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_rx_ts_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.rx_ts_valid; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_rx_ts_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.rx_ts_valid = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_dscp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.dscp; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_dscp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.dscp = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_acl_index_toggle_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.acl_index_toggle; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_acl_index_toggle_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.acl_index_toggle = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_ctag_flag_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.ctag_flag; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_ctag_flag_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.ctag_flag = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_ip_addr_index_toggle_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.ip_addr_index_toggle; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_ip_addr_index_toggle_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.ip_addr_index_toggle = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_tx_os_correction_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf0.tx_os_correction_en; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_tx_os_correction_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf0.tx_os_correction_en = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_int_spcp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.int_spcp; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_int_spcp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.int_spcp = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_pppoe_flag_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.pppoe_flag; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_pppoe_flag_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.pppoe_flag = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_l3_type_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.l3_type; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_l3_type_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.l3_type = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_vsi_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf1.vsi_valid; + return ret; +} + +sw_error_t +hppe_pkt_desp_tbl_vsi_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pkt_desp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pkt_desp_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf1.vsi_valid = value; + ret = hppe_pkt_desp_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uni_drop_cnt_tbl_uni_drop_byte_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union uni_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uni_drop_cnt_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.uni_drop_byte_1 << 32 | \ + reg_val.bf.uni_drop_byte_0; + return ret; +} + +sw_error_t +hppe_uni_drop_cnt_tbl_uni_drop_byte_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union uni_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uni_drop_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.uni_drop_byte_1 = value >> 32; + reg_val.bf.uni_drop_byte_0 = value & (((a_uint64_t)1<<32)-1); + ret = hppe_uni_drop_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uni_drop_cnt_tbl_uni_drop_pkt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uni_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uni_drop_cnt_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.uni_drop_pkt; + return ret; +} + +sw_error_t +hppe_uni_drop_cnt_tbl_uni_drop_pkt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uni_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uni_drop_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.uni_drop_pkt = value; + ret = hppe_uni_drop_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mul_p0_drop_cnt_tbl_mul_p0_drop_pkt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mul_p0_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mul_p0_drop_cnt_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.mul_p0_drop_pkt; + return ret; +} + +sw_error_t +hppe_mul_p0_drop_cnt_tbl_mul_p0_drop_pkt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mul_p0_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mul_p0_drop_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mul_p0_drop_pkt = value; + ret = hppe_mul_p0_drop_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mul_p0_drop_cnt_tbl_mul_p0_drop_byte_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union mul_p0_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mul_p0_drop_cnt_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.mul_p0_drop_byte_1 << 32 | \ + reg_val.bf.mul_p0_drop_byte_0; + return ret; +} + +sw_error_t +hppe_mul_p0_drop_cnt_tbl_mul_p0_drop_byte_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union mul_p0_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mul_p0_drop_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mul_p0_drop_byte_1 = value >> 32; + reg_val.bf.mul_p0_drop_byte_0 = value & (((a_uint64_t)1<<32)-1); + ret = hppe_mul_p0_drop_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mul_p1_drop_cnt_tbl_mul_p1_drop_byte_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union mul_p1_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mul_p1_drop_cnt_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.mul_p1_drop_byte_1 << 32 | \ + reg_val.bf.mul_p1_drop_byte_0; + return ret; +} + +sw_error_t +hppe_mul_p1_drop_cnt_tbl_mul_p1_drop_byte_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union mul_p1_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mul_p1_drop_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mul_p1_drop_byte_1 = value >> 32; + reg_val.bf.mul_p1_drop_byte_0 = value & (((a_uint64_t)1<<32)-1); + ret = hppe_mul_p1_drop_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mul_p1_drop_cnt_tbl_mul_p1_drop_pkt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mul_p1_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mul_p1_drop_cnt_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.mul_p1_drop_pkt; + return ret; +} + +sw_error_t +hppe_mul_p1_drop_cnt_tbl_mul_p1_drop_pkt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mul_p1_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mul_p1_drop_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mul_p1_drop_pkt = value; + ret = hppe_mul_p1_drop_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mul_p2_drop_cnt_tbl_mul_p2_drop_pkt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mul_p2_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mul_p2_drop_cnt_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.mul_p2_drop_pkt; + return ret; +} + +sw_error_t +hppe_mul_p2_drop_cnt_tbl_mul_p2_drop_pkt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mul_p2_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mul_p2_drop_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mul_p2_drop_pkt = value; + ret = hppe_mul_p2_drop_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mul_p2_drop_cnt_tbl_mul_p2_drop_byte_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union mul_p2_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mul_p2_drop_cnt_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.mul_p2_drop_byte_1 << 32 | \ + reg_val.bf.mul_p2_drop_byte_0; + return ret; +} + +sw_error_t +hppe_mul_p2_drop_cnt_tbl_mul_p2_drop_byte_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union mul_p2_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mul_p2_drop_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mul_p2_drop_byte_1 = value >> 32; + reg_val.bf.mul_p2_drop_byte_0 = value & (((a_uint64_t)1<<32)-1); + ret = hppe_mul_p2_drop_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mul_p3_drop_cnt_tbl_mul_p3_drop_pkt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mul_p3_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mul_p3_drop_cnt_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.mul_p3_drop_pkt; + return ret; +} + +sw_error_t +hppe_mul_p3_drop_cnt_tbl_mul_p3_drop_pkt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mul_p3_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mul_p3_drop_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mul_p3_drop_pkt = value; + ret = hppe_mul_p3_drop_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mul_p3_drop_cnt_tbl_mul_p3_drop_byte_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union mul_p3_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mul_p3_drop_cnt_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.mul_p3_drop_byte_1 << 32 | \ + reg_val.bf.mul_p3_drop_byte_0; + return ret; +} + +sw_error_t +hppe_mul_p3_drop_cnt_tbl_mul_p3_drop_byte_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union mul_p3_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mul_p3_drop_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mul_p3_drop_byte_1 = value >> 32; + reg_val.bf.mul_p3_drop_byte_0 = value & (((a_uint64_t)1<<32)-1); + ret = hppe_mul_p3_drop_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mul_p4_drop_cnt_tbl_mul_p4_drop_pkt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mul_p4_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mul_p4_drop_cnt_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.mul_p4_drop_pkt; + return ret; +} + +sw_error_t +hppe_mul_p4_drop_cnt_tbl_mul_p4_drop_pkt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mul_p4_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mul_p4_drop_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mul_p4_drop_pkt = value; + ret = hppe_mul_p4_drop_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mul_p4_drop_cnt_tbl_mul_p4_drop_byte_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union mul_p4_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mul_p4_drop_cnt_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.mul_p4_drop_byte_1 << 32 | \ + reg_val.bf.mul_p4_drop_byte_0; + return ret; +} + +sw_error_t +hppe_mul_p4_drop_cnt_tbl_mul_p4_drop_byte_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union mul_p4_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mul_p4_drop_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mul_p4_drop_byte_1 = value >> 32; + reg_val.bf.mul_p4_drop_byte_0 = value & (((a_uint64_t)1<<32)-1); + ret = hppe_mul_p4_drop_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mul_p5_drop_cnt_tbl_mul_p5_drop_byte_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union mul_p5_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mul_p5_drop_cnt_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.mul_p5_drop_byte_1 << 32 | \ + reg_val.bf.mul_p5_drop_byte_0; + return ret; +} + +sw_error_t +hppe_mul_p5_drop_cnt_tbl_mul_p5_drop_byte_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union mul_p5_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mul_p5_drop_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mul_p5_drop_byte_1 = value >> 32; + reg_val.bf.mul_p5_drop_byte_0 = value & (((a_uint64_t)1<<32)-1); + ret = hppe_mul_p5_drop_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mul_p5_drop_cnt_tbl_mul_p5_drop_pkt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mul_p5_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mul_p5_drop_cnt_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.mul_p5_drop_pkt; + return ret; +} + +sw_error_t +hppe_mul_p5_drop_cnt_tbl_mul_p5_drop_pkt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mul_p5_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mul_p5_drop_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mul_p5_drop_pkt = value; + ret = hppe_mul_p5_drop_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mul_p6_drop_cnt_tbl_mul_p6_drop_byte_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union mul_p6_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mul_p6_drop_cnt_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.mul_p6_drop_byte_1 << 32 | \ + reg_val.bf.mul_p6_drop_byte_0; + return ret; +} + +sw_error_t +hppe_mul_p6_drop_cnt_tbl_mul_p6_drop_byte_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union mul_p6_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mul_p6_drop_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mul_p6_drop_byte_1 = value >> 32; + reg_val.bf.mul_p6_drop_byte_0 = value & (((a_uint64_t)1<<32)-1); + ret = hppe_mul_p6_drop_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mul_p6_drop_cnt_tbl_mul_p6_drop_pkt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mul_p6_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mul_p6_drop_cnt_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.mul_p6_drop_pkt; + return ret; +} + +sw_error_t +hppe_mul_p6_drop_cnt_tbl_mul_p6_drop_pkt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mul_p6_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mul_p6_drop_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mul_p6_drop_pkt = value; + ret = hppe_mul_p6_drop_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mul_p7_drop_cnt_tbl_mul_p7_drop_pkt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mul_p7_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mul_p7_drop_cnt_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.mul_p7_drop_pkt; + return ret; +} + +sw_error_t +hppe_mul_p7_drop_cnt_tbl_mul_p7_drop_pkt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mul_p7_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mul_p7_drop_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mul_p7_drop_pkt = value; + ret = hppe_mul_p7_drop_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mul_p7_drop_cnt_tbl_mul_p7_drop_byte_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union mul_p7_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mul_p7_drop_cnt_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.mul_p7_drop_byte_1 << 32 | \ + reg_val.bf.mul_p7_drop_byte_0; + return ret; +} + +sw_error_t +hppe_mul_p7_drop_cnt_tbl_mul_p7_drop_byte_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union mul_p7_drop_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mul_p7_drop_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mul_p7_drop_byte_1 = value >> 32; + reg_val.bf.mul_p7_drop_byte_0 = value & (((a_uint64_t)1<<32)-1); + ret = hppe_mul_p7_drop_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uq_agg_profile_map_qid_2_agg_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uq_agg_profile_map_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uq_agg_profile_map_get(dev_id, index, ®_val); + *value = reg_val.bf.qid_2_agg_id; + return ret; +} + +sw_error_t +hppe_uq_agg_profile_map_qid_2_agg_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uq_agg_profile_map_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uq_agg_profile_map_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.qid_2_agg_id = value; + ret = hppe_uq_agg_profile_map_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uq_agg_profile_map_enable_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uq_agg_profile_map_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uq_agg_profile_map_get(dev_id, index, ®_val); + *value = reg_val.bf.enable; + return ret; +} + +sw_error_t +hppe_uq_agg_profile_map_enable_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uq_agg_profile_map_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uq_agg_profile_map_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.enable = value; + ret = hppe_uq_agg_profile_map_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_queue_tx_counter_tbl_tx_bytes_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union queue_tx_counter_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_queue_tx_counter_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.tx_bytes_1 << 32 | \ + reg_val.bf.tx_bytes_0; + return ret; +} + +sw_error_t +hppe_queue_tx_counter_tbl_tx_bytes_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union queue_tx_counter_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_queue_tx_counter_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_bytes_1 = value >> 32; + reg_val.bf.tx_bytes_0 = value & (((a_uint64_t)1<<32)-1); + ret = hppe_queue_tx_counter_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_queue_tx_counter_tbl_tx_packets_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union queue_tx_counter_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_queue_tx_counter_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_packets; + return ret; +} + +sw_error_t +hppe_queue_tx_counter_tbl_tx_packets_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union queue_tx_counter_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_queue_tx_counter_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_packets = value; + ret = hppe_queue_tx_counter_tbl_set(dev_id, index, ®_val); + return ret; +} +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_qos.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_qos.c new file mode 100755 index 000000000..f617917f3 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_qos.c @@ -0,0 +1,4548 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hppe_reg_access.h" +#include "hppe_qos_reg.h" +#include "hppe_qos.h" + +sw_error_t +hppe_dscp_qos_group_0_get( + a_uint32_t dev_id, + a_uint32_t index, + union dscp_qos_group_0_u *value) +{ + if (index >= DSCP_QOS_GROUP_0_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + DSCP_QOS_GROUP_0_ADDRESS + \ + index * DSCP_QOS_GROUP_0_INC, + &value->val); +} + +sw_error_t +hppe_dscp_qos_group_0_set( + a_uint32_t dev_id, + a_uint32_t index, + union dscp_qos_group_0_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L2_BASE_ADDR + DSCP_QOS_GROUP_0_ADDRESS + \ + index * DSCP_QOS_GROUP_0_INC, + value->val); +} + +sw_error_t +hppe_dscp_qos_group_1_get( + a_uint32_t dev_id, + a_uint32_t index, + union dscp_qos_group_1_u *value) +{ + if (index >= DSCP_QOS_GROUP_1_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + DSCP_QOS_GROUP_1_ADDRESS + \ + index * DSCP_QOS_GROUP_1_INC, + &value->val); +} + +sw_error_t +hppe_dscp_qos_group_1_set( + a_uint32_t dev_id, + a_uint32_t index, + union dscp_qos_group_1_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L2_BASE_ADDR + DSCP_QOS_GROUP_1_ADDRESS + \ + index * DSCP_QOS_GROUP_1_INC, + value->val); +} + +sw_error_t +hppe_pcp_qos_group_0_get( + a_uint32_t dev_id, + a_uint32_t index, + union pcp_qos_group_0_u *value) +{ + if (index >= PCP_QOS_GROUP_0_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + PCP_QOS_GROUP_0_ADDRESS + \ + index * PCP_QOS_GROUP_0_INC, + &value->val); +} + +sw_error_t +hppe_pcp_qos_group_0_set( + a_uint32_t dev_id, + a_uint32_t index, + union pcp_qos_group_0_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L2_BASE_ADDR + PCP_QOS_GROUP_0_ADDRESS + \ + index * PCP_QOS_GROUP_0_INC, + value->val); +} + +sw_error_t +hppe_pcp_qos_group_1_get( + a_uint32_t dev_id, + a_uint32_t index, + union pcp_qos_group_1_u *value) +{ + if (index >= PCP_QOS_GROUP_1_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + PCP_QOS_GROUP_1_ADDRESS + \ + index * PCP_QOS_GROUP_1_INC, + &value->val); +} + +sw_error_t +hppe_pcp_qos_group_1_set( + a_uint32_t dev_id, + a_uint32_t index, + union pcp_qos_group_1_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L2_BASE_ADDR + PCP_QOS_GROUP_1_ADDRESS + \ + index * PCP_QOS_GROUP_1_INC, + value->val); +} + +sw_error_t +hppe_flow_qos_group_0_get( + a_uint32_t dev_id, + a_uint32_t index, + union flow_qos_group_0_u *value) +{ + if (index >= FLOW_QOS_GROUP_0_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + FLOW_QOS_GROUP_0_ADDRESS + \ + index * FLOW_QOS_GROUP_0_INC, + &value->val); +} + +sw_error_t +hppe_flow_qos_group_0_set( + a_uint32_t dev_id, + a_uint32_t index, + union flow_qos_group_0_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L2_BASE_ADDR + FLOW_QOS_GROUP_0_ADDRESS + \ + index * FLOW_QOS_GROUP_0_INC, + value->val); +} + +sw_error_t +hppe_flow_qos_group_1_get( + a_uint32_t dev_id, + a_uint32_t index, + union flow_qos_group_1_u *value) +{ + if (index >= FLOW_QOS_GROUP_1_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + FLOW_QOS_GROUP_1_ADDRESS + \ + index * FLOW_QOS_GROUP_1_INC, + &value->val); +} + +sw_error_t +hppe_flow_qos_group_1_set( + a_uint32_t dev_id, + a_uint32_t index, + union flow_qos_group_1_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L2_BASE_ADDR + FLOW_QOS_GROUP_1_ADDRESS + \ + index * FLOW_QOS_GROUP_1_INC, + value->val); +} + +sw_error_t +hppe_port_qos_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_qos_ctrl_u *value) +{ + if (index >= PORT_QOS_CTRL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + PORT_QOS_CTRL_ADDRESS + \ + index * PORT_QOS_CTRL_INC, + &value->val); +} + +sw_error_t +hppe_port_qos_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_qos_ctrl_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L2_BASE_ADDR + PORT_QOS_CTRL_ADDRESS + \ + index * PORT_QOS_CTRL_INC, + value->val); +} +#ifndef IN_QOS_MINI +sw_error_t +hppe_tdm_depth_cfg_get( + a_uint32_t dev_id, + union tdm_depth_cfg_u *value) +{ + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + TDM_DEPTH_CFG_ADDRESS, + &value->val); +} +#endif +sw_error_t +hppe_tdm_depth_cfg_set( + a_uint32_t dev_id, + union tdm_depth_cfg_u *value) +{ + return hppe_reg_set( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + TDM_DEPTH_CFG_ADDRESS, + value->val); +} +#ifndef IN_QOS_MINI +sw_error_t +hppe_min_max_mode_cfg_get( + a_uint32_t dev_id, + union min_max_mode_cfg_u *value) +{ + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + MIN_MAX_MODE_CFG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_min_max_mode_cfg_set( + a_uint32_t dev_id, + union min_max_mode_cfg_u *value) +{ + return hppe_reg_set( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + MIN_MAX_MODE_CFG_ADDRESS, + value->val); +} + +sw_error_t +hppe_tm_dbg_addr_get( + a_uint32_t dev_id, + union tm_dbg_addr_u *value) +{ + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + TM_DBG_ADDR_ADDRESS, + &value->val); +} + +sw_error_t +hppe_tm_dbg_addr_set( + a_uint32_t dev_id, + union tm_dbg_addr_u *value) +{ + return hppe_reg_set( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + TM_DBG_ADDR_ADDRESS, + value->val); +} + +sw_error_t +hppe_tm_dbg_data_get( + a_uint32_t dev_id, + union tm_dbg_data_u *value) +{ + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + TM_DBG_DATA_ADDRESS, + &value->val); +} + +sw_error_t +hppe_tm_dbg_data_set( + a_uint32_t dev_id, + union tm_dbg_data_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_eco_reserve_0_get( + a_uint32_t dev_id, + union eco_reserve_0_u *value) +{ + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + ECO_RESERVE_0_ADDRESS, + &value->val); +} + +sw_error_t +hppe_eco_reserve_0_set( + a_uint32_t dev_id, + union eco_reserve_0_u *value) +{ + return hppe_reg_set( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + ECO_RESERVE_0_ADDRESS, + value->val); +} + +sw_error_t +hppe_eco_reserve_1_get( + a_uint32_t dev_id, + union eco_reserve_1_u *value) +{ + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + ECO_RESERVE_1_ADDRESS, + &value->val); +} + +sw_error_t +hppe_eco_reserve_1_set( + a_uint32_t dev_id, + union eco_reserve_1_u *value) +{ + return hppe_reg_set( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + ECO_RESERVE_1_ADDRESS, + value->val); +} +#endif +sw_error_t +hppe_l0_flow_map_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_flow_map_tbl_u *value) +{ + if (index >= L0_FLOW_MAP_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L0_FLOW_MAP_TBL_ADDRESS + \ + index * L0_FLOW_MAP_TBL_INC, + &value->val); +} + +sw_error_t +hppe_l0_flow_map_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_flow_map_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L0_FLOW_MAP_TBL_ADDRESS + \ + index * L0_FLOW_MAP_TBL_INC, + value->val); +} + +sw_error_t +hppe_l0_c_sp_cfg_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_c_sp_cfg_tbl_u *value) +{ + if (index >= L0_C_SP_CFG_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L0_C_SP_CFG_TBL_ADDRESS + \ + index * L0_C_SP_CFG_TBL_INC, + &value->val); +} + +sw_error_t +hppe_l0_c_sp_cfg_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_c_sp_cfg_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L0_C_SP_CFG_TBL_ADDRESS + \ + index * L0_C_SP_CFG_TBL_INC, + value->val); +} + +sw_error_t +hppe_l0_e_sp_cfg_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_e_sp_cfg_tbl_u *value) +{ + if (index >= L0_E_SP_CFG_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L0_E_SP_CFG_TBL_ADDRESS + \ + index * L0_E_SP_CFG_TBL_INC, + &value->val); +} + +sw_error_t +hppe_l0_e_sp_cfg_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_e_sp_cfg_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L0_E_SP_CFG_TBL_ADDRESS + \ + index * L0_E_SP_CFG_TBL_INC, + value->val); +} + +sw_error_t +hppe_l0_flow_port_map_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_flow_port_map_tbl_u *value) +{ + if (index >= L0_FLOW_PORT_MAP_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L0_FLOW_PORT_MAP_TBL_ADDRESS + \ + index * L0_FLOW_PORT_MAP_TBL_INC, + &value->val); +} + +sw_error_t +hppe_l0_flow_port_map_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_flow_port_map_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L0_FLOW_PORT_MAP_TBL_ADDRESS + \ + index * L0_FLOW_PORT_MAP_TBL_INC, + value->val); +} +#ifndef IN_QOS_MINI +sw_error_t +hppe_l0_c_drr_head_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_c_drr_head_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L0_C_DRR_HEAD_TBL_ADDRESS + \ + index * L0_C_DRR_HEAD_TBL_INC, + value->val, + 2); +} + +sw_error_t +hppe_l0_c_drr_head_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_c_drr_head_tbl_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_e_drr_head_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_e_drr_head_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L0_E_DRR_HEAD_TBL_ADDRESS + \ + index * L0_E_DRR_HEAD_TBL_INC, + value->val, + 2); +} + +sw_error_t +hppe_l0_e_drr_head_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_e_drr_head_tbl_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_drr_credit_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_drr_credit_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L0_DRR_CREDIT_TBL_ADDRESS + \ + index * L0_DRR_CREDIT_TBL_INC, + value->val, + 2); +} + +sw_error_t +hppe_l0_drr_credit_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_drr_credit_tbl_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_c_drr_ll_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_c_drr_ll_tbl_u *value) +{ + if (index >= L0_C_DRR_LL_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L0_C_DRR_LL_TBL_ADDRESS + \ + index * L0_C_DRR_LL_TBL_INC, + &value->val); +} + +sw_error_t +hppe_l0_c_drr_ll_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_c_drr_ll_tbl_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_c_drr_reverse_ll_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_c_drr_reverse_ll_tbl_u *value) +{ + if (index >= L0_C_DRR_REVERSE_LL_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L0_C_DRR_REVERSE_LL_TBL_ADDRESS + \ + index * L0_C_DRR_REVERSE_LL_TBL_INC, + &value->val); +} + +sw_error_t +hppe_l0_c_drr_reverse_ll_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_c_drr_reverse_ll_tbl_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_e_drr_ll_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_e_drr_ll_tbl_u *value) +{ + if (index >= L0_E_DRR_LL_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L0_E_DRR_LL_TBL_ADDRESS + \ + index * L0_E_DRR_LL_TBL_INC, + &value->val); +} + +sw_error_t +hppe_l0_e_drr_ll_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_e_drr_ll_tbl_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_e_drr_reverse_ll_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_e_drr_reverse_ll_tbl_u *value) +{ + if (index >= L0_E_DRR_REVERSE_LL_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L0_E_DRR_REVERSE_LL_TBL_ADDRESS + \ + index * L0_E_DRR_REVERSE_LL_TBL_INC, + &value->val); +} + +sw_error_t +hppe_l0_e_drr_reverse_ll_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_e_drr_reverse_ll_tbl_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_sp_entry_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_sp_entry_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L0_SP_ENTRY_TBL_ADDRESS + \ + index * L0_SP_ENTRY_TBL_INC, + value->val, + 5); +} + +sw_error_t +hppe_l0_sp_entry_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_sp_entry_tbl_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_ens_q_ll_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_ens_q_ll_tbl_u *value) +{ + if (index >= L0_ENS_Q_LL_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L0_ENS_Q_LL_TBL_ADDRESS + \ + index * L0_ENS_Q_LL_TBL_INC, + &value->val); +} + +sw_error_t +hppe_l0_ens_q_ll_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_ens_q_ll_tbl_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_ens_q_head_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_ens_q_head_tbl_u *value) +{ + if (index >= L0_ENS_Q_HEAD_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L0_ENS_Q_HEAD_TBL_ADDRESS + \ + index * L0_ENS_Q_HEAD_TBL_INC, + &value->val); +} + +sw_error_t +hppe_l0_ens_q_head_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_ens_q_head_tbl_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_ens_q_entry_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_ens_q_entry_tbl_u *value) +{ + if (index >= L0_ENS_Q_ENTRY_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L0_ENS_Q_ENTRY_TBL_ADDRESS + \ + index * L0_ENS_Q_ENTRY_TBL_INC, + &value->val); +} + +sw_error_t +hppe_l0_ens_q_entry_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_ens_q_entry_tbl_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_flow_status_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_flow_status_tbl_u *value) +{ + if (index >= L0_FLOW_STATUS_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L0_FLOW_STATUS_TBL_ADDRESS + \ + index * L0_FLOW_STATUS_TBL_INC, + &value->val); +} + +sw_error_t +hppe_l0_flow_status_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_flow_status_tbl_u *value) +{ + return SW_NOT_SUPPORTED; +} +#endif +sw_error_t +hppe_ring_q_map_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union ring_q_map_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + RING_Q_MAP_TBL_ADDRESS + \ + index * RING_Q_MAP_TBL_INC, + value->val, + 10); +} + +sw_error_t +hppe_ring_q_map_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union ring_q_map_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + RING_Q_MAP_TBL_ADDRESS + \ + index * RING_Q_MAP_TBL_INC, + value->val, + 10); +} +#ifndef IN_QOS_MINI +sw_error_t +hppe_rfc_block_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union rfc_block_tbl_u *value) +{ + if (index >= RFC_BLOCK_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + RFC_BLOCK_TBL_ADDRESS + \ + index * RFC_BLOCK_TBL_INC, + &value->val); +} + +sw_error_t +hppe_rfc_block_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union rfc_block_tbl_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rfc_status_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union rfc_status_tbl_u *value) +{ + if (index >= RFC_STATUS_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + RFC_STATUS_TBL_ADDRESS + \ + index * RFC_STATUS_TBL_INC, + &value->val); +} + +sw_error_t +hppe_rfc_status_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union rfc_status_tbl_u *value) +{ + return SW_NOT_SUPPORTED; +} +#endif +sw_error_t +hppe_deq_dis_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union deq_dis_tbl_u *value) +{ + if (index >= DEQ_DIS_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + DEQ_DIS_TBL_ADDRESS + \ + index * DEQ_DIS_TBL_INC, + &value->val); +} + +sw_error_t +hppe_deq_dis_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union deq_dis_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + DEQ_DIS_TBL_ADDRESS + \ + index * DEQ_DIS_TBL_INC, + value->val); +} + +sw_error_t +hppe_l1_flow_map_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_flow_map_tbl_u *value) +{ + if (index >= L1_FLOW_MAP_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L1_FLOW_MAP_TBL_ADDRESS + \ + index * L1_FLOW_MAP_TBL_INC, + &value->val); +} + +sw_error_t +hppe_l1_flow_map_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_flow_map_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L1_FLOW_MAP_TBL_ADDRESS + \ + index * L1_FLOW_MAP_TBL_INC, + value->val); +} + +sw_error_t +hppe_l1_c_sp_cfg_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_c_sp_cfg_tbl_u *value) +{ + if (index >= L1_C_SP_CFG_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L1_C_SP_CFG_TBL_ADDRESS + \ + index * L1_C_SP_CFG_TBL_INC, + &value->val); +} + +sw_error_t +hppe_l1_c_sp_cfg_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_c_sp_cfg_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L1_C_SP_CFG_TBL_ADDRESS + \ + index * L1_C_SP_CFG_TBL_INC, + value->val); +} + +sw_error_t +hppe_l1_e_sp_cfg_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_e_sp_cfg_tbl_u *value) +{ + if (index >= L1_E_SP_CFG_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L1_E_SP_CFG_TBL_ADDRESS + \ + index * L1_E_SP_CFG_TBL_INC, + &value->val); +} + +sw_error_t +hppe_l1_e_sp_cfg_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_e_sp_cfg_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L1_E_SP_CFG_TBL_ADDRESS + \ + index * L1_E_SP_CFG_TBL_INC, + value->val); +} + +sw_error_t +hppe_l1_flow_port_map_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_flow_port_map_tbl_u *value) +{ + if (index >= L1_FLOW_PORT_MAP_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L1_FLOW_PORT_MAP_TBL_ADDRESS + \ + index * L1_FLOW_PORT_MAP_TBL_INC, + &value->val); +} + +sw_error_t +hppe_l1_flow_port_map_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_flow_port_map_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L1_FLOW_PORT_MAP_TBL_ADDRESS + \ + index * L1_FLOW_PORT_MAP_TBL_INC, + value->val); +} + +sw_error_t +hppe_l1_c_drr_head_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_c_drr_head_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L1_C_DRR_HEAD_TBL_ADDRESS + \ + index * L1_C_DRR_HEAD_TBL_INC, + value->val, + 2); +} +#ifndef IN_QOS_MINI +sw_error_t +hppe_l1_c_drr_head_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_c_drr_head_tbl_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_e_drr_head_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_e_drr_head_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L1_E_DRR_HEAD_TBL_ADDRESS + \ + index * L1_E_DRR_HEAD_TBL_INC, + value->val, + 2); +} + +sw_error_t +hppe_l1_e_drr_head_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_e_drr_head_tbl_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_drr_credit_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_drr_credit_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L1_DRR_CREDIT_TBL_ADDRESS + \ + index * L1_DRR_CREDIT_TBL_INC, + value->val, + 2); +} + +sw_error_t +hppe_l1_drr_credit_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_drr_credit_tbl_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_c_drr_ll_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_c_drr_ll_tbl_u *value) +{ + if (index >= L1_C_DRR_LL_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L1_C_DRR_LL_TBL_ADDRESS + \ + index * L1_C_DRR_LL_TBL_INC, + &value->val); +} + +sw_error_t +hppe_l1_c_drr_ll_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_c_drr_ll_tbl_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_c_drr_reverse_ll_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_c_drr_reverse_ll_tbl_u *value) +{ + if (index >= L1_C_DRR_REVERSE_LL_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L1_C_DRR_REVERSE_LL_TBL_ADDRESS + \ + index * L1_C_DRR_REVERSE_LL_TBL_INC, + &value->val); +} + +sw_error_t +hppe_l1_c_drr_reverse_ll_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_c_drr_reverse_ll_tbl_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_e_drr_ll_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_e_drr_ll_tbl_u *value) +{ + if (index >= L1_E_DRR_LL_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L1_E_DRR_LL_TBL_ADDRESS + \ + index * L1_E_DRR_LL_TBL_INC, + &value->val); +} + +sw_error_t +hppe_l1_e_drr_ll_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_e_drr_ll_tbl_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_e_drr_reverse_ll_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_e_drr_reverse_ll_tbl_u *value) +{ + if (index >= L1_E_DRR_REVERSE_LL_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L1_E_DRR_REVERSE_LL_TBL_ADDRESS + \ + index * L1_E_DRR_REVERSE_LL_TBL_INC, + &value->val); +} + +sw_error_t +hppe_l1_e_drr_reverse_ll_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_e_drr_reverse_ll_tbl_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_a_flow_entry_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_a_flow_entry_tbl_u *value) +{ + if (index >= L1_A_FLOW_ENTRY_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L1_A_FLOW_ENTRY_TBL_ADDRESS + \ + index * L1_A_FLOW_ENTRY_TBL_INC, + &value->val); +} + +sw_error_t +hppe_l1_a_flow_entry_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_a_flow_entry_tbl_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_b_flow_entry_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_b_flow_entry_tbl_u *value) +{ + if (index >= L1_B_FLOW_ENTRY_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L1_B_FLOW_ENTRY_TBL_ADDRESS + \ + index * L1_B_FLOW_ENTRY_TBL_INC, + &value->val); +} + +sw_error_t +hppe_l1_b_flow_entry_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_b_flow_entry_tbl_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_sp_entry_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_sp_entry_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L1_SP_ENTRY_TBL_ADDRESS + \ + index * L1_SP_ENTRY_TBL_INC, + value->val, + 9); +} + +sw_error_t +hppe_l1_sp_entry_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_sp_entry_tbl_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_ens_q_ll_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_ens_q_ll_tbl_u *value) +{ + if (index >= L1_ENS_Q_LL_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L1_ENS_Q_LL_TBL_ADDRESS + \ + index * L1_ENS_Q_LL_TBL_INC, + &value->val); +} + +sw_error_t +hppe_l1_ens_q_ll_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_ens_q_ll_tbl_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_ens_q_head_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_ens_q_head_tbl_u *value) +{ + if (index >= L1_ENS_Q_HEAD_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L1_ENS_Q_HEAD_TBL_ADDRESS + \ + index * L1_ENS_Q_HEAD_TBL_INC, + &value->val); +} + +sw_error_t +hppe_l1_ens_q_head_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_ens_q_head_tbl_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_ens_q_entry_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_ens_q_entry_tbl_u *value) +{ + if (index >= L1_ENS_Q_ENTRY_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L1_ENS_Q_ENTRY_TBL_ADDRESS + \ + index * L1_ENS_Q_ENTRY_TBL_INC, + &value->val); +} + +sw_error_t +hppe_l1_ens_q_entry_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_ens_q_entry_tbl_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_flow_status_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_flow_status_tbl_u *value) +{ + if (index >= L1_FLOW_STATUS_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L1_FLOW_STATUS_TBL_ADDRESS + \ + index * L1_FLOW_STATUS_TBL_INC, + &value->val); +} + +sw_error_t +hppe_l1_flow_status_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_flow_status_tbl_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_psch_tdm_cfg_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union psch_tdm_cfg_tbl_u *value) +{ + if (index >= PSCH_TDM_CFG_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + PSCH_TDM_CFG_TBL_ADDRESS + \ + index * PSCH_TDM_CFG_TBL_INC, + &value->val); +} +#endif +sw_error_t +hppe_psch_tdm_cfg_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union psch_tdm_cfg_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + PSCH_TDM_CFG_TBL_ADDRESS + \ + index * PSCH_TDM_CFG_TBL_INC, + value->val); +} +#ifndef IN_QOS_MINI +sw_error_t +hppe_tdm_depth_cfg_tdm_depth_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union tdm_depth_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tdm_depth_cfg_get(dev_id, ®_val); + *value = reg_val.bf.tdm_depth; + return ret; +} + +sw_error_t +hppe_tdm_depth_cfg_tdm_depth_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union tdm_depth_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tdm_depth_cfg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tdm_depth = value; + ret = hppe_tdm_depth_cfg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_min_max_mode_cfg_min_max_mode_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union min_max_mode_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_min_max_mode_cfg_get(dev_id, ®_val); + *value = reg_val.bf.min_max_mode; + return ret; +} + +sw_error_t +hppe_min_max_mode_cfg_min_max_mode_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union min_max_mode_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_min_max_mode_cfg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.min_max_mode = value; + ret = hppe_min_max_mode_cfg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_tm_dbg_addr_dbg_addr_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union tm_dbg_addr_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tm_dbg_addr_get(dev_id, ®_val); + *value = reg_val.bf.dbg_addr; + return ret; +} + +sw_error_t +hppe_tm_dbg_addr_dbg_addr_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union tm_dbg_addr_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tm_dbg_addr_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.dbg_addr = value; + ret = hppe_tm_dbg_addr_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_tm_dbg_data_dbg_data_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union tm_dbg_data_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tm_dbg_data_get(dev_id, ®_val); + *value = reg_val.bf.dbg_data; + return ret; +} + +sw_error_t +hppe_tm_dbg_data_dbg_data_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_eco_reserve_0_eco_res_0_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union eco_reserve_0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eco_reserve_0_get(dev_id, ®_val); + *value = reg_val.bf.eco_res_0; + return ret; +} + +sw_error_t +hppe_eco_reserve_0_eco_res_0_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union eco_reserve_0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eco_reserve_0_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.eco_res_0 = value; + ret = hppe_eco_reserve_0_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_eco_reserve_1_eco_res_1_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union eco_reserve_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eco_reserve_1_get(dev_id, ®_val); + *value = reg_val.bf.eco_res_1; + return ret; +} + +sw_error_t +hppe_eco_reserve_1_eco_res_1_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union eco_reserve_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eco_reserve_1_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.eco_res_1 = value; + ret = hppe_eco_reserve_1_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l0_flow_map_tbl_e_pri_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_flow_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_flow_map_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.e_pri; + return ret; +} + +sw_error_t +hppe_l0_flow_map_tbl_e_pri_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l0_flow_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_flow_map_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.e_pri = value; + ret = hppe_l0_flow_map_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l0_flow_map_tbl_c_pri_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_flow_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_flow_map_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.c_pri; + return ret; +} + +sw_error_t +hppe_l0_flow_map_tbl_c_pri_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l0_flow_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_flow_map_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.c_pri = value; + ret = hppe_l0_flow_map_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l0_flow_map_tbl_e_drr_wt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_flow_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_flow_map_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.e_drr_wt; + return ret; +} + +sw_error_t +hppe_l0_flow_map_tbl_e_drr_wt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l0_flow_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_flow_map_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.e_drr_wt = value; + ret = hppe_l0_flow_map_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l0_flow_map_tbl_c_drr_wt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_flow_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_flow_map_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.c_drr_wt; + return ret; +} + +sw_error_t +hppe_l0_flow_map_tbl_c_drr_wt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l0_flow_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_flow_map_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.c_drr_wt = value; + ret = hppe_l0_flow_map_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l0_flow_map_tbl_sp_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_flow_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_flow_map_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.sp_id; + return ret; +} + +sw_error_t +hppe_l0_flow_map_tbl_sp_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l0_flow_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_flow_map_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.sp_id = value; + ret = hppe_l0_flow_map_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l0_c_sp_cfg_tbl_drr_credit_unit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_c_sp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_c_sp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.drr_credit_unit; + return ret; +} + +sw_error_t +hppe_l0_c_sp_cfg_tbl_drr_credit_unit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l0_c_sp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_c_sp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.drr_credit_unit = value; + ret = hppe_l0_c_sp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l0_c_sp_cfg_tbl_drr_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_c_sp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_c_sp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.drr_id; + return ret; +} + +sw_error_t +hppe_l0_c_sp_cfg_tbl_drr_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l0_c_sp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_c_sp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.drr_id = value; + ret = hppe_l0_c_sp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l0_e_sp_cfg_tbl_drr_credit_unit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_e_sp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_e_sp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.drr_credit_unit; + return ret; +} + +sw_error_t +hppe_l0_e_sp_cfg_tbl_drr_credit_unit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l0_e_sp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_e_sp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.drr_credit_unit = value; + ret = hppe_l0_e_sp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l0_e_sp_cfg_tbl_drr_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_e_sp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_e_sp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.drr_id; + return ret; +} + +sw_error_t +hppe_l0_e_sp_cfg_tbl_drr_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l0_e_sp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_e_sp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.drr_id = value; + ret = hppe_l0_e_sp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l0_flow_port_map_tbl_port_num_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_flow_port_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_flow_port_map_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.port_num; + return ret; +} + +sw_error_t +hppe_l0_flow_port_map_tbl_port_num_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l0_flow_port_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_flow_port_map_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_num = value; + ret = hppe_l0_flow_port_map_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l0_c_drr_head_tbl_backup_head_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_c_drr_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_c_drr_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.backup_head; + return ret; +} + +sw_error_t +hppe_l0_c_drr_head_tbl_backup_head_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_c_drr_head_tbl_active_vld_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_c_drr_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_c_drr_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.active_vld; + return ret; +} + +sw_error_t +hppe_l0_c_drr_head_tbl_active_vld_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_c_drr_head_tbl_backup_max_n_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_c_drr_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_c_drr_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.backup_max_n; + return ret; +} + +sw_error_t +hppe_l0_c_drr_head_tbl_backup_max_n_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_c_drr_head_tbl_active_tail_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_c_drr_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_c_drr_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.active_tail_1 << 8 | \ + reg_val.bf.active_tail_0; + return ret; +} + +sw_error_t +hppe_l0_c_drr_head_tbl_active_tail_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_c_drr_head_tbl_active_head_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_c_drr_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_c_drr_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.active_head; + return ret; +} + +sw_error_t +hppe_l0_c_drr_head_tbl_active_head_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_c_drr_head_tbl_backup_vld_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_c_drr_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_c_drr_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.backup_vld; + return ret; +} + +sw_error_t +hppe_l0_c_drr_head_tbl_backup_vld_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_c_drr_head_tbl_active_max_n_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_c_drr_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_c_drr_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.active_max_n; + return ret; +} + +sw_error_t +hppe_l0_c_drr_head_tbl_active_max_n_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_c_drr_head_tbl_backup_tail_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_c_drr_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_c_drr_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.backup_tail; + return ret; +} + +sw_error_t +hppe_l0_c_drr_head_tbl_backup_tail_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_e_drr_head_tbl_backup_head_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_e_drr_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_e_drr_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.backup_head; + return ret; +} + +sw_error_t +hppe_l0_e_drr_head_tbl_backup_head_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_e_drr_head_tbl_active_vld_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_e_drr_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_e_drr_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.active_vld; + return ret; +} + +sw_error_t +hppe_l0_e_drr_head_tbl_active_vld_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_e_drr_head_tbl_backup_max_n_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_e_drr_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_e_drr_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.backup_max_n; + return ret; +} + +sw_error_t +hppe_l0_e_drr_head_tbl_backup_max_n_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_e_drr_head_tbl_active_tail_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_e_drr_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_e_drr_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.active_tail_1 << 8 | \ + reg_val.bf.active_tail_0; + return ret; +} + +sw_error_t +hppe_l0_e_drr_head_tbl_active_tail_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_e_drr_head_tbl_active_head_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_e_drr_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_e_drr_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.active_head; + return ret; +} + +sw_error_t +hppe_l0_e_drr_head_tbl_active_head_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_e_drr_head_tbl_backup_vld_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_e_drr_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_e_drr_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.backup_vld; + return ret; +} + +sw_error_t +hppe_l0_e_drr_head_tbl_backup_vld_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_e_drr_head_tbl_active_max_n_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_e_drr_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_e_drr_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.active_max_n; + return ret; +} + +sw_error_t +hppe_l0_e_drr_head_tbl_active_max_n_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_e_drr_head_tbl_backup_tail_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_e_drr_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_e_drr_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.backup_tail; + return ret; +} + +sw_error_t +hppe_l0_e_drr_head_tbl_backup_tail_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_drr_credit_tbl_e_drr_credit_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_drr_credit_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_drr_credit_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.e_drr_credit_neg; + return ret; +} + +sw_error_t +hppe_l0_drr_credit_tbl_e_drr_credit_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_drr_credit_tbl_c_drr_credit_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_drr_credit_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_drr_credit_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.c_drr_credit_neg; + return ret; +} + +sw_error_t +hppe_l0_drr_credit_tbl_c_drr_credit_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_drr_credit_tbl_c_drr_credit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_drr_credit_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_drr_credit_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.c_drr_credit; + return ret; +} + +sw_error_t +hppe_l0_drr_credit_tbl_c_drr_credit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_drr_credit_tbl_e_drr_credit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_drr_credit_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_drr_credit_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.e_drr_credit_1 << 7 | \ + reg_val.bf.e_drr_credit_0; + return ret; +} + +sw_error_t +hppe_l0_drr_credit_tbl_e_drr_credit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_c_drr_ll_tbl_next_ptr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_c_drr_ll_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_c_drr_ll_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.next_ptr; + return ret; +} + +sw_error_t +hppe_l0_c_drr_ll_tbl_next_ptr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_c_drr_reverse_ll_tbl_pre_ptr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_c_drr_reverse_ll_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_c_drr_reverse_ll_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.pre_ptr; + return ret; +} + +sw_error_t +hppe_l0_c_drr_reverse_ll_tbl_pre_ptr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_e_drr_ll_tbl_next_ptr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_e_drr_ll_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_e_drr_ll_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.next_ptr; + return ret; +} + +sw_error_t +hppe_l0_e_drr_ll_tbl_next_ptr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_e_drr_reverse_ll_tbl_pre_ptr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_e_drr_reverse_ll_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_e_drr_reverse_ll_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.pre_ptr; + return ret; +} + +sw_error_t +hppe_l0_e_drr_reverse_ll_tbl_pre_ptr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_sp_entry_tbl_entry_vld_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_sp_entry_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_sp_entry_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.entry_vld; + return ret; +} + +sw_error_t +hppe_l0_sp_entry_tbl_entry_vld_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_sp_entry_tbl_entry_path_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union l0_sp_entry_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_sp_entry_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.entry_path_id_1 << 32 | \ + reg_val.bf.entry_path_id_0; + return ret; +} + +sw_error_t +hppe_l0_sp_entry_tbl_entry_path_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_ens_q_ll_tbl_next_ptr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_ens_q_ll_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_ens_q_ll_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.next_ptr; + return ret; +} + +sw_error_t +hppe_l0_ens_q_ll_tbl_next_ptr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_ens_q_head_tbl_vld_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_ens_q_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_ens_q_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.vld; + return ret; +} + +sw_error_t +hppe_l0_ens_q_head_tbl_vld_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_ens_q_head_tbl_head_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_ens_q_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_ens_q_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.head; + return ret; +} + +sw_error_t +hppe_l0_ens_q_head_tbl_head_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_ens_q_head_tbl_tail_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_ens_q_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_ens_q_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.tail; + return ret; +} + +sw_error_t +hppe_l0_ens_q_head_tbl_tail_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_ens_q_entry_tbl_entry_ens_in_q_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_ens_q_entry_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_ens_q_entry_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.entry_ens_in_q; + return ret; +} + +sw_error_t +hppe_l0_ens_q_entry_tbl_entry_ens_in_q_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_ens_q_entry_tbl_entry_ens_vld_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_ens_q_entry_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_ens_q_entry_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.entry_ens_vld; + return ret; +} + +sw_error_t +hppe_l0_ens_q_entry_tbl_entry_ens_vld_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_ens_q_entry_tbl_entry_ens_type_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_ens_q_entry_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_ens_q_entry_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.entry_ens_type; + return ret; +} + +sw_error_t +hppe_l0_ens_q_entry_tbl_entry_ens_type_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_flow_status_tbl_en_cdrr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_flow_status_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_flow_status_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.en_cdrr; + return ret; +} + +sw_error_t +hppe_l0_flow_status_tbl_en_cdrr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_flow_status_tbl_en_edrr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_flow_status_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_flow_status_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.en_edrr; + return ret; +} + +sw_error_t +hppe_l0_flow_status_tbl_en_edrr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_flow_status_tbl_en_level_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_flow_status_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_flow_status_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.en_level; + return ret; +} + +sw_error_t +hppe_l0_flow_status_tbl_en_level_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_ring_q_map_tbl_queue_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union ring_q_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ring_q_map_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.queue_bitmap_1 << 32 | \ + reg_val.bf.queue_bitmap_0; + return ret; +} + +sw_error_t +hppe_ring_q_map_tbl_queue_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union ring_q_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ring_q_map_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.queue_bitmap_1 = value >> 32; + reg_val.bf.queue_bitmap_0 = value & (((a_uint64_t)1<<32)-1); + ret = hppe_ring_q_map_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_rfc_block_tbl_rfc_block_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rfc_block_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rfc_block_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.rfc_block; + return ret; +} + +sw_error_t +hppe_rfc_block_tbl_rfc_block_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rfc_status_tbl_rfc_status_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rfc_status_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rfc_status_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.rfc_status; + return ret; +} + +sw_error_t +hppe_rfc_status_tbl_rfc_status_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_deq_dis_tbl_deq_dis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union deq_dis_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_deq_dis_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.deq_dis; + return ret; +} + +sw_error_t +hppe_deq_dis_tbl_deq_dis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union deq_dis_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_deq_dis_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.deq_dis = value; + ret = hppe_deq_dis_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l1_flow_map_tbl_e_pri_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_flow_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_flow_map_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.e_pri; + return ret; +} + +sw_error_t +hppe_l1_flow_map_tbl_e_pri_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l1_flow_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_flow_map_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.e_pri = value; + ret = hppe_l1_flow_map_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l1_flow_map_tbl_c_pri_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_flow_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_flow_map_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.c_pri; + return ret; +} + +sw_error_t +hppe_l1_flow_map_tbl_c_pri_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l1_flow_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_flow_map_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.c_pri = value; + ret = hppe_l1_flow_map_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l1_flow_map_tbl_e_drr_wt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_flow_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_flow_map_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.e_drr_wt; + return ret; +} + +sw_error_t +hppe_l1_flow_map_tbl_e_drr_wt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l1_flow_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_flow_map_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.e_drr_wt = value; + ret = hppe_l1_flow_map_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l1_flow_map_tbl_c_drr_wt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_flow_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_flow_map_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.c_drr_wt; + return ret; +} + +sw_error_t +hppe_l1_flow_map_tbl_c_drr_wt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l1_flow_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_flow_map_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.c_drr_wt = value; + ret = hppe_l1_flow_map_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l1_flow_map_tbl_sp_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_flow_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_flow_map_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.sp_id; + return ret; +} + +sw_error_t +hppe_l1_flow_map_tbl_sp_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l1_flow_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_flow_map_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.sp_id = value; + ret = hppe_l1_flow_map_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l1_c_sp_cfg_tbl_drr_credit_unit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_c_sp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_c_sp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.drr_credit_unit; + return ret; +} + +sw_error_t +hppe_l1_c_sp_cfg_tbl_drr_credit_unit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l1_c_sp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_c_sp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.drr_credit_unit = value; + ret = hppe_l1_c_sp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l1_c_sp_cfg_tbl_drr_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_c_sp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_c_sp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.drr_id; + return ret; +} + +sw_error_t +hppe_l1_c_sp_cfg_tbl_drr_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l1_c_sp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_c_sp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.drr_id = value; + ret = hppe_l1_c_sp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l1_e_sp_cfg_tbl_drr_credit_unit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_e_sp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_e_sp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.drr_credit_unit; + return ret; +} + +sw_error_t +hppe_l1_e_sp_cfg_tbl_drr_credit_unit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l1_e_sp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_e_sp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.drr_credit_unit = value; + ret = hppe_l1_e_sp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l1_e_sp_cfg_tbl_drr_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_e_sp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_e_sp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.drr_id; + return ret; +} + +sw_error_t +hppe_l1_e_sp_cfg_tbl_drr_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l1_e_sp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_e_sp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.drr_id = value; + ret = hppe_l1_e_sp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l1_flow_port_map_tbl_port_num_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_flow_port_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_flow_port_map_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.port_num; + return ret; +} + +sw_error_t +hppe_l1_flow_port_map_tbl_port_num_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l1_flow_port_map_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_flow_port_map_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_num = value; + ret = hppe_l1_flow_port_map_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l1_c_drr_head_tbl_backup_head_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_c_drr_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_c_drr_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.backup_head; + return ret; +} + +sw_error_t +hppe_l1_c_drr_head_tbl_backup_head_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_c_drr_head_tbl_active_vld_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_c_drr_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_c_drr_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.active_vld; + return ret; +} + +sw_error_t +hppe_l1_c_drr_head_tbl_active_vld_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_c_drr_head_tbl_backup_max_n_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_c_drr_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_c_drr_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.backup_max_n; + return ret; +} + +sw_error_t +hppe_l1_c_drr_head_tbl_backup_max_n_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_c_drr_head_tbl_active_tail_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_c_drr_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_c_drr_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.active_tail; + return ret; +} + +sw_error_t +hppe_l1_c_drr_head_tbl_active_tail_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_c_drr_head_tbl_active_head_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_c_drr_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_c_drr_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.active_head; + return ret; +} + +sw_error_t +hppe_l1_c_drr_head_tbl_active_head_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_c_drr_head_tbl_backup_vld_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_c_drr_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_c_drr_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.backup_vld; + return ret; +} + +sw_error_t +hppe_l1_c_drr_head_tbl_backup_vld_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_c_drr_head_tbl_active_max_n_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_c_drr_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_c_drr_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.active_max_n_1 << 1 | \ + reg_val.bf.active_max_n_0; + return ret; +} + +sw_error_t +hppe_l1_c_drr_head_tbl_active_max_n_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_c_drr_head_tbl_backup_tail_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_c_drr_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_c_drr_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.backup_tail; + return ret; +} + +sw_error_t +hppe_l1_c_drr_head_tbl_backup_tail_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_e_drr_head_tbl_backup_head_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_e_drr_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_e_drr_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.backup_head; + return ret; +} + +sw_error_t +hppe_l1_e_drr_head_tbl_backup_head_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_e_drr_head_tbl_active_vld_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_e_drr_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_e_drr_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.active_vld; + return ret; +} + +sw_error_t +hppe_l1_e_drr_head_tbl_active_vld_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_e_drr_head_tbl_backup_max_n_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_e_drr_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_e_drr_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.backup_max_n; + return ret; +} + +sw_error_t +hppe_l1_e_drr_head_tbl_backup_max_n_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_e_drr_head_tbl_active_tail_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_e_drr_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_e_drr_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.active_tail; + return ret; +} + +sw_error_t +hppe_l1_e_drr_head_tbl_active_tail_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_e_drr_head_tbl_active_head_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_e_drr_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_e_drr_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.active_head; + return ret; +} + +sw_error_t +hppe_l1_e_drr_head_tbl_active_head_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_e_drr_head_tbl_backup_vld_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_e_drr_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_e_drr_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.backup_vld; + return ret; +} + +sw_error_t +hppe_l1_e_drr_head_tbl_backup_vld_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_e_drr_head_tbl_active_max_n_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_e_drr_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_e_drr_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.active_max_n_1 << 1 | \ + reg_val.bf.active_max_n_0; + return ret; +} + +sw_error_t +hppe_l1_e_drr_head_tbl_active_max_n_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_e_drr_head_tbl_backup_tail_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_e_drr_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_e_drr_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.backup_tail; + return ret; +} + +sw_error_t +hppe_l1_e_drr_head_tbl_backup_tail_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_drr_credit_tbl_e_drr_credit_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_drr_credit_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_drr_credit_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.e_drr_credit_neg; + return ret; +} + +sw_error_t +hppe_l1_drr_credit_tbl_e_drr_credit_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_drr_credit_tbl_c_drr_credit_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_drr_credit_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_drr_credit_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.c_drr_credit_neg; + return ret; +} + +sw_error_t +hppe_l1_drr_credit_tbl_c_drr_credit_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_drr_credit_tbl_c_drr_credit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_drr_credit_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_drr_credit_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.c_drr_credit; + return ret; +} + +sw_error_t +hppe_l1_drr_credit_tbl_c_drr_credit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_drr_credit_tbl_e_drr_credit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_drr_credit_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_drr_credit_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.e_drr_credit_1 << 7 | \ + reg_val.bf.e_drr_credit_0; + return ret; +} + +sw_error_t +hppe_l1_drr_credit_tbl_e_drr_credit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_c_drr_ll_tbl_next_ptr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_c_drr_ll_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_c_drr_ll_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.next_ptr; + return ret; +} + +sw_error_t +hppe_l1_c_drr_ll_tbl_next_ptr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_c_drr_reverse_ll_tbl_pre_ptr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_c_drr_reverse_ll_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_c_drr_reverse_ll_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.pre_ptr; + return ret; +} + +sw_error_t +hppe_l1_c_drr_reverse_ll_tbl_pre_ptr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_e_drr_ll_tbl_next_ptr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_e_drr_ll_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_e_drr_ll_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.next_ptr; + return ret; +} + +sw_error_t +hppe_l1_e_drr_ll_tbl_next_ptr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_e_drr_reverse_ll_tbl_pre_ptr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_e_drr_reverse_ll_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_e_drr_reverse_ll_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.pre_ptr; + return ret; +} + +sw_error_t +hppe_l1_e_drr_reverse_ll_tbl_pre_ptr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_a_flow_entry_tbl_entry_path_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_a_flow_entry_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_a_flow_entry_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.entry_path_id; + return ret; +} + +sw_error_t +hppe_l1_a_flow_entry_tbl_entry_path_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_b_flow_entry_tbl_entry_path_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_b_flow_entry_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_b_flow_entry_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.entry_path_id; + return ret; +} + +sw_error_t +hppe_l1_b_flow_entry_tbl_entry_path_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_sp_entry_tbl_entry_vld_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_sp_entry_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_sp_entry_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.entry_vld; + return ret; +} + +sw_error_t +hppe_l1_sp_entry_tbl_entry_vld_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_sp_entry_tbl_entry_path_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union l1_sp_entry_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_sp_entry_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.entry_path_id_1 << 32 | \ + reg_val.bf.entry_path_id_0; + return ret; +} + +sw_error_t +hppe_l1_sp_entry_tbl_entry_path_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_ens_q_ll_tbl_next_ptr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_ens_q_ll_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_ens_q_ll_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.next_ptr; + return ret; +} + +sw_error_t +hppe_l1_ens_q_ll_tbl_next_ptr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_ens_q_head_tbl_vld_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_ens_q_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_ens_q_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.vld; + return ret; +} + +sw_error_t +hppe_l1_ens_q_head_tbl_vld_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_ens_q_head_tbl_head_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_ens_q_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_ens_q_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.head; + return ret; +} + +sw_error_t +hppe_l1_ens_q_head_tbl_head_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_ens_q_head_tbl_tail_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_ens_q_head_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_ens_q_head_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.tail; + return ret; +} + +sw_error_t +hppe_l1_ens_q_head_tbl_tail_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_ens_q_entry_tbl_entry_ens_in_q_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_ens_q_entry_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_ens_q_entry_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.entry_ens_in_q; + return ret; +} + +sw_error_t +hppe_l1_ens_q_entry_tbl_entry_ens_in_q_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_ens_q_entry_tbl_entry_ens_vld_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_ens_q_entry_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_ens_q_entry_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.entry_ens_vld; + return ret; +} + +sw_error_t +hppe_l1_ens_q_entry_tbl_entry_ens_vld_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_ens_q_entry_tbl_entry_ens_type_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_ens_q_entry_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_ens_q_entry_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.entry_ens_type; + return ret; +} + +sw_error_t +hppe_l1_ens_q_entry_tbl_entry_ens_type_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_flow_status_tbl_en_cdrr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_flow_status_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_flow_status_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.en_cdrr; + return ret; +} + +sw_error_t +hppe_l1_flow_status_tbl_en_cdrr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_flow_status_tbl_en_edrr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_flow_status_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_flow_status_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.en_edrr; + return ret; +} + +sw_error_t +hppe_l1_flow_status_tbl_en_edrr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_flow_status_tbl_en_level_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_flow_status_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_flow_status_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.en_level; + return ret; +} + +sw_error_t +hppe_l1_flow_status_tbl_en_level_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_psch_tdm_cfg_tbl_ens_port_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union psch_tdm_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_psch_tdm_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ens_port; + return ret; +} + +sw_error_t +hppe_psch_tdm_cfg_tbl_ens_port_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union psch_tdm_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_psch_tdm_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ens_port = value; + ret = hppe_psch_tdm_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_psch_tdm_cfg_tbl_des_port_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union psch_tdm_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_psch_tdm_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.des_port; + return ret; +} + +sw_error_t +hppe_psch_tdm_cfg_tbl_des_port_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union psch_tdm_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_psch_tdm_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.des_port = value; + ret = hppe_psch_tdm_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_psch_tdm_cfg_tbl_ens_port_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union psch_tdm_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_psch_tdm_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ens_port_bitmap; + return ret; +} + +sw_error_t +hppe_psch_tdm_cfg_tbl_ens_port_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union psch_tdm_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_psch_tdm_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ens_port_bitmap = value; + ret = hppe_psch_tdm_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_qos_ctrl_port_flow_qos_pri_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_qos_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_qos_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.port_flow_qos_pri; + return ret; +} + +sw_error_t +hppe_port_qos_ctrl_port_flow_qos_pri_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_qos_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_qos_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_flow_qos_pri = value; + ret = hppe_port_qos_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_qos_ctrl_port_dscp_qos_pri_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_qos_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_qos_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.port_dscp_qos_pri; + return ret; +} + +sw_error_t +hppe_port_qos_ctrl_port_dscp_qos_pri_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_qos_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_qos_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_dscp_qos_pri = value; + ret = hppe_port_qos_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_qos_ctrl_port_dscp_change_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_qos_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_qos_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.port_dscp_change_en; + return ret; +} + +sw_error_t +hppe_port_qos_ctrl_port_dscp_change_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_qos_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_qos_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_dscp_change_en = value; + ret = hppe_port_qos_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_qos_ctrl_port_pcp_change_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_qos_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_qos_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.port_pcp_change_en; + return ret; +} + +sw_error_t +hppe_port_qos_ctrl_port_pcp_change_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_qos_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_qos_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_pcp_change_en = value; + ret = hppe_port_qos_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_qos_ctrl_port_acl_qos_pri_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_qos_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_qos_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.port_acl_qos_pri; + return ret; +} + +sw_error_t +hppe_port_qos_ctrl_port_acl_qos_pri_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_qos_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_qos_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_acl_qos_pri = value; + ret = hppe_port_qos_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_qos_ctrl_flow_qos_group_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_qos_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_qos_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.flow_qos_group_id; + return ret; +} + +sw_error_t +hppe_port_qos_ctrl_flow_qos_group_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_qos_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_qos_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.flow_qos_group_id = value; + ret = hppe_port_qos_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_qos_ctrl_port_preheader_qos_pri_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_qos_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_qos_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.port_preheader_qos_pri; + return ret; +} + +sw_error_t +hppe_port_qos_ctrl_port_preheader_qos_pri_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_qos_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_qos_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_preheader_qos_pri = value; + ret = hppe_port_qos_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_qos_ctrl_pcp_qos_group_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_qos_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_qos_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.pcp_qos_group_id; + return ret; +} + +sw_error_t +hppe_port_qos_ctrl_pcp_qos_group_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_qos_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_qos_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pcp_qos_group_id = value; + ret = hppe_port_qos_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_qos_ctrl_dscp_qos_group_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_qos_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_qos_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.dscp_qos_group_id; + return ret; +} + +sw_error_t +hppe_port_qos_ctrl_dscp_qos_group_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_qos_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_qos_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.dscp_qos_group_id = value; + ret = hppe_port_qos_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_qos_ctrl_port_pcp_qos_pri_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_qos_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_qos_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.port_pcp_qos_pri; + return ret; +} + +sw_error_t +hppe_port_qos_ctrl_port_pcp_qos_pri_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_qos_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_qos_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_pcp_qos_pri = value; + ret = hppe_port_qos_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_qos_ctrl_port_dei_change_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_qos_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_qos_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.port_dei_change_en; + return ret; +} + +sw_error_t +hppe_port_qos_ctrl_port_dei_change_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_qos_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_qos_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_dei_change_en = value; + ret = hppe_port_qos_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pcp_qos_group_0_qos_info_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pcp_qos_group_0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pcp_qos_group_0_get(dev_id, index, ®_val); + *value = reg_val.bf.qos_info; + return ret; +} + +sw_error_t +hppe_pcp_qos_group_0_qos_info_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pcp_qos_group_0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pcp_qos_group_0_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.qos_info = value; + ret = hppe_pcp_qos_group_0_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pcp_qos_group_1_qos_info_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pcp_qos_group_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pcp_qos_group_1_get(dev_id, index, ®_val); + *value = reg_val.bf.qos_info; + return ret; +} + +sw_error_t +hppe_pcp_qos_group_1_qos_info_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pcp_qos_group_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pcp_qos_group_1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.qos_info = value; + ret = hppe_pcp_qos_group_1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_flow_qos_group_0_qos_info_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union flow_qos_group_0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_qos_group_0_get(dev_id, index, ®_val); + *value = reg_val.bf.qos_info; + return ret; +} + +sw_error_t +hppe_flow_qos_group_0_qos_info_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union flow_qos_group_0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_qos_group_0_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.qos_info = value; + ret = hppe_flow_qos_group_0_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_flow_qos_group_1_qos_info_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union flow_qos_group_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_qos_group_1_get(dev_id, index, ®_val); + *value = reg_val.bf.qos_info; + return ret; +} + +sw_error_t +hppe_flow_qos_group_1_qos_info_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union flow_qos_group_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_flow_qos_group_1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.qos_info = value; + ret = hppe_flow_qos_group_1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_dscp_qos_group_0_qos_info_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union dscp_qos_group_0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_dscp_qos_group_0_get(dev_id, index, ®_val); + *value = reg_val.bf.qos_info; + return ret; +} + +sw_error_t +hppe_dscp_qos_group_0_qos_info_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union dscp_qos_group_0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_dscp_qos_group_0_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.qos_info = value; + ret = hppe_dscp_qos_group_0_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_dscp_qos_group_1_qos_info_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union dscp_qos_group_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_dscp_qos_group_1_get(dev_id, index, ®_val); + *value = reg_val.bf.qos_info; + return ret; +} + +sw_error_t +hppe_dscp_qos_group_1_qos_info_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union dscp_qos_group_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_dscp_qos_group_1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.qos_info = value; + ret = hppe_dscp_qos_group_1_set(dev_id, index, ®_val); + return ret; +} +#endif \ No newline at end of file diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_reg_access.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_reg_access.c new file mode 100755 index 000000000..a7eeeda5f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_reg_access.c @@ -0,0 +1,77 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "ssdk_init.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ssdk_plat.h" +#include + +sw_error_t hppe_reg_get(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint32_t *val) +{ + qca_switch_reg_read(dev_id, reg_addr, (a_uint8_t *)val, 4); + return SW_OK; +} + +sw_error_t hppe_reg_set(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint32_t val) +{ + qca_switch_reg_write(dev_id, reg_addr, (a_uint8_t *)&val, 4); + return SW_OK; +} + +sw_error_t hppe_reg_tbl_get(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint32_t *val, a_uint32_t num) +{ + a_uint32_t i = 0; + for(i = 0; i < num; i++) { + hppe_reg_get(dev_id, (reg_addr + i *4), &val[i]); + } + return SW_OK; +} + +sw_error_t hppe_reg_tbl_set(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint32_t *val, a_uint32_t num) +{ + a_uint32_t i = 0; + for(i = 0; i < num; i++) { + hppe_reg_set(dev_id, (reg_addr + i *4), val[i]); + } + return SW_OK; +} + +sw_error_t hppe_uniphy_reg_get(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint32_t index, a_uint32_t *val) +{ + qca_uniphy_reg_read(dev_id, index, reg_addr, (a_uint8_t *)val, 4); + return SW_OK; +} + +sw_error_t hppe_uniphy_reg_set(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint32_t index, a_uint32_t val) +{ + qca_uniphy_reg_write(dev_id, index, reg_addr, (a_uint8_t *)&val, 4); + return SW_OK; +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_rss.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_rss.c new file mode 100755 index 000000000..d1ec5c3da --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_rss.c @@ -0,0 +1,585 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hppe_reg_access.h" +#include "hppe_rss_reg.h" +#include "hppe_rss.h" + +sw_error_t +hppe_rss_hash_mask_reg_get( + a_uint32_t dev_id, + union rss_hash_mask_reg_u *value) +{ + return hppe_reg_get( + dev_id, + IPO_CSR_BASE_ADDR + RSS_HASH_MASK_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_rss_hash_mask_reg_set( + a_uint32_t dev_id, + union rss_hash_mask_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPO_CSR_BASE_ADDR + RSS_HASH_MASK_REG_ADDRESS, + value->val); +} + +sw_error_t +hppe_rss_hash_seed_reg_get( + a_uint32_t dev_id, + union rss_hash_seed_reg_u *value) +{ + return hppe_reg_get( + dev_id, + IPO_CSR_BASE_ADDR + RSS_HASH_SEED_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_rss_hash_seed_reg_set( + a_uint32_t dev_id, + union rss_hash_seed_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPO_CSR_BASE_ADDR + RSS_HASH_SEED_REG_ADDRESS, + value->val); +} + +sw_error_t +hppe_rss_hash_mix_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + union rss_hash_mix_reg_u *value) +{ + if (index >= RSS_HASH_MIX_REG_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPO_CSR_BASE_ADDR + RSS_HASH_MIX_REG_ADDRESS + \ + index * RSS_HASH_MIX_REG_INC, + &value->val); +} + +sw_error_t +hppe_rss_hash_mix_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + union rss_hash_mix_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPO_CSR_BASE_ADDR + RSS_HASH_MIX_REG_ADDRESS + \ + index * RSS_HASH_MIX_REG_INC, + value->val); +} + +sw_error_t +hppe_rss_hash_fin_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + union rss_hash_fin_reg_u *value) +{ + if (index >= RSS_HASH_FIN_REG_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPO_CSR_BASE_ADDR + RSS_HASH_FIN_REG_ADDRESS + \ + index * RSS_HASH_FIN_REG_INC, + &value->val); +} + +sw_error_t +hppe_rss_hash_fin_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + union rss_hash_fin_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPO_CSR_BASE_ADDR + RSS_HASH_FIN_REG_ADDRESS + \ + index * RSS_HASH_FIN_REG_INC, + value->val); +} + +sw_error_t +hppe_rss_hash_mask_ipv4_reg_get( + a_uint32_t dev_id, + union rss_hash_mask_ipv4_reg_u *value) +{ + return hppe_reg_get( + dev_id, + IPO_CSR_BASE_ADDR + RSS_HASH_MASK_IPV4_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_rss_hash_mask_ipv4_reg_set( + a_uint32_t dev_id, + union rss_hash_mask_ipv4_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPO_CSR_BASE_ADDR + RSS_HASH_MASK_IPV4_REG_ADDRESS, + value->val); +} + +sw_error_t +hppe_rss_hash_seed_ipv4_reg_get( + a_uint32_t dev_id, + union rss_hash_seed_ipv4_reg_u *value) +{ + return hppe_reg_get( + dev_id, + IPO_CSR_BASE_ADDR + RSS_HASH_SEED_IPV4_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_rss_hash_seed_ipv4_reg_set( + a_uint32_t dev_id, + union rss_hash_seed_ipv4_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPO_CSR_BASE_ADDR + RSS_HASH_SEED_IPV4_REG_ADDRESS, + value->val); +} + +sw_error_t +hppe_rss_hash_mix_ipv4_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + union rss_hash_mix_ipv4_reg_u *value) +{ + if (index >= RSS_HASH_MIX_IPV4_REG_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPO_CSR_BASE_ADDR + RSS_HASH_MIX_IPV4_REG_ADDRESS + \ + index * RSS_HASH_MIX_IPV4_REG_INC, + &value->val); +} + +sw_error_t +hppe_rss_hash_mix_ipv4_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + union rss_hash_mix_ipv4_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPO_CSR_BASE_ADDR + RSS_HASH_MIX_IPV4_REG_ADDRESS + \ + index * RSS_HASH_MIX_IPV4_REG_INC, + value->val); +} + +sw_error_t +hppe_rss_hash_fin_ipv4_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + union rss_hash_fin_ipv4_reg_u *value) +{ + if (index >= RSS_HASH_FIN_IPV4_REG_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPO_CSR_BASE_ADDR + RSS_HASH_FIN_IPV4_REG_ADDRESS + \ + index * RSS_HASH_FIN_IPV4_REG_INC, + &value->val); +} + +sw_error_t +hppe_rss_hash_fin_ipv4_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + union rss_hash_fin_ipv4_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPO_CSR_BASE_ADDR + RSS_HASH_FIN_IPV4_REG_ADDRESS + \ + index * RSS_HASH_FIN_IPV4_REG_INC, + value->val); +} + +sw_error_t +hppe_rss_hash_mask_reg_fragment_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union rss_hash_mask_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rss_hash_mask_reg_get(dev_id, ®_val); + *value = reg_val.bf.fragment; + return ret; +} + +sw_error_t +hppe_rss_hash_mask_reg_fragment_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union rss_hash_mask_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rss_hash_mask_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.fragment = value; + ret = hppe_rss_hash_mask_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_rss_hash_mask_reg_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union rss_hash_mask_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rss_hash_mask_reg_get(dev_id, ®_val); + *value = reg_val.bf.mask; + return ret; +} + +sw_error_t +hppe_rss_hash_mask_reg_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union rss_hash_mask_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rss_hash_mask_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mask = value; + ret = hppe_rss_hash_mask_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_rss_hash_seed_reg_seed_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union rss_hash_seed_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rss_hash_seed_reg_get(dev_id, ®_val); + *value = reg_val.bf.seed; + return ret; +} + +sw_error_t +hppe_rss_hash_seed_reg_seed_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union rss_hash_seed_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rss_hash_seed_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.seed = value; + ret = hppe_rss_hash_seed_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_rss_hash_mix_reg_hash_mix_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rss_hash_mix_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rss_hash_mix_reg_get(dev_id, index, ®_val); + *value = reg_val.bf.hash_mix; + return ret; +} + +sw_error_t +hppe_rss_hash_mix_reg_hash_mix_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union rss_hash_mix_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rss_hash_mix_reg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.hash_mix = value; + ret = hppe_rss_hash_mix_reg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_rss_hash_fin_reg_fin_outer_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rss_hash_fin_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rss_hash_fin_reg_get(dev_id, index, ®_val); + *value = reg_val.bf.fin_outer; + return ret; +} + +sw_error_t +hppe_rss_hash_fin_reg_fin_outer_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union rss_hash_fin_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rss_hash_fin_reg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.fin_outer = value; + ret = hppe_rss_hash_fin_reg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_rss_hash_fin_reg_fin_inner_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rss_hash_fin_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rss_hash_fin_reg_get(dev_id, index, ®_val); + *value = reg_val.bf.fin_inner; + return ret; +} + +sw_error_t +hppe_rss_hash_fin_reg_fin_inner_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union rss_hash_fin_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rss_hash_fin_reg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.fin_inner = value; + ret = hppe_rss_hash_fin_reg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_rss_hash_mask_ipv4_reg_fragment_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union rss_hash_mask_ipv4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rss_hash_mask_ipv4_reg_get(dev_id, ®_val); + *value = reg_val.bf.fragment; + return ret; +} + +sw_error_t +hppe_rss_hash_mask_ipv4_reg_fragment_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union rss_hash_mask_ipv4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rss_hash_mask_ipv4_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.fragment = value; + ret = hppe_rss_hash_mask_ipv4_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_rss_hash_mask_ipv4_reg_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union rss_hash_mask_ipv4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rss_hash_mask_ipv4_reg_get(dev_id, ®_val); + *value = reg_val.bf.mask; + return ret; +} + +sw_error_t +hppe_rss_hash_mask_ipv4_reg_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union rss_hash_mask_ipv4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rss_hash_mask_ipv4_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mask = value; + ret = hppe_rss_hash_mask_ipv4_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_rss_hash_seed_ipv4_reg_seed_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union rss_hash_seed_ipv4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rss_hash_seed_ipv4_reg_get(dev_id, ®_val); + *value = reg_val.bf.seed; + return ret; +} + +sw_error_t +hppe_rss_hash_seed_ipv4_reg_seed_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union rss_hash_seed_ipv4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rss_hash_seed_ipv4_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.seed = value; + ret = hppe_rss_hash_seed_ipv4_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_rss_hash_mix_ipv4_reg_hash_mix_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rss_hash_mix_ipv4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rss_hash_mix_ipv4_reg_get(dev_id, index, ®_val); + *value = reg_val.bf.hash_mix; + return ret; +} + +sw_error_t +hppe_rss_hash_mix_ipv4_reg_hash_mix_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union rss_hash_mix_ipv4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rss_hash_mix_ipv4_reg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.hash_mix = value; + ret = hppe_rss_hash_mix_ipv4_reg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_rss_hash_fin_ipv4_reg_fin_outer_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rss_hash_fin_ipv4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rss_hash_fin_ipv4_reg_get(dev_id, index, ®_val); + *value = reg_val.bf.fin_outer; + return ret; +} + +sw_error_t +hppe_rss_hash_fin_ipv4_reg_fin_outer_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union rss_hash_fin_ipv4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rss_hash_fin_ipv4_reg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.fin_outer = value; + ret = hppe_rss_hash_fin_ipv4_reg_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_rss_hash_fin_ipv4_reg_fin_inner_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rss_hash_fin_ipv4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rss_hash_fin_ipv4_reg_get(dev_id, index, ®_val); + *value = reg_val.bf.fin_inner; + return ret; +} + +sw_error_t +hppe_rss_hash_fin_ipv4_reg_fin_inner_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union rss_hash_fin_ipv4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rss_hash_fin_ipv4_reg_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.fin_inner = value; + ret = hppe_rss_hash_fin_ipv4_reg_set(dev_id, index, ®_val); + return ret; +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_sec.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_sec.c new file mode 100755 index 000000000..992f47c16 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_sec.c @@ -0,0 +1,1041 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hppe_reg_access.h" +#include "hppe_sec_reg.h" +#include "hppe_sec.h" + +sw_error_t +hppe_l3_exception_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + union l3_exception_cmd_u *value) +{ + if (index >= L3_EXCEPTION_CMD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + L3_EXCEPTION_CMD_ADDRESS + \ + index * L3_EXCEPTION_CMD_INC, + &value->val); +} + +sw_error_t +hppe_l3_exception_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + union l3_exception_cmd_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + L3_EXCEPTION_CMD_ADDRESS + \ + index * L3_EXCEPTION_CMD_INC, + value->val); +} + +sw_error_t +hppe_l3_exp_l3_only_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l3_exp_l3_only_ctrl_u *value) +{ + if (index >= L3_EXP_L3_ONLY_CTRL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + L3_EXP_L3_ONLY_CTRL_ADDRESS + \ + index * L3_EXP_L3_ONLY_CTRL_INC, + &value->val); +} + +sw_error_t +hppe_l3_exp_l3_only_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l3_exp_l3_only_ctrl_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + L3_EXP_L3_ONLY_CTRL_ADDRESS + \ + index * L3_EXP_L3_ONLY_CTRL_INC, + value->val); +} + +sw_error_t +hppe_l3_exp_l2_only_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l3_exp_l2_only_ctrl_u *value) +{ + if (index >= L3_EXP_L2_ONLY_CTRL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + L3_EXP_L2_ONLY_CTRL_ADDRESS + \ + index * L3_EXP_L2_ONLY_CTRL_INC, + &value->val); +} + +sw_error_t +hppe_l3_exp_l2_only_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l3_exp_l2_only_ctrl_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + L3_EXP_L2_ONLY_CTRL_ADDRESS + \ + index * L3_EXP_L2_ONLY_CTRL_INC, + value->val); +} + +sw_error_t +hppe_l3_exp_l2_flow_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l3_exp_l2_flow_ctrl_u *value) +{ + if (index >= L3_EXP_L2_FLOW_CTRL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + L3_EXP_L2_FLOW_CTRL_ADDRESS + \ + index * L3_EXP_L2_FLOW_CTRL_INC, + &value->val); +} + +sw_error_t +hppe_l3_exp_l2_flow_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l3_exp_l2_flow_ctrl_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + L3_EXP_L2_FLOW_CTRL_ADDRESS + \ + index * L3_EXP_L2_FLOW_CTRL_INC, + value->val); +} + +sw_error_t +hppe_l3_exp_l3_flow_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l3_exp_l3_flow_ctrl_u *value) +{ + if (index >= L3_EXP_L3_FLOW_CTRL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + L3_EXP_L3_FLOW_CTRL_ADDRESS + \ + index * L3_EXP_L3_FLOW_CTRL_INC, + &value->val); +} + +sw_error_t +hppe_l3_exp_l3_flow_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l3_exp_l3_flow_ctrl_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + L3_EXP_L3_FLOW_CTRL_ADDRESS + \ + index * L3_EXP_L3_FLOW_CTRL_INC, + value->val); +} + +sw_error_t +hppe_l3_exp_multicast_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l3_exp_multicast_ctrl_u *value) +{ + if (index >= L3_EXP_MULTICAST_CTRL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPE_L3_BASE_ADDR + L3_EXP_MULTICAST_CTRL_ADDRESS + \ + index * L3_EXP_MULTICAST_CTRL_INC, + &value->val); +} + +sw_error_t +hppe_l3_exp_multicast_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l3_exp_multicast_ctrl_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L3_BASE_ADDR + L3_EXP_MULTICAST_CTRL_ADDRESS + \ + index * L3_EXP_MULTICAST_CTRL_INC, + value->val); +} + +sw_error_t +hppe_l3_exception_cmd_l3_excep_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_exception_cmd_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_exception_cmd_get(dev_id, index, ®_val); + *value = reg_val.bf.l3_excep_cmd; + return ret; +} + +sw_error_t +hppe_l3_exception_cmd_l3_excep_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_exception_cmd_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_exception_cmd_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l3_excep_cmd = value; + ret = hppe_l3_exception_cmd_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_exception_cmd_de_acce_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_exception_cmd_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_exception_cmd_get(dev_id, index, ®_val); + *value = reg_val.bf.de_acce; + return ret; +} + +sw_error_t +hppe_l3_exception_cmd_de_acce_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_exception_cmd_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_exception_cmd_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.de_acce = value; + ret = hppe_l3_exception_cmd_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_exp_l3_only_ctrl_excep_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_exp_l3_only_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_exp_l3_only_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.excep_en; + return ret; +} + +sw_error_t +hppe_l3_exp_l3_only_ctrl_excep_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_exp_l3_only_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_exp_l3_only_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.excep_en = value; + ret = hppe_l3_exp_l3_only_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_exp_l2_only_ctrl_excep_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_exp_l2_only_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_exp_l2_only_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.excep_en; + return ret; +} + +sw_error_t +hppe_l3_exp_l2_only_ctrl_excep_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_exp_l2_only_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_exp_l2_only_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.excep_en = value; + ret = hppe_l3_exp_l2_only_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_exp_l2_flow_ctrl_excep_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_exp_l2_flow_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_exp_l2_flow_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.excep_en; + return ret; +} + +sw_error_t +hppe_l3_exp_l2_flow_ctrl_excep_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_exp_l2_flow_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_exp_l2_flow_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.excep_en = value; + ret = hppe_l3_exp_l2_flow_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_exp_l3_flow_ctrl_excep_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_exp_l3_flow_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_exp_l3_flow_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.excep_en; + return ret; +} + +sw_error_t +hppe_l3_exp_l3_flow_ctrl_excep_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_exp_l3_flow_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_exp_l3_flow_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.excep_en = value; + ret = hppe_l3_exp_l3_flow_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_exp_multicast_ctrl_excep_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l3_exp_multicast_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_exp_multicast_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.excep_en; + return ret; +} + +sw_error_t +hppe_l3_exp_multicast_ctrl_excep_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l3_exp_multicast_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_exp_multicast_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.excep_en = value; + ret = hppe_l3_exp_multicast_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l3_exception_parsing_ctrl_reg_get( + a_uint32_t dev_id, + union l3_exception_parsing_ctrl_reg_u *value) +{ + return hppe_reg_get( + dev_id, + IPR_CSR_BASE_ADDR + L3_EXCEPTION_PARSING_CTRL_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_l3_exception_parsing_ctrl_reg_set( + a_uint32_t dev_id, + union l3_exception_parsing_ctrl_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPR_CSR_BASE_ADDR + L3_EXCEPTION_PARSING_CTRL_REG_ADDRESS, + value->val); +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_0_reg_get( + a_uint32_t dev_id, + union l4_exception_parsing_ctrl_0_reg_u *value) +{ + return hppe_reg_get( + dev_id, + IPR_CSR_BASE_ADDR + L4_EXCEPTION_PARSING_CTRL_0_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_0_reg_set( + a_uint32_t dev_id, + union l4_exception_parsing_ctrl_0_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPR_CSR_BASE_ADDR + L4_EXCEPTION_PARSING_CTRL_0_REG_ADDRESS, + value->val); +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_1_reg_get( + a_uint32_t dev_id, + union l4_exception_parsing_ctrl_1_reg_u *value) +{ + return hppe_reg_get( + dev_id, + IPR_CSR_BASE_ADDR + L4_EXCEPTION_PARSING_CTRL_1_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_1_reg_set( + a_uint32_t dev_id, + union l4_exception_parsing_ctrl_1_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPR_CSR_BASE_ADDR + L4_EXCEPTION_PARSING_CTRL_1_REG_ADDRESS, + value->val); +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_2_reg_get( + a_uint32_t dev_id, + union l4_exception_parsing_ctrl_2_reg_u *value) +{ + return hppe_reg_get( + dev_id, + IPR_CSR_BASE_ADDR + L4_EXCEPTION_PARSING_CTRL_2_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_2_reg_set( + a_uint32_t dev_id, + union l4_exception_parsing_ctrl_2_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPR_CSR_BASE_ADDR + L4_EXCEPTION_PARSING_CTRL_2_REG_ADDRESS, + value->val); +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_3_reg_get( + a_uint32_t dev_id, + union l4_exception_parsing_ctrl_3_reg_u *value) +{ + return hppe_reg_get( + dev_id, + IPR_CSR_BASE_ADDR + L4_EXCEPTION_PARSING_CTRL_3_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_3_reg_set( + a_uint32_t dev_id, + union l4_exception_parsing_ctrl_3_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPR_CSR_BASE_ADDR + L4_EXCEPTION_PARSING_CTRL_3_REG_ADDRESS, + value->val); +} + +sw_error_t +hppe_l3_exception_parsing_ctrl_reg_small_hop_limit_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l3_exception_parsing_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_exception_parsing_ctrl_reg_get(dev_id, ®_val); + *value = reg_val.bf.small_hop_limit; + return ret; +} + +sw_error_t +hppe_l3_exception_parsing_ctrl_reg_small_hop_limit_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l3_exception_parsing_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_exception_parsing_ctrl_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.small_hop_limit = value; + ret = hppe_l3_exception_parsing_ctrl_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l3_exception_parsing_ctrl_reg_small_ttl_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l3_exception_parsing_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_exception_parsing_ctrl_reg_get(dev_id, ®_val); + *value = reg_val.bf.small_ttl; + return ret; +} + +sw_error_t +hppe_l3_exception_parsing_ctrl_reg_small_ttl_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l3_exception_parsing_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l3_exception_parsing_ctrl_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.small_ttl = value; + ret = hppe_l3_exception_parsing_ctrl_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_0_reg_tcp_flags0_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l4_exception_parsing_ctrl_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l4_exception_parsing_ctrl_0_reg_get(dev_id, ®_val); + *value = reg_val.bf.tcp_flags0; + return ret; +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_0_reg_tcp_flags0_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l4_exception_parsing_ctrl_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l4_exception_parsing_ctrl_0_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tcp_flags0 = value; + ret = hppe_l4_exception_parsing_ctrl_0_reg_set(dev_id, ®_val); + return ret; +} +sw_error_t +hppe_l4_exception_parsing_ctrl_0_reg_tcp_flags0_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l4_exception_parsing_ctrl_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l4_exception_parsing_ctrl_0_reg_get(dev_id, ®_val); + *value = reg_val.bf.tcp_flags0_mask; + return ret; +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_0_reg_tcp_flags0_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l4_exception_parsing_ctrl_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l4_exception_parsing_ctrl_0_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tcp_flags0_mask = value; + ret = hppe_l4_exception_parsing_ctrl_0_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_0_reg_tcp_flags1_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l4_exception_parsing_ctrl_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l4_exception_parsing_ctrl_0_reg_get(dev_id, ®_val); + *value = reg_val.bf.tcp_flags1; + return ret; +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_0_reg_tcp_flags1_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l4_exception_parsing_ctrl_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l4_exception_parsing_ctrl_0_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tcp_flags1 = value; + ret = hppe_l4_exception_parsing_ctrl_0_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_0_reg_tcp_flags1_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l4_exception_parsing_ctrl_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l4_exception_parsing_ctrl_0_reg_get(dev_id, ®_val); + *value = reg_val.bf.tcp_flags1_mask; + return ret; +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_0_reg_tcp_flags1_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l4_exception_parsing_ctrl_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l4_exception_parsing_ctrl_0_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tcp_flags1_mask = value; + ret = hppe_l4_exception_parsing_ctrl_0_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_1_reg_tcp_flags2_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l4_exception_parsing_ctrl_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l4_exception_parsing_ctrl_1_reg_get(dev_id, ®_val); + *value = reg_val.bf.tcp_flags2; + return ret; +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_1_reg_tcp_flags2_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l4_exception_parsing_ctrl_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l4_exception_parsing_ctrl_1_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tcp_flags2 = value; + ret = hppe_l4_exception_parsing_ctrl_1_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_1_reg_tcp_flags2_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l4_exception_parsing_ctrl_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l4_exception_parsing_ctrl_1_reg_get(dev_id, ®_val); + *value = reg_val.bf.tcp_flags2_mask; + return ret; +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_1_reg_tcp_flags2_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l4_exception_parsing_ctrl_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l4_exception_parsing_ctrl_1_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tcp_flags2_mask = value; + ret = hppe_l4_exception_parsing_ctrl_1_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_1_reg_tcp_flags3_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l4_exception_parsing_ctrl_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l4_exception_parsing_ctrl_1_reg_get(dev_id, ®_val); + *value = reg_val.bf.tcp_flags3; + return ret; +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_1_reg_tcp_flags3_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l4_exception_parsing_ctrl_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l4_exception_parsing_ctrl_1_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tcp_flags3 = value; + ret = hppe_l4_exception_parsing_ctrl_1_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_1_reg_tcp_flags3_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l4_exception_parsing_ctrl_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l4_exception_parsing_ctrl_1_reg_get(dev_id, ®_val); + *value = reg_val.bf.tcp_flags3_mask; + return ret; +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_1_reg_tcp_flags3_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l4_exception_parsing_ctrl_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l4_exception_parsing_ctrl_1_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tcp_flags3_mask = value; + ret = hppe_l4_exception_parsing_ctrl_1_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_2_reg_tcp_flags4_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l4_exception_parsing_ctrl_2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l4_exception_parsing_ctrl_2_reg_get(dev_id, ®_val); + *value = reg_val.bf.tcp_flags4; + return ret; +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_2_reg_tcp_flags4_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l4_exception_parsing_ctrl_2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l4_exception_parsing_ctrl_2_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tcp_flags4 = value; + ret = hppe_l4_exception_parsing_ctrl_2_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_2_reg_tcp_flags4_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l4_exception_parsing_ctrl_2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l4_exception_parsing_ctrl_2_reg_get(dev_id, ®_val); + *value = reg_val.bf.tcp_flags4_mask; + return ret; +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_2_reg_tcp_flags4_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l4_exception_parsing_ctrl_2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l4_exception_parsing_ctrl_2_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tcp_flags4_mask = value; + ret = hppe_l4_exception_parsing_ctrl_2_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_2_reg_tcp_flags5_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l4_exception_parsing_ctrl_2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l4_exception_parsing_ctrl_2_reg_get(dev_id, ®_val); + *value = reg_val.bf.tcp_flags5; + return ret; +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_2_reg_tcp_flags5_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l4_exception_parsing_ctrl_2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l4_exception_parsing_ctrl_2_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tcp_flags5 = value; + ret = hppe_l4_exception_parsing_ctrl_2_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_2_reg_tcp_flags5_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l4_exception_parsing_ctrl_2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l4_exception_parsing_ctrl_2_reg_get(dev_id, ®_val); + *value = reg_val.bf.tcp_flags5_mask; + return ret; +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_2_reg_tcp_flags5_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l4_exception_parsing_ctrl_2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l4_exception_parsing_ctrl_2_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tcp_flags5_mask = value; + ret = hppe_l4_exception_parsing_ctrl_2_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_3_reg_tcp_flags6_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l4_exception_parsing_ctrl_3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l4_exception_parsing_ctrl_3_reg_get(dev_id, ®_val); + *value = reg_val.bf.tcp_flags6; + return ret; +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_3_reg_tcp_flags6_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l4_exception_parsing_ctrl_3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l4_exception_parsing_ctrl_3_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tcp_flags6 = value; + ret = hppe_l4_exception_parsing_ctrl_3_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_3_reg_tcp_flags6_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l4_exception_parsing_ctrl_3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l4_exception_parsing_ctrl_3_reg_get(dev_id, ®_val); + *value = reg_val.bf.tcp_flags6_mask; + return ret; +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_3_reg_tcp_flags6_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l4_exception_parsing_ctrl_3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l4_exception_parsing_ctrl_3_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tcp_flags6_mask = value; + ret = hppe_l4_exception_parsing_ctrl_3_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_3_reg_tcp_flags7_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l4_exception_parsing_ctrl_3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l4_exception_parsing_ctrl_3_reg_get(dev_id, ®_val); + *value = reg_val.bf.tcp_flags7; + return ret; +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_3_reg_tcp_flags7_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l4_exception_parsing_ctrl_3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l4_exception_parsing_ctrl_3_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tcp_flags7 = value; + ret = hppe_l4_exception_parsing_ctrl_3_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_3_reg_tcp_flags7_mask_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union l4_exception_parsing_ctrl_3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l4_exception_parsing_ctrl_3_reg_get(dev_id, ®_val); + *value = reg_val.bf.tcp_flags7_mask; + return ret; +} + +sw_error_t +hppe_l4_exception_parsing_ctrl_3_reg_tcp_flags7_mask_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union l4_exception_parsing_ctrl_3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l4_exception_parsing_ctrl_3_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tcp_flags7_mask = value; + ret = hppe_l4_exception_parsing_ctrl_3_reg_set(dev_id, ®_val); + return ret; +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_servcode.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_servcode.c new file mode 100755 index 000000000..0f5246a8c --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_servcode.c @@ -0,0 +1,511 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hppe_reg_access.h" +#include "hppe_servcode_reg.h" +#include "hppe_servcode.h" + +sw_error_t +hppe_service_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union service_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + INGRESS_VLAN_BASE_ADDR + SERVICE_TBL_ADDRESS + \ + index * SERVICE_TBL_INC, + value->val, + 2); +} + +sw_error_t +hppe_service_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union service_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + INGRESS_VLAN_BASE_ADDR + SERVICE_TBL_ADDRESS + \ + index * SERVICE_TBL_INC, + value->val, + 2); +} + +sw_error_t +hppe_service_tbl_rx_counting_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union service_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_service_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.rx_counting_en; + return ret; +} + +sw_error_t +hppe_service_tbl_rx_counting_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union service_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_service_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_counting_en = value; + ret = hppe_service_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_service_tbl_bypass_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union service_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_service_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.bypass_bitmap; + return ret; +} + +sw_error_t +hppe_service_tbl_bypass_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union service_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_service_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.bypass_bitmap = value; + ret = hppe_service_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_l2_service_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union in_l2_service_tbl_u *value) +{ + if (index >= IN_L2_SERVICE_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + IN_L2_SERVICE_TBL_ADDRESS + \ + index * IN_L2_SERVICE_TBL_INC, + &value->val); +} + +sw_error_t +hppe_in_l2_service_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union in_l2_service_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L2_BASE_ADDR + IN_L2_SERVICE_TBL_ADDRESS + \ + index * IN_L2_SERVICE_TBL_INC, + value->val); +} + +sw_error_t +hppe_in_l2_service_tbl_direction_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_l2_service_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_l2_service_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.direction; + return ret; +} + +sw_error_t +hppe_in_l2_service_tbl_direction_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_l2_service_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_l2_service_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.direction = value; + ret = hppe_in_l2_service_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_l2_service_tbl_rx_cnt_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_l2_service_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_l2_service_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.rx_cnt_en; + return ret; +} + +sw_error_t +hppe_in_l2_service_tbl_rx_cnt_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_l2_service_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_l2_service_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_cnt_en = value; + ret = hppe_in_l2_service_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_l2_service_tbl_tx_cnt_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_l2_service_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_l2_service_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_cnt_en; + return ret; +} + +sw_error_t +hppe_in_l2_service_tbl_tx_cnt_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_l2_service_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_l2_service_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_cnt_en = value; + ret = hppe_in_l2_service_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_l2_service_tbl_bypass_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_l2_service_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_l2_service_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.bypass_bitmap; + return ret; +} + +sw_error_t +hppe_in_l2_service_tbl_bypass_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_l2_service_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_l2_service_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.bypass_bitmap = value; + ret = hppe_in_l2_service_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_l2_service_tbl_dst_port_id_valid_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_l2_service_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_l2_service_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.dst_port_id_valid; + return ret; +} + +sw_error_t +hppe_in_l2_service_tbl_dst_port_id_valid_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_l2_service_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_l2_service_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.dst_port_id_valid = value; + ret = hppe_in_l2_service_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_in_l2_service_tbl_dst_port_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union in_l2_service_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_l2_service_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.dst_port_id; + return ret; +} + +sw_error_t +hppe_in_l2_service_tbl_dst_port_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union in_l2_service_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_in_l2_service_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.dst_port_id = value; + ret = hppe_in_l2_service_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_service_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union eg_service_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + NSS_PTX_CSR_BASE_ADDR + EG_SERVICE_TBL_ADDRESS + \ + index * EG_SERVICE_TBL_INC, + value->val, + 2); +} + +sw_error_t +hppe_eg_service_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union eg_service_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + NSS_PTX_CSR_BASE_ADDR + EG_SERVICE_TBL_ADDRESS + \ + index * EG_SERVICE_TBL_INC, + value->val, + 2); +} + +sw_error_t +hppe_eg_service_tbl_next_service_code_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_service_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_service_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.next_service_code; + return ret; +} + +sw_error_t +hppe_eg_service_tbl_next_service_code_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_service_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_service_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.next_service_code = value; + ret = hppe_eg_service_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_service_tbl_tx_counting_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_service_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_service_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_counting_en; + return ret; +} + +sw_error_t +hppe_eg_service_tbl_tx_counting_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_service_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_service_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_counting_en = value; + ret = hppe_eg_service_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_service_tbl_field_update_action_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_service_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_service_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.field_update_action; + return ret; +} + +sw_error_t +hppe_eg_service_tbl_field_update_action_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_service_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_service_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.field_update_action = value; + ret = hppe_eg_service_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_service_tbl_offset_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_service_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_service_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.offset_sel; + return ret; +} + +sw_error_t +hppe_eg_service_tbl_offset_sel_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_service_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_service_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.offset_sel = value; + ret = hppe_eg_service_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_service_tbl_hw_services_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_service_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_service_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.hw_services; + return ret; +} + +sw_error_t +hppe_eg_service_tbl_hw_services_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_service_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_service_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.hw_services = value; + ret = hppe_eg_service_tbl_set(dev_id, index, ®_val); + return ret; +} \ No newline at end of file diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_shaper.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_shaper.c new file mode 100755 index 000000000..339d3573b --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_shaper.c @@ -0,0 +1,2396 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hppe_reg_access.h" +#include "hppe_shaper_reg.h" +#include "hppe_shaper.h" + +sw_error_t +hppe_shp_slot_cfg_l0_get( + a_uint32_t dev_id, + union shp_slot_cfg_l0_u *value) +{ + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + SHP_SLOT_CFG_L0_ADDRESS, + &value->val); +} + +sw_error_t +hppe_shp_slot_cfg_l0_set( + a_uint32_t dev_id, + union shp_slot_cfg_l0_u *value) +{ + return hppe_reg_set( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + SHP_SLOT_CFG_L0_ADDRESS, + value->val); +} + +sw_error_t +hppe_shp_slot_cfg_l1_get( + a_uint32_t dev_id, + union shp_slot_cfg_l1_u *value) +{ + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + SHP_SLOT_CFG_L1_ADDRESS, + &value->val); +} + +sw_error_t +hppe_shp_slot_cfg_l1_set( + a_uint32_t dev_id, + union shp_slot_cfg_l1_u *value) +{ + return hppe_reg_set( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + SHP_SLOT_CFG_L1_ADDRESS, + value->val); +} + +sw_error_t +hppe_shp_slot_cfg_port_get( + a_uint32_t dev_id, + union shp_slot_cfg_port_u *value) +{ + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + SHP_SLOT_CFG_PORT_ADDRESS, + &value->val); +} + +sw_error_t +hppe_shp_slot_cfg_port_set( + a_uint32_t dev_id, + union shp_slot_cfg_port_u *value) +{ + return hppe_reg_set( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + SHP_SLOT_CFG_PORT_ADDRESS, + value->val); +} + +sw_error_t +hppe_l0_shp_credit_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_shp_credit_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L0_SHP_CREDIT_TBL_ADDRESS + \ + index * L0_SHP_CREDIT_TBL_INC, + value->val, + 2); +} + +sw_error_t +hppe_l0_shp_credit_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_shp_credit_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L0_SHP_CREDIT_TBL_ADDRESS + \ + index * L0_SHP_CREDIT_TBL_INC, + value->val, + 2); +} + +sw_error_t +hppe_l0_shp_cfg_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_shp_cfg_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L0_SHP_CFG_TBL_ADDRESS + \ + index * L0_SHP_CFG_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_l0_shp_cfg_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_shp_cfg_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L0_SHP_CFG_TBL_ADDRESS + \ + index * L0_SHP_CFG_TBL_INC, + value->val, + 3); +} + +#ifndef IN_SHAPER_MINI +sw_error_t +hppe_l0_comp_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_comp_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L0_COMP_TBL_ADDRESS + \ + index * L0_COMP_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_l0_comp_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_comp_tbl_u *value) +{ + return SW_NOT_SUPPORTED; +} +#endif + +sw_error_t +hppe_l0_comp_cfg_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l0_comp_cfg_tbl_u *value) +{ + if (index >= L0_COMP_CFG_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L0_COMP_CFG_TBL_ADDRESS + \ + index * L0_COMP_CFG_TBL_INC, + &value->val); +} + +sw_error_t +hppe_l0_comp_cfg_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l0_comp_cfg_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L0_COMP_CFG_TBL_ADDRESS + \ + index * L0_COMP_CFG_TBL_INC, + value->val); +} + + +sw_error_t +hppe_l1_shp_credit_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_shp_credit_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L1_SHP_CREDIT_TBL_ADDRESS + \ + index * L1_SHP_CREDIT_TBL_INC, + value->val, + 2); +} + +sw_error_t +hppe_l1_shp_credit_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_shp_credit_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L1_SHP_CREDIT_TBL_ADDRESS + \ + index * L1_SHP_CREDIT_TBL_INC, + value->val, + 2); +} + +#ifndef IN_SHAPER_MINI +sw_error_t +hppe_l1_shp_cfg_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_shp_cfg_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L1_SHP_CFG_TBL_ADDRESS + \ + index * L1_SHP_CFG_TBL_INC, + value->val, + 3); +} +#endif + +sw_error_t +hppe_l1_shp_cfg_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_shp_cfg_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L1_SHP_CFG_TBL_ADDRESS + \ + index * L1_SHP_CFG_TBL_INC, + value->val, + 3); +} + + +#ifndef IN_SHAPER_MINI +sw_error_t +hppe_l1_comp_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_comp_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L1_COMP_TBL_ADDRESS + \ + index * L1_COMP_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_l1_comp_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_comp_tbl_u *value) +{ + return SW_NOT_SUPPORTED; +} +#endif + +sw_error_t +hppe_l1_comp_cfg_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union l1_comp_cfg_tbl_u *value) +{ + if (index >= L1_COMP_CFG_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L1_COMP_CFG_TBL_ADDRESS + \ + index * L1_COMP_CFG_TBL_INC, + &value->val); +} + +sw_error_t +hppe_l1_comp_cfg_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union l1_comp_cfg_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + L1_COMP_CFG_TBL_ADDRESS + \ + index * L1_COMP_CFG_TBL_INC, + value->val); +} + +sw_error_t +hppe_psch_shp_sign_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union psch_shp_sign_tbl_u *value) +{ + if (index >= PSCH_SHP_SIGN_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + PSCH_SHP_SIGN_TBL_ADDRESS + \ + index * PSCH_SHP_SIGN_TBL_INC, + &value->val); +} + +sw_error_t +hppe_psch_shp_sign_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union psch_shp_sign_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + PSCH_SHP_SIGN_TBL_ADDRESS + \ + index * PSCH_SHP_SIGN_TBL_INC, + value->val); +} + +sw_error_t +hppe_psch_shp_credit_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union psch_shp_credit_tbl_u *value) +{ + if (index >= PSCH_SHP_CREDIT_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + PSCH_SHP_CREDIT_TBL_ADDRESS + \ + index * PSCH_SHP_CREDIT_TBL_INC, + &value->val); +} + +sw_error_t +hppe_psch_shp_credit_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union psch_shp_credit_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + PSCH_SHP_CREDIT_TBL_ADDRESS + \ + index * PSCH_SHP_CREDIT_TBL_INC, + value->val); +} + +sw_error_t +hppe_psch_shp_cfg_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union psch_shp_cfg_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + PSCH_SHP_CFG_TBL_ADDRESS + \ + index * PSCH_SHP_CFG_TBL_INC, + value->val, + 2); +} + +sw_error_t +hppe_psch_shp_cfg_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union psch_shp_cfg_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + PSCH_SHP_CFG_TBL_ADDRESS + \ + index * PSCH_SHP_CFG_TBL_INC, + value->val, + 2); +} + +#ifndef IN_SHAPER_MINI +sw_error_t +hppe_psch_comp_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union psch_comp_tbl_u *value) +{ + if (index >= PSCH_COMP_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + PSCH_COMP_TBL_ADDRESS + \ + index * PSCH_COMP_TBL_INC, + &value->val); +} + +sw_error_t +hppe_psch_comp_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union psch_comp_tbl_u *value) +{ + return SW_NOT_SUPPORTED; +} +#endif + +sw_error_t +hppe_psch_comp_cfg_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union psch_comp_cfg_tbl_u *value) +{ + if (index >= PSCH_COMP_CFG_TBL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + PSCH_COMP_CFG_TBL_ADDRESS + \ + index * PSCH_COMP_CFG_TBL_INC, + &value->val); +} + +sw_error_t +hppe_psch_comp_cfg_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union psch_comp_cfg_tbl_u *value) +{ + return hppe_reg_set( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + PSCH_COMP_CFG_TBL_ADDRESS + \ + index * PSCH_COMP_CFG_TBL_INC, + value->val); +} + +sw_error_t +hppe_ipg_pre_len_cfg_get( + a_uint32_t dev_id, + union ipg_pre_len_cfg_u *value) +{ + return hppe_reg_get( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + IPG_PRE_LEN_CFG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_ipg_pre_len_cfg_set( + a_uint32_t dev_id, + union ipg_pre_len_cfg_u *value) +{ + return hppe_reg_set( + dev_id, + TRAFFIC_MANAGER_BASE_ADDR + IPG_PRE_LEN_CFG_ADDRESS, + value->val); +} + +#ifndef IN_SHAPER_MINI +sw_error_t +hppe_ipg_pre_len_cfg_ipg_pre_len_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union ipg_pre_len_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipg_pre_len_cfg_get(dev_id, ®_val); + *value = reg_val.bf.ipg_pre_len; + return ret; +} + +sw_error_t +hppe_ipg_pre_len_cfg_ipg_pre_len_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union ipg_pre_len_cfg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ipg_pre_len_cfg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipg_pre_len = value; + ret = hppe_ipg_pre_len_cfg_set(dev_id, ®_val); + return ret; +} + + +sw_error_t +hppe_shp_slot_cfg_l0_l0_shp_slot_time_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union shp_slot_cfg_l0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_shp_slot_cfg_l0_get(dev_id, ®_val); + *value = reg_val.bf.l0_shp_slot_time; + return ret; +} + +sw_error_t +hppe_shp_slot_cfg_l0_l0_shp_slot_time_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union shp_slot_cfg_l0_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_shp_slot_cfg_l0_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l0_shp_slot_time = value; + ret = hppe_shp_slot_cfg_l0_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_shp_slot_cfg_l1_l1_shp_slot_time_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union shp_slot_cfg_l1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_shp_slot_cfg_l1_get(dev_id, ®_val); + *value = reg_val.bf.l1_shp_slot_time; + return ret; +} + +sw_error_t +hppe_shp_slot_cfg_l1_l1_shp_slot_time_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union shp_slot_cfg_l1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_shp_slot_cfg_l1_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l1_shp_slot_time = value; + ret = hppe_shp_slot_cfg_l1_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_shp_slot_cfg_port_port_shp_slot_time_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union shp_slot_cfg_port_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_shp_slot_cfg_port_get(dev_id, ®_val); + *value = reg_val.bf.port_shp_slot_time; + return ret; +} + +sw_error_t +hppe_shp_slot_cfg_port_port_shp_slot_time_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union shp_slot_cfg_port_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_shp_slot_cfg_port_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_shp_slot_time = value; + ret = hppe_shp_slot_cfg_port_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_l0_shp_credit_tbl_e_shaper_credit_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_shp_credit_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_shp_credit_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.e_shaper_credit_neg; + return ret; +} + +sw_error_t +hppe_l0_shp_credit_tbl_e_shaper_credit_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l0_shp_credit_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_shp_credit_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.e_shaper_credit_neg = value; + ret = hppe_l0_shp_credit_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l0_shp_credit_tbl_e_shaper_credit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_shp_credit_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_shp_credit_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.e_shaper_credit_1 << 1 | \ + reg_val.bf.e_shaper_credit_0; + return ret; +} + +sw_error_t +hppe_l0_shp_credit_tbl_e_shaper_credit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l0_shp_credit_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_shp_credit_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.e_shaper_credit_1 = value >> 1; + reg_val.bf.e_shaper_credit_0 = value & (((a_uint64_t)1<<1)-1); + ret = hppe_l0_shp_credit_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l0_shp_credit_tbl_c_shaper_credit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_shp_credit_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_shp_credit_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.c_shaper_credit; + return ret; +} + +sw_error_t +hppe_l0_shp_credit_tbl_c_shaper_credit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l0_shp_credit_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_shp_credit_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.c_shaper_credit = value; + ret = hppe_l0_shp_credit_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l0_shp_credit_tbl_c_shaper_credit_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_shp_credit_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_shp_credit_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.c_shaper_credit_neg; + return ret; +} + +sw_error_t +hppe_l0_shp_credit_tbl_c_shaper_credit_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l0_shp_credit_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_shp_credit_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.c_shaper_credit_neg = value; + ret = hppe_l0_shp_credit_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l0_shp_cfg_tbl_cir_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_shp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.cir; + return ret; +} + +sw_error_t +hppe_l0_shp_cfg_tbl_cir_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l0_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_shp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cir = value; + ret = hppe_l0_shp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l0_shp_cfg_tbl_cf_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_shp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.cf; + return ret; +} + +sw_error_t +hppe_l0_shp_cfg_tbl_cf_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l0_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_shp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cf = value; + ret = hppe_l0_shp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l0_shp_cfg_tbl_meter_unit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_shp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.meter_unit; + return ret; +} + +sw_error_t +hppe_l0_shp_cfg_tbl_meter_unit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l0_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_shp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.meter_unit = value; + ret = hppe_l0_shp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l0_shp_cfg_tbl_e_shaper_enable_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_shp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.e_shaper_enable; + return ret; +} + +sw_error_t +hppe_l0_shp_cfg_tbl_e_shaper_enable_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l0_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_shp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.e_shaper_enable = value; + ret = hppe_l0_shp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l0_shp_cfg_tbl_c_shaper_enable_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_shp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.c_shaper_enable; + return ret; +} + +sw_error_t +hppe_l0_shp_cfg_tbl_c_shaper_enable_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l0_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_shp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.c_shaper_enable = value; + ret = hppe_l0_shp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l0_shp_cfg_tbl_eir_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_shp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.eir; + return ret; +} + +sw_error_t +hppe_l0_shp_cfg_tbl_eir_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l0_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_shp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.eir = value; + ret = hppe_l0_shp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l0_shp_cfg_tbl_token_unit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_shp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.token_unit; + return ret; +} + +sw_error_t +hppe_l0_shp_cfg_tbl_token_unit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l0_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_shp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.token_unit = value; + ret = hppe_l0_shp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l0_shp_cfg_tbl_cbs_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_shp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.cbs; + return ret; +} + +sw_error_t +hppe_l0_shp_cfg_tbl_cbs_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l0_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_shp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cbs = value; + ret = hppe_l0_shp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l0_shp_cfg_tbl_ebs_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_shp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ebs; + return ret; +} + +sw_error_t +hppe_l0_shp_cfg_tbl_ebs_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l0_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_shp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ebs = value; + ret = hppe_l0_shp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l0_comp_tbl_c_drr_compensate_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_comp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_comp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.c_drr_compensate_byte_cnt_1 << 9 | \ + reg_val.bf.c_drr_compensate_byte_cnt_0; + return ret; +} + +sw_error_t +hppe_l0_comp_tbl_c_drr_compensate_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_comp_tbl_e_drr_compensate_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_comp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_comp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.e_drr_compensate_byte_cnt; + return ret; +} + +sw_error_t +hppe_l0_comp_tbl_e_drr_compensate_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_comp_tbl_c_shaper_compensate_byte_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_comp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_comp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.c_shaper_compensate_byte_neg; + return ret; +} + +sw_error_t +hppe_l0_comp_tbl_c_shaper_compensate_byte_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_comp_tbl_c_shaper_compensate_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_comp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_comp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.c_shaper_compensate_pkt_cnt; + return ret; +} + +sw_error_t +hppe_l0_comp_tbl_c_shaper_compensate_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_comp_tbl_c_shaper_compensate_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_comp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_comp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.c_shaper_compensate_byte_cnt; + return ret; +} + +sw_error_t +hppe_l0_comp_tbl_c_shaper_compensate_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_comp_tbl_e_shaper_compensate_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_comp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_comp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.e_shaper_compensate_pkt_cnt; + return ret; +} + +sw_error_t +hppe_l0_comp_tbl_e_shaper_compensate_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_comp_tbl_e_drr_compensate_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_comp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_comp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.e_drr_compensate_pkt_cnt; + return ret; +} + +sw_error_t +hppe_l0_comp_tbl_e_drr_compensate_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_comp_tbl_e_drr_compensate_byte_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_comp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_comp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.e_drr_compensate_byte_neg; + return ret; +} + +sw_error_t +hppe_l0_comp_tbl_e_drr_compensate_byte_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_comp_tbl_c_drr_compensate_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_comp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_comp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.c_drr_compensate_pkt_cnt; + return ret; +} + +sw_error_t +hppe_l0_comp_tbl_c_drr_compensate_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_comp_tbl_c_drr_compensate_byte_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_comp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_comp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.c_drr_compensate_byte_neg; + return ret; +} + +sw_error_t +hppe_l0_comp_tbl_c_drr_compensate_byte_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_comp_tbl_e_shaper_compensate_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_comp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_comp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.e_shaper_compensate_byte_cnt; + return ret; +} + +sw_error_t +hppe_l0_comp_tbl_e_shaper_compensate_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_comp_tbl_e_shaper_compensate_byte_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_comp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_comp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.e_shaper_compensate_byte_neg; + return ret; +} + +sw_error_t +hppe_l0_comp_tbl_e_shaper_compensate_byte_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l0_comp_cfg_tbl_drr_meter_len_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_comp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_comp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.drr_meter_len; + return ret; +} + +sw_error_t +hppe_l0_comp_cfg_tbl_drr_meter_len_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l0_comp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_comp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.drr_meter_len = value; + ret = hppe_l0_comp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l0_comp_cfg_tbl_shaper_meter_len_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l0_comp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_comp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.shaper_meter_len; + return ret; +} + +sw_error_t +hppe_l0_comp_cfg_tbl_shaper_meter_len_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l0_comp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l0_comp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.shaper_meter_len = value; + ret = hppe_l0_comp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l1_shp_credit_tbl_e_shaper_credit_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_shp_credit_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_shp_credit_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.e_shaper_credit_neg; + return ret; +} + +sw_error_t +hppe_l1_shp_credit_tbl_e_shaper_credit_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l1_shp_credit_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_shp_credit_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.e_shaper_credit_neg = value; + ret = hppe_l1_shp_credit_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l1_shp_credit_tbl_e_shaper_credit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_shp_credit_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_shp_credit_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.e_shaper_credit_1 << 1 | \ + reg_val.bf.e_shaper_credit_0; + return ret; +} + +sw_error_t +hppe_l1_shp_credit_tbl_e_shaper_credit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l1_shp_credit_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_shp_credit_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.e_shaper_credit_1 = value >> 1; + reg_val.bf.e_shaper_credit_0 = value & (((a_uint64_t)1<<1)-1); + ret = hppe_l1_shp_credit_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l1_shp_credit_tbl_c_shaper_credit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_shp_credit_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_shp_credit_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.c_shaper_credit; + return ret; +} + +sw_error_t +hppe_l1_shp_credit_tbl_c_shaper_credit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l1_shp_credit_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_shp_credit_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.c_shaper_credit = value; + ret = hppe_l1_shp_credit_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l1_shp_credit_tbl_c_shaper_credit_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_shp_credit_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_shp_credit_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.c_shaper_credit_neg; + return ret; +} + +sw_error_t +hppe_l1_shp_credit_tbl_c_shaper_credit_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l1_shp_credit_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_shp_credit_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.c_shaper_credit_neg = value; + ret = hppe_l1_shp_credit_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l1_shp_cfg_tbl_cir_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_shp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.cir; + return ret; +} + +sw_error_t +hppe_l1_shp_cfg_tbl_cir_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l1_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_shp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cir = value; + ret = hppe_l1_shp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l1_shp_cfg_tbl_cf_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_shp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.cf; + return ret; +} + +sw_error_t +hppe_l1_shp_cfg_tbl_cf_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l1_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_shp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cf = value; + ret = hppe_l1_shp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l1_shp_cfg_tbl_meter_unit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_shp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.meter_unit; + return ret; +} + +sw_error_t +hppe_l1_shp_cfg_tbl_meter_unit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l1_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_shp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.meter_unit = value; + ret = hppe_l1_shp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l1_shp_cfg_tbl_e_shaper_enable_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_shp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.e_shaper_enable; + return ret; +} + +sw_error_t +hppe_l1_shp_cfg_tbl_e_shaper_enable_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l1_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_shp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.e_shaper_enable = value; + ret = hppe_l1_shp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l1_shp_cfg_tbl_c_shaper_enable_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_shp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.c_shaper_enable; + return ret; +} + +sw_error_t +hppe_l1_shp_cfg_tbl_c_shaper_enable_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l1_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_shp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.c_shaper_enable = value; + ret = hppe_l1_shp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l1_shp_cfg_tbl_eir_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_shp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.eir; + return ret; +} + +sw_error_t +hppe_l1_shp_cfg_tbl_eir_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l1_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_shp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.eir = value; + ret = hppe_l1_shp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l1_shp_cfg_tbl_token_unit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_shp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.token_unit; + return ret; +} + +sw_error_t +hppe_l1_shp_cfg_tbl_token_unit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l1_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_shp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.token_unit = value; + ret = hppe_l1_shp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l1_shp_cfg_tbl_cbs_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_shp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.cbs; + return ret; +} + +sw_error_t +hppe_l1_shp_cfg_tbl_cbs_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l1_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_shp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cbs = value; + ret = hppe_l1_shp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l1_shp_cfg_tbl_ebs_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_shp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.ebs; + return ret; +} + +sw_error_t +hppe_l1_shp_cfg_tbl_ebs_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l1_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_shp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ebs = value; + ret = hppe_l1_shp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l1_comp_tbl_c_drr_compensate_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_comp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_comp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.c_drr_compensate_byte_cnt_1 << 9 | \ + reg_val.bf.c_drr_compensate_byte_cnt_0; + return ret; +} + +sw_error_t +hppe_l1_comp_tbl_c_drr_compensate_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_comp_tbl_e_drr_compensate_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_comp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_comp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.e_drr_compensate_byte_cnt; + return ret; +} + +sw_error_t +hppe_l1_comp_tbl_e_drr_compensate_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_comp_tbl_c_shaper_compensate_byte_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_comp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_comp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.c_shaper_compensate_byte_neg; + return ret; +} + +sw_error_t +hppe_l1_comp_tbl_c_shaper_compensate_byte_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_comp_tbl_c_shaper_compensate_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_comp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_comp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.c_shaper_compensate_pkt_cnt; + return ret; +} + +sw_error_t +hppe_l1_comp_tbl_c_shaper_compensate_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_comp_tbl_c_shaper_compensate_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_comp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_comp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.c_shaper_compensate_byte_cnt; + return ret; +} + +sw_error_t +hppe_l1_comp_tbl_c_shaper_compensate_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_comp_tbl_e_shaper_compensate_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_comp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_comp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.e_shaper_compensate_pkt_cnt; + return ret; +} + +sw_error_t +hppe_l1_comp_tbl_e_shaper_compensate_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_comp_tbl_e_drr_compensate_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_comp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_comp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.e_drr_compensate_pkt_cnt; + return ret; +} + +sw_error_t +hppe_l1_comp_tbl_e_drr_compensate_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_comp_tbl_e_drr_compensate_byte_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_comp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_comp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.e_drr_compensate_byte_neg; + return ret; +} + +sw_error_t +hppe_l1_comp_tbl_e_drr_compensate_byte_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_comp_tbl_c_drr_compensate_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_comp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_comp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.c_drr_compensate_pkt_cnt; + return ret; +} + +sw_error_t +hppe_l1_comp_tbl_c_drr_compensate_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_comp_tbl_c_drr_compensate_byte_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_comp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_comp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.c_drr_compensate_byte_neg; + return ret; +} + +sw_error_t +hppe_l1_comp_tbl_c_drr_compensate_byte_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_comp_tbl_e_shaper_compensate_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_comp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_comp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.e_shaper_compensate_byte_cnt; + return ret; +} + +sw_error_t +hppe_l1_comp_tbl_e_shaper_compensate_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_comp_tbl_e_shaper_compensate_byte_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_comp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_comp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.e_shaper_compensate_byte_neg; + return ret; +} + +sw_error_t +hppe_l1_comp_tbl_e_shaper_compensate_byte_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_l1_comp_cfg_tbl_drr_meter_len_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_comp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_comp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.drr_meter_len; + return ret; +} + +sw_error_t +hppe_l1_comp_cfg_tbl_drr_meter_len_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l1_comp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_comp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.drr_meter_len = value; + ret = hppe_l1_comp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_l1_comp_cfg_tbl_shaper_meter_len_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union l1_comp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_comp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.shaper_meter_len; + return ret; +} + +sw_error_t +hppe_l1_comp_cfg_tbl_shaper_meter_len_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union l1_comp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_l1_comp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.shaper_meter_len = value; + ret = hppe_l1_comp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_psch_shp_sign_tbl_shaper_credit_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union psch_shp_sign_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_psch_shp_sign_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.shaper_credit_neg; + return ret; +} + +sw_error_t +hppe_psch_shp_sign_tbl_shaper_credit_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union psch_shp_sign_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_psch_shp_sign_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.shaper_credit_neg = value; + ret = hppe_psch_shp_sign_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_psch_shp_credit_tbl_shaper_credit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union psch_shp_credit_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_psch_shp_credit_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.shaper_credit; + return ret; +} + +sw_error_t +hppe_psch_shp_credit_tbl_shaper_credit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union psch_shp_credit_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_psch_shp_credit_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.shaper_credit = value; + ret = hppe_psch_shp_credit_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_psch_shp_cfg_tbl_cir_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union psch_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_psch_shp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.cir; + return ret; +} + +sw_error_t +hppe_psch_shp_cfg_tbl_cir_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union psch_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_psch_shp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cir = value; + ret = hppe_psch_shp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_psch_shp_cfg_tbl_meter_unit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union psch_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_psch_shp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.meter_unit; + return ret; +} + +sw_error_t +hppe_psch_shp_cfg_tbl_meter_unit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union psch_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_psch_shp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.meter_unit = value; + ret = hppe_psch_shp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_psch_shp_cfg_tbl_token_unit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union psch_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_psch_shp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.token_unit; + return ret; +} + +sw_error_t +hppe_psch_shp_cfg_tbl_token_unit_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union psch_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_psch_shp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.token_unit = value; + ret = hppe_psch_shp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_psch_shp_cfg_tbl_cbs_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union psch_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_psch_shp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.cbs; + return ret; +} + +sw_error_t +hppe_psch_shp_cfg_tbl_cbs_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union psch_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_psch_shp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cbs = value; + ret = hppe_psch_shp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_psch_shp_cfg_tbl_shaper_enable_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union psch_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_psch_shp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.shaper_enable; + return ret; +} + +sw_error_t +hppe_psch_shp_cfg_tbl_shaper_enable_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union psch_shp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_psch_shp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.shaper_enable = value; + ret = hppe_psch_shp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_psch_comp_tbl_shaper_compensate_byte_neg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union psch_comp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_psch_comp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.shaper_compensate_byte_neg; + return ret; +} + +sw_error_t +hppe_psch_comp_tbl_shaper_compensate_byte_neg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_psch_comp_tbl_shaper_compensate_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union psch_comp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_psch_comp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.shaper_compensate_pkt_cnt; + return ret; +} + +sw_error_t +hppe_psch_comp_tbl_shaper_compensate_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_psch_comp_tbl_shaper_compensate_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union psch_comp_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_psch_comp_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.shaper_compensate_byte_cnt; + return ret; +} + +sw_error_t +hppe_psch_comp_tbl_shaper_compensate_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_psch_comp_cfg_tbl_shaper_meter_len_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union psch_comp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_psch_comp_cfg_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.shaper_meter_len; + return ret; +} + +sw_error_t +hppe_psch_comp_cfg_tbl_shaper_meter_len_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union psch_comp_cfg_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_psch_comp_cfg_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.shaper_meter_len = value; + ret = hppe_psch_comp_cfg_tbl_set(dev_id, index, ®_val); + return ret; +} +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_stp.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_stp.c new file mode 100755 index 000000000..a6b4b82fb --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_stp.c @@ -0,0 +1,85 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hppe_reg_access.h" +#include "hppe_stp_reg.h" +#include "hppe_stp.h" + +sw_error_t +hppe_cst_state_get( + a_uint32_t dev_id, + a_uint32_t index, + union cst_state_u *value) +{ + if (index >= CST_STATE_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + CST_STATE_ADDRESS + \ + index * CST_STATE_INC, + &value->val); +} + +sw_error_t +hppe_cst_state_set( + a_uint32_t dev_id, + a_uint32_t index, + union cst_state_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L2_BASE_ADDR + CST_STATE_ADDRESS + \ + index * CST_STATE_INC, + value->val); +} + +sw_error_t +hppe_cst_state_port_state_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union cst_state_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_cst_state_get(dev_id, index, ®_val); + *value = reg_val.bf.port_state; + return ret; +} + +sw_error_t +hppe_cst_state_port_state_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union cst_state_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_cst_state_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.port_state = value; + ret = hppe_cst_state_set(dev_id, index, ®_val); + return ret; +} + + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_trunk.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_trunk.c new file mode 100755 index 000000000..d9db536b8 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_trunk.c @@ -0,0 +1,790 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hppe_reg_access.h" +#include "hppe_trunk_reg.h" +#include "hppe_trunk.h" + +sw_error_t +hppe_trunk_hash_field_reg_get( + a_uint32_t dev_id, + union trunk_hash_field_reg_u *value) +{ + return hppe_reg_get( + dev_id, + IPR_CSR_BASE_ADDR + TRUNK_HASH_FIELD_REG_ADDRESS, + &value->val); +} + +sw_error_t +hppe_trunk_hash_field_reg_set( + a_uint32_t dev_id, + union trunk_hash_field_reg_u *value) +{ + return hppe_reg_set( + dev_id, + IPR_CSR_BASE_ADDR + TRUNK_HASH_FIELD_REG_ADDRESS, + value->val); +} + +sw_error_t +hppe_trunk_filter_get( + a_uint32_t dev_id, + a_uint32_t index, + union trunk_filter_u *value) +{ + if (index >= TRUNK_FILTER_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + TRUNK_FILTER_ADDRESS + \ + index * TRUNK_FILTER_INC, + &value->val); +} + +sw_error_t +hppe_trunk_filter_set( + a_uint32_t dev_id, + a_uint32_t index, + union trunk_filter_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L2_BASE_ADDR + TRUNK_FILTER_ADDRESS + \ + index * TRUNK_FILTER_INC, + value->val); +} + +sw_error_t +hppe_trunk_member_get( + a_uint32_t dev_id, + a_uint32_t index, + union trunk_member_u *value) +{ + if (index >= TRUNK_MEMBER_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + TRUNK_MEMBER_ADDRESS + \ + index * TRUNK_MEMBER_INC, + &value->val); +} + +sw_error_t +hppe_trunk_member_set( + a_uint32_t dev_id, + a_uint32_t index, + union trunk_member_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L2_BASE_ADDR + TRUNK_MEMBER_ADDRESS + \ + index * TRUNK_MEMBER_INC, + value->val); +} +sw_error_t +hppe_port_trunk_id_get( + a_uint32_t dev_id, + a_uint32_t index, + union port_trunk_id_u *value) +{ + if (index >= PORT_TRUNK_ID_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + IPE_L2_BASE_ADDR + PORT_TRUNK_ID_ADDRESS + \ + index * PORT_TRUNK_ID_INC, + &value->val); +} + +sw_error_t +hppe_port_trunk_id_set( + a_uint32_t dev_id, + a_uint32_t index, + union port_trunk_id_u *value) +{ + return hppe_reg_set( + dev_id, + IPE_L2_BASE_ADDR + PORT_TRUNK_ID_ADDRESS + \ + index * PORT_TRUNK_ID_INC, + value->val); +} + +sw_error_t +hppe_trunk_hash_field_reg_udf2_incl_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union trunk_hash_field_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_hash_field_reg_get(dev_id, ®_val); + *value = reg_val.bf.udf2_incl; + return ret; +} + +sw_error_t +hppe_trunk_hash_field_reg_udf2_incl_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union trunk_hash_field_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_hash_field_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udf2_incl = value; + ret = hppe_trunk_hash_field_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_trunk_hash_field_reg_mac_da_incl_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union trunk_hash_field_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_hash_field_reg_get(dev_id, ®_val); + *value = reg_val.bf.mac_da_incl; + return ret; +} + +sw_error_t +hppe_trunk_hash_field_reg_mac_da_incl_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union trunk_hash_field_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_hash_field_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_da_incl = value; + ret = hppe_trunk_hash_field_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_trunk_hash_field_reg_src_port_incl_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union trunk_hash_field_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_hash_field_reg_get(dev_id, ®_val); + *value = reg_val.bf.src_port_incl; + return ret; +} + +sw_error_t +hppe_trunk_hash_field_reg_src_port_incl_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union trunk_hash_field_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_hash_field_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.src_port_incl = value; + ret = hppe_trunk_hash_field_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_trunk_hash_field_reg_udf3_incl_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union trunk_hash_field_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_hash_field_reg_get(dev_id, ®_val); + *value = reg_val.bf.udf3_incl; + return ret; +} + +sw_error_t +hppe_trunk_hash_field_reg_udf3_incl_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union trunk_hash_field_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_hash_field_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udf3_incl = value; + ret = hppe_trunk_hash_field_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_trunk_hash_field_reg_l4_dst_port_incl_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union trunk_hash_field_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_hash_field_reg_get(dev_id, ®_val); + *value = reg_val.bf.l4_dst_port_incl; + return ret; +} + +sw_error_t +hppe_trunk_hash_field_reg_l4_dst_port_incl_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union trunk_hash_field_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_hash_field_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l4_dst_port_incl = value; + ret = hppe_trunk_hash_field_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_trunk_hash_field_reg_udf0_incl_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union trunk_hash_field_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_hash_field_reg_get(dev_id, ®_val); + *value = reg_val.bf.udf0_incl; + return ret; +} + +sw_error_t +hppe_trunk_hash_field_reg_udf0_incl_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union trunk_hash_field_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_hash_field_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udf0_incl = value; + ret = hppe_trunk_hash_field_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_trunk_hash_field_reg_dst_ip_incl_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union trunk_hash_field_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_hash_field_reg_get(dev_id, ®_val); + *value = reg_val.bf.dst_ip_incl; + return ret; +} + +sw_error_t +hppe_trunk_hash_field_reg_dst_ip_incl_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union trunk_hash_field_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_hash_field_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.dst_ip_incl = value; + ret = hppe_trunk_hash_field_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_trunk_hash_field_reg_l4_src_port_incl_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union trunk_hash_field_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_hash_field_reg_get(dev_id, ®_val); + *value = reg_val.bf.l4_src_port_incl; + return ret; +} + +sw_error_t +hppe_trunk_hash_field_reg_l4_src_port_incl_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union trunk_hash_field_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_hash_field_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l4_src_port_incl = value; + ret = hppe_trunk_hash_field_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_trunk_hash_field_reg_src_ip_incl_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union trunk_hash_field_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_hash_field_reg_get(dev_id, ®_val); + *value = reg_val.bf.src_ip_incl; + return ret; +} + +sw_error_t +hppe_trunk_hash_field_reg_src_ip_incl_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union trunk_hash_field_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_hash_field_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.src_ip_incl = value; + ret = hppe_trunk_hash_field_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_trunk_hash_field_reg_udf1_incl_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union trunk_hash_field_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_hash_field_reg_get(dev_id, ®_val); + *value = reg_val.bf.udf1_incl; + return ret; +} + +sw_error_t +hppe_trunk_hash_field_reg_udf1_incl_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union trunk_hash_field_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_hash_field_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udf1_incl = value; + ret = hppe_trunk_hash_field_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_trunk_hash_field_reg_mac_sa_incl_get( + a_uint32_t dev_id, + a_uint32_t *value) +{ + union trunk_hash_field_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_hash_field_reg_get(dev_id, ®_val); + *value = reg_val.bf.mac_sa_incl; + return ret; +} + +sw_error_t +hppe_trunk_hash_field_reg_mac_sa_incl_set( + a_uint32_t dev_id, + a_uint32_t value) +{ + union trunk_hash_field_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_hash_field_reg_get(dev_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_sa_incl = value; + ret = hppe_trunk_hash_field_reg_set(dev_id, ®_val); + return ret; +} + +sw_error_t +hppe_trunk_filter_mem_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union trunk_filter_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_filter_get(dev_id, index, ®_val); + *value = reg_val.bf.mem_bitmap; + return ret; +} + +sw_error_t +hppe_trunk_filter_mem_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union trunk_filter_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_filter_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mem_bitmap = value; + ret = hppe_trunk_filter_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_trunk_member_member_2_port_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union trunk_member_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_member_get(dev_id, index, ®_val); + *value = reg_val.bf.member_2_port_id; + return ret; +} + +sw_error_t +hppe_trunk_member_member_2_port_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union trunk_member_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_member_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.member_2_port_id = value; + ret = hppe_trunk_member_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_trunk_member_member_0_port_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union trunk_member_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_member_get(dev_id, index, ®_val); + *value = reg_val.bf.member_0_port_id; + return ret; +} + +sw_error_t +hppe_trunk_member_member_0_port_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union trunk_member_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_member_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.member_0_port_id = value; + ret = hppe_trunk_member_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_trunk_member_member_1_port_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union trunk_member_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_member_get(dev_id, index, ®_val); + *value = reg_val.bf.member_1_port_id; + return ret; +} + +sw_error_t +hppe_trunk_member_member_1_port_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union trunk_member_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_member_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.member_1_port_id = value; + ret = hppe_trunk_member_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_trunk_member_member_6_port_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union trunk_member_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_member_get(dev_id, index, ®_val); + *value = reg_val.bf.member_6_port_id; + return ret; +} + +sw_error_t +hppe_trunk_member_member_6_port_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union trunk_member_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_member_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.member_6_port_id = value; + ret = hppe_trunk_member_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_trunk_member_member_4_port_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union trunk_member_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_member_get(dev_id, index, ®_val); + *value = reg_val.bf.member_4_port_id; + return ret; +} + +sw_error_t +hppe_trunk_member_member_4_port_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union trunk_member_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_member_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.member_4_port_id = value; + ret = hppe_trunk_member_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_trunk_member_member_3_port_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union trunk_member_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_member_get(dev_id, index, ®_val); + *value = reg_val.bf.member_3_port_id; + return ret; +} + +sw_error_t +hppe_trunk_member_member_3_port_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union trunk_member_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_member_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.member_3_port_id = value; + ret = hppe_trunk_member_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_trunk_member_member_5_port_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union trunk_member_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_member_get(dev_id, index, ®_val); + *value = reg_val.bf.member_5_port_id; + return ret; +} + +sw_error_t +hppe_trunk_member_member_5_port_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union trunk_member_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_member_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.member_5_port_id = value; + ret = hppe_trunk_member_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_trunk_member_member_7_port_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union trunk_member_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_member_get(dev_id, index, ®_val); + *value = reg_val.bf.member_7_port_id; + return ret; +} + +sw_error_t +hppe_trunk_member_member_7_port_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union trunk_member_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_trunk_member_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.member_7_port_id = value; + ret = hppe_trunk_member_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_trunk_id_trunk_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_trunk_id_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_trunk_id_get(dev_id, index, ®_val); + *value = reg_val.bf.trunk_id; + return ret; +} + +sw_error_t +hppe_port_trunk_id_trunk_id_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_trunk_id_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_trunk_id_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.trunk_id = value; + ret = hppe_port_trunk_id_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_port_trunk_id_trunk_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union port_trunk_id_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_trunk_id_get(dev_id, index, ®_val); + *value = reg_val.bf.trunk_en; + return ret; +} + +sw_error_t +hppe_port_trunk_id_trunk_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union port_trunk_id_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_port_trunk_id_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.trunk_en = value; + ret = hppe_port_trunk_id_set(dev_id, index, ®_val); + return ret; +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_uniphy.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_uniphy.c new file mode 100755 index 000000000..9588e67dc --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_uniphy.c @@ -0,0 +1,6120 @@ +/* + * 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. + */ + + +/** + * @defgroup + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hppe_reg_access.h" +#include "hppe_uniphy_reg.h" +#include "hppe_uniphy.h" + +sw_error_t +hppe_uniphy_offset_calib_4_get( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_offset_calib_4_u *value) +{ + if (index >= UNIPHY_OFFSET_CALIB_4_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_uniphy_reg_get( + dev_id, + NSS_UNIPHY_BASE_ADDR + UNIPHY_OFFSET_CALIB_4_ADDRESS, + index * UNIPHY_OFFSET_CALIB_4_INC, + &value->val); +} +#ifndef IN_UNIPHY_MINI +sw_error_t +hppe_uniphy_offset_calib_4_set( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_offset_calib_4_u *value) +{ + return hppe_uniphy_reg_set( + dev_id, + NSS_UNIPHY_BASE_ADDR + UNIPHY_OFFSET_CALIB_4_ADDRESS, + index * UNIPHY_OFFSET_CALIB_4_INC, + value->val); +} +#endif +sw_error_t +hppe_uniphy_mode_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_mode_ctrl_u *value) +{ + if (index >= UNIPHY_MODE_CTRL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_uniphy_reg_get( + dev_id, + NSS_UNIPHY_BASE_ADDR + UNIPHY_MODE_CTRL_ADDRESS, + index * UNIPHY_MODE_CTRL_INC, + &value->val); +} + +sw_error_t +hppe_uniphy_mode_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_mode_ctrl_u *value) +{ + return hppe_uniphy_reg_set( + dev_id, + NSS_UNIPHY_BASE_ADDR + UNIPHY_MODE_CTRL_ADDRESS, + index * UNIPHY_MODE_CTRL_INC, + value->val); +} + +sw_error_t +hppe_uniphy_channel0_input_output_4_get( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_channel0_input_output_4_u *value) +{ + if (index >= UNIPHY_CHANNEL0_INPUT_OUTPUT_4_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_uniphy_reg_get( + dev_id, + NSS_UNIPHY_BASE_ADDR + UNIPHY_CHANNEL0_INPUT_OUTPUT_4_ADDRESS, + index * UNIPHY_CHANNEL0_INPUT_OUTPUT_4_INC, + &value->val); +} + +sw_error_t +hppe_uniphy_channel0_input_output_4_set( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_channel0_input_output_4_u *value) +{ + return hppe_uniphy_reg_set( + dev_id, + NSS_UNIPHY_BASE_ADDR + UNIPHY_CHANNEL0_INPUT_OUTPUT_4_ADDRESS, + index * UNIPHY_CHANNEL0_INPUT_OUTPUT_4_INC, + value->val); +} + +sw_error_t +hppe_uniphy_channel1_input_output_4_get( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_channel1_input_output_4_u *value) +{ + if (index >= UNIPHY_CHANNEL1_INPUT_OUTPUT_4_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_uniphy_reg_get( + dev_id, + NSS_UNIPHY_BASE_ADDR + UNIPHY_CHANNEL1_INPUT_OUTPUT_4_ADDRESS, + index * UNIPHY_CHANNEL1_INPUT_OUTPUT_4_INC, + &value->val); +} + +sw_error_t +hppe_uniphy_channel1_input_output_4_set( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_channel1_input_output_4_u *value) +{ + return hppe_uniphy_reg_set( + dev_id, + NSS_UNIPHY_BASE_ADDR + UNIPHY_CHANNEL1_INPUT_OUTPUT_4_ADDRESS, + index * UNIPHY_CHANNEL1_INPUT_OUTPUT_4_INC, + value->val); +} + +sw_error_t +hppe_uniphy_channel2_input_output_4_get( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_channel2_input_output_4_u *value) +{ + if (index >= UNIPHY_CHANNEL2_INPUT_OUTPUT_4_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_uniphy_reg_get( + dev_id, + NSS_UNIPHY_BASE_ADDR + UNIPHY_CHANNEL2_INPUT_OUTPUT_4_ADDRESS, + index * UNIPHY_CHANNEL2_INPUT_OUTPUT_4_INC, + &value->val); +} + +sw_error_t +hppe_uniphy_channel2_input_output_4_set( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_channel2_input_output_4_u *value) +{ + return hppe_uniphy_reg_set( + dev_id, + NSS_UNIPHY_BASE_ADDR + UNIPHY_CHANNEL2_INPUT_OUTPUT_4_ADDRESS, + index * UNIPHY_CHANNEL2_INPUT_OUTPUT_4_INC, + value->val); +} + +sw_error_t +hppe_uniphy_channel3_input_output_4_get( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_channel3_input_output_4_u *value) +{ + if (index >= UNIPHY_CHANNEL3_INPUT_OUTPUT_4_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_uniphy_reg_get( + dev_id, + NSS_UNIPHY_BASE_ADDR + UNIPHY_CHANNEL3_INPUT_OUTPUT_4_ADDRESS, + index * UNIPHY_CHANNEL3_INPUT_OUTPUT_4_INC, + &value->val); +} + +sw_error_t +hppe_uniphy_channel3_input_output_4_set( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_channel3_input_output_4_u *value) +{ + return hppe_uniphy_reg_set( + dev_id, + NSS_UNIPHY_BASE_ADDR + UNIPHY_CHANNEL3_INPUT_OUTPUT_4_ADDRESS, + index * UNIPHY_CHANNEL3_INPUT_OUTPUT_4_INC, + value->val); +} + +sw_error_t +hppe_uniphy_channel4_input_output_4_get( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_channel4_input_output_4_u *value) +{ + if (index >= UNIPHY_CHANNEL4_INPUT_OUTPUT_4_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_uniphy_reg_get( + dev_id, + NSS_UNIPHY_BASE_ADDR + UNIPHY_CHANNEL4_INPUT_OUTPUT_4_ADDRESS, + index * UNIPHY_CHANNEL4_INPUT_OUTPUT_4_INC, + &value->val); +} + +sw_error_t +hppe_uniphy_channel4_input_output_4_set( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_channel4_input_output_4_u *value) +{ + return hppe_uniphy_reg_set( + dev_id, + NSS_UNIPHY_BASE_ADDR + UNIPHY_CHANNEL4_INPUT_OUTPUT_4_ADDRESS, + index * UNIPHY_CHANNEL4_INPUT_OUTPUT_4_INC, + value->val); +} + +sw_error_t +hppe_uniphy_instance_link_detect_get( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_instance_link_detect_u *value) +{ + return hppe_uniphy_reg_get( + dev_id, + NSS_UNIPHY_BASE_ADDR + UNIPHY_INSTANCE_LINK_DETECT_ADDRESS, + index * UNIPHY_INSTANCE_LINK_DETECT_INC, + &value->val); +} + + +sw_error_t +hppe_uniphy_instance_link_detect_set( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_instance_link_detect_u *value) +{ + return hppe_uniphy_reg_set( + dev_id, + NSS_UNIPHY_BASE_ADDR + UNIPHY_INSTANCE_LINK_DETECT_ADDRESS, + index * UNIPHY_INSTANCE_LINK_DETECT_INC, + value->val); +} + +sw_error_t +hppe_sr_xs_pcs_kr_sts1_get( + a_uint32_t dev_id, + a_uint32_t index, + union sr_xs_pcs_kr_sts1_u *value) +{ + if (index >= SR_XS_PCS_KR_STS1_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_uniphy_reg_get( + dev_id, + NSS_UNIPHY_BASE_ADDR + SR_XS_PCS_KR_STS1_ADDRESS, + index * SR_XS_PCS_KR_STS1_INC, + &value->val); +} +#ifndef IN_UNIPHY_MINI +sw_error_t +hppe_sr_xs_pcs_kr_sts1_set( + a_uint32_t dev_id, + a_uint32_t index, + union sr_xs_pcs_kr_sts1_u *value) +{ + return hppe_uniphy_reg_set( + dev_id, + NSS_UNIPHY_BASE_ADDR + SR_XS_PCS_KR_STS1_ADDRESS, + index * SR_XS_PCS_KR_STS1_INC, + value->val); +} +#endif +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_get( + a_uint32_t dev_id, + a_uint32_t index, + union vr_xs_pcs_dig_ctrl1_u *value) +{ + if (index >= VR_XS_PCS_DIG_CTRL1_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_uniphy_reg_get( + dev_id, + NSS_UNIPHY_BASE_ADDR + VR_XS_PCS_DIG_CTRL1_ADDRESS, + index * VR_XS_PCS_DIG_CTRL1_INC, + &value->val); +} + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_set( + a_uint32_t dev_id, + a_uint32_t index, + union vr_xs_pcs_dig_ctrl1_u *value) +{ + return hppe_uniphy_reg_set( + dev_id, + NSS_UNIPHY_BASE_ADDR + VR_XS_PCS_DIG_CTRL1_ADDRESS, + index * VR_XS_PCS_DIG_CTRL1_INC, + value->val); +} + +sw_error_t +hppe_sr_mii_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union sr_mii_ctrl_u *value) +{ + if (index >= SR_MII_CTRL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_uniphy_reg_get( + dev_id, + NSS_UNIPHY_BASE_ADDR + SR_MII_CTRL_ADDRESS, + index * SR_MII_CTRL_INC, + &value->val); +} + +sw_error_t +hppe_sr_mii_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union sr_mii_ctrl_u *value) +{ + return hppe_uniphy_reg_set( + dev_id, + NSS_UNIPHY_BASE_ADDR + SR_MII_CTRL_ADDRESS, + index * SR_MII_CTRL_INC, + value->val); +} + +sw_error_t +hppe_vr_mii_an_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union vr_mii_an_ctrl_u *value) +{ + if (index >= VR_MII_AN_CTRL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_uniphy_reg_get( + dev_id, + NSS_UNIPHY_BASE_ADDR + VR_MII_AN_CTRL_ADDRESS, + index * VR_MII_AN_CTRL_INC, + &value->val); +} + +sw_error_t +hppe_vr_mii_an_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union vr_mii_an_ctrl_u *value) +{ + return hppe_uniphy_reg_set( + dev_id, + NSS_UNIPHY_BASE_ADDR + VR_MII_AN_CTRL_ADDRESS, + index * VR_MII_AN_CTRL_INC, + value->val); +} + +sw_error_t +hppe_vr_mii_an_intr_sts_get( + a_uint32_t dev_id, + a_uint32_t index, + union vr_mii_an_intr_sts_u *value) +{ + if (index >= VR_MII_AN_INTR_STS_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_uniphy_reg_get( + dev_id, + NSS_UNIPHY_BASE_ADDR + VR_MII_AN_INTR_STS_ADDRESS, + index * VR_MII_AN_INTR_STS_INC, + &value->val); +} + +sw_error_t +hppe_vr_mii_an_intr_sts_set( + a_uint32_t dev_id, + a_uint32_t index, + union vr_mii_an_intr_sts_u *value) +{ + return hppe_uniphy_reg_set( + dev_id, + NSS_UNIPHY_BASE_ADDR + VR_MII_AN_INTR_STS_ADDRESS, + index * VR_MII_AN_INTR_STS_INC, + value->val); +} + +sw_error_t +hppe_uniphy_offset_calib_4_mmd1_reg_cal_rep_time_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_offset_calib_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_offset_calib_4_get(dev_id, index, ®_val); + *value = reg_val.bf.mmd1_reg_cal_rep_time; + return ret; +} +#ifndef IN_UNIPHY_MINI +sw_error_t +hppe_uniphy_offset_calib_4_mmd1_reg_cal_rep_time_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_offset_calib_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_offset_calib_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mmd1_reg_cal_rep_time = value; + ret = hppe_uniphy_offset_calib_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_offset_calib_4_mmd1_reg_pll_locked_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_offset_calib_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_offset_calib_4_get(dev_id, index, ®_val); + *value = reg_val.bf.mmd1_reg_pll_locked_reg; + return ret; +} + +sw_error_t +hppe_uniphy_offset_calib_4_mmd1_reg_pll_locked_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_offset_calib_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_offset_calib_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mmd1_reg_pll_locked_reg = value; + ret = hppe_uniphy_offset_calib_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_offset_calib_4_mmd1_reg_clr_sampler_calib_timeout_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_offset_calib_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_offset_calib_4_get(dev_id, index, ®_val); + *value = reg_val.bf.mmd1_reg_clr_sampler_calib_timeout; + return ret; +} + +sw_error_t +hppe_uniphy_offset_calib_4_mmd1_reg_clr_sampler_calib_timeout_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_offset_calib_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_offset_calib_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mmd1_reg_clr_sampler_calib_timeout = value; + ret = hppe_uniphy_offset_calib_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_offset_calib_4_mmd1_reg_lockdet_lckdt_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_offset_calib_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_offset_calib_4_get(dev_id, index, ®_val); + *value = reg_val.bf.mmd1_reg_lockdet_lckdt_reg; + return ret; +} + +sw_error_t +hppe_uniphy_offset_calib_4_mmd1_reg_lockdet_lckdt_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_offset_calib_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_offset_calib_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mmd1_reg_lockdet_lckdt_reg = value; + ret = hppe_uniphy_offset_calib_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_offset_calib_4_mmd1_reg_cal_detect_time_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_offset_calib_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_offset_calib_4_get(dev_id, index, ®_val); + *value = reg_val.bf.mmd1_reg_cal_detect_time; + return ret; +} + +sw_error_t +hppe_uniphy_offset_calib_4_mmd1_reg_cal_detect_time_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_offset_calib_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_offset_calib_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mmd1_reg_cal_detect_time = value; + ret = hppe_uniphy_offset_calib_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_offset_calib_4_mmd1_reg_calibration_done_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_offset_calib_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_offset_calib_4_get(dev_id, index, ®_val); + *value = reg_val.bf.mmd1_reg_calibration_done_reg; + return ret; +} + +sw_error_t +hppe_uniphy_offset_calib_4_mmd1_reg_calibration_done_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_offset_calib_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_offset_calib_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mmd1_reg_calibration_done_reg = value; + ret = hppe_uniphy_offset_calib_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_offset_calib_4_mmd1_reg_smpl_cal_ready_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_offset_calib_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_offset_calib_4_get(dev_id, index, ®_val); + *value = reg_val.bf.mmd1_reg_smpl_cal_ready; + return ret; +} + +sw_error_t +hppe_uniphy_offset_calib_4_mmd1_reg_smpl_cal_ready_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_offset_calib_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_offset_calib_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mmd1_reg_smpl_cal_ready = value; + ret = hppe_uniphy_offset_calib_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_ch1_ch0_sgmii_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_mode_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_mode_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch1_ch0_sgmii; + return ret; +} + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_ch1_ch0_sgmii_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_mode_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_mode_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch1_ch0_sgmii = value; + ret = hppe_uniphy_mode_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_usxg_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_mode_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_mode_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_usxg_en; + return ret; +} + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_usxg_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_mode_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_mode_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_usxg_en = value; + ret = hppe_uniphy_mode_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_ch4_ch1_0_sgmii_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_mode_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_mode_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch4_ch1_0_sgmii; + return ret; +} + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_ch4_ch1_0_sgmii_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_mode_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_mode_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch4_ch1_0_sgmii = value; + ret = hppe_uniphy_mode_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_sgplus_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_mode_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_mode_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_sgplus_mode; + return ret; +} + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_sgplus_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_mode_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_mode_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_sgplus_mode = value; + ret = hppe_uniphy_mode_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_xpcs_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_mode_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_mode_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_xpcs_mode; + return ret; +} + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_xpcs_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_mode_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_mode_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_xpcs_mode = value; + ret = hppe_uniphy_mode_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_ch0_psgmii_qsgmii_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_mode_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_mode_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch0_psgmii_qsgmii; + return ret; +} + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_ch0_psgmii_qsgmii_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_mode_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_mode_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch0_psgmii_qsgmii = value; + ret = hppe_uniphy_mode_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_ch0_autoneg_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_mode_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_mode_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch0_autoneg_mode; + return ret; +} + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_ch0_autoneg_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_mode_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_mode_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch0_autoneg_mode = value; + ret = hppe_uniphy_mode_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_sw_v17_v18_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_mode_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_mode_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_sw_v17_v18; + return ret; +} + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_sw_v17_v18_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_mode_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_mode_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_sw_v17_v18 = value; + ret = hppe_uniphy_mode_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_ch0_mode_ctrl_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_mode_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_mode_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch0_mode_ctrl_25m; + return ret; +} + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_ch0_mode_ctrl_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_mode_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_mode_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch0_mode_ctrl_25m = value; + ret = hppe_uniphy_mode_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_sgmii_even_low_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_mode_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_mode_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_sgmii_even_low; + return ret; +} + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_sgmii_even_low_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_mode_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_mode_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_sgmii_even_low = value; + ret = hppe_uniphy_mode_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_ch0_qsgmii_sgmii_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_mode_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_mode_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch0_qsgmii_sgmii; + return ret; +} + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_ch0_qsgmii_sgmii_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_mode_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_mode_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch0_qsgmii_sgmii = value; + ret = hppe_uniphy_mode_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_sg_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_mode_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_mode_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_sg_mode; + return ret; +} + +sw_error_t +hppe_uniphy_mode_ctrl_newaddedfromhere_sg_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_mode_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_mode_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_sg_mode = value; + ret = hppe_uniphy_mode_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_mr_restart_an_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel0_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel0_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch0_mr_restart_an_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_mr_restart_an_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel0_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel0_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch0_mr_restart_an_25m = value; + ret = hppe_uniphy_channel0_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_rem_phy_lpbk_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel0_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel0_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch0_rem_phy_lpbk; + return ret; +} + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_rem_phy_lpbk_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel0_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel0_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch0_rem_phy_lpbk = value; + ret = hppe_uniphy_channel0_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_mr_reg4_ch_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel0_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel0_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch0_mr_reg4_ch_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_mr_reg4_ch_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel0_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel0_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch0_mr_reg4_ch_25m = value; + ret = hppe_uniphy_channel0_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_power_on_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel0_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel0_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch0_power_on_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_power_on_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel0_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel0_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch0_power_on_25m = value; + ret = hppe_uniphy_channel0_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_mr_main_reset_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel0_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel0_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch0_mr_main_reset_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_mr_main_reset_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel0_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel0_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch0_mr_main_reset_25m = value; + ret = hppe_uniphy_channel0_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel0_force_speed_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel0_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel0_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch0_force_speed_25m; + return ret; +} +#endif +sw_error_t +hppe_uniphy_channel0_force_speed_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel0_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel0_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch0_force_speed_25m = value; + ret = hppe_uniphy_channel0_input_output_4_set(dev_id, index, ®_val); + return ret; +} +#ifndef IN_UNIPHY_MINI +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_adp_sw_rstn_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel0_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel0_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch0_adp_sw_rstn; + return ret; +} + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_adp_sw_rstn_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel0_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel0_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch0_adp_sw_rstn = value; + ret = hppe_uniphy_channel0_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_speed_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel0_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel0_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch0_speed_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_speed_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel0_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel0_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch0_speed_25m = value; + ret = hppe_uniphy_channel0_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_mr_an_enable_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel0_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel0_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch0_mr_an_enable_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_mr_an_enable_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel0_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel0_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch0_mr_an_enable_25m = value; + ret = hppe_uniphy_channel0_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_mr_np_loaded_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel0_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel0_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch0_mr_np_loaded_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_mr_np_loaded_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel0_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel0_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch0_mr_np_loaded_25m = value; + ret = hppe_uniphy_channel0_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_mr_loopback_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel0_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel0_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch0_mr_loopback_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel0_input_output_4_newaddedfromhere_ch0_mr_loopback_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel0_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel0_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch0_mr_loopback_25m = value; + ret = hppe_uniphy_channel0_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_adp_sw_rstn_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel1_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel1_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch1_adp_sw_rstn; + return ret; +} + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_adp_sw_rstn_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel1_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel1_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch1_adp_sw_rstn = value; + ret = hppe_uniphy_channel1_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_power_on_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel1_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel1_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch1_power_on_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_power_on_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel1_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel1_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch1_power_on_25m = value; + ret = hppe_uniphy_channel1_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_mr_main_reset_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel1_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel1_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch1_mr_main_reset_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_mr_main_reset_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel1_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel1_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch1_mr_main_reset_25m = value; + ret = hppe_uniphy_channel1_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_mr_an_enable_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel1_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel1_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch1_mr_an_enable_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_mr_an_enable_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel1_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel1_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch1_mr_an_enable_25m = value; + ret = hppe_uniphy_channel1_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_speed_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel1_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel1_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch1_speed_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_speed_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel1_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel1_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch1_speed_25m = value; + ret = hppe_uniphy_channel1_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_rem_phy_lpbk_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel1_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel1_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch1_rem_phy_lpbk; + return ret; +} + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_rem_phy_lpbk_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel1_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel1_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch1_rem_phy_lpbk = value; + ret = hppe_uniphy_channel1_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_mr_reg4_ch_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel1_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel1_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch1_mr_reg4_ch_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_mr_reg4_ch_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel1_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel1_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch1_mr_reg4_ch_25m = value; + ret = hppe_uniphy_channel1_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_mr_np_loaded_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel1_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel1_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch1_mr_np_loaded_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_mr_np_loaded_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel1_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel1_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch1_mr_np_loaded_25m = value; + ret = hppe_uniphy_channel1_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_force_speed_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel1_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel1_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch1_force_speed_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_force_speed_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel1_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel1_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch1_force_speed_25m = value; + ret = hppe_uniphy_channel1_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_mr_restart_an_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel1_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel1_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch1_mr_restart_an_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_mr_restart_an_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel1_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel1_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch1_mr_restart_an_25m = value; + ret = hppe_uniphy_channel1_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_mr_loopback_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel1_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel1_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch1_mr_loopback_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel1_input_output_4_newaddedfromhere_ch1_mr_loopback_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel1_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel1_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch1_mr_loopback_25m = value; + ret = hppe_uniphy_channel1_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_rem_phy_lpbk_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel2_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel2_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch2_rem_phy_lpbk; + return ret; +} + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_rem_phy_lpbk_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel2_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel2_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch2_rem_phy_lpbk = value; + ret = hppe_uniphy_channel2_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_adp_sw_rstn_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel2_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel2_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch2_adp_sw_rstn; + return ret; +} + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_adp_sw_rstn_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel2_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel2_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch2_adp_sw_rstn = value; + ret = hppe_uniphy_channel2_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_mr_main_reset_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel2_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel2_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch2_mr_main_reset_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_mr_main_reset_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel2_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel2_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch2_mr_main_reset_25m = value; + ret = hppe_uniphy_channel2_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_mr_loopback_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel2_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel2_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch2_mr_loopback_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_mr_loopback_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel2_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel2_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch2_mr_loopback_25m = value; + ret = hppe_uniphy_channel2_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_mr_restart_an_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel2_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel2_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch2_mr_restart_an_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_mr_restart_an_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel2_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel2_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch2_mr_restart_an_25m = value; + ret = hppe_uniphy_channel2_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_speed_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel2_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel2_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch2_speed_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_speed_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel2_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel2_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch2_speed_25m = value; + ret = hppe_uniphy_channel2_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_mr_np_loaded_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel2_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel2_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch2_mr_np_loaded_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_mr_np_loaded_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel2_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel2_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch2_mr_np_loaded_25m = value; + ret = hppe_uniphy_channel2_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_force_speed_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel2_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel2_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch2_force_speed_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_force_speed_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel2_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel2_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch2_force_speed_25m = value; + ret = hppe_uniphy_channel2_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_mr_an_enable_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel2_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel2_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch2_mr_an_enable_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_mr_an_enable_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel2_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel2_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch2_mr_an_enable_25m = value; + ret = hppe_uniphy_channel2_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_power_on_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel2_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel2_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch2_power_on_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_power_on_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel2_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel2_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch2_power_on_25m = value; + ret = hppe_uniphy_channel2_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_mr_reg4_ch_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel2_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel2_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch2_mr_reg4_ch_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel2_input_output_4_newaddedfromhere_ch2_mr_reg4_ch_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel2_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel2_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch2_mr_reg4_ch_25m = value; + ret = hppe_uniphy_channel2_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_mr_main_reset_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel3_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel3_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch3_mr_main_reset_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_mr_main_reset_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel3_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel3_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch3_mr_main_reset_25m = value; + ret = hppe_uniphy_channel3_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_speed_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel3_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel3_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch3_speed_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_speed_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel3_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel3_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch3_speed_25m = value; + ret = hppe_uniphy_channel3_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_mr_np_loaded_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel3_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel3_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch3_mr_np_loaded_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_mr_np_loaded_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel3_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel3_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch3_mr_np_loaded_25m = value; + ret = hppe_uniphy_channel3_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_adp_sw_rstn_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel3_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel3_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch3_adp_sw_rstn; + return ret; +} + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_adp_sw_rstn_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel3_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel3_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch3_adp_sw_rstn = value; + ret = hppe_uniphy_channel3_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_power_on_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel3_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel3_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch3_power_on_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_power_on_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel3_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel3_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch3_power_on_25m = value; + ret = hppe_uniphy_channel3_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_mr_an_enable_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel3_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel3_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch3_mr_an_enable_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_mr_an_enable_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel3_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel3_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch3_mr_an_enable_25m = value; + ret = hppe_uniphy_channel3_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_mr_reg4_ch_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel3_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel3_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch3_mr_reg4_ch_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_mr_reg4_ch_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel3_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel3_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch3_mr_reg4_ch_25m = value; + ret = hppe_uniphy_channel3_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_mr_restart_an_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel3_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel3_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch3_mr_restart_an_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_mr_restart_an_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel3_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel3_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch3_mr_restart_an_25m = value; + ret = hppe_uniphy_channel3_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_rem_phy_lpbk_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel3_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel3_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch3_rem_phy_lpbk; + return ret; +} + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_rem_phy_lpbk_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel3_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel3_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch3_rem_phy_lpbk = value; + ret = hppe_uniphy_channel3_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_force_speed_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel3_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel3_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch3_force_speed_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_force_speed_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel3_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel3_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch3_force_speed_25m = value; + ret = hppe_uniphy_channel3_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_mr_loopback_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel3_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel3_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch3_mr_loopback_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel3_input_output_4_newaddedfromhere_ch3_mr_loopback_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel3_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel3_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch3_mr_loopback_25m = value; + ret = hppe_uniphy_channel3_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_mr_loopback_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel4_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel4_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch4_mr_loopback_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_mr_loopback_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel4_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel4_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch4_mr_loopback_25m = value; + ret = hppe_uniphy_channel4_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_mr_reg4_ch_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel4_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel4_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch4_mr_reg4_ch_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_mr_reg4_ch_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel4_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel4_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch4_mr_reg4_ch_25m = value; + ret = hppe_uniphy_channel4_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_mr_restart_an_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel4_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel4_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch4_mr_restart_an_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_mr_restart_an_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel4_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel4_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch4_mr_restart_an_25m = value; + ret = hppe_uniphy_channel4_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_mr_an_enable_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel4_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel4_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch4_mr_an_enable_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_mr_an_enable_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel4_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel4_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch4_mr_an_enable_25m = value; + ret = hppe_uniphy_channel4_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_force_speed_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel4_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel4_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch4_force_speed_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_force_speed_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel4_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel4_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch4_force_speed_25m = value; + ret = hppe_uniphy_channel4_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_mr_main_reset_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel4_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel4_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch4_mr_main_reset_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_mr_main_reset_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel4_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel4_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch4_mr_main_reset_25m = value; + ret = hppe_uniphy_channel4_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_power_on_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel4_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel4_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch4_power_on_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_power_on_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel4_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel4_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch4_power_on_25m = value; + ret = hppe_uniphy_channel4_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_speed_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel4_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel4_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch4_speed_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_speed_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel4_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel4_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch4_speed_25m = value; + ret = hppe_uniphy_channel4_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_rem_phy_lpbk_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel4_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel4_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch4_rem_phy_lpbk; + return ret; +} + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_rem_phy_lpbk_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel4_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel4_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch4_rem_phy_lpbk = value; + ret = hppe_uniphy_channel4_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_mr_np_loaded_25m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel4_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel4_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch4_mr_np_loaded_25m; + return ret; +} + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_mr_np_loaded_25m_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel4_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel4_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch4_mr_np_loaded_25m = value; + ret = hppe_uniphy_channel4_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_adp_sw_rstn_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_channel4_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel4_input_output_4_get(dev_id, index, ®_val); + *value = reg_val.bf.newaddedfromhere_ch4_adp_sw_rstn; + return ret; +} + +sw_error_t +hppe_uniphy_channel4_input_output_4_newaddedfromhere_ch4_adp_sw_rstn_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_channel4_input_output_4_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_channel4_input_output_4_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.newaddedfromhere_ch4_adp_sw_rstn = value; + ret = hppe_uniphy_channel4_input_output_4_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_sr_xs_pcs_kr_sts1_plu_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sr_xs_pcs_kr_sts1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_sr_xs_pcs_kr_sts1_get(dev_id, index, ®_val); + *value = reg_val.bf.plu; + return ret; +} + +sw_error_t +hppe_sr_xs_pcs_kr_sts1_plu_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union sr_xs_pcs_kr_sts1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_sr_xs_pcs_kr_sts1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.plu = value; + ret = hppe_sr_xs_pcs_kr_sts1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_sr_xs_pcs_kr_sts1_prbs31abl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sr_xs_pcs_kr_sts1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_sr_xs_pcs_kr_sts1_get(dev_id, index, ®_val); + *value = reg_val.bf.prbs31abl; + return ret; +} + +sw_error_t +hppe_sr_xs_pcs_kr_sts1_prbs31abl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union sr_xs_pcs_kr_sts1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_sr_xs_pcs_kr_sts1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.prbs31abl = value; + ret = hppe_sr_xs_pcs_kr_sts1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_sr_xs_pcs_kr_sts1_rpcs_bklk_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sr_xs_pcs_kr_sts1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_sr_xs_pcs_kr_sts1_get(dev_id, index, ®_val); + *value = reg_val.bf.rpcs_bklk; + return ret; +} + +sw_error_t +hppe_sr_xs_pcs_kr_sts1_rpcs_bklk_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union sr_xs_pcs_kr_sts1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_sr_xs_pcs_kr_sts1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rpcs_bklk = value; + ret = hppe_sr_xs_pcs_kr_sts1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_sr_xs_pcs_kr_sts1_prcs_hiber_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sr_xs_pcs_kr_sts1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_sr_xs_pcs_kr_sts1_get(dev_id, index, ®_val); + *value = reg_val.bf.prcs_hiber; + return ret; +} + +sw_error_t +hppe_sr_xs_pcs_kr_sts1_prcs_hiber_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union sr_xs_pcs_kr_sts1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_sr_xs_pcs_kr_sts1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.prcs_hiber = value; + ret = hppe_sr_xs_pcs_kr_sts1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_sr_xs_pcs_kr_sts1_prbs9abl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sr_xs_pcs_kr_sts1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_sr_xs_pcs_kr_sts1_get(dev_id, index, ®_val); + *value = reg_val.bf.prbs9abl; + return ret; +} + +sw_error_t +hppe_sr_xs_pcs_kr_sts1_prbs9abl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union sr_xs_pcs_kr_sts1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_sr_xs_pcs_kr_sts1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.prbs9abl = value; + ret = hppe_sr_xs_pcs_kr_sts1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_vr_rst_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vr_xs_pcs_dig_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_xs_pcs_dig_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.vr_rst; + return ret; +} + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_vr_rst_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vr_xs_pcs_dig_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_xs_pcs_dig_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.vr_rst = value; + ret = hppe_vr_xs_pcs_dig_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_usra_rst_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vr_xs_pcs_dig_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_xs_pcs_dig_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.usra_rst; + return ret; +} + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_usra_rst_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vr_xs_pcs_dig_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_xs_pcs_dig_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.usra_rst = value; + ret = hppe_vr_xs_pcs_dig_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_en_2_5g_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vr_xs_pcs_dig_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_xs_pcs_dig_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.en_2_5g_mode; + return ret; +} + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_en_2_5g_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vr_xs_pcs_dig_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_xs_pcs_dig_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.en_2_5g_mode = value; + ret = hppe_vr_xs_pcs_dig_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_dskbyp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vr_xs_pcs_dig_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_xs_pcs_dig_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.dskbyp; + return ret; +} + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_dskbyp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vr_xs_pcs_dig_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_xs_pcs_dig_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.dskbyp = value; + ret = hppe_vr_xs_pcs_dig_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_en_vsmmd1_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vr_xs_pcs_dig_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_xs_pcs_dig_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.en_vsmmd1; + return ret; +} + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_en_vsmmd1_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vr_xs_pcs_dig_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_xs_pcs_dig_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.en_vsmmd1 = value; + ret = hppe_vr_xs_pcs_dig_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_init_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vr_xs_pcs_dig_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_xs_pcs_dig_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.init; + return ret; +} + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_init_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vr_xs_pcs_dig_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_xs_pcs_dig_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.init = value; + ret = hppe_vr_xs_pcs_dig_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_cl37_bp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vr_xs_pcs_dig_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_xs_pcs_dig_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.cl37_bp; + return ret; +} + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_cl37_bp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vr_xs_pcs_dig_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_xs_pcs_dig_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cl37_bp = value; + ret = hppe_vr_xs_pcs_dig_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_pwrsv_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vr_xs_pcs_dig_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_xs_pcs_dig_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.pwrsv; + return ret; +} + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_pwrsv_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vr_xs_pcs_dig_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_xs_pcs_dig_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pwrsv = value; + ret = hppe_vr_xs_pcs_dig_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_dtxlaned_3_1_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vr_xs_pcs_dig_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_xs_pcs_dig_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.dtxlaned_3_1; + return ret; +} + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_dtxlaned_3_1_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vr_xs_pcs_dig_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_xs_pcs_dig_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.dtxlaned_3_1 = value; + ret = hppe_vr_xs_pcs_dig_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_usxg_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vr_xs_pcs_dig_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_xs_pcs_dig_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.usxg_en; + return ret; +} + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_usxg_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vr_xs_pcs_dig_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_xs_pcs_dig_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.usxg_en = value; + ret = hppe_vr_xs_pcs_dig_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_r2tlbe_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vr_xs_pcs_dig_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_xs_pcs_dig_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.r2tlbe; + return ret; +} + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_r2tlbe_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vr_xs_pcs_dig_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_xs_pcs_dig_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.r2tlbe = value; + ret = hppe_vr_xs_pcs_dig_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_cr_cjn_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vr_xs_pcs_dig_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_xs_pcs_dig_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.cr_cjn; + return ret; +} + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_cr_cjn_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vr_xs_pcs_dig_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_xs_pcs_dig_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cr_cjn = value; + ret = hppe_vr_xs_pcs_dig_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_dtxlaned_0_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vr_xs_pcs_dig_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_xs_pcs_dig_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.dtxlaned_0; + return ret; +} + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_dtxlaned_0_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vr_xs_pcs_dig_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_xs_pcs_dig_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.dtxlaned_0 = value; + ret = hppe_vr_xs_pcs_dig_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_byp_pwrup_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vr_xs_pcs_dig_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_xs_pcs_dig_ctrl1_get(dev_id, index, ®_val); + *value = reg_val.bf.byp_pwrup; + return ret; +} + +sw_error_t +hppe_vr_xs_pcs_dig_ctrl1_byp_pwrup_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vr_xs_pcs_dig_ctrl1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_xs_pcs_dig_ctrl1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.byp_pwrup = value; + ret = hppe_vr_xs_pcs_dig_ctrl1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_sr_mii_ctrl_lpm_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sr_mii_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_sr_mii_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.lpm; + return ret; +} + +sw_error_t +hppe_sr_mii_ctrl_lpm_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union sr_mii_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_sr_mii_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.lpm = value; + ret = hppe_sr_mii_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_sr_mii_ctrl_duplex_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sr_mii_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_sr_mii_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.duplex_mode; + return ret; +} + +sw_error_t +hppe_sr_mii_ctrl_duplex_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union sr_mii_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_sr_mii_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.duplex_mode = value; + ret = hppe_sr_mii_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_sr_mii_ctrl_ss6_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sr_mii_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_sr_mii_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.ss6; + return ret; +} + +sw_error_t +hppe_sr_mii_ctrl_ss6_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union sr_mii_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_sr_mii_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ss6 = value; + ret = hppe_sr_mii_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_sr_mii_ctrl_ss5_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sr_mii_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_sr_mii_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.ss5; + return ret; +} + +sw_error_t +hppe_sr_mii_ctrl_ss5_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union sr_mii_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_sr_mii_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ss5 = value; + ret = hppe_sr_mii_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_sr_mii_ctrl_ss13_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sr_mii_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_sr_mii_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.ss13; + return ret; +} + +sw_error_t +hppe_sr_mii_ctrl_ss13_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union sr_mii_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_sr_mii_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ss13 = value; + ret = hppe_sr_mii_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_sr_mii_ctrl_an_enable_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sr_mii_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_sr_mii_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.an_enable; + return ret; +} + +sw_error_t +hppe_sr_mii_ctrl_an_enable_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union sr_mii_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_sr_mii_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.an_enable = value; + ret = hppe_sr_mii_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_sr_mii_ctrl_restart_an_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sr_mii_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_sr_mii_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.restart_an; + return ret; +} + +sw_error_t +hppe_sr_mii_ctrl_restart_an_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union sr_mii_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_sr_mii_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.restart_an = value; + ret = hppe_sr_mii_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_sr_mii_ctrl_rst_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sr_mii_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_sr_mii_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.rst; + return ret; +} + +sw_error_t +hppe_sr_mii_ctrl_rst_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union sr_mii_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_sr_mii_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rst = value; + ret = hppe_sr_mii_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_sr_mii_ctrl_lbe_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sr_mii_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_sr_mii_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.lbe; + return ret; +} + +sw_error_t +hppe_sr_mii_ctrl_lbe_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union sr_mii_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_sr_mii_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.lbe = value; + ret = hppe_sr_mii_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vr_mii_an_ctrl_pcs_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vr_mii_an_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_mii_an_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.pcs_mode; + return ret; +} + +sw_error_t +hppe_vr_mii_an_ctrl_pcs_mode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vr_mii_an_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_mii_an_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pcs_mode = value; + ret = hppe_vr_mii_an_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vr_mii_an_ctrl_mii_an_intr_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vr_mii_an_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_mii_an_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.mii_an_intr_en; + return ret; +} + +sw_error_t +hppe_vr_mii_an_ctrl_mii_an_intr_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vr_mii_an_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_mii_an_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mii_an_intr_en = value; + ret = hppe_vr_mii_an_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vr_mii_an_ctrl_sgmii_link_sts_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vr_mii_an_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_mii_an_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.sgmii_link_sts; + return ret; +} + +sw_error_t +hppe_vr_mii_an_ctrl_sgmii_link_sts_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vr_mii_an_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_mii_an_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.sgmii_link_sts = value; + ret = hppe_vr_mii_an_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vr_mii_an_ctrl_tx_config_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vr_mii_an_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_mii_an_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_config; + return ret; +} + +sw_error_t +hppe_vr_mii_an_ctrl_tx_config_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vr_mii_an_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_mii_an_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_config = value; + ret = hppe_vr_mii_an_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vr_mii_an_ctrl_mii_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vr_mii_an_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_mii_an_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.mii_ctrl; + return ret; +} + +sw_error_t +hppe_vr_mii_an_ctrl_mii_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vr_mii_an_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_mii_an_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mii_ctrl = value; + ret = hppe_vr_mii_an_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vr_mii_an_intr_sts_usxg_an_sts_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vr_mii_an_intr_sts_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_mii_an_intr_sts_get(dev_id, index, ®_val); + *value = reg_val.bf.usxg_an_sts; + return ret; +} + +sw_error_t +hppe_vr_mii_an_intr_sts_usxg_an_sts_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vr_mii_an_intr_sts_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_mii_an_intr_sts_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.usxg_an_sts = value; + ret = hppe_vr_mii_an_intr_sts_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vr_mii_an_intr_sts_cl37_ansgm_sts_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vr_mii_an_intr_sts_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_mii_an_intr_sts_get(dev_id, index, ®_val); + *value = reg_val.bf.cl37_ansgm_sts; + return ret; +} + +sw_error_t +hppe_vr_mii_an_intr_sts_cl37_ansgm_sts_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vr_mii_an_intr_sts_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_mii_an_intr_sts_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cl37_ansgm_sts = value; + ret = hppe_vr_mii_an_intr_sts_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vr_mii_an_intr_sts_cl37_ancmplt_intr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vr_mii_an_intr_sts_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_mii_an_intr_sts_get(dev_id, index, ®_val); + *value = reg_val.bf.cl37_ancmplt_intr; + return ret; +} + +sw_error_t +hppe_vr_mii_an_intr_sts_cl37_ancmplt_intr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vr_mii_an_intr_sts_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vr_mii_an_intr_sts_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cl37_ancmplt_intr = value; + ret = hppe_vr_mii_an_intr_sts_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_pll_control_vco_related_selection_get( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_pll_control_vco_related_selection_u *value) +{ + if (index >= UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_uniphy_reg_get( + dev_id, + NSS_UNIPHY_BASE_ADDR + UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_ADDRESS, + index * UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_INC, + &value->val); +} + +sw_error_t +hppe_uniphy_pll_control_vco_related_selection_set( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_pll_control_vco_related_selection_u *value) +{ + return hppe_uniphy_reg_set( + dev_id, + NSS_UNIPHY_BASE_ADDR + UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_ADDRESS, + index * UNIPHY_PLL_CONTROL_VCO_RELATED_SELECTION_INC, + value->val); +} + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_get( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_tx_ac_jtag_mux_driver_selection_u *value) +{ + if (index >= UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_uniphy_reg_get( + dev_id, + NSS_UNIPHY_BASE_ADDR + UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_ADDRESS, + index * UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_INC, + &value->val); +} + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_set( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_tx_ac_jtag_mux_driver_selection_u *value) +{ + return hppe_uniphy_reg_set( + dev_id, + NSS_UNIPHY_BASE_ADDR + UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_ADDRESS, + index * UNIPHY_TX_AC_JTAG_MUX_DRIVER_SELECTION_INC, + value->val); +} + +sw_error_t +hppe_uniphy_resistor_calibration_1_get( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_resistor_calibration_1_u *value) +{ + if (index >= UNIPHY_RESISTOR_CALIBRATION_1_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_uniphy_reg_get( + dev_id, + NSS_UNIPHY_BASE_ADDR + UNIPHY_RESISTOR_CALIBRATION_1_ADDRESS, + index * UNIPHY_RESISTOR_CALIBRATION_1_INC, + &value->val); +} + +sw_error_t +hppe_uniphy_resistor_calibration_1_set( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_resistor_calibration_1_u *value) +{ + return hppe_uniphy_reg_set( + dev_id, + NSS_UNIPHY_BASE_ADDR + UNIPHY_RESISTOR_CALIBRATION_1_ADDRESS, + index * UNIPHY_RESISTOR_CALIBRATION_1_INC, + value->val); +} + +sw_error_t +hppe_uniphy_pll_vco_related_control_1_get( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_pll_vco_related_control_1_u *value) +{ + if (index >= UNIPHY_PLL_VCO_RELATED_CONTROL_1_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_uniphy_reg_get( + dev_id, + NSS_UNIPHY_BASE_ADDR + UNIPHY_PLL_VCO_RELATED_CONTROL_1_ADDRESS, + index * UNIPHY_PLL_VCO_RELATED_CONTROL_1_INC, + &value->val); +} + +sw_error_t +hppe_uniphy_pll_vco_related_control_1_set( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_pll_vco_related_control_1_u *value) +{ + return hppe_uniphy_reg_set( + dev_id, + NSS_UNIPHY_BASE_ADDR + UNIPHY_PLL_VCO_RELATED_CONTROL_1_ADDRESS, + index * UNIPHY_PLL_VCO_RELATED_CONTROL_1_INC, + value->val); +} + +sw_error_t +hppe_uniphy_rx_afe_2_get( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_rx_afe_2_u *value) +{ + if (index >= UNIPHY_RX_AFE_2_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_uniphy_reg_get( + dev_id, + NSS_UNIPHY_BASE_ADDR + UNIPHY_RX_AFE_2_ADDRESS, + index * UNIPHY_RX_AFE_2_INC, + &value->val); +} + +sw_error_t +hppe_uniphy_rx_afe_2_set( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_rx_afe_2_u *value) +{ + return hppe_uniphy_reg_set( + dev_id, + NSS_UNIPHY_BASE_ADDR + UNIPHY_RX_AFE_2_ADDRESS, + index * UNIPHY_RX_AFE_2_INC, + value->val); +} + +sw_error_t +hppe_bandgap_ip_mbias_2_get( + a_uint32_t dev_id, + a_uint32_t index, + union bandgap_ip_mbias_2_u *value) +{ + if (index >= BANDGAP_IP_MBIAS_2_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_uniphy_reg_get( + dev_id, + NSS_UNIPHY_BASE_ADDR + BANDGAP_IP_MBIAS_2_ADDRESS, + index * BANDGAP_IP_MBIAS_2_INC, + &value->val); +} + +sw_error_t +hppe_bandgap_ip_mbias_2_set( + a_uint32_t dev_id, + a_uint32_t index, + union bandgap_ip_mbias_2_u *value) +{ + return hppe_uniphy_reg_set( + dev_id, + NSS_UNIPHY_BASE_ADDR + BANDGAP_IP_MBIAS_2_ADDRESS, + index * BANDGAP_IP_MBIAS_2_INC, + value->val); +} + +sw_error_t +hppe_ldo_0p9v_related_1_get( + a_uint32_t dev_id, + a_uint32_t index, + union ldo_0p9v_related_1_u *value) +{ + if (index >= LDO_0P9V_RELATED_1_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_uniphy_reg_get( + dev_id, + NSS_UNIPHY_BASE_ADDR + LDO_0P9V_RELATED_1_ADDRESS, + index * LDO_0P9V_RELATED_1_INC, + &value->val); +} + +sw_error_t +hppe_ldo_0p9v_related_1_set( + a_uint32_t dev_id, + a_uint32_t index, + union ldo_0p9v_related_1_u *value) +{ + return hppe_uniphy_reg_set( + dev_id, + NSS_UNIPHY_BASE_ADDR + LDO_0P9V_RELATED_1_ADDRESS, + index * LDO_0P9V_RELATED_1_INC, + value->val); +} + +sw_error_t +hppe_otp_vtt_ldo_related_get( + a_uint32_t dev_id, + a_uint32_t index, + union otp_vtt_ldo_related_u *value) +{ + if (index >= OTP_VTT_LDO_RELATED_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_uniphy_reg_get( + dev_id, + NSS_UNIPHY_BASE_ADDR + OTP_VTT_LDO_RELATED_ADDRESS, + index * OTP_VTT_LDO_RELATED_INC, + &value->val); +} + +sw_error_t +hppe_otp_vtt_ldo_related_set( + a_uint32_t dev_id, + a_uint32_t index, + union otp_vtt_ldo_related_u *value) +{ + return hppe_uniphy_reg_set( + dev_id, + NSS_UNIPHY_BASE_ADDR + OTP_VTT_LDO_RELATED_ADDRESS, + index * OTP_VTT_LDO_RELATED_INC, + value->val); +} + +sw_error_t +hppe_otp_temperature_compensate_1_get( + a_uint32_t dev_id, + a_uint32_t index, + union otp_temperature_compensate_1_u *value) +{ + if (index >= OTP_TEMPERATURE_COMPENSATE_1_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_uniphy_reg_get( + dev_id, + NSS_UNIPHY_BASE_ADDR + OTP_TEMPERATURE_COMPENSATE_1_ADDRESS, + index * OTP_TEMPERATURE_COMPENSATE_1_INC, + &value->val); +} + +sw_error_t +hppe_otp_temperature_compensate_1_set( + a_uint32_t dev_id, + a_uint32_t index, + union otp_temperature_compensate_1_u *value) +{ + return hppe_uniphy_reg_set( + dev_id, + NSS_UNIPHY_BASE_ADDR + OTP_TEMPERATURE_COMPENSATE_1_ADDRESS, + index * OTP_TEMPERATURE_COMPENSATE_1_INC, + value->val); +} + +sw_error_t +hppe_pll_vco_related_control_1_get( + a_uint32_t dev_id, + a_uint32_t index, + union pll_vco_related_control_1_u *value) +{ + if (index >= PLL_VCO_RELATED_CONTROL_1_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_uniphy_reg_get( + dev_id, + NSS_UNIPHY_BASE_ADDR + PLL_VCO_RELATED_CONTROL_1_ADDRESS, + index * PLL_VCO_RELATED_CONTROL_1_INC, + &value->val); +} + +sw_error_t +hppe_pll_vco_related_control_1_set( + a_uint32_t dev_id, + a_uint32_t index, + union pll_vco_related_control_1_u *value) +{ + return hppe_uniphy_reg_set( + dev_id, + NSS_UNIPHY_BASE_ADDR + PLL_VCO_RELATED_CONTROL_1_ADDRESS, + index * PLL_VCO_RELATED_CONTROL_1_INC, + value->val); +} + +sw_error_t +hppe_pll_control_vco_related_selection_2_get( + a_uint32_t dev_id, + a_uint32_t index, + union pll_control_vco_related_selection_2_u *value) +{ + if (index >= PLL_CONTROL_VCO_RELATED_SELECTION_2_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_uniphy_reg_get( + dev_id, + NSS_UNIPHY_BASE_ADDR + PLL_CONTROL_VCO_RELATED_SELECTION_2_ADDRESS, + index * PLL_CONTROL_VCO_RELATED_SELECTION_2_INC, + &value->val); +} + +sw_error_t +hppe_pll_control_vco_related_selection_2_set( + a_uint32_t dev_id, + a_uint32_t index, + union pll_control_vco_related_selection_2_u *value) +{ + return hppe_uniphy_reg_set( + dev_id, + NSS_UNIPHY_BASE_ADDR + PLL_CONTROL_VCO_RELATED_SELECTION_2_ADDRESS, + index * PLL_CONTROL_VCO_RELATED_SELECTION_2_INC, + value->val); +} + +sw_error_t +hppe_uniphy_pll_control_vco_related_selection_mmd1_reg_src_uphy_pll_vco_gain_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_pll_control_vco_related_selection_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_pll_control_vco_related_selection_get(dev_id, index, ®_val); + *value = reg_val.bf.mmd1_reg_src_uphy_pll_vco_gain; + return ret; +} + +sw_error_t +hppe_uniphy_pll_control_vco_related_selection_mmd1_reg_src_uphy_pll_vco_gain_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_pll_control_vco_related_selection_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_pll_control_vco_related_selection_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mmd1_reg_src_uphy_pll_vco_gain = value; + ret = hppe_uniphy_pll_control_vco_related_selection_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_pll_control_vco_related_selection_mmd1_reg_src_uphy_pll_vco_temp_cmp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_pll_control_vco_related_selection_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_pll_control_vco_related_selection_get(dev_id, index, ®_val); + *value = reg_val.bf.mmd1_reg_src_uphy_pll_vco_temp_cmp; + return ret; +} + +sw_error_t +hppe_uniphy_pll_control_vco_related_selection_mmd1_reg_src_uphy_pll_vco_temp_cmp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_pll_control_vco_related_selection_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_pll_control_vco_related_selection_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mmd1_reg_src_uphy_pll_vco_temp_cmp = value; + ret = hppe_uniphy_pll_control_vco_related_selection_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_pll_control_vco_related_selection_mmd1_reg_src_uphy_pll_lpf_c2_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_pll_control_vco_related_selection_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_pll_control_vco_related_selection_get(dev_id, index, ®_val); + *value = reg_val.bf.mmd1_reg_src_uphy_pll_lpf_c2; + return ret; +} + +sw_error_t +hppe_uniphy_pll_control_vco_related_selection_mmd1_reg_src_uphy_pll_lpf_c2_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_pll_control_vco_related_selection_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_pll_control_vco_related_selection_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mmd1_reg_src_uphy_pll_lpf_c2 = value; + ret = hppe_uniphy_pll_control_vco_related_selection_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_pll_control_vco_related_selection_mmd1_reg_src_uphy_pll_vco_amp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_pll_control_vco_related_selection_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_pll_control_vco_related_selection_get(dev_id, index, ®_val); + *value = reg_val.bf.mmd1_reg_src_uphy_pll_vco_amp; + return ret; +} + +sw_error_t +hppe_uniphy_pll_control_vco_related_selection_mmd1_reg_src_uphy_pll_vco_amp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_pll_control_vco_related_selection_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_pll_control_vco_related_selection_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mmd1_reg_src_uphy_pll_vco_amp = value; + ret = hppe_uniphy_pll_control_vco_related_selection_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_pll_control_vco_related_selection_mmd1_reg_src_uphy_pll_lpf_dc_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_pll_control_vco_related_selection_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_pll_control_vco_related_selection_get(dev_id, index, ®_val); + *value = reg_val.bf.mmd1_reg_src_uphy_pll_lpf_dc; + return ret; +} + +sw_error_t +hppe_uniphy_pll_control_vco_related_selection_mmd1_reg_src_uphy_pll_lpf_dc_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_pll_control_vco_related_selection_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_pll_control_vco_related_selection_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mmd1_reg_src_uphy_pll_lpf_dc = value; + ret = hppe_uniphy_pll_control_vco_related_selection_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_pll_control_vco_related_selection_mmd1_reg_src_uphy_pll_cp_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_pll_control_vco_related_selection_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_pll_control_vco_related_selection_get(dev_id, index, ®_val); + *value = reg_val.bf.mmd1_reg_src_uphy_pll_cp_sel; + return ret; +} + +sw_error_t +hppe_uniphy_pll_control_vco_related_selection_mmd1_reg_src_uphy_pll_cp_sel_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_pll_control_vco_related_selection_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_pll_control_vco_related_selection_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mmd1_reg_src_uphy_pll_cp_sel = value; + ret = hppe_uniphy_pll_control_vco_related_selection_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_pll_control_vco_related_selection_mmd1_reg_src_uphy_pll_lpf_res_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_pll_control_vco_related_selection_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_pll_control_vco_related_selection_get(dev_id, index, ®_val); + *value = reg_val.bf.mmd1_reg_src_uphy_pll_lpf_res; + return ret; +} + +sw_error_t +hppe_uniphy_pll_control_vco_related_selection_mmd1_reg_src_uphy_pll_lpf_res_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_pll_control_vco_related_selection_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_pll_control_vco_related_selection_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mmd1_reg_src_uphy_pll_lpf_res = value; + ret = hppe_uniphy_pll_control_vco_related_selection_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_mmd1_reg_src_uphy_tx_vcm_delta_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_tx_ac_jtag_mux_driver_selection_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_tx_ac_jtag_mux_driver_selection_get(dev_id, index, ®_val); + *value = reg_val.bf.mmd1_reg_src_uphy_tx_vcm_delta; + return ret; +} + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_mmd1_reg_src_uphy_tx_vcm_delta_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_tx_ac_jtag_mux_driver_selection_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_tx_ac_jtag_mux_driver_selection_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mmd1_reg_src_uphy_tx_vcm_delta = value; + ret = hppe_uniphy_tx_ac_jtag_mux_driver_selection_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_mmd1_reg_src_uphy_tx_emp_lsb_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_tx_ac_jtag_mux_driver_selection_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_tx_ac_jtag_mux_driver_selection_get(dev_id, index, ®_val); + *value = reg_val.bf.mmd1_reg_src_uphy_tx_emp_lsb_en; + return ret; +} + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_mmd1_reg_src_uphy_tx_emp_lsb_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_tx_ac_jtag_mux_driver_selection_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_tx_ac_jtag_mux_driver_selection_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mmd1_reg_src_uphy_tx_emp_lsb_en = value; + ret = hppe_uniphy_tx_ac_jtag_mux_driver_selection_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_mmd1_reg_src_uphy_tx_emp_lvl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_tx_ac_jtag_mux_driver_selection_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_tx_ac_jtag_mux_driver_selection_get(dev_id, index, ®_val); + *value = reg_val.bf.mmd1_reg_src_uphy_tx_emp_lvl; + return ret; +} + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_mmd1_reg_src_uphy_tx_emp_lvl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_tx_ac_jtag_mux_driver_selection_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_tx_ac_jtag_mux_driver_selection_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mmd1_reg_src_uphy_tx_emp_lvl = value; + ret = hppe_uniphy_tx_ac_jtag_mux_driver_selection_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_mmd1_reg_src_uphy_tx_acjtag_beacon_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_tx_ac_jtag_mux_driver_selection_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_tx_ac_jtag_mux_driver_selection_get(dev_id, index, ®_val); + *value = reg_val.bf.mmd1_reg_src_uphy_tx_acjtag_beacon_en; + return ret; +} + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_mmd1_reg_src_uphy_tx_acjtag_beacon_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_tx_ac_jtag_mux_driver_selection_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_tx_ac_jtag_mux_driver_selection_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mmd1_reg_src_uphy_tx_acjtag_beacon_en = value; + ret = hppe_uniphy_tx_ac_jtag_mux_driver_selection_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_mmd1_reg_src_uphy_tx_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_tx_ac_jtag_mux_driver_selection_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_tx_ac_jtag_mux_driver_selection_get(dev_id, index, ®_val); + *value = reg_val.bf.mmd1_reg_src_uphy_tx_en; + return ret; +} + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_mmd1_reg_src_uphy_tx_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_tx_ac_jtag_mux_driver_selection_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_tx_ac_jtag_mux_driver_selection_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mmd1_reg_src_uphy_tx_en = value; + ret = hppe_uniphy_tx_ac_jtag_mux_driver_selection_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_mmd1_reg_src_uphy_txd_bit_width_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_tx_ac_jtag_mux_driver_selection_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_tx_ac_jtag_mux_driver_selection_get(dev_id, index, ®_val); + *value = reg_val.bf.mmd1_reg_src_uphy_txd_bit_width; + return ret; +} + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_mmd1_reg_src_uphy_txd_bit_width_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_tx_ac_jtag_mux_driver_selection_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_tx_ac_jtag_mux_driver_selection_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mmd1_reg_src_uphy_txd_bit_width = value; + ret = hppe_uniphy_tx_ac_jtag_mux_driver_selection_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_mmd1_reg_src_uphy_tx_rescal_code_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_tx_ac_jtag_mux_driver_selection_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_tx_ac_jtag_mux_driver_selection_get(dev_id, index, ®_val); + *value = reg_val.bf.mmd1_reg_src_uphy_tx_rescal_code; + return ret; +} + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_mmd1_reg_src_uphy_tx_rescal_code_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_tx_ac_jtag_mux_driver_selection_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_tx_ac_jtag_mux_driver_selection_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mmd1_reg_src_uphy_tx_rescal_code = value; + ret = hppe_uniphy_tx_ac_jtag_mux_driver_selection_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_mmd1_reg_src_uphy_tx_amp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_tx_ac_jtag_mux_driver_selection_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_tx_ac_jtag_mux_driver_selection_get(dev_id, index, ®_val); + *value = reg_val.bf.mmd1_reg_src_uphy_tx_amp; + return ret; +} + +sw_error_t +hppe_uniphy_tx_ac_jtag_mux_driver_selection_mmd1_reg_src_uphy_tx_amp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_tx_ac_jtag_mux_driver_selection_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_tx_ac_jtag_mux_driver_selection_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mmd1_reg_src_uphy_tx_amp = value; + ret = hppe_uniphy_tx_ac_jtag_mux_driver_selection_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_resistor_calibration_1_mmd1_reg_disable_load_res_txrx_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_resistor_calibration_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_resistor_calibration_1_get(dev_id, index, ®_val); + *value = reg_val.bf.mmd1_reg_disable_load_res_txrx; + return ret; +} + +sw_error_t +hppe_uniphy_resistor_calibration_1_mmd1_reg_disable_load_res_txrx_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_resistor_calibration_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_resistor_calibration_1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mmd1_reg_disable_load_res_txrx = value; + ret = hppe_uniphy_resistor_calibration_1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_resistor_calibration_1_mmd1_reg_calib_tx_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_resistor_calibration_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_resistor_calibration_1_get(dev_id, index, ®_val); + *value = reg_val.bf.mmd1_reg_calib_tx_reg; + return ret; +} + +sw_error_t +hppe_uniphy_resistor_calibration_1_mmd1_reg_calib_tx_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_resistor_calibration_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_resistor_calibration_1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mmd1_reg_calib_tx_reg = value; + ret = hppe_uniphy_resistor_calibration_1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_resistor_calibration_1_mmd1_reg_calib_rx_reg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_resistor_calibration_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_resistor_calibration_1_get(dev_id, index, ®_val); + *value = reg_val.bf.mmd1_reg_calib_rx_reg; + return ret; +} + +sw_error_t +hppe_uniphy_resistor_calibration_1_mmd1_reg_calib_rx_reg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_resistor_calibration_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_resistor_calibration_1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mmd1_reg_calib_rx_reg = value; + ret = hppe_uniphy_resistor_calibration_1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_resistor_calibration_1_mmd1_reg_vref_lvl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_resistor_calibration_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_resistor_calibration_1_get(dev_id, index, ®_val); + *value = reg_val.bf.mmd1_reg_vref_lvl; + return ret; +} + +sw_error_t +hppe_uniphy_resistor_calibration_1_mmd1_reg_vref_lvl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_resistor_calibration_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_resistor_calibration_1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mmd1_reg_vref_lvl = value; + ret = hppe_uniphy_resistor_calibration_1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_pll_vco_related_control_1_miireg_uphy_pll_lckdt_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_pll_vco_related_control_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_pll_vco_related_control_1_get(dev_id, index, ®_val); + *value = reg_val.bf.miireg_uphy_pll_lckdt_en; + return ret; +} + +sw_error_t +hppe_uniphy_pll_vco_related_control_1_miireg_uphy_pll_lckdt_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_pll_vco_related_control_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_pll_vco_related_control_1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.miireg_uphy_pll_lckdt_en = value; + ret = hppe_uniphy_pll_vco_related_control_1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_pll_vco_related_control_1_miireg_autoload_sel_pll_vco_calib_ready_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_pll_vco_related_control_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_pll_vco_related_control_1_get(dev_id, index, ®_val); + *value = reg_val.bf.miireg_autoload_sel_pll_vco_calib_ready; + return ret; +} + +sw_error_t +hppe_uniphy_pll_vco_related_control_1_miireg_autoload_sel_pll_vco_calib_ready_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_pll_vco_related_control_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_pll_vco_related_control_1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.miireg_autoload_sel_pll_vco_calib_ready = value; + ret = hppe_uniphy_pll_vco_related_control_1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_pll_vco_related_control_1_miireg_reg_uphy_pll_vco_calib_ready_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_pll_vco_related_control_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_pll_vco_related_control_1_get(dev_id, index, ®_val); + *value = reg_val.bf.miireg_reg_uphy_pll_vco_calib_ready; + return ret; +} + +sw_error_t +hppe_uniphy_pll_vco_related_control_1_miireg_reg_uphy_pll_vco_calib_ready_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_pll_vco_related_control_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_pll_vco_related_control_1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.miireg_reg_uphy_pll_vco_calib_ready = value; + ret = hppe_uniphy_pll_vco_related_control_1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_pll_vco_related_control_1_miireg_reg_uphy_pll_vco_temp_cmp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_pll_vco_related_control_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_pll_vco_related_control_1_get(dev_id, index, ®_val); + *value = reg_val.bf.miireg_reg_uphy_pll_vco_temp_cmp; + return ret; +} + +sw_error_t +hppe_uniphy_pll_vco_related_control_1_miireg_reg_uphy_pll_vco_temp_cmp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_pll_vco_related_control_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_pll_vco_related_control_1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.miireg_reg_uphy_pll_vco_temp_cmp = value; + ret = hppe_uniphy_pll_vco_related_control_1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_pll_vco_related_control_1_miireg_reg_uphy_pll_vco_amp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_pll_vco_related_control_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_pll_vco_related_control_1_get(dev_id, index, ®_val); + *value = reg_val.bf.miireg_reg_uphy_pll_vco_amp; + return ret; +} + +sw_error_t +hppe_uniphy_pll_vco_related_control_1_miireg_reg_uphy_pll_vco_amp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_pll_vco_related_control_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_pll_vco_related_control_1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.miireg_reg_uphy_pll_vco_amp = value; + ret = hppe_uniphy_pll_vco_related_control_1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_pll_vco_related_control_1_miireg_reg_uphy_pll_vco_gain_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_pll_vco_related_control_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_pll_vco_related_control_1_get(dev_id, index, ®_val); + *value = reg_val.bf.miireg_reg_uphy_pll_vco_gain; + return ret; +} + +sw_error_t +hppe_uniphy_pll_vco_related_control_1_miireg_reg_uphy_pll_vco_gain_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_pll_vco_related_control_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_pll_vco_related_control_1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.miireg_reg_uphy_pll_vco_gain = value; + ret = hppe_uniphy_pll_vco_related_control_1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_rx_afe_2_miireg_reg_uphy_rx_afe_res1_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_rx_afe_2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_rx_afe_2_get(dev_id, index, ®_val); + *value = reg_val.bf.miireg_reg_uphy_rx_afe_res1; + return ret; +} + +sw_error_t +hppe_uniphy_rx_afe_2_miireg_reg_uphy_rx_afe_res1_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_rx_afe_2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_rx_afe_2_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.miireg_reg_uphy_rx_afe_res1 = value; + ret = hppe_uniphy_rx_afe_2_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_rx_afe_2_miireg_reg_uphy_rx_afe_cap1_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_rx_afe_2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_rx_afe_2_get(dev_id, index, ®_val); + *value = reg_val.bf.miireg_reg_uphy_rx_afe_cap1; + return ret; +} + +sw_error_t +hppe_uniphy_rx_afe_2_miireg_reg_uphy_rx_afe_cap1_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_rx_afe_2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_rx_afe_2_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.miireg_reg_uphy_rx_afe_cap1 = value; + ret = hppe_uniphy_rx_afe_2_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_uniphy_rx_afe_2_miireg_reg_uphy_rx_rescal_code_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union uniphy_rx_afe_2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_rx_afe_2_get(dev_id, index, ®_val); + *value = reg_val.bf.miireg_reg_uphy_rx_rescal_code; + return ret; +} + +sw_error_t +hppe_uniphy_rx_afe_2_miireg_reg_uphy_rx_rescal_code_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union uniphy_rx_afe_2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_uniphy_rx_afe_2_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.miireg_reg_uphy_rx_rescal_code = value; + ret = hppe_uniphy_rx_afe_2_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_bandgap_ip_mbias_2_cmn_mmd1_reg_mbias_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union bandgap_ip_mbias_2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_bandgap_ip_mbias_2_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mmd1_reg_mbias_en; + return ret; +} + +sw_error_t +hppe_bandgap_ip_mbias_2_cmn_mmd1_reg_mbias_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union bandgap_ip_mbias_2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_bandgap_ip_mbias_2_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mmd1_reg_mbias_en = value; + ret = hppe_bandgap_ip_mbias_2_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_bandgap_ip_mbias_2_cmn_mmd1_reg_cmn_icc_rescode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union bandgap_ip_mbias_2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_bandgap_ip_mbias_2_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mmd1_reg_cmn_icc_rescode; + return ret; +} + +sw_error_t +hppe_bandgap_ip_mbias_2_cmn_mmd1_reg_cmn_icc_rescode_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union bandgap_ip_mbias_2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_bandgap_ip_mbias_2_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mmd1_reg_cmn_icc_rescode = value; + ret = hppe_bandgap_ip_mbias_2_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_bandgap_ip_mbias_2_cmn_mmd1_reg_cmn_bg_rsv_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union bandgap_ip_mbias_2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_bandgap_ip_mbias_2_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mmd1_reg_cmn_bg_rsv; + return ret; +} + +sw_error_t +hppe_bandgap_ip_mbias_2_cmn_mmd1_reg_cmn_bg_rsv_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union bandgap_ip_mbias_2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_bandgap_ip_mbias_2_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mmd1_reg_cmn_bg_rsv = value; + ret = hppe_bandgap_ip_mbias_2_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_ldo_ocp_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ldo_0p9v_related_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ldo_0p9v_related_1_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mmd1_reg_cmn_ldo_ocp_en; + return ret; +} + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_ldo_ocp_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ldo_0p9v_related_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ldo_0p9v_related_1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mmd1_reg_cmn_ldo_ocp_en = value; + ret = hppe_ldo_0p9v_related_1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_ldo_int_load_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ldo_0p9v_related_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ldo_0p9v_related_1_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mmd1_reg_cmn_ldo_int_load_en; + return ret; +} + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_ldo_int_load_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ldo_0p9v_related_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ldo_0p9v_related_1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mmd1_reg_cmn_ldo_int_load_en = value; + ret = hppe_ldo_0p9v_related_1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_ldo_int_res_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ldo_0p9v_related_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ldo_0p9v_related_1_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mmd1_reg_cmn_ldo_int_res_ctrl; + return ret; +} + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_ldo_int_res_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ldo_0p9v_related_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ldo_0p9v_related_1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mmd1_reg_cmn_ldo_int_res_ctrl = value; + ret = hppe_ldo_0p9v_related_1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_ldo_vout_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ldo_0p9v_related_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ldo_0p9v_related_1_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mmd1_reg_cmn_ldo_vout_ctrl; + return ret; +} + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_ldo_vout_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ldo_0p9v_related_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ldo_0p9v_related_1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mmd1_reg_cmn_ldo_vout_ctrl = value; + ret = hppe_ldo_0p9v_related_1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_ldo_ocp_current_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ldo_0p9v_related_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ldo_0p9v_related_1_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mmd1_reg_cmn_ldo_ocp_current_sel; + return ret; +} + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_ldo_ocp_current_sel_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ldo_0p9v_related_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ldo_0p9v_related_1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mmd1_reg_cmn_ldo_ocp_current_sel = value; + ret = hppe_ldo_0p9v_related_1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_vtt_ldo_biasgen_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ldo_0p9v_related_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ldo_0p9v_related_1_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mmd1_reg_cmn_vtt_ldo_biasgen_sel; + return ret; +} + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_vtt_ldo_biasgen_sel_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ldo_0p9v_related_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ldo_0p9v_related_1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mmd1_reg_cmn_vtt_ldo_biasgen_sel = value; + ret = hppe_ldo_0p9v_related_1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_ldo_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ldo_0p9v_related_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ldo_0p9v_related_1_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mmd1_reg_cmn_ldo_en; + return ret; +} + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_ldo_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ldo_0p9v_related_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ldo_0p9v_related_1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mmd1_reg_cmn_ldo_en = value; + ret = hppe_ldo_0p9v_related_1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_ldo_comp_current_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ldo_0p9v_related_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ldo_0p9v_related_1_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mmd1_reg_cmn_ldo_comp_current_en; + return ret; +} + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_ldo_comp_current_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ldo_0p9v_related_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ldo_0p9v_related_1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mmd1_reg_cmn_ldo_comp_current_en = value; + ret = hppe_ldo_0p9v_related_1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_ldo_bias_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union ldo_0p9v_related_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ldo_0p9v_related_1_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mmd1_reg_cmn_ldo_bias_ctrl; + return ret; +} + +sw_error_t +hppe_ldo_0p9v_related_1_cmn_mmd1_reg_cmn_ldo_bias_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union ldo_0p9v_related_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_ldo_0p9v_related_1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mmd1_reg_cmn_ldo_bias_ctrl = value; + ret = hppe_ldo_0p9v_related_1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_otp_vtt_ldo_related_cmn_mmd1_reg_cmn_ana_isolation_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union otp_vtt_ldo_related_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_otp_vtt_ldo_related_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mmd1_reg_cmn_ana_isolation; + return ret; +} + +sw_error_t +hppe_otp_vtt_ldo_related_cmn_mmd1_reg_cmn_ana_isolation_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union otp_vtt_ldo_related_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_otp_vtt_ldo_related_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mmd1_reg_cmn_ana_isolation = value; + ret = hppe_otp_vtt_ldo_related_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_otp_vtt_ldo_related_cmn_mmd1_reg_cmn_vtt_ldo_ocp_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union otp_vtt_ldo_related_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_otp_vtt_ldo_related_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mmd1_reg_cmn_vtt_ldo_ocp_en; + return ret; +} + +sw_error_t +hppe_otp_vtt_ldo_related_cmn_mmd1_reg_cmn_vtt_ldo_ocp_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union otp_vtt_ldo_related_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_otp_vtt_ldo_related_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mmd1_reg_cmn_vtt_ldo_ocp_en = value; + ret = hppe_otp_vtt_ldo_related_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_otp_vtt_ldo_related_cmn_mmd1_reg_cmn_vtt_ldo_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union otp_vtt_ldo_related_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_otp_vtt_ldo_related_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mmd1_reg_cmn_vtt_ldo_en; + return ret; +} + +sw_error_t +hppe_otp_vtt_ldo_related_cmn_mmd1_reg_cmn_vtt_ldo_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union otp_vtt_ldo_related_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_otp_vtt_ldo_related_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mmd1_reg_cmn_vtt_ldo_en = value; + ret = hppe_otp_vtt_ldo_related_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_otp_vtt_ldo_related_cmn_mmd1_reg_cmn_vtt_ldo_bias_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union otp_vtt_ldo_related_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_otp_vtt_ldo_related_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mmd1_reg_cmn_vtt_ldo_bias_ctrl; + return ret; +} + +sw_error_t +hppe_otp_vtt_ldo_related_cmn_mmd1_reg_cmn_vtt_ldo_bias_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union otp_vtt_ldo_related_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_otp_vtt_ldo_related_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mmd1_reg_cmn_vtt_ldo_bias_ctrl = value; + ret = hppe_otp_vtt_ldo_related_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_otp_vtt_ldo_related_cmn_mmd1_reg_cmn_vtt_ldo_rsv_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union otp_vtt_ldo_related_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_otp_vtt_ldo_related_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mmd1_reg_cmn_vtt_ldo_rsv; + return ret; +} + +sw_error_t +hppe_otp_vtt_ldo_related_cmn_mmd1_reg_cmn_vtt_ldo_rsv_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union otp_vtt_ldo_related_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_otp_vtt_ldo_related_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mmd1_reg_cmn_vtt_ldo_rsv = value; + ret = hppe_otp_vtt_ldo_related_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_otp_vtt_ldo_related_cmn_mmd1_reg_cmn_vtt_ldo_ocp_current_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union otp_vtt_ldo_related_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_otp_vtt_ldo_related_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mmd1_reg_cmn_vtt_ldo_ocp_current_sel; + return ret; +} + +sw_error_t +hppe_otp_vtt_ldo_related_cmn_mmd1_reg_cmn_vtt_ldo_ocp_current_sel_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union otp_vtt_ldo_related_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_otp_vtt_ldo_related_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mmd1_reg_cmn_vtt_ldo_ocp_current_sel = value; + ret = hppe_otp_vtt_ldo_related_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_otp_vtt_ldo_related_cmn_mmd1_reg_cmn_vtt_ldo_int_load_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union otp_vtt_ldo_related_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_otp_vtt_ldo_related_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mmd1_reg_cmn_vtt_ldo_int_load_ctrl; + return ret; +} + +sw_error_t +hppe_otp_vtt_ldo_related_cmn_mmd1_reg_cmn_vtt_ldo_int_load_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union otp_vtt_ldo_related_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_otp_vtt_ldo_related_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mmd1_reg_cmn_vtt_ldo_int_load_ctrl = value; + ret = hppe_otp_vtt_ldo_related_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_otp_temperature_compensate_1_cmn_mmd1_reg_uphy_ictat100u_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union otp_temperature_compensate_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_otp_temperature_compensate_1_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mmd1_reg_uphy_ictat100u_en; + return ret; +} + +sw_error_t +hppe_otp_temperature_compensate_1_cmn_mmd1_reg_uphy_ictat100u_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union otp_temperature_compensate_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_otp_temperature_compensate_1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mmd1_reg_uphy_ictat100u_en = value; + ret = hppe_otp_temperature_compensate_1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_otp_temperature_compensate_1_cmn_mmd1_reg_cmn_pll_ictat100u_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union otp_temperature_compensate_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_otp_temperature_compensate_1_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mmd1_reg_cmn_pll_ictat100u_en; + return ret; +} + +sw_error_t +hppe_otp_temperature_compensate_1_cmn_mmd1_reg_cmn_pll_ictat100u_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union otp_temperature_compensate_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_otp_temperature_compensate_1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mmd1_reg_cmn_pll_ictat100u_en = value; + ret = hppe_otp_temperature_compensate_1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_otp_temperature_compensate_1_cmn_mmd1_reg_uphy_ictat100u_ctrl1_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union otp_temperature_compensate_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_otp_temperature_compensate_1_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mmd1_reg_uphy_ictat100u_ctrl1; + return ret; +} + +sw_error_t +hppe_otp_temperature_compensate_1_cmn_mmd1_reg_uphy_ictat100u_ctrl1_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union otp_temperature_compensate_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_otp_temperature_compensate_1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mmd1_reg_uphy_ictat100u_ctrl1 = value; + ret = hppe_otp_temperature_compensate_1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_otp_temperature_compensate_1_cmn_mmd1_reg_uphy_ictat100u_ctrl2_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union otp_temperature_compensate_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_otp_temperature_compensate_1_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mmd1_reg_uphy_ictat100u_ctrl2; + return ret; +} + +sw_error_t +hppe_otp_temperature_compensate_1_cmn_mmd1_reg_uphy_ictat100u_ctrl2_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union otp_temperature_compensate_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_otp_temperature_compensate_1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mmd1_reg_uphy_ictat100u_ctrl2 = value; + ret = hppe_otp_temperature_compensate_1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_otp_temperature_compensate_1_cmn_mmd1_reg_uphy_ictat100u_ctrl0_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union otp_temperature_compensate_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_otp_temperature_compensate_1_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mmd1_reg_uphy_ictat100u_ctrl0; + return ret; +} + +sw_error_t +hppe_otp_temperature_compensate_1_cmn_mmd1_reg_uphy_ictat100u_ctrl0_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union otp_temperature_compensate_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_otp_temperature_compensate_1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mmd1_reg_uphy_ictat100u_ctrl0 = value; + ret = hppe_otp_temperature_compensate_1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pll_vco_related_control_1_cmn_mii_reg_reg_cmn_pll_vco_calib_ready_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pll_vco_related_control_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pll_vco_related_control_1_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mii_reg_reg_cmn_pll_vco_calib_ready; + return ret; +} + +sw_error_t +hppe_pll_vco_related_control_1_cmn_mii_reg_reg_cmn_pll_vco_calib_ready_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pll_vco_related_control_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pll_vco_related_control_1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mii_reg_reg_cmn_pll_vco_calib_ready = value; + ret = hppe_pll_vco_related_control_1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pll_vco_related_control_1_cmn_mii_reg_reg_cmn_pll_vco_temp_cmp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pll_vco_related_control_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pll_vco_related_control_1_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mii_reg_reg_cmn_pll_vco_temp_cmp; + return ret; +} + +sw_error_t +hppe_pll_vco_related_control_1_cmn_mii_reg_reg_cmn_pll_vco_temp_cmp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pll_vco_related_control_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pll_vco_related_control_1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mii_reg_reg_cmn_pll_vco_temp_cmp = value; + ret = hppe_pll_vco_related_control_1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pll_vco_related_control_1_cmn_mii_reg_cmn_pll_lckdt_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pll_vco_related_control_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pll_vco_related_control_1_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mii_reg_cmn_pll_lckdt_en; + return ret; +} + +sw_error_t +hppe_pll_vco_related_control_1_cmn_mii_reg_cmn_pll_lckdt_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pll_vco_related_control_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pll_vco_related_control_1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mii_reg_cmn_pll_lckdt_en = value; + ret = hppe_pll_vco_related_control_1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pll_vco_related_control_1_cmn_mii_reg_reg_cmn_pll_vco_amp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pll_vco_related_control_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pll_vco_related_control_1_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mii_reg_reg_cmn_pll_vco_amp; + return ret; +} + +sw_error_t +hppe_pll_vco_related_control_1_cmn_mii_reg_reg_cmn_pll_vco_amp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pll_vco_related_control_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pll_vco_related_control_1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mii_reg_reg_cmn_pll_vco_amp = value; + ret = hppe_pll_vco_related_control_1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pll_vco_related_control_1_cmn_mii_reg_autoload_sel_pll_vco_calib_ready_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pll_vco_related_control_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pll_vco_related_control_1_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mii_reg_autoload_sel_pll_vco_calib_ready; + return ret; +} + +sw_error_t +hppe_pll_vco_related_control_1_cmn_mii_reg_autoload_sel_pll_vco_calib_ready_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pll_vco_related_control_1_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pll_vco_related_control_1_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mii_reg_autoload_sel_pll_vco_calib_ready = value; + ret = hppe_pll_vco_related_control_1_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pll_control_vco_related_selection_2_cmn_mmd1_reg_src_cmn_pll_vco_calib_ready_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pll_control_vco_related_selection_2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pll_control_vco_related_selection_2_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mmd1_reg_src_cmn_pll_vco_calib_ready; + return ret; +} + +sw_error_t +hppe_pll_control_vco_related_selection_2_cmn_mmd1_reg_src_cmn_pll_vco_calib_ready_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pll_control_vco_related_selection_2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pll_control_vco_related_selection_2_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mmd1_reg_src_cmn_pll_vco_calib_ready = value; + ret = hppe_pll_control_vco_related_selection_2_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pll_control_vco_related_selection_2_cmn_mmd1_reg_src_cmn_pll_vco_temp_cmp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pll_control_vco_related_selection_2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pll_control_vco_related_selection_2_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mmd1_reg_src_cmn_pll_vco_temp_cmp; + return ret; +} + +sw_error_t +hppe_pll_control_vco_related_selection_2_cmn_mmd1_reg_src_cmn_pll_vco_temp_cmp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pll_control_vco_related_selection_2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pll_control_vco_related_selection_2_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mmd1_reg_src_cmn_pll_vco_temp_cmp = value; + ret = hppe_pll_control_vco_related_selection_2_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pll_control_vco_related_selection_2_cmn_mmd1_reg_src_cmn_pll_vco_amp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pll_control_vco_related_selection_2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pll_control_vco_related_selection_2_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mmd1_reg_src_cmn_pll_vco_amp; + return ret; +} + +sw_error_t +hppe_pll_control_vco_related_selection_2_cmn_mmd1_reg_src_cmn_pll_vco_amp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pll_control_vco_related_selection_2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pll_control_vco_related_selection_2_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mmd1_reg_src_cmn_pll_vco_amp = value; + ret = hppe_pll_control_vco_related_selection_2_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pll_control_vco_related_selection_2_cmn_mmd1_reg_src_cmn_pll_vco_calib_start_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pll_control_vco_related_selection_2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pll_control_vco_related_selection_2_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mmd1_reg_src_cmn_pll_vco_calib_start; + return ret; +} + +sw_error_t +hppe_pll_control_vco_related_selection_2_cmn_mmd1_reg_src_cmn_pll_vco_calib_start_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pll_control_vco_related_selection_2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pll_control_vco_related_selection_2_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mmd1_reg_src_cmn_pll_vco_calib_start = value; + ret = hppe_pll_control_vco_related_selection_2_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pll_control_vco_related_selection_2_cmn_mmd1_reg_src_cmn_pll_vco_calib_code_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pll_control_vco_related_selection_2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pll_control_vco_related_selection_2_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mmd1_reg_src_cmn_pll_vco_calib_code; + return ret; +} + +sw_error_t +hppe_pll_control_vco_related_selection_2_cmn_mmd1_reg_src_cmn_pll_vco_calib_code_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pll_control_vco_related_selection_2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pll_control_vco_related_selection_2_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mmd1_reg_src_cmn_pll_vco_calib_code = value; + ret = hppe_pll_control_vco_related_selection_2_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pll_control_vco_related_selection_2_cmn_mmd1_reg_src_cmn_pll_fbclk_div_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pll_control_vco_related_selection_2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pll_control_vco_related_selection_2_get(dev_id, index, ®_val); + *value = reg_val.bf.cmn_mmd1_reg_src_cmn_pll_fbclk_div; + return ret; +} + +sw_error_t +hppe_pll_control_vco_related_selection_2_cmn_mmd1_reg_src_cmn_pll_fbclk_div_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pll_control_vco_related_selection_2_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pll_control_vco_related_selection_2_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cmn_mmd1_reg_src_cmn_pll_fbclk_div = value; + ret = hppe_pll_control_vco_related_selection_2_set(dev_id, index, ®_val); + return ret; +} +#endif + +sw_error_t +hppe_uniphy_phy_mode_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_misc2_phy_mode_u *value) +{ + if (index >= UNIPHY_MISC2_PHY_MODE_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_uniphy_reg_get( + dev_id, + NSS_UNIPHY_BASE_ADDR + UNIPHY_MISC2_PHY_MODE_ADDRESS, + index * UNIPHY_MISC2_PHY_MODE_INC, + &value->val); +} + +sw_error_t +hppe_uniphy_phy_mode_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_misc2_phy_mode_u *value) +{ + if (index >= UNIPHY_MISC2_PHY_MODE_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_uniphy_reg_set( + dev_id, + NSS_UNIPHY_BASE_ADDR + UNIPHY_MISC2_PHY_MODE_ADDRESS, + index * UNIPHY_MISC2_PHY_MODE_INC, + value->val); +} + +sw_error_t +hppe_uniphy_pll_reset_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union pll_power_on_and_reset_u *value) +{ + if (index >= UNIPHY_PLL_POWER_ON_AND_RESET_INC_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_uniphy_reg_get( + dev_id, + NSS_UNIPHY_BASE_ADDR + PLL_POWER_ON_AND_RESET_ADDRESS, + index * PLL_POWER_ON_AND_RESET_INC, + &value->val); +} + +sw_error_t +hppe_uniphy_pll_reset_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union pll_power_on_and_reset_u *value) +{ + if (index >= UNIPHY_PLL_POWER_ON_AND_RESET_INC_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_uniphy_reg_set( + dev_id, + NSS_UNIPHY_BASE_ADDR + PLL_POWER_ON_AND_RESET_ADDRESS, + index * PLL_POWER_ON_AND_RESET_INC, + value->val); +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_vsi.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_vsi.c new file mode 100755 index 000000000..25d1d908b --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_vsi.c @@ -0,0 +1,650 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hppe_reg_access.h" +#include "hppe_vsi_reg.h" +#include "hppe_vsi.h" + +sw_error_t +hppe_vsi_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union vsi_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + IPE_L2_BASE_ADDR + VSI_TBL_ADDRESS + \ + index * VSI_TBL_INC, + value->val, + 2); +} + +sw_error_t +hppe_vsi_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union vsi_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + IPE_L2_BASE_ADDR + VSI_TBL_ADDRESS + \ + index * VSI_TBL_INC, + value->val, + 2); +} + +#ifndef IN_VSI_MINI +sw_error_t +hppe_vsi_tbl_umc_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vsi_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vsi_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.umc_bitmap; + return ret; +} + +sw_error_t +hppe_vsi_tbl_umc_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vsi_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vsi_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.umc_bitmap = value; + ret = hppe_vsi_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vsi_tbl_station_move_lrn_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vsi_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vsi_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.station_move_lrn_en; + return ret; +} + +sw_error_t +hppe_vsi_tbl_station_move_lrn_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vsi_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vsi_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.station_move_lrn_en = value; + ret = hppe_vsi_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vsi_tbl_new_addr_fwd_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vsi_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vsi_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.new_addr_fwd_cmd; + return ret; +} + +sw_error_t +hppe_vsi_tbl_new_addr_fwd_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vsi_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vsi_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.new_addr_fwd_cmd = value; + ret = hppe_vsi_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vsi_tbl_uuc_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vsi_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vsi_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.uuc_bitmap; + return ret; +} + +sw_error_t +hppe_vsi_tbl_uuc_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vsi_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vsi_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.uuc_bitmap = value; + ret = hppe_vsi_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vsi_tbl_member_port_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vsi_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vsi_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.member_port_bitmap; + return ret; +} + +sw_error_t +hppe_vsi_tbl_member_port_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vsi_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vsi_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.member_port_bitmap = value; + ret = hppe_vsi_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vsi_tbl_new_addr_lrn_en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vsi_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vsi_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.new_addr_lrn_en; + return ret; +} + +sw_error_t +hppe_vsi_tbl_new_addr_lrn_en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vsi_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vsi_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.new_addr_lrn_en = value; + ret = hppe_vsi_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vsi_tbl_bc_bitmap_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vsi_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vsi_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.bc_bitmap; + return ret; +} + +sw_error_t +hppe_vsi_tbl_bc_bitmap_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vsi_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vsi_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.bc_bitmap = value; + ret = hppe_vsi_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vsi_tbl_station_move_fwd_cmd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vsi_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vsi_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.station_move_fwd_cmd; + return ret; +} + +sw_error_t +hppe_vsi_tbl_station_move_fwd_cmd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vsi_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vsi_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.station_move_fwd_cmd = value; + ret = hppe_vsi_tbl_set(dev_id, index, ®_val); + return ret; +} +#endif + +sw_error_t +hppe_vlan_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union vlan_cnt_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + INGRESS_POLICER_BASE_ADDR + VLAN_CNT_TBL_ADDRESS + \ + index * VLAN_CNT_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_vlan_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union vlan_cnt_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + INGRESS_POLICER_BASE_ADDR + VLAN_CNT_TBL_ADDRESS + \ + index * VLAN_CNT_TBL_INC, + value->val, + 3); +} + +#ifndef IN_VSI_MINI +sw_error_t +hppe_vlan_cnt_tbl_rx_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union vlan_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vlan_cnt_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.rx_byte_cnt_1 << 32 | \ + reg_val.bf.rx_byte_cnt_0; + return ret; +} + +sw_error_t +hppe_vlan_cnt_tbl_rx_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union vlan_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vlan_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_byte_cnt_1 = value >> 32; + reg_val.bf.rx_byte_cnt_0 = value & (((a_uint64_t)1<<32)-1); + ret = hppe_vlan_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_vlan_cnt_tbl_rx_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union vlan_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vlan_cnt_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.rx_pkt_cnt; + return ret; +} + +sw_error_t +hppe_vlan_cnt_tbl_rx_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union vlan_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_vlan_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_pkt_cnt = value; + ret = hppe_vlan_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} +#endif + + +sw_error_t +hppe_eg_vsi_counter_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union eg_vsi_counter_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + NSS_PTX_CSR_BASE_ADDR + EG_VSI_COUNTER_TBL_ADDRESS + \ + index * EG_VSI_COUNTER_TBL_INC, + value->val, + 3); +} + +sw_error_t +hppe_eg_vsi_counter_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union eg_vsi_counter_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + NSS_PTX_CSR_BASE_ADDR + EG_VSI_COUNTER_TBL_ADDRESS + \ + index * EG_VSI_COUNTER_TBL_INC, + value->val, + 3); +} + +#ifndef IN_VSI_MINI +sw_error_t +hppe_eg_vsi_counter_tbl_tx_bytes_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union eg_vsi_counter_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vsi_counter_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.tx_bytes_1 << 32 | \ + reg_val.bf.tx_bytes_0; + return ret; +} + +sw_error_t +hppe_eg_vsi_counter_tbl_tx_bytes_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union eg_vsi_counter_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vsi_counter_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_bytes_1 = value >> 32; + reg_val.bf.tx_bytes_0 = value & (((a_uint64_t)1<<32)-1); + ret = hppe_eg_vsi_counter_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_eg_vsi_counter_tbl_tx_packets_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union eg_vsi_counter_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vsi_counter_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_packets; + return ret; +} + +sw_error_t +hppe_eg_vsi_counter_tbl_tx_packets_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union eg_vsi_counter_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_eg_vsi_counter_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_packets = value; + ret = hppe_eg_vsi_counter_tbl_set(dev_id, index, ®_val); + return ret; +} +#endif + +sw_error_t +hppe_pre_l2_cnt_tbl_get( + a_uint32_t dev_id, + a_uint32_t index, + union pre_l2_cnt_tbl_u *value) +{ + return hppe_reg_tbl_get( + dev_id, + INGRESS_POLICER_BASE_ADDR + PRE_L2_CNT_TBL_ADDRESS + \ + index * PRE_L2_CNT_TBL_INC, + value->val, + 5); +} + +sw_error_t +hppe_pre_l2_cnt_tbl_set( + a_uint32_t dev_id, + a_uint32_t index, + union pre_l2_cnt_tbl_u *value) +{ + return hppe_reg_tbl_set( + dev_id, + INGRESS_POLICER_BASE_ADDR + PRE_L2_CNT_TBL_ADDRESS + \ + index * PRE_L2_CNT_TBL_INC, + value->val, + 5); +} +#ifndef IN_VSI_MINI +sw_error_t +hppe_pre_l2_cnt_tbl_rx_drop_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union pre_l2_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pre_l2_cnt_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.rx_drop_byte_cnt_1 << 24 | \ + reg_val.bf.rx_drop_byte_cnt_0; + return ret; +} + +sw_error_t +hppe_pre_l2_cnt_tbl_rx_drop_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union pre_l2_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pre_l2_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_drop_byte_cnt_1 = value >> 24; + reg_val.bf.rx_drop_byte_cnt_0 = value & (((a_uint64_t)1<<24)-1); + ret = hppe_pre_l2_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pre_l2_cnt_tbl_rx_byte_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t *value) +{ + union pre_l2_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pre_l2_cnt_tbl_get(dev_id, index, ®_val); + *value = (a_uint64_t)reg_val.bf.rx_byte_cnt_1 << 32 | \ + reg_val.bf.rx_byte_cnt_0; + return ret; +} + +sw_error_t +hppe_pre_l2_cnt_tbl_rx_byte_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint64_t value) +{ + union pre_l2_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pre_l2_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_byte_cnt_1 = value >> 32; + reg_val.bf.rx_byte_cnt_0 = value & (((a_uint64_t)1<<32)-1); + ret = hppe_pre_l2_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pre_l2_cnt_tbl_rx_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pre_l2_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pre_l2_cnt_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.rx_pkt_cnt; + return ret; +} + +sw_error_t +hppe_pre_l2_cnt_tbl_rx_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pre_l2_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pre_l2_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_pkt_cnt = value; + ret = hppe_pre_l2_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_pre_l2_cnt_tbl_rx_drop_pkt_cnt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union pre_l2_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pre_l2_cnt_tbl_get(dev_id, index, ®_val); + *value = reg_val.bf.rx_drop_pkt_cnt_1 << 24 | \ + reg_val.bf.rx_drop_pkt_cnt_0; + return ret; +} + +sw_error_t +hppe_pre_l2_cnt_tbl_rx_drop_pkt_cnt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union pre_l2_cnt_tbl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_pre_l2_cnt_tbl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_drop_pkt_cnt_1 = value >> 24; + reg_val.bf.rx_drop_pkt_cnt_0 = value & (((a_uint64_t)1<<24)-1); + ret = hppe_pre_l2_cnt_tbl_set(dev_id, index, ®_val); + return ret; +} +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_xgmacmib.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_xgmacmib.c new file mode 100755 index 000000000..aee2f49fd --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_xgmacmib.c @@ -0,0 +1,4210 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hppe_reg_access.h" +#include "hppe_xgmacmib_reg.h" +#include "hppe_xgmacmib.h" + + +sw_error_t +hppe_mmc_control_get( + a_uint32_t dev_id, + a_uint32_t index, + union mmc_control_u *value) +{ + if (index >= MMC_CONTROL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MMC_CONTROL_ADDRESS + \ + index * MMC_CONTROL_INC, + &value->val); +} + +sw_error_t +hppe_mmc_control_set( + a_uint32_t dev_id, + a_uint32_t index, + union mmc_control_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MMC_CONTROL_ADDRESS + \ + index * MMC_CONTROL_INC, + value->val); +} + +sw_error_t +hppe_tx_octet_count_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_octet_count_good_bad_low_u *value) +{ + if (index >= TX_OCTET_COUNT_GOOD_BAD_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_OCTET_COUNT_GOOD_BAD_LOW_ADDRESS + \ + index * TX_OCTET_COUNT_GOOD_BAD_LOW_INC, + &value->val); +} + +sw_error_t +hppe_tx_octet_count_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_octet_count_good_bad_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_octet_count_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_octet_count_good_bad_high_u *value) +{ + if (index >= TX_OCTET_COUNT_GOOD_BAD_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_OCTET_COUNT_GOOD_BAD_HIGH_ADDRESS + \ + index * TX_OCTET_COUNT_GOOD_BAD_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_tx_octet_count_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_octet_count_good_bad_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_frame_count_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_frame_count_good_bad_low_u *value) +{ + if (index >= TX_FRAME_COUNT_GOOD_BAD_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_FRAME_COUNT_GOOD_BAD_LOW_ADDRESS + \ + index * TX_FRAME_COUNT_GOOD_BAD_LOW_INC, + &value->val); +} + +sw_error_t +hppe_tx_frame_count_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_frame_count_good_bad_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_frame_count_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_frame_count_good_bad_high_u *value) +{ + if (index >= TX_FRAME_COUNT_GOOD_BAD_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_FRAME_COUNT_GOOD_BAD_HIGH_ADDRESS + \ + index * TX_FRAME_COUNT_GOOD_BAD_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_tx_frame_count_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_frame_count_good_bad_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_broadcast_frames_good_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_broadcast_frames_good_low_u *value) +{ + if (index >= TX_BROADCAST_FRAMES_GOOD_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_BROADCAST_FRAMES_GOOD_LOW_ADDRESS + \ + index * TX_BROADCAST_FRAMES_GOOD_LOW_INC, + &value->val); +} + +sw_error_t +hppe_tx_broadcast_frames_good_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_broadcast_frames_good_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_broadcast_frames_good_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_broadcast_frames_good_high_u *value) +{ + if (index >= TX_BROADCAST_FRAMES_GOOD_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_BROADCAST_FRAMES_GOOD_HIGH_ADDRESS + \ + index * TX_BROADCAST_FRAMES_GOOD_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_tx_broadcast_frames_good_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_broadcast_frames_good_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_multicast_frames_good_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_multicast_frames_good_low_u *value) +{ + if (index >= TX_MULTICAST_FRAMES_GOOD_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_MULTICAST_FRAMES_GOOD_LOW_ADDRESS + \ + index * TX_MULTICAST_FRAMES_GOOD_LOW_INC, + &value->val); +} + +sw_error_t +hppe_tx_multicast_frames_good_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_multicast_frames_good_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_multicast_frames_good_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_multicast_frames_good_high_u *value) +{ + if (index >= TX_MULTICAST_FRAMES_GOOD_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_MULTICAST_FRAMES_GOOD_HIGH_ADDRESS + \ + index * TX_MULTICAST_FRAMES_GOOD_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_tx_multicast_frames_good_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_multicast_frames_good_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_64octets_frames_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_64octets_frames_good_bad_low_u *value) +{ + if (index >= TX_64OCTETS_FRAMES_GOOD_BAD_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_64OCTETS_FRAMES_GOOD_BAD_LOW_ADDRESS + \ + index * TX_64OCTETS_FRAMES_GOOD_BAD_LOW_INC, + &value->val); +} + +sw_error_t +hppe_tx_64octets_frames_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_64octets_frames_good_bad_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_64octets_frames_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_64octets_frames_good_bad_high_u *value) +{ + if (index >= TX_64OCTETS_FRAMES_GOOD_BAD_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_64OCTETS_FRAMES_GOOD_BAD_HIGH_ADDRESS + \ + index * TX_64OCTETS_FRAMES_GOOD_BAD_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_tx_64octets_frames_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_64octets_frames_good_bad_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_65to127octets_frames_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_65to127octets_frames_good_bad_low_u *value) +{ + if (index >= TX_65TO127OCTETS_FRAMES_GOOD_BAD_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_65TO127OCTETS_FRAMES_GOOD_BAD_LOW_ADDRESS + \ + index * TX_65TO127OCTETS_FRAMES_GOOD_BAD_LOW_INC, + &value->val); +} + +sw_error_t +hppe_tx_65to127octets_frames_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_65to127octets_frames_good_bad_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_65to127octets_frames_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_65to127octets_frames_good_bad_high_u *value) +{ + if (index >= TX_65TO127OCTETS_FRAMES_GOOD_BAD_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_65TO127OCTETS_FRAMES_GOOD_BAD_HIGH_ADDRESS + \ + index * TX_65TO127OCTETS_FRAMES_GOOD_BAD_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_tx_65to127octets_frames_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_65to127octets_frames_good_bad_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_128to255octets_frames_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_128to255octets_frames_good_bad_low_u *value) +{ + if (index >= TX_128TO255OCTETS_FRAMES_GOOD_BAD_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_128TO255OCTETS_FRAMES_GOOD_BAD_LOW_ADDRESS + \ + index * TX_128TO255OCTETS_FRAMES_GOOD_BAD_LOW_INC, + &value->val); +} + +sw_error_t +hppe_tx_128to255octets_frames_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_128to255octets_frames_good_bad_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_128to255octets_frames_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_128to255octets_frames_good_bad_high_u *value) +{ + if (index >= TX_128TO255OCTETS_FRAMES_GOOD_BAD_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_128TO255OCTETS_FRAMES_GOOD_BAD_HIGH_ADDRESS + \ + index * TX_128TO255OCTETS_FRAMES_GOOD_BAD_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_tx_128to255octets_frames_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_128to255octets_frames_good_bad_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_256to511octets_frames_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_256to511octets_frames_good_bad_low_u *value) +{ + if (index >= TX_256TO511OCTETS_FRAMES_GOOD_BAD_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_256TO511OCTETS_FRAMES_GOOD_BAD_LOW_ADDRESS + \ + index * TX_256TO511OCTETS_FRAMES_GOOD_BAD_LOW_INC, + &value->val); +} + +sw_error_t +hppe_tx_256to511octets_frames_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_256to511octets_frames_good_bad_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_256to511octets_frames_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_256to511octets_frames_good_bad_high_u *value) +{ + if (index >= TX_256TO511OCTETS_FRAMES_GOOD_BAD_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_256TO511OCTETS_FRAMES_GOOD_BAD_HIGH_ADDRESS + \ + index * TX_256TO511OCTETS_FRAMES_GOOD_BAD_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_tx_256to511octets_frames_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_256to511octets_frames_good_bad_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_512to1023octets_frames_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_512to1023octets_frames_good_bad_low_u *value) +{ + if (index >= TX_512TO1023OCTETS_FRAMES_GOOD_BAD_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_512TO1023OCTETS_FRAMES_GOOD_BAD_LOW_ADDRESS + \ + index * TX_512TO1023OCTETS_FRAMES_GOOD_BAD_LOW_INC, + &value->val); +} + +sw_error_t +hppe_tx_512to1023octets_frames_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_512to1023octets_frames_good_bad_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_512to1023octets_frames_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_512to1023octets_frames_good_bad_high_u *value) +{ + if (index >= TX_512TO1023OCTETS_FRAMES_GOOD_BAD_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_512TO1023OCTETS_FRAMES_GOOD_BAD_HIGH_ADDRESS + \ + index * TX_512TO1023OCTETS_FRAMES_GOOD_BAD_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_tx_512to1023octets_frames_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_512to1023octets_frames_good_bad_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_1024tomaxoctets_frames_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_1024tomaxoctets_frames_good_bad_low_u *value) +{ + if (index >= TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_LOW_ADDRESS + \ + index * TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_LOW_INC, + &value->val); +} + +sw_error_t +hppe_tx_1024tomaxoctets_frames_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_1024tomaxoctets_frames_good_bad_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_1024tomaxoctets_frames_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_1024tomaxoctets_frames_good_bad_high_u *value) +{ + if (index >= TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_HIGH_ADDRESS + \ + index * TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_tx_1024tomaxoctets_frames_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_1024tomaxoctets_frames_good_bad_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_unicast_frames_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_unicast_frames_good_bad_low_u *value) +{ + if (index >= TX_UNICAST_FRAMES_GOOD_BAD_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_UNICAST_FRAMES_GOOD_BAD_LOW_ADDRESS + \ + index * TX_UNICAST_FRAMES_GOOD_BAD_LOW_INC, + &value->val); +} + +sw_error_t +hppe_tx_unicast_frames_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_unicast_frames_good_bad_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_unicast_frames_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_unicast_frames_good_bad_high_u *value) +{ + if (index >= TX_UNICAST_FRAMES_GOOD_BAD_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_UNICAST_FRAMES_GOOD_BAD_HIGH_ADDRESS + \ + index * TX_UNICAST_FRAMES_GOOD_BAD_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_tx_unicast_frames_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_unicast_frames_good_bad_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_multicast_frames_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_multicast_frames_good_bad_low_u *value) +{ + if (index >= TX_MULTICAST_FRAMES_GOOD_BAD_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_MULTICAST_FRAMES_GOOD_BAD_LOW_ADDRESS + \ + index * TX_MULTICAST_FRAMES_GOOD_BAD_LOW_INC, + &value->val); +} + +sw_error_t +hppe_tx_multicast_frames_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_multicast_frames_good_bad_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_multicast_frames_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_multicast_frames_good_bad_high_u *value) +{ + if (index >= TX_MULTICAST_FRAMES_GOOD_BAD_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_MULTICAST_FRAMES_GOOD_BAD_HIGH_ADDRESS + \ + index * TX_MULTICAST_FRAMES_GOOD_BAD_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_tx_multicast_frames_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_multicast_frames_good_bad_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_broadcast_frames_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_broadcast_frames_good_bad_low_u *value) +{ + if (index >= TX_BROADCAST_FRAMES_GOOD_BAD_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_BROADCAST_FRAMES_GOOD_BAD_LOW_ADDRESS + \ + index * TX_BROADCAST_FRAMES_GOOD_BAD_LOW_INC, + &value->val); +} + +sw_error_t +hppe_tx_broadcast_frames_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_broadcast_frames_good_bad_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_broadcast_frames_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_broadcast_frames_good_bad_high_u *value) +{ + if (index >= TX_BROADCAST_FRAMES_GOOD_BAD_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_BROADCAST_FRAMES_GOOD_BAD_HIGH_ADDRESS + \ + index * TX_BROADCAST_FRAMES_GOOD_BAD_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_tx_broadcast_frames_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_broadcast_frames_good_bad_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_underflow_error_frames_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_underflow_error_frames_low_u *value) +{ + if (index >= TX_UNDERFLOW_ERROR_FRAMES_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_UNDERFLOW_ERROR_FRAMES_LOW_ADDRESS + \ + index * TX_UNDERFLOW_ERROR_FRAMES_LOW_INC, + &value->val); +} + +sw_error_t +hppe_tx_underflow_error_frames_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_underflow_error_frames_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_underflow_error_frames_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_underflow_error_frames_high_u *value) +{ + if (index >= TX_UNDERFLOW_ERROR_FRAMES_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_UNDERFLOW_ERROR_FRAMES_HIGH_ADDRESS + \ + index * TX_UNDERFLOW_ERROR_FRAMES_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_tx_underflow_error_frames_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_underflow_error_frames_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_octet_count_good_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_octet_count_good_low_u *value) +{ + if (index >= TX_OCTET_COUNT_GOOD_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_OCTET_COUNT_GOOD_LOW_ADDRESS + \ + index * TX_OCTET_COUNT_GOOD_LOW_INC, + &value->val); +} + +sw_error_t +hppe_tx_octet_count_good_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_octet_count_good_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_octet_count_good_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_octet_count_good_high_u *value) +{ + if (index >= TX_OCTET_COUNT_GOOD_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_OCTET_COUNT_GOOD_HIGH_ADDRESS + \ + index * TX_OCTET_COUNT_GOOD_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_tx_octet_count_good_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_octet_count_good_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_frame_count_good_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_frame_count_good_low_u *value) +{ + if (index >= TX_FRAME_COUNT_GOOD_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_FRAME_COUNT_GOOD_LOW_ADDRESS + \ + index * TX_FRAME_COUNT_GOOD_LOW_INC, + &value->val); +} + +sw_error_t +hppe_tx_frame_count_good_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_frame_count_good_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_frame_count_good_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_frame_count_good_high_u *value) +{ + if (index >= TX_FRAME_COUNT_GOOD_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_FRAME_COUNT_GOOD_HIGH_ADDRESS + \ + index * TX_FRAME_COUNT_GOOD_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_tx_frame_count_good_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_frame_count_good_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_pause_frames_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_pause_frames_low_u *value) +{ + if (index >= TX_PAUSE_FRAMES_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_PAUSE_FRAMES_LOW_ADDRESS + \ + index * TX_PAUSE_FRAMES_LOW_INC, + &value->val); +} + +sw_error_t +hppe_tx_pause_frames_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_pause_frames_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_pause_frames_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_pause_frames_high_u *value) +{ + if (index >= TX_PAUSE_FRAMES_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_PAUSE_FRAMES_HIGH_ADDRESS + \ + index * TX_PAUSE_FRAMES_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_tx_pause_frames_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_pause_frames_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_vlan_frames_good_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_vlan_frames_good_low_u *value) +{ + if (index >= TX_VLAN_FRAMES_GOOD_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_VLAN_FRAMES_GOOD_LOW_ADDRESS + \ + index * TX_VLAN_FRAMES_GOOD_LOW_INC, + &value->val); +} + +sw_error_t +hppe_tx_vlan_frames_good_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_vlan_frames_good_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_vlan_frames_good_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_vlan_frames_good_high_u *value) +{ + if (index >= TX_VLAN_FRAMES_GOOD_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_VLAN_FRAMES_GOOD_HIGH_ADDRESS + \ + index * TX_VLAN_FRAMES_GOOD_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_tx_vlan_frames_good_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_vlan_frames_good_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_lpi_usec_cntr_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_lpi_usec_cntr_u *value) +{ + if (index >= TX_LPI_USEC_CNTR_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_LPI_USEC_CNTR_ADDRESS + \ + index * TX_LPI_USEC_CNTR_INC, + &value->val); +} + +sw_error_t +hppe_tx_lpi_usec_cntr_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_lpi_usec_cntr_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_lpi_tran_cntr_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_lpi_tran_cntr_u *value) +{ + if (index >= TX_LPI_TRAN_CNTR_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + TX_LPI_TRAN_CNTR_ADDRESS + \ + index * TX_LPI_TRAN_CNTR_INC, + &value->val); +} + +sw_error_t +hppe_tx_lpi_tran_cntr_set( + a_uint32_t dev_id, + a_uint32_t index, + union tx_lpi_tran_cntr_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_frame_count_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_frame_count_good_bad_low_u *value) +{ + if (index >= RX_FRAME_COUNT_GOOD_BAD_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_FRAME_COUNT_GOOD_BAD_LOW_ADDRESS + \ + index * RX_FRAME_COUNT_GOOD_BAD_LOW_INC, + &value->val); +} + +sw_error_t +hppe_rx_frame_count_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_frame_count_good_bad_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_frame_count_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_frame_count_good_bad_high_u *value) +{ + if (index >= RX_FRAME_COUNT_GOOD_BAD_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_FRAME_COUNT_GOOD_BAD_HIGH_ADDRESS + \ + index * RX_FRAME_COUNT_GOOD_BAD_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_rx_frame_count_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_frame_count_good_bad_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_octet_count_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_octet_count_good_bad_low_u *value) +{ + if (index >= RX_OCTET_COUNT_GOOD_BAD_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_OCTET_COUNT_GOOD_BAD_LOW_ADDRESS + \ + index * RX_OCTET_COUNT_GOOD_BAD_LOW_INC, + &value->val); +} + +sw_error_t +hppe_rx_octet_count_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_octet_count_good_bad_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_octet_count_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_octet_count_good_bad_high_u *value) +{ + if (index >= RX_OCTET_COUNT_GOOD_BAD_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_OCTET_COUNT_GOOD_BAD_HIGH_ADDRESS + \ + index * RX_OCTET_COUNT_GOOD_BAD_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_rx_octet_count_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_octet_count_good_bad_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_octet_count_good_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_octet_count_good_low_u *value) +{ + if (index >= RX_OCTET_COUNT_GOOD_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_OCTET_COUNT_GOOD_LOW_ADDRESS + \ + index * RX_OCTET_COUNT_GOOD_LOW_INC, + &value->val); +} + +sw_error_t +hppe_rx_octet_count_good_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_octet_count_good_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_octet_count_good_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_octet_count_good_high_u *value) +{ + if (index >= RX_OCTET_COUNT_GOOD_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_OCTET_COUNT_GOOD_HIGH_ADDRESS + \ + index * RX_OCTET_COUNT_GOOD_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_rx_octet_count_good_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_octet_count_good_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_broadcast_frames_good_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_broadcast_frames_good_low_u *value) +{ + if (index >= RX_BROADCAST_FRAMES_GOOD_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_BROADCAST_FRAMES_GOOD_LOW_ADDRESS + \ + index * RX_BROADCAST_FRAMES_GOOD_LOW_INC, + &value->val); +} + +sw_error_t +hppe_rx_broadcast_frames_good_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_broadcast_frames_good_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_broadcast_frames_good_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_broadcast_frames_good_high_u *value) +{ + if (index >= RX_BROADCAST_FRAMES_GOOD_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_BROADCAST_FRAMES_GOOD_HIGH_ADDRESS + \ + index * RX_BROADCAST_FRAMES_GOOD_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_rx_broadcast_frames_good_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_broadcast_frames_good_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_multicast_frames_good_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_multicast_frames_good_low_u *value) +{ + if (index >= RX_MULTICAST_FRAMES_GOOD_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_MULTICAST_FRAMES_GOOD_LOW_ADDRESS + \ + index * RX_MULTICAST_FRAMES_GOOD_LOW_INC, + &value->val); +} + +sw_error_t +hppe_rx_multicast_frames_good_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_multicast_frames_good_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_multicast_frames_good_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_multicast_frames_good_high_u *value) +{ + if (index >= RX_MULTICAST_FRAMES_GOOD_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_MULTICAST_FRAMES_GOOD_HIGH_ADDRESS + \ + index * RX_MULTICAST_FRAMES_GOOD_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_rx_multicast_frames_good_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_multicast_frames_good_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_crc_error_frames_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_crc_error_frames_low_u *value) +{ + if (index >= RX_CRC_ERROR_FRAMES_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_CRC_ERROR_FRAMES_LOW_ADDRESS + \ + index * RX_CRC_ERROR_FRAMES_LOW_INC, + &value->val); +} + +sw_error_t +hppe_rx_crc_error_frames_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_crc_error_frames_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_crc_error_frames_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_crc_error_frames_high_u *value) +{ + if (index >= RX_CRC_ERROR_FRAMES_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_CRC_ERROR_FRAMES_HIGH_ADDRESS + \ + index * RX_CRC_ERROR_FRAMES_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_rx_crc_error_frames_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_crc_error_frames_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_runt_error_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_runt_error_frames_u *value) +{ + if (index >= RX_RUNT_ERROR_FRAMES_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_RUNT_ERROR_FRAMES_ADDRESS + \ + index * RX_RUNT_ERROR_FRAMES_INC, + &value->val); +} + +sw_error_t +hppe_rx_runt_error_frames_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_runt_error_frames_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_jabber_error_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_jabber_error_frames_u *value) +{ + if (index >= RX_JABBER_ERROR_FRAMES_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_JABBER_ERROR_FRAMES_ADDRESS + \ + index * RX_JABBER_ERROR_FRAMES_INC, + &value->val); +} + +sw_error_t +hppe_rx_jabber_error_frames_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_jabber_error_frames_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_undersize_frames_good_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_undersize_frames_good_u *value) +{ + if (index >= RX_UNDERSIZE_FRAMES_GOOD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_UNDERSIZE_FRAMES_GOOD_ADDRESS + \ + index * RX_UNDERSIZE_FRAMES_GOOD_INC, + &value->val); +} + +sw_error_t +hppe_rx_undersize_frames_good_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_undersize_frames_good_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_oversize_frames_good_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_oversize_frames_good_u *value) +{ + if (index >= RX_OVERSIZE_FRAMES_GOOD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_OVERSIZE_FRAMES_GOOD_ADDRESS + \ + index * RX_OVERSIZE_FRAMES_GOOD_INC, + &value->val); +} + +sw_error_t +hppe_rx_oversize_frames_good_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_oversize_frames_good_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_64octets_frames_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_64octets_frames_good_bad_low_u *value) +{ + if (index >= RX_64OCTETS_FRAMES_GOOD_BAD_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_64OCTETS_FRAMES_GOOD_BAD_LOW_ADDRESS + \ + index * RX_64OCTETS_FRAMES_GOOD_BAD_LOW_INC, + &value->val); +} + +sw_error_t +hppe_rx_64octets_frames_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_64octets_frames_good_bad_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_64octets_frames_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_64octets_frames_good_bad_high_u *value) +{ + if (index >= RX_64OCTETS_FRAMES_GOOD_BAD_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_64OCTETS_FRAMES_GOOD_BAD_HIGH_ADDRESS + \ + index * RX_64OCTETS_FRAMES_GOOD_BAD_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_rx_64octets_frames_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_64octets_frames_good_bad_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_65to127octets_frames_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_65to127octets_frames_good_bad_low_u *value) +{ + if (index >= RX_65TO127OCTETS_FRAMES_GOOD_BAD_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_65TO127OCTETS_FRAMES_GOOD_BAD_LOW_ADDRESS + \ + index * RX_65TO127OCTETS_FRAMES_GOOD_BAD_LOW_INC, + &value->val); +} + +sw_error_t +hppe_rx_65to127octets_frames_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_65to127octets_frames_good_bad_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_65to127octets_frames_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_65to127octets_frames_good_bad_high_u *value) +{ + if (index >= RX_65TO127OCTETS_FRAMES_GOOD_BAD_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_65TO127OCTETS_FRAMES_GOOD_BAD_HIGH_ADDRESS + \ + index * RX_65TO127OCTETS_FRAMES_GOOD_BAD_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_rx_65to127octets_frames_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_65to127octets_frames_good_bad_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_128to255octets_frames_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_128to255octets_frames_good_bad_low_u *value) +{ + if (index >= RX_128TO255OCTETS_FRAMES_GOOD_BAD_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_128TO255OCTETS_FRAMES_GOOD_BAD_LOW_ADDRESS + \ + index * RX_128TO255OCTETS_FRAMES_GOOD_BAD_LOW_INC, + &value->val); +} + +sw_error_t +hppe_rx_128to255octets_frames_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_128to255octets_frames_good_bad_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_128to255octets_frames_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_128to255octets_frames_good_bad_high_u *value) +{ + if (index >= RX_128TO255OCTETS_FRAMES_GOOD_BAD_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_128TO255OCTETS_FRAMES_GOOD_BAD_HIGH_ADDRESS + \ + index * RX_128TO255OCTETS_FRAMES_GOOD_BAD_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_rx_128to255octets_frames_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_128to255octets_frames_good_bad_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_256to511octets_frames_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_256to511octets_frames_good_bad_low_u *value) +{ + if (index >= RX_256TO511OCTETS_FRAMES_GOOD_BAD_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_256TO511OCTETS_FRAMES_GOOD_BAD_LOW_ADDRESS + \ + index * RX_256TO511OCTETS_FRAMES_GOOD_BAD_LOW_INC, + &value->val); +} + +sw_error_t +hppe_rx_256to511octets_frames_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_256to511octets_frames_good_bad_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_256to511octets_frames_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_256to511octets_frames_good_bad_high_u *value) +{ + if (index >= RX_256TO511OCTETS_FRAMES_GOOD_BAD_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_256TO511OCTETS_FRAMES_GOOD_BAD_HIGH_ADDRESS + \ + index * RX_256TO511OCTETS_FRAMES_GOOD_BAD_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_rx_256to511octets_frames_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_256to511octets_frames_good_bad_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_512to1023octets_frames_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_512to1023octets_frames_good_bad_low_u *value) +{ + if (index >= RX_512TO1023OCTETS_FRAMES_GOOD_BAD_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_512TO1023OCTETS_FRAMES_GOOD_BAD_LOW_ADDRESS + \ + index * RX_512TO1023OCTETS_FRAMES_GOOD_BAD_LOW_INC, + &value->val); +} + +sw_error_t +hppe_rx_512to1023octets_frames_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_512to1023octets_frames_good_bad_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_512to1023octets_frames_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_512to1023octets_frames_good_bad_high_u *value) +{ + if (index >= RX_512TO1023OCTETS_FRAMES_GOOD_BAD_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_512TO1023OCTETS_FRAMES_GOOD_BAD_HIGH_ADDRESS + \ + index * RX_512TO1023OCTETS_FRAMES_GOOD_BAD_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_rx_512to1023octets_frames_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_512to1023octets_frames_good_bad_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_1024tomaxoctets_frames_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_1024tomaxoctets_frames_good_bad_low_u *value) +{ + if (index >= RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_LOW_ADDRESS + \ + index * RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_LOW_INC, + &value->val); +} + +sw_error_t +hppe_rx_1024tomaxoctets_frames_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_1024tomaxoctets_frames_good_bad_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_1024tomaxoctets_frames_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_1024tomaxoctets_frames_good_bad_high_u *value) +{ + if (index >= RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_HIGH_ADDRESS + \ + index * RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_rx_1024tomaxoctets_frames_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_1024tomaxoctets_frames_good_bad_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_unicast_frames_good_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_unicast_frames_good_low_u *value) +{ + if (index >= RX_UNICAST_FRAMES_GOOD_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_UNICAST_FRAMES_GOOD_LOW_ADDRESS + \ + index * RX_UNICAST_FRAMES_GOOD_LOW_INC, + &value->val); +} + +sw_error_t +hppe_rx_unicast_frames_good_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_unicast_frames_good_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_unicast_frames_good_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_unicast_frames_good_high_u *value) +{ + if (index >= RX_UNICAST_FRAMES_GOOD_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_UNICAST_FRAMES_GOOD_HIGH_ADDRESS + \ + index * RX_UNICAST_FRAMES_GOOD_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_rx_unicast_frames_good_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_unicast_frames_good_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_length_error_frames_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_length_error_frames_low_u *value) +{ + if (index >= RX_LENGTH_ERROR_FRAMES_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_LENGTH_ERROR_FRAMES_LOW_ADDRESS + \ + index * RX_LENGTH_ERROR_FRAMES_LOW_INC, + &value->val); +} + +sw_error_t +hppe_rx_length_error_frames_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_length_error_frames_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_length_error_frames_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_length_error_frames_high_u *value) +{ + if (index >= RX_LENGTH_ERROR_FRAMES_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_LENGTH_ERROR_FRAMES_HIGH_ADDRESS + \ + index * RX_LENGTH_ERROR_FRAMES_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_rx_length_error_frames_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_length_error_frames_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_outofrange_frames_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_outofrange_frames_low_u *value) +{ + if (index >= RX_OUTOFRANGE_FRAMES_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_OUTOFRANGE_FRAMES_LOW_ADDRESS + \ + index * RX_OUTOFRANGE_FRAMES_LOW_INC, + &value->val); +} + +sw_error_t +hppe_rx_outofrange_frames_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_outofrange_frames_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_outofrange_frames_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_outofrange_frames_high_u *value) +{ + if (index >= RX_OUTOFRANGE_FRAMES_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_OUTOFRANGE_FRAMES_HIGH_ADDRESS + \ + index * RX_OUTOFRANGE_FRAMES_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_rx_outofrange_frames_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_outofrange_frames_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_pause_frames_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_pause_frames_low_u *value) +{ + if (index >= RX_PAUSE_FRAMES_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_PAUSE_FRAMES_LOW_ADDRESS + \ + index * RX_PAUSE_FRAMES_LOW_INC, + &value->val); +} + +sw_error_t +hppe_rx_pause_frames_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_pause_frames_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_pause_frames_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_pause_frames_high_u *value) +{ + if (index >= RX_PAUSE_FRAMES_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_PAUSE_FRAMES_HIGH_ADDRESS + \ + index * RX_PAUSE_FRAMES_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_rx_pause_frames_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_pause_frames_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_fifooverflow_frames_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_fifooverflow_frames_low_u *value) +{ + if (index >= RX_FIFOOVERFLOW_FRAMES_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_FIFOOVERFLOW_FRAMES_LOW_ADDRESS + \ + index * RX_FIFOOVERFLOW_FRAMES_LOW_INC, + &value->val); +} + +sw_error_t +hppe_rx_fifooverflow_frames_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_fifooverflow_frames_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_fifooverflow_frames_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_fifooverflow_frames_high_u *value) +{ + if (index >= RX_FIFOOVERFLOW_FRAMES_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_FIFOOVERFLOW_FRAMES_HIGH_ADDRESS + \ + index * RX_FIFOOVERFLOW_FRAMES_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_rx_fifooverflow_frames_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_fifooverflow_frames_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_vlan_frames_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_vlan_frames_good_bad_low_u *value) +{ + if (index >= RX_VLAN_FRAMES_GOOD_BAD_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_VLAN_FRAMES_GOOD_BAD_LOW_ADDRESS + \ + index * RX_VLAN_FRAMES_GOOD_BAD_LOW_INC, + &value->val); +} + +sw_error_t +hppe_rx_vlan_frames_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_vlan_frames_good_bad_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_vlan_frames_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_vlan_frames_good_bad_high_u *value) +{ + if (index >= RX_VLAN_FRAMES_GOOD_BAD_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_VLAN_FRAMES_GOOD_BAD_HIGH_ADDRESS + \ + index * RX_VLAN_FRAMES_GOOD_BAD_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_rx_vlan_frames_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_vlan_frames_good_bad_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_watchdog_error_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_watchdog_error_frames_u *value) +{ + if (index >= RX_WATCHDOG_ERROR_FRAMES_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_WATCHDOG_ERROR_FRAMES_ADDRESS + \ + index * RX_WATCHDOG_ERROR_FRAMES_INC, + &value->val); +} + +sw_error_t +hppe_rx_watchdog_error_frames_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_watchdog_error_frames_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_lpi_usec_cntr_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_lpi_usec_cntr_u *value) +{ + if (index >= RX_LPI_USEC_CNTR_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_LPI_USEC_CNTR_ADDRESS + \ + index * RX_LPI_USEC_CNTR_INC, + &value->val); +} + +sw_error_t +hppe_rx_lpi_usec_cntr_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_lpi_usec_cntr_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_lpi_tran_cntr_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_lpi_tran_cntr_u *value) +{ + if (index >= RX_LPI_TRAN_CNTR_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_LPI_TRAN_CNTR_ADDRESS + \ + index * RX_LPI_TRAN_CNTR_INC, + &value->val); +} + +sw_error_t +hppe_rx_lpi_tran_cntr_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_lpi_tran_cntr_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_discard_frame_count_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_discard_frame_count_good_bad_low_u *value) +{ + if (index >= RX_DISCARD_FRAME_COUNT_GOOD_BAD_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_DISCARD_FRAME_COUNT_GOOD_BAD_LOW_ADDRESS + \ + index * RX_DISCARD_FRAME_COUNT_GOOD_BAD_LOW_INC, + &value->val); +} + +sw_error_t +hppe_rx_discard_frame_count_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_discard_frame_count_good_bad_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_discard_frame_count_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_discard_frame_count_good_bad_high_u *value) +{ + if (index >= RX_DISCARD_FRAME_COUNT_GOOD_BAD_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_DISCARD_FRAME_COUNT_GOOD_BAD_HIGH_ADDRESS + \ + index * RX_DISCARD_FRAME_COUNT_GOOD_BAD_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_rx_discard_frame_count_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_discard_frame_count_good_bad_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_discard_octet_count_good_bad_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_discard_octet_count_good_bad_low_u *value) +{ + if (index >= RX_DISCARD_OCTET_COUNT_GOOD_BAD_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_DISCARD_OCTET_COUNT_GOOD_BAD_LOW_ADDRESS + \ + index * RX_DISCARD_OCTET_COUNT_GOOD_BAD_LOW_INC, + &value->val); +} + +sw_error_t +hppe_rx_discard_octet_count_good_bad_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_discard_octet_count_good_bad_low_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_discard_octet_count_good_bad_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_discard_octet_count_good_bad_high_u *value) +{ + if (index >= RX_DISCARD_OCTET_COUNT_GOOD_BAD_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + RX_DISCARD_OCTET_COUNT_GOOD_BAD_HIGH_ADDRESS + \ + index * RX_DISCARD_OCTET_COUNT_GOOD_BAD_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_rx_discard_octet_count_good_bad_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union rx_discard_octet_count_good_bad_high_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_control_cntrst_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_control_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_control_get(dev_id, index, ®_val); + *value = reg_val.bf.cntrst; + return ret; +} + +sw_error_t +hppe_mmc_control_cntrst_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_control_rstonrd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_control_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_control_get(dev_id, index, ®_val); + *value = reg_val.bf.rstonrd; + return ret; +} + +sw_error_t +hppe_mmc_control_rstonrd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_control_cntstopro_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_control_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_control_get(dev_id, index, ®_val); + *value = reg_val.bf.cntstopro; + return ret; +} + +sw_error_t +hppe_mmc_control_cntstopro_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_control_mct_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_control_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_control_get(dev_id, index, ®_val); + *value = reg_val.bf.mct; + return ret; +} + +sw_error_t +hppe_mmc_control_mct_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_control_pr_mmc_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_control_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_control_get(dev_id, index, ®_val); + *value = reg_val.bf.pr_mmc_sel; + return ret; +} + +sw_error_t +hppe_mmc_control_pr_mmc_sel_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_control_cntprst_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_control_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_control_get(dev_id, index, ®_val); + *value = reg_val.bf.cntprst; + return ret; +} + +sw_error_t +hppe_mmc_control_cntprst_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_control_mcf_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_control_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_control_get(dev_id, index, ®_val); + *value = reg_val.bf.mcf; + return ret; +} + +sw_error_t +hppe_mmc_control_mcf_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_octet_count_good_bad_low_txoctgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_octet_count_good_bad_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_octet_count_good_bad_low_get(dev_id, index, ®_val); + *value = reg_val.bf.txoctgblo; + return ret; +} + +sw_error_t +hppe_tx_octet_count_good_bad_low_txoctgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_octet_count_good_bad_high_txoctgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_octet_count_good_bad_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_octet_count_good_bad_high_get(dev_id, index, ®_val); + *value = reg_val.bf.txoctgbhi; + return ret; +} + +sw_error_t +hppe_tx_octet_count_good_bad_high_txoctgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_frame_count_good_bad_low_txfrmgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_frame_count_good_bad_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_frame_count_good_bad_low_get(dev_id, index, ®_val); + *value = reg_val.bf.txfrmgblo; + return ret; +} + +sw_error_t +hppe_tx_frame_count_good_bad_low_txfrmgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_frame_count_good_bad_high_txfrmgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_frame_count_good_bad_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_frame_count_good_bad_high_get(dev_id, index, ®_val); + *value = reg_val.bf.txfrmgbhi; + return ret; +} + +sw_error_t +hppe_tx_frame_count_good_bad_high_txfrmgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_broadcast_frames_good_low_txbcastglo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_broadcast_frames_good_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_broadcast_frames_good_low_get(dev_id, index, ®_val); + *value = reg_val.bf.txbcastglo; + return ret; +} + +sw_error_t +hppe_tx_broadcast_frames_good_low_txbcastglo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_broadcast_frames_good_high_txbcastghi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_broadcast_frames_good_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_broadcast_frames_good_high_get(dev_id, index, ®_val); + *value = reg_val.bf.txbcastghi; + return ret; +} + +sw_error_t +hppe_tx_broadcast_frames_good_high_txbcastghi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_multicast_frames_good_low_txmcastglo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_multicast_frames_good_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_multicast_frames_good_low_get(dev_id, index, ®_val); + *value = reg_val.bf.txmcastglo; + return ret; +} + +sw_error_t +hppe_tx_multicast_frames_good_low_txmcastglo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_multicast_frames_good_high_txmcastghi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_multicast_frames_good_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_multicast_frames_good_high_get(dev_id, index, ®_val); + *value = reg_val.bf.txmcastghi; + return ret; +} + +sw_error_t +hppe_tx_multicast_frames_good_high_txmcastghi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_64octets_frames_good_bad_low_tx64octgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_64octets_frames_good_bad_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_64octets_frames_good_bad_low_get(dev_id, index, ®_val); + *value = reg_val.bf.tx64octgblo; + return ret; +} + +sw_error_t +hppe_tx_64octets_frames_good_bad_low_tx64octgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_64octets_frames_good_bad_high_tx64octgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_64octets_frames_good_bad_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_64octets_frames_good_bad_high_get(dev_id, index, ®_val); + *value = reg_val.bf.tx64octgbhi; + return ret; +} + +sw_error_t +hppe_tx_64octets_frames_good_bad_high_tx64octgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_65to127octets_frames_good_bad_low_tx65_127octgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_65to127octets_frames_good_bad_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_65to127octets_frames_good_bad_low_get(dev_id, index, ®_val); + *value = reg_val.bf.tx65_127octgblo; + return ret; +} + +sw_error_t +hppe_tx_65to127octets_frames_good_bad_low_tx65_127octgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_65to127octets_frames_good_bad_high_tx65_127octgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_65to127octets_frames_good_bad_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_65to127octets_frames_good_bad_high_get(dev_id, index, ®_val); + *value = reg_val.bf.tx65_127octgbhi; + return ret; +} + +sw_error_t +hppe_tx_65to127octets_frames_good_bad_high_tx65_127octgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_128to255octets_frames_good_bad_low_tx128_255octgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_128to255octets_frames_good_bad_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_128to255octets_frames_good_bad_low_get(dev_id, index, ®_val); + *value = reg_val.bf.tx128_255octgblo; + return ret; +} + +sw_error_t +hppe_tx_128to255octets_frames_good_bad_low_tx128_255octgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_128to255octets_frames_good_bad_high_tx128_255octgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_128to255octets_frames_good_bad_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_128to255octets_frames_good_bad_high_get(dev_id, index, ®_val); + *value = reg_val.bf.tx128_255octgbhi; + return ret; +} + +sw_error_t +hppe_tx_128to255octets_frames_good_bad_high_tx128_255octgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_256to511octets_frames_good_bad_low_tx256_511octgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_256to511octets_frames_good_bad_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_256to511octets_frames_good_bad_low_get(dev_id, index, ®_val); + *value = reg_val.bf.tx256_511octgblo; + return ret; +} + +sw_error_t +hppe_tx_256to511octets_frames_good_bad_low_tx256_511octgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_256to511octets_frames_good_bad_high_tx256_511octgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_256to511octets_frames_good_bad_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_256to511octets_frames_good_bad_high_get(dev_id, index, ®_val); + *value = reg_val.bf.tx256_511octgbhi; + return ret; +} + +sw_error_t +hppe_tx_256to511octets_frames_good_bad_high_tx256_511octgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_512to1023octets_frames_good_bad_low_tx512_1023octgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_512to1023octets_frames_good_bad_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_512to1023octets_frames_good_bad_low_get(dev_id, index, ®_val); + *value = reg_val.bf.tx512_1023octgblo; + return ret; +} + +sw_error_t +hppe_tx_512to1023octets_frames_good_bad_low_tx512_1023octgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_512to1023octets_frames_good_bad_high_tx512_1023octgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_512to1023octets_frames_good_bad_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_512to1023octets_frames_good_bad_high_get(dev_id, index, ®_val); + *value = reg_val.bf.tx512_1023octgbhi; + return ret; +} + +sw_error_t +hppe_tx_512to1023octets_frames_good_bad_high_tx512_1023octgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_1024tomaxoctets_frames_good_bad_low_tx1024_maxoctgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_1024tomaxoctets_frames_good_bad_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_1024tomaxoctets_frames_good_bad_low_get(dev_id, index, ®_val); + *value = reg_val.bf.tx1024_maxoctgblo; + return ret; +} + +sw_error_t +hppe_tx_1024tomaxoctets_frames_good_bad_low_tx1024_maxoctgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_1024tomaxoctets_frames_good_bad_high_tx1024_maxoctgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_1024tomaxoctets_frames_good_bad_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_1024tomaxoctets_frames_good_bad_high_get(dev_id, index, ®_val); + *value = reg_val.bf.tx1024_maxoctgbhi; + return ret; +} + +sw_error_t +hppe_tx_1024tomaxoctets_frames_good_bad_high_tx1024_maxoctgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_unicast_frames_good_bad_low_txucastgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_unicast_frames_good_bad_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_unicast_frames_good_bad_low_get(dev_id, index, ®_val); + *value = reg_val.bf.txucastgblo; + return ret; +} + +sw_error_t +hppe_tx_unicast_frames_good_bad_low_txucastgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_unicast_frames_good_bad_high_txucastgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_unicast_frames_good_bad_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_unicast_frames_good_bad_high_get(dev_id, index, ®_val); + *value = reg_val.bf.txucastgbhi; + return ret; +} + +sw_error_t +hppe_tx_unicast_frames_good_bad_high_txucastgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_multicast_frames_good_bad_low_txmcastgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_multicast_frames_good_bad_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_multicast_frames_good_bad_low_get(dev_id, index, ®_val); + *value = reg_val.bf.txmcastgblo; + return ret; +} + +sw_error_t +hppe_tx_multicast_frames_good_bad_low_txmcastgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_multicast_frames_good_bad_high_txmcastgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_multicast_frames_good_bad_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_multicast_frames_good_bad_high_get(dev_id, index, ®_val); + *value = reg_val.bf.txmcastgbhi; + return ret; +} + +sw_error_t +hppe_tx_multicast_frames_good_bad_high_txmcastgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_broadcast_frames_good_bad_low_txbcastgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_broadcast_frames_good_bad_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_broadcast_frames_good_bad_low_get(dev_id, index, ®_val); + *value = reg_val.bf.txbcastgblo; + return ret; +} + +sw_error_t +hppe_tx_broadcast_frames_good_bad_low_txbcastgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_broadcast_frames_good_bad_high_txbcastgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_broadcast_frames_good_bad_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_broadcast_frames_good_bad_high_get(dev_id, index, ®_val); + *value = reg_val.bf.txbcastgbhi; + return ret; +} + +sw_error_t +hppe_tx_broadcast_frames_good_bad_high_txbcastgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_underflow_error_frames_low_txundrflwlo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_underflow_error_frames_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_underflow_error_frames_low_get(dev_id, index, ®_val); + *value = reg_val.bf.txundrflwlo; + return ret; +} + +sw_error_t +hppe_tx_underflow_error_frames_low_txundrflwlo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_underflow_error_frames_high_txundrflwhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_underflow_error_frames_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_underflow_error_frames_high_get(dev_id, index, ®_val); + *value = reg_val.bf.txundrflwhi; + return ret; +} + +sw_error_t +hppe_tx_underflow_error_frames_high_txundrflwhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_octet_count_good_low_txoctglo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_octet_count_good_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_octet_count_good_low_get(dev_id, index, ®_val); + *value = reg_val.bf.txoctglo; + return ret; +} + +sw_error_t +hppe_tx_octet_count_good_low_txoctglo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_octet_count_good_high_txoctghi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_octet_count_good_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_octet_count_good_high_get(dev_id, index, ®_val); + *value = reg_val.bf.txoctghi; + return ret; +} + +sw_error_t +hppe_tx_octet_count_good_high_txoctghi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_frame_count_good_low_txfrmglo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_frame_count_good_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_frame_count_good_low_get(dev_id, index, ®_val); + *value = reg_val.bf.txfrmglo; + return ret; +} + +sw_error_t +hppe_tx_frame_count_good_low_txfrmglo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_frame_count_good_high_txfrmghi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_frame_count_good_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_frame_count_good_high_get(dev_id, index, ®_val); + *value = reg_val.bf.txfrmghi; + return ret; +} + +sw_error_t +hppe_tx_frame_count_good_high_txfrmghi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_pause_frames_low_txpauseglo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_pause_frames_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_pause_frames_low_get(dev_id, index, ®_val); + *value = reg_val.bf.txpauseglo; + return ret; +} + +sw_error_t +hppe_tx_pause_frames_low_txpauseglo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_pause_frames_high_txpauseghi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_pause_frames_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_pause_frames_high_get(dev_id, index, ®_val); + *value = reg_val.bf.txpauseghi; + return ret; +} + +sw_error_t +hppe_tx_pause_frames_high_txpauseghi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_vlan_frames_good_low_txvlanglo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_vlan_frames_good_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_vlan_frames_good_low_get(dev_id, index, ®_val); + *value = reg_val.bf.txvlanglo; + return ret; +} + +sw_error_t +hppe_tx_vlan_frames_good_low_txvlanglo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_vlan_frames_good_high_txvlanghi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_vlan_frames_good_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_vlan_frames_good_high_get(dev_id, index, ®_val); + *value = reg_val.bf.txvlanghi; + return ret; +} + +sw_error_t +hppe_tx_vlan_frames_good_high_txvlanghi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_lpi_usec_cntr_txlpiusc_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_lpi_usec_cntr_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_lpi_usec_cntr_get(dev_id, index, ®_val); + *value = reg_val.bf.txlpiusc; + return ret; +} + +sw_error_t +hppe_tx_lpi_usec_cntr_txlpiusc_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_tx_lpi_tran_cntr_txlpitrc_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union tx_lpi_tran_cntr_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_tx_lpi_tran_cntr_get(dev_id, index, ®_val); + *value = reg_val.bf.txlpitrc; + return ret; +} + +sw_error_t +hppe_tx_lpi_tran_cntr_txlpitrc_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_frame_count_good_bad_low_rxfrmgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_frame_count_good_bad_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_frame_count_good_bad_low_get(dev_id, index, ®_val); + *value = reg_val.bf.rxfrmgblo; + return ret; +} + +sw_error_t +hppe_rx_frame_count_good_bad_low_rxfrmgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_frame_count_good_bad_high_rxfrmgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_frame_count_good_bad_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_frame_count_good_bad_high_get(dev_id, index, ®_val); + *value = reg_val.bf.rxfrmgbhi; + return ret; +} + +sw_error_t +hppe_rx_frame_count_good_bad_high_rxfrmgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_octet_count_good_bad_low_rxoctgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_octet_count_good_bad_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_octet_count_good_bad_low_get(dev_id, index, ®_val); + *value = reg_val.bf.rxoctgblo; + return ret; +} + +sw_error_t +hppe_rx_octet_count_good_bad_low_rxoctgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_octet_count_good_bad_high_rxoctgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_octet_count_good_bad_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_octet_count_good_bad_high_get(dev_id, index, ®_val); + *value = reg_val.bf.rxoctgbhi; + return ret; +} + +sw_error_t +hppe_rx_octet_count_good_bad_high_rxoctgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_octet_count_good_low_rxoctglo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_octet_count_good_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_octet_count_good_low_get(dev_id, index, ®_val); + *value = reg_val.bf.rxoctglo; + return ret; +} + +sw_error_t +hppe_rx_octet_count_good_low_rxoctglo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_octet_count_good_high_rxoctghi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_octet_count_good_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_octet_count_good_high_get(dev_id, index, ®_val); + *value = reg_val.bf.rxoctghi; + return ret; +} + +sw_error_t +hppe_rx_octet_count_good_high_rxoctghi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_broadcast_frames_good_low_rxbcastglo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_broadcast_frames_good_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_broadcast_frames_good_low_get(dev_id, index, ®_val); + *value = reg_val.bf.rxbcastglo; + return ret; +} + +sw_error_t +hppe_rx_broadcast_frames_good_low_rxbcastglo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_broadcast_frames_good_high_rxbcastghi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_broadcast_frames_good_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_broadcast_frames_good_high_get(dev_id, index, ®_val); + *value = reg_val.bf.rxbcastghi; + return ret; +} + +sw_error_t +hppe_rx_broadcast_frames_good_high_rxbcastghi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_multicast_frames_good_low_rxmcastglo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_multicast_frames_good_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_multicast_frames_good_low_get(dev_id, index, ®_val); + *value = reg_val.bf.rxmcastglo; + return ret; +} + +sw_error_t +hppe_rx_multicast_frames_good_low_rxmcastglo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_multicast_frames_good_high_rxmcastghi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_multicast_frames_good_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_multicast_frames_good_high_get(dev_id, index, ®_val); + *value = reg_val.bf.rxmcastghi; + return ret; +} + +sw_error_t +hppe_rx_multicast_frames_good_high_rxmcastghi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_crc_error_frames_low_rxcrcerlo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_crc_error_frames_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_crc_error_frames_low_get(dev_id, index, ®_val); + *value = reg_val.bf.rxcrcerlo; + return ret; +} + +sw_error_t +hppe_rx_crc_error_frames_low_rxcrcerlo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_crc_error_frames_high_rxcrcerhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_crc_error_frames_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_crc_error_frames_high_get(dev_id, index, ®_val); + *value = reg_val.bf.rxcrcerhi; + return ret; +} + +sw_error_t +hppe_rx_crc_error_frames_high_rxcrcerhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_runt_error_frames_rxrunter_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_runt_error_frames_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_runt_error_frames_get(dev_id, index, ®_val); + *value = reg_val.bf.rxrunter; + return ret; +} + +sw_error_t +hppe_rx_runt_error_frames_rxrunter_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_jabber_error_frames_rxjaberer_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_jabber_error_frames_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_jabber_error_frames_get(dev_id, index, ®_val); + *value = reg_val.bf.rxjaberer; + return ret; +} + +sw_error_t +hppe_rx_jabber_error_frames_rxjaberer_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_undersize_frames_good_rxusizeg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_undersize_frames_good_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_undersize_frames_good_get(dev_id, index, ®_val); + *value = reg_val.bf.rxusizeg; + return ret; +} + +sw_error_t +hppe_rx_undersize_frames_good_rxusizeg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_oversize_frames_good_rxosizeg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_oversize_frames_good_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_oversize_frames_good_get(dev_id, index, ®_val); + *value = reg_val.bf.rxosizeg; + return ret; +} + +sw_error_t +hppe_rx_oversize_frames_good_rxosizeg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_64octets_frames_good_bad_low_rx64octgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_64octets_frames_good_bad_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_64octets_frames_good_bad_low_get(dev_id, index, ®_val); + *value = reg_val.bf.rx64octgblo; + return ret; +} + +sw_error_t +hppe_rx_64octets_frames_good_bad_low_rx64octgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_64octets_frames_good_bad_high_rx64octgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_64octets_frames_good_bad_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_64octets_frames_good_bad_high_get(dev_id, index, ®_val); + *value = reg_val.bf.rx64octgbhi; + return ret; +} + +sw_error_t +hppe_rx_64octets_frames_good_bad_high_rx64octgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_65to127octets_frames_good_bad_low_rx65_127octgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_65to127octets_frames_good_bad_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_65to127octets_frames_good_bad_low_get(dev_id, index, ®_val); + *value = reg_val.bf.rx65_127octgblo; + return ret; +} + +sw_error_t +hppe_rx_65to127octets_frames_good_bad_low_rx65_127octgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_65to127octets_frames_good_bad_high_rx65_127octgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_65to127octets_frames_good_bad_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_65to127octets_frames_good_bad_high_get(dev_id, index, ®_val); + *value = reg_val.bf.rx65_127octgbhi; + return ret; +} + +sw_error_t +hppe_rx_65to127octets_frames_good_bad_high_rx65_127octgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_128to255octets_frames_good_bad_low_rx128_255octgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_128to255octets_frames_good_bad_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_128to255octets_frames_good_bad_low_get(dev_id, index, ®_val); + *value = reg_val.bf.rx128_255octgblo; + return ret; +} + +sw_error_t +hppe_rx_128to255octets_frames_good_bad_low_rx128_255octgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_128to255octets_frames_good_bad_high_rx128_255octgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_128to255octets_frames_good_bad_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_128to255octets_frames_good_bad_high_get(dev_id, index, ®_val); + *value = reg_val.bf.rx128_255octgbhi; + return ret; +} + +sw_error_t +hppe_rx_128to255octets_frames_good_bad_high_rx128_255octgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_256to511octets_frames_good_bad_low_rx256_511octgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_256to511octets_frames_good_bad_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_256to511octets_frames_good_bad_low_get(dev_id, index, ®_val); + *value = reg_val.bf.rx256_511octgblo; + return ret; +} + +sw_error_t +hppe_rx_256to511octets_frames_good_bad_low_rx256_511octgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_256to511octets_frames_good_bad_high_rx256_511octgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_256to511octets_frames_good_bad_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_256to511octets_frames_good_bad_high_get(dev_id, index, ®_val); + *value = reg_val.bf.rx256_511octgbhi; + return ret; +} + +sw_error_t +hppe_rx_256to511octets_frames_good_bad_high_rx256_511octgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_512to1023octets_frames_good_bad_low_rx512_1023octgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_512to1023octets_frames_good_bad_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_512to1023octets_frames_good_bad_low_get(dev_id, index, ®_val); + *value = reg_val.bf.rx512_1023octgblo; + return ret; +} + +sw_error_t +hppe_rx_512to1023octets_frames_good_bad_low_rx512_1023octgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_512to1023octets_frames_good_bad_high_rx512_1023octgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_512to1023octets_frames_good_bad_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_512to1023octets_frames_good_bad_high_get(dev_id, index, ®_val); + *value = reg_val.bf.rx512_1023octgbhi; + return ret; +} + +sw_error_t +hppe_rx_512to1023octets_frames_good_bad_high_rx512_1023octgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_1024tomaxoctets_frames_good_bad_low_rx1024_maxgboctlo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_1024tomaxoctets_frames_good_bad_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_1024tomaxoctets_frames_good_bad_low_get(dev_id, index, ®_val); + *value = reg_val.bf.rx1024_maxgboctlo; + return ret; +} + +sw_error_t +hppe_rx_1024tomaxoctets_frames_good_bad_low_rx1024_maxgboctlo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_1024tomaxoctets_frames_good_bad_high_rx1024_maxgbocthi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_1024tomaxoctets_frames_good_bad_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_1024tomaxoctets_frames_good_bad_high_get(dev_id, index, ®_val); + *value = reg_val.bf.rx1024_maxgbocthi; + return ret; +} + +sw_error_t +hppe_rx_1024tomaxoctets_frames_good_bad_high_rx1024_maxgbocthi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_unicast_frames_good_low_rxucastglo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_unicast_frames_good_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_unicast_frames_good_low_get(dev_id, index, ®_val); + *value = reg_val.bf.rxucastglo; + return ret; +} + +sw_error_t +hppe_rx_unicast_frames_good_low_rxucastglo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_unicast_frames_good_high_rxucastghi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_unicast_frames_good_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_unicast_frames_good_high_get(dev_id, index, ®_val); + *value = reg_val.bf.rxucastghi; + return ret; +} + +sw_error_t +hppe_rx_unicast_frames_good_high_rxucastghi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_length_error_frames_low_rxlenerrlo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_length_error_frames_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_length_error_frames_low_get(dev_id, index, ®_val); + *value = reg_val.bf.rxlenerrlo; + return ret; +} + +sw_error_t +hppe_rx_length_error_frames_low_rxlenerrlo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_length_error_frames_high_rxlenerrhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_length_error_frames_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_length_error_frames_high_get(dev_id, index, ®_val); + *value = reg_val.bf.rxlenerrhi; + return ret; +} + +sw_error_t +hppe_rx_length_error_frames_high_rxlenerrhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_outofrange_frames_low_rxorangelo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_outofrange_frames_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_outofrange_frames_low_get(dev_id, index, ®_val); + *value = reg_val.bf.rxorangelo; + return ret; +} + +sw_error_t +hppe_rx_outofrange_frames_low_rxorangelo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_outofrange_frames_high_rxorangehi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_outofrange_frames_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_outofrange_frames_high_get(dev_id, index, ®_val); + *value = reg_val.bf.rxorangehi; + return ret; +} + +sw_error_t +hppe_rx_outofrange_frames_high_rxorangehi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_pause_frames_low_rxpauselo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_pause_frames_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_pause_frames_low_get(dev_id, index, ®_val); + *value = reg_val.bf.rxpauselo; + return ret; +} + +sw_error_t +hppe_rx_pause_frames_low_rxpauselo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_pause_frames_high_rxpausehi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_pause_frames_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_pause_frames_high_get(dev_id, index, ®_val); + *value = reg_val.bf.rxpausehi; + return ret; +} + +sw_error_t +hppe_rx_pause_frames_high_rxpausehi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_fifooverflow_frames_low_rxfovflo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_fifooverflow_frames_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_fifooverflow_frames_low_get(dev_id, index, ®_val); + *value = reg_val.bf.rxfovflo; + return ret; +} + +sw_error_t +hppe_rx_fifooverflow_frames_low_rxfovflo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_fifooverflow_frames_high_rxfovfhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_fifooverflow_frames_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_fifooverflow_frames_high_get(dev_id, index, ®_val); + *value = reg_val.bf.rxfovfhi; + return ret; +} + +sw_error_t +hppe_rx_fifooverflow_frames_high_rxfovfhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_vlan_frames_good_bad_low_rxvlangblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_vlan_frames_good_bad_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_vlan_frames_good_bad_low_get(dev_id, index, ®_val); + *value = reg_val.bf.rxvlangblo; + return ret; +} + +sw_error_t +hppe_rx_vlan_frames_good_bad_low_rxvlangblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_vlan_frames_good_bad_high_rxvlangbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_vlan_frames_good_bad_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_vlan_frames_good_bad_high_get(dev_id, index, ®_val); + *value = reg_val.bf.rxvlangbhi; + return ret; +} + +sw_error_t +hppe_rx_vlan_frames_good_bad_high_rxvlangbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_watchdog_error_frames_rxwdogerr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_watchdog_error_frames_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_watchdog_error_frames_get(dev_id, index, ®_val); + *value = reg_val.bf.rxwdogerr; + return ret; +} + +sw_error_t +hppe_rx_watchdog_error_frames_rxwdogerr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_lpi_usec_cntr_rxlpiusc_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_lpi_usec_cntr_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_lpi_usec_cntr_get(dev_id, index, ®_val); + *value = reg_val.bf.rxlpiusc; + return ret; +} + +sw_error_t +hppe_rx_lpi_usec_cntr_rxlpiusc_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_lpi_tran_cntr_rxlpitrc_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_lpi_tran_cntr_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_lpi_tran_cntr_get(dev_id, index, ®_val); + *value = reg_val.bf.rxlpitrc; + return ret; +} + +sw_error_t +hppe_rx_lpi_tran_cntr_rxlpitrc_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_discard_frame_count_good_bad_low_rxdfcntgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_discard_frame_count_good_bad_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_discard_frame_count_good_bad_low_get(dev_id, index, ®_val); + *value = reg_val.bf.rxdfcntgblo; + return ret; +} + +sw_error_t +hppe_rx_discard_frame_count_good_bad_low_rxdfcntgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_discard_frame_count_good_bad_high_rxdfcntgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_discard_frame_count_good_bad_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_discard_frame_count_good_bad_high_get(dev_id, index, ®_val); + *value = reg_val.bf.rxdfcntgbhi; + return ret; +} + +sw_error_t +hppe_rx_discard_frame_count_good_bad_high_rxdfcntgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_discard_octet_count_good_bad_low_rxdocntgblo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_discard_octet_count_good_bad_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_discard_octet_count_good_bad_low_get(dev_id, index, ®_val); + *value = reg_val.bf.rxdocntgblo; + return ret; +} + +sw_error_t +hppe_rx_discard_octet_count_good_bad_low_rxdocntgblo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_rx_discard_octet_count_good_bad_high_rxdocntgbhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union rx_discard_octet_count_good_bad_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_rx_discard_octet_count_good_bad_high_get(dev_id, index, ®_val); + *value = reg_val.bf.rxdocntgbhi; + return ret; +} + +sw_error_t +hppe_rx_discard_octet_count_good_bad_high_rxdocntgbhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_xgportctrl.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_xgportctrl.c new file mode 100755 index 000000000..2caddc717 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/hppe/hppe_xgportctrl.c @@ -0,0 +1,6074 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hppe_reg_access.h" +#include "hppe_xgportctrl_reg.h" +#include "hppe_xgportctrl.h" + +sw_error_t +hppe_mac_tx_configuration_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_tx_configuration_u *value) +{ + if (index >= MAC_TX_CONFIGURATION_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MAC_TX_CONFIGURATION_ADDRESS + \ + index * MAC_TX_CONFIGURATION_INC, + &value->val); +} + +sw_error_t +hppe_mac_tx_configuration_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_tx_configuration_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MAC_TX_CONFIGURATION_ADDRESS + \ + index * MAC_TX_CONFIGURATION_INC, + value->val); +} + +sw_error_t +hppe_mac_rx_configuration_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_rx_configuration_u *value) +{ + if (index >= MAC_RX_CONFIGURATION_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MAC_RX_CONFIGURATION_ADDRESS + \ + index * MAC_RX_CONFIGURATION_INC, + &value->val); +} + +sw_error_t +hppe_mac_rx_configuration_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_rx_configuration_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MAC_RX_CONFIGURATION_ADDRESS + \ + index * MAC_RX_CONFIGURATION_INC, + value->val); +} + +sw_error_t +hppe_mac_packet_filter_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_packet_filter_u *value) +{ + if (index >= MAC_PACKET_FILTER_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MAC_PACKET_FILTER_ADDRESS + \ + index * MAC_PACKET_FILTER_INC, + &value->val); +} + +sw_error_t +hppe_mac_packet_filter_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_packet_filter_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MAC_PACKET_FILTER_ADDRESS + \ + index * MAC_PACKET_FILTER_INC, + value->val); +} +#ifndef IN_PORTCONTROL_MINI + +sw_error_t +hppe_mac_watchdog_timeout_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_watchdog_timeout_u *value) +{ + if (index >= MAC_WATCHDOG_TIMEOUT_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MAC_WATCHDOG_TIMEOUT_ADDRESS + \ + index * MAC_WATCHDOG_TIMEOUT_INC, + &value->val); +} + +sw_error_t +hppe_mac_watchdog_timeout_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_watchdog_timeout_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MAC_WATCHDOG_TIMEOUT_ADDRESS + \ + index * MAC_WATCHDOG_TIMEOUT_INC, + value->val); +} + +sw_error_t +hppe_mac_vlan_tag_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_vlan_tag_u *value) +{ + if (index >= MAC_VLAN_TAG_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MAC_VLAN_TAG_ADDRESS + \ + index * MAC_VLAN_TAG_INC, + &value->val); +} + +sw_error_t +hppe_mac_vlan_tag_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_vlan_tag_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MAC_VLAN_TAG_ADDRESS + \ + index * MAC_VLAN_TAG_INC, + value->val); +} + +sw_error_t +hppe_mac_rx_eth_type_match_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_rx_eth_type_match_u *value) +{ + if (index >= MAC_RX_ETH_TYPE_MATCH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MAC_RX_ETH_TYPE_MATCH_ADDRESS + \ + index * MAC_RX_ETH_TYPE_MATCH_INC, + &value->val); +} + +sw_error_t +hppe_mac_rx_eth_type_match_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_rx_eth_type_match_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MAC_RX_ETH_TYPE_MATCH_ADDRESS + \ + index * MAC_RX_ETH_TYPE_MATCH_INC, + value->val); +} +#endif +sw_error_t +hppe_mac_q0_tx_flow_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_q0_tx_flow_ctrl_u *value) +{ + if (index >= MAC_Q0_TX_FLOW_CTRL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MAC_Q0_TX_FLOW_CTRL_ADDRESS + \ + index * MAC_Q0_TX_FLOW_CTRL_INC, + &value->val); +} + +sw_error_t +hppe_mac_q0_tx_flow_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_q0_tx_flow_ctrl_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MAC_Q0_TX_FLOW_CTRL_ADDRESS + \ + index * MAC_Q0_TX_FLOW_CTRL_INC, + value->val); +} + +sw_error_t +hppe_mac_rx_flow_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_rx_flow_ctrl_u *value) +{ + if (index >= MAC_RX_FLOW_CTRL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MAC_RX_FLOW_CTRL_ADDRESS + \ + index * MAC_RX_FLOW_CTRL_INC, + &value->val); +} + +sw_error_t +hppe_mac_rx_flow_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_rx_flow_ctrl_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MAC_RX_FLOW_CTRL_ADDRESS + \ + index * MAC_RX_FLOW_CTRL_INC, + value->val); +} +#ifndef IN_PORTCONTROL_MINI + +sw_error_t +hppe_mac_interrupt_status_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_interrupt_status_u *value) +{ + if (index >= MAC_INTERRUPT_STATUS_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MAC_INTERRUPT_STATUS_ADDRESS + \ + index * MAC_INTERRUPT_STATUS_INC, + &value->val); +} + +sw_error_t +hppe_mac_interrupt_status_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_interrupt_status_u *value) +{ + return SW_NOT_SUPPORTED; + +} + +sw_error_t +hppe_mac_interrupt_enable_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_interrupt_enable_u *value) +{ + if (index >= MAC_INTERRUPT_ENABLE_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MAC_INTERRUPT_ENABLE_ADDRESS + \ + index * MAC_INTERRUPT_ENABLE_INC, + &value->val); +} + +sw_error_t +hppe_mac_interrupt_enable_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_interrupt_enable_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MAC_INTERRUPT_ENABLE_ADDRESS + \ + index * MAC_INTERRUPT_ENABLE_INC, + value->val); +} + +sw_error_t +hppe_mac_rx_tx_status_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_rx_tx_status_u *value) +{ + if (index >= MAC_RX_TX_STATUS_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MAC_RX_TX_STATUS_ADDRESS + \ + index * MAC_RX_TX_STATUS_INC, + &value->val); +} + +sw_error_t +hppe_mac_rx_tx_status_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_rx_tx_status_u *value) +{ + return SW_NOT_SUPPORTED; + +} + +sw_error_t +hppe_mac_lpi_control_status_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_lpi_control_status_u *value) +{ + if (index >= MAC_LPI_CONTROL_STATUS_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MAC_LPI_CONTROL_STATUS_ADDRESS + \ + index * MAC_LPI_CONTROL_STATUS_INC, + &value->val); +} + +sw_error_t +hppe_mac_lpi_control_status_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_lpi_control_status_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MAC_LPI_CONTROL_STATUS_ADDRESS + \ + index * MAC_LPI_CONTROL_STATUS_INC, + value->val); +} + +sw_error_t +hppe_mac_lpi_timers_control_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_lpi_timers_control_u *value) +{ + if (index >= MAC_LPI_TIMERS_CONTROL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MAC_LPI_TIMERS_CONTROL_ADDRESS + \ + index * MAC_LPI_TIMERS_CONTROL_INC, + &value->val); +} + +sw_error_t +hppe_mac_lpi_timers_control_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_lpi_timers_control_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MAC_LPI_TIMERS_CONTROL_ADDRESS + \ + index * MAC_LPI_TIMERS_CONTROL_INC, + value->val); +} + +sw_error_t +hppe_mac_lpi_auto_entry_timer_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_lpi_auto_entry_timer_u *value) +{ + if (index >= MAC_LPI_AUTO_ENTRY_TIMER_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MAC_LPI_AUTO_ENTRY_TIMER_ADDRESS + \ + index * MAC_LPI_AUTO_ENTRY_TIMER_INC, + &value->val); +} + +sw_error_t +hppe_mac_lpi_auto_entry_timer_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_lpi_auto_entry_timer_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MAC_LPI_AUTO_ENTRY_TIMER_ADDRESS + \ + index * MAC_LPI_AUTO_ENTRY_TIMER_INC, + value->val); +} + +sw_error_t +hppe_mac_1us_tic_counter_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_1us_tic_counter_u *value) +{ + if (index >= MAC_1US_TIC_COUNTER_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MAC_1US_TIC_COUNTER_ADDRESS + \ + index * MAC_1US_TIC_COUNTER_INC, + &value->val); +} + +sw_error_t +hppe_mac_1us_tic_counter_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_1us_tic_counter_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MAC_1US_TIC_COUNTER_ADDRESS + \ + index * MAC_1US_TIC_COUNTER_INC, + value->val); +} + +sw_error_t +hppe_mac_address0_high_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_address0_high_u *value) +{ + if (index >= MAC_ADDRESS0_HIGH_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MAC_ADDRESS0_HIGH_ADDRESS + \ + index * MAC_ADDRESS0_HIGH_INC, + &value->val); +} + +sw_error_t +hppe_mac_address0_high_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_address0_high_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MAC_ADDRESS0_HIGH_ADDRESS + \ + index * MAC_ADDRESS0_HIGH_INC, + value->val); +} + +sw_error_t +hppe_mac_address0_low_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_address0_low_u *value) +{ + if (index >= MAC_ADDRESS0_LOW_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MAC_ADDRESS0_LOW_ADDRESS + \ + index * MAC_ADDRESS0_LOW_INC, + &value->val); +} + +sw_error_t +hppe_mac_address0_low_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_address0_low_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MAC_ADDRESS0_LOW_ADDRESS + \ + index * MAC_ADDRESS0_LOW_INC, + value->val); +} + +sw_error_t +hppe_mmc_receive_interrupt_get( + a_uint32_t dev_id, + a_uint32_t index, + union mmc_receive_interrupt_u *value) +{ + if (index >= MMC_RECEIVE_INTERRUPT_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MMC_RECEIVE_INTERRUPT_ADDRESS + \ + index * MMC_RECEIVE_INTERRUPT_INC, + &value->val); +} + +sw_error_t +hppe_mmc_receive_interrupt_set( + a_uint32_t dev_id, + a_uint32_t index, + union mmc_receive_interrupt_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_get( + a_uint32_t dev_id, + a_uint32_t index, + union mmc_transmit_interrupt_u *value) +{ + if (index >= MMC_TRANSMIT_INTERRUPT_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MMC_TRANSMIT_INTERRUPT_ADDRESS + \ + index * MMC_TRANSMIT_INTERRUPT_INC, + &value->val); +} + +sw_error_t +hppe_mmc_transmit_interrupt_set( + a_uint32_t dev_id, + a_uint32_t index, + union mmc_transmit_interrupt_u *value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_get( + a_uint32_t dev_id, + a_uint32_t index, + union mmc_receive_interrupt_enable_u *value) +{ + if (index >= MMC_RECEIVE_INTERRUPT_ENABLE_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MMC_RECEIVE_INTERRUPT_ENABLE_ADDRESS + \ + index * MMC_RECEIVE_INTERRUPT_ENABLE_INC, + &value->val); +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_set( + a_uint32_t dev_id, + a_uint32_t index, + union mmc_receive_interrupt_enable_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MMC_RECEIVE_INTERRUPT_ENABLE_ADDRESS + \ + index * MMC_RECEIVE_INTERRUPT_ENABLE_INC, + value->val); +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_get( + a_uint32_t dev_id, + a_uint32_t index, + union mmc_transmit_interrupt_enable_u *value) +{ + if (index >= MMC_TRANSMIT_INTERRUPT_ENABLE_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_reg_get( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MMC_TRANSMIT_INTERRUPT_ENABLE_ADDRESS + \ + index * MMC_TRANSMIT_INTERRUPT_ENABLE_INC, + &value->val); +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_set( + a_uint32_t dev_id, + a_uint32_t index, + union mmc_transmit_interrupt_enable_u *value) +{ + return hppe_reg_set( + dev_id, + NSS_XGMAC_CSR_BASE_ADDR + MMC_TRANSMIT_INTERRUPT_ENABLE_ADDRESS + \ + index * MMC_TRANSMIT_INTERRUPT_ENABLE_INC, + value->val); +} + +sw_error_t +hppe_mac_tx_configuration_vne_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_tx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_tx_configuration_get(dev_id, index, ®_val); + *value = reg_val.bf.vne; + return ret; +} + +sw_error_t +hppe_mac_tx_configuration_vne_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_tx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_tx_configuration_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.vne = value; + ret = hppe_mac_tx_configuration_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_tx_configuration_ddic_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_tx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_tx_configuration_get(dev_id, index, ®_val); + *value = reg_val.bf.ddic; + return ret; +} + +sw_error_t +hppe_mac_tx_configuration_ddic_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_tx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_tx_configuration_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ddic = value; + ret = hppe_mac_tx_configuration_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_tx_configuration_te_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_tx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_tx_configuration_get(dev_id, index, ®_val); + *value = reg_val.bf.te; + return ret; +} + +sw_error_t +hppe_mac_tx_configuration_te_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_tx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_tx_configuration_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.te = value; + ret = hppe_mac_tx_configuration_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_tx_configuration_ipg_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_tx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_tx_configuration_get(dev_id, index, ®_val); + *value = reg_val.bf.ipg; + return ret; +} + +sw_error_t +hppe_mac_tx_configuration_ipg_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_tx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_tx_configuration_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipg = value; + ret = hppe_mac_tx_configuration_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_tx_configuration_ism_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_tx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_tx_configuration_get(dev_id, index, ®_val); + *value = reg_val.bf.ism; + return ret; +} + +sw_error_t +hppe_mac_tx_configuration_ism_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_tx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_tx_configuration_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ism = value; + ret = hppe_mac_tx_configuration_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_tx_configuration_ifp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_tx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_tx_configuration_get(dev_id, index, ®_val); + *value = reg_val.bf.ifp; + return ret; +} + +sw_error_t +hppe_mac_tx_configuration_ifp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_tx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_tx_configuration_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ifp = value; + ret = hppe_mac_tx_configuration_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_tx_configuration_sarc_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_tx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_tx_configuration_get(dev_id, index, ®_val); + *value = reg_val.bf.sarc; + return ret; +} + +sw_error_t +hppe_mac_tx_configuration_sarc_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_tx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_tx_configuration_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.sarc = value; + ret = hppe_mac_tx_configuration_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_tx_configuration_isr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_tx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_tx_configuration_get(dev_id, index, ®_val); + *value = reg_val.bf.isr; + return ret; +} + +sw_error_t +hppe_mac_tx_configuration_isr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_tx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_tx_configuration_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.isr = value; + ret = hppe_mac_tx_configuration_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_tx_configuration_ss_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_tx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_tx_configuration_get(dev_id, index, ®_val); + *value = reg_val.bf.ss; + return ret; +} + +sw_error_t +hppe_mac_tx_configuration_ss_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_tx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_tx_configuration_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ss = value; + ret = hppe_mac_tx_configuration_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_tx_configuration_g9991en_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_tx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_tx_configuration_get(dev_id, index, ®_val); + *value = reg_val.bf.g9991en; + return ret; +} + +sw_error_t +hppe_mac_tx_configuration_g9991en_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_tx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_tx_configuration_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.g9991en = value; + ret = hppe_mac_tx_configuration_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_tx_configuration_uss_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_tx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_tx_configuration_get(dev_id, index, ®_val); + *value = reg_val.bf.uss; + return ret; +} + +sw_error_t +hppe_mac_tx_configuration_uss_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_tx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_tx_configuration_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.uss = value; + ret = hppe_mac_tx_configuration_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_tx_configuration_vnm_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_tx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_tx_configuration_get(dev_id, index, ®_val); + *value = reg_val.bf.vnm; + return ret; +} + +sw_error_t +hppe_mac_tx_configuration_vnm_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_tx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_tx_configuration_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.vnm = value; + ret = hppe_mac_tx_configuration_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_tx_configuration_jd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_tx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_tx_configuration_get(dev_id, index, ®_val); + *value = reg_val.bf.jd; + return ret; +} +#endif +sw_error_t +hppe_mac_tx_configuration_jd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_tx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_tx_configuration_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.jd = value; + ret = hppe_mac_tx_configuration_set(dev_id, index, ®_val); + return ret; +} +#ifndef IN_PORTCONTROL_MINI + +sw_error_t +hppe_mac_rx_configuration_lm_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_rx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_configuration_get(dev_id, index, ®_val); + *value = reg_val.bf.lm; + return ret; +} + +sw_error_t +hppe_mac_rx_configuration_lm_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_rx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_configuration_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.lm = value; + ret = hppe_mac_rx_configuration_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_rx_configuration_je_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_rx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_configuration_get(dev_id, index, ®_val); + *value = reg_val.bf.je; + return ret; +} + +sw_error_t +hppe_mac_rx_configuration_je_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_rx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_configuration_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.je = value; + ret = hppe_mac_rx_configuration_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_rx_configuration_arpen_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_rx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_configuration_get(dev_id, index, ®_val); + *value = reg_val.bf.arpen; + return ret; +} + +sw_error_t +hppe_mac_rx_configuration_arpen_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_rx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_configuration_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.arpen = value; + ret = hppe_mac_rx_configuration_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_rx_configuration_elen_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_rx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_configuration_get(dev_id, index, ®_val); + *value = reg_val.bf.elen; + return ret; +} + +sw_error_t +hppe_mac_rx_configuration_elen_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_rx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_configuration_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.elen = value; + ret = hppe_mac_rx_configuration_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_rx_configuration_gmpslce_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_rx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_configuration_get(dev_id, index, ®_val); + *value = reg_val.bf.gmpslce; + return ret; +} +#endif +sw_error_t +hppe_mac_rx_configuration_gmpslce_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_rx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_configuration_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.gmpslce = value; + ret = hppe_mac_rx_configuration_set(dev_id, index, ®_val); + return ret; +} +#ifndef IN_PORTCONTROL_MINI + +sw_error_t +hppe_mac_rx_configuration_hdsms_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_rx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_configuration_get(dev_id, index, ®_val); + *value = reg_val.bf.hdsms; + return ret; +} + +sw_error_t +hppe_mac_rx_configuration_hdsms_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_rx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_configuration_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.hdsms = value; + ret = hppe_mac_rx_configuration_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_rx_configuration_spen_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_rx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_configuration_get(dev_id, index, ®_val); + *value = reg_val.bf.spen; + return ret; +} + +sw_error_t +hppe_mac_rx_configuration_spen_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_rx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_configuration_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.spen = value; + ret = hppe_mac_rx_configuration_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_rx_configuration_usp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_rx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_configuration_get(dev_id, index, ®_val); + *value = reg_val.bf.usp; + return ret; +} + +sw_error_t +hppe_mac_rx_configuration_usp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_rx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_configuration_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.usp = value; + ret = hppe_mac_rx_configuration_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_rx_configuration_ipc_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_rx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_configuration_get(dev_id, index, ®_val); + *value = reg_val.bf.ipc; + return ret; +} + +sw_error_t +hppe_mac_rx_configuration_ipc_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_rx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_configuration_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipc = value; + ret = hppe_mac_rx_configuration_set(dev_id, index, ®_val); + return ret; +} +#endif +sw_error_t +hppe_mac_rx_configuration_gpsl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_rx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_configuration_get(dev_id, index, ®_val); + *value = reg_val.bf.gpsl; + return ret; +} + +sw_error_t +hppe_mac_rx_configuration_gpsl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_rx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_configuration_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.gpsl = value; + ret = hppe_mac_rx_configuration_set(dev_id, index, ®_val); + return ret; +} +#ifndef IN_PORTCONTROL_MINI + +sw_error_t +hppe_mac_rx_configuration_re_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_rx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_configuration_get(dev_id, index, ®_val); + *value = reg_val.bf.re; + return ret; +} + +sw_error_t +hppe_mac_rx_configuration_re_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_rx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_configuration_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.re = value; + ret = hppe_mac_rx_configuration_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_rx_configuration_cst_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_rx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_configuration_get(dev_id, index, ®_val); + *value = reg_val.bf.cst; + return ret; +} + +sw_error_t +hppe_mac_rx_configuration_cst_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_rx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_configuration_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cst = value; + ret = hppe_mac_rx_configuration_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_rx_configuration_dcrcc_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_rx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_configuration_get(dev_id, index, ®_val); + *value = reg_val.bf.dcrcc; + return ret; +} + +sw_error_t +hppe_mac_rx_configuration_dcrcc_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_rx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_configuration_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.dcrcc = value; + ret = hppe_mac_rx_configuration_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_rx_configuration_wd_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_rx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_configuration_get(dev_id, index, ®_val); + *value = reg_val.bf.wd; + return ret; +} +#endif +sw_error_t +hppe_mac_rx_configuration_wd_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_rx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_configuration_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.wd = value; + ret = hppe_mac_rx_configuration_set(dev_id, index, ®_val); + return ret; +} +#ifndef IN_PORTCONTROL_MINI + +sw_error_t +hppe_mac_rx_configuration_acs_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_rx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_configuration_get(dev_id, index, ®_val); + *value = reg_val.bf.acs; + return ret; +} + +sw_error_t +hppe_mac_rx_configuration_acs_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_rx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_configuration_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.acs = value; + ret = hppe_mac_rx_configuration_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_rx_configuration_s2kp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_rx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_configuration_get(dev_id, index, ®_val); + *value = reg_val.bf.s2kp; + return ret; +} + +sw_error_t +hppe_mac_rx_configuration_s2kp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_rx_configuration_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_configuration_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.s2kp = value; + ret = hppe_mac_rx_configuration_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_packet_filter_pcf_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_packet_filter_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_packet_filter_get(dev_id, index, ®_val); + *value = reg_val.bf.pcf; + return ret; +} +#endif +sw_error_t +hppe_mac_packet_filter_pcf_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_packet_filter_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_packet_filter_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pcf = value; + ret = hppe_mac_packet_filter_set(dev_id, index, ®_val); + return ret; +} +#ifndef IN_PORTCONTROL_MINI + +sw_error_t +hppe_mac_packet_filter_hmc_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_packet_filter_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_packet_filter_get(dev_id, index, ®_val); + *value = reg_val.bf.hmc; + return ret; +} + +sw_error_t +hppe_mac_packet_filter_hmc_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_packet_filter_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_packet_filter_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.hmc = value; + ret = hppe_mac_packet_filter_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_packet_filter_dntu_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_packet_filter_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_packet_filter_get(dev_id, index, ®_val); + *value = reg_val.bf.dntu; + return ret; +} + +sw_error_t +hppe_mac_packet_filter_dntu_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_packet_filter_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_packet_filter_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.dntu = value; + ret = hppe_mac_packet_filter_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_packet_filter_saf_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_packet_filter_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_packet_filter_get(dev_id, index, ®_val); + *value = reg_val.bf.saf; + return ret; +} + +sw_error_t +hppe_mac_packet_filter_saf_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_packet_filter_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_packet_filter_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.saf = value; + ret = hppe_mac_packet_filter_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_packet_filter_dbf_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_packet_filter_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_packet_filter_get(dev_id, index, ®_val); + *value = reg_val.bf.dbf; + return ret; +} + +sw_error_t +hppe_mac_packet_filter_dbf_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_packet_filter_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_packet_filter_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.dbf = value; + ret = hppe_mac_packet_filter_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_packet_filter_huc_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_packet_filter_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_packet_filter_get(dev_id, index, ®_val); + *value = reg_val.bf.huc; + return ret; +} + +sw_error_t +hppe_mac_packet_filter_huc_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_packet_filter_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_packet_filter_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.huc = value; + ret = hppe_mac_packet_filter_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_packet_filter_vtfe_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_packet_filter_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_packet_filter_get(dev_id, index, ®_val); + *value = reg_val.bf.vtfe; + return ret; +} + +sw_error_t +hppe_mac_packet_filter_vtfe_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_packet_filter_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_packet_filter_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.vtfe = value; + ret = hppe_mac_packet_filter_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_packet_filter_daif_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_packet_filter_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_packet_filter_get(dev_id, index, ®_val); + *value = reg_val.bf.daif; + return ret; +} + +sw_error_t +hppe_mac_packet_filter_daif_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_packet_filter_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_packet_filter_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.daif = value; + ret = hppe_mac_packet_filter_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_packet_filter_ra_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_packet_filter_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_packet_filter_get(dev_id, index, ®_val); + *value = reg_val.bf.ra; + return ret; +} + +sw_error_t +hppe_mac_packet_filter_ra_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_packet_filter_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_packet_filter_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ra = value; + ret = hppe_mac_packet_filter_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_packet_filter_hpf_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_packet_filter_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_packet_filter_get(dev_id, index, ®_val); + *value = reg_val.bf.hpf; + return ret; +} + +sw_error_t +hppe_mac_packet_filter_hpf_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_packet_filter_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_packet_filter_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.hpf = value; + ret = hppe_mac_packet_filter_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_packet_filter_pm_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_packet_filter_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_packet_filter_get(dev_id, index, ®_val); + *value = reg_val.bf.pm; + return ret; +} + +sw_error_t +hppe_mac_packet_filter_pm_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_packet_filter_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_packet_filter_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pm = value; + ret = hppe_mac_packet_filter_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_packet_filter_vucc_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_packet_filter_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_packet_filter_get(dev_id, index, ®_val); + *value = reg_val.bf.vucc; + return ret; +} + +sw_error_t +hppe_mac_packet_filter_vucc_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_packet_filter_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_packet_filter_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.vucc = value; + ret = hppe_mac_packet_filter_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_packet_filter_pr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_packet_filter_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_packet_filter_get(dev_id, index, ®_val); + *value = reg_val.bf.pr; + return ret; +} +#endif +sw_error_t +hppe_mac_packet_filter_pr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_packet_filter_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_packet_filter_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pr = value; + ret = hppe_mac_packet_filter_set(dev_id, index, ®_val); + return ret; +} +#ifndef IN_PORTCONTROL_MINI + +sw_error_t +hppe_mac_packet_filter_ipfe_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_packet_filter_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_packet_filter_get(dev_id, index, ®_val); + *value = reg_val.bf.ipfe; + return ret; +} + +sw_error_t +hppe_mac_packet_filter_ipfe_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_packet_filter_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_packet_filter_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipfe = value; + ret = hppe_mac_packet_filter_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_packet_filter_saif_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_packet_filter_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_packet_filter_get(dev_id, index, ®_val); + *value = reg_val.bf.saif; + return ret; +} + +sw_error_t +hppe_mac_packet_filter_saif_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_packet_filter_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_packet_filter_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.saif = value; + ret = hppe_mac_packet_filter_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_watchdog_timeout_pwe_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_watchdog_timeout_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_watchdog_timeout_get(dev_id, index, ®_val); + *value = reg_val.bf.pwe; + return ret; +} + +sw_error_t +hppe_mac_watchdog_timeout_pwe_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_watchdog_timeout_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_watchdog_timeout_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pwe = value; + ret = hppe_mac_watchdog_timeout_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_watchdog_timeout_wto_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_watchdog_timeout_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_watchdog_timeout_get(dev_id, index, ®_val); + *value = reg_val.bf.wto; + return ret; +} + +sw_error_t +hppe_mac_watchdog_timeout_wto_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_watchdog_timeout_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_watchdog_timeout_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.wto = value; + ret = hppe_mac_watchdog_timeout_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_vlan_tag_eivls_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_vlan_tag_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_vlan_tag_get(dev_id, index, ®_val); + *value = reg_val.bf.eivls; + return ret; +} + +sw_error_t +hppe_mac_vlan_tag_eivls_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_vlan_tag_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_vlan_tag_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.eivls = value; + ret = hppe_mac_vlan_tag_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_vlan_tag_vthm_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_vlan_tag_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_vlan_tag_get(dev_id, index, ®_val); + *value = reg_val.bf.vthm; + return ret; +} + +sw_error_t +hppe_mac_vlan_tag_vthm_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_vlan_tag_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_vlan_tag_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.vthm = value; + ret = hppe_mac_vlan_tag_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_vlan_tag_vl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_vlan_tag_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_vlan_tag_get(dev_id, index, ®_val); + *value = reg_val.bf.vl; + return ret; +} + +sw_error_t +hppe_mac_vlan_tag_vl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_vlan_tag_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_vlan_tag_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.vl = value; + ret = hppe_mac_vlan_tag_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_vlan_tag_dovltc_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_vlan_tag_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_vlan_tag_get(dev_id, index, ®_val); + *value = reg_val.bf.dovltc; + return ret; +} + +sw_error_t +hppe_mac_vlan_tag_dovltc_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_vlan_tag_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_vlan_tag_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.dovltc = value; + ret = hppe_mac_vlan_tag_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_vlan_tag_etv_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_vlan_tag_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_vlan_tag_get(dev_id, index, ®_val); + *value = reg_val.bf.etv; + return ret; +} + +sw_error_t +hppe_mac_vlan_tag_etv_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_vlan_tag_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_vlan_tag_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.etv = value; + ret = hppe_mac_vlan_tag_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_vlan_tag_erivlt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_vlan_tag_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_vlan_tag_get(dev_id, index, ®_val); + *value = reg_val.bf.erivlt; + return ret; +} + +sw_error_t +hppe_mac_vlan_tag_erivlt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_vlan_tag_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_vlan_tag_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.erivlt = value; + ret = hppe_mac_vlan_tag_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_vlan_tag_eivlrxs_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_vlan_tag_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_vlan_tag_get(dev_id, index, ®_val); + *value = reg_val.bf.eivlrxs; + return ret; +} + +sw_error_t +hppe_mac_vlan_tag_eivlrxs_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_vlan_tag_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_vlan_tag_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.eivlrxs = value; + ret = hppe_mac_vlan_tag_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_vlan_tag_vtim_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_vlan_tag_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_vlan_tag_get(dev_id, index, ®_val); + *value = reg_val.bf.vtim; + return ret; +} + +sw_error_t +hppe_mac_vlan_tag_vtim_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_vlan_tag_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_vlan_tag_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.vtim = value; + ret = hppe_mac_vlan_tag_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_vlan_tag_edvlp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_vlan_tag_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_vlan_tag_get(dev_id, index, ®_val); + *value = reg_val.bf.edvlp; + return ret; +} + +sw_error_t +hppe_mac_vlan_tag_edvlp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_vlan_tag_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_vlan_tag_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.edvlp = value; + ret = hppe_mac_vlan_tag_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_vlan_tag_evlrxs_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_vlan_tag_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_vlan_tag_get(dev_id, index, ®_val); + *value = reg_val.bf.evlrxs; + return ret; +} + +sw_error_t +hppe_mac_vlan_tag_evlrxs_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_vlan_tag_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_vlan_tag_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.evlrxs = value; + ret = hppe_mac_vlan_tag_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_vlan_tag_evls_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_vlan_tag_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_vlan_tag_get(dev_id, index, ®_val); + *value = reg_val.bf.evls; + return ret; +} + +sw_error_t +hppe_mac_vlan_tag_evls_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_vlan_tag_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_vlan_tag_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.evls = value; + ret = hppe_mac_vlan_tag_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_vlan_tag_esvl_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_vlan_tag_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_vlan_tag_get(dev_id, index, ®_val); + *value = reg_val.bf.esvl; + return ret; +} + +sw_error_t +hppe_mac_vlan_tag_esvl_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_vlan_tag_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_vlan_tag_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.esvl = value; + ret = hppe_mac_vlan_tag_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_vlan_tag_ersvlm_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_vlan_tag_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_vlan_tag_get(dev_id, index, ®_val); + *value = reg_val.bf.ersvlm; + return ret; +} + +sw_error_t +hppe_mac_vlan_tag_ersvlm_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_vlan_tag_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_vlan_tag_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ersvlm = value; + ret = hppe_mac_vlan_tag_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_rx_eth_type_match_et_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_rx_eth_type_match_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_eth_type_match_get(dev_id, index, ®_val); + *value = reg_val.bf.et; + return ret; +} + +sw_error_t +hppe_mac_rx_eth_type_match_et_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_rx_eth_type_match_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_eth_type_match_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.et = value; + ret = hppe_mac_rx_eth_type_match_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_q0_tx_flow_ctrl_pt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_q0_tx_flow_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_q0_tx_flow_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.pt; + return ret; +} + +sw_error_t +hppe_mac_q0_tx_flow_ctrl_pt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_q0_tx_flow_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_q0_tx_flow_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pt = value; + ret = hppe_mac_q0_tx_flow_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_q0_tx_flow_ctrl_plt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_q0_tx_flow_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_q0_tx_flow_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.plt; + return ret; +} + +sw_error_t +hppe_mac_q0_tx_flow_ctrl_plt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_q0_tx_flow_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_q0_tx_flow_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.plt = value; + ret = hppe_mac_q0_tx_flow_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_q0_tx_flow_ctrl_tfe_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_q0_tx_flow_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_q0_tx_flow_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.tfe; + return ret; +} + +sw_error_t +hppe_mac_q0_tx_flow_ctrl_tfe_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_q0_tx_flow_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_q0_tx_flow_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tfe = value; + ret = hppe_mac_q0_tx_flow_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_q0_tx_flow_ctrl_fcb_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_q0_tx_flow_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_q0_tx_flow_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.fcb; + return ret; +} + +sw_error_t +hppe_mac_q0_tx_flow_ctrl_fcb_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_q0_tx_flow_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_q0_tx_flow_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.fcb = value; + ret = hppe_mac_q0_tx_flow_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_q0_tx_flow_ctrl_dapq_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_q0_tx_flow_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_q0_tx_flow_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.dapq; + return ret; +} + +sw_error_t +hppe_mac_q0_tx_flow_ctrl_dapq_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_q0_tx_flow_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_q0_tx_flow_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.dapq = value; + ret = hppe_mac_q0_tx_flow_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_rx_flow_ctrl_pfce_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_rx_flow_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_flow_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.pfce; + return ret; +} + +sw_error_t +hppe_mac_rx_flow_ctrl_pfce_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_rx_flow_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_flow_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pfce = value; + ret = hppe_mac_rx_flow_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_rx_flow_ctrl_up_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_rx_flow_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_flow_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.up; + return ret; +} + +sw_error_t +hppe_mac_rx_flow_ctrl_up_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_rx_flow_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_flow_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.up = value; + ret = hppe_mac_rx_flow_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_rx_flow_ctrl_rfe_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_rx_flow_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_flow_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.rfe; + return ret; +} + +sw_error_t +hppe_mac_rx_flow_ctrl_rfe_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_rx_flow_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_flow_ctrl_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rfe = value; + ret = hppe_mac_rx_flow_ctrl_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_interrupt_status_txesis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_interrupt_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_interrupt_status_get(dev_id, index, ®_val); + *value = reg_val.bf.txesis; + return ret; +} + +sw_error_t +hppe_mac_interrupt_status_txesis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_interrupt_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_interrupt_status_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.txesis = value; + ret = hppe_mac_interrupt_status_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_interrupt_status_gpiis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_interrupt_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_interrupt_status_get(dev_id, index, ®_val); + *value = reg_val.bf.gpiis; + return ret; +} + +sw_error_t +hppe_mac_interrupt_status_gpiis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_interrupt_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_interrupt_status_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.gpiis = value; + ret = hppe_mac_interrupt_status_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_interrupt_status_tsis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_interrupt_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_interrupt_status_get(dev_id, index, ®_val); + *value = reg_val.bf.tsis; + return ret; +} + +sw_error_t +hppe_mac_interrupt_status_tsis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_interrupt_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_interrupt_status_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tsis = value; + ret = hppe_mac_interrupt_status_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_interrupt_status_mmctxis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_interrupt_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_interrupt_status_get(dev_id, index, ®_val); + *value = reg_val.bf.mmctxis; + return ret; +} + +sw_error_t +hppe_mac_interrupt_status_mmctxis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_interrupt_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_interrupt_status_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mmctxis = value; + ret = hppe_mac_interrupt_status_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_interrupt_status_ls_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_interrupt_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_interrupt_status_get(dev_id, index, ®_val); + *value = reg_val.bf.ls; + return ret; +} + +sw_error_t +hppe_mac_interrupt_status_ls_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_interrupt_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_interrupt_status_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ls = value; + ret = hppe_mac_interrupt_status_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_interrupt_status_mmcrxis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_interrupt_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_interrupt_status_get(dev_id, index, ®_val); + *value = reg_val.bf.mmcrxis; + return ret; +} + +sw_error_t +hppe_mac_interrupt_status_mmcrxis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_interrupt_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_interrupt_status_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mmcrxis = value; + ret = hppe_mac_interrupt_status_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_interrupt_status_smi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_interrupt_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_interrupt_status_get(dev_id, index, ®_val); + *value = reg_val.bf.smi; + return ret; +} + +sw_error_t +hppe_mac_interrupt_status_smi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_interrupt_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_interrupt_status_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.smi = value; + ret = hppe_mac_interrupt_status_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_interrupt_status_pmtis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_interrupt_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_interrupt_status_get(dev_id, index, ®_val); + *value = reg_val.bf.pmtis; + return ret; +} + +sw_error_t +hppe_mac_interrupt_status_pmtis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_interrupt_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_interrupt_status_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pmtis = value; + ret = hppe_mac_interrupt_status_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_interrupt_status_rxesis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_interrupt_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_interrupt_status_get(dev_id, index, ®_val); + *value = reg_val.bf.rxesis; + return ret; +} + +sw_error_t +hppe_mac_interrupt_status_rxesis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_interrupt_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_interrupt_status_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rxesis = value; + ret = hppe_mac_interrupt_status_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_interrupt_status_lpiis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_interrupt_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_interrupt_status_get(dev_id, index, ®_val); + *value = reg_val.bf.lpiis; + return ret; +} + +sw_error_t +hppe_mac_interrupt_status_lpiis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_interrupt_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_interrupt_status_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.lpiis = value; + ret = hppe_mac_interrupt_status_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_interrupt_enable_tsie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.tsie; + return ret; +} + +sw_error_t +hppe_mac_interrupt_enable_tsie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mac_interrupt_enable_lpiie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.lpiie; + return ret; +} + +sw_error_t +hppe_mac_interrupt_enable_lpiie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mac_interrupt_enable_txesie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.txesie; + return ret; +} + +sw_error_t +hppe_mac_interrupt_enable_txesie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mac_interrupt_enable_pmtie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.pmtie; + return ret; +} + +sw_error_t +hppe_mac_interrupt_enable_pmtie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mac_interrupt_enable_rxesie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.rxesie; + return ret; +} + +sw_error_t +hppe_mac_interrupt_enable_rxesie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mac_rx_tx_status_tjt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_rx_tx_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_tx_status_get(dev_id, index, ®_val); + *value = reg_val.bf.tjt; + return ret; +} + +sw_error_t +hppe_mac_rx_tx_status_tjt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_rx_tx_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_tx_status_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tjt = value; + ret = hppe_mac_rx_tx_status_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_rx_tx_status_rwt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_rx_tx_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_tx_status_get(dev_id, index, ®_val); + *value = reg_val.bf.rwt; + return ret; +} + +sw_error_t +hppe_mac_rx_tx_status_rwt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_rx_tx_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_rx_tx_status_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rwt = value; + ret = hppe_mac_rx_tx_status_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_lpi_control_status_tlpien_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_lpi_control_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_lpi_control_status_get(dev_id, index, ®_val); + *value = reg_val.bf.tlpien; + return ret; +} + +sw_error_t +hppe_mac_lpi_control_status_tlpien_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_lpi_control_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_lpi_control_status_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tlpien = value; + ret = hppe_mac_lpi_control_status_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_lpi_control_status_lpitcse_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_lpi_control_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_lpi_control_status_get(dev_id, index, ®_val); + *value = reg_val.bf.lpitcse; + return ret; +} + +sw_error_t +hppe_mac_lpi_control_status_lpitcse_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_lpi_control_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_lpi_control_status_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.lpitcse = value; + ret = hppe_mac_lpi_control_status_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_lpi_control_status_rxrstp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_lpi_control_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_lpi_control_status_get(dev_id, index, ®_val); + *value = reg_val.bf.rxrstp; + return ret; +} + +sw_error_t +hppe_mac_lpi_control_status_rxrstp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_lpi_control_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_lpi_control_status_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rxrstp = value; + ret = hppe_mac_lpi_control_status_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_lpi_control_status_lpite_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_lpi_control_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_lpi_control_status_get(dev_id, index, ®_val); + *value = reg_val.bf.lpite; + return ret; +} + +sw_error_t +hppe_mac_lpi_control_status_lpite_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_lpi_control_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_lpi_control_status_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.lpite = value; + ret = hppe_mac_lpi_control_status_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_lpi_control_status_pls_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_lpi_control_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_lpi_control_status_get(dev_id, index, ®_val); + *value = reg_val.bf.pls; + return ret; +} + +sw_error_t +hppe_mac_lpi_control_status_pls_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_lpi_control_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_lpi_control_status_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pls = value; + ret = hppe_mac_lpi_control_status_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_lpi_control_status_rlpiex_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_lpi_control_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_lpi_control_status_get(dev_id, index, ®_val); + *value = reg_val.bf.rlpiex; + return ret; +} + +sw_error_t +hppe_mac_lpi_control_status_rlpiex_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_lpi_control_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_lpi_control_status_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rlpiex = value; + ret = hppe_mac_lpi_control_status_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_lpi_control_status_rlpien_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_lpi_control_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_lpi_control_status_get(dev_id, index, ®_val); + *value = reg_val.bf.rlpien; + return ret; +} + +sw_error_t +hppe_mac_lpi_control_status_rlpien_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_lpi_control_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_lpi_control_status_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rlpien = value; + ret = hppe_mac_lpi_control_status_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_lpi_control_status_rlpist_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_lpi_control_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_lpi_control_status_get(dev_id, index, ®_val); + *value = reg_val.bf.rlpist; + return ret; +} + +sw_error_t +hppe_mac_lpi_control_status_rlpist_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_lpi_control_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_lpi_control_status_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rlpist = value; + ret = hppe_mac_lpi_control_status_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_lpi_control_status_tlpist_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_lpi_control_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_lpi_control_status_get(dev_id, index, ®_val); + *value = reg_val.bf.tlpist; + return ret; +} + +sw_error_t +hppe_mac_lpi_control_status_tlpist_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_lpi_control_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_lpi_control_status_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tlpist = value; + ret = hppe_mac_lpi_control_status_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_lpi_control_status_txrstp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_lpi_control_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_lpi_control_status_get(dev_id, index, ®_val); + *value = reg_val.bf.txrstp; + return ret; +} + +sw_error_t +hppe_mac_lpi_control_status_txrstp_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_lpi_control_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_lpi_control_status_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.txrstp = value; + ret = hppe_mac_lpi_control_status_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_lpi_control_status_plsdis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_lpi_control_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_lpi_control_status_get(dev_id, index, ®_val); + *value = reg_val.bf.plsdis; + return ret; +} + +sw_error_t +hppe_mac_lpi_control_status_plsdis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_lpi_control_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_lpi_control_status_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.plsdis = value; + ret = hppe_mac_lpi_control_status_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_lpi_control_status_lpitxa_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_lpi_control_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_lpi_control_status_get(dev_id, index, ®_val); + *value = reg_val.bf.lpitxa; + return ret; +} + +sw_error_t +hppe_mac_lpi_control_status_lpitxa_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_lpi_control_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_lpi_control_status_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.lpitxa = value; + ret = hppe_mac_lpi_control_status_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_lpi_control_status_tlpiex_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_lpi_control_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_lpi_control_status_get(dev_id, index, ®_val); + *value = reg_val.bf.tlpiex; + return ret; +} + +sw_error_t +hppe_mac_lpi_control_status_tlpiex_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_lpi_control_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_lpi_control_status_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tlpiex = value; + ret = hppe_mac_lpi_control_status_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_lpi_control_status_lpitxen_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_lpi_control_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_lpi_control_status_get(dev_id, index, ®_val); + *value = reg_val.bf.lpitxen; + return ret; +} + +sw_error_t +hppe_mac_lpi_control_status_lpitxen_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + union mac_lpi_control_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_lpi_control_status_get(dev_id, index, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.lpitxen = value; + ret = hppe_mac_lpi_control_status_set(dev_id, index, ®_val); + return ret; +} + +sw_error_t +hppe_mac_lpi_timers_control_lst_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_lpi_timers_control_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_lpi_timers_control_get(dev_id, index, ®_val); + *value = reg_val.bf.lst; + return ret; +} + +sw_error_t +hppe_mac_lpi_timers_control_lst_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mac_lpi_timers_control_twt_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_lpi_timers_control_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_lpi_timers_control_get(dev_id, index, ®_val); + *value = reg_val.bf.twt; + return ret; +} + +sw_error_t +hppe_mac_lpi_timers_control_twt_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mac_lpi_auto_entry_timer_lpiet_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_lpi_auto_entry_timer_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_lpi_auto_entry_timer_get(dev_id, index, ®_val); + *value = reg_val.bf.lpiet; + return ret; +} + +sw_error_t +hppe_mac_lpi_auto_entry_timer_lpiet_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mac_1us_tic_counter_tic_1us_cntr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_1us_tic_counter_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_1us_tic_counter_get(dev_id, index, ®_val); + *value = reg_val.bf.tic_1us_cntr; + return ret; +} + +sw_error_t +hppe_mac_1us_tic_counter_tic_1us_cntr_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mac_address0_high_addrhi_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_address0_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_address0_high_get(dev_id, index, ®_val); + *value = reg_val.bf.addrhi; + return ret; +} + +sw_error_t +hppe_mac_address0_high_addrhi_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mac_address0_high_ae_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_address0_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_address0_high_get(dev_id, index, ®_val); + *value = reg_val.bf.ae; + return ret; +} + +sw_error_t +hppe_mac_address0_high_ae_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mac_address0_high_dcs_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_address0_high_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_address0_high_get(dev_id, index, ®_val); + *value = reg_val.bf.dcs; + return ret; +} + +sw_error_t +hppe_mac_address0_high_dcs_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mac_address0_low_addrlo_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mac_address0_low_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mac_address0_low_get(dev_id, index, ®_val); + *value = reg_val.bf.addrlo; + return ret; +} + +sw_error_t +hppe_mac_address0_low_addrlo_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxorangefis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.rxorangefis; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxorangefis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxlenerfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.rxlenerfis; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxlenerfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_rx65t127octgbfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.rx65t127octgbfis; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_rx65t127octgbfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxprmmcis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.rxprmmcis; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxprmmcis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_rx512t1023octgbfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.rx512t1023octgbfis; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_rx512t1023octgbfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxgboctis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.rxgboctis; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxgboctis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxlpiuscis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.rxlpiuscis; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxlpiuscis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxjaberfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.rxjaberfis; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxjaberfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxvlangbfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.rxvlangbfis; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxvlangbfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxpausfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.rxpausfis; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxpausfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxcrcerfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.rxcrcerfis; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxcrcerfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxdisocgbis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.rxdisocgbis; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxdisocgbis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxwdogfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.rxwdogfis; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxwdogfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_rx128t255octgbfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.rx128t255octgbfis; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_rx128t255octgbfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxdisfcgbis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.rxdisfcgbis; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxdisfcgbis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxosizegfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.rxosizegfis; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxosizegfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_rx1024tmaxoctgbfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.rx1024tmaxoctgbfis; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_rx1024tmaxoctgbfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxruntfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.rxruntfis; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxruntfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxmcgfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.rxmcgfis; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxmcgfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_rx256t511octgbfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.rx256t511octgbfis; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_rx256t511octgbfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_rx64octgbfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.rx64octgbfis; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_rx64octgbfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxfovfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.rxfovfis; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxfovfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxgoctis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.rxgoctis; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxgoctis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxgbfrmis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.rxgbfrmis; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxgbfrmis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxlpitrcis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.rxlpitrcis; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxlpitrcis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxbcgfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.rxbcgfis; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxbcgfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxusizegfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.rxusizegfis; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxusizegfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxucgfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.rxucgfis; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_rxucgfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_txgbfrmis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.txgbfrmis; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_txgbfrmis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_txprmmcis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.txprmmcis; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_txprmmcis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_tx1024tmaxoctgbfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.tx1024tmaxoctgbfis; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_tx1024tmaxoctgbfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_tx256t511octgbfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.tx256t511octgbfis; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_tx256t511octgbfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_txlpitrcis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.txlpitrcis; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_txlpitrcis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_txbcgfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.txbcgfis; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_txbcgfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_tx64octgbfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.tx64octgbfis; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_tx64octgbfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_txlpiuscis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.txlpiuscis; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_txlpiuscis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_txuflowerfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.txuflowerfis; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_txuflowerfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_txbcgbfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.txbcgbfis; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_txbcgbfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_txpausfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.txpausfis; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_txpausfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_txvlangfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.txvlangfis; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_txvlangfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_txgboctis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.txgboctis; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_txgboctis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_txgfrmis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.txgfrmis; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_txgfrmis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_tx512t1023octgbfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.tx512t1023octgbfis; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_tx512t1023octgbfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_txmcgfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.txmcgfis; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_txmcgfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_txucgbfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.txucgbfis; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_txucgbfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_tx65t127octgbfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.tx65t127octgbfis; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_tx65t127octgbfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_txmcgbfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.txmcgbfis; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_txmcgbfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_tx128t255octgbfis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.tx128t255octgbfis; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_tx128t255octgbfis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_txgoctis_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_get(dev_id, index, ®_val); + *value = reg_val.bf.txgoctis; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_txgoctis_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxprmmcise_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.rxprmmcise; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxprmmcise_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rx65t127octgbfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.rx65t127octgbfie; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rx65t127octgbfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxruntfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.rxruntfie; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxruntfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxcrcerfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.rxcrcerfie; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxcrcerfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rx256t511octgbfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.rx256t511octgbfie; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rx256t511octgbfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxlenerfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.rxlenerfie; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxlenerfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxusizegfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.rxusizegfie; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxusizegfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxosizegfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.rxosizegfie; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxosizegfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxfovfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.rxfovfie; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxfovfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxmcgfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.rxmcgfie; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxmcgfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxvlangbfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.rxvlangbfie; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxvlangbfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxwdogfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.rxwdogfie; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxwdogfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxdisocie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.rxdisocie; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxdisocie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxgbfrmie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.rxgbfrmie; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxgbfrmie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxjaberfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.rxjaberfie; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxjaberfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxlpiuscie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.rxlpiuscie; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxlpiuscie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxucgfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.rxucgfie; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxucgfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rx1024tmaxoctgbfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.rx1024tmaxoctgbfie; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rx1024tmaxoctgbfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxpausfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.rxpausfie; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxpausfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxdisfcie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.rxdisfcie; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxdisfcie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxgoctie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.rxgoctie; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxgoctie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxgboctie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.rxgboctie; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxgboctie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rx128t255octgbfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.rx128t255octgbfie; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rx128t255octgbfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxlpitrcie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.rxlpitrcie; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxlpitrcie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxbcgfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.rxbcgfie; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxbcgfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rx64octgbfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.rx64octgbfie; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rx64octgbfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxorangefie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.rxorangefie; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rxorangefie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rx512t1023octgbfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_receive_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_receive_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.rx512t1023octgbfie; + return ret; +} + +sw_error_t +hppe_mmc_receive_interrupt_enable_rx512t1023octgbfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txucgbfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.txucgbfie; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txucgbfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_tx64octgbfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.tx64octgbfie; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_tx64octgbfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txbcgfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.txbcgfie; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txbcgfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txgbfrmie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.txgbfrmie; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txgbfrmie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txgfrmie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.txgfrmie; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txgfrmie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txgoctie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.txgoctie; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txgoctie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txbcgbfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.txbcgbfie; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txbcgbfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txlpitrcie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.txlpitrcie; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txlpitrcie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txvlangfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.txvlangfie; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txvlangfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txpausfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.txpausfie; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txpausfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txgboctie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.txgboctie; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txgboctie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txmcgfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.txmcgfie; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txmcgfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txuflowerfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.txuflowerfie; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txuflowerfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txlpiuscie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.txlpiuscie; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txlpiuscie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_tx256t511octgbfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.tx256t511octgbfie; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_tx256t511octgbfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_tx65t127octgbfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.tx65t127octgbfie; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_tx65t127octgbfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_tx128t255octgbfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.tx128t255octgbfie; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_tx128t255octgbfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_tx512t1023octgbfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.tx512t1023octgbfie; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_tx512t1023octgbfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_tx1024tmaxoctgbfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.tx1024tmaxoctgbfie; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_tx1024tmaxoctgbfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txprmmcise_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.txprmmcise; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txprmmcise_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txmcgbfie_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union mmc_transmit_interrupt_enable_u reg_val; + sw_error_t ret = SW_OK; + + ret = hppe_mmc_transmit_interrupt_enable_get(dev_id, index, ®_val); + *value = reg_val.bf.txmcgbfie; + return ret; +} + +sw_error_t +hppe_mmc_transmit_interrupt_enable_txmcgbfie_set( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t value) +{ + return SW_NOT_SUPPORTED; +} +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/hsl_acl.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/hsl_acl.c new file mode 100755 index 000000000..2361fae49 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/hsl_acl.c @@ -0,0 +1,972 @@ +/* + * Copyright (c) 2012, 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. + */ + + +#include "sw_config.h" +#include "aos_head.h" +#include "sw_error.h" +#include "shared_func.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_acl.h" + +typedef struct +{ + a_uint32_t pri; + a_uint32_t addr; + a_uint32_t size; + a_uint32_t status; + a_uint32_t info; +} hsl_acl_blk_t; + +typedef struct +{ + a_uint32_t used_blk; + a_uint32_t total_blk; + a_uint32_t free_rsc; + hsl_acl_blk_t *blk_ent; +} hsl_acl_pool_t; + +#define MEM_FREE 1 +#define MEM_USED 2 + +static hsl_acl_pool_t acl_pool[SW_MAX_NR_DEV]; + +static sw_error_t +_hsl_acl_blk_loc(a_uint32_t dev_id, a_uint32_t addr, a_uint32_t * idx); + +static sw_error_t +_hsl_acl_blk_comb(a_uint32_t dev_id, a_uint32_t idx, a_uint32_t nr); + +static sw_error_t _hsl_acl_free_blk_comb(a_uint32_t dev_id, a_uint32_t idx); + +static sw_error_t +_hsl_acl_blk_ent_left_mv(a_uint32_t dev_id, a_uint32_t idx, a_uint32_t offset); + +static sw_error_t +_hsl_acl_blk_ent_right_mv(a_uint32_t dev_id, a_uint32_t idx, a_uint32_t offset); + +static sw_error_t +_hsl_acl_blk_left_defrag(a_uint32_t dev_id, a_uint32_t p_idx, a_uint32_t t_size, + a_bool_t b_must, a_uint32_t * f_idx, a_uint32_t * f_nr, + a_uint32_t * f_size); + +static sw_error_t +_hsl_acl_blk_right_defrag(a_uint32_t dev_id, a_uint32_t p_idx, + a_uint32_t t_size, a_bool_t b_must, + a_uint32_t * f_idx, a_uint32_t * f_nr, + a_uint32_t * f_size); + +static sw_error_t +_hsl_acl_blk_alloc(a_uint32_t dev_id, a_uint32_t free_idx, a_uint32_t pri, + a_uint32_t size, a_uint32_t info, a_uint32_t * addr); + +static sw_error_t +_hsl_acl_blk_reduce(a_uint32_t dev_id, a_uint32_t idx, a_uint32_t new_size); + +static sw_error_t +_hsl_acl_blk_left_enlarge(a_uint32_t dev_id, a_uint32_t idx, + a_uint32_t new_size); + +static sw_error_t +_hsl_acl_blk_right_enlarge(a_uint32_t dev_id, a_uint32_t idx, + a_uint32_t new_size); + +static sw_error_t +_hsl_acl_rule_copy(a_uint32_t dev_id, a_uint32_t src_addr, a_uint32_t dest_addr, + a_uint32_t size); + +static sw_error_t +_hsl_acl_rule_invalid(a_uint32_t dev_id, a_uint32_t addr, a_uint32_t size); + +static sw_error_t +_hsl_acl_addr_update(a_uint32_t dev_id, a_uint32_t old_addr, + a_uint32_t new_addr, a_uint32_t info); + +//#define ACL_POOL_DEBUG +#ifdef ACL_POOL_DEBUG +static void +_hsl_acl_blk_dump(a_uint32_t dev_id, const char *info) +{ + a_uint32_t i; + + aos_printk("\n%s dev_id=%d free_rsc=%d total_blk=%d used_blk=%d", + info, dev_id, acl_pool[dev_id].free_rsc, + acl_pool[dev_id].total_blk, acl_pool[dev_id].used_blk); + + for (i = 0; i < acl_pool[dev_id].used_blk; i++) + { + aos_printk("\naddr=%d status = %d size=%d list_id=%d list_pri=%d", + acl_pool[dev_id].blk_ent[i].addr, + acl_pool[dev_id].blk_ent[i].status, + acl_pool[dev_id].blk_ent[i].size, + acl_pool[dev_id].blk_ent[i].info, + acl_pool[dev_id].blk_ent[i].pri); + } + aos_printk("\n"); +} +#else +#define _hsl_acl_blk_dump(dev_id, info) +#endif + +static sw_error_t +_hsl_acl_blk_loc(a_uint32_t dev_id, a_uint32_t addr, a_uint32_t * idx) +{ + a_uint32_t i; + + for (i = 0; i < acl_pool[dev_id].used_blk; i++) + { + if (addr == acl_pool[dev_id].blk_ent[i].addr) + { + *idx = i; + return SW_OK; + } + } + return SW_NOT_FOUND; +} + +static sw_error_t +_hsl_acl_blk_comb(a_uint32_t dev_id, a_uint32_t idx, a_uint32_t nr) +{ + sw_error_t rv; + a_uint32_t i, size; + + _hsl_acl_blk_dump(dev_id, "_hsl_acl_blk_comb before combine"); + + if ((idx + nr) > acl_pool[dev_id].used_blk) + { + return SW_BAD_PARAM; + } + + if (nr < 2) + { + _hsl_acl_blk_dump(dev_id, "_hsl_acl_blk_comb after combine"); + return SW_OK; + } + + size = 0; + for (i = 0; i < nr; i++) + { + size += acl_pool[dev_id].blk_ent[idx + i].size; + } + acl_pool[dev_id].blk_ent[idx].size = size; + + rv = _hsl_acl_blk_ent_left_mv(dev_id, idx + nr, nr - 1); + _hsl_acl_blk_dump(dev_id, "_hsl_acl_blk_comb after combine"); + return rv; +} + +static sw_error_t +_hsl_acl_free_blk_comb(a_uint32_t dev_id, a_uint32_t idx) +{ + sw_error_t rv; + a_uint32_t first, num; + + _hsl_acl_blk_dump(dev_id, "_hsl_acl_free_blk_comb before combine"); + + first = idx; + num = 1; + if (0 != idx) + { + if (MEM_FREE == acl_pool[dev_id].blk_ent[idx - 1].status) + { + num++; + first = idx - 1; + } + } + + if ((acl_pool[dev_id].used_blk - 1) != idx) + { + if (MEM_FREE == acl_pool[dev_id].blk_ent[idx + 1].status) + { + num++; + } + } + + rv = _hsl_acl_blk_comb(dev_id, first, num); + _hsl_acl_blk_dump(dev_id, "_hsl_acl_free_blk_comb after combine"); + return rv; +} + +static sw_error_t +_hsl_acl_blk_ent_left_mv(a_uint32_t dev_id, a_uint32_t idx, a_uint32_t offset) +{ + a_uint32_t i; + + _hsl_acl_blk_dump(dev_id, "_hsl_acl_blk_ent_left_mv before move"); + + if (offset > idx) + { + return SW_BAD_PARAM; + } + + for (i = idx; i < acl_pool[dev_id].used_blk; i++) + { + acl_pool[dev_id].blk_ent[i - offset] = acl_pool[dev_id].blk_ent[i]; + } + + acl_pool[dev_id].used_blk -= offset; + _hsl_acl_blk_dump(dev_id, "_hsl_acl_blk_ent_left_mv after move"); + return SW_OK; +} + +static sw_error_t +_hsl_acl_blk_ent_right_mv(a_uint32_t dev_id, a_uint32_t idx, a_uint32_t offset) +{ + a_uint32_t i, cnt, tmp; + + _hsl_acl_blk_dump(dev_id, "_hsl_acl_blk_ent_right_mv before move"); + + if (acl_pool[dev_id].total_blk < (acl_pool[dev_id].used_blk + offset)) + { + return SW_BAD_PARAM; + } + + /* we support to increase used block number without block moving */ + if (idx > acl_pool[dev_id].used_blk) + { + return SW_BAD_PARAM; + } + + cnt = acl_pool[dev_id].used_blk - idx; + tmp = acl_pool[dev_id].used_blk - 1; + for (i = 0; i < cnt; i++) + { + acl_pool[dev_id].blk_ent[tmp + offset - i] + = acl_pool[dev_id].blk_ent[tmp - i]; + } + + acl_pool[dev_id].used_blk += offset; + _hsl_acl_blk_dump(dev_id, "_hsl_acl_blk_ent_right_mv after move"); + return SW_OK; +} + +static sw_error_t +_hsl_acl_blk_left_defrag(a_uint32_t dev_id, a_uint32_t p_idx, a_uint32_t t_size, + a_bool_t b_must, a_uint32_t * f_idx, a_uint32_t * f_nr, + a_uint32_t * f_size) +{ + sw_error_t rv; + a_int32_t idx; + a_uint32_t i, f_rsc, f_blk, dest_addr; + + _hsl_acl_blk_dump(dev_id, "_hsl_acl_left_defrag before defrag"); + + f_rsc = 0; + for (idx = p_idx - 1; idx >= 0; idx--) + { + if (MEM_FREE == acl_pool[dev_id].blk_ent[idx].status) + { + f_rsc += acl_pool[dev_id].blk_ent[idx].size; + } + + if (t_size <= f_rsc) + { + break; + } + } + + if ((f_rsc < t_size) && (A_TRUE == b_must)) + { + return SW_NO_RESOURCE; + } + + if (0 == f_rsc) + { + *f_idx = p_idx; + *f_nr = 0; + *f_size = 0; + _hsl_acl_blk_dump(dev_id, "_hsl_acl_left_defrag after defrag"); + return SW_OK; + } + + if (idx < 0) + { + idx = 0; + } + + f_blk = 0; + f_rsc = 0; + dest_addr = acl_pool[dev_id].blk_ent[idx].addr; + for (i = idx; i < p_idx; i++) + { + if (MEM_FREE == acl_pool[dev_id].blk_ent[i].status) + { + f_blk += 1; + f_rsc += acl_pool[dev_id].blk_ent[i].size; + } + + if (MEM_USED == acl_pool[dev_id].blk_ent[i].status) + { + if (dest_addr != acl_pool[dev_id].blk_ent[i].addr) + { + /* update acl rules hardware position */ + rv = _hsl_acl_rule_copy(dev_id, + acl_pool[dev_id].blk_ent[i].addr, + dest_addr, + acl_pool[dev_id].blk_ent[i].size); + SW_RTN_ON_ERROR(rv); + + rv = _hsl_acl_addr_update(dev_id, + acl_pool[dev_id].blk_ent[i].addr, + dest_addr, + acl_pool[dev_id].blk_ent[i].info); + SW_RTN_ON_ERROR(rv); + + /* update acl memory block control infomation */ + acl_pool[dev_id].blk_ent[i - f_blk] = + acl_pool[dev_id].blk_ent[i]; + acl_pool[dev_id].blk_ent[i - f_blk].addr -= f_rsc; + } + dest_addr += acl_pool[dev_id].blk_ent[i].size; + } + } + + for (i = p_idx - f_blk; i < p_idx; i++) + { + acl_pool[dev_id].blk_ent[i].status = MEM_FREE; + acl_pool[dev_id].blk_ent[i].addr = dest_addr; + acl_pool[dev_id].blk_ent[i].size = 0; + acl_pool[dev_id].blk_ent[i].info = 0; + acl_pool[dev_id].blk_ent[i].pri = 0; + } + acl_pool[dev_id].blk_ent[p_idx - f_blk].size = f_rsc; + + *f_idx = p_idx - f_blk; + *f_nr = f_blk; + *f_size = f_rsc; + rv = _hsl_acl_rule_invalid(dev_id, acl_pool[dev_id].blk_ent[*f_idx].addr, + f_rsc); + _hsl_acl_blk_dump(dev_id, "_hsl_acl_left_defrag after defrag"); + return rv; +} + +static sw_error_t +_hsl_acl_blk_right_defrag(a_uint32_t dev_id, a_uint32_t p_idx, + a_uint32_t t_size, a_bool_t b_must, + a_uint32_t * f_idx, a_uint32_t * f_nr, + a_uint32_t * f_size) +{ + sw_error_t rv; + a_uint32_t i, cnt; + a_uint32_t idx, f_rsc, f_blk, dest_addr; + + _hsl_acl_blk_dump(dev_id, "_hsl_acl_right_defrag before defrag"); + + f_rsc = 0; + for (idx = p_idx; idx < acl_pool[dev_id].used_blk; idx++) + { + if (MEM_FREE == acl_pool[dev_id].blk_ent[idx].status) + { + f_rsc += acl_pool[dev_id].blk_ent[idx].size; + } + + if (t_size <= f_rsc) + { + break; + } + } + + if ((f_rsc < t_size) && (A_TRUE == b_must)) + { + return SW_NO_RESOURCE; + } + + if (0 == f_rsc) + { + *f_idx = p_idx; + *f_nr = 0; + *f_size = 0; + _hsl_acl_blk_dump(dev_id, "_hsl_acl_right_defrag after defrag"); + return SW_OK; + } + + if (idx >= acl_pool[dev_id].used_blk) + { + idx = acl_pool[dev_id].used_blk - 1; + } + + f_blk = 0; + f_rsc = 0; + dest_addr = acl_pool[dev_id].blk_ent[idx].addr + + acl_pool[dev_id].blk_ent[idx].size; + for (cnt = 0; cnt <= (idx -p_idx); cnt++) + { + i = idx - cnt; + if (MEM_FREE == acl_pool[dev_id].blk_ent[i].status) + { + f_blk += 1; + f_rsc += acl_pool[dev_id].blk_ent[i].size; + } + + if (MEM_USED == acl_pool[dev_id].blk_ent[i].status) + { + dest_addr -= acl_pool[dev_id].blk_ent[i].size; + + if (dest_addr != acl_pool[dev_id].blk_ent[i].addr) + { + /* update acl rules hardware position */ + rv = _hsl_acl_rule_copy(dev_id, + acl_pool[dev_id].blk_ent[i].addr, + dest_addr, + acl_pool[dev_id].blk_ent[i].size); + SW_RTN_ON_ERROR(rv); + + rv = _hsl_acl_addr_update(dev_id, + acl_pool[dev_id].blk_ent[i].addr, + dest_addr, + acl_pool[dev_id].blk_ent[i].info); + SW_RTN_ON_ERROR(rv); + + /* update acl memory block control infomation */ + acl_pool[dev_id].blk_ent[i + f_blk] = + acl_pool[dev_id].blk_ent[i]; + acl_pool[dev_id].blk_ent[i + f_blk].addr += f_rsc; + } + } + } + + for (i = p_idx; i < (p_idx + f_blk); i++) + { + acl_pool[dev_id].blk_ent[i].status = MEM_FREE; + acl_pool[dev_id].blk_ent[i].size = 0; + acl_pool[dev_id].blk_ent[i].addr = dest_addr - f_rsc; + } + acl_pool[dev_id].blk_ent[p_idx].size = f_rsc; + + *f_idx = p_idx; + *f_nr = f_blk; + *f_size = f_rsc; + rv = _hsl_acl_rule_invalid(dev_id, acl_pool[dev_id].blk_ent[*f_idx].addr, + f_rsc); + _hsl_acl_blk_dump(dev_id, "_hsl_acl_right_defrag after defrag"); + return rv; +} + +static sw_error_t +_hsl_acl_blk_alloc(a_uint32_t dev_id, a_uint32_t free_idx, a_uint32_t pri, + a_uint32_t size, a_uint32_t info, a_uint32_t * addr) +{ + sw_error_t rv; + a_uint32_t i; + a_bool_t b_comb = A_FALSE; + + _hsl_acl_blk_dump(dev_id, "_hsl_acl_blk_alloc before alloc"); + + if (MEM_FREE != acl_pool[dev_id].blk_ent[free_idx].status) + { + return SW_BAD_PARAM; + } + + if (size > acl_pool[dev_id].blk_ent[free_idx].size) + { + return SW_NO_RESOURCE; + } + + if (size != acl_pool[dev_id].blk_ent[free_idx].size) + { + b_comb = A_TRUE; + i = free_idx + 1; + rv = _hsl_acl_blk_ent_right_mv(dev_id, i, 1); + SW_RTN_ON_ERROR(rv); + + acl_pool[dev_id].blk_ent[i].addr = + acl_pool[dev_id].blk_ent[free_idx].addr + size; + acl_pool[dev_id].blk_ent[i].size = + acl_pool[dev_id].blk_ent[free_idx].size - size; + acl_pool[dev_id].blk_ent[i].status = MEM_FREE; + acl_pool[dev_id].blk_ent[i].pri = 0; + acl_pool[dev_id].blk_ent[i].info = 0; + } + + acl_pool[dev_id].blk_ent[free_idx].status = MEM_USED; + acl_pool[dev_id].blk_ent[free_idx].size = size; + acl_pool[dev_id].blk_ent[free_idx].pri = pri; + acl_pool[dev_id].blk_ent[free_idx].info = info; + acl_pool[dev_id].free_rsc -= size; + + if (A_TRUE == b_comb) + { + /* try to combine neighbor free memory blocks */ + rv = _hsl_acl_free_blk_comb(dev_id, free_idx + 1); + SW_RTN_ON_ERROR(rv); + } + + *addr = acl_pool[dev_id].blk_ent[free_idx].addr; + _hsl_acl_blk_dump(dev_id, "_hsl_acl_blk_alloc after alloc"); + return SW_OK; +} + +static sw_error_t +_hsl_acl_blk_reduce(a_uint32_t dev_id, a_uint32_t idx, a_uint32_t new_size) +{ + sw_error_t rv; + a_uint32_t addr, old_size; + + _hsl_acl_blk_dump(dev_id, "_hsl_acl_blk_reduce before reduce"); + + addr = acl_pool[dev_id].blk_ent[idx].addr; + old_size = acl_pool[dev_id].blk_ent[idx].size; + + rv = _hsl_acl_blk_ent_right_mv(dev_id, idx + 1, 1); + SW_RTN_ON_ERROR(rv); + + acl_pool[dev_id].blk_ent[idx].size = new_size; + acl_pool[dev_id].blk_ent[idx + 1].status = MEM_FREE; + acl_pool[dev_id].blk_ent[idx + 1].addr = addr + new_size; + acl_pool[dev_id].blk_ent[idx + 1].size = old_size - new_size; + acl_pool[dev_id].blk_ent[idx + 1].pri = 0; + acl_pool[dev_id].blk_ent[idx + 1].info = 0; + acl_pool[dev_id].free_rsc += (old_size - new_size); + + /* try to combine neighbor free blocks */ + rv = _hsl_acl_free_blk_comb(dev_id, idx + 1); + SW_RTN_ON_ERROR(rv); + + rv = _hsl_acl_rule_invalid(dev_id, addr + new_size, old_size - new_size); + _hsl_acl_blk_dump(dev_id, "_hsl_acl_blk_reduce after reduce"); + return rv; +} + +static sw_error_t +_hsl_acl_blk_left_enlarge(a_uint32_t dev_id, a_uint32_t idx, + a_uint32_t new_size) +{ + sw_error_t rv; + a_uint32_t old_size, old_addr, new_addr; + + _hsl_acl_blk_dump(dev_id, "_hsl_acl_blk_left_enlarge before enlarge"); + + if (0 == idx) + { + return SW_BAD_PARAM; + } + + if (MEM_FREE != acl_pool[dev_id].blk_ent[idx - 1].status) + { + return SW_BAD_PARAM; + } + + old_size = acl_pool[dev_id].blk_ent[idx].size; + if ((new_size - old_size) > acl_pool[dev_id].blk_ent[idx - 1].size) + { + return SW_BAD_PARAM; + } + + old_addr = acl_pool[dev_id].blk_ent[idx].addr; + new_addr = old_addr - (new_size - old_size); + rv = _hsl_acl_rule_copy(dev_id, old_addr, new_addr, old_size); + SW_RTN_ON_ERROR(rv); + + rv = _hsl_acl_rule_invalid(dev_id, new_addr + old_size, new_size - old_size); + SW_RTN_ON_ERROR(rv); + + acl_pool[dev_id].blk_ent[idx].size = new_size; + acl_pool[dev_id].blk_ent[idx].addr = new_addr; + acl_pool[dev_id].free_rsc -= (new_size - old_size); + rv = _hsl_acl_addr_update(dev_id, old_addr, new_addr, + acl_pool[dev_id].blk_ent[idx].info); + SW_RTN_ON_ERROR(rv); + + rv = SW_OK; + if ((new_size - old_size) == acl_pool[dev_id].blk_ent[idx - 1].size) + { + rv = _hsl_acl_blk_ent_left_mv(dev_id, idx, 1); + } + else + { + acl_pool[dev_id].blk_ent[idx - 1].size -= (new_size - old_size); + } + + _hsl_acl_blk_dump(dev_id, "_hsl_acl_blk_left_enlarge after enlarge"); + return rv; +} + +static sw_error_t +_hsl_acl_blk_right_enlarge(a_uint32_t dev_id, a_uint32_t idx, + a_uint32_t new_size) +{ + sw_error_t rv; + a_uint32_t old_size; + + _hsl_acl_blk_dump(dev_id, "_hsl_acl_blk_right_enlarge before enlarge"); + + if ((idx + 1) >= acl_pool[dev_id].used_blk) + { + return SW_BAD_PARAM; + } + + if (MEM_FREE != acl_pool[dev_id].blk_ent[idx + 1].status) + { + return SW_BAD_PARAM; + } + + old_size = acl_pool[dev_id].blk_ent[idx].size; + if ((new_size - old_size) > acl_pool[dev_id].blk_ent[idx + 1].size) + { + return SW_BAD_PARAM; + } + + acl_pool[dev_id].blk_ent[idx].size = new_size; + acl_pool[dev_id].free_rsc -= (new_size - old_size); + rv = SW_OK; + if ((new_size - old_size) < acl_pool[dev_id].blk_ent[idx + 1].size) + { + acl_pool[dev_id].blk_ent[idx + 1].size -= (new_size - old_size); + acl_pool[dev_id].blk_ent[idx + 1].addr += (new_size - old_size); + } + else + { + if ((idx + 2) < acl_pool[dev_id].used_blk) + { + rv = _hsl_acl_blk_ent_left_mv(dev_id, idx + 2, 1); + } + } + + _hsl_acl_blk_dump(dev_id, "_hsl_acl_blk_right_enlarge after enlarge"); + return rv; +} + +static sw_error_t +_hsl_acl_rule_copy(a_uint32_t dev_id, a_uint32_t src_addr, a_uint32_t dest_addr, + a_uint32_t size) +{ + hsl_acl_func_t * p_api; + sw_error_t rv; + + p_api = hsl_acl_ptr_get(dev_id); + SW_RTN_ON_NULL(p_api); + + if (NULL == p_api->acl_rule_copy) + return SW_NOT_SUPPORTED; + + rv = p_api->acl_rule_copy(dev_id, src_addr, dest_addr, size); + return rv; +} + +static sw_error_t +_hsl_acl_rule_invalid(a_uint32_t dev_id, a_uint32_t addr, a_uint32_t size) +{ + hsl_acl_func_t * p_api; + sw_error_t rv; + + p_api = hsl_acl_ptr_get(dev_id); + SW_RTN_ON_NULL(p_api); + + if (NULL == p_api->acl_rule_invalid) + return SW_NOT_SUPPORTED; + + rv = p_api->acl_rule_invalid(dev_id, addr, size); + return rv; +} + +static sw_error_t +_hsl_acl_addr_update(a_uint32_t dev_id, a_uint32_t old_addr, + a_uint32_t new_addr, a_uint32_t info) +{ + hsl_acl_func_t * p_api; + sw_error_t rv; + + p_api = hsl_acl_ptr_get(dev_id); + SW_RTN_ON_NULL(p_api); + + if (NULL == p_api->acl_addr_update) + return SW_NOT_SUPPORTED; + + rv = p_api->acl_addr_update(dev_id, old_addr, new_addr, info); + return rv; +} + +sw_error_t +hsl_acl_pool_creat(a_uint32_t dev_id, a_uint32_t blk_nr, a_uint32_t rsc_nr) +{ + HSL_DEV_ID_CHECK(dev_id); + + acl_pool[dev_id].blk_ent = aos_mem_alloc(blk_nr * (sizeof (hsl_acl_blk_t))); + if (NULL == acl_pool[dev_id].blk_ent) + { + return SW_NO_RESOURCE; + } + aos_mem_zero(acl_pool[dev_id].blk_ent, blk_nr * (sizeof (hsl_acl_blk_t))); + + acl_pool[dev_id].used_blk = 1; + acl_pool[dev_id].total_blk = blk_nr; + acl_pool[dev_id].free_rsc = rsc_nr; + + acl_pool[dev_id].blk_ent[0].addr = 0; + acl_pool[dev_id].blk_ent[0].size = rsc_nr; + acl_pool[dev_id].blk_ent[0].status = MEM_FREE; + + _hsl_acl_blk_dump(dev_id, "hsl_acl_pool_creat after creat"); + return SW_OK; +} + +sw_error_t +hsl_acl_pool_destroy(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + + if (NULL == acl_pool[dev_id].blk_ent) + { + return SW_FAIL; + } + + aos_mem_free(acl_pool[dev_id].blk_ent); + aos_mem_zero(&acl_pool[dev_id], sizeof(acl_pool[dev_id])); + return SW_OK; +} + +sw_error_t +hsl_acl_blk_alloc(a_uint32_t dev_id, a_uint32_t pri, a_uint32_t size, + a_uint32_t info, a_uint32_t * addr) +{ + sw_error_t rv; + a_uint32_t i; + a_uint32_t blk_nr; + a_uint32_t p_idx, largest_idx, prev_f_s, largest_f_s; + a_uint32_t l_idx, l_nr, l_size, r_idx, r_nr, r_size; + + HSL_DEV_ID_CHECK(dev_id); + + _hsl_acl_blk_dump(dev_id, "hsl_acl_blk_alloc before alloc"); + + if (0 == size) + { + return SW_BAD_PARAM; + } + + if (size > acl_pool[dev_id].free_rsc) + { + return SW_NO_RESOURCE; + } + + blk_nr = acl_pool[dev_id].used_blk; + + p_idx = 0; + prev_f_s = 0; + largest_f_s = 0; + largest_idx = 0; + + for (i = 0; i < blk_nr; i++) + { + if (MEM_FREE == acl_pool[dev_id].blk_ent[i].status) + { + prev_f_s += acl_pool[dev_id].blk_ent[i].size; + continue; + } + + p_idx = i; + if (pri <= acl_pool[dev_id].blk_ent[i].pri) + { + break; + } + } + + if (i == blk_nr) + { + p_idx = blk_nr; + } + + for (i = p_idx; i < blk_nr; i++) + { + if (MEM_FREE == acl_pool[dev_id].blk_ent[i].status) + { + if (largest_f_s < acl_pool[dev_id].blk_ent[i].size) + { + largest_idx = i; + largest_f_s = acl_pool[dev_id].blk_ent[i].size; + } + continue; + } + + if (pri != acl_pool[dev_id].blk_ent[i].pri) + { + break; + } + } + + if (largest_f_s >= size) + { + rv = _hsl_acl_blk_alloc(dev_id, largest_idx, pri, size, info, + addr); + + } + else if (prev_f_s >= size) + { + rv = _hsl_acl_blk_left_defrag(dev_id, p_idx, size, A_TRUE, &l_idx, + &l_nr, &l_size); + SW_RTN_ON_ERROR(rv); + + rv = _hsl_acl_blk_comb(dev_id, l_idx, l_nr); + SW_RTN_ON_ERROR(rv); + + rv = _hsl_acl_blk_alloc(dev_id, l_idx, pri, size, info, addr); + } + else if ((acl_pool[dev_id].free_rsc - prev_f_s) >= size) + { + rv = _hsl_acl_blk_right_defrag(dev_id, p_idx, size, A_TRUE, &r_idx, + &r_nr, &r_size); + SW_RTN_ON_ERROR(rv); + + rv = _hsl_acl_blk_comb(dev_id, r_idx, r_nr); + SW_RTN_ON_ERROR(rv); + + rv = _hsl_acl_blk_alloc(dev_id, r_idx, pri, size, info, addr); + } + else + { + rv = _hsl_acl_blk_left_defrag(dev_id, p_idx, size, A_FALSE, &l_idx, + &l_nr, &l_size); + SW_RTN_ON_ERROR(rv); + + rv = _hsl_acl_blk_right_defrag(dev_id, p_idx, size, A_FALSE, &r_idx, + &r_nr, &r_size); + SW_RTN_ON_ERROR(rv); + + rv = _hsl_acl_blk_comb(dev_id, l_idx, (l_nr + r_nr)); + SW_RTN_ON_ERROR(rv); + + rv = _hsl_acl_blk_alloc(dev_id, l_idx, pri, size, info, addr); + } + + _hsl_acl_blk_dump(dev_id, "hsl_acl_blk_alloc after alloc"); + return rv; +} + +sw_error_t +hsl_acl_blk_free(a_uint32_t dev_id, a_uint32_t addr) +{ + sw_error_t rv; + a_uint32_t idx; + + HSL_DEV_ID_CHECK(dev_id); + + _hsl_acl_blk_dump(dev_id, "hsl_acl_blk_free before free"); + + rv = _hsl_acl_blk_loc(dev_id, addr, &idx); + SW_RTN_ON_ERROR(rv); + + acl_pool[dev_id].blk_ent[idx].status = MEM_FREE; + acl_pool[dev_id].blk_ent[idx].pri = 0; + acl_pool[dev_id].blk_ent[idx].info = 0; + acl_pool[dev_id].free_rsc += acl_pool[dev_id].blk_ent[idx].size; + + rv = _hsl_acl_rule_invalid(dev_id, addr, acl_pool[dev_id].blk_ent[idx].size); + SW_RTN_ON_ERROR(rv); + + rv = _hsl_acl_free_blk_comb(dev_id, idx); + SW_RTN_ON_ERROR(rv); + + _hsl_acl_blk_dump(dev_id, "hsl_acl_blk_free after free"); + return SW_OK; +} + +sw_error_t +hsl_acl_blk_resize(a_uint32_t dev_id, a_uint32_t addr, a_uint32_t new_size) +{ + sw_error_t rv; + a_uint32_t idx, l_idx, l_nr, l_size, r_idx, r_nr, r_size, old_size; + + HSL_DEV_ID_CHECK(dev_id); + + _hsl_acl_blk_dump(dev_id, "hsl_acl_blk_resize before resize"); + + rv = _hsl_acl_blk_loc(dev_id, addr, &idx); + SW_RTN_ON_ERROR(rv); + + if (MEM_USED != acl_pool[dev_id].blk_ent[idx].status) + { + return SW_BAD_PARAM; + } + + old_size = acl_pool[dev_id].blk_ent[idx].size; + if (new_size == old_size) + { + return SW_OK; + } + + if (0 == new_size) + { + rv = hsl_acl_blk_free(dev_id, addr); + return rv; + } + + /* reduce acl memory block size */ + if (new_size < old_size) + { + rv = _hsl_acl_blk_reduce(dev_id, idx, new_size); + _hsl_acl_blk_dump(dev_id, "hsl_acl_blk_resize after resize"); + return rv; + } + + /* enlarge acl memory block size */ + if (acl_pool[dev_id].free_rsc < (new_size - old_size)) + { + return SW_NO_RESOURCE; + } + + rv = _hsl_acl_blk_left_defrag(dev_id, idx, new_size - old_size, + A_FALSE, &l_idx, &l_nr, &l_size); + SW_RTN_ON_ERROR(rv); + + rv = _hsl_acl_blk_comb(dev_id, l_idx, l_nr); + SW_RTN_ON_ERROR(rv); + + rv = _hsl_acl_blk_loc(dev_id, addr, &idx); + SW_RTN_ON_ERROR(rv); + + if (l_size >= (new_size - old_size)) + { + rv = _hsl_acl_blk_left_enlarge(dev_id, idx, new_size); + _hsl_acl_blk_dump(dev_id, "hsl_acl_blk_resize after resize"); + return rv; + } + + if (idx >= (acl_pool[dev_id].used_blk - 1)) + { + return SW_NO_RESOURCE; + } + rv = _hsl_acl_blk_right_defrag(dev_id, idx + 1, new_size - old_size, + A_FALSE, &r_idx, &r_nr, &r_size); + SW_RTN_ON_ERROR(rv); + + rv = _hsl_acl_blk_comb(dev_id, r_idx, r_nr); + SW_RTN_ON_ERROR(rv); + + rv = _hsl_acl_blk_loc(dev_id, addr, &idx); + SW_RTN_ON_ERROR(rv); + + if (r_size >= (new_size - old_size)) + { + rv = _hsl_acl_blk_right_enlarge(dev_id, idx, new_size); + _hsl_acl_blk_dump(dev_id, "hsl_acl_blk_resize after resize"); + return rv; + } + + rv = _hsl_acl_blk_right_enlarge(dev_id, idx, old_size + r_size); + SW_RTN_ON_ERROR(rv); + + rv = _hsl_acl_blk_left_enlarge(dev_id, idx, new_size); + _hsl_acl_blk_dump(dev_id, "hsl_acl_blk_resize after resize"); + return rv; +} + +sw_error_t +hsl_acl_free_rsc_get(a_uint32_t dev_id, a_uint32_t * free_rsc) +{ + HSL_DEV_ID_CHECK(dev_id); + + * free_rsc = acl_pool[dev_id].free_rsc; + return SW_OK; +} diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/hsl_api.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/hsl_api.c new file mode 100755 index 000000000..aeb3d36e8 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/hsl_api.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 "hsl_api.h" + +static hsl_api_t hsl_api_table[SW_MAX_NR_DEV]; + +hsl_api_t * +hsl_api_ptr_get(a_uint32_t dev_id) +{ + if (dev_id >= SW_MAX_NR_DEV) + return NULL; + + return &(hsl_api_table[dev_id]); +} + +sw_error_t +hsl_api_init(a_uint32_t dev_id) +{ + if (SW_MAX_NR_DEV <= dev_id) + { + return SW_BAD_PARAM; + } + + aos_mem_set(&hsl_api_table[dev_id], 0, sizeof (hsl_api_t)); + return SW_OK; +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/hsl_dev.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/hsl_dev.c new file mode 100755 index 000000000..ae9b98aca --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/hsl_dev.c @@ -0,0 +1,705 @@ +/* + * Copyright (c) 2012, 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*/ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_lock.h" +#include "sd.h" +/*qca808x_end*/ +#if defined ATHENA +#include "athena_init.h" +#endif +#if defined GARUDA +#include "garuda_init.h" +#endif +#if defined SHIVA +#include "shiva_init.h" +#endif +#if defined HORUS +#include "horus_init.h" +#endif +#if defined ISIS +#include "isis_init.h" +#endif +#if defined ISISC +#include "isisc_init.h" +#endif +#if defined DESS +#include "dess_init.h" +#endif +#if defined HPPE +#include "hppe_init.h" +#endif +#if defined SCOMPHY +/*qca808x_start*/ +#include "scomphy_init.h" +/*qca808x_end*/ +#endif +/*qca808x_start*/ +#include "sw_api.h" +/*qca808x_end*/ +#ifdef KERNEL_MODULE +/*qca808x_start*/ +#include "sw_api_ks.h" +/*qca808x_end*/ +#else +#include "sw_api_us.h" +#endif +#include "ssdk_plat.h" +#ifdef MP +#include "hsl_phy.h" +#endif +/*qca808x_start*/ +static hsl_dev_t dev_table[SW_MAX_NR_DEV]; +static ssdk_init_cfg *dev_ssdk_cfg[SW_MAX_NR_DEV] = { 0 }; +ssdk_chip_type SSDK_CURRENT_CHIP_TYPE = CHIP_UNSPECIFIED; + +static sw_error_t hsl_set_current_chip_type(ssdk_chip_type chip_type) +{ + sw_error_t rv = SW_OK; + + SSDK_CURRENT_CHIP_TYPE = chip_type; + + if (SSDK_CURRENT_CHIP_TYPE == CHIP_UNSPECIFIED) + { +/*qca808x_end*/ +#if defined ATHENA + SSDK_CURRENT_CHIP_TYPE = CHIP_ATHENA; +#elif defined GARUDA + SSDK_CURRENT_CHIP_TYPE = CHIP_GARUDA; +#elif defined SHIVA + SSDK_CURRENT_CHIP_TYPE = CHIP_SHIVA; +#elif defined HORUS + SSDK_CURRENT_CHIP_TYPE = CHIP_HORUS; +#elif defined ISIS + SSDK_CURRENT_CHIP_TYPE = CHIP_ISIS; +#elif defined ISISC + SSDK_CURRENT_CHIP_TYPE = CHIP_ISISC; +#elif defined DESS + SSDK_CURRENT_CHIP_TYPE = CHIP_DESS; +#elif defined HPPE + SSDK_CURRENT_CHIP_TYPE = CHIP_HPPE; +#elif defined SCOMPHY +/*qca808x_start*/ + SSDK_CURRENT_CHIP_TYPE = CHIP_SCOMPHY; +/*qca808x_end*/ +#else + rv = SW_FAIL; +#endif +/*qca808x_start*/ + } + return rv; +} + +hsl_dev_t * +hsl_dev_ptr_get(a_uint32_t dev_id) +{ + if (dev_id >= SW_MAX_NR_DEV) + return NULL; + + return &dev_table[dev_id]; +} +/*qca808x_end*/ +hsl_acl_func_t * +hsl_acl_ptr_get(a_uint32_t dev_id) +{ + if (dev_id >= SW_MAX_NR_DEV) + return NULL; + + return &(dev_table[dev_id].acl_func); +} + +a_uint32_t hsl_dev_wan_port_get(a_uint32_t dev_id) +{ + if(dev_ssdk_cfg[dev_id]) { + return dev_ssdk_cfg[dev_id]->port_cfg.wan_bmp; + } + return 0; +} + +a_uint32_t hsl_dev_inner_ports_get(a_uint32_t dev_id) +{ + if(dev_ssdk_cfg[dev_id]) { + return dev_ssdk_cfg[dev_id]->port_cfg.inner_bmp; + } + return 0; +} + +/*qca808x_start*/ +sw_error_t +hsl_dev_init(a_uint32_t dev_id, ssdk_init_cfg *cfg) +{ + sw_error_t rv = SW_OK; + static int dev_init = 0; + + if (SW_MAX_NR_DEV <= dev_id) + { + return SW_BAD_PARAM; + } + + aos_mem_set(&dev_table[dev_id], 0, sizeof (hsl_dev_t)); + + if (!dev_init) { + SW_RTN_ON_ERROR(sd_init(dev_id,cfg)); + +#ifdef UK_IF + SW_RTN_ON_ERROR(sw_uk_init(cfg->nl_prot)); +#endif + +#if defined API_LOCK + SW_RTN_ON_ERROR(hsl_api_lock_init()); +#endif + dev_init = 1; + } + rv = hsl_set_current_chip_type(cfg->chip_type); + SW_RTN_ON_ERROR(rv); + + if (NULL == dev_ssdk_cfg[dev_id]) + { + dev_ssdk_cfg[dev_id] = aos_mem_alloc(sizeof (ssdk_init_cfg)); + } + + if (NULL == dev_ssdk_cfg[dev_id]) + { + return SW_OUT_OF_MEM; + } + + aos_mem_copy(dev_ssdk_cfg[dev_id], cfg, sizeof (ssdk_init_cfg)); +#if defined UK_MINOR_DEV + dev_ssdk_cfg[dev_id]->nl_prot = UK_MINOR_DEV; +#endif + + rv = SW_INIT_ERROR; + switch (cfg->chip_type) + { +/*qca808x_end*/ + case CHIP_ATHENA: +#if defined ATHENA + rv = athena_init(dev_id, cfg); +#endif + break; + + case CHIP_GARUDA: +#if defined GARUDA + rv = garuda_init(dev_id, cfg); +#endif + break; + + case CHIP_SHIVA: +#if defined SHIVA + rv = shiva_init(dev_id, cfg); +#endif + break; + + case CHIP_HORUS: +#if defined HORUS + rv = horus_init(dev_id, cfg); +#endif + break; + + case CHIP_ISIS: +#if defined ISIS + rv = isis_init(dev_id, cfg); +#endif + break; + case CHIP_ISISC: +#if defined ISISC + rv = isisc_init(dev_id, cfg); +#endif + break; + case CHIP_DESS: +#if defined DESS + rv = dess_init(dev_id, cfg); +#endif + break; + case CHIP_HPPE: +#if defined HPPE + rv = hppe_init(dev_id, cfg); +#endif + break; +/*qca808x_start*/ + case CHIP_SCOMPHY: +/*qca808x_end*/ +#if defined SCOMPHY +/*qca808x_start*/ + rv = scomphy_init(dev_id, cfg); +/*qca808x_end*/ +#endif +/*qca808x_start*/ + break; +/*qca808x_end*/ + case CHIP_UNSPECIFIED: +#if defined ATHENA + rv = athena_init(dev_id, cfg); +#elif defined GARUDA + rv = garuda_init(dev_id, cfg); +#elif defined SHIVA + rv = shiva_init(dev_id, cfg); +#elif defined HORUS + rv = horus_init(dev_id, cfg); +#elif defined ISIS + rv = isis_init(dev_id, cfg); +#elif defined ISISC + rv = isisc_init(dev_id, cfg); +#endif + break; +/*qca808x_start*/ + default: + return SW_BAD_PARAM; + } + + return rv; +} +/*qca808x_end*/ +sw_error_t +hsl_ssdk_cfg(a_uint32_t dev_id, ssdk_cfg_t *ssdk_cfg) +{ + if(!dev_ssdk_cfg[dev_id]) + { + SSDK_ERROR("the dev%d wasn't initialized\n", dev_id); + return SW_BAD_VALUE; + } + aos_mem_set(&(ssdk_cfg->init_cfg), 0, sizeof(ssdk_init_cfg)); + + aos_mem_copy(&(ssdk_cfg->init_cfg), dev_ssdk_cfg[dev_id], sizeof(ssdk_init_cfg)); + +#ifdef VERSION + aos_mem_copy(ssdk_cfg->build_ver, VERSION, sizeof(VERSION)); +#endif + +#ifdef BUILD_DATE + aos_mem_copy(ssdk_cfg->build_date, BUILD_DATE, sizeof(BUILD_DATE)); +#endif + + switch (dev_ssdk_cfg[dev_id]->chip_type) + { + case CHIP_ATHENA: + aos_mem_copy(ssdk_cfg->chip_type, "athena", sizeof("athena")); + break; + + case CHIP_GARUDA: + aos_mem_copy(ssdk_cfg->chip_type, "garuda", sizeof("garuda")); + break; + + case CHIP_SHIVA: + aos_mem_copy(ssdk_cfg->chip_type, "shiva", sizeof("shiva")); + break; + + case CHIP_HORUS: + aos_mem_copy(ssdk_cfg->chip_type, "horus", sizeof("horus")); + break; + + case CHIP_ISIS: + aos_mem_copy(ssdk_cfg->chip_type, "isis", sizeof("isis")); + break; + + case CHIP_ISISC: + aos_mem_copy(ssdk_cfg->chip_type, "isisc", sizeof("isisc")); + break; + + case CHIP_DESS: + aos_mem_copy(ssdk_cfg->chip_type, "dess", sizeof("dess")); + break; + + case CHIP_HPPE: + aos_mem_copy(ssdk_cfg->chip_type, "hppe", sizeof("hppe")); + break; + + case CHIP_SCOMPHY: +#ifdef MP + if(dev_ssdk_cfg[dev_id]->chip_revision == MP_GEPHY) + { + aos_mem_copy(ssdk_cfg->chip_type, "mp", sizeof("mp")); + } +#endif + break; + + case CHIP_UNSPECIFIED: +#if defined ATHENA + aos_mem_copy(ssdk_cfg->chip_type, "athena", sizeof("athena")); +#elif defined GARUDA + aos_mem_copy(ssdk_cfg->chip_type, "garuda", sizeof("garuda")); +#elif defined SHIVA + aos_mem_copy(ssdk_cfg->chip_type, "shiva", sizeof("shiva")); +#elif defined HORUS + aos_mem_copy(ssdk_cfg->chip_type, "horus", sizeof("horus")); +#elif defined ISIS + aos_mem_copy(ssdk_cfg->chip_type, "isis", sizeof("isis")); +#elif defined ISISC + aos_mem_copy(ssdk_cfg->chip_type, "isisc", sizeof("isisc")); +#endif + break; + + default: + return SW_BAD_PARAM; + } + +#ifdef CPU + aos_mem_copy(ssdk_cfg->cpu_type, CPU, sizeof(CPU)); +#endif + +#ifdef OS + aos_mem_copy(ssdk_cfg->os_info, OS, sizeof(OS)); +#if defined KVER26 + aos_mem_copy(ssdk_cfg->os_info+sizeof(OS)-1, " version 2.6", sizeof(" version 2.6")); +#elif defined KVER24 + aos_mem_copy(ssdk_cfg->os_info+sizeof(OS)-1, " version 2.4", sizeof(" version 2.4")); +#else + aos_mem_copy(ssdk_cfg->os_info+sizeof(OS)-1, " unknown", sizeof(" unknown")); +#endif +#endif + +#ifdef HSL_STANDALONG + ssdk_cfg->fal_mod = A_FALSE; +#else + ssdk_cfg->fal_mod = A_TRUE; +#endif + +#ifdef USER_MODE + ssdk_cfg->kernel_mode = A_FALSE; +#else + ssdk_cfg->kernel_mode = A_TRUE; +#endif + +#ifdef UK_IF + ssdk_cfg->uk_if = A_TRUE; +#else + ssdk_cfg->uk_if = A_FALSE; +#endif + +#ifdef IN_ACL + ssdk_cfg->features.in_acl = A_TRUE; +#endif +#ifdef IN_FDB + ssdk_cfg->features.in_fdb = A_TRUE; +#endif +#ifdef IN_IGMP + ssdk_cfg->features.in_igmp = A_TRUE; +#endif +#ifdef IN_LEAKY + ssdk_cfg->features.in_leaky = A_TRUE; +#endif +#ifdef IN_LED + ssdk_cfg->features.in_led = A_TRUE; +#endif +#ifdef IN_MIB + ssdk_cfg->features.in_mib = A_TRUE; +#endif +#ifdef IN_MIRROR + ssdk_cfg->features.in_mirror = A_TRUE; +#endif +#ifdef IN_MISC + ssdk_cfg->features.in_misc = A_TRUE; +#endif +#ifdef IN_PORTCONTROL + ssdk_cfg->features.in_portcontrol = A_TRUE; +#endif +#ifdef IN_PORTVLAN + ssdk_cfg->features.in_portvlan = A_TRUE; +#endif +#ifdef IN_QOS + ssdk_cfg->features.in_qos = A_TRUE; +#endif +#ifdef IN_RATE + ssdk_cfg->features.in_rate = A_TRUE; +#endif +#ifdef IN_STP + ssdk_cfg->features.in_stp = A_TRUE; +#endif +#ifdef IN_VLAN + ssdk_cfg->features.in_vlan = A_TRUE; +#endif +#ifdef IN_REDUCED_ACL + ssdk_cfg->features.in_reduced_acl = A_TRUE; +#endif +#ifdef IN_IP + ssdk_cfg->features.in_ip = A_TRUE; +#endif +#ifdef IN_NAT + ssdk_cfg->features.in_nat = A_TRUE; +#endif +#ifdef IN_COSMAP + ssdk_cfg->features.in_cosmap = A_TRUE; +#endif +#ifdef IN_SEC + ssdk_cfg->features.in_sec = A_TRUE; +#endif +#ifdef IN_TRUNK + ssdk_cfg->features.in_trunk = A_TRUE; +#endif +#ifdef IN_NAT_HELPER + ssdk_cfg->features.in_nathelper= A_TRUE; +#endif +#ifdef IN_INTERFACECONTROL + ssdk_cfg->features.in_interfacectrl= A_TRUE; +#endif + + return SW_OK; +} +/*qca808x_start*/ +sw_error_t +hsl_dev_cleanup(void) +{ + sw_error_t rv = SW_OK; + a_uint32_t dev_id; + + for (dev_id = 0; dev_id < SW_MAX_NR_DEV; dev_id++) + { + if (dev_ssdk_cfg[dev_id]) + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + if (p_api->dev_clean) + { + rv = p_api->dev_clean(dev_id); + SW_RTN_ON_ERROR(rv); + } + + aos_mem_free(dev_ssdk_cfg[dev_id]); + dev_ssdk_cfg[dev_id] = NULL; + } + } + +#ifdef UK_IF + SW_RTN_ON_ERROR(sw_uk_cleanup()); +#endif + + return SW_OK; +} +/*qca808x_end*/ +sw_error_t +hsl_access_mode_set(a_uint32_t dev_id, hsl_access_mode reg_mode) +{ + sw_error_t rv; + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + if (p_api->dev_access_set) + { + rv = p_api->dev_access_set(dev_id, reg_mode); + } + else + { + return SW_BAD_PARAM; + } + + return rv; +} + +sw_error_t reduce_hsl_reg_entry_get(a_uint32_t dev,a_uint32_t reg,a_uint8_t* value,a_uint8_t val_len) +{ + sw_error_t rv; + + hsl_api_t *p_api = hsl_api_ptr_get(dev); + if (p_api) { + rv = p_api->reg_get(dev, reg, (a_uint8_t*)value, (a_uint8_t)val_len); + } else { + rv = SW_NOT_INITIALIZED; + } + + return rv; +} + +sw_error_t reduce_hsl_reg_entry_set(a_uint32_t dev,a_uint32_t reg,a_uint8_t* value,a_uint8_t val_len) +{ + sw_error_t rv; + + hsl_api_t *p_api = hsl_api_ptr_get(dev); + if (p_api) { + rv = p_api->reg_set (dev, reg, + (a_uint8_t*)value, (a_uint8_t)val_len); + } else { + rv = SW_NOT_INITIALIZED; + } + + return rv; + +} + +sw_error_t reduce_hsl_reg_field_get(a_uint32_t dev,a_uint32_t reg,a_uint32_t reg_offset, + a_uint32_t reg_offset_len,a_uint8_t* value,a_uint8_t val_len) +{ + sw_error_t rv; + + hsl_api_t *p_api = hsl_api_ptr_get(dev); + if (p_api) { + rv = p_api->reg_field_get(dev, reg, reg_offset, reg_offset_len, (a_uint8_t*)value, val_len); + } else { + rv = SW_NOT_INITIALIZED; + } + return rv; +} + +sw_error_t reduce_hsl_reg_field_set(a_uint32_t dev,a_uint32_t reg,a_uint32_t reg_offset, + a_uint32_t reg_offset_len,a_uint8_t* value,a_uint8_t val_len) +{ + sw_error_t rv; + + hsl_api_t *p_api = hsl_api_ptr_get(dev); + if (p_api) { + rv = p_api->reg_field_set(dev, reg, + reg_offset, + reg_offset_len, (a_uint8_t*)value, val_len); + } else { + rv = SW_NOT_INITIALIZED; + } + return rv; +} + +sw_error_t reduce_hsl_reg_entry_gen_get(a_uint32_t dev,a_uint32_t addr,a_uint8_t* value,a_uint8_t val_len) +{ + sw_error_t rv; + + hsl_api_t *p_api = hsl_api_ptr_get(dev); + if (p_api) { + rv = p_api->reg_get(dev, addr, (a_uint8_t*)value, val_len); + } else { + rv = SW_NOT_INITIALIZED; + } + + return rv; +} + + +sw_error_t reduce_hsl_reg_entry_gen_set(a_uint32_t dev,a_uint32_t addr,a_uint8_t* value,a_uint8_t val_len) +{ + sw_error_t rv; + + hsl_api_t *p_api = hsl_api_ptr_get(dev); + if (p_api) { + rv = p_api->reg_set(dev, addr, (a_uint8_t*)value, val_len); + } else { + rv = SW_NOT_INITIALIZED; + } + + return rv; +} + +sw_error_t reduce_hsl_reg_field_gen_get(a_uint32_t dev,a_uint32_t reg_addr,a_uint32_t bitoffset, + a_uint32_t field_len,a_uint8_t* value,a_uint8_t val_len) +{ + sw_error_t rv; + + hsl_api_t *p_api = hsl_api_ptr_get(dev); + if (p_api) { + rv = p_api->reg_field_get(dev, reg_addr, + bitoffset, + field_len, (a_uint8_t*)value, val_len); + } else { + rv = SW_NOT_INITIALIZED; + } + return rv; +} + + +sw_error_t reduce_hsl_reg_field_gen_set(a_uint32_t dev,a_uint32_t regaddr,a_uint32_t bitoffset, + a_uint32_t bitlength,a_uint8_t* value,a_uint8_t val_len) +{ + sw_error_t rv; + + hsl_api_t *p_api = hsl_api_ptr_get(dev); + if (p_api) { + rv = p_api->reg_field_set(dev, regaddr, + bitoffset, + bitlength, (a_uint8_t*)value, val_len); + } else { + rv = SW_NOT_INITIALIZED; + } + return rv; +} + +/*qca808x_start*/ +sw_error_t reduce_hsl_phy_set(a_uint32_t dev,a_uint32_t phy_addr,a_uint32_t reg,a_uint16_t value) +{ + sw_error_t rv; + + hsl_api_t *p_api = hsl_api_ptr_get(dev); + if (p_api) { + rv = p_api->phy_set(dev, phy_addr, reg, value); + } else { + rv = SW_NOT_INITIALIZED; + } + + return rv; +} + +sw_error_t reduce_hsl_phy_get(a_uint32_t dev,a_uint32_t phy_addr,a_uint32_t reg,a_uint16_t* value) +{ + sw_error_t rv; + + hsl_api_t *p_api = hsl_api_ptr_get(dev); + if (p_api) { + rv = p_api->phy_get(dev, phy_addr, reg, value); + } else { + rv = SW_NOT_INITIALIZED; + } + + return rv; +} + +sw_error_t hsl_phy_i2c_set(a_uint32_t dev,a_uint32_t phy_addr,a_uint32_t reg,a_uint16_t value) +{ + sw_error_t rv; + + hsl_api_t *p_api = hsl_api_ptr_get(dev); + if (p_api) { + rv = p_api->phy_i2c_set(dev, phy_addr, reg, value); + } else { + rv = SW_NOT_INITIALIZED; + } + + return rv; +} + +sw_error_t hsl_phy_i2c_get(a_uint32_t dev,a_uint32_t phy_addr,a_uint32_t reg,a_uint16_t* value) +{ + sw_error_t rv; + + hsl_api_t *p_api = hsl_api_ptr_get(dev); + if (p_api) { + rv = p_api->phy_i2c_get(dev, phy_addr, reg, value); + } else { + rv = SW_NOT_INITIALIZED; + } + + return rv; +} + +#if 0 +void reduce_sw_set_reg_by_field_u32(unsigned int reg_value,unsigned int field_value, + unsigned int reg_offset,unsigned int reg_len) +{ + do { + (reg_value) = (((reg_value) & SW_FIELD_MASK_NOT_U32((reg_offset),(reg_offset))) + | (((field_value) & SW_BIT_MASK_U32(reg_len)) << (reg_offset))); + } while (0); + +} + + +void reduce_sw_field_get_by_reg_u32(unsigned int reg_value,unsigned int field_value, + unsigned int reg_offset,unsigned int reg_len) +{ + do { + (field_value) = (((reg_value) >> (reg_offset)) & SW_BIT_MASK_U32(reg_len)); + } while (0); + +} +#endif +/*qca808x_end*/ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/hsl_lock.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/hsl_lock.c new file mode 100755 index 000000000..e9d454052 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/hsl_lock.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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" + +#ifdef KVER32 +aos_lock_t sw_hsl_api_lock; +#else +aos_lock_t sw_hsl_api_lock = aos_default_unlock; +#endif + +sw_error_t +hsl_api_lock_init(void) +{ + aos_lock_init(&sw_hsl_api_lock); + return SW_OK; +} diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/hsl_port_prop.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/hsl_port_prop.c new file mode 100755 index 000000000..b450fe40a --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/hsl_port_prop.c @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2012, 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_config.h" +#include "aos_head.h" +#include "sw_error.h" +#include "shared_func.h" +#include "fal_type.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "hsl_phy.h" + + +typedef struct +{ + a_uint32_t phy_id[SW_MAX_NR_PORT]; + fal_pbmp_t dev_portmap; + fal_pbmp_t property[HSL_PP_BUTT]; +} port_info_t; + +static port_info_t *p_port_info[SW_MAX_NR_DEV] = { 0 }; + +a_bool_t +hsl_port_prop_check(a_uint32_t dev_id, fal_port_t port_id, + hsl_port_prop_t p_type) +{ + fal_pbmp_t pbitmap; + + if (dev_id >= SW_MAX_NR_DEV) + return A_FALSE; + + if (HSL_PP_BUTT <= p_type) + { + return A_FALSE; + } + + pbitmap = p_port_info[dev_id]->property[p_type]; + + return SW_IS_PBMP_MEMBER(pbitmap, port_id); +} + +a_bool_t +hsl_mports_prop_check(a_uint32_t dev_id, fal_pbmp_t port_bitmap, + hsl_port_prop_t p_type) +{ + fal_pbmp_t pbitmap; + + if (dev_id >= SW_MAX_NR_DEV) + return A_FALSE; + + if (HSL_PP_BUTT <= p_type) + { + return A_FALSE; + } + + pbitmap = p_port_info[dev_id]->property[p_type]; + + return (SW_IS_PBMP_INCLUDE(pbitmap, port_bitmap)); +} + +a_bool_t +hsl_port_validity_check(a_uint32_t dev_id, fal_port_t port_id) +{ + fal_pbmp_t pbitmap; + + if (dev_id >= SW_MAX_NR_DEV) + return A_FALSE; + + pbitmap = p_port_info[dev_id]->dev_portmap; + + return SW_IS_PBMP_MEMBER(pbitmap, port_id); +} + +a_bool_t +hsl_mports_validity_check(a_uint32_t dev_id, fal_pbmp_t port_bitmap) +{ + fal_pbmp_t pbitmap; + + if (dev_id >= SW_MAX_NR_DEV) + return A_FALSE; + + pbitmap = p_port_info[dev_id]->dev_portmap; + + return (SW_IS_PBMP_INCLUDE(pbitmap, port_bitmap)); +} + +sw_error_t +hsl_port_prop_set(a_uint32_t dev_id, fal_port_t port_id, hsl_port_prop_t p_type) +{ + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_validity_check(dev_id, port_id)) + { + return SW_OUT_OF_RANGE; + } + + if (HSL_PP_BUTT <= p_type) + { + return SW_BAD_PARAM; + } + + SW_PBMP_ADD_PORT(p_port_info[dev_id]->property[p_type], port_id); + + return SW_OK; +} + +sw_error_t +hsl_port_prop_clr(a_uint32_t dev_id, fal_port_t port_id, hsl_port_prop_t p_type) +{ + HSL_DEV_ID_CHECK(dev_id);; + + if (A_FALSE == hsl_port_validity_check(dev_id, port_id)) + { + return SW_OUT_OF_RANGE; + } + + if (HSL_PP_BUTT <= p_type) + { + return SW_BAD_PARAM; + } + + SW_PBMP_DEL_PORT(p_port_info[dev_id]->property[p_type], port_id); + + return SW_OK; +} + +sw_error_t +hsl_port_prop_get_phyid(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * phy_id) +{ + HSL_DEV_ID_CHECK(dev_id); + HSL_PORT_ID_CHECK(port_id); + + if (A_FALSE == hsl_port_validity_check(dev_id, port_id)) + { + return SW_BAD_PARAM; + } + + *phy_id = qca_ssdk_port_to_phy_addr(dev_id, port_id); + + return SW_OK; +} + +sw_error_t +hsl_port_prop_set_phyid(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t phy_id) +{ + HSL_DEV_ID_CHECK(dev_id); + HSL_PORT_ID_CHECK(port_id); + + if (A_FALSE == hsl_port_validity_check(dev_id, port_id)) + { + return SW_BAD_PARAM; + } + + p_port_info[dev_id]->phy_id[port_id] = phy_id; + return SW_OK; +} + +sw_error_t +hsl_port_prop_portmap_set(a_uint32_t dev_id, fal_port_t port_id) +{ + HSL_DEV_ID_CHECK(dev_id); + + if (port_id > SW_MAX_NR_PORT) + return SW_OUT_OF_RANGE; + + SW_PBMP_ADD_PORT(p_port_info[dev_id]->dev_portmap, port_id); + + return SW_OK; +} + +sw_error_t +hsl_port_prop_init_by_dev(a_uint32_t dev_id) +{ + port_info_t *p_mem; + + HSL_DEV_ID_CHECK(dev_id); + + p_mem = aos_mem_alloc(sizeof (port_info_t)); + if (p_mem == NULL) + return SW_OUT_OF_MEM; + + aos_mem_zero(p_mem, sizeof (port_info_t)); + p_port_info[dev_id] = p_mem; + + return SW_OK; +} + +sw_error_t +hsl_port_prop_cleanup_by_dev(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + + if (p_port_info[dev_id] != NULL) + aos_mem_free((void *)p_port_info[dev_id]); + + p_port_info[dev_id] = NULL; + + return SW_OK; +} + + +sw_error_t +hsl_port_prop_init(a_uint32_t dev_id) +{ + if (dev_id >= SW_MAX_NR_DEV) + return SW_BAD_VALUE; + + p_port_info[dev_id] = NULL; + + return SW_OK; +} diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/Makefile b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/Makefile new file mode 100755 index 000000000..2fa5d4bc3 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/Makefile @@ -0,0 +1,124 @@ +LOC_DIR=src/hsl/isis +LIB=HSL + +include $(PRJ_PATH)/make/config.mk + +SRC_LIST=isis_reg_access.c isis_init.c + +ifeq (TRUE, $(IN_ACL)) + SRC_LIST += isis_acl.c isis_acl_parse.c isis_multicast_acl.c +endif + +ifeq (TRUE, $(IN_FDB)) + SRC_LIST += isis_fdb.c +endif + +ifeq (TRUE, $(IN_IGMP)) + SRC_LIST += isis_igmp.c +endif + +ifeq (TRUE, $(IN_LEAKY)) + SRC_LIST += isis_leaky.c +endif + +ifeq (TRUE, $(IN_LED)) + SRC_LIST += isis_led.c +endif + +ifeq (TRUE, $(IN_MIB)) + SRC_LIST += isis_mib.c +endif + +ifeq (TRUE, $(IN_MIRROR)) + SRC_LIST += isis_mirror.c +endif + +ifeq (TRUE, $(IN_MISC)) + SRC_LIST += isis_misc.c +endif + +ifeq (TRUE, $(IN_PORTCONTROL)) + SRC_LIST += isis_port_ctrl.c +endif + +ifeq (TRUE, $(IN_PORTVLAN)) + SRC_LIST += isis_portvlan.c +endif + +ifeq (TRUE, $(IN_QOS)) + SRC_LIST += isis_qos.c +endif + +ifeq (TRUE, $(IN_RATE)) + SRC_LIST += isis_rate.c +endif + +ifeq (TRUE, $(IN_STP)) + SRC_LIST += isis_stp.c +endif + +ifeq (TRUE, $(IN_VLAN)) + SRC_LIST += isis_vlan.c +endif + +ifeq (TRUE, $(IN_REDUCED_ACL)) + SRC_LIST += isis_reduced_acl.c +endif + +ifeq (TRUE, $(IN_COSMAP)) + SRC_LIST += isis_cosmap.c +endif + +ifeq (TRUE, $(IN_IP)) + SRC_LIST += isis_ip.c +endif + +ifeq (TRUE, $(IN_NAT)) + SRC_LIST += isis_nat.c +endif + +ifeq (TRUE, $(IN_NAT_HELPER)) + SRC_LIST += nat_helper_dt.c + SRC_LIST += nat_helper_hsl.c + SRC_LIST += nat_ipt_helper.c + SRC_LIST += napt_helper.c + SRC_LIST += host_helper.c + SRC_LIST += nat_helper.c + SRC_LIST += napt_acl.c + SRC_LIST += napt_procfs.c +endif + +ifeq (TRUE, $(IN_TRUNK)) + SRC_LIST += isis_trunk.c +endif + +ifeq (TRUE, $(IN_SEC)) + SRC_LIST += isis_sec.c +endif + +ifeq (TRUE, $(IN_INTERFACECONTROL)) + SRC_LIST += isis_interface_ctrl.c +endif + +ifeq (TRUE, $(IN_MACBLOCK)) + SRC_LIST += isis_mac_block.c +endif + + +ifeq (linux, $(OS)) + ifeq (KSLIB, $(MODULE_TYPE)) + ifneq (TRUE, $(KERNEL_MODE)) + SRC_LIST=isis_reg_access.c isis_init.c + endif + endif +endif + +ifeq (, $(filter ISIS, $(SUPPORT_CHIP))) + SRC_LIST= +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/src/src/hsl/isis/isis_acl.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_acl.c new file mode 100755 index 000000000..edca76acf --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_acl.c @@ -0,0 +1,1904 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup isis_acl ISIS_ACL + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_acl.h" +#include "isis_acl.h" +#include "isis_reg.h" +#include "isis_acl_prv.h" + +//#define ISIS_ACL_DEBUG +//#define ISIS_SW_ENTRY +#define ISIS_HW_ENTRY + +static isis_acl_list_t *sw_list_ent[SW_MAX_NR_DEV]; +static isis_acl_rule_t *sw_rule_ent[SW_MAX_NR_DEV]; + +static isis_acl_rule_t *sw_rule_tmp[SW_MAX_NR_DEV]; +static isis_acl_rule_t *hw_rule_tmp[SW_MAX_NR_DEV]; +#ifdef ISIS_SW_ENTRY +static a_uint8_t *sw_filter_mem = NULL; +#endif + +static sw_error_t +_isis_filter_valid_set(a_uint32_t dev_id, a_uint32_t flt_idx, a_uint32_t flag); + +static sw_error_t +_isis_filter_ports_bind(a_uint32_t dev_id, a_uint32_t flt_idx, + a_uint32_t ports); + +#ifdef ISIS_SW_ENTRY +static sw_error_t +_isis_filter_write(a_uint32_t dev_id, a_uint32_t reg[], a_uint32_t flt_idx, + a_uint32_t op); + +static sw_error_t +_isis_filter_read(a_uint32_t dev_id, a_uint32_t reg[], a_uint32_t flt_idx, + a_uint32_t op); +#endif + +static sw_error_t +_isis_filter_down_to_hw(a_uint32_t dev_id, hw_filter_t * filter, + a_uint32_t flt_idx); + +static sw_error_t +_isis_filter_up_to_sw(a_uint32_t dev_id, hw_filter_t * filter, + a_uint32_t flt_idx); + +static void +_isis_acl_list_dump(a_uint32_t dev_id) +{ + a_uint32_t i; + isis_acl_list_t *sw_list; + + aos_printk("\ndev_id=%d list control infomation:", dev_id); + for (i = 0; i < ISIS_MAX_FILTER; i++) + { + sw_list = &(sw_list_ent[dev_id][i]); + if (ENT_USED & sw_list->status) + { + aos_printk + ("\nlist_id=%02d list_pri=%02d rule_nr=%02d [pts_map]:0x%02x idx=%02d ", + sw_list->list_id, sw_list->list_pri, sw_list->rule_nr, + sw_list->bind_pts, i); + } + } + aos_printk("\n"); +} + +static void +_isis_acl_sw_rule_dump(char *info, isis_acl_rule_t * sw_rule) +{ +#ifdef ISIS_ACL_DEBUG + a_uint32_t flt_idx, i; + + aos_printk("\n%s", info); + for (flt_idx = 0; flt_idx < ISIS_MAX_FILTER; flt_idx++) + { + aos_printk("\n%d software filter:", flt_idx); + aos_printk("\nact:"); + for (i = 0; i < 3; i++) + { + aos_printk("%08x ", sw_rule[flt_idx].filter.act[i]); + } + + aos_printk("\nvlu:"); + for (i = 0; i < 5; i++) + { + aos_printk("%08x ", sw_rule[flt_idx].filter.vlu[i]); + } + + aos_printk("\nmsk:"); + for (i = 0; i < 5; i++) + { + aos_printk("%08x ", sw_rule[flt_idx].filter.msk[i]); + } + + aos_printk("\nctl:status[%02d] list_id[%02d] rule_id[%02d]", + sw_rule[flt_idx].status, + sw_rule[flt_idx].list_id, sw_rule[flt_idx].rule_id); + + aos_printk("\n\n"); + } +#else + return; +#endif +} + +static isis_acl_list_t * +_isis_acl_list_loc(a_uint32_t dev_id, a_uint32_t list_id) +{ + a_uint32_t i; + + for (i = 0; i < ISIS_MAX_FILTER; i++) + { + if ((ENT_USED & sw_list_ent[dev_id][i].status) + && (list_id == sw_list_ent[dev_id][i].list_id)) + { + return &(sw_list_ent[dev_id][i]); + } + } + return NULL; +} + +static sw_error_t +_isis_filter_valid_set(a_uint32_t dev_id, a_uint32_t flt_idx, a_uint32_t flag) +{ +#ifdef ISIS_SW_ENTRY + hw_filter_t filter; + + _isis_filter_up_to_sw(dev_id, &filter, flt_idx); + + filter.msk[4] &= 0xfffffff8; + filter.msk[4] |= (flag & 0x7); + + _isis_filter_down_to_hw(dev_id, &filter, flt_idx); + + return SW_OK; +#else +#ifdef ISIS_HW_ENTRY + hw_filter_t filter; + + filter = sw_rule_ent[dev_id][flt_idx].filter; + + filter.msk[4] &= 0xfffffff8; + filter.msk[4] |= (flag & 0x7); + + _isis_filter_down_to_hw(dev_id, &filter, flt_idx); + return SW_OK; +#else + sw_error_t rv; + a_uint32_t addr, data = 0; + + /* read filter mask at first */ + addr = ISIS_RULE_FUNC_ADDR; + data = (flt_idx & 0x7f) | (0x1 << 8) | (0x1 << 10) | (0x1 << 31); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* get filter mask and modify it */ + addr = ISIS_RULE_FUNC_ADDR + 20; + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data &= 0xfffffff8; + data |= (flag & 0x7); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* write back filter mask */ + addr = ISIS_RULE_FUNC_ADDR; + data = (flt_idx & 0x7f) | (0x1 << 8) | (0x1 << 31); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +#endif +#endif +} + +static sw_error_t +_isis_filter_ports_bind(a_uint32_t dev_id, a_uint32_t flt_idx, a_uint32_t ports) +{ +#ifdef ISIS_SW_ENTRY + hw_filter_t filter; + + _isis_filter_up_to_sw(dev_id, &filter, flt_idx); + + filter.vlu[4] &= 0xffffff80; + filter.vlu[4] |= (ports & 0x7f); + + _isis_filter_down_to_hw(dev_id, &filter, flt_idx); + + return SW_OK; +#else +#ifdef ISIS_HW_ENTRY + hw_filter_t filter; + + filter = sw_rule_ent[dev_id][flt_idx].filter; + + filter.vlu[4] &= 0xffffff80; + filter.vlu[4] |= (ports & 0x7f); + + _isis_filter_down_to_hw(dev_id, &filter, flt_idx); + + return SW_OK; +#else + sw_error_t rv; + a_uint32_t addr, data; + + /* read filter value at first */ + addr = ISIS_RULE_FUNC_ADDR; + data = (flt_idx & 0x7f) | (0x1 << 10) | (0x1 << 31); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* get filter value and modify it */ + addr = ISIS_RULE_FUNC_ADDR + 20; + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data &= 0xffffff80; + data |= (ports & 0x7f); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* write back filter value */ + addr = ISIS_RULE_FUNC_ADDR; + data = (flt_idx & 0x7f) | (0x1 << 31); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +#endif +#endif +} + +#ifdef ISIS_SW_ENTRY +static sw_error_t +_isis_filter_write(a_uint32_t dev_id, a_uint32_t reg[], a_uint32_t flt_idx, + a_uint32_t op) +{ + a_uint32_t i, addr, data, idx = 6; + sw_error_t rv; + + if (ISIS_FILTER_ACT_OP == op) + { + idx = 4; + } + + for (i = 1; i < idx; i++) + { + addr = ISIS_RULE_FUNC_ADDR + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(reg[i - 1])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + addr = ISIS_RULE_FUNC_ADDR; + data = (flt_idx & 0x7f) | (op << 8) | (0x1 << 31); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_isis_filter_read(a_uint32_t dev_id, a_uint32_t reg[], a_uint32_t flt_idx, + a_uint32_t op) +{ + a_uint32_t i, addr, data, idx = 6; + sw_error_t rv; + + addr = ISIS_RULE_FUNC_ADDR; + data = (flt_idx & 0x7f) | (op << 8) | (0x1 << 10) | (0x1 << 31); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (ISIS_FILTER_ACT_OP == op) + { + idx = 4; + } + + for (i = 1; i < idx; i++) + { + addr = ISIS_RULE_FUNC_ADDR + (i << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(reg[i - 1])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} +#endif + +static sw_error_t +_isis_filter_down_to_hw(a_uint32_t dev_id, hw_filter_t * filter, + a_uint32_t flt_idx) +{ +#ifdef ISIS_SW_ENTRY + a_uint8_t *tbl = sw_filter_mem + sizeof (hw_filter_t) * flt_idx; + + aos_mem_copy(tbl, filter, sizeof (hw_filter_t)); +#else +#ifdef ISIS_HW_ENTRY + sw_error_t rv; + a_uint32_t i, base, addr; + + base = ISIS_FILTER_ACT_ADDR + (flt_idx << 4); + for (i = 0; i < 3; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(filter->act[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + base = ISIS_FILTER_VLU_ADDR + (flt_idx << 5); + for (i = 0; i < 5; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(filter->vlu[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + base = ISIS_FILTER_MSK_ADDR + (flt_idx << 5); + for (i = 0; i < 5; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(filter->msk[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } +#else + sw_error_t rv; + + rv = _isis_filter_write(dev_id, &(filter->act[0]), flt_idx, + ISIS_FILTER_ACT_OP); + SW_RTN_ON_ERROR(rv); + + rv = _isis_filter_write(dev_id, &(filter->vlu[0]), flt_idx, + ISIS_FILTER_VLU_OP); + SW_RTN_ON_ERROR(rv); + + rv = _isis_filter_write(dev_id, &(filter->msk[0]), flt_idx, + ISIS_FILTER_MSK_OP); + SW_RTN_ON_ERROR(rv); +#endif +#endif + + return SW_OK; +} + +static sw_error_t +_isis_filter_up_to_sw(a_uint32_t dev_id, hw_filter_t * filter, + a_uint32_t flt_idx) +{ +#ifdef ISIS_SW_ENTRY + a_uint8_t *tbl = sw_filter_mem + sizeof (hw_filter_t) * flt_idx; + + aos_mem_copy(filter, tbl, sizeof (hw_filter_t)); +#else +#ifdef ISIS_HW_ENTRY + sw_error_t rv; + a_uint32_t i, base, addr; + + base = ISIS_FILTER_VLU_ADDR + (flt_idx << 5); + for (i = 0; i < 5; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(filter->vlu[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + base = ISIS_FILTER_MSK_ADDR + (flt_idx << 5); + for (i = 0; i < 5; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(filter->msk[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + base = ISIS_FILTER_ACT_ADDR + (flt_idx << 4); + for (i = 0; i < 3; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(filter->act[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } +#else + sw_error_t rv; + + rv = _isis_filter_read(dev_id, &(filter->vlu[0]), flt_idx, + ISIS_FILTER_VLU_OP); + SW_RTN_ON_ERROR(rv); + + rv = _isis_filter_read(dev_id, &(filter->msk[0]), flt_idx, + ISIS_FILTER_MSK_OP); + SW_RTN_ON_ERROR(rv); + + rv = _isis_filter_read(dev_id, &(filter->act[0]), flt_idx, + ISIS_FILTER_ACT_OP); + SW_RTN_ON_ERROR(rv); +#endif +#endif + + return SW_OK; +} + +static sw_error_t +_isis_acl_list_insert(a_uint32_t dev_id, a_uint32_t * src_idx, + a_uint32_t * dst_idx, isis_acl_rule_t * src_rule, + isis_acl_rule_t * dst_rule) +{ + a_uint32_t i, data, rule_id, list_id, list_pri; + + rule_id = 0; + list_id = src_rule[*src_idx].list_id; + list_pri = src_rule[*src_idx].list_pri; + + for (i = *src_idx; i < ISIS_MAX_FILTER; i++) + { + if (!(ENT_USED & src_rule[i].status)) + { + continue; // was: break; + } + + if (src_rule[i].list_id != list_id) + { + break; + } + + SW_GET_FIELD_BY_REG(MAC_RUL_M4, RULE_TYP, data, + src_rule[i].filter.msk[4]); + if (!data) + { + continue; + } + + if (ISIS_MAX_FILTER <= *dst_idx) + { + return SW_NO_RESOURCE; + } + + if (ENT_USED & dst_rule[*dst_idx].status) + { + return SW_NO_RESOURCE; + } + + SW_GET_FIELD_BY_REG(MAC_RUL_M4, RULE_VALID, data, + src_rule[i].filter.msk[4]); + if ((FLT_START == data) && (*dst_idx % 2)) + { + if (*src_idx != i) + { + dst_rule[*dst_idx].list_id = list_id; + dst_rule[*dst_idx].list_pri = list_pri; + dst_rule[*dst_idx].rule_id = rule_id - 1; + dst_rule[*dst_idx].status |= ENT_USED; + } + + (*dst_idx)++; + if (ISIS_MAX_FILTER <= *dst_idx) + { + return SW_NO_RESOURCE; + } + + if (ENT_USED & dst_rule[*dst_idx].status) + { + return SW_NO_RESOURCE; + } + } + + aos_mem_copy(&(dst_rule[*dst_idx].filter), &(src_rule[i].filter), + sizeof (hw_filter_t)); + dst_rule[*dst_idx].list_id = list_id; + dst_rule[*dst_idx].list_pri = list_pri; + dst_rule[*dst_idx].rule_id = rule_id; + dst_rule[*dst_idx].status |= ENT_USED; + if (ENT_DEACTIVE & src_rule[i].status) + { + dst_rule[*dst_idx].status |= ENT_DEACTIVE; + } + (*dst_idx)++; + + if ((FLT_END == data) && (*dst_idx % 2)) + { + if (ISIS_MAX_FILTER > *dst_idx) + { + dst_rule[*dst_idx].list_id = list_id; + dst_rule[*dst_idx].list_pri = list_pri; + dst_rule[*dst_idx].rule_id = rule_id; + dst_rule[*dst_idx].status |= ENT_USED; + (*dst_idx)++; + } + } + + if ((FLT_END == data) || (FLT_STARTEND == data)) + { + rule_id++; + } + } + + *src_idx = i; + return SW_OK; +} + +static sw_error_t +_isis_acl_rule_alloc(a_uint32_t dev_id, isis_acl_list_t * sw_list, + a_uint32_t filter_nr) +{ + a_uint32_t free_flt_nr, load_idx, begin_idx, start_idx, end_idx, i; + a_uint32_t largest_nr, largest_idx; + sw_error_t rv; + + /* calculate the proper location, [start_idx, end_idx) */ + start_idx = 0; + end_idx = ISIS_MAX_FILTER; + for (i = 0; i < ISIS_MAX_FILTER; i++) + { + if (ENT_USED & sw_rule_ent[dev_id][i].status) + { + if (sw_rule_ent[dev_id][i].list_pri < sw_list->list_pri) + { + start_idx = i + 1; + } + else if (sw_rule_ent[dev_id][i].list_pri > sw_list->list_pri) + { + end_idx = i; + break; + } + } + } + + /* find the larget free filters block */ + largest_nr = 0; + largest_idx = 0; + free_flt_nr = 0; + begin_idx = start_idx; + for (i = start_idx; i < end_idx; i++) + { + if (!(ENT_USED & sw_rule_ent[dev_id][i].status)) + { + free_flt_nr++; + } + else + { + if (free_flt_nr > largest_nr) + { + largest_nr = free_flt_nr; + largest_idx = begin_idx; + } + free_flt_nr = 0; + begin_idx = i + 1; + } + } + + if (free_flt_nr > largest_nr) + { + largest_nr = free_flt_nr; + largest_idx = begin_idx; + } + + if ((!largest_nr) || ((largest_nr + 1) < filter_nr)) + { + return SW_NO_RESOURCE; + } + + for (i = 0; i < ISIS_MAX_FILTER; i++) + { + if (ENT_USED & sw_rule_ent[dev_id][i].status) + { + aos_mem_copy(&(sw_rule_tmp[dev_id][i]), &(sw_rule_ent[dev_id][i]), + sizeof (isis_acl_rule_t)); + } + } + + begin_idx = 0; + load_idx = largest_idx; + rv = _isis_acl_list_insert(dev_id, &begin_idx, &load_idx, + hw_rule_tmp[dev_id], sw_rule_tmp[dev_id]); + return rv; +} + +static sw_error_t +_isis_acl_rule_reorder(a_uint32_t dev_id, isis_acl_list_t * sw_list) +{ + a_uint32_t i, src_idx, dst_idx; + sw_error_t rv; + + dst_idx = 0; + for (i = 0; i < ISIS_MAX_FILTER;) + { + if (ENT_USED & sw_rule_ent[dev_id][i].status) + { + if (sw_rule_ent[dev_id][i].list_pri <= sw_list->list_pri) + { + rv = _isis_acl_list_insert(dev_id, &i, &dst_idx, + sw_rule_ent[dev_id], + sw_rule_tmp[dev_id]); + SW_RTN_ON_ERROR(rv); + } + else + { + break; + } + } + else + { + i++; + } + } + + src_idx = 0; + rv = _isis_acl_list_insert(dev_id, &src_idx, &dst_idx, hw_rule_tmp[dev_id], + sw_rule_tmp[dev_id]); + SW_RTN_ON_ERROR(rv); + + for (; i < ISIS_MAX_FILTER;) + { + if (ENT_USED & sw_rule_ent[dev_id][i].status) + { + rv = _isis_acl_list_insert(dev_id, &i, &dst_idx, + sw_rule_ent[dev_id], + sw_rule_tmp[dev_id]); + SW_RTN_ON_ERROR(rv); + } + else + { + i++; + } + } + + return SW_OK; +} + +static void +_isis_acl_rule_sync(a_uint32_t dev_id, a_uint32_t flt_idx, a_uint32_t flt_nr) +{ + a_uint32_t i, data; + + for (i = flt_idx; i < (flt_idx + flt_nr); i++) + { + if (aos_mem_cmp + (&(sw_rule_ent[dev_id][i]), &(sw_rule_tmp[dev_id][i]), + sizeof (isis_acl_rule_t))) + { + SW_GET_FIELD_BY_REG(MAC_RUL_M4, RULE_TYP, data, + sw_rule_tmp[dev_id][i].filter.msk[4]); + if (data) + { + _isis_filter_down_to_hw(dev_id, + &(sw_rule_tmp[dev_id][i].filter), i); + } + else + { + _isis_filter_valid_set(dev_id, i, 0); + } + + aos_mem_copy(&(sw_rule_ent[dev_id][i]), &(sw_rule_tmp[dev_id][i]), + sizeof (isis_acl_rule_t)); + } + } +} + +static sw_error_t +_isis_acl_list_creat(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t list_pri) +{ + a_uint32_t i, loc = ISIS_MAX_FILTER; + isis_acl_list_t *sw_list; + + HSL_DEV_ID_CHECK(dev_id); + + if ((ISIS_MAX_LIST_ID < list_id) || (ISIS_MAX_LIST_PRI < list_pri)) + { + return SW_NOT_SUPPORTED; + } + + for (i = 0; i < ISIS_MAX_FILTER; i++) + { + sw_list = &(sw_list_ent[dev_id][i]); + if (ENT_USED & sw_list->status) + { + if (list_id == sw_list->list_id) + { + return SW_ALREADY_EXIST; + } + } + else + { + loc = i; + } + } + + if (ISIS_MAX_FILTER == loc) + { + return SW_NO_RESOURCE; + } + + sw_list = &(sw_list_ent[dev_id][loc]); + aos_mem_zero(sw_list, sizeof (isis_acl_list_t)); + sw_list->list_id = list_id; + sw_list->list_pri = list_pri; + sw_list->status |= ENT_USED; + return SW_OK; +} + +static sw_error_t +_isis_acl_list_destroy(a_uint32_t dev_id, a_uint32_t list_id) +{ + isis_acl_list_t *sw_list; + + HSL_DEV_ID_CHECK(dev_id); + + if (ISIS_MAX_LIST_ID < list_id) + { + return SW_NOT_SUPPORTED; + } + + sw_list = _isis_acl_list_loc(dev_id, list_id); + if (NULL == sw_list) + { + return SW_NOT_FOUND; + } + + if (0 != sw_list->bind_pts) + { + return SW_NOT_SUPPORTED; + } + + if (0 != sw_list->rule_nr) + { + return SW_NOT_SUPPORTED; + } + + aos_mem_zero(sw_list, sizeof (isis_acl_list_t)); + return SW_OK; +} + +static sw_error_t +_isis_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; + isis_acl_list_t *sw_list; + isis_acl_rule_t *sw_rule; + a_uint32_t i, free_flt_nr, old_flt_nr, old_flt_idx, new_flt_nr, bind_pts; + + HSL_DEV_ID_CHECK(dev_id); + + if (ISIS_MAX_LIST_ID < list_id) + { + return SW_NOT_SUPPORTED; + } + + if ((0 == rule_nr) || (NULL == rule)) + { + return SW_BAD_PARAM; + } + + sw_list = _isis_acl_list_loc(dev_id, list_id); + if (NULL == sw_list) + { + return SW_NOT_FOUND; + } + + if (rule_id != sw_list->rule_nr) + { + return SW_BAD_PARAM; + } + + old_flt_idx = 0; + old_flt_nr = 0; + free_flt_nr = 0; + aos_mem_zero(hw_rule_tmp[dev_id], + ISIS_HW_RULE_TMP_CNT * sizeof (isis_acl_rule_t)); + aos_mem_zero(sw_rule_tmp[dev_id], + ISIS_MAX_FILTER * sizeof (isis_acl_rule_t)); + for (i = 0; i < ISIS_MAX_FILTER; i++) + { + sw_rule = &(sw_rule_ent[dev_id][i]); + if (ENT_USED & sw_rule->status) + { + if (sw_rule->list_id == sw_list->list_id) + { + aos_mem_copy(&(hw_rule_tmp[dev_id][old_flt_nr]), sw_rule, + sizeof (isis_acl_rule_t)); + if (!old_flt_nr) + { + old_flt_idx = i; + } + old_flt_nr++; + } + } + else + { + free_flt_nr++; + } + } + + if (!free_flt_nr) + { + return SW_NO_RESOURCE; + } + + /* parse rule entry and alloc rule resource */ + new_flt_nr = old_flt_nr; + for (i = 0; i < rule_nr; i++) + { + rv = _isis_acl_rule_sw_to_hw(dev_id, &rule[i], hw_rule_tmp[dev_id], + &new_flt_nr); + SW_RTN_ON_ERROR(rv); + } + + if (free_flt_nr < (new_flt_nr - old_flt_nr)) + { + return SW_NO_RESOURCE; + } + + for (i = old_flt_nr; i < new_flt_nr; i++) + { + hw_rule_tmp[dev_id][i].status |= ENT_USED; + hw_rule_tmp[dev_id][i].list_id = sw_list->list_id; + hw_rule_tmp[dev_id][i].list_pri = sw_list->list_pri; + bind_pts = sw_list->bind_pts; + SW_SET_REG_BY_FIELD(MAC_RUL_V4, SRC_PT, bind_pts, + (hw_rule_tmp[dev_id][i].filter.vlu[4])); + } + + for (i = 0; i < old_flt_nr; i++) + { + sw_rule = &(sw_rule_ent[dev_id][old_flt_idx + i]); + sw_rule->status &= (~ENT_USED); + sw_rule->status |= (ENT_TMP); + } + + rv = _isis_acl_rule_alloc(dev_id, sw_list, new_flt_nr); + if (SW_OK != rv) + { + aos_mem_zero(sw_rule_tmp[dev_id], + ISIS_MAX_FILTER * sizeof (isis_acl_rule_t)); + rv = _isis_acl_rule_reorder(dev_id, sw_list); + } + + for (i = 0; i < old_flt_nr; i++) + { + sw_rule = &(sw_rule_ent[dev_id][i + old_flt_idx]); + sw_rule->status |= (ENT_USED); + sw_rule->status &= (~ENT_TMP); + } + SW_RTN_ON_ERROR(rv); + + _isis_acl_rule_sync(dev_id, 0, ISIS_MAX_FILTER); + sw_list->rule_nr += rule_nr; + + _isis_acl_sw_rule_dump("sw rule after add", sw_rule_ent[dev_id]); + return SW_OK; +} + +static sw_error_t +_isis_acl_rule_delete(a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t rule_id, a_uint32_t rule_nr) +{ + isis_acl_rule_t *sw_rule; + isis_acl_list_t *sw_list; + a_uint32_t i, flt_idx = 0, src_idx, dst_idx, del_nr = 0, flt_nr = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (ISIS_MAX_LIST_ID < list_id) + { + return SW_NOT_SUPPORTED; + } + + sw_list = _isis_acl_list_loc(dev_id, list_id); + if (NULL == sw_list) + { + return SW_NOT_FOUND; + } + + if (sw_list->rule_nr < (rule_id + rule_nr)) + { + return SW_BAD_PARAM; + } + + aos_mem_zero(hw_rule_tmp[dev_id], + ISIS_HW_RULE_TMP_CNT * sizeof (isis_acl_rule_t)); + aos_mem_zero(sw_rule_tmp[dev_id], + ISIS_MAX_FILTER * sizeof (isis_acl_rule_t)); + + for (i = 0; i < ISIS_MAX_FILTER; i++) + { + sw_rule = &(sw_rule_ent[dev_id][i]); + if ((ENT_USED & sw_rule->status) && (sw_rule->list_id == list_id)) + { + if (!flt_nr) + { + flt_idx = i; + } + + if ((sw_rule->rule_id >= rule_id) + && (sw_rule->rule_id < (rule_id + rule_nr))) + { + del_nr++; + } + else + { + aos_mem_copy(&(hw_rule_tmp[dev_id][flt_idx + flt_nr]), sw_rule, + sizeof (isis_acl_rule_t)); + } + flt_nr++; + } + } + + if (!del_nr) + { + return SW_NOT_FOUND; + } + + _isis_acl_sw_rule_dump("hw rule before del", hw_rule_tmp[dev_id]); + + for (i = 0; i < flt_nr; i++) + { + sw_rule = &(hw_rule_tmp[dev_id][flt_idx + i]); + if (ENT_USED & sw_rule->status) + { + break; + } + } + + if (i != flt_nr) + { + src_idx = flt_idx + i; + dst_idx = flt_idx; + rv = _isis_acl_list_insert(dev_id, &src_idx, &dst_idx, + hw_rule_tmp[dev_id], sw_rule_tmp[dev_id]); + SW_RTN_ON_ERROR(rv); + } + + _isis_acl_rule_sync(dev_id, flt_idx, flt_nr); + sw_list->rule_nr -= rule_nr; + + _isis_acl_sw_rule_dump("sw rule after del", sw_rule_ent[dev_id]); + return SW_OK; +} + +static sw_error_t +_isis_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; + isis_acl_rule_t *sw_rule; + a_uint32_t flt_nr = 0, i; + + HSL_DEV_ID_CHECK(dev_id); + + if (ISIS_MAX_LIST_ID < list_id) + { + return SW_NOT_SUPPORTED; + } + + aos_mem_zero(hw_rule_tmp[dev_id], + ISIS_HW_RULE_TMP_CNT * sizeof (isis_acl_rule_t)); + for (i = 0; i < ISIS_MAX_FILTER; i++) + { + sw_rule = &(sw_rule_ent[dev_id][i]); + if (ENT_USED & sw_rule->status) + { + if ((sw_rule->list_id == list_id) && (sw_rule->rule_id == rule_id)) + { + aos_mem_copy(&(hw_rule_tmp[dev_id][flt_nr]), sw_rule, + sizeof (isis_acl_rule_t)); + flt_nr++; + } + } + } + + if (!flt_nr) + { + return SW_NOT_FOUND; + } + + aos_mem_zero(rule, sizeof (fal_acl_rule_t)); + rv = _isis_acl_rule_hw_to_sw(dev_id, rule, hw_rule_tmp[dev_id], 0, flt_nr); + return rv; +} + +static sw_error_t +_isis_acl_rule_bind(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t ports) +{ + sw_error_t rv; + a_uint32_t i; + isis_acl_rule_t *sw_rule; + + for (i = 0; i < ISIS_MAX_FILTER; i++) + { + sw_rule = &(sw_rule_ent[dev_id][i]); + + if ((ENT_USED & sw_rule->status) + && (list_id == sw_rule->list_id) + && (!(ENT_DEACTIVE & sw_rule->status))) + { + rv = _isis_filter_ports_bind(dev_id, i, ports); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(MAC_RUL_V4, SRC_PT, ports, + (sw_rule->filter.vlu[4])); + } + } + + return SW_OK; +} + +static sw_error_t +_isis_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; + a_uint32_t ports; + isis_acl_list_t *sw_list; + + HSL_DEV_ID_CHECK(dev_id); + + if (ISIS_MAX_LIST_ID < list_id) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_ACL_DIREC_IN != direc) + { + return SW_NOT_SUPPORTED; + } + + sw_list = _isis_acl_list_loc(dev_id, list_id); + if (NULL == sw_list) + { + return SW_NOT_FOUND; + } + + if (FAL_ACL_BIND_PORT == obj_t) + { + ports = (sw_list->bind_pts) | (0x1 << obj_idx); + } + else if (FAL_ACL_BIND_PORTBITMAP == obj_t) + { + ports = (sw_list->bind_pts) | obj_idx; + } + else + { + return SW_NOT_SUPPORTED; + } + + rv = _isis_acl_rule_bind(dev_id, list_id, ports); + SW_RTN_ON_ERROR(rv); + + sw_list->bind_pts = ports; + return SW_OK; +} + +static sw_error_t +_isis_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; + a_uint32_t ports; + isis_acl_list_t *sw_list; + + HSL_DEV_ID_CHECK(dev_id); + + if (ISIS_MAX_LIST_ID < list_id) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_ACL_DIREC_IN != direc) + { + return SW_NOT_SUPPORTED; + } + + sw_list = _isis_acl_list_loc(dev_id, list_id); + if (NULL == sw_list) + { + return SW_NOT_FOUND; + } + + if (FAL_ACL_BIND_PORT == obj_t) + { + ports = (sw_list->bind_pts) & (~(0x1UL << obj_idx)); + } + else if (FAL_ACL_BIND_PORTBITMAP == obj_t) + { + ports = (sw_list->bind_pts) & (~obj_idx); + } + else + { + return SW_NOT_SUPPORTED; + } + + rv = _isis_acl_rule_bind(dev_id, list_id, ports); + SW_RTN_ON_ERROR(rv); + + sw_list->bind_pts = ports; + return SW_OK; +} + +static sw_error_t +_isis_acl_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, MOD_ENABLE, 0, ACL_EN, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_acl_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, MOD_ENABLE, 0, ACL_EN, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isis_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; + a_uint32_t reg = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (ISIS_UDF_MAX_OFFSET < offset) + { + return SW_BAD_PARAM; + } + + if (ISIS_UDF_MAX_OFFSET < length) + { + return SW_BAD_PARAM; + } + + if ((FAL_ACL_UDF_TYPE_L2_SNAP == udf_type) + || (FAL_ACL_UDF_TYPE_L3_PLUS == udf_type)) + { + HSL_REG_ENTRY_GET(rv, dev_id, WIN_RULE_CTL1, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + HSL_REG_ENTRY_GET(rv, dev_id, WIN_RULE_CTL0, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + SW_RTN_ON_ERROR(rv); + + switch (udf_type) + { + case FAL_ACL_UDF_TYPE_L2: + SW_SET_REG_BY_FIELD(WIN_RULE_CTL0, L2_OFFSET, offset, reg); + SW_SET_REG_BY_FIELD(WIN_RULE_CTL0, L2_LENGTH, length, reg); + break; + case FAL_ACL_UDF_TYPE_L3: + SW_SET_REG_BY_FIELD(WIN_RULE_CTL0, L3_OFFSET, offset, reg); + SW_SET_REG_BY_FIELD(WIN_RULE_CTL0, L3_LENGTH, length, reg); + break; + case FAL_ACL_UDF_TYPE_L4: + SW_SET_REG_BY_FIELD(WIN_RULE_CTL0, L4_OFFSET, offset, reg); + SW_SET_REG_BY_FIELD(WIN_RULE_CTL0, L4_LENGTH, length, reg); + break; + case FAL_ACL_UDF_TYPE_L2_SNAP: + SW_SET_REG_BY_FIELD(WIN_RULE_CTL1, L2S_OFFSET, offset, reg); + SW_SET_REG_BY_FIELD(WIN_RULE_CTL1, L2S_LENGTH, length, reg); + break; + case FAL_ACL_UDF_TYPE_L3_PLUS: + SW_SET_REG_BY_FIELD(WIN_RULE_CTL1, L3P_OFFSET, offset, reg); + SW_SET_REG_BY_FIELD(WIN_RULE_CTL1, L3P_LENGTH, length, reg); + break; + default: + return SW_BAD_PARAM; + } + + if ((FAL_ACL_UDF_TYPE_L2_SNAP == udf_type) + || (FAL_ACL_UDF_TYPE_L3_PLUS == udf_type)) + { + HSL_REG_ENTRY_SET(rv, dev_id, WIN_RULE_CTL1, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + HSL_REG_ENTRY_SET(rv, dev_id, WIN_RULE_CTL0, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + + return rv; +} + +static sw_error_t +_isis_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; + a_uint32_t reg = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if ((FAL_ACL_UDF_TYPE_L2_SNAP == udf_type) + || (FAL_ACL_UDF_TYPE_L3_PLUS == udf_type)) + { + HSL_REG_ENTRY_GET(rv, dev_id, WIN_RULE_CTL1, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + HSL_REG_ENTRY_GET(rv, dev_id, WIN_RULE_CTL0, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + SW_RTN_ON_ERROR(rv); + + switch (udf_type) + { + case FAL_ACL_UDF_TYPE_L2: + SW_GET_FIELD_BY_REG(WIN_RULE_CTL0, L2_OFFSET, (*offset), reg); + SW_GET_FIELD_BY_REG(WIN_RULE_CTL0, L2_LENGTH, (*length), reg); + break; + case FAL_ACL_UDF_TYPE_L3: + SW_GET_FIELD_BY_REG(WIN_RULE_CTL0, L3_OFFSET, (*offset), reg); + SW_GET_FIELD_BY_REG(WIN_RULE_CTL0, L3_LENGTH, (*length), reg); + break; + case FAL_ACL_UDF_TYPE_L4: + SW_GET_FIELD_BY_REG(WIN_RULE_CTL0, L4_OFFSET, (*offset), reg); + SW_GET_FIELD_BY_REG(WIN_RULE_CTL0, L4_LENGTH, (*length), reg); + break; + case FAL_ACL_UDF_TYPE_L2_SNAP: + SW_GET_FIELD_BY_REG(WIN_RULE_CTL1, L2S_OFFSET, (*offset), reg); + SW_GET_FIELD_BY_REG(WIN_RULE_CTL1, L2S_LENGTH, (*length), reg); + break; + case FAL_ACL_UDF_TYPE_L3_PLUS: + SW_GET_FIELD_BY_REG(WIN_RULE_CTL1, L3P_OFFSET, (*offset), reg); + SW_GET_FIELD_BY_REG(WIN_RULE_CTL1, L3P_LENGTH, (*length), reg); + break; + default: + return SW_BAD_PARAM; + } + + return SW_OK; +} + +static sw_error_t +_isis_acl_rule_active(a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t rule_id, a_uint32_t rule_nr, a_bool_t active) +{ + sw_error_t rv; + a_uint32_t i, ports; + isis_acl_list_t *sw_list; + isis_acl_rule_t *sw_rule; + + HSL_DEV_ID_CHECK(dev_id); + + sw_list = _isis_acl_list_loc(dev_id, list_id); + if (NULL == sw_list) + { + return SW_NOT_FOUND; + } + + if (sw_list->rule_nr < (rule_id + rule_nr)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == active) + { + ports = (sw_list->bind_pts); + } + else + { + ports = 0; + } + + for (i = 0; i < ISIS_MAX_FILTER; i++) + { + sw_rule = &(sw_rule_ent[dev_id][i]); + + if ((ENT_USED & sw_rule->status) + && (list_id == sw_rule->list_id) + && (rule_id <= sw_rule->rule_id) + && ((rule_id + rule_nr) > sw_rule->rule_id)) + { + rv = _isis_filter_ports_bind(dev_id, i, ports); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(MAC_RUL_V4, SRC_PT, ports, + (sw_rule->filter.vlu[4])); + + if (A_TRUE == active) + { + sw_rule->status &= (~ENT_DEACTIVE); + } + else + { + sw_rule->status |= (ENT_DEACTIVE); + } + } + } + + return SW_OK; +} + +HSL_LOCAL sw_error_t +isis_acl_list_dump(a_uint32_t dev_id) +{ + _isis_acl_list_dump(dev_id); + return SW_OK; +} + +HSL_LOCAL sw_error_t +isis_acl_rule_dump(a_uint32_t dev_id) +{ + a_uint32_t flt_idx, i; + sw_error_t rv; + hw_filter_t filter; + + aos_printk("\nisis_acl_rule_dump:\n"); + + for (flt_idx = 0; flt_idx < ISIS_MAX_FILTER; flt_idx++) + { + aos_mem_zero(&filter, sizeof (hw_filter_t)); + + rv = _isis_filter_up_to_sw(dev_id, &filter, flt_idx); + if (SW_OK != rv) + { + continue; + } + + aos_printk("\n%d filter dump:", flt_idx); + + aos_printk("\nhardware content:"); + aos_printk("\nact:"); + for (i = 0; i < (sizeof (filter.act) / sizeof (a_uint32_t)); i++) + { + aos_printk("%08x ", filter.act[i]); + } + + aos_printk("\nvlu:"); + for (i = 0; i < (sizeof (filter.vlu) / sizeof (a_uint32_t)); i++) + { + aos_printk("%08x ", filter.vlu[i]); + } + + aos_printk("\nmsk:"); + for (i = 0; i < (sizeof (filter.msk) / sizeof (a_uint32_t)); i++) + { + aos_printk("%08x ", filter.msk[i]); + } + + aos_printk("\nsoftware content:"); + aos_printk("\nact:"); + for (i = 0; i < (sizeof (filter.act) / sizeof (a_uint32_t)); i++) + { + aos_printk("%08x ", sw_rule_ent[dev_id][flt_idx].filter.act[i]); + } + + aos_printk("\nvlu:"); + for (i = 0; i < (sizeof (filter.vlu) / sizeof (a_uint32_t)); i++) + { + aos_printk("%08x ", sw_rule_ent[dev_id][flt_idx].filter.vlu[i]); + } + + aos_printk("\nmsk:"); + for (i = 0; i < (sizeof (filter.msk) / sizeof (a_uint32_t)); i++) + { + aos_printk("%08x ", sw_rule_ent[dev_id][flt_idx].filter.msk[i]); + } + + aos_printk("\nctl:status[%02d] list_id[%02d] rule_id[%02d]", + sw_rule_ent[dev_id][flt_idx].status, + sw_rule_ent[dev_id][flt_idx].list_id, + sw_rule_ent[dev_id][flt_idx].rule_id); + + aos_printk("\n\n"); + } + + return SW_OK; +} + +sw_error_t +isis_acl_reset(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + + aos_mem_zero(sw_list_ent[dev_id], + ISIS_MAX_FILTER * sizeof (isis_acl_list_t)); + + aos_mem_zero(sw_rule_ent[dev_id], + ISIS_MAX_FILTER * sizeof (isis_acl_rule_t)); + + return SW_OK; +} + +/** + * @brief Creat an acl list + * @details Comments: + * If the value of list_pri is more small then the priority is more high, + * that means the list could be first matched. + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] list_pri acl list priority + * @return SW_OK or error code + */ +sw_error_t +isis_acl_list_creat(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t list_pri) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_acl_list_creat(dev_id, list_id, list_pri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Destroy an acl list + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_acl_list_destroy(a_uint32_t dev_id, a_uint32_t list_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_acl_list_destroy(dev_id, list_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add one rule or more rules to an existing acl list + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] rule_id first rule id of this adding operation in list + * @param[in] rule_nr rule number of this adding operation + * @param[in] rule rules content of this adding operation + * @return SW_OK or error code + */ +sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_acl_rule_add(dev_id, list_id, rule_id, rule_nr, rule); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete one rule or more rules from an existing acl list + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] rule_id first rule id of this deleteing operation in list + * @param[in] rule_nr rule number of this deleteing operation + * @return SW_OK or error code + */ +sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_acl_rule_delete(dev_id, list_id, rule_id, rule_nr); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Query one particular rule in a particular acl list + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] rule_id first rule id of this deleteing operation in list + * @param[out] rule rule content of this operation + * @return SW_OK or error code + */ +sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_acl_rule_query(dev_id, list_id, rule_id, rule); + HSL_API_UNLOCK; + return rv; +} + +a_uint32_t +isis_acl_rule_get_offset(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t rule_id) +{ + a_uint32_t i, pos=0; + isis_acl_rule_t *sw_rule; + + for (i = 0; i < ISIS_MAX_FILTER; i++) + { + sw_rule = &(sw_rule_ent[0][i]); + + if ((ENT_USED & sw_rule->status) + && (list_id == sw_rule->list_id) && (sw_rule->rule_id == rule_id) + && (!(ENT_DEACTIVE & sw_rule->status))) + { + pos = i; + break; + + } + } + + return pos; +} + + +sw_error_t +isis_acl_rule_sync_multi_portmap(a_uint32_t dev_id, a_uint32_t pos, a_uint32_t *act) +{ + + HSL_DEV_ID_CHECK(dev_id); + + if (ISIS_MAX_LIST_ID < pos) + { + return SW_NOT_SUPPORTED; + } + + sw_rule_ent[dev_id][pos].filter.act[1] = act[1]; + sw_rule_ent[dev_id][pos].filter.act[2] = act[2]; + + sw_rule_tmp[dev_id][pos].filter.act[1] = act[1]; + sw_rule_tmp[dev_id][pos].filter.act[2] = act[2]; + + hw_rule_tmp[dev_id][pos].filter.act[1] = act[1]; + hw_rule_tmp[dev_id][pos].filter.act[2] = act[2]; + + + return SW_OK; +} + +/** + * @brief Bind an acl list to a particular object + * @details Comments: + * If obj_t equals FAL_ACL_BIND_PORT then obj_idx means port id + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] direc direction of this binding operation + * @param[in] obj_t object type of this binding operation + * @param[in] obj_idx object index of this binding operation + * @return SW_OK or error code + */ +sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_acl_list_bind(dev_id, list_id, direc, obj_t, obj_idx); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Unbind an acl list from a particular object + * @details Comments: + * If obj_t equals FAL_ACL_BIND_PORT then obj_idx means port id + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] direc direction of this unbinding operation + * @param[in] obj_t object type of this unbinding operation + * @param[in] obj_idx object index of this unbinding operation + * @return SW_OK or error code + */ +sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_acl_list_unbind(dev_id, list_id, direc, obj_t, obj_idx); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set working status of ACL engine on a particular device + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +isis_acl_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_acl_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get working status of ACL engine on a particular device + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_acl_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_acl_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set user define fields profile on a particular port + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] udf_type udf type + * @param[in] offset udf offset + * @param[in] length udf length + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_acl_port_udf_profile_set(dev_id, port_id, udf_type, offset, + length); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get user define fields profile on a particular port + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] udf_type udf type + * @param[out] offset udf offset + * @param[out] length udf length + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_acl_port_udf_profile_get(dev_id, port_id, udf_type, offset, + length); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Active one or more rules in an existing acl list + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] rule_id first rule id of this deactive operation in list + * @param[in] rule_nr rule number of this deactive operation + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_acl_rule_active(dev_id, list_id, rule_id, rule_nr, A_TRUE); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Deactive one or more rules in an existing acl list + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] rule_id first rule id of this deactive operation in list + * @param[in] rule_nr rule number of this deactive operation + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_acl_rule_active(dev_id, list_id, rule_id, rule_nr, A_FALSE); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +isis_acl_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + + sw_list_ent[dev_id] = + (isis_acl_list_t *) aos_mem_alloc(ISIS_MAX_FILTER * + sizeof (isis_acl_list_t)); + if (NULL == sw_list_ent[dev_id]) + { + return SW_NO_RESOURCE; + } + aos_mem_zero(sw_list_ent[dev_id], + ISIS_MAX_FILTER * sizeof (isis_acl_list_t)); + + sw_rule_ent[dev_id] = + (isis_acl_rule_t *) aos_mem_alloc(ISIS_MAX_FILTER * + sizeof (isis_acl_rule_t)); + if (NULL == sw_rule_ent[dev_id]) + { + return SW_NO_RESOURCE; + } + aos_mem_zero(sw_rule_ent[dev_id], + ISIS_MAX_FILTER * sizeof (isis_acl_rule_t)); + + hw_rule_tmp[dev_id] = + (isis_acl_rule_t *) aos_mem_alloc(ISIS_HW_RULE_TMP_CNT * + sizeof (isis_acl_rule_t)); + if (NULL == hw_rule_tmp[dev_id]) + { + return SW_NO_RESOURCE; + } + + sw_rule_tmp[dev_id] = + (isis_acl_rule_t *) aos_mem_alloc(ISIS_MAX_FILTER * + sizeof (isis_acl_rule_t)); + if (NULL == sw_rule_tmp[dev_id]) + { + return SW_NO_RESOURCE; + } +#ifdef ISIS_SW_ENTRY + sw_filter_mem = aos_mem_alloc(ISIS_MAX_FILTER * sizeof (hw_filter_t)); + if (NULL == sw_filter_mem) + { + return SW_NO_RESOURCE; + } + aos_mem_zero(sw_filter_mem, ISIS_MAX_FILTER * sizeof (hw_filter_t)); +#endif + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->acl_list_creat = isis_acl_list_creat; + p_api->acl_list_destroy = isis_acl_list_destroy; + p_api->acl_list_bind = isis_acl_list_bind; + p_api->acl_list_unbind = isis_acl_list_unbind; + p_api->acl_rule_add = isis_acl_rule_add; + p_api->acl_rule_delete = isis_acl_rule_delete; + p_api->acl_rule_query = isis_acl_rule_query; + p_api->acl_status_set = isis_acl_status_set; + p_api->acl_status_get = isis_acl_status_get; + p_api->acl_list_dump = isis_acl_list_dump; + p_api->acl_rule_dump = isis_acl_rule_dump; + p_api->acl_port_udf_profile_set = isis_acl_port_udf_profile_set; + p_api->acl_port_udf_profile_get = isis_acl_port_udf_profile_get; + p_api->acl_rule_active = isis_acl_rule_active; + p_api->acl_rule_deactive = isis_acl_rule_deactive; + p_api->acl_rule_get_offset = isis_acl_rule_get_offset; + p_api->acl_rule_sync_multi_portmap = isis_acl_rule_sync_multi_portmap; + } +#endif + + return SW_OK; +} + +sw_error_t +isis_acl_cleanup(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + + if (NULL != sw_list_ent[dev_id]) + { + aos_mem_free(sw_list_ent[dev_id]); + } + + if (NULL != sw_rule_ent[dev_id]) + { + aos_mem_free(sw_rule_ent[dev_id]); + } + + if (NULL != hw_rule_tmp[dev_id]) + { + aos_mem_free(hw_rule_tmp[dev_id]); + } + + if (NULL != sw_rule_tmp[dev_id]) + { + aos_mem_free(sw_rule_tmp[dev_id]); + } +#ifdef DESS_SW_ENTRY + if (NULL != sw_filter_mem) + { + aos_mem_free(sw_filter_mem); + } +#endif + + return SW_OK; +} +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_acl_parse.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_acl_parse.c new file mode 100755 index 000000000..4c52671ef --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_acl_parse.c @@ -0,0 +1,2452 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 "hsl.h" +#include "hsl_dev.h" +#include "hsl_acl.h" +#include "isis_acl.h" +#include "isis_reg.h" +#include "isis_acl_prv.h" + +#define DAH 0x1 +#define SAH 0x2 +#define TAG 0x4 +#define STAG 0x8 +#define CTAG 0x10 + +typedef sw_error_t(*parse_func_t) (fal_acl_rule_t * sw, + hw_filter_t * hw_filter_snap, + a_bool_t * b_care); + +static a_bool_t +_isis_acl_zero_addr(const fal_mac_addr_t addr) +{ + a_uint32_t i; + + for (i = 0; i < 6; i++) + { + if (addr.uc[i]) + { + return A_FALSE; + } + } + return A_TRUE; +} + +static a_bool_t +_isis_acl_field_care(fal_acl_field_op_t op, a_uint32_t val, a_uint32_t mask, + a_uint32_t chkvlu) +{ + if (FAL_ACL_FIELD_MASK == op) + { + if (0 == mask) + return A_FALSE; + } + else if (FAL_ACL_FIELD_RANGE == op) + { + if ((0 == val) && (chkvlu == mask)) + return A_FALSE; + } + else if (FAL_ACL_FIELD_LE == op) + { + if (chkvlu == val) + return A_FALSE; + } + else if (FAL_ACL_FIELD_GE == op) + { + if (0 == val) + return A_FALSE; + } + else if (FAL_ACL_FIELD_NE == op) + { + return A_TRUE; + } + + return A_TRUE; +} + +static sw_error_t +_isis_acl_rule_bmac_parse(fal_acl_rule_t * sw, + hw_filter_t * hw, a_bool_t * b_care) +{ + a_uint32_t i; + + *b_care = A_FALSE; + aos_mem_zero(&(hw->vlu[0]), sizeof (hw->vlu)); + aos_mem_zero(&(hw->msk[0]), sizeof (hw->msk)); + + FIELD_SET_MASK(MAC_RUL_M4, RULE_TYP, ISIS_MAC_FILTER); + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_DA)) + { + if (A_TRUE != _isis_acl_zero_addr(sw->dest_mac_mask)) + { + *b_care = A_TRUE; + } + + for (i = 0; i < 6; i++) + { + sw->dest_mac_val.uc[i] &= sw->dest_mac_mask.uc[i]; + } + + FIELD_SET(MAC_RUL_V0, DAV_BYTE2, sw->dest_mac_val.uc[2]); + FIELD_SET(MAC_RUL_V0, DAV_BYTE3, sw->dest_mac_val.uc[3]); + FIELD_SET(MAC_RUL_V0, DAV_BYTE4, sw->dest_mac_val.uc[4]); + FIELD_SET(MAC_RUL_V0, DAV_BYTE5, sw->dest_mac_val.uc[5]); + FIELD_SET(MAC_RUL_V1, DAV_BYTE0, sw->dest_mac_val.uc[0]); + FIELD_SET(MAC_RUL_V1, DAV_BYTE1, sw->dest_mac_val.uc[1]); + + FIELD_SET_MASK(MAC_RUL_M0, DAM_BYTE2, sw->dest_mac_mask.uc[2]); + FIELD_SET_MASK(MAC_RUL_M0, DAM_BYTE3, sw->dest_mac_mask.uc[3]); + FIELD_SET_MASK(MAC_RUL_M0, DAM_BYTE4, sw->dest_mac_mask.uc[4]); + FIELD_SET_MASK(MAC_RUL_M0, DAM_BYTE5, sw->dest_mac_mask.uc[5]); + FIELD_SET_MASK(MAC_RUL_M1, DAM_BYTE0, sw->dest_mac_mask.uc[0]); + FIELD_SET_MASK(MAC_RUL_M1, DAM_BYTE1, sw->dest_mac_mask.uc[1]); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_SA)) + { + if (A_TRUE != _isis_acl_zero_addr(sw->src_mac_mask)) + { + *b_care = A_TRUE; + } + + for (i = 0; i < 6; i++) + { + sw->src_mac_val.uc[i] &= sw->src_mac_mask.uc[i]; + } + + FIELD_SET(MAC_RUL_V1, SAV_BYTE4, sw->src_mac_val.uc[4]); + FIELD_SET(MAC_RUL_V1, SAV_BYTE5, sw->src_mac_val.uc[5]); + FIELD_SET(MAC_RUL_V2, SAV_BYTE0, sw->src_mac_val.uc[0]); + FIELD_SET(MAC_RUL_V2, SAV_BYTE1, sw->src_mac_val.uc[1]); + FIELD_SET(MAC_RUL_V2, SAV_BYTE2, sw->src_mac_val.uc[2]); + FIELD_SET(MAC_RUL_V2, SAV_BYTE3, sw->src_mac_val.uc[3]); + + FIELD_SET_MASK(MAC_RUL_M1, SAM_BYTE4, sw->src_mac_mask.uc[4]); + FIELD_SET_MASK(MAC_RUL_M1, SAM_BYTE5, sw->src_mac_mask.uc[5]); + FIELD_SET_MASK(MAC_RUL_M2, SAM_BYTE0, sw->src_mac_mask.uc[0]); + FIELD_SET_MASK(MAC_RUL_M2, SAM_BYTE1, sw->src_mac_mask.uc[1]); + FIELD_SET_MASK(MAC_RUL_M2, SAM_BYTE2, sw->src_mac_mask.uc[2]); + FIELD_SET_MASK(MAC_RUL_M2, SAM_BYTE3, sw->src_mac_mask.uc[3]); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_ETHTYPE)) + { + if (0x0 != sw->ethtype_mask) + { + *b_care = A_TRUE; + } + + sw->ethtype_val &= sw->ethtype_mask; + FIELD_SET(MAC_RUL_V3, ETHTYPV, sw->ethtype_val); + FIELD_SET_MASK(MAC_RUL_M3, ETHTYPM, sw->ethtype_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_TAGGED)) + { + if (0x0 != sw->tagged_mask) + { + *b_care = A_TRUE; + } + + sw->tagged_val &= sw->tagged_mask; + FIELD_SET_MASK(MAC_RUL_M4, TAGGEDV, sw->tagged_val); + FIELD_SET_MASK(MAC_RUL_M4, TAGGEDM, sw->tagged_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_UP)) + { + if (0x0 != sw->up_mask) + { + *b_care = A_TRUE; + } + + sw->up_val &= sw->up_mask; + FIELD_SET(MAC_RUL_V3, VLANPRIV, sw->up_val); + FIELD_SET_MASK(MAC_RUL_M3, VLANPRIM, sw->up_mask); + } + + FIELD_SET_MASK(MAC_RUL_M4, VIDMSK, 1); + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_VID)) + { + if ((FAL_ACL_FIELD_MASK != sw->vid_op) + && (FAL_ACL_FIELD_RANGE != sw->vid_op) + && (FAL_ACL_FIELD_LE != sw->vid_op) + && (FAL_ACL_FIELD_GE != sw->vid_op)) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == + _isis_acl_field_care(sw->vid_op, sw->vid_val, sw->vid_mask, + 0xfff)) + { + *b_care = A_TRUE; + } + + FIELD_SET_MASK(MAC_RUL_M4, VIDMSK, 0); + if (FAL_ACL_FIELD_MASK == sw->vid_op) + { + sw->vid_val &= sw->vid_mask; + FIELD_SET(MAC_RUL_V3, VLANIDV, sw->vid_val); + FIELD_SET_MASK(MAC_RUL_M3, VLANIDM, sw->vid_mask); + FIELD_SET_MASK(MAC_RUL_M4, VIDMSK, 1); + } + else if (FAL_ACL_FIELD_RANGE == sw->vid_op) + { + FIELD_SET(MAC_RUL_V3, VLANIDV, sw->vid_val); + FIELD_SET_MASK(MAC_RUL_M3, VLANIDM, sw->vid_mask); + } + else if (FAL_ACL_FIELD_LE == sw->vid_op) + { + FIELD_SET(MAC_RUL_V3, VLANIDV, 0); + FIELD_SET_MASK(MAC_RUL_M3, VLANIDM, sw->vid_val); + } + else + { + FIELD_SET(MAC_RUL_V3, VLANIDV, sw->vid_val); + FIELD_SET_MASK(MAC_RUL_M3, VLANIDM, 0xfff); + } + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_CFI)) + { + if (0x0 != sw->cfi_mask) + { + *b_care = A_TRUE; + } + + sw->cfi_val &= sw->cfi_mask; + FIELD_SET(MAC_RUL_V3, VLANCFIV, sw->cfi_val); + FIELD_SET_MASK(MAC_RUL_M3, VLANCFIM, sw->cfi_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL)) + { + FIELD_SET(MAC_RUL_V4, RULE_INV, 1); + } + + return SW_OK; +} + +static sw_error_t +_isis_acl_rule_ehmac_parse(fal_acl_rule_t * sw, + hw_filter_t * hw, a_bool_t * b_care) +{ + a_uint32_t i; + a_bool_t da_h = A_FALSE, sa_h = A_FALSE; + + *b_care = A_FALSE; + aos_mem_zero(&(hw->vlu[0]), sizeof (hw->vlu)); + aos_mem_zero(&(hw->msk[0]), sizeof (hw->msk)); + + FIELD_SET_MASK(MAC_RUL_M4, RULE_TYP, ISIS_EHMAC_FILTER); + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_DA)) + { + for (i = 0; i < 3; i++) + { + if (sw->dest_mac_mask.uc[i]) + { + da_h = A_TRUE; + break; + } + } + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_SA)) + { + for (i = 0; i < 3; i++) + { + if (sw->src_mac_mask.uc[i]) + { + sa_h = A_TRUE; + break; + } + } + } + + /* if sa_h and da_h both are true need't process mac address fileds */ + if ((A_TRUE == da_h) && ((A_TRUE == sa_h))) + { + da_h = A_FALSE; + sa_h = A_FALSE; + } + + if (A_TRUE == da_h) + { + FIELD_SET(EHMAC_RUL_V3, DA_EN, 1); + + if (A_TRUE != _isis_acl_zero_addr(sw->dest_mac_mask)) + { + *b_care = A_TRUE; + } + + for (i = 0; i < 6; i++) + { + sw->dest_mac_val.uc[i] &= sw->dest_mac_mask.uc[i]; + } + + FIELD_SET(EHMAC_RUL_V0, DAV_BYTE2, sw->dest_mac_val.uc[2]); + FIELD_SET(EHMAC_RUL_V0, DAV_BYTE3, sw->dest_mac_val.uc[3]); + FIELD_SET(EHMAC_RUL_V0, DAV_BYTE4, sw->dest_mac_val.uc[4]); + FIELD_SET(EHMAC_RUL_V0, DAV_BYTE5, sw->dest_mac_val.uc[5]); + FIELD_SET(EHMAC_RUL_V1, DAV_BYTE0, sw->dest_mac_val.uc[0]); + FIELD_SET(EHMAC_RUL_V1, DAV_BYTE1, sw->dest_mac_val.uc[1]); + + FIELD_SET_MASK(EHMAC_RUL_M0, DAM_BYTE2, sw->dest_mac_mask.uc[2]); + FIELD_SET_MASK(EHMAC_RUL_M0, DAM_BYTE3, sw->dest_mac_mask.uc[3]); + FIELD_SET_MASK(EHMAC_RUL_M0, DAM_BYTE4, sw->dest_mac_mask.uc[4]); + FIELD_SET_MASK(EHMAC_RUL_M0, DAM_BYTE5, sw->dest_mac_mask.uc[5]); + FIELD_SET_MASK(EHMAC_RUL_M1, DAM_BYTE0, sw->dest_mac_mask.uc[0]); + FIELD_SET_MASK(EHMAC_RUL_M1, DAM_BYTE1, sw->dest_mac_mask.uc[1]); + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_SA)) + { + if (A_TRUE != _isis_acl_zero_addr(sw->src_mac_mask)) + { + *b_care = A_TRUE; + } + + for (i = 0; i < 6; i++) + { + sw->src_mac_val.uc[i] &= sw->src_mac_mask.uc[i]; + } + + FIELD_SET(EHMAC_RUL_V2, SAV_BYTE3, sw->src_mac_val.uc[3]); + FIELD_SET(EHMAC_RUL_V1, SAV_BYTE4, sw->src_mac_val.uc[4]); + FIELD_SET(EHMAC_RUL_V1, SAV_BYTE5, sw->src_mac_val.uc[5]); + + FIELD_SET_MASK(EHMAC_RUL_M2, SAM_BYTE3, sw->src_mac_mask.uc[3]); + FIELD_SET_MASK(EHMAC_RUL_M1, SAM_BYTE4, sw->src_mac_mask.uc[4]); + FIELD_SET_MASK(EHMAC_RUL_M1, SAM_BYTE5, sw->src_mac_mask.uc[5]); + } + } + + if (A_TRUE == sa_h) + { + if (A_TRUE != _isis_acl_zero_addr(sw->src_mac_mask)) + { + *b_care = A_TRUE; + } + + for (i = 0; i < 6; i++) + { + sw->src_mac_val.uc[i] &= sw->src_mac_mask.uc[i]; + } + + FIELD_SET(EHMAC_RUL_V0, DAV_BYTE2, sw->src_mac_val.uc[2]); + FIELD_SET(EHMAC_RUL_V0, DAV_BYTE3, sw->src_mac_val.uc[3]); + FIELD_SET(EHMAC_RUL_V0, DAV_BYTE4, sw->src_mac_val.uc[4]); + FIELD_SET(EHMAC_RUL_V0, DAV_BYTE5, sw->src_mac_val.uc[5]); + FIELD_SET(EHMAC_RUL_V1, DAV_BYTE0, sw->src_mac_val.uc[0]); + FIELD_SET(EHMAC_RUL_V1, DAV_BYTE1, sw->src_mac_val.uc[1]); + + FIELD_SET_MASK(EHMAC_RUL_M0, DAM_BYTE2, sw->src_mac_mask.uc[2]); + FIELD_SET_MASK(EHMAC_RUL_M0, DAM_BYTE3, sw->src_mac_mask.uc[3]); + FIELD_SET_MASK(EHMAC_RUL_M0, DAM_BYTE4, sw->src_mac_mask.uc[4]); + FIELD_SET_MASK(EHMAC_RUL_M0, DAM_BYTE5, sw->src_mac_mask.uc[5]); + FIELD_SET_MASK(EHMAC_RUL_M1, DAM_BYTE0, sw->src_mac_mask.uc[0]); + FIELD_SET_MASK(EHMAC_RUL_M1, DAM_BYTE1, sw->src_mac_mask.uc[1]); + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_DA)) + { + if (A_TRUE != _isis_acl_zero_addr(sw->dest_mac_mask)) + { + *b_care = A_TRUE; + } + + for (i = 0; i < 6; i++) + { + sw->dest_mac_val.uc[i] &= sw->dest_mac_mask.uc[i]; + } + + FIELD_SET(EHMAC_RUL_V2, SAV_BYTE3, sw->dest_mac_val.uc[3]); + FIELD_SET(EHMAC_RUL_V1, SAV_BYTE4, sw->dest_mac_val.uc[4]); + FIELD_SET(EHMAC_RUL_V1, SAV_BYTE5, sw->dest_mac_val.uc[5]); + + FIELD_SET_MASK(EHMAC_RUL_M2, SAM_BYTE3, sw->dest_mac_mask.uc[3]); + FIELD_SET_MASK(EHMAC_RUL_M1, SAM_BYTE4, sw->dest_mac_mask.uc[4]); + FIELD_SET_MASK(EHMAC_RUL_M1, SAM_BYTE5, sw->dest_mac_mask.uc[5]); + } + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_ETHTYPE)) + { + if (0x0 != sw->ethtype_mask) + { + *b_care = A_TRUE; + } + + sw->ethtype_val &= sw->ethtype_mask; + FIELD_SET(EHMAC_RUL_V3, ETHTYPV, sw->ethtype_val); + FIELD_SET_MASK(EHMAC_RUL_M3, ETHTYPM, sw->ethtype_mask); + } + + /* Process Stag Fields */ + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_STAGGED)) + { + if (0x0 != sw->stagged_mask) + { + *b_care = A_TRUE; + } + + sw->stagged_val &= sw->stagged_mask; + FIELD_SET(EHMAC_RUL_V3, STAGGEDV, sw->stagged_val); + FIELD_SET(EHMAC_RUL_V3, STAGGEDM, sw->stagged_mask); + } + + FIELD_SET(EHMAC_RUL_V3, SVIDMSK, 1); + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_STAG_VID)) + { + if ((FAL_ACL_FIELD_MASK != sw->stag_vid_op) + && (FAL_ACL_FIELD_RANGE != sw->stag_vid_op) + && (FAL_ACL_FIELD_LE != sw->stag_vid_op) + && (FAL_ACL_FIELD_GE != sw->stag_vid_op)) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == + _isis_acl_field_care(sw->stag_vid_op, sw->stag_vid_val, + sw->stag_vid_mask, 0xfff)) + { + *b_care = A_TRUE; + } + + FIELD_SET(EHMAC_RUL_V3, SVIDMSK, 0); + if (FAL_ACL_FIELD_MASK == sw->stag_vid_op) + { + sw->stag_vid_val &= sw->stag_vid_mask; + FIELD_SET(EHMAC_RUL_V2, STAG_VIDV, sw->stag_vid_val); + FIELD_SET_MASK(EHMAC_RUL_M2, STAG_VIDM, sw->stag_vid_mask); + FIELD_SET(EHMAC_RUL_V3, SVIDMSK, 1); + + } + else if (FAL_ACL_FIELD_RANGE == sw->stag_vid_op) + { + FIELD_SET(EHMAC_RUL_V2, STAG_VIDV, sw->stag_vid_val); + FIELD_SET_MASK(EHMAC_RUL_M2, STAG_VIDM, sw->stag_vid_mask); + + } + else if (FAL_ACL_FIELD_LE == sw->stag_vid_op) + { + FIELD_SET(EHMAC_RUL_V2, STAG_VIDV, 0); + FIELD_SET_MASK(EHMAC_RUL_M2, STAG_VIDM, sw->stag_vid_val); + + } + else + { + FIELD_SET(EHMAC_RUL_V2, STAG_VIDV, sw->stag_vid_val); + FIELD_SET_MASK(EHMAC_RUL_M2, STAG_VIDM, 0xfff); + } + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_STAG_PRI)) + { + if (0x0 != sw->stag_pri_mask) + { + *b_care = A_TRUE; + } + + sw->stag_pri_val &= sw->stag_pri_mask; + FIELD_SET(EHMAC_RUL_V2, STAG_PRIV, sw->stag_pri_val); + FIELD_SET_MASK(EHMAC_RUL_M2, STAG_PRIM, sw->stag_pri_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_STAG_DEI)) + { + if (0x0 != sw->stag_dei_mask) + { + *b_care = A_TRUE; + } + + sw->stag_dei_val &= sw->stag_dei_mask; + FIELD_SET(EHMAC_RUL_V2, STAG_DEIV, sw->stag_dei_val); + FIELD_SET_MASK(EHMAC_RUL_M2, STAG_DEIM, sw->stag_dei_mask); + } + + /* Process Ctag Fields */ + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_CTAGGED)) + { + if (0x0 != sw->ctagged_mask) + { + *b_care = A_TRUE; + } + + sw->ctagged_val &= sw->ctagged_mask; + FIELD_SET_MASK(EHMAC_RUL_M4, CTAGGEDV, sw->ctagged_val); + FIELD_SET_MASK(EHMAC_RUL_M4, CTAGGEDM, sw->ctagged_mask); + } + + FIELD_SET_MASK(EHMAC_RUL_M4, CVIDMSK, 1); + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_CTAG_VID)) + { + if ((FAL_ACL_FIELD_MASK != sw->ctag_vid_op) + && (FAL_ACL_FIELD_RANGE != sw->ctag_vid_op) + && (FAL_ACL_FIELD_LE != sw->ctag_vid_op) + && (FAL_ACL_FIELD_GE != sw->ctag_vid_op)) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == + _isis_acl_field_care(sw->ctag_vid_op, sw->ctag_vid_val, + sw->ctag_vid_mask, 0xfff)) + { + *b_care = A_TRUE; + } + + FIELD_SET_MASK(EHMAC_RUL_M4, CVIDMSK, 0); + if (FAL_ACL_FIELD_MASK == sw->ctag_vid_op) + { + sw->ctag_vid_val &= sw->ctag_vid_mask; + FIELD_SET(EHMAC_RUL_V2, CTAG_VIDLV, sw->ctag_vid_val); + FIELD_SET(EHMAC_RUL_V3, CTAG_VIDHV, (sw->ctag_vid_val >> 8)); + FIELD_SET_MASK(EHMAC_RUL_M2, CTAG_VIDLM, sw->ctag_vid_mask); + FIELD_SET_MASK(EHMAC_RUL_M3, CTAG_VIDHM, (sw->ctag_vid_mask >> 8)); + FIELD_SET_MASK(EHMAC_RUL_M4, CVIDMSK, 1); + + } + else if (FAL_ACL_FIELD_RANGE == sw->ctag_vid_op) + { + FIELD_SET(EHMAC_RUL_V2, CTAG_VIDLV, sw->ctag_vid_val); + FIELD_SET(EHMAC_RUL_V3, CTAG_VIDHV, (sw->ctag_vid_val >> 8)); + FIELD_SET_MASK(EHMAC_RUL_M2, CTAG_VIDLM, sw->ctag_vid_mask); + FIELD_SET_MASK(EHMAC_RUL_M3, CTAG_VIDHM, (sw->ctag_vid_mask >> 8)); + + } + else if (FAL_ACL_FIELD_LE == sw->ctag_vid_op) + { + FIELD_SET(EHMAC_RUL_V2, CTAG_VIDLV, 0); + FIELD_SET(EHMAC_RUL_V3, CTAG_VIDHV, 0); + FIELD_SET_MASK(EHMAC_RUL_M2, CTAG_VIDLM, sw->ctag_vid_val); + FIELD_SET_MASK(EHMAC_RUL_M3, CTAG_VIDHM, (sw->ctag_vid_val >> 8)); + + } + else + { + FIELD_SET(EHMAC_RUL_V2, CTAG_VIDLV, sw->ctag_vid_val); + FIELD_SET(EHMAC_RUL_V3, CTAG_VIDHV, (sw->ctag_vid_val >> 8)); + FIELD_SET_MASK(EHMAC_RUL_M2, CTAG_VIDLM, 0xff); + FIELD_SET_MASK(EHMAC_RUL_M3, CTAG_VIDHM, 0xf); + } + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_CTAG_PRI)) + { + if (0x0 != sw->ctag_pri_mask) + { + *b_care = A_TRUE; + } + + sw->ctag_pri_val &= sw->ctag_pri_mask; + FIELD_SET(EHMAC_RUL_V3, CTAG_PRIV, sw->ctag_pri_val); + FIELD_SET_MASK(EHMAC_RUL_M3, CTAG_PRIM, sw->ctag_pri_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_CTAG_CFI)) + { + if (0x0 != sw->ctag_cfi_mask) + { + *b_care = A_TRUE; + } + + sw->ctag_cfi_val &= sw->ctag_cfi_mask; + FIELD_SET(EHMAC_RUL_V3, CTAG_CFIV, sw->ctag_cfi_val); + FIELD_SET_MASK(EHMAC_RUL_M3, CTAG_CFIM, sw->ctag_cfi_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL)) + { + FIELD_SET(MAC_RUL_V4, RULE_INV, 1); + } + + return SW_OK; +} + +static void +_isis_acl_rule_mac_preparse(fal_acl_rule_t * sw, a_bool_t * b_mac, + a_bool_t * eh_mac) +{ + a_uint32_t bm = 0, i, tmp; + + *b_mac = A_FALSE; + *eh_mac = A_FALSE; + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_DA)) + { + for (i = 0; i < 3; i++) + { + if (sw->dest_mac_mask.uc[i]) + { + bm |= DAH; + break; + } + } + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_SA)) + { + for (i = 0; i < 3; i++) + { + if (sw->src_mac_mask.uc[i]) + { + bm |= SAH; + break; + } + } + } + + tmp = 0; + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_TAGGED)) + { + tmp |= ((sw->tagged_mask & 0x1) << 16); + } + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_UP)) + { + tmp |= ((sw->up_mask & 0x7) << 13); + } + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_CFI)) + { + tmp |= ((sw->cfi_mask & 0x1) << 12); + } + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_VID)) + { + if (A_TRUE == + _isis_acl_field_care(sw->vid_op, sw->vid_val, sw->vid_mask, + 0xfff)) + { + tmp |= 0xfff; + } + } + if (tmp) + { + bm |= TAG; + } + + tmp = 0; + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_STAGGED)) + { + tmp |= ((sw->stagged_mask & 0x1) << 16); + } + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_STAG_PRI)) + { + tmp |= ((sw->stag_pri_mask & 0x7) << 13); + } + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_STAG_DEI)) + { + tmp |= ((sw->stag_dei_mask & 0x1) << 12); + } + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_STAG_VID)) + { + if (A_TRUE == + _isis_acl_field_care(sw->stag_vid_op, sw->stag_vid_val, + sw->stag_vid_mask, 0xfff)) + { + tmp |= 0xfff; + } + } + if (tmp) + { + bm |= STAG; + } + + tmp = 0; + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_CTAGGED)) + { + tmp |= ((sw->ctagged_mask & 0x1) << 16); + } + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_CTAG_PRI)) + { + tmp |= ((sw->ctag_pri_mask & 0x7) << 13); + } + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_CTAG_CFI)) + { + tmp |= ((sw->ctag_cfi_mask & 0x1) << 12); + } + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_CTAG_VID)) + { + if (A_TRUE == + _isis_acl_field_care(sw->ctag_vid_op, sw->ctag_vid_val, + sw->ctag_vid_mask, 0xfff)) + { + tmp |= 0xfff; + } + } + if (tmp) + { + bm |= CTAG; + } + + if ((bm & CTAG) || (bm & STAG)) + { + *eh_mac = A_TRUE; + } + + if ((bm & TAG) || ((bm & DAH) && (bm & SAH))) + { + *b_mac = A_TRUE; + } +} + +static sw_error_t +_isis_acl_rule_ip4_parse(fal_acl_rule_t * sw, + hw_filter_t * hw, a_bool_t * b_care) +{ + *b_care = A_FALSE; + aos_mem_zero(&(hw->vlu[0]), sizeof (hw->vlu)); + aos_mem_zero(&(hw->msk[0]), sizeof (hw->msk)); + + FIELD_SET_MASK(MAC_RUL_M4, RULE_TYP, ISIS_IP4_FILTER); + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP_DSCP)) + { + if (0x0 != sw->ip_dscp_mask) + { + *b_care = A_TRUE; + } + + sw->ip_dscp_val &= sw->ip_dscp_mask; + FIELD_SET(IP4_RUL_V2, IP4DSCPV, sw->ip_dscp_val); + FIELD_SET_MASK(IP4_RUL_M2, IP4DSCPM, sw->ip_dscp_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP_PROTO)) + { + if (0x0 != sw->ip_proto_mask) + { + *b_care = A_TRUE; + } + + sw->ip_proto_val &= sw->ip_proto_mask; + FIELD_SET(IP4_RUL_V2, IP4PROTV, sw->ip_proto_val); + FIELD_SET_MASK(IP4_RUL_M2, IP4PROTM, sw->ip_proto_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP4_SIP)) + { + if (0x0 != sw->src_ip4_mask) + { + *b_care = A_TRUE; + } + sw->src_ip4_val &= sw->src_ip4_mask; + hw->vlu[1] = sw->src_ip4_val; + hw->msk[1] = sw->src_ip4_mask; + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP4_DIP)) + { + if (0x0 != sw->dest_ip4_mask) + { + *b_care = A_TRUE; + } + sw->dest_ip4_val &= sw->dest_ip4_mask; + hw->vlu[0] = sw->dest_ip4_val; + hw->msk[0] = sw->dest_ip4_mask; + } + + if ((FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_L4_SPORT)) + && ((FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_ICMP_TYPE)) + || (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_ICMP_CODE)))) + { + return SW_BAD_PARAM; + } + + FIELD_SET_MASK(IP4_RUL_M3, IP4SPORTM_EN, 1); + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_L4_SPORT)) + { + if ((FAL_ACL_FIELD_MASK != sw->src_l4port_op) + && (FAL_ACL_FIELD_RANGE != sw->src_l4port_op) + && (FAL_ACL_FIELD_LE != sw->src_l4port_op) + && (FAL_ACL_FIELD_GE != sw->src_l4port_op)) + { + return SW_NOT_SUPPORTED; + } + + if (A_FALSE == + _isis_acl_field_care(sw->src_l4port_op, sw->src_l4port_val, + sw->src_l4port_mask, 0xffff)) + { + if (FAL_ACL_FIELD_MASK == sw->src_l4port_op) + { + sw->src_l4port_op = FAL_ACL_FIELD_RANGE; + sw->src_l4port_val = 0; + sw->src_l4port_mask = 0xffff; + } + } + *b_care = A_TRUE; + + FIELD_SET_MASK(IP4_RUL_M3, IP4SPORTM_EN, 0); + if (FAL_ACL_FIELD_MASK == sw->src_l4port_op) + { + sw->src_l4port_val &= sw->src_l4port_mask; + FIELD_SET(IP4_RUL_V3, IP4SPORTV, sw->src_l4port_val); + FIELD_SET_MASK(IP4_RUL_M3, IP4SPORTM, sw->src_l4port_mask); + FIELD_SET_MASK(IP4_RUL_M3, IP4SPORTM_EN, 1); + } + else if (FAL_ACL_FIELD_RANGE == sw->src_l4port_op) + { + FIELD_SET(IP4_RUL_V3, IP4SPORTV, sw->src_l4port_val); + FIELD_SET_MASK(IP4_RUL_M3, IP4SPORTM, sw->src_l4port_mask); + } + else if (FAL_ACL_FIELD_LE == sw->src_l4port_op) + { + FIELD_SET(IP4_RUL_V3, IP4SPORTV, 0); + FIELD_SET_MASK(IP4_RUL_M3, IP4SPORTM, sw->src_l4port_val); + } + else + { + FIELD_SET(IP4_RUL_V3, IP4SPORTV, sw->src_l4port_val); + FIELD_SET_MASK(IP4_RUL_M3, IP4SPORTM, 0xffff); + } + } + + FIELD_SET_MASK(IP4_RUL_M3, IP4DPORTM_EN, 1); + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_L4_DPORT)) + { + if ((FAL_ACL_FIELD_MASK != sw->dest_l4port_op) + && (FAL_ACL_FIELD_RANGE != sw->dest_l4port_op) + && (FAL_ACL_FIELD_LE != sw->dest_l4port_op) + && (FAL_ACL_FIELD_GE != sw->dest_l4port_op)) + { + return SW_NOT_SUPPORTED; + } + + if (A_FALSE == + _isis_acl_field_care(sw->dest_l4port_op, sw->dest_l4port_val, + sw->dest_l4port_mask, 0xffff)) + { + if (FAL_ACL_FIELD_MASK == sw->dest_l4port_op) + { + sw->dest_l4port_op = FAL_ACL_FIELD_RANGE; + sw->dest_l4port_val = 0; + sw->dest_l4port_mask = 0xffff; + } + } + *b_care = A_TRUE; + + FIELD_SET_MASK(IP4_RUL_M3, IP4DPORTM_EN, 0); + if (FAL_ACL_FIELD_MASK == sw->dest_l4port_op) + { + sw->dest_l4port_val &= sw->dest_l4port_mask; + FIELD_SET(IP4_RUL_V2, IP4DPORTV, sw->dest_l4port_val); + FIELD_SET_MASK(IP4_RUL_M2, IP4DPORTM, sw->dest_l4port_mask); + FIELD_SET_MASK(IP4_RUL_M3, IP4DPORTM_EN, 1); + } + else if (FAL_ACL_FIELD_RANGE == sw->dest_l4port_op) + { + FIELD_SET(IP4_RUL_V2, IP4DPORTV, sw->dest_l4port_val); + FIELD_SET_MASK(IP4_RUL_M2, IP4DPORTM, sw->dest_l4port_mask); + } + else if (FAL_ACL_FIELD_LE == sw->dest_l4port_op) + { + FIELD_SET(IP4_RUL_V2, IP4DPORTV, 0); + FIELD_SET_MASK(IP4_RUL_M2, IP4DPORTM, sw->dest_l4port_val); + } + else + { + FIELD_SET(IP4_RUL_V2, IP4DPORTV, sw->dest_l4port_val); + FIELD_SET_MASK(IP4_RUL_M2, IP4DPORTM, 0xffff); + } + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_ICMP_TYPE)) + { + if (0x0 != sw->icmp_type_mask) + { + *b_care = A_TRUE; + } + FIELD_SET(IP4_RUL_V3, ICMP_EN, 1); + + sw->icmp_type_val &= sw->icmp_type_mask; + FIELD_SET(IP4_RUL_V3, IP4ICMPTYPV, sw->icmp_type_val); + FIELD_SET_MASK(IP4_RUL_M3, IP4ICMPTYPM, sw->icmp_type_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_ICMP_CODE)) + { + if (0x0 != sw->icmp_code_mask) + { + *b_care = A_TRUE; + } + FIELD_SET(IP4_RUL_V3, ICMP_EN, 1); + + sw->icmp_code_val &= sw->icmp_code_mask; + FIELD_SET(IP4_RUL_V3, IP4ICMPCODEV, sw->icmp_code_val); + FIELD_SET_MASK(IP4_RUL_M3, IP4ICMPCODEM, sw->icmp_code_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_TCP_FLAG)) + { + if (0x0 != sw->tcp_flag_mask) + { + *b_care = A_TRUE; + } + + sw->tcp_flag_val &= sw->tcp_flag_mask; + FIELD_SET(IP4_RUL_V3, IP4TCPFLAGV, sw->tcp_flag_val); + FIELD_SET_MASK(IP4_RUL_M3, IP4TCPFLAGM, sw->tcp_flag_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_RIPV1)) + { + if (0x0 != sw->ripv1_mask) + { + *b_care = A_TRUE; + } + + sw->ripv1_val &= sw->ripv1_mask; + FIELD_SET(IP4_RUL_V3, IP4RIPV, sw->ripv1_val); + FIELD_SET_MASK(IP4_RUL_M3, IP4RIPM, sw->ripv1_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_DHCPV4)) + { + if (0x0 != sw->dhcpv4_mask) + { + *b_care = A_TRUE; + } + + sw->dhcpv4_val &= sw->dhcpv4_mask; + FIELD_SET(IP4_RUL_V3, IP4DHCPV, sw->dhcpv4_val); + FIELD_SET_MASK(IP4_RUL_M3, IP4DHCPM, sw->dhcpv4_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL)) + { + FIELD_SET(MAC_RUL_V4, RULE_INV, 1); + } + + return SW_OK; +} + +static sw_error_t +_isis_acl_rule_ip6r1_parse(fal_acl_rule_t * sw, + hw_filter_t * hw, a_bool_t * b_care) +{ + a_uint32_t i; + + *b_care = A_FALSE; + aos_mem_zero(&(hw->vlu[0]), sizeof (hw->vlu)); + aos_mem_zero(&(hw->msk[0]), sizeof (hw->msk)); + + FIELD_SET_MASK(MAC_RUL_M4, RULE_TYP, ISIS_IP6R1_FILTER); + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP6_DIP)) + { + for (i = 0; i < 4; i++) + { + if (0x0 != sw->dest_ip6_mask.ul[i]) + { + *b_care = A_TRUE; + } + + sw->dest_ip6_val.ul[3 - i] &= sw->dest_ip6_mask.ul[3 - i]; + hw->vlu[i] = sw->dest_ip6_val.ul[3 - i]; + hw->msk[i] = sw->dest_ip6_mask.ul[3 - i]; + } + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL)) + { + FIELD_SET(MAC_RUL_V4, RULE_INV, 1); + } + + return SW_OK; +} + +static sw_error_t +_isis_acl_rule_ip6r2_parse(fal_acl_rule_t * sw, + hw_filter_t * hw, a_bool_t * b_care) +{ + a_uint32_t i; + + *b_care = A_FALSE; + aos_mem_zero(&(hw->vlu[0]), sizeof (hw->vlu)); + aos_mem_zero(&(hw->msk[0]), sizeof (hw->msk)); + + FIELD_SET_MASK(MAC_RUL_M4, RULE_TYP, ISIS_IP6R2_FILTER); + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP6_SIP)) + { + for (i = 0; i < 4; i++) + { + if (0x0 != sw->src_ip6_mask.ul[i]) + { + *b_care = A_TRUE; + } + + sw->src_ip6_val.ul[3 - i] &= sw->src_ip6_mask.ul[3 - i]; + hw->vlu[i] = sw->src_ip6_val.ul[3 - i]; + hw->msk[i] = sw->src_ip6_mask.ul[3 - i]; + } + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL)) + { + FIELD_SET(MAC_RUL_V4, RULE_INV, 1); + } + + return SW_OK; +} + +static sw_error_t +_isis_acl_rule_ip6r3_parse(fal_acl_rule_t * sw, + hw_filter_t * hw, a_bool_t * b_care) +{ + *b_care = A_FALSE; + aos_mem_zero(&(hw->vlu[0]), sizeof (hw->vlu)); + aos_mem_zero(&(hw->msk[0]), sizeof (hw->msk)); + + FIELD_SET_MASK(MAC_RUL_M4, RULE_TYP, ISIS_IP6R3_FILTER); + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP6_LABEL)) + { + if (0x0 != sw->ip6_lable_mask) + { + *b_care = A_TRUE; + } + + sw->ip6_lable_val &= sw->ip6_lable_mask; + FIELD_SET(IP6_RUL3_V1, IP6LABEL1V, sw->ip6_lable_val); + FIELD_SET_MASK(IP6_RUL3_M1, IP6LABEL1M, sw->ip6_lable_mask); + + FIELD_SET(IP6_RUL3_V2, IP6LABEL2V, (sw->ip6_lable_val >> 16)); + FIELD_SET_MASK(IP6_RUL3_M2, IP6LABEL2M, (sw->ip6_lable_mask >> 16)); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP_PROTO)) + { + if (0x0 != sw->ip_proto_mask) + { + *b_care = A_TRUE; + } + + sw->ip_proto_val &= sw->ip_proto_mask; + FIELD_SET(IP6_RUL3_V0, IP6PROTV, sw->ip_proto_val); + FIELD_SET_MASK(IP6_RUL3_M0, IP6PROTM, sw->ip_proto_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP_DSCP)) + { + if (0x0 != sw->ip_dscp_mask) + { + *b_care = A_TRUE; + } + + sw->ip_dscp_val &= sw->ip_dscp_mask; + FIELD_SET(IP6_RUL3_V0, IP6DSCPV, sw->ip_dscp_val); + FIELD_SET_MASK(IP6_RUL3_M0, IP6DSCPM, sw->ip_dscp_mask); + } + + if ((FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_L4_SPORT)) + && ((FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_ICMP_TYPE)) + || (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_ICMP_CODE)))) + { + return SW_BAD_PARAM; + } + + FIELD_SET_MASK(IP6_RUL3_M3, IP6SPORTM_EN, 1); + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_L4_SPORT)) + { + if ((FAL_ACL_FIELD_MASK != sw->src_l4port_op) + && (FAL_ACL_FIELD_RANGE != sw->src_l4port_op) + && (FAL_ACL_FIELD_LE != sw->src_l4port_op) + && (FAL_ACL_FIELD_GE != sw->src_l4port_op)) + { + return SW_NOT_SUPPORTED; + } + + if (A_FALSE == + _isis_acl_field_care(sw->src_l4port_op, sw->src_l4port_val, + sw->src_l4port_mask, 0xffff)) + { + if (FAL_ACL_FIELD_MASK == sw->src_l4port_op) + { + sw->src_l4port_op = FAL_ACL_FIELD_RANGE; + sw->src_l4port_val = 0; + sw->src_l4port_mask = 0xffff; + } + } + *b_care = A_TRUE; + + FIELD_SET_MASK(IP6_RUL3_M3, IP6SPORTM_EN, 0); + if (FAL_ACL_FIELD_MASK == sw->src_l4port_op) + { + sw->src_l4port_val &= sw->src_l4port_mask; + FIELD_SET(IP6_RUL3_V3, IP6SPORTV, sw->src_l4port_val); + FIELD_SET_MASK(IP6_RUL3_M3, IP6SPORTM, sw->src_l4port_mask); + FIELD_SET_MASK(IP6_RUL3_M3, IP6SPORTM_EN, 1); + + } + else if (FAL_ACL_FIELD_RANGE == sw->src_l4port_op) + { + FIELD_SET(IP6_RUL3_V3, IP6SPORTV, sw->src_l4port_val); + FIELD_SET_MASK(IP6_RUL3_M3, IP6SPORTM, sw->src_l4port_mask); + + } + else if (FAL_ACL_FIELD_LE == sw->src_l4port_op) + { + FIELD_SET(IP6_RUL3_V3, IP6SPORTV, 0); + FIELD_SET_MASK(IP6_RUL3_M3, IP6SPORTM, sw->src_l4port_val); + + } + else + { + FIELD_SET(IP6_RUL3_V3, IP6SPORTV, sw->src_l4port_val); + FIELD_SET_MASK(IP6_RUL3_M3, IP6SPORTM, 0xffff); + } + } + + FIELD_SET_MASK(IP6_RUL3_M3, IP6DPORTM_EN, 1); + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_L4_DPORT)) + { + if ((FAL_ACL_FIELD_MASK != sw->dest_l4port_op) + && (FAL_ACL_FIELD_RANGE != sw->dest_l4port_op) + && (FAL_ACL_FIELD_LE != sw->dest_l4port_op) + && (FAL_ACL_FIELD_GE != sw->dest_l4port_op)) + { + return SW_NOT_SUPPORTED; + } + + if (A_FALSE == + _isis_acl_field_care(sw->dest_l4port_op, sw->dest_l4port_val, + sw->dest_l4port_mask, 0xffff)) + { + if (FAL_ACL_FIELD_MASK == sw->dest_l4port_op) + { + sw->dest_l4port_op = FAL_ACL_FIELD_RANGE; + sw->dest_l4port_val = 0; + sw->dest_l4port_mask = 0xffff; + } + } + *b_care = A_TRUE; + + FIELD_SET_MASK(IP6_RUL3_M3, IP6DPORTM_EN, 0); + if (FAL_ACL_FIELD_MASK == sw->dest_l4port_op) + { + sw->dest_l4port_val &= sw->dest_l4port_mask; + FIELD_SET(IP6_RUL3_V2, IP6DPORTV, sw->dest_l4port_val); + FIELD_SET_MASK(IP6_RUL3_M2, IP6DPORTM, sw->dest_l4port_mask); + FIELD_SET_MASK(IP6_RUL3_M3, IP6DPORTM_EN, 1); + } + else if (FAL_ACL_FIELD_RANGE == sw->dest_l4port_op) + { + FIELD_SET(IP6_RUL3_V2, IP6DPORTV, sw->dest_l4port_val); + FIELD_SET_MASK(IP6_RUL3_M2, IP6DPORTM, sw->dest_l4port_mask); + } + else if (FAL_ACL_FIELD_LE == sw->dest_l4port_op) + { + FIELD_SET(IP6_RUL3_V2, IP6DPORTV, 0); + FIELD_SET_MASK(IP6_RUL3_M2, IP6DPORTM, sw->dest_l4port_val); + } + else + { + FIELD_SET(IP6_RUL3_V2, IP6DPORTV, sw->dest_l4port_val); + FIELD_SET_MASK(IP6_RUL3_M2, IP6DPORTM, 0xffff); + } + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_ICMP_TYPE)) + { + if (0x0 != sw->icmp_type_mask) + { + *b_care = A_TRUE; + } + FIELD_SET(IP6_RUL3_V3, ICMP6_EN, 1); + + sw->icmp_type_val &= sw->icmp_type_mask; + FIELD_SET(IP6_RUL3_V3, IP6ICMPTYPV, sw->icmp_type_val); + FIELD_SET_MASK(IP6_RUL3_M3, IP6ICMPTYPM, sw->icmp_type_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_ICMP_CODE)) + { + if (0x0 != sw->icmp_code_mask) + { + *b_care = A_TRUE; + } + FIELD_SET(IP6_RUL3_V3, ICMP6_EN, 1); + + sw->icmp_code_val &= sw->icmp_code_mask; + FIELD_SET(IP6_RUL3_V3, IP6ICMPCODEV, sw->icmp_code_val); + FIELD_SET_MASK(IP6_RUL3_M3, IP6ICMPCODEM, sw->icmp_code_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_TCP_FLAG)) + { + if (0x0 != sw->tcp_flag_mask) + { + *b_care = A_TRUE; + } + + sw->tcp_flag_val &= sw->tcp_flag_mask; + FIELD_SET(IP6_RUL3_V3, IP6TCPFLAGV, sw->tcp_flag_val); + FIELD_SET_MASK(IP6_RUL3_M3, IP6TCPFLAGM, sw->tcp_flag_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_DHCPV6)) + { + if (0x0 != sw->dhcpv6_mask) + { + *b_care = A_TRUE; + } + + sw->dhcpv6_val &= sw->dhcpv6_mask; + FIELD_SET(IP6_RUL3_V3, IP6DHCPV, sw->dhcpv6_val); + FIELD_SET_MASK(IP6_RUL3_M3, IP6DHCPM, sw->dhcpv6_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL)) + { + FIELD_SET(MAC_RUL_V4, RULE_INV, 1); + } + + return SW_OK; +} + +static sw_error_t +_isis_acl_rule_udf_parse(fal_acl_rule_t * sw, + hw_filter_t * hw, a_bool_t * b_care) +{ + a_uint32_t i; + + *b_care = A_FALSE; + aos_mem_zero(&(hw->vlu[0]), sizeof (hw->vlu)); + aos_mem_zero(&(hw->msk[0]), sizeof (hw->msk)); + + FIELD_SET_MASK(MAC_RUL_M4, RULE_TYP, ISIS_UDF_FILTER); + + if (!FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_UDF)) + { + if (FAL_ACL_RULE_UDF == sw->rule_type) + { + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL)) + { + FIELD_SET(MAC_RUL_V4, RULE_INV, 1); + } + *b_care = A_TRUE; + } + return SW_OK; + } + + if (ISIS_MAX_UDF_LENGTH < sw->udf_len) + { + return SW_NOT_SUPPORTED; + } + + *b_care = A_TRUE; + for (i = 0; i < sw->udf_len; i++) + { + hw->vlu[3 - i / 4] |= + ((sw->udf_mask[i] & sw->udf_val[i]) << (24 - 8 * (i % 4))); + hw->msk[3 - i / 4] |= ((sw->udf_mask[i]) << (24 - 8 * i)); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL)) + { + FIELD_SET(MAC_RUL_V4, RULE_INV, 1); + } + + return SW_OK; +} + +static sw_error_t +_isis_acl_action_parse(a_uint32_t dev_id, const fal_acl_rule_t * sw, + hw_filter_t * hw) +{ + fal_pbmp_t des_pts; + + aos_mem_zero(&(hw->act[0]), sizeof (hw->act)); + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_MATCH_TRIGGER_INTR)) + { + FIELD_SET_ACTION(ACL_RSLT2, TRIGGER_INTR, 1); + } + + /* FAL_ACL_ACTION_PERMIT need't process */ + + if ((FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_RDTCPU)) + && (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_CPYCPU))) + { + return SW_BAD_PARAM; + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_RDTCPU)) + { + FIELD_SET_ACTION(ACL_RSLT2, FWD_CMD, 0x3); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_CPYCPU)) + { + FIELD_SET_ACTION(ACL_RSLT2, FWD_CMD, 0x1); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_DENY)) + { + FIELD_SET_ACTION(ACL_RSLT2, FWD_CMD, 0x7); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_MIRROR)) + { + FIELD_SET_ACTION(ACL_RSLT2, MIRR_EN, 1); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REDPT)) + { + FIELD_SET_ACTION(ACL_RSLT2, DES_PORT_EN, 1); + + des_pts = (sw->ports >> 3) & 0xf; + FIELD_SET_ACTION(ACL_RSLT2, DES_PORT1, des_pts); + + des_pts = sw->ports & 0x7; + FIELD_SET_ACTION(ACL_RSLT1, DES_PORT0, des_pts); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REMARK_UP)) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REMARK_QUEUE)) + { + FIELD_SET_ACTION(ACL_RSLT1, PRI_QU_EN, 1); + FIELD_SET_ACTION(ACL_RSLT1, PRI_QU, sw->queue); + } + + if ((FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_MODIFY_VLAN)) + || (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_NEST_VLAN))) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REMARK_DSCP)) + { + FIELD_SET_ACTION(ACL_RSLT1, DSCPV, sw->dscp); + FIELD_SET_ACTION(ACL_RSLT1, DSCP_REMAP, 1); + } + + FIELD_SET_ACTION(ACL_RSLT0, STAGVID, sw->stag_vid); + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REMARK_STAG_VID)) + { + FIELD_SET_ACTION(ACL_RSLT1, TRANS_SVID_CHG, 1); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REMARK_STAG_PRI)) + { + FIELD_SET_ACTION(ACL_RSLT0, STAGPRI, sw->stag_pri); + FIELD_SET_ACTION(ACL_RSLT1, STAG_PRI_REMAP, 1); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REMARK_STAG_DEI)) + { + FIELD_SET_ACTION(ACL_RSLT0, STAGDEI, sw->stag_dei); + FIELD_SET_ACTION(ACL_RSLT1, STAG_DEI_CHG, 1); + } + + FIELD_SET_ACTION(ACL_RSLT0, CTAGVID, sw->ctag_vid); + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REMARK_CTAG_VID)) + { + FIELD_SET_ACTION(ACL_RSLT1, TRANS_CVID_CHG, 1); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REMARK_CTAG_PRI)) + { + FIELD_SET_ACTION(ACL_RSLT0, CTAGPRI, sw->ctag_pri); + FIELD_SET_ACTION(ACL_RSLT1, CTAG_PRI_REMAP, 1); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REMARK_CTAG_CFI)) + { + FIELD_SET_ACTION(ACL_RSLT0, CTAGCFI, sw->ctag_cfi); + FIELD_SET_ACTION(ACL_RSLT1, CTAG_CFI_CHG, 1); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REMARK_LOOKUP_VID)) + { + FIELD_SET_ACTION(ACL_RSLT1, LOOK_VID_CHG, 1); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_POLICER_EN)) + { + FIELD_SET_ACTION(ACL_RSLT2, POLICER_PTR, sw->policer_ptr); + FIELD_SET_ACTION(ACL_RSLT2, POLICER_EN, 1); + } + + if ((FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_ARP_EN)) + && (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_WCMP_EN))) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_ARP_EN)) + { + FIELD_SET_ACTION(ACL_RSLT1, ARP_PTR, sw->arp_ptr); + FIELD_SET_ACTION(ACL_RSLT1, ARP_PTR_EN, 1); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_WCMP_EN)) + { + FIELD_SET_ACTION(ACL_RSLT1, ARP_PTR, sw->wcmp_ptr); + FIELD_SET_ACTION(ACL_RSLT1, WCMP_EN, 1); + FIELD_SET_ACTION(ACL_RSLT1, ARP_PTR_EN, 1); + } + + FIELD_SET_ACTION(ACL_RSLT1, FORCE_L3_MODE, 0x0); + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_POLICY_FORWARD_EN)) + { + if (FAL_ACL_POLICY_ROUTE == sw->policy_fwd) + { + return SW_NOT_SUPPORTED; + } + else if (FAL_ACL_POLICY_SNAT == sw->policy_fwd) + { + FIELD_SET_ACTION(ACL_RSLT1, FORCE_L3_MODE, 0x1); + } + else if (FAL_ACL_POLICY_DNAT == sw->policy_fwd) + { + FIELD_SET_ACTION(ACL_RSLT1, FORCE_L3_MODE, 0x2); + } + else if (FAL_ACL_POLICY_RESERVE == sw->policy_fwd) + { + FIELD_SET_ACTION(ACL_RSLT1, FORCE_L3_MODE, 0x3); + } + else + { + return SW_BAD_PARAM; + } + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_BYPASS_EGRESS_TRANS)) + { + FIELD_SET_ACTION(ACL_RSLT2, EG_BYPASS, 1); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_MATCH_TRIGGER_INTR)) + { + FIELD_SET_ACTION(ACL_RSLT2, TRIGGER_INTR, 1); + } + + return SW_OK; +} + +static sw_error_t +_isis_acl_rule_bmac_reparse(fal_acl_rule_t * sw, const hw_filter_t * hw) +{ + a_uint32_t mask_en; + + /* destnation mac address */ + FIELD_GET(MAC_RUL_V0, DAV_BYTE2, sw->dest_mac_val.uc[2]); + FIELD_GET(MAC_RUL_V0, DAV_BYTE3, sw->dest_mac_val.uc[3]); + FIELD_GET(MAC_RUL_V0, DAV_BYTE4, sw->dest_mac_val.uc[4]); + FIELD_GET(MAC_RUL_V0, DAV_BYTE5, sw->dest_mac_val.uc[5]); + FIELD_GET(MAC_RUL_V1, DAV_BYTE0, sw->dest_mac_val.uc[0]); + FIELD_GET(MAC_RUL_V1, DAV_BYTE1, sw->dest_mac_val.uc[1]); + + FIELD_GET_MASK(MAC_RUL_M0, DAM_BYTE2, sw->dest_mac_mask.uc[2]); + FIELD_GET_MASK(MAC_RUL_M0, DAM_BYTE3, sw->dest_mac_mask.uc[3]); + FIELD_GET_MASK(MAC_RUL_M0, DAM_BYTE4, sw->dest_mac_mask.uc[4]); + FIELD_GET_MASK(MAC_RUL_M0, DAM_BYTE5, sw->dest_mac_mask.uc[5]); + FIELD_GET_MASK(MAC_RUL_M1, DAM_BYTE0, sw->dest_mac_mask.uc[0]); + FIELD_GET_MASK(MAC_RUL_M1, DAM_BYTE1, sw->dest_mac_mask.uc[1]); + if (A_FALSE == _isis_acl_zero_addr(sw->dest_mac_mask)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_DA); + } + + /* source mac address */ + FIELD_GET(MAC_RUL_V2, SAV_BYTE0, sw->src_mac_val.uc[0]); + FIELD_GET(MAC_RUL_V2, SAV_BYTE1, sw->src_mac_val.uc[1]); + FIELD_GET(MAC_RUL_V2, SAV_BYTE2, sw->src_mac_val.uc[2]); + FIELD_GET(MAC_RUL_V2, SAV_BYTE3, sw->src_mac_val.uc[3]); + FIELD_GET(MAC_RUL_V1, SAV_BYTE4, sw->src_mac_val.uc[4]); + FIELD_GET(MAC_RUL_V1, SAV_BYTE5, sw->src_mac_val.uc[5]); + + FIELD_GET_MASK(MAC_RUL_M2, SAM_BYTE0, sw->src_mac_mask.uc[0]); + FIELD_GET_MASK(MAC_RUL_M2, SAM_BYTE1, sw->src_mac_mask.uc[1]); + FIELD_GET_MASK(MAC_RUL_M2, SAM_BYTE2, sw->src_mac_mask.uc[2]); + FIELD_GET_MASK(MAC_RUL_M2, SAM_BYTE3, sw->src_mac_mask.uc[3]); + FIELD_GET_MASK(MAC_RUL_M1, SAM_BYTE4, sw->src_mac_mask.uc[4]); + FIELD_GET_MASK(MAC_RUL_M1, SAM_BYTE5, sw->src_mac_mask.uc[5]); + if (A_FALSE == _isis_acl_zero_addr(sw->src_mac_mask)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_SA); + } + + /* ethernet type */ + FIELD_GET(MAC_RUL_V3, ETHTYPV, sw->ethtype_val); + FIELD_GET_MASK(MAC_RUL_M3, ETHTYPM, sw->ethtype_mask); + if (0x0 != sw->ethtype_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_ETHTYPE); + } + + /* packet tagged */ + FIELD_GET_MASK(MAC_RUL_M4, TAGGEDV, sw->tagged_val); + FIELD_GET_MASK(MAC_RUL_M4, TAGGEDM, sw->tagged_mask); + if (0x0 != sw->tagged_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_TAGGED); + } + + /* vlan priority */ + FIELD_GET(MAC_RUL_V3, VLANPRIV, sw->up_val); + FIELD_GET_MASK(MAC_RUL_M3, VLANPRIM, sw->up_mask); + if (0x0 != sw->up_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_UP); + } + + /* vlanid */ + FIELD_GET(MAC_RUL_V3, VLANIDV, sw->vid_val); + FIELD_GET_MASK(MAC_RUL_M3, VLANIDM, sw->vid_mask); + FIELD_GET_MASK(MAC_RUL_M4, VIDMSK, mask_en); + if (mask_en) + { + sw->vid_op = FAL_ACL_FIELD_MASK; + } + else + { + sw->vid_op = FAL_ACL_FIELD_RANGE; + } + + if (A_TRUE == + _isis_acl_field_care(sw->vid_op, (a_uint32_t) sw->vid_val, + (a_uint32_t) sw->vid_mask, 0xfff)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_VID); + } + + /* vlan cfi */ + FIELD_GET(MAC_RUL_V3, VLANCFIV, sw->cfi_val); + FIELD_GET_MASK(MAC_RUL_M3, VLANCFIM, sw->cfi_mask); + if (0x0 != sw->cfi_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_CFI); + } + + FIELD_GET(MAC_RUL_V4, RULE_INV, mask_en); + if (mask_en) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL); + } + + return SW_OK; +} + +static sw_error_t +_isis_acl_rule_ehmac_reparse(fal_acl_rule_t * sw, const hw_filter_t * hw) +{ + a_uint32_t i, mask_en, data; + + FIELD_GET(EHMAC_RUL_V3, DA_EN, data); + if (data) + { + for (i = 2; i < 6; i++) + { + sw->dest_mac_val.uc[i] = ((hw->vlu[0]) >> ((5 - i) << 3)) & 0xff; + sw->dest_mac_mask.uc[i] = ((hw->msk[0]) >> ((5 - i) << 3)) & 0xff; + } + + for (i = 0; i < 2; i++) + { + sw->dest_mac_val.uc[i] = ((hw->vlu[1]) >> ((1 - i) << 3)) & 0xff; + sw->dest_mac_mask.uc[i] = ((hw->msk[1]) >> ((1 - i) << 3)) & 0xff; + } + + if (A_FALSE == _isis_acl_zero_addr(sw->dest_mac_mask)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_DA); + } + + FIELD_GET(EHMAC_RUL_V2, SAV_BYTE3, sw->src_mac_val.uc[3]); + FIELD_GET(EHMAC_RUL_V1, SAV_BYTE4, sw->src_mac_val.uc[4]); + FIELD_GET(EHMAC_RUL_V1, SAV_BYTE5, sw->src_mac_val.uc[5]); + + FIELD_GET_MASK(EHMAC_RUL_M2, SAM_BYTE3, sw->src_mac_mask.uc[3]); + FIELD_GET_MASK(EHMAC_RUL_M1, SAM_BYTE4, sw->src_mac_mask.uc[4]); + FIELD_GET_MASK(EHMAC_RUL_M1, SAM_BYTE5, sw->src_mac_mask.uc[5]); + + if (A_FALSE == _isis_acl_zero_addr(sw->src_mac_mask)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_SA); + } + } + else + { + for (i = 2; i < 6; i++) + { + sw->src_mac_val.uc[i] = ((hw->vlu[0]) >> ((5 - i) << 3)) & 0xff; + sw->src_mac_mask.uc[i] = ((hw->msk[0]) >> ((5 - i) << 3)) & 0xff; + } + + for (i = 0; i < 2; i++) + { + sw->src_mac_val.uc[i] = ((hw->vlu[1]) >> ((1 - i) << 3)) & 0xff; + sw->src_mac_mask.uc[i] = ((hw->msk[1]) >> ((1 - i) << 3)) & 0xff; + } + + if (A_FALSE == _isis_acl_zero_addr(sw->src_mac_mask)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_SA); + } + + FIELD_GET(EHMAC_RUL_V2, SAV_BYTE3, sw->dest_mac_val.uc[3]); + FIELD_GET(EHMAC_RUL_V1, SAV_BYTE4, sw->dest_mac_val.uc[4]); + FIELD_GET(EHMAC_RUL_V1, SAV_BYTE5, sw->dest_mac_val.uc[5]); + + FIELD_GET_MASK(EHMAC_RUL_M2, SAM_BYTE3, sw->dest_mac_mask.uc[3]); + FIELD_GET_MASK(EHMAC_RUL_M1, SAM_BYTE4, sw->dest_mac_mask.uc[4]); + FIELD_GET_MASK(EHMAC_RUL_M1, SAM_BYTE5, sw->dest_mac_mask.uc[5]); + if (A_FALSE == _isis_acl_zero_addr(sw->dest_mac_mask)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_DA); + } + } + + /* ethernet type */ + FIELD_GET(EHMAC_RUL_V3, ETHTYPV, sw->ethtype_val); + FIELD_GET_MASK(EHMAC_RUL_M3, ETHTYPM, sw->ethtype_mask); + if (0x0 != sw->ethtype_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_ETHTYPE); + } + + /* packet stagged */ + FIELD_GET(EHMAC_RUL_V3, STAGGEDV, sw->stagged_val); + FIELD_GET(EHMAC_RUL_V3, STAGGEDM, sw->stagged_mask); + if (0x0 != sw->stagged_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_STAGGED); + } + + /* stag vid */ + FIELD_GET(EHMAC_RUL_V2, STAG_VIDV, sw->stag_vid_val); + FIELD_GET_MASK(EHMAC_RUL_M2, STAG_VIDM, sw->stag_vid_mask); + FIELD_GET(EHMAC_RUL_V3, SVIDMSK, mask_en); + if (mask_en) + { + sw->stag_vid_op = FAL_ACL_FIELD_MASK; + } + else + { + sw->stag_vid_op = FAL_ACL_FIELD_RANGE; + } + + if (A_TRUE == + _isis_acl_field_care(sw->stag_vid_op, (a_uint32_t) sw->stag_vid_val, + (a_uint32_t) sw->stag_vid_mask, 0xfff)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_STAG_VID); + } + + /* stag priority */ + FIELD_GET(EHMAC_RUL_V2, STAG_PRIV, sw->stag_pri_val); + FIELD_GET_MASK(EHMAC_RUL_M2, STAG_PRIM, sw->stag_pri_mask); + if (0x0 != sw->stag_pri_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_STAG_PRI); + } + + /* stag dei */ + FIELD_GET(EHMAC_RUL_V2, STAG_DEIV, sw->stag_dei_val); + FIELD_GET_MASK(EHMAC_RUL_M2, STAG_DEIM, sw->stag_dei_mask); + if (0x0 != sw->stag_dei_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_STAG_DEI); + } + + /* packet ctagged */ + FIELD_GET_MASK(EHMAC_RUL_M4, CTAGGEDV, sw->ctagged_val); + FIELD_GET_MASK(EHMAC_RUL_M4, CTAGGEDM, sw->ctagged_mask); + if (0x0 != sw->ctagged_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_CTAGGED); + } + + /* ctag vid */ + FIELD_GET(EHMAC_RUL_V2, CTAG_VIDLV, sw->ctag_vid_val); + FIELD_GET(EHMAC_RUL_V3, CTAG_VIDHV, data); + sw->ctag_vid_val |= (data << 8); + FIELD_GET_MASK(EHMAC_RUL_M2, CTAG_VIDLM, sw->ctag_vid_mask); + FIELD_GET_MASK(EHMAC_RUL_M3, CTAG_VIDHM, data); + sw->ctag_vid_mask |= (data << 8); + + FIELD_GET_MASK(EHMAC_RUL_M4, CVIDMSK, mask_en); + if (mask_en) + { + sw->ctag_vid_op = FAL_ACL_FIELD_MASK; + } + else + { + sw->ctag_vid_op = FAL_ACL_FIELD_RANGE; + } + + if (A_TRUE == + _isis_acl_field_care(sw->ctag_vid_op, (a_uint32_t) sw->ctag_vid_val, + (a_uint32_t) sw->ctag_vid_mask, 0xfff)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_CTAG_VID); + } + + /* ctag priority */ + FIELD_GET(EHMAC_RUL_V3, CTAG_PRIV, sw->ctag_pri_val); + FIELD_GET_MASK(EHMAC_RUL_M3, CTAG_PRIM, sw->ctag_pri_mask); + if (0x0 != sw->ctag_pri_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_CTAG_PRI); + } + + /* ctag dei */ + FIELD_GET(EHMAC_RUL_V3, CTAG_CFIV, sw->ctag_cfi_val); + FIELD_GET_MASK(EHMAC_RUL_M3, CTAG_CFIM, sw->ctag_cfi_mask); + if (0x0 != sw->ctag_cfi_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_CTAG_CFI); + } + + FIELD_GET(MAC_RUL_V4, RULE_INV, mask_en); + if (mask_en) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL); + } + + return SW_OK; +} + +static sw_error_t +_isis_acl_rule_ip4_reparse(fal_acl_rule_t * sw, const hw_filter_t * hw) +{ + a_uint32_t mask_en, icmp_en; + + sw->dest_ip4_val = hw->vlu[0]; + sw->dest_ip4_mask = hw->msk[0]; + if (0x0 != sw->dest_ip4_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP4_DIP); + } + + sw->src_ip4_val = hw->vlu[1]; + sw->src_ip4_mask = hw->msk[1]; + if (0x0 != sw->src_ip4_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP4_SIP); + } + + FIELD_GET(IP4_RUL_V2, IP4PROTV, sw->ip_proto_val); + FIELD_GET_MASK(IP4_RUL_M2, IP4PROTM, sw->ip_proto_mask); + if (0x0 != sw->ip_proto_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP_PROTO); + } + + FIELD_GET(IP4_RUL_V2, IP4DSCPV, sw->ip_dscp_val); + FIELD_GET_MASK(IP4_RUL_M2, IP4DSCPM, sw->ip_dscp_mask); + if (0x0 != sw->ip_dscp_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP_DSCP); + } + + FIELD_GET(IP4_RUL_V2, IP4DPORTV, sw->dest_l4port_val); + FIELD_GET_MASK(IP4_RUL_M2, IP4DPORTM, sw->dest_l4port_mask); + FIELD_GET_MASK(IP4_RUL_M3, IP4DPORTM_EN, mask_en); + if (mask_en) + { + sw->dest_l4port_op = FAL_ACL_FIELD_MASK; + } + else + { + sw->dest_l4port_op = FAL_ACL_FIELD_RANGE; + } + + if (A_TRUE == + _isis_acl_field_care(sw->dest_l4port_op, + (a_uint32_t) sw->dest_l4port_val, + (a_uint32_t) sw->dest_l4port_mask, 0xffff)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_DPORT); + } + else if (FAL_ACL_FIELD_RANGE == sw->dest_l4port_op) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_DPORT); + } + + FIELD_GET(IP4_RUL_V3, ICMP_EN, icmp_en); + if (icmp_en) + { + FIELD_GET(IP4_RUL_V3, IP4ICMPTYPV, sw->icmp_type_val); + FIELD_GET_MASK(IP4_RUL_M3, IP4ICMPTYPM, sw->icmp_type_mask); + if (0x0 != sw->icmp_type_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_ICMP_TYPE); + } + + FIELD_GET(IP4_RUL_V3, IP4ICMPCODEV, sw->icmp_code_val); + FIELD_GET_MASK(IP4_RUL_M3, IP4ICMPCODEM, sw->icmp_code_mask); + if (0x0 != sw->icmp_code_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_ICMP_CODE); + } + } + else + { + FIELD_GET(IP4_RUL_V3, IP4SPORTV, sw->src_l4port_val); + FIELD_GET_MASK(IP4_RUL_M3, IP4SPORTM, sw->src_l4port_mask); + FIELD_GET_MASK(IP4_RUL_M3, IP4SPORTM_EN, mask_en); + if (mask_en) + { + sw->src_l4port_op = FAL_ACL_FIELD_MASK; + } + else + { + sw->src_l4port_op = FAL_ACL_FIELD_RANGE; + } + + if (A_TRUE == + _isis_acl_field_care(sw->src_l4port_op, + (a_uint32_t) sw->src_l4port_val, + (a_uint32_t) sw->src_l4port_mask, 0xffff)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_SPORT); + } + else if (FAL_ACL_FIELD_RANGE == sw->src_l4port_op) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_SPORT); + } + } + + FIELD_GET(IP4_RUL_V3, IP4TCPFLAGV, sw->tcp_flag_val); + FIELD_GET_MASK(IP4_RUL_M3, IP4TCPFLAGM, sw->tcp_flag_mask); + if (0x0 != sw->tcp_flag_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_TCP_FLAG); + } + + FIELD_GET(IP4_RUL_V3, IP4RIPV, sw->ripv1_val); + FIELD_GET_MASK(IP4_RUL_M3, IP4RIPM, sw->ripv1_mask); + if (0x0 != sw->ripv1_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_RIPV1); + } + + FIELD_GET(IP4_RUL_V3, IP4DHCPV, sw->dhcpv4_val); + FIELD_GET_MASK(IP4_RUL_M3, IP4DHCPM, sw->dhcpv4_mask); + if (0x0 != sw->dhcpv4_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_DHCPV4); + } + + FIELD_GET(MAC_RUL_V4, RULE_INV, mask_en); + if (mask_en) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL); + } + + return SW_OK; +} + +static sw_error_t +_isis_acl_rule_ip6r1_reparse(fal_acl_rule_t * sw, const hw_filter_t * hw) +{ + a_uint32_t i; + + for (i = 0; i < 4; i++) + { + sw->dest_ip6_val.ul[i] = hw->vlu[3 - i]; + sw->dest_ip6_mask.ul[i] = hw->msk[3 - i]; + if (0x0 != sw->dest_ip6_mask.ul[i]) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP6_DIP); + } + } + + FIELD_GET(MAC_RUL_V4, RULE_INV, i); + if (i) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL); + } + + return SW_OK; +} + +static sw_error_t +_isis_acl_rule_ip6r2_reparse(fal_acl_rule_t * sw, const hw_filter_t * hw) +{ + a_uint32_t i; + + for (i = 0; i < 4; i++) + { + sw->src_ip6_val.ul[i] = hw->vlu[3 - i]; + sw->src_ip6_mask.ul[i] = hw->msk[3 - i]; + if (0x0 != sw->src_ip6_mask.ul[i]) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP6_SIP); + } + } + + FIELD_GET(MAC_RUL_V4, RULE_INV, i); + if (i) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL); + } + + return SW_OK; +} + +static sw_error_t +_isis_acl_rule_ip6r3_reparse(fal_acl_rule_t * sw, const hw_filter_t * hw) +{ + a_uint32_t mask_en, icmp6_en, tmp; + + FIELD_GET(IP6_RUL3_V0, IP6PROTV, sw->ip_proto_val); + FIELD_GET_MASK(IP6_RUL3_M0, IP6PROTM, sw->ip_proto_mask); + if (0x0 != sw->ip_proto_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP_PROTO); + } + + FIELD_GET(IP6_RUL3_V0, IP6DSCPV, sw->ip_dscp_val); + FIELD_GET_MASK(IP6_RUL3_M0, IP6DSCPM, sw->ip_dscp_mask); + if (0x0 != sw->ip_dscp_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP_DSCP); + } + + FIELD_GET(IP6_RUL3_V2, IP6DPORTV, sw->dest_l4port_val); + FIELD_GET_MASK(IP6_RUL3_M2, IP6DPORTM, sw->dest_l4port_mask); + FIELD_GET_MASK(IP6_RUL3_M3, IP6DPORTM_EN, mask_en); + if (mask_en) + { + sw->dest_l4port_op = FAL_ACL_FIELD_MASK; + } + else + { + sw->dest_l4port_op = FAL_ACL_FIELD_RANGE; + } + + if (A_TRUE == + _isis_acl_field_care(sw->dest_l4port_op, + (a_uint32_t) sw->dest_l4port_val, + (a_uint32_t) sw->dest_l4port_mask, 0xffff)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_DPORT); + } + else if (FAL_ACL_FIELD_RANGE == sw->dest_l4port_op) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_DPORT); + } + + FIELD_GET(IP6_RUL3_V3, ICMP6_EN, icmp6_en); + if (icmp6_en) + { + FIELD_GET(IP6_RUL3_V3, IP6ICMPTYPV, sw->icmp_type_val); + FIELD_GET_MASK(IP6_RUL3_M3, IP6ICMPTYPM, sw->icmp_type_mask); + if (0x0 != sw->icmp_type_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_ICMP_TYPE); + } + + FIELD_GET(IP6_RUL3_V3, IP6ICMPCODEV, sw->icmp_code_val); + FIELD_GET_MASK(IP6_RUL3_M3, IP6ICMPCODEM, sw->icmp_code_mask); + if (0x0 != sw->icmp_code_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_ICMP_CODE); + } + } + else + { + FIELD_GET(IP6_RUL3_V3, IP6SPORTV, sw->src_l4port_val); + FIELD_GET_MASK(IP6_RUL3_M3, IP6SPORTM, sw->src_l4port_mask); + FIELD_GET_MASK(IP6_RUL3_M3, IP6SPORTM_EN, mask_en); + if (mask_en) + { + sw->src_l4port_op = FAL_ACL_FIELD_MASK; + } + else + { + sw->src_l4port_op = FAL_ACL_FIELD_RANGE; + } + + if (A_TRUE == + _isis_acl_field_care(sw->src_l4port_op, + (a_uint32_t) sw->src_l4port_val, + (a_uint32_t) sw->src_l4port_mask, 0xffff)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_SPORT); + } + else if (FAL_ACL_FIELD_RANGE == sw->src_l4port_op) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_SPORT); + } + } + + FIELD_GET(IP6_RUL3_V1, IP6LABEL1V, sw->ip6_lable_val); + FIELD_GET_MASK(IP6_RUL3_M1, IP6LABEL1M, sw->ip6_lable_mask); + + FIELD_GET(IP6_RUL3_V2, IP6LABEL2V, tmp); + sw->ip6_lable_val |= (tmp << 16); + FIELD_GET_MASK(IP6_RUL3_M2, IP6LABEL2M, tmp); + sw->ip6_lable_mask |= (tmp << 16); + + if (0x0 != sw->ip6_lable_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP6_LABEL); + } + + FIELD_GET(IP6_RUL3_V3, IP6TCPFLAGV, sw->tcp_flag_val); + FIELD_GET_MASK(IP6_RUL3_M3, IP6TCPFLAGM, sw->tcp_flag_mask); + if (0x0 != sw->tcp_flag_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_TCP_FLAG); + } + + FIELD_GET(IP6_RUL3_V3, IP6DHCPV, sw->dhcpv6_val); + FIELD_GET_MASK(IP6_RUL3_M3, IP6DHCPM, sw->dhcpv6_mask); + if (0x0 != sw->dhcpv6_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_DHCPV6); + } + + FIELD_GET(MAC_RUL_V4, RULE_INV, mask_en); + if (mask_en) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL); + } + + return SW_OK; +} + +static sw_error_t +_isis_acl_rule_udf_reparse(fal_acl_rule_t * sw, const hw_filter_t * hw) +{ + a_uint32_t i; + + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_UDF); + + /* for ISIS UDF type, length and offset no meanging in rules, just set default value */ + sw->udf_type = FAL_ACL_UDF_TYPE_L2; + sw->udf_len = 16; + sw->udf_offset = 0; + + for (i = 0; i < ISIS_MAX_UDF_LENGTH; i++) + { + sw->udf_val[i] = ((hw->vlu[3 - i / 4]) >> (24 - 8 * (i % 4))) & 0xff; + sw->udf_mask[i] = ((hw->msk[3 - i / 4]) >> (24 - 8 * (i % 4))) & 0xff; + } + + FIELD_GET(MAC_RUL_V4, RULE_INV, i); + if (i) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL); + } + + return SW_OK; +} + +static sw_error_t +_isis_acl_rule_action_reparse(fal_acl_rule_t * sw, const hw_filter_t * hw) +{ + a_uint32_t data; + + sw->action_flg = 0; + + FIELD_GET_ACTION(ACL_RSLT2, DES_PORT_EN, data); + if (1 == data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REDPT); + FIELD_GET_ACTION(ACL_RSLT1, DES_PORT0, sw->ports); + FIELD_GET_ACTION(ACL_RSLT2, DES_PORT1, data); + sw->ports |= (data << 3); + } + + FIELD_GET_ACTION(ACL_RSLT2, FWD_CMD, data); + if (0x7 == data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_DENY); + } + else if (0x3 == data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_RDTCPU); + } + else if (0x1 == data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_CPYCPU); + } + else + { + /* need't set permit action */ + } + + FIELD_GET_ACTION(ACL_RSLT2, MIRR_EN, data); + if (1 == data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_MIRROR); + } + + FIELD_GET_ACTION(ACL_RSLT1, PRI_QU_EN, data); + if (1 == data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REMARK_QUEUE); + FIELD_GET_ACTION(ACL_RSLT1, PRI_QU, sw->queue); + } + + FIELD_GET_ACTION(ACL_RSLT1, DSCP_REMAP, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REMARK_DSCP); + FIELD_GET_ACTION(ACL_RSLT1, DSCPV, sw->dscp); + } + + FIELD_GET_ACTION(ACL_RSLT0, STAGVID, sw->stag_vid); + + FIELD_GET_ACTION(ACL_RSLT1, TRANS_SVID_CHG, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REMARK_STAG_VID); + } + + FIELD_GET_ACTION(ACL_RSLT1, STAG_PRI_REMAP, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REMARK_STAG_PRI); + FIELD_GET_ACTION(ACL_RSLT0, STAGPRI, sw->stag_pri); + } + + FIELD_GET_ACTION(ACL_RSLT1, STAG_DEI_CHG, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REMARK_STAG_DEI); + FIELD_GET_ACTION(ACL_RSLT0, STAGDEI, sw->stag_dei); + } + + FIELD_GET_ACTION(ACL_RSLT0, CTAGVID, sw->ctag_vid); + + FIELD_GET_ACTION(ACL_RSLT1, TRANS_CVID_CHG, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REMARK_CTAG_VID); + } + + FIELD_GET_ACTION(ACL_RSLT1, CTAG_PRI_REMAP, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REMARK_CTAG_PRI); + FIELD_GET_ACTION(ACL_RSLT0, CTAGPRI, sw->ctag_pri); + } + + FIELD_GET_ACTION(ACL_RSLT1, CTAG_CFI_CHG, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REMARK_CTAG_CFI); + FIELD_GET_ACTION(ACL_RSLT0, CTAGCFI, sw->ctag_cfi); + } + + FIELD_GET_ACTION(ACL_RSLT1, LOOK_VID_CHG, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REMARK_LOOKUP_VID); + } + + FIELD_GET_ACTION(ACL_RSLT2, POLICER_EN, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_POLICER_EN); + FIELD_GET_ACTION(ACL_RSLT2, POLICER_PTR, sw->policer_ptr); + } + + FIELD_GET_ACTION(ACL_RSLT1, ARP_PTR_EN, data); + if (data) + { + FIELD_GET_ACTION(ACL_RSLT1, WCMP_EN, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_WCMP_EN); + FIELD_GET_ACTION(ACL_RSLT1, ARP_PTR, sw->wcmp_ptr); + } + else + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_ARP_EN); + FIELD_GET_ACTION(ACL_RSLT1, ARP_PTR, sw->arp_ptr); + } + } + + FIELD_GET_ACTION(ACL_RSLT1, FORCE_L3_MODE, data); + if ((0 != data) && (3 != data)) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_POLICY_FORWARD_EN); + if (0x1 == data) + { + sw->policy_fwd = FAL_ACL_POLICY_SNAT; + } + else + { + sw->policy_fwd = FAL_ACL_POLICY_DNAT; + } + } + + FIELD_GET_ACTION(ACL_RSLT2, EG_BYPASS, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_BYPASS_EGRESS_TRANS); + } + + FIELD_GET_ACTION(ACL_RSLT2, TRIGGER_INTR, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_MATCH_TRIGGER_INTR); + } + + return SW_OK; +} + +sw_error_t +_isis_acl_rule_sw_to_hw(a_uint32_t dev_id, fal_acl_rule_t * sw, + isis_acl_rule_t * hw_rule_snap, a_uint32_t * idx) +{ + sw_error_t rv; + a_uint32_t tmp_idx, i, b_rule[7] = { 0 }; + parse_func_t ptr[7] = { NULL }; + a_bool_t b_care, b_mac, eh_mac; + + rv = _isis_acl_action_parse(dev_id, sw, &(hw_rule_snap[*idx].filter)); + SW_RTN_ON_ERROR(rv); + + ptr[0] = _isis_acl_rule_udf_parse; + _isis_acl_rule_mac_preparse(sw, &b_mac, &eh_mac); + + /* ehmac rule must be parsed bofore mac rule. + it's important for reparse process */ + if (A_TRUE == eh_mac) + { + ptr[1] = _isis_acl_rule_ehmac_parse; + } + + if (A_TRUE == b_mac) + { + ptr[2] = _isis_acl_rule_bmac_parse; + } + + if ((A_FALSE == b_mac) && (A_FALSE == eh_mac)) + { + ptr[2] = _isis_acl_rule_bmac_parse; + } + + if (FAL_ACL_RULE_MAC == sw->rule_type) + { + } + else if (FAL_ACL_RULE_IP4 == sw->rule_type) + { + ptr[3] = _isis_acl_rule_ip4_parse; + } + else if (FAL_ACL_RULE_IP6 == sw->rule_type) + { + ptr[4] = _isis_acl_rule_ip6r1_parse; + ptr[5] = _isis_acl_rule_ip6r2_parse; + ptr[6] = _isis_acl_rule_ip6r3_parse; + } + else if (FAL_ACL_RULE_UDF == sw->rule_type) + { + ptr[1] = NULL; + ptr[2] = NULL; + } + else + { + return SW_NOT_SUPPORTED; + } + + tmp_idx = *idx; + for (i = 0; i < 7; i++) + { + if (ptr[i]) + { + if (ISIS_HW_RULE_TMP_CNT <= tmp_idx) + { + return SW_NO_RESOURCE; + } + + rv = ptr[i] (sw, &(hw_rule_snap[tmp_idx].filter), &b_care); + SW_RTN_ON_ERROR(rv); + if (A_TRUE == b_care) + { + tmp_idx++; + b_rule[i] = 1; + } + } + } + + if (FAL_ACL_RULE_IP6 == sw->rule_type) + { + if ((!b_rule[4]) && (!b_rule[5]) && (!b_rule[6])) + { + tmp_idx++; + } + } + + if (FAL_ACL_RULE_IP4 == sw->rule_type) + { + if (!b_rule[3]) + { + tmp_idx++; + } + } + + if (tmp_idx == *idx) + { + /* set type start & end */ + SW_SET_REG_BY_FIELD(MAC_RUL_M4, RULE_VALID, FLT_STARTEND, + (hw_rule_snap[*idx].filter.msk[4])); + (*idx)++; + } + else + { + if (1 == (tmp_idx - *idx)) + { + if (FAL_ACL_COMBINED_START == sw->combined) + { + SW_SET_REG_BY_FIELD(MAC_RUL_M4, RULE_VALID, FLT_START, + (hw_rule_snap[*idx].filter.msk[4])); + } + else if (FAL_ACL_COMBINED_CONTINUE == sw->combined) + { + SW_SET_REG_BY_FIELD(MAC_RUL_M4, RULE_VALID, FLT_CONTINUE, + (hw_rule_snap[*idx].filter.msk[4])); + } + else if (FAL_ACL_COMBINED_END == sw->combined) + { + SW_SET_REG_BY_FIELD(MAC_RUL_M4, RULE_VALID, FLT_END, + (hw_rule_snap[*idx].filter.msk[4])); + } + else + { + SW_SET_REG_BY_FIELD(MAC_RUL_M4, RULE_VALID, FLT_STARTEND, + (hw_rule_snap[*idx].filter.msk[4])); + } + } + else + { + for (i = *idx; i < tmp_idx; i++) + { + if (i == *idx) + { + SW_SET_REG_BY_FIELD(MAC_RUL_M4, RULE_VALID, FLT_START, + (hw_rule_snap[i].filter.msk[4])); + } + else if (i == (tmp_idx - 1)) + { + SW_SET_REG_BY_FIELD(MAC_RUL_M4, RULE_VALID, FLT_END, + (hw_rule_snap[i].filter.msk[4])); + } + else + { + SW_SET_REG_BY_FIELD(MAC_RUL_M4, RULE_VALID, FLT_CONTINUE, + (hw_rule_snap[i].filter.msk[4])); + } + aos_mem_copy(&(hw_rule_snap[i].filter.act[0]), + &(hw_rule_snap[*idx].filter.act[0]), + sizeof (hw_rule_snap[*idx].filter.act)); + } + } + *idx = tmp_idx; + } + + return SW_OK; +} + +sw_error_t +_isis_acl_rule_hw_to_sw(a_uint32_t dev_id, fal_acl_rule_t * sw, + isis_acl_rule_t * hw_rule_snap, a_uint32_t idx, + a_uint32_t ent_nr) +{ + a_bool_t b_mac = A_FALSE, b_ip4 = A_FALSE, b_ip6 = A_FALSE; + sw_error_t rv; + a_uint32_t i, flt_typ; + hw_filter_t *hw; + + rv = _isis_acl_rule_action_reparse(sw, &(hw_rule_snap[idx].filter)); + SW_RTN_ON_ERROR(rv); + + sw->rule_type = FAL_ACL_RULE_UDF; + for (i = 0; i < ent_nr; i++) + { + hw = &(hw_rule_snap[idx + i].filter); + FIELD_GET_MASK(MAC_RUL_M4, RULE_TYP, flt_typ); + + if (ISIS_UDF_FILTER == flt_typ) + { + rv = _isis_acl_rule_udf_reparse(sw, hw); + SW_RTN_ON_ERROR(rv); + } + else if (ISIS_MAC_FILTER == flt_typ) + { + rv = _isis_acl_rule_bmac_reparse(sw, hw); + SW_RTN_ON_ERROR(rv); + b_mac = A_TRUE; + } + else if (ISIS_EHMAC_FILTER == flt_typ) + { + rv = _isis_acl_rule_ehmac_reparse(sw, hw); + SW_RTN_ON_ERROR(rv); + b_mac = A_TRUE; + } + else if (ISIS_IP4_FILTER == flt_typ) + { + rv = _isis_acl_rule_ip4_reparse(sw, hw); + SW_RTN_ON_ERROR(rv); + b_ip4 = A_TRUE; + } + else if (ISIS_IP6R1_FILTER == flt_typ) + { + rv = _isis_acl_rule_ip6r1_reparse(sw, hw); + SW_RTN_ON_ERROR(rv); + b_ip6 = A_TRUE; + } + else if (ISIS_IP6R2_FILTER == flt_typ) + { + rv = _isis_acl_rule_ip6r2_reparse(sw, hw); + SW_RTN_ON_ERROR(rv); + b_ip6 = A_TRUE; + } + else if (ISIS_IP6R3_FILTER == flt_typ) + { + rv = _isis_acl_rule_ip6r3_reparse(sw, hw); + SW_RTN_ON_ERROR(rv); + b_ip6 = A_TRUE; + } + else + { + /* ignore fill gap filters */ + } + } + + if (A_TRUE == b_mac) + { + sw->rule_type = FAL_ACL_RULE_MAC; + } + + if (A_TRUE == b_ip4) + { + sw->rule_type = FAL_ACL_RULE_IP4; + } + + if (A_TRUE == b_ip6) + { + sw->rule_type = FAL_ACL_RULE_IP6; + } + + return SW_OK; +} diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_acl_prv.h b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_acl_prv.h new file mode 100755 index 000000000..f6b9c7fc1 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_acl_prv.h @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +typedef struct +{ + a_uint8_t status; + a_uint8_t list_id; + a_uint8_t list_pri; + a_uint8_t rule_nr; + fal_pbmp_t bind_pts; +} isis_acl_list_t; + + +typedef struct +{ + a_uint32_t vlu[5]; + a_uint32_t msk[5]; + a_uint32_t act[3]; +} hw_filter_t; + + +typedef struct +{ + a_uint8_t status; + a_uint8_t list_id; + a_uint8_t list_pri; + a_uint8_t rule_id; + hw_filter_t filter; +} isis_acl_rule_t; + + +#define ENT_USED 0x1 +#define ENT_TMP 0x2 +#define ENT_DEACTIVE 0x4 + +#define FLT_START 0x0 +#define FLT_CONTINUE 0x1 +#define FLT_END 0x2 +#define FLT_STARTEND 0x3 + + +#define ISIS_MAC_FILTER 1 +#define ISIS_IP4_FILTER 2 +#define ISIS_IP6R1_FILTER 3 +#define ISIS_IP6R2_FILTER 4 +#define ISIS_IP6R3_FILTER 5 +#define ISIS_UDF_FILTER 6 +#define ISIS_EHMAC_FILTER 7 + + +#define ISIS_MAX_UDF_OFFSET 31 +#define ISIS_MAX_UDF_LENGTH 16 + + +#define ISIS_FILTER_VLU_OP 0x0 +#define ISIS_FILTER_MSK_OP 0x1 +#define ISIS_FILTER_ACT_OP 0x2 + + + +//#define ISIS_MAX_FILTER 8 +#define ISIS_MAX_FILTER 96 +#define ISIS_RULE_FUNC_ADDR 0x0400 +#define ISIS_HW_RULE_TMP_CNT (ISIS_MAX_FILTER + 4) + +#define ISIS_MAX_LIST_ID 255 +#define ISIS_MAX_LIST_PRI 255 + +#define ISIS_UDF_MAX_LENGTH 15 +#define ISIS_UDF_MAX_OFFSET 31 + +#define WIN_RULE_CTL0_ADDR 0x218 +#define WIN_RULE_CTL1_ADDR 0x234 + + +#define ISIS_FILTER_VLU_ADDR 0x58000 +#define ISIS_FILTER_MSK_ADDR 0x59000 +#define ISIS_FILTER_ACT_ADDR 0x5a000 + + +#define FIELD_SET(reg, field, val) \ + SW_REG_SET_BY_FIELD_U32(hw->vlu[reg], val, reg##_##field##_BOFFSET, \ + reg##_##field##_BLEN) + +#define FIELD_GET(reg, field, val) \ + SW_FIELD_GET_BY_REG_U32(hw->vlu[reg], val, reg##_##field##_BOFFSET, \ + reg##_##field##_BLEN) + +#define FIELD_SET_MASK(reg, field, val) \ + SW_REG_SET_BY_FIELD_U32(hw->msk[reg-5], val, reg##_##field##_BOFFSET, \ + reg##_##field##_BLEN) + +#define FIELD_GET_MASK(reg, field, val) \ + SW_FIELD_GET_BY_REG_U32(hw->msk[reg-5], val, reg##_##field##_BOFFSET, \ + reg##_##field##_BLEN) + +#define FIELD_SET_ACTION(reg, field, val) \ + SW_REG_SET_BY_FIELD_U32(hw->act[reg-10], val, reg##_##field##_BOFFSET, \ + reg##_##field##_BLEN) + +#define FIELD_GET_ACTION(reg, field, val) \ + SW_FIELD_GET_BY_REG_U32(hw->act[reg-10], val, reg##_##field##_BOFFSET, \ + reg##_##field##_BLEN) + +sw_error_t +_isis_acl_rule_sw_to_hw(a_uint32_t dev_id, fal_acl_rule_t * sw, isis_acl_rule_t * hw_filter_snap, a_uint32_t * idx); + + +sw_error_t +_isis_acl_rule_hw_to_sw(a_uint32_t dev_id, fal_acl_rule_t * sw, isis_acl_rule_t * hw_filter_snap, a_uint32_t idx, a_uint32_t ent_nr); + + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_cosmap.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_cosmap.c new file mode 100755 index 000000000..4cecb0268 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_cosmap.c @@ -0,0 +1,637 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup isis_cosmap ISIS_COSMAP + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isis_cosmap.h" +#include "isis_reg.h" + +#define ISIS_MAX_DSCP 63 +#define ISIS_MAX_UP 7 +#define ISIS_MAX_PRI 7 +#define ISIS_MAX_DP 1 +#define ISIS_MAX_QUEUE 3 +#define ISIS_MAX_EH_QUEUE 5 + +#define ISIS_DSCP_TO_PRI 0 +#define ISIS_DSCP_TO_DP 1 +#define ISIS_UP_TO_PRI 2 +#define ISIS_UP_TO_DP 3 + +#define ISIS_EGRESS_REAMRK_ADDR 0x5ae00 +#define ISIS_EGRESS_REAMRK_NUM 16 + +static sw_error_t +_isis_cosmap_dscp_to_pri_dp_set(a_uint32_t dev_id, a_uint32_t mode, + a_uint32_t dscp, a_uint32_t val) +{ + sw_error_t rv; + a_uint32_t index, data = 0; + + if (ISIS_MAX_DSCP < dscp) + { + return SW_BAD_PARAM; + } + + index = dscp >> 3; + HSL_REG_ENTRY_GET(rv, dev_id, DSCP_TO_PRI, index, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (ISIS_DSCP_TO_PRI == mode) + { + if (ISIS_MAX_PRI < val) + { + return SW_BAD_PARAM; + } + + data &= (~(0x7 << ((dscp & 0x7) << 2))); + data |= (val << ((dscp & 0x7) << 2)); + } + else + { + if (ISIS_MAX_DP < val) + { + return SW_BAD_PARAM; + } + + data &= (~(0x1 << (((dscp & 0x7) << 2) + 3))); + data |= (val << (((dscp & 0x7) << 2) + 3)); + } + + HSL_REG_ENTRY_SET(rv, dev_id, DSCP_TO_PRI, index, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_cosmap_dscp_to_pri_dp_get(a_uint32_t dev_id, a_uint32_t mode, + a_uint32_t dscp, a_uint32_t * val) +{ + sw_error_t rv; + a_uint32_t index, data = 0; + + if (ISIS_MAX_DSCP < dscp) + { + return SW_BAD_PARAM; + } + + index = dscp >> 3; + HSL_REG_ENTRY_GET(rv, dev_id, DSCP_TO_PRI, index, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data = (data >> ((dscp & 0x7) << 2)) & 0xf; + if (ISIS_DSCP_TO_PRI == mode) + { + *val = data & 0x7; + } + else + { + *val = (data & 0x8) >> 3; + } + + return SW_OK; +} + +static sw_error_t +_isis_cosmap_up_to_pri_dp_set(a_uint32_t dev_id, a_uint32_t mode, a_uint32_t up, + a_uint32_t val) +{ + sw_error_t rv; + a_uint32_t data = 0; + + if (ISIS_MAX_UP < up) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, UP_TO_PRI, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (ISIS_UP_TO_PRI == mode) + { + if (ISIS_MAX_PRI < val) + { + return SW_BAD_PARAM; + } + + data &= (~(0x7 << (up << 2))); + data |= (val << (up << 2)); + } + else + { + if (ISIS_MAX_DP < val) + { + return SW_BAD_PARAM; + } + + data &= (~(0x1 << ((up << 2) + 3))); + data |= (val << ((up << 2) + 3)); + } + + HSL_REG_ENTRY_SET(rv, dev_id, UP_TO_PRI, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_cosmap_up_to_pri_dp_get(a_uint32_t dev_id, a_uint32_t mode, a_uint32_t up, + a_uint32_t * val) +{ + sw_error_t rv; + a_uint32_t data = 0; + + if (ISIS_MAX_UP < up) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, UP_TO_PRI, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data = (data >> (up << 2)) & 0xf; + + if (ISIS_UP_TO_PRI == mode) + { + *val = (data & 0x7); + } + else + { + *val = (data & 0x8) >> 3; + } + + return SW_OK; +} + +static sw_error_t +_isis_cosmap_pri_to_queue_set(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t queue) +{ + sw_error_t rv; + a_uint32_t data = 0; + + if ((ISIS_MAX_PRI < pri) || (ISIS_MAX_QUEUE < queue)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PRI_TO_QUEUE, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data &= (~(0x3 << (pri << 2))); + data |= (queue << (pri << 2)); + + HSL_REG_ENTRY_SET(rv, dev_id, PRI_TO_QUEUE, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_cosmap_pri_to_queue_get(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t * queue) +{ + sw_error_t rv; + a_uint32_t data = 0; + + if (ISIS_MAX_PRI < pri) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PRI_TO_QUEUE, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *queue = (data >> (pri << 2)) & 0x3; + return SW_OK; +} + +static sw_error_t +_isis_cosmap_pri_to_ehqueue_set(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t queue) +{ + sw_error_t rv; + a_uint32_t data = 0; + + if ((ISIS_MAX_PRI < pri) || (ISIS_MAX_EH_QUEUE < queue)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PRI_TO_EHQUEUE, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data &= (~(0x7 << (pri << 2))); + data |= (queue << (pri << 2)); + + HSL_REG_ENTRY_SET(rv, dev_id, PRI_TO_EHQUEUE, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_cosmap_pri_to_ehqueue_get(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t * queue) +{ + sw_error_t rv; + a_uint32_t data= 0; + + if (ISIS_MAX_PRI < pri) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PRI_TO_EHQUEUE, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *queue = (data >> (pri << 2)) & 0x7; + return SW_OK; +} + +static sw_error_t +_isis_cosmap_egress_remark_set(a_uint32_t dev_id, a_uint32_t tbl_id, + fal_egress_remark_table_t * tbl) +{ + sw_error_t rv; + a_uint32_t data, addr; + + if (ISIS_EGRESS_REAMRK_NUM <= tbl_id) + { + return SW_BAD_PARAM; + } + + data = (tbl->y_up & 0x7) + | ((tbl->g_up & 0x7) << 4) + | ((tbl->y_dscp & 0x3f) << 8) + | ((tbl->g_dscp & 0x3f) << 16) + | ((tbl->remark_dscp & 0x1) << 23) + | ((tbl->remark_up & 0x1) << 22); + + addr = ISIS_EGRESS_REAMRK_ADDR + (tbl_id << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_cosmap_egress_remark_get(a_uint32_t dev_id, a_uint32_t tbl_id, + fal_egress_remark_table_t * tbl) +{ + sw_error_t rv; + a_uint32_t data = 0, addr; + + if (ISIS_EGRESS_REAMRK_NUM <= tbl_id) + { + return SW_BAD_PARAM; + } + + aos_mem_zero(tbl, sizeof (fal_egress_remark_table_t)); + + addr = ISIS_EGRESS_REAMRK_ADDR + (tbl_id << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data & (0x1 << 23)) + { + tbl->remark_dscp = A_TRUE; + tbl->y_dscp = (data >> 8) & 0x3f; + tbl->g_dscp = (data >> 16) & 0x3f; + } + + if (data & (0x1 << 22)) + { + tbl->remark_up = A_TRUE; + tbl->y_up = data & 0x7; + tbl->g_up = (data >> 4) & 0x7; + } + + return SW_OK; +} + +/** + * @brief Set dscp to internal priority mapping on one particular device. + * @param[in] dev_id device id + * @param[in] dscp dscp + * @param[in] pri internal priority + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_cosmap_dscp_to_pri_set(a_uint32_t dev_id, a_uint32_t dscp, a_uint32_t pri) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_cosmap_dscp_to_pri_dp_set(dev_id, ISIS_DSCP_TO_PRI, dscp, pri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dscp to internal priority mapping on one particular device. + * @param[in] dev_id device id + * @param[in] dscp dscp + * @param[out] pri internal priority + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_cosmap_dscp_to_pri_get(a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t * pri) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_cosmap_dscp_to_pri_dp_get(dev_id, ISIS_DSCP_TO_PRI, dscp, pri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dscp to internal drop precedence mapping on one particular device. + * @param[in] dev_id device id + * @param[in] dscp dscp + * @param[in] dp internal drop precedence + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_cosmap_dscp_to_dp_set(a_uint32_t dev_id, a_uint32_t dscp, a_uint32_t dp) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_cosmap_dscp_to_pri_dp_set(dev_id, ISIS_DSCP_TO_DP, dscp, dp); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dscp to internal drop precedence mapping on one particular device. + * @param[in] dev_id device id + * @param[in] dscp dscp + * @param[out] dp internal drop precedence + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_cosmap_dscp_to_dp_get(a_uint32_t dev_id, a_uint32_t dscp, a_uint32_t * dp) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_cosmap_dscp_to_pri_dp_get(dev_id, ISIS_DSCP_TO_DP, dscp, dp); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dot1p to internal priority mapping on one particular device. + * @param[in] dev_id device id + * @param[in] up dot1p + * @param[in] pri internal priority + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_cosmap_up_to_pri_set(a_uint32_t dev_id, a_uint32_t up, a_uint32_t pri) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_cosmap_up_to_pri_dp_set(dev_id, ISIS_UP_TO_PRI, up, pri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dot1p to internal priority mapping on one particular device. + * @param[in] dev_id device id + * @param[in] up dot1p + * @param[out] pri internal priority + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_cosmap_up_to_pri_get(a_uint32_t dev_id, a_uint32_t up, a_uint32_t * pri) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_cosmap_up_to_pri_dp_get(dev_id, ISIS_UP_TO_PRI, up, pri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dot1p to internal drop precedence mapping on one particular device. + * @param[in] dev_id device id + * @param[in] up dot1p + * @param[in] dp internal drop precedence + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_cosmap_up_to_dp_set(a_uint32_t dev_id, a_uint32_t up, a_uint32_t dp) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_cosmap_up_to_pri_dp_set(dev_id, ISIS_UP_TO_DP, up, dp); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dot1p to internal drop precedence mapping on one particular device. + * @param[in] dev_id device id + * @param[in] up dot1p + * @param[in] dp internal drop precedence + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_cosmap_up_to_dp_get(a_uint32_t dev_id, a_uint32_t up, a_uint32_t * dp) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_cosmap_up_to_pri_dp_get(dev_id, ISIS_UP_TO_DP, up, dp); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set internal priority to queue mapping on one particular device. + * @details Comments: + * This function is for port 1/2/3/4 which have four egress queues + * @param[in] dev_id device id + * @param[in] pri internal priority + * @param[in] queue queue id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_cosmap_pri_to_queue_set(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t queue) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_cosmap_pri_to_queue_set(dev_id, pri, queue); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get internal priority to queue mapping on one particular device. + * @details Comments: + * This function is for port 1/2/3/4 which have four egress queues + * @param[in] dev_id device id + * @param[in] pri internal priority + * @param[out] queue queue id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_cosmap_pri_to_queue_get(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t * queue) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_cosmap_pri_to_queue_get(dev_id, pri, queue); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set internal priority to queue mapping on one particular device. + * @details Comments: + * This function is for port 0/5/6 which have six egress queues + * @param[in] dev_id device id + * @param[in] pri internal priority + * @param[in] queue queue id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_cosmap_pri_to_ehqueue_set(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t queue) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_cosmap_pri_to_ehqueue_set(dev_id, pri, queue); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get internal priority to queue mapping on one particular device. + * @details Comments: + * This function is for port 0/5/6 which have six egress queues + * @param[in] dev_id device id + * @param[in] pri internal priority + * @param[in] queue queue id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_cosmap_pri_to_ehqueue_get(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t * queue) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_cosmap_pri_to_ehqueue_get(dev_id, pri, queue); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set egress queue based CoS remap table on one particular device. + * @param[in] dev_id device id + * @param[in] tbl_id CoS remap table id + * @param[in] tbl CoS remap table + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_cosmap_egress_remark_set(a_uint32_t dev_id, a_uint32_t tbl_id, + fal_egress_remark_table_t * tbl) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_cosmap_egress_remark_set(dev_id, tbl_id, tbl); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get egress queue based CoS remap table on one particular device. + * @param[in] dev_id device id + * @param[in] tbl_id CoS remap table id + * @param[out] tbl CoS remap table + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_cosmap_egress_remark_get(a_uint32_t dev_id, a_uint32_t tbl_id, + fal_egress_remark_table_t * tbl) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_cosmap_egress_remark_get(dev_id, tbl_id, tbl); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +isis_cosmap_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->cosmap_dscp_to_pri_set = isis_cosmap_dscp_to_pri_set; + p_api->cosmap_dscp_to_pri_get = isis_cosmap_dscp_to_pri_get; + p_api->cosmap_dscp_to_dp_set = isis_cosmap_dscp_to_dp_set; + p_api->cosmap_dscp_to_dp_get = isis_cosmap_dscp_to_dp_get; + p_api->cosmap_up_to_pri_set = isis_cosmap_up_to_pri_set; + p_api->cosmap_up_to_pri_get = isis_cosmap_up_to_pri_get; + p_api->cosmap_up_to_dp_set = isis_cosmap_up_to_dp_set; + p_api->cosmap_up_to_dp_get = isis_cosmap_up_to_dp_get; + p_api->cosmap_pri_to_queue_set = isis_cosmap_pri_to_queue_set; + p_api->cosmap_pri_to_queue_get = isis_cosmap_pri_to_queue_get; + p_api->cosmap_pri_to_ehqueue_set = isis_cosmap_pri_to_ehqueue_set; + p_api->cosmap_pri_to_ehqueue_get = isis_cosmap_pri_to_ehqueue_get; + p_api->cosmap_egress_remark_set = isis_cosmap_egress_remark_set; + p_api->cosmap_egress_remark_get = isis_cosmap_egress_remark_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_fdb.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_fdb.c new file mode 100755 index 000000000..da21f2276 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_fdb.c @@ -0,0 +1,2217 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup isis_fdb ISIS_FDB + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isis_fdb.h" +#include "isis_reg.h" + +#define ARL_FLUSH_ALL 1 +#define ARL_LOAD_ENTRY 2 +#define ARL_PURGE_ENTRY 3 +#define ARL_FLUSH_ALL_UNLOCK 4 +#define ARL_FLUSH_PORT_UNICAST 5 +#define ARL_NEXT_ENTRY 6 +#define ARL_FIND_ENTRY 7 +#define ARL_TRANSFER_ENTRY 8 + +#define ARL_FIRST_ENTRY 1001 +#define ARL_FLUSH_PORT_NO_STATIC 1002 +#define ARL_FLUSH_PORT_AND_STATIC 1003 + +#define ISIS_MAX_FID 4095 +#define ISIS_MAX_LEARN_LIMIT_CNT 2047 +#define ISIS_MAX_PORT_LEARN_LIMIT_CNT 1023 + +static sw_error_t +_isis_wl_feature_check(a_uint32_t dev_id) +{ + sw_error_t rv; + a_uint32_t entry = 0; + + HSL_REG_FIELD_GET(rv, dev_id, MASK_CTL, 0, DEVICE_ID, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (S17_DEVICE_ID == entry) + { + return SW_OK; + } + else + { + return SW_NOT_SUPPORTED; + } +} + +static a_bool_t +_isis_fdb_is_zeroaddr(fal_mac_addr_t addr) +{ + a_uint32_t i; + + for (i = 0; i < 6; i++) + { + if (addr.uc[i]) + { + return A_FALSE; + } + } + + return A_TRUE; +} + +static void +_isis_fdb_fill_addr(fal_mac_addr_t addr, a_uint32_t * reg0, a_uint32_t * reg1) +{ + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_ADDR_BYTE0, addr.uc[0], *reg1); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_ADDR_BYTE1, addr.uc[1], *reg1); + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_ADDR_BYTE2, addr.uc[2], *reg0); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_ADDR_BYTE3, addr.uc[3], *reg0); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_ADDR_BYTE4, addr.uc[4], *reg0); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_ADDR_BYTE5, addr.uc[5], *reg0); + + return; +} + +static sw_error_t +_isis_atu_sw_to_hw(a_uint32_t dev_id, const fal_fdb_entry_t * entry, + a_uint32_t reg[]) +{ + a_uint32_t port; + sw_error_t rv; + + if (A_TRUE == entry->white_list_en) + { + rv = _isis_wl_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, WL_EN, 1, reg[2]); + } + + if (FAL_SVL_FID == entry->fid) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_VID, 0, reg[2]); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_SVL_EN, 1, reg[1]); + } + else if (ISIS_MAX_FID >= entry->fid) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_VID, (entry->fid), reg[2]); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_SVL_EN, 0, reg[1]); + } + else + { + return SW_BAD_PARAM; + } + + if (A_FALSE == entry->portmap_en) + { + if (A_TRUE != + hsl_port_prop_check(dev_id, entry->port.id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + port = 0x1UL << entry->port.id; + } + else + { + if (A_FALSE == + hsl_mports_prop_check(dev_id, entry->port.map, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + port = entry->port.map; + } + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, DES_PORT, port, reg[1]); + + if (FAL_MAC_CPY_TO_CPU == entry->dacmd) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, COPY_TO_CPU, 1, reg[2]); + } + else if (FAL_MAC_RDT_TO_CPU == entry->dacmd) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, REDRCT_TO_CPU, 1, reg[2]); + } + else if (FAL_MAC_FRWRD != entry->dacmd) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == entry->leaky_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, LEAKY_EN, 1, reg[2]); + } + else + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, LEAKY_EN, 0, reg[2]); + } + + if (A_TRUE == entry->static_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_STATUS, 15, reg[2]); + } + else + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_STATUS, 7, reg[2]); + } + + if (FAL_MAC_DROP == entry->sacmd) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, SA_DROP_EN, 1, reg[1]); + } + else if (FAL_MAC_FRWRD != entry->sacmd) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == entry->mirror_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, MIRROR_EN, 1, reg[1]); + } + + if (A_TRUE == entry->cross_pt_state) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, CROSS_PT, 1, reg[1]); + } + else + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, CROSS_PT, 0, reg[1]); + } + + if (A_TRUE == entry->da_pri_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_PRI_EN, 1, reg[1]); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_PRI, (entry->da_queue & 0x7), + reg[1]); + } + else + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_PRI_EN, 0, reg[1]); + } + + _isis_fdb_fill_addr(entry->addr, ®[0], ®[1]); + return SW_OK; +} + +static void +_isis_atu_hw_to_sw(const a_uint32_t reg[], fal_fdb_entry_t * entry) +{ + a_uint32_t i, data; + + aos_mem_zero(entry, sizeof (fal_fdb_entry_t)); + + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC1, AT_SVL_EN, data, reg[1]); + if (data) + { + entry->fid = FAL_SVL_FID; + } + else + { + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, AT_VID, data, reg[2]); + entry->fid = data; + } + + entry->dacmd = FAL_MAC_FRWRD; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, COPY_TO_CPU, data, reg[2]); + if (1 == data) + { + entry->dacmd = FAL_MAC_CPY_TO_CPU; + } + + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, REDRCT_TO_CPU, data, reg[2]); + if (1 == data) + { + entry->dacmd = FAL_MAC_RDT_TO_CPU; + } + + entry->sacmd = FAL_MAC_FRWRD; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC1, SA_DROP_EN, data, reg[1]); + if (1 == data) + { + entry->sacmd = FAL_MAC_DROP; + } + + entry->leaky_en = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, LEAKY_EN, data, reg[2]); + if (1 == data) + { + entry->leaky_en = A_TRUE; + } + + entry->static_en = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, AT_STATUS, data, reg[2]); + if (0xf == data) + { + entry->static_en = A_TRUE; + } + + entry->mirror_en = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC1, MIRROR_EN, data, reg[1]); + if (1 == data) + { + entry->mirror_en = A_TRUE; + } + + entry->da_pri_en = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC1, AT_PRI_EN, data, reg[1]); + if (1 == data) + { + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC1, AT_PRI, data, reg[1]); + entry->da_pri_en = A_TRUE; + entry->da_queue = data & 0x7; + } + + entry->cross_pt_state = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC1, CROSS_PT, data, reg[1]); + if (1 == data) + { + entry->cross_pt_state = A_TRUE; + } + + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC1, DES_PORT, data, reg[1]); + entry->portmap_en = A_TRUE; + entry->port.map = data; + + for (i = 2; i < 6; i++) + { + entry->addr.uc[i] = (reg[0] >> ((5 - i) << 3)) & 0xff; + } + + for (i = 0; i < 2; i++) + { + entry->addr.uc[i] = (reg[1] >> ((1 - i) << 3)) & 0xff; + } + + entry->white_list_en = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, WL_EN, data, reg[2]); + if (1 == data) + { + entry->white_list_en = A_TRUE; + } + + return; +} + +static sw_error_t +_isis_atu_down_to_hw(a_uint32_t dev_id, a_uint32_t reg[]) +{ + sw_error_t rv; + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC2, 0, + (a_uint8_t *) (®[2]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC3, 0, + (a_uint8_t *) (®[3]), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_atu_up_to_sw(a_uint32_t dev_id, a_uint32_t reg[]) +{ + sw_error_t rv; + + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC2, 0, + (a_uint8_t *) (®[2]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC3, 0, + (a_uint8_t *) (®[3]), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_fdb_commit(a_uint32_t dev_id, a_uint32_t op) +{ + sw_error_t rv; + a_uint32_t busy = 1; + a_uint32_t full_vio; + a_uint32_t i = 2000; + a_uint32_t entry = 0; + a_uint32_t hwop = op; + + while (busy && --i) + { + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC3, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC3, AT_BUSY, busy, entry); + aos_udelay(5); + } + + if (0 == i) + { + printk("%s BUSY\n", __FUNCTION__); + return SW_BUSY; + } + + if (ARL_FIRST_ENTRY == op) + { + hwop = ARL_NEXT_ENTRY; + } + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_BUSY, 1, entry); + + if (ARL_FLUSH_PORT_AND_STATIC == hwop) + { + hwop = ARL_FLUSH_PORT_UNICAST; + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, FLUSH_ST_EN, 1, entry); + } + + if (ARL_FLUSH_PORT_NO_STATIC == hwop) + { + hwop = ARL_FLUSH_PORT_UNICAST; + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, FLUSH_ST_EN, 0, entry); + } + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_FUNC, hwop, entry); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC3, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + busy = 1; + i = 2000; + while (busy && --i) + { + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC3, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC3, AT_BUSY, busy, entry); + } + + if (0 == i) + { + return SW_FAIL; + } + + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC3, AT_FULL_VIO, full_vio, entry); + + if (full_vio) + { + /* must clear AT_FULL_VOI bit */ + entry = 0x1000; + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC3, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (ARL_LOAD_ENTRY == hwop) + { + return SW_FULL; + } + else if ((ARL_PURGE_ENTRY == hwop) + || (ARL_FLUSH_PORT_UNICAST == hwop)) + { + return SW_NOT_FOUND; + } + else + { + return SW_FAIL; + } + } + + return SW_OK; +} + +static sw_error_t +_isis_fdb_get(a_uint32_t dev_id, fal_fdb_op_t * option, fal_fdb_entry_t * entry, + a_uint32_t hwop) +{ + sw_error_t rv; + a_uint32_t i, port = 0, status, reg[4] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == option->port_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_PORT_EN, 1, reg[3]); + if (A_FALSE == entry->portmap_en) + { + if (A_TRUE != + hsl_port_prop_check(dev_id, entry->port.id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + port = entry->port.id; + } + else + { + if (A_FALSE == + hsl_mports_prop_check(dev_id, entry->port.map, + HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + status = 0; + for (i = 0; i < SW_MAX_NR_PORT; i++) + { + if ((entry->port.map) & (0x1UL << i)) + { + if (status) + { + return SW_BAD_PARAM; + } + port = i; + status = 1; + } + } + } + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_PORT_NUM, port, reg[3]); + } + + if (A_TRUE == option->fid_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_VID_EN, 1, reg[3]); + } + + if (A_TRUE == option->multicast_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_MULTI_EN, 1, reg[3]); + } + + if (FAL_SVL_FID == entry->fid) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_VID, 0, reg[2]); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_SVL_EN, 1, reg[1]); + } + else if (ISIS_MAX_FID >= entry->fid) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_VID, entry->fid, reg[2]); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_SVL_EN, 0, reg[1]); + } + else + { + return SW_BAD_PARAM; + } + + if (ARL_FIRST_ENTRY != hwop) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_STATUS, 0xf, reg[2]); + } + + _isis_fdb_fill_addr(entry->addr, ®[0], ®[1]); + + rv = _isis_atu_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_fdb_commit(dev_id, hwop); + SW_RTN_ON_ERROR(rv); + + rv = _isis_atu_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + _isis_atu_hw_to_sw(reg, entry); + + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, AT_STATUS, status, reg[2]); + if ((A_TRUE == _isis_fdb_is_zeroaddr(entry->addr)) + && (0 == status)) + { + if (ARL_NEXT_ENTRY == hwop) + { + return SW_NO_MORE; + } + else + { + return SW_NOT_FOUND; + } + } + else + { + return SW_OK; + } + + return SW_OK; +} + +static sw_error_t +_isis_fdb_add(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t reg[4] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_atu_sw_to_hw(dev_id, entry, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_atu_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_fdb_commit(dev_id, ARL_LOAD_ENTRY); + return rv; +} + +static sw_error_t +_isis_fdb_del_all(a_uint32_t dev_id, a_uint32_t flag) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_FDB_DEL_STATIC & flag) + { + rv = _isis_fdb_commit(dev_id, ARL_FLUSH_ALL); + } + else + { + rv = _isis_fdb_commit(dev_id, ARL_FLUSH_ALL_UNLOCK); + } + + return rv; +} + +static sw_error_t +_isis_fdb_del_by_port(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t flag) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_PORT_NUM, port_id, reg); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC3, 0, (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_FDB_DEL_STATIC & flag) + { + rv = _isis_fdb_commit(dev_id, ARL_FLUSH_PORT_AND_STATIC); + } + else + { + rv = _isis_fdb_commit(dev_id, ARL_FLUSH_PORT_NO_STATIC); + } + + return rv; +} + +static sw_error_t +_isis_fdb_del_by_mac(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t reg0 = 0, reg1 = 0, reg2 = 0; + + HSL_DEV_ID_CHECK(dev_id); + + _isis_fdb_fill_addr(entry->addr, ®0, ®1); + + if (FAL_SVL_FID == entry->fid) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_VID, 0, reg2); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_SVL_EN, 1, reg1); + } + else if (ISIS_MAX_FID >= entry->fid) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_VID, (entry->fid), reg2); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_SVL_EN, 0, reg1); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC2, 0, (a_uint8_t *) (®2), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC1, 0, (a_uint8_t *) (®1), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC0, 0, (a_uint8_t *) (®0), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = _isis_fdb_commit(dev_id, ARL_PURGE_ENTRY); + return rv; +} + +static sw_error_t +_isis_fdb_find(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + fal_fdb_op_t option; + + aos_mem_zero(&option, sizeof (fal_fdb_op_t)); + rv = _isis_fdb_get(dev_id, &option, entry, ARL_FIND_ENTRY); + return rv; +} + +static sw_error_t +_isis_fdb_extend_next(a_uint32_t dev_id, fal_fdb_op_t * option, + fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + rv = _isis_fdb_get(dev_id, option, entry, ARL_NEXT_ENTRY); + return rv; +} + +static sw_error_t +_isis_fdb_extend_first(a_uint32_t dev_id, fal_fdb_op_t * option, + fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + rv = _isis_fdb_get(dev_id, option, entry, ARL_FIRST_ENTRY); + return rv; +} + +static sw_error_t +_isis_fdb_transfer(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; + a_uint32_t reg[4] = { 0 }; + + if (A_TRUE == option->port_en) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == option->fid_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_VID_EN, 1, reg[3]); + } + + if (A_TRUE == option->multicast_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_MULTI_EN, 1, reg[3]); + } + + if (FAL_SVL_FID == fid) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_VID, 0, reg[2]); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_SVL_EN, 1, reg[1]); + } + else if (ISIS_MAX_FID >= fid) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_VID, fid, reg[2]); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_SVL_EN, 0, reg[1]); + } + else + { + return SW_BAD_PARAM; + } + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_PORT_NUM, old_port, reg[3]); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, NEW_PORT_NUM, new_port, reg[3]); + + rv = _isis_atu_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_fdb_commit(dev_id, ARL_TRANSFER_ENTRY); + return rv; +} + +static sw_error_t +_isis_fdb_port_learn_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LOOKUP_CTL, port_id, LEARN_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_fdb_port_learn_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LOOKUP_CTL, port_id, LEARN_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isis_fdb_age_ctrl_set(a_uint32_t dev_id, a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, ADDR_TABLE_CTL, 0, AGE_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_fdb_age_ctrl_get(a_uint32_t dev_id, a_bool_t * enable) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_CTL, 0, AGE_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isis_fdb_age_time_set(a_uint32_t dev_id, a_uint32_t * time) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if ((65535 * 7 < *time) || (7 > *time)) + { + return SW_BAD_PARAM; + } + data = *time / 7; + *time = data * 7; + HSL_REG_FIELD_SET(rv, dev_id, ADDR_TABLE_CTL, 0, AGE_TIME, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_fdb_age_time_get(a_uint32_t dev_id, a_uint32_t * time) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_CTL, 0, AGE_TIME, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *time = data * 7; + return SW_OK; +} + +static sw_error_t +_isis_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; + a_uint32_t reg = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + if (ISIS_MAX_PORT_LEARN_LIMIT_CNT < cnt) + { + return SW_BAD_PARAM; + } + SW_SET_REG_BY_FIELD(PORT_LEARN_LIMIT_CTL, SA_LEARN_LIMIT_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_LEARN_LIMIT_CTL, SA_LEARN_CNT, cnt, reg); + } + else if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(PORT_LEARN_LIMIT_CTL, SA_LEARN_LIMIT_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_LEARN_LIMIT_CTL, SA_LEARN_CNT, 0, reg); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_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; + a_uint32_t data, reg = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_LEARN_LIMIT_CTL, SA_LEARN_LIMIT_EN, data, reg); + if (data) + { + SW_GET_FIELD_BY_REG(PORT_LEARN_LIMIT_CTL, SA_LEARN_CNT, data, reg); + *enable = A_TRUE; + *cnt = data; + } + else + { + *enable = A_FALSE; + *cnt = 0; + } + + return SW_OK; +} + +static sw_error_t +_isis_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; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_MAC_DROP == cmd) + { + data = 1; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + data = 0; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + SA_LEARN_LIMIT_DROP_EN, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_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; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + SA_LEARN_LIMIT_DROP_EN, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data) + { + *cmd = FAL_MAC_DROP; + } + else + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + + return SW_OK; +} + +static sw_error_t +_isis_fdb_learn_limit_set(a_uint32_t dev_id, a_bool_t enable, a_uint32_t cnt) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + HSL_REG_ENTRY_GET(rv, dev_id, GLOBAL_LEARN_LIMIT_CTL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + if (ISIS_MAX_LEARN_LIMIT_CNT < cnt) + { + return SW_BAD_PARAM; + } + SW_SET_REG_BY_FIELD(GLOBAL_LEARN_LIMIT_CTL, GOL_SA_LEARN_LIMIT_EN, 1, + reg); + SW_SET_REG_BY_FIELD(GLOBAL_LEARN_LIMIT_CTL, GOL_SA_LEARN_CNT, cnt, reg); + } + else if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(GLOBAL_LEARN_LIMIT_CTL, GOL_SA_LEARN_LIMIT_EN, 0, + reg); + SW_SET_REG_BY_FIELD(GLOBAL_LEARN_LIMIT_CTL, GOL_SA_LEARN_CNT, 0, reg); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_SET(rv, dev_id, GLOBAL_LEARN_LIMIT_CTL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_fdb_learn_limit_get(a_uint32_t dev_id, a_bool_t * enable, + a_uint32_t * cnt) +{ + sw_error_t rv; + a_uint32_t data, reg = 0; + + HSL_REG_ENTRY_GET(rv, dev_id, GLOBAL_LEARN_LIMIT_CTL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(GLOBAL_LEARN_LIMIT_CTL, GOL_SA_LEARN_LIMIT_EN, data, + reg); + if (data) + { + SW_GET_FIELD_BY_REG(GLOBAL_LEARN_LIMIT_CTL, GOL_SA_LEARN_CNT, data, + reg); + *enable = A_TRUE; + *cnt = data; + } + else + { + *enable = A_FALSE; + *cnt = 0; + } + + return SW_OK; +} + +static sw_error_t +_isis_fdb_learn_exceed_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_MAC_DROP == cmd) + { + data = 1; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + data = 0; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, GLOBAL_LEARN_LIMIT_CTL, 0, + GOL_SA_LEARN_LIMIT_DROP_EN, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_fdb_learn_exceed_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, GLOBAL_LEARN_LIMIT_CTL, 0, + GOL_SA_LEARN_LIMIT_DROP_EN, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data) + { + *cmd = FAL_MAC_DROP; + } + else + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + + return SW_OK; +} + +#define ISIS_RESV_ADDR_NUM 32 +#define RESV_ADDR_TBL0_ADDR 0x3c000 +#define RESV_ADDR_TBL1_ADDR 0x3c004 +#define RESV_ADDR_TBL2_ADDR 0x3c008 + +static void +_isis_resv_addr_parse(const a_uint32_t reg[], fal_mac_addr_t * addr) +{ + a_uint32_t i; + + for (i = 2; i < 6; i++) + { + addr->uc[i] = (reg[0] >> ((5 - i) << 3)) & 0xff; + } + + for (i = 0; i < 2; i++) + { + addr->uc[i] = (reg[1] >> ((1 - i) << 3)) & 0xff; + } +} + +static sw_error_t +_isis_resv_atu_sw_to_hw(a_uint32_t dev_id, fal_fdb_entry_t * entry, + a_uint32_t reg[]) +{ + a_uint32_t port; + + if (A_FALSE == entry->portmap_en) + { + if (A_TRUE != + hsl_port_prop_check(dev_id, entry->port.id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + port = 0x1UL << entry->port.id; + } + else + { + if (A_FALSE == + hsl_mports_prop_check(dev_id, entry->port.map, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + port = entry->port.map; + } + SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_DES_PORT, port, reg[1]); + + if (FAL_MAC_CPY_TO_CPU == entry->dacmd) + { + SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_COPY_TO_CPU, 1, reg[1]); + } + else if (FAL_MAC_RDT_TO_CPU == entry->dacmd) + { + SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_REDRCT_TO_CPU, 1, reg[1]); + } + else if (FAL_MAC_FRWRD != entry->dacmd) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_MAC_FRWRD != entry->sacmd) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == entry->leaky_en) + { + SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_LEAKY_EN, 1, reg[1]); + } + else + { + SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_LEAKY_EN, 0, reg[1]); + } + + if (A_TRUE != entry->static_en) + { + return SW_NOT_SUPPORTED; + } + SW_SET_REG_BY_FIELD(RESV_ADDR_TBL2, RESV_STATUS, 1, reg[2]); + + if (A_TRUE == entry->mirror_en) + { + SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_MIRROR_EN, 1, reg[1]); + } + + if (A_TRUE == entry->cross_pt_state) + { + SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_CROSS_PT, 1, reg[1]); + } + + if (A_TRUE == entry->da_pri_en) + { + SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_PRI_EN, 1, reg[1]); + SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_PRI, (entry->da_queue & 0x7), + reg[1]); + } + + _isis_fdb_fill_addr(entry->addr, ®[0], ®[1]); + return SW_OK; +} + +static void +_isis_resv_atu_hw_to_sw(const a_uint32_t reg[], fal_fdb_entry_t * entry) +{ + a_uint32_t data; + + aos_mem_zero(entry, sizeof (fal_fdb_entry_t)); + + entry->fid = FAL_SVL_FID; + + entry->dacmd = FAL_MAC_FRWRD; + SW_GET_FIELD_BY_REG(RESV_ADDR_TBL1, RESV_COPY_TO_CPU, data, reg[1]); + if (1 == data) + { + entry->dacmd = FAL_MAC_CPY_TO_CPU; + } + + SW_GET_FIELD_BY_REG(RESV_ADDR_TBL1, RESV_REDRCT_TO_CPU, data, reg[1]); + if (1 == data) + { + entry->dacmd = FAL_MAC_RDT_TO_CPU; + } + + entry->sacmd = FAL_MAC_FRWRD; + + entry->leaky_en = A_FALSE; + SW_GET_FIELD_BY_REG(RESV_ADDR_TBL1, RESV_LEAKY_EN, data, reg[1]); + if (1 == data) + { + entry->leaky_en = A_TRUE; + } + + entry->static_en = A_TRUE; + + entry->mirror_en = A_FALSE; + SW_GET_FIELD_BY_REG(RESV_ADDR_TBL1, RESV_MIRROR_EN, data, reg[1]); + if (1 == data) + { + entry->mirror_en = A_TRUE; + } + + entry->da_pri_en = A_FALSE; + SW_GET_FIELD_BY_REG(RESV_ADDR_TBL1, RESV_PRI_EN, data, reg[1]); + if (1 == data) + { + SW_GET_FIELD_BY_REG(RESV_ADDR_TBL1, RESV_PRI, data, reg[1]); + entry->da_pri_en = A_TRUE; + entry->da_queue = data & 0x7; + } + + entry->cross_pt_state = A_FALSE; + SW_GET_FIELD_BY_REG(RESV_ADDR_TBL1, RESV_CROSS_PT, data, reg[1]); + if (1 == data) + { + entry->cross_pt_state = A_TRUE; + } + + SW_GET_FIELD_BY_REG(RESV_ADDR_TBL1, RESV_DES_PORT, data, reg[1]); + entry->portmap_en = A_TRUE; + entry->port.map = data; + + _isis_resv_addr_parse(reg, &(entry->addr)); + return; +} + +static sw_error_t +_isis_fdb_resv_commit(a_uint32_t dev_id, fal_fdb_entry_t * entry, a_uint32_t op, + a_uint32_t * empty) +{ + a_uint32_t index, addr, data, tbl[3] = { 0 }; + sw_error_t rv; + fal_mac_addr_t mac_tmp; + + *empty = ISIS_RESV_ADDR_NUM; + for (index = 0; index < ISIS_RESV_ADDR_NUM; index++) + { + addr = RESV_ADDR_TBL2_ADDR + (index << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[2])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(RESV_ADDR_TBL2, RESV_STATUS, data, tbl[2]); + if (data) + { + addr = RESV_ADDR_TBL0_ADDR + (index << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[0])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + addr = RESV_ADDR_TBL1_ADDR + (index << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[1])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + _isis_resv_addr_parse(tbl, &mac_tmp); + if (!aos_mem_cmp + ((void *) &(entry->addr), (void *) &mac_tmp, + sizeof (fal_mac_addr_t))) + { + if (ARL_PURGE_ENTRY == op) + { + addr = RESV_ADDR_TBL2_ADDR + (index << 4); + tbl[2] = 0; + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[2])), + sizeof (a_uint32_t)); + return rv; + } + else if (ARL_LOAD_ENTRY == op) + { + return SW_ALREADY_EXIST; + } + else if (ARL_FIND_ENTRY == op) + { + _isis_resv_atu_hw_to_sw(tbl, entry); + return SW_OK; + } + } + } + else + { + *empty = index; + } + } + + return SW_NOT_FOUND; +} + +static sw_error_t +_isis_fdb_resv_add(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t i, empty, addr, tbl[3] = { 0 }; + + rv = _isis_resv_atu_sw_to_hw(dev_id, entry, tbl); + SW_RTN_ON_ERROR(rv); + + rv = _isis_fdb_resv_commit(dev_id, entry, ARL_LOAD_ENTRY, &empty); + if (SW_ALREADY_EXIST == rv) + { + return rv; + } + + if (ISIS_RESV_ADDR_NUM == empty) + { + return SW_NO_RESOURCE; + } + + for (i = 0; i < 3; i++) + { + addr = RESV_ADDR_TBL0_ADDR + (empty << 4) + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[i])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +static sw_error_t +_isis_fdb_resv_del(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t empty; + + rv = _isis_fdb_resv_commit(dev_id, entry, ARL_PURGE_ENTRY, &empty); + return rv; +} + +static sw_error_t +_isis_fdb_resv_find(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t empty; + + rv = _isis_fdb_resv_commit(dev_id, entry, ARL_FIND_ENTRY, &empty); + return rv; +} + +static sw_error_t +_isis_fdb_resv_iterate(a_uint32_t dev_id, a_uint32_t * iterator, + fal_fdb_entry_t * entry) +{ + a_uint32_t index, addr, data, tbl[3] = { 0 }; + sw_error_t rv; + + if ((NULL == iterator) || (NULL == entry)) + { + return SW_BAD_PTR; + } + + if (ISIS_RESV_ADDR_NUM < *iterator) + { + return SW_BAD_PARAM; + } + + for (index = *iterator; index < ISIS_RESV_ADDR_NUM; index++) + { + addr = RESV_ADDR_TBL2_ADDR + (index << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[2])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(RESV_ADDR_TBL2, RESV_STATUS, data, tbl[2]); + if (data) + { + addr = RESV_ADDR_TBL0_ADDR + (index << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[0])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + addr = RESV_ADDR_TBL1_ADDR + (index << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[1])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + _isis_resv_atu_hw_to_sw(tbl, entry); + break; + } + } + + if (ISIS_RESV_ADDR_NUM == index) + { + return SW_NO_MORE; + } + + *iterator = index + 1; + return SW_OK; +} + +static sw_error_t +_isis_fdb_port_learn_static_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 0xf; + } + else if (A_FALSE == enable) + { + data = 0x7; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + SA_LEARN_STATUS, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_fdb_port_learn_static_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + SA_LEARN_STATUS, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0xf == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isis_fdb_port_update(a_uint32_t dev_id, a_uint32_t fid, fal_mac_addr_t * addr, fal_port_t port_id, a_uint32_t op) +{ + sw_error_t rv; + fal_fdb_entry_t entry; + fal_fdb_op_t option; + a_uint32_t reg, port; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_SVL_FID < fid) + { + return SW_BAD_PARAM; + } + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + aos_mem_zero(&option, sizeof(fal_fdb_op_t)); + aos_mem_copy(&(entry.addr), addr, sizeof(fal_mac_addr_t)); + entry.fid = fid & 0xffff; + rv = _isis_fdb_get(dev_id, &option, &entry, ARL_FIND_ENTRY); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC1, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC1, DES_PORT, port, reg); + if (op) + { + port |= (0x1 << port_id); + } + else + { + port &= (~(0x1 << port_id)); + } + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, DES_PORT, port, reg); + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC1, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + rv = _isis_fdb_commit(dev_id, ARL_LOAD_ENTRY); + return rv; +} + +/** + * @brief Add a Fdb entry + * @param[in] dev_id device id + * @param[in] entry fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_fdb_add(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_fdb_add(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete all Fdb entries + * @details Comments: + * If set FAL_FDB_DEL_STATIC bit in flag which means delete all fdb + * entries otherwise only delete dynamic entries. + * @param[in] dev_id device id + * @param[in] flag delete operation option + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_fdb_del_all(a_uint32_t dev_id, a_uint32_t flag) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_fdb_del_all(dev_id, flag); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete Fdb entries on a particular port + * @details Comments: + * If set FAL_FDB_DEL_STATIC bit in flag which means delete all fdb + * entries otherwise only delete dynamic entries. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] flag delete operation option + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_fdb_del_by_port(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t flag) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_fdb_del_by_port(dev_id, port_id, flag); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a particular Fdb entry through mac address + * @details Comments: + * Only addr field in entry is meaning. For IVL learning vid or fid field + * also is meaning. + * @param[in] dev_id device id + * @param[in] entry fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_fdb_del_by_mac(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_fdb_del_by_mac(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Find a particular Fdb entry from device through mac address. + * @details Comments: + For input parameter only addr field in entry is meaning. + * @param[in] dev_id device id + * @param[in] entry fdb entry + * @param[out] entry fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_fdb_find(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_fdb_find(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get next Fdb entry from a particular device + * @param[in] dev_id device id + * @param[in] option next operation options + * @param[out] entry fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_fdb_extend_next(a_uint32_t dev_id, fal_fdb_op_t * option, + fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_fdb_extend_next(dev_id, option, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get first Fdb entry from a particular device + * @param[in] dev_id device id + * @param[in] option first operation options + * @param[out] entry fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_fdb_extend_first(a_uint32_t dev_id, fal_fdb_op_t * option, + fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_fdb_extend_first(dev_id, option, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Transfer fdb entries port information on a particular device. + * @param[in] dev_id device id + * @param[in] old_port source port id + * @param[in] new_port destination port id + * @param[in] fid filter database id + * @param[in] option transfer operation options + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_fdb_transfer(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; + + HSL_API_LOCK; + rv = _isis_fdb_transfer(dev_id, old_port, new_port, fid, option); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dynamic address learning status on a particular port. + * @details Comments: + * This operation will enable or disable dynamic address learning + * feature on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable enable or disable + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_fdb_port_learn_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_fdb_port_learn_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dynamic address learning status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_fdb_port_learn_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_fdb_port_learn_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dynamic address aging status on particular device. + * @details Comments: + * This operation will enable or disable dynamic address aging + * feature on particular device. + * @param[in] dev_id device id + * @param[in] enable enable or disable + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_fdb_age_ctrl_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_fdb_age_ctrl_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dynamic address aging status on particular device. + * @param[in] dev_id device id + * @param[in] enable enable or disable + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_fdb_age_ctrl_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_fdb_age_ctrl_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dynamic address aging time on a particular device. + * @details Comments: + * This operation will set dynamic address aging time on a particular device. + * The unit of time is second. Because different device has differnet + * hardware granularity function will return actual time in hardware. + * @param[in] dev_id device id + * @param time aging time + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_fdb_age_time_set(a_uint32_t dev_id, a_uint32_t * time) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_fdb_age_time_set(dev_id, time); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dynamic address aging time on a particular device. + * @param[in] dev_id device id + * @param[out] time aging time + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_fdb_age_time_get(a_uint32_t dev_id, a_uint32_t * time) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_fdb_age_time_get(dev_id, time); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dynamic address learning count limit on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] cnt limit count + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_port_fdb_learn_limit_set(dev_id, port_id, enable, cnt); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dynamic address learning count limit on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @param[out] cnt limit count + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_port_fdb_learn_limit_get(dev_id, port_id, enable, cnt); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dynamic address learning count exceed command on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_port_fdb_learn_exceed_cmd_set(dev_id, port_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dynamic address learning count exceed command on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_port_fdb_learn_exceed_cmd_get(dev_id, port_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dynamic address learning count limit on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] cnt limit count + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_fdb_learn_limit_set(a_uint32_t dev_id, a_bool_t enable, a_uint32_t cnt) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_fdb_learn_limit_set(dev_id, enable, cnt); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dynamic address learning count limit on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] cnt limit count + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_fdb_learn_limit_get(a_uint32_t dev_id, a_bool_t * enable, a_uint32_t * cnt) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_fdb_learn_limit_get(dev_id, enable, cnt); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dynamic address learning count exceed command on a particular device. + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_fdb_learn_exceed_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_fdb_learn_exceed_cmd_set(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dynamic address learning count exceed command on a particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_fdb_learn_exceed_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_fdb_learn_exceed_cmd_get(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add a particular reserve Fdb entry + * @param[in] dev_id device id + * @param[in] entry reserve fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_fdb_resv_add(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_fdb_resv_add(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a particular reserve Fdb entry through mac address + * @param[in] dev_id device id + * @param[in] entry reserve fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_fdb_resv_del(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_fdb_resv_del(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Find a particular reserve Fdb entry through mac address + * @param[in] dev_id device id + * @param[in] entry reserve fdb entry + * @param[out] entry reserve fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_fdb_resv_find(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_fdb_resv_find(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Iterate all reserve fdb entries on a particular device. + * @param[in] dev_id device id + * @param[in] iterator reserve fdb entry index if it's zero means get the first entry + * @param[out] iterator next valid fdb entry index + * @param[out] entry reserve fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_fdb_resv_iterate(a_uint32_t dev_id, a_uint32_t * iterator, + fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_fdb_resv_iterate(dev_id, iterator, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set the static status of fdb entries which learned by hardware on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_fdb_port_learn_static_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_fdb_port_learn_static_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get the static status of fdb entries which learned by hardware on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_fdb_port_learn_static_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_fdb_port_learn_static_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add a port to an exsiting entry + * @param[in] dev_id device id + * @param[in] fid filtering database id + * @param[in] addr MAC address + * @param[in] port_id port id + * @return SW_OK or error code, If entry not exist will return error. + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_fdb_port_update(dev_id, fid, addr, port_id, 1); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a port from an exsiting entry + * @param[in] dev_id device id + * @param[in] fid filtering database id + * @param[in] addr MAC address + * @param[in] port_id port id + * @return SW_OK or error code, If entry not exist will return error. + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_fdb_port_update(dev_id, fid, addr, port_id, 0); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +isis_fdb_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->fdb_add = isis_fdb_add; + p_api->fdb_del_all = isis_fdb_del_all; + p_api->fdb_del_by_port = isis_fdb_del_by_port; + p_api->fdb_del_by_mac = isis_fdb_del_by_mac; + p_api->fdb_extend_first = isis_fdb_extend_first; + p_api->fdb_extend_next = isis_fdb_extend_next; + p_api->fdb_find = isis_fdb_find; + p_api->port_learn_set = isis_fdb_port_learn_set; + p_api->port_learn_get = isis_fdb_port_learn_get; + p_api->age_ctrl_set = isis_fdb_age_ctrl_set; + p_api->age_ctrl_get = isis_fdb_age_ctrl_get; + p_api->age_time_set = isis_fdb_age_time_set; + p_api->age_time_get = isis_fdb_age_time_get; + p_api->fdb_extend_next = isis_fdb_extend_next; + p_api->fdb_extend_first = isis_fdb_extend_first; + p_api->fdb_transfer = isis_fdb_transfer; + p_api->port_fdb_learn_limit_set = isis_port_fdb_learn_limit_set; + p_api->port_fdb_learn_limit_get = isis_port_fdb_learn_limit_get; + p_api->port_fdb_learn_exceed_cmd_set = isis_port_fdb_learn_exceed_cmd_set; + p_api->port_fdb_learn_exceed_cmd_get = isis_port_fdb_learn_exceed_cmd_get; + p_api->fdb_learn_limit_set = isis_fdb_learn_limit_set; + p_api->fdb_learn_limit_get = isis_fdb_learn_limit_get; + p_api->fdb_learn_exceed_cmd_set = isis_fdb_learn_exceed_cmd_set; + p_api->fdb_learn_exceed_cmd_get = isis_fdb_learn_exceed_cmd_get; + p_api->fdb_resv_add = isis_fdb_resv_add; + p_api->fdb_resv_del = isis_fdb_resv_del; + p_api->fdb_resv_find = isis_fdb_resv_find; + p_api->fdb_resv_iterate = isis_fdb_resv_iterate; + p_api->fdb_port_learn_static_set = isis_fdb_port_learn_static_set; + p_api->fdb_port_learn_static_get = isis_fdb_port_learn_static_get; + p_api->fdb_port_add = isis_fdb_port_add; + p_api->fdb_port_del = isis_fdb_port_del; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_igmp.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_igmp.c new file mode 100755 index 000000000..300dd0430 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_igmp.c @@ -0,0 +1,1143 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup isis_igmp ISIS_IGMP + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isis_igmp.h" +#include "isis_reg.h" + +#define LEAVE_EN_OFFSET 2 +#define JOIN_EN_OFFSET 1 +#define IGMP_MLD_EN_OFFSET 0 + +#define ISIS_MAX_PORT_LEARN_LIMIT_CNT 1023 + +extern sw_error_t +isis_igmp_sg_entry_set(a_uint32_t dev_id, fal_igmp_sg_entry_t * entry); + +extern sw_error_t +isis_igmp_sg_entry_clear(a_uint32_t dev_id, fal_igmp_sg_entry_t * entry); + +extern sw_error_t +isis_igmp_sg_entry_show(a_uint32_t dev_id); + +static sw_error_t +_isis_port_igmp_property_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable, a_uint32_t item) +{ + sw_error_t rv; + a_uint32_t reg = 0, val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + if (3 >= port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, FRAME_ACK_CTL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + reg &= ~(0x1UL << ((port_id << 3) + item)); + reg |= (val << ((port_id << 3) + item)); + + HSL_REG_ENTRY_SET(rv, dev_id, FRAME_ACK_CTL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + HSL_REG_ENTRY_GET(rv, dev_id, FRAME_ACK_CTL1, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + reg &= ~(0x1UL << (((port_id - 4) << 3) + item)); + reg |= (val << (((port_id - 4) << 3) + item)); + + HSL_REG_ENTRY_SET(rv, dev_id, FRAME_ACK_CTL1, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + return rv; +} + +static sw_error_t +_isis_port_igmp_property_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable, a_uint32_t item) +{ + sw_error_t rv; + a_uint32_t reg = 0, val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (3 >= port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, FRAME_ACK_CTL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + val = (reg >> ((port_id << 3) + item)) & 0x1UL; + } + else + { + HSL_REG_ENTRY_GET(rv, dev_id, FRAME_ACK_CTL1, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + val = (reg >> (((port_id - 4) << 3) + item)) & 0x1UL; + } + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isis_igmp_mld_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_MAC_CPY_TO_CPU == cmd) + { + val = 1; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + val = 0; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, IGMP_COPY_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_igmp_mld_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, IGMP_COPY_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *cmd = FAL_MAC_CPY_TO_CPU; + } + else + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + + return SW_OK; +} + +static sw_error_t +_isis_igmp_mld_rp_set(a_uint32_t dev_id, fal_pbmp_t pts) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_mports_validity_check(dev_id, pts)) + { + return SW_BAD_PARAM; + } + val = pts; + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL1, 0, IGMP_DP, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_igmp_mld_rp_get(a_uint32_t dev_id, fal_pbmp_t * pts) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL1, 0, IGMP_DP, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *pts = val; + return SW_OK; +} + +static sw_error_t +_isis_igmp_mld_entry_creat_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, ADDR_TABLE_CTL, 0, IGMP_CREAT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_igmp_mld_entry_creat_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_CTL, 0, IGMP_CREAT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isis_igmp_mld_entry_static_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 0xf; + } + else if (A_FALSE == enable) + { + val = 0xe; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, ADDR_TABLE_CTL, 0, IGMP_JOIN_STATIC, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_igmp_mld_entry_static_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_CTL, 0, IGMP_JOIN_STATIC, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0xf == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isis_igmp_mld_entry_leaky_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, ADDR_TABLE_CTL, 0, IGMP_JOIN_LEAKY, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_igmp_mld_entry_leaky_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_CTL, 0, IGMP_JOIN_LEAKY, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isis_igmp_mld_entry_v3_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FRAME_ACK_CTL1, 0, IGMP_V3_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_igmp_mld_entry_v3_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FRAME_ACK_CTL1, 0, IGMP_V3_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isis_igmp_mld_entry_queue_set(a_uint32_t dev_id, a_bool_t enable, + a_uint32_t queue) +{ + sw_error_t rv; + a_uint32_t entry = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_CTL, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_CTL, IGMP_PRI_EN, 1, entry); + SW_SET_REG_BY_FIELD(ADDR_TABLE_CTL, IGMP_PRI, queue, entry); + } + else if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_CTL, IGMP_PRI_EN, 0, entry); + SW_SET_REG_BY_FIELD(ADDR_TABLE_CTL, IGMP_PRI, 0, entry); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_CTL, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_igmp_mld_entry_queue_get(a_uint32_t dev_id, a_bool_t * enable, + a_uint32_t * queue) +{ + sw_error_t rv; + a_uint32_t entry = 0, data; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_CTL, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(ADDR_TABLE_CTL, IGMP_PRI_EN, data, entry); + if (data) + { + *enable = A_TRUE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_CTL, IGMP_PRI, data, entry); + *queue = data; + } + else + { + *enable = A_FALSE; + *queue = 0; + } + + return SW_OK; +} + +static sw_error_t +_isis_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; + a_uint32_t reg = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + if (ISIS_MAX_PORT_LEARN_LIMIT_CNT < cnt) + { + return SW_BAD_PARAM; + } + SW_SET_REG_BY_FIELD(PORT_LEARN_LIMIT_CTL, IGMP_JOIN_LIMIT_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_LEARN_LIMIT_CTL, IGMP_JOIN_CNT, cnt, reg); + } + else if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(PORT_LEARN_LIMIT_CTL, IGMP_JOIN_LIMIT_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_LEARN_LIMIT_CTL, IGMP_JOIN_CNT, 0, reg); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_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; + a_uint32_t data, reg = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_LEARN_LIMIT_CTL, IGMP_JOIN_LIMIT_EN, data, reg); + if (data) + { + SW_GET_FIELD_BY_REG(PORT_LEARN_LIMIT_CTL, IGMP_JOIN_CNT, data, reg); + *enable = A_TRUE; + *cnt = data; + } + else + { + *enable = A_FALSE; + *cnt = data; + } + + return SW_OK; +} + +static sw_error_t +_isis_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; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_MAC_DROP == cmd) + { + data = 1; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + data = 0; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + IGMP_JOIN_LIMIT_DROP_EN, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_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; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + IGMP_JOIN_LIMIT_DROP_EN, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data) + { + *cmd = FAL_MAC_DROP; + } + else + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + + return SW_OK; +} + +/** + * @brief Set igmp/mld packets snooping status on a particular port. + * @details Comments: + * After enabling igmp/mld snooping feature on a particular port all kinds + * igmp/mld packets received on this port would be acknowledged by hardware. + * Particular forwarding decision could be setted by fal_igmp_mld_cmd_set. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_igmps_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_igmp_property_set(dev_id, port_id, enable, + IGMP_MLD_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld packets snooping status on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_igmps_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_igmp_property_get(dev_id, port_id, enable, + IGMP_MLD_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmp/mld packets forwarding command on a particular device. + * @details Comments: + * Particular device may only support parts of forwarding commands. + * This operation will take effect only after enabling igmp/mld snooping + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_igmp_mld_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_igmp_mld_cmd_set(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld packets forwarding command on a particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_igmp_mld_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_igmp_mld_cmd_get(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmp/mld join packets hardware acknowledgement status on particular port. + * @details Comments: + * After enabling igmp/mld join feature on a particular port hardware will + * dynamic learning or changing multicast entry. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_igmp_mld_join_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_igmp_property_set(dev_id, port_id, enable, JOIN_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld join packets hardware acknowledgement status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_igmp_mld_join_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_igmp_property_get(dev_id, port_id, enable, JOIN_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmp/mld leave packets hardware acknowledgement status on a particular port. + * @details Comments: + * After enabling igmp leave feature on a particular port hardware will dynamic + * deleting or changing multicast entry. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_igmp_mld_leave_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_igmp_property_set(dev_id, port_id, enable, LEAVE_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld leave packets hardware acknowledgement status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_igmp_mld_leave_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_igmp_property_get(dev_id, port_id, enable, LEAVE_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmp/mld router ports on a particular device. + * @details Comments: + * After enabling igmp/mld join/leave feature on a particular port igmp/mld + * join/leave packets received on this port will be forwarded to router ports. + * @param[in] dev_id device id + * @param[in] pts dedicates ports + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_igmp_mld_rp_set(a_uint32_t dev_id, fal_pbmp_t pts) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_igmp_mld_rp_set(dev_id, pts); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld router ports on a particular device. + * @param[in] dev_id device id + * @param[out] pts dedicates ports + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_igmp_mld_rp_get(a_uint32_t dev_id, fal_pbmp_t * pts) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_igmp_mld_rp_get(dev_id, pts); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set the status of creating multicast entry during igmp/mld join/leave procedure. + * @details Comments: + * After enabling igmp/mld join/leave feature on a particular port if enable + * entry creat hardware will dynamic creat and delete multicast entry, + * otherwise hardware only can change destination ports of existing muticast entry. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_igmp_mld_entry_creat_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_igmp_mld_entry_creat_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get the status of creating multicast entry during igmp/mld join/leave procedure. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_igmp_mld_entry_creat_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_igmp_mld_entry_creat_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set the static status of multicast entry which learned by hardware. + * @details Comments: + * After enabling igmp/mld join/leave feature on a particular port if enable + * static status hardware will not age out multicast entry which leardned by hardware, + * otherwise hardware will age out multicast entry which leardned by hardware. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_igmp_mld_entry_static_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_igmp_mld_entry_static_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get the static status of multicast entry which learned by hardware. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_igmp_mld_entry_static_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_igmp_mld_entry_static_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set the leaky status of multicast entry which learned by hardware. + * @details Comments: + * After enabling igmp/mld join/leave feature on a particular port if enable + * leaky status hardware will set leaky flag of multicast entry which leardned by hardware, + * otherwise hardware will not set leaky flag of multicast entry which leardned by hardware. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_igmp_mld_entry_leaky_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_igmp_mld_entry_leaky_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get the leaky status of multicast entry which learned by hardware. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_igmp_mld_entry_leaky_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_igmp_mld_entry_leaky_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmpv3/mldv2 packets hardware acknowledgement status on a particular device. + * @details Comments: + * After enabling igmp join/leave feature on a particular port hardware will dynamic + * creating or changing multicast entry after receiving igmpv3/mldv2 packets. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_igmp_mld_entry_v3_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_igmp_mld_entry_v3_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmpv3/mldv2 packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_igmp_mld_entry_v3_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_igmp_mld_entry_v3_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set the queue status of multicast entry which learned by hardware. + * @details Comments: + * After enabling igmp/mld join/leave feature on a particular port if enable + * leaky status hardware will set queue flag of multicast entry which leardned by hardware, + * otherwise hardware will not set queue flag of multicast entry which leardned by hardware. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] queue queue id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_igmp_mld_entry_queue_set(a_uint32_t dev_id, a_bool_t enable, + a_uint32_t queue) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_igmp_mld_entry_queue_set(dev_id, enable, queue); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get the queue status of multicast entry which learned by hardware. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @param[out] queue queue id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_igmp_mld_entry_queue_get(a_uint32_t dev_id, a_bool_t * enable, + a_uint32_t * queue) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_igmp_mld_entry_queue_get(dev_id, enable, queue); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set IGMP hardware learning count limit on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] cnt limit count + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_port_igmp_mld_learn_limit_set(dev_id, port_id, enable, cnt); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IGMP hardware learning count limit on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @param[out] cnt limit count + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_port_igmp_mld_learn_limit_get(dev_id, port_id, enable, cnt); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set IGMP hardware learning count exceed command on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_port_igmp_mld_learn_exceed_cmd_set(dev_id, port_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IGMP hardware learning count exceed command on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_port_igmp_mld_learn_exceed_cmd_get(dev_id, port_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +isis_igmp_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->port_igmps_status_set = isis_port_igmps_status_set; + p_api->port_igmps_status_get = isis_port_igmps_status_get; + p_api->igmp_mld_cmd_set = isis_igmp_mld_cmd_set; + p_api->igmp_mld_cmd_get = isis_igmp_mld_cmd_get; + p_api->port_igmp_join_set = isis_port_igmp_mld_join_set; + p_api->port_igmp_join_get = isis_port_igmp_mld_join_get; + p_api->port_igmp_leave_set = isis_port_igmp_mld_leave_set; + p_api->port_igmp_leave_get = isis_port_igmp_mld_leave_get; + p_api->igmp_rp_set = isis_igmp_mld_rp_set; + p_api->igmp_rp_get = isis_igmp_mld_rp_get; + p_api->igmp_entry_creat_set = isis_igmp_mld_entry_creat_set; + p_api->igmp_entry_creat_get = isis_igmp_mld_entry_creat_get; + p_api->igmp_entry_static_set = isis_igmp_mld_entry_static_set; + p_api->igmp_entry_static_get = isis_igmp_mld_entry_static_get; + p_api->igmp_entry_leaky_set = isis_igmp_mld_entry_leaky_set; + p_api->igmp_entry_leaky_get = isis_igmp_mld_entry_leaky_get; + p_api->igmp_entry_v3_set = isis_igmp_mld_entry_v3_set; + p_api->igmp_entry_v3_get = isis_igmp_mld_entry_v3_get; + p_api->igmp_entry_queue_set = isis_igmp_mld_entry_queue_set; + p_api->igmp_entry_queue_get = isis_igmp_mld_entry_queue_get; + p_api->port_igmp_mld_learn_limit_set = isis_port_igmp_mld_learn_limit_set; + p_api->port_igmp_mld_learn_limit_get = isis_port_igmp_mld_learn_limit_get; + p_api->port_igmp_mld_learn_exceed_cmd_set = isis_port_igmp_mld_learn_exceed_cmd_set; + p_api->port_igmp_mld_learn_exceed_cmd_get = isis_port_igmp_mld_learn_exceed_cmd_get; + p_api->igmp_sg_entry_set = isis_igmp_sg_entry_set; + p_api->igmp_sg_entry_clear = isis_igmp_sg_entry_clear; + p_api->igmp_sg_entry_show = isis_igmp_sg_entry_show; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_init.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_init.c new file mode 100755 index 000000000..b854c2b45 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_init.c @@ -0,0 +1,340 @@ +/* + * Copyright (c) 2012, 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 isis_init ISIS_INIT + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isis_mib.h" +#include "isis_port_ctrl.h" +#include "isis_portvlan.h" +#include "isis_vlan.h" +#include "isis_fdb.h" +#include "isis_qos.h" +#include "isis_mirror.h" +#include "isis_stp.h" +#include "isis_rate.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" +#if defined(IN_NAT_HELPER) +#include "isis_nat_helper.h" +#endif +#include "isis_sec.h" +#include "isis_trunk.h" +#include "isis_interface_ctrl.h" +#include "isis_reg_access.h" +#include "isis_reg.h" +#include "isis_init.h" +#include "f1_phy.h" + +static ssdk_init_cfg * isis_cfg[SW_MAX_NR_DEV] = { 0 }; +a_uint32_t isis_nat_global_status = 0; + +#if !(defined(KERNEL_MODULE) && defined(USER_MODE)) +/* For isis there are five internal PHY devices and seven MAC devices. + MAC0 always connect to external MAC device. + PHY4 can connect to MAC5 or external MAC device. + MAC6 always connect to external devices. + MAC1..MAC4 connect to internal PHY0..PHY3. +*/ +static sw_error_t +isis_portproperty_init(a_uint32_t dev_id, hsl_init_mode mode) +{ + hsl_port_prop_t p_type; + hsl_dev_t *pdev = NULL; + fal_port_t port_id; + + pdev = hsl_dev_ptr_get(dev_id); + if (pdev == NULL) + return SW_NOT_INITIALIZED; + + /* for port property set, SSDK should not generate some limitations */ + for (port_id = 0; port_id < pdev->nr_ports; port_id++) + { + hsl_port_prop_portmap_set(dev_id, port_id); + + for (p_type = HSL_PP_PHY; p_type < HSL_PP_BUTT; p_type++) + { + if (HSL_NO_CPU == mode) + { + SW_RTN_ON_ERROR(hsl_port_prop_set(dev_id, port_id, p_type)); + continue; + } + + switch (p_type) + { + case HSL_PP_PHY: + /* Only port0/port6 without PHY device */ + if ((port_id != pdev->cpu_port_nr) + && (port_id != pdev->nr_ports - 1)) + { + SW_RTN_ON_ERROR(hsl_port_prop_set(dev_id, port_id, p_type)); + } + break; + + case HSL_PP_INCL_CPU: + /* include cpu port but exclude wan port in some cases */ + /* but which port is wan port, we are no meaning */ + SW_RTN_ON_ERROR(hsl_port_prop_set(dev_id, port_id, p_type)); + break; + + case HSL_PP_EXCL_CPU: + /* exclude cpu port and wan port in some cases */ + /* which port is wan port, we are no meaning but port0 is + always CPU port */ + if (port_id != pdev->cpu_port_nr) + { + SW_RTN_ON_ERROR(hsl_port_prop_set(dev_id, port_id, p_type)); + } + break; + + default: + break; + } + } + + if (HSL_NO_CPU == mode) + { + SW_RTN_ON_ERROR(hsl_port_prop_set_phyid + (dev_id, port_id, port_id + 1)); + } + else + { + if (port_id != pdev->cpu_port_nr) + { + SW_RTN_ON_ERROR(hsl_port_prop_set_phyid + (dev_id, port_id, port_id - 1)); + } + } + } + + return SW_OK; +} + +static sw_error_t +isis_hw_init(a_uint32_t dev_id, ssdk_init_cfg *cfg) +{ + return SW_OK; +} + +#endif + +static sw_error_t +isis_dev_init(a_uint32_t dev_id, hsl_init_mode cpu_mode) +{ + a_uint32_t entry = 0; + sw_error_t rv; + hsl_dev_t *pdev = NULL; + + pdev = hsl_dev_ptr_get(dev_id); + if (pdev == NULL) + return SW_NOT_INITIALIZED; + + HSL_REG_FIELD_GET(rv, dev_id, MASK_CTL, 0, DEVICE_ID, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (S17_DEVICE_ID == entry) + { + pdev->nr_ports = 7; + pdev->nr_phy = 5; + pdev->cpu_port_nr = 0; + pdev->nr_vlans = 4096; + pdev->hw_vlan_query = A_TRUE; + pdev->nr_queue = 6; + pdev->cpu_mode = cpu_mode; + } + else + { + pdev->nr_ports = 6; + pdev->nr_phy = 5; + pdev->cpu_port_nr = 0; + pdev->nr_vlans = 4096; + pdev->hw_vlan_query = A_TRUE; + pdev->nr_queue = 6; + pdev->cpu_mode = cpu_mode; + } + + return SW_OK; +} + + +static sw_error_t +_isis_reset(a_uint32_t dev_id) +{ +#if !(defined(KERNEL_MODULE) && defined(USER_MODE)) + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + val = 0x1; + HSL_REG_FIELD_SET(rv, dev_id, MASK_CTL, 0, SOFT_RST, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = isis_hw_init(dev_id, isis_cfg[dev_id]); + SW_RTN_ON_ERROR(rv); + + ISIS_ACL_RESET(rv, dev_id); + ISIS_IP_RESET(rv, dev_id); + ISIS_NAT_RESET(rv, dev_id); +#endif + + return SW_OK; +} + +sw_error_t +isis_cleanup(a_uint32_t dev_id) +{ + sw_error_t rv; + + if (isis_cfg[dev_id]) + { +#if defined(IN_NAT_HELPER) + if(isis_nat_global_status) { + ISIS_NAT_HELPER_CLEANUP(rv, dev_id); + isis_nat_global_status = 0; + } +#endif + + ISIS_ACL_CLEANUP(rv, dev_id); + + SW_RTN_ON_ERROR(hsl_port_prop_cleanup_by_dev(dev_id)); + + aos_mem_free(isis_cfg[dev_id]); + isis_cfg[dev_id] = NULL; + } + + return SW_OK; +} + +/** + * @brief reset hsl layer. + * @details Comments: + * This operation will reset hsl layer + * @param[in] dev_id device id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_reset(a_uint32_t dev_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_reset(dev_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Init hsl layer. + * @details Comments: + * This operation will init hsl layer and hsl layer + * @param[in] dev_id device id + * @param[in] cfg configuration for initialization + * @return SW_OK or error code + */ +sw_error_t +isis_init(a_uint32_t dev_id, ssdk_init_cfg *cfg) +{ + HSL_DEV_ID_CHECK(dev_id); + + if (NULL == isis_cfg[dev_id]) + { + isis_cfg[dev_id] = aos_mem_alloc(sizeof (ssdk_init_cfg)); + } + + if (NULL == isis_cfg[dev_id]) + { + return SW_OUT_OF_MEM; + } + + aos_mem_copy(isis_cfg[dev_id], cfg, sizeof (ssdk_init_cfg)); + + SW_RTN_ON_ERROR(isis_reg_access_init(dev_id, cfg->reg_mode)); + + SW_RTN_ON_ERROR(isis_dev_init(dev_id, cfg->cpu_mode)); + +#if !(defined(KERNEL_MODULE) && defined(USER_MODE)) + { + sw_error_t rv; + + SW_RTN_ON_ERROR(hsl_port_prop_init(dev_id)); + SW_RTN_ON_ERROR(hsl_port_prop_init_by_dev(dev_id)); + SW_RTN_ON_ERROR(isis_portproperty_init(dev_id, cfg->cpu_mode)); + + ISIS_MIB_INIT(rv, dev_id); + ISIS_PORT_CTRL_INIT(rv, dev_id); + ISIS_PORTVLAN_INIT(rv, dev_id); + ISIS_VLAN_INIT(rv, dev_id); + ISIS_FDB_INIT(rv, dev_id); + ISIS_QOS_INIT(rv, dev_id); + ISIS_STP_INIT(rv, dev_id); + ISIS_MIRR_INIT(rv, dev_id); + ISIS_RATE_INIT(rv, dev_id); + ISIS_MISC_INIT(rv, dev_id); + ISIS_LEAKY_INIT(rv, dev_id); + ISIS_IGMP_INIT(rv, dev_id); + ISIS_ACL_INIT(rv, dev_id); + ISIS_LED_INIT(rv, dev_id); + ISIS_COSMAP_INIT(rv, dev_id); + ISIS_IP_INIT(rv, dev_id); + ISIS_NAT_INIT(rv, dev_id); + ISIS_TRUNK_INIT(rv, dev_id); + ISIS_SEC_INIT(rv, dev_id); + ISIS_INTERFACE_CTRL_INIT(rv, dev_id); + + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->dev_reset = isis_reset; + p_api->dev_clean = isis_cleanup; + } + + SW_RTN_ON_ERROR(isis_hw_init(dev_id, cfg)); +#if 0 +#if defined(IN_NAT_HELPER) + if(!isis_nat_global_status) { + ISIS_NAT_HELPER_INIT(rv, dev_id); + isis_nat_global_status = 1; + } +#endif +#endif + +#if defined(IN_MACBLOCK) + qca_mac_scan_helper_init(); +#endif + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_interface_ctrl.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_interface_ctrl.c new file mode 100755 index 000000000..8874ad1c5 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_interface_ctrl.c @@ -0,0 +1,1710 @@ +/* + * Copyright (c) 2012, 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 isis_interface_ctrl ISIS_INTERFACE_CONTROL + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isis_interface_ctrl.h" +#include "isis_reg.h" +#include "hsl_phy.h" + +#define ISIS_MAC_0 0 +#define ISIS_MAC_5 5 +#define ISIS_MAC_6 6 + +#define ISIS_PHY_MODE_PHY_ID 4 +#define ISIS_LPI_PORT1_OFFSET 4 +#define ISIS_LPI_BIT_STEP 2 + +/* we need to do more about MAC5/PHY4 connection... */ +#if 0 +static sw_error_t +_isis_port_mac5_internal_mode(a_uint32_t dev_id, a_bool_t * inter_mode) +{ + sw_error_t rv; + a_uint32_t reg, rgmii, gmii_mac, gmii_phy, mii_mac, mii_phy, sgmii; + + HSL_REG_ENTRY_GET(rv, dev_id, PORT5_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_RGMII_EN, rgmii, reg); + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_MAC_GMII_EN, gmii_mac, reg); + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_PHY_GMII_EN, gmii_phy, reg); + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_MAC_MII_EN, mii_mac, reg); + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_PHY_MII_EN, mii_phy, reg); + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_SGMII_EN, sgmii, reg); + + if (rgmii || gmii_mac || gmii_phy || mii_mac || mii_phy || sgmii) + { + *inter_mode = A_FALSE; + } + else + { + *inter_mode = A_TRUE; + } + + return SW_OK; +} + +static sw_error_t +_isis_port_phy4_internal_mode(a_uint32_t dev_id, a_bool_t * inter_mode) +{ + sw_error_t rv; + a_uint32_t reg, rgmii, gmii, mii; + + HSL_REG_ENTRY_GET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT6_PAD_CTRL, PHY4_RGMII_EN, rgmii, reg); + SW_GET_FIELD_BY_REG(PORT6_PAD_CTRL, PHY4_GMII_EN, gmii, reg); + SW_GET_FIELD_BY_REG(PORT6_PAD_CTRL, PHY4_MII_EN, mii, reg); + + if (rgmii || gmii || mii) + { + *inter_mode = A_FALSE; + } + else + { + *inter_mode = A_TRUE; + } + + return SW_OK; +} +#endif + +static sw_error_t +_isis_port_3az_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t reg = 0, field, offset, device_id, rev_id, reverse = 0; + + HSL_REG_ENTRY_GET(rv, dev_id, MASK_CTL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(MASK_CTL, DEVICE_ID, device_id, reg); + if (S17_DEVICE_ID != device_id) + { + return SW_NOT_SUPPORTED; + } + + SW_GET_FIELD_BY_REG(MASK_CTL, REV_ID, rev_id, reg); + if (S17_REVISION_A == rev_id) + { + reverse = 0; + } + else + { + reverse = 1; + } + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, EEE_CTL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + field = 1; + } + else if (A_FALSE == enable) + { + field = 0; + } + else + { + return SW_BAD_PARAM; + } + + if (reverse) + { + field = (~field) & 0x1UL; + } + + offset = (port_id - 1) * ISIS_LPI_BIT_STEP + ISIS_LPI_PORT1_OFFSET; + reg &= (~(0x1UL << offset)); + reg |= (field << offset); + + HSL_REG_ENTRY_SET(rv, dev_id, EEE_CTL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_3az_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t reg = 0, field, offset, device_id, rev_id, reverse = 0; + + HSL_REG_ENTRY_GET(rv, dev_id, MASK_CTL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(MASK_CTL, DEVICE_ID, device_id, reg); + if (S17_DEVICE_ID != device_id) + { + return SW_NOT_SUPPORTED; + } + + SW_GET_FIELD_BY_REG(MASK_CTL, REV_ID, rev_id, reg); + if (S17_REVISION_A == rev_id) + { + reverse = 0; + } + else + { + reverse = 1; + } + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, EEE_CTL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + offset = (port_id - 1) * ISIS_LPI_BIT_STEP + ISIS_LPI_PORT1_OFFSET; + field = (reg >> offset) & 0x1; + + if (reverse) + { + field = (~field) & 0x1UL; + } + + if (field) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isis_port_rgmii_mode_set(a_uint32_t dev_id, fal_port_t port_id, fal_mac_rgmii_config_t * config) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + if (ISIS_MAC_0 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISIS_MAC_5 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT5_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISIS_MAC_6 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_SGMII_EN, 0, reg); + + /* hardware suggestions: restore to defatult settings */ + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_RXCLK_SEL, 0, reg); + + if (A_TRUE == config->txclk_delay_cmd) + { + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_TXCLK_DELAY_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_TXCLK_DELAY_SEL, config->txclk_delay_sel, reg); + } + else + { + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_TXCLK_DELAY_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_TXCLK_DELAY_SEL, 0, reg); + } + + if (A_TRUE == config->rxclk_delay_cmd) + { + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_RXCLK_DELAY_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_RXCLK_DELAY_SEL, config->rxclk_delay_sel, reg); + } + else + { + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_RXCLK_DELAY_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_RXCLK_DELAY_SEL, 0, reg); + } + + if (ISIS_MAC_0 == port_id) + { + HSL_REG_ENTRY_SET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISIS_MAC_5 == port_id) + { + HSL_REG_ENTRY_SET(rv, dev_id, PORT5_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + HSL_REG_ENTRY_SET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + SW_RTN_ON_ERROR(rv); + + /* Port status register setting */ + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + /* setting port status default configuration */ + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, FLOW_LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, RX_FLOW_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TX_FLOW_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, DUPLEX_MODE, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, RXMAC_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TXMAC_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, SPEED_MODE, 2, reg); + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_rgmii_mode_get(a_uint32_t dev_id, fal_port_t port_id, fal_mac_rgmii_config_t * config) +{ + sw_error_t rv; + a_uint32_t reg = 0, field; + + if (ISIS_MAC_0 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISIS_MAC_5 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT5_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISIS_MAC_6 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_RGMII_TXCLK_DELAY_EN, field, reg); + if (field) + { + config->txclk_delay_cmd = A_TRUE; + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_RGMII_TXCLK_DELAY_SEL, field, reg); + config->txclk_delay_sel = field; + } + else + { + config->txclk_delay_cmd = A_FALSE; + config->txclk_delay_sel = 0; + } + + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_RGMII_RXCLK_DELAY_EN, field, reg); + if (field) + { + config->rxclk_delay_cmd = A_TRUE; + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_RGMII_RXCLK_DELAY_SEL, field, reg); + config->rxclk_delay_sel = field; + } + else + { + config->rxclk_delay_cmd = A_FALSE; + config->rxclk_delay_sel = 0; + } + + return SW_OK; +} + +static sw_error_t +_isis_port_gmii_mode_set(a_uint32_t dev_id, fal_port_t port_id, fal_mac_gmii_config_t * config) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + if (ISIS_MAC_0 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISIS_MAC_6 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_SGMII_EN, 0, reg); + + /* hardware suggestions: restore to defatult settings */ + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_TXCLK_DELAY_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_RXCLK_DELAY_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_TXCLK_DELAY_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_RXCLK_DELAY_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_RXCLK_SEL, 0, reg); + + if (FAL_INTERFACE_CLOCK_PHY_MODE == config->clock_mode) + { + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_TXCLK_SEL, config->txclk_select, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_RXCLK_SEL, config->rxclk_select, reg); + + } + else if (FAL_INTERFACE_CLOCK_MAC_MODE == config->clock_mode) + { + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_TXCLK_SEL, config->txclk_select, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_RXCLK_SEL, config->rxclk_select, reg); + + } + else + { + return SW_BAD_PARAM; + } + + if (ISIS_MAC_0 == port_id) + { + HSL_REG_ENTRY_SET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + HSL_REG_ENTRY_SET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + SW_RTN_ON_ERROR(rv); + + /* Port status register setting */ + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + /* setting port status default configuration */ + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, FLOW_LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, RX_FLOW_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TX_FLOW_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, DUPLEX_MODE, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, RXMAC_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TXMAC_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, SPEED_MODE, 2, reg); + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_gmii_mode_get(a_uint32_t dev_id, fal_port_t port_id, fal_mac_gmii_config_t * config) +{ + sw_error_t rv; + a_uint32_t reg = 0, field; + + if (ISIS_MAC_0 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISIS_MAC_6 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_PHY_GMII_EN, field, reg); + if (field) + { + config->clock_mode = FAL_INTERFACE_CLOCK_PHY_MODE; + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_PHY_GMII_TXCLK_SEL, field, reg); + config->txclk_select = field; + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_PHY_GMII_RXCLK_SEL, field, reg); + config->rxclk_select = field; + + } + else + { + config->clock_mode = FAL_INTERFACE_CLOCK_MAC_MODE; + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_MAC_GMII_TXCLK_SEL, field, reg); + config->txclk_select = field; + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_MAC_GMII_RXCLK_SEL, field, reg); + config->rxclk_select = field; + } + + return SW_OK; +} + +static sw_error_t +_isis_port_mii_mode_set(a_uint32_t dev_id, fal_port_t port_id, fal_mac_mii_config_t * config) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + if (ISIS_MAC_0 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISIS_MAC_5 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT5_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISIS_MAC_6 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_SGMII_EN, 0, reg); + + /* hardware suggestions: restore to defatult settings */ + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_TXCLK_DELAY_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_RXCLK_DELAY_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_TXCLK_DELAY_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_RXCLK_DELAY_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_RXCLK_SEL, 0, reg); + + if (FAL_INTERFACE_CLOCK_PHY_MODE == config->clock_mode) + { + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_TXCLK_SEL, config->txclk_select, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_RXCLK_SEL, config->rxclk_select, reg); + } + else if (FAL_INTERFACE_CLOCK_MAC_MODE == config->clock_mode) + { + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_TXCLK_SEL, config->txclk_select, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_RXCLK_SEL, config->rxclk_select, reg); + } + else + { + return SW_BAD_PARAM; + } + + if (ISIS_MAC_0 == port_id) + { + HSL_REG_ENTRY_SET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISIS_MAC_5 == port_id) + { + HSL_REG_ENTRY_SET(rv, dev_id, PORT5_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + HSL_REG_ENTRY_SET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + SW_RTN_ON_ERROR(rv); + + /* Port status register setting */ + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + /* setting port status default configuration */ + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, FLOW_LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, RX_FLOW_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TX_FLOW_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, DUPLEX_MODE, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, RXMAC_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TXMAC_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, SPEED_MODE, 1, reg); + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_mii_mode_get(a_uint32_t dev_id, fal_port_t port_id, fal_mac_mii_config_t * config) +{ + sw_error_t rv; + a_uint32_t reg = 0, field; + + if (ISIS_MAC_0 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISIS_MAC_5 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT5_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISIS_MAC_6 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_PHY_MII_EN, field, reg); + if (field) + { + config->clock_mode = FAL_INTERFACE_CLOCK_PHY_MODE; + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_PHY_MII_TXCLK_SEL, field, reg); + config->txclk_select = field; + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_PHY_MII_RXCLK_SEL, field, reg); + config->rxclk_select = field; + } + else + { + config->clock_mode = FAL_INTERFACE_CLOCK_MAC_MODE; + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_MAC_MII_TXCLK_SEL, field, reg); + config->txclk_select = field; + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_MAC_MII_RXCLK_SEL, field, reg); + config->rxclk_select = field; + } + + return SW_OK; +} + +static sw_error_t +_isis_port_sgmii_mode_set(a_uint32_t dev_id, fal_port_t port_id, fal_mac_sgmii_config_t * config) +{ + sw_error_t rv; + a_uint32_t reg = 0, field; + + if (ISIS_MAC_0 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISIS_MAC_6 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_SGMII_EN, 1, reg); + + /* hardware suggestions: restore to defatult settings */ + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_TXCLK_DELAY_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_RXCLK_DELAY_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_TXCLK_DELAY_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_RXCLK_DELAY_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_RXCLK_SEL, 0, reg); + + if (ISIS_MAC_0 == port_id) + { + HSL_REG_ENTRY_SET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* only support one SGMII interface, so we need to disable another SGMII */ + field = 0; + HSL_REG_FIELD_SET(rv, dev_id, PORT6_PAD_CTRL, port_id, MAC6_SGMII_EN, + (a_uint8_t *) (&field), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else + { + HSL_REG_ENTRY_SET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* only support one SGMII interface, so we need to disable another SGMII */ + field = 0; + HSL_REG_FIELD_SET(rv, dev_id, PORT0_PAD_CTRL, port_id, MAC0_SGMII_EN, + (a_uint8_t *) (&field), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + /* SGMII global settings, for all SGMII interfaces, now we fix all the values */ + /* TX/RX clock setting */ + HSL_REG_ENTRY_GET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, SGMII_CLK125M_RX_SEL, 1, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, SGMII_CLK125M_TX_SEL, 0, reg); + + HSL_REG_ENTRY_SET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* SGMII control register setting */ + HSL_REG_ENTRY_GET(rv, dev_id, SGMII_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(SGMII_CTRL, SGMII_FIBER_MODE, 0, reg); + SW_SET_REG_BY_FIELD(SGMII_CTRL, SGMII_EN_PLL, 0, reg); + SW_SET_REG_BY_FIELD(SGMII_CTRL, SGMII_EN_RX, 0, reg); + SW_SET_REG_BY_FIELD(SGMII_CTRL, SGMII_EN_TX, 0, reg); + SW_SET_REG_BY_FIELD(SGMII_CTRL, SGMII_EN_SD, 1, reg); + if (FAL_INTERFACE_CLOCK_PHY_MODE == config->clock_mode) + { + SW_SET_REG_BY_FIELD(SGMII_CTRL, MODE_CTRL_25M, 1, reg); + } + else + { + SW_SET_REG_BY_FIELD(SGMII_CTRL, MODE_CTRL_25M, 2, reg); + } + HSL_REG_ENTRY_SET(rv, dev_id, SGMII_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* Port status register setting */ + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + /* setting port status default configuration */ + SW_SET_REG_BY_FIELD(PORT_STATUS, FLOW_LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, RX_FLOW_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TX_FLOW_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, DUPLEX_MODE, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, RXMAC_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TXMAC_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, SPEED_MODE, 2, reg); + if (A_TRUE == config->auto_neg) + { + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 1, reg); + } + else + { + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 0, reg); + } + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_sgmii_mode_get(a_uint32_t dev_id, fal_port_t port_id, fal_mac_sgmii_config_t * config) +{ + sw_error_t rv; + a_uint32_t reg = 0, field; + + if (ISIS_MAC_0 == port_id) + { + /* nothing to do */ + } + else if (ISIS_MAC_6 == port_id) + { + /* nothing to do */ + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_STATUS, LINK_EN, field, reg); + if (field) + { + config->auto_neg = A_TRUE; + } + else + { + config->auto_neg = A_FALSE; + } + + HSL_REG_ENTRY_GET(rv, dev_id, SGMII_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + SW_GET_FIELD_BY_REG(SGMII_CTRL, MODE_CTRL_25M, field, reg); + if (1 == field) + { + config->clock_mode = FAL_INTERFACE_CLOCK_PHY_MODE; + } + else + { + config->clock_mode = FAL_INTERFACE_CLOCK_MAC_MODE; + } + + return SW_OK; +} + +static sw_error_t +_isis_port_fiber_mode_set(a_uint32_t dev_id, fal_port_t port_id, fal_mac_fiber_config_t * config) +{ + sw_error_t rv; + a_uint32_t reg = 0, field; + + if (ISIS_MAC_0 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISIS_MAC_6 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_SGMII_EN, 1, reg); + + /* hardware suggestions: restore to defatult settings */ + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_TXCLK_DELAY_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_RXCLK_DELAY_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_TXCLK_DELAY_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_RXCLK_DELAY_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_RXCLK_SEL, 0, reg); + + if (ISIS_MAC_0 == port_id) + { + HSL_REG_ENTRY_SET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* only support one SGMII interface, so we need to disable another SGMII */ + field = 0; + HSL_REG_FIELD_SET(rv, dev_id, PORT6_PAD_CTRL, port_id, MAC6_SGMII_EN, + (a_uint8_t *) (&field), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else + { + HSL_REG_ENTRY_SET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* only support one SGMII interface, so we need to disable another SGMII */ + field = 0; + HSL_REG_FIELD_SET(rv, dev_id, PORT0_PAD_CTRL, port_id, MAC0_SGMII_EN, + (a_uint8_t *) (&field), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + /* SGMII global settings, for all SGMII interfaces, now we fix all the values */ + /* TX/RX clock setting */ + HSL_REG_ENTRY_GET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, SGMII_CLK125M_RX_SEL, 1, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, SGMII_CLK125M_TX_SEL, 0, reg); + + HSL_REG_ENTRY_SET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* SGMII control register setting */ + HSL_REG_ENTRY_GET(rv, dev_id, SGMII_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(SGMII_CTRL, MODE_CTRL_25M, 0, reg); + SW_SET_REG_BY_FIELD(SGMII_CTRL, SGMII_FIBER_MODE, 3, reg); + SW_SET_REG_BY_FIELD(SGMII_CTRL, SGMII_EN_PLL, 0, reg); + SW_SET_REG_BY_FIELD(SGMII_CTRL, SGMII_EN_RX, 0, reg); + SW_SET_REG_BY_FIELD(SGMII_CTRL, SGMII_EN_TX, 0, reg); + SW_SET_REG_BY_FIELD(SGMII_CTRL, SGMII_EN_SD, 1, reg); + + HSL_REG_ENTRY_SET(rv, dev_id, SGMII_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* Power on strip register setting */ + HSL_REG_ENTRY_GET(rv, dev_id, POWER_STRIP, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + if (A_TRUE == config->auto_neg) + { + SW_SET_REG_BY_FIELD(POWER_STRIP, SERDES_AN_EN, 1, reg); + } + else + { + SW_SET_REG_BY_FIELD(POWER_STRIP, SERDES_AN_EN, 0, reg); + } + HSL_REG_ENTRY_SET(rv, dev_id, POWER_STRIP, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + /* Port status register setting */ + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + /* setting port status default configuration */ + SW_SET_REG_BY_FIELD(PORT_STATUS, FLOW_LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, RX_FLOW_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TX_FLOW_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, DUPLEX_MODE, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, RXMAC_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TXMAC_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, SPEED_MODE, 2, reg); + if (A_TRUE == config->auto_neg) + { + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 1, reg); + } + else + { + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 0, reg); + } + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_fiber_mode_get(a_uint32_t dev_id, fal_port_t port_id, fal_mac_fiber_config_t * config) +{ + sw_error_t rv; + a_uint32_t reg = 0, field; + + if (ISIS_MAC_0 == port_id) + { + /* nothing to do */ + } + else if (ISIS_MAC_6 == port_id) + { + /* nothing to do */ + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, POWER_STRIP, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(POWER_STRIP, SERDES_AN_EN, field, reg); + if (field) + { + config->auto_neg = A_TRUE; + } + else + { + config->auto_neg = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isis_port_default_mode_set(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + if (ISIS_MAC_0 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISIS_MAC_5 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT5_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISIS_MAC_6 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_SGMII_EN, 0, reg); + + /* hardware suggestions: restore to defatult settings */ + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_TXCLK_DELAY_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_RXCLK_DELAY_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_TXCLK_DELAY_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_RXCLK_DELAY_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_RXCLK_SEL, 0, reg); + + if (ISIS_MAC_0 == port_id) + { + HSL_REG_ENTRY_SET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISIS_MAC_5 == port_id) + { + HSL_REG_ENTRY_SET(rv, dev_id, PORT5_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + HSL_REG_ENTRY_SET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + + return rv; +} + +static sw_error_t +_isis_interface_mac_mode_set(a_uint32_t dev_id, fal_port_t port_id, fal_mac_config_t * config) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_MAC_MODE_RGMII == config->mac_mode) + { + rv = _isis_port_rgmii_mode_set(dev_id, port_id, &(config->config.rgmii)); + } + else if (FAL_MAC_MODE_GMII == config->mac_mode) + { + rv = _isis_port_gmii_mode_set(dev_id, port_id, &(config->config.gmii)); + } + else if (FAL_MAC_MODE_MII == config->mac_mode) + { + rv = _isis_port_mii_mode_set(dev_id, port_id, &(config->config.mii)); + } + else if (FAL_MAC_MODE_SGMII == config->mac_mode) + { + rv = _isis_port_sgmii_mode_set(dev_id, port_id, &(config->config.sgmii)); + } + else if (FAL_MAC_MODE_FIBER == config->mac_mode) + { + rv = _isis_port_fiber_mode_set(dev_id, port_id, &(config->config.fiber)); + } + else if (FAL_MAC_MODE_DEFAULT == config->mac_mode) + { + rv = _isis_port_default_mode_set(dev_id, port_id); + } + else + { + return SW_BAD_PARAM; + } + + return rv; +} + +static sw_error_t +_isis_interface_mac_mode_get(a_uint32_t dev_id, fal_port_t port_id, fal_mac_config_t * config) +{ + sw_error_t rv; + a_uint32_t reg = 0, field, field2; + + HSL_DEV_ID_CHECK(dev_id); + + if (ISIS_MAC_0 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISIS_MAC_5 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT5_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISIS_MAC_6 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + aos_mem_zero(config, sizeof(fal_interface_mac_mode_t)); + + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_RGMII_EN, field, reg); + if (field) + { + config->mac_mode = FAL_MAC_MODE_RGMII; + rv = _isis_port_rgmii_mode_get(dev_id, port_id, &(config->config.rgmii)); + return rv; + } + + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_MAC_GMII_EN, field, reg); + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_PHY_GMII_EN, field2, reg); + if (field || field2) + { + config->mac_mode = FAL_MAC_MODE_GMII; + rv = _isis_port_gmii_mode_get(dev_id, port_id, &(config->config.gmii)); + return rv; + } + + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_MAC_MII_EN, field, reg); + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_PHY_MII_EN, field2, reg); + if (field || field2) + { + config->mac_mode = FAL_MAC_MODE_MII; + rv = _isis_port_mii_mode_get(dev_id, port_id, &(config->config.mii)); + return rv; + } + + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_SGMII_EN, field, reg); + if (field) + { + HSL_REG_ENTRY_GET(rv, dev_id, SGMII_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(SGMII_CTRL, SGMII_FIBER_MODE, field, reg); + if (3 == field) + { + config->mac_mode = FAL_MAC_MODE_FIBER; + rv = _isis_port_fiber_mode_get(dev_id, port_id, &(config->config.fiber)); + } + else + { + config->mac_mode = FAL_MAC_MODE_SGMII; + rv = _isis_port_sgmii_mode_get(dev_id, port_id, &(config->config.sgmii)); + } + return rv; + } + + config->mac_mode = FAL_MAC_MODE_DEFAULT; + return SW_OK; +} + +static sw_error_t +_isis_interface_phy_mode_set(a_uint32_t dev_id, a_uint32_t phy_id, fal_phy_config_t * config) +{ + sw_error_t rv; + a_uint16_t data; + a_bool_t tx_delay_cmd, rx_delay_cmd; + hsl_phy_ops_t *phy_drv; + a_uint32_t reg, rgmii_mode, tx_delay = 2, port_id; + + HSL_DEV_ID_CHECK(dev_id); + + /* only PHY4 support mode setting */ + if (ISIS_PHY_MODE_PHY_ID != phy_id) + { + return SW_BAD_PARAM; + } + + port_id = qca_ssdk_phy_addr_to_port(dev_id, phy_id); + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get(dev_id, port_id)); + if ((NULL == phy_drv->phy_debug_write) || (NULL == phy_drv->phy_debug_read)) + return SW_NOT_SUPPORTED; + + HSL_REG_ENTRY_GET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_MAC_MODE_RGMII == config->mac_mode) + { + SW_SET_REG_BY_FIELD(PORT6_PAD_CTRL, PHY4_RGMII_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT6_PAD_CTRL, PHY4_GMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT6_PAD_CTRL, PHY4_MII_EN, 0, reg); + rgmii_mode = 1; + /* PHY TX delay */ + if (A_TRUE == config->txclk_delay_cmd) + { + tx_delay_cmd = A_TRUE; + tx_delay = config->txclk_delay_sel; + } + else + { + tx_delay_cmd = A_FALSE; + } + + /* PHY RX delay */ + if (A_TRUE == config->rxclk_delay_cmd) + { + rx_delay_cmd = A_TRUE; + } + else + { + rx_delay_cmd = A_FALSE; + } + } + else if (FAL_MAC_MODE_GMII == config->mac_mode) + { + SW_SET_REG_BY_FIELD(PORT6_PAD_CTRL, PHY4_RGMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT6_PAD_CTRL, PHY4_GMII_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT6_PAD_CTRL, PHY4_MII_EN, 0, reg); + rgmii_mode = 0; + tx_delay_cmd = A_FALSE; + rx_delay_cmd = A_FALSE; + } + else if (FAL_MAC_MODE_MII == config->mac_mode) + { + SW_SET_REG_BY_FIELD(PORT6_PAD_CTRL, PHY4_RGMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT6_PAD_CTRL, PHY4_GMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT6_PAD_CTRL, PHY4_MII_EN, 1, reg); + rgmii_mode = 0; + tx_delay_cmd = A_FALSE; + rx_delay_cmd = A_FALSE; + } + else if (FAL_MAC_MODE_DEFAULT == config->mac_mode) + { + SW_SET_REG_BY_FIELD(PORT6_PAD_CTRL, PHY4_RGMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT6_PAD_CTRL, PHY4_GMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT6_PAD_CTRL, PHY4_MII_EN, 0, reg); + + rgmii_mode = 0; + tx_delay_cmd = A_FALSE; + rx_delay_cmd = A_FALSE; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_SET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* PHY RGMII mode, debug register18 bit3 */ + data = phy_drv->phy_debug_read(dev_id, ISIS_PHY_MODE_PHY_ID, 18); + data &= 0xfff7UL; + data |= ((rgmii_mode & 0x1) << 3); + rv = phy_drv->phy_debug_write(dev_id, ISIS_PHY_MODE_PHY_ID, 18, data); + SW_RTN_ON_ERROR(rv); + + /* PHY TX delay command, debug regigster5 bit8 */ + data = phy_drv->phy_debug_read(dev_id, ISIS_PHY_MODE_PHY_ID, 5); + if (A_TRUE == tx_delay_cmd) + { + data |= 0x0100UL; + } + else + { + data &= 0xfeffUL; + } + rv = phy_drv->phy_debug_write(dev_id, ISIS_PHY_MODE_PHY_ID, 5, data); + SW_RTN_ON_ERROR(rv); + + /* PHY TX delay select, debug register11 bit-6 */ + data = phy_drv->phy_debug_read(dev_id, ISIS_PHY_MODE_PHY_ID, 11); + data &= 0xff9fUL; + data |= ((tx_delay & 0x3UL) << 5); + if (A_TRUE == tx_delay_cmd) + { + data |= 0x0100UL; + } + else + { + data &= 0xfeffUL; + } + rv = phy_drv->phy_debug_write(dev_id, ISIS_PHY_MODE_PHY_ID, 11, data); + SW_RTN_ON_ERROR(rv); + + /* PHY RX delay command, debug regigster0 bit15 */ + data = phy_drv->phy_debug_read(dev_id, ISIS_PHY_MODE_PHY_ID, 0); + if (A_TRUE == rx_delay_cmd) + { + data |= 0x8000UL; + } + else + { + data &= 0x7fffUL; + } + rv = phy_drv->phy_debug_write(dev_id, ISIS_PHY_MODE_PHY_ID, 0, data); + SW_RTN_ON_ERROR(rv); + + /* PHY RX delay select, now hardware not support */ + + return SW_OK; +} + +static sw_error_t +_isis_interface_phy_mode_get(a_uint32_t dev_id, a_uint32_t phy_id, fal_phy_config_t * config) +{ + sw_error_t rv; + a_uint16_t data; + a_uint32_t reg = 0, rgmii, gmii, mii, port_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + port_id = qca_ssdk_phy_addr_to_port(dev_id, phy_id); + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get(dev_id, port_id)); + if (NULL == phy_drv->phy_debug_read) + return SW_NOT_SUPPORTED; + + /* only one PHY device support this */ + if (ISIS_PHY_MODE_PHY_ID != phy_id) + { + return SW_BAD_PARAM; + } + + aos_mem_zero(config, sizeof(fal_phy_config_t)); + + HSL_REG_ENTRY_GET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT6_PAD_CTRL, PHY4_RGMII_EN, rgmii, reg); + SW_GET_FIELD_BY_REG(PORT6_PAD_CTRL, PHY4_GMII_EN, gmii, reg); + SW_GET_FIELD_BY_REG(PORT6_PAD_CTRL, PHY4_MII_EN, mii, reg); + + if ((rgmii) && (!gmii) && (!mii)) + { + config->mac_mode = FAL_MAC_MODE_RGMII; + data = phy_drv->phy_debug_read(dev_id, ISIS_PHY_MODE_PHY_ID, 5); + if (data & 0x0100) + { + config->txclk_delay_cmd = A_TRUE; + data = phy_drv->phy_debug_read(dev_id, ISIS_PHY_MODE_PHY_ID, 11); + config->txclk_delay_sel = (data >> 5) & 0x3UL; + } + else + { + config->txclk_delay_cmd = A_FALSE; + } + + data = phy_drv->phy_debug_read(dev_id, ISIS_PHY_MODE_PHY_ID, 0); + if (data & 0x8000) + { + config->rxclk_delay_cmd = A_TRUE; + } + else + { + config->rxclk_delay_cmd = A_FALSE; + } + } + else if ((!rgmii) && (gmii) && (!mii)) + { + config->mac_mode = FAL_MAC_MODE_GMII; + } + else if ((!rgmii) && (!gmii) && (mii)) + { + config->mac_mode = FAL_MAC_MODE_MII; + } + else + { + config->mac_mode = FAL_MAC_MODE_DEFAULT; + } + + return SW_OK; +} + +static sw_error_t +_isis_interface_mac_sgmii_set(a_uint32_t dev_id,a_uint32_t value) +{ + sw_error_t rv; + a_uint32_t reg; + + reg = value; + + HSL_REG_ENTRY_SET(rv, dev_id, SGMII_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_isis_interface_mac_sgmii_get(a_uint32_t dev_id, a_uint32_t *value) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + HSL_REG_ENTRY_GET(rv, dev_id, SGMII_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + *value = reg; + + return rv; +} + +static sw_error_t +_isis_interface_mac_pad_set(a_uint32_t dev_id,a_uint32_t port_num, a_uint32_t value) +{ + sw_error_t rv; + a_uint32_t reg; + + reg = value; + + switch (port_num) + { + case ISIS_MAC_0: + HSL_REG_ENTRY_SET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + break; + case ISIS_MAC_5: + HSL_REG_ENTRY_SET(rv, dev_id, PORT5_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + break; + case ISIS_MAC_6: + HSL_REG_ENTRY_SET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + break; + default: + return SW_BAD_PARAM; + } + + return rv; +} + +static sw_error_t +_isis_interface_mac_pad_get(a_uint32_t dev_id,a_uint32_t port_num, a_uint32_t *value) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + switch (port_num) + { + case ISIS_MAC_0: + HSL_REG_ENTRY_GET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + break; + case ISIS_MAC_5: + HSL_REG_ENTRY_GET(rv, dev_id, PORT5_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + break; + case ISIS_MAC_6: + HSL_REG_ENTRY_GET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + break; + default: + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + *value = reg; + + return rv; +} + + + +/** + * @brief Set 802.3az status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_3az_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_3az_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get 802.3az status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_3az_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_3az_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set interface mode on a particular MAC device. + * @param[in] dev_id device id + * @param[in] mca_id MAC device ID + * @param[in] config interface configuration + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_interface_mac_mode_set(a_uint32_t dev_id, fal_port_t port_id, fal_mac_config_t * config) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_interface_mac_mode_set(dev_id, port_id, config); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get interface mode on a particular MAC device. + * @param[in] dev_id device id + * @param[in] mca_id MAC device ID + * @param[out] config interface configuration + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_interface_mac_mode_get(a_uint32_t dev_id, fal_port_t port_id, fal_mac_config_t * config) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_interface_mac_mode_get(dev_id, port_id, config); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set interface phy mode on a particular PHY device. + * @param[in] dev_id device id + * @param[in] phy_id PHY device ID + * @param[in] config interface configuration + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_interface_phy_mode_set(a_uint32_t dev_id, a_uint32_t phy_id, fal_phy_config_t * config) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_interface_phy_mode_set(dev_id, phy_id, config); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get interface phy mode on a particular PHY device. + * @param[in] dev_id device id + * @param[in] phy_id PHY device ID + * @param[out] config interface configuration + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_interface_phy_mode_get(a_uint32_t dev_id, a_uint32_t phy_id, fal_phy_config_t * config) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_interface_phy_mode_get(dev_id, phy_id, config); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mac pad configuration. + * @param[in] dev_id device id + * @param[in] port_num port num + * @param[out] config value + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_interface_mac_pad_get(a_uint32_t dev_id,a_uint32_t port_num, a_uint32_t* value) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_interface_mac_pad_get(dev_id, port_num, value); + HSL_API_UNLOCK; + return rv; +} + + +/** + * @brief Set mac pad configuration. + * @param[in] dev_id device id + * @param[in] port_num port num + * @param[in] config value + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_interface_mac_pad_set(a_uint32_t dev_id,a_uint32_t port_num, a_uint32_t value) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_interface_mac_pad_set(dev_id,port_num,value); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mac SGMII configuration. + * @param[in] dev_id device id + * @param[out] config value + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_interface_mac_sgmii_get(a_uint32_t dev_id, a_uint32_t* value) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_interface_mac_sgmii_get(dev_id, value); + HSL_API_UNLOCK; + return rv; +} + + +/** + * @brief Set mac SGMII configuration. + * @param[in] dev_id device id + * @param[in] config value + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_interface_mac_sgmii_set(a_uint32_t dev_id, a_uint32_t value) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_interface_mac_sgmii_set(dev_id, value); + HSL_API_UNLOCK; + return rv; +} + + +sw_error_t +isis_interface_ctrl_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->port_3az_status_set = isis_port_3az_status_set; + p_api->port_3az_status_get = isis_port_3az_status_get; + p_api->interface_mac_mode_set = isis_interface_mac_mode_set; + p_api->interface_mac_mode_get = isis_interface_mac_mode_get; + p_api->interface_phy_mode_set = isis_interface_phy_mode_set; + p_api->interface_phy_mode_get = isis_interface_phy_mode_get; + p_api->interface_mac_pad_get = isis_interface_mac_pad_get; + p_api->interface_mac_pad_set = isis_interface_mac_pad_set; + p_api->interface_mac_sgmii_get = isis_interface_mac_sgmii_get; + p_api->interface_mac_sgmii_set = isis_interface_mac_sgmii_set; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_ip.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_ip.c new file mode 100755 index 000000000..f216add4f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_ip.c @@ -0,0 +1,2516 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup isis_ip ISIS_IP + * @{ + */ + +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isis_ip.h" +#include "isis_reg.h" + +#define ISIS_HOST_ENTRY_DATA0_ADDR 0x0e48 +#define ISIS_HOST_ENTRY_DATA1_ADDR 0x0e4c +#define ISIS_HOST_ENTRY_DATA2_ADDR 0x0e50 +#define ISIS_HOST_ENTRY_DATA3_ADDR 0x0e54 +#define ISIS_HOST_ENTRY_DATA4_ADDR 0x0e58 + +#define ISIS_HOST_ENTRY_FLUSH 1 +#define ISIS_HOST_ENTRY_ADD 2 +#define ISIS_HOST_ENTRY_DEL 3 +#define ISIS_HOST_ENTRY_NEXT 4 +#define ISIS_HOST_ENTRY_SEARCH 5 + +#define ISIS_ENTRY_ARP 3 + +#define ISIS_INTF_MAC_ADDR_NUM 8 +#define ISIS_INTF_MAC_TBL0_ADDR 0x5a900 +#define ISIS_INTF_MAC_TBL1_ADDR 0x5a904 +#define ISIS_INTF_MAC_TBL2_ADDR 0x5a908 +#define ISIS_INTF_MAC_EDIT0_ADDR 0x02000 +#define ISIS_INTF_MAC_EDIT1_ADDR 0x02004 +#define ISIS_INTF_MAC_EDIT2_ADDR 0x02008 + +#define ISIS_IP6_BASE_ADDR 0x0470 + +#define ISIS_HOST_ENTRY_NUM 128 + +#define ISIS_IP_COUTER_ADDR 0x2b000 + +static a_uint32_t isis_mac_snap[SW_MAX_NR_DEV] = { 0 }; +static fal_intf_mac_entry_t isis_intf_snap[SW_MAX_NR_DEV][ISIS_INTF_MAC_ADDR_NUM]; + +static void +_isis_ip_pt_learn_save(a_uint32_t dev_id, a_uint32_t * status) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_PTCTRL2, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + if (SW_OK != rv) + { + return; + } + + *status = (data & 0x7f7f); + + data &= 0xffff8080; + HSL_REG_ENTRY_SET(rv, dev_id, ROUTER_PTCTRL2, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return; +} + +static void +_isis_ip_pt_learn_restore(a_uint32_t dev_id, a_uint32_t status) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_PTCTRL2, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + if (SW_OK != rv) + { + return; + } + + data &= 0xffff8080; + data |= (status & 0x7f7f); + + HSL_REG_ENTRY_SET(rv, dev_id, ROUTER_PTCTRL2, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return; +} + +static sw_error_t +_isis_ip_feature_check(a_uint32_t dev_id) +{ + sw_error_t rv; + a_uint32_t entry = 0; + + HSL_REG_FIELD_GET(rv, dev_id, MASK_CTL, 0, DEVICE_ID, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (S17_DEVICE_ID == entry) + { + return SW_OK; + } + else + { + return SW_NOT_SUPPORTED; + } +} + +static sw_error_t +_isis_ip_counter_get(a_uint32_t dev_id, a_uint32_t cnt_id, + a_uint32_t counter[2]) +{ + sw_error_t rv; + a_uint32_t i, addr; + + addr = ISIS_IP_COUTER_ADDR + (cnt_id << 3); + for (i = 0; i < 2; i++) + { + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(counter[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + addr += 4; + } + + return SW_OK; +} + +static sw_error_t +_isis_host_entry_commit(a_uint32_t dev_id, a_uint32_t entry_type, a_uint32_t op) +{ + a_uint32_t busy = 1, i = 0x100, entry = 0, j, try_num; + a_uint32_t learn_status = 0; + sw_error_t rv; + + while (busy && --i) + { + HSL_REG_ENTRY_GET(rv, dev_id, HOST_ENTRY4, 0, (a_uint8_t *) (&entry), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + SW_GET_FIELD_BY_REG(HOST_ENTRY4, TBL_BUSY, busy, entry); + aos_udelay(500); + } + + if (i == 0) + { + printk("%s BUSY\n", __FUNCTION__); + return SW_BUSY; + } + + SW_SET_REG_BY_FIELD(HOST_ENTRY4, TBL_BUSY, 1, entry); + SW_SET_REG_BY_FIELD(HOST_ENTRY4, TBL_SEL, entry_type, entry); + SW_SET_REG_BY_FIELD(HOST_ENTRY4, ENTRY_FUNC, op, entry); + + HSL_REG_ENTRY_SET(rv, dev_id, HOST_ENTRY4, 0, (a_uint8_t *) (&entry), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* hardware requirements, we should disable ARP learn at first */ + /* and maybe we should try several times... */ + _isis_ip_pt_learn_save(dev_id, &learn_status); + if (learn_status) + { + try_num = 10; + } + else + { + try_num = 1; + } + + for (j = 0; j < try_num; j++) + { + busy = 1; + i = 0x100; + while (busy && --i) + { + HSL_REG_ENTRY_GET(rv, dev_id, HOST_ENTRY4, 0, (a_uint8_t *) (&entry), + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + _isis_ip_pt_learn_restore(dev_id, learn_status); + return rv; + } + SW_GET_FIELD_BY_REG(HOST_ENTRY4, TBL_BUSY, busy, entry); + aos_udelay(500); + } + + if (i == 0) + { + _isis_ip_pt_learn_restore(dev_id, learn_status); + printk("%s BUSY\n", __FUNCTION__); + return SW_BUSY; + } + + /* hardware requirement, we should read again... */ + HSL_REG_ENTRY_GET(rv, dev_id, HOST_ENTRY4, 0, (a_uint8_t *) (&entry), + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + _isis_ip_pt_learn_restore(dev_id, learn_status); + return rv; + } + + /* operation success...... */ + SW_GET_FIELD_BY_REG(HOST_ENTRY4, TBL_STAUS, busy, entry); + if (busy) + { + _isis_ip_pt_learn_restore(dev_id, learn_status); + return SW_OK; + } + } + + _isis_ip_pt_learn_restore(dev_id, learn_status); + if (ISIS_HOST_ENTRY_NEXT == op) + { + return SW_NO_MORE; + } + else if (ISIS_HOST_ENTRY_SEARCH == op) + { + return SW_NOT_FOUND; + } + else if (ISIS_HOST_ENTRY_DEL == op) + { + return SW_NOT_FOUND; + } + else + { + return SW_FAIL; + } +} + +static sw_error_t +_isis_ip_intf_sw_to_hw(a_uint32_t dev_id, fal_host_entry_t * entry, + a_uint32_t * hw_intf) +{ + sw_error_t rv; + a_uint32_t addr, lvid, hvid, tbl[3] = {0}, i; + a_uint32_t sw_intf = entry->intf_id; + a_uint32_t vid_offset; + + for (i = 0; i < ISIS_INTF_MAC_ADDR_NUM; i++) + { + if (isis_mac_snap[dev_id] & (0x1 << i)) + { + addr = ISIS_INTF_MAC_TBL0_ADDR + (i << 4) + 4; + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[1])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + addr = ISIS_INTF_MAC_TBL0_ADDR + (i << 4) + 8; + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[2])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY1, VID_HIGH0, hvid, tbl[1]); + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY2, VID_HIGH1, lvid, tbl[2]); + hvid |= ((lvid & 0xff) << 4); + + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY1, VID_LOW, lvid, tbl[1]); + + if ((lvid <= sw_intf) && (hvid >= sw_intf)) + { + vid_offset = entry->expect_vid ? (entry->expect_vid - lvid) : (sw_intf - lvid); + *hw_intf = (vid_offset << 3) | i; + return SW_OK; + } + } + } + + return SW_BAD_PARAM; +} + +static sw_error_t +_isis_ip_intf_hw_to_sw(a_uint32_t dev_id, a_uint32_t hw_intf, + a_uint32_t * sw_intf) +{ + sw_error_t rv; + a_uint32_t addr, lvid, tbl = 0, i; + + i = hw_intf & 0x7; + + addr = ISIS_INTF_MAC_TBL0_ADDR + (i << 4) + 4; + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&tbl), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY1, VID_LOW, lvid, tbl); + *sw_intf = lvid + (hw_intf >> 3); + + return SW_OK; +} + +static sw_error_t +_isis_ip_age_time_set(a_uint32_t dev_id, a_uint32_t * time) +{ + sw_error_t rv; + a_uint32_t data; + + if (255 < ((*time + 5) / 6)) + { + return SW_BAD_PARAM; + } + + data = ((*time + 5) / 6); + *time = data * 6; + + HSL_REG_FIELD_SET(rv, dev_id, ROUTER_CTRL, 0, ARP_AGE_TIME, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_ip_age_time_get(a_uint32_t dev_id, a_uint32_t * time) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_REG_FIELD_GET(rv, dev_id, ROUTER_CTRL, 0, ARP_AGE_TIME, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *time = data * 6; + return SW_OK; +} + +static sw_error_t +_isis_host_sw_to_hw(a_uint32_t dev_id, fal_host_entry_t * entry, + a_uint32_t reg[]) +{ + sw_error_t rv; + a_uint32_t data; + + if (FAL_IP_IP4_ADDR & entry->flags) + { + reg[0] = entry->ip4_addr; + } + + if (FAL_IP_IP6_ADDR & entry->flags) + { + return SW_NOT_SUPPORTED; + } + + SW_SET_REG_BY_FIELD(HOST_ENTRY1, MAC_ADDR2, entry->mac_addr.uc[2], reg[1]); + SW_SET_REG_BY_FIELD(HOST_ENTRY1, MAC_ADDR3, entry->mac_addr.uc[3], reg[1]); + SW_SET_REG_BY_FIELD(HOST_ENTRY1, MAC_ADDR4, entry->mac_addr.uc[4], reg[1]); + SW_SET_REG_BY_FIELD(HOST_ENTRY1, MAC_ADDR5, entry->mac_addr.uc[5], reg[1]); + SW_SET_REG_BY_FIELD(HOST_ENTRY2, MAC_ADDR0, entry->mac_addr.uc[0], reg[2]); + SW_SET_REG_BY_FIELD(HOST_ENTRY2, MAC_ADDR1, entry->mac_addr.uc[1], reg[2]); + + rv = _isis_ip_intf_sw_to_hw(dev_id, entry/*was:->intf_id*/, &data); + SW_RTN_ON_ERROR(rv); + SW_SET_REG_BY_FIELD(HOST_ENTRY2, INTF_ID, data, reg[2]); + + if (A_TRUE != hsl_port_prop_check(dev_id, entry->port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + SW_SET_REG_BY_FIELD(HOST_ENTRY2, SRC_PORT, entry->port_id, reg[2]); + + if (FAL_IP_CPU_ADDR & entry->flags) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY2, CPU_ADDR, 1, reg[2]); + } + + SW_SET_REG_BY_FIELD(HOST_ENTRY3, AGE_FLAG, entry->status, reg[3]); + + if ((A_TRUE == entry->mirror_en) && (FAL_MAC_FRWRD != entry->action)) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == entry->counter_en) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY3, CNT_EN, 1, reg[3]); + SW_SET_REG_BY_FIELD(HOST_ENTRY3, CNT_IDX, entry->counter_id, reg[3]); + } + + if (FAL_MAC_DROP == entry->action) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY2, SRC_PORT, 7, reg[2]); + SW_SET_REG_BY_FIELD(HOST_ENTRY3, ACTION, 3, reg[3]); + } + else if (FAL_MAC_RDT_TO_CPU == entry->action) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY3, ACTION, 1, reg[3]); + } + else if (FAL_MAC_CPY_TO_CPU == entry->action) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY3, ACTION, 2, reg[3]); + } + else + { + if (A_TRUE == entry->mirror_en) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY3, ACTION, 0, reg[3]); + } + else + { + SW_SET_REG_BY_FIELD(HOST_ENTRY3, ACTION, 3, reg[3]); + } + } + + return SW_OK; +} + +static sw_error_t +_isis_host_hw_to_sw(a_uint32_t dev_id, a_uint32_t reg[], + fal_host_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t data, cnt[2] = {0}; + + SW_GET_FIELD_BY_REG(HOST_ENTRY3, IP_VER, data, reg[3]); + if (data) + { + entry->ip6_addr.ul[0] = reg[0]; + entry->flags |= FAL_IP_IP6_ADDR; + } + else + { + entry->ip4_addr = reg[0]; + entry->flags |= FAL_IP_IP4_ADDR; + } + + SW_GET_FIELD_BY_REG(HOST_ENTRY1, MAC_ADDR2, entry->mac_addr.uc[2], reg[1]); + SW_GET_FIELD_BY_REG(HOST_ENTRY1, MAC_ADDR3, entry->mac_addr.uc[3], reg[1]); + SW_GET_FIELD_BY_REG(HOST_ENTRY1, MAC_ADDR4, entry->mac_addr.uc[4], reg[1]); + SW_GET_FIELD_BY_REG(HOST_ENTRY1, MAC_ADDR5, entry->mac_addr.uc[5], reg[1]); + SW_GET_FIELD_BY_REG(HOST_ENTRY2, MAC_ADDR0, entry->mac_addr.uc[0], reg[2]); + SW_GET_FIELD_BY_REG(HOST_ENTRY2, MAC_ADDR1, entry->mac_addr.uc[1], reg[2]); + + SW_GET_FIELD_BY_REG(HOST_ENTRY2, INTF_ID, data, reg[2]); + rv = _isis_ip_intf_hw_to_sw(dev_id, data, &(entry->intf_id)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(HOST_ENTRY2, SRC_PORT, entry->port_id, reg[2]); + + SW_GET_FIELD_BY_REG(HOST_ENTRY2, CPU_ADDR, data, reg[2]); + if (data) + { + entry->flags |= FAL_IP_CPU_ADDR; + } + + SW_GET_FIELD_BY_REG(HOST_ENTRY3, AGE_FLAG, entry->status, reg[3]); + + SW_GET_FIELD_BY_REG(HOST_ENTRY3, CNT_EN, data, reg[3]); + if (data) + { + entry->counter_en = A_TRUE; + SW_GET_FIELD_BY_REG(HOST_ENTRY3, CNT_IDX, entry->counter_id, reg[3]); + + rv = _isis_ip_counter_get(dev_id, entry->counter_id, cnt); + SW_RTN_ON_ERROR(rv); + + entry->packet = cnt[0]; + entry->byte = cnt[1]; + } + else + { + entry->counter_en = A_FALSE; + } + + SW_GET_FIELD_BY_REG(HOST_ENTRY3, PPPOE_EN, data, reg[3]); + if (data) + { + entry->pppoe_en = A_TRUE; + SW_GET_FIELD_BY_REG(HOST_ENTRY3, PPPOE_IDX, data, reg[3]); + entry->pppoe_id = data; + } + else + { + entry->pppoe_en = A_FALSE; + } + + if (7 == entry->port_id) + { + entry->port_id = 0; + entry->action = FAL_MAC_DROP; + } + else + { + SW_GET_FIELD_BY_REG(HOST_ENTRY3, ACTION, data, reg[3]); + entry->action = FAL_MAC_FRWRD; + if (0 == data) + { + entry->mirror_en = A_TRUE; + } + else if (1 == data) + { + entry->action = FAL_MAC_RDT_TO_CPU; + } + else if (2 == data) + { + entry->action = FAL_MAC_CPY_TO_CPU; + } + } + + return SW_OK; +} + +static sw_error_t +_isis_host_down_to_hw(a_uint32_t dev_id, a_uint32_t reg[]) +{ + sw_error_t rv; + a_uint32_t i, addr; + + for (i = 0; i < 5; i++) + { + addr = ISIS_HOST_ENTRY_DATA0_ADDR + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®[i]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +static sw_error_t +_isis_host_up_to_sw(a_uint32_t dev_id, a_uint32_t reg[]) +{ + sw_error_t rv; + a_uint32_t i, addr; + + for (i = 0; i < 5; i++) + { + addr = ISIS_HOST_ENTRY_DATA0_ADDR + (i << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®[i]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +static sw_error_t +_isis_ip_host_add(a_uint32_t dev_id, fal_host_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t reg[5] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + rv = _isis_host_sw_to_hw(dev_id, entry, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_host_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_host_entry_commit(dev_id, ISIS_ENTRY_ARP, ISIS_HOST_ENTRY_ADD); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, HOST_ENTRY4, 0, (a_uint8_t *) (®[4]), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(HOST_ENTRY4, TBL_IDX, entry->entry_id, reg[4]); + return SW_OK; +} + +static sw_error_t +_isis_ip_host_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_host_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t data, reg[5] = { 0 }, op = ISIS_HOST_ENTRY_FLUSH; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_IP_ENTRY_ID_EN & del_mode) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_IP_ENTRY_IPADDR_EN & del_mode) + { + op = ISIS_HOST_ENTRY_DEL; + if (FAL_IP_IP4_ADDR & entry->flags) + { + reg[0] = entry->ip4_addr; + } + + if (FAL_IP_IP6_ADDR & entry->flags) + { + return SW_NOT_SUPPORTED; + } + } + + if (FAL_IP_ENTRY_INTF_EN & del_mode) + { + rv = _isis_ip_intf_sw_to_hw(dev_id, entry/*was:->intf_id*/, &data); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(HOST_ENTRY4, SPEC_VID, 1, reg[4]); + SW_SET_REG_BY_FIELD(HOST_ENTRY2, INTF_ID, data, reg[2]); + } + + if (FAL_IP_ENTRY_PORT_EN & del_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY4, SPEC_SP, 1, reg[4]); + SW_SET_REG_BY_FIELD(HOST_ENTRY2, SRC_PORT, entry->port_id, reg[2]); + } + + if (FAL_IP_ENTRY_STATUS_EN & del_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY4, SPEC_STATUS, 1, reg[4]); + SW_SET_REG_BY_FIELD(HOST_ENTRY3, AGE_FLAG, entry->status, reg[3]); + } + + rv = _isis_host_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_host_entry_commit(dev_id, ISIS_ENTRY_ARP, op); + return rv; +} + +static sw_error_t +_isis_ip_host_get(a_uint32_t dev_id, a_uint32_t get_mode, + fal_host_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t reg[5] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_IP_ENTRY_IPADDR_EN != get_mode) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_IP_IP4_ADDR & entry->flags) + { + reg[0] = entry->ip4_addr; + } + else if (FAL_IP_IP6_ADDR & entry->flags) + { + return SW_NOT_SUPPORTED; + } + + rv = _isis_host_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_host_entry_commit(dev_id, ISIS_ENTRY_ARP, + ISIS_HOST_ENTRY_SEARCH); + SW_RTN_ON_ERROR(rv); + + rv = _isis_host_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + aos_mem_zero(entry, sizeof (fal_host_entry_t)); + + rv = _isis_host_hw_to_sw(dev_id, reg, entry); + SW_RTN_ON_ERROR(rv); + + if (!(entry->status)) + { + return SW_NOT_FOUND; + } + + HSL_REG_ENTRY_GET(rv, dev_id, HOST_ENTRY4, 0, (a_uint8_t *) (®[4]), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(HOST_ENTRY4, TBL_IDX, entry->entry_id, reg[4]); + return SW_OK; +} + +static sw_error_t +_isis_ip_host_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_host_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t idx, data, reg[5] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_NEXT_ENTRY_FIRST_ID == entry->entry_id) + { + idx = ISIS_HOST_ENTRY_NUM - 1; + } + else + { + if ((ISIS_HOST_ENTRY_NUM - 1) == entry->entry_id) + { + return SW_NO_MORE; + } + else + { + idx = entry->entry_id; + } + } + + SW_SET_REG_BY_FIELD(HOST_ENTRY4, TBL_IDX, idx, reg[4]); + + if (FAL_IP_ENTRY_INTF_EN & next_mode) + { + rv = _isis_ip_intf_sw_to_hw(dev_id, entry/*was:->intf_id*/, &data); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(HOST_ENTRY4, SPEC_VID, 1, reg[4]); + SW_SET_REG_BY_FIELD(HOST_ENTRY2, INTF_ID, data, reg[2]); + } + + if (FAL_IP_ENTRY_PORT_EN & next_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY4, SPEC_SP, 1, reg[4]); + SW_SET_REG_BY_FIELD(HOST_ENTRY2, SRC_PORT, entry->port_id, reg[2]); + } + + if (FAL_IP_ENTRY_STATUS_EN & next_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY4, SPEC_STATUS, 1, reg[4]); + SW_SET_REG_BY_FIELD(HOST_ENTRY3, AGE_FLAG, entry->status, reg[3]); + } + + rv = _isis_host_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_host_entry_commit(dev_id, ISIS_ENTRY_ARP, ISIS_HOST_ENTRY_NEXT); + SW_RTN_ON_ERROR(rv); + + rv = _isis_host_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + aos_mem_zero(entry, sizeof (fal_host_entry_t)); + + rv = _isis_host_hw_to_sw(dev_id, reg, entry); + SW_RTN_ON_ERROR(rv); + + if (!(entry->status)) + { + return SW_NO_MORE; + } + + SW_GET_FIELD_BY_REG(HOST_ENTRY4, TBL_IDX, entry->entry_id, reg[4]); + return SW_OK; +} + +static sw_error_t +_isis_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; + a_uint32_t reg[5] = { 0 }, tbl[5] = { 0 }, tbl_idx; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + tbl_idx = (entry_id - 1) & 0x7f; + SW_SET_REG_BY_FIELD(HOST_ENTRY4, TBL_IDX, tbl_idx, reg[4]); + + rv = _isis_host_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_host_entry_commit(dev_id, ISIS_ENTRY_ARP, ISIS_HOST_ENTRY_NEXT); + if (SW_OK != rv) + { + return SW_NOT_FOUND; + } + + rv = _isis_host_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(HOST_ENTRY4, TBL_IDX, tbl_idx, reg[4]); + if (entry_id != tbl_idx) + { + return SW_NOT_FOUND; + } + + tbl[0] = reg[0]; + tbl[3] = (reg[3] >> 15) << 15; + rv = _isis_host_down_to_hw(dev_id, tbl); + SW_RTN_ON_ERROR(rv); + + rv = _isis_host_entry_commit(dev_id, ISIS_ENTRY_ARP, ISIS_HOST_ENTRY_DEL); + SW_RTN_ON_ERROR(rv); + + if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY3, CNT_EN, 0, reg[3]); + } + else if (A_TRUE == enable) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY3, CNT_EN, 1, reg[3]); + SW_SET_REG_BY_FIELD(HOST_ENTRY3, CNT_IDX, cnt_id, reg[3]); + } + else + { + return SW_BAD_PARAM; + } + + reg[4] = 0x0; + rv = _isis_host_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_host_entry_commit(dev_id, ISIS_ENTRY_ARP, ISIS_HOST_ENTRY_ADD); + return rv; +} + +static sw_error_t +_isis_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; + a_uint32_t reg[5] = { 0 }, tbl[5] = { 0 }, tbl_idx; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + tbl_idx = (entry_id - 1) & 0x7f; + SW_SET_REG_BY_FIELD(HOST_ENTRY4, TBL_IDX, tbl_idx, reg[4]); + + rv = _isis_host_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_host_entry_commit(dev_id, ISIS_ENTRY_ARP, ISIS_HOST_ENTRY_NEXT); + SW_RTN_ON_ERROR(rv); + + rv = _isis_host_up_to_sw(dev_id, reg); + if (SW_OK != rv) + { + return SW_NOT_FOUND; + } + + SW_GET_FIELD_BY_REG(HOST_ENTRY4, TBL_IDX, tbl_idx, reg[4]); + if (entry_id != tbl_idx) + { + return SW_NOT_FOUND; + } + + if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY3, PPPOE_EN, 0, reg[3]); + } + else if (A_TRUE == enable) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY3, PPPOE_EN, 1, reg[3]); + SW_SET_REG_BY_FIELD(HOST_ENTRY3, PPPOE_IDX, pppoe_id, reg[3]); + } + else + { + return SW_BAD_PARAM; + } + + tbl[0] = reg[0]; + tbl[3] = (reg[3] >> 15) << 15; + rv = _isis_host_down_to_hw(dev_id, tbl); + SW_RTN_ON_ERROR(rv); + + rv = _isis_host_entry_commit(dev_id, ISIS_ENTRY_ARP, ISIS_HOST_ENTRY_DEL); + SW_RTN_ON_ERROR(rv); + + reg[4] = 0x0; + rv = _isis_host_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_host_entry_commit(dev_id, ISIS_ENTRY_ARP, ISIS_HOST_ENTRY_ADD); + SW_RTN_ON_ERROR(rv); + + rv = _isis_host_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +static sw_error_t +_isis_ip_pt_arp_learn_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t flags) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_PTCTRL2, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_ARP_LEARN_REQ & flags) + { + data |= (0x1 << port_id); + } + else + { + data &= (~(0x1 << port_id)); + } + + if (FAL_ARP_LEARN_ACK & flags) + { + data |= (0x1 << (ROUTER_PTCTRL2_ARP_LEARN_ACK_BOFFSET + port_id)); + } + else + { + data &= (~(0x1 << (ROUTER_PTCTRL2_ARP_LEARN_ACK_BOFFSET + port_id))); + } + + HSL_REG_ENTRY_SET(rv, dev_id, ROUTER_PTCTRL2, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_ip_pt_arp_learn_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * flags) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + *flags = 0; + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_PTCTRL2, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data & (0x1 << port_id)) + { + *flags |= FAL_ARP_LEARN_REQ; + } + + if (data & (0x1 << (ROUTER_PTCTRL2_ARP_LEARN_ACK_BOFFSET + port_id))) + { + *flags |= FAL_ARP_LEARN_ACK; + } + + return SW_OK; +} + +static sw_error_t +_isis_ip_arp_learn_set(a_uint32_t dev_id, fal_arp_learn_mode_t mode) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_ARP_LEARN_ALL == mode) + { + data = 1; + } + else if (FAL_ARP_LEARN_LOCAL == mode) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, ROUTER_CTRL, 0, ARP_LEARN_MODE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_ip_arp_learn_get(a_uint32_t dev_id, fal_arp_learn_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, ROUTER_CTRL, 0, ARP_LEARN_MODE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data) + { + *mode = FAL_ARP_LEARN_ALL; + } + else + { + *mode = FAL_ARP_LEARN_LOCAL; + } + + return SW_OK; +} + +static sw_error_t +_isis_ip_source_guard_set(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t mode) +{ + sw_error_t rv; + a_uint32_t reg = 0, data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_PTCTRL1, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_NO_SOURCE_GUARD < mode) + { + return SW_BAD_PARAM; + } + + data = 0; + if (FAL_MAC_IP_GUARD == mode) + { + data = 1; + } + else if (FAL_MAC_IP_PORT_GUARD == mode) + { + data = 2; + } + else if (FAL_MAC_IP_VLAN_GUARD == mode) + { + data = 3; + } + else if (FAL_MAC_IP_PORT_VLAN_GUARD == mode) + { + data = 4; + } + reg &= (~(0x7 << (port_id * 3))); + reg |= ((data & 0x7) << (port_id * 3)); + + HSL_REG_ENTRY_SET(rv, dev_id, ROUTER_PTCTRL1, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data = 1; + if (FAL_NO_SOURCE_GUARD == mode) + { + data = 0; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN1, port_id, SP_CHECK_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_ip_source_guard_get(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t reg = 0, data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_PTCTRL1, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data = (reg >> (port_id * 3)) & 0x7; + + *mode = FAL_NO_SOURCE_GUARD; + if (1 == data) + { + *mode = FAL_MAC_IP_GUARD; + } + else if (2 == data) + { + *mode = FAL_MAC_IP_PORT_GUARD; + } + else if (3 == data) + { + *mode = FAL_MAC_IP_VLAN_GUARD; + } + else if (4 == data) + { + *mode = FAL_MAC_IP_PORT_VLAN_GUARD; + } + + return SW_OK; +} + +static sw_error_t +_isis_ip_unk_source_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_MAC_FRWRD == cmd) + { + data = 0; + } + else if (FAL_MAC_DROP == cmd) + { + data = 1; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + data = 2; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, IP_NOT_FOUND, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_ip_unk_source_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, IP_NOT_FOUND, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0 == data) + { + *cmd = FAL_MAC_FRWRD; + } + else if (1 == data) + { + *cmd = FAL_MAC_DROP; + } + else + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + + return SW_OK; +} + +static sw_error_t +_isis_ip_arp_guard_set(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t mode) +{ + sw_error_t rv; + a_uint32_t reg = 0, data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_PTCTRL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_NO_SOURCE_GUARD < mode) + { + return SW_BAD_PARAM; + } + + data = 0; + if (FAL_MAC_IP_GUARD == mode) + { + data = 1; + } + else if (FAL_MAC_IP_PORT_GUARD == mode) + { + data = 2; + } + else if (FAL_MAC_IP_VLAN_GUARD == mode) + { + data = 3; + } + else if (FAL_MAC_IP_PORT_VLAN_GUARD == mode) + { + data = 4; + } + reg &= (~(0x7 << (port_id * 3))); + reg |= ((data & 0x7) << (port_id * 3)); + + HSL_REG_ENTRY_SET(rv, dev_id, ROUTER_PTCTRL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_ip_arp_guard_get(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t reg = 0, data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_PTCTRL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data = (reg >> (port_id * 3)) & 0x7; + + *mode = FAL_NO_SOURCE_GUARD; + if (1 == data) + { + *mode = FAL_MAC_IP_GUARD; + } + else if (2 == data) + { + *mode = FAL_MAC_IP_PORT_GUARD; + } + else if (3 == data) + { + *mode = FAL_MAC_IP_VLAN_GUARD; + } + else if (4 == data) + { + *mode = FAL_MAC_IP_PORT_VLAN_GUARD; + } + + return SW_OK; +} + +static sw_error_t +_isis_arp_unk_source_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_MAC_FRWRD == cmd) + { + data = 0; + } + else if (FAL_MAC_DROP == cmd) + { + data = 1; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + data = 2; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, ARP_NOT_FOUND, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_arp_unk_source_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, ARP_NOT_FOUND, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0 == data) + { + *cmd = FAL_MAC_FRWRD; + } + else if (1 == data) + { + *cmd = FAL_MAC_DROP; + } + else + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + + return SW_OK; +} + +static sw_error_t +_isis_ip_route_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, ROUTER_CTRL, 0, ROUTER_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, MOD_ENABLE, 0, L3_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_ip_route_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t route_en = 0, l3_en = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, ROUTER_CTRL, 0, ROUTER_EN, + (a_uint8_t *) (&route_en), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, MOD_ENABLE, 0, L3_EN, + (a_uint8_t *) (&l3_en), sizeof (a_uint32_t)) + SW_RTN_ON_ERROR(rv); + + if (route_en && l3_en) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return rv; +} + +static sw_error_t +_isis_ip_intf_entry_add(a_uint32_t dev_id, fal_intf_mac_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t i, j, found = 0, addr, tbl[3] = { 0 }; + fal_intf_mac_entry_t * intf_entry; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + for (i = 0; i < ISIS_INTF_MAC_ADDR_NUM; i++) + { + if (isis_mac_snap[dev_id] & (0x1 << i)) + { + intf_entry = &(isis_intf_snap[dev_id][i]); + if ((entry->vid_low == intf_entry->vid_low) + && (entry->vid_high == intf_entry->vid_high) + &&(!memcmp(&entry->mac_addr, &intf_entry->mac_addr, 6))) + { + /* all same, return OK directly */ + if (!aos_mem_cmp(intf_entry, entry, sizeof(fal_intf_mac_entry_t))) + { + return SW_OK; + } + else + { + /* update entry */ + found = 1; + break; + } + } + else + { +#if 0 /* Different mac should be ok for VID range? */ + /* entry VID cross border, not support */ + if ((entry->vid_low >= intf_entry->vid_low) && (entry->vid_low <= intf_entry->vid_high)) + { + return SW_BAD_PARAM; + } + + /* entry VID cross border, not support */ + if ((entry->vid_high >= intf_entry->vid_low) && (entry->vid_low <= intf_entry->vid_high)) + { + return SW_BAD_PARAM; + } +#endif + } + } + } + + if (!found) + { + for (i = 0; i < ISIS_INTF_MAC_ADDR_NUM; i++) + { + if (!(isis_mac_snap[dev_id] & (0x1 << i))) + { + intf_entry = &(isis_intf_snap[dev_id][i]); + break; + } + } + } + + if (ISIS_INTF_MAC_ADDR_NUM == i) + { + return SW_NO_RESOURCE; + } + + if ((A_FALSE == entry->ip4_route) && (A_FALSE == entry->ip6_route)) + { + return SW_NOT_SUPPORTED; + } + + if (512 <= (entry->vid_high - entry->vid_low)) + { + return SW_BAD_PARAM; + } + + SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY0, MAC_ADDR2, entry->mac_addr.uc[2], + tbl[0]); + SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY0, MAC_ADDR3, entry->mac_addr.uc[3], + tbl[0]); + SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY0, MAC_ADDR4, entry->mac_addr.uc[4], + tbl[0]); + SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY0, MAC_ADDR5, entry->mac_addr.uc[5], + tbl[0]); + SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY1, MAC_ADDR0, entry->mac_addr.uc[0], + tbl[1]); + SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY1, MAC_ADDR1, entry->mac_addr.uc[1], + tbl[1]); + + SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY1, VID_LOW, entry->vid_low, tbl[1]); + SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY1, VID_HIGH0, (entry->vid_high & 0xf), + tbl[1]); + SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY2, VID_HIGH1, (entry->vid_high >> 4), + tbl[2]); + + if (A_TRUE == entry->ip4_route) + { + SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY2, IP4_ROUTE, 1, tbl[2]); + } + + if (A_TRUE == entry->ip6_route) + { + SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY2, IP6_ROUTE, 1, tbl[2]); + } + + for (j = 0; j < 2; j++) + { + addr = ISIS_INTF_MAC_EDIT0_ADDR + (i << 4) + (j << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[j])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + for (j = 0; j < 3; j++) + { + addr = ISIS_INTF_MAC_TBL0_ADDR + (i << 4) + (j << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[j])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + isis_mac_snap[dev_id] |= (0x1 << i); + *intf_entry = *entry; + entry->entry_id = i; + return SW_OK; +} + +static sw_error_t +_isis_ip_intf_entry_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_intf_mac_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t addr, tbl[3] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (!(FAL_IP_ENTRY_ID_EN & del_mode)) + { + return SW_NOT_SUPPORTED; + } + + if (ISIS_INTF_MAC_ADDR_NUM <= entry->entry_id) + { + return SW_BAD_PARAM; + } + + /* clear valid bits */ + addr = ISIS_INTF_MAC_TBL2_ADDR + (entry->entry_id << 4); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[2])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + isis_mac_snap[dev_id] &= (~(0x1 << entry->entry_id)); + return SW_OK; +} + +static sw_error_t +_isis_ip_intf_entry_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_intf_mac_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t i, j, idx, addr, tbl[3] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_NEXT_ENTRY_FIRST_ID == entry->entry_id) + { + idx = 0; + } + else + { + if ((ISIS_INTF_MAC_ADDR_NUM - 1) == entry->entry_id) + { + return SW_NO_MORE; + } + else + { + idx = entry->entry_id + 1; + } + } + + for (i = idx; i < ISIS_INTF_MAC_ADDR_NUM; i++) + { + if (isis_mac_snap[dev_id] & (0x1 << i)) + { + break; + } + } + + if (ISIS_INTF_MAC_ADDR_NUM == i) + { + return SW_NO_MORE; + } + + for (j = 0; j < 3; j++) + { + addr = ISIS_INTF_MAC_TBL0_ADDR + (i << 4) + (j << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[j])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + aos_mem_zero(entry, sizeof (fal_intf_mac_entry_t)); + + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY0, MAC_ADDR2, entry->mac_addr.uc[2], + tbl[0]); + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY0, MAC_ADDR3, entry->mac_addr.uc[3], + tbl[0]); + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY0, MAC_ADDR4, entry->mac_addr.uc[4], + tbl[0]); + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY0, MAC_ADDR5, entry->mac_addr.uc[5], + tbl[0]); + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY1, MAC_ADDR0, entry->mac_addr.uc[0], + tbl[1]); + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY1, MAC_ADDR1, entry->mac_addr.uc[1], + tbl[1]); + + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY1, VID_LOW, entry->vid_low, tbl[1]); + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY1, VID_HIGH0, j, tbl[1]); + entry->vid_high = j & 0xf; + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY2, VID_HIGH1, j, tbl[2]); + entry->vid_high |= ((j & 0xff) << 4); + + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY2, IP4_ROUTE, j, tbl[2]); + if (j) + { + entry->ip4_route = A_TRUE; + } + + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY2, IP6_ROUTE, j, tbl[2]); + if (j) + { + entry->ip6_route = A_TRUE; + } + + entry->entry_id = i; + return SW_OK; +} + +#define ISIS_WCMP_ENTRY_MAX_ID 3 +#define ISIS_WCMP_HASH_MAX_NUM 16 +#define ISIS_IP_ENTRY_MAX_ID 127 + +#define ISIS_WCMP_HASH_TBL_ADDR 0x0e10 +#define ISIS_WCMP_NHOP_TBL_ADDR 0x0e20 + +#if 0 +static sw_error_t +_isis_ip_wcmp_entry_set(a_uint32_t dev_id, a_uint32_t wcmp_id, fal_ip_wcmp_t * wcmp) +{ + sw_error_t rv; + a_uint32_t i, j, addr, data; + a_uint8_t idx, ptr[4] = { 0 }, pos[16] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (ISIS_WCMP_ENTRY_MAX_ID < wcmp_id) + { + return SW_BAD_PARAM; + } + + if (ISIS_WCMP_HASH_MAX_NUM < wcmp->nh_nr) + { + return SW_BAD_PARAM; + } + + for (i = 0; i < wcmp->nh_nr; i++) + { + if (ISIS_IP_ENTRY_MAX_ID < wcmp->nh_id[i]) + { + return SW_BAD_PARAM; + } + + idx = 4; + for (j = 0; j < 4; j++) + { + if (ptr[j] & 0x80) + { + if ((ptr[j] & 0x7f) == wcmp->nh_id[i]) + { + idx = j; + break; + } + } + else + { + idx = j; + } + } + + if (4 == idx) + { + return SW_BAD_PARAM; + } + else + { + ptr[idx] = (wcmp->nh_id[i] & 0x7f) | 0x80; + pos[i] = idx; + } + } + + data = 0; + for (j = 0; j < 4; j++) + { + data |= (ptr[j] << (j << 3)); + } + + addr = ISIS_WCMP_NHOP_TBL_ADDR + (wcmp_id << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data = 0; + for (j = 0; j < 16; j++) + { + data |= (pos[j] << (j << 1)); + } + + addr = ISIS_WCMP_HASH_TBL_ADDR + (wcmp_id << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +static sw_error_t +_isis_ip_wcmp_entry_get(a_uint32_t dev_id, a_uint32_t wcmp_id, fal_ip_wcmp_t * wcmp) +{ + sw_error_t rv; + a_uint32_t i, addr, data= 0; + a_uint8_t ptr[4] = { 0 }, pos[16] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (ISIS_WCMP_ENTRY_MAX_ID < wcmp_id) + { + return SW_BAD_PARAM; + } + + wcmp->nh_nr = ISIS_WCMP_HASH_MAX_NUM; + + addr = ISIS_WCMP_NHOP_TBL_ADDR + (wcmp_id << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + for (i = 0; i < 4; i++) + { + ptr[i] = (data >> (i << 3)) & 0x7f; + } + + addr = ISIS_WCMP_HASH_TBL_ADDR + (wcmp_id << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + for (i = 0; i < 16; i++) + { + pos[i] = (data >> (i << 1)) & 0x3; + } + + for (i = 0; i < 16; i++) + { + wcmp->nh_id[i] = ptr[pos[i]]; + } + + return SW_OK; +} +#endif + +static sw_error_t +_isis_ip_wcmp_hash_mode_set(a_uint32_t dev_id, a_uint32_t hash_mode) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_CTRL, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_WCMP_HASH_KEY_SIP & hash_mode) + { + SW_SET_REG_BY_FIELD(ROUTER_CTRL, WCMP_HAHS_SIP, 1, data); + } + else + { + SW_SET_REG_BY_FIELD(ROUTER_CTRL, WCMP_HAHS_SIP, 0, data); + } + + if (FAL_WCMP_HASH_KEY_DIP & hash_mode) + { + SW_SET_REG_BY_FIELD(ROUTER_CTRL, WCMP_HAHS_DIP, 1, data); + } + else + { + SW_SET_REG_BY_FIELD(ROUTER_CTRL, WCMP_HAHS_DIP, 0, data); + } + + if (FAL_WCMP_HASH_KEY_SPORT & hash_mode) + { + SW_SET_REG_BY_FIELD(ROUTER_CTRL, WCMP_HAHS_SP, 1, data); + } + else + { + SW_SET_REG_BY_FIELD(ROUTER_CTRL, WCMP_HAHS_SP, 0, data); + } + + if (FAL_WCMP_HASH_KEY_DPORT & hash_mode) + { + SW_SET_REG_BY_FIELD(ROUTER_CTRL, WCMP_HAHS_DP, 1, data); + } + else + { + SW_SET_REG_BY_FIELD(ROUTER_CTRL, WCMP_HAHS_DP, 0, data); + } + + + HSL_REG_ENTRY_SET(rv, dev_id, ROUTER_CTRL, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_ip_wcmp_hash_mode_get(a_uint32_t dev_id, a_uint32_t * hash_mode) +{ + sw_error_t rv; + a_uint32_t data = 0, field; + + *hash_mode = 0; + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_CTRL, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(ROUTER_CTRL, WCMP_HAHS_SIP, field, data); + if (field) + { + *hash_mode |= FAL_WCMP_HASH_KEY_SIP; + } + + SW_GET_FIELD_BY_REG(ROUTER_CTRL, WCMP_HAHS_DIP, field, data); + if (field) + { + *hash_mode |= FAL_WCMP_HASH_KEY_DIP; + } + + SW_GET_FIELD_BY_REG(ROUTER_CTRL, WCMP_HAHS_SP, field, data); + if (field) + { + *hash_mode |= FAL_WCMP_HASH_KEY_SPORT; + } + + SW_GET_FIELD_BY_REG(ROUTER_CTRL, WCMP_HAHS_DP, field, data); + if (field) + { + *hash_mode |= FAL_WCMP_HASH_KEY_DPORT; + } + + return SW_OK; +} + +sw_error_t +isis_ip_reset(a_uint32_t dev_id) +{ + sw_error_t rv; + a_uint32_t i, addr, data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, HOST_ENTRY4, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = _isis_host_entry_commit(dev_id, ISIS_ENTRY_ARP, ISIS_HOST_ENTRY_FLUSH); + SW_RTN_ON_ERROR(rv); + + isis_mac_snap[dev_id] = 0; + for (i = 0; i < ISIS_INTF_MAC_ADDR_NUM; i++) + { + addr = ISIS_INTF_MAC_TBL2_ADDR + (i << 4); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +/** + * @brief Add one host entry to one particular device. + * @details Comments: + * For ISIS the intf_id parameter in host_entry means vlan id. + Before host entry added related interface entry and ip6 base address + must be set at first. + Hardware entry id will be returned. + * @param[in] dev_id device id + * @param[in] host_entry host entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_ip_host_add(a_uint32_t dev_id, fal_host_entry_t * host_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_ip_host_add(dev_id, host_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete one host entry from one particular device. + * @details Comments: + * For ISIS the intf_id parameter in host_entry means vlan id. + Before host entry deleted related interface entry and ip6 base address + must be set atfirst. + For del_mode please refer IP entry operation flags. + * @param[in] dev_id device id + * @param[in] del_mode delete operation mode + * @param[in] host_entry host entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_ip_host_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_host_entry_t * host_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_ip_host_del(dev_id, del_mode, host_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get one host entry from one particular device. + * @details Comments: + * For ISIS the intf_id parameter in host_entry means vlan id. + Before host entry deleted related interface entry and ip6 base address + must be set atfirst. + For get_mode please refer IP entry operation flags. + * @param[in] dev_id device id + * @param[in] get_mode get operation mode + * @param[out] host_entry host entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_ip_host_get(a_uint32_t dev_id, a_uint32_t get_mode, + fal_host_entry_t * host_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_ip_host_get(dev_id, get_mode, host_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Next one host entry from one particular device. + * @details Comments: + * For ISIS the intf_id parameter in host_entry means vlan id. + Before host entry deleted related interface entry and ip6 base address + must be set atfirst. + For next_mode please refer IP entry operation flags. + For get the first entry please set entry id as FAL_NEXT_ENTRY_FIRST_ID + * @param[in] dev_id device id + * @param[in] next_mode next operation mode + * @param[out] host_entry host entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_ip_host_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_host_entry_t * host_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_ip_host_next(dev_id, next_mode, host_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Bind one counter entry to one host entry on one particular device. + * @param[in] dev_id device id + * @param[in] entry_id host entry id + * @param[in] cnt_id counter entry id + * @param[in] enable A_TRUE means bind, A_FALSE means unbind + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_ip_host_counter_bind(dev_id, entry_id, cnt_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Bind one pppoe session entry to one host entry on one particular device. + * @param[in] dev_id device id + * @param[in] entry_id host entry id + * @param[in] pppoe_id pppoe session entry id + * @param[in] enable A_TRUE means bind, A_FALSE means unbind + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_ip_host_pppoe_bind(dev_id, entry_id, pppoe_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set arp packets type to learn on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] flags arp type FAL_ARP_LEARN_REQ and/or FAL_ARP_LEARN_ACK + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_ip_pt_arp_learn_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t flags) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_ip_pt_arp_learn_set(dev_id, port_id, flags); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp packets type to learn on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] flags arp type FAL_ARP_LEARN_REQ and/or FAL_ARP_LEARN_ACK + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_ip_pt_arp_learn_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * flags) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_ip_pt_arp_learn_get(dev_id, port_id, flags); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set arp packets type to learn on one particular device. + * @param[in] dev_id device id + * @param[in] mode learning mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_ip_arp_learn_set(a_uint32_t dev_id, fal_arp_learn_mode_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_ip_arp_learn_set(dev_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp packets type to learn on one particular device. + * @param[in] dev_id device id + * @param[out] mode learning mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_ip_arp_learn_get(a_uint32_t dev_id, fal_arp_learn_mode_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_ip_arp_learn_get(dev_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set ip packets source guarding mode on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode source guarding mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_ip_source_guard_set(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_ip_source_guard_set(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get ip packets source guarding mode on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mode source guarding mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_ip_source_guard_get(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_ip_source_guard_get(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set unkonw source ip packets forwarding command on one particular device. + * @details Comments: + * This settin is no meaning when ip source guard not enable + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_ip_unk_source_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_ip_unk_source_cmd_set(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get unkonw source ip packets forwarding command on one particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_ip_unk_source_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_ip_unk_source_cmd_get(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set arp packets source guarding mode on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode source guarding mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_ip_arp_guard_set(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_ip_arp_guard_set(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp packets source guarding mode on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mode source guarding mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_ip_arp_guard_get(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_ip_arp_guard_get(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set unkonw source arp packets forwarding command on one particular device. + * @details Comments: + * This settin is no meaning when arp source guard not enable + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_arp_unk_source_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_arp_unk_source_cmd_set(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get unkonw source arp packets forwarding command on one particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_arp_unk_source_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_arp_unk_source_cmd_get(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set IP unicast routing status on one particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_ip_route_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_ip_route_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IP unicast routing status on one particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_ip_route_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_ip_route_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add one interface entry to one particular device. + * @param[in] dev_id device id + * @param[in] entry interface entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_ip_intf_entry_add(a_uint32_t dev_id, fal_intf_mac_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_ip_intf_entry_add(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete one interface entry from one particular device. + * @param[in] dev_id device id + * @param[in] del_mode delete operation mode + * @param[in] entry interface entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_ip_intf_entry_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_intf_mac_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_ip_intf_entry_del(dev_id, del_mode, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Next one interface entry from one particular device. + * @param[in] dev_id device id + * @param[in] next_mode next operation mode + * @param[out] entry interface entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_ip_intf_entry_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_intf_mac_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_ip_intf_entry_next(dev_id, next_mode, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set IP host entry aging time on one particular device. + * @details Comments: + * This operation will set dynamic entry aging time on a particular device. + * The unit of time is second. Because different device has differnet + * hardware granularity function will return actual time in hardware. + * @param[in] dev_id device id + * @param[in] time aging time + * @param[out] time actual aging time + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_ip_age_time_set(a_uint32_t dev_id, a_uint32_t * time) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_ip_age_time_set(dev_id, time); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IP host entry aging time on one particular device. + * @param[in] dev_id device id + * @param[out] time aging time + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_ip_age_time_get(a_uint32_t dev_id, a_uint32_t * time) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_ip_age_time_get(dev_id, time); + HSL_API_UNLOCK; + return rv; +} + +#if 0 +/** + * @brief Set IP WCMP table one particular device. + * @details Comments: + * Hardware only support 0 - 15 hash values and 4 different host tables. + * @param[in] dev_id device id + * @param[in] wcmp_id wcmp entry id + * @param[in] wcmp wcmp entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_ip_wcmp_entry_set(a_uint32_t dev_id, a_uint32_t wcmp_id, fal_ip_wcmp_t * wcmp) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_ip_wcmp_entry_set(dev_id, wcmp_id, wcmp); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IP WCMP table one particular device. + * @details Comments: + * Hardware only support 0 - 15 hash values and 4 different host tables. + * @param[in] dev_id device id + * @param[in] wcmp_id wcmp entry id + * @param[out] wcmp wcmp entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_ip_wcmp_entry_get(a_uint32_t dev_id, a_uint32_t wcmp_id, fal_ip_wcmp_t * wcmp) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_ip_wcmp_entry_get(dev_id, wcmp_id, wcmp); + HSL_API_UNLOCK; + return rv; +} +#endif + +/** + * @brief Set IP WCMP hash key mode. + * @param[in] dev_id device id + * @param[in] hash_mode hash mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_ip_wcmp_hash_mode_set(a_uint32_t dev_id, a_uint32_t hash_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_ip_wcmp_hash_mode_set(dev_id, hash_mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IP WCMP hash key mode. + * @param[in] dev_id device id + * @param[out] hash_mode hash mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_ip_wcmp_hash_mode_get(a_uint32_t dev_id, a_uint32_t * hash_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_ip_wcmp_hash_mode_get(dev_id, hash_mode); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +isis_ip_init(a_uint32_t dev_id) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + rv = isis_ip_reset(dev_id); + SW_RTN_ON_ERROR(rv); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->ip_host_add = isis_ip_host_add; + p_api->ip_host_del = isis_ip_host_del; + p_api->ip_host_get = isis_ip_host_get; + p_api->ip_host_next = isis_ip_host_next; + p_api->ip_host_counter_bind = isis_ip_host_counter_bind; + p_api->ip_host_pppoe_bind = isis_ip_host_pppoe_bind; + p_api->ip_pt_arp_learn_set = isis_ip_pt_arp_learn_set; + p_api->ip_pt_arp_learn_get = isis_ip_pt_arp_learn_get; + p_api->ip_arp_learn_set = isis_ip_arp_learn_set; + p_api->ip_arp_learn_get = isis_ip_arp_learn_get; + p_api->ip_source_guard_set = isis_ip_source_guard_set; + p_api->ip_source_guard_get = isis_ip_source_guard_get; + p_api->ip_unk_source_cmd_set = isis_ip_unk_source_cmd_set; + p_api->ip_unk_source_cmd_get = isis_ip_unk_source_cmd_get; + p_api->ip_arp_guard_set = isis_ip_arp_guard_set; + p_api->ip_arp_guard_get = isis_ip_arp_guard_get; + p_api->arp_unk_source_cmd_set = isis_arp_unk_source_cmd_set; + p_api->arp_unk_source_cmd_get = isis_arp_unk_source_cmd_get; + p_api->ip_route_status_set = isis_ip_route_status_set; + p_api->ip_route_status_get = isis_ip_route_status_get; + p_api->ip_intf_entry_add = isis_ip_intf_entry_add; + p_api->ip_intf_entry_del = isis_ip_intf_entry_del; + p_api->ip_intf_entry_next = isis_ip_intf_entry_next; + p_api->ip_age_time_set = isis_ip_age_time_set; + p_api->ip_age_time_get = isis_ip_age_time_get; + p_api->ip_wcmp_hash_mode_set = isis_ip_wcmp_hash_mode_set; + p_api->ip_wcmp_hash_mode_get = isis_ip_wcmp_hash_mode_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_leaky.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_leaky.c new file mode 100755 index 000000000..0d720be03 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_leaky.c @@ -0,0 +1,526 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup isis_leaky ISIS_LEAKY + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isis_leaky.h" +#include "isis_reg.h" + +static sw_error_t +_isis_uc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_LEAKY_PORT_CTRL == ctrl_mode) + { + data = 0; + } + else if (FAL_LEAKY_FDB_CTRL == ctrl_mode) + { + data = 1; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, ARL_UNI_LEAKY, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_uc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t *ctrl_mode) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, ARL_UNI_LEAKY, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *ctrl_mode = FAL_LEAKY_FDB_CTRL; + } + else + { + *ctrl_mode = FAL_LEAKY_PORT_CTRL; + } + + return SW_OK; +} + +static sw_error_t +_isis_mc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_LEAKY_PORT_CTRL == ctrl_mode) + { + data = 0; + } + else if (FAL_LEAKY_FDB_CTRL == ctrl_mode) + { + data = 1; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, ARL_MUL_LEAKY, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_mc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t *ctrl_mode) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, ARL_MUL_LEAKY, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *ctrl_mode = FAL_LEAKY_FDB_CTRL; + } + else + { + *ctrl_mode = FAL_LEAKY_PORT_CTRL; + } + + return SW_OK; +} + +static sw_error_t +_isis_port_arp_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LOOKUP_CTL, port_id, ARP_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_arp_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LOOKUP_CTL, port_id, ARP_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isis_port_uc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LOOKUP_CTL, port_id, UNI_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_uc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LOOKUP_CTL, port_id, UNI_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isis_port_mc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LOOKUP_CTL, port_id, MUL_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_mc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LOOKUP_CTL, port_id, MUL_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +/** +* @brief Set unicast packets leaky control mode on a particular device. +* @param[in] dev_id device id +* @param[in] ctrl_mode leaky control mode +* @return SW_OK or error code +*/ +HSL_LOCAL sw_error_t +isis_uc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_uc_leaky_mode_set(dev_id, ctrl_mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get unicast packets leaky control mode on a particular device. + * @param[in] dev_id device id + * @param[out] ctrl_mode leaky control mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_uc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t *ctrl_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_uc_leaky_mode_get(dev_id, ctrl_mode); + HSL_API_UNLOCK; + return rv; +} + +/** +* @brief Set multicast packets leaky control mode on a particular device. +* @param[in] dev_id device id +* @param[in] ctrl_mode leaky control mode +* @return SW_OK or error code +*/ +HSL_LOCAL sw_error_t +isis_mc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_mc_leaky_mode_set(dev_id, ctrl_mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get multicast packets leaky control mode on a particular device. + * @param[in] dev_id device id + * @param[out] ctrl_mode leaky control mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_mc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t *ctrl_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_mc_leaky_mode_get(dev_id, ctrl_mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set arp packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_arp_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_arp_leaky_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_arp_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_arp_leaky_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set unicast packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_uc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_uc_leaky_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get unicast packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_uc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_uc_leaky_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set multicast packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_mc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_mc_leaky_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get multicast packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_mc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_mc_leaky_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +isis_leaky_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->uc_leaky_mode_set = isis_uc_leaky_mode_set; + p_api->uc_leaky_mode_get = isis_uc_leaky_mode_get; + p_api->mc_leaky_mode_set = isis_mc_leaky_mode_set; + p_api->mc_leaky_mode_get = isis_mc_leaky_mode_get; + p_api->port_arp_leaky_set = isis_port_arp_leaky_set; + p_api->port_arp_leaky_get = isis_port_arp_leaky_get; + p_api->port_uc_leaky_set = isis_port_uc_leaky_set; + p_api->port_uc_leaky_get = isis_port_uc_leaky_get; + p_api->port_mc_leaky_set = isis_port_mc_leaky_set; + p_api->port_mc_leaky_get = isis_port_mc_leaky_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_led.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_led.c new file mode 100755 index 000000000..1f52c67e4 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_led.c @@ -0,0 +1,405 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup isis_led ISIS_LED + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "isis_led.h" +#include "isis_reg.h" + +#define MAX_LED_PATTERN_ID 2 +#define LED_PATTERN_ADDR 0x50 + +static sw_error_t +_isis_led_ctrl_pattern_set(a_uint32_t dev_id, led_pattern_group_t group, + led_pattern_id_t id, led_ctrl_pattern_t * pattern) +{ + a_uint32_t data = 0, reg = 0, mode; + a_uint32_t addr; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if ((LED_WAN_PORT_GROUP != group) && (LED_LAN_PORT_GROUP != group)) + { + return SW_BAD_PARAM; + } + + if (id > MAX_LED_PATTERN_ID) + { + return SW_BAD_PARAM; + } + + addr = LED_PATTERN_ADDR + (id << 2); + + if (LED_ALWAYS_OFF == pattern->mode) + { + mode = 0; + } + else if (LED_ALWAYS_BLINK == pattern->mode) + { + mode = 1; + } + else if (LED_ALWAYS_ON == pattern->mode) + { + mode = 2; + } + else if (LED_PATTERN_MAP_EN == pattern->mode) + { + mode = 3; + } + else + { + return SW_BAD_PARAM; + } + SW_SET_REG_BY_FIELD(LED_CTRL, PATTERN_EN, mode, data); + + if (pattern->map & (1 << FULL_DUPLEX_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, FULL_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << HALF_DUPLEX_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, HALF_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << POWER_ON_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, POWERON_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << LINK_1000M_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, GE_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << LINK_100M_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, FE_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << LINK_10M_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, ETH_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << COLLISION_BLINK_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, COL_BLINK_EN, 1, data); + } + + if (pattern->map & (1 << RX_TRAFFIC_BLINK_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, RX_BLINK_EN, 1, data); + } + + if (pattern->map & (1 << TX_TRAFFIC_BLINK_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, TX_BLINK_EN, 1, data); + } + + if (pattern->map & (1 << LINKUP_OVERRIDE_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, LINKUP_OVER_EN, 1, data); + } + else + { + SW_SET_REG_BY_FIELD(LED_CTRL, LINKUP_OVER_EN, 0, data); + } + + if (LED_BLINK_2HZ == pattern->freq) + { + SW_SET_REG_BY_FIELD(LED_CTRL, BLINK_FREQ, 0, data); + } + else if (LED_BLINK_4HZ == pattern->freq) + { + SW_SET_REG_BY_FIELD(LED_CTRL, BLINK_FREQ, 1, data); + } + else if (LED_BLINK_8HZ == pattern->freq) + { + SW_SET_REG_BY_FIELD(LED_CTRL, BLINK_FREQ, 2, data); + } + else if (LED_BLINK_TXRX == pattern->freq) + { + SW_SET_REG_BY_FIELD(LED_CTRL, BLINK_FREQ, 3, data); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (LED_WAN_PORT_GROUP == group) + { + reg &= 0xffff; + reg |= (data << 16); + } + else + { + reg &= 0xffff0000; + reg |= data; + } + + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (LED_WAN_PORT_GROUP == group) + { + return SW_OK; + } + + HSL_REG_ENTRY_GET(rv, dev_id, LED_PATTERN, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (LED_LAN_PORT_GROUP == group) + { + if (0 == id) + { + SW_SET_REG_BY_FIELD(LED_PATTERN, P3L0_MODE, mode, data); + SW_SET_REG_BY_FIELD(LED_PATTERN, P2L0_MODE, mode, data); + SW_SET_REG_BY_FIELD(LED_PATTERN, P1L0_MODE, mode, data); + } + else if (1 == id) + { + SW_SET_REG_BY_FIELD(LED_PATTERN, P3L1_MODE, mode, data); + SW_SET_REG_BY_FIELD(LED_PATTERN, P2L1_MODE, mode, data); + SW_SET_REG_BY_FIELD(LED_PATTERN, P1L1_MODE, mode, data); + } + else + { + SW_SET_REG_BY_FIELD(LED_PATTERN, P3L2_MODE, mode, data); + SW_SET_REG_BY_FIELD(LED_PATTERN, P2L2_MODE, mode, data); + SW_SET_REG_BY_FIELD(LED_PATTERN, P1L2_MODE, mode, data); + } + } + + HSL_REG_ENTRY_SET(rv, dev_id, LED_PATTERN, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +static sw_error_t +_isis_led_ctrl_pattern_get(a_uint32_t dev_id, led_pattern_group_t group, + led_pattern_id_t id, led_ctrl_pattern_t * pattern) +{ + a_uint32_t data = 0, reg = 0, tmp; + a_uint32_t addr; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if ((LED_WAN_PORT_GROUP != group) && (LED_LAN_PORT_GROUP != group)) + { + return SW_BAD_PARAM; + } + + if (id > MAX_LED_PATTERN_ID) + { + return SW_BAD_PARAM; + } + + aos_mem_zero(pattern, sizeof(led_ctrl_pattern_t)); + + addr = LED_PATTERN_ADDR + (id << 2); + + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (LED_WAN_PORT_GROUP == group) + { + data = (reg >> 16) & 0xffff; + } + else + { + data = reg & 0xffff; + } + + SW_GET_FIELD_BY_REG(LED_CTRL, PATTERN_EN, tmp, data); + if (0 == tmp) + { + pattern->mode = LED_ALWAYS_OFF; + } + else if (1 == tmp) + { + pattern->mode = LED_ALWAYS_BLINK; + } + else if (2 == tmp) + { + pattern->mode = LED_ALWAYS_ON; + } + else + { + pattern->mode = LED_PATTERN_MAP_EN; + } + + SW_GET_FIELD_BY_REG(LED_CTRL, FULL_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << FULL_DUPLEX_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, HALF_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << HALF_DUPLEX_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, POWERON_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << POWER_ON_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, GE_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << LINK_1000M_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, FE_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << LINK_100M_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, ETH_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << LINK_10M_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, COL_BLINK_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << COLLISION_BLINK_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, RX_BLINK_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << RX_TRAFFIC_BLINK_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, TX_BLINK_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << TX_TRAFFIC_BLINK_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, LINKUP_OVER_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << LINKUP_OVERRIDE_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, BLINK_FREQ, tmp, data); + if (0 == tmp) + { + pattern->freq = LED_BLINK_2HZ; + } + else if (1 == tmp) + { + pattern->freq = LED_BLINK_4HZ; + } + else if (2 == tmp) + { + pattern->freq = LED_BLINK_8HZ; + } + else + { + pattern->freq = LED_BLINK_TXRX; + } + + return SW_OK; +} + +/** +* @brief Set led control pattern on a particular device. +* @param[in] dev_id device id +* @param[in] group pattern group, lan or wan +* @param[in] id pattern id +* @param[in] pattern led control pattern +* @return SW_OK or error code +*/ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_led_ctrl_pattern_set(dev_id, group, id, pattern); + HSL_API_UNLOCK; + return rv; +} + +/** +* @brief Get led control pattern on a particular device. +* @param[in] dev_id device id +* @param[in] group pattern group, lan or wan +* @param[in] id pattern id +* @param[out] pattern led control pattern +* @return SW_OK or error code +*/ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_led_ctrl_pattern_get(dev_id, group, id, pattern); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +isis_led_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->led_ctrl_pattern_set = isis_led_ctrl_pattern_set; + p_api->led_ctrl_pattern_get = isis_led_ctrl_pattern_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_mac_block.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_mac_block.c new file mode 100755 index 000000000..6a33202dd --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_mac_block.c @@ -0,0 +1,388 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isis_port_ctrl.h" +#include "isis_mib.h" +#include "isis_misc.h" +#include "isis_reg.h" +#include "f1_phy.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct task_struct *mac_scan_task; +static a_bool_t qca_phy_info[7] = {A_FALSE}; +static a_bool_t qca_portvlan_mem_info[7] = {A_FALSE}; +static struct net_device *master_dev = NULL; +static fal_port_t uplink_portid =5; + +static void qca_cpu_pkt_xmit(struct net_device *dev) +{ + if (dev) + { + arp_send(ARPOP_RREQUEST, ETH_P_RARP, 0, dev, 0, NULL, + dev->dev_addr, dev->dev_addr); + } +} + +static a_bool_t +_isis_port_phy_connected(a_uint32_t dev_id, fal_port_t port_id) +{ + if ((0 == port_id) || (6 == port_id)) + { + return A_FALSE; + } + else + { + return A_TRUE; + } +} + + + +static sw_error_t qca_isis_rec_port_speed_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t speed) +{ + sw_error_t rv; + a_uint32_t reg_val; + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_val), sizeof (a_uint32_t)); + + if (FAL_SPEED_10 == speed) + { + SW_SET_REG_BY_FIELD(PORT_STATUS, SPEED_MODE, 0, reg_val); + SW_SET_REG_BY_FIELD(PORT_STATUS, DUPLEX_MODE, 1, reg_val); + } + else if (FAL_SPEED_100 == speed) + { + SW_SET_REG_BY_FIELD(PORT_STATUS, SPEED_MODE, 1, reg_val); + SW_SET_REG_BY_FIELD(PORT_STATUS, DUPLEX_MODE, 1, reg_val); + } + else + { + SW_SET_REG_BY_FIELD(PORT_STATUS, SPEED_MODE, 2, reg_val); + SW_SET_REG_BY_FIELD(PORT_STATUS, DUPLEX_MODE, 1, reg_val); + } + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_val), sizeof (a_uint32_t)); +} + + +static sw_error_t qca_isis_nor_port_speed_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t speed, fal_port_duplex_t duplex) +{ + sw_error_t rv; + a_uint32_t reg_val; + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_val), sizeof (a_uint32_t)); + + if (FAL_SPEED_10 == speed) + { + SW_SET_REG_BY_FIELD(PORT_STATUS, SPEED_MODE, 0, reg_val); + } + else if (FAL_SPEED_100 == speed) + { + SW_SET_REG_BY_FIELD(PORT_STATUS, SPEED_MODE, 1, reg_val); + } + else + { + SW_SET_REG_BY_FIELD(PORT_STATUS, SPEED_MODE, 2, reg_val); + } + + if (duplex == FAL_FULL_DUPLEX) + { + SW_SET_REG_BY_FIELD(PORT_STATUS, DUPLEX_MODE, 1, reg_val); + } + else + { + SW_SET_REG_BY_FIELD(PORT_STATUS, DUPLEX_MODE, 0, reg_val); + } + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_val), sizeof (a_uint32_t)); +} + + +static void qca_mac_ctrl_init(void) +{ + hsl_dev_t *pdev = NULL; + fal_port_t port_id; + a_uint32_t dev_id = 0, reg_val = 0, reg_save = 0; + sw_error_t rv; + + pdev = hsl_dev_ptr_get(dev_id); + if (pdev == NULL) + return; + + /* for port property set, SSDK should not generate some limitations */ + for (port_id = 0; port_id < pdev->nr_ports; port_id++) + { + if (A_FALSE == _isis_port_phy_connected(dev_id, port_id)) + continue; + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_val), sizeof (a_uint32_t)); + + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 0, reg_val); + + reg_save = reg_val; + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_save), sizeof (a_uint32_t)); + + } + + isis_mib_status_set(dev_id, A_TRUE); +} + +static void qca_mac_phy_poll(void) +{ + hsl_dev_t *pdev = NULL; + fal_port_t port_id; + a_uint32_t dev_id = 0, phy_id = 0; + a_bool_t status, lastStatus; + fal_mib_info_t counter; + fal_port_speed_t speed; + fal_port_duplex_t duplex; + a_uint32_t txok = 0; + sw_error_t rv; + a_uint32_t reg_val; + a_uint32_t index; + fal_pbmp_t uplink_portvlanmem = 0; + + pdev = hsl_dev_ptr_get(dev_id); + if (pdev == NULL) + return; + + + /* for port property set, SSDK should not generate some limitations */ + for (port_id = 0; port_id < pdev->nr_ports; port_id++) + { + if (A_FALSE == _isis_port_phy_connected(dev_id, port_id)) + continue; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + if (rv != SW_OK) + continue; + + status = f1_phy_get_link_status(dev_id, phy_id); + + lastStatus = qca_phy_info[phy_id]; + + if (lastStatus) + { + /*phy from up to down, disable mac rx/tx*/ + if (!status) + { + + /*make sure UNI port doesn't forward these types of pkts*/ + isis_port_bc_filter_set(dev_id, port_id, A_TRUE); + isis_port_unk_mc_filter_set(dev_id, port_id, A_TRUE); + isis_port_unk_uc_filter_set(dev_id, port_id, A_TRUE); + + /*make sure traffic from uplink port doesn't go to UNI port*/ + isis_portvlan_member_get(0, uplink_portid, &uplink_portvlanmem); + if ((0x1UL<pid); +} + + +void +qca_mac_scan_helper_exit(void) +{ + if(mac_scan_task) + { + kthread_stop(mac_scan_task); + } +} + +void qca_set_master_dev(struct net_device *dev) +{ + master_dev = dev; + +} + + + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_mib.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_mib.c new file mode 100755 index 000000000..d2f9d3ceb --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_mib.c @@ -0,0 +1,663 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup isis_mib ISIS_MIB + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isis_mib.h" +#include "isis_reg.h" + +static sw_error_t +_isis_get_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info) +{ + a_uint32_t val = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_OUT_OF_RANGE; + } + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBROAD, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxBroad = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXPAUSE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxPause = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXMULTI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxMulti = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXFCSERR, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxFcsErr = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXALLIGNERR, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxAllignErr = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXRUNT, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxRunt = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXFRAGMENT, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxFragment = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX64BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx64Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX128BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx128Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX256BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx256Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX512BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx512Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX1024BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx1024Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX1518BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx1518Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXMAXBYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxMaxByte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXTOOLONG, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxTooLong = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXGOODBYTE_LO, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxGoodByte_lo = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXGOODBYTE_HI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxGoodByte_hi = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBADBYTE_LO, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxBadByte_lo = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBADBYTE_HI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxBadByte_hi = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXOVERFLOW, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxOverFlow = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_FILTERED, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Filtered = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBROAD, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxBroad = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXPAUSE, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxPause = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMULTI, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxMulti = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXUNDERRUN, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxUnderRun = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX64BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx64Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX128BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx128Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX256BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx256Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX512BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx512Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX1024BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx1024Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX1518BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx1518Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMAXBYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxMaxByte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXOVERSIZE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxOverSize = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBYTE_LO, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxByte_lo = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBYTE_HI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxByte_hi = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXCOLLISION, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxCollision = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXABORTCOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxAbortCol = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMULTICOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxMultiCol = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXSINGALCOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxSingalCol = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXEXCDEFER, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxExcDefer = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXDEFER, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxDefer = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXLATECOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxLateCol = val; + + return SW_OK; +} + +static sw_error_t +_isis_get_rx_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info) +{ + a_uint32_t val = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_OUT_OF_RANGE; + } + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBROAD, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxBroad = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXPAUSE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxPause = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXMULTI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxMulti = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXFCSERR, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxFcsErr = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXALLIGNERR, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxAllignErr = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXRUNT, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxRunt = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXFRAGMENT, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxFragment = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX64BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx64Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX128BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx128Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX256BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx256Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX512BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx512Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX1024BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx1024Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX1518BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx1518Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXMAXBYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxMaxByte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXTOOLONG, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxTooLong = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXGOODBYTE_LO, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxGoodByte_lo = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXGOODBYTE_HI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxGoodByte_hi = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBADBYTE_LO, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxBadByte_lo = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBADBYTE_HI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxBadByte_hi = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXOVERFLOW, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxOverFlow = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_FILTERED, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Filtered = val; + + return SW_OK; +} + +static sw_error_t +_isis_get_tx_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info) +{ + a_uint32_t val = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_OUT_OF_RANGE; + } + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBROAD, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxBroad = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXPAUSE, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxPause = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMULTI, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxMulti = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXUNDERRUN, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxUnderRun = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX64BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx64Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX128BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx128Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX256BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx256Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX512BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx512Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX1024BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx1024Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX1518BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx1518Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMAXBYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxMaxByte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXOVERSIZE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxOverSize = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBYTE_LO, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxByte_lo = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBYTE_HI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxByte_hi = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXCOLLISION, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxCollision = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXABORTCOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxAbortCol = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMULTICOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxMultiCol = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXSINGALCOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxSingalCol = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXEXCDEFER, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxExcDefer = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXDEFER, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxDefer = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXLATECOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxLateCol = val; + + return SW_OK; +} + +static sw_error_t +_isis_mib_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, MOD_ENABLE, 0, MIB_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_mib_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, MOD_ENABLE, 0, MIB_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +/** + * @brief Get mib infomation on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mib_info mib infomation + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_get_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_get_mib_info(dev_id, port_id, mib_info); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get RX mib infomation on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mib_info mib infomation + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_get_rx_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_get_rx_mib_info(dev_id, port_id, mib_info); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get TX mib infomation on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mib_info mib infomation + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_get_tx_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_get_tx_mib_info(dev_id, port_id, mib_info); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set mib status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_mib_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_mib_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mib status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_mib_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_mib_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +isis_mib_init(a_uint32_t dev_id) +{ +#ifndef HSL_STANDALONG + hsl_api_t *p_api; +#endif + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->get_mib_info = isis_get_mib_info; + p_api->get_rx_mib_info = isis_get_rx_mib_info; + p_api->get_tx_mib_info = isis_get_tx_mib_info; + p_api->mib_status_set = isis_mib_status_set; + p_api->mib_status_get = isis_mib_status_get; +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_mirror.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_mirror.c new file mode 100755 index 000000000..16a7d214e --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_mirror.c @@ -0,0 +1,315 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup isis_mirror ISIS_MIRROR + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isis_mirror.h" +#include "isis_reg.h" + +static sw_error_t +_isis_mirr_analysis_port_set(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + if (port_id != MIRROR_ANALYZER_NONE) { + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) { + return SW_BAD_PARAM; + } + } + val = port_id; + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, MIRROR_PORT_NUM, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_mirr_analysis_port_get(a_uint32_t dev_id, fal_port_t * port_id) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, MIRROR_PORT_NUM, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *port_id = val; + return SW_OK; +} + +static sw_error_t +_isis_mirr_port_in_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LOOKUP_CTL, port_id, ING_MIRROR_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_mirr_port_in_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LOOKUP_CTL, port_id, ING_MIRROR_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isis_mirr_port_eg_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_HOL_CTL1, port_id, EG_MIRROR_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_mirr_port_eg_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_HOL_CTL1, port_id, EG_MIRROR_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +/** + * @details Comments: + * The analysis port works for both ingress and egress mirror. + * @brief Set mirror analyzer port on particular a device. + * @param[in] dev_id device id + * @param[in] port_id port id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_mirr_analysis_port_set(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_mirr_analysis_port_set(dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mirror analysis port on particular a device. + * @param[in] dev_id device id + * @param[out] port_id port id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_mirr_analysis_port_get(a_uint32_t dev_id, fal_port_t * port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_mirr_analysis_port_get(dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set ingress mirror status on particular a port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_mirr_port_in_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_mirr_port_in_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get ingress mirror status on particular a port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_mirr_port_in_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_mirr_port_in_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set egress mirror status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_mirr_port_eg_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_mirr_port_eg_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get egress mirror status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_mirr_port_eg_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_mirr_port_eg_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +isis_mirr_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->mirr_analysis_port_set = isis_mirr_analysis_port_set; + p_api->mirr_analysis_port_get = isis_mirr_analysis_port_get; + p_api->mirr_port_in_set = isis_mirr_port_in_set; + p_api->mirr_port_in_get = isis_mirr_port_in_get; + p_api->mirr_port_eg_set = isis_mirr_port_eg_set; + p_api->mirr_port_eg_get = isis_mirr_port_eg_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_misc.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_misc.c new file mode 100755 index 000000000..b2a8d3ddb --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_misc.c @@ -0,0 +1,1835 @@ +/* + * Copyright (c) 2012, 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 isis_misc ISIS_MISC + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isis_misc.h" +#include "isis_reg.h" +#include "hsl_phy.h" + + +#define ISIS_MAX_FRMAE_SIZE 9216 + +#define ARP_REQ_EN_OFFSET 6 +#define ARP_ACK_EN_OFFSET 5 +#define DHCP_EN_OFFSET 4 +#define EAPOL_EN_OFFSET 3 + +#define ISIS_SWITCH_INT_PHY_INT 0x8000 + +static sw_error_t +_isis_port_misc_property_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable, a_uint32_t item) +{ + sw_error_t rv; + a_uint32_t reg = 0, val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + if (3 >= port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, FRAME_ACK_CTL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + reg &= ~(0x1UL << ((port_id << 3) + item)); + reg |= (val << ((port_id << 3) + item)); + + HSL_REG_ENTRY_SET(rv, dev_id, FRAME_ACK_CTL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + HSL_REG_ENTRY_GET(rv, dev_id, FRAME_ACK_CTL1, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + reg &= ~(0x1UL << (((port_id - 4) << 3) + item)); + reg |= (val << (((port_id - 4) << 3) + item)); + + HSL_REG_ENTRY_SET(rv, dev_id, FRAME_ACK_CTL1, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + return rv; +} + +static sw_error_t +_isis_port_misc_property_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable, a_uint32_t item) +{ + sw_error_t rv; + a_uint32_t reg = 0, val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (3 >= port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, FRAME_ACK_CTL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + val = (reg >> ((port_id << 3) + item)) & 0x1UL; + } + else + { + HSL_REG_ENTRY_GET(rv, dev_id, FRAME_ACK_CTL1, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + val = (reg >> (((port_id - 4) << 3) + item)) & 0x1UL; + } + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isis_frame_max_size_set(a_uint32_t dev_id, a_uint32_t size) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (ISIS_MAX_FRMAE_SIZE < size) + { + return SW_BAD_PARAM; + } + + data = size; + HSL_REG_FIELD_SET(rv, dev_id, MAX_SIZE, 0, MAX_FRAME_SIZE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_frame_max_size_get(a_uint32_t dev_id, a_uint32_t * size) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, MAX_SIZE, 0, MAX_FRAME_SIZE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *size = data; + return SW_OK; +} + +static sw_error_t +_isis_port_unk_uc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL1, 0, UNI_FLOOD_DP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + data &= (~((a_uint32_t) 0x1 << port_id)); + } + else if (A_FALSE == enable) + { + data |= (0x1 << port_id); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL1, 0, UNI_FLOOD_DP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_unk_uc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t reg = 0, field; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL1, 0, UNI_FLOOD_DP, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + field = reg & (0x1 << port_id); + if (field) + { + *enable = A_FALSE; + } + else + { + *enable = A_TRUE; + } + + return SW_OK; +} + +static sw_error_t +_isis_port_unk_mc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL1, 0, MUL_FLOOD_DP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + data &= (~((a_uint32_t) 0x1 << port_id)); + } + else if (A_FALSE == enable) + { + data |= (0x1 << port_id); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL1, 0, MUL_FLOOD_DP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_unk_mc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t reg = 0, field; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL1, 0, MUL_FLOOD_DP, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + field = reg & (0x1 << port_id); + if (field) + { + *enable = A_FALSE; + } + else + { + *enable = A_TRUE; + } + + return SW_OK; +} + +static sw_error_t +_isis_port_bc_filter_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL1, 0, BC_FLOOD_DP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + data &= (~((a_uint32_t) 0x1 << port_id)); + } + else if (A_FALSE == enable) + { + data |= (0x1 << port_id); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL1, 0, BC_FLOOD_DP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_bc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t reg = 0, field; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL1, 0, BC_FLOOD_DP, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + field = reg & (0x1 << port_id); + if (field) + { + *enable = A_FALSE; + } + else + { + *enable = A_TRUE; + } + + return SW_OK; +} + +static sw_error_t +_isis_cpu_port_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, CPU_PORT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_cpu_port_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, CPU_PORT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isis_pppoe_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_MAC_FRWRD == cmd) + { + val = 0; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + val = 1; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, PPPOE_RDT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_pppoe_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, PPPOE_RDT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + else + { + *cmd = FAL_MAC_FRWRD; + } + + return SW_OK; +} + +static sw_error_t +_isis_pppoe_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FRAME_ACK_CTL1, 0, PPPOE_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_pppoe_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FRAME_ACK_CTL1, 0, PPPOE_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isis_arp_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_MAC_CPY_TO_CPU == cmd) + { + val = 1; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + val = 0; + } + else if (FAL_MAC_FRWRD == cmd) + { + val = 2; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, ARP_CMD, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_arp_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, ARP_CMD, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *cmd = FAL_MAC_CPY_TO_CPU; + } + else if (0 == val) + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + else + { + *cmd = FAL_MAC_FRWRD; + } + + return SW_OK; +} + +static sw_error_t +_isis_eapol_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_MAC_CPY_TO_CPU == cmd) + { + val = 0; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + val = 1; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, EAPOL_CMD, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_eapol_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, EAPOL_CMD, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0 == val) + { + *cmd = FAL_MAC_CPY_TO_CPU; + } + else + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + + return SW_OK; +} + +#define ISIS_MAX_PPPOE_SESSION 16 +#define ISIS_MAX_SESSION_ID 0xffff + +static sw_error_t +_isis_pppoe_session_add(a_uint32_t dev_id, fal_pppoe_session_t * session_tbl) +{ + sw_error_t rv; + a_uint32_t reg = 0, i, valid, id, entry_idx = ISIS_MAX_PPPOE_SESSION; + + HSL_DEV_ID_CHECK(dev_id); + + if (session_tbl->session_id > ISIS_MAX_SESSION_ID) + { + return SW_BAD_PARAM; + } + + if ((A_FALSE == session_tbl->multi_session) + && (A_TRUE == session_tbl->uni_session)) + { + return SW_BAD_PARAM; + } + + if ((A_FALSE == session_tbl->multi_session) + && (A_FALSE == session_tbl->uni_session)) + { + return SW_BAD_PARAM; + } + + for (i = 0; i < ISIS_MAX_PPPOE_SESSION; i++) + { + HSL_REG_ENTRY_GET(rv, dev_id, PPPOE_SESSION, i, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PPPOE_SESSION, ENTRY_VALID, valid, reg); + SW_GET_FIELD_BY_REG(PPPOE_SESSION, SEESION_ID, id, reg); + + if (!valid) + { + entry_idx = i; + } + else if (id == session_tbl->session_id) + { + return SW_ALREADY_EXIST; + } + } + + if (ISIS_MAX_PPPOE_SESSION == entry_idx) + { + return SW_NO_RESOURCE; + } + + if (A_TRUE == session_tbl->uni_session) + { + SW_SET_REG_BY_FIELD(PPPOE_SESSION, ENTRY_VALID, 2, reg); + } + else + { + SW_SET_REG_BY_FIELD(PPPOE_SESSION, ENTRY_VALID, 1, reg); + } + SW_SET_REG_BY_FIELD(PPPOE_SESSION, SEESION_ID, session_tbl->session_id, + reg); + + HSL_REG_ENTRY_SET(rv, dev_id, PPPOE_SESSION, entry_idx, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + session_tbl->entry_id = entry_idx; + return SW_OK; +} + +static sw_error_t +_isis_pppoe_session_del(a_uint32_t dev_id, fal_pppoe_session_t * session_tbl) +{ + sw_error_t rv; + a_uint32_t reg = 0, i, valid, id; + + HSL_DEV_ID_CHECK(dev_id); + + if (session_tbl->session_id > ISIS_MAX_SESSION_ID) + { + return SW_BAD_PARAM; + } + + for (i = 0; i < ISIS_MAX_PPPOE_SESSION; i++) + { + HSL_REG_ENTRY_GET(rv, dev_id, PPPOE_SESSION, i, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PPPOE_SESSION, ENTRY_VALID, valid, reg); + SW_GET_FIELD_BY_REG(PPPOE_SESSION, SEESION_ID, id, reg); + + if (((1 == valid) || (2 == valid)) && (id == session_tbl->session_id)) + { + SW_SET_REG_BY_FIELD(PPPOE_SESSION, ENTRY_VALID, 0, reg); + SW_SET_REG_BY_FIELD(PPPOE_SESSION, SEESION_ID, 0, reg); + HSL_REG_ENTRY_SET(rv, dev_id, PPPOE_SESSION, i, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; + } + } + + return SW_NOT_FOUND; +} + +static sw_error_t +_isis_pppoe_session_get(a_uint32_t dev_id, fal_pppoe_session_t * session_tbl) +{ + sw_error_t rv; + a_uint32_t reg = 0, i, valid, id; + + HSL_DEV_ID_CHECK(dev_id); + + if (session_tbl->session_id > ISIS_MAX_SESSION_ID) + { + return SW_BAD_PARAM; + } + + for (i = 0; i < ISIS_MAX_PPPOE_SESSION; i++) + { + HSL_REG_ENTRY_GET(rv, dev_id, PPPOE_SESSION, i, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PPPOE_SESSION, ENTRY_VALID, valid, reg); + SW_GET_FIELD_BY_REG(PPPOE_SESSION, SEESION_ID, id, reg); + + if (((1 == valid) || (2 == valid)) && (id == session_tbl->session_id)) + { + if (1 == valid) + { + session_tbl->multi_session = A_TRUE; + session_tbl->uni_session = A_FALSE; + } + else + { + session_tbl->multi_session = A_TRUE; + session_tbl->uni_session = A_TRUE; + } + + session_tbl->entry_id = i; + return SW_OK; + } + } + + return SW_NOT_FOUND; +} + +static sw_error_t +_isis_pppoe_session_id_set(a_uint32_t dev_id, a_uint32_t index, + a_uint32_t id) +{ + sw_error_t rv; + a_uint32_t reg; + + if (ISIS_MAX_PPPOE_SESSION <= index) + { + return SW_BAD_PARAM; + } + + if (ISIS_MAX_SESSION_ID < id) + { + return SW_BAD_PARAM; + } + + reg = 0; + SW_SET_REG_BY_FIELD(PPPOE_EDIT, EDIT_ID, id, reg); + HSL_REG_ENTRY_SET(rv, dev_id, PPPOE_EDIT, index, (a_uint8_t *) (®), + sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_isis_pppoe_session_id_get(a_uint32_t dev_id, a_uint32_t index, + a_uint32_t * id) +{ + sw_error_t rv; + a_uint32_t reg = 0, tmp; + + if (ISIS_MAX_PPPOE_SESSION <= index) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PPPOE_EDIT, index, (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + tmp = 0; + SW_GET_FIELD_BY_REG(PPPOE_EDIT, EDIT_ID, tmp, reg); + *id = tmp; + return SW_OK; +} + +static sw_error_t +_isis_ripv1_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, 0, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, RIP_CPY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_ripv1_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, 0, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, RIP_CPY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isis_intr_mask_set(a_uint32_t dev_id, a_uint32_t intr_mask) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + HSL_REG_ENTRY_GET(rv, dev_id, GBL_INT_MASK1, 0, (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (intr_mask & FAL_SWITCH_INTR_LINK_STATUS) + { + reg |= ISIS_SWITCH_INT_PHY_INT; + } + else + { + reg &= (~ISIS_SWITCH_INT_PHY_INT); + } + + HSL_REG_ENTRY_SET(rv, dev_id, GBL_INT_MASK1, 0, (a_uint8_t *) (®), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_intr_mask_get(a_uint32_t dev_id, a_uint32_t * intr_mask) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + *intr_mask = 0; + HSL_REG_ENTRY_GET(rv, dev_id, GBL_INT_MASK1, 0, (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (reg & ISIS_SWITCH_INT_PHY_INT) + { + *intr_mask |= FAL_SWITCH_INTR_LINK_STATUS; + } + + return SW_OK; +} + +static sw_error_t +_isis_intr_status_get(a_uint32_t dev_id, a_uint32_t * intr_status) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + *intr_status = 0; + HSL_REG_ENTRY_GET(rv, dev_id, GBL_INT_STATUS1, 0, (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (reg & ISIS_SWITCH_INT_PHY_INT) + { + *intr_status |= FAL_SWITCH_INTR_LINK_STATUS; + } + + return SW_OK; +} + +static sw_error_t +_isis_intr_status_clear(a_uint32_t dev_id, a_uint32_t intr_status) +{ + sw_error_t rv; + a_uint32_t reg; + + reg = 0; + if (intr_status & FAL_SWITCH_INTR_LINK_STATUS) + { + reg |= ISIS_SWITCH_INT_PHY_INT; + } + + HSL_REG_ENTRY_SET(rv, dev_id, GBL_INT_STATUS1, 0, (a_uint8_t *) (®), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_link_intr_mask_set(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t intr_mask_flag) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_intr_mask_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_intr_mask_set(dev_id, phy_id, intr_mask_flag); + return rv; +} + +static sw_error_t +_isis_port_link_intr_mask_get(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t * intr_mask_flag) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_intr_mask_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_intr_mask_get(dev_id, phy_id, intr_mask_flag); + return rv; +} + +static sw_error_t +_isis_port_link_intr_status_get(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t * intr_mask_flag) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_intr_status_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_intr_status_get(dev_id, phy_id, intr_mask_flag); + return rv; +} + +/** + * @brief Set max frame size which device can received on a particular device. + * @details Comments: + * The granularity of packets size is byte. + * @param[in] dev_id device id + * @param[in] size packet size + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_frame_max_size_set(a_uint32_t dev_id, a_uint32_t size) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_frame_max_size_set(dev_id, size); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get max frame size which device can received on a particular device. + * @details Comments: + * The unit of packets size is byte. + * @param[in] dev_id device id + * @param[out] size packet size + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_frame_max_size_get(a_uint32_t dev_id, a_uint32_t * size) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_frame_max_size_get(dev_id, size); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flooding status of unknown unicast packets on a particular port. + * @details Comments: + * If enable unknown unicast packets filter on one port then unknown + * unicast packets can't flood out from this port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_unk_uc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_unk_uc_filter_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get flooding status of unknown unicast packets on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_unk_uc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_unk_uc_filter_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flooding status of unknown multicast packets on a particular port. + * @details Comments: + * If enable unknown multicast packets filter on one port then unknown + * multicast packets can't flood out from this port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_unk_mc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_unk_mc_filter_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** @brief Get flooding status of unknown multicast packets on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_unk_mc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_unk_mc_filter_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flooding status of broadcast packets on a particular port. + * @details Comments: + * If enable unknown multicast packets filter on one port then unknown + * multicast packets can't flood out from this port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_bc_filter_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_bc_filter_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** @brief Get flooding status of broadcast packets on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_bc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_bc_filter_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set cpu port status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_cpu_port_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_cpu_port_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get cpu port status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_cpu_port_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_cpu_port_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set pppoe packets forwarding command on a particular device. + * @details comments: + * Particular device may only support parts of forwarding commands. + * Ihis operation will take effect only after enabling pppoe packets + * hardware acknowledgement + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_pppoe_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_pppoe_cmd_set(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get pppoe packets forwarding command on a particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_pppoe_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_pppoe_cmd_get(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set pppoe packets hardware acknowledgement status on particular device. + * @details comments: + * Particular device may only support parts of pppoe packets. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_pppoe_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_pppoe_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get pppoe packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_pppoe_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_pppoe_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dhcp packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_dhcp_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_misc_property_set(dev_id, port_id, enable, DHCP_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dhcp packets hardware acknowledgement status on particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_dhcp_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_misc_property_get(dev_id, port_id, enable, DHCP_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set arp packets forwarding command on a particular device. + * @details comments: + * Particular device may only support parts of forwarding commands. + * Ihis operation will take effect only after enabling arp packets + * hardware acknowledgement + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_arp_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_arp_cmd_set(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp packets forwarding command on a particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_arp_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_arp_cmd_get(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set eapol packets forwarding command on a particular device. + * @details comments: + * Particular device may only support parts of forwarding commands. + * Ihis operation will take effect only after enabling eapol packets + * hardware acknowledgement + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_eapol_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_eapol_cmd_set(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get eapol packets forwarding command on a particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_eapol_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_eapol_cmd_get(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add a pppoe session entry to a particular device. + * The entry only for pppoe/ppp header remove. + * @param[in] dev_id device id + * @param[in] session_tbl pppoe session table + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_pppoe_session_table_add(a_uint32_t dev_id, + fal_pppoe_session_t * session_tbl) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_pppoe_session_add(dev_id, session_tbl); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a pppoe session entry from a particular device. + * The entry only for pppoe/ppp header remove. + * @param[in] dev_id device id + * @param[in] session_tbl pppoe session table + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_pppoe_session_table_del(a_uint32_t dev_id, + fal_pppoe_session_t * session_tbl) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_pppoe_session_del(dev_id, session_tbl); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get a pppoe session entry from a particular device. + * The entry only for pppoe/ppp header remove. + * @param[in] dev_id device id + * @param[out] session_tbl pppoe session table + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_pppoe_session_table_get(a_uint32_t dev_id, + fal_pppoe_session_t * session_tbl) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_pppoe_session_get(dev_id, session_tbl); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set a pppoe session id entry to a particular device. + * The entry only for pppoe/ppp header add. + * @param[in] dev_id device id + * @param[in] session_tbl pppoe session table + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_pppoe_session_id_set(a_uint32_t dev_id, a_uint32_t index, + a_uint32_t id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_pppoe_session_id_set(dev_id, index, id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get a pppoe session id entry from a particular device. + * The entry only for pppoe/ppp header add. + * @param[in] dev_id device id + * @param[out] session_tbl pppoe session table + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_pppoe_session_id_get(a_uint32_t dev_id, a_uint32_t index, + a_uint32_t * id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_pppoe_session_id_get(dev_id, index, id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set eapol packets hardware acknowledgement status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_eapol_status_set(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_misc_property_set(dev_id, port_id, enable, EAPOL_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get eapol packets hardware acknowledgement status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_eapol_status_get(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_misc_property_get(dev_id, port_id, enable, EAPOL_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set rip v1 packets hardware acknowledgement status on a particular port. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_ripv1_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_ripv1_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get rip v1 packets hardware acknowledgement status on a particular port. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_ripv1_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_ripv1_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set arp req packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_arp_req_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_misc_property_set(dev_id, port_id, enable, + ARP_REQ_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp req packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_arp_req_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_misc_property_get(dev_id, port_id, enable, + ARP_REQ_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set arp ack packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_arp_ack_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_misc_property_set(dev_id, port_id, enable, + ARP_ACK_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp ack packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_arp_ack_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_misc_property_get(dev_id, port_id, enable, + ARP_ACK_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set switch interrupt mask on one particular device. + * @param[in] dev_id device id + * @param[in] intr_mask mask + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_intr_mask_set(a_uint32_t dev_id, a_uint32_t intr_mask) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_intr_mask_set(dev_id, intr_mask); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get switch interrupt mask on one particular device. + * @param[in] dev_id device id + * @param[in] intr_mask mask + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_intr_mask_get(a_uint32_t dev_id, a_uint32_t * intr_mask) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_intr_mask_get(dev_id, intr_mask); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get switch interrupt status on one particular device. + * @param[in] dev_id device id + * @param[in] intr_status status + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_intr_status_get(a_uint32_t dev_id, a_uint32_t * intr_status) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_intr_status_get(dev_id, intr_status); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Clear switch interrupt status on one particular device. + * @param[in] dev_id device id + * @param[in] intr_status status + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_intr_status_clear(a_uint32_t dev_id, a_uint32_t intr_status) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_intr_status_clear(dev_id, intr_status); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set link interrupt mask on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] intr_mask_flag interrupt mask + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_intr_port_link_mask_set(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t intr_mask_flag) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _isis_port_link_intr_mask_set(dev_id, port_id, intr_mask_flag); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get link interrupt mask on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] intr_mask_flag interrupt mask + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_intr_port_link_mask_get(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t * intr_mask_flag) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_link_intr_mask_get(dev_id, port_id, intr_mask_flag); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get link interrupt status on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] intr_mask_flag interrupt mask + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_intr_port_link_status_get(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t * intr_mask_flag) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_link_intr_status_get(dev_id, port_id, intr_mask_flag); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +isis_misc_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->frame_max_size_set = isis_frame_max_size_set; + p_api->frame_max_size_get = isis_frame_max_size_get; + p_api->port_unk_uc_filter_set = isis_port_unk_uc_filter_set; + p_api->port_unk_uc_filter_get = isis_port_unk_uc_filter_get; + p_api->port_unk_mc_filter_set = isis_port_unk_mc_filter_set; + p_api->port_unk_mc_filter_get = isis_port_unk_mc_filter_get; + p_api->port_bc_filter_set = isis_port_bc_filter_set; + p_api->port_bc_filter_get = isis_port_bc_filter_get; + p_api->cpu_port_status_set = isis_cpu_port_status_set; + p_api->cpu_port_status_get = isis_cpu_port_status_get; + p_api->pppoe_cmd_set = isis_pppoe_cmd_set; + p_api->pppoe_cmd_get = isis_pppoe_cmd_get; + p_api->pppoe_status_set = isis_pppoe_status_set; + p_api->pppoe_status_get = isis_pppoe_status_get; + p_api->port_dhcp_set = isis_port_dhcp_set; + p_api->port_dhcp_get = isis_port_dhcp_get; + p_api->arp_cmd_set = isis_arp_cmd_set; + p_api->arp_cmd_get = isis_arp_cmd_get; + p_api->eapol_cmd_set = isis_eapol_cmd_set; + p_api->eapol_cmd_get = isis_eapol_cmd_get; + p_api->pppoe_session_table_add = isis_pppoe_session_table_add; + p_api->pppoe_session_table_del = isis_pppoe_session_table_del; + p_api->pppoe_session_table_get = isis_pppoe_session_table_get; + p_api->pppoe_session_id_set = isis_pppoe_session_id_set; + p_api->pppoe_session_id_get = isis_pppoe_session_id_get; + p_api->eapol_status_set = isis_eapol_status_set; + p_api->eapol_status_get = isis_eapol_status_get; + p_api->ripv1_status_set = isis_ripv1_status_set; + p_api->ripv1_status_get = isis_ripv1_status_get; + p_api->port_arp_req_status_set = isis_port_arp_req_status_set; + p_api->port_arp_req_status_get = isis_port_arp_req_status_get; + p_api->port_arp_ack_status_set = isis_port_arp_ack_status_set; + p_api->port_arp_ack_status_get = isis_port_arp_ack_status_get; + p_api->intr_mask_set = isis_intr_mask_set; + p_api->intr_mask_get = isis_intr_mask_get; + p_api->intr_status_get = isis_intr_status_get; + p_api->intr_status_clear = isis_intr_status_clear; + p_api->intr_port_link_mask_set = isis_intr_port_link_mask_set; + p_api->intr_port_link_mask_get = isis_intr_port_link_mask_get; + p_api->intr_port_link_status_get = isis_intr_port_link_status_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_multicast_acl.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_multicast_acl.c new file mode 100755 index 000000000..9db89f4d2 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_multicast_acl.c @@ -0,0 +1,985 @@ +/* + * Copyright (c) 2012, 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. + */ + + +#include "fal_nat.h" +#include "fal_ip.h" +#include "hsl_api.h" +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isis_igmp.h" +#include "isis_reg.h" +#include "fal_multi.h" +#include "isis_acl.h" +#include "sal/os/aos_lock.h" + +#if 0 +/** + * I/F prototype for complete igmpv3 & mldv2 support + */ + +/*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; +} fal_igmp_sg_entry_t; + +/** + * @brief set PortMap of IGMP sg entry. + * search entry according to source/group address, + * update PortMap if SG entry is found, otherwise create a new sg entry. + * @param[in] dev_id device id + * @param[in-out] entry SG entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_igmp_sg_entry_set(a_uint32_t dev_id, fal_igmp_sg_entry_t * entry); + +/** + * @brief clear PortMap of IGMP sg entry. + * search entry according to source/group address, + * update PortMap if SG entry is found, delete the entry in case PortMap was 0. + * SW_NOT_FOUND will be returned in case search failed. + * @param[in] dev_id device id + * @param[in-out] entry SG entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_igmp_sg_entry_clear(a_uint32_t dev_id, fal_igmp_sg_entry_t * entry); + +#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 1 +#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; +#endif + +static a_uint32_t rule_nr=1; + +void +isis_multicast_init(a_uint32_t dev_id); + +HSL_LOCAL sw_error_t multi_portmap_aclreg_set(a_uint32_t pos, fal_igmp_sg_entry_t * entry); + +static multi_acl_info_t multi_acl_info[FAL_IGMP_SG_ENTRY_MAX]; +static multi_acl_info_t multi_acl_group[FAL_IGMP_SG_ENTRY_MAX]; + +static int ip6_addr_is_null(fal_ip6_addr_t *ip6) +{ + if (NULL == ip6) + { + aos_printk("Invalid ip6 address\n"); + return -1; + } + if(0 == ip6->ul[0] && 0 == ip6->ul[1] && 0 == ip6->ul[2] && 0 == ip6->ul[3]) + return 1; + else + return 0; +} +static int multi_source_is_null(fal_igmp_sg_addr_t *s) +{ + if (NULL == s) + { + aos_printk("Invalid source address\n"); + return -1; + } + if(0 == s->type && 0==s->u.ip4_addr) + return 1; + if(1 == s->type && 1 == ip6_addr_is_null(&(s->u.ip6_addr))) + return 1; + + return 0; +} + +HSL_LOCAL int iterate_multicast_acl_rule(int list_id, int start_n) +{ + a_uint32_t dev_id=0; + a_uint32_t rule_id; + sw_error_t ret; + fal_acl_rule_t rule= {0}; + + if(start_n>=FAL_IGMP_SG_ENTRY_MAX || start_n < 0) + { + return -1; + } + + for(rule_id=0; rule_id=FAL_IGMP_SG_ENTRY_MAX) + { + return -1; + } + multi_acl_info[rule_id+start_n].index = rule_id; // consider here... index is NOT related start_n + //MULTI_DEBUG("normal query1: rule dest_ip4_val=%x, src ip4=%x, dst_ip6=%x, ports=%x\n", + //rule.dest_ip4_val, rule.src_ip4_val, rule.dest_ip6_val.ul[0], rule.ports); + + if(rule.dest_ip4_val !=0 && ip6_addr_is_null(&rule.dest_ip6_val)) //only ip4 + { + multi_acl_info[rule_id+start_n].entry.group.type = FAL_ADDR_IPV4; + multi_acl_info[rule_id+start_n].entry.source.type = FAL_ADDR_IPV4; + multi_acl_info[rule_id+start_n].entry.group.u.ip4_addr = rule.dest_ip4_val; + multi_acl_info[rule_id+start_n].entry.source.u.ip4_addr = rule.src_ip4_val; + multi_acl_info[rule_id+start_n].entry.port_map= rule.ports; + } + else if(rule.dest_ip4_val ==0 && !ip6_addr_is_null(&rule.dest_ip6_val)) //only ip6 + { + multi_acl_info[rule_id+start_n].entry.group.type = FAL_ADDR_IPV6; + multi_acl_info[rule_id+start_n].entry.source.type = FAL_ADDR_IPV6; + memcpy(&(multi_acl_info[rule_id+start_n].entry.group.u.ip6_addr), &(rule.dest_ip6_val), sizeof(rule.dest_ip6_val)); + memcpy(&(multi_acl_info[rule_id+start_n].entry.source.u.ip6_addr), &(rule.src_ip6_val), sizeof(rule.src_ip6_val)); + multi_acl_info[rule_id+start_n].entry.port_map= rule.ports; + } + } + + return rule_id+start_n; +} +/* +** Iterate the total 32 multicast ACL entries. + After the function completes: + 1. Stores all multicast related ACL rules in multi_acl_info[32] + 2. return the number of multicast related ACL rules +*/ +HSL_LOCAL a_uint32_t isis_multicast_acl_query(void) +{ + int start_n; + int total_n; + //a_uint32_t i; + + start_n = iterate_multicast_acl_rule(FAL_ACL_LIST_MULTICAST, 0); + if(-1 == start_n) + aos_printk("ACL rule1 is FULL\n"); + total_n = iterate_multicast_acl_rule(FAL_ACL_LIST_MULTICAST+1, start_n); + if(-1 == total_n) + aos_printk("ACL rule2 is FULL\n"); + + MULTI_DEBUG("KKK, the total ACL rule number is %d, (G,S) number=%d\n", total_n, start_n); + /* + for(i=0;i>6)&0x3) == 0x3) || (((msk_valid>>6)&0x3) == 0x2)) + { + rv = multi_portmap_aclreg_set(i, entry); + break; + } + else if ((((msk_valid>>6)&0x3)) == 0x0 || (((msk_valid>>6)&0x3) == 0x1)) + { + rv = multi_portmap_aclreg_set(i, entry); + continue; + } + else + { + aos_printk("The rule valid bit:6 7 is wrong!!!"); + break; + } + } + return rv; +} +HSL_LOCAL sw_error_t multi_portmap_aclreg_set(a_uint32_t pos, fal_igmp_sg_entry_t * entry) +{ + a_uint32_t i, base, addr; + a_uint32_t dev_id=0; + sw_error_t rv; + a_uint32_t act[3]= {0}; + fal_pbmp_t pm; + + pm = entry->port_map; + + base = ISIS_FILTER_ACT_ADDR + (pos << 4); + for (i = 0; i < 3; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&act[i]), + sizeof (a_uint32_t)); + //MULTI_DEBUG("2:Get register value 0x%x =%x\n", addr, act[i]); + SW_RTN_ON_ERROR(rv); + } + + act[1] &= ~(0x7<<29); // clear the high 3 bits + act[1] |= (pm&0x7)<<29; //the low 3 bits of pm means redirect port 0,1,2 + + /* New modification: update acl ACTION register from DENY to redirect */ + if (((act[2]>>6)&0x7) == 0x7) //DENY mode + { + if(pm) + { + act[2] &= ~(0x7<<6);//clear DENY bits + act[2] |= (0x1<<4); //DES_PORT_EN set 1, enable + } + } + else if (((act[2]>>4)&0x1) == 0x1) //redirect mode + { + if(pm==0) + { + act[2] &= ~(0x1<<4);//clear redirect bits + act[2] |= (0x7<<6); //set to DENY + } + } + + act[2] &= ~0xf; //clear the low 4 bits of port 3,4,5,6 + act[2] |= (pm>>3)&0xf; + + addr = base + (1<<2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&act[1]), sizeof (a_uint32_t)); + addr = base + (2<<2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&act[2]), sizeof (a_uint32_t)); + MULTI_DEBUG("pos=%d, before sync portmap, the new act=%x %x\n", pos, act[1],act[2]); + if((rv = isis_acl_rule_sync_multi_portmap(dev_id, pos, act)) < 0) + aos_printk("Sync multicast portmap error\n"); + return rv; +} + +HSL_LOCAL int multi_get_dp(void) +{ + a_uint32_t addr; + a_uint32_t dev_id=0; + sw_error_t rv; + int val=0; + + addr = 0x624;//GLOBAL_FW_CTRL1 + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + if (rv != SW_OK) + aos_printk("Get entry value error\n"); + + val = (val>>24)&0x7f; //30:24, IGMP_JOIN_LEAVE_DP + + return val; +} +static int old_bind_p=-1; +HSL_LOCAL int multi_acl_bind(void) +{ + int bind_p; + int i; + + bind_p = multi_get_dp(); + if(bind_p == old_bind_p) + return 0; + old_bind_p = bind_p; + + for(i=0; i<6; i++) + { + isis_acl_list_unbind(0, FAL_ACL_LIST_MULTICAST, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, i); + isis_acl_list_unbind(0, FAL_ACL_LIST_MULTICAST+1, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, i); + } + + if(bind_p==0) + { + for(i=0; i<6; i++) + { + isis_acl_list_bind(0, FAL_ACL_LIST_MULTICAST, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, i); + isis_acl_list_bind(0, FAL_ACL_LIST_MULTICAST+1, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, i); + } + } + else + { + for(i=0; i<6; i++) + if((bind_p>>i) &0x1) + { + isis_acl_list_bind(0, FAL_ACL_LIST_MULTICAST, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, i); + isis_acl_list_bind(0, FAL_ACL_LIST_MULTICAST+1, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, i); + } + else + continue; + } + return 0; +} +/* +** Only update the related portmap from the privious input. +*/ +HSL_LOCAL sw_error_t isis_multicast_acl_update( int list_id, int acl_index, fal_igmp_sg_entry_t * entry, int action) +{ + a_uint32_t dev_id=0; + a_uint32_t rule_pos; + sw_error_t rv = SW_OK; + + if(acl_index<0) + { + aos_printk("Something is wrong...\n"); + return SW_FAIL; + } + + rule_pos = isis_acl_rule_get_offset(dev_id, list_id, multi_acl_group[acl_index].index); + if(MULT_ACTION_SET == action) + { + multi_acl_group[acl_index].entry.port_map |= entry->port_map; + if(entry->port_map == 0) + { + multi_acl_group[acl_index].entry.port_map = 0; + } + } + else if(MULT_ACTION_CLEAR == action) + multi_acl_group[acl_index].entry.port_map &= ~(entry->port_map); + + rv = multi_portmap_aclreg_set_all(rule_pos, &multi_acl_group[acl_index].entry); + + multi_acl_bind(); //Here need extra bind since IGMP join/leave would happen + return rv; +} + +HSL_LOCAL sw_error_t isis_multicast_acl_del(int list_id, int index) +{ + sw_error_t rv; + int rule_id; + + rule_id = multi_acl_group[index].index; + + rv = isis_acl_rule_delete(0, list_id, rule_id, 1); + multi_acl_bind(); //Here need extra bind since IGMP join/leave would happen + return rv; +} + +/* +** Add new acl rule with parameters: DIP, SIP, redirect port. +*/ +HSL_LOCAL sw_error_t isis_multicast_acl_add(int list_id, fal_igmp_sg_entry_t * entry) +{ + sw_error_t val; + a_uint32_t pos; + fal_acl_rule_t acl= {0}; + + /* IPv4 multicast */ + if( entry->group.type == FAL_ADDR_IPV4 ) + { + MULTI_DEBUG("KKK1, group[%d][%x], source[%d][%x]\n",entry->group.type, + entry->group.u.ip4_addr, entry->source.type, entry->source.u.ip4_addr); + + acl.rule_type = FAL_ACL_RULE_IP4; + + if(entry->group.u.ip4_addr!= 0) + { + acl.dest_ip4_val = entry->group.u.ip4_addr; + acl.dest_ip4_mask = 0xffffffff;//e->ip.dmsk.s_addr; + FAL_FIELD_FLG_SET(acl.field_flg, FAL_ACL_FIELD_IP4_DIP); + } + if(entry->source.u.ip4_addr!= 0) + { + acl.src_ip4_val = entry->source.u.ip4_addr; + acl.src_ip4_mask = 0xffffffff;//e->ip.smsk.s_addr; + FAL_FIELD_FLG_SET(acl.field_flg, FAL_ACL_FIELD_IP4_SIP); + } + if( entry->port_map==0 ) + FAL_ACTION_FLG_SET ( acl.action_flg, FAL_ACL_ACTION_DENY); + else + //FAL_FIELD_FLG_SET(acl.field_flg, FAL_ACL_FIELD_INVERSE_ALL); + FAL_ACTION_FLG_SET ( acl.action_flg, FAL_ACL_ACTION_PERMIT ); + + /* Be careful, _isis_acl_action_parse() will block FAL_ACL_ACTION_DENY action, So we change it. */ + if( entry->port_map ) + { + FAL_ACTION_FLG_SET(acl.action_flg, FAL_ACL_ACTION_REDPT); + acl.ports = entry->port_map; + } + } + else if( entry->group.type == FAL_ADDR_IPV6 ) + { + MULTI_DEBUG("KKK2, group[%d][%x], source[%d][%x], pm=%x\n",entry->group.type, + entry->group.u.ip6_addr.ul[0], entry->source.type, entry->source.u.ip6_addr.ul[0], entry->port_map); + + acl.rule_type = FAL_ACL_RULE_IP6; + + if(!ip6_addr_is_null(&(entry->group.u.ip6_addr))) + { + memcpy(&acl.dest_ip6_val, &(entry->group.u.ip6_addr), sizeof(entry->group.u.ip6_addr)); + acl.dest_ip6_mask.ul[0] = 0xffffffff; + acl.dest_ip6_mask.ul[1] = 0xffffffff; + acl.dest_ip6_mask.ul[2] = 0xffffffff; + acl.dest_ip6_mask.ul[3] = 0xffffffff; + FAL_FIELD_FLG_SET(acl.field_flg, FAL_ACL_FIELD_IP6_DIP); + } + if(!ip6_addr_is_null(&(entry->source.u.ip6_addr))) + { + memcpy(&acl.src_ip6_val, &(entry->source.u.ip6_addr), sizeof(entry->source.u.ip6_addr)); + acl.src_ip6_mask.ul[0] = 0xffffffff; + acl.src_ip6_mask.ul[1] = 0xffffffff; + acl.src_ip6_mask.ul[2] = 0xffffffff; + acl.src_ip6_mask.ul[3] = 0xffffffff; + FAL_FIELD_FLG_SET(acl.field_flg, FAL_ACL_FIELD_IP6_SIP); + } + + if( entry->port_map==0 ) + FAL_ACTION_FLG_SET ( acl.action_flg, FAL_ACL_ACTION_DENY); + else + //FAL_FIELD_FLG_SET(acl.field_flg, FAL_ACL_FIELD_INVERSE_ALL); + FAL_ACTION_FLG_SET ( acl.action_flg, FAL_ACL_ACTION_PERMIT ); + + /* Be careful, _isis_acl_action_parse() will block FAL_ACL_ACTION_DENY action, So we change it. */ + if( entry->port_map ) + { + FAL_ACTION_FLG_SET(acl.action_flg, FAL_ACL_ACTION_REDPT); + acl.ports = entry->port_map; + } + } + + pos = isis_multicast_acl_total_n(list_id); + + MULTI_DEBUG("In isis_multicast_acl_add, list_id=%d, rule_id=%d\n", list_id, pos); + val = isis_acl_rule_add(0, list_id, pos, rule_nr, &acl); + + multi_acl_bind(); + + return val; +} + + +HSL_LOCAL int iterate_multicast_acl_group(a_uint32_t number, fal_igmp_sg_entry_t * entry) +{ + int count=0; + int i; + + if (number == 0) + return 0; //no any ACL rules based the query + + for(i=0; igroup.type, entry->group.u.ip6_addr.ul[0], entry->port_map);*/ + + if(0 == memcmp(&(multi_acl_info[i].entry.group), &(entry->group), sizeof(entry->group))) + { + memcpy(&multi_acl_group[count], &multi_acl_info[i], sizeof(multi_acl_info[i])); + count++;//return the real number of multi_acl_group[] + MULTI_DEBUG("in iterate_multicast_acl_group, count=%d, i=%d\n", count, i); + } + } + + return count; +} + +HSL_LOCAL int mult_acl_has_entry(fal_igmp_sg_addr_t * group, fal_igmp_sg_addr_t *source) +{ + int rule_id; + int ret = 0; +#if 0 + if(source != NULL) + { + MULTI_DEBUG("new group[%d]= %x %x %x %x, new source[%d]=%x %x %x %x\n", + group->type, group->u.ip6_addr.ul[0], group->u.ip6_addr.ul[1], group->u.ip6_addr.ul[2], group->u.ip6_addr.ul[3], + source->type, source->u.ip6_addr.ul[0], source->u.ip6_addr.ul[1], source->u.ip6_addr.ul[2], source->u.ip6_addr.ul[3]); + + MULTI_DEBUG("old group[%d]= %x %x %x %x, old source[%d]=%x %x %x %x\n", + multi_acl_group[0].entry.group.type, multi_acl_group[0].entry.group.u.ip6_addr.ul[0], + multi_acl_group[0].entry.group.u.ip6_addr.ul[1], multi_acl_group[0].entry.group.u.ip6_addr.ul[2], multi_acl_group[0].entry.group.u.ip6_addr.ul[3], + multi_acl_group[0].entry.source.type, multi_acl_group[0].entry.source.u.ip6_addr.ul[0], + multi_acl_group[0].entry.source.u.ip6_addr.ul[1], multi_acl_group[0].entry.source.u.ip6_addr.ul[2], multi_acl_group[0].entry.source.u.ip6_addr.ul[3]); + } +#endif + if(source == NULL) + { + for(rule_id=0; rule_idport_map, g_source->source.u.ip4_addr, g_source->group.u.ip4_addr, + g_star->port_map, g_star->source.u.ip4_addr,g_star->group.u.ip4_addr);*/ + + if(multi_source_is_null(&(g_star->source))) + { + if((g_source->port_map|g_star->port_map) == g_star->port_map) + { + return 0; + } + } + + return 1; +} + + +HSL_LOCAL int portmap_clear_type(int count, int index, fal_pbmp_t portmap) +{ + if(count>=0 && index0; this means there're (G,*) and (G,S) + { + //if the new clear portmap will cause (G,S)=(G,*), Delete the (G,S) + if((multi_acl_group[index].entry.port_map & (~portmap)) == multi_acl_group[count].entry.port_map) + return 1; //delete + + + //The following means there must be at least one bit clear wrong. Clear the (G,*) portmap. + if( ((multi_acl_group[index].entry.port_map & (~portmap)) & (multi_acl_group[count].entry.port_map)) + != (multi_acl_group[count].entry.port_map)) + return 0; + + return 2; //Normal update + } + return 0; +} +sw_error_t isis_igmp_sg_entry_set(a_uint32_t dev_id, fal_igmp_sg_entry_t * entry) +{ + int number, count; + int new_index=0; + sw_error_t rv; + int action = MULT_ACTION_SET; + int i=0; + + HSL_API_LOCK; + (void)isis_multicast_init(0); + aos_mem_zero(multi_acl_info, FAL_IGMP_SG_ENTRY_MAX * sizeof (multi_acl_info_t)); + aos_mem_zero(multi_acl_group, FAL_IGMP_SG_ENTRY_MAX * sizeof (multi_acl_info_t)); + MULTI_DEBUG("Before query: group=%x, source=%x, portmap=%x\n", entry->group.u.ip4_addr, entry->source.u.ip4_addr, entry->port_map); + //number is the total multicast ACL rules amount, stores in multi_acl_info[]; + number = isis_multicast_acl_query(); + if(number > FAL_IGMP_SG_ENTRY_MAX) + return SW_FAIL; + //count the total specific multicast group ACL rules, stores in multi_acl_group[]; count <=number + count = iterate_multicast_acl_group(number, entry); + //new_index-1 is the found entry index in multi_acl_group[], the real index is [new_index-1], 0 means no entry + new_index = mult_acl_has_entry(&entry->group, &entry->source); + + MULTI_DEBUG("Start entry set: number=%d, count=%d, new_index=%d, pm=%x\n", number, count, new_index, entry->port_map); + if( 0==multi_source_is_null(&entry->source) ) // new entry is (G, S) + { + MULTI_DEBUG("the new entry is (G,S)\n"); + if(count>0 && 0 == portmap_valid(entry, &(multi_acl_group[count-1].entry))) //specfic group entry exist,(G,S) or (G,*) + { + //return SW_NO_CHANGE; // The new portmap is Not valid + MULTI_DEBUG("KKK, modified 1 !!!\n"); + } + + if(0 == new_index) //new entry, need add + { +#if 0 + /*The method: + 1. predict if the portmap should be modified. + 2. add new acl rule with new portmap value. + */ + if((tmp_index = mult_acl_has_entry(&entry->group, NULL))>0) // (G, *) entry exist + { + /*Here the update should new (G, S) OR orignal (G,*) portmap, + be careful, entry's portmap value will be modified, so I use tmp_entry. + */ + memcpy(tmp_entry, entry, sizeof(fal_igmp_sg_entry_t)); + MULTI_DEBUG("Here, (G,*) exist! tmp_index=%d\n", tmp_index); + sw_multicast_acl_update(FAL_ACL_LIST_MULTICAST+1, tmp_index-1, tmp_entry, action); + + isis_multicast_acl_add(FAL_ACL_LIST_MULTICAST, tmp_entry); + return SW_OK; + } +#endif + isis_multicast_acl_add(FAL_ACL_LIST_MULTICAST, entry); + MULTI_DEBUG("Here, need add (G, S), portmap=%x\n", entry->port_map); + return SW_OK; + } + else + { + //Here update Just: the old exist entry portmap OR the new entry portmap + isis_multicast_acl_update(FAL_ACL_LIST_MULTICAST, new_index-1, entry, action); + return SW_OK; + } + } //end of memcmp + else // new entry is (G, *) + { + if(0 == new_index) //new entry, need add + { + isis_multicast_acl_add(FAL_ACL_LIST_MULTICAST+1, entry); + rv = SW_OK; + } + else if(new_index > 0) // (G, *) entry exist? + { + //Update exist (G, *) portmap with new portmap + MULTI_DEBUG("(G,*) exist, before update, new_index=%d\n", new_index ); + isis_multicast_acl_update(FAL_ACL_LIST_MULTICAST+1, new_index-1, entry, action); + rv = SW_OK; + } + + if(new_index>0&&count>1) //(G,S*) and (G,*) exist, new entry is (G,*) + { + for(i=count-2; i>=0&&i0) //only exist (G,S*) orignally + { + for(i=count-1; i>=0&&iport_map); + isis_multicast_acl_del(FAL_ACL_LIST_MULTICAST, i); + rv = SW_NO_MORE; + } + else + { + MULTI_DEBUG("2:Start update all (G,S),i=%d, portmap=%x\n", i, entry->port_map); + //Update all (G,S) entry portmap with new(G, *) portmap + isis_multicast_acl_update(FAL_ACL_LIST_MULTICAST, i, entry, action); + rv = SW_OK; + } + } + } + } + HSL_API_UNLOCK; + return rv; +} + +sw_error_t isis_igmp_sg_entry_clear(a_uint32_t dev_id, fal_igmp_sg_entry_t * entry) +{ + a_uint32_t number, count; + int new_index=0; + sw_error_t rv = SW_OK; + int action= MULT_ACTION_CLEAR; + int i=0; + int pm_type; + + HSL_API_LOCK; + (void)isis_multicast_init(0); + aos_mem_zero(multi_acl_info, FAL_IGMP_SG_ENTRY_MAX * sizeof (multi_acl_info_t)); + aos_mem_zero(multi_acl_group, FAL_IGMP_SG_ENTRY_MAX * sizeof (multi_acl_info_t)); + //number is the total multicast ACL rules amount, stores in multi_acl_info[]; + number = isis_multicast_acl_query(); + if(number > FAL_IGMP_SG_ENTRY_MAX) + return SW_FAIL; + + //count the total specific multicast group ACL rules, stores in multi_acl_group[]; count <=number + count = iterate_multicast_acl_group(number, entry); + if(count == 0) + return SW_OK; + + //new_index-1 is the found entry index in multi_acl_group[] + new_index = mult_acl_has_entry(&entry->group, &entry->source); + + MULTI_DEBUG("Start entry clear: number=%d, count=%d, new_index=%d\n", number, count, new_index); + if(0 == new_index || new_index > FAL_IGMP_SG_ENTRY_MAX ||count > FAL_IGMP_SG_ENTRY_MAX) //new entry, the user command is wrong + { + return SW_NO_SUCH; + } + + if( 0==multi_source_is_null(&entry->source) ) // new entry is (G, S) + { + if (portmap_null(new_index-1, entry->port_map)) + { + MULTI_DEBUG("KKK entry clear, new(G,S), with null portmap. \n"); + isis_multicast_acl_del(FAL_ACL_LIST_MULTICAST, new_index-1); + return SW_NO_MORE; + } + else + { + MULTI_DEBUG("KKK entry clear, new(G,S), with NOT null portmap. \n"); + /* If (G,*) doesn't exist, [count-1] is the last specfic group, maybe(G,*) */ + if(0 == multi_source_is_null(&(multi_acl_group[count-1].entry.source))) + { + isis_multicast_acl_update(FAL_ACL_LIST_MULTICAST, new_index-1, entry, action); + } + else //(G,*) exist + { + pm_type = portmap_clear_type(count-1, new_index-1, entry->port_map); + if(pm_type == 0) + return SW_NO_CHANGE; + else if(pm_type == 1) + { + isis_multicast_acl_del(FAL_ACL_LIST_MULTICAST, new_index-1); + return SW_NO_MORE; + } + else + { + //normal update; consider here...wangson + isis_multicast_acl_update(FAL_ACL_LIST_MULTICAST, new_index-1, entry, action); + } + } + } + return SW_OK; + } + else //clear entry is (G,*) + { + MULTI_DEBUG("Here, new_index[%d]>=0, new portmap to clear is %x\n", new_index, entry->port_map); + if (portmap_null(new_index-1, entry->port_map)) + { + isis_multicast_acl_del(FAL_ACL_LIST_MULTICAST+1, new_index-1); + rv = SW_NO_MORE; + } + else + { + MULTI_DEBUG("Update (G,*)!, new_index=%d, pm=%x\n", new_index, entry->port_map); + isis_multicast_acl_update(FAL_ACL_LIST_MULTICAST+1, new_index-1, entry, action); + } + MULTI_DEBUG("KKK, ready clear (G, S*), count=%d\n", count); +#if 0 + if(count>1) // (G, S*) entry exist, if count=1 here, only exist(G,*)entry + { + //count must >=2 + for(i=count-2; i>=0; i--) + { + if(portmap_null(i, entry->port_map)) + { + MULTI_DEBUG("portmap_null, i=%d\n", i); + isis_multicast_acl_del(FAL_ACL_LIST_MULTICAST, i); + rv = SW_NO_MORE; + } + else + { + //Update all (G,S) entry portmap with new(G, *) portmap + isis_multicast_acl_update(FAL_ACL_LIST_MULTICAST, i, entry, action); + rv = SW_OK; + } + } + } +#else + if(count>1) // (G, S*) entry exist, if count=1 here, only exist(G,*)entry + { + //count must >=2 + for(i=count-2; i>=0&&iport_map))) == + multi_acl_group[i].entry.port_map) + isis_multicast_acl_del(FAL_ACL_LIST_MULTICAST, i); + else + //Update all (G,S) entry portmap with new(G, *) portmap + isis_multicast_acl_update(FAL_ACL_LIST_MULTICAST, i, entry, action); + rv = SW_OK; + } + } +#endif + } + HSL_API_UNLOCK; + return rv; +} + +static void +print_ip4addr(char * param_name, a_uint32_t * buf, + a_uint32_t size) +{ + a_uint32_t i; + fal_ip4_addr_t ip4; + + ip4 = *((fal_ip4_addr_t *) buf); + aos_printk("%s", param_name); + for (i = 0; i < 3; i++) + { + aos_printk("%d.", (ip4 >> (24 - i * 8)) & 0xff); + } + aos_printk("%d", (ip4 & 0xff)); +} +static void +print_ip6addr(char * param_name, a_uint32_t * buf, + a_uint32_t size) +{ + a_uint32_t i; + fal_ip6_addr_t ip6; + + ip6 = *(fal_ip6_addr_t *) buf; + aos_printk("%s", param_name); + for (i = 0; i < 3; i++) + { + aos_printk("%x:%x:", (ip6.ul[i] >> 16) & 0xffff, ip6.ul[i] & 0xffff); + } + aos_printk("%x:%x", (ip6.ul[3] >> 16) & 0xffff, ip6.ul[3] & 0xffff); +} +sw_error_t isis_igmp_sg_entry_show(a_uint32_t dev_id) +{ + a_uint32_t number; + int i; + + HSL_API_LOCK; + (void)isis_multicast_init(0); + aos_mem_zero(multi_acl_info, FAL_IGMP_SG_ENTRY_MAX * sizeof (multi_acl_info_t)); + aos_mem_zero(multi_acl_group, FAL_IGMP_SG_ENTRY_MAX * sizeof (multi_acl_info_t)); + //number is the total multicast ACL rules amount, stores in multi_acl_info[]; + number = isis_multicast_acl_query(); + + for(i=0; i> 16) & 0xf) << 8); + } + else + { + *hw_addr = sw_addr & 0xfff; + } + + return SW_OK; +} + +static sw_error_t +_isis_ip_prvaddr_hw_to_sw(a_uint32_t dev_id, a_uint32_t hw_addr, + fal_ip4_addr_t * sw_addr) +{ + sw_error_t rv; + a_uint32_t data = 0, addr = 0; + + HSL_REG_FIELD_GET(rv, dev_id, PRVIP_CTL, 0, BASEADDR_SEL, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, PRVIP_CTL, 0, IP4_BASEADDR, + (a_uint8_t *) (&addr), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data) + { + *sw_addr = ((addr & 0xff) << 8) | (((addr >> 8) & 0xfff) << 8) + | (hw_addr & 0xff) | (((hw_addr >> 8) & 0xf) << 16); + } + else + { + *sw_addr = (addr << 12) | (hw_addr & 0xfff); + } + + return SW_OK; +} + +static sw_error_t +_isis_nat_counter_get(a_uint32_t dev_id, a_uint32_t cnt_id, + a_uint32_t counter[4]) +{ + sw_error_t rv; + a_uint32_t i, addr; + + addr = ISIS_NAT_COUTER_ADDR + (cnt_id << 4); + for (i = 0; i < 4; i++) + { + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(counter[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + addr += 4; + } + + return SW_OK; +} + +static sw_error_t +_isis_nat_entry_commit(a_uint32_t dev_id, a_uint32_t entry_type, a_uint32_t op) +{ + a_uint32_t busy = 1, i = 0x100, entry = 0; + sw_error_t rv; + + while (busy && --i) + { + HSL_REG_ENTRY_GET(rv, dev_id, HOST_ENTRY4, 0, (a_uint8_t *) (&entry), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + SW_GET_FIELD_BY_REG(HOST_ENTRY4, TBL_BUSY, busy, entry); + aos_udelay(500); + } + + if (i == 0) + { + printk("%s BUSY\n", __FUNCTION__); + return SW_BUSY; + } + + SW_SET_REG_BY_FIELD(HOST_ENTRY4, TBL_BUSY, 1, entry); + SW_SET_REG_BY_FIELD(HOST_ENTRY4, TBL_SEL, entry_type, entry); + SW_SET_REG_BY_FIELD(HOST_ENTRY4, ENTRY_FUNC, op, entry); + + HSL_REG_ENTRY_SET(rv, dev_id, HOST_ENTRY4, 0, (a_uint8_t *) (&entry), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + busy = 1; + i = 0x100; + while (busy && --i) + { + HSL_REG_ENTRY_GET(rv, dev_id, HOST_ENTRY4, 0, (a_uint8_t *) (&entry), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + SW_GET_FIELD_BY_REG(HOST_ENTRY4, TBL_BUSY, busy, entry); + aos_udelay(500); +#if 1 + if(ISIS_NAT_ENTRY_SEARCH == op && busy) break; +#endif + } + + if (i == 0) + { + printk("%s BUSY\n", __FUNCTION__); + return SW_BUSY; + } + + /* hardware requirement, we should delay... */ + if ((ISIS_NAT_ENTRY_FLUSH == op) && (ISIS_ENTRY_NAPT == entry_type)) + { + aos_mdelay(10); + } + + /* hardware requirement, we should read again... */ + HSL_REG_ENTRY_GET(rv, dev_id, HOST_ENTRY4, 0, (a_uint8_t *) (&entry), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(HOST_ENTRY4, TBL_STAUS, busy, entry); + if (!busy) + { + if (ISIS_NAT_ENTRY_NEXT == op) + { + return SW_NO_MORE; + } + else if (ISIS_NAT_ENTRY_SEARCH == op) + { + return SW_NOT_FOUND; + } + else + { + return SW_FAIL; + } + } + + return SW_OK; +} + +static sw_error_t +_isis_nat_sw_to_hw(a_uint32_t dev_id, fal_nat_entry_t * entry, a_uint32_t reg[]) +{ + sw_error_t rv; + a_uint32_t data; + + if (FAL_NAT_ENTRY_TRANS_IPADDR_INDEX & entry->flags) + { + return SW_BAD_PARAM; + } + + reg[0] = entry->trans_addr; + + if (FAL_NAT_ENTRY_PORT_CHECK & entry->flags) + { + SW_SET_REG_BY_FIELD(NAT_ENTRY2, PORT_EN, 1, reg[2]); + SW_SET_REG_BY_FIELD(NAT_ENTRY1, PORT_RANGE, entry->port_range, reg[1]); + if (ISIS_NAT_PORT_NUM < entry->port_range) + { + return SW_BAD_PARAM; + } + SW_SET_REG_BY_FIELD(NAT_ENTRY1, PORT_NUM, entry->port_num, reg[1]); + } + else + { + SW_SET_REG_BY_FIELD(NAT_ENTRY2, PORT_EN, 0, reg[2]); + } + + rv = _isis_ip_prvaddr_sw_to_hw(dev_id, entry->src_addr, &data); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(NAT_ENTRY1, PRV_IPADDR0, data, reg[1]); + SW_SET_REG_BY_FIELD(NAT_ENTRY2, PRV_IPADDR1, (data >> 8), reg[2]); + + if (FAL_MAC_FRWRD == entry->action) + { + if (A_TRUE == entry->mirror_en) + { + SW_SET_REG_BY_FIELD(NAT_ENTRY2, ACTION, 0, reg[2]); + } + else + { + SW_SET_REG_BY_FIELD(NAT_ENTRY2, ACTION, 3, reg[2]); + } + } + else if (FAL_MAC_CPY_TO_CPU == entry->action) + { + SW_SET_REG_BY_FIELD(NAT_ENTRY2, ACTION, 2, reg[2]); + } + else if (FAL_MAC_RDT_TO_CPU == entry->action) + { + SW_SET_REG_BY_FIELD(NAT_ENTRY2, ACTION, 1, reg[2]); + } + else + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == entry->counter_en) + { + SW_SET_REG_BY_FIELD(NAT_ENTRY2, CNT_EN, 1, reg[2]); + SW_SET_REG_BY_FIELD(NAT_ENTRY2, CNT_IDX, entry->counter_id, reg[2]); + } + + if (FAL_NAT_ENTRY_PROTOCOL_ANY & entry->flags) + { + data = 3; + } + else if ((FAL_NAT_ENTRY_PROTOCOL_TCP & entry->flags) + && (FAL_NAT_ENTRY_PROTOCOL_UDP & entry->flags)) + { + data = 2; + } + else if (FAL_NAT_ENTRY_PROTOCOL_TCP & entry->flags) + { + data = 0; + } + else if (FAL_NAT_ENTRY_PROTOCOL_UDP & entry->flags) + { + data = 1; + } + else + { + return SW_BAD_PARAM; + } + + SW_SET_REG_BY_FIELD(NAT_ENTRY2, PRO_TYP, data, reg[2]); + + SW_SET_REG_BY_FIELD(NAT_ENTRY2, HASH_KEY, entry->slct_idx, reg[2]); + + SW_SET_REG_BY_FIELD(NAT_ENTRY2, ENTRY_VALID, 1, reg[2]); + SW_SET_REG_BY_FIELD(HOST_ENTRY4, TBL_IDX, entry->entry_id, reg[4]); + return SW_OK; +} + +static sw_error_t +_isis_nat_hw_to_sw(a_uint32_t dev_id, a_uint32_t reg[], fal_nat_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t data, cnt[4] = {0}; + + entry->trans_addr = reg[0]; + + SW_GET_FIELD_BY_REG(NAT_ENTRY2, PORT_EN, data, reg[2]); + if (data) + { + entry->flags |= FAL_NAT_ENTRY_PORT_CHECK; + SW_GET_FIELD_BY_REG(NAT_ENTRY1, PORT_RANGE, data, reg[1]); + entry->port_range = data; + SW_GET_FIELD_BY_REG(NAT_ENTRY1, PORT_NUM, data, reg[1]); + entry->port_num = data; + } + + SW_GET_FIELD_BY_REG(NAT_ENTRY1, PRV_IPADDR0, data, reg[1]); + entry->src_addr = data; + SW_GET_FIELD_BY_REG(NAT_ENTRY2, PRV_IPADDR1, data, reg[2]); + data = (entry->src_addr & 0xff) | (data << 8); + + rv = _isis_ip_prvaddr_hw_to_sw(dev_id, data, &(entry->src_addr)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(NAT_ENTRY2, ACTION, data, reg[2]); + entry->action = FAL_MAC_FRWRD; + if (0 == data) + { + entry->mirror_en = A_TRUE; + } + else if (2 == data) + { + entry->action = FAL_MAC_CPY_TO_CPU; + } + else if (1 == data) + { + entry->action = FAL_MAC_RDT_TO_CPU; + } + + SW_GET_FIELD_BY_REG(NAT_ENTRY2, CNT_EN, data, reg[2]); + if (data) + { + entry->counter_en = A_TRUE; + SW_GET_FIELD_BY_REG(NAT_ENTRY2, CNT_IDX, entry->counter_id, reg[2]); + + rv = _isis_nat_counter_get(dev_id, entry->counter_id, cnt); + SW_RTN_ON_ERROR(rv); + + entry->ingress_packet = cnt[0]; + entry->ingress_byte = cnt[1]; + entry->egress_packet = cnt[2]; + entry->egress_byte = cnt[3]; + } + else + { + entry->counter_en = A_FALSE; + } + + SW_GET_FIELD_BY_REG(NAT_ENTRY2, PRO_TYP, data, reg[2]); + if (3 == data) + { + entry->flags |= FAL_NAT_ENTRY_PROTOCOL_ANY; + } + else if (2 == data) + { + entry->flags |= FAL_NAT_ENTRY_PROTOCOL_TCP; + entry->flags |= FAL_NAT_ENTRY_PROTOCOL_UDP; + } + else if (1 == data) + { + entry->flags |= FAL_NAT_ENTRY_PROTOCOL_UDP; + } + else if (0 == data) + { + entry->flags |= FAL_NAT_ENTRY_PROTOCOL_TCP; + } + + SW_GET_FIELD_BY_REG(NAT_ENTRY2, HASH_KEY, data, reg[2]); + entry->slct_idx = data; + + return SW_OK; +} + +static sw_error_t +_isis_napt_sw_to_hw(a_uint32_t dev_id, fal_napt_entry_t * entry, + a_uint32_t reg[]) +{ + sw_error_t rv; + a_uint32_t data; + + reg[0] = entry->dst_addr; + + SW_SET_REG_BY_FIELD(NAPT_ENTRY1, DST_PORT, entry->dst_port, reg[1]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY1, SRC_PORT, entry->src_port, reg[1]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY2, TRANS_PORT, entry->trans_port, reg[2]); + + rv = _isis_ip_prvaddr_sw_to_hw(dev_id, entry->src_addr, &data); + SW_RTN_ON_ERROR(rv); + SW_SET_REG_BY_FIELD(NAPT_ENTRY2, SRC_IPADDR, data, reg[2]); + + if (!(FAL_NAT_ENTRY_TRANS_IPADDR_INDEX & entry->flags)) + { + return SW_BAD_PARAM; + } + SW_SET_REG_BY_FIELD(NAPT_ENTRY2, TRANS_IPADDR, entry->trans_addr, reg[2]); + + if (FAL_MAC_FRWRD == entry->action) + { + if (A_TRUE == entry->mirror_en) + { + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, ACTION, 0, reg[3]); + } + else + { + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, ACTION, 3, reg[3]); + } + } + else if (FAL_MAC_CPY_TO_CPU == entry->action) + { + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, ACTION, 2, reg[3]); + } + else if (FAL_MAC_RDT_TO_CPU == entry->action) + { + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, ACTION, 1, reg[3]); + } + else + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == entry->counter_en) + { + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, CNT_EN, 1, reg[3]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, CNT_IDX, entry->counter_id, reg[3]); + } + + data = 2; + if (FAL_NAT_ENTRY_PROTOCOL_TCP & entry->flags) + { + data = 0; + } + else if (FAL_NAT_ENTRY_PROTOCOL_UDP & entry->flags) + { + data = 1; + } + else if (FAL_NAT_ENTRY_PROTOCOL_PPTP & entry->flags) + { + data = 3; + } + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, PROT_TYP, data, reg[3]); + + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, AGE_FLAG, entry->status, reg[3]); + return SW_OK; +} + +static sw_error_t +_isis_napt_hw_to_sw(a_uint32_t dev_id, a_uint32_t reg[], + fal_napt_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t data, cnt[4] = {0}; + + entry->dst_addr = reg[0]; + + SW_GET_FIELD_BY_REG(NAPT_ENTRY1, DST_PORT, entry->dst_port, reg[1]); + SW_GET_FIELD_BY_REG(NAPT_ENTRY1, SRC_PORT, entry->src_port, reg[1]); + SW_GET_FIELD_BY_REG(NAPT_ENTRY2, TRANS_PORT, entry->trans_port, reg[2]); + + SW_GET_FIELD_BY_REG(NAPT_ENTRY2, SRC_IPADDR, data, reg[2]); + rv = _isis_ip_prvaddr_hw_to_sw(dev_id, data, &(entry->src_addr)); + SW_RTN_ON_ERROR(rv); + + entry->flags |= FAL_NAT_ENTRY_TRANS_IPADDR_INDEX; + SW_GET_FIELD_BY_REG(NAPT_ENTRY2, TRANS_IPADDR, entry->trans_addr, reg[2]); + + SW_GET_FIELD_BY_REG(NAPT_ENTRY3, ACTION, data, reg[3]); + entry->action = FAL_MAC_FRWRD; + if (0 == data) + { + entry->mirror_en = A_TRUE; + } + else if (2 == data) + { + entry->action = FAL_MAC_CPY_TO_CPU; + } + else if (1 == data) + { + entry->action = FAL_MAC_RDT_TO_CPU; + } + + SW_GET_FIELD_BY_REG(NAPT_ENTRY3, CNT_EN, data, reg[3]); + if (data) + { + entry->counter_en = A_TRUE; + SW_GET_FIELD_BY_REG(NAPT_ENTRY3, CNT_IDX, entry->counter_id, reg[3]); + + rv = _isis_nat_counter_get(dev_id, entry->counter_id, cnt); + SW_RTN_ON_ERROR(rv); + + entry->ingress_packet = cnt[0]; + entry->ingress_byte = cnt[1]; + entry->egress_packet = cnt[2]; + entry->egress_byte = cnt[3]; + } + else + { + entry->counter_en = A_FALSE; + } + + SW_GET_FIELD_BY_REG(NAPT_ENTRY3, PROT_TYP, data, reg[3]); + if (0 == data) + { + entry->flags |= FAL_NAT_ENTRY_PROTOCOL_TCP; + } + else if (1 == data) + { + entry->flags |= FAL_NAT_ENTRY_PROTOCOL_UDP; + } + else if (3 == data) + { + entry->flags |= FAL_NAT_ENTRY_PROTOCOL_PPTP; + } + + SW_GET_FIELD_BY_REG(NAPT_ENTRY3, AGE_FLAG, entry->status, reg[3]); + return SW_OK; +} + +static sw_error_t +_isis_nat_down_to_hw(a_uint32_t dev_id, a_uint32_t reg[]) +{ + sw_error_t rv; + a_uint32_t i, addr; + + for (i = 0; i < 5; i++) + { + addr = ISIS_HOST_ENTRY_DATA0_ADDR + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®[i]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +static sw_error_t +_isis_nat_up_to_sw(a_uint32_t dev_id, a_uint32_t reg[]) +{ + sw_error_t rv; + a_uint32_t i, addr; + + for (i = 0; i < 5; i++) + { + addr = ISIS_HOST_ENTRY_DATA0_ADDR + (i << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®[i]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +static sw_error_t +_isis_nat_add(a_uint32_t dev_id, fal_nat_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t i, reg[5] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + for (i = 0; i < ISIS_NAT_ENTRY_NUM; i++) + { + if (!(isis_nat_snap[dev_id] & (0x1 << i))) + { + break; + } + } + + if (ISIS_NAT_ENTRY_NUM == i) + { + return SW_NO_RESOURCE; + } + + entry->entry_id = i; + + rv = _isis_nat_sw_to_hw(dev_id, entry, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_nat_entry_commit(dev_id, ISIS_ENTRY_NAT, ISIS_NAT_ENTRY_ADD); + SW_RTN_ON_ERROR(rv); + + isis_nat_snap[dev_id] |= (0x1 << i); + entry->entry_id = i; + return SW_OK; +} + +static sw_error_t +_isis_nat_del(a_uint32_t dev_id, a_uint32_t del_mode, fal_nat_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t reg[5] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_NAT_ENTRY_ID_EN & del_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY4, ENTRY_FUNC, ISIS_NAT_ENTRY_DEL, reg[4]); + SW_SET_REG_BY_FIELD(HOST_ENTRY4, TBL_IDX, entry->entry_id, reg[4]); + + rv = _isis_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_nat_entry_commit(dev_id, ISIS_ENTRY_NAT, ISIS_NAT_ENTRY_DEL); + SW_RTN_ON_ERROR(rv); + + isis_nat_snap[dev_id] &= (~(0x1 << entry->entry_id)); + } + else + { + rv = _isis_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_nat_entry_commit(dev_id, ISIS_ENTRY_NAT, ISIS_NAT_ENTRY_FLUSH); + SW_RTN_ON_ERROR(rv); + + isis_nat_snap[dev_id] = 0; + } + + return SW_OK; +} + +static sw_error_t +_isis_nat_get(a_uint32_t dev_id, a_uint32_t get_mode, fal_nat_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t reg[5] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_NAT_ENTRY_ID_EN != get_mode) + { + return SW_NOT_SUPPORTED; + } + + if (!(isis_nat_snap[dev_id] & (0x1 << entry->entry_id))) + { + return SW_NOT_FOUND; + } + + SW_SET_REG_BY_FIELD(HOST_ENTRY4, TBL_IDX, entry->entry_id, reg[4]); + + rv = _isis_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_nat_entry_commit(dev_id, ISIS_ENTRY_NAT, ISIS_NAT_ENTRY_SEARCH); + SW_RTN_ON_ERROR(rv); + + rv = _isis_nat_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_nat_hw_to_sw(dev_id, reg, entry); + return rv; +} + +static sw_error_t +_isis_nat_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_nat_entry_t * nat_entry) +{ + a_uint32_t i, idx, reg[5] = { 0 }; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_NEXT_ENTRY_FIRST_ID == nat_entry->entry_id) + { + idx = 0; + } + else + { + if ((ISIS_NAT_ENTRY_NUM - 1) == nat_entry->entry_id) + { + return SW_NO_MORE; + } + else + { + idx = nat_entry->entry_id + 1; + } + } + + for (i = idx; i < ISIS_NAT_ENTRY_NUM; i++) + { + if (isis_nat_snap[dev_id] & (0x1 << i)) + { + break; + } + } + + if (ISIS_NAT_ENTRY_NUM == i) + { + return SW_NO_MORE; + } + + SW_SET_REG_BY_FIELD(HOST_ENTRY4, TBL_IDX, i, reg[4]); + + rv = _isis_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_nat_entry_commit(dev_id, ISIS_ENTRY_NAT, ISIS_NAT_ENTRY_SEARCH); + SW_RTN_ON_ERROR(rv); + + rv = _isis_nat_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + aos_mem_zero(nat_entry, sizeof (fal_nat_entry_t)); + + rv = _isis_nat_hw_to_sw(dev_id, reg, nat_entry); + SW_RTN_ON_ERROR(rv); + + nat_entry->entry_id = i; + return SW_OK; +} + +static sw_error_t +_isis_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; + a_uint32_t reg[5] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (!(isis_nat_snap[dev_id] & (0x1 << entry_id))) + { + return SW_NOT_FOUND; + } + + SW_SET_REG_BY_FIELD(HOST_ENTRY4, TBL_IDX, entry_id, reg[4]); + + rv = _isis_nat_entry_commit(dev_id, ISIS_ENTRY_NAT, ISIS_NAT_ENTRY_SEARCH); + SW_RTN_ON_ERROR(rv); + + rv = _isis_nat_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(NAT_ENTRY2, CNT_EN, 0, reg[2]); + } + else if (A_TRUE == enable) + { + SW_SET_REG_BY_FIELD(NAT_ENTRY2, CNT_EN, 1, reg[2]); + SW_SET_REG_BY_FIELD(NAT_ENTRY2, CNT_IDX, cnt_id, reg[2]); + } + else + { + return SW_BAD_PARAM; + } + + /* needn't set TBL_IDX, keep hardware register value */ + + rv = _isis_nat_entry_commit(dev_id, ISIS_ENTRY_NAT, ISIS_NAT_ENTRY_DEL); + SW_RTN_ON_ERROR(rv); + + rv = _isis_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + /* needn't set TBL_IDX, keep hardware register value */ + + rv = _isis_nat_entry_commit(dev_id, ISIS_ENTRY_NAT, ISIS_NAT_ENTRY_ADD); + return rv; +} + +static sw_error_t +_isis_napt_add(a_uint32_t dev_id, fal_napt_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t reg[5] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_napt_sw_to_hw(dev_id, entry, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_nat_entry_commit(dev_id, ISIS_ENTRY_NAPT, ISIS_NAT_ENTRY_ADD); + SW_RTN_ON_ERROR(rv); + + rv = _isis_nat_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(HOST_ENTRY4, TBL_IDX, entry->entry_id, reg[4]); + return SW_OK; +} + +static sw_error_t +_isis_napt_del(a_uint32_t dev_id, a_uint32_t del_mode, fal_napt_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t data, reg[5] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_NAT_ENTRY_ID_EN & del_mode) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_NAT_ENTRY_KEY_EN & del_mode) + { + rv = _isis_napt_sw_to_hw(dev_id, entry, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_nat_entry_commit(dev_id, ISIS_ENTRY_NAPT, ISIS_NAT_ENTRY_DEL); + SW_RTN_ON_ERROR(rv); + + rv = _isis_nat_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(HOST_ENTRY4, TBL_IDX, entry->entry_id, reg[4]); + return SW_OK; + } + else + { + if (FAL_NAT_ENTRY_PUBLIC_IP_EN & del_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY4, SPEC_PIP, 1, reg[4]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY2, TRANS_IPADDR, entry->trans_addr, reg[2]); + } + + if (FAL_NAT_ENTRY_SOURCE_IP_EN & del_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY4, SPEC_SIP, 1, reg[4]); + rv = _isis_ip_prvaddr_sw_to_hw(dev_id, entry->src_addr, &data); + SW_RTN_ON_ERROR(rv); + SW_SET_REG_BY_FIELD(NAPT_ENTRY2, SRC_IPADDR, data, reg[2]); + } + + if (FAL_NAT_ENTRY_AGE_EN & del_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY4, SPEC_STATUS, 1, reg[4]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, AGE_FLAG, entry->status, reg[3]); + } + + rv = _isis_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_nat_entry_commit(dev_id, ISIS_ENTRY_NAPT, ISIS_NAT_ENTRY_FLUSH); + return rv; + } +} + +static sw_error_t +_isis_napt_get(a_uint32_t dev_id, a_uint32_t get_mode, fal_napt_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t found, age, reg[5] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + +#if 0 + if (FAL_NAT_ENTRY_ID_EN != get_mode) + { + return SW_NOT_SUPPORTED; + } + + SW_SET_REG_BY_FIELD(HOST_ENTRY4, TBL_IDX, entry->entry_id, reg[4]); +#else + rv = _isis_napt_sw_to_hw(dev_id, entry, reg); + SW_RTN_ON_ERROR(rv); +#endif + + rv = _isis_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_nat_entry_commit(dev_id, ISIS_ENTRY_NAPT, ISIS_NAT_ENTRY_SEARCH); + SW_RTN_ON_ERROR(rv); + + rv = _isis_nat_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(HOST_ENTRY4, TBL_STAUS, found, reg[4]); + SW_GET_FIELD_BY_REG(NAPT_ENTRY3, AGE_FLAG, age, reg[3]); + if (found && age) + { + found = 1; + } + else + { + found = 0; + } + + rv = _isis_napt_hw_to_sw(dev_id, reg, entry); + SW_RTN_ON_ERROR(rv); + + if (!found) + { + return SW_NOT_FOUND; + } + + SW_GET_FIELD_BY_REG(HOST_ENTRY4, TBL_IDX, entry->entry_id, reg[4]); + return SW_OK; +} + +static sw_error_t +_isis_napt_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_napt_entry_t * napt_entry) +{ + a_uint32_t data, idx, reg[5] = { 0 }; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_NEXT_ENTRY_FIRST_ID == napt_entry->entry_id) + { + idx = ISIS_NAPT_ENTRY_NUM - 1; + } + else + { + if ((ISIS_NAPT_ENTRY_NUM - 1) == napt_entry->entry_id) + { + return SW_NO_MORE; + } + else + { + idx = napt_entry->entry_id; + } + } + + if (FAL_NAT_ENTRY_PUBLIC_IP_EN & next_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY4, SPEC_PIP, 1, reg[4]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY2, TRANS_IPADDR, napt_entry->trans_addr, reg[2]); + } + + if (FAL_NAT_ENTRY_SOURCE_IP_EN & next_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY4, SPEC_SIP, 1, reg[4]); + rv = _isis_ip_prvaddr_sw_to_hw(dev_id, napt_entry->src_addr, &data); + SW_RTN_ON_ERROR(rv); + SW_SET_REG_BY_FIELD(NAPT_ENTRY2, SRC_IPADDR, data, reg[2]); + } + + if (FAL_NAT_ENTRY_AGE_EN & next_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY4, SPEC_STATUS, 1, reg[4]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, AGE_FLAG, napt_entry->status, reg[3]); + } + + SW_SET_REG_BY_FIELD(HOST_ENTRY4, TBL_IDX, idx, reg[4]); + + rv = _isis_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_nat_entry_commit(dev_id, ISIS_ENTRY_NAPT, ISIS_NAT_ENTRY_NEXT); + SW_RTN_ON_ERROR(rv); + + rv = _isis_nat_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + aos_mem_zero(napt_entry, sizeof (fal_nat_entry_t)); + + rv = _isis_napt_hw_to_sw(dev_id, reg, napt_entry); + SW_RTN_ON_ERROR(rv); + +#if 0 + a_uint32_t temp=0, complete=0; + + HSL_REG_ENTRY_GET(rv, dev_id, HOST_ENTRY4, 0, (a_uint8_t *) (&temp), + sizeof (a_uint32_t)); + + SW_GET_FIELD_BY_REG(HOST_ENTRY4, TBL_STAUS, complete, temp); + + if (!complete) + { + return SW_NO_MORE; + } +#endif + + SW_GET_FIELD_BY_REG(HOST_ENTRY4, TBL_IDX, napt_entry->entry_id, reg[4]); + return SW_OK; +} + +static sw_error_t +_isis_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; + a_uint32_t reg[5] = { 0 }, tbl_idx; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + tbl_idx = (entry_id - 1) & 0x3ff; + SW_SET_REG_BY_FIELD(HOST_ENTRY4, TBL_IDX, tbl_idx, reg[4]); + + rv = _isis_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_nat_entry_commit(dev_id, ISIS_ENTRY_NAPT, ISIS_NAT_ENTRY_NEXT); + if (SW_OK != rv) + { + return SW_NOT_FOUND; + } + + rv = _isis_nat_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(HOST_ENTRY4, TBL_IDX, tbl_idx, reg[4]); + if (entry_id != tbl_idx) + { + return SW_NOT_FOUND; + } + + if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, CNT_EN, 0, reg[3]); + } + else if (A_TRUE == enable) + { + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, CNT_EN, 1, reg[3]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, CNT_IDX, cnt_id, reg[3]); + } + else + { + return SW_BAD_PARAM; + } + + rv = _isis_nat_entry_commit(dev_id, ISIS_ENTRY_NAPT, ISIS_NAT_ENTRY_DEL); + SW_RTN_ON_ERROR(rv); + + reg[4] = 0x0; + rv = _isis_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_nat_entry_commit(dev_id, ISIS_ENTRY_NAPT, ISIS_NAT_ENTRY_ADD); + return rv; +} + +static sw_error_t +_isis_nat_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, NAT_CTRL, 0, NAT_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_nat_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, NAT_CTRL, 0, NAT_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return rv; +} + +static sw_error_t +_isis_napt_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, NAT_CTRL, 0, NAPT_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_napt_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, NAT_CTRL, 0, NAPT_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return rv; +} + +static sw_error_t +_isis_napt_mode_set(a_uint32_t dev_id, fal_napt_mode_t mode) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_NAPT_FULL_CONE == mode) + { + data = 0; + } + else if (FAL_NAPT_STRICT_CONE == mode) + { + data = 1; + } + else if ((FAL_NAPT_PORT_STRICT == mode) + || (FAL_NAPT_SYNMETRIC == mode)) + { + data = 2; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, NAT_CTRL, 0, NAPT_MODE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_napt_mode_get(a_uint32_t dev_id, fal_napt_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, NAT_CTRL, 0, NAPT_MODE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0 == data) + { + *mode = FAL_NAPT_FULL_CONE; + } + else if (1 == data) + { + *mode = FAL_NAPT_STRICT_CONE; + } + else + { + *mode = FAL_NAPT_PORT_STRICT; + } + + return SW_OK; +} + +static sw_error_t +_isis_nat_hash_mode_set(a_uint32_t dev_id, a_uint32_t mode) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if ((FAL_NAT_HASH_KEY_PORT & mode) + && (FAL_NAT_HASH_KEY_IPADDR & mode)) + { + data = 2; + } + else if (FAL_NAT_HASH_KEY_PORT & mode) + { + data = 0; + } + else if (FAL_NAT_HASH_KEY_IPADDR & mode) + { + data = 1; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, NAT_CTRL, 0, NAT_HASH_MODE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_nat_hash_mode_get(a_uint32_t dev_id, a_uint32_t * mode) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, NAT_CTRL, 0, NAT_HASH_MODE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *mode = 0; + if (0 == data) + { + *mode = FAL_NAT_HASH_KEY_PORT; + } + else if (1 == data) + { + *mode = FAL_NAT_HASH_KEY_IPADDR; + } + else if (2 == data) + { + *mode = FAL_NAT_HASH_KEY_PORT; + *mode |= FAL_NAT_HASH_KEY_IPADDR; + } + + return SW_OK; +} + +static sw_error_t +_isis_nat_prv_base_addr_set(a_uint32_t dev_id, fal_ip4_addr_t addr) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, PRVIP_CTL, 0, BASEADDR_SEL, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data) + { + data = (((addr >> 20) & 0xfff) << 8) | ((addr >> 8) & 0xff); + } + else + { + data = (addr >> 12) & 0xfffff; + } + + HSL_REG_FIELD_SET(rv, dev_id, PRVIP_CTL, 0, IP4_BASEADDR, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, OFFLOAD_PRVIP_CTL, 0, IP4_BASEADDR, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_nat_prv_base_addr_get(a_uint32_t dev_id, fal_ip4_addr_t * addr) +{ + sw_error_t rv; + a_uint32_t data = 0, tmp = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, PRVIP_CTL, 0, BASEADDR_SEL, + (a_uint8_t *) (&tmp), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, PRVIP_CTL, 0, IP4_BASEADDR, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (tmp) + { + *addr = ((data & 0xff) << 8) | (((data >> 8) & 0xfff) << 20); + } + else + { + *addr = (data & 0xfffff) << 12; + } + + return SW_OK; +} + +#if 0 +static sw_error_t +_isis_nat_psr_prv_base_addr_set(a_uint32_t dev_id, fal_ip4_addr_t addr) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, PRVIP_CTL, 0, BASEADDR_SEL, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data) + { + data = (((addr >> 20) & 0xfff) << 8) | ((addr >> 8) & 0xff); + } + else + { + data = (addr >> 12) & 0xfffff; + } + + HSL_REG_FIELD_SET(rv, dev_id, PRVIP_CTL, 0, IP4_BASEADDR, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_nat_psr_prv_base_addr_get(a_uint32_t dev_id, fal_ip4_addr_t * addr) +{ + sw_error_t rv; + a_uint32_t data, tmp = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, PRVIP_CTL, 0, BASEADDR_SEL, + (a_uint8_t *) (&tmp), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, PRVIP_CTL, 0, IP4_BASEADDR, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (tmp) + { + *addr = ((data & 0xff) << 8) | (((data >> 8) & 0xfff) << 20); + } + else + { + *addr = (data & 0xfffff) << 12; + } + + return SW_OK; +} +#endif + +static sw_error_t +_isis_nat_prv_addr_mode_set(a_uint32_t dev_id, a_bool_t map_en) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == map_en) + { + data = 1; + } + else if (A_FALSE == map_en) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PRVIP_CTL, 0, BASEADDR_SEL, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_nat_prv_addr_mode_get(a_uint32_t dev_id, a_bool_t * map_en) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, PRVIP_CTL, 0, BASEADDR_SEL, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data) + { + *map_en = A_TRUE; + } + else + { + *map_en = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isis_nat_pub_addr_commit(a_uint32_t dev_id, fal_nat_pub_addr_t * entry, + a_uint32_t op, a_uint32_t * empty) +{ + a_uint32_t index, addr, data, tbl[2] = { 0 }; + sw_error_t rv; + + *empty = ISIS_PUB_ADDR_NUM; + for (index = 0; index < ISIS_PUB_ADDR_NUM; index++) + { + addr = ISIS_PUB_ADDR_TBL1_ADDR + (index << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[1])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PUB_ADDR1, ADDR_VALID, data, tbl[1]); + if (data) + { + addr = ISIS_PUB_ADDR_TBL0_ADDR + (index << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[0])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (!aos_mem_cmp + ((void *) &(entry->pub_addr), (void *) &(tbl[0]), + sizeof (fal_ip4_addr_t))) + { + if (ISIS_NAT_ENTRY_DEL == op) + { + addr = ISIS_PUB_ADDR_TBL1_ADDR + (index << 4); + tbl[1] = 0; + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[1])), + sizeof (a_uint32_t)); + *empty = index; + return rv; + } + else if (ISIS_NAT_ENTRY_ADD == op) + { + entry->entry_id = index; + return SW_ALREADY_EXIST; + } + } + } + else + { + *empty = index; + } + } + + return SW_NOT_FOUND; +} + +static sw_error_t +_isis_nat_pub_addr_add(a_uint32_t dev_id, fal_nat_pub_addr_t * entry) +{ + sw_error_t rv; + a_uint32_t i, empty, addr, data = 0, tbl[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + tbl[0] = entry->pub_addr; + tbl[1] = 1; + + rv = _isis_nat_pub_addr_commit(dev_id, entry, ISIS_NAT_ENTRY_ADD, &empty); + if (SW_ALREADY_EXIST == rv) + { + return rv; + } + + if (ISIS_PUB_ADDR_NUM == empty) + { + return SW_NO_RESOURCE; + } + + for (i = 0; i < 1; i++) + { + addr = ISIS_PUB_ADDR_EDIT0_ADDR + (empty << 4) + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[i])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + addr = ISIS_PUB_ADDR_OFFLOAD_ADDR + (empty << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[0])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + addr = ISIS_PUB_ADDR_VALID_ADDR; + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data |= (0x1 << empty); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + for (i = 0; i < 2; i++) + { + addr = ISIS_PUB_ADDR_TBL0_ADDR + (empty << 4) + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[i])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + entry->entry_id = empty; + return SW_OK; +} + +static sw_error_t +_isis_nat_pub_addr_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_nat_pub_addr_t * entry) +{ + sw_error_t rv; + a_uint32_t empty, addr, data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + rv = _isis_nat_pub_addr_commit(dev_id, entry, ISIS_NAT_ENTRY_DEL, &empty); + SW_RTN_ON_ERROR(rv); + + addr = ISIS_PUB_ADDR_VALID_ADDR; + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data &= (~(0x1 << empty)); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_isis_nat_pub_addr_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_nat_pub_addr_t * entry) +{ + sw_error_t rv; + a_uint32_t data, addr, idx, index, tbl[2] = {0}; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_NEXT_ENTRY_FIRST_ID == entry->entry_id) + { + idx = 0; + } + else + { + if ((ISIS_PUB_ADDR_NUM - 1) == entry->entry_id) + { + return SW_NO_MORE; + } + else + { + idx = entry->entry_id + 1; + } + } + + for (index = idx; index < ISIS_PUB_ADDR_NUM; index++) + { + addr = ISIS_PUB_ADDR_TBL1_ADDR + (index << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[1])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PUB_ADDR1, ADDR_VALID, data, tbl[1]); + if (data) + { + break; + } + } + + if (ISIS_PUB_ADDR_NUM == index) + { + return SW_NO_MORE; + } + + addr = ISIS_PUB_ADDR_TBL0_ADDR + (index << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[0])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + entry->entry_id = index; + entry->pub_addr = tbl[0]; + + return SW_OK; +} + +static sw_error_t +_isis_nat_unk_session_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_MAC_DROP == cmd) + { + data = 1; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + data = 0; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, NAT_NOT_FOUND_DROP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_nat_unk_session_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, NAT_NOT_FOUND_DROP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0 == data) + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + else + { + *cmd = FAL_MAC_DROP; + } + + return SW_OK; +} + +sw_error_t +isis_nat_reset(a_uint32_t dev_id) +{ + sw_error_t rv; + a_uint32_t index, addr, data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + isis_nat_snap[dev_id] = 0; + + HSL_REG_ENTRY_SET(rv, dev_id, HOST_ENTRY4, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = _isis_nat_entry_commit(dev_id, ISIS_ENTRY_NAT, ISIS_NAT_ENTRY_FLUSH); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, HOST_ENTRY4, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = _isis_nat_entry_commit(dev_id, ISIS_ENTRY_NAPT, ISIS_NAT_ENTRY_FLUSH); + SW_RTN_ON_ERROR(rv); + + for (index = 0; index < ISIS_PUB_ADDR_NUM; index++) + { + addr = ISIS_PUB_ADDR_TBL1_ADDR + (index << 4); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +/** + * @brief Add one NAT entry to one particular device. + * @details Comments: + Before NAT entry added ip4 private base address must be set + at first. + In parameter nat_entry entry flags must be set + Hardware entry id will be returned. + * @param[in] dev_id device id + * @param[in] nat_entry NAT entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_nat_add(a_uint32_t dev_id, fal_nat_entry_t * nat_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_nat_add(dev_id, nat_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Del NAT entries from one particular device. + * @param[in] dev_id device id + * @param[in] del_mode NAT entry delete operation mode + * @param[in] nat_entry NAT entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_nat_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_nat_entry_t * nat_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_nat_del(dev_id, del_mode, nat_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get one NAT entry from one particular device. + * @param[in] dev_id device id + * @param[in] get_mode NAT entry get operation mode + * @param[in] nat_entry NAT entry parameter + * @param[out] nat_entry NAT entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_nat_get(a_uint32_t dev_id, a_uint32_t get_mode, + fal_nat_entry_t * nat_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_nat_get(dev_id, get_mode, nat_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Next NAT entries from one particular device. + * @param[in] dev_id device id + * @param[in] next_mode NAT entry next operation mode + * @param[in] nat_entry NAT entry parameter + * @param[out] nat_entry NAT entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_nat_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_nat_entry_t * nat_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_nat_next(dev_id, next_mode, nat_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Bind one counter entry to one NAT entry to one particular device. + * @param[in] dev_id device id + * @param[in] entry_id NAT entry id + * @param[in] cnt_id counter entry id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_nat_counter_bind(dev_id, entry_id, cnt_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add one NAPT entry to one particular device. + * @details Comments: + Before NAPT entry added related ip4 private base address must be set + at first. + In parameter napt_entry related entry flags must be set + Hardware entry id will be returned. + * @param[in] dev_id device id + * @param[in] napt_entry NAPT entry parameter + * @return SW_OK or error code + */ + +HSL_LOCAL sw_error_t +isis_napt_add(a_uint32_t dev_id, fal_napt_entry_t * napt_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_napt_add(dev_id, napt_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Del NAPT entries from one particular device. + * @param[in] dev_id device id + * @param[in] del_mode NAPT entry delete operation mode + * @param[in] napt_entry NAPT entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_napt_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_napt_entry_t * napt_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_napt_del(dev_id, del_mode, napt_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get one NAPT entry from one particular device. + * @param[in] dev_id device id + * @param[in] get_mode NAPT entry get operation mode + * @param[in] nat_entry NAPT entry parameter + * @param[out] nat_entry NAPT entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_napt_get(a_uint32_t dev_id, a_uint32_t get_mode, + fal_napt_entry_t * napt_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_napt_get(dev_id, get_mode, napt_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Next NAPT entries from one particular device. + * @param[in] dev_id device id + * @param[in] next_mode NAPT entry next operation mode + * @param[in] napt_entry NAPT entry parameter + * @param[out] napt_entry NAPT entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_napt_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_napt_entry_t * napt_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_napt_next(dev_id, next_mode, napt_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Bind one counter entry to one NAPT entry to one particular device. + * @param[in] dev_id device id + * @param[in] entry_id NAPT entry id + * @param[in] cnt_id counter entry id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_napt_counter_bind(dev_id, entry_id, cnt_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set working status of NAT engine on a particular device + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_nat_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_nat_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get working status of NAT engine on a particular device + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_nat_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_nat_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set NAT hash mode on a particular device + * @param[in] dev_id device id + * @param[in] mode NAT hash mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_nat_hash_mode_set(a_uint32_t dev_id, a_uint32_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_nat_hash_mode_set(dev_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get NAT hash mode on a particular device + * @param[in] dev_id device id + * @param[out] mode NAT hash mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_nat_hash_mode_get(a_uint32_t dev_id, a_uint32_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_nat_hash_mode_get(dev_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set working status of NAPT engine on a particular device + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_napt_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_napt_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get working status of NAPT engine on a particular device + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_napt_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_napt_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set working mode of NAPT engine on a particular device + * @param[in] dev_id device id + * @param[in] mode NAPT mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_napt_mode_set(a_uint32_t dev_id, fal_napt_mode_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_napt_mode_set(dev_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get working mode of NAPT engine on a particular device + * @param[in] dev_id device id + * @param[out] mode NAPT mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_napt_mode_get(a_uint32_t dev_id, fal_napt_mode_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_napt_mode_get(dev_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set IP4 private base address on a particular device + * @details Comments: + Only 20bits is meaning which 20bits is determined by private address mode. + * @param[in] dev_id device id + * @param[in] addr private base address + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_nat_prv_base_addr_set(a_uint32_t dev_id, fal_ip4_addr_t addr) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_nat_prv_base_addr_set(dev_id, addr); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IP4 private base address on a particular device + * @param[in] dev_id device id + * @param[out] addr private base address + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_nat_prv_base_addr_get(a_uint32_t dev_id, fal_ip4_addr_t * addr) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_nat_prv_base_addr_get(dev_id, addr); + HSL_API_UNLOCK; + return rv; +} + +#if 0 +/** + * @brief Set IP4 private base address on a particular device + * @details Comments: + Only 20bits is meaning which 20bits is determined by private address mode. + * @param[in] dev_id device id + * @param[in] addr private base address + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_nat_psr_prv_base_addr_set(a_uint32_t dev_id, fal_ip4_addr_t addr) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_nat_psr_prv_base_addr_set(dev_id, addr); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IP4 private base address on a particular device + * @param[in] dev_id device id + * @param[out] addr private base address + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_nat_psr_prv_base_addr_get(a_uint32_t dev_id, fal_ip4_addr_t * addr) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_nat_psr_prv_base_addr_get(dev_id, addr); + HSL_API_UNLOCK; + return rv; +} +#endif + +/** + * @brief Set IP4 private base address mode on a particular device + * @details Comments: + If map_en equal true means bits31-20 bits15-8 are base address + else bits31-12 are base address. + * @param[in] dev_id device id + * @param[in] map_en private base mapping mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_nat_prv_addr_mode_set(a_uint32_t dev_id, a_bool_t map_en) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_nat_prv_addr_mode_set(dev_id, map_en); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IP4 private base address mode on a particular device + * @param[in] dev_id device id + * @param[out] map_en private base mapping mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_nat_prv_addr_mode_get(a_uint32_t dev_id, a_bool_t * map_en) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_nat_prv_addr_mode_get(dev_id, map_en); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add one public address entry to one particular device. + * @details Comments: + Hardware entry id will be returned. + * @param[in] dev_id device id + * @param[in] entry public address entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_nat_pub_addr_add(a_uint32_t dev_id, fal_nat_pub_addr_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_nat_pub_addr_add(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete one public address entry from one particular device. + * @param[in] dev_id device id + * @param[in] del_mode delete operaton mode + * @param[in] entry public address entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_nat_pub_addr_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_nat_pub_addr_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_nat_pub_addr_del(dev_id, del_mode, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Next public address entries from one particular device. + * @param[in] dev_id device id + * @param[in] next_mode next operaton mode + * @param[out] entry public address entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_nat_pub_addr_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_nat_pub_addr_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_nat_pub_addr_next(dev_id, next_mode, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set forwarding command for those packets miss NAT entries on a particular device. + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_nat_unk_session_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_nat_unk_session_cmd_set(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get forwarding command for those packets miss NAT entries on a particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_nat_unk_session_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_nat_unk_session_cmd_get(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set working status of NAT engine on a particular device + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_nat_global_set(a_uint32_t dev_id, a_bool_t enable, a_uint32_t portbmp) +{ + sw_error_t rv = SW_OK; + + HSL_API_LOCK; + printk("enable:%d\n", enable); + if(enable) { + if(isis_nat_global_status == 0) { + isis_nat_global_status = 1; +#if defined(IN_NAT_HELPER) + ISIS_NAT_HELPER_INIT(rv, dev_id, portbmp); +#endif + } + } else { + if(isis_nat_global_status == 1) { + isis_nat_global_status = 0; +#if defined(IN_NAT_HELPER) + ISIS_NAT_HELPER_CLEANUP(rv, dev_id); +#endif + } + } + //rv = SW_OK; + HSL_API_UNLOCK; + return rv; +} + + +sw_error_t +isis_nat_init(a_uint32_t dev_id) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + rv = isis_nat_reset(dev_id); + SW_RTN_ON_ERROR(rv); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->nat_add = isis_nat_add; + p_api->nat_del = isis_nat_del; + p_api->nat_get = isis_nat_get; + p_api->nat_next = isis_nat_next; + p_api->nat_counter_bind = isis_nat_counter_bind; + p_api->napt_add = isis_napt_add; + p_api->napt_del = isis_napt_del; + p_api->napt_get = isis_napt_get; + p_api->napt_next = isis_napt_next; + p_api->napt_counter_bind = isis_napt_counter_bind; + p_api->nat_status_set = isis_nat_status_set; + p_api->nat_status_get = isis_nat_status_get; + p_api->nat_hash_mode_set = isis_nat_hash_mode_set; + p_api->nat_hash_mode_get = isis_nat_hash_mode_get; + p_api->napt_status_set = isis_napt_status_set; + p_api->napt_status_get = isis_napt_status_get; + p_api->napt_mode_set = isis_napt_mode_set; + p_api->napt_mode_get = isis_napt_mode_get; + p_api->nat_prv_base_addr_set = isis_nat_prv_base_addr_set; + p_api->nat_prv_base_addr_get = isis_nat_prv_base_addr_get; + p_api->nat_prv_addr_mode_set = isis_nat_prv_addr_mode_set; + p_api->nat_prv_addr_mode_get = isis_nat_prv_addr_mode_get; + p_api->nat_pub_addr_add = isis_nat_pub_addr_add; + p_api->nat_pub_addr_del = isis_nat_pub_addr_del; + p_api->nat_pub_addr_next = isis_nat_pub_addr_next; + p_api->nat_unk_session_cmd_set = isis_nat_unk_session_cmd_set; + p_api->nat_unk_session_cmd_get = isis_nat_unk_session_cmd_get; + p_api->nat_global_set = isis_nat_global_set; + } +#endif + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_port_ctrl.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_port_ctrl.c new file mode 100755 index 000000000..00531cce1 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_port_ctrl.c @@ -0,0 +1,2356 @@ +/* + * Copyright (c) 2012, 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 isis_port_ctrl ISIS_PORT_CONTROL + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isis_port_ctrl.h" +#include "isis_reg.h" +#include "hsl_phy.h" + +static a_bool_t +_isis_port_phy_connected(a_uint32_t dev_id, fal_port_t port_id) +{ + if ((0 == port_id) || (6 == port_id)) + { + return A_FALSE; + } + else + { + return A_TRUE; + } +} + +static sw_error_t +_isis_port_duplex_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t duplex) +{ + sw_error_t rv; + a_uint32_t phy_id, reg_save, reg_val = 0, force, tmp; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_DUPLEX_BUTT <= duplex) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_val), sizeof (a_uint32_t)); + SW_GET_FIELD_BY_REG(PORT_STATUS, DUPLEX_MODE, tmp, reg_val); + + /* for those ports without PHY device we set MAC register */ + if (A_FALSE == _isis_port_phy_connected(dev_id, port_id)) + { + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 0, reg_val); + if (FAL_HALF_DUPLEX == duplex) + { + if (tmp == 0) + return SW_OK; + SW_SET_REG_BY_FIELD(PORT_STATUS, DUPLEX_MODE, 0, reg_val); + } + else + { + if (tmp == 1) + return SW_OK; + SW_SET_REG_BY_FIELD(PORT_STATUS, DUPLEX_MODE, 1, reg_val); + } + reg_save = reg_val; + } + else + { + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_duplex_set) + return SW_NOT_SUPPORTED; + /* hardware requirement: set mac be config by sw and turn off RX/TX MAC */ + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + rv = phy_drv->phy_duplex_get (dev_id, phy_id, &tmp); + SW_RTN_ON_ERROR(rv); + if (tmp == duplex) + return SW_OK; + reg_save = reg_val; + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 0, reg_val); + SW_SET_REG_BY_FIELD(PORT_STATUS, RXMAC_EN, 0, reg_val); + SW_SET_REG_BY_FIELD(PORT_STATUS, TXMAC_EN, 0, reg_val); + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_val), sizeof (a_uint32_t)); + + + rv = phy_drv->phy_duplex_set (dev_id, phy_id, duplex); + SW_RTN_ON_ERROR(rv); + + /* If MAC not in sync with PHY mode, the behavior is undefine. + You must be careful... */ + SW_GET_FIELD_BY_REG(PORT_STATUS, LINK_EN, force, reg_save); + if (!force) + { + if (FAL_HALF_DUPLEX == duplex) + { + SW_SET_REG_BY_FIELD(PORT_STATUS, DUPLEX_MODE, 0, reg_save); + } + else + { + SW_SET_REG_BY_FIELD(PORT_STATUS, DUPLEX_MODE, 1, reg_save); + } + } + } + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_save), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_duplex_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t * pduplex) +{ + sw_error_t rv; + a_uint32_t reg = 0, field; + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_GET_FIELD_BY_REG(PORT_STATUS, DUPLEX_MODE, field, reg); + if (field) + { + *pduplex = FAL_FULL_DUPLEX; + } + else + { + *pduplex = FAL_HALF_DUPLEX; + } + + return rv; +} + +static sw_error_t +_isis_port_speed_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t speed) +{ + sw_error_t rv; + a_uint32_t phy_id, reg_save, reg_val = 0, force, tmp; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_SPEED_1000 < speed) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_val), sizeof (a_uint32_t)); + SW_GET_FIELD_BY_REG(PORT_STATUS, SPEED_MODE, tmp, reg_val); + + /* for those ports without PHY device we set MAC register */ + if (A_FALSE == _isis_port_phy_connected(dev_id, port_id)) + { + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 0, reg_val); + if (FAL_SPEED_10 == speed) + { + if (tmp == 0) + return SW_OK; + SW_SET_REG_BY_FIELD(PORT_STATUS, SPEED_MODE, 0, reg_val); + } + else if (FAL_SPEED_100 == speed) + { + if (tmp == 1) + return SW_OK; + SW_SET_REG_BY_FIELD(PORT_STATUS, SPEED_MODE, 1, reg_val); + } + else + { + if (tmp == 2) + return SW_OK; + SW_SET_REG_BY_FIELD(PORT_STATUS, SPEED_MODE, 2, reg_val); + } + reg_save = reg_val; + + } + else + { + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_speed_set) + return SW_NOT_SUPPORTED; + /* hardware requirement: set mac be config by sw and turn off RX/TX MAC */ + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + rv = phy_drv->phy_speed_get (dev_id, phy_id, &tmp); + SW_RTN_ON_ERROR(rv); + if (tmp == speed) + return SW_OK; + reg_save = reg_val; + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 0, reg_val); + SW_SET_REG_BY_FIELD(PORT_STATUS, RXMAC_EN, 0, reg_val); + SW_SET_REG_BY_FIELD(PORT_STATUS, TXMAC_EN, 0, reg_val); + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_val), sizeof (a_uint32_t)); + + rv = phy_drv->phy_speed_set (dev_id, phy_id, speed); + SW_RTN_ON_ERROR(rv); + + /* If MAC not in sync with PHY mode, the behavior is undefine. + You must be careful... */ + SW_GET_FIELD_BY_REG(PORT_STATUS, LINK_EN, force, reg_save); + if (!force) + { + if (FAL_SPEED_10 == speed) + { + SW_SET_REG_BY_FIELD(PORT_STATUS, SPEED_MODE, 0, reg_save); + } + else if (FAL_SPEED_100 == speed) + { + SW_SET_REG_BY_FIELD(PORT_STATUS, SPEED_MODE, 1, reg_save); + } + else + { + SW_SET_REG_BY_FIELD(PORT_STATUS, SPEED_MODE, 2, reg_save); + } + } + } + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_save), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_speed_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t * pspeed) +{ + sw_error_t rv = SW_OK; + a_uint32_t reg = 0, field; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_STATUS, SPEED_MODE, field, reg); + if (0 == field) + { + *pspeed = FAL_SPEED_10; + } + else if (1 == field) + { + *pspeed = FAL_SPEED_100; + } + else if (2 == field) + { + *pspeed = FAL_SPEED_1000; + } + else + { + *pspeed = FAL_SPEED_BUTT; + rv = SW_READ_ERROR; + } + + return rv; +} + +static sw_error_t +_isis_port_autoneg_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status) +{ + a_uint32_t phy_id; + sw_error_t rv; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_autoneg_status_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + *status = phy_drv->phy_autoneg_status_get (dev_id, phy_id); + + return SW_OK; +} + +static sw_error_t +_isis_port_autoneg_enable(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_autoneg_enable_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_autoneg_enable_set(dev_id, phy_id); + return rv; +} + +static sw_error_t +_isis_port_autoneg_restart(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_restart_autoneg) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_restart_autoneg (dev_id, phy_id); + return rv; +} + +static sw_error_t +_isis_port_autoneg_adv_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t autoadv) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_autoneg_adv_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_autoneg_adv_set(dev_id, phy_id, autoadv); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +static sw_error_t +_isis_port_autoneg_adv_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * autoadv) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_autoneg_adv_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + *autoadv = 0; + rv = phy_drv->phy_autoneg_adv_get (dev_id, phy_id, autoadv); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +static sw_error_t +_isis_port_flowctrl_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val, force, reg = 0, tmp; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_STATUS, FLOW_LINK_EN, force, reg); + if (force) + { + /* flow control isn't in force mode so can't set */ + return SW_DISABLE; + } + tmp = reg; + + SW_SET_REG_BY_FIELD(PORT_STATUS, RX_FLOW_EN, val, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TX_FLOW_EN, val, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TX_HALF_FLOW_EN, val, reg); + if (tmp == reg) + return SW_OK; + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_flowctrl_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t rx, reg = 0; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_STATUS, RX_FLOW_EN, rx, reg); + + if (1 == rx) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isis_port_flowctrl_forcemode_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t reg = 0, tmp; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + SW_GET_FIELD_BY_REG(PORT_STATUS, FLOW_LINK_EN, tmp, reg); + + if (A_TRUE == enable) + { + if (tmp == 0) + return SW_OK; + SW_SET_REG_BY_FIELD(PORT_STATUS, FLOW_LINK_EN, 0, reg); + } + else if (A_FALSE == enable) + { + /* for those ports without PHY, it can't sync flow control status */ + if (A_FALSE == _isis_port_phy_connected(dev_id, port_id)) + { + return SW_DISABLE; + } + if (tmp == 1) + return SW_OK; + SW_SET_REG_BY_FIELD(PORT_STATUS, FLOW_LINK_EN, 1, reg); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_flowctrl_forcemode_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t force, reg = 0; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_STATUS, FLOW_LINK_EN, force, reg); + if (0 == force) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isis_port_powersave_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_powersave_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_powersave_set(dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_isis_port_powersave_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_powersave_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_powersave_get(dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_isis_port_hibernate_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_hibernation_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_hibernation_set (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_isis_port_hibernate_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_hibernation_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_hibernation_get(dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_isis_port_cdt(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t mdi_pair, + fal_cable_status_t * cable_status, a_uint32_t * cable_len) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_cdt) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_cdt(dev_id, phy_id, mdi_pair, cable_status, cable_len); + + return rv; +} +static sw_error_t +_isis_port_8023az_set (a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_8023az_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_8023az_set (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_isis_port_8023az_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_8023az_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_8023az_get (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_isis_port_rxhdr_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t mode) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_NO_HEADER_EN == mode) + { + val = 0; + } + else if (FAL_ONLY_MANAGE_FRAME_EN == mode) + { + val = 1; + } + else if (FAL_ALL_TYPE_FRAME_EN == mode) + { + val = 2; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_HDR_CTL, port_id, RXHDR_MODE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_rxhdr_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_HDR_CTL, port_id, RXHDR_MODE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *mode = FAL_ONLY_MANAGE_FRAME_EN; + } + else if (2 == val) + { + *mode = FAL_ALL_TYPE_FRAME_EN; + } + else + { + *mode = FAL_NO_HEADER_EN; + } + + return SW_OK; +} + +static sw_error_t +_isis_port_txhdr_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t mode) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_NO_HEADER_EN == mode) + { + val = 0; + } + else if (FAL_ONLY_MANAGE_FRAME_EN == mode) + { + val = 1; + } + else if (FAL_ALL_TYPE_FRAME_EN == mode) + { + val = 2; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_HDR_CTL, port_id, TXHDR_MODE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_txhdr_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_HDR_CTL, port_id, TXHDR_MODE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *mode = FAL_ONLY_MANAGE_FRAME_EN; + } + else if (2 == val) + { + *mode = FAL_ALL_TYPE_FRAME_EN; + } + else + { + *mode = FAL_NO_HEADER_EN; + } + + return SW_OK; +} + +static sw_error_t +_isis_header_type_set(a_uint32_t dev_id, a_bool_t enable, a_uint32_t type) +{ + a_uint32_t reg = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_ENTRY_GET(rv, dev_id, HEADER_CTL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + if (0xffff < type) + { + return SW_BAD_PARAM; + } + SW_SET_REG_BY_FIELD(HEADER_CTL, TYPE_LEN, 1, reg); + SW_SET_REG_BY_FIELD(HEADER_CTL, TYPE_VAL, type, reg); + } + else if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(HEADER_CTL, TYPE_LEN, 0, reg); + SW_SET_REG_BY_FIELD(HEADER_CTL, TYPE_VAL, 0, reg); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_SET(rv, dev_id, HEADER_CTL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_header_type_get(a_uint32_t dev_id, a_bool_t * enable, a_uint32_t * type) +{ + a_uint32_t data, reg = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_ENTRY_GET(rv, dev_id, HEADER_CTL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(HEADER_CTL, TYPE_LEN, data, reg); + if (data) + { + SW_GET_FIELD_BY_REG(HEADER_CTL, TYPE_VAL, data, reg); + *enable = A_TRUE; + *type = data; + } + else + { + *enable = A_FALSE; + *type = 0; + } + + return SW_OK; +} + +static sw_error_t +_isis_port_txmac_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t reg = 0, force, val, tmp; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + tmp = reg; + + /* for those ports without PHY device we set MAC register */ + if (A_FALSE == _isis_port_phy_connected(dev_id, port_id)) + { + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TXMAC_EN, val, reg); + } + else + { + SW_GET_FIELD_BY_REG(PORT_STATUS, LINK_EN, force, reg); + if (force) + { + /* link isn't in force mode so can't set */ + return SW_DISABLE; + } + else + { + SW_SET_REG_BY_FIELD(PORT_STATUS, TXMAC_EN, val, reg); + } + } + if (tmp == reg) + return SW_OK; + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_txmac_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_STATUS, port_id, TXMAC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isis_port_rxmac_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t reg = 0, force, val, tmp; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + tmp = reg; + + /* for those ports without PHY device we set MAC register */ + if (A_FALSE == _isis_port_phy_connected(dev_id, port_id)) + { + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, RXMAC_EN, val, reg); + } + else + { + SW_GET_FIELD_BY_REG(PORT_STATUS, LINK_EN, force, reg); + if (force) + { + /* link isn't in force mode so can't set */ + return SW_DISABLE; + } + else + { + SW_SET_REG_BY_FIELD(PORT_STATUS, RXMAC_EN, val, reg); + } + } + if (tmp == reg) + return SW_OK; + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_rxmac_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_STATUS, port_id, RXMAC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isis_port_txfc_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val, reg = 0, force, tmp; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + tmp = reg; + + /* for those ports without PHY device we set MAC register */ + if (A_FALSE == _isis_port_phy_connected(dev_id, port_id)) + { + SW_SET_REG_BY_FIELD(PORT_STATUS, FLOW_LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TX_FLOW_EN, val, reg); + } + else + { + SW_GET_FIELD_BY_REG(PORT_STATUS, FLOW_LINK_EN, force, reg); + if (force) + { + /* flow control isn't in force mode so can't set */ + return SW_DISABLE; + } + else + { + SW_SET_REG_BY_FIELD(PORT_STATUS, TX_FLOW_EN, val, reg); + } + } + if ( tmp == reg) + return SW_OK; + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_txfc_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_STATUS, port_id, TX_FLOW_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isis_port_rxfc_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val, reg = 0, force, tmp; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + tmp = reg; + + /* for those ports without PHY device we set MAC register */ + if (A_FALSE == _isis_port_phy_connected(dev_id, port_id)) + { + SW_SET_REG_BY_FIELD(PORT_STATUS, FLOW_LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, RX_FLOW_EN, val, reg); + } + else + { + SW_GET_FIELD_BY_REG(PORT_STATUS, FLOW_LINK_EN, force, reg); + if (force) + { + /* flow control isn't in force mode so can't set */ + return SW_DISABLE; + } + else + { + SW_SET_REG_BY_FIELD(PORT_STATUS, RX_FLOW_EN, val, reg); + } + } + if ( tmp == reg) + return SW_OK; + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_rxfc_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_STATUS, port_id, RX_FLOW_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isis_port_bp_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val, tmp = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + HSL_REG_FIELD_GET(rv, dev_id, PORT_STATUS, port_id, TX_HALF_FLOW_EN, + (a_uint8_t *) (&tmp), sizeof (a_uint32_t)); + if (tmp == val) + return SW_OK; + HSL_REG_FIELD_SET(rv, dev_id, PORT_STATUS, port_id, TX_HALF_FLOW_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_bp_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_STATUS, port_id, TX_HALF_FLOW_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isis_port_link_forcemode_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t reg = 0, tmp; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + SW_GET_FIELD_BY_REG(PORT_STATUS, LINK_EN, tmp, reg); + + if (A_TRUE == enable) + { + if(tmp == 0) + return SW_OK; + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 0, reg); + } + else if (A_FALSE == enable) + { + if(tmp == 1) + return SW_OK; + /* for those ports without PHY, it can't sync link status */ + if (A_FALSE == _isis_port_phy_connected(dev_id, port_id)) + { + return SW_DISABLE; + } + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 1, reg); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_link_forcemode_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_STATUS, port_id, LINK_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isis_port_link_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * status) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + /* for those ports without PHY device supposed always link up */ + if (A_FALSE == _isis_port_phy_connected(dev_id, port_id)) + { + *status = A_TRUE; + } + else + { + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_link_status_get) + return SW_NOT_SUPPORTED; + + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == phy_drv->phy_link_status_get (dev_id, phy_id)) + { + *status = A_TRUE; + } + else + { + *status = A_FALSE; + } + } + + return SW_OK; +} + +static sw_error_t +_isis_port_mac_loopback_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_HDR_CTL, port_id, LOOPBACK_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_mac_loopback_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_HDR_CTL, port_id, LOOPBACK_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0 == val) + { + *enable = A_FALSE; + } + else + { + *enable = A_TRUE; + } + + return SW_OK; +} + +/** + * @brief Set duplex mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] duplex duplex mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_duplex_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t duplex) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_duplex_set(dev_id, port_id, duplex); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get duplex mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] duplex duplex mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_duplex_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t * pduplex) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_duplex_get(dev_id, port_id, pduplex); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set speed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] speed port speed + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_speed_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t speed) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_speed_set(dev_id, port_id, speed); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get speed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] speed port speed + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_speed_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t * pspeed) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_speed_get(dev_id, port_id, pspeed); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get auto negotiation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] status A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_autoneg_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_autoneg_status_get(dev_id, port_id, status); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Enable auto negotiation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_autoneg_enable(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_autoneg_enable(dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Restart auto negotiation procedule on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_autoneg_restart(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_autoneg_restart(dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set auto negotiation advtisement ability on a particular port. + * @details Comments: + * auto negotiation advtisement ability is defined by macro such as + * FAL_PHY_ADV_10T_HD, FAL_PHY_ADV_PAUSE... + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] autoadv auto negotiation advtisement ability bit map + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_autoneg_adv_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t autoadv) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_autoneg_adv_set(dev_id, port_id, autoadv); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get auto negotiation advtisement ability on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] autoadv auto negotiation advtisement ability bit map + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_autoneg_adv_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * autoadv) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_autoneg_adv_get(dev_id, port_id, autoadv); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flow control(rx/tx/bp) status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_flowctrl_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_flowctrl_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get flow control status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_flowctrl_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_flowctrl_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flow control force mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_flowctrl_forcemode_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_flowctrl_forcemode_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get flow control force mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_flowctrl_forcemode_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_flowctrl_forcemode_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set powersaving status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_powersave_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_powersave_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get powersaving status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_powersave_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_powersave_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set hibernate status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_hibernate_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_hibernate_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get hibernate status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_hibernate_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_hibernate_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Run cable diagnostic test on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mdi_pair mdi pair id + * @param[out] cable_status cable status + * @param[out] cable_len cable len + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_cdt(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t mdi_pair, + fal_cable_status_t * cable_status, a_uint32_t * cable_len) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_cdt(dev_id, port_id, mdi_pair, cable_status, cable_len); + HSL_API_UNLOCK; + return rv; +} +/** + * @brief Set 802.3az status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_8023az_set (a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_8023az_set (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get 8023az status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_8023az_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_8023az_get (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of Atheros header packets parsed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_rxhdr_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_rxhdr_mode_set(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get status of Atheros header packets parsed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_rxhdr_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_rxhdr_mode_get(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of Atheros header packets parsed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_txhdr_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_txhdr_mode_set(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get status of Atheros header packets parsed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_txhdr_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_txhdr_mode_get(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of Atheros header type value on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] type header type value + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_header_type_set(a_uint32_t dev_id, a_bool_t enable, a_uint32_t type) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _isis_header_type_set(dev_id, enable, type); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get status of Atheros header type value on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @param[out] type header type value + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_header_type_get(a_uint32_t dev_id, a_bool_t * enable, a_uint32_t * type) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_header_type_get(dev_id, enable, type); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of txmac on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_txmac_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _isis_port_txmac_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get status of txmac on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_txmac_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_txmac_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of rxmac on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_rxmac_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _isis_port_rxmac_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get status of rxmac on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_rxmac_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_rxmac_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of tx flow control on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_txfc_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _isis_port_txfc_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get status of tx flow control on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_txfc_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_txfc_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of rx flow control on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_rxfc_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _isis_port_rxfc_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of rx flow control on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_rxfc_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_rxfc_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of back pressure on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_bp_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _isis_port_bp_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of back pressure on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_bp_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_bp_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set link force mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_link_forcemode_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _isis_port_link_forcemode_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get link force mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_link_forcemode_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_link_forcemode_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get link status on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] status link status up (A_TRUE) or down (A_FALSE) + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_link_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * status) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_link_status_get(dev_id, port_id, status); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set mac loop back on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_mac_loopback_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _isis_port_mac_loopback_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mac loop back on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_mac_loopback_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_mac_loopback_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +isis_port_ctrl_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->port_duplex_get = isis_port_duplex_get; + p_api->port_duplex_set = isis_port_duplex_set; + p_api->port_speed_get = isis_port_speed_get; + p_api->port_speed_set = isis_port_speed_set; + p_api->port_autoneg_status_get = isis_port_autoneg_status_get; + p_api->port_autoneg_enable = isis_port_autoneg_enable; + p_api->port_autoneg_restart = isis_port_autoneg_restart; + p_api->port_autoneg_adv_get = isis_port_autoneg_adv_get; + p_api->port_autoneg_adv_set = isis_port_autoneg_adv_set; + p_api->port_flowctrl_set = isis_port_flowctrl_set; + p_api->port_flowctrl_get = isis_port_flowctrl_get; + p_api->port_flowctrl_forcemode_set = isis_port_flowctrl_forcemode_set; + p_api->port_flowctrl_forcemode_get = isis_port_flowctrl_forcemode_get; + p_api->port_powersave_set = isis_port_powersave_set; + p_api->port_powersave_get = isis_port_powersave_get; + p_api->port_hibernate_set = isis_port_hibernate_set; + p_api->port_hibernate_get = isis_port_hibernate_get; + p_api->port_cdt = isis_port_cdt; + p_api->port_rxhdr_mode_set = isis_port_rxhdr_mode_set; + p_api->port_rxhdr_mode_get = isis_port_rxhdr_mode_get; + p_api->port_txhdr_mode_set = isis_port_txhdr_mode_set; + p_api->port_txhdr_mode_get = isis_port_txhdr_mode_get; + p_api->header_type_set = isis_header_type_set; + p_api->header_type_get = isis_header_type_get; + p_api->port_txmac_status_set = isis_port_txmac_status_set; + p_api->port_txmac_status_get = isis_port_txmac_status_get; + p_api->port_rxmac_status_set = isis_port_rxmac_status_set; + p_api->port_rxmac_status_get = isis_port_rxmac_status_get; + p_api->port_txfc_status_set = isis_port_txfc_status_set; + p_api->port_txfc_status_get = isis_port_txfc_status_get; + p_api->port_rxfc_status_set = isis_port_rxfc_status_set; + p_api->port_rxfc_status_get = isis_port_rxfc_status_get; + p_api->port_bp_status_set = isis_port_bp_status_set; + p_api->port_bp_status_get = isis_port_bp_status_get; + p_api->port_link_forcemode_set = isis_port_link_forcemode_set; + p_api->port_link_forcemode_get = isis_port_link_forcemode_get; + p_api->port_link_status_get = isis_port_link_status_get; + p_api->port_mac_loopback_set = isis_port_mac_loopback_set; + p_api->port_mac_loopback_get = isis_port_mac_loopback_get; + p_api->port_8023az_set = isis_port_8023az_set; + p_api->port_8023az_get = isis_port_8023az_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_portvlan.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_portvlan.c new file mode 100755 index 000000000..596bc469e --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_portvlan.c @@ -0,0 +1,2130 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup isis_port_vlan ISIS_PORT_VLAN + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isis_portvlan.h" +#include "isis_reg.h" + +#define MAX_VLAN_ID 4095 +#define ISIS_MAX_VLAN_TRANS 64 +#define ISIS_VLAN_TRANS_ADDR 0x5ac00 + + +static sw_error_t +_isis_port_route_defv_set(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t data = 0, reg = 0; + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN1, port_id, + COREP_EN, (a_uint8_t *) (&data), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (data) + { + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN0, port_id, + DEF_SVID, (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else + { + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN0, port_id, + DEF_CVID, (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_DEFV, (port_id / 2), + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (port_id % 2) + { + reg &= 0xffff; + reg |= ((data & 0xfff) << 16); + } + else + { + reg &= 0xffff0000; + reg |= (data & 0xfff); + } + + HSL_REG_ENTRY_SET(rv, dev_id, ROUTER_DEFV, (port_id / 2), + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_1qmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t port_1qmode) +{ + sw_error_t rv; + a_uint32_t data, regval[FAL_1Q_MODE_BUTT] = { 0, 3, 2, 1 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_1Q_MODE_BUTT <= port_1qmode) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LOOKUP_CTL, port_id, DOT1Q_MODE, + (a_uint8_t *) (®val[port_1qmode]), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_1Q_DISABLE == port_1qmode) + { + data = 1; + } + else + { + data = 0; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN1, port_id, VLAN_DIS, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_1qmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t * pport_1qmode) +{ + sw_error_t rv; + a_uint32_t regval = 0; + fal_pt_1qmode_t retval[4] = { FAL_1Q_DISABLE, FAL_1Q_FALLBACK, + FAL_1Q_CHECK, FAL_1Q_SECURE + }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL(pport_1qmode); + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LOOKUP_CTL, port_id, DOT1Q_MODE, + (a_uint8_t *) (®val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + *pport_1qmode = retval[regval & 0x3]; + + return SW_OK; +} + +static sw_error_t +_isis_port_egvlanmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t port_egvlanmode) +{ + sw_error_t rv; + a_uint32_t data = 0, regval[FAL_EG_MODE_BUTT] = { 0, 1, 2, 3, 3 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if ((FAL_EG_MODE_BUTT <= port_egvlanmode) + || (FAL_EG_HYBRID == port_egvlanmode)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN1, port_id, EG_VLAN_MODE, + (a_uint8_t *) (®val[port_egvlanmode]), + sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_EG, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data &= (~(0x3 << (port_id << 2))); + data |= (regval[port_egvlanmode] << (port_id << 2)); + + HSL_REG_ENTRY_SET(rv, dev_id, ROUTER_EG, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_egvlanmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t * pport_egvlanmode) +{ + sw_error_t rv; + a_uint32_t regval = 0; + fal_pt_1q_egmode_t retval[4] = { FAL_EG_UNMODIFIED, FAL_EG_UNTAGGED, + FAL_EG_TAGGED, FAL_EG_UNTOUCHED + }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL(pport_egvlanmode); + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN1, port_id, EG_VLAN_MODE, + (a_uint8_t *) (®val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + *pport_egvlanmode = retval[regval & 0x3]; + + return SW_OK; +} + +static sw_error_t +_isis_portvlan_member_add(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id) +{ + sw_error_t rv; + a_uint32_t regval = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_FALSE == hsl_port_prop_check(dev_id, mem_port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LOOKUP_CTL, port_id, + PORT_VID_MEM, (a_uint8_t *) (®val), + sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + regval |= (0x1UL << mem_port_id); + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LOOKUP_CTL, port_id, + PORT_VID_MEM, (a_uint8_t *) (®val), + sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_isis_portvlan_member_del(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id) +{ + sw_error_t rv; + a_uint32_t regval = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_FALSE == hsl_port_prop_check(dev_id, mem_port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LOOKUP_CTL, port_id, + PORT_VID_MEM, (a_uint8_t *) (®val), + sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + regval &= (~(0x1UL << mem_port_id)); + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LOOKUP_CTL, port_id, + PORT_VID_MEM, (a_uint8_t *) (®val), + sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_isis_portvlan_member_update(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t mem_port_map) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_FALSE == hsl_mports_prop_check(dev_id, mem_port_map, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LOOKUP_CTL, port_id, + PORT_VID_MEM, (a_uint8_t *) (&mem_port_map), + sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_isis_portvlan_member_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t * mem_port_map) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + *mem_port_map = 0; + HSL_REG_FIELD_GET(rv, dev_id, PORT_LOOKUP_CTL, port_id, + PORT_VID_MEM, (a_uint8_t *) mem_port_map, + sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +static sw_error_t +_isis_port_force_default_vid_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN1, port_id, + FORCE_DEF_VID, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_force_default_vid_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN1, port_id, + FORCE_DEF_VID, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isis_port_force_portvlan_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LOOKUP_CTL, port_id, + FORCE_PVLAN, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_force_portvlan_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LOOKUP_CTL, port_id, + FORCE_PVLAN, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isis_nestvlan_tpid_set(a_uint32_t dev_id, a_uint32_t tpid) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + val = tpid; + HSL_REG_FIELD_SET(rv, dev_id, SERVICE_TAG, 0, + TAG_VALUE, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_nestvlan_tpid_get(a_uint32_t dev_id, a_uint32_t * tpid) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, SERVICE_TAG, 0, + TAG_VALUE, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *tpid = val; + return SW_OK; +} + +static sw_error_t +_isis_port_invlan_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_invlan_mode_t mode) +{ + sw_error_t rv; + a_uint32_t regval[FAL_INVLAN_MODE_BUTT] = { 0, 1, 2 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_INVLAN_MODE_BUTT <= mode) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN1, port_id, IN_VLAN_MODE, + (a_uint8_t *) (®val[mode]), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_invlan_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_invlan_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t regval = 0; + fal_pt_invlan_mode_t retval[FAL_INVLAN_MODE_BUTT] = { FAL_INVLAN_ADMIT_ALL, + FAL_INVLAN_ADMIT_TAGGED, FAL_INVLAN_ADMIT_UNTAGGED + }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL(mode); + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN1, port_id, IN_VLAN_MODE, + (a_uint8_t *) (®val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (regval >= 3) + { + return SW_FAIL; + } + *mode = retval[regval & 0x3]; + + return rv; +} + +static sw_error_t +_isis_port_tls_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN1, port_id, + TLS_EN, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_tls_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN1, port_id, + TLS_EN, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isis_port_pri_propagation_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN1, port_id, + PRI_PROPAGATION, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_pri_propagation_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN1, port_id, + PRI_PROPAGATION, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isis_port_default_svid_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vid) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (vid > MAX_VLAN_ID) + { + return SW_BAD_PARAM; + } + + val = vid; + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN0, port_id, + DEF_SVID, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + rv = _isis_port_route_defv_set(dev_id, port_id); + return rv; +} + +static sw_error_t +_isis_port_default_svid_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vid) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN0, port_id, + DEF_SVID, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + *vid = val & 0xfff; + return rv; +} + +static sw_error_t +_isis_port_default_cvid_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vid) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (vid > MAX_VLAN_ID) + { + return SW_BAD_PARAM; + } + + val = vid; + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN0, port_id, + DEF_CVID, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + rv = _isis_port_route_defv_set(dev_id, port_id); + return rv; +} + +static sw_error_t +_isis_port_default_cvid_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vid) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN0, port_id, + DEF_CVID, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + *vid = val & 0xfff; + return rv; +} + +static sw_error_t +_isis_port_vlan_propagation_set(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_propagation_mode_t mode) +{ + sw_error_t rv; + a_uint32_t reg = 0, p, c; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_VLAN_PROPAGATION_DISABLE == mode) + { + p = 0; + c = 0; + } + else if (FAL_VLAN_PROPAGATION_CLONE == mode) + { + p = 1; + c = 1; + } + else if (FAL_VLAN_PROPAGATION_REPLACE == mode) + { + p = 1; + c = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_VLAN1, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(PORT_VLAN1, PROPAGATION_EN, p, reg); + SW_SET_REG_BY_FIELD(PORT_VLAN1, CLONE, c, reg); + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_VLAN1, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_port_vlan_propagation_get(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_propagation_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t reg = 0, p, c; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_VLAN1, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_VLAN1, PROPAGATION_EN, p, reg); + SW_GET_FIELD_BY_REG(PORT_VLAN1, CLONE, c, reg); + + if (p) + { + if (c) + { + *mode = FAL_VLAN_PROPAGATION_CLONE; + } + else + { + *mode = FAL_VLAN_PROPAGATION_REPLACE; + } + } + else + { + *mode = FAL_VLAN_PROPAGATION_DISABLE; + } + + return SW_OK; +} + +static sw_error_t +_isis_vlan_trans_read(a_uint32_t dev_id, a_uint32_t entry_idx, + fal_pbmp_t * pbmp, fal_vlan_trans_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t i, addr, dir, table[2] = {0}; + + *pbmp = 0; + aos_mem_zero(entry, sizeof (fal_vlan_trans_entry_t)); + + addr = ISIS_VLAN_TRANS_ADDR + (entry_idx << 3); + /* get vlan trans table */ + for (i = 0; i < 2; i++) + { + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr + (i << 2), sizeof (a_uint32_t), + (a_uint8_t *) (&(table[i])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + dir = 0x3 & (table[1] >> 4); + if (!dir) + { + return SW_EMPTY; + } + + entry->o_vid = table[0] & 0xfff; + *pbmp = (table[1] >> 6) & 0x7f; + + if (3 == dir) + { + entry->bi_dir = A_TRUE; + entry->forward_dir = A_TRUE; + entry->reverse_dir = A_TRUE; + } + else if (1 == dir) + { + entry->bi_dir = A_FALSE; + entry->forward_dir = A_TRUE; + entry->reverse_dir = A_FALSE; + } + else + { + entry->bi_dir = A_FALSE; + entry->forward_dir = A_FALSE; + entry->reverse_dir = A_TRUE; + } + + entry->o_vid_is_cvid = (table[1] >> 13) & 0x1UL; + entry->one_2_one_vlan = (table[1] >> 16) & 0x1UL; + entry->s_vid_enable = (table[1] >> 14) & 0x1UL; + entry->c_vid_enable = (table[1] >> 15) & 0x1UL; + + if (A_TRUE == entry->s_vid_enable) + { + entry->s_vid = (table[0] >> 12) & 0xfff; + } + + if (A_TRUE == entry->c_vid_enable) + { + entry->c_vid = ((table[0] >> 24) & 0xff) | ((table[1] & 0xf) << 8); + } + + return SW_OK; +} + +static sw_error_t +_isis_vlan_trans_write(a_uint32_t dev_id, a_uint32_t entry_idx, fal_pbmp_t pbmp, + fal_vlan_trans_entry_t entry) +{ + sw_error_t rv; + a_uint32_t i, addr, table[2] = { 0 }; + + addr = ISIS_VLAN_TRANS_ADDR + (entry_idx << 3); + + if (0 != pbmp) + { + table[0] = entry.o_vid & 0xfff; + table[0] |= ((entry.s_vid & 0xfff) << 12); + table[0] |= ((entry.c_vid & 0xff) << 24); + table[1] = (entry.c_vid >> 8) & 0xf; + + if (A_TRUE == entry.bi_dir) + { + table[1] |= (0x3 << 4); + } + + if (A_TRUE == entry.forward_dir) + { + table[1] |= (0x1 << 4); + } + + if (A_TRUE == entry.reverse_dir) + { + table[1] |= (0x1 << 5); + } + + table[1] |= (pbmp << 6); + table[1] |= ((0x1UL & entry.o_vid_is_cvid) << 13); + table[1] |= ((0x1UL & entry.s_vid_enable) << 14); + table[1] |= ((0x1UL & entry.c_vid_enable) << 15); + table[1] |= ((0x1UL & entry.one_2_one_vlan) << 16); + } + + /* set vlan trans table */ + for (i = 0; i < 2; i++) + { + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr + (i << 2), sizeof (a_uint32_t), + (a_uint8_t *) (&(table[i])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +static sw_error_t +_isis_port_vlan_trans_convert(fal_vlan_trans_entry_t * entry, + fal_vlan_trans_entry_t * local) +{ + aos_mem_copy(local, entry, sizeof (fal_vlan_trans_entry_t)); + + if ((A_TRUE == local->bi_dir) + || ((A_TRUE == local->forward_dir) + && (A_TRUE == local->reverse_dir))) + { + local->bi_dir = A_TRUE; + local->forward_dir = A_TRUE; + local->reverse_dir = A_TRUE; + } + + if (A_FALSE == local->s_vid_enable) + { + local->s_vid = 0; + } + + if (A_FALSE == local->c_vid_enable) + { + local->c_vid = 0; + } + + return SW_OK; +} + +static sw_error_t +_isis_port_vlan_trans_add(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_trans_entry_t * entry) +{ + sw_error_t rv; + fal_pbmp_t t_pbmp; + a_uint32_t idx, entry_idx = ISIS_MAX_VLAN_TRANS; + fal_vlan_trans_entry_t temp, local; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (NULL == entry) + { + return SW_BAD_PTR; + } + aos_mem_zero(&local, sizeof(fal_vlan_trans_entry_t)); + rv = _isis_port_vlan_trans_convert(entry, &local); + SW_RTN_ON_ERROR(rv); + + for (idx = 0; idx < ISIS_MAX_VLAN_TRANS; idx++) + { + rv = _isis_vlan_trans_read(dev_id, idx, &t_pbmp, &temp); + if (SW_EMPTY == rv) + { + entry_idx = idx; + continue; + } + SW_RTN_ON_ERROR(rv); + + if (!aos_mem_cmp(&local, &temp, sizeof (fal_vlan_trans_entry_t))) + { + if (SW_IS_PBMP_MEMBER(t_pbmp, port_id)) + { + return SW_ALREADY_EXIST; + } + entry_idx = idx; + break; + } + else + { + t_pbmp = 0; + } + } + + if (ISIS_MAX_VLAN_TRANS != entry_idx) + { + t_pbmp |= (0x1 << port_id); + } + else + { + return SW_NO_RESOURCE; + } + + return _isis_vlan_trans_write(dev_id, entry_idx, t_pbmp, local); +} + +static sw_error_t +_isis_port_vlan_trans_del(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_trans_entry_t * entry) +{ + sw_error_t rv; + fal_pbmp_t t_pbmp; + a_uint32_t idx, entry_idx = ISIS_MAX_VLAN_TRANS; + fal_vlan_trans_entry_t temp, local; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (NULL == entry) + { + return SW_BAD_PTR; + } + aos_mem_zero(&local, sizeof(fal_vlan_trans_entry_t)); + rv = _isis_port_vlan_trans_convert(entry, &local); + SW_RTN_ON_ERROR(rv); + + for (idx = 0; idx < ISIS_MAX_VLAN_TRANS; idx++) + { + rv = _isis_vlan_trans_read(dev_id, idx, &t_pbmp, &temp); + if (SW_EMPTY == rv) + { + continue; + } + SW_RTN_ON_ERROR(rv); + + if (!aos_mem_cmp(&temp, &local, sizeof (fal_vlan_trans_entry_t))) + { + if (SW_IS_PBMP_MEMBER(t_pbmp, port_id)) + { + entry_idx = idx; + break; + } + } + } + + if (ISIS_MAX_VLAN_TRANS != entry_idx) + { + t_pbmp &= (~(0x1 << port_id)); + } + else + { + return SW_NOT_FOUND; + } + + return _isis_vlan_trans_write(dev_id, entry_idx, t_pbmp, local); +} + +static sw_error_t +_isis_port_vlan_trans_get(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_trans_entry_t * entry) +{ + sw_error_t rv; + fal_pbmp_t t_pbmp; + a_uint32_t idx; + fal_vlan_trans_entry_t temp, local; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (NULL == entry) + { + return SW_BAD_PTR; + } + aos_mem_zero(&local, sizeof(fal_vlan_trans_entry_t)); + rv = _isis_port_vlan_trans_convert(entry, &local); + SW_RTN_ON_ERROR(rv); + + for (idx = 0; idx < ISIS_MAX_VLAN_TRANS; idx++) + { + rv = _isis_vlan_trans_read(dev_id, idx, &t_pbmp, &temp); + if (SW_EMPTY == rv) + { + continue; + } + SW_RTN_ON_ERROR(rv); + + if (!aos_mem_cmp(&temp, &local, sizeof (fal_vlan_trans_entry_t))) + { + if (SW_IS_PBMP_MEMBER(t_pbmp, port_id)) + { + return SW_OK; + } + } + } + + return SW_NOT_FOUND; +} + +static sw_error_t +_isis_port_vlan_trans_iterate(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * iterator, + fal_vlan_trans_entry_t * entry) +{ + a_uint32_t index; + sw_error_t rv; + fal_vlan_trans_entry_t entry_t; + fal_pbmp_t pbmp_t; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if ((NULL == iterator) || (NULL == entry)) + { + return SW_BAD_PTR; + } + + if (ISIS_MAX_VLAN_TRANS < *iterator) + { + return SW_BAD_PARAM; + } + + for (index = *iterator; index < ISIS_MAX_VLAN_TRANS; index++) + { + rv = _isis_vlan_trans_read(dev_id, index, &pbmp_t, &entry_t); + if (SW_EMPTY == rv) + { + continue; + } + + if (SW_IS_PBMP_MEMBER(pbmp_t, port_id)) + { + aos_mem_copy(entry, &entry_t, sizeof (fal_vlan_trans_entry_t)); + break; + } + } + + if (ISIS_MAX_VLAN_TRANS == index) + { + return SW_NO_MORE; + } + + *iterator = index + 1; + return SW_OK; +} + +static sw_error_t +_isis_qinq_mode_set(a_uint32_t dev_id, fal_qinq_mode_t mode) +{ + sw_error_t rv; + a_uint32_t stag = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_QINQ_MODE_BUTT <= mode) + { + return SW_BAD_PARAM; + } + + if (FAL_QINQ_STAG_MODE == mode) + { + stag = 1; + } + + HSL_REG_FIELD_SET(rv, dev_id, SERVICE_TAG, 0, + STAG_MODE, (a_uint8_t *) (&stag), sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_isis_qinq_mode_get(a_uint32_t dev_id, fal_qinq_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t stag = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, SERVICE_TAG, 0, + STAG_MODE, (a_uint8_t *) (&stag), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (stag) + { + *mode = FAL_QINQ_STAG_MODE; + } + else + { + *mode = FAL_QINQ_CTAG_MODE; + } + + return SW_OK; +} + +static sw_error_t +_isis_port_qinq_role_set(a_uint32_t dev_id, fal_port_t port_id, + fal_qinq_port_role_t role) +{ + sw_error_t rv; + a_uint32_t core = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_QINQ_PORT_ROLE_BUTT <= role) + { + return SW_BAD_PARAM; + } + + if (FAL_QINQ_CORE_PORT == role) + { + core = 1; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN1, port_id, + COREP_EN, (a_uint8_t *) (&core), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + rv = _isis_port_route_defv_set(dev_id, port_id); + return rv; +} + +static sw_error_t +_isis_port_qinq_role_get(a_uint32_t dev_id, fal_port_t port_id, + fal_qinq_port_role_t * role) +{ + sw_error_t rv; + a_uint32_t core = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN1, port_id, + COREP_EN, (a_uint8_t *) (&core), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (core) + { + *role = FAL_QINQ_CORE_PORT; + } + else + { + *role = FAL_QINQ_EDGE_PORT; + } + + return SW_OK; +} + +static sw_error_t +_isis_port_mac_vlan_xlt_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PRI_CTL, port_id, + EG_MAC_BASE_VLAN_EN, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; + +} + +static sw_error_t +_isis_port_mac_vlan_xlt_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PRI_CTL, port_id, + EG_MAC_BASE_VLAN_EN, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +/** + * @brief Set 802.1q work mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] port_1qmode 802.1q work mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_1qmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t port_1qmode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_1qmode_set(dev_id, port_id, port_1qmode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get 802.1q work mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] port_1qmode 802.1q work mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_1qmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t * pport_1qmode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_1qmode_get(dev_id, port_id, pport_1qmode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set packets transmitted out vlan tagged mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] port_egvlanmode packets transmitted out vlan tagged mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_egvlanmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t port_egvlanmode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_egvlanmode_set(dev_id, port_id, port_egvlanmode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get packets transmitted out vlan tagged mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] port_egvlanmode packets transmitted out vlan tagged mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_egvlanmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t * pport_egvlanmode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_egvlanmode_get(dev_id, port_id, pport_egvlanmode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add member of port based vlan on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mem_port_id port member + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_portvlan_member_add(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_portvlan_member_add(dev_id, port_id, mem_port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete member of port based vlan on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mem_port_id port member + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_portvlan_member_del(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_portvlan_member_del(dev_id, port_id, mem_port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Update member of port based vlan on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mem_port_map port members + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_portvlan_member_update(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t mem_port_map) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_portvlan_member_update(dev_id, port_id, mem_port_map); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get member of port based vlan on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mem_port_map port members + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_portvlan_member_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t * mem_port_map) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_portvlan_member_get(dev_id, port_id, mem_port_map); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set force default vlan id status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_force_default_vid_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_force_default_vid_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get force default vlan id status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_force_default_vid_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_force_default_vid_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set force port based vlan status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_force_portvlan_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_force_portvlan_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get force port based vlan status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_force_portvlan_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_force_portvlan_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set nest vlan tpid on a particular device. + * @param[in] dev_id device id + * @param[in] tpid tag protocol identification + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_nestvlan_tpid_set(a_uint32_t dev_id, a_uint32_t tpid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_nestvlan_tpid_set(dev_id, tpid); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get nest vlan tpid on a particular device. + * @param[in] dev_id device id + * @param[out] tpid tag protocol identification + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_nestvlan_tpid_get(a_uint32_t dev_id, a_uint32_t * tpid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_nestvlan_tpid_get(dev_id, tpid); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set ingress vlan mode mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode ingress vlan mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_invlan_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_invlan_mode_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_invlan_mode_set(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get ingress vlan mode mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mode ingress vlan mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_invlan_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_invlan_mode_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_invlan_mode_get(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set tls status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_tls_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_tls_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get tls status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_tls_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_tls_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set priority propagation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_pri_propagation_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_pri_propagation_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get priority propagation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_pri_propagation_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_pri_propagation_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set default s-vid on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] vid s-vid + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_default_svid_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_default_svid_set(dev_id, port_id, vid); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get default s-vid on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] vid s-vid + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_default_svid_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_default_svid_get(dev_id, port_id, vid); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set default c-vid on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] vid c-vid + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_default_cvid_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_default_cvid_set(dev_id, port_id, vid); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get default c-vid on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] vid c-vid + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_default_cvid_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_default_cvid_get(dev_id, port_id, vid); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set vlan propagation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode vlan propagation mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_vlan_propagation_set(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_propagation_mode_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_vlan_propagation_set(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get vlan propagation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mode vlan propagation mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_vlan_propagation_get(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_propagation_mode_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_vlan_propagation_get(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add a vlan translation entry to a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param entry vlan translation entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_vlan_trans_add(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_trans_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_vlan_trans_add(dev_id, port_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a vlan translation entry from a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param entry vlan translation entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_vlan_trans_del(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_trans_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_vlan_trans_del(dev_id, port_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get a vlan translation entry from a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param entry vlan translation entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_vlan_trans_get(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_trans_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_vlan_trans_get(dev_id, port_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Iterate all vlan translation entries from a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] iterator translation entry index if it's zero means get the first entry + * @param[out] iterator next valid translation entry index + * @param[out] entry vlan translation entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_port_vlan_trans_iterate(dev_id, port_id, iterator, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set switch qinq work mode on a particular device. + * @param[in] dev_id device id + * @param[in] mode qinq work mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_qinq_mode_set(a_uint32_t dev_id, fal_qinq_mode_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_qinq_mode_set(dev_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get switch qinq work mode on a particular device. + * @param[in] dev_id device id + * @param[out] mode qinq work mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_qinq_mode_get(a_uint32_t dev_id, fal_qinq_mode_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_qinq_mode_get(dev_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set qinq role on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] role port role + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_qinq_role_set(a_uint32_t dev_id, fal_port_t port_id, + fal_qinq_port_role_t role) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_qinq_role_set(dev_id, port_id, role); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get qinq role on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] role port role + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_qinq_role_get(a_uint32_t dev_id, fal_port_t port_id, + fal_qinq_port_role_t * role) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_qinq_role_get(dev_id, port_id, role); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set MAC_VLAN_XLT status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] role port role + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_mac_vlan_xlt_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_mac_vlan_xlt_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get MAC_VLAN_XLT status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] role port role + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_mac_vlan_xlt_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_mac_vlan_xlt_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +#ifdef HSL_STANDALONG +HSL_LOCAL sw_error_t +isis_port_route_defv_set(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv =_isis_port_route_defv_set(dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} +#endif + +sw_error_t +isis_portvlan_init(a_uint32_t dev_id) +{ + a_uint32_t i; + sw_error_t rv; + fal_vlan_trans_entry_t entry_init; + hsl_api_t *p_api; + + HSL_DEV_ID_CHECK(dev_id); + + aos_mem_set(&entry_init, 0, sizeof (fal_vlan_trans_entry_t)); + + for (i = 0; i < ISIS_MAX_VLAN_TRANS; i++) + { + rv = _isis_vlan_trans_write(dev_id, i, 0, entry_init); + SW_RTN_ON_ERROR(rv); + } + +#ifndef HSL_STANDALONG + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->port_1qmode_get = isis_port_1qmode_get; + p_api->port_1qmode_set = isis_port_1qmode_set; + p_api->port_egvlanmode_get = isis_port_egvlanmode_get; + p_api->port_egvlanmode_set = isis_port_egvlanmode_set; + p_api->portvlan_member_add = isis_portvlan_member_add; + p_api->portvlan_member_del = isis_portvlan_member_del; + p_api->portvlan_member_update = isis_portvlan_member_update; + p_api->portvlan_member_get = isis_portvlan_member_get; + p_api->port_force_default_vid_set = isis_port_force_default_vid_set; + p_api->port_force_default_vid_get = isis_port_force_default_vid_get; + p_api->port_force_portvlan_set = isis_port_force_portvlan_set; + p_api->port_force_portvlan_get = isis_port_force_portvlan_get; + p_api->nestvlan_tpid_set = isis_nestvlan_tpid_set; + p_api->nestvlan_tpid_get = isis_nestvlan_tpid_get; + p_api->port_invlan_mode_set = isis_port_invlan_mode_set; + p_api->port_invlan_mode_get = isis_port_invlan_mode_get; + p_api->port_tls_set = isis_port_tls_set; + p_api->port_tls_get = isis_port_tls_get; + p_api->port_pri_propagation_set = isis_port_pri_propagation_set; + p_api->port_pri_propagation_get = isis_port_pri_propagation_get; + p_api->port_default_svid_set = isis_port_default_svid_set; + p_api->port_default_svid_get = isis_port_default_svid_get; + p_api->port_default_cvid_set = isis_port_default_cvid_set; + p_api->port_default_cvid_get = isis_port_default_cvid_get; + p_api->port_vlan_propagation_set = isis_port_vlan_propagation_set; + p_api->port_vlan_propagation_get = isis_port_vlan_propagation_get; + p_api->port_vlan_trans_add = isis_port_vlan_trans_add; + p_api->port_vlan_trans_del = isis_port_vlan_trans_del; + p_api->port_vlan_trans_get = isis_port_vlan_trans_get; + p_api->qinq_mode_set = isis_qinq_mode_set; + p_api->qinq_mode_get = isis_qinq_mode_get; + p_api->port_qinq_role_set = isis_port_qinq_role_set; + p_api->port_qinq_role_get = isis_port_qinq_role_get; + p_api->port_vlan_trans_iterate = isis_port_vlan_trans_iterate; + p_api->port_mac_vlan_xlt_set = isis_port_mac_vlan_xlt_set; + p_api->port_mac_vlan_xlt_get = isis_port_mac_vlan_xlt_get; +#endif + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_qos.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_qos.c new file mode 100755 index 000000000..0162b3a82 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_qos.c @@ -0,0 +1,1325 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup isis_qos ISIS_QOS + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isis_qos.h" +#include "isis_reg.h" + +#define ISIS_QOS_QUEUE_TX_BUFFER_MAX 60 +#define ISIS_QOS_PORT_TX_BUFFER_MAX 252 +#define ISIS_QOS_PORT_RX_BUFFER_MAX 60 + +//#define ISIS_MIN_QOS_MODE_PRI 0 +#define ISIS_MAX_QOS_MODE_PRI 3 +#define ISIS_MAX_PRI 7 +#define ISIS_MAX_QUEUE 3 +#define ISIS_MAX_EH_QUEUE 5 + +static sw_error_t +_isis_qos_queue_tx_buf_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_HOL_CTL1, port_id, QUEUE_DESC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_qos_queue_tx_buf_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_HOL_CTL1, port_id, QUEUE_DESC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isis_qos_port_tx_buf_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_HOL_CTL1, port_id, PORT_DESC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_qos_port_tx_buf_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_HOL_CTL1, port_id, PORT_DESC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isis_qos_port_queue_check(fal_port_t port_id, fal_queue_t queue_id) +{ + if ((0 == port_id) || (5 == port_id) || (6 == port_id)) + { + if (ISIS_MAX_EH_QUEUE < queue_id) + { + return SW_BAD_PARAM; + } + } + else + { + if (ISIS_MAX_QUEUE < queue_id) + { + return SW_BAD_PARAM; + } + } + + return SW_OK; +} + +static sw_error_t +_isis_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) +{ + a_uint32_t data = 0, val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (ISIS_QOS_QUEUE_TX_BUFFER_MAX < *number) + { + return SW_BAD_PARAM; + } + + rv = _isis_qos_port_queue_check(port_id, queue_id); + SW_RTN_ON_ERROR(rv); + + val = *number / 4; + *number = val << 2; + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_HOL_CTL0, port_id, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data &= (~(0xf << (queue_id << 2))); + data |= (val << (queue_id << 2)); + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_HOL_CTL0, port_id, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return rv; +} + +static sw_error_t +_isis_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) +{ + a_uint32_t data= 0, val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + rv = _isis_qos_port_queue_check(port_id, queue_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_HOL_CTL0, port_id, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + val = (data >> (queue_id << 2)) & 0xf; + *number = val << 2; + return SW_OK; +} + +static sw_error_t +_isis_qos_port_tx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (ISIS_QOS_PORT_TX_BUFFER_MAX < *number) + { + return SW_BAD_PARAM; + } + + val = *number / 4; + *number = val << 2; + HSL_REG_FIELD_SET(rv, dev_id, PORT_HOL_CTL0, port_id, PORT_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_qos_port_tx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_HOL_CTL0, port_id, PORT_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *number = val << 2; + return SW_OK; +} + +static sw_error_t +_isis_qos_port_rx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (ISIS_QOS_PORT_RX_BUFFER_MAX < *number) + { + return SW_BAD_PARAM; + } + + val = *number / 4; + *number = val << 2; + HSL_REG_FIELD_SET(rv, dev_id, PORT_HOL_CTL1, port_id, PORT_IN_DESC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_qos_port_rx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_HOL_CTL1, port_id, PORT_IN_DESC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *number = val << 2; + return SW_OK; +} + +static sw_error_t +_isis_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; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + if (FAL_QOS_DA_MODE == mode) + { + HSL_REG_FIELD_SET(rv, dev_id, PRI_CTL, port_id, DA_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (FAL_QOS_UP_MODE == mode) + { + HSL_REG_FIELD_SET(rv, dev_id, PRI_CTL, port_id, VLAN_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (FAL_QOS_DSCP_MODE == mode) + { + HSL_REG_FIELD_SET(rv, dev_id, PRI_CTL, port_id, IP_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + + return rv; +} + +static sw_error_t +_isis_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; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_QOS_DA_MODE == mode) + { + HSL_REG_FIELD_GET(rv, dev_id, PRI_CTL, port_id, DA_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (FAL_QOS_UP_MODE == mode) + { + HSL_REG_FIELD_GET(rv, dev_id, PRI_CTL, port_id, VLAN_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (FAL_QOS_DSCP_MODE == mode) + { + HSL_REG_FIELD_GET(rv, dev_id, PRI_CTL, port_id, IP_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isis_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; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (ISIS_MAX_QOS_MODE_PRI < pri) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PRI_CTL, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_QOS_DA_MODE == mode) + { + SW_SET_REG_BY_FIELD(PRI_CTL, DA_PRI_SEL, pri, val); + } + else if (FAL_QOS_UP_MODE == mode) + { + SW_SET_REG_BY_FIELD(PRI_CTL, VLAN_PRI_SEL, pri, val); + } + else if (FAL_QOS_DSCP_MODE == mode) + { + SW_SET_REG_BY_FIELD(PRI_CTL, IP_PRI_SEL, pri, val); + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_ENTRY_SET(rv, dev_id, PRI_CTL, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_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; + a_uint32_t entry = 0, f_val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PRI_CTL, port_id, (a_uint8_t *) (&entry), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_QOS_DA_MODE == mode) + { + SW_GET_FIELD_BY_REG(PRI_CTL, DA_PRI_SEL, f_val, entry); + } + else if (FAL_QOS_UP_MODE == mode) + { + SW_GET_FIELD_BY_REG(PRI_CTL, VLAN_PRI_SEL, f_val, entry); + } + else if (FAL_QOS_DSCP_MODE == mode) + { + SW_GET_FIELD_BY_REG(PRI_CTL, IP_PRI_SEL, f_val, entry); + } + else + { + return SW_NOT_SUPPORTED; + } + + *pri = f_val; + return SW_OK; +} + +static sw_error_t +_isis_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; + a_uint32_t reg = 0, val, w[6] = { 0 }; + a_int32_t i, _index; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_SCH_SP_MODE == mode) + { + val = 0; + _index = -1; + } + else if (FAL_SCH_WRR_MODE == mode) + { + val = 3; + _index = 5; + } + else if (FAL_SCH_MIX_MODE == mode) + { + val = 1; + _index = 4; + } + else if (FAL_SCH_MIX_PLUS_MODE == mode) + { + val = 2; + _index = 3; + } + else + { + return SW_NOT_SUPPORTED; + } + + for (i = _index; i >= 0; i--) + { + if (weight[i] > 0x1f) + { + return SW_BAD_PARAM; + } + w[i] = weight[i]; + } + + HSL_REG_ENTRY_GET(rv, dev_id, WRR_CTRL, port_id, (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(WRR_CTRL, SCH_MODE, val, reg); + SW_SET_REG_BY_FIELD(WRR_CTRL, Q5_W, w[5], reg); + SW_SET_REG_BY_FIELD(WRR_CTRL, Q4_W, w[4], reg); + SW_SET_REG_BY_FIELD(WRR_CTRL, Q3_W, w[3], reg); + SW_SET_REG_BY_FIELD(WRR_CTRL, Q2_W, w[2], reg); + SW_SET_REG_BY_FIELD(WRR_CTRL, Q1_W, w[1], reg); + SW_SET_REG_BY_FIELD(WRR_CTRL, Q0_W, w[0], reg); + + HSL_REG_ENTRY_SET(rv, dev_id, WRR_CTRL, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_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; + a_uint32_t val = 0, sch, w[6], i; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_ENTRY_GET(rv, dev_id, WRR_CTRL, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(WRR_CTRL, SCH_MODE, sch, val); + SW_GET_FIELD_BY_REG(WRR_CTRL, Q5_W, w[5], val); + SW_GET_FIELD_BY_REG(WRR_CTRL, Q4_W, w[4], val); + SW_GET_FIELD_BY_REG(WRR_CTRL, Q3_W, w[3], val); + SW_GET_FIELD_BY_REG(WRR_CTRL, Q2_W, w[2], val); + SW_GET_FIELD_BY_REG(WRR_CTRL, Q1_W, w[1], val); + SW_GET_FIELD_BY_REG(WRR_CTRL, Q0_W, w[0], val); + + if (0 == sch) + { + *mode = FAL_SCH_SP_MODE; + } + else if (1 == sch) + { + *mode = FAL_SCH_MIX_MODE; + } + else if (2 == sch) + { + *mode = FAL_SCH_MIX_PLUS_MODE; + } + else + { + *mode = FAL_SCH_WRR_MODE; + } + + for (i = 0; i < 6; i++) + { + weight[i] = w[i]; + } + + return SW_OK; +} + +static sw_error_t +_isis_qos_port_default_spri_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t spri) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (ISIS_MAX_PRI < spri) + { + return SW_BAD_PARAM; + } + + val = spri; + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN0, port_id, + ING_SPRI, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_isis_qos_port_default_spri_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * spri) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN0, port_id, + ING_SPRI, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + *spri = val & 0x7; + return rv; +} + +static sw_error_t +_isis_qos_port_default_cpri_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t cpri) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (ISIS_MAX_PRI < cpri) + { + return SW_BAD_PARAM; + } + + val = cpri; + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN0, port_id, + ING_CPRI, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + return rv; +} + +HSL_LOCAL sw_error_t +_isis_qos_port_default_cpri_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * cpri) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN0, port_id, + ING_CPRI, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + *cpri = val & 0x7; + return rv; +} + +static sw_error_t +_isis_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; + a_uint32_t addr, data = 0; + a_uint32_t base[7] = {0x0c40, 0x0c48, 0x0c4c, 0x0c50, 0x0c54, 0x0c58, 0x0c60}; + + rv = _isis_qos_port_queue_check(port_id, queue_id); + SW_RTN_ON_ERROR(rv); + + addr = base[port_id] + ((queue_id / 4) << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data &= (~(0xff << ((queue_id % 4) << 3))); + data |= (((enable << 7 ) | (tbl_id & 0xf)) << ((queue_id % 4) << 3)); + + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +HSL_LOCAL sw_error_t +_isis_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; + a_uint32_t addr, data = 0; + a_uint32_t base[7] = {0x0c40, 0x0c48, 0x0c4c, 0x0c50, 0x0c54, 0x0c58, 0x0c60}; + + rv = _isis_qos_port_queue_check(port_id, queue_id); + SW_RTN_ON_ERROR(rv); + + addr = base[port_id] + ((queue_id / 4) << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *tbl_id = (data >> ((queue_id % 4) << 3)) & 0xf; + *enable = ((data >> ((queue_id % 4) << 3)) & 0x80) >> 7; + return SW_OK; +} + +HSL_LOCAL sw_error_t +_isis_port_static_thresh_get(a_uint32_t dev_id, fal_port_t port_id, + fal_bm_static_cfg_t *cfg) +{ + sw_error_t rv; + a_uint32_t reg_value, xon_value, xoff_value; + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_FLOW_CTRL_THRESHOLD, port_id, + (a_uint8_t *) (®_value), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_FLOW_CTRL_THRESHOLD, XON_THRES, xon_value, reg_value); + SW_GET_FIELD_BY_REG(PORT_FLOW_CTRL_THRESHOLD, XOFF_THRES, xoff_value, reg_value); + cfg->max_thresh = xoff_value; + cfg->resume_off = xoff_value - xon_value; + + return SW_OK; +} + +HSL_LOCAL sw_error_t +_isis_port_static_thresh_set(a_uint32_t dev_id, fal_port_t port_id, + fal_bm_static_cfg_t *cfg) +{ + sw_error_t rv; + a_uint32_t reg_value = 0; + + SW_SET_REG_BY_FIELD(PORT_FLOW_CTRL_THRESHOLD, XON_THRES, cfg->max_thresh - cfg->resume_off, reg_value); + SW_SET_REG_BY_FIELD(PORT_FLOW_CTRL_THRESHOLD, XOFF_THRES, cfg->max_thresh, reg_value); + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_FLOW_CTRL_THRESHOLD, port_id, + (a_uint8_t *) (®_value), sizeof (a_uint32_t)); + + return SW_OK; +} + +/** + * @brief Set buffer aggsinment status of transmitting queue on one particular port. + * @details Comments: + * If enable queue tx buffer on one port that means each queue of this port + * will have fixed number buffers when transmitting packets. Otherwise they + * share the whole buffers with other queues in device. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_qos_queue_tx_buf_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_qos_queue_tx_buf_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get buffer aggsinment status of transmitting queue on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_qos_queue_tx_buf_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_qos_queue_tx_buf_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set buffer aggsinment status of transmitting port on one particular port. + * @details Comments: + If enable tx buffer on one port that means this port will have fixed + number buffers when transmitting packets. Otherwise they will + share the whole buffers with other ports in device. + * function will return actual buffer numbers in hardware. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_qos_port_tx_buf_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_qos_port_tx_buf_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get buffer aggsinment status of transmitting port on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_qos_port_tx_buf_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_qos_port_tx_buf_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set max occupied buffer number of transmitting queue on one particular port. + * @details Comments: + The step of buffer number in Garuda is 4, function will return actual + buffer numbers in hardware. + The buffer number range for queue is 4 to 60. + * share the whole buffers with other ports in device. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param number buffer number + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_qos_queue_tx_buf_nr_set(dev_id, port_id, queue_id, number); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get max occupied buffer number of transmitting queue on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param[out] number buffer number + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_qos_queue_tx_buf_nr_get(dev_id, port_id, queue_id, number); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set max occupied buffer number of transmitting port on one particular port. + * @details Comments: + The step of buffer number in Garuda is four, function will return actual + buffer numbers in hardware. + The buffer number range for transmitting port is 4 to 124. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param number buffer number + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_qos_port_tx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_qos_port_tx_buf_nr_set(dev_id, port_id, number); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get max occupied buffer number of transmitting port on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] number buffer number + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_qos_port_tx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_qos_port_tx_buf_nr_get(dev_id, port_id, number); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set max occupied buffer number of receiving port on one particular port. + * @details Comments: + The step of buffer number in Shiva is four, function will return actual + buffer numbers in hardware. + The buffer number range for receiving port is 4 to 60. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param number buffer number + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_qos_port_rx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_qos_port_rx_buf_nr_set(dev_id, port_id, number); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get max occupied buffer number of receiving port on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] number buffer number + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_qos_port_rx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_qos_port_rx_buf_nr_get(dev_id, port_id, number); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set port qos mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode qos mode + * @param[in] enable A_TRUE of A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_qos_port_mode_set(dev_id, port_id, mode, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get port qos mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode qos mode + * @param[out] enable A_TRUE of A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_qos_port_mode_get(dev_id, port_id, mode, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set priority of one particular qos mode on one particular port. + * @details Comments: + If the priority of a mode is more small then the priority is more high. + Differnet mode should have differnet priority. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode qos mode + * @param[in] pri priority of one particular qos mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_qos_port_mode_pri_set(dev_id, port_id, mode, pri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get priority of one particular qos mode on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode qos mode + * @param[out] pri priority of one particular qos mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_qos_port_mode_pri_get(dev_id, port_id, mode, pri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set traffic scheduling mode on particular one port. + * @details Comments: + * When scheduling mode is sp the weight is meaningless usually it's zero + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] fal_sch_mode_t traffic scheduling mode + * @param[in] weight[] weight value for each queue when in wrr mode, + the max value supported by ISIS is 0x1f. + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_qos_port_sch_mode_set(dev_id, port_id, mode, weight); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get traffic scheduling mode on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] fal_sch_mode_t traffic scheduling mode + * @param[out] weight weight value for wrr mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_qos_port_sch_mode_get(dev_id, port_id, mode, weight); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set default stag priority on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] spri vlan priority + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_qos_port_default_spri_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t spri) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_qos_port_default_spri_set(dev_id, port_id, spri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get default stag priority on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] spri vlan priority + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_qos_port_default_spri_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * spri) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_qos_port_default_spri_get(dev_id, port_id, spri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set default ctag priority on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] cpri vlan priority + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_qos_port_default_cpri_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t cpri) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_qos_port_default_cpri_set(dev_id, port_id, cpri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get default ctag priority on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] cpri vlan priority + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_qos_port_default_cpri_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * cpri) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_qos_port_default_cpri_get(dev_id, port_id, cpri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set egress queue based CoS remark on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param[in] tbl_id CoS remark table id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_qos_queue_remark_table_set(dev_id, port_id, queue_id, tbl_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get egress queue based CoS remark on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param[out] tbl_id CoS remark table id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_qos_queue_remark_table_get(dev_id, port_id, queue_id, tbl_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get static flow control threshold on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] static maximum threshold and resume offset + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_static_thresh_get(a_uint32_t dev_id, fal_port_t port_id, + fal_bm_static_cfg_t *cfg) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_static_thresh_get(dev_id, port_id, cfg); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set static flow control threshold on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] static maximum threshold and resume offset + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_port_static_thresh_set(a_uint32_t dev_id, fal_port_t port_id, + fal_bm_static_cfg_t *cfg) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_port_static_thresh_set(dev_id, port_id, cfg); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +isis_qos_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->qos_queue_tx_buf_status_set = isis_qos_queue_tx_buf_status_set; + p_api->qos_queue_tx_buf_status_get = isis_qos_queue_tx_buf_status_get; + p_api->qos_port_tx_buf_status_set = isis_qos_port_tx_buf_status_set; + p_api->qos_port_tx_buf_status_get = isis_qos_port_tx_buf_status_get; + p_api->qos_queue_tx_buf_nr_set = isis_qos_queue_tx_buf_nr_set; + p_api->qos_queue_tx_buf_nr_get = isis_qos_queue_tx_buf_nr_get; + p_api->qos_port_tx_buf_nr_set = isis_qos_port_tx_buf_nr_set; + p_api->qos_port_tx_buf_nr_get = isis_qos_port_tx_buf_nr_get; + p_api->qos_port_rx_buf_nr_set = isis_qos_port_rx_buf_nr_set; + p_api->qos_port_rx_buf_nr_get = isis_qos_port_rx_buf_nr_get; + p_api->qos_port_mode_set = isis_qos_port_mode_set; + p_api->qos_port_mode_get = isis_qos_port_mode_get; + p_api->qos_port_mode_pri_set = isis_qos_port_mode_pri_set; + p_api->qos_port_mode_pri_get = isis_qos_port_mode_pri_get; + p_api->qos_port_sch_mode_set = isis_qos_port_sch_mode_set; + p_api->qos_port_sch_mode_get = isis_qos_port_sch_mode_get; + p_api->qos_port_default_spri_set = isis_qos_port_default_spri_set; + p_api->qos_port_default_spri_get = isis_qos_port_default_spri_get; + p_api->qos_port_default_cpri_set = isis_qos_port_default_cpri_set; + p_api->qos_port_default_cpri_get = isis_qos_port_default_cpri_get; + p_api->qos_queue_remark_table_set = isis_qos_queue_remark_table_set; + p_api->qos_queue_remark_table_get = isis_qos_queue_remark_table_get; + + p_api->port_static_thresh_get = isis_port_static_thresh_get; + p_api->port_static_thresh_set = isis_port_static_thresh_set; + } +#endif + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_rate.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_rate.c new file mode 100755 index 000000000..8e516ed3e --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_rate.c @@ -0,0 +1,1549 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup isis_rate ISIS_RATE + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isis_rate.h" +#include "isis_reg.h" + +#define ISIS_MAX_POLICER_ID 31 +#define ISIS_MAX_QUEUE 3 +#define ISIS_MAX_EH_QUEUE 5 + +#define ACL_POLICER_CNT_SEL_ADDR 0x09f0 +#define ACL_POLICER_CNT_MODE_ADDR 0x09f4 +#define ACL_POLICER_CNT_RST_ADDR 0x09f8 + +static sw_error_t +_isis_rate_port_queue_check(fal_port_t port_id, fal_queue_t queue_id) +{ + if ((0 == port_id) || (5 == port_id) || (6 == port_id)) + { + if (ISIS_MAX_EH_QUEUE < queue_id) + { + return SW_BAD_PARAM; + } + } + else + { + if (ISIS_MAX_QUEUE < queue_id) + { + return SW_BAD_PARAM; + } + } + + return SW_OK; +} + +static void +_isis_egress_bs_byte_sw_to_hw(a_uint32_t sw_bs, a_uint32_t * hw_bs) +{ + a_int32_t i; + a_uint32_t data[8] = + { + 0, 2 * 1024, 4 * 1024, 8 * 1024, 16 * 1024, 32 * 1024, 128 * 1024, + 512 * 1024 + }; + + for (i = 7; i >= 0; i--) + { + if (sw_bs >= data[i]) + { + *hw_bs = i; + break; + } + } +} + +static void +_isis_egress_bs_byte_hw_to_sw(a_uint32_t hw_bs, a_uint32_t * sw_bs) +{ + a_uint32_t data[8] = + { + 0, 2 * 1024, 4 * 1024, 8 * 1024, 16 * 1024, 32 * 1024, 128 * 1024, + 512 * 1024 + }; + + *sw_bs = data[hw_bs & 0x7]; +} + +static void +_isis_egress_bs_frame_sw_to_hw(a_uint32_t sw_bs, a_uint32_t * hw_bs) +{ + a_uint32_t data[8] = { 0, 2, 4, 16, 64, 256, 512, 1024 }; + a_int32_t i; + + for (i = 7; i >= 0; i--) + { + if (sw_bs >= data[i]) + { + *hw_bs = i; + break; + } + } +} + +static void +_isis_egress_bs_frame_hw_to_sw(a_uint32_t hw_bs, a_uint32_t * sw_bs) +{ + a_uint32_t data[8] = { 0, 2, 4, 16, 64, 256, 512, 1024 }; + + *sw_bs = data[hw_bs & 0x7]; +} + +static void +_isis_ingress_bs_byte_sw_to_hw(a_uint32_t sw_bs, a_uint32_t * hw_bs) +{ + a_int32_t i; + a_uint32_t data[8] = + { + 0, 4 * 1024, 32 * 1024, 128 * 1024, 512 * 1024, 2 * 1024 * 1024, + 8 * 1024 * 1024, 32 * 1024 * 1024 + }; + + for (i = 7; i >= 0; i--) + { + if (sw_bs >= data[i]) + { + *hw_bs = i; + break; + } + } +} + +static void +_isis_ingress_bs_byte_hw_to_sw(a_uint32_t hw_bs, a_uint32_t * sw_bs) +{ + a_uint32_t data[8] = + { + 0, 4 * 1024, 32 * 1024, 128 * 1024, 512 * 1024, 2 * 1024 * 1024, + 8 * 1024 * 1024, 32 * 1024 * 1024 + }; + + *sw_bs = data[hw_bs & 0x7]; +} + +static void +_isis_ingress_bs_frame_sw_to_hw(a_uint32_t sw_bs, a_uint32_t * hw_bs) +{ + a_uint32_t data[8] = { 0, 4, 16, 64, 256, 1024, 4096, 16384 }; + a_int32_t i; + + for (i = 7; i >= 0; i--) + { + if (sw_bs >= data[i]) + { + *hw_bs = i; + break; + } + } +} + +static void +_isis_ingress_bs_frame_hw_to_sw(a_uint32_t hw_bs, a_uint32_t * sw_bs) +{ + a_uint32_t data[8] = { 0, 4, 16, 64, 256, 1024, 4096, 16384 }; + + *sw_bs = data[hw_bs & 0x7]; +} + +static void +_isis_rate_flag_parse(a_uint32_t sw_flag, a_uint32_t * hw_flag) +{ + *hw_flag = 0; + + if (FAL_INGRESS_POLICING_TCP_CTRL & sw_flag) + { + *hw_flag |= (0x1 << 1); + } + + if (FAL_INGRESS_POLICING_MANAGEMENT & sw_flag) + { + *hw_flag |= (0x1 << 2); + } + + if (FAL_INGRESS_POLICING_BROAD & sw_flag) + { + *hw_flag |= (0x1 << 3); + } + + if (FAL_INGRESS_POLICING_UNK_UNI & sw_flag) + { + *hw_flag |= (0x1 << 4); + } + + if (FAL_INGRESS_POLICING_UNK_MUL & sw_flag) + { + *hw_flag |= (0x1 << 5); + } + + if (FAL_INGRESS_POLICING_UNI & sw_flag) + { + *hw_flag |= (0x1 << 6); + } + + if (FAL_INGRESS_POLICING_MUL & sw_flag) + { + *hw_flag |= (0x1 << 7); + } +} + +static void +_isis_rate_flag_reparse(a_uint32_t hw_flag, a_uint32_t * sw_flag) +{ + *sw_flag = 0; + + if (hw_flag & 0x2) + { + *sw_flag |= FAL_INGRESS_POLICING_TCP_CTRL; + } + + if (hw_flag & 0x4) + { + *sw_flag |= FAL_INGRESS_POLICING_MANAGEMENT; + } + + if (hw_flag & 0x8) + { + *sw_flag |= FAL_INGRESS_POLICING_BROAD; + } + + if (hw_flag & 0x10) + { + *sw_flag |= FAL_INGRESS_POLICING_UNK_UNI; + } + + if (hw_flag & 0x20) + { + *sw_flag |= FAL_INGRESS_POLICING_UNK_MUL; + } + + if (hw_flag & 0x40) + { + *sw_flag |= FAL_INGRESS_POLICING_UNI; + } + + if (hw_flag & 0x80) + { + *sw_flag |= FAL_INGRESS_POLICING_MUL; + } +} + +static void +_isis_rate_ts_parse(fal_rate_mt_t sw, a_uint32_t * hw) +{ + if (FAL_RATE_MI_100US == sw) + { + *hw = 0; + } + else if (FAL_RATE_MI_1MS == sw) + { + *hw = 1; + } + else if (FAL_RATE_MI_10MS == sw) + { + *hw = 2; + } + else if (FAL_RATE_MI_100MS) + { + *hw = 3; + } + else + { + *hw = 0; + } +} + +static void +_isis_rate_ts_reparse(a_uint32_t hw, fal_rate_mt_t * sw) +{ + if (0 == hw) + { + *sw = FAL_RATE_MI_100US; + } + else if (1 == hw) + { + *sw = FAL_RATE_MI_1MS; + } + else if (2 == hw) + { + *sw = FAL_RATE_MI_10MS; + } + else + { + *sw = FAL_RATE_MI_100MS; + } +} + +static sw_error_t +_isis_rate_port_policer_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_policer_t * policer) +{ + sw_error_t rv; + a_uint32_t cir = 0x7fff, eir = 0x7fff, cbs = 0, ebs = 0, tmp, data[3] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + data[0] = 0x18000000; + if (FAL_BYTE_BASED == policer->meter_unit) + { + if (A_TRUE == policer->c_enable) + { + cir = policer->cir >> 5; + policer->cir = cir << 5; + _isis_ingress_bs_byte_sw_to_hw(policer->cbs, &cbs); + _isis_ingress_bs_byte_hw_to_sw(cbs, &(policer->cbs)); + } + + if (A_TRUE == policer->e_enable) + { + eir = policer->eir >> 5; + policer->eir = eir << 5; + _isis_ingress_bs_byte_sw_to_hw(policer->ebs, &ebs); + _isis_ingress_bs_byte_hw_to_sw(ebs, &(policer->ebs)); + } + + SW_SET_REG_BY_FIELD(INGRESS_POLICER1, INGRESS_UNIT, 0, data[1]); + } + else if (FAL_FRAME_BASED == policer->meter_unit) + { + if (A_TRUE == policer->c_enable) + { + cir = (policer->cir * 2) / 125; + policer->cir = cir / 2 * 125 + cir % 2 * 63; + _isis_ingress_bs_frame_sw_to_hw(policer->cbs, &cbs); + _isis_ingress_bs_frame_hw_to_sw(cbs, &(policer->cbs)); + } + + if (A_TRUE == policer->e_enable) + { + eir = (policer->eir * 2) / 125; + policer->eir = eir / 2 * 125 + eir % 2 * 63; + _isis_ingress_bs_frame_sw_to_hw(policer->ebs, &ebs); + _isis_ingress_bs_frame_hw_to_sw(ebs, &(policer->ebs)); + } + + SW_SET_REG_BY_FIELD(INGRESS_POLICER1, INGRESS_UNIT, 1, data[1]); + } + else + { + return SW_BAD_PARAM; + } + + SW_SET_REG_BY_FIELD(INGRESS_POLICER0, INGRESS_CIR, cir, data[0]); + SW_SET_REG_BY_FIELD(INGRESS_POLICER0, INGRESS_CBS, cbs, data[0]); + SW_SET_REG_BY_FIELD(INGRESS_POLICER1, INGRESS_EIR, eir, data[1]); + SW_SET_REG_BY_FIELD(INGRESS_POLICER1, INGRESS_EBS, ebs, data[1]); + + if (A_TRUE == policer->combine_mode) + { + SW_SET_REG_BY_FIELD(INGRESS_POLICER0, RATE_MODE, 1, data[0]); + } + + if (A_TRUE == policer->deficit_en) + { + SW_SET_REG_BY_FIELD(INGRESS_POLICER1, INGRESS_BORROW, 1, data[1]); + } + + if (A_TRUE == policer->color_mode) + { + SW_SET_REG_BY_FIELD(INGRESS_POLICER1, INGRESS_CM, 1, data[1]); + } + + if (A_TRUE == policer->couple_flag) + { + SW_SET_REG_BY_FIELD(INGRESS_POLICER1, INGRESS_CF, 1, data[1]); + } + + _isis_rate_ts_parse(policer->c_meter_interval, &tmp); + SW_SET_REG_BY_FIELD(INGRESS_POLICER0, C_ING_TS, tmp, data[0]); + + _isis_rate_ts_parse(policer->e_meter_interval, &tmp); + SW_SET_REG_BY_FIELD(INGRESS_POLICER1, E_ING_TS, tmp, data[1]); + + _isis_rate_flag_parse(policer->c_rate_flag, &tmp); + data[2] = (tmp << 8) & 0xff00; + + _isis_rate_flag_parse(policer->e_rate_flag, &tmp); + data[2] |= (tmp & 0xff); + + HSL_REG_ENTRY_SET(rv, dev_id, INGRESS_POLICER0, port_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, INGRESS_POLICER1, port_id, + (a_uint8_t *) (&data[1]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, INGRESS_POLICER2, port_id, + (a_uint8_t *) (&data[2]), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_rate_port_policer_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_policer_t * policer) +{ + sw_error_t rv; + a_uint32_t unit, ts, cir, eir, cbs, ebs, data[3] = {0}; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, INGRESS_POLICER0, port_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, INGRESS_POLICER1, port_id, + (a_uint8_t *) (&data[1]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, INGRESS_POLICER2, port_id, + (a_uint8_t *) (&data[2]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(INGRESS_POLICER0, INGRESS_CIR, cir, data[0]); + SW_GET_FIELD_BY_REG(INGRESS_POLICER0, INGRESS_CBS, cbs, data[0]); + SW_GET_FIELD_BY_REG(INGRESS_POLICER1, INGRESS_EIR, eir, data[1]); + SW_GET_FIELD_BY_REG(INGRESS_POLICER1, INGRESS_EBS, ebs, data[1]); + SW_GET_FIELD_BY_REG(INGRESS_POLICER1, INGRESS_UNIT, unit, data[1]); + + policer->c_enable = A_TRUE; + if (0x7fff == cir) + { + policer->c_enable = A_FALSE; + cir = 0; + } + + policer->e_enable = A_TRUE; + if (0x7fff == eir) + { + policer->e_enable = A_FALSE; + eir = 0; + } + + if (unit) + { + policer->meter_unit = FAL_FRAME_BASED; + policer->cir = cir / 2 * 125 + cir % 2 * 63; + policer->eir = eir / 2 * 125 + eir % 2 * 63; + _isis_ingress_bs_frame_hw_to_sw(cbs, &(policer->cbs)); + _isis_ingress_bs_frame_hw_to_sw(ebs, &(policer->ebs)); + } + else + { + policer->meter_unit = FAL_BYTE_BASED; + policer->cir = cir << 5; + policer->eir = eir << 5; + _isis_ingress_bs_byte_hw_to_sw(cbs, &(policer->cbs)); + _isis_ingress_bs_byte_hw_to_sw(ebs, &(policer->ebs)); + } + + SW_GET_FIELD_BY_REG(INGRESS_POLICER0, RATE_MODE, policer->combine_mode, + data[0]); + SW_GET_FIELD_BY_REG(INGRESS_POLICER1, INGRESS_BORROW, policer->deficit_en, + data[1]); + SW_GET_FIELD_BY_REG(INGRESS_POLICER1, INGRESS_CF, policer->couple_flag, + data[1]); + SW_GET_FIELD_BY_REG(INGRESS_POLICER1, INGRESS_CM, policer->color_mode, + data[1]); + + ts = (data[2] >> 8) & 0xff; + _isis_rate_flag_reparse(ts, &(policer->c_rate_flag)); + + ts = data[2] & 0xff; + _isis_rate_flag_reparse(ts, &(policer->e_rate_flag)); + + SW_GET_FIELD_BY_REG(INGRESS_POLICER0, C_ING_TS, ts, data[0]); + _isis_rate_ts_reparse(ts, &(policer->c_meter_interval)); + + SW_GET_FIELD_BY_REG(INGRESS_POLICER1, E_ING_TS, ts, data[1]); + _isis_rate_ts_reparse(ts, &(policer->e_meter_interval)); + + return SW_OK; +} + +static sw_error_t +_isis_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; + a_uint32_t data, cir, eir, cbs = 0, ebs = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_FALSE == enable) + { + aos_mem_zero(shaper, sizeof (fal_egress_shaper_t)); + + cir = 0x7fff; + eir = 0x7fff; + } + else + { + if (FAL_BYTE_BASED == shaper->meter_unit) + { + cir = shaper->cir >> 5; + shaper->cir = cir << 5; + + eir = shaper->eir >> 5; + shaper->eir = eir << 5; + + _isis_egress_bs_byte_sw_to_hw(shaper->cbs, &cbs); + _isis_egress_bs_byte_hw_to_sw(cbs, &(shaper->cbs)); + + _isis_egress_bs_byte_sw_to_hw(shaper->ebs, &ebs); + _isis_egress_bs_byte_hw_to_sw(ebs, &(shaper->ebs)); + + data = 0; + } + else if (FAL_FRAME_BASED == shaper->meter_unit) + { + cir = (shaper->cir * 2) / 125; + shaper->cir = cir / 2 * 125 + cir % 2 * 63; + + eir = (shaper->eir * 2) / 125; + shaper->eir = eir / 2 * 125 + eir % 2 * 63; + + _isis_egress_bs_frame_sw_to_hw(shaper->cbs, &cbs); + _isis_egress_bs_frame_hw_to_sw(cbs, &(shaper->cbs)); + + _isis_egress_bs_frame_sw_to_hw(shaper->ebs, &ebs); + _isis_egress_bs_frame_hw_to_sw(ebs, &(shaper->ebs)); + + data = 1; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q0_UNIT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data = 1; + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_PT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER0, port_id, EG_Q0_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER3, port_id, EG_Q0_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q0_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q0_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_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; + a_uint32_t data = 0, cir = 0, eir = 0, cbs = 0, ebs = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + aos_mem_zero(shaper, sizeof (fal_egress_shaper_t)); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_PT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (!data) + { + *enable = A_FALSE; + return SW_OK; + } + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER0, port_id, EG_Q0_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER3, port_id, EG_Q0_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q0_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q0_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if ((0x7fff == cir) && (0x7fff == eir)) + { + *enable = A_FALSE; + return SW_OK; + } + + *enable = A_TRUE; + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q0_UNIT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data) + { + shaper->meter_unit = FAL_FRAME_BASED; + shaper->cir = cir / 2 * 125 + cir % 2 * 63; + shaper->eir = eir / 2 * 125 + eir % 2 * 63; + _isis_egress_bs_frame_hw_to_sw(cbs, &(shaper->cbs)); + _isis_egress_bs_frame_hw_to_sw(ebs, &(shaper->ebs)); + } + else + { + shaper->meter_unit = FAL_BYTE_BASED; + shaper->cir = cir << 5; + shaper->eir = eir << 5; + _isis_egress_bs_byte_hw_to_sw(cbs, &(shaper->cbs)); + _isis_egress_bs_byte_hw_to_sw(ebs, &(shaper->ebs)); + } + + return SW_OK; +} + +static sw_error_t +_isis_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; + a_uint32_t unit = 0, data, cir, eir, cbs = 0, ebs = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + rv = _isis_rate_port_queue_check(port_id, queue_id); + SW_RTN_ON_ERROR(rv); + + if (A_FALSE == enable) + { + aos_mem_zero(shaper, sizeof (fal_egress_shaper_t)); + + cir = 0x7fff; + eir = 0x7fff; + } + else + { + if (FAL_BYTE_BASED == shaper->meter_unit) + { + cir = shaper->cir >> 5; + shaper->cir = cir << 5; + + eir = shaper->eir >> 5; + shaper->eir = eir << 5; + + _isis_egress_bs_byte_sw_to_hw(shaper->cbs, &cbs); + _isis_egress_bs_byte_hw_to_sw(cbs, &(shaper->cbs)); + + _isis_egress_bs_byte_sw_to_hw(shaper->ebs, &ebs); + _isis_egress_bs_byte_hw_to_sw(ebs, &(shaper->ebs)); + + unit = 0; + } + else if (FAL_FRAME_BASED == shaper->meter_unit) + { + cir = (shaper->cir * 2) / 125; + shaper->cir = cir / 2 * 125 + cir % 2 * 63; + + eir = (shaper->eir * 2) / 125; + shaper->eir = eir / 2 * 125 + eir % 2 * 63; + + _isis_egress_bs_frame_sw_to_hw(shaper->cbs, &cbs); + _isis_egress_bs_frame_hw_to_sw(cbs, &(shaper->cbs)); + + _isis_egress_bs_frame_sw_to_hw(shaper->ebs, &ebs); + _isis_egress_bs_frame_hw_to_sw(ebs, &(shaper->ebs)); + + unit = 1; + } + + data = 0; + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_PT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + if (0 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER0, port_id, EG_Q0_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER3, port_id, EG_Q0_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q0_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q0_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q0_UNIT, + (a_uint8_t *) (&unit), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else if (1 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER0, port_id, EG_Q1_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER3, port_id, EG_Q1_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q1_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q1_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q1_UNIT, + (a_uint8_t *) (&unit), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else if (2 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER1, port_id, EG_Q2_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER4, port_id, EG_Q2_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q2_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q2_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q2_UNIT, + (a_uint8_t *) (&unit), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else if (3 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER1, port_id, EG_Q3_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER4, port_id, EG_Q3_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q3_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q3_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q3_UNIT, + (a_uint8_t *) (&unit), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else if (4 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER2, port_id, EG_Q4_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER5, port_id, EG_Q4_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q4_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q4_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q4_UNIT, + (a_uint8_t *) (&unit), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else + { + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER2, port_id, EG_Q5_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER5, port_id, EG_Q5_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q5_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q5_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q5_UNIT, + (a_uint8_t *) (&unit), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +static sw_error_t +_isis_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; + a_uint32_t data = 0, cir = 0, eir = 0, cbs = 0, ebs = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + rv = _isis_rate_port_queue_check(port_id, queue_id); + SW_RTN_ON_ERROR(rv); + + aos_mem_zero(shaper, sizeof (fal_egress_shaper_t)); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_PT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data) + { + *enable = A_FALSE; + return SW_OK; + } + + if (0 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER0, port_id, EG_Q0_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER3, port_id, EG_Q0_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q0_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q0_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q0_UNIT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else if (1 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER0, port_id, EG_Q1_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER3, port_id, EG_Q1_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q1_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q1_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q1_UNIT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else if (2 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER1, port_id, EG_Q2_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER4, port_id, EG_Q2_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q2_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q2_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q2_UNIT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else if (3 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER1, port_id, EG_Q3_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER4, port_id, EG_Q3_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q3_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q3_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q3_UNIT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else if (4 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER2, port_id, EG_Q4_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER5, port_id, EG_Q4_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q4_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q4_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q4_UNIT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else + { + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER2, port_id, EG_Q5_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER5, port_id, EG_Q5_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q5_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q5_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q5_UNIT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + if ((0x7fff == cir) && (0x7fff == eir)) + { + *enable = A_FALSE; + return SW_OK; + } + + *enable = A_TRUE; + if (data) + { + shaper->meter_unit = FAL_FRAME_BASED; + shaper->cir = cir / 2 * 125 + cir % 2 * 63; + shaper->eir = eir / 2 * 125 + eir % 2 * 63; + _isis_egress_bs_frame_hw_to_sw(cbs, &(shaper->cbs)); + _isis_egress_bs_frame_hw_to_sw(ebs, &(shaper->ebs)); + } + else + { + shaper->meter_unit = FAL_BYTE_BASED; + shaper->cir = cir << 5; + shaper->eir = eir << 5; + _isis_egress_bs_byte_hw_to_sw(cbs, &(shaper->cbs)); + _isis_egress_bs_byte_hw_to_sw(ebs, &(shaper->ebs)); + } + + return SW_OK; +} + +static sw_error_t +_isis_rate_acl_policer_set(a_uint32_t dev_id, a_uint32_t policer_id, + fal_acl_policer_t * policer) +{ + sw_error_t rv; + a_uint32_t ts, cir, eir, cbs = 0, ebs = 0, addr, data[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (ISIS_MAX_POLICER_ID < policer_id) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == policer->counter_mode) + { + addr = ACL_POLICER_CNT_SEL_ADDR; + data[0] = 0x1; + HSL_REG_FIELD_GEN_SET(rv, dev_id, addr, 1, policer_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + addr = ACL_POLICER_CNT_MODE_ADDR; + if (FAL_FRAME_BASED == policer->meter_unit) + { + data[0] = 0x0; + } + else + { + data[0] = 0x1; + } + HSL_REG_FIELD_GEN_SET(rv, dev_id, addr, 1, policer_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + addr = ACL_POLICER_CNT_RST_ADDR; + data[0] = 0x1; + HSL_REG_FIELD_GEN_SET(rv, dev_id, addr, 1, policer_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data[0] = 0x0; + HSL_REG_FIELD_GEN_SET(rv, dev_id, addr, 1, policer_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + return rv; + } + + addr = ACL_POLICER_CNT_SEL_ADDR; + data[0] = 0x0; + HSL_REG_FIELD_GEN_SET(rv, dev_id, addr, 1, policer_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_BYTE_BASED == policer->meter_unit) + { + cir = policer->cir >> 5; + policer->cir = cir << 5; + + eir = policer->eir >> 5; + policer->eir = eir << 5; + + _isis_ingress_bs_byte_sw_to_hw(policer->cbs, &cbs); + _isis_ingress_bs_byte_hw_to_sw(cbs, &(policer->cbs)); + + _isis_ingress_bs_byte_sw_to_hw(policer->ebs, &ebs); + _isis_ingress_bs_byte_hw_to_sw(ebs, &(policer->ebs)); + + SW_SET_REG_BY_FIELD(ACL_POLICER1, ACL_UNIT, 0, data[1]); + } + else if (FAL_FRAME_BASED == policer->meter_unit) + { + cir = (policer->cir * 2) / 125; + policer->cir = cir / 2 * 125 + cir % 2 * 63; + + eir = (policer->eir * 2) / 125; + policer->eir = eir / 2 * 125 + eir % 2 * 63; + + _isis_ingress_bs_frame_sw_to_hw(policer->cbs, &cbs); + _isis_ingress_bs_frame_hw_to_sw(cbs, &(policer->cbs)); + + _isis_ingress_bs_frame_sw_to_hw(policer->ebs, &ebs); + _isis_ingress_bs_frame_hw_to_sw(ebs, &(policer->ebs)); + + SW_SET_REG_BY_FIELD(ACL_POLICER1, ACL_UNIT, 1, data[1]); + } + else + { + return SW_BAD_PARAM; + } + + SW_SET_REG_BY_FIELD(ACL_POLICER0, ACL_CIR, cir, data[0]); + SW_SET_REG_BY_FIELD(ACL_POLICER0, ACL_CBS, cbs, data[0]); + SW_SET_REG_BY_FIELD(ACL_POLICER1, ACL_EIR, eir, data[1]); + SW_SET_REG_BY_FIELD(ACL_POLICER1, ACL_EBS, ebs, data[1]); + + if (A_TRUE == policer->deficit_en) + { + SW_SET_REG_BY_FIELD(ACL_POLICER1, ACL_BORROW, 1, data[1]); + } + + if (A_TRUE == policer->color_mode) + { + SW_SET_REG_BY_FIELD(ACL_POLICER1, ACL_CM, 1, data[1]); + } + + if (A_TRUE == policer->couple_flag) + { + SW_SET_REG_BY_FIELD(ACL_POLICER1, ACL_CF, 1, data[1]); + } + + _isis_rate_ts_parse(policer->meter_interval, &ts); + SW_SET_REG_BY_FIELD(ACL_POLICER1, ACL_TS, ts, data[1]); + + HSL_REG_ENTRY_SET(rv, dev_id, ACL_POLICER0, policer_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ACL_POLICER1, policer_id, + (a_uint8_t *) (&data[1]), sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_isis_rate_acl_policer_get(a_uint32_t dev_id, a_uint32_t policer_id, + fal_acl_policer_t * policer) +{ + sw_error_t rv; + a_uint32_t unit, ts, cir, eir, cbs, ebs, addr, data[2] = {0}; + + HSL_DEV_ID_CHECK(dev_id); + + if (ISIS_MAX_POLICER_ID < policer_id) + { + return SW_BAD_PARAM; + } + + aos_mem_zero(policer, sizeof (policer)); + + addr = ACL_POLICER_CNT_SEL_ADDR; + HSL_REG_FIELD_GEN_GET(rv, dev_id, addr, 1, policer_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data[0]) + { + policer->counter_mode = A_TRUE; + + addr = ACL_POLICER_CNT_MODE_ADDR; + HSL_REG_FIELD_GEN_GET(rv, dev_id, addr, 1, policer_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data[0]) + { + policer->meter_unit = FAL_BYTE_BASED; + } + else + { + policer->meter_unit = FAL_FRAME_BASED; + } + + HSL_REG_ENTRY_GET(rv, dev_id, ACL_COUNTER0, policer_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ACL_COUNTER1, policer_id, + (a_uint8_t *) (&data[1]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + policer->counter_low = data[0]; + policer->counter_high = data[1]; + + return SW_OK; + } + + HSL_REG_ENTRY_GET(rv, dev_id, ACL_POLICER0, policer_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ACL_POLICER1, policer_id, + (a_uint8_t *) (&data[1]), sizeof (a_uint32_t)); + + SW_GET_FIELD_BY_REG(ACL_POLICER0, ACL_CIR, cir, data[0]); + SW_GET_FIELD_BY_REG(ACL_POLICER0, ACL_CBS, cbs, data[0]); + SW_GET_FIELD_BY_REG(ACL_POLICER1, ACL_EIR, eir, data[1]); + SW_GET_FIELD_BY_REG(ACL_POLICER1, ACL_EBS, ebs, data[1]); + SW_GET_FIELD_BY_REG(ACL_POLICER1, ACL_UNIT, unit, data[1]); + if (unit) + { + policer->meter_unit = FAL_FRAME_BASED; + policer->cir = cir / 2 * 125 + cir % 2 * 63; + policer->eir = eir / 2 * 125 + eir % 2 * 63; + _isis_ingress_bs_frame_hw_to_sw(cbs, &(policer->cbs)); + _isis_ingress_bs_frame_hw_to_sw(ebs, &(policer->ebs)); + + } + else + { + policer->meter_unit = FAL_BYTE_BASED; + policer->cir = cir << 5; + policer->eir = eir << 5; + _isis_ingress_bs_byte_hw_to_sw(cbs, &(policer->cbs)); + _isis_ingress_bs_byte_hw_to_sw(ebs, &(policer->ebs)); + } + + SW_GET_FIELD_BY_REG(ACL_POLICER1, ACL_CF, policer->couple_flag, data[1]); + SW_GET_FIELD_BY_REG(ACL_POLICER1, ACL_CM, policer->color_mode, data[1]); + + SW_GET_FIELD_BY_REG(ACL_POLICER1, ACL_TS, ts, data[1]); + _isis_rate_ts_reparse(ts, &(policer->meter_interval)); + + return SW_OK; +} + +sw_error_t +_isis_rate_port_add_rate_byte_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t number) +{ + a_uint32_t val = number; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (val>255) + return SW_BAD_PARAM; + + HSL_REG_FIELD_SET(rv, dev_id, INGRESS_POLICER0, port_id, ADD_RATE_BYTE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + return rv; +} + +sw_error_t +_isis_rate_port_add_rate_byte_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t *number) +{ + a_uint32_t val = 0; + sw_error_t rv = SW_OK; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + + HSL_REG_FIELD_GET(rv, dev_id, INGRESS_POLICER0, port_id, ADD_RATE_BYTE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + *number = val; + + return rv; +} + +/** + * @brief Set port ingress policer parameters on one particular port. + * @details Comments: + The granularity of speed is 32kbps or 62.5fps. + Because of hardware granularity function will return actual speed in hardware. + When disable port ingress policer input parameter speed is meaningless. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] policer port ingress policer parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_rate_port_policer_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_policer_t * policer) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_rate_port_policer_set(dev_id, port_id, policer); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get port ingress policer parameters on one particular port. + * @details Comments: + The granularity of speed is 32kbps or 62.5fps. + Because of hardware granularity function will return actual speed in hardware. + When disable port ingress policer input parameter speed is meaningless. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] policer port ingress policer parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_rate_port_policer_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_policer_t * policer) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_rate_port_policer_get(dev_id, port_id, policer); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set port egress shaper parameters on one particular port. + * @details Comments: + The granularity of speed is 32kbps or 62.5fps. + Because of hardware granularity function will return actual speed in hardware. + When disable port egress shaper parameters is meaningless. + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] shaper port egress shaper parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_rate_port_shaper_set(dev_id, port_id, enable, shaper); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get port egress shaper parameters on one particular port. + * @details Comments: + The granularity of speed is 32kbps or 62.5fps. + Because of hardware granularity function will return actual speed in hardware. + When disable port egress shaper parameters is meaningless. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @param[out] shaper port egress shaper parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_rate_port_shaper_get(dev_id, port_id, enable, shaper); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set queue egress shaper parameters on one particular port. + * @details Comments: + The granularity of speed is 32kbps or 62.5fps. + Because of hardware granularity function will return actual speed in hardware. + When disable queue egress shaper parameters is meaningless. + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] shaper port egress shaper parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_rate_queue_shaper_set(dev_id, port_id, queue_id, enable, shaper); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get queue egress shaper parameters on one particular port. + * @details Comments: + The granularity of speed is 32kbps or 62.5fps. + Because of hardware granularity function will return actual speed in hardware. + When disable queue egress shaper parameters is meaningless. + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param[out] enable A_TRUE or A_FALSE + * @param[out] shaper port egress shaper parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_rate_queue_shaper_get(dev_id, port_id, queue_id, enable, shaper); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set ACL ingress policer parameters. + * @details Comments: + The granularity of speed is 32kbps or 62.5fps. + Because of hardware granularity function will return actual speed in hardware. + * @param[in] dev_id device id + * @param[in] policer_id ACL policer id + * @param[in] policer ACL ingress policer parameters + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_rate_acl_policer_set(a_uint32_t dev_id, a_uint32_t policer_id, + fal_acl_policer_t * policer) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_rate_acl_policer_set(dev_id, policer_id, policer); + HSL_API_UNLOCK; + return rv; +} + + + +/** + * @brief Get ACL ingress policer parameters. + * @details Comments: + The granularity of speed is 32kbps or 62.5fps. + Because of hardware granularity function will return actual speed in hardware. + * @param[in] dev_id device id + * @param[in] policer_id ACL policer id + * @param[in] policer ACL ingress policer parameters + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_rate_acl_policer_get(a_uint32_t dev_id, a_uint32_t policer_id, + fal_acl_policer_t * policer) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_rate_acl_policer_get(dev_id, policer_id, policer); + HSL_API_UNLOCK; + return rv; +} + +HSL_LOCAL sw_error_t +isis_rate_port_add_rate_byte_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t number) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_rate_port_add_rate_byte_set(dev_id, port_id, number); + HSL_API_UNLOCK; + return rv; +} + +HSL_LOCAL sw_error_t +isis_rate_port_add_rate_byte_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t *number) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_rate_port_add_rate_byte_get(dev_id, port_id, number); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +isis_rate_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->rate_port_policer_set = isis_rate_port_policer_set; + p_api->rate_port_policer_get = isis_rate_port_policer_get; + p_api->rate_port_shaper_set = isis_rate_port_shaper_set; + p_api->rate_port_shaper_get = isis_rate_port_shaper_get; + p_api->rate_queue_shaper_set = isis_rate_queue_shaper_set; + p_api->rate_queue_shaper_get = isis_rate_queue_shaper_get; + p_api->rate_acl_policer_set = isis_rate_acl_policer_set; + p_api->rate_acl_policer_get = isis_rate_acl_policer_get; + p_api->rate_port_add_rate_byte_set = isis_rate_port_add_rate_byte_set; + p_api->rate_port_add_rate_byte_get = isis_rate_port_add_rate_byte_get; + + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_reg_access.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_reg_access.c new file mode 100755 index 000000000..bdcfc9ed0 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_reg_access.c @@ -0,0 +1,507 @@ +/* + * Copyright (c) 2012, 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. + */ + + +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "sd.h" +#include "isis_reg_access.h" + +static hsl_access_mode reg_mode; + +#if defined(API_LOCK) +static aos_lock_t mdio_lock; +#define MDIO_LOCKER_INIT aos_lock_init(&mdio_lock) +#define MDIO_LOCKER_LOCK aos_lock(&mdio_lock) +#define MDIO_LOCKER_UNLOCK aos_unlock(&mdio_lock) +#else +#define MDIO_LOCKER_INIT +#define MDIO_LOCKER_LOCK +#define MDIO_LOCKER_UNLOCK +#endif + +#if defined(REG_ACCESS_SPEEDUP) +static a_uint32_t mdio_base_addr = 0xffffffff; +#endif + +int +isis_reg_config_header (a_uint8_t *header, a_uint8_t wr_flag, + a_uint32_t reg_addr, a_uint8_t cmd_len, + a_uint8_t *val, a_uint32_t seq_num) +{ + athrs_header_t athrs_header; + athrs_header_regcmd_t reg_cmd; + a_uint16_t head_offset = ISIS_HEADER_CMD_LEN + ISIS_HEADER_DATA_LEN; + a_uint8_t buf[ISIS_HEADER_CMD_LEN+ISIS_HEADER_LEN+ISIS_HEADER_MAX_DATA_LEN] = { 0 }; + a_uint16_t data2_offset = ISIS_HEADER_CMD_LEN + ISIS_HEADER_DATA_LEN + ISIS_HEADER_LEN; + + aos_mem_set(&athrs_header, 0, sizeof(athrs_header)); + aos_mem_set(®_cmd, 0, sizeof(reg_cmd)); + aos_mem_set(buf, 0, sizeof(buf)); + + /*fill atheros header*/ + athrs_header.version = 2; + athrs_header.priority = 0; + athrs_header.type = 1;/*READ_WRITE_REG*/ + athrs_header.broadcast = 0; + athrs_header.from_cpu = 1; + athrs_header.port_num = 0; + + /*fill in 4 byte type atheros header witch specific header type + must config reg 0x98*/ + buf[head_offset] = (ATHRS_HEADER_4BYTE_VAL & 0xff00)>>8; + buf[head_offset+1] = ATHRS_HEADER_4BYTE_VAL & 0xff; + + buf[head_offset+2] = athrs_header.type; + buf[head_offset+2] |= athrs_header.priority << 3; + buf[head_offset+2] |= athrs_header.version << 6; + buf[head_offset+3] = athrs_header.port_num; + buf[head_offset+3] |= athrs_header.from_cpu << 7; + + /*fill reg cmd*/ + if(cmd_len > ISIS_HEADER_MAX_DATA_LEN) + cmd_len = ISIS_HEADER_MAX_DATA_LEN;//maximum data length is16 bytes + reg_cmd.reg_addr = reg_addr&0x7fffc; /*bit 0:18, lower 2 bits must be 0*/ + reg_cmd.cmd_len = cmd_len; + reg_cmd.cmd = wr_flag; + reg_cmd.check_code = 5; + reg_cmd.seq_num = seq_num; + + /*bit[0:18], reg addr*/ + buf[0] = reg_cmd.reg_addr & 0xff; + buf[1] = (reg_cmd.reg_addr & 0xff00) >> 8; + buf[2] = (reg_cmd.reg_addr & 0x70000) >> 16; + /*bit[19:23], cmd data length*/ + buf[2] |= reg_cmd.cmd_len << 3; + /*bit[28], cmd type, read/write*/ + buf[3] = reg_cmd.cmd << 4; + /*bit[29:31], check code, must be 3'b101*/ + buf[3] |= reg_cmd.check_code << 5; + /*bit[32:63], sequence num*/ + buf[4] = (reg_cmd.seq_num & 0xff); + buf[5] = (reg_cmd.seq_num & 0xff00) >> 8; + buf[6] = (reg_cmd.seq_num & 0xff0000) >> 16; + buf[7] = (reg_cmd.seq_num & 0xff000000) >> 24; + + if(!wr_flag)//write + { + aos_mem_copy(buf+ ISIS_HEADER_CMD_LEN , val, ISIS_HEADER_DATA_LEN); + if (cmd_len >4 ) + aos_mem_copy(buf+ data2_offset , val + ISIS_HEADER_DATA_LEN, cmd_len - ISIS_HEADER_DATA_LEN); + } + + aos_mem_copy(header, buf, sizeof(buf)); + return 0; +} + + +sw_error_t isis_reg_parser_header_skb(a_uint8_t *header_buf, athrs_cmd_resp_t *cmd_resp) +{ + a_uint16_t data2_offset = ISIS_HEADER_CMD_LEN + ISIS_HEADER_DATA_LEN + ISIS_HEADER_LEN; + aos_mem_set(cmd_resp, 0, sizeof(cmd_resp)); + cmd_resp->len = header_buf[2] >> 3; + if (cmd_resp->len > ISIS_HEADER_MAX_DATA_LEN) + return SW_BAD_LEN; + + cmd_resp->seq = 0; + cmd_resp->seq = header_buf[4]; + cmd_resp->seq |= header_buf[5] << 8; + cmd_resp->seq |= header_buf[6] << 16; + cmd_resp->seq |= header_buf[7] << 24; + + aos_mem_copy (cmd_resp->data, (header_buf + ISIS_HEADER_CMD_LEN), ISIS_HEADER_DATA_LEN); + if (cmd_resp->len > 4) + aos_mem_copy ((cmd_resp->data+ISIS_HEADER_DATA_LEN), (header_buf + data2_offset), cmd_resp->len-4); + return SW_OK; +} + +static sw_error_t +_isis_mdio_reg_get(a_uint32_t dev_id, a_uint32_t reg_addr, + a_uint8_t value[], a_uint32_t value_len) +{ +#if 0 + a_uint32_t reg_word_addr; + a_uint32_t phy_addr, reg_val; + a_uint16_t phy_val, tmp_val; + a_uint8_t phy_reg; + sw_error_t rv; +#else + a_uint32_t reg_val; +#endif + + if (value_len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + +#if 0 + /* change reg_addr to 16-bit word address, 32-bit aligned */ + reg_word_addr = (reg_addr & 0xfffffffc) >> 1; + + /* configure register high address */ + phy_addr = 0x18; + phy_reg = 0x0; + phy_val = (a_uint16_t) ((reg_word_addr >> 8) & 0x3ff); /* bit16-8 of reg address */ + +#if defined(REG_ACCESS_SPEEDUP) + if (phy_val != mdio_base_addr) + { + rv = sd_reg_mdio_set(dev_id, phy_addr, phy_reg, phy_val); + SW_RTN_ON_ERROR(rv); + + mdio_base_addr = phy_val; + } +#else + rv = sd_reg_mdio_set(dev_id, phy_addr, phy_reg, phy_val); + SW_RTN_ON_ERROR(rv); +#endif + + /* For some registers such as MIBs, since it is read/clear, we should */ + /* read the lower 16-bit register then the higher one */ + + /* read register in lower address */ + phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */ + phy_reg = (a_uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */ + rv = sd_reg_mdio_get(dev_id, phy_addr, phy_reg, &tmp_val); + SW_RTN_ON_ERROR(rv); + reg_val = tmp_val; + + /* read register in higher address */ + reg_word_addr++; + phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */ + phy_reg = (a_uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */ + rv = sd_reg_mdio_get(dev_id, phy_addr, phy_reg, &tmp_val); + SW_RTN_ON_ERROR(rv); + reg_val |= (((a_uint32_t)tmp_val) << 16); + +#else + reg_val = sd_reg_mii_get(dev_id, reg_addr); +#endif + aos_mem_copy(value, ®_val, sizeof (a_uint32_t)); + + return SW_OK; +} + +static sw_error_t +_isis_mdio_reg_set(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t value[], + a_uint32_t value_len) +{ +#if 0 + a_uint32_t reg_word_addr; + a_uint32_t phy_addr, reg_val; + a_uint16_t phy_val; + a_uint8_t phy_reg; + sw_error_t rv; +#else + a_uint32_t reg_val = 0; +#endif + + if (value_len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + + aos_mem_copy(®_val, value, sizeof (a_uint32_t)); + +#if 0 + /* change reg_addr to 16-bit word address, 32-bit aligned */ + reg_word_addr = (reg_addr & 0xfffffffc) >> 1; + + /* configure register high address */ + phy_addr = 0x18; + phy_reg = 0x0; + phy_val = (a_uint16_t) ((reg_word_addr >> 8) & 0x3ff); /* bit16-8 of reg address */ + +#if defined(REG_ACCESS_SPEEDUP) + if (phy_val != mdio_base_addr) + { + rv = sd_reg_mdio_set(dev_id, phy_addr, phy_reg, phy_val); + SW_RTN_ON_ERROR(rv); + + mdio_base_addr = phy_val; + } +#else + rv = sd_reg_mdio_set(dev_id, phy_addr, phy_reg, phy_val); + SW_RTN_ON_ERROR(rv); +#endif + + /* For some registers such as ARL and VLAN, since they include BUSY bit */ + /* in higher address, we should write the lower 16-bit register then the */ + /* higher one */ + + /* write register in lower address */ + phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */ + phy_reg = (a_uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */ + phy_val = (a_uint16_t) (reg_val & 0xffff); + rv = sd_reg_mdio_set(dev_id, phy_addr, phy_reg, phy_val); + SW_RTN_ON_ERROR(rv); + + /* write register in higher address */ + reg_word_addr++; + phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */ + phy_reg = (a_uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */ + phy_val = (a_uint16_t) ((reg_val >> 16) & 0xffff); + rv = sd_reg_mdio_set(dev_id, phy_addr, phy_reg, phy_val); + SW_RTN_ON_ERROR(rv); + +#else + sd_reg_mii_set(dev_id, reg_addr, reg_val); +#endif + return SW_OK; +} + +sw_error_t +isis_phy_get(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t * value) +{ + sw_error_t rv; + + MDIO_LOCKER_LOCK; + rv = sd_reg_mdio_get(dev_id, phy_addr, reg, value); + MDIO_LOCKER_UNLOCK; + return rv; +} + +sw_error_t +isis_phy_set(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t value) +{ + sw_error_t rv; + + MDIO_LOCKER_LOCK; + rv = sd_reg_mdio_set(dev_id, phy_addr, reg, value); + MDIO_LOCKER_UNLOCK; + return rv; +} + +sw_error_t +isis_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; + + MDIO_LOCKER_LOCK; + if (HSL_MDIO == reg_mode) + { + rv = _isis_mdio_reg_get(dev_id, reg_addr, value, value_len); + } + else + { + rv = sd_reg_hdr_get(dev_id, reg_addr, value, value_len); + } + MDIO_LOCKER_UNLOCK; + + return rv; +} + +sw_error_t +isis_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; + + MDIO_LOCKER_LOCK; + if (HSL_MDIO == reg_mode) + { + rv = _isis_mdio_reg_set(dev_id, reg_addr, value, value_len); + } + else + { + rv = sd_reg_hdr_set(dev_id, reg_addr, value, value_len); + } + MDIO_LOCKER_UNLOCK; + + return rv; +} + +sw_error_t +isis_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) +{ + a_uint32_t reg_val = 0; + + if ((bit_offset >= 32 || (field_len > 32)) || (field_len == 0)) + return SW_OUT_OF_RANGE; + + if (value_len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + + SW_RTN_ON_ERROR(isis_reg_get(dev_id, reg_addr, (a_uint8_t *) & reg_val, sizeof (a_uint32_t))); + + *((a_uint32_t *) value) = SW_REG_2_FIELD(reg_val, bit_offset, field_len); + return SW_OK; +} + +sw_error_t +isis_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) +{ + a_uint32_t reg_val = 0; + a_uint32_t field_val = *((a_uint32_t *) value); + + if ((bit_offset >= 32 || (field_len > 32)) || (field_len == 0)) + return SW_OUT_OF_RANGE; + + if (value_len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + + SW_RTN_ON_ERROR(isis_reg_get(dev_id, reg_addr, (a_uint8_t *) & reg_val, sizeof (a_uint32_t))); + + SW_REG_SET_BY_FIELD_U32(reg_val, field_val, bit_offset, field_len); + + SW_RTN_ON_ERROR(isis_reg_set(dev_id, reg_addr, (a_uint8_t *) & reg_val, sizeof (a_uint32_t))); + + return SW_OK; +} + +static sw_error_t +_isis_regsiter_dump(a_uint32_t dev_id,a_uint32_t register_idx, fal_reg_dump_t * reg_dump) +{ + sw_error_t rv = SW_OK; + typedef struct { + a_uint32_t reg_base; + a_uint32_t reg_end; + char name[30]; + } regdump; + + regdump reg_dumps[8] = + { + {0x0, 0xE4, "0.Global control registers"}, + {0x100, 0x168, "1.EEE control registers"}, + {0x200, 0x270, "2.Parser control registers"}, + {0x400, 0x474, "3.ACL control registers"}, + {0x600, 0x718, "4.Lookup control registers"}, + {0x800, 0xb70, "5.QM control registers"}, + {0xc00, 0xc80, "6.PKT edit control registers"}, + {0x820, 0x820, "7.QM debug registers"} + }; + + a_uint32_t dump_addr, reg_count, reg_val = 0; + switch (register_idx) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + reg_count = 0; + for (dump_addr = reg_dumps[register_idx].reg_base; dump_addr <= reg_dumps[register_idx].reg_end; reg_count++) + { + rv = isis_reg_get(dev_id, dump_addr, (a_uint8_t *) & reg_val, sizeof (a_uint32_t)); + reg_dump->reg_value[reg_count] = reg_val; + dump_addr += 4; + } + reg_dump->reg_count = reg_count; + reg_dump->reg_base = reg_dumps[register_idx].reg_base; + reg_dump->reg_end = reg_dumps[register_idx].reg_end; + snprintf((char *)reg_dump->reg_name,sizeof(reg_dump->reg_name),"%s",reg_dumps[register_idx].name); + break; + default: + return SW_BAD_PARAM; + } + + return rv; +} + +static sw_error_t +_isis_debug_regsiter_dump(a_uint32_t dev_id,fal_debug_reg_dump_t * dbg_reg_dump) +{ + sw_error_t rv = SW_OK; + a_uint32_t reg; + a_uint32_t reg_count, reg_val = 0; + + reg_count = 0; + + for(reg=0;reg<=0x1F;reg++) + { + isis_reg_set(dev_id, 0x820, (a_uint8_t *) & reg, sizeof (a_uint32_t)); + rv = isis_reg_get(dev_id, 0x824, (a_uint8_t *) & reg_val, sizeof (a_uint32_t)); + dbg_reg_dump->reg_value[reg_count] = reg_val; + dbg_reg_dump->reg_addr[reg_count] = reg; + reg_count++; + } + dbg_reg_dump->reg_count = reg_count; + + snprintf((char *)dbg_reg_dump->reg_name,sizeof(dbg_reg_dump->reg_name),"QM debug registers"); + + return rv; +} + + +/** + * @brief dump registers. + * @param[in] dev_id device id + * @param[in] register_idx register group id + * @param[out] reg_dump register dump result + * @return SW_OK or error code + */ +sw_error_t +isis_regsiter_dump(a_uint32_t dev_id,a_uint32_t register_idx, fal_reg_dump_t * reg_dump) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _isis_regsiter_dump(dev_id,register_idx,reg_dump); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief dump registers. + * @param[in] dev_id device id + * @param[out] reg_dump debug register dump + * @return SW_OK or error code + */ +sw_error_t +isis_debug_regsiter_dump(a_uint32_t dev_id, fal_debug_reg_dump_t * dbg_reg_dump) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _isis_debug_regsiter_dump(dev_id,dbg_reg_dump); + FAL_API_UNLOCK; + return rv; +} + + +sw_error_t +isis_reg_access_init(a_uint32_t dev_id, hsl_access_mode mode) +{ + hsl_api_t *p_api; + + MDIO_LOCKER_INIT; + reg_mode = mode; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->phy_get = isis_phy_get; + p_api->phy_set = isis_phy_set; + p_api->reg_get = isis_reg_get; + p_api->reg_set = isis_reg_set; + p_api->reg_field_get = isis_reg_field_get; + p_api->reg_field_set = isis_reg_field_set; + p_api->register_dump = isis_regsiter_dump; + p_api->debug_register_dump = isis_debug_regsiter_dump; + + return SW_OK; +} + +sw_error_t +isis_access_mode_set(a_uint32_t dev_id, hsl_access_mode mode) +{ + reg_mode = mode; + return SW_OK; + +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_sec.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_sec.c new file mode 100755 index 000000000..912d09c3c --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_sec.c @@ -0,0 +1,787 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup isis_sec ISIS_SEC + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isis_sec.h" +#include "isis_reg.h" + +#define NORM_CTRL0_ADDR 0x0200 +#define NORM_CTRL1_ADDR 0x0204 +#define NORM_CTRL2_ADDR 0x0208 +#define NORM_CTRL3_ADDR 0x0c00 + +static sw_error_t +_isis_sec_norm_item_set(a_uint32_t dev_id, fal_norm_item_t item, void *value) +{ + sw_error_t rv; + fal_fwd_cmd_t cmd; + a_bool_t enable; + a_uint32_t addr, offset, len, reg = 0, val; + + HSL_DEV_ID_CHECK(dev_id); + + cmd = *((fal_fwd_cmd_t *) value); + enable = *((a_bool_t *) value); + val = *((a_uint32_t *) value); + + len = 1; + switch (item) + { + case FAL_NORM_MAC_RESV_VID_CMD: + addr = NORM_CTRL0_ADDR; + offset = 0; + goto cmd_chk; + + case FAL_NORM_MAC_INVALID_SRC_ADDR_CMD: + addr = NORM_CTRL1_ADDR; + offset = 20; + goto cmd_chk; + + case FAL_NORM_IP_INVALID_VER_CMD: + addr = NORM_CTRL0_ADDR; + offset = 1; + goto cmd_chk; + + case FAL_NROM_IP_SAME_ADDR_CMD: + addr = NORM_CTRL0_ADDR; + offset = 2; + goto cmd_chk; + break; + + case FAL_NROM_IP_TTL_CHANGE_STATUS: + addr = NORM_CTRL3_ADDR; + offset = 11; + goto sts_chk; + + case FAL_NROM_IP_TTL_VALUE: + addr = NORM_CTRL3_ADDR; + offset = 12; + len = 8; + goto set_reg; + + case FAL_NROM_IP4_INVALID_HL_CMD: + addr = NORM_CTRL0_ADDR; + offset = 3; + goto cmd_chk; + + case FAL_NROM_IP4_HDR_OPTIONS_CMD: + addr = NORM_CTRL0_ADDR; + offset = 4; + len = 2; + goto s_cmd_chk; + + case FAL_NROM_IP4_INVALID_DF_CMD: + addr = NORM_CTRL0_ADDR; + offset = 7; + goto cmd_chk; + + case FAL_NROM_IP4_FRAG_OFFSET_MIN_LEN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 8; + goto cmd_chk; + + case FAL_NROM_IP4_FRAG_OFFSET_MIN_SIZE: + addr = NORM_CTRL1_ADDR; + offset = 24; + len = 8; + goto set_reg; + + case FAL_NROM_IP4_FRAG_OFFSET_MAX_LEN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 9; + goto cmd_chk; + + case FAL_NROM_IP4_INVALID_FRAG_OFFSET_CMD: + addr = NORM_CTRL0_ADDR; + offset = 10; + goto cmd_chk; + + case FAL_NROM_IP4_INVALID_SIP_CMD: + addr = NORM_CTRL0_ADDR; + offset = 11; + len = 1; + goto cmd_chk; + + case FAL_NROM_IP4_INVALID_DIP_CMD: + addr = NORM_CTRL0_ADDR; + offset = 12; + goto cmd_chk; + + case FAL_NROM_IP4_INVALID_CHKSUM_CMD: + addr = NORM_CTRL0_ADDR; + offset = 13; + goto cmd_chk; + + case FAL_NROM_IP4_INVALID_PL_CMD: + addr = NORM_CTRL1_ADDR; + offset = 19; + goto cmd_chk; + + case FAL_NROM_IP4_DF_CLEAR_STATUS: + addr = NORM_CTRL3_ADDR; + offset = 9; + goto sts_chk; + + case FAL_NROM_IP4_IPID_RANDOM_STATUS: + addr = NORM_CTRL3_ADDR; + offset = 10; + goto sts_chk; + + case FAL_NROM_IP6_INVALID_DIP_CMD: + addr = NORM_CTRL1_ADDR; + offset = 16; + goto cmd_chk; + + case FAL_NROM_IP6_INVALID_SIP_CMD: + addr = NORM_CTRL1_ADDR; + offset = 17; + goto cmd_chk; + + case FAL_NROM_IP6_INVALID_PL_CMD: + addr = NORM_CTRL1_ADDR; + offset = 18; + goto cmd_chk; + + case FAL_NROM_TCP_BLAT_CMD: + addr = NORM_CTRL0_ADDR; + offset = 14; + goto cmd_chk; + + case FAL_NROM_TCP_INVALID_HL_CMD: + addr = NORM_CTRL0_ADDR; + offset = 15; + goto cmd_chk; + + case FAL_NROM_TCP_MIN_HDR_SIZE: + addr = NORM_CTRL1_ADDR; + offset = 12; + len = 4; + goto set_reg; + + case FAL_NROM_TCP_INVALID_SYN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 16; + goto cmd_chk; + break; + + case FAL_NROM_TCP_SU_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 17; + goto cmd_chk; + + case FAL_NROM_TCP_SP_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 18; + goto cmd_chk; + + case FAL_NROM_TCP_SAP_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 19; + goto cmd_chk; + + case FAL_NROM_TCP_XMAS_SCAN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 20; + goto cmd_chk; + + case FAL_NROM_TCP_NULL_SCAN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 21; + goto cmd_chk; + + case FAL_NROM_TCP_SR_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 22; + goto cmd_chk; + + case FAL_NROM_TCP_SF_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 23; + goto cmd_chk; + + case FAL_NROM_TCP_SAR_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 24; + goto cmd_chk; + + case FAL_NROM_TCP_RST_SCAN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 25; + goto cmd_chk; + + case FAL_NROM_TCP_SYN_WITH_DATA_CMD: + addr = NORM_CTRL0_ADDR; + offset = 26; + goto cmd_chk; + + case FAL_NROM_TCP_RST_WITH_DATA_CMD: + addr = NORM_CTRL0_ADDR; + offset = 27; + goto cmd_chk; + + case FAL_NROM_TCP_FA_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 28; + goto cmd_chk; + + case FAL_NROM_TCP_PA_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 29; + goto cmd_chk; + + case FAL_NROM_TCP_UA_BLOCK_CMD: + addr = NORM_CTRL1_ADDR; + offset = 0; + goto cmd_chk; + + case FAL_NROM_TCP_INVALID_CHKSUM_CMD: + addr = NORM_CTRL1_ADDR; + offset = 1; + goto cmd_chk; + + case FAL_NROM_TCP_INVALID_URGPTR_CMD: + addr = NORM_CTRL1_ADDR; + offset = 2; + goto cmd_chk; + + case FAL_NROM_TCP_INVALID_OPTIONS_CMD: + addr = NORM_CTRL1_ADDR; + offset = 3; + goto cmd_chk; + + case FAL_NROM_UDP_BLAT_CMD: + addr = NORM_CTRL1_ADDR; + offset = 4; + goto cmd_chk; + + case FAL_NROM_UDP_INVALID_LEN_CMD: + addr = NORM_CTRL1_ADDR; + offset = 5; + goto cmd_chk; + + case FAL_NROM_UDP_INVALID_CHKSUM_CMD: + addr = NORM_CTRL1_ADDR; + offset = 6; + goto cmd_chk; + + case FAL_NROM_ICMP4_PING_PL_EXCEED_CMD: + addr = NORM_CTRL1_ADDR; + offset = 7; + goto cmd_chk; + + case FAL_NROM_ICMP6_PING_PL_EXCEED_CMD: + addr = NORM_CTRL1_ADDR; + offset = 8; + goto cmd_chk; + + case FAL_NROM_ICMP4_PING_FRAG_CMD: + addr = NORM_CTRL1_ADDR; + offset = 9; + goto cmd_chk; + + case FAL_NROM_ICMP6_PING_FRAG_CMD: + addr = NORM_CTRL1_ADDR; + offset = 10; + goto cmd_chk; + + case FAL_NROM_ICMP4_PING_MAX_PL_VALUE: + addr = NORM_CTRL2_ADDR; + offset = 0; + len = 14; + goto set_reg; + + case FAL_NROM_ICMP6_PING_MAX_PL_VALUE: + addr = NORM_CTRL2_ADDR; + offset = 16; + len = 14; + goto set_reg; + + default: + return SW_BAD_PARAM; + } + +sts_chk: + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + goto set_reg; + +s_cmd_chk: + if (FAL_MAC_FRWRD == cmd) + { + val = 0; + } + else if (FAL_MAC_DROP == cmd) + { + val = 3; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + val = 2; + } + else + { + return SW_BAD_PARAM; + } + goto set_reg; + +cmd_chk: + if (FAL_MAC_FRWRD == cmd) + { + val = 0; + } + else if (FAL_MAC_DROP == cmd) + { + val = 1; + } + else + { + return SW_BAD_PARAM; + } + +set_reg: + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_REG_SET_BY_FIELD_U32(reg, val, offset, len); + + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_sec_norm_item_get(a_uint32_t dev_id, fal_norm_item_t item, void *value) +{ + sw_error_t rv; + a_uint32_t addr, offset, len, reg = 0, val; + a_uint32_t status_chk = 0, val_chk = 0, scmd_chk = 0; + + HSL_DEV_ID_CHECK(dev_id); + + len = 1; + switch (item) + { + case FAL_NORM_MAC_RESV_VID_CMD: + addr = NORM_CTRL0_ADDR; + offset = 0; + break; + + case FAL_NORM_MAC_INVALID_SRC_ADDR_CMD: + addr = NORM_CTRL1_ADDR; + offset = 20; + break; + + case FAL_NORM_IP_INVALID_VER_CMD: + addr = NORM_CTRL0_ADDR; + offset = 1; + break; + + case FAL_NROM_IP_SAME_ADDR_CMD: + addr = NORM_CTRL0_ADDR; + offset = 2; + break; + + case FAL_NROM_IP_TTL_CHANGE_STATUS: + addr = NORM_CTRL3_ADDR; + offset = 11; + status_chk = 1; + break; + + case FAL_NROM_IP_TTL_VALUE: + addr = NORM_CTRL3_ADDR; + offset = 12; + len = 8; + val_chk = 1; + break; + + case FAL_NROM_IP4_INVALID_HL_CMD: + addr = NORM_CTRL0_ADDR; + offset = 3; + break; + + case FAL_NROM_IP4_HDR_OPTIONS_CMD: + addr = NORM_CTRL0_ADDR; + offset = 4; + len = 2; + scmd_chk = 1; + break; + + case FAL_NROM_IP4_INVALID_DF_CMD: + addr = NORM_CTRL0_ADDR; + offset = 7; + break; + + case FAL_NROM_IP4_FRAG_OFFSET_MIN_LEN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 8; + break; + + case FAL_NROM_IP4_FRAG_OFFSET_MIN_SIZE: + addr = NORM_CTRL1_ADDR; + offset = 24; + len = 8; + val_chk = 1; + break; + + case FAL_NROM_IP4_FRAG_OFFSET_MAX_LEN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 9; + break; + + case FAL_NROM_IP4_INVALID_FRAG_OFFSET_CMD: + addr = NORM_CTRL0_ADDR; + offset = 10; + break; + + case FAL_NROM_IP4_INVALID_SIP_CMD: + addr = NORM_CTRL0_ADDR; + offset = 11; + len = 1; + break; + + case FAL_NROM_IP4_INVALID_DIP_CMD: + addr = NORM_CTRL0_ADDR; + offset = 12; + break; + + case FAL_NROM_IP4_INVALID_CHKSUM_CMD: + addr = NORM_CTRL0_ADDR; + offset = 13; + break; + + case FAL_NROM_IP4_INVALID_PL_CMD: + addr = NORM_CTRL1_ADDR; + offset = 19; + break; + + case FAL_NROM_IP4_DF_CLEAR_STATUS: + addr = NORM_CTRL3_ADDR; + offset = 9; + status_chk = 1; + break; + + case FAL_NROM_IP4_IPID_RANDOM_STATUS: + addr = NORM_CTRL3_ADDR; + offset = 10; + status_chk = 1; + break; + + case FAL_NROM_IP6_INVALID_DIP_CMD: + addr = NORM_CTRL1_ADDR; + offset = 16; + break; + + case FAL_NROM_IP6_INVALID_SIP_CMD: + addr = NORM_CTRL1_ADDR; + offset = 17; + break; + + case FAL_NROM_IP6_INVALID_PL_CMD: + addr = NORM_CTRL1_ADDR; + offset = 18; + break; + + case FAL_NROM_TCP_BLAT_CMD: + addr = NORM_CTRL0_ADDR; + offset = 14; + break; + + case FAL_NROM_TCP_INVALID_HL_CMD: + addr = NORM_CTRL0_ADDR; + offset = 15; + break; + + case FAL_NROM_TCP_MIN_HDR_SIZE: + addr = NORM_CTRL1_ADDR; + offset = 12; + len = 4; + val_chk = 1; + break; + + case FAL_NROM_TCP_INVALID_SYN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 16; + break; + + case FAL_NROM_TCP_SU_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 17; + break; + + case FAL_NROM_TCP_SP_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 18; + break; + + case FAL_NROM_TCP_SAP_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 19; + break; + + case FAL_NROM_TCP_XMAS_SCAN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 20; + break; + + case FAL_NROM_TCP_NULL_SCAN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 21; + break; + + case FAL_NROM_TCP_SR_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 22; + break; + + case FAL_NROM_TCP_SF_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 23; + break; + + case FAL_NROM_TCP_SAR_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 24; + break; + + case FAL_NROM_TCP_RST_SCAN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 25; + break; + + case FAL_NROM_TCP_SYN_WITH_DATA_CMD: + addr = NORM_CTRL0_ADDR; + offset = 26; + break; + + case FAL_NROM_TCP_RST_WITH_DATA_CMD: + addr = NORM_CTRL0_ADDR; + offset = 27; + break; + + case FAL_NROM_TCP_FA_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 28; + break; + + case FAL_NROM_TCP_PA_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 29; + break; + + case FAL_NROM_TCP_UA_BLOCK_CMD: + addr = NORM_CTRL1_ADDR; + offset = 0; + break; + + case FAL_NROM_TCP_INVALID_CHKSUM_CMD: + addr = NORM_CTRL1_ADDR; + offset = 1; + break; + + case FAL_NROM_TCP_INVALID_URGPTR_CMD: + addr = NORM_CTRL1_ADDR; + offset = 2; + break; + + case FAL_NROM_TCP_INVALID_OPTIONS_CMD: + addr = NORM_CTRL1_ADDR; + offset = 3; + break; + + case FAL_NROM_UDP_BLAT_CMD: + addr = NORM_CTRL1_ADDR; + offset = 4; + break; + + case FAL_NROM_UDP_INVALID_LEN_CMD: + addr = NORM_CTRL1_ADDR; + offset = 5; + break; + + case FAL_NROM_UDP_INVALID_CHKSUM_CMD: + addr = NORM_CTRL1_ADDR; + offset = 6; + break; + + case FAL_NROM_ICMP4_PING_PL_EXCEED_CMD: + addr = NORM_CTRL1_ADDR; + offset = 7; + break; + + case FAL_NROM_ICMP6_PING_PL_EXCEED_CMD: + addr = NORM_CTRL1_ADDR; + offset = 8; + break; + + case FAL_NROM_ICMP4_PING_FRAG_CMD: + addr = NORM_CTRL1_ADDR; + offset = 9; + break; + + case FAL_NROM_ICMP6_PING_FRAG_CMD: + addr = NORM_CTRL1_ADDR; + offset = 10; + break; + + case FAL_NROM_ICMP4_PING_MAX_PL_VALUE: + addr = NORM_CTRL2_ADDR; + offset = 0; + len = 14; + val_chk = 1; + break; + + case FAL_NROM_ICMP6_PING_MAX_PL_VALUE: + addr = NORM_CTRL2_ADDR; + offset = 16; + len = 14; + val_chk = 1; + break; + + default: + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_FIELD_GET_BY_REG_U32(reg, val, offset, len); + + if (val_chk) + { + *((a_uint32_t *) value) = val; + } + else if (status_chk) + { + if (val) + { + *((a_bool_t *) value) = A_TRUE; + } + else + { + *((a_bool_t *) value) = A_FALSE; + } + } + else if (scmd_chk) + { + if (2 == val) + { + *((fal_fwd_cmd_t *) value) = FAL_MAC_RDT_TO_CPU; + } + else if (3 == val) + { + *((fal_fwd_cmd_t *) value) = FAL_MAC_DROP; + } + else + { + *((fal_fwd_cmd_t *) value) = FAL_MAC_FRWRD; + } + } + else + { + if (val) + { + *((fal_fwd_cmd_t *) value) = FAL_MAC_DROP; + } + else + { + *((fal_fwd_cmd_t *) value) = FAL_MAC_FRWRD; + } + } + + return SW_OK; +} + +/** + * @brief Set normalization particular item types value. + * @details Comments: + * This operation will set normalization item values on a particular device. + * The prototye of value based on the item type. + * @param[in] dev_id device id + * @param[in] item normalizaton item type + * @param[in] value normalizaton item value + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_sec_norm_item_set(a_uint32_t dev_id, fal_norm_item_t item, void *value) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_sec_norm_item_set(dev_id, item, value); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get normalization particular item types value. + * @details Comments: + * This operation will set normalization item values on a particular device. + * The prototye of value based on the item type. + * @param[in] dev_id device id + * @param[in] item normalizaton item type + * @param[out] value normalizaton item value + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_sec_norm_item_get(a_uint32_t dev_id, fal_norm_item_t item, void *value) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_sec_norm_item_get(dev_id, item, value); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +isis_sec_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->sec_norm_item_set = isis_sec_norm_item_set; + p_api->sec_norm_item_get = isis_sec_norm_item_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_stp.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_stp.c new file mode 100755 index 000000000..3d0581b97 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_stp.c @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup isis_stp ISIS_STP + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isis_stp.h" +#include "isis_reg.h" + +#define ISIS_PORT_DISABLED 0 +#define ISIS_STP_BLOCKING 1 +#define ISIS_STP_LISTENING 2 +#define ISIS_STP_LEARNING 3 +#define ISIS_STP_FARWARDING 4 + +static sw_error_t +_isis_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; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_SINGLE_STP_ID != st_id) + { + return SW_BAD_PARAM; + } + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + switch (state) + { + case FAL_STP_BLOKING: + val = ISIS_STP_BLOCKING; + break; + case FAL_STP_LISTENING: + val = ISIS_STP_LISTENING; + break; + case FAL_STP_LEARNING: + val = ISIS_STP_LEARNING; + break; + case FAL_STP_FARWARDING: + val = ISIS_STP_FARWARDING; + break; + case FAL_STP_DISABLED: + val = ISIS_PORT_DISABLED; + break; + default: + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LOOKUP_CTL, port_id, PORT_STATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_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; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_SINGLE_STP_ID != st_id) + { + return SW_BAD_PARAM; + } + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LOOKUP_CTL, port_id, PORT_STATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + switch (val) + { + case ISIS_STP_BLOCKING: + *state = FAL_STP_BLOKING; + break; + case ISIS_STP_LISTENING: + *state = FAL_STP_LISTENING; + break; + case ISIS_STP_LEARNING: + *state = FAL_STP_LEARNING; + break; + case ISIS_STP_FARWARDING: + *state = FAL_STP_FARWARDING; + break; + case ISIS_PORT_DISABLED: + *state = FAL_STP_DISABLED; + break; + default: + return SW_FAIL; + } + + return SW_OK; +} + +/** + * @brief Set port stp state on a particular spanning tree and port. + * @details Comments: + Garuda only support single spanning tree so st_id should be + FAL_SINGLE_STP_ID that is zero. + * @param[in] dev_id device id + * @param[in] st_id spanning tree id + * @param[in] port_id port id + * @param[in] state port state for spanning tree + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_stp_port_state_set(dev_id, st_id, port_id, state); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get port stp state on a particular spanning tree and port. + * @details Comments: + Garuda only support single spanning tree so st_id should be + FAL_SINGLE_STP_ID that is zero. + * @param[in] dev_id device id + * @param[in] st_id spanning tree id + * @param[in] port_id port id + * @param[out] state port state for spanning tree + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_stp_port_state_get(dev_id, st_id, port_id, state); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +isis_stp_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->stp_port_state_set = isis_stp_port_state_set; + p_api->stp_port_state_get = isis_stp_port_state_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_trunk.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_trunk.c new file mode 100755 index 000000000..d0767d290 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_trunk.c @@ -0,0 +1,692 @@ +/* + * Copyright (c) 2012, 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. + */ + + + +/** + * @defgroup isis_trunk ISIS_TRUNK + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isis_trunk.h" +#include "isis_reg.h" + +#define ISIS_MAX_TRUNK_ID 3 + +/*feature on/off for manipulating dp within trunk group*/ +#define ISIS_TRUNK_MANIPULATE_DP_ON 1 +#define ISIS_TRUNK_MANIPULATE_HEADER_LEN 12 +#define MAC_LEN 6 +#define HASH_SIZE 4 + +enum isis_trunk_reg_id +{ + ISIS_TRUNK_HASH_EN = 0, /*0x270*/ + ISIS_TRUNK_CTRL_0, /*0x700*/ + ISIS_TRUNK_CTRL_1, /*0x704*/ + ISIS_TRUNK_CTRL_2, /*0x708*/ + ISIS_TRUNK_REG_MAX +}; + +static a_uint32_t isis_trunk_regs[ISIS_TRUNK_REG_MAX] = +{ + 0xf, 0x0, 0x0, 0x0 +}; + +static a_uint8_t sa_hash[HASH_SIZE][MAC_LEN] = +{ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x03 } +}; + +static sw_error_t +_isis_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; + a_uint32_t i, reg = 0, cnt = 0, data0 = 0, data1 = 0; + + if (ISIS_MAX_TRUNK_ID < trunk_id) + { + return SW_BAD_PARAM; + } + + if (A_FALSE == hsl_mports_prop_check(dev_id, member, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data0 = (0x1 << 7) | member; + + for (i = 0; i < 7; i++) + { + if (member & (0x1 << i)) + { + if (4 <= cnt) + { + return SW_BAD_PARAM; + } + + data1 |= (i << (cnt << 2)); + data1 |= (1 << (3 + (cnt << 2))); + cnt++; + } + } + } + else if (A_FALSE == enable) + { + + } + else + { + return SW_BAD_PARAM; + } + + /* set trunk port member bitmap info */ + HSL_REG_ENTRY_GET(rv, dev_id, GOL_TRUNK_CTL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + reg &= (~(0xff << (trunk_id << 3))); + reg |= (data0 << (trunk_id << 3)); + + HSL_REG_ENTRY_SET(rv, dev_id, GOL_TRUNK_CTL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + isis_trunk_regs[ISIS_TRUNK_CTRL_0] = reg; + + /* set trunk port member id info */ + HSL_REG_ENTRY_GET(rv, dev_id, GOL_TRUNK_CTL1, (trunk_id >> 1), + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + reg &= (~(0xffff << ((trunk_id % 2) << 4))); + reg |= (data1 << ((trunk_id % 2) << 4)); + + HSL_REG_ENTRY_SET(rv, dev_id, GOL_TRUNK_CTL1, (trunk_id >> 1), + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + isis_trunk_regs[ISIS_TRUNK_CTRL_1 + (trunk_id >> 1)] = reg; + + return SW_OK; +} + +static sw_error_t +_isis_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; + a_uint32_t data, reg = 0; + + if (ISIS_MAX_TRUNK_ID < trunk_id) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, GOL_TRUNK_CTL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data = (reg >> (trunk_id << 3)) & 0xff; + if (0x80 & data) + { + *enable = A_TRUE; + *member = data & 0x7f; + } + else + { + *enable = A_FALSE; + *member = 0; + } + + return SW_OK; +} + +#if 0 +static sw_error_t +_isis_trunk_group_sw_get(a_uint32_t dev_id, a_uint32_t trunk_id, + a_bool_t * enable, fal_pbmp_t * member) +{ + a_uint32_t data, reg; + + if (ISIS_MAX_TRUNK_ID < trunk_id) + { + return SW_BAD_PARAM; + } + + reg = isis_trunk_regs[ISIS_TRUNK_CTRL_0]; + + data = (reg >> (trunk_id << 3)) & 0xff; + if (0x80 & data) + { + *enable = A_TRUE; + *member = data & 0x7f; + } + else + { + *enable = A_FALSE; + *member = 0; + } + + return SW_OK; +} +#endif + +static sw_error_t +_isis_trunk_hash_mode_set(a_uint32_t dev_id, a_uint32_t hash_mode) +{ + sw_error_t rv; + a_uint32_t data = 0; + + if (FAL_TRUNK_HASH_KEY_DA & hash_mode) + { + SW_SET_REG_BY_FIELD(TRUNK_HASH_MODE, DA_EN, 1, data); + } + + if (FAL_TRUNK_HASH_KEY_SA & hash_mode) + { + SW_SET_REG_BY_FIELD(TRUNK_HASH_MODE, SA_EN, 1, data); + } + + if (FAL_TRUNK_HASH_KEY_DIP & hash_mode) + { + SW_SET_REG_BY_FIELD(TRUNK_HASH_MODE, DIP_EN, 1, data); + } + + if (FAL_TRUNK_HASH_KEY_SIP & hash_mode) + { + SW_SET_REG_BY_FIELD(TRUNK_HASH_MODE, SIP_EN, 1, data); + } + + HSL_REG_ENTRY_SET(rv, dev_id, TRUNK_HASH_MODE, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + isis_trunk_regs[ISIS_TRUNK_HASH_EN] = data; + + return rv; +} + +static sw_error_t +_isis_trunk_hash_mode_get(a_uint32_t dev_id, a_uint32_t * hash_mode) +{ + sw_error_t rv; + a_uint32_t reg = 0, data = 0; + + HSL_REG_ENTRY_GET(rv, dev_id, TRUNK_HASH_MODE, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *hash_mode = 0; + + SW_GET_FIELD_BY_REG(TRUNK_HASH_MODE, DA_EN, data, reg); + if (data) + { + *hash_mode |= FAL_TRUNK_HASH_KEY_DA; + } + + SW_GET_FIELD_BY_REG(TRUNK_HASH_MODE, SA_EN, data, reg); + if (data) + { + *hash_mode |= FAL_TRUNK_HASH_KEY_SA; + } + + SW_GET_FIELD_BY_REG(TRUNK_HASH_MODE, DIP_EN, data, reg); + if (data) + { + *hash_mode |= FAL_TRUNK_HASH_KEY_DIP; + } + + SW_GET_FIELD_BY_REG(TRUNK_HASH_MODE, SIP_EN, data, reg); + if (data) + { + *hash_mode |= FAL_TRUNK_HASH_KEY_SIP; + } + + return SW_OK; +} + +#define BYTE_B2R(x, mask) ((x) ^ (mask)) +#define BYTE_B1C(x) ((((((x&0x55)+((x&0xaa)>>1))&0x33)+((((x&0x55)+((x&0xaa)>>1))&0xcc)>>2))&0x0f)+((((((x&0x55)+((x&0xaa)>>1))&0x33)+((((x&0x55)+((x&0xaa)>>1))&0xcc)>>2))&0xf0)>>4)) + +static sw_error_t +_isis_trunk_manipulate_sa_set(a_uint32_t dev_id, fal_mac_addr_t * addr) +{ + a_uint32_t i; + + for (i = 0; i < HASH_SIZE; i++) + { + memcpy(sa_hash[i], addr->uc, MAC_LEN); + sa_hash[i][MAC_LEN - 1] = BYTE_B2R(sa_hash[i][MAC_LEN - 1], i); + } + + return SW_OK; +} + +static sw_error_t +_isis_trunk_manipulate_sa_get(a_uint32_t dev_id, fal_mac_addr_t * addr) +{ + memcpy(addr->uc, sa_hash[0], MAC_LEN); + return SW_OK; +} + +#if 0 +static sw_error_t +_isis_trunk_hash_mode_sw_get(a_uint32_t dev_id, a_uint32_t * hash_mode) +{ + a_uint32_t reg, data = 0; + + reg = isis_trunk_regs[ISIS_TRUNK_HASH_EN]; + + *hash_mode = 0; + + SW_GET_FIELD_BY_REG(TRUNK_HASH_MODE, DA_EN, data, reg); + if (data) + { + *hash_mode |= FAL_TRUNK_HASH_KEY_DA; + } + + SW_GET_FIELD_BY_REG(TRUNK_HASH_MODE, SA_EN, data, reg); + if (data) + { + *hash_mode |= FAL_TRUNK_HASH_KEY_SA; + } + + SW_GET_FIELD_BY_REG(TRUNK_HASH_MODE, DIP_EN, data, reg); + if (data) + { + *hash_mode |= FAL_TRUNK_HASH_KEY_DIP; + } + + SW_GET_FIELD_BY_REG(TRUNK_HASH_MODE, SIP_EN, data, reg); + if (data) + { + *hash_mode |= FAL_TRUNK_HASH_KEY_SIP; + } + + return SW_OK; +} + +static sw_error_t +_isis_trunk_id_member_get(a_uint32_t dev_id, a_uint8_t expect_dp, + a_uint32_t * trunk_id, fal_pbmp_t * member) +{ + sw_error_t rv; + a_bool_t enable; + a_uint32_t i; + + for (i = 0; i <= ISIS_MAX_TRUNK_ID; i++) + { + rv = _isis_trunk_group_sw_get(dev_id, i, &enable, member); + SW_RTN_ON_ERROR(rv); + if (enable && (*member & expect_dp)) + { + *trunk_id = i; + return SW_OK; + } + } + + return SW_NOT_FOUND; +} + +static sw_error_t +_isis_trunk_hash_dp_get(a_uint32_t dev_id, a_uint8_t * header, a_uint32_t len, + a_uint32_t trunk_id, a_uint32_t mode, a_uint8_t * hash_dp) +{ +#define BIT2_MASK 0x03 +#define TRUNK_MEM_EN_MASK 0x8 +#define TRUNK_MEM_PT_MASK 0x7 +#define TRUNK_HASH_DP_SEL 4 + sw_error_t rv; + a_uint32_t i, hash_mode, reg, data1 = 0; + a_uint32_t da_xor = 0, sa_xor = 0; /*consider da-hash & sa-hash (TBD: dip-hash & sip-hash)*/ + a_uint8_t xor_dp = 0; + + rv = _isis_trunk_hash_mode_sw_get(dev_id, &hash_mode); + SW_RTN_ON_ERROR(rv); + + if (!hash_mode) + { + return SW_DISABLE; + } + + *hash_dp = 0; + + if ((mode & FAL_TRUNK_HASH_KEY_DA) && (hash_mode & FAL_TRUNK_HASH_KEY_DA)) + { + for (i = 0; i < MAC_LEN; i++) + { + da_xor ^= (header[i] & BIT2_MASK) ^ + ((header[i] >> 2) & BIT2_MASK) ^ + ((header[i] >> 4) & BIT2_MASK) ^ + ((header[i] >> 6) & BIT2_MASK); + } + *hash_dp = da_xor; + } + if ((mode & FAL_TRUNK_HASH_KEY_SA) && (hash_mode & FAL_TRUNK_HASH_KEY_SA)) + { + for (i = 6; i < 2 * MAC_LEN; i++) + { + sa_xor ^= (header[i] & BIT2_MASK) ^ + ((header[i] >> 2) & BIT2_MASK) ^ + ((header[i] >> 4) & BIT2_MASK) ^ + ((header[i] >> 6) & BIT2_MASK); + } + *hash_dp = (*hash_dp) ^ sa_xor; + } + + /*dp translation*/ +#if 0 + HSL_REG_ENTRY_GET(rv, dev_id, GOL_TRUNK_CTL1, (trunk_id >> 1), + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); +#else /*sw*/ + reg = isis_trunk_regs[ISIS_TRUNK_CTRL_1 + (trunk_id >> 1)]; +#endif + + for (i = 0; i < TRUNK_HASH_DP_SEL; i++) + { + xor_dp = BYTE_B2R(*hash_dp, i); + data1 = (0x0f & (reg >> (((trunk_id % 2) << 4) + (xor_dp << 2)))); + if (data1 & TRUNK_MEM_EN_MASK) + { + *hash_dp = data1 & TRUNK_MEM_PT_MASK; + *hash_dp = 0x01 << (*hash_dp); /*bmp*/ + return SW_OK; + } + } + + return SW_NOT_FOUND; +} + +static sw_error_t +_isis_trunk_sa_spoofing( a_uint32_t dev_id, a_uint8_t * header, a_uint32_t len, + a_uint8_t expect_dp, a_uint32_t trunk_id, fal_pbmp_t member) +{ + sw_error_t rv; + a_uint32_t i, hash_mode; + a_uint8_t hash_dp; + a_uint8_t ori_sa[MAC_LEN]; + + rv = _isis_trunk_hash_mode_sw_get(dev_id, &hash_mode); + SW_RTN_ON_ERROR(rv); + + if (!(hash_mode & FAL_TRUNK_HASH_KEY_SA)) + { + return SW_DISABLE; + } + + memcpy(ori_sa, &header[MAC_LEN], MAC_LEN); + + for (i = 0; i < HASH_SIZE/*not HASH_SIZE, for RAD only*/; i++) + { + memcpy(&header[MAC_LEN], sa_hash[i], MAC_LEN); + rv = _isis_trunk_hash_dp_get(dev_id, header, len, trunk_id, + FAL_TRUNK_HASH_KEY_DA | FAL_TRUNK_HASH_KEY_SA, &hash_dp); + SW_RTN_ON_ERROR(rv); + if (expect_dp == hash_dp) + { + // printk("expect_dp = 0x%x, hash_dp(DA+SA) = 0x%x, sa_id = %d\n", expect_dp, hash_dp, i); + return SW_OK; + } + } + + /*should never here*/ + memcpy(&header[MAC_LEN], ori_sa, MAC_LEN); + return SW_FAIL; +} + +static sw_error_t +_isis_trunk_manipulate_dp(a_uint32_t dev_id, a_uint8_t * header, + a_uint32_t len, fal_pbmp_t dp_member) +{ + sw_error_t rv; + a_uint8_t expect_dp, hash_dp; /*bitmap*/ + a_uint32_t i, trunk_id; + fal_pbmp_t member; + + if (!ISIS_TRUNK_MANIPULATE_DP_ON) + { + return SW_OK; /*feature not enabled*/ + } + + if (!header || len < ISIS_TRUNK_MANIPULATE_HEADER_LEN) + { + return SW_BAD_VALUE; + } + +#if 0 /*de-comment this to ignore broadcast packets*/ + const a_uint8_t bc_mac[MAC_LEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + if (!memcmp(header, bc_mac, MAC_LEN)) /*not for broadcast*/ + { + return SW_OK; + } +#endif + + /*expect_dp within trunk group*/ + expect_dp = dp_member & 0x7f; + for (i = 0; i < 7; i++) + { + if (expect_dp & (0x01 << i)) + { + rv = _isis_trunk_id_member_get(dev_id, (0x01 << i), &trunk_id, &member); + if (rv != SW_OK) + { + expect_dp &= ~(0x01 << i); /*not the dp doesn't belong to trunk*/ + } + } + } + + if (BYTE_B1C(expect_dp) != 1) /*supports 1 dp only*/ + { + return SW_OK; /*ignore none-dp or multi-dp*/ + } + + rv = _isis_trunk_id_member_get(dev_id, expect_dp, &trunk_id, &member); + SW_RTN_ON_ERROR(rv); + + member &= 0x7f; + if (BYTE_B1C(member) == 1) /*trunk group w/ one port*/ + { + return SW_OK; + } + + rv = _isis_trunk_hash_dp_get(dev_id, header, len, trunk_id, + FAL_TRUNK_HASH_KEY_DA | FAL_TRUNK_HASH_KEY_SA, &hash_dp); + SW_RTN_ON_ERROR(rv); + + // printk("expect_dp = 0x%x, hash_dp(DA+SA) = 0x%x, member = 0x%x\n", expect_dp, hash_dp, member); + if (expect_dp == hash_dp) + { + return SW_OK; + } + + rv = _isis_trunk_sa_spoofing(dev_id, header, len, expect_dp, trunk_id, member); + SW_RTN_ON_ERROR(rv); + + return rv; +} +#endif + +/** + * @brief Set particular trunk group information on particular device. + * @param[in] dev_id device id + * @param[in] trunk_id trunk group id + * @param[in] enable trunk group status, enable or disable + * @param[in] member port member information + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_trunk_group_set(dev_id, trunk_id, enable, member); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get particular trunk group information on particular device. + * @param[in] dev_id device id + * @param[in] trunk_id trunk group id + * @param[out] enable trunk group status, enable or disable + * @param[out] member port member information + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_trunk_group_get(dev_id, trunk_id, enable, member); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set trunk hash mode on particular device. + * @details Comments: + hash mode is listed below + FAL_TRUNK_HASH_KEY_DA, FAL_TRUNK_HASH_KEY_SA, FAL_TRUNK_HASH_KEY_DIP and FAL_TRUNK_HASH_KEY_SIP + * @param[in] dev_id device id + * @param[in] hash_mode trunk hash mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_trunk_hash_mode_set(a_uint32_t dev_id, a_uint32_t hash_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_trunk_hash_mode_set(dev_id, hash_mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get trunk hash mode on particular device. + * @param[in] dev_id device id + * @param[out] hash_mode trunk hash mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_trunk_hash_mode_get(a_uint32_t dev_id, a_uint32_t * hash_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_trunk_hash_mode_get(dev_id, hash_mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set trunk manipulate SA on particular device. + * @param[in] dev_id device id + * @param[in] addr manipulate SA + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_trunk_manipulate_sa_set(a_uint32_t dev_id, fal_mac_addr_t * addr) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_trunk_manipulate_sa_set(dev_id, addr); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get trunk manipulate SA on particular device. + * @param[in] dev_id device id + * @param[out] addr manipulate SA + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_trunk_manipulate_sa_get(a_uint32_t dev_id, fal_mac_addr_t * addr) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_trunk_manipulate_sa_get(dev_id, addr); + HSL_API_UNLOCK; + return rv; +} + +#if 0 +/** + * @brief manipulate destination port within a trunk group + * @details Comments: + * supporting hash mode include: FAL_TRUNK_HASH_KEY_DA & FAL_TRUNK_HASH_KEY_SA; + * FAL_TRUNK_HASH_KEY_DIP & FAL_TRUNK_HASH_KEY_SIP are NOT covered in current design + * @param[in] dev_id device id + * @param[in-out] header packet header, accept format: [DA:6B][SA:6B] + * @param[in] len length of packet header, should be 12 in current design (6B DA + 6B SA) + * @param[in] dp_member expect destination port members, bitmap format + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_trunk_manipulate_dp(a_uint32_t dev_id, a_uint8_t * header, + a_uint32_t len, fal_pbmp_t dp_member) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_trunk_manipulate_dp(dev_id, header, len, dp_member); + HSL_API_UNLOCK; + return rv; +} +#endif + +sw_error_t +isis_trunk_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->trunk_group_set = isis_trunk_group_set; + p_api->trunk_group_get = isis_trunk_group_get; + p_api->trunk_hash_mode_set = isis_trunk_hash_mode_set; + p_api->trunk_hash_mode_get = isis_trunk_hash_mode_get; + p_api->trunk_manipulate_sa_set = isis_trunk_manipulate_sa_set; + p_api->trunk_manipulate_sa_get = isis_trunk_manipulate_sa_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_vlan.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_vlan.c new file mode 100755 index 000000000..248623bd4 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isis/isis_vlan.c @@ -0,0 +1,909 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 isis_vlan ISIS_VLAN + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isis_vlan.h" +#include "isis_reg.h" + +#define MAX_VLAN_ID 4095 + +#define VLAN_FLUSH 1 +#define VLAN_LOAD_ENTRY 2 +#define VLAN_PURGE_ENTRY 3 +#define VLAN_REMOVE_PORT 4 +#define VLAN_NEXT_ENTRY 5 +#define VLAN_FIND_ENTRY 6 + +static void +_isis_vlan_hw_to_sw(a_uint32_t reg[], fal_vlan_t * vlan_entry) +{ + a_uint32_t i, data, tmp; + + aos_mem_zero(vlan_entry, sizeof (fal_vlan_t)); + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC1, VLAN_ID, data, reg[1]); + vlan_entry->vid = data & 0xfff; + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC0, IVL_EN, data, reg[0]); + if (1 == data) + { + vlan_entry->fid = vlan_entry->vid; + } + else + { + vlan_entry->fid = FAL_SVL_FID; + } + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC0, LEARN_DIS, data, reg[0]); + if (1 == data) + { + vlan_entry->learn_dis = A_TRUE; + } + else + { + vlan_entry->learn_dis = A_FALSE; + } + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC0, VT_PRI_EN, data, reg[0]); + if (1 == data) + { + vlan_entry->vid_pri_en = A_TRUE; + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC0, VT_PRI, data, reg[0]); + vlan_entry->vid_pri = data & 0xff; + } + else + { + vlan_entry->vid_pri_en = A_FALSE; + } + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC0, VID_MEM, data, reg[0]); + for (i = 0; i < 7; i++) + { + tmp = (data >> (i << 1)) & 0x3UL; + if (0 == tmp) + { + vlan_entry->mem_ports |= (0x1UL << i); + vlan_entry->unmodify_ports |= (0x1UL << i); + } + else if (1 == tmp) + { + vlan_entry->mem_ports |= (0x1UL << i); + vlan_entry->untagged_ports |= (0x1UL << i); + } + else if (2 == tmp) + { + vlan_entry->mem_ports |= (0x1UL << i); + vlan_entry->tagged_ports |= (0x1UL << i); + } + } + + return; +} + +static sw_error_t +_isis_vlan_sw_to_hw(a_uint32_t dev_id, const fal_vlan_t * vlan_entry, + a_uint32_t reg[]) +{ + a_uint32_t i, tag, untag, unmodify, member = 0; + + if (vlan_entry->vid > MAX_VLAN_ID) + { + return SW_OUT_OF_RANGE; + } + + if (A_FALSE == + hsl_mports_prop_check(dev_id, vlan_entry->mem_ports, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_VALID, 1, reg[0]); + + if (FAL_SVL_FID == vlan_entry->fid) + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, IVL_EN, 0, reg[0]); + } + else if (vlan_entry->vid == vlan_entry->fid) + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, IVL_EN, 1, reg[0]); + } + else + { + return SW_BAD_VALUE; + } + + if (A_TRUE == vlan_entry->learn_dis) + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, LEARN_DIS, 1, reg[0]); + } + else + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, LEARN_DIS, 0, reg[0]); + } + + for (i = 0; i < 7; i++) + { + if ((vlan_entry->mem_ports >> i) & 0x1UL) + { + tag = (vlan_entry->tagged_ports >> i) & 0x1UL; + untag = (vlan_entry->untagged_ports >> i) & 0x1UL; + unmodify = (vlan_entry->unmodify_ports >> i) & 0x1UL; + + if ((0 == (tag + untag + unmodify)) + || (1 < (tag + untag + unmodify))) + { + return SW_BAD_VALUE; + } + + if (tag) + { + member |= (2 << (i << 1)); + } + else if (untag) + { + member |= (1 << (i << 1)); + } + } + else + { + member |= (3 << (i << 1)); + } + } + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VID_MEM, member, reg[0]); + + if (A_TRUE == vlan_entry->vid_pri_en) + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_PRI_EN, 1, reg[0]); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_PRI, vlan_entry->vid_pri, + reg[0]); + } + else + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_PRI_EN, 0, reg[0]); + } + + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC1, VLAN_ID, vlan_entry->vid, reg[1]); + + return SW_OK; +} + +static sw_error_t +_isis_vlan_down_to_hw(a_uint32_t dev_id, a_uint32_t reg[]) +{ + sw_error_t rv; + + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_vlan_up_to_sw(a_uint32_t dev_id, a_uint32_t reg[]) +{ + sw_error_t rv; + + HSL_REG_ENTRY_GET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isis_vlan_commit(a_uint32_t dev_id, a_uint32_t op) +{ + a_uint32_t vt_busy = 1, i = 0x1000, vt_full, val; + sw_error_t rv; + + while (vt_busy && --i) + { + HSL_REG_FIELD_GET(rv, dev_id, VLAN_TABLE_FUNC1, 0, VT_BUSY, + (a_uint8_t *) (&vt_busy), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + aos_udelay(5); + } + + if (i == 0) + { + printk("%s BUSY\n", __FUNCTION__); + return SW_BUSY; + } + + HSL_REG_ENTRY_GET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC1, VT_FUNC, op, val); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC1, VT_BUSY, 1, val); + + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + vt_busy = 1; + i = 0x1000; + while (vt_busy && --i) + { + HSL_REG_FIELD_GET(rv, dev_id, VLAN_TABLE_FUNC1, 0, VT_BUSY, + (a_uint8_t *) (&vt_busy), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + aos_udelay(5); + } + + if (i == 0) + return SW_FAIL; + + HSL_REG_FIELD_GET(rv, dev_id, VLAN_TABLE_FUNC1, 0, VT_FULL_VIO, + (a_uint8_t *) (&vt_full), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (vt_full) + { + val = 0x10; + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + if (VLAN_LOAD_ENTRY == op) + { + return SW_FULL; + } + else if (VLAN_PURGE_ENTRY == op) + { + return SW_NOT_FOUND; + } + } + + HSL_REG_FIELD_GET(rv, dev_id, VLAN_TABLE_FUNC0, 0, VT_VALID, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (!val) + { + if (VLAN_FIND_ENTRY == op) + return SW_NOT_FOUND; + + if (VLAN_NEXT_ENTRY == op) + return SW_NO_MORE; + } + + return SW_OK; +} + +static sw_error_t +_isis_vlan_hwentry_get(a_uint32_t dev_id, a_uint32_t vlan_id, a_uint32_t reg[]) +{ + sw_error_t rv; + + if (vlan_id > MAX_VLAN_ID) + { + return SW_OUT_OF_RANGE; + } + + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC1, VLAN_ID, vlan_id, reg[1]); + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = _isis_vlan_commit(dev_id, VLAN_FIND_ENTRY); + SW_RTN_ON_ERROR(rv); + + rv = _isis_vlan_up_to_sw(dev_id, reg); + return rv; +} + +static sw_error_t +_isis_vlan_entry_append(a_uint32_t dev_id, const fal_vlan_t * vlan_entry) +{ + sw_error_t rv; + a_uint32_t reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_vlan_sw_to_hw(dev_id, vlan_entry, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_vlan_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_vlan_commit(dev_id, VLAN_LOAD_ENTRY); + return rv; +} + +static sw_error_t +_isis_vlan_create(a_uint32_t dev_id, a_uint32_t vlan_id) +{ + sw_error_t rv; + a_uint32_t reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (vlan_id > MAX_VLAN_ID) + { + return SW_OUT_OF_RANGE; + } + + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_VALID, 1, reg[0]); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, IVL_EN, 1, reg[0]); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, LEARN_DIS, 0, reg[0]); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VID_MEM, 0x3fff, reg[0]); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC1, VLAN_ID, vlan_id, reg[1]); + + rv = _isis_vlan_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_vlan_commit(dev_id, VLAN_LOAD_ENTRY); + return rv; +} + +static sw_error_t +_isis_vlan_next(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan) +{ + sw_error_t rv; + a_uint32_t reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_NEXT_ENTRY_FIRST_ID == vlan_id) + { + rv = _isis_vlan_hwentry_get(dev_id, 0, reg); + + if (SW_OK == rv) + { + _isis_vlan_hw_to_sw(reg, p_vlan); + return SW_OK; + } + else + { + vlan_id = 0; + } + } + + if (vlan_id > MAX_VLAN_ID) + return SW_OUT_OF_RANGE; + + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC1, VLAN_ID, vlan_id, reg[1]); + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + rv = _isis_vlan_commit(dev_id, VLAN_NEXT_ENTRY); + SW_RTN_ON_ERROR(rv); + + rv = _isis_vlan_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + _isis_vlan_hw_to_sw(reg, p_vlan); + + if (0 == p_vlan->vid) + { + return SW_NO_MORE; + } + else + { + return SW_OK; + } +} + +static sw_error_t +_isis_vlan_find(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan) +{ + sw_error_t rv; + a_uint32_t reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_vlan_hwentry_get(dev_id, vlan_id, reg); + SW_RTN_ON_ERROR(rv); + + _isis_vlan_hw_to_sw(reg, p_vlan); + return SW_OK; +} + +static sw_error_t +_isis_vlan_delete(a_uint32_t dev_id, a_uint32_t vlan_id) +{ + sw_error_t rv; + a_uint32_t reg; + + HSL_DEV_ID_CHECK(dev_id); + + if (vlan_id > MAX_VLAN_ID) + { + return SW_OUT_OF_RANGE; + } + + reg = (a_int32_t) vlan_id; + HSL_REG_FIELD_SET(rv, dev_id, VLAN_TABLE_FUNC1, 0, VLAN_ID, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = _isis_vlan_commit(dev_id, VLAN_PURGE_ENTRY); + return rv; +} + +static sw_error_t +_isis_vlan_flush(a_uint32_t dev_id) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_vlan_commit(dev_id, VLAN_FLUSH); + return rv; +} + +static sw_error_t +_isis_vlan_fid_set(a_uint32_t dev_id, a_uint32_t vlan_id, a_uint32_t fid) +{ + sw_error_t rv; + a_uint32_t reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + if ((MAX_VLAN_ID < fid) && (FAL_SVL_FID != fid)) + { + return SW_BAD_PARAM; + } + + if ((MAX_VLAN_ID >= fid) && (vlan_id != fid)) + { + return SW_BAD_PARAM; + } + + rv = _isis_vlan_hwentry_get(dev_id, vlan_id, reg); + SW_RTN_ON_ERROR(rv); + + if (FAL_SVL_FID == fid) + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, IVL_EN, 0, reg[0]); + } + else + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, IVL_EN, 1, reg[0]); + } + + rv = _isis_vlan_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_vlan_commit(dev_id, VLAN_LOAD_ENTRY); + if (SW_FULL == rv) + { + rv = SW_OK; + } + return rv; +} + +static sw_error_t +_isis_vlan_fid_get(a_uint32_t dev_id, a_uint32_t vlan_id, a_uint32_t * fid) +{ + sw_error_t rv; + a_uint32_t data, reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_vlan_hwentry_get(dev_id, vlan_id, reg); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC0, IVL_EN, data, reg[0]); + if (data) + { + *fid = vlan_id; + } + else + { + *fid = FAL_SVL_FID; + } + return SW_OK; +} + +static sw_error_t +_isis_vlan_member_update(a_uint32_t dev_id, a_uint32_t vlan_id, + fal_port_t port_id, a_uint32_t port_info) +{ + sw_error_t rv; + a_uint32_t data, reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + rv = _isis_vlan_hwentry_get(dev_id, vlan_id, reg); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC0, VID_MEM, data, reg[0]); + data &= (~(0x3 << (port_id << 1))); + data |= ((port_info & 0x3) << (port_id << 1)); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VID_MEM, data, reg[0]); + + rv = _isis_vlan_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_vlan_commit(dev_id, VLAN_LOAD_ENTRY); + if (SW_FULL == rv) + { + rv = SW_OK; + } + return rv; +} + +static sw_error_t +_isis_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; + a_uint32_t info = 0; + + if (FAL_EG_UNMODIFIED == port_info) + { + info = 0; + } + else if (FAL_EG_TAGGED == port_info) + { + info = 0x2; + } + else if (FAL_EG_UNTAGGED == port_info) + { + info = 0x1; + } + else + { + return SW_BAD_PARAM; + } + + rv = _isis_vlan_member_update(dev_id, vlan_id, port_id, info); + return rv; +} + +static sw_error_t +_isis_vlan_member_del(a_uint32_t dev_id, a_uint32_t vlan_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t info = 0x3; + + rv = _isis_vlan_member_update(dev_id, vlan_id, port_id, info); + return rv; +} + +static sw_error_t +_isis_vlan_learning_state_set(a_uint32_t dev_id, a_uint32_t vlan_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_vlan_hwentry_get(dev_id, vlan_id, reg); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, LEARN_DIS, 0, reg[0]); + } + else if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, LEARN_DIS, 1, reg[0]); + } + else + { + return SW_BAD_PARAM; + } + + rv = _isis_vlan_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isis_vlan_commit(dev_id, VLAN_LOAD_ENTRY); + if (SW_FULL == rv) + { + rv = SW_OK; + } + return rv; +} + +static sw_error_t +_isis_vlan_learning_state_get(a_uint32_t dev_id, a_uint32_t vlan_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t data, reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isis_vlan_hwentry_get(dev_id, vlan_id, reg); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC0, LEARN_DIS, data, reg[0]); + if (data) + { + *enable = A_FALSE; + } + else + { + *enable = A_TRUE; + } + return SW_OK; +} + +/** + * @brief Append a vlan entry on paticular device. + * @param[in] dev_id device id + * @param[in] vlan_entry vlan entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_vlan_entry_append(a_uint32_t dev_id, const fal_vlan_t * vlan_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_vlan_entry_append(dev_id, vlan_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Creat a vlan entry through vlan id on a paticular device. + * @details Comments: + * After this operation the member ports of the created vlan entry are null. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_vlan_create(a_uint32_t dev_id, a_uint32_t vlan_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_vlan_create(dev_id, vlan_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Next a vlan entry through vlan id on a paticular device. + * @details Comments: + * If the value of vid is zero this operation will get the first entry. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[out] p_vlan vlan entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_vlan_next(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_vlan_next(dev_id, vlan_id, p_vlan); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Find a vlan entry through vlan id on paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[out] p_vlan vlan entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_vlan_find(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_vlan_find(dev_id, vlan_id, p_vlan); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a vlan entry through vlan id on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_vlan_delete(a_uint32_t dev_id, a_uint32_t vlan_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_vlan_delete(dev_id, vlan_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Flush all vlan entries on a paticular device. + * @param[in] dev_id device id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_vlan_flush(a_uint32_t dev_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_vlan_flush(dev_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set FID of a paticular vlan entry on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[in] fid FDB id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_vlan_fid_set(a_uint32_t dev_id, a_uint32_t vlan_id, a_uint32_t fid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_vlan_fid_set(dev_id, vlan_id, fid); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get FID of a paticular vlan entry on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[out] fid FDB id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_vlan_fid_get(a_uint32_t dev_id, a_uint32_t vlan_id, a_uint32_t * fid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_vlan_fid_get(dev_id, vlan_id, fid); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add a port member to a paticular vlan entry on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[in] port_id port id + * @param[in] port_info port tag information + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_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; + + HSL_API_LOCK; + rv = _isis_vlan_member_add(dev_id, vlan_id, port_id, port_info); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Del a port member from a paticular vlan entry on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[in] port_id port id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_vlan_member_del(a_uint32_t dev_id, a_uint32_t vlan_id, fal_port_t port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_vlan_member_del(dev_id, vlan_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set FDB learning status of a paticular vlan entry on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_vlan_learning_state_set(a_uint32_t dev_id, a_uint32_t vlan_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_vlan_learning_state_set(dev_id, vlan_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get FDB learning status of a paticular vlan entry on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isis_vlan_learning_state_get(a_uint32_t dev_id, a_uint32_t vlan_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isis_vlan_learning_state_get(dev_id, vlan_id, enable); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +isis_vlan_init(a_uint32_t dev_id) +{ + hsl_api_t *p_api; + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->vlan_entry_append = isis_vlan_entry_append; + p_api->vlan_creat = isis_vlan_create; + p_api->vlan_delete = isis_vlan_delete; + p_api->vlan_next = isis_vlan_next; + p_api->vlan_find = isis_vlan_find; + p_api->vlan_flush = isis_vlan_flush; + p_api->vlan_fid_set = isis_vlan_fid_set; + p_api->vlan_fid_get = isis_vlan_fid_get; + p_api->vlan_member_add = isis_vlan_member_add; + p_api->vlan_member_del = isis_vlan_member_del; + p_api->vlan_learning_state_set = isis_vlan_learning_state_set; + p_api->vlan_learning_state_get = isis_vlan_learning_state_get; + + +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/Makefile b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/Makefile new file mode 100755 index 000000000..4990ff0b0 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/Makefile @@ -0,0 +1,122 @@ +LOC_DIR=src/hsl/isisc +LIB=HSL + +include $(PRJ_PATH)/make/config.mk + +SRC_LIST=isisc_reg_access.c isisc_init.c + +ifeq (TRUE, $(IN_ACL)) + SRC_LIST += isisc_acl.c isisc_acl_parse.c +endif + +ifeq (TRUE, $(IN_FDB)) + SRC_LIST += isisc_fdb.c +endif + +ifeq (TRUE, $(IN_IGMP)) + SRC_LIST += isisc_igmp.c + ifeq (TRUE, $(IN_ACL)) + SRC_LIST += isisc_multicast_acl.c + endif +endif + +ifeq (TRUE, $(IN_LEAKY)) + SRC_LIST += isisc_leaky.c +endif + +ifeq (TRUE, $(IN_LED)) + SRC_LIST += isisc_led.c +endif + +ifeq (TRUE, $(IN_MIB)) + SRC_LIST += isisc_mib.c +endif + +ifeq (TRUE, $(IN_MIRROR)) + SRC_LIST += isisc_mirror.c +endif + +ifeq (TRUE, $(IN_MISC)) + SRC_LIST += isisc_misc.c +endif + +ifeq (TRUE, $(IN_PORTCONTROL)) + SRC_LIST += isisc_port_ctrl.c +endif + +ifeq (TRUE, $(IN_PORTVLAN)) + SRC_LIST += isisc_portvlan.c +endif + +ifeq (TRUE, $(IN_QOS)) + SRC_LIST += isisc_qos.c +endif + +ifeq (TRUE, $(IN_RATE)) + SRC_LIST += isisc_rate.c +endif + +ifeq (TRUE, $(IN_STP)) + SRC_LIST += isisc_stp.c +endif + +ifeq (TRUE, $(IN_VLAN)) + SRC_LIST += isisc_vlan.c +endif + +ifeq (TRUE, $(IN_REDUCED_ACL)) + SRC_LIST += isisc_reduced_acl.c +endif + +ifeq (TRUE, $(IN_COSMAP)) + SRC_LIST += isisc_cosmap.c +endif + +ifeq (TRUE, $(IN_IP)) + SRC_LIST += isisc_ip.c +endif + +ifeq (TRUE, $(IN_NAT)) + SRC_LIST += isisc_nat.c +endif + +ifeq (TRUE, $(IN_NAT_HELPER)) + SRC_LIST += nat_helper_dt.c + SRC_LIST += nat_helper_hsl.c + SRC_LIST += nat_ipt_helper.c + SRC_LIST += napt_helper.c + SRC_LIST += host_helper.c + SRC_LIST += nat_helper.c + SRC_LIST += napt_acl.c + SRC_LIST += napt_procfs.c +endif + +ifeq (TRUE, $(IN_TRUNK)) + SRC_LIST += isisc_trunk.c +endif + +ifeq (TRUE, $(IN_SEC)) + SRC_LIST += isisc_sec.c +endif + +ifeq (TRUE, $(IN_INTERFACECONTROL)) + SRC_LIST += isisc_interface_ctrl.c +endif + +ifeq (linux, $(OS)) + ifeq (KSLIB, $(MODULE_TYPE)) + ifneq (TRUE, $(KERNEL_MODE)) + SRC_LIST=isisc_reg_access.c isisc_init.c + endif + endif +endif + +ifeq (, $(findstring ISISC, $(SUPPORT_CHIP))) + SRC_LIST= +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/src/src/hsl/isisc/isisc_acl.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_acl.c new file mode 100755 index 000000000..a446a2d10 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_acl.c @@ -0,0 +1,2035 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup isisc_acl ISISC_ACL + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_acl.h" +#include "isisc_acl.h" +#include "isisc_reg.h" +#include "isisc_acl_prv.h" + +//#define ISISC_ACL_DEBUG +//#define ISISC_SW_ENTRY +#define ISISC_HW_ENTRY + +static isisc_acl_list_t *sw_list_ent[SW_MAX_NR_DEV]; +static isisc_acl_rule_t *sw_rule_ent[SW_MAX_NR_DEV]; + +static isisc_acl_rule_t *sw_rule_tmp[SW_MAX_NR_DEV]; +static isisc_acl_rule_t *hw_rule_tmp[SW_MAX_NR_DEV]; +#ifdef ISISC_SW_ENTRY +static a_uint8_t *sw_filter_mem = NULL; +#endif + +static sw_error_t +_isisc_filter_valid_set(a_uint32_t dev_id, a_uint32_t flt_idx, a_uint32_t flag); + +static sw_error_t +_isisc_filter_ports_bind(a_uint32_t dev_id, a_uint32_t flt_idx, + a_uint32_t ports); + +#ifdef ISISC_SW_ENTRY +static sw_error_t +_isisc_filter_write(a_uint32_t dev_id, a_uint32_t reg[], a_uint32_t flt_idx, + a_uint32_t op); + +static sw_error_t +_isisc_filter_read(a_uint32_t dev_id, a_uint32_t reg[], a_uint32_t flt_idx, + a_uint32_t op); +#endif + +static sw_error_t +_isisc_filter_down_to_hw(a_uint32_t dev_id, hw_filter_t * filter, + a_uint32_t flt_idx); + +static sw_error_t +_isisc_filter_up_to_sw(a_uint32_t dev_id, hw_filter_t * filter, + a_uint32_t flt_idx); + +static sw_error_t +_isisc_acl_rule_src_filter_sts_set(a_uint32_t dev_id, + a_uint32_t rule_id, a_bool_t enable); + +static void +_isisc_acl_list_dump(a_uint32_t dev_id) +{ + a_uint32_t i; + isisc_acl_list_t *sw_list; + + aos_printk("\ndev_id=%d list control infomation:", dev_id); + for (i = 0; i < ISISC_MAX_FILTER; i++) + { + sw_list = &(sw_list_ent[dev_id][i]); + if (ENT_USED & sw_list->status) + { + aos_printk + ("\nlist_id=%02d list_pri=%02d rule_nr=%02d [pts_map]:0x%02x idx=%02d ", + sw_list->list_id, sw_list->list_pri, sw_list->rule_nr, + sw_list->bind_pts, i); + } + } + aos_printk("\n"); +} + +static void +_isisc_acl_sw_rule_dump(char *info, isisc_acl_rule_t * sw_rule) +{ +#ifdef ISISC_ACL_DEBUG + a_uint32_t flt_idx, i; + + aos_printk("\n%s", info); + for (flt_idx = 0; flt_idx < ISISC_MAX_FILTER; flt_idx++) + { + aos_printk("\n%d software filter:", flt_idx); + aos_printk("\nact:"); + for (i = 0; i < 3; i++) + { + aos_printk("%08x ", sw_rule[flt_idx].filter.act[i]); + } + + aos_printk("\nvlu:"); + for (i = 0; i < 5; i++) + { + aos_printk("%08x ", sw_rule[flt_idx].filter.vlu[i]); + } + + aos_printk("\nmsk:"); + for (i = 0; i < 5; i++) + { + aos_printk("%08x ", sw_rule[flt_idx].filter.msk[i]); + } + + aos_printk("\nctl:status[%02d] list_id[%02d] rule_id[%02d]", + sw_rule[flt_idx].status, + sw_rule[flt_idx].list_id, sw_rule[flt_idx].rule_id); + + aos_printk("\n\n"); + } +#else + return; +#endif +} + +static isisc_acl_list_t * +_isisc_acl_list_loc(a_uint32_t dev_id, a_uint32_t list_id) +{ + a_uint32_t i; + + for (i = 0; i < ISISC_MAX_FILTER; i++) + { + if ((ENT_USED & sw_list_ent[dev_id][i].status) + && (list_id == sw_list_ent[dev_id][i].list_id)) + { + return &(sw_list_ent[dev_id][i]); + } + } + return NULL; +} + +static sw_error_t +_isisc_filter_valid_set(a_uint32_t dev_id, a_uint32_t flt_idx, a_uint32_t flag) +{ +#ifdef ISISC_SW_ENTRY + hw_filter_t filter; + + _isisc_filter_up_to_sw(dev_id, &filter, flt_idx); + + filter.msk[4] &= 0xfffffff8; + filter.msk[4] |= (flag & 0x7); + + _isisc_filter_down_to_hw(dev_id, &filter, flt_idx); + + return SW_OK; +#else +#ifdef ISISC_HW_ENTRY + hw_filter_t filter; + + filter = sw_rule_ent[dev_id][flt_idx].filter; + + filter.msk[4] &= 0xfffffff8; + filter.msk[4] |= (flag & 0x7); + + _isisc_filter_down_to_hw(dev_id, &filter, flt_idx); + return SW_OK; +#else + sw_error_t rv; + a_uint32_t addr, data = 0; + + /* read filter mask at first */ + addr = ISISC_RULE_FUNC_ADDR; + data = (flt_idx & 0x7f) | (0x1 << 8) | (0x1 << 10) | (0x1 << 31); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* get filter mask and modify it */ + addr = ISISC_RULE_FUNC_ADDR + 20; + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data &= 0xfffffff8; + data |= (flag & 0x7); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* write back filter mask */ + addr = ISISC_RULE_FUNC_ADDR; + data = (flt_idx & 0x7f) | (0x1 << 8) | (0x1 << 31); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +#endif +#endif +} + +static sw_error_t +_isisc_filter_ports_bind(a_uint32_t dev_id, a_uint32_t flt_idx, a_uint32_t ports) +{ +#ifdef ISISC_SW_ENTRY + hw_filter_t filter; + + _isisc_filter_up_to_sw(dev_id, &filter, flt_idx); + + filter.vlu[4] &= 0xffffff80; + filter.vlu[4] |= (ports & 0x7f); + + _isisc_filter_down_to_hw(dev_id, &filter, flt_idx); + + return SW_OK; +#else +#ifdef ISISC_HW_ENTRY + hw_filter_t filter; + + filter = sw_rule_ent[dev_id][flt_idx].filter; + + filter.vlu[4] &= 0xffffff80; + filter.vlu[4] |= (ports & 0x7f); + + _isisc_filter_down_to_hw(dev_id, &filter, flt_idx); + + return SW_OK; +#else + sw_error_t rv; + a_uint32_t addr, data; + + /* read filter value at first */ + addr = ISISC_RULE_FUNC_ADDR; + data = (flt_idx & 0x7f) | (0x1 << 10) | (0x1 << 31); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* get filter value and modify it */ + addr = ISISC_RULE_FUNC_ADDR + 20; + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data &= 0xffffff80; + data |= (ports & 0x7f); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* write back filter value */ + addr = ISISC_RULE_FUNC_ADDR; + data = (flt_idx & 0x7f) | (0x1 << 31); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +#endif +#endif +} + +#ifdef ISISC_SW_ENTRY +static sw_error_t +_isisc_filter_write(a_uint32_t dev_id, a_uint32_t reg[], a_uint32_t flt_idx, + a_uint32_t op) +{ + a_uint32_t i, addr, data, idx = 6; + sw_error_t rv; + + if (ISISC_FILTER_ACT_OP == op) + { + idx = 4; + } + + for (i = 1; i < idx; i++) + { + addr = ISISC_RULE_FUNC_ADDR + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(reg[i - 1])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + addr = ISISC_RULE_FUNC_ADDR; + data = (flt_idx & 0x7f) | (op << 8) | (0x1 << 31); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_isisc_filter_read(a_uint32_t dev_id, a_uint32_t reg[], a_uint32_t flt_idx, + a_uint32_t op) +{ + a_uint32_t i, addr, data, idx = 6; + sw_error_t rv; + + addr = ISISC_RULE_FUNC_ADDR; + data = (flt_idx & 0x7f) | (op << 8) | (0x1 << 10) | (0x1 << 31); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (ISISC_FILTER_ACT_OP == op) + { + idx = 4; + } + + for (i = 1; i < idx; i++) + { + addr = ISISC_RULE_FUNC_ADDR + (i << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(reg[i - 1])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} +#endif + +static sw_error_t +_isisc_filter_down_to_hw(a_uint32_t dev_id, hw_filter_t * filter, + a_uint32_t flt_idx) +{ +#ifdef ISISC_SW_ENTRY + a_uint8_t *tbl = sw_filter_mem + sizeof (hw_filter_t) * flt_idx; + + aos_mem_copy(tbl, filter, sizeof (hw_filter_t)); +#else +#ifdef ISISC_HW_ENTRY + sw_error_t rv; + a_uint32_t i, base, addr; + + base = ISISC_FILTER_ACT_ADDR + (flt_idx << 4); + for (i = 0; i < 3; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(filter->act[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + base = ISISC_FILTER_VLU_ADDR + (flt_idx << 5); + for (i = 0; i < 5; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(filter->vlu[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + base = ISISC_FILTER_MSK_ADDR + (flt_idx << 5); + for (i = 0; i < 5; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(filter->msk[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } +#else + sw_error_t rv; + + rv = _isisc_filter_write(dev_id, &(filter->act[0]), flt_idx, + ISISC_FILTER_ACT_OP); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_filter_write(dev_id, &(filter->vlu[0]), flt_idx, + ISISC_FILTER_VLU_OP); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_filter_write(dev_id, &(filter->msk[0]), flt_idx, + ISISC_FILTER_MSK_OP); + SW_RTN_ON_ERROR(rv); +#endif +#endif + + return SW_OK; +} + +static sw_error_t +_isisc_filter_up_to_sw(a_uint32_t dev_id, hw_filter_t * filter, + a_uint32_t flt_idx) +{ +#ifdef ISISC_SW_ENTRY + a_uint8_t *tbl = sw_filter_mem + sizeof (hw_filter_t) * flt_idx; + + aos_mem_copy(filter, tbl, sizeof (hw_filter_t)); +#else +#ifdef ISISC_HW_ENTRY + sw_error_t rv; + a_uint32_t i, base, addr; + + base = ISISC_FILTER_VLU_ADDR + (flt_idx << 5); + for (i = 0; i < 5; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(filter->vlu[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + base = ISISC_FILTER_MSK_ADDR + (flt_idx << 5); + for (i = 0; i < 5; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(filter->msk[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + base = ISISC_FILTER_ACT_ADDR + (flt_idx << 4); + for (i = 0; i < 3; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(filter->act[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } +#else + sw_error_t rv; + + rv = _isisc_filter_read(dev_id, &(filter->vlu[0]), flt_idx, + ISISC_FILTER_VLU_OP); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_filter_read(dev_id, &(filter->msk[0]), flt_idx, + ISISC_FILTER_MSK_OP); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_filter_read(dev_id, &(filter->act[0]), flt_idx, + ISISC_FILTER_ACT_OP); + SW_RTN_ON_ERROR(rv); +#endif +#endif + + return SW_OK; +} + +static sw_error_t +_isisc_acl_list_insert(a_uint32_t dev_id, a_uint32_t * src_idx, + a_uint32_t * dst_idx, isisc_acl_rule_t * src_rule, + isisc_acl_rule_t * dst_rule) +{ + a_uint32_t i, data, rule_id, list_id, list_pri; + + rule_id = 0; + list_id = src_rule[*src_idx].list_id; + list_pri = src_rule[*src_idx].list_pri; + + for (i = *src_idx; i < ISISC_MAX_FILTER; i++) + { + if (!(ENT_USED & src_rule[i].status)) + { + continue; // was: break; + } + + if (src_rule[i].list_id != list_id) + { + break; + } + + SW_GET_FIELD_BY_REG(MAC_RUL_M4, RULE_TYP, data, + src_rule[i].filter.msk[4]); + if (!data) + { + continue; + } + + if (ISISC_MAX_FILTER <= *dst_idx) + { + return SW_NO_RESOURCE; + } + + if (ENT_USED & dst_rule[*dst_idx].status) + { + return SW_NO_RESOURCE; + } + + SW_GET_FIELD_BY_REG(MAC_RUL_M4, RULE_VALID, data, + src_rule[i].filter.msk[4]); + if ((FLT_START == data) && (*dst_idx % 2)) + { + if (*src_idx != i) + { + dst_rule[*dst_idx].src_flt_dis = src_rule[i].src_flt_dis; + dst_rule[*dst_idx].list_id = list_id; + dst_rule[*dst_idx].list_pri = list_pri; + dst_rule[*dst_idx].rule_id = rule_id - 1; + dst_rule[*dst_idx].status |= ENT_USED; + } + + (*dst_idx)++; + if (ISISC_MAX_FILTER <= *dst_idx) + { + return SW_NO_RESOURCE; + } + + if (ENT_USED & dst_rule[*dst_idx].status) + { + return SW_NO_RESOURCE; + } + } + + aos_mem_copy(&(dst_rule[*dst_idx].filter), &(src_rule[i].filter), + sizeof (hw_filter_t)); + dst_rule[*dst_idx].src_flt_dis = src_rule[i].src_flt_dis; + dst_rule[*dst_idx].list_id = list_id; + dst_rule[*dst_idx].list_pri = list_pri; + dst_rule[*dst_idx].rule_id = rule_id; + dst_rule[*dst_idx].status |= ENT_USED; + if (ENT_DEACTIVE & src_rule[i].status) + { + dst_rule[*dst_idx].status |= ENT_DEACTIVE; + } + (*dst_idx)++; + + if ((FLT_END == data) && (*dst_idx % 2)) + { + if (ISISC_MAX_FILTER > *dst_idx) + { + dst_rule[*dst_idx].src_flt_dis = src_rule[i].src_flt_dis; + dst_rule[*dst_idx].list_id = list_id; + dst_rule[*dst_idx].list_pri = list_pri; + dst_rule[*dst_idx].rule_id = rule_id; + dst_rule[*dst_idx].status |= ENT_USED; + (*dst_idx)++; + } + } + + if ((FLT_END == data) || (FLT_STARTEND == data)) + { + rule_id++; + } + } + + *src_idx = i; + return SW_OK; +} + +static sw_error_t +_isisc_acl_rule_alloc(a_uint32_t dev_id, isisc_acl_list_t * sw_list, + a_uint32_t filter_nr) +{ + a_uint32_t free_flt_nr, load_idx, begin_idx, start_idx, end_idx, i; + a_uint32_t largest_nr, largest_idx; + sw_error_t rv; + + /* calculate the proper location, [start_idx, end_idx) */ + start_idx = 0; + end_idx = ISISC_MAX_FILTER; + for (i = 0; i < ISISC_MAX_FILTER; i++) + { + if (ENT_USED & sw_rule_ent[dev_id][i].status) + { + if (sw_rule_ent[dev_id][i].list_pri < sw_list->list_pri) + { + start_idx = i + 1; + } + else if (sw_rule_ent[dev_id][i].list_pri > sw_list->list_pri) + { + end_idx = i; + break; + } + } + } + + /* find the larget free filters block */ + largest_nr = 0; + largest_idx = 0; + free_flt_nr = 0; + begin_idx = start_idx; + for (i = start_idx; i < end_idx; i++) + { + if (!(ENT_USED & sw_rule_ent[dev_id][i].status)) + { + free_flt_nr++; + } + else + { + if (free_flt_nr > largest_nr) + { + largest_nr = free_flt_nr; + largest_idx = begin_idx; + } + free_flt_nr = 0; + begin_idx = i + 1; + } + } + + if (free_flt_nr > largest_nr) + { + largest_nr = free_flt_nr; + largest_idx = begin_idx; + } + + if ((!largest_nr) || ((largest_nr + 1) < filter_nr)) + { + return SW_NO_RESOURCE; + } + + for (i = 0; i < ISISC_MAX_FILTER; i++) + { + if (ENT_USED & sw_rule_ent[dev_id][i].status) + { + aos_mem_copy(&(sw_rule_tmp[dev_id][i]), &(sw_rule_ent[dev_id][i]), + sizeof (isisc_acl_rule_t)); + } + } + + begin_idx = 0; + load_idx = largest_idx; + rv = _isisc_acl_list_insert(dev_id, &begin_idx, &load_idx, + hw_rule_tmp[dev_id], sw_rule_tmp[dev_id]); + return rv; +} + +static sw_error_t +_isisc_acl_rule_reorder(a_uint32_t dev_id, isisc_acl_list_t * sw_list) +{ + a_uint32_t i, src_idx, dst_idx; + sw_error_t rv; + + dst_idx = 0; + for (i = 0; i < ISISC_MAX_FILTER;) + { + if (ENT_USED & sw_rule_ent[dev_id][i].status) + { + if (sw_rule_ent[dev_id][i].list_pri <= sw_list->list_pri) + { + rv = _isisc_acl_list_insert(dev_id, &i, &dst_idx, + sw_rule_ent[dev_id], + sw_rule_tmp[dev_id]); + SW_RTN_ON_ERROR(rv); + } + else + { + break; + } + } + else + { + i++; + } + } + + src_idx = 0; + rv = _isisc_acl_list_insert(dev_id, &src_idx, &dst_idx, hw_rule_tmp[dev_id], + sw_rule_tmp[dev_id]); + SW_RTN_ON_ERROR(rv); + + for (; i < ISISC_MAX_FILTER;) + { + if (ENT_USED & sw_rule_ent[dev_id][i].status) + { + rv = _isisc_acl_list_insert(dev_id, &i, &dst_idx, + sw_rule_ent[dev_id], + sw_rule_tmp[dev_id]); + SW_RTN_ON_ERROR(rv); + } + else + { + i++; + } + } + + return SW_OK; +} + +static void +_isisc_acl_rule_sync(a_uint32_t dev_id, a_uint32_t flt_idx, a_uint32_t flt_nr) +{ + a_uint32_t i, data; + + for (i = flt_idx; i < (flt_idx + flt_nr); i++) + { + if (aos_mem_cmp + (&(sw_rule_ent[dev_id][i]), &(sw_rule_tmp[dev_id][i]), + sizeof (isisc_acl_rule_t))) + { + SW_GET_FIELD_BY_REG(MAC_RUL_M4, RULE_TYP, data, + sw_rule_tmp[dev_id][i].filter.msk[4]); + if (data) + { + _isisc_filter_down_to_hw(dev_id, + &(sw_rule_tmp[dev_id][i].filter), i); + } + else + { + _isisc_filter_valid_set(dev_id, i, 0); + } + + aos_mem_copy(&(sw_rule_ent[dev_id][i]), &(sw_rule_tmp[dev_id][i]), + sizeof (isisc_acl_rule_t)); + _isisc_acl_rule_src_filter_sts_set(dev_id, i, + !sw_rule_tmp[dev_id][i].src_flt_dis); + } + } +} + +static sw_error_t +_isisc_acl_list_creat(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t list_pri) +{ + a_uint32_t i, loc = ISISC_MAX_FILTER; + isisc_acl_list_t *sw_list; + + HSL_DEV_ID_CHECK(dev_id); + + if ((ISISC_MAX_LIST_ID < list_id) || (ISISC_MAX_LIST_PRI < list_pri)) + { + return SW_NOT_SUPPORTED; + } + + for (i = 0; i < ISISC_MAX_FILTER; i++) + { + sw_list = &(sw_list_ent[dev_id][i]); + if (ENT_USED & sw_list->status) + { + if (list_id == sw_list->list_id) + { + return SW_ALREADY_EXIST; + } + } + else + { + loc = i; + } + } + + if (ISISC_MAX_FILTER == loc) + { + return SW_NO_RESOURCE; + } + + sw_list = &(sw_list_ent[dev_id][loc]); + aos_mem_zero(sw_list, sizeof (isisc_acl_list_t)); + sw_list->list_id = list_id; + sw_list->list_pri = list_pri; + sw_list->status |= ENT_USED; + return SW_OK; +} + +static sw_error_t +_isisc_acl_list_destroy(a_uint32_t dev_id, a_uint32_t list_id) +{ + isisc_acl_list_t *sw_list; + + HSL_DEV_ID_CHECK(dev_id); + + if (ISISC_MAX_LIST_ID < list_id) + { + return SW_NOT_SUPPORTED; + } + + sw_list = _isisc_acl_list_loc(dev_id, list_id); + if (NULL == sw_list) + { + return SW_NOT_FOUND; + } + + if (0 != sw_list->bind_pts) + { + return SW_NOT_SUPPORTED; + } + + if (0 != sw_list->rule_nr) + { + return SW_NOT_SUPPORTED; + } + + aos_mem_zero(sw_list, sizeof (isisc_acl_list_t)); + return SW_OK; +} + +static sw_error_t +_isisc_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; + isisc_acl_list_t *sw_list; + isisc_acl_rule_t *sw_rule; + a_uint32_t i, free_flt_nr, old_flt_nr, old_flt_idx, new_flt_nr, bind_pts; + + HSL_DEV_ID_CHECK(dev_id); + + if (ISISC_MAX_LIST_ID < list_id) + { + return SW_NOT_SUPPORTED; + } + + if ((0 == rule_nr) || (NULL == rule)) + { + return SW_BAD_PARAM; + } + + sw_list = _isisc_acl_list_loc(dev_id, list_id); + if (NULL == sw_list) + { + return SW_NOT_FOUND; + } + + if (rule_id != sw_list->rule_nr) + { + return SW_BAD_PARAM; + } + + old_flt_idx = 0; + old_flt_nr = 0; + free_flt_nr = 0; + aos_mem_zero(hw_rule_tmp[dev_id], + ISISC_HW_RULE_TMP_CNT * sizeof (isisc_acl_rule_t)); + aos_mem_zero(sw_rule_tmp[dev_id], + ISISC_MAX_FILTER * sizeof (isisc_acl_rule_t)); + for (i = 0; i < ISISC_MAX_FILTER; i++) + { + sw_rule = &(sw_rule_ent[dev_id][i]); + if (ENT_USED & sw_rule->status) + { + if (sw_rule->list_id == sw_list->list_id) + { + aos_mem_copy(&(hw_rule_tmp[dev_id][old_flt_nr]), sw_rule, + sizeof (isisc_acl_rule_t)); + if (!old_flt_nr) + { + old_flt_idx = i; + } + old_flt_nr++; + } + } + else + { + free_flt_nr++; + } + } + + if (!free_flt_nr) + { + return SW_NO_RESOURCE; + } + + /* parse rule entry and alloc rule resource */ + new_flt_nr = old_flt_nr; + for (i = 0; i < rule_nr; i++) + { + rv = _isisc_acl_rule_sw_to_hw(dev_id, &rule[i], hw_rule_tmp[dev_id], + &new_flt_nr); + SW_RTN_ON_ERROR(rv); + } + + if (free_flt_nr < (new_flt_nr - old_flt_nr)) + { + return SW_NO_RESOURCE; + } + + for (i = old_flt_nr; i < new_flt_nr; i++) + { + hw_rule_tmp[dev_id][i].status |= ENT_USED; + hw_rule_tmp[dev_id][i].list_id = sw_list->list_id; + hw_rule_tmp[dev_id][i].list_pri = sw_list->list_pri; + bind_pts = sw_list->bind_pts; + SW_SET_REG_BY_FIELD(MAC_RUL_V4, SRC_PT, bind_pts, + (hw_rule_tmp[dev_id][i].filter.vlu[4])); + } + + for (i = 0; i < old_flt_nr; i++) + { + sw_rule = &(sw_rule_ent[dev_id][old_flt_idx + i]); + sw_rule->status &= (~ENT_USED); + sw_rule->status |= (ENT_TMP); + } + + rv = _isisc_acl_rule_alloc(dev_id, sw_list, new_flt_nr); + if (SW_OK != rv) + { + aos_mem_zero(sw_rule_tmp[dev_id], + ISISC_MAX_FILTER * sizeof (isisc_acl_rule_t)); + rv = _isisc_acl_rule_reorder(dev_id, sw_list); + } + + for (i = 0; i < old_flt_nr; i++) + { + sw_rule = &(sw_rule_ent[dev_id][i + old_flt_idx]); + sw_rule->status |= (ENT_USED); + sw_rule->status &= (~ENT_TMP); + } + SW_RTN_ON_ERROR(rv); + + _isisc_acl_rule_sync(dev_id, 0, ISISC_MAX_FILTER); + sw_list->rule_nr += rule_nr; + + _isisc_acl_sw_rule_dump("sw rule after add", sw_rule_ent[dev_id]); + return SW_OK; +} + +static sw_error_t +_isisc_acl_rule_delete(a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t rule_id, a_uint32_t rule_nr) +{ + isisc_acl_rule_t *sw_rule; + isisc_acl_list_t *sw_list; + a_uint32_t i, flt_idx = 0, src_idx, dst_idx, del_nr = 0, flt_nr = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (ISISC_MAX_LIST_ID < list_id) + { + return SW_NOT_SUPPORTED; + } + + sw_list = _isisc_acl_list_loc(dev_id, list_id); + if (NULL == sw_list) + { + return SW_NOT_FOUND; + } + + if (sw_list->rule_nr < (rule_id + rule_nr)) + { + return SW_BAD_PARAM; + } + + aos_mem_zero(hw_rule_tmp[dev_id], + ISISC_HW_RULE_TMP_CNT * sizeof (isisc_acl_rule_t)); + aos_mem_zero(sw_rule_tmp[dev_id], + ISISC_MAX_FILTER * sizeof (isisc_acl_rule_t)); + + for (i = 0; i < ISISC_MAX_FILTER; i++) + { + sw_rule = &(sw_rule_ent[dev_id][i]); + if ((ENT_USED & sw_rule->status) && (sw_rule->list_id == list_id)) + { + if (!flt_nr) + { + flt_idx = i; + } + + if ((sw_rule->rule_id >= rule_id) + && (sw_rule->rule_id < (rule_id + rule_nr))) + { + del_nr++; + } + else + { + aos_mem_copy(&(hw_rule_tmp[dev_id][flt_idx + flt_nr]), sw_rule, + sizeof (isisc_acl_rule_t)); + } + flt_nr++; + } + } + + if (!del_nr) + { + return SW_NOT_FOUND; + } + + _isisc_acl_sw_rule_dump("hw rule before del", hw_rule_tmp[dev_id]); + + for (i = 0; i < flt_nr; i++) + { + sw_rule = &(hw_rule_tmp[dev_id][flt_idx + i]); + if (ENT_USED & sw_rule->status) + { + break; + } + } + + if (i != flt_nr) + { + src_idx = flt_idx + i; + dst_idx = flt_idx; + rv = _isisc_acl_list_insert(dev_id, &src_idx, &dst_idx, + hw_rule_tmp[dev_id], sw_rule_tmp[dev_id]); + SW_RTN_ON_ERROR(rv); + } + + _isisc_acl_rule_sync(dev_id, flt_idx, flt_nr); + sw_list->rule_nr -= rule_nr; + + _isisc_acl_sw_rule_dump("sw rule after del", sw_rule_ent[dev_id]); + return SW_OK; +} + +static sw_error_t +_isisc_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; + isisc_acl_rule_t *sw_rule; + a_uint32_t flt_nr = 0, i; + + HSL_DEV_ID_CHECK(dev_id); + + if (ISISC_MAX_LIST_ID < list_id) + { + return SW_NOT_SUPPORTED; + } + + aos_mem_zero(hw_rule_tmp[dev_id], + ISISC_HW_RULE_TMP_CNT * sizeof (isisc_acl_rule_t)); + for (i = 0; i < ISISC_MAX_FILTER; i++) + { + sw_rule = &(sw_rule_ent[dev_id][i]); + if (ENT_USED & sw_rule->status) + { + if ((sw_rule->list_id == list_id) && (sw_rule->rule_id == rule_id)) + { + aos_mem_copy(&(hw_rule_tmp[dev_id][flt_nr]), sw_rule, + sizeof (isisc_acl_rule_t)); + flt_nr++; + } + } + } + + if (!flt_nr) + { + return SW_NOT_FOUND; + } + + aos_mem_zero(rule, sizeof (fal_acl_rule_t)); + rv = _isisc_acl_rule_hw_to_sw(dev_id, rule, hw_rule_tmp[dev_id], 0, flt_nr); + return rv; +} + +static sw_error_t +_isisc_acl_rule_bind(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t ports) +{ + sw_error_t rv; + a_uint32_t i; + isisc_acl_rule_t *sw_rule; + + for (i = 0; i < ISISC_MAX_FILTER; i++) + { + sw_rule = &(sw_rule_ent[dev_id][i]); + + if ((ENT_USED & sw_rule->status) + && (list_id == sw_rule->list_id) + && (!(ENT_DEACTIVE & sw_rule->status))) + { + rv = _isisc_filter_ports_bind(dev_id, i, ports); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(MAC_RUL_V4, SRC_PT, ports, + (sw_rule->filter.vlu[4])); + } + } + + return SW_OK; +} + +static sw_error_t +_isisc_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; + a_uint32_t ports; + isisc_acl_list_t *sw_list; + + HSL_DEV_ID_CHECK(dev_id); + + if (ISISC_MAX_LIST_ID < list_id) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_ACL_DIREC_IN != direc) + { + return SW_NOT_SUPPORTED; + } + + sw_list = _isisc_acl_list_loc(dev_id, list_id); + if (NULL == sw_list) + { + return SW_NOT_FOUND; + } + + if (FAL_ACL_BIND_PORT == obj_t) + { + ports = (sw_list->bind_pts) | (0x1 << obj_idx); + } + else if (FAL_ACL_BIND_PORTBITMAP == obj_t) + { + ports = (sw_list->bind_pts) | obj_idx; + } + else + { + return SW_NOT_SUPPORTED; + } + + rv = _isisc_acl_rule_bind(dev_id, list_id, ports); + SW_RTN_ON_ERROR(rv); + + sw_list->bind_pts = ports; + return SW_OK; +} + +static sw_error_t +_isisc_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; + a_uint32_t ports; + isisc_acl_list_t *sw_list; + + HSL_DEV_ID_CHECK(dev_id); + + if (ISISC_MAX_LIST_ID < list_id) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_ACL_DIREC_IN != direc) + { + return SW_NOT_SUPPORTED; + } + + sw_list = _isisc_acl_list_loc(dev_id, list_id); + if (NULL == sw_list) + { + return SW_NOT_FOUND; + } + + if (FAL_ACL_BIND_PORT == obj_t) + { + ports = (sw_list->bind_pts) & (~(0x1UL << obj_idx)); + } + else if (FAL_ACL_BIND_PORTBITMAP == obj_t) + { + ports = (sw_list->bind_pts) & (~obj_idx); + } + else + { + return SW_NOT_SUPPORTED; + } + + rv = _isisc_acl_rule_bind(dev_id, list_id, ports); + SW_RTN_ON_ERROR(rv); + + sw_list->bind_pts = ports; + return SW_OK; +} + +static sw_error_t +_isisc_acl_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, MOD_ENABLE, 0, ACL_EN, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_acl_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, MOD_ENABLE, 0, ACL_EN, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_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; + a_uint32_t reg = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (ISISC_UDF_MAX_OFFSET < offset) + { + return SW_BAD_PARAM; + } + + if (ISISC_UDF_MAX_OFFSET < length) + { + return SW_BAD_PARAM; + } + + if ((FAL_ACL_UDF_TYPE_L2_SNAP == udf_type) + || (FAL_ACL_UDF_TYPE_L3_PLUS == udf_type)) + { + HSL_REG_ENTRY_GET(rv, dev_id, WIN_RULE_CTL1, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + HSL_REG_ENTRY_GET(rv, dev_id, WIN_RULE_CTL0, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + SW_RTN_ON_ERROR(rv); + + switch (udf_type) + { + case FAL_ACL_UDF_TYPE_L2: + SW_SET_REG_BY_FIELD(WIN_RULE_CTL0, L2_OFFSET, offset, reg); + SW_SET_REG_BY_FIELD(WIN_RULE_CTL0, L2_LENGTH, length, reg); + break; + case FAL_ACL_UDF_TYPE_L3: + SW_SET_REG_BY_FIELD(WIN_RULE_CTL0, L3_OFFSET, offset, reg); + SW_SET_REG_BY_FIELD(WIN_RULE_CTL0, L3_LENGTH, length, reg); + break; + case FAL_ACL_UDF_TYPE_L4: + SW_SET_REG_BY_FIELD(WIN_RULE_CTL0, L4_OFFSET, offset, reg); + SW_SET_REG_BY_FIELD(WIN_RULE_CTL0, L4_LENGTH, length, reg); + break; + case FAL_ACL_UDF_TYPE_L2_SNAP: + SW_SET_REG_BY_FIELD(WIN_RULE_CTL1, L2S_OFFSET, offset, reg); + SW_SET_REG_BY_FIELD(WIN_RULE_CTL1, L2S_LENGTH, length, reg); + break; + case FAL_ACL_UDF_TYPE_L3_PLUS: + SW_SET_REG_BY_FIELD(WIN_RULE_CTL1, L3P_OFFSET, offset, reg); + SW_SET_REG_BY_FIELD(WIN_RULE_CTL1, L3P_LENGTH, length, reg); + break; + default: + return SW_BAD_PARAM; + } + + if ((FAL_ACL_UDF_TYPE_L2_SNAP == udf_type) + || (FAL_ACL_UDF_TYPE_L3_PLUS == udf_type)) + { + HSL_REG_ENTRY_SET(rv, dev_id, WIN_RULE_CTL1, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + HSL_REG_ENTRY_SET(rv, dev_id, WIN_RULE_CTL0, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + + return rv; +} + +static sw_error_t +_isisc_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; + a_uint32_t reg = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if ((FAL_ACL_UDF_TYPE_L2_SNAP == udf_type) + || (FAL_ACL_UDF_TYPE_L3_PLUS == udf_type)) + { + HSL_REG_ENTRY_GET(rv, dev_id, WIN_RULE_CTL1, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + HSL_REG_ENTRY_GET(rv, dev_id, WIN_RULE_CTL0, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + SW_RTN_ON_ERROR(rv); + + switch (udf_type) + { + case FAL_ACL_UDF_TYPE_L2: + SW_GET_FIELD_BY_REG(WIN_RULE_CTL0, L2_OFFSET, (*offset), reg); + SW_GET_FIELD_BY_REG(WIN_RULE_CTL0, L2_LENGTH, (*length), reg); + break; + case FAL_ACL_UDF_TYPE_L3: + SW_GET_FIELD_BY_REG(WIN_RULE_CTL0, L3_OFFSET, (*offset), reg); + SW_GET_FIELD_BY_REG(WIN_RULE_CTL0, L3_LENGTH, (*length), reg); + break; + case FAL_ACL_UDF_TYPE_L4: + SW_GET_FIELD_BY_REG(WIN_RULE_CTL0, L4_OFFSET, (*offset), reg); + SW_GET_FIELD_BY_REG(WIN_RULE_CTL0, L4_LENGTH, (*length), reg); + break; + case FAL_ACL_UDF_TYPE_L2_SNAP: + SW_GET_FIELD_BY_REG(WIN_RULE_CTL1, L2S_OFFSET, (*offset), reg); + SW_GET_FIELD_BY_REG(WIN_RULE_CTL1, L2S_LENGTH, (*length), reg); + break; + case FAL_ACL_UDF_TYPE_L3_PLUS: + SW_GET_FIELD_BY_REG(WIN_RULE_CTL1, L3P_OFFSET, (*offset), reg); + SW_GET_FIELD_BY_REG(WIN_RULE_CTL1, L3P_LENGTH, (*length), reg); + break; + default: + return SW_BAD_PARAM; + } + + return SW_OK; +} + +static sw_error_t +_isisc_acl_rule_active(a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t rule_id, a_uint32_t rule_nr, a_bool_t active) +{ + sw_error_t rv; + a_uint32_t i, ports; + isisc_acl_list_t *sw_list; + isisc_acl_rule_t *sw_rule; + + HSL_DEV_ID_CHECK(dev_id); + + sw_list = _isisc_acl_list_loc(dev_id, list_id); + if (NULL == sw_list) + { + return SW_NOT_FOUND; + } + + if (sw_list->rule_nr < (rule_id + rule_nr)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == active) + { + ports = (sw_list->bind_pts); + } + else + { + ports = 0; + } + + for (i = 0; i < ISISC_MAX_FILTER; i++) + { + sw_rule = &(sw_rule_ent[dev_id][i]); + + if ((ENT_USED & sw_rule->status) + && (list_id == sw_rule->list_id) + && (rule_id <= sw_rule->rule_id) + && ((rule_id + rule_nr) > sw_rule->rule_id)) + { + rv = _isisc_filter_ports_bind(dev_id, i, ports); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(MAC_RUL_V4, SRC_PT, ports, + (sw_rule->filter.vlu[4])); + + if (A_TRUE == active) + { + sw_rule->status &= (~ENT_DEACTIVE); + } + else + { + sw_rule->status |= (ENT_DEACTIVE); + } + } + } + + return SW_OK; +} + +static sw_error_t +_isisc_acl_rule_src_filter_sts_set(a_uint32_t dev_id, + a_uint32_t rule_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t reg = 0, regIdx; + isisc_acl_rule_t *sw_rule; + + HSL_DEV_ID_CHECK(dev_id); + + sw_rule = &sw_rule_ent[dev_id][rule_id]; + if (!(ENT_USED & sw_rule->status)) + { + return SW_NOT_FOUND; + } + + regIdx = rule_id >> 5; + + HSL_REG_ENTRY_GET(rv, dev_id, ACL_FWD_SRC_FILTER_CTL0, regIdx, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + reg |= (0x1 << (rule_id & 0x1F)); + sw_rule->src_flt_dis = 0; + } + else if (A_FALSE == enable) + { + reg &= ~(0x1 << (rule_id & 0x1F)); + sw_rule->src_flt_dis = 1; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_SET(rv, dev_id, ACL_FWD_SRC_FILTER_CTL0, regIdx, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_isisc_acl_rule_src_filter_sts_get(a_uint32_t dev_id, + a_uint32_t rule_id, a_bool_t* enable) +{ + sw_error_t rv; + a_uint32_t reg = 0, regIdx; + isisc_acl_rule_t *sw_rule; + + HSL_DEV_ID_CHECK(dev_id); + + sw_rule = &sw_rule_ent[dev_id][rule_id]; + if (!(ENT_USED & sw_rule->status)) + { + return SW_NOT_FOUND; + } + + regIdx = rule_id >> 5; + + HSL_REG_ENTRY_GET(rv, dev_id, ACL_FWD_SRC_FILTER_CTL0, regIdx, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (reg & (0x1 << (rule_id & 0x1F))) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return rv; +} + + +HSL_LOCAL sw_error_t +isisc_acl_list_dump(a_uint32_t dev_id) +{ + _isisc_acl_list_dump(dev_id); + return SW_OK; +} + +HSL_LOCAL sw_error_t +isisc_acl_rule_dump(a_uint32_t dev_id) +{ + a_uint32_t flt_idx, i; + sw_error_t rv; + hw_filter_t filter; + + aos_printk("\nisisc_acl_rule_dump:\n"); + + for (flt_idx = 0; flt_idx < ISISC_MAX_FILTER; flt_idx++) + { + aos_mem_zero(&filter, sizeof (hw_filter_t)); + + rv = _isisc_filter_up_to_sw(dev_id, &filter, flt_idx); + if (SW_OK != rv) + { + continue; + } + + aos_printk("\n%d filter dump:", flt_idx); + + aos_printk("\nhardware content:"); + aos_printk("\nact:"); + for (i = 0; i < (sizeof (filter.act) / sizeof (a_uint32_t)); i++) + { + aos_printk("%08x ", filter.act[i]); + } + + aos_printk("\nvlu:"); + for (i = 0; i < (sizeof (filter.vlu) / sizeof (a_uint32_t)); i++) + { + aos_printk("%08x ", filter.vlu[i]); + } + + aos_printk("\nmsk:"); + for (i = 0; i < (sizeof (filter.msk) / sizeof (a_uint32_t)); i++) + { + aos_printk("%08x ", filter.msk[i]); + } + + aos_printk("\nsoftware content:"); + aos_printk("\nact:"); + for (i = 0; i < (sizeof (filter.act) / sizeof (a_uint32_t)); i++) + { + aos_printk("%08x ", sw_rule_ent[dev_id][flt_idx].filter.act[i]); + } + + aos_printk("\nvlu:"); + for (i = 0; i < (sizeof (filter.vlu) / sizeof (a_uint32_t)); i++) + { + aos_printk("%08x ", sw_rule_ent[dev_id][flt_idx].filter.vlu[i]); + } + + aos_printk("\nmsk:"); + for (i = 0; i < (sizeof (filter.msk) / sizeof (a_uint32_t)); i++) + { + aos_printk("%08x ", sw_rule_ent[dev_id][flt_idx].filter.msk[i]); + } + + aos_printk("\nctl:status[%02d] list_id[%02d] rule_id[%02d] src_flt_dis[%02d]", + sw_rule_ent[dev_id][flt_idx].status, + sw_rule_ent[dev_id][flt_idx].list_id, + sw_rule_ent[dev_id][flt_idx].rule_id, + sw_rule_ent[dev_id][flt_idx].src_flt_dis); + + aos_printk("\n\n"); + } + + return SW_OK; +} + +sw_error_t +isisc_acl_reset(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + + aos_mem_zero(sw_list_ent[dev_id], + ISISC_MAX_FILTER * sizeof (isisc_acl_list_t)); + + aos_mem_zero(sw_rule_ent[dev_id], + ISISC_MAX_FILTER * sizeof (isisc_acl_rule_t)); + + return SW_OK; +} + +/** + * @brief Creat an acl list + * @details Comments: + * If the value of list_pri is more small then the priority is more high, + * that means the list could be first matched. + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] list_pri acl list priority + * @return SW_OK or error code + */ +sw_error_t +isisc_acl_list_creat(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t list_pri) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_acl_list_creat(dev_id, list_id, list_pri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Destroy an acl list + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_acl_list_destroy(a_uint32_t dev_id, a_uint32_t list_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_acl_list_destroy(dev_id, list_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add one rule or more rules to an existing acl list + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] rule_id first rule id of this adding operation in list + * @param[in] rule_nr rule number of this adding operation + * @param[in] rule rules content of this adding operation + * @return SW_OK or error code + */ +sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_acl_rule_add(dev_id, list_id, rule_id, rule_nr, rule); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete one rule or more rules from an existing acl list + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] rule_id first rule id of this deleteing operation in list + * @param[in] rule_nr rule number of this deleteing operation + * @return SW_OK or error code + */ +sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_acl_rule_delete(dev_id, list_id, rule_id, rule_nr); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Query one particular rule in a particular acl list + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] rule_id first rule id of this deleteing operation in list + * @param[out] rule rule content of this operation + * @return SW_OK or error code + */ +sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_acl_rule_query(dev_id, list_id, rule_id, rule); + HSL_API_UNLOCK; + return rv; +} + +a_uint32_t +isisc_acl_rule_get_offset(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t rule_id) +{ + a_uint32_t i, pos=0; + isisc_acl_rule_t *sw_rule; + + for (i = 0; i < ISISC_MAX_FILTER; i++) + { + sw_rule = &(sw_rule_ent[0][i]); + + if ((ENT_USED & sw_rule->status) + && (list_id == sw_rule->list_id) && (sw_rule->rule_id == rule_id) + && (!(ENT_DEACTIVE & sw_rule->status))) + { + pos = i; + break; + + } + } + + return pos; +} + + +sw_error_t +isisc_acl_rule_sync_multi_portmap(a_uint32_t dev_id, a_uint32_t pos, a_uint32_t *act) +{ + + HSL_DEV_ID_CHECK(dev_id); + + if (ISISC_MAX_LIST_ID < pos) + { + return SW_NOT_SUPPORTED; + } + + sw_rule_ent[dev_id][pos].filter.act[1] = act[1]; + sw_rule_ent[dev_id][pos].filter.act[2] = act[2]; + + sw_rule_tmp[dev_id][pos].filter.act[1] = act[1]; + sw_rule_tmp[dev_id][pos].filter.act[2] = act[2]; + + hw_rule_tmp[dev_id][pos].filter.act[1] = act[1]; + hw_rule_tmp[dev_id][pos].filter.act[2] = act[2]; + + + return SW_OK; +} + +/** + * @brief Bind an acl list to a particular object + * @details Comments: + * If obj_t equals FAL_ACL_BIND_PORT then obj_idx means port id + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] direc direction of this binding operation + * @param[in] obj_t object type of this binding operation + * @param[in] obj_idx object index of this binding operation + * @return SW_OK or error code + */ +sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_acl_list_bind(dev_id, list_id, direc, obj_t, obj_idx); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Unbind an acl list from a particular object + * @details Comments: + * If obj_t equals FAL_ACL_BIND_PORT then obj_idx means port id + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] direc direction of this unbinding operation + * @param[in] obj_t object type of this unbinding operation + * @param[in] obj_idx object index of this unbinding operation + * @return SW_OK or error code + */ +sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_acl_list_unbind(dev_id, list_id, direc, obj_t, obj_idx); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set working status of ACL engine on a particular device + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +sw_error_t +isisc_acl_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_acl_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get working status of ACL engine on a particular device + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_acl_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_acl_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set user define fields profile on a particular port + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] udf_type udf type + * @param[in] offset udf offset + * @param[in] length udf length + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_acl_port_udf_profile_set(dev_id, port_id, udf_type, offset, + length); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get user define fields profile on a particular port + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] udf_type udf type + * @param[out] offset udf offset + * @param[out] length udf length + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_acl_port_udf_profile_get(dev_id, port_id, udf_type, offset, + length); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Active one or more rules in an existing acl list + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] rule_id first rule id of this deactive operation in list + * @param[in] rule_nr rule number of this deactive operation + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_acl_rule_active(dev_id, list_id, rule_id, rule_nr, A_TRUE); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Deactive one or more rules in an existing acl list + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] rule_id first rule id of this deactive operation in list + * @param[in] rule_nr rule number of this deactive operation + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_acl_rule_active(dev_id, list_id, rule_id, rule_nr, A_FALSE); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief enable acl forward source filter of one rule. + * @param[in] dev_id device id + * @param[in] rule_id first rule id of this deactive operation in list + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_acl_rule_src_filter_sts_set(a_uint32_t dev_id, + a_uint32_t rule_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_acl_rule_src_filter_sts_set(dev_id, rule_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief get the status of acl forward source filter of one rule. + * @param[in] dev_id device id + * @param[in] rule_id first rule id of this deactive operation in list + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_acl_rule_src_filter_sts_get(a_uint32_t dev_id, + a_uint32_t rule_id, a_bool_t* enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_acl_rule_src_filter_sts_get(dev_id, rule_id, enable); + HSL_API_UNLOCK; + return rv; +} + + + +sw_error_t +isisc_acl_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + + sw_list_ent[dev_id] = + (isisc_acl_list_t *) aos_mem_alloc(ISISC_MAX_FILTER * + sizeof (isisc_acl_list_t)); + if (NULL == sw_list_ent[dev_id]) + { + return SW_NO_RESOURCE; + } + aos_mem_zero(sw_list_ent[dev_id], + ISISC_MAX_FILTER * sizeof (isisc_acl_list_t)); + + sw_rule_ent[dev_id] = + (isisc_acl_rule_t *) aos_mem_alloc(ISISC_MAX_FILTER * + sizeof (isisc_acl_rule_t)); + if (NULL == sw_rule_ent[dev_id]) + { + return SW_NO_RESOURCE; + } + aos_mem_zero(sw_rule_ent[dev_id], + ISISC_MAX_FILTER * sizeof (isisc_acl_rule_t)); + + hw_rule_tmp[dev_id] = + (isisc_acl_rule_t *) aos_mem_alloc(ISISC_HW_RULE_TMP_CNT * + sizeof (isisc_acl_rule_t)); + if (NULL == hw_rule_tmp[dev_id]) + { + return SW_NO_RESOURCE; + } + + sw_rule_tmp[dev_id] = + (isisc_acl_rule_t *) aos_mem_alloc(ISISC_MAX_FILTER * + sizeof (isisc_acl_rule_t)); + if (NULL == sw_rule_tmp[dev_id]) + { + return SW_NO_RESOURCE; + } +#ifdef ISISC_SW_ENTRY + sw_filter_mem = aos_mem_alloc(ISISC_MAX_FILTER * sizeof (hw_filter_t)); + if (NULL == sw_filter_mem) + { + return SW_NO_RESOURCE; + } + aos_mem_zero(sw_filter_mem, ISISC_MAX_FILTER * sizeof (hw_filter_t)); +#endif + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->acl_list_creat = isisc_acl_list_creat; + p_api->acl_list_destroy = isisc_acl_list_destroy; + p_api->acl_list_bind = isisc_acl_list_bind; + p_api->acl_list_unbind = isisc_acl_list_unbind; + p_api->acl_rule_add = isisc_acl_rule_add; + p_api->acl_rule_delete = isisc_acl_rule_delete; + p_api->acl_rule_query = isisc_acl_rule_query; + p_api->acl_status_set = isisc_acl_status_set; + p_api->acl_status_get = isisc_acl_status_get; + p_api->acl_list_dump = isisc_acl_list_dump; + p_api->acl_rule_dump = isisc_acl_rule_dump; + p_api->acl_port_udf_profile_set = isisc_acl_port_udf_profile_set; + p_api->acl_port_udf_profile_get = isisc_acl_port_udf_profile_get; + p_api->acl_rule_active = isisc_acl_rule_active; + p_api->acl_rule_deactive = isisc_acl_rule_deactive; + p_api->acl_rule_src_filter_sts_set = isisc_acl_rule_src_filter_sts_set; + p_api->acl_rule_src_filter_sts_get = isisc_acl_rule_src_filter_sts_get; + p_api->acl_rule_get_offset = isisc_acl_rule_get_offset; + p_api->acl_rule_sync_multi_portmap = isisc_acl_rule_sync_multi_portmap; + } +#endif + + return SW_OK; +} + +sw_error_t +isisc_acl_cleanup(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + + if (NULL != sw_list_ent[dev_id]) + { + aos_mem_free(sw_list_ent[dev_id]); + } + + if (NULL != sw_rule_ent[dev_id]) + { + aos_mem_free(sw_rule_ent[dev_id]); + } + + if (NULL != hw_rule_tmp[dev_id]) + { + aos_mem_free(hw_rule_tmp[dev_id]); + } + + if (NULL != sw_rule_tmp[dev_id]) + { + aos_mem_free(sw_rule_tmp[dev_id]); + } +#ifdef DESS_SW_ENTRY + if (NULL != sw_filter_mem) + { + aos_mem_free(sw_filter_mem); + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_acl_parse.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_acl_parse.c new file mode 100755 index 000000000..9fb7b5ecc --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_acl_parse.c @@ -0,0 +1,2452 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 "hsl.h" +#include "hsl_dev.h" +#include "hsl_acl.h" +#include "isisc_acl.h" +#include "isisc_reg.h" +#include "isisc_acl_prv.h" + +#define DAH 0x1 +#define SAH 0x2 +#define TAG 0x4 +#define STAG 0x8 +#define CTAG 0x10 + +typedef sw_error_t(*parse_func_t) (fal_acl_rule_t * sw, + hw_filter_t * hw_filter_snap, + a_bool_t * b_care); + +static a_bool_t +_isisc_acl_zero_addr(const fal_mac_addr_t addr) +{ + a_uint32_t i; + + for (i = 0; i < 6; i++) + { + if (addr.uc[i]) + { + return A_FALSE; + } + } + return A_TRUE; +} + +static a_bool_t +_isisc_acl_field_care(fal_acl_field_op_t op, a_uint32_t val, a_uint32_t mask, + a_uint32_t chkvlu) +{ + if (FAL_ACL_FIELD_MASK == op) + { + if (0 == mask) + return A_FALSE; + } + else if (FAL_ACL_FIELD_RANGE == op) + { + if ((0 == val) && (chkvlu == mask)) + return A_FALSE; + } + else if (FAL_ACL_FIELD_LE == op) + { + if (chkvlu == val) + return A_FALSE; + } + else if (FAL_ACL_FIELD_GE == op) + { + if (0 == val) + return A_FALSE; + } + else if (FAL_ACL_FIELD_NE == op) + { + return A_TRUE; + } + + return A_TRUE; +} + +static sw_error_t +_isisc_acl_rule_bmac_parse(fal_acl_rule_t * sw, + hw_filter_t * hw, a_bool_t * b_care) +{ + a_uint32_t i; + + *b_care = A_FALSE; + aos_mem_zero(&(hw->vlu[0]), sizeof (hw->vlu)); + aos_mem_zero(&(hw->msk[0]), sizeof (hw->msk)); + + FIELD_SET_MASK(MAC_RUL_M4, RULE_TYP, ISISC_MAC_FILTER); + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_DA)) + { + if (A_TRUE != _isisc_acl_zero_addr(sw->dest_mac_mask)) + { + *b_care = A_TRUE; + } + + for (i = 0; i < 6; i++) + { + sw->dest_mac_val.uc[i] &= sw->dest_mac_mask.uc[i]; + } + + FIELD_SET(MAC_RUL_V0, DAV_BYTE2, sw->dest_mac_val.uc[2]); + FIELD_SET(MAC_RUL_V0, DAV_BYTE3, sw->dest_mac_val.uc[3]); + FIELD_SET(MAC_RUL_V0, DAV_BYTE4, sw->dest_mac_val.uc[4]); + FIELD_SET(MAC_RUL_V0, DAV_BYTE5, sw->dest_mac_val.uc[5]); + FIELD_SET(MAC_RUL_V1, DAV_BYTE0, sw->dest_mac_val.uc[0]); + FIELD_SET(MAC_RUL_V1, DAV_BYTE1, sw->dest_mac_val.uc[1]); + + FIELD_SET_MASK(MAC_RUL_M0, DAM_BYTE2, sw->dest_mac_mask.uc[2]); + FIELD_SET_MASK(MAC_RUL_M0, DAM_BYTE3, sw->dest_mac_mask.uc[3]); + FIELD_SET_MASK(MAC_RUL_M0, DAM_BYTE4, sw->dest_mac_mask.uc[4]); + FIELD_SET_MASK(MAC_RUL_M0, DAM_BYTE5, sw->dest_mac_mask.uc[5]); + FIELD_SET_MASK(MAC_RUL_M1, DAM_BYTE0, sw->dest_mac_mask.uc[0]); + FIELD_SET_MASK(MAC_RUL_M1, DAM_BYTE1, sw->dest_mac_mask.uc[1]); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_SA)) + { + if (A_TRUE != _isisc_acl_zero_addr(sw->src_mac_mask)) + { + *b_care = A_TRUE; + } + + for (i = 0; i < 6; i++) + { + sw->src_mac_val.uc[i] &= sw->src_mac_mask.uc[i]; + } + + FIELD_SET(MAC_RUL_V1, SAV_BYTE4, sw->src_mac_val.uc[4]); + FIELD_SET(MAC_RUL_V1, SAV_BYTE5, sw->src_mac_val.uc[5]); + FIELD_SET(MAC_RUL_V2, SAV_BYTE0, sw->src_mac_val.uc[0]); + FIELD_SET(MAC_RUL_V2, SAV_BYTE1, sw->src_mac_val.uc[1]); + FIELD_SET(MAC_RUL_V2, SAV_BYTE2, sw->src_mac_val.uc[2]); + FIELD_SET(MAC_RUL_V2, SAV_BYTE3, sw->src_mac_val.uc[3]); + + FIELD_SET_MASK(MAC_RUL_M1, SAM_BYTE4, sw->src_mac_mask.uc[4]); + FIELD_SET_MASK(MAC_RUL_M1, SAM_BYTE5, sw->src_mac_mask.uc[5]); + FIELD_SET_MASK(MAC_RUL_M2, SAM_BYTE0, sw->src_mac_mask.uc[0]); + FIELD_SET_MASK(MAC_RUL_M2, SAM_BYTE1, sw->src_mac_mask.uc[1]); + FIELD_SET_MASK(MAC_RUL_M2, SAM_BYTE2, sw->src_mac_mask.uc[2]); + FIELD_SET_MASK(MAC_RUL_M2, SAM_BYTE3, sw->src_mac_mask.uc[3]); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_ETHTYPE)) + { + if (0x0 != sw->ethtype_mask) + { + *b_care = A_TRUE; + } + + sw->ethtype_val &= sw->ethtype_mask; + FIELD_SET(MAC_RUL_V3, ETHTYPV, sw->ethtype_val); + FIELD_SET_MASK(MAC_RUL_M3, ETHTYPM, sw->ethtype_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_TAGGED)) + { + if (0x0 != sw->tagged_mask) + { + *b_care = A_TRUE; + } + + sw->tagged_val &= sw->tagged_mask; + FIELD_SET_MASK(MAC_RUL_M4, TAGGEDV, sw->tagged_val); + FIELD_SET_MASK(MAC_RUL_M4, TAGGEDM, sw->tagged_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_UP)) + { + if (0x0 != sw->up_mask) + { + *b_care = A_TRUE; + } + + sw->up_val &= sw->up_mask; + FIELD_SET(MAC_RUL_V3, VLANPRIV, sw->up_val); + FIELD_SET_MASK(MAC_RUL_M3, VLANPRIM, sw->up_mask); + } + + FIELD_SET_MASK(MAC_RUL_M4, VIDMSK, 1); + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_VID)) + { + if ((FAL_ACL_FIELD_MASK != sw->vid_op) + && (FAL_ACL_FIELD_RANGE != sw->vid_op) + && (FAL_ACL_FIELD_LE != sw->vid_op) + && (FAL_ACL_FIELD_GE != sw->vid_op)) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == + _isisc_acl_field_care(sw->vid_op, sw->vid_val, sw->vid_mask, + 0xfff)) + { + *b_care = A_TRUE; + } + + FIELD_SET_MASK(MAC_RUL_M4, VIDMSK, 0); + if (FAL_ACL_FIELD_MASK == sw->vid_op) + { + sw->vid_val &= sw->vid_mask; + FIELD_SET(MAC_RUL_V3, VLANIDV, sw->vid_val); + FIELD_SET_MASK(MAC_RUL_M3, VLANIDM, sw->vid_mask); + FIELD_SET_MASK(MAC_RUL_M4, VIDMSK, 1); + } + else if (FAL_ACL_FIELD_RANGE == sw->vid_op) + { + FIELD_SET(MAC_RUL_V3, VLANIDV, sw->vid_val); + FIELD_SET_MASK(MAC_RUL_M3, VLANIDM, sw->vid_mask); + } + else if (FAL_ACL_FIELD_LE == sw->vid_op) + { + FIELD_SET(MAC_RUL_V3, VLANIDV, 0); + FIELD_SET_MASK(MAC_RUL_M3, VLANIDM, sw->vid_val); + } + else + { + FIELD_SET(MAC_RUL_V3, VLANIDV, sw->vid_val); + FIELD_SET_MASK(MAC_RUL_M3, VLANIDM, 0xfff); + } + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_CFI)) + { + if (0x0 != sw->cfi_mask) + { + *b_care = A_TRUE; + } + + sw->cfi_val &= sw->cfi_mask; + FIELD_SET(MAC_RUL_V3, VLANCFIV, sw->cfi_val); + FIELD_SET_MASK(MAC_RUL_M3, VLANCFIM, sw->cfi_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL)) + { + FIELD_SET(MAC_RUL_V4, RULE_INV, 1); + } + + return SW_OK; +} + +static sw_error_t +_isisc_acl_rule_ehmac_parse(fal_acl_rule_t * sw, + hw_filter_t * hw, a_bool_t * b_care) +{ + a_uint32_t i; + a_bool_t da_h = A_FALSE, sa_h = A_FALSE; + + *b_care = A_FALSE; + aos_mem_zero(&(hw->vlu[0]), sizeof (hw->vlu)); + aos_mem_zero(&(hw->msk[0]), sizeof (hw->msk)); + + FIELD_SET_MASK(MAC_RUL_M4, RULE_TYP, ISISC_EHMAC_FILTER); + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_DA)) + { + for (i = 0; i < 3; i++) + { + if (sw->dest_mac_mask.uc[i]) + { + da_h = A_TRUE; + break; + } + } + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_SA)) + { + for (i = 0; i < 3; i++) + { + if (sw->src_mac_mask.uc[i]) + { + sa_h = A_TRUE; + break; + } + } + } + + /* if sa_h and da_h both are true need't process mac address fileds */ + if ((A_TRUE == da_h) && ((A_TRUE == sa_h))) + { + da_h = A_FALSE; + sa_h = A_FALSE; + } + + if (A_TRUE == da_h) + { + FIELD_SET(EHMAC_RUL_V3, DA_EN, 1); + + if (A_TRUE != _isisc_acl_zero_addr(sw->dest_mac_mask)) + { + *b_care = A_TRUE; + } + + for (i = 0; i < 6; i++) + { + sw->dest_mac_val.uc[i] &= sw->dest_mac_mask.uc[i]; + } + + FIELD_SET(EHMAC_RUL_V0, DAV_BYTE2, sw->dest_mac_val.uc[2]); + FIELD_SET(EHMAC_RUL_V0, DAV_BYTE3, sw->dest_mac_val.uc[3]); + FIELD_SET(EHMAC_RUL_V0, DAV_BYTE4, sw->dest_mac_val.uc[4]); + FIELD_SET(EHMAC_RUL_V0, DAV_BYTE5, sw->dest_mac_val.uc[5]); + FIELD_SET(EHMAC_RUL_V1, DAV_BYTE0, sw->dest_mac_val.uc[0]); + FIELD_SET(EHMAC_RUL_V1, DAV_BYTE1, sw->dest_mac_val.uc[1]); + + FIELD_SET_MASK(EHMAC_RUL_M0, DAM_BYTE2, sw->dest_mac_mask.uc[2]); + FIELD_SET_MASK(EHMAC_RUL_M0, DAM_BYTE3, sw->dest_mac_mask.uc[3]); + FIELD_SET_MASK(EHMAC_RUL_M0, DAM_BYTE4, sw->dest_mac_mask.uc[4]); + FIELD_SET_MASK(EHMAC_RUL_M0, DAM_BYTE5, sw->dest_mac_mask.uc[5]); + FIELD_SET_MASK(EHMAC_RUL_M1, DAM_BYTE0, sw->dest_mac_mask.uc[0]); + FIELD_SET_MASK(EHMAC_RUL_M1, DAM_BYTE1, sw->dest_mac_mask.uc[1]); + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_SA)) + { + if (A_TRUE != _isisc_acl_zero_addr(sw->src_mac_mask)) + { + *b_care = A_TRUE; + } + + for (i = 0; i < 6; i++) + { + sw->src_mac_val.uc[i] &= sw->src_mac_mask.uc[i]; + } + + FIELD_SET(EHMAC_RUL_V2, SAV_BYTE3, sw->src_mac_val.uc[3]); + FIELD_SET(EHMAC_RUL_V1, SAV_BYTE4, sw->src_mac_val.uc[4]); + FIELD_SET(EHMAC_RUL_V1, SAV_BYTE5, sw->src_mac_val.uc[5]); + + FIELD_SET_MASK(EHMAC_RUL_M2, SAM_BYTE3, sw->src_mac_mask.uc[3]); + FIELD_SET_MASK(EHMAC_RUL_M1, SAM_BYTE4, sw->src_mac_mask.uc[4]); + FIELD_SET_MASK(EHMAC_RUL_M1, SAM_BYTE5, sw->src_mac_mask.uc[5]); + } + } + + if (A_TRUE == sa_h) + { + if (A_TRUE != _isisc_acl_zero_addr(sw->src_mac_mask)) + { + *b_care = A_TRUE; + } + + for (i = 0; i < 6; i++) + { + sw->src_mac_val.uc[i] &= sw->src_mac_mask.uc[i]; + } + + FIELD_SET(EHMAC_RUL_V0, DAV_BYTE2, sw->src_mac_val.uc[2]); + FIELD_SET(EHMAC_RUL_V0, DAV_BYTE3, sw->src_mac_val.uc[3]); + FIELD_SET(EHMAC_RUL_V0, DAV_BYTE4, sw->src_mac_val.uc[4]); + FIELD_SET(EHMAC_RUL_V0, DAV_BYTE5, sw->src_mac_val.uc[5]); + FIELD_SET(EHMAC_RUL_V1, DAV_BYTE0, sw->src_mac_val.uc[0]); + FIELD_SET(EHMAC_RUL_V1, DAV_BYTE1, sw->src_mac_val.uc[1]); + + FIELD_SET_MASK(EHMAC_RUL_M0, DAM_BYTE2, sw->src_mac_mask.uc[2]); + FIELD_SET_MASK(EHMAC_RUL_M0, DAM_BYTE3, sw->src_mac_mask.uc[3]); + FIELD_SET_MASK(EHMAC_RUL_M0, DAM_BYTE4, sw->src_mac_mask.uc[4]); + FIELD_SET_MASK(EHMAC_RUL_M0, DAM_BYTE5, sw->src_mac_mask.uc[5]); + FIELD_SET_MASK(EHMAC_RUL_M1, DAM_BYTE0, sw->src_mac_mask.uc[0]); + FIELD_SET_MASK(EHMAC_RUL_M1, DAM_BYTE1, sw->src_mac_mask.uc[1]); + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_DA)) + { + if (A_TRUE != _isisc_acl_zero_addr(sw->dest_mac_mask)) + { + *b_care = A_TRUE; + } + + for (i = 0; i < 6; i++) + { + sw->dest_mac_val.uc[i] &= sw->dest_mac_mask.uc[i]; + } + + FIELD_SET(EHMAC_RUL_V2, SAV_BYTE3, sw->dest_mac_val.uc[3]); + FIELD_SET(EHMAC_RUL_V1, SAV_BYTE4, sw->dest_mac_val.uc[4]); + FIELD_SET(EHMAC_RUL_V1, SAV_BYTE5, sw->dest_mac_val.uc[5]); + + FIELD_SET_MASK(EHMAC_RUL_M2, SAM_BYTE3, sw->dest_mac_mask.uc[3]); + FIELD_SET_MASK(EHMAC_RUL_M1, SAM_BYTE4, sw->dest_mac_mask.uc[4]); + FIELD_SET_MASK(EHMAC_RUL_M1, SAM_BYTE5, sw->dest_mac_mask.uc[5]); + } + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_ETHTYPE)) + { + if (0x0 != sw->ethtype_mask) + { + *b_care = A_TRUE; + } + + sw->ethtype_val &= sw->ethtype_mask; + FIELD_SET(EHMAC_RUL_V3, ETHTYPV, sw->ethtype_val); + FIELD_SET_MASK(EHMAC_RUL_M3, ETHTYPM, sw->ethtype_mask); + } + + /* Process Stag Fields */ + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_STAGGED)) + { + if (0x0 != sw->stagged_mask) + { + *b_care = A_TRUE; + } + + sw->stagged_val &= sw->stagged_mask; + FIELD_SET(EHMAC_RUL_V3, STAGGEDV, sw->stagged_val); + FIELD_SET(EHMAC_RUL_V3, STAGGEDM, sw->stagged_mask); + } + + FIELD_SET(EHMAC_RUL_V3, SVIDMSK, 1); + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_STAG_VID)) + { + if ((FAL_ACL_FIELD_MASK != sw->stag_vid_op) + && (FAL_ACL_FIELD_RANGE != sw->stag_vid_op) + && (FAL_ACL_FIELD_LE != sw->stag_vid_op) + && (FAL_ACL_FIELD_GE != sw->stag_vid_op)) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == + _isisc_acl_field_care(sw->stag_vid_op, sw->stag_vid_val, + sw->stag_vid_mask, 0xfff)) + { + *b_care = A_TRUE; + } + + FIELD_SET(EHMAC_RUL_V3, SVIDMSK, 0); + if (FAL_ACL_FIELD_MASK == sw->stag_vid_op) + { + sw->stag_vid_val &= sw->stag_vid_mask; + FIELD_SET(EHMAC_RUL_V2, STAG_VIDV, sw->stag_vid_val); + FIELD_SET_MASK(EHMAC_RUL_M2, STAG_VIDM, sw->stag_vid_mask); + FIELD_SET(EHMAC_RUL_V3, SVIDMSK, 1); + + } + else if (FAL_ACL_FIELD_RANGE == sw->stag_vid_op) + { + FIELD_SET(EHMAC_RUL_V2, STAG_VIDV, sw->stag_vid_val); + FIELD_SET_MASK(EHMAC_RUL_M2, STAG_VIDM, sw->stag_vid_mask); + + } + else if (FAL_ACL_FIELD_LE == sw->stag_vid_op) + { + FIELD_SET(EHMAC_RUL_V2, STAG_VIDV, 0); + FIELD_SET_MASK(EHMAC_RUL_M2, STAG_VIDM, sw->stag_vid_val); + + } + else + { + FIELD_SET(EHMAC_RUL_V2, STAG_VIDV, sw->stag_vid_val); + FIELD_SET_MASK(EHMAC_RUL_M2, STAG_VIDM, 0xfff); + } + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_STAG_PRI)) + { + if (0x0 != sw->stag_pri_mask) + { + *b_care = A_TRUE; + } + + sw->stag_pri_val &= sw->stag_pri_mask; + FIELD_SET(EHMAC_RUL_V2, STAG_PRIV, sw->stag_pri_val); + FIELD_SET_MASK(EHMAC_RUL_M2, STAG_PRIM, sw->stag_pri_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_STAG_DEI)) + { + if (0x0 != sw->stag_dei_mask) + { + *b_care = A_TRUE; + } + + sw->stag_dei_val &= sw->stag_dei_mask; + FIELD_SET(EHMAC_RUL_V2, STAG_DEIV, sw->stag_dei_val); + FIELD_SET_MASK(EHMAC_RUL_M2, STAG_DEIM, sw->stag_dei_mask); + } + + /* Process Ctag Fields */ + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_CTAGGED)) + { + if (0x0 != sw->ctagged_mask) + { + *b_care = A_TRUE; + } + + sw->ctagged_val &= sw->ctagged_mask; + FIELD_SET_MASK(EHMAC_RUL_M4, CTAGGEDV, sw->ctagged_val); + FIELD_SET_MASK(EHMAC_RUL_M4, CTAGGEDM, sw->ctagged_mask); + } + + FIELD_SET_MASK(EHMAC_RUL_M4, CVIDMSK, 1); + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_CTAG_VID)) + { + if ((FAL_ACL_FIELD_MASK != sw->ctag_vid_op) + && (FAL_ACL_FIELD_RANGE != sw->ctag_vid_op) + && (FAL_ACL_FIELD_LE != sw->ctag_vid_op) + && (FAL_ACL_FIELD_GE != sw->ctag_vid_op)) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == + _isisc_acl_field_care(sw->ctag_vid_op, sw->ctag_vid_val, + sw->ctag_vid_mask, 0xfff)) + { + *b_care = A_TRUE; + } + + FIELD_SET_MASK(EHMAC_RUL_M4, CVIDMSK, 0); + if (FAL_ACL_FIELD_MASK == sw->ctag_vid_op) + { + sw->ctag_vid_val &= sw->ctag_vid_mask; + FIELD_SET(EHMAC_RUL_V2, CTAG_VIDLV, sw->ctag_vid_val); + FIELD_SET(EHMAC_RUL_V3, CTAG_VIDHV, (sw->ctag_vid_val >> 8)); + FIELD_SET_MASK(EHMAC_RUL_M2, CTAG_VIDLM, sw->ctag_vid_mask); + FIELD_SET_MASK(EHMAC_RUL_M3, CTAG_VIDHM, (sw->ctag_vid_mask >> 8)); + FIELD_SET_MASK(EHMAC_RUL_M4, CVIDMSK, 1); + + } + else if (FAL_ACL_FIELD_RANGE == sw->ctag_vid_op) + { + FIELD_SET(EHMAC_RUL_V2, CTAG_VIDLV, sw->ctag_vid_val); + FIELD_SET(EHMAC_RUL_V3, CTAG_VIDHV, (sw->ctag_vid_val >> 8)); + FIELD_SET_MASK(EHMAC_RUL_M2, CTAG_VIDLM, sw->ctag_vid_mask); + FIELD_SET_MASK(EHMAC_RUL_M3, CTAG_VIDHM, (sw->ctag_vid_mask >> 8)); + + } + else if (FAL_ACL_FIELD_LE == sw->ctag_vid_op) + { + FIELD_SET(EHMAC_RUL_V2, CTAG_VIDLV, 0); + FIELD_SET(EHMAC_RUL_V3, CTAG_VIDHV, 0); + FIELD_SET_MASK(EHMAC_RUL_M2, CTAG_VIDLM, sw->ctag_vid_val); + FIELD_SET_MASK(EHMAC_RUL_M3, CTAG_VIDHM, (sw->ctag_vid_val >> 8)); + + } + else + { + FIELD_SET(EHMAC_RUL_V2, CTAG_VIDLV, sw->ctag_vid_val); + FIELD_SET(EHMAC_RUL_V3, CTAG_VIDHV, (sw->ctag_vid_val >> 8)); + FIELD_SET_MASK(EHMAC_RUL_M2, CTAG_VIDLM, 0xff); + FIELD_SET_MASK(EHMAC_RUL_M3, CTAG_VIDHM, 0xf); + } + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_CTAG_PRI)) + { + if (0x0 != sw->ctag_pri_mask) + { + *b_care = A_TRUE; + } + + sw->ctag_pri_val &= sw->ctag_pri_mask; + FIELD_SET(EHMAC_RUL_V3, CTAG_PRIV, sw->ctag_pri_val); + FIELD_SET_MASK(EHMAC_RUL_M3, CTAG_PRIM, sw->ctag_pri_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_CTAG_CFI)) + { + if (0x0 != sw->ctag_cfi_mask) + { + *b_care = A_TRUE; + } + + sw->ctag_cfi_val &= sw->ctag_cfi_mask; + FIELD_SET(EHMAC_RUL_V3, CTAG_CFIV, sw->ctag_cfi_val); + FIELD_SET_MASK(EHMAC_RUL_M3, CTAG_CFIM, sw->ctag_cfi_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL)) + { + FIELD_SET(MAC_RUL_V4, RULE_INV, 1); + } + + return SW_OK; +} + +static void +_isisc_acl_rule_mac_preparse(fal_acl_rule_t * sw, a_bool_t * b_mac, + a_bool_t * eh_mac) +{ + a_uint32_t bm = 0, i, tmp; + + *b_mac = A_FALSE; + *eh_mac = A_FALSE; + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_DA)) + { + for (i = 0; i < 3; i++) + { + if (sw->dest_mac_mask.uc[i]) + { + bm |= DAH; + break; + } + } + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_SA)) + { + for (i = 0; i < 3; i++) + { + if (sw->src_mac_mask.uc[i]) + { + bm |= SAH; + break; + } + } + } + + tmp = 0; + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_TAGGED)) + { + tmp |= ((sw->tagged_mask & 0x1) << 16); + } + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_UP)) + { + tmp |= ((sw->up_mask & 0x7) << 13); + } + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_CFI)) + { + tmp |= ((sw->cfi_mask & 0x1) << 12); + } + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_VID)) + { + if (A_TRUE == + _isisc_acl_field_care(sw->vid_op, sw->vid_val, sw->vid_mask, + 0xfff)) + { + tmp |= 0xfff; + } + } + if (tmp) + { + bm |= TAG; + } + + tmp = 0; + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_STAGGED)) + { + tmp |= ((sw->stagged_mask & 0x1) << 16); + } + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_STAG_PRI)) + { + tmp |= ((sw->stag_pri_mask & 0x7) << 13); + } + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_STAG_DEI)) + { + tmp |= ((sw->stag_dei_mask & 0x1) << 12); + } + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_STAG_VID)) + { + if (A_TRUE == + _isisc_acl_field_care(sw->stag_vid_op, sw->stag_vid_val, + sw->stag_vid_mask, 0xfff)) + { + tmp |= 0xfff; + } + } + if (tmp) + { + bm |= STAG; + } + + tmp = 0; + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_CTAGGED)) + { + tmp |= ((sw->ctagged_mask & 0x1) << 16); + } + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_CTAG_PRI)) + { + tmp |= ((sw->ctag_pri_mask & 0x7) << 13); + } + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_CTAG_CFI)) + { + tmp |= ((sw->ctag_cfi_mask & 0x1) << 12); + } + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_CTAG_VID)) + { + if (A_TRUE == + _isisc_acl_field_care(sw->ctag_vid_op, sw->ctag_vid_val, + sw->ctag_vid_mask, 0xfff)) + { + tmp |= 0xfff; + } + } + if (tmp) + { + bm |= CTAG; + } + + if ((bm & CTAG) || (bm & STAG)) + { + *eh_mac = A_TRUE; + } + + if ((bm & TAG) || ((bm & DAH) && (bm & SAH))) + { + *b_mac = A_TRUE; + } +} + +static sw_error_t +_isisc_acl_rule_ip4_parse(fal_acl_rule_t * sw, + hw_filter_t * hw, a_bool_t * b_care) +{ + *b_care = A_FALSE; + aos_mem_zero(&(hw->vlu[0]), sizeof (hw->vlu)); + aos_mem_zero(&(hw->msk[0]), sizeof (hw->msk)); + + FIELD_SET_MASK(MAC_RUL_M4, RULE_TYP, ISISC_IP4_FILTER); + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP_DSCP)) + { + if (0x0 != sw->ip_dscp_mask) + { + *b_care = A_TRUE; + } + + sw->ip_dscp_val &= sw->ip_dscp_mask; + FIELD_SET(IP4_RUL_V2, IP4DSCPV, sw->ip_dscp_val); + FIELD_SET_MASK(IP4_RUL_M2, IP4DSCPM, sw->ip_dscp_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP_PROTO)) + { + if (0x0 != sw->ip_proto_mask) + { + *b_care = A_TRUE; + } + + sw->ip_proto_val &= sw->ip_proto_mask; + FIELD_SET(IP4_RUL_V2, IP4PROTV, sw->ip_proto_val); + FIELD_SET_MASK(IP4_RUL_M2, IP4PROTM, sw->ip_proto_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP4_SIP)) + { + if (0x0 != sw->src_ip4_mask) + { + *b_care = A_TRUE; + } + sw->src_ip4_val &= sw->src_ip4_mask; + hw->vlu[1] = sw->src_ip4_val; + hw->msk[1] = sw->src_ip4_mask; + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP4_DIP)) + { + if (0x0 != sw->dest_ip4_mask) + { + *b_care = A_TRUE; + } + sw->dest_ip4_val &= sw->dest_ip4_mask; + hw->vlu[0] = sw->dest_ip4_val; + hw->msk[0] = sw->dest_ip4_mask; + } + + if ((FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_L4_SPORT)) + && ((FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_ICMP_TYPE)) + || (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_ICMP_CODE)))) + { + return SW_BAD_PARAM; + } + + FIELD_SET_MASK(IP4_RUL_M3, IP4SPORTM_EN, 1); + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_L4_SPORT)) + { + if ((FAL_ACL_FIELD_MASK != sw->src_l4port_op) + && (FAL_ACL_FIELD_RANGE != sw->src_l4port_op) + && (FAL_ACL_FIELD_LE != sw->src_l4port_op) + && (FAL_ACL_FIELD_GE != sw->src_l4port_op)) + { + return SW_NOT_SUPPORTED; + } + + if (A_FALSE == + _isisc_acl_field_care(sw->src_l4port_op, sw->src_l4port_val, + sw->src_l4port_mask, 0xffff)) + { + if (FAL_ACL_FIELD_MASK == sw->src_l4port_op) + { + sw->src_l4port_op = FAL_ACL_FIELD_RANGE; + sw->src_l4port_val = 0; + sw->src_l4port_mask = 0xffff; + } + } + *b_care = A_TRUE; + + FIELD_SET_MASK(IP4_RUL_M3, IP4SPORTM_EN, 0); + if (FAL_ACL_FIELD_MASK == sw->src_l4port_op) + { + sw->src_l4port_val &= sw->src_l4port_mask; + FIELD_SET(IP4_RUL_V3, IP4SPORTV, sw->src_l4port_val); + FIELD_SET_MASK(IP4_RUL_M3, IP4SPORTM, sw->src_l4port_mask); + FIELD_SET_MASK(IP4_RUL_M3, IP4SPORTM_EN, 1); + } + else if (FAL_ACL_FIELD_RANGE == sw->src_l4port_op) + { + FIELD_SET(IP4_RUL_V3, IP4SPORTV, sw->src_l4port_val); + FIELD_SET_MASK(IP4_RUL_M3, IP4SPORTM, sw->src_l4port_mask); + } + else if (FAL_ACL_FIELD_LE == sw->src_l4port_op) + { + FIELD_SET(IP4_RUL_V3, IP4SPORTV, 0); + FIELD_SET_MASK(IP4_RUL_M3, IP4SPORTM, sw->src_l4port_val); + } + else + { + FIELD_SET(IP4_RUL_V3, IP4SPORTV, sw->src_l4port_val); + FIELD_SET_MASK(IP4_RUL_M3, IP4SPORTM, 0xffff); + } + } + + FIELD_SET_MASK(IP4_RUL_M3, IP4DPORTM_EN, 1); + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_L4_DPORT)) + { + if ((FAL_ACL_FIELD_MASK != sw->dest_l4port_op) + && (FAL_ACL_FIELD_RANGE != sw->dest_l4port_op) + && (FAL_ACL_FIELD_LE != sw->dest_l4port_op) + && (FAL_ACL_FIELD_GE != sw->dest_l4port_op)) + { + return SW_NOT_SUPPORTED; + } + + if (A_FALSE == + _isisc_acl_field_care(sw->dest_l4port_op, sw->dest_l4port_val, + sw->dest_l4port_mask, 0xffff)) + { + if (FAL_ACL_FIELD_MASK == sw->dest_l4port_op) + { + sw->dest_l4port_op = FAL_ACL_FIELD_RANGE; + sw->dest_l4port_val = 0; + sw->dest_l4port_mask = 0xffff; + } + } + *b_care = A_TRUE; + + FIELD_SET_MASK(IP4_RUL_M3, IP4DPORTM_EN, 0); + if (FAL_ACL_FIELD_MASK == sw->dest_l4port_op) + { + sw->dest_l4port_val &= sw->dest_l4port_mask; + FIELD_SET(IP4_RUL_V2, IP4DPORTV, sw->dest_l4port_val); + FIELD_SET_MASK(IP4_RUL_M2, IP4DPORTM, sw->dest_l4port_mask); + FIELD_SET_MASK(IP4_RUL_M3, IP4DPORTM_EN, 1); + } + else if (FAL_ACL_FIELD_RANGE == sw->dest_l4port_op) + { + FIELD_SET(IP4_RUL_V2, IP4DPORTV, sw->dest_l4port_val); + FIELD_SET_MASK(IP4_RUL_M2, IP4DPORTM, sw->dest_l4port_mask); + } + else if (FAL_ACL_FIELD_LE == sw->dest_l4port_op) + { + FIELD_SET(IP4_RUL_V2, IP4DPORTV, 0); + FIELD_SET_MASK(IP4_RUL_M2, IP4DPORTM, sw->dest_l4port_val); + } + else + { + FIELD_SET(IP4_RUL_V2, IP4DPORTV, sw->dest_l4port_val); + FIELD_SET_MASK(IP4_RUL_M2, IP4DPORTM, 0xffff); + } + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_ICMP_TYPE)) + { + if (0x0 != sw->icmp_type_mask) + { + *b_care = A_TRUE; + } + FIELD_SET(IP4_RUL_V3, ICMP_EN, 1); + + sw->icmp_type_val &= sw->icmp_type_mask; + FIELD_SET(IP4_RUL_V3, IP4ICMPTYPV, sw->icmp_type_val); + FIELD_SET_MASK(IP4_RUL_M3, IP4ICMPTYPM, sw->icmp_type_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_ICMP_CODE)) + { + if (0x0 != sw->icmp_code_mask) + { + *b_care = A_TRUE; + } + FIELD_SET(IP4_RUL_V3, ICMP_EN, 1); + + sw->icmp_code_val &= sw->icmp_code_mask; + FIELD_SET(IP4_RUL_V3, IP4ICMPCODEV, sw->icmp_code_val); + FIELD_SET_MASK(IP4_RUL_M3, IP4ICMPCODEM, sw->icmp_code_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_TCP_FLAG)) + { + if (0x0 != sw->tcp_flag_mask) + { + *b_care = A_TRUE; + } + + sw->tcp_flag_val &= sw->tcp_flag_mask; + FIELD_SET(IP4_RUL_V3, IP4TCPFLAGV, sw->tcp_flag_val); + FIELD_SET_MASK(IP4_RUL_M3, IP4TCPFLAGM, sw->tcp_flag_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_RIPV1)) + { + if (0x0 != sw->ripv1_mask) + { + *b_care = A_TRUE; + } + + sw->ripv1_val &= sw->ripv1_mask; + FIELD_SET(IP4_RUL_V3, IP4RIPV, sw->ripv1_val); + FIELD_SET_MASK(IP4_RUL_M3, IP4RIPM, sw->ripv1_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_DHCPV4)) + { + if (0x0 != sw->dhcpv4_mask) + { + *b_care = A_TRUE; + } + + sw->dhcpv4_val &= sw->dhcpv4_mask; + FIELD_SET(IP4_RUL_V3, IP4DHCPV, sw->dhcpv4_val); + FIELD_SET_MASK(IP4_RUL_M3, IP4DHCPM, sw->dhcpv4_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL)) + { + FIELD_SET(MAC_RUL_V4, RULE_INV, 1); + } + + return SW_OK; +} + +static sw_error_t +_isisc_acl_rule_ip6r1_parse(fal_acl_rule_t * sw, + hw_filter_t * hw, a_bool_t * b_care) +{ + a_uint32_t i; + + *b_care = A_FALSE; + aos_mem_zero(&(hw->vlu[0]), sizeof (hw->vlu)); + aos_mem_zero(&(hw->msk[0]), sizeof (hw->msk)); + + FIELD_SET_MASK(MAC_RUL_M4, RULE_TYP, ISISC_IP6R1_FILTER); + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP6_DIP)) + { + for (i = 0; i < 4; i++) + { + if (0x0 != sw->dest_ip6_mask.ul[i]) + { + *b_care = A_TRUE; + } + + sw->dest_ip6_val.ul[3 - i] &= sw->dest_ip6_mask.ul[3 - i]; + hw->vlu[i] = sw->dest_ip6_val.ul[3 - i]; + hw->msk[i] = sw->dest_ip6_mask.ul[3 - i]; + } + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL)) + { + FIELD_SET(MAC_RUL_V4, RULE_INV, 1); + } + + return SW_OK; +} + +static sw_error_t +_isisc_acl_rule_ip6r2_parse(fal_acl_rule_t * sw, + hw_filter_t * hw, a_bool_t * b_care) +{ + a_uint32_t i; + + *b_care = A_FALSE; + aos_mem_zero(&(hw->vlu[0]), sizeof (hw->vlu)); + aos_mem_zero(&(hw->msk[0]), sizeof (hw->msk)); + + FIELD_SET_MASK(MAC_RUL_M4, RULE_TYP, ISISC_IP6R2_FILTER); + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP6_SIP)) + { + for (i = 0; i < 4; i++) + { + if (0x0 != sw->src_ip6_mask.ul[i]) + { + *b_care = A_TRUE; + } + + sw->src_ip6_val.ul[3 - i] &= sw->src_ip6_mask.ul[3 - i]; + hw->vlu[i] = sw->src_ip6_val.ul[3 - i]; + hw->msk[i] = sw->src_ip6_mask.ul[3 - i]; + } + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL)) + { + FIELD_SET(MAC_RUL_V4, RULE_INV, 1); + } + + return SW_OK; +} + +static sw_error_t +_isisc_acl_rule_ip6r3_parse(fal_acl_rule_t * sw, + hw_filter_t * hw, a_bool_t * b_care) +{ + *b_care = A_FALSE; + aos_mem_zero(&(hw->vlu[0]), sizeof (hw->vlu)); + aos_mem_zero(&(hw->msk[0]), sizeof (hw->msk)); + + FIELD_SET_MASK(MAC_RUL_M4, RULE_TYP, ISISC_IP6R3_FILTER); + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP6_LABEL)) + { + if (0x0 != sw->ip6_lable_mask) + { + *b_care = A_TRUE; + } + + sw->ip6_lable_val &= sw->ip6_lable_mask; + FIELD_SET(IP6_RUL3_V1, IP6LABEL1V, sw->ip6_lable_val); + FIELD_SET_MASK(IP6_RUL3_M1, IP6LABEL1M, sw->ip6_lable_mask); + + FIELD_SET(IP6_RUL3_V2, IP6LABEL2V, (sw->ip6_lable_val >> 16)); + FIELD_SET_MASK(IP6_RUL3_M2, IP6LABEL2M, (sw->ip6_lable_mask >> 16)); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP_PROTO)) + { + if (0x0 != sw->ip_proto_mask) + { + *b_care = A_TRUE; + } + + sw->ip_proto_val &= sw->ip_proto_mask; + FIELD_SET(IP6_RUL3_V0, IP6PROTV, sw->ip_proto_val); + FIELD_SET_MASK(IP6_RUL3_M0, IP6PROTM, sw->ip_proto_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP_DSCP)) + { + if (0x0 != sw->ip_dscp_mask) + { + *b_care = A_TRUE; + } + + sw->ip_dscp_val &= sw->ip_dscp_mask; + FIELD_SET(IP6_RUL3_V0, IP6DSCPV, sw->ip_dscp_val); + FIELD_SET_MASK(IP6_RUL3_M0, IP6DSCPM, sw->ip_dscp_mask); + } + + if ((FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_L4_SPORT)) + && ((FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_ICMP_TYPE)) + || (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_ICMP_CODE)))) + { + return SW_BAD_PARAM; + } + + FIELD_SET_MASK(IP6_RUL3_M3, IP6SPORTM_EN, 1); + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_L4_SPORT)) + { + if ((FAL_ACL_FIELD_MASK != sw->src_l4port_op) + && (FAL_ACL_FIELD_RANGE != sw->src_l4port_op) + && (FAL_ACL_FIELD_LE != sw->src_l4port_op) + && (FAL_ACL_FIELD_GE != sw->src_l4port_op)) + { + return SW_NOT_SUPPORTED; + } + + if (A_FALSE == + _isisc_acl_field_care(sw->src_l4port_op, sw->src_l4port_val, + sw->src_l4port_mask, 0xffff)) + { + if (FAL_ACL_FIELD_MASK == sw->src_l4port_op) + { + sw->src_l4port_op = FAL_ACL_FIELD_RANGE; + sw->src_l4port_val = 0; + sw->src_l4port_mask = 0xffff; + } + } + *b_care = A_TRUE; + + FIELD_SET_MASK(IP6_RUL3_M3, IP6SPORTM_EN, 0); + if (FAL_ACL_FIELD_MASK == sw->src_l4port_op) + { + sw->src_l4port_val &= sw->src_l4port_mask; + FIELD_SET(IP6_RUL3_V3, IP6SPORTV, sw->src_l4port_val); + FIELD_SET_MASK(IP6_RUL3_M3, IP6SPORTM, sw->src_l4port_mask); + FIELD_SET_MASK(IP6_RUL3_M3, IP6SPORTM_EN, 1); + + } + else if (FAL_ACL_FIELD_RANGE == sw->src_l4port_op) + { + FIELD_SET(IP6_RUL3_V3, IP6SPORTV, sw->src_l4port_val); + FIELD_SET_MASK(IP6_RUL3_M3, IP6SPORTM, sw->src_l4port_mask); + + } + else if (FAL_ACL_FIELD_LE == sw->src_l4port_op) + { + FIELD_SET(IP6_RUL3_V3, IP6SPORTV, 0); + FIELD_SET_MASK(IP6_RUL3_M3, IP6SPORTM, sw->src_l4port_val); + + } + else + { + FIELD_SET(IP6_RUL3_V3, IP6SPORTV, sw->src_l4port_val); + FIELD_SET_MASK(IP6_RUL3_M3, IP6SPORTM, 0xffff); + } + } + + FIELD_SET_MASK(IP6_RUL3_M3, IP6DPORTM_EN, 1); + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_L4_DPORT)) + { + if ((FAL_ACL_FIELD_MASK != sw->dest_l4port_op) + && (FAL_ACL_FIELD_RANGE != sw->dest_l4port_op) + && (FAL_ACL_FIELD_LE != sw->dest_l4port_op) + && (FAL_ACL_FIELD_GE != sw->dest_l4port_op)) + { + return SW_NOT_SUPPORTED; + } + + if (A_FALSE == + _isisc_acl_field_care(sw->dest_l4port_op, sw->dest_l4port_val, + sw->dest_l4port_mask, 0xffff)) + { + if (FAL_ACL_FIELD_MASK == sw->dest_l4port_op) + { + sw->dest_l4port_op = FAL_ACL_FIELD_RANGE; + sw->dest_l4port_val = 0; + sw->dest_l4port_mask = 0xffff; + } + } + *b_care = A_TRUE; + + FIELD_SET_MASK(IP6_RUL3_M3, IP6DPORTM_EN, 0); + if (FAL_ACL_FIELD_MASK == sw->dest_l4port_op) + { + sw->dest_l4port_val &= sw->dest_l4port_mask; + FIELD_SET(IP6_RUL3_V2, IP6DPORTV, sw->dest_l4port_val); + FIELD_SET_MASK(IP6_RUL3_M2, IP6DPORTM, sw->dest_l4port_mask); + FIELD_SET_MASK(IP6_RUL3_M3, IP6DPORTM_EN, 1); + } + else if (FAL_ACL_FIELD_RANGE == sw->dest_l4port_op) + { + FIELD_SET(IP6_RUL3_V2, IP6DPORTV, sw->dest_l4port_val); + FIELD_SET_MASK(IP6_RUL3_M2, IP6DPORTM, sw->dest_l4port_mask); + } + else if (FAL_ACL_FIELD_LE == sw->dest_l4port_op) + { + FIELD_SET(IP6_RUL3_V2, IP6DPORTV, 0); + FIELD_SET_MASK(IP6_RUL3_M2, IP6DPORTM, sw->dest_l4port_val); + } + else + { + FIELD_SET(IP6_RUL3_V2, IP6DPORTV, sw->dest_l4port_val); + FIELD_SET_MASK(IP6_RUL3_M2, IP6DPORTM, 0xffff); + } + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_ICMP_TYPE)) + { + if (0x0 != sw->icmp_type_mask) + { + *b_care = A_TRUE; + } + FIELD_SET(IP6_RUL3_V3, ICMP6_EN, 1); + + sw->icmp_type_val &= sw->icmp_type_mask; + FIELD_SET(IP6_RUL3_V3, IP6ICMPTYPV, sw->icmp_type_val); + FIELD_SET_MASK(IP6_RUL3_M3, IP6ICMPTYPM, sw->icmp_type_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_ICMP_CODE)) + { + if (0x0 != sw->icmp_code_mask) + { + *b_care = A_TRUE; + } + FIELD_SET(IP6_RUL3_V3, ICMP6_EN, 1); + + sw->icmp_code_val &= sw->icmp_code_mask; + FIELD_SET(IP6_RUL3_V3, IP6ICMPCODEV, sw->icmp_code_val); + FIELD_SET_MASK(IP6_RUL3_M3, IP6ICMPCODEM, sw->icmp_code_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_TCP_FLAG)) + { + if (0x0 != sw->tcp_flag_mask) + { + *b_care = A_TRUE; + } + + sw->tcp_flag_val &= sw->tcp_flag_mask; + FIELD_SET(IP6_RUL3_V3, IP6TCPFLAGV, sw->tcp_flag_val); + FIELD_SET_MASK(IP6_RUL3_M3, IP6TCPFLAGM, sw->tcp_flag_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_DHCPV6)) + { + if (0x0 != sw->dhcpv6_mask) + { + *b_care = A_TRUE; + } + + sw->dhcpv6_val &= sw->dhcpv6_mask; + FIELD_SET(IP6_RUL3_V3, IP6DHCPV, sw->dhcpv6_val); + FIELD_SET_MASK(IP6_RUL3_M3, IP6DHCPM, sw->dhcpv6_mask); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL)) + { + FIELD_SET(MAC_RUL_V4, RULE_INV, 1); + } + + return SW_OK; +} + +static sw_error_t +_isisc_acl_rule_udf_parse(fal_acl_rule_t * sw, + hw_filter_t * hw, a_bool_t * b_care) +{ + a_uint32_t i; + + *b_care = A_FALSE; + aos_mem_zero(&(hw->vlu[0]), sizeof (hw->vlu)); + aos_mem_zero(&(hw->msk[0]), sizeof (hw->msk)); + + FIELD_SET_MASK(MAC_RUL_M4, RULE_TYP, ISISC_UDF_FILTER); + + if (!FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_UDF)) + { + if (FAL_ACL_RULE_UDF == sw->rule_type) + { + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL)) + { + FIELD_SET(MAC_RUL_V4, RULE_INV, 1); + } + *b_care = A_TRUE; + } + return SW_OK; + } + + if (ISISC_MAX_UDF_LENGTH < sw->udf_len) + { + return SW_NOT_SUPPORTED; + } + + *b_care = A_TRUE; + for (i = 0; i < sw->udf_len; i++) + { + hw->vlu[3 - i / 4] |= + ((sw->udf_mask[i] & sw->udf_val[i]) << (24 - 8 * (i % 4))); + hw->msk[3 - i / 4] |= ((sw->udf_mask[i]) << (24 - 8 * (i % 4))); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL)) + { + FIELD_SET(MAC_RUL_V4, RULE_INV, 1); + } + + return SW_OK; +} + +static sw_error_t +_isisc_acl_action_parse(a_uint32_t dev_id, const fal_acl_rule_t * sw, + hw_filter_t * hw) +{ + fal_pbmp_t des_pts; + + aos_mem_zero(&(hw->act[0]), sizeof (hw->act)); + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_MATCH_TRIGGER_INTR)) + { + FIELD_SET_ACTION(ACL_RSLT2, TRIGGER_INTR, 1); + } + + /* FAL_ACL_ACTION_PERMIT need't process */ + + if ((FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_RDTCPU)) + && (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_CPYCPU))) + { + return SW_BAD_PARAM; + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_RDTCPU)) + { + FIELD_SET_ACTION(ACL_RSLT2, FWD_CMD, 0x3); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_CPYCPU)) + { + FIELD_SET_ACTION(ACL_RSLT2, FWD_CMD, 0x1); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_DENY)) + { + FIELD_SET_ACTION(ACL_RSLT2, FWD_CMD, 0x7); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_MIRROR)) + { + FIELD_SET_ACTION(ACL_RSLT2, MIRR_EN, 1); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REDPT)) + { + FIELD_SET_ACTION(ACL_RSLT2, DES_PORT_EN, 1); + + des_pts = (sw->ports >> 3) & 0xf; + FIELD_SET_ACTION(ACL_RSLT2, DES_PORT1, des_pts); + + des_pts = sw->ports & 0x7; + FIELD_SET_ACTION(ACL_RSLT1, DES_PORT0, des_pts); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REMARK_UP)) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REMARK_QUEUE)) + { + FIELD_SET_ACTION(ACL_RSLT1, PRI_QU_EN, 1); + FIELD_SET_ACTION(ACL_RSLT1, PRI_QU, sw->queue); + } + + if ((FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_MODIFY_VLAN)) + || (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_NEST_VLAN))) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REMARK_DSCP)) + { + FIELD_SET_ACTION(ACL_RSLT1, DSCPV, sw->dscp); + FIELD_SET_ACTION(ACL_RSLT1, DSCP_REMAP, 1); + } + + FIELD_SET_ACTION(ACL_RSLT0, STAGVID, sw->stag_vid); + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REMARK_STAG_VID)) + { + FIELD_SET_ACTION(ACL_RSLT1, TRANS_SVID_CHG, 1); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REMARK_STAG_PRI)) + { + FIELD_SET_ACTION(ACL_RSLT0, STAGPRI, sw->stag_pri); + FIELD_SET_ACTION(ACL_RSLT1, STAG_PRI_REMAP, 1); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REMARK_STAG_DEI)) + { + FIELD_SET_ACTION(ACL_RSLT0, STAGDEI, sw->stag_dei); + FIELD_SET_ACTION(ACL_RSLT1, STAG_DEI_CHG, 1); + } + + FIELD_SET_ACTION(ACL_RSLT0, CTAGVID, sw->ctag_vid); + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REMARK_CTAG_VID)) + { + FIELD_SET_ACTION(ACL_RSLT1, TRANS_CVID_CHG, 1); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REMARK_CTAG_PRI)) + { + FIELD_SET_ACTION(ACL_RSLT0, CTAGPRI, sw->ctag_pri); + FIELD_SET_ACTION(ACL_RSLT1, CTAG_PRI_REMAP, 1); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REMARK_CTAG_CFI)) + { + FIELD_SET_ACTION(ACL_RSLT0, CTAGCFI, sw->ctag_cfi); + FIELD_SET_ACTION(ACL_RSLT1, CTAG_CFI_CHG, 1); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REMARK_LOOKUP_VID)) + { + FIELD_SET_ACTION(ACL_RSLT1, LOOK_VID_CHG, 1); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_POLICER_EN)) + { + FIELD_SET_ACTION(ACL_RSLT2, POLICER_PTR, sw->policer_ptr); + FIELD_SET_ACTION(ACL_RSLT2, POLICER_EN, 1); + } + + if ((FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_ARP_EN)) + && (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_WCMP_EN))) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_ARP_EN)) + { + FIELD_SET_ACTION(ACL_RSLT1, ARP_PTR, sw->arp_ptr); + FIELD_SET_ACTION(ACL_RSLT1, ARP_PTR_EN, 1); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_WCMP_EN)) + { + FIELD_SET_ACTION(ACL_RSLT1, ARP_PTR, sw->wcmp_ptr); + FIELD_SET_ACTION(ACL_RSLT1, WCMP_EN, 1); + FIELD_SET_ACTION(ACL_RSLT1, ARP_PTR_EN, 1); + } + + FIELD_SET_ACTION(ACL_RSLT1, FORCE_L3_MODE, 0x0); + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_POLICY_FORWARD_EN)) + { + if (FAL_ACL_POLICY_ROUTE == sw->policy_fwd) + { + return SW_NOT_SUPPORTED; + } + else if (FAL_ACL_POLICY_SNAT == sw->policy_fwd) + { + FIELD_SET_ACTION(ACL_RSLT1, FORCE_L3_MODE, 0x1); + } + else if (FAL_ACL_POLICY_DNAT == sw->policy_fwd) + { + FIELD_SET_ACTION(ACL_RSLT1, FORCE_L3_MODE, 0x2); + } + else if (FAL_ACL_POLICY_RESERVE == sw->policy_fwd) + { + FIELD_SET_ACTION(ACL_RSLT1, FORCE_L3_MODE, 0x3); + } + else + { + return SW_BAD_PARAM; + } + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_BYPASS_EGRESS_TRANS)) + { + FIELD_SET_ACTION(ACL_RSLT2, EG_BYPASS, 1); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_MATCH_TRIGGER_INTR)) + { + FIELD_SET_ACTION(ACL_RSLT2, TRIGGER_INTR, 1); + } + + return SW_OK; +} + +static sw_error_t +_isisc_acl_rule_bmac_reparse(fal_acl_rule_t * sw, const hw_filter_t * hw) +{ + a_uint32_t mask_en; + + /* destnation mac address */ + FIELD_GET(MAC_RUL_V0, DAV_BYTE2, sw->dest_mac_val.uc[2]); + FIELD_GET(MAC_RUL_V0, DAV_BYTE3, sw->dest_mac_val.uc[3]); + FIELD_GET(MAC_RUL_V0, DAV_BYTE4, sw->dest_mac_val.uc[4]); + FIELD_GET(MAC_RUL_V0, DAV_BYTE5, sw->dest_mac_val.uc[5]); + FIELD_GET(MAC_RUL_V1, DAV_BYTE0, sw->dest_mac_val.uc[0]); + FIELD_GET(MAC_RUL_V1, DAV_BYTE1, sw->dest_mac_val.uc[1]); + + FIELD_GET_MASK(MAC_RUL_M0, DAM_BYTE2, sw->dest_mac_mask.uc[2]); + FIELD_GET_MASK(MAC_RUL_M0, DAM_BYTE3, sw->dest_mac_mask.uc[3]); + FIELD_GET_MASK(MAC_RUL_M0, DAM_BYTE4, sw->dest_mac_mask.uc[4]); + FIELD_GET_MASK(MAC_RUL_M0, DAM_BYTE5, sw->dest_mac_mask.uc[5]); + FIELD_GET_MASK(MAC_RUL_M1, DAM_BYTE0, sw->dest_mac_mask.uc[0]); + FIELD_GET_MASK(MAC_RUL_M1, DAM_BYTE1, sw->dest_mac_mask.uc[1]); + if (A_FALSE == _isisc_acl_zero_addr(sw->dest_mac_mask)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_DA); + } + + /* source mac address */ + FIELD_GET(MAC_RUL_V2, SAV_BYTE0, sw->src_mac_val.uc[0]); + FIELD_GET(MAC_RUL_V2, SAV_BYTE1, sw->src_mac_val.uc[1]); + FIELD_GET(MAC_RUL_V2, SAV_BYTE2, sw->src_mac_val.uc[2]); + FIELD_GET(MAC_RUL_V2, SAV_BYTE3, sw->src_mac_val.uc[3]); + FIELD_GET(MAC_RUL_V1, SAV_BYTE4, sw->src_mac_val.uc[4]); + FIELD_GET(MAC_RUL_V1, SAV_BYTE5, sw->src_mac_val.uc[5]); + + FIELD_GET_MASK(MAC_RUL_M2, SAM_BYTE0, sw->src_mac_mask.uc[0]); + FIELD_GET_MASK(MAC_RUL_M2, SAM_BYTE1, sw->src_mac_mask.uc[1]); + FIELD_GET_MASK(MAC_RUL_M2, SAM_BYTE2, sw->src_mac_mask.uc[2]); + FIELD_GET_MASK(MAC_RUL_M2, SAM_BYTE3, sw->src_mac_mask.uc[3]); + FIELD_GET_MASK(MAC_RUL_M1, SAM_BYTE4, sw->src_mac_mask.uc[4]); + FIELD_GET_MASK(MAC_RUL_M1, SAM_BYTE5, sw->src_mac_mask.uc[5]); + if (A_FALSE == _isisc_acl_zero_addr(sw->src_mac_mask)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_SA); + } + + /* ethernet type */ + FIELD_GET(MAC_RUL_V3, ETHTYPV, sw->ethtype_val); + FIELD_GET_MASK(MAC_RUL_M3, ETHTYPM, sw->ethtype_mask); + if (0x0 != sw->ethtype_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_ETHTYPE); + } + + /* packet tagged */ + FIELD_GET_MASK(MAC_RUL_M4, TAGGEDV, sw->tagged_val); + FIELD_GET_MASK(MAC_RUL_M4, TAGGEDM, sw->tagged_mask); + if (0x0 != sw->tagged_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_TAGGED); + } + + /* vlan priority */ + FIELD_GET(MAC_RUL_V3, VLANPRIV, sw->up_val); + FIELD_GET_MASK(MAC_RUL_M3, VLANPRIM, sw->up_mask); + if (0x0 != sw->up_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_UP); + } + + /* vlanid */ + FIELD_GET(MAC_RUL_V3, VLANIDV, sw->vid_val); + FIELD_GET_MASK(MAC_RUL_M3, VLANIDM, sw->vid_mask); + FIELD_GET_MASK(MAC_RUL_M4, VIDMSK, mask_en); + if (mask_en) + { + sw->vid_op = FAL_ACL_FIELD_MASK; + } + else + { + sw->vid_op = FAL_ACL_FIELD_RANGE; + } + + if (A_TRUE == + _isisc_acl_field_care(sw->vid_op, (a_uint32_t) sw->vid_val, + (a_uint32_t) sw->vid_mask, 0xfff)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_VID); + } + + /* vlan cfi */ + FIELD_GET(MAC_RUL_V3, VLANCFIV, sw->cfi_val); + FIELD_GET_MASK(MAC_RUL_M3, VLANCFIM, sw->cfi_mask); + if (0x0 != sw->cfi_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_CFI); + } + + FIELD_GET(MAC_RUL_V4, RULE_INV, mask_en); + if (mask_en) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL); + } + + return SW_OK; +} + +static sw_error_t +_isisc_acl_rule_ehmac_reparse(fal_acl_rule_t * sw, const hw_filter_t * hw) +{ + a_uint32_t i, mask_en, data; + + FIELD_GET(EHMAC_RUL_V3, DA_EN, data); + if (data) + { + for (i = 2; i < 6; i++) + { + sw->dest_mac_val.uc[i] = ((hw->vlu[0]) >> ((5 - i) << 3)) & 0xff; + sw->dest_mac_mask.uc[i] = ((hw->msk[0]) >> ((5 - i) << 3)) & 0xff; + } + + for (i = 0; i < 2; i++) + { + sw->dest_mac_val.uc[i] = ((hw->vlu[1]) >> ((1 - i) << 3)) & 0xff; + sw->dest_mac_mask.uc[i] = ((hw->msk[1]) >> ((1 - i) << 3)) & 0xff; + } + + if (A_FALSE == _isisc_acl_zero_addr(sw->dest_mac_mask)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_DA); + } + + FIELD_GET(EHMAC_RUL_V2, SAV_BYTE3, sw->src_mac_val.uc[3]); + FIELD_GET(EHMAC_RUL_V1, SAV_BYTE4, sw->src_mac_val.uc[4]); + FIELD_GET(EHMAC_RUL_V1, SAV_BYTE5, sw->src_mac_val.uc[5]); + + FIELD_GET_MASK(EHMAC_RUL_M2, SAM_BYTE3, sw->src_mac_mask.uc[3]); + FIELD_GET_MASK(EHMAC_RUL_M1, SAM_BYTE4, sw->src_mac_mask.uc[4]); + FIELD_GET_MASK(EHMAC_RUL_M1, SAM_BYTE5, sw->src_mac_mask.uc[5]); + + if (A_FALSE == _isisc_acl_zero_addr(sw->src_mac_mask)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_SA); + } + } + else + { + for (i = 2; i < 6; i++) + { + sw->src_mac_val.uc[i] = ((hw->vlu[0]) >> ((5 - i) << 3)) & 0xff; + sw->src_mac_mask.uc[i] = ((hw->msk[0]) >> ((5 - i) << 3)) & 0xff; + } + + for (i = 0; i < 2; i++) + { + sw->src_mac_val.uc[i] = ((hw->vlu[1]) >> ((1 - i) << 3)) & 0xff; + sw->src_mac_mask.uc[i] = ((hw->msk[1]) >> ((1 - i) << 3)) & 0xff; + } + + if (A_FALSE == _isisc_acl_zero_addr(sw->src_mac_mask)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_SA); + } + + FIELD_GET(EHMAC_RUL_V2, SAV_BYTE3, sw->dest_mac_val.uc[3]); + FIELD_GET(EHMAC_RUL_V1, SAV_BYTE4, sw->dest_mac_val.uc[4]); + FIELD_GET(EHMAC_RUL_V1, SAV_BYTE5, sw->dest_mac_val.uc[5]); + + FIELD_GET_MASK(EHMAC_RUL_M2, SAM_BYTE3, sw->dest_mac_mask.uc[3]); + FIELD_GET_MASK(EHMAC_RUL_M1, SAM_BYTE4, sw->dest_mac_mask.uc[4]); + FIELD_GET_MASK(EHMAC_RUL_M1, SAM_BYTE5, sw->dest_mac_mask.uc[5]); + if (A_FALSE == _isisc_acl_zero_addr(sw->dest_mac_mask)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_DA); + } + } + + /* ethernet type */ + FIELD_GET(EHMAC_RUL_V3, ETHTYPV, sw->ethtype_val); + FIELD_GET_MASK(EHMAC_RUL_M3, ETHTYPM, sw->ethtype_mask); + if (0x0 != sw->ethtype_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_ETHTYPE); + } + + /* packet stagged */ + FIELD_GET(EHMAC_RUL_V3, STAGGEDV, sw->stagged_val); + FIELD_GET(EHMAC_RUL_V3, STAGGEDM, sw->stagged_mask); + if (0x0 != sw->stagged_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_STAGGED); + } + + /* stag vid */ + FIELD_GET(EHMAC_RUL_V2, STAG_VIDV, sw->stag_vid_val); + FIELD_GET_MASK(EHMAC_RUL_M2, STAG_VIDM, sw->stag_vid_mask); + FIELD_GET(EHMAC_RUL_V3, SVIDMSK, mask_en); + if (mask_en) + { + sw->stag_vid_op = FAL_ACL_FIELD_MASK; + } + else + { + sw->stag_vid_op = FAL_ACL_FIELD_RANGE; + } + + if (A_TRUE == + _isisc_acl_field_care(sw->stag_vid_op, (a_uint32_t) sw->stag_vid_val, + (a_uint32_t) sw->stag_vid_mask, 0xfff)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_STAG_VID); + } + + /* stag priority */ + FIELD_GET(EHMAC_RUL_V2, STAG_PRIV, sw->stag_pri_val); + FIELD_GET_MASK(EHMAC_RUL_M2, STAG_PRIM, sw->stag_pri_mask); + if (0x0 != sw->stag_pri_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_STAG_PRI); + } + + /* stag dei */ + FIELD_GET(EHMAC_RUL_V2, STAG_DEIV, sw->stag_dei_val); + FIELD_GET_MASK(EHMAC_RUL_M2, STAG_DEIM, sw->stag_dei_mask); + if (0x0 != sw->stag_dei_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_STAG_DEI); + } + + /* packet ctagged */ + FIELD_GET_MASK(EHMAC_RUL_M4, CTAGGEDV, sw->ctagged_val); + FIELD_GET_MASK(EHMAC_RUL_M4, CTAGGEDM, sw->ctagged_mask); + if (0x0 != sw->ctagged_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_CTAGGED); + } + + /* ctag vid */ + FIELD_GET(EHMAC_RUL_V2, CTAG_VIDLV, sw->ctag_vid_val); + FIELD_GET(EHMAC_RUL_V3, CTAG_VIDHV, data); + sw->ctag_vid_val |= (data << 8); + FIELD_GET_MASK(EHMAC_RUL_M2, CTAG_VIDLM, sw->ctag_vid_mask); + FIELD_GET_MASK(EHMAC_RUL_M3, CTAG_VIDHM, data); + sw->ctag_vid_mask |= (data << 8); + + FIELD_GET_MASK(EHMAC_RUL_M4, CVIDMSK, mask_en); + if (mask_en) + { + sw->ctag_vid_op = FAL_ACL_FIELD_MASK; + } + else + { + sw->ctag_vid_op = FAL_ACL_FIELD_RANGE; + } + + if (A_TRUE == + _isisc_acl_field_care(sw->ctag_vid_op, (a_uint32_t) sw->ctag_vid_val, + (a_uint32_t) sw->ctag_vid_mask, 0xfff)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_CTAG_VID); + } + + /* ctag priority */ + FIELD_GET(EHMAC_RUL_V3, CTAG_PRIV, sw->ctag_pri_val); + FIELD_GET_MASK(EHMAC_RUL_M3, CTAG_PRIM, sw->ctag_pri_mask); + if (0x0 != sw->ctag_pri_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_CTAG_PRI); + } + + /* ctag dei */ + FIELD_GET(EHMAC_RUL_V3, CTAG_CFIV, sw->ctag_cfi_val); + FIELD_GET_MASK(EHMAC_RUL_M3, CTAG_CFIM, sw->ctag_cfi_mask); + if (0x0 != sw->ctag_cfi_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_CTAG_CFI); + } + + FIELD_GET(MAC_RUL_V4, RULE_INV, mask_en); + if (mask_en) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL); + } + + return SW_OK; +} + +static sw_error_t +_isisc_acl_rule_ip4_reparse(fal_acl_rule_t * sw, const hw_filter_t * hw) +{ + a_uint32_t mask_en, icmp_en; + + sw->dest_ip4_val = hw->vlu[0]; + sw->dest_ip4_mask = hw->msk[0]; + if (0x0 != sw->dest_ip4_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP4_DIP); + } + + sw->src_ip4_val = hw->vlu[1]; + sw->src_ip4_mask = hw->msk[1]; + if (0x0 != sw->src_ip4_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP4_SIP); + } + + FIELD_GET(IP4_RUL_V2, IP4PROTV, sw->ip_proto_val); + FIELD_GET_MASK(IP4_RUL_M2, IP4PROTM, sw->ip_proto_mask); + if (0x0 != sw->ip_proto_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP_PROTO); + } + + FIELD_GET(IP4_RUL_V2, IP4DSCPV, sw->ip_dscp_val); + FIELD_GET_MASK(IP4_RUL_M2, IP4DSCPM, sw->ip_dscp_mask); + if (0x0 != sw->ip_dscp_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP_DSCP); + } + + FIELD_GET(IP4_RUL_V2, IP4DPORTV, sw->dest_l4port_val); + FIELD_GET_MASK(IP4_RUL_M2, IP4DPORTM, sw->dest_l4port_mask); + FIELD_GET_MASK(IP4_RUL_M3, IP4DPORTM_EN, mask_en); + if (mask_en) + { + sw->dest_l4port_op = FAL_ACL_FIELD_MASK; + } + else + { + sw->dest_l4port_op = FAL_ACL_FIELD_RANGE; + } + + if (A_TRUE == + _isisc_acl_field_care(sw->dest_l4port_op, + (a_uint32_t) sw->dest_l4port_val, + (a_uint32_t) sw->dest_l4port_mask, 0xffff)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_DPORT); + } + else if (FAL_ACL_FIELD_RANGE == sw->dest_l4port_op) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_DPORT); + } + + FIELD_GET(IP4_RUL_V3, ICMP_EN, icmp_en); + if (icmp_en) + { + FIELD_GET(IP4_RUL_V3, IP4ICMPTYPV, sw->icmp_type_val); + FIELD_GET_MASK(IP4_RUL_M3, IP4ICMPTYPM, sw->icmp_type_mask); + if (0x0 != sw->icmp_type_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_ICMP_TYPE); + } + + FIELD_GET(IP4_RUL_V3, IP4ICMPCODEV, sw->icmp_code_val); + FIELD_GET_MASK(IP4_RUL_M3, IP4ICMPCODEM, sw->icmp_code_mask); + if (0x0 != sw->icmp_code_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_ICMP_CODE); + } + } + else + { + FIELD_GET(IP4_RUL_V3, IP4SPORTV, sw->src_l4port_val); + FIELD_GET_MASK(IP4_RUL_M3, IP4SPORTM, sw->src_l4port_mask); + FIELD_GET_MASK(IP4_RUL_M3, IP4SPORTM_EN, mask_en); + if (mask_en) + { + sw->src_l4port_op = FAL_ACL_FIELD_MASK; + } + else + { + sw->src_l4port_op = FAL_ACL_FIELD_RANGE; + } + + if (A_TRUE == + _isisc_acl_field_care(sw->src_l4port_op, + (a_uint32_t) sw->src_l4port_val, + (a_uint32_t) sw->src_l4port_mask, 0xffff)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_SPORT); + } + else if (FAL_ACL_FIELD_RANGE == sw->src_l4port_op) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_SPORT); + } + } + + FIELD_GET(IP4_RUL_V3, IP4TCPFLAGV, sw->tcp_flag_val); + FIELD_GET_MASK(IP4_RUL_M3, IP4TCPFLAGM, sw->tcp_flag_mask); + if (0x0 != sw->tcp_flag_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_TCP_FLAG); + } + + FIELD_GET(IP4_RUL_V3, IP4RIPV, sw->ripv1_val); + FIELD_GET_MASK(IP4_RUL_M3, IP4RIPM, sw->ripv1_mask); + if (0x0 != sw->ripv1_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_RIPV1); + } + + FIELD_GET(IP4_RUL_V3, IP4DHCPV, sw->dhcpv4_val); + FIELD_GET_MASK(IP4_RUL_M3, IP4DHCPM, sw->dhcpv4_mask); + if (0x0 != sw->dhcpv4_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_DHCPV4); + } + + FIELD_GET(MAC_RUL_V4, RULE_INV, mask_en); + if (mask_en) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL); + } + + return SW_OK; +} + +static sw_error_t +_isisc_acl_rule_ip6r1_reparse(fal_acl_rule_t * sw, const hw_filter_t * hw) +{ + a_uint32_t i; + + for (i = 0; i < 4; i++) + { + sw->dest_ip6_val.ul[i] = hw->vlu[3 - i]; + sw->dest_ip6_mask.ul[i] = hw->msk[3 - i]; + if (0x0 != sw->dest_ip6_mask.ul[i]) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP6_DIP); + } + } + + FIELD_GET(MAC_RUL_V4, RULE_INV, i); + if (i) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL); + } + + return SW_OK; +} + +static sw_error_t +_isisc_acl_rule_ip6r2_reparse(fal_acl_rule_t * sw, const hw_filter_t * hw) +{ + a_uint32_t i; + + for (i = 0; i < 4; i++) + { + sw->src_ip6_val.ul[i] = hw->vlu[3 - i]; + sw->src_ip6_mask.ul[i] = hw->msk[3 - i]; + if (0x0 != sw->src_ip6_mask.ul[i]) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP6_SIP); + } + } + + FIELD_GET(MAC_RUL_V4, RULE_INV, i); + if (i) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL); + } + + return SW_OK; +} + +static sw_error_t +_isisc_acl_rule_ip6r3_reparse(fal_acl_rule_t * sw, const hw_filter_t * hw) +{ + a_uint32_t mask_en, icmp6_en, tmp; + + FIELD_GET(IP6_RUL3_V0, IP6PROTV, sw->ip_proto_val); + FIELD_GET_MASK(IP6_RUL3_M0, IP6PROTM, sw->ip_proto_mask); + if (0x0 != sw->ip_proto_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP_PROTO); + } + + FIELD_GET(IP6_RUL3_V0, IP6DSCPV, sw->ip_dscp_val); + FIELD_GET_MASK(IP6_RUL3_M0, IP6DSCPM, sw->ip_dscp_mask); + if (0x0 != sw->ip_dscp_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP_DSCP); + } + + FIELD_GET(IP6_RUL3_V2, IP6DPORTV, sw->dest_l4port_val); + FIELD_GET_MASK(IP6_RUL3_M2, IP6DPORTM, sw->dest_l4port_mask); + FIELD_GET_MASK(IP6_RUL3_M3, IP6DPORTM_EN, mask_en); + if (mask_en) + { + sw->dest_l4port_op = FAL_ACL_FIELD_MASK; + } + else + { + sw->dest_l4port_op = FAL_ACL_FIELD_RANGE; + } + + if (A_TRUE == + _isisc_acl_field_care(sw->dest_l4port_op, + (a_uint32_t) sw->dest_l4port_val, + (a_uint32_t) sw->dest_l4port_mask, 0xffff)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_DPORT); + } + else if (FAL_ACL_FIELD_RANGE == sw->dest_l4port_op) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_DPORT); + } + + FIELD_GET(IP6_RUL3_V3, ICMP6_EN, icmp6_en); + if (icmp6_en) + { + FIELD_GET(IP6_RUL3_V3, IP6ICMPTYPV, sw->icmp_type_val); + FIELD_GET_MASK(IP6_RUL3_M3, IP6ICMPTYPM, sw->icmp_type_mask); + if (0x0 != sw->icmp_type_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_ICMP_TYPE); + } + + FIELD_GET(IP6_RUL3_V3, IP6ICMPCODEV, sw->icmp_code_val); + FIELD_GET_MASK(IP6_RUL3_M3, IP6ICMPCODEM, sw->icmp_code_mask); + if (0x0 != sw->icmp_code_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_ICMP_CODE); + } + } + else + { + FIELD_GET(IP6_RUL3_V3, IP6SPORTV, sw->src_l4port_val); + FIELD_GET_MASK(IP6_RUL3_M3, IP6SPORTM, sw->src_l4port_mask); + FIELD_GET_MASK(IP6_RUL3_M3, IP6SPORTM_EN, mask_en); + if (mask_en) + { + sw->src_l4port_op = FAL_ACL_FIELD_MASK; + } + else + { + sw->src_l4port_op = FAL_ACL_FIELD_RANGE; + } + + if (A_TRUE == + _isisc_acl_field_care(sw->src_l4port_op, + (a_uint32_t) sw->src_l4port_val, + (a_uint32_t) sw->src_l4port_mask, 0xffff)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_SPORT); + } + else if (FAL_ACL_FIELD_RANGE == sw->src_l4port_op) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_SPORT); + } + } + + FIELD_GET(IP6_RUL3_V1, IP6LABEL1V, sw->ip6_lable_val); + FIELD_GET_MASK(IP6_RUL3_M1, IP6LABEL1M, sw->ip6_lable_mask); + + FIELD_GET(IP6_RUL3_V2, IP6LABEL2V, tmp); + sw->ip6_lable_val |= (tmp << 16); + FIELD_GET_MASK(IP6_RUL3_M2, IP6LABEL2M, tmp); + sw->ip6_lable_mask |= (tmp << 16); + + if (0x0 != sw->ip6_lable_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP6_LABEL); + } + + FIELD_GET(IP6_RUL3_V3, IP6TCPFLAGV, sw->tcp_flag_val); + FIELD_GET_MASK(IP6_RUL3_M3, IP6TCPFLAGM, sw->tcp_flag_mask); + if (0x0 != sw->tcp_flag_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_TCP_FLAG); + } + + FIELD_GET(IP6_RUL3_V3, IP6DHCPV, sw->dhcpv6_val); + FIELD_GET_MASK(IP6_RUL3_M3, IP6DHCPM, sw->dhcpv6_mask); + if (0x0 != sw->dhcpv6_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_DHCPV6); + } + + FIELD_GET(MAC_RUL_V4, RULE_INV, mask_en); + if (mask_en) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL); + } + + return SW_OK; +} + +static sw_error_t +_isisc_acl_rule_udf_reparse(fal_acl_rule_t * sw, const hw_filter_t * hw) +{ + a_uint32_t i; + + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_UDF); + + /* for ISIS UDF type, length and offset no meanging in rules, just set default value */ + sw->udf_type = FAL_ACL_UDF_TYPE_L2; + sw->udf_len = 16; + sw->udf_offset = 0; + + for (i = 0; i < ISISC_MAX_UDF_LENGTH; i++) + { + sw->udf_val[i] = ((hw->vlu[3 - i / 4]) >> (24 - 8 * (i % 4))) & 0xff; + sw->udf_mask[i] = ((hw->msk[3 - i / 4]) >> (24 - 8 * (i % 4))) & 0xff; + } + + FIELD_GET(MAC_RUL_V4, RULE_INV, i); + if (i) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_INVERSE_ALL); + } + + return SW_OK; +} + +static sw_error_t +_isisc_acl_rule_action_reparse(fal_acl_rule_t * sw, const hw_filter_t * hw) +{ + a_uint32_t data; + + sw->action_flg = 0; + + FIELD_GET_ACTION(ACL_RSLT2, DES_PORT_EN, data); + if (1 == data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REDPT); + FIELD_GET_ACTION(ACL_RSLT1, DES_PORT0, sw->ports); + FIELD_GET_ACTION(ACL_RSLT2, DES_PORT1, data); + sw->ports |= (data << 3); + } + + FIELD_GET_ACTION(ACL_RSLT2, FWD_CMD, data); + if (0x7 == data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_DENY); + } + else if (0x3 == data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_RDTCPU); + } + else if (0x1 == data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_CPYCPU); + } + else + { + /* need't set permit action */ + } + + FIELD_GET_ACTION(ACL_RSLT2, MIRR_EN, data); + if (1 == data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_MIRROR); + } + + FIELD_GET_ACTION(ACL_RSLT1, PRI_QU_EN, data); + if (1 == data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REMARK_QUEUE); + FIELD_GET_ACTION(ACL_RSLT1, PRI_QU, sw->queue); + } + + FIELD_GET_ACTION(ACL_RSLT1, DSCP_REMAP, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REMARK_DSCP); + FIELD_GET_ACTION(ACL_RSLT1, DSCPV, sw->dscp); + } + + FIELD_GET_ACTION(ACL_RSLT0, STAGVID, sw->stag_vid); + + FIELD_GET_ACTION(ACL_RSLT1, TRANS_SVID_CHG, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REMARK_STAG_VID); + } + + FIELD_GET_ACTION(ACL_RSLT1, STAG_PRI_REMAP, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REMARK_STAG_PRI); + FIELD_GET_ACTION(ACL_RSLT0, STAGPRI, sw->stag_pri); + } + + FIELD_GET_ACTION(ACL_RSLT1, STAG_DEI_CHG, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REMARK_STAG_DEI); + FIELD_GET_ACTION(ACL_RSLT0, STAGDEI, sw->stag_dei); + } + + FIELD_GET_ACTION(ACL_RSLT0, CTAGVID, sw->ctag_vid); + + FIELD_GET_ACTION(ACL_RSLT1, TRANS_CVID_CHG, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REMARK_CTAG_VID); + } + + FIELD_GET_ACTION(ACL_RSLT1, CTAG_PRI_REMAP, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REMARK_CTAG_PRI); + FIELD_GET_ACTION(ACL_RSLT0, CTAGPRI, sw->ctag_pri); + } + + FIELD_GET_ACTION(ACL_RSLT1, CTAG_CFI_CHG, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REMARK_CTAG_CFI); + FIELD_GET_ACTION(ACL_RSLT0, CTAGCFI, sw->ctag_cfi); + } + + FIELD_GET_ACTION(ACL_RSLT1, LOOK_VID_CHG, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REMARK_LOOKUP_VID); + } + + FIELD_GET_ACTION(ACL_RSLT2, POLICER_EN, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_POLICER_EN); + FIELD_GET_ACTION(ACL_RSLT2, POLICER_PTR, sw->policer_ptr); + } + + FIELD_GET_ACTION(ACL_RSLT1, ARP_PTR_EN, data); + if (data) + { + FIELD_GET_ACTION(ACL_RSLT1, WCMP_EN, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_WCMP_EN); + FIELD_GET_ACTION(ACL_RSLT1, ARP_PTR, sw->wcmp_ptr); + } + else + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_ARP_EN); + FIELD_GET_ACTION(ACL_RSLT1, ARP_PTR, sw->arp_ptr); + } + } + + FIELD_GET_ACTION(ACL_RSLT1, FORCE_L3_MODE, data); + if ((0 != data) && (3 != data)) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_POLICY_FORWARD_EN); + if (0x1 == data) + { + sw->policy_fwd = FAL_ACL_POLICY_SNAT; + } + else + { + sw->policy_fwd = FAL_ACL_POLICY_DNAT; + } + } + + FIELD_GET_ACTION(ACL_RSLT2, EG_BYPASS, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_BYPASS_EGRESS_TRANS); + } + + FIELD_GET_ACTION(ACL_RSLT2, TRIGGER_INTR, data); + if (data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_MATCH_TRIGGER_INTR); + } + + return SW_OK; +} + +sw_error_t +_isisc_acl_rule_sw_to_hw(a_uint32_t dev_id, fal_acl_rule_t * sw, + isisc_acl_rule_t * hw_rule_snap, a_uint32_t * idx) +{ + sw_error_t rv; + a_uint32_t tmp_idx, i, b_rule[7] = { 0 }; + parse_func_t ptr[7] = { NULL }; + a_bool_t b_care, b_mac, eh_mac; + + rv = _isisc_acl_action_parse(dev_id, sw, &(hw_rule_snap[*idx].filter)); + SW_RTN_ON_ERROR(rv); + + ptr[0] = _isisc_acl_rule_udf_parse; + _isisc_acl_rule_mac_preparse(sw, &b_mac, &eh_mac); + + /* ehmac rule must be parsed bofore mac rule. + it's important for reparse process */ + if (A_TRUE == eh_mac) + { + ptr[1] = _isisc_acl_rule_ehmac_parse; + } + + if (A_TRUE == b_mac) + { + ptr[2] = _isisc_acl_rule_bmac_parse; + } + + if ((A_FALSE == b_mac) && (A_FALSE == eh_mac)) + { + ptr[2] = _isisc_acl_rule_bmac_parse; + } + + if (FAL_ACL_RULE_MAC == sw->rule_type) + { + } + else if (FAL_ACL_RULE_IP4 == sw->rule_type) + { + ptr[3] = _isisc_acl_rule_ip4_parse; + } + else if (FAL_ACL_RULE_IP6 == sw->rule_type) + { + ptr[4] = _isisc_acl_rule_ip6r1_parse; + ptr[5] = _isisc_acl_rule_ip6r2_parse; + ptr[6] = _isisc_acl_rule_ip6r3_parse; + } + else if (FAL_ACL_RULE_UDF == sw->rule_type) + { + ptr[1] = NULL; + ptr[2] = NULL; + } + else + { + return SW_NOT_SUPPORTED; + } + + tmp_idx = *idx; + for (i = 0; i < 7; i++) + { + if (ptr[i]) + { + if (ISISC_HW_RULE_TMP_CNT <= tmp_idx) + { + return SW_NO_RESOURCE; + } + + rv = ptr[i] (sw, &(hw_rule_snap[tmp_idx].filter), &b_care); + SW_RTN_ON_ERROR(rv); + if (A_TRUE == b_care) + { + tmp_idx++; + b_rule[i] = 1; + } + } + } + + if (FAL_ACL_RULE_IP6 == sw->rule_type) + { + if ((!b_rule[4]) && (!b_rule[5]) && (!b_rule[6])) + { + tmp_idx++; + } + } + + if (FAL_ACL_RULE_IP4 == sw->rule_type) + { + if (!b_rule[3]) + { + tmp_idx++; + } + } + + if (tmp_idx == *idx) + { + /* set type start & end */ + SW_SET_REG_BY_FIELD(MAC_RUL_M4, RULE_VALID, FLT_STARTEND, + (hw_rule_snap[*idx].filter.msk[4])); + (*idx)++; + } + else + { + if (1 == (tmp_idx - *idx)) + { + if (FAL_ACL_COMBINED_START == sw->combined) + { + SW_SET_REG_BY_FIELD(MAC_RUL_M4, RULE_VALID, FLT_START, + (hw_rule_snap[*idx].filter.msk[4])); + } + else if (FAL_ACL_COMBINED_CONTINUE == sw->combined) + { + SW_SET_REG_BY_FIELD(MAC_RUL_M4, RULE_VALID, FLT_CONTINUE, + (hw_rule_snap[*idx].filter.msk[4])); + } + else if (FAL_ACL_COMBINED_END == sw->combined) + { + SW_SET_REG_BY_FIELD(MAC_RUL_M4, RULE_VALID, FLT_END, + (hw_rule_snap[*idx].filter.msk[4])); + } + else + { + SW_SET_REG_BY_FIELD(MAC_RUL_M4, RULE_VALID, FLT_STARTEND, + (hw_rule_snap[*idx].filter.msk[4])); + } + } + else + { + for (i = *idx; i < tmp_idx; i++) + { + if (i == *idx) + { + SW_SET_REG_BY_FIELD(MAC_RUL_M4, RULE_VALID, FLT_START, + (hw_rule_snap[i].filter.msk[4])); + } + else if (i == (tmp_idx - 1)) + { + SW_SET_REG_BY_FIELD(MAC_RUL_M4, RULE_VALID, FLT_END, + (hw_rule_snap[i].filter.msk[4])); + } + else + { + SW_SET_REG_BY_FIELD(MAC_RUL_M4, RULE_VALID, FLT_CONTINUE, + (hw_rule_snap[i].filter.msk[4])); + } + aos_mem_copy(&(hw_rule_snap[i].filter.act[0]), + &(hw_rule_snap[*idx].filter.act[0]), + sizeof (hw_rule_snap[*idx].filter.act)); + } + } + *idx = tmp_idx; + } + + return SW_OK; +} + +sw_error_t +_isisc_acl_rule_hw_to_sw(a_uint32_t dev_id, fal_acl_rule_t * sw, + isisc_acl_rule_t * hw_rule_snap, a_uint32_t idx, + a_uint32_t ent_nr) +{ + a_bool_t b_mac = A_FALSE, b_ip4 = A_FALSE, b_ip6 = A_FALSE; + sw_error_t rv; + a_uint32_t i, flt_typ; + hw_filter_t *hw; + + rv = _isisc_acl_rule_action_reparse(sw, &(hw_rule_snap[idx].filter)); + SW_RTN_ON_ERROR(rv); + + sw->rule_type = FAL_ACL_RULE_UDF; + for (i = 0; i < ent_nr; i++) + { + hw = &(hw_rule_snap[idx + i].filter); + FIELD_GET_MASK(MAC_RUL_M4, RULE_TYP, flt_typ); + + if (ISISC_UDF_FILTER == flt_typ) + { + rv = _isisc_acl_rule_udf_reparse(sw, hw); + SW_RTN_ON_ERROR(rv); + } + else if (ISISC_MAC_FILTER == flt_typ) + { + rv = _isisc_acl_rule_bmac_reparse(sw, hw); + SW_RTN_ON_ERROR(rv); + b_mac = A_TRUE; + } + else if (ISISC_EHMAC_FILTER == flt_typ) + { + rv = _isisc_acl_rule_ehmac_reparse(sw, hw); + SW_RTN_ON_ERROR(rv); + b_mac = A_TRUE; + } + else if (ISISC_IP4_FILTER == flt_typ) + { + rv = _isisc_acl_rule_ip4_reparse(sw, hw); + SW_RTN_ON_ERROR(rv); + b_ip4 = A_TRUE; + } + else if (ISISC_IP6R1_FILTER == flt_typ) + { + rv = _isisc_acl_rule_ip6r1_reparse(sw, hw); + SW_RTN_ON_ERROR(rv); + b_ip6 = A_TRUE; + } + else if (ISISC_IP6R2_FILTER == flt_typ) + { + rv = _isisc_acl_rule_ip6r2_reparse(sw, hw); + SW_RTN_ON_ERROR(rv); + b_ip6 = A_TRUE; + } + else if (ISISC_IP6R3_FILTER == flt_typ) + { + rv = _isisc_acl_rule_ip6r3_reparse(sw, hw); + SW_RTN_ON_ERROR(rv); + b_ip6 = A_TRUE; + } + else + { + /* ignore fill gap filters */ + } + } + + if (A_TRUE == b_mac) + { + sw->rule_type = FAL_ACL_RULE_MAC; + } + + if (A_TRUE == b_ip4) + { + sw->rule_type = FAL_ACL_RULE_IP4; + } + + if (A_TRUE == b_ip6) + { + sw->rule_type = FAL_ACL_RULE_IP6; + } + + return SW_OK; +} diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_acl_prv.h b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_acl_prv.h new file mode 100755 index 000000000..cd5540aca --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_acl_prv.h @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +typedef struct +{ + a_uint8_t status; + a_uint8_t list_id; + a_uint8_t list_pri; + a_uint8_t rule_nr; + fal_pbmp_t bind_pts; +} isisc_acl_list_t; + + +typedef struct +{ + a_uint32_t vlu[5]; + a_uint32_t msk[5]; + a_uint32_t act[3]; +} hw_filter_t; + + +typedef struct +{ + a_uint8_t status; + a_uint8_t list_id; + a_uint8_t list_pri; + a_uint8_t rule_id; + hw_filter_t filter; + a_uint32_t src_flt_dis; /* src filter disabled */ +} isisc_acl_rule_t; + + +#define ENT_USED 0x1 +#define ENT_TMP 0x2 +#define ENT_DEACTIVE 0x4 + +#define FLT_START 0x0 +#define FLT_CONTINUE 0x1 +#define FLT_END 0x2 +#define FLT_STARTEND 0x3 + + +#define ISISC_MAC_FILTER 1 +#define ISISC_IP4_FILTER 2 +#define ISISC_IP6R1_FILTER 3 +#define ISISC_IP6R2_FILTER 4 +#define ISISC_IP6R3_FILTER 5 +#define ISISC_UDF_FILTER 6 +#define ISISC_EHMAC_FILTER 7 + + +#define ISISC_MAX_UDF_OFFSET 31 +#define ISISC_MAX_UDF_LENGTH 16 + + +#define ISISC_FILTER_VLU_OP 0x0 +#define ISISC_FILTER_MSK_OP 0x1 +#define ISISC_FILTER_ACT_OP 0x2 + + + +//#define ISISC_MAX_FILTER 8 +#define ISISC_MAX_FILTER 96 +#define ISISC_RULE_FUNC_ADDR 0x0400 +#define ISISC_HW_RULE_TMP_CNT (ISISC_MAX_FILTER + 4) + +#define ISISC_MAX_LIST_ID 255 +#define ISISC_MAX_LIST_PRI 255 + +#define ISISC_UDF_MAX_LENGTH 15 +#define ISISC_UDF_MAX_OFFSET 31 + +#define WIN_RULE_CTL0_ADDR 0x218 +#define WIN_RULE_CTL1_ADDR 0x234 + + +#define ISISC_FILTER_VLU_ADDR 0x58000 +#define ISISC_FILTER_MSK_ADDR 0x59000 +#define ISISC_FILTER_ACT_ADDR 0x5a000 + + +#define FIELD_SET(reg, field, val) \ + SW_REG_SET_BY_FIELD_U32(hw->vlu[reg], val, reg##_##field##_BOFFSET, \ + reg##_##field##_BLEN) + +#define FIELD_GET(reg, field, val) \ + SW_FIELD_GET_BY_REG_U32(hw->vlu[reg], val, reg##_##field##_BOFFSET, \ + reg##_##field##_BLEN) + +#define FIELD_SET_MASK(reg, field, val) \ + SW_REG_SET_BY_FIELD_U32(hw->msk[reg-5], val, reg##_##field##_BOFFSET, \ + reg##_##field##_BLEN) + +#define FIELD_GET_MASK(reg, field, val) \ + SW_FIELD_GET_BY_REG_U32(hw->msk[reg-5], val, reg##_##field##_BOFFSET, \ + reg##_##field##_BLEN) + +#define FIELD_SET_ACTION(reg, field, val) \ + SW_REG_SET_BY_FIELD_U32(hw->act[reg-10], val, reg##_##field##_BOFFSET, \ + reg##_##field##_BLEN) + +#define FIELD_GET_ACTION(reg, field, val) \ + SW_FIELD_GET_BY_REG_U32(hw->act[reg-10], val, reg##_##field##_BOFFSET, \ + reg##_##field##_BLEN) + +sw_error_t +_isisc_acl_rule_sw_to_hw(a_uint32_t dev_id, fal_acl_rule_t * sw, isisc_acl_rule_t * hw_filter_snap, a_uint32_t * idx); + + +sw_error_t +_isisc_acl_rule_hw_to_sw(a_uint32_t dev_id, fal_acl_rule_t * sw, isisc_acl_rule_t * hw_filter_snap, a_uint32_t idx, a_uint32_t ent_nr); + + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_cosmap.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_cosmap.c new file mode 100755 index 000000000..49473d5ea --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_cosmap.c @@ -0,0 +1,647 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup isisc_cosmap ISISC_COSMAP + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isisc_cosmap.h" +#include "isisc_reg.h" + +#define ISISC_MAX_DSCP 63 +#define ISISC_MAX_UP 7 +#define ISISC_MAX_PRI 7 +#define ISISC_MAX_DP 1 +#define ISISC_MAX_QUEUE 3 +#define ISISC_MAX_EH_QUEUE 5 + +#define ISISC_DSCP_TO_PRI 0 +#define ISISC_DSCP_TO_DP 1 +#define ISISC_UP_TO_PRI 2 +#define ISISC_UP_TO_DP 3 + +#define ISISC_EGRESS_REAMRK_ADDR 0x5ae00 +#define ISISC_EGRESS_REAMRK_NUM 16 + +#ifndef IN_COSMAP_MINI +static sw_error_t +_isisc_cosmap_dscp_to_pri_dp_set(a_uint32_t dev_id, a_uint32_t mode, + a_uint32_t dscp, a_uint32_t val) +{ + sw_error_t rv; + a_uint32_t index, data = 0; + + if (ISISC_MAX_DSCP < dscp) + { + return SW_BAD_PARAM; + } + + index = dscp >> 3; + HSL_REG_ENTRY_GET(rv, dev_id, DSCP_TO_PRI, index, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (ISISC_DSCP_TO_PRI == mode) + { + if (ISISC_MAX_PRI < val) + { + return SW_BAD_PARAM; + } + + data &= (~(0x7 << ((dscp & 0x7) << 2))); + data |= (val << ((dscp & 0x7) << 2)); + } + else + { + if (ISISC_MAX_DP < val) + { + return SW_BAD_PARAM; + } + + data &= (~(0x1 << (((dscp & 0x7) << 2) + 3))); + data |= (val << (((dscp & 0x7) << 2) + 3)); + } + + HSL_REG_ENTRY_SET(rv, dev_id, DSCP_TO_PRI, index, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_cosmap_dscp_to_pri_dp_get(a_uint32_t dev_id, a_uint32_t mode, + a_uint32_t dscp, a_uint32_t * val) +{ + sw_error_t rv; + a_uint32_t index, data = 0; + + if (ISISC_MAX_DSCP < dscp) + { + return SW_BAD_PARAM; + } + + index = dscp >> 3; + HSL_REG_ENTRY_GET(rv, dev_id, DSCP_TO_PRI, index, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data = (data >> ((dscp & 0x7) << 2)) & 0xf; + if (ISISC_DSCP_TO_PRI == mode) + { + *val = data & 0x7; + } + else + { + *val = (data & 0x8) >> 3; + } + + return SW_OK; +} + +static sw_error_t +_isisc_cosmap_up_to_pri_dp_set(a_uint32_t dev_id, a_uint32_t mode, a_uint32_t up, + a_uint32_t val) +{ + sw_error_t rv; + a_uint32_t data = 0; + + if (ISISC_MAX_UP < up) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, UP_TO_PRI, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (ISISC_UP_TO_PRI == mode) + { + if (ISISC_MAX_PRI < val) + { + return SW_BAD_PARAM; + } + + data &= (~(0x7 << (up << 2))); + data |= (val << (up << 2)); + } + else + { + if (ISISC_MAX_DP < val) + { + return SW_BAD_PARAM; + } + + data &= (~(0x1 << ((up << 2) + 3))); + data |= (val << ((up << 2) + 3)); + } + + HSL_REG_ENTRY_SET(rv, dev_id, UP_TO_PRI, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_cosmap_up_to_pri_dp_get(a_uint32_t dev_id, a_uint32_t mode, a_uint32_t up, + a_uint32_t * val) +{ + sw_error_t rv; + a_uint32_t data = 0; + + if (ISISC_MAX_UP < up) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, UP_TO_PRI, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data = (data >> (up << 2)) & 0xf; + + if (ISISC_UP_TO_PRI == mode) + { + *val = (data & 0x7); + } + else + { + *val = (data & 0x8) >> 3; + } + + return SW_OK; +} +#endif + +static sw_error_t +_isisc_cosmap_pri_to_queue_set(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t queue) +{ + sw_error_t rv; + a_uint32_t data = 0; + + if ((ISISC_MAX_PRI < pri) || (ISISC_MAX_QUEUE < queue)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PRI_TO_QUEUE, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data &= (~(0x3 << (pri << 2))); + data |= (queue << (pri << 2)); + + HSL_REG_ENTRY_SET(rv, dev_id, PRI_TO_QUEUE, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_cosmap_pri_to_ehqueue_set(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t queue) +{ + sw_error_t rv; + a_uint32_t data = 0; + + if ((ISISC_MAX_PRI < pri) || (ISISC_MAX_EH_QUEUE < queue)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PRI_TO_EHQUEUE, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data &= (~(0x7 << (pri << 2))); + data |= (queue << (pri << 2)); + + HSL_REG_ENTRY_SET(rv, dev_id, PRI_TO_EHQUEUE, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + return rv; +} + +#ifndef IN_COSMAP_MINI +static sw_error_t +_isisc_cosmap_pri_to_queue_get(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t * queue) +{ + sw_error_t rv; + a_uint32_t data = 0; + + if (ISISC_MAX_PRI < pri) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PRI_TO_QUEUE, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *queue = (data >> (pri << 2)) & 0x3; + return SW_OK; +} + +static sw_error_t +_isisc_cosmap_pri_to_ehqueue_get(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t * queue) +{ + sw_error_t rv; + a_uint32_t data = 0; + + if (ISISC_MAX_PRI < pri) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PRI_TO_EHQUEUE, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *queue = (data >> (pri << 2)) & 0x7; + return SW_OK; +} + +static sw_error_t +_isisc_cosmap_egress_remark_set(a_uint32_t dev_id, a_uint32_t tbl_id, + fal_egress_remark_table_t * tbl) +{ + sw_error_t rv; + a_uint32_t data, addr; + + if (ISISC_EGRESS_REAMRK_NUM <= tbl_id) + { + return SW_BAD_PARAM; + } + + data = (tbl->y_up & 0x7) + | ((tbl->g_up & 0x7) << 4) + | ((tbl->y_dscp & 0x3f) << 8) + | ((tbl->g_dscp & 0x3f) << 16) + | ((tbl->remark_dscp & 0x1) << 23) + | ((tbl->remark_up & 0x1) << 22); + + addr = ISISC_EGRESS_REAMRK_ADDR + (tbl_id << 4); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_cosmap_egress_remark_get(a_uint32_t dev_id, a_uint32_t tbl_id, + fal_egress_remark_table_t * tbl) +{ + sw_error_t rv; + a_uint32_t data = 0, addr; + + if (ISISC_EGRESS_REAMRK_NUM <= tbl_id) + { + return SW_BAD_PARAM; + } + + aos_mem_zero(tbl, sizeof (fal_egress_remark_table_t)); + + addr = ISISC_EGRESS_REAMRK_ADDR + (tbl_id << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data & (0x1 << 23)) + { + tbl->remark_dscp = A_TRUE; + tbl->y_dscp = (data >> 8) & 0x3f; + tbl->g_dscp = (data >> 16) & 0x3f; + } + + if (data & (0x1 << 22)) + { + tbl->remark_up = A_TRUE; + tbl->y_up = data & 0x7; + tbl->g_up = (data >> 4) & 0x7; + } + + return SW_OK; +} + +/** + * @brief Set dscp to internal priority mapping on one particular device. + * @param[in] dev_id device id + * @param[in] dscp dscp + * @param[in] pri internal priority + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_cosmap_dscp_to_pri_set(a_uint32_t dev_id, a_uint32_t dscp, a_uint32_t pri) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_cosmap_dscp_to_pri_dp_set(dev_id, ISISC_DSCP_TO_PRI, dscp, pri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dscp to internal priority mapping on one particular device. + * @param[in] dev_id device id + * @param[in] dscp dscp + * @param[out] pri internal priority + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_cosmap_dscp_to_pri_get(a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t * pri) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_cosmap_dscp_to_pri_dp_get(dev_id, ISISC_DSCP_TO_PRI, dscp, pri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dscp to internal drop precedence mapping on one particular device. + * @param[in] dev_id device id + * @param[in] dscp dscp + * @param[in] dp internal drop precedence + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_cosmap_dscp_to_dp_set(a_uint32_t dev_id, a_uint32_t dscp, a_uint32_t dp) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_cosmap_dscp_to_pri_dp_set(dev_id, ISISC_DSCP_TO_DP, dscp, dp); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dscp to internal drop precedence mapping on one particular device. + * @param[in] dev_id device id + * @param[in] dscp dscp + * @param[out] dp internal drop precedence + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_cosmap_dscp_to_dp_get(a_uint32_t dev_id, a_uint32_t dscp, a_uint32_t * dp) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_cosmap_dscp_to_pri_dp_get(dev_id, ISISC_DSCP_TO_DP, dscp, dp); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dot1p to internal priority mapping on one particular device. + * @param[in] dev_id device id + * @param[in] up dot1p + * @param[in] pri internal priority + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_cosmap_up_to_pri_set(a_uint32_t dev_id, a_uint32_t up, a_uint32_t pri) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_cosmap_up_to_pri_dp_set(dev_id, ISISC_UP_TO_PRI, up, pri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dot1p to internal priority mapping on one particular device. + * @param[in] dev_id device id + * @param[in] up dot1p + * @param[out] pri internal priority + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_cosmap_up_to_pri_get(a_uint32_t dev_id, a_uint32_t up, a_uint32_t * pri) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_cosmap_up_to_pri_dp_get(dev_id, ISISC_UP_TO_PRI, up, pri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dot1p to internal drop precedence mapping on one particular device. + * @param[in] dev_id device id + * @param[in] up dot1p + * @param[in] dp internal drop precedence + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_cosmap_up_to_dp_set(a_uint32_t dev_id, a_uint32_t up, a_uint32_t dp) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_cosmap_up_to_pri_dp_set(dev_id, ISISC_UP_TO_DP, up, dp); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dot1p to internal drop precedence mapping on one particular device. + * @param[in] dev_id device id + * @param[in] up dot1p + * @param[in] dp internal drop precedence + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_cosmap_up_to_dp_get(a_uint32_t dev_id, a_uint32_t up, a_uint32_t * dp) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_cosmap_up_to_pri_dp_get(dev_id, ISISC_UP_TO_DP, up, dp); + HSL_API_UNLOCK; + return rv; +} +#endif + +/** + * @brief Set internal priority to queue mapping on one particular device. + * @details Comments: + * This function is for port 1/2/3/4 which have four egress queues + * @param[in] dev_id device id + * @param[in] pri internal priority + * @param[in] queue queue id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_cosmap_pri_to_queue_set(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t queue) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_cosmap_pri_to_queue_set(dev_id, pri, queue); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set internal priority to queue mapping on one particular device. + * @details Comments: + * This function is for port 0/5/6 which have six egress queues + * @param[in] dev_id device id + * @param[in] pri internal priority + * @param[in] queue queue id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_cosmap_pri_to_ehqueue_set(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t queue) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_cosmap_pri_to_ehqueue_set(dev_id, pri, queue); + HSL_API_UNLOCK; + return rv; +} + +#ifndef IN_COSMAP_MINI +/** + * @brief Get internal priority to queue mapping on one particular device. + * @details Comments: + * This function is for port 1/2/3/4 which have four egress queues + * @param[in] dev_id device id + * @param[in] pri internal priority + * @param[out] queue queue id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_cosmap_pri_to_queue_get(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t * queue) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_cosmap_pri_to_queue_get(dev_id, pri, queue); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get internal priority to queue mapping on one particular device. + * @details Comments: + * This function is for port 0/5/6 which have six egress queues + * @param[in] dev_id device id + * @param[in] pri internal priority + * @param[in] queue queue id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_cosmap_pri_to_ehqueue_get(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t * queue) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_cosmap_pri_to_ehqueue_get(dev_id, pri, queue); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set egress queue based CoS remap table on one particular device. + * @param[in] dev_id device id + * @param[in] tbl_id CoS remap table id + * @param[in] tbl CoS remap table + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_cosmap_egress_remark_set(a_uint32_t dev_id, a_uint32_t tbl_id, + fal_egress_remark_table_t * tbl) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_cosmap_egress_remark_set(dev_id, tbl_id, tbl); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get egress queue based CoS remap table on one particular device. + * @param[in] dev_id device id + * @param[in] tbl_id CoS remap table id + * @param[out] tbl CoS remap table + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_cosmap_egress_remark_get(a_uint32_t dev_id, a_uint32_t tbl_id, + fal_egress_remark_table_t * tbl) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_cosmap_egress_remark_get(dev_id, tbl_id, tbl); + HSL_API_UNLOCK; + return rv; +} +#endif + +sw_error_t +isisc_cosmap_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + +#ifndef IN_COSMAP_MINI + p_api->cosmap_dscp_to_pri_set = isisc_cosmap_dscp_to_pri_set; + p_api->cosmap_dscp_to_pri_get = isisc_cosmap_dscp_to_pri_get; + p_api->cosmap_dscp_to_dp_set = isisc_cosmap_dscp_to_dp_set; + p_api->cosmap_dscp_to_dp_get = isisc_cosmap_dscp_to_dp_get; + p_api->cosmap_up_to_pri_set = isisc_cosmap_up_to_pri_set; + p_api->cosmap_up_to_pri_get = isisc_cosmap_up_to_pri_get; + p_api->cosmap_up_to_dp_set = isisc_cosmap_up_to_dp_set; + p_api->cosmap_up_to_dp_get = isisc_cosmap_up_to_dp_get; +#endif + p_api->cosmap_pri_to_queue_set = isisc_cosmap_pri_to_queue_set; + p_api->cosmap_pri_to_ehqueue_set = isisc_cosmap_pri_to_ehqueue_set; +#ifndef IN_COSMAP_MINI + p_api->cosmap_pri_to_queue_get = isisc_cosmap_pri_to_queue_get; + p_api->cosmap_pri_to_ehqueue_get = isisc_cosmap_pri_to_ehqueue_get; + p_api->cosmap_egress_remark_set = isisc_cosmap_egress_remark_set; + p_api->cosmap_egress_remark_get = isisc_cosmap_egress_remark_get; +#endif + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_fdb.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_fdb.c new file mode 100755 index 000000000..6a47bee0e --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_fdb.c @@ -0,0 +1,2294 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup isisc_fdb ISISC_FDB + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isisc_fdb.h" +#include "isisc_reg.h" +#include "isisc_fdb_prv.h" + +#ifndef IN_FDB_MINI +static sw_error_t +_isisc_wl_feature_check(a_uint32_t dev_id) +{ + sw_error_t rv; + a_uint32_t entry = 0; + + HSL_REG_FIELD_GET(rv, dev_id, MASK_CTL, 0, DEVICE_ID, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (S17C_DEVICE_ID == entry) + { + return SW_OK; + } + else + { + return SW_NOT_SUPPORTED; + } +} +#endif + +static a_bool_t +_isisc_fdb_is_zeroaddr(fal_mac_addr_t addr) +{ + a_uint32_t i; + + for (i = 0; i < 6; i++) + { + if (addr.uc[i]) + { + return A_FALSE; + } + } + + return A_TRUE; +} + +static void +_isisc_fdb_fill_addr(fal_mac_addr_t addr, a_uint32_t * reg0, a_uint32_t * reg1) +{ + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_ADDR_BYTE0, addr.uc[0], *reg1); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_ADDR_BYTE1, addr.uc[1], *reg1); + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_ADDR_BYTE2, addr.uc[2], *reg0); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_ADDR_BYTE3, addr.uc[3], *reg0); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_ADDR_BYTE4, addr.uc[4], *reg0); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_ADDR_BYTE5, addr.uc[5], *reg0); + + return; +} + +#ifndef IN_FDB_MINI +static sw_error_t +_isisc_atu_sw_to_hw(a_uint32_t dev_id, const fal_fdb_entry_t * entry, + a_uint32_t reg[]) +{ + a_uint32_t port; + sw_error_t rv; + + if (A_TRUE == entry->white_list_en) + { + rv = _isisc_wl_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, WL_EN, 1, reg[2]); + } + + if (FAL_SVL_FID == entry->fid) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_VID, 0, reg[2]); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_SVL_EN, 1, reg[1]); + } + else if (ISISC_MAX_FID >= entry->fid) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_VID, (entry->fid), reg[2]); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_SVL_EN, 0, reg[1]); + } + else + { + return SW_BAD_PARAM; + } + + if (A_FALSE == entry->portmap_en) + { + if (A_TRUE != + hsl_port_prop_check(dev_id, entry->port.id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + port = 0x1UL << entry->port.id; + } + else + { + if (A_FALSE == + hsl_mports_prop_check(dev_id, entry->port.map, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + port = entry->port.map; + } + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, DES_PORT, port, reg[1]); + + if (FAL_MAC_CPY_TO_CPU == entry->dacmd) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, COPY_TO_CPU, 1, reg[2]); + } + else if (FAL_MAC_RDT_TO_CPU == entry->dacmd) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, REDRCT_TO_CPU, 1, reg[2]); + } + else if (FAL_MAC_FRWRD != entry->dacmd) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == entry->leaky_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, LEAKY_EN, 1, reg[2]); + } + else + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, LEAKY_EN, 0, reg[2]); + } + + if (A_TRUE == entry->static_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_STATUS, 15, reg[2]); + } + else + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_STATUS, 7, reg[2]); + } + + if (FAL_MAC_DROP == entry->sacmd) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, SA_DROP_EN, 1, reg[1]); + } + else if (FAL_MAC_FRWRD != entry->sacmd) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == entry->mirror_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, MIRROR_EN, 1, reg[1]); + } + + if (A_TRUE == entry->cross_pt_state) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, CROSS_PT, 1, reg[1]); + } + else + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, CROSS_PT, 0, reg[1]); + } + + if (A_TRUE == entry->da_pri_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_PRI_EN, 1, reg[1]); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_PRI, (entry->da_queue & 0x7), + reg[1]); + } + else + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_PRI_EN, 0, reg[1]); + } + + _isisc_fdb_fill_addr(entry->addr, ®[0], ®[1]); + return SW_OK; +} +#endif + +static void +_isisc_atu_hw_to_sw(const a_uint32_t reg[], fal_fdb_entry_t * entry) +{ + a_uint32_t i, data; + + aos_mem_zero(entry, sizeof (fal_fdb_entry_t)); + + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC1, AT_SVL_EN, data, reg[1]); + if (data) + { + entry->fid = FAL_SVL_FID; + } + else + { + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, AT_VID, data, reg[2]); + entry->fid = data; + } + + entry->dacmd = FAL_MAC_FRWRD; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, COPY_TO_CPU, data, reg[2]); + if (1 == data) + { + entry->dacmd = FAL_MAC_CPY_TO_CPU; + } + + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, REDRCT_TO_CPU, data, reg[2]); + if (1 == data) + { + entry->dacmd = FAL_MAC_RDT_TO_CPU; + } + + entry->sacmd = FAL_MAC_FRWRD; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC1, SA_DROP_EN, data, reg[1]); + if (1 == data) + { + entry->sacmd = FAL_MAC_DROP; + } + + entry->leaky_en = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, LEAKY_EN, data, reg[2]); + if (1 == data) + { + entry->leaky_en = A_TRUE; + } + + entry->static_en = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, AT_STATUS, data, reg[2]); + if (0xf == data) + { + entry->static_en = A_TRUE; + } + + entry->mirror_en = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC1, MIRROR_EN, data, reg[1]); + if (1 == data) + { + entry->mirror_en = A_TRUE; + } + + entry->da_pri_en = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC1, AT_PRI_EN, data, reg[1]); + if (1 == data) + { + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC1, AT_PRI, data, reg[1]); + entry->da_pri_en = A_TRUE; + entry->da_queue = data & 0x7; + } + + entry->cross_pt_state = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC1, CROSS_PT, data, reg[1]); + if (1 == data) + { + entry->cross_pt_state = A_TRUE; + } + + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC1, DES_PORT, data, reg[1]); + entry->portmap_en = A_TRUE; + entry->port.map = data; + + for (i = 2; i < 6; i++) + { + entry->addr.uc[i] = (reg[0] >> ((5 - i) << 3)) & 0xff; + } + + for (i = 0; i < 2; i++) + { + entry->addr.uc[i] = (reg[1] >> ((1 - i) << 3)) & 0xff; + } + + entry->white_list_en = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, WL_EN, data, reg[2]); + if (1 == data) + { + entry->white_list_en = A_TRUE; + } + + return; +} + +static sw_error_t +_isisc_atu_down_to_hw(a_uint32_t dev_id, a_uint32_t reg[]) +{ + sw_error_t rv; + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC2, 0, + (a_uint8_t *) (®[2]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC3, 0, + (a_uint8_t *) (®[3]), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_atu_up_to_sw(a_uint32_t dev_id, a_uint32_t reg[]) +{ + sw_error_t rv; + + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC2, 0, + (a_uint8_t *) (®[2]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC3, 0, + (a_uint8_t *) (®[3]), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_fdb_commit(a_uint32_t dev_id, a_uint32_t op) +{ + sw_error_t rv; + a_uint32_t busy = 1; + a_uint32_t full_vio; + a_uint32_t i = 2000; + a_uint32_t entry = 0; + a_uint32_t hwop = op; + + while (busy && --i) + { + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC3, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC3, AT_BUSY, busy, entry); + } + + if (0 == i) + { + return SW_BUSY; + } + + if (ARL_FIRST_ENTRY == op) + { + hwop = ARL_NEXT_ENTRY; + } + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_BUSY, 1, entry); + + if (ARL_FLUSH_PORT_AND_STATIC == hwop) + { + hwop = ARL_FLUSH_PORT_UNICAST; + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, FLUSH_ST_EN, 1, entry); + } + + if (ARL_FLUSH_PORT_NO_STATIC == hwop) + { + hwop = ARL_FLUSH_PORT_UNICAST; + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, FLUSH_ST_EN, 0, entry); + } + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_FUNC, hwop, entry); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC3, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + busy = 1; + i = 2000; + while (busy && --i) + { + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC3, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC3, AT_BUSY, busy, entry); + } + + if (0 == i) + { + return SW_FAIL; + } + + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC3, AT_FULL_VIO, full_vio, entry); + + if (full_vio) + { + /* must clear AT_FULL_VOI bit */ + entry = 0x1000; + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC3, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (ARL_LOAD_ENTRY == hwop) + { + return SW_FULL; + } + else if ((ARL_PURGE_ENTRY == hwop) + || (ARL_FLUSH_PORT_UNICAST == hwop)) + { + return SW_NOT_FOUND; + } + else + { + return SW_FAIL; + } + } + + return SW_OK; +} + +static sw_error_t +_isisc_fdb_get(a_uint32_t dev_id, fal_fdb_op_t * option, fal_fdb_entry_t * entry, + a_uint32_t hwop) +{ + sw_error_t rv; + a_uint32_t i, port = 0, status, reg[4] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == option->port_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_PORT_EN, 1, reg[3]); + if (A_FALSE == entry->portmap_en) + { + if (A_TRUE != + hsl_port_prop_check(dev_id, entry->port.id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + port = entry->port.id; + } + else + { + if (A_FALSE == + hsl_mports_prop_check(dev_id, entry->port.map, + HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + status = 0; + for (i = 0; i < SW_MAX_NR_PORT; i++) + { + if ((entry->port.map) & (0x1UL << i)) + { + if (status) + { + return SW_BAD_PARAM; + } + port = i; + status = 1; + } + } + } + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_PORT_NUM, port, reg[3]); + } + + if (A_TRUE == option->fid_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_VID_EN, 1, reg[3]); + } + + if (A_TRUE == option->multicast_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_MULTI_EN, 1, reg[3]); + } + + if (FAL_SVL_FID == entry->fid) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_VID, 0, reg[2]); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_SVL_EN, 1, reg[1]); + } + else if (ISISC_MAX_FID >= entry->fid) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_VID, entry->fid, reg[2]); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_SVL_EN, 0, reg[1]); + } + else + { + return SW_BAD_PARAM; + } + + if (ARL_FIRST_ENTRY != hwop) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_STATUS, 0xf, reg[2]); + } + + _isisc_fdb_fill_addr(entry->addr, ®[0], ®[1]); + + rv = _isisc_atu_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_fdb_commit(dev_id, hwop); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_atu_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + _isisc_atu_hw_to_sw(reg, entry); + + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, AT_STATUS, status, reg[2]); + if ((A_TRUE == _isisc_fdb_is_zeroaddr(entry->addr)) + && (0 == status)) + { + if (ARL_NEXT_ENTRY == hwop) + { + return SW_NO_MORE; + } + else + { + return SW_NOT_FOUND; + } + } + else + { + return SW_OK; + } + + return SW_OK; +} + +#ifndef IN_FDB_MINI +static sw_error_t +_isisc_fdb_add(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t reg[4] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_atu_sw_to_hw(dev_id, entry, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_atu_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_fdb_commit(dev_id, ARL_LOAD_ENTRY); + return rv; +} +#endif + +static sw_error_t +_isisc_fdb_del_all(a_uint32_t dev_id, a_uint32_t flag) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_FDB_DEL_STATIC & flag) + { + rv = _isisc_fdb_commit(dev_id, ARL_FLUSH_ALL); + } + else + { + rv = _isisc_fdb_commit(dev_id, ARL_FLUSH_ALL_UNLOCK); + } + + return rv; +} +#ifndef IN_FDB_MINI +static sw_error_t +_isisc_fdb_del_by_port(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t flag) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_PORT_NUM, port_id, reg); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC3, 0, (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_FDB_DEL_STATIC & flag) + { + rv = _isisc_fdb_commit(dev_id, ARL_FLUSH_PORT_AND_STATIC); + } + else + { + rv = _isisc_fdb_commit(dev_id, ARL_FLUSH_PORT_NO_STATIC); + } + + return rv; +} + +static sw_error_t +_isisc_fdb_del_by_mac(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t reg0 = 0, reg1 = 0, reg2 = 0; + + HSL_DEV_ID_CHECK(dev_id); + + _isisc_fdb_fill_addr(entry->addr, ®0, ®1); + + if (FAL_SVL_FID == entry->fid) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_VID, 0, reg2); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_SVL_EN, 1, reg1); + } + else if (ISISC_MAX_FID >= entry->fid) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_VID, (entry->fid), reg2); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_SVL_EN, 0, reg1); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC2, 0, (a_uint8_t *) (®2), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC1, 0, (a_uint8_t *) (®1), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC0, 0, (a_uint8_t *) (®0), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_fdb_commit(dev_id, ARL_PURGE_ENTRY); + return rv; +} + +static sw_error_t +_isisc_fdb_find(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + fal_fdb_op_t option; + + aos_mem_zero(&option, sizeof (fal_fdb_op_t)); + rv = _isisc_fdb_get(dev_id, &option, entry, ARL_FIND_ENTRY); + return rv; +} +#endif +static sw_error_t +_isisc_fdb_extend_next(a_uint32_t dev_id, fal_fdb_op_t * option, + fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + rv = _isisc_fdb_get(dev_id, option, entry, ARL_NEXT_ENTRY); + return rv; +} + +static sw_error_t +_isisc_fdb_extend_first(a_uint32_t dev_id, fal_fdb_op_t * option, + fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + rv = _isisc_fdb_get(dev_id, option, entry, ARL_FIRST_ENTRY); + return rv; +} +#ifndef IN_FDB_MINI +static sw_error_t +_isisc_fdb_transfer(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; + a_uint32_t reg[4] = { 0 }; + + if (A_TRUE == option->port_en) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == option->fid_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_VID_EN, 1, reg[3]); + } + + if (A_TRUE == option->multicast_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_MULTI_EN, 1, reg[3]); + } + + if (FAL_SVL_FID == fid) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_VID, 0, reg[2]); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_SVL_EN, 1, reg[1]); + } + else if (ISISC_MAX_FID >= fid) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_VID, fid, reg[2]); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_SVL_EN, 0, reg[1]); + } + else + { + return SW_BAD_PARAM; + } + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_PORT_NUM, old_port, reg[3]); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, NEW_PORT_NUM, new_port, reg[3]); + + rv = _isisc_atu_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_fdb_commit(dev_id, ARL_TRANSFER_ENTRY); + return rv; +} +#endif +static sw_error_t +_isisc_fdb_port_learn_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LOOKUP_CTL, port_id, LEARN_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} +#ifndef IN_FDB_MINI +static sw_error_t +_isisc_fdb_port_learn_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LOOKUP_CTL, port_id, LEARN_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_fdb_age_ctrl_set(a_uint32_t dev_id, a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, ADDR_TABLE_CTL, 0, AGE_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_fdb_vlan_ivl_svl_set(a_uint32_t dev_id, fal_fdb_smode smode) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + data = smode; + + HSL_REG_FIELD_SET(rv, dev_id, ADDR_TABLE_CTL, 0, ARL_INI_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_fdb_vlan_ivl_svl_get(a_uint32_t dev_id, fal_fdb_smode* smode) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_CTL, 0, ARL_INI_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + + *smode = data; + + return rv; +} + + + +static sw_error_t +_isisc_fdb_age_ctrl_get(a_uint32_t dev_id, a_bool_t * enable) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_CTL, 0, AGE_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_fdb_age_time_set(a_uint32_t dev_id, a_uint32_t * time) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if ((65535 * 7 < *time) || (7 > *time)) + { + return SW_BAD_PARAM; + } + data = *time / 7; + *time = data * 7; + HSL_REG_FIELD_SET(rv, dev_id, ADDR_TABLE_CTL, 0, AGE_TIME, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_fdb_age_time_get(a_uint32_t dev_id, a_uint32_t * time) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_CTL, 0, AGE_TIME, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *time = data * 7; + return SW_OK; +} + +static sw_error_t +_isisc_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; + a_uint32_t reg = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + if (ISISC_MAX_PORT_LEARN_LIMIT_CNT < cnt) + { + return SW_BAD_PARAM; + } + SW_SET_REG_BY_FIELD(PORT_LEARN_LIMIT_CTL, SA_LEARN_LIMIT_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_LEARN_LIMIT_CTL, SA_LEARN_CNT, cnt, reg); + } + else if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(PORT_LEARN_LIMIT_CTL, SA_LEARN_LIMIT_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_LEARN_LIMIT_CTL, SA_LEARN_CNT, 0, reg); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_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; + a_uint32_t data, reg = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_LEARN_LIMIT_CTL, SA_LEARN_LIMIT_EN, data, reg); + if (data) + { + SW_GET_FIELD_BY_REG(PORT_LEARN_LIMIT_CTL, SA_LEARN_CNT, data, reg); + *enable = A_TRUE; + *cnt = data; + } + else + { + *enable = A_FALSE; + *cnt = 0; + } + + return SW_OK; +} + +static sw_error_t +_isisc_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; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_MAC_DROP == cmd) + { + data = 1; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + data = 0; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + SA_LEARN_LIMIT_DROP_EN, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_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; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + SA_LEARN_LIMIT_DROP_EN, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data) + { + *cmd = FAL_MAC_DROP; + } + else + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + + return SW_OK; +} + +static sw_error_t +_isisc_fdb_learn_limit_set(a_uint32_t dev_id, a_bool_t enable, a_uint32_t cnt) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + HSL_REG_ENTRY_GET(rv, dev_id, GLOBAL_LEARN_LIMIT_CTL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + if (ISISC_MAX_LEARN_LIMIT_CNT < cnt) + { + return SW_BAD_PARAM; + } + SW_SET_REG_BY_FIELD(GLOBAL_LEARN_LIMIT_CTL, GOL_SA_LEARN_LIMIT_EN, 1, + reg); + SW_SET_REG_BY_FIELD(GLOBAL_LEARN_LIMIT_CTL, GOL_SA_LEARN_CNT, cnt, reg); + } + else if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(GLOBAL_LEARN_LIMIT_CTL, GOL_SA_LEARN_LIMIT_EN, 0, + reg); + SW_SET_REG_BY_FIELD(GLOBAL_LEARN_LIMIT_CTL, GOL_SA_LEARN_CNT, 0, reg); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_SET(rv, dev_id, GLOBAL_LEARN_LIMIT_CTL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_fdb_learn_limit_get(a_uint32_t dev_id, a_bool_t * enable, + a_uint32_t * cnt) +{ + sw_error_t rv; + a_uint32_t data, reg = 0; + + HSL_REG_ENTRY_GET(rv, dev_id, GLOBAL_LEARN_LIMIT_CTL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(GLOBAL_LEARN_LIMIT_CTL, GOL_SA_LEARN_LIMIT_EN, data, + reg); + if (data) + { + SW_GET_FIELD_BY_REG(GLOBAL_LEARN_LIMIT_CTL, GOL_SA_LEARN_CNT, data, + reg); + *enable = A_TRUE; + *cnt = data; + } + else + { + *enable = A_FALSE; + *cnt = 0; + } + + return SW_OK; +} + +static sw_error_t +_isisc_fdb_learn_exceed_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_MAC_DROP == cmd) + { + data = 1; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + data = 0; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, GLOBAL_LEARN_LIMIT_CTL, 0, + GOL_SA_LEARN_LIMIT_DROP_EN, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_fdb_learn_exceed_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, GLOBAL_LEARN_LIMIT_CTL, 0, + GOL_SA_LEARN_LIMIT_DROP_EN, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data) + { + *cmd = FAL_MAC_DROP; + } + else + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + + return SW_OK; +} + +#define ISISC_RESV_ADDR_NUM 32 +#define RESV_ADDR_TBL0_ADDR 0x3c000 +#define RESV_ADDR_TBL1_ADDR 0x3c004 +#define RESV_ADDR_TBL2_ADDR 0x3c008 + +static void +_isisc_resv_addr_parse(const a_uint32_t reg[], fal_mac_addr_t * addr) +{ + a_uint32_t i; + + for (i = 2; i < 6; i++) + { + addr->uc[i] = (reg[0] >> ((5 - i) << 3)) & 0xff; + } + + for (i = 0; i < 2; i++) + { + addr->uc[i] = (reg[1] >> ((1 - i) << 3)) & 0xff; + } +} + +static sw_error_t +_isisc_resv_atu_sw_to_hw(a_uint32_t dev_id, fal_fdb_entry_t * entry, + a_uint32_t reg[]) +{ + a_uint32_t port; + + if (A_FALSE == entry->portmap_en) + { + if (A_TRUE != + hsl_port_prop_check(dev_id, entry->port.id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + port = 0x1UL << entry->port.id; + } + else + { + if (A_FALSE == + hsl_mports_prop_check(dev_id, entry->port.map, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + port = entry->port.map; + } + SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_DES_PORT, port, reg[1]); + + if (FAL_MAC_CPY_TO_CPU == entry->dacmd) + { + SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_COPY_TO_CPU, 1, reg[1]); + } + else if (FAL_MAC_RDT_TO_CPU == entry->dacmd) + { + SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_REDRCT_TO_CPU, 1, reg[1]); + } + else if (FAL_MAC_FRWRD != entry->dacmd) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_MAC_FRWRD != entry->sacmd) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == entry->leaky_en) + { + SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_LEAKY_EN, 1, reg[1]); + } + else + { + SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_LEAKY_EN, 0, reg[1]); + } + + if (A_TRUE != entry->static_en) + { + return SW_NOT_SUPPORTED; + } + SW_SET_REG_BY_FIELD(RESV_ADDR_TBL2, RESV_STATUS, 1, reg[2]); + + if (A_TRUE == entry->mirror_en) + { + SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_MIRROR_EN, 1, reg[1]); + } + + if (A_TRUE == entry->cross_pt_state) + { + SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_CROSS_PT, 1, reg[1]); + } + + if (A_TRUE == entry->da_pri_en) + { + SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_PRI_EN, 1, reg[1]); + SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_PRI, (entry->da_queue & 0x7), + reg[1]); + } + + _isisc_fdb_fill_addr(entry->addr, ®[0], ®[1]); + return SW_OK; +} + +static void +_isisc_resv_atu_hw_to_sw(const a_uint32_t reg[], fal_fdb_entry_t * entry) +{ + a_uint32_t data; + + aos_mem_zero(entry, sizeof (fal_fdb_entry_t)); + + entry->fid = FAL_SVL_FID; + + entry->dacmd = FAL_MAC_FRWRD; + SW_GET_FIELD_BY_REG(RESV_ADDR_TBL1, RESV_COPY_TO_CPU, data, reg[1]); + if (1 == data) + { + entry->dacmd = FAL_MAC_CPY_TO_CPU; + } + + SW_GET_FIELD_BY_REG(RESV_ADDR_TBL1, RESV_REDRCT_TO_CPU, data, reg[1]); + if (1 == data) + { + entry->dacmd = FAL_MAC_RDT_TO_CPU; + } + + entry->sacmd = FAL_MAC_FRWRD; + + entry->leaky_en = A_FALSE; + SW_GET_FIELD_BY_REG(RESV_ADDR_TBL1, RESV_LEAKY_EN, data, reg[1]); + if (1 == data) + { + entry->leaky_en = A_TRUE; + } + + entry->static_en = A_TRUE; + + entry->mirror_en = A_FALSE; + SW_GET_FIELD_BY_REG(RESV_ADDR_TBL1, RESV_MIRROR_EN, data, reg[1]); + if (1 == data) + { + entry->mirror_en = A_TRUE; + } + + entry->da_pri_en = A_FALSE; + SW_GET_FIELD_BY_REG(RESV_ADDR_TBL1, RESV_PRI_EN, data, reg[1]); + if (1 == data) + { + SW_GET_FIELD_BY_REG(RESV_ADDR_TBL1, RESV_PRI, data, reg[1]); + entry->da_pri_en = A_TRUE; + entry->da_queue = data & 0x7; + } + + entry->cross_pt_state = A_FALSE; + SW_GET_FIELD_BY_REG(RESV_ADDR_TBL1, RESV_CROSS_PT, data, reg[1]); + if (1 == data) + { + entry->cross_pt_state = A_TRUE; + } + + SW_GET_FIELD_BY_REG(RESV_ADDR_TBL1, RESV_DES_PORT, data, reg[1]); + entry->portmap_en = A_TRUE; + entry->port.map = data; + + _isisc_resv_addr_parse(reg, &(entry->addr)); + return; +} + +static sw_error_t +_isisc_fdb_resv_commit(a_uint32_t dev_id, fal_fdb_entry_t * entry, a_uint32_t op, + a_uint32_t * empty) +{ + a_uint32_t index, addr, data, tbl[3] = { 0 }; + sw_error_t rv; + fal_mac_addr_t mac_tmp; + + *empty = ISISC_RESV_ADDR_NUM; + for (index = 0; index < ISISC_RESV_ADDR_NUM; index++) + { + addr = RESV_ADDR_TBL2_ADDR + (index << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[2])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(RESV_ADDR_TBL2, RESV_STATUS, data, tbl[2]); + if (data) + { + addr = RESV_ADDR_TBL0_ADDR + (index << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[0])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + addr = RESV_ADDR_TBL1_ADDR + (index << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[1])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + _isisc_resv_addr_parse(tbl, &mac_tmp); + if (!aos_mem_cmp + ((void *) &(entry->addr), (void *) &mac_tmp, + sizeof (fal_mac_addr_t))) + { + if (ARL_PURGE_ENTRY == op) + { + addr = RESV_ADDR_TBL2_ADDR + (index << 4); + tbl[2] = 0; + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[2])), + sizeof (a_uint32_t)); + return rv; + } + else if (ARL_LOAD_ENTRY == op) + { + return SW_ALREADY_EXIST; + } + else if (ARL_FIND_ENTRY == op) + { + _isisc_resv_atu_hw_to_sw(tbl, entry); + return SW_OK; + } + } + } + else + { + *empty = index; + } + } + + return SW_NOT_FOUND; +} + +static sw_error_t +_isisc_fdb_resv_add(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t i, empty, addr, tbl[3] = { 0 }; + + rv = _isisc_resv_atu_sw_to_hw(dev_id, entry, tbl); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_fdb_resv_commit(dev_id, entry, ARL_LOAD_ENTRY, &empty); + if (SW_ALREADY_EXIST == rv) + { + return rv; + } + + if (ISISC_RESV_ADDR_NUM == empty) + { + return SW_NO_RESOURCE; + } + + for (i = 0; i < 3; i++) + { + addr = RESV_ADDR_TBL0_ADDR + (empty << 4) + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[i])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +static sw_error_t +_isisc_fdb_resv_del(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t empty; + + rv = _isisc_fdb_resv_commit(dev_id, entry, ARL_PURGE_ENTRY, &empty); + return rv; +} + +static sw_error_t +_isisc_fdb_resv_find(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t empty; + + rv = _isisc_fdb_resv_commit(dev_id, entry, ARL_FIND_ENTRY, &empty); + return rv; +} + +static sw_error_t +_isisc_fdb_resv_iterate(a_uint32_t dev_id, a_uint32_t * iterator, + fal_fdb_entry_t * entry) +{ + a_uint32_t index, addr, data, tbl[3] = { 0 }; + sw_error_t rv; + + if ((NULL == iterator) || (NULL == entry)) + { + return SW_BAD_PTR; + } + + if (ISISC_RESV_ADDR_NUM < *iterator) + { + return SW_BAD_PARAM; + } + + for (index = *iterator; index < ISISC_RESV_ADDR_NUM; index++) + { + addr = RESV_ADDR_TBL2_ADDR + (index << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[2])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(RESV_ADDR_TBL2, RESV_STATUS, data, tbl[2]); + if (data) + { + addr = RESV_ADDR_TBL0_ADDR + (index << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[0])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + addr = RESV_ADDR_TBL1_ADDR + (index << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[1])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + _isisc_resv_atu_hw_to_sw(tbl, entry); + break; + } + } + + if (ISISC_RESV_ADDR_NUM == index) + { + return SW_NO_MORE; + } + + *iterator = index + 1; + return SW_OK; +} + +static sw_error_t +_isisc_fdb_port_learn_static_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 0xf; + } + else if (A_FALSE == enable) + { + data = 0x7; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + SA_LEARN_STATUS, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_fdb_port_learn_static_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + SA_LEARN_STATUS, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0xf == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_fdb_port_update(a_uint32_t dev_id, a_uint32_t fid, fal_mac_addr_t * addr, fal_port_t port_id, a_uint32_t op) +{ + sw_error_t rv; + fal_fdb_entry_t entry; + fal_fdb_op_t option; + a_uint32_t reg, port; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_SVL_FID < fid) + { + return SW_BAD_PARAM; + } + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + aos_mem_zero(&option, sizeof(fal_fdb_op_t)); + aos_mem_copy(&(entry.addr), addr, sizeof(fal_mac_addr_t)); + entry.fid = fid & 0xffff; + rv = _isisc_fdb_get(dev_id, &option, &entry, ARL_FIND_ENTRY); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC1, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC1, DES_PORT, port, reg); + if (op) + { + port |= (0x1 << port_id); + } + else + { + port &= (~(0x1 << port_id)); + } + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, DES_PORT, port, reg); + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC1, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + rv = _isisc_fdb_commit(dev_id, ARL_LOAD_ENTRY); + return rv; +} + +sw_error_t +inter_isisc_fdb_flush(a_uint32_t dev_id, a_uint32_t flag) +{ + if (FAL_FDB_DEL_STATIC & flag) + { + return _isisc_fdb_commit(dev_id, ARL_FLUSH_ALL); + } + else + { + return _isisc_fdb_commit(dev_id, ARL_FLUSH_ALL_UNLOCK); + } +} + +/** + * @brief Add a Fdb entry + * @param[in] dev_id device id + * @param[in] entry fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_fdb_add(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_fdb_add(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Delete all Fdb entries + * @details Comments: + * If set FAL_FDB_DEL_STATIC bit in flag which means delete all fdb + * entries otherwise only delete dynamic entries. + * @param[in] dev_id device id + * @param[in] flag delete operation option + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_fdb_del_all(a_uint32_t dev_id, a_uint32_t flag) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_fdb_del_all(dev_id, flag); + HSL_API_UNLOCK; + return rv; +} +#ifndef IN_FDB_MINI +/** + * @brief Delete Fdb entries on a particular port + * @details Comments: + * If set FAL_FDB_DEL_STATIC bit in flag which means delete all fdb + * entries otherwise only delete dynamic entries. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] flag delete operation option + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_fdb_del_by_port(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t flag) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_fdb_del_by_port(dev_id, port_id, flag); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a particular Fdb entry through mac address + * @details Comments: + * Only addr field in entry is meaning. For IVL learning vid or fid field + * also is meaning. + * @param[in] dev_id device id + * @param[in] entry fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_fdb_del_by_mac(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_fdb_del_by_mac(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Find a particular Fdb entry from device through mac address. + * @details Comments: + For input parameter only addr field in entry is meaning. + * @param[in] dev_id device id + * @param[in] entry fdb entry + * @param[out] entry fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_fdb_find(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_fdb_find(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Get next Fdb entry from a particular device + * @param[in] dev_id device id + * @param[in] option next operation options + * @param[out] entry fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_fdb_extend_next(a_uint32_t dev_id, fal_fdb_op_t * option, + fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_fdb_extend_next(dev_id, option, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get first Fdb entry from a particular device + * @param[in] dev_id device id + * @param[in] option first operation options + * @param[out] entry fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_fdb_extend_first(a_uint32_t dev_id, fal_fdb_op_t * option, + fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_fdb_extend_first(dev_id, option, entry); + HSL_API_UNLOCK; + return rv; +} +#ifndef IN_FDB_MINI +/** + * @brief Transfer fdb entries port information on a particular device. + * @param[in] dev_id device id + * @param[in] old_port source port id + * @param[in] new_port destination port id + * @param[in] fid filter database id + * @param[in] option transfer operation options + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_fdb_transfer(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; + + HSL_API_LOCK; + rv = _isisc_fdb_transfer(dev_id, old_port, new_port, fid, option); + HSL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Set dynamic address learning status on a particular port. + * @details Comments: + * This operation will enable or disable dynamic address learning + * feature on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable enable or disable + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_fdb_port_learn_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_fdb_port_learn_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} +#ifndef IN_FDB_MINI +/** + * @brief Get dynamic address learning status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_fdb_port_learn_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_fdb_port_learn_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dynamic address aging status on particular device. + * @details Comments: + * This operation will enable or disable dynamic address aging + * feature on particular device. + * @param[in] dev_id device id + * @param[in] enable enable or disable + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_fdb_age_ctrl_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_fdb_age_ctrl_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dynamic address aging status on particular device. + * @param[in] dev_id device id + * @param[in] enable enable or disable + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_fdb_age_ctrl_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_fdb_age_ctrl_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief set arl search mode as ivl or svl when vlan invalid. + * @param[in] dev_id device id + * @param[in] smode INVALID_VLAN_IVL or INVALID_VLAN_SVL + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_fdb_vlan_ivl_svl_set(a_uint32_t dev_id, fal_fdb_smode smode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_fdb_vlan_ivl_svl_set(dev_id, smode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief get arl search mode when vlan invalid. + * @param[in] dev_id device id + * @param[out] smode INVALID_VLAN_IVL or INVALID_VLAN_SVL + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_fdb_vlan_ivl_svl_get(a_uint32_t dev_id, fal_fdb_smode* smode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_fdb_vlan_ivl_svl_get(dev_id, smode); + HSL_API_UNLOCK; + return rv; +} + + + +/** + * @brief Set dynamic address aging time on a particular device. + * @details Comments: + * This operation will set dynamic address aging time on a particular device. + * The unit of time is second. Because different device has differnet + * hardware granularity function will return actual time in hardware. + * @param[in] dev_id device id + * @param time aging time + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_fdb_age_time_set(a_uint32_t dev_id, a_uint32_t * time) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_fdb_age_time_set(dev_id, time); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dynamic address aging time on a particular device. + * @param[in] dev_id device id + * @param[out] time aging time + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_fdb_age_time_get(a_uint32_t dev_id, a_uint32_t * time) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_fdb_age_time_get(dev_id, time); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dynamic address learning count limit on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] cnt limit count + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_port_fdb_learn_limit_set(dev_id, port_id, enable, cnt); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dynamic address learning count limit on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @param[out] cnt limit count + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_port_fdb_learn_limit_get(dev_id, port_id, enable, cnt); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dynamic address learning count exceed command on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_port_fdb_learn_exceed_cmd_set(dev_id, port_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dynamic address learning count exceed command on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_port_fdb_learn_exceed_cmd_get(dev_id, port_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dynamic address learning count limit on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] cnt limit count + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_fdb_learn_limit_set(a_uint32_t dev_id, a_bool_t enable, a_uint32_t cnt) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_fdb_learn_limit_set(dev_id, enable, cnt); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dynamic address learning count limit on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] cnt limit count + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_fdb_learn_limit_get(a_uint32_t dev_id, a_bool_t * enable, a_uint32_t * cnt) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_fdb_learn_limit_get(dev_id, enable, cnt); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dynamic address learning count exceed command on a particular device. + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_fdb_learn_exceed_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_fdb_learn_exceed_cmd_set(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dynamic address learning count exceed command on a particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_fdb_learn_exceed_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_fdb_learn_exceed_cmd_get(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add a particular reserve Fdb entry + * @param[in] dev_id device id + * @param[in] entry reserve fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_fdb_resv_add(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_fdb_resv_add(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a particular reserve Fdb entry through mac address + * @param[in] dev_id device id + * @param[in] entry reserve fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_fdb_resv_del(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_fdb_resv_del(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Find a particular reserve Fdb entry through mac address + * @param[in] dev_id device id + * @param[in] entry reserve fdb entry + * @param[out] entry reserve fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_fdb_resv_find(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_fdb_resv_find(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Iterate all reserve fdb entries on a particular device. + * @param[in] dev_id device id + * @param[in] iterator reserve fdb entry index if it's zero means get the first entry + * @param[out] iterator next valid fdb entry index + * @param[out] entry reserve fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_fdb_resv_iterate(a_uint32_t dev_id, a_uint32_t * iterator, + fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_fdb_resv_iterate(dev_id, iterator, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set the static status of fdb entries which learned by hardware on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_fdb_port_learn_static_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_fdb_port_learn_static_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get the static status of fdb entries which learned by hardware on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_fdb_port_learn_static_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_fdb_port_learn_static_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add a port to an exsiting entry + * @param[in] dev_id device id + * @param[in] fid filtering database id + * @param[in] addr MAC address + * @param[in] port_id port id + * @return SW_OK or error code, If entry not exist will return error. + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_fdb_port_update(dev_id, fid, addr, port_id, 1); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a port from an exsiting entry + * @param[in] dev_id device id + * @param[in] fid filtering database id + * @param[in] addr MAC address + * @param[in] port_id port id + * @return SW_OK or error code, If entry not exist will return error. + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_fdb_port_update(dev_id, fid, addr, port_id, 0); + HSL_API_UNLOCK; + return rv; +} +#endif +sw_error_t +isisc_fdb_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); +#ifndef IN_FDB_MINI + p_api->fdb_add = isisc_fdb_add; +#endif + p_api->fdb_del_all = isisc_fdb_del_all; +#ifndef IN_FDB_MINI + p_api->fdb_del_by_port = isisc_fdb_del_by_port; + p_api->fdb_del_by_mac = isisc_fdb_del_by_mac; + p_api->fdb_find = isisc_fdb_find; +#endif + p_api->port_learn_set = isisc_fdb_port_learn_set; +#ifndef IN_FDB_MINI + p_api->port_learn_get = isisc_fdb_port_learn_get; + p_api->age_ctrl_set = isisc_fdb_age_ctrl_set; + p_api->age_ctrl_get = isisc_fdb_age_ctrl_get; + p_api->vlan_ivl_svl_set = isisc_fdb_vlan_ivl_svl_set; + p_api->vlan_ivl_svl_get = isisc_fdb_vlan_ivl_svl_get; + p_api->age_time_set = isisc_fdb_age_time_set; + p_api->age_time_get = isisc_fdb_age_time_get; +#endif + p_api->fdb_extend_next = isisc_fdb_extend_next; + p_api->fdb_extend_first = isisc_fdb_extend_first; +#ifndef IN_FDB_MINI + p_api->fdb_transfer = isisc_fdb_transfer; + p_api->port_fdb_learn_limit_set = isisc_port_fdb_learn_limit_set; + p_api->port_fdb_learn_limit_get = isisc_port_fdb_learn_limit_get; + p_api->port_fdb_learn_exceed_cmd_set = isisc_port_fdb_learn_exceed_cmd_set; + p_api->port_fdb_learn_exceed_cmd_get = isisc_port_fdb_learn_exceed_cmd_get; + p_api->fdb_learn_limit_set = isisc_fdb_learn_limit_set; + p_api->fdb_learn_limit_get = isisc_fdb_learn_limit_get; + p_api->fdb_learn_exceed_cmd_set = isisc_fdb_learn_exceed_cmd_set; + p_api->fdb_learn_exceed_cmd_get = isisc_fdb_learn_exceed_cmd_get; + p_api->fdb_resv_add = isisc_fdb_resv_add; + p_api->fdb_resv_del = isisc_fdb_resv_del; + p_api->fdb_resv_find = isisc_fdb_resv_find; + p_api->fdb_resv_iterate = isisc_fdb_resv_iterate; + p_api->fdb_port_learn_static_set = isisc_fdb_port_learn_static_set; + p_api->fdb_port_learn_static_get = isisc_fdb_port_learn_static_get; + p_api->fdb_port_add = isisc_fdb_port_add; + p_api->fdb_port_del = isisc_fdb_port_del; +#endif + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_igmp.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_igmp.c new file mode 100755 index 000000000..83a3df46e --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_igmp.c @@ -0,0 +1,1147 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup isisc_igmp ISISC_IGMP + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isisc_igmp.h" +#include "isisc_reg.h" + +#define LEAVE_EN_OFFSET 2 +#define JOIN_EN_OFFSET 1 +#define IGMP_MLD_EN_OFFSET 0 + +#define ISISC_MAX_PORT_LEARN_LIMIT_CNT 1024 + +extern sw_error_t +isisc_igmp_sg_entry_set(a_uint32_t dev_id, fal_igmp_sg_entry_t * entry); + +extern sw_error_t +isisc_igmp_sg_entry_clear(a_uint32_t dev_id, fal_igmp_sg_entry_t * entry); + +extern sw_error_t +isisc_igmp_sg_entry_show(a_uint32_t dev_id); + +extern sw_error_t +isisc_igmp_sg_entry_query(a_uint32_t dev_id, fal_igmp_sg_info_t * info); + +static sw_error_t +_isisc_port_igmp_property_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable, a_uint32_t item) +{ + sw_error_t rv; + a_uint32_t reg = 0, val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + if (3 >= port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, FRAME_ACK_CTL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + reg &= ~(0x1UL << ((port_id << 3) + item)); + reg |= (val << ((port_id << 3) + item)); + + HSL_REG_ENTRY_SET(rv, dev_id, FRAME_ACK_CTL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + HSL_REG_ENTRY_GET(rv, dev_id, FRAME_ACK_CTL1, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + reg &= ~(0x1UL << (((port_id - 4) << 3) + item)); + reg |= (val << (((port_id - 4) << 3) + item)); + + HSL_REG_ENTRY_SET(rv, dev_id, FRAME_ACK_CTL1, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + return rv; +} + +static sw_error_t +_isisc_port_igmp_property_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable, a_uint32_t item) +{ + sw_error_t rv; + a_uint32_t reg = 0, val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (3 >= port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, FRAME_ACK_CTL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + val = (reg >> ((port_id << 3) + item)) & 0x1UL; + } + else + { + HSL_REG_ENTRY_GET(rv, dev_id, FRAME_ACK_CTL1, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + val = (reg >> (((port_id - 4) << 3) + item)) & 0x1UL; + } + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_igmp_mld_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_MAC_CPY_TO_CPU == cmd) + { + val = 1; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + val = 0; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, IGMP_COPY_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_igmp_mld_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, IGMP_COPY_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *cmd = FAL_MAC_CPY_TO_CPU; + } + else + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + + return SW_OK; +} + +static sw_error_t +_isisc_igmp_mld_rp_set(a_uint32_t dev_id, fal_pbmp_t pts) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_mports_validity_check(dev_id, pts)) + { + return SW_BAD_PARAM; + } + val = pts; + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL1, 0, IGMP_DP, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_igmp_mld_rp_get(a_uint32_t dev_id, fal_pbmp_t * pts) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL1, 0, IGMP_DP, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *pts = val; + return SW_OK; +} + +static sw_error_t +_isisc_igmp_mld_entry_creat_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, ADDR_TABLE_CTL, 0, IGMP_CREAT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_igmp_mld_entry_creat_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_CTL, 0, IGMP_CREAT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_igmp_mld_entry_static_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 0xf; + } + else if (A_FALSE == enable) + { + val = 0xe; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, ADDR_TABLE_CTL, 0, IGMP_JOIN_STATIC, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_igmp_mld_entry_static_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_CTL, 0, IGMP_JOIN_STATIC, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0xf == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_igmp_mld_entry_leaky_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, ADDR_TABLE_CTL, 0, IGMP_JOIN_LEAKY, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_igmp_mld_entry_leaky_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_CTL, 0, IGMP_JOIN_LEAKY, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_igmp_mld_entry_v3_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FRAME_ACK_CTL1, 0, IGMP_V3_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_igmp_mld_entry_v3_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FRAME_ACK_CTL1, 0, IGMP_V3_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_igmp_mld_entry_queue_set(a_uint32_t dev_id, a_bool_t enable, + a_uint32_t queue) +{ + sw_error_t rv; + a_uint32_t entry = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_CTL, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_CTL, IGMP_PRI_EN, 1, entry); + SW_SET_REG_BY_FIELD(ADDR_TABLE_CTL, IGMP_PRI, queue, entry); + } + else if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_CTL, IGMP_PRI_EN, 0, entry); + SW_SET_REG_BY_FIELD(ADDR_TABLE_CTL, IGMP_PRI, 0, entry); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_CTL, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_igmp_mld_entry_queue_get(a_uint32_t dev_id, a_bool_t * enable, + a_uint32_t * queue) +{ + sw_error_t rv; + a_uint32_t entry = 0, data; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_CTL, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(ADDR_TABLE_CTL, IGMP_PRI_EN, data, entry); + if (data) + { + *enable = A_TRUE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_CTL, IGMP_PRI, data, entry); + *queue = data; + } + else + { + *enable = A_FALSE; + *queue = 0; + } + + return SW_OK; +} + +static sw_error_t +_isisc_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; + a_uint32_t reg = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + if (ISISC_MAX_PORT_LEARN_LIMIT_CNT < cnt) + { + return SW_BAD_PARAM; + } + SW_SET_REG_BY_FIELD(PORT_LEARN_LIMIT_CTL, IGMP_JOIN_LIMIT_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_LEARN_LIMIT_CTL, IGMP_JOIN_CNT, cnt, reg); + } + else if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(PORT_LEARN_LIMIT_CTL, IGMP_JOIN_LIMIT_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_LEARN_LIMIT_CTL, IGMP_JOIN_CNT, 0, reg); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_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; + a_uint32_t data, reg = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_LEARN_LIMIT_CTL, IGMP_JOIN_LIMIT_EN, data, reg); + if (data) + { + SW_GET_FIELD_BY_REG(PORT_LEARN_LIMIT_CTL, IGMP_JOIN_CNT, data, reg); + *enable = A_TRUE; + *cnt = data; + } + else + { + *enable = A_FALSE; + *cnt = data; + } + + return SW_OK; +} + +static sw_error_t +_isisc_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; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_MAC_DROP == cmd) + { + data = 1; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + data = 0; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + IGMP_JOIN_LIMIT_DROP_EN, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_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; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, + IGMP_JOIN_LIMIT_DROP_EN, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data) + { + *cmd = FAL_MAC_DROP; + } + else + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + + return SW_OK; +} + +/** + * @brief Set igmp/mld packets snooping status on a particular port. + * @details Comments: + * After enabling igmp/mld snooping feature on a particular port all kinds + * igmp/mld packets received on this port would be acknowledged by hardware. + * Particular forwarding decision could be setted by fal_igmp_mld_cmd_set. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_igmps_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_igmp_property_set(dev_id, port_id, enable, + IGMP_MLD_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld packets snooping status on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_igmps_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_igmp_property_get(dev_id, port_id, enable, + IGMP_MLD_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmp/mld packets forwarding command on a particular device. + * @details Comments: + * Particular device may only support parts of forwarding commands. + * This operation will take effect only after enabling igmp/mld snooping + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_igmp_mld_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_igmp_mld_cmd_set(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld packets forwarding command on a particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_igmp_mld_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_igmp_mld_cmd_get(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmp/mld join packets hardware acknowledgement status on particular port. + * @details Comments: + * After enabling igmp/mld join feature on a particular port hardware will + * dynamic learning or changing multicast entry. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_igmp_mld_join_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_igmp_property_set(dev_id, port_id, enable, JOIN_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld join packets hardware acknowledgement status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_igmp_mld_join_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_igmp_property_get(dev_id, port_id, enable, JOIN_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmp/mld leave packets hardware acknowledgement status on a particular port. + * @details Comments: + * After enabling igmp leave feature on a particular port hardware will dynamic + * deleting or changing multicast entry. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_igmp_mld_leave_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_igmp_property_set(dev_id, port_id, enable, LEAVE_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld leave packets hardware acknowledgement status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_igmp_mld_leave_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_igmp_property_get(dev_id, port_id, enable, LEAVE_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmp/mld router ports on a particular device. + * @details Comments: + * After enabling igmp/mld join/leave feature on a particular port igmp/mld + * join/leave packets received on this port will be forwarded to router ports. + * @param[in] dev_id device id + * @param[in] pts dedicates ports + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_igmp_mld_rp_set(a_uint32_t dev_id, fal_pbmp_t pts) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_igmp_mld_rp_set(dev_id, pts); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld router ports on a particular device. + * @param[in] dev_id device id + * @param[out] pts dedicates ports + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_igmp_mld_rp_get(a_uint32_t dev_id, fal_pbmp_t * pts) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_igmp_mld_rp_get(dev_id, pts); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set the status of creating multicast entry during igmp/mld join/leave procedure. + * @details Comments: + * After enabling igmp/mld join/leave feature on a particular port if enable + * entry creat hardware will dynamic creat and delete multicast entry, + * otherwise hardware only can change destination ports of existing muticast entry. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_igmp_mld_entry_creat_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_igmp_mld_entry_creat_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get the status of creating multicast entry during igmp/mld join/leave procedure. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_igmp_mld_entry_creat_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_igmp_mld_entry_creat_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set the static status of multicast entry which learned by hardware. + * @details Comments: + * After enabling igmp/mld join/leave feature on a particular port if enable + * static status hardware will not age out multicast entry which leardned by hardware, + * otherwise hardware will age out multicast entry which leardned by hardware. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_igmp_mld_entry_static_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_igmp_mld_entry_static_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get the static status of multicast entry which learned by hardware. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_igmp_mld_entry_static_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_igmp_mld_entry_static_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set the leaky status of multicast entry which learned by hardware. + * @details Comments: + * After enabling igmp/mld join/leave feature on a particular port if enable + * leaky status hardware will set leaky flag of multicast entry which leardned by hardware, + * otherwise hardware will not set leaky flag of multicast entry which leardned by hardware. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_igmp_mld_entry_leaky_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_igmp_mld_entry_leaky_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get the leaky status of multicast entry which learned by hardware. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_igmp_mld_entry_leaky_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_igmp_mld_entry_leaky_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmpv3/mldv2 packets hardware acknowledgement status on a particular device. + * @details Comments: + * After enabling igmp join/leave feature on a particular port hardware will dynamic + * creating or changing multicast entry after receiving igmpv3/mldv2 packets. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_igmp_mld_entry_v3_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_igmp_mld_entry_v3_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmpv3/mldv2 packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_igmp_mld_entry_v3_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_igmp_mld_entry_v3_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set the queue status of multicast entry which learned by hardware. + * @details Comments: + * After enabling igmp/mld join/leave feature on a particular port if enable + * leaky status hardware will set queue flag of multicast entry which leardned by hardware, + * otherwise hardware will not set queue flag of multicast entry which leardned by hardware. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] queue queue id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_igmp_mld_entry_queue_set(a_uint32_t dev_id, a_bool_t enable, + a_uint32_t queue) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_igmp_mld_entry_queue_set(dev_id, enable, queue); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get the queue status of multicast entry which learned by hardware. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @param[out] queue queue id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_igmp_mld_entry_queue_get(a_uint32_t dev_id, a_bool_t * enable, + a_uint32_t * queue) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_igmp_mld_entry_queue_get(dev_id, enable, queue); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set IGMP hardware learning count limit on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] cnt limit count + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_port_igmp_mld_learn_limit_set(dev_id, port_id, enable, cnt); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IGMP hardware learning count limit on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @param[out] cnt limit count + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_port_igmp_mld_learn_limit_get(dev_id, port_id, enable, cnt); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set IGMP hardware learning count exceed command on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_port_igmp_mld_learn_exceed_cmd_set(dev_id, port_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IGMP hardware learning count exceed command on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_port_igmp_mld_learn_exceed_cmd_get(dev_id, port_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +isisc_igmp_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->port_igmps_status_set = isisc_port_igmps_status_set; + p_api->port_igmps_status_get = isisc_port_igmps_status_get; + p_api->igmp_mld_cmd_set = isisc_igmp_mld_cmd_set; + p_api->igmp_mld_cmd_get = isisc_igmp_mld_cmd_get; + p_api->port_igmp_join_set = isisc_port_igmp_mld_join_set; + p_api->port_igmp_join_get = isisc_port_igmp_mld_join_get; + p_api->port_igmp_leave_set = isisc_port_igmp_mld_leave_set; + p_api->port_igmp_leave_get = isisc_port_igmp_mld_leave_get; + p_api->igmp_rp_set = isisc_igmp_mld_rp_set; + p_api->igmp_rp_get = isisc_igmp_mld_rp_get; + p_api->igmp_entry_creat_set = isisc_igmp_mld_entry_creat_set; + p_api->igmp_entry_creat_get = isisc_igmp_mld_entry_creat_get; + p_api->igmp_entry_static_set = isisc_igmp_mld_entry_static_set; + p_api->igmp_entry_static_get = isisc_igmp_mld_entry_static_get; + p_api->igmp_entry_leaky_set = isisc_igmp_mld_entry_leaky_set; + p_api->igmp_entry_leaky_get = isisc_igmp_mld_entry_leaky_get; + p_api->igmp_entry_v3_set = isisc_igmp_mld_entry_v3_set; + p_api->igmp_entry_v3_get = isisc_igmp_mld_entry_v3_get; + p_api->igmp_entry_queue_set = isisc_igmp_mld_entry_queue_set; + p_api->igmp_entry_queue_get = isisc_igmp_mld_entry_queue_get; + p_api->port_igmp_mld_learn_limit_set = isisc_port_igmp_mld_learn_limit_set; + p_api->port_igmp_mld_learn_limit_get = isisc_port_igmp_mld_learn_limit_get; + p_api->port_igmp_mld_learn_exceed_cmd_set = isisc_port_igmp_mld_learn_exceed_cmd_set; + p_api->port_igmp_mld_learn_exceed_cmd_get = isisc_port_igmp_mld_learn_exceed_cmd_get; + p_api->igmp_sg_entry_set = isisc_igmp_sg_entry_set; + p_api->igmp_sg_entry_clear = isisc_igmp_sg_entry_clear; + p_api->igmp_sg_entry_show = isisc_igmp_sg_entry_show; + p_api->igmp_sg_entry_query = isisc_igmp_sg_entry_query; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_init.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_init.c new file mode 100755 index 000000000..e55fa18d6 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_init.c @@ -0,0 +1,337 @@ +/* + * Copyright (c) 2012, 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 isisc_init ISISC_INIT + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isisc_mib.h" +#include "isisc_port_ctrl.h" +#include "isisc_portvlan.h" +#include "isisc_vlan.h" +#include "isisc_fdb.h" +#include "isisc_qos.h" +#include "isisc_mirror.h" +#include "isisc_stp.h" +#include "isisc_rate.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" +#if defined(IN_NAT_HELPER) +#include "isisc_nat_helper.h" +#endif +#include "isisc_sec.h" +#include "isisc_trunk.h" +#include "isisc_interface_ctrl.h" +#include "isisc_reg_access.h" +#include "isisc_reg.h" +#include "isisc_init.h" +#include "f1_phy.h" + +static ssdk_init_cfg * isisc_cfg[SW_MAX_NR_DEV] = { 0 }; +a_uint32_t isisc_nat_global_status = 0; + +#if !(defined(KERNEL_MODULE) && defined(USER_MODE)) +/* For isis there are five internal PHY devices and seven MAC devices. + MAC0 always connect to external MAC device. + PHY4 can connect to MAC5 or external MAC device. + MAC6 always connect to external devices. + MAC1..MAC4 connect to internal PHY0..PHY3. +*/ +static sw_error_t +isisc_portproperty_init(a_uint32_t dev_id, hsl_init_mode mode) +{ + hsl_port_prop_t p_type; + hsl_dev_t *pdev = NULL; + fal_port_t port_id; + + pdev = hsl_dev_ptr_get(dev_id); + if (pdev == NULL) + return SW_NOT_INITIALIZED; + + /* for port property set, SSDK should not generate some limitations */ + for (port_id = 0; port_id < pdev->nr_ports; port_id++) + { + hsl_port_prop_portmap_set(dev_id, port_id); + + for (p_type = HSL_PP_PHY; p_type < HSL_PP_BUTT; p_type++) + { + if (HSL_NO_CPU == mode) + { + SW_RTN_ON_ERROR(hsl_port_prop_set(dev_id, port_id, p_type)); + continue; + } + + switch (p_type) + { + case HSL_PP_PHY: + /* Only port0/port6 without PHY device */ + if ((port_id != pdev->cpu_port_nr) + && (port_id != pdev->nr_ports - 1)) + { + SW_RTN_ON_ERROR(hsl_port_prop_set(dev_id, port_id, p_type)); + } + break; + + case HSL_PP_INCL_CPU: + /* include cpu port but exclude wan port in some cases */ + /* but which port is wan port, we are no meaning */ + SW_RTN_ON_ERROR(hsl_port_prop_set(dev_id, port_id, p_type)); + break; + + case HSL_PP_EXCL_CPU: + /* exclude cpu port and wan port in some cases */ + /* which port is wan port, we are no meaning but port0 is + always CPU port */ + if (port_id != pdev->cpu_port_nr) + { + SW_RTN_ON_ERROR(hsl_port_prop_set(dev_id, port_id, p_type)); + } + break; + + default: + break; + } + } + + if (HSL_NO_CPU == mode) + { + SW_RTN_ON_ERROR(hsl_port_prop_set_phyid + (dev_id, port_id, port_id + 1)); + } + else + { + if (port_id != pdev->cpu_port_nr) + { + SW_RTN_ON_ERROR(hsl_port_prop_set_phyid + (dev_id, port_id, port_id - 1)); + } + } + } + + return SW_OK; +} + +static sw_error_t +isisc_hw_init(a_uint32_t dev_id, ssdk_init_cfg *cfg) +{ + return SW_OK; +} + +#endif + +static sw_error_t +isisc_dev_init(a_uint32_t dev_id, hsl_init_mode cpu_mode) +{ + a_uint32_t entry = 0; + sw_error_t rv; + hsl_dev_t *pdev = NULL; + + pdev = hsl_dev_ptr_get(dev_id); + if (pdev == NULL) + return SW_NOT_INITIALIZED; + + HSL_REG_FIELD_GET(rv, dev_id, MASK_CTL, 0, DEVICE_ID, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (S17C_DEVICE_ID == entry) + { + pdev->nr_ports = 7; + pdev->nr_phy = 5; + pdev->cpu_port_nr = 0; + pdev->nr_vlans = 4096; + pdev->hw_vlan_query = A_TRUE; + pdev->nr_queue = 6; + pdev->cpu_mode = cpu_mode; + } + else + { + pdev->nr_ports = 6; + pdev->nr_phy = 5; + pdev->cpu_port_nr = 0; + pdev->nr_vlans = 4096; + pdev->hw_vlan_query = A_TRUE; + pdev->nr_queue = 6; + pdev->cpu_mode = cpu_mode; + } + + return SW_OK; +} + + +static sw_error_t +_isisc_reset(a_uint32_t dev_id) +{ +#if !(defined(KERNEL_MODULE) && defined(USER_MODE)) + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + val = 0x1; + HSL_REG_FIELD_SET(rv, dev_id, MASK_CTL, 0, SOFT_RST, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = isisc_hw_init(dev_id, isisc_cfg[dev_id]); + SW_RTN_ON_ERROR(rv); + + ISISC_ACL_RESET(rv, dev_id); + ISISC_IP_RESET(rv, dev_id); + ISISC_NAT_RESET(rv, dev_id); +#endif + + return SW_OK; +} + +sw_error_t +isisc_cleanup(a_uint32_t dev_id) +{ + sw_error_t rv; + + if (isisc_cfg[dev_id]) + { +#if defined(IN_NAT_HELPER) + if(isisc_nat_global_status) { + ISISC_NAT_HELPER_CLEANUP(rv, dev_id); + isisc_nat_global_status = 0; + } +#endif + + ISISC_ACL_CLEANUP(rv, dev_id); + + SW_RTN_ON_ERROR(hsl_port_prop_cleanup_by_dev(dev_id)); + + aos_mem_free(isisc_cfg[dev_id]); + isisc_cfg[dev_id] = NULL; + } + + return SW_OK; +} + +/** + * @brief reset hsl layer. + * @details Comments: + * This operation will reset hsl layer + * @param[in] dev_id device id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_reset(a_uint32_t dev_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_reset(dev_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Init hsl layer. + * @details Comments: + * This operation will init hsl layer and hsl layer + * @param[in] dev_id device id + * @param[in] cfg configuration for initialization + * @return SW_OK or error code + */ +sw_error_t +isisc_init(a_uint32_t dev_id, ssdk_init_cfg *cfg) +{ + HSL_DEV_ID_CHECK(dev_id); + + if (NULL == isisc_cfg[dev_id]) + { + isisc_cfg[dev_id] = aos_mem_alloc(sizeof (ssdk_init_cfg)); + } + + if (NULL == isisc_cfg[dev_id]) + { + return SW_OUT_OF_MEM; + } + + aos_mem_copy(isisc_cfg[dev_id], cfg, sizeof (ssdk_init_cfg)); + + SW_RTN_ON_ERROR(isisc_reg_access_init(dev_id, cfg->reg_mode)); + + SW_RTN_ON_ERROR(isisc_dev_init(dev_id, cfg->cpu_mode)); + +#if !(defined(KERNEL_MODULE) && defined(USER_MODE)) + { + sw_error_t rv; + + SW_RTN_ON_ERROR(hsl_port_prop_init(dev_id)); + SW_RTN_ON_ERROR(hsl_port_prop_init_by_dev(dev_id)); + SW_RTN_ON_ERROR(isisc_portproperty_init(dev_id, cfg->cpu_mode)); + + ISISC_MIB_INIT(rv, dev_id); + ISISC_PORT_CTRL_INIT(rv, dev_id); + ISISC_PORTVLAN_INIT(rv, dev_id); + ISISC_VLAN_INIT(rv, dev_id); + ISISC_FDB_INIT(rv, dev_id); + ISISC_QOS_INIT(rv, dev_id); + ISISC_STP_INIT(rv, dev_id); + ISISC_MIRR_INIT(rv, dev_id); + ISISC_RATE_INIT(rv, dev_id); + ISISC_MISC_INIT(rv, dev_id); + ISISC_LEAKY_INIT(rv, dev_id); + ISISC_IGMP_INIT(rv, dev_id); + ISISC_ACL_INIT(rv, dev_id); + ISISC_LED_INIT(rv, dev_id); + ISISC_COSMAP_INIT(rv, dev_id); + ISISC_IP_INIT(rv, dev_id); + ISISC_NAT_INIT(rv, dev_id); + ISISC_TRUNK_INIT(rv, dev_id); + ISISC_SEC_INIT(rv, dev_id); + ISISC_INTERFACE_CTRL_INIT(rv, dev_id); + + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->dev_reset = isisc_reset; + p_api->dev_clean = isisc_cleanup; + } + + SW_RTN_ON_ERROR(isisc_hw_init(dev_id, cfg)); +#if 0 +#if defined(IN_NAT_HELPER) + if(!isisc_nat_global_status) { + ISISC_NAT_HELPER_INIT(rv, dev_id); + isisc_nat_global_status = 1; + } + +#endif +#endif + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_interface_ctrl.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_interface_ctrl.c new file mode 100755 index 000000000..7c45a34ae --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_interface_ctrl.c @@ -0,0 +1,2324 @@ +/* + * Copyright (c) 2012, 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 isisc_interface_ctrl ISISC_INTERFACE_CONTROL + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isisc_interface_ctrl.h" +#include "isisc_reg.h" +#include "hsl_phy.h" + +#define ISISC_MAC_0 0 +#define ISISC_MAC_5 5 +#define ISISC_MAC_6 6 + +#define ISISC_PHY_MODE_PHY_ID 4 +#define ISISC_LPI_PORT1_OFFSET 4 +#define ISISC_LPI_BIT_STEP 2 + +/* we need to do more about MAC5/PHY4 connection... */ +#if 0 +static sw_error_t +_isisc_port_mac5_internal_mode(a_uint32_t dev_id, a_bool_t * inter_mode) +{ + sw_error_t rv; + a_uint32_t reg, rgmii, gmii_mac, gmii_phy, mii_mac, mii_phy, sgmii; + + HSL_REG_ENTRY_GET(rv, dev_id, PORT5_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_RGMII_EN, rgmii, reg); + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_MAC_GMII_EN, gmii_mac, reg); + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_PHY_GMII_EN, gmii_phy, reg); + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_MAC_MII_EN, mii_mac, reg); + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_PHY_MII_EN, mii_phy, reg); + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_SGMII_EN, sgmii, reg); + + if (rgmii || gmii_mac || gmii_phy || mii_mac || mii_phy || sgmii) + { + *inter_mode = A_FALSE; + } + else + { + *inter_mode = A_TRUE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_port_phy4_internal_mode(a_uint32_t dev_id, a_bool_t * inter_mode) +{ + sw_error_t rv; + a_uint32_t reg, rgmii, gmii, mii; + + HSL_REG_ENTRY_GET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT6_PAD_CTRL, PHY4_RGMII_EN, rgmii, reg); + SW_GET_FIELD_BY_REG(PORT6_PAD_CTRL, PHY4_GMII_EN, gmii, reg); + SW_GET_FIELD_BY_REG(PORT6_PAD_CTRL, PHY4_MII_EN, mii, reg); + + if (rgmii || gmii || mii) + { + *inter_mode = A_FALSE; + } + else + { + *inter_mode = A_TRUE; + } + + return SW_OK; +} +#endif + +static sw_error_t +_isisc_port_3az_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t reg = 0, field, offset, device_id, rev_id, reverse = 0; + + HSL_REG_ENTRY_GET(rv, dev_id, MASK_CTL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(MASK_CTL, DEVICE_ID, device_id, reg); + if (S17C_DEVICE_ID != device_id) + { + return SW_NOT_SUPPORTED; + } + + SW_GET_FIELD_BY_REG(MASK_CTL, REV_ID, rev_id, reg); + if (S17_REVISION_A == rev_id) + { + reverse = 0; + } + else + { + reverse = 1; + } + + if (rev_id == 0) + { + reverse = 1; + } + else + { + reverse = 0; + } + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, EEE_CTL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + field = 1; + } + else if (A_FALSE == enable) + { + field = 0; + } + else + { + return SW_BAD_PARAM; + } + + if (reverse) + { + field = (~field) & 0x1UL; + } + + offset = (port_id - 1) * ISISC_LPI_BIT_STEP + ISISC_LPI_PORT1_OFFSET; + reg &= (~(0x1UL << offset)); + reg |= (field << offset); + + HSL_REG_ENTRY_SET(rv, dev_id, EEE_CTL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_port_3az_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t reg = 0, field, offset, device_id, rev_id, reverse = 0; + + HSL_REG_ENTRY_GET(rv, dev_id, MASK_CTL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(MASK_CTL, DEVICE_ID, device_id, reg); + if (S17C_DEVICE_ID != device_id) + { + return SW_NOT_SUPPORTED; + } + + SW_GET_FIELD_BY_REG(MASK_CTL, REV_ID, rev_id, reg); + if (S17_REVISION_A == rev_id) + { + reverse = 0; + } + else + { + reverse = 1; + } + + if (rev_id == 0) + { + reverse = 1; + } + else + { + reverse = 0; + } + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, EEE_CTL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + offset = (port_id - 1) * ISISC_LPI_BIT_STEP + ISISC_LPI_PORT1_OFFSET; + field = (reg >> offset) & 0x1; + + if (reverse) + { + field = (~field) & 0x1UL; + } + + if (field) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_port_rgmii_mode_set(a_uint32_t dev_id, fal_port_t port_id, fal_mac_rgmii_config_t * config) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + if (ISISC_MAC_0 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISISC_MAC_5 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT5_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISISC_MAC_6 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_SGMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, RMII_MASTER_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, RMII_SLAVE_EN, 0, reg); + + /* hardware suggestions: restore to defatult settings */ + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_RXCLK_SEL, 0, reg); + + if (A_TRUE == config->txclk_delay_cmd) + { + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_TXCLK_DELAY_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_TXCLK_DELAY_SEL, config->txclk_delay_sel, reg); + } + else + { + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_TXCLK_DELAY_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_TXCLK_DELAY_SEL, 0, reg); + } + + if (A_TRUE == config->rxclk_delay_cmd) + { + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_RXCLK_DELAY_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_RXCLK_DELAY_SEL, config->rxclk_delay_sel, reg); + } + else + { + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_RXCLK_DELAY_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_RXCLK_DELAY_SEL, 0, reg); + } + + if (ISISC_MAC_0 == port_id) + { + HSL_REG_ENTRY_SET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISISC_MAC_5 == port_id) + { + HSL_REG_ENTRY_SET(rv, dev_id, PORT5_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + HSL_REG_ENTRY_SET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + SW_RTN_ON_ERROR(rv); + + /* Port status register setting */ + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + /* setting port status default configuration */ + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, FLOW_LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, RX_FLOW_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TX_FLOW_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, DUPLEX_MODE, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, RXMAC_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TXMAC_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, SPEED_MODE, 2, reg); + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_port_rgmii_mode_get(a_uint32_t dev_id, fal_port_t port_id, fal_mac_rgmii_config_t * config) +{ + sw_error_t rv; + a_uint32_t reg = 0, field; + + if (ISISC_MAC_0 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISISC_MAC_5 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT5_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISISC_MAC_6 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_RGMII_TXCLK_DELAY_EN, field, reg); + if (field) + { + config->txclk_delay_cmd = A_TRUE; + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_RGMII_TXCLK_DELAY_SEL, field, reg); + config->txclk_delay_sel = field; + } + else + { + config->txclk_delay_cmd = A_FALSE; + config->txclk_delay_sel = 0; + } + + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_RGMII_RXCLK_DELAY_EN, field, reg); + if (field) + { + config->rxclk_delay_cmd = A_TRUE; + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_RGMII_RXCLK_DELAY_SEL, field, reg); + config->rxclk_delay_sel = field; + } + else + { + config->rxclk_delay_cmd = A_FALSE; + config->rxclk_delay_sel = 0; + } + + return SW_OK; +} + +static sw_error_t +_isisc_interface_mac06_exch_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + + HSL_REG_ENTRY_GET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, RMII_MAC06_EXCH_EN, 1, reg); + } + else + { + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, RMII_MAC06_EXCH_EN, 0, reg); + } + + HSL_REG_ENTRY_SET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_isisc_interface_mac06_exch_get(a_uint32_t dev_id, a_bool_t* enable) +{ + sw_error_t rv; + a_uint32_t reg = 0,field; + + + HSL_REG_ENTRY_GET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, RMII_MAC06_EXCH_EN, field, reg); + if (field) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return rv; +} + + +static sw_error_t +_isisc_interface_mac_sgmii_set(a_uint32_t dev_id,a_uint32_t value) +{ + sw_error_t rv; + a_uint32_t reg; + reg = value; + + HSL_REG_ENTRY_SET(rv, dev_id, SGMII_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_isisc_interface_mac_sgmii_get(a_uint32_t dev_id, a_uint32_t *value) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + HSL_REG_ENTRY_GET(rv, dev_id, SGMII_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + *value = reg; + + return rv; +} + +static sw_error_t +_isisc_interface_mac_pad_set(a_uint32_t dev_id,a_uint32_t port_num, a_uint32_t value) +{ + sw_error_t rv; + a_uint32_t reg; + + reg = value; + + switch (port_num) + { + case ISISC_MAC_0: + HSL_REG_ENTRY_SET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + break; + case ISISC_MAC_5: + HSL_REG_ENTRY_SET(rv, dev_id, PORT5_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + break; + case ISISC_MAC_6: + HSL_REG_ENTRY_SET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + break; + default: + return SW_BAD_PARAM; + } + + return rv; +} + +static sw_error_t +_isisc_interface_mac_pad_get(a_uint32_t dev_id,a_uint32_t port_num, a_uint32_t *value) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + switch (port_num) + { + case ISISC_MAC_0: + HSL_REG_ENTRY_GET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + break; + case ISISC_MAC_5: + HSL_REG_ENTRY_GET(rv, dev_id, PORT5_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + break; + case ISISC_MAC_6: + HSL_REG_ENTRY_GET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + break; + default: + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + *value = reg; + + return rv; +} + + + +static sw_error_t +_isisc_port_rmii_mode_set(a_uint32_t dev_id, fal_port_t port_id, fal_mac_rmii_config_t * config) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + if (ISISC_MAC_0 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + + if (config->master_mode == config->slave_mode) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_ERROR(rv); + if (A_TRUE == config->master_mode) + { + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, RMII_MASTER_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, RMII_SLAVE_EN, 0, reg); + } + else + { + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, RMII_MASTER_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, RMII_SLAVE_EN, 1, reg); + } + + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_SGMII_EN, 0, reg); + + /* hardware suggestions: restore to defatult settings */ + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_RXCLK_SEL, 0, reg); + + if (A_TRUE == config->clock_inverse) + { + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, RMII_SEL, 1, reg); + } + else + { + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, RMII_SEL, 0, reg); + } + + if (A_TRUE == config->pipe_rxclk_sel) + { + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, RMII_PIPE_RXCLK_SEL, 1, reg); + } + else + { + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, RMII_PIPE_RXCLK_SEL, 0, reg); + } + + if (ISISC_MAC_0 == port_id) + { + HSL_REG_ENTRY_SET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + + SW_RTN_ON_ERROR(rv); + + /* Port status register setting */ + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + /* setting port status default configuration */ + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, FLOW_LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, RX_FLOW_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TX_FLOW_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, DUPLEX_MODE, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, RXMAC_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TXMAC_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, SPEED_MODE, 2, reg); + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_port_rmii_mode_get(a_uint32_t dev_id, fal_port_t port_id, fal_mac_rmii_config_t * config) +{ + sw_error_t rv; + a_uint32_t reg = 0, field; + + if (ISISC_MAC_0 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, RMII_MASTER_EN, field, reg); + if (field) + { + config->master_mode = A_TRUE; + } + else + { + config->master_mode = A_FALSE; + } + + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, RMII_SLAVE_EN, field, reg); + if (field) + { + config->slave_mode = A_TRUE; + } + else + { + config->slave_mode = A_FALSE; + } + + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, RMII_SEL, field, reg); + if (field) + { + config->clock_inverse = A_TRUE; + } + else + { + config->clock_inverse = A_FALSE; + } + + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, RMII_PIPE_RXCLK_SEL, field, reg); + if (field) + { + config->pipe_rxclk_sel = A_TRUE; + } + else + { + config->pipe_rxclk_sel = A_FALSE; + } + + + return SW_OK; +} + +static sw_error_t +_isisc_port_gmii_mode_set(a_uint32_t dev_id, fal_port_t port_id, fal_mac_gmii_config_t * config) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + if (ISISC_MAC_0 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_SGMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, RMII_MASTER_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, RMII_SLAVE_EN, 0, reg); + + /* hardware suggestions: restore to defatult settings */ + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_TXCLK_DELAY_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_RXCLK_DELAY_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_TXCLK_DELAY_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_RXCLK_DELAY_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_RXCLK_SEL, 0, reg); + + if (FAL_INTERFACE_CLOCK_PHY_MODE == config->clock_mode) + { + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_TXCLK_SEL, config->txclk_select, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_RXCLK_SEL, config->rxclk_select, reg); + + } + else if (FAL_INTERFACE_CLOCK_MAC_MODE == config->clock_mode) + { + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_TXCLK_SEL, config->txclk_select, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_RXCLK_SEL, config->rxclk_select, reg); + + } + else + { + return SW_BAD_PARAM; + } + + if (ISISC_MAC_0 == port_id) + { + HSL_REG_ENTRY_SET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + HSL_REG_ENTRY_SET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + SW_RTN_ON_ERROR(rv); + + /* Port status register setting */ + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + /* setting port status default configuration */ + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, FLOW_LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, RX_FLOW_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TX_FLOW_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, DUPLEX_MODE, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, RXMAC_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TXMAC_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, SPEED_MODE, 2, reg); + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_port_gmii_mode_get(a_uint32_t dev_id, fal_port_t port_id, fal_mac_gmii_config_t * config) +{ + sw_error_t rv; + a_uint32_t reg = 0, field; + + if (ISISC_MAC_0 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISISC_MAC_6 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_PHY_GMII_EN, field, reg); + if (field) + { + config->clock_mode = FAL_INTERFACE_CLOCK_PHY_MODE; + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_PHY_GMII_TXCLK_SEL, field, reg); + config->txclk_select = field; + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_PHY_GMII_RXCLK_SEL, field, reg); + config->rxclk_select = field; + + } + else + { + config->clock_mode = FAL_INTERFACE_CLOCK_MAC_MODE; + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_MAC_GMII_TXCLK_SEL, field, reg); + config->txclk_select = field; + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_MAC_GMII_RXCLK_SEL, field, reg); + config->rxclk_select = field; + } + + return SW_OK; +} + +static sw_error_t +_isisc_port_mii_mode_set(a_uint32_t dev_id, fal_port_t port_id, fal_mac_mii_config_t * config) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + if (ISISC_MAC_0 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISISC_MAC_5 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT5_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISISC_MAC_6 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_SGMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, RMII_MASTER_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, RMII_SLAVE_EN, 0, reg); + + /* hardware suggestions: restore to defatult settings */ + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_TXCLK_DELAY_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_RXCLK_DELAY_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_TXCLK_DELAY_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_RXCLK_DELAY_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_RXCLK_SEL, 0, reg); + + if (FAL_INTERFACE_CLOCK_PHY_MODE == config->clock_mode) + { + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_TXCLK_SEL, config->txclk_select, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_RXCLK_SEL, config->rxclk_select, reg); + } + else if (FAL_INTERFACE_CLOCK_MAC_MODE == config->clock_mode) + { + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_TXCLK_SEL, config->txclk_select, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_RXCLK_SEL, config->rxclk_select, reg); + } + else + { + return SW_BAD_PARAM; + } + + if (ISISC_MAC_0 == port_id) + { + HSL_REG_ENTRY_SET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISISC_MAC_5 == port_id) + { + HSL_REG_ENTRY_SET(rv, dev_id, PORT5_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + HSL_REG_ENTRY_SET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + SW_RTN_ON_ERROR(rv); + + /* Port status register setting */ + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + /* setting port status default configuration */ + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, FLOW_LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, RX_FLOW_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TX_FLOW_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, DUPLEX_MODE, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, RXMAC_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TXMAC_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, SPEED_MODE, 1, reg); + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_port_mii_mode_get(a_uint32_t dev_id, fal_port_t port_id, fal_mac_mii_config_t * config) +{ + sw_error_t rv; + a_uint32_t reg = 0, field; + + if (ISISC_MAC_0 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISISC_MAC_5 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT5_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISISC_MAC_6 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_PHY_MII_EN, field, reg); + if (field) + { + config->clock_mode = FAL_INTERFACE_CLOCK_PHY_MODE; + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_PHY_MII_TXCLK_SEL, field, reg); + config->txclk_select = field; + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_PHY_MII_RXCLK_SEL, field, reg); + config->rxclk_select = field; + } + else + { + config->clock_mode = FAL_INTERFACE_CLOCK_MAC_MODE; + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_MAC_MII_TXCLK_SEL, field, reg); + config->txclk_select = field; + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_MAC_MII_RXCLK_SEL, field, reg); + config->rxclk_select = field; + } + + return SW_OK; +} + +static sw_error_t +_isisc_port_sgmii_mode_set(a_uint32_t dev_id, fal_port_t port_id, fal_mac_sgmii_config_t * config) +{ + sw_error_t rv; + a_uint32_t reg = 0, field; + + if (ISISC_MAC_0 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISISC_MAC_6 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_SGMII_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, RMII_MASTER_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, RMII_SLAVE_EN, 0, reg); + + /* hardware suggestions: restore to defatult settings */ + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_TXCLK_DELAY_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_RXCLK_DELAY_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_TXCLK_DELAY_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_RXCLK_DELAY_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_RXCLK_SEL, 0, reg); + + + if (A_TRUE == config->force_speed) + { + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_SGMII_FORCE_SPEED, 1, reg); + } + else + { + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_SGMII_FORCE_SPEED, 0, reg); + } + + if (A_TRUE == config->prbs_enable) + { + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, SGMII_PRBS_BERT_EN, 1, reg); + } + else + { + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, SGMII_PRBS_BERT_EN, 0, reg); + } + + if (A_TRUE == config->rem_phy_lpbk) + { + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, SGMII_REM_PHY_LPBK_EN, 1, reg); + } + else + { + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, SGMII_REM_PHY_LPBK_EN, 0, reg); + } + + if (ISISC_MAC_0 == port_id) + { + HSL_REG_ENTRY_SET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* only support one SGMII interface, so we need to disable another SGMII */ + field = 0; + HSL_REG_FIELD_SET(rv, dev_id, PORT6_PAD_CTRL, port_id, MAC6_SGMII_EN, + (a_uint8_t *) (&field), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else + { + HSL_REG_ENTRY_SET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* only support one SGMII interface, so we need to disable another SGMII */ + field = 0; + HSL_REG_FIELD_SET(rv, dev_id, PORT0_PAD_CTRL, port_id, MAC0_SGMII_EN, + (a_uint8_t *) (&field), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + /* SGMII global settings, for all SGMII interfaces, now we fix all the values */ + /* TX/RX clock setting */ + HSL_REG_ENTRY_GET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, SGMII_CLK125M_RX_SEL, 1, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, SGMII_CLK125M_TX_SEL, 0, reg); + + HSL_REG_ENTRY_SET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* SGMII control register setting */ + HSL_REG_ENTRY_GET(rv, dev_id, SGMII_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(SGMII_CTRL, SGMII_FIBER_MODE, 0, reg); + SW_SET_REG_BY_FIELD(SGMII_CTRL, SGMII_EN_PLL, 1, reg); + SW_SET_REG_BY_FIELD(SGMII_CTRL, SGMII_EN_RX, 1, reg); + SW_SET_REG_BY_FIELD(SGMII_CTRL, SGMII_EN_TX, 1, reg); + SW_SET_REG_BY_FIELD(SGMII_CTRL, SGMII_EN_SD, 1, reg); + if (FAL_INTERFACE_CLOCK_PHY_MODE == config->clock_mode) + { + SW_SET_REG_BY_FIELD(SGMII_CTRL, MODE_CTRL_25M, 1, reg); + } + else + { + SW_SET_REG_BY_FIELD(SGMII_CTRL, MODE_CTRL_25M, 2, reg); + } + HSL_REG_ENTRY_SET(rv, dev_id, SGMII_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* Port status register setting */ + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + /* setting port status default configuration */ + SW_SET_REG_BY_FIELD(PORT_STATUS, FLOW_LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, RX_FLOW_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TX_FLOW_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, DUPLEX_MODE, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, RXMAC_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TXMAC_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, SPEED_MODE, 2, reg); + if (A_TRUE == config->auto_neg) + { + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 1, reg); + } + else + { + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 0, reg); + } + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_port_sgmii_mode_get(a_uint32_t dev_id, fal_port_t port_id, fal_mac_sgmii_config_t * config) +{ + sw_error_t rv; + a_uint32_t reg = 0, field; + + if (ISISC_MAC_0 == port_id) + { + /* nothing to do */ + } + else if (ISISC_MAC_6 == port_id) + { + /* nothing to do */ + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_STATUS, LINK_EN, field, reg); + if (field) + { + config->auto_neg = A_TRUE; + } + else + { + config->auto_neg = A_FALSE; + } + + HSL_REG_ENTRY_GET(rv, dev_id, SGMII_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + SW_GET_FIELD_BY_REG(SGMII_CTRL, MODE_CTRL_25M, field, reg); + if (1 == field) + { + config->clock_mode = FAL_INTERFACE_CLOCK_PHY_MODE; + } + else + { + config->clock_mode = FAL_INTERFACE_CLOCK_MAC_MODE; + } + HSL_REG_ENTRY_GET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, SGMII_PRBS_BERT_EN, field, reg); + if (1 == field) + { + config->prbs_enable = A_TRUE; + } + else + { + config->prbs_enable = A_FALSE; + } + + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, SGMII_REM_PHY_LPBK_EN, field, reg); + if (1 == field) + { + config->rem_phy_lpbk = A_TRUE; + } + else + { + config->rem_phy_lpbk = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_port_fiber_mode_set(a_uint32_t dev_id, fal_port_t port_id, fal_mac_fiber_config_t * config) +{ + sw_error_t rv; + a_uint32_t reg = 0, field; + + if (ISISC_MAC_0 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISISC_MAC_6 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_SGMII_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, RMII_MASTER_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, RMII_SLAVE_EN, 0, reg); + + /* hardware suggestions: restore to defatult settings */ + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_TXCLK_DELAY_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_RXCLK_DELAY_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_TXCLK_DELAY_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_RXCLK_DELAY_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_RXCLK_SEL, 0, reg); + + if (ISISC_MAC_0 == port_id) + { + HSL_REG_ENTRY_SET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* only support one SGMII interface, so we need to disable another SGMII */ + field = 0; + HSL_REG_FIELD_SET(rv, dev_id, PORT6_PAD_CTRL, port_id, MAC6_SGMII_EN, + (a_uint8_t *) (&field), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else + { + HSL_REG_ENTRY_SET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* only support one SGMII interface, so we need to disable another SGMII */ + field = 0; + HSL_REG_FIELD_SET(rv, dev_id, PORT0_PAD_CTRL, port_id, MAC0_SGMII_EN, + (a_uint8_t *) (&field), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + /* SGMII global settings, for all SGMII interfaces, now we fix all the values */ + /* TX/RX clock setting */ + HSL_REG_ENTRY_GET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, SGMII_CLK125M_RX_SEL, 1, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, SGMII_CLK125M_TX_SEL, 0, reg); + + if (A_TRUE == config->fx100_enable) + { + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, SGMII_FX100_EN, 1, reg); + } + else + { + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, SGMII_FX100_EN, 0, reg); + } + + HSL_REG_ENTRY_SET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* SGMII control register setting */ + HSL_REG_ENTRY_GET(rv, dev_id, SGMII_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(SGMII_CTRL, MODE_CTRL_25M, 0, reg); + SW_SET_REG_BY_FIELD(SGMII_CTRL, SGMII_FIBER_MODE, 3, reg); + SW_SET_REG_BY_FIELD(SGMII_CTRL, SGMII_EN_PLL, 1, reg); + SW_SET_REG_BY_FIELD(SGMII_CTRL, SGMII_EN_RX, 1, reg); + SW_SET_REG_BY_FIELD(SGMII_CTRL, SGMII_EN_TX, 1, reg); + SW_SET_REG_BY_FIELD(SGMII_CTRL, SGMII_EN_SD, 1, reg); + + HSL_REG_ENTRY_SET(rv, dev_id, SGMII_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* Power on strip register setting */ + HSL_REG_ENTRY_GET(rv, dev_id, POWER_STRIP, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + if (A_TRUE == config->auto_neg) + { + SW_SET_REG_BY_FIELD(POWER_STRIP, SERDES_AN_EN, 1, reg); + } + else + { + SW_SET_REG_BY_FIELD(POWER_STRIP, SERDES_AN_EN, 0, reg); + } + HSL_REG_ENTRY_SET(rv, dev_id, POWER_STRIP, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + /* Port status register setting */ + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + /* setting port status default configuration */ + SW_SET_REG_BY_FIELD(PORT_STATUS, FLOW_LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, RX_FLOW_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TX_FLOW_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, DUPLEX_MODE, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, RXMAC_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TXMAC_EN, 1, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, SPEED_MODE, 2, reg); + if (A_TRUE == config->auto_neg) + { + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 1, reg); + } + else + { + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 0, reg); + } + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_port_fiber_mode_get(a_uint32_t dev_id, fal_port_t port_id, fal_mac_fiber_config_t * config) +{ + sw_error_t rv; + a_uint32_t reg = 0, field; + + if (ISISC_MAC_0 == port_id) + { + /* nothing to do */ + } + else if (ISISC_MAC_6 == port_id) + { + /* nothing to do */ + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, POWER_STRIP, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(POWER_STRIP, SERDES_AN_EN, field, reg); + if (field) + { + config->auto_neg = A_TRUE; + } + else + { + config->auto_neg = A_FALSE; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, SGMII_FX100_EN, field, reg); + + if (field) + { + config->fx100_enable = A_TRUE; + } + else + { + config->fx100_enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_port_default_mode_set(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + if (ISISC_MAC_0 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISISC_MAC_5 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT5_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISISC_MAC_6 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_SGMII_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, RMII_MASTER_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, RMII_SLAVE_EN, 0, reg); + + /* hardware suggestions: restore to defatult settings */ + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_TXCLK_DELAY_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_RXCLK_DELAY_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_TXCLK_DELAY_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_RGMII_RXCLK_DELAY_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_GMII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_PHY_MII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_GMII_RXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_TXCLK_SEL, 0, reg); + SW_SET_REG_BY_FIELD(PORT0_PAD_CTRL, MAC0_MAC_MII_RXCLK_SEL, 0, reg); + + if (ISISC_MAC_0 == port_id) + { + HSL_REG_ENTRY_SET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISISC_MAC_5 == port_id) + { + HSL_REG_ENTRY_SET(rv, dev_id, PORT5_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + HSL_REG_ENTRY_SET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + + return rv; +} + +static sw_error_t +_isisc_interface_mac_mode_set(a_uint32_t dev_id, fal_port_t port_id, fal_mac_config_t * config) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_MAC_MODE_RGMII == config->mac_mode) + { + rv = _isisc_port_rgmii_mode_set(dev_id, port_id, &(config->config.rgmii)); + } + else if (FAL_MAC_MODE_GMII == config->mac_mode) + { + rv = _isisc_port_gmii_mode_set(dev_id, port_id, &(config->config.gmii)); + } + else if (FAL_MAC_MODE_MII == config->mac_mode) + { + rv = _isisc_port_mii_mode_set(dev_id, port_id, &(config->config.mii)); + } + else if (FAL_MAC_MODE_SGMII == config->mac_mode) + { + rv = _isisc_port_sgmii_mode_set(dev_id, port_id, &(config->config.sgmii)); + } + else if (FAL_MAC_MODE_FIBER == config->mac_mode) + { + rv = _isisc_port_fiber_mode_set(dev_id, port_id, &(config->config.fiber)); + } + else if (FAL_MAC_MODE_DEFAULT == config->mac_mode) + { + rv = _isisc_port_default_mode_set(dev_id, port_id); + } + else if (FAL_MAC_MODE_RMII == config->mac_mode) + { + rv = _isisc_port_rmii_mode_set(dev_id, port_id, &(config->config.rmii)); + } + else + { + return SW_BAD_PARAM; + } + + return rv; +} + +static sw_error_t +_isisc_interface_mac_mode_get(a_uint32_t dev_id, fal_port_t port_id, fal_mac_config_t * config) +{ + sw_error_t rv; + a_uint32_t reg = 0, field, field2; + + HSL_DEV_ID_CHECK(dev_id); + + if (ISISC_MAC_0 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT0_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISISC_MAC_5 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT5_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else if (ISISC_MAC_6 == port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + aos_mem_zero(config, sizeof(fal_interface_mac_mode_t)); + + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_RGMII_EN, field, reg); + if (field) + { + config->mac_mode = FAL_MAC_MODE_RGMII; + rv = _isisc_port_rgmii_mode_get(dev_id, port_id, &(config->config.rgmii)); + return rv; + } + + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, RMII_MASTER_EN, field, reg); + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, RMII_SLAVE_EN, field2, reg); + if (field || field2) + { + config->mac_mode = FAL_MAC_MODE_RMII; + rv = _isisc_port_rmii_mode_get(dev_id, port_id, &(config->config.rmii)); + return rv; + } + + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_MAC_GMII_EN, field, reg); + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_PHY_GMII_EN, field2, reg); + if (field || field2) + { + config->mac_mode = FAL_MAC_MODE_GMII; + rv = _isisc_port_gmii_mode_get(dev_id, port_id, &(config->config.gmii)); + return rv; + } + + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_MAC_MII_EN, field, reg); + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_PHY_MII_EN, field2, reg); + if (field || field2) + { + config->mac_mode = FAL_MAC_MODE_MII; + rv = _isisc_port_mii_mode_get(dev_id, port_id, &(config->config.mii)); + return rv; + } + + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_SGMII_EN, field, reg); + SW_GET_FIELD_BY_REG(PORT0_PAD_CTRL, MAC0_MAC_SGMII_FORCE_SPEED, field2, reg); + + if (field) + { + HSL_REG_ENTRY_GET(rv, dev_id, SGMII_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(SGMII_CTRL, SGMII_FIBER_MODE, field, reg); + if (3 == field) + { + config->mac_mode = FAL_MAC_MODE_FIBER; + rv = _isisc_port_fiber_mode_get(dev_id, port_id, &(config->config.fiber)); + } + else + { + config->mac_mode = FAL_MAC_MODE_SGMII; + rv = _isisc_port_sgmii_mode_get(dev_id, port_id, &(config->config.sgmii)); + if (field2) + config->config.sgmii.force_speed = A_TRUE; + else + config->config.sgmii.force_speed = A_FALSE; + } + return rv; + } + + config->mac_mode = FAL_MAC_MODE_DEFAULT; + return SW_OK; +} + +static sw_error_t +_isisc_interface_phy_mode_set(a_uint32_t dev_id, a_uint32_t phy_id, fal_phy_config_t * config) +{ + sw_error_t rv; + a_uint16_t data; + a_bool_t tx_delay_cmd, rx_delay_cmd; + hsl_phy_ops_t *phy_drv; + a_uint32_t reg, rgmii_mode, tx_delay = 2, port_id; + + HSL_DEV_ID_CHECK(dev_id); + + /* only PHY4 support mode setting */ + if (ISISC_PHY_MODE_PHY_ID != phy_id) + { + return SW_BAD_PARAM; + } + + port_id = qca_ssdk_phy_addr_to_port(dev_id, phy_id); + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get(dev_id, port_id)); + if ((NULL == phy_drv->phy_debug_write) || (NULL == phy_drv->phy_debug_read)) + return SW_NOT_SUPPORTED; + + HSL_REG_ENTRY_GET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_MAC_MODE_RGMII == config->mac_mode) + { + SW_SET_REG_BY_FIELD(PORT6_PAD_CTRL, PHY4_RGMII_EN, 1, reg); + rgmii_mode = 1; + /* PHY TX delay */ + if (A_TRUE == config->txclk_delay_cmd) + { + tx_delay_cmd = A_TRUE; + tx_delay = config->txclk_delay_sel; + } + else + { + tx_delay_cmd = A_FALSE; + } + + /* PHY RX delay */ + if (A_TRUE == config->rxclk_delay_cmd) + { + rx_delay_cmd = A_TRUE; + } + else + { + rx_delay_cmd = A_FALSE; + } + } + else if (FAL_MAC_MODE_DEFAULT == config->mac_mode) + { + SW_SET_REG_BY_FIELD(PORT6_PAD_CTRL, PHY4_RGMII_EN, 0, reg); + rgmii_mode = 0; + tx_delay_cmd = A_FALSE; + rx_delay_cmd = A_FALSE; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_SET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* PHY RGMII mode, debug register18 bit3 */ + data = phy_drv->phy_debug_read(dev_id, ISISC_PHY_MODE_PHY_ID, 18); + data &= 0xfff7UL; + data |= ((rgmii_mode & 0x1) << 3); + rv = phy_drv->phy_debug_write(dev_id, ISISC_PHY_MODE_PHY_ID, 18, data); + SW_RTN_ON_ERROR(rv); + + /* PHY TX delay command, debug regigster5 bit8 */ + data = phy_drv->phy_debug_read(dev_id, ISISC_PHY_MODE_PHY_ID, 5); + if (A_TRUE == tx_delay_cmd) + { + data |= 0x0100UL; + } + else + { + data &= 0xfeffUL; + } + rv = phy_drv->phy_debug_write(dev_id, ISISC_PHY_MODE_PHY_ID, 5, data); + SW_RTN_ON_ERROR(rv); + + /* PHY TX delay select, debug register11 bit-6 */ + data = phy_drv->phy_debug_read(dev_id, ISISC_PHY_MODE_PHY_ID, 11); + data &= 0xff9fUL; + data |= ((tx_delay & 0x3UL) << 5); + if (A_TRUE == tx_delay_cmd) + { + data |= 0x0100UL; + } + else + { + data &= 0xfeffUL; + } + rv = phy_drv->phy_debug_write(dev_id, ISISC_PHY_MODE_PHY_ID, 11, data); + SW_RTN_ON_ERROR(rv); + + /* PHY RX delay command, debug regigster0 bit15 */ + data = phy_drv->phy_debug_read(dev_id, ISISC_PHY_MODE_PHY_ID, 0); + if (A_TRUE == rx_delay_cmd) + { + data |= 0x8000UL; + } + else + { + data &= 0x7fffUL; + } + rv = phy_drv->phy_debug_write(dev_id, ISISC_PHY_MODE_PHY_ID, 0, data); + SW_RTN_ON_ERROR(rv); + + /* PHY RX delay select, now hardware not support */ + + return SW_OK; +} + +static sw_error_t +_isisc_interface_phy_mode_get(a_uint32_t dev_id, a_uint32_t phy_id, fal_phy_config_t * config) +{ + sw_error_t rv; + a_uint16_t data; + a_uint32_t reg = 0, rgmii, port_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + /* only one PHY device support this */ + if (ISISC_PHY_MODE_PHY_ID != phy_id) + { + return SW_BAD_PARAM; + } + + port_id = qca_ssdk_phy_addr_to_port(dev_id, phy_id); + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get(dev_id, port_id)); + if (NULL == phy_drv->phy_debug_read) + return SW_NOT_SUPPORTED; + + aos_mem_zero(config, sizeof(fal_phy_config_t)); + + HSL_REG_ENTRY_GET(rv, dev_id, PORT6_PAD_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT6_PAD_CTRL, PHY4_RGMII_EN, rgmii, reg); + + if (rgmii) + { + config->mac_mode = FAL_MAC_MODE_RGMII; + data = phy_drv->phy_debug_read(dev_id, ISISC_PHY_MODE_PHY_ID, 5); + if (data & 0x0100) + { + config->txclk_delay_cmd = A_TRUE; + data = phy_drv->phy_debug_read(dev_id, ISISC_PHY_MODE_PHY_ID, 11); + config->txclk_delay_sel = (data >> 5) & 0x3UL; + } + else + { + config->txclk_delay_cmd = A_FALSE; + } + + data = phy_drv->phy_debug_read(dev_id, ISISC_PHY_MODE_PHY_ID, 0); + if (data & 0x8000) + { + config->rxclk_delay_cmd = A_TRUE; + } + else + { + config->rxclk_delay_cmd = A_FALSE; + } + } + else + { + config->mac_mode = FAL_MAC_MODE_DEFAULT; + } + + return SW_OK; +} + +static sw_error_t +_isisc_interface_fx100_ctrl_set(a_uint32_t dev_id, fal_fx100_ctrl_config_t* config) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_ENTRY_GET(rv, dev_id, FX100_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (Fx100BASE_MODE == config->link_mode) + { + SW_SET_REG_BY_FIELD(FX100_CTRL, LINK_CTRL, Fx100BASE_MODE, reg); + } + else + { + return SW_BAD_PARAM; + } + + if (A_TRUE == config->overshoot) + { + SW_SET_REG_BY_FIELD(FX100_CTRL, OVERSHOOT_MODE, 1, reg); + } + else + { + SW_SET_REG_BY_FIELD(FX100_CTRL, OVERSHOOT_MODE, 0, reg); + } + + if (A_TRUE == config->loopback) + { + SW_SET_REG_BY_FIELD(FX100_CTRL, LOOPBACK_MODE, 1, reg); + } + else + { + SW_SET_REG_BY_FIELD(FX100_CTRL, LOOPBACK_MODE, 0, reg); + } + + if (A_TRUE == config->fd_mode) + { + SW_SET_REG_BY_FIELD(FX100_CTRL, FD_MODE, 1, reg); + } + else + { + SW_SET_REG_BY_FIELD(FX100_CTRL, FD_MODE, 0, reg); + } + + if (A_TRUE == config->col_test) + { + SW_SET_REG_BY_FIELD(FX100_CTRL, COL_TEST, 1, reg); + } + else + { + SW_SET_REG_BY_FIELD(FX100_CTRL, COL_TEST, 0, reg); + } + + if (FX100_SERDS_MODE == config->sgmii_fiber_mode) + { + SW_SET_REG_BY_FIELD(FX100_CTRL, SGMII_FIBER, FX100_SERDS_MODE, reg); + } + else + { + return SW_BAD_PARAM; + } + + if (A_TRUE == config->crs_ctrl) + { + SW_SET_REG_BY_FIELD(FX100_CTRL, CRS_CTRL, 1, reg); + } + else + { + SW_SET_REG_BY_FIELD(FX100_CTRL, CRS_CTRL, 0, reg); + } + + if (A_TRUE == config->loopback_ctrl) + { + SW_SET_REG_BY_FIELD(FX100_CTRL, LOOPBACK_TEST, 1, reg); + } + else + { + SW_SET_REG_BY_FIELD(FX100_CTRL, LOOPBACK_TEST, 0, reg); + } + + if (A_TRUE == config->crs_col_100_ctrl) + { + SW_SET_REG_BY_FIELD(FX100_CTRL, CRS_COL_100_CTRL, 1, reg); + } + else + { + SW_SET_REG_BY_FIELD(FX100_CTRL, CRS_COL_100_CTRL, 0, reg); + } + + if (A_TRUE == config->loop_en) + { + SW_SET_REG_BY_FIELD(FX100_CTRL, FX100_LOOP_EN, 1, reg); + } + else + { + SW_SET_REG_BY_FIELD(FX100_CTRL, FX100_LOOP_EN, 0, reg); + } + + HSL_REG_ENTRY_SET(rv, dev_id, FX100_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +static sw_error_t +_isisc_interface_fx100_ctrl_get(a_uint32_t dev_id, fal_fx100_ctrl_config_t* config) +{ + sw_error_t rv; + a_uint32_t reg = 0, field; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_ENTRY_GET(rv, dev_id, FX100_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(FX100_CTRL, LINK_CTRL, field, reg); + if (field == Fx100BASE_MODE) + { + config->link_mode = Fx100BASE_MODE; + } + + SW_GET_FIELD_BY_REG(FX100_CTRL, OVERSHOOT_MODE, field, reg); + if (A_TRUE == field) + { + config->overshoot = A_TRUE; + } + else + { + config->overshoot = A_FALSE; + } + + SW_GET_FIELD_BY_REG(FX100_CTRL, LOOPBACK_MODE, field, reg); + if (A_TRUE == field) + { + config->loopback = A_TRUE; + } + else + { + config->loopback = A_FALSE; + } + + SW_GET_FIELD_BY_REG(FX100_CTRL, FD_MODE, field, reg); + config->fd_mode =field; + + SW_GET_FIELD_BY_REG(FX100_CTRL, COL_TEST, field, reg); + if (A_TRUE == field) + { + config->col_test = A_TRUE; + } + else + { + config->col_test = A_FALSE; + } + + SW_GET_FIELD_BY_REG(FX100_CTRL, SGMII_FIBER, field, reg); + if (FX100_SERDS_MODE == field) + { + config->sgmii_fiber_mode = FX100_SERDS_MODE; + } + + SW_GET_FIELD_BY_REG(FX100_CTRL, CRS_CTRL, field, reg); + if (A_TRUE == field) + { + config->crs_ctrl = A_TRUE; + } + else + { + config->crs_ctrl = A_FALSE; + } + + SW_GET_FIELD_BY_REG(FX100_CTRL, LOOPBACK_TEST, field, reg); + if (A_TRUE == field) + { + config->loopback_ctrl = A_TRUE; + } + else + { + config->loopback_ctrl = A_FALSE; + } + + SW_GET_FIELD_BY_REG(FX100_CTRL, CRS_COL_100_CTRL, field, reg); + if (A_TRUE == field) + { + config->crs_col_100_ctrl = A_TRUE; + } + else + { + config->crs_col_100_ctrl = A_FALSE; + } + + SW_GET_FIELD_BY_REG(FX100_CTRL, FX100_LOOP_EN, field, reg); + if (A_TRUE == field) + { + config->loop_en = A_TRUE; + } + else + { + config->loop_en = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_interface_fx100_status_get(a_uint32_t dev_id, a_uint32_t* status) +{ + sw_error_t rv; + a_uint32_t reg = 0, field; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_ENTRY_GET(rv, dev_id, FX100_CTRL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(FX100_CTRL, FX100_STATUS, field, reg); + + *status = field; + + return SW_OK; +} + +/** + * @brief Set 802.3az status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_3az_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_3az_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get 802.3az status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_3az_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_3az_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set interface mode on a particular MAC device. + * @param[in] dev_id device id + * @param[in] mca_id MAC device ID + * @param[in] config interface configuration + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_interface_mac_mode_set(a_uint32_t dev_id, fal_port_t port_id, fal_mac_config_t * config) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_interface_mac_mode_set(dev_id, port_id, config); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get interface mode on a particular MAC device. + * @param[in] dev_id device id + * @param[in] mca_id MAC device ID + * @param[out] config interface configuration + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_interface_mac_mode_get(a_uint32_t dev_id, fal_port_t port_id, fal_mac_config_t * config) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_interface_mac_mode_get(dev_id, port_id, config); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set interface phy mode on a particular PHY device. + * @param[in] dev_id device id + * @param[in] phy_id PHY device ID + * @param[in] config interface configuration + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_interface_phy_mode_set(a_uint32_t dev_id, a_uint32_t phy_id, fal_phy_config_t * config) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_interface_phy_mode_set(dev_id, phy_id, config); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get interface phy mode on a particular PHY device. + * @param[in] dev_id device id + * @param[in] phy_id PHY device ID + * @param[out] config interface configuration + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_interface_phy_mode_get(a_uint32_t dev_id, a_uint32_t phy_id, fal_phy_config_t * config) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_interface_phy_mode_get(dev_id, phy_id, config); + HSL_API_UNLOCK; + return rv; +} + + +/** + * @brief Set fx100 control configuration. + * @param[in] dev_id device id + * @param[in] config fx100 control configuration + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_interface_fx100_ctrl_set(a_uint32_t dev_id, fal_fx100_ctrl_config_t* config) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_interface_fx100_ctrl_set(dev_id, config); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get fx100 control configuration. + * @param[in] dev_id device id + * @param[out] config fx100 control configuration + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_interface_fx100_ctrl_get(a_uint32_t dev_id, fal_fx100_ctrl_config_t* config) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_interface_fx100_ctrl_get(dev_id, config); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get fx100 status. + * @param[in] dev_id device id + * @param[out] the value of fx100 status + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_interface_fx100_status_get(a_uint32_t dev_id, a_uint32_t* status) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_interface_fx100_status_get(dev_id, status); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set mac0 and mac6 exchange status. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_interface_mac06_exch_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_interface_mac06_exch_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mac0 and mac6 exchange status. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_interface_mac06_exch_get(a_uint32_t dev_id, a_bool_t* enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_interface_mac06_exch_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mac pad configuration. + * @param[in] dev_id device id + * @param[in] port_num port num + * @param[out] config value + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_interface_mac_pad_get(a_uint32_t dev_id,a_uint32_t port_num, a_uint32_t* value) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_interface_mac_pad_get(dev_id, port_num, value); + HSL_API_UNLOCK; + return rv; +} + + +/** + * @brief Set mac pad configuration. + * @param[in] dev_id device id + * @param[in] port_num port num + * @param[in] config value + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_interface_mac_pad_set(a_uint32_t dev_id,a_uint32_t port_num, a_uint32_t value) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_interface_mac_pad_set(dev_id,port_num,value); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mac SGMII configuration. + * @param[in] dev_id device id + * @param[out] config value + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_interface_mac_sgmii_get(a_uint32_t dev_id, a_uint32_t* value) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_interface_mac_sgmii_get(dev_id, value); + HSL_API_UNLOCK; + return rv; +} + + +/** + * @brief Set mac SGMII configuration. + * @param[in] dev_id device id + * @param[in] config value + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_interface_mac_sgmii_set(a_uint32_t dev_id, a_uint32_t value) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_interface_mac_sgmii_set(dev_id, value); + HSL_API_UNLOCK; + return rv; +} + + +sw_error_t +isisc_interface_ctrl_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->port_3az_status_set = isisc_port_3az_status_set; + p_api->port_3az_status_get = isisc_port_3az_status_get; + p_api->interface_mac_mode_set = isisc_interface_mac_mode_set; + p_api->interface_mac_mode_get = isisc_interface_mac_mode_get; + p_api->interface_phy_mode_set = isisc_interface_phy_mode_set; + p_api->interface_phy_mode_get = isisc_interface_phy_mode_get; + p_api->interface_fx100_ctrl_set = isisc_interface_fx100_ctrl_set; + p_api->interface_fx100_ctrl_get = isisc_interface_fx100_ctrl_get; + p_api->interface_fx100_status_get = isisc_interface_fx100_status_get; + p_api->interface_mac06_exch_set = isisc_interface_mac06_exch_set; + p_api->interface_mac06_exch_get = isisc_interface_mac06_exch_get; + p_api->interface_mac_pad_get = isisc_interface_mac_pad_get; + p_api->interface_mac_pad_set = isisc_interface_mac_pad_set; + p_api->interface_mac_sgmii_get = isisc_interface_mac_sgmii_get; + p_api->interface_mac_sgmii_set = isisc_interface_mac_sgmii_set; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_ip.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_ip.c new file mode 100755 index 000000000..b8851bff9 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_ip.c @@ -0,0 +1,2555 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup isisc_ip ISISC_IP + * @{ + */ + +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isisc_ip.h" +#include "isisc_reg.h" + +#define ISISC_HOST_ENTRY_DATA0_ADDR 0x0e80 +#define ISISC_HOST_ENTRY_DATA1_ADDR 0x0e84 +#define ISISC_HOST_ENTRY_DATA2_ADDR 0x0e88 +#define ISISC_HOST_ENTRY_DATA3_ADDR 0x0e8c +#define ISISC_HOST_ENTRY_DATA4_ADDR 0x0e90 +#define ISISC_HOST_ENTRY_DATA5_ADDR 0x0e94 +#define ISISC_HOST_ENTRY_DATA6_ADDR 0x0e98 +#define ISISC_HOST_ENTRY_DATA7_ADDR 0x0e58 + +#define ISISC_HOST_ENTRY_REG_NUM 8 + +#define ISISC_HOST_ENTRY_FLUSH 1 +#define ISISC_HOST_ENTRY_ADD 2 +#define ISISC_HOST_ENTRY_DEL 3 +#define ISISC_HOST_ENTRY_NEXT 4 +#define ISISC_HOST_ENTRY_SEARCH 5 + +#define ISISC_ENTRY_ARP 3 + +#define ISISC_INTF_MAC_ADDR_NUM 8 +#define ISISC_INTF_MAC_TBL0_ADDR 0x5a900 +#define ISISC_INTF_MAC_TBL1_ADDR 0x5a904 +#define ISISC_INTF_MAC_TBL2_ADDR 0x5a908 +#define ISISC_INTF_MAC_EDIT0_ADDR 0x02000 +#define ISISC_INTF_MAC_EDIT1_ADDR 0x02004 +#define ISISC_INTF_MAC_EDIT2_ADDR 0x02008 + +#define ISISC_IP6_BASE_ADDR 0x0470 + +#define ISISC_HOST_ENTRY_NUM 128 + +#define ISISC_IP_COUTER_ADDR 0x2b000 + +static a_uint32_t isisc_mac_snap[SW_MAX_NR_DEV] = { 0 }; +static fal_intf_mac_entry_t isisc_intf_snap[SW_MAX_NR_DEV][ISISC_INTF_MAC_ADDR_NUM]; + +static void +_isisc_ip_pt_learn_save(a_uint32_t dev_id, a_uint32_t * status) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_PTCTRL2, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + if (SW_OK != rv) + { + return; + } + + *status = (data & 0x7f7f); + + data &= 0xffff8080; + HSL_REG_ENTRY_SET(rv, dev_id, ROUTER_PTCTRL2, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return; +} + +static void +_isisc_ip_pt_learn_restore(a_uint32_t dev_id, a_uint32_t status) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_PTCTRL2, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + if (SW_OK != rv) + { + return; + } + + data &= 0xffff8080; + data |= (status & 0x7f7f); + + HSL_REG_ENTRY_SET(rv, dev_id, ROUTER_PTCTRL2, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return; +} + +static sw_error_t +_isisc_ip_feature_check(a_uint32_t dev_id) +{ + sw_error_t rv; + a_uint32_t entry = 0; + + HSL_REG_FIELD_GET(rv, dev_id, MASK_CTL, 0, DEVICE_ID, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (S17C_DEVICE_ID == entry) + { + return SW_OK; + } + else + { + return SW_NOT_SUPPORTED; + } +} + +static sw_error_t +_isisc_ip_counter_get(a_uint32_t dev_id, a_uint32_t cnt_id, + a_uint32_t counter[2]) +{ + sw_error_t rv; + a_uint32_t i, addr; + + addr = ISISC_IP_COUTER_ADDR + (cnt_id << 3); + for (i = 0; i < 2; i++) + { + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(counter[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + addr += 4; + } + + return SW_OK; +} + +static sw_error_t +_isisc_host_entry_commit(a_uint32_t dev_id, a_uint32_t entry_type, a_uint32_t op) +{ + a_uint32_t busy = 1, i = 0x100, entry = 0, j, try_num; + a_uint32_t learn_status = 0; + sw_error_t rv; + + while (busy && --i) + { + HSL_REG_ENTRY_GET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (&entry), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_BUSY, busy, entry); + } + + if (i == 0) + { + return SW_BUSY; + } + + SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_BUSY, 1, entry); + SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_SEL, entry_type, entry); + SW_SET_REG_BY_FIELD(HOST_ENTRY7, ENTRY_FUNC, op, entry); + + HSL_REG_ENTRY_SET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (&entry), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* hardware requirements, we should disable ARP learn at first */ + /* and maybe we should try several times... */ + _isisc_ip_pt_learn_save(dev_id, &learn_status); + if (learn_status) + { + try_num = 10; + } + else + { + try_num = 1; + } + + for (j = 0; j < try_num; j++) + { + busy = 1; + i = 0x1000; + while (busy && --i) + { + HSL_REG_ENTRY_GET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (&entry), + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + _isisc_ip_pt_learn_restore(dev_id, learn_status); + return rv; + } + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_BUSY, busy, entry); + } + + if (i == 0) + { + _isisc_ip_pt_learn_restore(dev_id, learn_status); + return SW_BUSY; + } + + /* hardware requirement, we should read again... */ + HSL_REG_ENTRY_GET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (&entry), + sizeof (a_uint32_t)); + if (SW_OK != rv) + { + _isisc_ip_pt_learn_restore(dev_id, learn_status); + return rv; + } + + /* operation success...... */ + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_STAUS, busy, entry); + if (busy) + { + _isisc_ip_pt_learn_restore(dev_id, learn_status); + return SW_OK; + } + } + + _isisc_ip_pt_learn_restore(dev_id, learn_status); + if (ISISC_HOST_ENTRY_NEXT == op) + { + return SW_NO_MORE; + } + else if (ISISC_HOST_ENTRY_SEARCH == op) + { + return SW_NOT_FOUND; + } + else if (ISISC_HOST_ENTRY_DEL == op) + { + return SW_NOT_FOUND; + } + else + { + return SW_FAIL; + } +} + +static sw_error_t +_isisc_ip_intf_sw_to_hw(a_uint32_t dev_id, fal_host_entry_t * entry, + a_uint32_t * hw_intf) +{ + sw_error_t rv; + a_uint32_t addr, lvid, hvid, tbl[3] = {0}, i; + a_uint32_t sw_intf = entry->intf_id; + a_uint32_t vid_offset; + + for (i = 0; i < ISISC_INTF_MAC_ADDR_NUM; i++) + { + if (isisc_mac_snap[dev_id] & (0x1 << i)) + { + addr = ISISC_INTF_MAC_TBL0_ADDR + (i << 4) + 4; + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[1])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + addr = ISISC_INTF_MAC_TBL0_ADDR + (i << 4) + 8; + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[2])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY1, VID_HIGH0, hvid, tbl[1]); + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY2, VID_HIGH1, lvid, tbl[2]); + hvid |= ((lvid & 0xff) << 4); + + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY1, VID_LOW, lvid, tbl[1]); + + if ((lvid <= sw_intf) && (hvid >= sw_intf)) + { + vid_offset = entry->expect_vid ? (entry->expect_vid - lvid) : (sw_intf - lvid); + *hw_intf = (vid_offset << 3) | i; + return SW_OK; + } + } + } + + return SW_BAD_PARAM; +} + +static sw_error_t +_isisc_ip_intf_hw_to_sw(a_uint32_t dev_id, a_uint32_t hw_intf, + a_uint32_t * sw_intf) +{ + sw_error_t rv; + a_uint32_t addr, lvid, tbl = 0, i; + + i = hw_intf & 0x7; + + addr = ISISC_INTF_MAC_TBL0_ADDR + (i << 4) + 4; + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&tbl), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY1, VID_LOW, lvid, tbl); + *sw_intf = lvid + (hw_intf >> 3); + + return SW_OK; +} + +static sw_error_t +_isisc_ip_age_time_set(a_uint32_t dev_id, a_uint32_t * time) +{ + sw_error_t rv; + a_uint32_t data; + + if (255 < ((*time + 5) / 6)) + { + return SW_BAD_PARAM; + } + + data = ((*time + 5) / 6); + *time = data * 6; + + HSL_REG_FIELD_SET(rv, dev_id, ROUTER_CTRL, 0, ARP_AGE_TIME, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_ip_age_time_get(a_uint32_t dev_id, a_uint32_t * time) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_REG_FIELD_GET(rv, dev_id, ROUTER_CTRL, 0, ARP_AGE_TIME, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *time = data * 6; + return SW_OK; +} + +static sw_error_t +_isisc_host_sw_to_hw(a_uint32_t dev_id, fal_host_entry_t * entry, + a_uint32_t reg[]) +{ + sw_error_t rv; + a_uint32_t data; + + if (FAL_IP_IP4_ADDR & entry->flags) + { + reg[0] = entry->ip4_addr; + SW_SET_REG_BY_FIELD(HOST_ENTRY6, IP_VER, 0, reg[6]); + } + + if (FAL_IP_IP6_ADDR & entry->flags) + { + reg[0] = entry->ip6_addr.ul[3]; + reg[1] = entry->ip6_addr.ul[2]; + reg[2] = entry->ip6_addr.ul[1]; + reg[3] = entry->ip6_addr.ul[0]; + SW_SET_REG_BY_FIELD(HOST_ENTRY6, IP_VER, 1, reg[6]); + } + + SW_SET_REG_BY_FIELD(HOST_ENTRY4, MAC_ADDR2, entry->mac_addr.uc[2], reg[4]); + SW_SET_REG_BY_FIELD(HOST_ENTRY4, MAC_ADDR3, entry->mac_addr.uc[3], reg[4]); + SW_SET_REG_BY_FIELD(HOST_ENTRY4, MAC_ADDR4, entry->mac_addr.uc[4], reg[4]); + SW_SET_REG_BY_FIELD(HOST_ENTRY4, MAC_ADDR5, entry->mac_addr.uc[5], reg[4]); + SW_SET_REG_BY_FIELD(HOST_ENTRY5, MAC_ADDR0, entry->mac_addr.uc[0], reg[5]); + SW_SET_REG_BY_FIELD(HOST_ENTRY5, MAC_ADDR1, entry->mac_addr.uc[1], reg[5]); + + rv = _isisc_ip_intf_sw_to_hw(dev_id, entry/*was:->intf_id*/, &data); + + SW_RTN_ON_ERROR(rv); + SW_SET_REG_BY_FIELD(HOST_ENTRY5, INTF_ID, data, reg[5]); + +#if 0 + if (A_TRUE != hsl_port_prop_check(dev_id, entry->port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } +#endif + + SW_SET_REG_BY_FIELD(HOST_ENTRY5, SRC_PORT, entry->port_id, reg[5]); + + if (FAL_IP_CPU_ADDR & entry->flags) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY5, CPU_ADDR, 1, reg[5]); + } + + SW_SET_REG_BY_FIELD(HOST_ENTRY6, AGE_FLAG, entry->status, reg[6]); + + if ((A_TRUE == entry->mirror_en) && (FAL_MAC_FRWRD != entry->action)) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == entry->counter_en) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY6, CNT_EN, 1, reg[6]); + SW_SET_REG_BY_FIELD(HOST_ENTRY6, CNT_IDX, entry->counter_id, reg[6]); + } + + if (FAL_MAC_DROP == entry->action) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY5, SRC_PORT, 7, reg[5]); + SW_SET_REG_BY_FIELD(HOST_ENTRY6, ACTION, 3, reg[6]); + } + else if (FAL_MAC_RDT_TO_CPU == entry->action) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY6, ACTION, 1, reg[6]); + } + else if (FAL_MAC_CPY_TO_CPU == entry->action) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY6, ACTION, 2, reg[6]); + } + else + { + if (A_TRUE == entry->mirror_en) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY6, ACTION, 0, reg[6]); + } + else + { + SW_SET_REG_BY_FIELD(HOST_ENTRY6, ACTION, 3, reg[6]); + } + } + + return SW_OK; +} + +static sw_error_t +_isisc_host_hw_to_sw(a_uint32_t dev_id, a_uint32_t reg[], + fal_host_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t data, cnt[2] = {0}; + + SW_GET_FIELD_BY_REG(HOST_ENTRY6, IP_VER, data, reg[6]); + if (data) + { + entry->ip6_addr.ul[0] = reg[3]; + entry->ip6_addr.ul[1] = reg[2]; + entry->ip6_addr.ul[2] = reg[1]; + entry->ip6_addr.ul[3] = reg[0]; + entry->flags |= FAL_IP_IP6_ADDR; + } + else + { + entry->ip4_addr = reg[0]; + entry->flags |= FAL_IP_IP4_ADDR; + } + + SW_GET_FIELD_BY_REG(HOST_ENTRY4, MAC_ADDR2, entry->mac_addr.uc[2], reg[4]); + SW_GET_FIELD_BY_REG(HOST_ENTRY4, MAC_ADDR3, entry->mac_addr.uc[3], reg[4]); + SW_GET_FIELD_BY_REG(HOST_ENTRY4, MAC_ADDR4, entry->mac_addr.uc[4], reg[4]); + SW_GET_FIELD_BY_REG(HOST_ENTRY4, MAC_ADDR5, entry->mac_addr.uc[5], reg[4]); + SW_GET_FIELD_BY_REG(HOST_ENTRY5, MAC_ADDR0, entry->mac_addr.uc[0], reg[5]); + SW_GET_FIELD_BY_REG(HOST_ENTRY5, MAC_ADDR1, entry->mac_addr.uc[1], reg[5]); + + SW_GET_FIELD_BY_REG(HOST_ENTRY5, INTF_ID, data, reg[5]); + rv = _isisc_ip_intf_hw_to_sw(dev_id, data, &(entry->intf_id)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(HOST_ENTRY5, SRC_PORT, entry->port_id, reg[5]); + + SW_GET_FIELD_BY_REG(HOST_ENTRY5, CPU_ADDR, data, reg[5]); + if (data) + { + entry->flags |= FAL_IP_CPU_ADDR; + } + + SW_GET_FIELD_BY_REG(HOST_ENTRY6, AGE_FLAG, entry->status, reg[6]); + + SW_GET_FIELD_BY_REG(HOST_ENTRY6, CNT_EN, data, reg[6]); + if (data) + { + entry->counter_en = A_TRUE; + SW_GET_FIELD_BY_REG(HOST_ENTRY6, CNT_IDX, entry->counter_id, reg[6]); + + rv = _isisc_ip_counter_get(dev_id, entry->counter_id, cnt); + SW_RTN_ON_ERROR(rv); + + entry->packet = cnt[0]; + entry->byte = cnt[1]; + } + else + { + entry->counter_en = A_FALSE; + } + + SW_GET_FIELD_BY_REG(HOST_ENTRY6, PPPOE_EN, data, reg[6]); + if (data) + { + entry->pppoe_en = A_TRUE; + SW_GET_FIELD_BY_REG(HOST_ENTRY6, PPPOE_IDX, data, reg[6]); + entry->pppoe_id = data; + } + else + { + entry->pppoe_en = A_FALSE; + } + + if (7 == entry->port_id) + { + entry->port_id = 0; + entry->action = FAL_MAC_DROP; + } + else + { + SW_GET_FIELD_BY_REG(HOST_ENTRY6, ACTION, data, reg[6]); + entry->action = FAL_MAC_FRWRD; + if (0 == data) + { + entry->mirror_en = A_TRUE; + } + else if (1 == data) + { + entry->action = FAL_MAC_RDT_TO_CPU; + } + else if (2 == data) + { + entry->action = FAL_MAC_CPY_TO_CPU; + } + } + + return SW_OK; +} + +static sw_error_t +_isisc_host_down_to_hw(a_uint32_t dev_id, a_uint32_t reg[]) +{ + sw_error_t rv; + a_uint32_t i, addr; + + for (i = 0; i < ISISC_HOST_ENTRY_REG_NUM; i++) + { + if((ISISC_HOST_ENTRY_REG_NUM - 1) == i) + { + addr = ISISC_HOST_ENTRY_DATA7_ADDR; + } + else + { + addr = ISISC_HOST_ENTRY_DATA0_ADDR + (i << 2); + } + + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®[i]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +static sw_error_t +_isisc_host_up_to_sw(a_uint32_t dev_id, a_uint32_t reg[]) +{ + sw_error_t rv; + a_uint32_t i, addr; + + for (i = 0; i < ISISC_HOST_ENTRY_REG_NUM; i++) + { + if((ISISC_HOST_ENTRY_REG_NUM - 1) == i) + { + addr = ISISC_HOST_ENTRY_DATA7_ADDR; + } + else + { + addr = ISISC_HOST_ENTRY_DATA0_ADDR + (i << 2); + } + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®[i]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +static sw_error_t +_isisc_ip_host_add(a_uint32_t dev_id, fal_host_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t reg[ISISC_HOST_ENTRY_REG_NUM] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_host_sw_to_hw(dev_id, entry, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_host_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_host_entry_commit(dev_id, ISISC_ENTRY_ARP, ISISC_HOST_ENTRY_ADD); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (®[7]), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_IDX, entry->entry_id, reg[7]); + return SW_OK; +} + +static sw_error_t +_isisc_ip_host_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_host_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t data, reg[ISISC_HOST_ENTRY_REG_NUM] = { 0 }, op = ISISC_HOST_ENTRY_FLUSH; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_IP_ENTRY_ID_EN & del_mode) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_IP_ENTRY_IPADDR_EN & del_mode) + { + op = ISISC_HOST_ENTRY_DEL; + if (FAL_IP_IP4_ADDR & entry->flags) + { + reg[0] = entry->ip4_addr; + } + + if (FAL_IP_IP6_ADDR & entry->flags) + { + reg[0] = entry->ip6_addr.ul[3]; + reg[1] = entry->ip6_addr.ul[2]; + reg[2] = entry->ip6_addr.ul[1]; + reg[3] = entry->ip6_addr.ul[0]; + SW_SET_REG_BY_FIELD(HOST_ENTRY6, IP_VER, 1, reg[6]); + } + } + + if (FAL_IP_ENTRY_INTF_EN & del_mode) + { + rv = _isisc_ip_intf_sw_to_hw(dev_id, entry/*was:->intf_id*/, &data); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_VID, 1, reg[7]); + SW_SET_REG_BY_FIELD(HOST_ENTRY5, INTF_ID, data, reg[5]); + } + + if (FAL_IP_ENTRY_PORT_EN & del_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_SP, 1, reg[7]); + SW_SET_REG_BY_FIELD(HOST_ENTRY5, SRC_PORT, entry->port_id, reg[5]); + } + + if (FAL_IP_ENTRY_STATUS_EN & del_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_STATUS, 1, reg[7]); + SW_SET_REG_BY_FIELD(HOST_ENTRY6, AGE_FLAG, entry->status, reg[6]); + } + + rv = _isisc_host_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_host_entry_commit(dev_id, ISISC_ENTRY_ARP, op); + return rv; +} + +static sw_error_t +_isisc_ip_host_get(a_uint32_t dev_id, a_uint32_t get_mode, + fal_host_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t reg[ISISC_HOST_ENTRY_REG_NUM] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_IP_ENTRY_IPADDR_EN != get_mode) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_IP_IP4_ADDR & entry->flags) + { + reg[0] = entry->ip4_addr; + } + else + { + reg[0] = entry->ip6_addr.ul[3]; + reg[1] = entry->ip6_addr.ul[2]; + reg[2] = entry->ip6_addr.ul[1]; + reg[3] = entry->ip6_addr.ul[0]; + SW_SET_REG_BY_FIELD(HOST_ENTRY6, IP_VER, 1, reg[6]); + } + + rv = _isisc_host_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_host_entry_commit(dev_id, ISISC_ENTRY_ARP, + ISISC_HOST_ENTRY_SEARCH); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_host_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + aos_mem_zero(entry, sizeof (fal_host_entry_t)); + + rv = _isisc_host_hw_to_sw(dev_id, reg, entry); + SW_RTN_ON_ERROR(rv); + + if (!(entry->status)) + { + return SW_NOT_FOUND; + } + + HSL_REG_ENTRY_GET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (®[7]), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_IDX, entry->entry_id, reg[7]); + return SW_OK; +} + +static sw_error_t +_isisc_ip_host_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_host_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t idx, data, reg[ISISC_HOST_ENTRY_REG_NUM] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_NEXT_ENTRY_FIRST_ID == entry->entry_id) + { + idx = ISISC_HOST_ENTRY_NUM - 1; + } + else + { + if ((ISISC_HOST_ENTRY_NUM - 1) == entry->entry_id) + { + return SW_NO_MORE; + } + else + { + idx = entry->entry_id; + } + } + + SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_IDX, idx, reg[7]); + + if (FAL_IP_ENTRY_INTF_EN & next_mode) + { + rv = _isisc_ip_intf_sw_to_hw(dev_id, entry/*was:->intf_id*/, &data); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_VID, 1, reg[7]); + SW_SET_REG_BY_FIELD(HOST_ENTRY5, INTF_ID, data, reg[5]); + } + + if (FAL_IP_ENTRY_PORT_EN & next_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_SP, 1, reg[7]); + SW_SET_REG_BY_FIELD(HOST_ENTRY5, SRC_PORT, entry->port_id, reg[5]); + } + + if (FAL_IP_ENTRY_STATUS_EN & next_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_STATUS, 1, reg[7]); + SW_SET_REG_BY_FIELD(HOST_ENTRY6, AGE_FLAG, entry->status, reg[6]); + } + + rv = _isisc_host_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_host_entry_commit(dev_id, ISISC_ENTRY_ARP, ISISC_HOST_ENTRY_NEXT); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_host_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + aos_mem_zero(entry, sizeof (fal_host_entry_t)); + + rv = _isisc_host_hw_to_sw(dev_id, reg, entry); + SW_RTN_ON_ERROR(rv); + + if (!(entry->status)) + { + return SW_NO_MORE; + } + + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_IDX, entry->entry_id, reg[7]); + return SW_OK; +} + +static sw_error_t +_isisc_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; + a_uint32_t reg[ISISC_HOST_ENTRY_REG_NUM] = { 0 }, tbl[ISISC_HOST_ENTRY_REG_NUM] = { 0 }, tbl_idx; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + tbl_idx = (entry_id - 1) & 0x7f; + SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_IDX, tbl_idx, reg[7]); + + rv = _isisc_host_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_host_entry_commit(dev_id, ISISC_ENTRY_ARP, ISISC_HOST_ENTRY_NEXT); + if (SW_OK != rv) + { + return SW_NOT_FOUND; + } + + rv = _isisc_host_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_IDX, tbl_idx, reg[7]); + if (entry_id != tbl_idx) + { + return SW_NOT_FOUND; + } + + tbl[0] = reg[0]; + tbl[1] = reg[1]; + tbl[2] = reg[2]; + tbl[3] = reg[3]; + tbl[6] = (reg[6] >> 15) << 15; + rv = _isisc_host_down_to_hw(dev_id, tbl); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_host_entry_commit(dev_id, ISISC_ENTRY_ARP, ISISC_HOST_ENTRY_DEL); + SW_RTN_ON_ERROR(rv); + + if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY6, CNT_EN, 0, reg[6]); + } + else if (A_TRUE == enable) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY6, CNT_EN, 1, reg[6]); + SW_SET_REG_BY_FIELD(HOST_ENTRY6, CNT_IDX, cnt_id, reg[6]); + } + else + { + return SW_BAD_PARAM; + } + + reg[7] = 0x0; + rv = _isisc_host_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_host_entry_commit(dev_id, ISISC_ENTRY_ARP, ISISC_HOST_ENTRY_ADD); + return rv; +} + +static sw_error_t +_isisc_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; + a_uint32_t reg[ISISC_HOST_ENTRY_REG_NUM] = { 0 }, tbl[ISISC_HOST_ENTRY_REG_NUM] = { 0 }, tbl_idx; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + tbl_idx = (entry_id - 1) & 0x7f; + SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_IDX, tbl_idx, reg[7]); + + rv = _isisc_host_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_host_entry_commit(dev_id, ISISC_ENTRY_ARP, ISISC_HOST_ENTRY_NEXT); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_host_up_to_sw(dev_id, reg); + if (SW_OK != rv) + { + return SW_NOT_FOUND; + } + + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_IDX, tbl_idx, reg[7]); + if (entry_id != tbl_idx) + { + return SW_NOT_FOUND; + } + + if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY6, PPPOE_EN, 0, reg[6]); + } + else if (A_TRUE == enable) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY6, PPPOE_EN, 1, reg[6]); + SW_SET_REG_BY_FIELD(HOST_ENTRY6, PPPOE_IDX, pppoe_id, reg[6]); + } + else + { + return SW_BAD_PARAM; + } + + tbl[0] = reg[0]; + tbl[1] = reg[1]; + tbl[2] = reg[2]; + tbl[3] = reg[3]; + tbl[6] = (reg[6] >> 15) << 15; + rv = _isisc_host_down_to_hw(dev_id, tbl); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_host_entry_commit(dev_id, ISISC_ENTRY_ARP, ISISC_HOST_ENTRY_DEL); + SW_RTN_ON_ERROR(rv); + + reg[7] = 0x0; + rv = _isisc_host_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_host_entry_commit(dev_id, ISISC_ENTRY_ARP, ISISC_HOST_ENTRY_ADD); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_host_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +static sw_error_t +_isisc_ip_pt_arp_learn_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t flags) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_PTCTRL2, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_ARP_LEARN_REQ & flags) + { + data |= (0x1 << port_id); + } + else + { + data &= (~(0x1 << port_id)); + } + + if (FAL_ARP_LEARN_ACK & flags) + { + data |= (0x1 << (ROUTER_PTCTRL2_ARP_LEARN_ACK_BOFFSET + port_id)); + } + else + { + data &= (~(0x1 << (ROUTER_PTCTRL2_ARP_LEARN_ACK_BOFFSET + port_id))); + } + + HSL_REG_ENTRY_SET(rv, dev_id, ROUTER_PTCTRL2, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_ip_pt_arp_learn_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * flags) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + *flags = 0; + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_PTCTRL2, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data & (0x1 << port_id)) + { + *flags |= FAL_ARP_LEARN_REQ; + } + + if (data & (0x1 << (ROUTER_PTCTRL2_ARP_LEARN_ACK_BOFFSET + port_id))) + { + *flags |= FAL_ARP_LEARN_ACK; + } + + return SW_OK; +} + +static sw_error_t +_isisc_ip_arp_learn_set(a_uint32_t dev_id, fal_arp_learn_mode_t mode) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_ARP_LEARN_ALL == mode) + { + data = 1; + } + else if (FAL_ARP_LEARN_LOCAL == mode) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, ROUTER_CTRL, 0, ARP_LEARN_MODE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_ip_arp_learn_get(a_uint32_t dev_id, fal_arp_learn_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, ROUTER_CTRL, 0, ARP_LEARN_MODE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data) + { + *mode = FAL_ARP_LEARN_ALL; + } + else + { + *mode = FAL_ARP_LEARN_LOCAL; + } + + return SW_OK; +} + +static sw_error_t +_isisc_ip_source_guard_set(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t mode) +{ + sw_error_t rv; + a_uint32_t reg = 0, data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_PTCTRL1, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_NO_SOURCE_GUARD < mode) + { + return SW_BAD_PARAM; + } + + data = 0; + if (FAL_MAC_IP_GUARD == mode) + { + data = 1; + } + else if (FAL_MAC_IP_PORT_GUARD == mode) + { + data = 2; + } + else if (FAL_MAC_IP_VLAN_GUARD == mode) + { + data = 3; + } + else if (FAL_MAC_IP_PORT_VLAN_GUARD == mode) + { + data = 4; + } + reg &= (~(0x7 << (port_id * 3))); + reg |= ((data & 0x7) << (port_id * 3)); + + HSL_REG_ENTRY_SET(rv, dev_id, ROUTER_PTCTRL1, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data = 1; + if (FAL_NO_SOURCE_GUARD == mode) + { + data = 0; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN1, port_id, SP_CHECK_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_ip_source_guard_get(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t reg = 0, data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_PTCTRL1, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data = (reg >> (port_id * 3)) & 0x7; + + *mode = FAL_NO_SOURCE_GUARD; + if (1 == data) + { + *mode = FAL_MAC_IP_GUARD; + } + else if (2 == data) + { + *mode = FAL_MAC_IP_PORT_GUARD; + } + else if (3 == data) + { + *mode = FAL_MAC_IP_VLAN_GUARD; + } + else if (4 == data) + { + *mode = FAL_MAC_IP_PORT_VLAN_GUARD; + } + + return SW_OK; +} + +static sw_error_t +_isisc_ip_unk_source_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_MAC_FRWRD == cmd) + { + data = 0; + } + else if (FAL_MAC_DROP == cmd) + { + data = 1; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + data = 2; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, IP_NOT_FOUND, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_ip_unk_source_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, IP_NOT_FOUND, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0 == data) + { + *cmd = FAL_MAC_FRWRD; + } + else if (1 == data) + { + *cmd = FAL_MAC_DROP; + } + else + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + + return SW_OK; +} + +static sw_error_t +_isisc_ip_arp_guard_set(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t mode) +{ + sw_error_t rv; + a_uint32_t reg = 0, data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_PTCTRL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_NO_SOURCE_GUARD < mode) + { + return SW_BAD_PARAM; + } + + data = 0; + if (FAL_MAC_IP_GUARD == mode) + { + data = 1; + } + else if (FAL_MAC_IP_PORT_GUARD == mode) + { + data = 2; + } + else if (FAL_MAC_IP_VLAN_GUARD == mode) + { + data = 3; + } + else if (FAL_MAC_IP_PORT_VLAN_GUARD == mode) + { + data = 4; + } + reg &= (~(0x7 << (port_id * 3))); + reg |= ((data & 0x7) << (port_id * 3)); + + HSL_REG_ENTRY_SET(rv, dev_id, ROUTER_PTCTRL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_ip_arp_guard_get(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t reg = 0, data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_PTCTRL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data = (reg >> (port_id * 3)) & 0x7; + + *mode = FAL_NO_SOURCE_GUARD; + if (1 == data) + { + *mode = FAL_MAC_IP_GUARD; + } + else if (2 == data) + { + *mode = FAL_MAC_IP_PORT_GUARD; + } + else if (3 == data) + { + *mode = FAL_MAC_IP_VLAN_GUARD; + } + else if (4 == data) + { + *mode = FAL_MAC_IP_PORT_VLAN_GUARD; + } + + return SW_OK; +} + +static sw_error_t +_isisc_arp_unk_source_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_MAC_FRWRD == cmd) + { + data = 0; + } + else if (FAL_MAC_DROP == cmd) + { + data = 1; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + data = 2; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, ARP_NOT_FOUND, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_arp_unk_source_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, ARP_NOT_FOUND, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0 == data) + { + *cmd = FAL_MAC_FRWRD; + } + else if (1 == data) + { + *cmd = FAL_MAC_DROP; + } + else + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + + return SW_OK; +} + +static sw_error_t +_isisc_ip_route_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, ROUTER_CTRL, 0, ROUTER_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, MOD_ENABLE, 0, L3_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_ip_route_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t route_en = 0, l3_en = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, ROUTER_CTRL, 0, ROUTER_EN, + (a_uint8_t *) (&route_en), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, MOD_ENABLE, 0, L3_EN, + (a_uint8_t *) (&l3_en), sizeof (a_uint32_t)) + SW_RTN_ON_ERROR(rv); + + if (route_en && l3_en) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return rv; +} + +static sw_error_t +_isisc_ip_intf_entry_add(a_uint32_t dev_id, fal_intf_mac_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t i, j, found = 0, addr, tbl[3] = { 0 }; + fal_intf_mac_entry_t * intf_entry = NULL; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + for (i = 0; i < ISISC_INTF_MAC_ADDR_NUM; i++) + { + if (isisc_mac_snap[dev_id] & (0x1 << i)) + { + intf_entry = &(isisc_intf_snap[dev_id][i]); + if ((entry->vid_low == intf_entry->vid_low) + && (entry->vid_high == intf_entry->vid_high)) + { + /* all same, return OK directly */ + if (!aos_mem_cmp(intf_entry, entry, sizeof(fal_intf_mac_entry_t))) + { + return SW_OK; + } + else + { + /* update entry */ + found = 1; + break; + } + } + else + { + /* entry VID cross border, not support */ + if ((entry->vid_low >= intf_entry->vid_low) && (entry->vid_low <= intf_entry->vid_high)) + { + return SW_BAD_PARAM; + } + + /* entry VID cross border, not support */ + if ((entry->vid_high >= intf_entry->vid_low) && (entry->vid_low <= intf_entry->vid_high)) + { + return SW_BAD_PARAM; + } + } + } + } + + if (!found) + { + for (i = 0; i < ISISC_INTF_MAC_ADDR_NUM; i++) + { + if (!(isisc_mac_snap[dev_id] & (0x1 << i))) + { + intf_entry = &(isisc_intf_snap[dev_id][i]); + break; + } + } + } + + if (ISISC_INTF_MAC_ADDR_NUM == i) + { + return SW_NO_RESOURCE; + } + + if ((A_FALSE == entry->ip4_route) && (A_FALSE == entry->ip6_route)) + { + return SW_NOT_SUPPORTED; + } + + if (512 <= (entry->vid_high - entry->vid_low)) + { + return SW_BAD_PARAM; + } + + SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY0, MAC_ADDR2, entry->mac_addr.uc[2], + tbl[0]); + SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY0, MAC_ADDR3, entry->mac_addr.uc[3], + tbl[0]); + SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY0, MAC_ADDR4, entry->mac_addr.uc[4], + tbl[0]); + SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY0, MAC_ADDR5, entry->mac_addr.uc[5], + tbl[0]); + SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY1, MAC_ADDR0, entry->mac_addr.uc[0], + tbl[1]); + SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY1, MAC_ADDR1, entry->mac_addr.uc[1], + tbl[1]); + + SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY1, VID_LOW, entry->vid_low, tbl[1]); + SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY1, VID_HIGH0, (entry->vid_high & 0xf), + tbl[1]); + SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY2, VID_HIGH1, (entry->vid_high >> 4), + tbl[2]); + + if (A_TRUE == entry->ip4_route) + { + SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY2, IP4_ROUTE, 1, tbl[2]); + } + + if (A_TRUE == entry->ip6_route) + { + SW_SET_REG_BY_FIELD(INTF_ADDR_ENTRY2, IP6_ROUTE, 1, tbl[2]); + } + + for (j = 0; j < 2; j++) + { + addr = ISISC_INTF_MAC_EDIT0_ADDR + (i << 4) + (j << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[j])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + for (j = 0; j < 3; j++) + { + addr = ISISC_INTF_MAC_TBL0_ADDR + (i << 4) + (j << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[j])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + isisc_mac_snap[dev_id] |= (0x1 << i); + *intf_entry = *entry; + entry->entry_id = i; + return SW_OK; +} + +static sw_error_t +_isisc_ip_intf_entry_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_intf_mac_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t addr, tbl[3] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (!(FAL_IP_ENTRY_ID_EN & del_mode)) + { + return SW_NOT_SUPPORTED; + } + + if (ISISC_INTF_MAC_ADDR_NUM <= entry->entry_id) + { + return SW_BAD_PARAM; + } + + /* clear valid bits */ + addr = ISISC_INTF_MAC_TBL2_ADDR + (entry->entry_id << 4); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[2])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + isisc_mac_snap[dev_id] &= (~(0x1 << entry->entry_id)); + return SW_OK; +} + +static sw_error_t +_isisc_ip_intf_entry_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_intf_mac_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t i, j, idx, addr, tbl[3] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_NEXT_ENTRY_FIRST_ID == entry->entry_id) + { + idx = 0; + } + else + { + if ((ISISC_INTF_MAC_ADDR_NUM - 1) == entry->entry_id) + { + return SW_NO_MORE; + } + else + { + idx = entry->entry_id + 1; + } + } + + for (i = idx; i < ISISC_INTF_MAC_ADDR_NUM; i++) + { + if (isisc_mac_snap[dev_id] & (0x1 << i)) + { + break; + } + } + + if (ISISC_INTF_MAC_ADDR_NUM == i) + { + return SW_NO_MORE; + } + + for (j = 0; j < 3; j++) + { + addr = ISISC_INTF_MAC_TBL0_ADDR + (i << 4) + (j << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[j])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + aos_mem_zero(entry, sizeof (fal_intf_mac_entry_t)); + + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY0, MAC_ADDR2, entry->mac_addr.uc[2], + tbl[0]); + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY0, MAC_ADDR3, entry->mac_addr.uc[3], + tbl[0]); + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY0, MAC_ADDR4, entry->mac_addr.uc[4], + tbl[0]); + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY0, MAC_ADDR5, entry->mac_addr.uc[5], + tbl[0]); + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY1, MAC_ADDR0, entry->mac_addr.uc[0], + tbl[1]); + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY1, MAC_ADDR1, entry->mac_addr.uc[1], + tbl[1]); + + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY1, VID_LOW, entry->vid_low, tbl[1]); + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY1, VID_HIGH0, j, tbl[1]); + entry->vid_high = j & 0xf; + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY2, VID_HIGH1, j, tbl[2]); + entry->vid_high |= ((j & 0xff) << 4); + + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY2, IP4_ROUTE, j, tbl[2]); + if (j) + { + entry->ip4_route = A_TRUE; + } + + SW_GET_FIELD_BY_REG(INTF_ADDR_ENTRY2, IP6_ROUTE, j, tbl[2]); + if (j) + { + entry->ip6_route = A_TRUE; + } + + entry->entry_id = i; + return SW_OK; +} + +#define ISISC_WCMP_ENTRY_MAX_ID 3 +#define ISISC_WCMP_HASH_MAX_NUM 16 +#define ISISC_IP_ENTRY_MAX_ID 127 + +#define ISISC_WCMP_HASH_TBL_ADDR 0x0e10 +#define ISISC_WCMP_NHOP_TBL_ADDR 0x0e20 + +#if 0 +static sw_error_t +_isisc_ip_wcmp_entry_set(a_uint32_t dev_id, a_uint32_t wcmp_id, fal_ip_wcmp_t * wcmp) +{ + sw_error_t rv; + a_uint32_t i, j, addr, data; + a_uint8_t idx, ptr[4] = { 0 }, pos[16] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (ISISC_WCMP_ENTRY_MAX_ID < wcmp_id) + { + return SW_BAD_PARAM; + } + + if (ISISC_WCMP_HASH_MAX_NUM < wcmp->nh_nr) + { + return SW_BAD_PARAM; + } + + for (i = 0; i < wcmp->nh_nr; i++) + { + if (ISISC_IP_ENTRY_MAX_ID < wcmp->nh_id[i]) + { + return SW_BAD_PARAM; + } + + idx = 4; + for (j = 0; j < 4; j++) + { + if (ptr[j] & 0x80) + { + if ((ptr[j] & 0x7f) == wcmp->nh_id[i]) + { + idx = j; + break; + } + } + else + { + idx = j; + } + } + + if (4 == idx) + { + return SW_BAD_PARAM; + } + else + { + ptr[idx] = (wcmp->nh_id[i] & 0x7f) | 0x80; + pos[i] = idx; + } + } + + data = 0; + for (j = 0; j < 4; j++) + { + data |= (ptr[j] << (j << 3)); + } + + addr = ISISC_WCMP_NHOP_TBL_ADDR + (wcmp_id << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data = 0; + for (j = 0; j < 16; j++) + { + data |= (pos[j] << (j << 1)); + } + + addr = ISISC_WCMP_HASH_TBL_ADDR + (wcmp_id << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +static sw_error_t +_isisc_ip_wcmp_entry_get(a_uint32_t dev_id, a_uint32_t wcmp_id, fal_ip_wcmp_t * wcmp) +{ + sw_error_t rv; + a_uint32_t i, addr, data = 0; + a_uint8_t ptr[4] = { 0 }, pos[16] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (ISISC_WCMP_ENTRY_MAX_ID < wcmp_id) + { + return SW_BAD_PARAM; + } + + wcmp->nh_nr = ISISC_WCMP_HASH_MAX_NUM; + + addr = ISISC_WCMP_NHOP_TBL_ADDR + (wcmp_id << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + for (i = 0; i < 4; i++) + { + ptr[i] = (data >> (i << 3)) & 0x7f; + } + + addr = ISISC_WCMP_HASH_TBL_ADDR + (wcmp_id << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + for (i = 0; i < 16; i++) + { + pos[i] = (data >> (i << 1)) & 0x3; + } + + for (i = 0; i < 16; i++) + { + wcmp->nh_id[i] = ptr[pos[i]]; + } + + return SW_OK; +} +#endif + +static sw_error_t +_isisc_ip_wcmp_hash_mode_set(a_uint32_t dev_id, a_uint32_t hash_mode) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_CTRL, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_WCMP_HASH_KEY_SIP & hash_mode) + { + SW_SET_REG_BY_FIELD(ROUTER_CTRL, WCMP_HAHS_SIP, 1, data); + } + else + { + SW_SET_REG_BY_FIELD(ROUTER_CTRL, WCMP_HAHS_SIP, 0, data); + } + + if (FAL_WCMP_HASH_KEY_DIP & hash_mode) + { + SW_SET_REG_BY_FIELD(ROUTER_CTRL, WCMP_HAHS_DIP, 1, data); + } + else + { + SW_SET_REG_BY_FIELD(ROUTER_CTRL, WCMP_HAHS_DIP, 0, data); + } + + if (FAL_WCMP_HASH_KEY_SPORT & hash_mode) + { + SW_SET_REG_BY_FIELD(ROUTER_CTRL, WCMP_HAHS_SP, 1, data); + } + else + { + SW_SET_REG_BY_FIELD(ROUTER_CTRL, WCMP_HAHS_SP, 0, data); + } + + if (FAL_WCMP_HASH_KEY_DPORT & hash_mode) + { + SW_SET_REG_BY_FIELD(ROUTER_CTRL, WCMP_HAHS_DP, 1, data); + } + else + { + SW_SET_REG_BY_FIELD(ROUTER_CTRL, WCMP_HAHS_DP, 0, data); + } + + + HSL_REG_ENTRY_SET(rv, dev_id, ROUTER_CTRL, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_ip_wcmp_hash_mode_get(a_uint32_t dev_id, a_uint32_t * hash_mode) +{ + sw_error_t rv; + a_uint32_t data = 0, field; + + *hash_mode = 0; + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_CTRL, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(ROUTER_CTRL, WCMP_HAHS_SIP, field, data); + if (field) + { + *hash_mode |= FAL_WCMP_HASH_KEY_SIP; + } + + SW_GET_FIELD_BY_REG(ROUTER_CTRL, WCMP_HAHS_DIP, field, data); + if (field) + { + *hash_mode |= FAL_WCMP_HASH_KEY_DIP; + } + + SW_GET_FIELD_BY_REG(ROUTER_CTRL, WCMP_HAHS_SP, field, data); + if (field) + { + *hash_mode |= FAL_WCMP_HASH_KEY_SPORT; + } + + SW_GET_FIELD_BY_REG(ROUTER_CTRL, WCMP_HAHS_DP, field, data); + if (field) + { + *hash_mode |= FAL_WCMP_HASH_KEY_DPORT; + } + + return SW_OK; +} + +sw_error_t +isisc_ip_reset(a_uint32_t dev_id) +{ + sw_error_t rv; + a_uint32_t i, addr, data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_ip_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_host_entry_commit(dev_id, ISISC_ENTRY_ARP, ISISC_HOST_ENTRY_FLUSH); + SW_RTN_ON_ERROR(rv); + + isisc_mac_snap[dev_id] = 0; + for (i = 0; i < ISISC_INTF_MAC_ADDR_NUM; i++) + { + addr = ISISC_INTF_MAC_TBL2_ADDR + (i << 4); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +/** + * @brief Add one host entry to one particular device. + * @details Comments: + * For ISIS the intf_id parameter in host_entry means vlan id. + Before host entry added related interface entry and ip6 base address + must be set at first. + Hardware entry id will be returned. + * @param[in] dev_id device id + * @param[in] host_entry host entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_ip_host_add(a_uint32_t dev_id, fal_host_entry_t * host_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_ip_host_add(dev_id, host_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete one host entry from one particular device. + * @details Comments: + * For ISIS the intf_id parameter in host_entry means vlan id. + Before host entry deleted related interface entry and ip6 base address + must be set atfirst. + For del_mode please refer IP entry operation flags. + * @param[in] dev_id device id + * @param[in] del_mode delete operation mode + * @param[in] host_entry host entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_ip_host_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_host_entry_t * host_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_ip_host_del(dev_id, del_mode, host_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get one host entry from one particular device. + * @details Comments: + * For ISIS the intf_id parameter in host_entry means vlan id. + Before host entry deleted related interface entry and ip6 base address + must be set atfirst. + For get_mode please refer IP entry operation flags. + * @param[in] dev_id device id + * @param[in] get_mode get operation mode + * @param[out] host_entry host entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_ip_host_get(a_uint32_t dev_id, a_uint32_t get_mode, + fal_host_entry_t * host_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_ip_host_get(dev_id, get_mode, host_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Next one host entry from one particular device. + * @details Comments: + * For ISIS the intf_id parameter in host_entry means vlan id. + Before host entry deleted related interface entry and ip6 base address + must be set atfirst. + For next_mode please refer IP entry operation flags. + For get the first entry please set entry id as FAL_NEXT_ENTRY_FIRST_ID + * @param[in] dev_id device id + * @param[in] next_mode next operation mode + * @param[out] host_entry host entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_ip_host_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_host_entry_t * host_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_ip_host_next(dev_id, next_mode, host_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Bind one counter entry to one host entry on one particular device. + * @param[in] dev_id device id + * @param[in] entry_id host entry id + * @param[in] cnt_id counter entry id + * @param[in] enable A_TRUE means bind, A_FALSE means unbind + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_ip_host_counter_bind(dev_id, entry_id, cnt_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Bind one pppoe session entry to one host entry on one particular device. + * @param[in] dev_id device id + * @param[in] entry_id host entry id + * @param[in] pppoe_id pppoe session entry id + * @param[in] enable A_TRUE means bind, A_FALSE means unbind + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_ip_host_pppoe_bind(dev_id, entry_id, pppoe_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set arp packets type to learn on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] flags arp type FAL_ARP_LEARN_REQ and/or FAL_ARP_LEARN_ACK + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_ip_pt_arp_learn_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t flags) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_ip_pt_arp_learn_set(dev_id, port_id, flags); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp packets type to learn on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] flags arp type FAL_ARP_LEARN_REQ and/or FAL_ARP_LEARN_ACK + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_ip_pt_arp_learn_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * flags) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_ip_pt_arp_learn_get(dev_id, port_id, flags); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set arp packets type to learn on one particular device. + * @param[in] dev_id device id + * @param[in] mode learning mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_ip_arp_learn_set(a_uint32_t dev_id, fal_arp_learn_mode_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_ip_arp_learn_set(dev_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp packets type to learn on one particular device. + * @param[in] dev_id device id + * @param[out] mode learning mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_ip_arp_learn_get(a_uint32_t dev_id, fal_arp_learn_mode_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_ip_arp_learn_get(dev_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set ip packets source guarding mode on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode source guarding mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_ip_source_guard_set(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_ip_source_guard_set(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get ip packets source guarding mode on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mode source guarding mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_ip_source_guard_get(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_ip_source_guard_get(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set unkonw source ip packets forwarding command on one particular device. + * @details Comments: + * This settin is no meaning when ip source guard not enable + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_ip_unk_source_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_ip_unk_source_cmd_set(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get unkonw source ip packets forwarding command on one particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_ip_unk_source_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_ip_unk_source_cmd_get(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set arp packets source guarding mode on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode source guarding mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_ip_arp_guard_set(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_ip_arp_guard_set(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp packets source guarding mode on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mode source guarding mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_ip_arp_guard_get(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_ip_arp_guard_get(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set unkonw source arp packets forwarding command on one particular device. + * @details Comments: + * This settin is no meaning when arp source guard not enable + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_arp_unk_source_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_arp_unk_source_cmd_set(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get unkonw source arp packets forwarding command on one particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_arp_unk_source_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_arp_unk_source_cmd_get(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set IP unicast routing status on one particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_ip_route_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_ip_route_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IP unicast routing status on one particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_ip_route_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_ip_route_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add one interface entry to one particular device. + * @param[in] dev_id device id + * @param[in] entry interface entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_ip_intf_entry_add(a_uint32_t dev_id, fal_intf_mac_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_ip_intf_entry_add(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete one interface entry from one particular device. + * @param[in] dev_id device id + * @param[in] del_mode delete operation mode + * @param[in] entry interface entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_ip_intf_entry_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_intf_mac_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_ip_intf_entry_del(dev_id, del_mode, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Next one interface entry from one particular device. + * @param[in] dev_id device id + * @param[in] next_mode next operation mode + * @param[out] entry interface entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_ip_intf_entry_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_intf_mac_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_ip_intf_entry_next(dev_id, next_mode, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set IP host entry aging time on one particular device. + * @details Comments: + * This operation will set dynamic entry aging time on a particular device. + * The unit of time is second. Because different device has differnet + * hardware granularity function will return actual time in hardware. + * @param[in] dev_id device id + * @param[in] time aging time + * @param[out] time actual aging time + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_ip_age_time_set(a_uint32_t dev_id, a_uint32_t * time) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_ip_age_time_set(dev_id, time); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IP host entry aging time on one particular device. + * @param[in] dev_id device id + * @param[out] time aging time + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_ip_age_time_get(a_uint32_t dev_id, a_uint32_t * time) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_ip_age_time_get(dev_id, time); + HSL_API_UNLOCK; + return rv; +} + +#if 0 +/** + * @brief Set IP WCMP table one particular device. + * @details Comments: + * Hardware only support 0 - 15 hash values and 4 different host tables. + * @param[in] dev_id device id + * @param[in] wcmp_id wcmp entry id + * @param[in] wcmp wcmp entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_ip_wcmp_entry_set(a_uint32_t dev_id, a_uint32_t wcmp_id, fal_ip_wcmp_t * wcmp) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_ip_wcmp_entry_set(dev_id, wcmp_id, wcmp); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IP WCMP table one particular device. + * @details Comments: + * Hardware only support 0 - 15 hash values and 4 different host tables. + * @param[in] dev_id device id + * @param[in] wcmp_id wcmp entry id + * @param[out] wcmp wcmp entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_ip_wcmp_entry_get(a_uint32_t dev_id, a_uint32_t wcmp_id, fal_ip_wcmp_t * wcmp) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_ip_wcmp_entry_get(dev_id, wcmp_id, wcmp); + HSL_API_UNLOCK; + return rv; +} +#endif + +/** + * @brief Set IP WCMP hash key mode. + * @param[in] dev_id device id + * @param[in] hash_mode hash mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_ip_wcmp_hash_mode_set(a_uint32_t dev_id, a_uint32_t hash_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_ip_wcmp_hash_mode_set(dev_id, hash_mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IP WCMP hash key mode. + * @param[in] dev_id device id + * @param[out] hash_mode hash mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_ip_wcmp_hash_mode_get(a_uint32_t dev_id, a_uint32_t * hash_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_ip_wcmp_hash_mode_get(dev_id, hash_mode); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +isisc_ip_init(a_uint32_t dev_id) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + rv = isisc_ip_reset(dev_id); + SW_RTN_ON_ERROR(rv); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->ip_host_add = isisc_ip_host_add; + p_api->ip_host_del = isisc_ip_host_del; + p_api->ip_host_get = isisc_ip_host_get; + p_api->ip_host_next = isisc_ip_host_next; + p_api->ip_host_counter_bind = isisc_ip_host_counter_bind; + p_api->ip_host_pppoe_bind = isisc_ip_host_pppoe_bind; + p_api->ip_pt_arp_learn_set = isisc_ip_pt_arp_learn_set; + p_api->ip_pt_arp_learn_get = isisc_ip_pt_arp_learn_get; + p_api->ip_arp_learn_set = isisc_ip_arp_learn_set; + p_api->ip_arp_learn_get = isisc_ip_arp_learn_get; + p_api->ip_source_guard_set = isisc_ip_source_guard_set; + p_api->ip_source_guard_get = isisc_ip_source_guard_get; + p_api->ip_unk_source_cmd_set = isisc_ip_unk_source_cmd_set; + p_api->ip_unk_source_cmd_get = isisc_ip_unk_source_cmd_get; + p_api->ip_arp_guard_set = isisc_ip_arp_guard_set; + p_api->ip_arp_guard_get = isisc_ip_arp_guard_get; + p_api->arp_unk_source_cmd_set = isisc_arp_unk_source_cmd_set; + p_api->arp_unk_source_cmd_get = isisc_arp_unk_source_cmd_get; + p_api->ip_route_status_set = isisc_ip_route_status_set; + p_api->ip_route_status_get = isisc_ip_route_status_get; + p_api->ip_intf_entry_add = isisc_ip_intf_entry_add; + p_api->ip_intf_entry_del = isisc_ip_intf_entry_del; + p_api->ip_intf_entry_next = isisc_ip_intf_entry_next; + p_api->ip_age_time_set = isisc_ip_age_time_set; + p_api->ip_age_time_get = isisc_ip_age_time_get; + p_api->ip_wcmp_hash_mode_set = isisc_ip_wcmp_hash_mode_set; + p_api->ip_wcmp_hash_mode_get = isisc_ip_wcmp_hash_mode_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_leaky.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_leaky.c new file mode 100755 index 000000000..14a3ddaf8 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_leaky.c @@ -0,0 +1,526 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup isisc_leaky ISISC_LEAKY + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isisc_leaky.h" +#include "isisc_reg.h" + +static sw_error_t +_isisc_uc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_LEAKY_PORT_CTRL == ctrl_mode) + { + data = 0; + } + else if (FAL_LEAKY_FDB_CTRL == ctrl_mode) + { + data = 1; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, ARL_UNI_LEAKY, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_uc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t *ctrl_mode) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, ARL_UNI_LEAKY, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *ctrl_mode = FAL_LEAKY_FDB_CTRL; + } + else + { + *ctrl_mode = FAL_LEAKY_PORT_CTRL; + } + + return SW_OK; +} + +static sw_error_t +_isisc_mc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_LEAKY_PORT_CTRL == ctrl_mode) + { + data = 0; + } + else if (FAL_LEAKY_FDB_CTRL == ctrl_mode) + { + data = 1; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, ARL_MUL_LEAKY, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_mc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t *ctrl_mode) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, ARL_MUL_LEAKY, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *ctrl_mode = FAL_LEAKY_FDB_CTRL; + } + else + { + *ctrl_mode = FAL_LEAKY_PORT_CTRL; + } + + return SW_OK; +} + +static sw_error_t +_isisc_port_arp_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LOOKUP_CTL, port_id, ARP_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_port_arp_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LOOKUP_CTL, port_id, ARP_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_port_uc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LOOKUP_CTL, port_id, UNI_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_port_uc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LOOKUP_CTL, port_id, UNI_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_port_mc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LOOKUP_CTL, port_id, MUL_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_port_mc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LOOKUP_CTL, port_id, MUL_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +/** +* @brief Set unicast packets leaky control mode on a particular device. +* @param[in] dev_id device id +* @param[in] ctrl_mode leaky control mode +* @return SW_OK or error code +*/ +HSL_LOCAL sw_error_t +isisc_uc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_uc_leaky_mode_set(dev_id, ctrl_mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get unicast packets leaky control mode on a particular device. + * @param[in] dev_id device id + * @param[out] ctrl_mode leaky control mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_uc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t *ctrl_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_uc_leaky_mode_get(dev_id, ctrl_mode); + HSL_API_UNLOCK; + return rv; +} + +/** +* @brief Set multicast packets leaky control mode on a particular device. +* @param[in] dev_id device id +* @param[in] ctrl_mode leaky control mode +* @return SW_OK or error code +*/ +HSL_LOCAL sw_error_t +isisc_mc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_mc_leaky_mode_set(dev_id, ctrl_mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get multicast packets leaky control mode on a particular device. + * @param[in] dev_id device id + * @param[out] ctrl_mode leaky control mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_mc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t *ctrl_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_mc_leaky_mode_get(dev_id, ctrl_mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set arp packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_arp_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_arp_leaky_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_arp_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_arp_leaky_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set unicast packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_uc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_uc_leaky_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get unicast packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_uc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_uc_leaky_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set multicast packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_mc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_mc_leaky_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get multicast packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_mc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_mc_leaky_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +isisc_leaky_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->uc_leaky_mode_set = isisc_uc_leaky_mode_set; + p_api->uc_leaky_mode_get = isisc_uc_leaky_mode_get; + p_api->mc_leaky_mode_set = isisc_mc_leaky_mode_set; + p_api->mc_leaky_mode_get = isisc_mc_leaky_mode_get; + p_api->port_arp_leaky_set = isisc_port_arp_leaky_set; + p_api->port_arp_leaky_get = isisc_port_arp_leaky_get; + p_api->port_uc_leaky_set = isisc_port_uc_leaky_set; + p_api->port_uc_leaky_get = isisc_port_uc_leaky_get; + p_api->port_mc_leaky_set = isisc_port_mc_leaky_set; + p_api->port_mc_leaky_get = isisc_port_mc_leaky_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_led.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_led.c new file mode 100755 index 000000000..fd3aebc38 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_led.c @@ -0,0 +1,405 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup isisc_led ISISC_LED + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "isisc_led.h" +#include "isisc_reg.h" + +#define MAX_LED_PATTERN_ID 2 +#define LED_PATTERN_ADDR 0x50 + +static sw_error_t +_isisc_led_ctrl_pattern_set(a_uint32_t dev_id, led_pattern_group_t group, + led_pattern_id_t id, led_ctrl_pattern_t * pattern) +{ + a_uint32_t data = 0, reg, mode; + a_uint32_t addr; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if ((LED_WAN_PORT_GROUP != group) && (LED_LAN_PORT_GROUP != group)) + { + return SW_BAD_PARAM; + } + + if (id > MAX_LED_PATTERN_ID) + { + return SW_BAD_PARAM; + } + + addr = LED_PATTERN_ADDR + (id << 2); + + if (LED_ALWAYS_OFF == pattern->mode) + { + mode = 0; + } + else if (LED_ALWAYS_BLINK == pattern->mode) + { + mode = 1; + } + else if (LED_ALWAYS_ON == pattern->mode) + { + mode = 2; + } + else if (LED_PATTERN_MAP_EN == pattern->mode) + { + mode = 3; + } + else + { + return SW_BAD_PARAM; + } + SW_SET_REG_BY_FIELD(LED_CTRL, PATTERN_EN, mode, data); + + if (pattern->map & (1 << FULL_DUPLEX_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, FULL_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << HALF_DUPLEX_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, HALF_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << POWER_ON_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, POWERON_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << LINK_1000M_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, GE_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << LINK_100M_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, FE_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << LINK_10M_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, ETH_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << COLLISION_BLINK_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, COL_BLINK_EN, 1, data); + } + + if (pattern->map & (1 << RX_TRAFFIC_BLINK_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, RX_BLINK_EN, 1, data); + } + + if (pattern->map & (1 << TX_TRAFFIC_BLINK_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, TX_BLINK_EN, 1, data); + } + + if (pattern->map & (1 << LINKUP_OVERRIDE_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, LINKUP_OVER_EN, 1, data); + } + else + { + SW_SET_REG_BY_FIELD(LED_CTRL, LINKUP_OVER_EN, 0, data); + } + + if (LED_BLINK_2HZ == pattern->freq) + { + SW_SET_REG_BY_FIELD(LED_CTRL, BLINK_FREQ, 0, data); + } + else if (LED_BLINK_4HZ == pattern->freq) + { + SW_SET_REG_BY_FIELD(LED_CTRL, BLINK_FREQ, 1, data); + } + else if (LED_BLINK_8HZ == pattern->freq) + { + SW_SET_REG_BY_FIELD(LED_CTRL, BLINK_FREQ, 2, data); + } + else if (LED_BLINK_TXRX == pattern->freq) + { + SW_SET_REG_BY_FIELD(LED_CTRL, BLINK_FREQ, 3, data); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (LED_WAN_PORT_GROUP == group) + { + reg &= 0xffff; + reg |= (data << 16); + } + else + { + reg &= 0xffff0000; + reg |= data; + } + + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (LED_WAN_PORT_GROUP == group) + { + return SW_OK; + } + + HSL_REG_ENTRY_GET(rv, dev_id, LED_PATTERN, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (LED_LAN_PORT_GROUP == group) + { + if (0 == id) + { + SW_SET_REG_BY_FIELD(LED_PATTERN, P3L0_MODE, mode, data); + SW_SET_REG_BY_FIELD(LED_PATTERN, P2L0_MODE, mode, data); + SW_SET_REG_BY_FIELD(LED_PATTERN, P1L0_MODE, mode, data); + } + else if (1 == id) + { + SW_SET_REG_BY_FIELD(LED_PATTERN, P3L1_MODE, mode, data); + SW_SET_REG_BY_FIELD(LED_PATTERN, P2L1_MODE, mode, data); + SW_SET_REG_BY_FIELD(LED_PATTERN, P1L1_MODE, mode, data); + } + else + { + SW_SET_REG_BY_FIELD(LED_PATTERN, P3L2_MODE, mode, data); + SW_SET_REG_BY_FIELD(LED_PATTERN, P2L2_MODE, mode, data); + SW_SET_REG_BY_FIELD(LED_PATTERN, P1L2_MODE, mode, data); + } + } + + HSL_REG_ENTRY_SET(rv, dev_id, LED_PATTERN, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +static sw_error_t +_isisc_led_ctrl_pattern_get(a_uint32_t dev_id, led_pattern_group_t group, + led_pattern_id_t id, led_ctrl_pattern_t * pattern) +{ + a_uint32_t data = 0, reg = 0, tmp; + a_uint32_t addr; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if ((LED_WAN_PORT_GROUP != group) && (LED_LAN_PORT_GROUP != group)) + { + return SW_BAD_PARAM; + } + + if (id > MAX_LED_PATTERN_ID) + { + return SW_BAD_PARAM; + } + + aos_mem_zero(pattern, sizeof(led_ctrl_pattern_t)); + + addr = LED_PATTERN_ADDR + (id << 2); + + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (LED_WAN_PORT_GROUP == group) + { + data = (reg >> 16) & 0xffff; + } + else + { + data = reg & 0xffff; + } + + SW_GET_FIELD_BY_REG(LED_CTRL, PATTERN_EN, tmp, data); + if (0 == tmp) + { + pattern->mode = LED_ALWAYS_OFF; + } + else if (1 == tmp) + { + pattern->mode = LED_ALWAYS_BLINK; + } + else if (2 == tmp) + { + pattern->mode = LED_ALWAYS_ON; + } + else + { + pattern->mode = LED_PATTERN_MAP_EN; + } + + SW_GET_FIELD_BY_REG(LED_CTRL, FULL_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << FULL_DUPLEX_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, HALF_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << HALF_DUPLEX_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, POWERON_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << POWER_ON_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, GE_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << LINK_1000M_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, FE_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << LINK_100M_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, ETH_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << LINK_10M_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, COL_BLINK_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << COLLISION_BLINK_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, RX_BLINK_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << RX_TRAFFIC_BLINK_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, TX_BLINK_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << TX_TRAFFIC_BLINK_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, LINKUP_OVER_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << LINKUP_OVERRIDE_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, BLINK_FREQ, tmp, data); + if (0 == tmp) + { + pattern->freq = LED_BLINK_2HZ; + } + else if (1 == tmp) + { + pattern->freq = LED_BLINK_4HZ; + } + else if (2 == tmp) + { + pattern->freq = LED_BLINK_8HZ; + } + else + { + pattern->freq = LED_BLINK_TXRX; + } + + return SW_OK; +} + +/** +* @brief Set led control pattern on a particular device. +* @param[in] dev_id device id +* @param[in] group pattern group, lan or wan +* @param[in] id pattern id +* @param[in] pattern led control pattern +* @return SW_OK or error code +*/ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_led_ctrl_pattern_set(dev_id, group, id, pattern); + HSL_API_UNLOCK; + return rv; +} + +/** +* @brief Get led control pattern on a particular device. +* @param[in] dev_id device id +* @param[in] group pattern group, lan or wan +* @param[in] id pattern id +* @param[out] pattern led control pattern +* @return SW_OK or error code +*/ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_led_ctrl_pattern_get(dev_id, group, id, pattern); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +isisc_led_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->led_ctrl_pattern_set = isisc_led_ctrl_pattern_set; + p_api->led_ctrl_pattern_get = isisc_led_ctrl_pattern_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_mib.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_mib.c new file mode 100755 index 000000000..5ca5def34 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_mib.c @@ -0,0 +1,860 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup isisc_mib ISISC_MIB + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isisc_mib.h" +#include "isisc_reg.h" + + +#define MIB_FLUSH_ALL_PORTS 0x1 +#define MIB_FLUSH_ONE_PORT 0x2 +#define MIB_AUTOCAST_ALL_PORTS 0x3 + +static sw_error_t +_isisc_mib_op_commit(a_uint32_t dev_id, a_uint32_t op) +{ + a_uint32_t mib_busy = 1, i = 0x1000, val; + sw_error_t rv; + + while (mib_busy && --i) + { + HSL_REG_FIELD_GET(rv, dev_id, MIB_FUNC, 0, MIB_BUSY, + (a_uint8_t *) (&mib_busy), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + aos_udelay(5); + } + + if (i == 0) + return SW_BUSY; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_FUNC, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_SET_REG_BY_FIELD(MIB_FUNC, MIB_FUN, op, val); + SW_SET_REG_BY_FIELD(MIB_FUNC, MIB_BUSY, 1, val); + + HSL_REG_ENTRY_SET(rv, dev_id, MIB_FUNC, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + mib_busy = 1; + i = 0x1000; + while (mib_busy && --i) + { + HSL_REG_FIELD_GET(rv, dev_id, MIB_FUNC, 0, MIB_BUSY, + (a_uint8_t *) (&mib_busy), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + aos_udelay(5); + } + + if (i == 0) + return SW_FAIL; + + return SW_OK; +} + +static sw_error_t +_isisc_get_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info) +{ + a_uint32_t val = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_OUT_OF_RANGE; + } + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBROAD, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxBroad = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXPAUSE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxPause = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXMULTI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxMulti = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXFCSERR, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxFcsErr = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXALLIGNERR, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxAllignErr = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXRUNT, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxRunt = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXFRAGMENT, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxFragment = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX64BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx64Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX128BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx128Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX256BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx256Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX512BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx512Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX1024BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx1024Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX1518BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx1518Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXMAXBYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxMaxByte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXTOOLONG, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxTooLong = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXGOODBYTE_LO, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxGoodByte_lo = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXGOODBYTE_HI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxGoodByte_hi = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBADBYTE_LO, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxBadByte_lo = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBADBYTE_HI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxBadByte_hi = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXOVERFLOW, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxOverFlow = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_FILTERED, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Filtered = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBROAD, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxBroad = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXPAUSE, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxPause = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMULTI, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxMulti = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXUNDERRUN, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxUnderRun = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX64BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx64Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX128BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx128Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX256BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx256Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX512BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx512Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX1024BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx1024Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX1518BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx1518Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMAXBYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxMaxByte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXOVERSIZE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxOverSize = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBYTE_LO, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxByte_lo = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBYTE_HI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxByte_hi = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXCOLLISION, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxCollision = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXABORTCOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxAbortCol = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMULTICOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxMultiCol = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXSINGALCOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxSingalCol = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXEXCDEFER, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxExcDefer = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXDEFER, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxDefer = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXLATECOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxLateCol = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXUNICAST, port_id, + (a_uint8_t *) (&val), sizeof + (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxUniCast = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXUNICAST, port_id, + (a_uint8_t *) (&val), sizeof + (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxUniCast = val; + + return SW_OK; +} + +static sw_error_t +_isisc_get_rx_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info) +{ + a_uint32_t val = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_OUT_OF_RANGE; + } + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBROAD, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxBroad = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXPAUSE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxPause = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXMULTI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxMulti = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXFCSERR, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxFcsErr = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXALLIGNERR, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxAllignErr = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXRUNT, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxRunt = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXFRAGMENT, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxFragment = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX64BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx64Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX128BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx128Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX256BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx256Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX512BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx512Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX1024BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx1024Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX1518BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx1518Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXMAXBYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxMaxByte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXTOOLONG, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxTooLong = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXGOODBYTE_LO, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxGoodByte_lo = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXGOODBYTE_HI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxGoodByte_hi = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBADBYTE_LO, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxBadByte_lo = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBADBYTE_HI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxBadByte_hi = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXOVERFLOW, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxOverFlow = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_FILTERED, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Filtered = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXUNICAST, port_id, + (a_uint8_t *) (&val), sizeof + (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxUniCast = val; + + return SW_OK; +} + +static sw_error_t +_isisc_get_tx_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info) +{ + a_uint32_t val = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_OUT_OF_RANGE; + } + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBROAD, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxBroad = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXPAUSE, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxPause = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMULTI, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxMulti = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXUNDERRUN, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxUnderRun = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX64BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx64Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX128BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx128Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX256BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx256Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX512BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx512Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX1024BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx1024Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX1518BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx1518Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMAXBYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxMaxByte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXOVERSIZE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxOverSize = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBYTE_LO, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxByte_lo = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBYTE_HI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxByte_hi = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXCOLLISION, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxCollision = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXABORTCOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxAbortCol = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMULTICOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxMultiCol = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXSINGALCOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxSingalCol = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXEXCDEFER, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxExcDefer = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXDEFER, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxDefer = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXLATECOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxLateCol = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXUNICAST, port_id, + (a_uint8_t *) (&val), sizeof + (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxUniCast = val; + + return SW_OK; +} + +static sw_error_t +_isisc_mib_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, MOD_ENABLE, 0, MIB_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_mib_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, MOD_ENABLE, 0, MIB_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_mib_cpukeep_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, MIB_FUNC, 0, MIB_CPU_KEEP, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return rv; +} + +static sw_error_t +_isisc_mib_cpukeep_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, MIB_FUNC, 0, MIB_CPU_KEEP, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_mib_port_flush_counters(a_uint32_t dev_id, fal_port_t port_id) +{ + a_uint32_t val; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_OUT_OF_RANGE; + } + + if (port_id>7) + return SW_BAD_PARAM; + + val = port_id; + HSL_REG_FIELD_SET(rv, dev_id, MIB_FUNC, 0, MIB_FLUSH_PORT, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + rv = _isisc_mib_op_commit( dev_id, MIB_FLUSH_ONE_PORT); + + return rv; +} + +/** + * @brief Get mib infomation on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mib_info mib infomation + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_get_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_get_mib_info(dev_id, port_id, mib_info); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get RX mib infomation on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mib_info mib infomation + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_get_rx_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_get_rx_mib_info(dev_id, port_id, mib_info); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get TX mib infomation on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mib_info mib infomation + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_get_tx_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_get_tx_mib_info(dev_id, port_id, mib_info); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set mib status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_mib_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_mib_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mib status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_mib_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_mib_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +HSL_LOCAL sw_error_t +isisc_mib_port_flush_counters(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_mib_port_flush_counters(dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set mib cpu keep bit on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_mib_cpukeep_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_mib_cpukeep_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mib keep bit on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_mib_cpukeep_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_mib_cpukeep_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +isisc_mib_init(a_uint32_t dev_id) +{ +#ifndef HSL_STANDALONG + hsl_api_t *p_api; +#endif + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->get_mib_info = isisc_get_mib_info; + p_api->get_rx_mib_info = isisc_get_rx_mib_info; + p_api->get_tx_mib_info = isisc_get_tx_mib_info; + p_api->mib_status_set = isisc_mib_status_set; + p_api->mib_status_get = isisc_mib_status_get; + p_api->mib_port_flush_counters = isisc_mib_port_flush_counters; + p_api->mib_cpukeep_set = isisc_mib_cpukeep_set; + p_api->mib_cpukeep_get = isisc_mib_cpukeep_get; +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_mirror.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_mirror.c new file mode 100755 index 000000000..12441dc63 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_mirror.c @@ -0,0 +1,315 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup isisc_mirror ISISC_MIRROR + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isisc_mirror.h" +#include "isisc_reg.h" + +static sw_error_t +_isisc_mirr_analysis_port_set(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + if (port_id != MIRROR_ANALYZER_NONE) { + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) { + return SW_BAD_PARAM; + } + } + val = port_id; + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, MIRROR_PORT_NUM, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_mirr_analysis_port_get(a_uint32_t dev_id, fal_port_t * port_id) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, MIRROR_PORT_NUM, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *port_id = val; + return SW_OK; +} + +static sw_error_t +_isisc_mirr_port_in_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LOOKUP_CTL, port_id, ING_MIRROR_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_mirr_port_in_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LOOKUP_CTL, port_id, ING_MIRROR_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_mirr_port_eg_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_HOL_CTL1, port_id, EG_MIRROR_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_mirr_port_eg_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_HOL_CTL1, port_id, EG_MIRROR_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +/** + * @details Comments: + * The analysis port works for both ingress and egress mirror. + * @brief Set mirror analyzer port on particular a device. + * @param[in] dev_id device id + * @param[in] port_id port id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_mirr_analysis_port_set(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_mirr_analysis_port_set(dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mirror analysis port on particular a device. + * @param[in] dev_id device id + * @param[out] port_id port id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_mirr_analysis_port_get(a_uint32_t dev_id, fal_port_t * port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_mirr_analysis_port_get(dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set ingress mirror status on particular a port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_mirr_port_in_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_mirr_port_in_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get ingress mirror status on particular a port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_mirr_port_in_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_mirr_port_in_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set egress mirror status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_mirr_port_eg_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_mirr_port_eg_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get egress mirror status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_mirr_port_eg_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_mirr_port_eg_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +isisc_mirr_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->mirr_analysis_port_set = isisc_mirr_analysis_port_set; + p_api->mirr_analysis_port_get = isisc_mirr_analysis_port_get; + p_api->mirr_port_in_set = isisc_mirr_port_in_set; + p_api->mirr_port_in_get = isisc_mirr_port_in_get; + p_api->mirr_port_eg_set = isisc_mirr_port_eg_set; + p_api->mirr_port_eg_get = isisc_mirr_port_eg_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_misc.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_misc.c new file mode 100755 index 000000000..bc79d4915 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_misc.c @@ -0,0 +1,2207 @@ +/* + * Copyright (c) 2012, 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 isisc_misc ISISC_MISC + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isisc_misc.h" +#include "isisc_reg.h" +#include "hsl_phy.h" + + +#define ISISC_MAX_FRMAE_SIZE 9216 + +#define ARP_REQ_EN_OFFSET 6 +#define ARP_ACK_EN_OFFSET 5 +#define DHCP_EN_OFFSET 4 +#define EAPOL_EN_OFFSET 3 + +#define ISISC_SWITCH_INT_PHY_INT 0x8000 + + +static sw_error_t +_isisc_port_misc_property_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable, a_uint32_t item) +{ + sw_error_t rv; + a_uint32_t reg = 0, val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + if (3 >= port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, FRAME_ACK_CTL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + reg &= ~(0x1UL << ((port_id << 3) + item)); + reg |= (val << ((port_id << 3) + item)); + + HSL_REG_ENTRY_SET(rv, dev_id, FRAME_ACK_CTL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + else + { + HSL_REG_ENTRY_GET(rv, dev_id, FRAME_ACK_CTL1, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + reg &= ~(0x1UL << (((port_id - 4) << 3) + item)); + reg |= (val << (((port_id - 4) << 3) + item)); + + HSL_REG_ENTRY_SET(rv, dev_id, FRAME_ACK_CTL1, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + } + return rv; +} + +#ifndef IN_MISC_MINI +static sw_error_t +_isisc_port_misc_property_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable, a_uint32_t item) +{ + sw_error_t rv; + a_uint32_t reg = 0, val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (3 >= port_id) + { + HSL_REG_ENTRY_GET(rv, dev_id, FRAME_ACK_CTL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + val = (reg >> ((port_id << 3) + item)) & 0x1UL; + } + else + { + HSL_REG_ENTRY_GET(rv, dev_id, FRAME_ACK_CTL1, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + val = (reg >> (((port_id - 4) << 3) + item)) & 0x1UL; + } + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} +#endif + +static sw_error_t +_isisc_frame_max_size_set(a_uint32_t dev_id, a_uint32_t size) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (ISISC_MAX_FRMAE_SIZE < size) + { + return SW_BAD_PARAM; + } + + data = size; + HSL_REG_FIELD_SET(rv, dev_id, MAX_SIZE, 0, MAX_FRAME_SIZE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_frame_max_size_get(a_uint32_t dev_id, a_uint32_t * size) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, MAX_SIZE, 0, MAX_FRAME_SIZE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *size = data; + return SW_OK; +} + +static sw_error_t +_isisc_port_unk_uc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL1, 0, UNI_FLOOD_DP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + data &= (~((a_uint32_t) 0x1 << port_id)); + } + else if (A_FALSE == enable) + { + data |= (0x1 << port_id); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL1, 0, UNI_FLOOD_DP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + + +static sw_error_t +_isisc_port_unk_mc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL1, 0, MUL_FLOOD_DP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + data &= (~((a_uint32_t) 0x1 << port_id)); + } + else if (A_FALSE == enable) + { + data |= (0x1 << port_id); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL1, 0, MUL_FLOOD_DP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + + +static sw_error_t +_isisc_port_bc_filter_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL1, 0, BC_FLOOD_DP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + data &= (~((a_uint32_t) 0x1 << port_id)); + } + else if (A_FALSE == enable) + { + data |= (0x1 << port_id); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL1, 0, BC_FLOOD_DP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_cpu_port_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, CPU_PORT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +#ifndef IN_MISC_MINI +static sw_error_t +_isisc_port_bc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t reg = 0, field; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL1, 0, BC_FLOOD_DP, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + field = reg & (0x1 << port_id); + if (field) + { + *enable = A_FALSE; + } + else + { + *enable = A_TRUE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_port_unk_uc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t reg = 0, field; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL1, 0, UNI_FLOOD_DP, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + field = reg & (0x1 << port_id); + if (field) + { + *enable = A_FALSE; + } + else + { + *enable = A_TRUE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_port_unk_mc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t reg = 0, field; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL1, 0, MUL_FLOOD_DP, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + field = reg & (0x1 << port_id); + if (field) + { + *enable = A_FALSE; + } + else + { + *enable = A_TRUE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_cpu_port_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, CPU_PORT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_cpu_vid_en_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PKT_CTRL, 0, CPU_VID_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_cpu_vid_en_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, PKT_CTRL, 0, CPU_VID_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_rtd_pppoe_en_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PKT_CTRL, 0, RTD_PPPOE_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_rtd_pppoe_en_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, PKT_CTRL, 0, RTD_PPPOE_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + + +static sw_error_t +_isisc_pppoe_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_MAC_FRWRD == cmd) + { + val = 0; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + val = 1; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, PPPOE_RDT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_pppoe_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, PPPOE_RDT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + else + { + *cmd = FAL_MAC_FRWRD; + } + + return SW_OK; +} + +static sw_error_t +_isisc_pppoe_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FRAME_ACK_CTL1, 0, PPPOE_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_pppoe_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FRAME_ACK_CTL1, 0, PPPOE_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_arp_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_MAC_CPY_TO_CPU == cmd) + { + val = 1; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + val = 0; + } + else if (FAL_MAC_FRWRD == cmd) + { + val = 2; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, ARP_CMD, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_arp_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, ARP_CMD, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *cmd = FAL_MAC_CPY_TO_CPU; + } + else if (0 == val) + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + else + { + *cmd = FAL_MAC_FRWRD; + } + + return SW_OK; +} +#endif + +static sw_error_t +_isisc_eapol_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_MAC_CPY_TO_CPU == cmd) + { + val = 0; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + val = 1; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, EAPOL_CMD, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +#ifndef IN_MISC_MINI +static sw_error_t +_isisc_eapol_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, EAPOL_CMD, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0 == val) + { + *cmd = FAL_MAC_CPY_TO_CPU; + } + else + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + + return SW_OK; +} + +#define ISISC_MAX_PPPOE_SESSION 16 +#define ISISC_MAX_SESSION_ID 0xffff + +static sw_error_t +_isisc_pppoe_session_add(a_uint32_t dev_id, fal_pppoe_session_t * session_tbl) +{ + sw_error_t rv; + a_uint32_t reg = 0, i, valid, id, entry_idx = ISISC_MAX_PPPOE_SESSION; + + HSL_DEV_ID_CHECK(dev_id); + + if (session_tbl->session_id > ISISC_MAX_SESSION_ID) + { + return SW_BAD_PARAM; + } + + if ((A_FALSE == session_tbl->multi_session) + && (A_TRUE == session_tbl->uni_session)) + { + return SW_BAD_PARAM; + } + + if ((A_FALSE == session_tbl->multi_session) + && (A_FALSE == session_tbl->uni_session)) + { + return SW_BAD_PARAM; + } + + for (i = 0; i < ISISC_MAX_PPPOE_SESSION; i++) + { + HSL_REG_ENTRY_GET(rv, dev_id, PPPOE_SESSION, i, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PPPOE_SESSION, ENTRY_VALID, valid, reg); + SW_GET_FIELD_BY_REG(PPPOE_SESSION, SEESION_ID, id, reg); + + if (!valid) + { + entry_idx = i; + } + else if (id == session_tbl->session_id) + { + return SW_ALREADY_EXIST; + } + } + + if (ISISC_MAX_PPPOE_SESSION == entry_idx) + { + return SW_NO_RESOURCE; + } + +#if 0 + if (A_TRUE == session_tbl->uni_session) + { + SW_SET_REG_BY_FIELD(PPPOE_SESSION, ENTRY_VALID, 2, reg); + } + else +#endif + { + SW_SET_REG_BY_FIELD(PPPOE_SESSION, ENTRY_VALID, 1, reg); + } + SW_SET_REG_BY_FIELD(PPPOE_SESSION, SEESION_ID, session_tbl->session_id, + reg); + + HSL_REG_ENTRY_SET(rv, dev_id, PPPOE_SESSION, entry_idx, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + session_tbl->entry_id = entry_idx; + return SW_OK; +} + +static sw_error_t +_isisc_pppoe_session_del(a_uint32_t dev_id, fal_pppoe_session_t * session_tbl) +{ + sw_error_t rv; + a_uint32_t reg = 0, i, valid, id; + + HSL_DEV_ID_CHECK(dev_id); + + if (session_tbl->session_id > ISISC_MAX_SESSION_ID) + { + return SW_BAD_PARAM; + } + + for (i = 0; i < ISISC_MAX_PPPOE_SESSION; i++) + { + HSL_REG_ENTRY_GET(rv, dev_id, PPPOE_SESSION, i, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PPPOE_SESSION, ENTRY_VALID, valid, reg); + SW_GET_FIELD_BY_REG(PPPOE_SESSION, SEESION_ID, id, reg); + + if (((1 == valid) || (2 == valid)) && (id == session_tbl->session_id)) + { + SW_SET_REG_BY_FIELD(PPPOE_SESSION, ENTRY_VALID, 0, reg); + SW_SET_REG_BY_FIELD(PPPOE_SESSION, SEESION_ID, 0, reg); + HSL_REG_ENTRY_SET(rv, dev_id, PPPOE_SESSION, i, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; + } + } + + return SW_NOT_FOUND; +} + +static sw_error_t +_isisc_pppoe_session_get(a_uint32_t dev_id, fal_pppoe_session_t * session_tbl) +{ + sw_error_t rv; + a_uint32_t reg = 0, i, valid, id; + + HSL_DEV_ID_CHECK(dev_id); + + if (session_tbl->session_id > ISISC_MAX_SESSION_ID) + { + return SW_BAD_PARAM; + } + + for (i = 0; i < ISISC_MAX_PPPOE_SESSION; i++) + { + HSL_REG_ENTRY_GET(rv, dev_id, PPPOE_SESSION, i, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PPPOE_SESSION, ENTRY_VALID, valid, reg); + SW_GET_FIELD_BY_REG(PPPOE_SESSION, SEESION_ID, id, reg); + + if (((1 == valid) || (2 == valid)) && (id == session_tbl->session_id)) + { + if (1 == valid) + { + session_tbl->multi_session = A_TRUE; + session_tbl->uni_session = A_FALSE; + } + else + { + session_tbl->multi_session = A_TRUE; + session_tbl->uni_session = A_TRUE; + } + + session_tbl->entry_id = i; + return SW_OK; + } + } + + return SW_NOT_FOUND; +} + +static sw_error_t +_isisc_pppoe_session_id_set(a_uint32_t dev_id, a_uint32_t index, + a_uint32_t id) +{ + sw_error_t rv; + a_uint32_t reg; + + if (ISISC_MAX_PPPOE_SESSION <= index) + { + return SW_BAD_PARAM; + } + + if (ISISC_MAX_SESSION_ID < id) + { + return SW_BAD_PARAM; + } + + reg = 0; + SW_SET_REG_BY_FIELD(PPPOE_EDIT, EDIT_ID, id, reg); + HSL_REG_ENTRY_SET(rv, dev_id, PPPOE_EDIT, index, (a_uint8_t *) (®), + sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_isisc_pppoe_session_id_get(a_uint32_t dev_id, a_uint32_t index, + a_uint32_t * id) +{ + sw_error_t rv; + a_uint32_t reg = 0, tmp; + + if (ISISC_MAX_PPPOE_SESSION <= index) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PPPOE_EDIT, index, (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + tmp = 0; + SW_GET_FIELD_BY_REG(PPPOE_EDIT, EDIT_ID, tmp, reg); + *id = tmp; + return SW_OK; +} + +static sw_error_t +_isisc_ripv1_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, 0, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, RIP_CPY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_ripv1_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, 0, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, RIP_CPY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_intr_mask_set(a_uint32_t dev_id, a_uint32_t intr_mask) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + HSL_REG_ENTRY_GET(rv, dev_id, GBL_INT_MASK1, 0, (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (intr_mask & FAL_SWITCH_INTR_LINK_STATUS) + { + reg |= ISISC_SWITCH_INT_PHY_INT; + } + else + { + reg &= (~ISISC_SWITCH_INT_PHY_INT); + } + + HSL_REG_ENTRY_SET(rv, dev_id, GBL_INT_MASK1, 0, (a_uint8_t *) (®), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_intr_mask_get(a_uint32_t dev_id, a_uint32_t * intr_mask) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + *intr_mask = 0; + HSL_REG_ENTRY_GET(rv, dev_id, GBL_INT_MASK1, 0, (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (reg & ISISC_SWITCH_INT_PHY_INT) + { + *intr_mask |= FAL_SWITCH_INTR_LINK_STATUS; + } + + return SW_OK; +} + +static sw_error_t +_isisc_intr_status_get(a_uint32_t dev_id, a_uint32_t * intr_status) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + *intr_status = 0; + HSL_REG_ENTRY_GET(rv, dev_id, GBL_INT_STATUS1, 0, (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (reg & ISISC_SWITCH_INT_PHY_INT) + { + *intr_status |= FAL_SWITCH_INTR_LINK_STATUS; + } + + return SW_OK; +} + +static sw_error_t +_isisc_intr_status_clear(a_uint32_t dev_id, a_uint32_t intr_status) +{ + sw_error_t rv; + a_uint32_t reg; + + reg = 0; + if (intr_status & FAL_SWITCH_INTR_LINK_STATUS) + { + reg |= ISISC_SWITCH_INT_PHY_INT; + } + + HSL_REG_ENTRY_SET(rv, dev_id, GBL_INT_STATUS1, 0, (a_uint8_t *) (®), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_port_link_intr_mask_set(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t intr_mask_flag) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_intr_mask_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_intr_mask_set(dev_id, phy_id, intr_mask_flag); + return rv; +} + +static sw_error_t +_isisc_port_link_intr_mask_get(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t * intr_mask_flag) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_intr_mask_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_intr_mask_get(dev_id, phy_id, intr_mask_flag); + return rv; +} + +static sw_error_t +_isisc_port_link_intr_status_get(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t * intr_mask_flag) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_intr_status_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_intr_status_get(dev_id, phy_id, intr_mask_flag); + return rv; +} + +static sw_error_t +_isisc_intr_mask_mac_linkchg_set(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, GBL_INT_MASK1, 0, LINK_CHG_INT_M, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_FALSE == enable) + { + data &= (~((a_uint32_t) 0x1 << port_id)); + } + else if (A_TRUE == enable) + { + data |= (0x1 << port_id); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, GBL_INT_MASK1, 0, LINK_CHG_INT_M, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + + return rv; +} + + +static sw_error_t +_isisc_intr_mask_mac_linkchg_get(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t reg = 0, field; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, GBL_INT_MASK1, 0, LINK_CHG_INT_M, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + field = reg & (0x1 << port_id); + if (field) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + + +static sw_error_t +_isisc_intr_status_mac_linkchg_get(a_uint32_t dev_id, fal_pbmp_t* port_bitmap) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, GBL_INT_STATUS1, 0, LINK_CHG_INT_S, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + *port_bitmap = reg; + + return rv; + +} + +static sw_error_t +_isisc_intr_status_mac_linkchg_clear(a_uint32_t dev_id) +{ + sw_error_t rv; + a_uint32_t reg; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, GBL_INT_STATUS1, 0, LINK_CHG_INT_S, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + HSL_REG_FIELD_SET(rv, dev_id, GBL_INT_STATUS1, 0, LINK_CHG_INT_S, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + return rv; + +} +#endif + +/** + * @brief Set max frame size which device can received on a particular device. + * @details Comments: + * The granularity of packets size is byte. + * @param[in] dev_id device id + * @param[in] size packet size + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_frame_max_size_set(a_uint32_t dev_id, a_uint32_t size) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_frame_max_size_set(dev_id, size); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get max frame size which device can received on a particular device. + * @details Comments: + * The unit of packets size is byte. + * @param[in] dev_id device id + * @param[out] size packet size + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_frame_max_size_get(a_uint32_t dev_id, a_uint32_t * size) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_frame_max_size_get(dev_id, size); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flooding status of unknown unicast packets on a particular port. + * @details Comments: + * If enable unknown unicast packets filter on one port then unknown + * unicast packets can't flood out from this port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_unk_uc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_unk_uc_filter_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flooding status of unknown multicast packets on a particular port. + * @details Comments: + * If enable unknown multicast packets filter on one port then unknown + * multicast packets can't flood out from this port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_unk_mc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_unk_mc_filter_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flooding status of broadcast packets on a particular port. + * @details Comments: + * If enable unknown multicast packets filter on one port then unknown + * multicast packets can't flood out from this port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_bc_filter_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_bc_filter_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set cpu port status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_cpu_port_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_cpu_port_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +#ifndef IN_MISC_MINI +/** + * @brief Get flooding status of unknown unicast packets on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_unk_uc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_unk_uc_filter_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** @brief Get flooding status of unknown multicast packets on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_unk_mc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_unk_mc_filter_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** @brief Get flooding status of broadcast packets on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_bc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_bc_filter_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get cpu port status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_cpu_port_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_cpu_port_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set pppoe packets forwarding command on a particular device. + * @details comments: + * Particular device may only support parts of forwarding commands. + * Ihis operation will take effect only after enabling pppoe packets + * hardware acknowledgement + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_pppoe_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_pppoe_cmd_set(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get pppoe packets forwarding command on a particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_pppoe_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_pppoe_cmd_get(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set pppoe packets hardware acknowledgement status on particular device. + * @details comments: + * Particular device may only support parts of pppoe packets. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_pppoe_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_pppoe_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get pppoe packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_pppoe_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_pppoe_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dhcp packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_dhcp_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_misc_property_set(dev_id, port_id, enable, DHCP_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dhcp packets hardware acknowledgement status on particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_dhcp_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_misc_property_get(dev_id, port_id, enable, DHCP_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set arp packets forwarding command on a particular device. + * @details comments: + * Particular device may only support parts of forwarding commands. + * Ihis operation will take effect only after enabling arp packets + * hardware acknowledgement + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_arp_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_arp_cmd_set(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp packets forwarding command on a particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_arp_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_arp_cmd_get(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} +#endif + +/** + * @brief Set eapol packets forwarding command on a particular device. + * @details comments: + * Particular device may only support parts of forwarding commands. + * Ihis operation will take effect only after enabling eapol packets + * hardware acknowledgement + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_eapol_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_eapol_cmd_set(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +#ifndef IN_MISC_MINI +/** + * @brief Get eapol packets forwarding command on a particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_eapol_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_eapol_cmd_get(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add a pppoe session entry to a particular device. + * The entry only for pppoe/ppp header remove. + * @param[in] dev_id device id + * @param[in] session_tbl pppoe session table + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_pppoe_session_table_add(a_uint32_t dev_id, + fal_pppoe_session_t * session_tbl) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_pppoe_session_add(dev_id, session_tbl); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a pppoe session entry from a particular device. + * The entry only for pppoe/ppp header remove. + * @param[in] dev_id device id + * @param[in] session_tbl pppoe session table + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_pppoe_session_table_del(a_uint32_t dev_id, + fal_pppoe_session_t * session_tbl) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_pppoe_session_del(dev_id, session_tbl); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get a pppoe session entry from a particular device. + * The entry only for pppoe/ppp header remove. + * @param[in] dev_id device id + * @param[out] session_tbl pppoe session table + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_pppoe_session_table_get(a_uint32_t dev_id, + fal_pppoe_session_t * session_tbl) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_pppoe_session_get(dev_id, session_tbl); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set a pppoe session id entry to a particular device. + * The entry only for pppoe/ppp header add. + * @param[in] dev_id device id + * @param[in] session_tbl pppoe session table + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_pppoe_session_id_set(a_uint32_t dev_id, a_uint32_t index, + a_uint32_t id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_pppoe_session_id_set(dev_id, index, id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get a pppoe session id entry from a particular device. + * The entry only for pppoe/ppp header add. + * @param[in] dev_id device id + * @param[out] session_tbl pppoe session table + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_pppoe_session_id_get(a_uint32_t dev_id, a_uint32_t index, + a_uint32_t * id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_pppoe_session_id_get(dev_id, index, id); + HSL_API_UNLOCK; + return rv; +} +#endif + +/** + * @brief Set eapol packets hardware acknowledgement status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_eapol_status_set(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_misc_property_set(dev_id, port_id, enable, EAPOL_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +#ifndef IN_MISC_MINI +/** + * @brief Get eapol packets hardware acknowledgement status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_eapol_status_get(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_misc_property_get(dev_id, port_id, enable, EAPOL_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set rip v1 packets hardware acknowledgement status on a particular port. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_ripv1_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_ripv1_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get rip v1 packets hardware acknowledgement status on a particular port. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_ripv1_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_ripv1_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set arp req packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_arp_req_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_misc_property_set(dev_id, port_id, enable, + ARP_REQ_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp req packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_arp_req_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_misc_property_get(dev_id, port_id, enable, + ARP_REQ_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set arp ack packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_arp_ack_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_misc_property_set(dev_id, port_id, enable, + ARP_ACK_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp ack packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_arp_ack_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_misc_property_get(dev_id, port_id, enable, + ARP_ACK_EN_OFFSET); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set switch interrupt mask on one particular device. + * @param[in] dev_id device id + * @param[in] intr_mask mask + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_intr_mask_set(a_uint32_t dev_id, a_uint32_t intr_mask) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_intr_mask_set(dev_id, intr_mask); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get switch interrupt mask on one particular device. + * @param[in] dev_id device id + * @param[in] intr_mask mask + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_intr_mask_get(a_uint32_t dev_id, a_uint32_t * intr_mask) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_intr_mask_get(dev_id, intr_mask); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get switch interrupt status on one particular device. + * @param[in] dev_id device id + * @param[in] intr_status status + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_intr_status_get(a_uint32_t dev_id, a_uint32_t * intr_status) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_intr_status_get(dev_id, intr_status); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Clear switch interrupt status on one particular device. + * @param[in] dev_id device id + * @param[in] intr_status status + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_intr_status_clear(a_uint32_t dev_id, a_uint32_t intr_status) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_intr_status_clear(dev_id, intr_status); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set link interrupt mask on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] intr_mask_flag interrupt mask + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_intr_port_link_mask_set(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t intr_mask_flag) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _isisc_port_link_intr_mask_set(dev_id, port_id, intr_mask_flag); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get link interrupt mask on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] intr_mask_flag interrupt mask + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_intr_port_link_mask_get(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t * intr_mask_flag) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_link_intr_mask_get(dev_id, port_id, intr_mask_flag); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get link interrupt status on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] intr_mask_flag interrupt mask + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_intr_port_link_status_get(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t * intr_mask_flag) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_link_intr_status_get(dev_id, port_id, intr_mask_flag); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set mac link change interrupt mask on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable ports intr mask enabled + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_intr_mask_mac_linkchg_set(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t enable) +{ + sw_error_t rv; + FAL_API_LOCK; + rv = _isisc_intr_mask_mac_linkchg_set(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mac link change interrupt mask on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] port interrupt mask or not + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_intr_mask_mac_linkchg_get(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _isisc_intr_mask_mac_linkchg_get(dev_id, port_id, enable); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Get link change interrupt status for all ports. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] ports bitmap which generates interrupt + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_intr_status_mac_linkchg_get(a_uint32_t dev_id, fal_pbmp_t* port_bitmap) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _isisc_intr_status_mac_linkchg_get(dev_id, port_bitmap); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief Set cpu vid enable status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_cpu_vid_en_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_cpu_vid_en_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get cpu vid enable status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_cpu_vid_en_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_cpu_vid_en_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set RM_RTD_PPPOE_EN status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_rtd_pppoe_en_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_rtd_pppoe_en_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get RM_RTD_PPPOE_EN status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_rtd_pppoe_en_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_rtd_pppoe_en_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Clear link change interrupt status for all ports. + * @param[in] dev_id device id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_intr_status_mac_linkchg_clear(a_uint32_t dev_id) +{ + sw_error_t rv; + + FAL_API_LOCK; + rv = _isisc_intr_status_mac_linkchg_clear(dev_id); + FAL_API_UNLOCK; + return rv; +} +#endif + +sw_error_t +isisc_misc_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->frame_max_size_set = isisc_frame_max_size_set; + p_api->frame_max_size_get = isisc_frame_max_size_get; + p_api->port_unk_uc_filter_set = isisc_port_unk_uc_filter_set; + p_api->port_unk_mc_filter_set = isisc_port_unk_mc_filter_set; + p_api->port_bc_filter_set = isisc_port_bc_filter_set; + p_api->cpu_port_status_set = isisc_cpu_port_status_set; +#ifndef IN_MISC_MINI + p_api->port_unk_uc_filter_get = isisc_port_unk_uc_filter_get; + p_api->port_unk_mc_filter_get = isisc_port_unk_mc_filter_get; + p_api->port_bc_filter_get = isisc_port_bc_filter_get; + p_api->cpu_port_status_get = isisc_cpu_port_status_get; + p_api->pppoe_cmd_set = isisc_pppoe_cmd_set; + p_api->pppoe_cmd_get = isisc_pppoe_cmd_get; + p_api->pppoe_status_set = isisc_pppoe_status_set; + p_api->pppoe_status_get = isisc_pppoe_status_get; + p_api->port_dhcp_set = isisc_port_dhcp_set; + p_api->port_dhcp_get = isisc_port_dhcp_get; + p_api->arp_cmd_set = isisc_arp_cmd_set; + p_api->arp_cmd_get = isisc_arp_cmd_get; +#endif + p_api->eapol_cmd_set = isisc_eapol_cmd_set; +#ifndef IN_MISC_MINI + p_api->eapol_cmd_get = isisc_eapol_cmd_get; + p_api->pppoe_session_table_add = isisc_pppoe_session_table_add; + p_api->pppoe_session_table_del = isisc_pppoe_session_table_del; + p_api->pppoe_session_table_get = isisc_pppoe_session_table_get; + p_api->pppoe_session_id_set = isisc_pppoe_session_id_set; + p_api->pppoe_session_id_get = isisc_pppoe_session_id_get; +#endif + p_api->eapol_status_set = isisc_eapol_status_set; +#ifndef IN_MISC_MINI + p_api->eapol_status_get = isisc_eapol_status_get; + p_api->ripv1_status_set = isisc_ripv1_status_set; + p_api->ripv1_status_get = isisc_ripv1_status_get; + p_api->port_arp_req_status_set = isisc_port_arp_req_status_set; + p_api->port_arp_req_status_get = isisc_port_arp_req_status_get; + p_api->port_arp_ack_status_set = isisc_port_arp_ack_status_set; + p_api->port_arp_ack_status_get = isisc_port_arp_ack_status_get; + p_api->intr_mask_set = isisc_intr_mask_set; + p_api->intr_mask_get = isisc_intr_mask_get; + p_api->intr_status_get = isisc_intr_status_get; + p_api->intr_status_clear = isisc_intr_status_clear; + p_api->intr_port_link_mask_set = isisc_intr_port_link_mask_set; + p_api->intr_port_link_mask_get = isisc_intr_port_link_mask_get; + p_api->intr_port_link_status_get = isisc_intr_port_link_status_get; + p_api->intr_mask_mac_linkchg_set = isisc_intr_mask_mac_linkchg_set; + p_api->intr_mask_mac_linkchg_get = isisc_intr_mask_mac_linkchg_get; + p_api->intr_status_mac_linkchg_get = isisc_intr_status_mac_linkchg_get; + p_api->cpu_vid_en_set = isisc_cpu_vid_en_set; + p_api->cpu_vid_en_get = isisc_cpu_vid_en_get; + p_api->rtd_pppoe_en_set = isisc_rtd_pppoe_en_set; + p_api->rtd_pppoe_en_get = isisc_rtd_pppoe_en_get; + p_api->intr_status_mac_linkchg_clear = isisc_intr_status_mac_linkchg_clear; +#endif + + } +#endif + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_multicast_acl.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_multicast_acl.c new file mode 100755 index 000000000..befd61cd5 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_multicast_acl.c @@ -0,0 +1,1024 @@ +/* + * Copyright (c) 2012, 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. + */ + + + +#include "fal_nat.h" +#include "fal_ip.h" +#include "hsl_api.h" +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isisc_igmp.h" +#include "isisc_reg.h" +#include "isisc_acl.h" +#include "fal_multi.h" +#include "sal/os/aos_lock.h" + +#if 0 +/** + * I/F prototype for complete igmpv3 & mldv2 support + */ + +/*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; +} fal_igmp_sg_entry_t; + +/** + * @brief set PortMap of IGMP sg entry. + * search entry according to source/group address, + * update PortMap if SG entry is found, otherwise create a new sg entry. + * @param[in] dev_id device id + * @param[in-out] entry SG entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_igmp_sg_entry_set(a_uint32_t dev_id, fal_igmp_sg_entry_t * entry); + +/** + * @brief clear PortMap of IGMP sg entry. + * search entry according to source/group address, + * update PortMap if SG entry is found, delete the entry in case PortMap was 0. + * SW_NOT_FOUND will be returned in case search failed. + * @param[in] dev_id device id + * @param[in-out] entry SG entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_igmp_sg_entry_clear(a_uint32_t dev_id, fal_igmp_sg_entry_t * entry); + +#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 1 +#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; +#endif + +static a_uint32_t mul_rule_nr=1; + +void +isisc_multicast_init(a_uint32_t dev_id); + +HSL_LOCAL sw_error_t multi_portmap_aclreg_set(a_uint32_t dev_id, a_uint32_t pos, fal_igmp_sg_entry_t * entry); + +static multi_acl_info_t multi_acl_info[FAL_IGMP_SG_ENTRY_MAX]; +static multi_acl_info_t multi_acl_group[FAL_IGMP_SG_ENTRY_MAX]; + +static int ip6_addr_is_null(fal_ip6_addr_t *ip6) +{ + if (NULL == ip6) + { + aos_printk("Invalid ip6 address\n"); + return -1; + } + if(0 == ip6->ul[0] && 0 == ip6->ul[1] && 0 == ip6->ul[2] && 0 == ip6->ul[3]) + return 1; + else + return 0; +} +static int multi_source_is_null(fal_igmp_sg_addr_t *s) +{ + if (NULL == s) + { + aos_printk("Invalid source address\n"); + return -1; + } + if(0 == s->type && 0==s->u.ip4_addr) + return 1; + if(1 == s->type && 1 == ip6_addr_is_null(&(s->u.ip6_addr))) + return 1; + + return 0; +} + +HSL_LOCAL int iterate_multicast_acl_rule(a_uint32_t dev_id, int list_id, int start_n) +{ + a_uint32_t rule_id; + sw_error_t ret; + fal_acl_rule_t rule= {0}; + + if(start_n>=FAL_IGMP_SG_ENTRY_MAX || start_n < 0) + { + return -1; + } + + for(rule_id=0; rule_id=FAL_IGMP_SG_ENTRY_MAX) + { + return -1; + } + + multi_acl_info[rule_id+start_n].index = rule_id; // consider here... index is NOT related start_n + //MULTI_DEBUG("normal query1: rule dest_ip4_val=%x, src ip4=%x, dst_ip6=%x, ports=%x\n", + //rule.dest_ip4_val, rule.src_ip4_val, rule.dest_ip6_val.ul[0], rule.ports); + + if(rule.dest_ip4_val !=0 && ip6_addr_is_null(&rule.dest_ip6_val)) //only ip4 + { + multi_acl_info[rule_id+start_n].entry.group.type = FAL_ADDR_IPV4; + multi_acl_info[rule_id+start_n].entry.source.type = FAL_ADDR_IPV4; + multi_acl_info[rule_id+start_n].entry.group.u.ip4_addr = rule.dest_ip4_val; + multi_acl_info[rule_id+start_n].entry.source.u.ip4_addr = rule.src_ip4_val; + multi_acl_info[rule_id+start_n].entry.port_map= rule.ports; + } + else if(rule.dest_ip4_val ==0 && !ip6_addr_is_null(&rule.dest_ip6_val)) //only ip6 + { + multi_acl_info[rule_id+start_n].entry.group.type = FAL_ADDR_IPV6; + multi_acl_info[rule_id+start_n].entry.source.type = FAL_ADDR_IPV6; + memcpy(&(multi_acl_info[rule_id+start_n].entry.group.u.ip6_addr), &(rule.dest_ip6_val), sizeof(rule.dest_ip6_val)); + memcpy(&(multi_acl_info[rule_id+start_n].entry.source.u.ip6_addr), &(rule.src_ip6_val), sizeof(rule.src_ip6_val)); + multi_acl_info[rule_id+start_n].entry.port_map= rule.ports; + } + if (FAL_FIELD_FLG_TST(rule.field_flg, FAL_ACL_FIELD_MAC_VID)) + { + multi_acl_info[rule_id+start_n].entry.vlan_id = rule.vid_val; + } + else + { + multi_acl_info[rule_id+start_n].entry.vlan_id = 0xffff; + } + } + + return rule_id+start_n; +} +/* +** Iterate the total 32 multicast ACL entries. + After the function completes: + 1. Stores all multicast related ACL rules in multi_acl_info[32] + 2. return the number of multicast related ACL rules +*/ +HSL_LOCAL a_uint32_t isisc_multicast_acl_query(a_uint32_t dev_id) +{ + int start_n; + int total_n; + //a_uint32_t i; + + start_n = iterate_multicast_acl_rule(dev_id, FAL_ACL_LIST_MULTICAST, 0); + if(-1 == start_n) + aos_printk("ACL rule1 is FULL\n"); + total_n = iterate_multicast_acl_rule(dev_id, FAL_ACL_LIST_MULTICAST+1, start_n); + if(-1 == total_n) + aos_printk("ACL rule2 is FULL\n"); + + MULTI_DEBUG("KKK, the total ACL rule number is %d, (G,S) number=%d\n", total_n, start_n); + /* + for(i=0;i>6)&0x3) == 0x3) || (((msk_valid>>6)&0x3) == 0x2)) + { + rv = multi_portmap_aclreg_set(dev_id, i, entry); + break; + } + else if ((((msk_valid>>6)&0x3)) == 0x0 || (((msk_valid>>6)&0x3) == 0x1)) + { + rv = multi_portmap_aclreg_set(dev_id, i, entry); + continue; + } + else + { + aos_printk("The rule valid bit:6 7 is wrong!!!"); + break; + } + } + return rv; +} +HSL_LOCAL sw_error_t multi_portmap_aclreg_set(a_uint32_t dev_id, a_uint32_t pos, fal_igmp_sg_entry_t * entry) +{ + a_uint32_t i, base, addr; + sw_error_t rv; + a_uint32_t act[3]= {0}; + fal_pbmp_t pm; + + pm = entry->port_map; + + base = ISISC_FILTER_ACT_ADDR + (pos << 4); + for (i = 0; i < 3; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&act[i]), + sizeof (a_uint32_t)); + //MULTI_DEBUG("2:Get register value 0x%x =%x\n", addr, act[i]); + SW_RTN_ON_ERROR(rv); + } + + act[1] &= ~(0x7<<29); // clear the high 3 bits + act[1] |= (pm&0x7)<<29; //the low 3 bits of pm means redirect port 0,1,2 + + /* New modification: update acl ACTION register from DENY to redirect */ + if (((act[2]>>6)&0x7) == 0x7) //DENY mode + { + if(pm) + { + act[2] &= ~(0x7<<6);//clear DENY bits + act[2] |= (0x1<<4); //DES_PORT_EN set 1, enable + } + } + else if (((act[2]>>4)&0x1) == 0x1) //redirect mode + { + if(pm==0) + { + act[2] &= ~(0x1<<4);//clear redirect bits + act[2] |= (0x7<<6); //set to DENY + } + } + + act[2] &= ~0xf; //clear the low 4 bits of port 3,4,5,6 + act[2] |= (pm>>3)&0xf; + + addr = base + (1<<2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&act[1]), sizeof (a_uint32_t)); + addr = base + (2<<2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&act[2]), sizeof (a_uint32_t)); + MULTI_DEBUG("pos=%d, before sync portmap, the new act=%x %x\n", pos, act[1],act[2]); + if((rv = isisc_acl_rule_sync_multi_portmap(dev_id, pos, act)) < 0) + aos_printk("Sync multicast portmap error\n"); + return rv; +} + +HSL_LOCAL int multi_get_dp(a_uint32_t dev_id) +{ + a_uint32_t addr; + sw_error_t rv; + int val=0; + + addr = 0x624;//GLOBAL_FW_CTRL1 + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + if (rv != SW_OK) + aos_printk("Get entry value error\n"); + + val = (val>>24)&0x7f; //30:24, IGMP_JOIN_LEAVE_DP + + return val; +} +static int old_bind_p=-1; +HSL_LOCAL int multi_acl_bind(a_uint32_t dev_id) +{ + int bind_p; + int i; + + bind_p = multi_get_dp(dev_id); + if(bind_p == old_bind_p) + return 0; + old_bind_p = bind_p; + + for(i=0; i<7; i++) + { + isisc_acl_list_unbind(dev_id, FAL_ACL_LIST_MULTICAST, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, i); + isisc_acl_list_unbind(dev_id, FAL_ACL_LIST_MULTICAST+1, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, i); + } + + if(bind_p==0) + { + for(i=0; i<7; i++) + { + isisc_acl_list_bind(dev_id, FAL_ACL_LIST_MULTICAST, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, i); + isisc_acl_list_bind(dev_id, FAL_ACL_LIST_MULTICAST+1, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, i); + } + } + else + { + for(i=0; i<7; i++) + if((bind_p>>i) &0x1) + { + isisc_acl_list_bind(dev_id, FAL_ACL_LIST_MULTICAST, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, i); + isisc_acl_list_bind(dev_id, FAL_ACL_LIST_MULTICAST+1, FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORT, i); + } + else + continue; + } + return 0; +} +/* +** Only update the related portmap from the privious input. +*/ +HSL_LOCAL sw_error_t isisc_multicast_acl_update(a_uint32_t dev_id, int list_id, int acl_index, fal_igmp_sg_entry_t * entry, int action) +{ + a_uint32_t rule_pos; + sw_error_t rv; + + if(acl_index<0) + { + aos_printk("Something is wrong...\n"); + return SW_FAIL; + } + + rule_pos = isisc_acl_rule_get_offset(dev_id, list_id, multi_acl_group[acl_index].index); + if(MULT_ACTION_SET == action) + { + multi_acl_group[acl_index].entry.port_map |= entry->port_map; + if(entry->port_map == 0) + { + multi_acl_group[acl_index].entry.port_map = 0; + } + } + else if(MULT_ACTION_CLEAR == action) + multi_acl_group[acl_index].entry.port_map &= ~(entry->port_map); + + rv = multi_portmap_aclreg_set_all(dev_id, rule_pos, &multi_acl_group[acl_index].entry); + + multi_acl_bind(dev_id); //Here need extra bind since IGMP join/leave would happen + return rv; +} + +HSL_LOCAL sw_error_t isisc_multicast_acl_del(a_uint32_t dev_id, int list_id, int index) +{ + sw_error_t rv; + int rule_id; + + rule_id = multi_acl_group[index].index; + + rv = isisc_acl_rule_delete(dev_id, list_id, rule_id, 1); + multi_acl_bind(dev_id); //Here need extra bind since IGMP join/leave would happen + return rv; +} + +/* +** Add new acl rule with parameters: DIP, SIP, redirect port. +*/ +HSL_LOCAL sw_error_t isisc_multicast_acl_add(a_uint32_t dev_id, int list_id, fal_igmp_sg_entry_t * entry) +{ + sw_error_t val; + a_uint32_t pos; + fal_acl_rule_t acl= {0}; + + /* IPv4 multicast */ + if( entry->group.type == FAL_ADDR_IPV4 ) + { + MULTI_DEBUG("KKK1, group[%d][%x], source[%d][%x]\n",entry->group.type, + entry->group.u.ip4_addr, entry->source.type, entry->source.u.ip4_addr); + + acl.rule_type = FAL_ACL_RULE_IP4; + + if(entry->group.u.ip4_addr!= 0) + { + acl.dest_ip4_val = entry->group.u.ip4_addr; + acl.dest_ip4_mask = 0xffffffff;//e->ip.dmsk.s_addr; + FAL_FIELD_FLG_SET(acl.field_flg, FAL_ACL_FIELD_IP4_DIP); + } + if(entry->source.u.ip4_addr!= 0) + { + acl.src_ip4_val = entry->source.u.ip4_addr; + acl.src_ip4_mask = 0xffffffff;//e->ip.smsk.s_addr; + FAL_FIELD_FLG_SET(acl.field_flg, FAL_ACL_FIELD_IP4_SIP); + } + if( entry->port_map==0 ) + FAL_ACTION_FLG_SET ( acl.action_flg, FAL_ACL_ACTION_DENY); + else + //FAL_FIELD_FLG_SET(acl.field_flg, FAL_ACL_FIELD_INVERSE_ALL); + FAL_ACTION_FLG_SET ( acl.action_flg, FAL_ACL_ACTION_PERMIT ); + + /* Be careful, _isisc_acl_action_parse() will block FAL_ACL_ACTION_DENY action, So we change it. */ + if( entry->port_map ) + { + FAL_ACTION_FLG_SET(acl.action_flg, FAL_ACL_ACTION_REDPT); + acl.ports = entry->port_map; + } + } + else if( entry->group.type == FAL_ADDR_IPV6 ) + { + MULTI_DEBUG("KKK2, group[%d][%x], source[%d][%x], pm=%x\n",entry->group.type, + entry->group.u.ip6_addr.ul[0], entry->source.type, entry->source.u.ip6_addr.ul[0], entry->port_map); + + acl.rule_type = FAL_ACL_RULE_IP6; + + if(!ip6_addr_is_null(&(entry->group.u.ip6_addr))) + { + memcpy(&acl.dest_ip6_val, &(entry->group.u.ip6_addr), sizeof(entry->group.u.ip6_addr)); + acl.dest_ip6_mask.ul[0] = 0xffffffff; + acl.dest_ip6_mask.ul[1] = 0xffffffff; + acl.dest_ip6_mask.ul[2] = 0xffffffff; + acl.dest_ip6_mask.ul[3] = 0xffffffff; + FAL_FIELD_FLG_SET(acl.field_flg, FAL_ACL_FIELD_IP6_DIP); + } + if(!ip6_addr_is_null(&(entry->source.u.ip6_addr))) + { + memcpy(&acl.src_ip6_val, &(entry->source.u.ip6_addr), sizeof(entry->source.u.ip6_addr)); + acl.src_ip6_mask.ul[0] = 0xffffffff; + acl.src_ip6_mask.ul[1] = 0xffffffff; + acl.src_ip6_mask.ul[2] = 0xffffffff; + acl.src_ip6_mask.ul[3] = 0xffffffff; + FAL_FIELD_FLG_SET(acl.field_flg, FAL_ACL_FIELD_IP6_SIP); + } + + if( entry->port_map==0 ) + FAL_ACTION_FLG_SET ( acl.action_flg, FAL_ACL_ACTION_DENY); + else + //FAL_FIELD_FLG_SET(acl.field_flg, FAL_ACL_FIELD_INVERSE_ALL); + FAL_ACTION_FLG_SET ( acl.action_flg, FAL_ACL_ACTION_PERMIT ); + + /* Be careful, _isisc_acl_action_parse() will block FAL_ACL_ACTION_DENY action, So we change it. */ + if( entry->port_map ) + { + FAL_ACTION_FLG_SET(acl.action_flg, FAL_ACL_ACTION_REDPT); + acl.ports = entry->port_map; + } + } + + if (entry->vlan_id < 4096) + { + FAL_FIELD_FLG_SET(acl.field_flg, FAL_ACL_FIELD_MAC_VID); + acl.vid_val = entry->vlan_id; + acl.vid_op = FAL_ACL_FIELD_MASK; + acl.vid_mask = 0xfff; + } + + pos = isisc_multicast_acl_total_n(dev_id, list_id); + + MULTI_DEBUG("In isisc_multicast_acl_add, list_id=%d, rule_id=%d\n", list_id, pos); + val = isisc_acl_rule_add(dev_id, list_id, pos, mul_rule_nr, &acl); + + multi_acl_bind(dev_id); + + return val; +} + + +HSL_LOCAL int iterate_multicast_acl_group(a_uint32_t number, fal_igmp_sg_entry_t * entry) +{ + int count=0; + int i; + + if (number == 0) + return 0; //no any ACL rules based the query + + for(i=0; igroup.type, entry->group.u.ip6_addr.ul[0], entry->port_map);*/ + + if(0 == memcmp(&(multi_acl_info[i].entry.group), &(entry->group), sizeof(entry->group))) + { + memcpy(&multi_acl_group[count], &multi_acl_info[i], sizeof(multi_acl_info[i])); + count++;//return the real number of multi_acl_group[] + MULTI_DEBUG("in iterate_multicast_acl_group, count=%d, i=%d\n", count, i); + } + } + + return count; +} + +HSL_LOCAL int mult_acl_has_entry(fal_igmp_sg_addr_t * group, fal_igmp_sg_addr_t *source) +{ + int rule_id; + int ret = 0; +#if 0 + if(source != NULL) + { + MULTI_DEBUG("new group[%d]= %x %x %x %x, new source[%d]=%x %x %x %x\n", + group->type, group->u.ip6_addr.ul[0], group->u.ip6_addr.ul[1], group->u.ip6_addr.ul[2], group->u.ip6_addr.ul[3], + source->type, source->u.ip6_addr.ul[0], source->u.ip6_addr.ul[1], source->u.ip6_addr.ul[2], source->u.ip6_addr.ul[3]); + + MULTI_DEBUG("old group[%d]= %x %x %x %x, old source[%d]=%x %x %x %x\n", + multi_acl_group[0].entry.group.type, multi_acl_group[0].entry.group.u.ip6_addr.ul[0], + multi_acl_group[0].entry.group.u.ip6_addr.ul[1], multi_acl_group[0].entry.group.u.ip6_addr.ul[2], multi_acl_group[0].entry.group.u.ip6_addr.ul[3], + multi_acl_group[0].entry.source.type, multi_acl_group[0].entry.source.u.ip6_addr.ul[0], + multi_acl_group[0].entry.source.u.ip6_addr.ul[1], multi_acl_group[0].entry.source.u.ip6_addr.ul[2], multi_acl_group[0].entry.source.u.ip6_addr.ul[3]); + } +#endif + if(source == NULL) + { + for(rule_id=0; rule_idport_map, g_source->source.u.ip4_addr, g_source->group.u.ip4_addr, + g_star->port_map, g_star->source.u.ip4_addr,g_star->group.u.ip4_addr);*/ + + if(multi_source_is_null(&(g_star->source))) + { + if((g_source->port_map|g_star->port_map) == g_star->port_map) + { + return 0; + } + } + + return 1; +} + + +HSL_LOCAL int portmap_clear_type(int count, int index, fal_pbmp_t portmap) +{ + if(count>=0 && index0; this means there're (G,*) and (G,S) + { + //if the new clear portmap will cause (G,S)=(G,*), Delete the (G,S) + if((multi_acl_group[index].entry.port_map & (~portmap)) == multi_acl_group[count].entry.port_map) + return 1; //delete + + + //The following means there must be at least one bit clear wrong. Clear the (G,*) portmap. + if( ((multi_acl_group[index].entry.port_map & (~portmap)) & (multi_acl_group[count].entry.port_map)) + != (multi_acl_group[count].entry.port_map)) + return 0; + + return 2; //Normal update + } + return 0; +} +sw_error_t isisc_igmp_sg_entry_set(a_uint32_t dev_id, fal_igmp_sg_entry_t * entry) +{ + int number, count; + int new_index=0; + sw_error_t rv; + int action = MULT_ACTION_SET; + int i=0; + + HSL_API_LOCK; + isisc_multicast_init(dev_id); + aos_mem_zero(multi_acl_info, FAL_IGMP_SG_ENTRY_MAX * sizeof (multi_acl_info_t)); + aos_mem_zero(multi_acl_group, FAL_IGMP_SG_ENTRY_MAX * sizeof (multi_acl_info_t)); + MULTI_DEBUG("Before query: group=%x, source=%x, portmap=%x\n", entry->group.u.ip4_addr, entry->source.u.ip4_addr, entry->port_map); + //number is the total multicast ACL rules amount, stores in multi_acl_info[]; + number = isisc_multicast_acl_query(dev_id); + if(number > FAL_IGMP_SG_ENTRY_MAX) + return SW_FAIL; + //count the total specific multicast group ACL rules, stores in multi_acl_group[]; count <=number + count = iterate_multicast_acl_group(number, entry); + //new_index-1 is the found entry index in multi_acl_group[], the real index is [new_index-1], 0 means no entry + new_index = mult_acl_has_entry(&entry->group, &entry->source); + + MULTI_DEBUG("Start entry set: number=%d, count=%d, new_index=%d, pm=%x\n", number, count, new_index, entry->port_map); + if( 0==multi_source_is_null(&entry->source) ) // new entry is (G, S) + { + MULTI_DEBUG("the new entry is (G,S)\n"); + if(count>0 && 0 == portmap_valid(entry, &(multi_acl_group[count-1].entry))) //specfic group entry exist,(G,S) or (G,*) + { + //return SW_NO_CHANGE; // The new portmap is Not valid + MULTI_DEBUG("KKK, modified 1 !!!\n"); + } + + if(0 == new_index) //new entry, need add + { +#if 0 + /*The method: + 1. predict if the portmap should be modified. + 2. add new acl rule with new portmap value. + */ + if((tmp_index = mult_acl_has_entry(&entry->group, NULL))>0) // (G, *) entry exist + { + /*Here the update should new (G, S) OR orignal (G,*) portmap, + be careful, entry's portmap value will be modified, so I use tmp_entry. + */ + memcpy(tmp_entry, entry, sizeof(fal_igmp_sg_entry_t)); + MULTI_DEBUG("Here, (G,*) exist! tmp_index=%d\n", tmp_index); + sw_multicast_acl_update(FAL_ACL_LIST_MULTICAST+1, tmp_index-1, tmp_entry, action); + + isisc_multicast_acl_add(FAL_ACL_LIST_MULTICAST, tmp_entry); + return SW_OK; + } +#endif + isisc_multicast_acl_add(dev_id, FAL_ACL_LIST_MULTICAST, entry); + MULTI_DEBUG("Here, need add (G, S), portmap=%x\n", entry->port_map); + return SW_OK; + } + else + { + //Here update Just: the old exist entry portmap OR the new entry portmap + isisc_multicast_acl_update(dev_id, FAL_ACL_LIST_MULTICAST, new_index-1, entry, action); + return SW_OK; + } + } //end of memcmp + else // new entry is (G, *) + { + if(0 == new_index) //new entry, need add + { + isisc_multicast_acl_add(dev_id, FAL_ACL_LIST_MULTICAST+1, entry); + rv = SW_OK; + } + else if(new_index > 0) // (G, *) entry exist? + { + //Update exist (G, *) portmap with new portmap + MULTI_DEBUG("(G,*) exist, before update, new_index=%d\n", new_index ); + isisc_multicast_acl_update(dev_id, FAL_ACL_LIST_MULTICAST+1, new_index-1, entry, action); + rv = SW_OK; + } + + if(new_index>0&&count>1) //(G,S*) and (G,*) exist, new entry is (G,*) + { + for(i=count-2; i>=0&&i0) //only exist (G,S*) orignally + { + for(i=count-1; i>=0&&iport_map); + isisc_multicast_acl_del(dev_id, FAL_ACL_LIST_MULTICAST, i); + rv = SW_NO_MORE; + } + else + { + MULTI_DEBUG("2:Start update all (G,S),i=%d, portmap=%x\n", i, entry->port_map); + //Update all (G,S) entry portmap with new(G, *) portmap + isisc_multicast_acl_update(dev_id, FAL_ACL_LIST_MULTICAST, i, entry, action); + rv = SW_OK; + } + } + } + } + HSL_API_UNLOCK; + return rv; +} + +sw_error_t isisc_igmp_sg_entry_clear(a_uint32_t dev_id, fal_igmp_sg_entry_t * entry) +{ + a_uint32_t number, count; + int new_index=0; + sw_error_t rv = SW_OK; + int action= MULT_ACTION_CLEAR; + int i=0; + int pm_type; + + HSL_API_LOCK; + isisc_multicast_init(dev_id); + aos_mem_zero(multi_acl_info, FAL_IGMP_SG_ENTRY_MAX * sizeof (multi_acl_info_t)); + aos_mem_zero(multi_acl_group, FAL_IGMP_SG_ENTRY_MAX * sizeof (multi_acl_info_t)); + //number is the total multicast ACL rules amount, stores in multi_acl_info[]; + number = isisc_multicast_acl_query(dev_id); + if(number > FAL_IGMP_SG_ENTRY_MAX) + return SW_FAIL; + //count the total specific multicast group ACL rules, stores in multi_acl_group[]; count <=number + count = iterate_multicast_acl_group(number, entry); + if(count == 0) + return SW_OK; + + //new_index-1 is the found entry index in multi_acl_group[] + new_index = mult_acl_has_entry(&entry->group, &entry->source); + + MULTI_DEBUG("Start entry clear: number=%d, count=%d, new_index=%d\n", number, count, new_index); + if(0 == new_index || new_index > FAL_IGMP_SG_ENTRY_MAX || count > FAL_IGMP_SG_ENTRY_MAX) //new entry, the user command is wrong + { + return SW_NO_SUCH; + } + + if( 0==multi_source_is_null(&entry->source) ) // new entry is (G, S) + { + if (portmap_null(new_index-1, entry->port_map)) + { + MULTI_DEBUG("KKK entry clear, new(G,S), with null portmap. \n"); + isisc_multicast_acl_del(dev_id, FAL_ACL_LIST_MULTICAST, new_index-1); + return SW_NO_MORE; + } + else + { + MULTI_DEBUG("KKK entry clear, new(G,S), with NOT null portmap. \n"); + /* If (G,*) doesn't exist, [count-1] is the last specfic group, maybe(G,*) */ + if(0 == multi_source_is_null(&(multi_acl_group[count-1].entry.source))) + { + isisc_multicast_acl_update(dev_id, FAL_ACL_LIST_MULTICAST, new_index-1, entry, action); + } + else //(G,*) exist + { + pm_type = portmap_clear_type(count-1, new_index-1, entry->port_map); + if(pm_type == 0) + return SW_NO_CHANGE; + else if(pm_type == 1) + { + isisc_multicast_acl_del(dev_id, FAL_ACL_LIST_MULTICAST, new_index-1); + return SW_NO_MORE; + } + else + { + //normal update; consider here...wangson + isisc_multicast_acl_update(dev_id, FAL_ACL_LIST_MULTICAST, new_index-1, entry, action); + } + } + } + return SW_OK; + } + else //clear entry is (G,*) + { + MULTI_DEBUG("Here, new_index[%d]>=0, new portmap to clear is %x\n", new_index, entry->port_map); + if (portmap_null(new_index-1, entry->port_map)) + { + isisc_multicast_acl_del(dev_id, FAL_ACL_LIST_MULTICAST+1, new_index-1); + rv = SW_NO_MORE; + } + else + { + MULTI_DEBUG("Update (G,*)!, new_index=%d, pm=%x\n", new_index, entry->port_map); + isisc_multicast_acl_update(dev_id, FAL_ACL_LIST_MULTICAST+1, new_index-1, entry, action); + } + MULTI_DEBUG("KKK, ready clear (G, S*), count=%d\n", count); +#if 0 + if(count>1) // (G, S*) entry exist, if count=1 here, only exist(G,*)entry + { + //count must >=2 + for(i=count-2; i>=0; i--) + { + if(portmap_null(i, entry->port_map)) + { + MULTI_DEBUG("portmap_null, i=%d\n", i); + isisc_multicast_acl_del(FAL_ACL_LIST_MULTICAST, i); + rv = SW_NO_MORE; + } + else + { + //Update all (G,S) entry portmap with new(G, *) portmap + isisc_multicast_acl_update(FAL_ACL_LIST_MULTICAST, i, entry, action); + rv = SW_OK; + } + } + } +#else + if(count>1) // (G, S*) entry exist, if count=1 here, only exist(G,*)entry + { + //count must >=2 + for(i=count-2; i>=0&&iport_map))) == + multi_acl_group[i].entry.port_map) + isisc_multicast_acl_del(dev_id, FAL_ACL_LIST_MULTICAST, i); + else + //Update all (G,S) entry portmap with new(G, *) portmap + isisc_multicast_acl_update(dev_id, FAL_ACL_LIST_MULTICAST, i, entry, action); + rv = SW_OK; + } + } +#endif + } + HSL_API_UNLOCK; + return rv; +} + +static void +print_ip4addr(char * param_name, a_uint32_t * buf, + a_uint32_t size) +{ + a_uint32_t i; + fal_ip4_addr_t ip4; + + ip4 = *((fal_ip4_addr_t *) buf); + aos_printk("%s", param_name); + for (i = 0; i < 3; i++) + { + aos_printk("%d.", (ip4 >> (24 - i * 8)) & 0xff); + } + aos_printk("%d", (ip4 & 0xff)); +} +static void +print_ip6addr(char * param_name, a_uint32_t * buf, + a_uint32_t size) +{ + a_uint32_t i; + fal_ip6_addr_t ip6; + + ip6 = *(fal_ip6_addr_t *) buf; + aos_printk("%s", param_name); + for (i = 0; i < 3; i++) + { + aos_printk("%x:%x:", (ip6.ul[i] >> 16) & 0xffff, ip6.ul[i] & 0xffff); + } + aos_printk("%x:%x", (ip6.ul[3] >> 16) & 0xffff, ip6.ul[3] & 0xffff); +} +sw_error_t isisc_igmp_sg_entry_show(a_uint32_t dev_id) +{ + a_uint32_t number; + int i; + + HSL_API_LOCK; + isisc_multicast_init(dev_id); + aos_mem_zero(multi_acl_info, FAL_IGMP_SG_ENTRY_MAX * sizeof (multi_acl_info_t)); + aos_mem_zero(multi_acl_group, FAL_IGMP_SG_ENTRY_MAX * sizeof (multi_acl_info_t)); + //number is the total multicast ACL rules amount, stores in multi_acl_info[]; + number = isisc_multicast_acl_query(dev_id); + + for(i=0; i FAL_IGMP_SG_ENTRY_MAX) + { + HSL_API_UNLOCK; + return SW_FAIL; + } + info->cnt = number; + + for(i=0; iacl_info[i]), &(multi_acl_info[i]), sizeof(multi_acl_info_t)); + } + HSL_API_UNLOCK; + + return SW_OK; +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_nat.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_nat.c new file mode 100755 index 000000000..830976128 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_nat.c @@ -0,0 +1,2468 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup isisc_ip ISISC_NAT + * @{ + */ + +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isisc_nat.h" +#include "isisc_reg.h" +#if defined(IN_NAT_HELPER) +#include "isisc_nat_helper.h" +#endif + +#define ISISC_HOST_ENTRY_DATA0_ADDR 0x0e80 +#define ISISC_HOST_ENTRY_DATA1_ADDR 0x0e84 +#define ISISC_HOST_ENTRY_DATA2_ADDR 0x0e88 +#define ISISC_HOST_ENTRY_DATA3_ADDR 0x0e8c +#define ISISC_HOST_ENTRY_DATA4_ADDR 0x0e90 +#define ISISC_HOST_ENTRY_DATA5_ADDR 0x0e94 +#define ISISC_HOST_ENTRY_DATA6_ADDR 0x0e98 +#define ISISC_HOST_ENTRY_DATA7_ADDR 0x0e58 + +#define ISISC_HOST_ENTRY_REG_NUM 8 + +#define ISISC_NAT_ENTRY_FLUSH 1 +#define ISISC_NAT_ENTRY_ADD 2 +#define ISISC_NAT_ENTRY_DEL 3 +#define ISISC_NAT_ENTRY_NEXT 4 +#define ISISC_NAT_ENTRY_SEARCH 5 + +#define ISISC_ENTRY_NAPT 0 +#define ISISC_ENTRY_NAT 2 +#define ISISC_ENTRY_ARP 3 + +#define ISISC_PUB_ADDR_NUM 16 +#define ISISC_PUB_ADDR_TBL0_ADDR 0x5aa00 +#define ISISC_PUB_ADDR_TBL1_ADDR 0x5aa04 +#define ISISC_PUB_ADDR_EDIT0_ADDR 0x02100 +#define ISISC_PUB_ADDR_EDIT1_ADDR 0x02104 +#define ISISC_PUB_ADDR_OFFLOAD_ADDR 0x2f000 +#define ISISC_PUB_ADDR_VALID_ADDR 0x2f040 + +#define ISISC_NAT_ENTRY_NUM 32 +#define ISISC_NAPT_ENTRY_NUM 1024 + +#define ISISC_NAT_COUTER_ADDR 0x2b000 + +#define ISISC_NAT_PORT_NUM 255 + +static a_uint32_t isisc_nat_snap[SW_MAX_NR_DEV] = { 0 }; +extern a_uint32_t isisc_nat_global_status; + +static sw_error_t +_isisc_nat_feature_check(a_uint32_t dev_id) +{ + sw_error_t rv; + a_uint32_t entry = 0; + + HSL_REG_FIELD_GET(rv, dev_id, MASK_CTL, 0, DEVICE_ID, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (S17C_DEVICE_ID == entry) + { + return SW_OK; + } + else + { + return SW_NOT_SUPPORTED; + } +} + +static sw_error_t +_isisc_ip_prvaddr_sw_to_hw(a_uint32_t dev_id, fal_ip4_addr_t sw_addr, + a_uint32_t * hw_addr) +{ + /* + sw_error_t rv; + a_uint32_t data; + + HSL_REG_FIELD_GET(rv, dev_id, PRVIP_CTL, 0, BASEADDR_SEL, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data) { + *hw_addr = (sw_addr & 0xff) | (((sw_addr >> 16) & 0xf) << 8); + } else { + *hw_addr = sw_addr & 0xfff; + } + */ + *hw_addr = sw_addr; + return SW_OK; +} + +static sw_error_t +_isisc_ip_prvaddr_hw_to_sw(a_uint32_t dev_id, a_uint32_t hw_addr, + fal_ip4_addr_t * sw_addr) +{ + /* + sw_error_t rv; + a_uint32_t data, addr; + + HSL_REG_FIELD_GET(rv, dev_id, PRVIP_CTL, 0, BASEADDR_SEL, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, PRVIP_CTL, 0, IP4_BASEADDR, + (a_uint8_t *) (&addr), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data) { + *sw_addr = ((addr & 0xff) << 8) | (((addr >> 8) & 0xfff) << 8) + | (hw_addr & 0xff) | (((hw_addr >> 8) & 0xf) << 16); + } else { + *sw_addr = (addr << 12) | (hw_addr & 0xfff); + } + */ + *sw_addr = hw_addr; + + return SW_OK; +} + +static sw_error_t +_isisc_nat_counter_get(a_uint32_t dev_id, a_uint32_t cnt_id, + a_uint32_t counter[4]) +{ + sw_error_t rv; + a_uint32_t i, addr; + + addr = ISISC_NAT_COUTER_ADDR + (cnt_id << 4); + for (i = 0; i < 4; i++) + { + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(counter[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + addr += 4; + } + + return SW_OK; +} + +static sw_error_t +_isisc_nat_entry_commit(a_uint32_t dev_id, a_uint32_t entry_type, a_uint32_t op) +{ + a_uint32_t busy = 1, i = 0x100, entry = 0; + sw_error_t rv; + + while (busy && --i) + { + HSL_REG_ENTRY_GET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (&entry), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_BUSY, busy, entry); + } + + if (i == 0) + { + return SW_BUSY; + } + + SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_BUSY, 1, entry); + SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_SEL, entry_type, entry); + SW_SET_REG_BY_FIELD(HOST_ENTRY7, ENTRY_FUNC, op, entry); + + HSL_REG_ENTRY_SET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (&entry), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + busy = 1; + i = 0x1000; + while (busy && --i) + { + HSL_REG_ENTRY_GET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (&entry), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_BUSY, busy, entry); +#if 1 + if(ISISC_NAT_ENTRY_SEARCH == op && busy) break; +#endif + } + + if (i == 0) + { + return SW_BUSY; + } + + /* hardware requirement, we should delay... */ + if ((ISISC_NAT_ENTRY_FLUSH == op) && (ISISC_ENTRY_NAPT == entry_type)) + { + aos_mdelay(10); + } + + /* hardware requirement, we should read again... */ + HSL_REG_ENTRY_GET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (&entry), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_STAUS, busy, entry); + if (!busy) + { + if (ISISC_NAT_ENTRY_NEXT == op) + { + return SW_NO_MORE; + } + else if (ISISC_NAT_ENTRY_SEARCH == op) + { + return SW_NOT_FOUND; + } + else + { + return SW_FAIL; + } + } + + return SW_OK; +} + +static sw_error_t +_isisc_nat_sw_to_hw(a_uint32_t dev_id, fal_nat_entry_t * entry, a_uint32_t reg[]) +{ + sw_error_t rv; + a_uint32_t data; + + if (FAL_NAT_ENTRY_TRANS_IPADDR_INDEX & entry->flags) + { + return SW_BAD_PARAM; + } + + reg[0] = entry->trans_addr; + + if (FAL_NAT_ENTRY_PORT_CHECK & entry->flags) + { + SW_SET_REG_BY_FIELD(NAT_ENTRY3, PORT_EN, 1, reg[3]); + SW_SET_REG_BY_FIELD(NAT_ENTRY1, PORT_RANGE, entry->port_range, reg[1]); + if (ISISC_NAT_PORT_NUM < entry->port_range) + { + return SW_BAD_PARAM; + } + SW_SET_REG_BY_FIELD(NAT_ENTRY1, PORT_NUM, entry->port_num, reg[1]); + } + else + { + SW_SET_REG_BY_FIELD(NAT_ENTRY3, PORT_EN, 0, reg[3]); + } + + rv = _isisc_ip_prvaddr_sw_to_hw(dev_id, entry->src_addr, &data); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(NAT_ENTRY1, PRV_IPADDR0, data, reg[1]); + SW_SET_REG_BY_FIELD(NAT_ENTRY2, PRV_IPADDR1, (data >> 8), reg[2]); + + if (FAL_MAC_FRWRD == entry->action) + { + if (A_TRUE == entry->mirror_en) + { + SW_SET_REG_BY_FIELD(NAT_ENTRY2, ACTION, 0, reg[2]); + } + else + { + SW_SET_REG_BY_FIELD(NAT_ENTRY2, ACTION, 3, reg[2]); + } + } + else if (FAL_MAC_CPY_TO_CPU == entry->action) + { + SW_SET_REG_BY_FIELD(NAT_ENTRY2, ACTION, 2, reg[2]); + } + else if (FAL_MAC_RDT_TO_CPU == entry->action) + { + SW_SET_REG_BY_FIELD(NAT_ENTRY2, ACTION, 1, reg[2]); + } + else + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == entry->counter_en) + { + SW_SET_REG_BY_FIELD(NAT_ENTRY2, CNT_EN, 1, reg[2]); + SW_SET_REG_BY_FIELD(NAT_ENTRY2, CNT_IDX, entry->counter_id, reg[2]); + } + + if (FAL_NAT_ENTRY_PROTOCOL_ANY & entry->flags) + { + data = 3; + } + else if ((FAL_NAT_ENTRY_PROTOCOL_TCP & entry->flags) + && (FAL_NAT_ENTRY_PROTOCOL_UDP & entry->flags)) + { + data = 2; + } + else if (FAL_NAT_ENTRY_PROTOCOL_TCP & entry->flags) + { + data = 0; + } + else if (FAL_NAT_ENTRY_PROTOCOL_UDP & entry->flags) + { + data = 1; + } + else + { + return SW_BAD_PARAM; + } + + SW_SET_REG_BY_FIELD(NAT_ENTRY3, PRO_TYP, data, reg[3]); + + SW_SET_REG_BY_FIELD(NAT_ENTRY2, HASH_KEY, entry->slct_idx, reg[2]); + + SW_SET_REG_BY_FIELD(NAT_ENTRY3, ENTRY_VALID, 1, reg[3]); + SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_IDX, entry->entry_id, reg[7]); + return SW_OK; +} + +static sw_error_t +_isisc_nat_hw_to_sw(a_uint32_t dev_id, a_uint32_t reg[], fal_nat_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t data, cnt[4] = {0}; + + entry->trans_addr = reg[0]; + + SW_GET_FIELD_BY_REG(NAT_ENTRY3, PORT_EN, data, reg[3]); + if (data) + { + entry->flags |= FAL_NAT_ENTRY_PORT_CHECK; + SW_GET_FIELD_BY_REG(NAT_ENTRY1, PORT_RANGE, data, reg[1]); + entry->port_range = data; + SW_GET_FIELD_BY_REG(NAT_ENTRY1, PORT_NUM, data, reg[1]); + entry->port_num = data; + } + + SW_GET_FIELD_BY_REG(NAT_ENTRY1, PRV_IPADDR0, data, reg[1]); + entry->src_addr = data; + SW_GET_FIELD_BY_REG(NAT_ENTRY2, PRV_IPADDR1, data, reg[2]); + data = (entry->src_addr & 0xff) | (data << 8); + + rv = _isisc_ip_prvaddr_hw_to_sw(dev_id, data, &(entry->src_addr)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(NAT_ENTRY2, ACTION, data, reg[2]); + entry->action = FAL_MAC_FRWRD; + if (0 == data) + { + entry->mirror_en = A_TRUE; + } + else if (2 == data) + { + entry->action = FAL_MAC_CPY_TO_CPU; + } + else if (1 == data) + { + entry->action = FAL_MAC_RDT_TO_CPU; + } + + SW_GET_FIELD_BY_REG(NAT_ENTRY2, CNT_EN, data, reg[2]); + if (data) + { + entry->counter_en = A_TRUE; + SW_GET_FIELD_BY_REG(NAT_ENTRY2, CNT_IDX, entry->counter_id, reg[2]); + + rv = _isisc_nat_counter_get(dev_id, entry->counter_id, cnt); + SW_RTN_ON_ERROR(rv); + + entry->ingress_packet = cnt[0]; + entry->ingress_byte = cnt[1]; + entry->egress_packet = cnt[2]; + entry->egress_byte = cnt[3]; + } + else + { + entry->counter_en = A_FALSE; + } + + SW_GET_FIELD_BY_REG(NAT_ENTRY3, PRO_TYP, data, reg[3]); + if (3 == data) + { + entry->flags |= FAL_NAT_ENTRY_PROTOCOL_ANY; + } + else if (2 == data) + { + entry->flags |= FAL_NAT_ENTRY_PROTOCOL_TCP; + entry->flags |= FAL_NAT_ENTRY_PROTOCOL_UDP; + } + else if (1 == data) + { + entry->flags |= FAL_NAT_ENTRY_PROTOCOL_UDP; + } + else if (0 == data) + { + entry->flags |= FAL_NAT_ENTRY_PROTOCOL_TCP; + } + + SW_GET_FIELD_BY_REG(NAT_ENTRY2, HASH_KEY, data, reg[2]); + entry->slct_idx = data; + + return SW_OK; +} + +static sw_error_t +_isisc_napt_sw_to_hw(a_uint32_t dev_id, fal_napt_entry_t * entry, + a_uint32_t reg[]) +{ + sw_error_t rv; + a_uint32_t data; + + reg[0] = entry->dst_addr; + + SW_SET_REG_BY_FIELD(NAPT_ENTRY1, DST_PORT, entry->dst_port, reg[1]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY1, SRC_PORT, entry->src_port, reg[1]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY2, TRANS_PORT, entry->trans_port, reg[2]); + + rv = _isisc_ip_prvaddr_sw_to_hw(dev_id, entry->src_addr, &data); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(NAPT_ENTRY2, SRC_IPADDR0, (data & 0xfff), reg[2]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, SRC_IPADDR1, (data >> 12), reg[3]); + + if (!(FAL_NAT_ENTRY_TRANS_IPADDR_INDEX & entry->flags)) + { + return SW_BAD_PARAM; + } + SW_SET_REG_BY_FIELD(NAPT_ENTRY2, TRANS_IPADDR, entry->trans_addr, reg[2]); + + if (FAL_MAC_FRWRD == entry->action) + { + if (A_TRUE == entry->mirror_en) + { + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, ACTION, 0, reg[3]); + } + else + { + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, ACTION, 3, reg[3]); + } + } + else if (FAL_MAC_CPY_TO_CPU == entry->action) + { + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, ACTION, 2, reg[3]); + } + else if (FAL_MAC_RDT_TO_CPU == entry->action) + { + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, ACTION, 1, reg[3]); + } + else + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == entry->counter_en) + { + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, CNT_EN, 1, reg[3]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, CNT_IDX, entry->counter_id, reg[3]); + } + + data = 2; + if (FAL_NAT_ENTRY_PROTOCOL_TCP & entry->flags) + { + data = 0; + } + else if (FAL_NAT_ENTRY_PROTOCOL_UDP & entry->flags) + { + data = 1; + } + else if (FAL_NAT_ENTRY_PROTOCOL_PPTP & entry->flags) + { + data = 3; + } + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, PROT_TYP, data, reg[3]); + + SW_SET_REG_BY_FIELD(NAPT_ENTRY4, AGE_FLAG, entry->status, reg[4]); + return SW_OK; +} + +static sw_error_t +_isisc_napt_hw_to_sw(a_uint32_t dev_id, a_uint32_t reg[], + fal_napt_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t data, cnt[4] = {0}; + + entry->dst_addr = reg[0]; + + SW_GET_FIELD_BY_REG(NAPT_ENTRY1, DST_PORT, entry->dst_port, reg[1]); + SW_GET_FIELD_BY_REG(NAPT_ENTRY1, SRC_PORT, entry->src_port, reg[1]); + SW_GET_FIELD_BY_REG(NAPT_ENTRY2, TRANS_PORT, entry->trans_port, reg[2]); + + SW_GET_FIELD_BY_REG(NAPT_ENTRY2, SRC_IPADDR0, data, reg[2]); + entry->src_addr = data; + SW_GET_FIELD_BY_REG(NAPT_ENTRY3, SRC_IPADDR1, data, reg[3]); + data = (entry->src_addr & 0xfff) | (data << 12); + rv = _isisc_ip_prvaddr_hw_to_sw(dev_id, data, &(entry->src_addr)); + SW_RTN_ON_ERROR(rv); + + entry->flags |= FAL_NAT_ENTRY_TRANS_IPADDR_INDEX; + SW_GET_FIELD_BY_REG(NAPT_ENTRY2, TRANS_IPADDR, entry->trans_addr, reg[2]); + + SW_GET_FIELD_BY_REG(NAPT_ENTRY3, ACTION, data, reg[3]); + entry->action = FAL_MAC_FRWRD; + if (0 == data) + { + entry->mirror_en = A_TRUE; + } + else if (2 == data) + { + entry->action = FAL_MAC_CPY_TO_CPU; + } + else if (1 == data) + { + entry->action = FAL_MAC_RDT_TO_CPU; + } + + SW_GET_FIELD_BY_REG(NAPT_ENTRY3, CNT_EN, data, reg[3]); + if (data) + { + entry->counter_en = A_TRUE; + SW_GET_FIELD_BY_REG(NAPT_ENTRY3, CNT_IDX, entry->counter_id, reg[3]); + + rv = _isisc_nat_counter_get(dev_id, entry->counter_id, cnt); + SW_RTN_ON_ERROR(rv); + + entry->ingress_packet = cnt[0]; + entry->ingress_byte = cnt[1]; + entry->egress_packet = cnt[2]; + entry->egress_byte = cnt[3]; + } + else + { + entry->counter_en = A_FALSE; + } + + SW_GET_FIELD_BY_REG(NAPT_ENTRY3, PROT_TYP, data, reg[3]); + if (0 == data) + { + entry->flags |= FAL_NAT_ENTRY_PROTOCOL_TCP; + } + else if (1 == data) + { + entry->flags |= FAL_NAT_ENTRY_PROTOCOL_UDP; + } + else if (3 == data) + { + entry->flags |= FAL_NAT_ENTRY_PROTOCOL_PPTP; + } + + SW_GET_FIELD_BY_REG(NAPT_ENTRY4, AGE_FLAG, entry->status, reg[4]); + return SW_OK; +} + +static sw_error_t +_isisc_nat_down_to_hw(a_uint32_t dev_id, a_uint32_t reg[]) +{ + sw_error_t rv; + a_uint32_t i, addr; + + for (i = 0; i < ISISC_HOST_ENTRY_REG_NUM; i++) + { + if((ISISC_HOST_ENTRY_REG_NUM - 1) == i) + { + addr = ISISC_HOST_ENTRY_DATA7_ADDR; + } + else + { + addr = ISISC_HOST_ENTRY_DATA0_ADDR + (i << 2); + } + + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®[i]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +static sw_error_t +_isisc_nat_up_to_sw(a_uint32_t dev_id, a_uint32_t reg[]) +{ + sw_error_t rv; + a_uint32_t i, addr; + + for (i = 0; i < ISISC_HOST_ENTRY_REG_NUM; i++) + { + if((ISISC_HOST_ENTRY_REG_NUM -1) == i) + { + addr = ISISC_HOST_ENTRY_DATA7_ADDR; + } + else + { + addr = ISISC_HOST_ENTRY_DATA0_ADDR + (i << 2); + } + + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®[i]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +static sw_error_t +_isisc_nat_add(a_uint32_t dev_id, fal_nat_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t i, reg[ISISC_HOST_ENTRY_REG_NUM] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + for (i = 0; i < ISISC_NAT_ENTRY_NUM; i++) + { + if (!(isisc_nat_snap[dev_id] & (0x1 << i))) + { + break; + } + } + + if (ISISC_NAT_ENTRY_NUM == i) + { + return SW_NO_RESOURCE; + } + + entry->entry_id = i; + + rv = _isisc_nat_sw_to_hw(dev_id, entry, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_nat_entry_commit(dev_id, ISISC_ENTRY_NAT, ISISC_NAT_ENTRY_ADD); + SW_RTN_ON_ERROR(rv); + + isisc_nat_snap[dev_id] |= (0x1 << i); + entry->entry_id = i; + return SW_OK; +} + +static sw_error_t +_isisc_nat_del(a_uint32_t dev_id, a_uint32_t del_mode, fal_nat_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t reg[ISISC_HOST_ENTRY_REG_NUM] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_NAT_ENTRY_ID_EN & del_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY7, ENTRY_FUNC, ISISC_NAT_ENTRY_DEL, reg[7]); + SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_IDX, entry->entry_id, reg[7]); + + rv = _isisc_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_nat_entry_commit(dev_id, ISISC_ENTRY_NAT, ISISC_NAT_ENTRY_DEL); + SW_RTN_ON_ERROR(rv); + + isisc_nat_snap[dev_id] &= (~(0x1 << entry->entry_id)); + } + else + { + rv = _isisc_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_nat_entry_commit(dev_id, ISISC_ENTRY_NAT, ISISC_NAT_ENTRY_FLUSH); + SW_RTN_ON_ERROR(rv); + + isisc_nat_snap[dev_id] = 0; + } + + return SW_OK; +} + +static sw_error_t +_isisc_nat_get(a_uint32_t dev_id, a_uint32_t get_mode, fal_nat_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t reg[ISISC_HOST_ENTRY_REG_NUM] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_NAT_ENTRY_ID_EN != get_mode) + { + return SW_NOT_SUPPORTED; + } + + if (!(isisc_nat_snap[dev_id] & (0x1 << entry->entry_id))) + { + return SW_NOT_FOUND; + } + + SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_IDX, entry->entry_id, reg[7]); + + rv = _isisc_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_nat_entry_commit(dev_id, ISISC_ENTRY_NAT, ISISC_NAT_ENTRY_SEARCH); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_nat_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_nat_hw_to_sw(dev_id, reg, entry); + return rv; +} + +static sw_error_t +_isisc_nat_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_nat_entry_t * nat_entry) +{ + a_uint32_t i, idx, reg[ISISC_HOST_ENTRY_REG_NUM] = { 0 }; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_NEXT_ENTRY_FIRST_ID == nat_entry->entry_id) + { + idx = 0; + } + else + { + if ((ISISC_NAT_ENTRY_NUM - 1) == nat_entry->entry_id) + { + return SW_NO_MORE; + } + else + { + idx = nat_entry->entry_id + 1; + } + } + + for (i = idx; i < ISISC_NAT_ENTRY_NUM; i++) + { + if (isisc_nat_snap[dev_id] & (0x1 << i)) + { + break; + } + } + + if (ISISC_NAT_ENTRY_NUM == i) + { + return SW_NO_MORE; + } + + SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_IDX, i, reg[7]); + + rv = _isisc_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_nat_entry_commit(dev_id, ISISC_ENTRY_NAT, ISISC_NAT_ENTRY_SEARCH); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_nat_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + aos_mem_zero(nat_entry, sizeof (fal_nat_entry_t)); + + rv = _isisc_nat_hw_to_sw(dev_id, reg, nat_entry); + SW_RTN_ON_ERROR(rv); + + nat_entry->entry_id = i; + return SW_OK; +} + +static sw_error_t +_isisc_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; + a_uint32_t reg[ISISC_HOST_ENTRY_REG_NUM] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (!(isisc_nat_snap[dev_id] & (0x1 << entry_id))) + { + return SW_NOT_FOUND; + } + + SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_IDX, entry_id, reg[7]); + + rv = _isisc_nat_entry_commit(dev_id, ISISC_ENTRY_NAT, ISISC_NAT_ENTRY_SEARCH); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_nat_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(NAT_ENTRY2, CNT_EN, 0, reg[2]); + } + else if (A_TRUE == enable) + { + SW_SET_REG_BY_FIELD(NAT_ENTRY2, CNT_EN, 1, reg[2]); + SW_SET_REG_BY_FIELD(NAT_ENTRY2, CNT_IDX, cnt_id, reg[2]); + } + else + { + return SW_BAD_PARAM; + } + + /* needn't set TBL_IDX, keep hardware register value */ + + rv = _isisc_nat_entry_commit(dev_id, ISISC_ENTRY_NAT, ISISC_NAT_ENTRY_DEL); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + /* needn't set TBL_IDX, keep hardware register value */ + + rv = _isisc_nat_entry_commit(dev_id, ISISC_ENTRY_NAT, ISISC_NAT_ENTRY_ADD); + return rv; +} + +static sw_error_t +_isisc_napt_add(a_uint32_t dev_id, fal_napt_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t reg[ISISC_HOST_ENTRY_REG_NUM] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_napt_sw_to_hw(dev_id, entry, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_nat_entry_commit(dev_id, ISISC_ENTRY_NAPT, ISISC_NAT_ENTRY_ADD); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_nat_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_IDX, entry->entry_id, reg[7]); + return SW_OK; +} + +static sw_error_t +_isisc_napt_del(a_uint32_t dev_id, a_uint32_t del_mode, fal_napt_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t data, reg[ISISC_HOST_ENTRY_REG_NUM] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_NAT_ENTRY_ID_EN & del_mode) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_NAT_ENTRY_KEY_EN & del_mode) + { + rv = _isisc_napt_sw_to_hw(dev_id, entry, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_nat_entry_commit(dev_id, ISISC_ENTRY_NAPT, ISISC_NAT_ENTRY_DEL); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_nat_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_IDX, entry->entry_id, reg[7]); + return SW_OK; + } + else + { + if (FAL_NAT_ENTRY_PUBLIC_IP_EN & del_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_PIP, 1, reg[7]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY2, TRANS_IPADDR, entry->trans_addr, reg[2]); + } + + if (FAL_NAT_ENTRY_SOURCE_IP_EN & del_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_SIP, 1, reg[7]); + rv = _isisc_ip_prvaddr_sw_to_hw(dev_id, entry->src_addr, &data); + SW_RTN_ON_ERROR(rv); + SW_SET_REG_BY_FIELD(NAPT_ENTRY2, SRC_IPADDR0, (data & 0xfff), reg[2]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, SRC_IPADDR1, (data >> 12), reg[3]); + } + + if (FAL_NAT_ENTRY_AGE_EN & del_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_STATUS, 1, reg[7]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY4, AGE_FLAG, entry->status, reg[4]); + } + + rv = _isisc_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_nat_entry_commit(dev_id, ISISC_ENTRY_NAPT, ISISC_NAT_ENTRY_FLUSH); + return rv; + } +} + +static sw_error_t +_isisc_napt_get(a_uint32_t dev_id, a_uint32_t get_mode, fal_napt_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t found, age, reg[ISISC_HOST_ENTRY_REG_NUM] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + +#if 0 + if (FAL_NAT_ENTRY_ID_EN != get_mode) + { + return SW_NOT_SUPPORTED; + } + + SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_IDX, entry->entry_id, reg[7]); +#else + rv = _isisc_napt_sw_to_hw(dev_id, entry, reg); + SW_RTN_ON_ERROR(rv); +#endif + + rv = _isisc_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_nat_entry_commit(dev_id, ISISC_ENTRY_NAPT, ISISC_NAT_ENTRY_SEARCH); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_nat_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_STAUS, found, reg[7]); + SW_GET_FIELD_BY_REG(NAPT_ENTRY4, AGE_FLAG, age, reg[4]); + if (found && age) + { + found = 1; + } + else + { + found = 0; + } + + rv = _isisc_napt_hw_to_sw(dev_id, reg, entry); + SW_RTN_ON_ERROR(rv); + + if (!found) + { + return SW_NOT_FOUND; + } + + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_IDX, entry->entry_id, reg[7]); + return SW_OK; +} + +static sw_error_t +_isisc_napt_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_napt_entry_t * napt_entry) +{ + a_uint32_t data, idx, reg[ISISC_HOST_ENTRY_REG_NUM] = { 0 }; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_NEXT_ENTRY_FIRST_ID == napt_entry->entry_id) + { + idx = ISISC_NAPT_ENTRY_NUM - 1; + } + else + { + if ((ISISC_NAPT_ENTRY_NUM - 1) == napt_entry->entry_id) + { + return SW_NO_MORE; + } + else + { + idx = napt_entry->entry_id; + } + } + + if (FAL_NAT_ENTRY_PUBLIC_IP_EN & next_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_PIP, 1, reg[7]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY2, TRANS_IPADDR, napt_entry->trans_addr, reg[2]); + } + + if (FAL_NAT_ENTRY_SOURCE_IP_EN & next_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_SIP, 1, reg[7]); + rv = _isisc_ip_prvaddr_sw_to_hw(dev_id, napt_entry->src_addr, &data); + SW_RTN_ON_ERROR(rv); + SW_SET_REG_BY_FIELD(NAPT_ENTRY2, SRC_IPADDR0, (data & 0xfff), reg[2]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, SRC_IPADDR1, (data >> 12), reg[3]); + } + + if (FAL_NAT_ENTRY_AGE_EN & next_mode) + { + SW_SET_REG_BY_FIELD(HOST_ENTRY7, SPEC_STATUS, 1, reg[7]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY4, AGE_FLAG, napt_entry->status, reg[4]); + } + + SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_IDX, idx, reg[7]); + + rv = _isisc_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_nat_entry_commit(dev_id, ISISC_ENTRY_NAPT, ISISC_NAT_ENTRY_NEXT); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_nat_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + aos_mem_zero(napt_entry, sizeof (fal_nat_entry_t)); + + rv = _isisc_napt_hw_to_sw(dev_id, reg, napt_entry); + SW_RTN_ON_ERROR(rv); + +#if 0 + a_uint32_t temp=0, complete=0; + + HSL_REG_ENTRY_GET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (&temp), + sizeof (a_uint32_t)); + + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_STAUS, complete, temp); + + if (!complete) + { + return SW_NO_MORE; + } +#endif + + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_IDX, napt_entry->entry_id, reg[7]); + return SW_OK; +} + +static sw_error_t +_isisc_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; + a_uint32_t reg[ISISC_HOST_ENTRY_REG_NUM] = { 0 }, tbl_idx; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + tbl_idx = (entry_id - 1) & 0x3ff; + SW_SET_REG_BY_FIELD(HOST_ENTRY7, TBL_IDX, tbl_idx, reg[7]); + + rv = _isisc_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_nat_entry_commit(dev_id, ISISC_ENTRY_NAPT, ISISC_NAT_ENTRY_NEXT); + if (SW_OK != rv) + { + return SW_NOT_FOUND; + } + + rv = _isisc_nat_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(HOST_ENTRY7, TBL_IDX, tbl_idx, reg[7]); + if (entry_id != tbl_idx) + { + return SW_NOT_FOUND; + } + + if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, CNT_EN, 0, reg[3]); + } + else if (A_TRUE == enable) + { + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, CNT_EN, 1, reg[3]); + SW_SET_REG_BY_FIELD(NAPT_ENTRY3, CNT_IDX, cnt_id, reg[3]); + } + else + { + return SW_BAD_PARAM; + } + + rv = _isisc_nat_entry_commit(dev_id, ISISC_ENTRY_NAPT, ISISC_NAT_ENTRY_DEL); + SW_RTN_ON_ERROR(rv); + + reg[4] = 0x0; + rv = _isisc_nat_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_nat_entry_commit(dev_id, ISISC_ENTRY_NAPT, ISISC_NAT_ENTRY_ADD); + return rv; +} + +static sw_error_t +_isisc_nat_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, NAT_CTRL, 0, NAT_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_nat_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, NAT_CTRL, 0, NAT_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return rv; +} + +static sw_error_t +_isisc_napt_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, NAT_CTRL, 0, NAPT_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_napt_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, NAT_CTRL, 0, NAPT_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return rv; +} + +static sw_error_t +_isisc_napt_mode_set(a_uint32_t dev_id, fal_napt_mode_t mode) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_NAPT_FULL_CONE == mode) + { + data = 0; + } + else if (FAL_NAPT_STRICT_CONE == mode) + { + data = 1; + } + else if ((FAL_NAPT_PORT_STRICT == mode) + || (FAL_NAPT_SYNMETRIC == mode)) + { + data = 2; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, NAT_CTRL, 0, NAPT_MODE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_napt_mode_get(a_uint32_t dev_id, fal_napt_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, NAT_CTRL, 0, NAPT_MODE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0 == data) + { + *mode = FAL_NAPT_FULL_CONE; + } + else if (1 == data) + { + *mode = FAL_NAPT_STRICT_CONE; + } + else + { + *mode = FAL_NAPT_PORT_STRICT; + } + + return SW_OK; +} + +static sw_error_t +_isisc_nat_hash_mode_set(a_uint32_t dev_id, a_uint32_t mode) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if ((FAL_NAT_HASH_KEY_PORT & mode) + && (FAL_NAT_HASH_KEY_IPADDR & mode)) + { + data = 2; + } + else if (FAL_NAT_HASH_KEY_PORT & mode) + { + data = 0; + } + else if (FAL_NAT_HASH_KEY_IPADDR & mode) + { + data = 1; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, NAT_CTRL, 0, NAT_HASH_MODE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_nat_hash_mode_get(a_uint32_t dev_id, a_uint32_t * mode) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, NAT_CTRL, 0, NAT_HASH_MODE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *mode = 0; + if (0 == data) + { + *mode = FAL_NAT_HASH_KEY_PORT; + } + else if (1 == data) + { + *mode = FAL_NAT_HASH_KEY_IPADDR; + } + else if (2 == data) + { + *mode = FAL_NAT_HASH_KEY_PORT; + *mode |= FAL_NAT_HASH_KEY_IPADDR; + } + + return SW_OK; +} + +static sw_error_t +_isisc_nat_prv_base_addr_set(a_uint32_t dev_id, fal_ip4_addr_t addr) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + data = addr; + HSL_REG_FIELD_SET(rv, dev_id, PRVIP_ADDR, 0, IP4_BASEADDR, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_nat_prv_base_addr_get(a_uint32_t dev_id, fal_ip4_addr_t * addr) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, PRVIP_ADDR, 0, IP4_BASEADDR, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + *addr = data; + + return SW_OK; +} + +static sw_error_t +_isisc_nat_prv_base_mask_set(a_uint32_t dev_id, fal_ip4_addr_t mask) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + data = mask; + HSL_REG_FIELD_SET(rv, dev_id, PRVIP_MASK, 0, IP4_BASEMASK, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +#if 0 +static sw_error_t +_isisc_nat_psr_prv_base_addr_set(a_uint32_t dev_id, fal_ip4_addr_t addr) +{ +#if 0 + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, PRVIP_CTL, 0, BASEADDR_SEL, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data) + { + data = (((addr >> 20) & 0xfff) << 8) | ((addr >> 8) & 0xff); + } + else + { + data = (addr >> 12) & 0xfffff; + } + + HSL_REG_FIELD_SET(rv, dev_id, PRVIP_CTL, 0, IP4_BASEADDR, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +#endif + return SW_OK; +} + +static sw_error_t +_isisc_nat_psr_prv_base_addr_get(a_uint32_t dev_id, fal_ip4_addr_t * addr) +{ +#if 0 + sw_error_t rv; + a_uint32_t data, tmp; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, PRVIP_CTL, 0, BASEADDR_SEL, + (a_uint8_t *) (&tmp), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, PRVIP_CTL, 0, IP4_BASEADDR, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (tmp) + { + *addr = ((data & 0xff) << 8) | (((data >> 8) & 0xfff) << 20); + } + else + { + *addr = (data & 0xfffff) << 12; + } +#endif + return SW_OK; +} +#endif + +static sw_error_t +_isisc_nat_prv_base_mask_get(a_uint32_t dev_id, fal_ip4_addr_t * mask) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, PRVIP_MASK, 0, IP4_BASEMASK, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *mask = data; + return SW_OK; +} + +static sw_error_t +_isisc_nat_pub_addr_commit(a_uint32_t dev_id, fal_nat_pub_addr_t * entry, + a_uint32_t op, a_uint32_t * empty) +{ + a_uint32_t index, addr, data, tbl[2] = { 0 }; + sw_error_t rv; + + *empty = ISISC_PUB_ADDR_NUM; + for (index = 0; index < ISISC_PUB_ADDR_NUM; index++) + { + addr = ISISC_PUB_ADDR_TBL1_ADDR + (index << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[1])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PUB_ADDR1, ADDR_VALID, data, tbl[1]); + if (data) + { + addr = ISISC_PUB_ADDR_TBL0_ADDR + (index << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[0])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (!aos_mem_cmp + ((void *) &(entry->pub_addr), (void *) &(tbl[0]), + sizeof (fal_ip4_addr_t))) + { + if (ISISC_NAT_ENTRY_DEL == op) + { + addr = ISISC_PUB_ADDR_TBL1_ADDR + (index << 4); + tbl[1] = 0; + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[1])), + sizeof (a_uint32_t)); + *empty = index; + return rv; + } + else if (ISISC_NAT_ENTRY_ADD == op) + { + entry->entry_id = index; + return SW_ALREADY_EXIST; + } + } + } + else + { + *empty = index; + } + } + + return SW_NOT_FOUND; +} + +static sw_error_t +_isisc_nat_pub_addr_add(a_uint32_t dev_id, fal_nat_pub_addr_t * entry) +{ + sw_error_t rv; + a_uint32_t i, empty, addr, data = 0, tbl[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + tbl[0] = entry->pub_addr; + tbl[1] = 1; + + rv = _isisc_nat_pub_addr_commit(dev_id, entry, ISISC_NAT_ENTRY_ADD, &empty); + if (SW_ALREADY_EXIST == rv) + { + return rv; + } + + if (ISISC_PUB_ADDR_NUM == empty) + { + return SW_NO_RESOURCE; + } + + for (i = 0; i < 1; i++) + { + addr = ISISC_PUB_ADDR_EDIT0_ADDR + (empty << 4) + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[i])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + addr = ISISC_PUB_ADDR_OFFLOAD_ADDR + (empty << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[0])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + addr = ISISC_PUB_ADDR_VALID_ADDR; + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data |= (0x1 << empty); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + for (i = 0; i < 2; i++) + { + addr = ISISC_PUB_ADDR_TBL0_ADDR + (empty << 4) + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[i])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + entry->entry_id = empty; + return SW_OK; +} + +static sw_error_t +_isisc_nat_pub_addr_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_nat_pub_addr_t * entry) +{ + sw_error_t rv; + a_uint32_t empty, addr, data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_nat_pub_addr_commit(dev_id, entry, ISISC_NAT_ENTRY_DEL, &empty); + SW_RTN_ON_ERROR(rv); + + addr = ISISC_PUB_ADDR_VALID_ADDR; + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data &= (~(0x1 << empty)); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_isisc_nat_pub_addr_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_nat_pub_addr_t * entry) +{ + sw_error_t rv; + a_uint32_t data, addr, idx, index, tbl[2] = {0}; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_NEXT_ENTRY_FIRST_ID == entry->entry_id) + { + idx = 0; + } + else + { + if ((ISISC_PUB_ADDR_NUM - 1) == entry->entry_id) + { + return SW_NO_MORE; + } + else + { + idx = entry->entry_id + 1; + } + } + + for (index = idx; index < ISISC_PUB_ADDR_NUM; index++) + { + addr = ISISC_PUB_ADDR_TBL1_ADDR + (index << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[1])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PUB_ADDR1, ADDR_VALID, data, tbl[1]); + if (data) + { + break; + } + } + + if (ISISC_PUB_ADDR_NUM == index) + { + return SW_NO_MORE; + } + + addr = ISISC_PUB_ADDR_TBL0_ADDR + (index << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[0])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + entry->entry_id = index; + entry->pub_addr = tbl[0]; + + return SW_OK; +} + +static sw_error_t +_isisc_nat_unk_session_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t data; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_MAC_DROP == cmd) + { + data = 1; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + data = 0; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, FORWARD_CTL0, 0, NAT_NOT_FOUND_DROP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_nat_unk_session_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, FORWARD_CTL0, 0, NAT_NOT_FOUND_DROP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0 == data) + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + else + { + *cmd = FAL_MAC_DROP; + } + + return SW_OK; +} + +sw_error_t +isisc_nat_reset(a_uint32_t dev_id) +{ + sw_error_t rv; + a_uint32_t index, addr, data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_nat_feature_check(dev_id); + SW_RTN_ON_ERROR(rv); + + isisc_nat_snap[dev_id] = 0; + + HSL_REG_ENTRY_SET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_nat_entry_commit(dev_id, ISISC_ENTRY_NAT, ISISC_NAT_ENTRY_FLUSH); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, HOST_ENTRY7, 0, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_nat_entry_commit(dev_id, ISISC_ENTRY_NAPT, ISISC_NAT_ENTRY_FLUSH); + SW_RTN_ON_ERROR(rv); + + for (index = 0; index < ISISC_PUB_ADDR_NUM; index++) + { + addr = ISISC_PUB_ADDR_TBL1_ADDR + (index << 4); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +/** + * @brief Add one NAT entry to one particular device. + * @details Comments: + Before NAT entry added ip4 private base address must be set + at first. + In parameter nat_entry entry flags must be set + Hardware entry id will be returned. + * @param[in] dev_id device id + * @param[in] nat_entry NAT entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_nat_add(a_uint32_t dev_id, fal_nat_entry_t * nat_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_nat_add(dev_id, nat_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Del NAT entries from one particular device. + * @param[in] dev_id device id + * @param[in] del_mode NAT entry delete operation mode + * @param[in] nat_entry NAT entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_nat_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_nat_entry_t * nat_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_nat_del(dev_id, del_mode, nat_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get one NAT entry from one particular device. + * @param[in] dev_id device id + * @param[in] get_mode NAT entry get operation mode + * @param[in] nat_entry NAT entry parameter + * @param[out] nat_entry NAT entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_nat_get(a_uint32_t dev_id, a_uint32_t get_mode, + fal_nat_entry_t * nat_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_nat_get(dev_id, get_mode, nat_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Next NAT entries from one particular device. + * @param[in] dev_id device id + * @param[in] next_mode NAT entry next operation mode + * @param[in] nat_entry NAT entry parameter + * @param[out] nat_entry NAT entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_nat_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_nat_entry_t * nat_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_nat_next(dev_id, next_mode, nat_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Bind one counter entry to one NAT entry to one particular device. + * @param[in] dev_id device id + * @param[in] entry_id NAT entry id + * @param[in] cnt_id counter entry id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_nat_counter_bind(dev_id, entry_id, cnt_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add one NAPT entry to one particular device. + * @details Comments: + Before NAPT entry added related ip4 private base address must be set + at first. + In parameter napt_entry related entry flags must be set + Hardware entry id will be returned. + * @param[in] dev_id device id + * @param[in] napt_entry NAPT entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_napt_add(a_uint32_t dev_id, fal_napt_entry_t * napt_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_napt_add(dev_id, napt_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Del NAPT entries from one particular device. + * @param[in] dev_id device id + * @param[in] del_mode NAPT entry delete operation mode + * @param[in] napt_entry NAPT entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_napt_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_napt_entry_t * napt_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_napt_del(dev_id, del_mode, napt_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get one NAPT entry from one particular device. + * @param[in] dev_id device id + * @param[in] get_mode NAPT entry get operation mode + * @param[in] nat_entry NAPT entry parameter + * @param[out] nat_entry NAPT entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_napt_get(a_uint32_t dev_id, a_uint32_t get_mode, + fal_napt_entry_t * napt_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_napt_get(dev_id, get_mode, napt_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Next NAPT entries from one particular device. + * @param[in] dev_id device id + * @param[in] next_mode NAPT entry next operation mode + * @param[in] napt_entry NAPT entry parameter + * @param[out] napt_entry NAPT entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_napt_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_napt_entry_t * napt_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_napt_next(dev_id, next_mode, napt_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Bind one counter entry to one NAPT entry to one particular device. + * @param[in] dev_id device id + * @param[in] entry_id NAPT entry id + * @param[in] cnt_id counter entry id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_napt_counter_bind(dev_id, entry_id, cnt_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set working status of NAT engine on a particular device + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_nat_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_nat_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get working status of NAT engine on a particular device + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_nat_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_nat_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set NAT hash mode on a particular device + * @param[in] dev_id device id + * @param[in] mode NAT hash mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_nat_hash_mode_set(a_uint32_t dev_id, a_uint32_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_nat_hash_mode_set(dev_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get NAT hash mode on a particular device + * @param[in] dev_id device id + * @param[out] mode NAT hash mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_nat_hash_mode_get(a_uint32_t dev_id, a_uint32_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_nat_hash_mode_get(dev_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set working status of NAPT engine on a particular device + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_napt_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_napt_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get working status of NAPT engine on a particular device + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_napt_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_napt_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set working mode of NAPT engine on a particular device + * @param[in] dev_id device id + * @param[in] mode NAPT mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_napt_mode_set(a_uint32_t dev_id, fal_napt_mode_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_napt_mode_set(dev_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get working mode of NAPT engine on a particular device + * @param[in] dev_id device id + * @param[out] mode NAPT mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_napt_mode_get(a_uint32_t dev_id, fal_napt_mode_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_napt_mode_get(dev_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set IP4 private base address on a particular device + * @details Comments: + Only 20bits is meaning which 20bits is determined by private address mode. + * @param[in] dev_id device id + * @param[in] addr private base address + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_nat_prv_base_addr_set(a_uint32_t dev_id, fal_ip4_addr_t addr) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_nat_prv_base_addr_set(dev_id, addr); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IP4 private base address on a particular device + * @param[in] dev_id device id + * @param[out] addr private base address + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_nat_prv_base_addr_get(a_uint32_t dev_id, fal_ip4_addr_t * addr) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_nat_prv_base_addr_get(dev_id, addr); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set IP4 private base address on a particular device + * @param[in] dev_id device id + * @param[in] mask private base mask + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_nat_prv_base_mask_set(a_uint32_t dev_id, fal_ip4_addr_t mask) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_nat_prv_base_mask_set(dev_id, mask); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IP4 private base address on a particular device + * @param[in] dev_id device id + * @param[out] mask private base mask + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_nat_prv_base_mask_get(a_uint32_t dev_id, fal_ip4_addr_t * mask) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_nat_prv_base_mask_get(dev_id, mask); + HSL_API_UNLOCK; + return rv; +} + +#if 0 +/** + * @brief Set IP4 private base address on a particular device + * @details Comments: + Only 20bits is meaning which 20bits is determined by private address mode. + * @param[in] dev_id device id + * @param[in] addr private base address + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_nat_psr_prv_base_addr_set(a_uint32_t dev_id, fal_ip4_addr_t addr) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_nat_psr_prv_base_addr_set(dev_id, addr); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get IP4 private base address on a particular device + * @param[in] dev_id device id + * @param[out] addr private base address + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_nat_psr_prv_base_addr_get(a_uint32_t dev_id, fal_ip4_addr_t * addr) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_nat_psr_prv_base_addr_get(dev_id, addr); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set IP4 private base address mode on a particular device + * @details Comments: + If map_en equal true means bits31-20 bits15-8 are base address + else bits31-12 are base address. + * @param[in] dev_id device id + * @param[in] map_en private base mapping mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_nat_prv_addr_mode_set(a_uint32_t dev_id, a_bool_t map_en) +{ + sw_error_t rv = SW_OK; + + HSL_API_LOCK; + /*rv = _isisc_nat_prv_addr_mode_set(dev_id, map_en);*/ + HSL_API_UNLOCK; + return rv; +} +#endif + +/** + * @brief Get IP4 private base address mode on a particular device + * @param[in] dev_id device id + * @param[out] map_en private base mapping mode + * @return SW_OK or error code + */ +sw_error_t +isisc_nat_prv_addr_mode_get(a_uint32_t dev_id, a_bool_t * map_en) +{ + sw_error_t rv = SW_OK; + + HSL_API_LOCK; + /*rv = _isisc_nat_prv_addr_mode_get(dev_id, map_en);*/ + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add one public address entry to one particular device. + * @details Comments: + Hardware entry id will be returned. + * @param[in] dev_id device id + * @param[in] entry public address entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_nat_pub_addr_add(a_uint32_t dev_id, fal_nat_pub_addr_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_nat_pub_addr_add(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete one public address entry from one particular device. + * @param[in] dev_id device id + * @param[in] del_mode delete operaton mode + * @param[in] entry public address entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_nat_pub_addr_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_nat_pub_addr_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_nat_pub_addr_del(dev_id, del_mode, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Next public address entries from one particular device. + * @param[in] dev_id device id + * @param[in] next_mode next operaton mode + * @param[out] entry public address entry parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_nat_pub_addr_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_nat_pub_addr_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_nat_pub_addr_next(dev_id, next_mode, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set forwarding command for those packets miss NAT entries on a particular device. + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_nat_unk_session_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_nat_unk_session_cmd_set(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get forwarding command for those packets miss NAT entries on a particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_nat_unk_session_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_nat_unk_session_cmd_get(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set working status of NAT engine on a particular device + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] portbmp port bitmap + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_nat_global_set(a_uint32_t dev_id, a_bool_t enable, a_uint32_t portbmp) +{ + sw_error_t rv = SW_OK; + + HSL_API_LOCK; + printk("enable:%d\n", enable); + if(enable) { + if(isisc_nat_global_status == 0) { + isisc_nat_global_status = 1; +#if defined(IN_NAT_HELPER) + ISISC_NAT_HELPER_INIT(rv, dev_id, portbmp); +#endif + } + } else { + if(isisc_nat_global_status == 1) { + isisc_nat_global_status = 0; +#if defined(IN_NAT_HELPER) + ISISC_NAT_HELPER_CLEANUP(rv, dev_id); +#endif + } + } + //rv = SW_OK; + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +isisc_nat_init(a_uint32_t dev_id) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + rv = isisc_nat_reset(dev_id); + SW_RTN_ON_ERROR(rv); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->nat_add = isisc_nat_add; + p_api->nat_del = isisc_nat_del; + p_api->nat_get = isisc_nat_get; + p_api->nat_next = isisc_nat_next; + p_api->nat_counter_bind = isisc_nat_counter_bind; + p_api->napt_add = isisc_napt_add; + p_api->napt_del = isisc_napt_del; + p_api->napt_get = isisc_napt_get; + p_api->napt_next = isisc_napt_next; + p_api->napt_counter_bind = isisc_napt_counter_bind; + p_api->nat_status_set = isisc_nat_status_set; + p_api->nat_status_get = isisc_nat_status_get; + p_api->nat_hash_mode_set = isisc_nat_hash_mode_set; + p_api->nat_hash_mode_get = isisc_nat_hash_mode_get; + p_api->napt_status_set = isisc_napt_status_set; + p_api->napt_status_get = isisc_napt_status_get; + p_api->napt_mode_set = isisc_napt_mode_set; + p_api->napt_mode_get = isisc_napt_mode_get; + p_api->nat_pub_addr_add = isisc_nat_pub_addr_add; + p_api->nat_pub_addr_del = isisc_nat_pub_addr_del; + p_api->nat_pub_addr_next = isisc_nat_pub_addr_next; + p_api->nat_unk_session_cmd_set = isisc_nat_unk_session_cmd_set; + p_api->nat_unk_session_cmd_get = isisc_nat_unk_session_cmd_get; + p_api->nat_prv_base_addr_set = isisc_nat_prv_base_addr_set; + p_api->nat_prv_base_addr_get = isisc_nat_prv_base_addr_get; + p_api->nat_prv_base_mask_set = isisc_nat_prv_base_mask_set; + p_api->nat_prv_base_mask_get = isisc_nat_prv_base_mask_get; + p_api->nat_global_set = isisc_nat_global_set; + } +#endif + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_port_ctrl.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_port_ctrl.c new file mode 100755 index 000000000..2549b0d0a --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_port_ctrl.c @@ -0,0 +1,2797 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup isisc_port_ctrl ISISC_PORT_CONTROL + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isisc_port_ctrl.h" +#include "isisc_reg.h" +#include "hsl_phy.h" + +static a_bool_t +_isisc_port_phy_connected(a_uint32_t dev_id, fal_port_t port_id) +{ + if ((0 == port_id) || (6 == port_id)) + { + return A_FALSE; + } + else + { + return A_TRUE; + } +} + +static sw_error_t +_isisc_port_duplex_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t duplex) +{ + sw_error_t rv; + a_uint32_t phy_id, reg_save, reg_val = 0, force, tmp; + hsl_phy_ops_t *phy_drv; + a_bool_t status; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_DUPLEX_BUTT <= duplex) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_val), sizeof (a_uint32_t)); + SW_GET_FIELD_BY_REG(PORT_STATUS, DUPLEX_MODE, tmp, reg_val); + + /* for those ports without PHY device we set MAC register */ + if (A_FALSE == _isisc_port_phy_connected(dev_id, port_id)) + { + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 0, reg_val); + if (FAL_HALF_DUPLEX == duplex) + { + if (tmp == 0) + return SW_OK; + SW_SET_REG_BY_FIELD(PORT_STATUS, DUPLEX_MODE, 0, reg_val); + } + else + { + if (tmp == 1) + return SW_OK; + SW_SET_REG_BY_FIELD(PORT_STATUS, DUPLEX_MODE, 1, reg_val); + } + reg_save = reg_val; + } + else + { + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_duplex_set) + return SW_NOT_SUPPORTED; + /* hardware requirement: set mac be config by sw and turn off RX/TX MAC */ + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + rv = phy_drv->phy_duplex_get (dev_id, phy_id, &tmp); + SW_RTN_ON_ERROR(rv); + status = phy_drv->phy_autoneg_status_get (dev_id, phy_id); + if ((tmp == duplex) && (status == A_FALSE)) + return SW_OK; + reg_save = reg_val; + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 0, reg_val); + SW_SET_REG_BY_FIELD(PORT_STATUS, RXMAC_EN, 0, reg_val); + SW_SET_REG_BY_FIELD(PORT_STATUS, TXMAC_EN, 0, reg_val); + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_val), sizeof (a_uint32_t)); + + rv = phy_drv->phy_duplex_set (dev_id, phy_id, duplex); + SW_RTN_ON_ERROR(rv); + + /* If MAC not in sync with PHY mode, the behavior is undefine. + You must be careful... */ + SW_GET_FIELD_BY_REG(PORT_STATUS, LINK_EN, force, reg_save); + if (!force) + { + if (FAL_HALF_DUPLEX == duplex) + { + SW_SET_REG_BY_FIELD(PORT_STATUS, DUPLEX_MODE, 0, reg_save); + } + else + { + SW_SET_REG_BY_FIELD(PORT_STATUS, DUPLEX_MODE, 1, reg_save); + } + } + } + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_save), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_port_speed_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t speed) +{ + sw_error_t rv; + a_uint32_t phy_id, reg_save, reg_val = 0, force, tmp; + hsl_phy_ops_t *phy_drv; + a_bool_t status; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_SPEED_1000 < speed) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_val), sizeof (a_uint32_t)); + SW_GET_FIELD_BY_REG(PORT_STATUS, SPEED_MODE, tmp, reg_val); + + /* for those ports without PHY device we set MAC register */ + if (A_FALSE == _isisc_port_phy_connected(dev_id, port_id)) + { + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 0, reg_val); + if (FAL_SPEED_10 == speed) + { + if (tmp == 0) + return SW_OK; + SW_SET_REG_BY_FIELD(PORT_STATUS, SPEED_MODE, 0, reg_val); + } + else if (FAL_SPEED_100 == speed) + { + if (tmp == 1) + return SW_OK; + SW_SET_REG_BY_FIELD(PORT_STATUS, SPEED_MODE, 1, reg_val); + } + else + { + if (tmp == 2) + return SW_OK; + SW_SET_REG_BY_FIELD(PORT_STATUS, SPEED_MODE, 2, reg_val); + } + reg_save = reg_val; + + } + else + { + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_speed_set) + return SW_NOT_SUPPORTED; + /* hardware requirement: set mac be config by sw and turn off RX/TX MAC */ + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + rv = phy_drv->phy_speed_get (dev_id, phy_id, &tmp); + SW_RTN_ON_ERROR(rv); + status = phy_drv->phy_autoneg_status_get (dev_id, phy_id); + if ((tmp == speed) && (status == A_FALSE)) + return SW_OK; + reg_save = reg_val; + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 0, reg_val); + SW_SET_REG_BY_FIELD(PORT_STATUS, RXMAC_EN, 0, reg_val); + SW_SET_REG_BY_FIELD(PORT_STATUS, TXMAC_EN, 0, reg_val); + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_val), sizeof (a_uint32_t)); + + + rv = phy_drv->phy_speed_set (dev_id, phy_id, speed); + SW_RTN_ON_ERROR(rv); + + /* If MAC not in sync with PHY mode, the behavior is undefine. + You must be careful... */ + SW_GET_FIELD_BY_REG(PORT_STATUS, LINK_EN, force, reg_save); + if (!force) + { + if (FAL_SPEED_10 == speed) + { + SW_SET_REG_BY_FIELD(PORT_STATUS, SPEED_MODE, 0, reg_save); + } + else if (FAL_SPEED_100 == speed) + { + SW_SET_REG_BY_FIELD(PORT_STATUS, SPEED_MODE, 1, reg_save); + } + else + { + SW_SET_REG_BY_FIELD(PORT_STATUS, SPEED_MODE, 2, reg_save); + } + } + } + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_save), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_port_flowctrl_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val, force, reg = 0, tmp; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_STATUS, FLOW_LINK_EN, force, reg); + if (force) + { + /* flow control isn't in force mode so can't set */ + return SW_DISABLE; + } + tmp = reg; + + SW_SET_REG_BY_FIELD(PORT_STATUS, RX_FLOW_EN, val, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TX_FLOW_EN, val, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TX_HALF_FLOW_EN, val, reg); + if (tmp == reg) + return SW_OK; + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_port_flowctrl_forcemode_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t reg = 0, tmp; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + SW_GET_FIELD_BY_REG(PORT_STATUS, FLOW_LINK_EN, tmp, reg); + + if (A_TRUE == enable) + { + if (tmp == 0) + return SW_OK; + SW_SET_REG_BY_FIELD(PORT_STATUS, FLOW_LINK_EN, 0, reg); + } + else if (A_FALSE == enable) + { + /* for those ports without PHY, it can't sync flow control status */ + if (A_FALSE == _isisc_port_phy_connected(dev_id, port_id)) + { + return SW_DISABLE; + } + if (tmp == 1) + return SW_OK; + SW_SET_REG_BY_FIELD(PORT_STATUS, FLOW_LINK_EN, 1, reg); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_port_speed_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t * pspeed) +{ + sw_error_t rv = SW_OK; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + /* for those ports without PHY device supposed always 1000Mbps */ + if (A_FALSE == _isisc_port_phy_connected(dev_id, port_id)) + { + *pspeed = FAL_SPEED_1000; + } + else + { + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_speed_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_speed_get (dev_id, phy_id, pspeed); + SW_RTN_ON_ERROR (rv); + } +#if 0 + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_STATUS, SPEED_MODE, field, reg); + if (0 == field) + { + *pspeed = FAL_SPEED_10; + } + else if (1 == field) + { + *pspeed = FAL_SPEED_100; + } + else if (2 == field) + { + *pspeed = FAL_SPEED_1000; + } + else + { + *pspeed = FAL_SPEED_BUTT; + rv = SW_READ_ERROR; + } +#endif + return rv; +} +static sw_error_t +_isisc_port_duplex_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t * pduplex) +{ + sw_error_t rv = SW_OK; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + /* for those ports without PHY device supposed always full */ + if (A_FALSE == _isisc_port_phy_connected(dev_id, port_id)) + { + *pduplex = FAL_FULL_DUPLEX; + } + else + { + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_duplex_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_duplex_get (dev_id, phy_id, pduplex); + SW_RTN_ON_ERROR (rv); + } +#if 0 + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_GET_FIELD_BY_REG(PORT_STATUS, DUPLEX_MODE, field, reg); + if (field) + { + *pduplex = FAL_FULL_DUPLEX; + } + else + { + *pduplex = FAL_HALF_DUPLEX; + } +#endif + return rv; +} + +static sw_error_t +_isisc_port_autoneg_restart(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_restart_autoneg) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_restart_autoneg (dev_id, phy_id); + return rv; +} + +static sw_error_t +_isisc_port_autoneg_adv_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t autoadv) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_autoneg_adv_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_autoneg_adv_set (dev_id, phy_id, autoadv); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +static sw_error_t +_isisc_port_autoneg_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status) +{ + a_uint32_t phy_id; + sw_error_t rv; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_autoneg_status_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + *status = phy_drv->phy_autoneg_status_get (dev_id, phy_id); + + return SW_OK; +} + +static sw_error_t +_isisc_port_autoneg_enable(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_autoneg_enable_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_autoneg_enable_set (dev_id, phy_id); + return rv; +} + + +static sw_error_t +_isisc_port_autoneg_adv_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * autoadv) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_autoneg_adv_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + *autoadv = 0; + rv = phy_drv->phy_autoneg_adv_get (dev_id, phy_id, autoadv); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + + +#ifndef IN_PORTCONTROL_MINI +static sw_error_t +_isisc_port_flowctrl_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t rx, reg = 0; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_STATUS, RX_FLOW_EN, rx, reg); + + if (1 == rx) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + + +static sw_error_t +_isisc_port_flowctrl_forcemode_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t force, reg; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_STATUS, FLOW_LINK_EN, force, reg); + if (0 == force) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_port_powersave_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_powersave_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_powersave_set (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_isisc_port_powersave_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_powersave_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_powersave_get (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_isisc_port_hibernate_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_hibernation_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_hibernation_set (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_isisc_port_hibernate_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_hibernation_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_hibernation_get (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_isisc_port_cdt(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t mdi_pair, + fal_cable_status_t * cable_status, a_uint32_t * cable_len) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_cdt) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_cdt (dev_id, phy_id, mdi_pair, cable_status, cable_len); + + return rv; +} + +static sw_error_t +_isisc_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; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + a_uint32_t phy_data; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_id_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_id_get (dev_id, phy_id, &phy_data); + SW_RTN_ON_ERROR (rv); + + *org_id = (phy_data >> 16) & 0xffff; + *rev_id = phy_data & 0xffff; + + return rv; +} + +static sw_error_t +_isisc_port_8023az_set (a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_8023az_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_8023az_set (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_isisc_port_8023az_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_8023az_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_8023az_get (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_isisc_port_local_loopback_set(a_uint32_t dev_id, a_uint32_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_local_loopback_set) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_local_loopback_set (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_isisc_port_local_loopback_get(a_uint32_t dev_id, a_uint32_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_local_loopback_set) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_local_loopback_get (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_isisc_port_remote_loopback_set(a_uint32_t dev_id, a_uint32_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_remote_loopback_set) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_remote_loopback_set (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_isisc_port_remote_loopback_get(a_uint32_t dev_id, a_uint32_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_remote_loopback_set) + { + return SW_NOT_SUPPORTED; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_remote_loopback_get (dev_id, phy_id, enable); + + return rv; +} + +#endif +static sw_error_t +_isisc_port_rxhdr_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t mode) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_NO_HEADER_EN == mode) + { + val = 0; + } + else if (FAL_ONLY_MANAGE_FRAME_EN == mode) + { + val = 1; + } + else if (FAL_ALL_TYPE_FRAME_EN == mode) + { + val = 2; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_HDR_CTL, port_id, RXHDR_MODE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} +#ifndef IN_PORTCONTROL_MINI +static sw_error_t +_isisc_port_rxhdr_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_HDR_CTL, port_id, RXHDR_MODE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *mode = FAL_ONLY_MANAGE_FRAME_EN; + } + else if (2 == val) + { + *mode = FAL_ALL_TYPE_FRAME_EN; + } + else + { + *mode = FAL_NO_HEADER_EN; + } + + return SW_OK; +} +#endif +static sw_error_t +_isisc_port_txhdr_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t mode) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_NO_HEADER_EN == mode) + { + val = 0; + } + else if (FAL_ONLY_MANAGE_FRAME_EN == mode) + { + val = 1; + } + else if (FAL_ALL_TYPE_FRAME_EN == mode) + { + val = 2; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_HDR_CTL, port_id, TXHDR_MODE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} +#ifndef IN_PORTCONTROL_MINI +static sw_error_t +_isisc_port_txhdr_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_HDR_CTL, port_id, TXHDR_MODE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *mode = FAL_ONLY_MANAGE_FRAME_EN; + } + else if (2 == val) + { + *mode = FAL_ALL_TYPE_FRAME_EN; + } + else + { + *mode = FAL_NO_HEADER_EN; + } + + return SW_OK; +} +#endif +static sw_error_t +_isisc_header_type_set(a_uint32_t dev_id, a_bool_t enable, a_uint32_t type) +{ + a_uint32_t reg = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_ENTRY_GET(rv, dev_id, HEADER_CTL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + if (0xffff < type) + { + return SW_BAD_PARAM; + } + SW_SET_REG_BY_FIELD(HEADER_CTL, TYPE_LEN, 1, reg); + SW_SET_REG_BY_FIELD(HEADER_CTL, TYPE_VAL, type, reg); + } + else if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(HEADER_CTL, TYPE_LEN, 0, reg); + SW_SET_REG_BY_FIELD(HEADER_CTL, TYPE_VAL, 0, reg); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_SET(rv, dev_id, HEADER_CTL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} +#ifndef IN_PORTCONTROL_MINI +static sw_error_t +_isisc_header_type_get(a_uint32_t dev_id, a_bool_t * enable, a_uint32_t * type) +{ + a_uint32_t data, reg = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_ENTRY_GET(rv, dev_id, HEADER_CTL, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(HEADER_CTL, TYPE_LEN, data, reg); + if (data) + { + SW_GET_FIELD_BY_REG(HEADER_CTL, TYPE_VAL, data, reg); + *enable = A_TRUE; + *type = data; + } + else + { + *enable = A_FALSE; + *type = 0; + } + + return SW_OK; +} +#endif +static sw_error_t +_isisc_port_txmac_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t reg, force, val = 0, tmp; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + tmp = reg; + + /* for those ports without PHY device we set MAC register */ + if (A_FALSE == _isisc_port_phy_connected(dev_id, port_id)) + { + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TXMAC_EN, val, reg); + } + else + { + SW_GET_FIELD_BY_REG(PORT_STATUS, LINK_EN, force, reg); + if (force) + { + /* link isn't in force mode so can't set */ + return SW_DISABLE; + } + else + { + SW_SET_REG_BY_FIELD(PORT_STATUS, TXMAC_EN, val, reg); + } + } + if (tmp == reg) + return SW_OK; + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} +#ifndef IN_PORTCONTROL_MINI +static sw_error_t +_isisc_port_txmac_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_STATUS, port_id, TXMAC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} +#endif +static sw_error_t +_isisc_port_rxmac_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t reg = 0, force, val = 0, tmp; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + tmp = reg; + + /* for those ports without PHY device we set MAC register */ + if (A_FALSE == _isisc_port_phy_connected(dev_id, port_id)) + { + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, RXMAC_EN, val, reg); + } + else + { + SW_GET_FIELD_BY_REG(PORT_STATUS, LINK_EN, force, reg); + if (force) + { + /* link isn't in force mode so can't set */ + return SW_DISABLE; + } + else + { + SW_SET_REG_BY_FIELD(PORT_STATUS, RXMAC_EN, val, reg); + } + } + if (tmp == reg) + return SW_OK; + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} +#ifndef IN_PORTCONTROL_MINI +static sw_error_t +_isisc_port_rxmac_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_STATUS, port_id, RXMAC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} +#endif +static sw_error_t +_isisc_port_txfc_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val, reg = 0, force, tmp; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + tmp = reg; + + /* for those ports without PHY device we set MAC register */ + if (A_FALSE == _isisc_port_phy_connected(dev_id, port_id)) + { + SW_SET_REG_BY_FIELD(PORT_STATUS, FLOW_LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TX_FLOW_EN, val, reg); + } + else + { + SW_GET_FIELD_BY_REG(PORT_STATUS, FLOW_LINK_EN, force, reg); + if (force) + { + /* flow control isn't in force mode so can't set */ + return SW_DISABLE; + } + else + { + SW_SET_REG_BY_FIELD(PORT_STATUS, TX_FLOW_EN, val, reg); + } + } + if (tmp == reg) + return SW_OK; + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_port_txfc_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_STATUS, port_id, TX_FLOW_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_port_rxfc_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val = 0, reg, force, tmp; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + tmp = reg; + + /* for those ports without PHY device we set MAC register */ + if (A_FALSE == _isisc_port_phy_connected(dev_id, port_id)) + { + SW_SET_REG_BY_FIELD(PORT_STATUS, FLOW_LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, RX_FLOW_EN, val, reg); + } + else + { + SW_GET_FIELD_BY_REG(PORT_STATUS, FLOW_LINK_EN, force, reg); + if (force) + { + /* flow control isn't in force mode so can't set */ + return SW_DISABLE; + } + else + { + SW_SET_REG_BY_FIELD(PORT_STATUS, RX_FLOW_EN, val, reg); + } + } + if ( tmp == reg) + return SW_OK; + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_port_rxfc_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_STATUS, port_id, RX_FLOW_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} +static sw_error_t +_isisc_port_link_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * status) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + + /* for those ports without PHY device supposed always link up */ + if (A_FALSE == _isisc_port_phy_connected(dev_id, port_id)) + { + *status = A_TRUE; + } + else + { + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_link_status_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == phy_drv->phy_link_status_get (dev_id, phy_id)) + { + *status = A_TRUE; + } + else + { + *status = A_FALSE; + } + } + + return SW_OK; +} + +static sw_error_t +_isisc_port_power_off (a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_power_off) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_power_off(dev_id, phy_id); + + return rv; +} + +static sw_error_t +_isisc_port_power_on (a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_power_on) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_power_on(dev_id, phy_id); + + return rv; +} + +static sw_error_t +_isisc_port_link_forcemode_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t reg = 0, tmp = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_STATUS, LINK_EN, tmp, reg); + + if (A_TRUE == enable) + { + if(tmp == 0) + return SW_OK; + + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 0, reg); + } + else if (A_FALSE == enable) + { + if(tmp == 1) + return SW_OK; + + /* for those ports without PHY, it can't sync link status */ + if (A_FALSE == _isisc_port_phy_connected(dev_id, port_id)) + { + return SW_DISABLE; + } + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 1, reg); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_port_link_forcemode_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_STATUS, port_id, LINK_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +#ifndef IN_PORTCONTROL_MINI +static sw_error_t +_isisc_port_bp_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val = 0, tmp; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + HSL_REG_FIELD_GET(rv, dev_id, PORT_STATUS, port_id, TX_HALF_FLOW_EN, + (a_uint8_t *) (&tmp), sizeof (a_uint32_t)); + if (tmp == val) + return SW_OK; + + HSL_REG_FIELD_SET(rv, dev_id, PORT_STATUS, port_id, TX_HALF_FLOW_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_port_bp_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_STATUS, port_id, TX_HALF_FLOW_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + + +static sw_error_t +_isisc_ports_link_status_get(a_uint32_t dev_id, a_uint32_t * status) +{ + sw_error_t rv; + a_uint32_t port_id; + a_uint32_t phy_id; + hsl_dev_t *pdev = NULL; + hsl_phy_ops_t *phy_drv; + a_uint32_t port_bmp[SW_MAX_NR_DEV] = {0}; + HSL_DEV_ID_CHECK(dev_id); + + pdev = hsl_dev_ptr_get(dev_id); + if (pdev == NULL) + return SW_NOT_INITIALIZED; + + port_bmp[dev_id] = qca_ssdk_phy_type_port_bmp_get(dev_id, F1_PHY_CHIP); + + *status = 0x0; + for (port_id = 0; port_id < pdev->nr_ports; port_id++) + { + if (port_id >= SW_MAX_NR_PORT) + break; + /* for those ports without PHY device supposed always link up */ + if (A_FALSE == _isisc_port_phy_connected(dev_id, port_id)) + { + *status |= (0x1 << port_id); + } + else + { + if(port_bmp[dev_id] & (0x1 << port_id)) + { + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_link_status_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == phy_drv->phy_link_status_get (dev_id, phy_id)) + { + *status |= (0x1 << port_id); + } + else + { + *status &= ~(0x1 << port_id); + } + } + } + } + return SW_OK; +} + +static sw_error_t +_isisc_port_mac_loopback_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_HDR_CTL, port_id, LOOPBACK_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_port_mac_loopback_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_HDR_CTL, port_id, LOOPBACK_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0 == val) + { + *enable = A_FALSE; + } + else + { + *enable = A_TRUE; + } + + return SW_OK; +} +#endif +/** + * @brief Set duplex mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] duplex duplex mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_duplex_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t duplex) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_duplex_set(dev_id, port_id, duplex); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set speed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] speed port speed + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_speed_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t speed) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_speed_set(dev_id, port_id, speed); + HSL_API_UNLOCK; + return rv; +} +/** + * @brief Get duplex mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] duplex duplex mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_duplex_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t * pduplex) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_duplex_get(dev_id, port_id, pduplex); + HSL_API_UNLOCK; + return rv; +} + + + +/** + * @brief Get speed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] speed port speed + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_speed_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t * pspeed) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_speed_get(dev_id, port_id, pspeed); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Enable auto negotiation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_autoneg_enable(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_autoneg_enable(dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Restart auto negotiation procedule on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_autoneg_restart(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_autoneg_restart(dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set auto negotiation advtisement ability on a particular port. + * @details Comments: + * auto negotiation advtisement ability is defined by macro such as + * FAL_PHY_ADV_10T_HD, FAL_PHY_ADV_PAUSE... + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] autoadv auto negotiation advtisement ability bit map + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_autoneg_adv_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t autoadv) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_autoneg_adv_set(dev_id, port_id, autoadv); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get auto negotiation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] status A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_autoneg_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_autoneg_status_get(dev_id, port_id, status); + HSL_API_UNLOCK; + return rv; +} + + +/** + * @brief Get auto negotiation advtisement ability on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] autoadv auto negotiation advtisement ability bit map + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_autoneg_adv_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * autoadv) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_autoneg_adv_get(dev_id, port_id, autoadv); + HSL_API_UNLOCK; + return rv; +} + +#ifndef IN_PORTCONTROL_MINI +/** + * @brief Get flow control status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_flowctrl_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_flowctrl_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + + + +/** + * @brief Get flow control force mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_flowctrl_forcemode_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_flowctrl_forcemode_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set powersaving status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_powersave_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_powersave_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get powersaving status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_powersave_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_powersave_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set hibernate status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_hibernate_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_hibernate_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get hibernate status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_hibernate_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_hibernate_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Run cable diagnostic test on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mdi_pair mdi pair id + * @param[out] cable_status cable status + * @param[out] cable_len cable len + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_cdt(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t mdi_pair, + fal_cable_status_t * cable_status, a_uint32_t * cable_len) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_cdt(dev_id, port_id, mdi_pair, cable_status, cable_len); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get phy id on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] org_id and rev_id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_port_phy_id_get (dev_id, port_id, org_id, rev_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set 802.3az status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_8023az_set (a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_8023az_set (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get 8023az status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_8023az_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_8023az_get (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +HSL_LOCAL sw_error_t +isisc_port_local_loopback_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_local_loopback_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +HSL_LOCAL sw_error_t +isisc_port_local_loopback_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_local_loopback_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +HSL_LOCAL sw_error_t +isisc_port_remote_loopback_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_remote_loopback_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +HSL_LOCAL sw_error_t +isisc_port_remote_loopback_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_remote_loopback_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +#endif + +/** + * @brief Set flow control(rx/tx/bp) status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_flowctrl_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_flowctrl_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flow control force mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_flowctrl_forcemode_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_flowctrl_forcemode_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of Atheros header packets parsed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_rxhdr_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_rxhdr_mode_set(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} +#ifndef IN_PORTCONTROL_MINI +/** + * @brief Get status of Atheros header packets parsed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_rxhdr_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_rxhdr_mode_get(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Set status of Atheros header packets parsed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_txhdr_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_txhdr_mode_set(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} +#ifndef IN_PORTCONTROL_MINI +/** + * @brief Get status of Atheros header packets parsed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_txhdr_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_txhdr_mode_get(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Set status of Atheros header type value on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] type header type value + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_header_type_set(a_uint32_t dev_id, a_bool_t enable, a_uint32_t type) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _isisc_header_type_set(dev_id, enable, type); + HSL_API_UNLOCK; + return rv; +} +#ifndef IN_PORTCONTROL_MINI +/** + * @brief Get status of Atheros header type value on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @param[out] type header type value + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_header_type_get(a_uint32_t dev_id, a_bool_t * enable, a_uint32_t * type) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_header_type_get(dev_id, enable, type); + HSL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Set status of txmac on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_txmac_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _isisc_port_txmac_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} +#ifndef IN_PORTCONTROL_MINI +/** + * @brief Get status of txmac on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_txmac_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_txmac_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Set status of rxmac on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_rxmac_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _isisc_port_rxmac_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} +#ifndef IN_PORTCONTROL_MINI +/** + * @brief Get status of rxmac on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_rxmac_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_rxmac_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Set status of tx flow control on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_txfc_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _isisc_port_txfc_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get status of tx flow control on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_txfc_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_txfc_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of rx flow control on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_rxfc_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _isisc_port_rxfc_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of rx flow control on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_rxfc_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_rxfc_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} +/** + * @brief Get link status on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] status link status up (A_TRUE) or down (A_FALSE) + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_link_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * status) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_link_status_get(dev_id, port_id, status); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief phy power off on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_power_off (a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _isisc_port_power_off (dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief phy power on on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_power_on (a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _isisc_port_power_on (dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set link force mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_link_forcemode_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _isisc_port_link_forcemode_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get link force mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_link_forcemode_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_link_forcemode_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +#ifndef IN_PORTCONTROL_MINI +/** + * @brief Set status of back pressure on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_bp_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _isisc_port_bp_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of back pressure on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_bp_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_bp_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get link status on all ports. + * @param[in] dev_id device id + * @param[out] status link status bitmap and bit 0 for port 0, bi 1 for port 1, ..., etc. + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_ports_link_status_get(a_uint32_t dev_id, a_uint32_t * status) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_ports_link_status_get(dev_id, status); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set mac loop back on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_mac_loopback_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _isisc_port_mac_loopback_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mac loop back on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_mac_loopback_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_mac_loopback_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} +#endif +sw_error_t +isisc_port_ctrl_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->port_duplex_set = isisc_port_duplex_set; + p_api->port_speed_set = isisc_port_speed_set; + p_api->port_flowctrl_set = isisc_port_flowctrl_set; + p_api->port_flowctrl_forcemode_set = isisc_port_flowctrl_forcemode_set; + p_api->port_duplex_get = isisc_port_duplex_get; + p_api->port_speed_get = isisc_port_speed_get; + p_api->port_autoneg_enable = isisc_port_autoneg_enable; + p_api->port_autoneg_restart = isisc_port_autoneg_restart; + p_api->port_autoneg_adv_set = isisc_port_autoneg_adv_set; + p_api->port_autoneg_status_get = isisc_port_autoneg_status_get; + p_api->port_autoneg_adv_get = isisc_port_autoneg_adv_get; +#ifndef IN_PORTCONTROL_MINI + p_api->port_flowctrl_get = isisc_port_flowctrl_get; + p_api->port_flowctrl_forcemode_get = isisc_port_flowctrl_forcemode_get; + p_api->port_powersave_set = isisc_port_powersave_set; + p_api->port_powersave_get = isisc_port_powersave_get; + p_api->port_hibernate_set = isisc_port_hibernate_set; + p_api->port_hibernate_get = isisc_port_hibernate_get; + p_api->port_cdt = isisc_port_cdt; + p_api->port_phy_id_get = isisc_port_phy_id_get; + p_api->port_rxhdr_mode_get = isisc_port_rxhdr_mode_get; + p_api->port_txhdr_mode_get = isisc_port_txhdr_mode_get; + p_api->header_type_get = isisc_header_type_get; + p_api->port_txmac_status_get = isisc_port_txmac_status_get; + p_api->port_rxmac_status_get = isisc_port_rxmac_status_get; + p_api->port_8023az_set = isisc_port_8023az_set; + p_api->port_8023az_get = isisc_port_8023az_get; + p_api->port_local_loopback_set = isisc_port_local_loopback_set; + p_api->port_local_loopback_get = isisc_port_local_loopback_get; + p_api->port_remote_loopback_set = isisc_port_remote_loopback_set; + p_api->port_remote_loopback_get = isisc_port_remote_loopback_get; + +#endif + p_api->port_txfc_status_get = isisc_port_txfc_status_get; + p_api->port_rxhdr_mode_set = isisc_port_rxhdr_mode_set; + p_api->port_txhdr_mode_set = isisc_port_txhdr_mode_set; + p_api->header_type_set = isisc_header_type_set; + p_api->port_txmac_status_set = isisc_port_txmac_status_set; + p_api->port_rxmac_status_set = isisc_port_rxmac_status_set; + p_api->port_txfc_status_set = isisc_port_txfc_status_set; + p_api->port_rxfc_status_set = isisc_port_rxfc_status_set; + p_api->port_link_status_get = isisc_port_link_status_get; + p_api->port_rxfc_status_get = isisc_port_rxfc_status_get; + p_api->port_power_off = isisc_port_power_off; + p_api->port_power_on = isisc_port_power_on; + p_api->port_link_forcemode_set = isisc_port_link_forcemode_set; + p_api->port_link_forcemode_get = isisc_port_link_forcemode_get; +#ifndef IN_PORTCONTROL_MINI + p_api->port_bp_status_set = isisc_port_bp_status_set; + p_api->port_bp_status_get = isisc_port_bp_status_get; + p_api->ports_link_status_get = isisc_ports_link_status_get; + p_api->port_mac_loopback_set=isisc_port_mac_loopback_set; + p_api->port_mac_loopback_get=isisc_port_mac_loopback_get; +#endif + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_portvlan.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_portvlan.c new file mode 100755 index 000000000..bac24ac1c --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_portvlan.c @@ -0,0 +1,2277 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup isisc_port_vlan ISISC_PORT_VLAN + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isisc_portvlan.h" +#include "isisc_reg.h" + +#define MAX_VLAN_ID 4095 +#define ISISC_MAX_VLAN_TRANS 64 +#define ISISC_VLAN_TRANS_ADDR 0x5ac00 + + +static sw_error_t +_isisc_port_route_defv_set(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t data = 0, reg = 0; + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN1, port_id, + COREP_EN, (a_uint8_t *) (&data), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (data) + { + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN0, port_id, + DEF_SVID, (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else + { + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN0, port_id, + DEF_CVID, (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_DEFV, (port_id / 2), + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (port_id % 2) + { + reg &= 0xffff; + reg |= ((data & 0xfff) << 16); + } + else + { + reg &= 0xffff0000; + reg |= (data & 0xfff); + } + + HSL_REG_ENTRY_SET(rv, dev_id, ROUTER_DEFV, (port_id / 2), + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_port_1qmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t port_1qmode) +{ + sw_error_t rv; + a_uint32_t data, regval[FAL_1Q_MODE_BUTT] = { 0, 3, 2, 1 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_1Q_MODE_BUTT <= port_1qmode) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LOOKUP_CTL, port_id, DOT1Q_MODE, + (a_uint8_t *) (®val[port_1qmode]), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_1Q_DISABLE == port_1qmode) + { + data = 1; + } + else + { + data = 0; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN1, port_id, VLAN_DIS, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} +#ifndef IN_PORTVLAN_MINI +static sw_error_t +_isisc_port_1qmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t * pport_1qmode) +{ + sw_error_t rv; + a_uint32_t regval = 0; + fal_pt_1qmode_t retval[4] = { FAL_1Q_DISABLE, FAL_1Q_FALLBACK, + FAL_1Q_CHECK, FAL_1Q_SECURE + }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL(pport_1qmode); + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LOOKUP_CTL, port_id, DOT1Q_MODE, + (a_uint8_t *) (®val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + *pport_1qmode = retval[regval & 0x3]; + + return SW_OK; +} +#endif +static sw_error_t +_isisc_port_egvlanmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t port_egvlanmode) +{ + sw_error_t rv; + a_uint32_t data = 0, regval[FAL_EG_MODE_BUTT] = { 0, 1, 2, 3, 3 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if ((FAL_EG_MODE_BUTT <= port_egvlanmode) + || (FAL_EG_HYBRID == port_egvlanmode)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN1, port_id, EG_VLAN_MODE, + (a_uint8_t *) (®val[port_egvlanmode]), + sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ROUTER_EG, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data &= (~(0x3 << (port_id << 2))); + data |= (regval[port_egvlanmode] << (port_id << 2)); + + HSL_REG_ENTRY_SET(rv, dev_id, ROUTER_EG, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} +#ifndef IN_PORTVLAN_MINI +static sw_error_t +_isisc_port_egvlanmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t * pport_egvlanmode) +{ + sw_error_t rv; + a_uint32_t regval = 0; + fal_pt_1q_egmode_t retval[4] = { FAL_EG_UNMODIFIED, FAL_EG_UNTAGGED, + FAL_EG_TAGGED, FAL_EG_UNTOUCHED + }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL(pport_egvlanmode); + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN1, port_id, EG_VLAN_MODE, + (a_uint8_t *) (®val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + *pport_egvlanmode = retval[regval & 0x3]; + + return SW_OK; +} +#endif +static sw_error_t +_isisc_portvlan_member_add(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id) +{ + sw_error_t rv; + a_uint32_t regval = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_FALSE == hsl_port_prop_check(dev_id, mem_port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LOOKUP_CTL, port_id, + PORT_VID_MEM, (a_uint8_t *) (®val), + sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + regval |= (0x1UL << mem_port_id); + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LOOKUP_CTL, port_id, + PORT_VID_MEM, (a_uint8_t *) (®val), + sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_isisc_portvlan_member_del(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id) +{ + sw_error_t rv; + a_uint32_t regval = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_FALSE == hsl_port_prop_check(dev_id, mem_port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LOOKUP_CTL, port_id, + PORT_VID_MEM, (a_uint8_t *) (®val), + sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + regval &= (~(0x1UL << mem_port_id)); + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LOOKUP_CTL, port_id, + PORT_VID_MEM, (a_uint8_t *) (®val), + sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_isisc_portvlan_member_update(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t mem_port_map) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_FALSE == hsl_mports_prop_check(dev_id, mem_port_map, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LOOKUP_CTL, port_id, + PORT_VID_MEM, (a_uint8_t *) (&mem_port_map), + sizeof (a_uint32_t)); + + return rv; +} +#ifndef IN_PORTVLAN_MINI +static sw_error_t +_isisc_portvlan_member_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t * mem_port_map) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + *mem_port_map = 0; + HSL_REG_FIELD_GET(rv, dev_id, PORT_LOOKUP_CTL, port_id, + PORT_VID_MEM, (a_uint8_t *) mem_port_map, + sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} +#endif +static sw_error_t +_isisc_port_force_default_vid_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN1, port_id, + FORCE_DEF_VID, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} +#ifndef IN_PORTVLAN_MINI +static sw_error_t +_isisc_port_force_default_vid_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN1, port_id, + FORCE_DEF_VID, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} +#endif +static sw_error_t +_isisc_port_force_portvlan_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LOOKUP_CTL, port_id, + FORCE_PVLAN, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} +#ifndef IN_PORTVLAN_MINI +static sw_error_t +_isisc_port_force_portvlan_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LOOKUP_CTL, port_id, + FORCE_PVLAN, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} +#endif +static sw_error_t +_isisc_nestvlan_tpid_set(a_uint32_t dev_id, a_uint32_t tpid) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + val = tpid; + HSL_REG_FIELD_SET(rv, dev_id, SERVICE_TAG, 0, + TAG_VALUE, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} +#ifndef IN_PORTVLAN_MINI +static sw_error_t +_isisc_nestvlan_tpid_get(a_uint32_t dev_id, a_uint32_t * tpid) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, SERVICE_TAG, 0, + TAG_VALUE, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *tpid = val; + return SW_OK; +} +#endif +static sw_error_t +_isisc_port_invlan_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_invlan_mode_t mode) +{ + sw_error_t rv; + a_uint32_t regval[FAL_INVLAN_MODE_BUTT] = { 0, 1, 2 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_INVLAN_MODE_BUTT <= mode) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN1, port_id, IN_VLAN_MODE, + (a_uint8_t *) (®val[mode]), sizeof (a_uint32_t)); + return rv; +} +#ifndef IN_PORTVLAN_MINI +static sw_error_t +_isisc_port_invlan_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_invlan_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t regval = 0; + fal_pt_invlan_mode_t retval[FAL_INVLAN_MODE_BUTT] = { FAL_INVLAN_ADMIT_ALL, + FAL_INVLAN_ADMIT_TAGGED, FAL_INVLAN_ADMIT_UNTAGGED + }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL(mode); + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN1, port_id, IN_VLAN_MODE, + (a_uint8_t *) (®val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (regval >= 3) + { + return SW_FAIL; + } + *mode = retval[regval & 0x3]; + + return rv; +} +#endif + +static sw_error_t +_isisc_port_tls_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN1, port_id, + TLS_EN, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} +#ifndef IN_PORTVLAN_MINI +static sw_error_t +_isisc_port_tls_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN1, port_id, + TLS_EN, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_port_pri_propagation_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN1, port_id, + PRI_PROPAGATION, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_port_pri_propagation_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN1, port_id, + PRI_PROPAGATION, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} +#endif +static sw_error_t +_isisc_port_default_svid_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vid) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (vid > MAX_VLAN_ID) + { + return SW_BAD_PARAM; + } + + val = vid; + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN0, port_id, + DEF_SVID, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + rv = _isisc_port_route_defv_set(dev_id, port_id); + return rv; +} +#ifndef IN_PORTVLAN_MINI +static sw_error_t +_isisc_port_default_svid_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vid) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN0, port_id, + DEF_SVID, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + *vid = val & 0xfff; + return rv; +} +#endif +static sw_error_t +_isisc_port_default_cvid_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vid) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (vid > MAX_VLAN_ID) + { + return SW_BAD_PARAM; + } + + val = vid; + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN0, port_id, + DEF_CVID, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + rv = _isisc_port_route_defv_set(dev_id, port_id); + return rv; +} +#ifndef IN_PORTVLAN_MINI +static sw_error_t +_isisc_port_default_cvid_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vid) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN0, port_id, + DEF_CVID, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + *vid = val & 0xfff; + return rv; +} +#endif +static sw_error_t +_isisc_port_vlan_propagation_set(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_propagation_mode_t mode) +{ + sw_error_t rv; + a_uint32_t reg = 0, p, c; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_VLAN_PROPAGATION_DISABLE == mode) + { + p = 0; + c = 0; + } + else if (FAL_VLAN_PROPAGATION_CLONE == mode) + { + p = 1; + c = 1; + } + else if (FAL_VLAN_PROPAGATION_REPLACE == mode) + { + p = 1; + c = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_VLAN1, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(PORT_VLAN1, PROPAGATION_EN, p, reg); + SW_SET_REG_BY_FIELD(PORT_VLAN1, CLONE, c, reg); + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_VLAN1, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} +static sw_error_t +_isisc_vlan_trans_write(a_uint32_t dev_id, a_uint32_t entry_idx, fal_pbmp_t pbmp, + fal_vlan_trans_entry_t entry) +{ + sw_error_t rv; + a_uint32_t i, addr, table[2] = { 0 }; + + addr = ISISC_VLAN_TRANS_ADDR + (entry_idx << 3); + + if (0 != pbmp) + { + table[0] = entry.o_vid & 0xfff; + table[0] |= ((entry.s_vid & 0xfff) << 12); + table[0] |= ((entry.c_vid & 0xff) << 24); + table[1] = (entry.c_vid >> 8) & 0xf; + + if (A_TRUE == entry.bi_dir) + { + table[1] |= (0x3 << 4); + } + + if (A_TRUE == entry.forward_dir) + { + table[1] |= (0x1 << 4); + } + + if (A_TRUE == entry.reverse_dir) + { + table[1] |= (0x1 << 5); + } + + table[1] |= (pbmp << 6); + table[1] |= ((0x1UL & entry.o_vid_is_cvid) << 13); + table[1] |= ((0x1UL & entry.s_vid_enable) << 14); + table[1] |= ((0x1UL & entry.c_vid_enable) << 15); + table[1] |= ((0x1UL & entry.one_2_one_vlan) << 16); + } + + /* set vlan trans table */ + for (i = 0; i < 2; i++) + { + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr + (i << 2), sizeof (a_uint32_t), + (a_uint8_t *) (&(table[i])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} +#ifndef IN_PORTVLAN_MINI + +static sw_error_t +_isisc_port_vlan_propagation_get(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_propagation_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t reg = 0, p, c; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_VLAN1, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_VLAN1, PROPAGATION_EN, p, reg); + SW_GET_FIELD_BY_REG(PORT_VLAN1, CLONE, c, reg); + + if (p) + { + if (c) + { + *mode = FAL_VLAN_PROPAGATION_CLONE; + } + else + { + *mode = FAL_VLAN_PROPAGATION_REPLACE; + } + } + else + { + *mode = FAL_VLAN_PROPAGATION_DISABLE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_vlan_trans_read(a_uint32_t dev_id, a_uint32_t entry_idx, + fal_pbmp_t * pbmp, fal_vlan_trans_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t i, addr, dir, table[2] = {0}; + + *pbmp = 0; + aos_mem_zero(entry, sizeof (fal_vlan_trans_entry_t)); + + addr = ISISC_VLAN_TRANS_ADDR + (entry_idx << 3); + /* get vlan trans table */ + for (i = 0; i < 2; i++) + { + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr + (i << 2), sizeof (a_uint32_t), + (a_uint8_t *) (&(table[i])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + dir = 0x3 & (table[1] >> 4); + if (!dir) + { + return SW_EMPTY; + } + + entry->o_vid = table[0] & 0xfff; + *pbmp = (table[1] >> 6) & 0x7f; + + if (3 == dir) + { + entry->bi_dir = A_TRUE; + entry->forward_dir = A_TRUE; + entry->reverse_dir = A_TRUE; + } + else if (1 == dir) + { + entry->bi_dir = A_FALSE; + entry->forward_dir = A_TRUE; + entry->reverse_dir = A_FALSE; + } + else + { + entry->bi_dir = A_FALSE; + entry->forward_dir = A_FALSE; + entry->reverse_dir = A_TRUE; + } + + entry->o_vid_is_cvid = (table[1] >> 13) & 0x1UL; + entry->one_2_one_vlan = (table[1] >> 16) & 0x1UL; + entry->s_vid_enable = (table[1] >> 14) & 0x1UL; + entry->c_vid_enable = (table[1] >> 15) & 0x1UL; + + if (A_TRUE == entry->s_vid_enable) + { + entry->s_vid = (table[0] >> 12) & 0xfff; + } + + if (A_TRUE == entry->c_vid_enable) + { + entry->c_vid = ((table[0] >> 24) & 0xff) | ((table[1] & 0xf) << 8); + } + + return SW_OK; +} + + + +static sw_error_t +_isisc_port_vlan_trans_convert(fal_vlan_trans_entry_t * entry, + fal_vlan_trans_entry_t * local) +{ + aos_mem_copy(local, entry, sizeof (fal_vlan_trans_entry_t)); + + if ((A_TRUE == local->bi_dir) + || ((A_TRUE == local->forward_dir) + && (A_TRUE == local->reverse_dir))) + { + local->bi_dir = A_TRUE; + local->forward_dir = A_TRUE; + local->reverse_dir = A_TRUE; + } + + if (A_FALSE == local->s_vid_enable) + { + local->s_vid = 0; + } + + if (A_FALSE == local->c_vid_enable) + { + local->c_vid = 0; + } + + return SW_OK; +} + +static sw_error_t +_isisc_port_vlan_trans_add(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_trans_entry_t * entry) +{ + sw_error_t rv; + fal_pbmp_t t_pbmp; + a_uint32_t idx, entry_idx = ISISC_MAX_VLAN_TRANS; + fal_vlan_trans_entry_t temp, local; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (NULL == entry) + { + return SW_BAD_PTR; + } + aos_mem_zero(&local, sizeof(fal_vlan_trans_entry_t)); + rv = _isisc_port_vlan_trans_convert(entry, &local); + SW_RTN_ON_ERROR(rv); + + for (idx = 0; idx < ISISC_MAX_VLAN_TRANS; idx++) + { + rv = _isisc_vlan_trans_read(dev_id, idx, &t_pbmp, &temp); + if (SW_EMPTY == rv) + { + entry_idx = idx; + continue; + } + SW_RTN_ON_ERROR(rv); + + if (!aos_mem_cmp(&local, &temp, sizeof (fal_vlan_trans_entry_t))) + { + if (SW_IS_PBMP_MEMBER(t_pbmp, port_id)) + { + return SW_ALREADY_EXIST; + } + entry_idx = idx; + break; + } + else + { + t_pbmp = 0; + } + } + + if (ISISC_MAX_VLAN_TRANS != entry_idx) + { + t_pbmp |= (0x1 << port_id); + } + else + { + return SW_NO_RESOURCE; + } + + return _isisc_vlan_trans_write(dev_id, entry_idx, t_pbmp, local); +} + +static sw_error_t +_isisc_port_vlan_trans_del(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_trans_entry_t * entry) +{ + sw_error_t rv; + fal_pbmp_t t_pbmp; + a_uint32_t idx, entry_idx = ISISC_MAX_VLAN_TRANS; + fal_vlan_trans_entry_t temp, local; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (NULL == entry) + { + return SW_BAD_PTR; + } + aos_mem_zero(&local, sizeof(fal_vlan_trans_entry_t)); + rv = _isisc_port_vlan_trans_convert(entry, &local); + SW_RTN_ON_ERROR(rv); + + for (idx = 0; idx < ISISC_MAX_VLAN_TRANS; idx++) + { + rv = _isisc_vlan_trans_read(dev_id, idx, &t_pbmp, &temp); + if (SW_EMPTY == rv) + { + continue; + } + SW_RTN_ON_ERROR(rv); + + if (!aos_mem_cmp(&temp, &local, sizeof (fal_vlan_trans_entry_t))) + { + if (SW_IS_PBMP_MEMBER(t_pbmp, port_id)) + { + entry_idx = idx; + break; + } + } + } + + if (ISISC_MAX_VLAN_TRANS != entry_idx) + { + t_pbmp &= (~(0x1 << port_id)); + } + else + { + return SW_NOT_FOUND; + } + + return _isisc_vlan_trans_write(dev_id, entry_idx, t_pbmp, local); +} + +static sw_error_t +_isisc_port_vlan_trans_get(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_trans_entry_t * entry) +{ + sw_error_t rv; + fal_pbmp_t t_pbmp; + a_uint32_t idx; + fal_vlan_trans_entry_t temp, local; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (NULL == entry) + { + return SW_BAD_PTR; + } + aos_mem_zero(&local, sizeof(fal_vlan_trans_entry_t)); + rv = _isisc_port_vlan_trans_convert(entry, &local); + SW_RTN_ON_ERROR(rv); + + for (idx = 0; idx < ISISC_MAX_VLAN_TRANS; idx++) + { + rv = _isisc_vlan_trans_read(dev_id, idx, &t_pbmp, &temp); + if (SW_EMPTY == rv) + { + continue; + } + SW_RTN_ON_ERROR(rv); + + if (!aos_mem_cmp(&temp, &local, sizeof (fal_vlan_trans_entry_t))) + { + if (SW_IS_PBMP_MEMBER(t_pbmp, port_id)) + { + return SW_OK; + } + } + } + + return SW_NOT_FOUND; +} + +static sw_error_t +_isisc_port_vlan_trans_iterate(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * iterator, + fal_vlan_trans_entry_t * entry) +{ + a_uint32_t index; + sw_error_t rv; + fal_vlan_trans_entry_t entry_t; + fal_pbmp_t pbmp_t; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if ((NULL == iterator) || (NULL == entry)) + { + return SW_BAD_PTR; + } + + if (ISISC_MAX_VLAN_TRANS < *iterator) + { + return SW_BAD_PARAM; + } + + for (index = *iterator; index < ISISC_MAX_VLAN_TRANS; index++) + { + rv = _isisc_vlan_trans_read(dev_id, index, &pbmp_t, &entry_t); + if (SW_EMPTY == rv) + { + continue; + } + + if (SW_IS_PBMP_MEMBER(pbmp_t, port_id)) + { + aos_mem_copy(entry, &entry_t, sizeof (fal_vlan_trans_entry_t)); + break; + } + } + + if (ISISC_MAX_VLAN_TRANS == index) + { + return SW_NO_MORE; + } + + *iterator = index + 1; + return SW_OK; +} + +static sw_error_t +_isisc_qinq_mode_set(a_uint32_t dev_id, fal_qinq_mode_t mode) +{ + sw_error_t rv; + a_uint32_t stag = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_QINQ_MODE_BUTT <= mode) + { + return SW_BAD_PARAM; + } + + if (FAL_QINQ_STAG_MODE == mode) + { + stag = 1; + } + + HSL_REG_FIELD_SET(rv, dev_id, SERVICE_TAG, 0, + STAG_MODE, (a_uint8_t *) (&stag), sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_isisc_qinq_mode_get(a_uint32_t dev_id, fal_qinq_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t stag = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, SERVICE_TAG, 0, + STAG_MODE, (a_uint8_t *) (&stag), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (stag) + { + *mode = FAL_QINQ_STAG_MODE; + } + else + { + *mode = FAL_QINQ_CTAG_MODE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_port_qinq_role_set(a_uint32_t dev_id, fal_port_t port_id, + fal_qinq_port_role_t role) +{ + sw_error_t rv; + a_uint32_t core = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_QINQ_PORT_ROLE_BUTT <= role) + { + return SW_BAD_PARAM; + } + + if (FAL_QINQ_CORE_PORT == role) + { + core = 1; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN1, port_id, + COREP_EN, (a_uint8_t *) (&core), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + rv = _isisc_port_route_defv_set(dev_id, port_id); + return rv; +} + +static sw_error_t +_isisc_port_qinq_role_get(a_uint32_t dev_id, fal_port_t port_id, + fal_qinq_port_role_t * role) +{ + sw_error_t rv; + a_uint32_t core = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN1, port_id, + COREP_EN, (a_uint8_t *) (&core), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (core) + { + *role = FAL_QINQ_CORE_PORT; + } + else + { + *role = FAL_QINQ_EDGE_PORT; + } + + return SW_OK; +} + +static sw_error_t +_isisc_port_mac_vlan_xlt_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PRI_CTL, port_id, + EG_MAC_BASE_VLAN_EN, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; + +} + +static sw_error_t +_isisc_port_mac_vlan_xlt_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PRI_CTL, port_id, + EG_MAC_BASE_VLAN_EN, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_netisolate_set(a_uint32_t dev_id, a_uint32_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + val = enable; + HSL_REG_FIELD_SET(rv, dev_id, VLAN_TRANS, 0, + NET_ISO, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_netisolate_get(a_uint32_t dev_id, a_uint32_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, VLAN_TRANS, 0, + NET_ISO, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *enable = val; + return SW_OK; +} + +static sw_error_t +_isisc_eg_trans_filter_bypass_en_set(a_uint32_t dev_id, a_uint32_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + val = enable; + HSL_REG_FIELD_SET(rv, dev_id, VLAN_TRANS, 0, + EG_FLTR_BYPASS_EN, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_eg_trans_filter_bypass_en_get(a_uint32_t dev_id, a_uint32_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, VLAN_TRANS, 0, + EG_FLTR_BYPASS_EN, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *enable = val; + return SW_OK; +} +#endif + + +/** + * @brief Set 802.1q work mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] port_1qmode 802.1q work mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_1qmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t port_1qmode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_1qmode_set(dev_id, port_id, port_1qmode); + HSL_API_UNLOCK; + return rv; +} +#ifndef IN_PORTVLAN_MINI +/** + * @brief Get 802.1q work mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] port_1qmode 802.1q work mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_1qmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t * pport_1qmode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_1qmode_get(dev_id, port_id, pport_1qmode); + HSL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Set packets transmitted out vlan tagged mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] port_egvlanmode packets transmitted out vlan tagged mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_egvlanmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t port_egvlanmode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_egvlanmode_set(dev_id, port_id, port_egvlanmode); + HSL_API_UNLOCK; + return rv; +} +#ifndef IN_PORTVLAN_MINI +/** + * @brief Get packets transmitted out vlan tagged mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] port_egvlanmode packets transmitted out vlan tagged mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_egvlanmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t * pport_egvlanmode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_egvlanmode_get(dev_id, port_id, pport_egvlanmode); + HSL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Add member of port based vlan on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mem_port_id port member + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_portvlan_member_add(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_portvlan_member_add(dev_id, port_id, mem_port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete member of port based vlan on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mem_port_id port member + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_portvlan_member_del(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_portvlan_member_del(dev_id, port_id, mem_port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Update member of port based vlan on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mem_port_map port members + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_portvlan_member_update(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t mem_port_map) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_portvlan_member_update(dev_id, port_id, mem_port_map); + HSL_API_UNLOCK; + return rv; +} +#ifndef IN_PORTVLAN_MINI +/** + * @brief Get member of port based vlan on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mem_port_map port members + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_portvlan_member_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t * mem_port_map) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_portvlan_member_get(dev_id, port_id, mem_port_map); + HSL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Set force default vlan id status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_force_default_vid_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_force_default_vid_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} +#ifndef IN_PORTVLAN_MINI +/** + * @brief Get force default vlan id status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_force_default_vid_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_force_default_vid_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Set force port based vlan status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_force_portvlan_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_force_portvlan_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} +#ifndef IN_PORTVLAN_MINI +/** + * @brief Get force port based vlan status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_force_portvlan_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_force_portvlan_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Set nest vlan tpid on a particular device. + * @param[in] dev_id device id + * @param[in] tpid tag protocol identification + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_nestvlan_tpid_set(a_uint32_t dev_id, a_uint32_t tpid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_nestvlan_tpid_set(dev_id, tpid); + HSL_API_UNLOCK; + return rv; +} +#ifndef IN_PORTVLAN_MINI +/** + * @brief Get nest vlan tpid on a particular device. + * @param[in] dev_id device id + * @param[out] tpid tag protocol identification + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_nestvlan_tpid_get(a_uint32_t dev_id, a_uint32_t * tpid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_nestvlan_tpid_get(dev_id, tpid); + HSL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Set ingress vlan mode mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode ingress vlan mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_invlan_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_invlan_mode_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_invlan_mode_set(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} +#ifndef IN_PORTVLAN_MINI +/** + * @brief Get ingress vlan mode mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mode ingress vlan mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_invlan_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_invlan_mode_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_invlan_mode_get(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Set tls status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_tls_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_tls_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} +#ifndef IN_PORTVLAN_MINI + + +/** + * @brief Get tls status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_tls_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_tls_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set priority propagation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_pri_propagation_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_pri_propagation_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get priority propagation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_pri_propagation_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_pri_propagation_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Set default s-vid on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] vid s-vid + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_default_svid_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_default_svid_set(dev_id, port_id, vid); + HSL_API_UNLOCK; + return rv; +} +#ifndef IN_PORTVLAN_MINI +/** + * @brief Get default s-vid on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] vid s-vid + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_default_svid_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_default_svid_get(dev_id, port_id, vid); + HSL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Set default c-vid on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] vid c-vid + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_default_cvid_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_default_cvid_set(dev_id, port_id, vid); + HSL_API_UNLOCK; + return rv; +} +#ifndef IN_PORTVLAN_MINI +/** + * @brief Get default c-vid on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] vid c-vid + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_default_cvid_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_default_cvid_get(dev_id, port_id, vid); + HSL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Set vlan propagation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode vlan propagation mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_vlan_propagation_set(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_propagation_mode_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_vlan_propagation_set(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} +#ifndef IN_PORTVLAN_MINI + + +/** + * @brief Get vlan propagation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mode vlan propagation mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_vlan_propagation_get(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_propagation_mode_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_vlan_propagation_get(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add a vlan translation entry to a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param entry vlan translation entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_vlan_trans_add(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_trans_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_vlan_trans_add(dev_id, port_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a vlan translation entry from a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param entry vlan translation entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_vlan_trans_del(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_trans_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_vlan_trans_del(dev_id, port_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get a vlan translation entry from a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param entry vlan translation entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_vlan_trans_get(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_trans_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_vlan_trans_get(dev_id, port_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Iterate all vlan translation entries from a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] iterator translation entry index if it's zero means get the first entry + * @param[out] iterator next valid translation entry index + * @param[out] entry vlan translation entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_port_vlan_trans_iterate(dev_id, port_id, iterator, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set switch qinq work mode on a particular device. + * @param[in] dev_id device id + * @param[in] mode qinq work mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_qinq_mode_set(a_uint32_t dev_id, fal_qinq_mode_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_qinq_mode_set(dev_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get switch qinq work mode on a particular device. + * @param[in] dev_id device id + * @param[out] mode qinq work mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_qinq_mode_get(a_uint32_t dev_id, fal_qinq_mode_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_qinq_mode_get(dev_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set qinq role on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] role port role + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_qinq_role_set(a_uint32_t dev_id, fal_port_t port_id, + fal_qinq_port_role_t role) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_qinq_role_set(dev_id, port_id, role); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get qinq role on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] role port role + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_qinq_role_get(a_uint32_t dev_id, fal_port_t port_id, + fal_qinq_port_role_t * role) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_qinq_role_get(dev_id, port_id, role); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set MAC_VLAN_XLT status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] role port role + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_mac_vlan_xlt_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_mac_vlan_xlt_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get MAC_VLAN_XLT status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] role port role + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_mac_vlan_xlt_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_mac_vlan_xlt_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +#ifdef HSL_STANDALONG +HSL_LOCAL sw_error_t +isisc_port_route_defv_set(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv =_isisc_port_route_defv_set(dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} +#endif + +/** + * @brief Set NET_ISOLATE_EN + * @param[in] dev_id device id + * @param[in] role port role + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_netisolate_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_netisolate_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get NET_ISOLATE_EN status + * @param[in] dev_id device id + * @param[out] role port role + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_netisolate_get(a_uint32_t dev_id, a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_netisolate_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set egress translation filter bypass enable + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_eg_trans_filter_bypass_en_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_eg_trans_filter_bypass_en_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get egress translation filter bypass enable + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_eg_trans_filter_bypass_en_get(a_uint32_t dev_id, a_bool_t* enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_eg_trans_filter_bypass_en_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} +#endif + + +sw_error_t +isisc_portvlan_init(a_uint32_t dev_id) +{ + a_uint32_t i; + sw_error_t rv; + fal_vlan_trans_entry_t entry_init; + hsl_api_t *p_api; + + HSL_DEV_ID_CHECK(dev_id); + + aos_mem_set(&entry_init, 0, sizeof (fal_vlan_trans_entry_t)); + + for (i = 0; i < ISISC_MAX_VLAN_TRANS; i++) + { + rv = _isisc_vlan_trans_write(dev_id, i, 0, entry_init); + SW_RTN_ON_ERROR(rv); + } + +#ifndef HSL_STANDALONG + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->port_1qmode_set = isisc_port_1qmode_set; + p_api->port_egvlanmode_set = isisc_port_egvlanmode_set; + p_api->portvlan_member_add = isisc_portvlan_member_add; + p_api->portvlan_member_del = isisc_portvlan_member_del; + p_api->portvlan_member_update = isisc_portvlan_member_update; + p_api->port_force_default_vid_set = isisc_port_force_default_vid_set; + p_api->port_force_portvlan_set = isisc_port_force_portvlan_set; + p_api->nestvlan_tpid_set = isisc_nestvlan_tpid_set; + p_api->port_invlan_mode_set = isisc_port_invlan_mode_set; + p_api->port_tls_set = isisc_port_tls_set; + #ifndef IN_PORTVLAN_MINI + p_api->port_1qmode_get = isisc_port_1qmode_get; + p_api->port_egvlanmode_get = isisc_port_egvlanmode_get; + p_api->portvlan_member_get = isisc_portvlan_member_get; + p_api->port_force_default_vid_get = isisc_port_force_default_vid_get; + p_api->port_force_portvlan_get = isisc_port_force_portvlan_get; + p_api->nestvlan_tpid_get = isisc_nestvlan_tpid_get; + p_api->port_invlan_mode_get = isisc_port_invlan_mode_get; + p_api->port_tls_get = isisc_port_tls_get; + p_api->port_pri_propagation_set = isisc_port_pri_propagation_set; + p_api->port_pri_propagation_get = isisc_port_pri_propagation_get; + #endif + p_api->port_default_svid_set = isisc_port_default_svid_set; + p_api->port_default_cvid_set = isisc_port_default_cvid_set; + p_api->port_vlan_propagation_set = isisc_port_vlan_propagation_set; + #ifndef IN_PORTVLAN_MINI + p_api->port_default_cvid_get = isisc_port_default_cvid_get; + p_api->port_default_svid_get = isisc_port_default_svid_get; + p_api->port_vlan_propagation_get = isisc_port_vlan_propagation_get; + p_api->port_vlan_trans_add = isisc_port_vlan_trans_add; + p_api->port_vlan_trans_del = isisc_port_vlan_trans_del; + p_api->port_vlan_trans_get = isisc_port_vlan_trans_get; + p_api->qinq_mode_set = isisc_qinq_mode_set; + p_api->qinq_mode_get = isisc_qinq_mode_get; + p_api->port_qinq_role_set = isisc_port_qinq_role_set; + p_api->port_qinq_role_get = isisc_port_qinq_role_get; + p_api->port_vlan_trans_iterate = isisc_port_vlan_trans_iterate; + p_api->port_mac_vlan_xlt_set = isisc_port_mac_vlan_xlt_set; + p_api->port_mac_vlan_xlt_get = isisc_port_mac_vlan_xlt_get; + p_api->netisolate_set = isisc_netisolate_set; + p_api->netisolate_get = isisc_netisolate_get; + p_api->eg_trans_filter_bypass_en_set = isisc_eg_trans_filter_bypass_en_set; + p_api->eg_trans_filter_bypass_en_get = isisc_eg_trans_filter_bypass_en_get; + #endif +#endif + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_qos.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_qos.c new file mode 100755 index 000000000..e62d75eb2 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_qos.c @@ -0,0 +1,1639 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup isisc_qos ISISC_QOS + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isisc_qos.h" +#include "isisc_reg.h" + +#define ISISC_QOS_QUEUE_TX_BUFFER_MAX 120 +#define ISISC_QOS_PORT_TX_BUFFER_MAX 504 +#define ISISC_QOS_PORT_RX_BUFFER_MAX 120 + +#define ISISC_QOS_HOL_STEP 8 +#define ISISC_QOS_HOL_MOD 3 + +//#define ISISC_MIN_QOS_MODE_PRI 0 +#define ISISC_MAX_QOS_MODE_PRI 3 +#define ISISC_MAX_PRI 7 +#define ISISC_MAX_QUEUE 3 +#define ISISC_MAX_EH_QUEUE 5 + +static sw_error_t +_isisc_qos_port_queue_check(fal_port_t port_id, fal_queue_t queue_id) +{ + if ((0 == port_id) || (5 == port_id) || (6 == port_id)) + { + if (ISISC_MAX_EH_QUEUE < queue_id) + { + return SW_BAD_PARAM; + } + } + else + { + if (ISISC_MAX_QUEUE < queue_id) + { + return SW_BAD_PARAM; + } + } + + return SW_OK; +} + + +#ifndef IN_QOS_MINI +static sw_error_t +_isisc_qos_queue_tx_buf_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_HOL_CTL1, port_id, QUEUE_DESC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_qos_queue_tx_buf_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_HOL_CTL1, port_id, QUEUE_DESC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_qos_port_tx_buf_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_HOL_CTL1, port_id, PORT_DESC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_qos_port_tx_buf_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_HOL_CTL1, port_id, PORT_DESC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + + + + +static sw_error_t +_isisc_qos_port_red_en_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_HOL_CTL1, port_id, PORT_RED_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + + + + + +static sw_error_t +_isisc_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) +{ + a_uint32_t data = 0, val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + rv = _isisc_qos_port_queue_check(port_id, queue_id); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_HOL_CTL0, port_id, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + val = (data >> (queue_id << 2)) & 0xf; + *number = val << ISISC_QOS_HOL_MOD; + return SW_OK; +} + + +static sw_error_t +_isisc_qos_port_tx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_HOL_CTL0, port_id, PORT_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *number = val << ISISC_QOS_HOL_MOD; + return SW_OK; +} + + +static sw_error_t +_isisc_qos_port_rx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_HOL_CTL1, port_id, PORT_IN_DESC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *number = val << ISISC_QOS_HOL_MOD; + return SW_OK; +} +#endif +static sw_error_t +_isisc_qos_port_red_en_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_HOL_CTL1, port_id, PORT_RED_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_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) +{ + a_uint32_t data = 0, val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (ISISC_QOS_QUEUE_TX_BUFFER_MAX < *number) + { + return SW_BAD_PARAM; + } + + rv = _isisc_qos_port_queue_check(port_id, queue_id); + SW_RTN_ON_ERROR(rv); + + val = *number / ISISC_QOS_HOL_STEP; + *number = val << ISISC_QOS_HOL_MOD; + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_HOL_CTL0, port_id, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data &= (~(0xf << (queue_id << 2))); + data |= (val << (queue_id << 2)); + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_HOL_CTL0, port_id, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return rv; +} + +static sw_error_t +_isisc_qos_port_tx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (ISISC_QOS_PORT_TX_BUFFER_MAX < *number) + { + return SW_BAD_PARAM; + } + + val = *number / ISISC_QOS_HOL_STEP; + *number = val << ISISC_QOS_HOL_MOD; + HSL_REG_FIELD_SET(rv, dev_id, PORT_HOL_CTL0, port_id, PORT_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_qos_port_rx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (ISISC_QOS_PORT_RX_BUFFER_MAX < *number) + { + return SW_BAD_PARAM; + } + + val = *number / ISISC_QOS_HOL_STEP; + *number = val << ISISC_QOS_HOL_MOD; + HSL_REG_FIELD_SET(rv, dev_id, PORT_HOL_CTL1, port_id, PORT_IN_DESC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_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; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + if (FAL_QOS_DA_MODE == mode) + { + HSL_REG_FIELD_SET(rv, dev_id, PRI_CTL, port_id, DA_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (FAL_QOS_UP_MODE == mode) + { + HSL_REG_FIELD_SET(rv, dev_id, PRI_CTL, port_id, VLAN_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (FAL_QOS_DSCP_MODE == mode) + { + HSL_REG_FIELD_SET(rv, dev_id, PRI_CTL, port_id, IP_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + + return rv; +} + +#ifndef IN_QOS_MINI +static sw_error_t +_isisc_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; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_QOS_DA_MODE == mode) + { + HSL_REG_FIELD_GET(rv, dev_id, PRI_CTL, port_id, DA_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (FAL_QOS_UP_MODE == mode) + { + HSL_REG_FIELD_GET(rv, dev_id, PRI_CTL, port_id, VLAN_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (FAL_QOS_DSCP_MODE == mode) + { + HSL_REG_FIELD_GET(rv, dev_id, PRI_CTL, port_id, IP_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_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; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (ISISC_MAX_QOS_MODE_PRI < pri) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PRI_CTL, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_QOS_DA_MODE == mode) + { + SW_SET_REG_BY_FIELD(PRI_CTL, DA_PRI_SEL, pri, val); + } + else if (FAL_QOS_UP_MODE == mode) + { + SW_SET_REG_BY_FIELD(PRI_CTL, VLAN_PRI_SEL, pri, val); + } + else if (FAL_QOS_DSCP_MODE == mode) + { + SW_SET_REG_BY_FIELD(PRI_CTL, IP_PRI_SEL, pri, val); + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_ENTRY_SET(rv, dev_id, PRI_CTL, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_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; + a_uint32_t entry = 0, f_val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PRI_CTL, port_id, (a_uint8_t *) (&entry), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_QOS_DA_MODE == mode) + { + SW_GET_FIELD_BY_REG(PRI_CTL, DA_PRI_SEL, f_val, entry); + } + else if (FAL_QOS_UP_MODE == mode) + { + SW_GET_FIELD_BY_REG(PRI_CTL, VLAN_PRI_SEL, f_val, entry); + } + else if (FAL_QOS_DSCP_MODE == mode) + { + SW_GET_FIELD_BY_REG(PRI_CTL, IP_PRI_SEL, f_val, entry); + } + else + { + return SW_NOT_SUPPORTED; + } + + *pri = f_val; + return SW_OK; +} + +static sw_error_t +_isisc_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; + a_uint32_t reg = 0, val, w[6] = { 0 }; + a_int32_t i, _index; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_SCH_SP_MODE == mode) + { + val = 0; + _index = -1; + } + else if (FAL_SCH_WRR_MODE == mode) + { + val = 3; + _index = 5; + } + else if (FAL_SCH_MIX_MODE == mode) + { + val = 1; + _index = 4; + } + else if (FAL_SCH_MIX_PLUS_MODE == mode) + { + val = 2; + _index = 3; + } + else + { + return SW_NOT_SUPPORTED; + } + + for (i = _index; i >= 0; i--) + { + if (weight[i] > 0x1f) + { + return SW_BAD_PARAM; + } + w[i] = weight[i]; + } + + HSL_REG_ENTRY_GET(rv, dev_id, WRR_CTRL, port_id, (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(WRR_CTRL, SCH_MODE, val, reg); + SW_SET_REG_BY_FIELD(WRR_CTRL, Q5_W, w[5], reg); + SW_SET_REG_BY_FIELD(WRR_CTRL, Q4_W, w[4], reg); + SW_SET_REG_BY_FIELD(WRR_CTRL, Q3_W, w[3], reg); + SW_SET_REG_BY_FIELD(WRR_CTRL, Q2_W, w[2], reg); + SW_SET_REG_BY_FIELD(WRR_CTRL, Q1_W, w[1], reg); + SW_SET_REG_BY_FIELD(WRR_CTRL, Q0_W, w[0], reg); + + HSL_REG_ENTRY_SET(rv, dev_id, WRR_CTRL, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_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; + a_uint32_t val = 0, sch, w[6], i; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_ENTRY_GET(rv, dev_id, WRR_CTRL, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(WRR_CTRL, SCH_MODE, sch, val); + SW_GET_FIELD_BY_REG(WRR_CTRL, Q5_W, w[5], val); + SW_GET_FIELD_BY_REG(WRR_CTRL, Q4_W, w[4], val); + SW_GET_FIELD_BY_REG(WRR_CTRL, Q3_W, w[3], val); + SW_GET_FIELD_BY_REG(WRR_CTRL, Q2_W, w[2], val); + SW_GET_FIELD_BY_REG(WRR_CTRL, Q1_W, w[1], val); + SW_GET_FIELD_BY_REG(WRR_CTRL, Q0_W, w[0], val); + + if (0 == sch) + { + *mode = FAL_SCH_SP_MODE; + } + else if (1 == sch) + { + *mode = FAL_SCH_MIX_MODE; + } + else if (2 == sch) + { + *mode = FAL_SCH_MIX_PLUS_MODE; + } + else + { + *mode = FAL_SCH_WRR_MODE; + } + + for (i = 0; i < 6; i++) + { + weight[i] = w[i]; + } + + return SW_OK; +} + +static sw_error_t +_isisc_qos_port_default_spri_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t spri) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (ISISC_MAX_PRI < spri) + { + return SW_BAD_PARAM; + } + + val = spri; + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN0, port_id, + ING_SPRI, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_isisc_qos_port_default_spri_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * spri) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN0, port_id, + ING_SPRI, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + *spri = val & 0x7; + return rv; +} + +static sw_error_t +_isisc_qos_port_default_cpri_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t cpri) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (ISISC_MAX_PRI < cpri) + { + return SW_BAD_PARAM; + } + + val = cpri; + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN0, port_id, + ING_CPRI, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + return rv; +} + +HSL_LOCAL sw_error_t +_isisc_qos_port_default_cpri_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * cpri) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN0, port_id, + ING_CPRI, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + *cpri = val & 0x7; + return rv; +} + +HSL_LOCAL sw_error_t +_isisc_qos_port_force_spri_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN0, port_id, + ING_FORCE_SPRI, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +HSL_LOCAL sw_error_t +_isisc_qos_port_force_spri_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t* enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN0, port_id, + ING_FORCE_SPRI, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return rv; +} + +HSL_LOCAL sw_error_t +_isisc_qos_port_force_cpri_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + val = enable ? 1 : 0; + + HSL_REG_FIELD_SET(rv, dev_id, PORT_VLAN0, port_id, + ING_FORCE_CPRI, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + return rv; +} + +HSL_LOCAL sw_error_t +_isisc_qos_port_force_cpri_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t* enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_VLAN0, port_id, + ING_FORCE_CPRI, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return rv; +} + +static sw_error_t +_isisc_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; + a_uint32_t addr, data = 0; + a_uint32_t base[7] = {0x0c40, 0x0c48, 0x0c4c, 0x0c50, 0x0c54, 0x0c58, 0x0c60}; + + rv = _isisc_qos_port_queue_check(port_id, queue_id); + SW_RTN_ON_ERROR(rv); + + addr = base[port_id] + ((queue_id / 4) << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data &= (~(0xff << ((queue_id % 4) << 3))); + data |= (((enable << 7 ) | (tbl_id & 0xf)) << ((queue_id % 4) << 3)); + + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +HSL_LOCAL sw_error_t +_isisc_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; + a_uint32_t addr, data = 0; + a_uint32_t base[7] = {0x0c40, 0x0c48, 0x0c4c, 0x0c50, 0x0c54, 0x0c58, 0x0c60}; + + rv = _isisc_qos_port_queue_check(port_id, queue_id); + SW_RTN_ON_ERROR(rv); + + addr = base[port_id] + ((queue_id / 4) << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *tbl_id = (data >> ((queue_id % 4) << 3)) & 0xf; + *enable = ((data >> ((queue_id % 4) << 3)) & 0x80) >> 7; + return SW_OK; +} + +HSL_LOCAL sw_error_t +_isisc_port_static_thresh_get(a_uint32_t dev_id, fal_port_t port_id, + fal_bm_static_cfg_t *cfg) +{ + sw_error_t rv; + a_uint32_t reg_value, xon_value, xoff_value; + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_FLOW_CTRL_THRESHOLD, port_id, + (a_uint8_t *) (®_value), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_FLOW_CTRL_THRESHOLD, XON_THRES, xon_value, reg_value); + SW_GET_FIELD_BY_REG(PORT_FLOW_CTRL_THRESHOLD, XOFF_THRES, xoff_value, reg_value); + cfg->max_thresh = xoff_value; + cfg->resume_off = xoff_value - xon_value; + + return SW_OK; +} + +HSL_LOCAL sw_error_t +_isisc_port_static_thresh_set(a_uint32_t dev_id, fal_port_t port_id, + fal_bm_static_cfg_t *cfg) +{ + sw_error_t rv; + a_uint32_t reg_value = 0; + + SW_SET_REG_BY_FIELD(PORT_FLOW_CTRL_THRESHOLD, XON_THRES, cfg->max_thresh - cfg->resume_off, reg_value); + SW_SET_REG_BY_FIELD(PORT_FLOW_CTRL_THRESHOLD, XOFF_THRES, cfg->max_thresh, reg_value); + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_FLOW_CTRL_THRESHOLD, port_id, + (a_uint8_t *) (®_value), sizeof (a_uint32_t)); + + return SW_OK; +} +#endif + +#ifndef IN_QOS_MINI +/** + * @brief Set buffer aggsinment status of transmitting queue on one particular port. + * @details Comments: + * If enable queue tx buffer on one port that means each queue of this port + * will have fixed number buffers when transmitting packets. Otherwise they + * share the whole buffers with other queues in device. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_qos_queue_tx_buf_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_qos_queue_tx_buf_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get buffer aggsinment status of transmitting queue on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_qos_queue_tx_buf_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_qos_queue_tx_buf_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set buffer aggsinment status of transmitting port on one particular port. + * @details Comments: + If enable tx buffer on one port that means this port will have fixed + number buffers when transmitting packets. Otherwise they will + share the whole buffers with other ports in device. + * function will return actual buffer numbers in hardware. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_qos_port_tx_buf_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_qos_port_tx_buf_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get buffer aggsinment status of transmitting port on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_qos_port_tx_buf_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_qos_port_tx_buf_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + + + +/** + * @brief Set status of port red on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_qos_port_red_en_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t* enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_qos_port_red_en_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + + + + +/** + * @brief Get max occupied buffer number of transmitting queue on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param[out] number buffer number + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_qos_queue_tx_buf_nr_get(dev_id, port_id, queue_id, number); + HSL_API_UNLOCK; + return rv; +} + + + +/** + * @brief Get max occupied buffer number of transmitting port on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] number buffer number + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_qos_port_tx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_qos_port_tx_buf_nr_get(dev_id, port_id, number); + HSL_API_UNLOCK; + return rv; +} + + + +/** + * @brief Get max occupied buffer number of receiving port on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] number buffer number + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_qos_port_rx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_qos_port_rx_buf_nr_get(dev_id, port_id, number); + HSL_API_UNLOCK; + return rv; +} +#endif +/** + * @brief Set status of port red on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_qos_port_red_en_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_qos_port_red_en_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} +/** + * @brief Set max occupied buffer number of transmitting queue on one particular port. + * @details Comments: + The step of buffer number in Garuda is 4, function will return actual + buffer numbers in hardware. + The buffer number range for queue is 4 to 60. + * share the whole buffers with other ports in device. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param number buffer number + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_qos_queue_tx_buf_nr_set(dev_id, port_id, queue_id, number); + HSL_API_UNLOCK; + return rv; +} +/** + * @brief Set max occupied buffer number of transmitting port on one particular port. + * @details Comments: + The step of buffer number in Garuda is four, function will return actual + buffer numbers in hardware. + The buffer number range for transmitting port is 4 to 124. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param number buffer number + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_qos_port_tx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_qos_port_tx_buf_nr_set(dev_id, port_id, number); + HSL_API_UNLOCK; + return rv; +} +/** + * @brief Set max occupied buffer number of receiving port on one particular port. + * @details Comments: + The step of buffer number in Shiva is four, function will return actual + buffer numbers in hardware. + The buffer number range for receiving port is 4 to 60. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param number buffer number + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_qos_port_rx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_qos_port_rx_buf_nr_set(dev_id, port_id, number); + HSL_API_UNLOCK; + return rv; +} +/** + * @brief Set port qos mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode qos mode + * @param[in] enable A_TRUE of A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_qos_port_mode_set(dev_id, port_id, mode, enable); + HSL_API_UNLOCK; + return rv; +} + + +#ifndef IN_QOS_MINI +/** + * @brief Get port qos mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode qos mode + * @param[out] enable A_TRUE of A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_qos_port_mode_get(dev_id, port_id, mode, enable); + HSL_API_UNLOCK; + return rv; +} +/** + * @brief Set priority of one particular qos mode on one particular port. + * @details Comments: + If the priority of a mode is more small then the priority is more high. + Differnet mode should have differnet priority. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode qos mode + * @param[in] pri priority of one particular qos mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_qos_port_mode_pri_set(dev_id, port_id, mode, pri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get priority of one particular qos mode on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode qos mode + * @param[out] pri priority of one particular qos mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_qos_port_mode_pri_get(dev_id, port_id, mode, pri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set traffic scheduling mode on particular one port. + * @details Comments: + * When scheduling mode is sp the weight is meaningless usually it's zero + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] fal_sch_mode_t traffic scheduling mode + * @param[in] weight[] weight value for each queue when in wrr mode, + the max value supported by ISIS is 0x1f. + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_qos_port_sch_mode_set(dev_id, port_id, mode, weight); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get traffic scheduling mode on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] fal_sch_mode_t traffic scheduling mode + * @param[out] weight weight value for wrr mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_qos_port_sch_mode_get(dev_id, port_id, mode, weight); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set default stag priority on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] spri vlan priority + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_qos_port_default_spri_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t spri) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_qos_port_default_spri_set(dev_id, port_id, spri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get default stag priority on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] spri vlan priority + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_qos_port_default_spri_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * spri) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_qos_port_default_spri_get(dev_id, port_id, spri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set default ctag priority on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] cpri vlan priority + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_qos_port_default_cpri_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t cpri) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_qos_port_default_cpri_set(dev_id, port_id, cpri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get default ctag priority on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] cpri vlan priority + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_qos_port_default_cpri_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * cpri) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_qos_port_default_cpri_get(dev_id, port_id, cpri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set port force stag priority enable flag one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_qos_port_force_spri_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_qos_port_force_spri_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get port force stag priority enable flag one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_qos_port_force_spri_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t* enable) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _isisc_qos_port_force_spri_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set port force ctag priority enable flag one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_qos_port_force_cpri_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_qos_port_force_cpri_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get port force ctag priority enable flag one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_qos_port_force_cpri_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t* enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_qos_port_force_cpri_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set egress queue based CoS remark on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param[in] tbl_id CoS remark table id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_qos_queue_remark_table_set(dev_id, port_id, queue_id, tbl_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get egress queue based CoS remark on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param[out] tbl_id CoS remark table id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_qos_queue_remark_table_get(dev_id, port_id, queue_id, tbl_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get static flow control threshold on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] static maximum threshold and resume offset + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_static_thresh_get(a_uint32_t dev_id, fal_port_t port_id, + fal_bm_static_cfg_t *cfg) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_static_thresh_get(dev_id, port_id, cfg); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set static flow control threshold on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] static maximum threshold and resume offset + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_port_static_thresh_set(a_uint32_t dev_id, fal_port_t port_id, + fal_bm_static_cfg_t *cfg) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_port_static_thresh_set(dev_id, port_id, cfg); + HSL_API_UNLOCK; + return rv; +} +#endif + +sw_error_t +isisc_qos_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->qos_queue_tx_buf_nr_set = isisc_qos_queue_tx_buf_nr_set; + p_api->qos_port_red_en_set = isisc_qos_port_red_en_set; + p_api->qos_port_tx_buf_nr_set = isisc_qos_port_tx_buf_nr_set; + p_api->qos_port_rx_buf_nr_set = isisc_qos_port_rx_buf_nr_set; + #ifndef IN_QOS_MINI + p_api->qos_queue_tx_buf_status_set = isisc_qos_queue_tx_buf_status_set; + p_api->qos_queue_tx_buf_status_get = isisc_qos_queue_tx_buf_status_get; + p_api->qos_port_tx_buf_status_set = isisc_qos_port_tx_buf_status_set; + p_api->qos_port_tx_buf_status_get = isisc_qos_port_tx_buf_status_get; + p_api->qos_port_red_en_get = isisc_qos_port_red_en_get; + p_api->qos_queue_tx_buf_nr_get = isisc_qos_queue_tx_buf_nr_get; + p_api->qos_port_tx_buf_nr_get = isisc_qos_port_tx_buf_nr_get; + p_api->qos_port_rx_buf_nr_get = isisc_qos_port_rx_buf_nr_get; + #endif + p_api->qos_port_mode_set = isisc_qos_port_mode_set; + + #ifndef IN_QOS_MINI + p_api->qos_port_mode_get = isisc_qos_port_mode_get; + p_api->qos_port_mode_pri_set = isisc_qos_port_mode_pri_set; + p_api->qos_port_mode_pri_get = isisc_qos_port_mode_pri_get; + p_api->qos_port_sch_mode_set = isisc_qos_port_sch_mode_set; + p_api->qos_port_sch_mode_get = isisc_qos_port_sch_mode_get; + p_api->qos_port_default_spri_set = isisc_qos_port_default_spri_set; + p_api->qos_port_default_spri_get = isisc_qos_port_default_spri_get; + p_api->qos_port_default_cpri_set = isisc_qos_port_default_cpri_set; + p_api->qos_port_default_cpri_get = isisc_qos_port_default_cpri_get; + p_api->qos_port_force_spri_status_set = isisc_qos_port_force_spri_status_set; + p_api->qos_port_force_spri_status_get = isisc_qos_port_force_spri_status_get; + p_api->qos_port_force_cpri_status_set = isisc_qos_port_force_cpri_status_set; + p_api->qos_port_force_cpri_status_get = isisc_qos_port_force_cpri_status_get; + p_api->qos_queue_remark_table_set = isisc_qos_queue_remark_table_set; + p_api->qos_queue_remark_table_get = isisc_qos_queue_remark_table_get; + p_api->port_static_thresh_get = isisc_port_static_thresh_get; + p_api->port_static_thresh_set = isisc_port_static_thresh_set; + #endif + } +#endif + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_rate.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_rate.c new file mode 100755 index 000000000..0cbe6b044 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_rate.c @@ -0,0 +1,1662 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup isisc_rate ISISC_RATE + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isisc_rate.h" +#include "isisc_reg.h" + +#define ISISC_MAX_POLICER_ID 31 +#define ISISC_MAX_QUEUE 3 +#define ISISC_MAX_EH_QUEUE 5 + +#define ACL_POLICER_CNT_SEL_ADDR 0x09f0 +#define ACL_POLICER_CNT_MODE_ADDR 0x09f4 +#define ACL_POLICER_CNT_RST_ADDR 0x09f8 + +static sw_error_t +_isisc_rate_port_queue_check(fal_port_t port_id, fal_queue_t queue_id) +{ + if ((0 == port_id) || (5 == port_id) || (6 == port_id)) + { + if (ISISC_MAX_EH_QUEUE < queue_id) + { + return SW_BAD_PARAM; + } + } + else + { + if (ISISC_MAX_QUEUE < queue_id) + { + return SW_BAD_PARAM; + } + } + + return SW_OK; +} + +static void +_isisc_egress_bs_byte_sw_to_hw(a_uint32_t sw_bs, a_uint32_t * hw_bs) +{ + a_int32_t i; + a_uint32_t data[8] = + { + 0, 2 * 1024, 4 * 1024, 8 * 1024, 16 * 1024, 32 * 1024, 128 * 1024, + 512 * 1024 + }; + + for (i = 7; i >= 0; i--) + { + if (sw_bs >= data[i]) + { + *hw_bs = i; + break; + } + } +} + +static void +_isisc_egress_bs_byte_hw_to_sw(a_uint32_t hw_bs, a_uint32_t * sw_bs) +{ + a_uint32_t data[8] = + { + 0, 2 * 1024, 4 * 1024, 8 * 1024, 16 * 1024, 32 * 1024, 128 * 1024, + 512 * 1024 + }; + + *sw_bs = data[hw_bs & 0x7]; +} + +static void +_isisc_egress_bs_frame_sw_to_hw(a_uint32_t sw_bs, a_uint32_t * hw_bs) +{ + a_uint32_t data[8] = { 0, 2, 4, 16, 64, 256, 512, 1024 }; + a_int32_t i; + + for (i = 7; i >= 0; i--) + { + if (sw_bs >= data[i]) + { + *hw_bs = i; + break; + } + } +} + +static void +_isisc_egress_bs_frame_hw_to_sw(a_uint32_t hw_bs, a_uint32_t * sw_bs) +{ + a_uint32_t data[8] = { 0, 2, 4, 16, 64, 256, 512, 1024 }; + + *sw_bs = data[hw_bs & 0x7]; +} + +static void +_isisc_ingress_bs_byte_sw_to_hw(a_uint32_t sw_bs, a_uint32_t * hw_bs) +{ + a_int32_t i; + a_uint32_t data[8] = + { + 0, 4 * 1024, 32 * 1024, 128 * 1024, 512 * 1024, 2 * 1024 * 1024, + 8 * 1024 * 1024, 32 * 1024 * 1024 + }; + + for (i = 7; i >= 0; i--) + { + if (sw_bs >= data[i]) + { + *hw_bs = i; + break; + } + } +} + +static void +_isisc_ingress_bs_byte_hw_to_sw(a_uint32_t hw_bs, a_uint32_t * sw_bs) +{ + a_uint32_t data[8] = + { + 0, 4 * 1024, 32 * 1024, 128 * 1024, 512 * 1024, 2 * 1024 * 1024, + 8 * 1024 * 1024, 32 * 1024 * 1024 + }; + + *sw_bs = data[hw_bs & 0x7]; +} + +static void +_isisc_ingress_bs_frame_sw_to_hw(a_uint32_t sw_bs, a_uint32_t * hw_bs) +{ + a_uint32_t data[8] = { 0, 4, 16, 64, 256, 1024, 4096, 16384 }; + a_int32_t i; + + for (i = 7; i >= 0; i--) + { + if (sw_bs >= data[i]) + { + *hw_bs = i; + break; + } + } +} + +static void +_isisc_ingress_bs_frame_hw_to_sw(a_uint32_t hw_bs, a_uint32_t * sw_bs) +{ + a_uint32_t data[8] = { 0, 4, 16, 64, 256, 1024, 4096, 16384 }; + + *sw_bs = data[hw_bs & 0x7]; +} + +static void +_isisc_rate_flag_parse(a_uint32_t sw_flag, a_uint32_t * hw_flag) +{ + *hw_flag = 0; + + if (FAL_INGRESS_POLICING_TCP_CTRL & sw_flag) + { + *hw_flag |= (0x1 << 1); + } + + if (FAL_INGRESS_POLICING_MANAGEMENT & sw_flag) + { + *hw_flag |= (0x1 << 2); + } + + if (FAL_INGRESS_POLICING_BROAD & sw_flag) + { + *hw_flag |= (0x1 << 3); + } + + if (FAL_INGRESS_POLICING_UNK_UNI & sw_flag) + { + *hw_flag |= (0x1 << 4); + } + + if (FAL_INGRESS_POLICING_UNK_MUL & sw_flag) + { + *hw_flag |= (0x1 << 5); + } + + if (FAL_INGRESS_POLICING_UNI & sw_flag) + { + *hw_flag |= (0x1 << 6); + } + + if (FAL_INGRESS_POLICING_MUL & sw_flag) + { + *hw_flag |= (0x1 << 7); + } +} + +static void +_isisc_rate_flag_reparse(a_uint32_t hw_flag, a_uint32_t * sw_flag) +{ + *sw_flag = 0; + + if (hw_flag & 0x2) + { + *sw_flag |= FAL_INGRESS_POLICING_TCP_CTRL; + } + + if (hw_flag & 0x4) + { + *sw_flag |= FAL_INGRESS_POLICING_MANAGEMENT; + } + + if (hw_flag & 0x8) + { + *sw_flag |= FAL_INGRESS_POLICING_BROAD; + } + + if (hw_flag & 0x10) + { + *sw_flag |= FAL_INGRESS_POLICING_UNK_UNI; + } + + if (hw_flag & 0x20) + { + *sw_flag |= FAL_INGRESS_POLICING_UNK_MUL; + } + + if (hw_flag & 0x40) + { + *sw_flag |= FAL_INGRESS_POLICING_UNI; + } + + if (hw_flag & 0x80) + { + *sw_flag |= FAL_INGRESS_POLICING_MUL; + } +} + +static void +_isisc_rate_ts_parse(fal_rate_mt_t sw, a_uint32_t * hw) +{ + if (FAL_RATE_MI_100US == sw) + { + *hw = 0; + } + else if (FAL_RATE_MI_1MS == sw) + { + *hw = 1; + } + else if (FAL_RATE_MI_10MS == sw) + { + *hw = 2; + } + else if (FAL_RATE_MI_100MS) + { + *hw = 3; + } + else + { + *hw = 0; + } +} + +static void +_isisc_rate_ts_reparse(a_uint32_t hw, fal_rate_mt_t * sw) +{ + if (0 == hw) + { + *sw = FAL_RATE_MI_100US; + } + else if (1 == hw) + { + *sw = FAL_RATE_MI_1MS; + } + else if (2 == hw) + { + *sw = FAL_RATE_MI_10MS; + } + else + { + *sw = FAL_RATE_MI_100MS; + } +} + +static sw_error_t +_isisc_rate_port_policer_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_policer_t * policer) +{ + sw_error_t rv; + a_uint32_t cir = 0x7fff, eir = 0x7fff, cbs = 0, ebs = 0, tmp, data[3] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + data[0] = 0x18000000; + if (FAL_BYTE_BASED == policer->meter_unit) + { + if (A_TRUE == policer->c_enable) + { + cir = policer->cir >> 5; + policer->cir = cir << 5; + _isisc_ingress_bs_byte_sw_to_hw(policer->cbs, &cbs); + _isisc_ingress_bs_byte_hw_to_sw(cbs, &(policer->cbs)); + } + + if (A_TRUE == policer->e_enable) + { + eir = policer->eir >> 5; + policer->eir = eir << 5; + _isisc_ingress_bs_byte_sw_to_hw(policer->ebs, &ebs); + _isisc_ingress_bs_byte_hw_to_sw(ebs, &(policer->ebs)); + } + + SW_SET_REG_BY_FIELD(INGRESS_POLICER1, INGRESS_UNIT, 0, data[1]); + } + else if (FAL_FRAME_BASED == policer->meter_unit) + { + if (A_TRUE == policer->c_enable) + { + cir = (policer->cir * 2) / 125; + policer->cir = cir / 2 * 125 + cir % 2 * 63; + _isisc_ingress_bs_frame_sw_to_hw(policer->cbs, &cbs); + _isisc_ingress_bs_frame_hw_to_sw(cbs, &(policer->cbs)); + } + + if (A_TRUE == policer->e_enable) + { + eir = (policer->eir * 2) / 125; + policer->eir = eir / 2 * 125 + eir % 2 * 63; + _isisc_ingress_bs_frame_sw_to_hw(policer->ebs, &ebs); + _isisc_ingress_bs_frame_hw_to_sw(ebs, &(policer->ebs)); + } + + SW_SET_REG_BY_FIELD(INGRESS_POLICER1, INGRESS_UNIT, 1, data[1]); + } + else + { + return SW_BAD_PARAM; + } + + SW_SET_REG_BY_FIELD(INGRESS_POLICER0, INGRESS_CIR, cir, data[0]); + SW_SET_REG_BY_FIELD(INGRESS_POLICER0, INGRESS_CBS, cbs, data[0]); + SW_SET_REG_BY_FIELD(INGRESS_POLICER1, INGRESS_EIR, eir, data[1]); + SW_SET_REG_BY_FIELD(INGRESS_POLICER1, INGRESS_EBS, ebs, data[1]); + + if (A_TRUE == policer->combine_mode) + { + SW_SET_REG_BY_FIELD(INGRESS_POLICER0, RATE_MODE, 1, data[0]); + } + + if (A_TRUE == policer->deficit_en) + { + SW_SET_REG_BY_FIELD(INGRESS_POLICER1, INGRESS_BORROW, 1, data[1]); + } + + if (A_TRUE == policer->color_mode) + { + SW_SET_REG_BY_FIELD(INGRESS_POLICER1, INGRESS_CM, 1, data[1]); + } + + if (A_TRUE == policer->couple_flag) + { + SW_SET_REG_BY_FIELD(INGRESS_POLICER1, INGRESS_CF, 1, data[1]); + } + + _isisc_rate_ts_parse(policer->c_meter_interval, &tmp); + SW_SET_REG_BY_FIELD(INGRESS_POLICER0, C_ING_TS, tmp, data[0]); + + _isisc_rate_ts_parse(policer->e_meter_interval, &tmp); + SW_SET_REG_BY_FIELD(INGRESS_POLICER1, E_ING_TS, tmp, data[1]); + + _isisc_rate_flag_parse(policer->c_rate_flag, &tmp); + data[2] = (tmp << 8) & 0xff00; + + _isisc_rate_flag_parse(policer->e_rate_flag, &tmp); + data[2] |= (tmp & 0xff); + + HSL_REG_ENTRY_SET(rv, dev_id, INGRESS_POLICER0, port_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, INGRESS_POLICER1, port_id, + (a_uint8_t *) (&data[1]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, INGRESS_POLICER2, port_id, + (a_uint8_t *) (&data[2]), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_rate_port_policer_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_policer_t * policer) +{ + sw_error_t rv; + a_uint32_t unit, ts, cir, eir, cbs, ebs, data[3] = {0}; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, INGRESS_POLICER0, port_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, INGRESS_POLICER1, port_id, + (a_uint8_t *) (&data[1]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, INGRESS_POLICER2, port_id, + (a_uint8_t *) (&data[2]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(INGRESS_POLICER0, INGRESS_CIR, cir, data[0]); + SW_GET_FIELD_BY_REG(INGRESS_POLICER0, INGRESS_CBS, cbs, data[0]); + SW_GET_FIELD_BY_REG(INGRESS_POLICER1, INGRESS_EIR, eir, data[1]); + SW_GET_FIELD_BY_REG(INGRESS_POLICER1, INGRESS_EBS, ebs, data[1]); + SW_GET_FIELD_BY_REG(INGRESS_POLICER1, INGRESS_UNIT, unit, data[1]); + + policer->c_enable = A_TRUE; + if (0x7fff == cir) + { + policer->c_enable = A_FALSE; + cir = 0; + } + + policer->e_enable = A_TRUE; + if (0x7fff == eir) + { + policer->e_enable = A_FALSE; + eir = 0; + } + + if (unit) + { + policer->meter_unit = FAL_FRAME_BASED; + policer->cir = cir / 2 * 125 + cir % 2 * 63; + policer->eir = eir / 2 * 125 + eir % 2 * 63; + _isisc_ingress_bs_frame_hw_to_sw(cbs, &(policer->cbs)); + _isisc_ingress_bs_frame_hw_to_sw(ebs, &(policer->ebs)); + } + else + { + policer->meter_unit = FAL_BYTE_BASED; + policer->cir = cir << 5; + policer->eir = eir << 5; + _isisc_ingress_bs_byte_hw_to_sw(cbs, &(policer->cbs)); + _isisc_ingress_bs_byte_hw_to_sw(ebs, &(policer->ebs)); + } + + SW_GET_FIELD_BY_REG(INGRESS_POLICER0, RATE_MODE, policer->combine_mode, + data[0]); + SW_GET_FIELD_BY_REG(INGRESS_POLICER1, INGRESS_BORROW, policer->deficit_en, + data[1]); + SW_GET_FIELD_BY_REG(INGRESS_POLICER1, INGRESS_CF, policer->couple_flag, + data[1]); + SW_GET_FIELD_BY_REG(INGRESS_POLICER1, INGRESS_CM, policer->color_mode, + data[1]); + + ts = (data[2] >> 8) & 0xff; + _isisc_rate_flag_reparse(ts, &(policer->c_rate_flag)); + + ts = data[2] & 0xff; + _isisc_rate_flag_reparse(ts, &(policer->e_rate_flag)); + + SW_GET_FIELD_BY_REG(INGRESS_POLICER0, C_ING_TS, ts, data[0]); + _isisc_rate_ts_reparse(ts, &(policer->c_meter_interval)); + + SW_GET_FIELD_BY_REG(INGRESS_POLICER1, E_ING_TS, ts, data[1]); + _isisc_rate_ts_reparse(ts, &(policer->e_meter_interval)); + + return SW_OK; +} + +static sw_error_t +_isisc_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; + a_uint32_t data, cir, eir, cbs = 0, ebs = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_FALSE == enable) + { + aos_mem_zero(shaper, sizeof (fal_egress_shaper_t)); + + cir = 0x7fff; + eir = 0x7fff; + } + else + { + if (FAL_BYTE_BASED == shaper->meter_unit) + { + cir = shaper->cir >> 5; + shaper->cir = cir << 5; + + eir = shaper->eir >> 5; + shaper->eir = eir << 5; + + _isisc_egress_bs_byte_sw_to_hw(shaper->cbs, &cbs); + _isisc_egress_bs_byte_hw_to_sw(cbs, &(shaper->cbs)); + + _isisc_egress_bs_byte_sw_to_hw(shaper->ebs, &ebs); + _isisc_egress_bs_byte_hw_to_sw(ebs, &(shaper->ebs)); + + data = 0; + } + else if (FAL_FRAME_BASED == shaper->meter_unit) + { + cir = (shaper->cir * 2) / 125; + shaper->cir = cir / 2 * 125 + cir % 2 * 63; + + eir = (shaper->eir * 2) / 125; + shaper->eir = eir / 2 * 125 + eir % 2 * 63; + + _isisc_egress_bs_frame_sw_to_hw(shaper->cbs, &cbs); + _isisc_egress_bs_frame_hw_to_sw(cbs, &(shaper->cbs)); + + _isisc_egress_bs_frame_sw_to_hw(shaper->ebs, &ebs); + _isisc_egress_bs_frame_hw_to_sw(ebs, &(shaper->ebs)); + + data = 1; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q0_UNIT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data = 1; + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_PT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER0, port_id, EG_Q0_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER3, port_id, EG_Q0_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q0_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q0_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_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; + a_uint32_t data = 0, cir = 0, eir = 0, cbs = 0, ebs = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + aos_mem_zero(shaper, sizeof (fal_egress_shaper_t)); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_PT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (!data) + { + *enable = A_FALSE; + return SW_OK; + } + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER0, port_id, EG_Q0_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER3, port_id, EG_Q0_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q0_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q0_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if ((0x7fff == cir) && (0x7fff == eir)) + { + *enable = A_FALSE; + return SW_OK; + } + + *enable = A_TRUE; + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q0_UNIT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data) + { + shaper->meter_unit = FAL_FRAME_BASED; + shaper->cir = cir / 2 * 125 + cir % 2 * 63; + shaper->eir = eir / 2 * 125 + eir % 2 * 63; + _isisc_egress_bs_frame_hw_to_sw(cbs, &(shaper->cbs)); + _isisc_egress_bs_frame_hw_to_sw(ebs, &(shaper->ebs)); + } + else + { + shaper->meter_unit = FAL_BYTE_BASED; + shaper->cir = cir << 5; + shaper->eir = eir << 5; + _isisc_egress_bs_byte_hw_to_sw(cbs, &(shaper->cbs)); + _isisc_egress_bs_byte_hw_to_sw(ebs, &(shaper->ebs)); + } + + return SW_OK; +} + +static sw_error_t +_isisc_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; + a_uint32_t unit = 0, data, cir, eir, cbs = 0, ebs = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + rv = _isisc_rate_port_queue_check(port_id, queue_id); + SW_RTN_ON_ERROR(rv); + + if (A_FALSE == enable) + { + aos_mem_zero(shaper, sizeof (fal_egress_shaper_t)); + + cir = 0x7fff; + eir = 0x7fff; + } + else + { + if (FAL_BYTE_BASED == shaper->meter_unit) + { + cir = shaper->cir >> 5; + shaper->cir = cir << 5; + + eir = shaper->eir >> 5; + shaper->eir = eir << 5; + + _isisc_egress_bs_byte_sw_to_hw(shaper->cbs, &cbs); + _isisc_egress_bs_byte_hw_to_sw(cbs, &(shaper->cbs)); + + _isisc_egress_bs_byte_sw_to_hw(shaper->ebs, &ebs); + _isisc_egress_bs_byte_hw_to_sw(ebs, &(shaper->ebs)); + + unit = 0; + } + else if (FAL_FRAME_BASED == shaper->meter_unit) + { + cir = (shaper->cir * 2) / 125; + shaper->cir = cir / 2 * 125 + cir % 2 * 63; + + eir = (shaper->eir * 2) / 125; + shaper->eir = eir / 2 * 125 + eir % 2 * 63; + + _isisc_egress_bs_frame_sw_to_hw(shaper->cbs, &cbs); + _isisc_egress_bs_frame_hw_to_sw(cbs, &(shaper->cbs)); + + _isisc_egress_bs_frame_sw_to_hw(shaper->ebs, &ebs); + _isisc_egress_bs_frame_hw_to_sw(ebs, &(shaper->ebs)); + + unit = 1; + } + + data = 0; + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_PT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + if (0 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER0, port_id, EG_Q0_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER3, port_id, EG_Q0_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q0_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q0_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q0_UNIT, + (a_uint8_t *) (&unit), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else if (1 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER0, port_id, EG_Q1_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER3, port_id, EG_Q1_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q1_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q1_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q1_UNIT, + (a_uint8_t *) (&unit), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else if (2 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER1, port_id, EG_Q2_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER4, port_id, EG_Q2_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q2_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q2_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q2_UNIT, + (a_uint8_t *) (&unit), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else if (3 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER1, port_id, EG_Q3_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER4, port_id, EG_Q3_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q3_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER6, port_id, EG_Q3_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q3_UNIT, + (a_uint8_t *) (&unit), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else if (4 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER2, port_id, EG_Q4_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER5, port_id, EG_Q4_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q4_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q4_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q4_UNIT, + (a_uint8_t *) (&unit), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else + { + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER2, port_id, EG_Q5_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER5, port_id, EG_Q5_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q5_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q5_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, EG_SHAPER7, port_id, EG_Q5_UNIT, + (a_uint8_t *) (&unit), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +static sw_error_t +_isisc_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; + a_uint32_t data = 0, cir = 0, eir = 0, cbs = 0, ebs = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + rv = _isisc_rate_port_queue_check(port_id, queue_id); + SW_RTN_ON_ERROR(rv); + + aos_mem_zero(shaper, sizeof (fal_egress_shaper_t)); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_PT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data) + { + *enable = A_FALSE; + return SW_OK; + } + + if (0 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER0, port_id, EG_Q0_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER3, port_id, EG_Q0_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q0_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q0_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q0_UNIT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else if (1 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER0, port_id, EG_Q1_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER3, port_id, EG_Q1_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q1_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q1_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q1_UNIT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else if (2 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER1, port_id, EG_Q2_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER4, port_id, EG_Q2_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q2_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q2_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q2_UNIT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else if (3 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER1, port_id, EG_Q3_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER4, port_id, EG_Q3_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q3_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER6, port_id, EG_Q3_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q3_UNIT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else if (4 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER2, port_id, EG_Q4_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER5, port_id, EG_Q4_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q4_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q4_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q4_UNIT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else + { + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER2, port_id, EG_Q5_CIR, + (a_uint8_t *) (&cir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER5, port_id, EG_Q5_EIR, + (a_uint8_t *) (&eir), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q5_CBS, + (a_uint8_t *) (&cbs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q5_EBS, + (a_uint8_t *) (&ebs), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, EG_SHAPER7, port_id, EG_Q5_UNIT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + if ((0x7fff == cir) && (0x7fff == eir)) + { + *enable = A_FALSE; + return SW_OK; + } + + *enable = A_TRUE; + if (data) + { + shaper->meter_unit = FAL_FRAME_BASED; + shaper->cir = cir / 2 * 125 + cir % 2 * 63; + shaper->eir = eir / 2 * 125 + eir % 2 * 63; + _isisc_egress_bs_frame_hw_to_sw(cbs, &(shaper->cbs)); + _isisc_egress_bs_frame_hw_to_sw(ebs, &(shaper->ebs)); + } + else + { + shaper->meter_unit = FAL_BYTE_BASED; + shaper->cir = cir << 5; + shaper->eir = eir << 5; + _isisc_egress_bs_byte_hw_to_sw(cbs, &(shaper->cbs)); + _isisc_egress_bs_byte_hw_to_sw(ebs, &(shaper->ebs)); + } + + return SW_OK; +} + +static sw_error_t +_isisc_rate_acl_policer_set(a_uint32_t dev_id, a_uint32_t policer_id, + fal_acl_policer_t * policer) +{ + sw_error_t rv; + a_uint32_t ts, cir, eir, cbs = 0, ebs = 0, addr, data[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (ISISC_MAX_POLICER_ID < policer_id) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == policer->counter_mode) + { + addr = ACL_POLICER_CNT_SEL_ADDR; + data[0] = 0x1; + HSL_REG_FIELD_GEN_SET(rv, dev_id, addr, 1, policer_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + addr = ACL_POLICER_CNT_MODE_ADDR; + if (FAL_FRAME_BASED == policer->meter_unit) + { + data[0] = 0x0; + } + else + { + data[0] = 0x1; + } + HSL_REG_FIELD_GEN_SET(rv, dev_id, addr, 1, policer_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + addr = ACL_POLICER_CNT_RST_ADDR; + data[0] = 0x1; + HSL_REG_FIELD_GEN_SET(rv, dev_id, addr, 1, policer_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data[0] = 0x0; + HSL_REG_FIELD_GEN_SET(rv, dev_id, addr, 1, policer_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + return rv; + } + + addr = ACL_POLICER_CNT_SEL_ADDR; + data[0] = 0x0; + HSL_REG_FIELD_GEN_SET(rv, dev_id, addr, 1, policer_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_BYTE_BASED == policer->meter_unit) + { + cir = policer->cir >> 5; + policer->cir = cir << 5; + + eir = policer->eir >> 5; + policer->eir = eir << 5; + + _isisc_ingress_bs_byte_sw_to_hw(policer->cbs, &cbs); + _isisc_ingress_bs_byte_hw_to_sw(cbs, &(policer->cbs)); + + _isisc_ingress_bs_byte_sw_to_hw(policer->ebs, &ebs); + _isisc_ingress_bs_byte_hw_to_sw(ebs, &(policer->ebs)); + + SW_SET_REG_BY_FIELD(ACL_POLICER1, ACL_UNIT, 0, data[1]); + } + else if (FAL_FRAME_BASED == policer->meter_unit) + { + cir = (policer->cir * 2) / 125; + policer->cir = cir / 2 * 125 + cir % 2 * 63; + + eir = (policer->eir * 2) / 125; + policer->eir = eir / 2 * 125 + eir % 2 * 63; + + _isisc_ingress_bs_frame_sw_to_hw(policer->cbs, &cbs); + _isisc_ingress_bs_frame_hw_to_sw(cbs, &(policer->cbs)); + + _isisc_ingress_bs_frame_sw_to_hw(policer->ebs, &ebs); + _isisc_ingress_bs_frame_hw_to_sw(ebs, &(policer->ebs)); + + SW_SET_REG_BY_FIELD(ACL_POLICER1, ACL_UNIT, 1, data[1]); + } + else + { + return SW_BAD_PARAM; + } + + SW_SET_REG_BY_FIELD(ACL_POLICER0, ACL_CIR, cir, data[0]); + SW_SET_REG_BY_FIELD(ACL_POLICER0, ACL_CBS, cbs, data[0]); + SW_SET_REG_BY_FIELD(ACL_POLICER1, ACL_EIR, eir, data[1]); + SW_SET_REG_BY_FIELD(ACL_POLICER1, ACL_EBS, ebs, data[1]); + + if (A_TRUE == policer->deficit_en) + { + SW_SET_REG_BY_FIELD(ACL_POLICER1, ACL_BORROW, 1, data[1]); + } + + if (A_TRUE == policer->color_mode) + { + SW_SET_REG_BY_FIELD(ACL_POLICER1, ACL_CM, 1, data[1]); + } + + if (A_TRUE == policer->couple_flag) + { + SW_SET_REG_BY_FIELD(ACL_POLICER1, ACL_CF, 1, data[1]); + } + + _isisc_rate_ts_parse(policer->meter_interval, &ts); + SW_SET_REG_BY_FIELD(ACL_POLICER1, ACL_TS, ts, data[1]); + + HSL_REG_ENTRY_SET(rv, dev_id, ACL_POLICER0, policer_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ACL_POLICER1, policer_id, + (a_uint8_t *) (&data[1]), sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_isisc_rate_acl_policer_get(a_uint32_t dev_id, a_uint32_t policer_id, + fal_acl_policer_t * policer) +{ + sw_error_t rv; + a_uint32_t unit, ts, cir, eir, cbs, ebs, addr, data[2] = {0}; + + HSL_DEV_ID_CHECK(dev_id); + + if (ISISC_MAX_POLICER_ID < policer_id) + { + return SW_BAD_PARAM; + } + + aos_mem_zero(policer, sizeof (policer)); + + addr = ACL_POLICER_CNT_SEL_ADDR; + HSL_REG_FIELD_GEN_GET(rv, dev_id, addr, 1, policer_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data[0]) + { + policer->counter_mode = A_TRUE; + + addr = ACL_POLICER_CNT_MODE_ADDR; + HSL_REG_FIELD_GEN_GET(rv, dev_id, addr, 1, policer_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (data[0]) + { + policer->meter_unit = FAL_BYTE_BASED; + } + else + { + policer->meter_unit = FAL_FRAME_BASED; + } + + HSL_REG_ENTRY_GET(rv, dev_id, ACL_COUNTER0, policer_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ACL_COUNTER1, policer_id, + (a_uint8_t *) (&data[1]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + policer->counter_low = data[0]; + policer->counter_high = data[1]; + + return SW_OK; + } + + HSL_REG_ENTRY_GET(rv, dev_id, ACL_POLICER0, policer_id, + (a_uint8_t *) (&data[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ACL_POLICER1, policer_id, + (a_uint8_t *) (&data[1]), sizeof (a_uint32_t)); + + SW_GET_FIELD_BY_REG(ACL_POLICER0, ACL_CIR, cir, data[0]); + SW_GET_FIELD_BY_REG(ACL_POLICER0, ACL_CBS, cbs, data[0]); + SW_GET_FIELD_BY_REG(ACL_POLICER1, ACL_EIR, eir, data[1]); + SW_GET_FIELD_BY_REG(ACL_POLICER1, ACL_EBS, ebs, data[1]); + SW_GET_FIELD_BY_REG(ACL_POLICER1, ACL_UNIT, unit, data[1]); + if (unit) + { + policer->meter_unit = FAL_FRAME_BASED; + policer->cir = cir / 2 * 125 + cir % 2 * 63; + policer->eir = eir / 2 * 125 + eir % 2 * 63; + _isisc_ingress_bs_frame_hw_to_sw(cbs, &(policer->cbs)); + _isisc_ingress_bs_frame_hw_to_sw(ebs, &(policer->ebs)); + + } + else + { + policer->meter_unit = FAL_BYTE_BASED; + policer->cir = cir << 5; + policer->eir = eir << 5; + _isisc_ingress_bs_byte_hw_to_sw(cbs, &(policer->cbs)); + _isisc_ingress_bs_byte_hw_to_sw(ebs, &(policer->ebs)); + } + + SW_GET_FIELD_BY_REG(ACL_POLICER1, ACL_BORROW, policer->deficit_en, + data[1]); + SW_GET_FIELD_BY_REG(ACL_POLICER1, ACL_CF, policer->couple_flag, data[1]); + SW_GET_FIELD_BY_REG(ACL_POLICER1, ACL_CM, policer->color_mode, data[1]); + + SW_GET_FIELD_BY_REG(ACL_POLICER1, ACL_TS, ts, data[1]); + _isisc_rate_ts_reparse(ts, &(policer->meter_interval)); + + return SW_OK; +} + +sw_error_t +_isisc_rate_port_add_rate_byte_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t number) +{ + a_uint32_t val = number; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (val>255) + return SW_BAD_PARAM; + + HSL_REG_FIELD_SET(rv, dev_id, INGRESS_POLICER0, port_id, ADD_RATE_BYTE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + return rv; +} + +sw_error_t +_isisc_rate_port_add_rate_byte_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t *number) +{ + a_uint32_t val = 0; + sw_error_t rv = SW_OK; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + + HSL_REG_FIELD_GET(rv, dev_id, INGRESS_POLICER0, port_id, ADD_RATE_BYTE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + *number = val; + + return rv; +} + +sw_error_t +_isisc_rate_port_gol_flow_en_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t val = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, QM_CTRL_REG, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + + if (A_TRUE == enable) + { + val |= (0x1<<(16+port_id)); + } + else if (A_FALSE == enable) + { + val &= ~(0x1<<(16+port_id)); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_SET(rv, dev_id, QM_CTRL_REG, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + return rv; +} + +sw_error_t +_isisc_rate_port_gol_flow_en_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t* enable) +{ + a_uint32_t val = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, QM_CTRL_REG, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (val&(0x1<<(16+port_id))) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return rv; +} + + + +/** + * @brief Set port ingress policer parameters on one particular port. + * @details Comments: + The granularity of speed is 32kbps or 62.5fps. + Because of hardware granularity function will return actual speed in hardware. + When disable port ingress policer input parameter speed is meaningless. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] policer port ingress policer parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_rate_port_policer_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_policer_t * policer) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_rate_port_policer_set(dev_id, port_id, policer); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get port ingress policer parameters on one particular port. + * @details Comments: + The granularity of speed is 32kbps or 62.5fps. + Because of hardware granularity function will return actual speed in hardware. + When disable port ingress policer input parameter speed is meaningless. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] policer port ingress policer parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_rate_port_policer_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_policer_t * policer) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_rate_port_policer_get(dev_id, port_id, policer); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set port egress shaper parameters on one particular port. + * @details Comments: + The granularity of speed is 32kbps or 62.5fps. + Because of hardware granularity function will return actual speed in hardware. + When disable port egress shaper parameters is meaningless. + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] shaper port egress shaper parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_rate_port_shaper_set(dev_id, port_id, enable, shaper); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get port egress shaper parameters on one particular port. + * @details Comments: + The granularity of speed is 32kbps or 62.5fps. + Because of hardware granularity function will return actual speed in hardware. + When disable port egress shaper parameters is meaningless. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @param[out] shaper port egress shaper parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_rate_port_shaper_get(dev_id, port_id, enable, shaper); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set queue egress shaper parameters on one particular port. + * @details Comments: + The granularity of speed is 32kbps or 62.5fps. + Because of hardware granularity function will return actual speed in hardware. + When disable queue egress shaper parameters is meaningless. + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] shaper port egress shaper parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_rate_queue_shaper_set(dev_id, port_id, queue_id, enable, shaper); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get queue egress shaper parameters on one particular port. + * @details Comments: + The granularity of speed is 32kbps or 62.5fps. + Because of hardware granularity function will return actual speed in hardware. + When disable queue egress shaper parameters is meaningless. + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param[out] enable A_TRUE or A_FALSE + * @param[out] shaper port egress shaper parameter + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_rate_queue_shaper_get(dev_id, port_id, queue_id, enable, shaper); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set ACL ingress policer parameters. + * @details Comments: + The granularity of speed is 32kbps or 62.5fps. + Because of hardware granularity function will return actual speed in hardware. + * @param[in] dev_id device id + * @param[in] policer_id ACL policer id + * @param[in] policer ACL ingress policer parameters + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_rate_acl_policer_set(a_uint32_t dev_id, a_uint32_t policer_id, + fal_acl_policer_t * policer) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_rate_acl_policer_set(dev_id, policer_id, policer); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get ACL ingress policer parameters. + * @details Comments: + The granularity of speed is 32kbps or 62.5fps. + Because of hardware granularity function will return actual speed in hardware. + * @param[in] dev_id device id + * @param[in] policer_id ACL policer id + * @param[in] policer ACL ingress policer parameters + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_rate_acl_policer_get(a_uint32_t dev_id, a_uint32_t policer_id, + fal_acl_policer_t * policer) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_rate_acl_policer_get(dev_id, policer_id, policer); + HSL_API_UNLOCK; + return rv; +} + +HSL_LOCAL sw_error_t +isisc_rate_port_add_rate_byte_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t number) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_rate_port_add_rate_byte_set(dev_id, port_id, number); + HSL_API_UNLOCK; + return rv; +} + +HSL_LOCAL sw_error_t +isisc_rate_port_add_rate_byte_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t *number) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_rate_port_add_rate_byte_get(dev_id, port_id, number); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of port global flow control when global threshold is reached. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_rate_port_gol_flow_en_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_rate_port_gol_flow_en_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief get status of port global flow control when global threshold is reached. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_rate_port_gol_flow_en_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t* enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_rate_port_gol_flow_en_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + + + +sw_error_t +isisc_rate_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->rate_port_policer_set = isisc_rate_port_policer_set; + p_api->rate_port_policer_get = isisc_rate_port_policer_get; + p_api->rate_port_shaper_set = isisc_rate_port_shaper_set; + p_api->rate_port_shaper_get = isisc_rate_port_shaper_get; + p_api->rate_queue_shaper_set = isisc_rate_queue_shaper_set; + p_api->rate_queue_shaper_get = isisc_rate_queue_shaper_get; + p_api->rate_acl_policer_set = isisc_rate_acl_policer_set; + p_api->rate_acl_policer_get = isisc_rate_acl_policer_get; + p_api->rate_port_gol_flow_en_set = isisc_rate_port_gol_flow_en_set; + p_api->rate_port_gol_flow_en_get = isisc_rate_port_gol_flow_en_get; + p_api->rate_port_add_rate_byte_set=isisc_rate_port_add_rate_byte_set; + p_api->rate_port_add_rate_byte_get=isisc_rate_port_add_rate_byte_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_reg_access.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_reg_access.c new file mode 100755 index 000000000..8b90afc51 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_reg_access.c @@ -0,0 +1,459 @@ +/* + * Copyright (c) 2012, 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. + */ + + +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "sd.h" +#include "isisc_reg_access.h" + +#if 0 +#include +#include +#include +#include +#include +#endif + +static hsl_access_mode reg_mode; + +#if defined(API_LOCK) +static aos_lock_t mdio_lock; +#define MDIO_LOCKER_INIT aos_lock_init(&mdio_lock) +#define MDIO_LOCKER_LOCK aos_lock(&mdio_lock) +#define MDIO_LOCKER_UNLOCK aos_unlock(&mdio_lock) +#else +#define MDIO_LOCKER_INIT +#define MDIO_LOCKER_LOCK +#define MDIO_LOCKER_UNLOCK +#endif + +#if defined(REG_ACCESS_SPEEDUP) +static a_uint32_t mdio_base_addr = 0xffffffff; +#endif + +static sw_error_t +_isisc_mdio_reg_get(a_uint32_t dev_id, a_uint32_t reg_addr, + a_uint8_t value[], a_uint32_t value_len) +{ + a_uint32_t reg_val; + + if (value_len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + +#if 0 + /* change reg_addr to 16-bit word address, 32-bit aligned */ + reg_word_addr = (reg_addr & 0xfffffffc) >> 1; + + /* configure register high address */ + phy_addr = 0x18; + phy_reg = 0x0; + phy_val = (a_uint16_t) ((reg_word_addr >> 8) & 0x3ff); /* bit16-8 of reg address */ + +#if defined(REG_ACCESS_SPEEDUP) + if (phy_val != mdio_base_addr) + { + rv = sd_reg_mdio_set(dev_id, phy_addr, phy_reg, phy_val); + SW_RTN_ON_ERROR(rv); + + mdio_base_addr = phy_val; + } +#else + rv = sd_reg_mdio_set(dev_id, phy_addr, phy_reg, phy_val); + SW_RTN_ON_ERROR(rv); +#endif + + /* For some registers such as MIBs, since it is read/clear, we should */ + /* read the lower 16-bit register then the higher one */ + + /* read register in lower address */ + phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */ + phy_reg = (a_uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */ + rv = sd_reg_mdio_get(dev_id, phy_addr, phy_reg, &tmp_val); + SW_RTN_ON_ERROR(rv); + reg_val = tmp_val; + + /* read register in higher address */ + reg_word_addr++; + phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */ + phy_reg = (a_uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */ + rv = sd_reg_mdio_get(dev_id, phy_addr, phy_reg, &tmp_val); + SW_RTN_ON_ERROR(rv); + reg_val |= (((a_uint32_t)tmp_val) << 16); +#else + reg_val = sd_reg_mii_get(dev_id, reg_addr); +#endif + aos_mem_copy(value, ®_val, sizeof (a_uint32_t)); + + return SW_OK; +} + +static sw_error_t +_isisc_mdio_reg_set(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t value[], + a_uint32_t value_len) +{ + a_uint32_t reg_val = 0; + + if (value_len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + + aos_mem_copy(®_val, value, sizeof (a_uint32_t)); + +#if 0 + /* change reg_addr to 16-bit word address, 32-bit aligned */ + reg_word_addr = (reg_addr & 0xfffffffc) >> 1; + + /* configure register high address */ + phy_addr = 0x18; + phy_reg = 0x0; + phy_val = (a_uint16_t) ((reg_word_addr >> 8) & 0x3ff); /* bit16-8 of reg address */ + +#if defined(REG_ACCESS_SPEEDUP) + if (phy_val != mdio_base_addr) + { + rv = sd_reg_mdio_set(dev_id, phy_addr, phy_reg, phy_val); + SW_RTN_ON_ERROR(rv); + + mdio_base_addr = phy_val; + } +#else + rv = sd_reg_mdio_set(dev_id, phy_addr, phy_reg, phy_val); + SW_RTN_ON_ERROR(rv); +#endif + + /* For some registers such as ARL and VLAN, since they include BUSY bit */ + /* in higher address, we should write the lower 16-bit register then the */ + /* higher one */ + + /* write register in lower address */ + phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */ + phy_reg = (a_uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */ + phy_val = (a_uint16_t) (reg_val & 0xffff); + rv = sd_reg_mdio_set(dev_id, phy_addr, phy_reg, phy_val); + SW_RTN_ON_ERROR(rv); + + /* write register in higher address */ + reg_word_addr++; + phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */ + phy_reg = (a_uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */ + phy_val = (a_uint16_t) ((reg_val >> 16) & 0xffff); + rv = sd_reg_mdio_set(dev_id, phy_addr, phy_reg, phy_val); + SW_RTN_ON_ERROR(rv); +#else + sd_reg_mii_set(dev_id, reg_addr, reg_val); +#endif + return SW_OK; +} + +sw_error_t +isisc_phy_get(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t * value) +{ + sw_error_t rv; + + MDIO_LOCKER_LOCK; + rv = sd_reg_mdio_get(dev_id, phy_addr, reg, value); + MDIO_LOCKER_UNLOCK; + return rv; +} + +sw_error_t +isisc_phy_set(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t value) +{ + sw_error_t rv; + + MDIO_LOCKER_LOCK; + rv = sd_reg_mdio_set(dev_id, phy_addr, reg, value); + MDIO_LOCKER_UNLOCK; + return rv; +} + +sw_error_t +isisc_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; + + MDIO_LOCKER_LOCK; + if (HSL_MDIO == reg_mode) + { + rv = _isisc_mdio_reg_get(dev_id, reg_addr, value, value_len); + } + else + { + rv = sd_reg_hdr_get(dev_id, reg_addr, value, value_len); + } + MDIO_LOCKER_UNLOCK; + + return rv; +} + +sw_error_t +isisc_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; +#if 0 + unsigned long flags; + + struct file *filp; + // mm_segment_t fs; + a_uint32_t rt_value = 0; + a_uint32_t write_flag = 0; + char s[20]= {0}; + a_uint32_t tmp_val = *((a_uint32_t *) value); + + /*get MODULE_EN reg rsv */ + SW_RTN_ON_ERROR(isisc_reg_get(dev_id, 0x30,(void *)&rt_value,4)); + write_flag = (rt_value>>15) & 0x1; +#endif + MDIO_LOCKER_LOCK; + if (HSL_MDIO == reg_mode) + { + rv = _isisc_mdio_reg_set(dev_id, reg_addr, value, value_len); + } + else + { + rv = sd_reg_hdr_set(dev_id, reg_addr, value, value_len); + } + MDIO_LOCKER_UNLOCK; + +#if 0 + if(write_flag) + { + filp = filp_open("/tmp/asic_output", O_RDWR|O_APPEND, 0644); + if(IS_ERR(filp)) + { + printk("open error...\n"); + return; + } + + fs=get_fs(); + + set_fs(KERNEL_DS); + sprintf(s,"%08x %08x\n",reg_addr,tmp_val); + filp->f_op->write(filp, s, strlen(s),&filp->f_pos); + + set_fs(fs); + + filp_close(filp,NULL); + } +#endif + + return rv; +} + +sw_error_t +isisc_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) +{ + a_uint32_t reg_val = 0; + + if ((bit_offset >= 32 || (field_len > 32)) || (field_len == 0)) + return SW_OUT_OF_RANGE; + + if (value_len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + + SW_RTN_ON_ERROR(isisc_reg_get(dev_id, reg_addr, (a_uint8_t *) & reg_val, sizeof (a_uint32_t))); + + + if(32 == field_len) + { + *((a_uint32_t *) value) = reg_val; + } + else + { + *((a_uint32_t *) value) = SW_REG_2_FIELD(reg_val, bit_offset, field_len); + } + return SW_OK; +} + +sw_error_t +isisc_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) +{ + a_uint32_t reg_val = 0; + a_uint32_t field_val = *((a_uint32_t *) value); + + if ((bit_offset >= 32 || (field_len > 32)) || (field_len == 0)) + return SW_OUT_OF_RANGE; + + if (value_len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + + SW_RTN_ON_ERROR(isisc_reg_get(dev_id, reg_addr, (a_uint8_t *) & reg_val, sizeof (a_uint32_t))); + + if(32 == field_len) + { + reg_val = field_val; + } + else + { + SW_REG_SET_BY_FIELD_U32(reg_val, field_val, bit_offset, field_len); + } + + + SW_RTN_ON_ERROR(isisc_reg_set(dev_id, reg_addr, (a_uint8_t *) & reg_val, sizeof (a_uint32_t))); + + return SW_OK; +} + + +static sw_error_t +_isisc_regsiter_dump(a_uint32_t dev_id,a_uint32_t register_idx, fal_reg_dump_t * reg_dump) +{ + sw_error_t rv = SW_OK; + typedef struct { + a_uint32_t reg_base; + a_uint32_t reg_end; + char name[30]; + } regdump; + + regdump reg_dumps[8] = + { + {0x0, 0xE4, "0.Global control registers"}, + {0x100, 0x168, "1.EEE control registers"}, + {0x200, 0x270, "2.Parser control registers"}, + {0x400, 0x474, "3.ACL control registers"}, + {0x600, 0x718, "4.Lookup control registers"}, + {0x800, 0xb70, "5.QM control registers"}, + {0xc00, 0xc80, "6.PKT edit control registers"}, + {0x820, 0x820, "7.QM debug registers"} + }; + + a_uint32_t dump_addr, reg_count, reg_val = 0; + switch (register_idx) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + reg_count = 0; + for (dump_addr = reg_dumps[register_idx].reg_base; dump_addr <= reg_dumps[register_idx].reg_end; reg_count++) + { + rv = isisc_reg_get(dev_id, dump_addr, (a_uint8_t *) & reg_val, sizeof (a_uint32_t)); + reg_dump->reg_value[reg_count] = reg_val; + dump_addr += 4; + } + reg_dump->reg_count = reg_count; + reg_dump->reg_base = reg_dumps[register_idx].reg_base; + reg_dump->reg_end = reg_dumps[register_idx].reg_end; + snprintf((char *)reg_dump->reg_name,sizeof(reg_dump->reg_name),"%s",reg_dumps[register_idx].name); + break; + default: + return SW_BAD_PARAM; + } + + return rv; +} + +static sw_error_t +_isisc_debug_regsiter_dump(a_uint32_t dev_id,fal_debug_reg_dump_t * dbg_reg_dump) +{ + sw_error_t rv = SW_OK; + a_uint32_t reg; + a_uint32_t reg_count, reg_val = 0; + + reg_count = 0; + + for(reg=0;reg<=0x1F;reg++) + { + isisc_reg_set(dev_id, 0x820, (a_uint8_t *) & reg, sizeof (a_uint32_t)); + rv = isisc_reg_get(dev_id, 0x824, (a_uint8_t *) & reg_val, sizeof (a_uint32_t)); + dbg_reg_dump->reg_value[reg_count] = reg_val; + dbg_reg_dump->reg_addr[reg_count] = reg; + reg_count++; + } + dbg_reg_dump->reg_count = reg_count; + + snprintf((char *)dbg_reg_dump->reg_name,sizeof(dbg_reg_dump->reg_name),"QM debug registers"); + + return rv; +} + + +/** + * @brief dump registers. + * @param[in] dev_id device id + * @param[in] register_idx register group id + * @param[out] reg_dump register dump result + * @return SW_OK or error code + */ +sw_error_t +isisc_regsiter_dump(a_uint32_t dev_id,a_uint32_t register_idx, fal_reg_dump_t * reg_dump) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _isisc_regsiter_dump(dev_id,register_idx,reg_dump); + FAL_API_UNLOCK; + return rv; +} + +/** + * @brief dump registers. + * @param[in] dev_id device id + * @param[out] reg_dump debug register dump + * @return SW_OK or error code + */ +sw_error_t +isisc_debug_regsiter_dump(a_uint32_t dev_id, fal_debug_reg_dump_t * dbg_reg_dump) +{ + sw_error_t rv = SW_OK; + + FAL_API_LOCK; + rv = _isisc_debug_regsiter_dump(dev_id,dbg_reg_dump); + FAL_API_UNLOCK; + return rv; +} + + + +sw_error_t +isisc_reg_access_init(a_uint32_t dev_id, hsl_access_mode mode) +{ + hsl_api_t *p_api; + + MDIO_LOCKER_INIT; + reg_mode = mode; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->phy_get = isisc_phy_get; + p_api->phy_set = isisc_phy_set; + p_api->reg_get = isisc_reg_get; + p_api->reg_set = isisc_reg_set; + p_api->reg_field_get = isisc_reg_field_get; + p_api->reg_field_set = isisc_reg_field_set; + p_api->register_dump = isisc_regsiter_dump; + p_api->debug_register_dump = isisc_debug_regsiter_dump; + + return SW_OK; +} + +sw_error_t +isisc_access_mode_set(a_uint32_t dev_id, hsl_access_mode mode) +{ + reg_mode = mode; + return SW_OK; + +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_sec.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_sec.c new file mode 100755 index 000000000..579868f77 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_sec.c @@ -0,0 +1,787 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup isisc_sec ISISC_SEC + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isisc_sec.h" +#include "isisc_reg.h" + +#define NORM_CTRL0_ADDR 0x0200 +#define NORM_CTRL1_ADDR 0x0204 +#define NORM_CTRL2_ADDR 0x0208 +#define NORM_CTRL3_ADDR 0x0c00 + +static sw_error_t +_isisc_sec_norm_item_set(a_uint32_t dev_id, fal_norm_item_t item, void *value) +{ + sw_error_t rv; + fal_fwd_cmd_t cmd; + a_bool_t enable; + a_uint32_t addr, offset, len, reg = 0, val; + + HSL_DEV_ID_CHECK(dev_id); + + cmd = *((fal_fwd_cmd_t *) value); + enable = *((a_bool_t *) value); + val = *((a_uint32_t *) value); + + len = 1; + switch (item) + { + case FAL_NORM_MAC_RESV_VID_CMD: + addr = NORM_CTRL0_ADDR; + offset = 0; + goto cmd_chk; + + case FAL_NORM_MAC_INVALID_SRC_ADDR_CMD: + addr = NORM_CTRL1_ADDR; + offset = 20; + goto cmd_chk; + + case FAL_NORM_IP_INVALID_VER_CMD: + addr = NORM_CTRL0_ADDR; + offset = 1; + goto cmd_chk; + + case FAL_NROM_IP_SAME_ADDR_CMD: + addr = NORM_CTRL0_ADDR; + offset = 2; + goto cmd_chk; + break; + + case FAL_NROM_IP_TTL_CHANGE_STATUS: + addr = NORM_CTRL3_ADDR; + offset = 11; + goto sts_chk; + + case FAL_NROM_IP_TTL_VALUE: + addr = NORM_CTRL3_ADDR; + offset = 12; + len = 8; + goto set_reg; + + case FAL_NROM_IP4_INVALID_HL_CMD: + addr = NORM_CTRL0_ADDR; + offset = 3; + goto cmd_chk; + + case FAL_NROM_IP4_HDR_OPTIONS_CMD: + addr = NORM_CTRL0_ADDR; + offset = 4; + len = 2; + goto s_cmd_chk; + + case FAL_NROM_IP4_INVALID_DF_CMD: + addr = NORM_CTRL0_ADDR; + offset = 7; + goto cmd_chk; + + case FAL_NROM_IP4_FRAG_OFFSET_MIN_LEN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 8; + goto cmd_chk; + + case FAL_NROM_IP4_FRAG_OFFSET_MIN_SIZE: + addr = NORM_CTRL1_ADDR; + offset = 24; + len = 8; + goto set_reg; + + case FAL_NROM_IP4_FRAG_OFFSET_MAX_LEN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 9; + goto cmd_chk; + + case FAL_NROM_IP4_INVALID_FRAG_OFFSET_CMD: + addr = NORM_CTRL0_ADDR; + offset = 10; + goto cmd_chk; + + case FAL_NROM_IP4_INVALID_SIP_CMD: + addr = NORM_CTRL0_ADDR; + offset = 11; + len = 1; + goto cmd_chk; + + case FAL_NROM_IP4_INVALID_DIP_CMD: + addr = NORM_CTRL0_ADDR; + offset = 12; + goto cmd_chk; + + case FAL_NROM_IP4_INVALID_CHKSUM_CMD: + addr = NORM_CTRL0_ADDR; + offset = 13; + goto cmd_chk; + + case FAL_NROM_IP4_INVALID_PL_CMD: + addr = NORM_CTRL1_ADDR; + offset = 19; + goto cmd_chk; + + case FAL_NROM_IP4_DF_CLEAR_STATUS: + addr = NORM_CTRL3_ADDR; + offset = 9; + goto sts_chk; + + case FAL_NROM_IP4_IPID_RANDOM_STATUS: + addr = NORM_CTRL3_ADDR; + offset = 10; + goto sts_chk; + + case FAL_NROM_IP6_INVALID_DIP_CMD: + addr = NORM_CTRL1_ADDR; + offset = 16; + goto cmd_chk; + + case FAL_NROM_IP6_INVALID_SIP_CMD: + addr = NORM_CTRL1_ADDR; + offset = 17; + goto cmd_chk; + + case FAL_NROM_IP6_INVALID_PL_CMD: + addr = NORM_CTRL1_ADDR; + offset = 18; + goto cmd_chk; + + case FAL_NROM_TCP_BLAT_CMD: + addr = NORM_CTRL0_ADDR; + offset = 14; + goto cmd_chk; + + case FAL_NROM_TCP_INVALID_HL_CMD: + addr = NORM_CTRL0_ADDR; + offset = 15; + goto cmd_chk; + + case FAL_NROM_TCP_MIN_HDR_SIZE: + addr = NORM_CTRL1_ADDR; + offset = 12; + len = 4; + goto set_reg; + + case FAL_NROM_TCP_INVALID_SYN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 16; + goto cmd_chk; + break; + + case FAL_NROM_TCP_SU_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 17; + goto cmd_chk; + + case FAL_NROM_TCP_SP_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 18; + goto cmd_chk; + + case FAL_NROM_TCP_SAP_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 19; + goto cmd_chk; + + case FAL_NROM_TCP_XMAS_SCAN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 20; + goto cmd_chk; + + case FAL_NROM_TCP_NULL_SCAN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 21; + goto cmd_chk; + + case FAL_NROM_TCP_SR_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 22; + goto cmd_chk; + + case FAL_NROM_TCP_SF_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 23; + goto cmd_chk; + + case FAL_NROM_TCP_SAR_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 24; + goto cmd_chk; + + case FAL_NROM_TCP_RST_SCAN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 25; + goto cmd_chk; + + case FAL_NROM_TCP_SYN_WITH_DATA_CMD: + addr = NORM_CTRL0_ADDR; + offset = 26; + goto cmd_chk; + + case FAL_NROM_TCP_RST_WITH_DATA_CMD: + addr = NORM_CTRL0_ADDR; + offset = 27; + goto cmd_chk; + + case FAL_NROM_TCP_FA_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 28; + goto cmd_chk; + + case FAL_NROM_TCP_PA_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 29; + goto cmd_chk; + + case FAL_NROM_TCP_UA_BLOCK_CMD: + addr = NORM_CTRL1_ADDR; + offset = 0; + goto cmd_chk; + + case FAL_NROM_TCP_INVALID_CHKSUM_CMD: + addr = NORM_CTRL1_ADDR; + offset = 1; + goto cmd_chk; + + case FAL_NROM_TCP_INVALID_URGPTR_CMD: + addr = NORM_CTRL1_ADDR; + offset = 2; + goto cmd_chk; + + case FAL_NROM_TCP_INVALID_OPTIONS_CMD: + addr = NORM_CTRL1_ADDR; + offset = 3; + goto cmd_chk; + + case FAL_NROM_UDP_BLAT_CMD: + addr = NORM_CTRL1_ADDR; + offset = 4; + goto cmd_chk; + + case FAL_NROM_UDP_INVALID_LEN_CMD: + addr = NORM_CTRL1_ADDR; + offset = 5; + goto cmd_chk; + + case FAL_NROM_UDP_INVALID_CHKSUM_CMD: + addr = NORM_CTRL1_ADDR; + offset = 6; + goto cmd_chk; + + case FAL_NROM_ICMP4_PING_PL_EXCEED_CMD: + addr = NORM_CTRL1_ADDR; + offset = 7; + goto cmd_chk; + + case FAL_NROM_ICMP6_PING_PL_EXCEED_CMD: + addr = NORM_CTRL1_ADDR; + offset = 8; + goto cmd_chk; + + case FAL_NROM_ICMP4_PING_FRAG_CMD: + addr = NORM_CTRL1_ADDR; + offset = 9; + goto cmd_chk; + + case FAL_NROM_ICMP6_PING_FRAG_CMD: + addr = NORM_CTRL1_ADDR; + offset = 10; + goto cmd_chk; + + case FAL_NROM_ICMP4_PING_MAX_PL_VALUE: + addr = NORM_CTRL2_ADDR; + offset = 0; + len = 14; + goto set_reg; + + case FAL_NROM_ICMP6_PING_MAX_PL_VALUE: + addr = NORM_CTRL2_ADDR; + offset = 16; + len = 14; + goto set_reg; + + default: + return SW_BAD_PARAM; + } + +sts_chk: + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + goto set_reg; + +s_cmd_chk: + if (FAL_MAC_FRWRD == cmd) + { + val = 0; + } + else if (FAL_MAC_DROP == cmd) + { + val = 3; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + val = 2; + } + else + { + return SW_BAD_PARAM; + } + goto set_reg; + +cmd_chk: + if (FAL_MAC_FRWRD == cmd) + { + val = 0; + } + else if (FAL_MAC_DROP == cmd) + { + val = 1; + } + else + { + return SW_BAD_PARAM; + } + +set_reg: + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_REG_SET_BY_FIELD_U32(reg, val, offset, len); + + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_sec_norm_item_get(a_uint32_t dev_id, fal_norm_item_t item, void *value) +{ + sw_error_t rv; + a_uint32_t addr, offset, len, reg = 0, val; + a_uint32_t status_chk = 0, val_chk = 0, scmd_chk = 0; + + HSL_DEV_ID_CHECK(dev_id); + + len = 1; + switch (item) + { + case FAL_NORM_MAC_RESV_VID_CMD: + addr = NORM_CTRL0_ADDR; + offset = 0; + break; + + case FAL_NORM_MAC_INVALID_SRC_ADDR_CMD: + addr = NORM_CTRL1_ADDR; + offset = 20; + break; + + case FAL_NORM_IP_INVALID_VER_CMD: + addr = NORM_CTRL0_ADDR; + offset = 1; + break; + + case FAL_NROM_IP_SAME_ADDR_CMD: + addr = NORM_CTRL0_ADDR; + offset = 2; + break; + + case FAL_NROM_IP_TTL_CHANGE_STATUS: + addr = NORM_CTRL3_ADDR; + offset = 11; + status_chk = 1; + break; + + case FAL_NROM_IP_TTL_VALUE: + addr = NORM_CTRL3_ADDR; + offset = 12; + len = 8; + val_chk = 1; + break; + + case FAL_NROM_IP4_INVALID_HL_CMD: + addr = NORM_CTRL0_ADDR; + offset = 3; + break; + + case FAL_NROM_IP4_HDR_OPTIONS_CMD: + addr = NORM_CTRL0_ADDR; + offset = 4; + len = 2; + scmd_chk = 1; + break; + + case FAL_NROM_IP4_INVALID_DF_CMD: + addr = NORM_CTRL0_ADDR; + offset = 7; + break; + + case FAL_NROM_IP4_FRAG_OFFSET_MIN_LEN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 8; + break; + + case FAL_NROM_IP4_FRAG_OFFSET_MIN_SIZE: + addr = NORM_CTRL1_ADDR; + offset = 24; + len = 8; + val_chk = 1; + break; + + case FAL_NROM_IP4_FRAG_OFFSET_MAX_LEN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 9; + break; + + case FAL_NROM_IP4_INVALID_FRAG_OFFSET_CMD: + addr = NORM_CTRL0_ADDR; + offset = 10; + break; + + case FAL_NROM_IP4_INVALID_SIP_CMD: + addr = NORM_CTRL0_ADDR; + offset = 11; + len = 1; + break; + + case FAL_NROM_IP4_INVALID_DIP_CMD: + addr = NORM_CTRL0_ADDR; + offset = 12; + break; + + case FAL_NROM_IP4_INVALID_CHKSUM_CMD: + addr = NORM_CTRL0_ADDR; + offset = 13; + break; + + case FAL_NROM_IP4_INVALID_PL_CMD: + addr = NORM_CTRL1_ADDR; + offset = 19; + break; + + case FAL_NROM_IP4_DF_CLEAR_STATUS: + addr = NORM_CTRL3_ADDR; + offset = 9; + status_chk = 1; + break; + + case FAL_NROM_IP4_IPID_RANDOM_STATUS: + addr = NORM_CTRL3_ADDR; + offset = 10; + status_chk = 1; + break; + + case FAL_NROM_IP6_INVALID_DIP_CMD: + addr = NORM_CTRL1_ADDR; + offset = 16; + break; + + case FAL_NROM_IP6_INVALID_SIP_CMD: + addr = NORM_CTRL1_ADDR; + offset = 17; + break; + + case FAL_NROM_IP6_INVALID_PL_CMD: + addr = NORM_CTRL1_ADDR; + offset = 18; + break; + + case FAL_NROM_TCP_BLAT_CMD: + addr = NORM_CTRL0_ADDR; + offset = 14; + break; + + case FAL_NROM_TCP_INVALID_HL_CMD: + addr = NORM_CTRL0_ADDR; + offset = 15; + break; + + case FAL_NROM_TCP_MIN_HDR_SIZE: + addr = NORM_CTRL1_ADDR; + offset = 12; + len = 4; + val_chk = 1; + break; + + case FAL_NROM_TCP_INVALID_SYN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 16; + break; + + case FAL_NROM_TCP_SU_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 17; + break; + + case FAL_NROM_TCP_SP_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 18; + break; + + case FAL_NROM_TCP_SAP_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 19; + break; + + case FAL_NROM_TCP_XMAS_SCAN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 20; + break; + + case FAL_NROM_TCP_NULL_SCAN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 21; + break; + + case FAL_NROM_TCP_SR_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 22; + break; + + case FAL_NROM_TCP_SF_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 23; + break; + + case FAL_NROM_TCP_SAR_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 24; + break; + + case FAL_NROM_TCP_RST_SCAN_CMD: + addr = NORM_CTRL0_ADDR; + offset = 25; + break; + + case FAL_NROM_TCP_SYN_WITH_DATA_CMD: + addr = NORM_CTRL0_ADDR; + offset = 26; + break; + + case FAL_NROM_TCP_RST_WITH_DATA_CMD: + addr = NORM_CTRL0_ADDR; + offset = 27; + break; + + case FAL_NROM_TCP_FA_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 28; + break; + + case FAL_NROM_TCP_PA_BLOCK_CMD: + addr = NORM_CTRL0_ADDR; + offset = 29; + break; + + case FAL_NROM_TCP_UA_BLOCK_CMD: + addr = NORM_CTRL1_ADDR; + offset = 0; + break; + + case FAL_NROM_TCP_INVALID_CHKSUM_CMD: + addr = NORM_CTRL1_ADDR; + offset = 1; + break; + + case FAL_NROM_TCP_INVALID_URGPTR_CMD: + addr = NORM_CTRL1_ADDR; + offset = 2; + break; + + case FAL_NROM_TCP_INVALID_OPTIONS_CMD: + addr = NORM_CTRL1_ADDR; + offset = 3; + break; + + case FAL_NROM_UDP_BLAT_CMD: + addr = NORM_CTRL1_ADDR; + offset = 4; + break; + + case FAL_NROM_UDP_INVALID_LEN_CMD: + addr = NORM_CTRL1_ADDR; + offset = 5; + break; + + case FAL_NROM_UDP_INVALID_CHKSUM_CMD: + addr = NORM_CTRL1_ADDR; + offset = 6; + break; + + case FAL_NROM_ICMP4_PING_PL_EXCEED_CMD: + addr = NORM_CTRL1_ADDR; + offset = 7; + break; + + case FAL_NROM_ICMP6_PING_PL_EXCEED_CMD: + addr = NORM_CTRL1_ADDR; + offset = 8; + break; + + case FAL_NROM_ICMP4_PING_FRAG_CMD: + addr = NORM_CTRL1_ADDR; + offset = 9; + break; + + case FAL_NROM_ICMP6_PING_FRAG_CMD: + addr = NORM_CTRL1_ADDR; + offset = 10; + break; + + case FAL_NROM_ICMP4_PING_MAX_PL_VALUE: + addr = NORM_CTRL2_ADDR; + offset = 0; + len = 14; + val_chk = 1; + break; + + case FAL_NROM_ICMP6_PING_MAX_PL_VALUE: + addr = NORM_CTRL2_ADDR; + offset = 16; + len = 14; + val_chk = 1; + break; + + default: + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_FIELD_GET_BY_REG_U32(reg, val, offset, len); + + if (val_chk) + { + *((a_uint32_t *) value) = val; + } + else if (status_chk) + { + if (val) + { + *((a_bool_t *) value) = A_TRUE; + } + else + { + *((a_bool_t *) value) = A_FALSE; + } + } + else if (scmd_chk) + { + if (2 == val) + { + *((fal_fwd_cmd_t *) value) = FAL_MAC_RDT_TO_CPU; + } + else if (3 == val) + { + *((fal_fwd_cmd_t *) value) = FAL_MAC_DROP; + } + else + { + *((fal_fwd_cmd_t *) value) = FAL_MAC_FRWRD; + } + } + else + { + if (val) + { + *((fal_fwd_cmd_t *) value) = FAL_MAC_DROP; + } + else + { + *((fal_fwd_cmd_t *) value) = FAL_MAC_FRWRD; + } + } + + return SW_OK; +} + +/** + * @brief Set normalization particular item types value. + * @details Comments: + * This operation will set normalization item values on a particular device. + * The prototye of value based on the item type. + * @param[in] dev_id device id + * @param[in] item normalizaton item type + * @param[in] value normalizaton item value + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_sec_norm_item_set(a_uint32_t dev_id, fal_norm_item_t item, void *value) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_sec_norm_item_set(dev_id, item, value); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get normalization particular item types value. + * @details Comments: + * This operation will set normalization item values on a particular device. + * The prototye of value based on the item type. + * @param[in] dev_id device id + * @param[in] item normalizaton item type + * @param[out] value normalizaton item value + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_sec_norm_item_get(a_uint32_t dev_id, fal_norm_item_t item, void *value) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_sec_norm_item_get(dev_id, item, value); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +isisc_sec_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->sec_norm_item_set = isisc_sec_norm_item_set; + p_api->sec_norm_item_get = isisc_sec_norm_item_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_stp.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_stp.c new file mode 100755 index 000000000..dc1716220 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_stp.c @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup isisc_stp ISISC_STP + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isisc_stp.h" +#include "isisc_reg.h" + +#define ISISC_PORT_DISABLED 0 +#define ISISC_STP_BLOCKING 1 +#define ISISC_STP_LISTENING 2 +#define ISISC_STP_LEARNING 3 +#define ISISC_STP_FARWARDING 4 + +static sw_error_t +_isisc_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; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_SINGLE_STP_ID != st_id) + { + return SW_BAD_PARAM; + } + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + switch (state) + { + case FAL_STP_BLOKING: + val = ISISC_STP_BLOCKING; + break; + case FAL_STP_LISTENING: + val = ISISC_STP_LISTENING; + break; + case FAL_STP_LEARNING: + val = ISISC_STP_LEARNING; + break; + case FAL_STP_FARWARDING: + val = ISISC_STP_FARWARDING; + break; + case FAL_STP_DISABLED: + val = ISISC_PORT_DISABLED; + break; + default: + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_LOOKUP_CTL, port_id, PORT_STATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_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; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_SINGLE_STP_ID != st_id) + { + return SW_BAD_PARAM; + } + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_LOOKUP_CTL, port_id, PORT_STATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + switch (val) + { + case ISISC_STP_BLOCKING: + *state = FAL_STP_BLOKING; + break; + case ISISC_STP_LISTENING: + *state = FAL_STP_LISTENING; + break; + case ISISC_STP_LEARNING: + *state = FAL_STP_LEARNING; + break; + case ISISC_STP_FARWARDING: + *state = FAL_STP_FARWARDING; + break; + case ISISC_PORT_DISABLED: + *state = FAL_STP_DISABLED; + break; + default: + return SW_FAIL; + } + + return SW_OK; +} + +/** + * @brief Set port stp state on a particular spanning tree and port. + * @details Comments: + Garuda only support single spanning tree so st_id should be + FAL_SINGLE_STP_ID that is zero. + * @param[in] dev_id device id + * @param[in] st_id spanning tree id + * @param[in] port_id port id + * @param[in] state port state for spanning tree + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_stp_port_state_set(dev_id, st_id, port_id, state); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get port stp state on a particular spanning tree and port. + * @details Comments: + Garuda only support single spanning tree so st_id should be + FAL_SINGLE_STP_ID that is zero. + * @param[in] dev_id device id + * @param[in] st_id spanning tree id + * @param[in] port_id port id + * @param[out] state port state for spanning tree + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_stp_port_state_get(dev_id, st_id, port_id, state); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +isisc_stp_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->stp_port_state_set = isisc_stp_port_state_set; + p_api->stp_port_state_get = isisc_stp_port_state_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_trunk.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_trunk.c new file mode 100755 index 000000000..2ed7936db --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_trunk.c @@ -0,0 +1,692 @@ +/* + * Copyright (c) 2012, 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. + */ + + + +/** + * @defgroup isisc_trunk ISISC_TRUNK + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isisc_trunk.h" +#include "isisc_reg.h" + +#define ISISC_MAX_TRUNK_ID 3 + +/*feature on/off for manipulating dp within trunk group*/ +#define ISISC_TRUNK_MANIPULATE_DP_ON 1 +#define ISISC_TRUNK_MANIPULATE_HEADER_LEN 12 +#define MAC_LEN 6 +#define HASH_SIZE 4 + +enum isisc_trunk_reg_id +{ + ISISC_TRUNK_HASH_EN = 0, /*0x270*/ + ISISC_TRUNK_CTRL_0, /*0x700*/ + ISISC_TRUNK_CTRL_1, /*0x704*/ + ISISC_TRUNK_CTRL_2, /*0x708*/ + ISISC_TRUNK_REG_MAX +}; + +static a_uint32_t isisc_trunk_regs[ISISC_TRUNK_REG_MAX] = +{ + 0xf, 0x0, 0x0, 0x0 +}; + +static a_uint8_t sa_hash[HASH_SIZE][MAC_LEN] = +{ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x03 } +}; + +static sw_error_t +_isisc_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; + a_uint32_t i, reg = 0, cnt = 0, data0 = 0, data1 = 0; + + if (ISISC_MAX_TRUNK_ID < trunk_id) + { + return SW_BAD_PARAM; + } + + if (A_FALSE == hsl_mports_prop_check(dev_id, member, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data0 = (0x1 << 7) | member; + + for (i = 0; i < 7; i++) + { + if (member & (0x1 << i)) + { + if (4 <= cnt) + { + return SW_BAD_PARAM; + } + + data1 |= (i << (cnt << 2)); + data1 |= (1 << (3 + (cnt << 2))); + cnt++; + } + } + } + else if (A_FALSE == enable) + { + + } + else + { + return SW_BAD_PARAM; + } + + /* set trunk port member bitmap info */ + HSL_REG_ENTRY_GET(rv, dev_id, GOL_TRUNK_CTL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + reg &= (~(0xff << (trunk_id << 3))); + reg |= (data0 << (trunk_id << 3)); + + HSL_REG_ENTRY_SET(rv, dev_id, GOL_TRUNK_CTL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + isisc_trunk_regs[ISISC_TRUNK_CTRL_0] = reg; + + /* set trunk port member id info */ + HSL_REG_ENTRY_GET(rv, dev_id, GOL_TRUNK_CTL1, (trunk_id >> 1), + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + reg &= (~(0xffff << ((trunk_id % 2) << 4))); + reg |= (data1 << ((trunk_id % 2) << 4)); + + HSL_REG_ENTRY_SET(rv, dev_id, GOL_TRUNK_CTL1, (trunk_id >> 1), + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + isisc_trunk_regs[ISISC_TRUNK_CTRL_1 + (trunk_id >> 1)] = reg; + + return SW_OK; +} + +static sw_error_t +_isisc_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; + a_uint32_t data, reg = 0; + + if (ISISC_MAX_TRUNK_ID < trunk_id) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, GOL_TRUNK_CTL0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data = (reg >> (trunk_id << 3)) & 0xff; + if (0x80 & data) + { + *enable = A_TRUE; + *member = data & 0x7f; + } + else + { + *enable = A_FALSE; + *member = 0; + } + + return SW_OK; +} + +#if 0 +static sw_error_t +_isisc_trunk_group_sw_get(a_uint32_t dev_id, a_uint32_t trunk_id, + a_bool_t * enable, fal_pbmp_t * member) +{ + a_uint32_t data, reg; + + if (ISISC_MAX_TRUNK_ID < trunk_id) + { + return SW_BAD_PARAM; + } + + reg = isisc_trunk_regs[ISISC_TRUNK_CTRL_0]; + + data = (reg >> (trunk_id << 3)) & 0xff; + if (0x80 & data) + { + *enable = A_TRUE; + *member = data & 0x7f; + } + else + { + *enable = A_FALSE; + *member = 0; + } + + return SW_OK; +} +#endif + +static sw_error_t +_isisc_trunk_hash_mode_set(a_uint32_t dev_id, a_uint32_t hash_mode) +{ + sw_error_t rv; + a_uint32_t data = 0; + + if (FAL_TRUNK_HASH_KEY_DA & hash_mode) + { + SW_SET_REG_BY_FIELD(TRUNK_HASH_MODE, DA_EN, 1, data); + } + + if (FAL_TRUNK_HASH_KEY_SA & hash_mode) + { + SW_SET_REG_BY_FIELD(TRUNK_HASH_MODE, SA_EN, 1, data); + } + + if (FAL_TRUNK_HASH_KEY_DIP & hash_mode) + { + SW_SET_REG_BY_FIELD(TRUNK_HASH_MODE, DIP_EN, 1, data); + } + + if (FAL_TRUNK_HASH_KEY_SIP & hash_mode) + { + SW_SET_REG_BY_FIELD(TRUNK_HASH_MODE, SIP_EN, 1, data); + } + + HSL_REG_ENTRY_SET(rv, dev_id, TRUNK_HASH_MODE, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + isisc_trunk_regs[ISISC_TRUNK_HASH_EN] = data; + + return rv; +} + +static sw_error_t +_isisc_trunk_hash_mode_get(a_uint32_t dev_id, a_uint32_t * hash_mode) +{ + sw_error_t rv; + a_uint32_t reg = 0, data = 0; + + HSL_REG_ENTRY_GET(rv, dev_id, TRUNK_HASH_MODE, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *hash_mode = 0; + + SW_GET_FIELD_BY_REG(TRUNK_HASH_MODE, DA_EN, data, reg); + if (data) + { + *hash_mode |= FAL_TRUNK_HASH_KEY_DA; + } + + SW_GET_FIELD_BY_REG(TRUNK_HASH_MODE, SA_EN, data, reg); + if (data) + { + *hash_mode |= FAL_TRUNK_HASH_KEY_SA; + } + + SW_GET_FIELD_BY_REG(TRUNK_HASH_MODE, DIP_EN, data, reg); + if (data) + { + *hash_mode |= FAL_TRUNK_HASH_KEY_DIP; + } + + SW_GET_FIELD_BY_REG(TRUNK_HASH_MODE, SIP_EN, data, reg); + if (data) + { + *hash_mode |= FAL_TRUNK_HASH_KEY_SIP; + } + + return SW_OK; +} + +#define BYTE_B2R(x, mask) ((x) ^ (mask)) +#define BYTE_B1C(x) ((((((x&0x55)+((x&0xaa)>>1))&0x33)+((((x&0x55)+((x&0xaa)>>1))&0xcc)>>2))&0x0f)+((((((x&0x55)+((x&0xaa)>>1))&0x33)+((((x&0x55)+((x&0xaa)>>1))&0xcc)>>2))&0xf0)>>4)) + +static sw_error_t +_isisc_trunk_manipulate_sa_set(a_uint32_t dev_id, fal_mac_addr_t * addr) +{ + a_uint32_t i; + + for (i = 0; i < HASH_SIZE; i++) + { + memcpy(sa_hash[i], addr->uc, MAC_LEN); + sa_hash[i][MAC_LEN - 1] = BYTE_B2R(sa_hash[i][MAC_LEN - 1], i); + } + + return SW_OK; +} + +static sw_error_t +_isisc_trunk_manipulate_sa_get(a_uint32_t dev_id, fal_mac_addr_t * addr) +{ + memcpy(addr->uc, sa_hash[0], MAC_LEN); + return SW_OK; +} + +#if 0 +static sw_error_t +_isisc_trunk_hash_mode_sw_get(a_uint32_t dev_id, a_uint32_t * hash_mode) +{ + a_uint32_t reg, data = 0; + + reg = isisc_trunk_regs[ISISC_TRUNK_HASH_EN]; + + *hash_mode = 0; + + SW_GET_FIELD_BY_REG(TRUNK_HASH_MODE, DA_EN, data, reg); + if (data) + { + *hash_mode |= FAL_TRUNK_HASH_KEY_DA; + } + + SW_GET_FIELD_BY_REG(TRUNK_HASH_MODE, SA_EN, data, reg); + if (data) + { + *hash_mode |= FAL_TRUNK_HASH_KEY_SA; + } + + SW_GET_FIELD_BY_REG(TRUNK_HASH_MODE, DIP_EN, data, reg); + if (data) + { + *hash_mode |= FAL_TRUNK_HASH_KEY_DIP; + } + + SW_GET_FIELD_BY_REG(TRUNK_HASH_MODE, SIP_EN, data, reg); + if (data) + { + *hash_mode |= FAL_TRUNK_HASH_KEY_SIP; + } + + return SW_OK; +} + +static sw_error_t +_isisc_trunk_id_member_get(a_uint32_t dev_id, a_uint8_t expect_dp, + a_uint32_t * trunk_id, fal_pbmp_t * member) +{ + sw_error_t rv; + a_bool_t enable; + a_uint32_t i; + + for (i = 0; i <= ISISC_MAX_TRUNK_ID; i++) + { + rv = _isisc_trunk_group_sw_get(dev_id, i, &enable, member); + SW_RTN_ON_ERROR(rv); + if (enable && (*member & expect_dp)) + { + *trunk_id = i; + return SW_OK; + } + } + + return SW_NOT_FOUND; +} + +static sw_error_t +_isisc_trunk_hash_dp_get(a_uint32_t dev_id, a_uint8_t * header, a_uint32_t len, + a_uint32_t trunk_id, a_uint32_t mode, a_uint8_t * hash_dp) +{ +#define BIT2_MASK 0x03 +#define TRUNK_MEM_EN_MASK 0x8 +#define TRUNK_MEM_PT_MASK 0x7 +#define TRUNK_HASH_DP_SEL 4 + sw_error_t rv; + a_uint32_t i, hash_mode, reg, data1 = 0; + a_uint32_t da_xor = 0, sa_xor = 0; /*consider da-hash & sa-hash (TBD: dip-hash & sip-hash)*/ + a_uint8_t xor_dp = 0; + + rv = _isisc_trunk_hash_mode_sw_get(dev_id, &hash_mode); + SW_RTN_ON_ERROR(rv); + + if (!hash_mode) + { + return SW_DISABLE; + } + + *hash_dp = 0; + + if ((mode & FAL_TRUNK_HASH_KEY_DA) && (hash_mode & FAL_TRUNK_HASH_KEY_DA)) + { + for (i = 0; i < MAC_LEN; i++) + { + da_xor ^= (header[i] & BIT2_MASK) ^ + ((header[i] >> 2) & BIT2_MASK) ^ + ((header[i] >> 4) & BIT2_MASK) ^ + ((header[i] >> 6) & BIT2_MASK); + } + *hash_dp = da_xor; + } + if ((mode & FAL_TRUNK_HASH_KEY_SA) && (hash_mode & FAL_TRUNK_HASH_KEY_SA)) + { + for (i = 6; i < 2 * MAC_LEN; i++) + { + sa_xor ^= (header[i] & BIT2_MASK) ^ + ((header[i] >> 2) & BIT2_MASK) ^ + ((header[i] >> 4) & BIT2_MASK) ^ + ((header[i] >> 6) & BIT2_MASK); + } + *hash_dp = (*hash_dp) ^ sa_xor; + } + + /*dp translation*/ +#if 0 + HSL_REG_ENTRY_GET(rv, dev_id, GOL_TRUNK_CTL1, (trunk_id >> 1), + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); +#else /*sw*/ + reg = isisc_trunk_regs[ISISC_TRUNK_CTRL_1 + (trunk_id >> 1)]; +#endif + + for (i = 0; i < TRUNK_HASH_DP_SEL; i++) + { + xor_dp = BYTE_B2R(*hash_dp, i); + data1 = (0x0f & (reg >> (((trunk_id % 2) << 4) + (xor_dp << 2)))); + if (data1 & TRUNK_MEM_EN_MASK) + { + *hash_dp = data1 & TRUNK_MEM_PT_MASK; + *hash_dp = 0x01 << (*hash_dp); /*bmp*/ + return SW_OK; + } + } + + return SW_NOT_FOUND; +} + +static sw_error_t +_isisc_trunk_sa_spoofing( a_uint32_t dev_id, a_uint8_t * header, a_uint32_t len, + a_uint8_t expect_dp, a_uint32_t trunk_id, fal_pbmp_t member) +{ + sw_error_t rv; + a_uint32_t i, hash_mode; + a_uint8_t hash_dp; + a_uint8_t ori_sa[MAC_LEN]; + + rv = _isisc_trunk_hash_mode_sw_get(dev_id, &hash_mode); + SW_RTN_ON_ERROR(rv); + + if (!(hash_mode & FAL_TRUNK_HASH_KEY_SA)) + { + return SW_DISABLE; + } + + memcpy(ori_sa, &header[MAC_LEN], MAC_LEN); + + for (i = 0; i < HASH_SIZE/*not HASH_SIZE, for RAD only*/; i++) + { + memcpy(&header[MAC_LEN], sa_hash[i], MAC_LEN); + rv = _isisc_trunk_hash_dp_get(dev_id, header, len, trunk_id, + FAL_TRUNK_HASH_KEY_DA | FAL_TRUNK_HASH_KEY_SA, &hash_dp); + SW_RTN_ON_ERROR(rv); + if (expect_dp == hash_dp) + { + // printk("expect_dp = 0x%x, hash_dp(DA+SA) = 0x%x, sa_id = %d\n", expect_dp, hash_dp, i); + return SW_OK; + } + } + + /*should never here*/ + memcpy(&header[MAC_LEN], ori_sa, MAC_LEN); + return SW_FAIL; +} + +static sw_error_t +_isisc_trunk_manipulate_dp(a_uint32_t dev_id, a_uint8_t * header, + a_uint32_t len, fal_pbmp_t dp_member) +{ + sw_error_t rv; + a_uint8_t expect_dp, hash_dp; /*bitmap*/ + a_uint32_t i, trunk_id; + fal_pbmp_t member; + + if (!ISISC_TRUNK_MANIPULATE_DP_ON) + { + return SW_OK; /*feature not enabled*/ + } + + if (!header || len < ISISC_TRUNK_MANIPULATE_HEADER_LEN) + { + return SW_BAD_VALUE; + } + +#if 0 /*de-comment this to ignore broadcast packets*/ + const a_uint8_t bc_mac[MAC_LEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + if (!memcmp(header, bc_mac, MAC_LEN)) /*not for broadcast*/ + { + return SW_OK; + } +#endif + + /*expect_dp within trunk group*/ + expect_dp = dp_member & 0x7f; + for (i = 0; i < 7; i++) + { + if (expect_dp & (0x01 << i)) + { + rv = _isisc_trunk_id_member_get(dev_id, (0x01 << i), &trunk_id, &member); + if (rv != SW_OK) + { + expect_dp &= ~(0x01 << i); /*not the dp doesn't belong to trunk*/ + } + } + } + + if (BYTE_B1C(expect_dp) != 1) /*supports 1 dp only*/ + { + return SW_OK; /*ignore none-dp or multi-dp*/ + } + + rv = _isisc_trunk_id_member_get(dev_id, expect_dp, &trunk_id, &member); + SW_RTN_ON_ERROR(rv); + + member &= 0x7f; + if (BYTE_B1C(member) == 1) /*trunk group w/ one port*/ + { + return SW_OK; + } + + rv = _isisc_trunk_hash_dp_get(dev_id, header, len, trunk_id, + FAL_TRUNK_HASH_KEY_DA | FAL_TRUNK_HASH_KEY_SA, &hash_dp); + SW_RTN_ON_ERROR(rv); + + // printk("expect_dp = 0x%x, hash_dp(DA+SA) = 0x%x, member = 0x%x\n", expect_dp, hash_dp, member); + if (expect_dp == hash_dp) + { + return SW_OK; + } + + rv = _isisc_trunk_sa_spoofing(dev_id, header, len, expect_dp, trunk_id, member); + SW_RTN_ON_ERROR(rv); + + return rv; +} +#endif + +/** + * @brief Set particular trunk group information on particular device. + * @param[in] dev_id device id + * @param[in] trunk_id trunk group id + * @param[in] enable trunk group status, enable or disable + * @param[in] member port member information + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_trunk_group_set(dev_id, trunk_id, enable, member); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get particular trunk group information on particular device. + * @param[in] dev_id device id + * @param[in] trunk_id trunk group id + * @param[out] enable trunk group status, enable or disable + * @param[out] member port member information + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_trunk_group_get(dev_id, trunk_id, enable, member); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set trunk hash mode on particular device. + * @details Comments: + hash mode is listed below + FAL_TRUNK_HASH_KEY_DA, FAL_TRUNK_HASH_KEY_SA, FAL_TRUNK_HASH_KEY_DIP and FAL_TRUNK_HASH_KEY_SIP + * @param[in] dev_id device id + * @param[in] hash_mode trunk hash mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_trunk_hash_mode_set(a_uint32_t dev_id, a_uint32_t hash_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_trunk_hash_mode_set(dev_id, hash_mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get trunk hash mode on particular device. + * @param[in] dev_id device id + * @param[out] hash_mode trunk hash mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_trunk_hash_mode_get(a_uint32_t dev_id, a_uint32_t * hash_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_trunk_hash_mode_get(dev_id, hash_mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set trunk manipulate SA on particular device. + * @param[in] dev_id device id + * @param[in] addr manipulate SA + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_trunk_manipulate_sa_set(a_uint32_t dev_id, fal_mac_addr_t * addr) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_trunk_manipulate_sa_set(dev_id, addr); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get trunk manipulate SA on particular device. + * @param[in] dev_id device id + * @param[out] addr manipulate SA + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_trunk_manipulate_sa_get(a_uint32_t dev_id, fal_mac_addr_t * addr) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_trunk_manipulate_sa_get(dev_id, addr); + HSL_API_UNLOCK; + return rv; +} + +#if 0 +/** + * @brief manipulate destination port within a trunk group + * @details Comments: + * supporting hash mode include: FAL_TRUNK_HASH_KEY_DA & FAL_TRUNK_HASH_KEY_SA; + * FAL_TRUNK_HASH_KEY_DIP & FAL_TRUNK_HASH_KEY_SIP are NOT covered in current design + * @param[in] dev_id device id + * @param[in-out] header packet header, accept format: [DA:6B][SA:6B] + * @param[in] len length of packet header, should be 12 in current design (6B DA + 6B SA) + * @param[in] dp_member expect destination port members, bitmap format + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_trunk_manipulate_dp(a_uint32_t dev_id, a_uint8_t * header, + a_uint32_t len, fal_pbmp_t dp_member) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_trunk_manipulate_dp(dev_id, header, len, dp_member); + HSL_API_UNLOCK; + return rv; +} +#endif + +sw_error_t +isisc_trunk_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->trunk_group_set = isisc_trunk_group_set; + p_api->trunk_group_get = isisc_trunk_group_get; + p_api->trunk_hash_mode_set = isisc_trunk_hash_mode_set; + p_api->trunk_hash_mode_get = isisc_trunk_hash_mode_get; + p_api->trunk_manipulate_sa_set = isisc_trunk_manipulate_sa_set; + p_api->trunk_manipulate_sa_get = isisc_trunk_manipulate_sa_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_vlan.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_vlan.c new file mode 100755 index 000000000..1d613175c --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/isisc/isisc_vlan.c @@ -0,0 +1,906 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 isisc_vlan ISISC_VLAN + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "isisc_vlan.h" +#include "isisc_reg.h" + +#define MAX_VLAN_ID 4095 + +#define VLAN_FLUSH 1 +#define VLAN_LOAD_ENTRY 2 +#define VLAN_PURGE_ENTRY 3 +#define VLAN_REMOVE_PORT 4 +#define VLAN_NEXT_ENTRY 5 +#define VLAN_FIND_ENTRY 6 + +static void +_isisc_vlan_hw_to_sw(a_uint32_t reg[], fal_vlan_t * vlan_entry) +{ + a_uint32_t i, data, tmp; + + aos_mem_zero(vlan_entry, sizeof (fal_vlan_t)); + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC1, VLAN_ID, data, reg[1]); + vlan_entry->vid = data & 0xfff; + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC0, IVL_EN, data, reg[0]); + if (1 == data) + { + vlan_entry->fid = vlan_entry->vid; + } + else + { + vlan_entry->fid = FAL_SVL_FID; + } + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC0, LEARN_DIS, data, reg[0]); + if (1 == data) + { + vlan_entry->learn_dis = A_TRUE; + } + else + { + vlan_entry->learn_dis = A_FALSE; + } + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC0, VT_PRI_EN, data, reg[0]); + if (1 == data) + { + vlan_entry->vid_pri_en = A_TRUE; + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC0, VT_PRI, data, reg[0]); + vlan_entry->vid_pri = data & 0xff; + } + else + { + vlan_entry->vid_pri_en = A_FALSE; + } + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC0, VID_MEM, data, reg[0]); + for (i = 0; i < 7; i++) + { + tmp = (data >> (i << 1)) & 0x3UL; + if (0 == tmp) + { + vlan_entry->mem_ports |= (0x1UL << i); + vlan_entry->unmodify_ports |= (0x1UL << i); + } + else if (1 == tmp) + { + vlan_entry->mem_ports |= (0x1UL << i); + vlan_entry->untagged_ports |= (0x1UL << i); + } + else if (2 == tmp) + { + vlan_entry->mem_ports |= (0x1UL << i); + vlan_entry->tagged_ports |= (0x1UL << i); + } + } + + return; +} + +static sw_error_t +_isisc_vlan_sw_to_hw(a_uint32_t dev_id, const fal_vlan_t * vlan_entry, + a_uint32_t reg[]) +{ + a_uint32_t i, tag, untag, unmodify, member = 0; + + if (vlan_entry->vid > MAX_VLAN_ID) + { + return SW_OUT_OF_RANGE; + } + + if (A_FALSE == + hsl_mports_prop_check(dev_id, vlan_entry->mem_ports, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_VALID, 1, reg[0]); + + if (FAL_SVL_FID == vlan_entry->fid) + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, IVL_EN, 0, reg[0]); + } + else if (vlan_entry->vid == vlan_entry->fid) + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, IVL_EN, 1, reg[0]); + } + else + { + return SW_BAD_VALUE; + } + + if (A_TRUE == vlan_entry->learn_dis) + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, LEARN_DIS, 1, reg[0]); + } + else + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, LEARN_DIS, 0, reg[0]); + } + + for (i = 0; i < 7; i++) + { + if ((vlan_entry->mem_ports >> i) & 0x1UL) + { + tag = (vlan_entry->tagged_ports >> i) & 0x1UL; + untag = (vlan_entry->untagged_ports >> i) & 0x1UL; + unmodify = (vlan_entry->unmodify_ports >> i) & 0x1UL; + + if ((0 == (tag + untag + unmodify)) + || (1 < (tag + untag + unmodify))) + { + return SW_BAD_VALUE; + } + + if (tag) + { + member |= (2 << (i << 1)); + } + else if (untag) + { + member |= (1 << (i << 1)); + } + } + else + { + member |= (3 << (i << 1)); + } + } + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VID_MEM, member, reg[0]); + + if (A_TRUE == vlan_entry->vid_pri_en) + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_PRI_EN, 1, reg[0]); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_PRI, vlan_entry->vid_pri, + reg[0]); + } + else + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_PRI_EN, 0, reg[0]); + } + + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC1, VLAN_ID, vlan_entry->vid, reg[1]); + + return SW_OK; +} + +static sw_error_t +_isisc_vlan_down_to_hw(a_uint32_t dev_id, a_uint32_t reg[]) +{ + sw_error_t rv; + + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_vlan_up_to_sw(a_uint32_t dev_id, a_uint32_t reg[]) +{ + sw_error_t rv; + + HSL_REG_ENTRY_GET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_isisc_vlan_commit(a_uint32_t dev_id, a_uint32_t op) +{ + a_uint32_t vt_busy = 1, i = 0x1000, vt_full, val; + sw_error_t rv; + + while (vt_busy && --i) + { + HSL_REG_FIELD_GET(rv, dev_id, VLAN_TABLE_FUNC1, 0, VT_BUSY, + (a_uint8_t *) (&vt_busy), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + aos_udelay(5); + } + + if (i == 0) + return SW_BUSY; + + HSL_REG_ENTRY_GET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC1, VT_FUNC, op, val); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC1, VT_BUSY, 1, val); + + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + vt_busy = 1; + i = 0x1000; + while (vt_busy && --i) + { + HSL_REG_FIELD_GET(rv, dev_id, VLAN_TABLE_FUNC1, 0, VT_BUSY, + (a_uint8_t *) (&vt_busy), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + aos_udelay(5); + } + + if (i == 0) + return SW_FAIL; + + HSL_REG_FIELD_GET(rv, dev_id, VLAN_TABLE_FUNC1, 0, VT_FULL_VIO, + (a_uint8_t *) (&vt_full), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (vt_full) + { + val = 0x10; + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + if (VLAN_LOAD_ENTRY == op) + { + return SW_FULL; + } + else if (VLAN_PURGE_ENTRY == op) + { + return SW_NOT_FOUND; + } + } + + HSL_REG_FIELD_GET(rv, dev_id, VLAN_TABLE_FUNC0, 0, VT_VALID, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (!val) + { + if (VLAN_FIND_ENTRY == op) + return SW_NOT_FOUND; + + if (VLAN_NEXT_ENTRY == op) + return SW_NO_MORE; + } + + return SW_OK; +} + +static sw_error_t +_isisc_vlan_hwentry_get(a_uint32_t dev_id, a_uint32_t vlan_id, a_uint32_t reg[]) +{ + sw_error_t rv; + + if (vlan_id > MAX_VLAN_ID) + { + return SW_OUT_OF_RANGE; + } + + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC1, VLAN_ID, vlan_id, reg[1]); + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_vlan_commit(dev_id, VLAN_FIND_ENTRY); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_vlan_up_to_sw(dev_id, reg); + return rv; +} + +static sw_error_t +_isisc_vlan_entry_append(a_uint32_t dev_id, const fal_vlan_t * vlan_entry) +{ + sw_error_t rv; + a_uint32_t reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_vlan_sw_to_hw(dev_id, vlan_entry, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_vlan_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_vlan_commit(dev_id, VLAN_LOAD_ENTRY); + return rv; +} + +static sw_error_t +_isisc_vlan_create(a_uint32_t dev_id, a_uint32_t vlan_id) +{ + sw_error_t rv; + a_uint32_t reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (vlan_id > MAX_VLAN_ID) + { + return SW_OUT_OF_RANGE; + } + + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_VALID, 1, reg[0]); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, IVL_EN, 1, reg[0]); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, LEARN_DIS, 0, reg[0]); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VID_MEM, 0x3fff, reg[0]); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC1, VLAN_ID, vlan_id, reg[1]); + + rv = _isisc_vlan_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_vlan_commit(dev_id, VLAN_LOAD_ENTRY); + return rv; +} + +static sw_error_t +_isisc_vlan_next(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan) +{ + sw_error_t rv; + a_uint32_t reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_NEXT_ENTRY_FIRST_ID == vlan_id) + { + rv = _isisc_vlan_hwentry_get(dev_id, 0, reg); + + if (SW_OK == rv) + { + _isisc_vlan_hw_to_sw(reg, p_vlan); + return SW_OK; + } + else + { + vlan_id = 0; + } + } + + if (vlan_id > MAX_VLAN_ID) + return SW_OUT_OF_RANGE; + + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC1, VLAN_ID, vlan_id, reg[1]); + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + rv = _isisc_vlan_commit(dev_id, VLAN_NEXT_ENTRY); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_vlan_up_to_sw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + _isisc_vlan_hw_to_sw(reg, p_vlan); + + if (0 == p_vlan->vid) + { + return SW_NO_MORE; + } + else + { + return SW_OK; + } +} + +static sw_error_t +_isisc_vlan_find(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan) +{ + sw_error_t rv; + a_uint32_t reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_vlan_hwentry_get(dev_id, vlan_id, reg); + SW_RTN_ON_ERROR(rv); + + _isisc_vlan_hw_to_sw(reg, p_vlan); + return SW_OK; +} + +static sw_error_t +_isisc_vlan_delete(a_uint32_t dev_id, a_uint32_t vlan_id) +{ + sw_error_t rv; + a_uint32_t reg; + + HSL_DEV_ID_CHECK(dev_id); + + if (vlan_id > MAX_VLAN_ID) + { + return SW_OUT_OF_RANGE; + } + + reg = (a_int32_t) vlan_id; + HSL_REG_FIELD_SET(rv, dev_id, VLAN_TABLE_FUNC1, 0, VLAN_ID, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_vlan_commit(dev_id, VLAN_PURGE_ENTRY); + return rv; +} + +static sw_error_t +_isisc_vlan_flush(a_uint32_t dev_id) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_vlan_commit(dev_id, VLAN_FLUSH); + return rv; +} + +static sw_error_t +_isisc_vlan_fid_set(a_uint32_t dev_id, a_uint32_t vlan_id, a_uint32_t fid) +{ + sw_error_t rv; + a_uint32_t reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + if ((MAX_VLAN_ID < fid) && (FAL_SVL_FID != fid)) + { + return SW_BAD_PARAM; + } + + if ((MAX_VLAN_ID >= fid) && (vlan_id != fid)) + { + return SW_BAD_PARAM; + } + + rv = _isisc_vlan_hwentry_get(dev_id, vlan_id, reg); + SW_RTN_ON_ERROR(rv); + + if (FAL_SVL_FID == fid) + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, IVL_EN, 0, reg[0]); + } + else + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, IVL_EN, 1, reg[0]); + } + + rv = _isisc_vlan_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_vlan_commit(dev_id, VLAN_LOAD_ENTRY); + if (SW_FULL == rv) + { + rv = SW_OK; + } + return rv; +} + +static sw_error_t +_isisc_vlan_fid_get(a_uint32_t dev_id, a_uint32_t vlan_id, a_uint32_t * fid) +{ + sw_error_t rv; + a_uint32_t data, reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_vlan_hwentry_get(dev_id, vlan_id, reg); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC0, IVL_EN, data, reg[0]); + if (data) + { + *fid = vlan_id; + } + else + { + *fid = FAL_SVL_FID; + } + return SW_OK; +} + +static sw_error_t +_isisc_vlan_member_update(a_uint32_t dev_id, a_uint32_t vlan_id, + fal_port_t port_id, a_uint32_t port_info) +{ + sw_error_t rv; + a_uint32_t data, reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + rv = _isisc_vlan_hwentry_get(dev_id, vlan_id, reg); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC0, VID_MEM, data, reg[0]); + data &= (~(0x3 << (port_id << 1))); + data |= ((port_info & 0x3) << (port_id << 1)); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VID_MEM, data, reg[0]); + + rv = _isisc_vlan_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_vlan_commit(dev_id, VLAN_LOAD_ENTRY); + if (SW_FULL == rv) + { + rv = SW_OK; + } + return rv; +} + +static sw_error_t +_isisc_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; + a_uint32_t info = 0; + + if (FAL_EG_UNMODIFIED == port_info) + { + info = 0; + } + else if (FAL_EG_TAGGED == port_info) + { + info = 0x2; + } + else if (FAL_EG_UNTAGGED == port_info) + { + info = 0x1; + } + else + { + return SW_BAD_PARAM; + } + + rv = _isisc_vlan_member_update(dev_id, vlan_id, port_id, info); + return rv; +} + +static sw_error_t +_isisc_vlan_member_del(a_uint32_t dev_id, a_uint32_t vlan_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t info = 0x3; + + rv = _isisc_vlan_member_update(dev_id, vlan_id, port_id, info); + return rv; +} + +static sw_error_t +_isisc_vlan_learning_state_set(a_uint32_t dev_id, a_uint32_t vlan_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_vlan_hwentry_get(dev_id, vlan_id, reg); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, LEARN_DIS, 0, reg[0]); + } + else if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, LEARN_DIS, 1, reg[0]); + } + else + { + return SW_BAD_PARAM; + } + + rv = _isisc_vlan_down_to_hw(dev_id, reg); + SW_RTN_ON_ERROR(rv); + + rv = _isisc_vlan_commit(dev_id, VLAN_LOAD_ENTRY); + if (SW_FULL == rv) + { + rv = SW_OK; + } + return rv; +} + +static sw_error_t +_isisc_vlan_learning_state_get(a_uint32_t dev_id, a_uint32_t vlan_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t data, reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _isisc_vlan_hwentry_get(dev_id, vlan_id, reg); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC0, LEARN_DIS, data, reg[0]); + if (data) + { + *enable = A_FALSE; + } + else + { + *enable = A_TRUE; + } + return SW_OK; +} + +/** + * @brief Append a vlan entry on paticular device. + * @param[in] dev_id device id + * @param[in] vlan_entry vlan entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_vlan_entry_append(a_uint32_t dev_id, const fal_vlan_t * vlan_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_vlan_entry_append(dev_id, vlan_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Creat a vlan entry through vlan id on a paticular device. + * @details Comments: + * After this operation the member ports of the created vlan entry are null. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_vlan_create(a_uint32_t dev_id, a_uint32_t vlan_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_vlan_create(dev_id, vlan_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Next a vlan entry through vlan id on a paticular device. + * @details Comments: + * If the value of vid is zero this operation will get the first entry. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[out] p_vlan vlan entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_vlan_next(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_vlan_next(dev_id, vlan_id, p_vlan); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Find a vlan entry through vlan id on paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[out] p_vlan vlan entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_vlan_find(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_vlan_find(dev_id, vlan_id, p_vlan); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a vlan entry through vlan id on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_vlan_delete(a_uint32_t dev_id, a_uint32_t vlan_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_vlan_delete(dev_id, vlan_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Flush all vlan entries on a paticular device. + * @param[in] dev_id device id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_vlan_flush(a_uint32_t dev_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_vlan_flush(dev_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set FID of a paticular vlan entry on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[in] fid FDB id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_vlan_fid_set(a_uint32_t dev_id, a_uint32_t vlan_id, a_uint32_t fid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_vlan_fid_set(dev_id, vlan_id, fid); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get FID of a paticular vlan entry on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[out] fid FDB id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_vlan_fid_get(a_uint32_t dev_id, a_uint32_t vlan_id, a_uint32_t * fid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_vlan_fid_get(dev_id, vlan_id, fid); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add a port member to a paticular vlan entry on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[in] port_id port id + * @param[in] port_info port tag information + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_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; + + HSL_API_LOCK; + rv = _isisc_vlan_member_add(dev_id, vlan_id, port_id, port_info); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Del a port member from a paticular vlan entry on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[in] port_id port id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_vlan_member_del(a_uint32_t dev_id, a_uint32_t vlan_id, fal_port_t port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_vlan_member_del(dev_id, vlan_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set FDB learning status of a paticular vlan entry on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_vlan_learning_state_set(a_uint32_t dev_id, a_uint32_t vlan_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_vlan_learning_state_set(dev_id, vlan_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get FDB learning status of a paticular vlan entry on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +isisc_vlan_learning_state_get(a_uint32_t dev_id, a_uint32_t vlan_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _isisc_vlan_learning_state_get(dev_id, vlan_id, enable); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +isisc_vlan_init(a_uint32_t dev_id) +{ + hsl_api_t *p_api; + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->vlan_entry_append = isisc_vlan_entry_append; + p_api->vlan_creat = isisc_vlan_create; + p_api->vlan_delete = isisc_vlan_delete; + p_api->vlan_next = isisc_vlan_next; + p_api->vlan_find = isisc_vlan_find; + p_api->vlan_flush = isisc_vlan_flush; + p_api->vlan_fid_set = isisc_vlan_fid_set; + p_api->vlan_fid_get = isisc_vlan_fid_get; + p_api->vlan_member_add = isisc_vlan_member_add; + p_api->vlan_member_del = isisc_vlan_member_del; + p_api->vlan_learning_state_set = isisc_vlan_learning_state_set; + p_api->vlan_learning_state_get = isisc_vlan_learning_state_get; + + +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/mp/Makefile b/feeds/ipq807x/qca-ssdk/src/src/hsl/mp/Makefile new file mode 100755 index 000000000..cfa823424 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/mp/Makefile @@ -0,0 +1,26 @@ +LOC_DIR=src/hsl/mp +LIB=HSL + +include $(PRJ_PATH)/make/config.mk + +ifeq (TRUE, $(IN_MIB)) + SRC_LIST+=mp_mib.c +endif + +ifeq (TRUE, $(IN_PORTCONTROL)) + SRC_LIST+=mp_portctrl.c +endif + +ifeq (TRUE, $(IN_UNIPHY)) + SRC_LIST+=mp_uniphy.c +endif + +ifeq (, $(filter MP, $(SUPPORT_CHIP))) + SRC_LIST= +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/src/src/hsl/mp/mp_mib.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/mp/mp_mib.c new file mode 100755 index 000000000..e3188a15d --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/mp/mp_mib.c @@ -0,0 +1,816 @@ +/* + * 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 "sw.h" +#include "hsl.h" +#include "scomphy_reg_access.h" +#include "mp_mib_reg.h" +#include "mp_mib.h" + +sw_error_t +mp_mmc_control_get( + a_uint32_t dev_id, + a_uint32_t index, + union mmc_control_u *value) +{ + if (index >= MMC_CONTROL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + MMC_CONTROL_ADDRESS + \ + index * MMC_CONTROL_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_mmc_control_set( + a_uint32_t dev_id, + a_uint32_t index, + union mmc_control_u *value) +{ + if (index >= MMC_CONTROL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_set( + dev_id, + MMC_CONTROL_ADDRESS + \ + index * MMC_CONTROL_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_tx_octet_count_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_octet_count_good_bad_u *value) +{ + if (index >= TX_OCTET_COUNT_GOOD_BAD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + TX_OCTET_COUNT_GOOD_BAD_ADDRESS + \ + index * TX_OCTET_COUNT_GOOD_BAD_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_tx_frame_count_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_frame_count_good_bad_u *value) +{ + if (index >= TX_FRAME_COUNT_GOOD_BAD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + TX_FRAME_COUNT_GOOD_BAD_ADDRESS + \ + index * TX_FRAME_COUNT_GOOD_BAD_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_tx_broadcast_frames_good_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_broadcast_frames_good_u *value) +{ + if (index >= TX_BROADCAST_FRAMES_GOOD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + TX_BROADCAST_FRAMES_GOOD_ADDRESS + \ + index * TX_BROADCAST_FRAMES_GOOD_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_tx_multicast_frames_good_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_multicast_frames_good_u *value) +{ + if (index >= TX_MULTICAST_FRAMES_GOOD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + TX_MULTICAST_FRAMES_GOOD_ADDRESS + \ + index * TX_MULTICAST_FRAMES_GOOD_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_tx_64octets_frames_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_64octets_frames_good_bad_u *value) +{ + if (index >= TX_64OCTETS_FRAMES_GOOD_BAD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + TX_64OCTETS_FRAMES_GOOD_BAD_ADDRESS + \ + index * TX_64OCTETS_FRAMES_GOOD_BAD_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_tx_65to127octets_frames_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_65to127octets_frames_good_bad_u *value) +{ + if (index >= TX_65TO127OCTETS_FRAMES_GOOD_BAD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + TX_65TO127OCTETS_FRAMES_GOOD_BAD_ADDRESS + \ + index * TX_65TO127OCTETS_FRAMES_GOOD_BAD_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_tx_128to255octets_frames_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_128to255octets_frames_good_bad_u *value) +{ + if (index >= TX_128TO255OCTETS_FRAMES_GOOD_BAD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + TX_128TO255OCTETS_FRAMES_GOOD_BAD_ADDRESS + \ + index * TX_128TO255OCTETS_FRAMES_GOOD_BAD_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_tx_256to511octets_frames_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_256to511octets_frames_good_bad_u *value) +{ + if (index >= TX_256TO511OCTETS_FRAMES_GOOD_BAD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + TX_256TO511OCTETS_FRAMES_GOOD_BAD_ADDRESS + \ + index * TX_256TO511OCTETS_FRAMES_GOOD_BAD_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_tx_512to1023octets_frames_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_512to1023octets_frames_good_bad_u *value) +{ + if (index >= TX_512TO1023OCTETS_FRAMES_GOOD_BAD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + TX_512TO1023OCTETS_FRAMES_GOOD_BAD_ADDRESS + \ + index * TX_512TO1023OCTETS_FRAMES_GOOD_BAD_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_tx_1024tomaxoctets_frames_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_1024tomaxoctets_frames_good_bad_u *value) +{ + if (index >= TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_ADDRESS + \ + index * TX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_tx_unicast_frames_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_unicast_frames_good_bad_u *value) +{ + if (index >= TX_UNICAST_FRAMES_GOOD_BAD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + TX_UNICAST_FRAMES_GOOD_BAD_ADDRESS + \ + index * TX_UNICAST_FRAMES_GOOD_BAD_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_tx_multicast_frames_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_multicast_frames_good_bad_u *value) +{ + if (index >= TX_MULTICAST_FRAMES_GOOD_BAD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + TX_MULTICAST_FRAMES_GOOD_BAD_ADDRESS + \ + index * TX_MULTICAST_FRAMES_GOOD_BAD_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_tx_broadcast_frames_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_broadcast_frames_good_bad_u *value) +{ + if (index >= TX_BROADCAST_FRAMES_GOOD_BAD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + TX_BROADCAST_FRAMES_GOOD_BAD_ADDRESS + \ + index * TX_BROADCAST_FRAMES_GOOD_BAD_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_tx_underflow_error_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_underflow_error_frames_u *value) +{ + if (index >= TX_UNDERFERROR_FRAMES_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + TX_UNDERFLOW_ERROR_FRAMES_ADDRESS + \ + index * TX_UNDERFLOW_ERROR_FRAMES_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_tx_single_col_good_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_single_collision_good_frames_u *value) +{ + if (index >= TX_SINGLE_COLLISION_GOOD_FRAMES_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + TX_SINGLE_COLLISION_GOOD_FRAMES_ADDRESS + \ + index * TX_SINGLE_COLLISION_GOOD_FRAMES_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_t_multi_col_good_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_multiple_collision_good_frames_u *value) +{ + if (index >= TX_MULTIPLE_COLLISION_GOOD_FRAMES_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + TX_MULTIPLE_COLLISION_GOOD_FRAMES_ADDRESS + \ + index * TX_MULTIPLE_COLLISION_GOOD_FRAMES_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_tx_defer_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_deferred_frames_u *value) +{ + if (index >= TX_DEFERRED_FRAMES_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + TX_DEFERRED_FRAMES_ADDRESS + \ + index * TX_DEFERRED_FRAMES_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_tx_late_col_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_late_collision_frames_u *value) +{ + if (index >= TX_LATE_COLLISION_FRAMES_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + TX_LATE_COLLISION_FRAMES_ADDRESS + \ + index * TX_LATE_COLLISION_FRAMES_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_tx_excessive_col_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_excessive_collision_frames_u *value) +{ + if (index >= TX_EXCESSIVE_COLLISION_FRAMES_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + TX_EXCESSIVE_COLLISION_FRAMES_ADDRESS + \ + index * TX_EXCESSIVE_COLLISION_FRAMES_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_tx_carrier_error_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_carrier_error_frames_u *value) +{ + if (index >= TX_CARRIER_ERROR_FRAMES_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + TX_CARRIER_ERROR_FRAMES_ADDRESS + \ + index * TX_CARRIER_ERROR_FRAMES_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_tx_octet_count_good_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_octet_count_good_u *value) +{ + if (index >= TX_OCTET_COUNT_GOOD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + TX_OCTET_COUNT_GOOD_ADDRESS + \ + index * TX_OCTET_COUNT_GOOD_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_tx_frame_count_good_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_frame_count_good_u *value) +{ + if (index >= TX_FRAME_COUNT_GOOD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + TX_FRAME_COUNT_GOOD_ADDRESS + \ + index * TX_FRAME_COUNT_GOOD_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_tx_pause_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_pause_frames_u *value) +{ + if (index >= TX_PAUSE_FRAMES_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + TX_PAUSE_FRAMES_ADDRESS + \ + index * TX_PAUSE_FRAMES_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_tx_vlan_frames_good_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_vlan_frames_good_u *value) +{ + if (index >= TX_VLAN_FRAMES_GOOD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + TX_VLAN_FRAMES_GOOD_ADDRESS + \ + index * TX_VLAN_FRAMES_GOOD_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_tx_osize_frames_good_get( + a_uint32_t dev_id, + a_uint32_t index, + union tx_osize_frames_good_u *value) +{ + if (index >= TX_OSIZE_FRAMES_GOOD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + TX_OSIZE_FRAMES_GOOD_ADDRESS + \ + index * TX_OSIZE_FRAMES_GOOD_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_rx_frame_count_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_frame_count_good_bad_u *value) +{ + if (index >= RX_FRAME_COUNT_GOOD_BAD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + RX_FRAME_COUNT_GOOD_BAD_ADDRESS + \ + index * RX_FRAME_COUNT_GOOD_BAD_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_rx_octet_count_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_octet_count_good_bad_u *value) +{ + if (index >= RX_OCTET_COUNT_GOOD_BAD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + RX_OCTET_COUNT_GOOD_BAD_ADDRESS + \ + index * RX_OCTET_COUNT_GOOD_BAD_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_rx_octet_count_good_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_octet_count_good_u *value) +{ + if (index >= RX_OCTET_COUNT_GOOD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + RX_OCTET_COUNT_GOOD_ADDRESS + \ + index * RX_OCTET_COUNT_GOOD_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_rx_broadcast_frames_good_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_broadcast_frames_good_u *value) +{ + if (index >= RX_BROADCAST_FRAMES_GOOD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + RX_BROADCAST_FRAMES_GOOD_ADDRESS + \ + index * RX_BROADCAST_FRAMES_GOOD_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_rx_multicast_frames_good_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_multicast_frames_good_u *value) +{ + if (index >= RX_MULTICAST_FRAMES_GOOD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + RX_MULTICAST_FRAMES_GOOD_ADDRESS + \ + index * RX_MULTICAST_FRAMES_GOOD_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_rx_crc_error_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_crc_error_frames_u *value) +{ + if (index >= RX_CRC_ERROR_FRAMES_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + RX_CRC_ERROR_FRAMES_ADDRESS + \ + index * RX_CRC_ERROR_FRAMES_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_rx_alignment_error_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_crc_error_frames_u *value) +{ + if (index >= RX_ALIGNMENT_ERROR_FRAMES_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + RX_ALIGNMENT_ERROR_FRAMES_ADDRESS + \ + index * RX_ALIGNMENT_ERROR_FRAMES_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_rx_runt_error_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_runt_error_frames_u *value) +{ + if (index >= RX_RUNT_ERROR_FRAMES_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + RX_RUNT_ERROR_FRAMES_ADDRESS + \ + index * RX_RUNT_ERROR_FRAMES_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_rx_jabber_error_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_jabber_error_frames_u *value) +{ + if (index >= RX_JABBER_ERROR_FRAMES_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + RX_JABBER_ERROR_FRAMES_ADDRESS + \ + index * RX_JABBER_ERROR_FRAMES_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_rx_undersize_frames_good_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_undersize_frames_good_u *value) +{ + if (index >= RX_UNDERSIZE_FRAMES_GOOD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + RX_UNDERSIZE_FRAMES_GOOD_ADDRESS + \ + index * RX_UNDERSIZE_FRAMES_GOOD_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_rx_oversize_frames_good_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_oversize_frames_good_u *value) +{ + if (index >= RX_OVERSIZE_FRAMES_GOOD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + RX_OVERSIZE_FRAMES_GOOD_ADDRESS + \ + index * RX_OVERSIZE_FRAMES_GOOD_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_rx_64octets_frames_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_64octets_frames_good_bad_u *value) +{ + if (index >= RX_64OCTETS_FRAMES_GOOD_BAD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + RX_64OCTETS_FRAMES_GOOD_BAD_ADDRESS + \ + index * RX_64OCTETS_FRAMES_GOOD_BAD_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_rx_65to127octets_frames_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_65to127octets_frames_good_bad_u *value) +{ + if (index >= RX_65TO127OCTETS_FRAMES_GOOD_BAD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + RX_65TO127OCTETS_FRAMES_GOOD_BAD_ADDRESS + \ + index * RX_65TO127OCTETS_FRAMES_GOOD_BAD_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_rx_128to255octets_frames_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_128to255octets_frames_good_bad_u *value) +{ + if (index >= RX_128TO255OCTETS_FRAMES_GOOD_BAD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + RX_128TO255OCTETS_FRAMES_GOOD_BAD_ADDRESS + \ + index * RX_128TO255OCTETS_FRAMES_GOOD_BAD_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_rx_256to511octets_frames_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_256to511octets_frames_good_bad_u *value) +{ + if (index >= RX_256TO511OCTETS_FRAMES_GOOD_BAD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + RX_256TO511OCTETS_FRAMES_GOOD_BAD_ADDRESS + \ + index * RX_256TO511OCTETS_FRAMES_GOOD_BAD_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_rx_512to1023octets_frames_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_512to1023octets_frames_good_bad_u *value) +{ + if (index >= RX_512TO1023OCTETS_FRAMES_GOOD_BAD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + RX_512TO1023OCTETS_FRAMES_GOOD_BAD_ADDRESS + \ + index * RX_512TO1023OCTETS_FRAMES_GOOD_BAD_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_rx_1024tomaxoctets_frames_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_1024tomaxoctets_frames_good_bad_u *value) +{ + if (index >= RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_ADDRESS + \ + index * RX_1024TOMAXOCTETS_FRAMES_GOOD_BAD_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_rx_unicast_frames_good_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_unicast_frames_good_u *value) +{ + if (index >= RX_UNICAST_FRAMES_GOOD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + RX_UNICAST_FRAMES_GOOD_ADDRESS + \ + index * RX_UNICAST_FRAMES_GOOD_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_rx_length_error_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_length_error_frames_u *value) +{ + if (index >= RX_LENGTH_ERROR_FRAMES_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + RX_LENGTH_ERROR_FRAMES_ADDRESS + \ + index * RX_LENGTH_ERROR_FRAMES_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_rx_outofrange_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_outofrange_frames_u *value) +{ + if (index >= RX_OUTOFRANGE_FRAMES_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + RX_OUTOFRANGE_FRAMES_ADDRESS + \ + index * RX_OUTOFRANGE_FRAMES_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_rx_pause_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_pause_frames_u *value) +{ + if (index >= RX_PAUSE_FRAMES_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + RX_PAUSE_FRAMES_ADDRESS + \ + index * RX_PAUSE_FRAMES_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_rx_fifo_over_flow_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_fifo_over_flow_frames_u *value) +{ + if (index >= RX_FIFO_OVER_FLOW_FRAMES_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + RX_FIFOOVERFW_FRAMES_ADDRESS + \ + index * RX_FIFOOVERFW_FRAMES_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_rx_vlan_frames_good_bad_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_vlan_frames_good_bad_u *value) +{ + if (index >= RX_VLAN_FRAMES_GOOD_BAD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + RX_VLAN_FRAMES_GOOD_BAD_ADDRESS + \ + index * RX_VLAN_FRAMES_GOOD_BAD_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_rx_watchdog_error_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_watchdog_error_frames_u *value) +{ + if (index >= RX_WATCHDOG_ERROR_FRAMES_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + RX_WATCHDOG_ERROR_FRAMES_ADDRESS + \ + index * RX_WATCHDOG_ERROR_FRAMES_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_rx_receive_error_frames_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_receive_error_frames_u *value) +{ + if (index >= RX_RECEIVE_ERROR_FRAMES_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + RX_RECEIVE_ERROR_FRAMES_ADDRESS + \ + index * RX_RECEIVE_ERROR_FRAMES_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_rx_control_frames_good_get( + a_uint32_t dev_id, + a_uint32_t index, + union rx_control_frames_good_u *value) +{ + if (index >= RX_CONTROL_FRAMES_GOOD_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + RX_CONTROL_FRAMES_GOOD_ADDRESS + \ + index * RX_CONTROL_FRAMES_GOOD_INC, + (a_uint8_t *)&value->val, 4); +} diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/mp/mp_portctrl.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/mp/mp_portctrl.c new file mode 100755 index 000000000..e4931ce4a --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/mp/mp_portctrl.c @@ -0,0 +1,231 @@ +/* + * 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 "sw.h" +#include "hsl.h" +#include "scomphy_reg_access.h" +#include "mp_portctrl_reg.h" +#include "mp_portctrl.h" + +sw_error_t +mp_mac_configuration_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_configuration_u *value) +{ + if (index >= MAC_CONFIGURATION_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + MAC_CONFIGURATION_ADDRESS + \ + index * MAC_CONFIGURATION_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_mac_configuration_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_configuration_u *value) +{ + if (index >= MAC_CONFIGURATION_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_set( + dev_id, + MAC_CONFIGURATION_ADDRESS + \ + index * MAC_CONFIGURATION_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_mac_frame_filter_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_frame_filter_u *value) +{ + if (index >= MAC_FRAME_FILTER_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + MAC_FRAME_FILTER_ADDRESS + \ + index * MAC_FRAME_FILTER_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_mac_frame_filter_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_frame_filter_u *value) +{ + if (index >= MAC_FRAME_FILTER_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_set( + dev_id, + MAC_FRAME_FILTER_ADDRESS + \ + index * MAC_FRAME_FILTER_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_mac_flowctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_flow_ctrl_u *value) +{ + if (index >= MAC_FLOW_CTRL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + MAC_FLOW_CTRL_ADDRESS + \ + index * MAC_FLOW_CTRL_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_mac_flowctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_flow_ctrl_u *value) +{ + if (index >= MAC_FLOW_CTRL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_set( + dev_id, + MAC_FLOW_CTRL_ADDRESS + \ + index * MAC_FLOW_CTRL_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_mac_lpi_ctrl_status_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_lpi_ctrl_status_u *value) +{ + if (index >= MAC_LPI_CTRL_STATUS_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + MAC_LPI_CTRL_STATUS_ADDRESS + \ + index * MAC_LPI_CTRL_STATUS_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_mac_lpi_ctrl_status_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_lpi_ctrl_status_u *value) +{ + if (index >= MAC_LPI_CTRL_STATUS_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_set( + dev_id, + MAC_LPI_CTRL_STATUS_ADDRESS + \ + index * MAC_LPI_CTRL_STATUS_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_mac_lpi_timer_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_lpi_timer_ctrl_u *value) +{ + if (index >= MAC_LPI_TIMER_CTRL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + MAC_LPI_TIMER_CTRL_ADDRESS + \ + index * MAC_LPI_TIMER_CTRL_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_mac_lpi_timer_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_lpi_timer_ctrl_u *value) +{ + if (index >= MAC_LPI_TIMER_CTRL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_set( + dev_id, + MAC_LPI_TIMER_CTRL_ADDRESS + \ + index * MAC_LPI_TIMER_CTRL_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_mac_max_frame_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_max_frame_ctrl_u *value) +{ + if (index >= MAC_MAX_FRAME_CTRL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + MAC_MAX_FRAME_CTRL_ADDRESS + \ + index * MAC_MAX_FRAME_CTRL_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_mac_max_frame_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_max_frame_ctrl_u *value) +{ + if (index >= MAC_MAX_FRAME_CTRL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_set( + dev_id, + MAC_MAX_FRAME_CTRL_ADDRESS + \ + index * MAC_MAX_FRAME_CTRL_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_mac_operation_mode_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union mac_operation_mode_ctrl_u *value) +{ + if (index >= MAC_OPERATION_MODE_CTRL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_get( + dev_id, + MAC_OPERATION_MODE_CTRL_ADDRESS + \ + index * MAC_OPERATION_MODE_CTRL_INC, + (a_uint8_t *)&value->val, 4); +} + +sw_error_t +mp_mac_operation_mode_ctrl_set( + a_uint32_t dev_id, + a_uint32_t index, + union mac_operation_mode_ctrl_u *value) +{ + if (index >= MAC_OPERATION_MODE_CTRL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return scomphy_reg_set( + dev_id, + MAC_OPERATION_MODE_CTRL_ADDRESS + \ + index * MAC_OPERATION_MODE_CTRL_INC, + (a_uint8_t *)&value->val, 4); +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/mp/mp_uniphy.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/mp/mp_uniphy.c new file mode 100755 index 000000000..5d49a7e97 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/mp/mp_uniphy.c @@ -0,0 +1,55 @@ +/* + * 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. + */ + +/** + * @defgroup + * @{ + */ + +#include "sw.h" +#include "hppe_reg_access.h" +#include "mp_uniphy_reg.h" +#include "mp_uniphy.h" + +sw_error_t +mp_uniphy_clock_output_control_get( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_clock_output_control_u *value) +{ + if (index >= UNIPHY_CLOCK_OUTPUT_CONTROL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_uniphy_reg_get( + dev_id, + NSS_UNIPHY_BASE_ADDR + UNIPHY_CLOCK_OUTPUT_CONTROL_ADDRESS, + index * UNIPHY_CLOCK_OUTPUT_CONTROL_INC, + &value->val); +} + +sw_error_t +mp_uniphy_clock_output_control_set( + a_uint32_t dev_id, + a_uint32_t index, + union uniphy_clock_output_control_u *value) +{ + if (index >= UNIPHY_CLOCK_OUTPUT_CONTROL_MAX_ENTRY) + return SW_OUT_OF_RANGE; + return hppe_uniphy_reg_set( + dev_id, + NSS_UNIPHY_BASE_ADDR + UNIPHY_CLOCK_OUTPUT_CONTROL_ADDRESS, + index * UNIPHY_CLOCK_OUTPUT_CONTROL_INC, + value->val); +} diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/Makefile b/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/Makefile new file mode 100644 index 000000000..51d6d0b2e --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/Makefile @@ -0,0 +1,96 @@ +LOC_DIR=src/hsl/phy +LIB=HSL + +include $(PRJ_PATH)/make/config.mk + +ifeq (ATHENA, $(CHIP_TYPE)) + SRC_LIST = f2_phy.c +endif + +ifeq (GARUDA, $(CHIP_TYPE)) + SRC_LIST = f1_phy.c +endif + +ifeq (SHIVA, $(CHIP_TYPE)) + SRC_LIST = f2_phy.c +endif + +ifeq (HORUS, $(CHIP_TYPE)) + SRC_LIST = f2_phy.c +endif + +ifeq (ISIS, $(CHIP_TYPE)) + SRC_LIST = f1_phy.c +endif + +ifeq (MP, $(CHIP_TYPE)) + SRC_LIST = mpge_phy.c +ifeq (TRUE, $(IN_LED)) + SRC_LIST += mpge_led.c +endif +endif + +ifneq (,$(filter ISISC, $(SUPPORT_CHIP))) + SRC_LIST += f1_phy.c +endif + +ifeq (TRUE, $(IN_MALIBU_PHY)) + SRC_LIST += malibu_phy.c +endif + +ifeq (ALL_CHIP, $(CHIP_TYPE)) + SRC_LIST = f1_phy.c f2_phy.c malibu_phy.c +ifneq (,$(filter MP, $(SUPPORT_CHIP))) + SRC_LIST += mpge_phy.c +ifeq (TRUE, $(IN_LED)) + SRC_LIST += mpge_led.c +endif +endif +endif + +ifeq (NONHK_CHIP, $(CHIP_TYPE)) + SRC_LIST = f1_phy.c f2_phy.c malibu_phy.c +endif + +ifeq (TRUE, $(IN_AQUANTIA_PHY)) + SRC_LIST += aquantia_phy.c +endif + +ifeq (TRUE, $(IN_QCA803X_PHY)) + SRC_LIST += qca803x_phy.c +endif + +ifeq (TRUE, $(IN_QCA808X_PHY)) + SRC_LIST += qca808x_phy.c + SRC_LIST += qca808x.c +ifeq (TRUE, $(IN_LED)) + SRC_LIST += qca808x_led.c +endif +ifeq (TRUE, $(IN_PTP)) + SRC_LIST += qca808x_ptp.c + SRC_LIST += qca808x_ptp_api.c +ifeq ($(CONFIG_PTP_1588_CLOCK), y) + SRC_LIST += qca808x_phc.c +endif +endif +endif + +ifeq (TRUE, $(IN_SFP_PHY)) + SRC_LIST += sfp_phy.c +endif + +SRC_LIST += hsl_phy.c + +ifeq (linux, $(OS)) + ifeq (KSLIB, $(MODULE_TYPE)) + ifneq (TRUE, $(KERNEL_MODE)) + SRC_LIST= + endif + endif +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/src/src/hsl/phy/aquantia_phy.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/aquantia_phy.c new file mode 100755 index 000000000..1a1f9ab64 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/aquantia_phy.c @@ -0,0 +1,2205 @@ +/* + * 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. + */ + +#include "sw.h" +#include "fal_port_ctrl.h" +#include "hsl_api.h" +#include "hsl.h" +#include "aquantia_phy.h" +#include "hsl_phy.h" +#include "ssdk_plat.h" + +/* #define aquantia_phy_reg_read _phy_reg_read */ +/* #define aquantia_phy_reg_write _phy_reg_write */ + +/****************************************************************************** +* +* aquantia_phy_mii_read - mii register read +* +* mii register read +*/ +static sw_error_t +aquantia_phy_reg_read(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t reg_mmd, + a_uint32_t reg_id, a_uint16_t *phy_data) +{ + sw_error_t rv; + + reg_id = AQUANTIA_REG_ADDRESS(reg_mmd, reg_id); + HSL_PHY_GET(rv, dev_id, phy_id, reg_id, phy_data); + + return rv; +} + +/****************************************************************************** +* +* aquantia_phy_mii_write - mii register write +* +* mii register write +*/ +static sw_error_t +aquantia_phy_reg_write(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t reg_mmd, + a_uint32_t reg_id, a_uint16_t reg_val) +{ + sw_error_t rv; + + reg_id = AQUANTIA_REG_ADDRESS(reg_mmd, reg_id); + HSL_PHY_SET(rv, dev_id, phy_id, reg_id, reg_val); + + return rv; +} +#ifndef IN_PORTCONTROL_MINI +/****************************************************************************** +* +* aquantia_phy_get_phy_id - get the phy id +* +*/ +sw_error_t +aquantia_phy_get_phy_id(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *phy_data) +{ + sw_error_t rv; + a_uint16_t org_id, rev_id; + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_PHY_XS_REGISTERS, + AQUANTIA_PHY_ID1, &org_id); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_PHY_XS_REGISTERS, + AQUANTIA_PHY_ID2, &rev_id); + SW_RTN_ON_ERROR(rv); + + *phy_data = ((org_id & 0xffff) << 16) | (rev_id & 0xffff); + + return rv; +} +#endif +sw_error_t +aquantia_phy_get_speed(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_speed_t * speed) +{ + a_uint16_t phy_data; + sw_error_t rv = SW_OK; + a_bool_t link_status; + + link_status = aquantia_phy_get_link_status(dev_id, phy_id); + if (link_status != A_TRUE) { + /*the speed register(0x4007c800) is not stable when aquantia phy is down, + but some APIs such as aquantia_phy_set_duplex() aquantia_phy_interface_set_mode() + need to get the speed, so set the speed default value as 100M when link down*/ + *speed = FAL_SPEED_100; + return SW_OK; + } + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_REG_AUTONEG_VENDOR_STATUS, &phy_data); + SW_RTN_ON_ERROR(rv); + switch ((phy_data & AQUANTIA_STATUS_SPEED_MASK) >> 1) { + case AQUANTIA_STATUS_SPEED_100MBS: + *speed = FAL_SPEED_100; + break; + case AQUANTIA_STATUS_SPEED_1000MBS: + *speed = FAL_SPEED_1000; + break; + case AQUANTIA_STATUS_SPEED_10000MBS: + *speed = FAL_SPEED_10000; + break; + case AQUANTIA_STATUS_SPEED_2500MBS: + *speed = FAL_SPEED_2500; + break; + case AQUANTIA_STATUS_SPEED_5000MBS: + *speed = FAL_SPEED_5000; + break; + default: + return SW_READ_ERROR; + } + + return rv; +} + +/****************************************************************************** +* +* aquantia_phy_get_duplex - Determines the speed of phy ports associated with the +* specified device. +*/ +sw_error_t +aquantia_phy_get_duplex(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_duplex_t * duplex) +{ + a_uint16_t phy_data; + sw_error_t rv = SW_OK; + a_bool_t link_status; + + link_status = aquantia_phy_get_link_status(dev_id, phy_id); + if (link_status != A_TRUE) + { + return SW_OK; + } + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_REG_AUTONEG_VENDOR_STATUS, &phy_data); + SW_RTN_ON_ERROR(rv); + //read duplex + if (phy_data & AQUANTIA_STATUS_FULL_DUPLEX) + { + *duplex = FAL_FULL_DUPLEX; + } + else + { + *duplex = FAL_HALF_DUPLEX; + } + + return rv; +} +#ifndef IN_PORTCONTROL_MINI +/****************************************************************************** +* +* aquantia_phy_reset - reset the phy +* +* reset the phy +*/ +sw_error_t aquantia_phy_reset(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + sw_error_t rv = SW_OK; + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_GLOBAL_REGISTERS, + AQUANTIA_GLOBAL_STANDARD_CONTROL1, &phy_data); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_GLOBAL_REGISTERS, + AQUANTIA_GLOBAL_STANDARD_CONTROL1, phy_data | AQUANTIA_CTRL_SOFTWARE_RESET); + aos_mdelay(100); + + return rv; +} + +/****************************************************************************** +* +* aquantia_phy_set_powersave - set power saving status +* +* set power saving status +*/ +sw_error_t +aquantia_phy_set_powersave(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable) +{ + a_uint16_t phy_data; + sw_error_t rv; + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_GLOBAL_REGISTERS, + AQUANTIA_GLOBAL_RESERVED_PROVISIONING6, &phy_data); + SW_RTN_ON_ERROR(rv); + if (enable == A_TRUE) + { + phy_data |= AQUANTIA_POWER_SAVE; + } + else + { + phy_data &= ~AQUANTIA_POWER_SAVE; + } + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_GLOBAL_REGISTERS, + AQUANTIA_GLOBAL_RESERVED_PROVISIONING6,phy_data); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_restart_autoneg(dev_id, phy_id); + + return rv; +} + +/****************************************************************************** +* +* aquantia_phy_get_powersave - get power saving status +* +* set power saving status +*/ +sw_error_t +aquantia_phy_get_powersave(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t * enable) +{ + a_uint16_t phy_data; + sw_error_t rv = SW_OK; + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_GLOBAL_REGISTERS, + AQUANTIA_GLOBAL_RESERVED_PROVISIONING6, &phy_data); + SW_RTN_ON_ERROR(rv); + if (phy_data& AQUANTIA_POWER_SAVE) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return rv; +} + +/****************************************************************************** +* +* aquantia_phy_set_mdix - +* +* set phy mdix configuraiton +*/ +sw_error_t +aquantia_phy_set_mdix(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_mdix_mode_t mode) +{ + a_uint16_t phy_data; + sw_error_t rv = SW_OK; + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_RESERVED_VENDOR_PROVISIONING1, &phy_data); + SW_RTN_ON_ERROR(rv); + phy_data &= ~(BITS(0,2)); + switch(mode) + { + case PHY_MDIX_AUTO: + phy_data |= AQUANTIA_PHY_MDIX_AUTO; + break; + case PHY_MDIX_MDIX: + phy_data |= AQUANTIA_PHY_MDIX; + break; + case PHY_MDIX_MDI: + phy_data |= AQUANTIA_PHY_MDI; + break; + default: + return SW_BAD_PARAM; + } + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_RESERVED_VENDOR_PROVISIONING1,phy_data); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_restart_autoneg(dev_id, phy_id); + + return rv; +} + +/****************************************************************************** +* +* aquantia_phy_get_mdix +* +* get phy mdix configuration +*/ +sw_error_t +aquantia_phy_get_mdix(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_mdix_mode_t * mode) +{ + a_uint16_t phy_data; + sw_error_t rv = SW_OK; + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_RESERVED_VENDOR_PROVISIONING1,&phy_data); + SW_RTN_ON_ERROR(rv); + phy_data &= BITS(0,2); + switch(phy_data) + { + case AQUANTIA_PHY_MDIX_AUTO: + *mode = PHY_MDIX_AUTO; + break; + case AQUANTIA_PHY_MDIX: + *mode = PHY_MDIX_MDIX; + break; + case AQUANTIA_PHY_MDI: + *mode = PHY_MDIX_MDI; + break; + default: + return SW_NOT_SUPPORTED; + } + + return rv; +} + +/****************************************************************************** +* +* aquantia_phy_get_mdix status +* +* get phy mdix status +*/ +sw_error_t +aquantia_phy_get_mdix_status(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_mdix_status_t * mode) +{ + a_uint16_t phy_data; + sw_error_t rv = SW_OK; + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_RESERVED_VENDOR_STATUS1, &phy_data); + SW_RTN_ON_ERROR(rv); + *mode = (phy_data & AQUANTIA_PHY_MDIX_STATUS) ? PHY_MDIX_STATUS_MDIX : + PHY_MDIX_STATUS_MDI; + + return rv; +} + +/****************************************************************************** +* +* aquantia_phy_set_local_loopback +* +* set phy local loopback +*/ +sw_error_t +aquantia_phy_set_local_loopback(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t enable) +{ + a_uint16_t phy_data; + fal_port_speed_t old_speed; + sw_error_t rv = SW_OK; + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_PHY_XS_REGISTERS, + AQUANTIA_PHY_XS_TRANAMIT_RESERVED_VENDOR_PROVISION5, &phy_data); + SW_RTN_ON_ERROR(rv); + if (enable == A_TRUE) + { + phy_data |= AQUANTIA_INTERNAL_LOOPBACK; + rv = aquantia_phy_get_speed(dev_id, phy_id, &old_speed); + SW_RTN_ON_ERROR(rv); + switch(old_speed) + { + case FAL_SPEED_100: + phy_data |= AQUANTIA_100M_LOOPBACK; + break; + case FAL_SPEED_1000: + phy_data |= AQUANTIA_1000M_LOOPBACK; + break; + case FAL_SPEED_10000: + phy_data |= AQUANTIA_10000M_LOOPBACK; + break; + case FAL_SPEED_2500: + phy_data |= AQUANTIA_2500M_LOOPBACK; + break; + case FAL_SPEED_5000: + phy_data |= AQUANTIA_5000M_LOOPBACK; + break; + default: + return SW_FAIL; + } + } + else + { + phy_data &= ~(AQUANTIA_INTERNAL_LOOPBACK | AQUANTIA_ALL_SPEED_LOOPBACK); + } + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_PHY_XS_REGISTERS, + AQUANTIA_PHY_XS_TRANAMIT_RESERVED_VENDOR_PROVISION5,phy_data); + + return rv; +} + +/****************************************************************************** +* +* aquantia_phy_get_local_loopback +* +* get phy local loopback +*/ +sw_error_t +aquantia_phy_get_local_loopback(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t * enable) +{ + a_uint16_t phy_data; + sw_error_t rv = SW_OK; + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_PHY_XS_REGISTERS, + AQUANTIA_PHY_XS_TRANAMIT_RESERVED_VENDOR_PROVISION5, &phy_data); + SW_RTN_ON_ERROR(rv); + if (phy_data & AQUANTIA_INTERNAL_LOOPBACK) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return rv; +} + +sw_error_t +aquantia_phy_set_remote_loopback(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t enable) +{ + a_uint16_t phy_data; + fal_port_speed_t speed; + sw_error_t rv = SW_OK; + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_PHY_XS_REGISTERS, + AQUANTIA_PHY_XS_TRANAMIT_RESERVED_VENDOR_PROVISION5, &phy_data); + SW_RTN_ON_ERROR(rv); + + if (enable == A_TRUE) + { + rv = aquantia_phy_get_speed(dev_id, phy_id, &speed); + SW_RTN_ON_ERROR(rv); + switch(speed) + { + case FAL_SPEED_100: + phy_data |= AQUANTIA_100M_LOOPBACK; + break; + case FAL_SPEED_1000: + phy_data |= AQUANTIA_1000M_LOOPBACK; + break; + case FAL_SPEED_2500: + phy_data |= AQUANTIA_2500M_LOOPBACK; + break; + case FAL_SPEED_5000: + phy_data |= AQUANTIA_5000M_LOOPBACK; + break; + case FAL_SPEED_10000: + phy_data |= AQUANTIA_10000M_LOOPBACK; + break; + default: + break; + } + phy_data |= AQUANTIA_PHY_REMOTE_LOOPBACK; + } + else + { + phy_data &= ~(AQUANTIA_PHY_REMOTE_LOOPBACK |AQUANTIA_ALL_SPEED_LOOPBACK); + } + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_PHY_XS_REGISTERS, + AQUANTIA_PHY_XS_TRANAMIT_RESERVED_VENDOR_PROVISION5, phy_data); + + return rv; +} + +/****************************************************************************** +* +* aquantia_phy_get_remote_loopback +* +* get phy remote loopback +*/ +sw_error_t +aquantia_phy_get_remote_loopback(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t * enable) +{ + a_uint16_t phy_data; + sw_error_t rv = SW_OK; + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_PHY_XS_REGISTERS, + AQUANTIA_PHY_XS_TRANAMIT_RESERVED_VENDOR_PROVISION5, &phy_data); + SW_RTN_ON_ERROR(rv); + if (phy_data & AQUANTIA_PHY_REMOTE_LOOPBACK) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return rv; +} + +/****************************************************************************** +* +* aquantia_phy_cdt - cable diagnostic test +* +* cable diagnostic test +*/ +static inline fal_cable_status_t _phy_cdt_status_mapping(a_uint32_t pair_type, a_uint16_t status) +{ + fal_cable_status_t status_mapping = FAL_CABLE_STATUS_INVALID; + + switch(status) + { + case 0: + status_mapping = FAL_CABLE_STATUS_NORMAL; + break; + case 1: + if(pair_type == CABLE_PAIR_B) + status_mapping = FAL_CABLE_STATUS_CROSSOVERA; + else if(pair_type == CABLE_PAIR_C) + status_mapping = FAL_CABLE_STATUS_CROSSOVERB; + else if(pair_type == CABLE_PAIR_D) + status_mapping = FAL_CABLE_STATUS_CROSSOVERC; + else + status_mapping = FAL_CABLE_STATUS_INVALID; + break; + case 2: + if(pair_type == CABLE_PAIR_C) + status_mapping = FAL_CABLE_STATUS_CROSSOVERA; + else if(pair_type == CABLE_PAIR_D) + status_mapping = FAL_CABLE_STATUS_CROSSOVERB; + else + status_mapping = FAL_CABLE_STATUS_INVALID; + break; + case 3: + if(pair_type == CABLE_PAIR_D) + status_mapping = FAL_CABLE_STATUS_CROSSOVERA; + else + status_mapping = FAL_CABLE_STATUS_INVALID; + break; + case 4: + status_mapping = FAL_CABLE_STATUS_SHORT; + break; + case 5: + status_mapping = FAL_CABLE_STATUS_LOW_MISMATCH; + break; + case 6: + status_mapping = FAL_CABLE_STATUS_HIGH_MISMATCH; + break; + case 7: + status_mapping = FAL_CABLE_STATUS_OPENED; + break; + default: + status_mapping = FAL_CABLE_STATUS_INVALID; + break; + } + + return status_mapping; +} + +sw_error_t +aquantia_phy_cdt_get(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_cdt_t * port_cdt) +{ + a_uint16_t status = 0; + sw_error_t rv = SW_OK; + a_uint16_t phy_data; + + if ((!port_cdt) || (phy_id > 7)) { + return SW_FAIL; + } + /* Get cable status */ + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_GLOBAL_REGISTERS, + AQUANTIA_CABLE_DIAGNOSTIC_STATUS1, &status); + SW_RTN_ON_ERROR(rv); + port_cdt->pair_a_status = (status & AQUANTIA_CABLE_DIAGNOSTIC_STATUS_PAIRA) >> 12 + & BITS(0, 3); + port_cdt->pair_b_status = (status & AQUANTIA_CABLE_DIAGNOSTIC_STATUS_PAIRB) >> 8 + & BITS(0, 3); + port_cdt->pair_c_status = (status & AQUANTIA_CABLE_DIAGNOSTIC_STATUS_PAIRC) >> 4 + & BITS(0, 3); + port_cdt->pair_d_status = (status & AQUANTIA_CABLE_DIAGNOSTIC_STATUS_PAIRD) + & BITS(0, 3); + SSDK_DEBUG("status:%x, pair_a_status:%x,pair_b_status:%x,pair_c_status:%x, pair_d_status:%x\n", + status, port_cdt->pair_a_status,port_cdt->pair_b_status, + port_cdt->pair_c_status, port_cdt->pair_d_status); + /* Get Cable Length value */ + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_GLOBAL_REGISTERS, + AQUANTIA_CABLE_DIAGNOSTIC_STATUS2, &phy_data); + SW_RTN_ON_ERROR(rv); + port_cdt->pair_a_len = phy_data >> 8 & BITS(0, 8); + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_GLOBAL_REGISTERS, + AQUANTIA_CABLE_DIAGNOSTIC_STATUS4, &phy_data); + SW_RTN_ON_ERROR(rv); + port_cdt->pair_b_len = phy_data >> 8 & BITS(0, 8); + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_GLOBAL_REGISTERS, + AQUANTIA_CABLE_DIAGNOSTIC_STATUS6, &phy_data); + SW_RTN_ON_ERROR(rv); + port_cdt->pair_c_len = phy_data >> 8 & BITS(0, 8); + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_GLOBAL_REGISTERS, + AQUANTIA_CABLE_DIAGNOSTIC_STATUS8, &phy_data); + SW_RTN_ON_ERROR(rv); + port_cdt->pair_d_len = phy_data >> 8 & BITS(0, 8); + + return rv; +} + +sw_error_t aquatia_phy_cdt_start(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t status = 0, phy_data = 0; + a_uint32_t aq_phy_id; + a_uint16_t ii = 300; + sw_error_t rv = SW_OK; + + /*select mode0 if aq107, and select mode2 if aq109*/ + rv = aquantia_phy_get_phy_id(dev_id, phy_id, &aq_phy_id); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_GLOBAL_REGISTERS, + AQUANTIA_GLOBAL_CDT_CONTROL, &phy_data); + SW_RTN_ON_ERROR(rv); + if(aq_phy_id == AQUANTIA_PHY_109) + { + phy_data |= AQUANTIA_PHY_CDT_MODE2; + } + else + { + phy_data |= AQUANTIA_PHY_CDT_MODE0; + } + + phy_data |= AQUANTIA_NORMAL_CABLE_DIAGNOSTICS; + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_GLOBAL_REGISTERS, + AQUANTIA_GLOBAL_CDT_CONTROL, phy_data); + SW_RTN_ON_ERROR(rv); + do { + aos_mdelay(30); + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_GLOBAL_REGISTERS, + AQUANTIA_GLOBAL_GENERAL_STATUS, &status); + SW_RTN_ON_ERROR(rv); + } + while ((status & AQUANTIA_CABLE_DIAGNOSTICS_STATUS) && (--ii)); + + return rv; +} + +sw_error_t +aquantia_phy_cdt(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t mdi_pair, + fal_cable_status_t * cable_status, a_uint32_t * cable_len) +{ + fal_port_cdt_t aquantia_port_cdt; + sw_error_t rv = SW_OK; + + if ((mdi_pair >= 4) || (phy_id > 7)) { + return SW_BAD_PARAM; + } + rv = aquatia_phy_cdt_start(dev_id, phy_id); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_cdt_get(dev_id, phy_id, &aquantia_port_cdt); + SW_RTN_ON_ERROR(rv); + switch (mdi_pair) + { + case 0: + *cable_status = + _phy_cdt_status_mapping(CABLE_PAIR_A, aquantia_port_cdt.pair_a_status); + /* Get Cable Length value */ + *cable_len = aquantia_port_cdt.pair_a_len; + break; + case 1: + *cable_status = + _phy_cdt_status_mapping(CABLE_PAIR_B, aquantia_port_cdt.pair_b_status); + /* Get Cable Length value */ + *cable_len = aquantia_port_cdt.pair_b_len; + break; + case 2: + *cable_status = + _phy_cdt_status_mapping(CABLE_PAIR_C, aquantia_port_cdt.pair_c_status); + /* Get Cable Length value */ + *cable_len = aquantia_port_cdt.pair_c_len; + break; + case 3: + *cable_status = + _phy_cdt_status_mapping(CABLE_PAIR_D, aquantia_port_cdt.pair_d_status); + /* Get Cable Length value */ + *cable_len = aquantia_port_cdt.pair_d_len; + break; + default: + break; + } + + return rv; +} +#endif +/****************************************************************************** +* +* AQUANTIA_autoneg_done +* +* AQUANTIA_autoneg_done +*/ +a_bool_t aquantia_autoneg_done(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + a_uint16_t ii = 200; + sw_error_t rv = SW_OK; + + do { + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_STANDARD_STATUS1, &phy_data); + SW_RTN_ON_ERROR(rv); + aos_mdelay(10); + } + while ((!AQUANTIA_AUTONEG_DONE(phy_data)) && --ii); + + if (ii == 0) + return A_FALSE; + + return A_TRUE; +} +#ifndef IN_PORTCONTROL_MINI +/****************************************************************************** +* +* aquantia_phy_get_ability - get the phy ability +* +* +*/ +sw_error_t +aquantia_phy_get_partner_ability(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * ability) +{ + a_uint16_t phy_data; + sw_error_t rv = SW_OK; + + *ability = 0; + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_LINK_PARTNER_ABILITY, &phy_data); + SW_RTN_ON_ERROR(rv); + if (phy_data & AQUANTIA_LINK_10BASETX_HALF_DUPLEX) + { + *ability |= FAL_PHY_PART_10T_HD; + } + if (phy_data & AQUANTIA_LINK_10BASETX_FULL_DUPLEX) + { + *ability |= FAL_PHY_PART_10T_FD; + } + if (phy_data & AQUANTIA_LINK_100BASETX_HALF_DUPLEX) + { + *ability |= FAL_PHY_PART_100TX_HD; + } + if (phy_data & AQUANTIA_LINK_100BASETX_FULL_DUPLEX) + { + *ability |= FAL_PHY_PART_100TX_FD; + } + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_LINK_PARTNER_5G_ABILITY, &phy_data); + SW_RTN_ON_ERROR(rv); + if (phy_data & AQUANTIA_LINK_1000BASETX_FULL_DUPLEX) + { + *ability |= FAL_PHY_PART_1000T_FD; + } + if (phy_data & AQUANTIA_LINK_5000BASETX_FULL_DUPLEX) + { + *ability |= FAL_PHY_PART_5000T_FD; + } + if (phy_data & AQUANTIA_LINK_2500BASETX_FULL_DUPLEX) + { + *ability |= FAL_PHY_PART_2500T_FD; + } + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_LINK_PARTNER_10G_ABILITY, &phy_data); + if (phy_data & AQUANTIA_LINK_10000BASETX_FULL_DUPLEX) + { + *ability |= FAL_PHY_PART_10000T_FD; + } + + return rv; +} +#endif +/****************************************************************************** +* +* aquantia_phy_status - test to see if the specified phy link is alive +* +* RETURNS: +* A_TRUE --> link is alive +* A_FALSE --> link is down +*/ +a_bool_t aquantia_phy_get_link_status(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + sw_error_t rv = SW_OK; + + /*in order to get the link status of real time, need to read the link status two times */ + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_STANDARD_STATUS1, &phy_data); + if(rv != SW_OK) + { + return A_FALSE; + } + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_STANDARD_STATUS1, &phy_data); + if(rv != SW_OK) + { + return A_FALSE; + } + if (phy_data & AQUANTIA_STATUS_LINK) + { + return A_TRUE; + } + + return A_FALSE; +} + +/****************************************************************************** +* +* AQUANTIA_set_autoneg_adv - set the phy autoneg Advertisement +* +*/ +sw_error_t +aquantia_phy_set_autoneg_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t autoneg) +{ + a_uint16_t phy_data = 0, phy_data1 = 0 ; + sw_error_t rv = SW_OK; + + if ((autoneg & FAL_PHY_ADV_10T_FD) ||(autoneg & FAL_PHY_ADV_10T_HD)|| + (autoneg & FAL_PHY_ADV_100TX_HD)) + { + return SW_NOT_SUPPORTED; + } + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_ADVERTISEMENT_REGISTER, &phy_data); + SW_RTN_ON_ERROR(rv); + phy_data &= ~AQUANTIA_ADVERTISE_MEGA_ALL; + phy_data &= + ~(AQUANTIA_ADVERTISE_PAUSE | AQUANTIA_ADVERTISE_ASYM_PAUSE); + if (autoneg & FAL_PHY_ADV_100TX_FD) + { + phy_data |= AQUANTIA_ADVERTISE_100FULL; + } + if (autoneg & FAL_PHY_ADV_PAUSE) + { + phy_data |= AQUANTIA_ADVERTISE_PAUSE; + } + if (autoneg & FAL_PHY_ADV_ASY_PAUSE) + { + phy_data |= AQUANTIA_ADVERTISE_ASYM_PAUSE; + } + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_ADVERTISEMENT_REGISTER, phy_data); + SW_RTN_ON_ERROR(rv); + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_VENDOR_PROVISION1, &phy_data); + SW_RTN_ON_ERROR(rv); + phy_data &= ~AQUANTIA_ADVERTISE_GIGA_ALL; + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_10GBASE_T_CONTROL_REGISTER, &phy_data1); + SW_RTN_ON_ERROR(rv); + phy_data1 &= ~AQUANTIA_ADVERTISE_GIGA_PLUS_ALL; + if (autoneg & FAL_PHY_ADV_1000T_FD) + { + phy_data |= AQUANTIA_ADVERTISE_1000FULL; + } + if (autoneg & FAL_PHY_ADV_2500T_FD) + { + phy_data |= AQUANTIA_ADVERTISE_2500FULL; + phy_data1 |= AQUANTIA_ADVERTISE_8023BZ_2500FULL; + } + if (autoneg & FAL_PHY_ADV_5000T_FD) + { + phy_data |= AQUANTIA_ADVERTISE_5000FULL; + phy_data1 |= AQUANTIA_ADVERTISE_8023BZ_5000FULL; + } + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_VENDOR_PROVISION1, phy_data); + SW_RTN_ON_ERROR(rv); + + if (autoneg & FAL_PHY_ADV_10000T_FD) + phy_data1 |= AQUANTIA_ADVERTISE_10000FULL; + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_10GBASE_T_CONTROL_REGISTER,phy_data1); + + return rv; +} + +/****************************************************************************** +* +* AQUANTIA_get_autoneg_adv - get the phy autoneg Advertisement +* +*/ +sw_error_t +aquantia_phy_get_autoneg_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * autoneg) +{ + a_uint16_t phy_data = 0, phy_data1 = 0; + sw_error_t rv = SW_OK; + + *autoneg = 0; + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_ADVERTISEMENT_REGISTER, &phy_data); + SW_RTN_ON_ERROR(rv); + if (phy_data & AQUANTIA_ADVERTISE_100FULL) + { + *autoneg |= FAL_PHY_ADV_100TX_FD; + } + if (phy_data & AQUANTIA_ADVERTISE_PAUSE) + { + *autoneg |= FAL_PHY_ADV_PAUSE; + } + if (phy_data & AQUANTIA_ADVERTISE_ASYM_PAUSE) + { + *autoneg |= FAL_PHY_ADV_ASY_PAUSE; + } + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_VENDOR_PROVISION1, &phy_data); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_10GBASE_T_CONTROL_REGISTER, &phy_data1); + SW_RTN_ON_ERROR(rv); + if (phy_data & AQUANTIA_ADVERTISE_1000FULL) + { + *autoneg |= FAL_PHY_ADV_1000T_FD; + } + if ((phy_data & AQUANTIA_ADVERTISE_2500FULL) && + (phy_data1 & AQUANTIA_ADVERTISE_8023BZ_2500FULL)) + { + *autoneg |= FAL_PHY_ADV_2500T_FD; + } + if ((phy_data & AQUANTIA_ADVERTISE_5000FULL) && + (phy_data1 & AQUANTIA_ADVERTISE_8023BZ_5000FULL)) + { + *autoneg |= FAL_PHY_ADV_5000T_FD; + } + + if (phy_data1 & AQUANTIA_ADVERTISE_10000FULL) + { + *autoneg |= FAL_PHY_ADV_10000T_FD; + } + + return rv; +} + +/****************************************************************************** +* +* aquantia_phy_enable_autonego +* +*/ +a_bool_t aquantia_phy_autoneg_status(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + sw_error_t rv = SW_OK; + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_STANDARD_CONTROL1, &phy_data); + SW_RTN_ON_ERROR(rv); + if (phy_data & AQUANTIA_CTRL_AUTONEGOTIATION_ENABLE) + { + return A_TRUE; + } + + return A_FALSE; +} +/****************************************************************************** +* +* AQUANTIA_restart_autoneg - restart the phy autoneg +* +*/ +sw_error_t aquantia_phy_restart_autoneg(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data = 0; + sw_error_t rv = SW_OK; + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_PHY_XS_REGISTERS, + AQUANTIA_PHY_XS_USX_TRANSMIT, &phy_data); + SW_RTN_ON_ERROR(rv); + if (!(phy_data & AQUANTIA_PHY_USX_AUTONEG_ENABLE)) + { + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_PHY_XS_REGISTERS, + AQUANTIA_PHY_XS_USX_TRANSMIT, + phy_data | AQUANTIA_PHY_USX_AUTONEG_ENABLE); + SW_RTN_ON_ERROR(rv); + } + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_STANDARD_CONTROL1, &phy_data); + phy_data |= AQUANTIA_CTRL_AUTONEGOTIATION_ENABLE; + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_STANDARD_CONTROL1, + phy_data | AQUANTIA_CTRL_RESTART_AUTONEGOTIATION); + + return rv; +} + +/****************************************************************************** +* +* aquantia_phy_enable_autonego +* +*/ +sw_error_t aquantia_phy_enable_autoneg(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data = 0; + sw_error_t rv = SW_OK; + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_STANDARD_CONTROL1, &phy_data); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_STANDARD_CONTROL1, + phy_data | AQUANTIA_CTRL_AUTONEGOTIATION_ENABLE); + + return rv; +} +#ifndef IN_PORTCONTROL_MINI +/****************************************************************************** +* +* aquantia_phy_set_802.3az +* +* set 802.3az status +*/ +sw_error_t +aquantia_phy_set_8023az(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable) +{ + a_uint16_t phy_data = 0, phy_data1 = 0; + sw_error_t rv = SW_OK; + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_EEE_ADVERTISTMENT_REGISTER, &phy_data); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_EEE_ADVERTISTMENT_REGISTER1, &phy_data1); + SW_RTN_ON_ERROR(rv); + if(enable == A_TRUE) + { + phy_data |= (AQUANTIA_EEE_ADV_10000M | AQUANTIA_EEE_ADV_1000M); + phy_data1 |= (AQUANTIA_EEE_ADV_2500M | AQUANTIA_EEE_ADV_5000M); + } + else + { + phy_data &= ~(AQUANTIA_EEE_ADV_10000M | AQUANTIA_EEE_ADV_1000M); + phy_data1 &= ~(AQUANTIA_EEE_ADV_2500M | AQUANTIA_EEE_ADV_5000M); + } + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_EEE_ADVERTISTMENT_REGISTER, phy_data); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_EEE_ADVERTISTMENT_REGISTER1, phy_data1); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_restart_autoneg(dev_id, phy_id); + + return rv; +} + +/****************************************************************************** +* +* aquantia_phy_get_8023az status +* +* get 8023az status +*/ +sw_error_t +aquantia_phy_get_8023az(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t * enable) +{ + a_uint16_t phy_data = 0, phy_data1 = 0; + sw_error_t rv = SW_OK; + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_EEE_ADVERTISTMENT_REGISTER, &phy_data); + SW_RTN_ON_ERROR(rv); + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_EEE_ADVERTISTMENT_REGISTER1, &phy_data1); + SW_RTN_ON_ERROR(rv); + + if((phy_data & (AQUANTIA_EEE_ADV_1000M | AQUANTIA_EEE_ADV_10000M)) && + (phy_data1 & (AQUANTIA_EEE_ADV_2500M | AQUANTIA_EEE_ADV_5000M))) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return rv; +} +#endif +/****************************************************************************** +* +* aquantia_phy_set_speed - Determines the speed of phy ports associated with the +* specified device. +*/ +static sw_error_t _aquantia_phy_set_100speed(a_uint32_t dev_id, a_uint32_t phy_id, fal_port_duplex_t duplex) +{ + a_uint16_t phy_data = 0; + sw_error_t rv = SW_OK; + /*set 100M */ + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_ADVERTISEMENT_REGISTER, &phy_data); + SW_RTN_ON_ERROR(rv); + phy_data &= ~(AQUANTIA_ADVERTISE_MEGA_ALL); + if(duplex == FAL_FULL_DUPLEX) + { + phy_data |= AQUANTIA_ADVERTISE_100FULL; + } + else + { + phy_data |= AQUANTIA_ADVERTISE_100HALF; + } + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_ADVERTISEMENT_REGISTER, phy_data); + SW_RTN_ON_ERROR(rv); + /*disable 1000M, 2500M, 5000M speed*/ + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_VENDOR_PROVISION1, &phy_data); + SW_RTN_ON_ERROR(rv); + phy_data &= ~(AQUANTIA_ADVERTISE_GIGA_ALL); + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_VENDOR_PROVISION1, phy_data); + SW_RTN_ON_ERROR(rv); + /*disable 10000M speed*/ + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_10GBASE_T_CONTROL_REGISTER, &phy_data); + SW_RTN_ON_ERROR(rv); + phy_data &= ~(AQUANTIA_ADVERTISE_GIGA_PLUS_ALL); + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_10GBASE_T_CONTROL_REGISTER, phy_data); + + return rv; +} + +static sw_error_t _aquantia_phy_set_giga_speed(a_uint32_t dev_id, a_uint32_t phy_id, fal_port_speed_t speed) +{ + a_uint16_t phy_data = 0, phy_data1 = 0; + sw_error_t rv = SW_OK; + /*set 1000M and disable 2500M, 5000M */ + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_VENDOR_PROVISION1, &phy_data); + SW_RTN_ON_ERROR(rv); + phy_data &= ~(AQUANTIA_ADVERTISE_GIGA_ALL); + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_10GBASE_T_CONTROL_REGISTER, &phy_data1); + SW_RTN_ON_ERROR(rv); + phy_data1 &= ~(AQUANTIA_ADVERTISE_GIGA_PLUS_ALL); + switch(speed) + { + case FAL_SPEED_1000: + phy_data |= AQUANTIA_ADVERTISE_1000FULL; + break; + case FAL_SPEED_2500: + phy_data |= AQUANTIA_ADVERTISE_2500FULL; + phy_data1 |= AQUANTIA_ADVERTISE_8023BZ_2500FULL; + break; + case FAL_SPEED_5000: + phy_data |= AQUANTIA_ADVERTISE_5000FULL; + phy_data1 |= AQUANTIA_ADVERTISE_8023BZ_5000FULL; + break; + default: + return SW_NOT_SUPPORTED; + } + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_VENDOR_PROVISION1, phy_data); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_10GBASE_T_CONTROL_REGISTER, phy_data1); + SW_RTN_ON_ERROR(rv); + + /*disable 100M speed*/ + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_ADVERTISEMENT_REGISTER, &phy_data); + SW_RTN_ON_ERROR(rv); + phy_data &= ~(AQUANTIA_ADVERTISE_MEGA_ALL); + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_ADVERTISEMENT_REGISTER, phy_data); + + return rv; +} + +static sw_error_t _aquantia_phy_set_10g_speed(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data = 0; + sw_error_t rv = SW_OK; + /*set giga speed */ + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_10GBASE_T_CONTROL_REGISTER,&phy_data); + SW_RTN_ON_ERROR(rv); + phy_data &= ~(AQUANTIA_ADVERTISE_GIGA_PLUS_ALL); + phy_data |= AQUANTIA_ADVERTISE_10000FULL; + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_10GBASE_T_CONTROL_REGISTER, phy_data); + SW_RTN_ON_ERROR(rv); + + /*disable 100M speed*/ + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_ADVERTISEMENT_REGISTER, &phy_data); + SW_RTN_ON_ERROR(rv); + phy_data &= ~(AQUANTIA_ADVERTISE_MEGA_ALL); + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_ADVERTISEMENT_REGISTER, phy_data); + SW_RTN_ON_ERROR(rv); + + /*disable 1000M 2500M 5000M speed*/ + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_VENDOR_PROVISION1, &phy_data); + SW_RTN_ON_ERROR(rv); + phy_data &= ~(AQUANTIA_ADVERTISE_GIGA_ALL); + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_VENDOR_PROVISION1, phy_data); + + return rv; +} + +sw_error_t +aquantia_phy_set_speed(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_speed_t speed) +{ + fal_port_duplex_t old_duplex; + sw_error_t rv; + + rv = aquantia_phy_get_duplex(dev_id, phy_id, &old_duplex); + SW_RTN_ON_ERROR(rv); + if (old_duplex == FAL_FULL_DUPLEX) { + if (FAL_SPEED_100 == speed) { + rv = _aquantia_phy_set_100speed(dev_id, phy_id, FAL_FULL_DUPLEX); + SW_RTN_ON_ERROR(rv); + } else if(FAL_SPEED_2500 == speed ||FAL_SPEED_5000 == speed || FAL_SPEED_1000 == speed){ + rv = _aquantia_phy_set_giga_speed(dev_id, phy_id, speed); + SW_RTN_ON_ERROR(rv); + } else if(FAL_SPEED_10000 == speed){ + rv = _aquantia_phy_set_10g_speed(dev_id, phy_id); + SW_RTN_ON_ERROR(rv); + } else { + return SW_BAD_PARAM; + } + } else if (old_duplex == FAL_HALF_DUPLEX) { + if (FAL_SPEED_100 == speed) { + rv = _aquantia_phy_set_100speed(dev_id, phy_id, FAL_HALF_DUPLEX); + SW_RTN_ON_ERROR(rv); + } else { + return SW_BAD_PARAM; + } + } else { + return SW_FAIL; + } + rv = aquantia_phy_restart_autoneg(dev_id, phy_id); + + return rv; +} + +/****************************************************************************** +* +* aquantia_phy_set_duplex - Determines the speed of phy ports associated with the +* specified device. +*/ +sw_error_t +aquantia_phy_set_duplex(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_duplex_t duplex) +{ + a_uint16_t phy_data = 0; + fal_port_speed_t old_speed; + sw_error_t rv = SW_OK; + + rv = aquantia_phy_get_speed(dev_id, phy_id, &old_speed); + SW_RTN_ON_ERROR(rv); + if (old_speed == FAL_SPEED_100){ + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_ADVERTISEMENT_REGISTER, &phy_data); + SW_RTN_ON_ERROR(rv); + if (duplex == FAL_FULL_DUPLEX) { + phy_data &= ~(AQUANTIA_ADVERTISE_MEGA_ALL); + phy_data |= AQUANTIA_ADVERTISE_100FULL; + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_ADVERTISEMENT_REGISTER, phy_data); + SW_RTN_ON_ERROR(rv); + } else { + phy_data &= ~(AQUANTIA_ADVERTISE_MEGA_ALL); + phy_data |= AQUANTIA_ADVERTISE_100HALF; + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_ADVERTISEMENT_REGISTER, phy_data); + SW_RTN_ON_ERROR(rv); + } + } else { + return SW_NOT_SUPPORTED; + } + rv = aquantia_phy_restart_autoneg(dev_id, phy_id); + + return rv; +} +#ifndef IN_PORTCONTROL_MINI +/****************************************************************************** +* +* aquantia_phy_set wol enable or disable +* +* set phy wol enable or disable +*/ +sw_error_t +aquantia_phy_set_wol_status(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable) +{ + a_uint16_t phy_data0, phy_data1, phy_data2; + sw_error_t rv = SW_OK; + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_RESERVED_VENDOR_PROVISIONING1, &phy_data0); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_GBE_STANDARD_REGISTERS, + AQUANTIA_MAGIC_ENGINE_REGISTER1, &phy_data1); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_GBE_STANDARD_REGISTERS, + AQUANTIA_MAGIC_ENGINE_REGISTER2, &phy_data2); + + if (enable == A_TRUE) + { + phy_data0 |= AQUANTIA_PHY_WOL_ENABLE; + phy_data1 |= AQUANTIA_MAGIC_PACKETS_ENABLE; + phy_data2 |= AQUANTIA_MAGIC_PACKETS_ENABLE; + } + else + { + phy_data0 &= ~AQUANTIA_PHY_WOL_ENABLE; + phy_data1 &= ~AQUANTIA_MAGIC_PACKETS_ENABLE; + phy_data2 &= ~AQUANTIA_MAGIC_PACKETS_ENABLE; + } + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_RESERVED_VENDOR_PROVISIONING1, phy_data0); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_GBE_STANDARD_REGISTERS, + AQUANTIA_MAGIC_ENGINE_REGISTER1, phy_data1); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_GBE_STANDARD_REGISTERS, + AQUANTIA_MAGIC_ENGINE_REGISTER2, phy_data2); + + return rv; +} + +/****************************************************************************** +* +* aquantia_phy_get_wol status +* +* get wol status +*/ +sw_error_t +aquantia_phy_get_wol_status(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t * enable) +{ + a_uint16_t phy_data; + sw_error_t rv = SW_OK; + + *enable = A_FALSE; + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_RESERVED_VENDOR_PROVISIONING1, &phy_data); + SW_RTN_ON_ERROR(rv); + if (phy_data & AQUANTIA_PHY_WOL_ENABLE) + { + *enable = A_TRUE; + } + + return rv; +} + +/****************************************************************************** +* +* aquantia_phy_set wol frame mac address +* +* set phy wol frame mac address +*/ +sw_error_t +aquantia_phy_set_magic_frame_mac(a_uint32_t dev_id, a_uint32_t phy_id, + fal_mac_addr_t * mac) +{ + a_uint16_t phy_data1; + a_uint16_t phy_data2; + a_uint16_t phy_data3; + sw_error_t rv = SW_OK; + + phy_data1 = (mac->uc[1] << 8) | mac->uc[0]; + phy_data2 = (mac->uc[3] << 8) | mac->uc[2]; + phy_data3 = (mac->uc[5] << 8) | mac->uc[4]; + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_GBE_STANDARD_REGISTERS, + AQUANTIA_MAGIC_FRAME_MAC0, phy_data1); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_GBE_STANDARD_REGISTERS, + AQUANTIA_MAGIC_FRAME_MAC1, phy_data2); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_GBE_STANDARD_REGISTERS, + AQUANTIA_MAGIC_FRAME_MAC2, phy_data3); + + return rv; +} + +/****************************************************************************** +* +* aquantia_phy_get wol frame mac address +* +* get phy wol frame mac address +*/ +sw_error_t +aquantia_phy_get_magic_frame_mac(a_uint32_t dev_id, a_uint32_t phy_id, + fal_mac_addr_t * mac) +{ + a_uint16_t phy_data1; + a_uint16_t phy_data2; + a_uint16_t phy_data3; + sw_error_t rv = SW_OK; + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_GBE_STANDARD_REGISTERS, + AQUANTIA_MAGIC_FRAME_MAC0, &phy_data1); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_GBE_STANDARD_REGISTERS, + AQUANTIA_MAGIC_FRAME_MAC1, &phy_data2); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_GBE_STANDARD_REGISTERS, + AQUANTIA_MAGIC_FRAME_MAC2, &phy_data3); + SW_RTN_ON_ERROR(rv); + mac->uc[0] = (phy_data1 & BITS(0, 8)); + mac->uc[1] = (phy_data1 >> 8) & BITS(0, 8); + mac->uc[2] = (phy_data2 & BITS(0, 8)); + mac->uc[3] = (phy_data2 >> 8) & BITS(0, 8); + mac->uc[4] = (phy_data3 & BITS(0, 8)); + mac->uc[5] = (phy_data3 >> 8) & BITS(0, 8); + + return rv; +} +#endif +sw_error_t +aquantia_phy_interface_set_mode(a_uint32_t dev_id, a_uint32_t phy_id, fal_port_interface_mode_t interface_mode) +{ + a_uint16_t phy_data; + a_uint32_t phy_register; + fal_port_speed_t speed; + sw_error_t rv =SW_OK; + + rv = aquantia_phy_get_speed(dev_id, phy_id, &speed); + SW_RTN_ON_ERROR(rv); + switch (speed) + { + case FAL_SPEED_100: + phy_register = AQUANTIA_GLOBAL_SYS_CONFIG_FOR_100M; + break; + case FAL_SPEED_1000: + phy_register = AQUANTIA_GLOBAL_SYS_CONFIG_FOR_1000M; + break; + case FAL_SPEED_2500: + phy_register = AQUANTIA_GLOBAL_SYS_CONFIG_FOR_2500M; + break; + case FAL_SPEED_5000: + phy_register = AQUANTIA_GLOBAL_SYS_CONFIG_FOR_5000M; + break; + case FAL_SPEED_10000: + phy_register = AQUANTIA_GLOBAL_SYS_CONFIG_FOR_10000M; + break; + default: + return SW_NOT_SUPPORTED; + } + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_GLOBAL_REGISTERS, + phy_register, &phy_data); + SW_RTN_ON_ERROR(rv); + phy_data &= ~(BITS(0, 3)); + switch(interface_mode) + { + case PHY_SGMII_BASET: + if(speed == FAL_SPEED_100 || speed == FAL_SPEED_1000) + { + phy_data |= AQUANTIA_SERDES_MODE_SGMII; + } + else + { + return SW_NOT_SUPPORTED; + } + break; + case PORT_USXGMII: + phy_data |= AQUANTIA_SERDES_MODE_XFI; + break; + case PORT_SGMII_PLUS: + if(speed == FAL_SPEED_2500) + { + phy_data |= AQUANTIA_SERDES_MODE_OCSGMII; + } + else + { + return SW_NOT_SUPPORTED; + } + break; + default: + return SW_NOT_SUPPORTED; + } + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_GLOBAL_REGISTERS, + phy_register, phy_data); + + return rv; +} + +/****************************************************************************** +* +* aquantia_phy_interface mode status get +* +* get aquantia phy interface mode status +*/ +sw_error_t +aquantia_phy_interface_get_mode_status(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_interface_mode_t *interface_mode_status) +{ + a_uint16_t phy_data; + a_uint32_t phy_register; + fal_port_speed_t speed; + sw_error_t rv = SW_OK; + + rv = aquantia_phy_get_speed(dev_id, phy_id, &speed); + SW_RTN_ON_ERROR(rv); + switch (speed) + { + case FAL_SPEED_100: + phy_register = AQUANTIA_GLOBAL_SYS_CONFIG_FOR_100M; + break; + case FAL_SPEED_1000: + phy_register = AQUANTIA_GLOBAL_SYS_CONFIG_FOR_1000M; + break; + case FAL_SPEED_2500: + phy_register = AQUANTIA_GLOBAL_SYS_CONFIG_FOR_2500M; + break; + case FAL_SPEED_5000: + phy_register = AQUANTIA_GLOBAL_SYS_CONFIG_FOR_5000M; + break; + case FAL_SPEED_10000: + phy_register = AQUANTIA_GLOBAL_SYS_CONFIG_FOR_10000M; + break; + default: + return SW_NOT_SUPPORTED; + } + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_GLOBAL_REGISTERS, + phy_register, &phy_data); + SW_RTN_ON_ERROR(rv); + phy_data &= (BITS(0, 3)); + switch(phy_data) + { + case AQUANTIA_SERDES_MODE_SGMII: + *interface_mode_status = PHY_SGMII_BASET; + break; + case AQUANTIA_SERDES_MODE_XFI: + *interface_mode_status = PORT_USXGMII; + break; + case AQUANTIA_SERDES_MODE_OCSGMII: + *interface_mode_status = PORT_SGMII_PLUS; + break; + default: + return SW_NOT_SUPPORTED; + } + + return rv; +} +#ifndef IN_PORTCONTROL_MINI +/****************************************************************************** +* +* aquantia_phy_intr_mask_set - Set interrupt mask with the +* specified device. +*/ +sw_error_t +aquantia_phy_intr_mask_set(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t intr_mask_flag) +{ + a_uint16_t phy_data = 0; + sw_error_t rv = SW_OK; + + if ((FAL_PHY_INTR_STATUS_DOWN_CHANGE |FAL_PHY_INTR_STATUS_UP_CHANGE) + & intr_mask_flag) + { + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_TRANSMIT_VENDOR_INTR_MASK, &phy_data); + SW_RTN_ON_ERROR(rv); + phy_data |= AQUANTIA_INTR_LINK_STATUS_CHANGE; + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_TRANSMIT_VENDOR_INTR_MASK, phy_data); + SW_RTN_ON_ERROR(rv); + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_GLOBAL_REGISTERS, + AQUANTIA_GLOBAL_INTR_VENDOR_MASK, &phy_data); + SW_RTN_ON_ERROR(rv); + phy_data |= AQUANTIA_AUTO_AND_ALARMS_INTR_MASK; + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_GLOBAL_REGISTERS, + AQUANTIA_GLOBAL_INTR_VENDOR_MASK, phy_data); + SW_RTN_ON_ERROR(rv); + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_GLOBAL_REGISTERS, + AQUANTIA_GLOBAL_INTR_STANDARD_MASK, &phy_data); + SW_RTN_ON_ERROR(rv); + phy_data |= AQUANTIA_ALL_VENDOR_ALARMS_INTR_MASK; + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_GLOBAL_REGISTERS, + AQUANTIA_GLOBAL_INTR_STANDARD_MASK, phy_data); + } + + return rv; +} + +/****************************************************************************** +* +* aquantia_phy_intr_mask_get - Get interrupt mask with the +* specified device. +*/ +sw_error_t +aquantia_phy_intr_mask_get(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * intr_mask_flag) +{ + a_uint16_t phy_data1 = 0, phy_data2 = 0, phy_data3 = 0; + sw_error_t rv = SW_OK; + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_TRANSMIT_VENDOR_INTR_MASK, &phy_data1); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_GLOBAL_REGISTERS, + AQUANTIA_GLOBAL_INTR_VENDOR_MASK, &phy_data2); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_GLOBAL_REGISTERS, + AQUANTIA_GLOBAL_INTR_STANDARD_MASK, &phy_data3); + if ((AQUANTIA_INTR_LINK_STATUS_CHANGE & phy_data1) && + (AQUANTIA_AUTO_AND_ALARMS_INTR_MASK & phy_data2) && + (AQUANTIA_ALL_VENDOR_ALARMS_INTR_MASK & phy_data3)) + { + *intr_mask_flag = FAL_PHY_INTR_STATUS_DOWN_CHANGE | + FAL_PHY_INTR_STATUS_UP_CHANGE; + } + + return rv; +} +#endif +/****************************************************************************** +* +* aquantia_phy_off - power off the phy +* +* Power off the phy +*/ +sw_error_t aquantia_phy_poweroff(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + sw_error_t rv; + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_GLOBAL_REGISTERS, + AQUANTIA_GLOBAL_STANDARD_CONTROL1, &phy_data); + SW_RTN_ON_ERROR(rv); + phy_data |= AQUANTIA_POWER_DOWN; + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_GLOBAL_REGISTERS, + AQUANTIA_GLOBAL_STANDARD_CONTROL1,phy_data); + + return rv; +} + +/****************************************************************************** +* +* aquantia_phy_on - power on the phy +* +* Power on the phy +*/ +sw_error_t aquantia_phy_poweron(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + sw_error_t rv; + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_GLOBAL_REGISTERS, + AQUANTIA_GLOBAL_STANDARD_CONTROL1, &phy_data); + SW_RTN_ON_ERROR(rv); + phy_data &= ~AQUANTIA_POWER_DOWN; + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_GLOBAL_REGISTERS, + AQUANTIA_GLOBAL_STANDARD_CONTROL1,phy_data); + + return rv; +} +#ifndef IN_PORTCONTROL_MINI +static sw_error_t +_aquantia_phy_line_side_counter_get(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_counter_info_t * counter_infor) +{ + a_uint16_t msw_counter; + a_uint16_t lsw_counter; + sw_error_t rv = SW_OK; + + /*get line side tx good packets*/ + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_PCS_REGISTERS, + AQUANTIA_LINE_SIDE_TRANSMIT_GOOD_FRAME_COUNTER2, &msw_counter); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_PCS_REGISTERS, + AQUANTIA_LINE_SIDE_TRANSMIT_GOOD_FRAME_COUNTER1, &lsw_counter); + SW_RTN_ON_ERROR(rv); + counter_infor->TxGoodFrame = (msw_counter << 16) | lsw_counter; + + /*get line side tx bad packets*/ + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_PCS_REGISTERS, + AQUANTIA_LINE_SIDE_TRANSMIT_ERROR_FRAME_COUNTER2, &msw_counter); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_PCS_REGISTERS, + AQUANTIA_LINE_SIDE_TRANSMIT_ERROR_FRAME_COUNTER1, &lsw_counter); + SW_RTN_ON_ERROR(rv); + counter_infor->TxBadCRC = (msw_counter << 16) | lsw_counter; + + /*get line side rx good packets*/ + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_PCS_REGISTERS, + AQUANTIA_LINE_SIDE_RECEIVE_GOOD_FRAME_COUNTER2, &msw_counter); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_PCS_REGISTERS, + AQUANTIA_LINE_SIDE_RECEIVE_GOOD_FRAME_COUNTER1, &lsw_counter); + SW_RTN_ON_ERROR(rv); + counter_infor->RxGoodFrame = (msw_counter << 16) | lsw_counter; + + /*get line side rx bad packets*/ + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_PCS_REGISTERS, + AQUANTIA_LINE_SIDE_RECEIVE_ERROR_FRAME_COUNTER2, &msw_counter); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_PCS_REGISTERS, + AQUANTIA_LINE_SIDE_RECEIVE_ERROR_FRAME_COUNTER1, &lsw_counter); + SW_RTN_ON_ERROR(rv); + counter_infor->RxBadCRC = (msw_counter << 16) | lsw_counter; + + return rv; +} + +static sw_error_t +_aquantia_phy_system_side_counter_get(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_counter_info_t * counter_infor) +{ + a_uint16_t msw_counter; + a_uint16_t lsw_counter; + sw_error_t rv = SW_OK; + + /*get system tx good packets*/ + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_PCS_REGISTERS, + AQUANTIA_SYSTEM_SIDE_TRANSMIT_GOOD_FRAME_COUNTER2, &msw_counter); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_PCS_REGISTERS, + AQUANTIA_SYSTEM_SIDE_TRANSMIT_GOOD_FRAME_COUNTER1, &lsw_counter); + SW_RTN_ON_ERROR(rv); + counter_infor->SysTxGoodFrame = (msw_counter << 16) | lsw_counter; + + /*get system tx bad packets*/ + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_PCS_REGISTERS, + AQUANTIA_SYSTEM_SIDE_TRANSMIT_ERROR_FRAME_COUNTER2, &msw_counter); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_PCS_REGISTERS, + AQUANTIA_SYSTEM_SIDE_TRANSMIT_ERROR_FRAME_COUNTER1, &lsw_counter); + SW_RTN_ON_ERROR(rv); + counter_infor->SysTxBadCRC = (msw_counter << 16) | lsw_counter; + + /*get system rx good packets*/ + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_PCS_REGISTERS, + AQUANTIA_SYSTEM_SIDE_RECEIVE_GOOD_FRAME_COUNTER2, &msw_counter); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_PCS_REGISTERS, + AQUANTIA_SYSTEM_SIDE_RECEIVE_GOOD_FRAME_COUNTER1, &lsw_counter); + SW_RTN_ON_ERROR(rv); + counter_infor->SysRxGoodFrame = (msw_counter << 16) | lsw_counter; + + /*get system rx bad packets*/ + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_PCS_REGISTERS, + AQUANTIA_SYSTEM_SIDE_RECEIVE_ERROR_FRAME_COUNTER2, &msw_counter); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_PCS_REGISTERS, + AQUANTIA_SYSTEM_SIDE_RECEIVE_ERROR_FRAME_COUNTER1, &lsw_counter); + SW_RTN_ON_ERROR(rv); + counter_infor->SysRxBadCRC = (msw_counter << 16) | lsw_counter; + + return rv; +} + +/****************************************************************************** +* +* aquantia_phy_show show counter statistics +* +* show counter statistics +*/ +sw_error_t +aquantia_phy_show_counter(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_counter_info_t * counter_infor) +{ + sw_error_t rv = SW_OK; + fal_port_speed_t speed; + + rv = aquantia_phy_get_speed(dev_id, phy_id, &speed); + SW_RTN_ON_ERROR(rv); + if(speed == FAL_SPEED_2500 || speed == FAL_SPEED_5000 || speed == FAL_SPEED_10000) + { + rv = _aquantia_phy_line_side_counter_get(dev_id, phy_id, counter_infor); + SW_RTN_ON_ERROR(rv); + } + rv = _aquantia_phy_system_side_counter_get(dev_id, phy_id, counter_infor); + + return rv; +} +#endif +/****************************************************************************** +* +* aquantia_phy_get_status +* +* get phy status +*/ +sw_error_t +aquantia_phy_get_status(a_uint32_t dev_id, a_uint32_t phy_id, + struct port_phy_status *phy_status) +{ + sw_error_t rv = SW_OK; + a_uint16_t phy_data; + + /*get phy link status*/ + phy_status->link_status = aquantia_phy_get_link_status(dev_id, phy_id); + if(phy_status->link_status != A_TRUE) + { + return SW_OK; + } + /*get phy speed and duplex*/ + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_REG_AUTONEG_VENDOR_STATUS, &phy_data); + SW_RTN_ON_ERROR(rv); + switch ((phy_data & AQUANTIA_STATUS_SPEED_MASK) >>1) + { + case AQUANTIA_STATUS_SPEED_100MBS: + phy_status->speed = FAL_SPEED_100; + break; + case AQUANTIA_STATUS_SPEED_1000MBS: + phy_status->speed = FAL_SPEED_1000; + break; + case AQUANTIA_STATUS_SPEED_2500MBS: + phy_status->speed = FAL_SPEED_2500; + break; + case AQUANTIA_STATUS_SPEED_5000MBS: + phy_status->speed = FAL_SPEED_5000; + break; + case AQUANTIA_STATUS_SPEED_10000MBS: + phy_status->speed = FAL_SPEED_10000; + break; + default: + return SW_READ_ERROR; + } + if (phy_data & AQUANTIA_STATUS_FULL_DUPLEX) + { + phy_status->duplex = FAL_FULL_DUPLEX; + } + else + { + phy_status->duplex = FAL_HALF_DUPLEX; + } + /* get phy tx flowctrl and rx flowctrl resolution status */ + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_RESERVED_VENDOR_STATUS1, &phy_data); + SW_RTN_ON_ERROR(rv); + if(phy_data & AQUANTIA_PHY_TX_FLOWCTRL_STATUS) + { + phy_status->tx_flowctrl = A_TRUE; + } + else + { + phy_status->tx_flowctrl = A_FALSE; + } + if(phy_data & AQUANTIA_PHY_RX_FLOWCTRL_STATUS) + { + phy_status->rx_flowctrl = A_TRUE; + } + else + { + phy_status->rx_flowctrl = A_FALSE; + } + + return rv; +} + +/****************************************************************************** +* +* aquantia_phy_set_eee_advertisement +* +* set eee advertisement +*/ +sw_error_t +aquantia_phy_set_eee_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t adv) +{ + a_uint16_t phy_data = 0, phy_data1 = 0; + sw_error_t rv = SW_OK; + + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_EEE_ADVERTISTMENT_REGISTER, &phy_data); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_EEE_ADVERTISTMENT_REGISTER1, &phy_data1); + SW_RTN_ON_ERROR(rv); + + phy_data &= ~(AQUANTIA_EEE_ADV_1000M | AQUANTIA_EEE_ADV_10000M); + if (adv & FAL_PHY_EEE_1000BASE_T) { + phy_data |= AQUANTIA_EEE_ADV_1000M; + } + if (adv & FAL_PHY_EEE_10000BASE_T) { + phy_data |= AQUANTIA_EEE_ADV_10000M; + } + + phy_data1 &= ~(AQUANTIA_EEE_ADV_2500M | AQUANTIA_EEE_ADV_5000M); + if (adv & FAL_PHY_EEE_2500BASE_T) { + phy_data1 |= AQUANTIA_EEE_ADV_2500M; + } + if (adv & FAL_PHY_EEE_5000BASE_T) { + phy_data1 |= AQUANTIA_EEE_ADV_5000M; + } + + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_EEE_ADVERTISTMENT_REGISTER, phy_data); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_reg_write(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_EEE_ADVERTISTMENT_REGISTER1, phy_data1); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_restart_autoneg(dev_id, phy_id); + + return rv; +} + +/****************************************************************************** +* +* aquantia_phy_get_eee_advertisement +* +* get eee advertisement +*/ +sw_error_t +aquantia_phy_get_eee_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *adv) +{ + a_uint16_t phy_data = 0; + sw_error_t rv = SW_OK; + + *adv = 0; + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_EEE_ADVERTISTMENT_REGISTER, &phy_data); + SW_RTN_ON_ERROR(rv); + + if (phy_data & AQUANTIA_EEE_ADV_1000M) { + *adv |= FAL_PHY_EEE_1000BASE_T; + } + if (phy_data & AQUANTIA_EEE_ADV_10000M){ + *adv |= FAL_PHY_EEE_10000BASE_T; + } + phy_data = 0; + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_EEE_ADVERTISTMENT_REGISTER1, &phy_data); + SW_RTN_ON_ERROR(rv); + + if (phy_data & AQUANTIA_EEE_ADV_2500M) { + *adv |= FAL_PHY_EEE_2500BASE_T; + } + if (phy_data & AQUANTIA_EEE_ADV_5000M) { + *adv |= FAL_PHY_EEE_5000BASE_T; + } + + return rv; +} +/****************************************************************************** +* +* aquantia_phy_get_eee_partner_advertisement +* +* get eee partner advertisement +*/ +sw_error_t +aquantia_phy_get_eee_partner_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *adv) +{ + a_uint16_t phy_data = 0; + sw_error_t rv = SW_OK; + + *adv = 0; + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_EEE_PARTNER_ADVERTISTMENT_REGISTER, &phy_data); + SW_RTN_ON_ERROR(rv); + + if (phy_data & AQUANTIA_EEE_PARTNER_ADV_1000M) { + *adv |= FAL_PHY_EEE_1000BASE_T; + } + if (phy_data & AQUANTIA_EEE_PARTNER_ADV_10000M){ + *adv |= FAL_PHY_EEE_10000BASE_T; + } + phy_data = 0; + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_AUTONEG, + AQUANTIA_EEE_PARTNER_ADVERTISTMENT_REGISTER1, &phy_data); + SW_RTN_ON_ERROR(rv); + + if (phy_data & AQUANTIA_EEE_PARTNER_ADV_2500M) { + *adv |= FAL_PHY_EEE_2500BASE_T; + } + if (phy_data & AQUANTIA_EEE_PARTNER_ADV_5000M) { + *adv |= FAL_PHY_EEE_5000BASE_T; + } + + return rv; +} +/****************************************************************************** +* +* aquantia_phy_get_eee_capability +* +* get eee capability +*/ +sw_error_t +aquantia_phy_get_eee_cap(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *cap) +{ + a_uint16_t phy_data = 0; + sw_error_t rv = SW_OK; + + *cap = 0; + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_PCS_REGISTERS, + AQUANTIA_EEE_CAPABILITY_REGISTER, &phy_data); + SW_RTN_ON_ERROR(rv); + + if (phy_data & AQUANTIA_EEE_CAPABILITY_1000M) { + *cap |= FAL_PHY_EEE_1000BASE_T; + } + if (phy_data & AQUANTIA_EEE_CAPABILITY_10000M){ + *cap |= FAL_PHY_EEE_10000BASE_T; + } + phy_data = 0; + rv = aquantia_phy_reg_read(dev_id, phy_id, AQUANTIA_MMD_PCS_REGISTERS, + AQUANTIA_EEE_CAPABILITY_REGISTER1, &phy_data); + SW_RTN_ON_ERROR(rv); + + if (phy_data & AQUANTIA_EEE_CAPABILITY_2500M) { + *cap |= FAL_PHY_EEE_2500BASE_T; + } + if (phy_data & AQUANTIA_EEE_CAPABILITY_5000M) { + *cap |= FAL_PHY_EEE_5000BASE_T; + } + + return rv; +} +/****************************************************************************** +* +* aquantia_phy_get_eee_status +* +* get eee status +*/ +sw_error_t +aquantia_phy_get_eee_status(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *status) +{ + a_uint32_t adv = 0, lp_adv = 0; + sw_error_t rv = SW_OK; + + rv = aquantia_phy_get_eee_adv(dev_id, phy_id, &adv); + SW_RTN_ON_ERROR(rv); + + rv = aquantia_phy_get_eee_partner_adv(dev_id, phy_id, &lp_adv); + SW_RTN_ON_ERROR(rv); + + *status = (adv & lp_adv); + + return rv; +} + +/****************************************************************************** +* +* aquantia_phy_hw_register init to avoid packet loss +* +*/ +sw_error_t +aquantia_phy_hw_init(a_uint32_t dev_id, a_uint32_t port_bmp) +{ + a_uint16_t phy_data = 0; + a_uint32_t port_id = 0, phy_addr = 0; + sw_error_t rv = SW_OK; + + for (port_id = 0; port_id < SW_MAX_NR_PORT; port_id ++) + { + if (port_bmp & (0x1 << port_id)) + { + phy_addr = qca_ssdk_port_to_phy_addr(dev_id, port_id); + /*set auto neg of aq*/ + rv = aquantia_phy_reg_read(dev_id, phy_addr, AQUANTIA_MMD_PHY_XS_REGISTERS, + AQUANTIA_PHY_XS_USX_TRANSMIT, &phy_data); + SW_RTN_ON_ERROR(rv); + phy_data |= AQUANTIA_PHY_USX_AUTONEG_ENABLE; + rv = aquantia_phy_reg_write(dev_id, phy_addr, AQUANTIA_MMD_PHY_XS_REGISTERS, + AQUANTIA_PHY_XS_USX_TRANSMIT,phy_data); + SW_RTN_ON_ERROR(rv); + /*config interrupt of aq*/ + rv = aquantia_phy_reg_read(dev_id, phy_addr, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_TRANSMIT_VENDOR_INTR_MASK, &phy_data); + SW_RTN_ON_ERROR(rv); + phy_data |= AQUANTIA_INTR_LINK_STATUS_CHANGE; + rv = aquantia_phy_reg_write(dev_id, phy_addr, AQUANTIA_MMD_AUTONEG, + AQUANTIA_AUTONEG_TRANSMIT_VENDOR_INTR_MASK, phy_data); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_reg_read(dev_id, phy_addr, AQUANTIA_MMD_GLOBAL_REGISTERS, + AQUANTIA_GLOBAL_INTR_STANDARD_MASK, &phy_data); + SW_RTN_ON_ERROR(rv); + phy_data |= AQUANTIA_ALL_VENDOR_ALARMS_INTR_MASK; + rv = aquantia_phy_reg_write(dev_id, phy_addr, AQUANTIA_MMD_GLOBAL_REGISTERS, + AQUANTIA_GLOBAL_INTR_STANDARD_MASK, phy_data); + SW_RTN_ON_ERROR(rv); + rv = aquantia_phy_reg_read(dev_id, phy_addr, AQUANTIA_MMD_GLOBAL_REGISTERS, + AQUANTIA_GLOBAL_INTR_VENDOR_MASK, &phy_data); + SW_RTN_ON_ERROR(rv); + phy_data |= AQUANTIA_AUTO_AND_ALARMS_INTR_MASK; + rv = aquantia_phy_reg_write(dev_id, phy_addr, AQUANTIA_MMD_GLOBAL_REGISTERS, + AQUANTIA_GLOBAL_INTR_VENDOR_MASK, phy_data); + SW_RTN_ON_ERROR(rv); + + /* config aq phy ACT and LINK led behavior*/ + phy_data = AQUANTIA_ACT_LED_VALUE; + rv = aquantia_phy_reg_write(dev_id, phy_addr, AQUANTIA_MMD_GLOBAL_REGISTERS, + AQUANTIA_ACT_LED_STATUS, phy_data); + SW_RTN_ON_ERROR(rv); + phy_data = AQUANTIA_LINK_LED_VALUE; + rv = aquantia_phy_reg_write(dev_id, phy_addr, AQUANTIA_MMD_GLOBAL_REGISTERS, + AQUANTIA_LINK_LED_STATUS, phy_data); + SW_RTN_ON_ERROR(rv); + /*add all ability of aq phy*/ + rv = aquantia_phy_set_autoneg_adv(dev_id, phy_addr, + FAL_PHY_ADV_XGE_SPEED_ALL | FAL_PHY_ADV_100TX_FD | + FAL_PHY_ADV_1000T_FD); + SW_RTN_ON_ERROR(rv); +#if 0 + rv = aquantia_phy_set_eee_adv(dev_id, phy_addr, FAL_PHY_EEE_1000BASE_T + | FAL_PHY_EEE_2500BASE_T | FAL_PHY_EEE_5000BASE_T | + FAL_PHY_EEE_10000BASE_T); + SW_RTN_ON_ERROR(rv); +#endif + } + } + + return rv; +} + +static int aquantia_phy_api_ops_init(void) +{ + int ret; + hsl_phy_ops_t *aquantia_phy_api_ops = NULL; + + aquantia_phy_api_ops = kzalloc(sizeof(hsl_phy_ops_t), GFP_KERNEL); + if (aquantia_phy_api_ops == NULL) { + SSDK_ERROR("aquantia phy ops kzalloc failed!\n"); + return -ENOMEM; + } + + phy_api_ops_init(AQUANTIA_PHY_CHIP); + + aquantia_phy_api_ops->phy_speed_get = aquantia_phy_get_speed; + aquantia_phy_api_ops->phy_speed_set = aquantia_phy_set_speed; + aquantia_phy_api_ops->phy_duplex_get = aquantia_phy_get_duplex; + aquantia_phy_api_ops->phy_duplex_set = aquantia_phy_set_duplex; + aquantia_phy_api_ops->phy_autoneg_enable_set = aquantia_phy_enable_autoneg; + aquantia_phy_api_ops->phy_restart_autoneg = aquantia_phy_restart_autoneg; + aquantia_phy_api_ops->phy_autoneg_status_get = aquantia_phy_autoneg_status; + aquantia_phy_api_ops->phy_autoneg_adv_set = aquantia_phy_set_autoneg_adv; + aquantia_phy_api_ops->phy_autoneg_adv_get = aquantia_phy_get_autoneg_adv; +#ifndef IN_PORTCONTROL_MINI + aquantia_phy_api_ops->phy_powersave_set = aquantia_phy_set_powersave; + aquantia_phy_api_ops->phy_powersave_get = aquantia_phy_get_powersave; + aquantia_phy_api_ops->phy_8023az_set = aquantia_phy_set_8023az; + aquantia_phy_api_ops->phy_8023az_get = aquantia_phy_get_8023az; +#endif + aquantia_phy_api_ops->phy_power_on = aquantia_phy_poweron; + aquantia_phy_api_ops->phy_power_off = aquantia_phy_poweroff; +#ifndef IN_PORTCONTROL_MINI + aquantia_phy_api_ops->phy_cdt = aquantia_phy_cdt; +#endif + aquantia_phy_api_ops->phy_link_status_get = aquantia_phy_get_link_status; +#ifndef IN_PORTCONTROL_MINI + aquantia_phy_api_ops->phy_mdix_set = aquantia_phy_set_mdix; + aquantia_phy_api_ops->phy_mdix_get = aquantia_phy_get_mdix; + aquantia_phy_api_ops->phy_mdix_status_get = aquantia_phy_get_mdix_status; + aquantia_phy_api_ops->phy_local_loopback_set = aquantia_phy_set_local_loopback; + aquantia_phy_api_ops->phy_local_loopback_get = aquantia_phy_get_local_loopback; + aquantia_phy_api_ops->phy_remote_loopback_set = aquantia_phy_set_remote_loopback; + aquantia_phy_api_ops->phy_remote_loopback_get = aquantia_phy_get_remote_loopback; + aquantia_phy_api_ops->phy_reset = aquantia_phy_reset; + aquantia_phy_api_ops->phy_wol_status_set = aquantia_phy_set_wol_status; + aquantia_phy_api_ops->phy_wol_status_get = aquantia_phy_get_wol_status; + aquantia_phy_api_ops->phy_magic_frame_mac_get = aquantia_phy_get_magic_frame_mac; + aquantia_phy_api_ops->phy_magic_frame_mac_set = aquantia_phy_set_magic_frame_mac; + aquantia_phy_api_ops->phy_intr_mask_set = aquantia_phy_intr_mask_set; + aquantia_phy_api_ops->phy_intr_mask_get = aquantia_phy_intr_mask_get; + aquantia_phy_api_ops->phy_id_get = aquantia_phy_get_phy_id; +#endif + aquantia_phy_api_ops->phy_interface_mode_set = aquantia_phy_interface_set_mode; + aquantia_phy_api_ops->phy_interface_mode_status_get=aquantia_phy_interface_get_mode_status; + aquantia_phy_api_ops->phy_get_status = aquantia_phy_get_status; +#ifndef IN_PORTCONTROL_MINI + aquantia_phy_api_ops->phy_counter_show = aquantia_phy_show_counter; +#endif + aquantia_phy_api_ops->phy_eee_adv_set = aquantia_phy_set_eee_adv; + aquantia_phy_api_ops->phy_eee_adv_get = aquantia_phy_get_eee_adv; + aquantia_phy_api_ops->phy_eee_partner_adv_get = aquantia_phy_get_eee_partner_adv; + aquantia_phy_api_ops->phy_eee_cap_get = aquantia_phy_get_eee_cap; + aquantia_phy_api_ops->phy_eee_status_get = aquantia_phy_get_eee_status; + ret = hsl_phy_api_ops_register(AQUANTIA_PHY_CHIP, aquantia_phy_api_ops); + if (ret == 0) + SSDK_INFO("qca probe aquantia phy driver succeeded!\n"); + else + SSDK_ERROR("qca probe aquantia phy driver failed! (code: %d)\n", ret); + + return ret; +} + +/****************************************************************************** +* +* aquantia_phy_init - +* +*/ +int aquantia_phy_init(a_uint32_t dev_id, a_uint32_t port_bmp) +{ + static a_uint32_t phy_ops_flag = 0; + + if(phy_ops_flag == 0) { + aquantia_phy_api_ops_init(); + phy_ops_flag = 1; + } + aquantia_phy_hw_init(dev_id, port_bmp); + + return 0; + +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/f1_phy.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/f1_phy.c new file mode 100755 index 000000000..b3017b00d --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/f1_phy.c @@ -0,0 +1,1534 @@ +/* + * Copyright (c) 2012, 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. + */ + +#include "sw.h" +#include "fal_port_ctrl.h" +#include "hsl_api.h" +#include "hsl.h" +#include "f1_phy.h" +#include "hsl_phy.h" +#include "ssdk_plat.h" + +static a_uint16_t +_phy_reg_read(a_uint32_t dev_id, a_uint32_t phy_addr, a_uint32_t reg) +{ + sw_error_t rv; + a_uint16_t val = 0; + + HSL_PHY_GET(rv, dev_id, phy_addr, reg, &val); + if (SW_OK != rv) + return 0xFFFF; + + return val; +} + +static sw_error_t +_phy_reg_write(a_uint32_t dev_id, a_uint32_t phy_addr, a_uint32_t reg, + a_uint16_t val) +{ + sw_error_t rv; + + HSL_PHY_SET(rv, dev_id, phy_addr, reg, val); + + return rv; +} + +/* #define f1_phy_reg_read _phy_reg_read */ +/* #define f1_phy_reg_write _phy_reg_write */ + +/****************************************************************************** +* +* f1_phy_mii_read - mii register read +* +* mil register read +*/ +a_uint16_t +f1_phy_reg_read(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t reg_id) +{ + return _phy_reg_read(dev_id, phy_id, reg_id); + +} + +/****************************************************************************** +* +* f1_phy_reg_write - mii register write +* +* mii register write +*/ +sw_error_t +f1_phy_reg_write(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t reg_id, + a_uint16_t reg_val) +{ + + _phy_reg_write(dev_id,phy_id, reg_id, reg_val); + + return SW_OK; +} + + +/****************************************************************************** +* +* f1_phy_debug_write - debug port write +* +* debug port write +*/ +sw_error_t +f1_phy_debug_write(a_uint32_t dev_id, a_uint32_t phy_id, a_uint16_t reg_id, + a_uint16_t reg_val) +{ + f1_phy_reg_write(dev_id, phy_id, F1_DEBUG_PORT_ADDRESS, reg_id); + f1_phy_reg_write(dev_id, phy_id, F1_DEBUG_PORT_DATA, reg_val); + + return SW_OK; +} + +/****************************************************************************** +* +* f1_phy_debug_read - debug port read +* +* debug port read +*/ +a_uint16_t +f1_phy_debug_read(a_uint32_t dev_id, a_uint32_t phy_id, a_uint16_t reg_id) +{ + f1_phy_reg_write(dev_id, phy_id, F1_DEBUG_PORT_ADDRESS, reg_id); + return f1_phy_reg_read(dev_id, phy_id, F1_DEBUG_PORT_DATA); +} + +/****************************************************************************** +* +* f1_phy_mmd_write - PHY MMD register write +* +* PHY MMD register write +*/ +sw_error_t +f1_phy_mmd_write(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint16_t mmd_num, + a_uint16_t reg_id, + a_uint16_t reg_val) +{ + f1_phy_reg_write(dev_id, phy_id, F1_MMD_CTRL_REG, mmd_num); + f1_phy_reg_write(dev_id, phy_id, F1_MMD_DATA_REG, reg_id); + f1_phy_reg_write(dev_id, phy_id, F1_MMD_CTRL_REG, 0x4000|mmd_num); + f1_phy_reg_write(dev_id, phy_id, F1_MMD_DATA_REG, reg_val); + + return SW_OK; +} + +/****************************************************************************** +* +* f1_phy_mmd_read - PHY MMD register read +* +* PHY MMD register read +*/ +a_uint16_t +f1_phy_mmd_read(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint16_t mmd_num, + a_uint16_t reg_id) +{ + f1_phy_reg_write(dev_id, phy_id, F1_MMD_CTRL_REG, mmd_num); + f1_phy_reg_write(dev_id, phy_id, F1_MMD_DATA_REG, reg_id); + f1_phy_reg_write(dev_id, phy_id, F1_MMD_CTRL_REG, 0x4000|mmd_num); + + return f1_phy_reg_read(dev_id, phy_id, F1_MMD_DATA_REG); +} + + +/****************************************************************************** +* +* f1_phy_set_powersave - set power saving status +* +* set power saving status +*/ +sw_error_t +f1_phy_set_powersave(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable) +{ + a_uint16_t phy_data; + f1_phy_reg_write(dev_id, phy_id, F1_DEBUG_PORT_ADDRESS, 0x29); + phy_data = f1_phy_reg_read(dev_id, phy_id, F1_DEBUG_PORT_DATA); + + if(enable == A_TRUE) + { + phy_data |= 0x8000; + } + else + { + phy_data &= ~0x8000; + } + + f1_phy_reg_write(dev_id, phy_id, F1_DEBUG_PORT_DATA, phy_data); + + return SW_OK; +} + +/****************************************************************************** +* +* f1_phy_get_powersave - get power saving status +* +* set power saving status +*/ +sw_error_t +f1_phy_get_powersave(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t *enable) +{ + a_uint16_t phy_data; + *enable = A_FALSE; + + f1_phy_reg_write(dev_id, phy_id, F1_DEBUG_PORT_ADDRESS, 0x29); + phy_data = f1_phy_reg_read(dev_id, phy_id, F1_DEBUG_PORT_DATA); + + if(phy_data & 0x8000) + *enable = A_TRUE; + + return SW_OK; +} + +/****************************************************************************** +* +* f1_phy_set_hibernate - set hibernate status +* +* set hibernate status +*/ +sw_error_t +f1_phy_set_hibernate(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable) +{ + a_uint16_t phy_data; + f1_phy_reg_write(dev_id, phy_id, F1_DEBUG_PORT_ADDRESS, 0xb); + phy_data = f1_phy_reg_read(dev_id, phy_id, F1_DEBUG_PORT_DATA); + + if(enable == A_TRUE) + { + phy_data |= 0x8000; + } + else + { + phy_data &= ~0x8000; + } + + f1_phy_reg_write(dev_id, phy_id, F1_DEBUG_PORT_DATA, phy_data); + + return SW_OK; +} + +/****************************************************************************** +* +* f1_phy_get_hibernate - get hibernate status +* +* get hibernate status +*/ +sw_error_t +f1_phy_get_hibernate(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t *enable) +{ + a_uint16_t phy_data; + *enable = A_FALSE; + + f1_phy_reg_write(dev_id, phy_id, F1_DEBUG_PORT_ADDRESS, 0xb); + phy_data = f1_phy_reg_read(dev_id, phy_id, F1_DEBUG_PORT_DATA); + + if(phy_data & 0x8000) + *enable = A_TRUE; + + return SW_OK; +} + +/****************************************************************************** +* +* f1_phy_cdt - cable diagnostic test +* +* cable diagnostic test +*/ +#ifdef ISISC +#define RUN_CDT 0x8000 +#define CABLE_LENGTH_UNIT 0x0400 +sw_error_t f1_phy_reset(a_uint32_t dev_id, a_uint32_t phy_id); +a_bool_t f1_phy_reset_done(a_uint32_t dev_id, a_uint32_t phy_id); +a_bool_t f1_phy_get_link_status(a_uint32_t dev_id, a_uint32_t phy_id); + +static inline fal_cable_status_t +_fal_cdt_status_mapping(a_uint16_t status) +{ + fal_cable_status_t status_mapping = FAL_CABLE_STATUS_INVALID; + + if (0 == status) + status_mapping = FAL_CABLE_STATUS_INVALID; + else if (1 == status) + status_mapping = FAL_CABLE_STATUS_NORMAL; + else if (2 == status) + status_mapping = FAL_CABLE_STATUS_OPENED; + else if (3 == status) + status_mapping = FAL_CABLE_STATUS_SHORT; + + return status_mapping; +} + +static sw_error_t +f1_phy_cdt_start(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t status = 0; + a_uint16_t ii = 100; + + /* RUN CDT */ + f1_phy_reg_write(dev_id, phy_id, F1_PHY_CDT_CONTROL, RUN_CDT|CABLE_LENGTH_UNIT); + do + { + aos_mdelay(30); + status = f1_phy_reg_read(dev_id, phy_id, F1_PHY_CDT_CONTROL); + } + while ((status & RUN_CDT) && (--ii)); + + return SW_OK; +} + +sw_error_t +f1_phy_cdt_get(a_uint32_t dev_id, a_uint32_t phy_id, fal_port_cdt_t *port_cdt) +{ + a_uint16_t status = 0; + a_uint16_t cable_delta_time = 0; + a_uint16_t org_debug_value = 0; + int ii = 100; + a_bool_t link_st = A_FALSE; + a_uint16_t reg806e = 0; + int i; + + if((!port_cdt) || (phy_id > 4)) + { + return SW_FAIL; + } + + /*disable clock gating*/ + org_debug_value = f1_phy_debug_read(dev_id, phy_id, 0x3f); + f1_phy_debug_write(dev_id, phy_id, 0x3f, 0); + + f1_phy_cdt_start(dev_id, phy_id); + + /* Get cable status */ + status = f1_phy_mmd_read(dev_id, phy_id, 3, 0x8064); + + /* Workaround for cable lenth less than 20M */ + port_cdt->pair_c_status = (status >> 4) & 0x3; + /* Get Cable Length value */ + cable_delta_time = f1_phy_mmd_read(dev_id, phy_id, 3, 0x8067); + /* the actual cable length equals to CableDeltaTime * 0.824*/ + port_cdt->pair_c_len = (cable_delta_time * 824) /1000; + if ((1 == port_cdt->pair_c_status) && + (port_cdt->pair_c_len > 0) && (port_cdt->pair_c_len <= 20)) + { + reg806e = f1_phy_mmd_read(dev_id, phy_id, 3, 0x806e); + f1_phy_mmd_write(dev_id, phy_id, 3, 0x806e, reg806e & (~0x8000)); + + f1_phy_reset(dev_id, phy_id); + f1_phy_reset_done(dev_id, phy_id); + do + { + link_st = f1_phy_get_link_status(dev_id, phy_id); + aos_mdelay(100); + } while ((A_FALSE == link_st) && (--ii)); + + f1_phy_cdt_start(dev_id, phy_id); + /* Get cable status */ + status = f1_phy_mmd_read(dev_id, phy_id, 3, 0x8064); + } + + for (i=0;i<4;i++) + { + switch(i) + { + case 0: + port_cdt->pair_a_status = (status >> 12) & 0x3; + /* Get Cable Length value */ + cable_delta_time = f1_phy_mmd_read(dev_id, phy_id, 3, 0x8065); + /* the actual cable length equals to CableDeltaTime * 0.824*/ + port_cdt->pair_a_len = (cable_delta_time * 824) /1000; + + break; + case 1: + port_cdt->pair_b_status = (status >> 8) & 0x3; + /* Get Cable Length value */ + cable_delta_time = f1_phy_mmd_read(dev_id, phy_id, 3, 0x8066); + /* the actual cable length equals to CableDeltaTime * 0.824*/ + port_cdt->pair_b_len = (cable_delta_time * 824) /1000; + break; + case 2: + port_cdt->pair_c_status = (status >> 4) & 0x3; + /* Get Cable Length value */ + cable_delta_time = f1_phy_mmd_read(dev_id, phy_id, 3, 0x8067); + /* the actual cable length equals to CableDeltaTime * 0.824*/ + port_cdt->pair_c_len = (cable_delta_time * 824) /1000; + break; + case 3: + port_cdt->pair_d_status = status & 0x3; + /* Get Cable Length value */ + cable_delta_time = f1_phy_mmd_read(dev_id, phy_id, 3, 0x8068); + /* the actual cable length equals to CableDeltaTime * 0.824*/ + port_cdt->pair_d_len = (cable_delta_time * 824) /1000; + break; + default: + break; + } + } + + /*restore debug port value*/ + f1_phy_debug_write(dev_id, phy_id, 0x3f, org_debug_value); + + return SW_OK; +} + +sw_error_t +f1_phy_cdt(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t mdi_pair, + fal_cable_status_t *cable_status, a_uint32_t *cable_len) +{ + fal_port_cdt_t f1_port_cdt; + + if((mdi_pair >= 4) || (phy_id > 4)) + { + //There are only 4 mdi pairs in 1000BASE-T + return SW_BAD_PARAM; + } + + f1_phy_cdt_get(dev_id, phy_id, &f1_port_cdt); + + switch(mdi_pair) + { + case 0: + *cable_status = _fal_cdt_status_mapping(f1_port_cdt.pair_a_status); + /* Get Cable Length value */ + *cable_len = f1_port_cdt.pair_a_len; + break; + case 1: + *cable_status = _fal_cdt_status_mapping(f1_port_cdt.pair_b_status); + /* Get Cable Length value */ + *cable_len = f1_port_cdt.pair_b_len; + break; + case 2: + *cable_status = _fal_cdt_status_mapping(f1_port_cdt.pair_c_status); + /* Get Cable Length value */ + *cable_len = f1_port_cdt.pair_c_len; + break; + case 3: + *cable_status = _fal_cdt_status_mapping(f1_port_cdt.pair_d_status); + /* Get Cable Length value */ + *cable_len = f1_port_cdt.pair_d_len; + break; + default: + break; + } + + return SW_OK; +} +#else +sw_error_t +f1_phy_cdt(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t mdi_pair, + fal_cable_status_t *cable_status, a_uint32_t *cable_len) +{ + a_uint16_t status = 0; + a_uint16_t ii = 100; + a_uint16_t org_debug_value; + a_uint16_t cable_delta_time; + + if(!cable_status || !cable_len) + { + return SW_FAIL; + } + + if(mdi_pair >= 4) + { + //There are only 4 mdi pairs in 1000BASE-T + return SW_BAD_PARAM; + } + + org_debug_value = f1_phy_debug_read(dev_id, phy_id, 0x3f); + + /*disable clock gating*/ + f1_phy_debug_write(dev_id, phy_id, 0x3f, 0); + f1_phy_reg_write(dev_id, phy_id, F1_PHY_CDT_CONTROL, (mdi_pair << 8) | 0x0001); + + do + { + aos_mdelay(30); + status = f1_phy_reg_read(dev_id, phy_id, F1_PHY_CDT_CONTROL); + } + while ((status & 0x0001) && (--ii)); + + status = f1_phy_reg_read(dev_id, phy_id, F1_PHY_CDT_STATUS); + + *cable_status = (status&0x300) >> 8; + if ( (*cable_status == 1) || (*cable_status == 2)) + { + if ( mdi_pair == 1 || mdi_pair == 3 ) + { + /*Reverse the mdi status for channel 1 and channel 3*/ + *cable_status = (~(*cable_status)) & 0x3; + } + } + + /* the actual cable length equals to CableDeltaTime * 0.824*/ + cable_delta_time = status & 0xff; + *cable_len = (cable_delta_time * 824) /1000; + + /*restore debug port value*/ + f1_phy_debug_write(dev_id, phy_id, 0x3f, org_debug_value); + //f1_phy_reg_write(dev_id, phy_id, 0x00, 0x9000);//Reset the PHY if necessary + + return SW_OK; +} +#endif + +/****************************************************************************** +* +* f1_phy_reset_done - reset the phy +* +* reset the phy +*/ +a_bool_t +f1_phy_reset_done(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + a_uint16_t ii = 200; + + do + { + phy_data = f1_phy_reg_read(dev_id, phy_id, F1_PHY_CONTROL); + aos_mdelay(10); + } + while ((!F1_RESET_DONE(phy_data)) && --ii); + + if (ii == 0) + return A_FALSE; + + return A_TRUE; +} + +/****************************************************************************** +* +* f1_autoneg_done +* +* f1_autoneg_done +*/ +a_bool_t +f1_autoneg_done(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + a_uint16_t ii = 200; + + do + { + phy_data = f1_phy_reg_read(dev_id, phy_id, F1_PHY_STATUS); + aos_mdelay(10); + } + while ((!F1_AUTONEG_DONE(phy_data)) && --ii); + + if (ii == 0) + return A_FALSE; + + return A_TRUE; +} + +/****************************************************************************** +* +* f1_phy_Speed_Duplex_Resolved + - reset the phy +* +* reset the phy +*/ +a_bool_t +f1_phy_speed_duplex_resolved(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + a_uint16_t ii = 200; + + do + { + phy_data = f1_phy_reg_read(dev_id, phy_id, F1_PHY_SPEC_STATUS); + aos_mdelay(10); + } + while ((!F1_SPEED_DUPLEX_RESOVLED(phy_data)) && --ii); + + if (ii == 0) + return A_FALSE; + + return A_TRUE; +} + +/****************************************************************************** +* +* f1_phy_reset - reset the phy +* +* reset the phy +*/ +sw_error_t +f1_phy_reset(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + + phy_data = f1_phy_reg_read(dev_id, phy_id, F1_PHY_CONTROL); + f1_phy_reg_write(dev_id, phy_id, F1_PHY_CONTROL, + phy_data | F1_CTRL_SOFTWARE_RESET); + + return SW_OK; +} + +/****************************************************************************** +* +* f1_phy_off - power off the phy to change its speed +* +* Power off the phy +*/ +sw_error_t +f1_phy_poweroff(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + + phy_data = f1_phy_reg_read(dev_id, phy_id, F1_PHY_CONTROL); + f1_phy_reg_write(dev_id, phy_id, F1_PHY_CONTROL, + phy_data | F1_CTRL_POWER_DOWN); + + return SW_OK; +} + +/****************************************************************************** +* +* f1_phy_on - power on the phy after speed changed +* +* Power on the phy +*/ +sw_error_t +f1_phy_poweron(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + + phy_data = f1_phy_reg_read(dev_id, phy_id, F1_PHY_CONTROL); + f1_phy_reg_write(dev_id, phy_id, F1_PHY_CONTROL, + phy_data & ~F1_CTRL_POWER_DOWN); + + aos_mdelay(200); + + return SW_OK; +} + +/****************************************************************************** +* +* f1_phy_get_ability - get the phy ability +* +* +*/ +sw_error_t +f1_phy_get_ability(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * ability) +{ + a_uint16_t phy_data; + + *ability = 0; + phy_data = f1_phy_reg_read(dev_id, phy_id, F1_PHY_STATUS); + + if (phy_data & F1_STATUS_AUTONEG_CAPS) + *ability |= FAL_PHY_AUTONEG_CAPS; + + if (phy_data & F1_STATUS_100T2_HD_CAPS) + *ability |= FAL_PHY_100T2_HD_CAPS; + + if (phy_data & F1_STATUS_100T2_FD_CAPS) + *ability |= FAL_PHY_100T2_FD_CAPS; + + if (phy_data & F1_STATUS_10T_HD_CAPS) + *ability |= FAL_PHY_10T_HD_CAPS; + + if (phy_data & F1_STATUS_10T_FD_CAPS) + *ability |= FAL_PHY_10T_FD_CAPS; + + if (phy_data & F1_STATUS_100X_HD_CAPS) + *ability |= FAL_PHY_100X_HD_CAPS; + + if (phy_data & F1_STATUS_100X_FD_CAPS) + *ability |= FAL_PHY_100X_FD_CAPS; + + if (phy_data & F1_STATUS_100T4_CAPS) + *ability |= FAL_PHY_100T4_CAPS; + + if (phy_data & F1_STATUS_EXTENDED_STATUS) + { + phy_data = f1_phy_reg_read(dev_id, phy_id, F1_EXTENDED_STATUS); + + if (phy_data & F1_STATUS_1000T_FD_CAPS) + { + *ability |= FAL_PHY_1000T_FD_CAPS; + } + + if (phy_data & F1_STATUS_1000X_FD_CAPS) + { + *ability |= FAL_PHY_1000X_FD_CAPS; + } + } + + return SW_OK; +} + +/****************************************************************************** +* +* f1_phy_get_ability - get the phy ability +* +* +*/ +sw_error_t +f1_phy_get_partner_ability(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * ability) +{ + a_uint16_t phy_data; + + *ability = 0; + phy_data = f1_phy_reg_read(dev_id, phy_id, F1_LINK_PARTNER_ABILITY); + + if (phy_data & F1_LINK_10BASETX_HALF_DUPLEX) + *ability |= FAL_PHY_PART_10T_HD; + + if (phy_data & F1_LINK_10BASETX_FULL_DUPLEX) + *ability |= FAL_PHY_PART_10T_FD; + + if (phy_data & F1_LINK_100BASETX_HALF_DUPLEX) + *ability |= FAL_PHY_PART_100TX_HD; + + if (phy_data & F1_LINK_100BASETX_FULL_DUPLEX) + *ability |= FAL_PHY_PART_100TX_FD; + + if (phy_data & F1_LINK_NPAGE) + { + phy_data = f1_phy_reg_read(dev_id, phy_id, F1_1000BASET_STATUS); + + if (phy_data & F1_LINK_1000BASETX_FULL_DUPLEX) + *ability |= FAL_PHY_PART_1000T_FD; + } + + return SW_OK; +} + +/****************************************************************************** +* +* f1_phy_status - test to see if the specified phy link is alive +* +* RETURNS: +* A_TRUE --> link is alive +* A_FALSE --> link is down +*/ +a_bool_t +f1_phy_get_link_status(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + + phy_data = f1_phy_reg_read(dev_id, phy_id, F1_PHY_SPEC_STATUS); + + if (phy_data & F1_STATUS_LINK_PASS) + return A_TRUE; + + return A_FALSE; +} + +/****************************************************************************** +* +* f1_set_autoneg_adv - set the phy autoneg Advertisement +* +*/ +sw_error_t +f1_phy_set_autoneg_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t autoneg) +{ + a_uint16_t phy_data = 0; + + phy_data = f1_phy_reg_read(dev_id, phy_id, F1_AUTONEG_ADVERT); + phy_data &= ~F1_ADVERTISE_MEGA_ALL; + phy_data &= ~(F1_ADVERTISE_PAUSE | F1_ADVERTISE_ASYM_PAUSE); + + if (autoneg & FAL_PHY_ADV_100TX_FD) + phy_data |= F1_ADVERTISE_100FULL; + + if (autoneg & FAL_PHY_ADV_100TX_HD) + phy_data |= F1_ADVERTISE_100HALF; + + if (autoneg & FAL_PHY_ADV_10T_FD) + phy_data |= F1_ADVERTISE_10FULL; + + if (autoneg & FAL_PHY_ADV_10T_HD) + phy_data |= F1_ADVERTISE_10HALF; + + if (autoneg & FAL_PHY_ADV_PAUSE) + phy_data |= F1_ADVERTISE_PAUSE; + + if (autoneg & FAL_PHY_ADV_ASY_PAUSE) + phy_data |= F1_ADVERTISE_ASYM_PAUSE; + + f1_phy_reg_write(dev_id, phy_id, F1_AUTONEG_ADVERT, phy_data); + + phy_data = f1_phy_reg_read(dev_id, phy_id, F1_1000BASET_CONTROL); + phy_data &= ~F1_ADVERTISE_1000FULL; + phy_data &= ~F1_ADVERTISE_1000HALF; + + if (autoneg & FAL_PHY_ADV_1000T_FD) + phy_data |= F1_ADVERTISE_1000FULL; + + f1_phy_reg_write(dev_id, phy_id, F1_1000BASET_CONTROL, phy_data); + + return SW_OK; +} + +/****************************************************************************** +* +* f1_get_autoneg_adv - get the phy autoneg Advertisement +* +*/ +sw_error_t +f1_phy_get_autoneg_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * autoneg) +{ + a_uint16_t phy_data = 0; + + *autoneg = 0; + phy_data = f1_phy_reg_read(dev_id, phy_id, F1_AUTONEG_ADVERT); + + if (phy_data & F1_ADVERTISE_100FULL) + *autoneg |= FAL_PHY_ADV_100TX_FD; + + if (phy_data & F1_ADVERTISE_100HALF) + *autoneg |= FAL_PHY_ADV_100TX_HD; + + if (phy_data & F1_ADVERTISE_10FULL) + *autoneg |= FAL_PHY_ADV_10T_FD; + + if (phy_data & F1_ADVERTISE_10HALF) + *autoneg |= FAL_PHY_ADV_10T_HD; + + if (phy_data & F1_ADVERTISE_PAUSE) + *autoneg |= FAL_PHY_ADV_PAUSE; + + if (phy_data & F1_ADVERTISE_ASYM_PAUSE) + *autoneg |= FAL_PHY_ADV_ASY_PAUSE; + + phy_data = f1_phy_reg_read(dev_id, phy_id, F1_1000BASET_CONTROL); + + if (phy_data & F1_ADVERTISE_1000FULL) + *autoneg |= FAL_PHY_ADV_1000T_FD; + + return SW_OK; +} + +/****************************************************************************** +* +* f1_phy_enable_autonego - power off the phy to change its speed +* +* Power off the phy +*/ +a_bool_t +f1_phy_autoneg_status(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + + phy_data = f1_phy_reg_read(dev_id, phy_id, F1_PHY_CONTROL); + + if (phy_data & F1_CTRL_AUTONEGOTIATION_ENABLE) + return A_TRUE; + + return A_FALSE; +} + +/****************************************************************************** +* +* f1_restart_autoneg - restart the phy autoneg +* +*/ +sw_error_t +f1_phy_restart_autoneg(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data = 0; + + phy_data = f1_phy_reg_read(dev_id, phy_id, F1_PHY_CONTROL); + + phy_data |= F1_CTRL_AUTONEGOTIATION_ENABLE; + f1_phy_reg_write(dev_id, phy_id, F1_PHY_CONTROL, + phy_data | F1_CTRL_RESTART_AUTONEGOTIATION); + + return SW_OK; +} + +/****************************************************************************** +* +* f1_phy_enable_autonego - power off the phy to change its speed +* +* Power off the phy +*/ +sw_error_t +f1_phy_enable_autoneg(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data = 0; + + phy_data = f1_phy_reg_read(dev_id, phy_id, F1_PHY_CONTROL); + + f1_phy_reg_write(dev_id, phy_id, F1_PHY_CONTROL, + phy_data | F1_CTRL_AUTONEGOTIATION_ENABLE); + + return SW_OK; +} + + +/****************************************************************************** +* +* f1_phy_get_speed - Determines the speed of phy ports associated with the +* specified device. +*/ + +sw_error_t +f1_phy_get_speed(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_speed_t * speed) +{ + a_uint16_t phy_data; + a_bool_t auto_neg; + + auto_neg = f1_phy_autoneg_status(dev_id, phy_id); + if (A_TRUE == auto_neg ) { + phy_data = f1_phy_reg_read(dev_id, phy_id, F1_PHY_SPEC_STATUS); + switch (phy_data & F1_STATUS_SPEED_MASK) + { + case F1_STATUS_SPEED_1000MBS: + *speed = FAL_SPEED_1000; + break; + case F1_STATUS_SPEED_100MBS: + *speed = FAL_SPEED_100; + break; + case F1_STATUS_SPEED_10MBS: + *speed = FAL_SPEED_10; + break; + default: + return SW_READ_ERROR; + } + } + else + { + phy_data = f1_phy_reg_read(dev_id, phy_id, F1_PHY_CONTROL); + switch (phy_data & F1_CTRL_SPEED_MASK) + { + case F1_CTRL_SPEED_1000: + *speed = FAL_SPEED_1000; + break; + case F1_CTRL_SPEED_100: + *speed = FAL_SPEED_100; + break; + case F1_CTRL_SPEED_10: + *speed = FAL_SPEED_10; + break; + default: + return SW_READ_ERROR; + } + } + return SW_OK; +} + +/****************************************************************************** +* +* f1_phy_set_speed - Determines the speed of phy ports associated with the +* specified device. +*/ +sw_error_t +f1_phy_set_speed(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_speed_t speed) +{ + a_uint16_t phy_data = 0; + a_uint16_t phy_status = 0; + + a_uint32_t autoneg, oldneg; + fal_port_duplex_t old_duplex; + + if (FAL_SPEED_1000 == speed) + { + phy_data |= F1_CTRL_SPEED_1000; + phy_data |= F1_CTRL_AUTONEGOTIATION_ENABLE; + } + else if (FAL_SPEED_100 == speed) + { + phy_data |= F1_CTRL_SPEED_100; + phy_data &= ~F1_CTRL_AUTONEGOTIATION_ENABLE; + } + else if (FAL_SPEED_10 == speed) + { + phy_data |= F1_CTRL_SPEED_10; + phy_data &= ~F1_CTRL_AUTONEGOTIATION_ENABLE; + } + else + { + return SW_BAD_PARAM; + } + + (void)f1_phy_get_autoneg_adv(dev_id, phy_id, &autoneg); + oldneg = autoneg; + autoneg &= ~FAL_PHY_ADV_GE_SPEED_ALL; + + (void)f1_phy_get_duplex(dev_id, phy_id, &old_duplex); + + if (old_duplex == FAL_FULL_DUPLEX) + { + phy_data |= F1_CTRL_FULL_DUPLEX; + + if (FAL_SPEED_1000 == speed) + { + autoneg |= FAL_PHY_ADV_1000T_FD; + } + else if (FAL_SPEED_100 == speed) + { + autoneg |= FAL_PHY_ADV_100TX_FD; + } + else + { + autoneg |= FAL_PHY_ADV_10T_FD; + } + } + else if (old_duplex == FAL_HALF_DUPLEX) + { + phy_data &= ~F1_CTRL_FULL_DUPLEX; + + if (FAL_SPEED_100 == speed) + { + autoneg |= FAL_PHY_ADV_100TX_HD; + } + else + { + autoneg |= FAL_PHY_ADV_10T_HD; + } + } + else + { + return SW_FAIL; + } + + (void)f1_phy_set_autoneg_adv(dev_id, phy_id, autoneg); + (void)f1_phy_restart_autoneg(dev_id, phy_id); + if(f1_phy_get_link_status(dev_id, phy_id)) + { + do + { + phy_status = f1_phy_reg_read(dev_id, phy_id, F1_PHY_STATUS); + } + while(!F1_AUTONEG_DONE(phy_status)); + } + + f1_phy_reg_write(dev_id, phy_id, F1_PHY_CONTROL, phy_data); + (void)f1_phy_set_autoneg_adv(dev_id, phy_id, oldneg); + + return SW_OK; + +} + +/****************************************************************************** +* +* f1_phy_get_duplex - Determines the speed of phy ports associated with the +* specified device. +*/ +sw_error_t +f1_phy_get_duplex(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_duplex_t * duplex) +{ + a_uint16_t phy_data; + a_bool_t auto_neg; + + auto_neg = f1_phy_autoneg_status(dev_id, phy_id); + if (A_TRUE == auto_neg ) { + phy_data = f1_phy_reg_read(dev_id, phy_id, F1_PHY_SPEC_STATUS); + + //read duplex + if (phy_data & F1_STATUS_FULL_DUPLEX) + *duplex = FAL_FULL_DUPLEX; + else + *duplex = FAL_HALF_DUPLEX; + } + else + { + phy_data = f1_phy_reg_read(dev_id, phy_id, F1_PHY_CONTROL); + //read duplex + if (phy_data & F1_CTRL_FULL_DUPLEX) + *duplex = FAL_FULL_DUPLEX; + else + *duplex = FAL_HALF_DUPLEX; + } + return SW_OK; +} + +/****************************************************************************** +* +* f1_phy_set_duplex - Determines the speed of phy ports associated with the +* specified device. +*/ +sw_error_t +f1_phy_set_duplex(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_duplex_t duplex) +{ + a_uint16_t phy_data = 0; + a_uint16_t phy_status = 0; + + fal_port_speed_t old_speed = FAL_SPEED_10; + a_uint32_t oldneg, autoneg; + + if (A_TRUE == f1_phy_autoneg_status(dev_id, phy_id)) + phy_data &= ~F1_CTRL_AUTONEGOTIATION_ENABLE; + + (void)f1_phy_get_autoneg_adv(dev_id, phy_id, &autoneg); + oldneg = autoneg; + autoneg &= ~FAL_PHY_ADV_GE_SPEED_ALL; + (void)f1_phy_get_speed(dev_id, phy_id, &old_speed); + + if (FAL_SPEED_1000 == old_speed) + { + phy_data |= F1_CTRL_SPEED_1000; + phy_data |= F1_CTRL_AUTONEGOTIATION_ENABLE; + } + else if (FAL_SPEED_100 == old_speed) + { + phy_data |= F1_CTRL_SPEED_100; + } + else if (FAL_SPEED_10 == old_speed) + { + phy_data |= F1_CTRL_SPEED_10; + } + else + { + return SW_FAIL; + } + + if (duplex == FAL_FULL_DUPLEX) + { + phy_data |= F1_CTRL_FULL_DUPLEX; + + if (FAL_SPEED_1000 == old_speed) + { + autoneg = FAL_PHY_ADV_1000T_FD; + } + else if (FAL_SPEED_100 == old_speed) + { + autoneg = FAL_PHY_ADV_100TX_FD; + } + else + { + autoneg = FAL_PHY_ADV_10T_FD; + } + } + else if (duplex == FAL_HALF_DUPLEX) + { + phy_data &= ~F1_CTRL_FULL_DUPLEX; + + if (FAL_SPEED_100 == old_speed) + { + autoneg = FAL_PHY_ADV_100TX_HD; + } + else + { + autoneg = FAL_PHY_ADV_10T_HD; + } + } + else + { + return SW_BAD_PARAM; + } + + (void)f1_phy_set_autoneg_adv(dev_id, phy_id, autoneg); + (void)f1_phy_restart_autoneg(dev_id, phy_id); + if(f1_phy_get_link_status(dev_id, phy_id)) + { + do + { + phy_status = f1_phy_reg_read(dev_id, phy_id, F1_PHY_STATUS); + } + while(!F1_AUTONEG_DONE(phy_status)); + } + + f1_phy_reg_write(dev_id, phy_id, F1_PHY_CONTROL, phy_data); + (void)f1_phy_set_autoneg_adv(dev_id, phy_id, oldneg); + + return SW_OK; +} + +/****************************************************************************** +* +* f1_phy_get_phy_id - get the phy id +* +*/ +static sw_error_t +f1_phy_get_phy_id(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *phy_data) +{ + a_uint16_t org_id, rev_id; + + org_id = f1_phy_reg_read(dev_id, phy_id, F1_PHY_ID1); + rev_id = f1_phy_reg_read(dev_id, phy_id, F1_PHY_ID2); + *phy_data = ((org_id & 0xffff) << 16) | (rev_id & 0xffff); + + return SW_OK; +} + +/****************************************************************************** +* +* f1_phy_intr_mask_set - Set interrupt mask with the +* specified device. +*/ +sw_error_t +f1_phy_intr_mask_set(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t intr_mask_flag) +{ + a_uint16_t phy_data = 0; + + phy_data = f1_phy_reg_read(dev_id, phy_id, F1_PHY_INTR_MASK); + + if (FAL_PHY_INTR_STATUS_UP_CHANGE & intr_mask_flag) + { + phy_data |= F1_INTR_STATUS_UP_CHANGE; + } + else + { + phy_data &= (~F1_INTR_STATUS_UP_CHANGE); + } + + if (FAL_PHY_INTR_STATUS_DOWN_CHANGE & intr_mask_flag) + { + phy_data |= F1_INTR_STATUS_DOWN_CHANGE; + } + else + { + phy_data &= (~F1_INTR_STATUS_DOWN_CHANGE); + } + + if (FAL_PHY_INTR_SPEED_CHANGE & intr_mask_flag) + { + phy_data |= F1_INTR_SPEED_CHANGE; + } + else + { + phy_data &= (~F1_INTR_SPEED_CHANGE); + } + + if (FAL_PHY_INTR_DUPLEX_CHANGE & intr_mask_flag) + { + phy_data |= F1_INTR_DUPLEX_CHANGE; + } + else + { + phy_data &= (~F1_INTR_DUPLEX_CHANGE); + } + + f1_phy_reg_write(dev_id, phy_id, F1_PHY_INTR_MASK, phy_data); + return SW_OK; +} + +/****************************************************************************** +* +* f1_phy_intr_mask_get - Get interrupt mask with the +* specified device. +*/ +sw_error_t +f1_phy_intr_mask_get(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * intr_mask_flag) +{ + a_uint16_t phy_data = 0; + + phy_data = f1_phy_reg_read(dev_id, phy_id, F1_PHY_INTR_MASK); + + *intr_mask_flag = 0; + if (F1_INTR_STATUS_UP_CHANGE & phy_data) + { + *intr_mask_flag |= FAL_PHY_INTR_STATUS_UP_CHANGE; + } + + if (F1_INTR_STATUS_DOWN_CHANGE & phy_data) + { + *intr_mask_flag |= FAL_PHY_INTR_STATUS_DOWN_CHANGE; + } + + if (F1_INTR_SPEED_CHANGE & phy_data) + { + *intr_mask_flag |= FAL_PHY_INTR_SPEED_CHANGE; + } + + if (F1_INTR_DUPLEX_CHANGE & phy_data) + { + *intr_mask_flag |= FAL_PHY_INTR_DUPLEX_CHANGE; + } + + return SW_OK; +} + +/****************************************************************************** +* +* f1_phy_intr_status_get - Get interrupt status with the +* specified device. +*/ +sw_error_t +f1_phy_intr_status_get(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * intr_status_flag) +{ + a_uint16_t phy_data = 0; + + phy_data = f1_phy_reg_read(dev_id, phy_id, F1_PHY_INTR_STATUS); + + *intr_status_flag = 0; + if (F1_INTR_STATUS_UP_CHANGE & phy_data) + { + *intr_status_flag |= FAL_PHY_INTR_STATUS_UP_CHANGE; + } + + if (F1_INTR_STATUS_DOWN_CHANGE & phy_data) + { + *intr_status_flag |= FAL_PHY_INTR_STATUS_DOWN_CHANGE; + } + + if (F1_INTR_SPEED_CHANGE & phy_data) + { + *intr_status_flag |= FAL_PHY_INTR_SPEED_CHANGE; + } + + if (F1_INTR_DUPLEX_CHANGE & phy_data) + { + *intr_status_flag |= FAL_PHY_INTR_DUPLEX_CHANGE; + } + + return SW_OK; +} +/****************************************************************************** +* +*f1_phy_set_8023az status +* +* get 8023az status +*/ + +sw_error_t +f1_phy_set_8023az(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable) +{ + a_uint16_t phy_data; + + phy_data = f1_phy_mmd_read(dev_id, phy_id, F1_PHY_MMD7_NUM, + F1_PHY_8023AZ_EEE_CTRL); + if (enable == A_TRUE) { + phy_data |= F1_PHY_AZ_ENABLE; + + f1_phy_mmd_write(dev_id, phy_id, F1_PHY_MMD7_NUM, + F1_PHY_8023AZ_EEE_CTRL, phy_data); + } else { + phy_data &= ~F1_PHY_AZ_ENABLE; + + f1_phy_mmd_write(dev_id, phy_id, F1_PHY_MMD7_NUM, + F1_PHY_8023AZ_EEE_CTRL, phy_data); + } + + f1_phy_restart_autoneg(dev_id, phy_id); + + return SW_OK; +} + +/****************************************************************************** +* +*f1_phy_get_8023az status +* +* get 8023az status +*/ +sw_error_t +f1_phy_get_8023az(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t * enable) +{ + a_uint16_t phy_data; + + *enable = A_FALSE; + + phy_data = f1_phy_mmd_read(dev_id, phy_id, F1_PHY_MMD7_NUM, + F1_PHY_8023AZ_EEE_CTRL); + + if ((phy_data & 0x6) == F1_PHY_AZ_ENABLE) + *enable = A_TRUE; + + return SW_OK; +} + +/****************************************************************************** +* +* f1_phy_set_local_loopback +* +* set phy local loopback +*/ +sw_error_t +f1_phy_set_local_loopback(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable) +{ + a_uint16_t phy_data; + fal_port_speed_t old_speed; + sw_error_t rv = SW_OK; + + if (enable == A_TRUE) { + rv = f1_phy_get_speed(dev_id, phy_id, &old_speed); + SW_RTN_ON_ERROR(rv); + + if (old_speed == FAL_SPEED_1000) { + phy_data = F1_1000M_LOOPBACK; + } else if (old_speed == FAL_SPEED_100) { + phy_data = F1_100M_LOOPBACK; + } else if (old_speed == FAL_SPEED_10) { + phy_data = F1_10M_LOOPBACK; + } else { + return SW_FAIL; + } + phy_data |= F1_CTRL_FULL_DUPLEX; + } else { + phy_data = F1_COMMON_CTRL; + } + + rv = f1_phy_reg_write(dev_id, phy_id, F1_PHY_CONTROL, phy_data); + + return rv; +} + +/****************************************************************************** +* +* f1_phy_get_local_loopback +* +* get phy local loopback +*/ +sw_error_t +f1_phy_get_local_loopback(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t * enable) +{ + a_uint16_t phy_data; + + phy_data = f1_phy_reg_read(dev_id, phy_id, F1_PHY_CONTROL); + + if (phy_data & F1_LOCAL_LOOPBACK_ENABLE) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +/****************************************************************************** +* +* f1_phy_set_remote_loopback +* +* set phy remote loopback +*/ +sw_error_t +f1_phy_set_remote_loopback(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable) +{ + a_uint16_t phy_data; + sw_error_t rv = SW_OK; + + phy_data = f1_phy_mmd_read(dev_id, phy_id, F1_PHY_MMD3_NUM, + F1_PHY_MMD3_ADDR_REMOTE_LOOPBACK_CTRL); + + if (enable == A_TRUE) + { + phy_data |= F1_PHY_REMOTE_LOOPBACK_ENABLE; + } + else + { + phy_data &= ~F1_PHY_REMOTE_LOOPBACK_ENABLE; + } + + rv = f1_phy_mmd_write(dev_id, phy_id, F1_PHY_MMD3_NUM, + F1_PHY_MMD3_ADDR_REMOTE_LOOPBACK_CTRL, phy_data); + + return rv; +} + +/****************************************************************************** +* +* f1_phy_get_remote_loopback +* +* get phy remote loopback +*/ +sw_error_t +f1_phy_get_remote_loopback(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t * enable) +{ + a_uint16_t phy_data; + + phy_data = f1_phy_mmd_read(dev_id, phy_id, F1_PHY_MMD3_NUM, + F1_PHY_MMD3_ADDR_REMOTE_LOOPBACK_CTRL); + + if (phy_data & F1_PHY_REMOTE_LOOPBACK_ENABLE) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static int f1_phy_api_ops_init(void) +{ + int ret; + hsl_phy_ops_t *f1_phy_api_ops = NULL; + + f1_phy_api_ops = kzalloc(sizeof(hsl_phy_ops_t), GFP_KERNEL); + if (f1_phy_api_ops == NULL) { + SSDK_ERROR("f1 phy ops kzalloc failed!\n"); + return -ENOMEM; + } + + phy_api_ops_init(F1_PHY_CHIP); + + f1_phy_api_ops->phy_hibernation_set = f1_phy_set_hibernate; + f1_phy_api_ops->phy_hibernation_get = f1_phy_get_hibernate; + f1_phy_api_ops->phy_speed_get = f1_phy_get_speed; + f1_phy_api_ops->phy_speed_set = f1_phy_set_speed; + f1_phy_api_ops->phy_duplex_get = f1_phy_get_duplex; + f1_phy_api_ops->phy_duplex_set = f1_phy_set_duplex; + f1_phy_api_ops->phy_autoneg_enable_set = f1_phy_enable_autoneg; + f1_phy_api_ops->phy_restart_autoneg = f1_phy_restart_autoneg; + f1_phy_api_ops->phy_autoneg_status_get = f1_phy_autoneg_status; + f1_phy_api_ops->phy_autoneg_adv_set = f1_phy_set_autoneg_adv; + f1_phy_api_ops->phy_autoneg_adv_get = f1_phy_get_autoneg_adv; + f1_phy_api_ops->phy_powersave_set = f1_phy_set_powersave; + f1_phy_api_ops->phy_powersave_get = f1_phy_get_powersave; + f1_phy_api_ops->phy_cdt = f1_phy_cdt; + f1_phy_api_ops->phy_link_status_get = f1_phy_get_link_status; + f1_phy_api_ops->phy_reset = f1_phy_reset; + f1_phy_api_ops->phy_power_off = f1_phy_poweroff; + f1_phy_api_ops->phy_power_on = f1_phy_poweron; + f1_phy_api_ops->phy_id_get = f1_phy_get_phy_id; + f1_phy_api_ops->phy_reg_write = f1_phy_reg_write; + f1_phy_api_ops->phy_reg_read = f1_phy_reg_read; + f1_phy_api_ops->phy_debug_write = f1_phy_debug_write; + f1_phy_api_ops->phy_debug_read = f1_phy_debug_read; + f1_phy_api_ops->phy_mmd_write = f1_phy_mmd_write; + f1_phy_api_ops->phy_mmd_read = f1_phy_mmd_read; + f1_phy_api_ops->phy_local_loopback_set = f1_phy_set_local_loopback; + f1_phy_api_ops->phy_local_loopback_get = f1_phy_get_local_loopback; + f1_phy_api_ops->phy_remote_loopback_set = f1_phy_set_remote_loopback; + f1_phy_api_ops->phy_remote_loopback_get = f1_phy_get_remote_loopback; + f1_phy_api_ops->phy_intr_mask_set = f1_phy_intr_mask_set; + f1_phy_api_ops->phy_intr_mask_get = f1_phy_intr_mask_get; + f1_phy_api_ops->phy_intr_status_get = f1_phy_intr_status_get; + f1_phy_api_ops->phy_8023az_set = f1_phy_set_8023az; + f1_phy_api_ops->phy_8023az_get = f1_phy_get_8023az; + + ret = hsl_phy_api_ops_register(F1_PHY_CHIP, f1_phy_api_ops); + + if (ret == 0) + SSDK_INFO("qca probe f1 phy driver succeeded!\n"); + else + SSDK_ERROR("qca probe f1 phy driver failed! (code: %d)\n", ret); + return ret; +} + +int f1_phy_init(a_uint32_t dev_id, a_uint32_t port_bmp) +{ + static a_uint32_t phy_ops_flag = 0; + + if(phy_ops_flag == 0) { + f1_phy_api_ops_init(); + phy_ops_flag = 1; + } + + return 0; +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/f2_phy.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/f2_phy.c new file mode 100755 index 000000000..07429446c --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/f2_phy.c @@ -0,0 +1,918 @@ +/* + * Copyright (c) 2012, 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. + */ + +#include "sw.h" +#include "fal_port_ctrl.h" +#include "hsl_api.h" +#include "hsl.h" +#include "f2_phy.h" +#include "hsl_phy.h" +#include "ssdk_plat.h" + +static a_uint16_t +_phy_reg_read(a_uint32_t dev_id, a_uint32_t phy_addr, a_uint8_t reg) +{ + sw_error_t rv; + a_uint16_t val = 0; + + HSL_PHY_GET(rv, dev_id, phy_addr, reg, &val); + if (SW_OK != rv) + return 0xFFFF; + + return val; +} + + +static sw_error_t +_phy_reg_write(a_uint32_t dev_id, a_uint32_t phy_addr, a_uint8_t reg, + a_uint16_t val) +{ + sw_error_t rv; + + HSL_PHY_SET(rv, dev_id, phy_addr, reg, val); + + return rv; +} + +/* #define f2_phy_reg_read _phy_reg_read */ +/* #define f2_phy_reg_write _phy_reg_write */ + +/****************************************************************************** +* +* f2_phy_mii_read - mii register read +* +* mil register read +*/ +a_uint16_t +f2_phy_reg_read(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t reg_id) +{ + return _phy_reg_read(dev_id, phy_id, reg_id); + +} + +/****************************************************************************** +* +* f2_phy_reg_write - mii register write +* +* mii register write +*/ +sw_error_t +f2_phy_reg_write(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t reg_id, + a_uint16_t reg_val) +{ + + _phy_reg_write(dev_id,phy_id, reg_id, reg_val); + + return SW_OK; +} + + +/****************************************************************************** +* +* f2_phy_debug_write - debug port write +* +* debug port write +*/ +sw_error_t +f2_phy_debug_write(a_uint32_t dev_id, a_uint32_t phy_id, a_uint16_t reg_id, + a_uint16_t reg_val) +{ + f2_phy_reg_write(dev_id, phy_id, F2_DEBUG_PORT_ADDRESS, reg_id); + f2_phy_reg_write(dev_id, phy_id, F2_DEBUG_PORT_DATA, reg_val); + + return SW_OK; +} + +/****************************************************************************** +* +* f2_phy_debug_read - debug port read +* +* debug port read +*/ +a_uint16_t +f2_phy_debug_read(a_uint32_t dev_id, a_uint32_t phy_id, a_uint16_t reg_id) +{ + f2_phy_reg_write(dev_id, phy_id, F2_DEBUG_PORT_ADDRESS, reg_id); + return f2_phy_reg_read(dev_id, phy_id, F2_DEBUG_PORT_DATA); +} + +/****************************************************************************** +* +* f2_phy_set_powersave - set power saving status +* +* set power saving status +*/ +sw_error_t +f2_phy_set_powersave(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable) +{ + a_uint16_t phy_data; + f2_phy_reg_write(dev_id, phy_id, F2_DEBUG_PORT_ADDRESS, 0x29); + phy_data = f2_phy_reg_read(dev_id, phy_id, F2_DEBUG_PORT_DATA); + + if(enable == A_TRUE) + { + phy_data |= 0x8000; + } + else + { + phy_data &= ~0x8000; + } + + f2_phy_reg_write(dev_id, phy_id, F2_DEBUG_PORT_DATA, phy_data); + + return SW_OK; +} + +/****************************************************************************** +* +* f2_phy_get_powersave - get power saving status +* +* set power saving status +*/ +sw_error_t +f2_phy_get_powersave(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t *enable) +{ + a_uint16_t phy_data; + *enable = A_FALSE; + + f2_phy_reg_write(dev_id, phy_id, F2_DEBUG_PORT_ADDRESS, 0x29); + phy_data = f2_phy_reg_read(dev_id, phy_id, F2_DEBUG_PORT_DATA); + + if(phy_data & 0x8000) + *enable = A_TRUE; + + return SW_OK; +} + +/****************************************************************************** +* +* f2_phy_set_hibernate - set hibernate status +* +* set hibernate status +*/ +sw_error_t +f2_phy_set_hibernate(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable) +{ + a_uint16_t phy_data; + f2_phy_reg_write(dev_id, phy_id, F2_DEBUG_PORT_ADDRESS, 0xb); + phy_data = f2_phy_reg_read(dev_id, phy_id, F2_DEBUG_PORT_DATA); + + if(enable == A_TRUE) + { + phy_data |= 0x8000; + } + else + { + phy_data &= ~0x8000; + } + + f2_phy_reg_write(dev_id, phy_id, F2_DEBUG_PORT_DATA, phy_data); + + return SW_OK; +} + +/****************************************************************************** +* +* f2_phy_get_hibernate - get hibernate status +* +* get hibernate status +*/ +sw_error_t +f2_phy_get_hibernate(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t *enable) +{ + a_uint16_t phy_data; + *enable = A_FALSE; + + f2_phy_reg_write(dev_id, phy_id, F2_DEBUG_PORT_ADDRESS, 0xb); + phy_data = f2_phy_reg_read(dev_id, phy_id, F2_DEBUG_PORT_DATA); + + if(phy_data & 0x8000) + *enable = A_TRUE; + + return SW_OK; +} + +/****************************************************************************** +* +* f2_phy_cdt - cable diagnostic test +* +* cable diagnostic test +*/ +sw_error_t +f2_phy_cdt(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t mdi_pair, + fal_cable_status_t *cable_status, a_uint32_t *cable_len) +{ + a_uint16_t status = 0; + a_uint16_t ii = 100; + a_uint16_t cable_delta_time; + + if(!cable_status || !cable_len) + { + return SW_FAIL; + } + + if(mdi_pair >= 2) + { + //There are only 4 mdi pairs in 1000BASE-T + return SW_BAD_PARAM; + } + + f2_phy_reg_write(dev_id, phy_id, F2_PHY_CDT_CONTROL, (mdi_pair << 8) | 0x0001); + + do + { + aos_mdelay(30); + status = f2_phy_reg_read(dev_id, phy_id, F2_PHY_CDT_CONTROL); + } + while ((status & 0x0001) && (--ii)); + + status = f2_phy_reg_read(dev_id, phy_id, F2_PHY_CDT_STATUS); + *cable_status = (status & 0x300) >> 8;//(00:normal 01:short 10:opened 11:invalid) + + /*the actual cable length equals to CableDeltaTime * 0.824*/ + cable_delta_time = status & 0xff; + *cable_len = (cable_delta_time * 824) /1000; + + /*workaround*/ + if(*cable_len <= 2 && *cable_status == 1) + *cable_status = 2; + + //f2_phy_reg_write(dev_id, phy_id, 0x00, 0x9000); //Reset the PHY if necessary + + return SW_OK; +} + +/****************************************************************************** +* +* f2_phy_reset_done - reset the phy +* +* reset the phy +*/ +a_bool_t +f2_phy_reset_done(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + a_uint16_t ii = 200; + + do + { + phy_data = f2_phy_reg_read(dev_id, phy_id, F2_PHY_CONTROL); + aos_mdelay(10); + } + while ((!F2_RESET_DONE(phy_data)) && --ii); + + if (ii == 0) + return A_FALSE; + + return A_TRUE; +} + +/****************************************************************************** +* +* f2_autoneg_done +* +* f2_autoneg_done +*/ +a_bool_t +f2_autoneg_done(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + a_uint16_t ii = 200; + + do + { + phy_data = f2_phy_reg_read(dev_id, phy_id, F2_PHY_STATUS); + aos_mdelay(10); + } + while ((!F2_AUTONEG_DONE(phy_data)) && --ii); + + if (ii == 0) + return A_FALSE; + + return A_TRUE; +} + +/****************************************************************************** +* +* f2_phy_Speed_Duplex_Resolved + - reset the phy +* +* reset the phy +*/ +a_bool_t +f2_phy_speed_duplex_resolved(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + a_uint16_t ii = 200; + + do + { + phy_data = f2_phy_reg_read(dev_id, phy_id, F2_PHY_SPEC_STATUS); + aos_mdelay(10); + } + while ((!F2_SPEED_DUPLEX_RESOVLED(phy_data)) && --ii); + + if (ii == 0) + return A_FALSE; + + return A_TRUE; +} + +/****************************************************************************** +* +* f2_phy_reset - reset the phy +* +* reset the phy +*/ +sw_error_t +f2_phy_reset(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + + phy_data = f2_phy_reg_read(dev_id, phy_id, F2_PHY_CONTROL); + f2_phy_reg_write(dev_id, phy_id, F2_PHY_CONTROL, + phy_data | F2_CTRL_SOFTWARE_RESET); + + return SW_OK; +} + +/****************************************************************************** +* +* f2_phy_off - power off the phy to change its speed +* +* Power off the phy +*/ +sw_error_t +f2_phy_poweroff(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + + phy_data = f2_phy_reg_read(dev_id, phy_id, F2_PHY_CONTROL); + f2_phy_reg_write(dev_id, phy_id, F2_PHY_CONTROL, + phy_data | F2_CTRL_POWER_DOWN); + + return SW_OK; +} + +/****************************************************************************** +* +* f2_phy_on - power on the phy after speed changed +* +* Power on the phy +*/ +sw_error_t +f2_phy_poweron(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + + phy_data = f2_phy_reg_read(dev_id, phy_id, F2_PHY_CONTROL); + f2_phy_reg_write(dev_id, phy_id, F2_PHY_CONTROL, + phy_data & ~F2_CTRL_POWER_DOWN); + + aos_mdelay(200); + + return SW_OK; +} + +/****************************************************************************** +* +* f2_phy_get_ability - get the phy ability +* +* +*/ +sw_error_t +f2_phy_get_ability(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint16_t * ability) +{ + a_uint16_t phy_data; + + *ability = 0; + + phy_data = f2_phy_reg_read(dev_id, phy_id, F2_PHY_STATUS); + + if (phy_data & F2_STATUS_AUTONEG_CAPS) + *ability |= FAL_PHY_AUTONEG_CAPS; + + if (phy_data & F2_STATUS_100T2_HD_CAPS) + *ability |= FAL_PHY_100T2_HD_CAPS; + + if (phy_data & F2_STATUS_100T2_FD_CAPS) + *ability |= FAL_PHY_100T2_FD_CAPS; + + if (phy_data & F2_STATUS_10T_HD_CAPS) + *ability |= FAL_PHY_10T_HD_CAPS; + + if (phy_data & F2_STATUS_10T_FD_CAPS) + *ability |= FAL_PHY_10T_FD_CAPS; + + if (phy_data & F2_STATUS_100X_HD_CAPS) + *ability |= FAL_PHY_100X_HD_CAPS; + + if (phy_data & F2_STATUS_100X_FD_CAPS) + *ability |= FAL_PHY_100X_FD_CAPS; + + if (phy_data & F2_STATUS_100T4_CAPS) + *ability |= FAL_PHY_100T4_CAPS; + + return SW_OK; +} + +/****************************************************************************** +* +* f2_phy_get_ability - get the phy ability +* +* +*/ +sw_error_t +f2_phy_get_partner_ability(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint16_t * ability) +{ + a_uint16_t phy_data; + + *ability = 0; + + phy_data = f2_phy_reg_read(dev_id, phy_id, F2_LINK_PARTNER_ABILITY); + + if (phy_data & F2_LINK_10BASETX_HALF_DUPLEX) + *ability |= FAL_PHY_PART_10T_HD; + + if (phy_data & F2_LINK_10BASETX_FULL_DUPLEX) + *ability |= FAL_PHY_PART_10T_FD; + + if (phy_data & F2_LINK_100BASETX_HALF_DUPLEX) + *ability |= FAL_PHY_PART_100TX_HD; + + if (phy_data & F2_LINK_100BASETX_FULL_DUPLEX) + *ability |= FAL_PHY_PART_100TX_FD; + + return SW_OK; +} + +/****************************************************************************** +* +* f2_phy_status - test to see if the specified phy link is alive +* +* RETURNS: +* A_TRUE --> link is alive +* A_FALSE --> link is down +*/ +a_bool_t +f2_phy_get_link_status(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + + phy_data = f2_phy_reg_read(dev_id, phy_id, F2_PHY_STATUS); + + if (phy_data & F2_STATUS_LINK_STATUS_UP) + return A_TRUE; + + return A_FALSE; +} + +/****************************************************************************** +* +* f2_set_autoneg_adv - set the phy autoneg Advertisement +* +*/ +sw_error_t +f2_phy_set_autoneg_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t autoneg) +{ + a_uint16_t phy_data = 0; + + phy_data = f2_phy_reg_read(dev_id, phy_id, F2_AUTONEG_ADVERT); + phy_data &= ~F2_ADVERTISE_ALL; + phy_data &= ~(F2_ADVERTISE_PAUSE | F2_ADVERTISE_ASYM_PAUSE); + + if (autoneg & FAL_PHY_ADV_100TX_FD) + phy_data |= F2_ADVERTISE_100FULL; + + if (autoneg & FAL_PHY_ADV_100TX_HD) + phy_data |= F2_ADVERTISE_100HALF; + + if (autoneg & FAL_PHY_ADV_10T_FD) + phy_data |= F2_ADVERTISE_10FULL; + + if (autoneg & FAL_PHY_ADV_10T_HD) + phy_data |= F2_ADVERTISE_10HALF; + + if (autoneg & FAL_PHY_ADV_PAUSE) + phy_data |= F2_ADVERTISE_PAUSE; + + if (autoneg & FAL_PHY_ADV_ASY_PAUSE) + phy_data |= F2_ADVERTISE_ASYM_PAUSE; + + f2_phy_reg_write(dev_id, phy_id, F2_AUTONEG_ADVERT, phy_data); + + return SW_OK; +} + +/****************************************************************************** +* +* f2_get_autoneg_adv - get the phy autoneg Advertisement +* +*/ +sw_error_t +f2_phy_get_autoneg_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * autoneg) +{ + a_uint16_t phy_data = 0; + + *autoneg = 0; + + phy_data = f2_phy_reg_read(dev_id, phy_id, F2_AUTONEG_ADVERT); + + if (phy_data & F2_ADVERTISE_100FULL) + *autoneg |= FAL_PHY_ADV_100TX_FD; + + if (phy_data & F2_ADVERTISE_100HALF) + *autoneg |= FAL_PHY_ADV_100TX_HD; + + if (phy_data & F2_ADVERTISE_10FULL) + *autoneg |= FAL_PHY_ADV_10T_FD; + + if (phy_data & F2_ADVERTISE_10HALF) + *autoneg |= FAL_PHY_ADV_10T_HD; + + if (phy_data & F2_ADVERTISE_PAUSE) + *autoneg |= FAL_PHY_ADV_PAUSE; + + if (phy_data & F2_ADVERTISE_ASYM_PAUSE) + *autoneg |= FAL_PHY_ADV_ASY_PAUSE; + + return SW_OK; +} + +/****************************************************************************** +* +* f2_phy_enable_autonego - power off the phy to change its speed +* +* Power off the phy +*/ +a_bool_t +f2_phy_autoneg_status(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + + phy_data = f2_phy_reg_read(dev_id, phy_id, F2_PHY_CONTROL); + + if (phy_data & F2_CTRL_AUTONEGOTIATION_ENABLE) + return A_TRUE; + + return A_FALSE; +} + +/****************************************************************************** +* +* f2_restart_autoneg - restart the phy autoneg +* +*/ +sw_error_t +f2_phy_restart_autoneg(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data = 0; + + phy_data = f2_phy_reg_read(dev_id, phy_id, F2_PHY_CONTROL); + + phy_data |= F2_CTRL_AUTONEGOTIATION_ENABLE; + f2_phy_reg_write(dev_id, phy_id, F2_PHY_CONTROL, + phy_data | F2_CTRL_RESTART_AUTONEGOTIATION); + + return SW_OK; +} + +/****************************************************************************** +* +* f2_phy_enable_autonego - power off the phy to change its speed +* +* Power off the phy +*/ +sw_error_t +f2_phy_enable_autoneg(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data = 0; + + phy_data = f2_phy_reg_read(dev_id, phy_id, F2_PHY_CONTROL); + + f2_phy_reg_write(dev_id, phy_id, F2_PHY_CONTROL, + phy_data | F2_CTRL_AUTONEGOTIATION_ENABLE); + + return SW_OK; +} + + +/****************************************************************************** +* +* f2_phy_get_speed - Determines the speed of phy ports associated with the +* specified device. +* +* RETURNS: +* AG7100_PHY_SPEED_10T, AG7100_PHY_SPEED_100TX; +* AG7100_PHY_SPEED_1000T; +*/ + +sw_error_t +f2_phy_get_speed(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_speed_t * speed) +{ + a_uint16_t phy_data; + + phy_data = f2_phy_reg_read(dev_id, phy_id, F2_PHY_SPEC_STATUS); + + //read speed + switch (phy_data & F2_STATUS_SPEED_MASK) + { + case F2_STATUS_SPEED_1000MBS: + *speed = FAL_SPEED_1000; + break; + case F2_STATUS_SPEED_100MBS: + *speed = FAL_SPEED_100; + break; + case F2_STATUS_SPEED_10MBS: + *speed = FAL_SPEED_10; + break; + default: + return SW_READ_ERROR; + } + + return SW_OK; +} + +/****************************************************************************** +* +* f2_phy_set_speed - Determines the speed of phy ports associated with the +* specified device. +* +* RETURNS: +* AG7100_PHY_SPEED_10T, AG7100_PHY_SPEED_100TX; +* AG7100_PHY_SPEED_1000T; +*/ +sw_error_t +f2_phy_set_speed(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_speed_t speed) +{ + a_uint16_t phy_data = 0; + a_uint16_t phy_status = 0; + a_uint32_t autoneg, oldneg; + fal_port_duplex_t old_duplex; + + phy_data &= ~F2_CTRL_AUTONEGOTIATION_ENABLE; + + (void)f2_phy_get_autoneg_adv(dev_id, phy_id, &autoneg); + oldneg = autoneg; + autoneg &= ~FAL_PHY_ADV_FE_SPEED_ALL; + + (void)f2_phy_get_duplex(dev_id, phy_id, &old_duplex); + + if (old_duplex == FAL_FULL_DUPLEX) + { + phy_data |= F2_CTRL_FULL_DUPLEX; + + if (speed == FAL_SPEED_100) + autoneg |= FAL_PHY_ADV_100TX_FD; + else + autoneg |= FAL_PHY_ADV_10T_FD; + } + else if (old_duplex == FAL_HALF_DUPLEX) + { + phy_data &= ~F2_CTRL_FULL_DUPLEX; + + if (speed == FAL_SPEED_100) + autoneg |= FAL_PHY_ADV_100TX_HD; + else + autoneg |= FAL_PHY_ADV_10T_HD; + } + else + return SW_FAIL; + + (void)f2_phy_set_autoneg_adv(dev_id, phy_id, autoneg); + (void)f2_phy_restart_autoneg(dev_id, phy_id); + + if(f2_phy_get_link_status(dev_id, phy_id)) + { + do + { + phy_status = f2_phy_reg_read(dev_id, phy_id, F2_PHY_STATUS); + } + while(!F2_AUTONEG_DONE(phy_status)); + } + + if (speed == FAL_SPEED_100) + phy_data |= F2_CTRL_SPEED_100; + else if (speed == FAL_SPEED_10) + phy_data |= F2_CTRL_SPEED_10; + else + return SW_BAD_PARAM; + + f2_phy_reg_write(dev_id, phy_id, F2_PHY_CONTROL, phy_data); + (void)f2_phy_set_autoneg_adv(dev_id, phy_id, oldneg); + + return SW_OK; + +} + +/****************************************************************************** +* +* f2_phy_get_duplex - Determines the speed of phy ports associated with the +* specified device. +* +* RETURNS: +* AG7100_PHY_SPEED_10T, AG7100_PHY_SPEED_100TX; +* AG7100_PHY_SPEED_1000T; +*/ +sw_error_t +f2_phy_get_duplex(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_duplex_t * duplex) +{ + a_uint16_t phy_data; + +#if 0 + //a_uint16_t ii = 200; + a_uint16_t ii = 2; + + if (phy_id >= F2_PHY_MAX) + return SW_BAD_PARAM; + + do + { + phy_data = f2_phy_reg_read(dev_id, phy_id, F2_PHY_SPEC_STATUS); + aos_mdelay(10); + } + while ((!(phy_data & F2_STATUS_RESOVLED)) && --ii); + + //read time out + if (ii == 0) + return SW_DISABLE; +#endif + + phy_data = f2_phy_reg_read(dev_id, phy_id, F2_PHY_SPEC_STATUS); + + //read duplex + if (phy_data & F2_STATUS_FULL_DUPLEX) + *duplex = FAL_FULL_DUPLEX; + else + *duplex = FAL_HALF_DUPLEX; + + return SW_OK; +} + +/****************************************************************************** +* +* f2_phy_set_duplex - Determines the speed of phy ports associated with the +* specified device. +* +* RETURNS: +* AG7100_PHY_SPEED_10T, AG7100_PHY_SPEED_100TX; +* AG7100_PHY_SPEED_1000T; +*/ +sw_error_t +f2_phy_set_duplex(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_duplex_t duplex) +{ + a_uint16_t phy_data = 0; + a_uint16_t phy_status = 0; + + fal_port_speed_t old_speed = FAL_SPEED_10; + a_uint32_t autoneg, oldneg; + + if (f2_phy_autoneg_status(dev_id, phy_id)) + phy_data &= ~F2_CTRL_AUTONEGOTIATION_ENABLE; + + (void)f2_phy_get_autoneg_adv(dev_id, phy_id, &autoneg); + oldneg = autoneg; + autoneg &= ~FAL_PHY_ADV_FE_SPEED_ALL; + + (void)f2_phy_get_speed(dev_id, phy_id, &old_speed); + + if (old_speed == FAL_SPEED_100) + phy_data |= F2_CTRL_SPEED_100; + else if (old_speed == FAL_SPEED_10) + phy_data |= F2_CTRL_SPEED_10; + else + return SW_FAIL; + + if (duplex == FAL_FULL_DUPLEX) + { + phy_data |= F2_CTRL_FULL_DUPLEX; + + if (old_speed == FAL_SPEED_100) + autoneg = FAL_PHY_ADV_100TX_FD; + else + autoneg = FAL_PHY_ADV_10T_FD; + } + else if (duplex == FAL_HALF_DUPLEX) + { + phy_data &= ~F2_CTRL_FULL_DUPLEX; + + if (old_speed == FAL_SPEED_100) + autoneg = FAL_PHY_ADV_100TX_HD; + else + autoneg = FAL_PHY_ADV_10T_HD; + } + else + return SW_BAD_PARAM; + + (void)f2_phy_set_autoneg_adv(dev_id, phy_id, autoneg); + (void)f2_phy_restart_autoneg(dev_id, phy_id); + + if(f2_phy_get_link_status(dev_id, phy_id)) + { + do + { + phy_status = f2_phy_reg_read(dev_id, phy_id, F2_PHY_STATUS); + } + while(!F2_AUTONEG_DONE(phy_status)); + } + + f2_phy_reg_write(dev_id, phy_id, F2_PHY_CONTROL, phy_data); + (void)f2_phy_set_autoneg_adv(dev_id, phy_id, oldneg); + + return SW_OK; +} + +/****************************************************************************** +* +* f2_phy_get_phy_id - get the phy id +* +*/ +static sw_error_t +f2_phy_get_phy_id(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *phy_data) +{ + a_uint16_t org_id, rev_id; + + org_id = f2_phy_reg_read(dev_id, phy_id, F2_PHY_ID1); + rev_id = f2_phy_reg_read(dev_id, phy_id, F2_PHY_ID2); + *phy_data = ((org_id & 0xffff) << 16) | (rev_id & 0xffff); + + return SW_OK; +} +static int f2_phy_api_ops_init(void) +{ + int ret; + hsl_phy_ops_t *f2_phy_api_ops = NULL; + + f2_phy_api_ops = kzalloc(sizeof(hsl_phy_ops_t), GFP_KERNEL); + if (f2_phy_api_ops == NULL) { + SSDK_ERROR("f2 phy ops kzalloc failed!\n"); + return -ENOMEM; + } + + phy_api_ops_init(F2_PHY_CHIP); + + f2_phy_api_ops->phy_hibernation_set = f2_phy_set_hibernate; + f2_phy_api_ops->phy_hibernation_get = f2_phy_get_hibernate; + f2_phy_api_ops->phy_speed_get = f2_phy_get_speed; + f2_phy_api_ops->phy_speed_set = f2_phy_set_speed; + f2_phy_api_ops->phy_duplex_get = f2_phy_get_duplex; + f2_phy_api_ops->phy_duplex_set = f2_phy_set_duplex; + f2_phy_api_ops->phy_autoneg_enable_set = f2_phy_enable_autoneg; + f2_phy_api_ops->phy_restart_autoneg = f2_phy_restart_autoneg; + f2_phy_api_ops->phy_autoneg_status_get = f2_phy_autoneg_status; + f2_phy_api_ops->phy_autoneg_adv_set = f2_phy_set_autoneg_adv; + f2_phy_api_ops->phy_autoneg_adv_get = f2_phy_get_autoneg_adv; + f2_phy_api_ops->phy_powersave_set = f2_phy_set_powersave; + f2_phy_api_ops->phy_powersave_get = f2_phy_get_powersave; + f2_phy_api_ops->phy_cdt = f2_phy_cdt; + f2_phy_api_ops->phy_link_status_get = f2_phy_get_link_status; + f2_phy_api_ops->phy_reset = f2_phy_reset; + f2_phy_api_ops->phy_power_off = f2_phy_poweroff; + f2_phy_api_ops->phy_power_on = f2_phy_poweron; + f2_phy_api_ops->phy_id_get = f2_phy_get_phy_id; + f2_phy_api_ops->phy_reg_write = f2_phy_reg_write; + f2_phy_api_ops->phy_reg_read = f2_phy_reg_read; + f2_phy_api_ops->phy_debug_write = f2_phy_debug_write; + f2_phy_api_ops->phy_debug_read = f2_phy_debug_read; + + ret = hsl_phy_api_ops_register(F2_PHY_CHIP, f2_phy_api_ops); + + if (ret == 0) + SSDK_INFO("qca probe f2 phy driver succeeded!\n"); + else + SSDK_ERROR("qca probe f2 phy driver failed! (code: %d)\n", ret); + + return ret; +} +int f2_phy_init(a_uint32_t dev_id, a_uint32_t port_bmp) +{ + static a_uint32_t phy_ops_flag = 0; + + if(phy_ops_flag == 0) { + f2_phy_api_ops_init(); + phy_ops_flag = 1; + } + + return 0; +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/hsl_phy.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/hsl_phy.c new file mode 100755 index 000000000..5ad88c6c9 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/hsl_phy.c @@ -0,0 +1,818 @@ +/* + * 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. + */ +/*qca808x_start*/ +#include "sw.h" +#include "hsl_phy.h" +#include "hsl.h" +/*qca808x_end*/ +#include "ssdk_dts.h" +#if defined(ISIS) ||defined(ISISC) ||defined(GARUDA) +#include +#endif +#if defined(ATHENA) ||defined(SHIVA) ||defined(HORUS) +#include +#endif +#ifdef MP +#include "mpge_phy.h" +#endif +#ifdef IN_MALIBU_PHY +#include +#endif +#ifdef IN_AQUANTIA_PHY +#include +#endif +#ifdef IN_QCA803X_PHY +#include +#endif +#ifdef IN_SFP_PHY +#include +#endif +#ifdef IN_QCA808X_PHY +/*qca808x_start*/ +#include +/*qca808x_end*/ +#endif +#include +/*qca808x_start*/ +#include "sw.h" +#include "ssdk_plat.h" +#include "hsl_port_prop.h" + +phy_info_t *phy_info[SW_MAX_NR_DEV] = {0}; +a_uint32_t port_bmp[SW_MAX_NR_DEV] = {0}; + + +phy_driver_instance_t ssdk_phy_driver[] = +{ +/*qca808x_end*/ + #if defined(ISIS) ||defined(ISISC) ||defined(GARUDA) + {F1_PHY_CHIP, {0}, NULL, f1_phy_init, NULL}, + #else + {F1_PHY_CHIP, {0}, NULL, NULL, NULL}, + #endif + #if defined(ATHENA) ||defined(SHIVA) ||defined(HORUS) + {F2_PHY_CHIP, {0}, NULL, f2_phy_init, NULL}, + #else + {F2_PHY_CHIP, {0}, NULL, NULL, NULL}, + #endif + #ifdef IN_MALIBU_PHY + {MALIBU_PHY_CHIP, {0}, NULL, malibu_phy_init, NULL}, + #else + {MALIBU_PHY_CHIP, {0}, NULL, NULL, NULL}, + #endif + #ifdef IN_AQUANTIA_PHY + {AQUANTIA_PHY_CHIP, {0}, NULL, aquantia_phy_init, NULL}, + #else + {AQUANTIA_PHY_CHIP, {0}, NULL, NULL, NULL}, + #endif + #ifdef IN_QCA803X_PHY + {QCA803X_PHY_CHIP, {0}, NULL, qca803x_phy_init, NULL}, + #else + {QCA803X_PHY_CHIP, {0}, NULL, NULL, NULL}, + #endif + #ifdef IN_SFP_PHY + {SFP_PHY_CHIP, {0}, NULL, sfp_phy_init, sfp_phy_exit}, + #else + {SFP_PHY_CHIP, {0}, NULL, NULL, NULL}, + #endif + #ifdef MP + {MPGE_PHY_CHIP, {0}, NULL, mpge_phy_init, NULL}, + #else + {MPGE_PHY_CHIP, {0}, NULL, NULL, NULL}, + #endif + #ifdef IN_QCA808X_PHY +/*qca808x_start*/ + {QCA808X_PHY_CHIP, {0}, NULL, qca808x_phy_init, qca808x_phy_exit}, +/*qca808x_end*/ + #else + {QCA808X_PHY_CHIP, {0}, NULL, NULL, NULL}, + #endif +/*qca808x_start*/ + {MAX_PHY_CHIP, {0}, NULL, NULL, NULL} +}; +sw_error_t hsl_phy_api_ops_register(phy_type_t phy_type, hsl_phy_ops_t * phy_api_ops) +{ + + ssdk_phy_driver[phy_type].phy_ops = phy_api_ops; + + return SW_OK; + +} + +sw_error_t hsl_phy_api_ops_unregister(phy_type_t phy_type, hsl_phy_ops_t * phy_api_ops) +{ + + ssdk_phy_driver[phy_type].phy_ops = NULL; + + return SW_OK; + +} + +hsl_phy_ops_t *hsl_phy_api_ops_get(a_uint32_t dev_id, a_uint32_t port_id) +{ + phy_type_t phytype = 0; + + if (dev_id >= SW_MAX_NR_DEV) + return NULL; + + phytype = phy_info[dev_id]->phy_type[port_id]; + if(phytype == MAX_PHY_CHIP) + { + return NULL; + } + + return ssdk_phy_driver[phytype].phy_ops; + +} + +sw_error_t phy_api_ops_init(phy_type_t phy_type) +{ + + if (MAX_PHY_CHIP <= phy_type) + return SW_BAD_PARAM; + + if(ssdk_phy_driver[phy_type].phy_ops != NULL) + { + kfree(ssdk_phy_driver[phy_type].phy_ops); + ssdk_phy_driver[phy_type].phy_ops = NULL; + } + return SW_OK; +} + +a_bool_t hsl_port_is_sfp(a_uint32_t dev_id, a_uint32_t port_id, ssdk_init_cfg *cfg) +{ + if ((cfg->chip_type == CHIP_HPPE) && + (((SSDK_PHYSICAL_PORT5 == port_id) && + ((cfg->mac_mode1 == PORT_WRAPPER_10GBASE_R) || + (cfg->mac_mode1 == PORT_WRAPPER_SGMII_FIBER))) || + ((SSDK_PHYSICAL_PORT6 == port_id) && + ((cfg->mac_mode2 == PORT_WRAPPER_10GBASE_R) || + (cfg->mac_mode2 == PORT_WRAPPER_SGMII_FIBER))))) + return A_TRUE; + else + return A_FALSE; +} + +a_uint32_t hsl_phyid_get(a_uint32_t dev_id, + a_uint32_t port_id, ssdk_init_cfg *cfg) +{ + a_uint16_t org_id = 0, rev_id = 0; + a_uint32_t reg_pad = 0, phy_id = 0; + +/*qca808x_end*/ + if(ssdk_is_emulation(dev_id) && ssdk_emu_chip_ver_get(dev_id) == MP_GEPHY){ + return MP_GEPHY; + } +/*qca808x_start*/ + if (hsl_port_is_sfp(dev_id, port_id, cfg)){ + return SFP_PHY; + } + + if (phy_info[dev_id]->phy_c45[port_id] == A_TRUE){ + reg_pad = BIT(30) | BIT(16); + } + +#if defined(IN_PHY_I2C_MODE) + if (hsl_port_phy_access_type_get(dev_id, port_id) == PHY_I2C_ACCESS) { + cfg->reg_func.i2c_get(dev_id, + phy_info[dev_id]->phy_address[port_id], reg_pad | 2, &org_id); + cfg->reg_func.i2c_get(dev_id, + phy_info[dev_id]->phy_address[port_id], reg_pad | 3, &rev_id); + if(((org_id << 16) | rev_id) == INVALID_PHY_ID) { + return QCA8081_PHY_V1_1; + } + } + else +#endif + { + cfg->reg_func.mdio_get(dev_id, + phy_info[dev_id]->phy_address[port_id], reg_pad | 2, &org_id); + cfg->reg_func.mdio_get(dev_id, + phy_info[dev_id]->phy_address[port_id], reg_pad | 3, &rev_id); + } + + phy_id = (org_id<<16) | rev_id; + + return phy_id; +} + +phy_type_t hsl_phytype_get_by_phyid(a_uint32_t dev_id, a_uint32_t phy_id) +{ + phy_type_t phytype = MAX_PHY_CHIP; + + switch (phy_id) + { +/*qca808x_end*/ + case F1V1_PHY: + case F1V2_PHY: + case F1V3_PHY: + case F1V4_PHY: + phytype = F1_PHY_CHIP; + break; + case F2V1_PHY: + phytype = F2_PHY_CHIP; + break; + case MALIBU2PORT_PHY: + case MALIBU5PORT_PHY: + phytype = MALIBU_PHY_CHIP; + break; + case AQUANTIA_PHY_107: + case AQUANTIA_PHY_108: + case AQUANTIA_PHY_109: + case AQUANTIA_PHY_111: + case AQUANTIA_PHY_111B0: + case AQUANTIA_PHY_112: + case AQUANTIA_PHY_113C_A0: + case AQUANTIA_PHY_113C_A1: + case AQUANTIA_PHY_112C: + phytype = AQUANTIA_PHY_CHIP; + break; + case QCA8030_PHY: + case QCA8033_PHY: + case QCA8035_PHY: + phytype = QCA803X_PHY_CHIP; + break; + case SFP_PHY: + phytype = SFP_PHY_CHIP; + break; + case MP_GEPHY: + phytype = MPGE_PHY_CHIP; + break; +/*qca808x_start*/ + case QCA8081_PHY_V1_1: + phytype = QCA808X_PHY_CHIP; + break; + default: + phytype = MAX_PHY_CHIP; + } + + return phytype; +} +/*qca808x_end*/ +sw_error_t hsl_phydriver_update(a_uint32_t dev_id, a_uint32_t port_id, + a_uint32_t mode) +{ + a_uint32_t phy_id; + phy_type_t phytype; + ssdk_init_cfg cfg; + + cfg.chip_type = CHIP_HPPE; + if(port_id == SSDK_PHYSICAL_PORT5) + { + cfg.mac_mode1 = mode; + } + else if(port_id == SSDK_PHYSICAL_PORT6) + { + cfg.mac_mode2 = mode; + } + else + { + return SW_NOT_SUPPORTED; + } + if (hsl_port_phy_access_type_get(dev_id, port_id) == PHY_I2C_ACCESS) + { + cfg.reg_func.i2c_get = hsl_phy_i2c_get; + } + else + { + cfg.reg_func.mdio_get = reduce_hsl_phy_get; + } + phy_id = hsl_phyid_get(dev_id, port_id, &cfg); + phytype = hsl_phytype_get_by_phyid(dev_id, phy_id); + SSDK_DEBUG("port_id is %x, phy_id is %x, phy_type is:%x\n", + port_id, phy_id, phytype); + if (MAX_PHY_CHIP != phytype) + { + phy_info[dev_id]->phy_type[port_id] = phytype; + ssdk_phy_driver[phytype].port_bmp[dev_id] |= (0x1 << port_id); + } + + return SW_OK; +} +/*qca808x_start*/ +int ssdk_phy_driver_init(a_uint32_t dev_id, ssdk_init_cfg *cfg) +{ + + int i = 0; + a_uint32_t phy_id = 0; + phy_type_t phytype = MAX_PHY_CHIP; + + for (i = 0; i < SW_MAX_NR_PORT; i++) + { + if (port_bmp[dev_id] & (0x1 << i)) + { +/*qca808x_end*/ + if(ssdk_port_feature_get(dev_id, i, PHY_F_FORCE)) { + continue; + } +/*qca808x_start*/ + phy_id = hsl_phyid_get(dev_id, i, cfg); + phytype = hsl_phytype_get_by_phyid(dev_id, phy_id); + if (MAX_PHY_CHIP != phytype) { + phy_info[dev_id]->phy_type[i] = phytype; + ssdk_phy_driver[phytype].port_bmp[dev_id] |= (0x1 << i); + } else { + SSDK_INFO("dev_id = %d, phy_adress = %d, phy_id = 0x%x phy" + "type doesn't match\n", dev_id, + phy_info[dev_id]->phy_address[i], phy_id); + } + } + } + + for(i = 0; i < MAX_PHY_CHIP;i++) { + if(ssdk_phy_driver[i].port_bmp[dev_id] != 0 && + ssdk_phy_driver[i].init != NULL) { + ssdk_phy_driver[i].init(dev_id, ssdk_phy_driver[i].port_bmp[dev_id]); + } + } + return 0; +} + +#ifdef QCA808X_PORTS_INFO +typedef struct { + a_uint32_t port_id; + a_uint32_t phy_address; + a_uint8_t phy_access_type; +} qca808x_phy_info_t; +/*5 is port_id, 0x1c is qca808x phy address, PHY_MDIO_ACCESS is mdio +mode to access qca808x phy, PHY_I2C_ACCESS is I2C mode to access +qca808x phy*/ +static qca808x_phy_info_t qca808x_phy_info[] = { + {5,0x7c,PHY_I2C_ACCESS} +}; +static int qca_ssdk_qca808x_phy_info_init(a_uint32_t dev_id) +{ + a_uint32_t port_bmp = 0, port_id = 0, port_index = 0, port_index_max = 0; + + port_index_max = sizeof(qca808x_phy_info)/(sizeof(qca808x_phy_info_t)); + for(port_index = 0; port_index < port_index_max; port_index++) { + port_id = qca808x_phy_info[port_index].port_id; + port_bmp |= (1 << port_id); + /*qca808x phy address*/ + phy_info[dev_id]->phy_address[port_id] = + qca808x_phy_info[port_index].phy_address; + /*qca808x access mode, 1:i2c, 0:mdio*/ + phy_info[dev_id]->phy_access_type[port_id] = + qca808x_phy_info[port_index].phy_access_type; + } + qca_ssdk_port_bmp_set(dev_id, port_bmp); + + return 0; +} +#endif + +int qca_ssdk_phy_info_init(a_uint32_t dev_id) +{ + a_uint32_t j = 0; + phy_info_t *phy_information; + + phy_information = kzalloc(sizeof(phy_info_t), GFP_KERNEL); + if (phy_information == NULL) { + SSDK_ERROR("phy_information kzalloc failed!\n"); + return -ENOMEM; + } + memset(phy_information, 0, sizeof(*phy_information)); + phy_info[dev_id] = phy_information; + + for (j = SSDK_PHYSICAL_PORT0; j < SW_MAX_NR_PORT; j ++) + { + phy_info[dev_id]->phy_type[j] = MAX_PHY_CHIP; + if(j == SSDK_PHYSICAL_PORT0) + { + phy_info[dev_id]->phy_address[j] = INVALID_PHY_ADDR; + } + else + { + phy_info[dev_id]->phy_address[j] = j - 1; + } + } +#ifdef QCA808X_PORTS_INFO + qca_ssdk_qca808x_phy_info_init(dev_id); +#endif + + return 0; +} +void qca_ssdk_port_bmp_init(a_uint32_t dev_id) +{ + port_bmp[dev_id] = 0x3e; + + return; +} +/*qca808x_end*/ +void hsl_phy_address_init(a_uint32_t dev_id, a_uint32_t i, + a_uint32_t value) +{ + phy_info[dev_id]->phy_address[i] = value; + + return; +} +/*qca808x_start*/ +void qca_ssdk_port_bmp_set(a_uint32_t dev_id, a_uint32_t value) +{ + port_bmp[dev_id] = value; + + return; +} + +a_uint32_t qca_ssdk_port_bmp_get(a_uint32_t dev_id) +{ + + return port_bmp[dev_id]; +} +/*qca808x_end*/ +a_uint32_t qca_ssdk_phy_type_port_bmp_get(a_uint32_t dev_id, + phy_type_t phy_type) +{ + + return ssdk_phy_driver[phy_type].port_bmp[dev_id]; +} + +void +qca_ssdk_phy_address_set(a_uint32_t dev_id, a_uint32_t port_id, + a_uint32_t phy_addr) +{ + phy_info[dev_id]->phy_address[port_id] = phy_addr; + + return; +} + +a_uint32_t +qca_ssdk_port_to_phy_mdio_fake_addr(a_uint32_t dev_id, a_uint32_t port_id) +{ + return phy_info[dev_id]->phy_mdio_fake_address[port_id]; +} + +void qca_ssdk_phy_mdio_fake_address_set(a_uint32_t dev_id, a_uint32_t i, + a_uint32_t value) +{ + phy_info[dev_id]->phy_mdio_fake_address[i] = value; + + return; +} + +a_uint32_t +qca_ssdk_phy_mdio_fake_addr_to_port(a_uint32_t dev_id, a_uint32_t phy_mdio_fake_addr) +{ + a_uint32_t i = 0; + + for (i = 0; i < SW_MAX_NR_PORT; i ++) + { + if (phy_info[dev_id]->phy_mdio_fake_address[i] == phy_mdio_fake_addr) + return i; + } + SSDK_ERROR("doesn't match port_id to specified phy_mdio_fake_addr !\n"); + return 0; +} +/*qca808x_start*/ +a_uint32_t +qca_ssdk_port_to_phy_addr(a_uint32_t dev_id, a_uint32_t port_id) +{ + return phy_info[dev_id]->phy_address[port_id]; +} + +a_uint32_t +qca_ssdk_phy_addr_to_port(a_uint32_t dev_id, a_uint32_t phy_addr) +{ + a_uint32_t i = 0; + + for (i = 0; i < SW_MAX_NR_PORT; i ++) + { + if (phy_info[dev_id]->phy_address[i] == phy_addr) + return i; + } + SSDK_ERROR("doesn't match port_id to specified phy_addr !\n"); + return 0; +} + +a_bool_t +hsl_port_phy_combo_capability_get(a_uint32_t dev_id, a_uint32_t port_id) +{ + if (dev_id >= SW_MAX_NR_DEV) + return A_FALSE; + + return phy_info[dev_id]->phy_combo[port_id]; +} + +void +hsl_port_phy_combo_capability_set(a_uint32_t dev_id, a_uint32_t port_id, + a_bool_t enable) +{ + if (dev_id >= SW_MAX_NR_DEV) + return; + + phy_info[dev_id]->phy_combo[port_id] = enable; + + return; +} + +a_uint8_t +hsl_port_phy_access_type_get(a_uint32_t dev_id, a_uint32_t port_id) +{ + if (dev_id >= SW_MAX_NR_DEV) + return 0; + + return phy_info[dev_id]->phy_access_type[port_id]; +} + +void +hsl_port_phy_access_type_set(a_uint32_t dev_id, a_uint32_t port_id, + a_uint8_t access_type) +{ + if (dev_id >= SW_MAX_NR_DEV) + return; + + phy_info[dev_id]->phy_access_type[port_id] = access_type; + + return; +} +/*qca808x_end*/ +void +hsl_port_phy_c45_capability_set(a_uint32_t dev_id, a_uint32_t port_id, + a_bool_t enable) +{ + phy_info[dev_id]->phy_c45[port_id] = enable; + + return; +} +sw_error_t +hsl_port_phy_serdes_reset(a_uint32_t dev_id) +{ + sw_error_t rv; + int i = 0; + hsl_phy_ops_t *phy_drv; + + for (i = 0; i < SW_MAX_NR_PORT; i++) + { + if (phy_info[dev_id]->phy_type[i] == MALIBU_PHY_CHIP) + { + SW_RTN_ON_NULL(phy_drv = hsl_phy_api_ops_get (dev_id, i)); + if (NULL == phy_drv->phy_serdes_reset) + return SW_NOT_SUPPORTED; + rv = phy_drv->phy_serdes_reset(dev_id); + return rv; + } + } + + return SW_OK; +} + +sw_error_t hsl_port_phy_hw_init(a_uint32_t dev_id, a_uint32_t port_id) +{ + phy_type_t phytype; + + phytype = hsl_phy_type_get(dev_id, port_id); + + if(ssdk_phy_driver[phytype].port_bmp[dev_id] != 0 && + ssdk_phy_driver[phytype].init != NULL) + { + ssdk_phy_driver[phytype].init(dev_id, + ssdk_phy_driver[phytype].port_bmp[dev_id]); + } + + return SW_OK; +} + +a_uint32_t +hsl_port_phyid_get(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv = SW_OK; + a_uint32_t phy_addr, phy_id; + hsl_phy_ops_t *phy_drv; + + phy_drv = hsl_phy_api_ops_get (dev_id, port_id); + if (phy_drv == NULL) { + return INVALID_PHY_ID; + } + if (NULL == phy_drv->phy_id_get) { + return INVALID_PHY_ID; + } + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_addr); + if(rv) { + return INVALID_PHY_ID; + } + + rv = phy_drv->phy_id_get (dev_id, phy_addr, &phy_id); + if(rv) { + return INVALID_PHY_ID; + } + + return phy_id; +} + +sw_error_t +hsl_port_phy_mode_set(a_uint32_t dev_id, fal_port_interface_mode_t mode) +{ + sw_error_t rv; + a_uint32_t i = 0, phy_addr = 0; + hsl_phy_ops_t *phy_drv; + + for (i = 0; i < SW_MAX_NR_PORT; i++) + { + if (phy_info[dev_id]->phy_type[i] == MALIBU_PHY_CHIP) + { + SW_RTN_ON_NULL(phy_drv = hsl_phy_api_ops_get (dev_id, i)); + if (NULL == phy_drv->phy_interface_mode_set) + return SW_NOT_SUPPORTED; + + phy_addr = qca_ssdk_port_to_phy_addr(dev_id, i); + rv = phy_drv->phy_interface_mode_set(dev_id, phy_addr, mode); + return rv; + } + } + + return SW_OK; +} +phy_type_t hsl_phy_type_get(a_uint32_t dev_id, a_uint32_t port_id) +{ + + if (dev_id >= SW_MAX_NR_DEV) + return MAX_PHY_CHIP; + + return phy_info[dev_id]->phy_type[port_id]; +} + +a_uint32_t hsl_port_phy_reset_gpio_get(a_uint32_t dev_id, a_uint32_t port_id) +{ + return phy_info[dev_id]->phy_reset_gpio[port_id]; +} + +void hsl_port_phy_reset_gpio_set(a_uint32_t dev_id, a_uint32_t port_id, + a_uint32_t phy_reset_gpio) +{ + phy_info[dev_id]->phy_reset_gpio[port_id] = phy_reset_gpio; + + return; +} + +void hsl_port_phy_gpio_reset(a_uint32_t dev_id, a_uint32_t port_id) + +{ + a_uint32_t gpio_num, ret = 0; + + gpio_num = hsl_port_phy_reset_gpio_get(dev_id, port_id); + + if(gpio_num == SSDK_INVALID_GPIO) + { + return; + } + ret = gpio_request(gpio_num, "phy_reset_gpio"); + if(ret) + { + SSDK_ERROR("gpio request failed, ret:%d\n", ret); + return; + } + ret = gpio_direction_output(gpio_num, SSDK_GPIO_RESET); + if(ret) + { + SSDK_ERROR("when reset, gpio set failed, ret:%d\n", + ret); + return; + } + msleep(200); + gpio_set_value(gpio_num, SSDK_GPIO_RELEASE); + SSDK_INFO("GPIO%d reset PHY done\n", gpio_num); + + gpio_free(gpio_num); + + return; +} + +void +hsl_port_phy_dac_get(a_uint32_t dev_id, a_uint32_t port_id, + phy_dac_t *phy_dac) +{ + phy_dac->mdac = phy_info[dev_id]->phy_dac[port_id].mdac; + phy_dac->edac = phy_info[dev_id]->phy_dac[port_id].edac; + + return; +} + +void +hsl_port_phy_dac_set(a_uint32_t dev_id, a_uint32_t port_id, + phy_dac_t phy_dac) +{ + phy_info[dev_id]->phy_dac[port_id].mdac = phy_dac.mdac; + phy_info[dev_id]->phy_dac[port_id].edac = phy_dac.edac; + + return; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)) +static sw_error_t +hsl_phy_adv_to_linkmode_adv(a_uint32_t autoadv, a_ulong_t *advertising) +{ + linkmode_mod_bit(ETHTOOL_LINK_MODE_Pause_BIT, + advertising, autoadv & FAL_PHY_ADV_PAUSE); + linkmode_mod_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, + advertising, autoadv & FAL_PHY_ADV_ASY_PAUSE); + + linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, + advertising, autoadv & FAL_PHY_ADV_10T_HD); + linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, + advertising, autoadv & FAL_PHY_ADV_10T_FD); + + linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, + advertising, autoadv & FAL_PHY_ADV_100TX_HD); + linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, + advertising, autoadv & FAL_PHY_ADV_100TX_FD); + + linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, + advertising, autoadv & FAL_PHY_ADV_1000T_FD); + + linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, + advertising, autoadv & FAL_PHY_ADV_2500T_FD); + + linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, + advertising, autoadv & FAL_PHY_ADV_5000T_FD); + + linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT, + advertising, autoadv & FAL_PHY_ADV_10000T_FD); + + SSDK_DEBUG("autoadv:0x%x, advertising::0x%lx\n", + autoadv, *advertising); + + return SW_OK; +} + +static sw_error_t +hsl_port_phydev_get(a_uint32_t dev_id, a_uint32_t port_id, + struct phy_device **phydev) +{ + struct qca_phy_priv *priv; + a_uint32_t phy_addr; + + priv = ssdk_phy_priv_data_get(dev_id); + SW_RTN_ON_NULL(priv); + + phy_addr = qca_ssdk_port_to_phy_addr(dev_id, port_id); + SW_RTN_ON_NULL(phydev); + *phydev = mdiobus_get_phy(priv->miibus, phy_addr); + if(*phydev == NULL) + { + SSDK_ERROR("port %d phydev is NULL\n", port_id); + return SW_NOT_INITIALIZED; + } + SSDK_DEBUG("phy[%d]: device %s, driver %s\n", + (*phydev)->mdio.addr, phydev_name(*phydev), + (*phydev)->drv ? (*phydev)->drv->name : "unknown"); + + return SW_OK; +} + +sw_error_t +hsl_port_phydev_adv_update(a_uint32_t dev_id, a_uint32_t port_id, + a_uint32_t autoadv) +{ + sw_error_t rv = SW_OK; + struct phy_device *phydev; + + rv = hsl_port_phydev_get(dev_id, port_id, &phydev); + SW_RTN_ON_ERROR(rv); + rv = hsl_phy_adv_to_linkmode_adv(autoadv, phydev->advertising); + + return rv; +} +#endif + +/*qca808x_start*/ +sw_error_t ssdk_phy_driver_cleanup(void) +{ + a_uint32_t i = 0, j = 0; + + for (i = 0; i < MAX_PHY_CHIP;i++) { + for (j = 0; j < SW_MAX_NR_DEV; j++) { + if (ssdk_phy_driver[i].port_bmp[j] != 0 && + ssdk_phy_driver[i].exit != NULL) { + ssdk_phy_driver[i].exit(j, ssdk_phy_driver[i].port_bmp[j]); + } + } + if(ssdk_phy_driver[i].phy_ops != NULL) + { + kfree(ssdk_phy_driver[i].phy_ops); + ssdk_phy_driver[i].phy_ops = NULL; + } + } + + for(i = 0; i < SW_MAX_NR_DEV;i++) { + + if(phy_info[i] != NULL) + { + kfree(phy_info[i]); + phy_info[i] = NULL; + } + } + return SW_OK; +} +/*qca808x_end*/ diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/malibu_phy.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/malibu_phy.c new file mode 100755 index 000000000..bbebc59e5 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/malibu_phy.c @@ -0,0 +1,2872 @@ +/* + * Copyright (c) 2015-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 "fal_port_ctrl.h" +#include "hsl_api.h" +#include "hsl.h" +#include "malibu_phy.h" +#include "hsl_phy.h" +#include "ssdk_plat.h" + +static a_uint32_t first_phy_addr = MAX_PHY_ADDR; + +static a_uint16_t +_phy_reg_read(a_uint32_t dev_id, a_uint32_t phy_addr, a_uint32_t reg) +{ + sw_error_t rv; + a_uint16_t phy_data = 0; + + HSL_PHY_GET(rv, dev_id, phy_addr, reg, &phy_data); + if (SW_OK != rv) + return 0xFFFF; + + return phy_data; + +} + +static sw_error_t +_phy_reg_write(a_uint32_t dev_id, a_uint32_t phy_addr, a_uint32_t reg, + a_uint16_t phy_data) +{ + sw_error_t rv; + + HSL_PHY_SET(rv, dev_id, phy_addr, reg, phy_data); + + return rv; +} + +/* #define malibu_phy_reg_read _phy_reg_read */ +/* #define malibu_phy_reg_write _phy_reg_write */ + +/****************************************************************************** +* +* malibu_phy_mii_read - mii register read +* +* mii register read +*/ +a_uint16_t +malibu_phy_reg_read(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t reg_id) +{ + return _phy_reg_read(dev_id, phy_id, reg_id); + +} + +/****************************************************************************** +* +* malibu_phy_mii_write - mii register write +* +* mii register write +*/ +sw_error_t +malibu_phy_reg_write(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t reg_id, + a_uint16_t reg_val) +{ + + _phy_reg_write(dev_id,phy_id, reg_id, reg_val); + + return SW_OK; +} + +/****************************************************************************** +* +* phy4 medium is fiber 100fx +* +* get phy4 medium is 100fx +*/ +static a_bool_t __medium_is_fiber_100fx(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data = 0; + + phy_data = malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_SGMII_STATUS); + + if (phy_data & MALIBU_PHY4_AUTO_FX100_SELECT) { + return A_TRUE; + } + /* Link down */ + if ((!(phy_data & MALIBU_PHY4_AUTO_COPPER_SELECT)) && + (!(phy_data & MALIBU_PHY4_AUTO_BX1000_SELECT)) && + (!(phy_data & MALIBU_PHY4_AUTO_SGMII_SELECT))) { + + phy_data = + malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_CHIP_CONFIG); + if ((phy_data & MALIBU_PHY4_PREFER_FIBER) + && (!(phy_data & MALIBU_PHY4_FIBER_MODE_1000BX))) { + return A_TRUE; + } + } + + return A_FALSE; +} + +/****************************************************************************** +* +* phy4 prfer medium +* +* get phy4 prefer medum, fiber or copper; +*/ +static malibu_phy_medium_t __phy_prefer_medium_get(a_uint32_t dev_id, + a_uint32_t phy_id) +{ + a_uint16_t phy_medium = 0; + + phy_medium = + malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_CHIP_CONFIG); + + return ((phy_medium & MALIBU_PHY4_PREFER_FIBER) ? + MALIBU_PHY_MEDIUM_FIBER : MALIBU_PHY_MEDIUM_COPPER); +} + +/****************************************************************************** +* +* phy4 activer medium +* +* get phy4 current active medium, fiber or copper; +*/ +static malibu_phy_medium_t __phy_active_medium_get(a_uint32_t dev_id, + a_uint32_t phy_id) +{ + a_uint16_t phy_data = 0; + a_uint16_t phy_mode = 0; + + phy_mode = malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_CHIP_CONFIG); + phy_mode &= 0x000f; + + if (phy_mode == MALIBU_PHY_PSGMII_AMDET) { + + phy_data = malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_SGMII_STATUS); + + if ((phy_data & MALIBU_PHY4_AUTO_COPPER_SELECT)) { + return MALIBU_PHY_MEDIUM_COPPER; + } else if ((phy_data & MALIBU_PHY4_AUTO_BX1000_SELECT)) { + return MALIBU_PHY_MEDIUM_FIBER; /*PHY_MEDIUM_FIBER_BX1000 */ + } else if ((phy_data & MALIBU_PHY4_AUTO_FX100_SELECT)) { + return MALIBU_PHY_MEDIUM_FIBER; /*PHY_MEDIUM_FIBER_FX100 */ + } + /* link down */ + return __phy_prefer_medium_get(dev_id, phy_id); + } else if ((phy_mode == MALIBU_PHY_PSGMII_BASET) ||(phy_mode == MALIBU_PHY_SGMII_BASET) ) { + return MALIBU_PHY_MEDIUM_COPPER; + } else if ((phy_mode == MALIBU_PHY_PSGMII_BX1000) ||(phy_mode == MALIBU_PHY_PSGMII_FX100)) { + return MALIBU_PHY_MEDIUM_FIBER; + } else { + return MALIBU_PHY_MEDIUM_COPPER; + } +} + +/****************************************************************************** +* +* phy4 copper page or fiber page select +* +* set phy4 copper or fiber page +*/ + +static sw_error_t __phy_reg_pages_sel(a_uint32_t dev_id, a_uint32_t phy_id, + malibu_phy_reg_pages_t phy_reg_pages) +{ + a_uint16_t reg_pages = 0; + reg_pages = malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_CHIP_CONFIG); + + if (phy_reg_pages == MALIBU_PHY_COPPER_PAGES) { + reg_pages |= 0x8000; + } else if (phy_reg_pages == MALIBU_PHY_SGBX_PAGES) { + reg_pages &= ~0x8000; + } else + return SW_BAD_PARAM; + + malibu_phy_reg_write(dev_id, phy_id, MALIBU_PHY_CHIP_CONFIG, reg_pages); + + return SW_OK; +} + +/****************************************************************************** +* +* phy4 reg pages selection by active medium +* +* phy4 reg pages selection +*/ +static sw_error_t __phy_reg_pages_sel_by_active_medium(a_uint32_t dev_id, + a_uint32_t phy_id) +{ + malibu_phy_medium_t phy_medium; + malibu_phy_reg_pages_t reg_pages; + + phy_medium = __phy_active_medium_get(dev_id, phy_id); + if (phy_medium == MALIBU_PHY_MEDIUM_FIBER) { + reg_pages = MALIBU_PHY_SGBX_PAGES; + } else if (phy_medium == MALIBU_PHY_MEDIUM_COPPER) { + + reg_pages = MALIBU_PHY_COPPER_PAGES; + } else + + return SW_BAD_VALUE; + + return __phy_reg_pages_sel(dev_id, phy_id, reg_pages); +} + +/****************************************************************************** +* +* malibu_phy_debug_write - debug port write +* +* debug port write +*/ +sw_error_t +malibu_phy_debug_write(a_uint32_t dev_id, a_uint32_t phy_id, a_uint16_t reg_id, + a_uint16_t reg_val) +{ + malibu_phy_reg_write(dev_id, phy_id, MALIBU_DEBUG_PORT_ADDRESS, reg_id); + malibu_phy_reg_write(dev_id, phy_id, MALIBU_DEBUG_PORT_DATA, reg_val); + + return SW_OK; +} + +/****************************************************************************** +* +* malibu_phy_debug_read - debug port read +* +* debug port read +*/ +a_uint16_t +malibu_phy_debug_read(a_uint32_t dev_id, a_uint32_t phy_id, a_uint16_t reg_id) +{ + malibu_phy_reg_write(dev_id, phy_id, MALIBU_DEBUG_PORT_ADDRESS, reg_id); + return malibu_phy_reg_read(dev_id, phy_id, MALIBU_DEBUG_PORT_DATA); +} + +/****************************************************************************** +* +* malibu_phy_mmd_write - PHY MMD register write +* +* PHY MMD register write +*/ +sw_error_t +malibu_phy_mmd_write(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint16_t mmd_num, a_uint16_t reg_id, a_uint16_t reg_val) +{ + malibu_phy_reg_write(dev_id, phy_id, MALIBU_MMD_CTRL_REG, mmd_num); + malibu_phy_reg_write(dev_id, phy_id, MALIBU_MMD_DATA_REG, reg_id); + malibu_phy_reg_write(dev_id, phy_id, MALIBU_MMD_CTRL_REG, + 0x4000 | mmd_num); + malibu_phy_reg_write(dev_id, phy_id, MALIBU_MMD_DATA_REG, reg_val); + + return SW_OK; +} + +/****************************************************************************** +* +* malibu_phy_mmd_read - PHY MMD register read +* +* PHY MMD register read +*/ +a_uint16_t +malibu_phy_mmd_read(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint16_t mmd_num, a_uint16_t reg_id) +{ + malibu_phy_reg_write(dev_id, phy_id, MALIBU_MMD_CTRL_REG, mmd_num); + malibu_phy_reg_write(dev_id, phy_id, MALIBU_MMD_DATA_REG, reg_id); + malibu_phy_reg_write(dev_id, phy_id, MALIBU_MMD_CTRL_REG, + 0x4000 | mmd_num); + + return malibu_phy_reg_read(dev_id, phy_id, MALIBU_MMD_DATA_REG); +} + +/****************************************************************************** +* +* malibu_phy_get_speed - Determines the speed of phy ports associated with the +* specified device. +*/ + +sw_error_t +malibu_phy_get_speed(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_speed_t * speed) +{ + a_uint16_t phy_data; + + if (phy_id == COMBO_PHY_ID) { + __phy_reg_pages_sel_by_active_medium(dev_id, phy_id); + } + phy_data = malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_SPEC_STATUS); + + switch (phy_data & MALIBU_STATUS_SPEED_MASK) { + case MALIBU_STATUS_SPEED_1000MBS: + *speed = FAL_SPEED_1000; + break; + case MALIBU_STATUS_SPEED_100MBS: + *speed = FAL_SPEED_100; + break; + case MALIBU_STATUS_SPEED_10MBS: + *speed = FAL_SPEED_10; + break; + default: + return SW_READ_ERROR; + } + + return SW_OK; +} + +/****************************************************************************** +* +* malibu_phy_get_duplex - Determines the speed of phy ports associated with the +* specified device. +*/ +sw_error_t +malibu_phy_get_duplex(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_duplex_t * duplex) +{ + a_uint16_t phy_data; + + if (phy_id == COMBO_PHY_ID) { + __phy_reg_pages_sel_by_active_medium(dev_id, phy_id); + } + + phy_data = malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_SPEC_STATUS); + + //read duplex + if (phy_data & MALIBU_STATUS_FULL_DUPLEX) + *duplex = FAL_FULL_DUPLEX; + else + *duplex = FAL_HALF_DUPLEX; + + return SW_OK; +} +#ifndef IN_PORTCONTROL_MINI +/****************************************************************************** +* +* malibu_phy_reset - reset the phy +* +* reset the phy +*/ +sw_error_t malibu_phy_reset(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + + if (phy_id == COMBO_PHY_ID) + __phy_reg_pages_sel_by_active_medium(dev_id, phy_id); + + phy_data = malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_CONTROL); + malibu_phy_reg_write(dev_id, phy_id, MALIBU_PHY_CONTROL, + phy_data | MALIBU_CTRL_SOFTWARE_RESET); + + return SW_OK; +} +#endif +/****************************************************************************** +* +* malibu_phy_set_powersave - set power saving status +* +* set power saving status +*/ +sw_error_t +malibu_phy_set_powersave(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable) +{ + a_uint16_t phy_data; + a_bool_t status; + + if (phy_id == COMBO_PHY_ID) { + if (MALIBU_PHY_MEDIUM_COPPER != + __phy_active_medium_get(dev_id, phy_id)) + return SW_NOT_SUPPORTED; + } + + if (enable == A_TRUE) { + malibu_phy_get_8023az (dev_id,phy_id,&status); + if (status == A_FALSE) { + phy_data = malibu_phy_mmd_read(dev_id, phy_id, MALIBU_PHY_MMD3_NUM, + MALIBU_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL); + phy_data &= ~(1<<14); + malibu_phy_mmd_write(dev_id, phy_id, MALIBU_PHY_MMD3_NUM, + MALIBU_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL, phy_data); + } + phy_data = malibu_phy_mmd_read(dev_id, phy_id, MALIBU_PHY_MMD3_NUM, + MALIBU_PHY_MMD3_ADDR_CLD_CTRL5); + phy_data &= ~(1<<14); + malibu_phy_mmd_write(dev_id, phy_id, MALIBU_PHY_MMD3_NUM, + MALIBU_PHY_MMD3_ADDR_CLD_CTRL5, phy_data); + phy_data = malibu_phy_mmd_read(dev_id, phy_id, MALIBU_PHY_MMD3_NUM, + MALIBU_PHY_MMD3_ADDR_CLD_CTRL3); + phy_data &= ~(1<<15); + malibu_phy_mmd_write(dev_id, phy_id, MALIBU_PHY_MMD3_NUM, + MALIBU_PHY_MMD3_ADDR_CLD_CTRL3, phy_data); + + } else { + phy_data = malibu_phy_mmd_read(dev_id, phy_id, MALIBU_PHY_MMD3_NUM, + MALIBU_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL); + phy_data|= (1<<14); + malibu_phy_mmd_write(dev_id, phy_id, MALIBU_PHY_MMD3_NUM, + MALIBU_PHY_MMD3_ADDR_8023AZ_TIMER_CTRL, phy_data); + phy_data = malibu_phy_mmd_read(dev_id, phy_id, MALIBU_PHY_MMD3_NUM, + MALIBU_PHY_MMD3_ADDR_CLD_CTRL5); + phy_data|= (1<<14); + malibu_phy_mmd_write(dev_id, phy_id, MALIBU_PHY_MMD3_NUM, + MALIBU_PHY_MMD3_ADDR_CLD_CTRL5, phy_data); + phy_data = malibu_phy_mmd_read(dev_id, phy_id, MALIBU_PHY_MMD3_NUM, + MALIBU_PHY_MMD3_ADDR_CLD_CTRL3); + phy_data|= (1<<15); + malibu_phy_mmd_write(dev_id, phy_id, MALIBU_PHY_MMD3_NUM, + MALIBU_PHY_MMD3_ADDR_CLD_CTRL3, phy_data); + + } + malibu_phy_reg_write(dev_id, phy_id, MALIBU_PHY_CONTROL, 0x9040); + + return SW_OK; +} +#ifndef IN_PORTCONTROL_MINI +/****************************************************************************** +* +* malibu_phy_get_powersave - get power saving status +* +* set power saving status +*/ +sw_error_t +malibu_phy_get_powersave(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t * enable) +{ + a_uint16_t phy_data; + a_uint16_t phy_data1; + + if (phy_id == COMBO_PHY_ID) { + if (MALIBU_PHY_MEDIUM_COPPER != + __phy_active_medium_get(dev_id, phy_id)) + return SW_NOT_SUPPORTED; + } + + phy_data = malibu_phy_mmd_read(dev_id, phy_id, MALIBU_PHY_MMD3_NUM, + MALIBU_PHY_MMD3_ADDR_CLD_CTRL5); + phy_data1 = malibu_phy_mmd_read(dev_id, phy_id, MALIBU_PHY_MMD3_NUM, + MALIBU_PHY_MMD3_ADDR_CLD_CTRL3); + if (!(phy_data& 0x4000) && !(phy_data1 & 0x8000)) { + *enable = A_TRUE; + } + if ((phy_data& 0x4000) && (phy_data1 & 0x8000)) { + *enable = A_FALSE; + } + return SW_OK; +} +#endif +/****************************************************************************** +* +* malibu_phy_set_802.3az +* +* set 802.3az status +*/ +sw_error_t +malibu_phy_set_8023az(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable) +{ + a_uint16_t phy_data; + + if (phy_id == COMBO_PHY_ID) { + if (MALIBU_PHY_MEDIUM_COPPER != + __phy_active_medium_get(dev_id, phy_id)) + return SW_NOT_SUPPORTED; + } + + phy_data = malibu_phy_mmd_read(dev_id, phy_id, MALIBU_PHY_MMD7_NUM, + MALIBU_PHY_MMD7_ADDR_8023AZ_EEE_CTRL); + if (enable == A_TRUE) { + phy_data |= 0x0006; + + malibu_phy_mmd_write(dev_id, phy_id, MALIBU_PHY_MMD7_NUM, + MALIBU_PHY_MMD7_ADDR_8023AZ_EEE_CTRL, phy_data); + } else { + phy_data &= ~0x0006; + + malibu_phy_mmd_write(dev_id, phy_id, MALIBU_PHY_MMD7_NUM, + MALIBU_PHY_MMD7_ADDR_8023AZ_EEE_CTRL, phy_data); + } + + malibu_phy_restart_autoneg(dev_id, phy_id); + + return SW_OK; +} + +/****************************************************************************** +* +* malibu_phy_get_8023az status +* +* get 8023az status +*/ +sw_error_t +malibu_phy_get_8023az(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t * enable) +{ + a_uint16_t phy_data; + if (phy_id == COMBO_PHY_ID) { + if (MALIBU_PHY_MEDIUM_COPPER != + __phy_active_medium_get(dev_id, phy_id)) + return SW_NOT_SUPPORTED; + } + + *enable = A_FALSE; + + phy_data = malibu_phy_mmd_read(dev_id, phy_id, MALIBU_PHY_MMD7_NUM, + MALIBU_PHY_MMD7_ADDR_8023AZ_EEE_CTRL); + + if ((phy_data & 0x0004) && (phy_data & 0x0002)) + *enable = A_TRUE; + + return SW_OK; +} + +/****************************************************************************** +* +* malibu_phy_set_hibernate - set hibernate status +* +* set hibernate status +*/ +sw_error_t +malibu_phy_set_hibernate(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable) +{ + a_uint16_t phy_data; + + malibu_phy_reg_write(dev_id, phy_id, MALIBU_DEBUG_PORT_ADDRESS, + MALIBU_DEBUG_PHY_HIBERNATION_CTRL); + phy_data = malibu_phy_reg_read(dev_id, phy_id, MALIBU_DEBUG_PORT_DATA); + + if (enable == A_TRUE) { + phy_data |= 0x8000; + } else { + phy_data &= ~0x8000; + } + + malibu_phy_reg_write(dev_id, phy_id, MALIBU_DEBUG_PORT_DATA, phy_data); + + return SW_OK; +} +#ifndef IN_PORTCONTROL_MINI +/****************************************************************************** +* +* malibu_phy_get_hibernate - get hibernate status +* +* get hibernate status +*/ +sw_error_t +malibu_phy_get_hibernate(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t * enable) +{ + a_uint16_t phy_data; + + *enable = A_FALSE; + + malibu_phy_reg_write(dev_id, phy_id, MALIBU_DEBUG_PORT_ADDRESS, + MALIBU_DEBUG_PHY_HIBERNATION_CTRL); + phy_data = malibu_phy_reg_read(dev_id, phy_id, MALIBU_DEBUG_PORT_DATA); + + if (phy_data & 0x8000) + *enable = A_TRUE; + + return SW_OK; +} + +/****************************************************************************** +* +* malibu_phy_set combo medium type +* +* set combo medium fiber or copper +*/ +sw_error_t +malibu_phy_set_combo_prefer_medium(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_medium_t phy_medium) +{ + a_uint16_t phy_data; + if (phy_id != COMBO_PHY_ID) + return SW_NOT_SUPPORTED; + + phy_data = malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_CHIP_CONFIG); + + if (phy_medium == PHY_MEDIUM_FIBER) { + phy_data |= MALIBU_PHY4_PREFER_FIBER; + phy_data &= ~0x8000; + } else if (phy_medium == PHY_MEDIUM_COPPER) { + phy_data &= ~MALIBU_PHY4_PREFER_FIBER; + phy_data |= 0x8000; + } else { + return SW_BAD_PARAM; + } + malibu_phy_reg_write(dev_id, phy_id, MALIBU_PHY_CHIP_CONFIG, phy_data); + + return SW_OK; +} + +/****************************************************************************** +* +* malibu_phy_get combo medium type +* +* get combo medium fiber or copper +*/ +sw_error_t +malibu_phy_get_combo_prefer_medium(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_medium_t * phy_medium) +{ + a_uint16_t phy_data; + if (phy_id != COMBO_PHY_ID) + return SW_NOT_SUPPORTED; + + phy_data = malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_CHIP_CONFIG); + + *phy_medium = + (phy_data & MALIBU_PHY4_PREFER_FIBER) ? PHY_MEDIUM_FIBER : + PHY_MEDIUM_COPPER; + + return SW_OK; +} + +/****************************************************************************** +* +* malibu_phy_get current combo medium type copper or fiber +* +* get current combo medium type +*/ +sw_error_t +malibu_phy_get_combo_current_medium_type(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_medium_t * phy_medium) +{ + + if (phy_id != COMBO_PHY_ID) + return SW_NOT_SUPPORTED; + + *phy_medium = __phy_active_medium_get(dev_id, phy_id); + + return SW_OK; +} + +/****************************************************************************** +* +* malibu_phy_set fiber mode 1000bx or 100fx +* +* set combo fbier mode +*/ +sw_error_t +malibu_phy_set_combo_fiber_mode(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_fiber_mode_t fiber_mode) +{ + a_uint16_t phy_data; + if (phy_id != COMBO_PHY_ID) + return SW_NOT_SUPPORTED; + + phy_data = malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_CHIP_CONFIG); + + if (fiber_mode == PHY_FIBER_1000BX) { + phy_data |= MALIBU_PHY4_FIBER_MODE_1000BX; + } else if (fiber_mode == PHY_FIBER_100FX) { + phy_data &= ~MALIBU_PHY4_FIBER_MODE_1000BX; + } else { + return SW_BAD_PARAM; + } + + malibu_phy_reg_write(dev_id, phy_id, MALIBU_PHY_CHIP_CONFIG, phy_data); + + return SW_OK; +} + +/****************************************************************************** +* +* malibu_phy_get fiber mode 1000bx or 100fx +* +* get combo fbier mode +*/ +sw_error_t +malibu_phy_get_combo_fiber_mode(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_fiber_mode_t * fiber_mode) +{ + a_uint16_t phy_data; + if (phy_id != COMBO_PHY_ID) + return SW_NOT_SUPPORTED; + + phy_data = malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_CHIP_CONFIG); + + *fiber_mode = + (phy_data & MALIBU_PHY4_FIBER_MODE_1000BX) ? PHY_FIBER_1000BX : + PHY_FIBER_100FX; + + return SW_OK; +} + +/****************************************************************************** +* +* malibu_phy_set_mdix - +* +* set phy mdix configuraiton +*/ +sw_error_t +malibu_phy_set_mdix(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_mdix_mode_t mode) +{ + a_uint16_t phy_data; + + if ((phy_id == COMBO_PHY_ID) + && (MALIBU_PHY_MEDIUM_COPPER != + __phy_active_medium_get(dev_id, phy_id))) + + return SW_NOT_SUPPORTED; + + phy_data = malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_SPEC_CONTROL); + + if (mode == PHY_MDIX_AUTO) { + phy_data |= MALIBU_PHY_MDIX_AUTO; + } else if (mode == PHY_MDIX_MDIX) { + phy_data &= ~MALIBU_PHY_MDIX_AUTO; + phy_data |= MALIBU_PHY_MDIX; + } else if (mode == PHY_MDIX_MDI) { + phy_data &= ~MALIBU_PHY_MDIX_AUTO; + } else { + return SW_BAD_PARAM; + } + + malibu_phy_reg_write(dev_id, phy_id, MALIBU_PHY_SPEC_CONTROL, phy_data); + + malibu_phy_reset(dev_id, phy_id); + return SW_OK; +} + +/****************************************************************************** +* +* malibu_phy_get_mdix +* +* get phy mdix configuration +*/ +sw_error_t +malibu_phy_get_mdix(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_mdix_mode_t * mode) +{ + a_uint16_t phy_data; + + if ((phy_id == COMBO_PHY_ID) + && (MALIBU_PHY_MEDIUM_COPPER != + __phy_active_medium_get(dev_id, phy_id))) + + return SW_NOT_SUPPORTED; + + phy_data = malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_SPEC_CONTROL); + + if ((phy_data & MALIBU_PHY_MDIX_AUTO) == MALIBU_PHY_MDIX_AUTO) { + *mode = PHY_MDIX_AUTO; + } else if ((phy_data & MALIBU_PHY_MDIX) == MALIBU_PHY_MDIX) { + *mode = PHY_MDIX_MDIX; + } else { + *mode = PHY_MDIX_MDI; + } + + return SW_OK; + +} + +/****************************************************************************** +* +* malibu_phy_get_mdix status +* +* get phy mdix status +*/ +sw_error_t +malibu_phy_get_mdix_status(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_mdix_status_t * mode) +{ + a_uint16_t phy_data; + + if (phy_id == COMBO_PHY_ID) { + + if (MALIBU_PHY_MEDIUM_COPPER != + __phy_active_medium_get(dev_id, phy_id)) + return SW_NOT_SUPPORTED; + + __phy_reg_pages_sel(dev_id, phy_id, MALIBU_PHY_COPPER_PAGES); + } + + phy_data = malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_SPEC_STATUS); + + *mode = + (phy_data & MALIBU_PHY_MDIX_STATUS) ? PHY_MDIX_STATUS_MDIX : + PHY_MDIX_STATUS_MDI; + + return SW_OK; + +} + +/****************************************************************************** +* +* malibu_phy_set_local_loopback +* +* set phy local loopback +*/ +sw_error_t +malibu_phy_set_local_loopback(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t enable) +{ + a_uint16_t phy_data; + fal_port_speed_t old_speed; + + if (enable == A_TRUE) { + if (phy_id == COMBO_PHY_ID) { + + if (MALIBU_PHY_MEDIUM_COPPER != + __phy_active_medium_get(dev_id, phy_id)) { + + __phy_reg_pages_sel(dev_id, phy_id, + MALIBU_PHY_SGBX_PAGES); + + if (__medium_is_fiber_100fx(dev_id, phy_id)) { + + phy_data = MALIBU_100M_LOOPBACK; + + } else { + phy_data = MALIBU_1000M_LOOPBACK; + } + malibu_phy_reg_write(dev_id, phy_id, MALIBU_PHY_CONTROL, phy_data); + return SW_OK; + } + __phy_reg_pages_sel(dev_id, phy_id, + MALIBU_PHY_COPPER_PAGES); + } + + malibu_phy_get_speed(dev_id, phy_id, &old_speed); + if (old_speed == FAL_SPEED_1000) { + phy_data = MALIBU_1000M_LOOPBACK; + } else if (old_speed == FAL_SPEED_100) { + phy_data = MALIBU_100M_LOOPBACK; + } else if (old_speed == FAL_SPEED_10) { + phy_data = MALIBU_10M_LOOPBACK; + } else { + return SW_FAIL; + } + } else { + if (phy_id == COMBO_PHY_ID) { + if (MALIBU_PHY_MEDIUM_COPPER != + __phy_active_medium_get(dev_id, phy_id)) { + + __phy_reg_pages_sel(dev_id, phy_id, + MALIBU_PHY_SGBX_PAGES); + + } else { + __phy_reg_pages_sel(dev_id, phy_id, + MALIBU_PHY_COPPER_PAGES); + } + } + phy_data = MALIBU_COMMON_CTRL; + } + + + malibu_phy_reg_write(dev_id, phy_id, MALIBU_PHY_CONTROL, phy_data); + return SW_OK; + +} + +/****************************************************************************** +* +* malibu_phy_get_local_loopback +* +* get phy local loopback +*/ +sw_error_t +malibu_phy_get_local_loopback(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t * enable) +{ + a_uint16_t phy_data; + + if (phy_id == COMBO_PHY_ID) { + + __phy_reg_pages_sel_by_active_medium(dev_id, phy_id); + + } + + phy_data = malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_CONTROL); + + if (phy_data & MALIBU_LOCAL_LOOPBACK_ENABLE) { + *enable = A_TRUE; + } else { + *enable = A_FALSE; + } + + return SW_OK; + +} + +/****************************************************************************** +* +* malibu_phy_set_remote_loopback +* +* set phy remote loopback +*/ +sw_error_t +malibu_phy_set_remote_loopback(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t enable) +{ + a_uint16_t phy_data; + + phy_data = malibu_phy_mmd_read(dev_id, phy_id, MALIBU_PHY_MMD3_NUM, + MALIBU_PHY_MMD3_ADDR_REMOTE_LOOPBACK_CTRL); + + if (enable == A_TRUE) { + phy_data |= 0x0001; + } else { + phy_data &= ~0x0001; + } + + malibu_phy_mmd_write(dev_id, phy_id, MALIBU_PHY_MMD3_NUM, + MALIBU_PHY_MMD3_ADDR_REMOTE_LOOPBACK_CTRL, + phy_data); + return SW_OK; + +} + +/****************************************************************************** +* +* malibu_phy_get_remote_loopback +* +* get phy remote loopback +*/ +sw_error_t +malibu_phy_get_remote_loopback(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t * enable) +{ + a_uint16_t phy_data; + + phy_data = malibu_phy_mmd_read(dev_id, phy_id, MALIBU_PHY_MMD3_NUM, + MALIBU_PHY_MMD3_ADDR_REMOTE_LOOPBACK_CTRL); + + if (phy_data & 0x0001) { + *enable = A_TRUE; + } else { + *enable = A_FALSE; + } + + return SW_OK; + +} + +/****************************************************************************** +* +* malibu_phy_cdt - cable diagnostic test +* +* cable diagnostic test +*/ + +static inline fal_cable_status_t _phy_cdt_status_mapping(a_uint16_t status) +{ + fal_cable_status_t status_mapping = FAL_CABLE_STATUS_INVALID; + + if (0 == status) + status_mapping = FAL_CABLE_STATUS_INVALID; + else if (1 == status) + status_mapping = FAL_CABLE_STATUS_NORMAL; + else if (2 == status) + status_mapping = FAL_CABLE_STATUS_OPENED; + else if (3 == status) + status_mapping = FAL_CABLE_STATUS_SHORT; + + return status_mapping; +} + +static sw_error_t malibu_phy_cdt_start(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t status = 0; + a_uint16_t ii = 100; + + if (phy_id == COMBO_PHY_ID) { + + if (MALIBU_PHY_MEDIUM_COPPER != + __phy_active_medium_get(dev_id, phy_id)) + return SW_NOT_SUPPORTED; + + __phy_reg_pages_sel(dev_id, phy_id, MALIBU_PHY_COPPER_PAGES); + } + + /* RUN CDT */ + malibu_phy_reg_write(dev_id, phy_id, MALIBU_PHY_CDT_CONTROL, + RUN_CDT | CABLE_LENGTH_UNIT); + do { + aos_mdelay(30); + status = + malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_CDT_CONTROL); + } + while ((status & RUN_CDT) && (--ii)); + + return SW_OK; +} + +sw_error_t +malibu_phy_cdt_get(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_cdt_t * port_cdt) +{ + a_uint16_t status = 0; + a_uint16_t cable_delta_time = 0; + int i; + + if ((!port_cdt) || (phy_id > 4)) { + return SW_FAIL; + } + + + malibu_phy_cdt_start(dev_id, phy_id); + + /* Get cable status */ + status = malibu_phy_mmd_read(dev_id, phy_id, 3, 0x8064); + + + + for (i = 0; i < 4; i++) { + switch (i) { + case 0: + port_cdt->pair_a_status = (status >> 12) & 0x3; + /* Get Cable Length value */ + cable_delta_time = + malibu_phy_mmd_read(dev_id, phy_id, 3, 0x8065); + /* the actual cable length equals to CableDeltaTime * 0.824 */ + port_cdt->pair_a_len = + ((cable_delta_time & 0xff) * 800) / 1000; + + break; + case 1: + port_cdt->pair_b_status = (status >> 8) & 0x3; + /* Get Cable Length value */ + cable_delta_time = + malibu_phy_mmd_read(dev_id, phy_id, 3, 0x8066); + /* the actual cable length equals to CableDeltaTime * 0.824 */ + port_cdt->pair_b_len = + ((cable_delta_time & 0xff) * 800) / 1000; + break; + case 2: + port_cdt->pair_c_status = (status >> 4) & 0x3; + /* Get Cable Length value */ + cable_delta_time = + malibu_phy_mmd_read(dev_id, phy_id, 3, 0x8067); + /* the actual cable length equals to CableDeltaTime * 0.824 */ + port_cdt->pair_c_len = + ((cable_delta_time & 0xff) * 800) / 1000; + break; + case 3: + port_cdt->pair_d_status = status & 0x3; + /* Get Cable Length value */ + cable_delta_time = + malibu_phy_mmd_read(dev_id, phy_id, 3, 0x8068); + /* the actual cable length equals to CableDeltaTime * 0.824 */ + port_cdt->pair_d_len = + ((cable_delta_time & 0xff) * 800) / 1000; + break; + default: + break; + } + } + + + return SW_OK; +} + +sw_error_t +malibu_phy_cdt(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t mdi_pair, + fal_cable_status_t * cable_status, a_uint32_t * cable_len) +{ + fal_port_cdt_t malibu_port_cdt; + + if (phy_id == COMBO_PHY_ID) { + + if (MALIBU_PHY_MEDIUM_COPPER != + __phy_active_medium_get(dev_id, phy_id)) + return SW_NOT_SUPPORTED; + + __phy_reg_pages_sel(dev_id, phy_id, MALIBU_PHY_COPPER_PAGES); + } + + if ((mdi_pair >= 4) || (phy_id > 4)) { + //There are only 4 mdi pairs in 1000BASE-T + return SW_BAD_PARAM; + } + + malibu_phy_cdt_get(dev_id, phy_id, &malibu_port_cdt); + + switch (mdi_pair) { + case 0: + *cable_status = + _phy_cdt_status_mapping(malibu_port_cdt.pair_a_status); + /* Get Cable Length value */ + *cable_len = malibu_port_cdt.pair_a_len; + break; + case 1: + *cable_status = + _phy_cdt_status_mapping(malibu_port_cdt.pair_b_status); + /* Get Cable Length value */ + *cable_len = malibu_port_cdt.pair_b_len; + break; + case 2: + *cable_status = + _phy_cdt_status_mapping(malibu_port_cdt.pair_c_status); + /* Get Cable Length value */ + *cable_len = malibu_port_cdt.pair_c_len; + break; + case 3: + *cable_status = + _phy_cdt_status_mapping(malibu_port_cdt.pair_d_status); + /* Get Cable Length value */ + *cable_len = malibu_port_cdt.pair_d_len; + break; + default: + break; + } + + return SW_OK; +} + +/****************************************************************************** +* +* malibu_phy_reset_done - reset the phy +* +* reset the phy +*/ +a_bool_t malibu_phy_reset_done(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + a_uint16_t ii = 200; + + if (phy_id == COMBO_PHY_ID) + __phy_reg_pages_sel_by_active_medium(dev_id, phy_id); + + do { + phy_data = + malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_CONTROL); + aos_mdelay(10); + } + while ((!MALIBU_RESET_DONE(phy_data)) && --ii); + + if (ii == 0) + return A_FALSE; + + return A_TRUE; +} + +/****************************************************************************** +* +* malibu_autoneg_done +* +* malibu_autoneg_done +*/ +a_bool_t malibu_autoneg_done(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + a_uint16_t ii = 200; + + if (phy_id == COMBO_PHY_ID) + __phy_reg_pages_sel_by_active_medium(dev_id, phy_id); + + do { + phy_data = + malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_STATUS); + aos_mdelay(10); + } + while ((!MALIBU_AUTONEG_DONE(phy_data)) && --ii); + + if (ii == 0) + return A_FALSE; + + return A_TRUE; +} + +/****************************************************************************** +* +* malibu_phy_Speed_Duplex_Resolved + - reset the phy +* +* reset the phy +*/ +a_bool_t malibu_phy_speed_duplex_resolved(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + a_uint16_t ii = 200; + + if (phy_id == COMBO_PHY_ID) + __phy_reg_pages_sel_by_active_medium(dev_id, phy_id); + + do { + phy_data = + malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_SPEC_STATUS); + aos_mdelay(10); + } + while ((!MALIBU_SPEED_DUPLEX_RESOVLED(phy_data)) && --ii); + + if (ii == 0) + return A_FALSE; + + return A_TRUE; +} +#endif +/****************************************************************************** +* +* malibu_phy_off - power off the phy +* +* Power off the phy +*/ +sw_error_t malibu_phy_poweroff(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + if (phy_id == COMBO_PHY_ID) { + __phy_reg_pages_sel(dev_id, phy_id, MALIBU_PHY_SGBX_PAGES); + phy_data = + malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_CONTROL); + malibu_phy_reg_write(dev_id, phy_id, MALIBU_PHY_CONTROL, + phy_data | MALIBU_CTRL_POWER_DOWN); + + __phy_reg_pages_sel(dev_id, phy_id, MALIBU_PHY_COPPER_PAGES); + phy_data = + malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_CONTROL); + malibu_phy_reg_write(dev_id, phy_id, MALIBU_PHY_CONTROL, + phy_data | MALIBU_CTRL_POWER_DOWN); + } else { + phy_data = + malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_CONTROL); + malibu_phy_reg_write(dev_id, phy_id, MALIBU_PHY_CONTROL, + phy_data | MALIBU_CTRL_POWER_DOWN); + } + return SW_OK; +} + +/****************************************************************************** +* +* malibu_phy_on - power on the phy +* +* Power on the phy +*/ +sw_error_t malibu_phy_poweron(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + if (phy_id == COMBO_PHY_ID) { + __phy_reg_pages_sel(dev_id, phy_id, MALIBU_PHY_SGBX_PAGES); + phy_data = + malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_CONTROL); + malibu_phy_reg_write(dev_id, phy_id, MALIBU_PHY_CONTROL, + phy_data & ~MALIBU_CTRL_POWER_DOWN); + + __phy_reg_pages_sel(dev_id, phy_id, MALIBU_PHY_COPPER_PAGES); + phy_data = + malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_CONTROL); + malibu_phy_reg_write(dev_id, phy_id, MALIBU_PHY_CONTROL, + phy_data & ~MALIBU_CTRL_POWER_DOWN); + + } else { + phy_data = + malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_CONTROL); + malibu_phy_reg_write(dev_id, phy_id, MALIBU_PHY_CONTROL, + phy_data & ~MALIBU_CTRL_POWER_DOWN); + } + + aos_mdelay(200); + + return SW_OK; +} +#ifndef IN_PORTCONTROL_MINI +/****************************************************************************** +* +* malibu_phy_get_ability - get the phy ability +* +* +*/ +sw_error_t +malibu_phy_get_ability(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * ability) +{ + a_uint16_t phy_data; + + *ability = 0; + if (phy_id == COMBO_PHY_ID) + __phy_reg_pages_sel_by_active_medium(dev_id, phy_id); + + phy_data = malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_STATUS); + + if (phy_data & MALIBU_STATUS_AUTONEG_CAPS) + *ability |= FAL_PHY_AUTONEG_CAPS; + + if (phy_data & MALIBU_STATUS_100T2_HD_CAPS) + *ability |= FAL_PHY_100T2_HD_CAPS; + + if (phy_data & MALIBU_STATUS_100T2_FD_CAPS) + *ability |= FAL_PHY_100T2_FD_CAPS; + + if (phy_data & MALIBU_STATUS_10T_HD_CAPS) + *ability |= FAL_PHY_10T_HD_CAPS; + + if (phy_data & MALIBU_STATUS_10T_FD_CAPS) + *ability |= FAL_PHY_10T_FD_CAPS; + + if (phy_data & MALIBU_STATUS_100X_HD_CAPS) + *ability |= FAL_PHY_100X_HD_CAPS; + + if (phy_data & MALIBU_STATUS_100X_FD_CAPS) + *ability |= FAL_PHY_100X_FD_CAPS; + + if (phy_data & MALIBU_STATUS_100T4_CAPS) + *ability |= FAL_PHY_100T4_CAPS; + + if (phy_data & MALIBU_STATUS_EXTENDED_STATUS) { + phy_data = + malibu_phy_reg_read(dev_id, phy_id, MALIBU_EXTENDED_STATUS); + + if (phy_data & MALIBU_STATUS_1000T_FD_CAPS) { + *ability |= FAL_PHY_1000T_FD_CAPS; + } + + if (phy_data & MALIBU_STATUS_1000X_FD_CAPS) { + *ability |= FAL_PHY_1000X_FD_CAPS; + } + } + + return SW_OK; +} + +/****************************************************************************** +* +* malibu_phy_get_ability - get the phy ability +* +* +*/ +sw_error_t +malibu_phy_get_partner_ability(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * ability) +{ + a_uint16_t phy_data; + + *ability = 0; + + if (phy_id == COMBO_PHY_ID) + __phy_reg_pages_sel_by_active_medium(dev_id, phy_id); + + phy_data = + malibu_phy_reg_read(dev_id, phy_id, MALIBU_LINK_PARTNER_ABILITY); + + if (phy_data & MALIBU_LINK_10BASETX_HALF_DUPLEX) + *ability |= FAL_PHY_PART_10T_HD; + + if (phy_data & MALIBU_LINK_10BASETX_FULL_DUPLEX) + *ability |= FAL_PHY_PART_10T_FD; + + if (phy_data & MALIBU_LINK_100BASETX_HALF_DUPLEX) + *ability |= FAL_PHY_PART_100TX_HD; + + if (phy_data & MALIBU_LINK_100BASETX_FULL_DUPLEX) + *ability |= FAL_PHY_PART_100TX_FD; + + if (phy_data & MALIBU_LINK_NPAGE) { + phy_data = + malibu_phy_reg_read(dev_id, phy_id, + MALIBU_1000BASET_STATUS); + + if (phy_data & MALIBU_LINK_1000BASETX_FULL_DUPLEX) + *ability |= FAL_PHY_PART_1000T_FD; + } + + return SW_OK; +} +#endif +/****************************************************************************** +* +* malibu_phy_status - test to see if the specified phy link is alive +* +* RETURNS: +* A_TRUE --> link is alive +* A_FALSE --> link is down +*/ +a_bool_t malibu_phy_get_link_status(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + if (phy_id == COMBO_PHY_ID) + __phy_reg_pages_sel_by_active_medium(dev_id, phy_id); + phy_data = malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_SPEC_STATUS); + + if (phy_data & MALIBU_STATUS_LINK_PASS) + return A_TRUE; + + return A_FALSE; +} + +/****************************************************************************** +* +* malibu_set_autoneg_adv - set the phy autoneg Advertisement +* +*/ +sw_error_t +malibu_phy_set_autoneg_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t autoneg) +{ + a_uint16_t phy_data = 0; + if (phy_id == COMBO_PHY_ID) { + if (__medium_is_fiber_100fx(dev_id, phy_id)) + return SW_NOT_SUPPORTED; + + if (MALIBU_PHY_MEDIUM_COPPER == + __phy_active_medium_get(dev_id, phy_id)) { + + __phy_reg_pages_sel(dev_id, phy_id, + MALIBU_PHY_COPPER_PAGES); + phy_data = + malibu_phy_reg_read(dev_id, phy_id, + MALIBU_AUTONEG_ADVERT); + phy_data &= ~MALIBU_ADVERTISE_MEGA_ALL; + phy_data &= + ~(MALIBU_ADVERTISE_PAUSE | + MALIBU_ADVERTISE_ASYM_PAUSE); + + if (autoneg & FAL_PHY_ADV_100TX_FD) { + phy_data |= MALIBU_ADVERTISE_100FULL; + } + if (autoneg & FAL_PHY_ADV_100TX_HD) { + phy_data |= MALIBU_ADVERTISE_100HALF; + } + if (autoneg & FAL_PHY_ADV_10T_FD) { + phy_data |= MALIBU_ADVERTISE_10FULL; + } + if (autoneg & FAL_PHY_ADV_10T_HD) { + phy_data |= MALIBU_ADVERTISE_10HALF; + } + if (autoneg & FAL_PHY_ADV_PAUSE) { + phy_data |= MALIBU_ADVERTISE_PAUSE; + } + if (autoneg & FAL_PHY_ADV_ASY_PAUSE) { + phy_data |= MALIBU_ADVERTISE_ASYM_PAUSE; + } + __phy_reg_pages_sel(dev_id, phy_id, + MALIBU_PHY_COPPER_PAGES); + if (autoneg & FAL_PHY_ADV_1000T_FD) { + phy_data |= MALIBU_EXTENDED_NEXT_PAGE_EN; + } else { + phy_data &= ~MALIBU_EXTENDED_NEXT_PAGE_EN; + } + malibu_phy_reg_write(dev_id, phy_id, + MALIBU_AUTONEG_ADVERT, phy_data); + + phy_data = + malibu_phy_reg_read(dev_id, phy_id, + MALIBU_1000BASET_CONTROL); + phy_data &= ~MALIBU_ADVERTISE_1000FULL; + phy_data &= ~MALIBU_ADVERTISE_1000HALF; + + if (autoneg & FAL_PHY_ADV_1000T_FD) { + phy_data |= MALIBU_ADVERTISE_1000FULL; + } + malibu_phy_reg_write(dev_id, phy_id, + MALIBU_1000BASET_CONTROL, + phy_data); + } else { + + __phy_reg_pages_sel(dev_id, phy_id, + MALIBU_PHY_SGBX_PAGES); + phy_data = + malibu_phy_reg_read(dev_id, phy_id, + MALIBU_AUTONEG_ADVERT); + phy_data &= ~MALIBU_BX_ADVERTISE_ALL; + + if (autoneg & FAL_PHY_ADV_1000BX_FD) { + phy_data |= MALIBU_BX_ADVERTISE_1000FULL; + } + if (autoneg & FAL_PHY_ADV_1000BX_HD) { + phy_data |= MALIBU_BX_ADVERTISE_1000HALF; + } + if (autoneg & FAL_PHY_ADV_PAUSE) { + phy_data |= MALIBU_BX_ADVERTISE_PAUSE; + } + if (autoneg & FAL_PHY_ADV_ASY_PAUSE) { + phy_data |= MALIBU_BX_ADVERTISE_ASYM_PAUSE; + } + __phy_reg_pages_sel(dev_id, phy_id, + MALIBU_PHY_SGBX_PAGES); + + malibu_phy_reg_write(dev_id, phy_id, + MALIBU_AUTONEG_ADVERT, phy_data); + } + } else { + + phy_data = + malibu_phy_reg_read(dev_id, phy_id, MALIBU_AUTONEG_ADVERT); + phy_data &= ~MALIBU_ADVERTISE_MEGA_ALL; + phy_data &= + ~(MALIBU_ADVERTISE_PAUSE | MALIBU_ADVERTISE_ASYM_PAUSE); + + if (autoneg & FAL_PHY_ADV_100TX_FD) { + phy_data |= MALIBU_ADVERTISE_100FULL; + } + if (autoneg & FAL_PHY_ADV_100TX_HD) { + phy_data |= MALIBU_ADVERTISE_100HALF; + } + if (autoneg & FAL_PHY_ADV_10T_FD) { + phy_data |= MALIBU_ADVERTISE_10FULL; + } + if (autoneg & FAL_PHY_ADV_10T_HD) { + phy_data |= MALIBU_ADVERTISE_10HALF; + } + if (autoneg & FAL_PHY_ADV_PAUSE) { + phy_data |= MALIBU_ADVERTISE_PAUSE; + } + if (autoneg & FAL_PHY_ADV_ASY_PAUSE) { + phy_data |= MALIBU_ADVERTISE_ASYM_PAUSE; + } + if (autoneg & FAL_PHY_ADV_1000T_FD) { + phy_data |= MALIBU_EXTENDED_NEXT_PAGE_EN; + } else { + phy_data &= ~MALIBU_EXTENDED_NEXT_PAGE_EN; + } + malibu_phy_reg_write(dev_id, phy_id, MALIBU_AUTONEG_ADVERT, + phy_data); + + phy_data = + malibu_phy_reg_read(dev_id, phy_id, + MALIBU_1000BASET_CONTROL); + phy_data &= ~MALIBU_ADVERTISE_1000FULL; + phy_data &= ~MALIBU_ADVERTISE_1000HALF; + + if (autoneg & FAL_PHY_ADV_1000T_FD) { + phy_data |= MALIBU_ADVERTISE_1000FULL; + } + malibu_phy_reg_write(dev_id, phy_id, MALIBU_1000BASET_CONTROL, + phy_data); + + } + + return SW_OK; +} + +/****************************************************************************** +* +* malibu_get_autoneg_adv - get the phy autoneg Advertisement +* +*/ +sw_error_t +malibu_phy_get_autoneg_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * autoneg) +{ + a_uint16_t phy_data = 0; + + *autoneg = 0; + + if (phy_id == COMBO_PHY_ID) { + if (__medium_is_fiber_100fx(dev_id, phy_id)) + return SW_NOT_SUPPORTED; + + if (MALIBU_PHY_MEDIUM_COPPER == + __phy_active_medium_get(dev_id, phy_id)) { + + __phy_reg_pages_sel(dev_id, phy_id, + MALIBU_PHY_COPPER_PAGES); + + phy_data = + malibu_phy_reg_read(dev_id, phy_id, + MALIBU_AUTONEG_ADVERT); + + if (phy_data & MALIBU_ADVERTISE_100FULL) + *autoneg |= FAL_PHY_ADV_100TX_FD; + + if (phy_data & MALIBU_ADVERTISE_100HALF) + *autoneg |= FAL_PHY_ADV_100TX_HD; + + if (phy_data & MALIBU_ADVERTISE_10FULL) + *autoneg |= FAL_PHY_ADV_10T_FD; + + if (phy_data & MALIBU_ADVERTISE_10HALF) + *autoneg |= FAL_PHY_ADV_10T_HD; + + if (phy_data & MALIBU_ADVERTISE_PAUSE) + *autoneg |= FAL_PHY_ADV_PAUSE; + + if (phy_data & MALIBU_ADVERTISE_ASYM_PAUSE) + *autoneg |= FAL_PHY_ADV_ASY_PAUSE; + + phy_data = + malibu_phy_reg_read(dev_id, phy_id, + MALIBU_1000BASET_CONTROL); + + if (phy_data & MALIBU_ADVERTISE_1000FULL) + *autoneg |= FAL_PHY_ADV_1000T_FD; + + } else { + + __phy_reg_pages_sel(dev_id, phy_id, + MALIBU_PHY_SGBX_PAGES); + phy_data = + malibu_phy_reg_read(dev_id, phy_id, + MALIBU_AUTONEG_ADVERT); + + if (phy_data & MALIBU_BX_ADVERTISE_PAUSE) + *autoneg |= FAL_PHY_ADV_PAUSE; + + if (phy_data & MALIBU_BX_ADVERTISE_ASYM_PAUSE) + *autoneg |= FAL_PHY_ADV_ASY_PAUSE; + + if (phy_data & MALIBU_BX_ADVERTISE_1000HALF) + *autoneg |= FAL_PHY_ADV_1000BX_HD; + + if (phy_data & MALIBU_BX_ADVERTISE_1000FULL) + *autoneg |= FAL_PHY_ADV_1000BX_FD; + } + } else { + + phy_data = + malibu_phy_reg_read(dev_id, phy_id, MALIBU_AUTONEG_ADVERT); + + if (phy_data & MALIBU_ADVERTISE_100FULL) + *autoneg |= FAL_PHY_ADV_100TX_FD; + + if (phy_data & MALIBU_ADVERTISE_100HALF) + *autoneg |= FAL_PHY_ADV_100TX_HD; + + if (phy_data & MALIBU_ADVERTISE_10FULL) + *autoneg |= FAL_PHY_ADV_10T_FD; + + if (phy_data & MALIBU_ADVERTISE_10HALF) + *autoneg |= FAL_PHY_ADV_10T_HD; + + if (phy_data & MALIBU_ADVERTISE_PAUSE) + *autoneg |= FAL_PHY_ADV_PAUSE; + + if (phy_data & MALIBU_ADVERTISE_ASYM_PAUSE) + *autoneg |= FAL_PHY_ADV_ASY_PAUSE; + + phy_data = + malibu_phy_reg_read(dev_id, phy_id, + MALIBU_1000BASET_CONTROL); + if (phy_data & MALIBU_ADVERTISE_1000FULL) + *autoneg |= FAL_PHY_ADV_1000T_FD; + } + + return SW_OK; +} + +/****************************************************************************** +* +* malibu_phy_enable_autonego +* +* Power off the phy +*/ +a_bool_t malibu_phy_autoneg_status(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + + if (phy_id == COMBO_PHY_ID) { + + if (__medium_is_fiber_100fx(dev_id, phy_id)) + return A_FALSE; + __phy_reg_pages_sel_by_active_medium(dev_id, phy_id); + } + + phy_data = malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_CONTROL); + + if (phy_data & MALIBU_CTRL_AUTONEGOTIATION_ENABLE) + return A_TRUE; + + return A_FALSE; +} + +/****************************************************************************** +* +* malibu_restart_autoneg - restart the phy autoneg +* +*/ +sw_error_t malibu_phy_restart_autoneg(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data = 0; + + if (phy_id == COMBO_PHY_ID) { + if (__medium_is_fiber_100fx(dev_id, phy_id)) + return SW_NOT_SUPPORTED; + __phy_reg_pages_sel_by_active_medium(dev_id, phy_id); + } + phy_data = malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_CONTROL); + + phy_data |= MALIBU_CTRL_AUTONEGOTIATION_ENABLE; + malibu_phy_reg_write(dev_id, phy_id, MALIBU_PHY_CONTROL, + phy_data | MALIBU_CTRL_RESTART_AUTONEGOTIATION); + + return SW_OK; +} + +/****************************************************************************** +* +* malibu_phy_enable_autonego +* +*/ +sw_error_t malibu_phy_enable_autoneg(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data = 0; + + if (phy_id == COMBO_PHY_ID) { + if (__medium_is_fiber_100fx(dev_id, phy_id)) + return SW_NOT_SUPPORTED; + __phy_reg_pages_sel_by_active_medium(dev_id, phy_id); + } + phy_data = malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_CONTROL); + + malibu_phy_reg_write(dev_id, phy_id, MALIBU_PHY_CONTROL, + phy_data | MALIBU_CTRL_AUTONEGOTIATION_ENABLE); + + return SW_OK; +} + +/****************************************************************************** +* +* malibu_phy_set_speed - Determines the speed of phy ports associated with the +* specified device. +*/ +sw_error_t +malibu_phy_set_speed(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_speed_t speed) +{ + a_uint16_t phy_data = 0; + fal_port_duplex_t old_duplex; + + if (phy_id == COMBO_PHY_ID) { + if (MALIBU_PHY_MEDIUM_COPPER != + __phy_active_medium_get(dev_id, phy_id)) + + return SW_NOT_SUPPORTED; + + __phy_reg_pages_sel(dev_id, phy_id, MALIBU_PHY_COPPER_PAGES); + } + + phy_data = malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_CONTROL); + + malibu_phy_get_duplex(dev_id, phy_id, &old_duplex); + + if (old_duplex == FAL_FULL_DUPLEX) { + phy_data |= MALIBU_CTRL_FULL_DUPLEX; + + if (FAL_SPEED_1000 == speed) { + phy_data |= MALIBU_CTRL_SPEED_1000; + phy_data &= ~MALIBU_CTRL_SPEED_100; + phy_data |= MALIBU_CTRL_AUTONEGOTIATION_ENABLE; + } else if (FAL_SPEED_100 == speed) { + phy_data |= MALIBU_CTRL_SPEED_100; + phy_data &= ~MALIBU_CTRL_SPEED_1000; + phy_data &= ~MALIBU_CTRL_AUTONEGOTIATION_ENABLE; + } else if (FAL_SPEED_10 == speed){ + phy_data &= ~MALIBU_CTRL_SPEED_100; + phy_data &= ~MALIBU_CTRL_SPEED_1000; + phy_data &= ~MALIBU_CTRL_AUTONEGOTIATION_ENABLE; + } else { + return SW_BAD_PARAM; + } + } else if (old_duplex == FAL_HALF_DUPLEX) { + phy_data &= ~MALIBU_CTRL_FULL_DUPLEX; + + if (FAL_SPEED_100 == speed) { + phy_data |= MALIBU_CTRL_SPEED_100; + phy_data &= ~MALIBU_CTRL_SPEED_1000; + phy_data &= ~MALIBU_CTRL_AUTONEGOTIATION_ENABLE; + } else if (FAL_SPEED_10 == speed) { + phy_data &= ~MALIBU_CTRL_SPEED_100; + phy_data &= ~MALIBU_CTRL_SPEED_1000; + phy_data &= ~MALIBU_CTRL_AUTONEGOTIATION_ENABLE; + } else if (FAL_SPEED_1000 == speed){ + phy_data |= MALIBU_CTRL_FULL_DUPLEX; + phy_data |= MALIBU_CTRL_SPEED_1000; + phy_data &= ~MALIBU_CTRL_SPEED_100; + phy_data |= MALIBU_CTRL_AUTONEGOTIATION_ENABLE; + } else { + return SW_BAD_PARAM; + } + } else { + return SW_FAIL; + } + + malibu_phy_reg_write(dev_id, phy_id, MALIBU_PHY_CONTROL, phy_data); + return SW_OK; + +} + +/****************************************************************************** +* +* malibu_phy_set_duplex - Determines the speed of phy ports associated with the +* specified device. +*/ +sw_error_t +malibu_phy_set_duplex(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_duplex_t duplex) +{ + a_uint16_t phy_data = 0; + fal_port_speed_t old_speed; + + if (phy_id == COMBO_PHY_ID) { + + if (MALIBU_PHY_MEDIUM_COPPER != + __phy_active_medium_get(dev_id, phy_id)) { + + __phy_reg_pages_sel(dev_id, phy_id, + MALIBU_PHY_SGBX_PAGES); + + phy_data = + malibu_phy_reg_read(dev_id, phy_id, + MALIBU_PHY_CONTROL); + + if (__medium_is_fiber_100fx(dev_id, phy_id)) { + + if (duplex == FAL_FULL_DUPLEX) { + phy_data |= MALIBU_CTRL_FULL_DUPLEX; + } else if (duplex == FAL_HALF_DUPLEX) { + phy_data &= ~MALIBU_CTRL_FULL_DUPLEX; + } else { + return SW_BAD_PARAM; + } + } else { + + if (duplex == FAL_FULL_DUPLEX) { + phy_data |= MALIBU_CTRL_FULL_DUPLEX; + phy_data &= ~MALIBU_CTRL_AUTONEGOTIATION_ENABLE; + } else if (duplex == FAL_HALF_DUPLEX) { + phy_data &= ~MALIBU_CTRL_FULL_DUPLEX; + phy_data &= ~MALIBU_CTRL_AUTONEGOTIATION_ENABLE; + } else { + return SW_BAD_PARAM; + } + } + malibu_phy_reg_write(dev_id, phy_id, + MALIBU_PHY_CONTROL, + phy_data); + + return SW_OK; + } + __phy_reg_pages_sel(dev_id, phy_id, + MALIBU_PHY_COPPER_PAGES); + } + + phy_data = malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_CONTROL); + + malibu_phy_get_speed(dev_id, phy_id, &old_speed); + + if (old_speed == FAL_SPEED_1000) { + + phy_data |= MALIBU_CTRL_SPEED_1000; + phy_data &= ~MALIBU_CTRL_SPEED_100; + phy_data |= MALIBU_CTRL_AUTONEGOTIATION_ENABLE; + + if (duplex == FAL_FULL_DUPLEX) { + phy_data |= MALIBU_CTRL_FULL_DUPLEX; + + } else if (duplex == FAL_HALF_DUPLEX) { + + return SW_NOT_SUPPORTED; + } else { + return SW_BAD_PARAM; + } + } else if (old_speed == FAL_SPEED_100) { + phy_data |= MALIBU_CTRL_SPEED_100; + phy_data &= ~MALIBU_CTRL_SPEED_1000; + phy_data &= ~MALIBU_CTRL_AUTONEGOTIATION_ENABLE; + + if (duplex == FAL_FULL_DUPLEX) { + phy_data |= MALIBU_CTRL_FULL_DUPLEX; + + } else if (duplex == FAL_HALF_DUPLEX) { + + phy_data &= ~MALIBU_CTRL_FULL_DUPLEX; + + } else { + return SW_BAD_PARAM; + } + } else if (old_speed == FAL_SPEED_10) { + phy_data &= ~MALIBU_CTRL_SPEED_100; + phy_data &= ~MALIBU_CTRL_SPEED_1000; + phy_data &= ~MALIBU_CTRL_AUTONEGOTIATION_ENABLE; + + if (duplex == FAL_FULL_DUPLEX) { + phy_data |= MALIBU_CTRL_FULL_DUPLEX; + + } else if (duplex == FAL_HALF_DUPLEX) { + + phy_data &= ~MALIBU_CTRL_FULL_DUPLEX; + + } else { + return SW_BAD_PARAM; + } + } else { + return SW_FAIL; + } + malibu_phy_reg_write(dev_id, phy_id, MALIBU_PHY_CONTROL, phy_data); + + return SW_OK; +} + +/****************************************************************************** +* +* malibu_phy_get_phy_id - get the phy id +* +*/ +sw_error_t +malibu_phy_get_phy_id(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *phy_data) +{ + a_uint16_t org_id, rev_id; + + org_id = malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_ID1); + rev_id = malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_ID2); + + *phy_data = ((org_id & 0xffff) << 16) | (rev_id & 0xffff); + + return SW_OK; +} +#ifndef IN_PORTCONTROL_MINI +/****************************************************************************** +* +* malibu_phy_set wol frame mac address +* +* set phy wol frame mac address +*/ +sw_error_t +malibu_phy_set_magic_frame_mac(a_uint32_t dev_id, a_uint32_t phy_id, + fal_mac_addr_t * mac) +{ + a_uint16_t phy_data1; + a_uint16_t phy_data2; + a_uint16_t phy_data3; + + phy_data1 = (mac->uc[0] << 8) | mac->uc[1]; + phy_data2 = (mac->uc[2] << 8) | mac->uc[3]; + phy_data3 = (mac->uc[4] << 8) | mac->uc[5]; + + malibu_phy_mmd_write(dev_id, phy_id, MALIBU_PHY_MMD3_NUM, + MALIBU_PHY_MMD3_WOL_MAGIC_MAC_CTRL1, phy_data1); + + malibu_phy_mmd_write(dev_id, phy_id, MALIBU_PHY_MMD3_NUM, + MALIBU_PHY_MMD3_WOL_MAGIC_MAC_CTRL2, phy_data2); + + malibu_phy_mmd_write(dev_id, phy_id, MALIBU_PHY_MMD3_NUM, + MALIBU_PHY_MMD3_WOL_MAGIC_MAC_CTRL3, phy_data3); + + return SW_OK; +} + +/****************************************************************************** +* +* malibu_phy_get wol frame mac address +* +* get phy wol frame mac address +*/ +sw_error_t +malibu_phy_get_magic_frame_mac(a_uint32_t dev_id, a_uint32_t phy_id, + fal_mac_addr_t * mac) +{ + a_uint16_t phy_data1; + a_uint16_t phy_data2; + a_uint16_t phy_data3; + + phy_data1 = malibu_phy_mmd_read(dev_id, phy_id, MALIBU_PHY_MMD3_NUM, + MALIBU_PHY_MMD3_WOL_MAGIC_MAC_CTRL1); + + phy_data2 = malibu_phy_mmd_read(dev_id, phy_id, MALIBU_PHY_MMD3_NUM, + MALIBU_PHY_MMD3_WOL_MAGIC_MAC_CTRL2); + + phy_data3 = malibu_phy_mmd_read(dev_id, phy_id, MALIBU_PHY_MMD3_NUM, + MALIBU_PHY_MMD3_WOL_MAGIC_MAC_CTRL3); + + mac->uc[0] = (phy_data1 >> 8); + mac->uc[1] = (phy_data1 & 0x00ff); + mac->uc[2] = (phy_data2 >> 8); + mac->uc[3] = (phy_data2 & 0x00ff); + mac->uc[4] = (phy_data3 >> 8); + mac->uc[5] = (phy_data3 & 0x00ff); + phy_data2 = (mac->uc[2] << 8) | mac->uc[3]; + phy_data3 = (mac->uc[4] << 8) | mac->uc[5]; + + return SW_OK; +} + +/****************************************************************************** +* +* malibu_phy_set wol enable or disable +* +* set phy wol enable or disable +*/ +sw_error_t +malibu_phy_set_wol_status(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable) +{ + a_uint16_t phy_data; + phy_data = malibu_phy_mmd_read(dev_id, phy_id, MALIBU_PHY_MMD3_NUM, + MALIBU_PHY_MMD3_WOL_CTRL); + + if (enable == A_TRUE) { + phy_data |= 0x0020; + } else { + phy_data &= ~0x0020; + } + + malibu_phy_mmd_write(dev_id, phy_id, MALIBU_PHY_MMD3_NUM, + MALIBU_PHY_MMD3_WOL_CTRL, phy_data); + + return SW_OK; +} + +/****************************************************************************** +* +* malibu_phy_get_wol status +* +* get wol status +*/ +sw_error_t +malibu_phy_get_wol_status(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t * enable) +{ + a_uint16_t phy_data; + + *enable = A_FALSE; + + phy_data = malibu_phy_mmd_read(dev_id, phy_id, MALIBU_PHY_MMD3_NUM, + MALIBU_PHY_MMD3_WOL_CTRL); + + if (phy_data & 0x0020) + *enable = A_TRUE; + + return SW_OK; +} +#endif +/****************************************************************************** +* +* malibu_serdes_reset - malibu psgmii serdes reset +* +* reset serdes +*/ +sw_error_t +malibu_phy_serdes_reset(a_uint32_t dev_id) +{ + + malibu_phy_reg_write(dev_id, first_phy_addr + MALIBU_PHY_PSGMII_ADDR_INC, + MALIBU_MODE_RESET_REG, MALIBU_MODE_CHANAGE_RESET); + mdelay(100); + malibu_phy_reg_write(dev_id, first_phy_addr + MALIBU_PHY_PSGMII_ADDR_INC, + MALIBU_MODE_RESET_REG, MALIBU_MODE_RESET_DEFAULT_VALUE); + + return SW_OK; +} + +/****************************************************************************** +* +* malibu_phy_interface mode set +* +* set malibu phy interface mode +*/ +sw_error_t +malibu_phy_interface_set_mode(a_uint32_t dev_id, a_uint32_t phy_id, fal_port_interface_mode_t interface_mode) +{ + a_uint16_t phy_data; + + if ((phy_id < first_phy_addr) || + (phy_id > (first_phy_addr + MALIBU_PHY_MAX_ADDR_INC))) + return SW_NOT_SUPPORTED; + + phy_data = malibu_phy_reg_read(dev_id, + first_phy_addr + MALIBU_PHY_MAX_ADDR_INC, MALIBU_PHY_CHIP_CONFIG); + phy_data &= 0xfff0; + + if (interface_mode == PHY_PSGMII_BASET) { + phy_data |= MALIBU_PHY_PSGMII_BASET; + } else if (interface_mode == PHY_PSGMII_BX1000) { + phy_data |= MALIBU_PHY_PSGMII_BX1000; + } else if (interface_mode == PHY_PSGMII_FX100) { + phy_data |= MALIBU_PHY_PSGMII_FX100; + } else if (interface_mode == PHY_PSGMII_AMDET) { + phy_data |= MALIBU_PHY_PSGMII_AMDET; + } else if (interface_mode == PHY_SGMII_BASET || + interface_mode == PORT_QSGMII) { + phy_data |= MALIBU_PHY_SGMII_BASET; + } else if (interface_mode == PHY_PSGMII_FIBER) { + phy_data |= MALIBU_PHY_PSGMII_AMDET; + } else { + return SW_BAD_PARAM; + } + + malibu_phy_reg_write(dev_id, + first_phy_addr + MALIBU_PHY_MAX_ADDR_INC, MALIBU_PHY_CHIP_CONFIG, phy_data); + + /* reset operation */ + malibu_phy_serdes_reset(dev_id); + + if (interface_mode == PHY_PSGMII_FIBER) { + malibu_phy_reg_write(dev_id, first_phy_addr + MALIBU_PHY_MAX_ADDR_INC, + MALIBU_PHY_CHIP_CONFIG, MALIBU_MODECTRL_DFLT); + malibu_phy_reg_write(dev_id, first_phy_addr + MALIBU_PHY_MAX_ADDR_INC, + MALIBU_PHY_CONTROL, MALIBU_MIICTRL_DFLT); + } + + return SW_OK; +} + +/****************************************************************************** +* +* malibu_phy_interface mode get +* +* get malibu phy interface mode +*/ +sw_error_t +malibu_phy_interface_get_mode(a_uint32_t dev_id, a_uint32_t phy_id, fal_port_interface_mode_t *interface_mode) +{ + a_uint16_t phy_data; + a_uint16_t copper_mode; + + if ((phy_id < first_phy_addr) || + (phy_id > (first_phy_addr + MALIBU_PHY_MAX_ADDR_INC))) { + return SW_NOT_SUPPORTED; + } + + phy_data = malibu_phy_reg_read(dev_id, + first_phy_addr + MALIBU_PHY_MAX_ADDR_INC, MALIBU_PHY_CHIP_CONFIG); + copper_mode = ((phy_data & MALIBU_PHY_COPPER_MODE) >> 0xf); + phy_data &= 0x000f; + + switch (phy_data) { + case MALIBU_PHY_PSGMII_BASET: + *interface_mode = PHY_PSGMII_BASET; + break; + case MALIBU_PHY_PSGMII_BX1000: + *interface_mode = PHY_PSGMII_BX1000; + break; + case MALIBU_PHY_PSGMII_FX100: + *interface_mode = PHY_PSGMII_FX100; + break; + case MALIBU_PHY_PSGMII_AMDET: + if (copper_mode) { + *interface_mode = PHY_PSGMII_AMDET; + } else { + if (phy_id == first_phy_addr + MALIBU_PHY_MAX_ADDR_INC) + *interface_mode = PHY_PSGMII_FIBER; + else + *interface_mode = PHY_PSGMII_AMDET; + } + break; + case MALIBU_PHY_SGMII_BASET: + if (phy_id == first_phy_addr + MALIBU_PHY_MAX_ADDR_INC) + *interface_mode = PHY_SGMII_BASET; + else + *interface_mode = PORT_QSGMII; + break; + default: + *interface_mode = PORT_INTERFACE_MODE_MAX; + break; + } + + return SW_OK; +} + +/****************************************************************************** +* +* malibu_phy_interface mode status get +* +* get malibu phy interface mode status +*/ +sw_error_t +malibu_phy_interface_get_mode_status(a_uint32_t dev_id, a_uint32_t phy_id, fal_port_interface_mode_t *interface_mode_status) +{ + a_uint16_t phy_data; + a_uint16_t copper_mode; + + if ((phy_id < first_phy_addr) || + (phy_id > (first_phy_addr + MALIBU_PHY_MAX_ADDR_INC))) { + return SW_NOT_SUPPORTED; + } + + phy_data = malibu_phy_reg_read(dev_id, + first_phy_addr + MALIBU_PHY_MAX_ADDR_INC, MALIBU_PHY_CHIP_CONFIG); + copper_mode = ((phy_data & MALIBU_PHY_COPPER_MODE) >> 0xf); + phy_data &= 0x00f0; + phy_data = (phy_data >>4); + + switch (phy_data) { + case MALIBU_PHY_PSGMII_BASET: + *interface_mode_status = PHY_PSGMII_BASET; + break; + case MALIBU_PHY_PSGMII_BX1000: + *interface_mode_status = PHY_PSGMII_BX1000; + break; + case MALIBU_PHY_PSGMII_FX100: + *interface_mode_status = PHY_PSGMII_FX100; + break; + case MALIBU_PHY_PSGMII_AMDET: + if (copper_mode) { + *interface_mode_status = PHY_PSGMII_BASET; + } else { + if (phy_id == first_phy_addr + MALIBU_PHY_MAX_ADDR_INC) + *interface_mode_status = PHY_PSGMII_FIBER; + else + *interface_mode_status = PHY_PSGMII_BASET; + } + break; + case MALIBU_PHY_SGMII_BASET: + if (phy_id == first_phy_addr + MALIBU_PHY_MAX_ADDR_INC) + *interface_mode_status = PHY_SGMII_BASET; + else + *interface_mode_status = PORT_QSGMII; + break; + default: + *interface_mode_status = PORT_INTERFACE_MODE_MAX; + break; + } + + return SW_OK; +} +#ifndef IN_PORTCONTROL_MINI +/****************************************************************************** +* +* malibu_phy_intr_mask_set - Set interrupt mask with the +* specified device. +*/ +sw_error_t +malibu_phy_intr_mask_set(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t intr_mask_flag) +{ + a_uint16_t phy_data = 0; + + phy_data = malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_INTR_MASK); + + if (FAL_PHY_INTR_STATUS_UP_CHANGE & intr_mask_flag) { + phy_data |= MALIBU_INTR_STATUS_UP_CHANGE; + } else { + phy_data &= (~MALIBU_INTR_STATUS_UP_CHANGE); + } + + if (FAL_PHY_INTR_STATUS_DOWN_CHANGE & intr_mask_flag) { + phy_data |= MALIBU_INTR_STATUS_DOWN_CHANGE; + } else { + phy_data &= (~MALIBU_INTR_STATUS_DOWN_CHANGE); + } + + if (FAL_PHY_INTR_SPEED_CHANGE & intr_mask_flag) { + phy_data |= MALIBU_INTR_SPEED_CHANGE; + } else { + phy_data &= (~MALIBU_INTR_SPEED_CHANGE); + } + + if (FAL_PHY_INTR_DUPLEX_CHANGE & intr_mask_flag) { + phy_data |= MALIBU_INTR_DUPLEX_CHANGE; + } else { + phy_data &= (~MALIBU_INTR_DUPLEX_CHANGE); + } + + if (FAL_PHY_INTR_BX_FX_STATUS_UP_CHANGE & intr_mask_flag) { + phy_data |= MALIBU_INTR_BX_FX_STATUS_UP_CHANGE; + } else { + phy_data &= (~MALIBU_INTR_BX_FX_STATUS_UP_CHANGE); + } + + if (FAL_PHY_INTR_BX_FX_STATUS_DOWN_CHANGE & intr_mask_flag) { + phy_data |= MALIBU_INTR_BX_FX_STATUS_DOWN_CHANGE; + } else { + phy_data &= (~MALIBU_INTR_BX_FX_STATUS_DOWN_CHANGE); + } + + if (FAL_PHY_INTR_MEDIA_STATUS_CHANGE & intr_mask_flag) { + phy_data |= MALIBU_INTR_MEDIA_STATUS_CHANGE; + } else { + phy_data &= (~MALIBU_INTR_MEDIA_STATUS_CHANGE); + } + + if (FAL_PHY_INTR_WOL_STATUS & intr_mask_flag) { + phy_data |= MALIBU_INTR_WOL; + } else { + phy_data &= (~MALIBU_INTR_WOL); + } + + if (FAL_PHY_INTR_POE_STATUS & intr_mask_flag) { + phy_data |= MALIBU_INTR_POE; + } else { + phy_data &= (~MALIBU_INTR_POE); + } + + malibu_phy_reg_write(dev_id, phy_id, MALIBU_PHY_INTR_MASK, phy_data); + return SW_OK; +} + +/****************************************************************************** +* +* malibu_phy_intr_mask_get - Get interrupt mask with the +* specified device. +*/ +sw_error_t +malibu_phy_intr_mask_get(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * intr_mask_flag) +{ + a_uint16_t phy_data = 0; + + phy_data = malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_INTR_MASK); + + *intr_mask_flag = 0; + if (MALIBU_INTR_STATUS_UP_CHANGE & phy_data) { + *intr_mask_flag |= FAL_PHY_INTR_STATUS_UP_CHANGE; + } + + if (MALIBU_INTR_STATUS_DOWN_CHANGE & phy_data) { + *intr_mask_flag |= FAL_PHY_INTR_STATUS_DOWN_CHANGE; + } + + if (MALIBU_INTR_SPEED_CHANGE & phy_data) { + *intr_mask_flag |= FAL_PHY_INTR_SPEED_CHANGE; + } + + if (MALIBU_INTR_DUPLEX_CHANGE & phy_data) { + *intr_mask_flag |= FAL_PHY_INTR_DUPLEX_CHANGE; + } + + if (MALIBU_INTR_BX_FX_STATUS_UP_CHANGE & phy_data) { + *intr_mask_flag |= FAL_PHY_INTR_BX_FX_STATUS_UP_CHANGE; + } + + if (MALIBU_INTR_BX_FX_STATUS_DOWN_CHANGE & phy_data) { + *intr_mask_flag |= FAL_PHY_INTR_BX_FX_STATUS_DOWN_CHANGE; + } + + if (MALIBU_INTR_MEDIA_STATUS_CHANGE & phy_data) { + *intr_mask_flag |= FAL_PHY_INTR_MEDIA_STATUS_CHANGE; + } + + if (MALIBU_INTR_WOL & phy_data) { + *intr_mask_flag |= FAL_PHY_INTR_WOL_STATUS; + } + + if (MALIBU_INTR_POE & phy_data) { + *intr_mask_flag |= FAL_PHY_INTR_POE_STATUS; + } + + return SW_OK; +} + +/****************************************************************************** +* +* malibu_phy_intr_status_get - Get interrupt status with the +* specified device. +*/ +sw_error_t +malibu_phy_intr_status_get(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * intr_status_flag) +{ + a_uint16_t phy_data = 0; + + phy_data = malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_INTR_STATUS); + + *intr_status_flag = 0; + if (MALIBU_INTR_STATUS_UP_CHANGE & phy_data) { + *intr_status_flag |= FAL_PHY_INTR_STATUS_UP_CHANGE; + } + + if (MALIBU_INTR_STATUS_DOWN_CHANGE & phy_data) { + *intr_status_flag |= FAL_PHY_INTR_STATUS_DOWN_CHANGE; + } + + if (MALIBU_INTR_SPEED_CHANGE & phy_data) { + *intr_status_flag |= FAL_PHY_INTR_SPEED_CHANGE; + } + + if (MALIBU_INTR_DUPLEX_CHANGE & phy_data) { + *intr_status_flag |= FAL_PHY_INTR_DUPLEX_CHANGE; + } + + if (MALIBU_INTR_BX_FX_STATUS_UP_CHANGE & phy_data) { + *intr_status_flag |= FAL_PHY_INTR_BX_FX_STATUS_UP_CHANGE; + } + + if (MALIBU_INTR_BX_FX_STATUS_DOWN_CHANGE & phy_data) { + *intr_status_flag |= FAL_PHY_INTR_BX_FX_STATUS_DOWN_CHANGE; + } + if (MALIBU_INTR_MEDIA_STATUS_CHANGE & phy_data) { + *intr_status_flag |= FAL_PHY_INTR_MEDIA_STATUS_CHANGE; + } + + if (MALIBU_INTR_WOL & phy_data) { + *intr_status_flag |= FAL_PHY_INTR_WOL_STATUS; + } + + if (MALIBU_INTR_POE & phy_data) { + *intr_status_flag |= FAL_PHY_INTR_POE_STATUS; + } + + return SW_OK; +} + +/****************************************************************************** +* +* malibu_phy_set_counter - set counter status +* +* set counter status +*/ +sw_error_t +malibu_phy_set_counter(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable) +{ + a_uint16_t phy_data; + + phy_data = malibu_phy_mmd_read(dev_id, phy_id, MALIBU_PHY_MMD7_NUM, + MALIBU_PHY_MMD7_COUNTER_CTRL); + + if (enable == A_TRUE) { + phy_data |= 0x0003; + } else { + phy_data &= ~0x0003; + } + + malibu_phy_mmd_write(dev_id, phy_id, MALIBU_PHY_MMD7_NUM, + MALIBU_PHY_MMD7_COUNTER_CTRL, phy_data); + + return SW_OK; +} + +/****************************************************************************** +* +* malibu_phy_get_counter_status - get counter status +* +* set counter status +*/ +sw_error_t +malibu_phy_get_counter(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t * enable) +{ + a_uint16_t phy_data; + + *enable = A_FALSE; + + phy_data = malibu_phy_mmd_read(dev_id, phy_id, MALIBU_PHY_MMD7_NUM, + MALIBU_PHY_MMD7_COUNTER_CTRL); + + if (phy_data & 0x0001) + *enable = A_TRUE; + + return SW_OK; +} + +/****************************************************************************** +* +* malibu_phy_show show counter statistics +* +* show counter statistics +*/ +sw_error_t +malibu_phy_show_counter(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_counter_info_t * counter_infor) +{ + a_uint16_t ingress_high_counter; + a_uint16_t ingress_low_counter; + a_uint16_t egress_high_counter; + a_uint16_t egress_low_counter; + + ingress_high_counter = malibu_phy_mmd_read(dev_id, phy_id, MALIBU_PHY_MMD7_NUM, + MALIBU_PHY_MMD7_INGRESS_COUNTER_HIGH); + ingress_low_counter = malibu_phy_mmd_read(dev_id, phy_id, MALIBU_PHY_MMD7_NUM, + MALIBU_PHY_MMD7_INGRESS_COUNTER_LOW); + counter_infor->RxGoodFrame = (ingress_high_counter << 16 ) | ingress_low_counter; + counter_infor->RxBadCRC = malibu_phy_mmd_read(dev_id, phy_id, MALIBU_PHY_MMD7_NUM, + MALIBU_PHY_MMD7_INGRESS_ERROR_COUNTER); + + egress_high_counter = malibu_phy_mmd_read(dev_id, phy_id, MALIBU_PHY_MMD7_NUM, + MALIBU_PHY_MMD7_EGRESS_COUNTER_HIGH); + egress_low_counter = malibu_phy_mmd_read(dev_id, phy_id, MALIBU_PHY_MMD7_NUM, + MALIBU_PHY_MMD7_EGRESS_COUNTER_LOW); + counter_infor->TxGoodFrame = (egress_high_counter << 16 ) | egress_low_counter; + counter_infor->TxBadCRC = malibu_phy_mmd_read(dev_id, phy_id, MALIBU_PHY_MMD7_NUM, + MALIBU_PHY_MMD7_EGRESS_ERROR_COUNTER); + + return SW_OK; +} +#endif +/****************************************************************************** +* +* malibu_phy_get status +* +* get phy status +*/ +sw_error_t +malibu_phy_get_status(a_uint32_t dev_id, a_uint32_t phy_id, + struct port_phy_status *phy_status) +{ + a_uint16_t phy_data; + + if (phy_id == COMBO_PHY_ID) { + __phy_reg_pages_sel_by_active_medium(dev_id, phy_id); + } + + phy_data = malibu_phy_reg_read(dev_id, phy_id, MALIBU_PHY_SPEC_STATUS); + + /*get phy link status*/ + if (phy_data & MALIBU_STATUS_LINK_PASS) { + phy_status->link_status = A_TRUE; + } else { + phy_status->link_status = A_FALSE; + return SW_OK; + } + + /*get phy speed*/ + switch (phy_data & MALIBU_STATUS_SPEED_MASK) { + case MALIBU_STATUS_SPEED_1000MBS: + phy_status->speed = FAL_SPEED_1000; + break; + case MALIBU_STATUS_SPEED_100MBS: + phy_status->speed = FAL_SPEED_100; + break; + case MALIBU_STATUS_SPEED_10MBS: + phy_status->speed = FAL_SPEED_10; + break; + default: + return SW_READ_ERROR; + } + + /*get phy duplex*/ + if (phy_data & MALIBU_STATUS_FULL_DUPLEX) { + phy_status->duplex = FAL_FULL_DUPLEX; + } else { + phy_status->duplex = FAL_HALF_DUPLEX; + } + + /* get phy flowctrl resolution status */ + if (phy_data & MALIBU_PHY_RX_FLOWCTRL_STATUS) { + phy_status->rx_flowctrl = A_TRUE; + } else { + phy_status->rx_flowctrl = A_FALSE; + } + + if (phy_data & MALIBU_PHY_TX_FLOWCTRL_STATUS) { + phy_status->tx_flowctrl = A_TRUE; + } else { + phy_status->tx_flowctrl = A_FALSE; + } + + return SW_OK; +} +/****************************************************************************** +* +* malibu_phy_set_eee_advertisement +* +* set eee advertisement +*/ +sw_error_t +malibu_phy_set_eee_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t adv) +{ + a_uint16_t phy_data = 0; + sw_error_t rv = SW_OK; + + if (phy_id == COMBO_PHY_ID) { + if (MALIBU_PHY_MEDIUM_COPPER != + __phy_active_medium_get(dev_id, phy_id)) + return SW_NOT_SUPPORTED; + } + + phy_data = malibu_phy_mmd_read(dev_id, phy_id, MALIBU_PHY_MMD7_NUM, + MALIBU_PHY_MMD7_ADDR_8023AZ_EEE_CTRL); + phy_data &= ~(MALIBU_PHY_EEE_ADV_100M | MALIBU_PHY_EEE_ADV_1000M); + + if (adv & FAL_PHY_EEE_100BASE_T) { + phy_data |= MALIBU_PHY_EEE_ADV_100M; + } + if (adv & FAL_PHY_EEE_1000BASE_T) { + phy_data |= MALIBU_PHY_EEE_ADV_1000M; + } + + rv = malibu_phy_mmd_write(dev_id, phy_id, MALIBU_PHY_MMD7_NUM, + MALIBU_PHY_MMD7_ADDR_8023AZ_EEE_CTRL, phy_data); + + rv = malibu_phy_restart_autoneg(dev_id, phy_id); + + return rv; + +} + +/****************************************************************************** +* +* malibu_phy_get_eee_advertisement +* +* get eee advertisement +*/ +sw_error_t +malibu_phy_get_eee_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *adv) +{ + a_uint16_t phy_data = 0; + sw_error_t rv = SW_OK; + + if (phy_id == COMBO_PHY_ID) { + if (MALIBU_PHY_MEDIUM_COPPER != + __phy_active_medium_get(dev_id, phy_id)) + return SW_NOT_SUPPORTED; + } + + *adv = 0; + phy_data = malibu_phy_mmd_read(dev_id, phy_id, MALIBU_PHY_MMD7_NUM, + MALIBU_PHY_MMD7_ADDR_8023AZ_EEE_CTRL); + + if (phy_data & MALIBU_PHY_EEE_ADV_100M) { + *adv |= FAL_PHY_EEE_100BASE_T; + } + if (phy_data & MALIBU_PHY_EEE_ADV_1000M) { + *adv |= FAL_PHY_EEE_1000BASE_T; + } + + return rv; +} +/****************************************************************************** +* +* malibu_phy_get_eee_partner_advertisement +* +* get eee partner advertisement +*/ +sw_error_t +malibu_phy_get_eee_partner_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *adv) +{ + a_uint16_t phy_data = 0; + sw_error_t rv = SW_OK; + + if (phy_id == COMBO_PHY_ID) { + if (MALIBU_PHY_MEDIUM_COPPER != + __phy_active_medium_get(dev_id, phy_id)) + return SW_NOT_SUPPORTED; + } + + *adv = 0; + phy_data = malibu_phy_mmd_read(dev_id, phy_id, MALIBU_PHY_MMD7_NUM, + MALIBU_PHY_MMD7_ADDR_8023AZ_EEE_PARTNER); + + if (phy_data & MALIBU_PHY_EEE_PARTNER_ADV_100M) { + *adv |= FAL_PHY_EEE_100BASE_T; + } + if (phy_data & MALIBU_PHY_EEE_PARTNER_ADV_1000M) { + *adv |= FAL_PHY_EEE_1000BASE_T; + } + + return rv; +} +/****************************************************************************** +* +* malibu_phy_get_eee_capability +* +* get eee capability +*/ +sw_error_t +malibu_phy_get_eee_cap(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *cap) +{ + a_uint16_t phy_data = 0; + sw_error_t rv = SW_OK; + + if (phy_id == COMBO_PHY_ID) { + if (MALIBU_PHY_MEDIUM_COPPER != + __phy_active_medium_get(dev_id, phy_id)) + return SW_NOT_SUPPORTED; + } + + *cap = 0; + phy_data = malibu_phy_mmd_read(dev_id, phy_id, MALIBU_PHY_MMD3_NUM, + MALIBU_PHY_MMD3_ADDR_8023AZ_EEE_CAPABILITY); + + if (phy_data & MALIBU_PHY_EEE_CAPABILITY_100M) { + *cap |= FAL_PHY_EEE_100BASE_T; + } + if (phy_data & MALIBU_PHY_EEE_CAPABILITY_1000M) { + *cap |= FAL_PHY_EEE_1000BASE_T; + } + + return rv; +} +/****************************************************************************** +* +* malibu_phy_get_eee_status +* +* get eee status +*/ +sw_error_t +malibu_phy_get_eee_status(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *status) +{ + a_uint16_t phy_data = 0; + sw_error_t rv = SW_OK; + + if (phy_id == COMBO_PHY_ID) { + if (MALIBU_PHY_MEDIUM_COPPER != + __phy_active_medium_get(dev_id, phy_id)) + return SW_NOT_SUPPORTED; + } + + *status = 0; + phy_data = malibu_phy_mmd_read(dev_id, phy_id, MALIBU_PHY_MMD7_NUM, + MALIBU_PHY_MMD7_ADDR_8023AZ_EEE_STATUS); + + if (phy_data & MALIBU_PHY_EEE_STATUS_100M) { + *status |= FAL_PHY_EEE_100BASE_T; + } + if (phy_data & MALIBU_PHY_EEE_STATUS_1000M) { + *status |= FAL_PHY_EEE_1000BASE_T; + } + + return rv; +} +/****************************************************************************** +* +* malibu_phy_hw_register init +* +*/ +sw_error_t +malibu_phy_hw_init(a_uint32_t dev_id, a_uint32_t port_bmp) +{ + a_uint32_t port_id = 0, phy_addr = 0, phy_cnt = 0; + a_uint16_t dac_value,led_status, phy_data; + a_uint32_t mode; + + for (port_id = 0; port_id < SW_MAX_NR_PORT; port_id ++) + { + if (port_bmp & (0x1 << port_id)) + { + phy_cnt ++; + phy_addr = qca_ssdk_port_to_phy_addr(dev_id, port_id); + if (phy_addr < first_phy_addr) + { + first_phy_addr = phy_addr; + } + /*enable phy power saving function by default */ + malibu_phy_set_8023az(dev_id, phy_addr, A_TRUE); + malibu_phy_set_powersave(dev_id, phy_addr, A_TRUE); + malibu_phy_set_hibernate(dev_id, phy_addr, A_TRUE); + /*change malibu control_dac[2:0] of MMD7 0x801A bit[9:7] from 111 to 101*/ + dac_value = malibu_phy_mmd_read(dev_id, phy_addr, MALIBU_PHY_MMD7_NUM, + MALIBU_PHY_MMD7_DAC_CTRL); + dac_value &= ~MALIBU_DAC_CTRL_MASK; + dac_value |= MALIBU_DAC_CTRL_VALUE; + malibu_phy_mmd_write(dev_id, phy_addr, MALIBU_PHY_MMD7_NUM, + MALIBU_PHY_MMD7_DAC_CTRL, dac_value); + + /* add 10M and 100M link LED behavior for QFN board*/ + led_status = malibu_phy_mmd_read(dev_id, phy_addr, MALIBU_PHY_MMD7_NUM, + MALIBU_PHY_MMD7_LED_1000_CTRL1); + led_status &= ~MALIBU_LED_1000_CTRL1_100_10_MASK; + led_status |= MALIBU_LED_1000_CTRL1_100_10_MASK; + malibu_phy_mmd_write(dev_id, phy_addr, MALIBU_PHY_MMD7_NUM, + MALIBU_PHY_MMD7_LED_1000_CTRL1, led_status); + } + } + /* qca 8072 two ports phy chip's firstly address to init phy chip */ + if ((phy_cnt == QCA8072_PHY_NUM) && (first_phy_addr >= 0x3)) { + first_phy_addr = first_phy_addr - 0x3; + } + + /*workaround to enable AZ transmitting ability*/ + malibu_phy_mmd_write(dev_id, first_phy_addr + 5, MALIBU_PHY_MMD1_NUM, + MALIBU_PSGMII_MODE_CTRL, MALIBU_PHY_PSGMII_MODE_CTRL_ADJUST_VALUE); + + /* adjust psgmii serdes tx amp */ + malibu_phy_reg_write(dev_id, first_phy_addr + 5, MALIBU_PSGMII_TX_DRIVER_1_CTRL, + MALIBU_PHY_PSGMII_REDUCE_SERDES_TX_AMP); + + /* to avoid psgmii module goes into hibernation, work with psgmii self test*/ + phy_data = malibu_phy_mmd_read(dev_id, first_phy_addr + 4, MALIBU_PHY_MMD3_NUM, + MALIBU_PHY_MMD3_ADDR_REMOTE_LOOPBACK_CTRL); + phy_data &= (~(1<<1)); + malibu_phy_mmd_write(dev_id, first_phy_addr + 4, MALIBU_PHY_MMD3_NUM, + MALIBU_PHY_MMD3_ADDR_REMOTE_LOOPBACK_CTRL, phy_data); + + + mode = ssdk_dt_global_get_mac_mode(dev_id, 0); + if (mode == PORT_WRAPPER_PSGMII_FIBER) + malibu_phy_interface_set_mode(dev_id, first_phy_addr, PHY_PSGMII_FIBER); + return SW_OK; +} + +static int malibu_phy_api_ops_init(void) +{ + + int ret; + hsl_phy_ops_t *malibu_phy_api_ops = NULL; + + malibu_phy_api_ops = kzalloc(sizeof(hsl_phy_ops_t), GFP_KERNEL); + if (malibu_phy_api_ops == NULL) { + SSDK_ERROR("malibu phy ops kzalloc failed!\n"); + return -ENOMEM; + } + + phy_api_ops_init(MALIBU_PHY_CHIP); +#ifndef IN_PORTCONTROL_MINI + malibu_phy_api_ops->phy_hibernation_set = malibu_phy_set_hibernate; + malibu_phy_api_ops->phy_hibernation_get = malibu_phy_get_hibernate; +#endif + malibu_phy_api_ops->phy_speed_get = malibu_phy_get_speed; + malibu_phy_api_ops->phy_speed_set = malibu_phy_set_speed; + malibu_phy_api_ops->phy_duplex_get = malibu_phy_get_duplex; + malibu_phy_api_ops->phy_duplex_set = malibu_phy_set_duplex; + malibu_phy_api_ops->phy_autoneg_enable_set = malibu_phy_enable_autoneg; + malibu_phy_api_ops->phy_restart_autoneg = malibu_phy_restart_autoneg; + malibu_phy_api_ops->phy_autoneg_status_get = malibu_phy_autoneg_status; + malibu_phy_api_ops->phy_autoneg_adv_set = malibu_phy_set_autoneg_adv; + malibu_phy_api_ops->phy_autoneg_adv_get = malibu_phy_get_autoneg_adv; +#ifndef IN_PORTCONTROL_MINI + malibu_phy_api_ops->phy_powersave_set = malibu_phy_set_powersave; + malibu_phy_api_ops->phy_powersave_get = malibu_phy_get_powersave; + malibu_phy_api_ops->phy_cdt = malibu_phy_cdt; +#endif + malibu_phy_api_ops->phy_link_status_get = malibu_phy_get_link_status; +#ifndef IN_PORTCONTROL_MINI + malibu_phy_api_ops->phy_mdix_set = malibu_phy_set_mdix; + malibu_phy_api_ops->phy_mdix_get = malibu_phy_get_mdix; + malibu_phy_api_ops->phy_mdix_status_get = malibu_phy_get_mdix_status; + malibu_phy_api_ops->phy_8023az_set = malibu_phy_set_8023az; + malibu_phy_api_ops->phy_8023az_get = malibu_phy_get_8023az; + malibu_phy_api_ops->phy_local_loopback_set = malibu_phy_set_local_loopback; + malibu_phy_api_ops->phy_local_loopback_get = malibu_phy_get_local_loopback; + malibu_phy_api_ops->phy_remote_loopback_set = malibu_phy_set_remote_loopback; + malibu_phy_api_ops->phy_remote_loopback_get = malibu_phy_get_remote_loopback; + malibu_phy_api_ops->phy_combo_prefer_medium_set = malibu_phy_set_combo_prefer_medium; + malibu_phy_api_ops->phy_combo_prefer_medium_get = malibu_phy_get_combo_prefer_medium; + malibu_phy_api_ops->phy_combo_medium_status_get = malibu_phy_get_combo_current_medium_type; + malibu_phy_api_ops->phy_combo_fiber_mode_set = malibu_phy_set_combo_fiber_mode; + malibu_phy_api_ops->phy_combo_fiber_mode_get = malibu_phy_get_combo_fiber_mode; + malibu_phy_api_ops->phy_reset = malibu_phy_reset; +#endif + malibu_phy_api_ops->phy_power_off = malibu_phy_poweroff; + malibu_phy_api_ops->phy_power_on = malibu_phy_poweron; + malibu_phy_api_ops->phy_id_get = malibu_phy_get_phy_id; + malibu_phy_api_ops->phy_reg_write = malibu_phy_reg_write; + malibu_phy_api_ops->phy_reg_read = malibu_phy_reg_read; + malibu_phy_api_ops->phy_debug_write = malibu_phy_debug_write; + malibu_phy_api_ops->phy_debug_read = malibu_phy_debug_read; + malibu_phy_api_ops->phy_mmd_write = malibu_phy_mmd_write; + malibu_phy_api_ops->phy_mmd_read = malibu_phy_mmd_read; +#ifndef IN_PORTCONTROL_MINI + malibu_phy_api_ops->phy_magic_frame_mac_set = malibu_phy_set_magic_frame_mac; + malibu_phy_api_ops->phy_magic_frame_mac_get = malibu_phy_get_magic_frame_mac; + malibu_phy_api_ops->phy_wol_status_set = malibu_phy_set_wol_status; + malibu_phy_api_ops->phy_wol_status_get = malibu_phy_get_wol_status; +#endif + malibu_phy_api_ops->phy_interface_mode_set = malibu_phy_interface_set_mode; + malibu_phy_api_ops->phy_interface_mode_get = malibu_phy_interface_get_mode; + malibu_phy_api_ops->phy_interface_mode_status_get = malibu_phy_interface_get_mode_status; +#ifndef IN_PORTCONTROL_MINI + malibu_phy_api_ops->phy_intr_mask_set = malibu_phy_intr_mask_set; + malibu_phy_api_ops->phy_intr_mask_get = malibu_phy_intr_mask_get; + malibu_phy_api_ops->phy_intr_status_get = malibu_phy_intr_status_get; + malibu_phy_api_ops->phy_counter_set = malibu_phy_set_counter; + malibu_phy_api_ops->phy_counter_get = malibu_phy_get_counter; + malibu_phy_api_ops->phy_counter_show = malibu_phy_show_counter; +#endif + malibu_phy_api_ops->phy_serdes_reset = malibu_phy_serdes_reset; + malibu_phy_api_ops->phy_get_status = malibu_phy_get_status; + malibu_phy_api_ops->phy_eee_adv_set = malibu_phy_set_eee_adv; + malibu_phy_api_ops->phy_eee_adv_get = malibu_phy_get_eee_adv; + malibu_phy_api_ops->phy_eee_partner_adv_get = malibu_phy_get_eee_partner_adv; + malibu_phy_api_ops->phy_eee_cap_get = malibu_phy_get_eee_cap; + malibu_phy_api_ops->phy_eee_status_get = malibu_phy_get_eee_status; + + ret = hsl_phy_api_ops_register(MALIBU_PHY_CHIP, malibu_phy_api_ops); + + if (ret == 0) + SSDK_INFO("qca probe malibu phy driver succeeded!\n"); + else + SSDK_ERROR("qca probe malibu phy driver failed! (code: %d)\n", ret); + return ret; +} + +/****************************************************************************** +* +* malibu_phy_init - +* +*/ +int malibu_phy_init(a_uint32_t dev_id, a_uint32_t port_bmp) +{ + static a_uint32_t phy_ops_flag = 0; + + if(phy_ops_flag == 0) { + malibu_phy_api_ops_init(); + phy_ops_flag = 1; + } + malibu_phy_hw_init(dev_id, port_bmp); + + return 0; +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/mpge_led.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/mpge_led.c new file mode 100644 index 000000000..31f47f709 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/mpge_led.c @@ -0,0 +1,66 @@ +/* + * 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 "sw.h" +#include "hsl_phy.h" +#include "qca808x_led.h" + +/****************************************************************************** +* +* mpge_phy_led_ctrl_pattern_set - set led behavior +* +*/ +sw_error_t +mpge_phy_led_ctrl_pattern_set(a_uint32_t dev_id, a_uint32_t phy_id, + led_ctrl_pattern_t *pattern) +{ + return qca808x_phy_led_ctrl_pattern_set(dev_id, phy_id, pattern); +} + +/****************************************************************************** +* +* mpge_phy_led_ctrl_pattern_get - get led behavior +* +*/ +sw_error_t +mpge_phy_led_ctrl_pattern_get(a_uint32_t dev_id, a_uint32_t phy_id, + led_ctrl_pattern_t * pattern) +{ + return qca808x_phy_led_ctrl_pattern_get(dev_id, phy_id, pattern); +} +/****************************************************************************** +* +* mpge_phy_led_source_pattern_set - set led behavior based on source id +* +*/ +sw_error_t +mpge_phy_led_ctrl_source_set(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t source_id, led_ctrl_pattern_t * pattern) +{ + return qca808x_phy_led_ctrl_source_set(dev_id, phy_id, source_id, pattern); +} + +void mpge_phy_led_api_ops_init(hsl_phy_ops_t *mpge_phy_led_api_ops) +{ + if (!mpge_phy_led_api_ops) { + return; + } + mpge_phy_led_api_ops->phy_led_ctrl_pattern_get = mpge_phy_led_ctrl_pattern_get; + mpge_phy_led_api_ops->phy_led_ctrl_pattern_set = mpge_phy_led_ctrl_pattern_set; + mpge_phy_led_api_ops->phy_led_ctrl_source_set = mpge_phy_led_ctrl_source_set; + + return; +} diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/mpge_phy.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/mpge_phy.c new file mode 100644 index 000000000..970c3331b --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/mpge_phy.c @@ -0,0 +1,1090 @@ +/* + * 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 "sw.h" +#include "fal_port_ctrl.h" +#include "hsl_api.h" +#include "hsl.h" +#include "hsl_phy.h" +#include "ssdk_plat.h" +#include "qca808x_phy.h" +#include "mpge_phy.h" +#ifdef IN_LED +#include "mpge_led.h" +#endif + +#define PHY_DAC(val) (val<<8) + +/****************************************************************************** +* +* mpge_phy_mii_read - mii register read +* +*/ +static a_uint16_t +mpge_phy_reg_read (a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t reg_id) +{ + return qca808x_phy_reg_read (dev_id, phy_id, reg_id); +} + +/****************************************************************************** +* +* mpge_phy_mii_write - mii register write +* +*/ +static sw_error_t +mpge_phy_reg_write (a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t reg_id, + a_uint16_t reg_val) +{ + return qca808x_phy_reg_write (dev_id, phy_id, reg_id, reg_val); +} + +/****************************************************************************** +* +* mpge_phy_debug_read - debug port read +* +*/ +static a_uint16_t +mpge_phy_debug_read(a_uint32_t dev_id, a_uint32_t phy_id, a_uint16_t reg_id) +{ + return qca808x_phy_debug_read(dev_id, phy_id, reg_id); +} + +/****************************************************************************** +* +* mpge_phy_debug_write - debug port write +* +*/ +static sw_error_t +mpge_phy_debug_write(a_uint32_t dev_id, a_uint32_t phy_id, a_uint16_t reg_id, + a_uint16_t reg_val) +{ + return qca808x_phy_debug_write (dev_id, phy_id, reg_id, reg_val); +} + +/****************************************************************************** +* +* mpge_phy_mmd_read - PHY MMD register read +* +*/ +static a_uint16_t +mpge_phy_mmd_read(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint16_t mmd_num, a_uint16_t reg_id) +{ + return qca808x_phy_mmd_read(dev_id, phy_id, mmd_num, reg_id); +} + +/****************************************************************************** +* +* mpge_phy_mmd_write - PHY MMD register write +* +*/ +static sw_error_t +mpge_phy_mmd_write(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint16_t mmd_num, a_uint16_t reg_id, a_uint16_t reg_val) +{ + return qca808x_phy_mmd_write (dev_id, phy_id, mmd_num, + reg_id, reg_val); +} + +/****************************************************************************** +* +* mpge_phy_get_status - get the phy status +* +*/ +static sw_error_t +mpge_phy_get_status(a_uint32_t dev_id, a_uint32_t phy_id, + struct port_phy_status *phy_status) +{ + return qca808x_phy_get_status(dev_id, phy_id, phy_status); +} + +/****************************************************************************** +* +* mpge_set_autoneg_adv - set the phy autoneg Advertisement +* +*/ +static sw_error_t +mpge_phy_set_autoneg_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t autoneg) +{ + if (autoneg & (~FAL_PHY_GE_ADV_ALL)) + { + SSDK_ERROR("autoneg adv caps 0x%x is not support for MP\n", autoneg); + return SW_BAD_PARAM; + } + return qca808x_phy_set_autoneg_adv(dev_id, phy_id, autoneg); +} + +/****************************************************************************** +* +* mpge_get_autoneg_adv - get the phy autoneg Advertisement +* +*/ +static sw_error_t +mpge_phy_get_autoneg_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * autoneg) +{ + return qca808x_phy_get_autoneg_adv(dev_id, phy_id, autoneg); +} + +/****************************************************************************** +* +* mpge_phy_get_speed - Determines the speed of phy ports associated with the +* specified device. +*/ + +static sw_error_t +mpge_phy_get_speed(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_speed_t * speed) +{ + return qca808x_phy_get_speed(dev_id, phy_id, speed); +} + +/****************************************************************************** +* +* mpge_phy_get_duplex - Determines the duplex of phy ports associated with the +* specified device. +*/ +static sw_error_t +mpge_phy_get_duplex(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_duplex_t * duplex) +{ + return qca808x_phy_get_duplex(dev_id, phy_id, duplex); +} + +/****************************************************************************** +* +* mpge_phy_set_speed - Set the speed of phy ports associated with the +* specified device. +*/ +static sw_error_t +mpge_phy_set_speed(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_speed_t speed) +{ + a_uint16_t phy_data = 0; + a_uint32_t autoneg = 0; + fal_port_duplex_t old_duplex = MPGE_CTRL_FULL_DUPLEX; + sw_error_t rv = SW_OK; + + phy_data = mpge_phy_reg_read(dev_id, phy_id, MPGE_PHY_CONTROL); + PHY_RTN_ON_READ_ERROR(phy_data); + + switch(speed) + { + case FAL_SPEED_1000: + rv = mpge_phy_get_autoneg_adv(dev_id, phy_id, &autoneg); + PHY_RTN_ON_ERROR(rv); + if (!(autoneg & FAL_PHY_ADV_1000T_FD)) { + rv = mpge_phy_set_autoneg_adv(dev_id, phy_id, + autoneg | FAL_PHY_ADV_1000T_FD); + PHY_RTN_ON_ERROR(rv); + } + phy_data |= MPGE_CTRL_FULL_DUPLEX; + phy_data |= MPGE_CTRL_AUTONEGOTIATION_ENABLE; + phy_data |= MPGE_CTRL_RESTART_AUTONEGOTIATION; + break; + case FAL_SPEED_100: + case FAL_SPEED_10: + phy_data &= ~MPGE_CONTROL_SPEED_MASK; + if (speed == FAL_SPEED_100) { + phy_data |= MPGE_CONTROL_100M; + } else { + phy_data |= MPGE_CONTROL_10M; + } + rv = mpge_phy_get_duplex(dev_id, phy_id, &old_duplex); + PHY_RTN_ON_ERROR(rv); + + if (old_duplex == FAL_FULL_DUPLEX) { + phy_data |= MPGE_CTRL_FULL_DUPLEX; + } + else if (old_duplex == FAL_HALF_DUPLEX) { + phy_data &= ~MPGE_CTRL_FULL_DUPLEX; + } + phy_data &= ~MPGE_CTRL_AUTONEGOTIATION_ENABLE; + break; + default: + return SW_BAD_PARAM; + } + rv = mpge_phy_reg_write(dev_id, phy_id, MPGE_PHY_CONTROL, phy_data); + + return rv; +} + +/****************************************************************************** +* +* mpge_phy_set_duplex - Set the duplex of phy ports associated with the +* specified device. +*/ +static sw_error_t +mpge_phy_set_duplex(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_duplex_t duplex) +{ + + a_uint16_t phy_data = 0; + a_uint32_t autoneg = 0; + fal_port_speed_t old_speed; + sw_error_t rv = SW_OK; + + phy_data = mpge_phy_reg_read(dev_id, phy_id, MPGE_PHY_CONTROL); + PHY_RTN_ON_READ_ERROR(phy_data); + + rv = mpge_phy_get_speed(dev_id, phy_id, &old_speed); + PHY_RTN_ON_ERROR(rv); + + switch(old_speed) + { + case FAL_SPEED_1000: + if (duplex == FAL_FULL_DUPLEX) { + phy_data |= MPGE_CTRL_FULL_DUPLEX; + } else { + return SW_NOT_SUPPORTED; + } + phy_data |= MPGE_CTRL_AUTONEGOTIATION_ENABLE; + rv = mpge_phy_get_autoneg_adv(dev_id, phy_id, &autoneg); + PHY_RTN_ON_ERROR(rv); + if (!(autoneg & FAL_PHY_ADV_1000T_FD)) { + rv = mpge_phy_set_autoneg_adv(dev_id, phy_id, + autoneg | FAL_PHY_ADV_1000T_FD); + PHY_RTN_ON_ERROR(rv); + } + break; + case FAL_SPEED_100: + case FAL_SPEED_10: + phy_data &= ~MPGE_CONTROL_SPEED_MASK; + if (old_speed == FAL_SPEED_100) { + phy_data |= MPGE_CONTROL_100M; + } else { + phy_data |= MPGE_CONTROL_10M; + } + phy_data &= ~MPGE_CTRL_AUTONEGOTIATION_ENABLE; + if (duplex == FAL_FULL_DUPLEX) { + phy_data |= MPGE_CTRL_FULL_DUPLEX; + } else { + phy_data &= ~MPGE_CTRL_FULL_DUPLEX; + } + break; + default: + return SW_FAIL; + } + rv = mpge_phy_reg_write(dev_id, phy_id, MPGE_PHY_CONTROL, phy_data); + + return rv; +} + +/****************************************************************************** +* +* mpge_phy_enable_autoneg - enable the phy autoneg +* +*/ +static sw_error_t +mpge_phy_enable_autoneg(a_uint32_t dev_id, a_uint32_t phy_id) +{ + return qca808x_phy_enable_autoneg(dev_id, phy_id); +} + +/****************************************************************************** +* +* mpge_restart_autoneg - restart the phy autoneg +* +*/ +static sw_error_t +mpge_phy_restart_autoneg(a_uint32_t dev_id, a_uint32_t phy_id) +{ + return qca808x_phy_restart_autoneg(dev_id, phy_id); +} + +/****************************************************************************** +* +* mpge_phy_autoneg_status - get the phy autoneg status +* +*/ +static a_bool_t +mpge_phy_autoneg_status(a_uint32_t dev_id, a_uint32_t phy_id) +{ + return qca808x_phy_autoneg_status(dev_id, phy_id); +} + +/****************************************************************************** +* +* mpge_phy_status - get the phy link status +* +* RETURNS: +* A_TRUE --> link is alive +* A_FALSE --> link is down +*/ +static a_bool_t +mpge_phy_get_link_status(a_uint32_t dev_id, a_uint32_t phy_id) +{ + return qca808x_phy_get_link_status(dev_id, phy_id); +} + +/****************************************************************************** +* +* mpge_phy_reset - reset the phy +* +*/ +static sw_error_t +mpge_phy_reset(a_uint32_t dev_id, a_uint32_t phy_id) +{ + return qca808x_phy_reset(dev_id, phy_id); +} + + +/****************************************************************************** +* +* mpge_phy_get_phy_id - get the phy id +* +*/ +static sw_error_t +mpge_phy_get_phy_id(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *phy_data) +{ + return qca808x_phy_get_phy_id (dev_id, phy_id, phy_data); +} + +/****************************************************************************** +* +* mpge_phy_off - power off the phy +* +*/ +static sw_error_t +mpge_phy_poweroff(a_uint32_t dev_id, a_uint32_t phy_id) +{ + return qca808x_phy_poweroff (dev_id, phy_id); +} + +/****************************************************************************** +* +* mpge_phy_on - power on the phy +* +*/ +static sw_error_t +mpge_phy_poweron(a_uint32_t dev_id, a_uint32_t phy_id) +{ + return qca808x_phy_poweron (dev_id, phy_id); +} + +#ifndef IN_PORTCONTROL_MINI +/****************************************************************************** +* +* mpge_phy_set_hibernate - set hibernate status +* +*/ +static sw_error_t +mpge_phy_set_hibernate(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable) +{ + return qca808x_phy_set_hibernate (dev_id, phy_id, enable); +} + +/****************************************************************************** +* +* mpge_phy_get_hibernate - get hibernate status +* +*/ +static sw_error_t +mpge_phy_get_hibernate(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t * enable) +{ + return qca808x_phy_get_hibernate (dev_id, phy_id, enable); +} + +/****************************************************************************** +* +* mpge_phy_cdt - cable diagnostic test +* +*/ +static sw_error_t +mpge_phy_cdt(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t mdi_pair, + fal_cable_status_t * cable_status, a_uint32_t * cable_len) +{ + return qca808x_phy_cdt (dev_id, phy_id, mdi_pair, + cable_status, cable_len); +} + +/****************************************************************************** +* +* mpge_phy_set_mdix - set phy mdix configuration +* +*/ +static sw_error_t +mpge_phy_set_mdix(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_mdix_mode_t mode) +{ + return qca808x_phy_set_mdix(dev_id, phy_id, mode); +} + +/****************************************************************************** +* +* mpge_phy_get_mdix - get phy mdix configuration +* +*/ +static sw_error_t +mpge_phy_get_mdix(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_mdix_mode_t * mode) +{ + return qca808x_phy_get_mdix(dev_id, phy_id, mode); +} + +/****************************************************************************** +* +* mpge_phy_get_mdix_status - get phy mdix status +* +*/ +static sw_error_t +mpge_phy_get_mdix_status(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_mdix_status_t * mode) +{ + return qca808x_phy_get_mdix_status(dev_id, phy_id, mode); +} + +/****************************************************************************** +* +* mpge_phy_set_local_loopback +* +*/ +static sw_error_t +mpge_phy_set_local_loopback(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t enable) +{ + a_uint16_t phy_data; + fal_port_speed_t old_speed; + sw_error_t rv = SW_OK; + + if (enable == A_TRUE) + { + mpge_phy_get_speed(dev_id, phy_id, &old_speed); + if (old_speed == FAL_SPEED_1000) + { + phy_data = MPGE_1000M_LOOPBACK; + } + else if (old_speed == FAL_SPEED_100) + { + phy_data = MPGE_100M_LOOPBACK; + } + else if (old_speed == FAL_SPEED_10) + { + phy_data = MPGE_10M_LOOPBACK; + } + else + { + return SW_FAIL; + } + } + else + { + phy_data = MPGE_COMMON_CTRL; + } + + rv = mpge_phy_reg_write(dev_id, phy_id, MPGE_PHY_CONTROL, phy_data); + + return rv; +} + +/****************************************************************************** +* +* mpge_phy_get_local_loopback +* +*/ +static sw_error_t +mpge_phy_get_local_loopback(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t * enable) +{ + return qca808x_phy_get_local_loopback (dev_id, phy_id, enable); +} + +/****************************************************************************** +* +* mpge_phy_set_remote_loopback +* +*/ +static sw_error_t +mpge_phy_set_remote_loopback(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t enable) +{ + return qca808x_phy_set_remote_loopback (dev_id, phy_id, enable); +} + +/****************************************************************************** +* +* mpge_phy_get_remote_loopback +* +*/ +static sw_error_t +mpge_phy_get_remote_loopback(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t * enable) +{ + return qca808x_phy_get_remote_loopback (dev_id, phy_id, enable); + +} + +/****************************************************************************** +* +* mpge_phy_set_802.3az +* +*/ +static sw_error_t +mpge_phy_set_8023az(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable) +{ + return qca808x_phy_set_8023az (dev_id, phy_id, enable); +} + +/****************************************************************************** +* +* mpge_phy_get_8023az status +* +*/ +static sw_error_t +mpge_phy_get_8023az(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t * enable) +{ + return qca808x_phy_get_8023az (dev_id, phy_id, enable); +} + +/****************************************************************************** +* +* mpge_phy_set wol-frame mac address +* +*/ +static sw_error_t +mpge_phy_set_magic_frame_mac(a_uint32_t dev_id, a_uint32_t phy_id, + fal_mac_addr_t * mac) +{ + return qca808x_phy_set_magic_frame_mac (dev_id, phy_id, mac); +} + +/****************************************************************************** +* +* mpge_phy_get wol - frame mac address +* +*/ +static sw_error_t +mpge_phy_get_magic_frame_mac(a_uint32_t dev_id, a_uint32_t phy_id, + fal_mac_addr_t * mac) +{ + return qca808x_phy_get_magic_frame_mac (dev_id, phy_id, mac); +} + +/****************************************************************************** +* +* mpge_phy_set wol - enable or disable +* +*/ +static sw_error_t +mpge_phy_set_wol_status(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable) +{ + return qca808x_phy_set_wol_status (dev_id, phy_id, enable); +} + +/****************************************************************************** +* +* mpge_phy_get_wol status - get wol status +* +*/ +static sw_error_t +mpge_phy_get_wol_status(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t * enable) +{ + return qca808x_phy_get_wol_status (dev_id, phy_id, enable); +} + +/****************************************************************************** +* +* mpge_phy_set_counter - set counter status +* +*/ +static sw_error_t +mpge_phy_set_counter(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable) +{ + return qca808x_phy_set_counter (dev_id, phy_id, enable); +} + +/****************************************************************************** +* +* mpge_phy_get_counter_status - get counter status +* +*/ +static sw_error_t +mpge_phy_get_counter(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t * enable) +{ + return qca808x_phy_get_counter (dev_id, phy_id, enable); +} + +/****************************************************************************** +* +* mpge_phy_show show - counter statistics +* +*/ +static sw_error_t +mpge_phy_show_counter(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_counter_info_t * counter_infor) +{ + return qca808x_phy_show_counter (dev_id, phy_id, counter_infor); +} + +/****************************************************************************** +* +* mpge_phy_set_intr_mask - Set interrupt mask with the +* specified device. +*/ +sw_error_t +mpge_phy_set_intr_mask(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t intr_mask_flag) +{ + a_uint16_t phy_data = 0; + sw_error_t rv = SW_OK; + + phy_data = mpge_phy_reg_read(dev_id, phy_id, MPGE_PHY_INTR_MASK); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (intr_mask_flag & FAL_PHY_INTR_STATUS_UP_CHANGE) { + phy_data |= MPGE_INTR_STATUS_LINK_UP; + } else { + phy_data &= (~MPGE_INTR_STATUS_LINK_UP); + } + + if (intr_mask_flag & FAL_PHY_INTR_STATUS_DOWN_CHANGE) { + phy_data |= MPGE_INTR_STATUS_LINK_DOWN; + } else { + phy_data &= (~MPGE_INTR_STATUS_LINK_DOWN); + } + + if (intr_mask_flag & FAL_PHY_INTR_SPEED_CHANGE) { + phy_data |= MPGE_INTR_SPEED_CHANGE; + } else { + phy_data &= (~MPGE_INTR_SPEED_CHANGE); + } + + if (intr_mask_flag & FAL_PHY_INTR_DUPLEX_CHANGE) { + phy_data |= MPGE_INTR_DUPLEX_CHANGE; + } else { + phy_data &= (~MPGE_INTR_DUPLEX_CHANGE); + } + + if (intr_mask_flag & FAL_PHY_INTR_WOL_STATUS) { + phy_data |= MPGE_INTR_WOL; + } else { + phy_data &= (~MPGE_INTR_WOL); + } + + rv = mpge_phy_reg_write(dev_id, phy_id, MPGE_PHY_INTR_MASK, phy_data); + + return rv; +} + +/****************************************************************************** +* +* mpge_phy_get_intr_mask - Get interrupt mask with the +* specified device. +*/ +sw_error_t +mpge_phy_get_intr_mask(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * intr_mask_flag) +{ + a_uint16_t phy_data = 0; + + phy_data = mpge_phy_reg_read(dev_id, phy_id, MPGE_PHY_INTR_MASK); + PHY_RTN_ON_READ_ERROR(phy_data); + + *intr_mask_flag = 0; + if (phy_data & MPGE_INTR_STATUS_LINK_UP) { + *intr_mask_flag |= FAL_PHY_INTR_STATUS_UP_CHANGE; + } + + if (phy_data & MPGE_INTR_STATUS_LINK_DOWN) { + *intr_mask_flag |= FAL_PHY_INTR_STATUS_DOWN_CHANGE; + } + + if (phy_data & MPGE_INTR_SPEED_CHANGE) { + *intr_mask_flag |= FAL_PHY_INTR_SPEED_CHANGE; + } + + if (phy_data & MPGE_INTR_DUPLEX_CHANGE) { + *intr_mask_flag |= FAL_PHY_INTR_DUPLEX_CHANGE; + } + + if (phy_data & MPGE_INTR_WOL) { + *intr_mask_flag |= FAL_PHY_INTR_WOL_STATUS; + } + + return SW_OK; +} + +/****************************************************************************** +* +* mpge_phy_get_intr_status - Get interrupt status with the +* specified device. +*/ +sw_error_t +mpge_phy_get_intr_status(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * intr_status_flag) +{ + a_uint16_t phy_data = 0; + + phy_data = mpge_phy_reg_read(dev_id, phy_id, MPGE_PHY_INTR_STATUS); + PHY_RTN_ON_READ_ERROR(phy_data); + + *intr_status_flag = 0; + if (phy_data & MPGE_INTR_STATUS_LINK_UP) { + *intr_status_flag |= FAL_PHY_INTR_STATUS_UP_CHANGE; + } + + if (phy_data & MPGE_INTR_STATUS_LINK_DOWN) { + *intr_status_flag |= FAL_PHY_INTR_STATUS_DOWN_CHANGE; + } + + if (phy_data & MPGE_INTR_SPEED_CHANGE) { + *intr_status_flag |= FAL_PHY_INTR_SPEED_CHANGE; + } + + if (phy_data & MPGE_INTR_DUPLEX_CHANGE) { + *intr_status_flag |= FAL_PHY_INTR_DUPLEX_CHANGE; + } + + if (phy_data & MPGE_INTR_WOL) { + *intr_status_flag |= FAL_PHY_INTR_WOL_STATUS; + } + + return SW_OK; +} +#endif + +/****************************************************************************** +* +* mpge_phy_set_eee_advertisement +* +*/ +static sw_error_t +mpge_phy_set_eee_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t adv) +{ + return qca808x_phy_set_eee_adv (dev_id, phy_id, adv); +} + +/****************************************************************************** +* +* mpge_phy_get_eee_advertisement +* +*/ +static sw_error_t +mpge_phy_get_eee_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *adv) +{ + return qca808x_phy_get_eee_adv (dev_id, phy_id, adv); +} + +/****************************************************************************** +* +* mpge_phy_get_eee_partner_advertisement +* +*/ +static sw_error_t +mpge_phy_get_eee_partner_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *adv) +{ + return qca808x_phy_get_eee_partner_adv (dev_id, phy_id, adv); +} + +/****************************************************************************** +* +* mpge_phy_get_eee_capability +* +*/ +static sw_error_t +mpge_phy_get_eee_cap(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *cap) +{ + return qca808x_phy_get_eee_cap (dev_id, phy_id, cap); +} + +/****************************************************************************** +* +* mpge_phy_get_eee_status - get eee status +* +*/ +static sw_error_t +mpge_phy_get_eee_status(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *status) +{ + return qca808x_phy_get_eee_status (dev_id, phy_id, status); +} +/****************************************************************************** +* +* mpge_phy_cdt_thresh_set - set CDT threshold +* +* set CDT threshold +*/ +static sw_error_t +mpge_phy_cdt_thresh_init(a_uint32_t dev_id, a_uint32_t phy_id) +{ + sw_error_t rv = SW_OK; + + rv = mpge_phy_mmd_write(dev_id, phy_id, MPGE_PHY_MMD3_NUM, + MPGE_PHY_MMD3_CDT_THRESH_CTRL3, + MPGE_PHY_MMD3_CDT_THRESH_CTRL3_VAL); + SW_RTN_ON_ERROR(rv); + rv = mpge_phy_mmd_write(dev_id, phy_id, MPGE_PHY_MMD3_NUM, + MPGE_PHY_MMD3_CDT_THRESH_CTRL4, + MPGE_PHY_MMD3_CDT_THRESH_CTRL4_VAL); + SW_RTN_ON_ERROR(rv); + rv = mpge_phy_mmd_write(dev_id, phy_id, MPGE_PHY_MMD3_NUM, + MPGE_PHY_MMD3_CDT_THRESH_CTRL5, + MPGE_PHY_MMD3_CDT_THRESH_CTRL5_VAL); + SW_RTN_ON_ERROR(rv); + rv = mpge_phy_mmd_write(dev_id, phy_id, MPGE_PHY_MMD3_NUM, + MPGE_PHY_MMD3_CDT_THRESH_CTRL6, + MPGE_PHY_MMD3_CDT_THRESH_CTRL6_VAL); + SW_RTN_ON_ERROR(rv); + rv = mpge_phy_mmd_write(dev_id, phy_id, MPGE_PHY_MMD3_NUM, + MPGE_PHY_MMD3_CDT_THRESH_CTRL7, + MPGE_PHY_MMD3_CDT_THRESH_CTRL7_VAL); + SW_RTN_ON_ERROR(rv); + rv = mpge_phy_mmd_write(dev_id, phy_id, MPGE_PHY_MMD3_NUM, + MPGE_PHY_MMD3_CDT_THRESH_CTRL9, + MPGE_PHY_MMD3_CDT_THRESH_CTRL9_VAL); + SW_RTN_ON_ERROR(rv); + rv = mpge_phy_mmd_write(dev_id, phy_id, MPGE_PHY_MMD3_NUM, + MPGE_PHY_MMD3_CDT_THRESH_CTRL13, + MPGE_PHY_MMD3_CDT_THRESH_CTRL13_VAL); + SW_RTN_ON_ERROR(rv); + rv = mpge_phy_mmd_write(dev_id, phy_id, MPGE_PHY_MMD3_NUM, + MPGE_PHY_MMD3_CDT_THRESH_CTRL14, + MPGE_PHY_MMD3_NEAR_ECHO_THRESH_VAL); + + return rv; +} + +/****************************************************************************** +* +* mpge_phy_function_reset - do function reset +* +*/ +static sw_error_t +mpge_phy_function_reset(a_uint32_t dev_id, a_uint32_t phy_id, + hsl_phy_function_reset_t phy_reset_type) +{ + a_uint16_t phy_data = 0; + sw_error_t rv = SW_OK; + + switch (phy_reset_type) + { + case PHY_FIFO_RESET: + phy_data = mpge_phy_reg_read (dev_id, phy_id, MPGE_PHY_FIFO_CONTROL); + PHY_RTN_ON_READ_ERROR(phy_data); + + rv = mpge_phy_reg_write(dev_id, phy_id, MPGE_PHY_FIFO_CONTROL, + phy_data & (~MPGE_PHY_FIFO_RESET)); + SW_RTN_ON_ERROR(rv); + + aos_mdelay(50); + + rv = mpge_phy_reg_write(dev_id, phy_id, MPGE_PHY_FIFO_CONTROL, + phy_data | MPGE_PHY_FIFO_RESET); + SW_RTN_ON_ERROR(rv); + break; + default: + return SW_NOT_SUPPORTED; + } + + return rv; +} + +static void +mpge_phy_lock_init(void) +{ + return qca808x_phy_lock_init(); +} + +static sw_error_t +mpge_phy_dac_set(a_uint32_t dev_id, a_uint32_t phy_id, phy_dac_t phy_dac) +{ + a_uint16_t phy_data = 0; + sw_error_t rv = SW_OK; + + if(phy_dac.mdac != PHY_INVALID_DAC) + { + SSDK_INFO("phy mdac is set as 0x%x\n", phy_dac.mdac); + /*set mdac value*/ + phy_data = mpge_phy_mmd_read(dev_id, phy_id, MPGE_PHY_MMD1_NUM, + MPGE_PHY_MMD1_DAC); + PHY_RTN_ON_READ_ERROR(phy_data); + phy_data &= ~(BITS(8,8)); + rv = mpge_phy_mmd_write(dev_id, phy_id, MPGE_PHY_MMD1_NUM, + MPGE_PHY_MMD1_DAC, phy_data | PHY_DAC(phy_dac.mdac)); + SW_RTN_ON_ERROR(rv); + } + if(phy_dac.edac != PHY_INVALID_DAC) + { + SSDK_INFO("phy edac is set as 0x%x\n", phy_dac.edac); + /*set edac value*/ + phy_data = mpge_phy_debug_read(dev_id, phy_id, MPGE_PHY_DEBUG_EDAC); + PHY_RTN_ON_READ_ERROR(phy_data); + phy_data &= ~(BITS(8,8)); + rv = mpge_phy_debug_write(dev_id, phy_id, MPGE_PHY_DEBUG_EDAC, + phy_data | PHY_DAC(phy_dac.edac)); + SW_RTN_ON_ERROR(rv); + } + + return rv; +} + +static void +mpge_phy_dac_init(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t port_id) +{ + phy_dac_t phy_dac; + + hsl_port_phy_dac_get(dev_id, port_id, &phy_dac); + mpge_phy_dac_set(dev_id, phy_id, phy_dac); + + return; +} + +static sw_error_t +mpge_phy_hw_init(a_uint32_t dev_id, a_uint32_t port_bmp) +{ + a_uint32_t port_id = 0, phy_addr = 0; + sw_error_t rv = SW_OK; + + for (port_id = SSDK_PHYSICAL_PORT0; port_id < SW_MAX_NR_PORT; port_id ++) + { + if (port_bmp & (0x1 << port_id)) + { + phy_addr = qca_ssdk_port_to_phy_addr(dev_id, port_id); + SW_RTN_ON_ERROR(rv); + /*configure the CDT threshold*/ + rv = mpge_phy_cdt_thresh_init (dev_id, phy_addr); + SW_RTN_ON_ERROR(rv); + /*special configuration for AZ*/ + rv = mpge_phy_mmd_write(dev_id, phy_addr, MPGE_PHY_MMD3_NUM, + MPGE_PHY_MMD3_AZ_CTRL1, MPGE_PHY_MMD3_AZ_CTRL1_VAL); + SW_RTN_ON_ERROR(rv); + rv = mpge_phy_mmd_write(dev_id, phy_addr, MPGE_PHY_MMD3_NUM, + MPGE_PHY_MMD3_AZ_CTRL2, MPGE_PHY_MMD3_AZ_CTRL2_VAL); + SW_RTN_ON_ERROR(rv); + /*configure MSE threshold and over threshold times*/ + rv = mpge_phy_mmd_write(dev_id, phy_addr, MPGE_PHY_MMD1_NUM, + MPGE_PHY_MMD1_MSE_THRESH1, MPGE_PHY_MMD1_MSE_THRESH1_VAL); + SW_RTN_ON_ERROR(rv); + rv = mpge_phy_mmd_write(dev_id, phy_addr, MPGE_PHY_MMD1_NUM, + MPGE_PHY_MMD1_MSE_THRESH2, MPGE_PHY_MMD1_MSE_THRESH2_VAL); + SW_RTN_ON_ERROR(rv); + mpge_phy_dac_init(dev_id, phy_addr, port_id); + } + } + + return rv; +} + +static sw_error_t mpge_phy_api_ops_init(void) +{ + sw_error_t ret = SW_OK; + hsl_phy_ops_t *mpge_phy_api_ops = NULL; + + mpge_phy_api_ops = kzalloc(sizeof(hsl_phy_ops_t), GFP_KERNEL); + if (mpge_phy_api_ops == NULL) + { + SSDK_ERROR("mpge phy ops kzalloc failed!\n"); + return -ENOMEM; + } + + phy_api_ops_init(MPGE_PHY_CHIP); + + mpge_phy_api_ops->phy_reg_write = mpge_phy_reg_write; + mpge_phy_api_ops->phy_reg_read = mpge_phy_reg_read; + mpge_phy_api_ops->phy_debug_write = mpge_phy_debug_write; + mpge_phy_api_ops->phy_debug_read = mpge_phy_debug_read; + mpge_phy_api_ops->phy_mmd_write = mpge_phy_mmd_write; + mpge_phy_api_ops->phy_mmd_read = mpge_phy_mmd_read; + mpge_phy_api_ops->phy_get_status = mpge_phy_get_status; + mpge_phy_api_ops->phy_speed_get = mpge_phy_get_speed; + mpge_phy_api_ops->phy_speed_set = mpge_phy_set_speed; + mpge_phy_api_ops->phy_duplex_get = mpge_phy_get_duplex; + mpge_phy_api_ops->phy_duplex_set = mpge_phy_set_duplex; + mpge_phy_api_ops->phy_autoneg_enable_set = mpge_phy_enable_autoneg; + mpge_phy_api_ops->phy_restart_autoneg = mpge_phy_restart_autoneg; + mpge_phy_api_ops->phy_autoneg_status_get = mpge_phy_autoneg_status; + mpge_phy_api_ops->phy_autoneg_adv_set = mpge_phy_set_autoneg_adv; + mpge_phy_api_ops->phy_autoneg_adv_get = mpge_phy_get_autoneg_adv; + mpge_phy_api_ops->phy_link_status_get = mpge_phy_get_link_status; + mpge_phy_api_ops->phy_reset = mpge_phy_reset; + mpge_phy_api_ops->phy_id_get = mpge_phy_get_phy_id; + mpge_phy_api_ops->phy_power_off = mpge_phy_poweroff; + mpge_phy_api_ops->phy_power_on = mpge_phy_poweron; +#ifndef IN_PORTCONTROL_MINI + mpge_phy_api_ops->phy_cdt = mpge_phy_cdt; + mpge_phy_api_ops->phy_mdix_set = mpge_phy_set_mdix; + mpge_phy_api_ops->phy_mdix_get = mpge_phy_get_mdix; + mpge_phy_api_ops->phy_mdix_status_get = mpge_phy_get_mdix_status; + mpge_phy_api_ops->phy_local_loopback_set = mpge_phy_set_local_loopback; + mpge_phy_api_ops->phy_local_loopback_get = mpge_phy_get_local_loopback; + mpge_phy_api_ops->phy_remote_loopback_set = mpge_phy_set_remote_loopback; + mpge_phy_api_ops->phy_remote_loopback_get = mpge_phy_get_remote_loopback; + mpge_phy_api_ops->phy_8023az_set = mpge_phy_set_8023az; + mpge_phy_api_ops->phy_8023az_get = mpge_phy_get_8023az; + mpge_phy_api_ops->phy_hibernation_set = mpge_phy_set_hibernate; + mpge_phy_api_ops->phy_hibernation_get = mpge_phy_get_hibernate; + mpge_phy_api_ops->phy_magic_frame_mac_set = mpge_phy_set_magic_frame_mac; + mpge_phy_api_ops->phy_magic_frame_mac_get = mpge_phy_get_magic_frame_mac; + mpge_phy_api_ops->phy_counter_set = mpge_phy_set_counter; + mpge_phy_api_ops->phy_counter_get = mpge_phy_get_counter; + mpge_phy_api_ops->phy_counter_show = mpge_phy_show_counter; + mpge_phy_api_ops->phy_wol_status_set = mpge_phy_set_wol_status; + mpge_phy_api_ops->phy_wol_status_get = mpge_phy_get_wol_status; + mpge_phy_api_ops->phy_intr_mask_set = mpge_phy_set_intr_mask; + mpge_phy_api_ops->phy_intr_mask_get = mpge_phy_get_intr_mask; + mpge_phy_api_ops->phy_intr_status_get = mpge_phy_get_intr_status; +#endif + mpge_phy_api_ops->phy_eee_adv_set = mpge_phy_set_eee_adv; + mpge_phy_api_ops->phy_eee_adv_get = mpge_phy_get_eee_adv; + mpge_phy_api_ops->phy_eee_partner_adv_get = mpge_phy_get_eee_partner_adv; + mpge_phy_api_ops->phy_eee_cap_get = mpge_phy_get_eee_cap; + mpge_phy_api_ops->phy_eee_status_get = mpge_phy_get_eee_status; + mpge_phy_api_ops->phy_function_reset = mpge_phy_function_reset; +#ifdef IN_LED + mpge_phy_led_api_ops_init(mpge_phy_api_ops); +#endif + ret = hsl_phy_api_ops_register(MPGE_PHY_CHIP, mpge_phy_api_ops); + + if (ret == SW_OK) + { + SSDK_INFO("qca probe mpge phy driver succeeded!\n"); + } + else + { + SSDK_ERROR("qca probe mpge phy driver failed! (code: %d)\n", ret); + } + + return ret; +} + +/****************************************************************************** +* +* mpge_phy_init - +* +*/ +int mpge_phy_init(a_uint32_t dev_id, a_uint32_t port_bmp) +{ + a_int32_t ret = 0; + static a_bool_t phy_ops_flag = A_FALSE; + + if(phy_ops_flag == A_FALSE && + mpge_phy_api_ops_init() == SW_OK) { + mpge_phy_lock_init(); + phy_ops_flag = A_TRUE; + } + mpge_phy_hw_init(dev_id, port_bmp); + + return ret; +} diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/qca803x_phy.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/qca803x_phy.c new file mode 100644 index 000000000..e9ca3bc79 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/qca803x_phy.c @@ -0,0 +1,2341 @@ +/* + * 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 "sw.h" +#include "fal_port_ctrl.h" +#include "hsl_api.h" +#include "hsl.h" +#include "qca803x_phy.h" +#include "hsl_phy.h" +#include "ssdk_plat.h" + +#define QCA803X_PHY_DELAYED_INIT_TICKS msecs_to_jiffies(1000) + +typedef struct { + a_uint32_t dev_id; + a_uint32_t combo_phy_bmp; + qca803x_phy_medium_t combo_cfg[SW_MAX_NR_PORT]; + struct delayed_work phy_sync_dwork; +} qca803x_priv_t; + +static qca803x_priv_t g_qca803x_phy; +static struct mutex qca803x_reg_lock; + +#define QCA803X_LOCKER_INIT mutex_init(&qca803x_reg_lock) +#define QCA803X_REG_LOCK mutex_lock(&qca803x_reg_lock) +#define QCA803X_REG_UNLOCK mutex_unlock(&qca803x_reg_lock) + + +/****************************************************************************** +* +* qca803x_phy_mii_read - mii register read +* +* mii register read +*/ +a_uint16_t +qca803x_phy_reg_read(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t reg_id) +{ + sw_error_t rv = SW_OK; + a_uint16_t phy_data = 0; + + HSL_PHY_GET(rv, dev_id, phy_id, reg_id, &phy_data); + if (SW_OK != rv) { + return 0xffff; + } + + return phy_data; +} + +/****************************************************************************** +* +* qca803x_phy_mii_write - mii register write +* +* mii register write +*/ +sw_error_t +qca803x_phy_reg_write(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t reg_id, + a_uint16_t reg_val) +{ + sw_error_t rv; + + HSL_PHY_SET(rv, dev_id, phy_id, reg_id, reg_val); + + return rv; + +} + +/****************************************************************************** +* +* qca803x_phy_debug_write - debug port write +* +* debug port write +*/ +sw_error_t +qca803x_phy_debug_write(a_uint32_t dev_id, a_uint32_t phy_id, a_uint16_t reg_id, + a_uint16_t reg_val) +{ + qca803x_phy_reg_write(dev_id, phy_id, QCA803X_DEBUG_PORT_ADDRESS, reg_id); + qca803x_phy_reg_write(dev_id, phy_id, QCA803X_DEBUG_PORT_DATA, reg_val); + + return SW_OK; +} + +/****************************************************************************** +* +* qca803x_phy_debug_read - debug port read +* +* debug port read +*/ +a_uint16_t +qca803x_phy_debug_read(a_uint32_t dev_id, a_uint32_t phy_id, a_uint16_t reg_id) +{ + qca803x_phy_reg_write(dev_id, phy_id, QCA803X_DEBUG_PORT_ADDRESS, reg_id); + return qca803x_phy_reg_read(dev_id, phy_id, QCA803X_DEBUG_PORT_DATA); +} + +/****************************************************************************** +* +* qca803x_phy_mmd_write - PHY MMD register write +* +* PHY MMD register write +*/ +sw_error_t +qca803x_phy_mmd_write(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint16_t mmd_num, a_uint16_t reg_id, a_uint16_t reg_val) +{ + qca803x_phy_reg_write(dev_id, phy_id, QCA803X_MMD_CTRL_REG, mmd_num); + qca803x_phy_reg_write(dev_id, phy_id, QCA803X_MMD_DATA_REG, reg_id); + qca803x_phy_reg_write(dev_id, phy_id, QCA803X_MMD_CTRL_REG, + 0x4000 | mmd_num); + qca803x_phy_reg_write(dev_id, phy_id, QCA803X_MMD_DATA_REG, reg_val); + + return SW_OK; +} + +/****************************************************************************** +* +* qca803x_phy_mmd_read - PHY MMD register read +* +* PHY MMD register read +*/ +a_uint16_t +qca803x_phy_mmd_read(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint16_t mmd_num, a_uint16_t reg_id) +{ + qca803x_phy_reg_write(dev_id, phy_id, QCA803X_MMD_CTRL_REG, mmd_num); + qca803x_phy_reg_write(dev_id, phy_id, QCA803X_MMD_DATA_REG, reg_id); + qca803x_phy_reg_write(dev_id, phy_id, QCA803X_MMD_CTRL_REG, + 0x4000 | mmd_num); + + return qca803x_phy_reg_read(dev_id, phy_id, QCA803X_MMD_DATA_REG); +} + +/****************************************************************************** +* +* qca803x_phy_get_speed - Determines the speed of phy ports associated with the +* specified device. +*/ + +sw_error_t +qca803x_phy_get_speed(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_speed_t * speed) +{ + a_uint16_t phy_data; + sw_error_t rv = SW_OK; + + phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_SPEC_STATUS); + PHY_RTN_ON_READ_ERROR(phy_data); + + switch (phy_data & QCA803X_STATUS_SPEED_MASK) + { + case QCA803X_STATUS_SPEED_1000MBS: + *speed = FAL_SPEED_1000; + break; + case QCA803X_STATUS_SPEED_100MBS: + *speed = FAL_SPEED_100; + break; + case QCA803X_STATUS_SPEED_10MBS: + *speed = FAL_SPEED_10; + break; + default: + return SW_READ_ERROR; + } + + return rv; +} + +/****************************************************************************** +* +* qca803x_phy_set_speed - Determines the speed of phy ports associated with the +* specified device. +*/ +sw_error_t +qca803x_phy_set_speed(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_speed_t speed) +{ + a_uint16_t phy_data = 0; + fal_port_duplex_t old_duplex; + sw_error_t rv = SW_OK; + + phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_CONTROL); + PHY_RTN_ON_READ_ERROR(phy_data); + + rv = qca803x_phy_get_duplex(dev_id, phy_id, &old_duplex); + if(rv != SW_OK) { + return rv; + } + + if (old_duplex == FAL_FULL_DUPLEX) { + phy_data |= QCA803X_CTRL_FULL_DUPLEX; + switch(speed) + { + case FAL_SPEED_1000: + phy_data |= QCA803X_CTRL_SPEED_1000; + phy_data &= ~QCA803X_CTRL_SPEED_100; + phy_data |= QCA803X_CTRL_AUTONEGOTIATION_ENABLE; + break; + case FAL_SPEED_100: + case FAL_SPEED_10: + phy_data &= ~QCA803X_CTRL_SPEED_1000; + phy_data &= ~QCA803X_CTRL_AUTONEGOTIATION_ENABLE; + if (FAL_SPEED_100 == speed) { + phy_data |= QCA803X_CTRL_SPEED_100; + } else { + phy_data &= ~QCA803X_CTRL_SPEED_100; + } + break; + default: + return SW_BAD_PARAM; + } + } else if (old_duplex == FAL_HALF_DUPLEX) { + phy_data &= ~QCA803X_CTRL_FULL_DUPLEX; + switch(speed) + { + case FAL_SPEED_100: + case FAL_SPEED_10: + phy_data &= ~QCA803X_CTRL_SPEED_1000; + phy_data &= ~QCA803X_CTRL_AUTONEGOTIATION_ENABLE; + if (FAL_SPEED_100 == speed) { + phy_data |= QCA803X_CTRL_SPEED_100; + } else { + phy_data &= ~QCA803X_CTRL_SPEED_100; + } + break; + case FAL_SPEED_1000: + phy_data |= QCA803X_CTRL_FULL_DUPLEX; + phy_data |= QCA803X_CTRL_SPEED_1000; + phy_data &= ~QCA803X_CTRL_SPEED_100; + phy_data |= QCA803X_CTRL_AUTONEGOTIATION_ENABLE; + break; + default: + return SW_BAD_PARAM; + } + } else { + return SW_FAIL; + } + rv = qca803x_phy_reg_write(dev_id, phy_id, QCA803X_PHY_CONTROL, phy_data); + + return rv; +} + +/****************************************************************************** +* +* qca803x_phy_set_duplex - Determines the speed of phy ports associated with the +* specified device. +*/ +sw_error_t +qca803x_phy_set_duplex(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_duplex_t duplex) +{ + a_uint16_t phy_data = 0; + fal_port_speed_t old_speed; + sw_error_t rv = SW_OK; + + phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_CONTROL); + PHY_RTN_ON_READ_ERROR(phy_data); + + qca803x_phy_get_speed(dev_id, phy_id, &old_speed); + switch(old_speed) + { + case FAL_SPEED_1000: + phy_data |= QCA803X_CTRL_SPEED_1000; + phy_data &= ~QCA803X_CTRL_SPEED_100; + phy_data |= QCA803X_CTRL_AUTONEGOTIATION_ENABLE; + if (duplex == FAL_FULL_DUPLEX) { + phy_data |= QCA803X_CTRL_FULL_DUPLEX; + } else { + return SW_NOT_SUPPORTED; + } + break; + case FAL_SPEED_100: + case FAL_SPEED_10: + if(old_speed == FAL_SPEED_100) { + phy_data |= QCA803X_CTRL_SPEED_100; + } else { + phy_data &= ~QCA803X_CTRL_SPEED_100; + } + phy_data &= ~QCA803X_CTRL_SPEED_1000; + phy_data &= ~QCA803X_CTRL_AUTONEGOTIATION_ENABLE; + if (duplex == FAL_FULL_DUPLEX) { + phy_data |= QCA803X_CTRL_FULL_DUPLEX; + } else { + phy_data &= ~QCA803X_CTRL_FULL_DUPLEX; + } + break; + default: + return SW_FAIL; + } + rv = qca803x_phy_reg_write(dev_id, phy_id, QCA803X_PHY_CONTROL, phy_data); + + return rv; +} + +/****************************************************************************** +* +* qca803x_phy_get_duplex - Determines the speed of phy ports associated with the +* specified device. +*/ +sw_error_t +qca803x_phy_get_duplex(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_duplex_t * duplex) +{ + a_uint16_t phy_data; + sw_error_t rv = SW_OK; + + phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_SPEC_STATUS); + PHY_RTN_ON_READ_ERROR(phy_data); + + //read duplex + if (phy_data & QCA803X_STATUS_FULL_DUPLEX) + *duplex = FAL_FULL_DUPLEX; + else + *duplex = FAL_HALF_DUPLEX; + + return rv; +} + +/****************************************************************************** +* +* qca803x_phy_reset - reset the phy +* +* reset the phy +*/ +sw_error_t qca803x_phy_reset(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + sw_error_t rv = SW_OK; + + phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_CONTROL); + PHY_RTN_ON_READ_ERROR(phy_data); + + rv = qca803x_phy_reg_write(dev_id, phy_id, QCA803X_PHY_CONTROL, + phy_data | QCA803X_CTRL_SOFTWARE_RESET); + + return rv; +} +/****************************************************************************** +* +* qca803x_phy_status - test to see if the specified phy link is alive +* +* RETURNS: +* A_TRUE --> link is alive +* A_FALSE --> link is down +*/ +a_bool_t qca803x_phy_get_link_status(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + a_bool_t rv = A_TRUE; + phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_SPEC_STATUS); + + if (phy_data & QCA803X_STATUS_LINK_PASS) { + rv = A_TRUE; + } else { + rv = A_FALSE; + } + return rv; +} +#ifndef IN_PORTCONTROL_MINI +/****************************************************************************** +* +* qca803x_phy_cdt - cable diagnostic test +* +* cable diagnostic test +*/ + +static inline fal_cable_status_t _phy_cdt_status_mapping(a_uint16_t status) +{ + fal_cable_status_t status_mapping = FAL_CABLE_STATUS_INVALID; + + switch (status) { + case 3: + status_mapping = FAL_CABLE_STATUS_INVALID; + break; + case 2: + status_mapping = FAL_CABLE_STATUS_OPENED; + break; + case 1: + status_mapping = FAL_CABLE_STATUS_SHORT; + break; + case 0: + status_mapping = FAL_CABLE_STATUS_NORMAL; + break; + } + return status_mapping; +} + +static sw_error_t qca803x_phy_cdt_start(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t mdi_pair) +{ + a_uint16_t status = 0; + a_uint16_t ii = 100; + a_uint16_t MDI_PAIR_S = (mdi_pair << 8) & CDT_PAIR_MASK; + + /* RUN CDT */ + qca803x_phy_reg_write(dev_id, phy_id, QCA803X_PHY_CDT_CONTROL, + QCA803X_RUN_CDT | MDI_PAIR_S); + do { + aos_mdelay(30); + status = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_CDT_CONTROL); + } + while ((status & QCA803X_RUN_CDT) && (--ii)); + + return SW_OK; +} + +sw_error_t +qca803x_phy_cdt(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t mdi_pair, + fal_cable_status_t * cable_status, a_uint32_t * cable_len) +{ + a_uint16_t status = 0; + + if (mdi_pair >= QCA803X_MDI_PAIR_NUM) { + //There are only 4 mdi pairs in 1000BASE-T + return SW_BAD_PARAM; + } + + qca803x_phy_cdt_start(dev_id, phy_id, mdi_pair); + + /* Get cable status */ + status = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_CDT_STATUS); + *cable_status = _phy_cdt_status_mapping((status >> 8) & 0x3); + /* the actual cable length equals to CableDeltaTime * 0.824 */ + *cable_len = ((status & 0xff) * 824) / 1000; + + return SW_OK; +} + +/****************************************************************************** +* +* qca803x_phy_set_mdix - +* +* set phy mdix configuraiton +*/ +sw_error_t +qca803x_phy_set_mdix(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_mdix_mode_t mode) +{ + a_uint16_t phy_data; + + phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_SPEC_CONTROL); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (mode == PHY_MDIX_AUTO) { + phy_data |= QCA803X_PHY_MDIX_AUTO; + } else if (mode == PHY_MDIX_MDIX) { + phy_data &= ~QCA803X_PHY_MDIX_AUTO; + phy_data |= QCA803X_PHY_MDIX; + } else if (mode == PHY_MDIX_MDI) { + phy_data &= ~QCA803X_PHY_MDIX_AUTO; + } else { + return SW_BAD_PARAM; + } + + qca803x_phy_reg_write(dev_id, phy_id, QCA803X_PHY_SPEC_CONTROL, phy_data); + + qca803x_phy_reset(dev_id, phy_id); + return SW_OK; +} + +/****************************************************************************** +* +* qca803x_phy_get_mdix +* +* get phy mdix configuration +*/ +sw_error_t +qca803x_phy_get_mdix(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_mdix_mode_t * mode) +{ + a_uint16_t phy_data; + + phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_SPEC_CONTROL); + PHY_RTN_ON_READ_ERROR(phy_data); + + if ((phy_data & QCA803X_PHY_MDIX_AUTO) == QCA803X_PHY_MDIX_AUTO) { + *mode = PHY_MDIX_AUTO; + } else if ((phy_data & QCA803X_PHY_MDIX) == QCA803X_PHY_MDIX) { + *mode = PHY_MDIX_MDIX; + } else { + *mode = PHY_MDIX_MDI; + } + + return SW_OK; + +} + +/****************************************************************************** +* +* qca803x_phy_get_mdix status +* +* get phy mdix status +*/ +sw_error_t +qca803x_phy_get_mdix_status(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_mdix_status_t * mode) +{ + a_uint16_t phy_data; + + phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_SPEC_STATUS); + PHY_RTN_ON_READ_ERROR(phy_data); + + *mode = + (phy_data & QCA803X_PHY_MDIX_STATUS) ? PHY_MDIX_STATUS_MDIX : + PHY_MDIX_STATUS_MDI; + + return SW_OK; + +} + +/****************************************************************************** +* +* qca803x_phy_set_local_loopback +* +* set phy local loopback +*/ +sw_error_t +qca803x_phy_set_local_loopback(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t enable) +{ + a_uint16_t phy_data; + fal_port_speed_t old_speed; + + if (enable == A_TRUE) { + qca803x_phy_get_speed(dev_id, phy_id, &old_speed); + if (old_speed == FAL_SPEED_1000) { + phy_data = QCA803X_1000M_LOOPBACK; + } else if (old_speed == FAL_SPEED_100) { + phy_data = QCA803X_100M_LOOPBACK; + } else if (old_speed == FAL_SPEED_10) { + phy_data = QCA803X_10M_LOOPBACK; + } else { + return SW_FAIL; + } + } else { + phy_data = QCA803X_COMMON_CTRL; + } + + qca803x_phy_reg_write(dev_id, phy_id, QCA803X_PHY_CONTROL, phy_data); + return SW_OK; + +} + +/****************************************************************************** +* +* qca803x_phy_get_local_loopback +* +* get phy local loopback +*/ +sw_error_t +qca803x_phy_get_local_loopback(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t * enable) +{ + a_uint16_t phy_data; + + phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_CONTROL); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (phy_data & QCA803X_LOCAL_LOOPBACK_ENABLE) { + *enable = A_TRUE; + } else { + *enable = A_FALSE; + } + + return SW_OK; + +} + +/****************************************************************************** +* +* qca803x_phy_set_remote_loopback +* +* set phy remote loopback +*/ +sw_error_t +qca803x_phy_set_remote_loopback(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t enable) +{ + a_uint16_t phy_data; + + phy_data = qca803x_phy_mmd_read(dev_id, phy_id, QCA803X_PHY_MMD3_NUM, + QCA803X_PHY_MMD3_ADDR_REMOTE_LOOPBACK_CTRL); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (enable == A_TRUE) { + phy_data |= 0x0001; + } else { + phy_data &= ~0x0001; + } + + qca803x_phy_mmd_write(dev_id, phy_id, QCA803X_PHY_MMD3_NUM, + QCA803X_PHY_MMD3_ADDR_REMOTE_LOOPBACK_CTRL, + phy_data); + return SW_OK; + +} + +/****************************************************************************** +* +* qca803x_phy_get_remote_loopback +* +* get phy remote loopback +*/ +sw_error_t +qca803x_phy_get_remote_loopback(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t * enable) +{ + a_uint16_t phy_data; + + phy_data = qca803x_phy_mmd_read(dev_id, phy_id, QCA803X_PHY_MMD3_NUM, + QCA803X_PHY_MMD3_ADDR_REMOTE_LOOPBACK_CTRL); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (phy_data & 0x0001) { + *enable = A_TRUE; + } else { + *enable = A_FALSE; + } + + return SW_OK; + +} +#endif +/****************************************************************************** +* +* qca803x_set_autoneg_adv - set the phy autoneg Advertisement +* +*/ +sw_error_t +qca803x_phy_set_autoneg_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t autoneg) +{ + a_uint16_t phy_data = 0; + + phy_data = qca803x_phy_reg_read(dev_id, phy_id, + QCA803X_AUTONEG_ADVERT); + PHY_RTN_ON_READ_ERROR(phy_data); + + phy_data &= ~QCA803X_ADVERTISE_MEGA_ALL; + + if (autoneg & FAL_PHY_ADV_100TX_FD) { + phy_data |= QCA803X_ADVERTISE_100FULL; + } + if (autoneg & FAL_PHY_ADV_100TX_HD) { + phy_data |= QCA803X_ADVERTISE_100HALF; + } + if (autoneg & FAL_PHY_ADV_10T_FD) { + phy_data |= QCA803X_ADVERTISE_10FULL; + } + if (autoneg & FAL_PHY_ADV_10T_HD) { + phy_data |= QCA803X_ADVERTISE_10HALF; + } + if (autoneg & FAL_PHY_ADV_PAUSE) { + phy_data |= QCA803X_ADVERTISE_PAUSE; + } + if (autoneg & FAL_PHY_ADV_ASY_PAUSE) { + phy_data |= QCA803X_ADVERTISE_ASYM_PAUSE; + } + if (autoneg & FAL_PHY_ADV_1000T_FD) { + phy_data |= QCA803X_EXTENDED_NEXT_PAGE_EN; + } else { + phy_data &= ~QCA803X_EXTENDED_NEXT_PAGE_EN; + } + qca803x_phy_reg_write(dev_id, phy_id, QCA803X_AUTONEG_ADVERT, + phy_data); + + phy_data = qca803x_phy_reg_read(dev_id, phy_id, + QCA803X_1000BASET_CONTROL); + PHY_RTN_ON_READ_ERROR(phy_data); + + phy_data &= ~QCA803X_ADVERTISE_1000FULL; + phy_data &= ~QCA803X_ADVERTISE_1000HALF; + + if (autoneg & FAL_PHY_ADV_1000T_FD) { + phy_data |= QCA803X_ADVERTISE_1000FULL; + } + qca803x_phy_reg_write(dev_id, phy_id, QCA803X_1000BASET_CONTROL, + phy_data); + + return SW_OK; +} + +/****************************************************************************** +* +* qca803x_get_autoneg_adv - get the phy autoneg Advertisement +* +*/ +sw_error_t +qca803x_phy_get_autoneg_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * autoneg) +{ + a_uint16_t phy_data = 0; + + *autoneg = 0; + phy_data = + qca803x_phy_reg_read(dev_id, phy_id, QCA803X_AUTONEG_ADVERT); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (phy_data & QCA803X_ADVERTISE_100FULL) + *autoneg |= FAL_PHY_ADV_100TX_FD; + + if (phy_data & QCA803X_ADVERTISE_100HALF) + *autoneg |= FAL_PHY_ADV_100TX_HD; + + if (phy_data & QCA803X_ADVERTISE_10FULL) + *autoneg |= FAL_PHY_ADV_10T_FD; + + if (phy_data & QCA803X_ADVERTISE_10HALF) + *autoneg |= FAL_PHY_ADV_10T_HD; + + if (phy_data & QCA803X_ADVERTISE_PAUSE) + *autoneg |= FAL_PHY_ADV_PAUSE; + + if (phy_data & QCA803X_ADVERTISE_ASYM_PAUSE) + *autoneg |= FAL_PHY_ADV_ASY_PAUSE; + + phy_data = qca803x_phy_reg_read(dev_id, phy_id, + QCA803X_1000BASET_CONTROL); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (phy_data & QCA803X_ADVERTISE_1000FULL) + *autoneg |= FAL_PHY_ADV_1000T_FD; + + return SW_OK; +} + +/****************************************************************************** +* +* qca803x_phy_autoneg_status +* +* Power off the phy +*/ +a_bool_t qca803x_phy_autoneg_status(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + + phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_CONTROL); + + if (phy_data & QCA803X_CTRL_AUTONEGOTIATION_ENABLE) + return A_TRUE; + + return A_FALSE; +} + +/****************************************************************************** +* +* qca803x_restart_autoneg - restart the phy autoneg +* +*/ +sw_error_t qca803x_phy_restart_autoneg(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data = 0; + sw_error_t rv = SW_OK; + + phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_CONTROL); + PHY_RTN_ON_READ_ERROR(phy_data); + + phy_data |= QCA803X_CTRL_AUTONEGOTIATION_ENABLE; + rv = qca803x_phy_reg_write(dev_id, phy_id, QCA803X_PHY_CONTROL, + phy_data | QCA803X_CTRL_RESTART_AUTONEGOTIATION); + + return rv; +} +/****************************************************************************** +* +* qca803x_phy_enable_autonego +* +*/ +sw_error_t qca803x_phy_enable_autoneg(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data = 0; + sw_error_t rv = SW_OK; + + phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_CONTROL); + PHY_RTN_ON_READ_ERROR(phy_data); + + rv = qca803x_phy_reg_write(dev_id, phy_id, QCA803X_PHY_CONTROL, + phy_data | QCA803X_CTRL_AUTONEGOTIATION_ENABLE); + + return rv; +} +#ifndef IN_PORTCONTROL_MINI +/****************************************************************************** +* +* qca803x_phy_get_ability - get the phy ability +* +* +*/ +sw_error_t +qca803x_phy_get_ability(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * ability) +{ + a_uint16_t phy_data; + + *ability = 0; + + phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_STATUS); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (phy_data & QCA803X_STATUS_AUTONEG_CAPS) + *ability |= FAL_PHY_AUTONEG_CAPS; + + if (phy_data & QCA803X_STATUS_100T2_HD_CAPS) + *ability |= FAL_PHY_100T2_HD_CAPS; + + if (phy_data & QCA803X_STATUS_100T2_FD_CAPS) + *ability |= FAL_PHY_100T2_FD_CAPS; + + if (phy_data & QCA803X_STATUS_10T_HD_CAPS) + *ability |= FAL_PHY_10T_HD_CAPS; + + if (phy_data & QCA803X_STATUS_10T_FD_CAPS) + *ability |= FAL_PHY_10T_FD_CAPS; + + if (phy_data & QCA803X_STATUS_100X_HD_CAPS) + *ability |= FAL_PHY_100X_HD_CAPS; + + if (phy_data & QCA803X_STATUS_100X_FD_CAPS) + *ability |= FAL_PHY_100X_FD_CAPS; + + if (phy_data & QCA803X_STATUS_100T4_CAPS) + *ability |= FAL_PHY_100T4_CAPS; + + if (phy_data & QCA803X_STATUS_EXTENDED_STATUS) { + phy_data = + qca803x_phy_reg_read(dev_id, phy_id, QCA803X_EXTENDED_STATUS); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (phy_data & QCA803X_STATUS_1000T_FD_CAPS) { + *ability |= FAL_PHY_1000T_FD_CAPS; + } + + if (phy_data & QCA803X_STATUS_1000X_FD_CAPS) { + *ability |= FAL_PHY_1000X_FD_CAPS; + } + } + + return SW_OK; +} + +/****************************************************************************** +* +* qca803x_phy_get_partner_ability - get the phy ability +* +* +*/ +sw_error_t +qca803x_phy_get_partner_ability(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * ability) +{ + a_uint16_t phy_data; + + *ability = 0; + + phy_data = + qca803x_phy_reg_read(dev_id, phy_id, QCA803X_LINK_PARTNER_ABILITY); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (phy_data & QCA803X_LINK_10BASETX_HALF_DUPLEX) + *ability |= FAL_PHY_PART_10T_HD; + + if (phy_data & QCA803X_LINK_10BASETX_FULL_DUPLEX) + *ability |= FAL_PHY_PART_10T_FD; + + if (phy_data & QCA803X_LINK_100BASETX_HALF_DUPLEX) + *ability |= FAL_PHY_PART_100TX_HD; + + if (phy_data & QCA803X_LINK_100BASETX_FULL_DUPLEX) + *ability |= FAL_PHY_PART_100TX_FD; + + if (phy_data & QCA803X_LINK_NPAGE) { + phy_data = + qca803x_phy_reg_read(dev_id, phy_id, + QCA803X_1000BASET_STATUS); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (phy_data & QCA803X_LINK_1000BASETX_FULL_DUPLEX) + *ability |= FAL_PHY_PART_1000T_FD; + } + + return SW_OK; +} + +/****************************************************************************** +* +* qca803x_phy_reset_done - reset the phy +* +* reset the phy +*/ +a_bool_t qca803x_phy_reset_done(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + a_uint16_t ii = 200; + + do { + phy_data = + qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_CONTROL); + aos_mdelay(10); + } + while ((!QCA803X_RESET_DONE(phy_data)) && --ii); + + if (ii == 0) + return A_FALSE; + + return A_TRUE; +} + +/****************************************************************************** +* +* qca803x_autoneg_done +* +* qca803x_autoneg_done +*/ +a_bool_t qca803x_autoneg_done(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + a_uint16_t ii = 200; + + do { + phy_data = + qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_STATUS); + aos_mdelay(10); + } + while ((!QCA803X_AUTONEG_DONE(phy_data)) && --ii); + + if (ii == 0) + return A_FALSE; + + return A_TRUE; +} + +/****************************************************************************** +* +* qca803x_phy_Speed_Duplex_Resolved + - reset the phy +* +* reset the phy +*/ +a_bool_t qca803x_phy_speed_duplex_resolved(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + a_uint16_t ii = 200; + + do { + phy_data = + qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_SPEC_STATUS); + aos_mdelay(10); + } + while ((!QCA803X_SPEED_DUPLEX_RESOVLED(phy_data)) && --ii); + + if (ii == 0) + return A_FALSE; + + return A_TRUE; +} +#endif +/****************************************************************************** +* +* qca803x_phy_get_phy_id - get the phy id +* +*/ +sw_error_t +qca803x_phy_get_phy_id(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *phy_data) +{ + a_uint16_t org_id, rev_id; + + org_id = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_ID1); + rev_id = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_ID2); + + *phy_data = ((org_id & 0xffff) << 16) | (rev_id & 0xffff); + + return SW_OK; +} + +/****************************************************************************** +* +* qca803x_phy_off - power off the phy +* +* Power off the phy +*/ +sw_error_t qca803x_phy_poweroff(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_CONTROL); + PHY_RTN_ON_READ_ERROR(phy_data); + + qca803x_phy_reg_write(dev_id, phy_id, QCA803X_PHY_CONTROL, + phy_data | QCA803X_CTRL_POWER_DOWN); + return SW_OK; +} + +/****************************************************************************** +* +* qca803x_phy_on - power on the phy +* +* Power on the phy +*/ +sw_error_t qca803x_phy_poweron(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_CONTROL); + PHY_RTN_ON_READ_ERROR(phy_data); + + qca803x_phy_reg_write(dev_id, phy_id, QCA803X_PHY_CONTROL, + phy_data & ~QCA803X_CTRL_POWER_DOWN); + + aos_mdelay(200); + + return SW_OK; +} +#ifndef IN_PORTCONTROL_MINI +/****************************************************************************** +* +* qca803x_phy_set_802.3az +* +* set 802.3az status +*/ +sw_error_t +qca803x_phy_set_8023az(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable) +{ + a_uint16_t phy_data; + + phy_data = qca803x_phy_mmd_read(dev_id, phy_id, QCA803X_PHY_MMD7_NUM, + QCA803X_PHY_MMD7_ADDR_8023AZ_EEE_CTRL); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (enable == A_TRUE) { + phy_data |= 0x0006; + + qca803x_phy_mmd_write(dev_id, phy_id, QCA803X_PHY_MMD7_NUM, + QCA803X_PHY_MMD7_ADDR_8023AZ_EEE_CTRL, phy_data); + } else { + phy_data &= ~0x0006; + + qca803x_phy_mmd_write(dev_id, phy_id, QCA803X_PHY_MMD7_NUM, + QCA803X_PHY_MMD7_ADDR_8023AZ_EEE_CTRL, phy_data); + } + + qca803x_phy_restart_autoneg(dev_id, phy_id); + + return SW_OK; +} + +/****************************************************************************** +* +* qca803x_phy_get_8023az status +* +* get 8023az status +*/ +sw_error_t +qca803x_phy_get_8023az(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t * enable) +{ + a_uint16_t phy_data; + *enable = A_FALSE; + + phy_data = qca803x_phy_mmd_read(dev_id, phy_id, QCA803X_PHY_MMD7_NUM, + QCA803X_PHY_MMD7_ADDR_8023AZ_EEE_CTRL); + PHY_RTN_ON_READ_ERROR(phy_data); + + if ((phy_data & 0x0004) && (phy_data & 0x0002)) + *enable = A_TRUE; + + return SW_OK; +} + +/****************************************************************************** +* +* qca803x_phy_set_powersave - set power saving status +* +* set power saving status +*/ +sw_error_t +qca803x_phy_set_powersave(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable) +{ + a_uint16_t phy_data; + + phy_data = qca803x_phy_debug_read(dev_id, phy_id, QCA803X_PWR_SAVE); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (enable == A_TRUE) + phy_data = phy_data | QCA803X_PWR_SAVE_EN; + else + phy_data = phy_data & ~QCA803X_PWR_SAVE_EN; + + qca803x_phy_debug_write(dev_id, phy_id, QCA803X_PWR_SAVE, phy_data); + + qca803x_phy_restart_autoneg(dev_id, phy_id); + + return SW_OK; +} + +/****************************************************************************** +* +* qca803x_phy_get_powersave - get power saving status +* +* set power saving status +*/ +sw_error_t +qca803x_phy_get_powersave(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t * enable) +{ + a_uint16_t phy_data; + + phy_data = qca803x_phy_debug_read(dev_id, phy_id, QCA803X_PWR_SAVE); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (phy_data & QCA803X_PWR_SAVE_EN) + *enable = A_FALSE; + else + *enable = A_TRUE; + + return SW_OK; +} + +/****************************************************************************** +* +* qca803x_phy_set wol frame mac address +* +* set phy wol frame mac address +*/ +sw_error_t +qca803x_phy_set_magic_frame_mac(a_uint32_t dev_id, a_uint32_t phy_id, + fal_mac_addr_t * mac) +{ + a_uint16_t phy_data1; + a_uint16_t phy_data2; + a_uint16_t phy_data3; + + phy_data1 = (mac->uc[0] << 8) | mac->uc[1]; + phy_data2 = (mac->uc[2] << 8) | mac->uc[3]; + phy_data3 = (mac->uc[4] << 8) | mac->uc[5]; + + qca803x_phy_mmd_write(dev_id, phy_id, QCA803X_PHY_MMD3_NUM, + QCA803X_PHY_MMD3_WOL_MAGIC_MAC_CTRL1, phy_data1); + + qca803x_phy_mmd_write(dev_id, phy_id, QCA803X_PHY_MMD3_NUM, + QCA803X_PHY_MMD3_WOL_MAGIC_MAC_CTRL2, phy_data2); + + qca803x_phy_mmd_write(dev_id, phy_id, QCA803X_PHY_MMD3_NUM, + QCA803X_PHY_MMD3_WOL_MAGIC_MAC_CTRL3, phy_data3); + + return SW_OK; +} + +/****************************************************************************** +* +* qca803x_phy_get wol frame mac address +* +* get phy wol frame mac address +*/ +sw_error_t +qca803x_phy_get_magic_frame_mac(a_uint32_t dev_id, a_uint32_t phy_id, + fal_mac_addr_t * mac) +{ + a_uint16_t phy_data1; + a_uint16_t phy_data2; + a_uint16_t phy_data3; + + phy_data1 = qca803x_phy_mmd_read(dev_id, phy_id, QCA803X_PHY_MMD3_NUM, + QCA803X_PHY_MMD3_WOL_MAGIC_MAC_CTRL1); + + phy_data2 = qca803x_phy_mmd_read(dev_id, phy_id, QCA803X_PHY_MMD3_NUM, + QCA803X_PHY_MMD3_WOL_MAGIC_MAC_CTRL2); + + phy_data3 = qca803x_phy_mmd_read(dev_id, phy_id, QCA803X_PHY_MMD3_NUM, + QCA803X_PHY_MMD3_WOL_MAGIC_MAC_CTRL3); + + mac->uc[0] = (phy_data1 >> 8); + mac->uc[1] = (phy_data1 & 0x00ff); + mac->uc[2] = (phy_data2 >> 8); + mac->uc[3] = (phy_data2 & 0x00ff); + mac->uc[4] = (phy_data3 >> 8); + mac->uc[5] = (phy_data3 & 0x00ff); + + return SW_OK; +} + +/****************************************************************************** +* +* qca803x_phy_set wol enable or disable +* +* set phy wol enable or disable +*/ +sw_error_t +qca803x_phy_set_wol_status(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable) +{ + a_uint16_t phy_data; + phy_data = qca803x_phy_mmd_read(dev_id, phy_id, QCA803X_PHY_MMD3_NUM, + QCA803X_PHY_MMD3_WOL_CTRL); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (enable == A_TRUE) { + phy_data |= 0x0020; + } else { + phy_data &= ~0x0020; + } + + qca803x_phy_mmd_write(dev_id, phy_id, QCA803X_PHY_MMD3_NUM, + QCA803X_PHY_MMD3_WOL_CTRL, phy_data); + + return SW_OK; +} + +/****************************************************************************** +* +* qca803x_phy_get_wol status +* +* get wol status +*/ +sw_error_t +qca803x_phy_get_wol_status(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t * enable) +{ + a_uint16_t phy_data; + + *enable = A_FALSE; + + phy_data = qca803x_phy_mmd_read(dev_id, phy_id, QCA803X_PHY_MMD3_NUM, + QCA803X_PHY_MMD3_WOL_CTRL); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (phy_data & 0x0020) + *enable = A_TRUE; + + return SW_OK; +} + +/****************************************************************************** +* +* qca803x_phy_set_hibernate - set hibernate status +* +* set hibernate status +*/ +sw_error_t +qca803x_phy_set_hibernate(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable) +{ + a_uint16_t phy_data; + + phy_data = qca803x_phy_debug_read(dev_id, phy_id, + QCA803X_DEBUG_PHY_HIBERNATION_CTRL); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (enable == A_TRUE) { + phy_data |= 0x8000; + } else { + phy_data &= ~0x8000; + } + + qca803x_phy_debug_write(dev_id, phy_id, + QCA803X_DEBUG_PHY_HIBERNATION_CTRL, phy_data); + + return SW_OK; +} + +/****************************************************************************** +* +* qca803x_phy_get_hibernate - get hibernate status +* +* get hibernate status +*/ +sw_error_t +qca803x_phy_get_hibernate(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t * enable) +{ + a_uint16_t phy_data; + + *enable = A_FALSE; + + phy_data = qca803x_phy_debug_read(dev_id, phy_id, + QCA803X_DEBUG_PHY_HIBERNATION_CTRL); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (phy_data & 0x8000) + *enable = A_TRUE; + + return SW_OK; +} +#endif +sw_error_t +__phy_chip_config_get(a_uint32_t dev_id, a_uint32_t phy_id, + qca803x_cfg_type_t cfg_sel, qca803x_cfg_t *cfg_value) +{ + a_uint16_t phy_data; + phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_CHIP_CONFIG); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (cfg_sel == QCA803X_CHIP_CFG_STAT) + *cfg_value = (phy_data & QCA803X_PHY_CHIP_MODE_STAT) >> 4; + else + *cfg_value = phy_data & QCA803X_PHY_CHIP_MODE_CFG; + + return SW_OK; +} + +/****************************************************************************** +* +* qca803x_phy_interface mode set +* +* set qca803x phy interface mode +*/ +sw_error_t +qca803x_phy_interface_set_mode(a_uint32_t dev_id, a_uint32_t phy_id, fal_port_interface_mode_t interface_mode) +{ + a_uint16_t phy_data; + + QCA803X_REG_LOCK; + + phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_CHIP_CONFIG); + + phy_data &= 0xfff0; + + switch (interface_mode) { + case PORT_RGMII_BASET: + phy_data |= QCA803X_PHY_RGMII_BASET; + break; + case PHY_SGMII_BASET: + phy_data |= QCA803X_PHY_SGMII_BASET; + break; + case PORT_RGMII_BX1000: + phy_data |= QCA803X_PHY_BX1000_RGMII_50; + break; + case PORT_RGMII_FX100: + phy_data |= QCA803X_PHY_FX100_RGMII_50; + break; + case PORT_RGMII_AMDET: + phy_data |= QCA803X_PHY_RGMII_AMDET; + break; + default: + QCA803X_REG_UNLOCK; + return SW_BAD_PARAM; + } + + qca803x_phy_reg_write(dev_id, phy_id, QCA803X_PHY_CHIP_CONFIG, phy_data); + + QCA803X_REG_UNLOCK; + + /* reset operation */ + qca803x_phy_reset(dev_id, phy_id); + + return SW_OK; +} + +/****************************************************************************** +* +* qca803x_phy_interface mode get +* +* get qca803x phy interface mode +*/ +sw_error_t +qca803x_phy_interface_get_mode(a_uint32_t dev_id, a_uint32_t phy_id, fal_port_interface_mode_t *interface_mode) +{ + qca803x_cfg_t cfg_value; + SW_RTN_ON_ERROR(__phy_chip_config_get(dev_id, phy_id, + QCA803X_CHIP_CFG_SET, &cfg_value)); + + switch (cfg_value) { + case QCA803X_PHY_RGMII_BASET: + *interface_mode = PORT_RGMII_BASET; + break; + case QCA803X_PHY_SGMII_BASET: + *interface_mode = PHY_SGMII_BASET; + break; + case QCA803X_PHY_BX1000_RGMII_50: + *interface_mode = PORT_RGMII_BX1000; + break; + case QCA803X_PHY_FX100_RGMII_50: + *interface_mode = PORT_RGMII_FX100; + break; + case QCA803X_PHY_RGMII_AMDET: + *interface_mode = PORT_RGMII_AMDET; + break; + default: + *interface_mode = PORT_INTERFACE_MODE_MAX; + break; + } + + return SW_OK; +} + +/****************************************************************************** +* +* qca803x_phy_interface mode status get +* +* get qca803x phy interface mode status +*/ +sw_error_t +qca803x_phy_interface_get_mode_status(a_uint32_t dev_id, a_uint32_t phy_id, fal_port_interface_mode_t *interface_mode_status) +{ + qca803x_cfg_t cfg_value; + + SW_RTN_ON_ERROR(__phy_chip_config_get(dev_id, phy_id, + QCA803X_CHIP_CFG_STAT, &cfg_value)); + + switch (cfg_value) { + case QCA803X_PHY_RGMII_BASET: + *interface_mode_status = PORT_RGMII_BASET; + break; + case QCA803X_PHY_SGMII_BASET: + *interface_mode_status = PHY_SGMII_BASET; + break; + case QCA803X_PHY_BX1000_RGMII_50: + *interface_mode_status = PORT_RGMII_BX1000; + break; + case QCA803X_PHY_FX100_RGMII_50: + *interface_mode_status = PORT_RGMII_FX100; + break; + case QCA803X_PHY_RGMII_AMDET: + *interface_mode_status = PORT_RGMII_AMDET; + break; + default: + *interface_mode_status = PORT_INTERFACE_MODE_MAX; + break; + } + + return SW_OK; +} +#ifndef IN_PORTCONTROL_MINI +/****************************************************************************** +* +* qca803x_phy_set_intr_mask - Set interrupt mask with the +* specified device. +*/ +sw_error_t +qca803x_phy_set_intr_mask(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t intr_mask_flag) +{ + a_uint16_t phy_data = 0; + + phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_INTR_MASK); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (FAL_PHY_INTR_STATUS_UP_CHANGE & intr_mask_flag) { + phy_data |= QCA803X_INTR_STATUS_UP_CHANGE; + } else { + phy_data &= (~QCA803X_INTR_STATUS_UP_CHANGE); + } + + if (FAL_PHY_INTR_STATUS_DOWN_CHANGE & intr_mask_flag) { + phy_data |= QCA803X_INTR_STATUS_DOWN_CHANGE; + } else { + phy_data &= (~QCA803X_INTR_STATUS_DOWN_CHANGE); + } + + if (FAL_PHY_INTR_SPEED_CHANGE & intr_mask_flag) { + phy_data |= QCA803X_INTR_SPEED_CHANGE; + } else { + phy_data &= (~QCA803X_INTR_SPEED_CHANGE); + } + + /* DUPLEX INTR bit is reserved for AR803X phy + if (FAL_PHY_INTR_DUPLEX_CHANGE & intr_mask_flag) { + phy_data |= QCA803X_INTR_DUPLEX_CHANGE; + } else { + phy_data &= (~QCA803X_INTR_DUPLEX_CHANGE); + } + */ + + if (FAL_PHY_INTR_BX_FX_STATUS_UP_CHANGE & intr_mask_flag) { + phy_data |= QCA803X_INTR_BX_FX_STATUS_UP_CHANGE; + } else { + phy_data &= (~QCA803X_INTR_BX_FX_STATUS_UP_CHANGE); + } + + if (FAL_PHY_INTR_BX_FX_STATUS_DOWN_CHANGE & intr_mask_flag) { + phy_data |= QCA803X_INTR_BX_FX_STATUS_DOWN_CHANGE; + } else { + phy_data &= (~QCA803X_INTR_BX_FX_STATUS_DOWN_CHANGE); + } + + if (FAL_PHY_INTR_MEDIA_STATUS_CHANGE & intr_mask_flag) { + phy_data |= QCA803X_INTR_MEDIA_STATUS_CHANGE; + } else { + phy_data &= (~QCA803X_INTR_MEDIA_STATUS_CHANGE); + } + + if (FAL_PHY_INTR_WOL_STATUS & intr_mask_flag) { + phy_data |= QCA803X_INTR_WOL; + } else { + phy_data &= (~QCA803X_INTR_WOL); + } + + if (FAL_PHY_INTR_POE_STATUS & intr_mask_flag) { + phy_data |= QCA803X_INTR_POE; + } else { + phy_data &= (~QCA803X_INTR_POE); + } + + qca803x_phy_reg_write(dev_id, phy_id, QCA803X_PHY_INTR_MASK, phy_data); + return SW_OK; +} + +/****************************************************************************** +* +* qca803x_phy_get_intr_mask - Get interrupt mask with the +* specified device. +*/ +sw_error_t +qca803x_phy_get_intr_mask(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * intr_mask_flag) +{ + a_uint16_t phy_data = 0; + + phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_INTR_MASK); + PHY_RTN_ON_READ_ERROR(phy_data); + + *intr_mask_flag = 0; + if (QCA803X_INTR_STATUS_UP_CHANGE & phy_data) { + *intr_mask_flag |= FAL_PHY_INTR_STATUS_UP_CHANGE; + } + + if (QCA803X_INTR_STATUS_DOWN_CHANGE & phy_data) { + *intr_mask_flag |= FAL_PHY_INTR_STATUS_DOWN_CHANGE; + } + + if (QCA803X_INTR_SPEED_CHANGE & phy_data) { + *intr_mask_flag |= FAL_PHY_INTR_SPEED_CHANGE; + } + + /* DUPLEX INTR bit is reserved for AR803X phy + if (QCA803X_INTR_DUPLEX_CHANGE & phy_data) { + *intr_mask_flag |= FAL_PHY_INTR_DUPLEX_CHANGE; + } + */ + + if (QCA803X_INTR_BX_FX_STATUS_UP_CHANGE & phy_data) { + *intr_mask_flag |= FAL_PHY_INTR_BX_FX_STATUS_UP_CHANGE; + } + + if (QCA803X_INTR_BX_FX_STATUS_DOWN_CHANGE & phy_data) { + *intr_mask_flag |= FAL_PHY_INTR_BX_FX_STATUS_DOWN_CHANGE; + } + + if (QCA803X_INTR_MEDIA_STATUS_CHANGE & phy_data) { + *intr_mask_flag |= FAL_PHY_INTR_MEDIA_STATUS_CHANGE; + } + + if (QCA803X_INTR_WOL & phy_data) { + *intr_mask_flag |= FAL_PHY_INTR_WOL_STATUS; + } + + if (QCA803X_INTR_POE & phy_data) { + *intr_mask_flag |= FAL_PHY_INTR_POE_STATUS; + } + + return SW_OK; +} + +/****************************************************************************** +* +* qca803x_phy_get_intr_status - Get interrupt status with the +* specified device. +*/ +sw_error_t +qca803x_phy_get_intr_status(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * intr_status_flag) +{ + a_uint16_t phy_data = 0; + + phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_INTR_STATUS); + PHY_RTN_ON_READ_ERROR(phy_data); + + *intr_status_flag = 0; + if (QCA803X_INTR_STATUS_UP_CHANGE & phy_data) { + *intr_status_flag |= FAL_PHY_INTR_STATUS_UP_CHANGE; + } + + if (QCA803X_INTR_STATUS_DOWN_CHANGE & phy_data) { + *intr_status_flag |= FAL_PHY_INTR_STATUS_DOWN_CHANGE; + } + + if (QCA803X_INTR_SPEED_CHANGE & phy_data) { + *intr_status_flag |= FAL_PHY_INTR_SPEED_CHANGE; + } + + /* DUPLEX INTR bit is reserved for AR803X phy + if (QCA803X_INTR_DUPLEX_CHANGE & phy_data) { + *intr_status_flag |= FAL_PHY_INTR_DUPLEX_CHANGE; + } + */ + + if (QCA803X_INTR_BX_FX_STATUS_UP_CHANGE & phy_data) { + *intr_status_flag |= FAL_PHY_INTR_BX_FX_STATUS_UP_CHANGE; + } + + if (QCA803X_INTR_BX_FX_STATUS_DOWN_CHANGE & phy_data) { + *intr_status_flag |= FAL_PHY_INTR_BX_FX_STATUS_DOWN_CHANGE; + } + if (QCA803X_INTR_MEDIA_STATUS_CHANGE & phy_data) { + *intr_status_flag |= FAL_PHY_INTR_MEDIA_STATUS_CHANGE; + } + + if (QCA803X_INTR_WOL & phy_data) { + *intr_status_flag |= FAL_PHY_INTR_WOL_STATUS; + } + + if (QCA803X_INTR_POE & phy_data) { + *intr_status_flag |= FAL_PHY_INTR_POE_STATUS; + } + + return SW_OK; +} + +/****************************************************************************** +* +* qca803x_phy_set combo medium type +* +* set combo medium fiber or copper +*/ +sw_error_t +qca803x_phy_set_combo_prefer_medium(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_medium_t phy_medium) +{ + a_uint16_t phy_data; + + QCA803X_REG_LOCK; + + phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_CHIP_CONFIG); + + if (phy_medium == PHY_MEDIUM_FIBER) + phy_data |= QCA803X_PHY_PREFER_FIBER; + else if (phy_medium == PHY_MEDIUM_COPPER) + phy_data &= ~QCA803X_PHY_PREFER_FIBER; + else { + QCA803X_REG_UNLOCK; + return SW_BAD_PARAM; + } + + qca803x_phy_reg_write(dev_id, phy_id, QCA803X_PHY_CHIP_CONFIG, phy_data); + + QCA803X_REG_UNLOCK; + + /* soft reset after switching combo medium*/ + qca803x_phy_reset(dev_id, phy_id); + + return SW_OK; +} + +/****************************************************************************** +* +* qca803x_phy_get combo medium type +* +* get combo medium fiber or copper +*/ +sw_error_t +qca803x_phy_get_combo_prefer_medium(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_medium_t * phy_medium) +{ + a_uint16_t phy_data; + + phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_CHIP_CONFIG); + PHY_RTN_ON_READ_ERROR(phy_data); + + *phy_medium = + (phy_data & QCA803X_PHY_PREFER_FIBER) ? PHY_MEDIUM_FIBER : + PHY_MEDIUM_COPPER; + + return SW_OK; +} + +/****************************************************************************** +* +* qca803x phy activer medium +* +* get qca803x phy current active medium, fiber or copper; +*/ +static qca803x_phy_medium_t __phy_active_medium_get(a_uint32_t dev_id, + a_uint32_t phy_id) +{ + qca803x_cfg_t cfg_value; + + SW_RTN_ON_ERROR(__phy_chip_config_get(dev_id, phy_id, + QCA803X_CHIP_CFG_STAT, &cfg_value)); + + switch (cfg_value) { + case QCA803X_PHY_RGMII_BASET: + case QCA803X_PHY_SGMII_BASET: + return QCA803X_PHY_MEDIUM_COPPER; + case QCA803X_PHY_BX1000_RGMII_50: + case QCA803X_PHY_FX100_RGMII_50: + return QCA803X_PHY_MEDIUM_FIBER; + case QCA803X_PHY_RGMII_AMDET: + default: + return QCA803X_PHY_MEDIUM_MAX; + } +} + +/****************************************************************************** +* +* qca803x_phy_get current combo medium type copper or fiber +* +* get current combo medium type +*/ +sw_error_t +qca803x_phy_get_combo_current_medium_type(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_medium_t * phy_medium) +{ + qca803x_phy_medium_t phy_cur_meduim = __phy_active_medium_get(dev_id, phy_id); + + /* auto media select is not done + * or link down, then return prefer medium */ + if (phy_cur_meduim == QCA803X_PHY_MEDIUM_MAX) + qca803x_phy_get_combo_prefer_medium(dev_id, phy_id, phy_medium); + else + *phy_medium = phy_cur_meduim; + + return SW_OK; +} + +/****************************************************************************** +* +* qca803x_phy_set fiber mode 1000bx or 100fx +* +* set combo fbier mode +*/ +sw_error_t +qca803x_phy_set_combo_fiber_mode(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_fiber_mode_t fiber_mode) +{ + a_uint16_t phy_data; + + QCA803X_REG_LOCK; + + phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_CHIP_CONFIG); + + if (fiber_mode == PHY_FIBER_1000BX) { + phy_data |= QCA803X_PHY_FIBER_MODE_1000BX; + } else if (fiber_mode == PHY_FIBER_100FX) { + phy_data &= ~QCA803X_PHY_FIBER_MODE_1000BX; + } else { + QCA803X_REG_UNLOCK; + return SW_BAD_PARAM; + } + + qca803x_phy_reg_write(dev_id, phy_id, QCA803X_PHY_CHIP_CONFIG, phy_data); + + QCA803X_REG_UNLOCK; + + return SW_OK; +} + +/****************************************************************************** +* +* qca803x_phy_get fiber mode 1000bx or 100fx +* +* get combo fbier mode +*/ +sw_error_t +qca803x_phy_get_combo_fiber_mode(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_fiber_mode_t * fiber_mode) +{ + a_uint16_t phy_data; + + phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_CHIP_CONFIG); + PHY_RTN_ON_READ_ERROR(phy_data); + + *fiber_mode = + (phy_data & QCA803X_PHY_FIBER_MODE_1000BX) ? PHY_FIBER_1000BX : + PHY_FIBER_100FX; + + return SW_OK; +} + +/****************************************************************************** +* +* qca803x_phy_set_counter_status - set counter status +* +*/ +sw_error_t +qca803x_phy_set_counter_status(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t enable) +{ + a_uint16_t phy_data; + a_uint16_t frame_dir = 0; + + phy_data = qca803x_phy_mmd_read(dev_id, phy_id, + QCA803X_PHY_MMD7_NUM, + QCA803X_PHY_MMD7_FRAME_CTRL); + frame_dir = (phy_data & QCA803X_PHY_MMD7_FRAME_DIR) >> 14; + + /*for qca803x phy, tx and rx cannot be all enabled one time, + so we will enable tx or rx based current state, enable rx if + current is tx and enable tx if current is rx*/ + if (enable == A_TRUE) + { + phy_data |= QCA803X_PHY_MMD7_FRAME_CHECK; + /*enable RX counter*/ + if(frame_dir) + { + SSDK_INFO("ENABLE QCA803X RX COUNTER\n"); + phy_data &= ~QCA803X_PHY_MMD7_FRAME_DIR; + } + /*enable TX counter*/ + else + { + SSDK_INFO("ENABLE QCA803X TX COUNTER\n"); + phy_data |= QCA803X_PHY_MMD7_FRAME_DIR; + } + } + else + { + phy_data &= ~QCA803X_PHY_MMD7_FRAME_CHECK; + } + + qca803x_phy_mmd_write(dev_id, phy_id, QCA803X_PHY_MMD7_NUM, + QCA803X_PHY_MMD7_FRAME_CTRL, phy_data); + + return SW_OK; +} + +/****************************************************************************** +* +* qca803x_phy_get_counter_status - get counter status +* +*/ +sw_error_t +qca803x_phy_get_counter_status(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t * enable) +{ + a_uint16_t phy_data; + *enable = A_FALSE; + + phy_data = qca803x_phy_mmd_read(dev_id, phy_id, + QCA803X_PHY_MMD7_NUM, + QCA803X_PHY_MMD7_FRAME_CTRL); + + if (phy_data & QCA803X_PHY_MMD7_FRAME_CHECK) { + *enable = A_TRUE; + } + + return SW_OK; +} + +/****************************************************************************** +* +* qca803x_phy_show_counter - show counter statistics +* +*/ +sw_error_t +qca803x_phy_show_counter(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_counter_info_t * counter_infor) +{ + a_uint16_t phy_data, phy_data1; + a_uint16_t frame_dir = 0; + + phy_data = qca803x_phy_mmd_read(dev_id, phy_id, + QCA803X_PHY_MMD7_NUM, + QCA803X_PHY_MMD7_FRAME_CTRL); + phy_data1 = qca803x_phy_mmd_read(dev_id, phy_id, + QCA803X_PHY_MMD7_NUM, + QCA803X_PHY_MMD7_FRAME_DATA); + frame_dir = (phy_data & QCA803X_PHY_MMD7_FRAME_DIR) >> 14; + + if(frame_dir) + { + /*get the counter of tx*/ + counter_infor->TxGoodFrame = phy_data1 & QCA803X_PHY_FRAME_CNT; + counter_infor->TxBadCRC = (phy_data1 & QCA803X_PHY_FRAME_ERROR) >> 8; + counter_infor->RxGoodFrame = 0; + counter_infor->RxBadCRC = 0; + } + else + { + /*get the counter of rx*/ + counter_infor->TxGoodFrame = 0; + counter_infor->TxBadCRC = 0; + counter_infor->RxGoodFrame = phy_data1 & QCA803X_PHY_FRAME_CNT; + counter_infor->RxBadCRC = (phy_data1 & QCA803X_PHY_FRAME_ERROR) >> 8; + } + + return SW_OK; +} + +#endif +/****************************************************************************** +* +* qca803x_phy_get status +* +* get phy status +*/ +sw_error_t +qca803x_phy_get_status(a_uint32_t dev_id, a_uint32_t phy_id, + struct port_phy_status *phy_status) +{ + a_uint16_t phy_data, phy_data1; + + phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_SPEC_STATUS); + PHY_RTN_ON_READ_ERROR(phy_data); + phy_data1 = qca803x_phy_debug_read(dev_id, phy_id, + QCA803X_DEBUG_MSE_THRESH); + PHY_RTN_ON_READ_ERROR(phy_data1); + + /*get phy link status*/ + if (phy_data & QCA803X_STATUS_LINK_PASS) { + phy_status->link_status = A_TRUE; + if((phy_data1 & QCA803X_PHY_MSE_THRESH_MASK) != + QCA803X_PHY_MSE_THRESH_LINK_UP) { + phy_data1 &= ~QCA803X_PHY_MSE_THRESH_MASK; + SW_RTN_ON_ERROR(qca803x_phy_debug_write(dev_id, + phy_id, QCA803X_DEBUG_MSE_THRESH, + phy_data1 | QCA803X_PHY_MSE_THRESH_LINK_UP)); + } + } + else { + phy_status->link_status = A_FALSE; + if((phy_data1 & QCA803X_PHY_MSE_THRESH_MASK) != + QCA803X_PHY_MSE_THRESH_LINK_DOWN) { + phy_data1 &= ~QCA803X_PHY_MSE_THRESH_MASK; + SW_RTN_ON_ERROR(qca803x_phy_debug_write(dev_id, + phy_id, QCA803X_DEBUG_MSE_THRESH, + phy_data1 | QCA803X_PHY_MSE_THRESH_LINK_DOWN)); + } + return SW_OK; + } + + /*get phy speed*/ + switch (phy_data & QCA803X_STATUS_SPEED_MASK) { + case QCA803X_STATUS_SPEED_1000MBS: + phy_status->speed = FAL_SPEED_1000; + break; + case QCA803X_STATUS_SPEED_100MBS: + phy_status->speed = FAL_SPEED_100; + break; + case QCA803X_STATUS_SPEED_10MBS: + phy_status->speed = FAL_SPEED_10; + break; + default: + return SW_READ_ERROR; + } + + /*get phy duplex*/ + if (phy_data & QCA803X_STATUS_FULL_DUPLEX) + phy_status->duplex = FAL_FULL_DUPLEX; + else + phy_status->duplex = FAL_HALF_DUPLEX; + + /* get phy flowctrl resolution status */ + if (phy_data & QCA803X_PHY_RX_FLOWCTRL_STATUS) + phy_status->rx_flowctrl = A_TRUE; + else + phy_status->rx_flowctrl = A_FALSE; + + if (phy_data & QCA803X_PHY_TX_FLOWCTRL_STATUS) + phy_status->tx_flowctrl = A_TRUE; + else + phy_status->tx_flowctrl = A_FALSE; + + return SW_OK; +} +/****************************************************************************** +* +* qca803x_phy_set_eee_advertisement +* +* set eee advertisement +*/ +sw_error_t +qca803x_phy_set_eee_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t adv) +{ + a_uint16_t phy_data = 0; + sw_error_t rv = SW_OK; + + phy_data = qca803x_phy_mmd_read(dev_id, phy_id, QCA803X_PHY_MMD7_NUM, + QCA803X_PHY_MMD7_ADDR_8023AZ_EEE_CTRL); + phy_data &= ~(QCA803X_PHY_EEE_ADV_100M | QCA803X_PHY_EEE_ADV_1000M); + + if (adv & FAL_PHY_EEE_100BASE_T) { + phy_data |= QCA803X_PHY_EEE_ADV_100M; + } + if (adv & FAL_PHY_EEE_1000BASE_T) { + phy_data |= QCA803X_PHY_EEE_ADV_1000M; + } + + rv = qca803x_phy_mmd_write(dev_id, phy_id, QCA803X_PHY_MMD7_NUM, + QCA803X_PHY_MMD7_ADDR_8023AZ_EEE_CTRL, phy_data); + + rv = qca803x_phy_restart_autoneg(dev_id, phy_id); + + return rv; +} + +/****************************************************************************** +* +* qca803x_phy_get_eee_advertisement +* +* get eee advertisement +*/ +sw_error_t +qca803x_phy_get_eee_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *adv) +{ + a_uint16_t phy_data = 0; + sw_error_t rv = SW_OK; + + *adv = 0; + phy_data = qca803x_phy_mmd_read(dev_id, phy_id, QCA803X_PHY_MMD7_NUM, + QCA803X_PHY_MMD7_ADDR_8023AZ_EEE_CTRL); + + if (phy_data & QCA803X_PHY_EEE_ADV_100M) { + *adv |= FAL_PHY_EEE_100BASE_T; + } + if (phy_data & QCA803X_PHY_EEE_ADV_1000M) { + *adv |= FAL_PHY_EEE_1000BASE_T; + } + + return rv; +} +/****************************************************************************** +* +* qca803x_phy_get_eee_partner_advertisement +* +* get eee partner advertisement +*/ +sw_error_t +qca803x_phy_get_eee_partner_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *adv) +{ + a_uint16_t phy_data = 0; + sw_error_t rv = SW_OK; + + *adv = 0; + phy_data = qca803x_phy_mmd_read(dev_id, phy_id, QCA803X_PHY_MMD7_NUM, + QCA803X_PHY_MMD7_ADDR_8023AZ_EEE_PARTNER); + + if (phy_data & QCA803X_PHY_EEE_PARTNER_ADV_100M) { + *adv |= FAL_PHY_EEE_100BASE_T; + } + if (phy_data & QCA803X_PHY_EEE_PARTNER_ADV_1000M) { + *adv |= FAL_PHY_EEE_1000BASE_T; + } + + return rv; +} +/****************************************************************************** +* +* qca803x_phy_get_eee_capability +* +* get eee capability +*/ +sw_error_t +qca803x_phy_get_eee_cap(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *cap) +{ + a_uint16_t phy_data = 0; + sw_error_t rv = SW_OK; + + *cap = 0; + phy_data = qca803x_phy_mmd_read(dev_id, phy_id, QCA803X_PHY_MMD3_NUM, + QCA803X_PHY_MMD3_ADDR_8023AZ_EEE_CAPABILITY); + + if (phy_data & QCA803X_PHY_EEE_CAPABILITY_100M) { + *cap |= FAL_PHY_EEE_100BASE_T; + } + if (phy_data & QCA803X_PHY_EEE_CAPABILITY_1000M) { + *cap |= FAL_PHY_EEE_1000BASE_T; + } + + return rv; +} +/****************************************************************************** +* +* qca803x_phy_get_eee_status +* +* get eee status +*/ +sw_error_t +qca803x_phy_get_eee_status(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *status) +{ + a_uint16_t phy_data = 0; + sw_error_t rv = SW_OK; + + *status = 0; + phy_data = qca803x_phy_mmd_read(dev_id, phy_id, QCA803X_PHY_MMD7_NUM, + QCA803X_PHY_MMD7_ADDR_8023AZ_EEE_STATUS); + + if (phy_data & QCA803X_PHY_EEE_STATUS_100M) { + *status |= FAL_PHY_EEE_100BASE_T; + } + if (phy_data & QCA803X_PHY_EEE_STATUS_1000M) { + *status |= FAL_PHY_EEE_1000BASE_T; + } + + return rv; +} + +static sw_error_t qca803x_phy_api_ops_init(void) +{ + sw_error_t ret = SW_OK; + hsl_phy_ops_t *qca803x_phy_api_ops = NULL; + + qca803x_phy_api_ops = kzalloc(sizeof(hsl_phy_ops_t), GFP_KERNEL); + if (qca803x_phy_api_ops == NULL) { + SSDK_ERROR("qca803x phy ops kzalloc failed!\n"); + return -ENOMEM; + } + + phy_api_ops_init(QCA803X_PHY_CHIP); + + qca803x_phy_api_ops->phy_speed_get = qca803x_phy_get_speed; + qca803x_phy_api_ops->phy_speed_set = qca803x_phy_set_speed; + qca803x_phy_api_ops->phy_duplex_get = qca803x_phy_get_duplex; + qca803x_phy_api_ops->phy_duplex_set = qca803x_phy_set_duplex; + qca803x_phy_api_ops->phy_autoneg_enable_set = qca803x_phy_enable_autoneg; + qca803x_phy_api_ops->phy_restart_autoneg = qca803x_phy_restart_autoneg; + qca803x_phy_api_ops->phy_autoneg_status_get = qca803x_phy_autoneg_status; + qca803x_phy_api_ops->phy_autoneg_adv_set = qca803x_phy_set_autoneg_adv; + qca803x_phy_api_ops->phy_autoneg_adv_get = qca803x_phy_get_autoneg_adv; + qca803x_phy_api_ops->phy_link_status_get = qca803x_phy_get_link_status; + qca803x_phy_api_ops->phy_reset = qca803x_phy_reset; +#ifndef IN_PORTCONTROL_MINI + qca803x_phy_api_ops->phy_powersave_set = qca803x_phy_set_powersave; + qca803x_phy_api_ops->phy_powersave_get = qca803x_phy_get_powersave; + qca803x_phy_api_ops->phy_cdt = qca803x_phy_cdt; + qca803x_phy_api_ops->phy_mdix_set = qca803x_phy_set_mdix; + qca803x_phy_api_ops->phy_mdix_get = qca803x_phy_get_mdix; + qca803x_phy_api_ops->phy_mdix_status_get = qca803x_phy_get_mdix_status; + qca803x_phy_api_ops->phy_local_loopback_set = qca803x_phy_set_local_loopback; + qca803x_phy_api_ops->phy_local_loopback_get = qca803x_phy_get_local_loopback; + qca803x_phy_api_ops->phy_remote_loopback_set = qca803x_phy_set_remote_loopback; + qca803x_phy_api_ops->phy_remote_loopback_get = qca803x_phy_get_remote_loopback; +#endif + qca803x_phy_api_ops->phy_reg_write = qca803x_phy_reg_write; + qca803x_phy_api_ops->phy_reg_read = qca803x_phy_reg_read; + qca803x_phy_api_ops->phy_debug_write = qca803x_phy_debug_write; + qca803x_phy_api_ops->phy_debug_read = qca803x_phy_debug_read; + qca803x_phy_api_ops->phy_mmd_write = qca803x_phy_mmd_write; + qca803x_phy_api_ops->phy_mmd_read = qca803x_phy_mmd_read; + qca803x_phy_api_ops->phy_id_get = qca803x_phy_get_phy_id; + qca803x_phy_api_ops->phy_power_off = qca803x_phy_poweroff; + qca803x_phy_api_ops->phy_power_on = qca803x_phy_poweron; +#ifndef IN_PORTCONTROL_MINI + qca803x_phy_api_ops->phy_8023az_set = qca803x_phy_set_8023az; + qca803x_phy_api_ops->phy_8023az_get = qca803x_phy_get_8023az; + qca803x_phy_api_ops->phy_hibernation_set = qca803x_phy_set_hibernate; + qca803x_phy_api_ops->phy_hibernation_get = qca803x_phy_get_hibernate; + qca803x_phy_api_ops->phy_magic_frame_mac_set = qca803x_phy_set_magic_frame_mac; + qca803x_phy_api_ops->phy_magic_frame_mac_get = qca803x_phy_get_magic_frame_mac; + qca803x_phy_api_ops->phy_wol_status_set = qca803x_phy_set_wol_status; + qca803x_phy_api_ops->phy_wol_status_get = qca803x_phy_get_wol_status; +#endif + qca803x_phy_api_ops->phy_interface_mode_set = qca803x_phy_interface_set_mode; + qca803x_phy_api_ops->phy_interface_mode_get = qca803x_phy_interface_get_mode; + qca803x_phy_api_ops->phy_interface_mode_status_get = qca803x_phy_interface_get_mode_status; +#ifndef IN_PORTCONTROL_MINI + qca803x_phy_api_ops->phy_intr_mask_set = qca803x_phy_set_intr_mask; + qca803x_phy_api_ops->phy_intr_mask_get = qca803x_phy_get_intr_mask; + qca803x_phy_api_ops->phy_intr_status_get = qca803x_phy_get_intr_status; + qca803x_phy_api_ops->phy_combo_prefer_medium_set = qca803x_phy_set_combo_prefer_medium; + qca803x_phy_api_ops->phy_combo_prefer_medium_get = qca803x_phy_get_combo_prefer_medium; + qca803x_phy_api_ops->phy_combo_medium_status_get = qca803x_phy_get_combo_current_medium_type; + qca803x_phy_api_ops->phy_combo_fiber_mode_set = qca803x_phy_set_combo_fiber_mode; + qca803x_phy_api_ops->phy_combo_fiber_mode_get = qca803x_phy_get_combo_fiber_mode; + qca803x_phy_api_ops->phy_counter_set = qca803x_phy_set_counter_status; + qca803x_phy_api_ops->phy_counter_get = qca803x_phy_get_counter_status; + qca803x_phy_api_ops->phy_counter_show = qca803x_phy_show_counter; +#endif + qca803x_phy_api_ops->phy_get_status = qca803x_phy_get_status; + qca803x_phy_api_ops->phy_eee_adv_set = qca803x_phy_set_eee_adv; + qca803x_phy_api_ops->phy_eee_adv_get = qca803x_phy_get_eee_adv; + qca803x_phy_api_ops->phy_eee_partner_adv_get = qca803x_phy_get_eee_partner_adv; + qca803x_phy_api_ops->phy_eee_cap_get = qca803x_phy_get_eee_cap; + qca803x_phy_api_ops->phy_eee_status_get = qca803x_phy_get_eee_status; + + ret = hsl_phy_api_ops_register(QCA803X_PHY_CHIP, qca803x_phy_api_ops); + + if (ret == SW_OK) + SSDK_INFO("qca probe qca803x phy driver succeeded!\n"); + else + SSDK_ERROR("qca probe qca803x phy driver failed! (code: %d)\n", ret); + + return ret; +} + +static sw_error_t +_qca803x_phy_set_combo_page_regs(a_uint32_t dev_id, a_uint32_t phy_id, + qca803x_phy_medium_t phy_medium) +{ + a_uint16_t phy_data; + + phy_data = qca803x_phy_reg_read(dev_id, phy_id, QCA803X_PHY_CHIP_CONFIG); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (phy_medium == QCA803X_PHY_MEDIUM_FIBER) { + phy_data &= ~QCA803X_PHY_COPPER_PAGE_SEL; + } + else if (phy_medium == QCA803X_PHY_MEDIUM_COPPER) { + phy_data |= QCA803X_PHY_COPPER_PAGE_SEL; + } + else { + return SW_BAD_PARAM; + } + + qca803x_phy_reg_write(dev_id, phy_id, QCA803X_PHY_CHIP_CONFIG, phy_data); + + return SW_OK; +} + +void qca803x_combo_phy_polling(qca803x_priv_t *priv) +{ + + qca803x_cfg_t cfg_value; + a_uint32_t combo_phy_addr = 0; + a_uint32_t combo_bits = priv->combo_phy_bmp; + qca803x_phy_medium_t combo_cfg_new = QCA803X_PHY_MEDIUM_COPPER; + + while (combo_bits) { + if (combo_bits & 1) { + QCA803X_REG_LOCK; + __phy_chip_config_get(priv->dev_id, combo_phy_addr, + QCA803X_CHIP_CFG_STAT, &cfg_value); + + switch (cfg_value) { + case QCA803X_PHY_RGMII_BASET: + case QCA803X_PHY_SGMII_BASET: + combo_cfg_new = QCA803X_PHY_MEDIUM_COPPER; + break; + case QCA803X_PHY_BX1000_RGMII_50: + case QCA803X_PHY_FX100_RGMII_50: + combo_cfg_new = QCA803X_PHY_MEDIUM_FIBER; + break; + default: + combo_cfg_new = QCA803X_PHY_MEDIUM_COPPER; + } + + if (priv->combo_cfg[combo_phy_addr] != combo_cfg_new) { + priv->combo_cfg[combo_phy_addr] = combo_cfg_new; + _qca803x_phy_set_combo_page_regs(priv->dev_id, combo_phy_addr, combo_cfg_new); + } + + QCA803X_REG_UNLOCK; + } + combo_bits >>= 1; + combo_phy_addr++; + } +} + +void +qca803x_phy_polling_work(struct work_struct *work) +{ + qca803x_priv_t *priv = container_of(work, qca803x_priv_t, + phy_sync_dwork.work); + qca803x_combo_phy_polling(priv); + + schedule_delayed_work(&priv->phy_sync_dwork, + QCA803X_PHY_DELAYED_INIT_TICKS); +} + +sw_error_t +qca803x_phy_work_start(a_uint32_t dev_id) +{ + qca803x_priv_t *priv = &g_qca803x_phy; + priv->dev_id = dev_id; + + INIT_DELAYED_WORK(&priv->phy_sync_dwork, + qca803x_phy_polling_work); + schedule_delayed_work(&priv->phy_sync_dwork, + QCA803X_PHY_DELAYED_INIT_TICKS); + return SW_OK; +} + +/****************************************************************************** +* +* qca803x_phy_hw_init +* +*/ +sw_error_t +qca803x_phy_hw_init(a_uint32_t dev_id, a_uint32_t port_bmp) +{ + sw_error_t ret = SW_OK; + a_uint32_t port_id = 0, phy_addr = 0, mac_mode = 0; + a_uint16_t phy_data= 0; + + for (port_id = 0; port_id < SW_MAX_NR_PORT; port_id ++) + { + if (port_bmp & (0x1 << port_id)) + { + /*config phy mode based on the mac mode DT*/ + switch (port_id) { + case SSDK_PHYSICAL_PORT0: + mac_mode = ssdk_dt_global_get_mac_mode(dev_id, SSDK_UNIPHY_INSTANCE0); + break; + case SSDK_PHYSICAL_PORT6: + mac_mode = ssdk_dt_global_get_mac_mode(dev_id, SSDK_UNIPHY_INSTANCE2); + break; + default: + mac_mode = PORT_WRAPPER_MAX; + } + + phy_addr = qca_ssdk_port_to_phy_addr(dev_id, port_id); + if (mac_mode == PORT_WRAPPER_SGMII_CHANNEL0) + qca803x_phy_interface_set_mode(dev_id, phy_addr, PHY_SGMII_BASET); + else if (mac_mode == PORT_WRAPPER_RGMII) + qca803x_phy_interface_set_mode(dev_id, phy_addr, PORT_RGMII_BASET); + + if (A_TRUE == hsl_port_phy_combo_capability_get(dev_id, port_id)) { + g_qca803x_phy.combo_phy_bmp |= (0x1 << phy_addr); + qca803x_phy_interface_set_mode(dev_id, phy_addr, PORT_RGMII_AMDET); + } + /*config the times that MSE is over threshold as max*/ + phy_data = qca803x_phy_debug_read(dev_id, phy_addr, + QCA803X_DEBUG_MSE_OVER_THRESH_TIMES); + PHY_RTN_ON_READ_ERROR(phy_data); + ret = qca803x_phy_debug_write(dev_id, phy_addr, + QCA803X_DEBUG_MSE_OVER_THRESH_TIMES, phy_data | + QCA803X_PHY_MSE_OVER_THRESH_TIMES_MAX); + SW_RTN_ON_ERROR(ret); + } + } + + /* start polling task for the combo port */ + if (g_qca803x_phy.combo_phy_bmp) + qca803x_phy_work_start(dev_id); + + return ret; +} + +/****************************************************************************** +* +* qca803x_phy_init - +* +*/ +int qca803x_phy_init(a_uint32_t dev_id, a_uint32_t port_bmp) +{ + static a_uint32_t phy_ops_flag = 0; + + if(phy_ops_flag == 0) { + QCA803X_LOCKER_INIT; + qca803x_phy_api_ops_init(); + phy_ops_flag = 1; + } + + qca803x_phy_hw_init(dev_id, port_bmp); + return 0; +} diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/qca808x.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/qca808x.c new file mode 100755 index 000000000..bdb37f2d0 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/qca808x.c @@ -0,0 +1,595 @@ +/* + * 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 "qca808x.h" + +#if defined(IN_PHY_I2C_MODE) +#include "sfp_phy.h" +#endif + +#define PHY_INVALID_DATA 0xffff +#define QCA808X_INTR_INIT 0xec00 + +#define QCA808X_PHY_LINK_UP 1 +#define QCA808X_PHY_LINK_DOWN 0 + +LIST_HEAD(g_qca808x_phy_list); + +struct qca808x_phy_info* qca808x_phy_info_get(a_uint32_t phy_addr) +{ + struct qca808x_phy_info *pdata = NULL; + list_for_each_entry(pdata, &g_qca808x_phy_list, list) { + if (pdata->phydev_addr == phy_addr) { + return pdata; + } + } + + SSDK_ERROR("%s can't get the data for phy addr: %d\n", __func__, phy_addr); + return NULL; +} + +static sw_error_t qca808x_phy_config_init(struct phy_device *phydev) +{ + a_uint16_t phy_data; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)) + a_uint32_t features; +#else + __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; +#endif + a_uint32_t dev_id = 0, phy_id = 0; + qca808x_priv *priv = phydev->priv; + struct qca808x_phy_info *pdata = priv->phy_info; + + if (!pdata) { + return SW_NOT_FOUND; + } + + dev_id = pdata->dev_id; + phy_id = pdata->phy_addr; + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)) + features = SUPPORTED_TP | SUPPORTED_MII | + SUPPORTED_AUI | SUPPORTED_BNC; +#else + linkmode_set_bit(ETHTOOL_LINK_MODE_TP_BIT, mask); + linkmode_set_bit(ETHTOOL_LINK_MODE_MII_BIT, mask); + linkmode_set_bit(ETHTOOL_LINK_MODE_AUI_BIT, mask); + linkmode_set_bit(ETHTOOL_LINK_MODE_BNC_BIT, mask); +#endif + + phy_data = qca808x_phy_reg_read(dev_id, + phy_id, QCA808X_PHY_STATUS); + + if (phy_data == PHY_INVALID_DATA) { + return SW_READ_ERROR; + } + + if (phy_data & QCA808X_STATUS_AUTONEG_CAPS) { +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)) + features |= SUPPORTED_Autoneg; +#else + linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, mask); +#endif + } + if (phy_data & QCA808X_STATUS_100TX_FD_CAPS) { +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)) + features |= SUPPORTED_100baseT_Full; +#else + linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, mask); +#endif + } + if (phy_data & QCA808X_STATUS_100TX_HD_CAPS) { +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)) + features |= SUPPORTED_100baseT_Half; +#else + linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, mask); +#endif + } + if (phy_data & QCA808X_STATUS_10T_FD_CAPS) { +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)) + features |= SUPPORTED_10baseT_Full; +#else + linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, mask); +#endif + } + if (phy_data & QCA808X_STATUS_10T_HD_CAPS) { +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)) + features |= SUPPORTED_10baseT_Half; +#else + linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, mask); +#endif + } + + if (phy_data & QCA808X_STATUS_EXTENDED_STATUS) { + phy_data = qca808x_phy_reg_read(dev_id, + phy_id, QCA808X_EXTENDED_STATUS); + + if (phy_data == PHY_INVALID_DATA) { + return SW_READ_ERROR; + } + if (phy_data & QCA808X_STATUS_1000T_FD_CAPS) { +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)) + features |= SUPPORTED_1000baseT_Full; +#else + linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, + mask); +#endif + } + if (phy_data & QCA808X_STATUS_1000T_HD_CAPS) { +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)) + features |= SUPPORTED_1000baseT_Half; +#else + linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, + mask); +#endif + } + } + + phy_data = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD1_NUM, + QCA808X_MMD1_PMA_CAP_REG); + + if (phy_data & QCA808X_STATUS_2500T_FD_CAPS) { +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)) + features |= SUPPORTED_2500baseX_Full; +#else + linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, mask); +#endif + } + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)) + phydev->supported = features; + phydev->advertising = features; +#else + linkmode_copy(phydev->supported, mask); + linkmode_copy(phydev->advertising, mask); +#endif + + return SW_OK; +} + +static int qca808x_config_init(struct phy_device *phydev) +{ + int ret = 0; +#if defined(IN_LINUX_STD_PTP) + /* ptp function initialization */ + ret |= qca808x_ptp_config_init(phydev); +#endif + + ret |= qca808x_phy_config_init(phydev); + + return ret; +} + +static int qca808x_config_intr(struct phy_device *phydev) +{ + int err; + a_uint16_t phy_data; + a_uint32_t dev_id = 0, phy_id = 0; + qca808x_priv *priv = phydev->priv; + const struct qca808x_phy_info *pdata = priv->phy_info; + + if (!pdata) { + return SW_FAIL; + } + + dev_id = pdata->dev_id; + phy_id = pdata->phy_addr; + + phy_data = qca808x_phy_reg_read(dev_id, phy_id, + QCA808X_PHY_INTR_MASK); + + if (phydev->interrupts == PHY_INTERRUPT_ENABLED) { + err = qca808x_phy_reg_write(dev_id, phy_id, + QCA808X_PHY_INTR_MASK, + phy_data | QCA808X_INTR_INIT); + } else { + err = qca808x_phy_reg_write(dev_id, phy_id, + QCA808X_PHY_INTR_MASK, 0); + } + + return err; +} + +static int qca808x_ack_interrupt(struct phy_device *phydev) +{ + int err; + a_uint32_t dev_id = 0, phy_id = 0; + qca808x_priv *priv = phydev->priv; + const struct qca808x_phy_info *pdata = priv->phy_info; + + if (!pdata) { + return SW_FAIL; + } + + dev_id = pdata->dev_id; + phy_id = pdata->phy_addr; + + err = qca808x_phy_reg_read(dev_id, phy_id, + QCA808X_PHY_INTR_STATUS); + + return (err < 0) ? err : 0; +} + +/* switch linux negtiation capability to fal avariable */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)) +static a_uint32_t qca808x_negtiation_cap_get(struct phy_device *phydev) +{ + a_uint32_t autoneg = 0; + a_uint32_t advertise = phydev->advertising & phydev->supported; + + if (advertise & ADVERTISED_Pause) { + autoneg |= FAL_PHY_ADV_PAUSE; + } + if (advertise & ADVERTISED_Asym_Pause) { + autoneg |= FAL_PHY_ADV_ASY_PAUSE; + } + if (advertise & ADVERTISED_10baseT_Half) { + autoneg |= FAL_PHY_ADV_10T_HD; + } + if (advertise & ADVERTISED_10baseT_Full) { + autoneg |= FAL_PHY_ADV_10T_FD; + } + if (advertise & ADVERTISED_100baseT_Half) { + autoneg |= FAL_PHY_ADV_100TX_HD; + } + if (advertise & ADVERTISED_100baseT_Full) { + autoneg |= FAL_PHY_ADV_100TX_FD; + } + if (advertise & ADVERTISED_1000baseT_Full) { + autoneg |= FAL_PHY_ADV_1000T_FD; + } + if (advertise & ADVERTISED_2500baseX_Full) { + autoneg |= FAL_PHY_ADV_2500T_FD; + } + + return autoneg; +} +#else +static a_uint32_t qca808x_negtiation_cap_get(struct phy_device *phydev) +{ + a_uint32_t autoneg = 0; + __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising) = { 0, }; + + linkmode_and(advertising, phydev->advertising, phydev->supported); + + if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, advertising)) { + autoneg |= FAL_PHY_ADV_PAUSE; + } + if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, advertising)) { + autoneg |= FAL_PHY_ADV_ASY_PAUSE; + } + if (linkmode_test_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, advertising)) { + autoneg |= FAL_PHY_ADV_10T_HD; + } + if (linkmode_test_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, advertising)) { + autoneg |= FAL_PHY_ADV_10T_FD; + } + if (linkmode_test_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, advertising)) { + autoneg |= FAL_PHY_ADV_100TX_HD; + } + if (linkmode_test_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, advertising)) { + autoneg |= FAL_PHY_ADV_100TX_FD; + } + if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, advertising)) { + autoneg |= FAL_PHY_ADV_1000T_FD; + } + if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, advertising)) { + autoneg |= FAL_PHY_ADV_2500T_FD; + } + + return autoneg; +} +#endif + +static int qca808x_config_aneg(struct phy_device *phydev) +{ + a_uint32_t advertise = 0; + a_uint16_t phy_data = 0; + int err = 0; + a_uint32_t dev_id = 0, phy_id = 0; + qca808x_priv *priv = phydev->priv; + const struct qca808x_phy_info *pdata = priv->phy_info; + + if (!pdata) { + return SW_FAIL; + } + + dev_id = pdata->dev_id; + phy_id = pdata->phy_addr; + if (phydev->autoneg != AUTONEG_ENABLE) + { + /* force speed */ + phydev->pause = 0; + phydev->asym_pause = 0; + + phy_data = qca808x_phy_reg_read(dev_id, phy_id, QCA808X_PHY_CONTROL); + phy_data &= ~QCA808X_CTRL_AUTONEGOTIATION_ENABLE; + if (phydev->duplex == FAL_FULL_DUPLEX) { + phy_data |= QCA808X_CTRL_FULL_DUPLEX; + } else { + phy_data &= ~QCA808X_CTRL_FULL_DUPLEX; + } + qca808x_phy_reg_write(dev_id, phy_id, QCA808X_PHY_CONTROL, phy_data); + err = qca808x_phy_set_force_speed(dev_id, phy_id, phydev->speed); + } else { + /* autoneg enabled */ + advertise = qca808x_negtiation_cap_get(phydev); + err |= qca808x_phy_set_autoneg_adv(dev_id, phy_id, advertise); + err |= qca808x_phy_restart_autoneg(dev_id, phy_id); + } + + return err; +} + +static int qca808x_aneg_done(struct phy_device *phydev) +{ + + a_uint16_t phy_data; + a_uint32_t dev_id = 0, phy_id = 0; + qca808x_priv *priv = phydev->priv; + const struct qca808x_phy_info *pdata = priv->phy_info; + + if (!pdata) { + return SW_FAIL; + } + + dev_id = pdata->dev_id; + phy_id = pdata->phy_addr; + + phy_data = qca808x_phy_reg_read(dev_id, phy_id, + QCA808X_PHY_STATUS); + + return (phy_data < 0) ? phy_data : (phy_data & QCA808X_STATUS_AUTO_NEG_DONE); +} + +static int qca808x_read_status(struct phy_device *phydev) +{ + struct port_phy_status phy_status; + a_uint32_t dev_id = 0, phy_id = 0; + qca808x_priv *priv = phydev->priv; + const struct qca808x_phy_info *pdata = priv->phy_info; + + if (!pdata) { + return SW_FAIL; + } + + dev_id = pdata->dev_id; + phy_id = pdata->phy_addr; + + qca808x_phy_get_status(dev_id, phy_id, &phy_status); + + if (phy_status.link_status) { + phydev->link = QCA808X_PHY_LINK_UP; + } else { + phydev->link = QCA808X_PHY_LINK_DOWN; + } + + switch (phy_status.speed) { + case FAL_SPEED_2500: + phydev->speed = SPEED_2500; + break; + case FAL_SPEED_1000: + phydev->speed = SPEED_1000; + break; + case FAL_SPEED_100: + phydev->speed = SPEED_100; + break; + default: + phydev->speed = SPEED_10; + break; + } + + if (phy_status.duplex == FAL_FULL_DUPLEX) { + phydev->duplex = DUPLEX_FULL; + } else { + phydev->duplex = DUPLEX_HALF; + } + + return 0; +} + +static int qca808x_suspend(struct phy_device *phydev) +{ + a_uint32_t dev_id = 0, phy_id = 0; + qca808x_priv *priv = phydev->priv; + const struct qca808x_phy_info *pdata = priv->phy_info; + + if (!pdata) { + return SW_FAIL; + } + + dev_id = pdata->dev_id; + phy_id = pdata->phy_addr; + + return qca808x_phy_poweroff(dev_id, phy_id); +} + +static int qca808x_resume(struct phy_device *phydev) +{ + a_uint32_t dev_id = 0, phy_id = 0; + qca808x_priv *priv = phydev->priv; + const struct qca808x_phy_info *pdata = priv->phy_info; + + if (!pdata) { + return SW_FAIL; + } + + dev_id = pdata->dev_id; + phy_id = pdata->phy_addr; + + return qca808x_phy_poweron(dev_id, phy_id); +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) +static int qca808x_soft_reset(struct phy_device *phydev) +{ + a_uint32_t dev_id = 0, phy_id = 0; + qca808x_priv *priv = phydev->priv; + const struct qca808x_phy_info *pdata = priv->phy_info; + + if (!pdata) { + return SW_FAIL; + } + + dev_id = pdata->dev_id; + phy_id = pdata->phy_addr; + + return qca808x_phy_reset(dev_id, phy_id); +} + +static void qca808x_link_change_notify(struct phy_device *phydev) +{ +#if defined(IN_LINUX_STD_PTP) + qca808x_ptp_change_notify(phydev); +#endif +} +#endif + +static int qca808x_phy_probe(struct phy_device *phydev) +{ + qca808x_priv *priv; + int err = 0; + + priv = kzalloc(sizeof(qca808x_priv), GFP_KERNEL); + if (!priv) { + return -ENOMEM; + } + + priv->phydev = phydev; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)) + priv->phy_info = qca808x_phy_info_get(phydev->addr); +#else + priv->phy_info = qca808x_phy_info_get(phydev->mdio.addr); +#endif + phydev->priv = priv; + +#if defined(IN_LINUX_STD_PTP) + err = qca808x_ptp_init(priv); +#endif + + return err; +} + +static void qca808x_phy_remove(struct phy_device *phydev) +{ + qca808x_priv *priv = phydev->priv; + +#if defined(IN_LINUX_STD_PTP) + qca808x_ptp_deinit(priv); +#endif + kfree(priv); +} + +struct phy_driver qca808x_phy_driver = { + .phy_id = QCA8081_PHY_V1_1, + .phy_id_mask = 0xffffffff, + .name = "QCA808X ethernet", + .features = PHY_GBIT_FEATURES, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)) + .flags = PHY_HAS_INTERRUPT, +#endif + .probe = qca808x_phy_probe, + .remove = qca808x_phy_remove, + .config_init = qca808x_config_init, + .config_intr = qca808x_config_intr, + .config_aneg = qca808x_config_aneg, + .aneg_done = qca808x_aneg_done, + .ack_interrupt = qca808x_ack_interrupt, + .read_status = qca808x_read_status, + .suspend = qca808x_suspend, + .resume = qca808x_resume, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) + .soft_reset = qca808x_soft_reset, + .link_change_notify = qca808x_link_change_notify, +#endif +#if defined(IN_LINUX_STD_PTP) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) + .ts_info = qca808x_ts_info, +#endif + .hwtstamp = qca808x_hwtstamp, + .rxtstamp = qca808x_rxtstamp, + .txtstamp = qca808x_txtstamp, +#endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,9,0)) + .mdiodrv.driver = { .owner = THIS_MODULE }, +#else + .driver = { .owner = THIS_MODULE }, +#endif +}; + +a_int32_t qca808x_phy_driver_register(void) +{ + a_int32_t ret; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,9,0)) + ret = phy_driver_register(&qca808x_phy_driver, THIS_MODULE); +#else + ret = phy_driver_register(&qca808x_phy_driver); +#endif + return ret; +} + +void qca808x_phy_driver_unregister(void) +{ + phy_driver_unregister(&qca808x_phy_driver); +} + +void qca808x_phydev_init(a_uint32_t dev_id, a_uint32_t port_id) +{ + struct qca808x_phy_info *pdata; + pdata = kzalloc(sizeof(struct qca808x_phy_info), GFP_KERNEL); + + if (!pdata) { + return; + } + list_add_tail(&pdata->list, &g_qca808x_phy_list); + pdata->dev_id = dev_id; + /* the phy address may be the i2c slave addr or mdio addr */ + pdata->phy_addr = qca_ssdk_port_to_phy_addr(dev_id, port_id); + pdata->phydev_addr = pdata->phy_addr; +#if defined(IN_PHY_I2C_MODE) + /* in i2c mode, need to register a fake phy device + * before the phy driver register */ + if (hsl_port_phy_access_type_get(dev_id, port_id) == PHY_I2C_ACCESS) { + a_uint32_t phy_id = 0; + sw_error_t ret = SW_OK; + ret = qca808x_phy_get_phy_id(dev_id, pdata->phy_addr, &phy_id); + if (ret != SW_OK) { + SSDK_ERROR("%s fail to get phy id\n", __func__); + return; + } + if(phy_id == INVALID_PHY_ID) { + phy_id = QCA8081_PHY_V1_1; + } + pdata->phydev_addr = qca_ssdk_port_to_phy_mdio_fake_addr(dev_id, port_id); + sfp_phy_device_setup(dev_id, port_id, phy_id); + } +#endif +} + +void qca808x_phydev_deinit(a_uint32_t dev_id, a_uint32_t port_id) +{ + struct qca808x_phy_info *pdata, *pnext; + +#if defined(IN_PHY_I2C_MODE) + /* in i2c mode, need to remove the fake phy device + * after the phy driver unregistered */ + if (hsl_port_phy_access_type_get(dev_id, port_id) == PHY_I2C_ACCESS) { + sfp_phy_device_remove(dev_id, port_id); + } +#endif + list_for_each_entry_safe(pdata, pnext, &g_qca808x_phy_list, list) { + list_del(&pdata->list); + kfree(pdata); + } +} diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/qca808x_led.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/qca808x_led.c new file mode 100644 index 000000000..7abca48bc --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/qca808x_led.c @@ -0,0 +1,272 @@ +/* + * 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 "sw.h" +#include "hsl_phy.h" +#include "ssdk_plat.h" +#include "qca808x_phy.h" +#include "qca808x_led.h" + +static sw_error_t +_qca808x_phy_led_active_set(a_uint32_t dev_id, a_uint32_t phy_id, + led_ctrl_pattern_t *pattern) +{ + sw_error_t rv = SW_OK; + a_uint16_t phy_data = 0; + + phy_data= qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD7_NUM, + QCA808X_PHY_MMD7_LED_POLARITY_CTRL); + PHY_RTN_ON_READ_ERROR(phy_data); + if(pattern->map & BIT(LED_ACTIVE_HIGH)) + { + phy_data |= QCA808X_PHY_MMD7_LED_POLARITY_MASK; + } + else + { + phy_data &= ~QCA808X_PHY_MMD7_LED_POLARITY_MASK; + } + rv = qca808x_phy_mmd_write(dev_id, phy_id, QCA808X_PHY_MMD7_NUM, + QCA808X_PHY_MMD7_LED_POLARITY_CTRL, phy_data); + + return rv; +} + +static sw_error_t +_qca808x_phy_led_active_get(a_uint32_t dev_id, a_uint32_t phy_id, + led_ctrl_pattern_t *pattern) +{ + a_uint16_t phy_data = 0; + + phy_data = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD7_NUM, + QCA808X_PHY_MMD7_LED_POLARITY_CTRL); + PHY_RTN_ON_READ_ERROR(phy_data); + if(phy_data & QCA808X_PHY_MMD7_LED_POLARITY_MASK) + { + pattern->map |= BIT(LED_ACTIVE_HIGH); + } + + return SW_OK; +} + +static sw_error_t +_qca808x_phy_led_pattern_map_from_phy(a_uint32_t dev_id, a_uint32_t phy_id, + led_ctrl_pattern_t *pattern, a_uint16_t *phy_data) +{ + if (qca808x_phy_2500caps(dev_id, phy_id) == A_TRUE) + { + if(*phy_data & QCA808X_PHY_LINK_2500M_LIGHT_EN) + { + pattern->map |= BIT(LINK_2500M_LIGHT_EN); + } + } + if(*phy_data & QCA808X_PHY_LINK_1000M_LIGHT_EN) + { + pattern->map |= BIT(LINK_1000M_LIGHT_EN); + } + if(*phy_data & QCA808X_PHY_LINK_100M_LIGHT_EN) + { + pattern->map |= BIT(LINK_100M_LIGHT_EN); + } + if(*phy_data & QCA808X_PHY_LINK_10M_LIGHT_EN) + { + pattern->map |= BIT(LINK_10M_LIGHT_EN); + } + if (*phy_data & QCA808X_PHY_RX_TRAFFIC_BLINK_EN) + { + pattern->map |= BIT(RX_TRAFFIC_BLINK_EN); + } + if (*phy_data & QCA808X_PHY_TX_TRAFFIC_BLINK_EN) + { + pattern->map |= BIT(TX_TRAFFIC_BLINK_EN); + } + + return SW_OK; +} + +static sw_error_t +_qca808x_phy_led_pattern_map_to_phy(a_uint32_t dev_id, a_uint32_t phy_id, + led_ctrl_pattern_t *pattern, a_uint32_t *led_map) +{ + if (qca808x_phy_2500caps(dev_id, phy_id) == A_TRUE) + { + if (pattern->map & BIT(LINK_2500M_LIGHT_EN)) + { + *led_map |= QCA808X_PHY_LINK_2500M_LIGHT_EN; + } + } + if (pattern->map & BIT(LINK_1000M_LIGHT_EN)) + { + *led_map |= QCA808X_PHY_LINK_1000M_LIGHT_EN; + } + if (pattern->map & BIT(LINK_100M_LIGHT_EN)) + { + *led_map |= QCA808X_PHY_LINK_100M_LIGHT_EN; + } + if (pattern->map & BIT(LINK_10M_LIGHT_EN)) + { + *led_map |= QCA808X_PHY_LINK_10M_LIGHT_EN; + } + if (pattern->map & BIT(RX_TRAFFIC_BLINK_EN)) + { + *led_map |= QCA808X_PHY_RX_TRAFFIC_BLINK_EN; + } + if (pattern->map & BIT(TX_TRAFFIC_BLINK_EN)) + { + *led_map |= QCA808X_PHY_TX_TRAFFIC_BLINK_EN; + } + + return SW_OK; +} + +/****************************************************************************** +* +* qca808x_phy_led_ctrl_pattern_set +* +*/ +sw_error_t +qca808x_phy_led_ctrl_pattern_set(a_uint32_t dev_id, a_uint32_t phy_id, + led_ctrl_pattern_t *pattern) +{ + sw_error_t rv = SW_OK; + a_uint32_t source_id = 0; + + if(LED_PATTERN_MAP_EN != pattern->mode) + { + SSDK_ERROR("led mode %d is not supported\n", pattern->mode); + return SW_NOT_SUPPORTED; + } + for(source_id = QCA808X_PHY_LED_SOURCE0; source_id <= QCA808X_PHY_LED_SOURCE2; + source_id++) + { + /*three source use the same pattern*/ + rv = qca808x_phy_led_ctrl_source_set (dev_id, phy_id, source_id, pattern); + SW_RTN_ON_ERROR(rv); + } + + return rv; +} + +/****************************************************************************** +* +* qca808x_phy_led_ctrl_pattern_get +* +*/ +sw_error_t +qca808x_phy_led_ctrl_pattern_get(a_uint32_t dev_id, a_uint32_t phy_id, + led_ctrl_pattern_t *pattern) +{ + sw_error_t rv = SW_OK; + + /*three source use the same pattern*/ + rv = qca808x_phy_led_ctrl_source_get(dev_id, phy_id, QCA808X_PHY_LED_SOURCE0, + pattern); + + return rv; +} + +/****************************************************************************** +* +* qca808x_phy_led_source_pattern_set +* +*/ +sw_error_t +qca808x_phy_led_ctrl_source_set(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t source_id, led_ctrl_pattern_t *pattern) +{ + sw_error_t rv = SW_OK; + a_uint32_t led_map = 0; + a_uint16_t led_mmd_addr = 0; + + if(LED_PATTERN_MAP_EN != pattern->mode) + { + return SW_NOT_SUPPORTED; + } + + rv = _qca808x_phy_led_active_set(dev_id, phy_id, pattern); + SW_RTN_ON_ERROR(rv); + rv = _qca808x_phy_led_pattern_map_to_phy(dev_id, phy_id, pattern, &led_map); + SW_RTN_ON_ERROR(rv); + switch(source_id) + { + case QCA808X_PHY_LED_SOURCE0: + led_mmd_addr = QCA808X_PHY_MMD7_LED0_CTRL; + break; + case QCA808X_PHY_LED_SOURCE1: + led_mmd_addr = QCA808X_PHY_MMD7_LED1_CTRL; + break; + case QCA808X_PHY_LED_SOURCE2: + led_mmd_addr = QCA808X_PHY_MMD7_LED2_CTRL; + break; + default: + SSDK_ERROR("source %d is not support\n", source_id); + break; + } + rv = qca808x_phy_mmd_write(dev_id, phy_id, QCA808X_PHY_MMD7_NUM, + led_mmd_addr, led_map); + + return rv; +} +/****************************************************************************** +* +* qca808x_phy_led_source_pattern_get +* +*/ +sw_error_t +qca808x_phy_led_ctrl_source_get(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t source_id, led_ctrl_pattern_t *pattern) +{ + sw_error_t rv = SW_OK; + a_uint16_t phy_data = 0, led_mmd_addr = 0; + + pattern->map = 0; + pattern->mode = LED_PATTERN_MAP_EN; + rv = _qca808x_phy_led_active_get(dev_id, phy_id, pattern); + SW_RTN_ON_ERROR(rv); + switch(source_id) + { + case QCA808X_PHY_LED_SOURCE0: + led_mmd_addr = QCA808X_PHY_MMD7_LED0_CTRL; + break; + case QCA808X_PHY_LED_SOURCE1: + led_mmd_addr = QCA808X_PHY_MMD7_LED1_CTRL; + break; + case QCA808X_PHY_LED_SOURCE2: + led_mmd_addr = QCA808X_PHY_MMD7_LED2_CTRL; + break; + default: + SSDK_ERROR("source %d is not support\n", source_id); + break; + } + phy_data = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD7_NUM, + led_mmd_addr); + PHY_RTN_ON_READ_ERROR(phy_data); + rv = _qca808x_phy_led_pattern_map_from_phy(dev_id, phy_id, pattern, + &phy_data); + + return rv; +} + +void qca808x_phy_led_api_ops_init(hsl_phy_ops_t *qca808x_phy_led_api_ops) +{ + if (!qca808x_phy_led_api_ops) { + return; + } + qca808x_phy_led_api_ops->phy_led_ctrl_pattern_get = qca808x_phy_led_ctrl_pattern_get; + qca808x_phy_led_api_ops->phy_led_ctrl_pattern_set = qca808x_phy_led_ctrl_pattern_set; + qca808x_phy_led_api_ops->phy_led_ctrl_source_set = qca808x_phy_led_ctrl_source_set; + + return; +} diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/qca808x_phc.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/qca808x_phc.c new file mode 100755 index 000000000..648ffaa95 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/qca808x_phc.c @@ -0,0 +1,1472 @@ +/* + * 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 +#include +#include + +#include "qca808x.h" + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) +#include +#else +#include +#define ns_to_timespec64 ns_to_timespec +#define timespec64_to_ns timespec_to_ns +#define timespec64 timespec +#endif + +#include "qca808x_ptp.h" +#include "qca808x_ptp_reg.h" +#include "qca808x_ptp_api.h" + +#define QCA808X_PTP_EMBEDDED_MODE 0xa + +#define QCA808X_PTP_INCVAL_SYNC_MODE 0x8 +#define QCA808X_PTP_TICK_RATE_125M 8 +#define QCA808X_PTP_TICK_RATE_200M 5 + +#define PTP_HDR_RESERVED0_OFFSET 1 +#define PTP_HDR_RESERVED1_OFFSET 5 +#define PTP_HDR_CORRECTIONFIELD_OFFSET 8 +#define PTP_HDR_RESERVED2_OFFSET 16 + +#define SKB_TIMESTAMP_TIMEOUT 1 /* jiffies */ +#define GPS_WORK_TIMEOUT HZ + +#define HWTSTAMP_TX_ONESTEP_P2P (HWTSTAMP_TX_ONESTEP_SYNC + 1) + +extern struct list_head g_qca808x_phy_list; +void qca808x_ptp_gm_gps_seconds_sync_enable(a_uint32_t dev_id, + a_uint32_t phy_addr, a_bool_t en) +{ + struct qca808x_phy_info *pdata; +#if defined(IN_PHY_I2C_MODE) + a_uint32_t port_id; + port_id = qca_ssdk_phy_addr_to_port(dev_id, phy_addr); + if (hsl_port_phy_access_type_get(dev_id, port_id) == PHY_I2C_ACCESS) { + phy_addr = qca_ssdk_port_to_phy_mdio_fake_addr(dev_id, port_id); + } +#endif + + pdata = qca808x_phy_info_get(phy_addr); + if (pdata) { + pdata->gps_seconds_sync_en = en; + } + + if (en == A_TRUE) { + schedule_delayed_work(&pdata->ts_schedule_work, GPS_WORK_TIMEOUT); + } + + return; +} + +a_bool_t qca808x_ptp_gm_gps_seconds_sync_status_get(a_uint32_t dev_id, + a_uint32_t phy_addr) +{ + struct qca808x_phy_info *pdata; +#if defined(IN_PHY_I2C_MODE) + a_uint32_t port_id; + port_id = qca_ssdk_phy_addr_to_port(dev_id, phy_addr); + if (hsl_port_phy_access_type_get(dev_id, port_id) == PHY_I2C_ACCESS) { + phy_addr = qca_ssdk_port_to_phy_mdio_fake_addr(dev_id, port_id); + } +#endif + + pdata = qca808x_phy_info_get(phy_addr); + if (pdata) { + return pdata->gps_seconds_sync_en; + } + + return A_FALSE; +} + +void qca808x_ptp_clock_mode_config(a_uint32_t dev_id, + a_uint32_t phy_addr, a_uint16_t clock_mode, a_uint16_t step_mode) +{ + struct qca808x_phy_info *pdata; +#if defined(IN_PHY_I2C_MODE) + a_uint32_t port_id; + port_id = qca_ssdk_phy_addr_to_port(dev_id, phy_addr); + if (hsl_port_phy_access_type_get(dev_id, port_id) == PHY_I2C_ACCESS) { + phy_addr = qca_ssdk_port_to_phy_mdio_fake_addr(dev_id, port_id); + } +#endif + + pdata = qca808x_phy_info_get(phy_addr); + + if (pdata) { + pdata->clock_mode = clock_mode; + pdata->step_mode = step_mode; + } + + return; +} + +void qca808x_ptp_stat_update(struct qca808x_phy_info *pdata, fal_ptp_direction_t direction, + a_int32_t msg_type, a_int32_t seqid_matched) +{ + ptp_packet_stat *pkt_stat = NULL; + + if (((direction != FAL_RX_DIRECTION) && (direction != FAL_TX_DIRECTION)) || + (seqid_matched < PTP_PKT_SEQID_UNMATCHED) || + (seqid_matched >= PTP_PKT_SEQID_MATCH_MAX)) { + return; + } + + pkt_stat = &pdata->pkt_stat[direction]; + switch (msg_type) { + case QCA808X_PTP_MSG_SYNC: + pkt_stat->sync_cnt[seqid_matched]++; + break; + case QCA808X_PTP_MSG_DREQ: + pkt_stat->delay_req_cnt[seqid_matched]++; + break; + case QCA808X_PTP_MSG_PREQ: + pkt_stat->pdelay_req_cnt[seqid_matched]++; + break; + case QCA808X_PTP_MSG_PRESP: + pkt_stat->pdelay_resp_cnt[seqid_matched]++; + break; + case QCA808X_PTP_MSG_MAX: + pkt_stat->event_pkt_cnt++; + break; + default: + SSDK_DEBUG("%s: msg %x is not event frame\n", + __func__, msg_type); + } +} + +void qca808x_ptp_stat_get(void) +{ + int i = 0; + struct qca808x_phy_info *pdata = NULL; + ptp_packet_stat *pkt_stat; + + list_for_each_entry(pdata, &g_qca808x_phy_list, list) { + pkt_stat = pdata->pkt_stat; + SSDK_INFO("PHY [%#x] PTP event packet statistics:\n", pdata->phy_addr); + for (i=0; i <= FAL_TX_DIRECTION; i++) + { + if (i == FAL_TX_DIRECTION) { + SSDK_INFO("----------TX direction----------\n"); + } else { + SSDK_INFO("----------RX direction----------\n"); + } + + SSDK_INFO("even sum: %lld\n", + pkt_stat[i].event_pkt_cnt); + SSDK_INFO("seq id matched stat:\n"); + SSDK_INFO("sync: %lld\n", + pkt_stat[i].sync_cnt[PTP_PKT_SEQID_MATCHED]); + SSDK_INFO("delay_req: %lld\n", + pkt_stat[i].delay_req_cnt[PTP_PKT_SEQID_MATCHED]); + SSDK_INFO("pdelay_req: %lld\n", + pkt_stat[i].pdelay_req_cnt[PTP_PKT_SEQID_MATCHED]); + SSDK_INFO("pdelay_resp: %lld\n\n", + pkt_stat[i].pdelay_resp_cnt[PTP_PKT_SEQID_MATCHED]); + + SSDK_INFO("seq id unmatched stat:\n"); + SSDK_INFO("sync: %lld\n", + pkt_stat[i].sync_cnt[PTP_PKT_SEQID_UNMATCHED]); + SSDK_INFO("delay_req: %lld\n", + pkt_stat[i].delay_req_cnt[PTP_PKT_SEQID_UNMATCHED]); + SSDK_INFO("pdelay_req: %lld\n", + pkt_stat[i].pdelay_req_cnt[PTP_PKT_SEQID_UNMATCHED]); + SSDK_INFO("pdelay_resp: %lld\n\n", + pkt_stat[i].pdelay_resp_cnt[PTP_PKT_SEQID_UNMATCHED]); + } + } +} + +void qca808x_ptp_stat_set(void) +{ + struct qca808x_phy_info *pdata; + + list_for_each_entry(pdata, &g_qca808x_phy_list, list) { + memset(pdata->pkt_stat, 0, sizeof(pdata->pkt_stat)); + } +} + +static sw_error_t qca808x_ptp_clock_synce_clock_enable(a_uint32_t dev_id, + a_uint32_t phy_id, a_bool_t enable) +{ + a_uint16_t phy_data, phy_data1; + sw_error_t ret = SW_OK; + + phy_data = qca808x_phy_debug_read(dev_id, phy_id, + QCA808X_DEBUG_ANA_CLOCK_CTRL_REG); + + phy_data1 = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD7_NUM, + QCA808X_MMD7_CLOCK_CTRL_REG); + + if (enable == A_TRUE) { + /* enable analog synce clock output */ + phy_data |= QCA808X_ANALOG_PHY_SYNCE_CLOCK_EN; + /* enable digital synce clock output */ + phy_data1 |= QCA808X_DIGITAL_PHY_SYNCE_CLOCK_EN; + } else { + phy_data &= ~QCA808X_ANALOG_PHY_SYNCE_CLOCK_EN; + phy_data1 &= ~QCA808X_DIGITAL_PHY_SYNCE_CLOCK_EN; + } + + ret = qca808x_phy_debug_write(dev_id, phy_id, + QCA808X_DEBUG_ANA_CLOCK_CTRL_REG, phy_data); + + ret |= qca808x_phy_mmd_write(dev_id, phy_id, QCA808X_PHY_MMD7_NUM, + QCA808X_MMD7_CLOCK_CTRL_REG, phy_data1); + return ret; +} + +static sw_error_t qca808x_ptp_clock_incval_mode_set(a_uint32_t dev_id, + a_uint32_t phy_id, a_bool_t enable) +{ + a_uint16_t phy_data; + sw_error_t ret = SW_OK; + + phy_data = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD3_NUM, + PTP_RTC_EXT_CONF_REG_ADDRESS); + + if (enable == A_TRUE) { + phy_data |= QCA808X_PTP_INCVAL_SYNC_MODE; + } else { + phy_data &= ~QCA808X_PTP_INCVAL_SYNC_MODE; + } + + ret = qca808x_phy_mmd_write(dev_id, phy_id, QCA808X_PHY_MMD3_NUM, + PTP_RTC_EXT_CONF_REG_ADDRESS, phy_data); + + return ret; +} + +sw_error_t qca808x_ptp_config_init(struct phy_device *phydev) +{ + fal_ptp_config_t ptp_config; + fal_ptp_reference_clock_t ptp_ref_clock; + fal_ptp_rx_timestamp_mode_t rx_ts_mode; + fal_ptp_time_t ptp_time = {0}; + sw_error_t ret = SW_OK; + a_uint32_t dev_id = 0, phy_id = 0; + qca808x_priv *priv = phydev->priv; + const struct qca808x_phy_info *pdata = priv->phy_info; + struct qca808x_ptp_info *ptp_info = &priv->ptp_info; + + if (!pdata) { + return SW_FAIL; + } + + dev_id = pdata->dev_id; + phy_id = pdata->phy_addr; + + /* disable ptp function by default */ + ptp_info->hwts_tx_type = HWTSTAMP_TX_OFF; + ptp_info->hwts_rx_type = PTP_CLASS_NONE; + + ptp_config.ptp_en = A_FALSE; + ptp_config.clock_mode = FAL_OC_CLOCK_MODE; + ptp_config.step_mode = FAL_TWO_STEP_MODE; + ret = qca808x_phy_ptp_config_set(dev_id, phy_id, &ptp_config); + + qca808x_ptp_clock_mode_config(dev_id, phy_id, ptp_config.clock_mode, + ptp_config.step_mode); + + /* set rtc clock to asynchronization mode*/ + ret |= qca808x_ptp_clock_incval_mode_set(dev_id, phy_id, A_FALSE); + + /* adjust frequency to 8ns(125MHz) */ + ptp_time.nanoseconds = QCA808X_PTP_TICK_RATE_125M; + ret |= qca808x_phy_ptp_rtc_adjfreq_set(dev_id, phy_id, &ptp_time); + + /* use SyncE reference clock */ + ptp_ref_clock = FAL_REF_CLOCK_SYNCE; + ret |= qca808x_phy_ptp_reference_clock_set(dev_id, phy_id, ptp_ref_clock); + + /* use Embed mode to get RX timestamp */ + rx_ts_mode = FAL_RX_TS_EMBED; + ret |= qca808x_phy_ptp_rx_timestamp_mode_set(dev_id, phy_id, rx_ts_mode); + + /* disable SYNCE clock output */ + ret |= qca808x_ptp_clock_synce_clock_enable(dev_id, phy_id, A_FALSE); + + if (ret != SW_OK) { + SSDK_ERROR("%s failed\n", __func__); + } + + return ret; +} + +static a_uint8_t* skb_ptp_header(struct sk_buff *skb, int type) +{ + a_uint8_t *data = skb_mac_header(skb); + a_uint32_t offset = 0; + + if (type & PTP_CLASS_VLAN) { + offset += VLAN_HLEN; + } + + switch (type & PTP_CLASS_PMASK) { + case PTP_CLASS_IPV4: + offset += ETH_HLEN + IPV4_HLEN(data + offset) + UDP_HLEN; + break; + case PTP_CLASS_IPV6: + offset += ETH_HLEN + IP6_HLEN + UDP_HLEN; + break; + case PTP_CLASS_L2: + offset += ETH_HLEN; + break; + default: + return NULL; + } + + if (skb->len + ETH_HLEN < offset + + OFF_PTP_SEQUENCE_ID + sizeof(a_uint16_t)) { + return NULL; + } + + return data + offset; +} + +void qca808x_pkt_info_get(struct sk_buff *skb, + unsigned int type, fal_ptp_pkt_info_t *pkt_info) +{ + a_uint16_t *seqid, seqid_pkt; + a_uint32_t *clockid; + a_uint32_t clockid_lo; + a_uint64_t clockid_pkt; + a_uint16_t *portid, portid_pkt; + a_uint8_t msgtype_pkt; + a_uint8_t *ptp_header = NULL; + + ptp_header = skb_ptp_header(skb, type); + if (!ptp_header) { + return; + } + +#define OFF_PTP_CLOCK_ID 20 +#define OFF_PTP_PORT_ID 28 + + seqid = (a_uint16_t *)(ptp_header + OFF_PTP_SEQUENCE_ID); + seqid_pkt = ntohs(*seqid); + clockid = (a_uint32_t *)(ptp_header + OFF_PTP_CLOCK_ID); + clockid_pkt = ntohl(*clockid); + + clockid = (a_uint32_t *)(ptp_header + OFF_PTP_CLOCK_ID + 4); + clockid_lo = ntohl(*clockid); + clockid_pkt = (clockid_pkt << 32) | clockid_lo; + portid = (a_uint16_t *)(ptp_header + OFF_PTP_PORT_ID); + portid_pkt = ntohs(*portid); + msgtype_pkt = (*ptp_header) & 0xf; + + pkt_info->sequence_id = seqid_pkt; + pkt_info->clock_identify = clockid_pkt; + pkt_info->port_number = portid_pkt; + pkt_info->msg_type = msgtype_pkt; + return ; +} + +static void tx_timestamp_work(struct work_struct *work) +{ + struct sk_buff *skb; + struct skb_shared_hwtstamps shhwtstamps; + struct timespec64 ts; + a_uint64_t ns; + a_uint32_t dev_id, phy_id; + qca808x_ptp_cb *ptp_cb; + struct qca808x_phy_info *pdata; + fal_ptp_pkt_info_t pkt_info; + fal_ptp_time_t tx_time = {0}; + sw_error_t ret = SW_OK; + a_uint16_t times = 0; + a_uint16_t seqid = 0; + struct qca808x_ptp_info *ptp_data = + container_of(work, struct qca808x_ptp_info, tx_ts_work.work); + + qca808x_priv *priv = + container_of(ptp_data, qca808x_priv, ptp_info); + + pdata = priv->phy_info; + + if (!pdata) { + return; + } + + dev_id = pdata->dev_id; + phy_id = pdata->phy_addr; + + memset(&shhwtstamps, 0, sizeof(shhwtstamps)); + + while ((skb = skb_dequeue(&ptp_data->tx_queue))) { + ptp_cb = (qca808x_ptp_cb *)skb->cb; + qca808x_pkt_info_get(skb, ptp_cb->ptp_type, &pkt_info); + + times = 0; + do { + /* poll the seqid of the transmitted ptp packet to + * acquire the correspoding tx time stamp. + */ + seqid = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD3_NUM, + PTP_TX_SEQID_REG_ADDRESS); + udelay(1); + times++; + } while (seqid != pkt_info.sequence_id && times < 100); + + ret = qca808x_phy_ptp_timestamp_get(dev_id, phy_id, + FAL_TX_DIRECTION, &pkt_info, &tx_time); + + if (ret == SW_NOT_FOUND) { + qca808x_ptp_stat_update(pdata, FAL_TX_DIRECTION, + pkt_info.msg_type, PTP_PKT_SEQID_UNMATCHED); + SSDK_DEBUG("Fail to get tx_ts: sequence_id:%x, clock_identify:%llx," + " port_number:%x, msg_type:%x\n", + pkt_info.sequence_id, pkt_info.clock_identify, + pkt_info.port_number, pkt_info.msg_type); + } else { + qca808x_ptp_stat_update(pdata, FAL_TX_DIRECTION, + pkt_info.msg_type, PTP_PKT_SEQID_MATCHED); + } + ts.tv_sec = tx_time.seconds; + ts.tv_nsec = tx_time.nanoseconds; + + ns = timespec64_to_ns(&ts); + + shhwtstamps.hwtstamp = ns_to_ktime(ns); + skb_complete_tx_timestamp(skb, &shhwtstamps); + } + + if (!skb_queue_empty(&ptp_data->tx_queue)) + schedule_delayed_work(&ptp_data->tx_ts_work, SKB_TIMESTAMP_TIMEOUT); +} + +static void ptp_ingress_time_sync(a_uint32_t phy_addr, a_uint32_t ingress_time, + a_bool_t forward) +{ + fal_ptp_time_t ingress_trig_time = {0}; + struct qca808x_phy_info *pdata = NULL; + + ingress_trig_time.nanoseconds = ingress_time; + + if (forward == A_FALSE) { + list_for_each_entry(pdata, &g_qca808x_phy_list, list) { + if (pdata->phydev_addr == phy_addr) { + qca808x_phy_ptp_pkt_timestamp_set(pdata->dev_id, + pdata->phy_addr, &ingress_trig_time); + break; + } + } + } else { + list_for_each_entry(pdata, &g_qca808x_phy_list, list) { + if (pdata->phydev_addr != phy_addr) { + qca808x_phy_ptp_pkt_timestamp_set(pdata->dev_id, + pdata->phy_addr, &ingress_trig_time); + } + } + } +} + +static void rx_timestamp_work(struct work_struct *work) +{ + struct sk_buff *skb; + struct skb_shared_hwtstamps *shhwtstamps = NULL; + struct timespec64 ts; + a_uint64_t ns; + a_uint32_t dev_id, phy_id; + qca808x_ptp_cb *ptp_cb; + struct qca808x_phy_info *pdata; + fal_ptp_pkt_info_t pkt_info; + fal_ptp_time_t rx_time = {0}; + sw_error_t ret = SW_OK; + + struct qca808x_ptp_info *ptp_data = + container_of(work, struct qca808x_ptp_info, rx_ts_work.work); + + qca808x_priv *priv = + container_of(ptp_data, qca808x_priv, ptp_info); + + pdata = priv->phy_info; + + if (!pdata) { + return; + } + dev_id = pdata->dev_id; + phy_id = pdata->phy_addr; + + /* Deliver packets */ + while ((skb = skb_dequeue(&ptp_data->rx_queue))) { + ptp_cb = (qca808x_ptp_cb *)skb->cb; + qca808x_pkt_info_get(skb, ptp_cb->ptp_type, &pkt_info); + + ret = qca808x_phy_ptp_timestamp_get(dev_id, phy_id, + FAL_RX_DIRECTION, &pkt_info, &rx_time); + if (ret == SW_NOT_FOUND) { + qca808x_ptp_stat_update(pdata, FAL_RX_DIRECTION, + pkt_info.msg_type, PTP_PKT_SEQID_UNMATCHED); + SSDK_DEBUG("Fail to get rx_ts: sequence_id:%x, clock_identify:%llx, " + "port_number:%x, msg_type:%x\n", + pkt_info.sequence_id, pkt_info.clock_identify, + pkt_info.port_number, pkt_info.msg_type); + } else { + qca808x_ptp_stat_update(pdata, FAL_RX_DIRECTION, + pkt_info.msg_type, PTP_PKT_SEQID_MATCHED); + } + + ts.tv_sec = rx_time.seconds; + ts.tv_nsec = rx_time.nanoseconds; + ns = timespec64_to_ns(&ts); + shhwtstamps = skb_hwtstamps(skb); + memset(shhwtstamps, 0, sizeof(*shhwtstamps)); + shhwtstamps->hwtstamp = ns_to_ktime(ns); + + /* OC/BC needs record ingress time stamp on receiving + * peer delay request message under one-step mode. + * TC one step mode should use the embeded mode for offloading + * function. + */ + if (pdata->step_mode == FAL_ONE_STEP_MODE) { + switch (pdata->clock_mode) { + case FAL_OC_CLOCK_MODE: + case FAL_BC_CLOCK_MODE: + if (pkt_info.msg_type == QCA808X_PTP_MSG_PREQ) { + ptp_ingress_time_sync(phy_id, + ts.tv_nsec, A_FALSE); + } + break; + default: + break; + } + } + netif_rx_ni(skb); + } + + if (!skb_queue_empty(&ptp_data->rx_queue)) + schedule_delayed_work(&ptp_data->rx_ts_work, SKB_TIMESTAMP_TIMEOUT); +} + +static void qca808x_gps_second_sync(struct qca808x_phy_info *pdata, a_int32_t *buf) +{ + fal_ptp_time_t time, old_time; + a_uint32_t dev_id, phy_id; + + if (!pdata) { + return; + } + dev_id = pdata->dev_id; + phy_id = pdata->phy_addr; + /* 0-3: time of week; 4-5: week number; 6-7: UTC offset + * Time(UTC) = Time(GPS) - UTC offset */ +#define WEEK_TIME 604800 + time.seconds = ((a_int64_t)buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3]) + + ((buf[4] << 8 | buf[5]) * WEEK_TIME) - (buf[6] << 8 | buf[7]); + + time.nanoseconds = 0; + time.fracnanoseconds = 0; + + qca808x_phy_ptp_rtc_time_get(dev_id, phy_id, &old_time); + time.seconds -= old_time.seconds; + qca808x_phy_ptp_rtc_adjtime_set(dev_id, phy_id, &time); + + qca808x_ptp_gm_gps_seconds_sync_enable(dev_id, phy_id, A_FALSE); + return; +} + +static void gps_seconds_sync_thread(struct qca808x_phy_info *pdata) +{ + struct file *filp; + mm_segment_t fs; + a_uint32_t nread; + char buff[128]; + char *dev ="/dev/ttyMSM0"; + a_int32_t data[32]; + a_uint32_t i = 0, j = 0; + a_bool_t is_time_pkt = A_FALSE; + a_int32_t try_cycle = 32; + + filp = filp_open(dev, O_RDONLY, 0); + if (IS_ERR(filp)) + { + SSDK_ERROR("Open %s error\n", dev); + return; + } + + fs=get_fs(); + set_fs(KERNEL_DS); + while(1) + { + memset(data, 0, sizeof(data)); + memset(buff, 0, sizeof(buff)); + is_time_pkt = A_FALSE; + filp->f_pos = 0; + nread = filp->f_op->read(filp, buff, sizeof(buff), &filp->f_pos); + if (nread > 0) + { + /* the packet format: */ +#define PKT_DLE 0x10 +#define PKT_ETX 0x3 +#define PKT_PTIME_ID 0x8f +#define PKT_PTIME_SID 0xab +#define PKT_PTIME_LEN 0x10 + buff[nread+1]='\0'; + for(i = 0; i < nread; i++) + { + if (is_time_pkt == A_FALSE) + { + if (buff[i] == PKT_DLE && i+2 < nread && + buff[i+1] == PKT_PTIME_ID && + buff[i+2] == PKT_PTIME_SID) { + is_time_pkt = A_TRUE; + i = i + 2; + j = 0; + } + } else { + data[j++] = buff[i]; + if (j >= PKT_PTIME_LEN && data[j-2] == PKT_DLE && + data[j-1] == PKT_ETX) + { + qca808x_gps_second_sync(pdata, data); + goto gps_time_sync_exit; + } + + if (j > PKT_PTIME_LEN+2) { + is_time_pkt = A_FALSE; + } + } + } + } + + if (--try_cycle <= 0) { + break; + } + } + +gps_time_sync_exit: + set_fs(fs); + filp_close(filp, NULL); +} + +static void qca808x_ptp_schedule_work(struct work_struct *work) +{ + struct qca808x_phy_info *pdata = + container_of(work, struct qca808x_phy_info, ts_schedule_work.work); + + if (!pdata) { + return; + } + gps_seconds_sync_thread(pdata); + + if (pdata->gps_seconds_sync_en == A_TRUE) { + schedule_delayed_work(&pdata->ts_schedule_work, GPS_WORK_TIMEOUT); + } +} + +static void ingress_trig_time_work(struct work_struct *work) +{ + const struct qca808x_phy_info *pdata; + struct qca808x_ptp_info *ptp_data = + container_of(work, struct qca808x_ptp_info, ingress_trig_work.work); + + qca808x_priv *priv = + container_of(ptp_data, qca808x_priv, ptp_info); + + pdata = priv->phy_info; + + if (!pdata) { + return; + } + + switch (pdata->clock_mode) { + case FAL_P2PTC_CLOCK_MODE: + /* p2p tc one step just use ingress trig time for pdelay resp, + * the ingress timestamp should be recorded in the local phy. + */ + ptp_ingress_time_sync(pdata->phy_addr, ptp_data->ingress_time, A_FALSE); + break; + case FAL_E2ETC_CLOCK_MODE: + ptp_ingress_time_sync(pdata->phy_addr, ptp_data->ingress_time, A_TRUE); + break; + case FAL_OC_CLOCK_MODE: + case FAL_BC_CLOCK_MODE: + ptp_ingress_time_sync(pdata->phy_addr, ptp_data->ingress_time, A_FALSE); + break; + default: + break; + } + + return; +} + +/****************************************************************************** +* +* qca808x_ptp_settime - reset the rtc timecounter +* +* ptp: the ptp clock info structure +* ts: the new rtc timecounter +* +*/ +static int qca808x_ptp_settime(struct ptp_clock_info *ptp, + const struct timespec64 *ts) +{ + const struct qca808x_phy_info *pdata; + struct qca808x_ptp_clock *clock = + container_of(ptp, struct qca808x_ptp_clock, caps); + + fal_ptp_time_t ptp_time = {0}; + + qca808x_priv *priv = clock->priv; + pdata = priv->phy_info; + + if (!pdata) { + return SW_FAIL; + } + ptp_time.seconds = ts->tv_sec; + ptp_time.nanoseconds = ts->tv_nsec; + + mutex_lock(&clock->tsreg_lock); + qca808x_phy_ptp_rtc_time_set(pdata->dev_id, pdata->phy_addr, &ptp_time); + mutex_unlock(&clock->tsreg_lock); + return 0; +} + +/****************************************************************************** +* +* qca808x_ptp_gettime - read the rtc timecounter +* +* ptp: the ptp clock info structure +* ts: the timespace to hold the current rtc time +* +*/ +static int qca808x_ptp_gettime(struct ptp_clock_info *ptp, + struct timespec64 *ts) +{ + const struct qca808x_phy_info *pdata; + struct qca808x_ptp_clock *clock = + container_of(ptp, struct qca808x_ptp_clock, caps); + + fal_ptp_time_t ptp_time = {0}; + + qca808x_priv *priv = clock->priv; + pdata = priv->phy_info; + + if (!pdata) { + return SW_FAIL; + } + mutex_lock(&clock->tsreg_lock); + qca808x_phy_ptp_rtc_time_get(pdata->dev_id, pdata->phy_addr, &ptp_time); + mutex_unlock(&clock->tsreg_lock); + + ts->tv_sec = ptp_time.seconds; + ts->tv_nsec = ptp_time.nanoseconds; + return 0; +} + +/****************************************************************************** +* +* qca808x_ptp_adjtime - adjust the rtc timecounter offset +* +* ptp: the ptp clock info structure +* delta: offset to be adjusted per cycle counter +* +*/ +static int qca808x_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) +{ + struct timespec64 ts; + const struct qca808x_phy_info *pdata; + struct qca808x_ptp_clock *clock = + container_of(ptp, struct qca808x_ptp_clock, caps); + + fal_ptp_time_t ptp_time = {0}; + + qca808x_priv *priv = clock->priv; + pdata = priv->phy_info; + + if (!pdata) { + return SW_FAIL; + } + ts = ns_to_timespec64(delta); + ptp_time.seconds = ts.tv_sec; + ptp_time.nanoseconds = ts.tv_nsec; + + mutex_lock(&clock->tsreg_lock); + qca808x_phy_ptp_rtc_adjtime_set(pdata->dev_id, pdata->phy_addr, &ptp_time); + mutex_unlock(&clock->tsreg_lock); + return 0; +} + +static void qca808x_ppb_to_freq (a_int32_t speed, a_int32_t ppb, fal_ptp_time_t *ptp_time) +{ + a_uint64_t rate; + a_uint16_t ns, ns_tmp; + a_int32_t neg_adj = 0, tmp = 0; + + if (ppb < 0) { + neg_adj = 1; + ppb = -ppb; + } + + rate = ppb; + rate <<= 20; + /* divided by (200Mhz-ppb/8)/64 */ + if (speed == FAL_SPEED_2500) { + tmp = (ppb/5)/64; + ns_tmp = QCA808X_PTP_TICK_RATE_200M; + rate = div_u64(rate, 3125000 + tmp); + } else { + tmp = (ppb/8)/64; + ns_tmp = QCA808X_PTP_TICK_RATE_125M; + rate = div_u64(rate, 1953125 + tmp); + } + + if(neg_adj && rate != 0) { + ns = ns_tmp - 1; + rate = (2<<26)-rate; + } else { + ns = ns_tmp; + } + + /* remove the redundant bits, only 26 bits for fracnanoseconds */ + while (rate & 0xfc000000) { + rate >>= 1; + } + + ptp_time->seconds = 0; + ptp_time->nanoseconds = ns; + ptp_time->fracnanoseconds = rate; + + return; +} + +static void qca808x_ptp_adjfreq_sync(a_uint32_t phy_addr, + a_int32_t ppb, fal_ptp_time_t ptp_time_org) +{ + fal_ptp_reference_clock_t ref_clock = FAL_REF_CLOCK_LOCAL; + fal_ptp_time_t ptp_time = {0}; + struct qca808x_phy_info *pdata = NULL; + sw_error_t ret = SW_OK; + a_uint32_t gm_mode = 0; + + /* + * In BC mode, the SYNC clock, PPS and Toduart PINs are connected, + * the adjust frequency should be same among the ports to guaranteeing + * the RTC consistent. + */ + list_for_each_entry(pdata, &g_qca808x_phy_list, list) { + if (pdata->phydev_addr != phy_addr) { + ret = qca808x_ptp_gm_conf0_reg_grandmaster_mode_get(pdata->dev_id, + pdata->phy_addr, &gm_mode); + /* The grandmaster mode should be configured to sync RTC */ + if (ret == SW_OK && gm_mode == PTP_REG_BIT_TRUE) { + ptp_time = ptp_time_org; + ret = qca808x_phy_ptp_reference_clock_get(pdata->dev_id, + pdata->phy_addr, &ref_clock); + /* + * BC ports share the same RTC clock in the external mode + * so the adjust frequency should be also same, otherwise + * the ppb should be converted to the corresponding value + * of the adjust frequency. + */ + if (ret == SW_OK && ref_clock != FAL_REF_CLOCK_EXTERNAL) { + qca808x_ppb_to_freq(pdata->speed, ppb, &ptp_time); + } + qca808x_phy_ptp_rtc_adjfreq_set(pdata->dev_id, + pdata->phy_addr, &ptp_time); + } + } + } + + return; +} + +/****************************************************************************** +* +* qca808x_ptp_adjfreq - adjust the frequency of cycle counter +* +* ptp: the ptp clock info structure +* ppb: parts per billion adjustment from master +* +*/ +static int qca808x_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb) +{ + const struct qca808x_phy_info *pdata; + struct qca808x_ptp_clock *clock = + container_of(ptp, struct qca808x_ptp_clock, caps); + + fal_ptp_time_t ptp_time = {0}; + + qca808x_priv *priv = clock->priv; + struct phy_device *phydev = priv->phydev; + pdata = priv->phy_info; + + if (!pdata || !phydev) { + return SW_FAIL; + } + + qca808x_ppb_to_freq(pdata->speed, ppb, &ptp_time); + + mutex_lock(&clock->tsreg_lock); + qca808x_phy_ptp_rtc_adjfreq_set(pdata->dev_id, pdata->phy_addr, &ptp_time); + if (pdata->clock_mode == FAL_BC_CLOCK_MODE) { + /* Keep RTC time consistent among BC ports */ + qca808x_ptp_adjfreq_sync(pdata->phy_addr, ppb, ptp_time); + } + mutex_unlock(&clock->tsreg_lock); + return 0; +} + +static int qca808x_ptp_enable(struct ptp_clock_info *ptp, + struct ptp_clock_request *rq, int on) +{ + return -EOPNOTSUPP; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) +static int qca808x_ptp_verify(struct ptp_clock_info *ptp, unsigned int pin, + enum ptp_pin_function func, unsigned int chan) +{ + return 1; +} +#endif + +void qca808x_ptp_change_notify(struct phy_device *phydev) +{ + fal_ptp_reference_clock_t ptp_ref_clock = FAL_REF_CLOCK_EXTERNAL; + fal_ptp_time_t ptp_cycle_time = {0}; + a_uint32_t nanoseconds = 0; + qca808x_priv *priv = phydev->priv; + struct qca808x_phy_info *pdata = priv->phy_info; + + if (!pdata) { + return; + } + + if (pdata->speed != phydev->speed) { + if (phydev->speed == SPEED_2500 && + pdata->speed < SPEED_2500) { + /* adjust frequency to 5ns(200MHz) */ + nanoseconds = QCA808X_PTP_TICK_RATE_200M; + } else if (pdata->speed == SPEED_2500 && + phydev->speed < SPEED_2500) { + /* adjust frequency to 8ns(125MHz) */ + nanoseconds = QCA808X_PTP_TICK_RATE_125M; + } + + if (phydev->speed == SPEED_10) { + /* local free running clock for 10M */ + ptp_ref_clock = FAL_REF_CLOCK_LOCAL; + } else if (pdata->speed == SPEED_10) { + ptp_ref_clock = FAL_REF_CLOCK_SYNCE; + } + + if (ptp_ref_clock != FAL_REF_CLOCK_EXTERNAL) { + qca808x_phy_ptp_reference_clock_set(pdata->dev_id, + pdata->phy_addr, ptp_ref_clock); + } + + pdata->speed = phydev->speed; + if (nanoseconds != 0) { + ptp_cycle_time.nanoseconds = nanoseconds; + qca808x_phy_ptp_rtc_adjfreq_set(pdata->dev_id, + pdata->phy_addr, &ptp_cycle_time); + } + } +} + +int qca808x_hwtstamp(struct phy_device *phydev, struct ifreq *ifr) +{ + struct hwtstamp_config cfg; + a_uint32_t gm_mode = 0; + fal_ptp_reference_clock_t ref_clock = FAL_REF_CLOCK_LOCAL; + sw_error_t ret = SW_OK; + fal_ptp_config_t ptp_config = {0}; + qca808x_priv *priv = phydev->priv; + struct qca808x_phy_info *pdata = priv->phy_info; + struct qca808x_ptp_info *ptp_info = &priv->ptp_info; + struct qca808x_ptp_clock *clock = ptp_info->clock; + + if (!pdata || !clock) { + return -EFAULT; + } + + if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) + return -EFAULT; + if (cfg.flags) /* reserved for future extensions */ + return -EINVAL; + + if (cfg.tx_type < 0 || cfg.tx_type > HWTSTAMP_TX_ONESTEP_P2P) + return -ERANGE; + + ptp_info->hwts_tx_type = cfg.tx_type; + + switch (cfg.rx_filter) { + case HWTSTAMP_FILTER_NONE: + ptp_info->hwts_rx_type = PTP_CLASS_NONE; + break; + case HWTSTAMP_FILTER_PTP_V2_EVENT: + case HWTSTAMP_FILTER_PTP_V2_SYNC: + case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: + ptp_info->hwts_rx_type = PTP_CLASS_L4 | PTP_CLASS_L2; + break; + case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: + case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: + case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: + ptp_info->hwts_rx_type = PTP_CLASS_L4; + break; + case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: + case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: + case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: + ptp_info->hwts_rx_type = PTP_CLASS_L2; + break; + default: + return -ERANGE; + } + + mutex_lock(&clock->tsreg_lock); + ptp_config.clock_mode = pdata->clock_mode; + switch (ptp_info->hwts_tx_type) { + case HWTSTAMP_TX_ON: + ptp_config.ptp_en = A_TRUE; + ptp_config.step_mode = FAL_TWO_STEP_MODE; + break; + case HWTSTAMP_TX_ONESTEP_SYNC: + case HWTSTAMP_TX_ONESTEP_P2P: + ptp_config.ptp_en = A_TRUE; + ptp_config.step_mode = FAL_ONE_STEP_MODE; + break; + case HWTSTAMP_TX_OFF: + default: + ptp_config.ptp_en = A_FALSE; + ptp_config.step_mode = FAL_TWO_STEP_MODE; + break; + } + ret = qca808x_phy_ptp_config_set(pdata->dev_id, pdata->phy_addr, &ptp_config); + mutex_unlock(&clock->tsreg_lock); + if (ret != SW_OK) { + return -EFAULT; + } + + /* + * disable SYNCE clock output by default, + * only enabling the clock output under the + * BC mode && not in external reference mode + */ + qca808x_ptp_clock_synce_clock_enable(pdata->dev_id, pdata->phy_addr, A_FALSE); + + if (pdata->clock_mode == FAL_BC_CLOCK_MODE) { + ret = qca808x_ptp_gm_conf0_reg_grandmaster_mode_get(pdata->dev_id, + pdata->phy_addr, &gm_mode); + /* The grandmaster mode should be configured to sync RTC */ + if (ret == SW_OK && gm_mode != PTP_REG_BIT_TRUE) { + ret = qca808x_phy_ptp_reference_clock_get(pdata->dev_id, + pdata->phy_addr, &ref_clock); + /* + * The PHC should be with below PINs connected for clock synchronized + * so NAPA1 should be configured as sync or local reference clock, + * and NAPA2 is configured as FAL_REF_CLOCK_EXTERNAL & grandmaster mode. + * + * Napa1 ToD out --- > Napa2 ToD in. + * Napa1 PPS out --- > Napa2 PPS in. + * Napa1 sync clock out --- > Napa2 reference clock in. + */ + if (ret == SW_OK && ref_clock != FAL_REF_CLOCK_EXTERNAL) { + /* enable SYNCE clock output */ + qca808x_ptp_clock_synce_clock_enable(pdata->dev_id, + pdata->phy_addr, A_TRUE); + } + } + } + + pdata->step_mode = ptp_config.step_mode; + + return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; +} + +bool qca808x_rxtstamp(struct phy_device *phydev, + struct sk_buff *nskb, int type) +{ + struct skb_shared_hwtstamps *shhwtstamps = NULL; + struct timespec64 ts = {0}; + a_bool_t ingress_trig_flag = A_FALSE; + a_uint64_t ns; + a_int64_t *correction; + a_uint16_t *seqid; + a_int32_t ptp_class; + a_uint32_t *reserved2; + a_uint8_t *reserved0, *reserved1; + a_uint32_t *cf1; + a_uint8_t *ptp_header; + a_uint8_t embed_val, pkt_type; + qca808x_ptp_cb *ptp_cb = (qca808x_ptp_cb *)nskb->cb; + qca808x_priv *priv = phydev->priv; + struct qca808x_phy_info *pdata = priv->phy_info; + struct qca808x_ptp_info *ptp_info = &priv->ptp_info; + + if (ptp_info->hwts_rx_type == PTP_CLASS_NONE || !pdata) { + return false; + } + + /* The PTP_CLASS_NONE is passed, which indicates that the + * PTP class is not determined, calling ptp_classify_raw to + * classfy the packet. + */ + if (type == PTP_CLASS_NONE) { + __skb_push(nskb, ETH_HLEN); + /* dissecting the packet content to get ptp class */ + ptp_class = ptp_classify_raw(nskb); + __skb_pull(nskb, ETH_HLEN); + if (ptp_class == PTP_CLASS_NONE) { + /* this case should not happen, only ptp event packet passed */ + SSDK_ERROR("%s: No PTP event packet received\n", __func__); + return false; + } + type = ptp_class; + } + + if ((ptp_info->hwts_rx_type & type) == PTP_CLASS_NONE) { + return false; + } + + ptp_header = skb_ptp_header(nskb, type); + if (!ptp_header) { + return false; + } + shhwtstamps = skb_hwtstamps(nskb); + memset(shhwtstamps, 0, sizeof(*shhwtstamps)); + +#define PTP_HDR_CORRECTIONFIELD_CPY_SRC 11 +#define PTP_HDR_CORRECTIONFIELD_CPY_DST 9 +#define PTP_HDR_CORRECTIONFIELD_CPY_LEN 5 + + reserved0 = ptp_header + PTP_HDR_RESERVED0_OFFSET; + reserved1 = ptp_header + PTP_HDR_RESERVED1_OFFSET; + cf1 = (a_uint32_t *)(ptp_header + PTP_HDR_CORRECTIONFIELD_OFFSET); + correction = (a_uint64_t *)(ptp_header + PTP_HDR_CORRECTIONFIELD_OFFSET); + seqid = (a_uint16_t *)(ptp_header + OFF_PTP_SEQUENCE_ID); + reserved2 = (a_uint32_t *)(ptp_header + PTP_HDR_RESERVED2_OFFSET); + + embed_val = (*reserved0 & 0xf0) >> 4; + pkt_type = *ptp_header & 0xf; + + qca808x_ptp_stat_update(pdata, FAL_RX_DIRECTION, + QCA808X_PTP_MSG_MAX, PTP_PKT_SEQID_UNMATCHED); + + if (embed_val == QCA808X_PTP_EMBEDDED_MODE) { + ts.tv_sec = ntohl(*reserved2); + ts.tv_nsec = ((a_uint32_t)*reserved1 << 24) | (ntohl(*cf1) >> 8); + + if (pdata->step_mode == FAL_ONE_STEP_MODE) { + switch (pdata->clock_mode) { + case FAL_OC_CLOCK_MODE: + case FAL_BC_CLOCK_MODE: + case FAL_P2PTC_CLOCK_MODE: + /* message sync with the timestamp inserted into the ptp + * header, do not use the ingress_trig_time register, the + * ingress time will be acquired from ptp header. + * the ingress time of pdealy request msg should be + * recorded and will be copied the corresponding pdealy + * response msg. + */ + if (pkt_type == QCA808X_PTP_MSG_PREQ) { + ptp_info->embeded_ts.reserved0 = *reserved0; + ptp_info->embeded_ts.reserved1 = *reserved1; + ptp_info->embeded_ts.reserved2 = *reserved2; + ptp_info->embeded_ts.correction = *correction; + ptp_info->embeded_ts.seqid = *seqid; + ptp_info->embeded_ts.msg_type = pkt_type; + } + break; + case FAL_E2ETC_CLOCK_MODE: + ingress_trig_flag = A_TRUE; + break; + default: + break; + } + if (ingress_trig_flag == A_TRUE) { + ptp_info->ingress_time = ts.tv_nsec; + schedule_delayed_work(&ptp_info->ingress_trig_work, 0); + } + } + + /* restore the original correctionfield value except for + * the TC one-step mode offloading*/ + if (!(((pdata->clock_mode == FAL_P2PTC_CLOCK_MODE && + pkt_type == QCA808X_PTP_MSG_SYNC) || + pdata->clock_mode == FAL_E2ETC_CLOCK_MODE) && + pdata->step_mode == FAL_ONE_STEP_MODE)) + { + /* in embeded mode for the rx time stamp, the correction field + * is modfied to keep the low 50 bit of nanosecond and the + * fractional nanoseconds should be dropped + */ + *reserved0 = *reserved0 & 0xf; + memmove(ptp_header + PTP_HDR_CORRECTIONFIELD_CPY_DST, + ptp_header + PTP_HDR_CORRECTIONFIELD_CPY_SRC, + PTP_HDR_CORRECTIONFIELD_CPY_LEN); + memset(ptp_header + PTP_HDR_CORRECTIONFIELD_OFFSET, 0, 1); + memset(ptp_header + PTP_HDR_RESERVED2_OFFSET - 2, 0, 6); + } + } else { + ptp_cb->ptp_type = type; + ptp_cb->pkt_type = pkt_type; + skb_queue_tail(&ptp_info->rx_queue, nskb); + schedule_delayed_work(&ptp_info->rx_ts_work, 0); + return true; + } + ns = timespec64_to_ns(&ts); + + qca808x_ptp_stat_update(pdata, FAL_RX_DIRECTION, + pkt_type, PTP_PKT_SEQID_MATCHED); + + shhwtstamps->hwtstamp = ns_to_ktime(ns); + netif_rx_ni(nskb); + + return true; +} + +void qca808x_txtstamp(struct phy_device *phydev, + struct sk_buff *org_skb, int type) +{ + a_uint8_t msg_type; + struct sk_buff *skb; + qca808x_ptp_cb *ptp_cb; + a_uint8_t *ptp_header; + a_int64_t *correction; + a_uint32_t *reserved2; + a_uint8_t *reserved0, *reserved1; + a_uint16_t *seqid; + a_int32_t ptp_class; + qca808x_priv *priv = phydev->priv; + struct qca808x_ptp_info *ptp_info = &priv->ptp_info; + + /* The PTP_CLASS_NONE is passed, which indicates that the + * PTP class is not determined, calling ptp_classify_raw to + * classfy the packet. + */ + if (type == PTP_CLASS_NONE) { + ptp_class = ptp_classify_raw(org_skb); + if (ptp_class == PTP_CLASS_NONE) { + return; + } + skb = skb_clone_sk(org_skb); + if (!skb) { + SSDK_ERROR("%s: skb_clone_sk failed\n", __func__); + return; + } + type = ptp_class; + } else { + skb = org_skb; + } + + ptp_header = skb_ptp_header(skb, type); + if (!ptp_header) { + kfree_skb(skb); + return; + } + + ptp_cb = (qca808x_ptp_cb *)skb->cb; + seqid = (a_uint16_t *)(ptp_header + OFF_PTP_SEQUENCE_ID); + reserved0 = ptp_header + PTP_HDR_RESERVED0_OFFSET; + reserved1 = ptp_header + PTP_HDR_RESERVED1_OFFSET; + reserved2 = (a_uint32_t *)(ptp_header + PTP_HDR_RESERVED2_OFFSET); + correction = (a_uint64_t *)(ptp_header + PTP_HDR_CORRECTIONFIELD_OFFSET); + msg_type = *ptp_header & 0xf; + switch (ptp_info->hwts_tx_type) { + case HWTSTAMP_TX_ONESTEP_SYNC: + if (msg_type == QCA808X_PTP_MSG_SYNC) { + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; + kfree_skb(skb); + return; + } + break; + case HWTSTAMP_TX_ONESTEP_P2P: + switch (msg_type) { + case QCA808X_PTP_MSG_PRESP: + if (ptp_info->embeded_ts.seqid == *seqid && + ptp_info->embeded_ts.msg_type == + QCA808X_PTP_MSG_PREQ) { + *reserved0 = ptp_info->embeded_ts.reserved0; + *reserved1 = ptp_info->embeded_ts.reserved1; + *reserved2 = ptp_info->embeded_ts.reserved2; + *correction = ptp_info->embeded_ts.correction; + } + /* fall down */ + case QCA808X_PTP_MSG_SYNC: + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; + kfree_skb(skb); + return; + default: + break; + } + break; + case HWTSTAMP_TX_ON: + break; + /* enqueue skb to get tx timestamp */ + case HWTSTAMP_TX_OFF: + default: + kfree_skb(skb); + return; + } + + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; + skb_queue_tail(&ptp_info->tx_queue, skb); + ptp_cb->ptp_type = type; + qca808x_ptp_stat_update(priv->phy_info, FAL_TX_DIRECTION, + QCA808X_PTP_MSG_MAX, PTP_PKT_SEQID_UNMATCHED); + schedule_delayed_work(&ptp_info->tx_ts_work, 0); +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) +int qca808x_ts_info(struct phy_device *phydev, + struct ethtool_ts_info *info) +{ + qca808x_priv *priv = phydev->priv; + struct qca808x_ptp_info *ptp_info = &priv->ptp_info; + struct qca808x_ptp_clock *clock = ptp_info->clock; + + if (clock) { + info->phc_index = ptp_clock_index(clock->ptp_clock); + } + + info->so_timestamping = + SOF_TIMESTAMPING_TX_HARDWARE | + SOF_TIMESTAMPING_RX_HARDWARE | + SOF_TIMESTAMPING_RAW_HARDWARE; + info->tx_types = + (1 << HWTSTAMP_TX_OFF) | + (1 << HWTSTAMP_TX_ON) | + (1 << HWTSTAMP_TX_ONESTEP_SYNC) | + (1 << HWTSTAMP_TX_ONESTEP_P2P); + + info->rx_filters = + (1 << HWTSTAMP_FILTER_NONE) | + (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT) | + (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) | + (1 << HWTSTAMP_FILTER_PTP_V2_EVENT); + + return 0; +} +#endif + +static int qca808x_ptp_register(struct phy_device *phydev) +{ + int err; + struct qca808x_ptp_clock *clock; + qca808x_priv *priv = phydev->priv; + struct qca808x_ptp_info *ptp_info = &priv->ptp_info; + + clock = kzalloc(sizeof(struct qca808x_ptp_clock), GFP_KERNEL); + if (!clock) { + return -ENOMEM; + } + + mutex_init(&clock->tsreg_lock); + clock->caps.owner = THIS_MODULE; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) + snprintf(clock->caps.name, sizeof(clock->caps.name), "qca808x timer %x", phydev->mdio.addr); +#else + snprintf(clock->caps.name, sizeof(clock->caps.name), "qca808x timer %x", phydev->addr); +#endif + clock->caps.max_adj = 3124999; + clock->caps.n_alarm = 0; + clock->caps.n_ext_ts = 6; + clock->caps.n_per_out = 7; + clock->caps.pps = 0; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) + clock->caps.n_pins = 0; + clock->caps.verify = qca808x_ptp_verify; + clock->caps.gettime64 = qca808x_ptp_gettime; + clock->caps.settime64 = qca808x_ptp_settime; +#else + clock->caps.gettime = qca808x_ptp_gettime; + clock->caps.settime = qca808x_ptp_settime; +#endif + clock->caps.adjfreq = qca808x_ptp_adjfreq; + clock->caps.adjtime = qca808x_ptp_adjtime; + clock->caps.enable = qca808x_ptp_enable; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) + clock->ptp_clock = ptp_clock_register(&clock->caps, &phydev->mdio.dev); +#else + clock->ptp_clock = ptp_clock_register(&clock->caps, &phydev->dev); +#endif + if (IS_ERR(clock->ptp_clock)) { + err = PTR_ERR(clock->ptp_clock); + kfree(clock); + return err; + } + ptp_info->clock = clock; + clock->priv = priv; + + SSDK_INFO("qca808x ptp clock registered\n"); + return 0; +} + +static void qca808x_ptp_unregister(struct phy_device *phydev) +{ + qca808x_priv *priv = phydev->priv; + struct qca808x_ptp_info *ptp_info = &priv->ptp_info; + struct qca808x_ptp_clock *clock = ptp_info->clock; + + if (clock) { + ptp_clock_unregister(clock->ptp_clock); + mutex_destroy(&clock->tsreg_lock); + kfree(clock); + } +} + +int qca808x_ptp_init(qca808x_priv *priv) +{ + int err; + struct qca808x_ptp_info *ptp_info; + struct qca808x_phy_info *pdata; + + if (!priv) { + return -1; + } + + ptp_info = &priv->ptp_info; + pdata = priv->phy_info; + INIT_DELAYED_WORK(&ptp_info->tx_ts_work, tx_timestamp_work); + INIT_DELAYED_WORK(&ptp_info->rx_ts_work, rx_timestamp_work); + skb_queue_head_init(&ptp_info->tx_queue); + skb_queue_head_init(&ptp_info->rx_queue); + + INIT_DELAYED_WORK(&ptp_info->ingress_trig_work, ingress_trig_time_work); + INIT_DELAYED_WORK(&pdata->ts_schedule_work, qca808x_ptp_schedule_work); + + err = qca808x_ptp_register(priv->phydev); + if (err <0) { + SSDK_ERROR("qca808x ptp clock register failed\n"); + kfree(ptp_info); + return err; + } + + return err; +} + +void qca808x_ptp_deinit(qca808x_priv *priv) +{ + struct qca808x_ptp_info *ptp_info; + struct qca808x_phy_info *pdata; + if (!priv) { + return; + } + + ptp_info = &priv->ptp_info; + pdata = priv->phy_info; + cancel_delayed_work_sync(&ptp_info->tx_ts_work); + cancel_delayed_work_sync(&ptp_info->rx_ts_work); + cancel_delayed_work_sync(&ptp_info->ingress_trig_work); + cancel_delayed_work_sync(&pdata->ts_schedule_work); + skb_queue_purge(&ptp_info->tx_queue); + skb_queue_purge(&ptp_info->rx_queue); + + qca808x_ptp_unregister(priv->phydev); +} diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/qca808x_phy.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/qca808x_phy.c new file mode 100644 index 000000000..cecbf2061 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/qca808x_phy.c @@ -0,0 +1,2265 @@ +/* + * 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. + */ +/*qca808x_start*/ +#include "sw.h" +#include "fal_port_ctrl.h" +#include "hsl_api.h" +#include "hsl.h" +#include "hsl_phy.h" +#include "ssdk_plat.h" +#include "qca808x_phy.h" +/*qca808x_end*/ +#if defined(IN_PTP) +#include "qca808x_ptp.h" +#endif +#include "qca808x.h" +#ifdef IN_LED +#include "qca808x_led.h" +#endif + +static a_bool_t phy_dev_drv_init_flag = A_FALSE; +/*qca808x_start*/ +static a_bool_t phy_ops_flag = A_FALSE; + +static struct mutex qca808x_reg_lock; + +#define QCA808X_LOCKER_INIT mutex_init(&qca808x_reg_lock) +#define QCA808X_REG_LOCK mutex_lock(&qca808x_reg_lock) +#define QCA808X_REG_UNLOCK mutex_unlock(&qca808x_reg_lock) + +/****************************************************************************** +* +* qca808x_phy_mii_read - mii register read +* +* mii register read +*/ +a_uint16_t +qca808x_phy_reg_read(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t reg_id) +{ + sw_error_t rv = SW_OK; + a_uint16_t phy_data = 0; +#if defined(IN_PHY_I2C_MODE) + a_uint32_t port_id = qca_ssdk_phy_addr_to_port(dev_id, phy_id); + a_uint8_t phy_access_type = hsl_port_phy_access_type_get(dev_id, port_id); + + if (phy_access_type == PHY_I2C_ACCESS) { + HSL_PHY_I2C_GET(rv, dev_id, phy_id, reg_id, &phy_data); + } + else +#endif + { + HSL_PHY_GET(rv, dev_id, phy_id, reg_id, &phy_data); + } + + if (rv != SW_OK) { + return PHY_INVALID_DATA; + } + + return phy_data; +} + +/****************************************************************************** +* +* qca808x_phy_mii_write - mii register write +* +* mii register write +*/ +sw_error_t +qca808x_phy_reg_write(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t reg_id, + a_uint16_t reg_val) +{ + sw_error_t rv; +#if defined(IN_PHY_I2C_MODE) + a_uint32_t port_id = qca_ssdk_phy_addr_to_port(dev_id, phy_id); + a_uint8_t phy_access_type = hsl_port_phy_access_type_get(dev_id, port_id); + + if (phy_access_type == PHY_I2C_ACCESS) { + HSL_PHY_I2C_SET(rv, dev_id, phy_id, reg_id, reg_val); + } + else +#endif + { + HSL_PHY_SET(rv, dev_id, phy_id, reg_id, reg_val); + } + + return rv; + +} + +/****************************************************************************** +* +* qca808x_phy_debug_write - debug port write +* +* debug port write +*/ +sw_error_t +qca808x_phy_debug_write(a_uint32_t dev_id, a_uint32_t phy_id, a_uint16_t reg_id, + a_uint16_t reg_val) +{ + sw_error_t rv = SW_OK; + + QCA808X_REG_LOCK; + rv = qca808x_phy_reg_write(dev_id, phy_id, QCA808X_DEBUG_PORT_ADDRESS, reg_id); + if (rv != SW_OK) + { + QCA808X_REG_UNLOCK; + SSDK_ERROR("qca808x_phy_reg_write failed\n"); + return SW_FAIL; + } + + rv = qca808x_phy_reg_write(dev_id, phy_id, QCA808X_DEBUG_PORT_DATA, reg_val); + if (rv != SW_OK) + { + QCA808X_REG_UNLOCK; + SSDK_ERROR("qca808x_phy_reg_write failed\n"); + return SW_FAIL; + } + QCA808X_REG_UNLOCK; + + return rv; +} + +/****************************************************************************** +* +* qca808x_phy_debug_read - debug port read +* +* debug port read +*/ +a_uint16_t +qca808x_phy_debug_read(a_uint32_t dev_id, a_uint32_t phy_id, a_uint16_t reg_id) +{ + sw_error_t rv = SW_OK; + a_uint16_t phy_data = 0; + + QCA808X_REG_LOCK; + rv = qca808x_phy_reg_write(dev_id, phy_id, QCA808X_DEBUG_PORT_ADDRESS, reg_id); + if (rv != SW_OK) { + QCA808X_REG_UNLOCK; + SSDK_ERROR("qca808x_phy_reg_write failed\n"); + return PHY_INVALID_DATA; + } + phy_data = qca808x_phy_reg_read(dev_id, phy_id, QCA808X_DEBUG_PORT_DATA); + if (phy_data == PHY_INVALID_DATA) { + QCA808X_REG_UNLOCK; + SSDK_ERROR("qca808x_phy_reg_read failed\n"); + return PHY_INVALID_DATA; + } + QCA808X_REG_UNLOCK; + + return phy_data; +} + +/****************************************************************************** +* +* qca808x_phy_mmd_write - PHY MMD register write +* +* PHY MMD register write +*/ +sw_error_t +qca808x_phy_mmd_write(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint16_t mmd_num, a_uint16_t reg_id, a_uint16_t reg_val) +{ + sw_error_t rv; + a_uint32_t reg_id_c45 = QCA808X_REG_C45_ADDRESS(mmd_num, reg_id); +#if defined(IN_PHY_I2C_MODE) + a_uint32_t port_id = qca_ssdk_phy_addr_to_port(dev_id, phy_id); + a_uint8_t phy_access_type = hsl_port_phy_access_type_get(dev_id, port_id); + + if (phy_access_type == PHY_I2C_ACCESS) { + HSL_PHY_I2C_SET(rv, dev_id, phy_id, reg_id_c45, reg_val); + } + else +#endif + { + HSL_PHY_SET(rv, dev_id, phy_id, reg_id_c45, reg_val); + } + + return rv; +} + +/****************************************************************************** +* +* qca808x_phy_mmd_read - PHY MMD register read +* +* PHY MMD register read +*/ +a_uint16_t +qca808x_phy_mmd_read(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint16_t mmd_num, a_uint16_t reg_id) +{ + sw_error_t rv = SW_OK; + a_uint16_t phy_data = 0; + a_uint32_t reg_id_c45 = QCA808X_REG_C45_ADDRESS(mmd_num, reg_id); +#if defined(IN_PHY_I2C_MODE) + a_uint32_t port_id = qca_ssdk_phy_addr_to_port(dev_id, phy_id); + a_uint8_t phy_access_type = hsl_port_phy_access_type_get(dev_id, port_id); + + if (phy_access_type == PHY_I2C_ACCESS) { + HSL_PHY_I2C_GET(rv, dev_id, phy_id, reg_id_c45, &phy_data); + } + else +#endif + { + HSL_PHY_GET(rv, dev_id, phy_id, reg_id_c45, &phy_data); + } + + if (rv != SW_OK) { + return PHY_INVALID_DATA; + } + + return phy_data; +} + +static sw_error_t +qca808x_phy_ms_random_seed_set(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + sw_error_t rv = SW_OK; + + phy_data = qca808x_phy_debug_read(dev_id, phy_id, + QCA808X_DEBUG_LOCAL_SEED); + phy_data &= ~(QCA808X_MASTER_SLAVE_SEED_CFG); + phy_data |= (prandom_u32()%QCA808X_MASTER_SLAVE_SEED_RANGE) << 2; + SSDK_DEBUG("QCA808X_DEBUG_LOCAL_SEED:%x\n", phy_data); + rv = qca808x_phy_debug_write(dev_id, phy_id, + QCA808X_DEBUG_LOCAL_SEED, phy_data); + + return rv; +} + +static sw_error_t +qca808x_phy_ms_seed_enable(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t enable) +{ + a_uint16_t phy_data; + sw_error_t rv = SW_OK; + + phy_data = qca808x_phy_debug_read(dev_id, phy_id, + QCA808X_DEBUG_LOCAL_SEED); + if(enable) + { + phy_data |= QCA808X_MASTER_SLAVE_SEED_ENABLE; + } + else + { + phy_data &= ~(QCA808X_MASTER_SLAVE_SEED_ENABLE); + } + rv = qca808x_phy_debug_write(dev_id, phy_id, + QCA808X_DEBUG_LOCAL_SEED, phy_data); + + return rv; +} + +a_bool_t +qca808x_phy_2500caps(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + + phy_data = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD1_NUM, + QCA808X_MMD1_PMA_CAP_REG); + + if (phy_data & QCA808X_STATUS_2500T_FD_CAPS) { + return A_TRUE; + } + + return A_FALSE; + +} + +/****************************************************************************** +* +* qca808x_phy_get status +* +* get phy status +*/ +sw_error_t +qca808x_phy_get_status(a_uint32_t dev_id, a_uint32_t phy_id, + struct port_phy_status *phy_status) +{ + a_uint16_t phy_data; + + phy_data = qca808x_phy_reg_read(dev_id, phy_id, QCA808X_PHY_SPEC_STATUS); + PHY_RTN_ON_READ_ERROR(phy_data); + + /*get phy link status*/ + if (phy_data & QCA808X_STATUS_LINK_PASS) { + phy_status->link_status = A_TRUE; + } + else { + phy_status->link_status = A_FALSE; + if (qca808x_phy_2500caps(dev_id, phy_id) == A_TRUE) { + SW_RTN_ON_ERROR( + qca808x_phy_ms_random_seed_set (dev_id, phy_id)); + /*protect logic, if MASTER_SLAVE_CONFIG_FAULT is 1, + then disable this logic*/ + phy_data = qca808x_phy_reg_read(dev_id, phy_id, + QCA808X_1000BASET_STATUS); + if ((phy_data & QCA808X_MASTER_SLAVE_CONFIG_FAULT) >> 15) + { + SW_RTN_ON_ERROR( + qca808x_phy_ms_seed_enable (dev_id, phy_id, A_FALSE)); + SSDK_INFO("master_slave_config_fault was set\n"); + } + } + + return SW_OK; + } + + /*get phy speed*/ + switch (phy_data & QCA808X_STATUS_SPEED_MASK) { + case QCA808X_STATUS_SPEED_2500MBS: + phy_status->speed = FAL_SPEED_2500; + break; + case QCA808X_STATUS_SPEED_1000MBS: + phy_status->speed = FAL_SPEED_1000; + break; + case QCA808X_STATUS_SPEED_100MBS: + phy_status->speed = FAL_SPEED_100; + break; + case QCA808X_STATUS_SPEED_10MBS: + phy_status->speed = FAL_SPEED_10; + break; + default: + return SW_READ_ERROR; + } + + /*get phy duplex*/ + if (phy_data & QCA808X_STATUS_FULL_DUPLEX) { + phy_status->duplex = FAL_FULL_DUPLEX; + } else { + phy_status->duplex = FAL_HALF_DUPLEX; + } + + /* get phy flowctrl resolution status */ + if (phy_data & QCA808X_PHY_RX_FLOWCTRL_STATUS) { + phy_status->rx_flowctrl = A_TRUE; + } else { + phy_status->rx_flowctrl = A_FALSE; + } + + if (phy_data & QCA808X_PHY_TX_FLOWCTRL_STATUS) { + phy_status->tx_flowctrl = A_TRUE; + } else { + phy_status->tx_flowctrl = A_FALSE; + } + + return SW_OK; +} + +/****************************************************************************** +* +* qca808x_phy_get_speed - Determines the speed of phy ports associated with the +* specified device. +*/ + +sw_error_t +qca808x_phy_get_speed(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_speed_t * speed) +{ + sw_error_t rv = SW_OK; + struct port_phy_status phy_status = {0}; + + rv = qca808x_phy_get_status(dev_id, phy_id, &phy_status); + PHY_RTN_ON_ERROR(rv); + + if (phy_status.link_status == A_TRUE) { + *speed = phy_status.speed; + } else { + *speed = FAL_SPEED_10; + } + + return rv; +} + +/****************************************************************************** +* +* qca808x_phy_set_force_speed - Force the speed of qca808x phy ports associated with the +* specified device. +*/ +sw_error_t +qca808x_phy_set_force_speed(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_speed_t speed) +{ + a_uint16_t phy_data1 = 0; + a_uint16_t phy_data2 = 0; + sw_error_t rv = SW_OK; + + /* the speed of qca808x controled by MMD1 PMA/PMD control register */ + phy_data1 = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD1_NUM, + QCA808X_PHY_MMD1_PMA_CONTROL); + PHY_RTN_ON_READ_ERROR(phy_data1); + phy_data1 &= ~QCA808X_PMA_CONTROL_SPEED_MASK; + + phy_data2 = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD1_NUM, + QCA808X_PHY_MMD1_PMA_TYPE); + PHY_RTN_ON_READ_ERROR(phy_data2); + phy_data2 &= ~QCA808X_PMA_TYPE_MASK; + + switch(speed) + { + case FAL_SPEED_2500: + phy_data1 |= QCA808X_PMA_CONTROL_2500M; + phy_data2 |= QCA808X_PMA_TYPE_2500M; + break; + case FAL_SPEED_1000: + phy_data1 |= QCA808X_PMA_CONTROL_1000M; + phy_data2 |= QCA808X_PMA_TYPE_1000M; + break; + case FAL_SPEED_100: + phy_data1 |= QCA808X_PMA_CONTROL_100M; + phy_data2 |= QCA808X_PMA_TYPE_100M; + break; + case FAL_SPEED_10: + phy_data1 |= QCA808X_PMA_CONTROL_10M; + phy_data2 |= QCA808X_PMA_TYPE_10M; + break; + default: + return SW_BAD_PARAM; + } + + rv = qca808x_phy_mmd_write(dev_id, phy_id, QCA808X_PHY_MMD1_NUM, + QCA808X_PHY_MMD1_PMA_CONTROL, phy_data1); + PHY_RTN_ON_ERROR(rv); + + rv = qca808x_phy_mmd_write(dev_id, phy_id, QCA808X_PHY_MMD1_NUM, + QCA808X_PHY_MMD1_PMA_TYPE, phy_data2); + + return rv; +} + +sw_error_t +_qca808x_phy_set_autoneg_adv_ext(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t autoneg) +{ + a_uint16_t phy_data = 0; + sw_error_t rv = SW_OK; + + phy_data = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD7_NUM, + QCA808X_PHY_MMD7_AUTONEGOTIATION_CONTROL); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (autoneg & FAL_PHY_ADV_2500T_FD) { + phy_data |= QCA808X_ADVERTISE_2500FULL; + } else { + phy_data &= ~QCA808X_ADVERTISE_2500FULL; + } + + rv = qca808x_phy_mmd_write(dev_id, phy_id, QCA808X_PHY_MMD7_NUM, + QCA808X_PHY_MMD7_AUTONEGOTIATION_CONTROL, phy_data); + + return rv; + +} + +/****************************************************************************** +* +* qca808x_phy_set_speed - Determines the speed of phy ports associated with the +* specified device. +*/ +sw_error_t +qca808x_phy_set_speed(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_speed_t speed) +{ + a_uint16_t phy_data = 0; + fal_port_duplex_t old_duplex = QCA808X_CTRL_FULL_DUPLEX; + sw_error_t rv = SW_OK; + + phy_data = qca808x_phy_reg_read(dev_id, phy_id, QCA808X_PHY_CONTROL); + PHY_RTN_ON_READ_ERROR(phy_data); + + switch(speed) + { + case FAL_SPEED_2500: + case FAL_SPEED_1000: + if (speed == FAL_SPEED_2500) { + rv = _qca808x_phy_set_autoneg_adv_ext(dev_id, phy_id, + FAL_PHY_ADV_2500T_FD); + PHY_RTN_ON_ERROR(rv); + } else { + rv = _qca808x_phy_set_autoneg_adv_ext(dev_id, phy_id, + ~FAL_PHY_ADV_2500T_FD); + PHY_RTN_ON_ERROR(rv); + } + phy_data |= QCA808X_CTRL_FULL_DUPLEX; + phy_data |= QCA808X_CTRL_AUTONEGOTIATION_ENABLE; + phy_data |= QCA808X_CTRL_RESTART_AUTONEGOTIATION; + break; + case FAL_SPEED_100: + case FAL_SPEED_10: + /* set qca808x phy speed by pma control registers */ + rv = qca808x_phy_set_force_speed(dev_id, phy_id, speed); + PHY_RTN_ON_ERROR(rv); + rv = qca808x_phy_get_duplex(dev_id, phy_id, &old_duplex); + PHY_RTN_ON_ERROR(rv); + + if (old_duplex == FAL_FULL_DUPLEX) { + phy_data |= QCA808X_CTRL_FULL_DUPLEX; + } + else if (old_duplex == FAL_HALF_DUPLEX) { + phy_data &= ~QCA808X_CTRL_FULL_DUPLEX; + } + phy_data &= ~QCA808X_CTRL_AUTONEGOTIATION_ENABLE; + break; + default: + return SW_BAD_PARAM; + } + + rv = qca808x_phy_reg_write(dev_id, phy_id, QCA808X_PHY_CONTROL, phy_data); + + return rv; +} + +/****************************************************************************** +* +* qca808x_phy_set_duplex - Determines the duplex of phy ports associated with the +* specified device. +*/ +sw_error_t +qca808x_phy_set_duplex(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_duplex_t duplex) +{ + a_uint16_t phy_data = 0; + fal_port_speed_t old_speed; + sw_error_t rv = SW_OK; + + phy_data = qca808x_phy_reg_read(dev_id, phy_id, QCA808X_PHY_CONTROL); + PHY_RTN_ON_READ_ERROR(phy_data); + + rv = qca808x_phy_get_speed(dev_id, phy_id, &old_speed); + PHY_RTN_ON_ERROR(rv); + + switch(old_speed) + { + case FAL_SPEED_2500: + case FAL_SPEED_1000: + if (duplex == FAL_FULL_DUPLEX) { + phy_data |= QCA808X_CTRL_FULL_DUPLEX; + } else { + return SW_NOT_SUPPORTED; + } + phy_data |= QCA808X_CTRL_AUTONEGOTIATION_ENABLE; + + if (old_speed == FAL_SPEED_2500) { + rv = _qca808x_phy_set_autoneg_adv_ext(dev_id, phy_id, + FAL_PHY_ADV_2500T_FD); + PHY_RTN_ON_ERROR(rv); + } else { + rv = _qca808x_phy_set_autoneg_adv_ext(dev_id, phy_id, + ~FAL_PHY_ADV_2500T_FD); + PHY_RTN_ON_ERROR(rv); + } + break; + case FAL_SPEED_100: + case FAL_SPEED_10: + /* force the speed */ + rv = qca808x_phy_set_force_speed(dev_id, phy_id, old_speed); + PHY_RTN_ON_ERROR(rv); + phy_data &= ~QCA808X_CTRL_AUTONEGOTIATION_ENABLE; + if (duplex == FAL_FULL_DUPLEX) { + phy_data |= QCA808X_CTRL_FULL_DUPLEX; + } else { + phy_data &= ~QCA808X_CTRL_FULL_DUPLEX; + } + break; + default: + return SW_FAIL; + } + rv = qca808x_phy_reg_write(dev_id, phy_id, QCA808X_PHY_CONTROL, phy_data); + + return rv; +} + +/****************************************************************************** +* +* qca808x_phy_get_duplex - Determines the duplex of phy ports associated with the +* specified device. +*/ +sw_error_t +qca808x_phy_get_duplex(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_duplex_t * duplex) +{ + sw_error_t rv = SW_OK; + struct port_phy_status phy_status = {0}; + + rv = qca808x_phy_get_status(dev_id, phy_id, &phy_status); + PHY_RTN_ON_ERROR(rv); + + if (phy_status.link_status == A_TRUE) { + *duplex = phy_status.duplex; + } else { + *duplex = FAL_HALF_DUPLEX; + } + + return rv; +} + +/****************************************************************************** +* +* qca808x_phy_reset - reset the phy +* +* reset the phy +*/ +sw_error_t qca808x_phy_reset(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + sw_error_t rv = SW_OK; + + phy_data = qca808x_phy_reg_read(dev_id, phy_id, QCA808X_PHY_CONTROL); + PHY_RTN_ON_READ_ERROR(phy_data); + + rv = qca808x_phy_reg_write(dev_id, phy_id, QCA808X_PHY_CONTROL, + phy_data | QCA808X_CTRL_SOFTWARE_RESET); + SW_RTN_ON_ERROR(rv); + /*the configure will lost when reset.*/ + rv = qca808x_phy_ms_seed_enable(dev_id, phy_id, A_TRUE); + + return rv; +} +/****************************************************************************** +* +* qca808x_phy_status - test to see if the specified phy link is alive +* +* RETURNS: +* A_TRUE --> link is alive +* A_FALSE --> link is down +*/ +a_bool_t qca808x_phy_get_link_status(a_uint32_t dev_id, a_uint32_t phy_id) +{ + struct port_phy_status phy_status = {0}; + sw_error_t rv = SW_OK; + + rv = qca808x_phy_get_status(dev_id, phy_id, &phy_status); + if (rv == SW_OK) { + return phy_status.link_status; + } else { + return A_FALSE; + } +} +#ifndef IN_PORTCONTROL_MINI +/****************************************************************************** +* +* qca808x_phy_cdt - cable diagnostic test +* +* cable diagnostic test +*/ + +static inline fal_cable_status_t _phy_cdt_status_mapping(a_uint16_t status) +{ + fal_cable_status_t status_mapping = FAL_CABLE_STATUS_INVALID; + + switch (status) { + case 0: + status_mapping = FAL_CABLE_STATUS_INVALID; + break; + case 1: + status_mapping = FAL_CABLE_STATUS_NORMAL; + break; + case 2: + status_mapping = FAL_CABLE_STATUS_OPENED; + break; + case 3: + status_mapping = FAL_CABLE_STATUS_SHORT; + break; + } + + return status_mapping; +} + +static sw_error_t qca808x_phy_cdt_start(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t status = 0; + a_uint16_t ii = 100; + sw_error_t rv = SW_OK; + + /* RUN CDT */ + rv = qca808x_phy_reg_write(dev_id, phy_id, QCA808X_PHY_CDT_CONTROL, + QCA808X_RUN_CDT | QCA808X_CABLE_LENGTH_UNIT); + PHY_RTN_ON_ERROR(rv); + + do { + aos_mdelay(30); + status = + qca808x_phy_reg_read(dev_id, phy_id, QCA808X_PHY_CDT_CONTROL); + PHY_RTN_ON_READ_ERROR(status); + } + while ((status & QCA808X_RUN_CDT) && (--ii)); + + if (ii == 0) { + return SW_TIMEOUT; + } else { + return SW_OK; + } +} + +sw_error_t +qca808x_phy_cdt(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t mdi_pair, + fal_cable_status_t * cable_status, a_uint32_t * cable_len) +{ + a_uint16_t cable_delta_time = 0; + a_uint16_t status; + sw_error_t rv; + + if ((mdi_pair >= QCA808X_MDI_PAIR_NUM)) { + return SW_BAD_PARAM; + } + + rv = qca808x_phy_cdt_start(dev_id, phy_id); + + if (rv != SW_OK) { + *cable_status = FAL_CABLE_STATUS_INVALID; + *cable_len = 0; + return rv; + } + + /* Get cable status */ + status = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD3_NUM, + QCA808X_PHY_CDT_STATUS); + PHY_RTN_ON_READ_ERROR(status); + + switch (mdi_pair) { + case 0: + *cable_status = + _phy_cdt_status_mapping((status >> 12) & 0x3); + cable_delta_time = + qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD3_NUM, + QCA808X_PHY_CDT_DIAG_PAIR0); + PHY_RTN_ON_READ_ERROR(cable_delta_time); + + break; + case 1: + *cable_status = + _phy_cdt_status_mapping((status >> 8) & 0x3); + cable_delta_time = + qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD3_NUM, + QCA808X_PHY_CDT_DIAG_PAIR1); + PHY_RTN_ON_READ_ERROR(cable_delta_time); + + break; + case 2: + *cable_status = + _phy_cdt_status_mapping((status >> 4) & 0x3); + cable_delta_time = + qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD3_NUM, + QCA808X_PHY_CDT_DIAG_PAIR2); + PHY_RTN_ON_READ_ERROR(cable_delta_time); + + break; + case 3: + *cable_status = + _phy_cdt_status_mapping(status & 0x3); + cable_delta_time = + qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD3_NUM, + QCA808X_PHY_CDT_DIAG_PAIR3); + PHY_RTN_ON_READ_ERROR(cable_delta_time); + + break; + } + + /* the actual cable length equals to CableDeltaTime * 0.824 */ + *cable_len = ((cable_delta_time & 0xff) * 824) / 1000; + + return rv; +} + +/****************************************************************************** +* +* qca808x_phy_set_mdix - +* +* set phy mdix configuraiton +*/ +sw_error_t +qca808x_phy_set_mdix(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_mdix_mode_t mode) +{ + a_uint16_t phy_data; + sw_error_t rv; + + phy_data = qca808x_phy_reg_read(dev_id, phy_id, QCA808X_PHY_SPEC_CONTROL); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (mode == PHY_MDIX_AUTO) { + phy_data |= QCA808X_PHY_MDIX_AUTO; + } else if (mode == PHY_MDIX_MDIX) { + phy_data &= ~QCA808X_PHY_MDIX_AUTO; + phy_data |= QCA808X_PHY_MDIX; + } else if (mode == PHY_MDIX_MDI) { + phy_data &= ~QCA808X_PHY_MDIX_AUTO; + } else { + return SW_BAD_PARAM; + } + + rv = qca808x_phy_reg_write(dev_id, phy_id, QCA808X_PHY_SPEC_CONTROL, phy_data); + PHY_RTN_ON_ERROR(rv); + + rv = qca808x_phy_reset(dev_id, phy_id); + return rv; +} + +/****************************************************************************** +* +* qca808x_phy_get_mdix +* +* get phy mdix configuration +*/ +sw_error_t +qca808x_phy_get_mdix(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_mdix_mode_t * mode) +{ + a_uint16_t phy_data; + + phy_data = qca808x_phy_reg_read(dev_id, phy_id, QCA808X_PHY_SPEC_CONTROL); + PHY_RTN_ON_READ_ERROR(phy_data); + + if ((phy_data & QCA808X_PHY_MDIX_AUTO) == QCA808X_PHY_MDIX_AUTO) { + *mode = PHY_MDIX_AUTO; + } else if ((phy_data & QCA808X_PHY_MDIX) == QCA808X_PHY_MDIX) { + *mode = PHY_MDIX_MDIX; + } else { + *mode = PHY_MDIX_MDI; + } + + return SW_OK; + +} + +/****************************************************************************** +* +* qca808x_phy_get_mdix status +* +* get phy mdix status +*/ +sw_error_t +qca808x_phy_get_mdix_status(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_mdix_status_t * mode) +{ + a_uint16_t phy_data; + + phy_data = qca808x_phy_reg_read(dev_id, phy_id, QCA808X_PHY_SPEC_STATUS); + PHY_RTN_ON_READ_ERROR(phy_data); + + *mode = + (phy_data & QCA808X_PHY_MDIX_STATUS) ? PHY_MDIX_STATUS_MDIX : + PHY_MDIX_STATUS_MDI; + + return SW_OK; + +} + +/****************************************************************************** +* +* qca808x_phy_set_local_loopback +* +* set phy local loopback +*/ +sw_error_t +qca808x_phy_set_local_loopback(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t enable) +{ + a_uint16_t phy_data; + fal_port_speed_t old_speed; + sw_error_t rv = SW_OK; + + phy_data = qca808x_phy_reg_read(dev_id, phy_id, QCA808X_PHY_CONTROL); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (enable == A_TRUE) { + /* get the link speed first, then force the corresponding + * speed to enable local loopback */ + rv = qca808x_phy_get_speed(dev_id, phy_id, &old_speed); + PHY_RTN_ON_ERROR(rv); + rv = qca808x_phy_set_force_speed(dev_id, phy_id, old_speed); + PHY_RTN_ON_ERROR(rv); + + phy_data &= ~QCA808X_CTRL_AUTONEGOTIATION_ENABLE; + phy_data |= QCA808X_LOCAL_LOOPBACK_ENABLE; + phy_data |= QCA808X_CTRL_FULL_DUPLEX; + } else { + phy_data = QCA808X_COMMON_CTRL; + } + + rv = qca808x_phy_reg_write(dev_id, phy_id, QCA808X_PHY_CONTROL, phy_data); + return rv; +} + +/****************************************************************************** +* +* qca808x_phy_get_local_loopback +* +* get phy local loopback +*/ +sw_error_t +qca808x_phy_get_local_loopback(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t * enable) +{ + a_uint16_t phy_data; + + phy_data = qca808x_phy_reg_read(dev_id, phy_id, QCA808X_PHY_CONTROL); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (phy_data & QCA808X_LOCAL_LOOPBACK_ENABLE) { + *enable = A_TRUE; + } else { + *enable = A_FALSE; + } + + return SW_OK; + +} + +/****************************************************************************** +* +* qca808x_phy_set_remote_loopback +* +* set phy remote loopback +*/ +sw_error_t +qca808x_phy_set_remote_loopback(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t enable) +{ + a_uint16_t phy_data; + sw_error_t rv = SW_OK; + + phy_data = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD3_NUM, + QCA808X_PHY_MMD3_ADDR_REMOTE_LOOPBACK_CTRL); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (enable == A_TRUE) { + phy_data |= QCA808X_PHY_REMOTE_LOOPBACK_EN; + } else { + phy_data &= ~QCA808X_PHY_REMOTE_LOOPBACK_EN; + } + + rv = qca808x_phy_mmd_write(dev_id, phy_id, QCA808X_PHY_MMD3_NUM, + QCA808X_PHY_MMD3_ADDR_REMOTE_LOOPBACK_CTRL, + phy_data); + return rv; + +} + +/****************************************************************************** +* +* qca808x_phy_get_remote_loopback +* +* get phy remote loopback +*/ +sw_error_t +qca808x_phy_get_remote_loopback(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t * enable) +{ + a_uint16_t phy_data; + + phy_data = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD3_NUM, + QCA808X_PHY_MMD3_ADDR_REMOTE_LOOPBACK_CTRL); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (phy_data & QCA808X_PHY_REMOTE_LOOPBACK_EN) { + *enable = A_TRUE; + } else { + *enable = A_FALSE; + } + + return SW_OK; + +} +#endif +/****************************************************************************** +* +* qca808x_set_autoneg_adv - set the phy autoneg Advertisement +* +*/ +sw_error_t +qca808x_phy_set_autoneg_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t autoneg) +{ + a_uint16_t phy_data = 0; + sw_error_t rv = SW_OK; + + phy_data = qca808x_phy_reg_read(dev_id, phy_id, + QCA808X_AUTONEG_ADVERT); + PHY_RTN_ON_READ_ERROR(phy_data); + + phy_data &= ~QCA808X_ADVERTISE_MEGA_ALL; + + if (autoneg & FAL_PHY_ADV_100TX_FD) { + phy_data |= QCA808X_ADVERTISE_100FULL; + } + + if (autoneg & FAL_PHY_ADV_100TX_HD) { + phy_data |= QCA808X_ADVERTISE_100HALF; + } + + if (autoneg & FAL_PHY_ADV_10T_FD) { + phy_data |= QCA808X_ADVERTISE_10FULL; + } + + if (autoneg & FAL_PHY_ADV_10T_HD) { + phy_data |= QCA808X_ADVERTISE_10HALF; + } + + if (autoneg & FAL_PHY_ADV_PAUSE) { + phy_data |= QCA808X_ADVERTISE_PAUSE; + } + + if (autoneg & FAL_PHY_ADV_ASY_PAUSE) { + phy_data |= QCA808X_ADVERTISE_ASYM_PAUSE; + } + rv = qca808x_phy_reg_write(dev_id, phy_id, QCA808X_AUTONEG_ADVERT, + phy_data); + PHY_RTN_ON_ERROR(rv); + + phy_data = qca808x_phy_reg_read(dev_id, phy_id, + QCA808X_1000BASET_CONTROL); + PHY_RTN_ON_READ_ERROR(phy_data); + + phy_data &= ~QCA808X_ADVERTISE_1000FULL; + phy_data &= ~QCA808X_ADVERTISE_1000HALF; + + if (autoneg & FAL_PHY_ADV_1000T_FD) { + phy_data |= QCA808X_ADVERTISE_1000FULL; + } + + rv = qca808x_phy_reg_write(dev_id, phy_id, QCA808X_1000BASET_CONTROL, + phy_data); + PHY_RTN_ON_ERROR(rv); + + if (qca808x_phy_2500caps(dev_id, phy_id) == A_TRUE) { + rv = _qca808x_phy_set_autoneg_adv_ext(dev_id, phy_id, autoneg); + } + + return rv; +} + +sw_error_t +_qca808x_phy_get_autoneg_adv_ext(a_uint32_t dev_id, a_uint32_t phy_id, a_uint16_t *phy_data) +{ + *phy_data = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD7_NUM, + QCA808X_PHY_MMD7_AUTONEGOTIATION_CONTROL); + PHY_RTN_ON_READ_ERROR(*phy_data); + + return SW_OK; +} + +/****************************************************************************** +* +* qca808x_get_autoneg_adv - get the phy autoneg Advertisement +* +*/ +sw_error_t +qca808x_phy_get_autoneg_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * autoneg) +{ + a_uint16_t phy_data = 0; + sw_error_t rv = SW_OK; + + *autoneg = 0; + phy_data = + qca808x_phy_reg_read(dev_id, phy_id, QCA808X_AUTONEG_ADVERT); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (phy_data & QCA808X_ADVERTISE_100FULL) { + *autoneg |= FAL_PHY_ADV_100TX_FD; + } + + if (phy_data & QCA808X_ADVERTISE_100HALF) { + *autoneg |= FAL_PHY_ADV_100TX_HD; + } + + if (phy_data & QCA808X_ADVERTISE_10FULL) { + *autoneg |= FAL_PHY_ADV_10T_FD; + } + + if (phy_data & QCA808X_ADVERTISE_10HALF) { + *autoneg |= FAL_PHY_ADV_10T_HD; + } + + if (phy_data & QCA808X_ADVERTISE_PAUSE) { + *autoneg |= FAL_PHY_ADV_PAUSE; + } + + if (phy_data & QCA808X_ADVERTISE_ASYM_PAUSE) { + *autoneg |= FAL_PHY_ADV_ASY_PAUSE; + } + + phy_data = qca808x_phy_reg_read(dev_id, phy_id, + QCA808X_1000BASET_CONTROL); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (phy_data & QCA808X_ADVERTISE_1000FULL) { + *autoneg |= FAL_PHY_ADV_1000T_FD; + } + + if (qca808x_phy_2500caps(dev_id, phy_id) == A_TRUE) { + rv = _qca808x_phy_get_autoneg_adv_ext(dev_id, phy_id, &phy_data); + if ((rv == SW_OK) && + (phy_data & QCA808X_ADVERTISE_2500FULL)) { + *autoneg |= FAL_PHY_ADV_2500T_FD; + } + } + + return rv; +} + +/****************************************************************************** +* +* qca808x_phy_autoneg_status - get the phy autoneg status +* +*/ +a_bool_t qca808x_phy_autoneg_status(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + + phy_data = qca808x_phy_reg_read(dev_id, phy_id, QCA808X_PHY_CONTROL); + + if (phy_data & QCA808X_CTRL_AUTONEGOTIATION_ENABLE) { + return A_TRUE; + } + + return A_FALSE; +} + +/****************************************************************************** +* +* qca808x_restart_autoneg - restart the phy autoneg +* +*/ +sw_error_t qca808x_phy_restart_autoneg(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data = 0; + sw_error_t rv = SW_OK; + + phy_data = qca808x_phy_reg_read(dev_id, phy_id, QCA808X_PHY_CONTROL); + PHY_RTN_ON_READ_ERROR(phy_data); + + phy_data |= QCA808X_CTRL_AUTONEGOTIATION_ENABLE; + rv = qca808x_phy_reg_write(dev_id, phy_id, QCA808X_PHY_CONTROL, + phy_data | QCA808X_CTRL_RESTART_AUTONEGOTIATION); + + return rv; +} + +/****************************************************************************** +* +* qca808x_phy_enable_autonego +* +*/ +sw_error_t qca808x_phy_enable_autoneg(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data = 0; + sw_error_t rv = SW_OK; + + phy_data = qca808x_phy_reg_read(dev_id, phy_id, QCA808X_PHY_CONTROL); + PHY_RTN_ON_READ_ERROR(phy_data); + + rv = qca808x_phy_reg_write(dev_id, phy_id, QCA808X_PHY_CONTROL, + phy_data | QCA808X_CTRL_AUTONEGOTIATION_ENABLE); + + return rv; +} + +/****************************************************************************** +* +* qca808x_phy_get_phy_id - get the phy id +* +*/ +sw_error_t +qca808x_phy_get_phy_id(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *phy_data) +{ + a_uint16_t org_id, rev_id; + org_id = qca808x_phy_reg_read(dev_id, phy_id, QCA808X_PHY_ID1); + PHY_RTN_ON_READ_ERROR(org_id); + + rev_id = qca808x_phy_reg_read(dev_id, phy_id, QCA808X_PHY_ID2); + PHY_RTN_ON_READ_ERROR(rev_id); + + *phy_data = ((org_id & 0xffff) << 16) | (rev_id & 0xffff); + + return SW_OK; +} + +/****************************************************************************** +* +* qca808x_phy_off - power off the phy +* +* Power off the phy +*/ +sw_error_t qca808x_phy_poweroff(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + sw_error_t rv = SW_OK; + + phy_data = qca808x_phy_reg_read(dev_id, phy_id, QCA808X_PHY_CONTROL); + PHY_RTN_ON_READ_ERROR(phy_data); + + rv = qca808x_phy_reg_write(dev_id, phy_id, QCA808X_PHY_CONTROL, + phy_data | QCA808X_CTRL_POWER_DOWN); + return rv; +} + +/****************************************************************************** +* +* qca808x_phy_on - power on the phy +* +* Power on the phy +*/ +sw_error_t qca808x_phy_poweron(a_uint32_t dev_id, a_uint32_t phy_id) +{ + a_uint16_t phy_data; + sw_error_t rv = SW_OK; + + phy_data = qca808x_phy_reg_read(dev_id, phy_id, QCA808X_PHY_CONTROL); + PHY_RTN_ON_READ_ERROR(phy_data); + + rv = qca808x_phy_reg_write(dev_id, phy_id, QCA808X_PHY_CONTROL, + phy_data & ~QCA808X_CTRL_POWER_DOWN); + + aos_mdelay(200); + + return rv; +} +#ifndef IN_PORTCONTROL_MINI +/****************************************************************************** +* +* qca808x_phy_set_802.3az +* +* set 802.3az status +*/ +sw_error_t +qca808x_phy_set_8023az(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable) +{ + a_uint16_t phy_data; + sw_error_t rv = SW_OK; + + phy_data = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD7_NUM, + QCA808X_PHY_MMD7_ADDR_8023AZ_EEE_CTRL); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (enable == A_TRUE) { + phy_data |= QCA808X_PHY_8023AZ_EEE_1000BT; + phy_data |= QCA808X_PHY_8023AZ_EEE_100BT; + } else { + phy_data &= ~QCA808X_PHY_8023AZ_EEE_1000BT; + phy_data &= ~QCA808X_PHY_8023AZ_EEE_100BT; + } + + rv = qca808x_phy_mmd_write(dev_id, phy_id, QCA808X_PHY_MMD7_NUM, + QCA808X_PHY_MMD7_ADDR_8023AZ_EEE_CTRL, phy_data); + PHY_RTN_ON_ERROR(rv); + + rv = qca808x_phy_restart_autoneg(dev_id, phy_id); + + return rv; +} + +/****************************************************************************** +* +* qca808x_phy_get_8023az status +* +* get 8023az status +*/ +sw_error_t +qca808x_phy_get_8023az(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t * enable) +{ + a_uint16_t phy_data; + *enable = A_FALSE; + + phy_data = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD7_NUM, + QCA808X_PHY_MMD7_ADDR_8023AZ_EEE_CTRL); + PHY_RTN_ON_READ_ERROR(phy_data); + + if ((phy_data & QCA808X_PHY_8023AZ_EEE_1000BT) && + (phy_data & QCA808X_PHY_8023AZ_EEE_100BT)) { + *enable = A_TRUE; + } + + return SW_OK; +} + +/****************************************************************************** +* +* _qca808x_phy_get_8023az_status status +* +* get 8023az status +*/ +sw_error_t +_qca808x_phy_get_8023az_status(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t * enable) +{ + a_uint16_t phy_data; + *enable = A_FALSE; + + phy_data = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD3_NUM, + QCA808X_PHY_MMD3_ADDR_8023AZ_EEE_DB); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (phy_data & QCA808X_PHY_8023AZ_EEE_LP_STAT) { + *enable = A_TRUE; + } + + return SW_OK; +} + +/****************************************************************************** +* +* qca808x_phy_set wol frame mac address +* +* set phy wol frame mac address +*/ +sw_error_t +qca808x_phy_set_magic_frame_mac(a_uint32_t dev_id, a_uint32_t phy_id, + fal_mac_addr_t * mac) +{ + a_uint16_t phy_data1; + a_uint16_t phy_data2; + a_uint16_t phy_data3; + sw_error_t rv = SW_OK; + + phy_data1 = (mac->uc[0] << 8) | mac->uc[1]; + phy_data2 = (mac->uc[2] << 8) | mac->uc[3]; + phy_data3 = (mac->uc[4] << 8) | mac->uc[5]; + + rv = qca808x_phy_mmd_write(dev_id, phy_id, QCA808X_PHY_MMD3_NUM, + QCA808X_PHY_MMD3_WOL_MAGIC_MAC_CTRL1, phy_data1); + PHY_RTN_ON_ERROR(rv); + + rv = qca808x_phy_mmd_write(dev_id, phy_id, QCA808X_PHY_MMD3_NUM, + QCA808X_PHY_MMD3_WOL_MAGIC_MAC_CTRL2, phy_data2); + PHY_RTN_ON_ERROR(rv); + + rv = qca808x_phy_mmd_write(dev_id, phy_id, QCA808X_PHY_MMD3_NUM, + QCA808X_PHY_MMD3_WOL_MAGIC_MAC_CTRL3, phy_data3); + + return rv; +} + +/****************************************************************************** +* +* qca808x_phy_get wol frame mac address +* +* get phy wol frame mac address +*/ +sw_error_t +qca808x_phy_get_magic_frame_mac(a_uint32_t dev_id, a_uint32_t phy_id, + fal_mac_addr_t * mac) +{ + a_uint16_t phy_data1; + a_uint16_t phy_data2; + a_uint16_t phy_data3; + + phy_data1 = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD3_NUM, + QCA808X_PHY_MMD3_WOL_MAGIC_MAC_CTRL1); + PHY_RTN_ON_READ_ERROR(phy_data1); + + phy_data2 = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD3_NUM, + QCA808X_PHY_MMD3_WOL_MAGIC_MAC_CTRL2); + PHY_RTN_ON_READ_ERROR(phy_data2); + + phy_data3 = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD3_NUM, + QCA808X_PHY_MMD3_WOL_MAGIC_MAC_CTRL3); + PHY_RTN_ON_READ_ERROR(phy_data3); + + mac->uc[0] = (phy_data1 >> 8); + mac->uc[1] = (phy_data1 & 0x00ff); + mac->uc[2] = (phy_data2 >> 8); + mac->uc[3] = (phy_data2 & 0x00ff); + mac->uc[4] = (phy_data3 >> 8); + mac->uc[5] = (phy_data3 & 0x00ff); + + return SW_OK; +} + +/****************************************************************************** +* +* qca808x_phy_set wol enable or disable +* +* set phy wol enable or disable +*/ +sw_error_t +qca808x_phy_set_wol_status(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable) +{ + a_uint16_t phy_data; + sw_error_t rv = SW_OK; + + phy_data = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD3_NUM, + QCA808X_PHY_MMD3_WOL_CTRL); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (enable == A_TRUE) { + phy_data |= QCA808X_PHY_WOL_EN; + } else { + phy_data &= ~QCA808X_PHY_WOL_EN; + } + + rv = qca808x_phy_mmd_write(dev_id, phy_id, QCA808X_PHY_MMD3_NUM, + QCA808X_PHY_MMD3_WOL_CTRL, phy_data); + + return rv; +} + +/****************************************************************************** +* +* qca808x_phy_get_wol status +* +* get wol status +*/ +sw_error_t +qca808x_phy_get_wol_status(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t * enable) +{ + a_uint16_t phy_data; + + *enable = A_FALSE; + + phy_data = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD3_NUM, + QCA808X_PHY_MMD3_WOL_CTRL); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (phy_data & QCA808X_PHY_WOL_EN) { + *enable = A_TRUE; + } + + return SW_OK; +} + +/****************************************************************************** +* +* qca808x_phy_set_hibernate - set hibernate status +* +* set hibernate status +*/ +sw_error_t +qca808x_phy_set_hibernate(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable) +{ + a_uint16_t phy_data; + sw_error_t rv = SW_OK; + + phy_data = qca808x_phy_debug_read(dev_id, phy_id, + QCA808X_DEBUG_PHY_HIBERNATION_CTRL); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (enable == A_TRUE) { + phy_data |= QCA808X_PHY_HIBERNATION_CFG; + } else { + phy_data &= ~QCA808X_PHY_HIBERNATION_CFG; + } + + rv = qca808x_phy_debug_write(dev_id, phy_id, + QCA808X_DEBUG_PHY_HIBERNATION_CTRL, phy_data); + + return rv; +} + +/****************************************************************************** +* +* qca808x_phy_get_hibernate - get hibernate status +* +* get hibernate status +*/ +sw_error_t +qca808x_phy_get_hibernate(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t * enable) +{ + a_uint16_t phy_data; + + *enable = A_FALSE; + + phy_data = qca808x_phy_debug_read(dev_id, phy_id, + QCA808X_DEBUG_PHY_HIBERNATION_CTRL); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (phy_data & QCA808X_PHY_HIBERNATION_CFG) { + *enable = A_TRUE; + } + + return SW_OK; +} + +/****************************************************************************** +* +* _qca808x_phy_get_hibernate_status - get hibernate status +* +* get hibernate status +*/ +sw_error_t +_qca808x_phy_get_hibernate_status(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t * enable) +{ + a_uint16_t phy_data; + + *enable = A_TRUE; + + phy_data = qca808x_phy_debug_read(dev_id, phy_id, + QCA808X_DEBUG_PHY_HIBERNATION_STAT); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (phy_data & QCA808X_PHY_HIBERNATION_STAT_EN) { + *enable = A_FALSE; + } + + return SW_OK; +} +#endif +/****************************************************************************** +* +* qca808x_phy_interface mode set +* +* set qca808x phy interface mode +*/ +sw_error_t +qca808x_phy_interface_set_mode(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_interface_mode_t interface_mode) +{ + /* qca808x phy will automatically switch the interface mode according + * to the speed, 2.5G works on SGMII+, other works on SGMII. + */ + + return SW_OK; +} + +/****************************************************************************** +* +* qca808x_phy_interface mode get +* +* get qca808x phy interface mode +*/ +sw_error_t +qca808x_phy_interface_get_mode(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_interface_mode_t *interface_mode) +{ + a_uint16_t phy_data; + phy_data = qca808x_phy_reg_read(dev_id, phy_id, QCA808X_PHY_CHIP_CONFIG); + PHY_RTN_ON_READ_ERROR(phy_data); + + phy_data &= QCA808X_PHY_CHIP_MODE_CFG; + if (phy_data == QCA808X_PHY_SGMII_BASET) { + *interface_mode = PHY_SGMII_BASET; + } + + return SW_OK; +} + +/****************************************************************************** +* +* qca808x_phy_interface mode status get +* +* get qca808x phy interface mode status +*/ +sw_error_t +qca808x_phy_interface_get_mode_status(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_interface_mode_t *interface_mode_status) +{ + a_uint16_t phy_data; + phy_data = qca808x_phy_reg_read(dev_id, phy_id, QCA808X_PHY_CHIP_CONFIG); + PHY_RTN_ON_READ_ERROR(phy_data); + + phy_data &= QCA808X_PHY_MODE_MASK; + switch (phy_data) { + case QCA808X_PHY_SGMII_PLUS_MODE: + *interface_mode_status = PORT_SGMII_PLUS; + break; + case QCA808X_PHY_SGMII_MODE: + *interface_mode_status = PHY_SGMII_BASET; + break; + default: + *interface_mode_status = PORT_INTERFACE_MODE_MAX; + break; + } + + return SW_OK; +} +#ifndef IN_PORTCONTROL_MINI +/****************************************************************************** +* +* qca808x_phy_set_intr_mask - Set interrupt mask with the +* specified device. +*/ +sw_error_t +qca808x_phy_set_intr_mask(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t intr_mask_flag) +{ + a_uint16_t phy_data = 0; + sw_error_t rv = SW_OK; + + phy_data = qca808x_phy_reg_read(dev_id, phy_id, QCA808X_PHY_INTR_MASK); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (intr_mask_flag & FAL_PHY_INTR_STATUS_UP_CHANGE) { + phy_data |= QCA808X_INTR_STATUS_UP_CHANGE; + } else { + phy_data &= (~QCA808X_INTR_STATUS_UP_CHANGE); + } + + if (intr_mask_flag & FAL_PHY_INTR_STATUS_DOWN_CHANGE) { + phy_data |= QCA808X_INTR_STATUS_DOWN_CHANGE; + } else { + phy_data &= (~QCA808X_INTR_STATUS_DOWN_CHANGE); + } + + if (intr_mask_flag & FAL_PHY_INTR_SPEED_CHANGE) { + phy_data |= QCA808X_INTR_SPEED_CHANGE; + } else { + phy_data &= (~QCA808X_INTR_SPEED_CHANGE); + } + + if (intr_mask_flag & FAL_PHY_INTR_BX_FX_STATUS_UP_CHANGE) { + phy_data |= QCA808X_INTR_LINK_SUCCESS_SG; + } else { + phy_data &= (~QCA808X_INTR_LINK_SUCCESS_SG); + } + + if (intr_mask_flag & FAL_PHY_INTR_BX_FX_STATUS_DOWN_CHANGE) { + phy_data |= QCA808X_INTR_LINK_FAIL_SG; + } else { + phy_data &= (~QCA808X_INTR_LINK_FAIL_SG); + } + + if (intr_mask_flag & FAL_PHY_INTR_WOL_STATUS) { + phy_data |= QCA808X_INTR_WOL; + } else { + phy_data &= (~QCA808X_INTR_WOL); + } + + if (intr_mask_flag & FAL_PHY_INTR_POE_STATUS) { + phy_data |= QCA808X_INTR_POE; + } else { + phy_data &= (~QCA808X_INTR_POE); + } + + rv = qca808x_phy_reg_write(dev_id, phy_id, QCA808X_PHY_INTR_MASK, phy_data); + return rv; +} + +/****************************************************************************** +* +* qca808x_phy_get_intr_mask - Get interrupt mask with the +* specified device. +*/ +sw_error_t +qca808x_phy_get_intr_mask(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * intr_mask_flag) +{ + a_uint16_t phy_data = 0; + + phy_data = qca808x_phy_reg_read(dev_id, phy_id, QCA808X_PHY_INTR_MASK); + PHY_RTN_ON_READ_ERROR(phy_data); + + *intr_mask_flag = 0; + if (phy_data & QCA808X_INTR_STATUS_UP_CHANGE) { + *intr_mask_flag |= FAL_PHY_INTR_STATUS_UP_CHANGE; + } + + if (phy_data & QCA808X_INTR_STATUS_DOWN_CHANGE) { + *intr_mask_flag |= FAL_PHY_INTR_STATUS_DOWN_CHANGE; + } + + if (phy_data & QCA808X_INTR_SPEED_CHANGE) { + *intr_mask_flag |= FAL_PHY_INTR_SPEED_CHANGE; + } + + if (phy_data & QCA808X_INTR_LINK_SUCCESS_SG) { + *intr_mask_flag |= FAL_PHY_INTR_BX_FX_STATUS_UP_CHANGE; + } + + if (phy_data & QCA808X_INTR_LINK_FAIL_SG) { + *intr_mask_flag |= FAL_PHY_INTR_BX_FX_STATUS_DOWN_CHANGE; + } + + if (phy_data & QCA808X_INTR_WOL) { + *intr_mask_flag |= FAL_PHY_INTR_WOL_STATUS; + } + + if (phy_data & QCA808X_INTR_POE) { + *intr_mask_flag |= FAL_PHY_INTR_POE_STATUS; + } + + return SW_OK; +} + +/****************************************************************************** +* +* qca808x_phy_get_intr_status - Get interrupt status with the +* specified device. +*/ +sw_error_t +qca808x_phy_get_intr_status(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t * intr_status_flag) +{ + a_uint16_t phy_data = 0; + + phy_data = qca808x_phy_reg_read(dev_id, phy_id, QCA808X_PHY_INTR_STATUS); + PHY_RTN_ON_READ_ERROR(phy_data); + + *intr_status_flag = 0; + if (phy_data & QCA808X_INTR_STATUS_UP_CHANGE) { + *intr_status_flag |= FAL_PHY_INTR_STATUS_UP_CHANGE; + } + + if (phy_data & QCA808X_INTR_STATUS_DOWN_CHANGE) { + *intr_status_flag |= FAL_PHY_INTR_STATUS_DOWN_CHANGE; + } + + if (phy_data & QCA808X_INTR_SPEED_CHANGE) { + *intr_status_flag |= FAL_PHY_INTR_SPEED_CHANGE; + } + + if (phy_data & QCA808X_INTR_LINK_SUCCESS_SG) { + *intr_status_flag |= FAL_PHY_INTR_BX_FX_STATUS_UP_CHANGE; + } + + if (phy_data & QCA808X_INTR_LINK_FAIL_SG) { + *intr_status_flag |= FAL_PHY_INTR_BX_FX_STATUS_DOWN_CHANGE; + } + + if (phy_data & QCA808X_INTR_WOL) { + *intr_status_flag |= FAL_PHY_INTR_WOL_STATUS; + } + + if (phy_data & QCA808X_INTR_POE) { + *intr_status_flag |= FAL_PHY_INTR_POE_STATUS; + } + + return SW_OK; +} + +/****************************************************************************** +* +* qca808x_phy_set_counter - set counter status +* +* set counter status +*/ +sw_error_t +qca808x_phy_set_counter(a_uint32_t dev_id, a_uint32_t phy_id, a_bool_t enable) +{ + a_uint16_t phy_data; + sw_error_t rv = SW_OK; + + phy_data = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD7_NUM, + QCA808X_PHY_MMD7_COUNTER_CTRL); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (enable == A_TRUE) { + phy_data |= QCA808X_PHY_FRAME_CHECK_EN; + phy_data |= QCA808X_PHY_XMIT_MAC_CNT_SELFCLR; + } else { + phy_data &= ~QCA808X_PHY_FRAME_CHECK_EN; + phy_data &= ~QCA808X_PHY_XMIT_MAC_CNT_SELFCLR; + } + + rv = qca808x_phy_mmd_write(dev_id, phy_id, QCA808X_PHY_MMD7_NUM, + QCA808X_PHY_MMD7_COUNTER_CTRL, phy_data); + + return rv; +} + +/****************************************************************************** +* +* qca808x_phy_get_counter_status - get counter status +* +* set counter status +*/ +sw_error_t +qca808x_phy_get_counter(a_uint32_t dev_id, a_uint32_t phy_id, + a_bool_t * enable) +{ + a_uint16_t phy_data; + + phy_data = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD7_NUM, + QCA808X_PHY_MMD7_COUNTER_CTRL); + PHY_RTN_ON_READ_ERROR(phy_data); + + if (phy_data & QCA808X_PHY_FRAME_CHECK_EN) { + *enable = A_TRUE; + } else { + *enable = A_FALSE; + } + + return SW_OK; +} + +/****************************************************************************** +* +* qca808x_phy_show show counter statistics +* +* show counter statistics +*/ +sw_error_t +qca808x_phy_show_counter(a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_counter_info_t * counter_infor) +{ + a_uint16_t ingress_high_counter = 0; + a_uint16_t ingress_low_counter = 0; + a_uint16_t egress_high_counter = 0; + a_uint16_t egress_low_counter = 0; + + ingress_high_counter = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD7_NUM, + QCA808X_PHY_MMD7_INGRESS_COUNTER_HIGH); + ingress_low_counter = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD7_NUM, + QCA808X_PHY_MMD7_INGRESS_COUNTER_LOW); + counter_infor->RxGoodFrame = (ingress_high_counter << 16 ) | ingress_low_counter; + counter_infor->RxBadCRC = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD7_NUM, + QCA808X_PHY_MMD7_INGRESS_ERROR_COUNTER); + + egress_high_counter = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD7_NUM, + QCA808X_PHY_MMD7_EGRESS_COUNTER_HIGH); + egress_low_counter = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD7_NUM, + QCA808X_PHY_MMD7_EGRESS_COUNTER_LOW); + counter_infor->TxGoodFrame = (egress_high_counter << 16 ) | egress_low_counter; + counter_infor->TxBadCRC = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD7_NUM, + QCA808X_PHY_MMD7_EGRESS_ERROR_COUNTER); + + return SW_OK; +} +#endif +/****************************************************************************** +* +* qca808x_phy_set_eee_advertisement +* +* set eee advertisement +*/ +sw_error_t +qca808x_phy_set_eee_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t adv) +{ + a_uint16_t phy_data = 0; + sw_error_t rv = SW_OK; + + phy_data = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD7_NUM, + QCA808X_PHY_MMD7_ADDR_8023AZ_EEE_CTRL); + phy_data &= ~(QCA808X_PHY_EEE_ADV_100M | QCA808X_PHY_EEE_ADV_1000M); + + if (adv & FAL_PHY_EEE_100BASE_T) { + phy_data |= QCA808X_PHY_EEE_ADV_100M; + } + if (adv & FAL_PHY_EEE_1000BASE_T) { + phy_data |= QCA808X_PHY_EEE_ADV_1000M; + } + + rv = qca808x_phy_mmd_write(dev_id, phy_id, QCA808X_PHY_MMD7_NUM, + QCA808X_PHY_MMD7_ADDR_8023AZ_EEE_CTRL, phy_data); + + rv = qca808x_phy_restart_autoneg(dev_id, phy_id); + + return rv; +} + +/****************************************************************************** +* +* qca808x_phy_get_eee_advertisement +* +* get eee advertisement +*/ +sw_error_t +qca808x_phy_get_eee_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *adv) +{ + a_uint16_t phy_data = 0; + sw_error_t rv = SW_OK; + + *adv = 0; + phy_data = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD7_NUM, + QCA808X_PHY_MMD7_ADDR_8023AZ_EEE_CTRL); + + if (phy_data & QCA808X_PHY_EEE_ADV_100M) { + *adv |= FAL_PHY_EEE_100BASE_T; + } + if (phy_data & QCA808X_PHY_EEE_ADV_1000M) { + *adv |= FAL_PHY_EEE_1000BASE_T; + } + + return rv; +} +/****************************************************************************** +* +* qca808x_phy_get_eee_partner_advertisement +* +* get eee partner advertisement +*/ +sw_error_t +qca808x_phy_get_eee_partner_adv(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *adv) +{ + a_uint16_t phy_data = 0; + sw_error_t rv = SW_OK; + + *adv = 0; + phy_data = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD7_NUM, + QCA808X_PHY_MMD7_ADDR_8023AZ_EEE_PARTNER); + + if (phy_data & QCA808X_PHY_EEE_PARTNER_ADV_100M) { + *adv |= FAL_PHY_EEE_100BASE_T; + } + if (phy_data & QCA808X_PHY_EEE_PARTNER_ADV_1000M) { + *adv |= FAL_PHY_EEE_1000BASE_T; + } + + return rv; +} +/****************************************************************************** +* +* qca808x_phy_get_eee_capability +* +* get eee capability +*/ +sw_error_t +qca808x_phy_get_eee_cap(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *cap) +{ + a_uint16_t phy_data = 0; + sw_error_t rv = SW_OK; + + *cap = 0; + phy_data = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD3_NUM, + QCA808X_PHY_MMD3_ADDR_8023AZ_EEE_CAPABILITY); + + if (phy_data & QCA808X_PHY_EEE_CAPABILITY_100M) { + *cap |= FAL_PHY_EEE_100BASE_T; + } + if (phy_data & QCA808X_PHY_EEE_CAPABILITY_1000M) { + *cap |= FAL_PHY_EEE_1000BASE_T; + } + + return rv; +} +/****************************************************************************** +* +* qca808x_phy_get_eee_status +* +* get eee status +*/ +sw_error_t +qca808x_phy_get_eee_status(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *status) +{ + a_uint16_t phy_data = 0; + sw_error_t rv = SW_OK; + + *status = 0; + phy_data = qca808x_phy_mmd_read(dev_id, phy_id, QCA808X_PHY_MMD7_NUM, + QCA808X_PHY_MMD7_ADDR_8023AZ_EEE_STATUS); + + if (phy_data & QCA808X_PHY_EEE_STATUS_100M) { + *status |= FAL_PHY_EEE_100BASE_T; + } + if (phy_data & QCA808X_PHY_EEE_STATUS_1000M) { + *status |= FAL_PHY_EEE_1000BASE_T; + } + + return rv; +} + +/****************************************************************************** +* +* qca808x_phy_led_init - set led behavior +* +* set led behavior +*/ +static sw_error_t +qca808x_phy_led_init(a_uint32_t dev_id, a_uint32_t phy_id) +{ + sw_error_t rv = SW_OK; + + rv = qca808x_phy_mmd_write(dev_id, phy_id, QCA808X_PHY_MMD7_NUM, + QCA808X_PHY_MMD7_LED_POLARITY_CTRL, + QCA808X_PHY_MMD7_LED_POLARITY_ACTIVE_HIGH); + SW_RTN_ON_ERROR(rv); + rv = qca808x_phy_mmd_write(dev_id, phy_id, QCA808X_PHY_MMD7_NUM, + QCA808X_PHY_MMD7_LED0_CTRL, + QCA808X_PHY_MMD7_LED0_CTRL_ENABLE); + SW_RTN_ON_ERROR(rv); + rv = qca808x_phy_mmd_write(dev_id, phy_id, QCA808X_PHY_MMD7_NUM, + QCA808X_PHY_MMD7_LED1_CTRL, + QCA808X_PHY_MMD7_LED1_CTRL_DISABLE); + SW_RTN_ON_ERROR(rv); + rv = qca808x_phy_mmd_write(dev_id, phy_id, QCA808X_PHY_MMD7_NUM, + QCA808X_PHY_MMD7_LED2_CTRL, + QCA808X_PHY_MMD7_LED2_CTRL_DISABLE); + SW_RTN_ON_ERROR(rv); + + return rv; +} + +static sw_error_t +qca808x_phy_fast_retrain_cfg(a_uint32_t dev_id, a_uint32_t phy_id) +{ + sw_error_t rv = SW_OK; + + rv = qca808x_phy_mmd_write(dev_id, phy_id, QCA808X_PHY_MMD7_NUM, + QCA808X_PHY_MMD7_AUTONEGOTIATION_CONTROL, + QCA808X_ADVERTISE_2500FULL | + QCA808X_PHY_FAST_RETRAIN_2500BT | + QCA808X_PHY_ADV_LOOP_TIMING); + SW_RTN_ON_ERROR(rv); + rv = qca808x_phy_mmd_write(dev_id, phy_id, QCA808X_PHY_MMD1_NUM, + QCA808X_PHY_MMD1_FAST_RETRAIN_STATUS_CTL, + QCA808X_PHY_FAST_RETRAIN_CTRL); + SW_RTN_ON_ERROR(rv); + rv = qca808x_phy_mmd_write(dev_id, phy_id, QCA808X_PHY_MMD1_NUM, + QCA808X_PHY_MMD1_MSE_THRESHOLD_20DB, + QCA808X_PHY_MSE_THRESHOLD_20DB_VALUE); + SW_RTN_ON_ERROR(rv); + rv = qca808x_phy_mmd_write(dev_id, phy_id, QCA808X_PHY_MMD1_NUM, + QCA808X_PHY_MMD1_MSE_THRESHOLD_17DB, + QCA808X_PHY_MSE_THRESHOLD_17DB_VALUE); + SW_RTN_ON_ERROR(rv); + rv = qca808x_phy_mmd_write(dev_id, phy_id, QCA808X_PHY_MMD1_NUM, + QCA808X_PHY_MMD1_MSE_THRESHOLD_27DB, + QCA808X_PHY_MSE_THRESHOLD_27DB_VALUE); + SW_RTN_ON_ERROR(rv); + rv = qca808x_phy_mmd_write(dev_id, phy_id, QCA808X_PHY_MMD1_NUM, + QCA808X_PHY_MMD1_MSE_THRESHOLD_28DB, + QCA808X_PHY_MSE_THRESHOLD_28DB_VALUE); + SW_RTN_ON_ERROR(rv); + rv = qca808x_phy_mmd_write(dev_id, phy_id, QCA808X_PHY_MMD7_NUM, + QCA808X_PHY_MMD7_ADDR_EEE_LP_ADVERTISEMENT, + QCA808X_PHY_EEE_ADV_THP); + SW_RTN_ON_ERROR(rv); + rv = qca808x_phy_mmd_write(dev_id, phy_id, QCA808X_PHY_MMD7_NUM, + QCA808X_PHY_MMD7_TOP_OPTION1, + QCA808X_PHY_TOP_OPTION1_DATA); + SW_RTN_ON_ERROR(rv); + /*adjust the threshold for link down*/ + rv = qca808x_phy_mmd_write(dev_id, phy_id, QCA808X_PHY_MMD3_NUM, + 0xa100, 0x9203); + SW_RTN_ON_ERROR(rv); + rv = qca808x_phy_mmd_write(dev_id, phy_id, QCA808X_PHY_MMD3_NUM, + 0xa105, 0x8001); + SW_RTN_ON_ERROR(rv); + rv = qca808x_phy_mmd_write(dev_id, phy_id, QCA808X_PHY_MMD3_NUM, + 0xa106, 0x1111); + SW_RTN_ON_ERROR(rv); + rv = qca808x_phy_mmd_write(dev_id, phy_id, QCA808X_PHY_MMD3_NUM, + 0xa103, 0x1698); + SW_RTN_ON_ERROR(rv); + rv = qca808x_phy_mmd_write(dev_id, phy_id, QCA808X_PHY_MMD3_NUM, + 0xa011, 0x5f85); + SW_RTN_ON_ERROR(rv); + rv = qca808x_phy_mmd_write(dev_id, phy_id, QCA808X_PHY_MMD3_NUM, + 0xa101, 0x48ad); + + return rv; +} + +void qca808x_phy_lock_init(void) +{ + static a_bool_t is_init = A_FALSE; + + if(!is_init) + { + QCA808X_LOCKER_INIT; + is_init = A_TRUE; + } + + return; +} + +static sw_error_t +qca808x_phy_adc_threshold_set(a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t adc_thresold) +{ + sw_error_t rv = SW_OK; + a_uint16_t phy_data = 0; + + phy_data = qca808x_phy_debug_read(dev_id, phy_id, + QCA808X_PHY_ADC_THRESHOLD); + PHY_RTN_ON_READ_ERROR(phy_data); + phy_data &= ~(BITS(0, 8)); + rv = qca808x_phy_debug_write (dev_id, phy_id, + QCA808X_PHY_ADC_THRESHOLD, phy_data | adc_thresold); + + return rv; +} + +static sw_error_t +qca808x_phy_hw_init(a_uint32_t dev_id, a_uint32_t port_bmp) +{ + a_uint16_t phy_data = 0; + a_uint32_t port_id = 0, phy_addr = 0; + sw_error_t rv = SW_OK; + + for (port_id = SSDK_PHYSICAL_PORT0; port_id < SW_MAX_NR_PORT; port_id ++) + { + if (port_bmp & (0x1 << port_id)) + { + phy_addr = qca_ssdk_port_to_phy_addr(dev_id, port_id); + /*enable vga when init napa to fix 8023az issue*/ + phy_data = qca808x_phy_mmd_read(dev_id, phy_addr, QCA808X_PHY_MMD3_NUM, + QCA808X_PHY_MMD3_ADDR_CLD_CTRL7); + phy_data &= (~QCA808X_PHY_8023AZ_AFE_CTRL_MASK); + phy_data |= QCA808X_PHY_8023AZ_AFE_EN; + rv = qca808x_phy_mmd_write(dev_id, phy_addr, QCA808X_PHY_MMD3_NUM, + QCA808X_PHY_MMD3_ADDR_CLD_CTRL7, phy_data); + SW_RTN_ON_ERROR(rv); + /*set napa led pin behavior on HK board*/ + rv = qca808x_phy_led_init(dev_id, phy_addr); + SW_RTN_ON_ERROR(rv); + /*special configuration for AZ under 1G speed mode*/ + phy_data = QCA808X_PHY_MMD3_AZ_TRAINING_VAL; + rv = qca808x_phy_mmd_write(dev_id, phy_addr, QCA808X_PHY_MMD3_NUM, + QCA808X_PHY_MMD3_AZ_TRAINING_CTRL, phy_data); + SW_RTN_ON_ERROR(rv); + /*config the fast retrain*/ + rv = qca808x_phy_fast_retrain_cfg(dev_id, phy_addr); + SW_RTN_ON_ERROR(rv); + /*enable seed and configure ramdom seed in order that napa can be + as slave easier*/ + rv = qca808x_phy_ms_seed_enable(dev_id, phy_addr, A_TRUE); + SW_RTN_ON_ERROR(rv); + rv = qca808x_phy_ms_random_seed_set(dev_id, phy_addr); + SW_RTN_ON_ERROR(rv); + /*set adc threshold as 100mv for 10M*/ + rv = qca808x_phy_adc_threshold_set(dev_id, phy_addr, + QCA808X_PHY_ADC_THRESHOLD_100MV); + SW_RTN_ON_ERROR(rv); + } + } + + return rv; +} + +static sw_error_t qca808x_phy_api_ops_init(void) +{ + sw_error_t ret = SW_OK; + hsl_phy_ops_t *qca808x_phy_api_ops = NULL; + + qca808x_phy_api_ops = kzalloc(sizeof(hsl_phy_ops_t), GFP_KERNEL); + if (qca808x_phy_api_ops == NULL) { + SSDK_ERROR("qca808x phy ops kzalloc failed!\n"); + return -ENOMEM; + } + + phy_api_ops_init(QCA808X_PHY_CHIP); + + qca808x_phy_api_ops->phy_reg_write = qca808x_phy_reg_write; + qca808x_phy_api_ops->phy_reg_read = qca808x_phy_reg_read; + qca808x_phy_api_ops->phy_debug_write = qca808x_phy_debug_write; + qca808x_phy_api_ops->phy_debug_read = qca808x_phy_debug_read; + qca808x_phy_api_ops->phy_mmd_write = qca808x_phy_mmd_write; + qca808x_phy_api_ops->phy_mmd_read = qca808x_phy_mmd_read; + qca808x_phy_api_ops->phy_get_status = qca808x_phy_get_status; + qca808x_phy_api_ops->phy_speed_get = qca808x_phy_get_speed; + qca808x_phy_api_ops->phy_speed_set = qca808x_phy_set_speed; + qca808x_phy_api_ops->phy_duplex_get = qca808x_phy_get_duplex; + qca808x_phy_api_ops->phy_duplex_set = qca808x_phy_set_duplex; + qca808x_phy_api_ops->phy_autoneg_enable_set = qca808x_phy_enable_autoneg; + qca808x_phy_api_ops->phy_restart_autoneg = qca808x_phy_restart_autoneg; + qca808x_phy_api_ops->phy_autoneg_status_get = qca808x_phy_autoneg_status; + qca808x_phy_api_ops->phy_autoneg_adv_set = qca808x_phy_set_autoneg_adv; + qca808x_phy_api_ops->phy_autoneg_adv_get = qca808x_phy_get_autoneg_adv; + qca808x_phy_api_ops->phy_link_status_get = qca808x_phy_get_link_status; + qca808x_phy_api_ops->phy_reset = qca808x_phy_reset; +#ifndef IN_PORTCONTROL_MINI + qca808x_phy_api_ops->phy_cdt = qca808x_phy_cdt; + qca808x_phy_api_ops->phy_mdix_set = qca808x_phy_set_mdix; + qca808x_phy_api_ops->phy_mdix_get = qca808x_phy_get_mdix; + qca808x_phy_api_ops->phy_mdix_status_get = qca808x_phy_get_mdix_status; + qca808x_phy_api_ops->phy_local_loopback_set = qca808x_phy_set_local_loopback; + qca808x_phy_api_ops->phy_local_loopback_get = qca808x_phy_get_local_loopback; + qca808x_phy_api_ops->phy_remote_loopback_set = qca808x_phy_set_remote_loopback; + qca808x_phy_api_ops->phy_remote_loopback_get = qca808x_phy_get_remote_loopback; +#endif + qca808x_phy_api_ops->phy_id_get = qca808x_phy_get_phy_id; + qca808x_phy_api_ops->phy_power_off = qca808x_phy_poweroff; + qca808x_phy_api_ops->phy_power_on = qca808x_phy_poweron; +#ifndef IN_PORTCONTROL_MINI + qca808x_phy_api_ops->phy_8023az_set = qca808x_phy_set_8023az; + qca808x_phy_api_ops->phy_8023az_get = qca808x_phy_get_8023az; + qca808x_phy_api_ops->phy_hibernation_set = qca808x_phy_set_hibernate; + qca808x_phy_api_ops->phy_hibernation_get = qca808x_phy_get_hibernate; + qca808x_phy_api_ops->phy_magic_frame_mac_set = qca808x_phy_set_magic_frame_mac; + qca808x_phy_api_ops->phy_magic_frame_mac_get = qca808x_phy_get_magic_frame_mac; + qca808x_phy_api_ops->phy_wol_status_set = qca808x_phy_set_wol_status; + qca808x_phy_api_ops->phy_wol_status_get = qca808x_phy_get_wol_status; +#endif + qca808x_phy_api_ops->phy_interface_mode_set = qca808x_phy_interface_set_mode; + qca808x_phy_api_ops->phy_interface_mode_get = qca808x_phy_interface_get_mode; + qca808x_phy_api_ops->phy_interface_mode_status_get = qca808x_phy_interface_get_mode_status; +#ifndef IN_PORTCONTROL_MINI + qca808x_phy_api_ops->phy_intr_mask_set = qca808x_phy_set_intr_mask; + qca808x_phy_api_ops->phy_intr_mask_get = qca808x_phy_get_intr_mask; + qca808x_phy_api_ops->phy_intr_status_get = qca808x_phy_get_intr_status; + qca808x_phy_api_ops->phy_counter_set = qca808x_phy_set_counter; + qca808x_phy_api_ops->phy_counter_get = qca808x_phy_get_counter; + qca808x_phy_api_ops->phy_counter_show = qca808x_phy_show_counter; +#endif + qca808x_phy_api_ops->phy_eee_adv_set = qca808x_phy_set_eee_adv; + qca808x_phy_api_ops->phy_eee_adv_get = qca808x_phy_get_eee_adv; + qca808x_phy_api_ops->phy_eee_partner_adv_get = qca808x_phy_get_eee_partner_adv; + qca808x_phy_api_ops->phy_eee_cap_get = qca808x_phy_get_eee_cap; + qca808x_phy_api_ops->phy_eee_status_get = qca808x_phy_get_eee_status; +#ifdef IN_LED + qca808x_phy_led_api_ops_init(qca808x_phy_api_ops); +#endif +/*qca808x_end*/ +#if defined(IN_PTP) + qca808x_phy_ptp_api_ops_init(&qca808x_phy_api_ops->phy_ptp_ops); +#endif +/*qca808x_start*/ + ret = hsl_phy_api_ops_register(QCA808X_PHY_CHIP, qca808x_phy_api_ops); + + if (ret == SW_OK) { + SSDK_INFO("qca probe qca808x phy driver succeeded!\n"); + } else { + SSDK_ERROR("qca probe qca808x phy driver failed! (code: %d)\n", ret); + } + + return ret; +} + +/****************************************************************************** +* +* qca808x_phy_init - +* +*/ +int qca808x_phy_init(a_uint32_t dev_id, a_uint32_t port_bmp) +{ +/*qca808x_end*/ + a_uint32_t port_id = 0; +/*qca808x_start*/ + a_int32_t ret = 0; + + if(phy_ops_flag == A_FALSE && + qca808x_phy_api_ops_init() == SW_OK) { + qca808x_phy_lock_init(); + phy_ops_flag = A_TRUE; + } + qca808x_phy_hw_init(dev_id, port_bmp); + +/*qca808x_end*/ + if(phy_dev_drv_init_flag == A_FALSE) + { + for (port_id = 0; port_id < SW_MAX_NR_PORT; port_id ++) + { + if (port_bmp & (0x1 << port_id)) { + qca808x_phydev_init(dev_id, port_id); + } + } + ret = qca808x_phy_driver_register(); + phy_dev_drv_init_flag = A_TRUE; + } +/*qca808x_start*/ + return ret; +} + +void qca808x_phy_exit(a_uint32_t dev_id, a_uint32_t port_bmp) +{ +/*qca808x_end*/ + a_uint32_t port_id = 0; + + qca808x_phy_driver_unregister(); + for (port_id = 0; port_id < SW_MAX_NR_PORT; port_id ++) + { + if (port_bmp & (0x1 << port_id)) { + qca808x_phydev_deinit(dev_id, port_id); + } + } +/*qca808x_start*/ +} +/*qca808x_end*/ diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/qca808x_ptp.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/qca808x_ptp.c new file mode 100755 index 000000000..c1e3e6589 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/qca808x_ptp.c @@ -0,0 +1,2843 @@ +/* + * 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 "hsl_api.h" +#include "hsl.h" +#include "hsl_phy.h" +#include "ssdk_plat.h" +#include "qca808x_phy.h" +#include "qca808x_ptp_reg.h" +#include "qca808x_ptp_api.h" +#include "qca808x_ptp.h" + +sw_error_t +qca808x_phy_ptp_config_set(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_config_t *config) +{ + union ptp_main_conf_reg_u ptp_main_conf_reg = {0}; + union ptp_misc_config_reg_u ptp_misc_config_reg = {0}; + union ptp_backup_reg_u ptp_backup_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_main_conf_reg_get(dev_id, phy_id, &ptp_main_conf_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_misc_config_reg_get(dev_id, phy_id, &ptp_misc_config_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_backup_reg_get(dev_id, phy_id, &ptp_backup_reg)); + if (config->ptp_en == A_TRUE) + { + ptp_main_conf_reg.bf.ptp_bypass = PTP_REG_BIT_FALSE; + ptp_main_conf_reg.bf.disable_1588_phy = PTP_REG_BIT_FALSE; + } + else + { + ptp_main_conf_reg.bf.ptp_bypass = PTP_REG_BIT_TRUE; + ptp_main_conf_reg.bf.disable_1588_phy = PTP_REG_BIT_TRUE; + } + if (config->clock_mode == FAL_OC_CLOCK_MODE || config->clock_mode == FAL_BC_CLOCK_MODE) + { + if (config->step_mode == FAL_ONE_STEP_MODE) + { + ptp_main_conf_reg.bf.ptp_clock_mode = + PTP_MAIN_CONF_REG_PTP_CLOCK_MODE_OC_ONE_STEP; + } + else + { + ptp_main_conf_reg.bf.ptp_clock_mode = + PTP_MAIN_CONF_REG_PTP_CLOCK_MODE_OC_TWO_STEP; + } + } + else + { + if (config->clock_mode == FAL_P2PTC_CLOCK_MODE) + { + ptp_backup_reg.bf.p2p_tc_en = PTP_REG_BIT_TRUE; + } + else + { + ptp_backup_reg.bf.p2p_tc_en = PTP_REG_BIT_FALSE; + } + + if (config->step_mode == FAL_ONE_STEP_MODE && + ptp_misc_config_reg.bf.embed_ingress_time_en == PTP_REG_BIT_TRUE) + { + ptp_misc_config_reg.bf.tc_offload = PTP_REG_BIT_TRUE; + } + else + { + ptp_misc_config_reg.bf.tc_offload = PTP_REG_BIT_FALSE; + } + + if (config->step_mode == FAL_ONE_STEP_MODE) + { + ptp_main_conf_reg.bf.ptp_clock_mode = + PTP_MAIN_CONF_REG_PTP_CLOCK_MODE_TC_ONE_STEP; + } + else + { + ptp_main_conf_reg.bf.ptp_clock_mode = + PTP_MAIN_CONF_REG_PTP_CLOCK_MODE_TC_TWO_STEP; + } + } + if (config->step_mode == FAL_AUTO_MODE) + { + ptp_misc_config_reg.bf.pkt_one_step_en = PTP_REG_BIT_TRUE; + } + else + { + ptp_misc_config_reg.bf.pkt_one_step_en = PTP_REG_BIT_FALSE; + } +#if defined(IN_LINUX_STD_PTP) + qca808x_ptp_clock_mode_config(dev_id, phy_id, config->clock_mode, config->step_mode); +#endif + SW_RTN_ON_ERROR(qca808x_ptp_main_conf_reg_set(dev_id, phy_id, &ptp_main_conf_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_misc_config_reg_set(dev_id, phy_id, &ptp_misc_config_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_backup_reg_set(dev_id, phy_id, &ptp_backup_reg)); + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_config_get(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_config_t *config) +{ + union ptp_main_conf_reg_u ptp_main_conf_reg = {0}; + union ptp_misc_config_reg_u ptp_misc_config_reg = {0}; + union ptp_backup_reg_u ptp_backup_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_main_conf_reg_get(dev_id, phy_id, &ptp_main_conf_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_misc_config_reg_get(dev_id, phy_id, &ptp_misc_config_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_backup_reg_get(dev_id, phy_id, &ptp_backup_reg)); + if (ptp_main_conf_reg.bf.ptp_bypass == PTP_REG_BIT_FALSE && + ptp_main_conf_reg.bf.disable_1588_phy == PTP_REG_BIT_FALSE) + { + config->ptp_en = A_TRUE; + } + if (ptp_main_conf_reg.bf.ptp_clock_mode == + PTP_MAIN_CONF_REG_PTP_CLOCK_MODE_OC_TWO_STEP) + { + config->clock_mode = FAL_OC_CLOCK_MODE; + config->step_mode = FAL_TWO_STEP_MODE; + } + else if (ptp_main_conf_reg.bf.ptp_clock_mode == + PTP_MAIN_CONF_REG_PTP_CLOCK_MODE_OC_ONE_STEP) + { + config->clock_mode = FAL_OC_CLOCK_MODE; + config->step_mode = FAL_ONE_STEP_MODE; + } + else if (ptp_main_conf_reg.bf.ptp_clock_mode == + PTP_MAIN_CONF_REG_PTP_CLOCK_MODE_TC_TWO_STEP) + { + if (ptp_backup_reg.bf.p2p_tc_en == PTP_REG_BIT_TRUE) + { + config->clock_mode = FAL_P2PTC_CLOCK_MODE; + } + else + { + config->clock_mode = FAL_E2ETC_CLOCK_MODE; + } + + config->step_mode = FAL_TWO_STEP_MODE; + } + else + { + if (ptp_backup_reg.bf.p2p_tc_en == PTP_REG_BIT_TRUE) + { + config->clock_mode = FAL_P2PTC_CLOCK_MODE; + } + else + { + config->clock_mode = FAL_E2ETC_CLOCK_MODE; + } + + config->step_mode = FAL_ONE_STEP_MODE; + } + if (ptp_misc_config_reg.bf.pkt_one_step_en == PTP_REG_BIT_TRUE) + { + config->step_mode = FAL_AUTO_MODE; + } + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_reference_clock_set(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_reference_clock_t ref_clock) +{ + union ptp_main_conf_reg_u ptp_main_conf_reg = {0}; + union ptp_rtc_clk_reg_u ptp_rtc_clk_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_main_conf_reg_get(dev_id, phy_id, &ptp_main_conf_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rtc_clk_reg_get(dev_id, phy_id, &ptp_rtc_clk_reg)); + if (ref_clock == FAL_REF_CLOCK_LOCAL) + { + ptp_main_conf_reg.bf.ptp_clk_sel = PTP_REG_BIT_FALSE; + ptp_rtc_clk_reg.bf.rtc_clk_selection = PTP_REG_BIT_FALSE; + } + else if (ref_clock == FAL_REF_CLOCK_SYNCE) + { + ptp_main_conf_reg.bf.ptp_clk_sel = PTP_REG_BIT_TRUE; + ptp_rtc_clk_reg.bf.rtc_clk_selection = PTP_REG_BIT_FALSE; + } + else + { + ptp_main_conf_reg.bf.ptp_clk_sel = PTP_REG_BIT_FALSE; + ptp_rtc_clk_reg.bf.rtc_clk_selection = PTP_REG_BIT_TRUE; + } + SW_RTN_ON_ERROR(qca808x_ptp_main_conf_reg_set(dev_id, phy_id, &ptp_main_conf_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rtc_clk_reg_set(dev_id, phy_id, &ptp_rtc_clk_reg)); + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_reference_clock_get(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_reference_clock_t *ref_clock) +{ + union ptp_main_conf_reg_u ptp_main_conf_reg = {0}; + union ptp_rtc_clk_reg_u ptp_rtc_clk_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_main_conf_reg_get(dev_id, phy_id, &ptp_main_conf_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rtc_clk_reg_get(dev_id, phy_id, &ptp_rtc_clk_reg)); + if (ptp_main_conf_reg.bf.ptp_clk_sel == PTP_REG_BIT_FALSE && + ptp_rtc_clk_reg.bf.rtc_clk_selection == PTP_REG_BIT_FALSE) + { + *ref_clock = FAL_REF_CLOCK_LOCAL; + } + else if (ptp_main_conf_reg.bf.ptp_clk_sel == PTP_REG_BIT_TRUE && + ptp_rtc_clk_reg.bf.rtc_clk_selection == PTP_REG_BIT_FALSE) + { + *ref_clock = FAL_REF_CLOCK_SYNCE; + } + else + { + *ref_clock = FAL_REF_CLOCK_EXTERNAL; + } + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_rx_timestamp_mode_set(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_rx_timestamp_mode_t ts_mode) +{ + union ptp_main_conf_reg_u ptp_main_conf_reg = {0}; + union ptp_misc_config_reg_u ptp_misc_config_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_main_conf_reg_get(dev_id, phy_id, &ptp_main_conf_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_misc_config_reg_get(dev_id, phy_id, &ptp_misc_config_reg)); + if (ts_mode == FAL_RX_TS_MDIO) + { + ptp_main_conf_reg.bf.ts_attach_mode = PTP_REG_BIT_FALSE; + ptp_main_conf_reg.bf.ipv6_embed_force_checksum_zero = PTP_REG_BIT_FALSE; + ptp_misc_config_reg.bf.embed_ingress_time_en = PTP_REG_BIT_FALSE; + ptp_misc_config_reg.bf.cf_from_pkt_en = PTP_REG_BIT_TRUE; + } + else + { + ptp_main_conf_reg.bf.ts_attach_mode = PTP_REG_BIT_FALSE; + ptp_main_conf_reg.bf.ipv6_embed_force_checksum_zero = PTP_REG_BIT_TRUE; + ptp_misc_config_reg.bf.embed_ingress_time_en = PTP_REG_BIT_TRUE; + ptp_misc_config_reg.bf.cf_from_pkt_en = PTP_REG_BIT_FALSE; + } + SW_RTN_ON_ERROR(qca808x_ptp_main_conf_reg_set(dev_id, phy_id, &ptp_main_conf_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_misc_config_reg_set(dev_id, phy_id, &ptp_misc_config_reg)); + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_rx_timestamp_mode_get(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_rx_timestamp_mode_t *ts_mode) +{ + union ptp_main_conf_reg_u ptp_main_conf_reg = {0}; + union ptp_misc_config_reg_u ptp_misc_config_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_main_conf_reg_get(dev_id, phy_id, &ptp_main_conf_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_misc_config_reg_get(dev_id, phy_id, &ptp_misc_config_reg)); + if (ptp_main_conf_reg.bf.ts_attach_mode == PTP_REG_BIT_FALSE && + ptp_misc_config_reg.bf.embed_ingress_time_en == PTP_REG_BIT_FALSE) + { + *ts_mode = FAL_RX_TS_MDIO; + } + else if (ptp_main_conf_reg.bf.ts_attach_mode == PTP_REG_BIT_FALSE && + ptp_misc_config_reg.bf.embed_ingress_time_en == PTP_REG_BIT_TRUE) + { + *ts_mode = FAL_RX_TS_EMBED; + } + else + { + return SW_BAD_VALUE; + } + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_rx_timestamp0_get(a_uint32_t dev_id, a_uint32_t phy_id, + fal_ptp_pkt_info_t *pkt_info, fal_ptp_time_t *time) +{ + union ptp_rx_seqid0_reg_u ptp_rx_seqid0_reg = {0}; + + union ptp_rx_portid0_0_reg_u ptp_rx_portid0_0_reg = {0}; + union ptp_rx_portid0_1_reg_u ptp_rx_portid0_1_reg = {0}; + union ptp_rx_portid0_2_reg_u ptp_rx_portid0_2_reg = {0}; + union ptp_rx_portid0_3_reg_u ptp_rx_portid0_3_reg = {0}; + union ptp_rx_portid0_4_reg_u ptp_rx_portid0_4_reg = {0}; + union ptp_rx_ts0_0_reg_u ptp_rx_ts0_0_reg = {0}; + union ptp_rx_ts0_1_reg_u ptp_rx_ts0_1_reg = {0}; + union ptp_rx_ts0_2_reg_u ptp_rx_ts0_2_reg = {0}; + union ptp_rx_ts0_3_reg_u ptp_rx_ts0_3_reg = {0}; + union ptp_rx_ts0_4_reg_u ptp_rx_ts0_4_reg = {0}; + union ptp_rx_ts0_5_reg_u ptp_rx_ts0_5_reg = {0}; + union ptp_rx_ts0_6_reg_u ptp_rx_ts0_6_reg = {0}; + + a_uint64_t clock_id; + a_uint32_t port_num, msgtype; + + SW_RTN_ON_ERROR(qca808x_ptp_rx_seqid0_reg_get(dev_id, phy_id, &ptp_rx_seqid0_reg)); + if (pkt_info->sequence_id != ptp_rx_seqid0_reg.bf.rx_seqid) + { + return SW_NOT_FOUND; + } + + SW_RTN_ON_ERROR(qca808x_ptp_rx_portid0_0_reg_get(dev_id, + phy_id, &ptp_rx_portid0_0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_portid0_1_reg_get(dev_id, + phy_id, &ptp_rx_portid0_1_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_portid0_2_reg_get(dev_id, + phy_id, &ptp_rx_portid0_2_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_portid0_3_reg_get(dev_id, + phy_id, &ptp_rx_portid0_3_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_rx_portid0_4_reg_get(dev_id, + phy_id, &ptp_rx_portid0_4_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_rx_ts0_0_reg_get(dev_id, + phy_id, &ptp_rx_ts0_0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_ts0_1_reg_get(dev_id, + phy_id, &ptp_rx_ts0_1_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_ts0_2_reg_get(dev_id, + phy_id, &ptp_rx_ts0_2_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_ts0_3_reg_get(dev_id, + phy_id, &ptp_rx_ts0_3_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_ts0_4_reg_get(dev_id, + phy_id, &ptp_rx_ts0_4_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_ts0_5_reg_get(dev_id, + phy_id, &ptp_rx_ts0_5_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_ts0_6_reg_get(dev_id, + phy_id, &ptp_rx_ts0_6_reg)); + + clock_id = ((a_uint64_t)ptp_rx_portid0_0_reg.bf.rx_portid << 48) | + ((a_uint64_t)ptp_rx_portid0_1_reg.bf.rx_portid << 32) | + ((a_uint64_t)ptp_rx_portid0_2_reg.bf.rx_portid << 16) | + ptp_rx_portid0_3_reg.bf.rx_portid; + port_num = ptp_rx_portid0_4_reg.bf.rx_portid; + msgtype = ptp_rx_ts0_5_reg.bf.rx_msg_type; + + if (pkt_info->clock_identify == clock_id && + pkt_info->port_number == port_num && + pkt_info->msg_type == msgtype) + { + time->seconds = + ((a_int64_t)ptp_rx_ts0_0_reg.bf.rx_ts_sec << 32) | + ((a_int64_t)ptp_rx_ts0_1_reg.bf.rx_ts_sec << 16) | + ptp_rx_ts0_2_reg.bf.rx_ts_sec; + time->nanoseconds = + ((a_int32_t)ptp_rx_ts0_3_reg.bf.rx_ts_nsec << 16) | + ptp_rx_ts0_4_reg.bf.rx_ts_nsec; + time->fracnanoseconds = + ((a_int32_t)ptp_rx_ts0_5_reg.bf.rx_ts_nfsec << 8) | + ptp_rx_ts0_6_reg.bf.rx_ts_nfsec; + + return SW_OK; + } + return SW_NOT_FOUND; +} + +sw_error_t +qca808x_phy_ptp_rx_timestamp1_get(a_uint32_t dev_id, a_uint32_t phy_id, + fal_ptp_pkt_info_t *pkt_info, fal_ptp_time_t *time) +{ + union ptp_rx_seqid1_reg_u ptp_rx_seqid1_reg = {0}; + + union ptp_rx_portid1_0_reg_u ptp_rx_portid1_0_reg = {0}; + union ptp_rx_portid1_1_reg_u ptp_rx_portid1_1_reg = {0}; + union ptp_rx_portid1_2_reg_u ptp_rx_portid1_2_reg = {0}; + union ptp_rx_portid1_3_reg_u ptp_rx_portid1_3_reg = {0}; + union ptp_rx_portid1_4_reg_u ptp_rx_portid1_4_reg = {0}; + union ptp_rx_ts1_0_reg_u ptp_rx_ts1_0_reg = {0}; + union ptp_rx_ts1_1_reg_u ptp_rx_ts1_1_reg = {0}; + union ptp_rx_ts1_2_reg_u ptp_rx_ts1_2_reg = {0}; + union ptp_rx_ts1_3_reg_u ptp_rx_ts1_3_reg = {0}; + union ptp_rx_ts1_4_reg_u ptp_rx_ts1_4_reg = {0}; + union ptp_rx_ts1_5_reg_u ptp_rx_ts1_5_reg = {0}; + union ptp_rx_ts1_6_reg_u ptp_rx_ts1_6_reg = {0}; + + a_uint64_t clock_id; + a_uint32_t port_num, msgtype; + + SW_RTN_ON_ERROR(qca808x_ptp_rx_seqid1_reg_get(dev_id, phy_id, &ptp_rx_seqid1_reg)); + if (pkt_info->sequence_id != ptp_rx_seqid1_reg.bf.rx_seqid) + { + return SW_NOT_FOUND; + } + + SW_RTN_ON_ERROR(qca808x_ptp_rx_portid1_0_reg_get(dev_id, + phy_id, &ptp_rx_portid1_0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_portid1_1_reg_get(dev_id, + phy_id, &ptp_rx_portid1_1_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_portid1_2_reg_get(dev_id, + phy_id, &ptp_rx_portid1_2_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_portid1_3_reg_get(dev_id, + phy_id, &ptp_rx_portid1_3_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_portid1_4_reg_get(dev_id, + phy_id, &ptp_rx_portid1_4_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_ts1_0_reg_get(dev_id, + phy_id, &ptp_rx_ts1_0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_ts1_1_reg_get(dev_id, + phy_id, &ptp_rx_ts1_1_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_ts1_2_reg_get(dev_id, + phy_id, &ptp_rx_ts1_2_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_ts1_3_reg_get(dev_id, + phy_id, &ptp_rx_ts1_3_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_ts1_4_reg_get(dev_id, + phy_id, &ptp_rx_ts1_4_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_ts1_5_reg_get(dev_id, + phy_id, &ptp_rx_ts1_5_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_ts1_6_reg_get(dev_id, + phy_id, &ptp_rx_ts1_6_reg)); + + clock_id = ((a_uint64_t)ptp_rx_portid1_0_reg.bf.rx_portid << 48) | + ((a_uint64_t)ptp_rx_portid1_1_reg.bf.rx_portid << 32) | + ((a_uint64_t)ptp_rx_portid1_2_reg.bf.rx_portid << 16) | + ptp_rx_portid1_3_reg.bf.rx_portid; + + port_num = ptp_rx_portid1_4_reg.bf.rx_portid; + msgtype = ptp_rx_ts1_5_reg.bf.rx_msg_type; + if (pkt_info->clock_identify == clock_id && + pkt_info->port_number == port_num && + pkt_info->msg_type == msgtype) + { + time->seconds = + ((a_int64_t)ptp_rx_ts1_0_reg.bf.rx_ts_sec << 32) | + ((a_int64_t)ptp_rx_ts1_1_reg.bf.rx_ts_sec << 16) | + ptp_rx_ts1_2_reg.bf.rx_ts_sec; + time->nanoseconds = + ((a_int32_t)ptp_rx_ts1_3_reg.bf.rx_ts_nsec << 16) | + ptp_rx_ts1_4_reg.bf.rx_ts_nsec; + time->fracnanoseconds = + ((a_int32_t)ptp_rx_ts1_5_reg.bf.rx_ts_nfsec << 8) | + ptp_rx_ts1_6_reg.bf.rx_ts_nfsec; + + return SW_OK; + } + return SW_NOT_FOUND; +} + +sw_error_t +qca808x_phy_ptp_rx_timestamp2_get(a_uint32_t dev_id, a_uint32_t phy_id, + fal_ptp_pkt_info_t *pkt_info, fal_ptp_time_t *time) +{ + union ptp_rx_seqid2_reg_u ptp_rx_seqid2_reg = {0}; + union ptp_rx_portid2_0_reg_u ptp_rx_portid2_0_reg = {0}; + union ptp_rx_portid2_1_reg_u ptp_rx_portid2_1_reg = {0}; + union ptp_rx_portid2_2_reg_u ptp_rx_portid2_2_reg = {0}; + union ptp_rx_portid2_3_reg_u ptp_rx_portid2_3_reg = {0}; + union ptp_rx_portid2_4_reg_u ptp_rx_portid2_4_reg = {0}; + union ptp_rx_ts2_0_reg_u ptp_rx_ts2_0_reg = {0}; + union ptp_rx_ts2_1_reg_u ptp_rx_ts2_1_reg = {0}; + union ptp_rx_ts2_2_reg_u ptp_rx_ts2_2_reg = {0}; + union ptp_rx_ts2_3_reg_u ptp_rx_ts2_3_reg = {0}; + union ptp_rx_ts2_4_reg_u ptp_rx_ts2_4_reg = {0}; + union ptp_rx_ts2_5_reg_u ptp_rx_ts2_5_reg = {0}; + union ptp_rx_ts2_6_reg_u ptp_rx_ts2_6_reg = {0}; + + a_uint64_t clock_id; + a_uint32_t port_num, msgtype; + + SW_RTN_ON_ERROR(qca808x_ptp_rx_seqid2_reg_get(dev_id, phy_id, &ptp_rx_seqid2_reg)); + if (pkt_info->sequence_id != ptp_rx_seqid2_reg.bf.rx_seqid) + { + return SW_NOT_FOUND; + } + + SW_RTN_ON_ERROR(qca808x_ptp_rx_portid2_0_reg_get(dev_id, + phy_id, &ptp_rx_portid2_0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_portid2_1_reg_get(dev_id, + phy_id, &ptp_rx_portid2_1_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_portid2_2_reg_get(dev_id, + phy_id, &ptp_rx_portid2_2_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_portid2_3_reg_get(dev_id, + phy_id, &ptp_rx_portid2_3_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_portid2_4_reg_get(dev_id, + phy_id, &ptp_rx_portid2_4_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_ts2_0_reg_get(dev_id, + phy_id, &ptp_rx_ts2_0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_ts2_1_reg_get(dev_id, + phy_id, &ptp_rx_ts2_1_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_ts2_2_reg_get(dev_id, + phy_id, &ptp_rx_ts2_2_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_ts2_3_reg_get(dev_id, + phy_id, &ptp_rx_ts2_3_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_ts2_4_reg_get(dev_id, + phy_id, &ptp_rx_ts2_4_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_ts2_5_reg_get(dev_id, + phy_id, &ptp_rx_ts2_5_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_ts2_6_reg_get(dev_id, + phy_id, &ptp_rx_ts2_6_reg)); + + clock_id = ((a_uint64_t)ptp_rx_portid2_0_reg.bf.rx_portid << 48) | + ((a_uint64_t)ptp_rx_portid2_1_reg.bf.rx_portid << 32) | + ((a_uint64_t)ptp_rx_portid2_2_reg.bf.rx_portid << 16) | + ptp_rx_portid2_3_reg.bf.rx_portid; + port_num = ptp_rx_portid2_4_reg.bf.rx_portid; + msgtype = ptp_rx_ts2_5_reg.bf.rx_msg_type; + + if (pkt_info->clock_identify == clock_id && + pkt_info->port_number == port_num && + pkt_info->msg_type == msgtype) + { + time->seconds = + ((a_int64_t)ptp_rx_ts2_0_reg.bf.rx_ts_sec << 32) | + ((a_int64_t)ptp_rx_ts2_1_reg.bf.rx_ts_sec << 16) | + ptp_rx_ts2_2_reg.bf.rx_ts_sec; + time->nanoseconds = + ((a_int32_t)ptp_rx_ts2_3_reg.bf.rx_ts_nsec << 16) | + ptp_rx_ts2_4_reg.bf.rx_ts_nsec; + time->fracnanoseconds = + ((a_int32_t)ptp_rx_ts2_5_reg.bf.rx_ts_nfsec << 8) | + ptp_rx_ts2_6_reg.bf.rx_ts_nfsec; + + return SW_OK; + } + return SW_NOT_FOUND; +} + +sw_error_t +qca808x_phy_ptp_rx_timestamp3_get(a_uint32_t dev_id, a_uint32_t phy_id, + fal_ptp_pkt_info_t *pkt_info, fal_ptp_time_t *time) +{ + union ptp_rx_seqid3_reg_u ptp_rx_seqid3_reg = {0}; + union ptp_rx_portid3_0_reg_u ptp_rx_portid3_0_reg = {0}; + union ptp_rx_portid3_1_reg_u ptp_rx_portid3_1_reg = {0}; + union ptp_rx_portid3_2_reg_u ptp_rx_portid3_2_reg = {0}; + union ptp_rx_portid3_3_reg_u ptp_rx_portid3_3_reg = {0}; + union ptp_rx_portid3_4_reg_u ptp_rx_portid3_4_reg = {0}; + union ptp_rx_ts3_0_reg_u ptp_rx_ts3_0_reg = {0}; + union ptp_rx_ts3_1_reg_u ptp_rx_ts3_1_reg = {0}; + union ptp_rx_ts3_2_reg_u ptp_rx_ts3_2_reg = {0}; + union ptp_rx_ts3_3_reg_u ptp_rx_ts3_3_reg = {0}; + union ptp_rx_ts3_4_reg_u ptp_rx_ts3_4_reg = {0}; + union ptp_rx_ts3_5_reg_u ptp_rx_ts3_5_reg = {0}; + union ptp_rx_ts3_6_reg_u ptp_rx_ts3_6_reg = {0}; + + a_uint64_t clock_id; + a_uint32_t port_num, msgtype; + + SW_RTN_ON_ERROR(qca808x_ptp_rx_seqid3_reg_get(dev_id, phy_id, &ptp_rx_seqid3_reg)); + if (pkt_info->sequence_id != ptp_rx_seqid3_reg.bf.rx_seqid) + { + return SW_NOT_FOUND; + } + SW_RTN_ON_ERROR(qca808x_ptp_rx_portid3_0_reg_get(dev_id, + phy_id, &ptp_rx_portid3_0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_portid3_1_reg_get(dev_id, + phy_id, &ptp_rx_portid3_1_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_portid3_2_reg_get(dev_id, + phy_id, &ptp_rx_portid3_2_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_portid3_3_reg_get(dev_id, + phy_id, &ptp_rx_portid3_3_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_portid3_4_reg_get(dev_id, + phy_id, &ptp_rx_portid3_4_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_ts3_0_reg_get(dev_id, + phy_id, &ptp_rx_ts3_0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_ts3_1_reg_get(dev_id, + phy_id, &ptp_rx_ts3_1_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_ts3_2_reg_get(dev_id, + phy_id, &ptp_rx_ts3_2_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_ts3_3_reg_get(dev_id, + phy_id, &ptp_rx_ts3_3_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_ts3_4_reg_get(dev_id, + phy_id, &ptp_rx_ts3_4_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_ts3_5_reg_get(dev_id, + phy_id, &ptp_rx_ts3_5_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_ts3_6_reg_get(dev_id, + phy_id, &ptp_rx_ts3_6_reg)); + + clock_id = ((a_uint64_t)ptp_rx_portid3_0_reg.bf.rx_portid << 48) | + ((a_uint64_t)ptp_rx_portid3_1_reg.bf.rx_portid << 32) | + ((a_uint64_t)ptp_rx_portid3_2_reg.bf.rx_portid << 16) | + ptp_rx_portid3_3_reg.bf.rx_portid; + port_num = ptp_rx_portid3_4_reg.bf.rx_portid; + msgtype = ptp_rx_ts3_5_reg.bf.rx_msg_type; + if (pkt_info->clock_identify == clock_id && + pkt_info->port_number == port_num && + pkt_info->msg_type == msgtype) + { + time->seconds = + ((a_int64_t)ptp_rx_ts3_0_reg.bf.rx_ts_sec << 32) | + ((a_int64_t)ptp_rx_ts3_1_reg.bf.rx_ts_sec << 16) | + ptp_rx_ts3_2_reg.bf.rx_ts_sec; + time->nanoseconds = + ((a_int32_t)ptp_rx_ts3_3_reg.bf.rx_ts_nsec << 16) | + ptp_rx_ts3_4_reg.bf.rx_ts_nsec; + time->fracnanoseconds = + ((a_int32_t)ptp_rx_ts3_5_reg.bf.rx_ts_nfsec << 8) | + ptp_rx_ts3_6_reg.bf.rx_ts_nfsec; + + return SW_OK; + } + return SW_NOT_FOUND; +} + +sw_error_t +qca808x_phy_ptp_tx_timestamp0_get(a_uint32_t dev_id, a_uint32_t phy_id, + fal_ptp_pkt_info_t *pkt_info, fal_ptp_time_t *time) +{ + union ptp_tx_seqid_reg_u ptp_tx_seqid_reg = {0}; + union ptp_tx_portid0_reg_u ptp_tx_portid0_reg = {0}; + union ptp_tx_portid1_reg_u ptp_tx_portid1_reg = {0}; + union ptp_tx_portid2_reg_u ptp_tx_portid2_reg = {0}; + union ptp_tx_portid3_reg_u ptp_tx_portid3_reg = {0}; + union ptp_tx_portid4_reg_u ptp_tx_portid4_reg = {0}; + union ptp_tx_ts0_reg_u ptp_tx_ts0_reg = {0}; + union ptp_tx_ts1_reg_u ptp_tx_ts1_reg = {0}; + union ptp_tx_ts2_reg_u ptp_tx_ts2_reg = {0}; + union ptp_tx_ts3_reg_u ptp_tx_ts3_reg = {0}; + union ptp_tx_ts4_reg_u ptp_tx_ts4_reg = {0}; + union ptp_tx_ts5_reg_u ptp_tx_ts5_reg = {0}; + union ptp_tx_ts6_reg_u ptp_tx_ts6_reg = {0}; + + a_uint64_t clock_id; + a_uint32_t port_num, msgtype; + + SW_RTN_ON_ERROR(qca808x_ptp_tx_seqid_reg_get(dev_id, phy_id, &ptp_tx_seqid_reg)); + if (pkt_info->sequence_id != ptp_tx_seqid_reg.bf.tx_seqid) + { + return SW_NOT_FOUND; + } + + SW_RTN_ON_ERROR(qca808x_ptp_tx_portid0_reg_get(dev_id, + phy_id, &ptp_tx_portid0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_tx_portid1_reg_get(dev_id, + phy_id, &ptp_tx_portid1_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_tx_portid2_reg_get(dev_id, + phy_id, &ptp_tx_portid2_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_tx_portid3_reg_get(dev_id, + phy_id, &ptp_tx_portid3_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_tx_portid4_reg_get(dev_id, + phy_id, &ptp_tx_portid4_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_tx_ts0_reg_get(dev_id, + phy_id, &ptp_tx_ts0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_tx_ts1_reg_get(dev_id, + phy_id, &ptp_tx_ts1_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_tx_ts2_reg_get(dev_id, + phy_id, &ptp_tx_ts2_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_tx_ts3_reg_get(dev_id, + phy_id, &ptp_tx_ts3_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_tx_ts4_reg_get(dev_id, + phy_id, &ptp_tx_ts4_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_tx_ts5_reg_get(dev_id, + phy_id, &ptp_tx_ts5_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_tx_ts6_reg_get(dev_id, + phy_id, &ptp_tx_ts6_reg)); + clock_id = ((a_uint64_t)ptp_tx_portid0_reg.bf.tx_portid << 48) | + ((a_uint64_t)ptp_tx_portid1_reg.bf.tx_portid << 32) | + ((a_uint64_t)ptp_tx_portid2_reg.bf.tx_portid << 16) | + ptp_tx_portid3_reg.bf.tx_portid; + port_num = ptp_tx_portid4_reg.bf.tx_portid; + msgtype = ptp_tx_ts5_reg.bf.tx_msg_type; + if (pkt_info->clock_identify == clock_id && + pkt_info->port_number == port_num && + pkt_info->msg_type == msgtype) + { + time->seconds = + ((a_int64_t)ptp_tx_ts0_reg.bf.tx_ts_sec << 32) | + ((a_int64_t)ptp_tx_ts1_reg.bf.tx_ts_sec << 16) | + ptp_tx_ts2_reg.bf.tx_ts_sec; + time->nanoseconds = + ((a_int32_t)ptp_tx_ts3_reg.bf.tx_ts_nsec << 16) | + ptp_tx_ts4_reg.bf.tx_ts_nsec; + time->fracnanoseconds = + ((a_int32_t)ptp_tx_ts5_reg.bf.tx_ts_nfsec << 8) | + ptp_tx_ts6_reg.bf.tx_ts_nfsec; + + return SW_OK; + } + return SW_NOT_FOUND; +} + +sw_error_t +qca808x_phy_ptp_timestamp_get(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_direction_t direction, + fal_ptp_pkt_info_t *pkt_info, fal_ptp_time_t *time) +{ + sw_error_t ret = SW_NOT_FOUND; + a_uint32_t seq = 0; + if (direction == FAL_RX_DIRECTION) + { + for (seq = 0; seq < 4; seq++) { + switch (seq) { + case 0: + ret = qca808x_phy_ptp_rx_timestamp0_get(dev_id, phy_id, + pkt_info, time); + if (ret == SW_OK) { + return ret; + } + break; + case 1: + ret = qca808x_phy_ptp_rx_timestamp1_get(dev_id, phy_id, + pkt_info, time); + if (ret == SW_OK) { + return ret; + } + break; + case 2: + ret = qca808x_phy_ptp_rx_timestamp2_get(dev_id, phy_id, + pkt_info, time); + if (ret == SW_OK) { + return ret; + } + break; + case 3: + ret = qca808x_phy_ptp_rx_timestamp3_get(dev_id, phy_id, + pkt_info, time); + if (ret == SW_OK) { + return ret; + } + break; + default: + break; + } + } + } else { + ret = qca808x_phy_ptp_tx_timestamp0_get(dev_id, phy_id, pkt_info, time); + } + + return ret; +} + +sw_error_t +qca808x_phy_ptp_pkt_timestamp_set(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_time_t *time) +{ + union ptp_in_trig0_reg_u ptp_in_trig0_reg = {0}; + union ptp_in_trig1_reg_u ptp_in_trig1_reg = {0}; + union ptp_in_trig2_reg_u ptp_in_trig2_reg = {0}; + union ptp_in_trig3_reg_u ptp_in_trig3_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_in_trig0_reg_get(dev_id, phy_id, &ptp_in_trig0_reg)); + ptp_in_trig0_reg.bf.ptp_in_trig_nisec = time->nanoseconds >> 16; + SW_RTN_ON_ERROR(qca808x_ptp_in_trig0_reg_set(dev_id, phy_id, &ptp_in_trig0_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_in_trig1_reg_get(dev_id, phy_id, &ptp_in_trig1_reg)); + ptp_in_trig1_reg.bf.ptp_in_trig_nisec = time->nanoseconds & 0xffff; + SW_RTN_ON_ERROR(qca808x_ptp_in_trig1_reg_set(dev_id, phy_id, &ptp_in_trig1_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_in_trig2_reg_get(dev_id, phy_id, &ptp_in_trig2_reg)); + ptp_in_trig2_reg.bf.ptp_in_trig_nisec = time->fracnanoseconds >> 4; + SW_RTN_ON_ERROR(qca808x_ptp_in_trig2_reg_set(dev_id, phy_id, &ptp_in_trig2_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_in_trig3_reg_get(dev_id, phy_id, &ptp_in_trig3_reg)); + ptp_in_trig3_reg.bf.ptp_in_trig_nisec = time->fracnanoseconds & 0xf; + SW_RTN_ON_ERROR(qca808x_ptp_in_trig3_reg_set(dev_id, phy_id, &ptp_in_trig3_reg)); + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_pkt_timestamp_get(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_time_t *time) +{ + union ptp_in_trig0_reg_u ptp_in_trig0_reg = {0}; + union ptp_in_trig1_reg_u ptp_in_trig1_reg = {0}; + union ptp_in_trig2_reg_u ptp_in_trig2_reg = {0}; + union ptp_in_trig3_reg_u ptp_in_trig3_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_in_trig0_reg_get(dev_id, phy_id, &ptp_in_trig0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_in_trig1_reg_get(dev_id, phy_id, &ptp_in_trig1_reg)); + time->nanoseconds = (ptp_in_trig0_reg.bf.ptp_in_trig_nisec << 16) | + ptp_in_trig1_reg.bf.ptp_in_trig_nisec; + + SW_RTN_ON_ERROR(qca808x_ptp_in_trig2_reg_get(dev_id, phy_id, &ptp_in_trig2_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_in_trig3_reg_get(dev_id, phy_id, &ptp_in_trig3_reg)); + time->fracnanoseconds = (ptp_in_trig2_reg.bf.ptp_in_trig_nisec << 4) | + (ptp_in_trig3_reg.bf.ptp_in_trig_nisec & 0xf); + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_grandmaster_mode_set(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_grandmaster_mode_t *gm_mode) +{ + union ptp_gm_conf0_reg_u ptp_gm_conf0_reg = {0}; + union ptp_gm_conf1_reg_u ptp_gm_conf1_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_gm_conf0_reg_get(dev_id, phy_id, &ptp_gm_conf0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_gm_conf1_reg_get(dev_id, phy_id, &ptp_gm_conf1_reg)); + ptp_gm_conf0_reg.bf.grandmaster_mode = gm_mode->grandmaster_mode_en; + if (gm_mode->ns_sync_mode == FAL_GM_PPSIN_MODE) + { + ptp_gm_conf0_reg.bf.gm_pps_sync = PTP_REG_BIT_TRUE; + ptp_gm_conf0_reg.bf.gm_pll_mode = PTP_REG_BIT_FALSE; + } + else if (gm_mode->ns_sync_mode == FAL_GM_HWPLL_MODE) + { + ptp_gm_conf0_reg.bf.gm_pps_sync = PTP_REG_BIT_FALSE; + ptp_gm_conf0_reg.bf.gm_pll_mode = PTP_REG_BIT_TRUE; + } + else + { + ptp_gm_conf0_reg.bf.gm_pps_sync = PTP_REG_BIT_FALSE; + ptp_gm_conf0_reg.bf.gm_pll_mode = PTP_REG_BIT_FALSE; + } + ptp_gm_conf0_reg.bf.gm_maxfreq_offset = gm_mode->freq_offset; + ptp_gm_conf1_reg.bf.gm_kp_ldn = + (gm_mode->right_shift_in_kp << (PTP_GM_CONF1_REG_GM_KP_LDN_LEN-1)) | + gm_mode->kp_value; + ptp_gm_conf1_reg.bf.gm_ki_ldn = + (gm_mode->right_shift_in_ki << (PTP_GM_CONF1_REG_GM_KI_LDN_LEN-1)) | + gm_mode->ki_value; + SW_RTN_ON_ERROR(qca808x_ptp_gm_conf0_reg_set(dev_id, phy_id, &ptp_gm_conf0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_gm_conf1_reg_set(dev_id, phy_id, &ptp_gm_conf1_reg)); + +#if defined(IN_LINUX_STD_PTP) + if (gm_mode->grandmaster_second_sync_en == A_TRUE) { + qca808x_ptp_gm_gps_seconds_sync_enable(dev_id, phy_id, A_TRUE); + } else { + qca808x_ptp_gm_gps_seconds_sync_enable(dev_id, phy_id, A_FALSE); + } +#endif + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_grandmaster_mode_get(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_grandmaster_mode_t *gm_mode) +{ + union ptp_gm_conf0_reg_u ptp_gm_conf0_reg = {0}; + union ptp_gm_conf1_reg_u ptp_gm_conf1_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_gm_conf0_reg_get(dev_id, phy_id, &ptp_gm_conf0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_gm_conf1_reg_get(dev_id, phy_id, &ptp_gm_conf1_reg)); + gm_mode->grandmaster_mode_en = ptp_gm_conf0_reg.bf.grandmaster_mode; + if (ptp_gm_conf0_reg.bf.gm_pps_sync == 1 && ptp_gm_conf0_reg.bf.gm_pll_mode == 0) + { + gm_mode->ns_sync_mode = FAL_GM_PPSIN_MODE; + } + else if (ptp_gm_conf0_reg.bf.gm_pps_sync == 0 && ptp_gm_conf0_reg.bf.gm_pll_mode == 1) + { + gm_mode->ns_sync_mode = FAL_GM_HWPLL_MODE; + } + else + { + gm_mode->ns_sync_mode = FAL_GM_SWPLL_MODE; + } + gm_mode->freq_offset = ptp_gm_conf0_reg.bf.gm_maxfreq_offset; + gm_mode->right_shift_in_kp = ptp_gm_conf1_reg.bf.gm_kp_ldn >> 5; + gm_mode->kp_value = ptp_gm_conf1_reg.bf.gm_kp_ldn & 0x1f; + gm_mode->right_shift_in_ki = ptp_gm_conf1_reg.bf.gm_ki_ldn >> 5; + gm_mode->ki_value = ptp_gm_conf1_reg.bf.gm_ki_ldn & 0x1f; + +#if defined(IN_LINUX_STD_PTP) + if (qca808x_ptp_gm_gps_seconds_sync_status_get(dev_id, phy_id) == A_TRUE) { + gm_mode->grandmaster_second_sync_en = A_TRUE; + } else { + gm_mode->grandmaster_second_sync_en = A_FALSE; + } +#endif + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_rtc_time_get(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_time_t *time) +{ + union ptp_rtc0_reg_u ptp_rtc0_reg = {0}; + union ptp_rtc1_reg_u ptp_rtc1_reg = {0}; + union ptp_rtc2_reg_u ptp_rtc2_reg = {0}; + union ptp_rtc3_reg_u ptp_rtc3_reg = {0}; + union ptp_rtc4_reg_u ptp_rtc4_reg = {0}; + union ptp_rtc5_reg_u ptp_rtc5_reg = {0}; + union ptp_rtc6_reg_u ptp_rtc6_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_rtc0_reg_get(dev_id, phy_id, &ptp_rtc0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rtc1_reg_get(dev_id, phy_id, &ptp_rtc1_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rtc2_reg_get(dev_id, phy_id, &ptp_rtc2_reg)); + time->seconds = ((a_int64_t)ptp_rtc0_reg.bf.ptp_rtc_sec << 32) | + (ptp_rtc1_reg.bf.ptp_rtc_sec << 16) | ptp_rtc2_reg.bf.ptp_rtc_sec; + + SW_RTN_ON_ERROR(qca808x_ptp_rtc3_reg_get(dev_id, phy_id, &ptp_rtc3_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rtc4_reg_get(dev_id, phy_id, &ptp_rtc4_reg)); + time->nanoseconds = (ptp_rtc3_reg.bf.ptp_rtc_nisec << 16) | ptp_rtc4_reg.bf.ptp_rtc_nisec; + + SW_RTN_ON_ERROR(qca808x_ptp_rtc5_reg_get(dev_id, phy_id, &ptp_rtc5_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rtc6_reg_get(dev_id, phy_id, &ptp_rtc6_reg)); + time->fracnanoseconds = (ptp_rtc5_reg.bf.ptp_rtc_nfsec << 4) | + ptp_rtc6_reg.bf.ptp_rtc_nfsec; + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_rtc_time_set(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_time_t *time) +{ + union ptp_rtc_preloaded0_reg_u ptp_rtc_preloaded0_reg = {0}; + union ptp_rtc_preloaded1_reg_u ptp_rtc_preloaded1_reg = {0}; + union ptp_rtc_preloaded2_reg_u ptp_rtc_preloaded2_reg = {0}; + union ptp_rtc_preloaded3_reg_u ptp_rtc_preloaded3_reg = {0}; + union ptp_rtc_preloaded4_reg_u ptp_rtc_preloaded4_reg = {0}; + union ptp_rtc_ext_conf_reg_u ptp_rtc_ext_conf_reg = {0}; + + ptp_rtc_preloaded0_reg.bf.ptp_rtc_preloaded_sec = (time->seconds >> 32) & 0xffff; + ptp_rtc_preloaded1_reg.bf.ptp_rtc_preloaded_sec = (time->seconds >> 16) & 0xffff; + ptp_rtc_preloaded2_reg.bf.ptp_rtc_preloaded_sec = time->seconds & 0xffff; + SW_RTN_ON_ERROR(qca808x_ptp_rtc_preloaded0_reg_set(dev_id, + phy_id, &ptp_rtc_preloaded0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rtc_preloaded1_reg_set(dev_id, + phy_id, &ptp_rtc_preloaded1_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rtc_preloaded2_reg_set(dev_id, + phy_id, &ptp_rtc_preloaded2_reg)); + + ptp_rtc_preloaded3_reg.bf.ptp_rtc_preloaded_nisec = time->nanoseconds >> 16; + ptp_rtc_preloaded4_reg.bf.ptp_rtc_preloaded_nisec = time->nanoseconds & 0xffff; + SW_RTN_ON_ERROR(qca808x_ptp_rtc_preloaded3_reg_set(dev_id, + phy_id, &ptp_rtc_preloaded3_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rtc_preloaded4_reg_set(dev_id, + phy_id, &ptp_rtc_preloaded4_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_rtc_ext_conf_reg_get(dev_id, + phy_id, &ptp_rtc_ext_conf_reg)); + ptp_rtc_ext_conf_reg.bf.load_rtc = 1; + SW_RTN_ON_ERROR(qca808x_ptp_rtc_ext_conf_reg_set(dev_id, + phy_id, &ptp_rtc_ext_conf_reg)); + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_rtc_time_clear(a_uint32_t dev_id, + a_uint32_t phy_id) +{ + union ptp_rtc_ext_conf_reg_u ptp_rtc_ext_conf_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_rtc_ext_conf_reg_get(dev_id, phy_id, &ptp_rtc_ext_conf_reg)); + ptp_rtc_ext_conf_reg.bf.clear_rtc = PTP_REG_BIT_TRUE; + SW_RTN_ON_ERROR(qca808x_ptp_rtc_ext_conf_reg_set(dev_id, phy_id, &ptp_rtc_ext_conf_reg)); + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_rtc_adjtime_set(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_time_t *time) +{ + union ptp_rtcoffs0_reg_u ptp_rtcoffs0_reg = {0}; + union ptp_rtcoffs1_reg_u ptp_rtcoffs1_reg = {0}; + union ptp_rtcoffs2_reg_u ptp_rtcoffs2_reg = {0}; + union ptp_rtcoffs3_reg_u ptp_rtcoffs3_reg = {0}; + union ptp_rtcoffs4_reg_u ptp_rtcoffs4_reg = {0}; + union ptp_rtcoffs_valid_reg_u ptp_rtcoffs_valid_reg = {0}; + + ptp_rtcoffs0_reg.bf.ptp_rtcoffs_nsec = time->nanoseconds >> 16; + ptp_rtcoffs1_reg.bf.ptp_rtcoffs_nsec = time->nanoseconds & 0xffff; + ptp_rtcoffs2_reg.bf.ptp_rtcoffs_sec = (time->seconds >> 32) & 0xffff; + ptp_rtcoffs3_reg.bf.ptp_rtcoffs_sec = (time->seconds >> 16) & 0xffff; + ptp_rtcoffs4_reg.bf.ptp_rtcoffs_sec = time->seconds & 0xffff; + ptp_rtcoffs_valid_reg.bf.ptp_rtcoffs_valid = 1; + SW_RTN_ON_ERROR(qca808x_ptp_rtcoffs0_reg_set(dev_id, phy_id, &ptp_rtcoffs0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rtcoffs1_reg_set(dev_id, phy_id, &ptp_rtcoffs1_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rtcoffs2_reg_set(dev_id, phy_id, &ptp_rtcoffs2_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rtcoffs3_reg_set(dev_id, phy_id, &ptp_rtcoffs3_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rtcoffs4_reg_set(dev_id, phy_id, &ptp_rtcoffs4_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rtcoffs_valid_reg_set(dev_id, phy_id, &ptp_rtcoffs_valid_reg)); + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_rtc_adjfreq_set(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_time_t *time) +{ + union ptp_rtc_ext_conf_reg_u ptp_rtc_ext_conf_reg = {0}; + union ptp_rtc_inc0_reg_u ptp_rtc_inc0_reg = {0}; + union ptp_rtc_inc1_reg_u ptp_rtc_inc1_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_rtc_inc0_reg_get(dev_id, phy_id, &ptp_rtc_inc0_reg)); + ptp_rtc_inc0_reg.bf.ptp_rtc_inc_nis = time->nanoseconds & 0x3f; + ptp_rtc_inc0_reg.bf.ptp_rtc_inc_nfs = (time->fracnanoseconds >> 16) & 0x3ff; + SW_RTN_ON_ERROR(qca808x_ptp_rtc_inc0_reg_set(dev_id, phy_id, &ptp_rtc_inc0_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_rtc_inc1_reg_get(dev_id, phy_id, &ptp_rtc_inc1_reg)); + ptp_rtc_inc1_reg.bf.ptp_rtc_inc_nfs = time->fracnanoseconds & 0xffff; + SW_RTN_ON_ERROR(qca808x_ptp_rtc_inc1_reg_set(dev_id, phy_id, &ptp_rtc_inc1_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_rtc_ext_conf_reg_get(dev_id, phy_id, &ptp_rtc_ext_conf_reg)); + ptp_rtc_ext_conf_reg.bf.set_incval_valid = PTP_REG_BIT_TRUE; + SW_RTN_ON_ERROR(qca808x_ptp_rtc_ext_conf_reg_set(dev_id, phy_id, &ptp_rtc_ext_conf_reg)); + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_rtc_adjfreq_get(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_time_t *time) +{ + union ptp_rtc_inc0_reg_u ptp_rtc_inc0_reg = {0}; + union ptp_rtc_inc1_reg_u ptp_rtc_inc1_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_rtc_inc0_reg_get(dev_id, phy_id, &ptp_rtc_inc0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rtc_inc1_reg_get(dev_id, phy_id, &ptp_rtc_inc1_reg)); + time->nanoseconds = ptp_rtc_inc0_reg.bf.ptp_rtc_inc_nis; + time->fracnanoseconds = (ptp_rtc_inc0_reg.bf.ptp_rtc_inc_nfs << 16) | + ptp_rtc_inc1_reg.bf.ptp_rtc_inc_nfs; + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_link_delay_set(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_time_t *time) +{ + union ptp_link_delay_0_reg_u ptp_link_delay_0_reg = {0}; + union ptp_link_delay_1_reg_u ptp_link_delay_1_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_link_delay_0_reg_get(dev_id, phy_id, &ptp_link_delay_0_reg)); + ptp_link_delay_0_reg.bf.link_delay = time->nanoseconds >> 16; + SW_RTN_ON_ERROR(qca808x_ptp_link_delay_0_reg_set(dev_id, phy_id, &ptp_link_delay_0_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_link_delay_1_reg_get(dev_id, phy_id, &ptp_link_delay_1_reg)); + ptp_link_delay_1_reg.bf.link_delay = time->nanoseconds & 0xffff; + SW_RTN_ON_ERROR(qca808x_ptp_link_delay_1_reg_set(dev_id, phy_id, &ptp_link_delay_1_reg)); + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_link_delay_get(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_time_t *time) +{ + union ptp_link_delay_0_reg_u ptp_link_delay_0_reg = {0}; + union ptp_link_delay_1_reg_u ptp_link_delay_1_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_link_delay_0_reg_get(dev_id, phy_id, &ptp_link_delay_0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_link_delay_1_reg_get(dev_id, phy_id, &ptp_link_delay_1_reg)); + time->nanoseconds = (ptp_link_delay_0_reg.bf.link_delay << 16) | + ptp_link_delay_1_reg.bf.link_delay; + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_security_set(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_security_t *sec) +{ + union ptp_misc_config_reg_u ptp_misc_config_reg = {0}; + union ptp_main_conf_reg_u ptp_main_conf_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_misc_config_reg_get(dev_id, phy_id, &ptp_misc_config_reg)); + ptp_misc_config_reg.bf.ptp_addr_chk_en = sec->address_check_en; + ptp_misc_config_reg.bf.ipv6_udp_chk_en = sec->ipv6_udp_checksum_recal_en; + ptp_misc_config_reg.bf.ptp_ver_chk_en = sec->version_check_en; + ptp_misc_config_reg.bf.ptp_version = sec->ptp_version; + SW_RTN_ON_ERROR(qca808x_ptp_misc_config_reg_set(dev_id, phy_id, &ptp_misc_config_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_main_conf_reg_get(dev_id, phy_id, &ptp_main_conf_reg)); + ptp_main_conf_reg.bf.ipv4_force_checksum_zero = + sec->ipv4_udp_checksum_force_zero_en; + ptp_main_conf_reg.bf.ipv6_embed_force_checksum_zero = + sec->ipv6_embed_udp_checksum_force_zero_en; + SW_RTN_ON_ERROR(qca808x_ptp_main_conf_reg_set(dev_id, phy_id, &ptp_main_conf_reg)); + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_security_get(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_security_t *sec) +{ + union ptp_misc_config_reg_u ptp_misc_config_reg = {0}; + union ptp_main_conf_reg_u ptp_main_conf_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_misc_config_reg_get(dev_id, phy_id, &ptp_misc_config_reg)); + sec->address_check_en = ptp_misc_config_reg.bf.ptp_addr_chk_en; + sec->ipv6_udp_checksum_recal_en = ptp_misc_config_reg.bf.ipv6_udp_chk_en; + sec->version_check_en = ptp_misc_config_reg.bf.ptp_ver_chk_en; + sec->ptp_version = ptp_misc_config_reg.bf.ptp_version; + + SW_RTN_ON_ERROR(qca808x_ptp_main_conf_reg_get(dev_id, phy_id, &ptp_main_conf_reg)); + sec->ipv4_udp_checksum_force_zero_en = ptp_main_conf_reg.bf.ipv4_force_checksum_zero; + sec->ipv6_embed_udp_checksum_force_zero_en = + ptp_main_conf_reg.bf.ipv6_embed_force_checksum_zero; + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_pps_signal_control_set(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_pps_signal_control_t *sig_control) +{ + union ptp_ppsin_latency_reg_u ptp_ppsin_latency_reg = {0}; + union ptp_phase_adjust_0_reg_u ptp_phase_adjust_0_reg = {0}; + union ptp_phase_adjust_1_reg_u ptp_phase_adjust_1_reg = {0}; + union ptp_pps_pul_width_0_reg_u ptp_pps_pul_width_0_reg = {0}; + union ptp_pps_pul_width_1_reg_u ptp_pps_pul_width_1_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_ppsin_latency_reg_get(dev_id, + phy_id, &ptp_ppsin_latency_reg)); + ptp_ppsin_latency_reg.bf.ptp_ppsin_latency_sign = sig_control->negative_in_latency; + ptp_ppsin_latency_reg.bf.ptp_ppsin_latency_value = sig_control->in_latency; + SW_RTN_ON_ERROR(qca808x_ptp_ppsin_latency_reg_set(dev_id, + phy_id, &ptp_ppsin_latency_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_phase_adjust_0_reg_get(dev_id, + phy_id, &ptp_phase_adjust_0_reg)); + ptp_phase_adjust_0_reg.bf.phase_value = sig_control->out_phase >> 16; + SW_RTN_ON_ERROR(qca808x_ptp_phase_adjust_0_reg_set(dev_id, + phy_id, &ptp_phase_adjust_0_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_phase_adjust_1_reg_get(dev_id, + phy_id, &ptp_phase_adjust_1_reg)); + ptp_phase_adjust_1_reg.bf.phase_value = sig_control->out_phase & 0xffff; + SW_RTN_ON_ERROR(qca808x_ptp_phase_adjust_1_reg_set(dev_id, + phy_id, &ptp_phase_adjust_1_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_pps_pul_width_0_reg_get(dev_id, + phy_id, &ptp_pps_pul_width_0_reg)); + ptp_pps_pul_width_0_reg.bf.pul_value = sig_control->out_pulse_width >> 16; + SW_RTN_ON_ERROR(qca808x_ptp_pps_pul_width_0_reg_set(dev_id, + phy_id, &ptp_pps_pul_width_0_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_pps_pul_width_1_reg_get(dev_id, + phy_id, &ptp_pps_pul_width_1_reg)); + ptp_pps_pul_width_1_reg.bf.pul_value = sig_control->out_pulse_width & 0xffff; + SW_RTN_ON_ERROR(qca808x_ptp_pps_pul_width_1_reg_set(dev_id, + phy_id, &ptp_pps_pul_width_1_reg)); + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_pps_signal_control_get(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_pps_signal_control_t *sig_control) +{ + union ptp_ppsin_latency_reg_u ptp_ppsin_latency_reg = {0}; + union ptp_phase_adjust_0_reg_u ptp_phase_adjust_0_reg = {0}; + union ptp_phase_adjust_1_reg_u ptp_phase_adjust_1_reg = {0}; + union ptp_pps_pul_width_0_reg_u ptp_pps_pul_width_0_reg = {0}; + union ptp_pps_pul_width_1_reg_u ptp_pps_pul_width_1_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_ppsin_latency_reg_get(dev_id, + phy_id, &ptp_ppsin_latency_reg)); + sig_control->negative_in_latency = ptp_ppsin_latency_reg.bf.ptp_ppsin_latency_sign; + sig_control->in_latency = ptp_ppsin_latency_reg.bf.ptp_ppsin_latency_value; + + SW_RTN_ON_ERROR(qca808x_ptp_phase_adjust_0_reg_get(dev_id, + phy_id, &ptp_phase_adjust_0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_phase_adjust_1_reg_get(dev_id, + phy_id, &ptp_phase_adjust_1_reg)); + sig_control->out_phase = (ptp_phase_adjust_0_reg.bf.phase_value << 16) | + ptp_phase_adjust_1_reg.bf.phase_value; + + SW_RTN_ON_ERROR(qca808x_ptp_pps_pul_width_0_reg_get(dev_id, + phy_id, &ptp_pps_pul_width_0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_pps_pul_width_1_reg_get(dev_id, + phy_id, &ptp_pps_pul_width_1_reg)); + sig_control->out_pulse_width = (ptp_pps_pul_width_0_reg.bf.pul_value << 16) | + ptp_pps_pul_width_1_reg.bf.pul_value; + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_rx_crc_recalc_enable(a_uint32_t dev_id, + a_uint32_t phy_id, a_bool_t status) +{ + union ptp_misc_config_reg_u ptp_misc_config_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_misc_config_reg_get(dev_id, phy_id, &ptp_misc_config_reg)); + ptp_misc_config_reg.bf.crc_validate_en = status; + SW_RTN_ON_ERROR(qca808x_ptp_misc_config_reg_set(dev_id, phy_id, &ptp_misc_config_reg)); + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_rx_crc_recalc_status_get(a_uint32_t dev_id, + a_uint32_t phy_id, a_bool_t *status) +{ + union ptp_misc_config_reg_u ptp_misc_config_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_misc_config_reg_get(dev_id, phy_id, &ptp_misc_config_reg)); + *status = ptp_misc_config_reg.bf.crc_validate_en; + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_asym_correction_set(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_asym_correction_t *asym_cf) +{ + union ptp_misc_control_reg_u ptp_misc_control_reg = {0}; + union ptp_ingress_asymmetry_0_reg_u ptp_ingress_asymmetry_0_reg = {0}; + union ptp_ingress_asymmetry_1_reg_u ptp_ingress_asymmetry_1_reg = {0}; + union ptp_egress_asymmetry_0_reg_u ptp_egress_asymmetry_0_reg = {0}; + union ptp_egress_asymmetry_1_reg_u ptp_egress_asymmetry_1_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_misc_control_reg_get(dev_id, + phy_id, &ptp_misc_control_reg)); + ptp_misc_control_reg.bf.eg_asym_en = asym_cf->eg_asym_en; + ptp_misc_control_reg.bf.in_asym_en = asym_cf->in_asym_en; + SW_RTN_ON_ERROR(qca808x_ptp_misc_control_reg_set(dev_id, + phy_id, &ptp_misc_control_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_ingress_asymmetry_0_reg_get(dev_id, + phy_id, &ptp_ingress_asymmetry_0_reg)); + ptp_ingress_asymmetry_0_reg.bf.in_asym = asym_cf->in_asym_value >> 16; + SW_RTN_ON_ERROR(qca808x_ptp_ingress_asymmetry_0_reg_set(dev_id, + phy_id, &ptp_ingress_asymmetry_0_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_ingress_asymmetry_1_reg_get(dev_id, + phy_id, &ptp_ingress_asymmetry_1_reg)); + ptp_ingress_asymmetry_1_reg.bf.in_asym = asym_cf->in_asym_value & 0xffff; + SW_RTN_ON_ERROR(qca808x_ptp_ingress_asymmetry_1_reg_set(dev_id, + phy_id, &ptp_ingress_asymmetry_1_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_egress_asymmetry_0_reg_get(dev_id, + phy_id, &ptp_egress_asymmetry_0_reg)); + ptp_egress_asymmetry_0_reg.bf.eg_asym = asym_cf->eg_asym_value >> 16; + SW_RTN_ON_ERROR(qca808x_ptp_egress_asymmetry_0_reg_get(dev_id, + phy_id, &ptp_egress_asymmetry_0_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_egress_asymmetry_1_reg_get(dev_id, + phy_id, &ptp_egress_asymmetry_1_reg)); + ptp_egress_asymmetry_1_reg.bf.eg_asym = asym_cf->eg_asym_value & 0xffff; + SW_RTN_ON_ERROR(qca808x_ptp_egress_asymmetry_1_reg_set(dev_id, + phy_id, &ptp_egress_asymmetry_1_reg)); + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_asym_correction_get(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_asym_correction_t* asym_cf) +{ + union ptp_misc_control_reg_u ptp_misc_control_reg = {0}; + union ptp_ingress_asymmetry_0_reg_u ptp_ingress_asymmetry_0_reg = {0}; + union ptp_ingress_asymmetry_1_reg_u ptp_ingress_asymmetry_1_reg = {0}; + union ptp_egress_asymmetry_0_reg_u ptp_egress_asymmetry_0_reg = {0}; + union ptp_egress_asymmetry_1_reg_u ptp_egress_asymmetry_1_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_misc_control_reg_get(dev_id, + phy_id, &ptp_misc_control_reg)); + asym_cf->eg_asym_en = ptp_misc_control_reg.bf.eg_asym_en; + asym_cf->in_asym_en = ptp_misc_control_reg.bf.in_asym_en; + + SW_RTN_ON_ERROR(qca808x_ptp_ingress_asymmetry_0_reg_get(dev_id, + phy_id, &ptp_ingress_asymmetry_0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_ingress_asymmetry_1_reg_get(dev_id, + phy_id, &ptp_ingress_asymmetry_1_reg)); + asym_cf->in_asym_value = (ptp_ingress_asymmetry_0_reg.bf.in_asym << 16) | + ptp_ingress_asymmetry_1_reg.bf.in_asym; + + SW_RTN_ON_ERROR(qca808x_ptp_egress_asymmetry_0_reg_get(dev_id, + phy_id, &ptp_egress_asymmetry_0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_egress_asymmetry_1_reg_get(dev_id, + phy_id, &ptp_egress_asymmetry_1_reg)); + asym_cf->eg_asym_value = (ptp_egress_asymmetry_0_reg.bf.eg_asym << 16) | + ptp_egress_asymmetry_1_reg.bf.eg_asym; + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_output_waveform_set(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_output_waveform_t *waveform) +{ + union ptp_rtc_ext_conf_reg_u ptp_rtc_ext_conf_reg = {0}; + union ptp_freq_waveform_period_0_reg_u ptp_freq_waveform_period_0_reg = {0}; + union ptp_freq_waveform_period_1_reg_u ptp_freq_waveform_period_1_reg = {0}; + union ptp_freq_waveform_period_2_reg_u ptp_freq_waveform_period_2_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_rtc_ext_conf_reg_get(dev_id, + phy_id, &ptp_rtc_ext_conf_reg)); + if (waveform->waveform_type == FAL_WAVE_FREQ) + { + ptp_rtc_ext_conf_reg.bf.select_output_waveform = + PTP_RTC_EXT_CONF_REG_SELECT_OUTPUT_WAVEFORM_FREQ; + } + else if (waveform->waveform_type == FAL_PULSE_10MS) + { + ptp_rtc_ext_conf_reg.bf.select_output_waveform = + PTP_RTC_EXT_CONF_REG_SELECT_OUTPUT_WAVEFORM_PULSE_10MS; + } + else if (waveform->waveform_type == FAL_TRIGGER0_GPIO) + { + ptp_rtc_ext_conf_reg.bf.select_output_waveform = + PTP_RTC_EXT_CONF_REG_SELECT_OUTPUT_WAVEFORM_TRIG0_GPIO; + } + else + { + ptp_rtc_ext_conf_reg.bf.select_output_waveform = + PTP_RTC_EXT_CONF_REG_SELECT_OUTPUT_WAVEFORM_RXTS_VALID; + } + SW_RTN_ON_ERROR(qca808x_ptp_rtc_ext_conf_reg_set(dev_id, phy_id, &ptp_rtc_ext_conf_reg)); + + ptp_freq_waveform_period_0_reg.bf.phase_ali = waveform->wave_align_pps_out_en; + ptp_freq_waveform_period_0_reg.bf.wave_period = (waveform->wave_period >> 32) & 0x7fff; + ptp_freq_waveform_period_1_reg.bf.wave_period = (waveform->wave_period >> 16) & 0xffff; + ptp_freq_waveform_period_2_reg.bf.wave_period = waveform->wave_period & 0xffff; + SW_RTN_ON_ERROR(qca808x_ptp_freq_waveform_period_0_reg_set(dev_id, + phy_id, &ptp_freq_waveform_period_0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_freq_waveform_period_1_reg_set(dev_id, + phy_id, &ptp_freq_waveform_period_1_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_freq_waveform_period_2_reg_set(dev_id, + phy_id, &ptp_freq_waveform_period_2_reg)); + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_output_waveform_get(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_output_waveform_t *waveform) +{ + union ptp_rtc_ext_conf_reg_u ptp_rtc_ext_conf_reg = {0}; + union ptp_freq_waveform_period_0_reg_u ptp_freq_waveform_period_0_reg = {0}; + union ptp_freq_waveform_period_1_reg_u ptp_freq_waveform_period_1_reg = {0}; + union ptp_freq_waveform_period_2_reg_u ptp_freq_waveform_period_2_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_rtc_ext_conf_reg_get(dev_id, + phy_id, &ptp_rtc_ext_conf_reg)); + if (ptp_rtc_ext_conf_reg.bf.select_output_waveform == + PTP_RTC_EXT_CONF_REG_SELECT_OUTPUT_WAVEFORM_FREQ) + { + waveform->waveform_type = FAL_WAVE_FREQ; + } + else if (ptp_rtc_ext_conf_reg.bf.select_output_waveform == + PTP_RTC_EXT_CONF_REG_SELECT_OUTPUT_WAVEFORM_PULSE_10MS) + { + waveform->waveform_type = FAL_PULSE_10MS; + } + else if (ptp_rtc_ext_conf_reg.bf.select_output_waveform == + PTP_RTC_EXT_CONF_REG_SELECT_OUTPUT_WAVEFORM_TRIG0_GPIO) + { + waveform->waveform_type = FAL_TRIGGER0_GPIO; + } + else + { + waveform->waveform_type = FAL_RX_PTP_STATE; + } + + SW_RTN_ON_ERROR(qca808x_ptp_freq_waveform_period_0_reg_get(dev_id, + phy_id, &ptp_freq_waveform_period_0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_freq_waveform_period_1_reg_get(dev_id, + phy_id, &ptp_freq_waveform_period_1_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_freq_waveform_period_2_reg_get(dev_id, + phy_id, &ptp_freq_waveform_period_2_reg)); + waveform->wave_align_pps_out_en = ptp_freq_waveform_period_0_reg.bf.phase_ali; + waveform->wave_period = ((a_int64_t)ptp_freq_waveform_period_0_reg.bf.wave_period << 32) | + (ptp_freq_waveform_period_1_reg.bf.wave_period << 16) | + ptp_freq_waveform_period_2_reg.bf.wave_period; + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_rtc_time_snapshot_enable(a_uint32_t dev_id, + a_uint32_t phy_id, a_bool_t status) +{ + union ptp_rtc_ext_conf_reg_u ptp_rtc_ext_conf_reg= {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_rtc_ext_conf_reg_get(dev_id, phy_id, &ptp_rtc_ext_conf_reg)); + ptp_rtc_ext_conf_reg.bf.rtc_read_mode = status; + if (status == A_TRUE) + { + ptp_rtc_ext_conf_reg.bf.rtc_snapshot = PTP_REG_BIT_TRUE; + } + + SW_RTN_ON_ERROR(qca808x_ptp_rtc_ext_conf_reg_set(dev_id, phy_id, &ptp_rtc_ext_conf_reg)); + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_rtc_time_snapshot_status_get(a_uint32_t dev_id, + a_uint32_t phy_id, a_bool_t *status) +{ + union ptp_rtc_ext_conf_reg_u ptp_rtc_ext_conf_reg= {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_rtc_ext_conf_reg_get(dev_id, phy_id, &ptp_rtc_ext_conf_reg)); + *status = ptp_rtc_ext_conf_reg.bf.rtc_read_mode; + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_increment_sync_from_clock_enable(a_uint32_t dev_id, + a_uint32_t phy_id, a_bool_t status) +{ + union ptp_rtc_ext_conf_reg_u ptp_rtc_ext_conf_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_rtc_ext_conf_reg_get(dev_id, phy_id, &ptp_rtc_ext_conf_reg)); + ptp_rtc_ext_conf_reg.bf.set_incval_mode = status; + if (status == A_TRUE) + { + ptp_rtc_ext_conf_reg.bf.set_incval_valid = PTP_REG_BIT_TRUE; + } + SW_RTN_ON_ERROR(qca808x_ptp_rtc_ext_conf_reg_set(dev_id, phy_id, &ptp_rtc_ext_conf_reg)); + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_increment_sync_from_clock_status_get(a_uint32_t dev_id, + a_uint32_t phy_id, a_bool_t *status) +{ + union ptp_rtc_ext_conf_reg_u ptp_rtc_ext_conf_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_rtc_ext_conf_reg_get(dev_id, phy_id, &ptp_rtc_ext_conf_reg)); + *status = ptp_rtc_ext_conf_reg.bf.set_incval_mode; + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_tod_uart_set(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_tod_uart_t *tod_uart) +{ + union ptp_baud_config_reg_u ptp_baud_config_reg = {0}; + union ptp_uart_configuration_reg_u ptp_uart_configuration_reg = {0}; + union ptp_reset_buffer_reg_u ptp_reset_buffer_reg = {0}; + union ptp_tx_buffer_write_reg_u ptp_tx_buffer_write_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_baud_config_reg_get(dev_id, phy_id, &ptp_baud_config_reg)); + ptp_baud_config_reg.bf.baud_rate = tod_uart->baud_config; + SW_RTN_ON_ERROR(qca808x_ptp_baud_config_reg_set(dev_id, phy_id, &ptp_baud_config_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_uart_configuration_reg_get(dev_id, + phy_id, &ptp_uart_configuration_reg)); + ptp_uart_configuration_reg.bf.start_polarity = tod_uart->uart_config_bmp & 0x1; + ptp_uart_configuration_reg.bf.msb_first = + (tod_uart->uart_config_bmp >> PTP_UART_CONFIGURATION_REG_MSB_FIRST_OFFSET) & 0x1; + ptp_uart_configuration_reg.bf.parity_en = + (tod_uart->uart_config_bmp >> PTP_UART_CONFIGURATION_REG_PARITY_EN_OFFSET) & 0x1; + ptp_uart_configuration_reg.bf.auto_tod_out_en = + (tod_uart->uart_config_bmp >> PTP_UART_CONFIGURATION_REG_AUTO_TOD_OUT_EN_OFFSET) & 0x1; + ptp_uart_configuration_reg.bf.auto_tod_in_en = + (tod_uart->uart_config_bmp >> PTP_UART_CONFIGURATION_REG_AUTO_TOD_IN_EN_OFFSET) & 0x1; + + SW_RTN_ON_ERROR(qca808x_ptp_uart_configuration_reg_set(dev_id, + phy_id, &ptp_uart_configuration_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_reset_buffer_reg_get(dev_id, phy_id, &ptp_reset_buffer_reg)); + ptp_reset_buffer_reg.bf.reset = tod_uart->reset_buf_en; + SW_RTN_ON_ERROR(qca808x_ptp_reset_buffer_reg_set(dev_id, phy_id, &ptp_reset_buffer_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_tx_buffer_write_reg_get(dev_id, + phy_id, &ptp_tx_buffer_write_reg)); + ptp_tx_buffer_write_reg.bf.tx_buffer = tod_uart->tx_buf_value; + SW_RTN_ON_ERROR(qca808x_ptp_tx_buffer_write_reg_set(dev_id, + phy_id, &ptp_tx_buffer_write_reg)); + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_tod_uart_get(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_tod_uart_t *tod_uart) +{ + union ptp_baud_config_reg_u ptp_baud_config_reg = {0}; + union ptp_uart_configuration_reg_u ptp_uart_configuration_reg = {0}; + union ptp_buffer_status_reg_u ptp_buffer_status_reg = {0}; + union ptp_tx_buffer_write_reg_u ptp_tx_buffer_write_reg = {0}; + union ptp_rx_buffer_read_reg_u ptp_rx_buffer_read_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_baud_config_reg_get(dev_id, phy_id, &ptp_baud_config_reg)); + tod_uart->baud_config = ptp_baud_config_reg.bf.baud_rate; + + SW_RTN_ON_ERROR(qca808x_ptp_uart_configuration_reg_get(dev_id, + phy_id, &ptp_uart_configuration_reg)); + tod_uart->uart_config_bmp = ptp_uart_configuration_reg.bf.start_polarity | + (ptp_uart_configuration_reg.bf.msb_first << + PTP_UART_CONFIGURATION_REG_MSB_FIRST_OFFSET) | + (ptp_uart_configuration_reg.bf.parity_en << + PTP_UART_CONFIGURATION_REG_PARITY_EN_OFFSET) | + (ptp_uart_configuration_reg.bf.auto_tod_out_en << + PTP_UART_CONFIGURATION_REG_AUTO_TOD_OUT_EN_OFFSET) | + (ptp_uart_configuration_reg.bf.auto_tod_in_en << + PTP_UART_CONFIGURATION_REG_AUTO_TOD_IN_EN_OFFSET); + + /* reset buffer is self clearing, always read as 0 */ + tod_uart->reset_buf_en = 0; + + SW_RTN_ON_ERROR(qca808x_ptp_buffer_status_reg_get(dev_id, phy_id, &ptp_buffer_status_reg)); + tod_uart->buf_status_bmp = ptp_buffer_status_reg.bf.tx_buffer_almost_empty | + (ptp_buffer_status_reg.bf.tx_buffer_almost_full << + PTP_BUFFER_STATUS_REG_TX_BUFFER_ALMOST_FULL_OFFSET) | + (ptp_buffer_status_reg.bf.tx_buffer_half_full << + PTP_BUFFER_STATUS_REG_TX_BUFFER_HALF_FULL_OFFSET) | + (ptp_buffer_status_reg.bf.tx_buffer_full << + PTP_BUFFER_STATUS_REG_TX_BUFFER_FULL_OFFSET) | + (ptp_buffer_status_reg.bf.rx_buffer_almost_empty << + PTP_BUFFER_STATUS_REG_RX_BUFFER_ALMOST_EMPTY_OFFSET) | + (ptp_buffer_status_reg.bf.rx_buffer_almost_full << + PTP_BUFFER_STATUS_REG_RX_BUFFER_ALMOST_FULL_OFFSET) | + (ptp_buffer_status_reg.bf.rx_buffer_half_full << + PTP_BUFFER_STATUS_REG_RX_BUFFER_HALF_FULL_OFFSET) | + (ptp_buffer_status_reg.bf.rx_buffer_full << + PTP_BUFFER_STATUS_REG_RX_BUFFER_FULL_OFFSET) | + (ptp_buffer_status_reg.bf.rx_buffer_data_present << + PTP_BUFFER_STATUS_REG_RX_BUFFER_DATA_PRESENT_OFFSET); + + + SW_RTN_ON_ERROR(qca808x_ptp_tx_buffer_write_reg_get(dev_id, + phy_id, &ptp_tx_buffer_write_reg)); + tod_uart->tx_buf_value = ptp_tx_buffer_write_reg.bf.tx_buffer; + + SW_RTN_ON_ERROR(qca808x_ptp_rx_buffer_read_reg_get(dev_id, + phy_id, &ptp_rx_buffer_read_reg)); + tod_uart->rx_buf_value = ptp_rx_buffer_read_reg.bf.rx_data; + + return SW_OK; +} + +sw_error_t +_qca808x_phy_ptp_enhanced_timestamp_engine_rx_set(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_enhanced_ts_engine_t *ts_engine) +{ + union ptp_rx_com_ts_ctrl_reg_u ptp_rx_com_ts_ctrl_reg = {0}; + union ptp_rx_filt_mac_da0_reg_u ptp_rx_filt_mac_da0_reg = {0}; + union ptp_rx_filt_mac_da1_reg_u ptp_rx_filt_mac_da1_reg = {0}; + union ptp_rx_filt_mac_da2_reg_u ptp_rx_filt_mac_da2_reg = {0}; + union ptp_rx_filt_ipv4_da0_reg_u ptp_rx_filt_ipv4_da0_reg = {0}; + union ptp_rx_filt_ipv4_da1_reg_u ptp_rx_filt_ipv4_da1_reg = {0}; + union ptp_rx_filt_ipv6_da0_reg_u ptp_rx_filt_ipv6_da0_reg = {0}; + union ptp_rx_filt_ipv6_da1_reg_u ptp_rx_filt_ipv6_da1_reg = {0}; + union ptp_rx_filt_ipv6_da2_reg_u ptp_rx_filt_ipv6_da2_reg = {0}; + union ptp_rx_filt_ipv6_da3_reg_u ptp_rx_filt_ipv6_da3_reg = {0}; + union ptp_rx_filt_ipv6_da4_reg_u ptp_rx_filt_ipv6_da4_reg = {0}; + union ptp_rx_filt_ipv6_da5_reg_u ptp_rx_filt_ipv6_da5_reg = {0}; + union ptp_rx_filt_ipv6_da6_reg_u ptp_rx_filt_ipv6_da6_reg = {0}; + union ptp_rx_filt_ipv6_da7_reg_u ptp_rx_filt_ipv6_da7_reg = {0}; + union ptp_rx_filt_mac_lengthtype_reg_u ptp_rx_filt_mac_lengthtype_reg = {0}; + union ptp_rx_filt_layer4_protocol_reg_u ptp_rx_filt_layer4_protocol_reg = {0}; + union ptp_rx_filt_udp_port_reg_u ptp_rx_filt_udp_port_reg = {0}; + + union ptp_loc_mac_addr_0_reg_u ptp_loc_mac_addr_0_reg = {0}; + union ptp_loc_mac_addr_1_reg_u ptp_loc_mac_addr_1_reg = {0}; + union ptp_loc_mac_addr_2_reg_u ptp_loc_mac_addr_2_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_rx_com_ts_ctrl_reg_get(dev_id, + phy_id, &ptp_rx_com_ts_ctrl_reg)); + ptp_rx_com_ts_ctrl_reg.bf.filt_en = ts_engine->filt_en; + ptp_rx_com_ts_ctrl_reg.bf.mac_lengthtype_en = + (ts_engine->enhance_ts_conf_bmp >> (PTP_RX_COM_TS_CTRL_REG_MAC_LENGTHTYPE_EN_OFFSET-1) + ) & PTP_REG_BIT_TRUE; + ptp_rx_com_ts_ctrl_reg.bf.mac_da_en = + (ts_engine->enhance_ts_conf_bmp >> (PTP_RX_COM_TS_CTRL_REG_MAC_DA_EN_OFFSET-1) + ) & PTP_REG_BIT_TRUE; + ptp_rx_com_ts_ctrl_reg.bf.mac_ptp_filt_en = + (ts_engine->enhance_ts_conf_bmp >> (PTP_RX_COM_TS_CTRL_REG_MAC_PTP_FILT_EN_OFFSET-1) + ) & PTP_REG_BIT_TRUE; + ptp_rx_com_ts_ctrl_reg.bf.ipv4_layer4_protocol_en = + (ts_engine->enhance_ts_conf_bmp >> (PTP_RX_COM_TS_CTRL_REG_IPV4_LAYER4_PROTOCOL_EN_OFFSET-1) + ) & PTP_REG_BIT_TRUE; + ptp_rx_com_ts_ctrl_reg.bf.ipv4_da_en = + (ts_engine->enhance_ts_conf_bmp >> (PTP_RX_COM_TS_CTRL_REG_IPV4_DA_EN_OFFSET-1) + ) & PTP_REG_BIT_TRUE; + ptp_rx_com_ts_ctrl_reg.bf.ipv4_ptp_filt_en = + (ts_engine->enhance_ts_conf_bmp >> (PTP_RX_COM_TS_CTRL_REG_IPV4_PTP_FILT_EN_OFFSET-1) + ) & PTP_REG_BIT_TRUE; + ptp_rx_com_ts_ctrl_reg.bf.ipv6_next_header_en = + (ts_engine->enhance_ts_conf_bmp >> (PTP_RX_COM_TS_CTRL_REG_IPV6_NEXT_HEADER_EN_OFFSET-1) + ) & PTP_REG_BIT_TRUE; + ptp_rx_com_ts_ctrl_reg.bf.ipv6_da_filt_en = + (ts_engine->enhance_ts_conf_bmp >> (PTP_RX_COM_TS_CTRL_REG_IPV6_DA_FILT_EN_OFFSET-1) + ) & PTP_REG_BIT_TRUE; + ptp_rx_com_ts_ctrl_reg.bf.ipv6_ptp_filt_en = + (ts_engine->enhance_ts_conf_bmp >> (PTP_RX_COM_TS_CTRL_REG_IPV6_PTP_FILT_EN_OFFSET-1) + ) & PTP_REG_BIT_TRUE; + ptp_rx_com_ts_ctrl_reg.bf.udp_dport_en = + (ts_engine->enhance_ts_conf_bmp >> (PTP_RX_COM_TS_CTRL_REG_UDP_DPORT_EN_OFFSET-1) + ) & PTP_REG_BIT_TRUE; + ptp_rx_com_ts_ctrl_reg.bf.udp_ptp_event_filt_en = + (ts_engine->enhance_ts_conf_bmp >> (PTP_RX_COM_TS_CTRL_REG_UDP_PTP_EVENT_FILT_EN_OFFSET-1) + ) & PTP_REG_BIT_TRUE; + ptp_rx_com_ts_ctrl_reg.bf.y1731_en = + (ts_engine->enhance_ts_conf_bmp >> (PTP_RX_COM_TS_CTRL_REG_Y1731_EN_OFFSET-1) + ) & PTP_REG_BIT_TRUE; + ptp_rx_com_ts_ctrl_reg.bf.y1731_insert_ts_en = + (ts_engine->enhance_ts_conf_bmp >> (PTP_RX_COM_TS_CTRL_REG_Y1731_INSERT_TS_EN_OFFSET-1) + ) & PTP_REG_BIT_TRUE; + ptp_rx_com_ts_ctrl_reg.bf.y1731_da_chk_en = + (ts_engine->enhance_ts_conf_bmp >> (PTP_RX_COM_TS_CTRL_REG_Y1731_DA_CHK_EN_OFFSET-1) + ) & PTP_REG_BIT_TRUE; + SW_RTN_ON_ERROR(qca808x_ptp_rx_com_ts_ctrl_reg_set(dev_id, + phy_id, &ptp_rx_com_ts_ctrl_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_mac_lengthtype_reg_get(dev_id, + phy_id, &ptp_rx_filt_mac_lengthtype_reg)); + ptp_rx_filt_mac_lengthtype_reg.bf.length_type = ts_engine->eth_type; + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_mac_lengthtype_reg_set(dev_id, + phy_id, &ptp_rx_filt_mac_lengthtype_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_mac_da0_reg_get(dev_id, + phy_id, &ptp_rx_filt_mac_da0_reg)); + ptp_rx_filt_mac_da0_reg.bf.mac_addr = (ts_engine->dmac_addr.uc[0] << 8) | + ts_engine->dmac_addr.uc[1]; + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_mac_da0_reg_set(dev_id, + phy_id, &ptp_rx_filt_mac_da0_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_mac_da1_reg_get(dev_id, + phy_id, &ptp_rx_filt_mac_da1_reg)); + ptp_rx_filt_mac_da1_reg.bf.mac_addr = (ts_engine->dmac_addr.uc[2] << 8) | + ts_engine->dmac_addr.uc[3]; + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_mac_da1_reg_set(dev_id, + phy_id, &ptp_rx_filt_mac_da1_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_mac_da2_reg_get(dev_id, + phy_id, &ptp_rx_filt_mac_da2_reg)); + ptp_rx_filt_mac_da2_reg.bf.mac_addr = (ts_engine->dmac_addr.uc[4] << 8) | + ts_engine->dmac_addr.uc[5]; + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_mac_da2_reg_set(dev_id, + phy_id, &ptp_rx_filt_mac_da2_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_layer4_protocol_reg_get(dev_id, + phy_id, &ptp_rx_filt_layer4_protocol_reg)); + ptp_rx_filt_layer4_protocol_reg.bf.l4_protocol = ts_engine->ipv4_l4_proto; + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_layer4_protocol_reg_set(dev_id, + phy_id, &ptp_rx_filt_layer4_protocol_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_ipv4_da0_reg_get(dev_id, + phy_id, &ptp_rx_filt_ipv4_da0_reg)); + ptp_rx_filt_ipv4_da0_reg.bf.ip_addr = ts_engine->ipv4_dip >> 16; + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_ipv4_da0_reg_set(dev_id, + phy_id, &ptp_rx_filt_ipv4_da0_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_ipv4_da1_reg_get(dev_id, + phy_id, &ptp_rx_filt_ipv4_da1_reg)); + ptp_rx_filt_ipv4_da1_reg.bf.ip_addr = ts_engine->ipv4_dip & 0xffff; + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_ipv4_da1_reg_set(dev_id, + phy_id, &ptp_rx_filt_ipv4_da1_reg));; + + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_ipv6_da0_reg_get(dev_id, + phy_id, &ptp_rx_filt_ipv6_da0_reg)); + ptp_rx_filt_ipv6_da0_reg.bf.ip_addr = ts_engine->ipv6_dip.ul[0] >> 16; + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_ipv6_da0_reg_set(dev_id, + phy_id, &ptp_rx_filt_ipv6_da0_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_ipv6_da1_reg_get(dev_id, + phy_id, &ptp_rx_filt_ipv6_da1_reg)); + ptp_rx_filt_ipv6_da1_reg.bf.ip_addr = ts_engine->ipv6_dip.ul[0] & 0xffff; + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_ipv6_da1_reg_set(dev_id, + phy_id, &ptp_rx_filt_ipv6_da1_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_ipv6_da2_reg_get(dev_id, + phy_id, &ptp_rx_filt_ipv6_da2_reg)); + ptp_rx_filt_ipv6_da2_reg.bf.ip_addr = ts_engine->ipv6_dip.ul[1] >> 16; + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_ipv6_da2_reg_set(dev_id, + phy_id, &ptp_rx_filt_ipv6_da2_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_ipv6_da3_reg_get(dev_id, + phy_id, &ptp_rx_filt_ipv6_da3_reg)); + ptp_rx_filt_ipv6_da3_reg.bf.ip_addr = ts_engine->ipv6_dip.ul[1] & 0xffff; + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_ipv6_da3_reg_set(dev_id, + phy_id, &ptp_rx_filt_ipv6_da3_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_ipv6_da4_reg_get(dev_id, + phy_id, &ptp_rx_filt_ipv6_da4_reg)); + ptp_rx_filt_ipv6_da4_reg.bf.ip_addr = ts_engine->ipv6_dip.ul[2] >> 16; + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_ipv6_da4_reg_set(dev_id, + phy_id, &ptp_rx_filt_ipv6_da4_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_ipv6_da5_reg_get(dev_id, + phy_id, &ptp_rx_filt_ipv6_da5_reg)); + ptp_rx_filt_ipv6_da5_reg.bf.ip_addr = ts_engine->ipv6_dip.ul[2] & 0xffff; + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_ipv6_da5_reg_set(dev_id, + phy_id, &ptp_rx_filt_ipv6_da5_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_ipv6_da6_reg_get(dev_id, + phy_id, &ptp_rx_filt_ipv6_da6_reg)); + ptp_rx_filt_ipv6_da6_reg.bf.ip_addr = ts_engine->ipv6_dip.ul[3] >> 16; + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_ipv6_da6_reg_set(dev_id, + phy_id, &ptp_rx_filt_ipv6_da6_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_ipv6_da7_reg_get(dev_id, + phy_id, &ptp_rx_filt_ipv6_da7_reg)); + ptp_rx_filt_ipv6_da7_reg.bf.ip_addr = ts_engine->ipv6_dip.ul[3] & 0xffff; + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_ipv6_da7_reg_set(dev_id, + phy_id, &ptp_rx_filt_ipv6_da7_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_udp_port_reg_get(dev_id, + phy_id, &ptp_rx_filt_udp_port_reg)); + ptp_rx_filt_udp_port_reg.bf.udp_port = ts_engine->udp_dport; + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_udp_port_reg_set(dev_id, + phy_id, &ptp_rx_filt_udp_port_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_loc_mac_addr_0_reg_get(dev_id, + phy_id, &ptp_loc_mac_addr_0_reg)); + ptp_loc_mac_addr_0_reg.bf.mac_addr = (ts_engine->y1731_mac_addr.uc[0] << 8) | + ts_engine->y1731_mac_addr.uc[1]; + SW_RTN_ON_ERROR(qca808x_ptp_loc_mac_addr_0_reg_set(dev_id, + phy_id, &ptp_loc_mac_addr_0_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_loc_mac_addr_1_reg_get(dev_id, + phy_id, &ptp_loc_mac_addr_1_reg)); + ptp_loc_mac_addr_1_reg.bf.mac_addr = (ts_engine->y1731_mac_addr.uc[2] << 8) | + ts_engine->y1731_mac_addr.uc[3]; + SW_RTN_ON_ERROR(qca808x_ptp_loc_mac_addr_1_reg_set(dev_id, + phy_id, &ptp_loc_mac_addr_1_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_loc_mac_addr_2_reg_get(dev_id, + phy_id, &ptp_loc_mac_addr_2_reg)); + ptp_loc_mac_addr_2_reg.bf.mac_addr = (ts_engine->y1731_mac_addr.uc[4] << 8) | + ts_engine->y1731_mac_addr.uc[5]; + SW_RTN_ON_ERROR(qca808x_ptp_loc_mac_addr_2_reg_set(dev_id, + phy_id, &ptp_loc_mac_addr_2_reg)); + + return SW_OK; +} + + +sw_error_t +_qca808x_phy_ptp_enhanced_timestamp_engine_tx_set(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_enhanced_ts_engine_t *ts_engine) +{ + union ptp_tx_com_ts_ctrl_reg_u ptp_tx_com_ts_ctrl_reg = {0}; + union ptp_tx_filt_mac_da0_reg_u ptp_tx_filt_mac_da0_reg = {0}; + union ptp_tx_filt_mac_da1_reg_u ptp_tx_filt_mac_da1_reg = {0}; + union ptp_tx_filt_mac_da2_reg_u ptp_tx_filt_mac_da2_reg = {0}; + union ptp_tx_filt_ipv4_da0_reg_u ptp_tx_filt_ipv4_da0_reg = {0}; + union ptp_tx_filt_ipv4_da1_reg_u ptp_tx_filt_ipv4_da1_reg = {0}; + union ptp_tx_filt_ipv6_da0_reg_u ptp_tx_filt_ipv6_da0_reg = {0}; + union ptp_tx_filt_ipv6_da1_reg_u ptp_tx_filt_ipv6_da1_reg = {0}; + union ptp_tx_filt_ipv6_da2_reg_u ptp_tx_filt_ipv6_da2_reg = {0}; + union ptp_tx_filt_ipv6_da3_reg_u ptp_tx_filt_ipv6_da3_reg = {0}; + union ptp_tx_filt_ipv6_da4_reg_u ptp_tx_filt_ipv6_da4_reg = {0}; + union ptp_tx_filt_ipv6_da5_reg_u ptp_tx_filt_ipv6_da5_reg = {0}; + union ptp_tx_filt_ipv6_da6_reg_u ptp_tx_filt_ipv6_da6_reg = {0}; + union ptp_tx_filt_ipv6_da7_reg_u ptp_tx_filt_ipv6_da7_reg = {0}; + union ptp_tx_filt_mac_lengthtype_reg_u ptp_tx_filt_mac_lengthtype_reg = {0}; + union ptp_tx_filt_layer4_protocol_reg_u ptp_tx_filt_layer4_protocol_reg = {0}; + union ptp_tx_filt_udp_port_reg_u ptp_tx_filt_udp_port_reg = {0}; + + union ptp_loc_mac_addr_0_reg_u ptp_loc_mac_addr_0_reg = {0}; + union ptp_loc_mac_addr_1_reg_u ptp_loc_mac_addr_1_reg = {0}; + union ptp_loc_mac_addr_2_reg_u ptp_loc_mac_addr_2_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_tx_com_ts_ctrl_reg_get(dev_id, + phy_id, &ptp_tx_com_ts_ctrl_reg)); + ptp_tx_com_ts_ctrl_reg.bf.filt_en = ts_engine->filt_en; + ptp_tx_com_ts_ctrl_reg.bf.mac_lengthtype_en = ts_engine->enhance_ts_conf_bmp & + PTP_REG_BIT_TRUE; + ptp_tx_com_ts_ctrl_reg.bf.mac_da_en = + (ts_engine->enhance_ts_conf_bmp >> (PTP_TX_COM_TS_CTRL_REG_MAC_DA_EN_OFFSET-1) + ) & PTP_REG_BIT_TRUE; + ptp_tx_com_ts_ctrl_reg.bf.mac_ptp_filt_en = + (ts_engine->enhance_ts_conf_bmp >> (PTP_TX_COM_TS_CTRL_REG_MAC_PTP_FILT_EN_OFFSET-1) + ) & PTP_REG_BIT_TRUE; + ptp_tx_com_ts_ctrl_reg.bf.ipv4_layer4_protocol_en = + (ts_engine->enhance_ts_conf_bmp >> (PTP_TX_COM_TS_CTRL_REG_IPV4_LAYER4_PROTOCOL_EN_OFFSET-1) + ) & PTP_REG_BIT_TRUE; + ptp_tx_com_ts_ctrl_reg.bf.ipv4_da_en = + (ts_engine->enhance_ts_conf_bmp >> (PTP_TX_COM_TS_CTRL_REG_IPV4_DA_EN_OFFSET-1) + ) & PTP_REG_BIT_TRUE; + ptp_tx_com_ts_ctrl_reg.bf.ipv4_ptp_filt_en = + (ts_engine->enhance_ts_conf_bmp >> (PTP_TX_COM_TS_CTRL_REG_IPV4_PTP_FILT_EN_OFFSET-1) + ) & PTP_REG_BIT_TRUE; + ptp_tx_com_ts_ctrl_reg.bf.ipv6_next_header_en = + (ts_engine->enhance_ts_conf_bmp >> (PTP_TX_COM_TS_CTRL_REG_IPV6_NEXT_HEADER_EN_OFFSET-1) + ) & PTP_REG_BIT_TRUE; + ptp_tx_com_ts_ctrl_reg.bf.ipv6_da_en = + (ts_engine->enhance_ts_conf_bmp >> (PTP_TX_COM_TS_CTRL_REG_IPV6_DA_EN_OFFSET-1) + ) & PTP_REG_BIT_TRUE; + ptp_tx_com_ts_ctrl_reg.bf.ipv6_ptp_filt_en = + (ts_engine->enhance_ts_conf_bmp >> (PTP_TX_COM_TS_CTRL_REG_IPV6_PTP_FILT_EN_OFFSET-1) + ) & PTP_REG_BIT_TRUE; + ptp_tx_com_ts_ctrl_reg.bf.udp_dport_en = + (ts_engine->enhance_ts_conf_bmp >> (PTP_TX_COM_TS_CTRL_REG_UDP_DPORT_EN_OFFSET-1) + ) & PTP_REG_BIT_TRUE; + ptp_tx_com_ts_ctrl_reg.bf.udp_ptp_event_filt_en = + (ts_engine->enhance_ts_conf_bmp >> (PTP_TX_COM_TS_CTRL_REG_UDP_PTP_EVENT_FILT_EN_OFFSET-1) + ) & PTP_REG_BIT_TRUE; + ptp_tx_com_ts_ctrl_reg.bf.y1731_en = + (ts_engine->enhance_ts_conf_bmp >> (PTP_TX_COM_TS_CTRL_REG_Y1731_EN_OFFSET-1) + ) & PTP_REG_BIT_TRUE; + ptp_tx_com_ts_ctrl_reg.bf.y1731_insert_ts_en = + (ts_engine->enhance_ts_conf_bmp >> (PTP_TX_COM_TS_CTRL_REG_Y1731_INSERT_TS_EN_OFFSET-1) + ) & PTP_REG_BIT_TRUE; + ptp_tx_com_ts_ctrl_reg.bf.y1731_sa_chk_en = + (ts_engine->enhance_ts_conf_bmp >> (PTP_TX_COM_TS_CTRL_REG_Y1731_SA_CHK_EN_OFFSET-1) + ) & PTP_REG_BIT_TRUE; + SW_RTN_ON_ERROR(qca808x_ptp_tx_com_ts_ctrl_reg_set(dev_id, + phy_id, &ptp_tx_com_ts_ctrl_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_mac_lengthtype_reg_get(dev_id, + phy_id, &ptp_tx_filt_mac_lengthtype_reg)); + ptp_tx_filt_mac_lengthtype_reg.bf.length_type = ts_engine->eth_type; + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_mac_lengthtype_reg_set(dev_id, + phy_id, &ptp_tx_filt_mac_lengthtype_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_mac_da0_reg_get(dev_id, + phy_id, &ptp_tx_filt_mac_da0_reg)); + ptp_tx_filt_mac_da0_reg.bf.mac_addr = (ts_engine->dmac_addr.uc[0] << 8) | + ts_engine->dmac_addr.uc[1]; + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_mac_da0_reg_set(dev_id, + phy_id, &ptp_tx_filt_mac_da0_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_mac_da1_reg_get(dev_id, + phy_id, &ptp_tx_filt_mac_da1_reg)); + ptp_tx_filt_mac_da1_reg.bf.mac_addr = (ts_engine->dmac_addr.uc[2] << 8) | + ts_engine->dmac_addr.uc[3]; + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_mac_da1_reg_set(dev_id, + phy_id, &ptp_tx_filt_mac_da1_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_mac_da2_reg_get(dev_id, + phy_id, &ptp_tx_filt_mac_da2_reg)); + ptp_tx_filt_mac_da2_reg.bf.mac_addr = (ts_engine->dmac_addr.uc[4] << 8) | + ts_engine->dmac_addr.uc[5]; + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_mac_da2_reg_set(dev_id, + phy_id, &ptp_tx_filt_mac_da2_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_layer4_protocol_reg_get(dev_id, + phy_id, &ptp_tx_filt_layer4_protocol_reg)); + ptp_tx_filt_layer4_protocol_reg.bf.l4_protocol = ts_engine->ipv4_l4_proto; + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_layer4_protocol_reg_set(dev_id, + phy_id, &ptp_tx_filt_layer4_protocol_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_ipv4_da0_reg_get(dev_id, + phy_id, &ptp_tx_filt_ipv4_da0_reg)); + ptp_tx_filt_ipv4_da0_reg.bf.ip_addr = ts_engine->ipv4_dip >> 16; + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_ipv4_da0_reg_set(dev_id, + phy_id, &ptp_tx_filt_ipv4_da0_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_ipv4_da1_reg_get(dev_id, + phy_id, &ptp_tx_filt_ipv4_da1_reg)); + ptp_tx_filt_ipv4_da1_reg.bf.ip_addr = ts_engine->ipv4_dip & 0xffff; + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_ipv4_da1_reg_set(dev_id, + phy_id, &ptp_tx_filt_ipv4_da1_reg));; + + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_ipv6_da0_reg_get(dev_id, + phy_id, &ptp_tx_filt_ipv6_da0_reg)); + ptp_tx_filt_ipv6_da0_reg.bf.ip_addr = ts_engine->ipv6_dip.ul[0] >> 16; + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_ipv6_da0_reg_set(dev_id, + phy_id, &ptp_tx_filt_ipv6_da0_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_ipv6_da1_reg_get(dev_id, + phy_id, &ptp_tx_filt_ipv6_da1_reg)); + ptp_tx_filt_ipv6_da1_reg.bf.ip_addr = ts_engine->ipv6_dip.ul[0] & 0xffff; + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_ipv6_da1_reg_set(dev_id, + phy_id, &ptp_tx_filt_ipv6_da1_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_ipv6_da2_reg_get(dev_id, + phy_id, &ptp_tx_filt_ipv6_da2_reg)); + ptp_tx_filt_ipv6_da2_reg.bf.ip_addr = ts_engine->ipv6_dip.ul[1] >> 16; + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_ipv6_da2_reg_set(dev_id, + phy_id, &ptp_tx_filt_ipv6_da2_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_ipv6_da3_reg_get(dev_id, + phy_id, &ptp_tx_filt_ipv6_da3_reg)); + ptp_tx_filt_ipv6_da3_reg.bf.ip_addr = ts_engine->ipv6_dip.ul[1] & 0xffff; + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_ipv6_da3_reg_set(dev_id, + phy_id, &ptp_tx_filt_ipv6_da3_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_ipv6_da4_reg_get(dev_id, + phy_id, &ptp_tx_filt_ipv6_da4_reg)); + ptp_tx_filt_ipv6_da4_reg.bf.ip_addr = ts_engine->ipv6_dip.ul[2] >> 16; + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_ipv6_da4_reg_set(dev_id, + phy_id, &ptp_tx_filt_ipv6_da4_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_ipv6_da5_reg_get(dev_id, + phy_id, &ptp_tx_filt_ipv6_da5_reg)); + ptp_tx_filt_ipv6_da5_reg.bf.ip_addr = ts_engine->ipv6_dip.ul[2] & 0xffff; + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_ipv6_da5_reg_set(dev_id, + phy_id, &ptp_tx_filt_ipv6_da5_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_ipv6_da6_reg_get(dev_id, + phy_id, &ptp_tx_filt_ipv6_da6_reg)); + ptp_tx_filt_ipv6_da6_reg.bf.ip_addr = ts_engine->ipv6_dip.ul[3] >> 16; + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_ipv6_da6_reg_set(dev_id, + phy_id, &ptp_tx_filt_ipv6_da6_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_ipv6_da7_reg_get(dev_id, + phy_id, &ptp_tx_filt_ipv6_da7_reg)); + ptp_tx_filt_ipv6_da7_reg.bf.ip_addr = ts_engine->ipv6_dip.ul[3] & 0xffff; + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_ipv6_da7_reg_set(dev_id, + phy_id, &ptp_tx_filt_ipv6_da7_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_udp_port_reg_get(dev_id, + phy_id, &ptp_tx_filt_udp_port_reg)); + ptp_tx_filt_udp_port_reg.bf.udp_port = ts_engine->udp_dport; + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_udp_port_reg_set(dev_id, + phy_id, &ptp_tx_filt_udp_port_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_loc_mac_addr_0_reg_get(dev_id, + phy_id, &ptp_loc_mac_addr_0_reg)); + ptp_loc_mac_addr_0_reg.bf.mac_addr = (ts_engine->y1731_mac_addr.uc[0] << 8) | + ts_engine->y1731_mac_addr.uc[1]; + SW_RTN_ON_ERROR(qca808x_ptp_loc_mac_addr_0_reg_set(dev_id, + phy_id, &ptp_loc_mac_addr_0_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_loc_mac_addr_1_reg_get(dev_id, + phy_id, &ptp_loc_mac_addr_1_reg)); + ptp_loc_mac_addr_1_reg.bf.mac_addr = (ts_engine->y1731_mac_addr.uc[2] << 8) | + ts_engine->y1731_mac_addr.uc[3]; + SW_RTN_ON_ERROR(qca808x_ptp_loc_mac_addr_1_reg_set(dev_id, + phy_id, &ptp_loc_mac_addr_1_reg)); + + SW_RTN_ON_ERROR(qca808x_ptp_loc_mac_addr_2_reg_get(dev_id, + phy_id, &ptp_loc_mac_addr_2_reg)); + ptp_loc_mac_addr_2_reg.bf.mac_addr = (ts_engine->y1731_mac_addr.uc[4] << 8) | + ts_engine->y1731_mac_addr.uc[5]; + SW_RTN_ON_ERROR(qca808x_ptp_loc_mac_addr_2_reg_set(dev_id, + phy_id, &ptp_loc_mac_addr_2_reg)); + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_enhanced_timestamp_engine_set(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_direction_t direction, + fal_ptp_enhanced_ts_engine_t *ts_engine) +{ + if (direction == FAL_RX_DIRECTION) + { + return _qca808x_phy_ptp_enhanced_timestamp_engine_rx_set(dev_id, phy_id, ts_engine); + } + else + { + return _qca808x_phy_ptp_enhanced_timestamp_engine_tx_set(dev_id, phy_id, ts_engine); + } + + return SW_BAD_PARAM; +} + +sw_error_t +_qca808x_phy_ptp_enhanced_timestamp_engine_rx_com_ts_get(a_uint32_t dev_id, a_uint32_t phy_id, + fal_ptp_enhanced_ts_engine_t *ts_engine) +{ + sw_error_t ret = SW_OK; + + union ptp_rx_com_timestamp0_reg_u ptp_rx_com_timestamp0_reg = {0}; + union ptp_rx_com_timestamp1_reg_u ptp_rx_com_timestamp1_reg = {0}; + union ptp_rx_com_timestamp2_reg_u ptp_rx_com_timestamp2_reg = {0}; + union ptp_rx_com_timestamp3_reg_u ptp_rx_com_timestamp3_reg = {0}; + union ptp_rx_com_timestamp4_reg_u ptp_rx_com_timestamp4_reg = {0}; + union ptp_rx_com_frac_nano_reg_u ptp_rx_com_frac_nano_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_rx_com_timestamp0_reg_get(dev_id, + phy_id, &ptp_rx_com_timestamp0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_com_timestamp1_reg_get(dev_id, + phy_id, &ptp_rx_com_timestamp1_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_com_timestamp2_reg_get(dev_id, + phy_id, &ptp_rx_com_timestamp2_reg)); + ts_engine->timestamp.seconds = + ((a_int64_t)ptp_rx_com_timestamp0_reg.bf.com_ts << 32) | + (ptp_rx_com_timestamp1_reg.bf.com_ts << 16) | ptp_rx_com_timestamp2_reg.bf.com_ts; + + SW_RTN_ON_ERROR(qca808x_ptp_rx_com_timestamp3_reg_get(dev_id, + phy_id, &ptp_rx_com_timestamp3_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_com_timestamp4_reg_get(dev_id, + phy_id, &ptp_rx_com_timestamp4_reg)); + ts_engine->timestamp.nanoseconds = (ptp_rx_com_timestamp3_reg.bf.com_ts << 16) | + ptp_rx_com_timestamp4_reg.bf.com_ts; + + SW_RTN_ON_ERROR(qca808x_ptp_rx_com_frac_nano_reg_get(dev_id, + phy_id, &ptp_rx_com_frac_nano_reg)); + ts_engine->timestamp.fracnanoseconds = ptp_rx_com_frac_nano_reg.bf.frac_nano; + + return ret; +} + +sw_error_t +_qca808x_phy_ptp_enhanced_timestamp_engine_rx_com_ts_pre_get(a_uint32_t dev_id, a_uint32_t phy_id, + fal_ptp_enhanced_ts_engine_t *ts_engine) +{ + sw_error_t ret = SW_OK; + union ptp_rx_com_timestamp_pre0_reg_u ptp_rx_com_timestamp_pre0_reg = {0}; + union ptp_rx_com_timestamp_pre1_reg_u ptp_rx_com_timestamp_pre1_reg = {0}; + union ptp_rx_com_timestamp_pre2_reg_u ptp_rx_com_timestamp_pre2_reg = {0}; + union ptp_rx_com_timestamp_pre3_reg_u ptp_rx_com_timestamp_pre3_reg = {0}; + union ptp_rx_com_timestamp_pre4_reg_u ptp_rx_com_timestamp_pre4_reg = {0}; + union ptp_rx_com_frac_nano_pre_reg_u ptp_rx_com_frac_nano_pre_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_rx_com_timestamp_pre0_reg_get(dev_id, + phy_id, &ptp_rx_com_timestamp_pre0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_com_timestamp_pre1_reg_get(dev_id, + phy_id, &ptp_rx_com_timestamp_pre1_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_com_timestamp_pre2_reg_get(dev_id, + phy_id, &ptp_rx_com_timestamp_pre2_reg)); + ts_engine->timestamp_pre.seconds = + ((a_int64_t)ptp_rx_com_timestamp_pre0_reg.bf.com_ts_pre << 32) | + (ptp_rx_com_timestamp_pre1_reg.bf.com_ts_pre << 16) | + ptp_rx_com_timestamp_pre2_reg.bf.com_ts_pre; + + SW_RTN_ON_ERROR(qca808x_ptp_rx_com_timestamp_pre3_reg_get(dev_id, + phy_id, &ptp_rx_com_timestamp_pre3_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_com_timestamp_pre4_reg_get(dev_id, + phy_id, &ptp_rx_com_timestamp_pre4_reg)); + ts_engine->timestamp_pre.nanoseconds = + (ptp_rx_com_timestamp_pre3_reg.bf.com_ts_pre << 16) | + ptp_rx_com_timestamp_pre4_reg.bf.com_ts_pre; + + SW_RTN_ON_ERROR(qca808x_ptp_rx_com_frac_nano_pre_reg_get(dev_id, + phy_id, &ptp_rx_com_frac_nano_pre_reg)); + ts_engine->timestamp_pre.fracnanoseconds = + ptp_rx_com_frac_nano_pre_reg.bf.frac_nano_pre; + + return ret; +} + +sw_error_t +_qca808x_phy_ptp_enhanced_timestamp_engine_rx_get(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_enhanced_ts_engine_t *ts_engine) +{ + sw_error_t ret = SW_OK; + union ptp_rx_com_ts_ctrl_reg_u ctrl_reg = {0}; + union ptp_rx_filt_mac_da0_reg_u ptp_rx_filt_mac_da0_reg = {0}; + union ptp_rx_filt_mac_da1_reg_u ptp_rx_filt_mac_da1_reg = {0}; + union ptp_rx_filt_mac_da2_reg_u ptp_rx_filt_mac_da2_reg = {0}; + union ptp_rx_filt_ipv4_da0_reg_u ptp_rx_filt_ipv4_da0_reg = {0}; + union ptp_rx_filt_ipv4_da1_reg_u ptp_rx_filt_ipv4_da1_reg = {0}; + union ptp_rx_filt_ipv6_da0_reg_u ptp_rx_filt_ipv6_da0_reg = {0}; + union ptp_rx_filt_ipv6_da1_reg_u ptp_rx_filt_ipv6_da1_reg = {0}; + union ptp_rx_filt_ipv6_da2_reg_u ptp_rx_filt_ipv6_da2_reg = {0}; + union ptp_rx_filt_ipv6_da3_reg_u ptp_rx_filt_ipv6_da3_reg = {0}; + union ptp_rx_filt_ipv6_da4_reg_u ptp_rx_filt_ipv6_da4_reg = {0}; + union ptp_rx_filt_ipv6_da5_reg_u ptp_rx_filt_ipv6_da5_reg = {0}; + union ptp_rx_filt_ipv6_da6_reg_u ptp_rx_filt_ipv6_da6_reg = {0}; + union ptp_rx_filt_ipv6_da7_reg_u ptp_rx_filt_ipv6_da7_reg = {0}; + union ptp_rx_filt_mac_lengthtype_reg_u ptp_rx_filt_mac_lengthtype_reg = {0}; + union ptp_rx_filt_layer4_protocol_reg_u ptp_rx_filt_layer4_protocol_reg = {0}; + union ptp_rx_filt_udp_port_reg_u ptp_rx_filt_udp_port_reg = {0}; + union ptp_rx_com_ts_status_reg_u ptp_rx_com_ts_status_reg = {0}; + union ptp_rx_com_ts_status_pre_reg_u ptp_rx_com_ts_status_pre_reg = {0}; + union ptp_rx_y1731_identify_reg_u ptp_rx_y1731_identify_reg = {0}; + union ptp_rx_y1731_identify_pre_reg_u ptp_rx_y1731_identify_pre_reg = {0}; + + union ptp_loc_mac_addr_0_reg_u ptp_loc_mac_addr_0_reg = {0}; + union ptp_loc_mac_addr_1_reg_u ptp_loc_mac_addr_1_reg = {0}; + union ptp_loc_mac_addr_2_reg_u ptp_loc_mac_addr_2_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_rx_com_ts_ctrl_reg_get(dev_id, + phy_id, &ctrl_reg)); + ts_engine->filt_en = ctrl_reg.bf.filt_en; + ts_engine->enhance_ts_conf_bmp = ctrl_reg.bf.mac_lengthtype_en | + (ctrl_reg.bf.mac_da_en << (PTP_RX_COM_TS_CTRL_REG_MAC_DA_EN_OFFSET-1)) | + (ctrl_reg.bf.mac_ptp_filt_en << (PTP_RX_COM_TS_CTRL_REG_MAC_PTP_FILT_EN_OFFSET-1)) | + (ctrl_reg.bf. + ipv4_layer4_protocol_en << (PTP_RX_COM_TS_CTRL_REG_IPV4_LAYER4_PROTOCOL_EN_OFFSET-1)) | + (ctrl_reg.bf.ipv4_da_en << (PTP_RX_COM_TS_CTRL_REG_IPV4_DA_EN_OFFSET-1)) | + (ctrl_reg.bf.ipv4_ptp_filt_en << (PTP_RX_COM_TS_CTRL_REG_IPV4_PTP_FILT_EN_OFFSET-1)) | + (ctrl_reg.bf.ipv6_next_header_en << (PTP_RX_COM_TS_CTRL_REG_IPV6_NEXT_HEADER_EN_OFFSET-1)) | + (ctrl_reg.bf.ipv6_da_filt_en << (PTP_RX_COM_TS_CTRL_REG_IPV6_DA_FILT_EN_OFFSET-1)) | + (ctrl_reg.bf.ipv6_ptp_filt_en << (PTP_RX_COM_TS_CTRL_REG_IPV6_PTP_FILT_EN_OFFSET-1)) | + (ctrl_reg.bf.udp_dport_en << (PTP_RX_COM_TS_CTRL_REG_UDP_DPORT_EN_OFFSET-1)) | + (ctrl_reg.bf. + udp_ptp_event_filt_en << (PTP_RX_COM_TS_CTRL_REG_UDP_PTP_EVENT_FILT_EN_OFFSET-1)) | + (ctrl_reg.bf.y1731_en << (PTP_RX_COM_TS_CTRL_REG_Y1731_EN_OFFSET-1)) | + (ctrl_reg.bf.y1731_insert_ts_en << (PTP_RX_COM_TS_CTRL_REG_Y1731_INSERT_TS_EN_OFFSET-1)) | + (ctrl_reg.bf.y1731_da_chk_en << (PTP_RX_COM_TS_CTRL_REG_Y1731_DA_CHK_EN_OFFSET-1)); + + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_mac_lengthtype_reg_get(dev_id, + phy_id, &ptp_rx_filt_mac_lengthtype_reg)); + ts_engine->eth_type = ptp_rx_filt_mac_lengthtype_reg.bf.length_type; + + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_mac_da0_reg_get(dev_id, + phy_id, &ptp_rx_filt_mac_da0_reg)); + ts_engine->dmac_addr.uc[0] = ptp_rx_filt_mac_da0_reg.bf.mac_addr >> 8; + ts_engine->dmac_addr.uc[1] = ptp_rx_filt_mac_da0_reg.bf.mac_addr & 0xff; + + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_mac_da1_reg_get(dev_id, + phy_id, &ptp_rx_filt_mac_da1_reg)); + ts_engine->dmac_addr.uc[2] = ptp_rx_filt_mac_da1_reg.bf.mac_addr >> 8; + ts_engine->dmac_addr.uc[3] = ptp_rx_filt_mac_da1_reg.bf.mac_addr & 0xff; + + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_mac_da2_reg_get(dev_id, + phy_id, &ptp_rx_filt_mac_da2_reg)); + ts_engine->dmac_addr.uc[4] = ptp_rx_filt_mac_da2_reg.bf.mac_addr >> 8; + ts_engine->dmac_addr.uc[5] = ptp_rx_filt_mac_da2_reg.bf.mac_addr & 0xff; + + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_layer4_protocol_reg_get(dev_id, + phy_id, &ptp_rx_filt_layer4_protocol_reg)); + ts_engine->ipv4_l4_proto = ptp_rx_filt_layer4_protocol_reg.bf.l4_protocol; + + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_ipv4_da0_reg_get(dev_id, + phy_id, &ptp_rx_filt_ipv4_da0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_ipv4_da1_reg_get(dev_id, + phy_id, &ptp_rx_filt_ipv4_da1_reg)); + ts_engine->ipv4_dip = (ptp_rx_filt_ipv4_da0_reg.bf.ip_addr << 16) | + ptp_rx_filt_ipv4_da1_reg.bf.ip_addr; + + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_ipv6_da0_reg_get(dev_id, + phy_id, &ptp_rx_filt_ipv6_da0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_ipv6_da1_reg_get(dev_id, + phy_id, &ptp_rx_filt_ipv6_da1_reg)); + ts_engine->ipv6_dip.ul[0] = (ptp_rx_filt_ipv6_da0_reg.bf.ip_addr << 16) | + ptp_rx_filt_ipv6_da1_reg.bf.ip_addr; + + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_ipv6_da2_reg_get(dev_id, + phy_id, &ptp_rx_filt_ipv6_da2_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_ipv6_da3_reg_get(dev_id, + phy_id, &ptp_rx_filt_ipv6_da3_reg)); + ts_engine->ipv6_dip.ul[1] = (ptp_rx_filt_ipv6_da2_reg.bf.ip_addr << 16) | + ptp_rx_filt_ipv6_da3_reg.bf.ip_addr; + + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_ipv6_da4_reg_get(dev_id, + phy_id, &ptp_rx_filt_ipv6_da4_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_ipv6_da5_reg_get(dev_id, + phy_id, &ptp_rx_filt_ipv6_da5_reg)); + ts_engine->ipv6_dip.ul[2] = (ptp_rx_filt_ipv6_da4_reg.bf.ip_addr << 16) | + ptp_rx_filt_ipv6_da5_reg.bf.ip_addr; + + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_ipv6_da6_reg_get(dev_id, + phy_id, &ptp_rx_filt_ipv6_da6_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_ipv6_da7_reg_get(dev_id, + phy_id, &ptp_rx_filt_ipv6_da7_reg)); + ts_engine->ipv6_dip.ul[3] = (ptp_rx_filt_ipv6_da6_reg.bf.ip_addr << 16) | + ptp_rx_filt_ipv6_da7_reg.bf.ip_addr; + + SW_RTN_ON_ERROR(qca808x_ptp_rx_filt_udp_port_reg_get(dev_id, + phy_id, &ptp_rx_filt_udp_port_reg)); + ts_engine->udp_dport = ptp_rx_filt_udp_port_reg.bf.udp_port; + + SW_RTN_ON_ERROR(qca808x_ptp_loc_mac_addr_0_reg_get(dev_id, + phy_id, &ptp_loc_mac_addr_0_reg)); + ts_engine->y1731_mac_addr.uc[0] = ptp_loc_mac_addr_0_reg.bf.mac_addr >> 8; + ts_engine->y1731_mac_addr.uc[1] = ptp_loc_mac_addr_0_reg.bf.mac_addr & 0xff; + + SW_RTN_ON_ERROR(qca808x_ptp_loc_mac_addr_1_reg_get(dev_id, + phy_id, &ptp_loc_mac_addr_1_reg)); + ts_engine->y1731_mac_addr.uc[2] = ptp_loc_mac_addr_1_reg.bf.mac_addr >> 8; + ts_engine->y1731_mac_addr.uc[3] = ptp_loc_mac_addr_1_reg.bf.mac_addr & 0xff; + + SW_RTN_ON_ERROR(qca808x_ptp_loc_mac_addr_2_reg_get(dev_id, + phy_id, &ptp_loc_mac_addr_2_reg)); + ts_engine->y1731_mac_addr.uc[4] = ptp_loc_mac_addr_2_reg.bf.mac_addr >> 8; + ts_engine->y1731_mac_addr.uc[5] = ptp_loc_mac_addr_2_reg.bf.mac_addr & 0xff; + + SW_RTN_ON_ERROR(qca808x_ptp_rx_com_ts_status_reg_get(dev_id, + phy_id, &ptp_rx_com_ts_status_reg)); + ts_engine->enhance_ts_status_bmp = ptp_rx_com_ts_status_reg.bf.mac_lengthtype | + (ptp_rx_com_ts_status_reg.bf.mac_da << + PTP_RX_COM_TS_STATUS_REG_MAC_DA_OFFSET) | + (ptp_rx_com_ts_status_reg.bf.mac_ptp_prim_addr << + PTP_RX_COM_TS_STATUS_REG_MAC_PTP_PRIM_ADDR_OFFSET) | + (ptp_rx_com_ts_status_reg.bf.mac_ptp_pdelay_addr << + PTP_RX_COM_TS_STATUS_REG_MAC_PTP_PDELAY_ADDR_OFFSET) | + (ptp_rx_com_ts_status_reg.bf.ipv4_layer4_protocol << + PTP_RX_COM_TS_STATUS_REG_IPV4_LAYER4_PROTOCOL_OFFSET) | + (ptp_rx_com_ts_status_reg.bf.ipv4_da << + PTP_RX_COM_TS_STATUS_REG_IPV4_DA_OFFSET) | + (ptp_rx_com_ts_status_reg.bf.ipv4_ptp_prim_addr << + PTP_RX_COM_TS_STATUS_REG_IPV4_PTP_PRIM_ADDR_OFFSET) | + (ptp_rx_com_ts_status_reg.bf.ipv4_ptp_pdelay_addr << + PTP_RX_COM_TS_STATUS_REG_IPV4_PTP_PDELAY_ADDR_OFFSET) | + (ptp_rx_com_ts_status_reg.bf.ipv6_next_header << + PTP_RX_COM_TS_STATUS_REG_IPV6_NEXT_HEADER_OFFSET) | + (ptp_rx_com_ts_status_reg.bf.ipv6_da << + PTP_RX_COM_TS_STATUS_REG_IPV6_DA_OFFSET) | + (ptp_rx_com_ts_status_reg.bf.ipv6_ptp_prim_addr << + PTP_RX_COM_TS_STATUS_REG_IPV6_PTP_PRIM_ADDR_OFFSET) | + (ptp_rx_com_ts_status_reg.bf.ipv6_ptp_pdelay_addr << + PTP_RX_COM_TS_STATUS_REG_IPV6_PTP_PDELAY_ADDR_OFFSET) | + (ptp_rx_com_ts_status_reg.bf.udp_dport << + PTP_RX_COM_TS_STATUS_REG_UDP_DPORT_OFFSET) | + (ptp_rx_com_ts_status_reg.bf.udp_ptp_event_dport << + PTP_RX_COM_TS_STATUS_REG_UDP_PTP_EVENT_DPORT_OFFSET) | + (ptp_rx_com_ts_status_reg.bf.y1731_mach << + PTP_RX_COM_TS_STATUS_REG_Y1731_MACH_OFFSET); + + SW_RTN_ON_ERROR(qca808x_ptp_rx_com_ts_status_pre_reg_get(dev_id, + phy_id, &ptp_rx_com_ts_status_pre_reg)); + ts_engine->enhance_ts_status_pre_bmp = ptp_rx_com_ts_status_pre_reg.bf.mac_lengthtype | + (ptp_rx_com_ts_status_pre_reg.bf.mac_da << + PTP_RX_COM_TS_STATUS_REG_MAC_DA_OFFSET) | + (ptp_rx_com_ts_status_pre_reg.bf.mac_ptp_prim_addr << + PTP_RX_COM_TS_STATUS_REG_MAC_PTP_PRIM_ADDR_OFFSET) | + (ptp_rx_com_ts_status_pre_reg.bf.mac_ptp_pdelay_addr << + PTP_RX_COM_TS_STATUS_REG_MAC_PTP_PDELAY_ADDR_OFFSET) | + (ptp_rx_com_ts_status_pre_reg.bf.ipv4_layer4_protocol << + PTP_RX_COM_TS_STATUS_REG_IPV4_LAYER4_PROTOCOL_OFFSET) | + (ptp_rx_com_ts_status_pre_reg.bf.ipv4_da << + PTP_RX_COM_TS_STATUS_REG_IPV4_DA_OFFSET) | + (ptp_rx_com_ts_status_pre_reg.bf.ipv4_ptp_prim_addr << + PTP_RX_COM_TS_STATUS_REG_IPV4_PTP_PRIM_ADDR_OFFSET) | + (ptp_rx_com_ts_status_pre_reg.bf.ipv4_ptp_pdelay_addr << + PTP_RX_COM_TS_STATUS_REG_IPV4_PTP_PDELAY_ADDR_OFFSET) | + (ptp_rx_com_ts_status_pre_reg.bf.ipv6_next_header << + PTP_RX_COM_TS_STATUS_REG_IPV6_NEXT_HEADER_OFFSET) | + (ptp_rx_com_ts_status_pre_reg.bf.ipv6_da << + PTP_RX_COM_TS_STATUS_REG_IPV6_DA_OFFSET) | + (ptp_rx_com_ts_status_pre_reg.bf.ipv6_ptp_prim_addr << + PTP_RX_COM_TS_STATUS_REG_IPV6_PTP_PRIM_ADDR_OFFSET) | + (ptp_rx_com_ts_status_pre_reg.bf.ipv6_ptp_pdelay_addr << + PTP_RX_COM_TS_STATUS_REG_IPV6_PTP_PDELAY_ADDR_OFFSET) | + (ptp_rx_com_ts_status_pre_reg.bf.udp_dport << + PTP_RX_COM_TS_STATUS_REG_UDP_DPORT_OFFSET) | + (ptp_rx_com_ts_status_pre_reg.bf.udp_ptp_event_dport << + PTP_RX_COM_TS_STATUS_REG_UDP_PTP_EVENT_DPORT_OFFSET) | + (ptp_rx_com_ts_status_pre_reg.bf.y1731_mach << + PTP_RX_COM_TS_STATUS_REG_Y1731_MACH_OFFSET); + + SW_RTN_ON_ERROR(qca808x_ptp_rx_y1731_identify_reg_get(dev_id, + phy_id, &ptp_rx_y1731_identify_reg)); + ts_engine->y1731_identity = ptp_rx_y1731_identify_reg.bf.identify; + + SW_RTN_ON_ERROR(qca808x_ptp_rx_y1731_identify_pre_reg_get(dev_id, + phy_id, &ptp_rx_y1731_identify_pre_reg)); + ts_engine->y1731_identity_pre = ptp_rx_y1731_identify_pre_reg.bf.identify_pre; + + ret = _qca808x_phy_ptp_enhanced_timestamp_engine_rx_com_ts_get(dev_id, phy_id, + ts_engine); + if (ret != SW_OK) + { + return ret; + } + + ret = _qca808x_phy_ptp_enhanced_timestamp_engine_rx_com_ts_pre_get(dev_id, phy_id, + ts_engine); + + return ret; +} + +sw_error_t +_qca808x_phy_ptp_enhanced_timestamp_engine_tx_get(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_enhanced_ts_engine_t *ts_engine) +{ + union ptp_tx_com_ts_ctrl_reg_u ctrl_reg = {0}; + union ptp_tx_filt_mac_da0_reg_u ptp_tx_filt_mac_da0_reg = {0}; + union ptp_tx_filt_mac_da1_reg_u ptp_tx_filt_mac_da1_reg = {0}; + union ptp_tx_filt_mac_da2_reg_u ptp_tx_filt_mac_da2_reg = {0}; + union ptp_tx_filt_ipv4_da0_reg_u ptp_tx_filt_ipv4_da0_reg = {0}; + union ptp_tx_filt_ipv4_da1_reg_u ptp_tx_filt_ipv4_da1_reg = {0}; + union ptp_tx_filt_ipv6_da0_reg_u ptp_tx_filt_ipv6_da0_reg = {0}; + union ptp_tx_filt_ipv6_da1_reg_u ptp_tx_filt_ipv6_da1_reg = {0}; + union ptp_tx_filt_ipv6_da2_reg_u ptp_tx_filt_ipv6_da2_reg = {0}; + union ptp_tx_filt_ipv6_da3_reg_u ptp_tx_filt_ipv6_da3_reg = {0}; + union ptp_tx_filt_ipv6_da4_reg_u ptp_tx_filt_ipv6_da4_reg = {0}; + union ptp_tx_filt_ipv6_da5_reg_u ptp_tx_filt_ipv6_da5_reg = {0}; + union ptp_tx_filt_ipv6_da6_reg_u ptp_tx_filt_ipv6_da6_reg = {0}; + union ptp_tx_filt_ipv6_da7_reg_u ptp_tx_filt_ipv6_da7_reg = {0}; + union ptp_tx_filt_mac_lengthtype_reg_u ptp_tx_filt_mac_lengthtype_reg = {0}; + union ptp_tx_filt_layer4_protocol_reg_u ptp_tx_filt_layer4_protocol_reg = {0}; + union ptp_tx_filt_udp_port_reg_u ptp_tx_filt_udp_port_reg = {0}; + union ptp_tx_com_ts_status_reg_u ptp_tx_com_ts_status_reg = {0}; + union ptp_tx_com_timestamp0_reg_u ptp_tx_com_timestamp0_reg = {0}; + union ptp_tx_com_timestamp1_reg_u ptp_tx_com_timestamp1_reg = {0}; + union ptp_tx_com_timestamp2_reg_u ptp_tx_com_timestamp2_reg = {0}; + union ptp_tx_com_timestamp3_reg_u ptp_tx_com_timestamp3_reg = {0}; + union ptp_tx_com_timestamp4_reg_u ptp_tx_com_timestamp4_reg = {0}; + union ptp_tx_com_frac_nano_reg_u ptp_tx_com_frac_nano_reg = {0}; + union ptp_tx_y1731_identify_reg_u ptp_tx_y1731_identify_reg = {0}; + + union ptp_loc_mac_addr_0_reg_u ptp_loc_mac_addr_0_reg = {0}; + union ptp_loc_mac_addr_1_reg_u ptp_loc_mac_addr_1_reg = {0}; + union ptp_loc_mac_addr_2_reg_u ptp_loc_mac_addr_2_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_tx_com_ts_ctrl_reg_get(dev_id, + phy_id, &ctrl_reg)); + ts_engine->filt_en = ctrl_reg.bf.filt_en; + ts_engine->enhance_ts_conf_bmp = ctrl_reg.bf.mac_lengthtype_en | + (ctrl_reg.bf.mac_da_en << (PTP_TX_COM_TS_CTRL_REG_MAC_DA_EN_OFFSET-1)) | + (ctrl_reg.bf.mac_ptp_filt_en << (PTP_TX_COM_TS_CTRL_REG_MAC_PTP_FILT_EN_OFFSET-1)) | + (ctrl_reg.bf. + ipv4_layer4_protocol_en << (PTP_TX_COM_TS_CTRL_REG_IPV4_LAYER4_PROTOCOL_EN_OFFSET-1)) | + (ctrl_reg.bf.ipv4_da_en << (PTP_TX_COM_TS_CTRL_REG_IPV4_DA_EN_OFFSET-1)) | + (ctrl_reg.bf.ipv4_ptp_filt_en << (PTP_TX_COM_TS_CTRL_REG_IPV4_PTP_FILT_EN_OFFSET-1)) | + (ctrl_reg.bf.ipv6_next_header_en << (PTP_TX_COM_TS_CTRL_REG_IPV6_NEXT_HEADER_EN_OFFSET-1)) | + (ctrl_reg.bf.ipv6_da_en << (PTP_TX_COM_TS_CTRL_REG_IPV6_DA_EN_OFFSET-1)) | + (ctrl_reg.bf.ipv6_ptp_filt_en << (PTP_TX_COM_TS_CTRL_REG_IPV6_PTP_FILT_EN_OFFSET-1)) | + (ctrl_reg.bf.udp_dport_en << (PTP_TX_COM_TS_CTRL_REG_UDP_DPORT_EN_OFFSET-1)) | + (ctrl_reg.bf. + udp_ptp_event_filt_en << (PTP_TX_COM_TS_CTRL_REG_UDP_PTP_EVENT_FILT_EN_OFFSET-1)) | + (ctrl_reg.bf.y1731_en << (PTP_TX_COM_TS_CTRL_REG_Y1731_EN_OFFSET-1)) | + (ctrl_reg.bf.y1731_insert_ts_en << (PTP_TX_COM_TS_CTRL_REG_Y1731_INSERT_TS_EN_OFFSET-1)) | + (ctrl_reg.bf.y1731_sa_chk_en << (PTP_TX_COM_TS_CTRL_REG_Y1731_SA_CHK_EN_OFFSET-1)); + + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_mac_lengthtype_reg_get(dev_id, + phy_id, &ptp_tx_filt_mac_lengthtype_reg)); + ts_engine->eth_type = ptp_tx_filt_mac_lengthtype_reg.bf.length_type; + + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_mac_da0_reg_get(dev_id, + phy_id, &ptp_tx_filt_mac_da0_reg)); + ts_engine->dmac_addr.uc[0] = ptp_tx_filt_mac_da0_reg.bf.mac_addr >> 8; + ts_engine->dmac_addr.uc[1] = ptp_tx_filt_mac_da0_reg.bf.mac_addr & 0xff; + + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_mac_da1_reg_get(dev_id, + phy_id, &ptp_tx_filt_mac_da1_reg)); + ts_engine->dmac_addr.uc[2] = ptp_tx_filt_mac_da1_reg.bf.mac_addr >> 8; + ts_engine->dmac_addr.uc[3] = ptp_tx_filt_mac_da1_reg.bf.mac_addr & 0xff; + + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_mac_da2_reg_get(dev_id, + phy_id, &ptp_tx_filt_mac_da2_reg)); + ts_engine->dmac_addr.uc[4] = ptp_tx_filt_mac_da2_reg.bf.mac_addr >> 8; + ts_engine->dmac_addr.uc[5] = ptp_tx_filt_mac_da2_reg.bf.mac_addr & 0xff; + + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_layer4_protocol_reg_get(dev_id, + phy_id, &ptp_tx_filt_layer4_protocol_reg)); + ts_engine->ipv4_l4_proto = ptp_tx_filt_layer4_protocol_reg.bf.l4_protocol; + + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_ipv4_da0_reg_get(dev_id, + phy_id, &ptp_tx_filt_ipv4_da0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_ipv4_da1_reg_get(dev_id, + phy_id, &ptp_tx_filt_ipv4_da1_reg)); + ts_engine->ipv4_dip = (ptp_tx_filt_ipv4_da0_reg.bf.ip_addr << 16) | + ptp_tx_filt_ipv4_da1_reg.bf.ip_addr; + + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_ipv6_da0_reg_get(dev_id, + phy_id, &ptp_tx_filt_ipv6_da0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_ipv6_da1_reg_get(dev_id, + phy_id, &ptp_tx_filt_ipv6_da1_reg)); + ts_engine->ipv6_dip.ul[0] = (ptp_tx_filt_ipv6_da0_reg.bf.ip_addr << 16) | + ptp_tx_filt_ipv6_da1_reg.bf.ip_addr; + + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_ipv6_da2_reg_get(dev_id, + phy_id, &ptp_tx_filt_ipv6_da2_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_ipv6_da3_reg_get(dev_id, + phy_id, &ptp_tx_filt_ipv6_da3_reg)); + ts_engine->ipv6_dip.ul[1] = (ptp_tx_filt_ipv6_da2_reg.bf.ip_addr << 16) | + ptp_tx_filt_ipv6_da3_reg.bf.ip_addr; + + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_ipv6_da4_reg_get(dev_id, + phy_id, &ptp_tx_filt_ipv6_da4_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_ipv6_da5_reg_get(dev_id, + phy_id, &ptp_tx_filt_ipv6_da5_reg)); + ts_engine->ipv6_dip.ul[2] = (ptp_tx_filt_ipv6_da4_reg.bf.ip_addr << 16) | + ptp_tx_filt_ipv6_da5_reg.bf.ip_addr; + + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_ipv6_da6_reg_get(dev_id, + phy_id, &ptp_tx_filt_ipv6_da6_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_ipv6_da7_reg_get(dev_id, + phy_id, &ptp_tx_filt_ipv6_da7_reg)); + ts_engine->ipv6_dip.ul[3] = (ptp_tx_filt_ipv6_da6_reg.bf.ip_addr << 16) | + ptp_tx_filt_ipv6_da7_reg.bf.ip_addr; + + SW_RTN_ON_ERROR(qca808x_ptp_tx_filt_udp_port_reg_get(dev_id, + phy_id, &ptp_tx_filt_udp_port_reg)); + ts_engine->udp_dport = ptp_tx_filt_udp_port_reg.bf.udp_port; + + SW_RTN_ON_ERROR(qca808x_ptp_loc_mac_addr_0_reg_get(dev_id, + phy_id, &ptp_loc_mac_addr_0_reg)); + ts_engine->y1731_mac_addr.uc[0] = ptp_loc_mac_addr_0_reg.bf.mac_addr >> 8; + ts_engine->y1731_mac_addr.uc[1] = ptp_loc_mac_addr_0_reg.bf.mac_addr & 0xff; + + SW_RTN_ON_ERROR(qca808x_ptp_loc_mac_addr_1_reg_get(dev_id, + phy_id, &ptp_loc_mac_addr_1_reg)); + ts_engine->y1731_mac_addr.uc[2] = ptp_loc_mac_addr_1_reg.bf.mac_addr >> 8; + ts_engine->y1731_mac_addr.uc[3] = ptp_loc_mac_addr_1_reg.bf.mac_addr & 0xff; + + SW_RTN_ON_ERROR(qca808x_ptp_loc_mac_addr_2_reg_get(dev_id, + phy_id, &ptp_loc_mac_addr_2_reg)); + ts_engine->y1731_mac_addr.uc[4] = ptp_loc_mac_addr_2_reg.bf.mac_addr >> 8; + ts_engine->y1731_mac_addr.uc[5] = ptp_loc_mac_addr_2_reg.bf.mac_addr & 0xff; + + SW_RTN_ON_ERROR(qca808x_ptp_tx_com_ts_status_reg_get(dev_id, + phy_id, &ptp_tx_com_ts_status_reg)); + ts_engine->enhance_ts_status_bmp = ptp_tx_com_ts_status_reg.bf.mac_lengthtype | + (ptp_tx_com_ts_status_reg.bf.mac_da << + PTP_TX_COM_TS_STATUS_REG_MAC_DA_OFFSET) | + (ptp_tx_com_ts_status_reg.bf.mac_ptp_prim_addr << + PTP_TX_COM_TS_STATUS_REG_MAC_PTP_PRIM_ADDR_OFFSET) | + (ptp_tx_com_ts_status_reg.bf.mac_ptp_pdelay_addr << + PTP_TX_COM_TS_STATUS_REG_MAC_PTP_PDELAY_ADDR_OFFSET) | + (ptp_tx_com_ts_status_reg.bf.ipv4_layer4_protocol << + PTP_TX_COM_TS_STATUS_REG_IPV4_LAYER4_PROTOCOL_OFFSET) | + (ptp_tx_com_ts_status_reg.bf.ipv4_da << + PTP_TX_COM_TS_STATUS_REG_IPV4_DA_OFFSET) | + (ptp_tx_com_ts_status_reg.bf.ipv4_ptp_prim_addr << + PTP_TX_COM_TS_STATUS_REG_IPV4_PTP_PRIM_ADDR_OFFSET) | + (ptp_tx_com_ts_status_reg.bf.ipv4_ptp_pdelay_addr << + PTP_TX_COM_TS_STATUS_REG_IPV4_PTP_PDELAY_ADDR_OFFSET) | + (ptp_tx_com_ts_status_reg.bf.ipv6_next_header << + PTP_TX_COM_TS_STATUS_REG_IPV6_NEXT_HEADER_OFFSET) | + (ptp_tx_com_ts_status_reg.bf.ipv6_da << + PTP_TX_COM_TS_STATUS_REG_IPV6_DA_OFFSET) | + (ptp_tx_com_ts_status_reg.bf.ipv6_ptp_prim_addr << + PTP_TX_COM_TS_STATUS_REG_IPV6_PTP_PRIM_ADDR_OFFSET) | + (ptp_tx_com_ts_status_reg.bf.ipv6_ptp_pdelay_addr << + PTP_TX_COM_TS_STATUS_REG_IPV6_PTP_PDELAY_ADDR_OFFSET) | + (ptp_tx_com_ts_status_reg.bf.udp_dport << + PTP_TX_COM_TS_STATUS_REG_UDP_DPORT_OFFSET) | + (ptp_tx_com_ts_status_reg.bf.udp_ptp_event_dport << + PTP_TX_COM_TS_STATUS_REG_UDP_PTP_EVENT_DPORT_OFFSET) | + (ptp_tx_com_ts_status_reg.bf.y1731_mach << + PTP_TX_COM_TS_STATUS_REG_Y1731_MACH_OFFSET); + + ts_engine->enhance_ts_status_pre_bmp = 0; + + SW_RTN_ON_ERROR(qca808x_ptp_tx_y1731_identify_reg_get(dev_id, + phy_id, &ptp_tx_y1731_identify_reg)); + ts_engine->y1731_identity = ptp_tx_y1731_identify_reg.bf.identify; + + ts_engine->y1731_identity_pre = 0; + + SW_RTN_ON_ERROR(qca808x_ptp_tx_com_timestamp0_reg_get(dev_id, + phy_id, &ptp_tx_com_timestamp0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_tx_com_timestamp1_reg_get(dev_id, + phy_id, &ptp_tx_com_timestamp1_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_tx_com_timestamp2_reg_get(dev_id, + phy_id, &ptp_tx_com_timestamp2_reg)); + ts_engine->timestamp.seconds = + ((a_int64_t)ptp_tx_com_timestamp0_reg.bf.com_ts << 32) | + (ptp_tx_com_timestamp1_reg.bf.com_ts << 16) | + ptp_tx_com_timestamp2_reg.bf.com_ts; + + SW_RTN_ON_ERROR(qca808x_ptp_tx_com_timestamp3_reg_get(dev_id, + phy_id, &ptp_tx_com_timestamp3_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_tx_com_timestamp4_reg_get(dev_id, + phy_id, &ptp_tx_com_timestamp4_reg)); + ts_engine->timestamp.nanoseconds = (ptp_tx_com_timestamp3_reg.bf.com_ts << 16) | + ptp_tx_com_timestamp4_reg.bf.com_ts; + + SW_RTN_ON_ERROR(qca808x_ptp_tx_com_frac_nano_reg_get(dev_id, + phy_id, &ptp_tx_com_frac_nano_reg)); + ts_engine->timestamp.fracnanoseconds = ptp_tx_com_frac_nano_reg.bf.frac_nano; + + ts_engine->timestamp_pre.seconds = 0; + ts_engine->timestamp_pre.nanoseconds = 0; + ts_engine->timestamp_pre.fracnanoseconds = 0; + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_enhanced_timestamp_engine_get(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_direction_t direction, + fal_ptp_enhanced_ts_engine_t *ts_engine) +{ + if (direction == FAL_RX_DIRECTION) + { + return _qca808x_phy_ptp_enhanced_timestamp_engine_rx_get(dev_id, + phy_id, ts_engine); + } + else + { + return _qca808x_phy_ptp_enhanced_timestamp_engine_tx_get(dev_id, + phy_id, ts_engine); + } + + return SW_BAD_PARAM; +} + +sw_error_t +qca808x_phy_ptp_trigger_set(a_uint32_t dev_id, + a_uint32_t phy_id, a_uint32_t trigger_id, + fal_ptp_trigger_t *triger) +{ + union ptp_trigger0_config_reg_u ptp_trigger0_config_reg = {0}; + union ptp_trigger1_config_reg_u ptp_trigger1_config_reg = {0}; + union ptp_trigger0_timestamp0_reg_u ptp_trigger0_timestamp0_reg = {0}; + union ptp_trigger0_timestamp1_reg_u ptp_trigger0_timestamp1_reg = {0}; + union ptp_trigger0_timestamp2_reg_u ptp_trigger0_timestamp2_reg = {0}; + union ptp_trigger0_timestamp3_reg_u ptp_trigger0_timestamp3_reg = {0}; + union ptp_trigger0_timestamp4_reg_u ptp_trigger0_timestamp4_reg = {0}; + union ptp_trigger1_timestamp0_reg_u ptp_trigger1_timestamp0_reg = {0}; + union ptp_trigger1_timestamp1_reg_u ptp_trigger1_timestamp1_reg = {0}; + union ptp_trigger1_timestamp2_reg_u ptp_trigger1_timestamp2_reg = {0}; + union ptp_trigger1_timestamp3_reg_u ptp_trigger1_timestamp3_reg = {0}; + union ptp_trigger1_timestamp4_reg_u ptp_trigger1_timestamp4_reg = {0}; + + if (trigger_id == 0) + { + SW_RTN_ON_ERROR(qca808x_ptp_trigger0_config_reg_get(dev_id, + phy_id, &ptp_trigger0_config_reg)); + ptp_trigger0_config_reg.bf.status = triger->trigger_conf.trigger_en; + ptp_trigger0_config_reg.bf.force_en = triger->trigger_conf.output_force_en; + ptp_trigger0_config_reg.bf.force_value = triger->trigger_conf.output_force_value; + ptp_trigger0_config_reg.bf.pattern = triger->trigger_conf.patten_select; + ptp_trigger0_config_reg.bf.if_late = triger->trigger_conf.late_operation; + ptp_trigger0_config_reg.bf.notify = triger->trigger_conf.notify; + ptp_trigger0_config_reg.bf.setting = triger->trigger_conf.trigger_effect; + SW_RTN_ON_ERROR(qca808x_ptp_trigger0_config_reg_set(dev_id, + phy_id, &ptp_trigger0_config_reg)); + + ptp_trigger0_timestamp0_reg.bf.ts_sec = + (triger->trigger_conf.tim.seconds >> 32) & 0xffff; + ptp_trigger0_timestamp1_reg.bf.ts_sec = + (triger->trigger_conf.tim.seconds >> 16) & 0xffff; + ptp_trigger0_timestamp2_reg.bf.ts_sec = + triger->trigger_conf.tim.seconds & 0xffff; + ptp_trigger0_timestamp3_reg.bf.ts_nsec = + triger->trigger_conf.tim.nanoseconds >> 16; + ptp_trigger0_timestamp4_reg.bf.ts_nsec = + triger->trigger_conf.tim.nanoseconds & 0xffff; + SW_RTN_ON_ERROR(qca808x_ptp_trigger0_timestamp0_reg_set(dev_id, + phy_id, &ptp_trigger0_timestamp0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_trigger0_timestamp1_reg_set(dev_id, + phy_id, &ptp_trigger0_timestamp1_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_trigger0_timestamp2_reg_set(dev_id, + phy_id, &ptp_trigger0_timestamp2_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_trigger0_timestamp3_reg_set(dev_id, + phy_id, &ptp_trigger0_timestamp3_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_trigger0_timestamp4_reg_set(dev_id, + phy_id, &ptp_trigger0_timestamp4_reg)); + } else { + SW_RTN_ON_ERROR(qca808x_ptp_trigger1_config_reg_get(dev_id, + phy_id, &ptp_trigger1_config_reg)); + ptp_trigger1_config_reg.bf.status = triger->trigger_conf.trigger_en; + ptp_trigger1_config_reg.bf.force_en = triger->trigger_conf.output_force_en; + ptp_trigger1_config_reg.bf.force_value = triger->trigger_conf.output_force_value; + ptp_trigger1_config_reg.bf.pattern = triger->trigger_conf.patten_select; + ptp_trigger1_config_reg.bf.if_late = triger->trigger_conf.late_operation; + ptp_trigger1_config_reg.bf.notify = triger->trigger_conf.notify; + ptp_trigger1_config_reg.bf.setting = triger->trigger_conf.trigger_effect; + SW_RTN_ON_ERROR(qca808x_ptp_trigger1_config_reg_set(dev_id, + phy_id, &ptp_trigger1_config_reg)); + + ptp_trigger1_timestamp0_reg.bf.ts_sec = + (triger->trigger_conf.tim.seconds >> 32) & 0xffff; + ptp_trigger1_timestamp1_reg.bf.ts_sec = + (triger->trigger_conf.tim.seconds >> 16) & 0xffff; + ptp_trigger1_timestamp2_reg.bf.ts_sec = + triger->trigger_conf.tim.seconds & 0xffff; + ptp_trigger1_timestamp3_reg.bf.ts_nsec = + triger->trigger_conf.tim.nanoseconds >> 16; + ptp_trigger1_timestamp4_reg.bf.ts_nsec = + triger->trigger_conf.tim.nanoseconds & 0xffff; + SW_RTN_ON_ERROR(qca808x_ptp_trigger1_timestamp0_reg_set(dev_id, + phy_id, &ptp_trigger1_timestamp0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_trigger1_timestamp1_reg_set(dev_id, + phy_id, &ptp_trigger1_timestamp1_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_trigger1_timestamp2_reg_set(dev_id, + phy_id, &ptp_trigger1_timestamp2_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_trigger1_timestamp3_reg_set(dev_id, + phy_id, &ptp_trigger1_timestamp3_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_trigger1_timestamp4_reg_set(dev_id, + phy_id, &ptp_trigger1_timestamp4_reg)); + } + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_trigger_get(a_uint32_t dev_id, + a_uint32_t phy_id, a_uint32_t trigger_id, + fal_ptp_trigger_t *triger) +{ + union ptp_trigger0_config_reg_u ptp_trigger0_config_reg = {0}; + union ptp_trigger0_status_reg_u ptp_trigger0_status_reg = {0}; + union ptp_trigger1_config_reg_u ptp_trigger1_config_reg = {0}; + union ptp_trigger1_status_reg_u ptp_trigger1_status_reg = {0}; + union ptp_trigger0_timestamp0_reg_u ptp_trigger0_timestamp0_reg = {0}; + union ptp_trigger0_timestamp1_reg_u ptp_trigger0_timestamp1_reg = {0}; + union ptp_trigger0_timestamp2_reg_u ptp_trigger0_timestamp2_reg = {0}; + union ptp_trigger0_timestamp3_reg_u ptp_trigger0_timestamp3_reg = {0}; + union ptp_trigger0_timestamp4_reg_u ptp_trigger0_timestamp4_reg = {0}; + union ptp_trigger1_timestamp0_reg_u ptp_trigger1_timestamp0_reg = {0}; + union ptp_trigger1_timestamp1_reg_u ptp_trigger1_timestamp1_reg = {0}; + union ptp_trigger1_timestamp2_reg_u ptp_trigger1_timestamp2_reg = {0}; + union ptp_trigger1_timestamp3_reg_u ptp_trigger1_timestamp3_reg = {0}; + union ptp_trigger1_timestamp4_reg_u ptp_trigger1_timestamp4_reg = {0}; + + if (trigger_id == 0) + { + SW_RTN_ON_ERROR(qca808x_ptp_trigger0_config_reg_get(dev_id, + phy_id, &ptp_trigger0_config_reg)); + triger->trigger_conf.trigger_en = ptp_trigger0_config_reg.bf.status; + triger->trigger_conf.output_force_en = ptp_trigger0_config_reg.bf.force_en; + triger->trigger_conf.output_force_value = ptp_trigger0_config_reg.bf.force_value; + triger->trigger_conf.patten_select = ptp_trigger0_config_reg.bf.pattern; + triger->trigger_conf.late_operation = ptp_trigger0_config_reg.bf.if_late; + triger->trigger_conf.notify = ptp_trigger0_config_reg.bf.notify; + triger->trigger_conf.trigger_effect = ptp_trigger0_config_reg.bf.setting; + + SW_RTN_ON_ERROR(qca808x_ptp_trigger0_timestamp0_reg_get(dev_id, + phy_id, &ptp_trigger0_timestamp0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_trigger0_timestamp1_reg_get(dev_id, + phy_id, &ptp_trigger0_timestamp1_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_trigger0_timestamp2_reg_get(dev_id, + phy_id, &ptp_trigger0_timestamp2_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_trigger0_timestamp3_reg_get(dev_id, + phy_id, &ptp_trigger0_timestamp3_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_trigger0_timestamp4_reg_get(dev_id, + phy_id, &ptp_trigger0_timestamp4_reg)); + triger->trigger_conf.tim.seconds = + ((a_int64_t)ptp_trigger0_timestamp0_reg.bf.ts_sec << 32) | + (ptp_trigger0_timestamp1_reg.bf.ts_sec << 16) | + ptp_trigger0_timestamp2_reg.bf.ts_sec; + triger->trigger_conf.tim.nanoseconds = + (ptp_trigger0_timestamp3_reg.bf.ts_nsec << 16) | + ptp_trigger0_timestamp4_reg.bf.ts_nsec; + + SW_RTN_ON_ERROR(qca808x_ptp_trigger0_status_reg_get(dev_id, + phy_id, &ptp_trigger0_status_reg)); + triger->trigger_status.trigger_finished = ptp_trigger0_status_reg.bf.finished; + triger->trigger_status.trigger_active = ptp_trigger0_status_reg.bf.active; + triger->trigger_status.trigger_error = ptp_trigger0_status_reg.bf.error; + } else { + SW_RTN_ON_ERROR(qca808x_ptp_trigger1_config_reg_get(dev_id, + phy_id, &ptp_trigger1_config_reg)); + triger->trigger_conf.trigger_en = ptp_trigger1_config_reg.bf.status; + triger->trigger_conf.output_force_en = ptp_trigger1_config_reg.bf.force_en; + triger->trigger_conf.output_force_value = ptp_trigger1_config_reg.bf.force_value; + triger->trigger_conf.patten_select = ptp_trigger1_config_reg.bf.pattern; + triger->trigger_conf.late_operation = ptp_trigger1_config_reg.bf.if_late; + triger->trigger_conf.notify = ptp_trigger1_config_reg.bf.notify; + triger->trigger_conf.trigger_effect = ptp_trigger1_config_reg.bf.setting; + + SW_RTN_ON_ERROR(qca808x_ptp_trigger1_timestamp0_reg_get(dev_id, + phy_id, &ptp_trigger1_timestamp0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_trigger1_timestamp1_reg_get(dev_id, + phy_id, &ptp_trigger1_timestamp1_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_trigger1_timestamp2_reg_get(dev_id, + phy_id, &ptp_trigger1_timestamp2_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_trigger1_timestamp3_reg_get(dev_id, + phy_id, &ptp_trigger1_timestamp3_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_trigger1_timestamp4_reg_get(dev_id, + phy_id, &ptp_trigger1_timestamp4_reg)); + triger->trigger_conf.tim.seconds = + ((a_int64_t)ptp_trigger1_timestamp0_reg.bf.ts_sec << 32) | + (ptp_trigger1_timestamp1_reg.bf.ts_sec << 16) | + ptp_trigger1_timestamp2_reg.bf.ts_sec; + triger->trigger_conf.tim.nanoseconds = + (ptp_trigger1_timestamp3_reg.bf.ts_nsec << 16) | + ptp_trigger1_timestamp4_reg.bf.ts_nsec; + + SW_RTN_ON_ERROR(qca808x_ptp_trigger1_status_reg_get(dev_id, + phy_id, &ptp_trigger1_status_reg)); + triger->trigger_status.trigger_finished = ptp_trigger1_status_reg.bf.finished; + triger->trigger_status.trigger_active = ptp_trigger1_status_reg.bf.active; + triger->trigger_status.trigger_error = ptp_trigger1_status_reg.bf.error; + } + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_capture_set(a_uint32_t dev_id, + a_uint32_t phy_id, a_uint32_t capture_id, + fal_ptp_capture_t *capture) +{ + union ptp_event0_config_reg_u ptp_event0_config_reg = {0}; + union ptp_event1_config_reg_u ptp_event1_config_reg = {0}; + + if (capture_id == 0) + { + SW_RTN_ON_ERROR(qca808x_ptp_event0_config_reg_get(dev_id, + phy_id, &ptp_event0_config_reg)); + ptp_event0_config_reg.bf.clear_stat = capture->capture_conf.status_clear; + ptp_event0_config_reg.bf.notify = capture->capture_conf.notify_event; + ptp_event0_config_reg.bf.single_cap = capture->capture_conf.single_multi_select; + ptp_event0_config_reg.bf.fall_en = capture->capture_conf.fall_edge_en; + ptp_event0_config_reg.bf.rise_en = capture->capture_conf.rise_edge_en; + SW_RTN_ON_ERROR(qca808x_ptp_event0_config_reg_set(dev_id, + phy_id, &ptp_event0_config_reg)); + } + else + { + SW_RTN_ON_ERROR(qca808x_ptp_event1_config_reg_get(dev_id, + phy_id, &ptp_event1_config_reg)); + ptp_event1_config_reg.bf.clear_stat = capture->capture_conf.status_clear; + ptp_event1_config_reg.bf.notify = capture->capture_conf.notify_event; + ptp_event1_config_reg.bf.single_cap = capture->capture_conf.single_multi_select; + ptp_event1_config_reg.bf.fall_en = capture->capture_conf.fall_edge_en; + ptp_event1_config_reg.bf.rise_en = capture->capture_conf.rise_edge_en; + SW_RTN_ON_ERROR(qca808x_ptp_event1_config_reg_set(dev_id, + phy_id, &ptp_event1_config_reg)); + } + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_capture_get(a_uint32_t dev_id, + a_uint32_t phy_id, a_uint32_t capture_id, + fal_ptp_capture_t *capture) +{ + union ptp_event0_config_reg_u ptp_event0_config_reg = {0}; + union ptp_event0_status_reg_u ptp_event0_status_reg = {0}; + union ptp_event1_config_reg_u ptp_event1_config_reg = {0}; + union ptp_event1_status_reg_u ptp_event1_status_reg = {0}; + union ptp_event0_timestamp0_reg_u ptp_event0_timestamp0_reg = {0}; + union ptp_event0_timestamp1_reg_u ptp_event0_timestamp1_reg = {0}; + union ptp_event0_timestamp2_reg_u ptp_event0_timestamp2_reg = {0}; + union ptp_event0_timestamp3_reg_u ptp_event0_timestamp3_reg = {0}; + union ptp_event0_timestamp4_reg_u ptp_event0_timestamp4_reg = {0}; + union ptp_event1_timestamp0_reg_u ptp_event1_timestamp0_reg = {0}; + union ptp_event1_timestamp1_reg_u ptp_event1_timestamp1_reg = {0}; + union ptp_event1_timestamp2_reg_u ptp_event1_timestamp2_reg = {0}; + union ptp_event1_timestamp3_reg_u ptp_event1_timestamp3_reg = {0}; + union ptp_event1_timestamp4_reg_u ptp_event1_timestamp4_reg = {0}; + + if (capture_id == 0) + { + SW_RTN_ON_ERROR(qca808x_ptp_event0_config_reg_get(dev_id, + phy_id, &ptp_event0_config_reg)); + capture->capture_conf.status_clear = ptp_event0_config_reg.bf.clear_stat; + capture->capture_conf.notify_event = ptp_event0_config_reg.bf.notify; + capture->capture_conf.single_multi_select = ptp_event0_config_reg.bf.single_cap; + capture->capture_conf.fall_edge_en = ptp_event0_config_reg.bf.fall_en; + capture->capture_conf.rise_edge_en = ptp_event0_config_reg.bf.rise_en; + + SW_RTN_ON_ERROR(qca808x_ptp_event0_status_reg_get(dev_id, + phy_id, &ptp_event0_status_reg)); + capture->capture_status.event_detected = ptp_event0_status_reg.bf.detected; + capture->capture_status.fall_rise_edge_detected = + ptp_event0_status_reg.bf.dir_detected; + capture->capture_status.single_multi_detected = ptp_event0_status_reg.bf.mul_event; + capture->capture_status.event_missed_cnt = ptp_event0_status_reg.bf.missed_count; + + SW_RTN_ON_ERROR(qca808x_ptp_event0_timestamp0_reg_get(dev_id, + phy_id, &ptp_event0_timestamp0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_event0_timestamp1_reg_get(dev_id, + phy_id, &ptp_event0_timestamp1_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_event0_timestamp2_reg_get(dev_id, + phy_id, &ptp_event0_timestamp2_reg)); + capture->capture_status.tim.seconds = + ((a_int64_t)ptp_event0_timestamp0_reg.bf.ts_nsec << 32) | + (ptp_event0_timestamp1_reg.bf.ts_nsec << 16) | + ptp_event0_timestamp2_reg.bf.ts_nsec; + SW_RTN_ON_ERROR(qca808x_ptp_event0_timestamp3_reg_get(dev_id, + phy_id, &ptp_event0_timestamp3_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_event0_timestamp4_reg_get(dev_id, + phy_id, &ptp_event0_timestamp4_reg)); + capture->capture_status.tim.nanoseconds = + (ptp_event0_timestamp3_reg.bf.ts_nsec << 16) | + ptp_event0_timestamp4_reg.bf.ts_nsec; + } else { + SW_RTN_ON_ERROR(qca808x_ptp_event1_config_reg_get(dev_id, + phy_id, &ptp_event1_config_reg)); + capture->capture_conf.status_clear = ptp_event1_config_reg.bf.clear_stat; + capture->capture_conf.notify_event = ptp_event1_config_reg.bf.notify; + capture->capture_conf.single_multi_select = ptp_event1_config_reg.bf.single_cap; + capture->capture_conf.fall_edge_en = ptp_event1_config_reg.bf.fall_en; + capture->capture_conf.rise_edge_en = ptp_event1_config_reg.bf.rise_en; + + SW_RTN_ON_ERROR(qca808x_ptp_event1_status_reg_get(dev_id, + phy_id, &ptp_event1_status_reg)); + capture->capture_status.event_detected = ptp_event1_status_reg.bf.detected; + capture->capture_status.fall_rise_edge_detected = + ptp_event1_status_reg.bf.dir_detected; + capture->capture_status.single_multi_detected = ptp_event1_status_reg.bf.mul_event; + capture->capture_status.event_missed_cnt = ptp_event1_status_reg.bf.missed_count; + + SW_RTN_ON_ERROR(qca808x_ptp_event1_timestamp0_reg_get(dev_id, + phy_id, &ptp_event1_timestamp0_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_event1_timestamp1_reg_get(dev_id, + phy_id, &ptp_event1_timestamp1_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_event1_timestamp2_reg_get(dev_id, + phy_id, &ptp_event1_timestamp2_reg)); + capture->capture_status.tim.seconds = + ((a_int64_t)ptp_event1_timestamp0_reg.bf.ts_nsec << 32) | + (ptp_event1_timestamp1_reg.bf.ts_nsec << 16) | + ptp_event1_timestamp2_reg.bf.ts_nsec; + SW_RTN_ON_ERROR(qca808x_ptp_event1_timestamp3_reg_get(dev_id, + phy_id, &ptp_event1_timestamp3_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_event1_timestamp4_reg_get(dev_id, + phy_id, &ptp_event1_timestamp4_reg)); + capture->capture_status.tim.nanoseconds = + (ptp_event1_timestamp3_reg.bf.ts_nsec << 16) | + ptp_event1_timestamp4_reg.bf.ts_nsec; + } + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_interrupt_set(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_interrupt_t *interrupt) +{ + union ptp_imr_reg_u ptp_imr_reg = {0}; + union ptp_ext_imr_reg_u ptp_ext_imr_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_imr_reg_get(dev_id, phy_id, &ptp_imr_reg)); + ptp_imr_reg.bf.mask_bmp &= (~(0x7 << 2)) & 0xffff; + ptp_imr_reg.bf.mask_bmp |= (interrupt->intr_mask & 0x7) << 2; + SW_RTN_ON_ERROR(qca808x_ptp_imr_reg_set(dev_id, phy_id, &ptp_imr_reg)); + + ptp_ext_imr_reg.bf.mask_bmp = interrupt->intr_mask >> 3; + SW_RTN_ON_ERROR(qca808x_ptp_ext_imr_reg_set(dev_id, phy_id, &ptp_ext_imr_reg)); + + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_interrupt_get(a_uint32_t dev_id, + a_uint32_t phy_id, fal_ptp_interrupt_t *interrupt) +{ + union ptp_imr_reg_u ptp_imr_reg = {0}; + union ptp_isr_reg_u ptp_isr_reg = {0}; + union ptp_ext_imr_reg_u ptp_ext_imr_reg = {0}; + union ptp_ext_isr_reg_u ptp_ext_isr_reg = {0}; + + SW_RTN_ON_ERROR(qca808x_ptp_imr_reg_get(dev_id, phy_id, &ptp_imr_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_ext_imr_reg_get(dev_id, phy_id, &ptp_ext_imr_reg)); + interrupt->intr_mask = ((ptp_imr_reg.bf.mask_bmp >> 2) & 0x7) | + ((ptp_ext_imr_reg.bf.mask_bmp & 0x7ff) << 3); + + SW_RTN_ON_ERROR(qca808x_ptp_isr_reg_get(dev_id, phy_id, &ptp_isr_reg)); + SW_RTN_ON_ERROR(qca808x_ptp_ext_isr_reg_get(dev_id, phy_id, &ptp_ext_isr_reg)); + interrupt->intr_status = ((ptp_isr_reg.bf.status_bmp >> 2) & 0x7) | + ((ptp_ext_isr_reg.bf.status_bmp & 0x7ff) << 3); + + return SW_OK; +} + +void qca808x_phy_ptp_api_ops_init(hsl_phy_ptp_ops_t *ptp_ops) +{ + if (!ptp_ops) { + return; + } + ptp_ops->phy_ptp_security_set = qca808x_phy_ptp_security_set; + ptp_ops->phy_ptp_link_delay_set = qca808x_phy_ptp_link_delay_set; + ptp_ops->phy_ptp_rx_crc_recalc_status_get = qca808x_phy_ptp_rx_crc_recalc_status_get; + ptp_ops->phy_ptp_tod_uart_set = qca808x_phy_ptp_tod_uart_set; + ptp_ops->phy_ptp_pps_signal_control_set = qca808x_phy_ptp_pps_signal_control_set; + ptp_ops->phy_ptp_timestamp_get = qca808x_phy_ptp_timestamp_get; + ptp_ops->phy_ptp_asym_correction_get = qca808x_phy_ptp_asym_correction_get; + ptp_ops->phy_ptp_capture_set = qca808x_phy_ptp_capture_set; + ptp_ops->phy_ptp_rtc_adjfreq_set = qca808x_phy_ptp_rtc_adjfreq_set; + ptp_ops->phy_ptp_asym_correction_set = qca808x_phy_ptp_asym_correction_set; + ptp_ops->phy_ptp_pkt_timestamp_set = qca808x_phy_ptp_pkt_timestamp_set; + ptp_ops->phy_ptp_rtc_time_get = qca808x_phy_ptp_rtc_time_get; + ptp_ops->phy_ptp_rtc_time_set = qca808x_phy_ptp_rtc_time_set; + ptp_ops->phy_ptp_pkt_timestamp_get = qca808x_phy_ptp_pkt_timestamp_get; + ptp_ops->phy_ptp_interrupt_set = qca808x_phy_ptp_interrupt_set; + ptp_ops->phy_ptp_trigger_set = qca808x_phy_ptp_trigger_set; + ptp_ops->phy_ptp_pps_signal_control_get = qca808x_phy_ptp_pps_signal_control_get; + ptp_ops->phy_ptp_capture_get = qca808x_phy_ptp_capture_get; + ptp_ops->phy_ptp_rx_crc_recalc_enable = qca808x_phy_ptp_rx_crc_recalc_enable; + ptp_ops->phy_ptp_security_get = qca808x_phy_ptp_security_get; + ptp_ops->phy_ptp_tod_uart_get = qca808x_phy_ptp_tod_uart_get; + ptp_ops->phy_ptp_rtc_time_clear = qca808x_phy_ptp_rtc_time_clear; + ptp_ops->phy_ptp_reference_clock_set = qca808x_phy_ptp_reference_clock_set; + ptp_ops->phy_ptp_output_waveform_set = qca808x_phy_ptp_output_waveform_set; + ptp_ops->phy_ptp_rx_timestamp_mode_set = qca808x_phy_ptp_rx_timestamp_mode_set; + ptp_ops->phy_ptp_grandmaster_mode_set = qca808x_phy_ptp_grandmaster_mode_set; + ptp_ops->phy_ptp_config_set = qca808x_phy_ptp_config_set; + ptp_ops->phy_ptp_trigger_get = qca808x_phy_ptp_trigger_get; + ptp_ops->phy_ptp_rtc_adjfreq_get = qca808x_phy_ptp_rtc_adjfreq_get; + ptp_ops->phy_ptp_grandmaster_mode_get = qca808x_phy_ptp_grandmaster_mode_get; + ptp_ops->phy_ptp_rx_timestamp_mode_get = qca808x_phy_ptp_rx_timestamp_mode_get; + ptp_ops->phy_ptp_rtc_adjtime_set = qca808x_phy_ptp_rtc_adjtime_set; + ptp_ops->phy_ptp_link_delay_get = qca808x_phy_ptp_link_delay_get; + ptp_ops->phy_ptp_config_get = qca808x_phy_ptp_config_get; + ptp_ops->phy_ptp_output_waveform_get = qca808x_phy_ptp_output_waveform_get; + ptp_ops->phy_ptp_interrupt_get = qca808x_phy_ptp_interrupt_get; + ptp_ops->phy_ptp_rtc_time_snapshot_enable = qca808x_phy_ptp_rtc_time_snapshot_enable; + ptp_ops->phy_ptp_reference_clock_get = qca808x_phy_ptp_reference_clock_get; + ptp_ops->phy_ptp_enhanced_timestamp_engine_set = + qca808x_phy_ptp_enhanced_timestamp_engine_set; + ptp_ops->phy_ptp_rtc_time_snapshot_status_get = + qca808x_phy_ptp_rtc_time_snapshot_status_get; + ptp_ops->phy_ptp_enhanced_timestamp_engine_get = + qca808x_phy_ptp_enhanced_timestamp_engine_get; + ptp_ops->phy_ptp_increment_sync_from_clock_enable = + qca808x_phy_ptp_increment_sync_from_clock_enable; + ptp_ops->phy_ptp_increment_sync_from_clock_status_get = + qca808x_phy_ptp_increment_sync_from_clock_status_get; +} diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/qca808x_ptp_api.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/qca808x_ptp_api.c new file mode 100755 index 000000000..e0342e9f6 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/qca808x_ptp_api.c @@ -0,0 +1,15319 @@ +/* + * 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. + */ + + +/** + * @defgroup + * @{ + */ + +#include "sw.h" +#include "hsl_api.h" +#include "hsl.h" +#include "hsl_phy.h" +#include "ssdk_plat.h" +#include "qca808x_ptp_reg.h" +#include "qca808x_ptp_api.h" +#include "qca808x_phy.h" + + +sw_error_t +qca808x_phy_ptp_reg_read(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t reg, a_uint32_t * val) +{ + *val = qca808x_phy_reg_read(dev_id, phy_id, reg); + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_reg_write(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t reg, a_uint32_t val) +{ + return qca808x_phy_reg_write(dev_id, phy_id, reg, (a_uint16_t)val); +} + +sw_error_t +qca808x_phy_ptp_mmd_read(a_uint32_t dev_id, a_uint32_t phy_id, a_uint16_t mmd_num, + a_uint32_t reg, a_uint32_t * val) +{ + *val = qca808x_phy_mmd_read(dev_id, phy_id, mmd_num, (a_uint16_t)reg); + return SW_OK; +} + +sw_error_t +qca808x_phy_ptp_mmd_write(a_uint32_t dev_id, a_uint32_t phy_id, a_uint16_t mmd_num, + a_uint32_t reg, a_uint32_t val) +{ + return qca808x_phy_mmd_write(dev_id, phy_id, mmd_num, (a_uint16_t)reg, (a_uint16_t)val); +} + +sw_error_t +qca808x_ptp_imr_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, union ptp_imr_reg_u *value) +{ + return qca808x_phy_ptp_reg_read( + dev_id, + phy_id, PTP_IMR_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_imr_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, union ptp_imr_reg_u *value) +{ + return qca808x_phy_ptp_reg_write( + dev_id, + phy_id, PTP_IMR_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_isr_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, union ptp_isr_reg_u *value) +{ + return qca808x_phy_ptp_reg_read( + dev_id, + phy_id, PTP_ISR_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_isr_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, union ptp_isr_reg_u *value) +{ + return qca808x_phy_ptp_reg_write( + dev_id, + phy_id, PTP_ISR_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_hw_enable_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_hw_enable_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_HW_ENABLE_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_hw_enable_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_hw_enable_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_HW_ENABLE_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_main_conf_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_main_conf_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_MAIN_CONF_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_main_conf_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_main_conf_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_MAIN_CONF_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_seqid0_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_seqid0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_SEQID0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_seqid0_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_seqid0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_SEQID0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_portid0_0_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid0_0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID0_0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_portid0_0_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid0_0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID0_0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_portid0_1_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid0_1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID0_1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_portid0_1_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid0_1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID0_1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_portid0_2_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid0_2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID0_2_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_portid0_2_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid0_2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID0_2_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_portid0_3_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid0_3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID0_3_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_portid0_3_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid0_3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID0_3_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_portid0_4_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid0_4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID0_4_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_portid0_4_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid0_4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID0_4_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rtc_clk_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_clk_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD7_NUM, PTP_RTC_CLK_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rtc_clk_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_clk_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD7_NUM, PTP_RTC_CLK_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_ts0_0_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts0_0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS0_0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_ts0_0_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts0_0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS0_0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_ts0_1_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts0_1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS0_1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_ts0_1_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts0_1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS0_1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_ts0_2_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts0_2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS0_2_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_ts0_2_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts0_2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS0_2_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_ts0_3_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts0_3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS0_3_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_ts0_3_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts0_3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS0_3_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_ts0_4_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts0_4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS0_4_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_ts0_4_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts0_4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS0_4_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_ts0_5_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts0_5_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS0_5_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_ts0_5_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts0_5_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS0_5_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_ts0_6_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts0_6_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS0_6_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_ts0_6_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts0_6_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS0_6_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_seqid_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_seqid_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_SEQID_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_seqid_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_seqid_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_SEQID_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_portid0_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_portid0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_PORTID0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_portid0_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_portid0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_PORTID0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_portid1_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_portid1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_PORTID1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_portid1_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_portid1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_PORTID1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_portid2_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_portid2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_PORTID2_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_portid2_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_portid2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_PORTID2_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_portid3_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_portid3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_PORTID3_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_portid3_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_portid3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_PORTID3_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_portid4_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_portid4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_PORTID4_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_portid4_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_portid4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_PORTID4_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_ts0_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_ts0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_TS0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_ts0_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_ts0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_TS0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_ts1_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_ts1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_TS1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_ts1_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_ts1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_TS1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_ts2_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_ts2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_TS2_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_ts2_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_ts2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_TS2_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_ts3_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_ts3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_TS3_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_ts3_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_ts3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_TS3_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_ts4_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_ts4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_TS4_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_ts4_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_ts4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_TS4_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_ts5_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_ts5_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_TS5_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_ts5_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_ts5_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_TS5_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_ts6_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_ts6_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_TS6_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_ts6_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_ts6_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_TS6_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_orig_corr0_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_orig_corr0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_ORIG_CORR0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_orig_corr0_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_orig_corr0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_ORIG_CORR0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_orig_corr1_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_orig_corr1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_ORIG_CORR1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_orig_corr1_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_orig_corr1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_ORIG_CORR1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_orig_corr2_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_orig_corr2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_ORIG_CORR2_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_orig_corr2_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_orig_corr2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_ORIG_CORR2_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_orig_corr3_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_orig_corr3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_ORIG_CORR3_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_orig_corr3_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_orig_corr3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_ORIG_CORR3_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_in_trig0_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_in_trig0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_IN_TRIG0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_in_trig0_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_in_trig0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_IN_TRIG0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_in_trig1_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_in_trig1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_IN_TRIG1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_in_trig1_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_in_trig1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_IN_TRIG1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_in_trig2_reg_get(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_in_trig2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_IN_TRIG2_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_in_trig2_reg_set(a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_in_trig2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_IN_TRIG2_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_in_trig3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_in_trig3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_IN_TRIG3_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_in_trig3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_in_trig3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_IN_TRIG3_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_latency_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_latency_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_LATENCY_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_latency_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_latency_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_LATENCY_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rtc_inc0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_inc0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTC_INC0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rtc_inc0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_inc0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTC_INC0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rtc_inc1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_inc1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTC_INC1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rtc_inc1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_inc1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTC_INC1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rtcoffs0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtcoffs0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTCOFFS0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rtcoffs0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtcoffs0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTCOFFS0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rtcoffs1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtcoffs1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTCOFFS1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rtcoffs1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtcoffs1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTCOFFS1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rtcoffs2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtcoffs2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTCOFFS2_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rtcoffs2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtcoffs2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTCOFFS2_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rtcoffs3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtcoffs3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTCOFFS3_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rtcoffs3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtcoffs3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTCOFFS3_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rtcoffs4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtcoffs4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTCOFFS4_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rtcoffs4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtcoffs4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTCOFFS4_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rtc0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTC0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rtc0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTC0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rtc1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTC1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rtc1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTC1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rtc2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTC2_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rtc2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTC2_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rtc3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTC3_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rtc3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTC3_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rtc4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTC4_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rtc4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTC4_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rtc5_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc5_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTC5_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rtc5_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc5_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTC5_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rtc6_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc6_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTC6_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rtc6_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc6_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTC6_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rtcoffs_valid_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtcoffs_valid_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTCOFFS_VALID_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rtcoffs_valid_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtcoffs_valid_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTCOFFS_VALID_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_misc_config_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_misc_config_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_MISC_CONFIG_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_misc_config_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_misc_config_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_MISC_CONFIG_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_ext_imr_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ext_imr_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EXT_IMR_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_ext_imr_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ext_imr_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EXT_IMR_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_ext_isr_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ext_isr_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EXT_ISR_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_ext_isr_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ext_isr_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EXT_ISR_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rtc_ext_conf_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_ext_conf_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTC_EXT_CONF_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rtc_ext_conf_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_ext_conf_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTC_EXT_CONF_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rtc_preloaded0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_preloaded0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTC_PRELOADED0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rtc_preloaded0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_preloaded0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTC_PRELOADED0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rtc_preloaded1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_preloaded1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTC_PRELOADED1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rtc_preloaded1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_preloaded1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTC_PRELOADED1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rtc_preloaded2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_preloaded2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTC_PRELOADED2_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rtc_preloaded2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_preloaded2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTC_PRELOADED2_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rtc_preloaded3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_preloaded3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTC_PRELOADED3_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rtc_preloaded3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_preloaded3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTC_PRELOADED3_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rtc_preloaded4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_preloaded4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTC_PRELOADED4_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rtc_preloaded4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rtc_preloaded4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RTC_PRELOADED4_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_gm_conf0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_gm_conf0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_GM_CONF0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_gm_conf0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_gm_conf0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_GM_CONF0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_gm_conf1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_gm_conf1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_GM_CONF1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_gm_conf1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_gm_conf1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_GM_CONF1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_ppsin_ts0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ppsin_ts0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_PPSIN_TS0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_ppsin_ts0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ppsin_ts0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_PPSIN_TS0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_ppsin_ts1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ppsin_ts1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_PPSIN_TS1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_ppsin_ts1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ppsin_ts1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_PPSIN_TS1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_ppsin_ts2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ppsin_ts2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_PPSIN_TS2_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_ppsin_ts2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ppsin_ts2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_PPSIN_TS2_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_ppsin_ts3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ppsin_ts3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_PPSIN_TS3_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_ppsin_ts3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ppsin_ts3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_PPSIN_TS3_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_ppsin_ts4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ppsin_ts4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_PPSIN_TS4_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_ppsin_ts4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ppsin_ts4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_PPSIN_TS4_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_hwpll_inc0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_hwpll_inc0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_HWPLL_INC0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_hwpll_inc0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_hwpll_inc0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_HWPLL_INC0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_hwpll_inc1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_hwpll_inc1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_HWPLL_INC1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_hwpll_inc1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_hwpll_inc1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_HWPLL_INC1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_ppsin_latency_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ppsin_latency_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_PPSIN_LATENCY_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_ppsin_latency_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ppsin_latency_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_PPSIN_LATENCY_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_trigger0_config_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger0_config_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TRIGGER0_CONFIG_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_trigger0_config_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger0_config_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TRIGGER0_CONFIG_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_trigger0_status_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger0_status_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TRIGGER0_STATUS_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_trigger0_status_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger0_status_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TRIGGER0_STATUS_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_trigger1_config_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger1_config_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TRIGGER1_CONFIG_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_trigger1_config_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger1_config_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TRIGGER1_CONFIG_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_trigger1_status_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger1_status_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TRIGGER1_STATUS_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_trigger1_status_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger1_status_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TRIGGER1_STATUS_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_trigger0_timestamp0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger0_timestamp0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TRIGGER0_TIMESTAMP0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_trigger0_timestamp0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger0_timestamp0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TRIGGER0_TIMESTAMP0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_trigger0_timestamp1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger0_timestamp1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TRIGGER0_TIMESTAMP1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_trigger0_timestamp1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger0_timestamp1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TRIGGER0_TIMESTAMP1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_trigger0_timestamp2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger0_timestamp2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TRIGGER0_TIMESTAMP2_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_trigger0_timestamp2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger0_timestamp2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TRIGGER0_TIMESTAMP2_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_trigger0_timestamp3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger0_timestamp3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TRIGGER0_TIMESTAMP3_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_trigger0_timestamp3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger0_timestamp3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TRIGGER0_TIMESTAMP3_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_trigger0_timestamp4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger0_timestamp4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TRIGGER0_TIMESTAMP4_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_trigger0_timestamp4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger0_timestamp4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TRIGGER0_TIMESTAMP4_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_trigger1_timestamp0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger1_timestamp0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TRIGGER1_TIMESTAMP0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_trigger1_timestamp0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger1_timestamp0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TRIGGER1_TIMESTAMP0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_trigger1_timestamp1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger1_timestamp1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TRIGGER1_TIMESTAMP1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_trigger1_timestamp1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger1_timestamp1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TRIGGER1_TIMESTAMP1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_trigger1_timestamp2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger1_timestamp2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TRIGGER1_TIMESTAMP2_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_trigger1_timestamp2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger1_timestamp2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TRIGGER1_TIMESTAMP2_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_trigger1_timestamp3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger1_timestamp3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TRIGGER1_TIMESTAMP3_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_trigger1_timestamp3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger1_timestamp3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TRIGGER1_TIMESTAMP3_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_trigger1_timestamp4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger1_timestamp4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TRIGGER1_TIMESTAMP4_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_trigger1_timestamp4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_trigger1_timestamp4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TRIGGER1_TIMESTAMP4_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_event0_config_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event0_config_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EVENT0_CONFIG_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_event0_config_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event0_config_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EVENT0_CONFIG_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_event0_status_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event0_status_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EVENT0_STATUS_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_event0_status_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event0_status_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EVENT0_STATUS_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_event1_config_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event1_config_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EVENT1_CONFIG_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_event1_config_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event1_config_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EVENT1_CONFIG_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_event1_status_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event1_status_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EVENT1_STATUS_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_event1_status_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event1_status_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EVENT1_STATUS_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_event0_timestamp0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event0_timestamp0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EVENT0_TIMESTAMP0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_event0_timestamp0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event0_timestamp0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EVENT0_TIMESTAMP0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_event0_timestamp1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event0_timestamp1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EVENT0_TIMESTAMP1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_event0_timestamp1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event0_timestamp1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EVENT0_TIMESTAMP1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_event0_timestamp2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event0_timestamp2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EVENT0_TIMESTAMP2_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_event0_timestamp2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event0_timestamp2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EVENT0_TIMESTAMP2_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_event0_timestamp3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event0_timestamp3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EVENT0_TIMESTAMP3_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_event0_timestamp3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event0_timestamp3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EVENT0_TIMESTAMP3_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_event0_timestamp4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event0_timestamp4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EVENT0_TIMESTAMP4_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_event0_timestamp4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event0_timestamp4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EVENT0_TIMESTAMP4_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_event1_timestamp0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event1_timestamp0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EVENT1_TIMESTAMP0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_event1_timestamp0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event1_timestamp0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EVENT1_TIMESTAMP0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_event1_timestamp1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event1_timestamp1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EVENT1_TIMESTAMP1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_event1_timestamp1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event1_timestamp1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EVENT1_TIMESTAMP1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_event1_timestamp2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event1_timestamp2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EVENT1_TIMESTAMP2_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_event1_timestamp2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event1_timestamp2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EVENT1_TIMESTAMP2_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_event1_timestamp3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event1_timestamp3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EVENT1_TIMESTAMP3_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_event1_timestamp3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event1_timestamp3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EVENT1_TIMESTAMP3_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_event1_timestamp4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event1_timestamp4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EVENT1_TIMESTAMP4_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_event1_timestamp4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_event1_timestamp4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EVENT1_TIMESTAMP4_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_seqid1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_seqid1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_SEQID1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_seqid1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_seqid1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_SEQID1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_portid1_0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid1_0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID1_0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_portid1_0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid1_0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID1_0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_portid1_1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid1_1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID1_1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_portid1_1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid1_1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID1_1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_portid1_2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid1_2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID1_2_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_portid1_2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid1_2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID1_2_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_portid1_3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid1_3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID1_3_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_portid1_3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid1_3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID1_3_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_portid1_4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid1_4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID1_4_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_portid1_4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid1_4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID1_4_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_ts1_0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts1_0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS1_0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_ts1_0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts1_0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS1_0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_ts1_1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts1_1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS1_1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_ts1_1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts1_1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS1_1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_ts1_2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts1_2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS1_2_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_ts1_2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts1_2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS1_2_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_ts1_3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts1_3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS1_3_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_ts1_3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts1_3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS1_3_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_ts1_4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts1_4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS1_4_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_ts1_4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts1_4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS1_4_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_ts1_5_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts1_5_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS1_5_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_ts1_5_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts1_5_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS1_5_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_ts1_6_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts1_6_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS1_6_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_ts1_6_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts1_6_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS1_6_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_seqid2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_seqid2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_SEQID2_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_seqid2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_seqid2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_SEQID2_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_portid2_0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid2_0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID2_0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_portid2_0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid2_0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID2_0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_portid2_1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid2_1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID2_1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_portid2_1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid2_1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID2_1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_portid2_2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid2_2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID2_2_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_portid2_2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid2_2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID2_2_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_portid2_3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid2_3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID2_3_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_portid2_3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid2_3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID2_3_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_portid2_4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid2_4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID2_4_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_portid2_4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid2_4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID2_4_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_ts2_0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts2_0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS2_0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_ts2_0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts2_0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS2_0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_ts2_1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts2_1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS2_1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_ts2_1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts2_1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS2_1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_ts2_2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts2_2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS2_2_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_ts2_2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts2_2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS2_2_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_ts2_3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts2_3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS2_3_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_ts2_3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts2_3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS2_3_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_ts2_4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts2_4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS2_4_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_ts2_4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts2_4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS2_4_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_ts2_5_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts2_5_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS2_5_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_ts2_5_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts2_5_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS2_5_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_ts2_6_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts2_6_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS2_6_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_ts2_6_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts2_6_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS2_6_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_seqid3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_seqid3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_SEQID3_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_seqid3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_seqid3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_SEQID3_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_portid3_0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid3_0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID3_0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_portid3_0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid3_0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID3_0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_portid3_1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid3_1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID3_1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_portid3_1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid3_1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID3_1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_portid3_2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid3_2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID3_2_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_portid3_2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid3_2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID3_2_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_portid3_3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid3_3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID3_3_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_portid3_3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid3_3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID3_3_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_portid3_4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid3_4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID3_4_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_portid3_4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_portid3_4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_PORTID3_4_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_ts3_0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts3_0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS3_0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_ts3_0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts3_0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS3_0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_ts3_1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts3_1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS3_1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_ts3_1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts3_1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS3_1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_ts3_2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts3_2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS3_2_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_ts3_2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts3_2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS3_2_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_ts3_3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts3_3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS3_3_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_ts3_3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts3_3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS3_3_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_ts3_4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts3_4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS3_4_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_ts3_4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts3_4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS3_4_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_ts3_5_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts3_5_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS3_5_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_ts3_5_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts3_5_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS3_5_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_ts3_6_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts3_6_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS3_6_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_ts3_6_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_ts3_6_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_TS3_6_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_imr_reg_mask_bmp_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_imr_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_imr_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.mask_bmp; + return ret; +} + +sw_error_t +qca808x_ptp_imr_reg_mask_bmp_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_imr_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_imr_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mask_bmp = value; + ret = qca808x_ptp_imr_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_isr_reg_status_bmp_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_isr_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_isr_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.status_bmp; + return ret; +} + +sw_error_t +qca808x_ptp_isr_reg_status_bmp_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_isr_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_isr_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.status_bmp = value; + ret = qca808x_ptp_isr_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_hw_enable_reg_ptp_hw_enable_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_hw_enable_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_hw_enable_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_hw_enable; + return ret; +} + +sw_error_t +qca808x_ptp_hw_enable_reg_ptp_hw_enable_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_hw_enable_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_hw_enable_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_hw_enable = value; + ret = qca808x_ptp_hw_enable_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_main_conf_reg_ts_attach_mode_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_main_conf_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_main_conf_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ts_attach_mode; + return ret; +} + +sw_error_t +qca808x_ptp_main_conf_reg_ts_attach_mode_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_main_conf_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_main_conf_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ts_attach_mode = value; + ret = qca808x_ptp_main_conf_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_main_conf_reg_ptp_clk_sel_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_main_conf_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_main_conf_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_clk_sel; + return ret; +} + +sw_error_t +qca808x_ptp_main_conf_reg_ptp_clk_sel_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_main_conf_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_main_conf_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_clk_sel = value; + ret = qca808x_ptp_main_conf_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_main_conf_reg_disable_1588_phy_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_main_conf_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_main_conf_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.disable_1588_phy; + return ret; +} + +sw_error_t +qca808x_ptp_main_conf_reg_disable_1588_phy_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_main_conf_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_main_conf_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.disable_1588_phy = value; + ret = qca808x_ptp_main_conf_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_main_conf_reg_attach_crc_recal_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_main_conf_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_main_conf_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.attach_crc_recal; + return ret; +} + +sw_error_t +qca808x_ptp_main_conf_reg_attach_crc_recal_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_main_conf_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_main_conf_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.attach_crc_recal = value; + ret = qca808x_ptp_main_conf_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_main_conf_reg_ipv4_force_checksum_zero_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_main_conf_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_main_conf_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ipv4_force_checksum_zero; + return ret; +} + +sw_error_t +qca808x_ptp_main_conf_reg_ipv4_force_checksum_zero_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_main_conf_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_main_conf_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv4_force_checksum_zero = value; + ret = qca808x_ptp_main_conf_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_main_conf_reg_ipv6_embed_force_checksum_zero_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_main_conf_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_main_conf_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ipv6_embed_force_checksum_zero; + return ret; +} + +sw_error_t +qca808x_ptp_main_conf_reg_ipv6_embed_force_checksum_zero_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_main_conf_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_main_conf_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv6_embed_force_checksum_zero = value; + ret = qca808x_ptp_main_conf_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_main_conf_reg_ptp_bypass_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_main_conf_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_main_conf_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_bypass; + return ret; +} + +sw_error_t +qca808x_ptp_main_conf_reg_ptp_bypass_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_main_conf_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_main_conf_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_bypass = value; + ret = qca808x_ptp_main_conf_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_main_conf_reg_wol_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_main_conf_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_main_conf_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.wol_en; + return ret; +} + +sw_error_t +qca808x_ptp_main_conf_reg_wol_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_main_conf_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_main_conf_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.wol_en = value; + ret = qca808x_ptp_main_conf_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_main_conf_reg_ptp_clock_mode_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_main_conf_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_main_conf_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_clock_mode; + return ret; +} + +sw_error_t +qca808x_ptp_main_conf_reg_ptp_clock_mode_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_main_conf_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_main_conf_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_clock_mode = value; + ret = qca808x_ptp_main_conf_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_seqid0_reg_rx_seqid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_seqid0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_seqid0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_seqid; + return ret; +} + +sw_error_t +qca808x_ptp_rx_seqid0_reg_rx_seqid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_seqid0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_seqid0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_seqid = value; + ret = qca808x_ptp_rx_seqid0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid0_0_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_portid0_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid0_0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_portid; + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid0_0_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_portid0_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid0_0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_portid = value; + ret = qca808x_ptp_rx_portid0_0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid0_1_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_portid0_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid0_1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_portid; + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid0_1_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_portid0_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid0_1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_portid = value; + ret = qca808x_ptp_rx_portid0_1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid0_2_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_portid0_2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid0_2_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_portid; + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid0_2_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_portid0_2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid0_2_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_portid = value; + ret = qca808x_ptp_rx_portid0_2_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid0_3_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_portid0_3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid0_3_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_portid; + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid0_3_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_portid0_3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid0_3_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_portid = value; + ret = qca808x_ptp_rx_portid0_3_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid0_4_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_portid0_4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid0_4_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_portid; + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid0_4_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_portid0_4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid0_4_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_portid = value; + ret = qca808x_ptp_rx_portid0_4_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rtc_clk_reg_rtc_clk_selection_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rtc_clk_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc_clk_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rtc_clk_selection; + return ret; +} + +sw_error_t +qca808x_ptp_rtc_clk_reg_rtc_clk_selection_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rtc_clk_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc_clk_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rtc_clk_selection = value; + ret = qca808x_ptp_rtc_clk_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts0_0_reg_rx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_ts0_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts0_0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_ts_sec; + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts0_0_reg_rx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_ts0_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts0_0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_ts_sec = value; + ret = qca808x_ptp_rx_ts0_0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts0_1_reg_rx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_ts0_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts0_1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_ts_sec; + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts0_1_reg_rx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_ts0_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts0_1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_ts_sec = value; + ret = qca808x_ptp_rx_ts0_1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts0_2_reg_rx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_ts0_2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts0_2_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_ts_sec; + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts0_2_reg_rx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_ts0_2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts0_2_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_ts_sec = value; + ret = qca808x_ptp_rx_ts0_2_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts0_3_reg_rx_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_ts0_3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts0_3_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_ts_nsec; + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts0_3_reg_rx_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_ts0_3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts0_3_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_ts_nsec = value; + ret = qca808x_ptp_rx_ts0_3_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts0_4_reg_rx_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_ts0_4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts0_4_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_ts_nsec; + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts0_4_reg_rx_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_ts0_4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts0_4_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_ts_nsec = value; + ret = qca808x_ptp_rx_ts0_4_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts0_5_reg_rx_ts_nfsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_ts0_5_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts0_5_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_ts_nfsec; + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts0_5_reg_rx_ts_nfsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_ts0_5_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts0_5_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_ts_nfsec = value; + ret = qca808x_ptp_rx_ts0_5_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts0_5_reg_rx_msg_type_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_ts0_5_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts0_5_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_msg_type; + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts0_5_reg_rx_msg_type_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_ts0_5_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts0_5_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_msg_type = value; + ret = qca808x_ptp_rx_ts0_5_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts0_6_reg_rx_ts_nfsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_ts0_6_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts0_6_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_ts_nfsec; + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts0_6_reg_rx_ts_nfsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_ts0_6_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts0_6_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_ts_nfsec = value; + ret = qca808x_ptp_rx_ts0_6_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_seqid_reg_tx_seqid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_seqid_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_seqid_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.tx_seqid; + return ret; +} + +sw_error_t +qca808x_ptp_tx_seqid_reg_tx_seqid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_seqid_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_seqid_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_seqid = value; + ret = qca808x_ptp_tx_seqid_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_portid0_reg_tx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_portid0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_portid0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.tx_portid; + return ret; +} + +sw_error_t +qca808x_ptp_tx_portid0_reg_tx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_portid0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_portid0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_portid = value; + ret = qca808x_ptp_tx_portid0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_portid1_reg_tx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_portid1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_portid1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.tx_portid; + return ret; +} + +sw_error_t +qca808x_ptp_tx_portid1_reg_tx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_portid1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_portid1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_portid = value; + ret = qca808x_ptp_tx_portid1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_portid2_reg_tx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_portid2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_portid2_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.tx_portid; + return ret; +} + +sw_error_t +qca808x_ptp_tx_portid2_reg_tx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_portid2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_portid2_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_portid = value; + ret = qca808x_ptp_tx_portid2_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_portid3_reg_tx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_portid3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_portid3_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.tx_portid; + return ret; +} + +sw_error_t +qca808x_ptp_tx_portid3_reg_tx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_portid3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_portid3_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_portid = value; + ret = qca808x_ptp_tx_portid3_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_portid4_reg_tx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_portid4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_portid4_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.tx_portid; + return ret; +} + +sw_error_t +qca808x_ptp_tx_portid4_reg_tx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_portid4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_portid4_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_portid = value; + ret = qca808x_ptp_tx_portid4_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_ts0_reg_tx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_ts0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_ts0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.tx_ts_sec; + return ret; +} + +sw_error_t +qca808x_ptp_tx_ts0_reg_tx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_ts0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_ts0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_ts_sec = value; + ret = qca808x_ptp_tx_ts0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_ts1_reg_tx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_ts1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_ts1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.tx_ts_sec; + return ret; +} + +sw_error_t +qca808x_ptp_tx_ts1_reg_tx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_ts1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_ts1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_ts_sec = value; + ret = qca808x_ptp_tx_ts1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_ts2_reg_tx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_ts2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_ts2_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.tx_ts_sec; + return ret; +} + +sw_error_t +qca808x_ptp_tx_ts2_reg_tx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_ts2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_ts2_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_ts_sec = value; + ret = qca808x_ptp_tx_ts2_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_ts3_reg_tx_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_ts3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_ts3_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.tx_ts_nsec; + return ret; +} + +sw_error_t +qca808x_ptp_tx_ts3_reg_tx_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_ts3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_ts3_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_ts_nsec = value; + ret = qca808x_ptp_tx_ts3_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_ts4_reg_tx_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_ts4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_ts4_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.tx_ts_nsec; + return ret; +} + +sw_error_t +qca808x_ptp_tx_ts4_reg_tx_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_ts4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_ts4_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_ts_nsec = value; + ret = qca808x_ptp_tx_ts4_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_ts5_reg_tx_ts_nfsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_ts5_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_ts5_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.tx_ts_nfsec; + return ret; +} + +sw_error_t +qca808x_ptp_tx_ts5_reg_tx_ts_nfsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_ts5_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_ts5_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_ts_nfsec = value; + ret = qca808x_ptp_tx_ts5_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_ts5_reg_tx_msg_type_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_ts5_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_ts5_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.tx_msg_type; + return ret; +} + +sw_error_t +qca808x_ptp_tx_ts5_reg_tx_msg_type_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_ts5_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_ts5_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_msg_type = value; + ret = qca808x_ptp_tx_ts5_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_ts6_reg_tx_ts_nfsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_ts6_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_ts6_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.tx_ts_nfsec; + return ret; +} + +sw_error_t +qca808x_ptp_tx_ts6_reg_tx_ts_nfsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_ts6_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_ts6_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_ts_nfsec = value; + ret = qca808x_ptp_tx_ts6_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_orig_corr0_reg_ptp_orig_corr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_orig_corr0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_orig_corr0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_orig_corr; + return ret; +} + +sw_error_t +qca808x_ptp_orig_corr0_reg_ptp_orig_corr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_orig_corr0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_orig_corr0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_orig_corr = value; + ret = qca808x_ptp_orig_corr0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_orig_corr1_reg_ptp_orig_corr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_orig_corr1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_orig_corr1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_orig_corr; + return ret; +} + +sw_error_t +qca808x_ptp_orig_corr1_reg_ptp_orig_corr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_orig_corr1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_orig_corr1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_orig_corr = value; + ret = qca808x_ptp_orig_corr1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_orig_corr2_reg_ptp_orig_corr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_orig_corr2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_orig_corr2_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_orig_corr; + return ret; +} + +sw_error_t +qca808x_ptp_orig_corr2_reg_ptp_orig_corr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_orig_corr2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_orig_corr2_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_orig_corr = value; + ret = qca808x_ptp_orig_corr2_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_orig_corr3_reg_ptp_orig_corr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_orig_corr3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_orig_corr3_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_orig_corr; + return ret; +} + +sw_error_t +qca808x_ptp_orig_corr3_reg_ptp_orig_corr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_orig_corr3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_orig_corr3_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_orig_corr = value; + ret = qca808x_ptp_orig_corr3_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_in_trig0_reg_ptp_in_trig_nisec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_in_trig0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_in_trig0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_in_trig_nisec; + return ret; +} + +sw_error_t +qca808x_ptp_in_trig0_reg_ptp_in_trig_nisec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_in_trig0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_in_trig0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_in_trig_nisec = value; + ret = qca808x_ptp_in_trig0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_in_trig1_reg_ptp_in_trig_nisec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_in_trig1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_in_trig1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_in_trig_nisec; + return ret; +} + +sw_error_t +qca808x_ptp_in_trig1_reg_ptp_in_trig_nisec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_in_trig1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_in_trig1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_in_trig_nisec = value; + ret = qca808x_ptp_in_trig1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_in_trig2_reg_ptp_in_trig_nisec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_in_trig2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_in_trig2_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_in_trig_nisec; + return ret; +} + +sw_error_t +qca808x_ptp_in_trig2_reg_ptp_in_trig_nisec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_in_trig2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_in_trig2_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_in_trig_nisec = value; + ret = qca808x_ptp_in_trig2_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_in_trig3_reg_ptp_in_trig_nisec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_in_trig3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_in_trig3_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_in_trig_nisec; + return ret; +} + +sw_error_t +qca808x_ptp_in_trig3_reg_ptp_in_trig_nisec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_in_trig3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_in_trig3_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_in_trig_nisec = value; + ret = qca808x_ptp_in_trig3_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_latency_reg_ptp_tx_latency_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_latency_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_latency_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_tx_latency; + return ret; +} + +sw_error_t +qca808x_ptp_tx_latency_reg_ptp_tx_latency_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_latency_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_latency_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_tx_latency = value; + ret = qca808x_ptp_tx_latency_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rtc_inc0_reg_ptp_rtc_inc_nis_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rtc_inc0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc_inc0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_rtc_inc_nis; + return ret; +} + +sw_error_t +qca808x_ptp_rtc_inc0_reg_ptp_rtc_inc_nis_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rtc_inc0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc_inc0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_rtc_inc_nis = value; + ret = qca808x_ptp_rtc_inc0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rtc_inc0_reg_ptp_rtc_inc_nfs_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rtc_inc0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc_inc0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_rtc_inc_nfs; + return ret; +} + +sw_error_t +qca808x_ptp_rtc_inc0_reg_ptp_rtc_inc_nfs_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rtc_inc0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc_inc0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_rtc_inc_nfs = value; + ret = qca808x_ptp_rtc_inc0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rtc_inc1_reg_ptp_rtc_inc_nfs_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rtc_inc1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc_inc1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_rtc_inc_nfs; + return ret; +} + +sw_error_t +qca808x_ptp_rtc_inc1_reg_ptp_rtc_inc_nfs_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rtc_inc1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc_inc1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_rtc_inc_nfs = value; + ret = qca808x_ptp_rtc_inc1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rtcoffs0_reg_ptp_rtcoffs_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rtcoffs0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtcoffs0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_rtcoffs_nsec; + return ret; +} + +sw_error_t +qca808x_ptp_rtcoffs0_reg_ptp_rtcoffs_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rtcoffs0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtcoffs0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_rtcoffs_nsec = value; + ret = qca808x_ptp_rtcoffs0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rtcoffs1_reg_ptp_rtcoffs_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rtcoffs1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtcoffs1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_rtcoffs_nsec; + return ret; +} + +sw_error_t +qca808x_ptp_rtcoffs1_reg_ptp_rtcoffs_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rtcoffs1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtcoffs1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_rtcoffs_nsec = value; + ret = qca808x_ptp_rtcoffs1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rtcoffs2_reg_ptp_rtcoffs_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rtcoffs2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtcoffs2_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_rtcoffs_sec; + return ret; +} + +sw_error_t +qca808x_ptp_rtcoffs2_reg_ptp_rtcoffs_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rtcoffs2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtcoffs2_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_rtcoffs_sec = value; + ret = qca808x_ptp_rtcoffs2_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rtcoffs3_reg_ptp_rtcoffs_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rtcoffs3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtcoffs3_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_rtcoffs_sec; + return ret; +} + +sw_error_t +qca808x_ptp_rtcoffs3_reg_ptp_rtcoffs_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rtcoffs3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtcoffs3_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_rtcoffs_sec = value; + ret = qca808x_ptp_rtcoffs3_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rtcoffs4_reg_ptp_rtcoffs_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rtcoffs4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtcoffs4_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_rtcoffs_sec; + return ret; +} + +sw_error_t +qca808x_ptp_rtcoffs4_reg_ptp_rtcoffs_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rtcoffs4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtcoffs4_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_rtcoffs_sec = value; + ret = qca808x_ptp_rtcoffs4_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rtc0_reg_ptp_rtc_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rtc0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_rtc_sec; + return ret; +} + +sw_error_t +qca808x_ptp_rtc0_reg_ptp_rtc_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rtc0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_rtc_sec = value; + ret = qca808x_ptp_rtc0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rtc1_reg_ptp_rtc_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rtc1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_rtc_sec; + return ret; +} + +sw_error_t +qca808x_ptp_rtc1_reg_ptp_rtc_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rtc1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_rtc_sec = value; + ret = qca808x_ptp_rtc1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rtc2_reg_ptp_rtc_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rtc2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc2_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_rtc_sec; + return ret; +} + +sw_error_t +qca808x_ptp_rtc2_reg_ptp_rtc_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rtc2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc2_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_rtc_sec = value; + ret = qca808x_ptp_rtc2_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rtc3_reg_ptp_rtc_nisec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rtc3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc3_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_rtc_nisec; + return ret; +} + +sw_error_t +qca808x_ptp_rtc3_reg_ptp_rtc_nisec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rtc3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc3_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_rtc_nisec = value; + ret = qca808x_ptp_rtc3_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rtc4_reg_ptp_rtc_nisec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rtc4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc4_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_rtc_nisec; + return ret; +} + +sw_error_t +qca808x_ptp_rtc4_reg_ptp_rtc_nisec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rtc4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc4_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_rtc_nisec = value; + ret = qca808x_ptp_rtc4_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rtc5_reg_ptp_rtc_nfsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rtc5_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc5_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_rtc_nfsec; + return ret; +} + +sw_error_t +qca808x_ptp_rtc5_reg_ptp_rtc_nfsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rtc5_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc5_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_rtc_nfsec = value; + ret = qca808x_ptp_rtc5_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rtc6_reg_ptp_rtc_nfsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rtc6_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc6_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_rtc_nfsec; + return ret; +} + +sw_error_t +qca808x_ptp_rtc6_reg_ptp_rtc_nfsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rtc6_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc6_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_rtc_nfsec = value; + ret = qca808x_ptp_rtc6_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rtcoffs_valid_reg_ptp_rtcoffs_valid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rtcoffs_valid_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtcoffs_valid_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_rtcoffs_valid; + return ret; +} + +sw_error_t +qca808x_ptp_rtcoffs_valid_reg_ptp_rtcoffs_valid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rtcoffs_valid_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtcoffs_valid_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_rtcoffs_valid = value; + ret = qca808x_ptp_rtcoffs_valid_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_misc_config_reg_ptp_ver_chk_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_misc_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_misc_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_ver_chk_en; + return ret; +} + +sw_error_t +qca808x_ptp_misc_config_reg_ptp_ver_chk_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_misc_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_misc_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_ver_chk_en = value; + ret = qca808x_ptp_misc_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_misc_config_reg_ipv6_udp_chk_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_misc_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_misc_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ipv6_udp_chk_en; + return ret; +} + +sw_error_t +qca808x_ptp_misc_config_reg_ipv6_udp_chk_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_misc_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_misc_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv6_udp_chk_en = value; + ret = qca808x_ptp_misc_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_misc_config_reg_cf_from_pkt_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_misc_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_misc_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.cf_from_pkt_en; + return ret; +} + +sw_error_t +qca808x_ptp_misc_config_reg_cf_from_pkt_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_misc_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_misc_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.cf_from_pkt_en = value; + ret = qca808x_ptp_misc_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_misc_config_reg_embed_ingress_time_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_misc_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_misc_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.embed_ingress_time_en; + return ret; +} + +sw_error_t +qca808x_ptp_misc_config_reg_embed_ingress_time_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_misc_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_misc_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.embed_ingress_time_en = value; + ret = qca808x_ptp_misc_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_misc_config_reg_ptp_addr_chk_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_misc_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_misc_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_addr_chk_en; + return ret; +} + +sw_error_t +qca808x_ptp_misc_config_reg_ptp_addr_chk_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_misc_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_misc_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_addr_chk_en = value; + ret = qca808x_ptp_misc_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_misc_config_reg_crc_validate_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_misc_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_misc_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.crc_validate_en; + return ret; +} + +sw_error_t +qca808x_ptp_misc_config_reg_crc_validate_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_misc_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_misc_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.crc_validate_en = value; + ret = qca808x_ptp_misc_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_misc_config_reg_pkt_one_step_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_misc_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_misc_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.pkt_one_step_en; + return ret; +} + +sw_error_t +qca808x_ptp_misc_config_reg_pkt_one_step_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_misc_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_misc_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pkt_one_step_en = value; + ret = qca808x_ptp_misc_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_misc_config_reg_ptp_version_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_misc_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_misc_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_version; + return ret; +} + +sw_error_t +qca808x_ptp_misc_config_reg_ptp_version_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_misc_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_misc_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_version = value; + ret = qca808x_ptp_misc_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_misc_config_reg_appended_timestamp_size_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_misc_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_misc_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.appended_timestamp_size; + return ret; +} + +sw_error_t +qca808x_ptp_misc_config_reg_appended_timestamp_size_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_misc_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_misc_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.appended_timestamp_size = value; + ret = qca808x_ptp_misc_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_misc_config_reg_ts_rtc_select_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_misc_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_misc_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ts_rtc_select; + return ret; +} + +sw_error_t +qca808x_ptp_misc_config_reg_ts_rtc_select_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_misc_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_misc_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ts_rtc_select = value; + ret = qca808x_ptp_misc_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_ext_imr_reg_mask_bmp_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_ext_imr_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_ext_imr_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.mask_bmp; + return ret; +} + +sw_error_t +qca808x_ptp_ext_imr_reg_mask_bmp_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_ext_imr_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_ext_imr_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mask_bmp = value; + ret = qca808x_ptp_ext_imr_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_ext_isr_reg_status_bmp_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_ext_isr_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_ext_isr_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.status_bmp; + return ret; +} + +sw_error_t +qca808x_ptp_ext_isr_reg_status_bmp_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_ext_isr_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_ext_isr_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.status_bmp = value; + ret = qca808x_ptp_ext_isr_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rtc_ext_conf_reg_rtc_snapshot_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rtc_ext_conf_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc_ext_conf_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rtc_snapshot; + return ret; +} + +sw_error_t +qca808x_ptp_rtc_ext_conf_reg_rtc_snapshot_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rtc_ext_conf_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc_ext_conf_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rtc_snapshot = value; + ret = qca808x_ptp_rtc_ext_conf_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rtc_ext_conf_reg_set_incval_mode_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rtc_ext_conf_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc_ext_conf_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.set_incval_mode; + return ret; +} + +sw_error_t +qca808x_ptp_rtc_ext_conf_reg_set_incval_mode_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rtc_ext_conf_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc_ext_conf_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.set_incval_mode = value; + ret = qca808x_ptp_rtc_ext_conf_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rtc_ext_conf_reg_load_rtc_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rtc_ext_conf_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc_ext_conf_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.load_rtc; + return ret; +} + +sw_error_t +qca808x_ptp_rtc_ext_conf_reg_load_rtc_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rtc_ext_conf_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc_ext_conf_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.load_rtc = value; + ret = qca808x_ptp_rtc_ext_conf_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rtc_ext_conf_reg_clear_rtc_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rtc_ext_conf_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc_ext_conf_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.clear_rtc; + return ret; +} + +sw_error_t +qca808x_ptp_rtc_ext_conf_reg_clear_rtc_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rtc_ext_conf_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc_ext_conf_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.clear_rtc = value; + ret = qca808x_ptp_rtc_ext_conf_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rtc_ext_conf_reg_rtc_read_mode_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rtc_ext_conf_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc_ext_conf_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rtc_read_mode; + return ret; +} + +sw_error_t +qca808x_ptp_rtc_ext_conf_reg_rtc_read_mode_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rtc_ext_conf_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc_ext_conf_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rtc_read_mode = value; + ret = qca808x_ptp_rtc_ext_conf_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rtc_ext_conf_reg_select_output_waveform_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rtc_ext_conf_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc_ext_conf_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.select_output_waveform; + return ret; +} + +sw_error_t +qca808x_ptp_rtc_ext_conf_reg_select_output_waveform_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rtc_ext_conf_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc_ext_conf_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.select_output_waveform = value; + ret = qca808x_ptp_rtc_ext_conf_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rtc_ext_conf_reg_set_incval_valid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rtc_ext_conf_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc_ext_conf_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.set_incval_valid; + return ret; +} + +sw_error_t +qca808x_ptp_rtc_ext_conf_reg_set_incval_valid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rtc_ext_conf_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc_ext_conf_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.set_incval_valid = value; + ret = qca808x_ptp_rtc_ext_conf_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rtc_preloaded0_reg_ptp_rtc_preloaded_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rtc_preloaded0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc_preloaded0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_rtc_preloaded_sec; + return ret; +} + +sw_error_t +qca808x_ptp_rtc_preloaded0_reg_ptp_rtc_preloaded_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rtc_preloaded0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc_preloaded0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_rtc_preloaded_sec = value; + ret = qca808x_ptp_rtc_preloaded0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rtc_preloaded1_reg_ptp_rtc_preloaded_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rtc_preloaded1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc_preloaded1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_rtc_preloaded_sec; + return ret; +} + +sw_error_t +qca808x_ptp_rtc_preloaded1_reg_ptp_rtc_preloaded_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rtc_preloaded1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc_preloaded1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_rtc_preloaded_sec = value; + ret = qca808x_ptp_rtc_preloaded1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rtc_preloaded2_reg_ptp_rtc_preloaded_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rtc_preloaded2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc_preloaded2_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_rtc_preloaded_sec; + return ret; +} + +sw_error_t +qca808x_ptp_rtc_preloaded2_reg_ptp_rtc_preloaded_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rtc_preloaded2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc_preloaded2_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_rtc_preloaded_sec = value; + ret = qca808x_ptp_rtc_preloaded2_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rtc_preloaded3_reg_ptp_rtc_preloaded_nisec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rtc_preloaded3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc_preloaded3_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_rtc_preloaded_nisec; + return ret; +} + +sw_error_t +qca808x_ptp_rtc_preloaded3_reg_ptp_rtc_preloaded_nisec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rtc_preloaded3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc_preloaded3_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_rtc_preloaded_nisec = value; + ret = qca808x_ptp_rtc_preloaded3_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rtc_preloaded4_reg_ptp_rtc_preloaded_nisec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rtc_preloaded4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc_preloaded4_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_rtc_preloaded_nisec; + return ret; +} + +sw_error_t +qca808x_ptp_rtc_preloaded4_reg_ptp_rtc_preloaded_nisec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rtc_preloaded4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rtc_preloaded4_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_rtc_preloaded_nisec = value; + ret = qca808x_ptp_rtc_preloaded4_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_gm_conf0_reg_gm_pps_sync_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_gm_conf0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_gm_conf0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.gm_pps_sync; + return ret; +} + +sw_error_t +qca808x_ptp_gm_conf0_reg_gm_pps_sync_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_gm_conf0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_gm_conf0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.gm_pps_sync = value; + ret = qca808x_ptp_gm_conf0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_gm_conf0_reg_gm_pll_mode_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_gm_conf0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_gm_conf0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.gm_pll_mode; + return ret; +} + +sw_error_t +qca808x_ptp_gm_conf0_reg_gm_pll_mode_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_gm_conf0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_gm_conf0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.gm_pll_mode = value; + ret = qca808x_ptp_gm_conf0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_gm_conf0_reg_gm_maxfreq_offset_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_gm_conf0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_gm_conf0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.gm_maxfreq_offset; + return ret; +} + +sw_error_t +qca808x_ptp_gm_conf0_reg_gm_maxfreq_offset_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_gm_conf0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_gm_conf0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.gm_maxfreq_offset = value; + ret = qca808x_ptp_gm_conf0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_gm_conf0_reg_grandmaster_mode_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_gm_conf0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_gm_conf0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.grandmaster_mode; + return ret; +} + +sw_error_t +qca808x_ptp_gm_conf0_reg_grandmaster_mode_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_gm_conf0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_gm_conf0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.grandmaster_mode = value; + ret = qca808x_ptp_gm_conf0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_gm_conf1_reg_gm_kp_ldn_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_gm_conf1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_gm_conf1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.gm_kp_ldn; + return ret; +} + +sw_error_t +qca808x_ptp_gm_conf1_reg_gm_kp_ldn_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_gm_conf1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_gm_conf1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.gm_kp_ldn = value; + ret = qca808x_ptp_gm_conf1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_gm_conf1_reg_gm_ki_ldn_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_gm_conf1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_gm_conf1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.gm_ki_ldn; + return ret; +} + +sw_error_t +qca808x_ptp_gm_conf1_reg_gm_ki_ldn_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_gm_conf1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_gm_conf1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.gm_ki_ldn = value; + ret = qca808x_ptp_gm_conf1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_ppsin_ts0_reg_rx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_ppsin_ts0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_ppsin_ts0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_ts_sec; + return ret; +} + +sw_error_t +qca808x_ptp_ppsin_ts0_reg_rx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_ppsin_ts0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_ppsin_ts0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_ts_sec = value; + ret = qca808x_ptp_ppsin_ts0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_ppsin_ts1_reg_rx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_ppsin_ts1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_ppsin_ts1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_ts_sec; + return ret; +} + +sw_error_t +qca808x_ptp_ppsin_ts1_reg_rx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_ppsin_ts1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_ppsin_ts1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_ts_sec = value; + ret = qca808x_ptp_ppsin_ts1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_ppsin_ts2_reg_rx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_ppsin_ts2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_ppsin_ts2_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_ts_sec; + return ret; +} + +sw_error_t +qca808x_ptp_ppsin_ts2_reg_rx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_ppsin_ts2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_ppsin_ts2_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_ts_sec = value; + ret = qca808x_ptp_ppsin_ts2_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_ppsin_ts3_reg_rx_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_ppsin_ts3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_ppsin_ts3_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_ts_nsec; + return ret; +} + +sw_error_t +qca808x_ptp_ppsin_ts3_reg_rx_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_ppsin_ts3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_ppsin_ts3_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_ts_nsec = value; + ret = qca808x_ptp_ppsin_ts3_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_ppsin_ts4_reg_rx_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_ppsin_ts4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_ppsin_ts4_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_ts_nsec; + return ret; +} + +sw_error_t +qca808x_ptp_ppsin_ts4_reg_rx_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_ppsin_ts4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_ppsin_ts4_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_ts_nsec = value; + ret = qca808x_ptp_ppsin_ts4_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_hwpll_inc0_reg_ptp_rtc_inc_nfs1_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_hwpll_inc0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_hwpll_inc0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_rtc_inc_nfs1; + return ret; +} + +sw_error_t +qca808x_ptp_hwpll_inc0_reg_ptp_rtc_inc_nfs1_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_hwpll_inc0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_hwpll_inc0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_rtc_inc_nfs1 = value; + ret = qca808x_ptp_hwpll_inc0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_hwpll_inc0_reg_ptp_rtc_inc_nis_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_hwpll_inc0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_hwpll_inc0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_rtc_inc_nis; + return ret; +} + +sw_error_t +qca808x_ptp_hwpll_inc0_reg_ptp_rtc_inc_nis_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_hwpll_inc0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_hwpll_inc0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_rtc_inc_nis = value; + ret = qca808x_ptp_hwpll_inc0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_hwpll_inc1_reg_ptp_rtc_inc_nfs0_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_hwpll_inc1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_hwpll_inc1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_rtc_inc_nfs0; + return ret; +} + +sw_error_t +qca808x_ptp_hwpll_inc1_reg_ptp_rtc_inc_nfs0_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_hwpll_inc1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_hwpll_inc1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_rtc_inc_nfs0 = value; + ret = qca808x_ptp_hwpll_inc1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_ppsin_latency_reg_ptp_ppsin_latency_sign_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_ppsin_latency_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_ppsin_latency_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_ppsin_latency_sign; + return ret; +} + +sw_error_t +qca808x_ptp_ppsin_latency_reg_ptp_ppsin_latency_sign_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_ppsin_latency_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_ppsin_latency_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_ppsin_latency_sign = value; + ret = qca808x_ptp_ppsin_latency_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_ppsin_latency_reg_ptp_ppsin_latency_value_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_ppsin_latency_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_ppsin_latency_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ptp_ppsin_latency_value; + return ret; +} + +sw_error_t +qca808x_ptp_ppsin_latency_reg_ptp_ppsin_latency_value_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_ppsin_latency_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_ppsin_latency_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ptp_ppsin_latency_value = value; + ret = qca808x_ptp_ppsin_latency_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_trigger0_config_reg_force_value_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_trigger0_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger0_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.force_value; + return ret; +} + +sw_error_t +qca808x_ptp_trigger0_config_reg_force_value_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_trigger0_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger0_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.force_value = value; + ret = qca808x_ptp_trigger0_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_trigger0_config_reg_pattern_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_trigger0_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger0_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.pattern; + return ret; +} + +sw_error_t +qca808x_ptp_trigger0_config_reg_pattern_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_trigger0_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger0_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pattern = value; + ret = qca808x_ptp_trigger0_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_trigger0_config_reg_status_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_trigger0_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger0_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.status; + return ret; +} + +sw_error_t +qca808x_ptp_trigger0_config_reg_status_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_trigger0_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger0_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.status = value; + ret = qca808x_ptp_trigger0_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_trigger0_config_reg_force_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_trigger0_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger0_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.force_en; + return ret; +} + +sw_error_t +qca808x_ptp_trigger0_config_reg_force_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_trigger0_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger0_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.force_en = value; + ret = qca808x_ptp_trigger0_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_trigger0_config_reg_setting_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_trigger0_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger0_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.setting; + return ret; +} + +sw_error_t +qca808x_ptp_trigger0_config_reg_setting_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_trigger0_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger0_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.setting = value; + ret = qca808x_ptp_trigger0_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_trigger0_config_reg_notify_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_trigger0_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger0_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.notify; + return ret; +} + +sw_error_t +qca808x_ptp_trigger0_config_reg_notify_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_trigger0_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger0_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.notify = value; + ret = qca808x_ptp_trigger0_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_trigger0_config_reg_if_late_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_trigger0_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger0_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.if_late; + return ret; +} + +sw_error_t +qca808x_ptp_trigger0_config_reg_if_late_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_trigger0_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger0_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.if_late = value; + ret = qca808x_ptp_trigger0_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_trigger0_status_reg_error_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_trigger0_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger0_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.error; + return ret; +} + +sw_error_t +qca808x_ptp_trigger0_status_reg_error_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_trigger0_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger0_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.error = value; + ret = qca808x_ptp_trigger0_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_trigger0_status_reg_active_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_trigger0_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger0_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.active; + return ret; +} + +sw_error_t +qca808x_ptp_trigger0_status_reg_active_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_trigger0_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger0_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.active = value; + ret = qca808x_ptp_trigger0_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_trigger0_status_reg_finished_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_trigger0_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger0_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.finished; + return ret; +} + +sw_error_t +qca808x_ptp_trigger0_status_reg_finished_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_trigger0_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger0_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.finished = value; + ret = qca808x_ptp_trigger0_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_trigger1_config_reg_force_value_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_trigger1_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger1_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.force_value; + return ret; +} + +sw_error_t +qca808x_ptp_trigger1_config_reg_force_value_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_trigger1_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger1_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.force_value = value; + ret = qca808x_ptp_trigger1_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_trigger1_config_reg_pattern_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_trigger1_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger1_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.pattern; + return ret; +} + +sw_error_t +qca808x_ptp_trigger1_config_reg_pattern_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_trigger1_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger1_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pattern = value; + ret = qca808x_ptp_trigger1_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_trigger1_config_reg_status_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_trigger1_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger1_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.status; + return ret; +} + +sw_error_t +qca808x_ptp_trigger1_config_reg_status_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_trigger1_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger1_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.status = value; + ret = qca808x_ptp_trigger1_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_trigger1_config_reg_force_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_trigger1_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger1_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.force_en; + return ret; +} + +sw_error_t +qca808x_ptp_trigger1_config_reg_force_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_trigger1_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger1_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.force_en = value; + ret = qca808x_ptp_trigger1_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_trigger1_config_reg_setting_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_trigger1_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger1_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.setting; + return ret; +} + +sw_error_t +qca808x_ptp_trigger1_config_reg_setting_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_trigger1_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger1_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.setting = value; + ret = qca808x_ptp_trigger1_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_trigger1_config_reg_notify_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_trigger1_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger1_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.notify; + return ret; +} + +sw_error_t +qca808x_ptp_trigger1_config_reg_notify_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_trigger1_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger1_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.notify = value; + ret = qca808x_ptp_trigger1_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_trigger1_config_reg_if_late_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_trigger1_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger1_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.if_late; + return ret; +} + +sw_error_t +qca808x_ptp_trigger1_config_reg_if_late_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_trigger1_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger1_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.if_late = value; + ret = qca808x_ptp_trigger1_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_trigger1_status_reg_error_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_trigger1_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger1_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.error; + return ret; +} + +sw_error_t +qca808x_ptp_trigger1_status_reg_error_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_trigger1_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger1_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.error = value; + ret = qca808x_ptp_trigger1_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_trigger1_status_reg_active_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_trigger1_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger1_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.active; + return ret; +} + +sw_error_t +qca808x_ptp_trigger1_status_reg_active_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_trigger1_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger1_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.active = value; + ret = qca808x_ptp_trigger1_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_trigger1_status_reg_finished_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_trigger1_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger1_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.finished; + return ret; +} + +sw_error_t +qca808x_ptp_trigger1_status_reg_finished_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_trigger1_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger1_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.finished = value; + ret = qca808x_ptp_trigger1_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_trigger0_timestamp0_reg_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_trigger0_timestamp0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger0_timestamp0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ts_sec; + return ret; +} + +sw_error_t +qca808x_ptp_trigger0_timestamp0_reg_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_trigger0_timestamp0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger0_timestamp0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ts_sec = value; + ret = qca808x_ptp_trigger0_timestamp0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_trigger0_timestamp1_reg_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_trigger0_timestamp1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger0_timestamp1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ts_sec; + return ret; +} + +sw_error_t +qca808x_ptp_trigger0_timestamp1_reg_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_trigger0_timestamp1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger0_timestamp1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ts_sec = value; + ret = qca808x_ptp_trigger0_timestamp1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_trigger0_timestamp2_reg_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_trigger0_timestamp2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger0_timestamp2_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ts_sec; + return ret; +} + +sw_error_t +qca808x_ptp_trigger0_timestamp2_reg_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_trigger0_timestamp2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger0_timestamp2_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ts_sec = value; + ret = qca808x_ptp_trigger0_timestamp2_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_trigger0_timestamp3_reg_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_trigger0_timestamp3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger0_timestamp3_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ts_nsec; + return ret; +} + +sw_error_t +qca808x_ptp_trigger0_timestamp3_reg_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_trigger0_timestamp3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger0_timestamp3_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ts_nsec = value; + ret = qca808x_ptp_trigger0_timestamp3_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_trigger0_timestamp4_reg_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_trigger0_timestamp4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger0_timestamp4_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ts_nsec; + return ret; +} + +sw_error_t +qca808x_ptp_trigger0_timestamp4_reg_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_trigger0_timestamp4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger0_timestamp4_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ts_nsec = value; + ret = qca808x_ptp_trigger0_timestamp4_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_trigger1_timestamp0_reg_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_trigger1_timestamp0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger1_timestamp0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ts_sec; + return ret; +} + +sw_error_t +qca808x_ptp_trigger1_timestamp0_reg_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_trigger1_timestamp0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger1_timestamp0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ts_sec = value; + ret = qca808x_ptp_trigger1_timestamp0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_trigger1_timestamp1_reg_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_trigger1_timestamp1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger1_timestamp1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ts_sec; + return ret; +} + +sw_error_t +qca808x_ptp_trigger1_timestamp1_reg_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_trigger1_timestamp1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger1_timestamp1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ts_sec = value; + ret = qca808x_ptp_trigger1_timestamp1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_trigger1_timestamp2_reg_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_trigger1_timestamp2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger1_timestamp2_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ts_sec; + return ret; +} + +sw_error_t +qca808x_ptp_trigger1_timestamp2_reg_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_trigger1_timestamp2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger1_timestamp2_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ts_sec = value; + ret = qca808x_ptp_trigger1_timestamp2_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_trigger1_timestamp3_reg_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_trigger1_timestamp3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger1_timestamp3_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ts_nsec; + return ret; +} + +sw_error_t +qca808x_ptp_trigger1_timestamp3_reg_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_trigger1_timestamp3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger1_timestamp3_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ts_nsec = value; + ret = qca808x_ptp_trigger1_timestamp3_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_trigger1_timestamp4_reg_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_trigger1_timestamp4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger1_timestamp4_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ts_nsec; + return ret; +} + +sw_error_t +qca808x_ptp_trigger1_timestamp4_reg_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_trigger1_timestamp4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_trigger1_timestamp4_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ts_nsec = value; + ret = qca808x_ptp_trigger1_timestamp4_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_event0_config_reg_rise_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_event0_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event0_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rise_en; + return ret; +} + +sw_error_t +qca808x_ptp_event0_config_reg_rise_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_event0_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event0_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rise_en = value; + ret = qca808x_ptp_event0_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_event0_config_reg_single_cap_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_event0_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event0_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.single_cap; + return ret; +} + +sw_error_t +qca808x_ptp_event0_config_reg_single_cap_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_event0_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event0_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.single_cap = value; + ret = qca808x_ptp_event0_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_event0_config_reg_fall_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_event0_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event0_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.fall_en; + return ret; +} + +sw_error_t +qca808x_ptp_event0_config_reg_fall_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_event0_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event0_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.fall_en = value; + ret = qca808x_ptp_event0_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_event0_config_reg_notify_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_event0_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event0_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.notify; + return ret; +} + +sw_error_t +qca808x_ptp_event0_config_reg_notify_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_event0_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event0_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.notify = value; + ret = qca808x_ptp_event0_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_event0_config_reg_clear_stat_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_event0_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event0_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.clear_stat; + return ret; +} + +sw_error_t +qca808x_ptp_event0_config_reg_clear_stat_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_event0_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event0_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.clear_stat = value; + ret = qca808x_ptp_event0_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_event0_status_reg_mul_event_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_event0_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event0_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.mul_event; + return ret; +} + +sw_error_t +qca808x_ptp_event0_status_reg_mul_event_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_event0_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event0_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mul_event = value; + ret = qca808x_ptp_event0_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_event0_status_reg_missed_count_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_event0_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event0_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.missed_count; + return ret; +} + +sw_error_t +qca808x_ptp_event0_status_reg_missed_count_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_event0_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event0_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.missed_count = value; + ret = qca808x_ptp_event0_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_event0_status_reg_dir_detected_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_event0_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event0_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.dir_detected; + return ret; +} + +sw_error_t +qca808x_ptp_event0_status_reg_dir_detected_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_event0_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event0_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.dir_detected = value; + ret = qca808x_ptp_event0_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_event0_status_reg_detected_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_event0_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event0_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.detected; + return ret; +} + +sw_error_t +qca808x_ptp_event0_status_reg_detected_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_event0_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event0_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.detected = value; + ret = qca808x_ptp_event0_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_event1_config_reg_rise_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_event1_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event1_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rise_en; + return ret; +} + +sw_error_t +qca808x_ptp_event1_config_reg_rise_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_event1_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event1_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rise_en = value; + ret = qca808x_ptp_event1_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_event1_config_reg_single_cap_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_event1_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event1_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.single_cap; + return ret; +} + +sw_error_t +qca808x_ptp_event1_config_reg_single_cap_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_event1_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event1_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.single_cap = value; + ret = qca808x_ptp_event1_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_event1_config_reg_fall_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_event1_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event1_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.fall_en; + return ret; +} + +sw_error_t +qca808x_ptp_event1_config_reg_fall_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_event1_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event1_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.fall_en = value; + ret = qca808x_ptp_event1_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_event1_config_reg_notify_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_event1_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event1_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.notify; + return ret; +} + +sw_error_t +qca808x_ptp_event1_config_reg_notify_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_event1_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event1_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.notify = value; + ret = qca808x_ptp_event1_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_event1_config_reg_clear_stat_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_event1_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event1_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.clear_stat; + return ret; +} + +sw_error_t +qca808x_ptp_event1_config_reg_clear_stat_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_event1_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event1_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.clear_stat = value; + ret = qca808x_ptp_event1_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_event1_status_reg_mul_event_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_event1_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event1_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.mul_event; + return ret; +} + +sw_error_t +qca808x_ptp_event1_status_reg_mul_event_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_event1_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event1_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mul_event = value; + ret = qca808x_ptp_event1_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_event1_status_reg_missed_count_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_event1_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event1_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.missed_count; + return ret; +} + +sw_error_t +qca808x_ptp_event1_status_reg_missed_count_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_event1_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event1_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.missed_count = value; + ret = qca808x_ptp_event1_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_event1_status_reg_dir_detected_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_event1_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event1_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.dir_detected; + return ret; +} + +sw_error_t +qca808x_ptp_event1_status_reg_dir_detected_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_event1_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event1_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.dir_detected = value; + ret = qca808x_ptp_event1_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_event1_status_reg_detected_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_event1_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event1_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.detected; + return ret; +} + +sw_error_t +qca808x_ptp_event1_status_reg_detected_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_event1_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event1_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.detected = value; + ret = qca808x_ptp_event1_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_event0_timestamp0_reg_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_event0_timestamp0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event0_timestamp0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ts_nsec; + return ret; +} + +sw_error_t +qca808x_ptp_event0_timestamp0_reg_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_event0_timestamp0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event0_timestamp0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ts_nsec = value; + ret = qca808x_ptp_event0_timestamp0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_event0_timestamp1_reg_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_event0_timestamp1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event0_timestamp1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ts_nsec; + return ret; +} + +sw_error_t +qca808x_ptp_event0_timestamp1_reg_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_event0_timestamp1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event0_timestamp1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ts_nsec = value; + ret = qca808x_ptp_event0_timestamp1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_event0_timestamp2_reg_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_event0_timestamp2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event0_timestamp2_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ts_nsec; + return ret; +} + +sw_error_t +qca808x_ptp_event0_timestamp2_reg_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_event0_timestamp2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event0_timestamp2_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ts_nsec = value; + ret = qca808x_ptp_event0_timestamp2_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_event0_timestamp3_reg_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_event0_timestamp3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event0_timestamp3_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ts_nsec; + return ret; +} + +sw_error_t +qca808x_ptp_event0_timestamp3_reg_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_event0_timestamp3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event0_timestamp3_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ts_nsec = value; + ret = qca808x_ptp_event0_timestamp3_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_event0_timestamp4_reg_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_event0_timestamp4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event0_timestamp4_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ts_nsec; + return ret; +} + +sw_error_t +qca808x_ptp_event0_timestamp4_reg_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_event0_timestamp4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event0_timestamp4_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ts_nsec = value; + ret = qca808x_ptp_event0_timestamp4_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_event1_timestamp0_reg_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_event1_timestamp0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event1_timestamp0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ts_nsec; + return ret; +} + +sw_error_t +qca808x_ptp_event1_timestamp0_reg_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_event1_timestamp0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event1_timestamp0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ts_nsec = value; + ret = qca808x_ptp_event1_timestamp0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_event1_timestamp1_reg_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_event1_timestamp1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event1_timestamp1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ts_nsec; + return ret; +} + +sw_error_t +qca808x_ptp_event1_timestamp1_reg_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_event1_timestamp1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event1_timestamp1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ts_nsec = value; + ret = qca808x_ptp_event1_timestamp1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_event1_timestamp2_reg_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_event1_timestamp2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event1_timestamp2_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ts_nsec; + return ret; +} + +sw_error_t +qca808x_ptp_event1_timestamp2_reg_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_event1_timestamp2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event1_timestamp2_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ts_nsec = value; + ret = qca808x_ptp_event1_timestamp2_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_event1_timestamp3_reg_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_event1_timestamp3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event1_timestamp3_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ts_nsec; + return ret; +} + +sw_error_t +qca808x_ptp_event1_timestamp3_reg_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_event1_timestamp3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event1_timestamp3_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ts_nsec = value; + ret = qca808x_ptp_event1_timestamp3_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_event1_timestamp4_reg_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_event1_timestamp4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event1_timestamp4_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ts_nsec; + return ret; +} + +sw_error_t +qca808x_ptp_event1_timestamp4_reg_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_event1_timestamp4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_event1_timestamp4_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ts_nsec = value; + ret = qca808x_ptp_event1_timestamp4_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_seqid1_reg_rx_seqid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_seqid1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_seqid1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_seqid; + return ret; +} + +sw_error_t +qca808x_ptp_rx_seqid1_reg_rx_seqid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_seqid1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_seqid1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_seqid = value; + ret = qca808x_ptp_rx_seqid1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid1_0_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_portid1_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid1_0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_portid; + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid1_0_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_portid1_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid1_0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_portid = value; + ret = qca808x_ptp_rx_portid1_0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid1_1_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_portid1_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid1_1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_portid; + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid1_1_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_portid1_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid1_1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_portid = value; + ret = qca808x_ptp_rx_portid1_1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid1_2_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_portid1_2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid1_2_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_portid; + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid1_2_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_portid1_2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid1_2_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_portid = value; + ret = qca808x_ptp_rx_portid1_2_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid1_3_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_portid1_3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid1_3_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_portid; + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid1_3_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_portid1_3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid1_3_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_portid = value; + ret = qca808x_ptp_rx_portid1_3_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid1_4_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_portid1_4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid1_4_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_portid; + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid1_4_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_portid1_4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid1_4_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_portid = value; + ret = qca808x_ptp_rx_portid1_4_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts1_0_reg_rx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_ts1_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts1_0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_ts_sec; + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts1_0_reg_rx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_ts1_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts1_0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_ts_sec = value; + ret = qca808x_ptp_rx_ts1_0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts1_1_reg_rx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_ts1_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts1_1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_ts_sec; + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts1_1_reg_rx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_ts1_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts1_1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_ts_sec = value; + ret = qca808x_ptp_rx_ts1_1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts1_2_reg_rx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_ts1_2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts1_2_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_ts_sec; + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts1_2_reg_rx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_ts1_2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts1_2_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_ts_sec = value; + ret = qca808x_ptp_rx_ts1_2_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts1_3_reg_rx_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_ts1_3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts1_3_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_ts_nsec; + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts1_3_reg_rx_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_ts1_3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts1_3_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_ts_nsec = value; + ret = qca808x_ptp_rx_ts1_3_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts1_4_reg_rx_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_ts1_4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts1_4_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_ts_nsec; + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts1_4_reg_rx_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_ts1_4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts1_4_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_ts_nsec = value; + ret = qca808x_ptp_rx_ts1_4_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts1_5_reg_rx_ts_nfsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_ts1_5_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts1_5_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_ts_nfsec; + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts1_5_reg_rx_ts_nfsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_ts1_5_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts1_5_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_ts_nfsec = value; + ret = qca808x_ptp_rx_ts1_5_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts1_5_reg_rx_msg_type_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_ts1_5_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts1_5_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_msg_type; + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts1_5_reg_rx_msg_type_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_ts1_5_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts1_5_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_msg_type = value; + ret = qca808x_ptp_rx_ts1_5_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts1_6_reg_rx_ts_nfsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_ts1_6_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts1_6_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_ts_nfsec; + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts1_6_reg_rx_ts_nfsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_ts1_6_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts1_6_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_ts_nfsec = value; + ret = qca808x_ptp_rx_ts1_6_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_seqid2_reg_rx_seqid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_seqid2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_seqid2_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_seqid; + return ret; +} + +sw_error_t +qca808x_ptp_rx_seqid2_reg_rx_seqid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_seqid2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_seqid2_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_seqid = value; + ret = qca808x_ptp_rx_seqid2_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid2_0_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_portid2_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid2_0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_portid; + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid2_0_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_portid2_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid2_0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_portid = value; + ret = qca808x_ptp_rx_portid2_0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid2_1_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_portid2_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid2_1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_portid; + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid2_1_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_portid2_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid2_1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_portid = value; + ret = qca808x_ptp_rx_portid2_1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid2_2_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_portid2_2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid2_2_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_portid; + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid2_2_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_portid2_2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid2_2_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_portid = value; + ret = qca808x_ptp_rx_portid2_2_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid2_3_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_portid2_3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid2_3_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_portid; + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid2_3_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_portid2_3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid2_3_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_portid = value; + ret = qca808x_ptp_rx_portid2_3_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid2_4_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_portid2_4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid2_4_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_portid; + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid2_4_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_portid2_4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid2_4_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_portid = value; + ret = qca808x_ptp_rx_portid2_4_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts2_0_reg_rx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_ts2_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts2_0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_ts_sec; + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts2_0_reg_rx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_ts2_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts2_0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_ts_sec = value; + ret = qca808x_ptp_rx_ts2_0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts2_1_reg_rx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_ts2_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts2_1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_ts_sec; + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts2_1_reg_rx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_ts2_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts2_1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_ts_sec = value; + ret = qca808x_ptp_rx_ts2_1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts2_2_reg_rx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_ts2_2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts2_2_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_ts_sec; + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts2_2_reg_rx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_ts2_2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts2_2_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_ts_sec = value; + ret = qca808x_ptp_rx_ts2_2_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts2_3_reg_rx_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_ts2_3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts2_3_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_ts_nsec; + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts2_3_reg_rx_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_ts2_3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts2_3_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_ts_nsec = value; + ret = qca808x_ptp_rx_ts2_3_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts2_4_reg_rx_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_ts2_4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts2_4_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_ts_nsec; + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts2_4_reg_rx_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_ts2_4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts2_4_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_ts_nsec = value; + ret = qca808x_ptp_rx_ts2_4_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts2_5_reg_rx_ts_nfsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_ts2_5_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts2_5_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_ts_nfsec; + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts2_5_reg_rx_ts_nfsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_ts2_5_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts2_5_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_ts_nfsec = value; + ret = qca808x_ptp_rx_ts2_5_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts2_5_reg_rx_msg_type_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_ts2_5_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts2_5_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_msg_type; + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts2_5_reg_rx_msg_type_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_ts2_5_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts2_5_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_msg_type = value; + ret = qca808x_ptp_rx_ts2_5_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts2_6_reg_rx_ts_nfsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_ts2_6_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts2_6_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_ts_nfsec; + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts2_6_reg_rx_ts_nfsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_ts2_6_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts2_6_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_ts_nfsec = value; + ret = qca808x_ptp_rx_ts2_6_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_seqid3_reg_rx_seqid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_seqid3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_seqid3_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_seqid; + return ret; +} + +sw_error_t +qca808x_ptp_rx_seqid3_reg_rx_seqid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_seqid3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_seqid3_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_seqid = value; + ret = qca808x_ptp_rx_seqid3_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid3_0_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_portid3_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid3_0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_portid; + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid3_0_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_portid3_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid3_0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_portid = value; + ret = qca808x_ptp_rx_portid3_0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid3_1_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_portid3_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid3_1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_portid; + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid3_1_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_portid3_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid3_1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_portid = value; + ret = qca808x_ptp_rx_portid3_1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid3_2_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_portid3_2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid3_2_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_portid; + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid3_2_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_portid3_2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid3_2_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_portid = value; + ret = qca808x_ptp_rx_portid3_2_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid3_3_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_portid3_3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid3_3_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_portid; + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid3_3_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_portid3_3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid3_3_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_portid = value; + ret = qca808x_ptp_rx_portid3_3_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid3_4_reg_rx_portid_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_portid3_4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid3_4_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_portid; + return ret; +} + +sw_error_t +qca808x_ptp_rx_portid3_4_reg_rx_portid_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_portid3_4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_portid3_4_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_portid = value; + ret = qca808x_ptp_rx_portid3_4_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts3_0_reg_rx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_ts3_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts3_0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_ts_sec; + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts3_0_reg_rx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_ts3_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts3_0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_ts_sec = value; + ret = qca808x_ptp_rx_ts3_0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts3_1_reg_rx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_ts3_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts3_1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_ts_sec; + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts3_1_reg_rx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_ts3_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts3_1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_ts_sec = value; + ret = qca808x_ptp_rx_ts3_1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts3_2_reg_rx_ts_sec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_ts3_2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts3_2_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_ts_sec; + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts3_2_reg_rx_ts_sec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_ts3_2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts3_2_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_ts_sec = value; + ret = qca808x_ptp_rx_ts3_2_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts3_3_reg_rx_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_ts3_3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts3_3_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_ts_nsec; + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts3_3_reg_rx_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_ts3_3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts3_3_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_ts_nsec = value; + ret = qca808x_ptp_rx_ts3_3_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts3_4_reg_rx_ts_nsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_ts3_4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts3_4_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_ts_nsec; + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts3_4_reg_rx_ts_nsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_ts3_4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts3_4_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_ts_nsec = value; + ret = qca808x_ptp_rx_ts3_4_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts3_5_reg_rx_ts_nfsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_ts3_5_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts3_5_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_ts_nfsec; + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts3_5_reg_rx_ts_nfsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_ts3_5_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts3_5_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_ts_nfsec = value; + ret = qca808x_ptp_rx_ts3_5_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts3_5_reg_rx_msg_type_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_ts3_5_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts3_5_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_msg_type; + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts3_5_reg_rx_msg_type_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_ts3_5_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts3_5_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_msg_type = value; + ret = qca808x_ptp_rx_ts3_5_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts3_6_reg_rx_ts_nfsec_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_ts3_6_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts3_6_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_ts_nfsec; + return ret; +} + +sw_error_t +qca808x_ptp_rx_ts3_6_reg_rx_ts_nfsec_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_ts3_6_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_ts3_6_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_ts_nfsec = value; + ret = qca808x_ptp_rx_ts3_6_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_phase_adjust_0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_phase_adjust_0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_PHASE_ADJUST_0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_phase_adjust_0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_phase_adjust_0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_PHASE_ADJUST_0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_phase_adjust_0_reg_phase_value_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_phase_adjust_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_phase_adjust_0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.phase_value; + return ret; +} + +sw_error_t +qca808x_ptp_phase_adjust_0_reg_phase_value_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_phase_adjust_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_phase_adjust_0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.phase_value = value; + ret = qca808x_ptp_phase_adjust_0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_phase_adjust_1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_phase_adjust_1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_PHASE_ADJUST_1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_phase_adjust_1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_phase_adjust_1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_PHASE_ADJUST_1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_phase_adjust_1_reg_phase_value_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_phase_adjust_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_phase_adjust_1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.phase_value; + return ret; +} + +sw_error_t +qca808x_ptp_phase_adjust_1_reg_phase_value_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_phase_adjust_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_phase_adjust_1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.phase_value = value; + ret = qca808x_ptp_phase_adjust_1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_pps_pul_width_0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_pps_pul_width_0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_PPS_PUL_WIDTH_0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_pps_pul_width_0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_pps_pul_width_0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_PPS_PUL_WIDTH_0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_pps_pul_width_0_reg_pul_value_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_pps_pul_width_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_pps_pul_width_0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.pul_value; + return ret; +} + +sw_error_t +qca808x_ptp_pps_pul_width_0_reg_pul_value_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_pps_pul_width_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_pps_pul_width_0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pul_value = value; + ret = qca808x_ptp_pps_pul_width_0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_pps_pul_width_1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_pps_pul_width_1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_PPS_PUL_WIDTH_1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_pps_pul_width_1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_pps_pul_width_1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_PPS_PUL_WIDTH_1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_pps_pul_width_1_reg_pul_value_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_pps_pul_width_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_pps_pul_width_1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.pul_value; + return ret; +} + +sw_error_t +qca808x_ptp_pps_pul_width_1_reg_pul_value_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_pps_pul_width_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_pps_pul_width_1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pul_value = value; + ret = qca808x_ptp_pps_pul_width_1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + + +sw_error_t +qca808x_ptp_freq_waveform_period_0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_freq_waveform_period_0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_FREQ_WAVEFORM_PERIOD_0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_freq_waveform_period_0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_freq_waveform_period_0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_FREQ_WAVEFORM_PERIOD_0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_freq_waveform_period_0_reg_wave_period_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_freq_waveform_period_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_freq_waveform_period_0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.wave_period; + return ret; +} + +sw_error_t +qca808x_ptp_freq_waveform_period_0_reg_wave_period_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_freq_waveform_period_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_freq_waveform_period_0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.wave_period = value; + ret = qca808x_ptp_freq_waveform_period_0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_freq_waveform_period_0_reg_phase_ali_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_freq_waveform_period_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_freq_waveform_period_0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.phase_ali; + return ret; +} + +sw_error_t +qca808x_ptp_freq_waveform_period_0_reg_phase_ali_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_freq_waveform_period_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_freq_waveform_period_0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.phase_ali = value; + ret = qca808x_ptp_freq_waveform_period_0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_freq_waveform_period_1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_freq_waveform_period_1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_FREQ_WAVEFORM_PERIOD_1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_freq_waveform_period_1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_freq_waveform_period_1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_FREQ_WAVEFORM_PERIOD_1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_freq_waveform_period_1_reg_wave_period_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_freq_waveform_period_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_freq_waveform_period_1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.wave_period; + return ret; +} + +sw_error_t +qca808x_ptp_freq_waveform_period_1_reg_wave_period_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_freq_waveform_period_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_freq_waveform_period_1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.wave_period = value; + ret = qca808x_ptp_freq_waveform_period_1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_freq_waveform_period_2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_freq_waveform_period_2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_FREQ_WAVEFORM_PERIOD_2_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_freq_waveform_period_2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_freq_waveform_period_2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_FREQ_WAVEFORM_PERIOD_2_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_freq_waveform_period_2_reg_wave_period_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_freq_waveform_period_2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_freq_waveform_period_2_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.wave_period; + return ret; +} + +sw_error_t +qca808x_ptp_freq_waveform_period_2_reg_wave_period_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_freq_waveform_period_2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_freq_waveform_period_2_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.wave_period = value; + ret = qca808x_ptp_freq_waveform_period_2_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_ts_ctrl_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_COM_TS_CTRL_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_ts_ctrl_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_COM_TS_CTRL_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_filt_mac_da0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_mac_da0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_FILT_MAC_DA0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_filt_mac_da0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_mac_da0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_FILT_MAC_DA0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_filt_mac_da1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_mac_da1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_FILT_MAC_DA1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_filt_mac_da1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_mac_da1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_FILT_MAC_DA1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_filt_mac_da2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_mac_da2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_FILT_MAC_DA2_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_filt_mac_da2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_mac_da2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_FILT_MAC_DA2_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_filt_ipv4_da0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv4_da0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_FILT_IPV4_DA0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_filt_ipv4_da0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv4_da0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_FILT_IPV4_DA0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_filt_ipv4_da1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv4_da1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_FILT_IPV4_DA1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_filt_ipv4_da1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv4_da1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_FILT_IPV4_DA1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv6_da0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_FILT_IPV6_DA0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv6_da0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_FILT_IPV6_DA0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv6_da1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_FILT_IPV6_DA1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv6_da1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_FILT_IPV6_DA1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv6_da2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_FILT_IPV6_DA2_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv6_da2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_FILT_IPV6_DA2_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv6_da3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_FILT_IPV6_DA3_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv6_da3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_FILT_IPV6_DA3_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv6_da4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_FILT_IPV6_DA4_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv6_da4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_FILT_IPV6_DA4_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da5_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv6_da5_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_FILT_IPV6_DA5_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da5_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv6_da5_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_FILT_IPV6_DA5_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da6_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv6_da6_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_FILT_IPV6_DA6_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da6_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv6_da6_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_FILT_IPV6_DA6_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da7_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv6_da7_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_FILT_IPV6_DA7_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da7_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_ipv6_da7_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_FILT_IPV6_DA7_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_filt_mac_lengthtype_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_mac_lengthtype_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_FILT_MAC_LENGTHTYPE_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_filt_mac_lengthtype_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_mac_lengthtype_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_FILT_MAC_LENGTHTYPE_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_filt_layer4_protocol_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_layer4_protocol_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_FILT_LAYER4_PROTOCOL_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_filt_layer4_protocol_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_layer4_protocol_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_FILT_LAYER4_PROTOCOL_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_filt_udp_port_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_udp_port_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_FILT_UDP_PORT_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_filt_udp_port_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_filt_udp_port_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_FILT_UDP_PORT_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_ts_status_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_COM_TS_STATUS_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_ts_status_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_COM_TS_STATUS_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_com_timestamp0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_COM_TIMESTAMP0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_com_timestamp0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_COM_TIMESTAMP0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_com_timestamp1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_COM_TIMESTAMP1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_com_timestamp1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_COM_TIMESTAMP1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_com_timestamp2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_COM_TIMESTAMP2_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_com_timestamp2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_COM_TIMESTAMP2_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_com_timestamp3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_COM_TIMESTAMP3_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_com_timestamp3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_COM_TIMESTAMP3_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_com_timestamp4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_COM_TIMESTAMP4_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_com_timestamp4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_COM_TIMESTAMP4_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_com_frac_nano_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_frac_nano_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_COM_FRAC_NANO_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_com_frac_nano_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_frac_nano_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_COM_FRAC_NANO_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp_pre0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_COM_TIMESTAMP_PRE0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp_pre0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_COM_TIMESTAMP_PRE0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp_pre1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_COM_TIMESTAMP_PRE1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp_pre1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_COM_TIMESTAMP_PRE1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp_pre2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_COM_TIMESTAMP_PRE2_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp_pre2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_COM_TIMESTAMP_PRE2_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp_pre3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_COM_TIMESTAMP_PRE3_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp_pre3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_COM_TIMESTAMP_PRE3_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp_pre4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_COM_TIMESTAMP_PRE4_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_timestamp_pre4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_COM_TIMESTAMP_PRE4_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_com_frac_nano_pre_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_frac_nano_pre_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_COM_FRAC_NANO_PRE_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_com_frac_nano_pre_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_frac_nano_pre_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_COM_FRAC_NANO_PRE_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_y1731_identify_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_y1731_identify_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_Y1731_IDENTIFY_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_y1731_identify_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_y1731_identify_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_Y1731_IDENTIFY_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_y1731_identify_pre_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_y1731_identify_pre_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_Y1731_IDENTIFY_PRE_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_y1731_identify_pre_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_y1731_identify_pre_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_Y1731_IDENTIFY_PRE_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_com_ts_ctrl_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_COM_TS_CTRL_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_com_ts_ctrl_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_COM_TS_CTRL_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_filt_mac_da0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_mac_da0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_FILT_MAC_DA0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_filt_mac_da0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_mac_da0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_FILT_MAC_DA0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_filt_mac_da1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_mac_da1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_FILT_MAC_DA1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_filt_mac_da1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_mac_da1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_FILT_MAC_DA1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_filt_mac_da2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_mac_da2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_FILT_MAC_DA2_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_filt_mac_da2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_mac_da2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_FILT_MAC_DA2_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_filt_ipv4_da0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv4_da0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_FILT_IPV4_DA0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_filt_ipv4_da0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv4_da0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_FILT_IPV4_DA0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_filt_ipv4_da1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv4_da1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_FILT_IPV4_DA1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_filt_ipv4_da1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv4_da1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_FILT_IPV4_DA1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv6_da0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_FILT_IPV6_DA0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv6_da0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_FILT_IPV6_DA0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv6_da1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_FILT_IPV6_DA1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv6_da1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_FILT_IPV6_DA1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv6_da2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_FILT_IPV6_DA2_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv6_da2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_FILT_IPV6_DA2_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv6_da3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_FILT_IPV6_DA3_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv6_da3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_FILT_IPV6_DA3_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv6_da4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_FILT_IPV6_DA4_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv6_da4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_FILT_IPV6_DA4_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da5_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv6_da5_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_FILT_IPV6_DA5_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da5_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv6_da5_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_FILT_IPV6_DA5_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da6_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv6_da6_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_FILT_IPV6_DA6_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da6_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv6_da6_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_FILT_IPV6_DA6_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da7_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv6_da7_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_FILT_IPV6_DA7_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da7_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_ipv6_da7_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_FILT_IPV6_DA7_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_filt_mac_lengthtype_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_mac_lengthtype_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_FILT_MAC_LENGTHTYPE_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_filt_mac_lengthtype_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_mac_lengthtype_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_FILT_MAC_LENGTHTYPE_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_filt_layer4_protocol_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_layer4_protocol_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_FILT_LAYER4_PROTOCOL_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_filt_layer4_protocol_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_layer4_protocol_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_FILT_LAYER4_PROTOCOL_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_filt_udp_port_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_udp_port_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_FILT_UDP_PORT_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_filt_udp_port_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_filt_udp_port_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_FILT_UDP_PORT_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_com_ts_status_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_COM_TS_STATUS_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_com_ts_status_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_COM_TS_STATUS_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_com_timestamp0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_com_timestamp0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_COM_TIMESTAMP0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_com_timestamp0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_com_timestamp0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_COM_TIMESTAMP0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_com_timestamp1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_com_timestamp1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_COM_TIMESTAMP1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_com_timestamp1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_com_timestamp1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_COM_TIMESTAMP1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_com_timestamp2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_com_timestamp2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_COM_TIMESTAMP2_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_com_timestamp2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_com_timestamp2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_COM_TIMESTAMP2_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_com_timestamp3_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_com_timestamp3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_COM_TIMESTAMP3_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_com_timestamp3_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_com_timestamp3_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_COM_TIMESTAMP3_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_com_timestamp4_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_com_timestamp4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_COM_TIMESTAMP4_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_com_timestamp4_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_com_timestamp4_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_COM_TIMESTAMP4_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_com_frac_nano_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_com_frac_nano_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_COM_FRAC_NANO_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_com_frac_nano_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_com_frac_nano_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_COM_FRAC_NANO_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_y1731_identify_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_y1731_identify_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_Y1731_IDENTIFY_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_y1731_identify_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_y1731_identify_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_Y1731_IDENTIFY_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_y1731_dm_control_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_y1731_dm_control_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_Y1731_DM_CONTROL_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_y1731_dm_control_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_y1731_dm_control_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_Y1731_DM_CONTROL_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_com_ts_status_pre_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_ts_status_pre_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_COM_TS_STATUS_PRE_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_com_ts_status_pre_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_com_ts_status_pre_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_COM_TS_STATUS_PRE_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_baud_config_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_baud_config_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_BAUD_CONFIG_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_baud_config_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_baud_config_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_BAUD_CONFIG_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_uart_configuration_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_uart_configuration_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_UART_CONFIGURATION_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_uart_configuration_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_uart_configuration_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_UART_CONFIGURATION_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_reset_buffer_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_reset_buffer_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RESET_BUFFER_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_reset_buffer_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_reset_buffer_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RESET_BUFFER_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_buffer_status_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_buffer_status_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_BUFFER_STATUS_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_buffer_status_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_buffer_status_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_BUFFER_STATUS_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_tx_buffer_write_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_buffer_write_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_BUFFER_WRITE_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_tx_buffer_write_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_tx_buffer_write_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_TX_BUFFER_WRITE_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_buffer_read_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_buffer_read_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_BUFFER_READ_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_rx_buffer_read_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_rx_buffer_read_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_RX_BUFFER_READ_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_ipv4_da_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ipv4_da_en; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_ipv4_da_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv4_da_en = value; + ret = qca808x_ptp_rx_com_ts_ctrl_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_mac_lengthtype_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.mac_lengthtype_en; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_mac_lengthtype_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_lengthtype_en = value; + ret = qca808x_ptp_rx_com_ts_ctrl_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_y1731_da_chk_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.y1731_da_chk_en; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_y1731_da_chk_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.y1731_da_chk_en = value; + ret = qca808x_ptp_rx_com_ts_ctrl_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_pw_mac_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.pw_mac_en; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_pw_mac_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pw_mac_en = value; + ret = qca808x_ptp_rx_com_ts_ctrl_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_udp_ptp_event_filt_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.udp_ptp_event_filt_en; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_udp_ptp_event_filt_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udp_ptp_event_filt_en = value; + ret = qca808x_ptp_rx_com_ts_ctrl_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_udp_dport_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.udp_dport_en; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_udp_dport_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udp_dport_en = value; + ret = qca808x_ptp_rx_com_ts_ctrl_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_mac_ptp_filt_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.mac_ptp_filt_en; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_mac_ptp_filt_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_ptp_filt_en = value; + ret = qca808x_ptp_rx_com_ts_ctrl_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_ipv6_da_filt_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ipv6_da_filt_en; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_ipv6_da_filt_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv6_da_filt_en = value; + ret = qca808x_ptp_rx_com_ts_ctrl_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_ipv6_next_header_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ipv6_next_header_en; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_ipv6_next_header_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv6_next_header_en = value; + ret = qca808x_ptp_rx_com_ts_ctrl_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_ipv4_layer4_protocol_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ipv4_layer4_protocol_en; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_ipv4_layer4_protocol_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv4_layer4_protocol_en = value; + ret = qca808x_ptp_rx_com_ts_ctrl_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_y1731_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.y1731_en; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_y1731_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.y1731_en = value; + ret = qca808x_ptp_rx_com_ts_ctrl_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_filt_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.filt_en; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_filt_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.filt_en = value; + ret = qca808x_ptp_rx_com_ts_ctrl_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_ipv6_ptp_filt_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ipv6_ptp_filt_en; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_ipv6_ptp_filt_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv6_ptp_filt_en = value; + ret = qca808x_ptp_rx_com_ts_ctrl_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_ipv4_ptp_filt_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ipv4_ptp_filt_en; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_ipv4_ptp_filt_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv4_ptp_filt_en = value; + ret = qca808x_ptp_rx_com_ts_ctrl_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_y1731_insert_ts_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.y1731_insert_ts_en; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_y1731_insert_ts_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.y1731_insert_ts_en = value; + ret = qca808x_ptp_rx_com_ts_ctrl_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_mac_da_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.mac_da_en; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_ctrl_reg_mac_da_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_da_en = value; + ret = qca808x_ptp_rx_com_ts_ctrl_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_filt_mac_da0_reg_mac_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_filt_mac_da0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_filt_mac_da0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.mac_addr; + return ret; +} + +sw_error_t +qca808x_ptp_rx_filt_mac_da0_reg_mac_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_filt_mac_da0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_filt_mac_da0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_addr = value; + ret = qca808x_ptp_rx_filt_mac_da0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_filt_mac_da1_reg_mac_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_filt_mac_da1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_filt_mac_da1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.mac_addr; + return ret; +} + +sw_error_t +qca808x_ptp_rx_filt_mac_da1_reg_mac_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_filt_mac_da1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_filt_mac_da1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_addr = value; + ret = qca808x_ptp_rx_filt_mac_da1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_filt_mac_da2_reg_mac_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_filt_mac_da2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_filt_mac_da2_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.mac_addr; + return ret; +} + +sw_error_t +qca808x_ptp_rx_filt_mac_da2_reg_mac_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_filt_mac_da2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_filt_mac_da2_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_addr = value; + ret = qca808x_ptp_rx_filt_mac_da2_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_filt_ipv4_da0_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_filt_ipv4_da0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_filt_ipv4_da0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ip_addr; + return ret; +} + +sw_error_t +qca808x_ptp_rx_filt_ipv4_da0_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_filt_ipv4_da0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_filt_ipv4_da0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_addr = value; + ret = qca808x_ptp_rx_filt_ipv4_da0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_filt_ipv4_da1_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_filt_ipv4_da1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_filt_ipv4_da1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ip_addr; + return ret; +} + +sw_error_t +qca808x_ptp_rx_filt_ipv4_da1_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_filt_ipv4_da1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_filt_ipv4_da1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_addr = value; + ret = qca808x_ptp_rx_filt_ipv4_da1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da0_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_filt_ipv6_da0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_filt_ipv6_da0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ip_addr; + return ret; +} + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da0_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_filt_ipv6_da0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_filt_ipv6_da0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_addr = value; + ret = qca808x_ptp_rx_filt_ipv6_da0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da1_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_filt_ipv6_da1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_filt_ipv6_da1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ip_addr; + return ret; +} + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da1_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_filt_ipv6_da1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_filt_ipv6_da1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_addr = value; + ret = qca808x_ptp_rx_filt_ipv6_da1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da2_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_filt_ipv6_da2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_filt_ipv6_da2_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ip_addr; + return ret; +} + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da2_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_filt_ipv6_da2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_filt_ipv6_da2_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_addr = value; + ret = qca808x_ptp_rx_filt_ipv6_da2_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da3_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_filt_ipv6_da3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_filt_ipv6_da3_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ip_addr; + return ret; +} + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da3_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_filt_ipv6_da3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_filt_ipv6_da3_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_addr = value; + ret = qca808x_ptp_rx_filt_ipv6_da3_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da4_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_filt_ipv6_da4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_filt_ipv6_da4_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ip_addr; + return ret; +} + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da4_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_filt_ipv6_da4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_filt_ipv6_da4_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_addr = value; + ret = qca808x_ptp_rx_filt_ipv6_da4_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da5_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_filt_ipv6_da5_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_filt_ipv6_da5_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ip_addr; + return ret; +} + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da5_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_filt_ipv6_da5_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_filt_ipv6_da5_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_addr = value; + ret = qca808x_ptp_rx_filt_ipv6_da5_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da6_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_filt_ipv6_da6_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_filt_ipv6_da6_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ip_addr; + return ret; +} + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da6_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_filt_ipv6_da6_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_filt_ipv6_da6_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_addr = value; + ret = qca808x_ptp_rx_filt_ipv6_da6_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da7_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_filt_ipv6_da7_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_filt_ipv6_da7_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ip_addr; + return ret; +} + +sw_error_t +qca808x_ptp_rx_filt_ipv6_da7_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_filt_ipv6_da7_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_filt_ipv6_da7_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_addr = value; + ret = qca808x_ptp_rx_filt_ipv6_da7_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_filt_mac_lengthtype_reg_length_type_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_filt_mac_lengthtype_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_filt_mac_lengthtype_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.length_type; + return ret; +} + +sw_error_t +qca808x_ptp_rx_filt_mac_lengthtype_reg_length_type_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_filt_mac_lengthtype_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_filt_mac_lengthtype_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.length_type = value; + ret = qca808x_ptp_rx_filt_mac_lengthtype_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_filt_layer4_protocol_reg_l4_protocol_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_filt_layer4_protocol_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_filt_layer4_protocol_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.l4_protocol; + return ret; +} + +sw_error_t +qca808x_ptp_rx_filt_layer4_protocol_reg_l4_protocol_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_filt_layer4_protocol_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_filt_layer4_protocol_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l4_protocol = value; + ret = qca808x_ptp_rx_filt_layer4_protocol_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_filt_udp_port_reg_udp_port_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_filt_udp_port_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_filt_udp_port_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.udp_port; + return ret; +} + +sw_error_t +qca808x_ptp_rx_filt_udp_port_reg_udp_port_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_filt_udp_port_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_filt_udp_port_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udp_port = value; + ret = qca808x_ptp_rx_filt_udp_port_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_mac_ptp_pdelay_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.mac_ptp_pdelay_addr; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_mac_ptp_pdelay_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_ptp_pdelay_addr = value; + ret = qca808x_ptp_rx_com_ts_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_mac_da_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.mac_da; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_mac_da_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_da = value; + ret = qca808x_ptp_rx_com_ts_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_ipv4_ptp_pdelay_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ipv4_ptp_pdelay_addr; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_ipv4_ptp_pdelay_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv4_ptp_pdelay_addr = value; + ret = qca808x_ptp_rx_com_ts_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_mac_lengthtype_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.mac_lengthtype; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_mac_lengthtype_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_lengthtype = value; + ret = qca808x_ptp_rx_com_ts_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_udp_dport_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.udp_dport; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_udp_dport_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udp_dport = value; + ret = qca808x_ptp_rx_com_ts_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_ipv4_layer4_protocol_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ipv4_layer4_protocol; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_ipv4_layer4_protocol_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv4_layer4_protocol = value; + ret = qca808x_ptp_rx_com_ts_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_udp_ptp_event_dport_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.udp_ptp_event_dport; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_udp_ptp_event_dport_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udp_ptp_event_dport = value; + ret = qca808x_ptp_rx_com_ts_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_ipv6_da_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ipv6_da; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_ipv6_da_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv6_da = value; + ret = qca808x_ptp_rx_com_ts_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_ipv4_ptp_prim_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ipv4_ptp_prim_addr; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_ipv4_ptp_prim_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv4_ptp_prim_addr = value; + ret = qca808x_ptp_rx_com_ts_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_ipv4_da_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ipv4_da; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_ipv4_da_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv4_da = value; + ret = qca808x_ptp_rx_com_ts_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_ipv6_ptp_pdelay_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ipv6_ptp_pdelay_addr; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_ipv6_ptp_pdelay_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv6_ptp_pdelay_addr = value; + ret = qca808x_ptp_rx_com_ts_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_ipv6_ptp_prim_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ipv6_ptp_prim_addr; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_ipv6_ptp_prim_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv6_ptp_prim_addr = value; + ret = qca808x_ptp_rx_com_ts_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_ipv6_next_header_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ipv6_next_header; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_ipv6_next_header_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv6_next_header = value; + ret = qca808x_ptp_rx_com_ts_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_y1731_mach_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.y1731_mach; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_y1731_mach_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.y1731_mach = value; + ret = qca808x_ptp_rx_com_ts_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_mac_ptp_prim_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.mac_ptp_prim_addr; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_ts_status_reg_mac_ptp_prim_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_ptp_prim_addr = value; + ret = qca808x_ptp_rx_com_ts_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_timestamp0_reg_com_ts_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_timestamp0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_timestamp0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.com_ts; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_timestamp0_reg_com_ts_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_timestamp0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_timestamp0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.com_ts = value; + ret = qca808x_ptp_rx_com_timestamp0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_timestamp1_reg_com_ts_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_timestamp1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_timestamp1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.com_ts; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_timestamp1_reg_com_ts_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_timestamp1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_timestamp1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.com_ts = value; + ret = qca808x_ptp_rx_com_timestamp1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_timestamp2_reg_com_ts_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_timestamp2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_timestamp2_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.com_ts; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_timestamp2_reg_com_ts_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_timestamp2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_timestamp2_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.com_ts = value; + ret = qca808x_ptp_rx_com_timestamp2_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_timestamp3_reg_com_ts_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_timestamp3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_timestamp3_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.com_ts; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_timestamp3_reg_com_ts_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_timestamp3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_timestamp3_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.com_ts = value; + ret = qca808x_ptp_rx_com_timestamp3_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_timestamp4_reg_com_ts_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_timestamp4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_timestamp4_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.com_ts; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_timestamp4_reg_com_ts_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_timestamp4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_timestamp4_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.com_ts = value; + ret = qca808x_ptp_rx_com_timestamp4_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_frac_nano_reg_frac_nano_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_frac_nano_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_frac_nano_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.frac_nano; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_frac_nano_reg_frac_nano_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_frac_nano_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_frac_nano_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.frac_nano = value; + ret = qca808x_ptp_rx_com_frac_nano_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre0_reg_com_ts_pre_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_timestamp_pre0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_timestamp_pre0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.com_ts_pre; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre0_reg_com_ts_pre_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_timestamp_pre0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_timestamp_pre0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.com_ts_pre = value; + ret = qca808x_ptp_rx_com_timestamp_pre0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre1_reg_com_ts_pre_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_timestamp_pre1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_timestamp_pre1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.com_ts_pre; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre1_reg_com_ts_pre_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_timestamp_pre1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_timestamp_pre1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.com_ts_pre = value; + ret = qca808x_ptp_rx_com_timestamp_pre1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre2_reg_com_ts_pre_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_timestamp_pre2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_timestamp_pre2_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.com_ts_pre; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre2_reg_com_ts_pre_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_timestamp_pre2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_timestamp_pre2_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.com_ts_pre = value; + ret = qca808x_ptp_rx_com_timestamp_pre2_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre3_reg_com_ts_pre_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_timestamp_pre3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_timestamp_pre3_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.com_ts_pre; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre3_reg_com_ts_pre_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_timestamp_pre3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_timestamp_pre3_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.com_ts_pre = value; + ret = qca808x_ptp_rx_com_timestamp_pre3_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre4_reg_com_ts_pre_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_timestamp_pre4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_timestamp_pre4_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.com_ts_pre; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_timestamp_pre4_reg_com_ts_pre_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_timestamp_pre4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_timestamp_pre4_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.com_ts_pre = value; + ret = qca808x_ptp_rx_com_timestamp_pre4_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_frac_nano_pre_reg_frac_nano_pre_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_com_frac_nano_pre_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_frac_nano_pre_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.frac_nano_pre; + return ret; +} + +sw_error_t +qca808x_ptp_rx_com_frac_nano_pre_reg_frac_nano_pre_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_com_frac_nano_pre_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_com_frac_nano_pre_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.frac_nano_pre = value; + ret = qca808x_ptp_rx_com_frac_nano_pre_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_y1731_identify_reg_identify_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_y1731_identify_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_y1731_identify_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.identify; + return ret; +} + +sw_error_t +qca808x_ptp_rx_y1731_identify_reg_identify_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_y1731_identify_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_y1731_identify_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.identify = value; + ret = qca808x_ptp_rx_y1731_identify_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_y1731_identify_pre_reg_identify_pre_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_y1731_identify_pre_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_y1731_identify_pre_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.identify_pre; + return ret; +} + +sw_error_t +qca808x_ptp_rx_y1731_identify_pre_reg_identify_pre_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_y1731_identify_pre_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_y1731_identify_pre_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.identify_pre = value; + ret = qca808x_ptp_rx_y1731_identify_pre_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_ipv4_da_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ipv4_da_en; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_ipv4_da_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv4_da_en = value; + ret = qca808x_ptp_tx_com_ts_ctrl_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_mac_lengthtype_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.mac_lengthtype_en; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_mac_lengthtype_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_lengthtype_en = value; + ret = qca808x_ptp_tx_com_ts_ctrl_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_ipv6_da_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ipv6_da_en; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_ipv6_da_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv6_da_en = value; + ret = qca808x_ptp_tx_com_ts_ctrl_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_pw_mac_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.pw_mac_en; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_pw_mac_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.pw_mac_en = value; + ret = qca808x_ptp_tx_com_ts_ctrl_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_udp_ptp_event_filt_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.udp_ptp_event_filt_en; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_udp_ptp_event_filt_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udp_ptp_event_filt_en = value; + ret = qca808x_ptp_tx_com_ts_ctrl_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_udp_dport_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.udp_dport_en; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_udp_dport_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udp_dport_en = value; + ret = qca808x_ptp_tx_com_ts_ctrl_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_mac_ptp_filt_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.mac_ptp_filt_en; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_mac_ptp_filt_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_ptp_filt_en = value; + ret = qca808x_ptp_tx_com_ts_ctrl_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_ipv6_next_header_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ipv6_next_header_en; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_ipv6_next_header_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv6_next_header_en = value; + ret = qca808x_ptp_tx_com_ts_ctrl_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_ipv4_layer4_protocol_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ipv4_layer4_protocol_en; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_ipv4_layer4_protocol_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv4_layer4_protocol_en = value; + ret = qca808x_ptp_tx_com_ts_ctrl_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_y1731_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.y1731_en; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_y1731_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.y1731_en = value; + ret = qca808x_ptp_tx_com_ts_ctrl_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_filt_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.filt_en; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_filt_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.filt_en = value; + ret = qca808x_ptp_tx_com_ts_ctrl_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_ipv6_ptp_filt_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ipv6_ptp_filt_en; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_ipv6_ptp_filt_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv6_ptp_filt_en = value; + ret = qca808x_ptp_tx_com_ts_ctrl_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_ipv4_ptp_filt_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ipv4_ptp_filt_en; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_ipv4_ptp_filt_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv4_ptp_filt_en = value; + ret = qca808x_ptp_tx_com_ts_ctrl_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_y1731_insert_ts_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.y1731_insert_ts_en; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_y1731_insert_ts_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.y1731_insert_ts_en = value; + ret = qca808x_ptp_tx_com_ts_ctrl_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_mac_da_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.mac_da_en; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_mac_da_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_da_en = value; + ret = qca808x_ptp_tx_com_ts_ctrl_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_y1731_sa_chk_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.y1731_sa_chk_en; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_ctrl_reg_y1731_sa_chk_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_ts_ctrl_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_ctrl_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.y1731_sa_chk_en = value; + ret = qca808x_ptp_tx_com_ts_ctrl_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_filt_mac_da0_reg_mac_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_filt_mac_da0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_filt_mac_da0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.mac_addr; + return ret; +} + +sw_error_t +qca808x_ptp_tx_filt_mac_da0_reg_mac_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_filt_mac_da0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_filt_mac_da0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_addr = value; + ret = qca808x_ptp_tx_filt_mac_da0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_filt_mac_da1_reg_mac_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_filt_mac_da1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_filt_mac_da1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.mac_addr; + return ret; +} + +sw_error_t +qca808x_ptp_tx_filt_mac_da1_reg_mac_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_filt_mac_da1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_filt_mac_da1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_addr = value; + ret = qca808x_ptp_tx_filt_mac_da1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_filt_mac_da2_reg_mac_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_filt_mac_da2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_filt_mac_da2_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.mac_addr; + return ret; +} + +sw_error_t +qca808x_ptp_tx_filt_mac_da2_reg_mac_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_filt_mac_da2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_filt_mac_da2_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_addr = value; + ret = qca808x_ptp_tx_filt_mac_da2_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_filt_ipv4_da0_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_filt_ipv4_da0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_filt_ipv4_da0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ip_addr; + return ret; +} + +sw_error_t +qca808x_ptp_tx_filt_ipv4_da0_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_filt_ipv4_da0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_filt_ipv4_da0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_addr = value; + ret = qca808x_ptp_tx_filt_ipv4_da0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_filt_ipv4_da1_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_filt_ipv4_da1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_filt_ipv4_da1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ip_addr; + return ret; +} + +sw_error_t +qca808x_ptp_tx_filt_ipv4_da1_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_filt_ipv4_da1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_filt_ipv4_da1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_addr = value; + ret = qca808x_ptp_tx_filt_ipv4_da1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da0_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_filt_ipv6_da0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_filt_ipv6_da0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ip_addr; + return ret; +} + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da0_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_filt_ipv6_da0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_filt_ipv6_da0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_addr = value; + ret = qca808x_ptp_tx_filt_ipv6_da0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da1_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_filt_ipv6_da1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_filt_ipv6_da1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ip_addr; + return ret; +} + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da1_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_filt_ipv6_da1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_filt_ipv6_da1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_addr = value; + ret = qca808x_ptp_tx_filt_ipv6_da1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da2_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_filt_ipv6_da2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_filt_ipv6_da2_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ip_addr; + return ret; +} + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da2_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_filt_ipv6_da2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_filt_ipv6_da2_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_addr = value; + ret = qca808x_ptp_tx_filt_ipv6_da2_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da3_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_filt_ipv6_da3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_filt_ipv6_da3_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ip_addr; + return ret; +} + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da3_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_filt_ipv6_da3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_filt_ipv6_da3_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_addr = value; + ret = qca808x_ptp_tx_filt_ipv6_da3_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da4_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_filt_ipv6_da4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_filt_ipv6_da4_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ip_addr; + return ret; +} + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da4_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_filt_ipv6_da4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_filt_ipv6_da4_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_addr = value; + ret = qca808x_ptp_tx_filt_ipv6_da4_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da5_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_filt_ipv6_da5_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_filt_ipv6_da5_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ip_addr; + return ret; +} + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da5_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_filt_ipv6_da5_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_filt_ipv6_da5_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_addr = value; + ret = qca808x_ptp_tx_filt_ipv6_da5_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da6_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_filt_ipv6_da6_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_filt_ipv6_da6_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ip_addr; + return ret; +} + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da6_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_filt_ipv6_da6_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_filt_ipv6_da6_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_addr = value; + ret = qca808x_ptp_tx_filt_ipv6_da6_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da7_reg_ip_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_filt_ipv6_da7_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_filt_ipv6_da7_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ip_addr; + return ret; +} + +sw_error_t +qca808x_ptp_tx_filt_ipv6_da7_reg_ip_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_filt_ipv6_da7_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_filt_ipv6_da7_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ip_addr = value; + ret = qca808x_ptp_tx_filt_ipv6_da7_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_filt_mac_lengthtype_reg_length_type_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_filt_mac_lengthtype_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_filt_mac_lengthtype_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.length_type; + return ret; +} + +sw_error_t +qca808x_ptp_tx_filt_mac_lengthtype_reg_length_type_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_filt_mac_lengthtype_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_filt_mac_lengthtype_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.length_type = value; + ret = qca808x_ptp_tx_filt_mac_lengthtype_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_filt_layer4_protocol_reg_l4_protocol_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_filt_layer4_protocol_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_filt_layer4_protocol_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.l4_protocol; + return ret; +} + +sw_error_t +qca808x_ptp_tx_filt_layer4_protocol_reg_l4_protocol_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_filt_layer4_protocol_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_filt_layer4_protocol_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.l4_protocol = value; + ret = qca808x_ptp_tx_filt_layer4_protocol_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_filt_udp_port_reg_udp_port_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_filt_udp_port_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_filt_udp_port_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.udp_port; + return ret; +} + +sw_error_t +qca808x_ptp_tx_filt_udp_port_reg_udp_port_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_filt_udp_port_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_filt_udp_port_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udp_port = value; + ret = qca808x_ptp_tx_filt_udp_port_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_mac_ptp_pdelay_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.mac_ptp_pdelay_addr; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_mac_ptp_pdelay_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_ptp_pdelay_addr = value; + ret = qca808x_ptp_tx_com_ts_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_mac_da_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.mac_da; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_mac_da_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_da = value; + ret = qca808x_ptp_tx_com_ts_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_ipv4_ptp_pdelay_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ipv4_ptp_pdelay_addr; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_ipv4_ptp_pdelay_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv4_ptp_pdelay_addr = value; + ret = qca808x_ptp_tx_com_ts_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_mac_lengthtype_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.mac_lengthtype; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_mac_lengthtype_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_lengthtype = value; + ret = qca808x_ptp_tx_com_ts_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_udp_dport_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.udp_dport; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_udp_dport_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udp_dport = value; + ret = qca808x_ptp_tx_com_ts_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_ipv4_layer4_protocol_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ipv4_layer4_protocol; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_ipv4_layer4_protocol_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv4_layer4_protocol = value; + ret = qca808x_ptp_tx_com_ts_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_udp_ptp_event_dport_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.udp_ptp_event_dport; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_udp_ptp_event_dport_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.udp_ptp_event_dport = value; + ret = qca808x_ptp_tx_com_ts_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_ipv6_da_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ipv6_da; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_ipv6_da_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv6_da = value; + ret = qca808x_ptp_tx_com_ts_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_ipv4_ptp_prim_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ipv4_ptp_prim_addr; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_ipv4_ptp_prim_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv4_ptp_prim_addr = value; + ret = qca808x_ptp_tx_com_ts_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_ipv4_da_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ipv4_da; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_ipv4_da_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv4_da = value; + ret = qca808x_ptp_tx_com_ts_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_ipv6_ptp_pdelay_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ipv6_ptp_pdelay_addr; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_ipv6_ptp_pdelay_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv6_ptp_pdelay_addr = value; + ret = qca808x_ptp_tx_com_ts_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_ipv6_ptp_prim_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ipv6_ptp_prim_addr; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_ipv6_ptp_prim_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv6_ptp_prim_addr = value; + ret = qca808x_ptp_tx_com_ts_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_ipv6_next_header_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.ipv6_next_header; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_ipv6_next_header_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.ipv6_next_header = value; + ret = qca808x_ptp_tx_com_ts_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_y1731_mach_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.y1731_mach; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_y1731_mach_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.y1731_mach = value; + ret = qca808x_ptp_tx_com_ts_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_mac_ptp_prim_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.mac_ptp_prim_addr; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_ts_status_reg_mac_ptp_prim_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_ts_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_ts_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_ptp_prim_addr = value; + ret = qca808x_ptp_tx_com_ts_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_timestamp0_reg_com_ts_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_timestamp0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_timestamp0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.com_ts; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_timestamp0_reg_com_ts_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_timestamp0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_timestamp0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.com_ts = value; + ret = qca808x_ptp_tx_com_timestamp0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_timestamp1_reg_com_ts_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_timestamp1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_timestamp1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.com_ts; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_timestamp1_reg_com_ts_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_timestamp1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_timestamp1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.com_ts = value; + ret = qca808x_ptp_tx_com_timestamp1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_timestamp2_reg_com_ts_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_timestamp2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_timestamp2_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.com_ts; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_timestamp2_reg_com_ts_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_timestamp2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_timestamp2_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.com_ts = value; + ret = qca808x_ptp_tx_com_timestamp2_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_timestamp3_reg_com_ts_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_timestamp3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_timestamp3_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.com_ts; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_timestamp3_reg_com_ts_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_timestamp3_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_timestamp3_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.com_ts = value; + ret = qca808x_ptp_tx_com_timestamp3_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_timestamp4_reg_com_ts_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_timestamp4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_timestamp4_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.com_ts; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_timestamp4_reg_com_ts_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_timestamp4_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_timestamp4_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.com_ts = value; + ret = qca808x_ptp_tx_com_timestamp4_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_frac_nano_reg_frac_nano_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_com_frac_nano_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_frac_nano_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.frac_nano; + return ret; +} + +sw_error_t +qca808x_ptp_tx_com_frac_nano_reg_frac_nano_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_com_frac_nano_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_com_frac_nano_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.frac_nano = value; + ret = qca808x_ptp_tx_com_frac_nano_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_y1731_identify_reg_identify_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_y1731_identify_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_y1731_identify_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.identify; + return ret; +} + +sw_error_t +qca808x_ptp_tx_y1731_identify_reg_identify_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_y1731_identify_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_y1731_identify_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.identify = value; + ret = qca808x_ptp_tx_y1731_identify_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_y1731_dm_control_reg_y1731_dmm_lpbk_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_y1731_dm_control_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_y1731_dm_control_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.y1731_dmm_lpbk_en; + return ret; +} + +sw_error_t +qca808x_ptp_y1731_dm_control_reg_y1731_dmm_lpbk_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_y1731_dm_control_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_y1731_dm_control_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.y1731_dmm_lpbk_en = value; + ret = qca808x_ptp_y1731_dm_control_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_y1731_dm_control_reg_valid_msg_lev_bmp_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_y1731_dm_control_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_y1731_dm_control_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.valid_msg_lev_bmp; + return ret; +} + +sw_error_t +qca808x_ptp_y1731_dm_control_reg_valid_msg_lev_bmp_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_y1731_dm_control_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_y1731_dm_control_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.valid_msg_lev_bmp = value; + ret = qca808x_ptp_y1731_dm_control_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_baud_config_reg_baud_rate_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_baud_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_baud_config_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.baud_rate; + return ret; +} + +sw_error_t +qca808x_ptp_baud_config_reg_baud_rate_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_baud_config_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_baud_config_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.baud_rate = value; + ret = qca808x_ptp_baud_config_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_uart_configuration_reg_start_polarity_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value) +{ + union ptp_uart_configuration_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_uart_configuration_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.start_polarity; + return ret; +} + +sw_error_t +qca808x_ptp_uart_configuration_reg_start_polarity_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_uart_configuration_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_uart_configuration_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.start_polarity = value; + ret = qca808x_ptp_uart_configuration_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_uart_configuration_reg_msb_first_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value) +{ + union ptp_uart_configuration_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_uart_configuration_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.msb_first; + return ret; +} + +sw_error_t +qca808x_ptp_uart_configuration_reg_msb_first_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_uart_configuration_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_uart_configuration_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.msb_first = value; + ret = qca808x_ptp_uart_configuration_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_uart_configuration_reg_parity_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value) +{ + union ptp_uart_configuration_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_uart_configuration_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.parity_en; + return ret; +} + +sw_error_t +qca808x_ptp_uart_configuration_reg_parity_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_uart_configuration_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_uart_configuration_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.parity_en = value; + ret = qca808x_ptp_uart_configuration_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_uart_configuration_reg_auto_tod_out_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value) +{ + union ptp_uart_configuration_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_uart_configuration_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.auto_tod_out_en; + return ret; +} + +sw_error_t +qca808x_ptp_uart_configuration_reg_auto_tod_out_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_uart_configuration_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_uart_configuration_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.auto_tod_out_en = value; + ret = qca808x_ptp_uart_configuration_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_uart_configuration_reg_auto_tod_in_en_get( + a_uint32_t dev_id, a_uint32_t phy_id, + unsigned int *value) +{ + union ptp_uart_configuration_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_uart_configuration_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.auto_tod_in_en; + return ret; +} + +sw_error_t +qca808x_ptp_uart_configuration_reg_auto_tod_in_en_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_uart_configuration_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_uart_configuration_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.auto_tod_in_en = value; + ret = qca808x_ptp_uart_configuration_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_reset_buffer_reg_reset_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_reset_buffer_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_reset_buffer_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.reset; + return ret; +} + +sw_error_t +qca808x_ptp_reset_buffer_reg_reset_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_reset_buffer_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_reset_buffer_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.reset = value; + ret = qca808x_ptp_reset_buffer_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_buffer_status_reg_tx_buffer_almost_empty_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_buffer_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_buffer_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.tx_buffer_almost_empty; + return ret; +} + +sw_error_t +qca808x_ptp_buffer_status_reg_tx_buffer_almost_empty_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_buffer_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_buffer_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_buffer_almost_empty = value; + ret = qca808x_ptp_buffer_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_buffer_status_reg_tx_buffer_almost_full_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_buffer_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_buffer_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.tx_buffer_almost_full; + return ret; +} + +sw_error_t +qca808x_ptp_buffer_status_reg_tx_buffer_almost_full_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_buffer_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_buffer_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_buffer_almost_full = value; + ret = qca808x_ptp_buffer_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_buffer_status_reg_tx_buffer_half_full_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_buffer_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_buffer_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.tx_buffer_half_full; + return ret; +} + +sw_error_t +qca808x_ptp_buffer_status_reg_tx_buffer_half_full_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_buffer_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_buffer_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_buffer_half_full = value; + ret = qca808x_ptp_buffer_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_buffer_status_reg_tx_buffer_full_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_buffer_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_buffer_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.tx_buffer_full; + return ret; +} + +sw_error_t +qca808x_ptp_buffer_status_reg_tx_buffer_full_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_buffer_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_buffer_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_buffer_full = value; + ret = qca808x_ptp_buffer_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_buffer_status_reg_rx_buffer_almost_empty_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_buffer_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_buffer_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_buffer_almost_empty; + return ret; +} + +sw_error_t +qca808x_ptp_buffer_status_reg_rx_buffer_almost_empty_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_buffer_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_buffer_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_buffer_almost_empty = value; + ret = qca808x_ptp_buffer_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_buffer_status_reg_rx_buffer_almost_full_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_buffer_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_buffer_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_buffer_almost_full; + return ret; +} + +sw_error_t +qca808x_ptp_buffer_status_reg_rx_buffer_almost_full_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_buffer_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_buffer_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_buffer_almost_full = value; + ret = qca808x_ptp_buffer_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_buffer_status_reg_rx_buffer_half_full_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_buffer_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_buffer_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_buffer_half_full; + return ret; +} + +sw_error_t +qca808x_ptp_buffer_status_reg_rx_buffer_half_full_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_buffer_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_buffer_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_buffer_half_full = value; + ret = qca808x_ptp_buffer_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_buffer_status_reg_rx_buffer_full_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_buffer_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_buffer_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_buffer_full; + return ret; +} + +sw_error_t +qca808x_ptp_buffer_status_reg_rx_buffer_full_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_buffer_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_buffer_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_buffer_full = value; + ret = qca808x_ptp_buffer_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_buffer_status_reg_rx_buffer_data_present_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_buffer_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_buffer_status_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_buffer_data_present; + return ret; +} + +sw_error_t +qca808x_ptp_buffer_status_reg_rx_buffer_data_present_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_buffer_status_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_buffer_status_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_buffer_data_present = value; + ret = qca808x_ptp_buffer_status_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_tx_buffer_write_reg_tx_buffer_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_tx_buffer_write_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_buffer_write_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.tx_buffer; + return ret; +} + +sw_error_t +qca808x_ptp_tx_buffer_write_reg_tx_buffer_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_tx_buffer_write_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_tx_buffer_write_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.tx_buffer = value; + ret = qca808x_ptp_tx_buffer_write_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_buffer_read_reg_rx_data_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_buffer_read_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_buffer_read_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_data; + return ret; +} + +sw_error_t +qca808x_ptp_rx_buffer_read_reg_rx_data_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_buffer_read_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_buffer_read_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_data = value; + ret = qca808x_ptp_rx_buffer_read_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_buffer_read_reg_rx_buffer_almost_empty_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_buffer_read_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_buffer_read_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_buffer_almost_empty; + return ret; +} + +sw_error_t +qca808x_ptp_rx_buffer_read_reg_rx_buffer_almost_empty_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_buffer_read_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_buffer_read_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_buffer_almost_empty = value; + ret = qca808x_ptp_rx_buffer_read_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_buffer_read_reg_rx_buffer_almost_full_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_buffer_read_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_buffer_read_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_buffer_almost_full; + return ret; +} + +sw_error_t +qca808x_ptp_rx_buffer_read_reg_rx_buffer_almost_full_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_buffer_read_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_buffer_read_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_buffer_almost_full = value; + ret = qca808x_ptp_rx_buffer_read_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_buffer_read_reg_rx_buffer_half_full_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_buffer_read_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_buffer_read_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_buffer_half_full; + return ret; +} + +sw_error_t +qca808x_ptp_rx_buffer_read_reg_rx_buffer_half_full_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_buffer_read_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_buffer_read_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_buffer_half_full = value; + ret = qca808x_ptp_rx_buffer_read_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_buffer_read_reg_rx_buffer_full_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_buffer_read_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_buffer_read_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_buffer_full; + return ret; +} + +sw_error_t +qca808x_ptp_rx_buffer_read_reg_rx_buffer_full_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_buffer_read_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_buffer_read_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_buffer_full = value; + ret = qca808x_ptp_rx_buffer_read_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_rx_buffer_read_reg_rx_buffer_data_present_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_rx_buffer_read_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_buffer_read_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.rx_buffer_data_present; + return ret; +} + +sw_error_t +qca808x_ptp_rx_buffer_read_reg_rx_buffer_data_present_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_rx_buffer_read_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_rx_buffer_read_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.rx_buffer_data_present = value; + ret = qca808x_ptp_rx_buffer_read_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +// +sw_error_t +qca808x_ptp_loc_mac_addr_0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_loc_mac_addr_0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_LOC_MAC_ADDR_0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_loc_mac_addr_0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_loc_mac_addr_0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_LOC_MAC_ADDR_0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_loc_mac_addr_1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_loc_mac_addr_1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_LOC_MAC_ADDR_1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_loc_mac_addr_1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_loc_mac_addr_1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_LOC_MAC_ADDR_1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_loc_mac_addr_2_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_loc_mac_addr_2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_LOC_MAC_ADDR_2_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_loc_mac_addr_2_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_loc_mac_addr_2_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_LOC_MAC_ADDR_2_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_loc_mac_addr_0_reg_mac_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_loc_mac_addr_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_loc_mac_addr_0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.mac_addr; + return ret; +} + +sw_error_t +qca808x_ptp_loc_mac_addr_0_reg_mac_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_loc_mac_addr_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_loc_mac_addr_0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_addr = value; + ret = qca808x_ptp_loc_mac_addr_0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_loc_mac_addr_1_reg_mac_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_loc_mac_addr_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_loc_mac_addr_1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.mac_addr; + return ret; +} + +sw_error_t +qca808x_ptp_loc_mac_addr_1_reg_mac_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_loc_mac_addr_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_loc_mac_addr_1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_addr = value; + ret = qca808x_ptp_loc_mac_addr_1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_loc_mac_addr_2_reg_mac_addr_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_loc_mac_addr_2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_loc_mac_addr_2_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.mac_addr; + return ret; +} + +sw_error_t +qca808x_ptp_loc_mac_addr_2_reg_mac_addr_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_loc_mac_addr_2_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_loc_mac_addr_2_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.mac_addr = value; + ret = qca808x_ptp_loc_mac_addr_2_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_link_delay_0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_link_delay_0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_LINK_DELAY_0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_link_delay_0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_link_delay_0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_LINK_DELAY_0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_link_delay_1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_link_delay_1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_LINK_DELAY_1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_link_delay_1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_link_delay_1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_LINK_DELAY_1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_link_delay_0_reg_link_delay_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_link_delay_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_link_delay_0_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.link_delay; + return ret; +} + +sw_error_t +qca808x_ptp_link_delay_0_reg_link_delay_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_link_delay_0_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_link_delay_0_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.link_delay = value; + ret = qca808x_ptp_link_delay_0_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_link_delay_1_reg_link_delay_get( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t *value) +{ + union ptp_link_delay_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_link_delay_1_reg_get(dev_id, phy_id, ®_val); + *value = reg_val.bf.link_delay; + return ret; +} + +sw_error_t +qca808x_ptp_link_delay_1_reg_link_delay_set( + a_uint32_t dev_id, a_uint32_t phy_id, + a_uint32_t value) +{ + union ptp_link_delay_1_reg_u reg_val; + sw_error_t ret = SW_OK; + + ret = qca808x_ptp_link_delay_1_reg_get(dev_id, phy_id, ®_val); + if (SW_OK != ret) + return ret; + reg_val.bf.link_delay = value; + ret = qca808x_ptp_link_delay_1_reg_set(dev_id, phy_id, ®_val); + return ret; +} + +sw_error_t +qca808x_ptp_misc_control_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_misc_control_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_MISC_CONTROL_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_misc_control_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_misc_control_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_MISC_CONTROL_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_ingress_asymmetry_0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ingress_asymmetry_0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_INGRESS_ASYMMETRY_0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_ingress_asymmetry_0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ingress_asymmetry_0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_INGRESS_ASYMMETRY_0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_ingress_asymmetry_1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ingress_asymmetry_1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_INGRESS_ASYMMETRY_1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_ingress_asymmetry_1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_ingress_asymmetry_1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_INGRESS_ASYMMETRY_1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_egress_asymmetry_0_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_egress_asymmetry_0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EGRESS_ASYMMETRY_0_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_egress_asymmetry_0_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_egress_asymmetry_0_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EGRESS_ASYMMETRY_0_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_egress_asymmetry_1_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_egress_asymmetry_1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EGRESS_ASYMMETRY_1_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_egress_asymmetry_1_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_egress_asymmetry_1_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_EGRESS_ASYMMETRY_1_REG_ADDRESS, + value->val); +} + +sw_error_t +qca808x_ptp_backup_reg_get( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_backup_reg_u *value) +{ + return qca808x_phy_ptp_mmd_read( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_BACKUP_REG_ADDRESS, + &value->val); +} + +sw_error_t +qca808x_ptp_backup_reg_set( + a_uint32_t dev_id, a_uint32_t phy_id, + union ptp_backup_reg_u *value) +{ + return qca808x_phy_ptp_mmd_write( + dev_id, + phy_id, QCA808X_PHY_MMD3_NUM, PTP_BACKUP_REG_ADDRESS, + value->val); +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/sfp_phy.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/sfp_phy.c new file mode 100755 index 000000000..91aca3889 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/phy/sfp_phy.c @@ -0,0 +1,254 @@ +/* + * 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 "sw.h" +#include "fal_port_ctrl.h" +#include "adpt.h" +#include "hsl_api.h" +#include "hsl.h" +#include "sfp_phy.h" +#include "aos_timer.h" +#include "hsl_phy.h" +#include +#include +#include +#include +#include "ssdk_plat.h" +#include "ssdk_phy_i2c.h" + +/****************************************************************************** +* +* sfp_phy_init - +* +*/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION (5, 0, 0)) +#define SFP_PHY_FEATURES (SUPPORTED_FIBRE | \ + SUPPORTED_1000baseT_Full | \ + SUPPORTED_10000baseT_Full | \ + SUPPORTED_Pause | \ + SUPPORTED_Asym_Pause) +#else +__ETHTOOL_DECLARE_LINK_MODE_MASK(SFP_PHY_FEATURES) __ro_after_init; +#endif + +static int +sfp_phy_probe(struct phy_device *pdev) +{ + pdev->autoneg = AUTONEG_DISABLE; + SSDK_INFO("sfp phy is probed!\n"); + return 0; +} + +static void +sfp_phy_remove(struct phy_device *pdev) +{ + return; +} + +static int +sfp_phy_config_aneg(struct phy_device *pdev) +{ + + return 0; +} + +static int +sfp_phy_aneg_done(struct phy_device *pdev) +{ + + return SFP_ANEG_DONE; +} + +static int +sfp_read_status(struct phy_device *pdev) +{ + sw_error_t rv; + fal_port_t port; + a_uint32_t addr; + struct qca_phy_priv *priv = pdev->priv; + struct port_phy_status phy_status; + adpt_api_t *p_api; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,9,0)) + addr = pdev->mdio.addr; +#else + addr = pdev->addr; +#endif + port = qca_ssdk_phy_addr_to_port(priv->device_id, addr); + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(priv->device_id)); + rv = p_api->adpt_port_phy_status_get(priv->device_id, port, &phy_status); + pdev->link = phy_status.link_status; + pdev->speed = phy_status.speed; + pdev->duplex = phy_status.duplex; + + return rv; +} + +static struct phy_driver sfp_phy_driver = { + .name = "QCA SFP", + .phy_id = SFP_PHY, + .phy_id_mask = SFP_PHY_MASK, + .probe = sfp_phy_probe, + .remove = sfp_phy_remove, + .config_aneg = sfp_phy_config_aneg, + .aneg_done = sfp_phy_aneg_done, + .read_status = sfp_read_status, + .features = SFP_PHY_FEATURES, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,9,0)) + .mdiodrv.driver = { .owner = THIS_MODULE }, +#else + .driver = { .owner = THIS_MODULE }, +#endif +}; + +int sfp_phy_device_setup(a_uint32_t dev_id, a_uint32_t port, a_uint32_t phy_id) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) + struct phy_device *phydev; + struct qca_phy_priv *priv; + a_uint32_t addr = 0; + struct mii_bus *bus; + + priv = ssdk_phy_priv_data_get(dev_id); + /*create phy device*/ +#if defined(IN_PHY_I2C_MODE) + if (hsl_port_phy_access_type_get(dev_id, port) == PHY_I2C_ACCESS) { + addr = qca_ssdk_port_to_phy_mdio_fake_addr(dev_id, port); + } else +#endif + { + addr = qca_ssdk_port_to_phy_addr(dev_id, port); + } + bus = ssdk_miibus_get_by_device(dev_id); + phydev = phy_device_create(bus, addr, phy_id, false, NULL); + if (IS_ERR(phydev) || phydev == NULL) { + SSDK_ERROR("Failed to create phy device!\n"); + return SW_NOT_SUPPORTED; + } + /*register phy device*/ + phy_device_register(phydev); + + phydev->priv = priv; +#endif + return 0; +} + +void sfp_phy_device_remove(a_uint32_t dev_id, a_uint32_t port) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) + struct phy_device *phydev = NULL; + a_uint32_t addr = 0; + struct mii_bus *bus; + + bus = ssdk_miibus_get_by_device(dev_id); +#if defined(IN_PHY_I2C_MODE) + if (hsl_port_phy_access_type_get(dev_id, port) == PHY_I2C_ACCESS) { + addr = qca_ssdk_port_to_phy_mdio_fake_addr(dev_id, port); + } else +#endif + { + addr = qca_ssdk_port_to_phy_addr(dev_id, port); + } + + if (addr < PHY_MAX_ADDR) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) + if (bus->mdio_map[addr]) + phydev = to_phy_device(&bus->mdio_map[addr]->dev); +#else + phydev = bus->phy_map[addr]; +#endif + if (phydev) + phy_device_remove(phydev); +#endif +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)) +static void sfp_features_init(void) +{ + const int features[] = { + ETHTOOL_LINK_MODE_FIBRE_BIT, + ETHTOOL_LINK_MODE_1000baseT_Full_BIT, + ETHTOOL_LINK_MODE_10000baseT_Full_BIT, + ETHTOOL_LINK_MODE_Pause_BIT, + ETHTOOL_LINK_MODE_Asym_Pause_BIT, + }; + + linkmode_set_bit_array(features, + ARRAY_SIZE(features), + SFP_PHY_FEATURES); +} +#endif + +int sfp_phy_init(a_uint32_t dev_id, a_uint32_t port_bmp) +{ + a_uint32_t port_id = 0; + + SSDK_INFO("sfp phy init for port 0x%x!\n", port_bmp); + + for (port_id = 0; port_id < SW_MAX_NR_PORT; port_id ++) { + if (port_bmp & (0x1 << port_id)) { + sfp_phy_device_setup(dev_id, port_id, SFP_PHY); + } + } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)) + sfp_features_init(); +#endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,9,0)) + phy_driver_register(&sfp_phy_driver, THIS_MODULE); +#else + phy_driver_register(&sfp_phy_driver); +#endif + return 0; +} + +void sfp_phy_exit(a_uint32_t dev_id, a_uint32_t port_bmp) +{ + a_uint32_t port_id = 0; + + phy_driver_unregister(&sfp_phy_driver); + + for (port_id = 0; port_id < SW_MAX_NR_PORT; port_id ++) { + if (port_bmp & (0x1 << port_id)) { + sfp_phy_device_remove(dev_id, port_id); + } + } + +} +sw_error_t sfp_phy_interface_get_mode_status(a_uint32_t dev_id, + a_uint32_t phy_id, fal_port_interface_mode_t *interface_mode_status) +{ + sw_error_t rv = SW_OK; + a_uint16_t reg_data = 0, sfp_speed = 0; + + rv = qca_phy_i2c_mii_read(dev_id, SFP_E2PROM_ADDR, SFP_SPEED_ADDR, + ®_data); + SW_RTN_ON_ERROR(rv); + sfp_speed = SFP_TO_SFP_SPEED(reg_data); + SSDK_DEBUG("sfp_speed:%d\n", sfp_speed); + if(sfp_speed >= SFP_SPEED_1000M && + sfp_speed < SFP_SPEED_2500M) + { + *interface_mode_status = PORT_SGMII_FIBER; + } + else if(sfp_speed >= SFP_SPEED_10000M) + { + *interface_mode_status = PORT_10GBASE_R; + } + else + { + return SW_NOT_SUPPORTED; + } + + return rv; +} diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/scomphy/Makefile b/feeds/ipq807x/qca-ssdk/src/src/hsl/scomphy/Makefile new file mode 100755 index 000000000..0e6e147da --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/scomphy/Makefile @@ -0,0 +1,28 @@ +LOC_DIR=src/hsl/scomphy +LIB=HSL + +include $(PRJ_PATH)/make/config.mk + +SRC_LIST=scomphy_reg_access.c scomphy_init.c + +ifeq (TRUE, $(IN_PORTCONTROL)) + SRC_LIST += scomphy_port_ctrl.c +endif + +ifeq (linux, $(OS)) + ifeq (KSLIB, $(MODULE_TYPE)) + ifneq (TRUE, $(KERNEL_MODE)) + SRC_LIST=scomphy_reg_access.c scomphy_init.c + endif + endif +endif + +ifeq (, $(findstring SCOMPHY, $(SUPPORT_CHIP))) + SRC_LIST= +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/src/src/hsl/scomphy/scomphy_init.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/scomphy/scomphy_init.c new file mode 100755 index 000000000..7f82807d8 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/scomphy/scomphy_init.c @@ -0,0 +1,196 @@ +/* + * 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. + */ + + +/** + * @defgroup scomphy_init SCOMPHY_INIT + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_phy.h" +#include "hsl_port_prop.h" +#include "scomphy_port_ctrl.h" +#include "scomphy_reg_access.h" +#include "scomphy_init.h" + +static ssdk_init_cfg * scomphy_cfg[SW_MAX_NR_DEV] = { 0 }; + +static sw_error_t +scomphy_portproperty_init(a_uint32_t dev_id, hsl_init_mode mode) +{ + hsl_port_prop_t p_type; + hsl_dev_t *pdev = NULL; + fal_port_t port_id; + a_uint32_t port_bmp = qca_ssdk_port_bmp_get(dev_id); + + pdev = hsl_dev_ptr_get(dev_id); + if (pdev == NULL) + return SW_NOT_INITIALIZED; + + /* for port property set, SSDK should not generate some limitations */ + for (port_id = 1; port_id < SW_MAX_NR_PORT; port_id++) + { + if((1 << port_id) & port_bmp) + { + hsl_port_prop_portmap_set(dev_id, port_id); + + for (p_type = HSL_PP_PHY; p_type < HSL_PP_BUTT; p_type++) + { + SW_RTN_ON_ERROR(hsl_port_prop_set(dev_id, port_id, p_type)); + } + } + } + + return SW_OK; +} + +static sw_error_t +scomphy_dev_init(a_uint32_t dev_id, hsl_init_mode cpu_mode) +{ + sw_error_t rv = SW_OK; + hsl_dev_t *pdev = NULL; + a_uint8_t nr_ports = 0; + a_uint32_t port_bmp = qca_ssdk_port_bmp_get(dev_id); + + pdev = hsl_dev_ptr_get(dev_id); + if (pdev == NULL) + return SW_NOT_INITIALIZED; + + while (port_bmp) { + if (port_bmp & 1) + nr_ports++; + port_bmp >>= 1; + } + + pdev->nr_ports = nr_ports; + pdev->nr_phy = nr_ports; + pdev->cpu_port_nr = 0; + pdev->hw_vlan_query = A_TRUE; + pdev->cpu_mode = cpu_mode; + + return rv; +} + + +static sw_error_t +_scomphy_reset(a_uint32_t dev_id) +{ + sw_error_t rv = SW_OK; + a_uint32_t port_bmp = 0; + a_uint8_t port_id = 0; + + HSL_DEV_ID_CHECK(dev_id); + + port_bmp = qca_ssdk_port_bmp_get(dev_id); + while (port_bmp) { + if (port_bmp & 1) + SW_RTN_ON_ERROR(scomphy_port_reset(dev_id, port_id)); + + port_bmp >>= 1; + port_id++; + } + + return rv; +} + +sw_error_t +scomphy_cleanup(a_uint32_t dev_id) +{ + sw_error_t rv = SW_OK; + + if (scomphy_cfg[dev_id]) + { + SW_RTN_ON_ERROR(hsl_port_prop_cleanup_by_dev(dev_id)); + + aos_mem_free(scomphy_cfg[dev_id]); + scomphy_cfg[dev_id] = NULL; + } + + return rv; +} + +/** + * @brief reset hsl layer. + * @details Comments: + * This operation will reset hsl layer + * @param[in] dev_id device id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_reset(a_uint32_t dev_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _scomphy_reset(dev_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Init hsl layer. + * @details Comments: + * This operation will init hsl layer and hsl layer + * @param[in] dev_id device id + * @param[in] cfg configuration for initialization + * @return SW_OK or error code + */ +sw_error_t +scomphy_init(a_uint32_t dev_id, ssdk_init_cfg *cfg) +{ + HSL_DEV_ID_CHECK(dev_id); + + if (NULL == scomphy_cfg[dev_id]) + { + scomphy_cfg[dev_id] = aos_mem_alloc(sizeof (ssdk_init_cfg)); + } + + if (NULL == scomphy_cfg[dev_id]) + { + return SW_OUT_OF_MEM; + } + + aos_mem_copy(scomphy_cfg[dev_id], cfg, sizeof (ssdk_init_cfg)); + + SW_RTN_ON_ERROR(scomphy_reg_access_init(dev_id, cfg)); + + SW_RTN_ON_ERROR(scomphy_dev_init(dev_id, cfg->cpu_mode)); + + { + sw_error_t rv; + + SW_RTN_ON_ERROR(hsl_port_prop_init(dev_id)); + SW_RTN_ON_ERROR(hsl_port_prop_init_by_dev(dev_id)); + SW_RTN_ON_ERROR(scomphy_portproperty_init(dev_id, cfg->cpu_mode)); + + SCOMPHY_PORT_CTRL_INIT(rv, dev_id); + + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->dev_reset = scomphy_reset; + p_api->dev_clean = scomphy_cleanup; + } + } + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/scomphy/scomphy_port_ctrl.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/scomphy/scomphy_port_ctrl.c new file mode 100644 index 000000000..e55dcaa97 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/scomphy/scomphy_port_ctrl.c @@ -0,0 +1,2078 @@ +/* + * 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. + */ + +/*qca808x_start*/ +/** + * @defgroup scomphy_port_ctrl SCOMPHY_PORT_CONTROL + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "scomphy_port_ctrl.h" +#include "hsl_phy.h" + +static sw_error_t +_scomphy_port_duplex_set (a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t duplex) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_duplex_set) + return SW_NOT_SUPPORTED; + + if (FAL_DUPLEX_BUTT <= duplex) + { + return SW_BAD_PARAM; + } + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_duplex_set (dev_id, phy_id, duplex); + SW_RTN_ON_ERROR (rv); + return rv; +} + +static sw_error_t +_scomphy_port_duplex_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t * pduplex) +{ + sw_error_t rv = SW_OK; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_duplex_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_duplex_get (dev_id, phy_id, pduplex); + SW_RTN_ON_ERROR (rv); + + return rv; +} + +static sw_error_t +_scomphy_port_speed_set (a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t speed) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_speed_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_speed_set (dev_id, phy_id, speed); + SW_RTN_ON_ERROR (rv); + return rv; +} + +static sw_error_t +_scomphy_port_speed_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t * pspeed) +{ + sw_error_t rv = SW_OK; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_speed_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + rv = phy_drv->phy_speed_get (dev_id, phy_id, pspeed); + SW_RTN_ON_ERROR (rv); + + return rv; +} + +static sw_error_t +_scomphy_port_autoneg_status_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status) +{ + a_uint32_t phy_id; + sw_error_t rv; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_autoneg_status_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + *status = phy_drv->phy_autoneg_status_get (dev_id, phy_id); + + return SW_OK; +} + +static sw_error_t +_scomphy_port_autoneg_enable (a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_autoneg_enable_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_autoneg_enable_set (dev_id, phy_id); + return rv; +} + +static sw_error_t +_scomphy_port_autoneg_restart (a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_restart_autoneg) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_restart_autoneg (dev_id, phy_id); + return rv; +} + +static sw_error_t +_scomphy_port_autoneg_adv_set (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t autoadv) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_autoneg_adv_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_autoneg_adv_set (dev_id, phy_id, autoadv); + SW_RTN_ON_ERROR (rv); + + return SW_OK; +} + +static sw_error_t +_scomphy_port_autoneg_adv_get (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * autoadv) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_autoneg_adv_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + *autoadv = 0; + rv = phy_drv->phy_autoneg_adv_get (dev_id, phy_id, autoadv); + SW_RTN_ON_ERROR (rv); + + return SW_OK; +} + +#ifndef IN_PORTCONTROL_MINI +static sw_error_t +_scomphy_port_powersave_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_powersave_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_powersave_set (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_scomphy_port_powersave_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_powersave_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_powersave_get (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_scomphy_port_hibernate_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_hibernation_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_hibernation_set (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_scomphy_port_hibernate_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_hibernation_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_hibernation_get (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_scomphy_port_cdt (a_uint32_t dev_id, fal_port_t port_id, a_uint32_t mdi_pair, + fal_cable_status_t * cable_status, a_uint32_t * cable_len) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_cdt) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_cdt (dev_id, phy_id, mdi_pair, cable_status, cable_len); + + return rv; +} + +static sw_error_t +_scomphy_port_8023az_set (a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_8023az_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_8023az_set (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_scomphy_port_8023az_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_8023az_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_8023az_get (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_scomphy_port_mdix_set (a_uint32_t dev_id, fal_port_t port_id, + fal_port_mdix_mode_t mode) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_mdix_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_mdix_set (dev_id, phy_id, mode); + + return rv; +} + +static sw_error_t +_scomphy_port_mdix_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_mdix_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_mdix_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_mdix_get (dev_id, phy_id, mode); + + return rv; +} + +static sw_error_t +_scomphy_port_mdix_status_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_mdix_status_t * mode) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_mdix_status_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_mdix_status_get (dev_id, phy_id, mode); + + return rv; +} +/*qca808x_end*/ +static sw_error_t +_scomphy_port_combo_prefer_medium_set (a_uint32_t dev_id, fal_port_t port_id, + fal_port_medium_t phy_medium) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_combo_prefer_medium_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_combo_prefer_medium_set (dev_id, phy_id, phy_medium); + + return rv; +} + +static sw_error_t +_scomphy_port_combo_prefer_medium_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_medium_t * phy_medium) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_combo_prefer_medium_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_combo_prefer_medium_get (dev_id, phy_id, phy_medium); + + return rv; +} + +static sw_error_t +_scomphy_port_combo_medium_status_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_medium_t * phy_medium) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_combo_medium_status_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_combo_medium_status_get (dev_id, phy_id, phy_medium); + + return rv; +} + +static sw_error_t +_scomphy_port_combo_fiber_mode_set (a_uint32_t dev_id, fal_port_t port_id, + fal_port_fiber_mode_t fiber_mode) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_combo_fiber_mode_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_combo_fiber_mode_set (dev_id, phy_id, fiber_mode); + + return rv; +} + +static sw_error_t +_scomphy_port_combo_fiber_mode_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_fiber_mode_t * fiber_mode) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_combo_fiber_mode_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_combo_fiber_mode_get (dev_id, phy_id, fiber_mode); + + return rv; +} +/*qca808x_start*/ +static sw_error_t +_scomphy_port_local_loopback_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_local_loopback_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_local_loopback_set (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_scomphy_port_local_loopback_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_local_loopback_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_local_loopback_get (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_scomphy_port_remote_loopback_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_remote_loopback_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_remote_loopback_set (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_scomphy_port_remote_loopback_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_remote_loopback_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_remote_loopback_get (dev_id, phy_id, enable); + + return rv; +} +#endif + +static sw_error_t +_scomphy_port_power_off (a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_power_off) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_power_off(dev_id, phy_id); + + return rv; +} + +static sw_error_t +_scomphy_port_power_on (a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_power_on) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_power_on(dev_id, phy_id); + + return rv; +} + +#ifndef IN_PORTCONTROL_MINI +static sw_error_t +_scomphy_port_wol_status_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_wol_status_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_wol_status_set (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_scomphy_port_wol_status_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_wol_status_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_wol_status_get (dev_id, phy_id, enable); + + return rv; +} +/*qca808x_end*/ +static sw_error_t +_scomphy_port_interface_mode_set (a_uint32_t dev_id, fal_port_t port_id, + fal_port_interface_mode_t mode) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_interface_mode_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_interface_mode_set (dev_id, phy_id,mode); + + return rv; +} + +static sw_error_t +_scomphy_port_interface_mode_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_interface_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_interface_mode_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_interface_mode_get (dev_id, phy_id,mode); + + return rv; +} +/*qca808x_start*/ +static sw_error_t +_scomphy_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; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_interface_mode_status_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_interface_mode_status_get (dev_id, phy_id,mode); + + return rv; +} + +static sw_error_t +_scomphy_port_magic_frame_mac_set (a_uint32_t dev_id, fal_port_t port_id, + fal_mac_addr_t * mac) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_magic_frame_mac_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_magic_frame_mac_set (dev_id, phy_id,mac); + + return rv; +} + +static sw_error_t +_scomphy_port_magic_frame_mac_get (a_uint32_t dev_id, fal_port_t port_id, + fal_mac_addr_t * mac) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_magic_frame_mac_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_magic_frame_mac_get (dev_id, phy_id,mac); + + return rv; +} + +static sw_error_t +_scomphy_port_counter_set (a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_counter_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_counter_set (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_scomphy_port_counter_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_counter_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_counter_get (dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_scomphy_port_counter_show (a_uint32_t dev_id, fal_port_t port_id, + fal_port_counter_info_t * counter_info) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_counter_show) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_counter_show (dev_id, phy_id,counter_info); + + return rv; +} +#endif + +static sw_error_t +_scomphy_port_link_status_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_link_status_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + if (A_TRUE == phy_drv->phy_link_status_get (dev_id, phy_id)) + { + *status = A_TRUE; + } + else + { + *status = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_scomphy_port_reset (a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_reset) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_reset(dev_id, phy_id); + + return rv; +} + +#ifndef IN_PORTCONTROL_MINI +static sw_error_t +_scomphy_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; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + a_uint32_t phy_data; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_id_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_id_get (dev_id, phy_id, &phy_data); + SW_RTN_ON_ERROR (rv); + + *org_id = (phy_data >> 16) & 0xffff; + *rev_id = phy_data & 0xffff; + + return rv; +} +#endif + +/** + * @brief Set duplex mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] duplex duplex mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_duplex_set (a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t duplex) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _scomphy_port_duplex_set (dev_id, port_id, duplex); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get duplex mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] duplex duplex mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_duplex_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t * pduplex) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _scomphy_port_duplex_get (dev_id, port_id, pduplex); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set speed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] speed port speed + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_speed_set (a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t speed) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _scomphy_port_speed_set (dev_id, port_id, speed); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get speed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] speed port speed + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_speed_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t * pspeed) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _scomphy_port_speed_get (dev_id, port_id, pspeed); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get auto negotiation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] status A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_autoneg_status_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _scomphy_port_autoneg_status_get (dev_id, port_id, status); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Enable auto negotiation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_autoneg_enable (a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _scomphy_port_autoneg_enable (dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Restart auto negotiation procedule on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_autoneg_restart (a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _scomphy_port_autoneg_restart (dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set auto negotiation advtisement ability on a particular port. + * @details Comments: + * auto negotiation advtisement ability is defined by macro such as + * FAL_PHY_ADV_10T_HD, FAL_PHY_ADV_PAUSE... + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] autoadv auto negotiation advtisement ability bit map + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_autoneg_adv_set (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t autoadv) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _scomphy_port_autoneg_adv_set (dev_id, port_id, autoadv); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get auto negotiation advtisement ability on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] autoadv auto negotiation advtisement ability bit map + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_autoneg_adv_get (a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * autoadv) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _scomphy_port_autoneg_adv_get (dev_id, port_id, autoadv); + HSL_API_UNLOCK; + return rv; +} + +#ifndef IN_PORTCONTROL_MINI +/** + * @brief Set powersaving status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_powersave_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _scomphy_port_powersave_set (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get powersaving status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_powersave_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _scomphy_port_powersave_get (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set hibernate status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_hibernate_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _scomphy_port_hibernate_set (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get hibernate status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_hibernate_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _scomphy_port_hibernate_get (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Run cable diagnostic test on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mdi_pair mdi pair id + * @param[out] cable_status cable status + * @param[out] cable_len cable len + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_cdt (a_uint32_t dev_id, fal_port_t port_id, a_uint32_t mdi_pair, + fal_cable_status_t * cable_status, a_uint32_t * cable_len) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _scomphy_port_cdt (dev_id, port_id, mdi_pair, cable_status, cable_len); + HSL_API_UNLOCK; + return rv; +} +/** + * @brief Set 802.3az status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_8023az_set (a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _scomphy_port_8023az_set (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get 8023az status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_8023az_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _scomphy_port_8023az_get (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set mdix on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_mdix_set (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_mdix_mode_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _scomphy_port_mdix_set (dev_id, phy_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mdix configuration on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mode + * @return SW_OK or error code + */ + +HSL_LOCAL sw_error_t +scomphy_port_mdix_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_mdix_mode_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _scomphy_port_mdix_get (dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mdix status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mode + * @return SW_OK or error code + */ + +HSL_LOCAL sw_error_t +scomphy_port_mdix_status_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_mdix_status_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _scomphy_port_mdix_status_get (dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} +/*qca808x_end*/ +/** + * @brief Set combo prefer medium on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] phy_medium [fiber or copper] + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_combo_prefer_medium_set (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_medium_t phy_medium) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _scomphy_port_combo_prefer_medium_set (dev_id, phy_id, phy_medium); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get combo prefer medium on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] phy_medium [fiber or copper] + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_combo_prefer_medium_get (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_medium_t * phy_medium) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _scomphy_port_combo_prefer_medium_get (dev_id, phy_id, phy_medium); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get current combo medium status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] phy_medium [fiber or copper] + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_combo_medium_status_get (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_medium_t * phy_medium) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _scomphy_port_combo_medium_status_get (dev_id, phy_id, phy_medium); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set fiber mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] fiber mode [1000bx or 100fx] + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_combo_fiber_mode_set (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_fiber_mode_t fiber_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _scomphy_port_combo_fiber_mode_set (dev_id, phy_id, fiber_mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get fiber mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] fiber mode [1000bx or 100fx] + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_combo_fiber_mode_get (a_uint32_t dev_id, a_uint32_t phy_id, + fal_port_fiber_mode_t * fiber_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _scomphy_port_combo_fiber_mode_get (dev_id, phy_id, fiber_mode); + HSL_API_UNLOCK; + return rv; +} +/*qca808x_start*/ +/** + * @brief Set phy local loop back on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_local_loopback_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _scomphy_port_local_loopback_set (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get phy local loop back on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_local_loopback_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _scomphy_port_local_loopback_get (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set phy remote loop back on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_remote_loopback_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _scomphy_port_remote_loopback_set (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get phy remote loop back on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_remote_loopback_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _scomphy_port_remote_loopback_get (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} +#endif + +/** + * @brief phy power off on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_power_off (a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _scomphy_port_power_off (dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief phy power on on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_power_on (a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _scomphy_port_power_on (dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +#ifndef IN_PORTCONTROL_MINI +/** + * @brief Set phy wol enable on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_wol_status_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _scomphy_port_wol_status_set (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get phy wol status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_wol_status_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _scomphy_port_wol_status_get (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set phy magic frame mac on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mac address + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_magic_frame_mac_set (a_uint32_t dev_id, fal_port_t port_id, + fal_mac_addr_t * mac) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _scomphy_port_magic_frame_mac_set (dev_id, port_id, mac); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get phy magic frame mac on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mac address + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_magic_frame_mac_get (a_uint32_t dev_id, fal_port_t port_id, + fal_mac_addr_t * mac) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _scomphy_port_magic_frame_mac_get (dev_id, port_id, mac); + HSL_API_UNLOCK; + return rv; +} +/*qca808x_end*/ +/** + * @brief Set phy interface mode. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] interface mode.. + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_interface_mode_set (a_uint32_t dev_id, fal_port_t port_id, + fal_port_interface_mode_t mode) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _scomphy_port_interface_mode_set (dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set phy interface mode. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] interface mode.. + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_interface_mode_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_interface_mode_t * mode) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _scomphy_port_interface_mode_get (dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} +/*qca808x_start*/ +/** + * @brief Set phy interface mode status. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] interface mode.. + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_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; + HSL_API_LOCK; + rv = _scomphy_port_interface_mode_status_get (dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} +#endif + +/** + * @brief Get link status on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] status link status up (A_TRUE) or down (A_FALSE) + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_link_status_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _scomphy_port_link_status_get (dev_id, port_id, status); + HSL_API_UNLOCK; + return rv; +} + +#ifndef IN_PORTCONTROL_MINI +/** + * @brief Set counter status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_counter_set (a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _scomphy_port_counter_set (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get counter status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_counter_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _scomphy_port_counter_get (dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get counter statistics on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] frame counter statistics + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_port_counter_show(a_uint32_t dev_id, fal_port_t port_id, + fal_port_counter_info_t * counter_info) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _scomphy_port_counter_show (dev_id, port_id, counter_info); + HSL_API_UNLOCK; + return rv; +} +#endif + +/** + * @brief software reset on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] + * @return SW_OK or error code + */ +sw_error_t +scomphy_port_reset (a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + HSL_API_LOCK; + rv = _scomphy_port_reset (dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +#ifndef IN_PORTCONTROL_MINI +/** + * @brief Get phy id on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] org_id and rev_id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +scomphy_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; + + HSL_API_LOCK; + rv = _scomphy_port_phy_id_get (dev_id, port_id, org_id,rev_id); + HSL_API_UNLOCK; + return rv; +} +#endif + +sw_error_t +scomphy_port_ctrl_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->port_duplex_get = scomphy_port_duplex_get; + p_api->port_duplex_set = scomphy_port_duplex_set; + p_api->port_speed_get = scomphy_port_speed_get; + p_api->port_speed_set = scomphy_port_speed_set; + p_api->port_autoneg_status_get = scomphy_port_autoneg_status_get; + p_api->port_autoneg_enable = scomphy_port_autoneg_enable; + p_api->port_autoneg_restart = scomphy_port_autoneg_restart; + p_api->port_autoneg_adv_get = scomphy_port_autoneg_adv_get; + p_api->port_autoneg_adv_set = scomphy_port_autoneg_adv_set; +#ifndef IN_PORTCONTROL_MINI + p_api->port_powersave_set = scomphy_port_powersave_set; + p_api->port_powersave_get = scomphy_port_powersave_get; + p_api->port_hibernate_set = scomphy_port_hibernate_set; + p_api->port_hibernate_get = scomphy_port_hibernate_get; + p_api->port_cdt = scomphy_port_cdt; + p_api->port_8023az_set = scomphy_port_8023az_set; + p_api->port_8023az_get = scomphy_port_8023az_get; + p_api->port_mdix_set = scomphy_port_mdix_set; + p_api->port_mdix_get = scomphy_port_mdix_get; + p_api->port_mdix_status_get = scomphy_port_mdix_status_get; +/*qca808x_end*/ + p_api->port_combo_prefer_medium_set = scomphy_port_combo_prefer_medium_set; + p_api->port_combo_prefer_medium_get = scomphy_port_combo_prefer_medium_get; + p_api->port_combo_medium_status_get = scomphy_port_combo_medium_status_get; + p_api->port_combo_fiber_mode_set = scomphy_port_combo_fiber_mode_set; + p_api->port_combo_fiber_mode_get = scomphy_port_combo_fiber_mode_get; +/*qca808x_start*/ + p_api->port_local_loopback_set = scomphy_port_local_loopback_set; + p_api->port_local_loopback_get = scomphy_port_local_loopback_get; + p_api->port_remote_loopback_set = scomphy_port_remote_loopback_set; + p_api->port_remote_loopback_get = scomphy_port_remote_loopback_get; +#endif + p_api->port_power_off = scomphy_port_power_off; + p_api->port_power_on = scomphy_port_power_on; +#ifndef IN_PORTCONTROL_MINI + p_api->port_wol_status_set = scomphy_port_wol_status_set; + p_api->port_wol_status_get = scomphy_port_wol_status_get; + p_api->port_magic_frame_mac_set = scomphy_port_magic_frame_mac_set; + p_api->port_magic_frame_mac_get = scomphy_port_magic_frame_mac_get; +/*qca808x_end*/ + p_api->port_interface_mode_set = scomphy_port_interface_mode_set; + p_api->port_interface_mode_get = scomphy_port_interface_mode_get; +/*qca808x_start*/ + p_api->port_interface_mode_status_get = scomphy_port_interface_mode_status_get; + p_api->port_counter_set = scomphy_port_counter_set; + p_api->port_counter_get = scomphy_port_counter_get; + p_api->port_counter_show = scomphy_port_counter_show; +#endif + p_api->port_link_status_get = scomphy_port_link_status_get; + p_api->port_reset = scomphy_port_reset; +#ifndef IN_PORTCONTROL_MINI + p_api->port_phy_id_get = scomphy_port_phy_id_get; +#endif + } +#endif + + return SW_OK; +} + +/** + * @} + */ +/*qca808x_end*/ diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/scomphy/scomphy_reg_access.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/scomphy/scomphy_reg_access.c new file mode 100755 index 000000000..ed6f83c99 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/scomphy/scomphy_reg_access.c @@ -0,0 +1,147 @@ +/* + * 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. + */ + +/*qca808x_start*/ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "sd.h" +#include "scomphy_reg_access.h" +#include "hsl_phy.h" + +#if defined(API_LOCK) +static aos_lock_t mdio_lock; +#define MDIO_LOCKER_INIT aos_lock_init(&mdio_lock) +#define MDIO_LOCKER_LOCK aos_lock(&mdio_lock) +#define MDIO_LOCKER_UNLOCK aos_unlock(&mdio_lock) +#else +#define MDIO_LOCKER_INIT +#define MDIO_LOCKER_LOCK +#define MDIO_LOCKER_UNLOCK +#endif + +sw_error_t +scomphy_phy_get(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t * value) +{ + sw_error_t rv; + + MDIO_LOCKER_LOCK; + rv = sd_reg_mdio_get(dev_id, phy_addr, reg, value); + MDIO_LOCKER_UNLOCK; + return rv; +} + +sw_error_t +scomphy_phy_set(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t value) +{ + sw_error_t rv; + + MDIO_LOCKER_LOCK; + rv = sd_reg_mdio_set(dev_id, phy_addr, reg, value); + MDIO_LOCKER_UNLOCK; + return rv; +} + +sw_error_t +scomphy_phy_i2c_get(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t * value) +{ + sw_error_t rv; + + rv = sd_reg_i2c_get(dev_id, phy_addr, reg, value); + + return rv; +} + +sw_error_t +scomphy_phyi2c_set(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t value) +{ + sw_error_t rv; + + rv = sd_reg_i2c_set(dev_id, phy_addr, reg, value); + + return rv; +} +/*qca808x_end*/ +sw_error_t +scomphy_reg_get(a_uint32_t dev_id, a_uint32_t reg_addr, + a_uint8_t *val, a_uint32_t len) +{ + sw_error_t rv; + + rv = sd_reg_hdr_get(dev_id, reg_addr, val, len); + + return rv; +} + +sw_error_t +scomphy_reg_set(a_uint32_t dev_id, a_uint32_t reg_addr, + a_uint8_t *val, a_uint32_t len) +{ + sw_error_t rv; + + rv = sd_reg_hdr_set(dev_id, reg_addr, val, len); + + return rv; +} + +sw_error_t +scomphy_uniphy_reg_get(a_uint32_t dev_id, a_uint32_t index, + a_uint32_t reg_addr, a_uint8_t *val, a_uint32_t len) +{ + sw_error_t rv; + + rv = sd_reg_uniphy_get(dev_id, index, reg_addr, val, len); + + return rv; +} + +sw_error_t +scomphy_uniphy_reg_set(a_uint32_t dev_id, a_uint32_t index, + a_uint32_t reg_addr, a_uint8_t *val, a_uint32_t len) +{ + sw_error_t rv; + + rv = sd_reg_uniphy_set(dev_id, index, reg_addr, val, len); + + return rv; +} +/*qca808x_start*/ +sw_error_t +scomphy_reg_access_init(a_uint32_t dev_id, ssdk_init_cfg *cfg) +{ + hsl_api_t *p_api; + + MDIO_LOCKER_INIT; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->phy_get = scomphy_phy_get; + p_api->phy_set = scomphy_phy_set; + p_api->phy_i2c_get = scomphy_phy_i2c_get; + p_api->phy_i2c_set = scomphy_phyi2c_set; +/*qca808x_end*/ + if(cfg->phy_id == MP_GEPHY) + { + p_api->reg_get = scomphy_reg_get; + p_api->reg_set = scomphy_reg_set; + p_api->uniphy_reg_get = scomphy_uniphy_reg_get; + p_api->uniphy_reg_set = scomphy_uniphy_reg_set; + } +/*qca808x_start*/ + return SW_OK; +} +/*qca808x_end*/ diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/sfp/Makefile b/feeds/ipq807x/qca-ssdk/src/src/hsl/sfp/Makefile new file mode 100755 index 000000000..550ba4de2 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/sfp/Makefile @@ -0,0 +1,16 @@ +LOC_DIR=src/hsl/sfp +LIB=HSL + +include $(PRJ_PATH)/make/config.mk + +SRC_LIST= + +ifeq (TRUE, $(IN_SFP)) + SRC_LIST+=sfp.c sfp_access.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/src/src/hsl/sfp/sfp.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/sfp/sfp.c new file mode 100644 index 000000000..4f5ca0f60 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/sfp/sfp.c @@ -0,0 +1,2296 @@ +/* + * 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 + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "sfp_access.h" +#include "sfp_reg.h" + +sw_error_t +sfp_eeprom_data_get(a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t i2c_addr, + a_uint32_t offset, a_uint8_t *buf, a_uint32_t count) +{ + return sfp_data_tbl_get( + dev_id, index, i2c_addr, + offset, + buf, count); + +} + +sw_error_t +sfp_eeprom_data_set(a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t i2c_addr, + a_uint32_t offset, a_uint8_t *buf, a_uint32_t count) +{ + return sfp_data_tbl_set( + dev_id, index, i2c_addr, + offset, + buf, count); + +} + +sw_error_t +sfp_dev_type_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_dev_type_u *value) +{ + return sfp_data_get( + dev_id, index, SFP_EEPROM_BASE_A0, + SFP_BASE_ADDR + SFP_DEV_TYPE_ADDRESS, + &value->val); +} + +sw_error_t +sfp_dev_type_ext_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_dev_type_ext_u *value) +{ + return sfp_data_get( + dev_id, index, SFP_EEPROM_BASE_A0, + SFP_BASE_ADDR + SFP_DEV_TYPE_EXT_ADDRESS, + &value->val); +} + +sw_error_t +sfp_dev_connector_type_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_dev_connector_type_u *value) +{ + return sfp_data_get( + dev_id, index, SFP_EEPROM_BASE_A0, + SFP_BASE_ADDR + SFP_DEV_CONNECTOR_TYPE_ADDRESS, + &value->val); +} + +sw_error_t +sfp_transc_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_transc_u *value) +{ + return sfp_data_tbl_get( + dev_id, index, SFP_EEPROM_BASE_A0, + SFP_BASE_ADDR + SFP_TRANSC_ADDRESS, + value->val, 8); +} + +sw_error_t +sfp_encoding_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_encoding_u *value) +{ + return sfp_data_get( + dev_id, index, SFP_EEPROM_BASE_A0, + SFP_BASE_ADDR + SFP_ENCODING_ADDRESS, + &value->val); +} + +sw_error_t +sfp_br_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_br_u *value) +{ + return sfp_data_get( + dev_id, index, SFP_EEPROM_BASE_A0, + SFP_BASE_ADDR + SFP_BR_ADDRESS, + &value->val); +} + +sw_error_t +sfp_rate_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_rate_u *value) +{ + return sfp_data_get( + dev_id, index, SFP_EEPROM_BASE_A0, + SFP_BASE_ADDR + SFP_RATE_ADDRESS, + &value->val); +} + +sw_error_t +sfp_link_len_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_link_len_u *value) +{ + return sfp_data_tbl_get( + dev_id, index, SFP_EEPROM_BASE_A0, + SFP_BASE_ADDR + SFP_LINK_LEN_ADDRESS, + value->val, 6); +} + +sw_error_t +sfp_vendor_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_vendor_u *value) +{ + return sfp_data_tbl_get( + dev_id, index, SFP_EEPROM_BASE_A0, + SFP_BASE_ADDR + SFP_VENDOR_ADDRESS, + value->val, 40); +} + +sw_error_t +sfp_laser_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_laser_u *value) +{ + return sfp_data_tbl_get( + dev_id, index, SFP_EEPROM_BASE_A0, + SFP_BASE_ADDR + SFP_LASER_ADDRESS, + value->val, 2); +} + +sw_error_t +sfp_base_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_base_u *value) +{ + return sfp_data_get( + dev_id, index, SFP_EEPROM_BASE_A0, + SFP_BASE_ADDR + SFP_BASE_ADDRESS, + &value->val); +} + +sw_error_t +sfp_option_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_option_u *value) +{ + return sfp_data_tbl_get( + dev_id, index, SFP_EEPROM_BASE_A0, + SFP_BASE_ADDR + SFP_OPTION_ADDRESS, + value->val, 2); +} + +sw_error_t +sfp_rate_ctrl_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_rate_ctrl_u *value) +{ + return sfp_data_tbl_get( + dev_id, index, SFP_EEPROM_BASE_A0, + SFP_BASE_ADDR + SFP_RATE_CTRL_ADDRESS, + value->val, 2); +} + +sw_error_t +sfp_vendor_ext_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_vendor_ext_u *value) +{ + return sfp_data_tbl_get( + dev_id, index, SFP_EEPROM_BASE_A0, + SFP_BASE_ADDR + SFP_VENDOR_EXT_ADDRESS, + value->val, 24); +} + +sw_error_t +sfp_enhanced_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_enhanced_u *value) +{ + return sfp_data_tbl_get( + dev_id, index, SFP_EEPROM_BASE_A0, + SFP_BASE_ADDR + SFP_ENHANCED_ADDRESS, + value->val, 3); +} + +sw_error_t +sfp_ext_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_ext_u *value) +{ + return sfp_data_get( + dev_id, index, SFP_EEPROM_BASE_A0, + SFP_BASE_ADDR + SFP_EXT_ADDRESS, + &value->val); +} + +sw_error_t +sfp_dev_type_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_dev_type_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_dev_type_get(dev_id, index, ®_val); + *value = reg_val.bf.id; + return ret; +} + +sw_error_t +sfp_dev_type_ext_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_dev_type_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_dev_type_ext_get(dev_id, index, ®_val); + *value = reg_val.bf.id; + return ret; +} + +sw_error_t +sfp_dev_connector_type_code_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_dev_connector_type_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_dev_connector_type_get(dev_id, index, ®_val); + *value = reg_val.bf.code; + return ret; +} + +sw_error_t +sfp_transc_sonet_ccode_2_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_transc_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_transc_get(dev_id, index, ®_val); + *value = reg_val.bf.sonet_ccode_2; + return ret; +} + +sw_error_t +sfp_transc_fiber_ch_tech_1_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_transc_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_transc_get(dev_id, index, ®_val); + *value = reg_val.bf.fiber_ch_tech_1; + return ret; +} + +sw_error_t +sfp_transc_sonet_ccode_1_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_transc_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_transc_get(dev_id, index, ®_val); + *value = reg_val.bf.sonet_ccode_1; + return ret; +} + +sw_error_t +sfp_transc_fiber_ch_speed_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_transc_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_transc_get(dev_id, index, ®_val); + *value = reg_val.bf.fiber_ch_speed; + return ret; +} + +sw_error_t +sfp_transc_fiber_ch_tech_2_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_transc_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_transc_get(dev_id, index, ®_val); + *value = reg_val.bf.fiber_ch_tech_2; + return ret; +} + +sw_error_t +sfp_transc_cable_tech_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_transc_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_transc_get(dev_id, index, ®_val); + *value = reg_val.bf.cable_tech; + return ret; +} + +sw_error_t +sfp_transc_fiber_ch_link_len_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_transc_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_transc_get(dev_id, index, ®_val); + *value = reg_val.bf.fiber_ch_link_len; + return ret; +} + +sw_error_t +sfp_transc_unallocated_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_transc_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_transc_get(dev_id, index, ®_val); + *value = reg_val.bf.unallocated; + return ret; +} + +sw_error_t +sfp_transc_fiber_chan_tm_media_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_transc_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_transc_get(dev_id, index, ®_val); + *value = reg_val.bf.fiber_chan_tm_media; + return ret; +} + +sw_error_t +sfp_transc_escon_ccode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_transc_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_transc_get(dev_id, index, ®_val); + *value = reg_val.bf.escon_ccode; + return ret; +} + +sw_error_t +sfp_transc_infiniband_ccode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_transc_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_transc_get(dev_id, index, ®_val); + *value = reg_val.bf.infiniband_ccode; + return ret; +} + +sw_error_t +sfp_transc_eth_ccode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_transc_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_transc_get(dev_id, index, ®_val); + *value = reg_val.bf.eth_ccode; + return ret; +} + +sw_error_t +sfp_transc_eth_10g_ccode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_transc_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_transc_get(dev_id, index, ®_val); + *value = reg_val.bf.eth_10g_ccode; + return ret; +} + +sw_error_t +sfp_encoding_code_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_encoding_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_encoding_get(dev_id, index, ®_val); + *value = reg_val.bf.code; + return ret; +} + +sw_error_t +sfp_br_bit_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_br_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_br_get(dev_id, index, ®_val); + *value = reg_val.bf.bit; + return ret; +} + +sw_error_t +sfp_rate_id_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_rate_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_rate_get(dev_id, index, ®_val); + *value = reg_val.bf.id; + return ret; +} + +sw_error_t +sfp_link_len_om3_mode_1m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_link_len_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_link_len_get(dev_id, index, ®_val); + *value = reg_val.bf.om3_mode_1m; + return ret; +} + +sw_error_t +sfp_link_len_single_mode_100m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_link_len_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_link_len_get(dev_id, index, ®_val); + *value = reg_val.bf.single_mode_100m; + return ret; +} + +sw_error_t +sfp_link_len_om2_mode_10m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_link_len_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_link_len_get(dev_id, index, ®_val); + *value = reg_val.bf.om2_mode_10m; + return ret; +} + +sw_error_t +sfp_link_len_copper_mode_1m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_link_len_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_link_len_get(dev_id, index, ®_val); + *value = reg_val.bf.copper_mode_1m; + return ret; +} + +sw_error_t +sfp_link_len_om1_mode_10m_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_link_len_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_link_len_get(dev_id, index, ®_val); + *value = reg_val.bf.om1_mode_10m; + return ret; +} + +sw_error_t +sfp_link_len_single_mode_km_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_link_len_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_link_len_get(dev_id, index, ®_val); + *value = reg_val.bf.single_mode_km; + return ret; +} + +sw_error_t +sfp_vendor_rev_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint8_t value[4]) +{ + union sfp_vendor_u reg_val; + sw_error_t ret = SW_OK; + a_uint8_t i; + + ret = sfp_vendor_get(dev_id, index, ®_val); + + for (i = 0; i < 4; i++) { + value[i] = reg_val.val[i]; + } + + return ret; +} + +sw_error_t +sfp_vendor_name_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint8_t value[16]) +{ + union sfp_vendor_u reg_val; + sw_error_t ret = SW_OK; + a_uint8_t i; + + ret = sfp_vendor_get(dev_id, index, ®_val); + + for (i = 0; i < 16; i++) { + value[i] = reg_val.val[i]; + } + + return ret; +} + +sw_error_t +sfp_vendor_oui_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint8_t value[3]) +{ + union sfp_vendor_u reg_val; + sw_error_t ret = SW_OK; + a_uint8_t i; + + ret = sfp_vendor_get(dev_id, index, ®_val); + + for (i = 0; i < 3; i++) { + value[i] = reg_val.val[i]; + } + + return ret; +} + +sw_error_t +sfp_vendor_pn_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint8_t value[16]) +{ + union sfp_vendor_u reg_val; + sw_error_t ret = SW_OK; + a_uint8_t i; + + ret = sfp_vendor_get(dev_id, index, ®_val); + + for (i = 0; i < 16; i++) { + value[i] = reg_val.val[i]; + } + + return ret; +} +sw_error_t +sfp_laser_wavelength_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_laser_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_laser_get(dev_id, index, ®_val); + *value = reg_val.bf.wavelength_0 << 8 + | reg_val.bf.wavelength_1; + return ret; +} + +sw_error_t +sfp_base_check_code_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_base_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_base_get(dev_id, index, ®_val); + *value = reg_val.bf.check_code; + return ret; +} + +sw_error_t +sfp_option_linear_recv_output_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_option_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_option_get(dev_id, index, ®_val); + *value = reg_val.bf.linear_recv_output; + return ret; +} + +sw_error_t +sfp_option_pwr_level_declar_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_option_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_option_get(dev_id, index, ®_val); + *value = reg_val.bf.pwr_level_declar; + return ret; +} + +sw_error_t +sfp_option_unallocated_1_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_option_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_option_get(dev_id, index, ®_val); + *value = reg_val.bf.unallocated_1; + return ret; +} + +sw_error_t +sfp_option_unallocated_3_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_option_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_option_get(dev_id, index, ®_val); + *value = reg_val.bf.unallocated_3; + return ret; +} + +sw_error_t +sfp_option_loss_signal_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_option_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_option_get(dev_id, index, ®_val); + *value = reg_val.bf.loss_signal; + return ret; +} + +sw_error_t +sfp_option_rate_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_option_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_option_get(dev_id, index, ®_val); + *value = reg_val.bf.rate_sel; + return ret; +} + +sw_error_t +sfp_option_unallocated_2_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_option_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_option_get(dev_id, index, ®_val); + *value = reg_val.bf.unallocated_2; + return ret; +} + +sw_error_t +sfp_option_loss_invert_signal_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_option_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_option_get(dev_id, index, ®_val); + *value = reg_val.bf.loss_invert_signal; + return ret; +} + +sw_error_t +sfp_option_tx_disable_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_option_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_option_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_disable; + return ret; +} + +sw_error_t +sfp_option_cool_transc_declar_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_option_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_option_get(dev_id, index, ®_val); + *value = reg_val.bf.cool_transc_declar; + return ret; +} + +sw_error_t +sfp_option_tx_fault_signal_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_option_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_option_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_fault_signal; + return ret; +} + +sw_error_t +sfp_rate_ctrl_upper_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_rate_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_rate_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.upper; + return ret; +} + +sw_error_t +sfp_rate_ctrl_lower_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_rate_ctrl_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_rate_ctrl_get(dev_id, index, ®_val); + *value = reg_val.bf.lower; + return ret; +} + +sw_error_t +sfp_vendor_ext_date_code_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint8_t value[8]) +{ + union sfp_vendor_ext_u reg_val; + sw_error_t ret = SW_OK; + a_uint8_t i; + + ret = sfp_vendor_ext_get(dev_id, index, ®_val); + + for (i = 0; i < 8; i++) { + value[i] = reg_val.val[i]; + } + + return ret; +} + +sw_error_t +sfp_vendor_ext_sn_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint8_t value[16]) +{ + union sfp_vendor_ext_u reg_val; + sw_error_t ret = SW_OK; + a_uint8_t i; + + ret = sfp_vendor_ext_get(dev_id, index, ®_val); + + for (i = 0; i < 16; i++) { + value[i] = reg_val.val[i]; + } + + return ret; +} + +sw_error_t +sfp_enhanced_diag_mon_flag_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_enhanced_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_enhanced_get(dev_id, index, ®_val); + *value = reg_val.bf.diag_mon_flag; + return ret; +} + +sw_error_t +sfp_enhanced_rx_los_op_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_enhanced_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_enhanced_get(dev_id, index, ®_val); + *value = reg_val.bf.rx_los_op; + return ret; +} + +sw_error_t +sfp_enhanced_cmpl_feature_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_enhanced_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_enhanced_get(dev_id, index, ®_val); + *value = reg_val.bf.cmpl_feature; + return ret; +} + +sw_error_t +sfp_enhanced_tx_disable_ctrl_op_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_enhanced_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_enhanced_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_disable_ctrl_op; + return ret; +} + +sw_error_t +sfp_enhanced_alarm_warning_flag_op_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_enhanced_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_enhanced_get(dev_id, index, ®_val); + *value = reg_val.bf.alarm_warning_flag_op; + return ret; +} + +sw_error_t +sfp_enhanced_addr_mode_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_enhanced_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_enhanced_get(dev_id, index, ®_val); + *value = reg_val.bf.addr_mode; + return ret; +} + +sw_error_t +sfp_enhanced_unallocated_op_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_enhanced_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_enhanced_get(dev_id, index, ®_val); + *value = reg_val.bf.unallocated_op; + return ret; +} + +sw_error_t +sfp_enhanced_soft_rate_sel_op_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_enhanced_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_enhanced_get(dev_id, index, ®_val); + *value = reg_val.bf.soft_rate_sel_op; + return ret; +} + +sw_error_t +sfp_enhanced_external_cal_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_enhanced_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_enhanced_get(dev_id, index, ®_val); + *value = reg_val.bf.external_cal; + return ret; +} + +sw_error_t +sfp_enhanced_internal_cal_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_enhanced_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_enhanced_get(dev_id, index, ®_val); + *value = reg_val.bf.internal_cal; + return ret; +} + +sw_error_t +sfp_enhanced_re_pwr_type_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_enhanced_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_enhanced_get(dev_id, index, ®_val); + *value = reg_val.bf.re_pwr_type; + return ret; +} + +sw_error_t +sfp_enhanced_soft_rate_ctrl_op_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_enhanced_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_enhanced_get(dev_id, index, ®_val); + *value = reg_val.bf.soft_rate_ctrl_op; + return ret; +} + +sw_error_t +sfp_enhanced_app_sel_op_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_enhanced_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_enhanced_get(dev_id, index, ®_val); + *value = reg_val.bf.app_sel_op; + return ret; +} + +sw_error_t +sfp_enhanced_legacy_type_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_enhanced_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_enhanced_get(dev_id, index, ®_val); + *value = reg_val.bf.legacy_type; + return ret; +} + +sw_error_t +sfp_enhanced_tx_fault_op_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_enhanced_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_enhanced_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_fault_op; + return ret; +} + +sw_error_t +sfp_enhanced_unallocated_type_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_enhanced_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_enhanced_get(dev_id, index, ®_val); + *value = reg_val.bf.unallocated_type; + return ret; +} + +sw_error_t +sfp_ext_check_code_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_ext_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_ext_get(dev_id, index, ®_val); + *value = reg_val.bf.check_code; + return ret; +} + +sw_error_t +sfp_diag_threshold_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_diag_threshold_u *value) +{ + return sfp_data_tbl_get( + dev_id, index, SFP_EEPROM_DIAG_A2, + SFP_DIAG_BASE_ADDR + SFP_DIAG_THRESHOLD_ADDRESS, + value->val, 40); +} + +sw_error_t +sfp_diag_cal_const_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_diag_cal_const_u *value) +{ + return sfp_data_tbl_get( + dev_id, index, SFP_EEPROM_DIAG_A2, + SFP_DIAG_BASE_ADDR + SFP_DIAG_CAL_CONST_ADDRESS, + value->val, 36); +} + +sw_error_t +sfp_diag_dmi_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_diag_dmi_u *value) +{ + return sfp_data_get( + dev_id, index, SFP_EEPROM_DIAG_A2, + SFP_DIAG_BASE_ADDR + SFP_DIAG_DMI_ADDRESS, + &value->val); +} + +sw_error_t +sfp_diag_realtime_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_diag_realtime_u *value) +{ + return sfp_data_tbl_get( + dev_id, index, SFP_EEPROM_DIAG_A2, + SFP_DIAG_BASE_ADDR + SFP_DIAG_REALTIME_ADDRESS, + value->val, 10); +} + +sw_error_t +sfp_diag_optional_ctrl_status_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_diag_optional_ctrl_status_u *value) +{ + return sfp_data_get( + dev_id, index, SFP_EEPROM_DIAG_A2, + SFP_DIAG_BASE_ADDR + SFP_DIAG_OPTIONAL_CTRL_STATUS_ADDRESS, + value->val); +} + +sw_error_t +sfp_diag_flag_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_diag_flag_u *value) +{ + return sfp_data_tbl_get( + dev_id, index, SFP_EEPROM_DIAG_A2, + SFP_DIAG_BASE_ADDR + SFP_DIAG_FLAG_ADDRESS, + value->val, 6); +} + +sw_error_t +sfp_diag_extended_ctrl_status_get( + a_uint32_t dev_id, + a_uint32_t index, + union sfp_diag_extended_ctrl_status_u *value) +{ + return sfp_data_tbl_get( + dev_id, index, SFP_EEPROM_DIAG_A2, + SFP_DIAG_BASE_ADDR + SFP_DIAG_EXTENDED_CTRL_STATUS_ADDRESS, + value->val, 2); +} + +sw_error_t +sfp_diag_threshold_rx_pwr_low_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_threshold_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_threshold_get(dev_id, index, ®_val); + *value = reg_val.bf.rx_pwr_low_alarm_0 << 8 | \ + reg_val.bf.rx_pwr_low_alarm_1; + return ret; +} + +sw_error_t +sfp_diag_threshold_rx_pwr_high_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_threshold_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_threshold_get(dev_id, index, ®_val); + *value = reg_val.bf.rx_pwr_high_warning_0 << 8 | \ + reg_val.bf.rx_pwr_high_warning_1; + return ret; +} + +sw_error_t +sfp_diag_threshold_temp_low_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_threshold_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_threshold_get(dev_id, index, ®_val); + *value = reg_val.bf.temp_low_alarm_0 << 8 | \ + reg_val.bf.temp_low_alarm_1; + return ret; +} + +sw_error_t +sfp_diag_threshold_vol_high_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_threshold_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_threshold_get(dev_id, index, ®_val); + *value = reg_val.bf.vol_high_alarm_0 << 8 | \ + reg_val.bf.vol_high_alarm_1; + return ret; +} + +sw_error_t +sfp_diag_threshold_tx_pwr_high_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_threshold_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_threshold_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_pwr_high_alarm_0 << 8 | \ + reg_val.bf.tx_pwr_high_alarm_1; + return ret; +} + +sw_error_t +sfp_diag_threshold_bias_low_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_threshold_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_threshold_get(dev_id, index, ®_val); + *value = reg_val.bf.bias_low_alarm_0 << 8 | \ + reg_val.bf.bias_low_alarm_1; + return ret; +} + +sw_error_t +sfp_diag_threshold_bias_high_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_threshold_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_threshold_get(dev_id, index, ®_val); + *value = reg_val.bf.bias_high_alarm_0 << 8 | \ + reg_val.bf.bias_high_alarm_1; + return ret; +} + +sw_error_t +sfp_diag_threshold_vol_low_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_threshold_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_threshold_get(dev_id, index, ®_val); + *value = reg_val.bf.vol_low_alarm_0 << 8 | \ + reg_val.bf.vol_low_alarm_1; + return ret; +} + +sw_error_t +sfp_diag_threshold_bias_high_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_threshold_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_threshold_get(dev_id, index, ®_val); + *value = reg_val.bf.bias_high_warning_0 << 8 | \ + reg_val.bf.bias_high_warning_1; + return ret; +} + +sw_error_t +sfp_diag_threshold_temp_high_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_threshold_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_threshold_get(dev_id, index, ®_val); + *value = reg_val.bf.temp_high_warning_0 << 8 | \ + reg_val.bf.temp_high_warning_1; + return ret; +} + +sw_error_t +sfp_diag_threshold_rx_pwr_low_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_threshold_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_threshold_get(dev_id, index, ®_val); + *value = reg_val.bf.rx_pwr_low_warning_0 << 8 | \ + reg_val.bf.rx_pwr_low_warning_1; + return ret; +} + +sw_error_t +sfp_diag_threshold_vol_low_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_threshold_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_threshold_get(dev_id, index, ®_val); + *value = reg_val.bf.vol_low_warning_0 << 8 | \ + reg_val.bf.vol_low_warning_1; + return ret; +} + +sw_error_t +sfp_diag_threshold_tx_pwr_low_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_threshold_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_threshold_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_pwr_low_alarm_0 << 8 | \ + reg_val.bf.tx_pwr_low_alarm_1; + return ret; +} + +sw_error_t +sfp_diag_threshold_bias_low_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_threshold_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_threshold_get(dev_id, index, ®_val); + *value = reg_val.bf.bias_low_warning_0 << 8 | \ + reg_val.bf.bias_low_warning_1; + return ret; +} + +sw_error_t +sfp_diag_threshold_temp_high_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_threshold_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_threshold_get(dev_id, index, ®_val); + *value = reg_val.bf.temp_high_alarm_0 << 8 | \ + reg_val.bf.temp_high_alarm_1; + return ret; +} + +sw_error_t +sfp_diag_threshold_tx_pwr_high_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_threshold_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_threshold_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_pwr_high_warning_0 << 8 | \ + reg_val.bf.tx_pwr_high_warning_1; + return ret; +} + +sw_error_t +sfp_diag_threshold_vol_high_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_threshold_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_threshold_get(dev_id, index, ®_val); + *value = reg_val.bf.vol_high_warning_0 << 8 | \ + reg_val.bf.vol_high_warning_1; + return ret; +} + +sw_error_t +sfp_diag_threshold_temp_low_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_threshold_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_threshold_get(dev_id, index, ®_val); + *value = reg_val.bf.temp_low_warning_0 << 8 | \ + reg_val.bf.temp_low_warning_1; + return ret; +} + +sw_error_t +sfp_diag_threshold_rx_pwr_high_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_threshold_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_threshold_get(dev_id, index, ®_val); + *value = reg_val.bf.rx_pwr_high_alarm_0 << 8 | \ + reg_val.bf.rx_pwr_high_alarm_1; + return ret; +} + +sw_error_t +sfp_diag_threshold_tx_pwr_low_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_threshold_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_threshold_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_pwr_low_warning_0 << 8 | \ + reg_val.bf.tx_pwr_low_warning_1; + return ret; +} + +sw_error_t +sfp_diag_cal_const_rx_pwr_1_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_cal_const_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_cal_const_get(dev_id, index, ®_val); + *value = reg_val.bf.rx_pwr_1_0 << 24 | \ + reg_val.bf.rx_pwr_1_1 << 16 | \ + reg_val.bf.rx_pwr_1_2 << 8 | \ + reg_val.bf.rx_pwr_1_3; + return ret; +} + +sw_error_t +sfp_diag_cal_const_t_slope_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_cal_const_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_cal_const_get(dev_id, index, ®_val); + *value = reg_val.bf.t_slope_0 << 8 | \ + reg_val.bf.t_slope_1; + return ret; +} + +sw_error_t +sfp_diag_cal_const_rx_pwr_3_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_cal_const_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_cal_const_get(dev_id, index, ®_val); + *value = reg_val.bf.rx_pwr_3_0 << 24 | \ + reg_val.bf.rx_pwr_3_1 << 16 | \ + reg_val.bf.rx_pwr_3_2 << 8 | \ + reg_val.bf.rx_pwr_3_3; + return ret; +} + +sw_error_t +sfp_diag_cal_const_v_offset_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_cal_const_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_cal_const_get(dev_id, index, ®_val); + *value = reg_val.bf.v_offset_0 << 8 | \ + reg_val.bf.v_offset_1; + return ret; +} + +sw_error_t +sfp_diag_cal_const_rx_pwr_2_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_cal_const_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_cal_const_get(dev_id, index, ®_val); + *value = reg_val.bf.rx_pwr_2_0 << 24 | \ + reg_val.bf.rx_pwr_2_1 << 16 | \ + reg_val.bf.rx_pwr_2_2 << 8 | \ + reg_val.bf.rx_pwr_2_3; + return ret; +} + +sw_error_t +sfp_diag_cal_const_tx_i_slope_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_cal_const_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_cal_const_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_i_slope_0 << 8 | \ + reg_val.bf.tx_i_slope_1; + return ret; +} + +sw_error_t +sfp_diag_cal_const_tx_i_offset_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_cal_const_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_cal_const_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_i_offset_0 << 8 | \ + reg_val.bf.tx_i_offset_1; + return ret; +} + +sw_error_t +sfp_diag_cal_const_v_slope_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_cal_const_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_cal_const_get(dev_id, index, ®_val); + *value = reg_val.bf.v_slope_0 << 8 | \ + reg_val.bf.v_slope_1; + return ret; +} + +sw_error_t +sfp_diag_cal_const_t_offset_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_cal_const_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_cal_const_get(dev_id, index, ®_val); + *value = reg_val.bf.t_offset_0 << 8 | \ + reg_val.bf.t_offset_1; + return ret; +} + +sw_error_t +sfp_diag_cal_const_tx_pwr_offset_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_cal_const_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_cal_const_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_pwr_offset_0 << 8 | \ + reg_val.bf.tx_pwr_offset_1; + return ret; +} + +sw_error_t +sfp_diag_cal_const_tx_pwr_slope_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_cal_const_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_cal_const_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_pwr_slope_0 << 8 | \ + reg_val.bf.tx_pwr_slope_1; + return ret; +} + +sw_error_t +sfp_diag_cal_const_rx_pwr_4_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_cal_const_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_cal_const_get(dev_id, index, ®_val); + *value = reg_val.bf.rx_pwr_4_0 << 24 | \ + reg_val.bf.rx_pwr_4_1 << 16 | \ + reg_val.bf.rx_pwr_4_2 << 8 | \ + reg_val.bf.rx_pwr_4_3; + return ret; +} + +sw_error_t +sfp_diag_cal_const_rx_pwr_0_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_cal_const_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_cal_const_get(dev_id, index, ®_val); + *value = reg_val.bf.rx_pwr_0_0 << 24 | \ + reg_val.bf.rx_pwr_0_1 << 16 | \ + reg_val.bf.rx_pwr_0_2 << 8 | \ + reg_val.bf.rx_pwr_0_3; + return ret; +} + +sw_error_t +sfp_diag_dmi_check_code_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_dmi_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_dmi_get(dev_id, index, ®_val); + *value = reg_val.bf.check_code; + return ret; +} + +sw_error_t +sfp_diag_realtime_vcc_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_realtime_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_realtime_get(dev_id, index, ®_val); + *value = reg_val.bf.vcc_1 << 8 | \ + reg_val.bf.vcc_0; + return ret; +} + +sw_error_t +sfp_diag_realtime_tx_pwr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_realtime_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_realtime_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_pwr_1 << 8 | \ + reg_val.bf.tx_pwr_0; + return ret; +} + +sw_error_t +sfp_diag_realtime_tx_bias_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_realtime_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_realtime_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_bias_1 << 8 | \ + reg_val.bf.tx_bias_0; + return ret; +} + +sw_error_t +sfp_diag_realtime_rx_pwr_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_realtime_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_realtime_get(dev_id, index, ®_val); + *value = reg_val.bf.rx_pwr_1 << 8 | \ + reg_val.bf.rx_pwr_0; + return ret; +} + +sw_error_t +sfp_diag_realtime_tmp_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_realtime_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_realtime_get(dev_id, index, ®_val); + *value = reg_val.bf.tmp_1 << 8 | \ + reg_val.bf.tmp_0; + return ret; +} + +sw_error_t +sfp_diag_optional_ctrl_status_rs_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_optional_ctrl_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_optional_ctrl_status_get(dev_id, index, ®_val); + *value = reg_val.bf.rs; + return ret; +} + +sw_error_t +sfp_diag_optional_ctrl_status_tx_fault_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_optional_ctrl_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_optional_ctrl_status_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_fault; + return ret; +} + +sw_error_t +sfp_diag_optional_ctrl_status_rx_los_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_optional_ctrl_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_optional_ctrl_status_get(dev_id, index, ®_val); + *value = reg_val.bf.rx_los; + return ret; +} + +sw_error_t +sfp_diag_optional_ctrl_status_data_ready_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_optional_ctrl_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_optional_ctrl_status_get(dev_id, index, ®_val); + *value = reg_val.bf.data_ready; + return ret; +} + +sw_error_t +sfp_diag_optional_ctrl_status_soft_rate_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_optional_ctrl_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_optional_ctrl_status_get(dev_id, index, ®_val); + *value = reg_val.bf.soft_rate_sel; + return ret; +} + +sw_error_t +sfp_diag_optional_ctrl_status_soft_tx_disable_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_optional_ctrl_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_optional_ctrl_status_get(dev_id, index, ®_val); + *value = reg_val.bf.soft_tx_disable_sel; + return ret; +} + +sw_error_t +sfp_diag_optional_ctrl_status_rate_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_optional_ctrl_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_optional_ctrl_status_get(dev_id, index, ®_val); + *value = reg_val.bf.rate_sel; + return ret; +} + +sw_error_t +sfp_diag_optional_ctrl_status_tx_disable_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_optional_ctrl_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_optional_ctrl_status_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_disable; + return ret; +} + +sw_error_t +sfp_diag_flag_rx_pwr_low_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_flag_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_flag_get(dev_id, index, ®_val); + *value = reg_val.bf.rx_pwr_low_alarm; + return ret; +} + +sw_error_t +sfp_diag_flag_rx_pwr_high_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_flag_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_flag_get(dev_id, index, ®_val); + *value = reg_val.bf.rx_pwr_high_warning; + return ret; +} + +sw_error_t +sfp_diag_flag_tx_bias_high_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_flag_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_flag_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_bias_high_alarm; + return ret; +} + +sw_error_t +sfp_diag_flag_tmp_high_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_flag_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_flag_get(dev_id, index, ®_val); + *value = reg_val.bf.tmp_high_alarm; + return ret; +} + +sw_error_t +sfp_diag_flag_tmp_low_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_flag_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_flag_get(dev_id, index, ®_val); + *value = reg_val.bf.tmp_low_alarm; + return ret; +} + +sw_error_t +sfp_diag_flag_tx_pwr_high_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_flag_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_flag_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_pwr_high_alarm; + return ret; +} + +sw_error_t +sfp_diag_flag_vcc_low_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_flag_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_flag_get(dev_id, index, ®_val); + *value = reg_val.bf.vcc_low_warning; + return ret; +} + +sw_error_t +sfp_diag_flag_vcc_high_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_flag_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_flag_get(dev_id, index, ®_val); + *value = reg_val.bf.vcc_high_warning; + return ret; +} + +sw_error_t +sfp_diag_flag_rx_pwr_low_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_flag_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_flag_get(dev_id, index, ®_val); + *value = reg_val.bf.rx_pwr_low_warning; + return ret; +} + +sw_error_t +sfp_diag_flag_unallocated_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_flag_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_flag_get(dev_id, index, ®_val); + *value = reg_val.bf.unallocated_1 << 8 | \ + reg_val.bf.unallocated_0; + return ret; +} + +sw_error_t +sfp_diag_flag_tx_bias_high_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_flag_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_flag_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_bias_high_warning; + return ret; +} + +sw_error_t +sfp_diag_flag_vcc_low_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_flag_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_flag_get(dev_id, index, ®_val); + *value = reg_val.bf.vcc_low_alarm; + return ret; +} + +sw_error_t +sfp_diag_flag_tx_pwr_low_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_flag_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_flag_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_pwr_low_alarm; + return ret; +} + +sw_error_t +sfp_diag_flag_vcc_high_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_flag_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_flag_get(dev_id, index, ®_val); + *value = reg_val.bf.vcc_high_alarm; + return ret; +} + +sw_error_t +sfp_diag_flag_tmp_low_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_flag_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_flag_get(dev_id, index, ®_val); + *value = reg_val.bf.tmp_low_warning; + return ret; +} + +sw_error_t +sfp_diag_flag_tx_bias_low_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_flag_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_flag_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_bias_low_warning; + return ret; +} + +sw_error_t +sfp_diag_flag_tx_bias_low_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_flag_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_flag_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_bias_low_alarm; + return ret; +} + +sw_error_t +sfp_diag_flag_tmp_high_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_flag_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_flag_get(dev_id, index, ®_val); + *value = reg_val.bf.tmp_high_warning; + return ret; +} + +sw_error_t +sfp_diag_flag_tx_pwr_high_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_flag_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_flag_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_pwr_high_warning; + return ret; +} + +sw_error_t +sfp_diag_flag_rx_pwr_high_alarm_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_flag_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_flag_get(dev_id, index, ®_val); + *value = reg_val.bf.rx_pwr_high_alarm; + return ret; +} + +sw_error_t +sfp_diag_flag_tx_pwr_low_warning_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_flag_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_flag_get(dev_id, index, ®_val); + *value = reg_val.bf.tx_pwr_low_warning; + return ret; +} + +sw_error_t +sfp_diag_extended_ctrl_status_unallocated_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_extended_ctrl_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_extended_ctrl_status_get(dev_id, index, ®_val); + *value = reg_val.bf.unallocated_0 << 8 + | reg_val.bf.unallocated_1; + return ret; +} + +sw_error_t +sfp_diag_extended_ctrl_status_pwr_level_op_state_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_extended_ctrl_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_extended_ctrl_status_get(dev_id, index, ®_val); + *value = reg_val.bf.pwr_level_op_state; + return ret; +} + +sw_error_t +sfp_diag_extended_ctrl_status_soft_rs_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_extended_ctrl_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_extended_ctrl_status_get(dev_id, index, ®_val); + *value = reg_val.bf.soft_rs_sel; + return ret; +} + +sw_error_t +sfp_diag_extended_ctrl_status_pwr_level_sel_get( + a_uint32_t dev_id, + a_uint32_t index, + a_uint32_t *value) +{ + union sfp_diag_extended_ctrl_status_u reg_val; + sw_error_t ret = SW_OK; + + ret = sfp_diag_extended_ctrl_status_get(dev_id, index, ®_val); + *value = reg_val.bf.pwr_level_sel; + return ret; +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/sfp/sfp_access.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/sfp/sfp_access.c new file mode 100755 index 000000000..4d2e6b586 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/sfp/sfp_access.c @@ -0,0 +1,59 @@ +/* + * 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 + * @{ + */ + +#include "sw.h" +#include "ssdk_init.h" +#include "ssdk_phy_i2c.h" + +sw_error_t +sfp_data_tbl_get(a_uint32_t dev_id, a_uint32_t index, a_uint32_t i2c_slave, + a_uint32_t data_addr, a_uint8_t *buf, a_uint32_t count) +{ + sw_error_t rv; + rv = qca_i2c_data_get(dev_id, i2c_slave, data_addr, buf, count); + return rv; +} + +sw_error_t +sfp_data_get(a_uint32_t dev_id, a_uint32_t index, a_uint32_t i2c_slave, + a_uint32_t data_addr, a_uint8_t *buf) +{ + sw_error_t rv; + rv = qca_i2c_data_get(dev_id, i2c_slave, data_addr, buf, 1); + return rv; +} + +sw_error_t +sfp_data_tbl_set(a_uint32_t dev_id, a_uint32_t index, a_uint32_t i2c_slave, + a_uint32_t data_addr, a_uint8_t *buf, a_uint32_t count) +{ + sw_error_t rv; + rv = qca_i2c_data_set(dev_id, i2c_slave, data_addr, buf, count); + return rv; +} + +sw_error_t +sfp_data_set(a_uint32_t dev_id, a_uint32_t index, a_uint32_t i2c_slave, + a_uint32_t data_addr, a_uint8_t *buf) +{ + sw_error_t rv; + rv = qca_i2c_data_set(dev_id, i2c_slave, data_addr, buf, 1); + return rv; +} diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/Makefile b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/Makefile new file mode 100755 index 000000000..20042efd9 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/Makefile @@ -0,0 +1,84 @@ +LOC_DIR=src/hsl/shiva +LIB=HSL + +include $(PRJ_PATH)/make/config.mk + +SRC_LIST=shiva_reg_access.c shiva_init.c + +ifeq (TRUE, $(IN_ACL)) + SRC_LIST += shiva_acl.c +endif + +ifeq (TRUE, $(IN_FDB)) + SRC_LIST += shiva_fdb.c +endif + +ifeq (TRUE, $(IN_IGMP)) + SRC_LIST += shiva_igmp.c +endif + +ifeq (TRUE, $(IN_LEAKY)) + SRC_LIST += shiva_leaky.c +endif + +ifeq (TRUE, $(IN_LED)) + SRC_LIST += shiva_led.c +endif + +ifeq (TRUE, $(IN_MIB)) + SRC_LIST += shiva_mib.c +endif + +ifeq (TRUE, $(IN_MIRROR)) + SRC_LIST += shiva_mirror.c +endif + +ifeq (TRUE, $(IN_MISC)) + SRC_LIST += shiva_misc.c +endif + +ifeq (TRUE, $(IN_PORTCONTROL)) + SRC_LIST += shiva_port_ctrl.c +endif + +ifeq (TRUE, $(IN_PORTVLAN)) + SRC_LIST += shiva_portvlan.c +endif + +ifeq (TRUE, $(IN_QOS)) + SRC_LIST += shiva_qos.c +endif + +ifeq (TRUE, $(IN_RATE)) + SRC_LIST += shiva_rate.c +endif + +ifeq (TRUE, $(IN_STP)) + SRC_LIST += shiva_stp.c +endif + +ifeq (TRUE, $(IN_VLAN)) + SRC_LIST += shiva_vlan.c +endif + +ifeq (TRUE, $(IN_REDUCED_ACL)) + SRC_LIST += shiva_reduced_acl.c +endif + +ifeq (linux, $(OS)) + ifeq (KSLIB, $(MODULE_TYPE)) + ifneq (TRUE, $(KERNEL_MODE)) + SRC_LIST=shiva_reg_access.c shiva_init.c + endif + endif +endif + +ifeq (, $(findstring SHIVA, $(SUPPORT_CHIP))) + SRC_LIST= +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/src/src/hsl/shiva/shiva_acl.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_acl.c new file mode 100755 index 000000000..837047f7f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_acl.c @@ -0,0 +1,3171 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup shiva_acl SHIVA_ACL + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_acl.h" +#include "shiva_acl.h" +#include "shiva_reg.h" + +//#define SHIVA_ACL_DEBUG +//#define SHIVA_SW_ENTRY +//#define SHIVA_ENTRY_DUMP + +typedef struct +{ + a_uint32_t list_id; + a_uint32_t list_pri; + a_uint32_t addr; + a_uint32_t size; + a_uint32_t status; + fal_pbmp_t bind_pts; +} shiva_acl_list_t; + +typedef struct +{ + a_uint32_t slct[6]; + a_uint32_t vlu[5]; + a_uint32_t msk[5]; + a_uint32_t typ; + a_uint32_t len; + a_uint32_t act[3]; +} shiva_acl_hw_rule_t; + +static shiva_acl_list_t *list_ent[SW_MAX_NR_DEV]; +static shiva_acl_hw_rule_t *hw_rule_ent; + +static a_uint32_t filter[SW_MAX_NR_DEV]; +static a_uint32_t filter_snap[SW_MAX_NR_DEV]; + +#define SHIVA_MAX_LIST 32 +#define SHIVA_MAX_RULE 32 + +#define ENT_FREE 0x1 +#define ENT_USED 0x2 + +#define SHIVA_RULE_VLU_ADDR 0x58400 +#define SHIVA_RULE_MSK_ADDR 0x58c00 +#define SHIVA_RULE_LEN_ADDR 0x58818 +#define SHIVA_RULE_TYP_ADDR 0x5881c +#define SHIVA_RULE_ACT_ADDR 0x58000 +#define SHIVA_RULE_SLCT_ADDR 0x58800 + +#define SHIVA_MAC_FILTER 1 +#define SHIVA_IP4_FILTER 2 +#define SHIVA_IP6R1_FILTER 3 +#define SHIVA_IP6R2_FILTER 4 +#define SHIVA_IP6R3_FILTER 5 +#define SHIVA_UDF_FILTER 6 + +#ifdef SHIVA_SW_ENTRY +static char *flt_vlu_mem = NULL; +static char *flt_msk_mem = NULL; +static char *flt_typ_mem = NULL; +static char *flt_len_mem = NULL; +static char *act_mem = NULL; +static char *slct_mem = NULL; +#endif + +static a_bool_t _shiva_acl_zero_addr(const fal_mac_addr_t addr); + +static a_bool_t +_shiva_acl_field_care(fal_acl_field_op_t op, a_uint32_t val, a_uint32_t mask, + a_uint32_t chkvlu); + +static sw_error_t +_shiva_acl_list_loc(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t * idx); + +static sw_error_t +_shiva_acl_filter_map_get(const shiva_acl_hw_rule_t * rule, + a_uint32_t flt_idx[], a_uint32_t * flt_nr); + +static sw_error_t +_shiva_acl_rule_mac_parse(fal_acl_rule_t * sw, + shiva_acl_hw_rule_t * hw, a_bool_t * b_care); + +static sw_error_t +_shiva_acl_rule_ip4_parse(fal_acl_rule_t * sw, + shiva_acl_hw_rule_t * hw, a_bool_t * b_care); + +static sw_error_t +_shiva_acl_rule_ip6r1_parse(fal_acl_rule_t * sw, + shiva_acl_hw_rule_t * hw, a_bool_t * b_care); + +static sw_error_t +_shiva_acl_rule_ip6r2_parse(fal_acl_rule_t * sw, + shiva_acl_hw_rule_t * hw, a_bool_t * b_care); + +static sw_error_t +_shiva_acl_rule_ip6r3_parse(fal_acl_rule_t * sw, + shiva_acl_hw_rule_t * hw, a_bool_t * b_care); + +static sw_error_t +_shiva_acl_rule_udf_parse(fal_acl_rule_t * sw, + shiva_acl_hw_rule_t * hw, a_bool_t * b_care); + +static sw_error_t +_shiva_acl_action_parse(a_uint32_t dev_id, const fal_acl_rule_t * sw, + shiva_acl_hw_rule_t * hw); + +static sw_error_t +_shiva_acl_rule_mac_reparse(fal_acl_rule_t * sw, + const shiva_acl_hw_rule_t * hw); + +static sw_error_t +_shiva_acl_rule_ip4_reparse(fal_acl_rule_t * sw, + const shiva_acl_hw_rule_t * hw); + +static sw_error_t +_shiva_acl_rule_ip6r1_reparse(fal_acl_rule_t * sw, + const shiva_acl_hw_rule_t * hw); + +static sw_error_t +_shiva_acl_rule_ip6r2_reparse(fal_acl_rule_t * sw, + const shiva_acl_hw_rule_t * hw); + +static sw_error_t +_shiva_acl_rule_ip6r3_reparse(fal_acl_rule_t * sw, + const shiva_acl_hw_rule_t * hw); + +static sw_error_t +_shiva_acl_rule_action_reparse(fal_acl_rule_t * sw, + const shiva_acl_hw_rule_t * hw); + +static sw_error_t +_shiva_acl_filter_alloc(a_uint32_t dev_id, a_uint32_t * idx); + +static void +_shiva_acl_filter_free(a_uint32_t dev_id, a_uint32_t idx); + +static void +_shiva_acl_filter_snap(a_uint32_t dev_id); + +static void +_shiva_acl_filter_commit(a_uint32_t dev_id); + +static sw_error_t +_shiva_acl_slct_update(shiva_acl_hw_rule_t * hw, a_uint32_t offset, + a_uint32_t flt_idx); + +static sw_error_t +_shiva_acl_filter_write(a_uint32_t dev_id, const shiva_acl_hw_rule_t * rule, + a_uint32_t flt_idx); + +static sw_error_t +_shiva_acl_action_write(a_uint32_t dev_id, const shiva_acl_hw_rule_t * rule, + a_uint32_t act_idx); + +static sw_error_t +_shiva_acl_slct_write(a_uint32_t dev_id, const shiva_acl_hw_rule_t * rule, + a_uint32_t slct_idx); + +static sw_error_t +_shiva_acl_filter_read(a_uint32_t dev_id, shiva_acl_hw_rule_t * rule, + a_uint32_t flt_idx); + +static sw_error_t +_shiva_acl_action_read(a_uint32_t dev_id, shiva_acl_hw_rule_t * rule, + a_uint32_t act_idx); + +static sw_error_t +_shiva_acl_slct_read(a_uint32_t dev_id, shiva_acl_hw_rule_t * rule, + a_uint32_t slct_idx); + +static sw_error_t +_shiva_acl_rule_set(a_uint32_t dev_id, a_uint32_t base_addr, + const shiva_acl_hw_rule_t * hw_rule_ent, + a_uint32_t rule_nr); + +static sw_error_t +_shiva_acl_rule_get(a_uint32_t dev_id, shiva_acl_hw_rule_t * rule, + a_uint32_t * ent_idx, a_uint32_t rule_idx); + +static sw_error_t +_shiva_acl_rule_sw_to_hw(a_uint32_t dev_id, fal_acl_rule_t * sw, + shiva_acl_hw_rule_t * hw, a_uint32_t * idx); + +static sw_error_t +_shiva_acl_rule_hw_to_sw(fal_acl_rule_t * sw, const shiva_acl_hw_rule_t * hw, + a_uint32_t ent_idx, a_uint32_t ent_nr); + +static sw_error_t +_shiva_acl_rule_copy(a_uint32_t dev_id, a_uint32_t src_slct_idx, + a_uint32_t dst_slct_idx, a_uint32_t size); + +static sw_error_t +_shiva_acl_rule_invalid(a_uint32_t dev_id, a_uint32_t rule_idx, + a_uint32_t size); + +static sw_error_t +_shiva_acl_rule_valid(a_uint32_t dev_id, a_uint32_t rule_idx, a_uint32_t size, + a_uint32_t flag); + +static sw_error_t +_shiva_acl_addr_update(a_uint32_t dev_id, a_uint32_t old_addr, + a_uint32_t new_addr, a_uint32_t list_id); + +static sw_error_t +_shiva_acl_rule_bind(a_uint32_t dev_id, a_uint32_t rule_idx, a_uint32_t ports); + +#ifdef SHIVA_ACL_DEBUG +static void +_shiva_acl_list_dump(a_uint32_t dev_id) +{ + a_uint32_t i; + + aos_printk("\ndev_id=%d list control infomation", dev_id); + for (i = 0; i < SHIVA_MAX_LIST; i++) + { + if (ENT_USED == list_ent[dev_id][i].status) + { + aos_printk("\nlist_id=%d list_pri=%d addr=%d size=%d idx=%d ", + list_ent[dev_id][i].list_id, + list_ent[dev_id][i].list_pri, + list_ent[dev_id][i].addr, list_ent[dev_id][i].size, i); + } + } + aos_printk("\n"); +} +#else +#define _shiva_acl_list_dump(dev_id) +#endif + +static a_bool_t +_shiva_acl_zero_addr(const fal_mac_addr_t addr) +{ + a_uint32_t i; + + for (i = 0; i < 6; i++) + { + if (addr.uc[i]) + { + return A_FALSE; + } + } + return A_TRUE; +} + +static a_bool_t +_shiva_acl_field_care(fal_acl_field_op_t op, a_uint32_t val, a_uint32_t mask, + a_uint32_t chkvlu) +{ + if (FAL_ACL_FIELD_MASK == op) + { + if (0 == mask) + return A_FALSE; + } + else if (FAL_ACL_FIELD_RANGE == op) + { + if ((0 == val) && (chkvlu == mask)) + return A_FALSE; + } + else if (FAL_ACL_FIELD_LE == op) + { + if (chkvlu == val) + return A_FALSE; + } + else if (FAL_ACL_FIELD_GE == op) + { + if (0 == val) + return A_FALSE; + } + else if (FAL_ACL_FIELD_NE == op) + { + return A_TRUE; + } + + return A_TRUE; +} + +static sw_error_t +_shiva_acl_list_loc(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t * idx) +{ + a_uint32_t i; + + for (i = 0; i < SHIVA_MAX_LIST; i++) + { + if ((ENT_USED == list_ent[dev_id][i].status) + && (list_id == list_ent[dev_id][i].list_id)) + { + *idx = i; + return SW_OK; + } + } + return SW_NOT_FOUND; +} + +static sw_error_t +_shiva_acl_filter_map_get(const shiva_acl_hw_rule_t * rule, + a_uint32_t flt_idx[], a_uint32_t * flt_nr) +{ + a_uint32_t flt_en, idx, i = 0; + + SW_GET_FIELD_BY_REG(RUL_SLCT0, ADDR0_EN, flt_en, (rule->slct[0])); + if (flt_en) + { + SW_GET_FIELD_BY_REG(RUL_SLCT1, ADDR0, idx, (rule->slct[1])); + flt_idx[i] = idx; + i++; + } + + SW_GET_FIELD_BY_REG(RUL_SLCT0, ADDR1_EN, flt_en, (rule->slct[0])); + if (flt_en) + { + SW_GET_FIELD_BY_REG(RUL_SLCT2, ADDR1, idx, (rule->slct[2])); + flt_idx[i] = idx; + i++; + } + + SW_GET_FIELD_BY_REG(RUL_SLCT0, ADDR2_EN, flt_en, (rule->slct[0])); + if (flt_en) + { + SW_GET_FIELD_BY_REG(RUL_SLCT3, ADDR2, idx, (rule->slct[3])); + flt_idx[i] = idx; + i++; + } + + SW_GET_FIELD_BY_REG(RUL_SLCT0, ADDR3_EN, flt_en, (rule->slct[0])); + if (flt_en) + { + SW_GET_FIELD_BY_REG(RUL_SLCT4, ADDR3, idx, (rule->slct[4])); + flt_idx[i] = idx; + i++; + } + + *flt_nr = i; + return SW_OK; +} + +static sw_error_t +_shiva_acl_rule_mac_parse(fal_acl_rule_t * sw, + shiva_acl_hw_rule_t * hw, a_bool_t * b_care) +{ + a_uint32_t i, len = 14; + + *b_care = A_FALSE; + + aos_mem_zero(&(hw->vlu[0]), sizeof (hw->vlu)); + aos_mem_zero(&(hw->msk[0]), sizeof (hw->msk)); + aos_mem_zero(&(hw->typ), sizeof (hw->typ)); + aos_mem_zero(&(hw->len), sizeof (hw->len)); + + SW_SET_REG_BY_FIELD(RUL_SLCT7, RULE_TYP, SHIVA_MAC_FILTER, hw->typ); + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_DA)) + { + if (A_TRUE != _shiva_acl_zero_addr(sw->dest_mac_mask)) + { + *b_care = A_TRUE; + } + + for (i = 0; i < 6; i++) + { + sw->dest_mac_val.uc[i] &= sw->dest_mac_mask.uc[i]; + } + + SW_SET_REG_BY_FIELD(MAC_RUL_V0, DAV_BYTE2, sw->dest_mac_val.uc[2], + hw->vlu[0]); + SW_SET_REG_BY_FIELD(MAC_RUL_V0, DAV_BYTE3, sw->dest_mac_val.uc[3], + hw->vlu[0]); + SW_SET_REG_BY_FIELD(MAC_RUL_V0, DAV_BYTE4, sw->dest_mac_val.uc[4], + hw->vlu[0]); + SW_SET_REG_BY_FIELD(MAC_RUL_V0, DAV_BYTE5, sw->dest_mac_val.uc[5], + hw->vlu[0]); + SW_SET_REG_BY_FIELD(MAC_RUL_V1, DAV_BYTE0, sw->dest_mac_val.uc[0], + hw->vlu[1]); + SW_SET_REG_BY_FIELD(MAC_RUL_V1, DAV_BYTE1, sw->dest_mac_val.uc[1], + hw->vlu[1]); + + SW_SET_REG_BY_FIELD(MAC_RUL_M0, DAM_BYTE2, sw->dest_mac_mask.uc[2], + hw->msk[0]); + SW_SET_REG_BY_FIELD(MAC_RUL_M0, DAM_BYTE3, sw->dest_mac_mask.uc[3], + hw->msk[0]); + SW_SET_REG_BY_FIELD(MAC_RUL_M0, DAM_BYTE4, sw->dest_mac_mask.uc[4], + hw->msk[0]); + SW_SET_REG_BY_FIELD(MAC_RUL_M0, DAM_BYTE5, sw->dest_mac_mask.uc[5], + hw->msk[0]); + SW_SET_REG_BY_FIELD(MAC_RUL_M1, DAM_BYTE0, sw->dest_mac_mask.uc[0], + hw->msk[1]); + SW_SET_REG_BY_FIELD(MAC_RUL_M1, DAM_BYTE1, sw->dest_mac_mask.uc[1], + hw->msk[1]); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_SA)) + { + if (A_TRUE != _shiva_acl_zero_addr(sw->src_mac_mask)) + { + *b_care = A_TRUE; + } + + for (i = 0; i < 6; i++) + { + sw->src_mac_val.uc[i] &= sw->src_mac_mask.uc[i]; + } + + SW_SET_REG_BY_FIELD(MAC_RUL_V1, SAV_BYTE4, sw->src_mac_val.uc[4], + hw->vlu[1]); + SW_SET_REG_BY_FIELD(MAC_RUL_V1, SAV_BYTE5, sw->src_mac_val.uc[5], + hw->vlu[1]); + SW_SET_REG_BY_FIELD(MAC_RUL_V2, SAV_BYTE0, sw->src_mac_val.uc[0], + hw->vlu[2]); + SW_SET_REG_BY_FIELD(MAC_RUL_V2, SAV_BYTE1, sw->src_mac_val.uc[1], + hw->vlu[2]); + SW_SET_REG_BY_FIELD(MAC_RUL_V2, SAV_BYTE2, sw->src_mac_val.uc[2], + hw->vlu[2]); + SW_SET_REG_BY_FIELD(MAC_RUL_V2, SAV_BYTE3, sw->src_mac_val.uc[3], + hw->vlu[2]); + + SW_SET_REG_BY_FIELD(MAC_RUL_M1, SAM_BYTE4, sw->src_mac_mask.uc[4], + hw->msk[1]); + SW_SET_REG_BY_FIELD(MAC_RUL_M1, SAM_BYTE5, sw->src_mac_mask.uc[5], + hw->msk[1]); + SW_SET_REG_BY_FIELD(MAC_RUL_M2, SAM_BYTE0, sw->src_mac_mask.uc[0], + hw->msk[2]); + SW_SET_REG_BY_FIELD(MAC_RUL_M2, SAM_BYTE1, sw->src_mac_mask.uc[1], + hw->msk[2]); + SW_SET_REG_BY_FIELD(MAC_RUL_M2, SAM_BYTE2, sw->src_mac_mask.uc[2], + hw->msk[2]); + SW_SET_REG_BY_FIELD(MAC_RUL_M2, SAM_BYTE3, sw->src_mac_mask.uc[3], + hw->msk[2]); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_ETHTYPE)) + { + if (0x0 != sw->ethtype_mask) + { + *b_care = A_TRUE; + } + + sw->ethtype_val &= sw->ethtype_mask; + SW_SET_REG_BY_FIELD(MAC_RUL_V3, ETHTYPV, sw->ethtype_val, hw->vlu[3]); + SW_SET_REG_BY_FIELD(MAC_RUL_M3, ETHTYPM, sw->ethtype_mask, hw->msk[3]); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_TAGGED)) + { + if (0x0 != sw->tagged_mask) + { + *b_care = A_TRUE; + } + + sw->tagged_val &= sw->tagged_mask; + SW_SET_REG_BY_FIELD(MAC_RUL_V4, TAGGEDV, sw->tagged_val, hw->vlu[4]); + SW_SET_REG_BY_FIELD(MAC_RUL_V4, TAGGEDM, sw->tagged_mask, hw->vlu[4]); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_UP)) + { + if (0x0 != sw->up_mask) + { + *b_care = A_TRUE; + } + + sw->up_val &= sw->up_mask; + SW_SET_REG_BY_FIELD(MAC_RUL_V3, VLANPRIV, sw->up_val, hw->vlu[3]); + SW_SET_REG_BY_FIELD(MAC_RUL_M3, VLANPRIM, sw->up_mask, hw->msk[3]); + } + + SW_SET_REG_BY_FIELD(MAC_RUL_V4, VIDMSK, 1, hw->vlu[4]); + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_VID)) + { + if ((FAL_ACL_FIELD_MASK != sw->vid_op) + && (FAL_ACL_FIELD_RANGE != sw->vid_op) + && (FAL_ACL_FIELD_LE != sw->vid_op) + && (FAL_ACL_FIELD_GE != sw->vid_op)) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == + _shiva_acl_field_care(sw->vid_op, sw->vid_val, sw->vid_mask, + 0xfff)) + { + *b_care = A_TRUE; + } + + SW_SET_REG_BY_FIELD(MAC_RUL_V4, VIDMSK, 0, hw->vlu[4]); + if (FAL_ACL_FIELD_MASK == sw->vid_op) + { + sw->vid_val &= sw->vid_mask; + SW_SET_REG_BY_FIELD(MAC_RUL_V3, VLANIDV, sw->vid_val, hw->vlu[3]); + SW_SET_REG_BY_FIELD(MAC_RUL_M3, VLANIDM, sw->vid_mask, hw->msk[3]); + SW_SET_REG_BY_FIELD(MAC_RUL_V4, VIDMSK, 1, hw->vlu[4]); + } + else if (FAL_ACL_FIELD_RANGE == sw->vid_op) + { + SW_SET_REG_BY_FIELD(MAC_RUL_V3, VLANIDV, sw->vid_val, hw->vlu[3]); + SW_SET_REG_BY_FIELD(MAC_RUL_M3, VLANIDM, sw->vid_mask, hw->msk[3]); + } + else if (FAL_ACL_FIELD_LE == sw->vid_op) + { + SW_SET_REG_BY_FIELD(MAC_RUL_V3, VLANIDV, 0, hw->vlu[3]); + SW_SET_REG_BY_FIELD(MAC_RUL_M3, VLANIDM, sw->vid_val, hw->msk[3]); + } + else + { + SW_SET_REG_BY_FIELD(MAC_RUL_V3, VLANIDV, sw->vid_val, hw->vlu[3]); + SW_SET_REG_BY_FIELD(MAC_RUL_M3, VLANIDM, 0xfff, hw->msk[3]); + } + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_MAC_CFI)) + { + if (0x0 != sw->cfi_mask) + { + *b_care = A_TRUE; + } + + sw->cfi_val &= sw->cfi_mask; + SW_SET_REG_BY_FIELD(MAC_RUL_V3, VLANCFIV, sw->cfi_val, hw->vlu[3]); + SW_SET_REG_BY_FIELD(MAC_RUL_M3, VLANCFIM, sw->cfi_mask, hw->msk[3]); + } + + SW_SET_REG_BY_FIELD(RUL_SLCT6, RULE_LEN, len, hw->len); + + return SW_OK; +} + +static sw_error_t +_shiva_acl_rule_ip4_parse(fal_acl_rule_t * sw, + shiva_acl_hw_rule_t * hw, a_bool_t * b_care) +{ + a_uint32_t len = 34; + + *b_care = A_FALSE; + aos_mem_zero(&(hw->vlu[0]), sizeof (hw->vlu)); + aos_mem_zero(&(hw->msk[0]), sizeof (hw->msk)); + aos_mem_zero(&(hw->typ), sizeof (hw->typ)); + aos_mem_zero(&(hw->len), sizeof (hw->len)); + + SW_SET_REG_BY_FIELD(RUL_SLCT7, RULE_TYP, SHIVA_IP4_FILTER, hw->typ); + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP_DSCP)) + { + if (0x0 != sw->ip_dscp_mask) + { + *b_care = A_TRUE; + } + + sw->ip_dscp_val &= sw->ip_dscp_mask; + SW_SET_REG_BY_FIELD(IP4_RUL_V2, IP4DSCPV, sw->ip_dscp_val, hw->vlu[2]); + SW_SET_REG_BY_FIELD(IP4_RUL_M2, IP4DSCPM, sw->ip_dscp_mask, hw->msk[2]); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP_PROTO)) + { + if (0x0 != sw->ip_proto_mask) + { + *b_care = A_TRUE; + } + + sw->ip_proto_val &= sw->ip_proto_mask; + SW_SET_REG_BY_FIELD(IP4_RUL_V2, IP4PROTV, sw->ip_proto_val, hw->vlu[2]); + SW_SET_REG_BY_FIELD(IP4_RUL_M2, IP4PROTM, sw->ip_proto_mask, + hw->msk[2]); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP4_SIP)) + { + if (0x0 != sw->src_ip4_mask) + { + *b_care = A_TRUE; + } + sw->src_ip4_val &= sw->src_ip4_mask; + hw->vlu[1] = sw->src_ip4_val; + hw->msk[1] = sw->src_ip4_mask; + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP4_DIP)) + { + if (0x0 != sw->dest_ip4_mask) + { + *b_care = A_TRUE; + } + sw->dest_ip4_val &= sw->dest_ip4_mask; + hw->vlu[0] = sw->dest_ip4_val; + hw->msk[0] = sw->dest_ip4_mask; + } + + SW_SET_REG_BY_FIELD(IP4_RUL_M3, IP4SPORTM_EN, 1, hw->msk[3]); + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_L4_SPORT)) + { + if ((FAL_ACL_FIELD_MASK != sw->src_l4port_op) + && (FAL_ACL_FIELD_RANGE != sw->src_l4port_op) + && (FAL_ACL_FIELD_LE != sw->src_l4port_op) + && (FAL_ACL_FIELD_GE != sw->src_l4port_op)) + { + return SW_NOT_SUPPORTED; + } + + if (A_FALSE == + _shiva_acl_field_care(sw->src_l4port_op, sw->src_l4port_val, + sw->src_l4port_mask, 0xffff)) + { + if (FAL_ACL_FIELD_MASK == sw->src_l4port_op) + { + sw->src_l4port_op = FAL_ACL_FIELD_RANGE; + sw->src_l4port_val = 0; + sw->src_l4port_mask = 0xffff; + } + } + *b_care = A_TRUE; + len = 38; + + SW_SET_REG_BY_FIELD(IP4_RUL_M3, IP4SPORTM_EN, 0, hw->msk[3]); + if (FAL_ACL_FIELD_MASK == sw->src_l4port_op) + { + sw->src_l4port_val &= sw->src_l4port_mask; + SW_SET_REG_BY_FIELD(IP4_RUL_V3, IP4SPORTV, sw->src_l4port_val, + hw->vlu[3]); + SW_SET_REG_BY_FIELD(IP4_RUL_M3, IP4SPORTM, sw->src_l4port_mask, + hw->msk[3]); + SW_SET_REG_BY_FIELD(IP4_RUL_M3, IP4SPORTM_EN, 1, hw->msk[3]); + } + else if (FAL_ACL_FIELD_RANGE == sw->src_l4port_op) + { + SW_SET_REG_BY_FIELD(IP4_RUL_V3, IP4SPORTV, sw->src_l4port_val, + hw->vlu[3]); + SW_SET_REG_BY_FIELD(IP4_RUL_M3, IP4SPORTM, sw->src_l4port_mask, + hw->msk[3]); + } + else if (FAL_ACL_FIELD_LE == sw->src_l4port_op) + { + SW_SET_REG_BY_FIELD(IP4_RUL_V3, IP4SPORTV, 0, hw->vlu[3]); + SW_SET_REG_BY_FIELD(IP4_RUL_M3, IP4SPORTM, sw->src_l4port_val, + hw->msk[3]); + } + else + { + SW_SET_REG_BY_FIELD(IP4_RUL_V3, IP4SPORTV, sw->src_l4port_val, + hw->vlu[3]); + SW_SET_REG_BY_FIELD(IP4_RUL_M3, IP4SPORTM, 0xffff, hw->msk[3]); + } + } + + SW_SET_REG_BY_FIELD(IP4_RUL_M3, IP4DPORTM_EN, 1, hw->msk[3]); + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_L4_DPORT)) + { + if ((FAL_ACL_FIELD_MASK != sw->dest_l4port_op) + && (FAL_ACL_FIELD_RANGE != sw->dest_l4port_op) + && (FAL_ACL_FIELD_LE != sw->dest_l4port_op) + && (FAL_ACL_FIELD_GE != sw->dest_l4port_op)) + { + return SW_NOT_SUPPORTED; + } + + if (A_FALSE == + _shiva_acl_field_care(sw->dest_l4port_op, sw->dest_l4port_val, + sw->dest_l4port_mask, 0xffff)) + { + if (FAL_ACL_FIELD_MASK == sw->dest_l4port_op) + { + sw->dest_l4port_op = FAL_ACL_FIELD_RANGE; + sw->dest_l4port_val = 0; + sw->dest_l4port_mask = 0xffff; + } + } + *b_care = A_TRUE; + len = 38; + + SW_SET_REG_BY_FIELD(IP4_RUL_M3, IP4DPORTM_EN, 0, hw->msk[3]); + if (FAL_ACL_FIELD_MASK == sw->dest_l4port_op) + { + sw->dest_l4port_val &= sw->dest_l4port_mask; + SW_SET_REG_BY_FIELD(IP4_RUL_V2, IP4DPORTV, sw->dest_l4port_val, + hw->vlu[2]); + SW_SET_REG_BY_FIELD(IP4_RUL_M2, IP4DPORTM, sw->dest_l4port_mask, + hw->msk[2]); + SW_SET_REG_BY_FIELD(IP4_RUL_M3, IP4DPORTM_EN, 1, hw->msk[3]); + } + else if (FAL_ACL_FIELD_RANGE == sw->dest_l4port_op) + { + SW_SET_REG_BY_FIELD(IP4_RUL_V2, IP4DPORTV, sw->dest_l4port_val, + hw->vlu[2]); + SW_SET_REG_BY_FIELD(IP4_RUL_M2, IP4DPORTM, sw->dest_l4port_mask, + hw->msk[2]); + } + else if (FAL_ACL_FIELD_LE == sw->dest_l4port_op) + { + SW_SET_REG_BY_FIELD(IP4_RUL_V2, IP4DPORTV, 0, hw->vlu[2]); + SW_SET_REG_BY_FIELD(IP4_RUL_M2, IP4DPORTM, sw->dest_l4port_val, + hw->msk[2]); + } + else + { + SW_SET_REG_BY_FIELD(IP4_RUL_V2, IP4DPORTV, sw->dest_l4port_val, + hw->vlu[2]); + SW_SET_REG_BY_FIELD(IP4_RUL_M2, IP4DPORTM, 0xffff, hw->msk[2]); + } + } + + SW_SET_REG_BY_FIELD(RUL_SLCT6, RULE_LEN, len, hw->len); + + return SW_OK; +} + +static sw_error_t +_shiva_acl_rule_ip6r1_parse(fal_acl_rule_t * sw, + shiva_acl_hw_rule_t * hw, a_bool_t * b_care) +{ + a_uint32_t i, len = 54; + + *b_care = A_FALSE; + aos_mem_zero(&(hw->vlu[0]), sizeof (hw->vlu)); + aos_mem_zero(&(hw->msk[0]), sizeof (hw->msk)); + aos_mem_zero(&(hw->typ), sizeof (hw->typ)); + aos_mem_zero(&(hw->len), sizeof (hw->len)); + + SW_SET_REG_BY_FIELD(RUL_SLCT7, RULE_TYP, SHIVA_IP6R1_FILTER, hw->typ); + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP6_DIP)) + { + for (i = 0; i < 4; i++) + { + if (0x0 != sw->dest_ip6_mask.ul[i]) + { + *b_care = A_TRUE; + } + + sw->dest_ip6_val.ul[3 - i] &= sw->dest_ip6_mask.ul[3 - i]; + hw->vlu[i] = sw->dest_ip6_val.ul[3 - i]; + hw->msk[i] = sw->dest_ip6_mask.ul[3 - i]; + } + } + + SW_SET_REG_BY_FIELD(RUL_SLCT6, RULE_LEN, len, hw->len); + + return SW_OK; +} + +static sw_error_t +_shiva_acl_rule_ip6r2_parse(fal_acl_rule_t * sw, + shiva_acl_hw_rule_t * hw, a_bool_t * b_care) +{ + a_uint32_t i, len = 54; + + *b_care = A_FALSE; + aos_mem_zero(&(hw->vlu[0]), sizeof (hw->vlu)); + aos_mem_zero(&(hw->msk[0]), sizeof (hw->msk)); + aos_mem_zero(&(hw->typ), sizeof (hw->typ)); + aos_mem_zero(&(hw->len), sizeof (hw->len)); + + SW_SET_REG_BY_FIELD(RUL_SLCT7, RULE_TYP, SHIVA_IP6R2_FILTER, hw->typ); + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP6_SIP)) + { + for (i = 0; i < 4; i++) + { + if (0x0 != sw->src_ip6_mask.ul[i]) + { + *b_care = A_TRUE; + } + + sw->src_ip6_val.ul[3 - i] &= sw->src_ip6_mask.ul[3 - i]; + hw->vlu[i] = sw->src_ip6_val.ul[3 - i]; + hw->msk[i] = sw->src_ip6_mask.ul[3 - i]; + } + } + + SW_SET_REG_BY_FIELD(RUL_SLCT6, RULE_LEN, len, hw->len); + + return SW_OK; +} + +static sw_error_t +_shiva_acl_rule_ip6r3_parse(fal_acl_rule_t * sw, + shiva_acl_hw_rule_t * hw, a_bool_t * b_care) +{ + a_uint32_t len = 54; + + *b_care = A_FALSE; + aos_mem_zero(&(hw->vlu[0]), sizeof (hw->vlu)); + aos_mem_zero(&(hw->msk[0]), sizeof (hw->msk)); + aos_mem_zero(&(hw->typ), sizeof (hw->typ)); + aos_mem_zero(&(hw->len), sizeof (hw->len)); + + SW_SET_REG_BY_FIELD(RUL_SLCT7, RULE_TYP, SHIVA_IP6R3_FILTER, hw->typ); + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP6_LABEL)) + { + if (0x0 != sw->ip6_lable_mask) + { + *b_care = A_TRUE; + } + + sw->ip6_lable_val &= sw->ip6_lable_mask; + SW_SET_REG_BY_FIELD(IP6_RUL3_V1, IP6LABEL1V, sw->ip6_lable_val, + hw->vlu[1]); + SW_SET_REG_BY_FIELD(IP6_RUL3_M1, IP6LABEL1M, sw->ip6_lable_mask, + hw->msk[1]); + + SW_SET_REG_BY_FIELD(IP6_RUL3_V2, IP6LABEL2V, (sw->ip6_lable_val >> 16), + hw->vlu[2]); + SW_SET_REG_BY_FIELD(IP6_RUL3_M2, IP6LABEL2M, (sw->ip6_lable_mask >> 16), + hw->msk[2]); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP_PROTO)) + { + if (0x0 != sw->ip_proto_mask) + { + *b_care = A_TRUE; + } + + sw->ip_proto_val &= sw->ip_proto_mask; + SW_SET_REG_BY_FIELD(IP6_RUL3_V0, IP6PROTV, sw->ip_proto_val, + hw->vlu[0]); + SW_SET_REG_BY_FIELD(IP6_RUL3_M0, IP6PROTM, sw->ip_proto_mask, + hw->msk[0]); + } + + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_IP_DSCP)) + { + if (0x0 != sw->ip_dscp_mask) + { + *b_care = A_TRUE; + } + + sw->ip_dscp_val &= sw->ip_dscp_mask; + SW_SET_REG_BY_FIELD(IP6_RUL3_V0, IP6DSCPV, sw->ip_dscp_val, hw->vlu[0]); + SW_SET_REG_BY_FIELD(IP6_RUL3_M0, IP6DSCPM, sw->ip_dscp_mask, + hw->msk[0]); + } + + SW_SET_REG_BY_FIELD(IP6_RUL3_M3, IP6SPORTM_EN, 1, hw->msk[3]); + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_L4_SPORT)) + { + if ((FAL_ACL_FIELD_MASK != sw->src_l4port_op) + && (FAL_ACL_FIELD_RANGE != sw->src_l4port_op) + && (FAL_ACL_FIELD_LE != sw->src_l4port_op) + && (FAL_ACL_FIELD_GE != sw->src_l4port_op)) + { + return SW_NOT_SUPPORTED; + } + + if (A_FALSE == + _shiva_acl_field_care(sw->src_l4port_op, sw->src_l4port_val, + sw->src_l4port_mask, 0xffff)) + { + if (FAL_ACL_FIELD_MASK == sw->src_l4port_op) + { + sw->src_l4port_op = FAL_ACL_FIELD_RANGE; + sw->src_l4port_val = 0; + sw->src_l4port_mask = 0xffff; + } + } + *b_care = A_TRUE; + len = 58; + + SW_SET_REG_BY_FIELD(IP6_RUL3_M3, IP6SPORTM_EN, 0, hw->msk[3]); + if (FAL_ACL_FIELD_MASK == sw->src_l4port_op) + { + sw->src_l4port_val &= sw->src_l4port_mask; + SW_SET_REG_BY_FIELD(IP6_RUL3_V3, IP6SPORTV, sw->src_l4port_val, + hw->vlu[3]); + SW_SET_REG_BY_FIELD(IP6_RUL3_M3, IP6SPORTM, sw->src_l4port_mask, + hw->msk[3]); + SW_SET_REG_BY_FIELD(IP6_RUL3_M3, IP6SPORTM_EN, 1, hw->msk[3]); + } + else if (FAL_ACL_FIELD_RANGE == sw->src_l4port_op) + { + SW_SET_REG_BY_FIELD(IP6_RUL3_V3, IP6SPORTV, sw->src_l4port_val, + hw->vlu[3]); + SW_SET_REG_BY_FIELD(IP6_RUL3_M3, IP6SPORTM, sw->src_l4port_mask, + hw->msk[3]); + } + else if (FAL_ACL_FIELD_LE == sw->src_l4port_op) + { + SW_SET_REG_BY_FIELD(IP6_RUL3_V3, IP6SPORTV, 0, hw->vlu[3]); + SW_SET_REG_BY_FIELD(IP6_RUL3_M3, IP6SPORTM, sw->src_l4port_val, + hw->msk[3]); + } + else + { + SW_SET_REG_BY_FIELD(IP6_RUL3_V3, IP6SPORTV, sw->src_l4port_val, + hw->vlu[3]); + SW_SET_REG_BY_FIELD(IP6_RUL3_M3, IP6SPORTM, 0xffff, hw->msk[3]); + } + } + + SW_SET_REG_BY_FIELD(IP6_RUL3_M3, IP6DPORTM_EN, 1, hw->msk[3]); + if (FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_L4_DPORT)) + { + if ((FAL_ACL_FIELD_MASK != sw->dest_l4port_op) + && (FAL_ACL_FIELD_RANGE != sw->dest_l4port_op) + && (FAL_ACL_FIELD_LE != sw->dest_l4port_op) + && (FAL_ACL_FIELD_GE != sw->dest_l4port_op)) + { + return SW_NOT_SUPPORTED; + } + + if (A_FALSE == + _shiva_acl_field_care(sw->dest_l4port_op, sw->dest_l4port_val, + sw->dest_l4port_mask, 0xffff)) + { + if (FAL_ACL_FIELD_MASK == sw->dest_l4port_op) + { + sw->dest_l4port_op = FAL_ACL_FIELD_RANGE; + sw->dest_l4port_val = 0; + sw->dest_l4port_mask = 0xffff; + } + } + *b_care = A_TRUE; + len = 58; + + SW_SET_REG_BY_FIELD(IP6_RUL3_M3, IP6DPORTM_EN, 0, hw->msk[3]); + if (FAL_ACL_FIELD_MASK == sw->dest_l4port_op) + { + sw->dest_l4port_val &= sw->dest_l4port_mask; + SW_SET_REG_BY_FIELD(IP6_RUL3_V2, IP6DPORTV, sw->dest_l4port_val, + hw->vlu[2]); + SW_SET_REG_BY_FIELD(IP6_RUL3_M2, IP6DPORTM, sw->dest_l4port_mask, + hw->msk[2]); + SW_SET_REG_BY_FIELD(IP6_RUL3_M3, IP6DPORTM_EN, 1, hw->msk[3]); + } + else if (FAL_ACL_FIELD_RANGE == sw->dest_l4port_op) + { + SW_SET_REG_BY_FIELD(IP6_RUL3_V2, IP6DPORTV, sw->dest_l4port_val, + hw->vlu[2]); + SW_SET_REG_BY_FIELD(IP6_RUL3_M2, IP6DPORTM, sw->dest_l4port_mask, + hw->msk[2]); + } + else if (FAL_ACL_FIELD_LE == sw->dest_l4port_op) + { + SW_SET_REG_BY_FIELD(IP6_RUL3_V2, IP6DPORTV, 0, hw->vlu[2]); + SW_SET_REG_BY_FIELD(IP6_RUL3_M2, IP6DPORTM, sw->dest_l4port_val, + hw->msk[2]); + } + else + { + SW_SET_REG_BY_FIELD(IP6_RUL3_V2, IP6DPORTV, sw->dest_l4port_val, + hw->vlu[2]); + SW_SET_REG_BY_FIELD(IP6_RUL3_M2, IP6DPORTM, 0xffff, hw->msk[2]); + } + } + + SW_SET_REG_BY_FIELD(RUL_SLCT6, RULE_LEN, len, hw->len); + + return SW_OK; +} + +#define SHIVA_MAX_UDF_OFFSET 127 +#define SHIVA_MAX_UDF_LENGTH 16 + +static sw_error_t +_shiva_acl_rule_udf_parse(fal_acl_rule_t * sw, + shiva_acl_hw_rule_t * hw, a_bool_t * b_care) +{ + a_uint32_t i, len = 0; + + if (FAL_ACL_UDF_TYPE_BUTT <= sw->udf_type) + { + return SW_BAD_PARAM; + } + + if (SHIVA_MAX_UDF_OFFSET < sw->udf_offset) + { + return SW_NOT_SUPPORTED; + } + + if (sw->udf_offset % 2) + { + return SW_NOT_SUPPORTED; + } + + if (SHIVA_MAX_UDF_LENGTH < sw->udf_len) + { + return SW_NOT_SUPPORTED; + } + + aos_mem_zero(&(hw->vlu[0]), sizeof (hw->vlu)); + aos_mem_zero(&(hw->msk[0]), sizeof (hw->msk)); + aos_mem_zero(&(hw->typ), sizeof (hw->typ)); + aos_mem_zero(&(hw->len), sizeof (hw->len)); + + *b_care = A_FALSE; + + SW_SET_REG_BY_FIELD(RUL_SLCT7, RULE_TYP, SHIVA_UDF_FILTER, hw->typ); + + if (!FAL_FIELD_FLG_TST(sw->field_flg, FAL_ACL_FIELD_UDF)) + { + return SW_OK; + } + + *b_care = A_TRUE; + if (FAL_ACL_UDF_TYPE_L2 == sw->udf_type) + { + SW_SET_REG_BY_FIELD(UDF_RUL_V4, LAYER_TYP, 0, hw->vlu[4]); + len = sw->udf_offset + sw->udf_len; + } + else + { + SW_SET_REG_BY_FIELD(UDF_RUL_V4, LAYER_TYP, 1, hw->vlu[4]); + len = 14 + sw->udf_offset + sw->udf_len; + } + SW_SET_REG_BY_FIELD(RUL_SLCT6, RULE_LEN, len, hw->len); + + SW_SET_REG_BY_FIELD(UDF_RUL_V4, LAYER_OFFSET, sw->udf_offset, hw->vlu[4]); + + for (i = 0; i < sw->udf_len; i++) + { + hw->vlu[3 - i / 4] |= ((sw->udf_mask[i] & sw->udf_val[i]) << (24 - 8 * (i % 4))); + hw->msk[3 - i / 4] |= ((sw->udf_mask[i]) << (24 - 8 * i)); + } + + return SW_OK; +} + +static sw_error_t +_shiva_acl_action_parse(a_uint32_t dev_id, const fal_acl_rule_t * sw, + shiva_acl_hw_rule_t * hw) +{ + aos_mem_zero(&(hw->act[0]), sizeof (hw->act)); + + if ((FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_MODIFY_VLAN)) + && (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_NEST_VLAN))) + { + return SW_NOT_SUPPORTED; + } + + /* FAL_ACL_ACTION_PERMIT need't process */ + + /* we should ignore any other action flags when DENY bit is settd. */ + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_DENY)) + { + SW_SET_REG_BY_FIELD(ACL_RSLT1, DES_PORT_EN, 1, hw->act[1]); + SW_SET_REG_BY_FIELD(ACL_RSLT1, PORT_MEM, 0, hw->act[1]); + return SW_OK; + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_RDTCPU)) + { + SW_SET_REG_BY_FIELD(ACL_RSLT2, RDTCPU, 1, hw->act[2]); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_CPYCPU)) + { + SW_SET_REG_BY_FIELD(ACL_RSLT2, CPYCPU, 1, hw->act[2]); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_MIRROR)) + { + SW_SET_REG_BY_FIELD(ACL_RSLT1, MIRR_EN, 1, hw->act[1]); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REDPT)) + { + SW_SET_REG_BY_FIELD(ACL_RSLT1, DES_PORT_EN, 1, hw->act[1]); + SW_SET_REG_BY_FIELD(ACL_RSLT1, PORT_MEM, sw->ports, hw->act[1]); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REMARK_UP)) + { + SW_SET_REG_BY_FIELD(ACL_RSLT1, REMARK_DOT1P, 1, hw->act[1]); + SW_SET_REG_BY_FIELD(ACL_RSLT1, DOT1P, sw->up, hw->act[1]); + } + + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REMARK_QUEUE)) + { + SW_SET_REG_BY_FIELD(ACL_RSLT1, REMARK_PRI_QU, 1, hw->act[1]); + SW_SET_REG_BY_FIELD(ACL_RSLT1, PRI_QU, sw->queue, hw->act[1]); + } + + if ((FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_MODIFY_VLAN)) + || (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_NEST_VLAN))) + { + + SW_SET_REG_BY_FIELD(ACL_RSLT1, CHG_VID_EN, 1, hw->act[1]); + SW_SET_REG_BY_FIELD(ACL_RSLT1, VID, sw->vid, hw->act[1]); + SW_SET_REG_BY_FIELD(ACL_RSLT1, STAG_CHG_EN, 1, hw->act[1]); + if (FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_MODIFY_VLAN)) + { + SW_SET_REG_BY_FIELD(ACL_RSLT1, STAG_CHG_EN, 0, hw->act[1]); + + if (!FAL_ACTION_FLG_TST(sw->action_flg, FAL_ACL_ACTION_REDPT)) + { + SW_SET_REG_BY_FIELD(ACL_RSLT1, VID_MEM_EN, 1, hw->act[1]); + SW_SET_REG_BY_FIELD(ACL_RSLT1, PORT_MEM, sw->ports, hw->act[1]); + } + } + } + + return SW_OK; +} + +static sw_error_t +_shiva_acl_rule_mac_reparse(fal_acl_rule_t * sw, + const shiva_acl_hw_rule_t * hw) +{ + a_uint32_t mask_en; + + /* destnation mac address */ + SW_GET_FIELD_BY_REG(MAC_RUL_V0, DAV_BYTE2, sw->dest_mac_val.uc[2], + hw->vlu[0]); + SW_GET_FIELD_BY_REG(MAC_RUL_V0, DAV_BYTE3, sw->dest_mac_val.uc[3], + hw->vlu[0]); + SW_GET_FIELD_BY_REG(MAC_RUL_V0, DAV_BYTE4, sw->dest_mac_val.uc[4], + hw->vlu[0]); + SW_GET_FIELD_BY_REG(MAC_RUL_V0, DAV_BYTE5, sw->dest_mac_val.uc[5], + hw->vlu[0]); + SW_GET_FIELD_BY_REG(MAC_RUL_V1, DAV_BYTE0, sw->dest_mac_val.uc[0], + hw->vlu[1]); + SW_GET_FIELD_BY_REG(MAC_RUL_V1, DAV_BYTE1, sw->dest_mac_val.uc[1], + hw->vlu[1]); + + SW_GET_FIELD_BY_REG(MAC_RUL_M0, DAM_BYTE2, sw->dest_mac_mask.uc[2], + hw->msk[0]); + SW_GET_FIELD_BY_REG(MAC_RUL_M0, DAM_BYTE3, sw->dest_mac_mask.uc[3], + hw->msk[0]); + SW_GET_FIELD_BY_REG(MAC_RUL_M0, DAM_BYTE4, sw->dest_mac_mask.uc[4], + hw->msk[0]); + SW_GET_FIELD_BY_REG(MAC_RUL_M0, DAM_BYTE5, sw->dest_mac_mask.uc[5], + hw->msk[0]); + SW_GET_FIELD_BY_REG(MAC_RUL_M1, DAM_BYTE0, sw->dest_mac_mask.uc[0], + hw->msk[1]); + SW_GET_FIELD_BY_REG(MAC_RUL_M1, DAM_BYTE1, sw->dest_mac_mask.uc[1], + hw->msk[1]); + if (A_FALSE == _shiva_acl_zero_addr(sw->dest_mac_mask)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_DA); + } + + /* source mac address */ + SW_GET_FIELD_BY_REG(MAC_RUL_V2, SAV_BYTE0, sw->src_mac_val.uc[0], + hw->vlu[2]); + SW_GET_FIELD_BY_REG(MAC_RUL_V2, SAV_BYTE1, sw->src_mac_val.uc[1], + hw->vlu[2]); + SW_GET_FIELD_BY_REG(MAC_RUL_V2, SAV_BYTE2, sw->src_mac_val.uc[2], + hw->vlu[2]); + SW_GET_FIELD_BY_REG(MAC_RUL_V2, SAV_BYTE3, sw->src_mac_val.uc[3], + hw->vlu[2]); + SW_GET_FIELD_BY_REG(MAC_RUL_V1, SAV_BYTE4, sw->src_mac_val.uc[4], + hw->vlu[1]); + SW_GET_FIELD_BY_REG(MAC_RUL_V1, SAV_BYTE5, sw->src_mac_val.uc[5], + hw->vlu[1]); + + SW_GET_FIELD_BY_REG(MAC_RUL_M2, SAM_BYTE0, sw->src_mac_mask.uc[0], + hw->msk[2]); + SW_GET_FIELD_BY_REG(MAC_RUL_M2, SAM_BYTE1, sw->src_mac_mask.uc[1], + hw->msk[2]); + SW_GET_FIELD_BY_REG(MAC_RUL_M2, SAM_BYTE2, sw->src_mac_mask.uc[2], + hw->msk[2]); + SW_GET_FIELD_BY_REG(MAC_RUL_M2, SAM_BYTE3, sw->src_mac_mask.uc[3], + hw->msk[2]); + SW_GET_FIELD_BY_REG(MAC_RUL_M1, SAM_BYTE4, sw->src_mac_mask.uc[4], + hw->msk[1]); + SW_GET_FIELD_BY_REG(MAC_RUL_M1, SAM_BYTE5, sw->src_mac_mask.uc[5], + hw->msk[1]); + if (A_FALSE == _shiva_acl_zero_addr(sw->src_mac_mask)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_SA); + } + + /* ethernet type */ + SW_GET_FIELD_BY_REG(MAC_RUL_V3, ETHTYPV, sw->ethtype_val, hw->vlu[3]); + SW_GET_FIELD_BY_REG(MAC_RUL_M3, ETHTYPM, sw->ethtype_mask, hw->msk[3]); + if (0x0 != sw->ethtype_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_ETHTYPE); + } + + /* packet tagged */ + SW_GET_FIELD_BY_REG(MAC_RUL_V4, TAGGEDV, sw->tagged_val, hw->vlu[4]); + SW_GET_FIELD_BY_REG(MAC_RUL_V4, TAGGEDM, sw->tagged_mask, hw->vlu[4]); + if (0x0 != sw->tagged_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_TAGGED); + } + + /* vlan priority */ + SW_GET_FIELD_BY_REG(MAC_RUL_V3, VLANPRIV, sw->up_val, hw->vlu[3]); + SW_GET_FIELD_BY_REG(MAC_RUL_M3, VLANPRIM, sw->up_mask, hw->msk[3]); + if (0x0 != sw->up_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_UP); + } + + /* vlanid */ + SW_GET_FIELD_BY_REG(MAC_RUL_V3, VLANIDV, sw->vid_val, hw->vlu[3]); + SW_GET_FIELD_BY_REG(MAC_RUL_M3, VLANIDM, sw->vid_mask, hw->msk[3]); + SW_GET_FIELD_BY_REG(MAC_RUL_V4, VIDMSK, mask_en, hw->vlu[4]); + if (mask_en) + { + sw->vid_op = FAL_ACL_FIELD_MASK; + } + else + { + sw->vid_op = FAL_ACL_FIELD_RANGE; + } + + if (A_TRUE == + _shiva_acl_field_care(sw->vid_op, (a_uint32_t) sw->vid_val, + (a_uint32_t) sw->vid_mask, 0xfff)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_VID); + } + + /* vlan cfi */ + SW_GET_FIELD_BY_REG(MAC_RUL_V3, VLANCFIV, sw->cfi_val, hw->vlu[3]); + SW_GET_FIELD_BY_REG(MAC_RUL_M3, VLANCFIM, sw->cfi_mask, hw->msk[3]); + if (0x0 != sw->cfi_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_MAC_CFI); + } + + return SW_OK; +} + +static sw_error_t +_shiva_acl_rule_ip4_reparse(fal_acl_rule_t * sw, + const shiva_acl_hw_rule_t * hw) +{ + a_uint32_t mask_en; + + sw->dest_ip4_val = hw->vlu[0]; + sw->dest_ip4_mask = hw->msk[0]; + if (0x0 != sw->dest_ip4_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP4_DIP); + } + + sw->src_ip4_val = hw->vlu[1]; + sw->src_ip4_mask = hw->msk[1]; + if (0x0 != sw->src_ip4_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP4_SIP); + } + + SW_GET_FIELD_BY_REG(IP4_RUL_V2, IP4PROTV, sw->ip_proto_val, hw->vlu[2]); + SW_GET_FIELD_BY_REG(IP4_RUL_M2, IP4PROTM, sw->ip_proto_mask, hw->msk[2]); + if (0x0 != sw->ip_proto_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP_PROTO); + } + + SW_GET_FIELD_BY_REG(IP4_RUL_V2, IP4DSCPV, sw->ip_dscp_val, hw->vlu[2]); + SW_GET_FIELD_BY_REG(IP4_RUL_M2, IP4DSCPM, sw->ip_dscp_mask, hw->msk[2]); + if (0x0 != sw->ip_dscp_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP_DSCP); + } + + SW_GET_FIELD_BY_REG(IP4_RUL_V2, IP4DPORTV, sw->dest_l4port_val, hw->vlu[2]); + SW_GET_FIELD_BY_REG(IP4_RUL_M2, IP4DPORTM, sw->dest_l4port_mask, + hw->msk[2]); + SW_GET_FIELD_BY_REG(IP4_RUL_M3, IP4DPORTM_EN, mask_en, hw->msk[3]); + if (mask_en) + { + sw->dest_l4port_op = FAL_ACL_FIELD_MASK; + } + else + { + sw->dest_l4port_op = FAL_ACL_FIELD_RANGE; + } + + if (A_TRUE == + _shiva_acl_field_care(sw->dest_l4port_op, + (a_uint32_t) sw->dest_l4port_val, + (a_uint32_t) sw->dest_l4port_mask, 0xffff)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_DPORT); + } + else if (FAL_ACL_FIELD_RANGE == sw->dest_l4port_op) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_DPORT); + } + + SW_GET_FIELD_BY_REG(IP4_RUL_V3, IP4SPORTV, sw->src_l4port_val, hw->vlu[3]); + SW_GET_FIELD_BY_REG(IP4_RUL_M3, IP4SPORTM, sw->src_l4port_mask, hw->msk[3]); + SW_GET_FIELD_BY_REG(IP4_RUL_M3, IP4SPORTM_EN, mask_en, hw->msk[3]); + if (mask_en) + { + sw->src_l4port_op = FAL_ACL_FIELD_MASK; + } + else + { + sw->src_l4port_op = FAL_ACL_FIELD_RANGE; + } + + if (A_TRUE == + _shiva_acl_field_care(sw->src_l4port_op, + (a_uint32_t) sw->src_l4port_val, + (a_uint32_t) sw->src_l4port_mask, 0xffff)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_SPORT); + } + else if (FAL_ACL_FIELD_RANGE == sw->src_l4port_op) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_SPORT); + } + + return SW_OK; +} + +static sw_error_t +_shiva_acl_rule_ip6r1_reparse(fal_acl_rule_t * sw, + const shiva_acl_hw_rule_t * hw) +{ + a_uint32_t i; + + for (i = 0; i < 4; i++) + { + sw->dest_ip6_val.ul[i] = hw->vlu[3 - i]; + sw->dest_ip6_mask.ul[i] = hw->msk[3 - i]; + if (0x0 != sw->dest_ip6_mask.ul[i]) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP6_DIP); + } + } + return SW_OK; +} + +static sw_error_t +_shiva_acl_rule_ip6r2_reparse(fal_acl_rule_t * sw, + const shiva_acl_hw_rule_t * hw) +{ + a_uint32_t i; + + for (i = 0; i < 4; i++) + { + sw->src_ip6_val.ul[i] = hw->vlu[3 - i]; + sw->src_ip6_mask.ul[i] = hw->msk[3 - i]; + if (0x0 != sw->src_ip6_mask.ul[i]) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP6_SIP); + } + } + return SW_OK; +} + +static sw_error_t +_shiva_acl_rule_ip6r3_reparse(fal_acl_rule_t * sw, + const shiva_acl_hw_rule_t * hw) +{ + a_uint32_t mask_en; + a_uint32_t tmp; + + SW_GET_FIELD_BY_REG(IP6_RUL3_V0, IP6PROTV, sw->ip_proto_val, hw->vlu[0]); + SW_GET_FIELD_BY_REG(IP6_RUL3_M0, IP6PROTM, sw->ip_proto_mask, hw->msk[0]); + if (0x0 != sw->ip_proto_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP_PROTO); + } + + SW_GET_FIELD_BY_REG(IP6_RUL3_V0, IP6DSCPV, sw->ip_dscp_val, hw->vlu[0]); + SW_GET_FIELD_BY_REG(IP6_RUL3_M0, IP6DSCPM, sw->ip_dscp_mask, hw->msk[0]); + if (0x0 != sw->ip_dscp_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP_DSCP); + } + + SW_GET_FIELD_BY_REG(IP6_RUL3_V2, IP6DPORTV, sw->dest_l4port_val, + hw->vlu[2]); + SW_GET_FIELD_BY_REG(IP6_RUL3_M2, IP6DPORTM, sw->dest_l4port_mask, + hw->msk[2]); + SW_GET_FIELD_BY_REG(IP6_RUL3_M3, IP6DPORTM_EN, mask_en, hw->msk[3]); + if (mask_en) + { + sw->dest_l4port_op = FAL_ACL_FIELD_MASK; + } + else + { + sw->dest_l4port_op = FAL_ACL_FIELD_RANGE; + } + + if (A_TRUE == + _shiva_acl_field_care(sw->dest_l4port_op, + (a_uint32_t) sw->dest_l4port_val, + (a_uint32_t) sw->dest_l4port_mask, 0xffff)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_DPORT); + } + else if (FAL_ACL_FIELD_RANGE == sw->dest_l4port_op) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_DPORT); + } + + SW_GET_FIELD_BY_REG(IP6_RUL3_V3, IP6SPORTV, sw->src_l4port_val, hw->vlu[3]); + SW_GET_FIELD_BY_REG(IP6_RUL3_M3, IP6SPORTM, sw->src_l4port_mask, + hw->msk[3]); + SW_GET_FIELD_BY_REG(IP6_RUL3_M3, IP6SPORTM_EN, mask_en, hw->msk[3]); + if (mask_en) + { + sw->src_l4port_op = FAL_ACL_FIELD_MASK; + } + else + { + sw->src_l4port_op = FAL_ACL_FIELD_RANGE; + } + + if (A_TRUE == + _shiva_acl_field_care(sw->src_l4port_op, + (a_uint32_t) sw->src_l4port_val, + (a_uint32_t) sw->src_l4port_mask, 0xffff)) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_SPORT); + } + else if (FAL_ACL_FIELD_RANGE == sw->src_l4port_op) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_L4_SPORT); + } + + SW_GET_FIELD_BY_REG(IP6_RUL3_V1, IP6LABEL1V, sw->ip6_lable_val, hw->vlu[1]); + SW_GET_FIELD_BY_REG(IP6_RUL3_M1, IP6LABEL1M, sw->ip6_lable_mask, + hw->msk[1]); + + SW_GET_FIELD_BY_REG(IP6_RUL3_V2, IP6LABEL2V, tmp, hw->vlu[2]); + sw->ip6_lable_val |= (tmp << 16); + SW_GET_FIELD_BY_REG(IP6_RUL3_M2, IP6LABEL2M, tmp, hw->msk[2]); + sw->ip6_lable_mask |= (tmp << 16); + + if (0x0 != sw->ip6_lable_mask) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_IP6_LABEL); + } + + return SW_OK; +} + +static sw_error_t +_shiva_acl_rule_udf_reparse(fal_acl_rule_t * sw, + const shiva_acl_hw_rule_t * hw) +{ + a_uint32_t i, tmp; + + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_UDF); + + SW_GET_FIELD_BY_REG(UDF_RUL_V4, LAYER_OFFSET, tmp, hw->vlu[4]); + sw->udf_offset = tmp; + + SW_GET_FIELD_BY_REG(UDF_RUL_V4, LAYER_TYP, tmp, hw->vlu[4]); + if (tmp) + { + sw->udf_type = FAL_ACL_UDF_TYPE_L3; + sw->udf_len = hw->len - sw->udf_offset - 14; + } + else + { + sw->udf_type = FAL_ACL_UDF_TYPE_L2; + sw->udf_len = hw->len - sw->udf_offset; + } + + if (SHIVA_MAX_UDF_LENGTH < sw->udf_len) + { + return SW_READ_ERROR; + } + + for (i = 0; i < sw->udf_len; i++) + { + sw->udf_val[i] = ((hw->vlu[3 - i / 4]) >> (24 - 8 * (i % 4))) & 0xff; + sw->udf_mask[i] = ((hw->msk[3 - i / 4]) >> (24 - 8 * (i % 4))) & 0xff; + } + + return SW_OK; +} + +static sw_error_t +_shiva_acl_rule_action_reparse(fal_acl_rule_t * sw, + const shiva_acl_hw_rule_t * hw) +{ + a_uint32_t data; + + sw->match_cnt = hw->act[0]; + + sw->action_flg = 0; + SW_GET_FIELD_BY_REG(ACL_RSLT1, DES_PORT_EN, data, (hw->act[1])); + if (1 == data) + { + SW_GET_FIELD_BY_REG(ACL_RSLT1, PORT_MEM, data, (hw->act[1])); + sw->ports = data; + + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REDPT); + } + + SW_GET_FIELD_BY_REG(ACL_RSLT2, RDTCPU, data, (hw->act[2])); + if (1 == data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_RDTCPU); + } + + SW_GET_FIELD_BY_REG(ACL_RSLT2, CPYCPU, data, (hw->act[2])); + if (1 == data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_CPYCPU); + } + + SW_GET_FIELD_BY_REG(ACL_RSLT1, MIRR_EN, data, (hw->act[1])); + if (1 == data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_MIRROR); + } + + SW_GET_FIELD_BY_REG(ACL_RSLT1, REMARK_DOT1P, data, (hw->act[1])); + if (1 == data) + { + SW_GET_FIELD_BY_REG(ACL_RSLT1, DOT1P, data, (hw->act[1])); + sw->up = data & 0x7; + + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REMARK_UP); + } + + SW_GET_FIELD_BY_REG(ACL_RSLT1, REMARK_PRI_QU, data, (hw->act[1])); + if (1 == data) + { + SW_GET_FIELD_BY_REG(ACL_RSLT1, PRI_QU, data, (hw->act[1])); + sw->queue = data & 0x3; + + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_REMARK_QUEUE); + } + + SW_GET_FIELD_BY_REG(ACL_RSLT1, CHG_VID_EN, data, (hw->act[1])); + if (1 == data) + { + SW_GET_FIELD_BY_REG(ACL_RSLT1, STAG_CHG_EN, data, (hw->act[1])); + if (1 == data) + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_NEST_VLAN); + } + else + { + FAL_ACTION_FLG_SET(sw->action_flg, FAL_ACL_ACTION_MODIFY_VLAN); + SW_GET_FIELD_BY_REG(ACL_RSLT1, PORT_MEM, data, (hw->act[1])); + sw->ports = data; + } + } + + SW_GET_FIELD_BY_REG(ACL_RSLT1, VID, data, (hw->act[1])); + sw->vid = data & 0xfff; + + return SW_OK; +} + +static sw_error_t +_shiva_acl_filter_alloc(a_uint32_t dev_id, a_uint32_t * idx) +{ + a_uint32_t i; + + for (i = 0; i < SHIVA_MAX_RULE; i++) + { + if (0 == (filter_snap[dev_id] & (0x1UL << i))) + { + filter_snap[dev_id] |= (0x1UL << i); + *idx = i; + return SW_OK; + } + } + return SW_NO_RESOURCE; +} + +static void +_shiva_acl_filter_free(a_uint32_t dev_id, a_uint32_t idx) +{ + filter_snap[dev_id] &= (~(0x1UL << idx)); +} + +static void +_shiva_acl_filter_snap(a_uint32_t dev_id) +{ + filter_snap[dev_id] = filter[dev_id]; + return; +} + +static void +_shiva_acl_filter_commit(a_uint32_t dev_id) +{ + filter[dev_id] = filter_snap[dev_id]; + return; +} + +static sw_error_t +_shiva_acl_slct_update(shiva_acl_hw_rule_t * hw, a_uint32_t offset, + a_uint32_t flt_idx) +{ + switch (offset) + { + case 0: + SW_SET_REG_BY_FIELD(RUL_SLCT0, ADDR0_EN, 1, hw->slct[0]); + SW_SET_REG_BY_FIELD(RUL_SLCT1, ADDR0, flt_idx, hw->slct[1]); + break; + + case 1: + SW_SET_REG_BY_FIELD(RUL_SLCT0, ADDR1_EN, 1, hw->slct[0]); + SW_SET_REG_BY_FIELD(RUL_SLCT2, ADDR1, flt_idx, hw->slct[2]); + break; + + case 2: + SW_SET_REG_BY_FIELD(RUL_SLCT0, ADDR2_EN, 1, hw->slct[0]); + SW_SET_REG_BY_FIELD(RUL_SLCT3, ADDR2, flt_idx, hw->slct[3]); + break; + + case 3: + SW_SET_REG_BY_FIELD(RUL_SLCT0, ADDR3_EN, 1, hw->slct[0]); + SW_SET_REG_BY_FIELD(RUL_SLCT4, ADDR3, flt_idx, hw->slct[4]); + break; + + default: + return SW_FAIL; + } + return SW_OK; +} + +static sw_error_t +_shiva_acl_filter_write(a_uint32_t dev_id, const shiva_acl_hw_rule_t * rule, + a_uint32_t flt_idx) +{ +#ifdef SHIVA_SW_ENTRY + char *memaddr; + + memaddr = flt_vlu_mem + (flt_idx << 5); + aos_mem_copy(memaddr, (char *) &(rule->vlu[0]), sizeof(rule->vlu)); + + memaddr = flt_msk_mem + (flt_idx << 5); + aos_mem_copy(memaddr, (char *) &(rule->msk[0]), sizeof(rule->vlu)); + + memaddr = flt_typ_mem + (flt_idx << 5); + aos_mem_copy(memaddr, (char *) &(rule->typ), sizeof(rule->typ)); + + memaddr = flt_len_mem + (flt_idx << 5); + aos_mem_copy(memaddr, (char *) &(rule->len), sizeof(rule->len)); + +#else + sw_error_t rv; + a_uint32_t i, base, addr; + + /* set filter value */ + base = SHIVA_RULE_VLU_ADDR + (flt_idx << 5); + for (i = 0; i < (sizeof(rule->vlu) / sizeof(a_uint32_t)); i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(rule->vlu[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + /* set filter mask */ + base = SHIVA_RULE_MSK_ADDR + (flt_idx << 5); + for (i = 0; i < (sizeof(rule->msk) / sizeof(a_uint32_t)); i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(rule->msk[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + /* set filter type */ + addr = SHIVA_RULE_TYP_ADDR + (flt_idx << 5); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(rule->typ)), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* set filter length */ + addr = SHIVA_RULE_LEN_ADDR + (flt_idx << 5); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(rule->len)), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); +#endif + +#ifdef SHIVA_ENTRY_DUMP + a_uint32_t j; + aos_printk("\n_shiva_acl_filter_write flt_idx = %d type = %d len = %d\n", + flt_idx, rule->typ, rule->len); + for (j = 0; j < (sizeof(rule->vlu) / sizeof(a_uint32_t)); j++) + { + aos_printk("%08x ", rule->vlu[j]); + } + aos_printk("\n"); + for (j = 0; j < (sizeof(rule->msk) / sizeof(a_uint32_t)); j++) + { + aos_printk("%08x ", rule->msk[j]); + } +#endif + + return SW_OK; +} + +static sw_error_t +_shiva_acl_action_write(a_uint32_t dev_id, const shiva_acl_hw_rule_t * rule, + a_uint32_t act_idx) +{ +#ifdef SHIVA_SW_ENTRY + char *memaddr; + + memaddr = act_mem + (act_idx << 5); + aos_mem_copy(memaddr, (char *) &(rule->act[0]), sizeof(rule->act)); + +#else + sw_error_t rv; + a_uint32_t i, base, addr; + + /* set rule action */ + base = SHIVA_RULE_ACT_ADDR + (act_idx << 5); + for (i = 0; i < (sizeof(rule->act) / sizeof(a_uint32_t)); i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(rule->act[i])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } +#endif + +#ifdef SHIVA_ENTRY_DUMP + a_uint32_t j; + aos_printk("\n_shiva_acl_action_write act_idx = %d\n", act_idx); + for (j = 0; j < (sizeof(rule->act) / sizeof(a_uint32_t)); j++) + { + aos_printk("%08x ", rule->act[j]); + } +#endif + + return SW_OK; +} + +static sw_error_t +_shiva_acl_slct_write(a_uint32_t dev_id, const shiva_acl_hw_rule_t * rule, + a_uint32_t slct_idx) +{ +#ifdef SHIVA_SW_ENTRY + char *memaddr; + + memaddr = slct_mem + (slct_idx << 5); + aos_mem_copy(memaddr, (char *) &(rule->slct[0]), sizeof(rule->slct)); + +#else + sw_error_t rv; + a_uint32_t base, addr; + a_uint32_t i; + + base = SHIVA_RULE_SLCT_ADDR + (slct_idx << 5); + + /* set filter address and source ports bitmap*/ + for (i = 1; i < (sizeof(rule->slct) / sizeof(a_uint32_t)); i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(rule->slct[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + /* set filter enable */ + HSL_REG_ENTRY_GEN_SET(rv, dev_id, base, sizeof (a_uint32_t), + (a_uint8_t *) (&(rule->slct[0])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); +#endif + +#ifdef SHIVA_ENTRY_DUMP + a_uint32_t j; + aos_printk("\n_shiva_acl_slct_write slct_idx = %d\n", slct_idx); + for (j = 0; j < (sizeof(rule->slct) / sizeof(a_uint32_t)); j++) + { + aos_printk("%08x ", rule->slct[j]); + } +#endif + + return SW_OK; +} + +static sw_error_t +_shiva_acl_filter_read(a_uint32_t dev_id, shiva_acl_hw_rule_t * rule, + a_uint32_t flt_idx) +{ +#ifdef SHIVA_SW_ENTRY + char *memaddr; + + memaddr = flt_vlu_mem + (flt_idx << 5); + aos_mem_copy((char *) &(rule->vlu[0]), memaddr, 20); + + memaddr = flt_msk_mem + (flt_idx << 5); + aos_mem_copy((char *) &(rule->msk[0]), memaddr, 20); + + memaddr = flt_typ_mem + (flt_idx << 5); + aos_mem_copy((char *) &(rule->typ), memaddr, 4); + + memaddr = flt_len_mem + (flt_idx << 5); + aos_mem_copy((char *) &(rule->len), memaddr, 4); + +#else + sw_error_t rv; + a_uint32_t i, base, addr; + + /* get filter value */ + base = SHIVA_RULE_VLU_ADDR + (flt_idx << 5); + for (i = 0; i < (sizeof(rule->vlu) / sizeof(a_uint32_t)); i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(rule->vlu[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + /* get filter mask */ + base = SHIVA_RULE_MSK_ADDR + (flt_idx << 5); + for (i = 0; i < (sizeof(rule->msk) / sizeof(a_uint32_t)); i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(rule->msk[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + /* get filter type */ + addr = SHIVA_RULE_TYP_ADDR + (flt_idx << 5); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(rule->typ)), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* get filter length */ + addr = SHIVA_RULE_LEN_ADDR + (flt_idx << 5); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(rule->len)), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); +#endif + +#ifdef SHIVA_ENTRY_DUMP + a_uint32_t j; + aos_printk("\n_shiva_acl_filter_read flt_idx = %d type = %d len = %d \n", + flt_idx, rule->typ, rule->len); + for (j = 0; j < (sizeof(rule->vlu) / sizeof(a_uint32_t)); j++) + { + aos_printk("%08x ", rule->vlu[j]); + } + aos_printk("\n"); + for (j = 0; j < (sizeof(rule->msk) / sizeof(a_uint32_t)); j++) + { + aos_printk("%08x ", rule->msk[j]); + } +#endif + + return SW_OK; +} + +static sw_error_t +_shiva_acl_action_read(a_uint32_t dev_id, shiva_acl_hw_rule_t * rule, + a_uint32_t act_idx) +{ +#ifdef SHIVA_SW_ENTRY + char *memaddr; + + memaddr = act_mem + (act_idx << 5); + aos_mem_copy((char *) &(rule->act[0]), memaddr, sizeof(rule->act)); + +#else + sw_error_t rv; + a_uint32_t i, base, addr; + + /* get rule action */ + base = SHIVA_RULE_ACT_ADDR + (act_idx << 5); + for (i = 0; i < (sizeof(rule->act) / sizeof(a_uint32_t)); i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(rule->act[i])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } +#endif + +#ifdef SHIVA_ENTRY_DUMP + a_uint32_t j; + aos_printk("\n_shiva_acl_action_read act_idx = %d ", act_idx); + for (j = 0; j < (sizeof(rule->act) / sizeof(a_uint32_t)); j++) + { + aos_printk("%08x ", rule->act[j]); + } +#endif + + return SW_OK; +} + +static sw_error_t +_shiva_acl_slct_read(a_uint32_t dev_id, shiva_acl_hw_rule_t * rule, + a_uint32_t slct_idx) +{ +#ifdef SHIVA_SW_ENTRY + char *memaddr; + + memaddr = slct_mem + (slct_idx << 5); + aos_mem_copy((char *) &(rule->slct[0]), memaddr, sizeof(rule->slct)); + +#else + sw_error_t rv; + a_uint32_t i, base, addr; + + base = SHIVA_RULE_SLCT_ADDR + (slct_idx << 5); + + /* get filter address and enable and source ports bitmap */ + for (i = 0; i < (sizeof(rule->slct) / sizeof(a_uint32_t)); i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(rule->slct[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } +#endif + +#ifdef SHIVA_ENTRY_DUMP + a_uint32_t j; + aos_printk("\n_shiva_acl_slct_read slct_idx = %d\n", slct_idx); + for (j = 0; j < (sizeof(rule->slct) / sizeof(a_uint32_t)); j++) + { + aos_printk("%08x ", rule->slct[j]); + } +#endif + + return SW_OK; +} + +static sw_error_t +_shiva_acl_rule_set(a_uint32_t dev_id, a_uint32_t base_addr, + const shiva_acl_hw_rule_t * rule, a_uint32_t rule_nr) +{ + sw_error_t rv; + a_uint32_t ent_idx, tmp_ent_idx; + a_uint32_t i, flt_nr, flt_idx[4] = {0}; + a_uint32_t act_idx, slct_idx; + + act_idx = base_addr; + slct_idx = base_addr; + ent_idx = 0; + for (i = 0; i < rule_nr; i++) + { + tmp_ent_idx = ent_idx; + + rv = _shiva_acl_filter_map_get(&rule[ent_idx], flt_idx, &flt_nr); + SW_RTN_ON_ERROR(rv); + + if (!flt_nr) + { + return SW_FAIL; + } + + for (i = 0; i < flt_nr; i++) + { + rv = _shiva_acl_filter_write(dev_id, &(rule[ent_idx]), flt_idx[i]); + ent_idx++; + } + + rv = _shiva_acl_action_write(dev_id, &(rule[tmp_ent_idx]), act_idx); + SW_RTN_ON_ERROR(rv); + + rv = _shiva_acl_slct_write(dev_id, &(rule[tmp_ent_idx]), slct_idx); + SW_RTN_ON_ERROR(rv); + + act_idx++; + slct_idx++; + } + return SW_OK; +} + +static sw_error_t +_shiva_acl_rule_get(a_uint32_t dev_id, shiva_acl_hw_rule_t * rule, + a_uint32_t * ent_idx, a_uint32_t rule_idx) +{ + sw_error_t rv; + a_uint32_t i = 0, tmp_idx = 0, flt_nr = 0, flt_idx[4] = {0}; + + tmp_idx = *ent_idx; + + rv = _shiva_acl_slct_read(dev_id, &rule[tmp_idx], rule_idx); + SW_RTN_ON_ERROR(rv); + + rv = _shiva_acl_action_read(dev_id, &rule[tmp_idx], rule_idx); + SW_RTN_ON_ERROR(rv); + + rv = _shiva_acl_filter_map_get(&rule[tmp_idx], flt_idx, &flt_nr); + SW_RTN_ON_ERROR(rv); + + for (i = 0; i < flt_nr; i++) + { + rv = _shiva_acl_filter_read(dev_id, &rule[tmp_idx], flt_idx[i]); + SW_RTN_ON_ERROR(rv); + + tmp_idx++; + } + + *ent_idx = tmp_idx; + return SW_OK; +} + +static sw_error_t +_shiva_acl_rule_sw_to_hw(a_uint32_t dev_id, fal_acl_rule_t * sw, + shiva_acl_hw_rule_t * hw, a_uint32_t * idx) +{ + sw_error_t rv; + a_bool_t b_care; + a_bool_t b_valid = A_FALSE; + a_uint32_t tmp_idx; + + tmp_idx = *idx; + if (FAL_ACL_RULE_MAC == sw->rule_type) + { + rv = _shiva_acl_rule_udf_parse(sw, &hw[tmp_idx], &b_care); + SW_RTN_ON_ERROR(rv); + if (A_TRUE == b_care) + { + tmp_idx++; + } + + rv = _shiva_acl_rule_mac_parse(sw, &hw[tmp_idx], &b_care); + SW_RTN_ON_ERROR(rv); + tmp_idx++; + } + else if (FAL_ACL_RULE_IP4 == sw->rule_type) + { + rv = _shiva_acl_rule_udf_parse(sw, &hw[tmp_idx], &b_care); + SW_RTN_ON_ERROR(rv); + if (A_TRUE == b_care) + { + tmp_idx++; + } + + rv = _shiva_acl_rule_mac_parse(sw, &hw[tmp_idx], &b_care); + SW_RTN_ON_ERROR(rv); + if (A_TRUE == b_care) + { + tmp_idx++; + } + + rv = _shiva_acl_rule_ip4_parse(sw, &hw[tmp_idx], &b_care); + SW_RTN_ON_ERROR(rv); + tmp_idx++; + } + else if (FAL_ACL_RULE_IP6 == sw->rule_type) + { + rv = _shiva_acl_rule_udf_parse(sw, &hw[tmp_idx], &b_care); + SW_RTN_ON_ERROR(rv); + if (A_TRUE == b_care) + { + tmp_idx++; + } + + rv = _shiva_acl_rule_mac_parse(sw, &hw[tmp_idx], &b_care); + SW_RTN_ON_ERROR(rv); + if (A_TRUE == b_care) + { + tmp_idx++; + } + + rv = _shiva_acl_rule_ip6r1_parse(sw, &hw[tmp_idx], &b_care); + SW_RTN_ON_ERROR(rv); + if (A_TRUE == b_care) + { + tmp_idx++; + b_valid = A_TRUE; + } + + rv = _shiva_acl_rule_ip6r2_parse(sw, &hw[tmp_idx], &b_care); + SW_RTN_ON_ERROR(rv); + if (A_TRUE == b_care) + { + tmp_idx++; + b_valid = A_TRUE; + } + + rv = _shiva_acl_rule_ip6r3_parse(sw, &hw[tmp_idx], &b_care); + SW_RTN_ON_ERROR(rv); + if ((A_TRUE == b_care) || (A_FALSE == b_valid)) + { + tmp_idx++; + } + else + { + hw[tmp_idx - 1].len = hw[tmp_idx].len; + } + } + else if (FAL_ACL_RULE_UDF == sw->rule_type) + { + FAL_FIELD_FLG_SET(sw->field_flg, FAL_ACL_FIELD_UDF); + rv = _shiva_acl_rule_udf_parse(sw, &hw[tmp_idx], &b_care); + SW_RTN_ON_ERROR(rv); + tmp_idx++; + } + else + { + return SW_NOT_SUPPORTED; + } + + rv = _shiva_acl_action_parse(dev_id, sw, &(hw_rule_ent[*idx])); + SW_RTN_ON_ERROR(rv); + + *idx = tmp_idx; + return SW_OK; +} + +static sw_error_t +_shiva_acl_rule_hw_to_sw(fal_acl_rule_t * sw, const shiva_acl_hw_rule_t * hw, + a_uint32_t ent_idx, a_uint32_t ent_nr) +{ + sw_error_t rv; + a_uint32_t i, flt_typ; + a_bool_t b_mac = A_FALSE, b_ip4 = A_FALSE, b_ip6 = A_FALSE; + + rv = _shiva_acl_rule_action_reparse(sw, &hw[ent_idx]); + SW_RTN_ON_ERROR(rv); + + sw->rule_type = FAL_ACL_RULE_UDF; + for (i = 0; i < ent_nr; i++) + { + SW_GET_FIELD_BY_REG(RUL_SLCT7, RULE_TYP, flt_typ, hw[ent_idx + i].typ); + + if (SHIVA_UDF_FILTER == flt_typ) + { + rv = _shiva_acl_rule_udf_reparse(sw, &hw[ent_idx + i]); + SW_RTN_ON_ERROR(rv); + } + else if (SHIVA_MAC_FILTER == flt_typ) + { + rv = _shiva_acl_rule_mac_reparse(sw, &hw[ent_idx + i]); + SW_RTN_ON_ERROR(rv); + b_mac = A_TRUE; + } + else if (SHIVA_IP4_FILTER == flt_typ) + { + rv = _shiva_acl_rule_ip4_reparse(sw, &hw[ent_idx + i]); + SW_RTN_ON_ERROR(rv); + b_ip4 = A_TRUE; + } + else if (SHIVA_IP6R1_FILTER == flt_typ) + { + rv = _shiva_acl_rule_ip6r1_reparse(sw, &hw[ent_idx + i]); + SW_RTN_ON_ERROR(rv); + b_ip6 = A_TRUE; + } + else if (SHIVA_IP6R2_FILTER == flt_typ) + { + rv = _shiva_acl_rule_ip6r2_reparse(sw, &hw[ent_idx + i]); + SW_RTN_ON_ERROR(rv); + b_ip6 = A_TRUE; + } + else if (SHIVA_IP6R3_FILTER == flt_typ) + { + rv = _shiva_acl_rule_ip6r3_reparse(sw, &hw[ent_idx + i]); + SW_RTN_ON_ERROR(rv); + b_ip6 = A_TRUE; + } + else + { + return SW_FAIL; + } + } + + if (A_TRUE == b_mac) + { + sw->rule_type = FAL_ACL_RULE_MAC; + } + + if (A_TRUE == b_ip4) + { + sw->rule_type = FAL_ACL_RULE_IP4; + } + + if (A_TRUE == b_ip6) + { + sw->rule_type = FAL_ACL_RULE_IP6; + } + + return SW_OK; +} + +static sw_error_t +_shiva_acl_rule_copy(a_uint32_t dev_id, a_uint32_t src_slct_idx, + a_uint32_t dst_slct_idx, a_uint32_t size) +{ + sw_error_t rv; + a_uint32_t i; + a_int32_t step, src_idx, dst_idx; + shiva_acl_hw_rule_t rule; + + if (dst_slct_idx <= src_slct_idx) + { + src_idx = src_slct_idx & 0x7fffffff; + dst_idx = dst_slct_idx & 0x7fffffff; + step = 1; + } + else + { + src_idx = (src_slct_idx + size - 1) & 0x7fffffff; + dst_idx = (dst_slct_idx + size - 1) & 0x7fffffff; + step = -1; + } + + aos_mem_zero(&rule, sizeof (shiva_acl_hw_rule_t)); + for (i = 0; i < size; i++) + { + rv = _shiva_acl_rule_invalid(dev_id, (a_uint32_t) dst_idx, 1); + SW_RTN_ON_ERROR(rv); + + rv = _shiva_acl_action_read(dev_id, &rule, (a_uint32_t) src_idx); + SW_RTN_ON_ERROR(rv); + + rv = _shiva_acl_action_write(dev_id, &rule, (a_uint32_t) dst_idx); + SW_RTN_ON_ERROR(rv); + + rv = _shiva_acl_slct_read(dev_id, &rule, (a_uint32_t) src_idx); + SW_RTN_ON_ERROR(rv); + + rv = _shiva_acl_slct_write(dev_id, &rule, (a_uint32_t) dst_idx); + SW_RTN_ON_ERROR(rv); + + rv = _shiva_acl_rule_invalid(dev_id, (a_uint32_t) src_idx, 1); + SW_RTN_ON_ERROR(rv); + + src_idx += step; + dst_idx += step; + } + + return SW_OK; +} + +static sw_error_t +_shiva_acl_rule_invalid(a_uint32_t dev_id, a_uint32_t rule_idx, + a_uint32_t size) +{ + sw_error_t rv; + a_uint32_t base, flag, i; + + flag = 0; + for (i = 0; i < size; i++) + { + base = SHIVA_RULE_SLCT_ADDR + ((rule_idx + i) << 5); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, base, sizeof (a_uint32_t), + (a_uint8_t *) (&flag), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + return SW_OK; +} + +static sw_error_t +_shiva_acl_rule_valid(a_uint32_t dev_id, a_uint32_t rule_idx, a_uint32_t size, + a_uint32_t flag) +{ + sw_error_t rv; + a_uint32_t base, i; + + for (i = 0; i < size; i++) + { + base = SHIVA_RULE_SLCT_ADDR + ((rule_idx + i) << 5); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, base, sizeof (a_uint32_t), + (a_uint8_t *) (&flag), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + return SW_OK; +} + +static sw_error_t +_shiva_acl_addr_update(a_uint32_t dev_id, a_uint32_t old_addr, + a_uint32_t new_addr, a_uint32_t list_id) +{ + sw_error_t rv; + a_uint32_t idx; + + rv = _shiva_acl_list_loc(dev_id, list_id, &idx); + SW_RTN_ON_ERROR(rv); + + if (old_addr != list_ent[dev_id][idx].addr) + { + return SW_FAIL; + } + + list_ent[dev_id][idx].addr = new_addr; + return SW_OK; +} + +static sw_error_t +_shiva_acl_rule_bind(a_uint32_t dev_id, a_uint32_t rule_idx, a_uint32_t ports) +{ + sw_error_t rv; + shiva_acl_hw_rule_t rule; + + aos_mem_zero(&rule, sizeof (shiva_acl_hw_rule_t)); + + rv = _shiva_acl_slct_read(dev_id, &rule, rule_idx); + SW_RTN_ON_ERROR(rv); + + rv = _shiva_acl_rule_invalid(dev_id, rule_idx, 1); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(RUL_SLCT5, SRC_PT, ports, rule.slct[5]); + + rv = _shiva_acl_slct_write(dev_id, &rule, rule_idx); + SW_RTN_ON_ERROR(rv); + + rv = _shiva_acl_rule_valid(dev_id, rule_idx, 1, rule.slct[0]); + return rv; +} + +static sw_error_t +_shiva_acl_list_creat(a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t list_pri) +{ + a_uint32_t i, loc = SHIVA_MAX_LIST; + + HSL_DEV_ID_CHECK(dev_id); + + for (i = 0; i < SHIVA_MAX_LIST; i++) + { + if ((ENT_USED == list_ent[dev_id][i].status) + && (list_id == list_ent[dev_id][i].list_id)) + { + return SW_ALREADY_EXIST; + } + + if (ENT_FREE == list_ent[dev_id][i].status) + { + loc = i; + } + } + + if (SHIVA_MAX_LIST == loc) + { + return SW_NO_RESOURCE; + } + + aos_mem_zero(&(list_ent[dev_id][loc]), sizeof (shiva_acl_list_t)); + list_ent[dev_id][loc].list_id = list_id; + list_ent[dev_id][loc].list_pri = list_pri; + list_ent[dev_id][loc].status = ENT_USED; + _shiva_acl_list_dump(dev_id); + return SW_OK; +} + +static sw_error_t +_shiva_acl_list_destroy(a_uint32_t dev_id, a_uint32_t list_id) +{ + a_uint32_t list_idx; + + HSL_DEV_ID_CHECK(dev_id); + + for (list_idx = 0; list_idx < SHIVA_MAX_LIST; list_idx++) + { + if ((ENT_USED == list_ent[dev_id][list_idx].status) + && (list_id == list_ent[dev_id][list_idx].list_id)) + { + break; + } + } + + if (list_idx >= SHIVA_MAX_LIST) + { + return SW_NOT_FOUND; + } + + if (0 != list_ent[dev_id][list_idx].bind_pts) + { + return SW_NOT_SUPPORTED; + } + + if (0 != list_ent[dev_id][list_idx].size) + { + return SW_NOT_SUPPORTED; + } + + aos_mem_zero(&(list_ent[dev_id][list_idx]), sizeof (shiva_acl_list_t)); + list_ent[dev_id][list_idx].status = ENT_FREE; + _shiva_acl_list_dump(dev_id); + return SW_OK; +} + +static sw_error_t +_shiva_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; + a_uint32_t hsl_f_rsc, list_new_size, list_addr; + a_uint32_t list_pri, list_idx, load_addr, bind_pts; + + HSL_DEV_ID_CHECK(dev_id); + + if ((0 == rule_nr) || (NULL == rule)) + { + return SW_BAD_PARAM; + } + + rv = hsl_acl_free_rsc_get(dev_id, &hsl_f_rsc); + SW_RTN_ON_ERROR(rv); + if (hsl_f_rsc < rule_nr) + { + return SW_NO_RESOURCE; + } + + rv = _shiva_acl_list_loc(dev_id, list_id, &list_idx); + SW_RTN_ON_ERROR(rv); + + if (rule_id != list_ent[dev_id][list_idx].size) + { + return SW_ALREADY_EXIST; + } + bind_pts = list_ent[dev_id][list_idx].bind_pts; + + _shiva_acl_filter_snap(dev_id); + + /* parse rule entry and alloc rule resource */ + { + a_uint32_t i, j; + a_uint32_t ent_idx, tmp_ent_idx, flt_idx; + + aos_mem_zero(hw_rule_ent, + SHIVA_MAX_RULE * sizeof (shiva_acl_hw_rule_t)); + + ent_idx = 0; + for (i = 0; i < rule_nr; i++) + { + tmp_ent_idx = ent_idx; + rv = _shiva_acl_rule_sw_to_hw(dev_id, &rule[i], + &hw_rule_ent[ent_idx], &ent_idx); + SW_RTN_ON_ERROR(rv); + + if (4 < (ent_idx - tmp_ent_idx)) + { + return SW_NOT_SUPPORTED; + } + + for (j = tmp_ent_idx; j < ent_idx; j++) + { + rv = _shiva_acl_filter_alloc(dev_id, &flt_idx); + SW_RTN_ON_ERROR(rv); + + rv = _shiva_acl_slct_update(&hw_rule_ent[tmp_ent_idx], + j - tmp_ent_idx, flt_idx); + SW_RTN_ON_ERROR(rv); + } + SW_SET_REG_BY_FIELD(RUL_SLCT5, SRC_PT, bind_pts, + hw_rule_ent[tmp_ent_idx].slct[5]); + } + } + + /* alloc hardware select entry resource */ + if (0 == list_ent[dev_id][list_idx].size) + { + list_new_size = rule_nr; + list_pri = list_ent[dev_id][list_idx].list_pri; + + rv = hsl_acl_blk_alloc(dev_id, list_pri, list_new_size, list_id, + &list_addr); + SW_RTN_ON_ERROR(rv); + + load_addr = list_addr; + } + else + { + list_new_size = list_ent[dev_id][list_idx].size + rule_nr; + list_addr = list_ent[dev_id][list_idx].addr; + + rv = hsl_acl_blk_resize(dev_id, list_addr, list_new_size); + SW_RTN_ON_ERROR(rv); + + /* must be careful resize opration maybe change list base address */ + list_addr = list_ent[dev_id][list_idx].addr; + load_addr = list_ent[dev_id][list_idx].size + list_addr; + } + + /* load acl rule to hardware */ + rv = _shiva_acl_rule_set(dev_id, load_addr, hw_rule_ent, rule_nr); + if (SW_OK != rv) + { + (void) hsl_acl_blk_resize(dev_id, list_addr, + list_ent[dev_id][list_idx].size); + return rv; + } + + /* update software list control information */ + list_ent[dev_id][list_idx].size = list_new_size; + list_ent[dev_id][list_idx].addr = list_addr; + + /* update hardware acl rule resource information */ + _shiva_acl_filter_commit(dev_id); + _shiva_acl_list_dump(dev_id); + return SW_OK; +} + +static sw_error_t +_shiva_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; + a_uint32_t flt_idx[4] = {0}; + a_uint32_t i, j, flt_nr; + a_uint32_t list_idx = 0, addr, size, rule_idx, cnt; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _shiva_acl_list_loc(dev_id, list_id, &list_idx); + SW_RTN_ON_ERROR(rv); + + if (0 == rule_nr) + { + return SW_BAD_PARAM; + } + + if ((rule_id + rule_nr) > list_ent[dev_id][list_idx].size) + { + return SW_NOT_FOUND; + } + + _shiva_acl_filter_snap(dev_id); + + /* free hardware filter resource */ + addr = list_ent[dev_id][list_idx].addr + rule_id; + for (i = 0; i < rule_nr; i++) + { + rv = _shiva_acl_slct_read(dev_id, &hw_rule_ent[0], i + addr); + SW_RTN_ON_ERROR(rv); + + rv = _shiva_acl_filter_map_get(&hw_rule_ent[0], flt_idx, &flt_nr); + SW_RTN_ON_ERROR(rv); + + for (j = 0; j < flt_nr; j++) + { + _shiva_acl_filter_free(dev_id, flt_idx[j]); + } + } + + cnt = list_ent[dev_id][list_idx].size - (rule_id + rule_nr); + rule_idx = list_ent[dev_id][list_idx].addr + (rule_id + rule_nr); + rv = _shiva_acl_rule_copy(dev_id, rule_idx, rule_idx - rule_nr, cnt); + SW_RTN_ON_ERROR(rv); + + addr = list_ent[dev_id][list_idx].addr; + size = list_ent[dev_id][list_idx].size; + rv = hsl_acl_blk_resize(dev_id, addr, size - rule_nr); + SW_RTN_ON_ERROR(rv); + + list_ent[dev_id][list_idx].size -= rule_nr; + _shiva_acl_filter_commit(dev_id); + _shiva_acl_list_dump(dev_id); + return SW_OK; +} + +static sw_error_t +_shiva_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; + a_uint32_t list_idx, ent_idx, tmp_ent_idx, rule_idx; + + HSL_DEV_ID_CHECK(dev_id); + + rv = _shiva_acl_list_loc(dev_id, list_id, &list_idx); + SW_RTN_ON_ERROR(rv); + + if (rule_id >= list_ent[dev_id][list_idx].size) + { + return SW_NOT_FOUND; + } + + aos_mem_zero(rule, sizeof (fal_acl_rule_t)); + + ent_idx = 0; + tmp_ent_idx = 0; + rule_idx = list_ent[dev_id][list_idx].addr + rule_id; + rv = _shiva_acl_rule_get(dev_id, hw_rule_ent, &tmp_ent_idx, rule_idx); + SW_RTN_ON_ERROR(rv); + + rv = _shiva_acl_rule_hw_to_sw(rule, hw_rule_ent, ent_idx, + tmp_ent_idx - ent_idx); + return rv; +} + +static sw_error_t +_shiva_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; + a_uint32_t i, list_idx, rule_idx, base, ports; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_ACL_DIREC_IN != direc) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_ACL_BIND_PORT != obj_t) + { + return SW_NOT_SUPPORTED; + } + + rv = _shiva_acl_list_loc(dev_id, list_id, &list_idx); + SW_RTN_ON_ERROR(rv); + + if (list_ent[dev_id][list_idx].bind_pts & (0x1 << obj_idx)) + { + return SW_ALREADY_EXIST; + } + + base = list_ent[dev_id][list_idx].addr; + ports = list_ent[dev_id][list_idx].bind_pts | (0x1 << obj_idx); + for (i = 0; i < list_ent[dev_id][list_idx].size; i++) + { + rule_idx = base + i; + rv = _shiva_acl_rule_bind(dev_id, rule_idx, ports); + SW_RTN_ON_ERROR(rv); + } + + list_ent[dev_id][list_idx].bind_pts = ports; + return SW_OK; +} + +static sw_error_t +_shiva_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; + a_uint32_t i, list_idx, rule_idx, base, ports; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_ACL_DIREC_IN != direc) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_ACL_BIND_PORT != obj_t) + { + return SW_NOT_SUPPORTED; + } + + rv = _shiva_acl_list_loc(dev_id, list_id, &list_idx); + SW_RTN_ON_ERROR(rv); + + if (!(list_ent[dev_id][list_idx].bind_pts & (0x1 << obj_idx))) + { + return SW_NOT_FOUND; + } + + base = list_ent[dev_id][list_idx].addr; + ports = list_ent[dev_id][list_idx].bind_pts & (~(0x1UL << obj_idx)); + for (i = 0; i < list_ent[dev_id][list_idx].size; i++) + { + rule_idx = base + i; + rv = _shiva_acl_rule_bind(dev_id, rule_idx, ports); + SW_RTN_ON_ERROR(rv); + } + + list_ent[dev_id][list_idx].bind_pts = ports; + return SW_OK; +} + +static sw_error_t +_shiva_acl_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, QM_CTL, 0, ACL_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_acl_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, QM_CTL, 0, ACL_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +HSL_LOCAL sw_error_t +shiva_acl_list_dump(a_uint32_t dev_id) +{ + a_uint32_t idx; + + aos_printk("\nshiva_acl_list_dump:\n"); + for (idx = 0; idx < SHIVA_MAX_LIST; idx++) + { + if (ENT_USED == list_ent[dev_id][idx].status) + { + aos_printk + ("\n[id]:%02d [pri]:%02d [size]:%02d [addr]:%02d [pts_map]:0x%02x", + list_ent[dev_id][idx].list_id, list_ent[dev_id][idx].list_pri, + list_ent[dev_id][idx].size, list_ent[dev_id][idx].addr, + list_ent[dev_id][idx].bind_pts); + } + } + aos_printk("\n"); + + return SW_OK; +} + +HSL_LOCAL sw_error_t +shiva_acl_rule_dump(a_uint32_t dev_id) +{ + a_uint32_t slt_idx, flt_nr, i, j; + a_uint32_t flt_idx[4] = {0}; + sw_error_t rv; + shiva_acl_hw_rule_t rule; + + aos_printk("\nshiva_acl_rule_dump:\n"); + + aos_printk("\nfilter_bitmap:0x%x", filter[dev_id]); + for (slt_idx = 0; slt_idx < SHIVA_MAX_RULE; slt_idx++) + { + aos_mem_zero(&rule, sizeof (shiva_acl_hw_rule_t)); + + rv = _shiva_acl_slct_read(dev_id, &rule, slt_idx); + if (SW_OK != rv) + { + continue; + } + + rv = _shiva_acl_filter_map_get(&rule, flt_idx, &flt_nr); + if (SW_OK != rv) + { + continue; + } + + aos_printk("\nslct_idx=%d ", slt_idx); + for (i = 0; i < flt_nr; i++) + { + aos_printk("flt%d_idx=%d ", i, flt_idx[i]); + } + + aos_printk("\nslt:"); + for (i = 0; i < (sizeof(rule.slct)/sizeof(a_uint32_t)); i++) + { + aos_printk("%08x ", rule.slct[i]); + } + + if (flt_nr) + { + rv = _shiva_acl_action_read(dev_id, &rule, slt_idx); + if (SW_OK != rv) + { + continue; + } + + aos_printk("\nact:"); + for (i = 0; i < (sizeof(rule.act)/sizeof(a_uint32_t)); i++) + { + aos_printk("%08x ", rule.act[i]); + } + + for (i = 0; i < flt_nr; i++) + { + rv = _shiva_acl_filter_read(dev_id, &rule, flt_idx[i]); + if (SW_OK != rv) + { + continue; + } + + aos_printk("\ntyp:%08x length:%08x", rule.typ, rule.len); + aos_printk("\nvlu:"); + for (j = 0; j < (sizeof(rule.vlu)/sizeof(a_uint32_t)); j++) + { + aos_printk("%08x ", rule.vlu[j]); + } + + aos_printk("\nmsk:"); + for (j = 0; j < (sizeof(rule.msk)/sizeof(a_uint32_t)); j++) + { + aos_printk("%08x ", rule.msk[j]); + } + aos_printk("\n"); + } + } + aos_printk("\n"); + } + + return SW_OK; +} + +sw_error_t +shiva_acl_reset(a_uint32_t dev_id) +{ + sw_error_t rv; + a_uint32_t i; + + HSL_DEV_ID_CHECK(dev_id); + + aos_mem_zero(hw_rule_ent, + (SHIVA_MAX_RULE + 3) * sizeof (shiva_acl_hw_rule_t)); + + aos_mem_zero(list_ent[dev_id], + SHIVA_MAX_LIST * sizeof (shiva_acl_list_t)); + + for (i = 0; i < SHIVA_MAX_LIST; i++) + { + list_ent[dev_id][i].status = ENT_FREE; + } + + filter[dev_id] = 0; + filter_snap[dev_id] = 0; + + rv = hsl_acl_pool_destroy(dev_id); + SW_RTN_ON_ERROR(rv); + + rv = hsl_acl_pool_creat(dev_id, SHIVA_MAX_LIST, SHIVA_MAX_RULE); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +/** + * @brief Creat an acl list + * @details Comments: + * If the priority of a list is more small then the priority is more high, + * that means the list could be first matched. + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] list_pri acl list priority + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_acl_list_creat(a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t list_pri) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_acl_list_creat(dev_id, list_id, list_pri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Destroy an acl list + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_acl_list_destroy(a_uint32_t dev_id, a_uint32_t list_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_acl_list_destroy(dev_id, list_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add one rule or more rules to an existing acl list + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] rule_id first rule id of this adding operation in list + * @param[in] rule_nr rule number of this adding operation + * @param[in] rule rules content of this adding operation + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_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; + + HSL_API_LOCK; + rv = _shiva_acl_rule_add(dev_id, list_id, rule_id, rule_nr, rule); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete one rule or more rules from an existing acl list + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] rule_id first rule id of this deleteing operation in list + * @param[in] rule_nr rule number of this deleteing operation + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_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; + + HSL_API_LOCK; + rv = _shiva_acl_rule_delete(dev_id, list_id, rule_id, rule_nr); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Query one particular rule in a particular acl list + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] rule_id first rule id of this deleteing operation in list + * @param[out] rule rule content of this operation + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_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; + + HSL_API_LOCK; + rv = _shiva_acl_rule_query(dev_id, list_id, rule_id, rule); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Bind an acl list to a particular object + * @details Comments: + * If obj_t equals FAL_ACL_BIND_PORT then obj_idx means port id + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] direc direction of this binding operation + * @param[in] obj_t object type of this binding operation + * @param[in] obj_idx object index of this binding operation + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_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; + + HSL_API_LOCK; + rv = _shiva_acl_list_bind(dev_id, list_id, direc, obj_t, obj_idx); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Unbind an acl list from a particular object + * @details Comments: + * If obj_t equals FAL_ACL_BIND_PORT then obj_idx means port id + * @param[in] dev_id device id + * @param[in] list_id acl list id + * @param[in] direc direction of this unbinding operation + * @param[in] obj_t object type of this unbinding operation + * @param[in] obj_idx object index of this unbinding operation + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_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; + + HSL_API_LOCK; + rv = _shiva_acl_list_unbind(dev_id, list_id, direc, obj_t, obj_idx); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set working status of ACL engine on a particular device + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_acl_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_acl_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get working status of ACL engine on a particular device + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_acl_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_acl_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +shiva_acl_init(a_uint32_t dev_id) +{ + static a_bool_t b_hw_rule = A_FALSE; + hsl_acl_func_t *acl_func; + shiva_acl_hw_rule_t rule; + sw_error_t rv; + a_uint32_t i; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == b_hw_rule) + { + hw_rule_ent = (shiva_acl_hw_rule_t *) + aos_mem_alloc((SHIVA_MAX_RULE + + 3) * sizeof (shiva_acl_hw_rule_t)); + if (NULL == hw_rule_ent) + { + return SW_NO_RESOURCE; + } + aos_mem_zero(hw_rule_ent, + (SHIVA_MAX_RULE + 3) * sizeof (shiva_acl_hw_rule_t)); + b_hw_rule = A_TRUE; + } + + list_ent[dev_id] = (shiva_acl_list_t *) + aos_mem_alloc(SHIVA_MAX_LIST * sizeof (shiva_acl_list_t)); + if (NULL == list_ent[dev_id]) + { + return SW_NO_RESOURCE; + } + aos_mem_zero(list_ent[dev_id], + SHIVA_MAX_LIST * sizeof (shiva_acl_list_t)); + + for (i = 0; i < SHIVA_MAX_LIST; i++) + { + list_ent[dev_id][i].status = ENT_FREE; + } + + filter[dev_id] = 0; + filter_snap[dev_id] = 0; + + rv = hsl_acl_pool_creat(dev_id, SHIVA_MAX_LIST, SHIVA_MAX_RULE); + SW_RTN_ON_ERROR(rv); + + acl_func = hsl_acl_ptr_get(dev_id); + SW_RTN_ON_NULL(acl_func); + + acl_func->acl_rule_copy = _shiva_acl_rule_copy; + acl_func->acl_rule_invalid = _shiva_acl_rule_invalid; + acl_func->acl_addr_update = _shiva_acl_addr_update; + + /* zero acl hardware memory */ + aos_mem_zero(&rule, sizeof (shiva_acl_hw_rule_t)); + for (i = 0; i < SHIVA_MAX_RULE; i++) + { + rv = _shiva_acl_slct_write(dev_id, &rule, i); + SW_RTN_ON_ERROR(rv); + } + +#ifdef SHIVA_SW_ENTRY + flt_vlu_mem = aos_mem_alloc(SHIVA_MAX_RULE * 32); + if (NULL == flt_vlu_mem) + { + return SW_NO_RESOURCE; + } + aos_mem_zero(flt_vlu_mem, SHIVA_MAX_RULE * 32); + + flt_msk_mem = aos_mem_alloc(SHIVA_MAX_RULE * 32); + if (NULL == flt_msk_mem) + { + return SW_NO_RESOURCE; + } + aos_mem_zero(flt_msk_mem, SHIVA_MAX_RULE * 32); + + flt_typ_mem = aos_mem_alloc(SHIVA_MAX_RULE * 4); + if (NULL == flt_typ_mem) + { + return SW_NO_RESOURCE; + } + aos_mem_zero(flt_typ_mem, SHIVA_MAX_RULE * 4); + + flt_len_mem = aos_mem_alloc(SHIVA_MAX_RULE * 4); + if (NULL == flt_len_mem) + { + return SW_NO_RESOURCE; + } + aos_mem_zero(flt_len_mem, SHIVA_MAX_RULE * 4); + + act_mem = aos_mem_alloc(SHIVA_MAX_RULE * 32); + if (NULL == act_mem) + { + return SW_NO_RESOURCE; + } + aos_mem_zero(act_mem, SHIVA_MAX_RULE * 32); + + slct_mem = aos_mem_alloc(SHIVA_MAX_RULE * 32); + if (NULL == slct_mem) + { + return SW_NO_RESOURCE; + } + aos_mem_zero(slct_mem, SHIVA_MAX_RULE * 32); +#endif + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->acl_list_creat = shiva_acl_list_creat; + p_api->acl_list_destroy = shiva_acl_list_destroy; + p_api->acl_list_bind = shiva_acl_list_bind; + p_api->acl_list_unbind = shiva_acl_list_unbind; + p_api->acl_rule_add = shiva_acl_rule_add; + p_api->acl_rule_delete = shiva_acl_rule_delete; + p_api->acl_rule_query = shiva_acl_rule_query; + p_api->acl_status_set = shiva_acl_status_set; + p_api->acl_status_get = shiva_acl_status_get; + p_api->acl_list_dump = shiva_acl_list_dump; + p_api->acl_rule_dump = shiva_acl_rule_dump; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_fdb.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_fdb.c new file mode 100755 index 000000000..5bc43b0fb --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_fdb.c @@ -0,0 +1,1135 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup shiva_fdb SHIVA_FDB + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "shiva_fdb.h" +#include "shiva_reg.h" + +#define ARL_FLUSH_ALL 1 +#define ARL_LOAD_ENTRY 2 +#define ARL_PURGE_ENTRY 3 +#define ARL_FLUSH_ALL_UNLOCK 4 +#define ARL_FLUSH_PORT_UNICAST 5 +#define ARL_NEXT_ENTRY 6 +#define ARL_FIND_ENTRY 7 + +#define ARL_FIRST_ENTRY 1001 +#define ARL_FLUSH_PORT_NO_STATIC 1002 +#define ARL_FLUSH_PORT_AND_STATIC 1003 + +static a_bool_t +shiva_fdb_is_zeroaddr(fal_mac_addr_t addr) +{ + a_uint32_t i; + + for (i = 0; i < 6; i++) + { + if (addr.uc[i]) + { + return A_FALSE; + } + } + + return A_TRUE; +} + +static void +shiva_fdb_fill_addr(fal_mac_addr_t addr, a_uint32_t * reg0, a_uint32_t * reg1) +{ + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_ADDR_BYTE0, addr.uc[0], *reg1); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_ADDR_BYTE1, addr.uc[1], *reg1); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_ADDR_BYTE2, addr.uc[2], *reg1); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_ADDR_BYTE3, addr.uc[3], *reg1); + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_ADDR_BYTE4, addr.uc[4], *reg0); + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_ADDR_BYTE5, addr.uc[5], *reg0); + + return; +} + +static sw_error_t +shiva_atu_sw_to_hw(a_uint32_t dev_id, const fal_fdb_entry_t * entry, + a_uint32_t reg[]) +{ + a_uint32_t port; + + if (A_FALSE == entry->portmap_en) + { + if (A_TRUE != + hsl_port_prop_check(dev_id, entry->port.id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + port = 0x1UL << entry->port.id; + } + else + { + if (A_FALSE == + hsl_mports_prop_check(dev_id, entry->port.map, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + port = entry->port.map; + } + + if (FAL_MAC_CPY_TO_CPU == entry->dacmd) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, COPY_TO_CPU, 1, reg[2]); + } + else if (FAL_MAC_RDT_TO_CPU == entry->dacmd) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, REDRCT_TO_CPU, 1, reg[2]); + } + else if (FAL_MAC_FRWRD != entry->dacmd) + { + return SW_NOT_SUPPORTED; + } + + if (FAL_MAC_DROP == entry->sacmd) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, SA_DROP_EN, 1, reg[2]); + } + else if (FAL_MAC_FRWRD != entry->sacmd) + { + return SW_NOT_SUPPORTED; + } + + if (A_TRUE == entry->leaky_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, LEAKY_EN, 1, reg[2]); + } + else + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, LEAKY_EN, 0, reg[2]); + } + + if (A_TRUE == entry->static_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_STATUS, 15, reg[2]); + } + else + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_STATUS, 7, reg[2]); + } + + if (A_TRUE == entry->mirror_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, MIRROR_EN, 1, reg[2]); + } + + if (A_TRUE == entry->clone_en) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, CLONE_EN, 1, reg[2]); + } + + if (A_TRUE == entry->cross_pt_state) + { + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, CROSS_PT, 1, reg[2]); + } + + if (A_TRUE == entry->da_pri_en) + { + hsl_dev_t *p_dev; + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_PRI_EN, 1, reg[2]); + + SW_RTN_ON_NULL(p_dev = hsl_dev_ptr_get(dev_id)); + + if (entry->da_queue > (p_dev->nr_queue - 1)) + return SW_BAD_PARAM; + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_PRI, entry->da_queue, reg[2]); + } + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, DES_PORT, port, reg[2]); + shiva_fdb_fill_addr(entry->addr, ®[0], ®[1]); + + return SW_OK; +} + +static void +shiva_atu_hw_to_sw(const a_uint32_t reg[], fal_fdb_entry_t * entry) +{ + a_uint32_t i, data; + + aos_mem_zero(entry, sizeof (fal_fdb_entry_t)); + + entry->dacmd = FAL_MAC_FRWRD; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, COPY_TO_CPU, data, reg[2]); + if (1 == data) + { + entry->dacmd = FAL_MAC_CPY_TO_CPU; + } + + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, REDRCT_TO_CPU, data, reg[2]); + if (1 == data) + { + entry->dacmd = FAL_MAC_RDT_TO_CPU; + } + + entry->sacmd = FAL_MAC_FRWRD; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, SA_DROP_EN, data, reg[2]); + if (1 == data) + { + entry->sacmd = FAL_MAC_DROP; + } + + entry->leaky_en = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, LEAKY_EN, data, reg[2]); + if (1 == data) + { + entry->leaky_en = A_TRUE; + } + + entry->static_en = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, AT_STATUS, data, reg[2]); + if (0xf == data) + { + entry->static_en = A_TRUE; + } + + entry->mirror_en = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, MIRROR_EN, data, reg[2]); + if (1 == data) + { + entry->mirror_en = A_TRUE; + } + + entry->clone_en = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, CLONE_EN, data, reg[2]); + if (1 == data) + { + entry->clone_en = A_TRUE; + } + + entry->da_pri_en = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, AT_PRI_EN, data, reg[2]); + if (1 == data) + { + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, AT_PRI, data, reg[2]); + entry->da_pri_en = A_TRUE; + entry->da_queue = data & 0x3; + } + + entry->cross_pt_state = A_FALSE; + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, CROSS_PT, data, reg[2]); + if (1 == data) + { + entry->cross_pt_state = A_TRUE; + } + + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, DES_PORT, data, reg[2]); + + entry->portmap_en = A_TRUE; + entry->port.map = data; + + for (i = 0; i < 4; i++) + { + entry->addr.uc[i] = (reg[1] >> ((3 - i) << 3)) & 0xff; + } + + for (i = 4; i < 6; i++) + { + entry->addr.uc[i] = (reg[0] >> ((7 - i) << 3)) & 0xff; + } + + return; +} + +static sw_error_t +shiva_fdb_commit(a_uint32_t dev_id, a_uint32_t op) +{ + sw_error_t rv; + a_uint32_t busy = 1; + a_uint32_t full_vio; + a_uint32_t i = 1000; + a_uint32_t entry; + a_uint32_t hwop = op; + + while (busy && --i) + { + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_FUNC0, 0, AT_BUSY, + (a_uint8_t *) (&busy), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + aos_udelay(5); + } + + if (0 == i) + { + return SW_BUSY; + } + + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC0, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_BUSY, 1, entry); + + if (ARL_FLUSH_PORT_AND_STATIC == hwop) + { + hwop = ARL_FLUSH_PORT_UNICAST; + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, FLUSH_ST_EN, 1, entry); + } + + if (ARL_FLUSH_PORT_NO_STATIC == hwop) + { + hwop = ARL_FLUSH_PORT_UNICAST; + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, FLUSH_ST_EN, 0, entry); + } + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_FUNC, hwop, entry); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC0, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + busy = 1; + i = 1000; + while (busy && --i) + { + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_FUNC0, 0, AT_BUSY, + (a_uint8_t *) (&busy), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + aos_udelay(5); + } + + if (0 == i) + { + return SW_FAIL; + } + + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_FUNC0, 0, AT_FULL_VIO, + (a_uint8_t *) (&full_vio), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (full_vio) + { + /* must clear AT_FULL_VOI bit */ + entry = 0x1000; + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC0, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (ARL_LOAD_ENTRY == hwop) + { + return SW_FULL; + } + else if ((ARL_PURGE_ENTRY == hwop) + || (ARL_FLUSH_PORT_UNICAST == hwop)) + { + return SW_NOT_FOUND; + } + else + { + return SW_FAIL; + } + } + + return SW_OK; +} + +static sw_error_t +shiva_atu_get(a_uint32_t dev_id, fal_fdb_entry_t * entry, a_uint32_t op) +{ + sw_error_t rv; + a_uint32_t reg[3] = { 0 }; + a_uint32_t status = 0; + a_uint32_t hwop = op; + + if ((ARL_NEXT_ENTRY == op) + || (ARL_FIND_ENTRY == op)) + { + shiva_fdb_fill_addr(entry->addr, ®[0], ®[1]); + } + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + /* set status not zero */ + if (ARL_NEXT_ENTRY == op) + { + reg[2] = 0xf0000; + } + + if (ARL_FIRST_ENTRY == op) + { + hwop = ARL_NEXT_ENTRY; + } + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC2, 0, + (a_uint8_t *) (®[2]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = shiva_fdb_commit(dev_id, hwop); + SW_RTN_ON_ERROR(rv); + + /* get hardware enrety */ + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC2, 0, + (a_uint8_t *) (®[2]), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, AT_STATUS, status, reg[2]); + + shiva_atu_hw_to_sw(reg, entry); + + /* If hardware return back with address and status all zero, + that means no other next valid entry in fdb table */ + if ((A_TRUE == shiva_fdb_is_zeroaddr(entry->addr)) + && (0 == status)) + { + if (ARL_NEXT_ENTRY == op) + { + return SW_NO_MORE; + } + else if ((ARL_FIND_ENTRY == op) + || (ARL_FIRST_ENTRY == op)) + { + return SW_NOT_FOUND; + } + else + { + return SW_FAIL; + } + } + else + { + return SW_OK; + } +} + +static sw_error_t +_shiva_fdb_add(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t reg[3] = { 0, 0, 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + rv = shiva_atu_sw_to_hw(dev_id, entry, reg); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC2, 0, + (a_uint8_t *) (®[2]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC1, 0, (a_uint8_t *) (®[1]), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC0, 0, (a_uint8_t *) (®[0]), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = shiva_fdb_commit(dev_id, ARL_LOAD_ENTRY); + + return rv; +} + +static sw_error_t +_shiva_fdb_del_all(a_uint32_t dev_id, a_uint32_t flag) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_FDB_DEL_STATIC & flag) + { + rv = shiva_fdb_commit(dev_id, ARL_FLUSH_ALL); + } + else + { + rv = shiva_fdb_commit(dev_id, ARL_FLUSH_ALL_UNLOCK); + } + + return rv; +} + +static sw_error_t +_shiva_fdb_del_by_port(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t flag) +{ + sw_error_t rv; + a_uint32_t reg = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_PORT_NUM, port_id, reg); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC0, 0, (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_FDB_DEL_STATIC & flag) + { + rv = shiva_fdb_commit(dev_id, ARL_FLUSH_PORT_AND_STATIC); + } + else + { + rv = shiva_fdb_commit(dev_id, ARL_FLUSH_PORT_NO_STATIC); + } + + return rv; +} + +static sw_error_t +_shiva_fdb_del_by_mac(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv; + a_uint32_t reg0 = 0, reg1 = 0; + + HSL_DEV_ID_CHECK(dev_id); + + shiva_fdb_fill_addr(entry->addr, ®0, ®1); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC1, 0, (a_uint8_t *) (®1), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC0, 0, (a_uint8_t *) (®0), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = shiva_fdb_commit(dev_id, ARL_PURGE_ENTRY); + return rv; +} + +static sw_error_t +_shiva_fdb_first(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + rv = shiva_atu_get(dev_id, entry, ARL_FIRST_ENTRY); + return rv; +} + +static sw_error_t +_shiva_fdb_find(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + rv = shiva_atu_get(dev_id, entry, ARL_FIND_ENTRY); + return rv; +} + +static sw_error_t +_shiva_fdb_port_learn_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, LEARN_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_fdb_port_learn_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, LEARN_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_shiva_fdb_age_ctrl_set(a_uint32_t dev_id, a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, ADDR_TABLE_CTL, 0, AGE_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_fdb_age_ctrl_get(a_uint32_t dev_id, a_bool_t *enable) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_CTL, 0, AGE_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_shiva_fdb_age_time_set(a_uint32_t dev_id, a_uint32_t * time) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if ((65535 * 7 < *time) || (7 > *time)) + { + return SW_BAD_PARAM; + } + data = *time / 7; + *time = data * 7; + HSL_REG_FIELD_SET(rv, dev_id, ADDR_TABLE_CTL, 0, AGE_TIME, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_fdb_age_time_get(a_uint32_t dev_id, a_uint32_t *time) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_CTL, 0, AGE_TIME, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *time = data * 7; + return SW_OK; +} + +static void +_shiva_fdb_hw_to_sw(a_uint32_t tbl[3], fal_fdb_entry_t * entry) +{ + a_uint32_t i, data; + + aos_mem_zero(entry, sizeof (fal_fdb_entry_t)); + + entry->dacmd = FAL_MAC_FRWRD; + SW_GET_FIELD_BY_REG(FDB_TABLE_FUNC2, FDB_CPYCPU_EN, data, tbl[2]); + if (1 == data) + { + entry->dacmd = FAL_MAC_CPY_TO_CPU; + } + + SW_GET_FIELD_BY_REG(FDB_TABLE_FUNC2, FDB_RDTCPU_EN, data, tbl[2]); + if (1 == data) + { + entry->dacmd = FAL_MAC_RDT_TO_CPU; + } + + entry->leaky_en = A_FALSE; + SW_GET_FIELD_BY_REG(FDB_TABLE_FUNC2, FDB_LEANKY_EN, data, tbl[2]); + if (1 == data) + { + entry->leaky_en = A_TRUE; + } + + entry->static_en = A_FALSE; + SW_GET_FIELD_BY_REG(FDB_TABLE_FUNC2, FDB_STATUS, data, tbl[2]); + if (0xf == data) + { + entry->static_en = A_TRUE; + } + + entry->clone_en = A_FALSE; + SW_GET_FIELD_BY_REG(FDB_TABLE_FUNC1, FDB_MACCLONE_EN, data, tbl[1]); + if (1 == data) + { + entry->clone_en = A_TRUE; + } + + entry->sacmd = FAL_MAC_FRWRD; + SW_GET_FIELD_BY_REG(FDB_TABLE_FUNC1, FDB_SADROP_EN, data, tbl[1]); + if (1 == data) + { + entry->sacmd = FAL_MAC_DROP; + } + + entry->mirror_en = A_FALSE; + SW_GET_FIELD_BY_REG(FDB_TABLE_FUNC1, FDB_MIRROR_EN, data, tbl[1]); + if (1 == data) + { + entry->mirror_en = A_TRUE; + } + + entry->da_pri_en = A_FALSE; + SW_GET_FIELD_BY_REG(FDB_TABLE_FUNC1, FDB_PRIORITY_EN, data, tbl[1]); + if (1 == data) + { + SW_GET_FIELD_BY_REG(FDB_TABLE_FUNC1, FDB_PRIORITY, data, tbl[1]); + entry->da_pri_en = A_TRUE; + entry->da_queue = data & 0x3; + } + + entry->cross_pt_state = A_FALSE; + SW_GET_FIELD_BY_REG(FDB_TABLE_FUNC1, FDB_CROSS_STATE, data, tbl[1]); + if (1 == data) + { + entry->cross_pt_state = A_TRUE; + } + + SW_GET_FIELD_BY_REG(FDB_TABLE_FUNC1, FDB_DES_PORT, data, tbl[1]); + entry->portmap_en = A_TRUE; + entry->port.map = data; + + for (i = 2; i < 6; i++) + { + entry->addr.uc[i] = (tbl[0] >> ((5 - i) << 3)) & 0xff; + } + + for (i = 0; i < 2; i++) + { + entry->addr.uc[i] = (tbl[1] >> ((1 - i) << 3)) & 0xff; + } +} + +#define SHIVA_FDB_ENTRY_NUM 1024 +#define SHIVA_FDB_ENTRY_ADDR0 0x30000 +#define SHIVA_FDB_ENTRY_ADDR1 0x30004 +#define SHIVA_FDB_ENTRY_ADDR2 0x30008 + +static sw_error_t +_shiva_fdb_iterate(a_uint32_t dev_id, a_uint32_t * iterator, fal_fdb_entry_t * entry) +{ + a_uint32_t index, addr, data, tbl[3] = { 0 }; + sw_error_t rv; + + if ((NULL == iterator) || (NULL == entry)) + { + return SW_BAD_PTR; + } + + if (SHIVA_FDB_ENTRY_NUM == *iterator) + { + return SW_NO_MORE; + } + + if (SHIVA_FDB_ENTRY_NUM < *iterator) + { + return SW_BAD_PARAM; + } + + for (index = *iterator; index < SHIVA_FDB_ENTRY_NUM; index++) + { + addr = SHIVA_FDB_ENTRY_ADDR2 + (index << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[2])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(FDB_TABLE_FUNC2, FDB_STATUS, data, tbl[2]); + if (data) + { + addr = SHIVA_FDB_ENTRY_ADDR0 + (index << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[0])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + addr = SHIVA_FDB_ENTRY_ADDR1 + (index << 4); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(tbl[1])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + _shiva_fdb_hw_to_sw(tbl, entry); + break; + } + } + + if (SHIVA_FDB_ENTRY_NUM == index) + { + return SW_NO_MORE; + } + + *iterator = index + 1; + return SW_OK; +} + +/** + * @brief Add a Fdb entry + * @param[in] dev_id device id + * @param[in] entry fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_fdb_add(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_fdb_add(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete all Fdb entries + * @details Comments: + * If set FAL_FDB_DEL_STATIC bit in flag which means delete all fdb + * entries otherwise only delete dynamic entries. + * @param[in] dev_id device id + * @param[in] flag delete operation option + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_fdb_del_all(a_uint32_t dev_id, a_uint32_t flag) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_fdb_del_all(dev_id, flag); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete Fdb entries on a particular port + * @details Comments: + * If set FAL_FDB_DEL_STATIC bit in flag which means delete all fdb + * entries otherwise only delete dynamic entries. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] flag delete operation option + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_fdb_del_by_port(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t flag) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_fdb_del_by_port(dev_id, port_id, flag); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a particular Fdb entry through mac address + * @details Comments: + * Only addr field in entry is meaning. For IVL learning vid or fid field + * also is meaning. + * @param[in] dev_id device id + * @param[in] entry fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_fdb_del_by_mac(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_fdb_del_by_mac(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get first Fdb entry from particular device + * @param[in] dev_id device id + * @param[out] entry fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_fdb_first(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_fdb_first(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Find a particular Fdb entry from device through mac address. + * @details Comments: + For input parameter only addr field in entry is meaning. + * @param[in] dev_id device id + * @param[in] entry fdb entry + * @param[out] entry fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_fdb_find(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_fdb_find(dev_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dynamic address learning status on a particular port. + * @details Comments: + * This operation will enable or disable dynamic address learning + * feature on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable enable or disable + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_fdb_port_learn_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_fdb_port_learn_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dynamic address learning status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_fdb_port_learn_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_fdb_port_learn_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dynamic address aging status on particular device. + * @details Comments: + * This operation will enable or disable dynamic address aging + * feature on particular device. + * @param[in] dev_id device id + * @param[in] enable enable or disable + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_fdb_age_ctrl_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_fdb_age_ctrl_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dynamic address aging status on particular device. + * @param[in] dev_id device id + * @param[in] enable enable or disable + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_fdb_age_ctrl_get(a_uint32_t dev_id, a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_fdb_age_ctrl_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dynamic address aging time on a particular device. + * @details Comments: + * This operation will set dynamic address aging time on a particular device. + * The unit of time is second. Because different device has differnet + * hardware granularity function will return actual time in hardware. + * @param[in] dev_id device id + * @param time aging time + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_fdb_age_time_set(a_uint32_t dev_id, a_uint32_t * time) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_fdb_age_time_set(dev_id, time); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dynamic address aging time on a particular device. + * @param[in] dev_id device id + * @param[out] time aging time + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_fdb_age_time_get(a_uint32_t dev_id, a_uint32_t *time) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_fdb_age_time_get(dev_id, time); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Iterate all fdb entries on a particular device. + * @param[in] dev_id device id + * @param[in] iterator fdb entry index if it's zero means get the first entry + * @param[out] iterator next valid fdb entry index + * @param[out] entry fdb entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_fdb_iterate(a_uint32_t dev_id, a_uint32_t * iterator, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_fdb_iterate(dev_id, iterator, entry); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +shiva_fdb_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->fdb_add = shiva_fdb_add; + p_api->fdb_del_all = shiva_fdb_del_all; + p_api->fdb_del_by_port = shiva_fdb_del_by_port; + p_api->fdb_del_by_mac = shiva_fdb_del_by_mac; + p_api->fdb_first = shiva_fdb_first; + p_api->fdb_find = shiva_fdb_find; + p_api->port_learn_set = shiva_fdb_port_learn_set; + p_api->port_learn_get = shiva_fdb_port_learn_get; + p_api->age_ctrl_set = shiva_fdb_age_ctrl_set; + p_api->age_ctrl_get = shiva_fdb_age_ctrl_get; + p_api->age_time_set = shiva_fdb_age_time_set; + p_api->age_time_get = shiva_fdb_age_time_get; + p_api->fdb_iterate = shiva_fdb_iterate; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_igmp.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_igmp.c new file mode 100755 index 000000000..2427d7884 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_igmp.c @@ -0,0 +1,980 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup shiva_igmp SHIVA_IGMP + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "shiva_igmp.h" +#include "shiva_reg.h" + +static sw_error_t +_shiva_port_igmps_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, IGMP_MLD_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_port_igmps_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, IGMP_MLD_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_shiva_igmp_mld_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_MAC_CPY_TO_CPU == cmd) + { + val = 1; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + val = 0; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, QM_CTL, 0, IGMP_COPY_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_igmp_mld_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, QM_CTL, 0, IGMP_COPY_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *cmd = FAL_MAC_CPY_TO_CPU; + } + else + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + + return SW_OK; +} + +static sw_error_t +_shiva_port_igmp_mld_join_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, JOIN_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_port_igmp_mld_join_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, JOIN_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_shiva_port_igmp_mld_leave_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, LEAVE_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_port_igmp_mld_leave_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, LEAVE_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_shiva_igmp_mld_rp_set(a_uint32_t dev_id, fal_pbmp_t pts) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_mports_validity_check(dev_id, pts)) + { + return SW_BAD_PARAM; + } + val = pts; + HSL_REG_FIELD_SET(rv, dev_id, FLOOD_MASK, 0, IGMP_DP, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_igmp_mld_rp_get(a_uint32_t dev_id, fal_pbmp_t * pts) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FLOOD_MASK, 0, IGMP_DP, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *pts = val; + return SW_OK; +} + +static sw_error_t +_shiva_igmp_mld_entry_creat_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, QM_CTL, 0, IGMP_CREAT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_igmp_mld_entry_creat_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, QM_CTL, 0, IGMP_CREAT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_shiva_igmp_mld_entry_static_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 0xf; + } + else if (A_FALSE == enable) + { + val = 0xe; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, QM_CTL, 0, IGMP_JOIN_STATIC, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_igmp_mld_entry_static_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, QM_CTL, 0, IGMP_JOIN_STATIC, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0xf == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_shiva_igmp_mld_entry_leaky_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, QM_CTL, 0, IGMP_JOIN_LEAKY, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_igmp_mld_entry_leaky_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, QM_CTL, 0, IGMP_JOIN_LEAKY, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_shiva_igmp_mld_entry_v3_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, QM_CTL, 0, IGMP_V3_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_igmp_mld_entry_v3_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, QM_CTL, 0, IGMP_V3_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_shiva_igmp_mld_entry_queue_set(a_uint32_t dev_id, a_bool_t enable, a_uint32_t queue) +{ + sw_error_t rv; + a_uint32_t entry = 0; + hsl_dev_t *p_dev; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_ENTRY_GET(rv, dev_id, QM_CTL, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + SW_SET_REG_BY_FIELD(QM_CTL, IGMP_PRI_EN, 1, entry); + SW_RTN_ON_NULL(p_dev = hsl_dev_ptr_get(dev_id)); + if (queue >= p_dev->nr_queue) + { + return SW_BAD_PARAM; + } + SW_SET_REG_BY_FIELD(QM_CTL, IGMP_PRI, queue, entry); + } + else if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(QM_CTL, IGMP_PRI_EN, 0, entry); + SW_SET_REG_BY_FIELD(QM_CTL, IGMP_PRI, 0, entry); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_SET(rv, dev_id, QM_CTL, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_igmp_mld_entry_queue_get(a_uint32_t dev_id, a_bool_t * enable, a_uint32_t * queue) +{ + sw_error_t rv; + a_uint32_t entry = 0, data; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_ENTRY_GET(rv, dev_id, QM_CTL, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(QM_CTL, IGMP_PRI_EN, data, entry); + if (data) + { + *enable = A_TRUE; + SW_GET_FIELD_BY_REG(QM_CTL, IGMP_PRI, data, entry); + *queue = data; + } + else + { + *enable = A_FALSE; + *queue = 0; + } + + return SW_OK; +} + +/** + * @brief Set igmp/mld packets snooping status on a particular port. + * @details Comments: + * After enabling igmp/mld snooping feature on a particular port all kinds + * igmp/mld packets received on this port would be acknowledged by hardware. + * Particular forwarding decision could be setted by fal_igmp_mld_cmd_set. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_igmps_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_igmps_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld packets snooping status on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_igmps_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_igmps_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmp/mld packets forwarding command on a particular device. + * @details Comments: + * Particular device may only support parts of forwarding commands. + * This operation will take effect only after enabling igmp/mld snooping + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_igmp_mld_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_igmp_mld_cmd_set(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld packets forwarding command on a particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_igmp_mld_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_igmp_mld_cmd_get(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmp/mld join packets hardware acknowledgement status on particular port. + * @details Comments: + * After enabling igmp/mld join feature on a particular port hardware will + * dynamic learning or changing multicast entry. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_igmp_mld_join_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_igmp_mld_join_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld join packets hardware acknowledgement status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_igmp_mld_join_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_igmp_mld_join_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmp/mld leave packets hardware acknowledgement status on a particular port. + * @details Comments: + * After enabling igmp leave feature on a particular port hardware will dynamic + * deleting or changing multicast entry. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_igmp_mld_leave_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_igmp_mld_leave_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld leave packets hardware acknowledgement status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_igmp_mld_leave_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_igmp_mld_leave_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmp/mld router ports on a particular device. + * @details Comments: + * After enabling igmp/mld join/leave feature on a particular port igmp/mld + * join/leave packets received on this port will be forwarded to router ports. + * @param[in] dev_id device id + * @param[in] pts dedicates ports + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_igmp_mld_rp_set(a_uint32_t dev_id, fal_pbmp_t pts) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_igmp_mld_rp_set(dev_id, pts); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmp/mld router ports on a particular device. + * @param[in] dev_id device id + * @param[out] pts dedicates ports + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_igmp_mld_rp_get(a_uint32_t dev_id, fal_pbmp_t * pts) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_igmp_mld_rp_get(dev_id, pts); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set the status of creating multicast entry during igmp/mld join/leave procedure. + * @details Comments: + * After enabling igmp/mld join/leave feature on a particular port if enable + * entry creat hardware will dynamic creat and delete multicast entry, + * otherwise hardware only can change destination ports of existing muticast entry. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_igmp_mld_entry_creat_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_igmp_mld_entry_creat_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get the status of creating multicast entry during igmp/mld join/leave procedure. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_igmp_mld_entry_creat_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_igmp_mld_entry_creat_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set the static status of multicast entry which learned by hardware. + * @details Comments: + * After enabling igmp/mld join/leave feature on a particular port if enable + * static status hardware will not age out multicast entry which leardned by hardware, + * otherwise hardware will age out multicast entry which leardned by hardware. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_igmp_mld_entry_static_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_igmp_mld_entry_static_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get the static status of multicast entry which learned by hardware. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_igmp_mld_entry_static_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_igmp_mld_entry_static_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set the leaky status of multicast entry which learned by hardware. + * @details Comments: + * After enabling igmp/mld join/leave feature on a particular port if enable + * leaky status hardware will set leaky flag of multicast entry which leardned by hardware, + * otherwise hardware will not set leaky flag of multicast entry which leardned by hardware. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_igmp_mld_entry_leaky_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_igmp_mld_entry_leaky_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get the leaky status of multicast entry which learned by hardware. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_igmp_mld_entry_leaky_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_igmp_mld_entry_leaky_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set igmpv3/mldv2 packets hardware acknowledgement status on a particular device. + * @details Comments: + * After enabling igmp join/leave feature on a particular port hardware will dynamic + * creating or changing multicast entry after receiving igmpv3/mldv2 packets. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_igmp_mld_entry_v3_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_igmp_mld_entry_v3_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get igmpv3/mldv2 packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_igmp_mld_entry_v3_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_igmp_mld_entry_v3_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set the queue status of multicast entry which learned by hardware. + * @details Comments: + * After enabling igmp/mld join/leave feature on a particular port if enable + * leaky status hardware will set queue flag of multicast entry which leardned by hardware, + * otherwise hardware will not set queue flag of multicast entry which leardned by hardware. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @param[in] queue queue id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_igmp_mld_entry_queue_set(a_uint32_t dev_id, a_bool_t enable, a_uint32_t queue) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_igmp_mld_entry_queue_set(dev_id, enable, queue); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get the queue status of multicast entry which learned by hardware. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @param[out] queue queue id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_igmp_mld_entry_queue_get(a_uint32_t dev_id, a_bool_t * enable, a_uint32_t * queue) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_igmp_mld_entry_queue_get(dev_id, enable, queue); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +shiva_igmp_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->port_igmps_status_set = shiva_port_igmps_status_set; + p_api->port_igmps_status_get = shiva_port_igmps_status_get; + p_api->igmp_mld_cmd_set = shiva_igmp_mld_cmd_set; + p_api->igmp_mld_cmd_get = shiva_igmp_mld_cmd_get; + p_api->port_igmp_join_set = shiva_port_igmp_mld_join_set; + p_api->port_igmp_join_get = shiva_port_igmp_mld_join_get; + p_api->port_igmp_leave_set = shiva_port_igmp_mld_leave_set; + p_api->port_igmp_leave_get = shiva_port_igmp_mld_leave_get; + p_api->igmp_rp_set = shiva_igmp_mld_rp_set; + p_api->igmp_rp_get = shiva_igmp_mld_rp_get; + p_api->igmp_entry_creat_set = shiva_igmp_mld_entry_creat_set; + p_api->igmp_entry_creat_get = shiva_igmp_mld_entry_creat_get; + p_api->igmp_entry_static_set = shiva_igmp_mld_entry_static_set; + p_api->igmp_entry_static_get = shiva_igmp_mld_entry_static_get; + p_api->igmp_entry_leaky_set = shiva_igmp_mld_entry_leaky_set; + p_api->igmp_entry_leaky_get = shiva_igmp_mld_entry_leaky_get; + p_api->igmp_entry_v3_set = shiva_igmp_mld_entry_v3_set; + p_api->igmp_entry_v3_get = shiva_igmp_mld_entry_v3_get; + p_api->igmp_entry_queue_set = shiva_igmp_mld_entry_queue_set; + p_api->igmp_entry_queue_get = shiva_igmp_mld_entry_queue_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_init.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_init.c new file mode 100755 index 000000000..1fea80f94 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_init.c @@ -0,0 +1,448 @@ +/* + * Copyright (c) 2012, 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 shiva_init SHIVA_INIT + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "shiva_mib.h" +#include "shiva_port_ctrl.h" +#include "shiva_portvlan.h" +#include "shiva_vlan.h" +#include "shiva_fdb.h" +#include "shiva_qos.h" +#include "shiva_mirror.h" +#include "shiva_stp.h" +#include "shiva_rate.h" +#include "shiva_misc.h" +#include "shiva_leaky.h" +#include "shiva_igmp.h" +#include "shiva_acl.h" +#include "shiva_led.h" +#include "shiva_reg_access.h" +#include "shiva_reg.h" +#include "shiva_init.h" +#include "f1_phy.h" + +static ssdk_init_cfg * shiva_cfg[SW_MAX_NR_DEV] = { 0 }; + +#if !(defined(KERNEL_MODULE) && defined(USER_MODE)) +/* For SHIVA there are five internal PHY devices and seven MAC devices. + MAC0 always connect to external MAC device. + PHY4 can connect to MAC5 or external MAC device. + MAC6 always connect to external devices. + MAC1..MAC4 connect to internal PHY0..PHY3. +*/ +static sw_error_t +shiva_portproperty_init(a_uint32_t dev_id, hsl_init_mode mode) +{ + hsl_port_prop_t p_type; + hsl_dev_t *pdev = NULL; + fal_port_t port_id; + + pdev = hsl_dev_ptr_get(dev_id); + if (pdev == NULL) + return SW_NOT_INITIALIZED; + + for (port_id = 0; port_id < pdev->nr_ports; port_id++) + { + hsl_port_prop_portmap_set(dev_id, port_id); + + for (p_type = HSL_PP_PHY; p_type < HSL_PP_BUTT; p_type++) + { + if (HSL_NO_CPU == mode) + { + SW_RTN_ON_ERROR(hsl_port_prop_set(dev_id, port_id, p_type)); + continue; + } + + switch (p_type) + { + case HSL_PP_PHY: + if (HSL_CPU_1 != mode) + { + if ((port_id != pdev->cpu_port_nr) + && (port_id != (pdev->nr_ports -1)) + && (port_id != (pdev->nr_ports -2))) + { + SW_RTN_ON_ERROR(hsl_port_prop_set(dev_id, port_id, p_type)); + } + } + else + { + if ((port_id != pdev->cpu_port_nr) + && (port_id != pdev->nr_ports - 1)) + { + SW_RTN_ON_ERROR(hsl_port_prop_set(dev_id, port_id, p_type)); + } + } + break; + + case HSL_PP_INCL_CPU: + /* include cpu port but exclude wan port in some cases */ + if (!((HSL_CPU_2 == mode) && (port_id == (pdev->nr_ports - 2)))) + SW_RTN_ON_ERROR(hsl_port_prop_set(dev_id, port_id, p_type)); + + break; + + case HSL_PP_EXCL_CPU: + /* exclude cpu port and wan port in some cases */ + if ((port_id != pdev->cpu_port_nr) + && (!((HSL_CPU_2 == mode) && (port_id == (pdev->nr_ports - 2))))) + SW_RTN_ON_ERROR(hsl_port_prop_set(dev_id, port_id, p_type)); + break; + + default: + break; + } + } + + if (HSL_NO_CPU == mode) + { + SW_RTN_ON_ERROR(hsl_port_prop_set_phyid + (dev_id, port_id, port_id + 1)); + } + else + { + if (port_id != pdev->cpu_port_nr) + { + SW_RTN_ON_ERROR(hsl_port_prop_set_phyid + (dev_id, port_id, port_id - 1)); + } + } + } + + return SW_OK; +} + +static sw_error_t +shiva_hw_init(a_uint32_t dev_id, ssdk_init_cfg *cfg) +{ + hsl_dev_t *pdev = NULL; + a_uint32_t port_id; + a_uint32_t data = 0; + sw_error_t rv; + + pdev = hsl_dev_ptr_get(dev_id); + if (NULL == pdev) + { + return SW_NOT_INITIALIZED; + } + + for (port_id = 0; port_id < pdev->nr_ports; port_id++) + { + if (port_id == pdev->cpu_port_nr) + { + continue; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 1, data); + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +#if 0 +static sw_error_t +shiva_bist_test(a_uint32_t dev_id) +{ + a_uint32_t entry = 0, data, i; + sw_error_t rv; + + data = 1; + i = 0x1000; + while (data && --i) + { + HSL_REG_ENTRY_GET(rv, dev_id, BIST_CTRL, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + SW_GET_FIELD_BY_REG(BIST_CTRL, BIST_BUSY, data, entry); + aos_udelay(5); + } + + if (0 == i) + { + return SW_INIT_ERROR; + } + + entry = 0; + SW_SET_REG_BY_FIELD(BIST_CTRL, BIST_BUSY, 1, entry); + SW_SET_REG_BY_FIELD(BIST_CTRL, PTN_EN2, 1, entry); + SW_SET_REG_BY_FIELD(BIST_CTRL, PTN_EN1, 1, entry); + SW_SET_REG_BY_FIELD(BIST_CTRL, PTN_EN0, 1, entry); + + HSL_REG_ENTRY_SET(rv, dev_id, BIST_CTRL, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data = 1; + i = 0x1000; + while (data && --i) + { + HSL_REG_ENTRY_GET(rv, dev_id, BIST_CTRL, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + SW_GET_FIELD_BY_REG(BIST_CTRL, BIST_BUSY, data, entry); + aos_udelay(5); + } + + if (0 == i) + { + return SW_INIT_ERROR; + } + + SW_GET_FIELD_BY_REG(BIST_CTRL, ERR_CNT, data, entry); + if (data) + { + SW_GET_FIELD_BY_REG(BIST_CTRL, ONE_ERR, data, entry); + if (!data) + { + return SW_INIT_ERROR; + } + + SW_GET_FIELD_BY_REG(BIST_CTRL, ERR_ADDR, data, entry); + + entry = 0; + SW_SET_REG_BY_FIELD(BIST_RCV, RCV_EN, 1, entry); + SW_SET_REG_BY_FIELD(BIST_RCV, RCV_ADDR, data, entry); + HSL_REG_ENTRY_SET(rv, dev_id, BIST_RCV, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + else + { + return SW_OK; + } + + entry = 0; + SW_SET_REG_BY_FIELD(BIST_CTRL, BIST_BUSY, 1, entry); + SW_SET_REG_BY_FIELD(BIST_CTRL, PTN_EN2, 1, entry); + SW_SET_REG_BY_FIELD(BIST_CTRL, PTN_EN1, 1, entry); + SW_SET_REG_BY_FIELD(BIST_CTRL, PTN_EN0, 1, entry); + + HSL_REG_ENTRY_SET(rv, dev_id, BIST_CTRL, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + data = 1; + i = 0x1000; + while (data && --i) + { + HSL_REG_ENTRY_GET(rv, dev_id, BIST_CTRL, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + SW_GET_FIELD_BY_REG(BIST_CTRL, BIST_BUSY, data, entry); + aos_udelay(5); + } + + if (0 == i) + { + return SW_INIT_ERROR; + } + + SW_GET_FIELD_BY_REG(BIST_CTRL, ERR_CNT, data, entry); + if (data) + { + return SW_INIT_ERROR; + } + + return SW_OK; +} +#endif +#endif + +static sw_error_t +shiva_dev_init(a_uint32_t dev_id, hsl_init_mode cpu_mode) +{ + hsl_dev_t *pdev = NULL; + + pdev = hsl_dev_ptr_get(dev_id); + if (pdev == NULL) + return SW_NOT_INITIALIZED; + + pdev->nr_ports = 7; + pdev->nr_phy = 5; + pdev->cpu_port_nr = 0; + pdev->nr_vlans = 4096; + pdev->hw_vlan_query = A_TRUE; + pdev->nr_queue = 4; + pdev->cpu_mode = cpu_mode; + + return SW_OK; +} + + +static sw_error_t +_shiva_reset(a_uint32_t dev_id) +{ +#if !(defined(KERNEL_MODULE) && defined(USER_MODE)) + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + val = 0x1; + HSL_REG_FIELD_SET(rv, dev_id, MASK_CTL, 0, SOFT_RST, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = shiva_hw_init(dev_id, shiva_cfg[dev_id]); + SW_RTN_ON_ERROR(rv); + + SHIVA_ACL_RESET(rv, dev_id); +#endif + + return SW_OK; +} + +sw_error_t +shiva_cleanup(a_uint32_t dev_id) +{ + if (shiva_cfg[dev_id]) + { + aos_mem_free(shiva_cfg[dev_id]); + shiva_cfg[dev_id] = NULL; + } + + return SW_OK; +} + +/** + * @brief reset hsl layer. + * @details Comments: + * This operation will reset hsl layer + * @param[in] dev_id device id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_reset(a_uint32_t dev_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_reset(dev_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Init hsl layer. + * @details Comments: + * This operation will init hsl layer and hsl layer + * @param[in] dev_id device id + * @param[in] cfg configuration for initialization + * @return SW_OK or error code + */ +sw_error_t +shiva_init(a_uint32_t dev_id, ssdk_init_cfg *cfg) +{ + sw_error_t rv; + HSL_DEV_ID_CHECK(dev_id); + + if (NULL == shiva_cfg[dev_id]) + { + shiva_cfg[dev_id] = aos_mem_alloc(sizeof (ssdk_init_cfg)); + } + + if (NULL == shiva_cfg[dev_id]) + { + return SW_OUT_OF_MEM; + } + + aos_mem_copy(shiva_cfg[dev_id], cfg, sizeof (ssdk_init_cfg)); + + SW_RTN_ON_ERROR(shiva_reg_access_init(dev_id, cfg->reg_mode)); + + SW_RTN_ON_ERROR(shiva_dev_init(dev_id, cfg->cpu_mode)); + +#if !(defined(KERNEL_MODULE) && defined(USER_MODE)) + { +/* + if(HSL_MDIO == cfg->reg_mode) + { + SW_RTN_ON_ERROR(shiva_bist_test(dev_id)); + + entry = 0x1; + HSL_REG_FIELD_SET(rv, dev_id, MASK_CTL, 0, SOFT_RST, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + i = 0x10; + do + { + HSL_REG_FIELD_GET(rv, dev_id, MASK_CTL, 0, SOFT_RST, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + aos_mdelay(10); + } + while (entry && --i); + + if (0 == i) + { + return SW_INIT_ERROR; + } + } +*/ + SW_RTN_ON_ERROR(hsl_port_prop_init(dev_id)); + SW_RTN_ON_ERROR(hsl_port_prop_init_by_dev(dev_id)); + SW_RTN_ON_ERROR(shiva_portproperty_init(dev_id, cfg->cpu_mode)); + + SHIVA_MIB_INIT(rv, dev_id); + SHIVA_PORT_CTRL_INIT(rv, dev_id); + SHIVA_PORTVLAN_INIT(rv, dev_id); + SHIVA_VLAN_INIT(rv, dev_id); + SHIVA_FDB_INIT(rv, dev_id); + SHIVA_QOS_INIT(rv, dev_id); + SHIVA_STP_INIT(rv, dev_id); + SHIVA_MIRR_INIT(rv, dev_id); + SHIVA_RATE_INIT(rv, dev_id); + SHIVA_MISC_INIT(rv, dev_id); + SHIVA_LEAKY_INIT(rv, dev_id); + SHIVA_IGMP_INIT(rv, dev_id); + SHIVA_ACL_INIT(rv, dev_id); + SHIVA_LED_INIT(rv, dev_id); + + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->dev_reset = shiva_reset; + p_api->dev_clean = shiva_cleanup; + } + + /*SW_RTN_ON_ERROR(shiva_hw_init(dev_id, cfg));*/ + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_leaky.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_leaky.c new file mode 100755 index 000000000..c68e66fb5 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_leaky.c @@ -0,0 +1,526 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup shiva_leaky SHIVA_LEAKY + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "shiva_leaky.h" +#include "shiva_reg.h" + +static sw_error_t +_shiva_uc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_LEAKY_PORT_CTRL == ctrl_mode) + { + data = 0; + } + else if (FAL_LEAKY_FDB_CTRL == ctrl_mode) + { + data = 1; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FLOOD_MASK, 0, ARL_UNI_LEAKY, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_uc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t *ctrl_mode) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FLOOD_MASK, 0, ARL_UNI_LEAKY, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *ctrl_mode = FAL_LEAKY_FDB_CTRL; + } + else + { + *ctrl_mode = FAL_LEAKY_PORT_CTRL; + } + + return SW_OK; +} + +static sw_error_t +_shiva_mc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_LEAKY_PORT_CTRL == ctrl_mode) + { + data = 0; + } + else if (FAL_LEAKY_FDB_CTRL == ctrl_mode) + { + data = 1; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FLOOD_MASK, 0, ARL_MUL_LEAKY, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_mc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t *ctrl_mode) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, FLOOD_MASK, 0, ARL_MUL_LEAKY, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *ctrl_mode = FAL_LEAKY_FDB_CTRL; + } + else + { + *ctrl_mode = FAL_LEAKY_PORT_CTRL; + } + + return SW_OK; +} + +static sw_error_t +_shiva_port_arp_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, ARP_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_port_arp_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, ARP_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_shiva_port_uc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_BASE_VLAN, port_id, UNI_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_port_uc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_BASE_VLAN, port_id, UNI_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_shiva_port_mc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_BASE_VLAN, port_id, MUL_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_port_mc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_BASE_VLAN, port_id, MUL_LEAKY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +/** +* @brief Set unicast packets leaky control mode on a particular device. +* @param[in] dev_id device id +* @param[in] ctrl_mode leaky control mode +* @return SW_OK or error code +*/ +HSL_LOCAL sw_error_t +shiva_uc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_uc_leaky_mode_set(dev_id, ctrl_mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get unicast packets leaky control mode on a particular device. + * @param[in] dev_id device id + * @param[out] ctrl_mode leaky control mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_uc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t *ctrl_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_uc_leaky_mode_get(dev_id, ctrl_mode); + HSL_API_UNLOCK; + return rv; +} + +/** +* @brief Set multicast packets leaky control mode on a particular device. +* @param[in] dev_id device id +* @param[in] ctrl_mode leaky control mode +* @return SW_OK or error code +*/ +HSL_LOCAL sw_error_t +shiva_mc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_mc_leaky_mode_set(dev_id, ctrl_mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get multicast packets leaky control mode on a particular device. + * @param[in] dev_id device id + * @param[out] ctrl_mode leaky control mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_mc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t *ctrl_mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_mc_leaky_mode_get(dev_id, ctrl_mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set arp packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_arp_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_arp_leaky_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_arp_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_arp_leaky_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set unicast packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_uc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_uc_leaky_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get unicast packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_uc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_uc_leaky_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set multicast packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_mc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_mc_leaky_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get multicast packets leaky status on a particular port. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_mc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_mc_leaky_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +shiva_leaky_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->uc_leaky_mode_set = shiva_uc_leaky_mode_set; + p_api->uc_leaky_mode_get = shiva_uc_leaky_mode_get; + p_api->mc_leaky_mode_set = shiva_mc_leaky_mode_set; + p_api->mc_leaky_mode_get = shiva_mc_leaky_mode_get; + p_api->port_arp_leaky_set = shiva_port_arp_leaky_set; + p_api->port_arp_leaky_get = shiva_port_arp_leaky_get; + p_api->port_uc_leaky_set = shiva_port_uc_leaky_set; + p_api->port_uc_leaky_get = shiva_port_uc_leaky_get; + p_api->port_mc_leaky_set = shiva_port_mc_leaky_set; + p_api->port_mc_leaky_get = shiva_port_mc_leaky_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_led.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_led.c new file mode 100755 index 000000000..06bcd3180 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_led.c @@ -0,0 +1,428 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup shiva_led SHIVA_LED + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "shiva_led.h" +#include "shiva_reg.h" + +#define MAX_LED_PATTERN_ID 1 +#define LED_PATTERN_ADDR 0xB0 + +static sw_error_t +_shiva_led_ctrl_pattern_set(a_uint32_t dev_id, led_pattern_group_t group, + led_pattern_id_t id, led_ctrl_pattern_t * pattern) +{ + a_uint32_t data = 0, reg = 0, mode; + a_uint32_t addr; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (group >= LED_GROUP_BUTT) + { + return SW_BAD_PARAM; + } + + if (id > MAX_LED_PATTERN_ID) + { + return SW_BAD_PARAM; + } + + if ((LED_MAC_PORT_GROUP == group) && (0 != id)) + { + return SW_BAD_PARAM; + } + + if (LED_MAC_PORT_GROUP == group) + { + addr = LED_PATTERN_ADDR + 8; + } + else + { + addr = LED_PATTERN_ADDR + (id << 2); + } + + if (LED_ALWAYS_OFF == pattern->mode) + { + mode = 0; + } + else if (LED_ALWAYS_BLINK == pattern->mode) + { + mode = 1; + } + else if (LED_ALWAYS_ON == pattern->mode) + { + mode = 2; + } + else if (LED_PATTERN_MAP_EN == pattern->mode) + { + mode = 3; + } + else + { + return SW_BAD_PARAM; + } + SW_SET_REG_BY_FIELD(LED_CTRL, PATTERN_EN, mode, data); + + if (pattern->map & (1 << FULL_DUPLEX_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, FULL_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << HALF_DUPLEX_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, HALF_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << POWER_ON_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, POWERON_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << LINK_1000M_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, GE_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << LINK_100M_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, FE_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << LINK_10M_LIGHT_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, ETH_LIGHT_EN, 1, data); + } + + if (pattern->map & (1 << COLLISION_BLINK_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, COL_BLINK_EN, 1, data); + } + + if (pattern->map & (1 << RX_TRAFFIC_BLINK_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, RX_BLINK_EN, 1, data); + } + + if (pattern->map & (1 << TX_TRAFFIC_BLINK_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, TX_BLINK_EN, 1, data); + } + + if (pattern->map & (1 << LINKUP_OVERRIDE_EN)) + { + SW_SET_REG_BY_FIELD(LED_CTRL, LINKUP_OVER_EN, 1, data); + } + else + { + SW_SET_REG_BY_FIELD(LED_CTRL, LINKUP_OVER_EN, 0, data); + } + + if (LED_BLINK_2HZ == pattern->freq) + { + SW_SET_REG_BY_FIELD(LED_CTRL, BLINK_FREQ, 0, data); + } + else if (LED_BLINK_4HZ == pattern->freq) + { + SW_SET_REG_BY_FIELD(LED_CTRL, BLINK_FREQ, 1, data); + } + else if (LED_BLINK_8HZ == pattern->freq) + { + SW_SET_REG_BY_FIELD(LED_CTRL, BLINK_FREQ, 2, data); + } + else if (LED_BLINK_TXRX == pattern->freq) + { + SW_SET_REG_BY_FIELD(LED_CTRL, BLINK_FREQ, 3, data); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (LED_WAN_PORT_GROUP == group) + { + reg &= 0xffff; + reg |= (data << 16); + } + else + { + reg &= 0xffff0000; + reg |= data; + } + + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (LED_WAN_PORT_GROUP == group) + { + return SW_OK; + } + + HSL_REG_ENTRY_GET(rv, dev_id, LED_PATTERN, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (LED_LAN_PORT_GROUP == group) + { + if (id) + { + SW_SET_REG_BY_FIELD(LED_PATTERN, P3L1_MODE, mode, data); + SW_SET_REG_BY_FIELD(LED_PATTERN, P2L1_MODE, mode, data); + SW_SET_REG_BY_FIELD(LED_PATTERN, P1L1_MODE, mode, data); + } + else + { + SW_SET_REG_BY_FIELD(LED_PATTERN, P3L0_MODE, mode, data); + SW_SET_REG_BY_FIELD(LED_PATTERN, P2L0_MODE, mode, data); + SW_SET_REG_BY_FIELD(LED_PATTERN, P1L0_MODE, mode, data); + } + } + else + { + SW_SET_REG_BY_FIELD(LED_PATTERN, M6_MODE, mode, data); + SW_SET_REG_BY_FIELD(LED_PATTERN, M5_MODE, mode, data); + } + + HSL_REG_ENTRY_SET(rv, dev_id, LED_PATTERN, 0, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +static sw_error_t +_shiva_led_ctrl_pattern_get(a_uint32_t dev_id, led_pattern_group_t group, + led_pattern_id_t id, led_ctrl_pattern_t * pattern) +{ + a_uint32_t data = 0, reg = 0, tmp; + a_uint32_t addr; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (group >= LED_GROUP_BUTT) + { + return SW_BAD_PARAM; + } + + if (id > MAX_LED_PATTERN_ID) + { + return SW_BAD_PARAM; + } + + if ((LED_MAC_PORT_GROUP == group) && (0 != id)) + { + return SW_BAD_PARAM; + } + + aos_mem_zero(pattern, sizeof(led_ctrl_pattern_t)); + + if (LED_MAC_PORT_GROUP == group) + { + addr = LED_PATTERN_ADDR + 8; + } + else + { + addr = LED_PATTERN_ADDR + (id << 2); + } + + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (LED_WAN_PORT_GROUP == group) + { + data = (reg >> 16) & 0xffff; + } + else + { + data = reg & 0xffff; + } + + SW_GET_FIELD_BY_REG(LED_CTRL, PATTERN_EN, tmp, data); + if (0 == tmp) + { + pattern->mode = LED_ALWAYS_OFF; + } + else if (1 == tmp) + { + pattern->mode = LED_ALWAYS_BLINK; + } + else if (2 == tmp) + { + pattern->mode = LED_ALWAYS_ON; + } + else + { + pattern->mode = LED_PATTERN_MAP_EN; + } + + SW_GET_FIELD_BY_REG(LED_CTRL, FULL_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << FULL_DUPLEX_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, HALF_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << HALF_DUPLEX_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, POWERON_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << POWER_ON_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, GE_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << LINK_1000M_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, FE_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << LINK_100M_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, ETH_LIGHT_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << LINK_10M_LIGHT_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, COL_BLINK_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << COLLISION_BLINK_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, RX_BLINK_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << RX_TRAFFIC_BLINK_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, TX_BLINK_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << TX_TRAFFIC_BLINK_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, LINKUP_OVER_EN, tmp, data); + if (1 == tmp) + { + pattern->map |= (1 << LINKUP_OVERRIDE_EN); + } + + SW_GET_FIELD_BY_REG(LED_CTRL, BLINK_FREQ, tmp, data); + if (0 == tmp) + { + pattern->freq = LED_BLINK_2HZ; + } + else if (1 == tmp) + { + pattern->freq = LED_BLINK_4HZ; + } + else if (2 == tmp) + { + pattern->freq = LED_BLINK_8HZ; + } + else + { + pattern->freq = LED_BLINK_TXRX; + } + + return SW_OK; +} + +/** +* @brief Set led control pattern on a particular device. +* @param[in] dev_id device id +* @param[in] group pattern group, lan or wan +* @param[in] id pattern id +* @param[in] pattern led control pattern +* @return SW_OK or error code +*/ +HSL_LOCAL sw_error_t +shiva_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; + + HSL_API_LOCK; + rv = _shiva_led_ctrl_pattern_set(dev_id, group, id, pattern); + HSL_API_UNLOCK; + return rv; +} + +/** +* @brief Get led control pattern on a particular device. +* @param[in] dev_id device id +* @param[in] group pattern group, lan or wan +* @param[in] id pattern id +* @param[out] pattern led control pattern +* @return SW_OK or error code +*/ +HSL_LOCAL sw_error_t +shiva_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; + + HSL_API_LOCK; + rv = _shiva_led_ctrl_pattern_get(dev_id, group, id, pattern); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +shiva_led_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->led_ctrl_pattern_set = shiva_led_ctrl_pattern_set; + p_api->led_ctrl_pattern_get = shiva_led_ctrl_pattern_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_mib.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_mib.c new file mode 100755 index 000000000..0122e561d --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_mib.c @@ -0,0 +1,663 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup shiva_mib SHIVA_MIB + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "shiva_mib.h" +#include "shiva_reg.h" + +static sw_error_t +_shiva_get_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info) +{ + a_uint32_t val = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_OUT_OF_RANGE; + } + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBROAD, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxBroad = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXPAUSE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxPause = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXMULTI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxMulti = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXFCSERR, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxFcsErr = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXALLIGNERR, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxAllignErr = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXRUNT, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxRunt = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXFRAGMENT, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxFragment = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX64BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx64Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX128BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx128Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX256BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx256Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX512BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx512Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX1024BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx1024Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX1518BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx1518Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXMAXBYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxMaxByte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXTOOLONG, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxTooLong = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXGOODBYTE_LO, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxGoodByte_lo = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXGOODBYTE_HI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxGoodByte_hi = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBADBYTE_LO, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxBadByte_lo = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBADBYTE_HI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxBadByte_hi = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXOVERFLOW, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxOverFlow = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_FILTERED, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Filtered = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBROAD, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxBroad = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXPAUSE, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxPause = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMULTI, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxMulti = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXUNDERRUN, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxUnderRun = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX64BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx64Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX128BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx128Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX256BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx256Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX512BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx512Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX1024BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx1024Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX1518BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx1518Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMAXBYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxMaxByte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXOVERSIZE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxOverSize = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBYTE_LO, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxByte_lo = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBYTE_HI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxByte_hi = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXCOLLISION, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxCollision = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXABORTCOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxAbortCol = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMULTICOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxMultiCol = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXSINGALCOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxSingalCol = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXEXCDEFER, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxExcDefer = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXDEFER, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxDefer = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXLATECOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxLateCol = val; + + return SW_OK; +} + +static sw_error_t +_shiva_get_rx_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info) +{ + a_uint32_t val = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_OUT_OF_RANGE; + } + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBROAD, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxBroad = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXPAUSE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxPause = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXMULTI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxMulti = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXFCSERR, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxFcsErr = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXALLIGNERR, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxAllignErr = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXRUNT, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxRunt = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXFRAGMENT, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxFragment = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX64BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx64Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX128BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx128Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX256BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx256Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX512BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx512Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX1024BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx1024Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RX1518BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Rx1518Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXMAXBYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxMaxByte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXTOOLONG, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxTooLong = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXGOODBYTE_LO, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxGoodByte_lo = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXGOODBYTE_HI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxGoodByte_hi = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBADBYTE_LO, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxBadByte_lo = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXBADBYTE_HI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxBadByte_hi = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_RXOVERFLOW, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->RxOverFlow = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_FILTERED, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Filtered = val; + + return SW_OK; +} + +static sw_error_t +_shiva_get_tx_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info) +{ + a_uint32_t val = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_OUT_OF_RANGE; + } + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBROAD, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxBroad = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXPAUSE, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxPause = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMULTI, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxMulti = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXUNDERRUN, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxUnderRun = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX64BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx64Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX128BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx128Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX256BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx256Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX512BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx512Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX1024BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx1024Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TX1518BYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->Tx1518Byte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMAXBYTE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxMaxByte = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXOVERSIZE, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxOverSize = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBYTE_LO, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxByte_lo = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXBYTE_HI, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxByte_hi = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXCOLLISION, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxCollision = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXABORTCOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxAbortCol = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXMULTICOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxMultiCol = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXSINGALCOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxSingalCol = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXEXCDEFER, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxExcDefer = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXDEFER, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxDefer = val; + + HSL_REG_ENTRY_GET(rv, dev_id, MIB_TXLATECOL, port_id, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + mib_info->TxLateCol = val; + + return SW_OK; +} + +static sw_error_t +_shiva_mib_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, MIB_FUNC, 0, MIB_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_mib_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, MIB_FUNC, 0, MIB_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +/** + * @brief Get mib infomation on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mib_info mib infomation + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_get_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_get_mib_info(dev_id, port_id, mib_info); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get RX mib infomation on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mib_info mib infomation + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_get_rx_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_get_rx_mib_info(dev_id, port_id, mib_info); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get TX mib infomation on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mib_info mib infomation + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_get_tx_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_get_tx_mib_info(dev_id, port_id, mib_info); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set mib status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_mib_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_mib_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mib status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_mib_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_mib_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +shiva_mib_init(a_uint32_t dev_id) +{ +#ifndef HSL_STANDALONG + hsl_api_t *p_api; +#endif + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->get_mib_info = shiva_get_mib_info; + p_api->get_rx_mib_info = shiva_get_rx_mib_info; + p_api->get_tx_mib_info = shiva_get_tx_mib_info; + p_api->mib_status_set = shiva_mib_status_set; + p_api->mib_status_get = shiva_mib_status_get; +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_mirror.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_mirror.c new file mode 100755 index 000000000..07e05ec02 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_mirror.c @@ -0,0 +1,317 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup shiva_mirror SHIVA_MIRROR + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "shiva_mirror.h" +#include "shiva_reg.h" + +static sw_error_t +_shiva_mirr_analysis_port_set(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + if (port_id != MIRROR_ANALYZER_NONE) { + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) { + return SW_BAD_PARAM; + } + } + val = port_id; + HSL_REG_FIELD_SET(rv, dev_id, CPU_PORT, 0, MIRROR_PORT_NUM, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_mirr_analysis_port_get(a_uint32_t dev_id, fal_port_t * port_id) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, CPU_PORT, 0, MIRROR_PORT_NUM, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *port_id = val; + return SW_OK; +} + +static sw_error_t +_shiva_mirr_port_in_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, ING_MIRROR_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_mirr_port_in_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, ING_MIRROR_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_shiva_mirr_port_eg_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, EG_MIRROR_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_mirr_port_eg_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, EG_MIRROR_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +/** + * @details Comments: + * The analysis port works for both ingress and egress mirror. + * @brief Set mirror analyzer port on particular a device. + * @param[in] dev_id device id + * @param[in] port_id port id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_mirr_analysis_port_set(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_mirr_analysis_port_set(dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get mirror analysis port on particular a device. + * @param[in] dev_id device id + * @param[out] port_id port id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_mirr_analysis_port_get(a_uint32_t dev_id, fal_port_t * port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_mirr_analysis_port_get(dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set ingress mirror status on particular a port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_mirr_port_in_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_mirr_port_in_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get ingress mirror status on particular a port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_mirr_port_in_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_mirr_port_in_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set egress mirror status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_mirr_port_eg_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_mirr_port_eg_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get egress mirror status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_mirr_port_eg_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_mirr_port_eg_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +shiva_mirr_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->mirr_analysis_port_set = shiva_mirr_analysis_port_set; + p_api->mirr_analysis_port_get = shiva_mirr_analysis_port_get; + p_api->mirr_port_in_set = shiva_mirr_port_in_set; + p_api->mirr_port_in_get = shiva_mirr_port_in_get; + p_api->mirr_port_eg_set = shiva_mirr_port_eg_set; + p_api->mirr_port_eg_get = shiva_mirr_port_eg_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_misc.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_misc.c new file mode 100755 index 000000000..f5793a268 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_misc.c @@ -0,0 +1,1749 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup shiva_misc SHIVA_MISC + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "shiva_misc.h" +#include "shiva_reg.h" + +#define SHIVA_MAX_FRMAE_SIZE 9216 + +static sw_error_t +_shiva_arp_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, QM_CTL, 0, ARP_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_arp_status_get(a_uint32_t dev_id, a_bool_t *enable) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, QM_CTL, 0, ARP_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_shiva_frame_max_size_set(a_uint32_t dev_id, a_uint32_t size) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (SHIVA_MAX_FRMAE_SIZE < size) + { + return SW_BAD_PARAM; + } + + data = size; + HSL_REG_FIELD_SET(rv, dev_id, GLOBAL_CTL, 0, MAX_FRAME_SIZE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_frame_max_size_get(a_uint32_t dev_id, a_uint32_t *size) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, GLOBAL_CTL, 0, MAX_FRAME_SIZE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *size = data; + return SW_OK; +} + +static sw_error_t +_shiva_port_unk_sa_cmd_set(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_CTL, port_id, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_MAC_FRWRD == cmd) + { + SW_SET_REG_BY_FIELD(PORT_CTL, PORT_LOCK_EN, 0, data); + } + else if (FAL_MAC_DROP == cmd) + { + SW_SET_REG_BY_FIELD(PORT_CTL, PORT_LOCK_EN, 1, data); + SW_SET_REG_BY_FIELD(PORT_CTL, LOCK_DROP_EN, 1, data); + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + SW_SET_REG_BY_FIELD(PORT_CTL, PORT_LOCK_EN, 1, data); + SW_SET_REG_BY_FIELD(PORT_CTL, LOCK_DROP_EN, 0, data); + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_CTL, port_id, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_port_unk_sa_cmd_get(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t * action) +{ + sw_error_t rv; + a_uint32_t data = 0; + a_uint32_t port_lock_en, port_drop_en; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_CTL, port_id, (a_uint8_t *) (&data), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_CTL, PORT_LOCK_EN, port_lock_en, data); + SW_GET_FIELD_BY_REG(PORT_CTL, LOCK_DROP_EN, port_drop_en, data); + + if (1 == port_lock_en) + { + if (1 == port_drop_en) + { + *action = FAL_MAC_DROP; + } + else + { + *action = FAL_MAC_RDT_TO_CPU; + } + } + else + { + *action = FAL_MAC_FRWRD; + } + + return SW_OK; +} + +static sw_error_t +_shiva_port_unk_uc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FLOOD_MASK, 0, UNI_FLOOD_DP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + data &= (~((a_uint32_t)0x1 << port_id)); + } + else if (A_FALSE == enable) + { + data |= (0x1 << port_id); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FLOOD_MASK, 0, UNI_FLOOD_DP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_port_unk_uc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t reg = 0, field; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FLOOD_MASK, 0, UNI_FLOOD_DP, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + field = reg & (0x1 << port_id); + if (field) + { + *enable = A_FALSE; + } + else + { + *enable = A_TRUE; + } + + return SW_OK; +} + +static sw_error_t +_shiva_port_unk_mc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FLOOD_MASK, 0, MUL_FLOOD_DP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + data &= (~((a_uint32_t)0x1 << port_id)); + } + else if (A_FALSE == enable) + { + data |= (0x1 << port_id); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FLOOD_MASK, 0, MUL_FLOOD_DP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_port_unk_mc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t reg = 0, field; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FLOOD_MASK, 0, MUL_FLOOD_DP, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + field = reg & (0x1 << port_id); + if (field) + { + *enable = A_FALSE; + } + else + { + *enable = A_TRUE; + } + + return SW_OK; +} + +static sw_error_t +_shiva_port_bc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FLOOD_MASK, 0, BC_FLOOD_DP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + data &= (~((a_uint32_t)0x1 << port_id)); + } + else if (A_FALSE == enable) + { + data |= (0x1 << port_id); + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, FLOOD_MASK, 0, BC_FLOOD_DP, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_port_bc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t reg = 0, field; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, FLOOD_MASK, 0, BC_FLOOD_DP, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + field = reg & (0x1 << port_id); + if (field) + { + *enable = A_FALSE; + } + else + { + *enable = A_TRUE; + } + + return SW_OK; +} + +static sw_error_t +_shiva_cpu_port_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, CPU_PORT, 0, CPU_PORT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_cpu_port_status_get(a_uint32_t dev_id, a_bool_t *enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, CPU_PORT, 0, CPU_PORT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_shiva_pppoe_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_MAC_FRWRD == cmd) + { + val = 0; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + val = 1; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, QM_CTL, 0, PPPOE_RDT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_pppoe_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, QM_CTL, 0, PPPOE_RDT_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + else + { + *cmd = FAL_MAC_FRWRD; + } + + return SW_OK; +} + +static sw_error_t +_shiva_pppoe_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, QM_CTL, 0, PPPOE_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_pppoe_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, QM_CTL, 0, PPPOE_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_shiva_port_dhcp_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, DHCP_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_port_dhcp_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, DHCP_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_shiva_arp_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_MAC_CPY_TO_CPU == cmd) + { + val = 0; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + val = 1; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, QM_CTL, 0, ARP_CMD, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_arp_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, QM_CTL, 0, ARP_CMD, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0 == val) + { + *cmd = FAL_MAC_CPY_TO_CPU; + } + else + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + + return SW_OK; +} + +static sw_error_t +_shiva_eapol_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_MAC_CPY_TO_CPU == cmd) + { + val = 0; + } + else if (FAL_MAC_RDT_TO_CPU == cmd) + { + val = 1; + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_SET(rv, dev_id, QM_CTL, 0, EAPOL_CMD, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_eapol_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, QM_CTL, 0, EAPOL_CMD, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0 == val) + { + *cmd = FAL_MAC_CPY_TO_CPU; + } + else + { + *cmd = FAL_MAC_RDT_TO_CPU; + } + + return SW_OK; +} + +#define SHIVA_MAX_PPPOE_SESSION 16 +#define SHIVA_MAX_SESSION_ID 0xffff + +static sw_error_t +_shiva_pppoe_session_add(a_uint32_t dev_id, a_uint32_t session_id, a_bool_t strip_hdr) +{ + sw_error_t rv; + a_uint32_t reg = 0, i, valid, cmd, id, entry_idx = 0xffff; + + HSL_DEV_ID_CHECK(dev_id); + + if (session_id > SHIVA_MAX_SESSION_ID) + { + return SW_BAD_PARAM; + } + + for (i = 0; i < SHIVA_MAX_PPPOE_SESSION; i++) + { + HSL_REG_ENTRY_GET(rv, dev_id, PPPOE_SESSION, i, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PPPOE_SESSION, ENTRY_VALID, valid, reg); + SW_GET_FIELD_BY_REG(PPPOE_SESSION, SEESION_ID, id, reg); + + if (!valid) + { + entry_idx = i; + } + else if (id == session_id) + { + return SW_ALREADY_EXIST; + } + } + + if (0xffff == entry_idx) + { + return SW_NO_RESOURCE; + } + + SW_SET_REG_BY_FIELD(PPPOE_SESSION, ENTRY_VALID, 1, reg); + if (A_TRUE == strip_hdr) + { + cmd = 1; + } + else if (A_FALSE == strip_hdr) + { + cmd = 0; + } + else + { + return SW_NOT_SUPPORTED; + } + SW_SET_REG_BY_FIELD(PPPOE_SESSION, STRIP_EN, cmd, reg); + SW_SET_REG_BY_FIELD(PPPOE_SESSION, SEESION_ID, session_id, reg); + + HSL_REG_ENTRY_SET(rv, dev_id, PPPOE_SESSION, entry_idx, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_pppoe_session_del(a_uint32_t dev_id, a_uint32_t session_id) +{ + sw_error_t rv; + a_uint32_t reg = 0, i, valid, id; + + HSL_DEV_ID_CHECK(dev_id); + + if (session_id > SHIVA_MAX_SESSION_ID) + { + return SW_BAD_PARAM; + } + + for (i = 0; i < SHIVA_MAX_PPPOE_SESSION; i++) + { + HSL_REG_ENTRY_GET(rv, dev_id, PPPOE_SESSION, i, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PPPOE_SESSION, ENTRY_VALID, valid, reg); + SW_GET_FIELD_BY_REG(PPPOE_SESSION, SEESION_ID, id, reg); + + if (valid && (id == session_id)) + { + SW_SET_REG_BY_FIELD(PPPOE_SESSION, ENTRY_VALID, 0, reg); + SW_SET_REG_BY_FIELD(PPPOE_SESSION, STRIP_EN, 0, reg); + SW_SET_REG_BY_FIELD(PPPOE_SESSION, SEESION_ID, 0, reg); + HSL_REG_ENTRY_SET(rv, dev_id, PPPOE_SESSION, i, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; + } + } + + return SW_NOT_FOUND; +} + +static sw_error_t +_shiva_pppoe_session_get(a_uint32_t dev_id, a_uint32_t session_id, a_bool_t * strip_hdr) +{ + sw_error_t rv; + a_uint32_t reg = 0, i, valid, cmd, id; + + HSL_DEV_ID_CHECK(dev_id); + + if (session_id > SHIVA_MAX_SESSION_ID) + { + return SW_BAD_PARAM; + } + + for (i = 0; i < SHIVA_MAX_PPPOE_SESSION; i++) + { + HSL_REG_ENTRY_GET(rv, dev_id, PPPOE_SESSION, i, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PPPOE_SESSION, ENTRY_VALID, valid, reg); + SW_GET_FIELD_BY_REG(PPPOE_SESSION, SEESION_ID, id, reg); + + if (valid && (id == session_id)) + { + SW_GET_FIELD_BY_REG(PPPOE_SESSION, STRIP_EN, cmd, reg); + if (cmd) + { + *strip_hdr = A_TRUE; + } + else + { + *strip_hdr = A_FALSE; + } + return SW_OK; + } + } + + return SW_NOT_FOUND; +} + +static sw_error_t +_shiva_eapol_status_set(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, EAPOL_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_eapol_status_get(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t *enable) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, EAPOL_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_shiva_ripv1_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, 0, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, QM_CTL, 0, RIP_CPY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_ripv1_status_get(a_uint32_t dev_id, a_bool_t *enable) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, 0, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, QM_CTL, 0, RIP_CPY_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +#if 0 +static sw_error_t +_shiva_loop_check_status_set(a_uint32_t dev_id, fal_loop_check_time_t time, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t data, intr; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE == enable) + { + if (FAL_LOOP_CHECK_1MS == time) + { + data = 1; + } + else if (FAL_LOOP_CHECK_10MS == time) + { + data = 2; + } + else if (FAL_LOOP_CHECK_100MS == time) + { + data = 3; + } + else if (FAL_LOOP_CHECK_500MS == time) + { + data = 4; + } + else + { + return SW_BAD_PARAM; + } + intr = 1; + } + else + { + data = 0; + intr = 0; + } + + HSL_REG_FIELD_SET(rv, dev_id, ADDR_TABLE_CTL, 0, LOOP_CHK_TIME, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, GLOBAL_INT_MASK, 0, GLBM_LOOP_CHECK, + (a_uint8_t *) (&intr), sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_shiva_loop_check_status_get(a_uint32_t dev_id, fal_loop_check_time_t * time, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t data = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_CTL, 0, LOOP_CHK_TIME, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *enable = A_TRUE; + *time = FAL_LOOP_CHECK_1MS; + if (0 == data) + { + *enable = A_FALSE; + } + else if (2 == data) + { + *time = FAL_LOOP_CHECK_10MS; + } + else if (3 == data) + { + *time = FAL_LOOP_CHECK_100MS; + } + else if (4 == data) + { + *time = FAL_LOOP_CHECK_500MS; + } + + return SW_OK; +} + +static sw_error_t +_shiva_loop_check_info_get(a_uint32_t dev_id, a_uint32_t * old_port_id, a_uint32_t * new_port_id) +{ + sw_error_t rv; + a_uint32_t reg = 0, data; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_ENTRY_GET(rv, dev_id, LOOP_CHECK, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(LOOP_CHECK, NEW_PORT, data, reg); + *new_port_id = data; + + SW_GET_FIELD_BY_REG(LOOP_CHECK, OLD_PORT, data, reg); + *old_port_id = data; + + return SW_OK; +} +#endif + +/** + * @brief Set arp packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_arp_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_arp_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_arp_status_get(a_uint32_t dev_id, a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_arp_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set max frame size which device can received on a particular device. + * @details Comments: + * The granularity of packets size is byte. + * @param[in] dev_id device id + * @param[in] size packet size + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_frame_max_size_set(a_uint32_t dev_id, a_uint32_t size) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_frame_max_size_set(dev_id, size); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get max frame size which device can received on a particular device. + * @details Comments: + * The unit of packets size is byte. + * @param[in] dev_id device id + * @param[out] size packet size + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_frame_max_size_get(a_uint32_t dev_id, a_uint32_t *size) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_frame_max_size_get(dev_id, size); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set forwarding command for packets which source address is unknown on a particular port. + * @details Comments: + * Particular device may only support parts of forwarding commands. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_unk_sa_cmd_set(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_unk_sa_cmd_set(dev_id, port_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get forwarding command for packets which source address is unknown on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_unk_sa_cmd_get(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t * action) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_unk_sa_cmd_get(dev_id, port_id, action); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flooding status of unknown unicast packets on a particular port. + * @details Comments: + * If enable unknown unicast packets filter on one port then unknown + * unicast packets can't flood out from this port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_unk_uc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_unk_uc_filter_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get flooding status of unknown unicast packets on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_unk_uc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_unk_uc_filter_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flooding status of unknown multicast packets on a particular port. + * @details Comments: + * If enable unknown multicast packets filter on one port then unknown + * multicast packets can't flood out from this port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_unk_mc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_unk_mc_filter_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** @brief Get flooding status of unknown multicast packets on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_unk_mc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_unk_mc_filter_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flooding status of broadcast packets on a particular port. + * @details Comments: + * If enable unknown multicast packets filter on one port then unknown + * multicast packets can't flood out from this port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_bc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_bc_filter_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** @brief Get flooding status of broadcast packets on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_bc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_bc_filter_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set cpu port status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_cpu_port_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_cpu_port_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get cpu port status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_cpu_port_status_get(a_uint32_t dev_id, a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_cpu_port_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set pppoe packets forwarding command on a particular device. + * @details comments: + * Particular device may only support parts of forwarding commands. + * Ihis operation will take effect only after enabling pppoe packets + * hardware acknowledgement + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_pppoe_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_pppoe_cmd_set(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get pppoe packets forwarding command on a particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_pppoe_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_pppoe_cmd_get(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set pppoe packets hardware acknowledgement status on particular device. + * @details comments: + * Particular device may only support parts of pppoe packets. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_pppoe_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_pppoe_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get pppoe packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_pppoe_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_pppoe_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set dhcp packets hardware acknowledgement status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_dhcp_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_dhcp_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get dhcp packets hardware acknowledgement status on particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_dhcp_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_dhcp_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set arp packets forwarding command on a particular device. + * @details comments: + * Particular device may only support parts of forwarding commands. + * Ihis operation will take effect only after enabling arp packets + * hardware acknowledgement + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_arp_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_arp_cmd_set(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get arp packets forwarding command on a particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_arp_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_arp_cmd_get(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set eapol packets forwarding command on a particular device. + * @details comments: + * Particular device may only support parts of forwarding commands. + * Ihis operation will take effect only after enabling eapol packets + * hardware acknowledgement + * @param[in] dev_id device id + * @param[in] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_eapol_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_eapol_cmd_set(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get eapol packets forwarding command on a particular device. + * @param[in] dev_id device id + * @param[out] cmd forwarding command + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_eapol_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_eapol_cmd_get(dev_id, cmd); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add a pppoe session entry to a particular device. + * @param[in] dev_id device id + * @param[in] session_id pppoe session id + * @param[in] strip_hdr strip or not strip pppoe header + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_pppoe_session_add(a_uint32_t dev_id, a_uint32_t session_id, a_bool_t strip_hdr) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_pppoe_session_add(dev_id, session_id, strip_hdr); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a pppoe session entry from a particular device. + * @param[in] dev_id device id + * @param[in] session_id pppoe session id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_pppoe_session_del(a_uint32_t dev_id, a_uint32_t session_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_pppoe_session_del(dev_id, session_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get a pppoe session entry from a particular device. + * @param[in] dev_id device id + * @param[in] session_id pppoe session id + * @param[out] strip_hdr strip or not strip pppoe header + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_pppoe_session_get(a_uint32_t dev_id, a_uint32_t session_id, a_bool_t * strip_hdr) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_pppoe_session_get(dev_id, session_id, strip_hdr); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set eapol packets hardware acknowledgement status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_eapol_status_set(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_eapol_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get eapol packets hardware acknowledgement status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_eapol_status_get(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_eapol_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set rip v1 packets hardware acknowledgement status on a particular port. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_ripv1_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_ripv1_status_set(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get rip v1 packets hardware acknowledgement status on a particular port. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_ripv1_status_get(a_uint32_t dev_id, a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_ripv1_status_get(dev_id, enable); + HSL_API_UNLOCK; + return rv; +} + +#if 0 +/** + * @brief Set loopback checking status on a particular device. + * @param[in] dev_id device id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_loop_check_status_set(a_uint32_t dev_id, fal_loop_check_time_t time, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_loop_check_status_set(dev_id, time, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get loopback checking status on a particular device. + * @param[in] dev_id device id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_loop_check_status_get(a_uint32_t dev_id, fal_loop_check_time_t * time, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_loop_check_status_get(dev_id, time, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get loopback checking information on a particular device. + * @param[in] dev_id device id + * @param[in] old_port_id + * @param[in] new_port_id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_loop_check_info_get(a_uint32_t dev_id, a_uint32_t * old_port_id, a_uint32_t * new_port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_loop_check_info_get(dev_id, old_port_id, new_port_id); + HSL_API_UNLOCK; + return rv; +} +#endif + +sw_error_t +shiva_misc_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->arp_status_set = shiva_arp_status_set; + p_api->arp_status_get = shiva_arp_status_get; + p_api->frame_max_size_set = shiva_frame_max_size_set; + p_api->frame_max_size_get = shiva_frame_max_size_get; + p_api->port_unk_sa_cmd_set = shiva_port_unk_sa_cmd_set; + p_api->port_unk_sa_cmd_get = shiva_port_unk_sa_cmd_get; + p_api->port_unk_uc_filter_set = shiva_port_unk_uc_filter_set; + p_api->port_unk_uc_filter_get = shiva_port_unk_uc_filter_get; + p_api->port_unk_mc_filter_set = shiva_port_unk_mc_filter_set; + p_api->port_unk_mc_filter_get = shiva_port_unk_mc_filter_get; + p_api->port_bc_filter_set = shiva_port_bc_filter_set; + p_api->port_bc_filter_get = shiva_port_bc_filter_get; + p_api->cpu_port_status_set = shiva_cpu_port_status_set; + p_api->cpu_port_status_get = shiva_cpu_port_status_get; + p_api->pppoe_cmd_set = shiva_pppoe_cmd_set; + p_api->pppoe_cmd_get = shiva_pppoe_cmd_get; + p_api->pppoe_status_set = shiva_pppoe_status_set; + p_api->pppoe_status_get = shiva_pppoe_status_get; + p_api->port_dhcp_set = shiva_port_dhcp_set; + p_api->port_dhcp_get = shiva_port_dhcp_get; + p_api->arp_cmd_set = shiva_arp_cmd_set; + p_api->arp_cmd_get = shiva_arp_cmd_get; + p_api->eapol_cmd_set = shiva_eapol_cmd_set; + p_api->eapol_cmd_get = shiva_eapol_cmd_get; + p_api->pppoe_session_add = shiva_pppoe_session_add; + p_api->pppoe_session_del = shiva_pppoe_session_del; + p_api->pppoe_session_get = shiva_pppoe_session_get; + p_api->eapol_status_set = shiva_eapol_status_set; + p_api->eapol_status_get = shiva_eapol_status_get; + p_api->ripv1_status_set = shiva_ripv1_status_set; + p_api->ripv1_status_get = shiva_ripv1_status_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_port_ctrl.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_port_ctrl.c new file mode 100755 index 000000000..de5868a61 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_port_ctrl.c @@ -0,0 +1,1384 @@ +/* + * Copyright (c) 2012, 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 shiva_port_ctrl SHIVA_PORT_CONTROL + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "shiva_port_ctrl.h" +#include "shiva_reg.h" +#include "hsl_phy.h" + + +static sw_error_t +_shiva_port_duplex_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t duplex) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + a_uint32_t reg_save = 0; + a_uint32_t reg_val = 0, tmp; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_duplex_set) + return SW_NOT_SUPPORTED; + + if (FAL_DUPLEX_BUTT <= duplex) + { + return SW_BAD_PARAM; + } + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_duplex_get(dev_id, phy_id, &tmp); + SW_RTN_ON_ERROR(rv); + if (tmp == duplex) + return SW_OK; + + //save reg value + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_val), sizeof (a_uint32_t)); + reg_save = reg_val; + + SW_SET_REG_BY_FIELD(PORT_STATUS, LINK_EN, 0, reg_val); + SW_SET_REG_BY_FIELD(PORT_STATUS, RXMAC_EN, 0, reg_val); + SW_SET_REG_BY_FIELD(PORT_STATUS, TXMAC_EN, 0, reg_val); + + //set mac be config by sw and turn off RX TX MAC_EN + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_val), sizeof (a_uint32_t)); + + rv = phy_drv->phy_duplex_set(dev_id, phy_id, duplex); + + //retore reg value + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®_save), sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_shiva_port_duplex_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t * pduplex) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_duplex_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_duplex_get(dev_id, phy_id, pduplex); + return rv; +} + +static sw_error_t +_shiva_port_speed_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t speed) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_speed_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + if (FAL_SPEED_100 < speed) + { + return SW_BAD_PARAM; + } + + rv = phy_drv->phy_speed_set(dev_id, phy_id, speed); + + return rv; +} + +static sw_error_t +_shiva_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; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + a_uint32_t phy_data; + + HSL_DEV_ID_CHECK (dev_id); + + if (A_TRUE != hsl_port_prop_check (dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_id_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid (dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR (rv); + + rv = phy_drv->phy_id_get (dev_id, phy_id, &phy_data); + SW_RTN_ON_ERROR (rv); + + *org_id = (phy_data >> 16) & 0xffff; + *rev_id = phy_data & 0xffff; + + return rv; +} + +static sw_error_t +_shiva_port_speed_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t * pspeed) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_speed_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_speed_get(dev_id, phy_id, pspeed); + + return rv; +} + +static sw_error_t +_shiva_port_autoneg_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status) +{ + a_uint32_t phy_id; + sw_error_t rv; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_autoneg_status_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + *status = phy_drv->phy_autoneg_status_get(dev_id, phy_id); + + return SW_OK; +} + +static sw_error_t +_shiva_port_autoneg_enable(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_autoneg_enable_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_autoneg_enable_set(dev_id, phy_id); + return rv; +} + +static sw_error_t +_shiva_port_autoneg_restart(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_restart_autoneg) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_restart_autoneg(dev_id, phy_id); + return rv; +} + +static sw_error_t +_shiva_port_autoneg_adv_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t autoadv) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_autoneg_adv_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_autoneg_adv_set(dev_id, phy_id, autoadv); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +static sw_error_t +_shiva_port_autoneg_adv_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * autoadv) +{ + sw_error_t rv; + a_uint32_t phy_id; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_autoneg_adv_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + *autoadv = 0; + rv = phy_drv->phy_autoneg_adv_get(dev_id, phy_id, autoadv); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +static sw_error_t +_shiva_port_hdr_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, HEAD_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_shiva_port_hdr_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, HEAD_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_shiva_port_flowctrl_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val, force, reg = 0, tmp; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_STATUS, FLOW_LINK_EN, force, reg); + if (force) + { + /* flow control isn't in force mode so can't set */ + return SW_DISABLE; + } + tmp = reg; + + SW_SET_REG_BY_FIELD(PORT_STATUS, RX_FLOW_EN, val, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TX_FLOW_EN, val, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TX_HALF_FLOW_EN, val, reg); + if (tmp == reg) + return SW_OK; + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_port_flowctrl_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t rx, reg = 0; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_STATUS, RX_FLOW_EN, rx, reg); + + if (1 == rx) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return rv; +} + +static sw_error_t +_shiva_port_flowctrl_forcemode_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t force, reg; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_STATUS, FLOW_LINK_EN, force, reg); + if (force != (a_uint32_t) enable) + { + return SW_OK; + } + + if (A_TRUE == enable) + { + SW_SET_REG_BY_FIELD(PORT_STATUS, FLOW_LINK_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TX_FLOW_EN, 0, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, RX_FLOW_EN, 0, reg); + } + else if (A_FALSE == enable) + { + SW_SET_REG_BY_FIELD(PORT_STATUS, FLOW_LINK_EN, 1, reg); + } + else + { + return SW_BAD_PARAM; + } + SW_SET_REG_BY_FIELD(PORT_STATUS, TX_HALF_FLOW_EN, 0, reg); + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_port_flowctrl_forcemode_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t force, reg; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_STATUS, FLOW_LINK_EN, force, reg); + if (0 == force) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_shiva_port_powersave_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_powersave_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_powersave_set(dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_shiva_port_powersave_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_powersave_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_powersave_get(dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_shiva_port_hibernate_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_hibernation_set) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_hibernation_set(dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_shiva_port_hibernate_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_hibernation_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_hibernation_get(dev_id, phy_id, enable); + + return rv; +} + +static sw_error_t +_shiva_port_cdt(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t mdi_pair, + fal_cable_status_t *cable_status, a_uint32_t *cable_len) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_cdt) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + rv = phy_drv->phy_cdt(dev_id, phy_id, mdi_pair, cable_status, cable_len); + + return rv; +} + +static sw_error_t +_shiva_port_link_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *status) +{ + sw_error_t rv; + a_uint32_t phy_id = 0; + hsl_phy_ops_t *phy_drv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_PHY)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL (phy_drv = hsl_phy_api_ops_get (dev_id, port_id)); + if (NULL == phy_drv->phy_link_status_get) + return SW_NOT_SUPPORTED; + + rv = hsl_port_prop_get_phyid(dev_id, port_id, &phy_id); + SW_RTN_ON_ERROR(rv); + + *status = phy_drv->phy_link_status_get(dev_id, phy_id); + + return rv; +} + +static sw_error_t +_shiva_port_txfc_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable) +{ + sw_error_t rv; + a_uint32_t tx_fc_full, tx_fc_half, reg = 0; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_STATUS, TX_FLOW_EN, tx_fc_full, reg); + SW_GET_FIELD_BY_REG(PORT_STATUS, TX_HALF_FLOW_EN, tx_fc_half, reg); + if (TX_FC_FULL_EN == tx_fc_full && TX_FC_HALF_EN == tx_fc_half) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return rv; +} + +static sw_error_t +_shiva_port_txfc_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t force, reg = 0, tmp; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE != enable && A_FALSE != enable) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_STATUS, FLOW_LINK_EN, force, reg); + if (force) + { + /* flow control isn't in force mode so can't set */ + return SW_DISABLE; + } + tmp = reg; + SW_SET_REG_BY_FIELD(PORT_STATUS, TX_FLOW_EN, enable, reg); + SW_SET_REG_BY_FIELD(PORT_STATUS, TX_HALF_FLOW_EN, enable, reg); + if (tmp == reg) + return SW_OK; + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_shiva_port_rxfc_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable) +{ + sw_error_t rv; + a_uint32_t rx_fc, reg = 0; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_STATUS, RX_FLOW_EN, rx_fc, reg); + if (RX_FC_EN == rx_fc) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return rv; +} + +static sw_error_t +_shiva_port_rxfc_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t force, reg = 0, tmp; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE != enable && A_FALSE != enable) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_STATUS, FLOW_LINK_EN, force, reg); + if (force) + { + /* flow control isn't in force mode so can't set */ + return SW_DISABLE; + } + tmp = reg; + + SW_SET_REG_BY_FIELD(PORT_STATUS, RX_FLOW_EN, enable, reg); + if (tmp == reg) + return SW_OK; + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_STATUS, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + return rv; +} + +/** + * @brief Set duplex mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] duplex duplex mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_duplex_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t duplex) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_duplex_set(dev_id, port_id, duplex); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get duplex mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] duplex duplex mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_duplex_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t * pduplex) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_duplex_get(dev_id, port_id, pduplex); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set speed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] speed port speed + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_speed_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t speed) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_speed_set(dev_id, port_id, speed); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get phy id on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] org_id and rev_id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_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; + + HSL_API_LOCK; + rv = _shiva_port_phy_id_get (dev_id, port_id, org_id, rev_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get speed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] speed port speed + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_speed_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t * pspeed) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_speed_get(dev_id, port_id, pspeed); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get auto negotiation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] status A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_autoneg_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_autoneg_status_get(dev_id, port_id, status); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Enable auto negotiation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_autoneg_enable(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_autoneg_enable(dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Restart auto negotiation procedule on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_autoneg_restart(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_autoneg_restart(dev_id, port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set auto negotiation advtisement ability on a particular port. + * @details Comments: + * auto negotiation advtisement ability is defined by macro such as + * FAL_PHY_ADV_10T_HD, FAL_PHY_ADV_PAUSE... + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] autoadv auto negotiation advtisement ability bit map + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_autoneg_adv_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t autoadv) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_autoneg_adv_set(dev_id, port_id, autoadv); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get auto negotiation advtisement ability on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] autoadv auto negotiation advtisement ability bit map + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_autoneg_adv_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * autoadv) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_autoneg_adv_get(dev_id, port_id, autoadv); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set status of Atheros header packets parsed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_hdr_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_hdr_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get status of Atheros header packets parsed on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_hdr_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_hdr_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flow control status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_flowctrl_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_flowctrl_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get flow control status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_flowctrl_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_flowctrl_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set flow control force mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_flowctrl_forcemode_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_flowctrl_forcemode_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get flow control force mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_flowctrl_forcemode_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_flowctrl_forcemode_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set powersaving status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_powersave_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_powersave_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get powersaving status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_powersave_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_powersave_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set hibernate status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_hibernate_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_hibernate_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get hibernate status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_hibernate_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_hibernate_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Run cable diagnostic test on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mdi_pair mdi pair id + * @param[out] cable_status cable status + * @param[out] cable_len cable len + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_cdt(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t mdi_pair, + fal_cable_status_t *cable_status, a_uint32_t *cable_len) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_cdt(dev_id, port_id, mdi_pair, cable_status, cable_len); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get linkstatus on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] status A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_link_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *status) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_link_status_get(dev_id, port_id, status); + HSL_API_UNLOCK; + + return rv; +} + +/** + * @brief Get txfc status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_txfc_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_txfc_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + + return rv; +} + +/** + * @brief Set tx flow control status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_txfc_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_txfc_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + + return rv; +} + +/** + * @brief Get rxfc status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_rxfc_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_rxfc_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + + return rv; +} + +/** + * @brief Set rx flow control status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_rxfc_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_rxfc_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + + return rv; +} + +sw_error_t +shiva_port_ctrl_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->port_duplex_get = shiva_port_duplex_get; + p_api->port_duplex_set = shiva_port_duplex_set; + p_api->port_speed_get = shiva_port_speed_get; + p_api->port_speed_set = shiva_port_speed_set; + p_api->port_phy_id_get = shiva_port_phy_id_get; + p_api->port_autoneg_status_get = shiva_port_autoneg_status_get; + p_api->port_autoneg_enable = shiva_port_autoneg_enable; + p_api->port_autoneg_restart = shiva_port_autoneg_restart; + p_api->port_autoneg_adv_get = shiva_port_autoneg_adv_get; + p_api->port_autoneg_adv_set = shiva_port_autoneg_adv_set; + p_api->port_hdr_status_set = shiva_port_hdr_status_set; + p_api->port_hdr_status_get = shiva_port_hdr_status_get; + p_api->port_flowctrl_set = shiva_port_flowctrl_set; + p_api->port_flowctrl_get = shiva_port_flowctrl_get; + p_api->port_flowctrl_forcemode_set = shiva_port_flowctrl_forcemode_set; + p_api->port_flowctrl_forcemode_get = shiva_port_flowctrl_forcemode_get; + p_api->port_powersave_set = shiva_port_powersave_set; + p_api->port_powersave_get = shiva_port_powersave_get; + p_api->port_hibernate_set = shiva_port_hibernate_set; + p_api->port_hibernate_get = shiva_port_hibernate_get; + p_api->port_cdt = shiva_port_cdt; + p_api->port_link_status_get = shiva_port_link_status_get; + p_api->port_txfc_status_get = shiva_port_txfc_status_get; + p_api->port_txfc_status_set = shiva_port_txfc_status_set; + p_api->port_rxfc_status_get = shiva_port_rxfc_status_get; + p_api->port_rxfc_status_set = shiva_port_rxfc_status_set; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_portvlan.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_portvlan.c new file mode 100755 index 000000000..b9292b060 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_portvlan.c @@ -0,0 +1,1859 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup shiva_port_vlan SHIVA_PORT_VLAN + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "shiva_portvlan.h" +#include "shiva_reg.h" + +#define MAX_VLAN_ID 4095 +#define SHIVA_MAX_VLAN_TRANS 16 +#define SHIVA_VLAN_TRANS_ADDR 0x59000 + +static sw_error_t +_shiva_port_1qmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t port_1qmode) +{ + sw_error_t rv; + a_uint32_t regval[FAL_1Q_MODE_BUTT] = { 0, 3, 2, 1 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_1Q_MODE_BUTT <= port_1qmode) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_BASE_VLAN, port_id, DOT1Q_MODE, + (a_uint8_t *) (®val[port_1qmode]), + sizeof (a_uint32_t)); + + return rv; + +} + +static sw_error_t +_shiva_port_1qmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t * pport_1qmode) +{ + sw_error_t rv; + a_uint32_t regval = 0; + fal_pt_1qmode_t retval[4] = { FAL_1Q_DISABLE, FAL_1Q_FALLBACK, + FAL_1Q_CHECK, FAL_1Q_SECURE + }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL(pport_1qmode); + + HSL_REG_FIELD_GET(rv, dev_id, PORT_BASE_VLAN, port_id, DOT1Q_MODE, + (a_uint8_t *) (®val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + *pport_1qmode = retval[regval & 0x3]; + + return SW_OK; + +} + +static sw_error_t +_shiva_port_egvlanmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t port_egvlanmode) +{ + sw_error_t rv; + a_uint32_t regval[FAL_EG_MODE_BUTT] = { 0, 1, 2, 3}; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_EG_MODE_BUTT <= port_egvlanmode) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, EG_VLAN_MODE, + (a_uint8_t *) (®val[port_egvlanmode]), + sizeof (a_uint32_t)); + + return rv; + +} + +static sw_error_t +_shiva_port_egvlanmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t * pport_egvlanmode) +{ + sw_error_t rv; + a_uint32_t regval = 0; + fal_pt_1q_egmode_t retval[4] = { FAL_EG_UNMODIFIED, FAL_EG_UNTAGGED, + FAL_EG_TAGGED, FAL_EG_HYBRID + }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL(pport_egvlanmode); + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, EG_VLAN_MODE, + (a_uint8_t *) (®val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + *pport_egvlanmode = retval[regval & 0x3]; + + return SW_OK; + +} + +static sw_error_t +_shiva_portvlan_member_add(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id) +{ + sw_error_t rv; + a_uint32_t regval = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_FALSE == hsl_port_prop_check(dev_id, mem_port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_BASE_VLAN, port_id, + PORT_VID_MEM, (a_uint8_t *) (®val), + sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + regval |= (0x1UL << mem_port_id); + + HSL_REG_FIELD_SET(rv, dev_id, PORT_BASE_VLAN, port_id, + PORT_VID_MEM, (a_uint8_t *) (®val), + sizeof (a_uint32_t)); + + return rv; + +} + +static sw_error_t +_shiva_portvlan_member_del(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id) +{ + sw_error_t rv; + a_uint32_t regval = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_FALSE == hsl_port_prop_check(dev_id, mem_port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_BASE_VLAN, port_id, + PORT_VID_MEM, (a_uint8_t *) (®val), + sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + regval &= (~(0x1UL << mem_port_id)); + + HSL_REG_FIELD_SET(rv, dev_id, PORT_BASE_VLAN, port_id, + PORT_VID_MEM, (a_uint8_t *) (®val), + sizeof (a_uint32_t)); + + return rv; + +} + +static sw_error_t +_shiva_portvlan_member_update(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t mem_port_map) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_FALSE == + hsl_mports_prop_check(dev_id, mem_port_map, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_BASE_VLAN, port_id, + PORT_VID_MEM, (a_uint8_t *) (&mem_port_map), + sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_shiva_portvlan_member_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t * mem_port_map) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + *mem_port_map = 0; + HSL_REG_FIELD_GET(rv, dev_id, PORT_BASE_VLAN, port_id, + PORT_VID_MEM, (a_uint8_t *) mem_port_map, + sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +static sw_error_t +_shiva_port_force_default_vid_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_DOT1AD, port_id, + FORCE_DEF_VID, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_port_force_default_vid_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_DOT1AD, port_id, + FORCE_DEF_VID, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_shiva_port_force_portvlan_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_DOT1AD, port_id, + FORCE_PVLAN, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_port_force_portvlan_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_DOT1AD, port_id, + FORCE_PVLAN, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_shiva_nestvlan_tpid_set(a_uint32_t dev_id, a_uint32_t tpid) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + val = tpid; + HSL_REG_FIELD_SET(rv, dev_id, SERVICE_TAG, 0, + TAG_VALUE, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_nestvlan_tpid_get(a_uint32_t dev_id, a_uint32_t *tpid) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, SERVICE_TAG, 0, + TAG_VALUE, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *tpid = val; + return SW_OK; +} + +static sw_error_t +_shiva_port_invlan_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_invlan_mode_t mode) +{ + sw_error_t rv; + a_uint32_t regval[FAL_INVLAN_MODE_BUTT] = { 0, 1, 2}; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_INVLAN_MODE_BUTT <= mode) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_BASE_VLAN, port_id, IN_VLAN_MODE, + (a_uint8_t *) (®val[mode]), + sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_shiva_port_invlan_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_invlan_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t regval = 0; + fal_pt_invlan_mode_t retval[FAL_INVLAN_MODE_BUTT] = { FAL_INVLAN_ADMIT_ALL, + FAL_INVLAN_ADMIT_TAGGED, FAL_INVLAN_ADMIT_UNTAGGED + }; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL(mode); + + HSL_REG_FIELD_GET(rv, dev_id, PORT_BASE_VLAN, port_id, IN_VLAN_MODE, + (a_uint8_t *) (®val), + sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (regval >= 3) + { + return SW_FAIL; + } + *mode = retval[regval & 0x3]; + + return rv; +} + +static sw_error_t +_shiva_port_tls_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_DOT1AD, port_id, + TLS_EN, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_port_tls_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_DOT1AD, port_id, + TLS_EN, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_shiva_port_pri_propagation_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_BASE_VLAN, port_id, + PRI_PROPAGATION, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_port_pri_propagation_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_BASE_VLAN, port_id, + PRI_PROPAGATION, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_shiva_port_default_svid_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vid) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if ((0 == vid) || (vid > MAX_VLAN_ID)) + { + return SW_BAD_PARAM; + } + + val = vid; + HSL_REG_FIELD_SET(rv, dev_id, PORT_DOT1AD, port_id, + DEF_SVID, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_shiva_port_default_svid_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vid) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_DOT1AD, port_id, + DEF_SVID, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + + *vid = val & 0xfff; + return rv; +} + +static sw_error_t +_shiva_port_default_cvid_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vid) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if ((0 == vid) || (vid > MAX_VLAN_ID)) + { + return SW_BAD_PARAM; + } + + val = vid; + HSL_REG_FIELD_SET(rv, dev_id, PORT_DOT1AD, port_id, + DEF_CVID, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_shiva_port_default_cvid_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vid) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_DOT1AD, port_id, + DEF_CVID, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + + *vid = val & 0xfff; + return rv; +} + +static sw_error_t +_shiva_port_vlan_propagation_set(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_propagation_mode_t mode) +{ + sw_error_t rv; + a_uint32_t reg = 0, p, c; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_VLAN_PROPAGATION_DISABLE == mode) + { + p = 0; + c = 0; + } + else if (FAL_VLAN_PROPAGATION_CLONE == mode) + { + p = 1; + c = 1; + } + else if (FAL_VLAN_PROPAGATION_REPLACE == mode) + { + p = 1; + c = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_DOT1AD, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(PORT_DOT1AD, PROPAGATION_EN, p, reg); + SW_SET_REG_BY_FIELD(PORT_DOT1AD, CLONE, c, reg); + + HSL_REG_ENTRY_SET(rv, dev_id, PORT_DOT1AD, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_port_vlan_propagation_get(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_propagation_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t reg = 0, p, c; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PORT_DOT1AD, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(PORT_DOT1AD, PROPAGATION_EN, p, reg); + SW_GET_FIELD_BY_REG(PORT_DOT1AD, CLONE, c, reg); + + if (p) + { + if (c) + { + *mode = FAL_VLAN_PROPAGATION_CLONE; + } + else + { + *mode = FAL_VLAN_PROPAGATION_REPLACE; + } + } + else + { + *mode = FAL_VLAN_PROPAGATION_DISABLE; + } + + return SW_OK; +} + +static sw_error_t +_shiva_vlan_trans_read(a_uint32_t dev_id, a_uint32_t entry_idx, fal_pbmp_t * pbmp, fal_vlan_trans_entry_t *entry) +{ + sw_error_t rv; + a_uint32_t i, addr, table[2] = {0}; + + addr = SHIVA_VLAN_TRANS_ADDR + (entry_idx << 3); + + /* get vlan trans table */ + for (i = 0; i < 2; i++) + { + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr + (i << 2), sizeof (a_uint32_t), + (a_uint8_t *) (&(table[i])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + if (0x1 & (table[1] >> 4)) + { + entry->o_vid = table[0] & 0xfff; + entry->s_vid = (table[0] >> 12) & 0xfff; + entry->c_vid = ((table[0] >> 24) & 0xff) | ((table[1] & 0xf) << 8); + entry->bi_dir = (~(table[1] >> 5)) & 0x1; + *pbmp = (table[1] >> 6) & 0x7f; + return SW_OK; + } + else + { + return SW_EMPTY; + } +} + +static sw_error_t +_shiva_vlan_trans_write(a_uint32_t dev_id, a_uint32_t entry_idx, fal_pbmp_t pbmp, fal_vlan_trans_entry_t entry) +{ + sw_error_t rv; + a_uint32_t i, addr, table[2] = {0}; + + addr = SHIVA_VLAN_TRANS_ADDR + (entry_idx << 3); + + if (0 != pbmp) + { + table[0] = entry.o_vid & 0xfff; + table[0] |= ((entry.s_vid & 0xfff) << 12); + table[0] |= ((entry.c_vid & 0xff) << 24); + table[1] = (entry.c_vid >> 8) & 0xf; + table[1] |= (0x1 << 4); + table[1] |= (((~(entry.bi_dir))& 0x1) << 5); + table[1] |= (pbmp << 6); + } + + /* set vlan trans table */ + for (i = 0; i < 2; i++) + { + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr + (i << 2), sizeof (a_uint32_t), + (a_uint8_t *) (&(table[i])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +static sw_error_t +_shiva_port_vlan_trans_add(a_uint32_t dev_id, fal_port_t port_id, fal_vlan_trans_entry_t *entry) +{ + sw_error_t rv; + fal_pbmp_t t_pbmp; + a_uint32_t idx, entry_idx = 0xffff, old_idx = 0xffff; + fal_vlan_trans_entry_t entry_temp; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + for (idx = 0; idx < SHIVA_MAX_VLAN_TRANS; idx++) + { + aos_mem_set(&entry_temp, 0, sizeof(fal_vlan_trans_entry_t)); + rv = _shiva_vlan_trans_read(dev_id, idx, &t_pbmp, &entry_temp); + if (SW_EMPTY == rv) + { + entry_idx = idx; + continue; + } + SW_RTN_ON_ERROR(rv); + + if (!aos_mem_cmp(&entry_temp, entry, sizeof(fal_vlan_trans_entry_t))) + { + if (SW_IS_PBMP_MEMBER(t_pbmp, port_id)) + { + return SW_ALREADY_EXIST; + } + old_idx = idx; + break; + } + } + + if (0xffff != old_idx) + { + t_pbmp |= (0x1 << port_id); + entry_idx = old_idx; + } + else if (0xffff != entry_idx) + { + t_pbmp = (0x1 << port_id); + aos_mem_copy(&entry_temp, entry, sizeof(fal_vlan_trans_entry_t)); + } + else + { + return SW_NO_RESOURCE; + } + + return _shiva_vlan_trans_write(dev_id, entry_idx, t_pbmp, entry_temp); +} + +static sw_error_t +_shiva_port_vlan_trans_del(a_uint32_t dev_id, fal_port_t port_id, fal_vlan_trans_entry_t *entry) +{ + sw_error_t rv; + fal_pbmp_t t_pbmp; + a_uint32_t idx, entry_idx = 0xffff; + fal_vlan_trans_entry_t entry_temp; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + for (idx = 0; idx < SHIVA_MAX_VLAN_TRANS; idx++) + { + aos_mem_set(&entry_temp, 0, sizeof(fal_vlan_trans_entry_t)); + rv = _shiva_vlan_trans_read(dev_id, idx, &t_pbmp, &entry_temp); + if (SW_EMPTY == rv) + { + continue; + } + SW_RTN_ON_ERROR(rv); + + if ((entry->o_vid == entry_temp.o_vid) + && (entry->bi_dir == entry_temp.bi_dir)) + { + if (SW_IS_PBMP_MEMBER(t_pbmp, port_id)) + { + entry_idx = idx; + break; + } + } + } + + if (0xffff != entry_idx) + { + t_pbmp &= (~(0x1 << port_id)); + } + else + { + return SW_NOT_FOUND; + } + + return _shiva_vlan_trans_write(dev_id, entry_idx, t_pbmp, entry_temp); +} + +static sw_error_t +_shiva_port_vlan_trans_get(a_uint32_t dev_id, fal_port_t port_id, fal_vlan_trans_entry_t *entry) +{ + sw_error_t rv; + fal_pbmp_t t_pbmp; + a_uint32_t idx; + fal_vlan_trans_entry_t entry_temp; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + for (idx = 0; idx < SHIVA_MAX_VLAN_TRANS; idx++) + { + aos_mem_set(&entry_temp, 0, sizeof(fal_vlan_trans_entry_t)); + rv = _shiva_vlan_trans_read(dev_id, idx, &t_pbmp, &entry_temp); + if (SW_EMPTY == rv) + { + continue; + } + + SW_RTN_ON_ERROR(rv); + if ((entry->o_vid == entry_temp.o_vid) + && (entry->bi_dir == entry_temp.bi_dir)) + { + if (SW_IS_PBMP_MEMBER(t_pbmp, port_id)) + { + aos_mem_copy(entry, &entry_temp, sizeof(fal_vlan_trans_entry_t)); + return SW_OK; + } + } + } + + return SW_NOT_FOUND; +} + +static sw_error_t +_shiva_port_vlan_trans_iterate(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * iterator, fal_vlan_trans_entry_t * entry) +{ + a_uint32_t index; + sw_error_t rv; + fal_vlan_trans_entry_t entry_t; + fal_pbmp_t pbmp_t = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if ((NULL == iterator) || (NULL == entry)) + { + return SW_BAD_PTR; + } + + if (SHIVA_MAX_VLAN_TRANS == *iterator) + { + return SW_NO_MORE; + } + + if (SHIVA_MAX_VLAN_TRANS < *iterator) + { + return SW_BAD_PARAM; + } + + aos_mem_set(&entry_t, 0, sizeof(fal_vlan_trans_entry_t)); + for (index = *iterator; index < SHIVA_MAX_VLAN_TRANS; index++) + { + rv = _shiva_vlan_trans_read(dev_id, index, &pbmp_t, &entry_t); + if (SW_EMPTY == rv) + { + continue; + } + + if (SW_IS_PBMP_MEMBER(pbmp_t, port_id)) + { + aos_mem_copy(entry, &entry_t, sizeof(fal_vlan_trans_entry_t)); + break; + } + } + + if (SHIVA_MAX_VLAN_TRANS == index) + { + return SW_NO_MORE; + } + + *iterator = index + 1; + return SW_OK; +} + +static sw_error_t +_shiva_qinq_mode_set(a_uint32_t dev_id, fal_qinq_mode_t mode) +{ + sw_error_t rv; + a_uint32_t stag = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_QINQ_MODE_BUTT <= mode) + { + return SW_BAD_PARAM; + } + + if (FAL_QINQ_STAG_MODE == mode) + { + stag = 1; + } + + HSL_REG_FIELD_SET(rv, dev_id, ADDR_TABLE_CTL, 0, + STAG_MODE, (a_uint8_t *) (&stag), + sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_shiva_qinq_mode_get(a_uint32_t dev_id, fal_qinq_mode_t * mode) +{ + sw_error_t rv; + a_uint32_t stag = 0; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_CTL, 0, + STAG_MODE, (a_uint8_t *) (&stag), + sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (stag) + { + *mode = FAL_QINQ_STAG_MODE; + } + else + { + *mode = FAL_QINQ_CTAG_MODE; + } + + return SW_OK; +} + +static sw_error_t +_shiva_port_qinq_role_set(a_uint32_t dev_id, fal_port_t port_id, fal_qinq_port_role_t role) +{ + sw_error_t rv; + a_uint32_t core = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_QINQ_PORT_ROLE_BUTT <= role) + { + return SW_BAD_PARAM; + } + + if (FAL_QINQ_CORE_PORT == role) + { + core = 1; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_BASE_VLAN, port_id, + COREP_EN, (a_uint8_t *) (&core), + sizeof (a_uint32_t)); + + return rv; +} + +static sw_error_t +_shiva_port_qinq_role_get(a_uint32_t dev_id, fal_port_t port_id, fal_qinq_port_role_t * role) +{ + sw_error_t rv; + a_uint32_t core = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_BASE_VLAN, port_id, + COREP_EN, (a_uint8_t *) (&core), + sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (core) + { + *role = FAL_QINQ_CORE_PORT; + } + else + { + *role = FAL_QINQ_EDGE_PORT; + } + + return SW_OK; +} + +/** + * @brief Set 802.1q work mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] port_1qmode 802.1q work mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_1qmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t port_1qmode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_1qmode_set(dev_id, port_id, port_1qmode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get 802.1q work mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] port_1qmode 802.1q work mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_1qmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t * pport_1qmode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_1qmode_get(dev_id, port_id, pport_1qmode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set packets transmitted out vlan tagged mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] port_egvlanmode packets transmitted out vlan tagged mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_egvlanmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t port_egvlanmode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_egvlanmode_set(dev_id, port_id, port_egvlanmode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get packets transmitted out vlan tagged mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] port_egvlanmode packets transmitted out vlan tagged mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_egvlanmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t * pport_egvlanmode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_egvlanmode_get(dev_id, port_id, pport_egvlanmode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add member of port based vlan on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mem_port_id port member + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_portvlan_member_add(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_portvlan_member_add(dev_id, port_id, mem_port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete member of port based vlan on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mem_port_id port member + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_portvlan_member_del(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_portvlan_member_del(dev_id, port_id, mem_port_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Update member of port based vlan on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mem_port_map port members + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_portvlan_member_update(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t mem_port_map) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_portvlan_member_update(dev_id, port_id, mem_port_map); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get member of port based vlan on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mem_port_map port members + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_portvlan_member_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t * mem_port_map) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_portvlan_member_get(dev_id, port_id, mem_port_map); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set force default vlan id status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_force_default_vid_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_force_default_vid_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get force default vlan id status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_force_default_vid_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_force_default_vid_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set force port based vlan status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_force_portvlan_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_force_portvlan_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get force port based vlan status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_force_portvlan_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_force_portvlan_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set nest vlan tpid on a particular device. + * @param[in] dev_id device id + * @param[in] tpid tag protocol identification + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_nestvlan_tpid_set(a_uint32_t dev_id, a_uint32_t tpid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_nestvlan_tpid_set(dev_id, tpid); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get nest vlan tpid on a particular device. + * @param[in] dev_id device id + * @param[out] tpid tag protocol identification + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_nestvlan_tpid_get(a_uint32_t dev_id, a_uint32_t *tpid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_nestvlan_tpid_get(dev_id, tpid); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set ingress vlan mode mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode ingress vlan mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_invlan_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_invlan_mode_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_invlan_mode_set(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get ingress vlan mode mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mode ingress vlan mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_invlan_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_invlan_mode_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_invlan_mode_get(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set tls status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_tls_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_tls_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get tls status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_tls_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_tls_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set priority propagation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_pri_propagation_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_pri_propagation_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get priority propagation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_pri_propagation_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_pri_propagation_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set default s-vid on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] vid s-vid + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_default_svid_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_default_svid_set(dev_id, port_id, vid); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get default s-vid on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] vid s-vid + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_default_svid_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_default_svid_get(dev_id, port_id, vid); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set default c-vid on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] vid c-vid + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_default_cvid_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_default_cvid_set(dev_id, port_id, vid); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get default c-vid on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] vid c-vid + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_default_cvid_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vid) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_default_cvid_get(dev_id, port_id, vid); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set vlan propagation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode vlan propagation mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_vlan_propagation_set(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_propagation_mode_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_vlan_propagation_set(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get vlan propagation status on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] mode vlan propagation mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_vlan_propagation_get(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_propagation_mode_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_vlan_propagation_get(dev_id, port_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Add a vlan translation entry to a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param entry vlan translation entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_vlan_trans_add(a_uint32_t dev_id, fal_port_t port_id, fal_vlan_trans_entry_t *entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_vlan_trans_add(dev_id, port_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a vlan translation entry from a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param entry vlan translation entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_vlan_trans_del(a_uint32_t dev_id, fal_port_t port_id, fal_vlan_trans_entry_t *entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_vlan_trans_del(dev_id, port_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get a vlan translation entry from a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param entry vlan translation entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_vlan_trans_get(a_uint32_t dev_id, fal_port_t port_id, fal_vlan_trans_entry_t *entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_vlan_trans_get(dev_id, port_id, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Iterate all vlan translation entries from a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] iterator translation entry index if it's zero means get the first entry + * @param[out] iterator next valid translation entry index + * @param[out] entry vlan translation entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_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; + + HSL_API_LOCK; + rv = _shiva_port_vlan_trans_iterate(dev_id, port_id, iterator, entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set switch qinq work mode on a particular device. + * @param[in] dev_id device id + * @param[in] mode qinq work mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_qinq_mode_set(a_uint32_t dev_id, fal_qinq_mode_t mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_qinq_mode_set(dev_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get switch qinq work mode on a particular device. + * @param[in] dev_id device id + * @param[out] mode qinq work mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_qinq_mode_get(a_uint32_t dev_id, fal_qinq_mode_t * mode) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_qinq_mode_get(dev_id, mode); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set qinq role on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] role port role + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_qinq_role_set(a_uint32_t dev_id, fal_port_t port_id, fal_qinq_port_role_t role) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_qinq_role_set(dev_id, port_id, role); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get qinq role on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] role port role + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_port_qinq_role_get(a_uint32_t dev_id, fal_port_t port_id, fal_qinq_port_role_t * role) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_port_qinq_role_get(dev_id, port_id, role); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +shiva_portvlan_init(a_uint32_t dev_id) +{ + a_uint32_t i; + sw_error_t rv; + fal_vlan_trans_entry_t entry_init; + hsl_api_t *p_api; + + HSL_DEV_ID_CHECK(dev_id); + + aos_mem_set(&entry_init, 0, sizeof(fal_vlan_trans_entry_t)); + entry_init.bi_dir = A_TRUE; + + for (i = 0; i < SHIVA_MAX_VLAN_TRANS; i++) + { + rv = _shiva_vlan_trans_write(dev_id, i, 0, entry_init); + SW_RTN_ON_ERROR(rv); + } + +#ifndef HSL_STANDALONG + + SW_RTN_ON_NULL (p_api = hsl_api_ptr_get(dev_id)); + + p_api->port_1qmode_get = shiva_port_1qmode_get; + p_api->port_1qmode_set = shiva_port_1qmode_set; + p_api->port_egvlanmode_get = shiva_port_egvlanmode_get; + p_api->port_egvlanmode_set = shiva_port_egvlanmode_set; + p_api->portvlan_member_add = shiva_portvlan_member_add; + p_api->portvlan_member_del = shiva_portvlan_member_del; + p_api->portvlan_member_update = shiva_portvlan_member_update; + p_api->portvlan_member_get = shiva_portvlan_member_get; + p_api->port_force_default_vid_set = shiva_port_force_default_vid_set; + p_api->port_force_default_vid_get = shiva_port_force_default_vid_get; + p_api->port_force_portvlan_set = shiva_port_force_portvlan_set; + p_api->port_force_portvlan_get = shiva_port_force_portvlan_get; + p_api->nestvlan_tpid_set = shiva_nestvlan_tpid_set; + p_api->nestvlan_tpid_get = shiva_nestvlan_tpid_get; + p_api->port_invlan_mode_set = shiva_port_invlan_mode_set; + p_api->port_invlan_mode_get = shiva_port_invlan_mode_get; + p_api->port_tls_set = shiva_port_tls_set; + p_api->port_tls_get = shiva_port_tls_get; + p_api->port_pri_propagation_set = shiva_port_pri_propagation_set; + p_api->port_pri_propagation_get = shiva_port_pri_propagation_get; + p_api->port_default_svid_set = shiva_port_default_svid_set; + p_api->port_default_svid_get = shiva_port_default_svid_get; + p_api->port_default_cvid_set = shiva_port_default_cvid_set; + p_api->port_default_cvid_get = shiva_port_default_cvid_get; + p_api->port_vlan_propagation_set = shiva_port_vlan_propagation_set; + p_api->port_vlan_propagation_get = shiva_port_vlan_propagation_get; + p_api->port_vlan_trans_add = shiva_port_vlan_trans_add; + p_api->port_vlan_trans_del = shiva_port_vlan_trans_del; + p_api->port_vlan_trans_get = shiva_port_vlan_trans_get; + p_api->qinq_mode_set = shiva_qinq_mode_set; + p_api->qinq_mode_get = shiva_qinq_mode_get; + p_api->port_qinq_role_set = shiva_port_qinq_role_set; + p_api->port_qinq_role_get = shiva_port_qinq_role_get; + p_api->port_vlan_trans_iterate = shiva_port_vlan_trans_iterate; +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_qos.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_qos.c new file mode 100755 index 000000000..64221f7ab --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_qos.c @@ -0,0 +1,1288 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup shiva_qos SHIVA_QOS + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "shiva_qos.h" +#include "shiva_reg.h" + +#define SHIVA_QOS_QUEUE_TX_BUFFER_MAX 60 +#define SHIVA_QOS_PORT_TX_BUFFER_MAX 252 +#define SHIVA_QOS_PORT_RX_BUFFER_MAX 60 + +//#define SHIVA_MIN_QOS_MODE_PRI 0 +#define SHIVA_MAX_QOS_MODE_PRI 3 + +static sw_error_t +_shiva_qos_queue_tx_buf_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, QUEUE_CTL, port_id, QUEUE_DESC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_qos_queue_tx_buf_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, QUEUE_CTL, port_id, QUEUE_DESC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_shiva_qos_port_tx_buf_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, QUEUE_CTL, port_id, PORT_DESC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_qos_port_tx_buf_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, QUEUE_CTL, port_id, PORT_DESC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_shiva_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) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (SHIVA_QOS_QUEUE_TX_BUFFER_MAX < *number) + { + return SW_BAD_PARAM; + } + + val = *number / 4; + *number = val << 2; + + if (0 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, QUEUE_CTL, port_id, QUEUE0_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (1 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, QUEUE_CTL, port_id, QUEUE1_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (2 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, QUEUE_CTL, port_id, QUEUE2_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (3 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, QUEUE_CTL, port_id, QUEUE3_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + + return rv; +} + +static sw_error_t +_shiva_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) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (0 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, QUEUE_CTL, port_id, QUEUE0_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (1 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, QUEUE_CTL, port_id, QUEUE1_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (2 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, QUEUE_CTL, port_id, QUEUE2_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (3 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, QUEUE_CTL, port_id, QUEUE3_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + *number = val << 2; + return SW_OK; +} + +static sw_error_t +_shiva_qos_port_tx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (SHIVA_QOS_PORT_TX_BUFFER_MAX < *number) + { + return SW_BAD_PARAM; + } + + val = *number / 4; + *number = val << 2; + HSL_REG_FIELD_SET(rv, dev_id, QUEUE_CTL, port_id, PORT_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_qos_port_tx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, QUEUE_CTL, port_id, PORT_DESC_NR, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *number = val << 2; + return SW_OK; +} + +static sw_error_t +_shiva_qos_port_rx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (SHIVA_QOS_PORT_RX_BUFFER_MAX < *number) + { + return SW_BAD_PARAM; + } + + val = *number / 4; + *number = val << 2; + HSL_REG_FIELD_SET(rv, dev_id, QUEUE_CTL, port_id, PORT_IN_DESC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_qos_port_rx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + a_uint32_t val = 0; + sw_error_t rv; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, QUEUE_CTL, port_id, PORT_IN_DESC_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *number = val << 2; + return SW_OK; +} + +static sw_error_t +_shiva_cosmap_up_queue_set(a_uint32_t dev_id, a_uint32_t up, + fal_queue_t queue) +{ + sw_error_t rv; + a_uint32_t val; + hsl_dev_t *p_dev = NULL; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_DOT1P_MAX < up) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL(p_dev = hsl_dev_ptr_get(dev_id)); + if (p_dev->nr_queue <= queue) + { + return SW_BAD_PARAM; + } + + val = queue; + HSL_REG_FIELD_GEN_SET(rv, dev_id, TAG_PRI_MAPPING_OFFSET, 2, + (a_uint16_t) (up << 1), (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_cosmap_up_queue_get(a_uint32_t dev_id, a_uint32_t up, + fal_queue_t * queue) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_DOT1P_MAX < up) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GEN_GET(rv, dev_id, TAG_PRI_MAPPING_OFFSET, 2, + (a_uint16_t) (up << 1), (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *queue = val; + return SW_OK; +} + +static sw_error_t +_shiva_cosmap_dscp_queue_set(a_uint32_t dev_id, a_uint32_t dscp, + fal_queue_t queue) +{ + sw_error_t rv; + a_uint32_t val; + a_uint32_t offsetaddr; + a_uint16_t fieldoffset; + hsl_dev_t *p_dev = NULL; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_DSCP_MAX < dscp) + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_NULL(p_dev = hsl_dev_ptr_get(dev_id)); + if (p_dev->nr_queue <= queue) + { + return SW_BAD_PARAM; + } + + offsetaddr = (dscp >> 4) << 2; + fieldoffset = (dscp & 0xf) << 1; + + val = queue; + HSL_REG_FIELD_GEN_SET(rv, dev_id, (IP_PRI_MAPPING_OFFSET + offsetaddr), + 2, fieldoffset, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_cosmap_dscp_queue_get(a_uint32_t dev_id, a_uint32_t dscp, + fal_queue_t * queue) +{ + sw_error_t rv; + a_uint32_t val = 0; + a_uint32_t offsetaddr; + a_uint16_t fieldoffset; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_DSCP_MAX < dscp) + { + return SW_BAD_PARAM; + } + + offsetaddr = (dscp / 16) << 2; + fieldoffset = (dscp & 0xf) << 1; + + HSL_REG_FIELD_GEN_GET(rv, dev_id, (IP_PRI_MAPPING_OFFSET + offsetaddr), + 2, fieldoffset, (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *queue = val; + return SW_OK; +} + +static sw_error_t +_shiva_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; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + val = 1; + } + else if (A_FALSE == enable) + { + val = 0; + } + else + { + return SW_BAD_PARAM; + } + + if (FAL_QOS_DA_MODE == mode) + { + HSL_REG_FIELD_SET(rv, dev_id, PRI_CTL, port_id, DA_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (FAL_QOS_UP_MODE == mode) + { + HSL_REG_FIELD_SET(rv, dev_id, PRI_CTL, port_id, VLAN_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (FAL_QOS_DSCP_MODE == mode) + { + HSL_REG_FIELD_SET(rv, dev_id, PRI_CTL, port_id, IP_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (FAL_QOS_PORT_MODE == mode) + { + HSL_REG_FIELD_SET(rv, dev_id, PRI_CTL, port_id, PORT_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + + return rv; +} + +static sw_error_t +_shiva_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; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_QOS_DA_MODE == mode) + { + HSL_REG_FIELD_GET(rv, dev_id, PRI_CTL, port_id, DA_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (FAL_QOS_UP_MODE == mode) + { + HSL_REG_FIELD_GET(rv, dev_id, PRI_CTL, port_id, VLAN_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (FAL_QOS_DSCP_MODE == mode) + { + HSL_REG_FIELD_GET(rv, dev_id, PRI_CTL, port_id, IP_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (FAL_QOS_PORT_MODE == mode) + { + HSL_REG_FIELD_GET(rv, dev_id, PRI_CTL, port_id, PORT_PRI_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_shiva_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; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (SHIVA_MAX_QOS_MODE_PRI < pri) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PRI_CTL, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_QOS_DA_MODE == mode) + { + SW_SET_REG_BY_FIELD(PRI_CTL, DA_PRI_SEL, pri, val); + } + else if (FAL_QOS_UP_MODE == mode) + { + SW_SET_REG_BY_FIELD(PRI_CTL, VLAN_PRI_SEL, pri, val); + } + else if (FAL_QOS_DSCP_MODE == mode) + { + SW_SET_REG_BY_FIELD(PRI_CTL, IP_PRI_SEL, pri, val); + } + else if (FAL_QOS_PORT_MODE == mode) + { + SW_SET_REG_BY_FIELD(PRI_CTL, PORT_PRI_SEL, pri, val); + } + else + { + return SW_NOT_SUPPORTED; + } + + HSL_REG_ENTRY_SET(rv, dev_id, PRI_CTL, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_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; + a_uint32_t entry = 0, f_val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_ENTRY_GET(rv, dev_id, PRI_CTL, port_id, (a_uint8_t *) (&entry), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (FAL_QOS_DA_MODE == mode) + { + SW_GET_FIELD_BY_REG(PRI_CTL, DA_PRI_SEL, f_val, entry); + } + else if (FAL_QOS_UP_MODE == mode) + { + SW_GET_FIELD_BY_REG(PRI_CTL, VLAN_PRI_SEL, f_val, entry); + } + else if (FAL_QOS_DSCP_MODE == mode) + { + SW_GET_FIELD_BY_REG(PRI_CTL, IP_PRI_SEL, f_val, entry); + } + else if (FAL_QOS_PORT_MODE == mode) + { + SW_GET_FIELD_BY_REG(PRI_CTL, PORT_PRI_SEL, f_val, entry); + } + else + { + return SW_NOT_SUPPORTED; + } + + *pri = f_val; + return SW_OK; +} + +static sw_error_t +_shiva_qos_port_default_up_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t up) +{ + sw_error_t rv; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_DOT1P_MAX < up) + { + return SW_BAD_PARAM; + } + + val = up; + HSL_REG_FIELD_SET(rv, dev_id, PORT_DOT1AD, port_id, ING_PRI, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_qos_port_default_up_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * up) +{ + sw_error_t rv; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_DOT1AD, port_id, ING_PRI, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + *up = val; + return SW_OK; +} + +static sw_error_t +_shiva_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; + a_uint32_t reg = 0, val, w[4] = {0}; + a_int32_t i, _index; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_SCH_SP_MODE == mode) + { + val = 0; + _index = -1; + } + else if (FAL_SCH_WRR_MODE == mode) + { + val = 3; + _index = 3; + } + else if (FAL_SCH_MIX_MODE == mode) + { + val = 1; + _index = 2; + } + else if (FAL_SCH_MIX_PLUS_MODE == mode) + { + val = 2; + _index = 1; + } + else + { + return SW_NOT_SUPPORTED; + } + + for (i = _index; i >= 0; i--) + { + if (weight[i] > 0x1f) + { + return SW_BAD_PARAM; + } + w[i] = weight[i]; + } + + HSL_REG_ENTRY_GET(rv, dev_id, WRR_CTRL, port_id, (a_uint8_t *) (®), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_SET_REG_BY_FIELD(WRR_CTRL, SCH_MODE, val, reg); + SW_SET_REG_BY_FIELD(WRR_CTRL, Q3_W, w[3], reg); + SW_SET_REG_BY_FIELD(WRR_CTRL, Q2_W, w[2], reg); + SW_SET_REG_BY_FIELD(WRR_CTRL, Q1_W, w[1], reg); + SW_SET_REG_BY_FIELD(WRR_CTRL, Q0_W, w[0], reg); + + HSL_REG_ENTRY_SET(rv, dev_id, WRR_CTRL, port_id, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_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; + a_uint32_t val = 0, sch, w[4], i; + + HSL_DEV_ID_CHECK(dev_id); + + HSL_REG_ENTRY_GET(rv, dev_id, WRR_CTRL, port_id, (a_uint8_t *) (&val), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + SW_GET_FIELD_BY_REG(WRR_CTRL, SCH_MODE, sch, val); + SW_GET_FIELD_BY_REG(WRR_CTRL, Q3_W, w[3], val); + SW_GET_FIELD_BY_REG(WRR_CTRL, Q2_W, w[2], val); + SW_GET_FIELD_BY_REG(WRR_CTRL, Q1_W, w[1], val); + SW_GET_FIELD_BY_REG(WRR_CTRL, Q0_W, w[0], val); + + if (0 == sch) + { + *mode = FAL_SCH_SP_MODE; + } + else if (1 == sch) + { + *mode = FAL_SCH_MIX_MODE; + } + else if (2 == sch) + { + *mode = FAL_SCH_MIX_PLUS_MODE; + } + else + { + *mode = FAL_SCH_WRR_MODE; + } + + for (i = 0; i < 6; i++) + { + weight[i] = 0; + } + + for (i = 0; i < 4; i++) + { + weight[i] = w[i]; + } + + return SW_OK; +} + +/** + * @brief Set buffer aggsinment status of transmitting queue on one particular port. + * @details Comments: + * If enable queue tx buffer on one port that means each queue of this port + * will have fixed number buffers when transmitting packets. Otherwise they + * share the whole buffers with other queues in device. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_qos_queue_tx_buf_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_qos_queue_tx_buf_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get buffer aggsinment status of transmitting queue on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_qos_queue_tx_buf_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_qos_queue_tx_buf_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set buffer aggsinment status of transmitting port on one particular port. + * @details Comments: + If enable tx buffer on one port that means this port will have fixed + number buffers when transmitting packets. Otherwise they will + share the whole buffers with other ports in device. + * function will return actual buffer numbers in hardware. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_qos_port_tx_buf_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_qos_port_tx_buf_status_set(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get buffer aggsinment status of transmitting port on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_qos_port_tx_buf_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_qos_port_tx_buf_status_get(dev_id, port_id, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set max occupied buffer number of transmitting queue on one particular port. + * @details Comments: + The step of buffer number in SHIVA is 4, function will return actual + buffer numbers in hardware. + The buffer number range for queue is 4 to 60. + * share the whole buffers with other ports in device. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param number buffer number + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_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; + + HSL_API_LOCK; + rv = _shiva_qos_queue_tx_buf_nr_set(dev_id, port_id, queue_id, number); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get max occupied buffer number of transmitting queue on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param[out] number buffer number + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_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; + + HSL_API_LOCK; + rv = _shiva_qos_queue_tx_buf_nr_get(dev_id, port_id, queue_id, number); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set max occupied buffer number of transmitting port on one particular port. + * @details Comments: + The step of buffer number in SHIVA is four, function will return actual + buffer numbers in hardware. + The buffer number range for transmitting port is 4 to 124. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param number buffer number + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_qos_port_tx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_qos_port_tx_buf_nr_set(dev_id, port_id, number); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get max occupied buffer number of transmitting port on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] number buffer number + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_qos_port_tx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_qos_port_tx_buf_nr_get(dev_id, port_id, number); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set max occupied buffer number of receiving port on one particular port. + * @details Comments: + The step of buffer number in SHIVA is four, function will return actual + buffer numbers in hardware. + The buffer number range for receiving port is 4 to 60. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param number buffer number + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_qos_port_rx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_qos_port_rx_buf_nr_set(dev_id, port_id, number); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get max occupied buffer number of receiving port on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] number buffer number + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_qos_port_rx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_qos_port_rx_buf_nr_get(dev_id, port_id, number); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set user priority to mapping on one particular device. + * @param[in] dev_id device id + * @param[in] dot1p 802.1p + * @param[in] queue queue id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_cosmap_up_queue_set(a_uint32_t dev_id, a_uint32_t up, + fal_queue_t queue) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_cosmap_up_queue_set(dev_id, up, queue); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get user priority to mapping on one particular device. + * @param[in] dev_id device id + * @param[in] dot1p 802.1p + * @param[out] queue queue id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_cosmap_up_queue_get(a_uint32_t dev_id, a_uint32_t up, + fal_queue_t * queue) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_cosmap_up_queue_get(dev_id, up, queue); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set cos map dscp_2_queue item on one particular device. + * @param[in] dev_id device id + * @param[in] dscp dscp + * @param[in] queue queue id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_cosmap_dscp_queue_set(a_uint32_t dev_id, a_uint32_t dscp, + fal_queue_t queue) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_cosmap_dscp_queue_set(dev_id, dscp, queue); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get cos map dscp_2_queue item on one particular device. + * @param[in] dev_id device id + * @param[in] dscp dscp + * @param[out] queue queue id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_cosmap_dscp_queue_get(a_uint32_t dev_id, a_uint32_t dscp, + fal_queue_t * queue) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_cosmap_dscp_queue_get(dev_id, dscp, queue); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set port qos mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode qos mode + * @param[in] enable A_TRUE of A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_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; + + HSL_API_LOCK; + rv = _shiva_qos_port_mode_set(dev_id, port_id, mode, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get port qos mode on a particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode qos mode + * @param[out] enable A_TRUE of A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_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; + + HSL_API_LOCK; + rv = _shiva_qos_port_mode_get(dev_id, port_id, mode, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set priority of one particular qos mode on one particular port. + * @details Comments: + If the priority of a mode is more small then the priority is more high. + Differnet mode should have differnet priority. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode qos mode + * @param[in] pri priority of one particular qos mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_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; + + HSL_API_LOCK; + rv = _shiva_qos_port_mode_pri_set(dev_id, port_id, mode, pri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get priority of one particular qos mode on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] mode qos mode + * @param[out] pri priority of one particular qos mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_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; + + HSL_API_LOCK; + rv = _shiva_qos_port_mode_pri_get(dev_id, port_id, mode, pri); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set default user priority on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] up 802.1p + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_qos_port_default_up_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t up) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_qos_port_default_up_set(dev_id, port_id, up); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get default user priority on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] up 802.1p + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_qos_port_default_up_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * up) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_qos_port_default_up_get(dev_id, port_id, up); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set traffic scheduling mode on particular one port. + * @details Comments: + * When scheduling mode is sp the weight is meaningless usually it's zero + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] fal_sch_mode_t traffic scheduling mode + * @param[in] weight[] weight value for each queue when in wrr mode, + the max value supported by SHIVA is 0x1f. + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_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; + + HSL_API_LOCK; + rv = _shiva_qos_port_sch_mode_set(dev_id, port_id, mode, weight); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get traffic scheduling mode on particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] fal_sch_mode_t traffic scheduling mode + * @param[out] weight weight value for wrr mode + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_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; + + HSL_API_LOCK; + rv = _shiva_qos_port_sch_mode_get(dev_id, port_id, mode, weight); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +shiva_qos_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->qos_queue_tx_buf_status_set = shiva_qos_queue_tx_buf_status_set; + p_api->qos_queue_tx_buf_status_get = shiva_qos_queue_tx_buf_status_get; + p_api->qos_port_tx_buf_status_set = shiva_qos_port_tx_buf_status_set; + p_api->qos_port_tx_buf_status_get = shiva_qos_port_tx_buf_status_get; + p_api->qos_queue_tx_buf_nr_set = shiva_qos_queue_tx_buf_nr_set; + p_api->qos_queue_tx_buf_nr_get = shiva_qos_queue_tx_buf_nr_get; + p_api->qos_port_tx_buf_nr_set = shiva_qos_port_tx_buf_nr_set; + p_api->qos_port_tx_buf_nr_get = shiva_qos_port_tx_buf_nr_get; + p_api->qos_port_rx_buf_nr_set = shiva_qos_port_rx_buf_nr_set; + p_api->qos_port_rx_buf_nr_get = shiva_qos_port_rx_buf_nr_get; + p_api->cosmap_up_queue_set = shiva_cosmap_up_queue_set; + p_api->cosmap_up_queue_get = shiva_cosmap_up_queue_get; + p_api->cosmap_dscp_queue_set = shiva_cosmap_dscp_queue_set; + p_api->cosmap_dscp_queue_get = shiva_cosmap_dscp_queue_get; + p_api->qos_port_mode_set = shiva_qos_port_mode_set; + p_api->qos_port_mode_get = shiva_qos_port_mode_get; + p_api->qos_port_mode_pri_set = shiva_qos_port_mode_pri_set; + p_api->qos_port_mode_pri_get = shiva_qos_port_mode_pri_get; + p_api->qos_port_default_up_set = shiva_qos_port_default_up_set; + p_api->qos_port_default_up_get = shiva_qos_port_default_up_get; + p_api->qos_port_sch_mode_set = shiva_qos_port_sch_mode_set; + p_api->qos_port_sch_mode_get = shiva_qos_port_sch_mode_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_rate.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_rate.c new file mode 100755 index 000000000..e6c64c023 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_rate.c @@ -0,0 +1,852 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup shiva_rate SHIVA_RATE + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "shiva_rate.h" +#include "shiva_reg.h" + +#define SHIVA_STORM_MIN_RATE_PPS 1000 +#define SHIVA_STORM_MAX_RATE_PPS (1024 * 1000) + +static sw_error_t +shiva_stormrate_sw_to_hw(a_uint32_t swrate, a_uint32_t * hwrate) +{ + a_uint32_t shrnr = 0; + a_uint32_t tmp = swrate / 1000; + + if ((SHIVA_STORM_MIN_RATE_PPS > swrate) + || (SHIVA_STORM_MAX_RATE_PPS < swrate)) + { + return SW_BAD_PARAM; + } + + while ((tmp != 0) && (shrnr < 12)) + { + tmp = tmp >> 1; + shrnr++; + } + + if (12 == shrnr) + { + return SW_BAD_PARAM; + } + + *hwrate = shrnr; + return SW_OK; +} + +static sw_error_t +shiva_stormrate_hw_to_sw(a_uint32_t hwrate, a_uint32_t * swrate) +{ + if (0 == hwrate) + { + hwrate = 1; + } + + if ((1 > hwrate) || (11 < hwrate)) + { + return SW_BAD_PARAM; + } + + *swrate = (1 << (hwrate - 1)) * 1000; + return SW_OK; +} + +static sw_error_t +_shiva_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; + a_uint32_t val; + a_uint32_t portrl = 0; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, RATE_LIMIT0, port_id, EG_RATE_EN, + (a_uint8_t *) (&portrl), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + if (1 == portrl) + { + /* already enable port egress rate limit, queue and port + egress rate limit can't coexist */ + return SW_NOT_SUPPORTED; + } + + if ((0x7ffe << 5) < *speed) + { + return SW_BAD_PARAM; + } + val = *speed >> 5; + *speed = val << 5; + } + else if (A_FALSE == enable) + { + val = 0x7fff; + *speed = 0; + if (1 == portrl) + { + /* already enable port egress rate limit */ + return SW_OK; + } + } + else + { + return SW_BAD_PARAM; + } + + if (0 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, RATE_LIMIT1, port_id, EG_Q0_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (1 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, RATE_LIMIT1, port_id, EG_Q1_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (2 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, RATE_LIMIT2, port_id, EG_Q2_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (3 == queue_id) + { + HSL_REG_FIELD_SET(rv, dev_id, RATE_LIMIT2, port_id, EG_Q3_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + + return rv; +} + +static sw_error_t +_shiva_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; + a_uint32_t val = 0; + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, RATE_LIMIT0, port_id, EG_RATE_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (1 == val) + { + /* already enable port egress rate limit */ + *speed = 0; + *enable = A_FALSE; + + return SW_OK; + } + + if (0 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, RATE_LIMIT1, port_id, EG_Q0_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (1 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, RATE_LIMIT1, port_id, EG_Q1_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (2 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, RATE_LIMIT2, port_id, EG_Q2_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else if (3 == queue_id) + { + HSL_REG_FIELD_GET(rv, dev_id, RATE_LIMIT2, port_id, EG_Q3_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_ERROR(rv); + + if (0x7fff == val) + { + *enable = A_FALSE; + } + else + { + *enable = A_TRUE; + *speed = val << 5; + } + + return SW_OK; +} + +static sw_error_t +_shiva_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; + a_uint32_t val = 0; + a_uint32_t portrl = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, RATE_LIMIT0, port_id, EG_RATE_EN, + (a_uint8_t *) (&portrl), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_FALSE == enable) + { + *speed = 0; + + /* if port egress rate limit current enable then disable */ + if (1 == portrl) + { + val = 0; + HSL_REG_FIELD_SET(rv, dev_id, RATE_LIMIT0, port_id, EG_RATE_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + val = 0x7fff; + HSL_REG_FIELD_SET(rv, dev_id, RATE_LIMIT2, port_id, EG_Q3_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + rv = SW_OK; + } + else + { + if ((0x7ffe << 5) < *speed) + { + return SW_BAD_PARAM; + } + + /* not enable egress port rate limit */ + if (0 == portrl) + { + HSL_REG_FIELD_GET(rv, dev_id, RATE_LIMIT1, port_id, EG_Q0_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0x7fff != val) + { + /* already enable egress queue0 rate limit, queue and port + egress rate limit can't coexist */ + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_GET(rv, dev_id, RATE_LIMIT1, port_id, EG_Q1_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0x7fff != val) + { + /* already enable egress queue1 rate limit, queue and port + egress rate limit can't coexist */ + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_GET(rv, dev_id, RATE_LIMIT2, port_id, EG_Q2_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0x7fff != val) + { + /* already enable egress queue2 rate limit, queue and port + egress rate limit can't coexist */ + return SW_NOT_SUPPORTED; + } + + HSL_REG_FIELD_GET(rv, dev_id, RATE_LIMIT2, port_id, EG_Q3_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0x7fff != val) + { + /* already enable egress queue3 rate limit, queue and port + egress rate limit can't coexist */ + return SW_NOT_SUPPORTED; + } + + val = 1; + HSL_REG_FIELD_SET(rv, dev_id, RATE_LIMIT0, port_id, EG_RATE_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + val = *speed >> 5; + *speed = val << 5; + HSL_REG_FIELD_SET(rv, dev_id, RATE_LIMIT2, port_id, EG_Q3_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + } + + return rv; +} + +static sw_error_t +_shiva_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; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, RATE_LIMIT0, port_id, EG_RATE_EN, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0 == val) + { + *speed = 0; + *enable = A_FALSE; + return SW_OK; + } + + HSL_REG_FIELD_GET(rv, dev_id, RATE_LIMIT2, port_id, EG_Q3_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + *enable = A_TRUE; + *speed = val << 5; + + return SW_OK; +} + +static sw_error_t +_shiva_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; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (A_TRUE == enable) + { + if ((0x7ffe << 5) < *speed) + { + return SW_BAD_PARAM; + } + val = *speed >> 5; + *speed = val << 5; + } + else if (A_FALSE == enable) + { + val = 0x7fff; + *speed = 0; + } + else + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, RATE_LIMIT0, port_id, ING_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_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; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, RATE_LIMIT0, port_id, ING_RATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0x7fff == val) + { + *enable = A_FALSE; + *speed = 0; + } + else + { + *enable = A_TRUE; + *speed = val << 5; + } + + return SW_OK; +} + +static sw_error_t +_shiva_storm_ctrl_frame_set(a_uint32_t dev_id, fal_port_t port_id, + fal_storm_type_t storm_type, a_bool_t enable) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + data = 2; + HSL_REG_FIELD_SET(rv, dev_id, STORM_CTL, port_id, UNIT, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (A_TRUE == enable) + { + data = 1; + } + else if (A_FALSE == enable) + { + data = 0; + } + else + { + return SW_BAD_PARAM; + } + + if (FAL_UNICAST_STORM == storm_type) + { + HSL_REG_FIELD_SET(rv, dev_id, STORM_CTL, port_id, UNI_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else if (FAL_MULTICAST_STORM == storm_type) + { + HSL_REG_FIELD_SET(rv, dev_id, STORM_CTL, port_id, MUL_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else if (FAL_BROADCAST_STORM == storm_type) + { + HSL_REG_FIELD_SET(rv, dev_id, STORM_CTL, port_id, BRO_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_GET(rv, dev_id, STORM_CTL, port_id, RATE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + if (0 == data) + { + data = 1; + HSL_REG_FIELD_SET(rv, dev_id, STORM_CTL, port_id, RATE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +static sw_error_t +_shiva_storm_ctrl_frame_get(a_uint32_t dev_id, fal_port_t port_id, + fal_storm_type_t storm_type, a_bool_t * enable) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + if (FAL_UNICAST_STORM == storm_type) + { + HSL_REG_FIELD_GET(rv, dev_id, STORM_CTL, port_id, UNI_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else if (FAL_MULTICAST_STORM == storm_type) + { + HSL_REG_FIELD_GET(rv, dev_id, STORM_CTL, port_id, MUL_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else if (FAL_BROADCAST_STORM == storm_type) + { + HSL_REG_FIELD_GET(rv, dev_id, STORM_CTL, port_id, BRO_EN, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + } + else + { + return SW_BAD_PARAM; + } + + SW_RTN_ON_ERROR(rv); + + if (1 == data) + { + data = 1; + *enable = A_TRUE; + } + else + { + *enable = A_FALSE; + } + + return SW_OK; +} + +static sw_error_t +_shiva_storm_ctrl_rate_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * rate_in_pps) +{ + a_uint32_t data; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + rv = shiva_stormrate_sw_to_hw(*rate_in_pps, &data); + SW_RTN_ON_ERROR(rv); + + HSL_REG_FIELD_SET(rv, dev_id, STORM_CTL, port_id, RATE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = shiva_stormrate_hw_to_sw(data, rate_in_pps); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +static sw_error_t +_shiva_storm_ctrl_rate_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * rate_in_pps) +{ + a_uint32_t data = 0; + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, STORM_CTL, port_id, RATE, + (a_uint8_t *) (&data), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = shiva_stormrate_hw_to_sw(data, rate_in_pps); + return rv; +} + +/** + * @brief Set queue egress rate limit status on one particular port and queue. + * @details Comments: + The granularity of speed is bps. + Because of hardware granularity function will return actual speed in hardware. + When disable queue egress rate limit input parameter speed is meaningless. + Egress queue rate limit can't coexist with port egress rate limit. + The step of speed is 32kbps. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param speed rate limit speed + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_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; + + HSL_API_LOCK; + rv = _shiva_rate_queue_egrl_set(dev_id, port_id, queue_id, speed, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get queue egress rate limit status on one particular port and queue. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] queue_id queue id + * @param[out] speed rate limit speed + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_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; + + HSL_API_LOCK; + rv = _shiva_rate_queue_egrl_get(dev_id, port_id, queue_id, speed, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set port egress rate limit status on one particular port. + * @details Comments: + The granularity of speed is bps. + Because of hardware granularity function will return actual speed in hardware. + When disable port egress rate limit input parameter speed is meaningless. + Egress port rate limit can't coexist with queue egress rate limit. + The step of speed is 32kbps. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param speed rate limit speed + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_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; + + HSL_API_LOCK; + rv = _shiva_rate_port_egrl_set(dev_id, port_id, speed, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get port egress rate limit status on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] speed rate limit speed + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_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; + + HSL_API_LOCK; + rv = _shiva_rate_port_egrl_get(dev_id, port_id, speed, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set port ingress rate limit status on one particular port. + * @details Comments: + The granularity of speed is bps. + Because of hardware granularity function will return actual speed in hardware. + When disable port ingress rate limit input parameter speed is meaningless. + The step of speed is 32kbps. + * When disable port ingress rate limit input parameter speed is meaningless. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param speed rate limit speed + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_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; + + HSL_API_LOCK; + rv = _shiva_rate_port_inrl_set(dev_id, port_id, speed, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get port ingress rate limit status on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] speed rate limit speed + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_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; + + HSL_API_LOCK; + rv = _shiva_rate_port_inrl_get(dev_id, port_id, speed, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set particular type storm control status on one particular port. + * @details Comments: + * When enable one particular packets type storm control this type packets + * speed will be calculated in storm control. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] frame_type packets type which causes storm + * @param[in] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_storm_ctrl_frame_set(a_uint32_t dev_id, fal_port_t port_id, + fal_storm_type_t storm_type, a_bool_t enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_storm_ctrl_frame_set(dev_id, port_id, storm_type, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get particular type storm control status on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[in] frame_type packets type which causes storm + * @param[out] enable A_TRUE or A_FALSE + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_storm_ctrl_frame_get(a_uint32_t dev_id, fal_port_t port_id, + fal_storm_type_t storm_type, a_bool_t * enable) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_storm_ctrl_frame_get(dev_id, port_id, storm_type, enable); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Set storm control speed on one particular port. + * @details Comments: + Because of hardware granularity function will return actual speed in hardware. + The step of speed is kpps. + The speed range is from 1k to 1M + * @param[in] dev_id device id + * @param[in] port_id port id + * @param speed storm control speed + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_storm_ctrl_rate_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * rate_in_pps) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_storm_ctrl_rate_set(dev_id, port_id, rate_in_pps); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get storm control speed on one particular port. + * @param[in] dev_id device id + * @param[in] port_id port id + * @param[out] speed storm control speed + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_storm_ctrl_rate_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * rate_in_pps) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_storm_ctrl_rate_get(dev_id, port_id, rate_in_pps); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +shiva_rate_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->rate_queue_egrl_set = shiva_rate_queue_egrl_set; + p_api->rate_queue_egrl_get = shiva_rate_queue_egrl_get; + p_api->rate_port_egrl_set = shiva_rate_port_egrl_set; + p_api->rate_port_egrl_get = shiva_rate_port_egrl_get; + p_api->rate_port_inrl_set = shiva_rate_port_inrl_set; + p_api->rate_port_inrl_get = shiva_rate_port_inrl_get; + p_api->storm_ctrl_frame_set = shiva_storm_ctrl_frame_set; + p_api->storm_ctrl_frame_get = shiva_storm_ctrl_frame_get; + p_api->storm_ctrl_rate_set = shiva_storm_ctrl_rate_set; + p_api->storm_ctrl_rate_get = shiva_storm_ctrl_rate_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_reduced_acl.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_reduced_acl.c new file mode 100755 index 000000000..eb0062980 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_reduced_acl.c @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 "shiva_reduced_acl.h" +#include "hsl.h" + +#define SHIVA_RULE_VLU_ADDR 0x58400 +#define SHIVA_RULE_MSK_ADDR 0x58c00 +#define SHIVA_RULE_LEN_ADDR 0x58818 +#define SHIVA_RULE_ACT_ADDR 0x58000 +#define SHIVA_RULE_SLCT_ADDR 0x58800 + +sw_error_t +shiva_acl_rule_write(a_uint32_t dev_id, a_uint32_t rule_idx, a_uint32_t vlu[8], + a_uint32_t msk[8]) +{ + sw_error_t rv; + a_uint32_t i, base, addr; + + /* set rule value */ + base = SHIVA_RULE_VLU_ADDR + (rule_idx << 5); + for (i = 0; i < 5; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(vlu[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + /* set rule mask */ + base = SHIVA_RULE_MSK_ADDR + (rule_idx << 5); + for (i = 0; i < 5; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(msk[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +sw_error_t +shiva_acl_action_write(a_uint32_t dev_id, a_uint32_t act_idx, + a_uint32_t act[3]) +{ + sw_error_t rv; + a_uint32_t base, addr, i; + + /* set rule action */ + base = SHIVA_RULE_ACT_ADDR + (act_idx << 5); + for (i = 0; i < 3; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(act[i])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +sw_error_t +shiva_acl_slct_write(a_uint32_t dev_id, a_uint32_t slct_idx, + a_uint32_t slct[8]) +{ + sw_error_t rv; + a_uint32_t base, addr; + a_uint32_t i; + + base = SHIVA_RULE_SLCT_ADDR + (slct_idx << 5); + + /* set rule address */ + for (i = 1; i < 7; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(slct[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + /* set rule enable */ + HSL_REG_ENTRY_GEN_SET(rv, dev_id, base, sizeof (a_uint32_t), + (a_uint8_t *) (&(slct[0])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + return SW_OK; +} + +sw_error_t +shiva_acl_rule_read(a_uint32_t dev_id, a_uint32_t rule_idx, a_uint32_t vlu[8], + a_uint32_t msk[8]) +{ + sw_error_t rv; + a_uint32_t i, base, addr; + + /* get rule value */ + base = SHIVA_RULE_VLU_ADDR + (rule_idx << 5); + for (i = 0; i < 5; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(vlu[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + /* get rule mask */ + base = SHIVA_RULE_MSK_ADDR + (rule_idx << 5); + for (i = 0; i < 5; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(msk[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +sw_error_t +shiva_acl_action_read(a_uint32_t dev_id, a_uint32_t act_idx, + a_uint32_t act[3]) +{ + sw_error_t rv; + a_uint32_t base, addr, i; + + /* get rule action */ + base = SHIVA_RULE_ACT_ADDR + (act_idx << 5); + for (i = 0; i < 3; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(act[i])), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} + +sw_error_t +shiva_acl_slct_read(a_uint32_t dev_id, a_uint32_t slct_idx, + a_uint32_t slct[8]) +{ + sw_error_t rv; + a_uint32_t i, base, addr; + + base = SHIVA_RULE_SLCT_ADDR + (slct_idx << 5); + + /* get filter address and enable */ + for (i = 0; i < 7; i++) + { + addr = base + (i << 2); + HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), + (a_uint8_t *) (&(slct[i])), + sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_reg_access.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_reg_access.c new file mode 100755 index 000000000..6a7f57fde --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_reg_access.c @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2012, 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. + */ + + +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "sd.h" +#include "shiva_reg_access.h" + +static hsl_access_mode reg_mode; + +#if defined(API_LOCK) +static aos_lock_t mdio_lock; +#define MDIO_LOCKER_INIT aos_lock_init(&mdio_lock) +#define MDIO_LOCKER_LOCK aos_lock(&mdio_lock) +#define MDIO_LOCKER_UNLOCK aos_unlock(&mdio_lock) +#else +#define MDIO_LOCKER_INIT +#define MDIO_LOCKER_LOCK +#define MDIO_LOCKER_UNLOCK +#endif + +static sw_error_t +_shiva_mdio_reg_get(a_uint32_t dev_id, a_uint32_t reg_addr, + a_uint8_t value[], a_uint32_t value_len) +{ + a_uint32_t reg_val; + + if (value_len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + +#if 0 + /* change reg_addr to 16-bit word address, 32-bit aligned */ + reg_word_addr = (reg_addr & 0xfffffffc) >> 1; + + /* configure register high address */ + phy_addr = 0x18; + phy_reg = 0x0; + phy_val = (a_uint16_t) ((reg_word_addr >> 8) & 0x3ff); /* bit16-8 of reg address */ + + rv = sd_reg_mdio_set(dev_id, phy_addr, phy_reg, phy_val); + SW_RTN_ON_ERROR(rv); + + /* For some registers such as MIBs, since it is read/clear, we should */ + /* read the lower 16-bit register then the higher one */ + + /* read register in lower address */ + phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */ + phy_reg = (a_uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */ + rv = sd_reg_mdio_get(dev_id, phy_addr, phy_reg, &tmp_val); + SW_RTN_ON_ERROR(rv); + reg_val = tmp_val; + + /* read register in higher address */ + reg_word_addr++; + phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */ + phy_reg = (a_uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */ + rv = sd_reg_mdio_get(dev_id, phy_addr, phy_reg, &tmp_val); + SW_RTN_ON_ERROR(rv); + reg_val |= (((a_uint32_t)tmp_val) << 16); +#else + reg_val = sd_reg_mii_get(dev_id, reg_addr); +#endif + aos_mem_copy(value, ®_val, sizeof (a_uint32_t)); + + return SW_OK; +} + +static sw_error_t +_shiva_mdio_reg_set(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t value[], + a_uint32_t value_len) +{ + a_uint32_t reg_val = 0; + + if (value_len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + + aos_mem_copy(®_val, value, sizeof (a_uint32_t)); + +#if 0 +/* change reg_addr to 16-bit word address, 32-bit aligned */ + reg_word_addr = (reg_addr & 0xfffffffc) >> 1; + + /* configure register high address */ + phy_addr = 0x18; + phy_reg = 0x0; + phy_val = (a_uint16_t) ((reg_word_addr >> 8) & 0x3ff); /* bit16-8 of reg address */ + + rv = sd_reg_mdio_set(dev_id, phy_addr, phy_reg, phy_val); + SW_RTN_ON_ERROR(rv); + + /* For some registers such as ARL and VLAN, since they include BUSY bit */ + /* in lower address, we should write the higher 16-bit register then the */ + /* lower one */ + + /* write register in higher address */ + reg_word_addr++; + phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */ + phy_reg = (a_uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */ + phy_val = (a_uint16_t) ((reg_val >> 16) & 0xffff); + rv = sd_reg_mdio_set(dev_id, phy_addr, phy_reg, phy_val); + SW_RTN_ON_ERROR(rv); + + /* write register in lower address */ + reg_word_addr--; + phy_addr = 0x10 | ((reg_word_addr >> 5) & 0x7); /* bit7-5 of reg address */ + phy_reg = (a_uint8_t) (reg_word_addr & 0x1f); /* bit4-0 of reg address */ + phy_val = (a_uint16_t) (reg_val & 0xffff); + rv = sd_reg_mdio_set(dev_id, phy_addr, phy_reg, phy_val); + SW_RTN_ON_ERROR(rv); +#else + sd_reg_mii_set(dev_id, reg_addr, reg_val); +#endif + + return SW_OK; +} + +sw_error_t +shiva_phy_get(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t * value) +{ + sw_error_t rv; + + MDIO_LOCKER_LOCK; + rv = sd_reg_mdio_get(dev_id, phy_addr, reg, value); + MDIO_LOCKER_UNLOCK; + + return rv; +} + +sw_error_t +shiva_phy_set(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t value) +{ + sw_error_t rv; + + MDIO_LOCKER_LOCK; + rv = sd_reg_mdio_set(dev_id, phy_addr, reg, value); + MDIO_LOCKER_UNLOCK; + + return rv; +} + +sw_error_t +shiva_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; + unsigned long flags; + + MDIO_LOCKER_LOCK; + if (HSL_MDIO == reg_mode) + { + aos_irq_save(flags); + rv = _shiva_mdio_reg_get(dev_id, reg_addr, value, value_len); + aos_irq_restore(flags); + } + else + { + rv = sd_reg_hdr_get(dev_id, reg_addr, value, value_len); + } + MDIO_LOCKER_UNLOCK; + + return rv; +} + +sw_error_t +shiva_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; + unsigned long flags; + + MDIO_LOCKER_LOCK; + if (HSL_MDIO == reg_mode) + { + aos_irq_save(flags); + rv = _shiva_mdio_reg_set(dev_id, reg_addr, value, value_len); + aos_irq_restore(flags); + } + else + { + rv = sd_reg_hdr_set(dev_id, reg_addr, value, value_len); + } + MDIO_LOCKER_UNLOCK; + + return rv; +} + +sw_error_t +shiva_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) +{ + a_uint32_t reg_val = 0; + + if ((bit_offset >= 32 || (field_len > 32)) || (field_len == 0)) + return SW_OUT_OF_RANGE; + + if (value_len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + + SW_RTN_ON_ERROR(shiva_reg_get(dev_id, reg_addr, (a_uint8_t *) & reg_val, sizeof (a_uint32_t))); + + *((a_uint32_t *) value) = SW_REG_2_FIELD(reg_val, bit_offset, field_len); + return SW_OK; +} + +sw_error_t +shiva_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) +{ + a_uint32_t reg_val = 0; + a_uint32_t field_val = *((a_uint32_t *) value); + + if ((bit_offset >= 32 || (field_len > 32)) || (field_len == 0)) + return SW_OUT_OF_RANGE; + + if (value_len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + + SW_RTN_ON_ERROR(shiva_reg_get(dev_id, reg_addr, (a_uint8_t *) & reg_val, sizeof (a_uint32_t))); + + SW_REG_SET_BY_FIELD_U32(reg_val, field_val, bit_offset, field_len); + + SW_RTN_ON_ERROR(shiva_reg_set(dev_id, reg_addr, (a_uint8_t *) & reg_val, sizeof (a_uint32_t))); + + return SW_OK; +} + +sw_error_t +shiva_reg_access_init(a_uint32_t dev_id, hsl_access_mode mode) +{ + hsl_api_t *p_api; + + MDIO_LOCKER_INIT; + reg_mode = mode; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + p_api->phy_get = shiva_phy_get; + p_api->phy_set = shiva_phy_set; + p_api->reg_get = shiva_reg_get; + p_api->reg_set = shiva_reg_set; + p_api->reg_field_get = shiva_reg_field_get; + p_api->reg_field_set = shiva_reg_field_set; + p_api->dev_access_set= shiva_access_mode_set; + + return SW_OK; +} + +sw_error_t +shiva_access_mode_set(a_uint32_t dev_id, hsl_access_mode mode) +{ + reg_mode = mode; + return SW_OK; + +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_stp.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_stp.c new file mode 100755 index 000000000..62c588ce2 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_stp.c @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2012, 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. + */ + + +/** + * @defgroup shiva_stp SHIVA_STP + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "shiva_stp.h" +#include "shiva_reg.h" + +#define SHIVA_PORT_DISABLED 0 +#define SHIVA_STP_BLOCKING 1 +#define SHIVA_STP_LISTENING 2 +#define SHIVA_STP_LEARNING 3 +#define SHIVA_STP_FARWARDING 4 + +static sw_error_t +_shiva_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; + a_uint32_t val; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_SINGLE_STP_ID != st_id) + { + return SW_BAD_PARAM; + } + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + switch (state) + { + case FAL_STP_BLOKING: + val = SHIVA_STP_BLOCKING; + break; + case FAL_STP_LISTENING: + val = SHIVA_STP_LISTENING; + break; + case FAL_STP_LEARNING: + val = SHIVA_STP_LEARNING; + break; + case FAL_STP_FARWARDING: + val = SHIVA_STP_FARWARDING; + break; + case FAL_STP_DISABLED: + val = SHIVA_PORT_DISABLED; + break; + default: + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_SET(rv, dev_id, PORT_CTL, port_id, PORT_STATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + return rv; +} + +static sw_error_t +_shiva_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; + a_uint32_t val = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if (FAL_SINGLE_STP_ID != st_id) + { + return SW_BAD_PARAM; + } + + if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_EXCL_CPU)) + { + return SW_BAD_PARAM; + } + + HSL_REG_FIELD_GET(rv, dev_id, PORT_CTL, port_id, PORT_STATE, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + switch (val) + { + case SHIVA_STP_BLOCKING: + *state = FAL_STP_BLOKING; + break; + case SHIVA_STP_LISTENING: + *state = FAL_STP_LISTENING; + break; + case SHIVA_STP_LEARNING: + *state = FAL_STP_LEARNING; + break; + case SHIVA_STP_FARWARDING: + *state = FAL_STP_FARWARDING; + break; + case SHIVA_PORT_DISABLED: + *state = FAL_STP_DISABLED; + break; + default: + return SW_FAIL; + } + + return SW_OK; +} + +/** + * @brief Set port stp state on a particular spanning tree and port. + * @details Comments: + SHIVA only support single spanning tree so st_id should be + FAL_SINGLE_STP_ID that is zero. + * @param[in] dev_id device id + * @param[in] st_id spanning tree id + * @param[in] port_id port id + * @param[in] state port state for spanning tree + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_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; + + HSL_API_LOCK; + rv = _shiva_stp_port_state_set(dev_id, st_id, port_id, state); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Get port stp state on a particular spanning tree and port. + * @details Comments: + SHIVA only support single spanning tree so st_id should be + FAL_SINGLE_STP_ID that is zero. + * @param[in] dev_id device id + * @param[in] st_id spanning tree id + * @param[in] port_id port id + * @param[out] state port state for spanning tree + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_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; + + HSL_API_LOCK; + rv = _shiva_stp_port_state_get(dev_id, st_id, port_id, state); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +shiva_stp_init(a_uint32_t dev_id) +{ + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + { + hsl_api_t *p_api; + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->stp_port_state_set = shiva_stp_port_state_set; + p_api->stp_port_state_get = shiva_stp_port_state_get; + } +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_vlan.c b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_vlan.c new file mode 100755 index 000000000..19dc70f9a --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/hsl/shiva/shiva_vlan.c @@ -0,0 +1,524 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 shiva_vlan SHIVA_VLAN + * @{ + */ +#include "sw.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_port_prop.h" +#include "shiva_vlan.h" +#include "shiva_reg.h" + +#define MAX_VLAN_ID 4095 + +#define VLAN_FLUSH 1 +#define VLAN_LOAD_ENTRY 2 +#define VLAN_PURGE_ENTRY 3 +#define VLAN_REMOVE_PORT 4 +#define VLAN_NEXT_ENTRY 5 +#define VLAN_FIND_ENTRY 6 + +static void +shiva_vlan_hw_to_sw(const a_uint32_t reg[], fal_vlan_t * vlan_entry) +{ + a_uint32_t data; + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC0, VT_PRI_EN, data, reg[0]); + if (1 == data) + { + vlan_entry->vid_pri_en = A_TRUE; + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC0, VT_PRI, data, reg[0]); + vlan_entry->vid_pri = data & 0xff; + } + else + { + vlan_entry->vid_pri_en = A_FALSE; + } + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC0, VLAN_ID, data, reg[0]); + vlan_entry->vid = data & 0xffff; + + SW_GET_FIELD_BY_REG(VLAN_TABLE_FUNC1, VID_MEM, data, reg[1]); + vlan_entry->mem_ports = data; + + return; +} + +static sw_error_t +shiva_vlan_sw_to_hw(const fal_vlan_t * vlan_entry, a_uint32_t reg[]) +{ + if (A_TRUE == vlan_entry->vid_pri_en) + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_PRI_EN, 1, reg[0]); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_PRI, vlan_entry->vid_pri, reg[0]); + } + else + { + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_PRI_EN, 0, reg[0]); + } + + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VLAN_ID, vlan_entry->vid, reg[0]); + + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC1, VT_VALID, 1, reg[1]); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC1, VID_MEM, vlan_entry->mem_ports, reg[1]); + + if (0 != vlan_entry->u_ports) + { + return SW_BAD_VALUE; + } + + return SW_OK; +} + +static sw_error_t +shiva_vlan_commit(a_uint32_t dev_id, a_uint32_t op) +{ + a_uint32_t vt_busy = 1, i = 0x1000, vt_full, val; + sw_error_t rv; + + while (vt_busy && --i) + { + HSL_REG_FIELD_GET(rv, dev_id, VLAN_TABLE_FUNC0, 0, VT_BUSY, + (a_uint8_t *) (&vt_busy), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + aos_udelay(5); + } + + if (i == 0) + return SW_BUSY; + + HSL_REG_ENTRY_GET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_FUNC, op, val); + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VT_BUSY, 1, val); + + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + vt_busy = 1; + i = 0x1000; + while (vt_busy && --i) + { + HSL_REG_FIELD_GET(rv, dev_id, VLAN_TABLE_FUNC0, 0, VT_BUSY, + (a_uint8_t *) (&vt_busy), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + aos_udelay(5); + } + + if (i == 0) + return SW_FAIL; + + HSL_REG_FIELD_GET(rv, dev_id, VLAN_TABLE_FUNC0, 0, VT_FULL_VIO, + (a_uint8_t *) (&vt_full), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (vt_full) + { + val = 0x10; + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + if (VLAN_LOAD_ENTRY == op) + { + return SW_OK; + } + else if (VLAN_PURGE_ENTRY == op) + { + return SW_NOT_FOUND; + } + } + + HSL_REG_FIELD_GET(rv, dev_id, VLAN_TABLE_FUNC1, 0, VT_VALID, + (a_uint8_t *) (&val), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + if (!val) + { + if (VLAN_FIND_ENTRY == op) + return SW_NOT_FOUND; + + if (VLAN_NEXT_ENTRY == op) + return SW_NO_MORE; + } + + return SW_OK; +} + +static sw_error_t +_shiva_vlan_entry_append(a_uint32_t dev_id, const fal_vlan_t * vlan_entry) +{ + sw_error_t rv; + a_uint32_t reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + if ((vlan_entry->vid == 0) || (vlan_entry->vid > MAX_VLAN_ID)) + return SW_OUT_OF_RANGE; + + if (A_FALSE == hsl_mports_prop_check(dev_id, vlan_entry->mem_ports, HSL_PP_INCL_CPU)) + return SW_BAD_PARAM; + + rv = shiva_vlan_sw_to_hw(vlan_entry, reg); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = shiva_vlan_commit(dev_id, VLAN_LOAD_ENTRY); + return rv; +} + +static sw_error_t +_shiva_vlan_create(a_uint32_t dev_id, a_uint32_t vlan_id) +{ + sw_error_t rv; + a_uint32_t entry = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if ((vlan_id == 0) || (vlan_id > MAX_VLAN_ID)) + return SW_OUT_OF_RANGE; + + /* set default value for VLAN_TABLE_FUNC0, all 0 except vid */ + entry = 0; + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VLAN_ID, vlan_id, entry); + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + /* set default value for VLAN_TABLE_FUNC1, all 0 */ + entry = 0; + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC1, VT_VALID, 1, entry); + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (&entry), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = shiva_vlan_commit(dev_id, VLAN_LOAD_ENTRY); + return rv; +} + +static sw_error_t +_shiva_vlan_next(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan) +{ + sw_error_t rv; + a_uint32_t reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + if (vlan_id > MAX_VLAN_ID) + return SW_OUT_OF_RANGE; + + aos_mem_zero(p_vlan, sizeof (fal_vlan_t)); + + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VLAN_ID, vlan_id, reg[0]); + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + rv = shiva_vlan_commit(dev_id, VLAN_NEXT_ENTRY); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + shiva_vlan_hw_to_sw(reg, p_vlan); + + if (0 == p_vlan->vid) + return SW_NO_MORE; + else + return SW_OK; +} + +static sw_error_t +_shiva_vlan_find(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan) +{ + sw_error_t rv; + a_uint32_t reg[2] = { 0 }; + + HSL_DEV_ID_CHECK(dev_id); + + if ((vlan_id == 0) || (vlan_id > MAX_VLAN_ID)) + return SW_OUT_OF_RANGE; + + aos_mem_zero(p_vlan, sizeof (fal_vlan_t)); + + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VLAN_ID, vlan_id, reg[0]); + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + rv = shiva_vlan_commit(dev_id, VLAN_FIND_ENTRY); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + HSL_REG_ENTRY_GET(rv, dev_id, VLAN_TABLE_FUNC1, 0, + (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + shiva_vlan_hw_to_sw(reg, p_vlan); + + return SW_OK; +} + +static sw_error_t +_shiva_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; + a_uint32_t reg = 0; + + HSL_DEV_ID_CHECK(dev_id); + + if ((vlan_id == 0) || (vlan_id > MAX_VLAN_ID)) + return SW_OUT_OF_RANGE; + + if (A_FALSE == hsl_mports_prop_check(dev_id, member, HSL_PP_INCL_CPU)) + return SW_BAD_PARAM; + + if (u_member != 0) + return SW_BAD_PARAM; + + /* get vlan entry first */ + SW_SET_REG_BY_FIELD(VLAN_TABLE_FUNC0, VLAN_ID, vlan_id, reg); + HSL_REG_ENTRY_SET(rv, dev_id, VLAN_TABLE_FUNC0, 0, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + + SW_RTN_ON_ERROR(rv); + + rv = shiva_vlan_commit(dev_id, VLAN_FIND_ENTRY); + SW_RTN_ON_ERROR(rv); + + /* set vlan member for VLAN_TABLE_FUNC1 */ + HSL_REG_FIELD_SET(rv, dev_id, VLAN_TABLE_FUNC1, 0, VID_MEM, + (a_uint8_t *) (&member), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = shiva_vlan_commit(dev_id, VLAN_LOAD_ENTRY); + /* when update port member through LOAD opration, hardware will + return VT_FULL_VIO, we should ignore it */ + if (SW_FULL == rv) + rv = SW_OK; + + return rv; +} + +static sw_error_t +_shiva_vlan_delete(a_uint32_t dev_id, a_uint32_t vlan_id) +{ + sw_error_t rv; + a_uint32_t reg; + + HSL_DEV_ID_CHECK(dev_id); + + if ((vlan_id == 0) || (vlan_id > MAX_VLAN_ID)) + return SW_OUT_OF_RANGE; + + reg = (a_int32_t) vlan_id; + HSL_REG_FIELD_SET(rv, dev_id, VLAN_TABLE_FUNC0, 0, VLAN_ID, + (a_uint8_t *) (®), sizeof (a_uint32_t)); + SW_RTN_ON_ERROR(rv); + + rv = shiva_vlan_commit(dev_id, VLAN_PURGE_ENTRY); + return rv; +} + +static sw_error_t +_shiva_vlan_flush(a_uint32_t dev_id) +{ + sw_error_t rv; + + HSL_DEV_ID_CHECK(dev_id); + rv = shiva_vlan_commit(dev_id, VLAN_FLUSH); + return rv; +} + +/** + * @brief Append a vlan entry on paticular device. + * @param[in] dev_id device id + * @param[in] vlan_entry vlan entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_vlan_entry_append(a_uint32_t dev_id, const fal_vlan_t * vlan_entry) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_vlan_entry_append(dev_id, vlan_entry); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Creat a vlan entry through vlan id on a paticular device. + * @details Comments: + * After this operation the member ports of the created vlan entry are null. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_vlan_create(a_uint32_t dev_id, a_uint32_t vlan_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_vlan_create(dev_id, vlan_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Next a vlan entry through vlan id on a paticular device. + * @details Comments: + * If the value of vid is zero this operation will get the first entry. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[out] p_vlan vlan entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_vlan_next(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_vlan_next(dev_id, vlan_id, p_vlan); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Find a vlan entry through vlan id on paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[out] p_vlan vlan entry + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_vlan_find(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_vlan_find(dev_id, vlan_id, p_vlan); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Update a vlan entry member port through vlan id on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @param[in] member member ports + * @param[in] u_member tagged or untagged infomation for member ports + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_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; + + HSL_API_LOCK; + rv = _shiva_vlan_member_update(dev_id, vlan_id, member, u_member); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Delete a vlan entry through vlan id on a paticular device. + * @param[in] dev_id device id + * @param[in] vlan_id vlan id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_vlan_delete(a_uint32_t dev_id, a_uint32_t vlan_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_vlan_delete(dev_id, vlan_id); + HSL_API_UNLOCK; + return rv; +} + +/** + * @brief Flush all vlan entries on a paticular device. + * @param[in] dev_id device id + * @return SW_OK or error code + */ +HSL_LOCAL sw_error_t +shiva_vlan_flush(a_uint32_t dev_id) +{ + sw_error_t rv; + + HSL_API_LOCK; + rv = _shiva_vlan_flush(dev_id); + HSL_API_UNLOCK; + return rv; +} + +sw_error_t +shiva_vlan_init(a_uint32_t dev_id) +{ + hsl_api_t *p_api; + HSL_DEV_ID_CHECK(dev_id); + +#ifndef HSL_STANDALONG + + SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); + + p_api->vlan_entry_append = shiva_vlan_entry_append; + p_api->vlan_creat = shiva_vlan_create; + p_api->vlan_member_update = shiva_vlan_member_update; + p_api->vlan_delete = shiva_vlan_delete; + p_api->vlan_next = shiva_vlan_next; + p_api->vlan_find = shiva_vlan_find; + p_api->vlan_flush = shiva_vlan_flush; + +#endif + + return SW_OK; +} + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/init/Makefile b/feeds/ipq807x/qca-ssdk/src/src/init/Makefile new file mode 100644 index 000000000..e54dd0654 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/init/Makefile @@ -0,0 +1,40 @@ +LOC_DIR=src/init +LIB=INIT + +include $(PRJ_PATH)/make/config.mk + +SRC_LIST=ssdk_init.c ssdk_plat.c ssdk_interrupt.c ssdk_dts.c + +ifneq (ISISC, $(CHIP_TYPE)) + SRC_LIST += ssdk_clk.c +endif + +ifeq (TRUE, $(IN_LED)) + SRC_LIST += ssdk_led.c +endif + +ifeq (TRUE, $(IN_PHY_I2C_MODE)) + SRC_LIST += ssdk_phy_i2c.c +endif + +ifneq (,$(findstring HPPE, $(SUPPORT_CHIP))) + SRC_LIST += ssdk_hppe.c +endif + +ifneq (,$(findstring SCOMPHY, $(SUPPORT_CHIP))) + SRC_LIST += ssdk_scomphy.c +endif + +ifneq (,$(filter MP, $(SUPPORT_CHIP))) + SRC_LIST += ssdk_mp.c +endif + +ifeq (TRUE, $(SWCONFIG)) + SRC_LIST += ssdk_uci.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/src/src/init/ssdk_clk.c b/feeds/ipq807x/qca-ssdk/src/src/init/ssdk_clk.c new file mode 100755 index 000000000..7d099f328 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/init/ssdk_clk.c @@ -0,0 +1,1207 @@ +/* + * 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 "sw.h" +#include "ssdk_init.h" +#include "ssdk_plat.h" +#include "ssdk_clk.h" +#include "ssdk_dts.h" +#if defined(HPPE) +#include "adpt_hppe.h" +#endif +#include "fal.h" +#include +#include +#include +#include +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) +#include +#include +#include +#include +#include +#endif + +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) +struct device_node *clock_node = NULL; +static struct clk *uniphy_port_clks[UNIPHYT_CLK_MAX] = {0}; + +struct device_node *rst_node = NULL; +struct reset_control *uniphy_rsts[UNIPHY_RST_MAX] = {0}; +struct reset_control *port_rsts[SSDK_MAX_PORT_NUM] = {0}; + +/* below 3 routines to be used as common */ +void ssdk_clock_rate_set_and_enable( + struct device_node *node, a_uint8_t* clock_id, a_uint32_t rate) +{ + struct clk *clk; + + if(ssdk_is_emulation(0)){ + SSDK_INFO("clock_id %s rate %d on emulation platform\n",clock_id, rate); + return; + } + + clk = of_clk_get_by_name(node, clock_id); + if (!IS_ERR(clk)) { + if (rate) + clk_set_rate(clk, rate); + + clk_prepare_enable(clk); + } +} + +void ssdk_gcc_reset(struct reset_control *rst, a_uint32_t action) +{ + if(ssdk_is_emulation(0)){ + SSDK_INFO("action %d on emulation platform\n",action); + return; + } + + if (action == SSDK_RESET_ASSERT) + reset_control_assert(rst); + else + reset_control_deassert(rst); + +} +#endif + +void ssdk_uniphy_reset( + a_uint32_t dev_id, + enum unphy_rst_type rst_type, + a_uint32_t action) +{ +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) + struct reset_control *rst; + + rst = uniphy_rsts[rst_type]; + if (IS_ERR(rst)) { + SSDK_ERROR("reset(%d) nof exist!\n", rst_type); + return; + } + + ssdk_gcc_reset(rst, action); +#endif + +} + +void ssdk_port_reset( + a_uint32_t dev_id, + a_uint32_t port_id, + a_uint32_t action) +{ +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) + struct reset_control *rst; + + if ((port_id < SSDK_PHYSICAL_PORT1) || (port_id > SSDK_PHYSICAL_PORT6)) + return; + + rst = port_rsts[port_id-1]; + if (IS_ERR(rst)) { + SSDK_ERROR("reset(%d) not exist!\n", port_id); + return; + } + + ssdk_gcc_reset(rst, action); +#endif + +} + +void ssdk_uniphy_clock_rate_set( + a_uint32_t dev_id, + enum unphy_clk_type clock_type, + a_uint32_t rate) +{ +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) + struct clk *uniphy_clk; + + if(ssdk_is_emulation(dev_id)){ + SSDK_INFO("clock_type %d rate %d on emulation platform\n", + clock_type, rate); + return; + } + + uniphy_clk = uniphy_port_clks[clock_type]; + if (!IS_ERR(uniphy_clk)) { + if (rate) + if (clk_set_rate(uniphy_clk, rate)) + SSDK_INFO("%d set rate=%d fail\n", clock_type, rate); + } else + SSDK_INFO("%d set rate %x fail!\n", clock_type, rate); +#endif + +} + +void ssdk_uniphy_clock_enable( + a_uint32_t dev_id, + enum unphy_clk_type clock_type, + a_bool_t enable) +{ +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) + struct clk *uniphy_clk; + + if(ssdk_is_emulation(dev_id)){ + SSDK_INFO("clock_type %d enable %d on emulation platform\n", + clock_type, enable); + return; + } + + uniphy_clk = uniphy_port_clks[clock_type]; + if (!IS_ERR(uniphy_clk)) { + if (enable) { + if (clk_prepare_enable(uniphy_clk)) + SSDK_ERROR("clock enable fail!\n"); + } else + clk_disable_unprepare(uniphy_clk); + } else { + SSDK_DEBUG("clock_type= %d enable=%d not find\n", + clock_type, enable); + } +#endif + +} + +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) +#if defined(HPPE) || defined(MP) +struct clk_uniphy { + struct clk_hw hw; + u8 uniphy_index; + u8 dir; + unsigned long rate; +}; + +#define to_clk_uniphy(_hw) container_of(_hw, struct clk_uniphy, hw) + +static unsigned long +uniphy_clks_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) +{ + struct clk_uniphy *uniphy = to_clk_uniphy(hw); + + return uniphy->rate; +} + +static int +uniphy_clks_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) +{ + /* add logic for checking the current mode */ + if (req->rate <= UNIPHY_CLK_RATE_125M) + req->rate = UNIPHY_CLK_RATE_125M; + else + req->rate = UNIPHY_CLK_RATE_312M; + + return 0; +} + +static int +uniphy_clks_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_uniphy *uniphy = to_clk_uniphy(hw); + + if (rate != UNIPHY_CLK_RATE_125M && rate != UNIPHY_CLK_RATE_312M) + return -1; + + uniphy->rate = rate; + + return 0; +} + +static const struct clk_ops clk_uniphy_ops = { + .recalc_rate = uniphy_clks_recalc_rate, + .determine_rate = uniphy_clks_determine_rate, + .set_rate = uniphy_clks_set_rate, +}; +#endif + +#if defined(HPPE) + +static struct clk_uniphy uniphy0_gcc_rx_clk = { + .hw.init = &(struct clk_init_data){ + .name = "uniphy0_gcc_rx_clk", + .ops = &clk_uniphy_ops, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,9,0)) + .flags = CLK_IS_ROOT, +#endif + }, + .uniphy_index = 0, + .dir = UNIPHY_RX, + .rate = UNIPHY_DEFAULT_RATE, +}; + +static struct clk_uniphy uniphy0_gcc_tx_clk = { + .hw.init = &(struct clk_init_data){ + .name = "uniphy0_gcc_tx_clk", + .ops = &clk_uniphy_ops, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,9,0)) + .flags = CLK_IS_ROOT, +#endif + }, + .uniphy_index = 0, + .dir = UNIPHY_TX, + .rate = UNIPHY_DEFAULT_RATE, +}; + +static struct clk_uniphy uniphy1_gcc_rx_clk = { + .hw.init = &(struct clk_init_data){ + .name = "uniphy1_gcc_rx_clk", + .ops = &clk_uniphy_ops, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,9,0)) + .flags = CLK_IS_ROOT, +#endif + }, + .uniphy_index = 1, + .dir = UNIPHY_RX, + .rate = UNIPHY_DEFAULT_RATE, +}; + +static struct clk_uniphy uniphy1_gcc_tx_clk = { + .hw.init = &(struct clk_init_data){ + .name = "uniphy1_gcc_tx_clk", + .ops = &clk_uniphy_ops, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,9,0)) + .flags = CLK_IS_ROOT, +#endif + }, + .uniphy_index = 1, + .dir = UNIPHY_TX, + .rate = UNIPHY_DEFAULT_RATE, +}; + +static struct clk_uniphy uniphy2_gcc_rx_clk = { + .hw.init = &(struct clk_init_data){ + .name = "uniphy2_gcc_rx_clk", + .ops = &clk_uniphy_ops, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,9,0)) + .flags = CLK_IS_ROOT, +#endif + }, + .uniphy_index = 2, + .dir = UNIPHY_RX, + .rate = UNIPHY_DEFAULT_RATE, +}; + +static struct clk_uniphy uniphy2_gcc_tx_clk = { + .hw.init = &(struct clk_init_data){ + .name = "uniphy2_gcc_tx_clk", + .ops = &clk_uniphy_ops, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,9,0)) + .flags = CLK_IS_ROOT, +#endif + }, + .uniphy_index = 2, + .dir = UNIPHY_TX, + .rate = UNIPHY_DEFAULT_RATE, +}; + +static struct clk_hw *uniphy_raw_clks[SSDK_MAX_UNIPHY_INSTANCE * 2] = { + &uniphy0_gcc_rx_clk.hw, &uniphy0_gcc_tx_clk.hw, + &uniphy1_gcc_rx_clk.hw, &uniphy1_gcc_tx_clk.hw, + &uniphy2_gcc_rx_clk.hw, &uniphy2_gcc_tx_clk.hw, +}; + +static char *ppe_clk_ids[UNIPHYT_CLK_MAX] = { + NSS_PORT1_RX_CLK, + NSS_PORT1_TX_CLK, + NSS_PORT2_RX_CLK, + NSS_PORT2_TX_CLK, + NSS_PORT3_RX_CLK, + NSS_PORT3_TX_CLK, + NSS_PORT4_RX_CLK, + NSS_PORT4_TX_CLK, + NSS_PORT5_RX_CLK, + NSS_PORT5_TX_CLK, + NSS_PORT6_RX_CLK, + NSS_PORT6_TX_CLK, + UNIPHY0_PORT1_RX_CLK, + UNIPHY0_PORT1_TX_CLK, + UNIPHY0_PORT2_RX_CLK, + UNIPHY0_PORT2_TX_CLK, + UNIPHY0_PORT3_RX_CLK, + UNIPHY0_PORT3_TX_CLK, + UNIPHY0_PORT4_RX_CLK, + UNIPHY0_PORT4_TX_CLK, + UNIPHY0_PORT5_RX_CLK, + UNIPHY0_PORT5_TX_CLK, + UNIPHY1_PORT5_RX_CLK, + UNIPHY1_PORT5_TX_CLK, + UNIPHY2_PORT6_RX_CLK, + UNIPHY2_PORT6_TX_CLK, + PORT5_RX_SRC, + PORT5_TX_SRC +}; + +static void ssdk_ppe_uniphy_clock_init(a_uint32_t revision) +{ + a_uint32_t i, inst_num; + struct clk *clk; + + if (revision == HPPE_REVISION) { + inst_num = SSDK_MAX_UNIPHY_INSTANCE; + } else { + inst_num = SSDK_MAX_UNIPHY_INSTANCE - 1; + } + + for (i = 0; i < inst_num * 2; i++) { + clk = clk_register(NULL, uniphy_raw_clks[i]); + if (IS_ERR(clk)) + SSDK_ERROR("Clk register %d fail!\n", i); + } + + for (i = NSS_PORT1_RX_CLK_E; i < UNIPHYT_CLK_MAX; i++) + uniphy_port_clks[i] = of_clk_get_by_name(clock_node, + ppe_clk_ids[i]); + + /* enable uniphy and mac clock */ + for (i = NSS_PORT1_RX_CLK_E; i < PORT5_RX_SRC_E; i++) + ssdk_uniphy_clock_enable(0, i, A_TRUE); +} + +static void ssdk_ppe_fixed_clock_init(a_uint32_t revision) +{ + /* AHB and sys clk */ + ssdk_clock_rate_set_and_enable(clock_node, CMN_AHB_CLK, 0); + ssdk_clock_rate_set_and_enable(clock_node, CMN_SYS_CLK, 0); + ssdk_clock_rate_set_and_enable(clock_node, UNIPHY0_AHB_CLK, + UNIPHY_AHB_CLK_RATE); + if (revision == HPPE_REVISION) { + ssdk_clock_rate_set_and_enable(clock_node, + UNIPHY0_SYS_CLK, + UNIPHY_SYS_CLK_RATE); + } else { + ssdk_clock_rate_set_and_enable(clock_node, + UNIPHY0_SYS_CLK, + CPPE_UNIPHY_SYS_CLK_RATE); + } + ssdk_clock_rate_set_and_enable(clock_node, UNIPHY1_AHB_CLK, + UNIPHY_AHB_CLK_RATE); + if (revision == HPPE_REVISION) { + ssdk_clock_rate_set_and_enable(clock_node, + UNIPHY1_SYS_CLK, + UNIPHY_SYS_CLK_RATE); + } else { + ssdk_clock_rate_set_and_enable(clock_node, + UNIPHY1_SYS_CLK, + CPPE_UNIPHY_SYS_CLK_RATE); + } + if (revision == HPPE_REVISION) { + ssdk_clock_rate_set_and_enable(clock_node, + UNIPHY2_AHB_CLK, + UNIPHY_AHB_CLK_RATE); + ssdk_clock_rate_set_and_enable(clock_node, + UNIPHY2_SYS_CLK, + UNIPHY_SYS_CLK_RATE); + } + + /* ppe related fixed clock init */ + ssdk_clock_rate_set_and_enable(clock_node, + PORT1_MAC_CLK, PPE_CLK_RATE); + ssdk_clock_rate_set_and_enable(clock_node, + PORT2_MAC_CLK, PPE_CLK_RATE); + ssdk_clock_rate_set_and_enable(clock_node, + PORT3_MAC_CLK, PPE_CLK_RATE); + ssdk_clock_rate_set_and_enable(clock_node, + PORT4_MAC_CLK, PPE_CLK_RATE); + ssdk_clock_rate_set_and_enable(clock_node, + PORT5_MAC_CLK, PPE_CLK_RATE); + if (revision == HPPE_REVISION) { + ssdk_clock_rate_set_and_enable(clock_node, + PORT6_MAC_CLK, PPE_CLK_RATE); + } + ssdk_clock_rate_set_and_enable(clock_node, + NSS_PPE_CLK, PPE_CLK_RATE); + ssdk_clock_rate_set_and_enable(clock_node, + NSS_PPE_CFG_CLK, PPE_CLK_RATE); + ssdk_clock_rate_set_and_enable(clock_node, + NSSNOC_PPE_CLK, PPE_CLK_RATE); + ssdk_clock_rate_set_and_enable(clock_node, + NSSNOC_PPE_CFG_CLK, PPE_CLK_RATE); + ssdk_clock_rate_set_and_enable(clock_node, + NSS_EDMA_CLK, PPE_CLK_RATE); + ssdk_clock_rate_set_and_enable(clock_node, + NSS_EDMA_CFG_CLK, PPE_CLK_RATE); + ssdk_clock_rate_set_and_enable(clock_node, + NSS_PPE_IPE_CLK, PPE_CLK_RATE); + if (revision == HPPE_REVISION) { + ssdk_clock_rate_set_and_enable(clock_node, + NSS_PPE_BTQ_CLK, PPE_CLK_RATE); + } + ssdk_clock_rate_set_and_enable(clock_node, + MDIO_AHB_CLK, MDIO_AHB_RATE); + if (revision == HPPE_REVISION) { + ssdk_clock_rate_set_and_enable(clock_node, + NSSNOC_CLK, NSS_NOC_RATE); + } else { + ssdk_clock_rate_set_and_enable(clock_node, + NSSNOC_CLK, NSSNOC_SNOC_RATE); + } + ssdk_clock_rate_set_and_enable(clock_node, + NSSNOC_SNOC_CLK, NSSNOC_SNOC_RATE); + if (revision == HPPE_REVISION) { + ssdk_clock_rate_set_and_enable(clock_node, + MEM_NOC_NSSAXI_CLK, NSS_AXI_RATE); + } + ssdk_clock_rate_set_and_enable(clock_node, + CRYPTO_PPE_CLK, PPE_CLK_RATE); + if (revision == HPPE_REVISION) { + ssdk_clock_rate_set_and_enable(clock_node, + NSS_IMEM_CLK, NSS_IMEM_RATE); + } + ssdk_clock_rate_set_and_enable(clock_node, + NSS_PTP_REF_CLK, PTP_REF_RARE); + if (revision == CPPE_REVISION) { + ssdk_clock_rate_set_and_enable(clock_node, + SNOC_NSSNOC_CLK, NSSNOC_SNOC_RATE); + } +} +#endif + +#if defined(MP) +#define TCSR_ETH_ADDR 0x19475C4 +#define TCSR_ETH_SIZE 4 +#define ETH_LDO_RDY 0x1 +#define CMN_PLL_LOCKED_ADDR 0x9B064 +#define CMN_PLL_LOCKED_SIZE 4 +#define CMN_PLL_LOCKED 4 +#define MP_RAW_CLOCK_INSTANCE 2 + +static char *mp_rst_ids[MP_BCR_RST_MAX] = { + GEHPY_BCR_RESET_ID, + UNIPHY_BCR_RESET_ID, + GMAC0_BCR_RESET_ID, + GMAC1_BCR_RESET_ID, + GEPHY_MISC_RESET_ID +}; + +static struct clk_uniphy gephy_gcc_rx_clk = { + .hw.init = &(struct clk_init_data){ + .name = "gephy_gcc_rx", + .ops = &clk_uniphy_ops, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,9,0)) + .flags = CLK_IS_ROOT, +#endif + }, + .uniphy_index = 0, + .dir = UNIPHY_RX, + .rate = UNIPHY_DEFAULT_RATE, +}; + +static struct clk_uniphy gephy_gcc_tx_clk = { + .hw.init = &(struct clk_init_data){ + .name = "gephy_gcc_tx", + .ops = &clk_uniphy_ops, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,9,0)) + .flags = CLK_IS_ROOT, +#endif + }, + .uniphy_index = 0, + .dir = UNIPHY_TX, + .rate = UNIPHY_DEFAULT_RATE, +}; + +static struct clk_uniphy uniphy_gcc_rx_clk = { + .hw.init = &(struct clk_init_data){ + .name = "uniphy_gcc_rx", + .ops = &clk_uniphy_ops, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,9,0)) + .flags = CLK_IS_ROOT, +#endif + }, + .uniphy_index = 1, + .dir = UNIPHY_RX, + .rate = UNIPHY_DEFAULT_RATE, +}; + +static struct clk_uniphy uniphy_gcc_tx_clk = { + .hw.init = &(struct clk_init_data){ + .name = "uniphy_gcc_tx", + .ops = &clk_uniphy_ops, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,9,0)) + .flags = CLK_IS_ROOT, +#endif + }, + .uniphy_index = 1, + .dir = UNIPHY_TX, + .rate = UNIPHY_DEFAULT_RATE, +}; + +static struct clk_hw *mp_raw_clks[MP_RAW_CLOCK_INSTANCE * 2] = { + &gephy_gcc_rx_clk.hw, &gephy_gcc_tx_clk.hw, + &uniphy_gcc_rx_clk.hw, &uniphy_gcc_tx_clk.hw, +}; + +static void ssdk_mp_fixed_clock_init(void) +{ + ssdk_clock_rate_set_and_enable(clock_node, CMN_AHB_CLK, 0); + ssdk_clock_rate_set_and_enable(clock_node, CMN_SYS_CLK, 0); + ssdk_clock_rate_set_and_enable(clock_node, UNIPHY_AHB_CLK, + UNIPHY_AHB_CLK_RATE); + ssdk_clock_rate_set_and_enable(clock_node, + UNIPHY_SYS_CLK, + MP_UNIPHY_SYS_CLK_RATE); + ssdk_clock_rate_set_and_enable(clock_node, + MDIO0_AHB_CLK, MDIO_AHB_RATE); + ssdk_clock_rate_set_and_enable(clock_node, + MDIO1_AHB_CLK, MDIO_AHB_RATE); + ssdk_clock_rate_set_and_enable(clock_node, + GMAC0_CFG_CLK, GMAC_CLK_RATE); + ssdk_clock_rate_set_and_enable(clock_node, + GMAC0_SYS_CLK, GMAC_CLK_RATE); + ssdk_clock_rate_set_and_enable(clock_node, + GMAC1_CFG_CLK, GMAC_CLK_RATE); + ssdk_clock_rate_set_and_enable(clock_node, + GMAC1_SYS_CLK, GMAC_CLK_RATE); + ssdk_clock_rate_set_and_enable(clock_node, + GMAC0_PTP_CLK, GMAC_CLK_RATE); + ssdk_clock_rate_set_and_enable(clock_node, + GMAC1_PTP_CLK, GMAC_CLK_RATE); + ssdk_clock_rate_set_and_enable(clock_node, + SNOC_GMAC0_AHB_CLK, GMAC_CLK_RATE); + ssdk_clock_rate_set_and_enable(clock_node, + SNOC_GMAC1_AHB_CLK, GMAC_CLK_RATE); +} + +static void ssdk_mp_uniphy_clock_init(void) +{ + a_uint32_t i, inst_num; + struct clk *clk; + struct clk **ports; + + inst_num = sizeof(mp_raw_clks) / sizeof(struct clk_hw *); + + for (i = 0; i < inst_num; i++) { + clk = clk_register(NULL, mp_raw_clks[i]); + if (IS_ERR(clk)) + SSDK_ERROR("Clk register %d fail!\n", i); + } + + ports = uniphy_port_clks; + ports[NSS_PORT1_RX_CLK_E] = of_clk_get_by_name(clock_node, + NSS_PORT1_RX_CLK); + ports[NSS_PORT1_TX_CLK_E] = of_clk_get_by_name(clock_node, + NSS_PORT1_TX_CLK); + ports[NSS_PORT2_RX_CLK_E] = of_clk_get_by_name(clock_node, + NSS_PORT2_RX_CLK); + ports[NSS_PORT2_TX_CLK_E] = of_clk_get_by_name(clock_node, + NSS_PORT2_TX_CLK); + ports[UNIPHY0_PORT1_RX_CLK_E] = of_clk_get_by_name(clock_node, + UNIPHY0_PORT1_RX_CLK); + ports[UNIPHY0_PORT1_TX_CLK_E] = of_clk_get_by_name(clock_node, + UNIPHY0_PORT1_TX_CLK); + ports[UNIPHY1_PORT5_RX_CLK_E] = of_clk_get_by_name(clock_node, + UNIPHY1_PORT5_RX_CLK); + ports[UNIPHY1_PORT5_TX_CLK_E] = of_clk_get_by_name(clock_node, + UNIPHY1_PORT5_TX_CLK); +} + +static void ssdk_mp_uniphy_clock_enable(void) +{ + ssdk_uniphy_clock_enable(0, NSS_PORT1_RX_CLK_E, A_TRUE); + ssdk_uniphy_clock_enable(0, NSS_PORT1_TX_CLK_E, A_TRUE); + ssdk_uniphy_clock_enable(0, NSS_PORT2_RX_CLK_E, A_TRUE); + ssdk_uniphy_clock_enable(0, NSS_PORT2_TX_CLK_E, A_TRUE); + ssdk_uniphy_clock_enable(0, UNIPHY0_PORT1_RX_CLK_E, A_TRUE); + ssdk_uniphy_clock_enable(0, UNIPHY0_PORT1_TX_CLK_E, A_TRUE); + ssdk_uniphy_clock_enable(0, UNIPHY1_PORT5_RX_CLK_E, A_TRUE); + ssdk_uniphy_clock_enable(0, UNIPHY1_PORT5_TX_CLK_E, A_TRUE); +} + +static void +ssdk_mp_cmnblk_enable(void) +{ + void __iomem *tcsr_eth = NULL; + a_uint32_t reg_val; + + tcsr_eth = ioremap_nocache(TCSR_ETH_ADDR, TCSR_ETH_SIZE); + if (!tcsr_eth) { + SSDK_ERROR("Failed to map tcsr eth address!\n"); + return; + } + + reg_val = readl(tcsr_eth); + reg_val |= ETH_LDO_RDY; + writel(reg_val, tcsr_eth); + + iounmap(tcsr_eth); +} + +static a_bool_t +ssdk_mp_cmnblk_stable_check(void) +{ + void __iomem *pll_lock = NULL; + a_uint32_t reg_val; + int i, loops = 20; + + pll_lock = ioremap_nocache(CMN_PLL_LOCKED_ADDR, CMN_PLL_LOCKED_SIZE); + if (!pll_lock) { + SSDK_ERROR("Failed to map CMN PLL LOCK register!\n"); + return A_FALSE; + } + + for (i = 0; i < loops; i++) { + reg_val = readl(pll_lock); + if (reg_val & CMN_PLL_LOCKED) { + break; + } + msleep(10); + } + + iounmap(pll_lock); + + if (i >= loops) { + return A_FALSE; + } else { + return A_TRUE; + } +} + +static void +ssdk_mp_reset_init(void) +{ +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) + struct reset_control *rst; + a_uint32_t i; + + rst_node = of_find_node_by_name(NULL, "ess-switch"); + + for (i = 0; i < MP_BCR_RST_MAX; i++) { + rst = of_reset_control_get(rst_node, mp_rst_ids[i]); + if (IS_ERR(rst)) { + SSDK_ERROR("%s not exist!\n", mp_rst_ids[i]); + return; + } + ssdk_gcc_reset(rst, SSDK_RESET_ASSERT); + msleep(200); + ssdk_gcc_reset(rst, SSDK_RESET_DEASSERT); + msleep(200); + reset_control_put(rst); + } + + i = UNIPHY1_SOFT_RESET_E; + uniphy_rsts[i] = of_reset_control_get(rst_node, UNIPHY1_SOFT_RESET_ID); + + SSDK_INFO("MP reset successfully!1\n"); +#endif +} + +static void ssdk_cmnblk_pll_src_set(enum cmnblk_pll_src_type pll_source) +{ + void __iomem *cmn_pll_src_base = NULL; + a_uint32_t reg_val; + + cmn_pll_src_base = ioremap_nocache(CMN_BLK_PLL_SRC_ADDR, CMN_BLK_SIZE); + if (!cmn_pll_src_base) { + SSDK_ERROR("Failed to map cmn pll source address!\n"); + return; + } + reg_val = readl(cmn_pll_src_base); + reg_val = (reg_val & PLL_CTRL_SRC_MASK) | (pll_source << 0x8); + writel(reg_val, cmn_pll_src_base); + iounmap(cmn_pll_src_base); + + return; +} +#endif +#endif + +#if defined(HPPE) || defined(MP) +static void ssdk_cmnblk_init(enum cmnblk_clk_type mode) +{ + void __iomem *gcc_pll_base = NULL; + a_uint32_t reg_val; + + gcc_pll_base = ioremap_nocache(CMN_BLK_ADDR, CMN_BLK_SIZE); + if (!gcc_pll_base) { + SSDK_ERROR("Failed to map gcc pll address!\n"); + return; + } + reg_val = readl(gcc_pll_base + 4); + + switch (mode) { + case INTERNAL_48MHZ: + reg_val = (reg_val & FREQUENCY_MASK) | INTERNAL_48MHZ_CLOCK; + break; + case EXTERNAL_50MHZ: + reg_val = (reg_val & FREQUENCY_MASK) | EXTERNAL_50MHZ_CLOCK; + break; + case EXTERNAL_25MHZ: + reg_val = (reg_val & FREQUENCY_MASK) | EXTERNAL_25MHZ_CLOCK; + break; + case EXTERNAL_31250KHZ: + reg_val = (reg_val & FREQUENCY_MASK) | EXTERNAL_31250KHZ_CLOCK; + break; + case EXTERNAL_40MHZ: + reg_val = (reg_val & FREQUENCY_MASK) | EXTERNAL_40MHZ_CLOCK; + break; + case EXTERNAL_48MHZ: + reg_val = (reg_val & FREQUENCY_MASK) | EXTERNAL_48MHZ_CLOCK; + break; +#if defined(MP) + case INTERNAL_96MHZ: + ssdk_cmnblk_pll_src_set(CMN_BLK_PLL_SRC_SEL_FROM_REG); + reg_val = (reg_val & PLL_REFCLK_DIV_MASK) | PLL_REFCLK_DIV_2; + break; +#endif + default: + return; + } + + writel(reg_val, gcc_pll_base + 0x4); + reg_val = readl(gcc_pll_base); + reg_val = reg_val | 0x40; + writel(reg_val, gcc_pll_base); + msleep(1); + reg_val = reg_val & (~0x40); + writel(reg_val, gcc_pll_base); + msleep(1); + writel(0xbf, gcc_pll_base); + msleep(1); + writel(0xff, gcc_pll_base); + msleep(1); + + iounmap(gcc_pll_base); +} + +void ssdk_port_mac_clock_reset( + a_uint32_t dev_id, + a_uint32_t port_id) +{ +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) + ssdk_port_reset(dev_id, port_id, SSDK_RESET_ASSERT); + msleep(150); + ssdk_port_reset(dev_id, port_id, SSDK_RESET_DEASSERT); + msleep(150); +#endif + return; +} +#endif + +#if defined(HPPE) +static +void ssdk_uniphy1_clock_source_set(void) +{ +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) + clk_set_parent(uniphy_port_clks[PORT5_RX_SRC_E], + uniphy_raw_clks[2]->clk); + clk_set_parent(uniphy_port_clks[PORT5_TX_SRC_E], + uniphy_raw_clks[3]->clk); +#endif +} + +void ssdk_uniphy_raw_clock_reset(a_uint8_t uniphy_index) +{ +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) + a_uint32_t id; + + if (uniphy_index >= SSDK_MAX_UNIPHY_INSTANCE) + return; + + id = uniphy_index*2; + if (clk_set_rate(uniphy_raw_clks[id]->clk, UNIPHY_DEFAULT_RATE)) + SSDK_ERROR("set rate for %d fail!\n", id); + if (clk_set_rate(uniphy_raw_clks[id+1]->clk, UNIPHY_DEFAULT_RATE)) + SSDK_ERROR("set rate for %d fail!\n", id+1); +#endif +} + +void ssdk_uniphy_raw_clock_set( + a_uint8_t uniphy_index, + a_uint8_t direction, + a_uint32_t clock) +{ +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) + a_uint32_t old_clock, id, mode; + + if ((uniphy_index >= SSDK_MAX_UNIPHY_INSTANCE) || + (direction > UNIPHY_TX) || + (clock != UNIPHY_CLK_RATE_125M && + clock != UNIPHY_CLK_RATE_312M)) + return; + + id = uniphy_index*2 + direction; + old_clock = clk_get_rate(uniphy_raw_clks[id]->clk); + + if (clock != old_clock) { + if (uniphy_index == SSDK_UNIPHY_INSTANCE1) { + if (UNIPHY_RX == direction) + ssdk_uniphy_clock_rate_set(0, + NSS_PORT5_RX_CLK_E, + NSS_PORT5_DFLT_RATE); + else + ssdk_uniphy_clock_rate_set(0, + NSS_PORT5_TX_CLK_E, + NSS_PORT5_DFLT_RATE); + } + if (clk_set_rate(uniphy_raw_clks[id]->clk, clock)) + SSDK_ERROR("set rate: %d fail!\n", clock); + } + + mode = ssdk_dt_global_get_mac_mode(0, SSDK_UNIPHY_INSTANCE1); + if (((uniphy_index == SSDK_UNIPHY_INSTANCE0) && + (mode == PORT_INTERFACE_MODE_MAX)) || + (uniphy_index == SSDK_UNIPHY_INSTANCE1)) { + if (clk_set_parent(uniphy_port_clks[PORT5_RX_SRC_E + direction], + uniphy_raw_clks[id]->clk)) + SSDK_ERROR("set parent fail!\n"); + } +#endif +} + +static +void ssdk_gcc_ppe_clock_init(a_uint32_t revision, enum cmnblk_clk_type mode) +{ +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) + ssdk_ppe_fixed_clock_init(revision); + /*fixme for cmn clock init*/ + ssdk_cmnblk_init(mode); + ssdk_ppe_uniphy_clock_init(revision); +#endif +} +#endif + +#if defined(MP) +void ssdk_gcc_mp_clock_init(enum cmnblk_clk_type mode) +{ +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) + ssdk_mp_fixed_clock_init(); + ssdk_mp_uniphy_clock_init(); + ssdk_cmnblk_init(mode); + msleep(200); + ssdk_mp_cmnblk_enable(); + if (ssdk_mp_cmnblk_stable_check()) { + ssdk_mp_reset_init(); + ssdk_mp_uniphy_clock_enable(); + } else { + SSDK_ERROR("Cmnblock is still not stable!\n"); + } +#endif +} + +void ssdk_mp_raw_clock_set( + a_uint8_t uniphy_index, + a_uint8_t direction, + a_uint32_t clock) +{ +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) + a_uint32_t old_clock, id; + + if ((uniphy_index >= MP_RAW_CLOCK_INSTANCE) || + (direction > UNIPHY_TX) || + (clock != UNIPHY_CLK_RATE_125M && + clock != UNIPHY_CLK_RATE_312M)) + return; + + if(ssdk_is_emulation(0)){ + SSDK_INFO("uniphy_index %d direction %d clock %d on emulation platform\n", + uniphy_index, direction, clock); + return; + } + + id = uniphy_index*2 + direction; + old_clock = clk_get_rate(mp_raw_clks[id]->clk); + + if (clock != old_clock) { + if (clk_set_rate(mp_raw_clks[id]->clk, clock)) + SSDK_ERROR("set rate: %d fail!\n", clock); + } +#endif +} + +#endif + +#if defined(HPPE) || defined(MP) +void ssdk_gcc_clock_init(void) +{ +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) + enum cmnblk_clk_type cmnblk_clk_mode = INTERNAL_48MHZ; + a_uint8_t *mode = NULL; + + clock_node = of_find_node_by_name(NULL, "ess-switch"); + if (of_property_read_string(clock_node, "cmnblk_clk", + (const char **)&mode)) { + cmnblk_clk_mode = INTERNAL_48MHZ; + } else { + if (!strcmp(mode, "external_50MHz")) { + cmnblk_clk_mode = EXTERNAL_50MHZ; + } else if (!strcmp(mode, "external_25MHz")) { + cmnblk_clk_mode = EXTERNAL_25MHZ; + } else if (!strcmp(mode, "external_31250KHz")) { + cmnblk_clk_mode = EXTERNAL_31250KHZ; + } else if (!strcmp(mode, "external_40MHz")) { + cmnblk_clk_mode = EXTERNAL_40MHZ; + } else if (!strcmp(mode, "external_48MHz")) { + cmnblk_clk_mode = EXTERNAL_48MHZ; + } else if (!strcmp(mode, "internal_96MHz")) { + cmnblk_clk_mode = INTERNAL_96MHZ; + } + } + + if (of_device_is_compatible(clock_node, "qcom,ess-switch-ipq807x")) { +#if defined(HPPE) + ssdk_gcc_ppe_clock_init(HPPE_REVISION, cmnblk_clk_mode); +#endif + } else if (of_device_is_compatible(clock_node, + "qcom,ess-switch-ipq60xx")) { +#if defined(HPPE) + ssdk_gcc_ppe_clock_init(CPPE_REVISION, cmnblk_clk_mode); +#endif + } else if (of_device_is_compatible(clock_node, + "qcom,ess-switch-ipq50xx")) { +#if defined(MP) + ssdk_gcc_mp_clock_init(cmnblk_clk_mode); +#endif + } +#endif + SSDK_INFO("SSDK gcc clock init successfully!\n"); +} + +void +qca_gcc_uniphy_port_clock_set( + a_uint32_t dev_id, a_uint32_t uniphy_index, + a_uint32_t port_id, a_bool_t enable) +{ + + if (uniphy_index == SSDK_UNIPHY_INSTANCE2) { + ssdk_uniphy_clock_enable(dev_id, + UNIPHY2_PORT6_RX_CLK_E, enable); + ssdk_uniphy_clock_enable(dev_id, + UNIPHY2_PORT6_TX_CLK_E, enable); + } else if (uniphy_index == SSDK_UNIPHY_INSTANCE1) { + ssdk_uniphy_clock_enable(dev_id, + UNIPHY1_PORT5_RX_CLK_E, enable); + ssdk_uniphy_clock_enable(dev_id, + UNIPHY1_PORT5_TX_CLK_E, enable); + } else if (uniphy_index == SSDK_UNIPHY_INSTANCE0) { + switch (port_id) { + case SSDK_PHYSICAL_PORT1: + ssdk_uniphy_clock_enable(dev_id, + UNIPHY0_PORT1_RX_CLK_E, + enable); + ssdk_uniphy_clock_enable(dev_id, + UNIPHY0_PORT1_TX_CLK_E, + enable); + break; + case SSDK_PHYSICAL_PORT2: + ssdk_uniphy_clock_enable(dev_id, + UNIPHY0_PORT2_RX_CLK_E, + enable); + ssdk_uniphy_clock_enable(dev_id, + UNIPHY0_PORT2_TX_CLK_E, + enable); + break; + case SSDK_PHYSICAL_PORT3: + ssdk_uniphy_clock_enable(dev_id, + UNIPHY0_PORT3_RX_CLK_E, + enable); + ssdk_uniphy_clock_enable(dev_id, + UNIPHY0_PORT3_TX_CLK_E, + enable); + break; + case SSDK_PHYSICAL_PORT4: + ssdk_uniphy_clock_enable(dev_id, + UNIPHY0_PORT4_RX_CLK_E, + enable); + ssdk_uniphy_clock_enable(dev_id, + UNIPHY0_PORT4_TX_CLK_E, + enable); + break; + case SSDK_PHYSICAL_PORT5: + ssdk_uniphy_clock_enable(dev_id, + UNIPHY0_PORT5_RX_CLK_E, + enable); + ssdk_uniphy_clock_enable(dev_id, + UNIPHY0_PORT5_TX_CLK_E, + enable); + break; + default: + break; + } + } +} + +void +qca_gcc_mac_port_clock_set( + a_uint32_t dev_id, + a_uint32_t port_id, + a_bool_t enable) +{ + + switch (port_id) { + case SSDK_PHYSICAL_PORT1: + ssdk_uniphy_clock_enable(dev_id, + NSS_PORT1_RX_CLK_E, + enable); + ssdk_uniphy_clock_enable(dev_id, + NSS_PORT1_TX_CLK_E, + enable); + break; + case SSDK_PHYSICAL_PORT2: + ssdk_uniphy_clock_enable(dev_id, + NSS_PORT2_RX_CLK_E, + enable); + ssdk_uniphy_clock_enable(dev_id, + NSS_PORT2_TX_CLK_E, + enable); + break; + case SSDK_PHYSICAL_PORT3: + ssdk_uniphy_clock_enable(dev_id, + NSS_PORT3_RX_CLK_E, + enable); + ssdk_uniphy_clock_enable(dev_id, + NSS_PORT3_TX_CLK_E, + enable); + break; + case SSDK_PHYSICAL_PORT4: + ssdk_uniphy_clock_enable(dev_id, + NSS_PORT4_RX_CLK_E, + enable); + ssdk_uniphy_clock_enable(dev_id, + NSS_PORT4_TX_CLK_E, + enable); + break; + case SSDK_PHYSICAL_PORT5: + ssdk_uniphy_clock_enable(dev_id, + NSS_PORT5_RX_CLK_E, + enable); + ssdk_uniphy_clock_enable(dev_id, + NSS_PORT5_TX_CLK_E, + enable); + break; + case SSDK_PHYSICAL_PORT6: + ssdk_uniphy_clock_enable(dev_id, + NSS_PORT6_RX_CLK_E, + enable); + ssdk_uniphy_clock_enable(dev_id, + NSS_PORT6_TX_CLK_E, + enable); + break; + default: + break; + } +} + +void +ssdk_port_speed_clock_set( + a_uint32_t dev_id, + a_uint32_t port_id, + a_uint32_t rate) +{ +#if defined(HPPE) + a_uint32_t mode = 0; +#endif + + switch (port_id ) { + case SSDK_PHYSICAL_PORT1: + ssdk_uniphy_clock_rate_set(dev_id, + NSS_PORT1_RX_CLK_E, rate); + ssdk_uniphy_clock_rate_set(dev_id, + NSS_PORT1_TX_CLK_E, rate); + break; + case SSDK_PHYSICAL_PORT2: + ssdk_uniphy_clock_rate_set(dev_id, + NSS_PORT2_RX_CLK_E, rate); + ssdk_uniphy_clock_rate_set(dev_id, + NSS_PORT2_TX_CLK_E, rate); + break; +#if defined(HPPE) + case SSDK_PHYSICAL_PORT3: + ssdk_uniphy_clock_rate_set(dev_id, + NSS_PORT3_RX_CLK_E, rate); + ssdk_uniphy_clock_rate_set(dev_id, + NSS_PORT3_TX_CLK_E, rate); + break; + case SSDK_PHYSICAL_PORT4: + ssdk_uniphy_clock_rate_set(dev_id, + NSS_PORT4_RX_CLK_E, rate); + ssdk_uniphy_clock_rate_set(dev_id, + NSS_PORT4_TX_CLK_E, rate); + break; + case SSDK_PHYSICAL_PORT5: + ssdk_uniphy_clock_rate_set(dev_id, + NSS_PORT5_RX_CLK_E, rate); + ssdk_uniphy_clock_rate_set(dev_id, + NSS_PORT5_TX_CLK_E, rate); + mode = ssdk_dt_global_get_mac_mode(dev_id, SSDK_UNIPHY_INSTANCE1); + if (mode != PORT_INTERFACE_MODE_MAX) + ssdk_uniphy1_clock_source_set(); + break; + case SSDK_PHYSICAL_PORT6: + ssdk_uniphy_clock_rate_set(dev_id, + NSS_PORT6_RX_CLK_E, rate); + ssdk_uniphy_clock_rate_set(dev_id, + NSS_PORT6_TX_CLK_E, rate); + break; +#endif + default: + break; + } +} +#endif + +#if defined(HPPE) +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) +static char *ppe_rst_ids[UNIPHY_RST_MAX] = { + UNIPHY0_SOFT_RESET_ID, + UNIPHY0_XPCS_RESET_ID, + UNIPHY1_SOFT_RESET_ID, + UNIPHY1_XPCS_RESET_ID, + UNIPHY2_SOFT_RESET_ID, + UNIPHY2_XPCS_RESET_ID, + UNIPHY0_PORT1_DISABLE_ID, + UNIPHY0_PORT2_DISABLE_ID, + UNIPHY0_PORT3_DISABLE_ID, + UNIPHY0_PORT4_DISABLE_ID, + UNIPHY0_PORT5_DISABLE_ID, + UNIPHY0_PORT_4_5_RESET_ID, + UNIPHY0_PORT_4_RESET_ID +}; +static char *port_rst_ids[SSDK_MAX_PORT_NUM] = { + SSDK_PORT1_RESET_ID, + SSDK_PORT2_RESET_ID, + SSDK_PORT3_RESET_ID, + SSDK_PORT4_RESET_ID, + SSDK_PORT5_RESET_ID, + SSDK_PORT6_RESET_ID, + NULL, NULL +}; +#endif + +void ssdk_ppe_reset_init(void) +{ +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) + struct reset_control *rst; + a_uint32_t i; + + rst_node = of_find_node_by_name(NULL, "ess-switch"); + rst = of_reset_control_get(rst_node, PPE_RESET_ID); + if (IS_ERR(rst)) { + SSDK_ERROR("%s not exist!\n", PPE_RESET_ID); + return; + } + + ssdk_gcc_reset(rst, SSDK_RESET_ASSERT); + msleep(100); + ssdk_gcc_reset(rst, SSDK_RESET_DEASSERT); + msleep(100); + reset_control_put(rst); + SSDK_INFO("ppe reset successfully!\n"); + + for (i = UNIPHY0_SOFT_RESET_E; i < UNIPHY_RST_MAX; i++) + uniphy_rsts[i] = of_reset_control_get(rst_node, + ppe_rst_ids[i]); + + for (i = SSDK_PHYSICAL_PORT1; i < SSDK_PHYSICAL_PORT7; i++) + port_rsts[i-1] = of_reset_control_get(rst_node, + port_rst_ids[i-1]); +#endif +} +#endif + diff --git a/feeds/ipq807x/qca-ssdk/src/src/init/ssdk_dts.c b/feeds/ipq807x/qca-ssdk/src/src/init/ssdk_dts.c new file mode 100644 index 000000000..21804970b --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/init/ssdk_dts.c @@ -0,0 +1,1199 @@ +/* + * 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 +#include +#if defined(CONFIG_OF) +#include +#include +#include +#include +#endif +#include +#include + +#include "ssdk_init.h" +#include "ssdk_dts.h" +#include "ssdk_plat.h" +#include "hsl_phy.h" + +static ssdk_dt_global_t ssdk_dt_global = {0}; +#ifdef HPPE +#ifdef IN_QOS +a_uint8_t ssdk_tm_tick_mode_get(a_uint32_t dev_id) +{ + ssdk_dt_cfg* cfg = ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]; + + return cfg->tm_tick_mode; +} + +ssdk_dt_scheduler_cfg* ssdk_bootup_shceduler_cfg_get(a_uint32_t dev_id) +{ + ssdk_dt_cfg* cfg = ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]; + + return &cfg->scheduler_cfg; +} +#endif +#endif +#ifdef IN_BM +a_uint8_t ssdk_bm_tick_mode_get(a_uint32_t dev_id) +{ + ssdk_dt_cfg* cfg = ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]; + + return cfg->bm_tick_mode; +} +#endif +#ifdef IN_QM +a_uint16_t ssdk_ucast_queue_start_get(a_uint32_t dev_id, a_uint32_t port) +{ + ssdk_dt_cfg* cfg = ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]; + + return cfg->scheduler_cfg.pool[port].ucastq_start; +} +#endif +a_uint32_t ssdk_intf_mac_num_get(void) +{ + return ssdk_dt_global.num_intf_mac; +} + +a_uint8_t* ssdk_intf_macaddr_get(a_uint32_t index) +{ + return ssdk_dt_global.intf_mac[index].uc; +} + +a_uint32_t ssdk_dt_global_get_mac_mode(a_uint32_t dev_id, a_uint32_t index) +{ + if (index == 0) { + return ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]->mac_mode; + } + if (index == 1) { + return ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]->mac_mode1; + } + if (index == 2) { + return ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]->mac_mode2; + } + + return 0; +} + +a_uint32_t ssdk_dt_global_set_mac_mode(a_uint32_t dev_id, a_uint32_t index, a_uint32_t mode) +{ + if (index == 0) + { + ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]->mac_mode= mode; + } + if (index == 1) + { + ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]->mac_mode1 = mode; + } + if (index == 2) + { + ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]->mac_mode2 = mode; + } + + return 0; +} + +a_uint32_t ssdk_cpu_bmp_get(a_uint32_t dev_id) +{ + ssdk_dt_cfg* cfg = ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]; + + return cfg->port_cfg.cpu_bmp; +} + +a_uint32_t ssdk_lan_bmp_get(a_uint32_t dev_id) +{ + ssdk_dt_cfg* cfg = ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]; + + return cfg->port_cfg.lan_bmp; +} + +a_uint32_t ssdk_wan_bmp_get(a_uint32_t dev_id) +{ + ssdk_dt_cfg* cfg = ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]; + + return cfg->port_cfg.wan_bmp; +} + +sw_error_t ssdk_lan_bmp_set(a_uint32_t dev_id, a_uint32_t lan_bmp) +{ + ssdk_dt_cfg* cfg = ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]; + cfg->port_cfg.lan_bmp = lan_bmp; + + return SW_OK; +} + +sw_error_t ssdk_wan_bmp_set(a_uint32_t dev_id, a_uint32_t wan_bmp) +{ + ssdk_dt_cfg* cfg = ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]; + cfg->port_cfg.wan_bmp = wan_bmp; + + return SW_OK; +} + +a_uint32_t ssdk_inner_bmp_get(a_uint32_t dev_id) +{ + ssdk_dt_cfg* cfg = ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]; + + return cfg->port_cfg.inner_bmp; +} + +ssdk_port_phyinfo* ssdk_port_phyinfo_get(a_uint32_t dev_id, a_uint32_t port_id) +{ + a_uint32_t i; + ssdk_port_phyinfo *phyinfo_tmp = NULL; + ssdk_dt_cfg *cfg = ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]; + + for (i = 0; i < cfg->phyinfo_num; i++) { + if (port_id == cfg->port_phyinfo[i].port_id) { + phyinfo_tmp = &cfg->port_phyinfo[i]; + break; + } else if (!(cfg->port_phyinfo[i].phy_features & PHY_F_INIT) && + phyinfo_tmp == NULL) { + phyinfo_tmp = &cfg->port_phyinfo[i]; + } + } + + return phyinfo_tmp; +} + +a_bool_t ssdk_port_feature_get(a_uint32_t dev_id, a_uint32_t port_id, phy_features_t feature) +{ + ssdk_port_phyinfo *phyinfo = ssdk_port_phyinfo_get(dev_id, port_id); + if (phyinfo && (phyinfo->phy_features & feature)) { + return A_TRUE; + } + return A_FALSE; +} + +a_uint32_t ssdk_port_force_speed_get(a_uint32_t dev_id, a_uint32_t port_id) +{ + ssdk_port_phyinfo *phyinfo = ssdk_port_phyinfo_get(dev_id, port_id); + if (phyinfo && (phyinfo->phy_features & PHY_F_FORCE)) { + return phyinfo->port_speed; + } + return FAL_SPEED_BUTT; +} + +struct mii_bus * +ssdk_dts_miibus_get(a_uint32_t dev_id, a_uint32_t phy_addr) +{ + a_uint32_t i; + ssdk_dt_cfg* cfg = ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]; + + for (i = 0; i < cfg->phyinfo_num; i++) { + if (phy_addr == cfg->port_phyinfo[i].phy_addr) + return cfg->port_phyinfo[i].miibus; + } + + return NULL; +} + +hsl_reg_mode ssdk_switch_reg_access_mode_get(a_uint32_t dev_id) +{ + ssdk_dt_cfg* cfg = ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]; + + return cfg->switch_reg_access_mode; +} +#ifdef IN_UNIPHY +hsl_reg_mode ssdk_uniphy_reg_access_mode_get(a_uint32_t dev_id) +{ + ssdk_dt_cfg* cfg = ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]; + + return cfg->uniphy_reg_access_mode; +} +#endif +#ifdef DESS +hsl_reg_mode ssdk_psgmii_reg_access_mode_get(a_uint32_t dev_id) +{ + ssdk_dt_cfg* cfg = ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]; + + return cfg->psgmii_reg_access_mode; +} +#endif +void ssdk_switch_reg_map_info_get(a_uint32_t dev_id, ssdk_reg_map_info *info) +{ + ssdk_dt_cfg* cfg = ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]; + + info->base_addr = cfg->switchreg_base_addr; + info->size = cfg->switchreg_size; +} +#ifdef DESS +void ssdk_psgmii_reg_map_info_get(a_uint32_t dev_id, ssdk_reg_map_info *info) +{ + ssdk_dt_cfg* cfg = ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]; + + info->base_addr = cfg->psgmiireg_base_addr; + info->size = cfg->psgmiireg_size; +} +#endif +#ifdef IN_UNIPHY +void ssdk_uniphy_reg_map_info_get(a_uint32_t dev_id, ssdk_reg_map_info *info) +{ + ssdk_dt_cfg* cfg = ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]; + + info->base_addr = cfg->uniphyreg_base_addr; + info->size = cfg->uniphyreg_size; +} +#endif +a_bool_t ssdk_ess_switch_flag_get(a_uint32_t dev_id) +{ + ssdk_dt_cfg* cfg = ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]; + + return cfg->ess_switch_flag; +} + +a_uint32_t ssdk_device_id_get(a_uint32_t index) +{ + return ssdk_dt_global.ssdk_dt_switch_nodes[index]->device_id; +} + +struct device_node *ssdk_dts_node_get(a_uint32_t dev_id) +{ + ssdk_dt_cfg* cfg = ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]; + + return cfg->of_node; +} + +struct clk *ssdk_dts_essclk_get(a_uint32_t dev_id) +{ + ssdk_dt_cfg* cfg = ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]; + + return cfg->ess_clk; +} + +struct clk *ssdk_dts_cmnclk_get(a_uint32_t dev_id) +{ + ssdk_dt_cfg* cfg = ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]; + + return cfg->cmnblk_clk; +} + +#ifndef BOARD_AR71XX +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) +static void ssdk_dt_parse_mac_mode(a_uint32_t dev_id, + struct device_node *switch_node, ssdk_init_cfg *cfg) +{ + const __be32 *mac_mode; + a_uint32_t len = 0; + + mac_mode = of_get_property(switch_node, "switch_mac_mode", &len); + if (!mac_mode) + SSDK_INFO("mac mode doesn't exit!\n"); + else { + cfg->mac_mode = be32_to_cpup(mac_mode); + SSDK_INFO("mac mode = 0x%x\n", be32_to_cpup(mac_mode)); + ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]->mac_mode = cfg->mac_mode; + } + + mac_mode = of_get_property(switch_node, "switch_mac_mode1", &len); + if(!mac_mode) + SSDK_INFO("mac mode1 doesn't exit!\n"); + else { + cfg->mac_mode1 = be32_to_cpup(mac_mode); + SSDK_INFO("mac mode1 = 0x%x\n", be32_to_cpup(mac_mode)); + ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]->mac_mode1 = cfg->mac_mode1; + } + + mac_mode = of_get_property(switch_node, "switch_mac_mode2", &len); + if(!mac_mode) + SSDK_INFO("mac mode2 doesn't exit!\n"); + else { + cfg->mac_mode2 = be32_to_cpup(mac_mode); + SSDK_INFO("mac mode2 = 0x%x\n", be32_to_cpup(mac_mode)); + ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]->mac_mode2 = cfg->mac_mode2; + } + + return; +} +#ifdef IN_UNIPHY +static void ssdk_dt_parse_uniphy(a_uint32_t dev_id) +{ + struct device_node *uniphy_node = NULL; + a_uint32_t len = 0; + const __be32 *reg_cfg; + ssdk_dt_cfg *cfg; + + /* read uniphy register base and address space */ + uniphy_node = of_find_node_by_name(NULL, "ess-uniphy"); + if (!uniphy_node) + SSDK_INFO("ess-uniphy DT doesn't exist!\n"); + else { + SSDK_INFO("ess-uniphy DT exist!\n"); + cfg = ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]; + reg_cfg = of_get_property(uniphy_node, "reg", &len); + if(!reg_cfg) + SSDK_INFO("uniphy reg address doesn't exist!\n"); + else { + cfg->uniphyreg_base_addr = be32_to_cpup(reg_cfg); + cfg->uniphyreg_size = be32_to_cpup(reg_cfg + 1); + } + if (of_property_read_string(uniphy_node, "uniphy_access_mode", + (const char **)&cfg->uniphy_access_mode)) + SSDK_INFO("uniphy access mode doesn't exist!\n"); + else { + if(!strcmp(cfg->uniphy_access_mode, "local bus")) + cfg->uniphy_reg_access_mode = HSL_REG_LOCAL_BUS; + } + } + + return; +} +#endif +#ifdef HPPE +#ifdef IN_QOS +static void ssdk_dt_parse_l1_scheduler_cfg( + struct device_node *port_node, + a_uint32_t port_id, a_uint32_t dev_id) +{ + struct device_node *scheduler_node; + struct device_node *child; + ssdk_dt_scheduler_cfg *cfg = &(ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]->scheduler_cfg); + a_uint32_t tmp_cfg[4]; + const __be32 *paddr; + a_uint32_t len, i, sp_id; + + scheduler_node = of_find_node_by_name(port_node, "l1scheduler"); + if (!scheduler_node) { + SSDK_ERROR("cannot find l1scheduler node for port\n"); + return; + } + for_each_available_child_of_node(scheduler_node, child) { + paddr = of_get_property(child, "sp", &len); + len /= sizeof(a_uint32_t); + if (!paddr) { + SSDK_ERROR("error reading sp property\n"); + return; + } + if (of_property_read_u32_array(child, + "cfg", tmp_cfg, 4)) { + SSDK_ERROR("error reading cfg property!\n"); + return; + } + for (i = 0; i < len; i++) { + sp_id = be32_to_cpup(paddr+i); + if (sp_id >= SSDK_L1SCHEDULER_CFG_MAX) { + SSDK_ERROR("Invalid parameter for sp(%d)\n", + sp_id); + return; + } + cfg->l1cfg[sp_id].valid = 1; + cfg->l1cfg[sp_id].port_id = port_id; + cfg->l1cfg[sp_id].cpri = tmp_cfg[0]; + cfg->l1cfg[sp_id].cdrr_id = tmp_cfg[1]; + cfg->l1cfg[sp_id].epri = tmp_cfg[2]; + cfg->l1cfg[sp_id].edrr_id = tmp_cfg[3]; + } + } +} + +static void ssdk_dt_parse_l0_queue_cfg( + a_uint32_t dev_id, + a_uint32_t port_id, + struct device_node *node, + a_uint8_t *queue_name, + a_uint8_t *loop_name) +{ + ssdk_dt_scheduler_cfg *cfg = &(ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]->scheduler_cfg); + a_uint32_t tmp_cfg[5]; + const __be32 *paddr; + a_uint32_t len, i, queue_id, pri_loop; + + paddr = of_get_property(node, queue_name, &len); + len /= sizeof(a_uint32_t); + if (!paddr) { + SSDK_ERROR("error reading %s property\n", queue_name); + return; + } + if (of_property_read_u32_array(node, "cfg", tmp_cfg, 5)) { + SSDK_ERROR("error reading cfg property!\n"); + return; + } + if (of_property_read_u32(node, loop_name, &pri_loop)) { + for (i = 0; i < len; i++) { + queue_id = be32_to_cpup(paddr+i); + if (queue_id >= SSDK_L0SCHEDULER_CFG_MAX) { + SSDK_ERROR("Invalid parameter for queue(%d)\n", + queue_id); + return; + } + cfg->l0cfg[queue_id].valid = 1; + cfg->l0cfg[queue_id].port_id = port_id; + cfg->l0cfg[queue_id].sp_id = tmp_cfg[0]; + cfg->l0cfg[queue_id].cpri = tmp_cfg[1]; + cfg->l0cfg[queue_id].cdrr_id = tmp_cfg[2]; + cfg->l0cfg[queue_id].epri = tmp_cfg[3]; + cfg->l0cfg[queue_id].edrr_id = tmp_cfg[4]; + } + } else { + /* should one queue for loop */ + if (len != 1) { + SSDK_ERROR("should one queue for loop!\n"); + return; + } + queue_id = be32_to_cpup(paddr); + if (queue_id >= SSDK_L0SCHEDULER_CFG_MAX) { + SSDK_ERROR("Invalid parameter for queue(%d)\n", + queue_id); + return; + } + for (i = 0; i < pri_loop; i++) { + cfg->l0cfg[queue_id + i].valid = 1; + cfg->l0cfg[queue_id + i].port_id = port_id; + cfg->l0cfg[queue_id + i].sp_id = tmp_cfg[0] + i/SSDK_SP_MAX_PRIORITY; + cfg->l0cfg[queue_id + i].cpri = tmp_cfg[1] + i%SSDK_SP_MAX_PRIORITY; + cfg->l0cfg[queue_id + i].cdrr_id = tmp_cfg[2] + i; + cfg->l0cfg[queue_id + i].epri = tmp_cfg[3] + i%SSDK_SP_MAX_PRIORITY; + cfg->l0cfg[queue_id + i].edrr_id = tmp_cfg[4] + i; + } + } +} + +static void ssdk_dt_parse_l0_scheduler_cfg( + struct device_node *port_node, + a_uint32_t port_id, a_uint32_t dev_id) +{ + struct device_node *scheduler_node; + struct device_node *child; + + scheduler_node = of_find_node_by_name(port_node, "l0scheduler"); + if (!scheduler_node) { + SSDK_ERROR("Can't find l0scheduler node for port\n"); + return; + } + for_each_available_child_of_node(scheduler_node, child) { + ssdk_dt_parse_l0_queue_cfg(dev_id, port_id, child, + "ucast_queue", "ucast_loop_pri"); + ssdk_dt_parse_l0_queue_cfg(dev_id, port_id, child, + "mcast_queue", "mcast_loop_pri"); + } +} + +static void ssdk_dt_parse_scheduler_resource( + struct device_node *port_node, + a_uint32_t dev_id, a_uint32_t port_id) +{ + a_uint32_t uq[2], mq[2], l0sp[2], l0cdrr[2]; + a_uint32_t l0edrr[2], l1cdrr[2], l1edrr[2]; + ssdk_dt_scheduler_cfg *cfg = &(ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]->scheduler_cfg); + + if (of_property_read_u32_array(port_node, "ucast_queue", uq, 2) + || of_property_read_u32_array(port_node, "mcast_queue", mq, 2) + || of_property_read_u32_array(port_node, "l0sp", l0sp, 2) + || of_property_read_u32_array(port_node, "l0cdrr", l0cdrr, 2) + || of_property_read_u32_array(port_node, "l0edrr", l0edrr, 2) + || of_property_read_u32_array(port_node, "l1cdrr", l1cdrr, 2) + || of_property_read_u32_array(port_node, "l1edrr", l1edrr, 2)){ + SSDK_ERROR("error reading port resource scheduler properties\n"); + return; + } + cfg->pool[port_id].ucastq_start = uq[0]; + cfg->pool[port_id].ucastq_end = uq[1]; + cfg->pool[port_id].mcastq_start = mq[0]; + cfg->pool[port_id].mcastq_end = mq[1]; + cfg->pool[port_id].l0sp_start = l0sp[0]; + cfg->pool[port_id].l0sp_end = l0sp[1]; + cfg->pool[port_id].l0cdrr_start = l0cdrr[0]; + cfg->pool[port_id].l0cdrr_end = l0cdrr[1]; + cfg->pool[port_id].l0edrr_start = l0edrr[0]; + cfg->pool[port_id].l0edrr_end = l0edrr[1]; + cfg->pool[port_id].l1cdrr_start = l1cdrr[0]; + cfg->pool[port_id].l1cdrr_end = l1cdrr[1]; + cfg->pool[port_id].l1edrr_start = l1edrr[0]; + cfg->pool[port_id].l1edrr_end = l1edrr[1]; +} + +static void ssdk_dt_parse_scheduler_cfg(a_uint32_t dev_id, struct device_node *switch_node) +{ + struct device_node *scheduler_node; + struct device_node *child; + a_uint32_t port_id; + + scheduler_node = of_find_node_by_name(switch_node, "port_scheduler_resource"); + if (!scheduler_node) { + SSDK_ERROR("cannot find port_scheduler_resource node\n"); + return; + } + for_each_available_child_of_node(scheduler_node, child) { + if (of_property_read_u32(child, "port_id", &port_id)) { + SSDK_ERROR("error reading for port_id property!\n"); + return; + } + if (port_id >= SSDK_MAX_PORT_NUM) { + SSDK_ERROR("invalid parameter for port_id(%d)!\n", port_id); + return; + } + ssdk_dt_parse_scheduler_resource(child, dev_id, port_id); + } + + scheduler_node = of_find_node_by_name(switch_node, "port_scheduler_config"); + if (!scheduler_node) { + SSDK_ERROR("cannot find port_scheduler_config node\n"); + return ; + } + for_each_available_child_of_node(scheduler_node, child) { + if (of_property_read_u32(child, "port_id", &port_id)) { + SSDK_ERROR("error reading for port_id property!\n"); + return; + } + if (port_id >= SSDK_MAX_PORT_NUM) { + SSDK_ERROR("invalid parameter for port_id(%d)!\n", port_id); + return; + } + ssdk_dt_parse_l1_scheduler_cfg(child, port_id, dev_id); + ssdk_dt_parse_l0_scheduler_cfg(child, port_id, dev_id); + } +} +#endif +#endif +static sw_error_t ssdk_dt_parse_phy_info(struct device_node *switch_node, a_uint32_t dev_id, + ssdk_init_cfg *cfg) +{ + struct device_node *phy_info_node, *port_node; + + ssdk_port_phyinfo *port_phyinfo; + a_uint8_t forced_duplex; + a_uint32_t port_id, phy_addr, phy_i2c_addr, forced_speed, len; + const __be32 *paddr; + a_bool_t phy_c45, phy_combo, phy_i2c, phy_forced; + const char *mac_type = NULL; + sw_error_t rv = SW_OK; + struct device_node *mdio_node; + int phy_reset_gpio = 0; + phy_dac_t phy_dac = {0}; + + phy_info_node = of_get_child_by_name(switch_node, "qcom,port_phyinfo"); + if (!phy_info_node) { + SSDK_INFO("qcom,port_phyinfo DT doesn't exist!\n"); + return SW_NOT_FOUND; + } + + for_each_available_child_of_node(phy_info_node, port_node) { + if (of_property_read_u32(port_node, "port_id", &port_id)) + return SW_BAD_VALUE; + + /* initialize phy_addr in case of undefined dts field */ + phy_addr = 0xff; + of_property_read_u32(port_node, "phy_address", &phy_addr); + + if (!cfg->port_cfg.wan_bmp) { + cfg->port_cfg.wan_bmp = BIT(port_id); + } else { + cfg->port_cfg.lan_bmp |= BIT(port_id); + } + + if (!of_property_read_u32(port_node, "forced-speed", &forced_speed) && + !of_property_read_u8(port_node, "forced-duplex", &forced_duplex)) { + phy_forced = A_TRUE; + } else { + phy_forced = A_FALSE; + } + paddr = of_get_property(port_node, "phy_dac", &len); + if(paddr) + { + phy_dac.mdac = be32_to_cpup(paddr); + phy_dac.edac = be32_to_cpup(paddr+1); + hsl_port_phy_dac_set(dev_id, port_id, phy_dac); + } + + phy_c45 = of_property_read_bool(port_node, + "ethernet-phy-ieee802.3-c45"); + phy_combo = of_property_read_bool(port_node, + "ethernet-phy-combo"); + mdio_node = of_parse_phandle(port_node, "mdiobus", 0); + phy_i2c = of_property_read_bool(port_node, "phy-i2c-mode"); + + if (phy_i2c) { + SSDK_INFO("[PORT %d] phy-i2c-mode\n", port_id); + hsl_port_phy_access_type_set(dev_id, port_id, PHY_I2C_ACCESS); + if (of_property_read_u32(port_node, "phy_i2c_address", + &phy_i2c_addr)) { + return SW_BAD_VALUE; + } + /* phy_i2c_address is the i2c slave addr */ + hsl_phy_address_init(dev_id, port_id, phy_i2c_addr); + /* phy_address is the mdio addr, + * which is a fake mdio addr in i2c mode */ + qca_ssdk_phy_mdio_fake_address_set(dev_id, port_id, phy_addr); + } else { + hsl_phy_address_init(dev_id, port_id, phy_addr); + } + + hsl_port_phy_combo_capability_set(dev_id, port_id, phy_combo); + hsl_port_phy_c45_capability_set(dev_id, port_id, phy_c45); + + port_phyinfo = ssdk_port_phyinfo_get(dev_id, port_id); + if (port_phyinfo) { + port_phyinfo->port_id = port_id; + port_phyinfo->phy_addr = phy_addr; + if (phy_c45) { + port_phyinfo->phy_features |= PHY_F_CLAUSE45; + } + + if (phy_combo) { + port_phyinfo->phy_features |= PHY_F_COMBO; + } + + if (phy_i2c) { + port_phyinfo->phy_features |= PHY_F_I2C; + } + + if (phy_forced) { + port_phyinfo->phy_features |= PHY_F_FORCE; + port_phyinfo->port_speed = forced_speed; + port_phyinfo->port_duplex = forced_duplex; + } + + if (!of_property_read_string(port_node, "port_mac_sel", &mac_type)) + { + SSDK_INFO("[PORT %d] port_mac_sel = %s\n", port_id, mac_type); + if (!strncmp("QGMAC_PORT", mac_type, 10)) { + port_phyinfo->phy_features |= PHY_F_QGMAC; + } + else if (!strncmp("XGMAC_PORT", mac_type, 10)) { + port_phyinfo->phy_features |= PHY_F_XGMAC; + } + } + + port_phyinfo->phy_features |= PHY_F_INIT; + + if (mdio_node) + { + port_phyinfo->miibus = of_mdio_find_bus(mdio_node); + phy_reset_gpio = of_get_named_gpio(mdio_node, "phy-reset-gpio", + SSDK_PHY_RESET_GPIO_INDEX); + if(phy_reset_gpio > 0) + { + SSDK_INFO("port%d's phy-reset-gpio is GPIO%d\n", port_id, + phy_reset_gpio); + hsl_port_phy_reset_gpio_set(dev_id, port_id, + (a_uint32_t)phy_reset_gpio); + } + } + } + } + + return rv; +} + +static void ssdk_dt_parse_mdio(a_uint32_t dev_id, struct device_node *switch_node, + ssdk_init_cfg *cfg) +{ + struct device_node *mdio_node = NULL; + struct device_node *child = NULL; + ssdk_port_phyinfo *port_phyinfo; + a_uint32_t len = 0, i = 1; + const __be32 *phy_addr; + const __be32 *c45_phy; + + /* prefer to get phy info from ess-switch node */ + if (SW_OK == ssdk_dt_parse_phy_info(switch_node, dev_id, cfg)) + return; + + mdio_node = of_find_node_by_name(NULL, "mdio"); + + if (!mdio_node) { + SSDK_INFO("mdio DT doesn't exist!\n"); + } + else { + SSDK_INFO("mdio DT exist!\n"); + for_each_available_child_of_node(mdio_node, child) { + phy_addr = of_get_property(child, "reg", &len); + if (phy_addr) { + hsl_phy_address_init(dev_id, i, be32_to_cpup(phy_addr)); + } + + c45_phy = of_get_property(child, "compatible", &len); + if (c45_phy) { + hsl_port_phy_c45_capability_set(dev_id, i, A_TRUE); + } + + port_phyinfo = ssdk_port_phyinfo_get(dev_id, i); + if (port_phyinfo) { + port_phyinfo->port_id = i; + if (phy_addr) { + port_phyinfo->phy_addr = be32_to_cpup(phy_addr); + } + if (c45_phy) { + port_phyinfo->phy_features |= PHY_F_CLAUSE45; + } + + port_phyinfo->phy_features |= PHY_F_INIT; + } + + if (!cfg->port_cfg.wan_bmp) { + cfg->port_cfg.wan_bmp = BIT(i); + } else { + cfg->port_cfg.lan_bmp |= BIT(i); + } + + i++; + if (i >= SW_MAX_NR_PORT) { + break; + } + } + } + return; +} + +static void ssdk_dt_parse_port_bmp(a_uint32_t dev_id, + struct device_node *switch_node, ssdk_init_cfg *cfg) +{ + a_uint32_t portbmp = 0; + + if (of_property_read_u32(switch_node, "switch_cpu_bmp", &cfg->port_cfg.cpu_bmp) + || of_property_read_u32(switch_node, "switch_lan_bmp", &cfg->port_cfg.lan_bmp) + || of_property_read_u32(switch_node, "switch_wan_bmp", &cfg->port_cfg.wan_bmp)) { + SSDK_INFO("port_bmp doesn't exist!\n"); + /* + * the bmp maybe initialized already, so just keep ongoing. + */ + } + + if (!of_property_read_u32(switch_node, "switch_inner_bmp", &cfg->port_cfg.inner_bmp)) { + ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]->port_cfg.inner_bmp = + cfg->port_cfg.inner_bmp; + } + + ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]->port_cfg.cpu_bmp = cfg->port_cfg.cpu_bmp; + ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]->port_cfg.lan_bmp = cfg->port_cfg.lan_bmp; + ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]->port_cfg.wan_bmp = cfg->port_cfg.wan_bmp; + + portbmp = cfg->port_cfg.lan_bmp | cfg->port_cfg.wan_bmp; + qca_ssdk_port_bmp_set(dev_id, portbmp); + + return; +} +#ifdef HPPE +static void ssdk_dt_parse_intf_mac(void) +{ + struct device_node *dp_node = NULL; + a_uint32_t dp = 0; + a_uint8_t *maddr = NULL; + char dp_name[8] = {0}; + + for (dp = 1; dp <= SSDK_MAX_NR_ETH; dp++) { + snprintf(dp_name, sizeof(dp_name), "dp%d", dp); + dp_node = of_find_node_by_name(NULL, dp_name); + if (!dp_node) { + continue; + } + maddr = (a_uint8_t *)of_get_mac_address(dp_node); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)) + if (maddr && is_valid_ether_addr(maddr)) { +#else + if (!IS_ERR(maddr) && is_valid_ether_addr(maddr)) { +#endif + ssdk_dt_global.num_intf_mac++; + ether_addr_copy(ssdk_dt_global.intf_mac[dp-1].uc, maddr); + SSDK_INFO("%s MAC %02x:%02x:%02x:%02x:%02x:%02x\n", + dp_name, maddr[0], maddr[1], maddr[2], maddr[3], + maddr[4], maddr[5]); + } + } + return; +} +#endif +#ifdef DESS +static void ssdk_dt_parse_psgmii(ssdk_dt_cfg *ssdk_dt_priv) +{ + + struct device_node *psgmii_node = NULL; + const __be32 *reg_cfg; + a_uint32_t len = 0; + + psgmii_node = of_find_node_by_name(NULL, "ess-psgmii"); + if (!psgmii_node) { + SSDK_ERROR("cannot find ess-psgmii node\n"); + return; + } + + SSDK_INFO("ess-psgmii DT exist!\n"); + reg_cfg = of_get_property(psgmii_node, "reg", &len); + if(!reg_cfg) { + SSDK_ERROR("%s: error reading device node properties for reg\n", + psgmii_node->name); + return; + } + + ssdk_dt_priv->psgmiireg_base_addr = be32_to_cpup(reg_cfg); + ssdk_dt_priv->psgmiireg_size = be32_to_cpup(reg_cfg + 1); + if (of_property_read_string(psgmii_node, "psgmii_access_mode", + (const char **)&ssdk_dt_priv->psgmii_reg_access_str)) { + SSDK_ERROR("%s: error reading properties for psmgii_access_mode\n", + psgmii_node->name); + return; + } + if(!strcmp(ssdk_dt_priv->psgmii_reg_access_str, "local bus")) + ssdk_dt_priv->psgmii_reg_access_mode = HSL_REG_LOCAL_BUS; + + return; +} +#endif +static sw_error_t ssdk_dt_parse_access_mode(struct device_node *switch_node, + ssdk_dt_cfg *ssdk_dt_priv) +{ + const __be32 *reg_cfg; + a_uint32_t len = 0; + + if (of_property_read_string(switch_node, "switch_access_mode", + (const char **)&ssdk_dt_priv->reg_access_mode)) { + SSDK_ERROR("%s: error reading properties for switch_access_mode\n", + switch_node->name); + return SW_BAD_PARAM; + } + + SSDK_INFO("switch_access_mode: %s\n", ssdk_dt_priv->reg_access_mode); + if(!strcmp(ssdk_dt_priv->reg_access_mode, "local bus")) { + ssdk_dt_priv->switch_reg_access_mode = HSL_REG_LOCAL_BUS; + + reg_cfg = of_get_property(switch_node, "reg", &len); + if(!reg_cfg) { + SSDK_ERROR("%s: error reading properties for reg\n", + switch_node->name); + return SW_BAD_PARAM; + } + ssdk_dt_priv->switchreg_base_addr = be32_to_cpup(reg_cfg); + ssdk_dt_priv->switchreg_size = be32_to_cpup(reg_cfg + 1); + + SSDK_INFO("switchreg_base_addr: 0x%x\n", ssdk_dt_priv->switchreg_base_addr); + SSDK_INFO("switchreg_size: 0x%x\n", ssdk_dt_priv->switchreg_size); + } + else { + ssdk_dt_priv->switch_reg_access_mode = HSL_REG_MDIO; + } + + return SW_OK; + +} +#if (defined(DESS) || defined(MP)) +#ifdef IN_LED +static void ssdk_dt_parse_led(struct device_node *switch_node, + ssdk_init_cfg *cfg) +{ + struct device_node *child = NULL; + const __be32 *led_source, *led_number; + a_uint8_t *led_str; + a_uint32_t len = 0, i = 0; + + for_each_available_child_of_node(switch_node, child) { + + led_source = of_get_property(child, "source", &len); + if (!led_source) { + continue; + } + cfg->led_source_cfg[i].led_source_id = be32_to_cpup(led_source); + led_number = of_get_property(child, "led", &len); + if (led_number) + cfg->led_source_cfg[i].led_num = be32_to_cpup(led_number); + if (!of_property_read_string(child, "mode", (const char **)&led_str)) { + if (!strcmp(led_str, "normal")) + cfg->led_source_cfg[i].led_pattern.mode = LED_PATTERN_MAP_EN; + if (!strcmp(led_str, "on")) + cfg->led_source_cfg[i].led_pattern.mode = LED_ALWAYS_ON; + if (!strcmp(led_str, "blink")) + cfg->led_source_cfg[i].led_pattern.mode = LED_ALWAYS_BLINK; + if (!strcmp(led_str, "off")) + cfg->led_source_cfg[i].led_pattern.mode = LED_ALWAYS_OFF; + } + if (!of_property_read_string(child, "speed", (const char **)&led_str)) { + if (!strcmp(led_str, "10M")) + cfg->led_source_cfg[i].led_pattern.map = LED_MAP_10M_SPEED; + if (!strcmp(led_str, "100M")) + cfg->led_source_cfg[i].led_pattern.map = LED_MAP_100M_SPEED; + if (!strcmp(led_str, "1000M")) + cfg->led_source_cfg[i].led_pattern.map = LED_MAP_1000M_SPEED; + if (!strcmp(led_str, "2500M")) + cfg->led_source_cfg[i].led_pattern.map = LED_MAP_2500M_SPEED; + if (!strcmp(led_str, "all")) + cfg->led_source_cfg[i].led_pattern.map = LED_MAP_ALL_SPEED; + } + if (!of_property_read_string(child, "freq", (const char **)&led_str)) { + if (!strcmp(led_str, "2Hz")) + cfg->led_source_cfg[i].led_pattern.freq = LED_BLINK_2HZ; + if (!strcmp(led_str, "4Hz")) + cfg->led_source_cfg[i].led_pattern.freq = LED_BLINK_4HZ; + if (!strcmp(led_str, "8Hz")) + cfg->led_source_cfg[i].led_pattern.freq = LED_BLINK_8HZ; + if (!strcmp(led_str, "auto")) + cfg->led_source_cfg[i].led_pattern.freq = LED_BLINK_TXRX; + } + if (!of_property_read_string(child, "active", (const char **)&led_str)) { + if (!strcmp(led_str, "high")) + cfg->led_source_cfg[i].led_pattern.map |= BIT(LED_ACTIVE_HIGH); + } + if (!of_property_read_string(child, "blink_en", (const char **)&led_str)) { + if (!strcmp(led_str, "disable")) + cfg->led_source_cfg[i].led_pattern.map &= ~(BIT(RX_TRAFFIC_BLINK_EN)| + BIT(TX_TRAFFIC_BLINK_EN)); + } + i++; + } + cfg->led_source_num = i; + SSDK_INFO("current dts led_source_num is %d\n",cfg->led_source_num); + + return; +} +#endif +#endif +static sw_error_t ssdk_dt_get_switch_node(struct device_node **switch_node, + a_uint32_t num) +{ + struct device_node *switch_instance = NULL; + char ess_switch_name[64] = {0}; + + if (num == 0) + snprintf(ess_switch_name, sizeof(ess_switch_name), "ess-switch"); + else + snprintf(ess_switch_name, sizeof(ess_switch_name), "ess-switch%d", num); + + /* + * Get reference to ESS SWITCH device node from ess-instance node firstly. + */ + switch_instance = of_find_node_by_name(NULL, "ess-instance"); + *switch_node = of_find_node_by_name(switch_instance, ess_switch_name); + if (!*switch_node) { + SSDK_WARN("cannot find ess-switch node\n"); + return SW_BAD_PARAM; + } + + SSDK_INFO("ess-switch DT exist!\n"); + + if (!of_device_is_available(*switch_node)) + { + SSDK_WARN("ess-switch node[%s] is disabled\n", ess_switch_name); + return SW_DISABLE; + } + + return SW_OK; +} + +sw_error_t ssdk_dt_parse(ssdk_init_cfg *cfg, a_uint32_t num, a_uint32_t *dev_id) +{ + sw_error_t rv = SW_OK; + struct device_node *switch_node = NULL; + ssdk_dt_cfg *ssdk_dt_priv = NULL; + a_uint32_t len = 0; + const __be32 *device_id; + + rv = ssdk_dt_get_switch_node(&switch_node, num); + SW_RTN_ON_ERROR(rv); + + device_id = of_get_property(switch_node, "device_id", &len); + if(!device_id) + *dev_id = 0; + else + *dev_id = be32_to_cpup(device_id); + + ssdk_dt_priv = ssdk_dt_global.ssdk_dt_switch_nodes[*dev_id]; + ssdk_dt_priv->device_id = *dev_id; + ssdk_dt_priv->ess_switch_flag = A_TRUE; + ssdk_dt_priv->of_node = switch_node; + ssdk_dt_priv->ess_clk= ERR_PTR(-ENOENT); + ssdk_dt_priv->cmnblk_clk = ERR_PTR(-ENOENT); + + if(of_property_read_bool(switch_node,"qcom,emulation")){ + ssdk_dt_priv->is_emulation = A_TRUE; + SSDK_INFO("RUMI emulation\n"); + } + /* parse common dts info */ + rv = ssdk_dt_parse_access_mode(switch_node, ssdk_dt_priv); + SW_RTN_ON_ERROR(rv); + ssdk_dt_parse_mac_mode(*dev_id, switch_node, cfg); + ssdk_dt_parse_mdio(*dev_id, switch_node, cfg); + ssdk_dt_parse_port_bmp(*dev_id, switch_node, cfg); + + if (of_device_is_compatible(switch_node, "qcom,ess-switch")) { + /* DESS chip */ +#ifdef DESS +#ifdef IN_LED + ssdk_dt_parse_led(switch_node, cfg); +#endif + ssdk_dt_parse_psgmii(ssdk_dt_priv); + + ssdk_dt_priv->ess_clk = of_clk_get_by_name(switch_node, "ess_clk"); + if (IS_ERR(ssdk_dt_priv->ess_clk)) + SSDK_INFO("ess_clk doesn't exist!\n"); +#endif + } + else if (of_device_is_compatible(switch_node, "qcom,ess-switch-ipq807x") || + of_device_is_compatible(switch_node, "qcom,ess-switch-ipq60xx")) { + /* HPPE chip */ +#ifdef HPPE + a_uint32_t mode = 0; +#ifdef IN_UNIPHY + ssdk_dt_parse_uniphy(*dev_id); +#endif +#ifdef IN_QOS + ssdk_dt_parse_scheduler_cfg(*dev_id, switch_node); +#endif + ssdk_dt_parse_intf_mac(); + + ssdk_dt_priv->cmnblk_clk = of_clk_get_by_name(switch_node, "cmn_ahb_clk"); + if (!of_property_read_u32(switch_node, "tm_tick_mode", &mode)) + ssdk_dt_priv->tm_tick_mode = mode; +#endif + } + else if (of_device_is_compatible(switch_node, "qcom,ess-switch-ipq50xx")) { +#ifdef MP + ssdk_dt_priv->emu_chip_ver = MP_GEPHY; +#ifdef IN_UNIPHY + ssdk_dt_parse_uniphy(*dev_id); +#endif +#ifdef IN_LED + ssdk_dt_parse_led(switch_node, cfg); +#endif + ssdk_dt_priv->cmnblk_clk = of_clk_get_by_name(switch_node, "cmn_ahb_clk"); +#endif + } + else if (of_device_is_compatible(switch_node, "qcom,ess-switch-qca83xx")) { + /* s17/s17c chip */ + SSDK_INFO("switch node is qca83xx!\n"); + } + else { + SSDK_WARN("invalid compatible property\n"); + } + + return SW_OK; +} + +static a_uint32_t ssdk_get_switch_port_nums(a_uint32_t dev_id) +{ + struct device_node *child, *mdio_np, *port_np, *switch_np, *switch_instance; + a_uint32_t port_count = 0, switch_id = 0; + + switch_instance = of_find_node_by_name(NULL, "ess-instance"); + if (switch_instance) { /* multi ess-switch */ + for_each_available_child_of_node(switch_instance, switch_np) { + if (of_property_read_u32(switch_np, "device_id", &switch_id) < 0) { + switch_id = 0; + } + if (switch_id == dev_id) { + port_np = of_find_node_by_name(switch_np, "qcom,port_phyinfo"); + if (port_np) { + for_each_available_child_of_node(port_np, child) + port_count++; + break; + } + } + } + } else { /* single ess-switch */ + switch_np = of_find_node_by_name(NULL, "ess-switch"); + if (switch_np && dev_id == 0) { + port_np = of_find_node_by_name(switch_np, "qcom,port_phyinfo"); + if (port_np) { + for_each_available_child_of_node(port_np, child) + port_count++; + } else { + mdio_np = of_find_node_by_name(NULL, "mido"); + if (mdio_np) { + for_each_available_child_of_node(mdio_np, child) + port_count++; + } + } + } + } + + return port_count; +} +#endif +#endif + +int ssdk_switch_device_num_init(void) +{ + struct device_node *switch_instance = NULL; + a_uint32_t len = 0, port_n = 0; + const __be32 *num_devices; + a_uint32_t dev_num = 1, dev_id = 0; + + switch_instance = of_find_node_by_name(NULL, "ess-instance"); + if (switch_instance) { + num_devices = of_get_property(switch_instance, "num_devices", &len); + if (num_devices) + dev_num = be32_to_cpup(num_devices); + } + + ssdk_dt_global.ssdk_dt_switch_nodes = kzalloc(dev_num * sizeof(ssdk_dt_cfg *), GFP_KERNEL); + if (ssdk_dt_global.ssdk_dt_switch_nodes == NULL) { + return -ENOMEM; + } + + for (dev_id = 0; dev_id < dev_num; dev_id++) { + ssdk_dt_global.ssdk_dt_switch_nodes[dev_id] = kzalloc(sizeof(ssdk_dt_cfg), + GFP_KERNEL); + if (ssdk_dt_global.ssdk_dt_switch_nodes[dev_id] == NULL) { + return -ENOMEM; + } + +#ifndef BOARD_AR71XX +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) + port_n = ssdk_get_switch_port_nums(dev_id); +#endif +#endif + if (!port_n) { + port_n = SW_MAX_NR_PORT; + } + ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]->port_phyinfo = kzalloc(port_n * + sizeof(ssdk_port_phyinfo), GFP_KERNEL); + if (!ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]->port_phyinfo) { + return -ENOMEM; + } + ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]->phyinfo_num = port_n; + + ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]->switch_reg_access_mode = HSL_REG_MDIO; + ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]->psgmii_reg_access_mode = HSL_REG_MDIO; + ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]->ess_switch_flag = A_FALSE; + } + + ssdk_dt_global.num_devices = dev_num; + SSDK_INFO("ess-switch dts node number: %d\n", dev_num); + + return 0; +} + +void ssdk_switch_device_num_exit(void) +{ + a_uint32_t dev_id = 0; + + for (dev_id = 0; dev_id < ssdk_dt_global.num_devices; dev_id++) { + if (ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]->port_phyinfo) { + kfree(ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]->port_phyinfo); + ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]->port_phyinfo = NULL; + } + + if (ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]) + kfree(ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]); + ssdk_dt_global.ssdk_dt_switch_nodes[dev_id] = NULL; + } + + if (ssdk_dt_global.ssdk_dt_switch_nodes) + kfree(ssdk_dt_global.ssdk_dt_switch_nodes); + ssdk_dt_global.ssdk_dt_switch_nodes = NULL; + + ssdk_dt_global.num_devices = 0; +} + +a_uint32_t ssdk_switch_device_num_get(void) +{ + return ssdk_dt_global.num_devices; +} + +a_bool_t ssdk_is_emulation(a_uint32_t dev_id) +{ + return ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]->is_emulation; +} +a_uint32_t ssdk_emu_chip_ver_get(a_uint32_t dev_id) +{ + return ssdk_dt_global.ssdk_dt_switch_nodes[dev_id]->emu_chip_ver; +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/init/ssdk_hppe.c b/feeds/ipq807x/qca-ssdk/src/src/init/ssdk_hppe.c new file mode 100644 index 000000000..e62747e40 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/init/ssdk_hppe.c @@ -0,0 +1,1271 @@ +/* + * Copyright (c) 2012, 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. + */ + +#include "ssdk_init.h" +#include "ssdk_dts.h" +#include "adpt.h" +#include "adpt_hppe.h" +#include "fal.h" +#include "ref_vsi.h" +#include "ssdk_clk.h" +#include "hsl_phy.h" + +#if defined(IN_VSI) +static sw_error_t qca_hppe_vsi_hw_init(a_uint32_t dev_id) +{ + return ppe_vsi_init(dev_id); +} +#endif + +#if defined(IN_FDB) +static sw_error_t qca_hppe_fdb_hw_init(a_uint32_t dev_id) +{ + a_uint32_t port = 0; + adpt_api_t *p_api; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + SW_RTN_ON_NULL(p_api->adpt_port_bridge_txmac_set); + + for(port = SSDK_PHYSICAL_PORT0; port <= SSDK_PHYSICAL_PORT7; port++) { + fal_fdb_port_learning_ctrl_set(dev_id, port, A_TRUE, FAL_MAC_FRWRD); + fal_fdb_port_stamove_ctrl_set(dev_id, port, A_TRUE, FAL_MAC_FRWRD); + fal_portvlan_member_update(dev_id, port, 0x7f); + if (port == SSDK_PHYSICAL_PORT0 || port == SSDK_PHYSICAL_PORT7) { + p_api->adpt_port_bridge_txmac_set(dev_id, port, A_TRUE); + } else { + p_api->adpt_port_bridge_txmac_set(dev_id, port, A_FALSE); + } + fal_port_promisc_mode_set(dev_id, port, A_TRUE); + } + + fal_fdb_aging_ctrl_set(dev_id, A_TRUE); + fal_fdb_learning_ctrl_set(dev_id, A_TRUE); + + return SW_OK; +} +#endif + +#if defined(IN_CTRLPKT) +#define RFDB_PROFILE_ID_STP 31 +static sw_error_t qca_hppe_ctlpkt_hw_init(a_uint32_t dev_id) +{ + fal_mac_addr_t mcast_mac_addr; + fal_ctrlpkt_action_t ctrlpkt_action; + fal_ctrlpkt_profile_t ctrlpkt_profile; + sw_error_t rv = SW_OK; + + memset(&ctrlpkt_action, 0, sizeof(ctrlpkt_action)); + memset(&ctrlpkt_profile, 0, sizeof(ctrlpkt_profile)); + memset(&mcast_mac_addr, 0, sizeof(mcast_mac_addr)); + + mcast_mac_addr.uc[0] = 0x01; + mcast_mac_addr.uc[1] = 0x80; + mcast_mac_addr.uc[2] = 0xc2; + rv = fal_mgmtctrl_rfdb_profile_set(dev_id, RFDB_PROFILE_ID_STP, + &mcast_mac_addr); + SW_RTN_ON_ERROR(rv); + + ctrlpkt_action.action = FAL_MAC_RDT_TO_CPU; + ctrlpkt_action.in_stp_bypass = A_TRUE; + + ctrlpkt_profile.action = ctrlpkt_action; + ctrlpkt_profile.port_map = qca_ssdk_port_bmp_get(dev_id); + ctrlpkt_profile.rfdb_profile_bitmap = (1 << RFDB_PROFILE_ID_STP); + rv = fal_mgmtctrl_ctrlpkt_profile_add(dev_id, &ctrlpkt_profile); + + return rv; +} +#endif + +#if defined(IN_PORTCONTROL) +static sw_error_t +qca_hppe_portctrl_hw_init(a_uint32_t dev_id) +{ + a_uint32_t i = 0; + a_uint32_t port_max = SSDK_PHYSICAL_PORT7; +#if defined(CPPE) + fal_loopback_config_t loopback_cfg; +#endif + + if(adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) { + SSDK_INFO("Cypress PPE port initializing\n"); + port_max = SSDK_PHYSICAL_PORT6; + } else { + SSDK_INFO("Hawkeye PPE port initializing\n"); + port_max = SSDK_PHYSICAL_PORT7; + } + for(i = SSDK_PHYSICAL_PORT1; i < port_max; i++) { + qca_hppe_port_mac_type_set(dev_id, i, PORT_GMAC_TYPE); + fal_port_txmac_status_set (dev_id, i, A_FALSE); + fal_port_rxmac_status_set (dev_id, i, A_FALSE); + fal_port_rxfc_status_set(dev_id, i, A_FALSE); + fal_port_txfc_status_set(dev_id, i, A_FALSE); + fal_port_max_frame_size_set(dev_id, i, SSDK_MAX_FRAME_SIZE); + } + + for(i = SSDK_PHYSICAL_PORT5; i < port_max; i++) { + qca_hppe_port_mac_type_set(dev_id, i, PORT_XGMAC_TYPE); + fal_port_txmac_status_set (dev_id, i, A_FALSE); + fal_port_rxmac_status_set (dev_id, i, A_FALSE); + fal_port_rxfc_status_set(dev_id, i, A_FALSE); + fal_port_txfc_status_set(dev_id, i, A_FALSE); + fal_port_max_frame_size_set(dev_id, i, SSDK_MAX_FRAME_SIZE); + } + +#if defined(CPPE) + if (adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) { + loopback_cfg.enable = A_TRUE; + loopback_cfg.crc_stripped = A_TRUE; + loopback_cfg.loopback_rate = FAL_DEFAULT_LOOPBACK_RATE; /* Mpps */ + fal_switch_port_loopback_set(dev_id, SSDK_PHYSICAL_PORT6, + &loopback_cfg); + fal_port_max_frame_size_set(dev_id, SSDK_PHYSICAL_PORT6, + SSDK_MAX_FRAME_SIZE); + } +#endif + return SW_OK; +} +#endif + +#if defined(IN_POLICER) +static sw_error_t +qca_hppe_policer_hw_init(a_uint32_t dev_id) +{ + a_uint32_t i = 0; + + fal_policer_timeslot_set(dev_id, HPPE_POLICER_TIMESLOT_DFT); + + for (i = SSDK_PHYSICAL_PORT0; i <= SSDK_PHYSICAL_PORT7; i++) { + fal_port_policer_compensation_byte_set(dev_id, i, 4); + } + + return SW_OK; +} +#endif + +#if defined(IN_SHAPER) +static sw_error_t +qca_hppe_shaper_hw_init(a_uint32_t dev_id) +{ + fal_shaper_token_number_t port_token_number, queue_token_number; + fal_shaper_token_number_t flow_token_number; + a_uint32_t i = 0; + + port_token_number.c_token_number_negative_en = A_FALSE; + port_token_number.c_token_number = HPPE_MAX_C_TOKEN_NUM; + queue_token_number.c_token_number_negative_en = A_FALSE; + queue_token_number.c_token_number = HPPE_MAX_C_TOKEN_NUM; + queue_token_number.e_token_number_negative_en = A_FALSE; + queue_token_number.e_token_number = HPPE_MAX_E_TOKEN_NUM; + flow_token_number.c_token_number_negative_en = A_FALSE; + flow_token_number.c_token_number = HPPE_MAX_C_TOKEN_NUM; + flow_token_number.e_token_number_negative_en = A_FALSE; + flow_token_number.e_token_number = HPPE_MAX_E_TOKEN_NUM; + + for (i = SSDK_PHYSICAL_PORT0; i <= SSDK_PHYSICAL_PORT7; i++) { + fal_port_shaper_token_number_set(dev_id, i, &port_token_number); + } + + for(i = 0; i < SSDK_L0SCHEDULER_CFG_MAX; i ++) { + fal_queue_shaper_token_number_set(dev_id, i, &queue_token_number); + } + + for(i = 0; i < SSDK_L1SCHEDULER_CFG_MAX; i ++) { + fal_flow_shaper_token_number_set(dev_id, i, &flow_token_number); + } + + fal_port_shaper_timeslot_set(dev_id, HPPE_PORT_SHAPER_TIMESLOT_DFT); + fal_flow_shaper_timeslot_set(dev_id, HPPE_FLOW_SHAPER_TIMESLOT_DFT); + fal_queue_shaper_timeslot_set(dev_id, HPPE_QUEUE_SHAPER_TIMESLOT_DFT); + fal_shaper_ipg_preamble_length_set(dev_id, + HPPE_SHAPER_IPG_PREAMBLE_LEN_DFT); + + return SW_OK; +} +#endif + +#if defined(IN_PORTVLAN) +static sw_error_t +qca_hppe_portvlan_hw_init(a_uint32_t dev_id) +{ + a_uint32_t port_id = 0, vsi_idx = 0; + fal_global_qinq_mode_t global_qinq_mode; + fal_port_qinq_role_t port_qinq_role; + fal_tpid_t in_eg_tpid; + fal_vlantag_egress_mode_t vlantag_eg_mode; + + /* configure ingress/egress global QinQ mode as ctag/ctag */ + global_qinq_mode.mask = 0x3; + global_qinq_mode.ingress_mode = FAL_QINQ_CTAG_MODE; + global_qinq_mode.egress_mode = FAL_QINQ_CTAG_MODE; + fal_global_qinq_mode_set(dev_id, &global_qinq_mode); + + /* configure port0, port7 ingress/egress QinQ role as core/core */ + port_qinq_role.mask = 0x3; + port_qinq_role.ingress_port_role = FAL_QINQ_CORE_PORT; + port_qinq_role.egress_port_role = FAL_QINQ_CORE_PORT; + fal_port_qinq_mode_set(dev_id, SSDK_PHYSICAL_PORT0, &port_qinq_role); + fal_port_qinq_mode_set(dev_id, SSDK_PHYSICAL_PORT7, &port_qinq_role); + /* configure port1 - port6 ingress/egress QinQ role as edge/edge */ + port_qinq_role.mask = 0x3; + port_qinq_role.ingress_port_role = FAL_QINQ_EDGE_PORT; + port_qinq_role.egress_port_role = FAL_QINQ_EDGE_PORT; + for (port_id = SSDK_PHYSICAL_PORT1; port_id <= SSDK_PHYSICAL_PORT6; + port_id++) { + fal_port_qinq_mode_set(dev_id, port_id, &port_qinq_role); + } + + /* configure ingress and egress stpid/ctpid as 0x88a8/0x8100 */ + in_eg_tpid.mask = 0x3; + in_eg_tpid.ctpid = FAL_DEF_VLAN_CTPID; + in_eg_tpid.stpid = FAL_DEF_VLAN_STPID; + fal_ingress_tpid_set(dev_id, &in_eg_tpid); + fal_egress_tpid_set(dev_id, &in_eg_tpid); + + /* configure the port0 - port7 of vsi0 - vsi31 to unmodified */ + for (vsi_idx = 0; vsi_idx <= FAL_VSI_MAX; vsi_idx++) { + for (port_id = SSDK_PHYSICAL_PORT0; + port_id <= SSDK_PHYSICAL_PORT7; port_id++) { + fal_port_vsi_egmode_set(dev_id, vsi_idx, + port_id, FAL_EG_UNMODIFIED); + } + } + + vlantag_eg_mode.mask = 0x3; + vlantag_eg_mode.stag_mode = FAL_EG_UNTOUCHED; + vlantag_eg_mode.ctag_mode = FAL_EG_UNTOUCHED; + /*stag/ctag egress mode as untouched/untouched*/ + fal_port_vlantag_egmode_set(dev_id, SSDK_PHYSICAL_PORT0, + &vlantag_eg_mode); + fal_port_vlantag_egmode_set(dev_id, SSDK_PHYSICAL_PORT7, + &vlantag_eg_mode); + /*vsi tag mode control to disable*/ + fal_port_vlantag_vsi_egmode_enable(dev_id, SSDK_PHYSICAL_PORT0, + A_FALSE); + fal_port_vlantag_vsi_egmode_enable(dev_id, SSDK_PHYSICAL_PORT7, + A_FALSE); + /*ingress vlan translation mismatched command as forward*/ + fal_port_vlan_xlt_miss_cmd_set(dev_id, SSDK_PHYSICAL_PORT0, + FAL_MAC_FRWRD); + + vlantag_eg_mode.stag_mode = FAL_EG_UNMODIFIED; + vlantag_eg_mode.ctag_mode = FAL_EG_UNMODIFIED; + for (port_id = SSDK_PHYSICAL_PORT1; port_id <= SSDK_PHYSICAL_PORT6; + port_id++) { + /*ingress vlan translation mismatched command as forward*/ + fal_port_vlan_xlt_miss_cmd_set(dev_id, port_id, FAL_MAC_FRWRD); + /*vsi tag mode control to enable*/ + fal_port_vlantag_vsi_egmode_enable(dev_id, port_id, A_TRUE); + /*stag/ctag egress mode as unmodified/unmodified*/ + fal_port_vlantag_egmode_set(dev_id, port_id, &vlantag_eg_mode); + } + + return SW_OK; +} +#endif + +#if defined(IN_BM) && defined(IN_QOS) +fal_port_scheduler_cfg_t port_scheduler0_tbl[] = { + {0xee, 6, 0}, + {0xde, 4, 5}, + {0x9f, 0, 6}, + {0xbe, 5, 0}, + {0x7e, 6, 7}, + {0x5f, 0, 5}, + {0x9f, 7, 6}, + {0xbe, 5, 0}, + {0xfc, 6, 1}, + {0xdd, 0, 5}, + {0xde, 1, 0}, + {0xbe, 5, 6}, + {0xbb, 0, 2}, + {0xdb, 6, 5}, + {0xde, 2, 0}, + {0xbe, 5, 6}, + {0x3f, 0, 7}, + {0x7e, 6, 0}, + {0xde, 7, 5}, + {0x9f, 0, 6}, + {0xb7, 5, 3}, + {0xf6, 6, 0}, + {0xde, 3, 5}, + {0x9f, 0, 6}, + {0xbe, 5, 0}, + {0xee, 6, 4}, + {0xcf, 0, 5}, + {0x9f, 4, 6}, + {0xbe, 5, 0}, + {0x7e, 6, 7}, + {0x5f, 0, 5}, + {0xde, 7, 0}, + {0xbe, 5, 6}, + {0xbd, 0, 1}, + {0xdd, 6, 5}, + {0xde, 1, 0}, + {0xbe, 5, 6}, + {0xbb, 0, 2}, + {0xfa, 6, 0}, + {0xde, 2, 5}, + {0x9f, 0, 6}, + {0x3f, 5, 7}, + {0x7e, 6, 0}, + {0xde, 7, 5}, + {0x9f, 0, 6}, + {0xb7, 5, 3}, + {0xf6, 6, 0}, + {0xde, 3, 5}, + {0x9f, 0, 6}, + {0xaf, 5, 4}, +}; + +fal_port_scheduler_cfg_t port_scheduler1_tbl[] = { + {0x30, 5, 6}, + {0x30, 4, 0}, + {0x30, 5, 6}, + {0x11, 0, 5}, + {0x50, 6, 0}, + {0x30, 5, 6}, + {0x21, 0, 4}, + {0x21, 5, 6}, + {0x30, 4, 0}, + {0x50, 6, 5}, + {0x11, 0, 6}, + {0x30, 5, 0}, + {0x30, 4, 6}, + {0x11, 0, 5}, + {0x50, 6, 0}, + {0x30, 5, 6}, + {0x11, 0, 5}, + {0x11, 4, 6}, + {0x30, 5, 0}, + {0x50, 6, 5}, + {0x11, 0, 6}, + {0x30, 5, 0}, + {0x30, 4, 6}, + {0x11, 0, 5}, + {0x50, 6, 0}, +}; + +fal_port_scheduler_cfg_t cppe_port_scheduler0_tbl[] = { + {0xb7, 0, 6}, + {0xbe, 3, 0}, + {0xde, 6, 5}, + {0xdd, 0, 1}, + {0xbd, 5, 6}, + {0xbe, 1, 0}, + {0xee, 6, 4}, + {0xcf, 0, 5}, + {0x9f, 4, 6}, + {0xbe, 5, 0}, + {0x7e, 6, 7}, + {0x5f, 0, 5}, + {0x9f, 7, 6}, + {0xbe, 5, 0}, + {0xfa, 6, 2}, + {0xbb, 0, 6}, + {0x9f, 2, 5}, + {0xcf, 6, 4}, + {0xee, 5, 0}, + {0xbe, 4, 6}, + {0x3f, 0, 7}, + {0x5f, 6, 5}, + {0xde, 7, 0}, + {0xbe, 5, 6}, + {0xb7, 0, 3}, + {0xe7, 6, 4}, + {0xee, 3, 0}, + {0xbe, 4, 6}, + {0x9f, 0, 5}, + {0xdd, 6, 1}, + {0xfc, 5, 0}, + {0xbe, 1, 6}, + {0x9f, 0, 5}, + {0x5f, 6, 7}, + {0x7e, 5, 0}, + {0xbe, 7, 6}, + {0xaf, 0, 4}, + {0xcf, 6, 5}, + {0x9f, 4, 6}, + {0xbe, 5, 0}, + {0xfa, 6, 2}, + {0xdb, 0, 5}, + {0x9f, 2, 6}, + {0xbe, 5, 0}, + {0x7e, 6, 7}, + {0x6f, 0, 4}, + {0xaf, 7, 6}, + {0x9f, 4, 5}, + {0xde, 6, 0}, + {0xf6, 5, 3}, +}; + +fal_port_tdm_tick_cfg_t port_tdm0_tbl[] = { + {1, FAL_PORT_TDB_DIR_INGRESS, 0}, + {1, FAL_PORT_TDB_DIR_EGRESS, 5}, + {1, FAL_PORT_TDB_DIR_INGRESS, 5}, + {1, FAL_PORT_TDB_DIR_EGRESS, 7}, + {1, FAL_PORT_TDB_DIR_INGRESS, 1}, + {1, FAL_PORT_TDB_DIR_EGRESS, 6}, + {1, FAL_PORT_TDB_DIR_INGRESS, 6}, + {1, FAL_PORT_TDB_DIR_EGRESS, 0}, + {1, FAL_PORT_TDB_DIR_INGRESS, 0}, + {1, FAL_PORT_TDB_DIR_EGRESS, 7}, + {1, FAL_PORT_TDB_DIR_INGRESS, 7}, + {1, FAL_PORT_TDB_DIR_EGRESS, 5}, + {1, FAL_PORT_TDB_DIR_INGRESS, 5}, + {1, FAL_PORT_TDB_DIR_EGRESS, 0}, + {1, FAL_PORT_TDB_DIR_INGRESS, 6}, + {1, FAL_PORT_TDB_DIR_EGRESS, 6}, + {1, FAL_PORT_TDB_DIR_INGRESS, 0}, + {1, FAL_PORT_TDB_DIR_EGRESS, 3}, + {1, FAL_PORT_TDB_DIR_INGRESS, 2}, + {1, FAL_PORT_TDB_DIR_EGRESS, 7}, + {1, FAL_PORT_TDB_DIR_INGRESS, 7}, + {1, FAL_PORT_TDB_DIR_EGRESS, 5}, + {1, FAL_PORT_TDB_DIR_INGRESS, 5}, + {1, FAL_PORT_TDB_DIR_EGRESS, 0}, + {1, FAL_PORT_TDB_DIR_INGRESS, 0}, + {1, FAL_PORT_TDB_DIR_EGRESS, 6}, + {1, FAL_PORT_TDB_DIR_INGRESS, 6}, + {1, FAL_PORT_TDB_DIR_EGRESS, 0}, + {1, FAL_PORT_TDB_DIR_INGRESS, 7}, + {1, FAL_PORT_TDB_DIR_EGRESS, 7}, + {1, FAL_PORT_TDB_DIR_INGRESS, 5}, + {1, FAL_PORT_TDB_DIR_EGRESS, 5}, + {1, FAL_PORT_TDB_DIR_INGRESS, 0}, + {1, FAL_PORT_TDB_DIR_EGRESS, 0}, + {1, FAL_PORT_TDB_DIR_INGRESS, 6}, + {1, FAL_PORT_TDB_DIR_EGRESS, 6}, + {1, FAL_PORT_TDB_DIR_INGRESS, 0}, + {1, FAL_PORT_TDB_DIR_EGRESS, 0}, + {1, FAL_PORT_TDB_DIR_INGRESS, 7}, + {1, FAL_PORT_TDB_DIR_EGRESS, 7}, + {1, FAL_PORT_TDB_DIR_INGRESS, 0}, + {1, FAL_PORT_TDB_DIR_EGRESS, 5}, + {1, FAL_PORT_TDB_DIR_INGRESS, 5}, + {1, FAL_PORT_TDB_DIR_EGRESS, 4}, + {1, FAL_PORT_TDB_DIR_INGRESS, 6}, + {1, FAL_PORT_TDB_DIR_EGRESS, 6}, + {1, FAL_PORT_TDB_DIR_INGRESS, 7}, + {1, FAL_PORT_TDB_DIR_EGRESS, 0}, + {1, FAL_PORT_TDB_DIR_INGRESS, 0}, + {1, FAL_PORT_TDB_DIR_EGRESS, 7}, + {1, FAL_PORT_TDB_DIR_INGRESS, 4}, + {1, FAL_PORT_TDB_DIR_EGRESS, 5}, + {1, FAL_PORT_TDB_DIR_INGRESS, 5}, + {1, FAL_PORT_TDB_DIR_EGRESS, 0}, + {1, FAL_PORT_TDB_DIR_INGRESS, 6}, + {1, FAL_PORT_TDB_DIR_EGRESS, 6}, + {1, FAL_PORT_TDB_DIR_INGRESS, 0}, + {1, FAL_PORT_TDB_DIR_EGRESS, 1}, + {1, FAL_PORT_TDB_DIR_INGRESS, 7}, + {1, FAL_PORT_TDB_DIR_EGRESS, 7}, + {1, FAL_PORT_TDB_DIR_INGRESS, 0}, + {1, FAL_PORT_TDB_DIR_EGRESS, 5}, + {1, FAL_PORT_TDB_DIR_INGRESS, 5}, + {1, FAL_PORT_TDB_DIR_EGRESS, 0}, + {1, FAL_PORT_TDB_DIR_INGRESS, 0}, + {1, FAL_PORT_TDB_DIR_EGRESS, 6}, + {1, FAL_PORT_TDB_DIR_INGRESS, 6}, + {1, FAL_PORT_TDB_DIR_EGRESS, 0}, + {1, FAL_PORT_TDB_DIR_INGRESS, 7}, + {1, FAL_PORT_TDB_DIR_EGRESS, 7}, + {1, FAL_PORT_TDB_DIR_INGRESS, 5}, + {1, FAL_PORT_TDB_DIR_EGRESS, 5}, + {1, FAL_PORT_TDB_DIR_INGRESS, 0}, + {1, FAL_PORT_TDB_DIR_EGRESS, 0}, + {1, FAL_PORT_TDB_DIR_INGRESS, 6}, + {1, FAL_PORT_TDB_DIR_EGRESS, 6}, + {1, FAL_PORT_TDB_DIR_INGRESS, 3}, + {1, FAL_PORT_TDB_DIR_EGRESS, 0}, + {1, FAL_PORT_TDB_DIR_INGRESS, 7}, + {1, FAL_PORT_TDB_DIR_EGRESS, 7}, + {1, FAL_PORT_TDB_DIR_INGRESS, 0}, + {1, FAL_PORT_TDB_DIR_EGRESS, 5}, + {1, FAL_PORT_TDB_DIR_INGRESS, 5}, + {1, FAL_PORT_TDB_DIR_EGRESS, 0}, + {1, FAL_PORT_TDB_DIR_INGRESS, 6}, + {1, FAL_PORT_TDB_DIR_EGRESS, 6}, + {1, FAL_PORT_TDB_DIR_INGRESS, 7}, + {1, FAL_PORT_TDB_DIR_EGRESS, 2}, + {1, FAL_PORT_TDB_DIR_INGRESS, 0}, + {1, FAL_PORT_TDB_DIR_EGRESS, 7}, + {1, FAL_PORT_TDB_DIR_INGRESS, 5}, + {1, FAL_PORT_TDB_DIR_EGRESS, 5}, + {1, FAL_PORT_TDB_DIR_INGRESS, 6}, + {1, FAL_PORT_TDB_DIR_EGRESS, 0}, + {1, FAL_PORT_TDB_DIR_INGRESS, 7}, + {1, FAL_PORT_TDB_DIR_EGRESS, 6}, +}; + +fal_port_tdm_tick_cfg_t cppe_port_tdm0_tbl[] = { + {1, FAL_PORT_TDB_DIR_INGRESS, 0}, + {1, FAL_PORT_TDB_DIR_EGRESS, 0}, + {1, FAL_PORT_TDB_DIR_INGRESS, 5}, + {1, FAL_PORT_TDB_DIR_EGRESS, 4}, + {1, FAL_PORT_TDB_DIR_INGRESS, 1}, + {1, FAL_PORT_TDB_DIR_EGRESS, 5}, + {1, FAL_PORT_TDB_DIR_INGRESS, 6}, + {1, FAL_PORT_TDB_DIR_EGRESS, 6}, + {1, FAL_PORT_TDB_DIR_INGRESS, 0}, + {1, FAL_PORT_TDB_DIR_EGRESS, 0}, + {1, FAL_PORT_TDB_DIR_INGRESS, 7}, + {1, FAL_PORT_TDB_DIR_EGRESS, 7}, + {1, FAL_PORT_TDB_DIR_INGRESS, 4}, + {1, FAL_PORT_TDB_DIR_EGRESS, 0}, + {1, FAL_PORT_TDB_DIR_INGRESS, 6}, + {1, FAL_PORT_TDB_DIR_EGRESS, 5}, + {1, FAL_PORT_TDB_DIR_INGRESS, 0}, + {1, FAL_PORT_TDB_DIR_EGRESS, 0}, + {1, FAL_PORT_TDB_DIR_INGRESS, 2}, + {1, FAL_PORT_TDB_DIR_EGRESS, 6}, + {1, FAL_PORT_TDB_DIR_INGRESS, 7}, + {1, FAL_PORT_TDB_DIR_EGRESS, 7}, + {1, FAL_PORT_TDB_DIR_INGRESS, 5}, + {1, FAL_PORT_TDB_DIR_EGRESS, 5}, + {1, FAL_PORT_TDB_DIR_INGRESS, 0}, + {1, FAL_PORT_TDB_DIR_EGRESS, 0}, + {1, FAL_PORT_TDB_DIR_INGRESS, 6}, + {1, FAL_PORT_TDB_DIR_EGRESS, 6}, + {1, FAL_PORT_TDB_DIR_INGRESS, 7}, + {1, FAL_PORT_TDB_DIR_EGRESS, 3}, + {1, FAL_PORT_TDB_DIR_INGRESS, 5}, + {1, FAL_PORT_TDB_DIR_EGRESS, 7}, + {1, FAL_PORT_TDB_DIR_INGRESS, 0}, + {1, FAL_PORT_TDB_DIR_EGRESS, 0}, + {1, FAL_PORT_TDB_DIR_INGRESS, 6}, + {1, FAL_PORT_TDB_DIR_EGRESS, 5}, + {1, FAL_PORT_TDB_DIR_INGRESS, 0}, + {1, FAL_PORT_TDB_DIR_EGRESS, 6}, + {1, FAL_PORT_TDB_DIR_INGRESS, 7}, + {1, FAL_PORT_TDB_DIR_EGRESS, 7}, + {1, FAL_PORT_TDB_DIR_INGRESS, 0}, + {1, FAL_PORT_TDB_DIR_EGRESS, 0}, + {1, FAL_PORT_TDB_DIR_INGRESS, 5}, + {1, FAL_PORT_TDB_DIR_EGRESS, 4}, + {1, FAL_PORT_TDB_DIR_INGRESS, 6}, + {1, FAL_PORT_TDB_DIR_EGRESS, 6}, + {1, FAL_PORT_TDB_DIR_INGRESS, 7}, + {1, FAL_PORT_TDB_DIR_EGRESS, 7}, + {1, FAL_PORT_TDB_DIR_INGRESS, 0}, + {1, FAL_PORT_TDB_DIR_EGRESS, 0}, + {1, FAL_PORT_TDB_DIR_INGRESS, 4}, + {1, FAL_PORT_TDB_DIR_EGRESS, 5}, + {1, FAL_PORT_TDB_DIR_INGRESS, 5}, + {1, FAL_PORT_TDB_DIR_EGRESS, 1}, + {1, FAL_PORT_TDB_DIR_INGRESS, 6}, + {1, FAL_PORT_TDB_DIR_EGRESS, 6}, + {1, FAL_PORT_TDB_DIR_INGRESS, 0}, + {1, FAL_PORT_TDB_DIR_EGRESS, 0}, + {1, FAL_PORT_TDB_DIR_INGRESS, 7}, + {1, FAL_PORT_TDB_DIR_EGRESS, 7}, + {1, FAL_PORT_TDB_DIR_INGRESS, 0}, + {1, FAL_PORT_TDB_DIR_EGRESS, 4}, + {1, FAL_PORT_TDB_DIR_INGRESS, 5}, + {1, FAL_PORT_TDB_DIR_EGRESS, 6}, + {1, FAL_PORT_TDB_DIR_INGRESS, 0}, + {1, FAL_PORT_TDB_DIR_EGRESS, 0}, + {1, FAL_PORT_TDB_DIR_INGRESS, 6}, + {1, FAL_PORT_TDB_DIR_EGRESS, 2}, + {1, FAL_PORT_TDB_DIR_INGRESS, 7}, + {1, FAL_PORT_TDB_DIR_EGRESS, 7}, + {1, FAL_PORT_TDB_DIR_INGRESS, 5}, + {1, FAL_PORT_TDB_DIR_EGRESS, 5}, + {1, FAL_PORT_TDB_DIR_INGRESS, 0}, + {1, FAL_PORT_TDB_DIR_EGRESS, 0}, + {1, FAL_PORT_TDB_DIR_INGRESS, 6}, + {1, FAL_PORT_TDB_DIR_EGRESS, 6}, + {1, FAL_PORT_TDB_DIR_INGRESS, 3}, + {1, FAL_PORT_TDB_DIR_EGRESS, 7}, + {1, FAL_PORT_TDB_DIR_INGRESS, 7}, + {1, FAL_PORT_TDB_DIR_EGRESS, 5}, + {1, FAL_PORT_TDB_DIR_INGRESS, 0}, + {1, FAL_PORT_TDB_DIR_EGRESS, 0}, + {1, FAL_PORT_TDB_DIR_INGRESS, 5}, + {1, FAL_PORT_TDB_DIR_EGRESS, 6}, + {1, FAL_PORT_TDB_DIR_INGRESS, 6}, + {1, FAL_PORT_TDB_DIR_EGRESS, 0}, + {1, FAL_PORT_TDB_DIR_INGRESS, 7}, + {1, FAL_PORT_TDB_DIR_EGRESS, 7}, + {1, FAL_PORT_TDB_DIR_INGRESS, 0}, + {1, FAL_PORT_TDB_DIR_EGRESS, 0}, + {1, FAL_PORT_TDB_DIR_INGRESS, 4}, + {1, FAL_PORT_TDB_DIR_EGRESS, 5}, + {1, FAL_PORT_TDB_DIR_INGRESS, 6}, + {1, FAL_PORT_TDB_DIR_EGRESS, 6}, + {1, FAL_PORT_TDB_DIR_INGRESS, 7}, + {1, FAL_PORT_TDB_DIR_EGRESS, 7}, +}; + +static sw_error_t +qca_hppe_tdm_hw_init(a_uint32_t dev_id) +{ + adpt_api_t *p_api; + a_uint32_t i = 0; + a_uint32_t num; + fal_port_tdm_ctrl_t tdm_ctrl; + fal_port_scheduler_cfg_t *scheduler_cfg; + fal_port_tdm_tick_cfg_t *bm_cfg; + a_uint8_t tm_tick_mode, bm_tick_mode; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + SW_RTN_ON_NULL(p_api->adpt_port_scheduler_cfg_set); + SW_RTN_ON_NULL(p_api->adpt_tdm_tick_num_set); + + tm_tick_mode = ssdk_tm_tick_mode_get(dev_id); + bm_tick_mode = ssdk_bm_tick_mode_get(dev_id); + + if (tm_tick_mode == 0) { + if (adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) { + num = sizeof(cppe_port_scheduler0_tbl) / + sizeof(fal_port_scheduler_cfg_t); + scheduler_cfg = cppe_port_scheduler0_tbl; + } else { + num = sizeof(port_scheduler0_tbl) / + sizeof(fal_port_scheduler_cfg_t); + scheduler_cfg = port_scheduler0_tbl; + } + } else if (tm_tick_mode == 1) { + num = sizeof(port_scheduler1_tbl) / sizeof(fal_port_scheduler_cfg_t); + scheduler_cfg = port_scheduler1_tbl; + } else { + return SW_BAD_VALUE; + } + + for (i = 0; i < num; i++) { + p_api->adpt_port_scheduler_cfg_set(dev_id, i, &scheduler_cfg[i]); + } + p_api->adpt_tdm_tick_num_set(dev_id, num); + + SW_RTN_ON_NULL(p_api->adpt_port_tdm_tick_cfg_set); + SW_RTN_ON_NULL(p_api->adpt_port_tdm_ctrl_set); + + if (bm_tick_mode == 0) { + if (adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) { + num = sizeof(cppe_port_tdm0_tbl) / + sizeof(fal_port_tdm_tick_cfg_t); + bm_cfg = cppe_port_tdm0_tbl; + } else { + num = sizeof(port_tdm0_tbl) / + sizeof(fal_port_tdm_tick_cfg_t); + bm_cfg = port_tdm0_tbl; + } + } else { + return SW_BAD_VALUE; + } + for (i = 0; i < num; i++) { + p_api->adpt_port_tdm_tick_cfg_set(dev_id, i, &bm_cfg[i]); + } + tdm_ctrl.enable = A_TRUE; + tdm_ctrl.offset = A_FALSE; + tdm_ctrl.depth = num; + p_api->adpt_port_tdm_ctrl_set(dev_id, &tdm_ctrl); + SSDK_INFO("tdm setup num=%d\n", num); + return SW_OK; +} +#endif + +#if defined(IN_BM) +static sw_error_t +qca_hppe_bm_hw_init(a_uint32_t dev_id) +{ + a_uint32_t i = 0; + fal_bm_dynamic_cfg_t cfg; + a_uint32_t chip_ver = 0; + + chip_ver = adpt_hppe_chip_revision_get(dev_id); + + for (i = 0; i < HPPE_BM_PORT_NUM; i++) { + /* enable fc */ + fal_port_bm_ctrl_set(0, i, A_TRUE); + /* map to group 0 */ + fal_port_bufgroup_map_set(0, i, 0); + } + + if (chip_ver == CPPE_REVISION) { + fal_bm_bufgroup_buffer_set(dev_id, 0, 1024); + } else { + fal_bm_bufgroup_buffer_set(dev_id, 0, 1400); + } + + /* set reserved buffer */ + for (i = 0; i < HPPE_BM_PHY_PORT_OFFSET; i++) { + fal_bm_port_reserved_buffer_set(dev_id, i, 0, 100); + } + for (i = HPPE_BM_PHY_PORT_OFFSET; i < HPPE_BM_PORT_NUM-1; i++) { + fal_bm_port_reserved_buffer_set(dev_id, i, 0, 128); + } + if (chip_ver == CPPE_REVISION) { + fal_bm_port_reserved_buffer_set(dev_id, HPPE_BM_PORT_NUM -2, + 0, 40); + } + fal_bm_port_reserved_buffer_set(dev_id, HPPE_BM_PORT_NUM-1, 0, 40); + + memset(&cfg, 0, sizeof(cfg)); + cfg.resume_min_thresh = 0; + cfg.resume_off = 36; + cfg.weight= 4; + if (chip_ver == CPPE_REVISION) { + cfg.shared_ceiling = 216; + } else { + cfg.shared_ceiling = 250; + } + for (i = 0; i < HPPE_BM_PORT_NUM; i++) { + fal_bm_port_dynamic_thresh_set(dev_id, i, &cfg); + } + return SW_OK; +} +#endif + +#if defined(IN_QM) +static sw_error_t +qca_hppe_qm_hw_init(a_uint32_t dev_id) +{ + a_uint32_t i; + fal_ucast_queue_dest_t queue_dst; + fal_ac_obj_t obj; + fal_ac_ctrl_t ac_ctrl; + fal_ac_group_buffer_t group_buff; + fal_ac_dynamic_threshold_t dthresh_cfg; + fal_ac_static_threshold_t sthresh_cfg; + a_uint32_t qbase = 0; + a_uint32_t chip_ver = 0; + + memset(&queue_dst, 0, sizeof(queue_dst)); + + chip_ver = adpt_hppe_chip_revision_get(dev_id); + + /* + * Redirect service code 2 to queue 1 + * TODO: keep sync with NSS + */ + queue_dst.service_code_en = A_TRUE; + queue_dst.service_code = 2; + fal_ucast_queue_base_profile_set(dev_id, &queue_dst, 8, 0); + + queue_dst.service_code = 3; + fal_ucast_queue_base_profile_set(dev_id, &queue_dst, 128, 0); + + queue_dst.service_code = 4; + fal_ucast_queue_base_profile_set(dev_id, &queue_dst, 128, 0); + + queue_dst.service_code = 5; + fal_ucast_queue_base_profile_set(dev_id, &queue_dst, 0, 0); + + queue_dst.service_code = 6; + fal_ucast_queue_base_profile_set(dev_id, &queue_dst, 8, 0); + + queue_dst.service_code = 7; + fal_ucast_queue_base_profile_set(dev_id, &queue_dst, 240, 0); + + queue_dst.service_code_en = A_FALSE; + queue_dst.service_code = 0; + for(i = 0; i < SSDK_MAX_PORT_NUM; i++) { + queue_dst.dst_port = i; + qbase = ssdk_ucast_queue_start_get(dev_id, i); + fal_ucast_queue_base_profile_set(dev_id, &queue_dst, qbase, i); + } + + /* + * Enable PPE source profile 1 and map it to PPE queue 4 + */ + memset(&queue_dst, 0, sizeof(queue_dst)); + queue_dst.src_profile = 1; + + /* + * Enable service code mapping for profile 1 + */ + queue_dst.service_code_en = A_TRUE; + for (i = 0; i < SSDK_MAX_SERVICE_CODE_NUM; i++) { + queue_dst.service_code = i; + + if (i == 2 || i == 6) { + fal_ucast_queue_base_profile_set(dev_id, &queue_dst, 8, 0); + } else if (i == 3 || i == 4) { + fal_ucast_queue_base_profile_set(dev_id, &queue_dst, 128, 0); + } else { + fal_ucast_queue_base_profile_set(dev_id, &queue_dst, 4, 0); + } + } + queue_dst.service_code_en = A_FALSE; + queue_dst.service_code = 0; + + /* + * Enable cpu code mapping for profile 1 + */ + queue_dst.cpu_code_en = A_TRUE; + for (i = 0; i < SSDK_MAX_CPU_CODE_NUM; i++) { + queue_dst.cpu_code = i; + fal_ucast_queue_base_profile_set(dev_id, &queue_dst, 4, 0); + } + queue_dst.cpu_code_en = A_FALSE; + queue_dst.cpu_code = 0; + + /* + * Enable destination port mappings for profile 1 + */ + for (i = 0; i < SSDK_MAX_PORT_NUM; i++) { + queue_dst.dst_port = i; + qbase = ssdk_ucast_queue_start_get(dev_id, i); + fal_ucast_queue_base_profile_set(dev_id, &queue_dst, qbase, i); + } + + for (i = SSDK_MAX_PORT_NUM; i < SSDK_MAX_VIRTUAL_PORT_NUM; i++) { + queue_dst.dst_port = i; + fal_ucast_queue_base_profile_set(dev_id, &queue_dst, 4, 0); + } + queue_dst.dst_port = 0; + + /* queue ac*/ + ac_ctrl.ac_en = A_TRUE; + ac_ctrl.ac_fc_en = A_FALSE; + for (i = 0; i < SSDK_L0SCHEDULER_CFG_MAX; i++) { + obj.type = FAL_AC_QUEUE; + obj.obj_id = i; + fal_ac_ctrl_set(dev_id, &obj, &ac_ctrl); + fal_ac_queue_group_set(dev_id, i, 0); + fal_ac_prealloc_buffer_set(dev_id, &obj, 0); + } + + group_buff.prealloc_buffer = 0; + if (chip_ver == CPPE_REVISION) { + group_buff.total_buffer = 1506; + } else { + group_buff.total_buffer = 2000; + } + fal_ac_group_buffer_set(dev_id, 0, &group_buff); + + memset(&dthresh_cfg, 0, sizeof(dthresh_cfg)); + dthresh_cfg.shared_weight = 4; + if (chip_ver == CPPE_REVISION) { + dthresh_cfg.ceiling = 216; + } else { + dthresh_cfg.ceiling = 400; + } + dthresh_cfg.green_resume_off = 36; + for (i = 0; i < SSDK_L0SCHEDULER_UCASTQ_CFG_MAX; i++) { + fal_ac_dynamic_threshold_set(dev_id, i, &dthresh_cfg); + } + + memset(&sthresh_cfg, 0, sizeof(sthresh_cfg)); + if (chip_ver == CPPE_REVISION) { + sthresh_cfg.green_max = 144; + } else { + sthresh_cfg.green_max = 250; + } + sthresh_cfg.green_resume_off = 36; + for (i = SSDK_L0SCHEDULER_UCASTQ_CFG_MAX; i < SSDK_L0SCHEDULER_CFG_MAX; + i++) { + obj.type = FAL_AC_QUEUE; + obj.obj_id = i; + fal_ac_static_threshold_set(dev_id, &obj, &sthresh_cfg); + } + + return SW_OK; +} +#endif + +#if defined(IN_QOS) +static sw_error_t +qca_hppe_qos_scheduler_hw_init(a_uint32_t dev_id) +{ + a_uint32_t i = 0; + fal_qos_scheduler_cfg_t cfg; + fal_queue_bmp_t queue_bmp; + fal_qos_group_t group_sel; + fal_qos_pri_precedence_t pri_pre; + ssdk_dt_scheduler_cfg *dt_cfg = ssdk_bootup_shceduler_cfg_get(dev_id); + + memset(&cfg, 0, sizeof(cfg)); + + /* L1 shceduler */ + for (i = 0; i < SSDK_L1SCHEDULER_CFG_MAX; i++) { + if (dt_cfg->l1cfg[i].valid) { + cfg.sp_id = dt_cfg->l1cfg[i].port_id; + cfg.c_pri = dt_cfg->l1cfg[i].cpri; + cfg.e_pri = dt_cfg->l1cfg[i].epri; + cfg.c_drr_id = dt_cfg->l1cfg[i].cdrr_id; + cfg.e_drr_id = dt_cfg->l1cfg[i].edrr_id; + cfg.c_drr_wt = 1; + cfg.e_drr_wt = 1; + fal_queue_scheduler_set(dev_id, i, 1, + dt_cfg->l1cfg[i].port_id, &cfg); + } + } + + /* L0 shceduler */ + for (i = 0; i < SSDK_L0SCHEDULER_CFG_MAX; i++) { + if (dt_cfg->l0cfg[i].valid) { + cfg.sp_id = dt_cfg->l0cfg[i].sp_id; + cfg.c_pri = dt_cfg->l0cfg[i].cpri; + cfg.e_pri = dt_cfg->l0cfg[i].epri; + cfg.c_drr_id = dt_cfg->l0cfg[i].cdrr_id; + cfg.e_drr_id = dt_cfg->l0cfg[i].edrr_id; + cfg.c_drr_wt = 1; + cfg.e_drr_wt = 1; + fal_queue_scheduler_set(dev_id, i, + 0, dt_cfg->l0cfg[i].port_id, &cfg); + } + } + + /* queue--edma ring mapping*/ + memset(&queue_bmp, 0, sizeof(queue_bmp)); + queue_bmp.bmp[0] = 0xF; + fal_edma_ring_queue_map_set(dev_id, 0, &queue_bmp); + queue_bmp.bmp[0] = 0xF0; + fal_edma_ring_queue_map_set(dev_id, 3, &queue_bmp); + queue_bmp.bmp[0] = 0xF00; + fal_edma_ring_queue_map_set(dev_id, 1, &queue_bmp); + queue_bmp.bmp[0] = 0; + queue_bmp.bmp[4] = 0xFFFF; + fal_edma_ring_queue_map_set(dev_id, 2, &queue_bmp); + + /* chose qos group 0 */ + group_sel.dscp_group = 0; + group_sel.flow_group = 0; + group_sel.pcp_group = 0; + for (i = SSDK_PHYSICAL_PORT0; i <= SSDK_PHYSICAL_PORT7; i++) { + fal_qos_port_group_get(dev_id, i, &group_sel); + } + /* qos precedence */ + pri_pre.flow_pri = 4; + pri_pre.acl_pri = 2; + pri_pre.dscp_pri = 1; + pri_pre.pcp_pri = 0; + pri_pre.preheader_pri = 3; + for (i = SSDK_PHYSICAL_PORT0; i <= SSDK_PHYSICAL_PORT7; i++) { + fal_qos_port_pri_precedence_set(dev_id, i, &pri_pre); + } + + return SW_OK; +} +#endif + + +#if defined(IN_ACL) +#define LIST_ID_BYP_FDB_LRN 63/*reserved for bypass fdb learning*/ +#define LIST_PRI_BYP_FDB_LRN 32 + +sw_error_t qca_hppe_acl_byp_intf_mac_learn(a_uint32_t dev_id) +{ + a_uint32_t index = 0, num; + fal_acl_rule_t rule = { 0 }; + a_uint8_t* mac; + a_uint32_t port_bmp = qca_ssdk_port_bmp_get(dev_id); + + num = ssdk_intf_mac_num_get(); + if(num == 0){ + return SW_OK;/*No found interface MAC*/ + } + + /*Bypass fdb learn*/ + rule.rule_type = FAL_ACL_RULE_MAC; + rule.bypass_bitmap |= (1<= num) + break; + mac = ssdk_intf_macaddr_get(index); + memcpy(rule.src_mac_val.uc, mac, 6); + memset(rule.src_mac_mask.uc, 0xff, 6); + SSDK_DEBUG("%02x:%02x:%02x:%02x:%02x:%02x\n", rule.src_mac_val.uc[0], + rule.src_mac_val.uc[1], rule.src_mac_val.uc[2], rule.src_mac_val.uc[3], + rule.src_mac_val.uc[4], rule.src_mac_val.uc[5]); + fal_acl_rule_add(dev_id, LIST_ID_BYP_FDB_LRN, index, 1, &rule); + } + fal_acl_list_bind(dev_id, LIST_ID_BYP_FDB_LRN, FAL_ACL_DIREC_IN, + FAL_ACL_BIND_PORTBITMAP, port_bmp); + + return SW_OK; +} + +#if defined(IN_PTP) +sw_error_t qca_hppe_acl_remark_ptp_servcode(a_uint32_t dev_id) { +#define LIST_ID_L2_TAG_SERVICE_CODE_PTP 58 +#define LIST_ID_L4_TAG_SERVICE_CODE_PTP 59 +#define LIST_PRI_TAG_SERVICE_CODE_PTP 1 +#define PTP_EVENT_PKT_SERVICE_CODE 0x9 +#define PTP_EV_PORT 319 +#define PTP_MSG_SYNC 0 +#define PTP_MSG_PRESP 3 + + sw_error_t ret; + fal_func_ctrl_t func_ctrl, func_ctrl_old; + fal_servcode_config_t servcode_conf; + fal_acl_rule_t entry = {0}; + a_uint32_t index = 0, msg_type = 0; + a_uint32_t ptp_port_bmp = 0; + + /* only marking ptp packet with service code for the qca808x phy */ + ptp_port_bmp = qca_ssdk_phy_type_port_bmp_get(dev_id, QCA808X_PHY_CHIP); + + /* Not found the PHY with ptp feature */ + if (ptp_port_bmp == 0) { + return SW_OK; + } + + /* Create PTP ACL L2 list */ + ret = fal_acl_list_creat(dev_id, LIST_ID_L2_TAG_SERVICE_CODE_PTP, + LIST_PRI_TAG_SERVICE_CODE_PTP); + SW_RTN_ON_ERROR(ret); + + /* Set up UDF0 profile */ + ret = fal_acl_udf_profile_set(dev_id, FAL_ACL_UDF_NON_IP, 0, FAL_ACL_UDF_TYPE_L3, 0); + SW_RTN_ON_ERROR(ret); + + /* Tag service code for PTP packet */ + entry.service_code = PTP_EVENT_PKT_SERVICE_CODE; + entry.pri = LIST_PRI_TAG_SERVICE_CODE_PTP; + FAL_ACTION_FLG_SET(entry.action_flg, FAL_ACL_ACTION_SERVICE_CODE); + FAL_ACTION_FLG_SET(entry.action_flg, FAL_ACL_ACTION_PERMIT); + + /* L2 PTP packet */ + entry.rule_type = FAL_ACL_RULE_MAC; + + /* L2 PTP ethernet type 0x88f7 */ + entry.ethtype_val = ETH_P_1588; + entry.ethtype_mask = 0xffff; + FAL_FIELD_FLG_SET(entry.field_flg, FAL_ACL_FIELD_MAC_ETHTYPE); + + for (msg_type = PTP_MSG_SYNC; msg_type <= PTP_MSG_PRESP; msg_type++) { + /* L2 UDF0 for msg type */ + entry.udf0_op = FAL_ACL_FIELD_MASK; + entry.udf0_val = (msg_type << 0x8); + entry.udf0_mask = 0x0f00; + FAL_FIELD_FLG_SET(entry.field_flg, FAL_ACL_FIELD_UDF0); + + /* Add PTP L2 rule to ACL list */ + ret = fal_acl_rule_add(dev_id, LIST_ID_L2_TAG_SERVICE_CODE_PTP, + index++, 1, &entry); + SW_RTN_ON_ERROR(ret); + } + + /* Unset L2 PTP ethernet type 0x88f7 */ + index = 0; + FAL_FIELD_FLG_CLR(entry.field_flg, FAL_ACL_FIELD_UDF0); + FAL_FIELD_FLG_CLR(entry.field_flg, FAL_ACL_FIELD_MAC_ETHTYPE); + + /* Create PTP ACL L4 list */ + ret = fal_acl_list_creat(dev_id, LIST_ID_L4_TAG_SERVICE_CODE_PTP, + LIST_PRI_TAG_SERVICE_CODE_PTP); + SW_RTN_ON_ERROR(ret); + + /* IPv4 PTP packet */ + entry.rule_type = FAL_ACL_RULE_IP4; + entry.is_ip_mask = 1; + entry.is_ip_val = A_TRUE; + FAL_FIELD_FLG_SET(entry.field_flg, FAL_ACL_FIELD_IP); + entry.is_ipv6_mask = 1; + entry.is_ipv6_val = A_FALSE; + FAL_FIELD_FLG_SET(entry.field_flg, FAL_ACL_FIELD_IPV6); + + /* PTP over UDP protocol */ + entry.ip_proto_val = IPPROTO_UDP; + entry.ip_proto_mask = 0xff; + FAL_FIELD_FLG_SET(entry.field_flg, FAL_ACL_FIELD_IP_PROTO); + + /* PTP UDP dest port 319 */ + entry.dest_l4port_op = FAL_ACL_FIELD_MASK; + entry.dest_l4port_val = PTP_EV_PORT; + entry.dest_l4port_mask = 0xffff; + FAL_FIELD_FLG_SET(entry.field_flg, FAL_ACL_FIELD_L4_DPORT); + + /* Add PTP IPv4 rule to ACL list */ + ret = fal_acl_rule_add(dev_id, LIST_ID_L4_TAG_SERVICE_CODE_PTP, index++, 1, &entry); + SW_RTN_ON_ERROR(ret); + + /* IPv6 PTP packet */ + entry.rule_type = FAL_ACL_RULE_IP6; + entry.is_ipv6_val = A_TRUE; + + /* Add PTP IPv6 rule to ACL list */ + ret = fal_acl_rule_add(dev_id, LIST_ID_L4_TAG_SERVICE_CODE_PTP, index++, 1, &entry); + SW_RTN_ON_ERROR(ret); + + /* Bind PTP ACL list to port bmp */ + ret = fal_acl_list_bind(dev_id, LIST_ID_L2_TAG_SERVICE_CODE_PTP, + FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORTBITMAP, ptp_port_bmp); + SW_RTN_ON_ERROR(ret); + ret = fal_acl_list_bind(dev_id, LIST_ID_L4_TAG_SERVICE_CODE_PTP, + FAL_ACL_DIREC_IN, FAL_ACL_BIND_PORTBITMAP, ptp_port_bmp); + SW_RTN_ON_ERROR(ret); + + /* enable service code module temporarily */ + ret = fal_module_func_ctrl_get(dev_id, FAL_MODULE_SERVCODE, &func_ctrl_old); + SW_RTN_ON_ERROR(ret); + func_ctrl.bitmap[0] = (1<adpt_port_mux_mac_type_set); + SW_RTN_ON_NULL(p_api->adpt_uniphy_mode_set); + + + rv = p_api->adpt_uniphy_mode_set(dev_id, SSDK_UNIPHY_INSTANCE0, mode0); + SW_RTN_ON_ERROR(rv); + + rv = p_api->adpt_uniphy_mode_set(dev_id, SSDK_UNIPHY_INSTANCE1, mode1); + SW_RTN_ON_ERROR(rv); + + if(adpt_hppe_chip_revision_get(dev_id) == HPPE_REVISION) { + rv = p_api->adpt_uniphy_mode_set(dev_id, + SSDK_UNIPHY_INSTANCE2, mode2); + SW_RTN_ON_ERROR(rv); + } + + if(adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) { + port_max = SSDK_PHYSICAL_PORT6; + } else { + port_max = SSDK_PHYSICAL_PORT7; + } + for(port_id = SSDK_PHYSICAL_PORT1; port_id < port_max; port_id++) { + rv = p_api->adpt_port_mux_mac_type_set(dev_id, port_id, mode0, mode1, mode2); + if(rv != SW_OK) { + SSDK_ERROR("port_id:%d, mode0:%d, mode1:%d, mode2:%d\n", port_id, mode0, mode1, mode2); + break; + } + } + + return rv; +} + + +#if defined(IN_FLOW) +static sw_error_t +qca_hppe_flow_hw_init(a_uint32_t dev_id) +{ + fal_flow_direction_t dir, dir_max; + fal_flow_mgmt_t mgmt; + sw_error_t rv; + + memset(&mgmt, 0, sizeof(fal_flow_mgmt_t)); + dir_max = FAL_FLOW_UNKOWN_DIR_DIR; + + /*set redirect to cpu for multicast flow*/ + for (dir = FAL_FLOW_LAN_TO_LAN_DIR; dir <= dir_max; dir++) { + rv = fal_flow_mgmt_get(dev_id, FAL_FLOW_MCAST, dir, &mgmt); + SW_RTN_ON_ERROR(rv); + mgmt.miss_action = FAL_MAC_RDT_TO_CPU; + rv = fal_flow_mgmt_set(dev_id, FAL_FLOW_MCAST, dir, &mgmt); + SW_RTN_ON_ERROR(rv); + } + return SW_OK; +} +#endif + +sw_error_t qca_hppe_hw_init(ssdk_init_cfg *cfg, a_uint32_t dev_id) +{ + sw_error_t rv = SW_OK; + + /* reset ppe */ + ssdk_ppe_reset_init(); + + rv = qca_switch_init(dev_id); + SW_RTN_ON_ERROR(rv); + +#if defined(IN_BM) + rv = qca_hppe_bm_hw_init(dev_id); + SW_RTN_ON_ERROR(rv); +#endif +#if defined(IN_QM) + rv = qca_hppe_qm_hw_init(dev_id); + SW_RTN_ON_ERROR(rv); +#endif +#if defined(IN_QOS) + rv = qca_hppe_qos_scheduler_hw_init(dev_id); + SW_RTN_ON_ERROR(rv); +#endif +#if defined(IN_BM) && defined(IN_QOS) + rv = qca_hppe_tdm_hw_init(dev_id); + SW_RTN_ON_ERROR(rv); +#endif +#if defined(IN_FDB) + rv= qca_hppe_fdb_hw_init(dev_id); + SW_RTN_ON_ERROR(rv); +#endif +#if defined(IN_VSI) + rv= qca_hppe_vsi_hw_init(dev_id); + SW_RTN_ON_ERROR(rv); +#endif +#if defined(IN_PORTVLAN) + rv = qca_hppe_portvlan_hw_init(dev_id); + SW_RTN_ON_ERROR(rv); +#endif +#if defined(IN_PORTCONTROL) + rv = qca_hppe_portctrl_hw_init(dev_id); + SW_RTN_ON_ERROR(rv); +#endif +#if defined(IN_POLICER) + rv = qca_hppe_policer_hw_init(dev_id); + SW_RTN_ON_ERROR(rv); +#endif +#if defined(IN_SHAPER) + rv = qca_hppe_shaper_hw_init(dev_id); + SW_RTN_ON_ERROR(rv); +#endif +#if defined(IN_FLOW) + rv = qca_hppe_flow_hw_init(dev_id); + SW_RTN_ON_ERROR(rv); +#endif +#if defined(IN_ACL) + rv = qca_hppe_acl_byp_intf_mac_learn(dev_id); + SW_RTN_ON_ERROR(rv); +#if defined(IN_PTP) + rv = qca_hppe_acl_remark_ptp_servcode(dev_id); + SW_RTN_ON_ERROR(rv); +#endif +#endif + rv = qca_hppe_interface_mode_init(dev_id, cfg->mac_mode, cfg->mac_mode1, + cfg->mac_mode2); + SW_RTN_ON_ERROR(rv); +#if defined(IN_CTRLPKT) + rv = qca_hppe_ctlpkt_hw_init(dev_id); + SW_RTN_ON_ERROR(rv); +#endif + + return rv; +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/init/ssdk_init.c b/feeds/ipq807x/qca-ssdk/src/src/init/ssdk_init.c new file mode 100644 index 000000000..43c4ddd7c --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/init/ssdk_init.c @@ -0,0 +1,3651 @@ +/* + * Copyright (c) 2012, 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. + */ + +/*qca808x_start*/ +#include "sw.h" +#include "ssdk_init.h" +#include "fal_init.h" +#include "fal.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_phy.h" +/*qca808x_end*/ +#include "ssdk_dts.h" +#include "ssdk_interrupt.h" +#include +#include +#include +/*qca808x_start*/ +#include +#include +#include +#include +/*qca808x_end*/ +//#include +#include +#include +#include +#include +#include +/*qca808x_start*/ +#include +#include +/*qca808x_end*/ +#include +#include +#include +#include +#include + +#if defined(IN_SWCONFIG) +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) +#include +#else +#include +#endif +#endif + +#if defined(ISIS) ||defined(ISISC) ||defined(GARUDA) +#include +#endif +#if defined(ATHENA) ||defined(SHIVA) ||defined(HORUS) +#include +#endif +#ifdef IN_MALIBU_PHY +#include +#endif +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0)) +/*qca808x_start*/ +#include +#include +#include +#include +#include +/*qca808x_end*/ +#ifdef BOARD_AR71XX +#ifdef CONFIG_AR8216_PHY +#include "drivers/net/phy/ar8327.h" +#endif +#include "drivers/net/ethernet/atheros/ag71xx/ag71xx.h" +#endif +#elif defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) +#include +#include +#include +#include +#include +#else +#include +#include +#include +#endif +/*qca808x_start*/ +#include "ssdk_plat.h" +/*qca808x_end*/ +#include "ssdk_clk.h" +#include "ssdk_led.h" +#include "ref_vlan.h" +#include "ref_fdb.h" +#include "ref_mib.h" +#include "ref_port_ctrl.h" +#include "ref_misc.h" +#include "ref_uci.h" +#include "ref_vsi.h" +#include "shell.h" +#ifdef BOARD_AR71XX +#include "ssdk_uci.h" +#endif +/*qca808x_start*/ +#if defined(IN_PHY_I2C_MODE) +#include "ssdk_phy_i2c.h" +#endif +/*qca808x_end*/ +#ifdef IN_IP +#if defined (CONFIG_NF_FLOW_COOKIE) +#include "fal_flowcookie.h" +#ifdef IN_SFE +#include +#endif +#endif +#endif + +#ifdef IN_RFS +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) +#include +#endif +#include +#ifdef IN_IP +#include "fal_rfs.h" +#endif +#endif +#include "adpt.h" +#ifdef HPPE +#include "ssdk_hppe.h" +#endif +#ifdef SCOMPHY +#include "ssdk_scomphy.h" +#endif + +#ifdef IN_RFS +struct rfs_device rfs_dev; +struct notifier_block ssdk_inet_notifier; +ssdk_rfs_intf_t rfs_intf_tbl[SSDK_RFS_INTF_MAX] = {{0}}; +#endif + +//#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) +struct notifier_block ssdk_dev_notifier; +//#endif + + +extern ssdk_chip_type SSDK_CURRENT_CHIP_TYPE; +extern a_uint32_t hsl_dev_wan_port_get(a_uint32_t dev_id); +extern void dess_rgmii_sw_mac_polling_task(struct qca_phy_priv *priv); +extern void qca_ar8327_sw_mac_polling_task(struct qca_phy_priv *priv); +extern void qca_ar8327_sw_mib_task(struct qca_phy_priv *priv); + +//#define PSGMII_DEBUG + +#define QCA_QM_WORK_DELAY 100 +#define QCA_QM_ITEM_NUMBER 41 +#define QCA_RGMII_WORK_DELAY 1000 +#define QCA_MAC_SW_SYNC_WORK_DELAY 1000 +#ifdef DESS +static bool qca_dess_rfs_registered = false; +#endif +/*qca808x_start*/ +struct qca_phy_priv **qca_phy_priv_global; + +struct qca_phy_priv* ssdk_phy_priv_data_get(a_uint32_t dev_id) +{ + if (dev_id >= SW_MAX_NR_DEV || !qca_phy_priv_global) + return NULL; + + return qca_phy_priv_global[dev_id]; +} +/*qca808x_end*/ + +a_uint32_t hppe_port_type[6] = {0,0,0,0,0,0}; // this variable should be init by ssdk_init + +a_uint32_t +qca_hppe_port_mac_type_get(a_uint32_t dev_id, a_uint32_t port_id) +{ + if ((port_id < 1) || (port_id > 6)) + return 0; + return hppe_port_type[port_id - 1]; +} + +a_uint32_t +qca_hppe_port_mac_type_set(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t port_type) +{ + if ((port_id < 1) || (port_id > 6)) + return 0; + hppe_port_type[port_id - 1] = port_type; + + return 0; +} + +#ifndef BOARD_AR71XX +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) +static void +ssdk_phy_rgmii_set(struct qca_phy_priv *priv) +{ + struct device_node *np = NULL; + u32 rgmii_en = 0, tx_delay = 0, rx_delay = 0; + + if (priv->ess_switch_flag == A_TRUE) + np = priv->of_node; + else +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,9,0)) + np = priv->phy->mdio.dev.of_node; +#else + np = priv->phy->dev.of_node; +#endif + + if (!np) + return; + + if (!of_property_read_u32(np, "phy_rgmii_en", &rgmii_en)) { + a_uint16_t val = 0; + /*enable RGMII mode */ + qca_ar8327_phy_dbg_read(0, AR8327_PORT5_PHY_ADDR, + AR8327_PHY_REG_MODE_SEL, &val); + val |= AR8327_PHY_RGMII_MODE; + qca_ar8327_phy_dbg_write(0, AR8327_PORT5_PHY_ADDR, + AR8327_PHY_REG_MODE_SEL, val); + if (!of_property_read_u32(np, "txclk_delay_en", &tx_delay) + && tx_delay == 1) { + qca_ar8327_phy_dbg_read(0, AR8327_PORT5_PHY_ADDR, + AR8327_PHY_REG_SYS_CTRL, &val); + val |= AR8327_PHY_RGMII_TX_DELAY; + qca_ar8327_phy_dbg_write(0, AR8327_PORT5_PHY_ADDR, + AR8327_PHY_REG_SYS_CTRL, val); + } + if (!of_property_read_u32(np, "rxclk_delay_en", &rx_delay) + && rx_delay == 1) { + qca_ar8327_phy_dbg_read(0, AR8327_PORT5_PHY_ADDR, + AR8327_PHY_REG_TEST_CTRL, &val); + val |= AR8327_PHY_RGMII_RX_DELAY; + qca_ar8327_phy_dbg_write(0, AR8327_PORT5_PHY_ADDR, + AR8327_PHY_REG_TEST_CTRL, val); + } + } +} +#else +static void +ssdk_phy_rgmii_set(struct qca_phy_priv *priv) +{ + struct ar8327_platform_data *plat_data; + + plat_data = priv->phy->dev.platform_data; + if (plat_data == NULL) { + return; + } + + if(plat_data->pad5_cfg) { + if(plat_data->pad5_cfg->mode == AR8327_PAD_PHY_RGMII) { + a_uint16_t val = 0; + /*enable RGMII mode */ + priv->phy_dbg_read(0, AR8327_PORT5_PHY_ADDR, + AR8327_PHY_REG_MODE_SEL, &val); + val |= AR8327_PHY_RGMII_MODE; + priv->phy_dbg_write(0, AR8327_PORT5_PHY_ADDR, + AR8327_PHY_REG_MODE_SEL, val); + if(plat_data->pad5_cfg->txclk_delay_en) { + priv->phy_dbg_read(0, AR8327_PORT5_PHY_ADDR, + AR8327_PHY_REG_SYS_CTRL, &val); + val |= AR8327_PHY_RGMII_TX_DELAY; + priv->phy_dbg_write(0, AR8327_PORT5_PHY_ADDR, + AR8327_PHY_REG_SYS_CTRL, val); + } + if(plat_data->pad5_cfg->rxclk_delay_en) { + priv->phy_dbg_read(0, AR8327_PORT5_PHY_ADDR, + AR8327_PHY_REG_TEST_CTRL, &val); + val |= AR8327_PHY_RGMII_RX_DELAY; + priv->phy_dbg_write(0, AR8327_PORT5_PHY_ADDR, + AR8327_PHY_REG_TEST_CTRL, val); + } + } + } +} +#endif +#endif + + +static void +qca_ar8327_phy_fixup(struct qca_phy_priv *priv, int phy) +{ + switch (priv->revision) { + case 1: + /* 100m waveform */ + priv->phy_dbg_write(priv->device_id, phy, 0, 0x02ea); + /* turn on giga clock */ + priv->phy_dbg_write(priv->device_id, phy, 0x3d, 0x68a0); + break; + + case 2: + priv->phy_mmd_write(priv->device_id, phy, 0x7, 0x3c); + priv->phy_mmd_write(priv->device_id, phy, 0x4007, 0x0); + /* fallthrough */ + case 4: + priv->phy_mmd_write(priv->device_id, phy, 0x3, 0x800d); + priv->phy_mmd_write(priv->device_id, phy, 0x4003, 0x803f); + + priv->phy_dbg_write(priv->device_id, phy, 0x3d, 0x6860); + priv->phy_dbg_write(priv->device_id, phy, 0x5, 0x2c46); + priv->phy_dbg_write(priv->device_id, phy, 0x3c, 0x6000); + break; + } +} + +#ifdef IN_PORTVLAN +static void qca_port_isolate(a_uint32_t dev_id) +{ + a_uint32_t port_id, mem_port_id, mem_port_map[AR8327_NUM_PORTS]={0}; + + for(port_id = 0; port_id < AR8327_NUM_PORTS; port_id++) + { + if(port_id == 6) + for(mem_port_id = 1; mem_port_id<= 4; mem_port_id++) + mem_port_map[port_id] |= (1 << mem_port_id); + else if (port_id == 0) + mem_port_map[port_id] |= (1 << 5); + else if (port_id >= 1 && port_id <= 4) + mem_port_map[port_id] |= (1 << 6); + else + mem_port_map[port_id] |= 1; + } + + for(port_id = 0; port_id < AR8327_NUM_PORTS; port_id++) + + fal_portvlan_member_update(dev_id, port_id, mem_port_map[port_id]); + +} + +void ssdk_portvlan_init(a_uint32_t dev_id) +{ + a_uint32_t port = 0; + a_uint32_t cpu_bmp, lan_bmp, wan_bmp; + + cpu_bmp = ssdk_cpu_bmp_get(dev_id); + lan_bmp = ssdk_lan_bmp_get(dev_id); + wan_bmp = ssdk_wan_bmp_get(dev_id); + + if (!(cpu_bmp | lan_bmp | wan_bmp)) { + qca_port_isolate(dev_id); + return; + } + + for(port = 0; port < SSDK_MAX_PORT_NUM; port++) + { + if(cpu_bmp & (1 << port)) + { + fal_portvlan_member_update(dev_id, port, lan_bmp|wan_bmp); + } + if(lan_bmp & (1 << port)) + { + fal_portvlan_member_update(dev_id, port, (lan_bmp|cpu_bmp)&(~(1<interface_mac_pad_set + && p_api->interface_mac_sgmii_set) + { + p_api->interface_mac_pad_set(device_id,0,0); + p_api->interface_mac_pad_set(device_id,5,0); + p_api->interface_mac_pad_set(device_id,6,0); + p_api->interface_mac_sgmii_set(device_id,AR8327_REG_PAD_SGMII_CTRL_HW_INIT); + } + else + { + SSDK_ERROR("API not support \n"); + } +} + +static void qca_switch_set_mac_force(struct qca_phy_priv *priv) +{ + a_uint32_t value, value0, i; + if (priv == NULL || (priv->mii_read == NULL) || (priv->mii_write == NULL)) { + SSDK_ERROR("In qca_switch_set_mac_force, private data is NULL!\r\n"); + return; + } + + for (i=0; i < AR8327_NUM_PORTS; ++i) { + /* b3:2=0,Tx/Rx Mac disable, + b9=0,LINK_EN disable */ + value0 = priv->mii_read(priv->device_id, AR8327_REG_PORT_STATUS(i)); + value = value0 & ~(AR8327_PORT_STATUS_LINK_AUTO | + AR8327_PORT_STATUS_TXMAC | + AR8327_PORT_STATUS_RXMAC); + priv->mii_write(priv->device_id, AR8327_REG_PORT_STATUS(i), value); + + /* Force speed to 1000M Full */ + value = priv->mii_read(priv->device_id, AR8327_REG_PORT_STATUS(i)); + value &= ~(AR8327_PORT_STATUS_DUPLEX | AR8327_PORT_STATUS_SPEED); + value |= AR8327_PORT_SPEED_1000M | AR8327_PORT_STATUS_DUPLEX; + priv->mii_write(priv->device_id, AR8327_REG_PORT_STATUS(i), value); + } + return; +} + +void +qca_ar8327_phy_enable(struct qca_phy_priv *priv) +{ + int i = 0; +#ifndef BOARD_AR71XX + ssdk_phy_rgmii_set(priv); +#endif + for (i = 0; i < AR8327_NUM_PHYS; i++) { + a_uint16_t value = 0; + + if (priv->version == QCA_VER_AR8327) + qca_ar8327_phy_fixup(priv, i); + + /* start autoneg*/ + priv->phy_write(priv->device_id, i, MII_ADVERTISE, ADVERTISE_ALL | + ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM); + //phy reg 0x9, b10,1 = Prefer multi-port device (master) + priv->phy_write(priv->device_id, i, MII_CTRL1000, (0x0400|ADVERTISE_1000FULL)); + + priv->phy_write(priv->device_id, i, MII_BMCR, BMCR_RESET | BMCR_ANENABLE); + + priv->phy_dbg_read(priv->device_id, i, 0, &value); + value &= (~(1<<12)); + priv->phy_dbg_write(priv->device_id, i, 0, value); + + msleep(100); + } +} +void qca_ar8327_sw_soft_reset(struct qca_phy_priv *priv) +{ + a_uint32_t value = 0; + + value = priv->mii_read(priv->device_id, AR8327_REG_CTRL); + value |= 0x80000000; + priv->mii_write(priv->device_id, AR8327_REG_CTRL, value); + /*Need wait reset done*/ + do { + udelay(10); + value = priv->mii_read(priv->device_id, AR8327_REG_CTRL); + } while(value & AR8327_CTRL_RESET); + do { + udelay(10); + value = priv->mii_read(priv->device_id, 0x20); + } while ((value & SSDK_GLOBAL_INITIALIZED_STATUS) != + SSDK_GLOBAL_INITIALIZED_STATUS); + + return; +} + +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) +int qca_ar8327_hw_init(struct qca_phy_priv *priv) +{ + struct device_node *np = NULL; + const __be32 *paddr; + a_uint32_t reg, value, i; + a_int32_t len; + + if (priv->ess_switch_flag == A_TRUE) + np = priv->of_node; + else +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,9,0)) + np = priv->phy->mdio.dev.of_node; +#else + np = priv->phy->dev.of_node; +#endif + + if(!np) + return -EINVAL; + + /*Before switch software reset, disable PHY and clear MAC PAD*/ + qca_ar8327_phy_linkdown(priv->device_id); + qca_mac_disable(priv->device_id); + msleep(1000); + + /*First software reset S17 chip*/ + qca_ar8327_sw_soft_reset(priv); + + /*After switch software reset, need disable all ports' MAC with 1000M FULL*/ + qca_switch_set_mac_force(priv); + + /* Configure switch register from DT information */ + paddr = of_get_property(np, "qca,ar8327-initvals", &len); + if (paddr) { + if (len < (2 * sizeof(*paddr))) { + SSDK_ERROR("len:%d < 2 * sizeof(*paddr):%zu\n", len, 2 * sizeof(*paddr)); + return -EINVAL; + } + + len /= sizeof(*paddr); + + for (i = 0; i < len - 1; i += 2) { + reg = be32_to_cpup(paddr + i); + value = be32_to_cpup(paddr + i + 1); + priv->mii_write(priv->device_id, reg, value); + } + } + + value = priv->mii_read(priv->device_id, AR8327_REG_MODULE_EN); + value &= ~AR8327_REG_MODULE_EN_QM_ERR; + value &= ~AR8327_REG_MODULE_EN_LOOKUP_ERR; + priv->mii_write(priv->device_id, AR8327_REG_MODULE_EN, value); + + qca_switch_init(priv->device_id); +#ifdef IN_PORTVLAN + ssdk_portvlan_init(priv->device_id); +#endif + qca_mac_enable_intr(priv); + qca_ar8327_phy_enable(priv); + + return 0; +} +#else +static a_uint32_t +qca_ar8327_get_pad_cfg(struct ar8327_pad_cfg *pad_cfg) +{ + a_uint32_t value = 0; + + if (pad_cfg == 0) { + return 0; + } + + if(pad_cfg->mode == AR8327_PAD_MAC2MAC_MII) { + value = AR8327_PAD_CTRL_MAC_MII_EN; + if (pad_cfg->rxclk_sel) + value |= AR8327_PAD_CTRL_MAC_MII_RXCLK_SEL; + if (pad_cfg->txclk_sel) + value |= AR8327_PAD_CTRL_MAC_MII_TXCLK_SEL; + + } else if (pad_cfg->mode == AR8327_PAD_MAC2MAC_GMII) { + value = AR8327_PAD_CTRL_MAC_GMII_EN; + if (pad_cfg->rxclk_sel) + value |= AR8327_PAD_CTRL_MAC_GMII_RXCLK_SEL; + if (pad_cfg->txclk_sel) + value |= AR8327_PAD_CTRL_MAC_GMII_TXCLK_SEL; + + } else if (pad_cfg->mode == AR8327_PAD_MAC_SGMII) { + value = AR8327_PAD_CTRL_SGMII_EN; + + /* WAR for AP136 board. */ + value |= pad_cfg->txclk_delay_sel << + AR8327_PAD_CTRL_RGMII_TXCLK_DELAY_SEL_S; + value |= pad_cfg->rxclk_delay_sel << + AR8327_PAD_CTRL_RGMII_RXCLK_DELAY_SEL_S; + if (pad_cfg->rxclk_delay_en) + value |= AR8327_PAD_CTRL_RGMII_RXCLK_DELAY_EN; + if (pad_cfg->txclk_delay_en) + value |= AR8327_PAD_CTRL_RGMII_TXCLK_DELAY_EN; + + } else if (pad_cfg->mode == AR8327_PAD_MAC2PHY_MII) { + value = AR8327_PAD_CTRL_PHY_MII_EN; + if (pad_cfg->rxclk_sel) + value |= AR8327_PAD_CTRL_PHY_MII_RXCLK_SEL; + if (pad_cfg->txclk_sel) + value |= AR8327_PAD_CTRL_PHY_MII_TXCLK_SEL; + + } else if (pad_cfg->mode == AR8327_PAD_MAC2PHY_GMII) { + value = AR8327_PAD_CTRL_PHY_GMII_EN; + if (pad_cfg->pipe_rxclk_sel) + value |= AR8327_PAD_CTRL_PHY_GMII_PIPE_RXCLK_SEL; + if (pad_cfg->rxclk_sel) + value |= AR8327_PAD_CTRL_PHY_GMII_RXCLK_SEL; + if (pad_cfg->txclk_sel) + value |= AR8327_PAD_CTRL_PHY_GMII_TXCLK_SEL; + + } else if (pad_cfg->mode == AR8327_PAD_MAC_RGMII) { + value = AR8327_PAD_CTRL_RGMII_EN; + value |= pad_cfg->txclk_delay_sel << + AR8327_PAD_CTRL_RGMII_TXCLK_DELAY_SEL_S; + value |= pad_cfg->rxclk_delay_sel << + AR8327_PAD_CTRL_RGMII_RXCLK_DELAY_SEL_S; + if (pad_cfg->rxclk_delay_en) + value |= AR8327_PAD_CTRL_RGMII_RXCLK_DELAY_EN; + if (pad_cfg->txclk_delay_en) + value |= AR8327_PAD_CTRL_RGMII_TXCLK_DELAY_EN; + + } else if (pad_cfg->mode == AR8327_PAD_PHY_GMII) { + value = AR8327_PAD_CTRL_PHYX_GMII_EN; + + } else if (pad_cfg->mode == AR8327_PAD_PHY_RGMII) { + value = AR8327_PAD_CTRL_PHYX_RGMII_EN; + + } else if (pad_cfg->mode == AR8327_PAD_PHY_MII) { + value = AR8327_PAD_CTRL_PHYX_MII_EN; + + } else { + value = 0; + } + + return value; +} + +#ifndef BOARD_AR71XX +static a_uint32_t +qca_ar8327_get_pwr_sel(struct qca_phy_priv *priv, + struct ar8327_platform_data *plat_data) +{ + struct ar8327_pad_cfg *cfg = NULL; + a_uint32_t value; + + if (!plat_data) { + return 0; + } + + value = priv->mii_read(priv->device_id, AR8327_REG_PAD_MAC_PWR_SEL); + + cfg = plat_data->pad0_cfg; + + if (cfg && (cfg->mode == AR8327_PAD_MAC_RGMII) && + cfg->rgmii_1_8v) { + value |= AR8327_PAD_MAC_PWR_RGMII0_1_8V; + } + + cfg = plat_data->pad5_cfg; + if (cfg && (cfg->mode == AR8327_PAD_MAC_RGMII) && + cfg->rgmii_1_8v) { + value |= AR8327_PAD_MAC_PWR_RGMII1_1_8V; + } + + cfg = plat_data->pad6_cfg; + if (cfg && (cfg->mode == AR8327_PAD_MAC_RGMII) && + cfg->rgmii_1_8v) { + value |= AR8327_PAD_MAC_PWR_RGMII1_1_8V; + } + + return value; +} +#endif + +static a_uint32_t +qca_ar8327_set_led_cfg(struct qca_phy_priv *priv, + struct ar8327_platform_data *plat_data, + a_uint32_t pos) +{ + struct ar8327_led_cfg *led_cfg; + a_uint32_t new_pos = pos; + + led_cfg = plat_data->led_cfg; + if (led_cfg) { + if (led_cfg->open_drain) + new_pos |= AR8327_POS_LED_OPEN_EN; + else + new_pos &= ~AR8327_POS_LED_OPEN_EN; + + priv->mii_write(priv->device_id, AR8327_REG_LED_CTRL_0, led_cfg->led_ctrl0); + priv->mii_write(priv->device_id, AR8327_REG_LED_CTRL_1, led_cfg->led_ctrl1); + priv->mii_write(priv->device_id, AR8327_REG_LED_CTRL_2, led_cfg->led_ctrl2); + priv->mii_write(priv->device_id, AR8327_REG_LED_CTRL_3, led_cfg->led_ctrl3); + + if (new_pos != pos) { + new_pos |= AR8327_POS_POWER_ON_SEL; + } + } + return new_pos; +} +#ifndef BOARD_AR71XX +static int +qca_ar8327_set_sgmii_cfg(struct qca_phy_priv *priv, + struct ar8327_platform_data *plat_data, + a_uint32_t* new_pos) +{ + a_uint32_t value = 0; + + /*configure the SGMII*/ + value = priv->mii_read(priv->device_id, AR8327_REG_PAD_SGMII_CTRL); + value &= ~(AR8327_PAD_SGMII_CTRL_MODE_CTRL); + value |= ((plat_data->sgmii_cfg->sgmii_mode) << + AR8327_PAD_SGMII_CTRL_MODE_CTRL_S); + + if (priv->version == QCA_VER_AR8337) { + value |= (AR8327_PAD_SGMII_CTRL_EN_PLL | + AR8327_PAD_SGMII_CTRL_EN_RX | + AR8327_PAD_SGMII_CTRL_EN_TX); + } else { + value &= ~(AR8327_PAD_SGMII_CTRL_EN_PLL | + AR8327_PAD_SGMII_CTRL_EN_RX | + AR8327_PAD_SGMII_CTRL_EN_TX); + } + value |= AR8327_PAD_SGMII_CTRL_EN_SD; + + priv->mii_write(priv->device_id, AR8327_REG_PAD_SGMII_CTRL, value); + + if (plat_data->sgmii_cfg->serdes_aen) { + *new_pos &= ~AR8327_POS_SERDES_AEN; + } else { + *new_pos |= AR8327_POS_SERDES_AEN; + } + return 0; +} +#endif + +static int +qca_ar8327_set_plat_data_cfg(struct qca_phy_priv *priv, + struct ar8327_platform_data *plat_data) +{ + a_uint32_t pos, new_pos; + + pos = priv->mii_read(priv->device_id, AR8327_REG_POS); + + new_pos = qca_ar8327_set_led_cfg(priv, plat_data, pos); + +#ifndef BOARD_AR71XX + /*configure the SGMII*/ + if (plat_data->sgmii_cfg) { + qca_ar8327_set_sgmii_cfg(priv, plat_data, &new_pos); + } +#endif + + priv->mii_write(priv->device_id, AR8327_REG_POS, new_pos); + + return 0; +} + +static int +qca_ar8327_set_pad_cfg(struct qca_phy_priv *priv, + struct ar8327_platform_data *plat_data) +{ + a_uint32_t pad0 = 0, pad5 = 0, pad6 = 0; + + pad0 = qca_ar8327_get_pad_cfg(plat_data->pad0_cfg); + priv->mii_write(priv->device_id, AR8327_REG_PAD0_CTRL, pad0); + + pad5 = qca_ar8327_get_pad_cfg(plat_data->pad5_cfg); + if(priv->version == QCA_VER_AR8337) { + pad5 |= AR8327_PAD_CTRL_RGMII_RXCLK_DELAY_EN; + } + priv->mii_write(priv->device_id, AR8327_REG_PAD5_CTRL, pad5); + + pad6 = qca_ar8327_get_pad_cfg(plat_data->pad6_cfg); + if(plat_data->pad5_cfg && + (plat_data->pad5_cfg->mode == AR8327_PAD_PHY_RGMII)) + pad6 |= AR8327_PAD_CTRL_PHYX_RGMII_EN; + priv->mii_write(priv->device_id, AR8327_REG_PAD6_CTRL, pad6); + + return 0; +} + +void +qca_ar8327_port_init(struct qca_phy_priv *priv, a_uint32_t port) +{ + struct ar8327_platform_data *plat_data; + struct ar8327_port_cfg *port_cfg; + a_uint32_t value; + + plat_data = priv->phy->dev.platform_data; + if (plat_data == NULL) { + return; + } + + if (((port == 0) && plat_data->pad0_cfg) || + ((port == 5) && plat_data->pad5_cfg) || + ((port == 6) && plat_data->pad6_cfg)) { + switch (port) { + case 0: + port_cfg = &plat_data->cpuport_cfg; + break; + case 5: + port_cfg = &plat_data->port5_cfg; + break; + case 6: + port_cfg = &plat_data->port6_cfg; + break; + } + } else { + return; + } + + /*disable mac at first*/ + fal_port_rxmac_status_set(priv->device_id, port, A_FALSE); + fal_port_txmac_status_set(priv->device_id, port, A_FALSE); + value = port_cfg->duplex ? FAL_FULL_DUPLEX : FAL_HALF_DUPLEX; + fal_port_duplex_set(priv->device_id, port, value); + value = port_cfg->txpause ? A_TRUE : A_FALSE; + fal_port_txfc_status_set(priv->device_id, port, value); + value = port_cfg->rxpause ? A_TRUE : A_FALSE; + fal_port_rxfc_status_set(priv->device_id, port, value); + if(port_cfg->speed == AR8327_PORT_SPEED_10) { + value = FAL_SPEED_10; + } else if(port_cfg->speed == AR8327_PORT_SPEED_100) { + value = FAL_SPEED_100; + } else if(port_cfg->speed == AR8327_PORT_SPEED_1000) { + value = FAL_SPEED_1000; + } else { + value = FAL_SPEED_1000; + } + fal_port_speed_set(priv->device_id, port, value); + /*enable mac at last*/ + udelay(800); + fal_port_rxmac_status_set(priv->device_id, port, A_TRUE); + fal_port_txmac_status_set(priv->device_id, port, A_TRUE); +} + +int +qca_ar8327_hw_init(struct qca_phy_priv *priv) +{ + struct ar8327_platform_data *plat_data; + a_uint32_t i = 0; + a_uint32_t value = 0; + + plat_data = priv->phy->dev.platform_data; + if (plat_data == NULL) { + return -EINVAL; + } + + /*Before switch software reset, disable PHY and clear MAC PAD*/ + qca_ar8327_phy_linkdown(priv->device_id); + qca_mac_disable(priv->device_id); + udelay(10); + + qca_ar8327_set_plat_data_cfg(priv, plat_data); + + /*mac reset*/ + priv->mii_write(priv->device_id, AR8327_REG_MAC_SFT_RST, 0x3fff); + + msleep(100); + + /*First software reset S17 chip*/ + qca_ar8327_sw_soft_reset(priv); + udelay(1000); + + /*After switch software reset, need disable all ports' MAC with 1000M FULL*/ + qca_switch_set_mac_force(priv); + + qca_ar8327_set_pad_cfg(priv, plat_data); + + value = priv->mii_read(priv->device_id, AR8327_REG_MODULE_EN); + value &= ~AR8327_REG_MODULE_EN_QM_ERR; + value &= ~AR8327_REG_MODULE_EN_LOOKUP_ERR; + priv->mii_write(priv->device_id, AR8327_REG_MODULE_EN, value); + + qca_switch_init(priv->device_id); + +#ifndef BOARD_AR71XX + value = qca_ar8327_get_pwr_sel(priv, plat_data); + priv->mii_write(priv->device_id, AR8327_REG_PAD_MAC_PWR_SEL, value); +#endif + + msleep(1000); + + for (i = 0; i < AR8327_NUM_PORTS; i++) { + qca_ar8327_port_init(priv, i); + } + + qca_ar8327_phy_enable(priv); + + return 0; +} +#endif + +#if defined(IN_SWCONFIG) +#ifndef BOARD_AR71XX +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)) +static int +qca_ar8327_sw_get_reg_val(struct switch_dev *dev, + int reg, int *val) +{ + return 0; +} + +static int +qca_ar8327_sw_set_reg_val(struct switch_dev *dev, + int reg, int val) +{ + return 0; +} +#endif +#endif +static struct switch_attr qca_ar8327_globals[] = { +#if defined(IN_VLAN) + { + .name = "enable_vlan", + .description = "Enable 8021q VLAN", + .type = SWITCH_TYPE_INT, + .set = qca_ar8327_sw_set_vlan, + .get = qca_ar8327_sw_get_vlan, + .max = 1 + }, +#endif +#if defined(IN_MISC) + { + .name = "max_frame_size", + .description = "Set Max frame Size Of Mac", + .type = SWITCH_TYPE_INT, + .set = qca_ar8327_sw_set_max_frame_size, + .get = qca_ar8327_sw_get_max_frame_size, + .max = 9018 + }, +#endif +#if defined(IN_MIB) + { + .name = "reset_mibs", + .description = "Reset All MIB Counters", + .type = SWITCH_TYPE_NOVAL, + .set = qca_ar8327_sw_set_reset_mibs, + }, +#endif +#ifdef IN_FDB + { + .name = "flush_arl", + .description = "Flush All ARL table", + .type = SWITCH_TYPE_NOVAL, + .set = qca_ar8327_sw_atu_flush, + }, + { + .name = "dump_arl", + .description = "Dump All ARL table", + .type = SWITCH_TYPE_STRING, + .get = qca_ar8327_sw_atu_dump, + }, +#endif + { + .name = "switch_ext", + .description = "Switch extended configuration", + .type = SWITCH_TYPE_EXT, + .set = qca_ar8327_sw_switch_ext, + }, +}; + +#if defined(IN_MIB) +static struct switch_attr qca_ar8327_port[] = { + { + .name = "reset_mib", + .description = "Reset Mib Counters", + .type = SWITCH_TYPE_NOVAL, + .set = qca_ar8327_sw_set_port_reset_mib, + }, + { + .name = "mib", + .description = "Get Mib Counters", + .type = SWITCH_TYPE_STRING, + .set = NULL, + .get = qca_ar8327_sw_get_port_mib, + }, +}; +#endif + +#if defined(IN_VLAN) +static struct switch_attr qca_ar8327_vlan[] = { + { + .name = "vid", + .description = "Configure Vlan Id", + .type = SWITCH_TYPE_INT, + .set = qca_ar8327_sw_set_vid, + .get = qca_ar8327_sw_get_vid, + .max = 4094, + }, +}; +#endif + +const struct switch_dev_ops qca_ar8327_sw_ops = { + .attr_global = { + .attr = qca_ar8327_globals, + .n_attr = ARRAY_SIZE(qca_ar8327_globals), + }, +#if defined(IN_MIB) + .attr_port = { + .attr = qca_ar8327_port, + .n_attr = ARRAY_SIZE(qca_ar8327_port), + }, +#endif +#if defined(IN_VLAN) + .attr_vlan = { + .attr = qca_ar8327_vlan, + .n_attr = ARRAY_SIZE(qca_ar8327_vlan), + }, + .get_port_pvid = qca_ar8327_sw_get_pvid, + .set_port_pvid = qca_ar8327_sw_set_pvid, + .get_vlan_ports = qca_ar8327_sw_get_ports, + .set_vlan_ports = qca_ar8327_sw_set_ports, + .apply_config = qca_ar8327_sw_hw_apply, +#endif +#if defined(IN_MISC) + .reset_switch = qca_ar8327_sw_reset_switch, +#endif +#if defined(IN_PORTCONTROL) + .get_port_link = qca_ar8327_sw_get_port_link, +#endif +#ifndef BOARD_AR71XX +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)) + .get_reg_val = qca_ar8327_sw_get_reg_val, + .set_reg_val = qca_ar8327_sw_set_reg_val, +#endif +#endif +}; +#endif + +#define SSDK_MIB_CHANGE_WQ + +static int +qca_phy_mib_task(struct qca_phy_priv *priv) +{ + qca_ar8327_sw_mib_task(priv); + return 0; +} + +static void +qca_phy_mib_work_task(struct work_struct *work) +{ + struct qca_phy_priv *priv = container_of(work, struct qca_phy_priv, + mib_dwork.work); + + mutex_lock(&priv->mib_lock); + + qca_phy_mib_task(priv); + + mutex_unlock(&priv->mib_lock); +#ifndef SSDK_MIB_CHANGE_WQ + schedule_delayed_work(&priv->mib_dwork, + msecs_to_jiffies(QCA_PHY_MIB_WORK_DELAY)); +#else + queue_delayed_work_on(0, system_long_wq, &priv->mib_dwork, + msecs_to_jiffies(QCA_PHY_MIB_WORK_DELAY)); +#endif +} + +int +qca_phy_mib_work_start(struct qca_phy_priv *priv) +{ + mutex_init(&priv->mib_lock); + if(SW_OK != fal_mib_counter_alloc(priv->device_id, &priv->mib_counters)){ + SSDK_ERROR("Memory allocation fail\n"); + return -ENOMEM; + } + + INIT_DELAYED_WORK(&priv->mib_dwork, qca_phy_mib_work_task); +#ifndef SSDK_MIB_CHANGE_WQ + schedule_delayed_work(&priv->mib_dwork, + msecs_to_jiffies(QCA_PHY_MIB_WORK_DELAY)); +#else + queue_delayed_work_on(0, system_long_wq, &priv->mib_dwork, + msecs_to_jiffies(QCA_PHY_MIB_WORK_DELAY)); +#endif + + return 0; +} + +void +qca_phy_mib_work_stop(struct qca_phy_priv *priv) +{ + if(!priv) + return; + if(priv->mib_counters) + kfree(priv->mib_counters); + cancel_delayed_work_sync(&priv->mib_dwork); +} + +#define SSDK_QM_CHANGE_WQ + +static void +qm_err_check_work_task_polling(struct work_struct *work) +{ + struct qca_phy_priv *priv = container_of(work, struct qca_phy_priv, + qm_dwork_polling.work); + + mutex_lock(&priv->qm_lock); + + qca_ar8327_sw_mac_polling_task(priv); + + mutex_unlock(&priv->qm_lock); + +#ifndef SSDK_QM_CHANGE_WQ + schedule_delayed_work(&priv->qm_dwork, + msecs_to_jiffies(QCA_QM_WORK_DELAY)); +#else + queue_delayed_work_on(0, system_long_wq, &priv->qm_dwork_polling, + msecs_to_jiffies(QCA_QM_WORK_DELAY)); +#endif +} + +static int config_gpio(a_uint32_t gpio_num) +{ + int error; + + if (gpio_is_valid(gpio_num)) + { + error = gpio_request_one(gpio_num, GPIOF_IN, "linkchange"); + if (error < 0) { + SSDK_ERROR("gpio request faild \n"); + return -1; + } + gpio_set_debounce(gpio_num, 60000); + } + else + { + SSDK_ERROR("gpio is invalid\n"); + return -1; + } + + return 0; +} +static int qca_link_polling_select(struct qca_phy_priv *priv) +{ + struct device_node *np = NULL; + const __be32 *link_polling_required, *link_intr_gpio; + a_int32_t len; + + if (priv->ess_switch_flag == A_TRUE) + np = priv->of_node; + else if(priv->version == QCA_VER_AR8337 || priv->version == QCA_VER_AR8327) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,9,0)) + np = priv->phy->mdio.dev.of_node; +#else + np = priv->phy->dev.of_node; +#endif + else + SSDK_ERROR("cannot find np node!\n"); + + if(!np) + { + SSDK_ERROR("np is null !\n"); + return -1; + } + + link_polling_required = of_get_property(np, "link-polling-required", &len); + if (!link_polling_required ) + { + SSDK_INFO("link-polling-required node does not exist\n"); + return -1; + } + priv->link_polling_required = be32_to_cpup(link_polling_required); + if(!priv->link_polling_required) + { + link_intr_gpio = of_get_property(np, "link-intr-gpio", &len); + if (!link_intr_gpio ) + { + SSDK_ERROR("cannot find link-intr-gpio node\n"); + return -1; + } + if(config_gpio(be32_to_cpup(link_intr_gpio))) + return -1; + priv->link_interrupt_no = gpio_to_irq (be32_to_cpup(link_intr_gpio)); + SSDK_INFO("the interrupt number is:%x\n",priv->link_interrupt_no); + } + + return 0; +} + +int +qm_err_check_work_start(struct qca_phy_priv *priv) +{ + /*Only valid for S17c chip*/ + if (priv->version != QCA_VER_AR8337 && + priv->version != QCA_VER_AR8327 && + priv->version != QCA_VER_DESS) + { + return 0; + } + + mutex_init(&priv->qm_lock); + INIT_DELAYED_WORK(&priv->qm_dwork_polling, qm_err_check_work_task_polling); +#ifndef SSDK_MIB_CHANGE_WQ + schedule_delayed_work(&priv->qm_dwork_polling, + msecs_to_jiffies(QCA_QM_WORK_DELAY)); +#else + queue_delayed_work_on(0, system_long_wq, &priv->qm_dwork_polling, + msecs_to_jiffies(QCA_QM_WORK_DELAY)); +#endif + + return 0; +} + +void +qm_err_check_work_stop(struct qca_phy_priv *priv) +{ + /*Only valid for S17c chip*/ + if (priv->version != QCA_VER_AR8337 && + priv->version != QCA_VER_AR8327 && + priv->version != QCA_VER_DESS) return; + + cancel_delayed_work_sync(&priv->qm_dwork_polling); + +} +#ifdef DESS +static void +dess_rgmii_mac_work_task(struct work_struct *work) +{ + struct qca_phy_priv *priv = container_of(work, struct qca_phy_priv, + rgmii_dwork.work); + + mutex_lock(&priv->rgmii_lock); + + dess_rgmii_sw_mac_polling_task(priv); + + mutex_unlock(&priv->rgmii_lock); + + schedule_delayed_work(&priv->rgmii_dwork, msecs_to_jiffies(QCA_RGMII_WORK_DELAY)); +} + +int +dess_rgmii_mac_work_start(struct qca_phy_priv *priv) +{ + mutex_init(&priv->rgmii_lock); + + INIT_DELAYED_WORK(&priv->rgmii_dwork, dess_rgmii_mac_work_task); + + schedule_delayed_work(&priv->rgmii_dwork, msecs_to_jiffies(QCA_RGMII_WORK_DELAY)); + + return 0; +} + +void +dess_rgmii_mac_work_stop(struct qca_phy_priv *priv) +{ + cancel_delayed_work_sync(&priv->rgmii_dwork); +} +#endif + +void +qca_mac_port_status_init(a_uint32_t dev_id, a_uint32_t port_id) +{ + qca_phy_priv_global[dev_id]->port_old_link[port_id - 1] = 0; + qca_phy_priv_global[dev_id]->port_old_speed[port_id - 1] = FAL_SPEED_BUTT; + qca_phy_priv_global[dev_id]->port_old_duplex[port_id - 1] = FAL_DUPLEX_BUTT; + qca_phy_priv_global[dev_id]->port_old_tx_flowctrl[port_id - 1] = A_FALSE; + qca_phy_priv_global[dev_id]->port_old_rx_flowctrl[port_id - 1] = A_FALSE; + qca_phy_priv_global[dev_id]->port_tx_flowctrl_forcemode[port_id - 1] = A_FALSE; + qca_phy_priv_global[dev_id]->port_rx_flowctrl_forcemode[port_id - 1] = A_FALSE; +} + +void +qca_mac_sw_sync_port_status_init(a_uint32_t dev_id) +{ + a_uint32_t port_id; + + for (port_id = SSDK_PHYSICAL_PORT1; port_id < SW_MAX_NR_PORT; port_id ++) { + qca_mac_port_status_init(dev_id, port_id); + } +} +void +qca_mac_sw_sync_work_task(struct work_struct *work) +{ + adpt_api_t *p_adpt_api; + + struct qca_phy_priv *priv = container_of(work, struct qca_phy_priv, + mac_sw_sync_dwork.work); + + mutex_lock(&priv->mac_sw_sync_lock); + + if((p_adpt_api = adpt_api_ptr_get(priv->device_id)) != NULL) { + if (NULL == p_adpt_api->adpt_port_polling_sw_sync_set) + return; + p_adpt_api->adpt_port_polling_sw_sync_set(priv); + } + + mutex_unlock(&priv->mac_sw_sync_lock); + + schedule_delayed_work(&priv->mac_sw_sync_dwork, + msecs_to_jiffies(QCA_MAC_SW_SYNC_WORK_DELAY)); +} + +int +qca_mac_sw_sync_work_start(struct qca_phy_priv *priv) +{ + if ((priv->version != QCA_VER_HPPE) && (priv->version != QCA_VER_SCOMPHY)) + return 0; + + if (priv->version == QCA_VER_HPPE) { + qca_mac_sw_sync_port_status_init(priv->device_id); + } + + mutex_init(&priv->mac_sw_sync_lock); + + INIT_DELAYED_WORK(&priv->mac_sw_sync_dwork, + qca_mac_sw_sync_work_task); + schedule_delayed_work(&priv->mac_sw_sync_dwork, + msecs_to_jiffies(QCA_MAC_SW_SYNC_WORK_DELAY)); + + return 0; +} + +void +qca_mac_sw_sync_work_stop(struct qca_phy_priv *priv) +{ + if ((priv->version != QCA_VER_HPPE) && (priv->version != QCA_VER_SCOMPHY)) { + return; + } + cancel_delayed_work_sync(&priv->mac_sw_sync_dwork); +} + +void +qca_mac_sw_sync_work_resume(struct qca_phy_priv *priv) +{ + if ((priv->version != QCA_VER_HPPE) && (priv->version != QCA_VER_SCOMPHY)) { + return; + } + + schedule_delayed_work(&priv->mac_sw_sync_dwork, + msecs_to_jiffies(QCA_MAC_SW_SYNC_WORK_DELAY)); +} + +int +qca_phy_id_chip(struct qca_phy_priv *priv) +{ + a_uint32_t value, version; + + value = qca_ar8216_mii_read(priv->device_id, AR8327_REG_CTRL); + version = value & (AR8327_CTRL_REVISION | + AR8327_CTRL_VERSION); + priv->version = (version & AR8327_CTRL_VERSION) >> + AR8327_CTRL_VERSION_S; + priv->revision = (version & AR8327_CTRL_REVISION); + + if((priv->version == QCA_VER_AR8327) || + (priv->version == QCA_VER_AR8337) || + (priv->version == QCA_VER_AR8227)) { + return 0; + + } else { + SSDK_ERROR("unsupported QCA device\n"); + return -ENODEV; + } +} + +#if defined(IN_SWCONFIG) +static int qca_switchdev_register(struct qca_phy_priv *priv) +{ + struct switch_dev *sw_dev; + int ret = SW_OK; + sw_dev = &priv->sw_dev; + + switch (priv->version) { + case QCA_VER_AR8227: + sw_dev->name = "QCA AR8227"; + sw_dev->alias = "QCA AR8227"; + break; + case QCA_VER_AR8327: + sw_dev->name = "QCA AR8327"; + sw_dev->alias = "QCA AR8327"; + break; + case QCA_VER_AR8337: + sw_dev->name = "QCA AR8337"; + sw_dev->alias = "QCA AR8337"; + break; + case QCA_VER_DESS: + sw_dev->name = "QCA DESS"; + sw_dev->alias = "QCA DESS"; + break; + case QCA_VER_HPPE: + sw_dev->name = "QCA HPPE"; + sw_dev->alias = "QCA HPPE"; + break; + case QCA_VER_SCOMPHY: +#ifdef MP + if(adapt_scomphy_revision_get(priv->device_id) + == MP_GEPHY) + { + sw_dev->name = "QCA MP"; + sw_dev->alias = "QCA MP"; + } +#endif + break; + default: + sw_dev->name = "unknown switch"; + sw_dev->alias = "unknown switch"; + break; + } + + sw_dev->ops = &qca_ar8327_sw_ops; + sw_dev->vlans = AR8327_MAX_VLANS; + sw_dev->ports = SSDK_MAX_PORT_NUM; + + ret = register_switch(sw_dev, NULL); + if (ret != SW_OK) { + SSDK_ERROR("register_switch failed for %s\n", sw_dev->name); + return ret; + } + + return ret; +} +#endif + +static int +qca_phy_config_init(struct phy_device *pdev) +{ + struct qca_phy_priv *priv = pdev->priv; + int ret = 0; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,9,0)) + if (pdev->mdio.addr != 0) { +#else + if (pdev->addr != 0) { +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)) + pdev->supported |= SUPPORTED_1000baseT_Full; + pdev->advertising |= ADVERTISED_1000baseT_Full; +#else + linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, + pdev->supported); + linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, + pdev->advertising); +#endif + +#ifndef BOARD_AR71XX +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) + ssdk_phy_rgmii_set(priv); +#endif +#endif + return 0; + } + + if (priv == NULL) + return -ENOMEM; + + priv->phy = pdev; + ret = qca_phy_id_chip(priv); + if (ret != 0) { + return ret; + } + + priv->mii_read = qca_ar8216_mii_read; + priv->mii_write = qca_ar8216_mii_write; + priv->phy_write = qca_ar8327_phy_write; + priv->phy_read = qca_ar8327_phy_read; + priv->phy_dbg_write = qca_ar8327_phy_dbg_write; + priv->phy_dbg_read = qca_ar8327_phy_dbg_read; + priv->phy_mmd_write = qca_ar8327_mmd_write; + priv->ports = AR8327_NUM_PORTS; + + ret = qca_link_polling_select(priv); + if(ret) + priv->link_polling_required = 1; + pdev->priv = priv; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)) + pdev->supported |= SUPPORTED_1000baseT_Full; + pdev->advertising |= ADVERTISED_1000baseT_Full; +#else + linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, + pdev->supported); + linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, + pdev->advertising); +#endif + +#if defined(IN_SWCONFIG) + ret = qca_switchdev_register(priv); + if (ret != SW_OK) { + return ret; + } +#endif + priv->qca_ssdk_sw_dev_registered = A_TRUE; + + snprintf(priv->link_intr_name, IFNAMSIZ, "switch0"); + + ret = qca_ar8327_hw_init(priv); + if (ret != 0) { + return ret; + } + + qca_phy_mib_work_start(priv); + + if(priv->link_polling_required) + { + SSDK_INFO("polling is selected\n"); + ret = qm_err_check_work_start(priv); + if (ret != 0) + { + SSDK_ERROR("qm_err_check_work_start failed for chip 0x%02x%02x\n", priv->version, priv->revision); + return ret; + } + } + else + { + SSDK_INFO("interrupt is selected\n"); + priv->interrupt_flag = IRQF_TRIGGER_LOW; + ret = qca_intr_init(priv); + if(ret) + SSDK_ERROR("the interrupt init faild !\n"); + } + + return ret; +} + +#if defined(DESS) || defined(HPPE) || defined (ISISC) || defined (ISIS) || defined(MP) +static int ssdk_switch_register(a_uint32_t dev_id, ssdk_chip_type chip_type) +{ + struct qca_phy_priv *priv; + int ret = 0; + a_uint32_t chip_id = 0; + priv = qca_phy_priv_global[dev_id]; + + priv->mii_read = qca_ar8216_mii_read; + priv->mii_write = qca_ar8216_mii_write; + priv->phy_write = qca_ar8327_phy_write; + priv->phy_read = qca_ar8327_phy_read; + priv->phy_dbg_write = qca_ar8327_phy_dbg_write; + priv->phy_dbg_read = qca_ar8327_phy_dbg_read; + priv->phy_mmd_write = qca_ar8327_mmd_write; + priv->ports = SSDK_MAX_PORT_NUM; +#ifdef MP + if(chip_type == CHIP_SCOMPHY) + { + priv->version = QCA_VER_SCOMPHY; + SSDK_INFO("Chip version 0x%02x\n", priv->version); + } + else +#endif + { + if (fal_reg_get(dev_id, 0, (a_uint8_t *)&chip_id, 4) == SW_OK) { + priv->version = ((chip_id >> 8) & 0xff); + priv->revision = (chip_id & 0xff); + SSDK_INFO("Chip version 0x%02x%02x\n", priv->version, priv->revision); + } + } + + mutex_init(&priv->reg_mutex); + +#if defined(IN_SWCONFIG) + ret = qca_switchdev_register(priv); + if (ret != SW_OK) { + return ret; + } +#endif + + snprintf(priv->link_intr_name, IFNAMSIZ, "switch%d", dev_id); + + priv->qca_ssdk_sw_dev_registered = A_TRUE; + ret = qca_phy_mib_work_start(qca_phy_priv_global[dev_id]); + if (ret != 0) { + SSDK_ERROR("qca_phy_mib_work_start failed for chip 0x%02x%02x\n", priv->version, priv->revision); + return ret; + } + ret = qca_link_polling_select(priv); + if(ret) + priv->link_polling_required = 1; + if(priv->link_polling_required) + { + SSDK_INFO("polling is selected\n"); + ret = qm_err_check_work_start(priv); + if (ret != 0) + { + SSDK_ERROR("qm_err_check_work_start failed for chip 0x%02x%02x\n", priv->version, priv->revision); + return ret; + } + } + else + { + SSDK_INFO("interrupt is selected\n"); + priv->interrupt_flag = IRQF_TRIGGER_MASK; + ret = qca_intr_init(priv); + if(ret) + { + SSDK_ERROR("the interrupt init faild !\n"); + return ret; + } + } + +#if 0 +#ifdef DESS + if ((ssdk_dt_global.mac_mode == PORT_WRAPPER_SGMII0_RGMII5) + ||(ssdk_dt_global.mac_mode == PORT_WRAPPER_SGMII1_RGMII5) + ||(ssdk_dt_global.mac_mode == PORT_WRAPPER_SGMII0_RGMII4) + ||(ssdk_dt_global.mac_mode == PORT_WRAPPER_SGMII1_RGMII4) + ||(ssdk_dt_global.mac_mode == PORT_WRAPPER_SGMII4_RGMII4)) { + ret = dess_rgmii_mac_work_start(priv); + if (ret != 0) { + SSDK_ERROR("dess_rgmii_mac_work_start failed for chip 0x%02x%02x\n", priv->version, priv->revision); + return ret; + } + } +#endif +#endif +#ifdef HPPE + if (priv->version == QCA_VER_HPPE) { + ret = qca_mac_sw_sync_work_start(priv); + if (ret != 0) { + SSDK_ERROR("qca_mac_sw_sync_work_start failed for chip 0x%02x%02x\n", + priv->version, priv->revision); + return ret; + } + } +#endif + + return 0; + +} + +static int ssdk_switch_unregister(a_uint32_t dev_id) +{ + qca_phy_mib_work_stop(qca_phy_priv_global[dev_id]); + qm_err_check_work_stop(qca_phy_priv_global[dev_id]); +#ifdef HPPE + qca_mac_sw_sync_work_stop(qca_phy_priv_global[dev_id]); +#endif +#if defined(IN_SWCONFIG) + unregister_switch(&qca_phy_priv_global[dev_id]->sw_dev); +#endif + return 0; +} +#endif + +static int +qca_phy_read_status(struct phy_device *pdev) +{ + struct qca_phy_priv *priv = pdev->priv; + a_uint32_t port_status; + a_uint32_t port_speed; + int ret = 0, addr = 0; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,9,0)) + addr = pdev->mdio.addr; +#else + addr = pdev->addr; +#endif + if (addr != 0) { + mutex_lock(&priv->reg_mutex); + ret = genphy_read_status(pdev); + mutex_unlock(&priv->reg_mutex); + return ret; + } + + mutex_lock(&priv->reg_mutex); + port_status = priv->mii_read(priv->device_id, AR8327_REG_PORT_STATUS(addr)); + mutex_unlock(&priv->reg_mutex); + + pdev->link = 1; + if (port_status & AR8327_PORT_STATUS_LINK_AUTO) { + pdev->link = !!(port_status & AR8327_PORT_STATUS_LINK_UP); + if (pdev->link == 0) { + return ret; + } + } + + port_speed = (port_status & AR8327_PORT_STATUS_SPEED) >> + AR8327_PORT_STATUS_SPEED_S; + + switch (port_speed) { + case AR8327_PORT_SPEED_10M: + pdev->speed = SPEED_10; + break; + case AR8327_PORT_SPEED_100M: + pdev->speed = SPEED_100; + break; + case AR8327_PORT_SPEED_1000M: + pdev->speed = SPEED_1000; + break; + default: + pdev->speed = 0; + break; + } + + if(port_status & AR8327_PORT_STATUS_DUPLEX) { + pdev->duplex = DUPLEX_FULL; + } else { + pdev->duplex = DUPLEX_HALF; + } + + pdev->state = PHY_RUNNING; + netif_carrier_on(pdev->attached_dev); + pdev->adjust_link(pdev->attached_dev); + + return ret; +} + +static int +qca_phy_config_aneg(struct phy_device *pdev) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,9,0)) + if (pdev->mdio.addr != 0) { +#else + if (pdev->addr != 0) { +#endif + return genphy_config_aneg(pdev); + } + + return 0; +} + +int qca_phy_suspend(struct phy_device *phydev) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,9,0)) + struct mii_bus *bus = phydev->mdio.bus; +#else + struct mii_bus *bus = phydev->bus; +#endif + int val = 0; + int addr; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,9,0)) + addr = phydev->mdio.addr; +#else + addr = phydev->addr; +#endif + + val = mdiobus_read(bus, addr, MII_BMCR); + return mdiobus_write(bus, addr, MII_BMCR, (u16)(val | BMCR_PDOWN)); +} + +int qca_phy_resume(struct phy_device *phydev) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,9,0)) + struct mii_bus *bus = phydev->mdio.bus; +#else + struct mii_bus *bus = phydev->bus; +#endif + int val = 0; + int addr; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,9,0)) + addr = phydev->mdio.addr; +#else + addr = phydev->addr; +#endif + + val = mdiobus_read(bus, addr, MII_BMCR); + return mdiobus_write(bus, addr, MII_BMCR, (u16)(val & ~BMCR_PDOWN)); +} + +static int +qca_phy_probe(struct phy_device *pdev) +{ + struct qca_phy_priv *priv; + int ret; + + priv = kzalloc(sizeof(struct qca_phy_priv), GFP_KERNEL); + if (priv == NULL) { + return -ENOMEM; + } + + pdev->priv = priv; + priv->phy = pdev; + mutex_init(&priv->reg_mutex); + + ret = qca_phy_id_chip(priv); + return ret; +} + +static void +qca_phy_remove(struct phy_device *pdev) +{ + struct qca_phy_priv *priv = pdev->priv; + int addr; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,9,0)) + addr = pdev->mdio.addr; +#else + addr = pdev->addr; +#endif + + if ((addr == 0) && priv && (priv->ports != 0)) { + qca_phy_mib_work_stop(priv); + qm_err_check_work_stop(priv); +#if defined(IN_SWCONFIG) + if (priv->sw_dev.name != NULL) + unregister_switch(&priv->sw_dev); +#endif + } + + if (priv) { + kfree(priv); + } +} + +static struct phy_driver qca_phy_driver = { + .name = "QCA AR8216 AR8236 AR8316 AR8327 AR8337", + .phy_id = 0x004d0000, + .phy_id_mask= 0xffff0000, + .probe = qca_phy_probe, + .remove = qca_phy_remove, + .config_init= &qca_phy_config_init, + .config_aneg= &qca_phy_config_aneg, + .read_status= &qca_phy_read_status, + .suspend = qca_phy_suspend, + .resume = qca_phy_resume, + .features = PHY_BASIC_FEATURES, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,9,0)) + .mdiodrv.driver = { .owner = THIS_MODULE }, +#else + .driver = { .owner = THIS_MODULE }, +#endif +}; + +#ifndef BOARD_AR71XX +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) +#ifdef DESS +struct reset_control *ess_rst = NULL; +struct reset_control *ess_mac_clock_disable[5] = {NULL,NULL,NULL,NULL,NULL}; + +void ssdk_ess_reset(void) +{ + if (!ess_rst) + return; + reset_control_assert(ess_rst); + mdelay(10); + reset_control_deassert(ess_rst); + mdelay(100); +} +#endif + +char ssdk_driver_name[] = "ess_ssdk"; + +static int ssdk_probe(struct platform_device *pdev) +{ + struct device_node *np; + + np = of_node_get(pdev->dev.of_node); + if (of_device_is_compatible(np, "qcom,ess-instance")) + return of_platform_populate(np, NULL, NULL, &pdev->dev); + +#ifdef DESS + ess_rst = devm_reset_control_get(&pdev->dev, "ess_rst"); + ess_mac_clock_disable[0] = devm_reset_control_get(&pdev->dev, "ess_mac1_clk_dis"); + ess_mac_clock_disable[1] = devm_reset_control_get(&pdev->dev, "ess_mac2_clk_dis"); + ess_mac_clock_disable[2] = devm_reset_control_get(&pdev->dev, "ess_mac3_clk_dis"); + ess_mac_clock_disable[3] = devm_reset_control_get(&pdev->dev, "ess_mac4_clk_dis"); + ess_mac_clock_disable[4] = devm_reset_control_get(&pdev->dev, "ess_mac5_clk_dis"); + + if (IS_ERR(ess_rst)) { + SSDK_INFO("ess_rst doesn't exist!\n"); + return 0; + } + if (!ess_mac_clock_disable[0]) { + SSDK_ERROR("ess_mac1_clock_disable fail!\n"); + return -1; + } + if (!ess_mac_clock_disable[1]) { + SSDK_ERROR("ess_mac2_clock_disable fail!\n"); + return -1; + } + if (!ess_mac_clock_disable[2]) { + SSDK_ERROR("ess_mac3_clock_disable fail!\n"); + return -1; + } + if (!ess_mac_clock_disable[3]) { + SSDK_ERROR("ess_mac4_clock_disable fail!\n"); + return -1; + } + if (!ess_mac_clock_disable[4]) { + SSDK_ERROR("ess_mac5_clock_disable fail!\n"); + return -1; + } +#endif + return 0; +} + +static const struct of_device_id ssdk_of_mtable[] = { + {.compatible = "qcom,ess-switch" }, + {.compatible = "qcom,ess-switch-ipq60xx" }, + {.compatible = "qcom,ess-switch-ipq807x" }, + {.compatible = "qcom,ess-instance" }, + {} +}; + +static struct platform_driver ssdk_driver = { + .driver = { + .name = ssdk_driver_name, + .owner = THIS_MODULE, + .of_match_table = ssdk_of_mtable, + }, + .probe = ssdk_probe, +}; +#endif +#endif +#ifdef DESS +static u32 phy_t_status = 0; +static a_uint16_t modectrl_data = 0; +void ssdk_malibu_psgmii_and_dakota_dess_reset(a_uint32_t dev_id, a_uint32_t first_phy_addr) +{ +#ifndef BOARD_AR71XX +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) + int m = 0, n = 0; + a_uint32_t psgmii_phy_addr; + + psgmii_phy_addr = first_phy_addr + 5; + + /*reset Malibu PSGMII and Dakota ESS start*/ + qca_ar8327_phy_write(dev_id, psgmii_phy_addr, 0x0, 0x005b);/*fix phy psgmii RX 20bit*/ + qca_ar8327_phy_write(dev_id, psgmii_phy_addr, 0x0, 0x001b);/*reset phy psgmii*/ + qca_ar8327_phy_write(dev_id, psgmii_phy_addr, 0x0, 0x005b);/*release reset phy psgmii*/ + /* mdelay(100); this 100ms be replaced with below malibu psgmii calibration process*/ + /*check malibu psgmii calibration done start*/ + n = 0; + while (n < 100) { + u16 status; + status = qca_phy_mmd_read(dev_id, psgmii_phy_addr, 1, 0x28); + if (status & BIT(0)) + break; + mdelay(10); + n++; + } +#ifdef PSGMII_DEBUG + if (n >= 100) + SSDK_INFO("MALIBU PSGMII PLL_VCO_CALIB NOT READY\n"); +#endif + mdelay(50); + /*check malibu psgmii calibration done end..*/ + qca_ar8327_phy_write(dev_id, psgmii_phy_addr, 0x1a, 0x2230);/*freeze phy psgmii RX CDR*/ + + ssdk_ess_reset(); + /*check dakota psgmii calibration done start*/ + m = 0; + while (m < 100) { + u32 status = 0; + qca_psgmii_reg_read(dev_id, 0xa0, (a_uint8_t *)&status, 4); + if (status & BIT(0)) + break; + mdelay(10); + m++; + } +#ifdef PSGMII_DEBUG + if (m >= 100) + SSDK_INFO("DAKOTA PSGMII PLL_VCO_CALIB NOT READY\n"); +#endif + mdelay(50); + /*check dakota psgmii calibration done end..*/ + qca_ar8327_phy_write(dev_id, psgmii_phy_addr, 0x1a, 0x3230);/*relesae phy psgmii RX CDR*/ + qca_ar8327_phy_write(dev_id, psgmii_phy_addr, 0x0, 0x005f);/*release phy psgmii RX 20bit*/ + mdelay(200); +#endif +#endif + /*reset Malibu PSGMII and Dakota ESS end*/ + return; +} + +static void ssdk_psgmii_phy_testing_printf(a_uint32_t phy, u32 tx_ok, u32 rx_ok, + u32 tx_counter_error, u32 rx_counter_error) +{ + SSDK_INFO("tx_ok = 0x%x, rx_ok = 0x%x, tx_counter_error = 0x%x, rx_counter_error = 0x%x\n", + tx_ok, rx_ok, tx_counter_error, rx_counter_error); + if (tx_ok== 0x3000 && tx_counter_error == 0) + SSDK_INFO("PHY %d single PSGMII test pass\n", phy); + else + SSDK_ERROR("PHY %d single PSGMII test fail\n", phy); + return; + +} +static void ssdk_psgmii_all_phy_testing_printf(a_uint32_t phy, u32 tx_ok, u32 rx_ok, + u32 tx_counter_error, u32 rx_counter_error) +{ + SSDK_INFO("tx_ok = 0x%x, rx_ok = 0x%x, tx_counter_error = 0x%x, rx_counter_error = 0x%x\n", + tx_ok, rx_ok, tx_counter_error, rx_counter_error); + if (tx_ok== 0x3000 && tx_counter_error == 0) + SSDK_INFO("PHY %d all PSGMII test pass\n", phy); + else + SSDK_ERROR("PHY %d all PSGMII test fail\n", phy); + return; + +} +void ssdk_psgmii_single_phy_testing(a_uint32_t dev_id, a_uint32_t phy, a_bool_t enable) +{ + int j = 0; + + u32 tx_counter_ok, tx_counter_error; + u32 rx_counter_ok, rx_counter_error; + u32 tx_counter_ok_high16; + u32 rx_counter_ok_high16; + u32 tx_ok, rx_ok; + qca_ar8327_phy_write(dev_id, phy, 0x0, 0x9000); + qca_ar8327_phy_write(dev_id, phy, 0x0, 0x4140); + j = 0; + while (j < 100) { + u16 status = 0; + qca_ar8327_phy_read(dev_id, phy, 0x11, &status); + if (status & (1 << 10)) + break; + mdelay(10); + j++; + } + /*add a 300ms delay as qm polling task existing*/ + if (enable == A_TRUE) + mdelay(300); + + /*enable check*/ + qca_phy_mmd_write(dev_id, phy, 7, 0x8029, 0x0000); + qca_phy_mmd_write(dev_id, phy, 7, 0x8029, 0x0003); + + /*start traffic*/ + qca_phy_mmd_write(dev_id, phy, 7, 0x8020, 0xa000); + mdelay(200); + + /*check counter*/ + tx_counter_ok = qca_phy_mmd_read(dev_id, phy, 7, 0x802e); + tx_counter_ok_high16 = qca_phy_mmd_read(dev_id, phy, 7, 0x802d); + tx_counter_error = qca_phy_mmd_read(dev_id, phy, 7, 0x802f); + rx_counter_ok = qca_phy_mmd_read(dev_id, phy, 7, 0x802b); + rx_counter_ok_high16 = qca_phy_mmd_read(dev_id, phy, 7, 0x802a); + rx_counter_error = qca_phy_mmd_read(dev_id, phy, 7, 0x802c); + tx_ok = tx_counter_ok + (tx_counter_ok_high16<<16); + rx_ok = rx_counter_ok + (rx_counter_ok_high16<<16); + if (tx_ok== 0x3000 && tx_counter_error == 0) { + /*success*/ + phy_t_status &= (~(1<= (first_phy_addr + 5)) + break; + mdelay(10); + j++; + } + /*add a 300ms delay as qm polling task existing*/ + if (enable == A_TRUE) + mdelay(300); + + /*enable check*/ + qca_phy_mmd_write(dev_id, 0x1f, 7, 0x8029, 0x0000); + qca_phy_mmd_write(dev_id, 0x1f, 7, 0x8029, 0x0003); + + /*start traffic*/ + qca_phy_mmd_write(dev_id, 0x1f, 7, 0x8020, 0xa000); + mdelay(200); + for (phy = first_phy_addr; phy < first_phy_addr + 5; phy++) { + u32 tx_counter_ok, tx_counter_error; + u32 rx_counter_ok, rx_counter_error; + u32 tx_counter_ok_high16; + u32 rx_counter_ok_high16; + u32 tx_ok, rx_ok; + /*check counter*/ + tx_counter_ok = qca_phy_mmd_read(dev_id, phy, 7, 0x802e); + tx_counter_ok_high16 = qca_phy_mmd_read(dev_id, phy, 7, 0x802d); + tx_counter_error = qca_phy_mmd_read(dev_id, phy, 7, 0x802f); + rx_counter_ok = qca_phy_mmd_read(dev_id, phy, 7, 0x802b); + rx_counter_ok_high16 = qca_phy_mmd_read(dev_id, phy, 7, 0x802a); + rx_counter_error = qca_phy_mmd_read(dev_id, phy, 7, 0x802c); + tx_ok = tx_counter_ok + (tx_counter_ok_high16<<16); + rx_ok = rx_counter_ok + (rx_counter_ok_high16<<16); + if (tx_ok== 0x3000 && tx_counter_error == 0) { + /*success*/ + phy_t_status &= (~(1<<(phy+8))); + } else { + phy_t_status |= (1<<(phy+8)); + } + + if (enable == A_TRUE) + ssdk_psgmii_all_phy_testing_printf(phy, tx_ok, + rx_ok, + tx_counter_error, rx_counter_error); + } + if (enable == A_TRUE) + SSDK_INFO("PHY final test result: 0x%x \r\n",phy_t_status); + +} + +void ssdk_psgmii_get_first_phy_address(a_uint32_t dev_id, + a_uint32_t *first_phy_addr) +{ + a_uint32_t port_id = 0, phy_addr = 0, phy_cnt = 0; + a_uint32_t port_bmp[SW_MAX_NR_DEV] = {0}; + + port_bmp[dev_id] = qca_ssdk_phy_type_port_bmp_get(dev_id, MALIBU_PHY_CHIP); + + for (port_id = 0; port_id < SW_MAX_NR_PORT; port_id ++) + { + if (port_bmp[dev_id] & (0x1 << port_id)) + { + phy_cnt ++; + phy_addr = qca_ssdk_port_to_phy_addr(dev_id, port_id); + if (phy_addr < *first_phy_addr) { + *first_phy_addr = phy_addr; + } + } + } + if ((phy_cnt == QCA8072_PHY_NUM) && (*first_phy_addr >= 0x3)) { + *first_phy_addr = *first_phy_addr - 3; + } +} + +void ssdk_psgmii_self_test(a_uint32_t dev_id, a_bool_t enable, a_uint32_t times, + a_uint32_t *result) +{ + int i = 0; + u32 value = 0; + a_uint32_t first_phy_addr = MAX_PHY_ADDR + 1, phy = 0; + + ssdk_psgmii_get_first_phy_address(dev_id, &first_phy_addr); + if ((first_phy_addr < 0) || (first_phy_addr > MAX_PHY_ADDR)) { + return; + } + + if (enable == A_FALSE) { + ssdk_malibu_psgmii_and_dakota_dess_reset(dev_id, first_phy_addr); + } + + qca_ar8327_phy_read(dev_id, first_phy_addr + 4, 0x1f, &modectrl_data); + qca_ar8327_phy_write(dev_id, first_phy_addr + 4, 0x1f, 0x8500);/*switch to access MII reg for copper*/ + for(phy = first_phy_addr; phy < first_phy_addr + 5; phy++) { + /*enable phy mdio broadcast write*/ + qca_phy_mmd_write(dev_id, phy, 7, 0x8028, 0x801f); + } + + /* force no link by power down */ + qca_ar8327_phy_write(dev_id, 0x1f, 0x0, 0x1840); + + /*packet number*/ + qca_phy_mmd_write(dev_id, 0x1f, 7, 0x8021, 0x3000); + qca_phy_mmd_write(dev_id, 0x1f, 7, 0x8062, 0x05e0); + + /*fix mdi status */ + qca_ar8327_phy_write(dev_id, 0x1f, 0x10, 0x6800); + + for(i = 0; i < times; i++) { + phy_t_status = 0; + + for(phy = 0; phy < 5; phy++) { + value = readl(qca_phy_priv_global[dev_id]->hw_addr + 0x66c + phy * 0xc); + writel((value|(1<<21)), (qca_phy_priv_global[dev_id]->hw_addr + 0x66c + phy * 0xc)); + } + + for (phy = first_phy_addr; phy < first_phy_addr + 5; phy++) { + ssdk_psgmii_single_phy_testing(dev_id, phy, enable); + } + ssdk_psgmii_all_phy_testing(dev_id, first_phy_addr, enable); + if (enable == A_FALSE) { + if (phy_t_status) { + ssdk_malibu_psgmii_and_dakota_dess_reset(dev_id, first_phy_addr); + } + else + { + break; + } + } + } + + *result = phy_t_status; +#ifdef PSGMII_DEBUG + if (i>=100) + SSDK_ERROR("PSGMII cannot recover\n"); + else + SSDK_INFO("PSGMII recovered after %d times reset\n",i); +#endif + /*configuration recover*/ + /*packet number*/ + qca_phy_mmd_write(dev_id, 0x1f, 7, 0x8021, 0x0); + /*disable check*/ + qca_phy_mmd_write(dev_id, 0x1f, 7, 0x8029, 0x0); + /*disable traffic*/ + qca_phy_mmd_write(dev_id, 0x1f, 7, 0x8020, 0x0); +} + + +void clear_self_test_config(a_uint32_t dev_id) +{ + u32 value = 0; + a_uint32_t first_phy_addr = MAX_PHY_ADDR + 1, phy = 0; + + ssdk_psgmii_get_first_phy_address(dev_id, &first_phy_addr); + if ((first_phy_addr < 0) || (first_phy_addr > MAX_PHY_ADDR)) { + return; + } + + /* disable EEE */ + /* qca_phy_mmd_write(0, 0x1f, 0x7, 0x3c, 0x0); */ + + /*disable phy internal loopback*/ + qca_ar8327_phy_write(dev_id, 0x1f, 0x10, 0x6860); + qca_ar8327_phy_write(dev_id, 0x1f, 0x0, 0x9040); + + for(phy = 0; phy < 5; phy++) + { + /*disable mac loop back*/ + value = readl(qca_phy_priv_global[dev_id]->hw_addr+0x66c+phy*0xc); + writel((value&(~(1<<21))), (qca_phy_priv_global[dev_id]->hw_addr+0x66c+phy*0xc)); + } + + for(phy = first_phy_addr; phy < first_phy_addr + 5; phy++) + { + /*diable phy mdio broadcast write*/ + qca_phy_mmd_write(dev_id, phy, 7, 0x8028, 0x001f); + + } + + qca_ar8327_phy_write(dev_id, first_phy_addr + 4, 0x1f, modectrl_data); + + /* clear fdb entry */ + fal_fdb_entry_flush(dev_id,1); +} +#endif +/*qca808x_start*/ +sw_error_t +ssdk_init(a_uint32_t dev_id, ssdk_init_cfg * cfg) +{ + sw_error_t rv; + + rv = fal_init(dev_id, cfg); + if (rv != SW_OK) + SSDK_ERROR("ssdk fal init failed: %d. \r\n", rv); + + rv = ssdk_phy_driver_init(dev_id, cfg); + if (rv != SW_OK) + SSDK_ERROR("ssdk phy init failed: %d. \r\n", rv); + + return rv; +} + +sw_error_t +ssdk_cleanup(void) +{ + sw_error_t rv; + + rv = fal_cleanup(); + rv = ssdk_phy_driver_cleanup(); + + return rv; +} +/*qca808x_end*/ + +sw_error_t +ssdk_hsl_access_mode_set(a_uint32_t dev_id, hsl_access_mode reg_mode) +{ + sw_error_t rv; + + rv = hsl_access_mode_set(dev_id, reg_mode); + return rv; +} + +void switch_cpuport_setup(a_uint32_t dev_id) +{ +#ifdef IN_PORTCONTROL + //According to HW suggestion, enable CPU port flow control for Dakota + fal_port_flowctrl_forcemode_set(dev_id, 0, A_TRUE); + fal_port_flowctrl_set(dev_id, 0, A_TRUE); + fal_port_duplex_set(dev_id, 0, FAL_FULL_DUPLEX); + fal_port_speed_set(dev_id, 0, FAL_SPEED_1000); + udelay(10); + fal_port_txmac_status_set(dev_id, 0, A_TRUE); + fal_port_rxmac_status_set(dev_id, 0, A_TRUE); +#endif +} +#ifdef IN_AQUANTIA_PHY +#ifdef CONFIG_MDIO +static struct mdio_if_info ssdk_mdio_ctl; +#endif +static struct net_device *ssdk_miireg_netdev = NULL; + +static int ssdk_miireg_open(struct net_device *netdev) +{ + return 0; +} +static int ssdk_miireg_close(struct net_device *netdev) +{ + return 0; +} + +static int ssdk_miireg_do_ioctl(struct net_device *netdev, + struct ifreq *ifr, int32_t cmd) +{ + int ret = -EINVAL; +#ifdef CONFIG_MDIO + struct mii_ioctl_data *mii_data = if_mii(ifr); + ret = mdio_mii_ioctl(&ssdk_mdio_ctl, mii_data, cmd); +#endif + return ret; +} + +static const struct net_device_ops ssdk_netdev_ops = { + .ndo_open = &ssdk_miireg_open, + .ndo_stop = &ssdk_miireg_close, + .ndo_do_ioctl = &ssdk_miireg_do_ioctl, +}; + +#ifdef CONFIG_MDIO +extern struct mutex switch_mdio_lock; +static int ssdk_miireg_ioctl_read(struct net_device *netdev, int phy_addr, int mmd, uint16_t addr) +{ + a_uint32_t reg = 0; + a_uint16_t val = 0; + + if (MDIO_DEVAD_NONE == mmd) { + qca_ar8327_phy_read(0, phy_addr, addr, &val); + return (int)val; + } + + reg = MII_ADDR_C45 | mmd << 16 | addr; + mutex_lock(&switch_mdio_lock); + qca_ar8327_phy_read(0, phy_addr, reg, &val); + mutex_unlock(&switch_mdio_lock); + + return (int)val; +} + +static int ssdk_miireg_ioctl_write(struct net_device *netdev, int phy_addr, int mmd, + uint16_t addr, uint16_t value) +{ + a_uint32_t reg = 0; + + if (MDIO_DEVAD_NONE == mmd) { + qca_ar8327_phy_write(0, phy_addr, addr, value); + return 0; + } + + reg = MII_ADDR_C45 | mmd << 16 | addr; + mutex_lock(&switch_mdio_lock); + qca_ar8327_phy_write(0, phy_addr, reg, value); + mutex_unlock(&switch_mdio_lock); + + return 0; +} +#endif + +static void ssdk_netdev_setup(struct net_device *dev) +{ + dev->netdev_ops = &ssdk_netdev_ops; +} +static void ssdk_miireg_ioctrl_register(void) +{ + if (ssdk_miireg_netdev) + return; +#ifdef CONFIG_MDIO + ssdk_mdio_ctl.mdio_read = ssdk_miireg_ioctl_read; + ssdk_mdio_ctl.mdio_write = ssdk_miireg_ioctl_write; + ssdk_mdio_ctl.mode_support = MDIO_SUPPORTS_C45; +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + ssdk_miireg_netdev = alloc_netdev(100, "miireg", 0, ssdk_netdev_setup); +#else + ssdk_miireg_netdev = alloc_netdev(100, "miireg", ssdk_netdev_setup); +#endif + if (ssdk_miireg_netdev) + register_netdev(ssdk_miireg_netdev); +} + +static void ssdk_miireg_ioctrl_unregister(void) +{ + if (ssdk_miireg_netdev) { + unregister_netdev(ssdk_miireg_netdev); + kfree(ssdk_miireg_netdev); + ssdk_miireg_netdev = NULL; + } +} +#endif +static void ssdk_driver_register(a_uint32_t dev_id) +{ + hsl_reg_mode reg_mode; + a_bool_t flag; + + reg_mode = ssdk_switch_reg_access_mode_get(dev_id); + + if(reg_mode == HSL_REG_LOCAL_BUS) { +#ifndef BOARD_AR71XX +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) + platform_driver_register(&ssdk_driver); +#endif +#endif + } + + flag = ssdk_ess_switch_flag_get(dev_id); + if(reg_mode == HSL_REG_MDIO && flag == A_FALSE) { + if(driver_find(qca_phy_driver.name, &mdio_bus_type)){ + SSDK_ERROR("QCA PHY driver had been Registered\n"); + return; + } + + SSDK_INFO("Register QCA PHY driver\n"); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,9,0)) + phy_driver_register(&qca_phy_driver, THIS_MODULE); +#else + phy_driver_register(&qca_phy_driver); +#endif + +#ifdef BOARD_AR71XX +#if defined(IN_SWCONFIG) + ssdk_uci_takeover_init(); +#endif + +#ifdef CONFIG_AR8216_PHY + ar8327_port_link_notify_register(ssdk_port_link_notify); +#endif + ar7240_port_link_notify_register(ssdk_port_link_notify); +#endif + } +} + +static void ssdk_driver_unregister(a_uint32_t dev_id) +{ + hsl_reg_mode reg_mode; + a_bool_t flag; + + reg_mode= ssdk_switch_reg_access_mode_get(dev_id); + flag = ssdk_ess_switch_flag_get(dev_id); + if(reg_mode == HSL_REG_MDIO && flag == A_FALSE) { + phy_driver_unregister(&qca_phy_driver); + +#if defined(BOARD_AR71XX) && defined(IN_SWCONFIG) + ssdk_uci_takeover_exit(); +#endif + } + + if (reg_mode == HSL_REG_LOCAL_BUS) { +#ifndef BOARD_AR71XX +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) + platform_driver_unregister(&ssdk_driver); +#endif +#endif + } +} +/*qca808x_start*/ +static int chip_is_scomphy(a_uint32_t dev_id, ssdk_init_cfg* cfg) +{ + int rv = -ENODEV; + a_uint32_t phy_id = 0, port_id = 0; + a_uint32_t port_bmp = qca_ssdk_port_bmp_get(dev_id); + while (port_bmp) { + if (port_bmp & 0x1) { + phy_id = hsl_phyid_get(dev_id, port_id, cfg); + switch (phy_id) { +/*qca808x_end*/ + case QCA8030_PHY: + case QCA8033_PHY: + case QCA8035_PHY: + case MP_GEPHY: +/*qca808x_start*/ + case QCA8081_PHY_V1_1: + cfg->chip_type = CHIP_SCOMPHY; + /*MP GEPHY is always the first port*/ + if(cfg->phy_id == 0) + { + cfg->phy_id = phy_id; + } + rv = SW_OK; + break; + default: + break; + } + } + port_bmp >>= 1; + port_id++; + } + + return rv; +} + +static int chip_ver_get(a_uint32_t dev_id, ssdk_init_cfg* cfg) +{ + int rv = SW_OK; + a_uint8_t chip_ver = 0; + a_uint8_t chip_revision = 0; +/*qca808x_end*/ + hsl_reg_mode reg_mode; + + reg_mode= ssdk_switch_reg_access_mode_get(dev_id); + if(reg_mode == HSL_REG_MDIO) + { + chip_ver = (qca_ar8216_mii_read(dev_id, 0)&0xff00)>>8; + } + else { + a_uint32_t reg_val = 0; + qca_switch_reg_read(dev_id,0,(a_uint8_t *)®_val, 4); + chip_ver = (reg_val&0xff00)>>8; + chip_revision = reg_val&0xff; + } +/*qca808x_start*/ + if(chip_ver == QCA_VER_AR8227) + cfg->chip_type = CHIP_SHIVA; + else if(chip_ver == QCA_VER_AR8337) + cfg->chip_type = CHIP_ISISC; + else if(chip_ver == QCA_VER_AR8327) + cfg->chip_type = CHIP_ISIS; + else if(chip_ver == QCA_VER_DESS) + cfg->chip_type = CHIP_DESS; + else if(chip_ver == QCA_VER_HPPE) { + cfg->chip_type = CHIP_HPPE; + cfg->chip_revision = chip_revision; + } + else { + /* try single phy without switch connected */ + rv = chip_is_scomphy(dev_id, cfg); + } + + return rv; +} +/*qca808x_end*/ + +#ifdef DESS +static int ssdk_flow_default_act_init(a_uint32_t dev_id) +{ + a_uint32_t vrf_id = 0; + fal_flow_type_t type = 0; + for(vrf_id = FAL_MIN_VRF_ID; vrf_id <= FAL_MAX_VRF_ID; vrf_id++) + { + for(type = FAL_FLOW_LAN_TO_LAN; type <= FAL_FLOW_WAN_TO_WAN; type++) + { +#ifdef IN_IP +#ifndef IN_IP_MINI + fal_default_flow_cmd_set(dev_id, vrf_id, type, FAL_DEFAULT_FLOW_ADMIT_ALL); +#endif +#endif + } + } + + return 0; +} +static int ssdk_dess_mac_mode_init(a_uint32_t dev_id, a_uint32_t mac_mode) +{ + a_uint32_t reg_value; + u8 __iomem *gcc_addr = NULL; + + switch(mac_mode) { + case PORT_WRAPPER_PSGMII: + case PORT_WRAPPER_PSGMII_FIBER: + reg_value = 0x2200; + qca_psgmii_reg_write(dev_id, DESS_PSGMII_MODE_CONTROL, + (a_uint8_t *)®_value, 4); + reg_value = 0x8380; + qca_psgmii_reg_write(dev_id, DESS_PSGMIIPHY_TX_CONTROL, + (a_uint8_t *)®_value, 4); + break; + case PORT_WRAPPER_SGMII0_RGMII5: + case PORT_WRAPPER_SGMII1_RGMII5: + case PORT_WRAPPER_SGMII0_RGMII4: + case PORT_WRAPPER_SGMII1_RGMII4: + case PORT_WRAPPER_SGMII4_RGMII4: + + /*config sgmii */ + if ((mac_mode == PORT_WRAPPER_SGMII0_RGMII5) + ||(mac_mode == PORT_WRAPPER_SGMII0_RGMII4)) { + /*PSGMII channnel 0 as SGMII*/ + reg_value = 0x2001; + fal_psgmii_reg_set(dev_id, 0x1b4, + (a_uint8_t *)®_value, 4); + udelay(1000); + } + if ((mac_mode == PORT_WRAPPER_SGMII1_RGMII5) + ||(mac_mode == PORT_WRAPPER_SGMII1_RGMII4)) { + /*PSGMII channnel 1 as SGMII*/ + reg_value = 0x2003; + fal_psgmii_reg_set(dev_id, 0x1b4, + (a_uint8_t *)®_value, 4); + udelay(1000); + } + if ((mac_mode == PORT_WRAPPER_SGMII4_RGMII4)) { + /*PSGMII channnel 4 as SGMII*/ + reg_value = 0x2005; + fal_psgmii_reg_set(dev_id, 0x1b4, + (a_uint8_t *)®_value, 4); + udelay(1000); + } + + /*clock gen 1*/ + reg_value = 0xea6; + fal_psgmii_reg_set(dev_id, 0x13c, + (a_uint8_t *)®_value, 4); + mdelay(10); + /*softreset psgmii, fixme*/ + gcc_addr = ioremap_nocache(0x1812000, 0x200); + if (!gcc_addr) { + SSDK_ERROR("gcc map fail!\n"); + return 0; + } else { + SSDK_INFO("gcc map success!\n"); + writel(0x20, gcc_addr+0xc); + mdelay(10); + writel(0x0, gcc_addr+0xc); + mdelay(10); + iounmap(gcc_addr); + } + /*relock pll*/ + reg_value = 0x2803; + fal_psgmii_reg_set(dev_id, DESS_PSGMII_PLL_VCO_RELATED_CONTROL_1, + (a_uint8_t *)®_value, 4); + udelay(1000); + reg_value = 0x4ADA; + fal_psgmii_reg_set(dev_id, DESS_PSGMII_VCO_CALIBRATION_CONTROL_1, + (a_uint8_t *)®_value, 4); + udelay(1000); + reg_value = 0xADA; + fal_psgmii_reg_set(dev_id, DESS_PSGMII_VCO_CALIBRATION_CONTROL_1, + (a_uint8_t *)®_value, 4); + udelay(1000); + + /* Reconfig channel 0 as SGMII and re autoneg*/ + if ((mac_mode == PORT_WRAPPER_SGMII0_RGMII5) + ||(mac_mode == PORT_WRAPPER_SGMII0_RGMII4)) { + /*PSGMII channnel 0 as SGMII*/ + reg_value = 0x2001; + fal_psgmii_reg_set(dev_id, 0x1b4, + (a_uint8_t *)®_value, 4); + udelay(1000); + /* restart channel 0 autoneg*/ + reg_value = 0xc4; + fal_psgmii_reg_set(dev_id, 0x1c8, + (a_uint8_t *)®_value, 4); + mdelay(10); + reg_value = 0x44; + fal_psgmii_reg_set(dev_id, 0x1c8, + (a_uint8_t *)®_value, 4); + mdelay(10); + } + /* Reconfig channel 1 as SGMII and re autoneg*/ + if ((mac_mode == PORT_WRAPPER_SGMII1_RGMII5) + ||(mac_mode == PORT_WRAPPER_SGMII1_RGMII4)) { + + /*PSGMII channnel 1 as SGMII*/ + reg_value = 0x2003; + fal_psgmii_reg_set(dev_id, 0x1b4, + (a_uint8_t *)®_value, 4); + udelay(1000); + /* restart channel 1 autoneg*/ + reg_value = 0xc4; + fal_psgmii_reg_set(dev_id, 0x1e0, + (a_uint8_t *)®_value, 4); + mdelay(10); + reg_value = 0x44; + fal_psgmii_reg_set(dev_id, 0x1e0, + (a_uint8_t *)®_value, 4); + mdelay(10); + + } + /* Reconfig channel 4 as SGMII and re autoneg*/ + if ((mac_mode == PORT_WRAPPER_SGMII4_RGMII4)) { + /*PSGMII channnel 4 as SGMII*/ + reg_value = 0x2005; + fal_psgmii_reg_set(dev_id, 0x1b4, + (a_uint8_t *)®_value, 4); + udelay(1000); + /* restart channel 4 autoneg*/ + reg_value = 0xc4; + fal_psgmii_reg_set(dev_id, 0x228, + (a_uint8_t *)®_value, 4); + mdelay(10); + reg_value = 0x44; + fal_psgmii_reg_set(dev_id, 0x228, + (a_uint8_t *)®_value, 4); + mdelay(10); + } + + /* config RGMII*/ + reg_value = 0x400; + fal_reg_set(dev_id, 0x4, (a_uint8_t *)®_value, 4); + /* config mac5 RGMII*/ + if ((mac_mode == PORT_WRAPPER_SGMII0_RGMII5) + ||(mac_mode == PORT_WRAPPER_SGMII1_RGMII5)) { + qca_ar8327_phy_dbg_write(0, 4, 0x5, 0x2d47); + qca_ar8327_phy_dbg_write(0, 4, 0xb, 0xbc40); + qca_ar8327_phy_dbg_write(0, 4, 0x0, 0x82ee); + reg_value = 0x72; + qca_switch_reg_write(dev_id, 0x90, (a_uint8_t *)®_value, 4); + } + /* config mac4 RGMII*/ + if ((mac_mode == PORT_WRAPPER_SGMII0_RGMII4) + ||(mac_mode == PORT_WRAPPER_SGMII1_RGMII4) + ||(mac_mode == PORT_WRAPPER_SGMII4_RGMII4)) { + qca_ar8327_phy_dbg_write(dev_id, 4, 0x5, 0x2d47); + qca_ar8327_phy_dbg_write(dev_id, 4, 0xb, 0xbc40); + qca_ar8327_phy_dbg_write(dev_id, 4, 0x0, 0x82ee); + reg_value = 0x72; + qca_switch_reg_write(dev_id, 0x8c, (a_uint8_t *)®_value, 4); + } + break; + case PORT_WRAPPER_PSGMII_RMII0_RMII1: + case PORT_WRAPPER_PSGMII_RMII0: + case PORT_WRAPPER_PSGMII_RMII1: + reg_value = 0x2200; + qca_psgmii_reg_write(dev_id, DESS_PSGMII_MODE_CONTROL, + (a_uint8_t *)®_value, 4); + reg_value = 0x8380; + qca_psgmii_reg_write(dev_id, DESS_PSGMIIPHY_TX_CONTROL, + (a_uint8_t *)®_value, 4); + /*switch RMII clock source to gcc_ess_clk,ESS_RGMII_CTRL:0x0C000004,dakota rmii1/rmii0 master mode*/ + if(mac_mode== PORT_WRAPPER_PSGMII_RMII0_RMII1) + reg_value = 0x3000000; + if(mac_mode== PORT_WRAPPER_PSGMII_RMII0) + reg_value = 0x1000000; + if(mac_mode== PORT_WRAPPER_PSGMII_RMII1) + reg_value = 0x2000000; + qca_switch_reg_write(dev_id, 0x4, (a_uint8_t *)®_value, 4); + /*enable RMII MAC5 100M/full*/ + if(mac_mode == PORT_WRAPPER_PSGMII_RMII0_RMII1 || mac_mode == PORT_WRAPPER_PSGMII_RMII0) + { + reg_value = 0x7d; + qca_switch_reg_write(dev_id, 0x90, (a_uint8_t *)®_value, 4); + } + + /*enable RMII MAC4 100M/full*/ + if(mac_mode == PORT_WRAPPER_PSGMII_RMII0_RMII1 || mac_mode == PORT_WRAPPER_PSGMII_RMII1) + { + reg_value = 0x7d; + qca_switch_reg_write(dev_id, 0x8C, (a_uint8_t *)®_value, 4); + } + /*set QM CONTROL REGISTER FLOW_DROP_CNT as max*/ + reg_value = 0x7f007f; + qca_switch_reg_write(dev_id, 0x808, (a_uint8_t *)®_value, 4); + + /*relock PSGMII PLL*/ + reg_value = 0x2803; + fal_psgmii_reg_set(dev_id, DESS_PSGMII_PLL_VCO_RELATED_CONTROL_1, + (a_uint8_t *)®_value, 4); + udelay(1000); + reg_value = 0x4ADA; + fal_psgmii_reg_set(dev_id, DESS_PSGMII_VCO_CALIBRATION_CONTROL_1, + (a_uint8_t *)®_value, 4); + udelay(1000); + reg_value = 0xADA; + fal_psgmii_reg_set(dev_id, DESS_PSGMII_VCO_CALIBRATION_CONTROL_1, + (a_uint8_t *)®_value, 4); + udelay(1000); + break; + } + + return 0; +} + +#ifdef IN_TRUNK +#define MULTIPLE_WAN_PORT_CNT 2 +#define TRUNK_ID_OF_MULTIPLE_WAN_PORTS 0 + +static a_bool_t +ssdk_dess_multiple_wan_port_check(a_uint32_t dev_id, + a_uint32_t wan_bitmap) +{ + a_uint32_t port_id = SSDK_PHYSICAL_PORT0, wan_ports_cnt = 0; + + for(port_id = SSDK_PHYSICAL_PORT0; port_id < SSDK_MAX_PORT_NUM; + port_id++) + { + if(BIT(port_id) & wan_bitmap) + { + wan_ports_cnt++; + } + } + if(wan_ports_cnt >= MULTIPLE_WAN_PORT_CNT) + { + return A_TRUE; + } + else + { + return A_FALSE; + } +} + +sw_error_t +ssdk_dess_trunk_init(a_uint32_t dev_id, a_uint32_t wan_bitmap) +{ + sw_error_t rv = SW_OK; + + if(ssdk_dess_multiple_wan_port_check(dev_id, wan_bitmap)) + { + rv = fal_trunk_group_set(dev_id, TRUNK_ID_OF_MULTIPLE_WAN_PORTS, + A_TRUE, wan_bitmap); + SW_RTN_ON_ERROR(rv); + } + + return rv; +} +#endif + +static sw_error_t +qca_dess_hw_init(ssdk_init_cfg *cfg, a_uint32_t dev_id) +{ + a_uint32_t reg_value = 0; + hsl_api_t *p_api; + a_uint32_t psgmii_result = 0; + a_uint32_t mac_mode; + + mac_mode = ssdk_dt_global_get_mac_mode(dev_id, 0); + /*Do Malibu self test to fix packet drop issue firstly*/ + if ((mac_mode == PORT_WRAPPER_PSGMII) || + (mac_mode == PORT_WRAPPER_PSGMII_FIBER)) { + ssdk_psgmii_self_test(dev_id, A_FALSE, 100, &psgmii_result); + clear_self_test_config(dev_id); + } else { +#ifndef BOARD_AR71XX + ssdk_ess_reset(); +#endif + } + + qca_switch_init(dev_id); +#ifdef IN_PORTVLAN + ssdk_portvlan_init(dev_id); +#endif + +#ifdef IN_PORTVLAN + fal_port_rxhdr_mode_set(dev_id, 0, FAL_ALL_TYPE_FRAME_EN); +#endif +#ifdef IN_IP +#ifndef IN_IP_MINI + fal_ip_route_status_set(dev_id, A_TRUE); +#endif +#endif + + ssdk_flow_default_act_init(dev_id); + + /*set normal hash and disable nat/napt*/ + qca_switch_reg_read(dev_id, 0x0e38, (a_uint8_t *)®_value, 4); + reg_value = (reg_value|0x1000000|0x8); + reg_value &= ~2; + qca_switch_reg_write(dev_id, 0x0e38, (a_uint8_t *)®_value, 4); +#ifdef IN_IP +#ifndef IN_IP_MINI + fal_ip_vrf_base_addr_set(dev_id, 0, 0); +#endif +#endif + + p_api = hsl_api_ptr_get (dev_id); + if (p_api && p_api->port_flowctrl_thresh_set) + p_api->port_flowctrl_thresh_set(dev_id, 0, SSDK_PORT0_FC_THRESH_ON_DFLT, + SSDK_PORT0_FC_THRESH_OFF_DFLT); + + if (p_api && p_api->ip_glb_lock_time_set) + p_api->ip_glb_lock_time_set(dev_id, FAL_GLB_LOCK_TIME_100US); + + + /*config psgmii,sgmii or rgmii mode for Dakota*/ + ssdk_dess_mac_mode_init(dev_id, cfg->mac_mode); + + /*add BGA Board led contorl*/ + ssdk_dess_led_init(cfg); +#ifdef IN_TRUNK + SW_RTN_ON_ERROR(ssdk_dess_trunk_init(dev_id, cfg->port_cfg.wan_bmp)); +#endif + + return SW_OK; +} +#endif +/*qca808x_start*/ +static void ssdk_cfg_default_init(ssdk_init_cfg *cfg) +{ + memset(cfg, 0, sizeof(ssdk_init_cfg)); + cfg->cpu_mode = HSL_CPU_1; + cfg->nl_prot = 30; + cfg->reg_func.mdio_set = qca_ar8327_phy_write; + cfg->reg_func.mdio_get = qca_ar8327_phy_read; +#if defined(IN_PHY_I2C_MODE) + cfg->reg_func.i2c_set = qca_phy_i2c_write; + cfg->reg_func.i2c_get = qca_phy_i2c_read; +#endif +/*qca808x_end*/ + + cfg->reg_func.header_reg_set = qca_switch_reg_write; + cfg->reg_func.header_reg_get = qca_switch_reg_read; + cfg->reg_func.mii_reg_set = qca_ar8216_mii_write; + cfg->reg_func.mii_reg_get = qca_ar8216_mii_read; +/*qca808x_start*/ +} +/*qca808x_end*/ + +#ifdef IN_RFS +#if defined(CONFIG_RFS_ACCEL) +int ssdk_netdev_rfs_cb( + struct net_device *dev, + __be32 src, __be32 dst, + __be16 sport, __be16 dport, + u8 proto, u16 rxq_index, u32 action) +{ + return ssdk_rfs_ipct_rule_set(src, dst, sport, dport, + proto, rxq_index, action); +} +#endif + +#ifdef DESS +a_bool_t ssdk_intf_search( + a_uint8_t *mac, a_uint16_t vid, + a_uint8_t *ret_index, a_uint8_t *free_index) +{ + a_uint8_t i = 0; + + for (i = 0; i < SSDK_RFS_INTF_MAX; i++) { + if (rfs_intf_tbl[i].vid == 0) + *free_index = i; + if (!memcmp(rfs_intf_tbl[i].macaddr.uc, mac, 6) && + rfs_intf_tbl[i].vid == vid) { + /* find it */ + *ret_index = i; + return A_TRUE; + } + } + + /* Not find the same entry */ + return A_FALSE; +} + +static a_bool_t ssdk_is_raw_dev(struct net_device *dev) +{ + struct device *pdev; + + pdev = dev->dev.parent; + if (!pdev) + return A_FALSE; + + if (!strstr(dev_name(pdev), "edma")) + return A_FALSE; + else + return A_TRUE; +} + +static a_uint16_t ssdk_raw_dev_vid_get(struct net_device *dev) +{ +#ifdef CONFIG_RFS_ACCEL + const struct net_device_ops *ops; + + ops = dev->netdev_ops; + if (!ops || + !ops->ndo_get_default_vlan_tag) { + return 0; + } + return ops->ndo_get_default_vlan_tag(dev); +#else + return 0; +#endif +} + +static a_uint16_t ssdk_netdev_vid_get(struct net_device *dev) +{ + struct net_device *pdev; + a_uint16_t vid = 0; + + if (is_vlan_dev(dev)) { + pdev = vlan_dev_real_dev(dev); + if (!ssdk_is_raw_dev(pdev)) { + SSDK_DEBUG("The device %s is not expected!\n", dev->name); + return 0; + } + vid = vlan_dev_vlan_id(dev); + } else if (ssdk_is_raw_dev(dev)) { + vid = ssdk_raw_dev_vid_get(dev); + } else if (dev->priv_flags & IFF_EBRIDGE) { + /* Do nothing for bridge */ + } else { + SSDK_DEBUG("The device %s is not expected!\n", dev->name); + } + + return vid; +} + +static void ssdk_rfs_intf_add(struct net_device *dev) +{ + a_uint8_t *devmac = NULL; + a_uint16_t vid = 0; + fal_intf_mac_entry_t intf_entry; + sw_error_t rv = 0; + a_uint8_t index0, index1; + + /* get vid */ + vid = ssdk_netdev_vid_get(dev); + if (vid == 0) + return; + + /*get mac*/ + devmac = (a_uint8_t*)(dev->dev_addr); + + if (ssdk_intf_search(devmac, vid, &index0, &index1)) { + /* already exist, ignore */ + return; + } + rfs_intf_tbl[index1].vid = vid; + rfs_intf_tbl[index1].if_idx = dev->ifindex; + memcpy(&rfs_intf_tbl[index1].macaddr, devmac, ETH_ALEN); + + memset(&intf_entry, 0, sizeof(intf_entry)); + intf_entry.ip4_route = 1; + intf_entry.ip6_route = 1; + intf_entry.vid_low = vid; + intf_entry.vid_high = vid; + memcpy(&intf_entry.mac_addr, devmac, 6); + rv = fal_ip_intf_entry_add(0, &intf_entry); + if (rv) { + SSDK_ERROR("Faled to add intf entry, rv=%d\n", rv); + memset(&rfs_intf_tbl[index1], 0, sizeof(ssdk_rfs_intf_t)); + return; + } + + rfs_intf_tbl[index1].hw_idx = intf_entry.entry_id; + +} + +static void ssdk_rfs_intf_del(struct net_device *dev) +{ + a_uint8_t i = 0; + fal_intf_mac_entry_t intf_entry; + sw_error_t rv = 0; + + for (i = 0; i < SSDK_RFS_INTF_MAX; i++) { + if ((rfs_intf_tbl[i].if_idx == dev->ifindex) && + (rfs_intf_tbl[i].vid != 0)) { + intf_entry.entry_id = rfs_intf_tbl[i].hw_idx; + rv = fal_ip_intf_entry_del(0, 1, &intf_entry); + if (rv) { + SSDK_ERROR("Faled to del entry, rv=%d\n", rv); + } else { + memset(&rfs_intf_tbl[i], 0, sizeof(ssdk_rfs_intf_t)); + } + return; + } + } +} + +static int ssdk_inet_event(struct notifier_block *this, unsigned long event, void *ptr) +{ + struct net_device *dev = ((struct in_ifaddr *)ptr)->ifa_dev->dev; + + /* Ignore the wireless dev */ +#ifdef CONFIG_WIRELESS_EXT + if (dev->wireless_handlers) + return NOTIFY_DONE; + else +#endif + if (dev->ieee80211_ptr) + return NOTIFY_DONE; + + switch (event) { + case NETDEV_DOWN: + ssdk_rfs_intf_del(dev); + break; + case NETDEV_UP: + ssdk_rfs_intf_add(dev); + break; + } + return NOTIFY_DONE; +} +#endif +#endif + +//#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) +static int ssdk_dev_event(struct notifier_block *this, unsigned long event, void *ptr) +{ + int rv = 0; + ssdk_init_cfg cfg; +#ifdef MP + a_uint32_t port_id = 0, dev_id = 0; + struct qca_phy_priv *priv = ssdk_phy_priv_data_get(dev_id); + adpt_api_t *p_api = adpt_api_ptr_get(dev_id); +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) + struct net_device *dev = netdev_notifier_info_to_dev(ptr); +#else + struct net_device *dev = (struct net_device *)ptr; +#endif + + ssdk_cfg_default_init(&cfg); + rv = chip_ver_get(0, &cfg); + if (rv) { + SSDK_ERROR("chip verfion get failed\n"); + return NOTIFY_DONE; + } + switch (event) { +#ifdef IN_RFS +#if defined(CONFIG_RFS_ACCEL) + case NETDEV_UP: + if (strstr(dev->name, "eth")) { + if (dev->netdev_ops && dev->netdev_ops->ndo_register_rfs_filter) { + dev->netdev_ops->ndo_register_rfs_filter(dev, + ssdk_netdev_rfs_cb); + } + } + break; +#endif +#endif + case NETDEV_CHANGEMTU: + if(dev->type == ARPHRD_ETHER) { + if (strstr(dev->name, "eth")) { + if (cfg.chip_type == CHIP_DESS || + cfg.chip_type == CHIP_ISIS || + cfg.chip_type == CHIP_ISISC) { +#ifdef IN_MISC + fal_frame_max_size_set(0, + dev->mtu + 18); +#endif + } + } + } + break; +#ifdef MP + case NETDEV_CHANGE: + if ((cfg.chip_type == CHIP_SCOMPHY) && + (cfg.phy_id == MP_GEPHY)) { + if ((p_api == NULL) || (p_api->adpt_port_netdev_notify_set == NULL) + || (priv == NULL)) { + SSDK_ERROR("Failed to get pointer\n"); + return NOTIFY_DONE; + } + if (dev->phydev != NULL) { + int addr; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,9,0)) + addr = dev->phydev->mdio.addr; +#else + addr = dev->phydev->addr; +#endif + port_id = qca_ssdk_phy_addr_to_port(priv->device_id, + addr); + rv = p_api->adpt_port_netdev_notify_set(priv, port_id); + if (rv) { + SSDK_ERROR("netdev change notify failed\n"); + return NOTIFY_DONE; + } + } + } + break; +#endif + } + + return NOTIFY_DONE; +} + +#ifdef DESS +static void qca_dess_rfs_remove(void) +{ + /* ssdk_dt_global->switch_reg_access_mode == HSL_REG_LOCAL_BUS */ + if(qca_dess_rfs_registered){ +#if defined (CONFIG_NF_FLOW_COOKIE) +#ifdef IN_NAT +#ifdef IN_SFE + sfe_unregister_flow_cookie_cb(ssdk_flow_cookie_set); +#endif +#endif +#endif +#ifdef IN_RFS + rfs_ess_device_unregister(&rfs_dev); + unregister_inetaddr_notifier(&ssdk_inet_notifier); +#if defined(CONFIG_RFS_ACCEL) +#endif +#endif + qca_dess_rfs_registered = false; + } + +} + +static void qca_dess_rfs_init(void) +{ + if (!qca_dess_rfs_registered) { +#if defined (CONFIG_NF_FLOW_COOKIE) +#ifdef IN_NAT +#ifdef IN_SFE + sfe_register_flow_cookie_cb(ssdk_flow_cookie_set); +#endif +#endif +#endif + +#ifdef IN_RFS + memset(&rfs_dev, 0, sizeof(rfs_dev)); + rfs_dev.name = NULL; +#ifdef IN_FDB + rfs_dev.mac_rule_cb = ssdk_rfs_mac_rule_set; +#endif +#ifdef IN_IP + rfs_dev.ip4_rule_cb = ssdk_rfs_ip4_rule_set; + rfs_dev.ip6_rule_cb = ssdk_rfs_ip6_rule_set; +#endif + rfs_ess_device_register(&rfs_dev); +#if defined(CONFIG_RFS_ACCEL) +#endif + ssdk_inet_notifier.notifier_call = ssdk_inet_event; + ssdk_inet_notifier.priority = 1; + register_inetaddr_notifier(&ssdk_inet_notifier); +#endif + qca_dess_rfs_registered = true; + } +} +#endif +/*qca808x_start*/ +static void ssdk_free_priv(void) +{ + a_uint32_t dev_id, dev_num = 1; + + if(!qca_phy_priv_global) { + return; + } +/*qca808x_end*/ + dev_num = ssdk_switch_device_num_get(); +/*qca808x_start*/ + for (dev_id = 0; dev_id < dev_num; dev_id++) { + if (qca_phy_priv_global[dev_id]) { + kfree(qca_phy_priv_global[dev_id]); + } + + qca_phy_priv_global[dev_id] = NULL; + } + + kfree(qca_phy_priv_global); + + qca_phy_priv_global = NULL; +/*qca808x_end*/ + ssdk_switch_device_num_exit(); +/*qca808x_start*/ +} + +static int ssdk_alloc_priv(a_uint32_t dev_num) +{ + int rev = SW_OK; + a_uint32_t dev_id = 0; + + qca_phy_priv_global = kzalloc(dev_num * sizeof(struct qca_phy_priv *), GFP_KERNEL); + if (qca_phy_priv_global == NULL) { + return -ENOMEM; + } + + for (dev_id = 0; dev_id < dev_num; dev_id++) { + qca_phy_priv_global[dev_id] = kzalloc(sizeof(struct qca_phy_priv), GFP_KERNEL); + if (qca_phy_priv_global[dev_id] == NULL) { + return -ENOMEM; + } +/*qca808x_end*/ + qca_phy_priv_global[dev_id]->qca_ssdk_sw_dev_registered = A_FALSE; + qca_phy_priv_global[dev_id]->ess_switch_flag = A_FALSE; +/*qca808x_start*/ + qca_ssdk_port_bmp_init(dev_id); + qca_ssdk_phy_info_init(dev_id); + } + + return rev; +} + +#ifndef SSDK_STR +#define SSDK_STR "ssdk" +#endif +#if defined (ISISC) || defined (ISIS) +static void qca_ar8327_gpio_reset(struct qca_phy_priv *priv) +{ + struct device_node *np = NULL; + const __be32 *reset_gpio; + a_int32_t len; + int gpio_num = 0, ret = 0; + + if (priv->ess_switch_flag == A_TRUE) + np = priv->of_node; + else +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,9,0)) + np = priv->phy->mdio.dev.of_node; +#else + np = priv->phy->dev.of_node; +#endif + if(!np) + return; + + reset_gpio = of_get_property(np, "reset_gpio", &len); + if (!reset_gpio ) + { + SSDK_INFO("reset_gpio node does not exist\n"); + return; + } + + gpio_num = be32_to_cpup(reset_gpio); + if(gpio_num <= 0) + { + SSDK_INFO("reset gpio doesn't exist\n "); + return; + } + ret = gpio_request(gpio_num, "reset_gpio"); + if(ret) + { + SSDK_ERROR("gpio%d request failed, ret:%d\n", gpio_num, ret); + return; + } + gpio_direction_output(gpio_num, SSDK_GPIO_RESET); + msleep(200); + gpio_set_value(gpio_num, SSDK_GPIO_RELEASE); + SSDK_INFO("GPIO%d reset switch done\n", gpio_num); + + gpio_free(gpio_num); + + return; +} +#endif +static int __init regi_init(void) +{ + a_uint32_t num = 0, dev_id = 0, dev_num = 1; + ssdk_init_cfg cfg; +/*qca808x_end*/ + garuda_init_spec_cfg chip_spec_cfg; +/*qca808x_start*/ + int rv = 0; +/*qca808x_end*/ + /*init switch device num firstly*/ + ssdk_switch_device_num_init(); + + dev_num = ssdk_switch_device_num_get(); +/*qca808x_start*/ + rv = ssdk_alloc_priv(dev_num); + if (rv) + goto out; + + for (num = 0; num < dev_num; num++) { + ssdk_cfg_default_init(&cfg); +/*qca808x_end*/ +#ifndef BOARD_AR71XX +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) + if(SW_DISABLE == ssdk_dt_parse(&cfg, num, &dev_id)) { + SSDK_INFO("ess-switch node is unavalilable\n"); + continue; + } +#endif +#endif + + /* device id is the array index */ + qca_phy_priv_global[dev_id]->device_id = ssdk_device_id_get(dev_id); + qca_phy_priv_global[dev_id]->ess_switch_flag = ssdk_ess_switch_flag_get(dev_id); + qca_phy_priv_global[dev_id]->of_node = ssdk_dts_node_get(dev_id); +/*qca808x_start*/ + rv = ssdk_plat_init(&cfg, dev_id); + SW_CNTU_ON_ERROR_AND_COND1_OR_GOTO_OUT(rv, -ENODEV); +/*qca808x_end*/ + ssdk_driver_register(dev_id); +/*qca808x_start*/ + rv = chip_ver_get(dev_id, &cfg); + SW_CNTU_ON_ERROR_AND_COND1_OR_GOTO_OUT(rv, -ENODEV); +/*qca808x_end*/ +#ifdef IN_AQUANTIA_PHY + ssdk_miireg_ioctrl_register(); +#endif + memset(&chip_spec_cfg, 0, sizeof(garuda_init_spec_cfg)); + cfg.chip_spec_cfg = &chip_spec_cfg; +/*qca808x_start*/ + rv = ssdk_init(dev_id, &cfg); + SW_CNTU_ON_ERROR_AND_COND1_OR_GOTO_OUT(rv, -ENODEV); +/*qca808x_end*/ + + + switch (cfg.chip_type) + { + case CHIP_ISIS: + case CHIP_ISISC: +#if defined (ISISC) || defined (ISIS) + if (qca_phy_priv_global[dev_id]->ess_switch_flag == A_TRUE) { + SSDK_INFO("Initializing ISISC!!\n"); + qca_ar8327_gpio_reset(qca_phy_priv_global[dev_id]); + rv = ssdk_switch_register(dev_id, cfg.chip_type); + SW_CNTU_ON_ERROR_AND_COND1_OR_GOTO_OUT(rv, -ENODEV); + rv = qca_ar8327_hw_init(qca_phy_priv_global[dev_id]); + SSDK_INFO("Initializing ISISC Done!!\n"); + } +#endif + break; + case CHIP_HPPE: +#if defined(HPPE) + SSDK_INFO("Initializing HPPE!!\n"); + qca_hppe_hw_init(&cfg, dev_id); + rv = ssdk_switch_register(dev_id, cfg.chip_type); + SW_CNTU_ON_ERROR_AND_COND1_OR_GOTO_OUT(rv, -ENODEV); + SSDK_INFO("Initializing HPPE Done!!\n"); +#endif + break; + + case CHIP_DESS: +#if defined(DESS) + SSDK_INFO("Initializing DESS!!\n"); + + qca_dess_hw_init(&cfg, dev_id); + qca_dess_rfs_init(); + + /* Setup Cpu port for Dakota platform. */ + switch_cpuport_setup(dev_id); + rv = ssdk_switch_register(dev_id, cfg.chip_type); + SW_CNTU_ON_ERROR_AND_COND1_OR_GOTO_OUT(rv, -ENODEV); + SSDK_INFO("Initializing DESS Done!!\n"); +#endif + break; + + case CHIP_SHIVA: + case CHIP_ATHENA: + case CHIP_GARUDA: + case CHIP_HORUS: + case CHIP_UNSPECIFIED: + break; + case CHIP_SCOMPHY: +#if defined(SCOMPHY) + SSDK_INFO("Initializing SCOMPHY!\n"); + rv = qca_scomphy_hw_init(&cfg, dev_id); + SW_CNTU_ON_ERROR_AND_COND1_OR_GOTO_OUT(rv, -ENODEV); +#if defined(MP) + if(cfg.phy_id == MP_GEPHY) + { + rv = ssdk_switch_register(dev_id, cfg.chip_type); + SW_CNTU_ON_ERROR_AND_COND1_OR_GOTO_OUT(rv, -ENODEV); + } +#endif + SSDK_INFO("Initializing SCOMPHY Done!!\n"); +#endif + break; + } + + fal_module_func_init(dev_id, &cfg); +/*qca808x_start*/ + + } +/*qca808x_end*/ + + ssdk_sysfs_init(); + + if (rv == 0){ + /* register the notifier later should be ok */ + ssdk_dev_notifier.notifier_call = ssdk_dev_event; + ssdk_dev_notifier.priority = 1; + register_netdevice_notifier(&ssdk_dev_notifier); + } +/*qca808x_start*/ + +out: + if (rv == 0) + SSDK_INFO("qca-%s module init succeeded!\n", SSDK_STR); + else { + if (rv == -ENODEV) { + rv = 0; + SSDK_INFO("qca-%s module init, no device found!\n", SSDK_STR); + } else { + SSDK_INFO("qca-%s module init failed! (code: %d)\n", SSDK_STR, rv); + ssdk_free_priv(); + } + } + + return rv; +} + +static void __exit +regi_exit(void) +{ +/*qca808x_end*/ + a_uint32_t dev_id, dev_num = 1; +/*qca808x_start*/ + sw_error_t rv; +/*qca808x_end*/ + dev_num = ssdk_switch_device_num_get(); + for (dev_id = 0; dev_id < dev_num; dev_id++) { + ssdk_driver_unregister(dev_id); +#if defined(DESS) || defined(HPPE) || defined(ISISC) || defined(ISIS) || defined(MP) + if (qca_phy_priv_global[dev_id]->qca_ssdk_sw_dev_registered == A_TRUE) + ssdk_switch_unregister(dev_id); +#endif + } +/*qca808x_start*/ + rv = ssdk_cleanup(); + + if (rv == 0) + SSDK_INFO("qca-%s module exit done!\n", SSDK_STR); + else + SSDK_ERROR("qca-%s module exit failed! (code: %d)\n", SSDK_STR, rv); +/*qca808x_end*/ + +#ifdef DESS + qca_dess_rfs_remove(); +#endif + + ssdk_sysfs_exit(); +#ifdef IN_AQUANTIA_PHY + ssdk_miireg_ioctrl_unregister(); +#endif + for (dev_id = 0; dev_id < dev_num; dev_id++) { + ssdk_plat_exit(dev_id); + } + + unregister_netdevice_notifier(&ssdk_dev_notifier); +/*qca808x_start*/ + ssdk_free_priv(); +} + +module_init(regi_init); +module_exit(regi_exit); + +MODULE_DESCRIPTION("QCA SSDK Driver"); +MODULE_LICENSE("Dual BSD/GPL"); +/*qca808x_end*/ diff --git a/feeds/ipq807x/qca-ssdk/src/src/init/ssdk_interrupt.c b/feeds/ipq807x/qca-ssdk/src/src/init/ssdk_interrupt.c new file mode 100755 index 000000000..0e0bac81c --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/init/ssdk_interrupt.c @@ -0,0 +1,209 @@ +/* + * 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 "fal_init.h" +#include "fal_reg_access.h" +#include "sw.h" +#include "ssdk_init.h" +#include "fal_init.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(ISIS) +#include +#elif defined(ISISC) +#include +#else +#include +#endif +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0)) +#include +#elif defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) +#include +#include +#include +#include +#else +#include +#endif +#include "ssdk_plat.h" +#include "ref_port_ctrl.h" + +#define LINK_CHANGE_INTR 0x8000 +/*phy interrupt enable and status register*/ +#define INTERRUPT_ENABLE_REGISTER 0X12 +#define INTERRUPT_STATUS_REGISTER 0X13 + +extern void qca_ar8327_sw_mac_polling_task(struct qca_phy_priv *priv); + +static int qca_phy_disable_intr(struct qca_phy_priv *priv) +{ + a_uint32_t phy_number = 0; + a_uint16_t value; + + for(phy_number = 0; phy_number < 5; phy_number++) + { + value = 0; + priv->phy_write(priv->device_id, phy_number, INTERRUPT_ENABLE_REGISTER, value); + priv->phy_read(priv->device_id, phy_number, INTERRUPT_STATUS_REGISTER, &value); + } + + return 0; +} + +static int qca_mac_disable_intr(struct qca_phy_priv *priv) +{ + a_uint32_t data; + + fal_reg_get(priv->device_id, GBL_INT_MASK1_OFFSET, (a_uint8_t *)&data, 4); + if (data ) + { + data = 0; + fal_reg_set(priv->device_id, GBL_INT_MASK1_OFFSET,(a_uint8_t *)&data, 4); + } + /*fal_reg_get(0, 0x20, (a_uint8_t *)&data, 4); + if (data ) + { + data = 0; + fal_reg_set(0, 0x20,(a_uint8_t *)&data, 4); + } + + fal_reg_get(0, 0x28, (a_uint8_t *)&data, 4); + fal_reg_set(0, 0x28,(a_uint8_t *)&data, 4); + */ + + fal_reg_get(priv->device_id, GBL_INT_STATUS1_OFFSET, (a_uint8_t *)&data, 4); + fal_reg_set(priv->device_id, GBL_INT_STATUS1_OFFSET,(a_uint8_t *)&data, 4); + + return 0; +} + +static int qca_phy_enable_intr(struct qca_phy_priv *priv) +{ + a_uint16_t value = 0; + a_uint32_t phy_number; + + for(phy_number = 0; phy_number < 5; phy_number++) + { + priv->phy_read(priv->device_id, phy_number, INTERRUPT_STATUS_REGISTER, &value); + /*enable link change intr*/ + if( !priv->link_polling_required) + value = 0xc00; + priv->phy_write(priv->device_id,phy_number, INTERRUPT_ENABLE_REGISTER, value); + } + + return 0; +} + +int qca_mac_enable_intr(struct qca_phy_priv *priv) +{ + a_uint32_t data = 0; + + /*enable link change intr*/ + if( !priv->link_polling_required) + data = 0x8000; + fal_reg_set(priv->device_id, GBL_INT_MASK1_OFFSET, (a_uint8_t *)&data, 4); + + return 0; +} +static int qca_phy_clean_intr(struct qca_phy_priv *priv) +{ + a_uint32_t phy_number; + a_uint16_t value; + + for(phy_number = 0; phy_number < 5; phy_number++) + priv->phy_read(priv->device_id, phy_number, INTERRUPT_STATUS_REGISTER, &value); + + return 0; +} + +static int qca_mac_clean_intr(struct qca_phy_priv *priv) +{ + a_uint32_t data; + + fal_reg_get(priv->device_id, GBL_INT_STATUS1_OFFSET, (a_uint8_t *) &data, 4); + fal_reg_set(priv->device_id, GBL_INT_STATUS1_OFFSET, (a_uint8_t *)&data, 4); + + return 0; +} + +static void +qca_link_change_task(struct qca_phy_priv *priv) +{ + SSDK_DEBUG("qca_link_change_task is running\n"); + mutex_lock(&priv->qm_lock); + qca_ar8327_sw_mac_polling_task(priv); + mutex_unlock(&priv->qm_lock); +} + +static void +qca_intr_workqueue_task(struct work_struct *work) +{ + a_uint32_t data; + struct qca_phy_priv *priv = container_of(work, struct qca_phy_priv, intr_workqueue); + + fal_reg_get(priv->device_id, GBL_INT_STATUS1_OFFSET, (a_uint8_t*)&data, 4); + qca_phy_clean_intr(priv); + qca_mac_clean_intr(priv); + SSDK_DEBUG("data:%x, priv->version:%x\n", data, priv->version); + switch(priv->version) + { + case QCA_VER_DESS: + qca_link_change_task(priv); + break; + default: + if((data &LINK_CHANGE_INTR)) + qca_link_change_task(priv); + break; + } + enable_irq(priv->link_interrupt_no); +} + + static irqreturn_t qca_link_intr_handle(int irq, void *phy_priv) + { + struct qca_phy_priv *priv = (struct qca_phy_priv *)phy_priv; + + disable_irq_nosync(irq); + schedule_work(&priv->intr_workqueue); + SSDK_DEBUG("irq number is :%x\n",irq); + + return IRQ_HANDLED; + } + + int qca_intr_init(struct qca_phy_priv *priv) +{ + SSDK_DEBUG("start to init the interrupt!\n"); + mutex_init(&priv->qm_lock); + INIT_WORK(&priv->intr_workqueue, qca_intr_workqueue_task); + qca_phy_disable_intr(priv); + qca_mac_disable_intr(priv); + if(request_irq(priv->link_interrupt_no, qca_link_intr_handle, priv->interrupt_flag, priv->link_intr_name, priv)) + return -1; + qca_phy_enable_intr(priv); + qca_mac_enable_intr(priv); + + return 0; +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/init/ssdk_led.c b/feeds/ipq807x/qca-ssdk/src/src/init/ssdk_led.c new file mode 100644 index 000000000..c5dcd08ef --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/init/ssdk_led.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2012, 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 "sw.h" +#include "ssdk_init.h" +#include "ssdk_led.h" +#include +#include +#include +#include "ssdk_plat.h" + +#if defined(CONFIG_OF) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0)) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,5,0)) +#include +#endif +#else +#include +#endif +#endif + + +#ifdef DESS +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,5,0)) +static int ssdk_dess_led_source_select(int led_num, enum led_source src_type) +{ +#if defined(CONFIG_OF) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0)) + ipq_led_source_select(led_num, src_type); +#else + ipq40xx_led_source_select(led_num, src_type); +#endif +#endif + return 0; +} +#endif + +int ssdk_dess_led_init(ssdk_init_cfg *cfg) +{ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,5,0)) + a_uint32_t i,led_num, led_source_id,source_id; + led_ctrl_pattern_t pattern; + + if(cfg->led_source_num != 0) { + for (i = 0; i < cfg->led_source_num; i++) { + + led_source_id = cfg->led_source_cfg[i].led_source_id; + pattern.mode = cfg->led_source_cfg[i].led_pattern.mode; + pattern.map = cfg->led_source_cfg[i].led_pattern.map; + pattern.freq = cfg->led_source_cfg[i].led_pattern.freq; +#ifdef IN_LED + fal_led_source_pattern_set(0, led_source_id,&pattern); +#endif + led_num = ((led_source_id -1) /3) + 3; + source_id = led_source_id % 3; + if (source_id == SRC_SELECTION_1) { + if (led_source_id == LED_SRC_ID_1) { + ssdk_dess_led_source_select(led_num, + LAN0_1000_LNK_ACTIVITY); + } + if (led_source_id == LED_SRC_ID_4) { + ssdk_dess_led_source_select(led_num, + LAN1_1000_LNK_ACTIVITY); + } + if (led_source_id == LED_SRC_ID_7) { + ssdk_dess_led_source_select(led_num, + LAN2_1000_LNK_ACTIVITY); + } + if (led_source_id == LED_SRC_ID_10) { + ssdk_dess_led_source_select(led_num, + LAN3_1000_LNK_ACTIVITY); + } + if (led_source_id == LED_SRC_ID_13) { + ssdk_dess_led_source_select(led_num, + WAN_1000_LNK_ACTIVITY); + } + } + if (source_id == SRC_SELECTION_2) { + if (led_source_id == LED_SRC_ID_2) { + ssdk_dess_led_source_select(led_num, + LAN0_100_LNK_ACTIVITY); + } + if (led_source_id == LED_SRC_ID_5) { + ssdk_dess_led_source_select(led_num, + LAN1_100_LNK_ACTIVITY); + } + if (led_source_id == LED_SRC_ID_8) { + ssdk_dess_led_source_select(led_num, + LAN2_100_LNK_ACTIVITY); + } + if (led_source_id == LED_SRC_ID_11) { + ssdk_dess_led_source_select(led_num, + LAN3_100_LNK_ACTIVITY); + } + if (led_source_id == LED_SRC_ID_14) { + ssdk_dess_led_source_select(led_num, + WAN_100_LNK_ACTIVITY); + } + } + if (source_id == SRC_SELECTION_0) { + if (led_source_id == LED_SRC_ID_3) { + ssdk_dess_led_source_select(led_num, + LAN0_10_LNK_ACTIVITY); + } + if (led_source_id == LED_SRC_ID_6) { + ssdk_dess_led_source_select(led_num, + LAN1_10_LNK_ACTIVITY); + } + if (led_source_id == LED_SRC_ID_9) { + ssdk_dess_led_source_select(led_num, + LAN2_10_LNK_ACTIVITY); + } + if (led_source_id == LED_SRC_ID_12) { + ssdk_dess_led_source_select(led_num, + LAN3_10_LNK_ACTIVITY); + } + if (led_source_id == LED_SRC_ID_15) { + ssdk_dess_led_source_select(led_num, + WAN_10_LNK_ACTIVITY); + } + } + } + } +#endif + return 0; +} +#endif + +#ifdef IN_LED +sw_error_t ssdk_led_init(a_uint32_t dev_id, ssdk_init_cfg *cfg) +{ + a_uint32_t src_index = 0, led_src_id = 0; + sw_error_t rv = SW_OK; + led_ctrl_pattern_t pattern = {0}; + + for(src_index = 0; src_index < cfg->led_source_num; src_index++) + { + pattern.mode = cfg->led_source_cfg[src_index].led_pattern.mode; + pattern.map = cfg->led_source_cfg[src_index].led_pattern.map; + led_src_id = cfg->led_source_cfg[src_index].led_source_id; + SSDK_INFO("ssdk_led_mode:%x, ssdk_led_map:%x, ssdk_led_src_id:%x\n", + pattern.mode, pattern.map, led_src_id); + rv = fal_led_source_pattern_set(dev_id, led_src_id, &pattern); + SW_RTN_ON_ERROR(rv); + } + + return SW_OK; +} +#endif diff --git a/feeds/ipq807x/qca-ssdk/src/src/init/ssdk_mp.c b/feeds/ipq807x/qca-ssdk/src/src/init/ssdk_mp.c new file mode 100644 index 000000000..9e96b4e42 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/init/ssdk_mp.c @@ -0,0 +1,117 @@ +/* + * 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 "ssdk_init.h" +#include "ssdk_plat.h" +#include "ssdk_dts.h" +#include "ssdk_mp.h" +#include "adpt.h" +#include "ssdk_led.h" + +#ifdef IN_PORTCONTROL +sw_error_t +qca_mp_portctrl_hw_init(a_uint32_t dev_id) +{ + sw_error_t rv = SW_OK; + a_uint32_t i = 0; + fal_port_eee_cfg_t port_eee_cfg; + a_bool_t force_port; + + memset(&port_eee_cfg, 0, sizeof(fal_port_eee_cfg_t)); + + for (i = SSDK_PHYSICAL_PORT1; i <= SSDK_PHYSICAL_PORT2; i++) { + force_port = ssdk_port_feature_get(dev_id, i, + PHY_F_FORCE); + if (force_port == A_FALSE) { + fal_port_txmac_status_set (dev_id, i, A_FALSE); + fal_port_rxmac_status_set (dev_id, i, A_FALSE); + /* init mac's lpi wake up timer to 70us */ + port_eee_cfg.lpi_wakeup_timer = MP_LPI_WAKEUP_TIMER; + fal_port_interface_eee_cfg_set(dev_id, i, &port_eee_cfg); + } else { + fal_port_txmac_status_set (dev_id, i, A_TRUE); + fal_port_rxmac_status_set (dev_id, i, A_TRUE); + } + fal_port_rxfc_status_set(dev_id, i, A_FALSE); + fal_port_txfc_status_set(dev_id, i, A_FALSE); + fal_port_max_frame_size_set(dev_id, i, + FAL_DEFAULT_MAX_FRAME_SIZE); + fal_port_promisc_mode_set(dev_id, i, A_TRUE); + /* init software level port status */ + qca_mac_port_status_init(dev_id, i); + } + return rv; +} +#endif +sw_error_t +qca_mp_interface_mode_init(a_uint32_t dev_id) +{ + sw_error_t rv = SW_OK; + adpt_api_t *p_api; + a_uint32_t i = 0, mode = 0; + a_bool_t force_port; + a_uint32_t force_speed = 0; + + SW_RTN_ON_NULL(p_api = adpt_api_ptr_get(dev_id)); + SW_RTN_ON_NULL(p_api->adpt_uniphy_mode_set); + SW_RTN_ON_NULL(p_api->adpt_port_mac_speed_set); + SW_RTN_ON_NULL(p_api->adpt_port_mac_duplex_set); + + mode = ssdk_dt_global_get_mac_mode(dev_id, SSDK_UNIPHY_INSTANCE0); + + rv = p_api->adpt_uniphy_mode_set(dev_id, SSDK_UNIPHY_INSTANCE0, + mode); + SW_RTN_ON_ERROR(rv); + + for (i = SSDK_PHYSICAL_PORT1; i <= SSDK_PHYSICAL_PORT2; i++) { + force_port = ssdk_port_feature_get(dev_id, i, PHY_F_FORCE); + if (force_port == A_TRUE) { + force_speed = ssdk_port_force_speed_get(dev_id, i); + rv = p_api->adpt_port_mac_speed_set(dev_id, + i, force_speed); + } else { + rv = p_api->adpt_port_mac_speed_set(dev_id, + i, FAL_SPEED_1000); + } + SW_RTN_ON_ERROR(rv); + rv = p_api->adpt_port_mac_duplex_set(dev_id, i, FAL_FULL_DUPLEX); + SW_RTN_ON_ERROR(rv); + } + + return rv; +} + +sw_error_t +qca_mp_hw_init(a_uint32_t dev_id, ssdk_init_cfg *cfg) +{ + sw_error_t rv = SW_OK; + +#ifdef IN_PORTCONTROL + rv = qca_mp_portctrl_hw_init(dev_id); + SW_RTN_ON_ERROR(rv); +#endif +#ifdef IN_MIB + rv = fal_mib_cpukeep_set(dev_id, A_FALSE); + SW_RTN_ON_ERROR(rv); +#endif + rv = qca_mp_interface_mode_init(dev_id); + SW_RTN_ON_ERROR(rv) +#ifdef IN_LED + /*init MP led*/ + rv = ssdk_led_init(dev_id, cfg); +#endif + return rv; +} diff --git a/feeds/ipq807x/qca-ssdk/src/src/init/ssdk_phy_i2c.c b/feeds/ipq807x/qca-ssdk/src/src/init/ssdk_phy_i2c.c new file mode 100755 index 000000000..8d9c5ff30 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/init/ssdk_phy_i2c.c @@ -0,0 +1,462 @@ +/* + * 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. + */ +/*qca808x_start*/ +#include "sw.h" +#include "ssdk_phy_i2c.h" +#include +#include "ssdk_init.h" +#include "ssdk_plat.h" + +#define I2C_RW_LIMIT 8 +#define I2C_ADAPTER_DEFAULT_ID 0 + +/****************************************************************************** +* +* _qca_i2c_read - read data per i2c bus +* +* read data per i2c bus +*/ +static inline a_int16_t +_qca_i2c_read(a_uint32_t i2c_bus_id, a_uint32_t i2c_slave, + a_uint32_t data_addr, a_uint8_t *buf, a_uint32_t count) +{ + a_int16_t ret, i; + struct i2c_adapter *adapt; + a_uint8_t addrbuf[2]; + struct i2c_msg msg[2]; + + ret =0; + i = 0; + + if (data_addr & 0xff00) { + addrbuf[i++] = (data_addr >> 8) & 0xff; + } + + addrbuf[i++] = data_addr & 0xff; + + if (count > I2C_RW_LIMIT) { + count = I2C_RW_LIMIT; + } + + /* + * msg for configuring the address + */ + aos_mem_set(msg, 0, sizeof(msg)); + msg[0].addr = i2c_slave; + msg[0].len = i; + msg[0].buf = addrbuf; + + /* + * msg for acquiring data + */ + msg[1].addr = i2c_slave; + msg[1].flags = I2C_M_RD; + msg[1].len = count; + msg[1].buf = buf; + + adapt = i2c_get_adapter(i2c_bus_id); + if (adapt) { + ret = i2c_transfer(adapt, msg, ARRAY_SIZE(msg)); + i2c_put_adapter(adapt); + } + + if (ret == ARRAY_SIZE(msg)) { + return count; + } + + return ret; +} + +/****************************************************************************** +* +* qca_i2c_data_get - wrapper of reading data per i2c bus +* +* wrapper of reading data per i2c bus +*/ +sw_error_t +qca_i2c_data_get(a_uint32_t dev_id, a_uint32_t i2c_slave, + a_uint32_t data_addr, a_uint8_t *buf, a_uint32_t count) +{ + a_int16_t ret = 0, cur = 0; + a_uint16_t cnt = count; + + while (cnt) { + cur = _qca_i2c_read(I2C_ADAPTER_DEFAULT_ID, + i2c_slave, data_addr, buf, cnt); + + /* No such i2c_slave device */ + if (cur == -ENXIO) { + return SW_NO_RESOURCE; + } + + if (cur <= 0) { + break; + } + /* + * loop to acquire the data from the new + * address based on the returned count. + */ + cnt -= cur; + buf += cur; + data_addr += cur; + ret += cur; + } + + if (ret != count) { + return SW_FAIL; + } + + return SW_OK; +} + +/****************************************************************************** +* +* _qca_i2c_write - write data per i2c bus +* +* write data per i2c bus +*/ +static inline a_int16_t +_qca_i2c_write(a_uint32_t i2c_bus_id, a_uint32_t i2c_slave, + a_uint32_t data_addr, a_uint8_t *buf, a_uint32_t count) +{ + a_int16_t ret, i; + struct i2c_adapter *adapt; + struct i2c_msg msg; + a_uint8_t i2c_wbuf[I2C_RW_LIMIT+2]; + + ret = 0; + i = 0; + + if (data_addr & 0xff00) { + i2c_wbuf[i++] = (data_addr >> 8) & 0xff; + } + + /* + * the write buffer is for saving address + * and the data to sent. + */ + i2c_wbuf[i++] = data_addr & 0xff; + + if (count > I2C_RW_LIMIT) { + count = I2C_RW_LIMIT; + } + memcpy(&i2c_wbuf[i], buf, count); + + aos_mem_set(&msg, 0, sizeof(msg)); + msg.addr = i2c_slave; + msg.len = i + count; + msg.buf = i2c_wbuf; + + adapt = i2c_get_adapter(i2c_bus_id); + if (adapt) { + ret = i2c_transfer(adapt, &msg, 1); + i2c_put_adapter(adapt); + } + + if (ret == 1) { + return count; + } + + return ret; +} + +/****************************************************************************** +* +* qca_i2c_data_set - wrapper of writting data per i2c bus +* +* wrapper of writting data per i2c bus +*/ +sw_error_t +qca_i2c_data_set(a_uint32_t dev_id, a_uint32_t i2c_slave, + a_uint32_t data_addr, a_uint8_t *buf, a_uint32_t count) +{ + a_int16_t ret = 0, cur = 0; + a_uint16_t cnt = count; + + while (cnt) { + cur = _qca_i2c_write(I2C_ADAPTER_DEFAULT_ID, + i2c_slave, data_addr, buf, cnt); + + /* No such i2c_slave device */ + if (cur == -ENXIO) { + return SW_NO_RESOURCE; + } + + if (cur <= 0) { + break; + } + /* + * loop to write the data to the new + * address based on the returned count. + */ + cnt -= cur; + buf += cur; + data_addr += cur; + ret += cur; + } + + if (ret != count) { + return SW_FAIL; + } + + return SW_OK; +} + +/****************************************************************************** +* +* _qca_phy_i2c_mii_read - mii register i2c read +* +* mii register i2c read +*/ +sw_error_t +qca_phy_i2c_mii_read(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg_addr, a_uint16_t *reg_data) +{ + sw_error_t ret; + a_uint8_t rx[2] = { 0 }; + + reg_addr &= 0xff; + + ret = qca_i2c_data_get(dev_id, phy_addr, + reg_addr, rx, sizeof(rx)); + + if (ret == SW_OK) { + *reg_data = (rx[0] << 8) | rx[1]; + } else { + *reg_data = 0xffff; + } + + return ret; +} + +/****************************************************************************** +* +* _qca_phy_i2c_mii_write - mii register i2c write +* +* mii register i2c write +*/ +sw_error_t +qca_phy_i2c_mii_write(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg_addr, a_uint16_t reg_data) +{ + sw_error_t ret; + a_uint8_t tx[2] = {(reg_data >> 8) & 0xff, reg_data & 0xff}; + + reg_addr &= 0xff; + + ret = qca_i2c_data_set(dev_id, phy_addr, + reg_addr, tx, sizeof(tx)); + + return ret; +} + +#ifdef IN_PHY_I2C_MODE +/****************************************************************************** +* +* _qca_phy_i2c_mmd_read - mmd register i2c read +* +* mmd register i2c read +*/ +sw_error_t +qca_phy_i2c_mmd_read(a_uint32_t dev_id, a_uint32_t phy_addr, a_uint16_t mmd_num, + a_uint32_t reg_addr, a_uint16_t *reg_data) +{ + a_uint8_t ret; + struct i2c_adapter *adapt; + /* + TX buffer to send: + 1st byte: Bit[6](1:MMD 0:MII) Bit[5](1:MMD address 0:MMD data) Bit[4:0](MMD num) + 2nd byte is high 8bits of reg addr + 3rd byte is low 8bits of reg addr + 4th byte: add one extra byte at the end of address writing msg to avoid qca808x + treat it as data writing operation + */ + a_uint8_t tx[4] = { ((QCA_PHY_I2C_IS_MMD << QCA_PHY_I2C_MMD_OR_MII_SHIFT) | + (QCA_PHY_I2C_MMD_IS_ADDR << QCA_PHY_I2C_MMD_ADDR_OR_DATA_SHIFT) | mmd_num), + (reg_addr >> 8) & 0xff, reg_addr & 0xff, 0 }; + /* + RX buffer to receive: + 1st byte is high 8bits of reg data + 2nd byte is low 8bits of reg data + */ + a_uint8_t rx[2] = { 0 }; + struct i2c_msg msg[] = { + { .addr = phy_addr, .flags = 0, + .buf = tx, .len = sizeof(tx) }, + { .addr = phy_addr, .flags = I2C_M_RD, + .buf = rx, .len = sizeof(rx) } }; + + if((mmd_num != QCA_PHY_MMD1_NUM) && (mmd_num != QCA_PHY_MMD3_NUM) && + (mmd_num != QCA_PHY_MMD7_NUM)) { + SSDK_ERROR("wrong MMD number:[%d]\n", mmd_num); + return SW_FAIL; + } + + adapt = i2c_get_adapter(I2C_ADAPTER_DEFAULT_ID); + if (!adapt) { + return SW_FAIL; + } + + ret = i2c_transfer(adapt, msg, ARRAY_SIZE(msg)); + *reg_data = (rx[0] << 8) | rx[1]; + + i2c_put_adapter(adapt); + + if (ret != ARRAY_SIZE(msg)) { + return SW_FAIL; + } + + return SW_OK; +} + +/****************************************************************************** +* +* _qca_phy_i2c_mmd_write - mmd register i2c write +* +* mmd register i2c write +*/ +sw_error_t +qca_phy_i2c_mmd_write(a_uint32_t dev_id, a_uint32_t phy_addr, a_uint16_t mmd_num, + a_uint32_t reg_addr, a_uint16_t reg_data) +{ + a_uint8_t ret; + struct i2c_adapter *adapt; + /* + First TX buffer to send: + 1st byte: Bit[6](1:MMD 0:MII) Bit[5](1:MMD address 0:MMD data) Bit[4:0](MMD num) + 2nd byte is high 8bits of reg addr + 3rd byte is low 8bits of reg addr + 4th byte: add one extra byte at the end of address writing msg to avoid qca808x + treat it as data writing operation + */ + a_uint8_t tx[4] = { ((QCA_PHY_I2C_IS_MMD << QCA_PHY_I2C_MMD_OR_MII_SHIFT) | + (QCA_PHY_I2C_MMD_IS_ADDR << QCA_PHY_I2C_MMD_ADDR_OR_DATA_SHIFT) | mmd_num), + (reg_addr >> 8) & 0xff, reg_addr & 0xff, 0 }; + + /* + Second TX buffer to send: + 1st byte: Bit[6](1:MMD 0:MII) Bit[5](1:MMD address 0:MMD data) Bit[4:0](MMD num) + 2nd byte is high 8bits of reg data + 3rd byte is low 8bits of reg data + */ + a_uint8_t tx2[3] = { ((QCA_PHY_I2C_IS_MMD << QCA_PHY_I2C_MMD_OR_MII_SHIFT) | + (QCA_PHY_I2C_MMD_IS_DATA << QCA_PHY_I2C_MMD_ADDR_OR_DATA_SHIFT) | mmd_num), + (reg_data >> 8) & 0xff, reg_data & 0xff }; + + struct i2c_msg msg[] = { + { .addr = phy_addr, .flags = 0, + .buf = tx, .len = sizeof(tx) }, + { .addr = phy_addr, .flags = 0, + .buf = tx2, .len = sizeof(tx2) } }; + + if((mmd_num != QCA_PHY_MMD1_NUM) && (mmd_num != QCA_PHY_MMD3_NUM) && + (mmd_num != QCA_PHY_MMD7_NUM)) { + SSDK_ERROR("wrong MMD number:[%d]\n", mmd_num); + return SW_FAIL; + } + + adapt = i2c_get_adapter(I2C_ADAPTER_DEFAULT_ID); + if (!adapt) { + return SW_FAIL; + } + + ret = i2c_transfer(adapt, msg, ARRAY_SIZE(msg)); + + i2c_put_adapter(adapt); + + if (ret != ARRAY_SIZE(msg)) { + return SW_FAIL; + } + + return SW_OK; +} + +/****************************************************************************** +* +* qca_phy_is_i2c_addr - check if phy addr is i2c addr +* +* check if phy addr is i2c addr +*/ +a_bool_t +qca_phy_is_i2c_addr(a_uint32_t phy_addr) +{ + if(((phy_addr & QCA_PHY_I2C_DEVADDR_MASK) == + QCA_PHY_I2C_PHYCORE_DEVADDR) || + ((phy_addr & QCA_PHY_I2C_DEVADDR_MASK) == + QCA_PHY_I2C_SERDES_DEVADDR)) { + return A_TRUE; + } else { + return A_FALSE; + } +} + +/****************************************************************************** +* +* qca_phy_i2c_read - PHY register i2c read +* +* PHY register i2c read +*/ +sw_error_t +qca_phy_i2c_read(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg_addr_c45, a_uint16_t *reg_data) +{ + a_uint32_t mmd_num = QCA_PHY_MII_ADDR_C45_MMD_NUM(reg_addr_c45); + a_uint32_t reg_addr = QCA_PHY_MII_ADDR_C45_REG_ADDR(reg_addr_c45); + + if(qca_phy_is_i2c_addr(phy_addr) == A_FALSE) { + return SW_BAD_PARAM; + } + + if(QCA_PHY_MII_ADDR_C45_IS_MMD(reg_addr_c45)) { + qca_phy_i2c_mmd_read(dev_id, phy_addr, mmd_num, reg_addr, reg_data); + + } else { + qca_phy_i2c_mii_read(dev_id, phy_addr, reg_addr, reg_data); + } + + return SW_OK; +} + +/****************************************************************************** +* +* qca_phy_i2c_write - PHY register i2c write +* +* PHY register i2c write +*/ +sw_error_t +qca_phy_i2c_write(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg_addr_c45, a_uint16_t reg_data) +{ + a_uint32_t mmd_num = QCA_PHY_MII_ADDR_C45_MMD_NUM(reg_addr_c45); + a_uint32_t reg_addr = QCA_PHY_MII_ADDR_C45_REG_ADDR(reg_addr_c45); + + if(qca_phy_is_i2c_addr(phy_addr) == A_FALSE) { + return SW_BAD_PARAM; + } + + if(QCA_PHY_MII_ADDR_C45_IS_MMD(reg_addr_c45)) { + qca_phy_i2c_mmd_write(dev_id, phy_addr, mmd_num, reg_addr, reg_data); + + } else { + qca_phy_i2c_mii_write(dev_id, phy_addr, reg_addr, reg_data); + } + + return SW_OK; +} +/*qca808x_end*/ +EXPORT_SYMBOL(qca_phy_i2c_read); +EXPORT_SYMBOL(qca_phy_i2c_write); +/*qca808x_start*/ +#endif +/*qca808x_start*/ diff --git a/feeds/ipq807x/qca-ssdk/src/src/init/ssdk_plat.c b/feeds/ipq807x/qca-ssdk/src/src/init/ssdk_plat.c new file mode 100644 index 000000000..7a6a3b635 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/init/ssdk_plat.c @@ -0,0 +1,1417 @@ +/* + * 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. + */ +/*qca808x_start*/ +#include "sw.h" +#include "ssdk_init.h" +#include "fal_init.h" +#include "fal.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "ssdk_init.h" +/*qca808x_end*/ +#include "ssdk_dts.h" +#if (defined(HPPE) || defined(MP)) +#include "hppe_init.h" +#endif +#include +/*qca808x_start*/ +#include +/*qca808x_end*/ +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(ISIS) ||defined(ISISC) ||defined(GARUDA) +#include +#endif +#if defined(ATHENA) ||defined(SHIVA) ||defined(HORUS) +#include +#endif +#ifdef IN_MALIBU_PHY +#include +#endif +/*qca808x_start*/ +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0)) +#include +#include +#include +#elif defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) +#include +#include +#include +#include +#include +#else +#include +#include +#include +#endif +#include "ssdk_plat.h" +/*qca808x_end*/ +#include "ssdk_clk.h" +#include "ref_vlan.h" +#include "ref_fdb.h" +#include "ref_mib.h" +#include "ref_port_ctrl.h" +#include "ref_misc.h" +#include "ref_uci.h" +#include "shell.h" +#ifdef BOARD_AR71XX +#include "ssdk_uci.h" +#endif + +#include "hsl_phy.h" +#ifdef IN_LINUX_STD_PTP +#include "qca808x_ptp.h" +#endif + +#ifdef IN_IP +#if defined (CONFIG_NF_FLOW_COOKIE) +#include "fal_flowcookie.h" +#ifdef IN_SFE +#include +#endif +#endif +#endif + +#ifdef IN_RFS +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) +#include +#endif +#include +#ifdef IN_IP +#include "fal_rfs.h" +#endif +#endif + +#include "adpt.h" +/*qca808x_start*/ + +extern struct qca_phy_priv **qca_phy_priv_global; +extern ssdk_chip_type SSDK_CURRENT_CHIP_TYPE; +/*qca808x_end*/ +struct mutex switch_mdio_lock; + +#ifdef BOARD_IPQ806X +#define PLATFORM_MDIO_BUS_NAME "mdio-gpio" +#endif + +#ifdef BOARD_AR71XX +#define PLATFORM_MDIO_BUS_NAME "ag71xx-mdio" +#endif +/*qca808x_start*/ +#define MDIO_BUS_0 0 +#define MDIO_BUS_1 1 +/*qca808x_end*/ +#define PLATFORM_MDIO_BUS_NUM MDIO_BUS_0 + +#define ISIS_CHIP_ID 0x18 +#define ISIS_CHIP_REG 0 +#define SHIVA_CHIP_ID 0x1f +#define SHIVA_CHIP_REG 0x10 +#define HIGH_ADDR_DFLT 0x200 + +/* + * Using ISIS's address as default + */ +static int switch_chip_id = ISIS_CHIP_ID; +static int switch_chip_reg = ISIS_CHIP_REG; + +static int ssdk_dev_id = 0; +/*qca808x_start*/ +a_uint32_t ssdk_log_level = SSDK_LOG_LEVEL_DEFAULT; +/*qca808x_end*/ + +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) +struct ag71xx_mdio { + struct mii_bus *mii_bus; + int mii_irq[PHY_MAX_ADDR]; + void __iomem *mdio_base; +}; +#endif + +#ifdef BOARD_AR71XX +static uint32_t switch_chip_id_adjuest(a_uint32_t dev_id) +{ + uint32_t chip_version = 0; + chip_version = (qca_ar8216_mii_read(dev_id, 0)&0xff00)>>8; + if((chip_version !=0) && (chip_version !=0xff)) + return 0; + + switch_chip_id = SHIVA_CHIP_ID; + switch_chip_reg = SHIVA_CHIP_REG; + + chip_version = (qca_ar8216_mii_read(dev_id, 0)&0xff00)>>8; + printk("chip_version:0x%x\n", chip_version); + return 1; +} +#endif + +static inline void +split_addr(uint32_t regaddr, uint16_t *r1, uint16_t *r2, uint16_t *page) +{ + regaddr >>= 1; + *r1 = regaddr & 0x1e; + + regaddr >>= 5; + *r2 = regaddr & 0x7; + + regaddr >>= 3; + *page = regaddr & 0x3ff; +} + +a_uint32_t +qca_ar8216_mii_read(a_uint32_t dev_id, a_uint32_t reg) +{ + struct mii_bus *bus; + uint16_t r1, r2, page; + uint16_t lo, hi; + + bus = qca_phy_priv_global[dev_id]->miibus; + + split_addr((uint32_t) reg, &r1, &r2, &page); + mutex_lock(&switch_mdio_lock); + mdiobus_write(bus, switch_chip_id, switch_chip_reg, page); + udelay(100); + lo = mdiobus_read(bus, 0x10 | r2, r1); + hi = mdiobus_read(bus, 0x10 | r2, r1 + 1); + mdiobus_write(bus, switch_chip_id, switch_chip_reg, HIGH_ADDR_DFLT); + mutex_unlock(&switch_mdio_lock); + return (hi << 16) | lo; +} + +void +qca_ar8216_mii_write(a_uint32_t dev_id, a_uint32_t reg, a_uint32_t val) +{ + struct mii_bus *bus; + uint16_t r1, r2, r3; + uint16_t lo, hi; + + bus = qca_phy_priv_global[dev_id]->miibus; + + split_addr((a_uint32_t) reg, &r1, &r2, &r3); + lo = val & 0xffff; + hi = (a_uint16_t) (val >> 16); + + mutex_lock(&switch_mdio_lock); + mdiobus_write(bus, switch_chip_id, switch_chip_reg, r3); + udelay(100); + if(SSDK_CURRENT_CHIP_TYPE != CHIP_SHIVA) { + mdiobus_write(bus, 0x10 | r2, r1, lo); + mdiobus_write(bus, 0x10 | r2, r1 + 1, hi); + } else { + mdiobus_write(bus, 0x10 | r2, r1 + 1, hi); + mdiobus_write(bus, 0x10 | r2, r1, lo); + } + mdiobus_write(bus, switch_chip_id, switch_chip_reg, HIGH_ADDR_DFLT); + mutex_unlock(&switch_mdio_lock); +} + +/*qca808x_start*/ +a_bool_t +phy_addr_validation_check(a_uint32_t phy_addr) +{ + + if ((phy_addr > SSDK_PHY_BCAST_ID) || (phy_addr < SSDK_PHY_MIN_ID)) + return A_FALSE; + else + return A_TRUE; +} + +static struct mii_bus * +ssdk_phy_miibus_get(a_uint32_t dev_id, a_uint32_t phy_addr) +{ + struct mii_bus *bus = NULL; +/*qca808x_end*/ +#ifndef BOARD_AR71XX +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) + bus = ssdk_dts_miibus_get(dev_id, phy_addr); +#endif +#endif +/*qca808x_start*/ + if (!bus) + bus = qca_phy_priv_global[dev_id]->miibus; + + return bus; +} + +sw_error_t +qca_ar8327_phy_read(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t* data) +{ + struct mii_bus *bus = NULL; + + if (A_TRUE != phy_addr_validation_check (phy_addr)) + { + return SW_BAD_PARAM; + } + + bus = ssdk_phy_miibus_get(dev_id, phy_addr); + if (!bus) + return SW_NOT_SUPPORTED; + + *data = mdiobus_read(bus, phy_addr, reg); + return 0; +} + +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) +{ + struct mii_bus *bus = NULL; + + if (A_TRUE != phy_addr_validation_check (phy_addr)) + { + return SW_BAD_PARAM; + } + + bus = ssdk_phy_miibus_get(dev_id, phy_addr); + if (!bus) + return SW_NOT_SUPPORTED; + + mdiobus_write(bus, phy_addr, reg, data); + return 0; +} + +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) +{ + struct mii_bus *bus = NULL; + + if (A_TRUE != phy_addr_validation_check (phy_addr)) + { + return; + } + + bus = ssdk_phy_miibus_get(dev_id, phy_addr); + if (!bus) + return; + + mdiobus_write(bus, phy_addr, QCA_MII_DBG_ADDR, dbg_addr); + mdiobus_write(bus, phy_addr, QCA_MII_DBG_DATA, dbg_data); +} + +void +qca_ar8327_phy_dbg_read(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint16_t dbg_addr, a_uint16_t *dbg_data) +{ + struct mii_bus *bus = NULL; + + if (A_TRUE != phy_addr_validation_check (phy_addr)) + { + return; + } + + bus = ssdk_phy_miibus_get(dev_id, phy_addr); + if (!bus) + return; + + mdiobus_write(bus, phy_addr, QCA_MII_DBG_ADDR, dbg_addr); + *dbg_data = mdiobus_read(bus, phy_addr, QCA_MII_DBG_DATA); +} + + +void +qca_ar8327_mmd_write(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint16_t addr, a_uint16_t data) +{ + struct mii_bus *bus = NULL; + + if (A_TRUE != phy_addr_validation_check (phy_addr)) + { + return; + } + + bus = ssdk_phy_miibus_get(dev_id, phy_addr); + if (!bus) + return; + + mdiobus_write(bus, phy_addr, QCA_MII_MMD_ADDR, addr); + mdiobus_write(bus, phy_addr, QCA_MII_MMD_DATA, data); +} + +void qca_phy_mmd_write(u32 dev_id, u32 phy_id, + u16 mmd_num, u16 reg_id, u16 reg_val) +{ + qca_ar8327_phy_write(dev_id, phy_id, + QCA_MII_MMD_ADDR, mmd_num); + qca_ar8327_phy_write(dev_id, phy_id, + QCA_MII_MMD_DATA, reg_id); + qca_ar8327_phy_write(dev_id, phy_id, + QCA_MII_MMD_ADDR, + 0x4000 | mmd_num); + qca_ar8327_phy_write(dev_id, phy_id, + QCA_MII_MMD_DATA, reg_val); +} + +u16 qca_phy_mmd_read(u32 dev_id, u32 phy_id, + u16 mmd_num, u16 reg_id) +{ + u16 value = 0; + qca_ar8327_phy_write(dev_id, phy_id, + QCA_MII_MMD_ADDR, mmd_num); + qca_ar8327_phy_write(dev_id, phy_id, + QCA_MII_MMD_DATA, reg_id); + qca_ar8327_phy_write(dev_id, phy_id, + QCA_MII_MMD_ADDR, + 0x4000 | mmd_num); + qca_ar8327_phy_read(dev_id, phy_id, + QCA_MII_MMD_DATA, &value); + return value; +} +/*qca808x_end*/ +sw_error_t +qca_switch_reg_read(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t * reg_data, a_uint32_t len) +{ + uint32_t reg_val = 0; + + if (len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + + if ((reg_addr%4)!= 0) + return SW_BAD_PARAM; + + reg_val = readl(qca_phy_priv_global[dev_id]->hw_addr + reg_addr); + + aos_mem_copy(reg_data, ®_val, sizeof (a_uint32_t)); + return 0; +} + +sw_error_t +qca_switch_reg_write(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t * reg_data, a_uint32_t len) +{ + uint32_t reg_val = 0; + if (len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + + if ((reg_addr%4)!= 0) + return SW_BAD_PARAM; + + aos_mem_copy(®_val, reg_data, sizeof (a_uint32_t)); + writel(reg_val, qca_phy_priv_global[dev_id]->hw_addr + reg_addr); + return 0; +} + +sw_error_t +qca_psgmii_reg_read(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t * reg_data, a_uint32_t len) +{ +#ifdef DESS + uint32_t reg_val = 0; + + if (len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + + if((reg_addr%4)!=0) + return SW_BAD_PARAM; + + if (qca_phy_priv_global[dev_id]->psgmii_hw_addr == NULL) + return SW_NOT_SUPPORTED; + + reg_val = readl(qca_phy_priv_global[dev_id]->psgmii_hw_addr + reg_addr); + + aos_mem_copy(reg_data, ®_val, sizeof (a_uint32_t)); +#endif + return 0; +} + +sw_error_t +qca_psgmii_reg_write(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t * reg_data, a_uint32_t len) +{ +#ifdef DESS + uint32_t reg_val = 0; + if (len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + + if((reg_addr%4)!=0) + return SW_BAD_PARAM; + + if (qca_phy_priv_global[dev_id]->psgmii_hw_addr == NULL) + return SW_NOT_SUPPORTED; + + aos_mem_copy(®_val, reg_data, sizeof (a_uint32_t)); + writel(reg_val, qca_phy_priv_global[dev_id]->psgmii_hw_addr + reg_addr); +#endif + return 0; +} + +sw_error_t +qca_uniphy_reg_read(a_uint32_t dev_id, a_uint32_t uniphy_index, + a_uint32_t reg_addr, a_uint8_t * reg_data, a_uint32_t len) +{ +#if (defined(HPPE) || defined(MP)) + uint32_t reg_val = 0; + void __iomem *hppe_uniphy_base = NULL; + a_uint32_t reg_addr1, reg_addr2; + + if (len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + + if (SSDK_UNIPHY_INSTANCE0 == uniphy_index) + hppe_uniphy_base = qca_phy_priv_global[dev_id]->uniphy_hw_addr; + else if (SSDK_UNIPHY_INSTANCE1 == uniphy_index) + hppe_uniphy_base = qca_phy_priv_global[dev_id]->uniphy_hw_addr + HPPE_UNIPHY_BASE1; + + else if (SSDK_UNIPHY_INSTANCE2 == uniphy_index) + hppe_uniphy_base = qca_phy_priv_global[dev_id]->uniphy_hw_addr + HPPE_UNIPHY_BASE2; + else + return SW_BAD_PARAM; + + if ( reg_addr > HPPE_UNIPHY_MAX_DIRECT_ACCESS_REG) + { + // uniphy reg indireclty access + reg_addr1 = (reg_addr & 0xffffff) >> 8; + writel(reg_addr1, hppe_uniphy_base + HPPE_UNIPHY_INDIRECT_REG_ADDR); + + reg_addr2 = reg_addr & HPPE_UNIPHY_INDIRECT_LOW_ADDR; + reg_addr = (HPPE_UNIPHY_INDIRECT_DATA << 10) | (reg_addr2 << 2); + + reg_val = readl(hppe_uniphy_base + reg_addr); + aos_mem_copy(reg_data, ®_val, sizeof (a_uint32_t)); + } + else + { // uniphy reg directly access + reg_val = readl(hppe_uniphy_base + reg_addr); + aos_mem_copy(reg_data, ®_val, sizeof (a_uint32_t)); + } +#endif + return 0; +} + +sw_error_t +qca_uniphy_reg_write(a_uint32_t dev_id, a_uint32_t uniphy_index, + a_uint32_t reg_addr, a_uint8_t * reg_data, a_uint32_t len) +{ +#if (defined(HPPE) || defined(MP)) + void __iomem *hppe_uniphy_base = NULL; + a_uint32_t reg_addr1, reg_addr2; + uint32_t reg_val = 0; + + if (len != sizeof (a_uint32_t)) + return SW_BAD_LEN; + + if (SSDK_UNIPHY_INSTANCE0 == uniphy_index) + hppe_uniphy_base = qca_phy_priv_global[dev_id]->uniphy_hw_addr; + else if (SSDK_UNIPHY_INSTANCE1 == uniphy_index) + hppe_uniphy_base = qca_phy_priv_global[dev_id]->uniphy_hw_addr + HPPE_UNIPHY_BASE1; + + else if (SSDK_UNIPHY_INSTANCE2 == uniphy_index) + hppe_uniphy_base = qca_phy_priv_global[dev_id]->uniphy_hw_addr + HPPE_UNIPHY_BASE2; + else + return SW_BAD_PARAM; + + if ( reg_addr > HPPE_UNIPHY_MAX_DIRECT_ACCESS_REG) + { + // uniphy reg indireclty access + reg_addr1 = (reg_addr & 0xffffff) >> 8; + writel(reg_addr1, hppe_uniphy_base + HPPE_UNIPHY_INDIRECT_REG_ADDR); + + reg_addr2 = reg_addr & HPPE_UNIPHY_INDIRECT_LOW_ADDR; + reg_addr = (HPPE_UNIPHY_INDIRECT_DATA << 10) | (reg_addr2 << 2); + aos_mem_copy(®_val, reg_data, sizeof (a_uint32_t)); + writel(reg_val, hppe_uniphy_base + reg_addr); + } + else + { // uniphy reg directly access + aos_mem_copy(®_val, reg_data, sizeof (a_uint32_t)); + writel(reg_val, hppe_uniphy_base + reg_addr); + } +#endif + return 0; +} +#ifndef BOARD_AR71XX +/*qca808x_start*/ +static int miibus_get(a_uint32_t dev_id) +{ +/*qca808x_end*/ +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) +/*qca808x_start*/ + struct device_node *mdio_node = NULL; + struct device_node *switch_node = NULL; + struct platform_device *mdio_plat = NULL; + struct ipq40xx_mdio_data *mdio_data = NULL; + struct qca_phy_priv *priv; + hsl_reg_mode reg_mode = HSL_REG_LOCAL_BUS; + priv = qca_phy_priv_global[dev_id]; + switch_node = qca_phy_priv_global[dev_id]->of_node; + if (switch_node) { + mdio_node = of_parse_phandle(switch_node, "mdio-bus", 0); + if (mdio_node) { + priv->miibus = of_mdio_find_bus(mdio_node); + return 0; + } + } +/*qca808x_end*/ + reg_mode=ssdk_switch_reg_access_mode_get(dev_id); +/*qca808x_start*/ + if(reg_mode == HSL_REG_LOCAL_BUS) + mdio_node = of_find_compatible_node(NULL, NULL, "qcom,ipq40xx-mdio"); + else + mdio_node = of_find_compatible_node(NULL, NULL, "virtual,mdio-gpio"); + + if (!mdio_node) { + SSDK_ERROR("No MDIO node found in DTS!\n"); + return 1; + } + + mdio_plat = of_find_device_by_node(mdio_node); + if (!mdio_plat) { + SSDK_ERROR("cannot find platform device from mdio node\n"); + return 1; + } + + if(reg_mode == HSL_REG_LOCAL_BUS) + { + mdio_data = dev_get_drvdata(&mdio_plat->dev); + if (!mdio_data) { + SSDK_ERROR("cannot get mdio_data reference from device data\n"); + return 1; + } + priv->miibus = mdio_data->mii_bus; + } + else + priv->miibus = dev_get_drvdata(&mdio_plat->dev); + + if (!priv->miibus) { + SSDK_ERROR("cannot get mii bus reference from device data\n"); + return 1; + } +/*qca808x_end*/ +#else + struct device *miidev; + char busid[MII_BUS_ID_SIZE]; + struct qca_phy_priv *priv; + + priv = qca_phy_priv_global[dev_id]; + snprintf(busid, MII_BUS_ID_SIZE, "%s.%d", + PLATFORM_MDIO_BUS_NAME, PLATFORM_MDIO_BUS_NUM); + + miidev = bus_find_device_by_name(&platform_bus_type, NULL, busid); + if (!miidev) { + SSDK_ERROR("Failed to get miidev\n"); + return 1; + } + + priv->miibus = dev_get_drvdata(miidev); + + if(!priv->miibus){ + SSDK_ERROR("mdio bus '%s' get FAIL\n", busid); + return 1; + } +#endif +/*qca808x_start*/ + return 0; +} +/*qca808x_end*/ +#else +static int miibus_get(a_uint32_t dev_id) +{ + struct ag71xx_mdio *am; + struct qca_phy_priv *priv = qca_phy_priv_global[dev_id]; +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) + struct device_node *mdio_node = NULL; + struct platform_device *mdio_plat = NULL; + + mdio_node = of_find_compatible_node(NULL, NULL, "qca,ag71xx-mdio"); + if (!mdio_node) { + SSDK_ERROR("No MDIO node found in DTS!\n"); + return 1; + } + mdio_plat = of_find_device_by_node(mdio_node); + if (!mdio_plat) { + SSDK_ERROR("cannot find platform device from mdio node\n"); + return 1; + } + am = dev_get_drvdata(&mdio_plat->dev); + if (!am) { + SSDK_ERROR("cannot get mdio_data reference from device data\n"); + return 1; + } + priv->miibus = am->mii_bus; + + switch_chip_id_adjuest(dev_id); +#else + struct device *miidev; + char busid[MII_BUS_ID_SIZE]; + + snprintf(busid, MII_BUS_ID_SIZE, "%s.%d", + PLATFORM_MDIO_BUS_NAME, PLATFORM_MDIO_BUS_NUM); + + miidev = bus_find_device_by_name(&platform_bus_type, NULL, busid); + if (!miidev) { + SSDK_ERROR("Failed to get miidev!\n"); + return 1; + } + am = dev_get_drvdata(miidev); + priv->miibus = am->mii_bus; + + if(switch_chip_id_adjuest(dev_id)) { + snprintf(busid, MII_BUS_ID_SIZE, "%s.%d", + PLATFORM_MDIO_BUS_NAME, MDIO_BUS_1); + + miidev = bus_find_device_by_name(&platform_bus_type, NULL, busid); + if (!miidev) { + SSDK_ERROR("Failed get mii bus\n"); + return 1; + } + + am = dev_get_drvdata(miidev); + priv->miibus = am->mii_bus; + SSDK_INFO("chip_version:0x%x\n", (qca_ar8216_mii_read(dev_id, 0)&0xff00)>>8); + } + + if(!miidev){ + SSDK_ERROR("mdio bus '%s' get FAIL\n", busid); + return 1; + } +#endif + + return 0; +} +#endif + +struct mii_bus *ssdk_miibus_get_by_device(a_uint32_t dev_id) +{ + return qca_phy_priv_global[dev_id]->miibus; +} + +static ssize_t ssdk_dev_id_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t count; + a_uint32_t num; + + num = (a_uint32_t)ssdk_dev_id; + + count = snprintf(buf, (ssize_t)PAGE_SIZE, "%u", num); + return count; +} + +static ssize_t ssdk_dev_id_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char num_buf[12]; + a_uint32_t num; + + if (count >= sizeof(num_buf)) return 0; + memcpy(num_buf, buf, count); + num_buf[count] = '\0'; + sscanf(num_buf, "%u", &num); + + ssdk_dev_id = num; + + return count; +} + +static ssize_t ssdk_log_level_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t count; + a_uint32_t num; + + num = ssdk_log_level; + + count = snprintf(buf, (ssize_t)PAGE_SIZE, "%u", num); + return count; +} + +static ssize_t ssdk_log_level_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char num_buf[12]; + a_uint32_t num; + + if (count >= sizeof(num_buf)) + return 0; + memcpy(num_buf, buf, count); + num_buf[count] = '\0'; + sscanf(num_buf, "%u", &num); + + ssdk_log_level = (a_uint32_t)num; + + return count; +} + +static ssize_t ssdk_packet_counter_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t count; + adpt_api_t *p_api; + + p_api = adpt_api_ptr_get(ssdk_dev_id); + if (p_api == NULL || p_api->adpt_debug_counter_get == NULL) + { + count = snprintf(buf, (ssize_t)PAGE_SIZE, "Unsupported\n"); + return count; + } + + count = snprintf(buf, (ssize_t)PAGE_SIZE, "\n"); + + p_api->adpt_debug_counter_get(A_FALSE); + + return count; +} + +static ssize_t ssdk_packet_counter_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char num_buf[12]; + adpt_api_t *p_api; + + p_api = adpt_api_ptr_get(ssdk_dev_id); + if (p_api == NULL || p_api->adpt_debug_counter_set == NULL) { + SSDK_WARN("Unsupported\n"); + return count; + } + + p_api->adpt_debug_counter_set(); + + if (count >= sizeof(num_buf)) + return 0; + memcpy(num_buf, buf, count); + num_buf[count] = '\0'; + + + return count; +} + +static ssize_t ssdk_byte_counter_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t count; + adpt_api_t *p_api; + + p_api = adpt_api_ptr_get(ssdk_dev_id); + if (p_api == NULL || p_api->adpt_debug_counter_get == NULL) + { + count = snprintf(buf, (ssize_t)PAGE_SIZE, "Unsupported\n"); + return count; + } + + count = snprintf(buf, (ssize_t)PAGE_SIZE, "\n"); + + p_api->adpt_debug_counter_get(A_TRUE); + + return count; +} + +static ssize_t ssdk_byte_counter_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char num_buf[12]; + adpt_api_t *p_api; + + p_api = adpt_api_ptr_get(ssdk_dev_id); + if (p_api == NULL || p_api->adpt_debug_counter_set == NULL) { + SSDK_WARN("Unsupported\n"); + return count; + } + + p_api->adpt_debug_counter_set(); + + if (count >= sizeof(num_buf)) + return 0; + memcpy(num_buf, buf, count); + num_buf[count] = '\0'; + + + return count; +} + +#ifdef HPPE +#ifdef IN_QOS +void ssdk_dts_port_scheduler_dump(a_uint32_t dev_id) +{ + a_uint32_t i; + ssdk_dt_portscheduler_cfg *portscheduler_cfg; + ssdk_dt_scheduler_cfg *scheduler_cfg; + a_uint8_t srcmsg[7][16]; + + scheduler_cfg = ssdk_bootup_shceduler_cfg_get(dev_id); + + printk("===============================port_scheduler_resource===========================\n"); + printk("portid ucastq mcastq 10sp 10cdrr 10edrr 11cdrr 11edrr\n"); + for (i = 0; i < SSDK_MAX_PORT_NUM; i++) + { + portscheduler_cfg = &scheduler_cfg->pool[i]; + snprintf(srcmsg[0], sizeof(srcmsg[0]), "<%d %d>", portscheduler_cfg->ucastq_start, + portscheduler_cfg->ucastq_end); + snprintf(srcmsg[1], sizeof(srcmsg[1]), "<%d %d>", portscheduler_cfg->mcastq_start, + portscheduler_cfg->mcastq_end); + snprintf(srcmsg[2], sizeof(srcmsg[2]), "<%d %d>", portscheduler_cfg->l0sp_start, + portscheduler_cfg->l0sp_end); + snprintf(srcmsg[3], sizeof(srcmsg[3]), "<%d %d>", portscheduler_cfg->l0cdrr_start, + portscheduler_cfg->l0cdrr_end); + snprintf(srcmsg[4], sizeof(srcmsg[4]), "<%d %d>", portscheduler_cfg->l0edrr_start, + portscheduler_cfg->l0edrr_end); + snprintf(srcmsg[5], sizeof(srcmsg[5]), "<%d %d>", portscheduler_cfg->l1cdrr_start, + portscheduler_cfg->l1cdrr_end); + snprintf(srcmsg[6], sizeof(srcmsg[6]), "<%d %d>", portscheduler_cfg->l1edrr_start, + portscheduler_cfg->l1edrr_end); + printk("%6d%11s%11s%9s%11s%11s%11s%11s\n", i, srcmsg[0], srcmsg[1], srcmsg[2], srcmsg[3], + srcmsg[4], srcmsg[5], srcmsg[6]); + } +} + +void ssdk_dts_l0scheduler_dump(a_uint32_t dev_id) +{ + a_uint32_t i; + ssdk_dt_l0scheduler_cfg *scheduler_cfg; + ssdk_dt_scheduler_cfg *cfg; + + cfg = ssdk_bootup_shceduler_cfg_get(dev_id); + printk("==========================l0scheduler_cfg===========================\n"); + printk("queue portid cpri cdrr_id epri edrr_id sp_id\n"); + for (i = 0; i < SSDK_L0SCHEDULER_CFG_MAX; i++) + { + scheduler_cfg = &cfg->l0cfg[i]; + if (scheduler_cfg->valid == 1) + printk("%5d%11d%9d%12d%9d%12d%10d\n", i, scheduler_cfg->port_id, + scheduler_cfg->cpri, scheduler_cfg->cdrr_id, scheduler_cfg->epri, + scheduler_cfg->edrr_id, scheduler_cfg->sp_id); + } +} + +void ssdk_dts_l1scheduler_dump(a_uint32_t dev_id) +{ + a_uint32_t i; + ssdk_dt_l1scheduler_cfg *scheduler_cfg; + ssdk_dt_scheduler_cfg *cfg; + + cfg = ssdk_bootup_shceduler_cfg_get(dev_id); + + printk("=====================l1scheduler_cfg=====================\n"); + printk("flow portid cpri cdrr_id epri edrr_id\n"); + for (i = 0; i < SSDK_L1SCHEDULER_CFG_MAX; i++) + { + scheduler_cfg = &cfg->l1cfg[i]; + if (scheduler_cfg->valid == 1) + printk("%4d%11d%9d%12d%9d%12d\n", i, scheduler_cfg->port_id, + scheduler_cfg->cpri, scheduler_cfg->cdrr_id, + scheduler_cfg->epri, scheduler_cfg->edrr_id); + } +} +#endif +#endif +static const a_int8_t *qca_phy_feature_str[QCA_PHY_FEATURE_MAX] = { + "PHY_CLAUSE45", + "PHY_COMBO", + "PHY_QGMAC", + "PHY_XGMAC", + "PHY_I2C", + "PHY_INIT", + "PHY_FORCE" +}; + +void ssdk_dts_phyinfo_dump(a_uint32_t dev_id) +{ + a_uint32_t i, j; + ssdk_port_phyinfo *port_phyinfo; + + printk("=====================port phyinfo========================\n"); + printk("portid phy_addr features\n"); + + for (i = 0; i <= SSDK_MAX_PORT_NUM; i++) { + port_phyinfo = ssdk_port_phyinfo_get(dev_id, i); + if (port_phyinfo) { + printk("%6d%13d%*s", port_phyinfo->port_id, + port_phyinfo->phy_addr, 5, ""); + for (j = 0; j < QCA_PHY_FEATURE_MAX; j++) { + if (port_phyinfo->phy_features & BIT(j) && BIT(j) != PHY_F_INIT) { + printk("%s ", qca_phy_feature_str[j]); + if (BIT(j) == PHY_F_FORCE) { + printk("(speed: %d, duplex: %s) ", + port_phyinfo->port_speed, + port_phyinfo->port_duplex > 0 ? + "full" : "half"); + } + } + } + printk("\n"); + } + } +} + +static ssize_t ssdk_dts_dump(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t count; + a_uint32_t dev_id, dev_num; + ssdk_reg_map_info map; + hsl_reg_mode mode; + + count = snprintf(buf, (ssize_t)PAGE_SIZE, "\n"); + + dev_num = ssdk_switch_device_num_get(); + for (dev_id = 0; dev_id < dev_num; dev_id ++) + { + ssdk_switch_reg_map_info_get(dev_id, &map); + mode = ssdk_switch_reg_access_mode_get(dev_id); + printk("=======================================================\n"); + printk("ess-switch\n"); + printk(" reg = <0x%x 0x%x>\n", map.base_addr, map.size); + if (mode == HSL_REG_LOCAL_BUS) + printk(" switch_access_mode = \n"); + else if (mode == HSL_REG_MDIO) + printk(" switch_access_mode = \n"); + else + printk(" switch_access_mode = <(null)>\n"); + printk(" switch_cpu_bmp = <0x%x>\n", ssdk_cpu_bmp_get(dev_id)); + printk(" switch_lan_bmp = <0x%x>\n", ssdk_lan_bmp_get(dev_id)); + printk(" switch_wan_bmp = <0x%x>\n", ssdk_wan_bmp_get(dev_id)); + printk(" switch_inner_bmp = <0x%x>\n", ssdk_inner_bmp_get(dev_id)); + printk(" switch_mac_mode = <0x%x>\n", ssdk_dt_global_get_mac_mode(dev_id, 0)); + printk(" switch_mac_mode1 = <0x%x>\n", ssdk_dt_global_get_mac_mode(dev_id, 1)); + printk(" switch_mac_mode2 = <0x%x>\n", ssdk_dt_global_get_mac_mode(dev_id, 2)); +#ifdef IN_BM + printk(" bm_tick_mode = <0x%x>\n", ssdk_bm_tick_mode_get(dev_id)); +#endif +#ifdef HPPE +#ifdef IN_QOS + printk(" tm_tick_mode = <0x%x>\n", ssdk_tm_tick_mode_get(dev_id)); +#endif +#endif +#ifdef DESS + printk("ess-psgmii\n"); + ssdk_psgmii_reg_map_info_get(dev_id, &map); + mode = ssdk_psgmii_reg_access_mode_get(dev_id); + printk(" reg = <0x%x 0x%x>\n", map.base_addr, map.size); + if (mode == HSL_REG_LOCAL_BUS) + printk(" psgmii_access_mode = \n"); + else if (mode == HSL_REG_MDIO) + printk(" psgmii_access_mode = \n"); + else + printk(" psgmii_access_mode = <(null)>\n"); +#endif +#ifdef IN_UNIPHY + printk("ess-uniphy\n"); + ssdk_uniphy_reg_map_info_get(dev_id, &map); + mode = ssdk_uniphy_reg_access_mode_get(dev_id); + printk(" reg = <0x%x 0x%x>\n", map.base_addr, map.size); + if (mode == HSL_REG_LOCAL_BUS) + printk(" uniphy_access_mode = \n"); + else if (mode == HSL_REG_MDIO) + printk(" uniphy_access_mode = \n"); + else + printk(" uniphy_access_mode = <(null)>\n"); +#endif +#ifdef HPPE +#ifdef IN_QOS + printk("\n"); + ssdk_dts_port_scheduler_dump(dev_id); + printk("\n"); + ssdk_dts_l0scheduler_dump(dev_id); + printk("\n"); + ssdk_dts_l1scheduler_dump(dev_id); +#endif +#endif + printk("\n"); + ssdk_dts_phyinfo_dump(dev_id); + } + + return count; +} + +static a_uint16_t phy_reg_val = 0; +static ssize_t ssdk_phy_write_reg_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char phy_buf[32]; + char *this_opt; + char *options = phy_buf; + unsigned int phy_addr, reg_addr, reg_value; + + if (count >= sizeof(phy_buf)) + return 0; + memcpy(phy_buf, buf, count); + phy_buf[count] = '\0'; + + this_opt = strsep(&options, " "); + if (!this_opt) + goto fail; + + kstrtouint(this_opt, 0, &phy_addr); + if ((options - phy_buf) >= (count - 1)) + goto fail; + + this_opt = strsep(&options, " "); + if (!this_opt) + goto fail; + + kstrtouint(this_opt, 0, ®_addr); + if ((options - phy_buf) >= (count - 1)) + goto fail; + + this_opt = strsep(&options, " "); + if (!this_opt) + goto fail; + + kstrtouint(this_opt, 0, ®_value); + + qca_ar8327_phy_write(0, phy_addr, reg_addr, reg_value); + + return count; + +fail: + printk("Format: phy_addr reg_addr reg_value\n"); + return -EINVAL; +} + +static ssize_t ssdk_phy_read_reg_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t count; + + count = snprintf(buf, (ssize_t)PAGE_SIZE, "reg_val = 0x%x\n", phy_reg_val); + return count; +} + +static ssize_t ssdk_phy_read_reg_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + char phy_buf[32]; + char *this_opt; + char *options = phy_buf; + unsigned int phy_addr, reg_addr; + + if (count >= sizeof(phy_buf)) + return 0; + memcpy(phy_buf, buf, count); + phy_buf[count] = '\0'; + + this_opt = strsep(&options, " "); + if (!this_opt) + goto fail; + + kstrtouint(this_opt, 0, &phy_addr); + if ((options - phy_buf) >= (count - 1)) + goto fail; + + this_opt = strsep(&options, " "); + if (!this_opt) + goto fail; + + kstrtouint(this_opt, 0, ®_addr); + + qca_ar8327_phy_read(0, phy_addr, reg_addr, &phy_reg_val); + + return count; + +fail: + printk("Format: phy_addr reg_addr\n"); + return -EINVAL; +} + +#ifdef IN_LINUX_STD_PTP +static ssize_t ssdk_ptp_counter_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t count; + + count = snprintf(buf, (ssize_t)PAGE_SIZE, "\n"); + qca808x_ptp_stat_get(); + return count; +} + +static ssize_t ssdk_ptp_counter_set(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + qca808x_ptp_stat_set(); + return count; +} +#endif + +static const struct device_attribute ssdk_dev_id_attr = + __ATTR(dev_id, 0660, ssdk_dev_id_get, ssdk_dev_id_set); +static const struct device_attribute ssdk_log_level_attr = + __ATTR(log_level, 0660, ssdk_log_level_get, ssdk_log_level_set); +static const struct device_attribute ssdk_packet_counter_attr = + __ATTR(packet_counter, 0660, ssdk_packet_counter_get, ssdk_packet_counter_set); +static const struct device_attribute ssdk_byte_counter_attr = + __ATTR(byte_counter, 0660, ssdk_byte_counter_get, ssdk_byte_counter_set); +static const struct device_attribute ssdk_dts_dump_attr = + __ATTR(dts_dump, 0660, ssdk_dts_dump, NULL); +static const struct device_attribute ssdk_phy_write_reg_attr = + __ATTR(phy_write_reg, 0660, NULL, ssdk_phy_write_reg_set); +static const struct device_attribute ssdk_phy_read_reg_attr = + __ATTR(phy_read_reg, 0660, ssdk_phy_read_reg_get, ssdk_phy_read_reg_set); +#ifdef IN_LINUX_STD_PTP +static const struct device_attribute ssdk_ptp_counter_attr = + __ATTR(ptp_packet_counter, 0660, ssdk_ptp_counter_get, ssdk_ptp_counter_set); +#endif +struct kobject *ssdk_sys = NULL; + +int ssdk_sysfs_init (void) +{ + int ret = 0; + + /* create /sys/ssdk/ dir */ + ssdk_sys = kobject_create_and_add("ssdk", NULL); + if (!ssdk_sys) { + printk("Failed to register SSDK sysfs\n"); + return ret; + } + + /* create /sys/ssdk/dev_id file */ + ret = sysfs_create_file(ssdk_sys, &ssdk_dev_id_attr.attr); + if (ret) { + printk("Failed to register SSDK dev id SysFS file\n"); + goto CLEANUP_1; + } + + /* create /sys/ssdk/log_level file */ + ret = sysfs_create_file(ssdk_sys, &ssdk_log_level_attr.attr); + if (ret) { + printk("Failed to register SSDK log level SysFS file\n"); + goto CLEANUP_2; + } + + /* create /sys/ssdk/packet_counter file */ + ret = sysfs_create_file(ssdk_sys, &ssdk_packet_counter_attr.attr); + if (ret) { + printk("Failed to register SSDK switch counter SysFS file\n"); + goto CLEANUP_3; + } + + /* create /sys/ssdk/byte_counter file */ + ret = sysfs_create_file(ssdk_sys, &ssdk_byte_counter_attr.attr); + if (ret) { + printk("Failed to register SSDK switch counter bytes SysFS file\n"); + goto CLEANUP_4; + } + + /* create /sys/ssdk/dts_dump file */ + ret = sysfs_create_file(ssdk_sys, &ssdk_dts_dump_attr.attr); + if (ret) { + printk("Failed to register SSDK switch show dts SysFS file\n"); + goto CLEANUP_5; + } + + /* create /sys/ssdk/phy_write_reg file */ + ret = sysfs_create_file(ssdk_sys, &ssdk_phy_write_reg_attr.attr); + if (ret) { + printk("Failed to register SSDK phy write reg file\n"); + goto CLEANUP_6; + } + + /* create /sys/ssdk/phy_read_reg file */ + ret = sysfs_create_file(ssdk_sys, &ssdk_phy_read_reg_attr.attr); + if (ret) { + printk("Failed to register SSDK phy read reg file\n"); + goto CLEANUP_7; + } + +#ifdef IN_LINUX_STD_PTP + /* create /sys/ssdk/ptp_packet_counter file */ + ret = sysfs_create_file(ssdk_sys, &ssdk_ptp_counter_attr.attr); + if (ret) { + printk("Failed to register SSDK ptp counter file\n"); + goto CLEANUP_8; + } +#endif + + return 0; + +#ifdef IN_LINUX_STD_PTP +CLEANUP_8: + sysfs_remove_file(ssdk_sys, &ssdk_phy_read_reg_attr.attr); +#endif +CLEANUP_7: + sysfs_remove_file(ssdk_sys, &ssdk_phy_write_reg_attr.attr); +CLEANUP_6: + sysfs_remove_file(ssdk_sys, &ssdk_dts_dump_attr.attr); +CLEANUP_5: + sysfs_remove_file(ssdk_sys, &ssdk_byte_counter_attr.attr); +CLEANUP_4: + sysfs_remove_file(ssdk_sys, &ssdk_packet_counter_attr.attr); +CLEANUP_3: + sysfs_remove_file(ssdk_sys, &ssdk_log_level_attr.attr); +CLEANUP_2: + sysfs_remove_file(ssdk_sys, &ssdk_dev_id_attr.attr); +CLEANUP_1: + kobject_put(ssdk_sys); + + return ret; +} + +void ssdk_sysfs_exit (void) +{ +#ifdef IN_LINUX_STD_PTP + sysfs_remove_file(ssdk_sys, &ssdk_ptp_counter_attr.attr); +#endif + sysfs_remove_file(ssdk_sys, &ssdk_phy_read_reg_attr.attr); + sysfs_remove_file(ssdk_sys, &ssdk_phy_write_reg_attr.attr); + sysfs_remove_file(ssdk_sys, &ssdk_dts_dump_attr.attr); + sysfs_remove_file(ssdk_sys, &ssdk_byte_counter_attr.attr); + sysfs_remove_file(ssdk_sys, &ssdk_packet_counter_attr.attr); + sysfs_remove_file(ssdk_sys, &ssdk_log_level_attr.attr); + sysfs_remove_file(ssdk_sys, &ssdk_dev_id_attr.attr); + kobject_put(ssdk_sys); +} + +/*qca808x_start*/ +int +ssdk_plat_init(ssdk_init_cfg *cfg, a_uint32_t dev_id) +{ +/*qca808x_end*/ + hsl_reg_mode reg_mode; + ssdk_reg_map_info map; + struct clk * ess_clk; + struct clk * cmn_clk; + #ifdef BOARD_AR71XX + int rv = 0; + #endif +/*qca808x_start*/ + printk("ssdk_plat_init start\n"); +/*qca808x_end*/ + mutex_init(&switch_mdio_lock); + + if(!ssdk_is_emulation(dev_id)){ +/*qca808x_start*/ + if(miibus_get(dev_id)) + return -ENODEV; +/*qca808x_end*/ + } +#ifdef IN_UNIPHY + reg_mode = ssdk_uniphy_reg_access_mode_get(dev_id); + if(reg_mode == HSL_REG_LOCAL_BUS) { + ssdk_uniphy_reg_map_info_get(dev_id, &map); + qca_phy_priv_global[dev_id]->uniphy_hw_addr = ioremap_nocache(map.base_addr, + map.size); + if (!qca_phy_priv_global[dev_id]->uniphy_hw_addr) { + SSDK_ERROR("%s ioremap fail.", __func__); + cfg->reg_func.uniphy_reg_set = NULL; + cfg->reg_func.uniphy_reg_get = NULL; + return -1; + } + cfg->reg_func.uniphy_reg_set = qca_uniphy_reg_write; + cfg->reg_func.uniphy_reg_get = qca_uniphy_reg_read; + } +#endif + reg_mode = ssdk_switch_reg_access_mode_get(dev_id); + if(reg_mode == HSL_REG_LOCAL_BUS) { + ssdk_switch_reg_map_info_get(dev_id, &map); + qca_phy_priv_global[dev_id]->hw_addr = ioremap_nocache(map.base_addr, + map.size); + if (!qca_phy_priv_global[dev_id]->hw_addr) { + SSDK_ERROR("%s ioremap fail.", __func__); + return -1; + } + ess_clk = ssdk_dts_essclk_get(dev_id); + cmn_clk = ssdk_dts_cmnclk_get(dev_id); + if (!IS_ERR(ess_clk)) { + /* Enable ess clock here */ + SSDK_INFO("Enable ess clk\n"); + clk_prepare_enable(ess_clk); + } else if (!IS_ERR(cmn_clk)) { +#if defined(HPPE) || defined(MP) + ssdk_gcc_clock_init(); +#endif + return 0; + } + + cfg->reg_mode = HSL_HEADER; + } +#ifdef DESS + reg_mode = ssdk_psgmii_reg_access_mode_get(dev_id); + if(reg_mode == HSL_REG_LOCAL_BUS) { + ssdk_psgmii_reg_map_info_get(dev_id, &map); + if (!request_mem_region(map.base_addr, + map.size, "psgmii_mem")) { + SSDK_ERROR("%s Unable to request psgmii resource.", __func__); + return -1; + } + + qca_phy_priv_global[dev_id]->psgmii_hw_addr = ioremap_nocache(map.base_addr, + map.size); + if (!qca_phy_priv_global[dev_id]->psgmii_hw_addr) { + SSDK_ERROR("%s ioremap fail.", __func__); + cfg->reg_func.psgmii_reg_set = NULL; + cfg->reg_func.psgmii_reg_get = NULL; + return -1; + } + + cfg->reg_func.psgmii_reg_set = qca_psgmii_reg_write; + cfg->reg_func.psgmii_reg_get = qca_psgmii_reg_read; + } +#endif + reg_mode = ssdk_switch_reg_access_mode_get(dev_id); + if(reg_mode == HSL_REG_MDIO) { + cfg->reg_mode = HSL_MDIO; + } else + return 0; +/*qca808x_start*/ + + return 0; +} + +void +ssdk_plat_exit(a_uint32_t dev_id) +{ +/*qca808x_end*/ + hsl_reg_mode reg_mode; +#ifdef DESS + ssdk_reg_map_info map; +#endif +/*qca808x_start*/ + printk("ssdk_plat_exit\n"); +/*qca808x_end*/ + reg_mode = ssdk_switch_reg_access_mode_get(dev_id); + if (reg_mode == HSL_REG_LOCAL_BUS) { + iounmap(qca_phy_priv_global[dev_id]->hw_addr); + } +#ifdef DESS + reg_mode = ssdk_psgmii_reg_access_mode_get(dev_id); + if (reg_mode == HSL_REG_LOCAL_BUS) { + ssdk_psgmii_reg_map_info_get(dev_id, &map); + iounmap(qca_phy_priv_global[dev_id]->psgmii_hw_addr); + release_mem_region(map.base_addr, + map.size); + } +#endif +#ifdef IN_UNIPHY + reg_mode = ssdk_uniphy_reg_access_mode_get(dev_id); + if (reg_mode == HSL_REG_LOCAL_BUS) { + iounmap(qca_phy_priv_global[dev_id]->uniphy_hw_addr); + } +#endif +/*qca808x_start*/ +} +/*qca808x_end*/ + diff --git a/feeds/ipq807x/qca-ssdk/src/src/init/ssdk_scomphy.c b/feeds/ipq807x/qca-ssdk/src/src/init/ssdk_scomphy.c new file mode 100644 index 000000000..15611445c --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/init/ssdk_scomphy.c @@ -0,0 +1,40 @@ +/* + * 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 "ssdk_init.h" + +#ifdef MP +#include "ssdk_mp.h" +#include "hsl_phy.h" +#endif + +sw_error_t qca_scomphy_hw_init(ssdk_init_cfg *cfg, a_uint32_t dev_id) +{ + sw_error_t rv = SW_OK; + + switch (cfg->phy_id) { +#ifdef MP + case MP_GEPHY: + rv = qca_mp_hw_init(dev_id, cfg); + SW_RTN_ON_ERROR(rv); + break; +#endif + default: + break; + } + return rv; +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/init/ssdk_uci.c b/feeds/ipq807x/qca-ssdk/src/src/init/ssdk_uci.c new file mode 100755 index 000000000..aebea6439 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/init/ssdk_uci.c @@ -0,0 +1,196 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) +#include + #include +#else +#include +#include +#endif +#include "sw.h" +#include "ssdk_init.h" +#include "ssdk_plat.h" + +#ifdef BOARD_AR71XX + +struct switch_dev *old_sw_dev = NULL; +struct net_device *sw_attach_dev = NULL; +struct qca_phy_priv qca_priv; + +extern int qca_phy_id_chip(struct qca_phy_priv *priv); +extern const struct switch_dev_ops qca_ar8327_sw_ops; +extern int qca_phy_mib_work_start(struct qca_phy_priv *priv); +extern void qca_phy_mib_work_stop(struct qca_phy_priv *priv); + +int +ssdk_uci_sw_set_vlan(const struct switch_attr *attr, + struct switch_val *val) +{ + if(old_sw_dev) { + struct switch_dev_ops *ops = old_sw_dev->ops; + if(ops) { + struct switch_attrlist attr_global = ops->attr_global; + int i = 0; + struct switch_attr *g_attr = attr_global.attr; + for(i = 0; i < attr_global.n_attr; i++) { + if(!strcmp(g_attr[i].name, "enable_vlan") && + g_attr[i].set) { + g_attr[i].set(old_sw_dev, attr, val); + break; + } + } + } + } + return 0; +} + +int +ssdk_uci_sw_set_vid(const struct switch_attr *attr, + struct switch_val *val) +{ + if(old_sw_dev) { + struct switch_dev_ops *ops = old_sw_dev->ops; + if(ops) { + struct switch_attrlist attr_vlan = ops->attr_vlan; + int i = 0; + struct switch_attr *v_attr = attr_vlan.attr; + for(i = 0; i < attr_vlan.n_attr; i++) { + if(!strcmp(v_attr[i].name, "vid") && + v_attr[i].set) { + v_attr[i].set(old_sw_dev, attr, val); + break; + } + } + } + } + return 0; +} + + +int +ssdk_uci_sw_set_pvid(int port, int vlan) +{ + if(old_sw_dev) { + struct switch_dev_ops *ops = old_sw_dev->ops; + if(ops && ops->set_port_pvid) { + ops->set_port_pvid(old_sw_dev, port, vlan); + } + } + return 0; +} + +int +ssdk_uci_sw_set_ports(struct switch_val *val) +{ + if(old_sw_dev) { + struct switch_dev_ops *ops = old_sw_dev->ops; + if(ops && ops->set_vlan_ports) { + ops->set_vlan_ports(old_sw_dev, val); + } + } + return 0; +} + + +int ssdk_uci_takeover_init() +{ + struct qca_phy_priv *priv = &qca_priv; + struct switch_dev tmp_dev; + struct switch_dev *sdev = NULL; + struct net_device *tmp_net = NULL; + + /*only for s27*/ + if((qca_ar8216_mii_read(0, 0)&0xff00)>>8 != 0x02) + return 0; + + memset(&qca_priv, 0, sizeof(qca_priv)); + mutex_init(&priv->reg_mutex); + qca_phy_id_chip(priv); + priv->mii_read = qca_ar8216_mii_read; + priv->mii_write = qca_ar8216_mii_write; + priv->phy_write = qca_ar8327_phy_write; + priv->phy_dbg_write = qca_ar8327_phy_dbg_write; + priv->phy_dbg_read = qca_ar8327_phy_dbg_read; + priv->phy_mmd_write = qca_ar8327_mmd_write; + + priv->sw_dev.ops = &qca_ar8327_sw_ops; + priv->sw_dev.name = "QCA AR8327 AR8337"; + priv->sw_dev.vlans = AR8327_MAX_VLANS; + priv->sw_dev.ports = AR8327_NUM_PORTS; + memset(&tmp_dev, 0, sizeof(tmp_dev)); + tmp_dev.ops = &qca_ar8327_sw_ops; + tmp_dev.name = "ssdk probe"; + SSDK_DEBUG("SSDK uci takeover!\n"); + tmp_net = dev_get_by_name(&init_net, "eth1"); + if(!tmp_net) { + tmp_net = dev_get_by_name(&init_net, "eth0"); + if(!tmp_net) + return 0; + } + SSDK_DEBUG("using %s\n", tmp_net->name); + if(register_switch(&tmp_dev, tmp_net) < 0) { + SSDK_ERROR("register temp switch fail!\n"); + return 0; + } + list_for_each_entry(sdev, &tmp_dev.dev_list, dev_list) { + SSDK_DEBUG("Found %s\n", sdev->name); + if(!strcmp(sdev->name, "AR7240/AR9330 built-in switch") || + !strcmp(sdev->name, "AR934X built-in switch")) { + int err; + /*found*/ + sw_attach_dev = sdev->netdev; + old_sw_dev = sdev; + /*unregister openwrt switch device*/ + unregister_switch(sdev); + /*register ours*/ + SSDK_DEBUG("ssdk register switch, old name %s\n", sdev->name); + if(err = register_switch(&priv->sw_dev, sw_attach_dev) < 0) { + SSDK_ERROR("ssdk register switch fail %d!\n", err); + } + break; + } + } + /*anyway should unregister the temp switch dev*/ + unregister_switch(&tmp_dev); + if(sw_attach_dev) { + qca_phy_mib_work_start(&qca_priv); + } + return 0; +} + +void ssdk_uci_takeover_exit() +{ + if(sw_attach_dev && old_sw_dev) { + unregister_switch(&qca_priv.sw_dev); + register_switch(old_sw_dev, sw_attach_dev); + qca_phy_mib_work_stop(&qca_priv); + } +} + +#endif + + diff --git a/feeds/ipq807x/qca-ssdk/src/src/ref/Makefile b/feeds/ipq807x/qca-ssdk/src/src/ref/Makefile new file mode 100755 index 000000000..fc2bca7de --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/ref/Makefile @@ -0,0 +1,45 @@ +LOC_DIR=src/ref +LIB=REF + +include $(PRJ_PATH)/make/config.mk + +SRC_LIST_TMP=ref_uci.c +SRC_SW_LIST=ref_misc.c ref_uci.c + +ifeq (TRUE, $(IN_FDB)) + SRC_LIST_TMP += ref_fdb.c +endif + +ifeq (TRUE, $(IN_MIB)) + SRC_LIST_TMP += ref_mib.c +endif + +ifeq (TRUE, $(IN_MISC)) + SRC_LIST_TMP += ref_misc.c +endif + +ifeq (TRUE, $(IN_PORTCONTROL)) + SRC_LIST_TMP += ref_port_ctrl.c +endif + +ifeq (TRUE, $(IN_VLAN)) + SRC_LIST_TMP += ref_vlan.c +endif + +ifeq (TRUE, $(IN_VSI)) + SRC_LIST_TMP += ref_vsi.c +endif + +ifeq (FALSE, $(SWCONFIG)) + SRC_LIST=$(filter-out $(SRC_SW_LIST), $(SRC_LIST_TMP)) +else + SRC_LIST=$(SRC_LIST_TMP) +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/src/src/ref/ref_fdb.c b/feeds/ipq807x/qca-ssdk/src/src/ref/ref_fdb.c new file mode 100755 index 000000000..87d01936c --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/ref/ref_fdb.c @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2012, 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 "fal_init.h" +#include "fal_misc.h" +#include "fal_mib.h" +#include "fal_port_ctrl.h" +#include "fal_portvlan.h" +#include "fal_fdb.h" +#include "fal_stp.h" +#include "fal_igmp.h" +#include "fal_qos.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "ssdk_init.h" +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0)) +#include +#endif +#include +#include +#include +#include "ssdk_plat.h" +#include "ref_vlan.h" +#include "ref_fdb.h" + + +#if defined(IN_SWCONFIG) +int +qca_ar8327_sw_atu_flush(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct qca_phy_priv *priv = qca_phy_priv_get(dev); + /* 0: dynamic 1:dynamic, static */ + fal_fdb_entry_flush(priv->device_id, 1); + + return 0; +} + +int +qca_ar8327_sw_atu_dump(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct qca_phy_priv *priv = qca_phy_priv_get(dev); + a_uint32_t rv; + char *buf; + a_uint32_t len = 0; + a_uint32_t i = 0; + fal_fdb_op_t option; + fal_fdb_entry_t entry; + fal_pbmp_t port_bmp = 0; + a_uint32_t port_type = 0; + + buf = (char*) priv->buf; + memset(buf, 0, 2048); + memset(&option, 0, sizeof(fal_fdb_op_t)); + memset(&entry, 0, sizeof(fal_fdb_entry_t)); + + if (priv->version == QCA_VER_AR8227) + rv = fal_fdb_entry_getfirst(priv->device_id, &entry); + else + rv = fal_fdb_entry_extend_getfirst(priv->device_id, &option, &entry); + while (!rv) + { + len += snprintf(buf+len, 2048-len, "MAC: %02x:%02x:%02x:%02x:%02x:%02x ", + entry.addr.uc[0],entry.addr.uc[1],entry.addr.uc[2],entry.addr.uc[3], + entry.addr.uc[4],entry.addr.uc[5]); + if(entry.portmap_en == A_TRUE) { + port_bmp = entry.port.map; + len += snprintf(buf+len, 2048-len, + "PORTMAP: 0x%02x VID: 0x%x STATUS: 0x%x\n", + port_bmp, entry.fid, entry.static_en); + } else { + port_type = FAL_PORT_ID_TYPE(entry.port.id); + if(port_type == FAL_PORT_TYPE_PPORT) { + port_bmp = 1 << entry.port.id; + len += snprintf(buf+len, 2048-len, + "PORTMAP: 0x%02x VID: 0x%x STATUS: 0x%x\n", + port_bmp, entry.fid, entry.static_en); + } else { + len += snprintf(buf+len, 2048-len, + "DEST_INFO: 0x%02x VID: 0x%x STATUS: 0x%x\n", + entry.port.id, entry.fid, entry.static_en); + } + } + + if (2048-len < 74){ +// snprintf(buf+len, 2048-len, "Buffer not enough!\n"); + break; + } + if (priv->version == QCA_VER_AR8227) + rv = fal_fdb_entry_getnext_byindex(priv->device_id, &i, &entry); + else + rv = fal_fdb_entry_extend_getnext(priv->device_id, &option, &entry); + } + + val->value.s = (char*)(priv->buf); + val->len = len; + + return 0; +} +#endif + +#define MAX_PORT 6 +/* + * example: + * vid=4; + * char addr[6] = {0x00, 0x01, 0x02, 0x88, 0x00, 0xaa} + * + * return value: + * success: 0 - 5 + * fail: 0xffffffff + */ +fal_port_t +ref_fdb_get_port_by_mac(unsigned int vid, const char * addr) +{ + fal_fdb_entry_t entry; + unsigned char i; + sw_error_t rv; + + memset(&entry, 0, sizeof(entry)); + entry.fid = vid; + for (i = 0; i < 6; i++) + entry.addr.uc[i] = addr[i]; + + rv = fal_fdb_find(0, &entry); + if (rv != SW_OK) + return 0xffffffff; + + for (i = 0; i < MAX_PORT; i++) + { + if (entry.port.id & (0x1 << i)) + { + return i; + } + } + return 0xffffffff; +} + +EXPORT_SYMBOL(ref_fdb_get_port_by_mac); + diff --git a/feeds/ipq807x/qca-ssdk/src/src/ref/ref_mib.c b/feeds/ipq807x/qca-ssdk/src/src/ref/ref_mib.c new file mode 100644 index 000000000..add4e2e28 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/ref/ref_mib.c @@ -0,0 +1,520 @@ +/* + * Copyright (c) 2012, 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 "fal_init.h" +#include "fal_misc.h" +#include "fal_mib.h" +#include "fal_port_ctrl.h" +#include "fal_portvlan.h" +#include "fal_fdb.h" +#include "fal_stp.h" +#include "fal_igmp.h" +#include "fal_qos.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "ssdk_init.h" +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0)) +#include +#endif +#include +#include +#include +#include "ssdk_plat.h" +#include "ref_vlan.h" + +#if defined(IN_SWCONFIG) +int +_qca_ar8327_sw_capture_port_counter(struct switch_dev *dev, int port) +{ + fal_mib_info_t mib_Info; + struct qca_phy_priv *priv = qca_phy_priv_get(dev); + + memset(&mib_Info, 0, sizeof(mib_Info)); + fal_get_mib_info(priv->device_id, port, &mib_Info); + + return 0; +} + +int +qca_ar8327_sw_set_reset_mibs(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + int i = 0; + int len = 0; + struct qca_phy_priv *priv = qca_phy_priv_get(dev); + fal_mib_info_t mib_Info; + len = dev->ports * QCA_MIB_ITEM_NUMBER * + sizeof(*priv->mib_counters); + + mutex_lock(&priv->mib_lock); + memset(priv->mib_counters, '\0', len); + for (i = 0; i < dev->ports; i++) + { + fal_get_mib_info(priv->device_id, i, &mib_Info); + fal_mib_port_flush_counters(priv->device_id, i); + } + mutex_unlock(&priv->mib_lock); + + return 0; +} + +int +qca_ar8327_sw_set_port_reset_mib(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + int len = 0; + struct qca_phy_priv *priv = qca_phy_priv_get(dev); + fal_mib_info_t mib_Info; + len = QCA_MIB_ITEM_NUMBER * sizeof(*priv->mib_counters); + + mutex_lock(&priv->mib_lock); + + memset(priv->mib_counters + (val->port_vlan * QCA_MIB_ITEM_NUMBER), '\0', len); + + fal_get_mib_info(priv->device_id, val->port_vlan, &mib_Info); + fal_mib_port_flush_counters(priv->device_id, val->port_vlan); + mutex_unlock(&priv->mib_lock); + + return 0; +} + +#ifdef HPPE +static int qca_ar8327_sw_print_xgport_mib(struct switch_dev *dev, + const struct switch_attr *attr, struct switch_val *val) +{ + int port = 0; + int len = 0; + fal_xgmib_info_t xgmib_info; + + struct qca_phy_priv *priv = qca_phy_priv_get(dev); + char *buf = (char *)(priv->buf); + + port = val->port_vlan; + if (port >= dev->ports) + return -EINVAL; + + fal_get_xgmib_info(priv->device_id, port, &xgmib_info); + + mutex_lock(&priv->mib_lock); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "XG Port %d MIB counters\n", + port); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "RxFrame", xgmib_info.RxFrame); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "RxByte", xgmib_info.RxByte); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "RxByteGood", xgmib_info.RxByteGood); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "RxBroadGood", xgmib_info.RxBroadGood); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "RxMultiGood", xgmib_info.RxMultiGood); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "RxFcsErr", xgmib_info.RxFcsErr); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "RxRuntErr", xgmib_info.RxRuntErr ); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "RxJabberError", xgmib_info.RxJabberError); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "RxUndersizeGood", xgmib_info.RxUndersizeGood); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "RxOversizeGood", xgmib_info.RxOversizeGood); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "Rx64Byte", xgmib_info.Rx64Byte); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "Rx128Byte", xgmib_info.Rx128Byte); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "Rx256Byte", xgmib_info.Rx256Byte); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "Rx512Byte", xgmib_info.Rx512Byte); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "Rx1024Byte", xgmib_info.Rx1024Byte); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "RxMaxByte", xgmib_info.RxMaxByte); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "RxUnicastGood", xgmib_info.RxUnicastGood); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "RxLengthError", xgmib_info.RxLengthError); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "RxOutOfRangeError", xgmib_info.RxOutOfRangeError); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "RxPause", xgmib_info.RxPause); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "RxOverFlow", xgmib_info.RxOverFlow); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "RxVLANFrameGoodBad", xgmib_info.RxVLANFrameGoodBad); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "RxWatchDogError", xgmib_info.RxWatchDogError); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "RxLPIUsec", xgmib_info.RxLPIUsec); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "RxLPITran", xgmib_info.RxLPITran); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "RxDropFrameGoodBad", xgmib_info.RxDropFrameGoodBad); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "RxDropByteGoodBad", xgmib_info.RxDropByteGoodBad); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "TxByte", xgmib_info.TxByte); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "TxFrame", xgmib_info.TxFrame); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "TxBroadGood", xgmib_info.TxBroadGood); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "TxMultiGood", xgmib_info.TxMultiGood); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "Tx64Byte", xgmib_info.Tx64Byte); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "Tx128Byte", xgmib_info.Tx128Byte); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "Tx256Byte", xgmib_info.Tx256Byte); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "Tx512Byte", xgmib_info.Tx512Byte); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "Tx1024Byte", xgmib_info.Tx1024Byte); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "TxMaxByte", xgmib_info.TxMaxByte); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "TxUnicast", xgmib_info.TxUnicast); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "TxMulti", xgmib_info.TxMulti); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "TxBroad", xgmib_info.TxBroad); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "TxUnderFlowError", xgmib_info.TxUnderFlowError); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "TxByteGood", xgmib_info.TxByteGood); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "TxByteGood", xgmib_info.TxByteGood); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "TxPause", xgmib_info.TxPause); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "TxVLANFrameGood", xgmib_info.TxVLANFrameGood); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "TxLPIUsec", xgmib_info.TxLPIUsec); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-18s: %llu\n", "TxLPITran", xgmib_info.TxLPITran); + + mutex_unlock(&priv->mib_lock); + + val->value.s = buf; + val->len = len; + + return 0; +} +#endif + +int +qca_ar8327_sw_get_port_mib(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + int port = 0; + int len = 0; + int pos = 0; + + struct qca_phy_priv *priv = qca_phy_priv_get(dev); + char *buf = (char *)(priv->buf); + + port = val->port_vlan; + if (port >= dev->ports) + return -EINVAL; +#ifdef HPPE + if (priv->version == QCA_VER_HPPE && + qca_hppe_port_mac_type_get(priv->device_id, port) == PORT_XGMAC_TYPE) + { + qca_ar8327_sw_print_xgport_mib(dev, attr, val); + return 0; + } +#endif + mutex_lock(&priv->mib_lock); + _qca_ar8327_sw_capture_port_counter(dev, port); + pos = port * (sizeof(fal_mib_counter_t)/sizeof(a_uint64_t)); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "Port %d MIB counters\n", + port); + + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "RxBroad", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "RxPause", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "RxMulti", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "RxFcsErr", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "RxAlignErr", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "RxRunt", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "RxFragment", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "Rx64Byte", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "Rx128Byte", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "Rx256Byte", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "Rx512Byte", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "Rx1024Byte", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "Rx1518Byte", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "RxMaxByte", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "RxTooLong", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "RxGoodByte", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "RxBadByte", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "RxOverFlow", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "Filtered", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "TxBroad", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "TxPause", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "TxMulti", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "TxUnderRun", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "Tx64Byte", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "Tx128Byte", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "Tx256Byte", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "Tx512Byte", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "Tx1024Byte", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "Tx1518Byte", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "TxMaxByte", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "TxOverSize", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "TxByte", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "TxCollision", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "TxAbortCol", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "TxMultiCol", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "TxSingleCol", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "TxExcDefer", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "TxDefer", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "TxLateCol", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "RxUniCast", + priv->mib_counters[pos++]); + len += snprintf(buf + len, sizeof(priv->buf) - len, + "%-12s: %llu\n", + "TxUniCast", + priv->mib_counters[pos++]); + mutex_unlock(&priv->mib_lock); + + val->value.s = buf; + val->len = len; + + return 0; +} +#endif + +int +_qca_ar8327_sw_capture_port_tx_counter(struct qca_phy_priv *priv, int port) +{ + fal_mib_info_t mib_Info; + + memset(&mib_Info, 0, sizeof(fal_mib_info_t)); + fal_get_tx_mib_info(priv->device_id, port, &mib_Info); + + return 0; +} + +int +_qca_ar8327_sw_capture_port_rx_counter(struct qca_phy_priv *priv, int port) +{ + fal_mib_info_t mib_Info; + + memset(&mib_Info, 0, sizeof(fal_mib_info_t)); + fal_get_rx_mib_info(priv->device_id, port, &mib_Info); + return 0; +} + +void +qca_ar8327_sw_mib_task(struct qca_phy_priv *priv) +{ + static int loop = 0; + + mutex_lock(&priv->reg_mutex); + if ((loop % 2) == 0) + _qca_ar8327_sw_capture_port_rx_counter(priv, loop/2); + else + _qca_ar8327_sw_capture_port_tx_counter(priv, loop/2); + + if(++loop == (2 * (priv->ports))) { + loop = 0; + } + + mutex_unlock(&priv->reg_mutex); + + return; +} diff --git a/feeds/ipq807x/qca-ssdk/src/src/ref/ref_misc.c b/feeds/ipq807x/qca-ssdk/src/src/ref/ref_misc.c new file mode 100755 index 000000000..5e05050d1 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/ref/ref_misc.c @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2012, 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 "fal_init.h" +#include "fal_misc.h" +#include "fal_mib.h" +#include "fal_port_ctrl.h" +#include "fal_portvlan.h" +#include "fal_fdb.h" +#include "fal_stp.h" +#include "fal_igmp.h" +#include "fal_qos.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "ssdk_init.h" +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) +#include +#else +#include +#include +#endif +#include +#include +#include +#include "ssdk_plat.h" +#include "ref_vlan.h" +#ifdef MP +#include +#include "hsl_phy.h" +#endif + +int +qca_ar8327_sw_set_max_frame_size(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct qca_phy_priv *priv = qca_phy_priv_get(dev); + a_uint32_t size = val->value.i; + a_uint32_t ret; + a_uint32_t port_id = SSDK_PHYSICAL_PORT0; + + if (priv->version == QCA_VER_HPPE) + { + for(port_id = SSDK_PHYSICAL_PORT1; port_id <= SSDK_PHYSICAL_PORT6; + port_id++) + { + ret = fal_port_max_frame_size_set(priv->device_id, + port_id, size); + if(ret) + { + return -1; + } + } + } + else if (priv->version == QCA_VER_SCOMPHY) + { +#ifdef MP + if(adapt_scomphy_revision_get(priv->device_id) + == MP_GEPHY) + { + for(port_id = SSDK_PHYSICAL_PORT1; port_id <= SSDK_PHYSICAL_PORT2; + port_id++) + { + ret = fal_port_max_frame_size_set(priv->device_id, + port_id, size); + if(ret) + { + return -1; + } + } + } +#endif + } + else + { + ret = fal_frame_max_size_set(priv->device_id, size); + if (ret) + { + return -1; + } + } + + return 0; +} + +int +qca_ar8327_sw_get_max_frame_size(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct qca_phy_priv *priv = qca_phy_priv_get(dev); + a_uint32_t size = 0; + a_uint32_t ret = 0; + + if (priv->version == QCA_VER_HPPE) + { + ret = fal_port_max_frame_size_get(priv->device_id, + SSDK_PHYSICAL_PORT1, &size); + } + else if (priv->version == QCA_VER_SCOMPHY) + { +#ifdef MP + if(adapt_scomphy_revision_get(priv->device_id) + == MP_GEPHY) + { + ret = fal_port_max_frame_size_get(priv->device_id, + SSDK_PHYSICAL_PORT1, &size); + } +#endif + } + else + { + ret = fal_frame_max_size_get(priv->device_id, &size); + } + if (ret){ + return -1; + } + + val->value.i = size; + + return 0; +} + +int +qca_ar8327_sw_reset_switch(struct switch_dev *dev) +{ + struct qca_phy_priv *priv = qca_phy_priv_get(dev); + int rv = 0; + a_uint32_t mac_mode; + + mutex_lock(&priv->reg_mutex); + + /* flush all vlan translation unit entries */ + fal_vlan_flush(priv->device_id); + + /* reset VLAN shadow */ + priv->vlan = 0; + memset(priv->vlan_id, 0, sizeof(a_uint16_t) * AR8327_MAX_VLANS); + memset(priv->vlan_table, 0, sizeof(a_uint8_t) * AR8327_MAX_VLANS); + memset(priv->vlan_tagged, 0, sizeof(a_uint8_t) * AR8327_MAX_VLANS); + memset(priv->pvid, 0, sizeof(a_uint16_t) * AR8327_NUM_PORTS); + + mutex_unlock(&priv->reg_mutex); + + priv->init = true; + rv += qca_ar8327_sw_hw_apply(dev); + priv->init = false; + + mac_mode = ssdk_dt_global_get_mac_mode(priv->device_id, 0); + /* set mac5 flowcontol force for RGMII */ + if ((mac_mode == PORT_WRAPPER_SGMII0_RGMII5) + ||(mac_mode == PORT_WRAPPER_SGMII1_RGMII5)) { + fal_port_flowctrl_forcemode_set(priv->device_id, 5, A_TRUE); + fal_port_flowctrl_set(priv->device_id, 5, A_TRUE); + } + /* set mac4 flowcontol force for RGMII */ + if ((mac_mode == PORT_WRAPPER_SGMII0_RGMII4) + ||(mac_mode == PORT_WRAPPER_SGMII1_RGMII4) + ||(mac_mode == PORT_WRAPPER_SGMII4_RGMII4)) { + /* fix channel4 will recieve packets when enable channel0 as SGMII */ + if(mac_mode == PORT_WRAPPER_SGMII0_RGMII4) { + fal_port_txmac_status_set (priv->device_id, 5, A_FALSE); + fal_port_rxmac_status_set (priv->device_id, 5, A_FALSE); + } + fal_port_flowctrl_forcemode_set(priv->device_id, 4, A_TRUE); + fal_port_flowctrl_set(priv->device_id, 4, A_TRUE); + } + + return rv; +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/ref/ref_port_ctrl.c b/feeds/ipq807x/qca-ssdk/src/src/ref/ref_port_ctrl.c new file mode 100755 index 000000000..e749897cd --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/ref/ref_port_ctrl.c @@ -0,0 +1,712 @@ +/* + * Copyright (c) 2012, 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 "ssdk_init.h" +#include "fal_init.h" +#include "fal_misc.h" +#include "fal_mib.h" +#include "fal_port_ctrl.h" +#include "fal_portvlan.h" +#include "fal_fdb.h" +#include "fal_stp.h" +#include "fal_igmp.h" +#include "fal_qos.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "hsl_phy.h" +#include "ssdk_init.h" +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) +#include +#else +#include +#endif +#include +#include +#include +#include "ssdk_plat.h" +#include "ref_vlan.h" +#include +#include "f1_phy.h" +#include "ref_port_ctrl.h" + +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) +#ifdef DESS +extern struct reset_control *ess_mac_clock_disable[5]; +#endif +#endif + +#if defined(IN_SWCONFIG) +int +qca_ar8327_sw_get_port_link(struct switch_dev *dev, int port, + struct switch_port_link *link) +{ + struct qca_phy_priv *priv = qca_phy_priv_get(dev); + + fal_port_speed_t speed = FAL_SPEED_10; + fal_port_duplex_t duplex = FAL_FULL_DUPLEX; + a_bool_t status = 0; + a_bool_t tx_fc = 0; + a_bool_t rx_fc = 0; + sw_error_t ret; + + mutex_lock(&priv->reg_mutex); + ret = fal_port_link_status_get(priv->device_id, port, &status); + if (ret == SW_OK) { + link->link = status; + } else { + mutex_unlock(&priv->reg_mutex); + return 0; + } + + ret = fal_port_speed_get(priv->device_id, port, &speed); + if (ret == SW_OK) { + if (speed == FAL_SPEED_10) { + link->speed = SWITCH_PORT_SPEED_10; + } else if (speed == FAL_SPEED_100) { + link->speed = SWITCH_PORT_SPEED_100; + } else if (speed == FAL_SPEED_1000) { + link->speed = SWITCH_PORT_SPEED_1000; + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) + } else if (speed == FAL_SPEED_2500) { + link->speed = SWITCH_PORT_SPEED_2500; + } else if (speed == FAL_SPEED_5000) { + link->speed = SWITCH_PORT_SPEED_5000; + } else if (speed == FAL_SPEED_10000) { + link->speed = SWITCH_PORT_SPEED_10000; + #endif + } else { + link->speed = SWITCH_PORT_SPEED_UNKNOWN; + } + } + + ret = fal_port_duplex_get(priv->device_id, port, &duplex); + if (ret == SW_OK) { + if (duplex == FAL_HALF_DUPLEX) { + link->duplex = 0; /* HALF */ + } else if (duplex == FAL_FULL_DUPLEX) { + link->duplex = 1; /* FULL */ + } + } + + ret = fal_port_rxfc_status_get(priv->device_id, port, &rx_fc); + if (ret == SW_OK) { + link->rx_flow = rx_fc; + } + + ret = fal_port_txfc_status_get(priv->device_id, port, &tx_fc); + if (ret == SW_OK) { + link->tx_flow = tx_fc; + } + mutex_unlock(&priv->reg_mutex); + + return 0; +} +#endif + +static int qca_switch_get_qm_status(struct qca_phy_priv *priv, a_uint32_t port_id, a_uint32_t *qm_buffer_err) +{ + a_uint32_t reg = 0; + a_uint32_t qm_val = 0; + + if (port_id < 0 || port_id > 6) { + *qm_buffer_err = 0; + return -1; + } + if (priv->version == 0x14) + { + if (port_id < 4) { + reg = 0x1D; + qca_switch_reg_write(priv->device_id, 0x820, (a_uint8_t *)®, 4); + qca_switch_reg_read(priv->device_id, 0x824, (a_uint8_t *)&qm_val, 4); + *qm_buffer_err = (qm_val >> (port_id * 8)) & 0xFF; + } else { + reg = 0x1E; + qca_switch_reg_write(priv->device_id, 0x820, (a_uint8_t *)®, 4); + qca_switch_reg_read(priv->device_id, 0x824, (a_uint8_t *)&qm_val, 4); + *qm_buffer_err = (qm_val >> ((port_id-4) * 8)) & 0xFF; + } + } + if (priv->version == QCA_VER_AR8337 || + priv->version == QCA_VER_AR8327) + { + if (port_id < 4) { + reg = 0x1D; + priv->mii_write(priv->device_id, 0x820, reg); + qm_val = priv->mii_read(priv->device_id, 0x824); + *qm_buffer_err = (qm_val >> (port_id * 8)) & 0xFF; + } else { + reg = 0x1E; + priv->mii_write(priv->device_id, 0x820, reg); + qm_val = priv->mii_read(priv->device_id, 0x824); + *qm_buffer_err = (qm_val >> ((port_id-4) * 8)) & 0xFF; + } + } + + return 0; +} + +static int qca_switch_force_mac_1000M_full(struct qca_phy_priv *priv, a_uint32_t port_id) +{ + a_uint32_t reg, value = 0; + + if (port_id < 0 || port_id > 6) + return -1; + if (priv->version == 0x14) + { + reg = AR8327_REG_PORT_STATUS(port_id); + qca_switch_reg_read(priv->device_id, reg, (a_uint8_t *)&value, 4); + value &= ~(BIT(6) | BITS(0,2)); + value |= AR8327_PORT_SPEED_1000M | BIT(6); + qca_switch_reg_write(priv->device_id, reg, (a_uint8_t *)&value, 4); + } + if (priv->version == QCA_VER_AR8337 || + priv->version == QCA_VER_AR8327) + { + reg = AR8327_REG_PORT_STATUS(port_id); + value = priv->mii_read(priv->device_id, reg); + value &= ~(BIT(6) | BITS(0,2)); + value |= AR8327_PORT_SPEED_1000M | BIT(6); + priv->mii_write(priv->device_id, reg, value); + } + return 0; +} + +static int qca_switch_force_mac_status(struct qca_phy_priv *priv, a_uint32_t port_id,a_uint32_t speed,a_uint32_t duplex) +{ + a_uint32_t reg, value = 0; + + if (port_id < 1 || port_id > 5) + return -1; + if (priv->version == 0x14) + { +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) +#ifdef DESS + /*disable mac clock*/ + reset_control_assert(ess_mac_clock_disable[port_id -1]); + udelay(10); + reg = AR8327_REG_PORT_STATUS(port_id); + qca_switch_reg_read(priv->device_id,reg,(a_uint8_t*)&value,4); + value &= ~(BIT(6) | BITS(0,2)); + value |= speed | (duplex?BIT(6):0); + qca_switch_reg_write(priv->device_id,reg,(a_uint8_t*)&value,4); + /*enable mac clock*/ + reset_control_deassert(ess_mac_clock_disable[port_id -1]); +#endif +#endif + } + if (priv->version == QCA_VER_AR8337 || + priv->version == QCA_VER_AR8327) + { + reg = AR8327_REG_PORT_STATUS(port_id); + value = priv->mii_read(priv->device_id, reg); + value &= ~(BIT(6) | BITS(0,2)); + value |= speed | (duplex?BIT(6):0); + priv->mii_write(priv->device_id, reg,value); + } + + return 0; +} + +a_bool_t +qca_ar8327_sw_rgmii_mode_valid(a_uint32_t dev_id, a_uint32_t port_id) +{ + a_uint32_t rgmii_mode; + + rgmii_mode = ssdk_dt_global_get_mac_mode(dev_id, 0); + + if(((rgmii_mode == PORT_WRAPPER_SGMII0_RGMII5) || + (rgmii_mode == PORT_WRAPPER_SGMII1_RGMII5)) && (port_id == 5)) + return A_TRUE; + + if(((rgmii_mode == PORT_WRAPPER_SGMII0_RGMII4) || + (rgmii_mode == PORT_WRAPPER_SGMII1_RGMII4) || + (rgmii_mode == PORT_WRAPPER_SGMII4_RGMII4)) && (port_id == 4)) + return A_TRUE; + + return A_FALSE; +} + +static int +qca_switch_get_mac_link(struct qca_phy_priv *priv, a_uint32_t port_id, a_uint32_t *link) +{ + a_uint32_t reg, value = 0; + + if (port_id < 0 || port_id > 6) + return -1; + if (priv->version == 0x14) + { + reg = AR8327_REG_PORT_STATUS(port_id); + qca_switch_reg_read(priv->device_id,reg,(a_uint8_t*)&value,4); + *link = (value>>8)&0x1; + } + if (priv->version == QCA_VER_AR8337 || + priv->version == QCA_VER_AR8327) + { + reg = AR8327_REG_PORT_STATUS(port_id); + value = priv->mii_read(priv->device_id, reg); + *link = (value>>8)&0x1; + } + + return 0; +} + + +#define MDI_FROM_PHY_STATUS 1 +#define MDI_FROM_MANUAL 0 +#define PORT_LINK_UP 1 +#define PORT_LINK_DOWN 0 + +#define QM_NOT_EMPTY 1 +#define QM_EMPTY 0 + + +static a_uint32_t phy_current_speed = 2; +static a_uint32_t phy_current_duplex = 1; + +#if defined(IN_VLAN) +int qca_ar8327_sw_enable_vlan0(a_uint32_t dev_id, a_bool_t enable, a_uint8_t portmap); +int qca_ar8327_vlan_recovery(struct qca_phy_priv *priv) +{ + fal_pbmp_t portmask[AR8327_NUM_PORTS]; + int i, j; + a_uint32_t reg, val; + u8 mask ; + + mutex_lock(&priv->reg_mutex); + + memset(portmask, 0, sizeof(portmask)); + if (!priv->init) { + /*Handle VLAN 0 entry*/ + if (priv->vlan_id[0] == 0 && priv->vlan_table[0] == 0) { + qca_ar8327_sw_enable_vlan0(priv->device_id,A_FALSE, 0); + } + + /* calculate the port destination masks and load vlans + * into the vlan translation unit */ + for (j = 0; j < AR8327_MAX_VLANS; j++) { + /* + //############################# VLAN -1 ######################### + //## VID=1 VLAN member : P1-t,P2-t,P3-t,P4-t,P5-t, P6-t + or 610 000AAAB0 + or 614 80010002 + */ + if (priv->vlan_id[j]) { + /* reg 0x610 VLAN_TABLE_FUNC0_OFFSET*/ + reg = 0x610; + val = 0x00180000; + for (i = 0; i < priv->ports; ++i) { + mask = (1 << i); + portmask[i] |= ~mask & priv->vlan_table[j]; + if (mask & priv->vlan_table[j]) + { + val |= ((mask & priv->vlan_tagged[j]) ? + FAL_EG_TAGGED : + FAL_EG_UNTAGGED) << ((i<<1) + 4); + } + else + val |= (0x3) << ((i << 1) + 4); // not member. + } + priv->mii_write(priv->device_id, reg, val); + + /* reg 0x614 VLAN_TABLE_FUNC1_OFFSET*/ + reg = 0x614; + val = 0x80000002; // load en entry + val |= priv->vlan_id[j] << 16; + priv->mii_write(priv->device_id, reg, val); + } + } + + /*Hanlde VLAN 0 entry*/ + if (priv->vlan_id[0] == 0 && priv->vlan_table[0]) { + qca_ar8327_sw_enable_vlan0(priv->device_id,A_TRUE, priv->vlan_table[0]); + } + + } else { +#if defined(IN_PORTVLAN) + /* vlan disabled: port based vlan used */ + ssdk_portvlan_init(priv->device_id); +#endif + } + +#if defined(IN_PORTVLAN) + /* update the port destination mask registers and tag settings */ + for (i = 0; i < priv->ports; i++) { + int pvid; + fal_pt_1qmode_t ingressMode; + fal_pt_1q_egmode_t egressMode; + + if (priv->vlan) { + pvid = priv->vlan_id[priv->pvid[i]]; + if (priv->vlan_tagged[priv->pvid[i]] & (1 << i)) { + egressMode = FAL_EG_TAGGED; + } else { + egressMode = FAL_EG_UNTAGGED; + } + + ingressMode = FAL_1Q_SECURE; + } else { + pvid = 0; + egressMode = FAL_EG_UNTOUCHED; + ingressMode = FAL_1Q_DISABLE; + } + + /*If VLAN 0 existes, change member port + *egress mode as UNTOUCHED*/ + if (priv->vlan_id[0] == 0 && + priv->vlan_table[0] && + ((0x1 << i) & priv->vlan_table[0]) && + priv->vlan) { + egressMode = FAL_EG_UNTOUCHED; + } + + fal_port_1qmode_set(priv->device_id, i, ingressMode); + fal_port_egvlanmode_set(priv->device_id, i, egressMode); + fal_port_default_cvid_set(priv->device_id, i, pvid); + if (!priv->init && priv->vlan) { + fal_portvlan_member_update(priv->device_id, i, portmask[i]); + } + } +#endif + + mutex_unlock(&priv->reg_mutex); + + return 0; +} +#endif + +int qca_qm_error_check(struct qca_phy_priv *priv) +{ + a_uint32_t value = 0, qm_err_int=0; + + if (priv->version == QCA_VER_AR8337 || + priv->version == QCA_VER_AR8327) + { + value = priv->mii_read(priv->device_id, 0x24); + qm_err_int = value & BIT(14); // b14-QM_ERR_INT + + if(qm_err_int) + return 1; + + priv->mii_write(priv->device_id, 0x820, 0x0); + value = priv->mii_read(priv->device_id, 0x824); + } + if(priv->version==0x14) + { + qca_switch_reg_read(priv->device_id, 0x24, (a_uint8_t*)&value, 4); + qm_err_int = value & BIT(14); // b14-QM_ERR_INT + + if(qm_err_int) + return 1; + value = 0; + qca_switch_reg_write(priv->device_id, 0x820, (a_uint8_t*)&value, 4); + qca_switch_reg_read(priv->device_id, 0x824, (a_uint8_t*)&value, 4); + } + return value; +} + +void qca_ar8327_phy_linkdown(a_uint32_t dev_id); +int qca_ar8327_hw_init(struct qca_phy_priv *priv); + +int qca_qm_err_recovery(struct qca_phy_priv *priv) +{ + memset(priv->port_link_down, 0, sizeof(priv->port_link_down)); + memset(priv->port_link_up, 0, sizeof(priv->port_link_up)); + memset(priv->port_old_link, 0, sizeof(priv->port_old_link)); + memset(priv->port_old_speed, 0, sizeof(priv->port_old_speed)); + memset(priv->port_old_duplex, 0, sizeof(priv->port_old_duplex)); + memset(priv->port_old_phy_status, 0, sizeof(priv->port_old_phy_status)); + memset(priv->port_qm_buf, 0, sizeof(priv->port_qm_buf)); + + /* in soft reset recovery procedure */ + qca_ar8327_phy_linkdown(priv->device_id); + + qca_ar8327_hw_init(priv); + +#if defined(IN_VLAN) + qca_ar8327_vlan_recovery(priv); +#endif + + /*To add customerized recovery codes*/ + + return 1; +} + +a_bool_t +qca_ar8327_sw_mac_polling_port_valid(struct qca_phy_priv *priv, a_uint32_t port_id) +{ + a_uint32_t mac_mode; + + mac_mode = ssdk_dt_global_get_mac_mode(priv->device_id, 0); + + if( port_id >= AR8327_NUM_PORTS-1 || port_id < 1) + return A_FALSE; + + if(((mac_mode == PORT_WRAPPER_SGMII0_RGMII5) || + (mac_mode == PORT_WRAPPER_SGMII1_RGMII5)) && (port_id != 5)) + return A_FALSE; + + if(((mac_mode == PORT_WRAPPER_SGMII0_RGMII4) || + (mac_mode == PORT_WRAPPER_SGMII1_RGMII4) || + (mac_mode == PORT_WRAPPER_SGMII4_RGMII4)) && (port_id != 4)) + return A_FALSE; + + return A_TRUE; +} +void +qca_phy_status_get(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t *speed_status, a_uint32_t *link_status, a_uint32_t *duplex_status) +{ + a_uint16_t port_phy_status; + a_uint32_t phy_addr; + + phy_addr = qca_ssdk_port_to_phy_addr(dev_id, port_id); + if (qca_ar8327_sw_rgmii_mode_valid(dev_id, port_id) == A_TRUE) + phy_addr = 4; + + qca_ar8327_phy_read(dev_id, phy_addr, F1_PHY_SPEC_STATUS, &port_phy_status); + *speed_status = (a_uint32_t)((port_phy_status >> 14) & 0x03); + *link_status = (a_uint32_t)((port_phy_status & BIT(10)) >> 10); + *duplex_status = (a_uint32_t)((port_phy_status & BIT(13)) >> 13); +} + +/* Initialize notifier list for QCA SSDK */ +static BLOCKING_NOTIFIER_HEAD(ssdk_port_link_notifier_list); + +int ssdk_port_link_notify(unsigned char port_id, + unsigned char link, unsigned char speed, unsigned char duplex) +{ + ssdk_port_status port_status; + + port_status.port_id = port_id; + port_status.port_link = link; + port_status.speed = speed; + port_status.duplex = duplex; + + return blocking_notifier_call_chain(&ssdk_port_link_notifier_list, 0, &port_status); +} + +int ssdk_port_link_notify_register(struct notifier_block *nb) +{ + return blocking_notifier_chain_register(&ssdk_port_link_notifier_list, nb); +} +EXPORT_SYMBOL(ssdk_port_link_notify_register); + +int ssdk_port_link_notify_unregister(struct notifier_block *nb) +{ + return blocking_notifier_chain_unregister(&ssdk_port_link_notifier_list, nb); +} +EXPORT_SYMBOL(ssdk_port_link_notify_unregister); + + +void +qca_ar8327_sw_mac_polling_task(struct qca_phy_priv *priv) +{ + static int task_count = 0; + a_uint32_t i, dev_id = 0; + a_uint32_t value; + a_uint32_t link = 0, speed = 0, duplex = 0; + a_uint32_t qm_buffer_err = 0, phy_addr = 0; + a_uint16_t port_phy_status[AR8327_NUM_PORTS] = {0,0,0,0,0,0,0}; + static a_uint32_t qm_err_cnt[AR8327_NUM_PORTS] = {0,0,0,0,0,0,0}; + + static a_uint32_t link_cnt[AR8327_NUM_PORTS] = {0,0,0,0,0,0,0}; + + dev_id = priv->device_id; + + /*Only valid for S17c chip*/ + if (priv->version != QCA_VER_AR8337 && + priv->version != QCA_VER_AR8327 && + priv->version != 0x14) + return; + + value = qca_qm_error_check(priv); + if(value) + { + if(priv->version != 0x14) + qca_qm_err_recovery(priv); + return; + } + + ++task_count; + + for (i = 1; i < AR8327_NUM_PORTS-1; i++) { + phy_addr = qca_ssdk_port_to_phy_addr(dev_id, i); + if(qca_ar8327_sw_mac_polling_port_valid(priv, i) == A_FALSE) + continue; + + if (qca_ar8327_sw_rgmii_mode_valid(dev_id, i) == A_FALSE) + qca_switch_get_mac_link(priv, i, &link); + else + { + qca_phy_status_get(dev_id, i, &speed, &link, &duplex); + } + if (link != priv->port_old_link[i]) { + if (qca_ar8327_sw_rgmii_mode_valid(dev_id, i) == A_FALSE) + { + qca_phy_status_get(dev_id, i, &speed, &link, &duplex); + } + ++link_cnt[i]; + /* Up --> Down */ + if ((priv->port_old_link[i] == PORT_LINK_UP) && (link == PORT_LINK_DOWN)) { + + if (qca_ar8327_sw_rgmii_mode_valid(dev_id, i) == A_TRUE) + { + fal_port_rxmac_status_set(dev_id, i, A_FALSE); + fal_port_txmac_status_set(dev_id, i, A_FALSE); + } + else + { + fal_port_link_forcemode_set(dev_id, i, A_TRUE); + SSDK_DEBUG("%s, %d, port_id %d link down\n",__FUNCTION__,__LINE__,i); + } + priv->port_link_down[i]=0; + ssdk_port_link_notify(i, 0, 0, 0); +#ifdef IN_FDB + fal_fdb_del_by_port(dev_id, i, 0);/*flush all dynamic fdb of this port*/ +#endif + if(priv->version != 0x14){ + /* Check queue buffer */ + a_uint16_t value = 0; + qm_err_cnt[i] = 0; + qca_switch_get_qm_status(priv, i, &qm_buffer_err); + + if (qm_buffer_err) { + priv->port_qm_buf[i] = QM_NOT_EMPTY; + } + else { + priv->port_qm_buf[i] = QM_EMPTY; + + /* Force MAC 1000M Full before auto negotiation */ + qca_switch_force_mac_1000M_full(priv, i); + mdelay(10); + SSDK_DEBUG("%s, %d, port %d link down\n",__FUNCTION__,__LINE__,i); + } + qca_ar8327_phy_dbg_read(dev_id, phy_addr, 0, &value); + value &= (~(1<<12)); + qca_ar8327_phy_dbg_write(dev_id, phy_addr, 0, value); + } + } + /* Down --> Up */ + else if ((priv->port_old_link[i] == PORT_LINK_DOWN) && (link == PORT_LINK_UP)) { + + if (priv->port_link_up[i] < 1) { + ++(priv->port_link_up[i]); + qca_switch_get_qm_status(priv, i, &qm_buffer_err); + if (qm_buffer_err) { + if(priv->version != 0x14) + qca_qm_err_recovery(priv); + if(priv->link_polling_required) + return; + } + } + if(priv->port_link_up[i] >=1) + { + priv->port_link_up[i]=0; + qca_switch_force_mac_status(priv, i, speed, duplex); + udelay(100); + if (qca_ar8327_sw_rgmii_mode_valid(dev_id, i) == A_FALSE) { + fal_port_link_forcemode_set(dev_id, i, A_FALSE); + } + else + { + fal_port_rxmac_status_set(dev_id, i, A_TRUE); + fal_port_txmac_status_set(dev_id, i, A_TRUE); + } + udelay(100); + SSDK_DEBUG("%s, %d, port %d link up speed %d, duplex %d\n",__FUNCTION__,__LINE__,i, speed, duplex); + ssdk_port_link_notify(i, 1, speed, duplex); + if((speed == 0x01) && (priv->version != 0x14))/*PHY is link up 100M*/ + { + a_uint16_t value = 0; + qca_ar8327_phy_dbg_read(dev_id, phy_addr, 0, &value); + value |= (1<<12); + qca_ar8327_phy_dbg_write(dev_id, phy_addr, 0, value); + } + } + } + if ((priv->port_link_down[i] == 0) + && (priv->port_link_up[i] == 0)){ + /* Save the current status */ + priv->port_old_speed[i] = speed; + priv->port_old_link[i] = link; + priv->port_old_duplex[i] = duplex; + priv->port_old_phy_status[i] = port_phy_status[i]; + } + } + + if (priv->port_qm_buf[i] == QM_NOT_EMPTY) { + /* Check QM */ + qca_switch_get_qm_status(priv, i, &qm_buffer_err); + if (qm_buffer_err) { + priv->port_qm_buf[i] = QM_NOT_EMPTY; + ++qm_err_cnt[i]; + } + else { + priv->port_qm_buf[i] = QM_EMPTY; + qm_err_cnt[i] = 0; + + /* Force MAC 1000M Full before auto negotiation */ + qca_switch_force_mac_1000M_full(priv, i); + } + } + } + return ; +} + +void +dess_rgmii_sw_mac_polling_task(struct qca_phy_priv *priv) +{ + a_uint32_t mac_mode; + a_uint16_t phy_spec_status, phy_link_status; + a_uint32_t speed, duplex; + + mac_mode = ssdk_dt_global_get_mac_mode(priv->device_id, 0); + + if ((mac_mode == PORT_WRAPPER_SGMII0_RGMII5) + ||(mac_mode == PORT_WRAPPER_SGMII1_RGMII5) + ||(mac_mode == PORT_WRAPPER_SGMII0_RGMII4) + ||(mac_mode == PORT_WRAPPER_SGMII1_RGMII4) + ||(mac_mode == PORT_WRAPPER_SGMII4_RGMII4)) { + qca_ar8327_phy_read(priv->device_id, 4, 0x11, &phy_spec_status); + phy_link_status = (a_uint16_t)((phy_spec_status & BIT(10)) >> 10); + if (phy_link_status == 1) { + speed = (a_uint32_t)((phy_spec_status >> 14) & 0x03); + duplex = (a_uint32_t)((phy_spec_status & BIT(13)) >> 13); + if ((speed != phy_current_speed) || (duplex != phy_current_duplex)) { + if ((mac_mode == PORT_WRAPPER_SGMII0_RGMII5) + ||(mac_mode == PORT_WRAPPER_SGMII1_RGMII5)) + qca_switch_force_mac_status(priv, 5,speed,duplex); + + if ((mac_mode == PORT_WRAPPER_SGMII0_RGMII4) + ||(mac_mode == PORT_WRAPPER_SGMII1_RGMII4) + ||(mac_mode == PORT_WRAPPER_SGMII4_RGMII4)) + qca_switch_force_mac_status(priv, 4,speed,duplex); + } + phy_current_speed = speed; + phy_current_duplex = duplex; + } + } + + return; +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/ref/ref_uci.c b/feeds/ipq807x/qca-ssdk/src/src/ref/ref_uci.c new file mode 100644 index 000000000..4276d1e4d --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/ref/ref_uci.c @@ -0,0 +1,11809 @@ +/* + * Copyright (c) 2013, 2015, 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 "sw.h" +#include "ssdk_init.h" +#include "fal_init.h" +#ifdef IN_MISC +#include "fal_misc.h" +#endif +#ifdef IN_MIB +#include "fal_mib.h" +#endif +#ifdef IN_PORTCONTROL +#include "fal_port_ctrl.h" +#endif +#ifdef IN_PORTVLAN +#include "fal_portvlan.h" +#endif +#ifdef IN_FDB +#include "fal_fdb.h" +#endif +#ifdef IN_STP +#include "fal_stp.h" +#endif +#ifdef IN_IGMP +#include "fal_igmp.h" +#endif +#ifdef IN_QOS +#include "fal_qos.h" +#endif +#ifdef IN_ACL +#include "fal_acl.h" +#endif +#ifdef IN_PPPOE +#include "fal_pppoe.h" +#endif +#ifdef IN_SERVCODE +#include "fal_servcode.h" +#endif +#ifdef IN_CTRLPKT +#include "fal_ctrlpkt.h" +#endif +#ifdef IN_POLICER +#include "fal_policer.h" +#endif +#ifdef IN_SHAPER +#include "fal_shaper.h" +#endif +#include "hsl.h" +#include "hsl_dev.h" +#include "ssdk_init.h" +#include "shell.h" +#include "shell_io.h" +#include "shell_sw.h" +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) +#include +#else +#include +#include +#endif +#include +#include +#include +#include "ssdk_plat.h" +#include +#include "ref_uci.h" + +#define MOD_NAME_MAX_LEN 32 +#define COMMAND_NAME_MAX_LEN 128 +#define COMMAND_LINE_MAX_LEN 1024 +#define SWITCH_CFG_LEN_MAX 64 +char module_name[MOD_NAME_MAX_LEN] = {0}; +char command_name[COMMAND_NAME_MAX_LEN] = {0}; +char whole_command_line[COMMAND_LINE_MAX_LEN] = {0}; +char *val_ptr[SWITCH_CFG_LEN_MAX] = {0}; +static unsigned int parameter_length = 0; +#ifdef IN_NAT +static char *vrf_dflt_str = "0"; +static char *lb_dflt_str = "0"; +static char *cookie_dflt_str = "0"; +static char *priority_dflt_str = "no"; +static char *param_dflt_str = " "; +#endif + +#ifdef IN_QOS +#ifndef IN_QOS_MINI +static int +parse_qos_qtxbufsts(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "buffer_limit")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qos_qtxbufnr(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "queue_id")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "number")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qos_pttxbufsts(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "buffer_limit")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qos_pttxbufnr(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "number")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qos_ptrxbufnr(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "number")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qos_ptreden(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "red_status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qos_ptmode(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "mode")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "status")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qos_ptmodepri(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "mode")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "priority")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qos_ptschmode(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "mode")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "weight")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qos_ptdefaultspri(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "stag_pri")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qos_ptdefaultcpri(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "ctag_pri")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qos_ptfsprists(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "force_stag_pri_status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qos_ptfcprists(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "force_ctag_pri_status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qos_ptquremark(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "queue_id")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "table_id")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "status")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qos_ptgroup(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "pcpgroup")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "dscpgroup")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "flowgroup")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qos_ptpri(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "pcpprec")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "dscpprec")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "preheaderprec")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "flowprec")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "aclprec")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "postaclprec")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "pcpprecforce")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "dscpprecforce")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qos_ptremark(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "pcp_change_en")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "dei_change_en")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "dscp_change_en")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +static int +parse_qos_pcpmap(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "group_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "pcp")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "internalpcp")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "internaldei")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "internalpri")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "internaldscp")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "internaldropprec")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "dscpmask")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "dscpen")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "pcpen")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "deien")) { + val_ptr[10] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "prien")) { + val_ptr[11] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "dpen")) { + val_ptr[12] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "qosprec")) { + val_ptr[13] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qos_flowmap(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "group_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "flow_id")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "internalpcp")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "internaldei")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "internalpri")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "internaldscp")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "internaldropprec")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qos_dscpmap(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "group_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "dscp")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "internalpcp")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "internaldei")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "internalpri")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "internaldscp")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "internaldropprec")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qos_qscheduler(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "node_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "level")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "spid")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "edrrpri")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "cdrrpri")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "cdrr_id")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "edrr_id")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "edrrweight")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "cdrrweight")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "cdrrunit")) { + val_ptr[10] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "edrrunit")) { + val_ptr[11] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "drr_frame_mode")) { + val_ptr[12] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qos_ringqueue(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "ring_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "queuebmp0")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "queuebmp1")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "queuebmp2")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "queuebmp3")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "queuebmp4")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "queuebmp5")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "queuebmp6")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "queuebmp7")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "queuebmp8")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "queuebmp9")) { + val_ptr[10] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qos_dequeue(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "queue_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "dequeue_ctrl_en")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qos_portscheduler(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +#endif +#endif + +#ifdef IN_COSMAP +static int +parse_cos_mappri2q(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "pri")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "queue")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_cos_mappri2ehq(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "pri")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "enhance_queue")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +#ifndef IN_COSMAP_MINI +static int +parse_cos_mapdscp2pri(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "dscp")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "pri")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_cos_mapdscp2dp(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "dscp")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "cfi")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_cos_mapup2pri(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "up")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "pri")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_cos_mapup2dp(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "up")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "cfi")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_cos_mapdscp2ehpri(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "dscp")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "pri")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_cos_mapdscp2ehdp(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "dscp")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "cfi")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_cos_mapup2ehpri(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "up")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "pri")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_cos_mapup2ehdp(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "up")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "cfi")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_cos_mapegremark(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "remark_dscp")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "remark_up")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "remark_dei")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "green_dscp")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "yellow_dscp")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "green_up")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "yellow_up")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "green_dei")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "yellow_dei")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#endif +#endif + +#ifdef IN_RATE +static int +parse_rate_portpolicer(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "combine_enable")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "byte_based")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "couple_flag")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "color_aware")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "deficit_flag")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "c_bucket_enable")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "cir")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "cbs")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "c_rate_flag")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "c_meter_interval")) { + val_ptr[10] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "e_bucket_enable")) { + val_ptr[11] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "eir")) { + val_ptr[12] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "ebs")) { + val_ptr[13] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "e_rate_flag")) { + val_ptr[14] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "e_meter_interval")) { + val_ptr[15] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_rate_portshaper(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "byte_based")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "cir")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "cbs")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "eir")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "ebs")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_rate_queueshaper(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "queue_id")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "status")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "byte_based")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "cir")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "cbs")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "eir")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "ebs")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_rate_aclpolicer(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "policer_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "counter_mode")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "byte_based")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "couple_flag")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "color_aware")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "deficit_flag")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "cir")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "cbs")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "eir")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "ebs")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "meter_interval")) { + val_ptr[10] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_rate_ptaddratebyte(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "add_rate_bytes")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_rate_ptgolflowen(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "golbal_flow_control_status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#endif + +#ifdef IN_PORTCONTROL +#ifndef IN_PORTCONTROL_MINI +static int +parse_port_duplex(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "duplex")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_speed(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "speed")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_autoadv(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "auto_adv")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_autonegenable(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_autonegrestart(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#endif +static int +parse_port_txhdr(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "tx_frame_atheros_header_tag_status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_rxhdr(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "rx_frame_atheros_header_tag_status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_hdrtype(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "atheros_header_tag_status")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "atheros_header_tag_type")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#ifndef IN_PORTCONTROL_MINI +static int +parse_port_flowctrl(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "flow_control_status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_flowctrlforcemode(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "flow_control_force_mode_status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_powersave(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "power_save_status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_hibernate(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "hibernate_status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_txmacstatus(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "tx_mac_status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_rxmacstatus(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "rx_mac_status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_txfcstatus(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "tx_flow_control_status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_rxfcstatus(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "rx_flow_control_status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#endif +#ifndef IN_PORTCONTROL_MINI +static int +parse_port_bpstatus(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "back_presure_status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_linkforcemode(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "link_force_mode_status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_macloopback(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "mac_loopback_status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_congedrop(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "queue_id")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "status")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_ringfcthresh(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "ring_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "on_thresh")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "off_thresh")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + + + +static int +parse_port_ieee8023az(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "mode")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_crossover(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "mode")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_prefermedium(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "mode")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_fibermode(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "mode")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_localloopback(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "mode")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_remoteloopback(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "mode")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_magicframemac(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "macaddr")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_wolstatus(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "mode")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_interfacemode(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "mode")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_interfacemodeapply(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_poweron(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_poweroff(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_reset(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_interface8023az(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "mode")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_promiscmode(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "promisc_mode")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +static int +parse_port_eeecfg(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "eee_en")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "eee_capability")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "lpi_sleep_timer")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "advertisement")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "lpi_tx_en")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "eee_status")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "lpi_wakeup_timer")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "link_partner_advertisement")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_srcfiltercfg(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "srcfilter_enable")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "srcfilter_mode")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_framemaxsize(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "frame_max_size")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_mtu(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "mtusize")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "mtuaction")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_mru(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "mrusize")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "mruaction")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_port_srcfilter(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "status_en")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_switch_port_loopback(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "loopback_en")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "crc_stripped_en")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "loopback_rate")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +#endif +#endif + +#ifdef IN_PORTVLAN +static int +parse_portvlan_ingress(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "ingress_vlan_mode")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_portvlan_egress(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "egress_vlan_mode")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_portvlan_member(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "member")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_portvlan_forcevid(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "force_vid_status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_portvlan_forcemode(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "force_mode")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_portvlan_svlantpid(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "stag_tpid")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +static int +parse_portvlan_defaultsvid(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "default_stag_vid")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +static int +parse_portvlan_defaultcvid(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "default_ctag_vid")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_portvlan_globalqinqmode(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "mask")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ingress_qinq_mode")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "egress_qinq_mode")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_portvlan_ptqinqmode(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "mask")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ingress_qinq_role")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "egress_qinq_role")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#ifdef HPPE +static int +parse_portvlan_intpid(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "mask")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ctagtpid")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "stagtpid")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_portvlan_egtpid(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "mask")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ctagtpid")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "stagtpid")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_portvlan_ingressfilter(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "membership_filter_en")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "tagged_filter_en")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "untagged_filter_en")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "priority_tagged_filter_en")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_portvlan_defaultvlantag(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "direction")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "default_ctag_vid_en")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "default_stag_vid_en")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "mask")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "default_ctag_vid")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "default_stag_vid")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "default_ctag_pri")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "default_stag_pri")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "default_ctag_dei")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "default_stag_dei")) { + val_ptr[10] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_portvlan_tagpropagation(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "direction")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "mask")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "vid_propagation_en")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "pri_propagation_en")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "dei_propagation_en")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_portvlan_translationmissaction(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "translation_miss_action")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#endif +static int +parse_portvlan_egmode(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "mask")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ctag_egress_vlan_mode")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "stag_egress_vlan_mode")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#ifdef HPPE +static int +parse_portvlan_vsiegmode(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "vsi")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "vsi_egress_vlan_mode")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_portvlan_vsiegmodeen(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "vsi_egress_vlan_mode_en")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_portvlan_counter(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "index")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_portvlan_translationadv(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "direction")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "stagformat")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "svid_en")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "svid")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "spcp_en")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "spcp")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "sdei_en")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "sdei")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ctagformat")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "cvid_en")) { + val_ptr[10] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "cvid")) { + val_ptr[11] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "cpcp_en")) { + val_ptr[12] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "cpcp")) { + val_ptr[13] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "cdei_en")) { + val_ptr[14] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "cdei")) { + val_ptr[15] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "frame_type_en")) { + val_ptr[16] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "frametype")) { + val_ptr[17] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "protocol_en")) { + val_ptr[18] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "protocol")) { + val_ptr[19] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "vsivalid")) { + val_ptr[20] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "vsi_en")) { + val_ptr[21] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "vsi")) { + val_ptr[22] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "swap_svid_cvid")) { + val_ptr[23] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "svid_translation_cmd")) { + val_ptr[24] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "svidtranslation")) { + val_ptr[25] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "cvid_translation_cmd")) { + val_ptr[26] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "cvidtranslation")) { + val_ptr[27] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "swap_spcp_cpcp")) { + val_ptr[28] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "spcp_translation_en")) { + val_ptr[29] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "spcptranslation")) { + val_ptr[30] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "cpcp_translation_en")) { + val_ptr[31] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "cpcptranslation")) { + val_ptr[32] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "swap_sdei_cdei")) { + val_ptr[33] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "sdei_translation_en")) { + val_ptr[34] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "sdeitranslation")) { + val_ptr[35] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "cdei_translation_en")) { + val_ptr[36] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "cdeitranslation")) { + val_ptr[37] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "counter_en")) { + val_ptr[38] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "counter_id")) { + val_ptr[39] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "vsi_translation_en")) { + val_ptr[40] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "vsitranslation")) { + val_ptr[41] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#endif +#ifndef IN_PORTVLAN_MINI +static int +parse_portvlan_invlan(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "ingress_tag_mode")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_portvlan_tlsmode(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "tls_mode")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_portvlan_pripropagation(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "vlan_priority_propagation_status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + + + +static int +parse_portvlan_vlanpropagation(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "vlan_propagation_mode")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_portvlan_translation(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "original_vid")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "bi_direction")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "forward_direction")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "reverse_direction")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "svid")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "cvid")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "original_vid_is_cvid")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "svid_enable")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "cvid_enable")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "one_2_one_vlan")) { + val_ptr[10] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_portvlan_qinqmode(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "qinq_mode")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_portvlan_qinqrole(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "qinq_role")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_portvlan_macvlanxlt(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "egress_mac_based_vlan")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_portvlan_netiso(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "net_isolate")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_portvlan_egbypass(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "egress_translation_filter_bypass")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_portvlan_ptvrfid(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "vrf_id")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#endif +#endif + +#ifdef IN_VLAN +static int +parse_vlan_entry(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "vlan_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_vlan_member(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "vlan_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "tag_mode")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#ifndef IN_VLAN_MINI +static int +parse_vlan_learnsts(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "vlan_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "learn_status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#endif +#endif + +#ifdef IN_FDB +#ifndef IN_FDB_MINI +static int +parse_fdb_entry(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "addr")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "fid")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "dacmd")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "sacmd")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "dest_port")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "static")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "leaky")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "mirror")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "clone")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "queue_override")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "cross_pt_state")) { + val_ptr[10] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "white_list_en")) { + val_ptr[11] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "load_balance_en")) { + val_ptr[12] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "load_balance")) { + val_ptr[13] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + if(val_ptr[12] == NULL) { + val_ptr[12] = "no"; + parameter_length++; + } + return rv; +} + +static int +parse_fdb_resventry(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "addr")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "fid")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "dacmd")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "sacmd")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "dest_port")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "static")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "leaky")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "mirror")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "clone")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "queue_override")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "cross_pt_state")) { + val_ptr[10] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "white_list_en")) { + val_ptr[11] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#endif +static int +parse_fdb_portlearn(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "learn_status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#ifndef IN_FDB_MINI +static int +parse_fdb_agectrl(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "aging_status")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_fdb_agetime(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "aging_time")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_fdb_vlansmode(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "vlan_searching_mode")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_fdb_ptlearnlimit(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "learn_limit_status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "learn_limit_counter")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_fdb_ptlearnexceedcmd(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "learn_exceed_cmd")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_fdb_learnlimit(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "learn_limit_status")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "learn_limit_counter")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_fdb_learnexceedcmd(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "learn_exceed_cmd")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_fdb_ptlearnstatic(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "learn_static_status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_fdb_learnctrl(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "learn_status")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_fdb_ptlearnctrl(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "learn_status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "learnaction")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_fdb_ptstationmove(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "stationmove_en")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "stationmove_action")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_fdb_ptmaclimitctrl(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "maclimit_status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "maclimit_counter")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "maclimit_exceed_action")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#endif +#endif + +#ifdef IN_RSS_HASH +static int +parse_rsshash_config(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "hash_mode")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "hask_mask")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "hash_fragment_mode")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "hash_seed")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "hash_sip_mix")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "hash_dip_mix")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "hash_protocol_mix")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "hash_sport_mix")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "hash_dport_mix")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "hash_fin_inner")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "hash_fin_outer")) { + val_ptr[10] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#endif + +#ifdef IN_IGMP +static int +parse_igmp_mode(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "igmp_mode")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_igmp_cmd(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "igmp_command")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_igmp_portjoin(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "join_status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_igmp_portleave(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "leave_status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_igmp_rp(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "route_port_bitmap")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_igmp_createstatus(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "create_status")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_igmp_static(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "static_status")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_igmp_leaky(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "leaky_status")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_igmp_version3(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "version3_status")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_igmp_queue(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "status")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "queue_id")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_igmp_ptlearnlimit(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "learn_limit_status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "learn_limit_counter")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_igmp_ptlearnexceedcmd(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "learn_exceed_cmd")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_igmp_multi(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "group_type")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "group_ip_addr")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "source_type")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "source_ip_addr")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "portmap")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "vlanid")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#endif + +#ifdef IN_SEC +static int +parse_sec_mac(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "item")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "value")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_sec_ip(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "item")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "value")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_sec_ip4(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "item")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "value")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_sec_ip6(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "item")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "value")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_sec_tcp(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "item")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "value")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_sec_udp(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "item")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "value")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_sec_icmp4(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "item")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "value")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_sec_icmp6(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "item")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "value")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#ifdef HPPE +static int +parse_sec_expctrl(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "excep_type")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "excep_cmd")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "deacclr_en")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "l3route_only_en")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "l2fwd_only_en")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "l2flow_en")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "l3flow_en")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "multicast_en")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_sec_l3parser(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "small_ip4ttl")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "small_ip6hoplimit")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_sec_l4parser(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "tcpflag0")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "tcpflag0_mask")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "tcpflag1")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "tcpflag1_mask")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "tcpflag2")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "tcpflag2_mask")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "tcpflag3")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "tcpflag3_mask")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "tcpflag4")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "tcpflag4_mask")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "tcpflag5")) { + val_ptr[10] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "tcpflag5_mask")) { + val_ptr[11] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "tcpflag6")) { + val_ptr[12] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "tcpflag6_mask")) { + val_ptr[13] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "tcpflag7")) { + val_ptr[14] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "tcpflag7_mask")) { + val_ptr[15] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#endif +#endif + +#ifdef IN_MISC +#ifndef IN_MISC_MINI +static int +parse_misc_framemaxsize(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "frame_max_size")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#endif +static int +parse_misc_ptunkucfilter(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_misc_ptunkmcfilter(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_misc_ptbcfilter(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#ifndef IN_MISC_MINI +static int +parse_misc_autoneg(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#endif +static int +parse_misc_cpuport(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "status")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#ifndef IN_MISC_MINI +static int +parse_misc_pppoecmd(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "action")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_misc_pppoe(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "status")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_misc_ptdhcp(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_misc_arpcmd(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "action")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#endif +static int +parse_misc_eapolcmd(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "action")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_misc_eapolstatus(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#ifndef IN_MISC_MINI +static int +parse_misc_rip(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "status")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_misc_ptarpreq(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_misc_ptarpack(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_misc_extendpppoe(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "entry_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "session_id")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "multicast_session")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "unicast_session")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "vrf_id")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "port")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "l3if_index")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "l3if_index_valid")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "smacaddr")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "smacaddr_valid")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_misc_pppoeid(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "index")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "pppoe_id")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_misc_cpuvid(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "status")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_misc_rtdpppoe(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "status")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_misc_glomacaddr(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "macaddr")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_misc_framecrc(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "status")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_misc_pppoeen(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "l3if_index")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "pppoe_en")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#endif +#endif + +#ifdef IN_IP +#ifndef IN_IP_MINI +static int +parse_ip_hostentry(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + char* vrf_temp = "0"; + val_ptr[6] = vrf_temp; + parameter_length ++; + val_ptr[7] = vrf_temp; + parameter_length ++; + val_ptr[12] = param_dflt_str; + parameter_length ++; + val_ptr[13] = vrf_temp; + parameter_length ++; + val_ptr[14] = vrf_temp; + parameter_length ++; + val_ptr[15] = vrf_temp; + parameter_length ++; + val_ptr[16] = param_dflt_str; + parameter_length ++; + val_ptr[17] = param_dflt_str; + parameter_length ++; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "entry_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "entry_flags")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "entry_status")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "ip_addr")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "mac_addr")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "interface_id")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "load_balance_num")) { + val_ptr[6] = (char*)ext_value_p->option_value; + parameter_length --; + } else if(!strcmp(ext_value_p->option_name, "vrf_id")) { + val_ptr[7] = (char*)ext_value_p->option_value; + parameter_length --; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "action")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "mirror")) { + val_ptr[10] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "counter")) { + val_ptr[11] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "counter_id")) { + val_ptr[12] = (char*)ext_value_p->option_value; + parameter_length --; + } else if (!strcmp(ext_value_p->option_name, "dstinfo")) { + val_ptr[13] = (char*)ext_value_p->option_value; + parameter_length --; + } else if (!strcmp(ext_value_p->option_name, "synctoggle")) { + val_ptr[14] = (char*)ext_value_p->option_value; + parameter_length --; + } else if (!strcmp(ext_value_p->option_name, "lan_wan")) { + val_ptr[15] = (char*)ext_value_p->option_value; + parameter_length --; + } else if (!strcmp(ext_value_p->option_name, "vsi")) { + val_ptr[16] = (char*)ext_value_p->option_value; + parameter_length --; + } else if (!strcmp(ext_value_p->option_name, "sip_addr")) { + val_ptr[17] = (char*)ext_value_p->option_value; + parameter_length --; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_ip_intfentry(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + char* vrf_temp = "0"; + val_ptr[1] = vrf_temp; + parameter_length ++; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "entry_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "vrf_id")) { + val_ptr[1] = (char*)ext_value_p->option_value; + parameter_length --; + } else if(!strcmp(ext_value_p->option_name, "vlan_low")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "vlan_high")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "mac_addr")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "ipv4_route")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "ipv6_route")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_ip_ptarplearn(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_ip_arplearn(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "mode")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_ip_ptipsrcguard(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "source_guard_mode")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_ip_ptarpsrcguard(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "source_guard_mode")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_ip_routestatus(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "status")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_ip_ipunksrc(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "action")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_ip_arpunksrc(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "action")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_ip_agetime(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "age_time")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_ip_wcmphashmode(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "wcmp_hash_mode")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_ip_defaultflowcmd(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "vrf_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "flow_type")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "flow_cmd")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_ip_defaultrtflowcmd(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "vrf_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "flow_type")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "flow_cmd")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_ip_hostroute(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "entry_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "entry_valid")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "vrf_id")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "ip_version")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "ip_addr")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "prefix_length")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_ip_defaultroute(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "entry_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "entry_valid")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "vrf_id")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "route_type")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "index")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_ip_vrfbaseaddr(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "vrf_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "base_addr")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_ip_vrfbasemask(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "vrf_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "base_mask")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_ip_rfsip4(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "mac_addr")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "ip4_addr")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "vlan_id")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "load_balance")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_ip_rfsip6(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "mac_addr")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "ip6_addr")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "vlan_id")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "load_balance")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_ip_vsiarpsg(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "vsi")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip4_arp_sourceguard_en")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip4_arp_sourceguard_violation_action")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip4_arp_sourceguard_port_en")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip4_arp_sourceguard_svlan_en")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip4_arp_sourcegurad_cvlan_en")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip4_arp_sourceunkown_action")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip6_nd_sourceguard_en")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip6_nd_sourceguard_violation_action")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip6_nd_sourceguard_port_en")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip6_nd_sourceguard_svlan_en")) { + val_ptr[10] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip6_nd_sourceguard_cvlan_en")) { + val_ptr[11] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip6_nd_sourceunknown_action")) { + val_ptr[12] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_ip_vsisg(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "vsi")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip4_sourceguard_en")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip4_sourcegurad_violation_action")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip4_sourceguard_port_en")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip4_sourceguard_svlan_en")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip4_sourceguard_cvlan_en")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip4_sourceunkown_action")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip6_sourceguard_en")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip6_sourceguard_violation_action")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip6_sourceguard_port_en")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip6_sourceguard_svlan_en")) { + val_ptr[10] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip6_sourceguard_cvlan_en")) { + val_ptr[11] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip6_sourceunknown_action")) { + val_ptr[12] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_ip_portarpsg(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip4_arp_sourceguard_en")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip4_arp_sourceguard_violation_action")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip4_arp_sourceguard_port_en")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip4_arp_sourceguard_svlan_en")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip4_arp_sourceguard_cvlan_en")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip4_arp_sourceunkown_action")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip6_nd_sourceguard_en")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip6_nd_sourceguard_violation_action")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip6_nd_sourceguard_port_en")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip6_nd_sourceguard_svlan_en")) { + val_ptr[10] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip6_nd_sourceguard_cvlan_en")) { + val_ptr[11] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip6_nd_sourceunkown_action")) { + val_ptr[12] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_ip_portsg(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip4_sourceguard_en")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip4_sourceguard_violation_action")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip4_sourceguard_port_en")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip4_sourceguard_svlan_en")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip4_sourceguard_cvlan_en")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip4_sourceunkown_action")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip6_sourceguard_en")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip6_sourceguard_violation_action")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip6_sourceguard_port_en")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip6_sourceguard_svlan_en")) { + val_ptr[10] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip6_sourceguard_cvlan_en")) { + val_ptr[11] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip6_sourceunkown_action")) { + val_ptr[12] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_ip_pubip(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "index")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip4addr")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_ip_networkroute(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "index")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "type")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "action")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "dstinfo")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "lan_wan")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip4addr")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip4addr_mask")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_ip_intf(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "index")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "mru")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "mtu")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ttl_dec_bypass_en")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip4_unicast_route_en")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip6_unicast_route_en")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "icmp_trigger_en")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ttl_exceed_action")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ttl_exceed_deacclr_en")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "macaddr_bitmap")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "macaddr")) { + val_ptr[10] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_ip_vsiintf(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "vsi")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "l3if_valid")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "l3if_index")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_ip_portintf(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "l3if_valid")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "l3if_index")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_ip_nexthop(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "index")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "type")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "l3if_index")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip_to_me_en")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "pub_ip_index")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "stag_fmt")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "svid")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ctag_fmt")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "cvid")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "macaddr")) { + val_ptr[10] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "dnat_ip")) { + val_ptr[11] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_ip_portmac(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "valid")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "macaddr")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_ip_routemiss(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "action")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_ip_mcmode(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "vsi")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "l2_ip4_multicast_en")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "l2_ip4_multicast_mode")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "l2_ip6_multicast_en")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "l2_ip6_multicast_mode")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_ip_globalctrl(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "mru_fail_action")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "mru_deacclr_en")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "mtu_fail_action")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "mtu_deacclr_en")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "mtu_nonfrag_fail_action")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "mtu_nonfrag_deacclr_en")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "prefix_bc_action")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "prefix_deacclr_en")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "icmp_redirect_action")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "icmp_redirect_deacclr_en")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "hash_mode_0")) { + val_ptr[10] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "hash_mode_1")) { + val_ptr[11] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#endif +#endif + +#ifdef IN_NAT +static int +parse_nat_natentry(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + val_ptr[4] = vrf_dflt_str; + parameter_length ++; + val_ptr[12] = param_dflt_str; + parameter_length ++; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "entry_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "entry_flags")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "entry_status")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "select_index")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "vrf_id")) { + val_ptr[4] = (char*)ext_value_p->option_value; + parameter_length --; + } else if(!strcmp(ext_value_p->option_name, "src_addr")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "translate_addr")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "port_number")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "port_range")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "action")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "mirror")) { + val_ptr[10] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "counter")) { + val_ptr[11] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "counter_id")) { + val_ptr[12] = (char*)ext_value_p->option_value; + parameter_length --; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_nat_naptentry(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + val_ptr[3] = vrf_dflt_str; + parameter_length ++; + val_ptr[4] = cookie_dflt_str; + parameter_length ++; + val_ptr[5] = lb_dflt_str; + parameter_length ++; + val_ptr[15] = param_dflt_str; + parameter_length ++; + val_ptr[16] = priority_dflt_str; + parameter_length ++; + val_ptr[17] = param_dflt_str; + parameter_length ++; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "entry_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "entry_flags")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "entry_status")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "vrf_id")) { + val_ptr[3] = (char*)ext_value_p->option_value; + parameter_length --; + } else if(!strcmp(ext_value_p->option_name, "flow_cookie")) { + val_ptr[4] = (char*)ext_value_p->option_value; + parameter_length --; + } else if(!strcmp(ext_value_p->option_name, "load_balance")) { + val_ptr[5] = (char*)ext_value_p->option_value; + parameter_length --; + } else if(!strcmp(ext_value_p->option_name, "src_addr")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "dst_addr")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "translate_addr")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "src_port")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "dst_port")) { + val_ptr[10] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "translate_port")) { + val_ptr[11] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "action")) { + val_ptr[12] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "mirror")) { + val_ptr[13] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "counter")) { + val_ptr[14] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "counter_id")) { + val_ptr[15] = (char*)ext_value_p->option_value; + parameter_length --; + } else if(!strcmp(ext_value_p->option_name, "priority")) { + val_ptr[16] = (char*)ext_value_p->option_value; + parameter_length --; + } else if(!strcmp(ext_value_p->option_name, "priority_val")) { + val_ptr[17] = (char*)ext_value_p->option_value; + parameter_length --; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_nat_flowentry(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + val_ptr[13] = param_dflt_str; + parameter_length ++; + val_ptr[15] = param_dflt_str; + parameter_length ++; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "entry_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "entry_flags")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "entry_status")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "vrf_id")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "flow_cookie")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "load_balance")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "src_addr")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "dst_addr")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "src_port")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "dst_port")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "action")) { + val_ptr[10] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "mirror")) { + val_ptr[11] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "counter")) { + val_ptr[12] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "counter_id")) { + val_ptr[13] = (char*)ext_value_p->option_value; + parameter_length --; + } else if(!strcmp(ext_value_p->option_name, "priority")) { + val_ptr[14] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "priority_val")) { + val_ptr[15] = (char*)ext_value_p->option_value; + parameter_length --; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_nat_flowcookie(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "proto")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "src_addr")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "dst_addr")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "src_port")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "dst_port")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "flow_cookie")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_nat_flowrfs(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "action")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "proto")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "src_addr")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "dst_addr")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "src_port")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "dst_port")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "flow_rfs")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + + + +static int +parse_nat_natstatus(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "status")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_nat_naptstatus(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "status")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_nat_nathash(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "hash_flag")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_nat_naptmode(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "napt_mode")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_nat_prvbaseaddr(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "base_addr")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_nat_prvaddrmode(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "status")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_nat_pubaddr(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "entry_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "pub_addr")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_nat_natunksess(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "action")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_nat_prvbasemask(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "base_addr_mask")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_nat_global(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + char *sync_str = "disable"; + char *portbmp_str = "0x20"; + val_ptr[1] = sync_str; + parameter_length++; + val_ptr[2] = portbmp_str; + parameter_length++; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "status")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "sync")) { + val_ptr[1] = (char*)ext_value_p->option_value; + parameter_length--; + } else if(!strcmp(ext_value_p->option_name, "portbmp")) { + val_ptr[2] = (char*)ext_value_p->option_value; + parameter_length--; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#endif + +#ifdef IN_STP +static int +parse_stp_portstate(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "stp_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "stp_status")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#endif + +#ifdef IN_MIRROR +static int +parse_mirror_analypt(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "analysis_port")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_mirror_ptingress(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "ingress_port")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_mirror_ptegress(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "egress_port")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_mirror_analycfg(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "direction")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "analysis_port")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "analysis_priority")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#endif + +#ifdef IN_LEAKY +static int +parse_leaky_ucmode(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "unicast_leaky_mode")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_leaky_mcmode(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "multicast_leaky_mode")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_leaky_arpmode(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_leaky_ptucmode(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_leaky_ptmcmode(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#endif + +#ifdef IN_TRUNK +static int +parse_trunk_group(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "trunk_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "trunk_port_bitmap")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_trunk_hashmode(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "trunk_hash_mode")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_trunk_failover(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "failover_en")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#endif + +#ifdef IN_MIB +static int +parse_mib_status(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "status")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_mib_cpukeep(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "status")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#endif + +#ifdef IN_ACL +static int +parse_acl_rule(struct switch_val *val, a_uint32_t dev_id) +{ + a_uint32_t prio = 0; + a_uint32_t i; + a_uint32_t portmap = 0; + a_uint32_t rule_id = 0; + a_uint32_t obj_type = 0; + a_uint32_t obj_value = 0; + a_uint32_t list_id = 0xffffffff; + fal_acl_rule_t rule; + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + a_uint32_t tmpdata = 0; + memset(&rule, 0, sizeof(fal_acl_rule_t)); + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "list_id")) { + cmd_data_check_uint32((char*)ext_value_p->option_value, + &list_id, sizeof(a_uint32_t)); + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "rule_id")) { + cmd_data_check_uint32((char*)ext_value_p->option_value, + &rule_id, sizeof(a_uint32_t)); + if(rule_id == 0) { + printk("ACL rule ID should begin with 1. Please Notice!\r\n"); + } + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "priority")) { + cmd_data_check_uint32((char*)ext_value_p->option_value, + &prio, sizeof(a_uint32_t)); + val_ptr[2] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "rule_type")) { + cmd_data_check_ruletype((char*)ext_value_p->option_value, + &(rule.rule_type), sizeof(a_uint32_t)); + val_ptr[3] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "is_postrouting")) { + cmd_data_check_confirm((char*)ext_value_p->option_value, A_FALSE, + &(rule.post_routing), sizeof(rule.post_routing)); + FAL_FIELD_FLG_SET(rule.field_flg, + FAL_ACL_FIELD_POST_ROURING_EN); + } else if(!strcmp(ext_value_p->option_name, "acl_pool")) { + cmd_data_check_integer((char*)ext_value_p->option_value, + &(tmpdata), 1, 0); + rule.acl_pool = tmpdata; + FAL_FIELD_FLG_SET(rule.field_flg, + FAL_ACL_FIELD_RES_CHAIN); + } else if(!strcmp(ext_value_p->option_name, "dst_mac_address")) { + cmd_data_check_macaddr((char*)ext_value_p->option_value, + &(rule.dest_mac_val), sizeof(fal_mac_addr_t)); + FAL_FIELD_FLG_SET(rule.field_flg, + FAL_ACL_FIELD_MAC_DA); + } else if(!strcmp(ext_value_p->option_name, "dst_mac_address_mask")) { + cmd_data_check_macaddr((char*)ext_value_p->option_value, + &(rule.dest_mac_mask), sizeof(fal_mac_addr_t)); + } else if(!strcmp(ext_value_p->option_name, "src_mac_address")) { + cmd_data_check_macaddr((char*)ext_value_p->option_value, + &(rule.src_mac_val), sizeof(fal_mac_addr_t)); + FAL_FIELD_FLG_SET(rule.field_flg, + FAL_ACL_FIELD_MAC_SA); + } else if(!strcmp(ext_value_p->option_name, "src_mac_address_mask")) { + cmd_data_check_macaddr((char*)ext_value_p->option_value, + &(rule.src_mac_mask), sizeof(fal_mac_addr_t)); + } else if(!strcmp(ext_value_p->option_name, "ethernet_type")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &(tmpdata), sizeof(tmpdata)); + rule.ethtype_val = tmpdata; + FAL_FIELD_FLG_SET(rule.field_flg, + FAL_ACL_FIELD_MAC_ETHTYPE); + } else if(!strcmp(ext_value_p->option_name, "ethernet_type_mask")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &(tmpdata), sizeof(tmpdata)); + rule.ethtype_mask = tmpdata; + } else if(!strcmp(ext_value_p->option_name, "vlan_id")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.vid_val = tmpdata; + FAL_FIELD_FLG_SET(rule.field_flg, + FAL_ACL_FIELD_MAC_VID); + } else if(!strcmp(ext_value_p->option_name, "vlan_id_mask")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.vid_mask = tmpdata; + } else if(!strcmp(ext_value_p->option_name, "vlan_priority")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.up_val = tmpdata; + FAL_FIELD_FLG_SET(rule.field_flg, + FAL_ACL_FIELD_MAC_UP); + } else if(!strcmp(ext_value_p->option_name, "vlan_priority_mask")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.up_mask = tmpdata; + } else if(!strcmp(ext_value_p->option_name, "tagged")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.tagged_val = tmpdata; + rule.tagged_mask = 1; + FAL_FIELD_FLG_SET(rule.field_flg, + FAL_ACL_FIELD_MAC_TAGGED); + } else if(!strcmp(ext_value_p->option_name, "tagged_mask")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.tagged_mask = tmpdata; + } else if(!strcmp(ext_value_p->option_name, "cfi")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.cfi_val = tmpdata; + rule.cfi_mask = 1; + FAL_FIELD_FLG_SET(rule.field_flg, + FAL_ACL_FIELD_MAC_CFI); + } else if(!strcmp(ext_value_p->option_name, "ctagged")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.ctagged_val = tmpdata; + rule.ctagged_mask = BITS(0,3); + FAL_FIELD_FLG_SET(rule.field_flg, + FAL_ACL_FIELD_MAC_CTAGGED); + } else if(!strcmp(ext_value_p->option_name, "ctag_vlan_id")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &(tmpdata), sizeof(tmpdata)); + rule.ctag_vid_val = tmpdata; + FAL_FIELD_FLG_SET(rule.field_flg, + FAL_ACL_FIELD_MAC_CTAG_VID); + } else if(!strcmp(ext_value_p->option_name, "ctag_vlan_id_mask")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.ctag_vid_mask = tmpdata; + } else if(!strcmp(ext_value_p->option_name, "ctag_vlan_priority")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.ctag_pri_val = tmpdata; + FAL_FIELD_FLG_SET(rule.field_flg, + FAL_ACL_FIELD_MAC_CTAG_PRI); + } else if(!strcmp(ext_value_p->option_name, "ctag_vlan_priority_mask")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.ctag_pri_mask = tmpdata; + } else if(!strcmp(ext_value_p->option_name, "ctag_cfi")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.ctag_cfi_val = tmpdata; + rule.ctag_cfi_mask = 1; + FAL_FIELD_FLG_SET(rule.field_flg, + FAL_ACL_FIELD_MAC_CTAG_CFI); + } else if(!strcmp(ext_value_p->option_name, "stagged")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.stagged_val = tmpdata; + rule.stagged_mask = BITS(0,3); + FAL_FIELD_FLG_SET(rule.field_flg, + FAL_ACL_FIELD_MAC_STAGGED); + } else if(!strcmp(ext_value_p->option_name, "stag_vlan_id")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.stag_vid_val = tmpdata; + FAL_FIELD_FLG_SET(rule.field_flg, + FAL_ACL_FIELD_MAC_STAG_VID); + } else if(!strcmp(ext_value_p->option_name, "stag_vlan_id_mask")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.stag_vid_mask = tmpdata; + } else if(!strcmp(ext_value_p->option_name, "stag_vlan_priority")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.stag_pri_val = tmpdata; + FAL_FIELD_FLG_SET(rule.field_flg, + FAL_ACL_FIELD_MAC_STAG_PRI); + } else if(!strcmp(ext_value_p->option_name, "stag_vlan_priority_mask")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &(tmpdata), sizeof(tmpdata)); + rule.stag_pri_mask = tmpdata; + } else if(!strcmp(ext_value_p->option_name, "stag_dei")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.stag_dei_val = tmpdata; + rule.stag_dei_mask = 1; + FAL_FIELD_FLG_SET(rule.field_flg, + FAL_ACL_FIELD_MAC_STAG_DEI); + } else if(!strcmp(ext_value_p->option_name, "ipv4_src_address")) { + cmd_data_check_ip4addr((char*)ext_value_p->option_value, + &(rule.src_ip4_val), 4); + FAL_FIELD_FLG_SET(rule.field_flg, + FAL_ACL_FIELD_IP4_SIP); + } else if(!strcmp(ext_value_p->option_name, "ipv4_src_address_mask")) { + cmd_data_check_ip4addr((char*)ext_value_p->option_value, + &(rule.src_ip4_mask), 4); + } else if(!strcmp(ext_value_p->option_name, "ipv4_dst_address")) { + cmd_data_check_ip4addr((char*)ext_value_p->option_value, + &(rule.dest_ip4_val), 4); + FAL_FIELD_FLG_SET(rule.field_flg, + FAL_ACL_FIELD_IP4_DIP); + } else if(!strcmp(ext_value_p->option_name, "ipv4_dst_address_mask")) { + cmd_data_check_ip4addr((char*)ext_value_p->option_value, + &(rule.dest_ip4_mask), 4); + } else if(!strcmp(ext_value_p->option_name, "ipv6_src_address")) { + cmd_data_check_ip6addr((char*)ext_value_p->option_value, + &(rule.src_ip6_val), 16); + FAL_FIELD_FLG_SET(rule.field_flg, + FAL_ACL_FIELD_IP6_SIP); + } else if(!strcmp(ext_value_p->option_name, "ipv6_src_address_mask")) { + cmd_data_check_ip6addr((char*)ext_value_p->option_value, + &(rule.src_ip6_mask), 16); + } else if(!strcmp(ext_value_p->option_name, "ipv6_dst_address")) { + cmd_data_check_ip6addr((char*)ext_value_p->option_value, + &(rule.dest_ip6_val), 16); + FAL_FIELD_FLG_SET(rule.field_flg, + FAL_ACL_FIELD_IP6_DIP); + } else if(!strcmp(ext_value_p->option_name, "ipv6_dst_address_mask")) { + cmd_data_check_ip6addr((char*)ext_value_p->option_value, + &(rule.dest_ip6_mask), 16); + } else if(!strcmp(ext_value_p->option_name, "ipv6_flow_label")) { + cmd_data_check_uint32((char*)ext_value_p->option_value, + &(rule.ip6_lable_val), + sizeof(rule.ip6_lable_val)); + FAL_FIELD_FLG_SET(rule.field_flg, + FAL_ACL_FIELD_IP6_LABEL); + } else if(!strcmp(ext_value_p->option_name, "ipv6_flow_label_mask")) { + cmd_data_check_uint32((char*)ext_value_p->option_value, + &(rule.ip6_lable_mask), + sizeof(rule.ip6_lable_mask)); + } else if(!strcmp(ext_value_p->option_name, "ip_protocol")) { + cmd_data_check_uint8((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.ip_proto_val = tmpdata; + FAL_FIELD_FLG_SET(rule.field_flg, + FAL_ACL_FIELD_IP_PROTO); + } else if(!strcmp(ext_value_p->option_name, "ip_protocol_mask")) { + cmd_data_check_uint8((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.ip_proto_mask = tmpdata; + } else if(!strcmp(ext_value_p->option_name, "ip_dscp")) { + cmd_data_check_uint8((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.ip_dscp_val = tmpdata; + FAL_FIELD_FLG_SET(rule.field_flg, + FAL_ACL_FIELD_IP_DSCP); + } else if(!strcmp(ext_value_p->option_name, "ip_dscp_mask")) { + cmd_data_check_uint8((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.ip_dscp_mask = tmpdata; + } else if(!strcmp(ext_value_p->option_name, "ip_dst_port")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.dest_l4port_val = tmpdata; + FAL_FIELD_FLG_SET(rule.field_flg, + FAL_ACL_FIELD_L4_DPORT); + rule.dest_l4port_op = FAL_ACL_FIELD_MASK; + } else if(!strcmp(ext_value_p->option_name, "ip_dst_port_mask")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.dest_l4port_mask = tmpdata; + } else if(!strcmp(ext_value_p->option_name, "ip_src_port")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.src_l4port_val = tmpdata; + FAL_FIELD_FLG_SET(rule.field_flg, + FAL_ACL_FIELD_L4_SPORT); + rule.src_l4port_op = FAL_ACL_FIELD_MASK; + } else if(!strcmp(ext_value_p->option_name, "ip_src_port_mask")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.src_l4port_mask = tmpdata; + } else if(!strcmp(ext_value_p->option_name, "icmp_type")) { + cmd_data_check_uint8((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.icmp_type_val = tmpdata; + FAL_FIELD_FLG_SET(rule.field_flg, + FAL_ACL_FIELD_ICMP_TYPE); + } else if(!strcmp(ext_value_p->option_name, "icmp_type_mask")) { + cmd_data_check_uint8((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.icmp_type_mask = tmpdata; + } else if(!strcmp(ext_value_p->option_name, "icmp_code")) { + cmd_data_check_uint8((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.icmp_code_val = tmpdata; + FAL_FIELD_FLG_SET(rule.field_flg, + FAL_ACL_FIELD_ICMP_CODE); + } else if(!strcmp(ext_value_p->option_name, "icmp_code_mask")) { + cmd_data_check_uint8((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.icmp_code_mask = tmpdata; + } else if(!strcmp(ext_value_p->option_name, "tcp_flag")) { + cmd_data_check_uint8((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.tcp_flag_val = tmpdata; + FAL_FIELD_FLG_SET(rule.field_flg, + FAL_ACL_FIELD_TCP_FLAG); + } else if(!strcmp(ext_value_p->option_name, "tcp_flag_mask")) { + cmd_data_check_uint8((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.tcp_flag_mask = tmpdata; + } else if(!strcmp(ext_value_p->option_name, "ripv1")) { + cmd_data_check_uint8((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.ripv1_val = tmpdata; + rule.ripv1_mask = 1; + FAL_FIELD_FLG_SET(rule.field_flg, + FAL_ACL_FIELD_RIPV1); + } else if(!strcmp(ext_value_p->option_name, "dhcpv4")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.dhcpv4_val = tmpdata; + rule.dhcpv4_mask = 1; + FAL_FIELD_FLG_SET(rule.field_flg, + FAL_ACL_FIELD_DHCPV4); + } else if(!strcmp(ext_value_p->option_name, "dhcpv6")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.dhcpv6_val = tmpdata; + rule.dhcpv6_mask = 1; + FAL_FIELD_FLG_SET(rule.field_flg, + FAL_ACL_FIELD_DHCPV6); + } else if(!strcmp(ext_value_p->option_name, "udf_start")) { + cmd_data_check_udf_type((char*)ext_value_p->option_value, + &rule.udf_type, sizeof(rule.udf_type)); + FAL_FIELD_FLG_SET(rule.field_flg, FAL_ACL_FIELD_UDF); + } else if(!strcmp(ext_value_p->option_name, "udf_offset")) { + cmd_data_check_uint8((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.udf_offset = tmpdata; + } else if(!strcmp(ext_value_p->option_name, "udf_length")) { + cmd_data_check_uint8((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.udf_len = tmpdata; + } else if(!strcmp(ext_value_p->option_name, "udf_value")) { + tmpdata = sizeof(rule.udf_val); + cmd_data_check_udf_element((char*)ext_value_p->option_value, + (a_uint8_t *)&rule.udf_val, (a_uint32_t *)&tmpdata); + } else if(!strcmp(ext_value_p->option_name, "udf_mask")) { + tmpdata = sizeof(rule.udf_mask); + cmd_data_check_udf_element((char*)ext_value_p->option_value, + (a_uint8_t *)&rule.udf_mask, (a_uint32_t *)&tmpdata); + } else if(!strcmp(ext_value_p->option_name, "is_ip")) { + cmd_data_check_confirm((char*)ext_value_p->option_value, A_FALSE, + &(rule.is_ip_val), sizeof(rule.is_ip_val)); + rule.is_ip_mask = 1; + FAL_FIELD_FLG_SET(rule.field_flg, FAL_ACL_FIELD_IP); + } else if(!strcmp(ext_value_p->option_name, "is_ip6")) { + cmd_data_check_confirm((char*)ext_value_p->option_value, A_FALSE, + &(rule.is_ipv6_val), sizeof(rule.is_ipv6_val)); + rule.is_ipv6_mask = 1; + FAL_FIELD_FLG_SET(rule.field_flg, FAL_ACL_FIELD_IPV6); + } else if(!strcmp(ext_value_p->option_name, "is_fakemacheader")) { + cmd_data_check_confirm((char*)ext_value_p->option_value, A_FALSE, + &(rule.is_fake_mac_header_val), sizeof(rule.is_fake_mac_header_val)); + rule.is_fake_mac_header_mask = 1; + FAL_FIELD_FLG_SET(rule.field_flg, FAL_ACL_FIELD_FAKE_MAC_HEADER); + } else if(!strcmp(ext_value_p->option_name, "is_snap")) { + cmd_data_check_confirm((char*)ext_value_p->option_value, A_FALSE, + &(rule.is_snap_val), sizeof(rule.is_snap_val)); + rule.is_snap_mask = 1; + FAL_FIELD_FLG_SET(rule.field_flg, FAL_ACL_FIELD_SNAP); + } else if(!strcmp(ext_value_p->option_name, "is_ethernet")) { + cmd_data_check_confirm((char*)ext_value_p->option_value, A_FALSE, + &(rule.is_ethernet_val), sizeof(rule.is_ethernet_val)); + rule.is_ethernet_mask = 1; + FAL_FIELD_FLG_SET(rule.field_flg, FAL_ACL_FIELD_ETHERNET); + } else if(!strcmp(ext_value_p->option_name, "is_fragment")) { + cmd_data_check_confirm((char*)ext_value_p->option_value, A_FALSE, + &(rule.is_fragement_val), sizeof(rule.is_fragement_val)); + rule.is_fragement_mask = 1; + FAL_FIELD_FLG_SET(rule.field_flg, FAL_ACL_FIELD_L3_FRAGMENT); + } else if(!strcmp(ext_value_p->option_name, "is_ahheader")) { + cmd_data_check_confirm((char*)ext_value_p->option_value, A_FALSE, + &(rule.is_ah_header_val), sizeof(rule.is_ah_header_val)); + rule.is_ah_header_mask = 1; + FAL_FIELD_FLG_SET(rule.field_flg, FAL_ACL_FIELD_AH_HEADER); + } else if(!strcmp(ext_value_p->option_name, "is_espheader")) { + cmd_data_check_confirm((char*)ext_value_p->option_value, A_FALSE, + &(rule.is_esp_header_val), sizeof(rule.is_esp_header_val)); + rule.is_esp_header_mask = 1; + FAL_FIELD_FLG_SET(rule.field_flg, FAL_ACL_FIELD_ESP_HEADER); + } else if(!strcmp(ext_value_p->option_name, "is_mobilityheader")) { + cmd_data_check_confirm((char*)ext_value_p->option_value, A_FALSE, + &(rule.is_mobility_header_val), sizeof(rule.is_mobility_header_val)); + rule.is_mobility_header_val = 1; + FAL_FIELD_FLG_SET(rule.field_flg, FAL_ACL_FIELD_MOBILITY_HEADER); + } else if(!strcmp(ext_value_p->option_name, "is_fragmentheader")) { + cmd_data_check_confirm((char*)ext_value_p->option_value, A_FALSE, + &(rule.is_fragment_header_val), sizeof(rule.is_fragment_header_val)); + rule.is_fragment_header_mask = 1; + FAL_FIELD_FLG_SET(rule.field_flg, FAL_ACL_FIELD_FRAGMENT_HEADER); + } else if(!strcmp(ext_value_p->option_name, "is_otherheader")) { + cmd_data_check_confirm((char*)ext_value_p->option_value, A_FALSE, + &(rule.is_other_header_val), sizeof(rule.is_other_header_val)); + rule.is_other_header_mask = 1; + FAL_FIELD_FLG_SET(rule.field_flg, FAL_ACL_FIELD_OTHER_EXT_HEADER); + } else if(!strcmp(ext_value_p->option_name, "is_ip4option")) { + cmd_data_check_confirm((char*)ext_value_p->option_value, A_FALSE, + &(rule.is_ipv4_option_val), sizeof(rule.is_ipv4_option_val)); + rule.is_ipv4_option_mask = 1; + FAL_FIELD_FLG_SET(rule.field_flg, FAL_ACL_FIELD_IPV4_OPTION); + } else if(!strcmp(ext_value_p->option_name, "is_firstfragment")) { + cmd_data_check_confirm((char*)ext_value_p->option_value, A_FALSE, + &(rule.is_first_frag_val), sizeof(rule.is_first_frag_val)); + rule.is_first_frag_mask = 1; + FAL_FIELD_FLG_SET(rule.field_flg, FAL_ACL_FIELD_FIRST_FRAGMENT); + } else if(!strcmp(ext_value_p->option_name, "vsi_valid")) { + cmd_data_check_confirm((char*)ext_value_p->option_value, A_FALSE, + &(rule.vsi_valid), sizeof(rule.vsi_valid)); + rule.vsi_mask = 1; + FAL_FIELD_FLG_SET(rule.field_flg, FAL_ACL_FIELD_VSI_VALID); + } else if(!strcmp(ext_value_p->option_name, "vsi")) { + cmd_data_check_uint8((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.vsi = tmpdata; + FAL_FIELD_FLG_SET(rule.field_flg, FAL_ACL_FIELD_VSI); + } else if(!strcmp(ext_value_p->option_name, "vsi_mask")) { + cmd_data_check_uint8((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.vsi_mask = tmpdata; + } else if(!strcmp(ext_value_p->option_name, "pppoe_session_id")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.pppoe_sessionid = tmpdata; + FAL_FIELD_FLG_SET(rule.field_flg, FAL_ACL_FIELD_PPPOE_SESSIONID); + } else if(!strcmp(ext_value_p->option_name, "pppoe_session_id_mask")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.pppoe_sessionid_mask = tmpdata; + } else if(!strcmp(ext_value_p->option_name, "l3ttl")) { + cmd_data_check_uint8((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.l3_ttl = tmpdata; + FAL_FIELD_FLG_SET(rule.field_flg, FAL_ACL_FIELD_L3_TTL); + } else if(!strcmp(ext_value_p->option_name, "l3ttl_mask")) { + cmd_data_check_uint8((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.l3_ttl_mask= tmpdata; + } else if(!strcmp(ext_value_p->option_name, "l3length")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.l3_length = tmpdata; + FAL_FIELD_FLG_SET(rule.field_flg, FAL_ACL_FIELD_L3_LENGTH); + } else if(!strcmp(ext_value_p->option_name, "l3length_mask")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.l3_length_mask = tmpdata; + } else if(!strcmp(ext_value_p->option_name, "l3packettype")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.l3_pkt_type = tmpdata; + FAL_FIELD_FLG_SET(rule.field_flg, FAL_ACL_FIELD_IP_PKT_TYPE); + } else if(!strcmp(ext_value_p->option_name, "l3packettype_mask")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.l3_pkt_type_mask = tmpdata; + } else if(!strcmp(ext_value_p->option_name, "user_defined_op0")) { + fal_acl_field_op_t op = FAL_ACL_FIELD_MASK; + cmd_data_check_fieldop((char*)ext_value_p->option_value, + FAL_ACL_FIELD_MASK, &op); + printk("%s, %d", (char*)ext_value_p->option_value, op); + rule.udf0_op= op; + } else if(!strcmp(ext_value_p->option_name, "user_defined_val0")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.udf0_val = tmpdata; + FAL_FIELD_FLG_SET(rule.field_flg, FAL_ACL_FIELD_UDF0); + } else if(!strcmp(ext_value_p->option_name, "user_defined_val0_mask")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.udf0_mask = tmpdata; + } else if(!strcmp(ext_value_p->option_name, "user_defined_op1")) { + fal_acl_field_op_t op = FAL_ACL_FIELD_MASK; + cmd_data_check_fieldop((char*)ext_value_p->option_value, + FAL_ACL_FIELD_MASK, &op); + rule.udf1_op= op; + } else if(!strcmp(ext_value_p->option_name, "user_defined_val1")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.udf1_val = tmpdata; + FAL_FIELD_FLG_SET(rule.field_flg, FAL_ACL_FIELD_UDF1); + } else if(!strcmp(ext_value_p->option_name, "user_defined_val1_mask")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.udf1_mask = tmpdata; + } else if(!strcmp(ext_value_p->option_name, "user_defined_val2")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.udf2_val = tmpdata; + FAL_FIELD_FLG_SET(rule.field_flg, FAL_ACL_FIELD_UDF2); + } else if(!strcmp(ext_value_p->option_name, "user_defined_val2_mask")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.udf2_mask = tmpdata; + } else if(!strcmp(ext_value_p->option_name, "user_defined_val3")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.udf3_val = tmpdata; + FAL_FIELD_FLG_SET(rule.field_flg, FAL_ACL_FIELD_UDF3); + } else if(!strcmp(ext_value_p->option_name, "user_defined_val3_mask")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.udf3_mask = tmpdata; + } else if(!strcmp(ext_value_p->option_name, "inverse_check_fields")) { + if (!strcmp(ext_value_p->option_value, "y") || + !strcmp(ext_value_p->option_value, "yes")) { + FAL_FIELD_FLG_SET(rule.field_flg, + FAL_ACL_FIELD_INVERSE_ALL); + } else if(!strcmp(ext_value_p->option_value, "n") || + !strcmp(ext_value_p->option_value, "no")) { + FAL_FIELD_FLG_CLR(rule.field_flg, + FAL_ACL_FIELD_INVERSE_ALL); + } + } else if(!strcmp(ext_value_p->option_name, "packet_drop")) { + if(!strcmp(ext_value_p->option_value, "y") || + !strcmp(ext_value_p->option_value, "yes")) { + FAL_ACTION_FLG_SET(rule.action_flg, + FAL_ACL_ACTION_DENY); + } else if(!strcmp(ext_value_p->option_value, "n") || + !strcmp(ext_value_p->option_value, "no")){ + FAL_ACTION_FLG_CLR(rule.action_flg, + FAL_ACL_ACTION_DENY); + FAL_ACTION_FLG_SET(rule.action_flg, + FAL_ACL_ACTION_PERMIT); + } + } else if(!strcmp(ext_value_p->option_name, "dscp_of_remark")) { + cmd_data_check_uint8((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.dscp = tmpdata; + FAL_ACTION_FLG_SET(rule.action_flg, + FAL_ACL_ACTION_REMARK_DSCP); + } +#if defined(CPPE) + else if(!strcmp(ext_value_p->option_name, "dscp_of_remark_mask")) { + cmd_data_check_uint8((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.dscp_mask = tmpdata; + } +#endif + else if(!strcmp(ext_value_p->option_name, "vlan_priority_of_remark")) { + cmd_data_check_uint8((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.up = tmpdata; + } else if(!strcmp(ext_value_p->option_name, "queue_of_remark")) { + cmd_data_check_uint8((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.queue = tmpdata; + FAL_ACTION_FLG_SET(rule.action_flg, + FAL_ACL_ACTION_REMARK_QUEUE); + } else if(!strcmp(ext_value_p->option_name, "port_bitmap")) { + cmd_data_check_pbmp((char*)ext_value_p->option_value, &portmap, 4); + } else if(!strcmp((char*)ext_value_p->option_name, "obj_type")) { + cmd_data_check_uint32((char*)ext_value_p->option_value, &obj_type, 4); + } else if(!strcmp((char*)ext_value_p->option_name, "obj_value")) { + cmd_data_check_uint32((char*)ext_value_p->option_value, &obj_value, 4); + } else if(!strcmp((char*)ext_value_p->option_name, "user_defined_field_value")) { + cmd_data_check_udf_element((char*)ext_value_p->option_value, + (a_uint8_t *)&(rule.udf_val[0]), (a_uint32_t *)&(rule.udf_len)); + FAL_FIELD_FLG_SET(rule.field_flg, + FAL_ACL_FIELD_UDF); + } else if(!strcmp(ext_value_p->option_name, "user_defined_field_mask")) { + cmd_data_check_udf_element((char*)ext_value_p->option_value, + (a_uint8_t *)&(rule.udf_mask[0]), (a_uint32_t *)&(rule.udf_len)); + } else if(!strcmp(ext_value_p->option_name, "redirect_to_cpu")) { + if(!strcmp(ext_value_p->option_value, "y") || + !strcmp(ext_value_p->option_value, "yes")) { + FAL_ACTION_FLG_SET(rule.action_flg, + FAL_ACL_ACTION_RDTCPU); + } else if(!strcmp(ext_value_p->option_value, "n") || + !strcmp(ext_value_p->option_value, "no")){ + FAL_ACTION_FLG_CLR(rule.action_flg, + FAL_ACL_ACTION_RDTCPU); + } + } else if(!strcmp(ext_value_p->option_name, "copy_to_cpu")) { + if(!strcmp(ext_value_p->option_value, "y") || + !strcmp(ext_value_p->option_value, "yes")) { + FAL_ACTION_FLG_SET(rule.action_flg, + FAL_ACL_ACTION_CPYCPU); + } else if(!strcmp(ext_value_p->option_value, "n") || + !strcmp(ext_value_p->option_value, "no")){ + FAL_ACTION_FLG_CLR(rule.action_flg, + FAL_ACL_ACTION_CPYCPU); + } + } else if(!strcmp(ext_value_p->option_name, "redirect_to_ports")) { + FAL_ACTION_FLG_SET(rule.action_flg, + FAL_ACL_ACTION_REDPT); + cmd_data_check_pbmp((char*)ext_value_p->option_value, &rule.ports, 4); + } else if(!strcmp(ext_value_p->option_name, "mirror")) { + if(!strcmp(ext_value_p->option_value, "y") || + !strcmp(ext_value_p->option_value, "yes")) { + FAL_ACTION_FLG_SET(rule.action_flg, + FAL_ACL_ACTION_MIRROR); + } else if(!strcmp(ext_value_p->option_value, "n") || + !strcmp(ext_value_p->option_value, "no")){ + FAL_ACTION_FLG_CLR(rule.action_flg, + FAL_ACL_ACTION_MIRROR); + } + } else if(!strcmp(ext_value_p->option_name, "remark_lookup_vid")) { + if(!strcmp(ext_value_p->option_value, "y") || + !strcmp(ext_value_p->option_value, "yes")) { + FAL_ACTION_FLG_SET(rule.action_flg, + FAL_ACL_ACTION_REMARK_LOOKUP_VID); + } else if(!strcmp(ext_value_p->option_value, "n") || + !strcmp(ext_value_p->option_value, "no")){ + FAL_ACTION_FLG_CLR(rule.action_flg, + FAL_ACL_ACTION_REMARK_LOOKUP_VID); + } + } else if(!strcmp(ext_value_p->option_name, "stag_vid_of_remark")) { + FAL_ACTION_FLG_SET(rule.action_flg, + FAL_ACL_ACTION_REMARK_STAG_VID); + cmd_data_check_uint16((char*)ext_value_p->option_value, (a_uint32_t *)&rule.stag_vid, 4); + } else if(!strcmp(ext_value_p->option_name, "stag_priority_of_remark")) { + FAL_ACTION_FLG_SET(rule.action_flg, + FAL_ACL_ACTION_REMARK_STAG_PRI); + cmd_data_check_uint16((char*)ext_value_p->option_value, (a_uint32_t *)&rule.stag_pri, 4); + } else if(!strcmp(ext_value_p->option_name, "stag_dei_of_remark")) { + FAL_ACTION_FLG_SET(rule.action_flg, + FAL_ACL_ACTION_REMARK_STAG_DEI); + cmd_data_check_uint16((char*)ext_value_p->option_value, (a_uint32_t *)&rule.stag_dei, 4); + } else if(!strcmp(ext_value_p->option_name, "ctag_vid_of_remark")) { + FAL_ACTION_FLG_SET(rule.action_flg, + FAL_ACL_ACTION_REMARK_CTAG_VID); + cmd_data_check_uint16((char*)ext_value_p->option_value, (a_uint32_t *)&rule.ctag_vid, 4); + } else if(!strcmp(ext_value_p->option_name, "ctag_priority_of_remark")) { + FAL_ACTION_FLG_SET(rule.action_flg, + FAL_ACL_ACTION_REMARK_CTAG_PRI); + cmd_data_check_uint16((char*)ext_value_p->option_value, (a_uint32_t *)&rule.ctag_pri, 4); + } else if(!strcmp(ext_value_p->option_name, "ctag_cfi_of_remark")) { + FAL_ACTION_FLG_SET(rule.action_flg, + FAL_ACL_ACTION_REMARK_CTAG_CFI); + cmd_data_check_uint16((char*)ext_value_p->option_value, (a_uint32_t *)&rule.ctag_cfi, 4); + } else if(!strcmp(ext_value_p->option_name, "action_policer_id")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + (a_uint32_t *)&(rule.policer_ptr), sizeof(a_uint32_t)); + FAL_ACTION_FLG_SET(rule.action_flg, + FAL_ACL_ACTION_POLICER_EN); + } else if(!strcmp(ext_value_p->option_name, "action_arp_ptr")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + (a_uint32_t *)&(rule.arp_ptr), sizeof(a_uint32_t)); + FAL_ACTION_FLG_SET(rule.action_flg, + FAL_ACL_ACTION_ARP_EN); + } else if(!strcmp(ext_value_p->option_name, "action_wcmp_ptr")) { + cmd_data_check_uint16((char*)ext_value_p->option_value, + (a_uint32_t *)&(rule.wcmp_ptr), sizeof(a_uint32_t)); + FAL_ACTION_FLG_SET(rule.action_flg, + FAL_ACL_ACTION_WCMP_EN); + } else if(!strcmp(ext_value_p->option_name, "action_snat")) { + if(!strcmp(ext_value_p->option_value, "y") || + !strcmp(ext_value_p->option_value, "yes")) { + FAL_ACTION_FLG_SET(rule.action_flg, + FAL_ACL_ACTION_POLICY_FORWARD_EN); + rule.policy_fwd |= FAL_ACL_POLICY_SNAT; + } else if(!strcmp(ext_value_p->option_value, "n") || + !strcmp(ext_value_p->option_value, "no")){ + rule.policy_fwd &= ~ FAL_ACL_POLICY_SNAT; + } + } else if(!strcmp(ext_value_p->option_name, "action_dnat")) { + if(!strcmp(ext_value_p->option_value, "y") || + !strcmp(ext_value_p->option_value, "yes")) { + FAL_ACTION_FLG_SET(rule.action_flg, + FAL_ACL_ACTION_POLICY_FORWARD_EN); + rule.policy_fwd |= FAL_ACL_POLICY_DNAT; + } else if(!strcmp(ext_value_p->option_value, "n") || + !strcmp(ext_value_p->option_value, "no")){ + rule.policy_fwd &= ~ FAL_ACL_POLICY_DNAT; + } + } else if(!strcmp(ext_value_p->option_name, "bypass_egress_translation")) { + if(!strcmp(ext_value_p->option_value, "y") || + !strcmp(ext_value_p->option_value, "yes")) { + FAL_ACTION_FLG_SET(rule.action_flg, + FAL_ACL_ACTION_BYPASS_EGRESS_TRANS); + } else if(!strcmp(ext_value_p->option_value, "n") || + !strcmp(ext_value_p->option_value, "no")){ + FAL_ACTION_FLG_CLR(rule.action_flg, + FAL_ACL_ACTION_BYPASS_EGRESS_TRANS); + } + } else if(!strcmp(ext_value_p->option_name, "interrupt_trigger")) { + if(!strcmp(ext_value_p->option_value, "y") || + !strcmp(ext_value_p->option_value, "yes")) { + FAL_ACTION_FLG_SET(rule.action_flg, + FAL_ACL_ACTION_MATCH_TRIGGER_INTR); + } else if(!strcmp(ext_value_p->option_value, "n") || + !strcmp(ext_value_p->option_value, "no")){ + FAL_ACTION_FLG_CLR(rule.action_flg, + FAL_ACL_ACTION_MATCH_TRIGGER_INTR); + } + } else if(!strcmp(ext_value_p->option_name, "bypass_bitmap")) { + cmd_data_check_uint32((char*)ext_value_p->option_value, + &(rule.bypass_bitmap), sizeof(rule.bypass_bitmap)); + } else if(!strcmp(ext_value_p->option_name, "enqueue_priority")) { + cmd_data_check_uint8((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.enqueue_pri = tmpdata; + FAL_ACTION_FLG_SET(rule.action_flg, FAL_ACL_ACTION_ENQUEUE_PRI); + } else if(!strcmp(ext_value_p->option_name, "stagformat")) { + cmd_data_check_uint8((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.stag_fmt = tmpdata; + FAL_ACTION_FLG_SET(rule.action_flg, FAL_ACL_ACTION_REMARK_STAG_VID); + } else if(!strcmp(ext_value_p->option_name, "ctagformat")) { + cmd_data_check_uint8((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.ctag_fmt = tmpdata; + FAL_ACTION_FLG_SET(rule.action_flg, FAL_ACL_ACTION_REMARK_CTAG_VID); + } else if(!strcmp(ext_value_p->option_name, "internaldropprec")) { + cmd_data_check_uint8((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.int_dp = tmpdata; + FAL_ACTION_FLG_SET(rule.action_flg, FAL_ACL_ACTION_INT_DP); + } else if(!strcmp(ext_value_p->option_name, "servicecode")) { + cmd_data_check_uint8((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.service_code= tmpdata; + FAL_ACTION_FLG_SET(rule.action_flg, FAL_ACL_ACTION_SERVICE_CODE); + } else if(!strcmp(ext_value_p->option_name, "cpucode")) { + cmd_data_check_uint8((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.cpu_code = tmpdata; + FAL_ACTION_FLG_SET(rule.action_flg, FAL_ACL_ACTION_CPU_CODE); + } else if(!strcmp(ext_value_p->option_name, "metadata_en")) { + cmd_data_check_uint8((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + if(tmpdata) + FAL_ACTION_FLG_SET(rule.action_flg, FAL_ACL_ACTION_METADATA_EN); + } else if(!strcmp(ext_value_p->option_name, "synctoggle")) { + cmd_data_check_uint8((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + if(tmpdata) + FAL_ACTION_FLG_SET(rule.action_flg, FAL_ACL_ACTION_SYN_TOGGLE); + } +#if defined(CPPE) + else if(!strcmp(ext_value_p->option_name, "qos_res_prec")) { + cmd_data_check_uint8((char*)ext_value_p->option_value, + &tmpdata, sizeof(tmpdata)); + rule.qos_res_prec = tmpdata; + } +#endif + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + /*to be compatible with previous version which didn't define list id*/ + if(0xffffffff == list_id) { + list_id = rule_id; + rule_id = 0; + } else { + rule.pri = prio & 0x7; + prio = (prio >> 3) & 0x3f; + } + SSDK_DEBUG("uci set acl list %d, rule %d\n", list_id, rule_id); + SSDK_DEBUG("uci set acl portbitmap 0x%x, obj_type %d, obj_value %d\n", + portmap, obj_type, obj_value); + fal_acl_list_creat(dev_id, list_id, prio); + fal_acl_rule_add(dev_id, list_id, rule_id, 1, &rule); + /*bind to port bitmap*/ + if( portmap != 0 ) { + for (i = 0; i < AR8327_NUM_PORTS; i++) { + fal_acl_list_unbind(dev_id, list_id, 0, 0, i); + if (portmap & (0x1 << i)) { + rv = fal_acl_list_bind(dev_id, list_id, 0, 0, i); + if(rv != SW_OK){ + SSDK_ERROR("uci set acl fail %d\n", rv); + } + } + } + } else { + rv = fal_acl_list_bind(dev_id, list_id, 0, obj_type, obj_value); + if(rv != SW_OK){ + SSDK_ERROR("uci set acl fail %d\n", rv); + } + } + fal_acl_status_set(dev_id, A_TRUE); + + return rv; +} + +static int +parse_acl_udfprofile(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "user_defined_type")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "user_defined_offset")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "user_defined_length")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_acl_udf(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "packet_type")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "index")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "user_defined_type")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "user_defined_offset")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +#endif + +#ifdef IN_FLOW +static int +parse_flow_entry(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "add_mode")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "entry_id")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "entrytype")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "host_addr_type")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "host_addr_index")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "protocol")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "age")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "srcintf_valid")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "srcintf_index")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "fwdtype")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "snat_nexthop")) { + val_ptr[10] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "snat_srcport")) { + val_ptr[11] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "dnat_nexthop")) { + val_ptr[12] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "dnat_dstport")) { + val_ptr[13] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "route_nexthop")) { + val_ptr[14] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "portvalid")) { + val_ptr[15] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "routeport")) { + val_ptr[16] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "bridgeport")) { + val_ptr[17] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "deacclr_en")) { + val_ptr[18] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "copy_tocpu_en")) { + val_ptr[19] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "syntoggle")) { + val_ptr[20] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "priprofile")) { + val_ptr[21] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "sevicecode")) { + val_ptr[22] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "iptype")) { + val_ptr[23] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip4addr")) { + val_ptr[26] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "srcport")) { + val_ptr[24] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "dstport")) { + val_ptr[25] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "tree_id")) { + val_ptr[27] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_flow_status(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "status")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_flow_age(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "agetime")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ageunit")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_flow_mgmt(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "flowtype")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "flowdirection")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "flow_miss_action")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "frag_bypass_en")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "tcp_specific_bypass_en")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "all_bypass_en")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "keysel")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_flow_host(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "add_mode")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "entry_id")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "entrytype")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "host_addr_type")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "host_addr_index")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "protocol")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "age")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "srcintf_valid")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "srcintf_index")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "fwdtype")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "snat_nexthop")) { + val_ptr[10] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "snat_srcport")) { + val_ptr[11] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "dnat_nexthop")) { + val_ptr[12] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "dnat_dstport")) { + val_ptr[13] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "route_nexthop")) { + val_ptr[14] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "portvalid")) { + val_ptr[15] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "routeport")) { + val_ptr[16] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "bridgeport")) { + val_ptr[17] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "deacclr_en")) { + val_ptr[18] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "copy_tocpu_en")) { + val_ptr[19] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "syntoggle")) { + val_ptr[20] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "priprofile")) { + val_ptr[21] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "sevicecode")) { + val_ptr[22] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "iptype")) { + val_ptr[23] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip4addr")) { + val_ptr[26] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "srcport")) { + val_ptr[24] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "dstport")) { + val_ptr[25] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "tree_id")) { + val_ptr[27] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ipentry_id")) { + val_ptr[28] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "entry_flags")) { + val_ptr[29] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "entry_status")) { + val_ptr[30] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip_addr")) { + val_ptr[31] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "mac_addr")) { + val_ptr[32] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "interface_id")) { + val_ptr[33] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "load_balance_num")) { + val_ptr[34] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "vrf_id")) { + val_ptr[35] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[36] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "action")) { + val_ptr[37] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "mirror")) { + val_ptr[38] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "counter")) { + val_ptr[39] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "destinfo")) { + val_ptr[40] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip_synctoggle")) { + val_ptr[41] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "lan_wan")) { + val_ptr[42] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_flow_global(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "srcif_check_action")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "srcif_check_deacclr_en")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "service_loop_en")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "service_loop_action")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "service_loop_deacclr_en")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "flow_deacclr_action")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "sync_mismatch_action")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "sync_mismatch_deacclr_en")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "hash_mode_0")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "hash_mode_1")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#endif + +#ifdef IN_BM +static int +parse_bm_ctrl(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "enable")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_bm_portgroupmap(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "group_id")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_bm_groupbuff(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "group_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "bufnum")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_bm_portrsvbuff(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "prealloc_bufnum")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "react_bufnum")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_bm_portsthresh(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "maxthreshold")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "resume_offset")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_bm_portdthresh(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "weight")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "sharedceiling")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "resumeoffset")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "resume_min_threshold")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +#endif + +#ifdef IN_QM +static int +parse_qm_ucastqbase(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "srcprofile")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "servicecode_en")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "servicecode")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "cpucode_en")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "cpucode")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "destport")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "queuebase")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "profile")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qm_ucastpriclass(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "profile")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "priority")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "class")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qm_mcastpriclass(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "priority")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "class")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qm_queue(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "queue_id")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qm_ucasthash(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "profile")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "rsshash")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "queuehash")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qm_ucastdflthash(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "queuevalue")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qm_mcastcpucode(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "cpucode")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "class")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qm_acctrl(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "type")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "obj_id")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "admis_ctrl_en")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "admis_flowctrl_en")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qm_acprebuffer(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "type")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "obj_id")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "bufnum")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qm_acqgroup(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "queue_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "group_id")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qm_acsthresh(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "type")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "obj_id")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "color_en")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "wred_en")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "greenmax")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "green_min_offset")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "yel_max_offset")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "yel_min_offset")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "red_max_offset")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "red_min_offset")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "green_resume_offset")) { + val_ptr[10] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "yel_resume_offset")) { + val_ptr[11] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "red_resume_offset")) { + val_ptr[12] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qm_acdthresh(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "queue_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "color_en")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "wred_en")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "sharedweight")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "green_min_offset")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "yel_max_offset")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "yel_min_offset")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "red_max_offset")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "red_min_offset")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "green_resume_off")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "yel_resume_offset")) { + val_ptr[10] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "red_resume_offset")) { + val_ptr[11] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ceiling")) { + val_ptr[12] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qm_acgbuff(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "group_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "prealloc_bufnum")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "total_bufnum")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qm_cntctrl(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "cnt_en")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qm_cnt(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "queue_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qm_enqueue(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "queue_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "enqueue_en")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_qm_srcprofile(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "sourceprofile")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +#endif + +#ifdef IN_SERVCODE +static int +parse_servcode_config(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "servcode_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "destport_en")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "destport_id")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "bypass_bitmap_0")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "bypass_bitmap_1")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "bypass_bitmap_2")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "direction")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "field_update_bitmap")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "next_servicecode")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "hardwareservices")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "offsetselection")) { + val_ptr[10] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_servcode_loopcheck(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "loopcheck_en")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#endif + +#ifdef IN_CTRLPKT +static int +parse_ctrlpkt_ethernettype(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "profile_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ethernettype")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_ctrlpkt_rfdb(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "profile_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "rfdb_macaddr")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_ctrlpkt_appprofile(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "port_bitmap")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ethtype_profile_bitmap")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "rfdb_profile_bitmap")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "eapol_en")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "pppoe_en")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "igmp_en")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "arp_request_en")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "arp_reponse_en")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "dhcp4_en")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "dhcp6_en")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "mld_en")) { + val_ptr[10] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip6ns_en")) { + val_ptr[11] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ip6na_en")) { + val_ptr[12] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ctrlpkt_profile_action")) { + val_ptr[13] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "sourceguard_bypass")) { + val_ptr[14] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "l2filter_bypass")) { + val_ptr[15] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ingress_stp_bypass")) { + val_ptr[16] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "ingress_vlan_filter_bypass")) { + val_ptr[17] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#endif + +#ifdef IN_POLICER +static int +parse_policer_timeslot(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "timeslot")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_policer_fcscompensation(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "fcscompensation_length")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_policer_portentry(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "policer_en")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "coupling_en")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "colormode")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "frametype")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "metermode")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "meterunit")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "cir")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "cbs")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "eir")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "ebs")) { + val_ptr[10] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "yellow_priremark_en")) { + val_ptr[11] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "yellow_dropprec_remark_en")) { + val_ptr[12] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "yellow_pcpremark_en")) { + val_ptr[13] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "yellow_deiremark_en")) { + val_ptr[14] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "yellowpri")) { + val_ptr[15] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "yellow_dropprec")) { + val_ptr[16] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "yellowpcp")) { + val_ptr[17] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "yellowdei")) { + val_ptr[18] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "redaction")) { + val_ptr[19] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "red_priremark_en")) { + val_ptr[20] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "red_dropprec_remark_en")) { + val_ptr[21] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "red_pcpremark_en")) { + val_ptr[22] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "red_deiremark_en")) { + val_ptr[23] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "redpri")) { + val_ptr[24] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "red_dropprec")) { + val_ptr[25] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "redpcp")) { + val_ptr[26] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "reddei")) { + val_ptr[27] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_policer_aclentry(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "index")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "policer_en")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "coupling_en")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "colormode")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "metermode")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "meterunit")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "cir")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "cbs")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "eir")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "ebs")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "yellow_priremark_en")) { + val_ptr[10] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "yellow_dropprec_remark_en")) { + val_ptr[11] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "yellow_pcpremark_en")) { + val_ptr[12] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "yellow_deiremark_en")) { + val_ptr[13] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "yellowpri")) { + val_ptr[14] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "yellow_dropprec")) { + val_ptr[15] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "yellowpcp")) { + val_ptr[16] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "yellowdei")) { + val_ptr[17] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "redaction")) { + val_ptr[18] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "red_priremark_en")) { + val_ptr[19] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "red_dropprec_remark_en")) { + val_ptr[20] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "red_pcpremark_en")) { + val_ptr[21] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "red_deiremark_en")) { + val_ptr[22] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "redpri")) { + val_ptr[23] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "red_dropprec")) { + val_ptr[24] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "redpcp")) { + val_ptr[25] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "reddei")) { + val_ptr[26] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +#endif + +#ifdef IN_SHAPER +static int +parse_shaper_porttimeslot(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "timeslot")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_shaper_flowtimeslot(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "timeslot")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_shaper_queuetimeslot(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "timeslot")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_shaper_ipgcompensation(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "ipgcompensation_length")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_shaper_porttoken(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "ctoken_negative_en")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "ctokennum")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_shaper_flowtoken(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "flow_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "ctoken_negative_en")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "ctokennum")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "etoken_negative_en")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "etokennum")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_shaper_queuetoken(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "queue_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "ctoken_negative_en")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "ctokennum")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "etoken_negative_en")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "etokennum")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_shaper_portshaper(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "meterunit")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "cshaper_en")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "cir")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "cbs")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "framemode")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_shaper_queueshaper(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "queue_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "coupling_en")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "meterunit")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "cshaper_en")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "cir")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "cbs")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "eshaper_en")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "eir")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "ebs")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "framemode")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_shaper_flowshaper(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + switch_ext_p = val->value.ext_val; + while(switch_ext_p) { + ext_value_p = switch_ext_p; + + if(!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if(!strcmp(ext_value_p->option_name, "flow_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "coupling_en")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "meterunit")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "cshaper_en")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "cir")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "cbs")) { + val_ptr[5] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "eshaper_en")) { + val_ptr[6] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "eir")) { + val_ptr[7] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "ebs")) { + val_ptr[8] = (char*)ext_value_p->option_value; + } else if(!strcmp(ext_value_p->option_name, "framemode")) { + val_ptr[9] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} +#endif + +#ifdef IN_QOS +static int +parse_qos(const char *command_name, struct switch_val *val) +{ + int rv = -1; + #ifndef IN_QOS_MINI + if(!strcmp(command_name, "QTxBufSts")) { + rv = parse_qos_qtxbufsts(val); + } else if(!strcmp(command_name, "QTxBufNr")) { + rv = parse_qos_qtxbufnr(val); + } else if(!strcmp(command_name, "PtTxBufSts")) { + rv = parse_qos_pttxbufsts(val); + } else if(!strcmp(command_name, "PtTxBufNr")) { + rv = parse_qos_pttxbufnr(val); + } else if(!strcmp(command_name, "PtRxBufNr")) { + rv = parse_qos_ptrxbufnr(val); + } else if(!strcmp(command_name, "PtRedEn")) { + rv = parse_qos_ptreden(val); + } else if(!strcmp(command_name, "PtMode")) { + rv = parse_qos_ptmode(val); + } else if(!strcmp(command_name, "PtModePri")) { + rv = parse_qos_ptmodepri(val); + } else if(!strcmp(command_name, "PtschMode")) { + rv = parse_qos_ptschmode(val); + } else if(!strcmp(command_name, "PtDefaultSpri")) { + rv = parse_qos_ptdefaultspri(val); + } else if(!strcmp(command_name, "PtDefaultCpri")) { + rv = parse_qos_ptdefaultcpri(val); + } else if(!strcmp(command_name, "PtFSpriSts")) { + rv = parse_qos_ptfsprists(val); + } else if(!strcmp(command_name, "PtFCpriSts")) { + rv = parse_qos_ptfcprists(val); + } else if(!strcmp(command_name, "PtQuRemark")) { + rv = parse_qos_ptquremark(val); + } else if (!strcmp(command_name, "Ptgroup")) { + rv = parse_qos_ptgroup(val); + } else if (!strcmp(command_name, "Ptpriprece")) { + rv = parse_qos_ptpri(val); + } else if (!strcmp(command_name, "Ptremark")) { + rv = parse_qos_ptremark(val); + } else if (!strcmp(command_name, "Pcpmap")) { + rv = parse_qos_pcpmap(val); + } else if (!strcmp(command_name, "Flowmap")) { + rv = parse_qos_flowmap(val); + } else if (!strcmp(command_name, "Dscpmap")) { + rv = parse_qos_dscpmap(val); + } else if (!strcmp(command_name, "Qscheduler")) { + rv = parse_qos_qscheduler(val); + } else if (!strcmp(command_name, "Ringqueue")) { + rv = parse_qos_ringqueue(val); + } else if (!strcmp(command_name, "Dequeue")) { + rv = parse_qos_dequeue(val); + } else if (!strcmp(command_name, "Portscheduler")) { + rv = parse_qos_portscheduler(val); + } + #endif + + return rv; +} +#endif + +#ifdef IN_COSMAP +static int +parse_cos(const char *command_name, struct switch_val *val) +{ + int rv = -1; + if(!strcmp(command_name, "Pri2Q")) { + rv = parse_cos_mappri2q(val); + } else if(!strcmp(command_name, "Pri2Ehq")) { + rv = parse_cos_mappri2ehq(val); + } + #ifndef IN_COSMAP_MINI + else if(!strcmp(command_name, "Dscp2Pri")) { + rv = parse_cos_mapdscp2pri(val); + } else if(!strcmp(command_name, "Dscp2Dp")) { + rv = parse_cos_mapdscp2dp(val); + } else if(!strcmp(command_name, "Up2Pri")) { + rv = parse_cos_mapup2pri(val); + } else if(!strcmp(command_name, "Up2Dp")) { + rv = parse_cos_mapup2dp(val); + } else if(!strcmp(command_name, "Dscp2ehPri")) { + rv = parse_cos_mapdscp2ehpri(val); + } else if(!strcmp(command_name, "Dscp2ehDp")) { + rv = parse_cos_mapdscp2ehdp(val); + } else if(!strcmp(command_name, "Up2ehPri")) { + rv = parse_cos_mapup2ehpri(val); + } else if(!strcmp(command_name, "Up2ehDp")) { + rv = parse_cos_mapup2ehdp(val); + } else if(!strcmp(command_name, "EgRemark")) { + rv = parse_cos_mapegremark(val); + } + #endif + + return rv; +} +#endif + +#ifdef IN_RATE +static int +parse_rate(const char *command_name, struct switch_val *val) +{ + int rv = -1; + if(!strcmp(command_name, "PortPolicer")) { + rv = parse_rate_portpolicer(val); + } else if(!strcmp(command_name, "PortShaper")) { + rv = parse_rate_portshaper(val); + } else if(!strcmp(command_name, "QueueShaper")) { + rv = parse_rate_queueshaper(val); + } else if(!strcmp(command_name, "AclPolicer")) { + rv = parse_rate_aclpolicer(val); + } else if(!strcmp(command_name, "PtAddRateByte")) { + rv = parse_rate_ptaddratebyte(val); + } else if(!strcmp(command_name, "PtGolflowen")) { + rv = parse_rate_ptgolflowen(val); + } + + return rv; +} +#endif + +#ifdef IN_PORTCONTROL +static int +parse_port(const char *command_name, struct switch_val *val) +{ + int rv = -1; + if(!strcmp(command_name, "TxHdr")) { + rv = parse_port_txhdr(val); + } else if(!strcmp(command_name, "RxHdr")) { + rv = parse_port_rxhdr(val); + } else if(!strcmp(command_name, "HdrType")) { + rv = parse_port_hdrtype(val); + } + #ifndef IN_PORTCONTROL_MINI + else if(!strcmp(command_name, "Duplex")) { + rv = parse_port_duplex(val); + } else if(!strcmp(command_name, "Speed")) { + rv = parse_port_speed(val); + } else if(!strcmp(command_name, "AutoAdv")) { + rv = parse_port_autoadv(val); + } else if(!strcmp(command_name, "AutoNegEnable")) { + rv = parse_port_autonegenable(val); + } else if(!strcmp(command_name, "AutoNegRestart")) { + rv = parse_port_autonegrestart(val); + } else if(!strcmp(command_name, "FlowCtrl")) { + rv = parse_port_flowctrl(val); + } else if(!strcmp(command_name, "FlowCtrlForceMode")) { + rv = parse_port_flowctrlforcemode(val); + } else if(!strcmp(command_name, "PowerSave")) { + rv = parse_port_powersave(val); + } else if(!strcmp(command_name, "Hibernate")) { + rv = parse_port_hibernate(val); + } else if(!strcmp(command_name, "TxMacStatus")) { + rv = parse_port_txmacstatus(val); + } else if(!strcmp(command_name, "RxMacStatus")) { + rv = parse_port_rxmacstatus(val); + } else if(!strcmp(command_name, "TxFcStatus")) { + rv = parse_port_txfcstatus(val); + } else if(!strcmp(command_name, "RxFcStatus")) { + rv = parse_port_rxfcstatus(val); + } else if(!strcmp(command_name, "BpStatus")) { + rv = parse_port_bpstatus(val); + } else if(!strcmp(command_name, "LinkForceMode")) { + rv = parse_port_linkforcemode(val); + } else if(!strcmp(command_name, "MacLoopback")) { + rv = parse_port_macloopback(val); + } else if(!strcmp(command_name, "CongeDrop")) { + rv = parse_port_congedrop(val); + } else if(!strcmp(command_name, "RingFcThresh")) { + rv = parse_port_ringfcthresh(val); + } else if(!strcmp(command_name, "Ieee8023az")) { + rv = parse_port_ieee8023az(val); + } else if(!strcmp(command_name, "Crossover")) { + rv = parse_port_crossover(val); + } else if(!strcmp(command_name, "PreferMedium")) { + rv = parse_port_prefermedium(val); + } else if(!strcmp(command_name, "FiberMode")) { + rv = parse_port_fibermode(val); + } else if(!strcmp(command_name, "LocalLoopback")) { + rv = parse_port_localloopback(val); + } else if(!strcmp(command_name, "RemoteLoopback")) { + rv = parse_port_remoteloopback(val); + } else if(!strcmp(command_name, "MagicFrameMac")) { + rv = parse_port_magicframemac(val); + } else if(!strcmp(command_name, "Wolstatus")) { + rv = parse_port_wolstatus(val); + } else if(!strcmp(command_name, "InterfaceMode")) { + rv = parse_port_interfacemode(val); + } else if(!strcmp(command_name, "InterfaceModeApply")) { + rv = parse_port_interfacemodeapply(val); + } else if(!strcmp(command_name, "Poweron")) { + rv = parse_port_poweron(val); + } else if(!strcmp(command_name, "Poweroff")) { + rv = parse_port_poweroff(val); + } else if(!strcmp(command_name, "Reset")) { + rv = parse_port_reset(val); + } else if(!strcmp(command_name, "FrameMaxSize")) { + rv = parse_port_framemaxsize(val); + } else if(!strcmp(command_name, "Mtu")) { + rv = parse_port_mtu(val); + } else if(!strcmp(command_name, "Mru")) { + rv = parse_port_mru(val); + } else if(!strcmp(command_name, "Srcfilter")) { + rv = parse_port_srcfilter(val); + } else if(!strcmp(command_name, "Interface3az")) { + rv = parse_port_interface8023az(val); + } else if(!strcmp(command_name, "Promiscmode")) { + rv = parse_port_promiscmode(val); + } else if(!strcmp(command_name, "Eeecfg")) { + rv = parse_port_eeecfg(val); + }else if(!strcmp(command_name, "Srcfiltercfg")) { + rv = parse_port_srcfiltercfg(val); + } else if(!strcmp(command_name, "SwitchPortLoopback")) { + rv = parse_switch_port_loopback(val); + } + #endif + + return rv; +} +#endif + +#ifdef IN_PORTVLAN +static int +parse_portvlan(const char *command_name, struct switch_val *val) +{ + int rv = -1; + if(!strcmp(command_name, "Ingress")) { + rv = parse_portvlan_ingress(val); + } else if(!strcmp(command_name, "Egress")) { + rv = parse_portvlan_egress(val); + } else if(!strcmp(command_name, "Member")) { + rv = parse_portvlan_member(val); + } else if(!strcmp(command_name, "ForceVid")) { + rv = parse_portvlan_forcevid(val); + } else if(!strcmp(command_name, "ForceMode")) { + rv = parse_portvlan_forcemode(val); + } else if(!strcmp(command_name, "SVlanTPID")) { + rv = parse_portvlan_svlantpid(val); + } else if(!strcmp(command_name, "DefaultSvid")) { + rv = parse_portvlan_defaultsvid(val); + } else if(!strcmp(command_name, "DefaultCvid")) { + rv = parse_portvlan_defaultcvid(val); + } else if (!strcmp(command_name, "GlobalQinQMode")) { + rv = parse_portvlan_globalqinqmode(val); + } else if (!strcmp(command_name, "PtQinQMode")) { + rv = parse_portvlan_ptqinqmode(val); +#ifdef HPPE + } else if (!strcmp(command_name, "InTpid")) { + rv = parse_portvlan_intpid(val); + } else if (!strcmp(command_name, "EgTpid")) { + rv = parse_portvlan_egtpid(val); + } else if (!strcmp(command_name, "IngressFilter")) { + rv = parse_portvlan_ingressfilter(val); + } else if (!strcmp(command_name, "DefaultVlanTag")) { + rv = parse_portvlan_defaultvlantag(val); + } else if (!strcmp(command_name, "TagPropagation")) { + rv = parse_portvlan_tagpropagation(val); + } else if (!strcmp(command_name, "TranslationMissAction")) { + rv = parse_portvlan_translationmissaction(val); +#endif + } else if (!strcmp(command_name, "EgMode")) { + rv = parse_portvlan_egmode(val); +#ifdef HPPE + } else if (!strcmp(command_name, "VsiEgMode")) { + rv = parse_portvlan_vsiegmode(val); + } else if (!strcmp(command_name, "VsiEgModeEn")) { + rv = parse_portvlan_vsiegmodeen(val); + } else if (!strcmp(command_name, "Counter")) { + rv = parse_portvlan_counter(val); + } else if (!strcmp(command_name, "TranslationAdv")) { + rv = parse_portvlan_translationadv(val); +#endif + } + #ifndef IN_PORTVLAN_MINI + else if(!strcmp(command_name, "InVlan")) { + rv = parse_portvlan_invlan(val); + } else if(!strcmp(command_name, "TlsMode")) { + rv = parse_portvlan_tlsmode(val); + } else if(!strcmp(command_name, "PriPropagation")) { + rv = parse_portvlan_pripropagation(val); + } else if(!strcmp(command_name, "VlanPropagation")) { + rv = parse_portvlan_vlanpropagation(val); + } else if(!strcmp(command_name, "Translation")) { + rv = parse_portvlan_translation(val); + } else if(!strcmp(command_name, "QinqMode")) { + rv = parse_portvlan_qinqmode(val); + } else if(!strcmp(command_name, "QinqRole")) { + rv = parse_portvlan_qinqrole(val); + } else if(!strcmp(command_name, "MacVlanXlt")) { + rv = parse_portvlan_macvlanxlt(val); + } else if(!strcmp(command_name, "Netiso")) { + rv = parse_portvlan_netiso(val); + } else if(!strcmp(command_name, "EgBypass")) { + rv = parse_portvlan_egbypass(val); + } else if(!strcmp(command_name, "Ptvrfid")) { + rv = parse_portvlan_ptvrfid(val); + } + #endif + + return rv; +} +#endif + +#ifdef IN_VLAN +static int +parse_vlan(const char *command_name, struct switch_val *val) +{ + int rv = -1; + if(!strcmp(command_name, "Entry")) { + rv = parse_vlan_entry(val); + } else if(!strcmp(command_name, "Member")) { + rv = parse_vlan_member(val); + } + #ifndef IN_VLAN_MINI + else if(!strcmp(command_name, "LearnSts")) { + rv = parse_vlan_learnsts(val); + } + #endif + + return rv; +} +#endif + +#ifdef IN_FDB +static int +parse_fdb(const char *command_name, struct switch_val *val) +{ + int rv = -1; + if(!strcmp(command_name, "PortLearn")) { + rv = parse_fdb_portlearn(val); + } + #ifndef IN_FDB_MINI + else if(!strcmp(command_name, "Resventry")) { + rv = parse_fdb_resventry(val); + } else if(!strcmp(command_name, "Entry")) { + rv = parse_fdb_entry(val); + } else if(!strcmp(command_name, "AgeCtrl")) { + rv = parse_fdb_agectrl(val); + } else if(!strcmp(command_name, "AgeTime")) { + rv = parse_fdb_agetime(val); + } else if(!strcmp(command_name, "Vlansmode")) { + rv = parse_fdb_vlansmode(val); + } else if(!strcmp(command_name, "Ptlearnlimit")) { + rv = parse_fdb_ptlearnlimit(val); + } else if(!strcmp(command_name, "Ptlearnexceedcmd")) { + rv = parse_fdb_ptlearnexceedcmd(val); + } else if(!strcmp(command_name, "Learnlimit")) { + rv = parse_fdb_learnlimit(val); + } else if(!strcmp(command_name, "Learnexceedcmd")) { + rv = parse_fdb_learnexceedcmd(val); + } else if(!strcmp(command_name, "PtLearnstatic")) { + rv = parse_fdb_ptlearnstatic(val); + } else if (!strcmp(command_name, "LearnCtrl")) { + rv = parse_fdb_learnctrl(val); + } else if (!strcmp(command_name, "PtLearnCtrl")) { + rv = parse_fdb_ptlearnctrl(val); + } else if (!strcmp(command_name, "PtStationMove")) { + rv = parse_fdb_ptstationmove(val); + } else if (!strcmp(command_name, "PtMacLimitCtrl")) { + rv = parse_fdb_ptmaclimitctrl(val); + } + #endif + + return rv; +} +#endif + +#ifdef IN_RSS_HASH +static int +parse_rsshash(const char *command_name, struct switch_val *val) +{ + int rv = -1; + if (!strcmp(command_name, "Config")) { + rv = parse_rsshash_config(val); + } + + return rv; +} +#endif + +#ifdef IN_IGMP +static int +parse_igmp(const char *command_name, struct switch_val *val) +{ + int rv = -1; + if(!strcmp(command_name, "Mode")) { + rv = parse_igmp_mode(val); + } else if(!strcmp(command_name, "Cmd")) { + rv = parse_igmp_cmd(val); + } else if(!strcmp(command_name, "PortJoin")) { + rv = parse_igmp_portjoin(val); + } else if(!strcmp(command_name, "PortLeave")) { + rv = parse_igmp_portleave(val); + } else if(!strcmp(command_name, "Rp")) { + rv = parse_igmp_rp(val); + } else if(!strcmp(command_name, "CreateStatus")) { + rv = parse_igmp_createstatus(val); + } else if(!strcmp(command_name, "Static")) { + rv = parse_igmp_static(val); + } else if(!strcmp(command_name, "Leaky")) { + rv = parse_igmp_leaky(val); + } else if(!strcmp(command_name, "Version3")) { + rv = parse_igmp_version3(val); + } else if(!strcmp(command_name, "Queue")) { + rv = parse_igmp_queue(val); + } else if(!strcmp(command_name, "Ptlearnlimit")) { + rv = parse_igmp_ptlearnlimit(val); + } else if(!strcmp(command_name, "Ptlearnexceedcmd")) { + rv = parse_igmp_ptlearnexceedcmd(val); + } else if(!strcmp(command_name, "Multi")) { + rv = parse_igmp_multi(val); + } + + return rv; +} +#endif + +#ifdef IN_SEC +static int +parse_sec(const char *command_name, struct switch_val *val) +{ + int rv = -1; + if(!strcmp(command_name, "Mac")) { + rv = parse_sec_mac(val); + } else if(!strcmp(command_name, "Ip")) { + rv = parse_sec_ip(val); + } else if(!strcmp(command_name, "Ip4")) { + rv = parse_sec_ip4(val); + } else if(!strcmp(command_name, "Ip6")) { + rv = parse_sec_ip6(val); + } else if(!strcmp(command_name, "Tcp")) { + rv = parse_sec_tcp(val); + } else if(!strcmp(command_name, "Udp")) { + rv = parse_sec_udp(val); + } else if(!strcmp(command_name, "Icmp4")) { + rv = parse_sec_icmp4(val); + } else if(!strcmp(command_name, "Icmp6")) { + rv = parse_sec_icmp6(val); +#ifdef HPPE + } else if (!strcmp(command_name, "Expctrl")) { + rv = parse_sec_expctrl(val); + } else if (!strcmp(command_name, "L3parser")) { + rv = parse_sec_l3parser(val); + } else if (!strcmp(command_name, "L4parser")) { + rv = parse_sec_l4parser(val); +#endif + } + + return rv; +} +#endif + +#ifdef IN_MISC +static int +parse_misc(const char *command_name, struct switch_val *val) +{ + int rv = -1; + if(!strcmp(command_name, "Eapolcmd")) { + rv = parse_misc_eapolcmd(val); + } else if(!strcmp(command_name, "Eapolstatus")) { + rv = parse_misc_eapolstatus(val); + } else if(!strcmp(command_name, "CpuPort")) { + rv = parse_misc_cpuport(val); + } else if(!strcmp(command_name, "PtUnkUcFilter")) { + rv = parse_misc_ptunkucfilter(val); + } else if(!strcmp(command_name, "PtUnkMcFilter")) { + rv = parse_misc_ptunkmcfilter(val); + } else if(!strcmp(command_name, "PtBcFilter")) { + rv = parse_misc_ptbcfilter(val); + } + #ifndef IN_MISC_MINI + else if(!strcmp(command_name, "CpuVid")) { + rv = parse_misc_cpuvid(val); + } else if(!strcmp(command_name, "FrameMaxSize")) { + rv = parse_misc_framemaxsize(val); + } else if(!strcmp(command_name, "AutoNeg")) { + rv = parse_misc_autoneg(val); + } else if(!strcmp(command_name, "PppoeCmd")) { + rv = parse_misc_pppoecmd(val); + } else if(!strcmp(command_name, "Pppoe")) { + rv = parse_misc_pppoe(val); + } else if(!strcmp(command_name, "PtDhcp")) { + rv = parse_misc_ptdhcp(val); + } else if(!strcmp(command_name, "Arpcmd")) { + rv = parse_misc_arpcmd(val); + } else if(!strcmp(command_name, "Rip")) { + rv = parse_misc_rip(val); + } else if(!strcmp(command_name, "Ptarpreq")) { + rv = parse_misc_ptarpreq(val); + } else if(!strcmp(command_name, "Ptarpack")) { + rv = parse_misc_ptarpack(val); + } else if(!strcmp(command_name, "Extendpppoe")) { + rv = parse_misc_extendpppoe(val); + } else if(!strcmp(command_name, "Pppoeid")) { + rv = parse_misc_pppoeid(val); + } else if(!strcmp(command_name, "RtdPppoe")) { + rv = parse_misc_rtdpppoe(val); + } else if(!strcmp(command_name, "GloMacAddr")) { + rv = parse_misc_glomacaddr(val); + } else if(!strcmp(command_name, "Framecrc")) { + rv = parse_misc_framecrc(val); + } else if(!strcmp(command_name, "Pppoeen")) { + rv = parse_misc_pppoeen(val); + } + #endif + + return rv; +} +#endif + +#ifdef IN_IP +static int +parse_ip(const char *command_name, struct switch_val *val) +{ + int rv = -1; +#ifndef IN_IP_MINI + if(!strcmp(command_name, "Hostentry")) { + rv = parse_ip_hostentry(val); + } else if(!strcmp(command_name, "Intfentry")) { + rv = parse_ip_intfentry(val); + } else if(!strcmp(command_name, "Ptarplearn")) { + rv = parse_ip_ptarplearn(val); + } else if(!strcmp(command_name, "Arplearn")) { + rv = parse_ip_arplearn(val); + } else if(!strcmp(command_name, "Ptipsrcguard")) { + rv = parse_ip_ptipsrcguard(val); + } else if(!strcmp(command_name, "Ptarpsrcguard")) { + rv = parse_ip_ptarpsrcguard(val); + } else if(!strcmp(command_name, "Routestatus")) { + rv = parse_ip_routestatus(val); + } else if(!strcmp(command_name, "Ipunksrc")) { + rv = parse_ip_ipunksrc(val); + } else if(!strcmp(command_name, "Arpunksrc")) { + rv = parse_ip_arpunksrc(val); + } else if(!strcmp(command_name, "IpAgetime")) { + rv = parse_ip_agetime(val); + } else if(!strcmp(command_name, "Wcmphashmode")) { + rv = parse_ip_wcmphashmode(val); + } else if(!strcmp(command_name, "Defaultflowcmd")) { + rv = parse_ip_defaultflowcmd(val); + } else if(!strcmp(command_name, "Defaultrtflowcmd")) { + rv = parse_ip_defaultrtflowcmd(val); + } else if(!strcmp(command_name, "HostRoute")) { + rv = parse_ip_hostroute(val); + } else if(!strcmp(command_name, "DefaultRoute")) { + rv = parse_ip_defaultroute(val); + } else if(!strcmp(command_name, "Vrfbaseaddr")) { + rv = parse_ip_vrfbaseaddr(val); + } else if(!strcmp(command_name, "Vrfbasemask")) { + rv = parse_ip_vrfbasemask(val); + } else if(!strcmp(command_name, "Rfsip4")) { + rv = parse_ip_rfsip4(val); + } else if(!strcmp(command_name, "Rfsip6")) { + rv = parse_ip_rfsip6(val); + } else if (!strcmp(command_name, "Vsiarpsg")) { + rv = parse_ip_vsiarpsg(val); + } else if (!strcmp(command_name, "Vsisg")) { + rv = parse_ip_vsisg(val); + } else if (!strcmp(command_name, "Portarpsg")) { + rv = parse_ip_portarpsg(val); + } else if (!strcmp(command_name, "Portsg")) { + rv = parse_ip_portsg(val); + } else if (!strcmp(command_name, "Pubip")) { + rv = parse_ip_pubip(val); + } else if (!strcmp(command_name, "Networkroute")) { + rv = parse_ip_networkroute(val); + } else if (!strcmp(command_name, "Intf")) { + rv = parse_ip_intf(val); + } else if (!strcmp(command_name, "Vsiintf")) { + rv = parse_ip_vsiintf(val); + } else if (!strcmp(command_name, "Portintf")) { + rv = parse_ip_portintf(val); + } else if (!strcmp(command_name, "Nexthop")) { + rv = parse_ip_nexthop(val); + } else if (!strcmp(command_name, "Portmac")) { + rv = parse_ip_portmac(val); + } else if (!strcmp(command_name, "Routemiss")) { + rv = parse_ip_routemiss(val); + } else if (!strcmp(command_name, "Mcmode")) { + rv = parse_ip_mcmode(val); + } else if (!strcmp(command_name, "Globalctrl")) { + rv = parse_ip_globalctrl(val); + } else if (!strcmp(command_name, "Hostentry")) { + rv = parse_ip_hostentry(val); + } +#endif + return rv; +} +#endif + +#ifdef IN_NAT +static int +parse_nat(const char *command_name, struct switch_val *val) +{ + int rv = -1; + if(!strcmp(command_name, "Natentry")) { + rv = parse_nat_natentry(val); + } else if(!strcmp(command_name, "Naptentry")) { + rv = parse_nat_naptentry(val); + } else if(!strcmp(command_name, "Flowentry")) { + rv = parse_nat_flowentry(val); + } else if(!strcmp(command_name, "Flowcookie")) { + rv = parse_nat_flowcookie(val); + } else if(!strcmp(command_name, "Flowrfs")) { + rv = parse_nat_flowrfs(val); + } else if(!strcmp(command_name, "Natstatus")) { + rv = parse_nat_natstatus(val); + } else if(!strcmp(command_name, "Naptstatus")) { + rv = parse_nat_naptstatus(val); + } else if(!strcmp(command_name, "Nathash")) { + rv = parse_nat_nathash(val); + } else if(!strcmp(command_name, "Naptmode")) { + rv = parse_nat_naptmode(val); + } else if(!strcmp(command_name, "Prvbaseaddr")) { + rv = parse_nat_prvbaseaddr(val); + } else if(!strcmp(command_name, "Prvaddrmode")) { + rv = parse_nat_prvaddrmode(val); + } else if(!strcmp(command_name, "Pubaddr")) { + rv = parse_nat_pubaddr(val); + } else if(!strcmp(command_name, "Natunksess")) { + rv = parse_nat_natunksess(val); + } else if(!strcmp(command_name, "Prvbasemask")) { + rv = parse_nat_prvbasemask(val); + } else if(!strcmp(command_name, "Global")) { + rv = parse_nat_global(val); + } + + return rv; +} +#endif + +#ifdef IN_STP +static int +parse_stp(const char *command_name, struct switch_val *val) +{ + int rv = -1; + if(!strcmp(command_name, "PortState")) { + rv = parse_stp_portstate(val); + } + + return rv; +} +#endif + +#ifdef IN_MIRROR +static int +parse_mirror(const char *command_name, struct switch_val *val) +{ + int rv = -1; + if(!strcmp(command_name, "AnalyPt")) { + rv = parse_mirror_analypt(val); + } else if(!strcmp(command_name, "PtIngress")) { + rv = parse_mirror_ptingress(val); + } else if(!strcmp(command_name, "PtEgress")) { + rv = parse_mirror_ptegress(val); + } else if (!strcmp(command_name, "AnalyCfg")) { + rv = parse_mirror_analycfg(val); + } + + return rv; +} +#endif + +#ifdef IN_LEAKY +static int +parse_leaky(const char *command_name, struct switch_val *val) +{ + int rv = -1; + if(!strcmp(command_name, "UcMode")) { + rv = parse_leaky_ucmode(val); + } else if(!strcmp(command_name, "McMode")) { + rv = parse_leaky_mcmode(val); + } else if(!strcmp(command_name, "ArpMode")) { + rv = parse_leaky_arpmode(val); + } else if(!strcmp(command_name, "PtUcMode")) { + rv = parse_leaky_ptucmode(val); + } else if(!strcmp(command_name, "PtMcMode")) { + rv = parse_leaky_ptmcmode(val); + } + + return rv; +} +#endif + +#ifdef IN_TRUNK +static int +parse_trunk(const char *command_name, struct switch_val *val) +{ + int rv = -1; + if(!strcmp(command_name, "Group")) { + rv = parse_trunk_group(val); + } else if(!strcmp(command_name, "Hashmode")) { + rv = parse_trunk_hashmode(val); + } else if (!strcmp(command_name, "Failover")) { + rv = parse_trunk_failover(val); + } + + return rv; +} +#endif + +#ifdef IN_MIB +static int +parse_mib(const char *command_name, struct switch_val *val) +{ + int rv = -1; + if(!strcmp(command_name, "Status")) { + rv = parse_mib_status(val); + } else if(!strcmp(command_name, "CpuKeep")) { + rv = parse_mib_cpukeep(val); + } + + return rv; +} +#endif + +#ifdef IN_ACL +static int +parse_acl(const char *command_name, struct switch_val *val, a_uint32_t dev_id) +{ + int rv = -1; + if(!strcmp(command_name, "Rule")) { + rv = parse_acl_rule(val, dev_id); + } else if(!strcmp(command_name, "Udfprofile")) { + rv = parse_acl_udfprofile(val); + } else if(!strcmp(command_name, "Udf")) { + rv = parse_acl_udf(val); + } + + return rv; +} +#endif + +#ifdef IN_FLOW +static int +parse_flow(const char *command_name, struct switch_val *val) +{ + int rv = -1; + if (!strcmp(command_name, "Entry")) { + rv = parse_flow_entry(val); + } else if (!strcmp(command_name, "Status")) { + rv = parse_flow_status(val); + } else if (!strcmp(command_name, "Agetime")) { + rv = parse_flow_age(val); + } else if (!strcmp(command_name, "Mgmt")) { + rv = parse_flow_mgmt(val); + } else if (!strcmp(command_name, "Host")) { + rv = parse_flow_host(val); + } else if (!strcmp(command_name, "Global")) { + rv = parse_flow_global(val); + } + + return rv; +} +#endif + +#ifdef IN_BM +static int +parse_bm(const char *command_name, struct switch_val *val) +{ + int rv = -1; + if (!strcmp(command_name, "Ctrl")) { + rv = parse_bm_ctrl(val); + } else if (!strcmp(command_name, "Portgroupmap")) { + rv = parse_bm_portgroupmap(val); + } else if (!strcmp(command_name, "Groupbuff")) { + rv = parse_bm_groupbuff(val); + } else if (!strcmp(command_name, "Portrsvbuff")) { + rv = parse_bm_portrsvbuff(val); + } else if (!strcmp(command_name, "Portsthresh")) { + rv = parse_bm_portsthresh(val); + } else if (!strcmp(command_name, "Portdthresh")) { + rv = parse_bm_portdthresh(val); + } + + return rv; +} +#endif + +#ifdef IN_QM +static int +parse_qm(const char *command_name, struct switch_val *val) +{ + int rv = -1; + if (!strcmp(command_name, "Ucastqbase")) { + rv = parse_qm_ucastqbase(val); + } else if (!strcmp(command_name, "Ucastpriclass")) { + rv = parse_qm_ucastpriclass(val); + } else if (!strcmp(command_name, "Mcastpriclass")) { + rv = parse_qm_mcastpriclass(val); + } else if (!strcmp(command_name, "Queue")) { + rv = parse_qm_queue(val); + } else if (!strcmp(command_name, "Ucasthash")) { + rv = parse_qm_ucasthash(val); + } else if (!strcmp(command_name, "Ucastdflthash")) { + rv = parse_qm_ucastdflthash(val); + } else if (!strcmp(command_name, "Mcastcpucode")) { + rv = parse_qm_mcastcpucode(val); + } else if (!strcmp(command_name, "Acctrl")) { + rv = parse_qm_acctrl(val); + } else if (!strcmp(command_name, "Acprebuffer")) { + rv = parse_qm_acprebuffer(val); + } else if (!strcmp(command_name, "Acqgroup")) { + rv = parse_qm_acqgroup(val); + } else if (!strcmp(command_name, "Acstaticthresh")) { + rv = parse_qm_acsthresh(val); + } else if (!strcmp(command_name, "Acdynamicthresh")) { + rv = parse_qm_acdthresh(val); + } else if (!strcmp(command_name, "Acgroupbuff")) { + rv = parse_qm_acgbuff(val); + } else if (!strcmp(command_name, "Cntctrl")) { + rv = parse_qm_cntctrl(val); + } else if (!strcmp(command_name, "Cnt")) { + rv = parse_qm_cnt(val); + } else if (!strcmp(command_name, "Enqueue")) { + rv = parse_qm_enqueue(val); + } else if (!strcmp(command_name, "Srcprofile")) { + rv = parse_qm_srcprofile(val); + } + + return rv; +} +#endif + +#ifdef IN_SERVCODE +static int +parse_servcode(const char *command_name, struct switch_val *val) +{ + int rv = -1; + if (!strcmp(command_name, "Config")) { + rv = parse_servcode_config(val); + } else if (!strcmp(command_name, "Loopcheck")) { + rv = parse_servcode_loopcheck(val); + } + + return rv; +} +#endif + +#ifdef IN_CTRLPKT +static int +parse_ctrlpkt(const char *command_name, struct switch_val *val) +{ + int rv = -1; + if (!strcmp(command_name, "EthernetType")) { + rv = parse_ctrlpkt_ethernettype(val); + } else if (!strcmp(command_name, "Rfdb")) { + rv = parse_ctrlpkt_rfdb(val); + } else if (!strcmp(command_name, "AppProfile")) { + rv = parse_ctrlpkt_appprofile(val); + } + + return rv; +} +#endif + +#ifdef IN_POLICER +static int +parse_policer(const char *command_name, struct switch_val *val) +{ + int rv = -1; + if(!strcmp(command_name, "Timeslot")) { + rv = parse_policer_timeslot(val); + } else if(!strcmp(command_name, "Fcscompensation")) { + rv = parse_policer_fcscompensation(val); + } else if(!strcmp(command_name, "Portentry")) { + rv = parse_policer_portentry(val); + } else if(!strcmp(command_name, "Aclentry")) { + rv = parse_policer_aclentry(val); + } + + return rv; +} +#endif + +#ifdef IN_SHAPER +static int +parse_shaper(const char *command_name, struct switch_val *val) +{ + int rv = -1; + if(!strcmp(command_name, "Porttimeslot")) { + rv = parse_shaper_porttimeslot(val); + } else if(!strcmp(command_name, "Flowtimeslot")) { + rv = parse_shaper_flowtimeslot(val); + } else if(!strcmp(command_name, "Queuetimeslot")) { + rv = parse_shaper_queuetimeslot(val); + } else if(!strcmp(command_name, "Ipgcompensation")) { + rv = parse_shaper_ipgcompensation(val); + } else if(!strcmp(command_name, "Porttoken")) { + rv = parse_shaper_porttoken(val); + } else if(!strcmp(command_name, "Flowtoken")) { + rv = parse_shaper_flowtoken(val); + } else if(!strcmp(command_name, "Queuetoken")) { + rv = parse_shaper_queuetoken(val); + } else if(!strcmp(command_name, "Portshaper")) { + rv = parse_shaper_portshaper(val); + } else if(!strcmp(command_name, "Queueshaper")) { + rv = parse_shaper_queueshaper(val); + } else if(!strcmp(command_name, "Flowshaper")) { + rv = parse_shaper_flowshaper(val); + } + + return rv; +} +#endif + +#ifdef IN_VSI +static int +parse_vsi_portbasedvsi(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "vsi")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_vsi_vlanbasedvsi(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "port_id")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "svid")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "cvid")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "vsi")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_vsi_learnctrl(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "vsi")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "learn_status")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "learnaction")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_vsi_stationmove(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "vsi")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "stationmove_en")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "stationmove_action")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_vsi_member(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "vsi")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "membership")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "unknown_unicast_membership")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "unknown_multicast_membership")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "broadcast_membership")) { + val_ptr[4] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_vsi(const char *command_name, struct switch_val *val) +{ + int rv = -1; + if (!strcmp(command_name, "Portbasedvsi")) { + rv = parse_vsi_portbasedvsi(val); + } else if (!strcmp(command_name, "Vlanbasedvsi")) { + rv = parse_vsi_vlanbasedvsi(val); + } else if (!strcmp(command_name, "Learnctrl")) { + rv = parse_vsi_learnctrl(val); + } else if (!strcmp(command_name, "Stationmove")) { + rv = parse_vsi_stationmove(val); + } else if (!strcmp(command_name, "Member")) { + rv = parse_vsi_member(val); + } + + return rv; +} +#endif + +static int +parse_debug_module_func(struct switch_val *val) +{ + struct switch_ext *switch_ext_p, *ext_value_p; + int rv = 0; + + switch_ext_p = val->value.ext_val; + while (switch_ext_p) { + ext_value_p = switch_ext_p; + + if (!strcmp(ext_value_p->option_name, "name")) { + switch_ext_p = switch_ext_p->next; + continue; + } else if (!strcmp(ext_value_p->option_name, "module")) { + val_ptr[0] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "bitmap0")) { + val_ptr[1] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "bitmap1")) { + val_ptr[2] = (char*)ext_value_p->option_value; + } else if (!strcmp(ext_value_p->option_name, "bitmap2")) { + val_ptr[3] = (char*)ext_value_p->option_value; + } else { + rv = -1; + break; + } + + parameter_length++; + switch_ext_p = switch_ext_p->next; + } + + return rv; +} + +static int +parse_debug(const char *command_name, struct switch_val *val) +{ + int rv = -1; + if (!strcmp(command_name, "Module_func")) { + rv = parse_debug_module_func(val); + } + return rv; +} + +static int name_transfer(char *name, char *module, char *cmd) +{ + char *p; + unsigned int i = 0, len = 0; + + p = name + 1; + len = strlen(name); + for(i=1; i='A'&&*p<='Z') + break; + p++; + } + + if(ivalue.ext_val; + + memset(whole_command_line, 0, sizeof(whole_command_line)); + memset(module_name, 0, sizeof(module_name)); + memset(command_name, 0, sizeof(command_name)); + while(switch_ext_p) { + ext_value_p = switch_ext_p; + if(!strcmp(ext_value_p->option_name, "name")) { + name_transfer((char*)ext_value_p->option_value, module_name, command_name); + SSDK_DEBUG("module_name:%s command_name:%s\n", module_name, command_name); + break; + } + switch_ext_p = switch_ext_p->next; + } + + parameter_length = 0; + + if(!strcmp(module_name, "Qos")) { +#ifdef IN_QOS + rv = parse_qos(command_name, val); +#endif + } else if(!strcmp(module_name, "Cosmap")) { +#ifdef IN_COSMAP + rv = parse_cos(command_name, val); +#endif + } else if(!strcmp(module_name, "Rate")) { +#ifdef IN_RATE + rv = parse_rate(command_name, val); +#endif + } else if(!strcmp(module_name, "Port")) { +#ifdef IN_PORTCONTROL + rv = parse_port(command_name, val); +#endif + } else if(!strcmp(module_name, "Portvlan")) { +#ifdef IN_PORTVLAN + rv = parse_portvlan(command_name, val); +#endif + } else if(!strcmp(module_name, "Vlan")) { +#ifdef IN_VLAN + rv = parse_vlan(command_name, val); +#endif + } else if(!strcmp(module_name, "Fdb")) { +#ifdef IN_FDB + rv = parse_fdb(command_name, val); +#endif + } else if(!strcmp(module_name, "Rsshash")) { +#ifdef IN_RSS_HASH + rv = parse_rsshash(command_name, val); +#endif + } else if(!strcmp(module_name, "Igmp")) { +#ifdef IN_IGMP + rv = parse_igmp(command_name, val); +#endif + } else if(!strcmp(module_name, "Sec")) { +#ifdef IN_SEC + rv = parse_sec(command_name, val); +#endif + } else if(!strcmp(module_name, "Misc")) { +#ifdef IN_MISC + rv = parse_misc(command_name, val); +#endif + } else if(!strcmp(module_name, "Ip")) { +#ifdef IN_IP + rv = parse_ip(command_name, val); +#endif + } else if(!strcmp(module_name, "Nat")) { +#ifdef IN_NAT + rv = parse_nat(command_name, val); +#endif + } else if(!strcmp(module_name, "Stp")) { +#ifdef IN_STP + rv = parse_stp(command_name, val); +#endif + } else if(!strcmp(module_name, "Mirror")) { +#ifdef IN_MIRROR + rv = parse_mirror(command_name, val); +#endif + } else if(!strcmp(module_name, "Leaky")) { +#ifdef IN_LEAKY + rv = parse_leaky(command_name, val); +#endif + } else if(!strcmp(module_name, "Trunk")) { +#ifdef IN_TRUNK + rv = parse_trunk(command_name, val); +#endif + } else if(!strcmp(module_name, "Mib")) { +#ifdef IN_MIB + rv = parse_mib(command_name, val); +#endif + } else if(!strcmp(module_name, "Acl")) { +#ifdef IN_ACL + rv = parse_acl(command_name, val, priv->device_id); +#endif + } else if(!strcmp(module_name, "Flow")) { +#ifdef IN_FLOW + rv = parse_flow(command_name, val); +#endif + } else if(!strcmp(module_name, "Bm")) { +#ifdef IN_BM + rv = parse_bm(command_name, val); +#endif + } else if(!strcmp(module_name, "Qm")) { +#ifdef IN_QM + rv = parse_qm(command_name, val); +#endif + } else if(!strcmp(module_name, "Servcode")) { +#ifdef IN_SERVCODE + rv = parse_servcode(command_name, val); +#endif + } else if(!strcmp(module_name, "Ctrlpkt")) { +#ifdef IN_CTRLPKT + rv = parse_ctrlpkt(command_name, val); +#endif + } else if(!strcmp(module_name, "Policer")) { +#ifdef IN_POLICER + rv = parse_policer(command_name, val); +#endif + } else if(!strcmp(module_name, "Shaper")) { +#ifdef IN_SHAPER + rv = parse_shaper(command_name, val); +#endif + } else if(!strcmp(module_name, "Vsi")) { +#ifdef IN_VSI + rv = parse_vsi(command_name, val); +#endif + } else if(!strcmp(module_name, "Debug")) { + rv = parse_debug(command_name, val); + } + + if(!rv) { + strlcat(whole_command_line, module_name, sizeof(whole_command_line)); + strlcat(whole_command_line, " ", sizeof(whole_command_line)); + strlcat(whole_command_line, command_name, sizeof(whole_command_line)); + strlcat(whole_command_line, " ", sizeof(whole_command_line)); + strlcat(whole_command_line, "set", sizeof(whole_command_line)); + strlcat(whole_command_line, " ", sizeof(whole_command_line)); + for(i=0; idevice_id); + set_talk_mode(0); + rv = cmd_run_one(whole_command_line); + set_talk_mode(1); + + SSDK_DEBUG("cmd_run_one: ret=%d\r\n", rv); + + return rv; +} diff --git a/feeds/ipq807x/qca-ssdk/src/src/ref/ref_vlan.c b/feeds/ipq807x/qca-ssdk/src/src/ref/ref_vlan.c new file mode 100755 index 000000000..4b99f2c4c --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/ref/ref_vlan.c @@ -0,0 +1,562 @@ +/* + * Copyright (c) 2012, 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 "fal_init.h" +#include "fal_misc.h" +#include "fal_mib.h" +#include "fal_port_ctrl.h" +#include "fal_portvlan.h" +#include "fal_fdb.h" +#include "fal_stp.h" +#include "fal_igmp.h" +#include "fal_qos.h" +#include "fal_acl.h" +#include "hsl.h" +#include "hsl_dev.h" +#include "ssdk_init.h" +#include "ssdk_dts.h" +#include "hsl_phy.h" +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0)) +#include +#endif +#include +#include +#include +#include "ssdk_plat.h" +#include "ref_vlan.h" +#ifdef BOARD_AR71XX +#include "ssdk_uci.h" +#endif + + +extern ssdk_chip_type SSDK_CURRENT_CHIP_TYPE; + +#if !defined(IN_VLAN_MINI) +sw_error_t +qca_lan_wan_cfg_set(a_uint32_t dev_id, qca_lan_wan_cfg_t *lan_wan_cfg) +{ + a_uint32_t i = 0, lan_bmp = 0, wan_bmp = 0; + sw_error_t rv = SW_OK; + fal_vlan_t vlan_entry; + + SW_RTN_ON_NULL(lan_wan_cfg); + + switch (SSDK_CURRENT_CHIP_TYPE) { + case CHIP_ISIS: + case CHIP_ISISC: + case CHIP_DESS: + break; + default: + return SW_NOT_SUPPORTED; + } + + fal_vlan_flush(dev_id); + aos_mem_set(&vlan_entry, 0, sizeof(vlan_entry)); + + if (lan_wan_cfg->lan_only_mode) { +#if defined(IN_PORTVLAN) + while (i < sizeof(lan_wan_cfg->v_port_info)/sizeof(lan_wan_cfg->v_port_info[0])) { + if (lan_wan_cfg->v_port_info[i].valid) { + /* use the portbased vlan table for forwarding */ + rv = fal_port_1qmode_set(dev_id, + lan_wan_cfg->v_port_info[i].port_id, + FAL_1Q_DISABLE); + SW_RTN_ON_ERROR(rv); + rv = fal_port_egvlanmode_set(dev_id, + lan_wan_cfg->v_port_info[i].port_id, + FAL_EG_UNMODIFIED); + SW_RTN_ON_ERROR(rv); + rv = fal_port_default_cvid_set(dev_id, + lan_wan_cfg->v_port_info[i].port_id, + 0); + SW_RTN_ON_ERROR(rv); + lan_bmp |= (0x1 << lan_wan_cfg->v_port_info[i].port_id); + } + i++; + } + /* CPU port 0 configurations */ + rv = fal_port_1qmode_set(dev_id, SSDK_PORT_CPU, FAL_1Q_DISABLE); + SW_RTN_ON_ERROR(rv); + rv = fal_port_egvlanmode_set(dev_id, SSDK_PORT_CPU, FAL_EG_UNMODIFIED); + SW_RTN_ON_ERROR(rv); + rv = fal_port_default_cvid_set(dev_id, SSDK_PORT_CPU, 0); + SW_RTN_ON_ERROR(rv); + rv = fal_portvlan_member_update(dev_id, SSDK_PORT_CPU, lan_bmp); + SW_RTN_ON_ERROR(rv); +#endif + } else { + while (i < sizeof(lan_wan_cfg->v_port_info)/sizeof(lan_wan_cfg->v_port_info[0])) { + if (lan_wan_cfg->v_port_info[i].valid) { + rv = fal_vlan_find(dev_id, + lan_wan_cfg->v_port_info[i].vid, &vlan_entry); + /* create vlan entry if the vlan entry does not exist */ + if (rv == SW_NOT_FOUND) { + rv = fal_vlan_create(dev_id, + lan_wan_cfg->v_port_info[i].vid); + SW_RTN_ON_ERROR(rv); +#if defined(IN_PORTVLAN) + rv = fal_port_1qmode_set(dev_id, + SSDK_PORT_CPU, FAL_1Q_SECURE); + SW_RTN_ON_ERROR(rv); +#endif + rv = fal_vlan_member_add(dev_id, + lan_wan_cfg->v_port_info[i].vid, + SSDK_PORT_CPU, FAL_EG_TAGGED); + SW_RTN_ON_ERROR(rv); + } + rv = fal_vlan_member_add(dev_id, + lan_wan_cfg->v_port_info[i].vid, + lan_wan_cfg->v_port_info[i].port_id, + FAL_EG_UNTAGGED); + SW_RTN_ON_ERROR(rv); +#if defined(IN_PORTVLAN) + rv = fal_port_1qmode_set(dev_id, + lan_wan_cfg->v_port_info[i].port_id, + FAL_1Q_SECURE); + SW_RTN_ON_ERROR(rv); + + rv = fal_port_default_cvid_set(dev_id, + lan_wan_cfg->v_port_info[i].port_id, + lan_wan_cfg->v_port_info[i].vid); + SW_RTN_ON_ERROR(rv); +#endif + if (lan_wan_cfg->v_port_info[i].is_wan_port) { + wan_bmp |= (0x1 << lan_wan_cfg->v_port_info[i].port_id); + } else { + lan_bmp |= (0x1 << lan_wan_cfg->v_port_info[i].port_id); + } + } + i++; + } + } + ssdk_lan_bmp_set(dev_id, lan_bmp); + ssdk_wan_bmp_set(dev_id, wan_bmp); + qca_ssdk_port_bmp_set(dev_id, lan_bmp|wan_bmp); +#if defined(DESS) && defined(IN_TRUNK) + if(SSDK_CURRENT_CHIP_TYPE == CHIP_DESS) { + ssdk_dess_trunk_init(dev_id, wan_bmp); + } +#endif +#if defined(IN_PORTVLAN) + ssdk_portvlan_init(dev_id); +#endif + 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 = SW_OK; + fal_vlan_t vlan_entry; + fal_pbmp_t member_pmap, lan_bmp, wan_bmp; + a_uint32_t port_id, entry_id, vlan_id; + + SW_RTN_ON_NULL(lan_wan_cfg); + + switch (SSDK_CURRENT_CHIP_TYPE) { + case CHIP_ISIS: + case CHIP_ISISC: + case CHIP_DESS: + break; + default: + return SW_NOT_SUPPORTED; + } + + lan_bmp = ssdk_lan_bmp_get(dev_id); + wan_bmp = ssdk_wan_bmp_get(dev_id); + + member_pmap = lan_bmp | wan_bmp; + vlan_id = FAL_NEXT_ENTRY_FIRST_ID; + entry_id = 0; + + while (1) { + aos_mem_set(&vlan_entry, 0, sizeof(vlan_entry)); + rv = fal_vlan_next(dev_id, vlan_id, &vlan_entry); + if (rv != SW_OK) { + break; + } + + /* + * the special port id should be existed only in one vlan entry + * starting from port 1. + */ + port_id = 1; + while (vlan_entry.mem_ports >> port_id) { + if (((vlan_entry.mem_ports >> port_id) & 1) && + SW_IS_PBMP_MEMBER(member_pmap, port_id)) { + lan_wan_cfg->v_port_info[entry_id].port_id = port_id; + lan_wan_cfg->v_port_info[entry_id].vid = vlan_entry.vid; + lan_wan_cfg->v_port_info[entry_id].valid = A_TRUE; + lan_wan_cfg->v_port_info[entry_id].is_wan_port = + SW_IS_PBMP_MEMBER(wan_bmp, port_id) ? A_TRUE : A_FALSE; + entry_id++; + } + port_id++; + } + vlan_id = vlan_entry.vid; + } + + /* + * no vlan entry exists, the portbased vlan used. + */ +#if defined(IN_PORTVLAN) + if (entry_id == 0) { + lan_wan_cfg->lan_only_mode = A_TRUE; + port_id = 1; + while (lan_bmp >> port_id) { + if ((lan_bmp >> port_id) & 1) { + lan_wan_cfg->v_port_info[entry_id].port_id = port_id; + lan_wan_cfg->v_port_info[entry_id].vid = 0; + lan_wan_cfg->v_port_info[entry_id].is_wan_port = A_FALSE; + + member_pmap = 0; +#if !defined(IN_PORTVLAN_MINI) + fal_portvlan_member_get(dev_id, port_id, &member_pmap); +#endif + lan_wan_cfg->v_port_info[entry_id].valid = + member_pmap ? A_TRUE : A_FALSE; + entry_id++; + } + port_id++; + } + } +#endif + return SW_OK; +} +#endif + +int +qca_ar8327_sw_enable_vlan0(a_uint32_t dev_id, a_bool_t enable, a_uint8_t portmap) +{ + fal_vlan_t entry; + fal_acl_rule_t rule; + int i = 0; + + memset(&entry, 0, sizeof(fal_vlan_t)); + memset(&rule, 0, sizeof(fal_acl_rule_t)); + for (i = 0; i < AR8327_NUM_PORTS; i ++) { + fal_port_tls_set(dev_id, i, A_FALSE); + fal_port_vlan_propagation_set(dev_id, i, FAL_VLAN_PROPAGATION_REPLACE); + } + + if (enable) { + entry.fid = 0; + entry.mem_ports = portmap; + entry.unmodify_ports = portmap; + entry.vid = 0; + fal_vlan_entry_append(dev_id, &entry); + for (i = 0; i < AR8327_NUM_PORTS; i++) { + if (portmap & (0x1 << i)) { + fal_port_egvlanmode_set(dev_id, i, FAL_EG_UNTOUCHED); + fal_port_tls_set(dev_id, i, A_TRUE); + fal_port_vlan_propagation_set(dev_id, i, FAL_VLAN_PROPAGATION_DISABLE); + fal_acl_port_udf_profile_set(dev_id, i, FAL_ACL_UDF_TYPE_L2, 12, 4); + } + } + + fal_acl_list_creat(dev_id, 0, 0); + rule.rule_type = FAL_ACL_RULE_UDF; + rule.udf_len = 4; + rule.udf_val[0] = 0x81; + rule.udf_val[1] = 0; + rule.udf_val[2] = 0; + rule.udf_val[3] = 0; + rule.udf_mask[0] = 0xff; + rule.udf_mask[1] = 0xff; + rule.udf_mask[2] = 0xf; + rule.udf_mask[3] = 0xff; + FAL_FIELD_FLG_SET(rule.field_flg, FAL_ACL_FIELD_UDF); + FAL_ACTION_FLG_SET(rule.action_flg, FAL_ACL_ACTION_REMARK_LOOKUP_VID); + fal_acl_rule_add(dev_id, 0, 0, 1, &rule); + for (i = 0; i < AR8327_NUM_PORTS; i ++) { + fal_acl_list_unbind(dev_id, 0, 0, 0, i); + if (portmap & (0x1 << i)) { + fal_acl_list_bind(dev_id, 0, 0, 0, i); + } + } + fal_acl_status_set(dev_id, A_TRUE); + } + else { + fal_acl_rule_delete(dev_id, 0, 0, 1); + } + + return 0; +} + +#if defined(IN_SWCONFIG) +int +qca_ar8327_sw_set_vlan(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct qca_phy_priv *priv = qca_phy_priv_get(dev); + + priv->vlan = !!val->value.i; + + #ifdef BOARD_AR71XX + if(SSDK_CURRENT_CHIP_TYPE == CHIP_SHIVA) { + ssdk_uci_sw_set_vlan(attr, val); + } + #endif + + return 0; +} + +int +qca_ar8327_sw_get_vlan(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct qca_phy_priv *priv = qca_phy_priv_get(dev); + + val->value.i = priv->vlan; + + return 0; +} + +int +qca_ar8327_sw_set_vid(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct qca_phy_priv *priv = qca_phy_priv_get(dev); + + priv->vlan_id[val->port_vlan] = val->value.i; + +#ifdef BOARD_AR71XX + if(SSDK_CURRENT_CHIP_TYPE == CHIP_SHIVA) { + ssdk_uci_sw_set_vid(attr, val); + } +#endif + + return 0; +} + +int +qca_ar8327_sw_get_vid(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct qca_phy_priv *priv = qca_phy_priv_get(dev); + + val->value.i = priv->vlan_id[val->port_vlan]; + + return 0; +} + +int +qca_ar8327_sw_get_pvid(struct switch_dev *dev, int port, int *vlan) +{ + struct qca_phy_priv *priv = qca_phy_priv_get(dev); + + *vlan = priv->pvid[port]; + + return 0; +} + +int +qca_ar8327_sw_set_pvid(struct switch_dev *dev, int port, int vlan) +{ + struct qca_phy_priv *priv = qca_phy_priv_get(dev); + + /* make sure no invalid PVIDs get set */ + if (vlan >= dev->vlans) + return -1; + + priv->pvid[port] = vlan; + +#ifdef BOARD_AR71XX + if(SSDK_CURRENT_CHIP_TYPE == CHIP_SHIVA) { + ssdk_uci_sw_set_pvid(port, vlan); + } +#endif + + return 0; +} + +int +qca_ar8327_sw_get_ports(struct switch_dev *dev, struct switch_val *val) +{ + struct qca_phy_priv *priv = qca_phy_priv_get(dev); + a_uint8_t ports = priv->vlan_table[val->port_vlan]; + int i; + + val->len = 0; + for (i = 0; i < dev->ports; i++) { + struct switch_port *p; + + if (!(ports & (1 << i))) + continue; + + p = &val->value.ports[val->len++]; + p->id = i; + if (priv->vlan_tagged[val->port_vlan] & (1 << i)) + p->flags = (1 << SWITCH_PORT_FLAG_TAGGED); + else + p->flags = 0; + + /*Handle for VLAN 0*/ + if (val->port_vlan == 0) + p->flags = (1 << SWITCH_PORT_FLAG_TAGGED); + } + + return 0; +} + +int +qca_ar8327_sw_set_ports(struct switch_dev *dev, struct switch_val *val) +{ + struct qca_phy_priv *priv = qca_phy_priv_get(dev); + a_uint8_t *vt = &priv->vlan_table[val->port_vlan]; + int i; + +#ifdef BOARD_AR71XX + if(SSDK_CURRENT_CHIP_TYPE == CHIP_SHIVA) { + ssdk_uci_sw_set_ports(val); + } +#endif + + /*Handle for VLAN 0*/ + if (val->port_vlan == 0) { + priv->vlan_table[0] = 0; + for (i = 0; i < val->len; i++) { + struct switch_port *p = &val->value.ports[i]; + priv->vlan_table[0] |= (1 << p->id); + } + + return 0; + } + if (priv->vlan_id[val->port_vlan] == 0) + priv->vlan_id[val->port_vlan] = val->port_vlan; + *vt = 0; + for (i = 0; i < val->len; i++) { + struct switch_port *p = &val->value.ports[i]; + + if (p->flags & (1 << SWITCH_PORT_FLAG_TAGGED)) { + priv->vlan_tagged[val->port_vlan] |= (1 << p->id); + } else { + priv->vlan_tagged[val->port_vlan] &= ~(1 << p->id); + priv->pvid[p->id] = val->port_vlan; + } + + *vt |= 1 << p->id; + } + + return 0; +} + +int +qca_ar8327_sw_hw_apply(struct switch_dev *dev) +{ + struct qca_phy_priv *priv = qca_phy_priv_get(dev); + fal_pbmp_t *portmask = NULL; + int i, j; + + if (priv->version == QCA_VER_HPPE) { + return 0; + } + + portmask = aos_mem_alloc(sizeof(fal_pbmp_t) * dev->ports); + if (portmask == NULL) { + SSDK_ERROR("%s: portmask malloc failed. \n", __func__); + return -1; + } + memset(portmask, 0, sizeof(fal_pbmp_t) * dev->ports); + + mutex_lock(&priv->reg_mutex); + + if (!priv->init) { + /*Handle VLAN 0 entry*/ + if (priv->vlan_id[0] == 0 && priv->vlan_table[0] == 0) { + qca_ar8327_sw_enable_vlan0(priv->device_id, A_FALSE, 0); + } + + /* calculate the port destination masks and load vlans + * into the vlan translation unit */ + for (j = 0; j < AR8327_MAX_VLANS; j++) { + u8 vp = priv->vlan_table[j]; + + if (!vp) { + fal_vlan_delete(priv->device_id, priv->vlan_id[j]); + continue; + } + fal_vlan_delete(priv->device_id, priv->vlan_id[j]); + fal_vlan_create(priv->device_id, priv->vlan_id[j]); + + for (i = 0; i < dev->ports; i++) { + u8 mask = (1 << i); + if (vp & mask) { + fal_vlan_member_add(priv->device_id, priv->vlan_id[j], i, + (mask & priv->vlan_tagged[j])? FAL_EG_TAGGED : FAL_EG_UNTAGGED); + portmask[i] |= vp & ~mask; + } + } + if (SSDK_CURRENT_CHIP_TYPE == CHIP_SHIVA) + fal_vlan_member_update(priv->device_id,priv->vlan_id[j],vp,0); + } + + /*Hanlde VLAN 0 entry*/ + if (priv->vlan_id[0] == 0 && priv->vlan_table[0]) { + qca_ar8327_sw_enable_vlan0(priv->device_id,A_TRUE, priv->vlan_table[0]); + } + + } else { + /* vlan disabled: port based vlan used */ + ssdk_portvlan_init(priv->device_id); + } + + /* update the port destination mask registers and tag settings */ + for (i = 0; i < dev->ports; i++) { + int pvid; + fal_pt_1qmode_t ingressMode; + fal_pt_1q_egmode_t egressMode; + + if (priv->vlan) { + pvid = priv->vlan_id[priv->pvid[i]]; + ingressMode = FAL_1Q_SECURE; + } else { + pvid = 0; + ingressMode = FAL_1Q_DISABLE; + } + egressMode = FAL_EG_UNTOUCHED; + + fal_port_1qmode_set(priv->device_id, i, ingressMode); + fal_port_egvlanmode_set(priv->device_id, i, egressMode); + fal_port_default_cvid_set(priv->device_id, i, pvid); + if (!priv->init && priv->vlan) { + fal_portvlan_member_update(priv->device_id, i, portmask[i]); + } + } + + aos_mem_free(portmask); + portmask = NULL; + + mutex_unlock(&priv->reg_mutex); + + return 0; +} +#endif + + diff --git a/feeds/ipq807x/qca-ssdk/src/src/ref/ref_vsi.c b/feeds/ipq807x/qca-ssdk/src/src/ref/ref_vsi.c new file mode 100755 index 000000000..1c7900d09 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/ref/ref_vsi.c @@ -0,0 +1,494 @@ +/* + * 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 "ref_vsi.h" +#include "ssdk_init.h" +#include "ssdk_plat.h" + +#define PPE_VSI_MAX FAL_VSI_MAX +#define PPE_VSI_RESERVE_MAX 6 + +static ref_vsi_t ref_vsi_mapping[SW_MAX_NR_DEV][PPE_VSI_MAX+1] ={{{0, 0, NULL}, + {0, 0, NULL}, + {0, 0, NULL}}}; +static a_uint32_t default_port_vsi[PPE_VSI_PPORT_NR] = {0, 1, 2, 3, 4, 5, 6};/*PPORT*/ + +static aos_lock_t ppe_vlan_vsi_lock[SW_MAX_NR_DEV]; + +static sw_error_t +_ppe_vsi_member_init(a_uint32_t dev_id, a_uint32_t vsi_id) +{ + fal_vsi_member_t vsi_member; + + aos_mem_zero(&vsi_member, sizeof(vsi_member)); + + vsi_member.member_ports = 0x1; + vsi_member.umc_ports = 0x1; + vsi_member.uuc_ports = 0x1; + vsi_member.bc_ports = 0x1; + + fal_vsi_member_set(dev_id, vsi_id, &vsi_member); + + return SW_OK; +} + +static sw_error_t +_ppe_vsi_member_update(a_uint32_t dev_id, a_uint32_t vsi_id, + fal_port_t port_id, a_uint32_t op) +{ + sw_error_t rv; + fal_vsi_member_t vsi_member; + + rv = fal_vsi_member_get( dev_id, vsi_id, &vsi_member); + if( rv != SW_OK ) + return rv; + if( PPE_VSI_DEL == op ) + { + vsi_member.member_ports &= (~(1<stag_vid) && + (ctag_vid == p_vsi_info->ctag_vid)) + { + p_vsi_info->vport_bitmap |= 1 << port_id; + break; + } + p_vsi_info = p_vsi_info->pNext; + } + + if(p_vsi_info == NULL)/*create a new entry if no match*/ + { + SSDK_DEBUG("port %d svlan %d cvlan %d vsi %d create new entry\n", + port_id, stag_vid, ctag_vid, vsi_id); + p_vsi_info = aos_mem_alloc(sizeof(ref_vlan_info_t)); + if(p_vsi_info == NULL) + { + SSDK_ERROR("port %d svlan %d cvlan %d vsi %d aos_mem_alloc fail\n", + port_id, stag_vid, ctag_vid, vsi_id); + return SW_NO_RESOURCE; + } + p_vsi_info->vport_bitmap = 1 << port_id; + p_vsi_info->stag_vid = stag_vid; + p_vsi_info->ctag_vid = ctag_vid; + p_vsi_info->pNext = (ref_vsi_mapping[dev_id][vsi_id].pHead); + ref_vsi_mapping[dev_id][vsi_id].pHead = p_vsi_info; + } + + return rv; +} + +static sw_error_t _ppe_vlan_vsi_mapping_del(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) +{ + ref_vlan_info_t *p_vsi_info = NULL; + ref_vlan_info_t *p_prev = NULL; + sw_error_t rv; + a_bool_t in_vsi = 0; + + rv = fal_port_vlan_vsi_set(dev_id, port_id, stag_vid, ctag_vid, PPE_VSI_INVALID); + if( rv != SW_OK ) + { + SSDK_ERROR("port %d svlan %d cvlan %d vsi %d set fail, rv = %d\n", + port_id, stag_vid, ctag_vid, vsi_id, rv); + return rv; + } + + /*vlan based vsi update*/ + p_vsi_info = ref_vsi_mapping[dev_id][vsi_id].pHead; + p_prev = p_vsi_info; + while(p_vsi_info != NULL) + { + if(p_vsi_info->vport_bitmap & (1 << port_id)) + { + if((ctag_vid == p_vsi_info->ctag_vid) && + (stag_vid == p_vsi_info->stag_vid)) + { + /*update software data*/ + p_vsi_info->vport_bitmap &= (~(1 << port_id)); + if(p_vsi_info->vport_bitmap == 0)/*free node if bitmap is 0*/ + { + if(p_vsi_info == ref_vsi_mapping[dev_id][vsi_id].pHead) + { + ref_vsi_mapping[dev_id][vsi_id].pHead = + p_vsi_info->pNext; + } + else + { + p_prev->pNext = p_vsi_info->pNext; + } + aos_mem_free(p_vsi_info); + p_vsi_info = NULL; + break; + } + } + else + { + in_vsi = 1;/*port + another vlan --> vsi*/ + } + } + p_prev = p_vsi_info; + p_vsi_info = p_vsi_info->pNext; + } + + if(in_vsi == 0 && + (!(1 << port_id & ref_vsi_mapping[dev_id][vsi_id].pport_bitmap))) + { + rv = _ppe_vsi_member_update(dev_id, vsi_id, port_id, PPE_VSI_DEL); + if( rv != SW_OK ) + { + SSDK_ERROR("port %d svlan %d cvlan %d vsi %d fail, rv = %d\n", + port_id, stag_vid, ctag_vid, vsi_id, rv); + return rv; + } + } + + return SW_OK; +} + +static sw_error_t _ppe_port_vsi_mapping_update(a_uint32_t dev_id, + fal_port_t port_id, a_uint32_t vsi_id) +{ + ref_vsi_t *p_vsi = NULL; + sw_error_t rv; + a_uint32_t i = 0; + + + if(ref_vsi_mapping[dev_id][vsi_id].valid == 0) + { + SSDK_ERROR("port %d vsi %d entry not found\n", port_id, vsi_id); + return SW_NOT_FOUND; + } + + /*check port previous vsi*/ + for( i = 0; i <= PPE_VSI_MAX; i++ ) + { + p_vsi = &(ref_vsi_mapping[dev_id][i]); + if(p_vsi->valid != 0 && (p_vsi->pport_bitmap & (1 << port_id))) + { + /*remmove from preious vsi*/ + rv = _ppe_vsi_member_update(dev_id, i, port_id, PPE_VSI_DEL); + if( rv != SW_OK ) + return rv; + p_vsi->pport_bitmap &= (~(1<vport_bitmap & (1 << port_id)) && + (ctag_vid== p_vsi_info->ctag_vid) && + (stag_vid== p_vsi_info->stag_vid)) + { + *vsi_id = i; + SSDK_DEBUG("Returned port %d svlan %d cvlan %d vsi %d\n", + port_id, stag_vid, ctag_vid, *vsi_id); + aos_unlock_bh(&ppe_vlan_vsi_lock[dev_id]); + + return SW_OK; + } + p_vsi_info = p_vsi_info->pNext; + } + } + aos_unlock_bh(&ppe_vlan_vsi_lock[dev_id]); + return SW_NOT_FOUND; +} + + +/*called when + 1. switchdev create physical interface for port + 2. add physical interface to a bridge*/ +sw_error_t +ppe_port_vsi_set(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t vsi_id) +{ + sw_error_t rv = SW_OK; + + REF_DEV_ID_CHECK(dev_id); + SSDK_DEBUG("port %d, vsi %d\n", port_id, vsi_id); + if(!(FAL_IS_PPORT(port_id)) && !(FAL_IS_VPORT(port_id))) + return SW_BAD_VALUE; + + if(vsi_id > PPE_VSI_MAX){ + SSDK_ERROR("invalid VSI port %d, vsi %d\n", port_id, vsi_id); + return SW_BAD_VALUE; + } + + if(FAL_IS_PPORT(port_id)){ + rv = _ppe_port_vsi_mapping_update(dev_id, FAL_PORT_ID_VALUE(port_id), vsi_id); + if( rv != SW_OK ) + return rv; + } + return rv; +} + +sw_error_t +ppe_port_vsi_get(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t *vsi_id) +{ + if(FAL_IS_PPORT(port_id)) + { + a_uint32_t i = 0; + for( i = 0; i <= PPE_VSI_MAX; i++ ) + { + if((ref_vsi_mapping[dev_id][i].valid != 0)&& + (ref_vsi_mapping[dev_id][i].pport_bitmap & (1 << port_id))) + { + *vsi_id = i; + SSDK_DEBUG("returned port %d, vsi %d\n", port_id, *vsi_id); + return SW_OK; + } + } + } + SSDK_ERROR("VSI is not configured on port %d\n", port_id); + return SW_NOT_FOUND; +} + +sw_error_t ppe_vsi_alloc(a_uint32_t dev_id, a_uint32_t *vsi) +{ + a_uint32_t vsi_id; + + REF_DEV_ID_CHECK(dev_id); + REF_NULL_POINT_CHECK(vsi); + SSDK_DEBUG("requesting vsi\n"); + + for( vsi_id = PPE_VSI_RESERVE_MAX+1; vsi_id <= PPE_VSI_MAX; vsi_id++ ) + { + if(ref_vsi_mapping[dev_id][vsi_id].valid == 0) + { + fal_vsi_newaddr_lrn_t newaddr_lrn; + fal_vsi_stamove_t stamove; + ref_vsi_mapping[dev_id][vsi_id].valid = 1; + ref_vsi_mapping[dev_id][vsi_id].pport_bitmap = 0; + ref_vsi_mapping[dev_id][vsi_id].pHead = NULL; + *vsi = vsi_id; + _ppe_vsi_member_init(dev_id, vsi_id); + newaddr_lrn.lrn_en = 1; + newaddr_lrn.action = 0; + fal_vsi_newaddr_lrn_set(dev_id, vsi_id, &newaddr_lrn); + stamove.stamove_en = 1; + stamove.action = 0; + fal_vsi_stamove_set(dev_id, vsi_id, &stamove); + SSDK_DEBUG("vsi %d allocated\n", *vsi); + return SW_OK; + } + } + + return SW_NO_RESOURCE; +} + +sw_error_t ppe_vsi_free(a_uint32_t dev_id, a_uint32_t vsi_id) +{ + ref_vlan_info_t *p_vsi_info = NULL; + REF_DEV_ID_CHECK(dev_id); + + if( vsi_id <= PPE_VSI_RESERVE_MAX || vsi_id > PPE_VSI_MAX ) + return SW_OUT_OF_RANGE; + + p_vsi_info = ref_vsi_mapping[dev_id][vsi_id].pHead; + while(p_vsi_info != NULL) + { + ref_vlan_info_t *ptemp = p_vsi_info; + p_vsi_info = p_vsi_info->pNext; + SSDK_DEBUG("port 0x%x svlan %d cvlan %d, vsi %d free vsi info\n", + ptemp->vport_bitmap, ptemp->stag_vid, ptemp->ctag_vid, vsi_id); + aos_mem_free(ptemp); + } + ref_vsi_mapping[dev_id][vsi_id].valid = 0; + ref_vsi_mapping[dev_id][vsi_id].pHead = NULL; + ref_vsi_mapping[dev_id][vsi_id].pport_bitmap = 0; + + SSDK_DEBUG("vsi %d released\n", vsi_id); + + return SW_OK; +} + +static void ppe_init_one_vsi(a_uint32_t dev_id, a_uint32_t vsi_id) +{ + if(ref_vsi_mapping[dev_id][vsi_id].valid == 0) + { + ref_vsi_mapping[dev_id][vsi_id].valid = 1; + ref_vsi_mapping[dev_id][vsi_id].pport_bitmap = 0; + ref_vsi_mapping[dev_id][vsi_id].pHead = NULL; + _ppe_vsi_member_init(dev_id, vsi_id); + } + + return; +} + +sw_error_t ppe_vsi_init(a_uint32_t dev_id) +{ + fal_port_t port_id; + fal_vsi_newaddr_lrn_t newaddr_lrn = {0}; + fal_vsi_stamove_t stamove = {0}; + + newaddr_lrn.action = 0; + newaddr_lrn.lrn_en = 1; + stamove.action = 0; + stamove.stamove_en = 1; + for(port_id = SSDK_PHYSICAL_PORT1; port_id <= SSDK_PHYSICAL_PORT7; port_id++) + { + ppe_init_one_vsi(dev_id, default_port_vsi[port_id-1]); + fal_vsi_newaddr_lrn_set(dev_id, default_port_vsi[port_id-1], &newaddr_lrn); + fal_vsi_stamove_set(dev_id, default_port_vsi[port_id-1], &stamove); + /*fal_port_vsi_set(0, port_id, default_port_vsi[port_id-1]);*/ + ppe_port_vsi_set(dev_id, port_id, default_port_vsi[port_id-1]); + } + + aos_lock_init(&ppe_vlan_vsi_lock[dev_id]); + + return SW_OK; +} + + +sw_error_t ppe_vsi_tbl_dump(a_uint32_t dev_id) +{ + a_uint32_t vsi_id; + ref_vlan_info_t *p_vsi_info = NULL; + + REF_DEV_ID_CHECK(dev_id); + printk("########Software VSI mapping table\n"); + for( vsi_id = 0; vsi_id <= PPE_VSI_MAX; vsi_id++ ) + { + if(ref_vsi_mapping[dev_id][vsi_id].valid == 0) + continue; + p_vsi_info = ref_vsi_mapping[dev_id][vsi_id].pHead; + printk("vsi %d, port bitmap 0x%x\n",vsi_id, ref_vsi_mapping[dev_id][vsi_id].pport_bitmap); + while(p_vsi_info != NULL) + { + printk("%8s svlan %d, cvlan %d, port bitmap 0x%x\n","", + p_vsi_info->stag_vid, p_vsi_info->ctag_vid, p_vsi_info->vport_bitmap); + p_vsi_info = p_vsi_info->pNext; + } + } + + return SW_OK; +} + +EXPORT_SYMBOL(ppe_port_vlan_vsi_set); +EXPORT_SYMBOL(ppe_port_vlan_vsi_get); +EXPORT_SYMBOL(ppe_port_vsi_set); +EXPORT_SYMBOL(ppe_port_vsi_get); +EXPORT_SYMBOL(ppe_vsi_alloc); +EXPORT_SYMBOL(ppe_vsi_free); + + diff --git a/feeds/ipq807x/qca-ssdk/src/src/sal/Makefile b/feeds/ipq807x/qca-ssdk/src/src/sal/Makefile new file mode 100755 index 000000000..805ae0f63 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/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/src/src/sal/sd/Makefile b/feeds/ipq807x/qca-ssdk/src/src/sal/sd/Makefile new file mode 100755 index 000000000..74c50e2eb --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/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/src/src/sal/sd/linux/Makefile b/feeds/ipq807x/qca-ssdk/src/src/sal/sd/linux/Makefile new file mode 100755 index 000000000..a038efc6d --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/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/src/src/sal/sd/linux/uk_interface/Makefile b/feeds/ipq807x/qca-ssdk/src/src/sal/sd/linux/uk_interface/Makefile new file mode 100755 index 000000000..a4bac32fe --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/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/src/src/sal/sd/linux/uk_interface/sw_api_ks_ioctl.c b/feeds/ipq807x/qca-ssdk/src/src/sal/sd/linux/uk_interface/sw_api_ks_ioctl.c new file mode 100755 index 000000000..2988a6e33 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/sal/sd/linux/uk_interface/sw_api_ks_ioctl.c @@ -0,0 +1,316 @@ +/* + * Copyright (c) 2012, 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. + */ + + +#include "sw.h" +#include "sw_api.h" + +#ifdef KVER26 /*Linux Kernel 2.6 */ +#define __USER __user +#else /*Linux Kernel 2.4 */ +#include +#define __USER +#endif /*KVER26 */ + +#ifdef KVER34 +#include +#include +#include +#else +#include +#include +//#include +#endif + +#include +#include +#include +#include "api_access.h" +#include "sw_api_ks.h" +#ifdef KVER32 +#include +#include +#endif +#include +#include "ssdk_init.h" +#include "ssdk_plat.h" + +static int +switch_open(struct inode * inode,struct file * file); + +static int +switch_close(struct inode * inode, struct file * file); + + +#ifdef KVER32 //for linux3.2 +static long +switch_ioctl(struct file * file, unsigned int cmd, unsigned long arg); +#else +static long +switch_ioctl(struct inode *inode, struct file * file, unsigned int cmd, unsigned long arg); +#endif + +static unsigned long *cmd_buf = NULL; + +static struct mutex api_ioctl_lock; + +static struct file_operations switch_device_fops = +{ + .owner = THIS_MODULE, + .read = NULL, + .write = NULL, + .poll = NULL, + .unlocked_ioctl= switch_ioctl, + .open = switch_open, + .release = switch_close +}; + +#ifndef SHELL_DEV +#define SHELL_DEV "switch_ssdk" +#endif +static struct miscdevice switch_device = +{ + MISC_DYNAMIC_MINOR, + SHELL_DEV, + &switch_device_fops +}; + +static sw_error_t +input_parser(sw_api_param_t *p, a_uint32_t nr_param, unsigned long *args) +{ + a_uint32_t i = 0, buf_head = nr_param; + a_uint32_t offset = sizeof(unsigned long); + a_uint32_t credit = sizeof(unsigned long) - 1; + + for (i = 0; i < nr_param; i++) + { + if (p->param_type & SW_PARAM_PTR) + { + cmd_buf[i] = (unsigned long) & cmd_buf[buf_head]; + buf_head += (p->data_size + credit) / offset; + + if (buf_head > (SW_MAX_API_BUF / offset)) + { + SSDK_ERROR("Lengh of command is more than cmd buffer\n"); + return SW_NO_RESOURCE; + } + + if (p->param_type & SW_PARAM_IN) + { + if (copy_from_user((a_uint8_t*)(cmd_buf[i]), (void __USER *)args[i + 2], + ((p->data_size + credit) / offset) * offset)) + { + SSDK_ERROR("copy_from_user fail\n"); + return SW_NO_RESOURCE; + } + SSDK_DEBUG("Input parameter %d: ", i); + SSDK_DUMP_BUF(DEBUG, (unsigned long *)cmd_buf[i], + ((p->data_size + credit) / offset)); + } + } + else + { + cmd_buf[i] = args[i + 2]; + SSDK_DEBUG("Input parameter %d: %ld\n", i, cmd_buf[i]); + } + p++; + } + return SW_OK; +} + +static sw_error_t +output_parser(sw_api_param_t *p, a_uint32_t nr_param, unsigned long *args) +{ + a_uint32_t i =0; + a_uint32_t offset = sizeof(unsigned long); + a_uint32_t credit = sizeof(unsigned long) - 1; + + for (i = 0; i < nr_param; i++) + { + if (p->param_type & SW_PARAM_OUT) + { + SSDK_DEBUG("Output parameter %d: ", i); + SSDK_DUMP_BUF(DEBUG, (unsigned long *)cmd_buf[i], + ((p->data_size + credit) / offset)); + if (copy_to_user((void __USER *) args[i + 2], (unsigned long *) cmd_buf[i], + ((p->data_size + credit) / offset) * offset)) + { + SSDK_ERROR("copy_to_user fail\n"); + return SW_NO_RESOURCE; + } + } + p++; + } + + return SW_OK; +} + +static sw_error_t +sw_api_cmd(unsigned long * args) +{ + unsigned long *p = cmd_buf, api_id = args[0], nr_param = 0; + sw_error_t(*func) (unsigned long, ...); + sw_api_param_t *pp; + sw_api_func_t *fp; + sw_error_t rv; + sw_api_t sw_api; + + SSDK_DEBUG("api_id is %ld\n", api_id); + sw_api.api_id = api_id; + rv = sw_api_get(&sw_api); + SW_OUT_ON_ERROR(rv); + + fp = sw_api.api_fp; + pp = sw_api.api_pp; + nr_param = sw_api.api_nr; + + /* Clean up cmd_buf */ + aos_mem_set(cmd_buf, 0, SW_MAX_API_BUF); + rv = input_parser(pp, nr_param, args); + SW_OUT_ON_ERROR(rv); + func = fp->func; + + switch (nr_param) + { + 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; + } + + SW_OUT_ON_ERROR(rv); + rv = output_parser(pp, nr_param, args); + +out: + return rv; +} + +static int +switch_open(struct inode * inode,struct file * file) +{ + return SW_OK; +} + +static int +switch_close(struct inode * inode, struct file * file) +{ + return SW_OK; +} + +#ifdef KVER32 +static long +switch_ioctl(struct file * file, unsigned int cmd, unsigned long arg) +#else +static long +switch_ioctl(struct inode *inode, struct file * file, unsigned int cmd, unsigned long arg) +#endif +{ + unsigned long args[SW_MAX_API_PARAM], rtn; + sw_error_t rv = SW_NO_RESOURCE; + void __user *argp = (void __user *)arg; + + SSDK_DEBUG("Recieved IOCTL call\n"); + if (copy_from_user(args, argp, sizeof (args))) + { + SSDK_ERROR("copy_from_user fail\n"); + return SW_NO_RESOURCE; + } + + mutex_lock(&api_ioctl_lock); + rv = sw_api_cmd(args); + mutex_unlock(&api_ioctl_lock); + + /* return API result to user */ + rtn = (unsigned long) rv; + if (copy_to_user + ((void __USER *) args[1], &rtn, sizeof (unsigned long))) + { + SSDK_ERROR("copy_to_user fail\n"); + rv = SW_NO_RESOURCE; + } + + return SW_OK; +} + +sw_error_t +sw_uk_init(a_uint32_t nl_prot) +{ + if (!cmd_buf) + { + if((cmd_buf = (unsigned long *) aos_mem_alloc(SW_MAX_API_BUF)) == NULL) + { + return SW_OUT_OF_MEM; + } + +#if defined UK_MINOR_DEV + switch_device.minor = UK_MINOR_DEV; +#else + switch_device.minor = nl_prot; +#endif + + if (misc_register(&switch_device)) + { + return SW_INIT_ERROR; + } + + mutex_init(&api_ioctl_lock); + } + + return SW_OK; +} + +sw_error_t +sw_uk_cleanup(void) +{ + if (cmd_buf) + { + aos_mem_free(cmd_buf); + cmd_buf = NULL; + + mutex_destroy(&api_ioctl_lock); + misc_deregister(&switch_device); + } + + return SW_OK; +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/sal/sd/linux/uk_interface/sw_api_ks_netlink.c b/feeds/ipq807x/qca-ssdk/src/src/sal/sd/linux/uk_interface/sw_api_ks_netlink.c new file mode 100755 index 000000000..3ad5da193 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/sal/sd/linux/uk_interface/sw_api_ks_netlink.c @@ -0,0 +1,789 @@ +/* + * Copyright (c) 2012, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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_api.h" + +#ifdef KVER26 /*Linux Kernel 2.6 */ +#define __USER __user +#else /*Linux Kernel 2.4 */ +#include +#define __USER +#define CLONE_KERNEL (CLONE_FS | CLONE_FILES | CLONE_SIGHAND) +#define for_each_process(p) for_each_task(p) +#endif /*KVER26 */ +#include +#include +#include +#include +#include "api_access.h" +#include "sw_api_ks.h" + +#if 0 +#define dprintk(args...) aos_printk(args) +#else +#define dprintk(args...) +#endif + +/*configurable value for max creating request of kernel thread*/ +#define PID_THREADS_MAX 32 + +#define RSV_PID_LOC_0 (0) +#define RSV_PID_LOC_1 (1) + +#define PID_TAB_MAX PID_THREADS_MAX +#define PID_TAB_NOT_FOUND PID_TAB_MAX+1 + +static pid_t pid_parents[PID_TAB_MAX] = {0}; +static pid_t pid_childs[PID_TAB_MAX] = {0}; +static wait_queue_head_t pid_child_wait[PID_TAB_MAX]; +static struct semaphore pid_tab_sem; + +static unsigned long *cmd_buf = NULL; +static struct semaphore api_sem; +static struct sock *ssdk_nl_sk = NULL; +static struct sk_buff * skb_array[PID_TAB_MAX] = {0}; + +static sw_error_t +input_parser(sw_api_param_t *p, a_uint32_t nr_param, a_uint32_t *args) +{ + a_uint32_t i = 0, buf_head = nr_param; + + for (i = 0; i < nr_param; i++) + { + if (p->param_type & SW_PARAM_PTR) + { + cmd_buf[i] = (a_uint32_t) & cmd_buf[buf_head]; + buf_head += (p->data_size + 3) / 4; + + if (buf_head > (SW_MAX_API_BUF / 4)) + return SW_NO_RESOURCE; + + if (p->param_type & SW_PARAM_IN) + { + if (copy_from_user((a_uint8_t*)(cmd_buf[i]), (void __USER *)args[i + 2], ((p->data_size + 3) >> 2) << 2)) + return SW_NO_RESOURCE; + } + } + else + { + cmd_buf[i] = args[i + 2]; + } + p++; + } + return SW_OK; +} + +static sw_error_t +output_parser(sw_api_param_t *p, a_uint32_t nr_param, a_uint32_t *args) +{ + a_uint32_t i =0; + + for (i = 0; i < nr_param; i++) + { + if (p->param_type & SW_PARAM_OUT) + { + if (copy_to_user + ((void __USER *) args[i + 2], (a_uint32_t *) cmd_buf[i], ((p->data_size + 3) >> 2) << 2)) + return SW_NO_RESOURCE; + } + p++; + } + + return SW_OK; +} + +static sw_error_t +sw_api_cmd(a_uint32_t * args) +{ + a_uint32_t *p = cmd_buf, api_id = args[0], nr_param = 0; + sw_error_t(*func) (a_uint32_t, ...); + sw_api_param_t *pp; + sw_api_func_t *fp; + sw_error_t rv; + sw_api_t sw_api; + + down(&api_sem); + + sw_api.api_id = api_id; + rv = sw_api_get(&sw_api); + SW_OUT_ON_ERROR(rv); + + fp = sw_api.api_fp; + pp = sw_api.api_pp; + nr_param = sw_api.api_nr; + + rv = input_parser(pp, nr_param, args); + SW_OUT_ON_ERROR(rv); + func = fp->func; + + switch (nr_param) + { + 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; + } + + SW_OUT_ON_ERROR(rv); + rv = output_parser(pp, nr_param, args); + +out: + up(&api_sem); + return rv; +} + +static inline int pid_find(pid_t pid, pid_t pids[]) +{ + a_uint32_t i, loc = PID_TAB_NOT_FOUND; + + for(i = 0; i< PID_TAB_MAX; i++) + { + if(pids[i] == pid) + { + loc = i; + break; + } + } + return loc; +} + +static inline a_bool_t pid_exit(pid_t parent_pid) +{ + struct task_struct *p; + a_bool_t rtn = A_TRUE; + + for_each_process(p) + { + if(parent_pid == p->pid) + { + rtn = A_FALSE; + break; + } + } + + return rtn; +} + +static inline void pid_free(a_uint32_t loc) +{ + if (down_interruptible(&pid_tab_sem)) + return; + + pid_childs[loc] = 0; + pid_parents[loc] = 0; + + up(&pid_tab_sem); +} + +static inline a_bool_t pid_full(void) +{ + return (pid_find(0, pid_parents) == PID_TAB_NOT_FOUND)?A_TRUE:A_FALSE; +} + +static a_uint32_t pid_find_save (pid_t parent_pid, pid_t child_pid) +{ + a_uint32_t loc = PID_TAB_NOT_FOUND; + + if(!parent_pid && !child_pid) + { + dprintk("child and father can't both zero\n"); + return loc; + } + + if (down_interruptible(&pid_tab_sem)) + return loc; + + if(!parent_pid) + { + /*find locate by child_pid*/ + loc = pid_find(child_pid, pid_childs); + + } + else + { + /*find locate by parent_pid*/ + loc = pid_find(parent_pid, pid_parents); + + if(child_pid) + { + loc = pid_find(0, pid_parents); + + if(loc != PID_TAB_NOT_FOUND) + { + pid_childs[loc] = child_pid; + pid_parents[loc] = parent_pid; + } + } + } + + up(&pid_tab_sem); + return loc; +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) +static void +sw_api_excep_ack(struct sock *sk, pid_t pid) +{ + sw_error_t rv = SW_NO_RESOURCE; + a_uint32_t args[SW_MAX_API_PARAM], rtn; + struct sk_buff *skb, *skb_first = NULL; + struct nlmsghdr *nlh = NULL; + + while(1) + { +#ifdef KVER26 + skb = skb_dequeue(&sk->sk_receive_queue); +#else + skb = skb_dequeue(&sk->receive_queue); +#endif + if (!skb) + { + dprintk("pid error: skb = null\n"); + return; + } + + nlh = (struct nlmsghdr *)skb->data; + if (!nlh) + { + dprintk("pid error: nlh = null\n"); + return; + } + + if(nlh->nlmsg_pid == pid) + { + break; + } + + if(!skb_first) + { + skb_first = skb; + } + else if (skb_first == skb) + { + dprintk("can't found my skb???\n"); + return; + } + +#ifdef KVER26 + skb_queue_tail(&sk->sk_receive_queue, skb); +#else + skb_queue_tail(&sk->receive_queue, skb); +#endif + } + + if(nlh->nlmsg_len < (SW_MAX_PAYLOAD + sizeof(nlmsghdr))) + { + dprintk("data length is less than %d bytes\n", SW_MAX_PAYLOAD); + SW_OUT_ON_ERROR(SW_ABORTED); + } + aos_mem_copy(args, NLMSG_DATA(nlh), SW_MAX_PAYLOAD); + /* return API result to user */ + rtn = (a_uint32_t) rv; + if (copy_to_user + ((void __USER *) args[1], (a_uint32_t *) & rtn, sizeof (a_uint32_t))) + { + rv = SW_NO_RESOURCE; + } + + NETLINK_CB(skb).pid = 0; + NETLINK_CB(skb).dst_pid = nlh->nlmsg_pid; +#ifdef KVER26 + NETLINK_CB(skb).dst_group = 0; +#else + NETLINK_CB(skb).dst_groups = 0; +#endif + + netlink_unicast(sk, skb, nlh->nlmsg_pid, MSG_DONTWAIT); +} + +static void +sw_api_exec(struct sock *sk, pid_t pid) +{ + sw_error_t rv = SW_NO_RESOURCE; + a_uint32_t args[SW_MAX_API_PARAM], rtn; + struct sk_buff *skb, *skb_first = NULL; + struct nlmsghdr *nlh = NULL; + + while(1) + { +#ifdef KVER26 + skb = skb_dequeue(&sk->sk_receive_queue); +#else + skb = skb_dequeue(&sk->receive_queue); +#endif + if (!skb) + { + dprintk("pid error: skb = null\n"); + return; + } + + nlh = (struct nlmsghdr *)skb->data; + if (!nlh) + { + dprintk("pid error: nlh = null\n"); + return; + } + + if(nlh->nlmsg_pid == pid) + { + break; + } + + if(!skb_first) + { + skb_first = skb; + } + else if (skb_first == skb) + { + dprintk("can't found my skb???\n"); + return; + } + +#ifdef KVER26 + skb_queue_tail(&sk->sk_receive_queue, skb); +#else + skb_queue_tail(&sk->receive_queue, skb); +#endif + } + + if(nlh->nlmsg_len < (SW_MAX_PAYLOAD + sizeof(nlmsghdr))) + { + dprintk("data length is less than %d bytes\n", SW_MAX_PAYLOAD); + SW_OUT_ON_ERROR(SW_ABORTED); + } + aos_mem_copy(args, NLMSG_DATA(nlh), SW_MAX_PAYLOAD); + + rv = sw_api_cmd(args); + /* return API result to user */ + rtn = (a_uint32_t) rv; + if (copy_to_user + ((void __USER *) args[1], (a_uint32_t *) & rtn, sizeof (a_uint32_t))) + { + rv = SW_NO_RESOURCE; + } + + NETLINK_CB(skb).pid = 0; + NETLINK_CB(skb).dst_pid = nlh->nlmsg_pid; +#ifdef KVER26 + NETLINK_CB(skb).dst_group = 0; +#else + NETLINK_CB(skb).dst_groups = 0; +#endif + + netlink_unicast(sk, skb, nlh->nlmsg_pid, MSG_DONTWAIT); +} + + +static int sw_api_thread(void *sk) +{ + a_uint32_t loc, i; + pid_t parent_pid = 0, child_pid = current->pid; + + while ((loc = pid_find_save(parent_pid, child_pid)) == PID_TAB_NOT_FOUND) + schedule_timeout(1*HZ); + + parent_pid = pid_parents[loc]; + dprintk("thread child [%d] find parent [%d] at %d \n", child_pid, parent_pid, loc); + + if ((RSV_PID_LOC_0 == loc) || (RSV_PID_LOC_1 == loc)) + { + for(i=0; ; i++) + { + if(i && !sleep_on_timeout(&pid_child_wait[loc], (5*HZ))) + { + if(pid_exit(parent_pid) == A_FALSE) + continue; + + pid_free(loc); + dprintk("thread child[%d] exit!\n", child_pid); + return 0; + } + + sw_api_exec(sk, parent_pid); + } + } + else + { + sw_api_exec(sk, parent_pid); + pid_free(loc); + } + + return 0; +} + +static void +sw_api_netlink(struct sock *sk, int len) +{ + pid_t parent_pid = current->pid, child_pid = 0; + a_uint32_t loc = pid_find_save (parent_pid, child_pid); + + if(loc == PID_TAB_NOT_FOUND) + { + if(pid_full()) + { + dprintk("###threads exceed the max [%d] for pid [%d]!###\n", PID_TAB_MAX, parent_pid); + sw_api_excep_ack(sk, parent_pid); + return; + } +#if 1 + struct task_struct *p; + p = kthread_create(sw_api_thread, (void *)ssdk_nl_sk, "netlink_child"); + if (IS_ERR(p)) + { + dprintk("thread can't be created for netlink\n"); + return; + } + child_pid = p->pid; +#else + if ((child_pid = kernel_thread(sw_api_thread, ssdk_nl_sk, CLONE_KERNEL)) < 0) + { + dprintk("thread can't be created for netlink\n"); + return; + } +#endif + dprintk("[%d] create child [%d] at %d\n", parent_pid, child_pid, loc); + pid_find_save(parent_pid, child_pid); + wake_up_process(p); + } + else + { + dprintk("[%d] wake up child [%d] at %d\n", parent_pid, pid_childs[loc], loc); + wake_up(&pid_child_wait[loc]); + } + + return; + +} + +#else + +static void +sw_api_excep_ack_26_22(struct sk_buff *skb) +{ + sw_error_t rv = SW_NO_RESOURCE; + a_uint32_t args[SW_MAX_API_PARAM], rtn, size, dst_pid; + struct nlmsghdr *nlh = NULL; + struct sk_buff *rep; + + nlh = (struct nlmsghdr *)skb->data; + if (!nlh) + { + dprintk("pid error: nlh = null\n"); + return; + } + dst_pid = nlh->nlmsg_pid; + + if(nlh->nlmsg_len < (SW_MAX_PAYLOAD + sizeof(nlmsghdr))) + { + dprintk("data length is less than %d bytes\n", SW_MAX_PAYLOAD); + SW_OUT_ON_ERROR(SW_ABORTED); + } + aos_mem_copy(args, NLMSG_DATA(nlh), SW_MAX_PAYLOAD); + /* return API result to user */ + rtn = (a_uint32_t) rv; + if (copy_to_user + ((void __USER *) args[1], (a_uint32_t *) & rtn, sizeof (a_uint32_t))) + { + rv = SW_NO_RESOURCE; + } + + size = NLMSG_SPACE(0); + rep = alloc_skb(size, GFP_ATOMIC); + if (!rep) + { + dprintk("reply socket buffer allocation error... \n"); + return; + } + nlh = nlmsg_put(rep, 0, 0, 0, 0, 0); + + NETLINK_CB(rep).pid = 0; + NETLINK_CB(rep).dst_group = 0; + netlink_unicast(ssdk_nl_sk, rep, dst_pid, MSG_DONTWAIT); +} + +static void +sw_api_exec_26_22(pid_t parent_pid) +{ + sw_error_t rv = SW_NO_RESOURCE; + a_uint32_t loc, args[SW_MAX_API_PARAM], rtn, skblen, nlmsglen, size, dst_pid; + struct nlmsghdr *nlh = NULL; + struct sk_buff *skb; + struct sk_buff *rep; + + loc = pid_find(parent_pid, pid_parents); + if (PID_TAB_NOT_FOUND == loc) + { + dprintk("parent PID not found - (%d)\n", parent_pid); + return; + } + + skb = skb_array[loc]; + if (!skb) + { + dprintk("skb null pointer error\n"); + return; + } + + skblen = skb->len; + if (skb->len < sizeof(nlh)) + { + dprintk("skb len error - (%d)\n", skb->len); + SW_OUT_ON_ERROR(SW_ABORTED); + } + + nlh = (struct nlmsghdr *)skb->data; + if (!nlh) + { + dprintk("pid error: nlh = null\n"); + SW_OUT_ON_ERROR(SW_ABORTED); + } + + nlmsglen = nlh->nlmsg_len; + if (nlmsglen < sizeof(*nlh) || skblen < nlmsglen) + { + dprintk("nlmsglen error - (%d)\n", nlmsglen); + SW_OUT_ON_ERROR(SW_ABORTED); + } + dst_pid = nlh->nlmsg_pid; + + if(nlmsglen < (SW_MAX_PAYLOAD + sizeof(nlmsghdr))) + { + dprintk("data length is less than %d bytes\n", SW_MAX_PAYLOAD); + SW_OUT_ON_ERROR(SW_ABORTED); + } + aos_mem_copy(args, NLMSG_DATA(nlh), SW_MAX_PAYLOAD); + rv = sw_api_cmd(args); + + /* return API result to user */ + rtn = (a_uint32_t) rv; + if (copy_to_user + ((void __USER *) args[1], (a_uint32_t *) & rtn, sizeof (a_uint32_t))) + { + rv = SW_NO_RESOURCE; + } + + size = NLMSG_SPACE(0); + rep = alloc_skb(size, GFP_ATOMIC); + if (!rep) + { + dprintk("reply socket buffer allocation error... \n"); + SW_OUT_ON_ERROR(SW_ABORTED); + } + nlh = nlmsg_put(rep, 0, 0, 0, 0, 0); + + NETLINK_CB(rep).pid = 0; + NETLINK_CB(rep).dst_group = 0; + netlink_unicast(ssdk_nl_sk, rep, dst_pid, MSG_DONTWAIT); + +out: + skb_array[loc] = NULL; + kfree_skb(skb); +} + +static int +sw_api_thread_26_22(void * data) +{ + a_uint32_t loc, i; + pid_t parent_pid = 0, child_pid = current->pid; + + while ((loc = pid_find_save(parent_pid, child_pid)) == PID_TAB_NOT_FOUND) + schedule_timeout(1*HZ); + + parent_pid = pid_parents[loc]; + dprintk("thread child [%d] find parent [%d] at %d \n", child_pid, parent_pid, loc); + + if ((RSV_PID_LOC_0 == loc) || (RSV_PID_LOC_1 == loc)) + { + for(i=0; ; i++) + { + if(i && !sleep_on_timeout(&pid_child_wait[loc], (5*HZ))) + { + if(pid_exit(parent_pid) == A_FALSE) + continue; + + pid_free(loc); + dprintk("thread child[%d] exit!\n", child_pid); + return 0; + } + + sw_api_exec_26_22(parent_pid); + } + } + else + { + sw_api_exec_26_22(parent_pid); + pid_free(loc); + } + + return 0; +} + +static void +sw_api_netlink_26_22(struct sk_buff *skb) +{ + pid_t parent_pid = current->pid, child_pid = 0; + a_uint32_t loc = pid_find_save (parent_pid, child_pid); + + if(loc == PID_TAB_NOT_FOUND) + { + if(pid_full()) + { + dprintk("###threads exceed the max [%d] for pid [%d]!###\n", PID_TAB_MAX, parent_pid); + sw_api_excep_ack_26_22(skb); + return; + } + + loc = pid_find_save(parent_pid, 0xffffffff); + +#if 1 + struct task_struct *p; + p = kthread_create(sw_api_thread_26_22, (void *)ssdk_nl_sk, "netlink_child"); + if (IS_ERR(p)) + { + dprintk("thread can't be created for netlink\n"); + return; + } + + skb_array[loc] = skb_get(skb); + child_pid = p->pid; + pid_childs[loc] = child_pid; + wake_up_process(p); +#else + if ((child_pid = kernel_thread(sw_api_thread_26_22, NULL, CLONE_KERNEL)) < 0) + { + dprintk("thread can't be created for netlink\n"); + return; + } +#endif + dprintk("[%d] create child [%d] at %d\n", parent_pid, child_pid, loc); + } + else + { + dprintk("[%d] wake up child [%d] at %d\n", parent_pid, pid_childs[loc], loc); + skb_array[loc] = skb_get(skb); + wake_up(&pid_child_wait[loc]); + } + + return; +} +#endif + +sw_error_t +sw_uk_init(a_uint32_t nl_prot) +{ + a_uint32_t i, protocol; + + if (!cmd_buf) + { + if((cmd_buf = (a_uint32_t *) aos_mem_alloc(SW_MAX_API_BUF)) == NULL) + return SW_OUT_OF_MEM; + } + + if (!ssdk_nl_sk) + { +#if defined UK_NL_PROT + protocol = UK_NL_PROT; +#else + protocol = nl_prot; +#endif + +#ifdef KVER26 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + ssdk_nl_sk = netlink_kernel_create(&init_net, protocol, 0, sw_api_netlink_26_22, NULL, THIS_MODULE); +#else + ssdk_nl_sk = netlink_kernel_create(protocol, 0, sw_api_netlink, THIS_MODULE); +#endif +#else + ssdk_nl_sk = netlink_kernel_create(protocol, sw_api_netlink); +#endif + if (!ssdk_nl_sk) + { + dprintk("netlink_kernel_create fail at nl_prot:[%d]\n", protocol); + return SW_NO_RESOURCE; + } + else + { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + dprintk("netlink_kernel_create succeeded at nl_prot: [%d] (>2.6.22)\n", protocol); +#else + dprintk("netlink_kernel_create succeeded at nl_prot: [%d] (<2.6.22)\n", protocol); +#endif + } + } + + init_MUTEX(&pid_tab_sem); + init_MUTEX(&api_sem); + + for(i = 0; i < PID_TAB_MAX; i++) + { + init_waitqueue_head(&pid_child_wait[i]); + } + + return SW_OK; +} + +sw_error_t +sw_uk_cleanup(void) +{ + if (cmd_buf) + { + aos_mem_free(cmd_buf); + cmd_buf = NULL; + } + + if (ssdk_nl_sk) + { +#ifdef KVER26 + sock_release(ssdk_nl_sk->sk_socket); +#else + sock_release(ssdk_nl_sk->socket); +#endif + ssdk_nl_sk = NULL; + } + + return SW_OK; +} + diff --git a/feeds/ipq807x/qca-ssdk/src/src/sal/sd/sd.c b/feeds/ipq807x/qca-ssdk/src/src/sal/sd/sd.c new file mode 100755 index 000000000..39c053037 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/sal/sd/sd.c @@ -0,0 +1,371 @@ +/* + * Copyright (c) 2012, 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 "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; +i2c_reg_set ssdk_i2c_set = NULL; +i2c_reg_get ssdk_i2c_get = NULL; +/*qca808x_end*/ +hdr_reg_set ssdk_hdr_reg_set = NULL; +hdr_reg_get ssdk_hdr_reg_get = NULL; +psgmii_reg_set ssdk_psgmii_reg_set = NULL; +psgmii_reg_get ssdk_psgmii_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; + +/*qca808x_start*/ +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 + { +#if ((!defined(KERNEL_MODULE)) && defined(UK_IF)) + { + a_uint32_t args[SW_MAX_API_PARAM]; + + args[0] = SW_API_PHY_SET; + args[1] = (a_uint32_t) & rv; + args[2] = dev_id; + args[3] = phy; + args[4] = reg; + args[5] = data; + if (SW_OK != sw_uk_if(args)) + { + return SW_FAIL; + } + } +#else + return SW_NOT_SUPPORTED; +#endif + } + + 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 + { +#if ((!defined(KERNEL_MODULE)) && defined(UK_IF)) + { + a_uint32_t args[SW_MAX_API_PARAM]; + a_uint32_t tmp; + + args[0] = SW_API_PHY_GET; + args[1] = (a_uint32_t) & rv; + args[2] = dev_id; + args[3] = phy; + args[4] = reg; + args[5] = (a_uint32_t) & tmp; + if (SW_OK != sw_uk_if(args)) + { + return SW_FAIL; + } + *data = *((a_uint16_t *)&tmp); + } +#else + return SW_NOT_SUPPORTED; +#endif + } + + return rv; +} + +sw_error_t +sd_reg_i2c_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_i2c_set) + { + rv = ssdk_i2c_set(dev_id, phy, reg, data); + } + else + { +#if ((!defined(KERNEL_MODULE)) && defined(UK_IF)) + { + a_uint32_t args[SW_MAX_API_PARAM]; + + args[0] = SW_API_PHY_I2C_SET; + args[1] = (a_uint32_t) & rv; + args[2] = dev_id; + args[3] = phy; + args[4] = reg; + args[5] = data; + if (SW_OK != sw_uk_if(args)) + { + return SW_FAIL; + } + } +#else + return SW_NOT_SUPPORTED; +#endif + } + + return rv; +} + +sw_error_t +sd_reg_i2c_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_i2c_get) + { + rv = ssdk_i2c_get(dev_id, phy, reg, data); + } + else + { +#if ((!defined(KERNEL_MODULE)) && defined(UK_IF)) + { + a_uint32_t args[SW_MAX_API_PARAM]; + a_uint32_t tmp; + + args[0] = SW_API_PHY_I2C_GET; + args[1] = (a_uint32_t) & rv; + args[2] = dev_id; + args[3] = phy; + args[4] = reg; + args[5] = (a_uint32_t) & tmp; + if (SW_OK != sw_uk_if(args)) + { + return SW_FAIL; + } + *data = *((a_uint16_t *)&tmp); + } +#else + return SW_NOT_SUPPORTED; +#endif + } + + return rv; +} +/*qca808x_end*/ +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_psgmii_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_psgmii_reg_set) + { + rv = ssdk_psgmii_reg_set(dev_id, reg_addr, reg_data, len); + } + else + { + return SW_NOT_SUPPORTED; + } + + return rv; +} + +sw_error_t +sd_reg_psgmii_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_psgmii_reg_get) + { + rv = ssdk_psgmii_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 dev_id, a_uint32_t reg, a_uint32_t val) +{ + if (NULL != ssdk_mii_reg_set) + { + ssdk_mii_reg_set(dev_id, reg, val); + } +} + +a_uint32_t +sd_reg_mii_get(a_uint32_t dev_id, a_uint32_t reg) +{ + a_uint32_t value = 0; + + if (NULL != ssdk_mii_reg_get) + { + value = ssdk_mii_reg_get(dev_id, reg); + } + + return value; +} +/*qca808x_start*/ +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.i2c_set) + { + ssdk_i2c_set = cfg->reg_func.i2c_set; + } + + if (NULL != cfg->reg_func.i2c_get) + { + ssdk_i2c_get = cfg->reg_func.i2c_get; + } +/*qca808x_end*/ + 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.psgmii_reg_set) + { + ssdk_psgmii_reg_set = cfg->reg_func.psgmii_reg_set; + } + + if (NULL != cfg->reg_func.psgmii_reg_get) + { + ssdk_psgmii_reg_get = cfg->reg_func.psgmii_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; + } +/*qca808x_start*/ + return SW_OK; +} +/*qca808x_end*/ diff --git a/feeds/ipq807x/qca-ssdk/src/src/shell_lib/Makefile b/feeds/ipq807x/qca-ssdk/src/src/shell_lib/Makefile new file mode 100755 index 000000000..2336b4f98 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/shell_lib/Makefile @@ -0,0 +1,12 @@ +LOC_DIR=src/shell_lib +LIB=SHELIB + +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/src/src/shell_lib/shell.c b/feeds/ipq807x/qca-ssdk/src/src/shell_lib/shell.c new file mode 100755 index 000000000..e0912561f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/shell_lib/shell.c @@ -0,0 +1,555 @@ +/* + * Copyright (c) 2013, 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 "shell.h" +#include "shell_io.h" +#include "shell_sw.h" +#include "shell_config.h" +#include "api_access.h" + +unsigned long ioctl_buf[IOCTL_BUF_SIZE]; +unsigned long ioctl_argp[CMDSTR_ARGS_MAX*4]; + +void +cmd_print_error(sw_error_t rtn) +{ + +} + +void +cmd_print(char *fmt, ...) +{ + +} + +static sw_error_t +cmd_input_parser(unsigned long *arg_val, a_uint32_t arg_index, sw_api_param_t *pp) +{ + a_int16_t i; + unsigned long *pbuf; + a_uint16_t rtn_size = 1; + sw_api_param_t *pptmp = NULL;; + + 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 (pptmp == NULL) + return SW_BAD_PTR; + + if ((pbuf - ioctl_buf + (pptmp->data_size + 3) / 4) > (IOCTL_BUF_SIZE/4)) + { + return SW_NO_RESOURCE; + } + + *arg_val = (unsigned long) pbuf; + + return SW_OK; +} + +static sw_error_t +cmd_api_func(sw_api_func_t *fp, a_uint32_t nr_param, unsigned long * args) +{ + unsigned long *p = &args[2]; + sw_error_t rv; + + switch (nr_param) + { + case 0: + { + sw_error_t(*func) (void); + func = fp->func; + rv = (func) (); + break; + } + case 1: + { + sw_error_t(*func1) (unsigned long); + func1 = fp->func; + rv = (func1) (p[0]); + break; + } + case 2: + { + sw_error_t(*func2) (unsigned long, unsigned long); + func2 = fp->func; + rv = (func2) (p[0], p[1]); + break; + } + case 3: + { + sw_error_t(*func3) (unsigned long, unsigned long, unsigned long); + func3 = fp->func; + rv = (func3) (p[0], p[1], p[2]); + break; + } + case 4: + { + sw_error_t(*func4) (unsigned long, unsigned long, unsigned long, \ + unsigned long); + func4 = fp->func; + rv = (func4) (p[0], p[1], p[2], p[3]); + break; + } + case 5: + { + sw_error_t(*func5) (unsigned long, unsigned long, unsigned long, \ + unsigned long, unsigned long); + func5 = fp->func; + rv = (func5) (p[0], p[1], p[2], p[3], p[4]); + break; + } + case 6: + { + sw_error_t(*func6) (unsigned long, unsigned long, unsigned long, \ + unsigned long, unsigned long, unsigned long); + func6 = fp->func; + rv = (func6) (p[0], p[1], p[2], p[3], p[4], p[5]); + break; + } + case 7: + { + sw_error_t(*func7) (unsigned long, unsigned long, unsigned long, \ + unsigned long, unsigned long, unsigned long, unsigned long); + func7 = fp->func; + rv = (func7) (p[0], p[1], p[2], p[3], p[4], p[5], p[6]); + break; + } + case 8: + { + sw_error_t(*func8) (unsigned long, unsigned long, unsigned long, \ + unsigned long, unsigned long, unsigned long, unsigned long, \ + unsigned long); + func8 = fp->func; + rv = (func8) (p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); + break; + } + case 9: + { + sw_error_t(*func9) (unsigned long, unsigned long, unsigned long, \ + unsigned long, unsigned long, unsigned long, unsigned long, \ + unsigned long, unsigned long); + func9 = fp->func; + rv = (func9) (p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8]); + break; + } + case 10: + { + sw_error_t(*func10) (unsigned long, unsigned long, unsigned long, \ + unsigned long, unsigned long, unsigned long, unsigned long, \ + unsigned long, unsigned long, unsigned long); + func10 = fp->func; + rv = (func10) (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; + } + + *(unsigned long *) args[1] = rv; + + return rv; +} +#if 0 +static sw_error_t +cmd_api_output(sw_api_param_t *pp, a_uint32_t nr_param, a_uint32_t * args) +{ + a_uint16_t i; + a_uint32_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); + } + 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; +} +#endif +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, unsigned long * 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; + unsigned long *temp; + void *pentry; + sw_api_param_t *pptmp = NULL; + sw_api_t sw_api; + a_uint32_t ignorecnt = 0, jump = 0; + sw_data_type_t *data_type; + 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]; + + 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, (a_uint32_t *)pentry, (a_uint32_t)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; +} + +/*user command api*/ +sw_error_t +cmd_exec_api(unsigned long *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] = (unsigned long) 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); + + #if 0 + rv = cmd_api_output(sw_api.api_pp, sw_api.api_nr, arg_val); + SW_RTN_ON_ERROR(rv); + #endif + + return rv; +} + + +void +cmd_print_usage (int cmd_index, int cmd_index_sub) +{ + #if 0 + 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)); + #endif +} +/* + 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 unsigned long * +cmd_parse(char *cmd_str, int *cmd_index, int *cmd_index_sub) +{ + int cmd_nr = 0; + unsigned long *arg_val = ioctl_argp; + char *tmp_str[CMDSTR_ARGS_MAX]; + int rtn_code = 0; + int cmd_depth; + + if (cmd_str == NULL) + return NULL; + + memset(arg_val, 0, CMDSTR_ARGS_MAX * sizeof (unsigned long)); + + /* split string into array */ + if ((tmp_str[cmd_nr] = (void *) strsep(&cmd_str, " ")) == NULL) + return NULL; + + /*handle help */ + if (!strcasecmp(tmp_str[cmd_nr], "help")) + { + return NULL; + } + + while (tmp_str[cmd_nr]) + { + if (++cmd_nr == 3) + break; + + tmp_str[cmd_nr] = (void *) strsep(&cmd_str, " "); + } + + /*commond string lookup */ + 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) + { + 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 *) strsep(&cmd_str, " "); + while (tmp_str[cmd_nr]) + { + if (strcmp(tmp_str[cmd_nr], "")) + if (++cmd_nr == CMDSTR_ARGS_MAX) + break; + tmp_str[cmd_nr] = (void *) strsep(&cmd_str, " "); + } + + arg_val[0] = GCMD_SUB_API(*cmd_index, *cmd_index_sub); + arg_val[1] = (unsigned long) ioctl_buf; + + if (arg_val[0] < SW_API_MAX) + { + /*api command parse */ + rtn_code = cmd_parse_api(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(unsigned long *arg_val, int cmd_index, int cmd_index_sub) +{ + unsigned long 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)) + { + } + else + { + rtn = SW_BAD_PARAM; + } + + if(rtn != SW_OK) + cmd_print_error(rtn); + + return 0; +} + +int +cmd_run_one(char *cmd_str) +{ + unsigned long *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; +} + +/* Dummy function to avoid linker complaints */ +void __aeabi_unwind_cpp_pr0(void) +{ +}; +void __aeabi_unwind_cpp_pr1(void) +{ +}; + diff --git a/feeds/ipq807x/qca-ssdk/src/src/shell_lib/shell_config.c b/feeds/ipq807x/qca-ssdk/src/src/shell_lib/shell_config.c new file mode 100644 index 000000000..3f4ad2ab4 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk/src/src/shell_lib/shell_config.c @@ -0,0 +1,1512 @@ +/* + * Copyright (c) 2013, 2015-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 "shell_config.h" +#include "shell_sw.h" + +#if 0 +/*cmdline tree descript*/ +struct cmd_des_t gcmd_des[] = +{ + /*port ctrl*/ +#ifdef IN_PORTCONTROL + { + "port", "config port control", + { + {"duplex", "set", "set duplex mode of a port", " ", SW_API_PT_DUPLEX_SET, NULL}, + {"speed", "set", "set speed mode of a port", " <10|100|1000>", SW_API_PT_SPEED_SET, NULL}, + {"autoAdv", "set", "set auto-negotiation advertisement of a port", " ", SW_API_PT_AN_ADV_SET, 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}, + {"autoNegenable", "set", "enable auto-negotiation of a port", "", SW_API_PT_AN_ENABLE, NULL}, + {"autoNegrestart", "set", "restart auto-negotiation process of a port", "", SW_API_PT_AN_RESTART, NULL}, + {"header", "set", "set atheros header/tag status of a port", " ", SW_API_PT_HDR_SET, NULL}, + {"txhdr", "set", "set tx frame atheros header/tag status of a port", " ", SW_API_PT_TXHDR_SET, NULL}, + {"rxhdr", "set", "set rx frame atheros header/tag status of a port", " ", SW_API_PT_RXHDR_SET, NULL}, + {"hdrtype", "set", "set atheros header/tag type", " ", SW_API_HEADER_TYPE_SET, NULL}, + {"flowCtrl", "set", "set flow control status of a port", " ", SW_API_PT_FLOWCTRL_SET, NULL}, + {"flowCtrlforcemode", "set", "set flow control force mode of a port", " ", SW_API_PT_FLOWCTRL_MODE_SET, NULL}, + {"powersave", "set", "set powersave status of a port", " ", SW_API_PT_POWERSAVE_SET, NULL}, + {"hibernate", "set", "set hibernate status of a port", " ", SW_API_PT_HIBERNATE_SET, NULL}, + {"cdt", "run", "run cable diagnostic test of a port", " ", SW_API_PT_CDT, NULL}, + {"txmacstatus", "set", "set txmac status of a port", " ", SW_API_TXMAC_STATUS_SET, NULL}, + {"rxmacstatus", "set", "set rxmac status of a port", " ", SW_API_RXMAC_STATUS_SET, NULL}, + {"txfcstatus", "set", "set tx flow control status of a port", " ", SW_API_TXFC_STATUS_SET, NULL}, + {"rxfcstatus", "set", "set rx flow control status of a port", " ", SW_API_RXFC_STATUS_SET, NULL}, + {"bpstatus", "set", "set back pressure status of a port", " ", SW_API_BP_STATUS_SET, NULL}, + {"linkforcemode", "set", "set link force mode of a port", " ", SW_API_PT_LINK_MODE_SET, NULL}, + {"macLoopback", "set", "set mac level loop back mode of port", " ", SW_API_PT_MAC_LOOPBACK_SET, NULL}, + {"congedrop", "set", "set congestion drop of port queue", " ", SW_API_PT_CONGESTION_DROP_SET, NULL}, + {"ringfcthresh", "set", "set flwo ctrl thres of ring", " ", SW_API_PT_RING_FLOW_CTRL_THRES_SET, NULL}, + {"Ieee8023az", "set", "set 8023az status of a port", " ", SW_API_PT_8023AZ_SET, 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}, + {"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>", 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}, + {"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}, + {"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", "status", "get current interface mode of phy", "", SW_API_PT_INTERFACE_MODE_STATUS_GET, NULL}, + {"counter", "set", "set counter status of a port", " ", SW_API_PT_COUNTER_SET, NULL}, + {"counter", "get", "get counter status of a port", "", SW_API_PT_COUNTER_GET, NULL}, + {"counter", "show", "show counter statistics of a port", "", SW_API_PT_COUNTER_SHOW, NULL}, + {NULL, NULL, NULL, NULL, (int)NULL, NULL},/*end of desc*/ + }, + }, +#endif + + /*vlan*/ +#ifdef IN_VLAN + { + "vlan", "config VLAN table", + { + {"entry", "set", "create a VLAN entry", "", SW_API_VLAN_ADD, NULL}, + {"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}, + {"fid", "set", "set VLAN entry fid", " ",SW_API_VLAN_FID_SET, NULL}, + {"member", "set", "add VLAN entry member", " ",SW_API_VLAN_MEMBER_ADD, 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}, + {NULL, NULL, NULL, NULL, (int)NULL, NULL}/*end of desc*/ + }, + }, +#endif + + /*portvlan*/ +#ifdef IN_PORTVLAN + { + "portVlan", "config port base VLAN", + { + {"ingress", "set", "set ingress VLAN mode of a port", " ", SW_API_PT_ING_MODE_SET, NULL}, + {"egress", "set", "set egress VLAN mode of a port", " ", SW_API_PT_EG_MODE_SET, NULL}, + {"member", "set", "add a member to the port based VLAN of a port", " ", SW_API_PT_VLAN_MEM_UPDATE, 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}, + {"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}, + {"forceMode", "set", "set port based VLAN enforcement status of a port", " ", SW_API_PT_FORCE_PORTVLAN_SET, NULL}, + {"nestVlan", "set", "set nest VLAN status of a port", " ", SW_API_PT_NESTVLAN_SET, NULL}, + {"sVlanTPID", "set", "set service VLAN tpid", "", SW_API_NESTVLAN_TPID_SET, NULL}, + {"invlan", "set", "set port invlan mode", " ", SW_API_PT_IN_VLAN_MODE_SET, NULL}, + {"tlsMode", "set", "set TLS mode", " ", SW_API_PT_TLS_SET, NULL}, + {"priPropagation", "set", "set priority propagation", " ", SW_API_PT_PRI_PROPAGATION_SET, NULL}, + {"defaultSVid", "set", "set default SVID", " ", SW_API_PT_DEF_SVID_SET, NULL}, + {"defaultCVid", "set", "set default CVID", " ", SW_API_PT_DEF_CVID_SET, NULL}, + {"vlanPropagation", "set", "set vlan propagation", " ", SW_API_PT_VLAN_PROPAGATION_SET, NULL}, + {"translation", "set", "add vlan translation", "", SW_API_PT_VLAN_TRANS_ADD, 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", "iterate", "iterate vlan translation tables", " ", SW_API_PT_VLAN_TRANS_ITERATE, NULL}, + {"qinqMode", "set", "set qinq mode", "", SW_API_QINQ_MODE_SET, NULL}, + {"qinqRole", "set", "set qinq role", " ", SW_API_PT_QINQ_ROLE_SET, NULL}, + {"macvlanxlt", "set", "set mac vlan xlt status", " ", SW_API_PT_MAC_VLAN_XLT_SET, NULL}, + {"netiso", "set", "enable public/private net isolate", "", SW_API_NETISOLATE_SET, NULL}, + {"egbypass", "set", "enable egress translation filter bypass", "", SW_API_EG_FLTR_BYPASS_EN_SET, NULL}, + {"ptvrfid", "set", "set port VRF ID", " ", SW_API_PT_VRF_ID_SET, NULL}, + {NULL, NULL, NULL, NULL, (int)NULL, NULL}/*end of desc*/ + }, + }, +#endif + + /*fdb*/ +#ifdef IN_FDB + { + "fdb", "config FDB table", + { + {"entry", "set", "add a FDB entry", "", SW_API_FDB_ADD, NULL}, + {"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", "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}, + {"ageCtrl", "set", "set FDB entry aging status", "", SW_API_FDB_AGE_CTRL_SET, NULL}, + {"vlansmode", "set", "set FDB vlan search mode", "", SW_API_FDB_VLAN_IVL_SVL_SET, NULL}, + {"ageTime", "set", "set FDB entry aging time", "", SW_API_FDB_AGE_TIME_SET, NULL}, + {"ptlearnlimit", "set", "set port FDB entry learn limit", " ", SW_API_PT_FDB_LEARN_LIMIT_SET, NULL}, + {"ptlearnexceedcmd", "set", "set port forwarding cmd when exceed learn limit", " ", SW_API_PT_FDB_LEARN_EXCEED_CMD_SET, NULL}, + {"learnlimit", "set", "set FDB entry learn limit", " ", SW_API_FDB_LEARN_LIMIT_SET, NULL}, + {"learnexceedcmd", "set", "set forwarding cmd when exceed learn limit", "", SW_API_FDB_LEARN_EXCEED_CMD_SET, NULL}, + {"resventry", "set", "add a reserve FDB entry", "", SW_API_FDB_RESV_ADD, 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}, + {"ptLearnstatic", "set", "set FDB entry learning static status of a port", " ", SW_API_FDB_PT_LEARN_STATIC_SET, 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}, + {NULL, NULL, NULL, NULL, (int)NULL, 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}, + {"status", "set", "set status of ACL engine", "", SW_API_ACL_STATUS_SET, NULL}, + {"udfprofile", "set", "set port udf profile", " ", SW_API_ACL_PT_UDF_PROFILE_SET, NULL}, + {NULL, NULL, NULL, NULL, (int)NULL, NULL}/*end of desc*/ + }, + }, +#endif + + /*qos*/ +#ifdef IN_QOS + { + "qos", "config Qos", + { +#ifndef ISISC + {"schMode", "set", "set traffic scheduling mode", " ", SW_API_QOS_SCH_MODE_SET, NULL}, +#endif + {"qTxBufSts", "set", "set queue tx buffer counting status of a port", " ", SW_API_QOS_QU_TX_BUF_ST_SET, NULL}, +#ifdef ISISC + {"qTxBufNr", "set", "set queue tx buffer number", " ", SW_API_QOS_QU_TX_BUF_NR_SET, NULL}, +#else + {"qTxBufNr", "set", "set queue tx buffer number", " ", SW_API_QOS_QU_TX_BUF_NR_SET, NULL}, +#endif + {"ptTxBufSts", "set", "set port tx buffer counting status of a port", " ", SW_API_QOS_PT_TX_BUF_ST_SET, NULL}, + {"ptRedEn", "set", "set status of port wred of a port", " ", SW_API_QOS_PT_RED_EN_SET, NULL}, +#ifdef ISISC + {"ptTxBufNr", "set", "set port tx buffer number", " ", SW_API_QOS_PT_TX_BUF_NR_SET, NULL}, +#else + {"ptTxBufNr", "set", "set port tx buffer number", " ", SW_API_QOS_PT_TX_BUF_NR_SET, NULL}, +#endif +#ifdef ISISC + {"ptRxBufNr", "set", "set port rx buffer number", " ", SW_API_QOS_PT_RX_BUF_NR_SET, NULL}, +#else + {"ptRxBufNr", "set", "set port rx buffer number", " ", SW_API_QOS_PT_RX_BUF_NR_SET, NULL}, +#endif +#ifndef ISISC + {"up2q", "set", "set user priority to queue mapping", " ", SW_API_COSMAP_UP_QU_SET, NULL}, + {"dscp2q", "set", "set dscp to queue mapping", " ", SW_API_COSMAP_DSCP_QU_SET, NULL}, +#endif +#ifdef ISISC + {"ptMode", "set", "set Qos mode of a port", " ", SW_API_QOS_PT_MODE_SET, NULL}, + {"ptModePri", "set", "set the priority of Qos modes of a port", " ", SW_API_QOS_PT_MODE_PRI_SET, NULL}, +#else + {"ptMode", "set", "set Qos mode of a port", " ", SW_API_QOS_PT_MODE_SET, NULL}, + {"ptModePri", "set", "set the priority of Qos modes of a port", " ", SW_API_QOS_PT_MODE_PRI_SET, NULL}, +#endif +#ifndef ISISC + {"ptDefaultUp", "set", "set default user priority for received frames of a port", " ", SW_API_QOS_PORT_DEF_UP_SET, NULL}, +#endif + {"ptschMode", "set", "set port traffic scheduling mode", " ", SW_API_QOS_PORT_SCH_MODE_SET, NULL}, + {"ptDefaultSpri", "set", "set default stag priority for received frames of a port", " ", SW_API_QOS_PT_DEF_SPRI_SET, NULL}, + {"ptDefaultCpri", "set", "set default ctag priority for received frames of a port", " ", SW_API_QOS_PT_DEF_CPRI_SET, NULL}, + {"ptFSpriSts", "set", "set port force Stag priority status for received frames of a port", " ", SW_API_QOS_PT_FORCE_SPRI_ST_SET, NULL}, + {"ptFCpriSts", "set", "set port force Ctag priority status for received frames of a port", " ", SW_API_QOS_PT_FORCE_CPRI_ST_SET, NULL}, + {"ptQuRemark", "set", "set egress queue based remark", " ", SW_API_QOS_QUEUE_REMARK_SET, NULL}, + {NULL, NULL, NULL, NULL, (int)NULL, 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}, + {"cmd", "set", "set IGMP/MLD frames forwarding command", "", SW_API_IGMP_MLD_CMD_SET, NULL}, + {"portJoin", "set", "set IGMP/MLD hardware joining status", " ", SW_API_IGMP_PT_JOIN_SET, NULL}, + {"portLeave", "set", "set IGMP/MLD hardware leaving status", " ", SW_API_IGMP_PT_LEAVE_SET, NULL}, + {"rp", "set", "set IGMP/MLD router ports", "", SW_API_IGMP_RP_SET, NULL}, + {"createStatus", "set", "set IGMP/MLD ability for creating entry", "", SW_API_IGMP_ENTRY_CREAT_SET, NULL}, + {"static", "set", "set IGMP/MLD static status for creating entry", "", SW_API_IGMP_ENTRY_STATIC_SET, NULL}, + {"leaky", "set", "set IGMP/MLD leaky status for creating entry", "", SW_API_IGMP_ENTRY_LEAKY_SET, NULL}, + {"version3", "set", "set IGMP v3/MLD v2 status for creating entry", "", SW_API_IGMP_ENTRY_V3_SET, NULL}, + {"queue", "set", "set IGMP/MLD queue status for creating entry", " ", SW_API_IGMP_ENTRY_QUEUE_SET, NULL}, + {"ptlearnlimit", "set", "set port Multicast entry learn limit", " ", SW_API_PT_IGMP_LEARN_LIMIT_SET, NULL}, + {"ptlearnexceedcmd", "set", "set port forwarding cmd when exceed multicast learn limit", " ", SW_API_PT_IGMP_LEARN_EXCEED_CMD_SET, 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, (int)NULL, 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}, + {"mcMode", "set", "set multicast packets leaky mode", "", SW_API_MC_LEAKY_MODE_SET, NULL}, + {"arpMode", "set", "set arp packets leaky mode", " ", SW_API_ARP_LEAKY_MODE_SET, NULL}, + {"ptUcMode", "set", "set unicast packets leaky status of a port", " ", SW_API_PT_UC_LEAKY_MODE_SET, NULL}, + {"ptMcMode", "set", "set multicast packets leaky status of a port", " ", SW_API_PT_MC_LEAKY_MODE_SET, NULL}, + {NULL, NULL, NULL, NULL, (int)NULL, 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}, + {"ptIngress", "set", "set ingress mirror status of a port", " ", SW_API_MIRROR_IN_PT_SET, NULL}, + {"ptEgress", "set", "set egress mirror status of a port", " ", SW_API_MIRROR_EG_PT_SET, NULL}, + {NULL, NULL, NULL, NULL, (int)NULL, NULL}/*end of desc*/ + }, + }, +#endif + + /*rate*/ +#ifdef IN_RATE + { + "rate", "config rate limit", + { +#ifndef ISISC + {"qEgress", "set", "set egress rate limit of a queue", " ", SW_API_RATE_QU_EGRL_SET, NULL}, + {"ptEgress", "set", "set egress rate limit of a port", " ", SW_API_RATE_PT_EGRL_SET, NULL}, + {"ptIngress", "set", "set ingress rate limit of a port", " ", SW_API_RATE_PT_INRL_SET, NULL}, + {"stormCtrl", "set", "set storm control status of a particular frame type", " ", SW_API_STORM_CTRL_FRAME_SET, NULL}, + {"stormCtrlRate", "set", "set storm ctrl rate", " ", SW_API_STORM_CTRL_RATE_SET, NULL}, +#endif + {"portpolicer", "set", "set port policer", "", SW_API_RATE_PORT_POLICER_SET, NULL}, + {"portshaper", "set", "set port egress shaper", " ", SW_API_RATE_PORT_SHAPER_SET, NULL}, + {"queueshaper", "set", "set queue egress shaper", " ", SW_API_RATE_QUEUE_SHAPER_SET, NULL}, + {"aclpolicer", "set", "set acl policer", "", SW_API_RATE_ACL_POLICER_SET, NULL}, + {"ptAddRateByte", "set", "set add_rate_byte when cal rate ", " ", SW_API_RATE_PT_ADDRATEBYTE_SET, NULL}, + {"ptgolflowen", "set", "set status of port globle flow control", " ", SW_API_RATE_PT_GOL_FLOW_EN_SET, NULL}, + {NULL, NULL, NULL, NULL, (int)NULL, NULL}/*end of desc*/ + }, + }, +#endif + +#ifdef IN_SEC +#ifdef ISISC + { + "sec", "config security", + { + {"mac", "set", "set MAC layer related security", " ", SW_API_SEC_MAC_SET, NULL}, + {"ip", "set", "set IP layer related security", " ", SW_API_SEC_IP_SET, NULL}, + {"ip4", "set", "set IP4 related security", " ", SW_API_SEC_IP4_SET, NULL}, + {"ip6", "set", "set IP6 related security", " ", SW_API_SEC_IP6_SET, NULL}, + {"tcp", "set", "set TCP related security", " ", SW_API_SEC_TCP_SET, NULL}, + {"udp", "set", "set UDP related security", " ", SW_API_SEC_UDP_SET, NULL}, + {"icmp4", "set", "set ICMP4 related security", " ", SW_API_SEC_ICMP4_SET, NULL}, + {"icmp6", "set", "set ICMP6 related security", " ", SW_API_SEC_ICMP6_SET, NULL}, + {NULL, NULL, NULL, NULL, (int)NULL, NULL}/*end of desc*/ + }, + }, +#endif +#endif + + /*stp*/ +#ifdef IN_STP + { + "stp", "config STP", + { + {"portState", "set", "set STP state of a port", " ", SW_API_STP_PT_STATE_SET, NULL}, + {NULL, NULL, NULL, NULL, (int)NULL, NULL}/*end of desc*/ + }, + }, +#endif + + /*mib*/ +#ifdef IN_MIB + { + "mib", "show MIB statistics information", + { + {"status", "set", "set mib status", "", SW_API_MIB_STATUS_SET, 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}, + {NULL, NULL, NULL, NULL, (int)NULL, 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}, + {NULL, NULL, NULL, NULL, (int)NULL, 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}, + {"dscp2dp", "set", "set dscp to dp map table", " ", SW_API_COSMAP_DSCP_TO_DP_SET, NULL}, + {"up2pri", "set", "set dot1p to priority map table", " ", SW_API_COSMAP_UP_TO_PRI_SET, NULL}, + {"up2dp", "set", "set dot1p to dp map table", " ", SW_API_COSMAP_UP_TO_DP_SET, NULL}, + {"dscp2ehpri", "set", "set dscp to priority map table for WAN port", " ", SW_API_COSMAP_DSCP_TO_EHPRI_SET, NULL}, + {"dscp2ehdp", "set", "set dscp to dp map table for WAN port", " ", SW_API_COSMAP_DSCP_TO_EHDP_SET, NULL}, + {"up2ehpri", "set", "set dot1p to priority map table for WAN port", " ", SW_API_COSMAP_UP_TO_EHPRI_SET, NULL}, + {"up2ehdp", "set", "set dot1p to dp map table for WAN port", " ", SW_API_COSMAP_UP_TO_EHDP_SET, NULL}, + {"pri2q", "set", "set priority to queue mapping", " ", SW_API_COSMAP_PRI_TO_QU_SET, NULL}, + {"pri2ehq", "set", "set priority to enhanced queue mapping", " ", SW_API_COSMAP_PRI_TO_EHQU_SET, NULL}, + {"egRemark", "set", "set egress remark table", "", SW_API_COSMAP_EG_REMARK_SET, NULL}, + {NULL, NULL, NULL, NULL, (int)NULL, NULL}/*end of desc*/ + }, + }, +#endif + + /*misc*/ +#ifdef IN_MISC + { + "misc", "config miscellaneous", + { +#ifndef ISISC + {"arp", "set", "set arp packets hardware identification status", "", SW_API_ARP_STATUS_SET, NULL}, +#endif + {"frameMaxSize", "set", "set the maximal received frame size of the device", "", SW_API_FRAME_MAX_SIZE_SET, NULL}, +#ifndef ISISC + {"ptUnkSaCmd", "set", "set forwarding command for frames with unknown source address", " ", SW_API_PT_UNK_SA_CMD_SET, NULL}, +#endif + {"ptUnkUcFilter", "set", "set flooding status of unknown unicast frames", " ", SW_API_PT_UNK_UC_FILTER_SET, NULL}, + {"ptUnkMcFilter", "set", "set flooding status of unknown multicast frames", " ", SW_API_PT_UNK_MC_FILTER_SET, NULL}, + {"ptBcFilter", "set", "set flooding status of broadcast frames", " ", SW_API_PT_BC_FILTER_SET, NULL}, + {"cpuPort", "set", "set cpu port status", "", SW_API_CPU_PORT_STATUS_SET, NULL}, +#ifndef ISISC + {"bctoCpu", "set", "set broadcast frames to Cpu port status", "", SW_API_BC_TO_CPU_PORT_SET, NULL}, +#endif +#ifdef ISISC + {"PppoeCmd", "set", "set pppoe frames forwarding command", "", SW_API_PPPOE_CMD_SET, NULL}, +#else + {"PppoeCmd", "set", "set pppoe frames forwarding command", "", SW_API_PPPOE_CMD_SET, NULL}, +#endif + {"Pppoe", "set", "set pppoe frames hardware identification status", "", SW_API_PPPOE_STATUS_SET, NULL}, + {"ptDhcp", "set", "set dhcp frames hardware identification status", " ", SW_API_PT_DHCP_SET, NULL}, +#ifdef ISISC + {"arpcmd", "set", "set arp packets forwarding command", "", SW_API_ARP_CMD_SET, NULL}, +#else + {"arpcmd", "set", "set arp packets forwarding command", "", SW_API_ARP_CMD_SET, NULL}, +#endif +#ifdef ISISC + {"eapolcmd", "set", "set eapol packets forwarding command", "", SW_API_EAPOL_CMD_SET, NULL}, +#else + {"eapolcmd", "set", "set eapol packets forwarding command", "", SW_API_EAPOL_CMD_SET, NULL}, +#endif +#ifndef ISISC + {"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}, +#endif + {"eapolstatus", "set", "set eapol frames hardware identification status", " ", SW_API_EAPOL_STATUS_SET, NULL}, + {"rip", "set", "set rip packets copy to cpu status", "", SW_API_RIPV1_STATUS_SET, NULL}, + {"ptarpreq", "set", "set arp request packets hardware identification status", " ", SW_API_PT_ARP_REQ_STATUS_SET, NULL}, + {"ptarpack", "set", "set arp ack packets hardware identification status", " ", SW_API_PT_ARP_ACK_STATUS_SET, NULL}, + {"extendpppoe", "set", "add a pppoe session entry", "", SW_API_PPPOE_SESSION_TABLE_ADD, 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}, + {"pppoeid", "set", "set a pppoe session id entry", " ", SW_API_PPPOE_SESSION_ID_SET, NULL}, + {"intrmask", "set", "set switch interrupt mask", "", SW_API_INTR_MASK_SET, 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}, + {"intrmaskmaclinkchg", "set", "set switch interrupt mask for mac link change", " ", SW_API_INTR_MASK_MAC_LINKCHG_SET, 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}, + {"rtdPppoe", "set", "set RM_RTD_PPPOE_EN status", "", SW_API_RTD_PPPOE_EN_SET, NULL}, + {"glomacaddr", "set", "set global macaddr", "", SW_API_GLOBAL_MACADDR_SET, NULL}, + {"lldp", "set", "set lldp frames hardware identification status", "", SW_API_LLDP_STATUS_SET, NULL}, + {"framecrc", "set", "set frame crc reserve enable", "", SW_API_FRAME_CRC_RESERVE_SET, NULL}, + {NULL, NULL, NULL, NULL, (int)NULL, NULL}/*end of desc*/ + }, + }, +#endif + + /* IP */ +#ifdef IN_IP + { + "ip", "config ip", + { + {"hostentry", "set", "add host entry", "", SW_API_IP_HOST_ADD, NULL}, + {"hostentry", "add", "add host entry", "", SW_API_IP_HOST_ADD, NULL}, + {"hostentry", "del", "del host entry", "", SW_API_IP_HOST_DEL, NULL}, + {"hostentry", "next", "next host entry", "", SW_API_IP_HOST_NEXT, NULL}, + {"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}, + {"arplearn", "set", "set arp learn mode", "", SW_API_IP_ARP_LEARN_SET, NULL}, + {"ptipsrcguard", "set", "set ip source guard mode", " ", SW_API_IP_SOURCE_GUARD_SET, NULL}, + {"ptarpsrcguard", "set", "set arp source guard mode", " ", SW_API_IP_ARP_GUARD_SET, NULL}, + {"routestatus", "set", "set ip route status", "", SW_API_IP_ROUTE_STATUS_SET, NULL}, + {"intfentry", "set", "add interface mac address", "", SW_API_IP_INTF_ENTRY_ADD, 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}, + {"ipunksrc", "set", "set ip unkown source command", "", SW_API_IP_UNK_SOURCE_CMD_SET, NULL}, + {"arpunksrc", "set", "set arp unkown source command", "", SW_API_ARP_UNK_SOURCE_CMD_SET, NULL}, + {"ipagetime", "set", "set dynamic ip entry age time", "
    + +
    NAME
    +
    +Judy1 macros - +C library for creating and accessing a dynamic array of bits, using +any value of a word as an index. + +

    +

    SYNOPSIS
    +
    +
    +cc [flags] sourcefiles -lJudy
    +
    +

    +

    +#include <Judy.h>
    +
    +int     Rc_int;                          // return code - integer
    +Word_t  Rc_word;                         // return code - unsigned word
    +Word_t  Index, Index1, Index2, Nth;
    +
    +Pvoid_t PJ1Array = (Pvoid_t) NULL;       // initialize Judy1 array
    +
    +J1S( Rc_int,  PJ1Array, Index);          // Judy1Set()
    +J1U( Rc_int,  PJ1Array, Index);          // Judy1Unset()
    +J1T( Rc_int,  PJ1Array, Index);          // Judy1Test()
    +J1C( Rc_word, PJ1Array, Index1, Index2); // Judy1Count()
    +J1BC(Rc_int,  PJ1Array, Nth, Index);     // Judy1ByCount()
    +J1FA(Rc_word, PJ1Array);                 // Judy1FreeArray()
    +J1MU(Rc_word, PJ1Array);                 // Judy1MemUsed()
    +J1F( Rc_int,  PJ1Array, Index);          // Judy1First()
    +J1N( Rc_int,  PJ1Array, Index);          // Judy1Next()
    +J1L( Rc_int,  PJ1Array, Index);          // Judy1Last()
    +J1P( Rc_int,  PJ1Array, Index);          // Judy1Prev()
    +J1FE(Rc_int,  PJ1Array, Index);          // Judy1FirstEmpty()
    +J1NE(Rc_int,  PJ1Array, Index);          // Judy1NextEmpty()
    +J1LE(Rc_int,  PJ1Array, Index);          // Judy1LastEmpty()
    +J1PE(Rc_int,  PJ1Array, Index);          // Judy1PrevEmpty()
    +
    + +

    +

    DESCRIPTION
    +
    +A Judy1 array is the equivalent of a bit array or bit map. +A bit is addressed by an Index (key). +The array may be sparse, and the Index may be any word-sized Value. +If an index is present, it represents a set bit +(a bit set represents an index present). +If an index is absent, it represents an unset bit +(a bit unset represents an absent index). +

    +A Judy1 array is allocated with a NULL pointer +

    +Pvoid_t PJ1Array = (Pvoid_t) NULL;
    +
    +Memory to support the array is allocated as bits are set, +and released as bits are unset. +If the Judy1 pointer (PJ1Array) is NULL, all bits are unset (and +the Judy1 array requires no memory). +

    +As with an ordinary array, a Judy1 array contains no duplicate indexes. +

    +Using the macros described here, rather than the +Judy1 function calls, +the default error handling sends a +message to the standard error and terminates the program with +exit(1). +For other error handling methods, see the +ERRORS section. +

    +Because the macro forms are sometimes faster and have a simpler error +handling interface than the equivalent +functions, +they are the preferred way of calling the Judy1 functions. +

    +

    +
    J1S(Rc_int, PJ1Array, Index); // Judy1Set()
    +
    +Set Index's bit in the Judy1 array PJ1Array. +

    +Return Rc_int set to 1 if Index's bit was previously unset +(successful), otherwise 0 +if the bit was already set (unsuccessful). +

    +

    J1U(Rc_int, PJ1Array, Index); // Judy1Unset()
    +
    +Unset Index's bit in the Judy1 array PJ1Array; +that is, remove Index from the Judy1 array. +

    +Return Rc_int set to 1 if Index's bit was +previously set (successful), otherwise 0 +if the bit was already unset (unsuccessful). +

    +

    J1T(Rc_int, PJ1Array, Index); // Judy1Test()
    +
    +Test if Index's bit is set in the +Judy1 array PJ1Array. +

    +Return Rc_int set to 1 if Index's bit is set +(Index is present), +0 if it is unset (Index is absent). +

    +

    J1C(Rc_word, PJ1Array, Index1, Index2); // Judy1Count()
    +
    +Count the number of indexes present in the Judy1 array +PJ1Array between +Index1 and Index2 (inclusive). +

    +Return Rc_word set to the count. +A return Value of 0 can be valid as a count, +or it can indicate a special case for fully +populated array (32-bit machines only). See +Judy1Count() +for ways to resolve this. +

    +To count all indexes present (population) in a Judy1 bit array, use: +

    +J1C(Rc_word, PJ1Array, 0, -1);
    +
    +Note: The -1 promotes to the maximum index, that is, all ones. +

    +

    J1BC(Rc_int, PJ1Array, Nth, Index); // Judy1ByCount()
    +
    +Locate the Nth index that is present in the Judy1 array +PJ1Array (Nth = 1 returns the first index present). +To refer to the last index in a fully populated array (all indexes +present, which is rare), use Nth = 0. +

    +Return Rc_int set to 1 and Index set to the +Nth index if found, otherwise return Rc_int +set to 0 (the Value of Index contains no +useful information). +

    +

    J1FA(Rc_word, PJ1Array); // Judy1FreeArray()
    +
    +Free the entire Judy1 array PJ1Array (much faster than using a +J1N(), J1U() loop). +

    +Return Rc_word set to the number of bytes freed, +and PJ1Array set to NULL. +

    +

    J1MU(Rc_word, PJ1Array); // Judy1MemUsed()
    +
    +Return Rc_word set to the number of bytes of memory currently in use by +Judy1 array PJ1Array. This is a very fast routine, and may be used after +a J1S() or J1U() call with little performance impact. +

    +

    Judy1 Search Functions
    +
    +The Judy1 search functions allow you to search for set or unset bits in the array. +You may search inclusively or exclusively, +in either forward or reverse directions. +All of the search functions use a similar calling sequence. +Rc_int is returned set to 1 for a successful search and the found Index is returned. +Rc_int is returned set to 0 for an unsuccessful search, +and Index contains no useful information. +The return code Rc_int must be checked prior to using the returned Index, +since a search failure is possible. +

    +

    J1F(Rc_int, PJ1Array, Index); // Judy1First()
    +
    +Search (inclusive) for the first index present that is equal +to or greater than the passed Index. +(Start with Index = 0 to find the first index in the +array.) J1F() is typically used to begin a +sorted-order scan of the indexes present in a Judy1 array. +

    +

    J1N(Rc_int, PJ1Array, Index); // Judy1Next()
    +
    +Search (exclusive) for the next index present that is +greater than the passed Index. +J1N() is typically used to continue a +sorted-order scan of the indexes present +in a Judy1 array, or to locate a "neighbor" of a given index. +

    +

    J1L(Rc_int, PJ1Array, Index); // Judy1Last()
    +
    +Search (inclusive) for the last index present that is equal +to or less than the passed Index. (Start with +Index = -1, that is, all ones, to find the last index +in the array.) J1L() is typically used to begin +a reverse-sorted-order scan +of the indexes present in a Judy1 array. +

    +

    J1P(Rc_int, PJ1Array, Index); // Judy1Prev()
    +
    +Search (exclusive) for the previous index present that is +less than the passed Index. J1P() is typically +used to continue a reverse-sorted-order scan of the indexes +present in a Judy1 array, or to locate a "neighbor" of a given index. +

    +

    J1FE(Rc_int, PJ1Array, Index); // Judy1FirstEmpty()
    +
    +Search (inclusive) for the first absent index that is equal to +or greater than the passed Index. (Start with +Index = 0 to find the first index absent in the array.) +

    +

    J1NE(Rc_int, PJ1Array, Index); // Judy1NextEmpty()
    +
    +Search (exclusive) for the next absent index that is +greater than the passed Index. +

    +

    J1LE(Rc_int, PJ1Array, Index); // Judy1LastEmpty()
    +
    +Search (inclusive) for the last absent index that is +equal to or less than the passed Index. +(Start with Index = -1 to find the last index +absent in the array.) +

    +

    J1PE(Rc_int, PJ1Array, Index); // Judy1PrevEmpty()
    +
    +Search (exclusive) for the previous absent index that is +less than the passed Index. +
    + +

    +

    ERRORS: See: Judy_3.htm#ERRORS
    +
    + +

    +

    EXAMPLE
    +
    +In the following example, errors in the J1S() or J1U() calls +go to a user-defined procedure, process_malloc_failure. This is not needed +when you use the default JUDYERROR() macro, since the default causes +your program to exit on all failures, +including malloc() failure. +

    +

    +#include <stdio.h>
    +#include <Judy.h>
    +
    +int main()                       // Example program of Judy1 macro APIs
    +{
    +   Word_t Index;                 // index (or key)
    +   Word_t Rcount;                // count of indexes (or bits set)
    +   Word_t Rc_word;               // full word return value
    +   int    Rc_int;                // boolean values returned (0 or 1)
    +
    +   Pvoid_t PJ1Array = (Pvoid_t) NULL; // initialize Judy1 array
    +
    +   Index = 123456;
    +   J1S(Rc_int, J1Array, Index);  // set bit at 123456
    +   if (Rc_int == JERR) goto process_malloc_failure;
    +   if (Rc_int == 1) printf("OK - bit successfully set at %lu\n", Index);
    +   if (Rc_int == 0) printf("BUG - bit already set at %lu\n", Index);
    +
    +   Index = 654321;
    +   J1T(Rc_int, J1Array, Index);  // test if bit set at 654321
    +   if (Rc_int == 1) printf("BUG - set bit at %lu\n", Index);
    +   if (Rc_int == 0) printf("OK - bit not set at %lu\n", Index);
    +
    +   J1C(Rcount, J1Array, 0, -1);  // count all bits set in array
    +   printf("%lu bits set in Judy1 array\n", Rcount);
    +
    +   Index = 0;
    +   J1F(Rc_int, J1Array, Index);  // find first bit set in array
    +   if (Rc_int == 1) printf("OK - first bit set is at %lu\n", Index);
    +   if (Rc_int == 0) printf("BUG - no bits set in array\n");
    +
    +   J1MU(Rc_word, J1Array);       // how much memory was used?
    +   printf("%lu Indexes used %lu bytes of memory\n", Rcount, Rc_word);
    +
    +   Index = 123456;
    +   J1U(Rc_int, J1Array, Index);  // unset bit at 123456
    +   if (Rc_int == JERR) goto process_malloc_failure;
    +   if (Rc_int == 1) printf("OK - bit successfully unset at %lu\n", Index);
    +   if (Rc_int == 0) printf("BUG - bit was not set at %lu\n", Index);
    +
    +   return(0);
    +}
    +
    + +

    +

    AUTHOR
    +
    +Judy was invented by Doug Baskins and implemented by Hewlett-Packard. + +

    +

    SEE ALSO
    +
    +Judy(3), +JudyL(3), +JudySL(3), +JudyHS(3), +
    +malloc(), +
    +the Judy website, + +http://judy.sourceforge.net, +for more information and Application Notes. +
    + + diff --git a/feeds/p4/libjudy/src/doc/ext/Judy1_funcs_3.htm b/feeds/p4/libjudy/src/doc/ext/Judy1_funcs_3.htm new file mode 100644 index 000000000..1f82d074b --- /dev/null +++ b/feeds/p4/libjudy/src/doc/ext/Judy1_funcs_3.htm @@ -0,0 +1,260 @@ + + + +Judy1_funcs(3) + + + + + + +
    Judy1_funcs(3) Judy1_funcs(3)
    +

    +

    + +
    NAME
    +
    +Judy1 functions - +C library for creating and accessing a dynamic array of bits, using +any value of a word as an index + +

    +

    SYNOPSIS
    +
    +
    +int    Judy1Set(       PPvoid_t PPJ1Array, Word_t   Index,  PJError_t PJError);
    +int    Judy1Unset(     PPvoid_t PPJ1Array, Word_t   Index,  PJError_t PJError);
    +int    Judy1Test(      Pcvoid_t  PJ1Array, Word_t   Index,  PJError_t PJError);
    +Word_t Judy1Count(     Pcvoid_t  PJ1Array, Word_t   Index1, Word_t    Index2, PJError_t PJError);
    +int    Judy1ByCount(   Pcvoid_t  PJ1Array, Word_t   Nth,    Word_t * PIndex,  PJError_t PJError);
    +Word_t Judy1FreeArray( PPvoid_t PPJ1Array, PJError_t PJError);
    +Word_t Judy1MemUsed(   Pcvoid_t  PJ1Array);
    +int    Judy1First(     Pcvoid_t  PJ1Array, Word_t * PIndex, PJError_t PJError);
    +int    Judy1Next(      Pcvoid_t  PJ1Array, Word_t * PIndex, PJError_t PJError);
    +int    Judy1Last(      Pcvoid_t  PJ1Array, Word_t * PIndex, PJError_t PJError);
    +int    Judy1Prev(      Pcvoid_t  PJ1Array, Word_t * PIndex, PJError_t PJError);
    +int    Judy1FirstEmpty(Pcvoid_t  PJ1Array, Word_t * PIndex, PJError_t PJError);
    +int    Judy1NextEmpty( Pcvoid_t  PJ1Array, Word_t * PIndex, PJError_t PJError);
    +int    Judy1LastEmpty( Pcvoid_t  PJ1Array, Word_t * PIndex, PJError_t PJError);
    +int    Judy1PrevEmpty( Pcvoid_t  PJ1Array, Word_t * PIndex, PJError_t PJError);
    +
    + +

    +

    DESCRIPTION
    +
    +A macro equivalent exists for each function call. +Because the macro forms are sometimes faster and have a simpler error +handling interface than the equivalent functions, +they are the preferred way of calling the Judy1 functions. +See Judy1(3) +for more information. +The function call definitions are included here for completeness. +

    +One of the difficulties in using the Judy1 function calls lies in +determining whether to pass a pointer or the address of a pointer. +Since the functions that modify the Judy1 array must also modify the +pointer to the Judy1 array, you must pass the address of the pointer +rather than the pointer itself. +This often leads to hard-to-debug programmatic errors. +In practice, the macros allow the compiler to catch programming +errors when pointers instead of addresses of pointers are passed. +

    +The Judy1 function calls have an additional parameter beyond +those specified in the macro calls. This parameter is either a +pointer to an error structure, or NULL (in which case the +detailed error information is not returned). +

    +In the following descriptions, the functions are described in +terms of how the macros use them (only in the case of +#define JUDYERROR_NOTEST 1). This is the suggested use +of the macros after your program has been fully debugged. +When the JUDYERROR_NOTEST macro is not specified, +an error structure is declared to store error information +returned from the Judy1 functions when an error occurs. +

    +Notice the placement of the & in the different functions. +

    +

    +
    Judy1Set(&PJ1Array, Index, &JError)
    +
    +
    +#define J1S(Rc_int, PJ1Array, Index) \
    +   Rc_int = Judy1Set(&PJ1Array, Index, PJE0)
    +
    +
    +

    +

    Judy1Unset(&PJ1Array, Index, &JError)
    +
    +
    +#define J1U(Rc_int, PJ1Array, Index) \
    +   Rc_int = Judy1Unset(&PJ1Array, Index, PJE0)
    +
    +
    +

    +

    Judy1Test(PJ1Array, Index, &JError)
    +
    +
    +#define J1T(Rc_int, PJ1Array, Index) \
    +   Rc_int = Judy1Test(PJ1Array, Index, PJE0)
    +
    +
    +

    +

    Judy1Count(PJ1Array, Index1, Index2, &JError)
    +
    +
    +#define J1C(Rc_word, PJ1Array, Index1, Index2) \
    +   Rc_word = Judy1Count(PJ1Array, Index1, Index2, PJE0)
    +
    +
    +A return value of 0 can be an error, valid as a count, or it can indicate a special case +for a fully-populated array (32-bit machines only). If necessary, the following +code can be used to disambiguate this return: +
    +JError_t JError;
    +
    +Rc_word = Judy1Count(PJ1Array, Index1, Index2, &JError);
    +if (Rc_word == 0)
    +{
    +    if (JU_ERRNO(&JError) == JU_ERRNO_NONE)
    +        printf("Judy1 array population == 0\n");
    +    if (JU_ERRNO(&JError) == JU_ERRNO_FULL)
    +        printf("Judy1 array population == 2^32\n");
    +    if (JU_ERRNO(&JError) == JU_ERRNO_NULLPPARRAY)
    +        goto NullArray;
    +    if (JU_ERRNO(&JError) >  JU_ERRNO_NFMAX)
    +        goto Null_or_CorruptArray;
    +}
    +
    +

    +

    Judy1ByCount(PJ1Array, Nth, &Index, &JError)
    +
    +
    +#define J1BC(Rc_int, PJ1Array, Nth, Index) \
    +   Rc_int = Judy1ByCount(PJ1Array, Nth, &Index, PJE0)
    +
    +
    +

    +

    Judy1FreeArray(&PJ1Array, &JError)
    +
    +
    +#define J1FA(Rc_word, PJ1Array) \
    +   Rc_word = Judy1FreeArray(&PJ1Array, PJE0)
    +
    +
    +

    +

    Judy1MemUsed(PJ1Array)
    +
    +
    +#define J1MU(Rc_word, PJ1Array) \
    +   Rc_word = Judy1MemUsed(PJ1Array)
    +
    +
    +

    +

    Judy1First(PJ1Array, &Index, &JError)
    +
    +
    +#define J1F(Rc_int, PJ1Array, Index) \
    +   Rc_int = Judy1First(PJ1Array, &Index, PJE0)
    +
    +
    +

    +

    Judy1Next(PJ1Array, &Index, &JError)
    +
    +
    +#define J1N(Rc_int, PJ1Array, Index) \
    +   Rc_int = Judy1Next(PJ1Array, &Index, PJE0)
    +
    +
    +

    +

    Judy1Last(PJ1Array, &Index, &JError)
    +
    +
    +#define J1L(Rc_int, PJ1Array, Index) \
    +   Rc_int = Judy1Last(PJ1Array, &Index, PJE0)
    +
    +
    +

    +

    Judy1Prev(PJ1Array, &Index, &JError)
    +
    +
    +#define J1P(Rc_int, PJ1Array, Index) \
    +   Rc_int = Judy1Prev(PJ1Array, &Index, PJE0)
    +
    +
    +

    +

    Judy1FirstEmpty(PJ1Array, &Index, &JError)
    +
    +
    +#define J1FE(Rc_int, PJ1Array, Index) \
    +   Rc_int = Judy1FirstEmpty(PJ1Array, &Index, PJE0)
    +
    +
    +

    +

    Judy1NextEmpty(PJ1Array, &Index, &JError)
    +
    +
    +#define J1NE(Rc_int, PJ1Array, Index) \
    +   Rc_int = Judy1NextEmpty(PJ1Array, &Index, PJE0)
    +
    +
    +

    +

    Judy1LastEmpty(PJ1Array, &Index, &JError)
    +
    +
    +#define J1LE(Rc_int, PJ1Array, Index) \
    +   Rc_int = Judy1LastEmpty(PJ1Array, &Index, PJE0)
    +
    +
    +

    +

    Judy1PrevEmpty(PJ1Array, &Index, &JError)
    +
    +
    +#define J1PE(Rc_int, PJ1Array, Index) \
    +   Rc_int = Judy1PrevEmpty(PJ1Array, &Index, PJE0)
    +
    +
    +
    +

    +Definitions for all of the Judy functions, the types +Pvoid_t, +Pcvoid_t, +PPvoid_t, +Word_t, +JError_t, +and +PJError_t, +the constants +NULL, +JU_ERRNO_*, +JERR, +and +PJE0, +are provided in the Judy.h header file +(/usr/include/Judy.h). +Note: Callers should define Judy1 arrays as type Pvoid_t, +which can be passed by value to functions that take +Pcvoid_t (constant Pvoid_t), +and also by address to functions that take PPvoid_t. + +

    +

    AUTHOR
    +
    +Judy was invented by Doug Baskins and implemented by Hewlett-Packard. + +

    +

    SEE ALSO
    +
    +Judy(3), +JudyL(3), +JudySL(3), +JudyHS(3), +
    +malloc(), +
    +the Judy website, + +http://judy.sourceforge.net, +for more information and Application Notes. +
    + + diff --git a/feeds/p4/libjudy/src/doc/ext/JudyHS_3.htm b/feeds/p4/libjudy/src/doc/ext/JudyHS_3.htm new file mode 100644 index 000000000..66d60b5fd --- /dev/null +++ b/feeds/p4/libjudy/src/doc/ext/JudyHS_3.htm @@ -0,0 +1,197 @@ + + + +JudyHS(3) + + + + + + +
    JudyHS(3) JudyHS(3)
    +

    + +

    NAME
    +
    +JudyHS macros - C library for creating and accessing a dynamic array, +using an array-of-bytes of Length as an Index and a word +as a Value. + +

    +

    SYNOPSIS
    +
    +
    +cc [flags] sourcefiles -lJudy
    +
    +#include <Judy.h>
    +
    +Word_t  * PValue;                           // JudyHS array element
    +int       Rc_int;                           // return flag
    +Word_t    Rc_word;                          // full word return value
    +Pvoid_t   PJHSArray = (Pvoid_t) NULL;       // initialize JudyHS array
    +uint8_t * Index;                            // array-of-bytes pointer
    +Word_t    Length;                           // number of bytes in Index
    +
    +JHSI( PValue,  PJHSArray, Index, Length);   // JudyHSIns()
    +JHSD( Rc_int,  PJHSArray, Index, Length);   // JudyHSDel()
    +JHSG( PValue,  PJHSArray, Index, Length);   // JudyHSGet()
    +JHSFA(Rc_word, PJHSArray);                  // JudyHSFreeArray()
    +
    + +
    DESCRIPTION
    +
    +A JudyHS array is the equivalent of an array of word-sized +value/pointers. An Index is a pointer to an array-of-bytes of +specified length: Length. Rather than using a null terminated +string, this difference from JudySL(3) +allows strings to contain all bits (specifically the null character). +This new addition (May 2004) to Judy arrays is a hybird using the best +capabilities of hashing and Judy methods. JudyHS does not have a +poor performance case where knowledge of the hash algorithm can be used +to degrade the performance. +

    +Since JudyHS is based on a hash method, Indexes are not stored in +any particular order. Therefore the JudyHSFirst(), JudyHSNext(), +JudyHSPrev() and JudyHSLast() neighbor search functions are not +practical. The Length of each array-of-bytes can be from 0 to +the limits of malloc() (about 2GB). +

    +The hallmark of JudyHS is speed with scalability, but memory +efficiency is excellent. The speed is very competitive with the best +hashing methods. The memory efficiency is similar to a linked list of +the same Indexes and Values. JudyHS is designed to +scale from 0 to billions of Indexes. +

    +A JudyHS array is allocated with a NULL pointer +

    +Pvoid_t PJHSArray = (Pvoid_t) NULL;
    +
    +

    +Because the macro forms of the API have a simpler error handling +interface than the equivalent +functions, +they are the preferred way to use JudyHS. +

    +

    +JHSI(PValue, PJHSArray, Index, Length) // JudyHSIns()
    +
    +Given a pointer to a JudyHS array (PJHSArray), insert an +Index string of length: Length and a Value into the +JudyHS array: PJHSArray. If the Index is successfully +inserted, the Value is initialized to 0. If the Index was +already present, the Value is not modified. +

    +Return PValue pointing to Value. Your program should use +this pointer to read or modify the Value, for example: +

    +Value = *PValue;
    +*PValue = 1234;
    +
    +

    +Note: +JHSI() and JHSD can reorganize the JudyHS array. +Therefore, pointers returned from previous JudyHS calls become +invalid and must be re-acquired (using JHSG()). +

    +

    JHSD(Rc_int, PJHSArray, Index, Length) // JudyHSDel()
    +
    +Given a pointer to a JudyHS array (PJHSArray), delete the +specified Index along with the Value from the JudyHS +array. +

    +Return Rc_int set to 1 if successfully removed from the array. +Return Rc_int set to 0 if Index was not present. +

    +

    JHSG(PValue, PJHSArray, Index, Length) // JudyHSGet()
    +
    +Given a pointer to a JudyHS array (PJHSArray), +find Value associated with Index. +

    +Return PValue pointing to Index's Value. +Return PValue set to NULL if the Index was not present. +

    +

    JHSFA(Rc_word, PJHSArray) // JudyHSFreeArray()
    +
    +Given a pointer to a JudyHS array (PJHSArray), free the entire array. +

    +Return Rc_word set to the number of bytes freed and PJHSArray set to NULL. + +

    +

    ERRORS: See: Judy_3.htm#ERRORS
    +
    +

    +

    EXAMPLES
    +
    +Show how to program with the JudyHS macros. This program will print +duplicate lines and their line number from stdin. +

    +#include <unistd.h>
    +#include <stdio.h>
    +#include <string.h>
    +#include <Judy.h>
    +
    +//  Compiled:
    +//  cc -O PrintDupLines.c -lJudy -o PrintDupLines
    +
    +#define MAXLINE 1000000                 /* max fgets length of line */
    +uint8_t   Index[MAXLINE];               // string to check
    +
    +int     // Usage:  PrintDupLines < file
    +main()
    +{
    +    Pvoid_t   PJArray = (PWord_t)NULL;  // Judy array.
    +    PWord_t   PValue;                   // Judy array element pointer.
    +    Word_t    Bytes;                    // size of JudyHS array.
    +    Word_t    LineNumb = 0;             // current line number
    +    Word_t    Dups = 0;                 // number of duplicate lines
    +
    +    while (fgets(Index, MAXLINE, stdin) != (char *)NULL)
    +    {
    +        LineNumb++;                     // line number
    +
    +        // store string into array
    +        JHSI(PValue, PJArray, Index, strlen(Index)); 
    +        if (PValue == PJERR)            // See ERRORS section
    +        {
    +            fprintf(stderr, "Out of memory -- exit\n");
    +            exit(1);
    +        }
    +        if (*PValue == 0)               // check if duplicate
    +        {
    +            Dups++;
    +            printf("Duplicate lines %lu:%lu:%s", *PValue, LineNumb, Index);
    +        }
    +        else
    +        {
    +            *PValue = LineNumb;         // store Line number
    +        }
    +    }
    +    printf("%lu Duplicates, free JudyHS array of %lu Lines\n", 
    +                    Dups, LineNumb - Dups);
    +    JHSFA(Bytes, PJArray);              // free JudyHS array
    +    printf("JudyHSFreeArray() free'ed %lu bytes of memory\n", Bytes);
    +    return (0);
    +}
    +
    + +

    +

    AUTHOR
    +
    +JudyHS was invented and implemented by Doug Baskins after retiring from Hewlett-Packard. + +

    +

    SEE ALSO
    +
    +Judy(3), +Judy1(3), +JudyL(3), +JudySL(3), +
    +malloc(), +
    +the Judy website, + +http://judy.sourceforge.net, +for further information and Application Notes. + + diff --git a/feeds/p4/libjudy/src/doc/ext/JudyHS_funcs_3.htm b/feeds/p4/libjudy/src/doc/ext/JudyHS_funcs_3.htm new file mode 100644 index 000000000..01c8dff43 --- /dev/null +++ b/feeds/p4/libjudy/src/doc/ext/JudyHS_funcs_3.htm @@ -0,0 +1,150 @@ + + + +JudyHS_funcs(3) + + + + + + +
    JudyHS_funcs(3) JudyHS_funcs(3)
    +

    +

    + +
    NAME
    +
    +JudyHS functions - +C library for creating and accessing a dynamic array, +using an array-of-bytes of a length: Length as an Index and a word +as a Value. + +

    +

    SYNOPSIS
    +
    +
    +PPvoid_t JudyHSIns(PPvoid_t PPJHS, void *Index, Word_t Length, PJError_t PJError);
    +int      JudyHSDel(PPvoid_t PPJHS, void *Index, Word_t Length, PJError_t PJError);
    +PPvoid_t JudyHSGet(Pcvoid_t  PJHS, void *Index, Word_t Length, PJError_t PJError);
    +Word_t   JudyHSFreeArray(PPvoid_t PPJHS, PJError_t PJError);
    +
    + +

    +

    DESCRIPTION
    +
    +A macro equivalent exists for each function call. Because the macro +forms are sometimes faster and have a simpler error handling interface +than the equivalent functions, they are the preferred way of calling the +JudyHS functions. +See JudyHS(3) +for more information. +The function call definitions are included here for completeness. +

    +One of the difficulties in using the JudyHS function calls lies in +determining whether to pass a pointer or the address of a pointer. +Since the functions that modify the JudyHS array must also modify the +pointer to the JudyHS array, you must pass the address of the pointer +rather than the pointer itself. +This often leads to hard-to-debug programmatic errors. +In practice, the macros allow the compiler to catch programming +errors when pointers instead of addresses of pointers are passed. +

    +The JudyHS function calls have an additional parameter beyond those +specified in the macro calls. This parameter is either a pointer to an +error structure, or NULL (in which case the error information is +not returned -- only PJERR in the return parameter). +

    +In the following descriptions, the functions are described in +terms of how the macros use them. +This is the suggested use +of the macros after your program has been fully debugged. +When the JUDYERROR_NOTEST macro is not specified, +an error structure is declared to store error information +returned from the JudyHS functions when an error occurs. +

    +Notice the placement of the & in the different functions. +

    +

    +
    JudyHSIns(&PJHS, Index, Length, &JError)
    +
    +
    +#define JHSI(PValue, PJHS, Index) \
    +   PValue = JudyLIns(&PJHS, Index, PJE0)
    +
    +
    +

    +

    JudyHSDel(&PJHS, Index, Length, &JError)
    +
    +
    +#define JHSD(Rc_int, PJHS, Index, Length) \
    +   Rc_int = JudyHSDel(&PJHS, Index, Length, PJE0)
    +
    +
    +

    +

    JudyHSGet(PJHS, Index, Length)
    +
    +
    +#define JHSG(PValue, PJHS, Index, Length) \
    +   PValue = JudyHSIns(PJHS, Index, Length)
    +
    +
    +

    +

    JudyHSFreeArray(&PJHS, &JError)
    +
    +
    +#define JHSFA(Rc_word, PJHS) \
    +   Rc_word = JudyHSFreeArray(&PJHS, PJE0)
    +
    +
    +
    +

    +Definitions for all the Judy functions, the types +Pvoid_t, +Pcvoid_t, +PPvoid_t, +Word_t , +JError_t, +and +PJError_t, +the constants +NULL, +JU_ERRNO_*, +JERR, +PPJERR, +and +PJE0 +are provided in the Judy.h header file +(/usr/include/Judy.h). +Note: Callers should define JudyHS arrays as type Pvoid_t, +which can be passed by value to functions that take +Pcvoid_t (constant Pvoid_t), +and also by address to functions that take PPvoid_t. +

    +The return type from most JudyHS functions is PPvoid_t so +that the values stored in the array can be pointers to other objects, +which is a typical usage, or cast to a Word_t * when a pointer +to a value is required instead of a pointer to a pointer. + +

    +

    AUTHOR
    +
    +JudyHS was invented and implemented by Doug Baskins after retiring from Hewlett-Packard. + +

    +

    SEE ALSO
    +
    +Judy(3), +Judy1(3), +JudyL(3), +JudySL(3), +JudyHS(3), +
    +malloc(), +
    +the Judy website, + +http://judy.sourceforge.net, +for more information and Application Notes. +
    + + diff --git a/feeds/p4/libjudy/src/doc/ext/JudyL_3.htm b/feeds/p4/libjudy/src/doc/ext/JudyL_3.htm new file mode 100644 index 000000000..5b6b8802a --- /dev/null +++ b/feeds/p4/libjudy/src/doc/ext/JudyL_3.htm @@ -0,0 +1,358 @@ + + + +JudyL(3) + + + + + + +
    JudyL(3) JudyL(3)
    +

    +

    + +
    NAME
    +
    +JudyL macros - +C library for creating and accessing a dynamic array of words, using +a word as an index. + +

    +

    SYNOPSIS
    +
    +
    +cc [flags] sourcefiles -lJudy
    +
    +#include <Judy.h>
    +
    +int      Rc_int;                          // return code - integer
    +Word_t   Rc_word;                         // return code - unsigned word
    +Word_t   Index, Index1, Index2, Nth;
    +PWord_t  PValue;                          // pointer to return value
    +Pvoid_t PJLArray = (Pvoid_t) NULL;        // initialize JudyL array
    +
    +JLI( PValue,  PJLArray, Index);          // JudyLIns()
    +JLD( Rc_int,  PJLArray, Index);          // JudyLDel()
    +JLG( PValue,  PJLArray, Index);          // JudyLGet()
    +JLC( Rc_word, PJLArray, Index1, Index2); // JudyLCount()
    +JLBC(PValue,  PJLArray, Nth, Index);     // JudyLByCount()
    +JLFA(Rc_word, PJLArray);                 // JudyLFreeArray()
    +JLMU(Rc_word, PJLArray);                 // JudyLMemUsed()
    +JLF( PValue,  PJLArray, Index);          // JudyLFirst()
    +JLN( PValue,  PJLArray, Index);          // JudyLNext()
    +JLL( PValue,  PJLArray, Index);          // JudyLLast()
    +JLP( PValue,  PJLArray, Index);          // JudyLPrev()
    +JLFE(Rc_int,  PJLArray, Index);          // JudyLFirstEmpty()
    +JLNE(Rc_int,  PJLArray, Index);          // JudyLNextEmpty()
    +JLLE(Rc_int,  PJLArray, Index);          // JudyLLastEmpty()
    +JLPE(Rc_int,  PJLArray, Index);          // JudyLPrevEmpty()
    +
    + +

    +

    +DESCRIPTION +
    +
    +A JudyL array is the equivalent of an array of word-sized values. +A Value is addressed by an Index (key). +The array may be sparse, and the Index may be any word-sized number. +Memory to support the array is allocated as index/value pairs are inserted, +and released as index/value pairs are deleted. A JudyL array can also be +thought of as a mapper, that is "map" a word to another word/pointer. +

    +As with an ordinary array, there are no duplicate indexes in a JudyL array. +

    +The value may be used as a scalar, or a pointer to a structure or block of data +(or even another Judy array). +

    +A JudyL array is allocated with a NULL pointer +

    +Pvoid_t PJLArray = (Pvoid_t) NULL;
    +
    +

    +Using the macros described here, rather than the +JudyL function calls, +the default error handling sends a +message to the standard error and terminates the program with exit(1);. +For other error handling methods, see the +ERRORS section. +JLI( PValue, PJLArray, Index); // JudyLIns() +

    +Because the macro forms are sometimes faster and have a simpler error +handling interface than the equivalent +JudyL functions, +they are the preferred way of calling the JudyL functions. +

    +

    +
    JLI(PValue, PJLArray, Index) // JudyLIns()
    +
    +Insert an Index and Value into the JudyL array PJLArray. +If the Index is successfully inserted, +the Value is initialized to 0. If the Index was already present, +the Value is not modified. +

    +Return PValue pointing to Value. +Your program can use this pointer to read or modify Value until the next +JLI() (insert), JLD() (delete) or JLFA() (freearray) +is executed on PJLArray. Examples: +

    +*PValue = 1234;
    +Value = *PValue;
    +
    +

    +Return PValue set to PJERR if a malloc() fail occured. +Note: +JLI() and JLD() reorganize the JudyL array. +Therefore, PValue returned from previous JudyL calls become +invalid and must be re-acquired. +

    +

    JLD(Rc_int, PJLArray, Index) // JudyLDel()
    +
    +Delete the Index/Value pair from the JudyL array. +

    +Return Rc_int set to 1 if successful. +Return Rc_int set to 0 if Index was not present. +Return Rc_int set to JERR if a malloc() fail occured. +

    +

    JLG(PValue, PJLArray, Index) // JudyLGet()
    +
    +Get the pointer PValue associated with Index in the PJLArray Judy array. +

    +Return PValue pointing to Value. +Return PValue set to NULL if the Index was not present. +Return PValue set to PJERR if a malloc() fail occured. +

    +

    JLC(Rc_word, PJLArray, Index1, Index2) // JudyLCount()
    +
    +Count the number of indexes present in the JudyL array PJLArray between +Index1 and Index2 (inclusive). +

    +Return Rc_word set to the count. +A return value of 0 can be valid as a count. +

    +To count all indexes present in a JudyL array, use: +

    +JLC(Rc_word, PJLArray, 0, -1);
    +
    +

    +

    JLBC(PValue, PJLArray, Nth, Index) // JudyLByCount()
    +
    +Locate the Nth index that is present in the JudyL array +PJLArray (Nth = 1 returns the first index present). +

    +Return PValue pointing to its Value and Index +set to the Nth index if found, otherwise return +PValue set to NULL (the value of Index +is undefined). +

    +

    JLFA(Rc_word, PJLArray) // JudyLFreeArray()
    +
    +Given a pointer to a JudyL array, free the entire array (much faster +than using a +JLN(), JLD() loop). +

    +Return Rc_word set to the number of bytes freed and PJLArray +set to NULL. +

    +

    JLMU(Rc_word, PJLArray) // JudyLMemUsed()
    +
    +Return Rc_word set to the number of bytes of memory malloc()'ed +by PJLArray. +This is a very fast routine, and may be used before and after +a JLI() or JLD() call with little performance impact. +

    +

    JudyL Search Functions
    +
    +JLF(), JLN(), JLL(), JLP() +allow you to search for indexes +in the array. +You may search inclusively or exclusively, +in either forward or reverse directions. +If successful, +Index is returned set to the found index, and +PValue is returned set to a pointer to Index's Value. +If unsuccessful, +PValue is returned set to NULL, +and Index contains no useful information. +PValue must be tested for non-NULL prior +to using Index, +since a search failure is possible. +

    +JLFE(), JLNE(), JLLE(), JLPE() allow you to search for +indexes that are not present ("empty") in the array. +You may search inclusively or exclusively, +in either forward or reverse directions. +If successful, Index is returned set to a not present ("empty") index, and +Rc_int is returned set to 1. +If unsuccessful, Rc_int is returned set to 0, and and Index contains no useful information. +Rc_int must be checked prior to using Index, since a search failure is possible. +

    +

    JLF(PValue, PJLArray, Index) // JudyLFirst()
    +
    +Search (inclusive) for the first index present that is equal to or greater than the +passed Index. +(Start with Index = 0 to find the first index in the array.) +JLF() is typically used to begin a sorted-order scan of +the indexes present in a JudyL array. +

    +

    JLN(PValue, PJLArray, Index) // JudyLNext()
    +
    +Search (exclusive) for the next index present that is greater than the passed +Index. +JLN() is typically used to continue a sorted-order scan of +the indexes present in a JudyL array, or to locate a "neighbor" of a given index. +

    +

    JLL(PValue, PJLArray, Index) // JudyLLast()
    +
    +Search (inclusive) for the last index present that is equal to or less than the passed Index. +(Start with Index = -1, that is, all ones, to find the last index in the array.) +JLL() is typically used to begin a reverse-sorted-order +scan of the indexes present in a JudyL array. +

    +

    JLP(PValue, PJLArray, Index) // JudyLPrev()
    +
    +Search (exclusive) for the previous index present that is less than the +passed Index. +JLP() is typically used to continue a reverse-sorted-order +scan of the indexes present in a JudyL array, or to locate a "neighbor" of +a given index. +

    +

    JLFE(Rc_int, PJLArray, Index) // JudyLFirstEmpty()
    +
    +Search (inclusive) for the first index absent that is equal to or greater than the passed +Index. +(Start with Index = 0 to find the first index absent in the array.) +

    +

    JLNE(Rc_int, PJLArray, Index) // JudyLNextEmpty()
    +
    +Search (exclusive) for the next index absent that is greater than the passed Index. +

    +

    JLLE(Rc_int, PJLArray, Index) // JudyLLastEmpty()
    +
    +Search (inclusive) for the last index absent that is equal to or less than the passed Index. +(Start with Index = -1, that is, all ones, to find the last index absent +in the array.) +

    +

    JLPE(Rc_int, PJLArray, Index) // JudyLPrevEmpty()
    +
    +Search (exclusive) for the previous index absent that is less than the passed +Index. +
    + +

    +

    Multi-dimensional JudyL Arrays
    +
    +Storing a pointer to another JudyL array in a JudyL array's Value +is a simple way to support dynamic multi-dimensional arrays. +These arrays (or trees) built using JudyL arrays are very fast and +memory efficient. (In fact, that is how JudySL and JudyHS are implemented). +An arbitrary number of dimensions can be realized this way. +To terminate the number of dimensions (or tree), the Value pointer is +marked to NOT point to another Judy array. A JLAP_INVALID flag is +used in the least significant bit(s) of the pointer. +After the flag JLAP_INVALID is removed, it is used as a pointer to the users data. +The Judy.h header file defines JLAP_INVALID. +See code fragment below. +

    +Note: The current version of Judy.h changed this flag from 0x4 to 0x1 +to allow for a malloc() that does not deliver memory on an 8 byte +aligned boundry (such as old versions of valgrind). +

    +The following example code segment can be used to determine whether or +not a pointer points to another JudyL: +

    +

    +PValue = (PWord_t)PMultiDimArray;
    +
    +for (Dim = 0; ;Dim++)
    +{
    +   if (PValue == (PWord_t)NULL) goto IndexNotFound;
    +
    +   /* Advance to next dimension in array */
    +   JLG(PValue, (Pvoid_t)*PValue, Index[Dim]);
    +
    +   /* Check if pointer to user buffer: */
    +   if (*PValue & JLAP_INVALID)) break;
    +}
    +UPointer = (UPointer_t) (*PValue & ~JLAP_INVALID);  // mask and cast.
    +printf("User object pointer is 0x%lx\n", (Word_t) UPointer);
    +       ...
    +
    +

    +Note: This works because malloc() guarantees to return a pointer +with the least bit(s) == 0x0. +You must remove JLAP_INVALID before using the pointer. +

    + +

    +

    ERRORS: See: Judy_3.htm#ERRORS
    +
    + +

    +

    EXAMPLE
    +
    +Read a series of index/value pairs from the standard input, store +in a JudyL array, and then print out in sorted order. +

    +

    +#include <stdio.h>
    +#include <Judy.h>
    +
    +Word_t   Index;                     // array index
    +Word_t   Value;                     // array element value
    +Word_t * PValue;                    // pointer to array element value
    +int      Rc_int;                    // return code
    +
    +Pvoid_t  PJLArray = (Pvoid_t) NULL; // initialize JudyL array
    +
    +while (scanf("%lu %lu", &Index, &Value))
    +{
    +    JLI(PValue, PJLArray, Index);
    +    If (PValue == PJERR) goto process_malloc_failure;
    +    *PValue = Value;                 // store new value
    +}
    +// Next, visit all the stored indexes in sorted order, first ascending,
    +// then descending, and delete each index during the descending pass.
    +
    +Index = 0;
    +JLF(PValue, PJLArray, Index);
    +while (PValue != NULL)
    +{
    +    printf("%lu %lu\n", Index, *PValue));
    +    JLN(PValue, PJLArray, Index);
    +}
    +
    +Index = -1;
    +JLL(PValue, PJLArray, Index);
    +while (PValue != NULL)
    +{
    +    printf("%lu %lu\n", Index, *PValue));
    +
    +    JLD(Rc_int, PJLArray, Index);
    +    if (Rc_int == JERR) goto process_malloc_failure;
    +
    +    JLP(PValue, PJLArray, Index);
    +}
    +
    + +

    +

    AUTHOR
    +
    +Judy was invented by Doug Baskins and implemented by Hewlett-Packard. + +

    +

    SEE ALSO
    +
    +Judy(3), +Judy1(3), +JudySL(3), +JudyHS(3), +
    +malloc(), +
    + +http://judy.sourceforge.net, +for more information and Application Notes. + + diff --git a/feeds/p4/libjudy/src/doc/ext/JudyL_funcs_3.htm b/feeds/p4/libjudy/src/doc/ext/JudyL_funcs_3.htm new file mode 100644 index 000000000..a06092cd1 --- /dev/null +++ b/feeds/p4/libjudy/src/doc/ext/JudyL_funcs_3.htm @@ -0,0 +1,248 @@ + + + +JudyL_funcs(3) + + + + + + +
    JudyL_funcs(3) JudyL_funcs(3)
    +

    +

    + +
    NAME
    +
    +JudyL functions - +C library for creating and accessing a dynamic array of words, using +any value of a word as an index + +

    +

    SYNOPSIS
    +
    +
    +PPvoid_t JudyLIns(       PPvoid_t PPJLArray, Word_t    Index, PJError_t PJError);
    +int      JudyLDel(       PPvoid_t PPJLArray, Word_t    Index, PJError_t PJError);
    +PPvoid_t JudyLGet(       Pcvoid_t  PJLArray, Word_t    Index, PJError_t PJError);
    +Word_t   JudyLCount(     Pcvoid_t  PJLArray, Word_t    Index1, Word_t    Index2, PJError_t PJError);
    +PPvoid_t JudyLByCount(   Pcvoid_t  PJLArray, Word_t    Nth,  Word_t * PIndex,  PJError_t PJError);
    +Word_t   JudyLFreeArray( PPvoid_t PPJLArray, PJError_t PJError);
    +Word_t   JudyLMemUsed(   Pcvoid_t  PJLArray);
    +PPvoid_t JudyLFirst(     Pcvoid_t  PJLArray, Word_t * PIndex, PJError_t PJError);
    +PPvoid_t JudyLNext(      Pcvoid_t  PJLArray, Word_t * PIndex, PJError_t PJError);
    +PPvoid_t JudyLLast(      Pcvoid_t  PJLArray, Word_t * PIndex, PJError_t PJError);
    +PPvoid_t JudyLPrev(      Pcvoid_t  PJLArray, Word_t * PIndex, PJError_t PJError);
    +int      JudyLFirstEmpty(Pcvoid_t  PJLArray, Word_t * PIndex, PJError_t PJError);
    +int      JudyLNextEmpty( Pcvoid_t  PJLArray, Word_t * PIndex, PJError_t PJError);
    +int      JudyLLastEmpty( Pcvoid_t  PJLArray, Word_t * PIndex, PJError_t PJError);
    +int      JudyLPrevEmpty( Pcvoid_t  PJLArray, Word_t * PIndex, PJError_t PJError);
    +
    + +

    +

    DESCRIPTION
    +
    +A macro equivalent exists for each function call. +Because the macro forms are sometimes faster and have a simpler error +handling interface than the equivalent functions, +they are the preferred way of calling the JudyL functions. +See JudyL(3) +for more information. +The function call definitions are included here for completeness. +

    +One of the difficulties in using the JudyL function calls lies in +determining whether to pass a pointer or the address of a pointer. +Since the functions that modify the JudyL array must also modify the +pointer to the JudyL array, you must pass the address of the pointer +rather than the pointer itself. +This often leads to hard-to-debug programmatic errors. +In practice, the macros allow the compiler to catch programming +errors when pointers instead of addresses of pointers are passed. +

    +The JudyL function calls have an additional parameter beyond +those specified in the macro calls. This parameter is either a +pointer to an error structure, or NULL (in which case the +detailed error information is not returned). +

    +In the following descriptions, the functions are described in +terms of how the macros use them (only in the case of +#define JUDYERROR_NOTEST 1). This is the suggested use +of the macros after your program has been fully debugged. +When the JUDYERROR_NOTEST macro is not specified, +an error structure is declared to store error information +returned from the JudyL functions when an error occurs. +

    +Notice the placement of the & in the different functions. +

    +

    +
    JudyLIns(&PJLArray, Index, &JError)
    +
    +
    +#define JLI(PValue, PJLArray, Index)  \
    +   PValue = JudyLIns(&PJLArray, Index, PJE0)
    +
    +
    +

    +

    JudyLDel(&PJLArray, Index, &JError)
    +
    +
    +#define JLD(Rc_int, PJLArray, Index)  \
    +   Rc_int = JudyLDel(&PJLArray, Index, PJE0)
    +
    +
    +

    +

    JudyLGet(PJLArray, Index, &JError)
    +
    +
    +#define JLG(PValue, PJLArray, Index)  \
    +   PValue = JudyLGet(PJLArray, Index, PJE0)
    +
    +
    +

    +

    JudyLCount(PJLArray, Index1, Index2, &JError)
    +
    +
    +#define JLC(Rc_word, PJLArray, Index1, Index2)  \
    +   Rc_word = JudyLCount(PJLArray, Index1, Index2, PJE0)
    +
    +
    +

    +

    JudyLByCount(PJLArray, Nth, &Index, &JError)
    +
    +
    +#define JLBC(PValue, PJLArray, Nth, Index) \
    +   PValue = JudyLByCount(PJLArray, Nth, &Index, PJE0)
    +
    +
    +

    +

    JudyLFreeArray(&PJLArray, &JError)
    +
    +
    +#define JLFA(Rc_word, PJLArray) \
    +   Rc_word = JudyLFreeArray(&PJLArray, PJE0)
    +
    +
    +

    +

    JudyLMemUsed(PJLArray)
    +
    +
    +#define JLMU(Rc_word, PJLArray) \
    +   Rc_word = JudyLMemUsed(PJLArray)
    +
    +
    +

    +

    JudyLFirst(PJLArray, &Index, &JError)
    +
    +
    +#define JLF(PValue, PJLArray, Index) \
    +   PValue = JudyLFirst(PJLArray, &Index, PJEO)
    +
    +
    +

    +

    JudyLNext(PJLArray, &Index, &JError)
    +
    +
    +#define JLN(PValue, PJLArray, Index) \
    +   PValue = JudyLNext(PJLArray, &Index, PJEO)
    +
    +
    +

    +

    JudyLLast(PJLArray, &Index, &JError)
    +
    +
    +#define JLL(PValue, PJLArray, Index) \
    +   PValue = JudyLLast(PJLArray, &Index, PJEO)
    +
    +
    +

    +

    JudyLPrev(PJLArray, &Index, &JError)
    +
    +
    +#define JLP(PValue, PJLArray, Index) \
    +   PValue = JudyLPrev(PJLArray, &Index, PJEO)
    +
    +
    +

    +

    JudyLFirstEmpty(PJLArray, &Index, &JError)
    +
    +
    +#define JLFE(Rc_int, PJLArray, Index) \
    +   Rc_int = JudyLFirstEmpty(PJLArray, &Index, PJEO)
    +
    +
    +

    +

    JudyLNextEmpty(PJLArray, &Index, &JError)
    +
    +
    +#define JLNE(Rc_int, PJLArray, Index) \
    +   Rc_int = JudyLNextEmpty(PJLArray, &Index, PJEO)
    +
    +
    +

    +

    JudyLLastEmpty(PJLArray, &Index, &JError)
    +
    +
    +#define JLLE(Rc_int, PJLArray, Index) \
    +   Rc_int = JudyLLastEmpty(PJLArray, &Index, PJEO)
    +
    +
    +

    +

    JudyLPrevEmpty(PJLArray, &Index, &JError)
    +
    +
    +#define JLPE(Rc_int, PJLArray, Index) \
    +   Rc_int = JudyLPrevEmpty(PJLArray, &Index, PJEO)
    +
    +
    +
    +

    +Definitions for all the Judy functions, the types +Pvoid_t, +Pcvoid_t, +PPvoid_t, +Word_t, +JError_t, +and +PJError_t, +the constants +NULL, +JU_ERRNO_*, +JERR, +PPJERR, +and +PJE0, +are provided in the Judy.h header file +(/usr/include/Judy.h). +Note: Callers should define JudyL arrays as type Pvoid_t, +which can be passed by value to functions that take +Pcvoid_t (constant Pvoid_t), +and also by address to functions that take PPvoid_t. +

    +The return type from most JudyL functions is PPvoid_t so +that the values stored in the array can be pointers to other objects, +which is a typical usage, or cast to a Word_t * when a pointer +to a Value is required instead of a pointer to a pointer. + +

    +

    AUTHOR
    +
    +Judy was invented by Doug Baskins and implemented by Hewlett-Packard. + +

    +

    SEE ALSO
    +
    +Judy(3), +Judy1(3), +JudyL(3), +JudySL(3), +JudyHS(3), +
    +malloc(), +
    +the Judy website, + +http://judy.sourceforge.net, +for more information and Application Notes. +
    + + diff --git a/feeds/p4/libjudy/src/doc/ext/JudySL_3.htm b/feeds/p4/libjudy/src/doc/ext/JudySL_3.htm new file mode 100644 index 000000000..05ed5c5d5 --- /dev/null +++ b/feeds/p4/libjudy/src/doc/ext/JudySL_3.htm @@ -0,0 +1,246 @@ + + + +JudySL(3) + + + + + + +
    JudySL(3) JudySL(3)
    +

    +

    + +
    NAME
    +
    +JudySL macros - +C library for creating and accessing a dynamic array, using +a null-terminated string as an Index (associative array) + +

    +

    SYNOPSIS
    +
    +
    +cc [flags] sourcefiles -lJudy
    +
    +#include <Judy.h>
    +
    +#define MAXLINELEN 1000000           // define maximum string length
    +
    +Word_t * PValue;                     // JudySL array element
    +uint8_t  Index[MAXLINELEN];          // string
    +int      Rc_int;                     // return value
    +Word_t   Rc_word;                    // full word return value
    +
    +Pvoid_t PJSLArray = (Pvoid_t) NULL;  // initialize JudySL array
    +
    +JSLI( PValue,  PJSLArray, Index);   // JudySLIns()
    +JSLD( Rc_int,  PJSLArray, Index);   // JudySLDel()
    +JSLG( PValue,  PJSLArray, Index);   // JudySLGet()
    +JSLFA(Rc_word, PJSLArray);          // JudySLFreeArray()
    +JSLF( PValue,  PJSLArray, Index);   // JudySLFirst()
    +JSLN( PValue,  PJSLArray, Index);   // JudySLNext()
    +JSLL( PValue,  PJSLArray, Index);   // JudySLLast()
    +JSLP( PValue,  PJSLArray, Index);   // JudySLPrev()
    +
    +
    + +

    +

    DESCRIPTION
    +
    +A JudySL array is the equivalent of a sorted set of strings, each associated +with a Value (word). +A Value is addressed by an Index (key), which is a null-terminated +character string of any length. +Memory to support the array is allocated as index/value pairs are inserted, +and released as index/value pairs are deleted. +This is a form of associative array, where array elements are also sorted +lexicographically (case-sensitive) by indexes. +This could be thought of as +

    +void * JudySLArray["Toto, I don't think we're in Kansas any more"];
    +
    +

    +A JudySL array is allocated with a NULL pointer +

    +Pvoid_t PJSLArray = (Pvoid_t) NULL;
    +
    +As with an ordinary array, there are no duplicate indexes (strings) +in a JudySL array. +

    +Using the macros described here, rather than the +JudySL function calls, +the default error handling sends a +message to the standard error and terminates the program with +exit(1). +

    +

    JSLI(PValue, PJSLArray, Index) // JudySLIns()
    +
    +Insert an Index string and Value in the JudySL array PJSLArray. +If the Index is successfully inserted, +the Value is initialized to 0. If the Index was already present, +the Value is not modified. +

    +Return PValue pointing to Index's Value. +Your program must use this pointer to modify the Value, +for example: +

    +*PValue = 1234;
    +
    +

    +Note: +JSLI() and JSLD reorganize the JudySL array. +Therefore, pointers returned from previous JudySL calls become +invalid and must be reacquired. +

    +

    JSLD(Rc_int, PJSLArray, Index) // JudySLDel()
    +
    +Delete the specified Index/Value pair (array element) from the +JudySL array. +

    +Return Rc_int set to 1 if successful. +array and it was previously inserted. +Return Rc_int set to 0 if Index was not present. +

    +

    JSLG(PValue, PJSLArray, Index) // JudySLGet()
    +
    +Get the pointer to Index's Value. +

    +Return PValue pointing to Index's Value. +Return PValue set to NULL if the Index was not present. +

    +

    JSLFA(Rc_word, PJSLArray) // JudySLFreeArray()
    +
    +Given a pointer to a JudySL array (PJSLArray), free the entire array (much faster +than using a JSLN(), JSLD() loop.) +

    +Return Rc_word set to the number of bytes freed and PJSLArray set to NULL. +

    +

    JudySL Search Functions
    +
    +The JudySL search functions allow you to search for indexes in the array. +You may search inclusively or exclusively, +in either forward or reverse directions. +

    +If successful, +Index is returned set to the found index, and +PValue is returned set to a pointer to Index's Value. +If unsuccessful, +PValue is returned set to NULL, +and Index contains no useful information. +PValue must be tested for non-NULL prior +to using Index, +since a search failure is possible. +

    +Note: +To accomodate all possible returns, the Index buffer must be +at least as large +as the largest string stored in the array. +

    +

    JSLF(PValue, PJSLArray, Index) // JudySLFirst()
    +
    +Search (inclusive) for the first index present that is equal to or greater than the +passed Index string. +(Start with a null string to find the first index in the array.) +JSLF() is typically used to begin a sorted-order scan of +the valid indexes in a JudySL array. +
    +uint8_t Index[MAXLINELEN];
    +strcpy (Index, "");
    +JSLF(PValue, PJSLArray, Index);
    +
    +

    +

    JSLN(PValue, PJSLArray, Index) // JudySLNext()
    +
    +Search (exclusive) for the next index present that is greater than the passed +Index string. +JSLN() is typically used to continue a sorted-order scan of +the valid indexes in a JudySL array, or to locate a "neighbor" of a given +index. +

    +

    JSLL(PValue, PJSLArray, Index) // JudySLLast()
    +
    +Search (inclusive) for the last index present that is equal to or less +than the passed Index string. +(Start with a maximum-valued string to look up the last index in the array, +such as a max-length string of 0xff bytes.) +JSLL() is typically used to begin a reverse-sorted-order +scan of the valid indexes in a JudySL array. +

    +

    JSLP(PValue, PJSLArray, Index) // JudySLPrev()
    +
    +Search (exclusive) for the previous index present that is less than the +passed Index string. +JSLP() is typically used to continue a reverse-sorted-order +scan of the valid indexes in a JudySL array, or to locate a "neighbor" of +a given index. + +

    +

    ERRORS: See: Judy_3.htm#ERRORS
    +
    + +

    +

    EXAMPLE of a string sort routine
    +

    +#include <stdio.h>
    +#include <Judy.h>
    +
    +#define MAXLINE 1000000                 // max string (line) length
    +
    +uint8_t   Index[MAXLINE];               // string to insert
    +
    +int     // Usage:  JudySort < file_to_sort
    +main()
    +{
    +    Pvoid_t   PJArray = (PWord_t)NULL;  // Judy array.
    +    PWord_t   PValue;                   // Judy array element.
    +    Word_t    Bytes;                    // size of JudySL array.
    +
    +    while (fgets(Index, MAXLINE, stdin) != (char *)NULL)
    +    {
    +        JSLI(PValue, PJArray, Index);   // store string into array
    +        if (PValue == PJERR)            // if out of memory?
    +        {                               // so do something
    +            printf("Malloc failed -- get more ram\n");
    +            exit(1);
    +        }
    +        ++(*PValue);                    // count instances of string
    +    }
    +    Index[0] = '\0';                    // start with smallest string.
    +    JSLF(PValue, PJArray, Index);       // get first string
    +    while (PValue != NULL)
    +    {
    +        while ((*PValue)--)             // print duplicates
    +            printf("%s", Index);
    +        JSLN(PValue, PJArray, Index);   // get next string
    +    }
    +    JSLFA(Bytes, PJArray);              // free array
    +
    +    fprintf(stderr, "The JudySL array used %lu bytes of memory\n", Bytes);
    +    return (0);
    +}
    +
    + +

    +

    AUTHOR
    +
    +Judy was invented by Doug Baskins and implemented by Hewlett-Packard. + +

    +

    SEE ALSO
    +
    +Judy(3), +Judy1(3), +JudyL(3), +JudyHS(3), +
    +malloc(), +
    +the Judy website, + +http://judy.sourceforge.net, +for further information and Application Notes. +
    + + diff --git a/feeds/p4/libjudy/src/doc/ext/JudySL_funcs_3.htm b/feeds/p4/libjudy/src/doc/ext/JudySL_funcs_3.htm new file mode 100644 index 000000000..e4045bdda --- /dev/null +++ b/feeds/p4/libjudy/src/doc/ext/JudySL_funcs_3.htm @@ -0,0 +1,186 @@ + + + +JudySL_funcs(3) + + + + + + +
    JudySL_funcs(3) JudySL_funcs(3)
    +

    +

    + +
    NAME
    +
    +JudySL functions - +C library for creating and accessing a dynamic array, using +a null-terminated string as an index (associative array) + +

    +

    SYNOPSIS
    +
    +
    +
    +PPvoid_t JudySLIns(      PPvoid_t PPJSLArray, const uint8_t * Index, PJError_t PJError);
    +int      JudySLDel(      PPvoid_t PPJSLArray, const uint8_t * Index, PJError_t PJError);
    +PPvoid_t JudySLGet(      Pcvoid_t  PJSLArray, const uint8_t * Index, PJError_t PJError);
    +Word_t   JudySLFreeArray(PPvoid_t PPJSLArray, PJError_t PJError);
    +PPvoid_t JudySLFirst(    Pcvoid_t  PJSLArray,       uint8_t * Index, PJError_t PJError);
    +PPvoid_t JudySLNext(     Pcvoid_t  PJSLArray,       uint8_t * Index, PJError_t PJError);
    +PPvoid_t JudySLLast(     Pcvoid_t  PJSLArray,       uint8_t * Index, PJError_t PJError);
    +PPvoid_t JudySLPrev(     Pcvoid_t  PJSLArray,       uint8_t * Index, PJError_t PJError);
    +
    + +

    +

    DESCRIPTION
    +
    +A macro equivalent exists for each function call. +Because the macro forms are sometimes faster and have a simpler error +handling interface than the equivalent functions, +they are the preferred way of calling the JudySL functions. +See JudySL(3) +for more information. +The function call definitions are included here for completeness. +

    +One of the difficulties in using the JudySL function calls lies in +determining whether to pass a pointer or the address of a pointer. +Since the functions that modify the JudySL array must also modify the +pointer to the JudySL array, you must pass the address of the pointer +rather than the pointer itself. +This often leads to hard-to-debug programmatic errors. +In practice, the macros allow the compiler to catch programming +errors when pointers instead of addresses of pointers are passed. +

    +The JudySL function calls have an additional parameter beyond +those specified in the macro calls. This parameter is either a +pointer to an error structure, or NULL (in which case the +detailed error information is not returned). +

    +In the following descriptions, the functions are described in +terms of how the macros use them (only in the case of +#define JUDYERROR_NOTEST 1). This is the suggested use +of the macros after your program has been fully debugged. +When the JUDYERROR_NOTEST macro is not specified, +an error structure is declared to store error information +returned from the JudySL functions when an error occurs. +

    +Notice the placement of the & in the different functions. +

    +

    +
    JudySLIns(&PJSLArray, Index, &JError)
    +
    +
    +#define JSLI(PValue, PJSLArray, Index) \
    +   PValue = JudyLIns(&PJSLArray, Index, PJE0)
    +
    +
    +

    +

    JudySLDel(&PJSLArray, Index, &JError)
    +
    +
    +#define JSLD(Rc_int, PJSLArray, Index) \
    +   Rc_int = JudySLDel(&PJSLArray, Index, PJE0)
    +
    +
    +

    +

    JudySLGet(PJSLArray, Index, &JError)
    +
    +
    +#define JSLG(PValue, PJSLArray, Index) \
    +   PValue = JudySLIns(PJSLArray, Index, PJE0)
    +
    +
    +

    +

    JudySLFreeArray(&PJSLArray, &JError)
    +
    +
    +#define JSLFA(Rc_word, PJSLArray) \
    +   Rc_word = JudySLFreeArray(&PJSLArray, PJE0)
    +
    +
    +

    +

    JudySLFirst(PJSLArray, Index, &JError)
    +
    +
    +#define JSLF(PValue, PJSLArray, Index) \
    +   PValue = JudySLFirst(PJSLArray, Index, PJE0)
    +
    +
    +

    +

    JudySLNext(PJSLArray, Index, &JError)
    +
    +
    +#define JSLN(PValue, PJSLArray, Index) \
    +   PValue = JudySLNext(PJSLArray, Index, PJE0)
    +
    +
    +

    +

    JudySLLast(PJSLArray, Index, &JError)
    +
    +
    +#define JSLL(PValue, PJSLArray, Index) \
    +   PValue = JudySLLast(PJSLArray, Index, PJE0)
    +
    +
    +

    +

    JudySLPrev(PJSLArray, Index, &JError)
    +
    +
    +#define JSLP(PValue, PJSLArray, Index) \
    +   PValue = JudySLPrev(PJSLArray, Index, PJE0)
    +
    +
    +
    +

    +Definitions for all the Judy functions, the types +Pvoid_t, +Pcvoid_t, +PPvoid_t, +Word_t , +JError_t, +and +PJError_t, +the constants +NULL, +JU_ERRNO_*, +JERR, +PPJERR, +and +PJE0 +are provided in the Judy.h header file +(/usr/include/Judy.h). +Note: Callers should define JudySL arrays as type Pvoid_t, +which can be passed by value to functions that take +Pcvoid_t (constant Pvoid_t), +and also by address to functions that take PPvoid_t. +

    +The return type from most JudySL functions is PPvoid_t so +that the values stored in the array can be pointers to other objects, +which is a typical usage, or cast to a Word_t * when a pointer +to a value is required instead of a pointer to a pointer. + +

    +

    AUTHOR
    +
    +Judy was invented by Doug Baskins and implemented by Hewlett-Packard. + +

    +

    SEE ALSO
    +
    +Judy(3), +Judy1(3), +JudyL(3), +JudySL(3), +JudyHS(3), +
    +malloc(), +
    +the Judy website, + +http://judy.sourceforge.net, +for more information and Application Notes. +
    + + diff --git a/feeds/p4/libjudy/src/doc/ext/Judy_3.htm b/feeds/p4/libjudy/src/doc/ext/Judy_3.htm new file mode 100644 index 000000000..1531a1a09 --- /dev/null +++ b/feeds/p4/libjudy/src/doc/ext/Judy_3.htm @@ -0,0 +1,283 @@ + + + +Judy(3) + + + + + + +
    Judy(3) Judy(3)
    +

    + +

    NAME
    +
    +Judy arrays - +C library functions for creating and accessing dynamic arrays +
    + +

    +

    SYNOPSIS
    +
    +
    +Judy1  - maps an Index (word) to a bit
    +JudyL  - maps an Index (word) to a Value (word/pointer)
    +JudySL - maps an Index (null terminated string) to a Value
    +JudyHS - maps an Index (array-of-bytes) of Length to a Value
    +
    + +

    +

    DESCRIPTION
    +
    +The Judy family of functions supports fully dynamic arrays. These +arrays may be indexed by a 32- or 64-bit word (depending on processor +word size), a null terminated string or an array-of-bytes plus length. +A dynamic array (sparsely populated) can also be thought of as a +mapping function or associative memory. +

    +A Word_t is a typedef unsigned long int in Judy.h +and must be the same size as sizeof(void *) I.E. a pointer. +

    +Judy1 functions: Index is a +Word_t and Value is just a bit or simply +a flag that Index is present or missing from the array. +This can be thought of as a huge bitmap. +

    +JudyL functions: Index is a +Word_t and Value is a Word_t. This makes +JudyL a pure word-to-word/pointer mapper. JudySL and +JudyHL are based on this property of JudyL. +

    +JudySL functions: Index is a +null-terminated string and Value is a Word_t. +

    +JudyHS functions: Index is an +array-of-bytes of length: Length. Value is a +Word_t. This new addition (May 2004) to Judy is a hybird using +the best features of hashing and Judy methods. The author believes +JudyHS is a good replacement for a hashing method when resizing +the hash table is done during population growth. A correctly tuned hash +method with a static hash table size and population is unbeatable +for speed. However, JudyHS will perform better than a hashing +method with smaller and larger populations than the optimum hash table +size. JudyHS does not have a degenerate performance case where +knowledge of the hash algorithm can be exploited. (I.E. JudyHS does +not use a linked list to handle hash collisions, it uses a tree of +JudyL arrays and a virtual hash table size of 4 billion). +

    +Judy arrays are both speed- and memory-efficient, with no +tuning or configuration required, across a wide range of index set types +(sequential, periodic, clustered, random). Judy's speed and memory +usage are typically better than other data storage models such as +skiplists, linked lists, binary, ternary, b-trees, or even hashing, and +improves with very large data sets. +

    +A Judy array is created merely by defining a null pointer and then +storing (inserting) the first element into the array under that pointer. +The memory used by a Judy array is nearly proportional to the population +(number of elements). +

    +Judy has two Application Program Interfaces (APIs): a C macro +interface, and a function call interface. Because the macro forms are +sometimes faster and have a simpler error handling interface than the +equivalent functions, they are the preferred way of using the Judy +functions. +

    +Since an initial (empty) Judy array is represented by a null pointer, it +is possible to construct an array of Judy arrays. In other words, a +Judy array's Values (except Judy1) can be pointers to other Judy +arrays. This makes it very simple to construct an array with an +arbitrary number of dimensions or Index sizes. (JudySL and +JudyHS are implemented using JudyL this way). + +

    +

    A 10 MINUTE TECHNICAL DESCRIPTION
    +
    +may be found at +http://judy.sourceforge.net/downloads/10minutes.htm + +

    +

    A 3 HOUR TECHNICAL DESCRIPTION (out of date and a bit corny)
    +
    +may be found at +http://judy.sourceforge.net/application/shop_interm.pdf + +

    +

    + DOWNLOADS
    +
    +Judy source downloads are available at +http://sourceforge.net/projects/judy
    +Binarys may be built and installed in a minute or two +after downloading +

    +For versions including more platforms and/or new features see: +http://judy.sourceforge.net/downloads/ + +

    +

    AUTHOR
    +
    +Judy was invented by Doug Baskins (dougbaskins .AT, yahoo.com) and +implemented by Hewlett-Packard. (Note: Judy is named for the +inventor's sister, after discarding many proposed names.) + +

    +

    + +FILES
    +
    +Locations of interest include: +
    +http://sourceforge.net/projects/judy + -- project downloads
    +file:/usr/share/doc/Judy/ +-- for HTML version of man pages.
    +/usr/share/doc/Judy/demo/ -- demonstration program source files.
    +
    +The author attempted to write interesting application notes using +advanced features of Judy. They may be found at +"http://judy.sourceforge.net/application/ +(Some may be out of date). + +

    +

    ERRORS
    +
    +A lot of thought (and time) went into making error handling in Judy +simple, while maintaining flexibility and capability. Error handling is +a very boring subject even to write about. So read this short section +and use the recommended second method. It generates the fastest code, +uses the least amount of memory and requires you to write extra code +only for insert/deletes functions. Also it is compatible with the other +two methods. This method is for production code that may want to handle +malloc() fails differently than the Judy default. If the Judy +default method of handling malloc() fails are OK, then use the +first method. +

    +There are two (2) categories of Judy error returns, (or for any dynamic ADT): +

    +1) User programming errors (bugs) such as memory corruption or +invalid pointers. +
    +2) Out-of-memory (malloc() failure) with Insert +(Set) or Delete (Unset) when modifying a Judy +array. Not all calls to insert and delete call malloc(), so they +may succeed even when a call to malloc() would fail. +
    +

    +There are roughly three (3) methods of handling errors when using +the macros: +

    +

    +

    1) Default Error Handling Method
    +
    +The default is to print error messages to stderr, for example: +

    +

    +File 'YourCfile.c', line 1234: JudyLIns(), JU_ERRNO_* == 2, ID == 321
    +
    +This indicates that an error occurred in the JudyLIns() function +at line 321. Line 1234 is the line in 'YourCfile.c' where the +JLI() call failed. JU_ERRNO_* == 2 is equal to JU_ERRNO_NOMEM +(as defined in the Judy.h file). The ID number indicates the +source line number in the function where the error originated. Your +program then terminates with an exit(1);. By default, both +categories of Judy error returns are printed this way. (The 'ID == 321' +is for die hards that want more detail or for debugging Judy itself.) +
    +

    +

    2) Disable Macro Error Handling
    +
    +When your program is "bug free", the only errors returned should be +malloc() failures. Therefore all error returns can be treated as +a malloc() failure. By using the below #define, all +error testing and printing is turned off. Additional code needs to be +added to the code that can have malloc() failures. Judy was +designed to leave the same data in the array before the call if a +malloc() fail occurs. (During testing of Judy, we found very few +malloc()/OS's that were bug free after a malloc() failure. +Sometimes it took weeks to discover because most systems go into a +paging frenzy before running out of memory). +
    +#define JUDYERROR_NOTEST 1
    +
    +(in your program code), or +
    +cc -DJUDYERROR_NOTEST sourcefile -lJudy
    +
    +(on your command line). +
    +// This is an example of how to program using method two (2).
    +    
    +JLI(PValue, PLArray, Index);
    +if (PValue == PJERR) goto out_of_memory_handling;
    +...
    +
    +JLD(RC_int, PLArray, Index);
    +if (RC_int == JERR) goto out_of_memory_handling;
    +...
    +
    +J1S(RC_int, P1Array, Index);
    +if (RC_int == JERR) goto out_of_memory_handling;
    +...
    +
    +J1U(RC_int, P1Array, Index);
    +if (RC_int == JERR) goto out_of_memory_handling;
    +...
    +
    +
    +Note: Without 'JUDYERROR_NOTEST' defined, the 'goto +out_of_memory_handling' will never be executed and will be optimized out +by the compiler. The default method will be used -- Macro will print +error information if an error occurs as explained above. +

    +With 'JUDYERROR_NOTEST' defined, the 'goto out_of_memory_handling' will +be executed when an error occurs -- which should only happen when +malloc() fails. +

    3) User-Specified JUDYERROR() Macro Method
    +
    +The JUDYERROR() macro (in Judy.h) provides flexibility for +handling error returns as needed to suit your program while still using +the Judy array macros instead of function calls. You can use a +different JUDYERROR() macro to suit your needs. The following +example is a possible alternative to the default. It is used to +distinguish between the two types of errors (described above), and +explicitly test for the remaining JU_ERRNO_NOMEM errors possible in your +program. +

    +

    +// This is an example of Judy macro API to continue when out of memory 
    +// and print and exit(1) when any other error occurs.
    +
    +#ifndef JUDYERROR_NOTEST
    +#include <stdio.h>  // needed for fprintf()
    +
    +// This is the macro that the Judy macro APIs use for return codes of -1:
    +
    +#define JUDYERROR(CallerFile, CallerLine, JudyFunc, JudyErrno, JudyErrID) \
    +{                                                                         \
    +    if ((JudyErrno) != JU_ERRNO_NOMEM) /* ! a malloc() failure */         \
    +    {                                                                     \
    +        (void) fprintf(stderr, "File '%s', line %d: %s(), "               \
    +            "JU_ERRNO_* == %d, ID == %d\n",                               \
    +            CallerFile, CallerLine,                                       \
    +            JudyFunc, JudyErrno, JudyErrID);                              \
    +        exit(1);                                                          \
    +    }                                                                     \
    +}
    +#endif // JUDYERROR_NOTEST not defined
    +
    +
    +This error handling macro must be included before the #include <Judy.h> +statement in your program. +
    + +

    +

    SEE ALSO
    +
    +Judy1(3), +JudyL(3), +JudySL(3), +JudyHS(3) + + diff --git a/feeds/p4/libjudy/src/doc/ext/LICENSE b/feeds/p4/libjudy/src/doc/ext/LICENSE new file mode 100644 index 000000000..e69de29bb diff --git a/feeds/p4/libjudy/src/doc/ext/README b/feeds/p4/libjudy/src/doc/ext/README new file mode 100644 index 000000000..f0b0946dc --- /dev/null +++ b/feeds/p4/libjudy/src/doc/ext/README @@ -0,0 +1,20 @@ +# @(#) $Revision: 4.11 $ + +Judy_3.htm the Judy(3) overview manual entry in HTML format; + normally placed where a web browser can read it + +Judy1_3.htm describes the Judy1*() macros +Judy1_funcs_3.htm describes the Judy1*() functions +JudyL_3.htm describes the JudyL*() macros +JudyL_funcs_3.htm describes the JudyL*() functions +JudySL_3.htm describes the JudySL*() macros +JudySL_funcs_3.htm describes the JudySL*() functions +JudyHS_3.htm describes the JudyHS*() macros +JudyHS_funcs_3.htm describes the JudyHS*() functions + +# Note: The library package README file comes from the following file, but the +# hierarchy of example sources package README files come from each +# corresponding directory: + +README_deliver packaged with other Judy delivered files, renamed to just + "README" in that context diff --git a/feeds/p4/libjudy/src/doc/ext/README_deliver b/feeds/p4/libjudy/src/doc/ext/README_deliver new file mode 100644 index 000000000..f0b0946dc --- /dev/null +++ b/feeds/p4/libjudy/src/doc/ext/README_deliver @@ -0,0 +1,20 @@ +# @(#) $Revision: 4.11 $ + +Judy_3.htm the Judy(3) overview manual entry in HTML format; + normally placed where a web browser can read it + +Judy1_3.htm describes the Judy1*() macros +Judy1_funcs_3.htm describes the Judy1*() functions +JudyL_3.htm describes the JudyL*() macros +JudyL_funcs_3.htm describes the JudyL*() functions +JudySL_3.htm describes the JudySL*() macros +JudySL_funcs_3.htm describes the JudySL*() functions +JudyHS_3.htm describes the JudyHS*() macros +JudyHS_funcs_3.htm describes the JudyHS*() functions + +# Note: The library package README file comes from the following file, but the +# hierarchy of example sources package README files come from each +# corresponding directory: + +README_deliver packaged with other Judy delivered files, renamed to just + "README" in that context diff --git a/feeds/p4/libjudy/src/doc/int/10minutes.htm b/feeds/p4/libjudy/src/doc/int/10minutes.htm new file mode 100644 index 000000000..7437f850e --- /dev/null +++ b/feeds/p4/libjudy/src/doc/int/10minutes.htm @@ -0,0 +1,190 @@ + + + + + + A 10-MINUTE DESCRIPTION OF HOW JUDY ARRAYS WORK AND WHY THEY ARE SO FAST + +
    +

    + + +A 10-MINUTE DESCRIPTION OF HOW JUDY ARRAYS WORK AND WHY THEY ARE SO FAST

    +

    + + +By Doug Baskins, doug@sourcejudy.com

    +

    + + +October 16, 2001, Revised July 2002

    +

    + + + As the inventor of the Judy algorithm I've been asked repeatedly, "What makes Judy so fast?" The answer is not simple, but finally I can share all of the details. (In June 2002, Judy was opened sourced with a LGPL license and hosted at +http://sourceforge.net/projects/judy + Let's see if I can give you a good understanding in 10 minutes. (The Judy data structures are very well described in another paper, the +Judy Shop Manual +, but it took me about three hours to read!)

    +

    + + + A Judy tree is generally faster than and uses less memory than contemporary forms of trees such as binary (AVL) trees, b-trees, and skip-lists. When used in the "Judy Scalable Hashing" configuration, Judy is generally faster then a hashing method at all populations. (See also +http://www.sourcejudy.com/application/ +Judy_hashing.

    +

    + + + +Expanse +, +population +, and +density + are not commonly used terms in tree search literature, so let's define them here:

    +
      +
    • + + + +Expanse + is a range of possible keys, such as: 256..511
    • +
    • + + + +Population + is the count of keys contained in an expanse, such as, 260, 300, 499, 500 = 4.
    • +
    • + + + +Density + is used to describe the sparseness of an expanse of keys; density = population / expanse. A density of 1.0 means that all possible keys are set or valid in that expanse.
    • +
    +

    + + + +Node + and +branch + are used interchangeably in this document.

    +

    + + + +Key + and +index + are used interchangeably. A Judy tree is thought of as an unbounded Judy array at the API level. The expanse of JudyL or Judy1 arrays are bounded by the expanse of the word (32[64]-bits) used for the index/key. A JudySL array is only bounded by the length of the key string that can be stored in the machine.

    +

    + + +A (CPU) +cache-line fill + is additional time required to do a read reference from RAM when a word is not found in cache. In today's computers the time for a cache-line fill is in the range of 50..2000 machine instructions. Therefore a cache-line fill should be avoided when fewer than 50 instructions can do the same job. (Modern machines tend to pipeline writes to RAM. They often take no additional time in the Judy design.)

    +

    + + +Some of the reasons Judy outperforms binary trees, b-trees, and skip-lists:

    +
      +
    • + + +Judy rarely compromises speed/space performance for simplicity (Judy will never be called simple except at the API).
    • +
    • + + +Judy is designed to avoid cache-line fills wherever possible. (This is the main design criteria for Judy.)
    • +
    • + + +A b-tree requires a search of each node (branch), resulting in more cache-line fills.
    • +
    • + + +A binary-tree has many more levels (about 8X), resulting in more cache-line fills.
    • +
    • + + +A skip-list is roughly equivalent to a degree-4 (4-ary) tree, resulting in more cache-line fills.
    • +
    • + + +An "expanse"-based digital tree (of which Judy is a variation) never needs balancing as it grows.
    • +
    • + + +A portion (8 bits) of the key is used to subdivide an expanse into sub-trees. Only the remainder of the key need exist in the sub-trees, if at all, resulting in key compression.
    • +
    +

    + + +The Achilles heel of a simple digital tree is very poor memory utilization, especially when the N in N-ary (the degree or fanout of each branch) increases. The Judy tree design was able to solve this problem. In fact a Judy tree is more memory-efficient than almost any other competitive structure (including a simple linked list). A highly populated linear array[] is the notable exception.

    +

    + + +From a speed point of view Judy is chiefly a 256-ary digital tree or trie (per D. Knuth Volume 3 definitions). A degree of 256-ary is a somewhat "magic" N-ary for a variety of reasons -- mostly because a byte (the least addressable memory unit) is 8 bits. Also a higher degree means reduced cache-line fills per access. You see the theme here -- avoid cache-line fills like the plague.

    +

    + + +It is interesting to note that an early version of Judy used branch widening (sometimes called a level-compressed trie). Branch widening opportunities occur primarily in the upper level(s) of the tree. Since a tree is a hierarchy, the upper branches are likely to be in cache, thus branch widening did not significantly reduce the number of actual cache-line fills. Branch widening was removed in later versions of Judy. (However, Judy was also tuned to use as few instructions as possible when an access was likely to be in the cache.)

    +

    + + +The presence of a CPU cache in modern machines has changed many of the ways to write a performance algorithm. To take advantage of a cache, it is important to leverage as much as possible. In a Judy tree, the presence of a cache results in 1..3 (or more) fewer cache-line fills per access than would be possible without a cache.

    +

    + + + As a digression, note that a hash method loses the advantages of a cache as the size of the hash table approaches or exceeds the size of the cache. With very large hash tables, the cache is no help at all. Also, hash methods often use a linked list to handle collisions (synonyms) and typically use a slow hash algorithm (greater than 50ns) or suffer from numerous collisions. "Judy Scalable Hashing" is an effective replacement for common hash methods when very high performance is required for small in-cache data sets. (See also +http://www.sourcejudy.com/application/ + Judy_hashing.

    +

    + + + With an expanse of 2^32 (or 256^4), a maximum of 4 cache-line fills would be required for a worst-case highly populated 256-ary digital tree access. In an expanse of 2^64 (or 256^8), 8 cache-line fills would be the worst case. In practice, Judy does much better than this. The reason is (in part) due to the fact "density" of the keys is seldom the lowest possible number in a "majority" of the sub-expanses. It takes high density combined with high population to increase the depth of a Judy tree. It would take a long time to explain why. The short version is an analogy with sand. It takes a lot of sand to build a tall sand pile, especially if it takes 256 grains to support 1 grain above it. In a 64-bit Judy, it would probably require more RAM than exists on this planet to get it to have 8 levels. A binary tree reaches 8 levels with a population of 256. It is truly remarkable to me how much research has been done on binary trees and still being taught.

    +

    + + + Judy adapts efficiently to a wide range of populations and data set densities. Since the Judy data structure is a tree of trees, each sub-tree is a static expanse that is optimized to match the "character" or density of the keys it contains. To support this flexibility, in 32[64]-bit Judy there are approximately 25[85] major data structures and a similar number of minor structures. I am going to only describe a few of them so you can infer how density is synergistic with compression.

    +

    + + +From a memory consumption (size) point of view, a Judy tree shares (does not duplicate) common digits of a key in a tree. This form of key compression is a natural outcome from using a digital tree. This would be very awkward to do in trees balanced by population and, as far as I know, has never been done. Each pointer traversed in a Judy tree points to ever smaller sub-expanses, while decoding another 8 bits of the key. (In a pure digital tree, the keys are not stored in the tree, they are inferred by position.)

    +

    + + + Now let me try to describe the top of a small Judy (JudyL) tree and the bottom of a highly populated Judy1 tree. A Judy tree with a population of zero is simply a NULL pointer. A JudyL tree with a population of one key is a root pointer to a 2-word object containing a key and and associated value. +A JudyL tree with a population of 2 keys, is 4-word object with 2 values and 2 sorted keys. A tree with a population of 3 keys, is an 8-word object with a count word + 3 values and 3 sorted keys.

    +

    + + +This continues until the population grows to 32 keys. At this point an actual tree structure is formed with a "compressed" 256-ary node (branch) that decodes the first byte of each key. The value 32 was chosen because this is where a tree structure requires an equivalent number of cache-line fills. All objects below this top branch contain keys that are shortened by at least the first byte.

    +

    + + +There are three kinds of branches. Two are 1-cache-line fill objects to traverse, and one is a 2-cache-line fill object to traverse. In every path down the tree and at all populations, a maximum of one of the 2-cache-line fill branches is used. This means it is sometimes possible to have 1 additional (the branch design often subtracts 1) cache-line fill than you would expect from a pure 256-ary branch traversal in an otherwise complete Judy tree.

    +

    + + +On the other extreme, a highly populated Judy1 tree where the key has been decoded down to 1 byte, and the density of a 256-wide sub-expanse of keys grows to greater than 0.094 (25 keys / 256 expanse), a bitmap of 32 bytes (256 bits) is formed from an existing sorted array of 24 1-byte keys. (I am leaving out the handling of the values.) This results in a key using about an average of 1.3 (32/25) bytes of memory (up from 1.0). Note that increasing the density (population) at this point does NOT require more memory for keys. For example, when the density reaches 0.5 (population = 128 / expanse = 256), the memory consumed is about 2 bits ((32/128)*8) per key + some overhead (2.0+ words) for the tree structure.

    +

    + + +Notice that to insert or delete a key is almost as simple as setting or clearing a bit. Also notice, the memory consumption is almost the same for both 32- and 64-bit Judy trees. Given the same set of keys, both 32- and 64-bit Judy trees have remarkably similar key-memory, depth, and performance. However, the memory consumption for 64-bit Judy is higher because the pointers and values (JudyL) are double the size.

    +

    + + +In this short writeup it wasn't possible to describe all the data structure details such as: Root, JPM, narrow and rich pointers, linear, bitmap and uncompressed branches, value areas, immediate indexes, terminal nodes (leafs), least compressed form, memory management, fast leaf searches and counting trees.

    +

    + + + Well I cannot describe Judy in 10 minutes -- what possessed me? I hope you understand some of what I have said and question me on the rest -- particularly those doubts. I will try to elaborate on parts where I get questions. +

    + Doug Baskins +
    +doug@sourcejudy.com

    +
    + + diff --git a/feeds/p4/libjudy/src/examples/Judy1Dup.c b/feeds/p4/libjudy/src/examples/Judy1Dup.c new file mode 100644 index 000000000..75733e031 --- /dev/null +++ b/feeds/p4/libjudy/src/examples/Judy1Dup.c @@ -0,0 +1,47 @@ +/* @(#) $Revision: 4.2 $ $Source: /judy/src/funcs/Judy1Dup.c $ */ + +#include "Judy.h" + +/******************************************************************* + * Name: Judy1Dup + * + * Description: + * Clone (duplicate) a Judy Array. + * + * Parameters: + * PPvoid_t PPDest (OUT) + * Pointer to a new Judy array with the same + * index/value pairs as PSource. + * Any initial value pointed to by PPDest is ignored. + * + * Pvoid_t PSource (IN) + * Ptr to source Judy array being duplicated. + * If PSource is NULL, TRUE is returned since this + * is simply a valid Null Judy array. + * + * JError_t *PJError (OUT) + * Judy error structure pointer. + * + * Returns: + * JERR - error, see PJError + * !JERR - success + */ + +int +Judy1Dup(PPvoid_t PPDest, Pvoid_t PSource, JError_t * PJError) +{ + Pvoid_t newJArray = 0; // new Judy1 array to ppopulate + Word_t kindex; // Key/index + int Ins_rv = 0; // Insert return value + + for (kindex = 0L, Ins_rv = Judy1First(PSource, &kindex, PJError); + Ins_rv == 1; Ins_rv = Judy1Next(PSource, &kindex, PJError)) + { + Ins_rv = Judy1Set(&newJArray, kindex, PJError); + } + if (Ins_rv == JERR) + return Ins_rv; + + *PPDest = newJArray; + return Ins_rv; +} /* Judy1Dup */ diff --git a/feeds/p4/libjudy/src/examples/Judy1Dup.h b/feeds/p4/libjudy/src/examples/Judy1Dup.h new file mode 100644 index 000000000..36d3e83e0 --- /dev/null +++ b/feeds/p4/libjudy/src/examples/Judy1Dup.h @@ -0,0 +1,31 @@ +/* @(#) $Revision: 4.2 $ $Source: /judy/src/funcs/Judy1Dup.H $ */ + +#include + +/* ****************************************************************** + * Name: Judy1Dup + * + * Description: + * Clone (duplicate) a Judy Array. + * + * Parameters: + * PPvoid_t PPDest (OUT) + * Pointer to a new Judy array with the same + * index/value pairs as PSource. + * Any initial value pointed to by PPDest is ignored. + * + * Pvoid_t PSource (IN) + * Ptr to source Judy array being duplicated. + * If PSource is NULL, TRUE is returned since this + * is simply a valid Null Judy array. + * + * JError_t *PJError (OUT) + * Judy error structure pointer. + * + * Returns: + * JERR - error, see PJError + * !JERR - success + */ + +int +Judy1Dup(PPvoid_t PPDest, Pvoid_t PSource, JError_t * PJError); diff --git a/feeds/p4/libjudy/src/examples/Judy1DupCheck.c b/feeds/p4/libjudy/src/examples/Judy1DupCheck.c new file mode 100644 index 000000000..f98d57ceb --- /dev/null +++ b/feeds/p4/libjudy/src/examples/Judy1DupCheck.c @@ -0,0 +1,80 @@ + +/* + * @(#) $Revision: 4.3 $ $Source: /judy/src/funcs/Judy1DupCheck.c $ + * + * Judy1DupCheck.c + * + * Test Judy1Dup.c + */ + +#include +#include +#include "Judy1Dup.h" + +#define LARRAYSIZE(array) sizeof(array)/sizeof(Word_t) + +// fcn to init a Judy array with an array of ulong's +Pvoid_t +ularray2Judy(Word_t *ularray, Word_t ularray_size) +{ + Word_t i; + Pvoid_t PJArray = 0; + JError_t JError; + + for (i = 0L; i < ularray_size; i++) + { + if (Judy1Set(&PJArray, ularray[i], &JError) == JERR) + { + printf("ularray2Judy: Judy1Set failure, error %d\n", + JU_ERRNO(&JError)); + exit(2); + } + } + return PJArray; +} /* ularray2Judy */ + +int +main() +{ + static Word_t knowns[] = { 0, 1, 1024, 4095, 4096, 4097, 4098, 123456 }; + int i; + Pvoid_t PJArray = 0; + Pvoid_t PJArrayNew = 0; + Word_t Index; + int Judy_rv; // Judy Return value + JError_t JError; + + // populate a judy array with known values + PJArray = ularray2Judy(knowns, LARRAYSIZE(knowns)); + + printf("Testing Judy1Dup ..."); + + // dup the judy array + if ((Judy1Dup(&PJArrayNew, PJArray, &JError)) == JERR) + { + printf("Judy1Dup failed: error %d\n", JU_ERRNO(&JError)); + return (2); + } + + // compare the duped array with known values + for (i = 0, Index = 0L, Judy_rv = Judy1First(PJArrayNew, &Index, &JError); + Judy_rv == 1; i++, Judy_rv = Judy1Next(PJArrayNew, &Index, &JError)) + { + if (Index != knowns[i]) + { + printf("Judy1DupCheck Failed: Judy1Dup does not match original\n"); + return (2); + } + } + + if (i != LARRAYSIZE(knowns)) + { + printf + ("Judy1DupCheck Failed: Judy1Dup does not match original (too short)\n"); + exit(2); + } + else + printf("Ok\n"); + + return (0); +} diff --git a/feeds/p4/libjudy/src/examples/Judy1Op.c b/feeds/p4/libjudy/src/examples/Judy1Op.c new file mode 100644 index 000000000..3bd541b43 --- /dev/null +++ b/feeds/p4/libjudy/src/examples/Judy1Op.c @@ -0,0 +1,150 @@ + +/* + * @(#) $Revision: 4.2 $ $Source: /judy/src/funcs/Judy1Op.c $ + * + * Judy1 set operations. + * + * The name of this function, "Judy1Op", was carefully chosen from + * a list of alternatives: + * + * Judy1Op() - It's hard to see that O is a letter and not a zero. + * Judy1Set() - Sounds like you are setting a bit. + * Judy1BS() - BS for Bit Set functions. + * Judy1SO() - SO for Set Operations + * Judy1AndIDontGiveADarn() - too long but goes with + * Judy1WhoseOnFirst() - now called Judy1First() and + * Judy1WhatsOnSecond() - now called Judy1Next() + * + * But Judy1SetOp() would conflict with Judy1Set() if we rename Judy1Set(), so + * Judy1Op() it is. + */ + +#include "Judy.h" +#include "Judy1Op.h" + +/******************************************************************* + * Name: Judy1Op + * + * Description: + * Logical set operations on Judy1 arrays. + * + * All of these operations can be done on an unbounded array because + * the dreaded "NOT" is avoided. The "NOT"'s can be implemented + * when Judy1 supports them. + * + * Parameters: + * PPvoid_t PPDest (OUT) + * Ptr to the Judy destination array. + * Any initial value pointed to by PPDest is ignored. + * + * Pvoid_t PSet1 (IN) + * First Judy1 set. + * This will be NULL for an empty Judy1 array. + * + * Pvoid_t PSet2 (IN) + * Second Judy1 set. + * This will be NULL for an empty Judy1 array. + * + * Word_t Operation (IN) + * Operation to be performed (ie. PSet1 {Operation} PSet2) + * Valid Operation values are: + * + * JUDY1OP_AND - intersection of two sets + * JUDY1OP_OR - union of two sets + * JUDY1OP_ANDNOT - set1 with set2 removed + * + * JError_t * PJError (OUT) + * Judy Error struct used to return Judy error. + * + * Returns: + * !JERR if successful + * JERR if an error occurs + * If the error is a caller error (invalid Operation or no PPDest) + * then the PJError error code will be JU_ERRNO_NONE. + */ +int +Judy1Op(PPvoid_t PPDest, Pvoid_t PSet1, Pvoid_t PSet2, + Word_t Operation, JError_t * PJError) +{ + Pvoid_t PnewJArray = 0; // empty Judy array + Word_t Index1 = 0L; + Word_t Index2 = 0L; + int Judy_rv; + + if (!PPDest) + return JERR; + + switch (Operation) + { + case JUDY1OP_AND: + // step through each array looking for index matches + Judy_rv = Judy1First(PSet1, &Index1, PJError); + Judy_rv += Judy1First(PSet2, &Index2, PJError); + while (Judy_rv == 2) + { + if (Index1 < Index2) + { + Index1 = Index2; + Judy_rv = Judy1First(PSet1, &Index1, PJError); + } + else if (Index1 > Index2) + { + Index2 = Index1; + Judy_rv = Judy1First(PSet2, &Index2, PJError); + } + else + { + // do the AND + Judy_rv = Judy1Set(&PnewJArray, Index1, PJError); + if (Judy_rv == JERR) + return JERR; + + // bump to the next bits + Judy_rv = Judy1Next(PSet1, &Index1, PJError); + Judy_rv += Judy1Next(PSet2, &Index2, PJError); + } + } + *PPDest = PnewJArray; + break; + + case JUDY1OP_OR: + /* Set all the bits from PSet1 */ + for (Index1 = 0L, Judy_rv = Judy1First(PSet1, &Index1, PJError); + Judy_rv == 1; Judy_rv = Judy1Next(PSet1, &Index1, PJError)) + { + if (Judy1Set(&PnewJArray, Index1, PJError) == JERR) + return JERR; + } + + /* Set all the bits from PSet2 */ + for (Index1 = 0L, Judy_rv = Judy1First(PSet2, &Index1, PJError); + Judy_rv == 1; Judy_rv = Judy1Next(PSet2, &Index1, PJError)) + { + if (Judy1Set(&PnewJArray, Index1, PJError) == JERR) + return JERR; + } + *PPDest = PnewJArray; + break; + + case JUDY1OP_ANDNOT: + // PSet1 with PSet2 removed + // 0010 = PSet1(1010) ANDNOT PSet2(1100) + + for (Index1 = 0L, Judy_rv = Judy1First(PSet1, &Index1, PJError); + Judy_rv == 1; Judy_rv = Judy1Next(PSet1, &Index1, PJError)) + { + // if bit doesn't exist in PSet2, then add to result + if (0 == Judy1Test(PSet2, Index1, PJError)) + { + if (Judy1Set(&PnewJArray, Index1, PJError) == JERR) + return JERR; + } + } + *PPDest = PnewJArray; + break; + + default: + return JERR; + } + return !JERR; +} /* Judy1Op */ diff --git a/feeds/p4/libjudy/src/examples/Judy1Op.h b/feeds/p4/libjudy/src/examples/Judy1Op.h new file mode 100644 index 000000000..207a5fd55 --- /dev/null +++ b/feeds/p4/libjudy/src/examples/Judy1Op.h @@ -0,0 +1,15 @@ +#ifndef _JUDY1OP_INCLUDED +#define _JUDY1OP_INCLUDED + +// @(#) $Revision: 4.1 $ $Source: /judy/src/funcs/Judy1Op.h $ +// +// HEADER FILE FOR EXPORTED FEATURES FROM Judy1Op(). + +#define JUDY1OP_AND 1L +#define JUDY1OP_OR 2L +#define JUDY1OP_ANDNOT 3L + +extern int Judy1Op(PPvoid_t PPDest, Pvoid_t PSet1, Pvoid_t PSet2, + Word_t Operation, JError_t * PJError); + +#endif // ! _JUDY1OP_INCLUDED diff --git a/feeds/p4/libjudy/src/examples/Judy1OpCheck.c b/feeds/p4/libjudy/src/examples/Judy1OpCheck.c new file mode 100644 index 000000000..b138718a6 --- /dev/null +++ b/feeds/p4/libjudy/src/examples/Judy1OpCheck.c @@ -0,0 +1,150 @@ +// @(#) $Revision: 4.3 $ $Source: /judy/src/funcs/Judy1OpCheck.c $ + +/* + * Judy1OpCheck.c + * + * Test Judy1Op.c + * + * Returns 0 if successful, -1 if test fails. + */ + +#include +#include +#include "Judy.h" +#include "Judy1Op.h" + +#define LARRAYSIZE(array) sizeof(array)/sizeof(Word_t) + +static Word_t set1[] = { 0L, + 5L, + 6L, + 7L, + 1024L, + 11111L, + 65534L, + 65535L, + 65536L, + 555555L, + ULONG_MAX +}; + +static Word_t set2[] = { 7L, + 9L, + 1023L, + 12345L, + 65535L, + ULONG_MAX +}; + +static Word_t resultAND[] = { 7L, + 65535L, + ULONG_MAX +}; + +static Word_t resultOR[] = { 0L, + 5L, + 6L, + 7L, + 9L, + 1023L, + 1024L, + 11111L, + 12345L, + 65534L, + 65535L, + 65536L, + 555555L, + ULONG_MAX +}; + +static Word_t result1ANDNOT2[] = { 0L, + 5L, + 6L, + 1024L, + 11111L, + 65534L, + 65536L, + 555555L +}; + +static Word_t result2ANDNOT1[] = { 9L, + 1023L, + 12345L +}; + +// fcn to init a Judy array with an array of ulong's +void * +ularray2Judy(Word_t *ularray, Word_t ularray_size) +{ + Word_t i; + void *PJArray = 0; + JError_t JError; + + for (i = 0L; i < ularray_size; i++) + { + if (Judy1Set(&PJArray, ularray[i], &JError) == JERR) + { + printf("ularray2Judy: Judy1Set failure, error %d\n", + JU_ERRNO(&JError)); + exit(2); + } + } + return PJArray; +} /* ularray2Judy */ + +// fcn to test Judy1Op and check the results +void +testandcheck(void *PJSet1, void *PJSet2, Word_t operation, + char *opstr, Word_t *result, int result_size) +{ + void *PJArrayNew; + Word_t Index; + int i; + int judy_rv = 0; + JError_t JError; + + printf("Testing Judy1Op(%s) ...", opstr); + if (Judy1Op(&PJArrayNew, PJSet1, PJSet2, operation, &JError) == JERR) + printf(" failed, error %d\n", JU_ERRNO(&JError)); + else + { // check results + for (i = 0, Index = 0L, judy_rv = + Judy1First(PJArrayNew, &Index, &JError); judy_rv == 1; + i++, judy_rv = Judy1Next(PJArrayNew, &Index, &JError)) + { + if ((i >= result_size) || (Index != result[i])) + { + printf("Failed\n"); + return; + } + } + if (i > result_size) + printf("Failed\n"); + else + printf("Ok\n"); + } + return; +} + +int +main() +{ + void *PJSet1 = 0; + void *PJSet2 = 0; + + // Test Judy1Op + // init PJSet1 and PJSet2 + PJSet1 = ularray2Judy(set1, LARRAYSIZE(set1)); + PJSet2 = ularray2Judy(set2, LARRAYSIZE(set2)); + + testandcheck(PJSet1, PJSet2, JUDY1OP_AND, "AND", + resultAND, LARRAYSIZE(resultAND)); + testandcheck(PJSet1, PJSet2, JUDY1OP_OR, "OR", + resultOR, LARRAYSIZE(resultOR)); + testandcheck(PJSet1, PJSet2, JUDY1OP_ANDNOT, "1ANDNOT2", + result1ANDNOT2, LARRAYSIZE(result1ANDNOT2)); + testandcheck(PJSet2, PJSet1, JUDY1OP_ANDNOT, "2ANDNOT1", + result2ANDNOT1, LARRAYSIZE(result2ANDNOT1)); + + return (0); +} diff --git a/feeds/p4/libjudy/src/examples/Makefile b/feeds/p4/libjudy/src/examples/Makefile new file mode 100644 index 000000000..a85c98c0a --- /dev/null +++ b/feeds/p4/libjudy/src/examples/Makefile @@ -0,0 +1,13 @@ +CCFLAGS += -ggdb +LIBS = -lJudy + +all: Judy1DupCheck Judy1OpCheck + +Judy1DupCheck: Judy1Dup.c Judy1DupCheck.c + $(CC) $(CCFLAGS) -o $@ $^ $(LIBS) + +Judy1OpCheck: Judy1Op.c Judy1OpCheck.c + $(CC) $(CCFLAGS) -o $@ $^ $(LIBS) + +clean: + rm -f Judy1DupCheck Judy1OpCheck *.o diff --git a/feeds/p4/libjudy/src/examples/README b/feeds/p4/libjudy/src/examples/README new file mode 100644 index 000000000..6e440b699 --- /dev/null +++ b/feeds/p4/libjudy/src/examples/README @@ -0,0 +1,8 @@ +This directory contains example programs that show some of the many ways Judy +can be utilized, in other words it contains useful applications of Judy. + +Judy1Dup: Clone (duplicate) a Judy Array. + +Judy1Op: Support Logical "set" operations on Judy1 arrays. + +See the source code for more information. diff --git a/feeds/p4/libjudy/src/src/Judy.h b/feeds/p4/libjudy/src/src/Judy.h new file mode 100644 index 000000000..adfb5b53b --- /dev/null +++ b/feeds/p4/libjudy/src/src/Judy.h @@ -0,0 +1,622 @@ +#ifndef _JUDY_INCLUDED +#define _JUDY_INCLUDED +// _________________ +// +// Copyright (C) 2000 - 2002 Hewlett-Packard Company +// +// This program is free software; you can redistribute it and/or modify it +// under the term of the GNU Lesser 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 Lesser General Public License +// for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// _________________ + +// @(#) $Revision: 4.52 $ $Source: /judy/src/Judy.h $ +// +// HEADER FILE FOR EXPORTED FEATURES IN JUDY LIBRARY, libJudy.* +// +// See the manual entries for details. +// +// Note: This header file uses old-style comments on #-directive lines and +// avoids "()" on macro names in comments for compatibility with older cc -Aa +// and some tools on some platforms. + + +// PLATFORM-SPECIFIC + +#ifdef JU_WIN /* =============================================== */ + +typedef __int8 int8_t; +typedef __int16 int16_t; +typedef __int32 int32_t; +typedef __int64 int64_t; + +typedef unsigned __int8 uint8_t; +typedef unsigned __int16 uint16_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int64 uint64_t; + +#else /* ================ ! JU_WIN ============================= */ + +// ISO C99: 7.8 Format conversion of integer types +#include /* if this FAILS, try #include */ + +// ISO C99: 7.18 Integer types uint*_t +//#include + +#endif /* ================ ! JU_WIN ============================= */ + +// ISO C99 Standard: 7.20 General utilities +#include + +// ISO C99 Standard: 7.10/5.2.4.2.1 Sizes of integer types +#include + +#ifdef __cplusplus /* support use by C++ code */ +extern "C" { +#endif + + +// **************************************************************************** +// DECLARE SOME BASE TYPES IN CASE THEY ARE MISSING: +// +// These base types include "const" where appropriate, but only where of +// interest to the caller. For example, a caller cares that a variable passed +// by reference will not be modified, such as, "const void * Pindex", but not +// that the called function internally does not modify the pointer itself, such +// as, "void * const Pindex". +// +// Note that its OK to pass a Pvoid_t to a Pcvoid_t; the latter is the same, +// only constant. Callers need to do this so they can also pass & Pvoid_t to +// PPvoid_t (non-constant). + +#ifndef _PCVOID_T +#define _PCVOID_T +typedef const void * Pcvoid_t; +#endif + +#ifndef _PVOID_T +#define _PVOID_T +typedef void * Pvoid_t; +typedef void ** PPvoid_t; +#endif + +#ifndef _WORD_T +#define _WORD_T +typedef unsigned long Word_t, * PWord_t; // expect 32-bit or 64-bit words. +#endif + +#ifndef NULL +#define NULL 0 +#endif + + +// **************************************************************************** +// SUPPORT FOR ERROR HANDLING: +// +// Judy error numbers: +// +// Note: These are an enum so theres a related typedef, but the numbers are +// spelled out so you can map a number back to its name. + +typedef enum // uint8_t -- but C does not support this type of enum. +{ + +// Note: JU_ERRNO_NONE and JU_ERRNO_FULL are not real errors. They specify +// conditions which are otherwise impossible return values from 32-bit +// Judy1Count, which has 2^32 + 1 valid returns (0..2^32) plus one error +// return. These pseudo-errors support the return values that cannot otherwise +// be unambiguously represented in a 32-bit word, and will never occur on a +// 64-bit system. + + JU_ERRNO_NONE = 0, + JU_ERRNO_FULL = 1, + JU_ERRNO_NFMAX = JU_ERRNO_FULL, + +// JU_ERRNO_NOMEM comes from malloc(3C) when Judy cannot obtain needed memory. +// The system errno value is also set to ENOMEM. This error can be recoverable +// if the calling application frees other memory. +// +// TBD: Currently there is no guarantee the Judy array has no memory leaks +// upon JU_ERRNO_NOMEM. + + JU_ERRNO_NOMEM = 2, + +// Problems with parameters from the calling program: +// +// JU_ERRNO_NULLPPARRAY means PPArray was null; perhaps PArray was passed where +// &PArray was intended. Similarly, JU_ERRNO_NULLPINDEX means PIndex was null; +// perhaps &Index was intended. Also, JU_ERRNO_NONNULLPARRAY, +// JU_ERRNO_NULLPVALUE, and JU_ERRNO_UNSORTED, all added later (hence with +// higher numbers), mean: A non-null array was passed in where a null pointer +// was required; PValue was null; and unsorted indexes were detected. + + JU_ERRNO_NULLPPARRAY = 3, // see above. + JU_ERRNO_NONNULLPARRAY = 10, // see above. + JU_ERRNO_NULLPINDEX = 4, // see above. + JU_ERRNO_NULLPVALUE = 11, // see above. + JU_ERRNO_NOTJUDY1 = 5, // PArray is not to a Judy1 array. + JU_ERRNO_NOTJUDYL = 6, // PArray is not to a JudyL array. + JU_ERRNO_NOTJUDYSL = 7, // PArray is not to a JudySL array. + JU_ERRNO_UNSORTED = 12, // see above. + +// Errors below this point are not recoverable; further tries to access the +// Judy array might result in EFAULT and a core dump: +// +// JU_ERRNO_OVERRUN occurs when Judy detects, upon reallocation, that a block +// of memory in its own freelist was modified since being freed. + + JU_ERRNO_OVERRUN = 8, + +// JU_ERRNO_CORRUPT occurs when Judy detects an impossible value in a Judy data +// structure: +// +// Note: The Judy data structure contains some redundant elements that support +// this type of checking. + + JU_ERRNO_CORRUPT = 9 + +// Warning: At least some C or C++ compilers do not tolerate a trailing comma +// above here. At least we know of one case, in aCC; see JAGad58928. + +} JU_Errno_t; + + +// Judy errno structure: +// +// WARNING: For compatibility with possible future changes, the fields of this +// struct should not be referenced directly. Instead use the macros supplied +// below. + +// This structure should be declared on the stack in a threaded process. + +typedef struct J_UDY_ERROR_STRUCT +{ + JU_Errno_t je_Errno; // one of the enums above. + int je_ErrID; // often an internal source line number. + Word_t je_reserved[4]; // for future backward compatibility. + +} JError_t, * PJError_t; + + +// Related macros: +// +// Fields from error struct: + +#define JU_ERRNO(PJError) ((PJError)->je_Errno) +#define JU_ERRID(PJError) ((PJError)->je_ErrID) + +// For checking return values from various Judy functions: +// +// Note: Define JERR as -1, not as the seemingly more portable (Word_t) +// (~0UL), to avoid a compiler "overflow in implicit constant conversion" +// warning. + +#define JERR (-1) /* functions returning int or Word_t */ +#define PJERR ((Pvoid_t) (~0UL)) /* mainly for use here, see below */ +#define PPJERR ((PPvoid_t) (~0UL)) /* functions that return PPvoid_t */ + +// Convenience macro for when detailed error information (PJError_t) is not +// desired by the caller; a purposely short name: + +#define PJE0 ((PJError_t) NULL) + + +// **************************************************************************** +// JUDY FUNCTIONS: +// +// P_JE is a shorthand for use below: + +#define P_JE PJError_t PJError + +// **************************************************************************** +// JUDY1 FUNCTIONS: + +extern int Judy1Test( Pcvoid_t PArray, Word_t Index, P_JE); +extern int Judy1Set( PPvoid_t PPArray, Word_t Index, P_JE); +extern int Judy1SetArray( PPvoid_t PPArray, Word_t Count, + const Word_t * const PIndex, + P_JE); +extern int Judy1Unset( PPvoid_t PPArray, Word_t Index, P_JE); +extern Word_t Judy1Count( Pcvoid_t PArray, Word_t Index1, + Word_t Index2, P_JE); +extern int Judy1ByCount( Pcvoid_t PArray, Word_t Count, + Word_t * PIndex, P_JE); +extern Word_t Judy1FreeArray( PPvoid_t PPArray, P_JE); +extern Word_t Judy1MemUsed( Pcvoid_t PArray); +extern Word_t Judy1MemActive( Pcvoid_t PArray); +extern int Judy1First( Pcvoid_t PArray, Word_t * PIndex, P_JE); +extern int Judy1Next( Pcvoid_t PArray, Word_t * PIndex, P_JE); +extern int Judy1Last( Pcvoid_t PArray, Word_t * PIndex, P_JE); +extern int Judy1Prev( Pcvoid_t PArray, Word_t * PIndex, P_JE); +extern int Judy1FirstEmpty( Pcvoid_t PArray, Word_t * PIndex, P_JE); +extern int Judy1NextEmpty( Pcvoid_t PArray, Word_t * PIndex, P_JE); +extern int Judy1LastEmpty( Pcvoid_t PArray, Word_t * PIndex, P_JE); +extern int Judy1PrevEmpty( Pcvoid_t PArray, Word_t * PIndex, P_JE); + +extern PPvoid_t JudyLGet( Pcvoid_t PArray, Word_t Index, P_JE); +extern PPvoid_t JudyLIns( PPvoid_t PPArray, Word_t Index, P_JE); +extern int JudyLInsArray( PPvoid_t PPArray, Word_t Count, + const Word_t * const PIndex, + const Word_t * const PValue, + +// **************************************************************************** +// JUDYL FUNCTIONS: + P_JE); +extern int JudyLDel( PPvoid_t PPArray, Word_t Index, P_JE); +extern Word_t JudyLCount( Pcvoid_t PArray, Word_t Index1, + Word_t Index2, P_JE); +extern PPvoid_t JudyLByCount( Pcvoid_t PArray, Word_t Count, + Word_t * PIndex, P_JE); +extern Word_t JudyLFreeArray( PPvoid_t PPArray, P_JE); +extern Word_t JudyLMemUsed( Pcvoid_t PArray); +extern Word_t JudyLMemActive( Pcvoid_t PArray); +extern PPvoid_t JudyLFirst( Pcvoid_t PArray, Word_t * PIndex, P_JE); +extern PPvoid_t JudyLNext( Pcvoid_t PArray, Word_t * PIndex, P_JE); +extern PPvoid_t JudyLLast( Pcvoid_t PArray, Word_t * PIndex, P_JE); +extern PPvoid_t JudyLPrev( Pcvoid_t PArray, Word_t * PIndex, P_JE); +extern int JudyLFirstEmpty( Pcvoid_t PArray, Word_t * PIndex, P_JE); +extern int JudyLNextEmpty( Pcvoid_t PArray, Word_t * PIndex, P_JE); +extern int JudyLLastEmpty( Pcvoid_t PArray, Word_t * PIndex, P_JE); +extern int JudyLPrevEmpty( Pcvoid_t PArray, Word_t * PIndex, P_JE); + +// **************************************************************************** +// JUDYSL FUNCTIONS: + +extern PPvoid_t JudySLGet( Pcvoid_t, const uint8_t * Index, P_JE); +extern PPvoid_t JudySLIns( PPvoid_t, const uint8_t * Index, P_JE); +extern int JudySLDel( PPvoid_t, const uint8_t * Index, P_JE); +extern Word_t JudySLFreeArray( PPvoid_t, P_JE); +extern PPvoid_t JudySLFirst( Pcvoid_t, uint8_t * Index, P_JE); +extern PPvoid_t JudySLNext( Pcvoid_t, uint8_t * Index, P_JE); +extern PPvoid_t JudySLLast( Pcvoid_t, uint8_t * Index, P_JE); +extern PPvoid_t JudySLPrev( Pcvoid_t, uint8_t * Index, P_JE); + +// **************************************************************************** +// JUDYHSL FUNCTIONS: + +extern PPvoid_t JudyHSGet( Pcvoid_t, void *, Word_t); +extern PPvoid_t JudyHSIns( PPvoid_t, void *, Word_t, P_JE); +extern int JudyHSDel( PPvoid_t, void *, Word_t, P_JE); +extern Word_t JudyHSFreeArray( PPvoid_t, P_JE); + +extern const char *Judy1MallocSizes; +extern const char *JudyLMallocSizes; + +// **************************************************************************** +// JUDY memory interface to malloc() FUNCTIONS: + +extern Word_t JudyMalloc(Word_t); // words reqd => words allocd. +extern Word_t JudyMallocVirtual(Word_t); // words reqd => words allocd. +extern void JudyFree(Pvoid_t, Word_t); // free, size in words. +extern void JudyFreeVirtual(Pvoid_t, Word_t); // free, size in words. + +#define JLAP_INVALID 0x1 /* flag to mark pointer "not a Judy array" */ + +// **************************************************************************** +// MACRO EQUIVALENTS FOR JUDY FUNCTIONS: +// +// The following macros, such as J1T, are shorthands for calling Judy functions +// with parameter address-of and detailed error checking included. Since they +// are macros, the error checking code is replicated each time the macro is +// used, but it runs fast in the normal case of no error. +// +// If the caller does not like the way the default JUDYERROR macro handles +// errors (such as an exit(1) call when out of memory), they may define their +// own before the "#include ". A routine such as HandleJudyError +// could do checking on specific error numbers and print a different message +// dependent on the error. The following is one example: +// +// Note: the back-slashes are removed because some compilers will not accept +// them in comments. +// +// void HandleJudyError(uint8_t *, int, uint8_t *, int, int); +// #define JUDYERROR(CallerFile, CallerLine, JudyFunc, JudyErrno, JudyErrID) +// { +// HandleJudyError(CallerFile, CallerLine, JudyFunc, JudyErrno, JudyErrID); +// } +// +// The routine HandleJudyError could do checking on specific error numbers and +// print a different message dependent on the error. +// +// The macro receives five parameters that are: +// +// 1. CallerFile: Source filename where a Judy call returned a serious error. +// 2. CallerLine: Line number in that source file. +// 3. JudyFunc: Name of Judy function reporting the error. +// 4. JudyErrno: One of the JU_ERRNO* values enumerated above. +// 5. JudyErrID: The je_ErrID field described above. + +#ifndef JUDYERROR_NOTEST +#ifndef JUDYERROR /* supply a default error macro */ +#include + +#define JUDYERROR(CallerFile, CallerLine, JudyFunc, JudyErrno, JudyErrID) \ + { \ + (void) fprintf(stderr, "File '%s', line %d: %s(), " \ + "JU_ERRNO_* == %d, ID == %d\n", \ + CallerFile, CallerLine, \ + JudyFunc, JudyErrno, JudyErrID); \ + exit(1); \ + } + +#endif /* JUDYERROR */ +#endif /* JUDYERROR_NOTEST */ + +// If the JUDYERROR macro is not desired at all, then the following eliminates +// it. However, the return code from each Judy function (that is, the first +// parameter of each macro) must be checked by the caller to assure that an +// error did not occur. +// +// Example: +// +// #define JUDYERROR_NOTEST 1 +// #include +// +// or use this cc option at compile time: +// +// cc -DJUDYERROR_NOTEST ... +// +// Example code: +// +// J1S(Rc, PArray, Index); +// if (Rc == JERR) goto ...error +// +// or: +// +// JLI(PValue, PArray, Index); +// if (PValue == PJERR) goto ...error + + +// Internal shorthand macros for writing the J1S, etc. macros: + +#ifdef JUDYERROR_NOTEST /* ============================================ */ + +// "Judy Set Error": + +#define J_SE(FuncName,Errno) ((void) 0) + +// Note: In each J_*() case below, the digit is the number of key parameters +// to the Judy*() call. Just assign the Func result to the callers Rc value +// without a cast because none is required, and this keeps the API simpler. +// However, a family of different J_*() macros is needed to support the +// different numbers of key parameters (0,1,2) and the Func return type. +// +// In the names below, "I" = integer result; "P" = pointer result. Note, the +// Funcs for J_*P() return PPvoid_t, but cast this to a Pvoid_t for flexible, +// error-free assignment, and then compare to PJERR. + +#define J_0I(Rc,PArray,Func,FuncName) \ + { (Rc) = Func(PArray, PJE0); } + +#define J_1I(Rc,PArray,Index,Func,FuncName) \ + { (Rc) = Func(PArray, Index, PJE0); } + +#define J_1P(PV,PArray,Index,Func,FuncName) \ + { (PV) = (Pvoid_t) Func(PArray, Index, PJE0); } + +#define J_2I(Rc,PArray,Index,Arg2,Func,FuncName) \ + { (Rc) = Func(PArray, Index, Arg2, PJE0); } + +#define J_2C(Rc,PArray,Index1,Index2,Func,FuncName) \ + { (Rc) = Func(PArray, Index1, Index2, PJE0); } + +#define J_2P(PV,PArray,Index,Arg2,Func,FuncName) \ + { (PV) = (Pvoid_t) Func(PArray, Index, Arg2, PJE0); } + +// Variations for Judy*Set/InsArray functions: + +#define J_2AI(Rc,PArray,Count,PIndex,Func,FuncName) \ + { (Rc) = Func(PArray, Count, PIndex, PJE0); } +#define J_3AI(Rc,PArray,Count,PIndex,PValue,Func,FuncName) \ + { (Rc) = Func(PArray, Count, PIndex, PValue, PJE0); } + +#else /* ================ ! JUDYERROR_NOTEST ============================= */ + +#define J_E(FuncName,PJE) \ + JUDYERROR(__FILE__, __LINE__, FuncName, JU_ERRNO(PJE), JU_ERRID(PJE)) + +#define J_SE(FuncName,Errno) \ + { \ + JError_t J_Error; \ + JU_ERRNO(&J_Error) = (Errno); \ + JU_ERRID(&J_Error) = __LINE__; \ + J_E(FuncName, &J_Error); \ + } + +// Note: In each J_*() case below, the digit is the number of key parameters +// to the Judy*() call. Just assign the Func result to the callers Rc value +// without a cast because none is required, and this keeps the API simpler. +// However, a family of different J_*() macros is needed to support the +// different numbers of key parameters (0,1,2) and the Func return type. +// +// In the names below, "I" = integer result; "P" = pointer result. Note, the +// Funcs for J_*P() return PPvoid_t, but cast this to a Pvoid_t for flexible, +// error-free assignment, and then compare to PJERR. + +#define J_0I(Rc,PArray,Func,FuncName) \ + { \ + JError_t J_Error; \ + if (((Rc) = Func(PArray, &J_Error)) == JERR) \ + J_E(FuncName, &J_Error); \ + } + +#define J_1I(Rc,PArray,Index,Func,FuncName) \ + { \ + JError_t J_Error; \ + if (((Rc) = Func(PArray, Index, &J_Error)) == JERR) \ + J_E(FuncName, &J_Error); \ + } + +#define J_1P(Rc,PArray,Index,Func,FuncName) \ + { \ + JError_t J_Error; \ + if (((Rc) = (Pvoid_t) Func(PArray, Index, &J_Error)) == PJERR) \ + J_E(FuncName, &J_Error); \ + } + +#define J_2I(Rc,PArray,Index,Arg2,Func,FuncName) \ + { \ + JError_t J_Error; \ + if (((Rc) = Func(PArray, Index, Arg2, &J_Error)) == JERR) \ + J_E(FuncName, &J_Error); \ + } + +// Variation for Judy*Count functions, which return 0, not JERR, for error (and +// also for other non-error cases): +// +// Note: JU_ERRNO_NFMAX should only apply to 32-bit Judy1, but this header +// file lacks the necessary ifdefs to make it go away otherwise, so always +// check against it. + +#define J_2C(Rc,PArray,Index1,Index2,Func,FuncName) \ + { \ + JError_t J_Error; \ + if ((((Rc) = Func(PArray, Index1, Index2, &J_Error)) == 0) \ + && (JU_ERRNO(&J_Error) > JU_ERRNO_NFMAX)) \ + { \ + J_E(FuncName, &J_Error); \ + } \ + } + +#define J_2P(PV,PArray,Index,Arg2,Func,FuncName) \ + { \ + JError_t J_Error; \ + if (((PV) = (Pvoid_t) Func(PArray, Index, Arg2, &J_Error)) \ + == PJERR) J_E(FuncName, &J_Error); \ + } + +// Variations for Judy*Set/InsArray functions: + +#define J_2AI(Rc,PArray,Count,PIndex,Func,FuncName) \ + { \ + JError_t J_Error; \ + if (((Rc) = Func(PArray, Count, PIndex, &J_Error)) == JERR) \ + J_E(FuncName, &J_Error); \ + } + +#define J_3AI(Rc,PArray,Count,PIndex,PValue,Func,FuncName) \ + { \ + JError_t J_Error; \ + if (((Rc) = Func(PArray, Count, PIndex, PValue, &J_Error)) \ + == JERR) J_E(FuncName, &J_Error); \ + } + +#endif /* ================ ! JUDYERROR_NOTEST ============================= */ + +// Some of the macros are special cases that use inlined shortcuts for speed +// with root-level leaves: + +// This is a slower version with current processors, but in the future... + +#define J1T(Rc,PArray,Index) \ + (Rc) = Judy1Test((Pvoid_t)(PArray), Index, PJE0) + +#define J1S( Rc, PArray, Index) \ + J_1I(Rc, (&(PArray)), Index, Judy1Set, "Judy1Set") +#define J1SA(Rc, PArray, Count, PIndex) \ + J_2AI(Rc,(&(PArray)), Count, PIndex, Judy1SetArray, "Judy1SetArray") +#define J1U( Rc, PArray, Index) \ + J_1I(Rc, (&(PArray)), Index, Judy1Unset, "Judy1Unset") +#define J1F( Rc, PArray, Index) \ + J_1I(Rc, PArray, &(Index), Judy1First, "Judy1First") +#define J1N( Rc, PArray, Index) \ + J_1I(Rc, PArray, &(Index), Judy1Next, "Judy1Next") +#define J1L( Rc, PArray, Index) \ + J_1I(Rc, PArray, &(Index), Judy1Last, "Judy1Last") +#define J1P( Rc, PArray, Index) \ + J_1I(Rc, PArray, &(Index), Judy1Prev, "Judy1Prev") +#define J1FE(Rc, PArray, Index) \ + J_1I(Rc, PArray, &(Index), Judy1FirstEmpty, "Judy1FirstEmpty") +#define J1NE(Rc, PArray, Index) \ + J_1I(Rc, PArray, &(Index), Judy1NextEmpty, "Judy1NextEmpty") +#define J1LE(Rc, PArray, Index) \ + J_1I(Rc, PArray, &(Index), Judy1LastEmpty, "Judy1LastEmpty") +#define J1PE(Rc, PArray, Index) \ + J_1I(Rc, PArray, &(Index), Judy1PrevEmpty, "Judy1PrevEmpty") +#define J1C( Rc, PArray, Index1, Index2) \ + J_2C(Rc, PArray, Index1, Index2, Judy1Count, "Judy1Count") +#define J1BC(Rc, PArray, Count, Index) \ + J_2I(Rc, PArray, Count, &(Index), Judy1ByCount, "Judy1ByCount") +#define J1FA(Rc, PArray) \ + J_0I(Rc, (&(PArray)), Judy1FreeArray, "Judy1FreeArray") +#define J1MU(Rc, PArray) \ + (Rc) = Judy1MemUsed(PArray) + +#define JLG(PV,PArray,Index) \ + (PV) = (Pvoid_t)JudyLGet((Pvoid_t)PArray, Index, PJE0) + +#define JLI( PV, PArray, Index) \ + J_1P(PV, (&(PArray)), Index, JudyLIns, "JudyLIns") + +#define JLIA(Rc, PArray, Count, PIndex, PValue) \ + J_3AI(Rc,(&(PArray)), Count, PIndex, PValue, JudyLInsArray, \ + "JudyLInsArray") +#define JLD( Rc, PArray, Index) \ + J_1I(Rc, (&(PArray)), Index, JudyLDel, "JudyLDel") + +#define JLF( PV, PArray, Index) \ + J_1P(PV, PArray, &(Index), JudyLFirst, "JudyLFirst") + +#define JLN( PV, PArray, Index) \ + J_1P(PV, PArray, &(Index), JudyLNext, "JudyLNext") + +#define JLL( PV, PArray, Index) \ + J_1P(PV, PArray, &(Index), JudyLLast, "JudyLLast") +#define JLP( PV, PArray, Index) \ + J_1P(PV, PArray, &(Index), JudyLPrev, "JudyLPrev") +#define JLFE(Rc, PArray, Index) \ + J_1I(Rc, PArray, &(Index), JudyLFirstEmpty, "JudyLFirstEmpty") +#define JLNE(Rc, PArray, Index) \ + J_1I(Rc, PArray, &(Index), JudyLNextEmpty, "JudyLNextEmpty") +#define JLLE(Rc, PArray, Index) \ + J_1I(Rc, PArray, &(Index), JudyLLastEmpty, "JudyLLastEmpty") +#define JLPE(Rc, PArray, Index) \ + J_1I(Rc, PArray, &(Index), JudyLPrevEmpty, "JudyLPrevEmpty") +#define JLC( Rc, PArray, Index1, Index2) \ + J_2C(Rc, PArray, Index1, Index2, JudyLCount, "JudyLCount") +#define JLBC(PV, PArray, Count, Index) \ + J_2P(PV, PArray, Count, &(Index), JudyLByCount, "JudyLByCount") +#define JLFA(Rc, PArray) \ + J_0I(Rc, (&(PArray)), JudyLFreeArray, "JudyLFreeArray") +#define JLMU(Rc, PArray) \ + (Rc) = JudyLMemUsed(PArray) + +#define JHSI(PV, PArray, PIndex, Count) \ + J_2P(PV, (&(PArray)), PIndex, Count, JudyHSIns, "JudyHSIns") +#define JHSG(PV, PArray, PIndex, Count) \ + (PV) = (Pvoid_t) JudyHSGet(PArray, PIndex, Count) +#define JHSD(Rc, PArray, PIndex, Count) \ + J_2I(Rc, (&(PArray)), PIndex, Count, JudyHSDel, "JudyHSDel") +#define JHSFA(Rc, PArray) \ + J_0I(Rc, (&(PArray)), JudyHSFreeArray, "JudyHSFreeArray") + +#define JSLG( PV, PArray, Index) \ + J_1P( PV, PArray, Index, JudySLGet, "JudySLGet") +#define JSLI( PV, PArray, Index) \ + J_1P( PV, (&(PArray)), Index, JudySLIns, "JudySLIns") +#define JSLD( Rc, PArray, Index) \ + J_1I( Rc, (&(PArray)), Index, JudySLDel, "JudySLDel") +#define JSLF( PV, PArray, Index) \ + J_1P( PV, PArray, Index, JudySLFirst, "JudySLFirst") +#define JSLN( PV, PArray, Index) \ + J_1P( PV, PArray, Index, JudySLNext, "JudySLNext") +#define JSLL( PV, PArray, Index) \ + J_1P( PV, PArray, Index, JudySLLast, "JudySLLast") +#define JSLP( PV, PArray, Index) \ + J_1P( PV, PArray, Index, JudySLPrev, "JudySLPrev") +#define JSLFA(Rc, PArray) \ + J_0I( Rc, (&(PArray)), JudySLFreeArray, "JudySLFreeArray") + +#ifdef __cplusplus +} +#endif +#endif /* ! _JUDY_INCLUDED */ diff --git a/feeds/p4/libjudy/src/src/Judy.h.check.c b/feeds/p4/libjudy/src/src/Judy.h.check.c new file mode 100644 index 000000000..658436e33 --- /dev/null +++ b/feeds/p4/libjudy/src/src/Judy.h.check.c @@ -0,0 +1,139 @@ +// Copyright (C) 2000 - 2002 Hewlett-Packard Company +// +// This program is free software; you can redistribute it and/or modify it +// under the term of the GNU Lesser 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 Lesser General Public License +// for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// _________________ + +// @(#) $Revision: 4.17 $ $Source: /judy/src/Judy.h.check.c $ +// +// Fake "program" to test the exports in Judy.h by exercising each one. This +// program should compile OK (with libJudy.a) but does not run OK. + +#include "Judy.h" + +int +main() +{ + Pvoid_t PArray = (Pvoid_t) NULL; + PPvoid_t PPArray = &PArray; + Word_t Index = 0; + PWord_t PIndex = &Index; + uint8_t *CIndex = NULL; + PPvoid_t PPvoid; + Word_t myword; + Word_t Length; + int myint; + +// JUDY FUNCTIONS: + + myint = Judy1Test ( PArray, Index, PJE0); + myint = Judy1Set (PPArray, Index, PJE0); + myint = Judy1SetArray (PPArray, Index, &Index, PJE0); + myint = Judy1Unset (PPArray, Index, PJE0); + myword = Judy1Count ( PArray, Index, Index, PJE0); + myint = Judy1ByCount ( PArray, Index, PIndex, PJE0); + myword = Judy1FreeArray (PPArray, PJE0); + myword = Judy1MemUsed ( PArray ); + myword = Judy1MemActive ( PArray ); + myint = Judy1First ( PArray, PIndex, PJE0); + myint = Judy1Next ( PArray, PIndex, PJE0); + myint = Judy1Last ( PArray, PIndex, PJE0); + myint = Judy1Prev ( PArray, PIndex, PJE0); + myint = Judy1FirstEmpty ( PArray, PIndex, PJE0); + myint = Judy1NextEmpty ( PArray, PIndex, PJE0); + myint = Judy1LastEmpty ( PArray, PIndex, PJE0); + myint = Judy1PrevEmpty ( PArray, PIndex, PJE0); + + PPvoid = JudyLGet ( PArray, Index, PJE0); + PPvoid = JudyLIns (PPArray, Index, PJE0); + myint = JudyLInsArray (PPArray, Index, &Index, &Index, PJE0); + myint = JudyLDel (PPArray, Index, PJE0); + myword = JudyLCount ( PArray, Index, Index, PJE0); + PPvoid = JudyLByCount ( PArray, Index, PIndex, PJE0); + myword = JudyLFreeArray (PPArray, PJE0); + myword = JudyLMemUsed ( PArray ); + myword = JudyLMemActive ( PArray ); + PPvoid = JudyLFirst ( PArray, PIndex, PJE0); + PPvoid = JudyLNext ( PArray, PIndex, PJE0); + PPvoid = JudyLLast ( PArray, PIndex, PJE0); + PPvoid = JudyLPrev ( PArray, PIndex, PJE0); + myint = JudyLFirstEmpty ( PArray, PIndex, PJE0); + myint = JudyLNextEmpty ( PArray, PIndex, PJE0); + myint = JudyLLastEmpty ( PArray, PIndex, PJE0); + myint = JudyLPrevEmpty ( PArray, PIndex, PJE0); + + PPvoid = JudySLGet ( PArray, CIndex, PJE0); + PPvoid = JudySLIns (PPArray, CIndex, PJE0); + myint = JudySLDel (PPArray, CIndex, PJE0); + myword = JudySLFreeArray (PPArray, PJE0); + PPvoid = JudySLFirst ( PArray, CIndex, PJE0); + PPvoid = JudySLNext ( PArray, CIndex, PJE0); + PPvoid = JudySLLast ( PArray, CIndex, PJE0); + PPvoid = JudySLPrev ( PArray, CIndex, PJE0); + + PPvoid = JudyHSGet ( PArray, CIndex, Length); + PPvoid = JudyHSIns (PPArray, CIndex, Length, PJE0); + myint = JudyHSDel (PPArray, CIndex, Length, PJE0); + + +// MACRO EQUIVALENTS: + + J1T (myint, PArray, Index); + J1S (myint, PArray, Index); + J1SA (myint, PArray, Index, &Index); + J1U (myint, PArray, Index); + J1F (myint, PArray, Index); + J1N (myint, PArray, Index); + J1L (myint, PArray, Index); + J1P (myint, PArray, Index); + J1FE (myint, PArray, Index); + J1NE (myint, PArray, Index); + J1LE (myint, PArray, Index); + J1PE (myint, PArray, Index); + J1C (myword, PArray, Index, Index); + J1BC (myint, PArray, Index, Index); + J1FA (myword, PArray); + + JLG (PPvoid, PArray, Index); + JLI (PPvoid, PArray, Index); + JLIA (myint, PArray, Index, &Index, &Index); + JLD (myint, PArray, Index); + JLF (PPvoid, PArray, Index); + JLN (PPvoid, PArray, Index); + JLL (PPvoid, PArray, Index); + JLP (PPvoid, PArray, Index); + JLFE (myint, PArray, Index); + JLNE (myint, PArray, Index); + JLLE (myint, PArray, Index); + JLPE (myint, PArray, Index); + JLC (myword, PArray, Index, Index); + JLBC (PPvoid, PArray, myword, Index); + JLFA (myword, PArray); + + JSLG (PPvoid, PArray, CIndex); + JSLI (PPvoid, PArray, CIndex); + JSLD (myint, PArray, CIndex); + JSLF (PPvoid, PArray, CIndex); + JSLN (PPvoid, PArray, CIndex); + JSLL (PPvoid, PArray, CIndex); + JSLP (PPvoid, PArray, CIndex); + JSLFA (myword, PArray); + + JHSI (PPvoid, PArray, CIndex, Length); + JHSG (PPvoid, PArray, CIndex, Length); + JHSD (myint, PArray, CIndex, Length); + + return(0); + +} // main() diff --git a/feeds/p4/libjudy/src/src/Judy1/Judy1.h b/feeds/p4/libjudy/src/src/Judy1/Judy1.h new file mode 100644 index 000000000..3f48f5593 --- /dev/null +++ b/feeds/p4/libjudy/src/src/Judy1/Judy1.h @@ -0,0 +1,551 @@ +#ifndef _JUDY1_INCLUDED +#define _JUDY1_INCLUDED +// _________________ +// +// Copyright (C) 2000 - 2002 Hewlett-Packard Company +// +// This program is free software; you can redistribute it and/or modify it +// under the term of the GNU Lesser 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 Lesser General Public License +// for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// _________________ + +// @(#) $Revision: 4.76 $ $Source: /judy/src/Judy1/Judy1.h $ + +// **************************************************************************** +// JUDY1 -- SMALL/LARGE AND/OR CLUSTERED/SPARSE BIT ARRAYS +// +// -by- +// +// Douglas L. Baskins +// doug@sourcejudy.com +// +// Judy arrays are designed to be used instead of arrays. The performance +// suggests the reason why Judy arrays are thought of as arrays, instead of +// trees. They are remarkably memory efficient at all populations. +// Implemented as a hybrid digital tree (but really a state machine, see +// below), Judy arrays feature fast insert/retrievals, fast near neighbor +// searching, and contain a population tree for extremely fast ordinal related +// retrievals. +// +// CONVENTIONS: +// +// - The comments here refer to 32-bit [64-bit] systems. +// +// - BranchL, LeafL refer to linear branches and leaves (small populations), +// except LeafL does not actually appear as such; rather, Leaf1..3 [Leaf1..7] +// is used to represent leaf Index sizes, and LeafW refers to a Leaf with +// full (long) word Indexes, which is also a type of linear leaf. Note that +// root-level LeafW (Leaf4 [Leaf8]) leaves are also called LEAFW. +// +// - BranchB, LeafB1 refer to bitmap branches and leaves (intermediate +// populations). +// +// - BranchU refers to uncompressed branches. An uncompressed branch has 256 +// JPs, some of which could be null. Note: All leaves are compressed (and +// sorted), or else an expanse is full (FullPopu), so there is no LeafU +// equivalent to BranchU. +// +// - "Popu" is short for "Population". +// - "Pop1" refers to actual population (base 1). +// - "Pop0" refers to Pop1 - 1 (base 0), the way populations are stored in data +// structures. +// +// - Branches and Leaves are both named by the number of bytes in their Pop0 +// field. In the case of Leaves, the same number applies to the Index sizes. +// +// - The representation of many numbers as hex is a relatively safe and +// portable way to get desired bitpatterns as unsigned longs. +// +// - Some preprocessors cant handle single apostrophe characters within +// #ifndef code, so here, use delete all instead. + +#include "JudyPrivate.h" // includes Judy.h in turn. +#include "JudyPrivateBranch.h" + + +// **************************************************************************** +// JUDY1 ROOT POINTER (JRP) AND JUDY1 POINTER (JP) TYPE FIELDS +// **************************************************************************** +// +// The following enum lists all possible JP Type fields. + +typedef enum // uint8_t -- but C does not support this type of enum. +{ + +// JP NULL TYPES: +// +// There is a series of cJ1_JPNULL* Types because each one pre-records a +// different Index Size for when the first Index is inserted in the previously +// null JP. They must start >= 8 (three bits). +// +// Note: These Types must be in sequential order for doing relative +// calculations between them. + + cJ1_JPNULL1 = 1, + // Index Size 1[1] byte when 1 Index inserted. + cJ1_JPNULL2, // Index Size 2[2] bytes when 1 Index inserted. + cJ1_JPNULL3, // Index Size 3[3] bytes when 1 Index inserted. + +#ifndef JU_64BIT +#define cJ1_JPNULLMAX cJ1_JPNULL3 +#else + cJ1_JPNULL4, // Index Size 4[4] bytes when 1 Index inserted. + cJ1_JPNULL5, // Index Size 5[5] bytes when 1 Index inserted. + cJ1_JPNULL6, // Index Size 6[6] bytes when 1 Index inserted. + cJ1_JPNULL7, // Index Size 7[7] bytes when 1 Index inserted. +#define cJ1_JPNULLMAX cJ1_JPNULL7 +#endif + + +// JP BRANCH TYPES: +// +// Note: There are no state-1 branches; only leaves reside at state 1. + +// Linear branches: +// +// Note: These Types must be in sequential order for doing relative +// calculations between them. + + cJ1_JPBRANCH_L2, // 2[2] bytes Pop0, 1[5] bytes Dcd. + cJ1_JPBRANCH_L3, // 3[3] bytes Pop0, 0[4] bytes Dcd. + +#ifdef JU_64BIT + cJ1_JPBRANCH_L4, // [4] bytes Pop0, [3] bytes Dcd. + cJ1_JPBRANCH_L5, // [5] bytes Pop0, [2] bytes Dcd. + cJ1_JPBRANCH_L6, // [6] bytes Pop0, [1] byte Dcd. + cJ1_JPBRANCH_L7, // [7] bytes Pop0, [0] bytes Dcd. +#endif + + cJ1_JPBRANCH_L, // note: DcdPopO field not used. + +// Bitmap branches: +// +// Note: These Types must be in sequential order for doing relative +// calculations between them. + + cJ1_JPBRANCH_B2, // 2[2] bytes Pop0, 1[5] bytes Dcd. + cJ1_JPBRANCH_B3, // 3[3] bytes Pop0, 0[4] bytes Dcd. + +#ifdef JU_64BIT + cJ1_JPBRANCH_B4, // [4] bytes Pop0, [3] bytes Dcd. + cJ1_JPBRANCH_B5, // [5] bytes Pop0, [2] bytes Dcd. + cJ1_JPBRANCH_B6, // [6] bytes Pop0, [1] byte Dcd. + cJ1_JPBRANCH_B7, // [7] bytes Pop0, [0] bytes Dcd. +#endif + + cJ1_JPBRANCH_B, // note: DcdPopO field not used. + +// Uncompressed branches: +// +// Note: These Types must be in sequential order for doing relative +// calculations between them. + + cJ1_JPBRANCH_U2, // 2[2] bytes Pop0, 1[5] bytes Dcd. + cJ1_JPBRANCH_U3, // 3[3] bytes Pop0, 0[4] bytes Dcd. + +#ifdef JU_64BIT + cJ1_JPBRANCH_U4, // [4] bytes Pop0, [3] bytes Dcd. + cJ1_JPBRANCH_U5, // [5] bytes Pop0, [2] bytes Dcd. + cJ1_JPBRANCH_U6, // [6] bytes Pop0, [1] byte Dcd. + cJ1_JPBRANCH_U7, // [7] bytes Pop0, [0] bytes Dcd. +#endif + + cJ1_JPBRANCH_U, // note: DcdPopO field not used. + + +// JP LEAF TYPES: + +// Linear leaves: +// +// Note: These Types must be in sequential order for doing relative +// calculations between them. +// +// Note: There is no cJ1_JPLEAF1 for 64-bit for a subtle reason. An immediate +// JP can hold 15 1-byte Indexes, and a bitmap leaf would be used for 17 +// Indexes, so rather than support a linear leaf for only the case of exactly +// 16 Indexes, a bitmap leaf is used in that case. See also below regarding +// cJ1_LEAF1_MAXPOP1 on 64-bit systems. +// +// Note: There is no full-word (4-byte [8-byte]) Index leaf under a JP because +// non-root-state leaves only occur under branches that decode at least one +// byte. Full-word, root-state leaves are under a JRP, not a JP. However, in +// the code a "fake" JP can be created temporarily above a root-state leaf. + +#ifndef JU_64BIT // 32-bit only; see above. + cJ1_JPLEAF1, // 1 byte Pop0, 2 bytes Dcd. +#endif + + cJ1_JPLEAF2, // 2[2] bytes Pop0, 1[5] bytes Dcd. + cJ1_JPLEAF3, // 3[3] bytes Pop0, 0[4] bytes Dcd. + +#ifdef JU_64BIT + cJ1_JPLEAF4, // [4] bytes Pop0, [3] bytes Dcd. + cJ1_JPLEAF5, // [5] bytes Pop0, [2] bytes Dcd. + cJ1_JPLEAF6, // [6] bytes Pop0, [1] byte Dcd. + cJ1_JPLEAF7, // [7] bytes Pop0, [0] bytes Dcd. +#endif + +// Bitmap leaf; Index Size == 1: +// +// Note: These are currently only supported at state 1. At other states the +// bitmap would grow from 256 to 256^2, 256^3, ... bits, which would not be +// efficient.. + + cJ1_JPLEAF_B1, // 1[1] byte Pop0, 2[6] bytes Dcd. + + +// Full population; Index Size == 1 virtual leaf: +// +// Note: These are currently only supported at state 1. At other states they +// could be used, but they would be rare and the savings are dubious. + + cJ1_JPFULLPOPU1, // 1[1] byte Pop0, 2[6] bytes Dcd. + +#ifdef notdef // for future enhancements + cJ1_JPFULLPOPU1m1, // Full Population - 1 + cJ1_JPFULLPOPU1m2, // Full Population - 2 + cJ1_JPFULLPOPU1m3, // Full Population - 3 + cJ1_JPFULLPOPU1m4, // Full Population - 4 + cJ1_JPFULLPOPU1m5, // Full Population - 5 + cJ1_JPFULLPOPU1m6, // Full Population - 6 + cJ1_JPFULLPOPU1m7, // Full Population - 7 + +#ifdef JU_64BIT + cJ1_JPFULLPOPU1m8, // Full Population - 8 + cJ1_JPFULLPOPU1m9, // Full Population - 9 + cJ1_JPFULLPOPU1m10, // Full Population - 10 + cJ1_JPFULLPOPU1m11, // Full Population - 11 + cJ1_JPFULLPOPU1m12, // Full Population - 12 + cJ1_JPFULLPOPU1m13, // Full Population - 13 + cJ1_JPFULLPOPU1m14, // Full Population - 14 + cJ1_JPFULLPOPU1m15, // Full Population - 15 +#endif +#endif // notdef -- for future enhancements + + +// JP IMMEDIATES; leaves (Indexes) stored inside a JP: +// +// The second numeric suffix is the Pop1 for each type. As the Index Size +// increases, the maximum possible population decreases. +// +// Note: These Types must be in sequential order in each group (Index Size), +// and the groups in correct order too, for doing relative calculations between +// them. For example, since these Types enumerate the Pop1 values (unlike +// other JP Types where there is a Pop0 value in the JP), the maximum Pop1 for +// each Index Size is computable. + + cJ1_JPIMMED_1_01, // Index Size = 1, Pop1 = 1. + cJ1_JPIMMED_2_01, // Index Size = 2, Pop1 = 1. + cJ1_JPIMMED_3_01, // Index Size = 3, Pop1 = 1. +#ifdef JU_64BIT + cJ1_JPIMMED_4_01, // Index Size = 4, Pop1 = 1. + cJ1_JPIMMED_5_01, // Index Size = 5, Pop1 = 1. + cJ1_JPIMMED_6_01, // Index Size = 6, Pop1 = 1. + cJ1_JPIMMED_7_01, // Index Size = 7, Pop1 = 1. +#endif + + cJ1_JPIMMED_1_02, // Index Size = 1, Pop1 = 2. + cJ1_JPIMMED_1_03, // Index Size = 1, Pop1 = 3. + cJ1_JPIMMED_1_04, // Index Size = 1, Pop1 = 4. + cJ1_JPIMMED_1_05, // Index Size = 1, Pop1 = 5. + cJ1_JPIMMED_1_06, // Index Size = 1, Pop1 = 6. + cJ1_JPIMMED_1_07, // Index Size = 1, Pop1 = 7. + +#ifdef JU_64BIT + cJ1_JPIMMED_1_08, // Index Size = 1, Pop1 = 8. + cJ1_JPIMMED_1_09, // Index Size = 1, Pop1 = 9. + cJ1_JPIMMED_1_10, // Index Size = 1, Pop1 = 10. + cJ1_JPIMMED_1_11, // Index Size = 1, Pop1 = 11. + cJ1_JPIMMED_1_12, // Index Size = 1, Pop1 = 12. + cJ1_JPIMMED_1_13, // Index Size = 1, Pop1 = 13. + cJ1_JPIMMED_1_14, // Index Size = 1, Pop1 = 14. + cJ1_JPIMMED_1_15, // Index Size = 1, Pop1 = 15. +#endif + + cJ1_JPIMMED_2_02, // Index Size = 2, Pop1 = 2. + cJ1_JPIMMED_2_03, // Index Size = 2, Pop1 = 3. + +#ifdef JU_64BIT + cJ1_JPIMMED_2_04, // Index Size = 2, Pop1 = 4. + cJ1_JPIMMED_2_05, // Index Size = 2, Pop1 = 5. + cJ1_JPIMMED_2_06, // Index Size = 2, Pop1 = 6. + cJ1_JPIMMED_2_07, // Index Size = 2, Pop1 = 7. +#endif + + cJ1_JPIMMED_3_02, // Index Size = 3, Pop1 = 2. + +#ifdef JU_64BIT + cJ1_JPIMMED_3_03, // Index Size = 3, Pop1 = 3. + cJ1_JPIMMED_3_04, // Index Size = 3, Pop1 = 4. + cJ1_JPIMMED_3_05, // Index Size = 3, Pop1 = 5. + + cJ1_JPIMMED_4_02, // Index Size = 4, Pop1 = 2. + cJ1_JPIMMED_4_03, // Index Size = 4, Pop1 = 3. + + cJ1_JPIMMED_5_02, // Index Size = 5, Pop1 = 2. + cJ1_JPIMMED_5_03, // Index Size = 3, Pop1 = 3. + + cJ1_JPIMMED_6_02, // Index Size = 6, Pop1 = 2. + + cJ1_JPIMMED_7_02, // Index Size = 7, Pop1 = 2. +#endif + +// This special Type is merely a sentinel for doing relative calculations. +// This value should not be used in switch statements (to avoid allocating code +// for it), which is also why it appears at the end of the enum list. + + cJ1_JPIMMED_CAP + +} jp1_Type_t; + + +// RELATED VALUES: +// +// Index Size (state) for leaf JP, and JP type based on Index Size (state): + +#ifndef JU_64BIT // 32-bit +#define J1_LEAFINDEXSIZE(jpType) ((jpType) - cJ1_JPLEAF1 + 1) +#define J1_LEAFTYPE(IndexSize) ((IndexSize) + cJ1_JPLEAF1 - 1) +#else +#define J1_LEAFINDEXSIZE(jpType) ((jpType) - cJ1_JPLEAF2 + 2) +#define J1_LEAFTYPE(IndexSize) ((IndexSize) + cJ1_JPLEAF2 - 2) +#endif + + +// **************************************************************************** +// JUDY1 POINTER (JP) -- RELATED MACROS AND CONSTANTS +// **************************************************************************** + +// MAXIMUM POPULATIONS OF LINEAR LEAVES: +// +// Allow up to 2 cache lines per leaf, with N bytes per index. +// +// J_1_MAXB is the maximum number of bytes (sort of) to allocate per leaf. +// ALLOCSIZES is defined here, not there, for single-point control of these key +// definitions. See JudyTables.c for "TERMINATOR". + +#define J_1_MAXB (sizeof(Word_t) * 32) +#define ALLOCSIZES { 3, 5, 7, 11, 15, 23, 32, 47, 64, TERMINATOR } // in words. +#define cJ1_LEAF1_MAXWORDS 5 // Leaf1 max alloc size in words. + +// Under JRP (root-state leaves): +// +// Includes a count (Population) word. +// +// Under JP (non-root-state leaves), which have no count (Population) words: +// +// When a 1-byte index leaf grows above cJ1_LEAF1_MAXPOP1 Indexes (bytes), +// the memory chunk required grows to a size where a bitmap is just as +// efficient, so use a bitmap instead for all greater Populations, on both +// 32-bit and 64-bit systems. However, on a 32-bit system this occurs upon +// going from 6 to 8 words (24 to 32 bytes) in the memory chunk, but on a +// 64-bit system this occurs upon going from 2 to 4 words (16 to 32 bytes). It +// would be silly to go from a 15-Index Immediate JP to a 16-Index linear leaf +// to a 17-Index bitmap leaf, so just use a bitmap leaf for 16+ Indexes, which +// means set cJ1_LEAF1_MAXPOP1 to cJ1_IMMED1_MAXPOP1 (15) to cause the +// transition at that point. +// +// Note: cJ1_LEAF1_MAXPOP1 is not used on 64-bit systems. + +#ifndef JU_64BIT // 32-bit + +#define cJ1_LEAF1_MAXPOP1 (cJ1_LEAF1_MAXWORDS * cJU_BYTESPERWORD) +#define cJ1_LEAF2_MAXPOP1 (J_1_MAXB / 2) +#define cJ1_LEAF3_MAXPOP1 (J_1_MAXB / 3) +#define cJ1_LEAFW_MAXPOP1 ((J_1_MAXB - cJU_BYTESPERWORD) / cJU_BYTESPERWORD) + +#else // 64-bit + +// #define cJ1_LEAF1_MAXPOP1 // no LEAF1 in 64-bit. +#define cJ1_LEAF2_MAXPOP1 (J_1_MAXB / 2) +#define cJ1_LEAF3_MAXPOP1 (J_1_MAXB / 3) +#define cJ1_LEAF4_MAXPOP1 (J_1_MAXB / 4) +#define cJ1_LEAF5_MAXPOP1 (J_1_MAXB / 5) +#define cJ1_LEAF6_MAXPOP1 (J_1_MAXB / 6) +#define cJ1_LEAF7_MAXPOP1 (J_1_MAXB / 7) +#define cJ1_LEAFW_MAXPOP1 ((J_1_MAXB - cJU_BYTESPERWORD) / cJU_BYTESPERWORD) + +#endif + + +// MAXIMUM POPULATIONS OF IMMEDIATE JPs: +// +// These specify the maximum Population of immediate JPs with various Index +// Sizes (== sizes of remaining undecoded Index bits). + +#define cJ1_IMMED1_MAXPOP1 ((sizeof(jp_t) - 1) / 1) // 7 [15]. +#define cJ1_IMMED2_MAXPOP1 ((sizeof(jp_t) - 1) / 2) // 3 [7]. +#define cJ1_IMMED3_MAXPOP1 ((sizeof(jp_t) - 1) / 3) // 2 [5]. + +#ifdef JU_64BIT +#define cJ1_IMMED4_MAXPOP1 ((sizeof(jp_t) - 1) / 4) // [3]. +#define cJ1_IMMED5_MAXPOP1 ((sizeof(jp_t) - 1) / 5) // [3]. +#define cJ1_IMMED6_MAXPOP1 ((sizeof(jp_t) - 1) / 6) // [2]. +#define cJ1_IMMED7_MAXPOP1 ((sizeof(jp_t) - 1) / 7) // [2]. +#endif + + +// **************************************************************************** +// JUDY1 BITMAP LEAF (J1LB) SUPPORT +// **************************************************************************** + +#define J1_JLB_BITMAP(Pjlb,Subexp) ((Pjlb)->j1lb_Bitmap[Subexp]) + +typedef struct J__UDY1_BITMAP_LEAF +{ + BITMAPL_t j1lb_Bitmap[cJU_NUMSUBEXPL]; + +} j1lb_t, * Pj1lb_t; + + +// **************************************************************************** +// MEMORY ALLOCATION SUPPORT +// **************************************************************************** + +// ARRAY-GLOBAL INFORMATION: +// +// At the cost of an occasional additional cache fill, this object, which is +// pointed at by a JRP and in turn points to a JP_BRANCH*, carries array-global +// information about a Judy1 array that has sufficient population to amortize +// the cost. The jpm_Pop0 field prevents having to add up the total population +// for the array in insert, delete, and count code. The jpm_JP field prevents +// having to build a fake JP for entry to a state machine; however, the +// jp_DcdPopO field in jpm_JP, being one byte too small, is not used. +// +// Note: Struct fields are ordered to keep "hot" data in the first 8 words +// (see left-margin comments) for machines with 8-word cache lines, and to keep +// sub-word fields together for efficient packing. + +typedef struct J_UDY1_POPULATION_AND_MEMORY +{ +/* 1 */ Word_t jpm_Pop0; // total population-1 in array. +/* 2 */ jp_t jpm_JP; // JP to first branch; see above. +/* 4 */ Word_t jpm_LastUPop0; // last jpm_Pop0 when convert to BranchU +// Note: Field names match PJError_t for convenience in macros: +/* 7 */ char je_Errno; // one of the enums in Judy.h. +/* 7/8 */ int je_ErrID; // often an internal source line number. +/* 8/9 */ Word_t jpm_TotalMemWords; // words allocated in array. +} j1pm_t, *Pj1pm_t; + + +// TABLES FOR DETERMINING IF LEAVES HAVE ROOM TO GROW: +// +// These tables indicate if a given memory chunk can support growth of a given +// object into wasted (rounded-up) memory in the chunk. This violates the +// hiddenness of the JudyMalloc code. +// +// Also define macros to hide the details in the code using these tables. + +#ifndef JU_64BIT +extern const uint8_t j__1_Leaf1PopToWords[cJ1_LEAF1_MAXPOP1 + 1]; +#endif +extern const uint8_t j__1_Leaf2PopToWords[cJ1_LEAF2_MAXPOP1 + 1]; +extern const uint8_t j__1_Leaf3PopToWords[cJ1_LEAF3_MAXPOP1 + 1]; +#ifdef JU_64BIT +extern const uint8_t j__1_Leaf4PopToWords[cJ1_LEAF4_MAXPOP1 + 1]; +extern const uint8_t j__1_Leaf5PopToWords[cJ1_LEAF5_MAXPOP1 + 1]; +extern const uint8_t j__1_Leaf6PopToWords[cJ1_LEAF6_MAXPOP1 + 1]; +extern const uint8_t j__1_Leaf7PopToWords[cJ1_LEAF7_MAXPOP1 + 1]; +#endif +extern const uint8_t j__1_LeafWPopToWords[cJ1_LEAFW_MAXPOP1 + 1]; + +// Check if increase of population will fit in same leaf: + +#ifndef JU_64BIT +#define J1_LEAF1GROWINPLACE(Pop1) \ + J__U_GROWCK(Pop1, cJ1_LEAF1_MAXPOP1, j__1_Leaf1PopToWords) +#endif +#define J1_LEAF2GROWINPLACE(Pop1) \ + J__U_GROWCK(Pop1, cJ1_LEAF2_MAXPOP1, j__1_Leaf2PopToWords) +#define J1_LEAF3GROWINPLACE(Pop1) \ + J__U_GROWCK(Pop1, cJ1_LEAF3_MAXPOP1, j__1_Leaf3PopToWords) +#ifdef JU_64BIT +#define J1_LEAF4GROWINPLACE(Pop1) \ + J__U_GROWCK(Pop1, cJ1_LEAF4_MAXPOP1, j__1_Leaf4PopToWords) +#define J1_LEAF5GROWINPLACE(Pop1) \ + J__U_GROWCK(Pop1, cJ1_LEAF5_MAXPOP1, j__1_Leaf5PopToWords) +#define J1_LEAF6GROWINPLACE(Pop1) \ + J__U_GROWCK(Pop1, cJ1_LEAF6_MAXPOP1, j__1_Leaf6PopToWords) +#define J1_LEAF7GROWINPLACE(Pop1) \ + J__U_GROWCK(Pop1, cJ1_LEAF7_MAXPOP1, j__1_Leaf7PopToWords) +#endif +#define J1_LEAFWGROWINPLACE(Pop1) \ + J__U_GROWCK(Pop1, cJ1_LEAFW_MAXPOP1, j__1_LeafWPopToWords) + +#ifndef JU_64BIT +#define J1_LEAF1POPTOWORDS(Pop1) (j__1_Leaf1PopToWords[Pop1]) +#endif +#define J1_LEAF2POPTOWORDS(Pop1) (j__1_Leaf2PopToWords[Pop1]) +#define J1_LEAF3POPTOWORDS(Pop1) (j__1_Leaf3PopToWords[Pop1]) +#ifdef JU_64BIT +#define J1_LEAF4POPTOWORDS(Pop1) (j__1_Leaf4PopToWords[Pop1]) +#define J1_LEAF5POPTOWORDS(Pop1) (j__1_Leaf5PopToWords[Pop1]) +#define J1_LEAF6POPTOWORDS(Pop1) (j__1_Leaf6PopToWords[Pop1]) +#define J1_LEAF7POPTOWORDS(Pop1) (j__1_Leaf7PopToWords[Pop1]) +#endif +#define J1_LEAFWPOPTOWORDS(Pop1) (j__1_LeafWPopToWords[Pop1]) + + +// FUNCTIONS TO ALLOCATE OBJECTS: + +Pj1pm_t j__udy1AllocJ1PM(void); // constant size. + +Pjbl_t j__udy1AllocJBL( Pj1pm_t); // constant size. +Pjbb_t j__udy1AllocJBB( Pj1pm_t); // constant size. +Pjp_t j__udy1AllocJBBJP(Word_t, Pj1pm_t); +Pjbu_t j__udy1AllocJBU( Pj1pm_t); // constant size. + +#ifndef JU_64BIT +Pjll_t j__udy1AllocJLL1( Word_t, Pj1pm_t); +#endif +Pjll_t j__udy1AllocJLL2( Word_t, Pj1pm_t); +Pjll_t j__udy1AllocJLL3( Word_t, Pj1pm_t); + +#ifdef JU_64BIT +Pjll_t j__udy1AllocJLL4( Word_t, Pj1pm_t); +Pjll_t j__udy1AllocJLL5( Word_t, Pj1pm_t); +Pjll_t j__udy1AllocJLL6( Word_t, Pj1pm_t); +Pjll_t j__udy1AllocJLL7( Word_t, Pj1pm_t); +#endif + +Pjlw_t j__udy1AllocJLW( Word_t ); // no Pj1pm needed. +Pj1lb_t j__udy1AllocJLB1( Pj1pm_t); // constant size. + + +// FUNCTIONS TO FREE OBJECTS: + +void j__udy1FreeJ1PM( Pj1pm_t, Pj1pm_t); // constant size. + +void j__udy1FreeJBL( Pjbl_t, Pj1pm_t); // constant size. +void j__udy1FreeJBB( Pjbb_t, Pj1pm_t); // constant size. +void j__udy1FreeJBBJP(Pjp_t, Word_t, Pj1pm_t); +void j__udy1FreeJBU( Pjbu_t, Pj1pm_t); // constant size. + +#ifndef JU_64BIT +void j__udy1FreeJLL1( Pjll_t, Word_t, Pj1pm_t); +#endif +void j__udy1FreeJLL2( Pjll_t, Word_t, Pj1pm_t); +void j__udy1FreeJLL3( Pjll_t, Word_t, Pj1pm_t); + +#ifdef JU_64BIT +void j__udy1FreeJLL4( Pjll_t, Word_t, Pj1pm_t); +void j__udy1FreeJLL5( Pjll_t, Word_t, Pj1pm_t); +void j__udy1FreeJLL6( Pjll_t, Word_t, Pj1pm_t); +void j__udy1FreeJLL7( Pjll_t, Word_t, Pj1pm_t); +#endif + +void j__udy1FreeJLW( Pjlw_t, Word_t, Pj1pm_t); +void j__udy1FreeJLB1( Pj1lb_t, Pj1pm_t); // constant size. +void j__udy1FreeSM( Pjp_t, Pj1pm_t); // everything below Pjp. + +#endif // ! _JUDY1_INCLUDED diff --git a/feeds/p4/libjudy/src/src/Judy1/Makefile.am b/feeds/p4/libjudy/src/src/Judy1/Makefile.am new file mode 100644 index 000000000..7c2d154fc --- /dev/null +++ b/feeds/p4/libjudy/src/src/Judy1/Makefile.am @@ -0,0 +1,114 @@ +INCLUDES = -I. -I.. -I../JudyCommon/ +AM_CFLAGS = -DJUDY1 @WARN_CFLAGS@ + +noinst_LTLIBRARIES = libJudy1.la libnext.la libprev.la libcount.la libinline.la + +libJudy1_la_SOURCES = Judy1Test.c Judy1Tables.c Judy1Set.c Judy1SetArray.c Judy1Unset.c Judy1Cascade.c Judy1Count.c Judy1CreateBranch.c Judy1Decascade.c Judy1First.c Judy1FreeArray.c Judy1InsertBranch.c Judy1MallocIF.c Judy1MemActive.c Judy1MemUsed.c + +libnext_la_SOURCES = Judy1Next.c Judy1NextEmpty.c +libnext_la_CFLAGS = $(AM_CFLAGS) -DJUDYNEXT + +libprev_la_SOURCES = Judy1Prev.c Judy1PrevEmpty.c +libprev_la_CFLAGS = $(AM_CFLAGS) -DJUDYPREV + +libcount_la_SOURCES = Judy1ByCount.c +libcount_la_CFLAGS = $(AM_CFLAGS) -DNOSMARTJBB -DNOSMARTJBU -DNOSMARTJLB + +libinline_la_SOURCES = j__udy1Test.c +libinline_la_CFLAGS = $(AM_CFLAGS) -DJUDYGETINLINE + +Judy1Tables.c: Judy1TablesGen.c + $(HOSTCC) $(INCLUDES) $(AM_CFLAGS)-DJU_64BIT $(HOSTCCFLAGS) -o Judy1TablesGen Judy1TablesGen.c; ./Judy1TablesGen + +Judy1ByCount.c:../JudyCommon/JudyByCount.c + cp -f ../JudyCommon/JudyByCount.c Judy1ByCount.c + +Judy1Cascade.c:../JudyCommon/JudyCascade.c + cp -f ../JudyCommon/JudyCascade.c Judy1Cascade.c + +Judy1Count.c:../JudyCommon/JudyCount.c + cp -f ../JudyCommon/JudyCount.c Judy1Count.c + +Judy1CreateBranch.c:../JudyCommon/JudyCreateBranch.c + cp -f ../JudyCommon/JudyCreateBranch.c Judy1CreateBranch.c + +Judy1Decascade.c:../JudyCommon/JudyDecascade.c + cp -f ../JudyCommon/JudyDecascade.c Judy1Decascade.c + +Judy1Unset.c:../JudyCommon/JudyDel.c + cp -f ../JudyCommon/JudyDel.c Judy1Unset.c + +Judy1First.c:../JudyCommon/JudyFirst.c + cp -f ../JudyCommon/JudyFirst.c Judy1First.c + +Judy1FreeArray.c:../JudyCommon/JudyFreeArray.c + cp -f ../JudyCommon/JudyFreeArray.c Judy1FreeArray.c + +Judy1Test.c:../JudyCommon/JudyGet.c + cp -f ../JudyCommon/JudyGet.c Judy1Test.c + +j__udy1Test.c:../JudyCommon/JudyGet.c + cp -f ../JudyCommon/JudyGet.c j__udy1Test.c + +Judy1SetArray.c:../JudyCommon/JudyInsArray.c + cp -f ../JudyCommon/JudyInsArray.c Judy1SetArray.c + +Judy1Set.c:../JudyCommon/JudyIns.c + cp -f ../JudyCommon/JudyIns.c Judy1Set.c + +Judy1InsertBranch.c:../JudyCommon/JudyInsertBranch.c + cp -f ../JudyCommon/JudyInsertBranch.c Judy1InsertBranch.c + +Judy1MallocIF.c:../JudyCommon/JudyMallocIF.c + cp -f ../JudyCommon/JudyMallocIF.c Judy1MallocIF.c + +Judy1MemActive.c:../JudyCommon/JudyMemActive.c + cp -f ../JudyCommon/JudyMemActive.c Judy1MemActive.c + +Judy1MemUsed.c:../JudyCommon/JudyMemUsed.c + cp -f ../JudyCommon/JudyMemUsed.c Judy1MemUsed.c + +Judy1Next.c:../JudyCommon/JudyPrevNext.c + cp -f ../JudyCommon/JudyPrevNext.c Judy1Next.c + +Judy1Prev.c:../JudyCommon/JudyPrevNext.c + cp -f ../JudyCommon/JudyPrevNext.c Judy1Prev.c + +Judy1NextEmpty.c:../JudyCommon/JudyPrevNextEmpty.c + cp -f ../JudyCommon/JudyPrevNextEmpty.c Judy1NextEmpty.c + +Judy1PrevEmpty.c:../JudyCommon/JudyPrevNextEmpty.c + cp -f ../JudyCommon/JudyPrevNextEmpty.c Judy1PrevEmpty.c + +Judy1TablesGen.c:../JudyCommon/JudyTables.c + cp -f ../JudyCommon/JudyTables.c Judy1TablesGen.c + +DISTCLEANFILES = .deps Makefile + +CLEANFILES = Judy1ByCount.c \ + Judy1Cascade.c \ + Judy1Count.c \ + Judy1CreateBranch.c \ + Judy1Decascade.c \ + Judy1Unset.c \ + Judy1First.c \ + Judy1FreeArray.c \ + Judy1Test.c \ + j__udy1Test.c \ + Judy1SetArray.c \ + Judy1Set.c \ + Judy1InsertBranch.c \ + Judy1MallocIF.c \ + Judy1MemActive.c \ + Judy1MemUsed.c \ + Judy1Next.c \ + Judy1Prev.c \ + Judy1NextEmpty.c \ + Judy1PrevEmpty.c \ + Judy1TablesGen.c \ + Judy1Tables.c \ + .libs \ + Judy1TablesGen \ + *.o \ + *.lo \ + *.la diff --git a/feeds/p4/libjudy/src/src/Judy1/README b/feeds/p4/libjudy/src/src/Judy1/README new file mode 100644 index 000000000..69c3d4be0 --- /dev/null +++ b/feeds/p4/libjudy/src/src/Judy1/README @@ -0,0 +1,11 @@ +# @(#) $Revision: 4.22 $ $Source: /judy/src/Judy1/README $ + +# This tree contains sources for the Judy1*() functions. +# +# Note: At one time, all of the Judy sources were split between Judy1/ and +# JudyL/ variants, but now most of them are merged in JudyCommon/ and this +# directory is vestigal. + +Judy1.h header for following functions + +lint.waivers see usage in makefile diff --git a/feeds/p4/libjudy/src/src/JudyCommon/JudyByCount.c b/feeds/p4/libjudy/src/src/JudyCommon/JudyByCount.c new file mode 100644 index 000000000..c5a004796 --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudyCommon/JudyByCount.c @@ -0,0 +1,954 @@ +// Copyright (C) 2000 - 2002 Hewlett-Packard Company +// +// This program is free software; you can redistribute it and/or modify it +// under the term of the GNU Lesser 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 Lesser General Public License +// for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// _________________ + +// @(#) $Revision: 4.28 $ $Source: /judy/src/JudyCommon/JudyByCount.c $ +// +// Judy*ByCount() function for Judy1 and JudyL. +// Compile with one of -DJUDY1 or -DJUDYL. +// +// Compile with -DNOSMARTJBB, -DNOSMARTJBU, and/or -DNOSMARTJLB to build a +// version with cache line optimizations deleted, for testing. +// +// Judy*ByCount() is a conceptual although not literal inverse of Judy*Count(). +// Judy*Count() takes a pair of Indexes, and allows finding the ordinal of a +// given Index (that is, its position in the list of valid indexes from the +// beginning) as a degenerate case, because in general the count between two +// Indexes, inclusive, is not always just the difference in their ordinals. +// However, it suffices for Judy*ByCount() to simply be an ordinal-to-Index +// mapper. +// +// Note: Like Judy*Count(), this code must "count sideways" in branches, which +// can result in a lot of cache line fills. However, unlike Judy*Count(), this +// code does not receive a specific Index, hence digit, where to start in each +// branch, so it cant accurately calculate cache line fills required in each +// direction. The best it can do is an approximation based on the total +// population of the expanse (pop1 from Pjp) and the ordinal of the target +// Index (see SETOFFSET()) within the expanse. +// +// Compile with -DSMARTMETRICS to obtain global variables containing smart +// cache line metrics. Note: Dont turn this on simultaneously for this file +// and JudyCount.c because they export the same globals. +// **************************************************************************** + +#if (! (defined(JUDY1) || defined(JUDYL))) +#error: One of -DJUDY1 or -DJUDYL must be specified. +#endif + +#ifdef JUDY1 +#include "Judy1.h" +#else +#include "JudyL.h" +#endif + +#include "JudyPrivate1L.h" + +// These are imported from JudyCount.c: +// +// TBD: Should this be in common code? Exported from a header file? + +#ifdef JUDY1 +extern Word_t j__udy1JPPop1(const Pjp_t Pjp); +#define j__udyJPPop1 j__udy1JPPop1 +#else +extern Word_t j__udyLJPPop1(const Pjp_t Pjp); +#define j__udyJPPop1 j__udyLJPPop1 +#endif + +// Avoid duplicate symbols since this file is multi-compiled: + +#ifdef SMARTMETRICS +#ifdef JUDY1 +Word_t jbb_upward = 0; // counts of directions taken: +Word_t jbb_downward = 0; +Word_t jbu_upward = 0; +Word_t jbu_downward = 0; +Word_t jlb_upward = 0; +Word_t jlb_downward = 0; +#else +extern Word_t jbb_upward; +extern Word_t jbb_downward; +extern Word_t jbu_upward; +extern Word_t jbu_downward; +extern Word_t jlb_upward; +extern Word_t jlb_downward; +#endif +#endif + + +// **************************************************************************** +// J U D Y 1 B Y C O U N T +// J U D Y L B Y C O U N T +// +// See the manual entry. + +#ifdef JUDY1 +FUNCTION int Judy1ByCount +#else +FUNCTION PPvoid_t JudyLByCount +#endif + ( + Pcvoid_t PArray, // root pointer to first branch/leaf in SM. + Word_t Count, // ordinal of Index to find, 1..MAX. + Word_t * PIndex, // to return found Index. + PJError_t PJError // optional, for returning error info. + ) +{ + Word_t Count0; // Count, base-0, to match pop0. + Word_t state; // current state in SM. + Word_t pop1; // of current branch or leaf, or of expanse. + Word_t pop1lower; // pop1 of expanses (JPs) below that for Count. + Word_t digit; // current word in branch. + Word_t jpcount; // JPs in a BranchB subexpanse. + long jpnum; // JP number in a branch (base 0). + long subexp; // for stepping through layer 1 (subexpanses). + int offset; // index ordinal within a leaf, base 0. + + Pjp_t Pjp; // current JP in branch. + Pjll_t Pjll; // current Judy linear leaf. + + +// CHECK FOR EMPTY ARRAY OR NULL PINDEX: + + if (PArray == (Pvoid_t) NULL) JU_RET_NOTFOUND; + + if (PIndex == (PWord_t) NULL) + { + JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX); + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + } + +// Convert Count to Count0; assume special case of Count = 0 maps to ~0, as +// desired, to represent the last index in a full array: +// +// Note: Think of Count0 as a reliable "number of Indexes below the target." + + Count0 = Count - 1; + assert((Count || Count0 == ~0)); // ensure CPU is sane about 0 - 1. + pop1lower = 0; + + if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW + { + Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf. + + if (Count0 > Pjlw[0]) JU_RET_NOTFOUND; // too high. + + *PIndex = Pjlw[Count]; // Index, base 1. + + JU_RET_FOUND_LEAFW(Pjlw, Pjlw[0] + 1, Count0); + } + else + { + Pjpm_t Pjpm = P_JPM(PArray); + + if (Count0 > (Pjpm->jpm_Pop0)) JU_RET_NOTFOUND; // too high. + + Pjp = &(Pjpm->jpm_JP); + pop1 = (Pjpm->jpm_Pop0) + 1; + +// goto SMByCount; + } + +// COMMON CODE: +// +// Prepare to handle a root-level or lower-level branch: Save the current +// state, obtain the total population for the branch in a state-dependent way, +// and then branch to common code for multiple cases. +// +// For root-level branches, the state is always cJU_ROOTSTATE, and the array +// population must already be set in pop1; it is not available in jp_DcdPopO. +// +// Note: The total population is only needed in cases where the common code +// "counts down" instead of up to minimize cache line fills. However, its +// available cheaply, and its better to do it with a constant shift (constant +// state value) instead of a variable shift later "when needed". + +#define PREPB_ROOT(Next) \ + state = cJU_ROOTSTATE; \ + goto Next + +// Use PREPB_DCD() to first copy the Dcd bytes to *PIndex if there are any +// (only if state < cJU_ROOTSTATE - 1): + +#define PREPB_DCD(Pjp,cState,Next) \ + JU_SETDCD(*PIndex, Pjp, cState); \ + PREPB((Pjp), cState, Next) + +#define PREPB(Pjp,cState,Next) \ + state = (cState); \ + pop1 = JU_JPBRANCH_POP0(Pjp, (cState)) + 1; \ + goto Next + +// Calculate whether the ordinal of an Index within a given expanse falls in +// the lower or upper half of the expanses population, taking care with +// unsigned math and boundary conditions: +// +// Note: Assume the ordinal falls within the expanses population, that is, +// 0 < (Count - Pop1lower) <= Pop1exp (assuming infinite math). +// +// Note: If the ordinal is the middle element, it doesnt matter whether +// LOWERHALF() is TRUE or FALSE. + +#define LOWERHALF(Count0,Pop1lower,Pop1exp) \ + (((Count0) - (Pop1lower)) < ((Pop1exp) / 2)) + +// Calculate the (signed) offset within a leaf to the desired ordinal (Count - +// Pop1lower; offset is one less), and optionally ensure its in range: + +#define SETOFFSET(Offset,Count0,Pop1lower,Pjp) \ + (Offset) = (Count0) - (Pop1lower); \ + assert((Offset) >= 0); \ + assert((Offset) <= JU_JPLEAF_POP0(Pjp)) + +// Variations for immediate indexes, with and without pop1-specific assertions: + +#define SETOFFSET_IMM_CK(Offset,Count0,Pop1lower,cPop1) \ + (Offset) = (Count0) - (Pop1lower); \ + assert((Offset) >= 0); \ + assert((Offset) < (cPop1)) + +#define SETOFFSET_IMM(Offset,Count0,Pop1lower) \ + (Offset) = (Count0) - (Pop1lower) + + +// STATE MACHINE -- TRAVERSE TREE: +// +// In branches, look for the expanse (digit), if any, where the total pop1 +// below or at that expanse would meet or exceed Count, meaning the Index must +// be in this expanse. + +SMByCount: // return here for next branch/leaf. + + switch (JU_JPTYPE(Pjp)) + { + + +// ---------------------------------------------------------------------------- +// LINEAR BRANCH; count populations in JPs in the JBL upwards until finding the +// expanse (digit) containing Count, and "recurse". +// +// Note: There are no null JPs in a JBL; watch out for pop1 == 0. +// +// Note: A JBL should always fit in one cache line => no need to count up +// versus down to save cache line fills. +// +// TBD: The previous is no longer true. Consider enhancing this code to count +// up/down, but it can wait for a later tuning phase. In the meantime, PREPB() +// sets pop1 for the whole array, but that value is not used here. 001215: +// Maybe its true again? + + case cJU_JPBRANCH_L2: PREPB_DCD(Pjp, 2, BranchL); +#ifndef JU_64BIT + case cJU_JPBRANCH_L3: PREPB( Pjp, 3, BranchL); +#else + case cJU_JPBRANCH_L3: PREPB_DCD(Pjp, 3, BranchL); + case cJU_JPBRANCH_L4: PREPB_DCD(Pjp, 4, BranchL); + case cJU_JPBRANCH_L5: PREPB_DCD(Pjp, 5, BranchL); + case cJU_JPBRANCH_L6: PREPB_DCD(Pjp, 6, BranchL); + case cJU_JPBRANCH_L7: PREPB( Pjp, 7, BranchL); +#endif + case cJU_JPBRANCH_L: PREPB_ROOT( BranchL); + { + Pjbl_t Pjbl; + +// Common code (state-independent) for all cases of linear branches: + +BranchL: + Pjbl = P_JBL(Pjp->jp_Addr); + + for (jpnum = 0; jpnum < (Pjbl->jbl_NumJPs); ++jpnum) + { + if ((pop1 = j__udyJPPop1((Pjbl->jbl_jp) + jpnum)) + == cJU_ALLONES) + { + JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + } + assert(pop1 != 0); + +// Warning: pop1lower and pop1 are unsigned, so do not subtract 1 and compare +// >=, but instead use the following expression: + + if (pop1lower + pop1 > Count0) // Index is in this expanse. + { + JU_SETDIGIT(*PIndex, Pjbl->jbl_Expanse[jpnum], state); + Pjp = (Pjbl->jbl_jp) + jpnum; + goto SMByCount; // look under this expanse. + } + + pop1lower += pop1; // add this JPs pop1. + } + + JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // should never get here. + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + + } // case cJU_JPBRANCH_L + + +// ---------------------------------------------------------------------------- +// BITMAP BRANCH; count populations in JPs in the JBB upwards or downwards +// until finding the expanse (digit) containing Count, and "recurse". +// +// Note: There are no null JPs in a JBB; watch out for pop1 == 0. + + case cJU_JPBRANCH_B2: PREPB_DCD(Pjp, 2, BranchB); +#ifndef JU_64BIT + case cJU_JPBRANCH_B3: PREPB( Pjp, 3, BranchB); +#else + case cJU_JPBRANCH_B3: PREPB_DCD(Pjp, 3, BranchB); + case cJU_JPBRANCH_B4: PREPB_DCD(Pjp, 4, BranchB); + case cJU_JPBRANCH_B5: PREPB_DCD(Pjp, 5, BranchB); + case cJU_JPBRANCH_B6: PREPB_DCD(Pjp, 6, BranchB); + case cJU_JPBRANCH_B7: PREPB( Pjp, 7, BranchB); +#endif + case cJU_JPBRANCH_B: PREPB_ROOT( BranchB); + { + Pjbb_t Pjbb; + +// Common code (state-independent) for all cases of bitmap branches: + +BranchB: + Pjbb = P_JBB(Pjp->jp_Addr); + +// Shorthand for one subexpanse in a bitmap and for one JP in a bitmap branch: +// +// Note: BMPJP0 exists separately to support assertions. + +#define BMPJP0(Subexp) (P_JP(JU_JBB_PJP(Pjbb, Subexp))) +#define BMPJP(Subexp,JPnum) (BMPJP0(Subexp) + (JPnum)) + + +// Common code for descending through a JP: +// +// Determine the digit for the expanse and save it in *PIndex; then "recurse". + +#define JBB_FOUNDEXPANSE \ + { \ + JU_BITMAPDIGITB(digit, subexp, JU_JBB_BITMAP(Pjbb,subexp), jpnum); \ + JU_SETDIGIT(*PIndex, digit, state); \ + Pjp = BMPJP(subexp, jpnum); \ + goto SMByCount; \ + } + + +#ifndef NOSMARTJBB // enable to turn off smart code for comparison purposes. + +// FIGURE OUT WHICH DIRECTION CAUSES FEWER CACHE LINE FILLS; adding the pop1s +// in JPs upwards, or subtracting the pop1s in JPs downwards: +// +// See header comments about limitations of this for Judy*ByCount(). + +#endif + +// COUNT UPWARD, adding each "below" JPs pop1: + +#ifndef NOSMARTJBB // enable to turn off smart code for comparison purposes. + + if (LOWERHALF(Count0, pop1lower, pop1)) + { +#endif +#ifdef SMARTMETRICS + ++jbb_upward; +#endif + for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp) + { + if ((jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb,subexp))) + && (BMPJP0(subexp) == (Pjp_t) NULL)) + { + JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // null ptr. + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + } + +// Note: An empty subexpanse (jpcount == 0) is handled "for free": + + for (jpnum = 0; jpnum < jpcount; ++jpnum) + { + if ((pop1 = j__udyJPPop1(BMPJP(subexp, jpnum))) + == cJU_ALLONES) + { + JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + } + assert(pop1 != 0); + +// Warning: pop1lower and pop1 are unsigned, see earlier comment: + + if (pop1lower + pop1 > Count0) + JBB_FOUNDEXPANSE; // Index is in this expanse. + + pop1lower += pop1; // add this JPs pop1. + } + } +#ifndef NOSMARTJBB // enable to turn off smart code for comparison purposes. + } + + +// COUNT DOWNWARD, subtracting each "above" JPs pop1 from the whole expanses +// pop1: + + else + { +#ifdef SMARTMETRICS + ++jbb_downward; +#endif + pop1lower += pop1; // add whole branch to start. + + for (subexp = cJU_NUMSUBEXPB - 1; subexp >= 0; --subexp) + { + if ((jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp))) + && (BMPJP0(subexp) == (Pjp_t) NULL)) + { + JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // null ptr. + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + } + +// Note: An empty subexpanse (jpcount == 0) is handled "for free": + + for (jpnum = jpcount - 1; jpnum >= 0; --jpnum) + { + if ((pop1 = j__udyJPPop1(BMPJP(subexp, jpnum))) + == cJU_ALLONES) + { + JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + } + assert(pop1 != 0); + +// Warning: pop1lower and pop1 are unsigned, see earlier comment: + + pop1lower -= pop1; + +// Beware unsigned math problems: + + if ((pop1lower == 0) || (pop1lower - 1 < Count0)) + JBB_FOUNDEXPANSE; // Index is in this expanse. + } + } + } +#endif // NOSMARTJBB + + JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // should never get here. + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + + } // case cJU_JPBRANCH_B + + +// ---------------------------------------------------------------------------- +// UNCOMPRESSED BRANCH; count populations in JPs in the JBU upwards or +// downwards until finding the expanse (digit) containing Count, and "recurse". + + case cJU_JPBRANCH_U2: PREPB_DCD(Pjp, 2, BranchU); +#ifndef JU_64BIT + case cJU_JPBRANCH_U3: PREPB( Pjp, 3, BranchU); +#else + case cJU_JPBRANCH_U3: PREPB_DCD(Pjp, 3, BranchU); + case cJU_JPBRANCH_U4: PREPB_DCD(Pjp, 4, BranchU); + case cJU_JPBRANCH_U5: PREPB_DCD(Pjp, 5, BranchU); + case cJU_JPBRANCH_U6: PREPB_DCD(Pjp, 6, BranchU); + case cJU_JPBRANCH_U7: PREPB( Pjp, 7, BranchU); +#endif + case cJU_JPBRANCH_U: PREPB_ROOT( BranchU); + { + Pjbu_t Pjbu; + +// Common code (state-independent) for all cases of uncompressed branches: + +BranchU: + Pjbu = P_JBU(Pjp->jp_Addr); + +// Common code for descending through a JP: +// +// Save the digit for the expanse in *PIndex, then "recurse". + +#define JBU_FOUNDEXPANSE \ + { \ + JU_SETDIGIT(*PIndex, jpnum, state); \ + Pjp = (Pjbu->jbu_jp) + jpnum; \ + goto SMByCount; \ + } + + +#ifndef NOSMARTJBU // enable to turn off smart code for comparison purposes. + +// FIGURE OUT WHICH DIRECTION CAUSES FEWER CACHE LINE FILLS; adding the pop1s +// in JPs upwards, or subtracting the pop1s in JPs downwards: +// +// See header comments about limitations of this for Judy*ByCount(). + +#endif + +// COUNT UPWARD, simply adding the pop1 of each JP: + +#ifndef NOSMARTJBU // enable to turn off smart code for comparison purposes. + + if (LOWERHALF(Count0, pop1lower, pop1)) + { +#endif +#ifdef SMARTMETRICS + ++jbu_upward; +#endif + + for (jpnum = 0; jpnum < cJU_BRANCHUNUMJPS; ++jpnum) + { + // shortcut, save a function call: + + if ((Pjbu->jbu_jp[jpnum].jp_Type) <= cJU_JPNULLMAX) + continue; + + if ((pop1 = j__udyJPPop1((Pjbu->jbu_jp) + jpnum)) + == cJU_ALLONES) + { + JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + } + assert(pop1 != 0); + +// Warning: pop1lower and pop1 are unsigned, see earlier comment: + + if (pop1lower + pop1 > Count0) + JBU_FOUNDEXPANSE; // Index is in this expanse. + + pop1lower += pop1; // add this JPs pop1. + } +#ifndef NOSMARTJBU // enable to turn off smart code for comparison purposes. + } + + +// COUNT DOWNWARD, subtracting the pop1 of each JP above from the whole +// expanses pop1: + + else + { +#ifdef SMARTMETRICS + ++jbu_downward; +#endif + pop1lower += pop1; // add whole branch to start. + + for (jpnum = cJU_BRANCHUNUMJPS - 1; jpnum >= 0; --jpnum) + { + // shortcut, save a function call: + + if ((Pjbu->jbu_jp[jpnum].jp_Type) <= cJU_JPNULLMAX) + continue; + + if ((pop1 = j__udyJPPop1(Pjbu->jbu_jp + jpnum)) + == cJU_ALLONES) + { + JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + } + assert(pop1 != 0); + +// Warning: pop1lower and pop1 are unsigned, see earlier comment: + + pop1lower -= pop1; + +// Beware unsigned math problems: + + if ((pop1lower == 0) || (pop1lower - 1 < Count0)) + JBU_FOUNDEXPANSE; // Index is in this expanse. + } + } +#endif // NOSMARTJBU + + JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // should never get here. + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + + } // case cJU_JPBRANCH_U + +// ---------------------------------------------------------------------------- +// LINEAR LEAF: +// +// Return the Index at the proper ordinal (see SETOFFSET()) in the leaf. First +// copy Dcd bytes, if there are any (only if state < cJU_ROOTSTATE - 1), to +// *PIndex. +// +// Note: The preceding branch traversal code MIGHT set pop1 for this expanse +// (linear leaf) as a side-effect, but dont depend on that (for JUDYL, which +// is the only cases that need it anyway). + +#define PREPL_DCD(cState) \ + JU_SETDCD(*PIndex, Pjp, cState); \ + PREPL + +#ifdef JUDY1 +#define PREPL_SETPOP1 // not needed in any cases. +#else +#define PREPL_SETPOP1 pop1 = JU_JPLEAF_POP0(Pjp) + 1 +#endif + +#define PREPL \ + Pjll = P_JLL(Pjp->jp_Addr); \ + PREPL_SETPOP1; \ + SETOFFSET(offset, Count0, pop1lower, Pjp) + +#if (defined(JUDYL) || (! defined(JU_64BIT))) + case cJU_JPLEAF1: + + PREPL_DCD(1); + JU_SETDIGIT1(*PIndex, ((uint8_t *) Pjll)[offset]); + JU_RET_FOUND_LEAF1(Pjll, pop1, offset); +#endif + + case cJU_JPLEAF2: + + PREPL_DCD(2); + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(2))) + | ((uint16_t *) Pjll)[offset]; + JU_RET_FOUND_LEAF2(Pjll, pop1, offset); + +#ifndef JU_64BIT + case cJU_JPLEAF3: + { + Word_t lsb; + PREPL; + JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (3 * offset)); + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb; + JU_RET_FOUND_LEAF3(Pjll, pop1, offset); + } + +#else + case cJU_JPLEAF3: + { + Word_t lsb; + PREPL_DCD(3); + JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (3 * offset)); + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb; + JU_RET_FOUND_LEAF3(Pjll, pop1, offset); + } + + case cJU_JPLEAF4: + + PREPL_DCD(4); + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(4))) + | ((uint32_t *) Pjll)[offset]; + JU_RET_FOUND_LEAF4(Pjll, pop1, offset); + + case cJU_JPLEAF5: + { + Word_t lsb; + PREPL_DCD(5); + JU_COPY5_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (5 * offset)); + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(5))) | lsb; + JU_RET_FOUND_LEAF5(Pjll, pop1, offset); + } + + case cJU_JPLEAF6: + { + Word_t lsb; + PREPL_DCD(6); + JU_COPY6_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (6 * offset)); + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(6))) | lsb; + JU_RET_FOUND_LEAF6(Pjll, pop1, offset); + } + + case cJU_JPLEAF7: + { + Word_t lsb; + PREPL; + JU_COPY7_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (7 * offset)); + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(7))) | lsb; + JU_RET_FOUND_LEAF7(Pjll, pop1, offset); + } +#endif + + +// ---------------------------------------------------------------------------- +// BITMAP LEAF: +// +// Return the Index at the proper ordinal (see SETOFFSET()) in the leaf by +// counting bits. First copy Dcd bytes (always present since state 1 < +// cJU_ROOTSTATE) to *PIndex. +// +// Note: The preceding branch traversal code MIGHT set pop1 for this expanse +// (bitmap leaf) as a side-effect, but dont depend on that. + + case cJU_JPLEAF_B1: + { + Pjlb_t Pjlb; + + JU_SETDCD(*PIndex, Pjp, 1); + Pjlb = P_JLB(Pjp->jp_Addr); + pop1 = JU_JPLEAF_POP0(Pjp) + 1; + +// COUNT UPWARD, adding the pop1 of each subexpanse: +// +// The entire bitmap should fit in one cache line, but still try to save some +// CPU time by counting the fewest possible number of subexpanses from the +// bitmap. +// +// See header comments about limitations of this for Judy*ByCount(). + +#ifndef NOSMARTJLB // enable to turn off smart code for comparison purposes. + + if (LOWERHALF(Count0, pop1lower, pop1)) + { +#endif +#ifdef SMARTMETRICS + ++jlb_upward; +#endif + for (subexp = 0; subexp < cJU_NUMSUBEXPL; ++subexp) + { + pop1 = j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp)); + +// Warning: pop1lower and pop1 are unsigned, see earlier comment: + + if (pop1lower + pop1 > Count0) + goto LeafB1; // Index is in this subexpanse. + + pop1lower += pop1; // add this subexpanses pop1. + } +#ifndef NOSMARTJLB // enable to turn off smart code for comparison purposes. + } + + +// COUNT DOWNWARD, subtracting each "above" subexpanses pop1 from the whole +// expanses pop1: + + else + { +#ifdef SMARTMETRICS + ++jlb_downward; +#endif + pop1lower += pop1; // add whole leaf to start. + + for (subexp = cJU_NUMSUBEXPL - 1; subexp >= 0; --subexp) + { + pop1lower -= j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp)); + +// Beware unsigned math problems: + + if ((pop1lower == 0) || (pop1lower - 1 < Count0)) + goto LeafB1; // Index is in this subexpanse. + } + } +#endif // NOSMARTJLB + + JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // should never get here. + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + + +// RETURN INDEX FOUND: +// +// Come here with subexp set to the correct subexpanse, and pop1lower set to +// the sum for all lower expanses and subexpanses in the Judy tree. Calculate +// and save in *PIndex the digit corresponding to the ordinal in this +// subexpanse. + +LeafB1: + SETOFFSET(offset, Count0, pop1lower, Pjp); + JU_BITMAPDIGITL(digit, subexp, JU_JLB_BITMAP(Pjlb, subexp), offset); + JU_SETDIGIT1(*PIndex, digit); + JU_RET_FOUND_LEAF_B1(Pjlb, subexp, offset); +// == return((PPvoid_t) (P_JV(JL_JLB_PVALUE(Pjlb, subexp)) + offset)) + + } // case cJU_JPLEAF_B1 + + +#ifdef JUDY1 +// ---------------------------------------------------------------------------- +// FULL POPULATION: +// +// Copy Dcd bytes (always present since state 1 < cJU_ROOTSTATE) to *PIndex, +// then set the appropriate digit for the ordinal (see SETOFFSET()) in the leaf +// as the LSB in *PIndex. + + case cJ1_JPFULLPOPU1: + + JU_SETDCD(*PIndex, Pjp, 1); + SETOFFSET(offset, Count0, pop1lower, Pjp); + assert(offset >= 0); + assert(offset <= cJU_JPFULLPOPU1_POP0); + JU_SETDIGIT1(*PIndex, offset); + JU_RET_FOUND_FULLPOPU1; +#endif + + +// ---------------------------------------------------------------------------- +// IMMEDIATE: +// +// Locate the Index with the proper ordinal (see SETOFFSET()) in the Immediate, +// depending on leaf Index Size and pop1. Note: There are no Dcd bytes in an +// Immediate JP, but in a cJU_JPIMMED_*_01 JP, the field holds the least bytes +// of the immediate Index. + +#define SET_01(cState) JU_SETDIGITS(*PIndex, JU_JPDCDPOP0(Pjp), cState) + + case cJU_JPIMMED_1_01: SET_01(1); goto Imm_01; + case cJU_JPIMMED_2_01: SET_01(2); goto Imm_01; + case cJU_JPIMMED_3_01: SET_01(3); goto Imm_01; +#ifdef JU_64BIT + case cJU_JPIMMED_4_01: SET_01(4); goto Imm_01; + case cJU_JPIMMED_5_01: SET_01(5); goto Imm_01; + case cJU_JPIMMED_6_01: SET_01(6); goto Imm_01; + case cJU_JPIMMED_7_01: SET_01(7); goto Imm_01; +#endif + +Imm_01: + + DBGCODE(SETOFFSET_IMM_CK(offset, Count0, pop1lower, 1);) + JU_RET_FOUND_IMM_01(Pjp); + +// Shorthand for where to find start of Index bytes array: + +#ifdef JUDY1 +#define PJI (Pjp->jp_1Index) +#else +#define PJI (Pjp->jp_LIndex) +#endif + +// Optional code to check the remaining ordinal (see SETOFFSET_IMM()) against +// the Index Size of the Immediate: + +#ifndef DEBUG // simple placeholder: +#define IMM(cPop1,Next) \ + goto Next +#else // extra pop1-specific checking: +#define IMM(cPop1,Next) \ + SETOFFSET_IMM_CK(offset, Count0, pop1lower, cPop1); \ + goto Next +#endif + + case cJU_JPIMMED_1_02: IMM( 2, Imm1); + case cJU_JPIMMED_1_03: IMM( 3, Imm1); +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_1_04: IMM( 4, Imm1); + case cJU_JPIMMED_1_05: IMM( 5, Imm1); + case cJU_JPIMMED_1_06: IMM( 6, Imm1); + case cJU_JPIMMED_1_07: IMM( 7, Imm1); +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_1_08: IMM( 8, Imm1); + case cJ1_JPIMMED_1_09: IMM( 9, Imm1); + case cJ1_JPIMMED_1_10: IMM(10, Imm1); + case cJ1_JPIMMED_1_11: IMM(11, Imm1); + case cJ1_JPIMMED_1_12: IMM(12, Imm1); + case cJ1_JPIMMED_1_13: IMM(13, Imm1); + case cJ1_JPIMMED_1_14: IMM(14, Imm1); + case cJ1_JPIMMED_1_15: IMM(15, Imm1); +#endif + +Imm1: SETOFFSET_IMM(offset, Count0, pop1lower); + JU_SETDIGIT1(*PIndex, ((uint8_t *) PJI)[offset]); + JU_RET_FOUND_IMM(Pjp, offset); + +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_2_02: IMM(2, Imm2); + case cJU_JPIMMED_2_03: IMM(3, Imm2); +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_2_04: IMM(4, Imm2); + case cJ1_JPIMMED_2_05: IMM(5, Imm2); + case cJ1_JPIMMED_2_06: IMM(6, Imm2); + case cJ1_JPIMMED_2_07: IMM(7, Imm2); +#endif + +#if (defined(JUDY1) || defined(JU_64BIT)) +Imm2: SETOFFSET_IMM(offset, Count0, pop1lower); + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(2))) + | ((uint16_t *) PJI)[offset]; + JU_RET_FOUND_IMM(Pjp, offset); +#endif + +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_3_02: IMM(2, Imm3); +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_3_03: IMM(3, Imm3); + case cJ1_JPIMMED_3_04: IMM(4, Imm3); + case cJ1_JPIMMED_3_05: IMM(5, Imm3); +#endif + +#if (defined(JUDY1) || defined(JU_64BIT)) +Imm3: + { + Word_t lsb; + SETOFFSET_IMM(offset, Count0, pop1lower); + JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (3 * offset)); + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb; + JU_RET_FOUND_IMM(Pjp, offset); + } +#endif + +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_4_02: IMM(2, Imm4); + case cJ1_JPIMMED_4_03: IMM(3, Imm4); + +Imm4: SETOFFSET_IMM(offset, Count0, pop1lower); + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(4))) + | ((uint32_t *) PJI)[offset]; + JU_RET_FOUND_IMM(Pjp, offset); + + case cJ1_JPIMMED_5_02: IMM(2, Imm5); + case cJ1_JPIMMED_5_03: IMM(3, Imm5); + +Imm5: + { + Word_t lsb; + SETOFFSET_IMM(offset, Count0, pop1lower); + JU_COPY5_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (5 * offset)); + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(5))) | lsb; + JU_RET_FOUND_IMM(Pjp, offset); + } + + case cJ1_JPIMMED_6_02: IMM(2, Imm6); + +Imm6: + { + Word_t lsb; + SETOFFSET_IMM(offset, Count0, pop1lower); + JU_COPY6_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (6 * offset)); + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(6))) | lsb; + JU_RET_FOUND_IMM(Pjp, offset); + } + + case cJ1_JPIMMED_7_02: IMM(2, Imm7); + +Imm7: + { + Word_t lsb; + SETOFFSET_IMM(offset, Count0, pop1lower); + JU_COPY7_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (7 * offset)); + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(7))) | lsb; + JU_RET_FOUND_IMM(Pjp, offset); + } +#endif // (JUDY1 && JU_64BIT) + + +// ---------------------------------------------------------------------------- +// UNEXPECTED JP TYPES: + + default: JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + + } // SMByCount switch. + + /*NOTREACHED*/ + +} // Judy1ByCount() / JudyLByCount() diff --git a/feeds/p4/libjudy/src/src/JudyCommon/JudyCascade.c b/feeds/p4/libjudy/src/src/JudyCommon/JudyCascade.c new file mode 100644 index 000000000..6b52ddf5f --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudyCommon/JudyCascade.c @@ -0,0 +1,1942 @@ +// Copyright (C) 2000 - 2002 Hewlett-Packard Company +// +// This program is free software; you can redistribute it and/or modify it +// under the term of the GNU Lesser 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 Lesser General Public License +// for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// _________________ + +// @(#) $Revision: 4.38 $ $Source: /judy/src/JudyCommon/JudyCascade.c $ + +#ifdef JUDY1 +#include "Judy1.h" +#else +#include "JudyL.h" +#endif + +#include "JudyPrivate1L.h" + +extern int j__udyCreateBranchL(Pjp_t, Pjp_t, uint8_t *, Word_t, Pvoid_t); +extern int j__udyCreateBranchB(Pjp_t, Pjp_t, uint8_t *, Word_t, Pvoid_t); + +DBGCODE(extern void JudyCheckSorted(Pjll_t Pjll, Word_t Pop1, long IndexSize);) + +static const jbb_t StageJBBZero; // zeroed versions of namesake struct. + +// TBD: There are multiple copies of (some of) these CopyWto3, Copy3toW, +// CopyWto7 and Copy7toW functions in Judy1Cascade.c, JudyLCascade.c, and +// JudyDecascade.c. These static functions should probably be moved to a +// common place, made macros, or something to avoid having four copies. + + +// **************************************************************************** +// __ J U D Y C O P Y X T O W + + +FUNCTION static void j__udyCopy3toW( + PWord_t PDest, + uint8_t * PSrc, + Word_t LeafIndexes) +{ + do + { + JU_COPY3_PINDEX_TO_LONG(*PDest, PSrc); + PSrc += 3; + PDest += 1; + + } while(--LeafIndexes); + +} //j__udyCopy3toW() + + +#ifdef JU_64BIT + +FUNCTION static void j__udyCopy4toW( + PWord_t PDest, + uint32_t * PSrc, + Word_t LeafIndexes) +{ + do { *PDest++ = *PSrc++; + } while(--LeafIndexes); + +} // j__udyCopy4toW() + + +FUNCTION static void j__udyCopy5toW( + PWord_t PDest, + uint8_t * PSrc, + Word_t LeafIndexes) +{ + do + { + JU_COPY5_PINDEX_TO_LONG(*PDest, PSrc); + PSrc += 5; + PDest += 1; + + } while(--LeafIndexes); + +} // j__udyCopy5toW() + + +FUNCTION static void j__udyCopy6toW( + PWord_t PDest, + uint8_t * PSrc, + Word_t LeafIndexes) +{ + do + { + JU_COPY6_PINDEX_TO_LONG(*PDest, PSrc); + PSrc += 6; + PDest += 1; + + } while(--LeafIndexes); + +} // j__udyCopy6toW() + + +FUNCTION static void j__udyCopy7toW( + PWord_t PDest, + uint8_t * PSrc, + Word_t LeafIndexes) +{ + do + { + JU_COPY7_PINDEX_TO_LONG(*PDest, PSrc); + PSrc += 7; + PDest += 1; + + } while(--LeafIndexes); + +} // j__udyCopy7toW() + +#endif // JU_64BIT + + +// **************************************************************************** +// __ J U D Y C O P Y W T O X + + +FUNCTION static void j__udyCopyWto3( + uint8_t * PDest, + PWord_t PSrc, + Word_t LeafIndexes) +{ + do + { + JU_COPY3_LONG_TO_PINDEX(PDest, *PSrc); + PSrc += 1; + PDest += 3; + + } while(--LeafIndexes); + +} // j__udyCopyWto3() + + +#ifdef JU_64BIT + +FUNCTION static void j__udyCopyWto4( + uint8_t * PDest, + PWord_t PSrc, + Word_t LeafIndexes) +{ + uint32_t *PDest32 = (uint32_t *)PDest; + + do + { + *PDest32 = *PSrc; + PSrc += 1; + PDest32 += 1; + } while(--LeafIndexes); + +} // j__udyCopyWto4() + + +FUNCTION static void j__udyCopyWto5( + uint8_t * PDest, + PWord_t PSrc, + Word_t LeafIndexes) +{ + do + { + JU_COPY5_LONG_TO_PINDEX(PDest, *PSrc); + PSrc += 1; + PDest += 5; + + } while(--LeafIndexes); + +} // j__udyCopyWto5() + + +FUNCTION static void j__udyCopyWto6( + uint8_t * PDest, + PWord_t PSrc, + Word_t LeafIndexes) +{ + do + { + JU_COPY6_LONG_TO_PINDEX(PDest, *PSrc); + PSrc += 1; + PDest += 6; + + } while(--LeafIndexes); + +} // j__udyCopyWto6() + + +FUNCTION static void j__udyCopyWto7( + uint8_t * PDest, + PWord_t PSrc, + Word_t LeafIndexes) +{ + do + { + JU_COPY7_LONG_TO_PINDEX(PDest, *PSrc); + PSrc += 1; + PDest += 7; + + } while(--LeafIndexes); + +} // j__udyCopyWto7() + +#endif // JU_64BIT + + +// **************************************************************************** +// COMMON CODE (MACROS): +// +// Free objects in an array of valid JPs, StageJP[ExpCnt] == last one may +// include Immeds, which are ignored. + +#define FREEALLEXIT(ExpCnt,StageJP,Pjpm) \ + { \ + Word_t _expct = (ExpCnt); \ + while (_expct--) j__udyFreeSM(&((StageJP)[_expct]), Pjpm); \ + return(-1); \ + } + +// Clear the array that keeps track of the number of JPs in a subexpanse: + +#define ZEROJP(SubJPCount) \ + { \ + int ii; \ + for (ii = 0; ii < cJU_NUMSUBEXPB; ii++) (SubJPCount[ii]) = 0; \ + } + +// **************************************************************************** +// __ J U D Y S T A G E J B B T O J B B +// +// Create a mallocd BranchB (jbb_t) from a staged BranchB while "splaying" a +// single old leaf. Return -1 if out of memory, otherwise 1. + +static int j__udyStageJBBtoJBB( + Pjp_t PjpLeaf, // JP of leaf being splayed. + Pjbb_t PStageJBB, // temp jbb_t on stack. + Pjp_t PjpArray, // array of JPs to splayed new leaves. + uint8_t * PSubCount, // count of JPs for each subexpanse. + Pjpm_t Pjpm) // the jpm_t for JudyAlloc*(). +{ + Pjbb_t PjbbRaw; // pointer to new bitmap branch. + Pjbb_t Pjbb; + Word_t subexp; + +// Get memory for new BranchB: + + if ((PjbbRaw = j__udyAllocJBB(Pjpm)) == (Pjbb_t) NULL) return(-1); + Pjbb = P_JBB(PjbbRaw); + +// Copy staged BranchB into just-allocated BranchB: + + *Pjbb = *PStageJBB; + +// Allocate the JP subarrays (BJP) for the new BranchB: + + for (subexp = 0; subexp < cJU_NUMSUBEXPB; subexp++) + { + Pjp_t PjpRaw; + Pjp_t Pjp; + Word_t NumJP; // number of JPs in each subexpanse. + + if ((NumJP = PSubCount[subexp]) == 0) continue; // empty. + +// Out of memory, back out previous allocations: + + if ((PjpRaw = j__udyAllocJBBJP(NumJP, Pjpm)) == (Pjp_t) NULL) + { + while(subexp--) + { + if ((NumJP = PSubCount[subexp]) == 0) continue; + + PjpRaw = JU_JBB_PJP(Pjbb, subexp); + j__udyFreeJBBJP(PjpRaw, NumJP, Pjpm); + } + j__udyFreeJBB(PjbbRaw, Pjpm); + return(-1); // out of memory. + } + Pjp = P_JP(PjpRaw); + +// Place the JP subarray pointer in the new BranchB, copy subarray JPs, and +// advance to the next subexpanse: + + JU_JBB_PJP(Pjbb, subexp) = PjpRaw; + JU_COPYMEM(Pjp, PjpArray, NumJP); + PjpArray += NumJP; + + } // for each subexpanse. + +// Change the PjpLeaf from Leaf to BranchB: + + PjpLeaf->jp_Addr = (Word_t) PjbbRaw; + PjpLeaf->jp_Type += cJU_JPBRANCH_B2 - cJU_JPLEAF2; // Leaf to BranchB. + + return(1); + +} // j__udyStageJBBtoJBB() + + +// **************************************************************************** +// __ J U D Y J L L 2 T O J L B 1 +// +// Create a LeafB1 (jlb_t = JLB1) from a Leaf2 (2-byte Indexes and for JudyL, +// Word_t Values). Return NULL if out of memory, else a pointer to the new +// LeafB1. +// +// NOTE: Caller must release the Leaf2 that was passed in. + +FUNCTION static Pjlb_t j__udyJLL2toJLB1( + uint16_t * Pjll, // array of 16-bit indexes. +#ifdef JUDYL + Pjv_t Pjv, // array of associated values. +#endif + Word_t LeafPop1, // number of indexes/values. + Pvoid_t Pjpm) // jpm_t for JudyAlloc*()/JudyFree*(). +{ + Pjlb_t PjlbRaw; + Pjlb_t Pjlb; + int offset; +JUDYLCODE(int subexp;) + +// Allocate the LeafB1: + + if ((PjlbRaw = j__udyAllocJLB1(Pjpm)) == (Pjlb_t) NULL) + return((Pjlb_t) NULL); + Pjlb = P_JLB(PjlbRaw); + +// Copy Leaf2 indexes to LeafB1: + + for (offset = 0; offset < LeafPop1; ++offset) + JU_BITMAPSETL(Pjlb, Pjll[offset]); + +#ifdef JUDYL + +// Build LeafVs from bitmap: + + for (subexp = 0; subexp < cJU_NUMSUBEXPL; ++subexp) + { + struct _POINTER_VALUES + { + Word_t pv_Pop1; // size of value area. + Pjv_t pv_Pjv; // raw pointer to value area. + } pv[cJU_NUMSUBEXPL]; + +// Get the population of the subexpanse, and if any, allocate a LeafV: + + pv[subexp].pv_Pop1 = j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp)); + + if (pv[subexp].pv_Pop1) + { + Pjv_t Pjvnew; + +// TBD: There is an opportunity to put pop == 1 value in pointer: + + pv[subexp].pv_Pjv = j__udyLAllocJV(pv[subexp].pv_Pop1, Pjpm); + +// Upon out of memory, free all previously allocated: + + if (pv[subexp].pv_Pjv == (Pjv_t) NULL) + { + while(subexp--) + { + if (pv[subexp].pv_Pop1) + { + j__udyLFreeJV(pv[subexp].pv_Pjv, pv[subexp].pv_Pop1, + Pjpm); + } + } + j__udyFreeJLB1(PjlbRaw, Pjpm); + return((Pjlb_t) NULL); + } + + Pjvnew = P_JV(pv[subexp].pv_Pjv); + JU_COPYMEM(Pjvnew, Pjv, pv[subexp].pv_Pop1); + Pjv += pv[subexp].pv_Pop1; // advance value pointer. + +// Place raw pointer to value array in bitmap subexpanse: + + JL_JLB_PVALUE(Pjlb, subexp) = pv[subexp].pv_Pjv; + + } // populated subexpanse. + } // each subexpanse. + +#endif // JUDYL + + return(PjlbRaw); // pointer to LeafB1. + +} // j__udyJLL2toJLB1() + + +// **************************************************************************** +// __ J U D Y C A S C A D E 1 +// +// Create bitmap leaf from 1-byte Indexes and Word_t Values. +// +// TBD: There must be a better way. +// +// Only for JudyL 32 bit: (note, unifdef disallows comment on next line) + +#if (defined(JUDYL) || (! defined(JU_64BIT))) + +FUNCTION int j__udyCascade1( + Pjp_t Pjp, + Pvoid_t Pjpm) +{ + Word_t DcdP0; + uint8_t * PLeaf; + Pjlb_t PjlbRaw; + Pjlb_t Pjlb; + Word_t Pop1; + Word_t ii; // temp for loop counter +JUDYLCODE(Pjv_t Pjv;) + + assert(JU_JPTYPE(Pjp) == cJU_JPLEAF1); + assert((JU_JPDCDPOP0(Pjp) & 0xFF) == (cJU_LEAF1_MAXPOP1-1)); + + PjlbRaw = j__udyAllocJLB1(Pjpm); + if (PjlbRaw == (Pjlb_t) NULL) return(-1); + + Pjlb = P_JLB(PjlbRaw); + PLeaf = (uint8_t *) P_JLL(Pjp->jp_Addr); + Pop1 = JU_JPLEAF_POP0(Pjp) + 1; + + JUDYLCODE(Pjv = JL_LEAF1VALUEAREA(PLeaf, Pop1);) + +// Copy 1 byte index Leaf to bitmap Leaf + for (ii = 0; ii < Pop1; ii++) JU_BITMAPSETL(Pjlb, PLeaf[ii]); + +#ifdef JUDYL +// Build 8 subexpanse Value leaves from bitmap + for (ii = 0; ii < cJU_NUMSUBEXPL; ii++) + { +// Get number of Indexes in subexpanse + if ((Pop1 = j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, ii)))) + { + Pjv_t PjvnewRaw; // value area of new leaf. + Pjv_t Pjvnew; + + PjvnewRaw = j__udyLAllocJV(Pop1, Pjpm); + if (PjvnewRaw == (Pjv_t) NULL) // out of memory. + { +// Free prevously allocated LeafVs: + while(ii--) + { + if ((Pop1 = j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, ii)))) + { + PjvnewRaw = JL_JLB_PVALUE(Pjlb, ii); + j__udyLFreeJV(PjvnewRaw, Pop1, Pjpm); + } + } +// Free the bitmap leaf + j__udyLFreeJLB1(PjlbRaw,Pjpm); + return(-1); + } + Pjvnew = P_JV(PjvnewRaw); + JU_COPYMEM(Pjvnew, Pjv, Pop1); + + Pjv += Pop1; + JL_JLB_PVALUE(Pjlb, ii) = PjvnewRaw; + } + } +#endif // JUDYL + + DcdP0 = JU_JPDCDPOP0(Pjp) | (PLeaf[0] & cJU_DCDMASK(1)); + JU_JPSETADT(Pjp, (Word_t)PjlbRaw, DcdP0, cJU_JPLEAF_B1); + + return(1); // return success + +} // j__udyCascade1() + +#endif // (!(JUDY1 && JU_64BIT)) + + +// **************************************************************************** +// __ J U D Y C A S C A D E 2 +// +// Entry PLeaf of size LeafPop1 is either compressed or splayed with pointer +// returned in Pjp. Entry Levels sizeof(Word_t) down to level 2. +// +// Splay or compress the 2-byte Index Leaf that Pjp point to. Return *Pjp as a +// (compressed) cJU_LEAFB1 or a cJU_BRANCH_*2 + +FUNCTION int j__udyCascade2( + Pjp_t Pjp, + Pvoid_t Pjpm) +{ + uint16_t * PLeaf; // pointer to leaf, explicit type. + Word_t End, Start; // temporaries. + Word_t ExpCnt; // count of expanses of splay. + Word_t CIndex; // current Index word. +JUDYLCODE(Pjv_t Pjv;) // value area of leaf. + +// Temp staging for parts(Leaves) of newly splayed leaf + jp_t StageJP [cJU_LEAF2_MAXPOP1]; // JPs of new leaves + uint8_t StageExp [cJU_LEAF2_MAXPOP1]; // Expanses of new leaves + uint8_t SubJPCount[cJU_NUMSUBEXPB]; // JPs in each subexpanse + jbb_t StageJBB; // staged bitmap branch + + assert(JU_JPTYPE(Pjp) == cJU_JPLEAF2); + assert((JU_JPDCDPOP0(Pjp) & 0xFFFF) == (cJU_LEAF2_MAXPOP1-1)); + +// Get the address of the Leaf + PLeaf = (uint16_t *) P_JLL(Pjp->jp_Addr); + +// And its Value area + JUDYLCODE(Pjv = JL_LEAF2VALUEAREA(PLeaf, cJU_LEAF2_MAXPOP1);) + +// If Leaf is in 1 expanse -- just compress it to a Bitmap Leaf + + CIndex = PLeaf[0]; + if (!JU_DIGITATSTATE(CIndex ^ PLeaf[cJU_LEAF2_MAXPOP1-1], 2)) + { +// cJU_JPLEAF_B1 + Word_t DcdP0; + Pjlb_t PjlbRaw; + PjlbRaw = j__udyJLL2toJLB1(PLeaf, +#ifdef JUDYL + Pjv, +#endif + cJU_LEAF2_MAXPOP1, Pjpm); + if (PjlbRaw == (Pjlb_t)NULL) return(-1); // out of memory + +// Merge in another Dcd byte because compressing + DcdP0 = (CIndex & cJU_DCDMASK(1)) | JU_JPDCDPOP0(Pjp); + JU_JPSETADT(Pjp, (Word_t)PjlbRaw, DcdP0, cJU_JPLEAF_B1); + + return(1); + } + +// Else in 2+ expanses, splay Leaf into smaller leaves at higher compression + + StageJBB = StageJBBZero; // zero staged bitmap branch + ZEROJP(SubJPCount); + +// Splay the 2 byte index Leaf to 1 byte Index Leaves + for (ExpCnt = Start = 0, End = 1; ; End++) + { +// Check if new expanse or last one + if ( (End == cJU_LEAF2_MAXPOP1) + || + (JU_DIGITATSTATE(CIndex ^ PLeaf[End], 2)) + ) + { +// Build a leaf below the previous expanse +// + Pjp_t PjpJP = StageJP + ExpCnt; + Word_t Pop1 = End - Start; + Word_t expanse = JU_DIGITATSTATE(CIndex, 2); + Word_t subexp = expanse / cJU_BITSPERSUBEXPB; +// +// set the bit that is the current expanse + JU_JBB_BITMAP(&StageJBB, subexp) |= JU_BITPOSMASKB(expanse); +#ifdef SUBEXPCOUNTS + StageJBB.jbb_subPop1[subexp] += Pop1; // pop of subexpanse +#endif +// count number of expanses in each subexpanse + SubJPCount[subexp]++; + +// Save byte expanse of leaf + StageExp[ExpCnt] = JU_DIGITATSTATE(CIndex, 2); + + if (Pop1 == 1) // cJU_JPIMMED_1_01 + { + Word_t DcdP0; + DcdP0 = (JU_JPDCDPOP0(Pjp) & cJU_DCDMASK(1)) | + CIndex; +#ifdef JUDY1 + JU_JPSETADT(PjpJP, 0, DcdP0, cJ1_JPIMMED_1_01); +#else // JUDYL + JU_JPSETADT(PjpJP, Pjv[Start], DcdP0, + cJL_JPIMMED_1_01); +#endif // JUDYL + } + else if (Pop1 <= cJU_IMMED1_MAXPOP1) // bigger + { +// cJL_JPIMMED_1_02..3: JudyL 32 +// cJ1_JPIMMED_1_02..7: Judy1 32 +// cJL_JPIMMED_1_02..7: JudyL 64 +// cJ1_JPIMMED_1_02..15: Judy1 64 +#ifdef JUDYL + Pjv_t PjvnewRaw; // value area of leaf. + Pjv_t Pjvnew; + +// Allocate Value area for Immediate Leaf + PjvnewRaw = j__udyLAllocJV(Pop1, Pjpm); + if (PjvnewRaw == (Pjv_t) NULL) + FREEALLEXIT(ExpCnt, StageJP, Pjpm); + + Pjvnew = P_JV(PjvnewRaw); + +// Copy to Values to Value Leaf + JU_COPYMEM(Pjvnew, Pjv + Start, Pop1); + PjpJP->jp_Addr = (Word_t) PjvnewRaw; + +// Copy to JP as an immediate Leaf + JU_COPYMEM(PjpJP->jp_LIndex, PLeaf + Start, + Pop1); +#else + JU_COPYMEM(PjpJP->jp_1Index, PLeaf + Start, + Pop1); +#endif +// Set Type, Population and Index size + PjpJP->jp_Type = cJU_JPIMMED_1_02 + Pop1 - 2; + } + +// 64Bit Judy1 does not have Leaf1: (note, unifdef disallows comment on next +// line) + +#if (! (defined(JUDY1) && defined(JU_64BIT))) + else if (Pop1 <= cJU_LEAF1_MAXPOP1) // still bigger + { +// cJU_JPLEAF1 + Word_t DcdP0; + Pjll_t PjllRaw; // pointer to new leaf. + Pjll_t Pjll; + JUDYLCODE(Pjv_t Pjvnew;) // value area of new leaf. + +// Get a new Leaf + PjllRaw = j__udyAllocJLL1(Pop1, Pjpm); + if (PjllRaw == (Pjll_t)NULL) + FREEALLEXIT(ExpCnt, StageJP, Pjpm); + + Pjll = P_JLL(PjllRaw); +#ifdef JUDYL +// Copy to Values to new Leaf + Pjvnew = JL_LEAF1VALUEAREA(Pjll, Pop1); + JU_COPYMEM(Pjvnew, Pjv + Start, Pop1); +#endif +// Copy Indexes to new Leaf + JU_COPYMEM((uint8_t *)Pjll, PLeaf+Start, Pop1); + + DBGCODE(JudyCheckSorted(Pjll, Pop1, 1);) + + DcdP0 = (JU_JPDCDPOP0(Pjp) & cJU_DCDMASK(2)) + | + (CIndex & cJU_DCDMASK(2-1)) + | + (Pop1 - 1); + + JU_JPSETADT(PjpJP, (Word_t)PjllRaw, DcdP0, + cJU_JPLEAF1); + } +#endif // (!(JUDY1 && JU_64BIT)) // Not 64Bit Judy1 + + else // biggest + { +// cJU_JPLEAF_B1 + Word_t DcdP0; + Pjlb_t PjlbRaw; + PjlbRaw = j__udyJLL2toJLB1( + PLeaf + Start, +#ifdef JUDYL + Pjv + Start, +#endif + Pop1, Pjpm); + if (PjlbRaw == (Pjlb_t)NULL) + FREEALLEXIT(ExpCnt, StageJP, Pjpm); + + DcdP0 = (JU_JPDCDPOP0(Pjp) & cJU_DCDMASK(2)) + | + (CIndex & cJU_DCDMASK(2-1)) + | + (Pop1 - 1); + + JU_JPSETADT(PjpJP, (Word_t)PjlbRaw, DcdP0, + cJU_JPLEAF_B1); + } + ExpCnt++; +// Done? + if (End == cJU_LEAF2_MAXPOP1) break; + +// New Expanse, Start and Count + CIndex = PLeaf[End]; + Start = End; + } + } + +// Now put all the Leaves below a BranchL or BranchB: + if (ExpCnt <= cJU_BRANCHLMAXJPS) // put the Leaves below a BranchL + { + if (j__udyCreateBranchL(Pjp, StageJP, StageExp, ExpCnt, + Pjpm) == -1) FREEALLEXIT(ExpCnt, StageJP, Pjpm); + + Pjp->jp_Type = cJU_JPBRANCH_L2; + } + else + { + if (j__udyStageJBBtoJBB(Pjp, &StageJBB, StageJP, SubJPCount, Pjpm) + == -1) FREEALLEXIT(ExpCnt, StageJP, Pjpm); + } + return(1); + +} // j__udyCascade2() + + +// **************************************************************************** +// __ J U D Y C A S C A D E 3 +// +// Return *Pjp as a (compressed) cJU_LEAF2, cJU_BRANCH_L3, cJU_BRANCH_B3. + +FUNCTION int j__udyCascade3( + Pjp_t Pjp, + Pvoid_t Pjpm) +{ + uint8_t * PLeaf; // pointer to leaf, explicit type. + Word_t End, Start; // temporaries. + Word_t ExpCnt; // count of expanses of splay. + Word_t CIndex; // current Index word. +JUDYLCODE(Pjv_t Pjv;) // value area of leaf. + +// Temp staging for parts(Leaves) of newly splayed leaf + jp_t StageJP [cJU_LEAF3_MAXPOP1]; // JPs of new leaves + Word_t StageA [cJU_LEAF3_MAXPOP1]; + uint8_t StageExp [cJU_LEAF3_MAXPOP1]; // Expanses of new leaves + uint8_t SubJPCount[cJU_NUMSUBEXPB]; // JPs in each subexpanse + jbb_t StageJBB; // staged bitmap branch + + assert(JU_JPTYPE(Pjp) == cJU_JPLEAF3); + assert((JU_JPDCDPOP0(Pjp) & 0xFFFFFF) == (cJU_LEAF3_MAXPOP1-1)); + +// Get the address of the Leaf + PLeaf = (uint8_t *) P_JLL(Pjp->jp_Addr); + +// Extract leaf to Word_t and insert-sort Index into it + j__udyCopy3toW(StageA, PLeaf, cJU_LEAF3_MAXPOP1); + +// Get the address of the Leaf and Value area + JUDYLCODE(Pjv = JL_LEAF3VALUEAREA(PLeaf, cJU_LEAF3_MAXPOP1);) + +// If Leaf is in 1 expanse -- just compress it (compare 1st, last & Index) + + CIndex = StageA[0]; + if (!JU_DIGITATSTATE(CIndex ^ StageA[cJU_LEAF3_MAXPOP1-1], 3)) + { + Word_t DcdP0; + Pjll_t PjllRaw; // pointer to new leaf. + Pjll_t Pjll; + JUDYLCODE(Pjv_t Pjvnew;) // value area of new leaf. + +// Alloc a 2 byte Index Leaf + PjllRaw = j__udyAllocJLL2(cJU_LEAF3_MAXPOP1, Pjpm); + if (PjllRaw == (Pjlb_t)NULL) return(-1); // out of memory + + Pjll = P_JLL(PjllRaw); + +// Copy just 2 bytes Indexes to new Leaf +// j__udyCopyWto2((uint16_t *) Pjll, StageA, cJU_LEAF3_MAXPOP1); + JU_COPYMEM ((uint16_t *) Pjll, StageA, cJU_LEAF3_MAXPOP1); +#ifdef JUDYL +// Copy Value area into new Leaf + Pjvnew = JL_LEAF2VALUEAREA(Pjll, cJU_LEAF3_MAXPOP1); + JU_COPYMEM(Pjvnew, Pjv, cJU_LEAF3_MAXPOP1); +#endif + DBGCODE(JudyCheckSorted(Pjll, cJU_LEAF3_MAXPOP1, 2);) + +// Form new JP, Pop0 field is unchanged +// Add in another Dcd byte because compressing + DcdP0 = (CIndex & cJU_DCDMASK(2)) | JU_JPDCDPOP0(Pjp); + + JU_JPSETADT(Pjp, (Word_t) PjllRaw, DcdP0, cJU_JPLEAF2); + + return(1); // Success + } + +// Else in 2+ expanses, splay Leaf into smaller leaves at higher compression + + StageJBB = StageJBBZero; // zero staged bitmap branch + ZEROJP(SubJPCount); + +// Splay the 3 byte index Leaf to 2 byte Index Leaves + for (ExpCnt = Start = 0, End = 1; ; End++) + { +// Check if new expanse or last one + if ( (End == cJU_LEAF3_MAXPOP1) + || + (JU_DIGITATSTATE(CIndex ^ StageA[End], 3)) + ) + { +// Build a leaf below the previous expanse + + Pjp_t PjpJP = StageJP + ExpCnt; + Word_t Pop1 = End - Start; + Word_t expanse = JU_DIGITATSTATE(CIndex, 3); + Word_t subexp = expanse / cJU_BITSPERSUBEXPB; +// +// set the bit that is the current expanse + JU_JBB_BITMAP(&StageJBB, subexp) |= JU_BITPOSMASKB(expanse); +#ifdef SUBEXPCOUNTS + StageJBB.jbb_subPop1[subexp] += Pop1; // pop of subexpanse +#endif +// count number of expanses in each subexpanse + SubJPCount[subexp]++; + +// Save byte expanse of leaf + StageExp[ExpCnt] = JU_DIGITATSTATE(CIndex, 3); + + if (Pop1 == 1) // cJU_JPIMMED_2_01 + { + Word_t DcdP0; + DcdP0 = (JU_JPDCDPOP0(Pjp) & cJU_DCDMASK(2)) | + CIndex; +#ifdef JUDY1 + JU_JPSETADT(PjpJP, 0, DcdP0, cJ1_JPIMMED_2_01); +#else // JUDYL + JU_JPSETADT(PjpJP, Pjv[Start], DcdP0, + cJL_JPIMMED_2_01); +#endif // JUDYL + } +#if (defined(JUDY1) || defined(JU_64BIT)) + else if (Pop1 <= cJU_IMMED2_MAXPOP1) + { +// cJ1_JPIMMED_2_02..3: Judy1 32 +// cJL_JPIMMED_2_02..3: JudyL 64 +// cJ1_JPIMMED_2_02..7: Judy1 64 +#ifdef JUDYL +// Alloc is 1st in case of malloc fail + Pjv_t PjvnewRaw; // value area of new leaf. + Pjv_t Pjvnew; + +// Allocate Value area for Immediate Leaf + PjvnewRaw = j__udyLAllocJV(Pop1, Pjpm); + if (PjvnewRaw == (Pjv_t) NULL) + FREEALLEXIT(ExpCnt, StageJP, Pjpm); + + Pjvnew = P_JV(PjvnewRaw); + +// Copy to Values to Value Leaf + JU_COPYMEM(Pjvnew, Pjv + Start, Pop1); + + PjpJP->jp_Addr = (Word_t) PjvnewRaw; + +// Copy to Index to JP as an immediate Leaf + JU_COPYMEM((uint16_t *) (PjpJP->jp_LIndex), + StageA + Start, Pop1); +#else // JUDY1 + JU_COPYMEM((uint16_t *) (PjpJP->jp_1Index), + StageA + Start, Pop1); +#endif // JUDY1 +// Set Type, Population and Index size + PjpJP->jp_Type = cJU_JPIMMED_2_02 + Pop1 - 2; + } +#endif // (JUDY1 || JU_64BIT) + + else // Make a linear leaf2 + { +// cJU_JPLEAF2 + Word_t DcdP0; + Pjll_t PjllRaw; // pointer to new leaf. + Pjll_t Pjll; + JUDYLCODE(Pjv_t Pjvnew;) // value area of new leaf. + + PjllRaw = j__udyAllocJLL2(Pop1, Pjpm); + if (PjllRaw == (Pjll_t) NULL) + FREEALLEXIT(ExpCnt, StageJP, Pjpm); + + Pjll = P_JLL(PjllRaw); +#ifdef JUDYL +// Copy to Values to new Leaf + Pjvnew = JL_LEAF2VALUEAREA(Pjll, Pop1); + JU_COPYMEM(Pjvnew, Pjv + Start, Pop1); +#endif +// Copy least 2 bytes per Index of Leaf to new Leaf + JU_COPYMEM((uint16_t *) Pjll, StageA+Start, + Pop1); + + DBGCODE(JudyCheckSorted(Pjll, Pop1, 2);) + + DcdP0 = (JU_JPDCDPOP0(Pjp) & cJU_DCDMASK(3)) + | + (CIndex & cJU_DCDMASK(3-1)) + | + (Pop1 - 1); + + JU_JPSETADT(PjpJP, (Word_t)PjllRaw, DcdP0, + cJU_JPLEAF2); + } + ExpCnt++; +// Done? + if (End == cJU_LEAF3_MAXPOP1) break; + +// New Expanse, Start and Count + CIndex = StageA[End]; + Start = End; + } + } + +// Now put all the Leaves below a BranchL or BranchB: + if (ExpCnt <= cJU_BRANCHLMAXJPS) // put the Leaves below a BranchL + { + if (j__udyCreateBranchL(Pjp, StageJP, StageExp, ExpCnt, + Pjpm) == -1) FREEALLEXIT(ExpCnt, StageJP, Pjpm); + + Pjp->jp_Type = cJU_JPBRANCH_L3; + } + else + { + if (j__udyStageJBBtoJBB(Pjp, &StageJBB, StageJP, SubJPCount, Pjpm) + == -1) FREEALLEXIT(ExpCnt, StageJP, Pjpm); + } + return(1); + +} // j__udyCascade3() + + +#ifdef JU_64BIT // JudyCascade[4567] + +// **************************************************************************** +// __ J U D Y C A S C A D E 4 +// +// Cascade from a cJU_JPLEAF4 to one of the following: +// 1. if leaf is in 1 expanse: +// compress it into a JPLEAF3 +// 2. if leaf contains multiple expanses: +// create linear or bitmap branch containing +// each new expanse is either a: +// JPIMMED_3_01 branch +// JPIMMED_3_02 branch +// JPLEAF3 + +FUNCTION int j__udyCascade4( + Pjp_t Pjp, + Pvoid_t Pjpm) +{ + uint32_t * PLeaf; // pointer to leaf, explicit type. + Word_t End, Start; // temporaries. + Word_t ExpCnt; // count of expanses of splay. + Word_t CIndex; // current Index word. +JUDYLCODE(Pjv_t Pjv;) // value area of leaf. + +// Temp staging for parts(Leaves) of newly splayed leaf + jp_t StageJP [cJU_LEAF4_MAXPOP1]; // JPs of new leaves + Word_t StageA [cJU_LEAF4_MAXPOP1]; + uint8_t StageExp [cJU_LEAF4_MAXPOP1]; // Expanses of new leaves + uint8_t SubJPCount[cJU_NUMSUBEXPB]; // JPs in each subexpanse + jbb_t StageJBB; // staged bitmap branch + + assert(JU_JPTYPE(Pjp) == cJU_JPLEAF4); + assert((JU_JPDCDPOP0(Pjp) & 0xFFFFFFFF) == (cJU_LEAF4_MAXPOP1-1)); + +// Get the address of the Leaf + PLeaf = (uint32_t *) P_JLL(Pjp->jp_Addr); + +// Extract 4 byte index Leaf to Word_t + j__udyCopy4toW(StageA, PLeaf, cJU_LEAF4_MAXPOP1); + +// Get the address of the Leaf and Value area + JUDYLCODE(Pjv = JL_LEAF4VALUEAREA(PLeaf, cJU_LEAF4_MAXPOP1);) + +// If Leaf is in 1 expanse -- just compress it (compare 1st, last & Index) + + CIndex = StageA[0]; + if (!JU_DIGITATSTATE(CIndex ^ StageA[cJU_LEAF4_MAXPOP1-1], 4)) + { + Word_t DcdP0; + Pjll_t PjllRaw; // pointer to new leaf. + Pjll_t Pjll; + JUDYLCODE(Pjv_t Pjvnew;) // value area of new Leaf. + +// Alloc a 3 byte Index Leaf + PjllRaw = j__udyAllocJLL3(cJU_LEAF4_MAXPOP1, Pjpm); + if (PjllRaw == (Pjlb_t)NULL) return(-1); // out of memory + + Pjll = P_JLL(PjllRaw); + +// Copy Index area into new Leaf + j__udyCopyWto3((uint8_t *) Pjll, StageA, cJU_LEAF4_MAXPOP1); +#ifdef JUDYL +// Copy Value area into new Leaf + Pjvnew = JL_LEAF3VALUEAREA(Pjll, cJU_LEAF4_MAXPOP1); + JU_COPYMEM(Pjvnew, Pjv, cJU_LEAF4_MAXPOP1); +#endif + DBGCODE(JudyCheckSorted(Pjll, cJU_LEAF4_MAXPOP1, 3);) + + DcdP0 = JU_JPDCDPOP0(Pjp) | (CIndex & cJU_DCDMASK(3)); + JU_JPSETADT(Pjp, (Word_t)PjllRaw, DcdP0, cJU_JPLEAF3); + + return(1); + } + +// Else in 2+ expanses, splay Leaf into smaller leaves at higher compression + + StageJBB = StageJBBZero; // zero staged bitmap branch + ZEROJP(SubJPCount); + +// Splay the 4 byte index Leaf to 3 byte Index Leaves + for (ExpCnt = Start = 0, End = 1; ; End++) + { +// Check if new expanse or last one + if ( (End == cJU_LEAF4_MAXPOP1) + || + (JU_DIGITATSTATE(CIndex ^ StageA[End], 4)) + ) + { +// Build a leaf below the previous expanse + + Pjp_t PjpJP = StageJP + ExpCnt; + Word_t Pop1 = End - Start; + Word_t expanse = JU_DIGITATSTATE(CIndex, 4); + Word_t subexp = expanse / cJU_BITSPERSUBEXPB; +// +// set the bit that is the current expanse + JU_JBB_BITMAP(&StageJBB, subexp) |= JU_BITPOSMASKB(expanse); +#ifdef SUBEXPCOUNTS + StageJBB.jbb_subPop1[subexp] += Pop1; // pop of subexpanse +#endif +// count number of expanses in each subexpanse + SubJPCount[subexp]++; + +// Save byte expanse of leaf + StageExp[ExpCnt] = JU_DIGITATSTATE(CIndex, 4); + + if (Pop1 == 1) // cJU_JPIMMED_3_01 + { + Word_t DcdP0; + DcdP0 = (JU_JPDCDPOP0(Pjp) & cJU_DCDMASK(3)) | + CIndex; +#ifdef JUDY1 + JU_JPSETADT(PjpJP, 0, DcdP0, cJ1_JPIMMED_3_01); +#else // JUDYL + JU_JPSETADT(PjpJP, Pjv[Start], DcdP0, + cJL_JPIMMED_3_01); +#endif // JUDYL + } + else if (Pop1 <= cJU_IMMED3_MAXPOP1) + { +// cJ1_JPIMMED_3_02 : Judy1 32 +// cJL_JPIMMED_3_02 : JudyL 64 +// cJ1_JPIMMED_3_02..5: Judy1 64 + +#ifdef JUDYL +// Alloc is 1st in case of malloc fail + Pjv_t PjvnewRaw; // value area of new leaf. + Pjv_t Pjvnew; + +// Allocate Value area for Immediate Leaf + PjvnewRaw = j__udyLAllocJV(Pop1, Pjpm); + if (PjvnewRaw == (Pjv_t) NULL) + FREEALLEXIT(ExpCnt, StageJP, Pjpm); + + Pjvnew = P_JV(PjvnewRaw); + +// Copy to Values to Value Leaf + JU_COPYMEM(Pjvnew, Pjv + Start, Pop1); + PjpJP->jp_Addr = (Word_t) PjvnewRaw; + +// Copy to Index to JP as an immediate Leaf + j__udyCopyWto3(PjpJP->jp_LIndex, + StageA + Start, Pop1); +#else + j__udyCopyWto3(PjpJP->jp_1Index, + StageA + Start, Pop1); +#endif +// Set type, population and Index size + PjpJP->jp_Type = cJU_JPIMMED_3_02 + Pop1 - 2; + } + else + { +// cJU_JPLEAF3 + Word_t DcdP0; + Pjll_t PjllRaw; // pointer to new leaf. + Pjll_t Pjll; + JUDYLCODE(Pjv_t Pjvnew;) // value area of new leaf. + + PjllRaw = j__udyAllocJLL3(Pop1, Pjpm); + if (PjllRaw == (Pjll_t)NULL) + FREEALLEXIT(ExpCnt, StageJP, Pjpm); + + Pjll = P_JLL(PjllRaw); + +// Copy Indexes to new Leaf + j__udyCopyWto3((uint8_t *) Pjll, StageA + Start, + Pop1); +#ifdef JUDYL +// Copy to Values to new Leaf + Pjvnew = JL_LEAF3VALUEAREA(Pjll, Pop1); + JU_COPYMEM(Pjvnew, Pjv + Start, Pop1); +#endif + DBGCODE(JudyCheckSorted(Pjll, Pop1, 3);) + + DcdP0 = (JU_JPDCDPOP0(Pjp) & cJU_DCDMASK(4)) + | + (CIndex & cJU_DCDMASK(4-1)) + | + (Pop1 - 1); + + JU_JPSETADT(PjpJP, (Word_t)PjllRaw, DcdP0, + cJU_JPLEAF3); + } + ExpCnt++; +// Done? + if (End == cJU_LEAF4_MAXPOP1) break; + +// New Expanse, Start and Count + CIndex = StageA[End]; + Start = End; + } + } + +// Now put all the Leaves below a BranchL or BranchB: + if (ExpCnt <= cJU_BRANCHLMAXJPS) // put the Leaves below a BranchL + { + if (j__udyCreateBranchL(Pjp, StageJP, StageExp, ExpCnt, + Pjpm) == -1) FREEALLEXIT(ExpCnt, StageJP, Pjpm); + + Pjp->jp_Type = cJU_JPBRANCH_L4; + } + else + { + if (j__udyStageJBBtoJBB(Pjp, &StageJBB, StageJP, SubJPCount, Pjpm) + == -1) FREEALLEXIT(ExpCnt, StageJP, Pjpm); + } + return(1); + +} // j__udyCascade4() + + +// **************************************************************************** +// __ J U D Y C A S C A D E 5 +// +// Cascade from a cJU_JPLEAF5 to one of the following: +// 1. if leaf is in 1 expanse: +// compress it into a JPLEAF4 +// 2. if leaf contains multiple expanses: +// create linear or bitmap branch containing +// each new expanse is either a: +// JPIMMED_4_01 branch +// JPLEAF4 + +FUNCTION int j__udyCascade5( + Pjp_t Pjp, + Pvoid_t Pjpm) +{ + uint8_t * PLeaf; // pointer to leaf, explicit type. + Word_t End, Start; // temporaries. + Word_t ExpCnt; // count of expanses of splay. + Word_t CIndex; // current Index word. +JUDYLCODE(Pjv_t Pjv;) // value area of leaf. + +// Temp staging for parts(Leaves) of newly splayed leaf + jp_t StageJP [cJU_LEAF5_MAXPOP1]; // JPs of new leaves + Word_t StageA [cJU_LEAF5_MAXPOP1]; + uint8_t StageExp [cJU_LEAF5_MAXPOP1]; // Expanses of new leaves + uint8_t SubJPCount[cJU_NUMSUBEXPB]; // JPs in each subexpanse + jbb_t StageJBB; // staged bitmap branch + + assert(JU_JPTYPE(Pjp) == cJU_JPLEAF5); + assert((JU_JPDCDPOP0(Pjp) & 0xFFFFFFFFFF) == (cJU_LEAF5_MAXPOP1-1)); + +// Get the address of the Leaf + PLeaf = (uint8_t *) P_JLL(Pjp->jp_Addr); + +// Extract 5 byte index Leaf to Word_t + j__udyCopy5toW(StageA, PLeaf, cJU_LEAF5_MAXPOP1); + +// Get the address of the Leaf and Value area + JUDYLCODE(Pjv = JL_LEAF5VALUEAREA(PLeaf, cJU_LEAF5_MAXPOP1);) + +// If Leaf is in 1 expanse -- just compress it (compare 1st, last & Index) + + CIndex = StageA[0]; + if (!JU_DIGITATSTATE(CIndex ^ StageA[cJU_LEAF5_MAXPOP1-1], 5)) + { + Word_t DcdP0; + Pjll_t PjllRaw; // pointer to new leaf. + Pjll_t Pjll; + JUDYLCODE(Pjv_t Pjvnew;) // value area of new leaf. + +// Alloc a 4 byte Index Leaf + PjllRaw = j__udyAllocJLL4(cJU_LEAF5_MAXPOP1, Pjpm); + if (PjllRaw == (Pjlb_t)NULL) return(-1); // out of memory + + Pjll = P_JLL(PjllRaw); + +// Copy Index area into new Leaf + j__udyCopyWto4((uint8_t *) Pjll, StageA, cJU_LEAF5_MAXPOP1); +#ifdef JUDYL +// Copy Value area into new Leaf + Pjvnew = JL_LEAF4VALUEAREA(Pjll, cJU_LEAF5_MAXPOP1); + JU_COPYMEM(Pjvnew, Pjv, cJU_LEAF5_MAXPOP1); +#endif + DBGCODE(JudyCheckSorted(Pjll, cJU_LEAF5_MAXPOP1, 4);) + + DcdP0 = JU_JPDCDPOP0(Pjp) | (CIndex & cJU_DCDMASK(4)); + JU_JPSETADT(Pjp, (Word_t)PjllRaw, DcdP0, cJU_JPLEAF4); + + return(1); + } + +// Else in 2+ expanses, splay Leaf into smaller leaves at higher compression + + StageJBB = StageJBBZero; // zero staged bitmap branch + ZEROJP(SubJPCount); + +// Splay the 5 byte index Leaf to 4 byte Index Leaves + for (ExpCnt = Start = 0, End = 1; ; End++) + { +// Check if new expanse or last one + if ( (End == cJU_LEAF5_MAXPOP1) + || + (JU_DIGITATSTATE(CIndex ^ StageA[End], 5)) + ) + { +// Build a leaf below the previous expanse + + Pjp_t PjpJP = StageJP + ExpCnt; + Word_t Pop1 = End - Start; + Word_t expanse = JU_DIGITATSTATE(CIndex, 5); + Word_t subexp = expanse / cJU_BITSPERSUBEXPB; +// +// set the bit that is the current expanse + JU_JBB_BITMAP(&StageJBB, subexp) |= JU_BITPOSMASKB(expanse); +#ifdef SUBEXPCOUNTS + StageJBB.jbb_subPop1[subexp] += Pop1; // pop of subexpanse +#endif +// count number of expanses in each subexpanse + SubJPCount[subexp]++; + +// Save byte expanse of leaf + StageExp[ExpCnt] = JU_DIGITATSTATE(CIndex, 5); + + if (Pop1 == 1) // cJU_JPIMMED_4_01 + { + Word_t DcdP0; + DcdP0 = (JU_JPDCDPOP0(Pjp) & cJU_DCDMASK(4)) | + CIndex; +#ifdef JUDY1 + JU_JPSETADT(PjpJP, 0, DcdP0, cJ1_JPIMMED_4_01); +#else // JUDYL + JU_JPSETADT(PjpJP, Pjv[Start], DcdP0, + cJL_JPIMMED_4_01); +#endif // JUDYL + } +#ifdef JUDY1 + else if (Pop1 <= cJ1_IMMED4_MAXPOP1) + { +// cJ1_JPIMMED_4_02..3: Judy1 64 + +// Copy to Index to JP as an immediate Leaf + j__udyCopyWto4(PjpJP->jp_1Index, + StageA + Start, Pop1); + +// Set pointer, type, population and Index size + PjpJP->jp_Type = cJ1_JPIMMED_4_02 + Pop1 - 2; + } +#endif + else + { +// cJU_JPLEAF4 + Word_t DcdP0; + Pjll_t PjllRaw; // pointer to new leaf. + Pjll_t Pjll; + JUDYLCODE(Pjv_t Pjvnew;) // value area of new leaf. + +// Get a new Leaf + PjllRaw = j__udyAllocJLL4(Pop1, Pjpm); + if (PjllRaw == (Pjll_t)NULL) + FREEALLEXIT(ExpCnt, StageJP, Pjpm); + + Pjll = P_JLL(PjllRaw); + +// Copy Indexes to new Leaf + j__udyCopyWto4((uint8_t *) Pjll, StageA + Start, + Pop1); +#ifdef JUDYL +// Copy to Values to new Leaf + Pjvnew = JL_LEAF4VALUEAREA(Pjll, Pop1); + JU_COPYMEM(Pjvnew, Pjv + Start, Pop1); +#endif + DBGCODE(JudyCheckSorted(Pjll, Pop1, 4);) + + DcdP0 = (JU_JPDCDPOP0(Pjp) & cJU_DCDMASK(5)) + | + (CIndex & cJU_DCDMASK(5-1)) + | + (Pop1 - 1); + + JU_JPSETADT(PjpJP, (Word_t)PjllRaw, DcdP0, + cJU_JPLEAF4); + } + ExpCnt++; +// Done? + if (End == cJU_LEAF5_MAXPOP1) break; + +// New Expanse, Start and Count + CIndex = StageA[End]; + Start = End; + } + } + +// Now put all the Leaves below a BranchL or BranchB: + if (ExpCnt <= cJU_BRANCHLMAXJPS) // put the Leaves below a BranchL + { + if (j__udyCreateBranchL(Pjp, StageJP, StageExp, ExpCnt, + Pjpm) == -1) FREEALLEXIT(ExpCnt, StageJP, Pjpm); + + Pjp->jp_Type = cJU_JPBRANCH_L5; + } + else + { + if (j__udyStageJBBtoJBB(Pjp, &StageJBB, StageJP, SubJPCount, Pjpm) + == -1) FREEALLEXIT(ExpCnt, StageJP, Pjpm); + } + return(1); + +} // j__udyCascade5() + + +// **************************************************************************** +// __ J U D Y C A S C A D E 6 +// +// Cascade from a cJU_JPLEAF6 to one of the following: +// 1. if leaf is in 1 expanse: +// compress it into a JPLEAF5 +// 2. if leaf contains multiple expanses: +// create linear or bitmap branch containing +// each new expanse is either a: +// JPIMMED_5_01 ... JPIMMED_5_03 branch +// JPIMMED_5_01 branch +// JPLEAF5 + +FUNCTION int j__udyCascade6( + Pjp_t Pjp, + Pvoid_t Pjpm) +{ + uint8_t * PLeaf; // pointer to leaf, explicit type. + Word_t End, Start; // temporaries. + Word_t ExpCnt; // count of expanses of splay. + Word_t CIndex; // current Index word. +JUDYLCODE(Pjv_t Pjv;) // value area of leaf. + +// Temp staging for parts(Leaves) of newly splayed leaf + jp_t StageJP [cJU_LEAF6_MAXPOP1]; // JPs of new leaves + Word_t StageA [cJU_LEAF6_MAXPOP1]; + uint8_t StageExp [cJU_LEAF6_MAXPOP1]; // Expanses of new leaves + uint8_t SubJPCount[cJU_NUMSUBEXPB]; // JPs in each subexpanse + jbb_t StageJBB; // staged bitmap branch + + assert(JU_JPTYPE(Pjp) == cJU_JPLEAF6); + assert((JU_JPDCDPOP0(Pjp) & 0xFFFFFFFFFFFF) == (cJU_LEAF6_MAXPOP1-1)); + +// Get the address of the Leaf + PLeaf = (uint8_t *) P_JLL(Pjp->jp_Addr); + +// Extract 6 byte index Leaf to Word_t + j__udyCopy6toW(StageA, PLeaf, cJU_LEAF6_MAXPOP1); + +// Get the address of the Leaf and Value area + JUDYLCODE(Pjv = JL_LEAF6VALUEAREA(PLeaf, cJU_LEAF6_MAXPOP1);) + +// If Leaf is in 1 expanse -- just compress it (compare 1st, last & Index) + + CIndex = StageA[0]; + if (!JU_DIGITATSTATE(CIndex ^ StageA[cJU_LEAF6_MAXPOP1-1], 6)) + { + Word_t DcdP0; + Pjll_t PjllRaw; // pointer to new leaf. + Pjll_t Pjll; + JUDYLCODE(Pjv_t Pjvnew;) // value area of new leaf. + +// Alloc a 5 byte Index Leaf + PjllRaw = j__udyAllocJLL5(cJU_LEAF6_MAXPOP1, Pjpm); + if (PjllRaw == (Pjlb_t)NULL) return(-1); // out of memory + + Pjll = P_JLL(PjllRaw); + +// Copy Index area into new Leaf + j__udyCopyWto5((uint8_t *) Pjll, StageA, cJU_LEAF6_MAXPOP1); +#ifdef JUDYL +// Copy Value area into new Leaf + Pjvnew = JL_LEAF5VALUEAREA(Pjll, cJU_LEAF6_MAXPOP1); + JU_COPYMEM(Pjvnew, Pjv, cJU_LEAF6_MAXPOP1); +#endif + DBGCODE(JudyCheckSorted(Pjll, cJU_LEAF6_MAXPOP1, 5);) + + DcdP0 = JU_JPDCDPOP0(Pjp) | (CIndex & cJU_DCDMASK(5)); + JU_JPSETADT(Pjp, (Word_t)PjllRaw, DcdP0, cJU_JPLEAF5); + + return(1); + } + +// Else in 2+ expanses, splay Leaf into smaller leaves at higher compression + + StageJBB = StageJBBZero; // zero staged bitmap branch + ZEROJP(SubJPCount); + +// Splay the 6 byte index Leaf to 5 byte Index Leaves + for (ExpCnt = Start = 0, End = 1; ; End++) + { +// Check if new expanse or last one + if ( (End == cJU_LEAF6_MAXPOP1) + || + (JU_DIGITATSTATE(CIndex ^ StageA[End], 6)) + ) + { +// Build a leaf below the previous expanse + + Pjp_t PjpJP = StageJP + ExpCnt; + Word_t Pop1 = End - Start; + Word_t expanse = JU_DIGITATSTATE(CIndex, 6); + Word_t subexp = expanse / cJU_BITSPERSUBEXPB; +// +// set the bit that is the current expanse + JU_JBB_BITMAP(&StageJBB, subexp) |= JU_BITPOSMASKB(expanse); +#ifdef SUBEXPCOUNTS + StageJBB.jbb_subPop1[subexp] += Pop1; // pop of subexpanse +#endif +// count number of expanses in each subexpanse + SubJPCount[subexp]++; + +// Save byte expanse of leaf + StageExp[ExpCnt] = JU_DIGITATSTATE(CIndex, 6); + + if (Pop1 == 1) // cJU_JPIMMED_5_01 + { + Word_t DcdP0; + DcdP0 = (JU_JPDCDPOP0(Pjp) & cJU_DCDMASK(5)) | + CIndex; +#ifdef JUDY1 + JU_JPSETADT(PjpJP, 0, DcdP0, cJ1_JPIMMED_5_01); +#else // JUDYL + JU_JPSETADT(PjpJP, Pjv[Start], DcdP0, + cJL_JPIMMED_5_01); +#endif // JUDYL + } +#ifdef JUDY1 + else if (Pop1 <= cJ1_IMMED5_MAXPOP1) + { +// cJ1_JPIMMED_5_02..3: Judy1 64 + +// Copy to Index to JP as an immediate Leaf + j__udyCopyWto5(PjpJP->jp_1Index, + StageA + Start, Pop1); + +// Set pointer, type, population and Index size + PjpJP->jp_Type = cJ1_JPIMMED_5_02 + Pop1 - 2; + } +#endif + else + { +// cJU_JPLEAF5 + Word_t DcdP0; + Pjll_t PjllRaw; // pointer to new leaf. + Pjll_t Pjll; + JUDYLCODE(Pjv_t Pjvnew;) // value area of new leaf. + +// Get a new Leaf + PjllRaw = j__udyAllocJLL5(Pop1, Pjpm); + if (PjllRaw == (Pjll_t)NULL) + FREEALLEXIT(ExpCnt, StageJP, Pjpm); + + Pjll = P_JLL(PjllRaw); + +// Copy Indexes to new Leaf + j__udyCopyWto5((uint8_t *) Pjll, StageA + Start, + Pop1); + +// Copy to Values to new Leaf +#ifdef JUDYL + Pjvnew = JL_LEAF5VALUEAREA(Pjll, Pop1); + JU_COPYMEM(Pjvnew, Pjv + Start, Pop1); +#endif + DBGCODE(JudyCheckSorted(Pjll, Pop1, 5);) + + DcdP0 = (JU_JPDCDPOP0(Pjp) & cJU_DCDMASK(6)) + | + (CIndex & cJU_DCDMASK(6-1)) + | + (Pop1 - 1); + + JU_JPSETADT(PjpJP, (Word_t)PjllRaw, DcdP0, + cJU_JPLEAF5); + } + ExpCnt++; +// Done? + if (End == cJU_LEAF6_MAXPOP1) break; + +// New Expanse, Start and Count + CIndex = StageA[End]; + Start = End; + } + } + +// Now put all the Leaves below a BranchL or BranchB: + if (ExpCnt <= cJU_BRANCHLMAXJPS) // put the Leaves below a BranchL + { + if (j__udyCreateBranchL(Pjp, StageJP, StageExp, ExpCnt, + Pjpm) == -1) FREEALLEXIT(ExpCnt, StageJP, Pjpm); + + Pjp->jp_Type = cJU_JPBRANCH_L6; + } + else + { + if (j__udyStageJBBtoJBB(Pjp, &StageJBB, StageJP, SubJPCount, Pjpm) + == -1) FREEALLEXIT(ExpCnt, StageJP, Pjpm); + } + return(1); + +} // j__udyCascade6() + + +// **************************************************************************** +// __ J U D Y C A S C A D E 7 +// +// Cascade from a cJU_JPLEAF7 to one of the following: +// 1. if leaf is in 1 expanse: +// compress it into a JPLEAF6 +// 2. if leaf contains multiple expanses: +// create linear or bitmap branch containing +// each new expanse is either a: +// JPIMMED_6_01 ... JPIMMED_6_02 branch +// JPIMMED_6_01 branch +// JPLEAF6 + +FUNCTION int j__udyCascade7( + Pjp_t Pjp, + Pvoid_t Pjpm) +{ + uint8_t * PLeaf; // pointer to leaf, explicit type. + Word_t End, Start; // temporaries. + Word_t ExpCnt; // count of expanses of splay. + Word_t CIndex; // current Index word. +JUDYLCODE(Pjv_t Pjv;) // value area of leaf. + +// Temp staging for parts(Leaves) of newly splayed leaf + jp_t StageJP [cJU_LEAF7_MAXPOP1]; // JPs of new leaves + Word_t StageA [cJU_LEAF7_MAXPOP1]; + uint8_t StageExp [cJU_LEAF7_MAXPOP1]; // Expanses of new leaves + uint8_t SubJPCount[cJU_NUMSUBEXPB]; // JPs in each subexpanse + jbb_t StageJBB; // staged bitmap branch + + assert(JU_JPTYPE(Pjp) == cJU_JPLEAF7); + assert(JU_JPDCDPOP0(Pjp) == (cJU_LEAF7_MAXPOP1-1)); + +// Get the address of the Leaf + PLeaf = (uint8_t *) P_JLL(Pjp->jp_Addr); + +// Extract 7 byte index Leaf to Word_t + j__udyCopy7toW(StageA, PLeaf, cJU_LEAF7_MAXPOP1); + +// Get the address of the Leaf and Value area + JUDYLCODE(Pjv = JL_LEAF7VALUEAREA(PLeaf, cJU_LEAF7_MAXPOP1);) + +// If Leaf is in 1 expanse -- just compress it (compare 1st, last & Index) + + CIndex = StageA[0]; + if (!JU_DIGITATSTATE(CIndex ^ StageA[cJU_LEAF7_MAXPOP1-1], 7)) + { + Word_t DcdP0; + Pjll_t PjllRaw; // pointer to new leaf. + Pjll_t Pjll; + JUDYLCODE(Pjv_t Pjvnew;) // value area of new leaf. + +// Alloc a 6 byte Index Leaf + PjllRaw = j__udyAllocJLL6(cJU_LEAF7_MAXPOP1, Pjpm); + if (PjllRaw == (Pjlb_t)NULL) return(-1); // out of memory + + Pjll = P_JLL(PjllRaw); + +// Copy Index area into new Leaf + j__udyCopyWto6((uint8_t *) Pjll, StageA, cJU_LEAF7_MAXPOP1); +#ifdef JUDYL +// Copy Value area into new Leaf + Pjvnew = JL_LEAF6VALUEAREA(Pjll, cJU_LEAF7_MAXPOP1); + JU_COPYMEM(Pjvnew, Pjv, cJU_LEAF7_MAXPOP1); +#endif + DBGCODE(JudyCheckSorted(Pjll, cJU_LEAF7_MAXPOP1, 6);) + + DcdP0 = JU_JPDCDPOP0(Pjp) | (CIndex & cJU_DCDMASK(6)); + JU_JPSETADT(Pjp, (Word_t)PjllRaw, DcdP0, cJU_JPLEAF6); + + return(1); + } + +// Else in 2+ expanses, splay Leaf into smaller leaves at higher compression + + StageJBB = StageJBBZero; // zero staged bitmap branch + ZEROJP(SubJPCount); + +// Splay the 7 byte index Leaf to 6 byte Index Leaves + for (ExpCnt = Start = 0, End = 1; ; End++) + { +// Check if new expanse or last one + if ( (End == cJU_LEAF7_MAXPOP1) + || + (JU_DIGITATSTATE(CIndex ^ StageA[End], 7)) + ) + { +// Build a leaf below the previous expanse + + Pjp_t PjpJP = StageJP + ExpCnt; + Word_t Pop1 = End - Start; + Word_t expanse = JU_DIGITATSTATE(CIndex, 7); + Word_t subexp = expanse / cJU_BITSPERSUBEXPB; +// +// set the bit that is the current expanse + JU_JBB_BITMAP(&StageJBB, subexp) |= JU_BITPOSMASKB(expanse); +#ifdef SUBEXPCOUNTS + StageJBB.jbb_subPop1[subexp] += Pop1; // pop of subexpanse +#endif +// count number of expanses in each subexpanse + SubJPCount[subexp]++; + +// Save byte expanse of leaf + StageExp[ExpCnt] = JU_DIGITATSTATE(CIndex, 7); + + if (Pop1 == 1) // cJU_JPIMMED_6_01 + { + Word_t DcdP0; + DcdP0 = (JU_JPDCDPOP0(Pjp) & cJU_DCDMASK(6)) | + CIndex; +#ifdef JUDY1 + JU_JPSETADT(PjpJP, 0, DcdP0, cJ1_JPIMMED_6_01); +#else // JUDYL + JU_JPSETADT(PjpJP, Pjv[Start], DcdP0, + cJL_JPIMMED_6_01); +#endif // JUDYL + } +#ifdef JUDY1 + else if (Pop1 == cJ1_IMMED6_MAXPOP1) + { +// cJ1_JPIMMED_6_02: Judy1 64 + +// Copy to Index to JP as an immediate Leaf + j__udyCopyWto6(PjpJP->jp_1Index, + StageA + Start, 2); + +// Set pointer, type, population and Index size + PjpJP->jp_Type = cJ1_JPIMMED_6_02; + } +#endif + else + { +// cJU_JPLEAF6 + Word_t DcdP0; + Pjll_t PjllRaw; // pointer to new leaf. + Pjll_t Pjll; + JUDYLCODE(Pjv_t Pjvnew;) // value area of new leaf. + +// Get a new Leaf + PjllRaw = j__udyAllocJLL6(Pop1, Pjpm); + if (PjllRaw == (Pjll_t)NULL) + FREEALLEXIT(ExpCnt, StageJP, Pjpm); + Pjll = P_JLL(PjllRaw); + +// Copy Indexes to new Leaf + j__udyCopyWto6((uint8_t *) Pjll, StageA + Start, + Pop1); +#ifdef JUDYL +// Copy to Values to new Leaf + Pjvnew = JL_LEAF6VALUEAREA(Pjll, Pop1); + JU_COPYMEM(Pjvnew, Pjv + Start, Pop1); +#endif + DBGCODE(JudyCheckSorted(Pjll, Pop1, 6);) + + DcdP0 = (JU_JPDCDPOP0(Pjp) & cJU_DCDMASK(7)) + | + (CIndex & cJU_DCDMASK(7-1)) + | + (Pop1 - 1); + + JU_JPSETADT(PjpJP, (Word_t)PjllRaw, DcdP0, + cJU_JPLEAF6); + } + ExpCnt++; +// Done? + if (End == cJU_LEAF7_MAXPOP1) break; + +// New Expanse, Start and Count + CIndex = StageA[End]; + Start = End; + } + } + +// Now put all the Leaves below a BranchL or BranchB: + if (ExpCnt <= cJU_BRANCHLMAXJPS) // put the Leaves below a BranchL + { + if (j__udyCreateBranchL(Pjp, StageJP, StageExp, ExpCnt, + Pjpm) == -1) FREEALLEXIT(ExpCnt, StageJP, Pjpm); + + Pjp->jp_Type = cJU_JPBRANCH_L7; + } + else + { + if (j__udyStageJBBtoJBB(Pjp, &StageJBB, StageJP, SubJPCount, Pjpm) + == -1) FREEALLEXIT(ExpCnt, StageJP, Pjpm); + } + return(1); + +} // j__udyCascade7() + +#endif // JU_64BIT + + +// **************************************************************************** +// __ J U D Y C A S C A D E L +// +// (Compressed) cJU_LEAF3[7], cJ1_JPBRANCH_L. +// +// Cascade from a LEAFW (under Pjp) to one of the following: +// 1. if LEAFW is in 1 expanse: +// create linear branch with a JPLEAF3[7] under it +// 2. LEAFW contains multiple expanses: +// create linear or bitmap branch containing new expanses +// each new expanse is either a: 32 64 +// JPIMMED_3_01 branch Y N +// JPIMMED_7_01 branch N Y +// JPLEAF3 Y N +// JPLEAF7 N Y + +FUNCTION int j__udyCascadeL( + Pjp_t Pjp, + Pvoid_t Pjpm) +{ + Pjlw_t Pjlw; // leaf to work on. + Word_t End, Start; // temporaries. + Word_t ExpCnt; // count of expanses of splay. + Word_t CIndex; // current Index word. +JUDYLCODE(Pjv_t Pjv;) // value area of leaf. + +// Temp staging for parts(Leaves) of newly splayed leaf + jp_t StageJP [cJU_LEAFW_MAXPOP1]; + uint8_t StageExp[cJU_LEAFW_MAXPOP1]; + uint8_t SubJPCount[cJU_NUMSUBEXPB]; // JPs in each subexpanse + jbb_t StageJBB; // staged bitmap branch + +// Get the address of the Leaf + Pjlw = P_JLW(Pjp->jp_Addr); + + assert(Pjlw[0] == (cJU_LEAFW_MAXPOP1 - 1)); + +// Get pointer to Value area of old Leaf + JUDYLCODE(Pjv = JL_LEAFWVALUEAREA(Pjlw, cJU_LEAFW_MAXPOP1);) + + Pjlw++; // Now point to Index area + +// If Leaf is in 1 expanse -- first compress it (compare 1st, last & Index): + + CIndex = Pjlw[0]; // also used far below + if (!JU_DIGITATSTATE(CIndex ^ Pjlw[cJU_LEAFW_MAXPOP1 - 1], + cJU_ROOTSTATE)) + { + Pjll_t PjllRaw; // pointer to new leaf. + Pjll_t Pjll; + JUDYLCODE(Pjv_t Pjvnew;) // value area of new leaf. + +// Get the common expanse to all elements in Leaf + StageExp[0] = JU_DIGITATSTATE(CIndex, cJU_ROOTSTATE); + +// Alloc a 3[7] byte Index Leaf +#ifdef JU_64BIT + PjllRaw = j__udyAllocJLL7(cJU_LEAFW_MAXPOP1, Pjpm); + if (PjllRaw == (Pjlb_t)NULL) return(-1); // out of memory + + Pjll = P_JLL(PjllRaw); + +// Copy LEAFW to a cJU_JPLEAF7 + j__udyCopyWto7((uint8_t *) Pjll, Pjlw, cJU_LEAFW_MAXPOP1); +#ifdef JUDYL +// Get the Value area of new Leaf + Pjvnew = JL_LEAF7VALUEAREA(Pjll, cJU_LEAFW_MAXPOP1); + JU_COPYMEM(Pjvnew, Pjv, cJU_LEAFW_MAXPOP1); +#endif + DBGCODE(JudyCheckSorted(Pjll, cJU_LEAFW_MAXPOP1, 7);) +#else // 32 Bit + PjllRaw = j__udyAllocJLL3(cJU_LEAFW_MAXPOP1, Pjpm); + if (PjllRaw == (Pjll_t) NULL) return(-1); + + Pjll = P_JLL(PjllRaw); + +// Copy LEAFW to a cJU_JPLEAF3 + j__udyCopyWto3((uint8_t *) Pjll, Pjlw, cJU_LEAFW_MAXPOP1); +#ifdef JUDYL +// Get the Value area of new Leaf + Pjvnew = JL_LEAF3VALUEAREA(Pjll, cJU_LEAFW_MAXPOP1); + JU_COPYMEM(Pjvnew, Pjv, cJU_LEAFW_MAXPOP1); +#endif + DBGCODE(JudyCheckSorted(Pjll, cJU_LEAFW_MAXPOP1, 3);) +#endif // 32 Bit + +// Following not needed because cJU_DCDMASK(3[7]) is == 0 +////// StageJP[0].jp_DcdPopO |= (CIndex & cJU_DCDMASK(3[7])); +#ifdef JU_64BIT + JU_JPSETADT(&(StageJP[0]), (Word_t)PjllRaw, cJU_LEAFW_MAXPOP1-1, + cJU_JPLEAF7); +#else // 32BIT + JU_JPSETADT(&(StageJP[0]), (Word_t)PjllRaw, cJU_LEAFW_MAXPOP1-1, + cJU_JPLEAF3); +#endif // 32BIT +// Create a 1 element Linear branch + if (j__udyCreateBranchL(Pjp, StageJP, StageExp, 1, Pjpm) == -1) + return(-1); + +// Change the type of callers JP + Pjp->jp_Type = cJU_JPBRANCH_L; + + return(1); + } + +// Else in 2+ expanses, splay Leaf into smaller leaves at higher compression + + StageJBB = StageJBBZero; // zero staged bitmap branch + ZEROJP(SubJPCount); + +// Splay the 4[8] byte Index Leaf to 3[7] byte Index Leaves + for (ExpCnt = Start = 0, End = 1; ; End++) + { +// Check if new expanse or last one + if ( (End == cJU_LEAFW_MAXPOP1) + || + (JU_DIGITATSTATE(CIndex ^ Pjlw[End], cJU_ROOTSTATE)) + ) + { +// Build a leaf below the previous expanse + + Pjp_t PjpJP = StageJP + ExpCnt; + Word_t Pop1 = End - Start; + Word_t expanse = JU_DIGITATSTATE(CIndex, cJU_ROOTSTATE); + Word_t subexp = expanse / cJU_BITSPERSUBEXPB; +// +// set the bit that is the current expanse + JU_JBB_BITMAP(&StageJBB, subexp) |= JU_BITPOSMASKB(expanse); +#ifdef SUBEXPCOUNTS + StageJBB.jbb_subPop1[subexp] += Pop1; // pop of subexpanse +#endif +// count number of expanses in each subexpanse + SubJPCount[subexp]++; + +// Save byte expanse of leaf + StageExp[ExpCnt] = JU_DIGITATSTATE(CIndex, + cJU_ROOTSTATE); + + if (Pop1 == 1) // cJU_JPIMMED_3[7]_01 + { +#ifdef JU_64BIT +#ifdef JUDY1 + JU_JPSETADT(PjpJP, 0, CIndex, cJ1_JPIMMED_7_01); +#else // JUDYL + JU_JPSETADT(PjpJP, Pjv[Start], CIndex, + cJL_JPIMMED_7_01); +#endif // JUDYL + +#else // JU_32BIT +#ifdef JUDY1 + JU_JPSETADT(PjpJP, 0, CIndex, cJ1_JPIMMED_3_01); +#else // JUDYL + JU_JPSETADT(PjpJP, Pjv[Start], CIndex, + cJL_JPIMMED_3_01); +#endif // JUDYL +#endif // JU_32BIT + } +#ifdef JUDY1 +#ifdef JU_64BIT + else if (Pop1 <= cJ1_IMMED7_MAXPOP1) +#else + else if (Pop1 <= cJ1_IMMED3_MAXPOP1) +#endif + { +// cJ1_JPIMMED_3_02 : Judy1 32 +// cJ1_JPIMMED_7_02 : Judy1 64 +// Copy to JP as an immediate Leaf +#ifdef JU_64BIT + j__udyCopyWto7(PjpJP->jp_1Index, Pjlw+Start, 2); + PjpJP->jp_Type = cJ1_JPIMMED_7_02; +#else + j__udyCopyWto3(PjpJP->jp_1Index, Pjlw+Start, 2); + PjpJP->jp_Type = cJ1_JPIMMED_3_02; +#endif // 32 Bit + } +#endif // JUDY1 + else // Linear Leaf JPLEAF3[7] + { +// cJU_JPLEAF3[7] + Pjll_t PjllRaw; // pointer to new leaf. + Pjll_t Pjll; + JUDYLCODE(Pjv_t Pjvnew;) // value area of new leaf. +#ifdef JU_64BIT + PjllRaw = j__udyAllocJLL7(Pop1, Pjpm); + if (PjllRaw == (Pjll_t) NULL) return(-1); + Pjll = P_JLL(PjllRaw); + + j__udyCopyWto7((uint8_t *) Pjll, Pjlw + Start, + Pop1); +#ifdef JUDYL + Pjvnew = JL_LEAF7VALUEAREA(Pjll, Pop1); + JU_COPYMEM(Pjvnew, Pjv + Start, Pop1); +#endif // JUDYL + DBGCODE(JudyCheckSorted(Pjll, Pop1, 7);) +#else // JU_64BIT - 32 Bit + PjllRaw = j__udyAllocJLL3(Pop1, Pjpm); + if (PjllRaw == (Pjll_t) NULL) return(-1); + Pjll = P_JLL(PjllRaw); + + j__udyCopyWto3((uint8_t *) Pjll, Pjlw + Start, + Pop1); +#ifdef JUDYL + Pjvnew = JL_LEAF3VALUEAREA(Pjll, Pop1); + JU_COPYMEM(Pjvnew, Pjv + Start, Pop1); +#endif // JUDYL + DBGCODE(JudyCheckSorted(Pjll, Pop1, 3);) +#endif // 32 Bit + +#ifdef JU_64BIT + JU_JPSETADT(PjpJP, (Word_t)PjllRaw, Pop1 - 1, + cJU_JPLEAF7); +#else // JU_64BIT - 32 Bit + JU_JPSETADT(PjpJP, (Word_t)PjllRaw, Pop1 - 1, + cJU_JPLEAF3); +#endif // 32 Bit + } + ExpCnt++; +// Done? + if (End == cJU_LEAFW_MAXPOP1) break; + +// New Expanse, Start and Count + CIndex = Pjlw[End]; + Start = End; + } + } + +// Now put all the Leaves below a BranchL or BranchB: + if (ExpCnt <= cJU_BRANCHLMAXJPS) // put the Leaves below a BranchL + { + if (j__udyCreateBranchL(Pjp, StageJP, StageExp, ExpCnt, + Pjpm) == -1) FREEALLEXIT(ExpCnt, StageJP, Pjpm); + + Pjp->jp_Type = cJU_JPBRANCH_L; + } + else + { + if (j__udyStageJBBtoJBB(Pjp, &StageJBB, StageJP, SubJPCount, Pjpm) + == -1) FREEALLEXIT(ExpCnt, StageJP, Pjpm); + + Pjp->jp_Type = cJU_JPBRANCH_B; // cJU_LEAFW is out of sequence + } + return(1); + +} // j__udyCascadeL() diff --git a/feeds/p4/libjudy/src/src/JudyCommon/JudyCount.c b/feeds/p4/libjudy/src/src/JudyCommon/JudyCount.c new file mode 100644 index 000000000..179757f0a --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudyCommon/JudyCount.c @@ -0,0 +1,1195 @@ +// Copyright (C) 2000 - 2002 Hewlett-Packard Company +// +// This program is free software; you can redistribute it and/or modify it +// under the term of the GNU Lesser 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 Lesser General Public License +// for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// _________________ + +// @(#) $Revision: 4.78 $ $Source: /judy/src/JudyCommon/JudyCount.c $ +// +// Judy*Count() function for Judy1 and JudyL. +// Compile with one of -DJUDY1 or -DJUDYL. +// +// Compile with -DNOSMARTJBB, -DNOSMARTJBU, and/or -DNOSMARTJLB to build a +// version with cache line optimizations deleted, for testing. +// +// Compile with -DSMARTMETRICS to obtain global variables containing smart +// cache line metrics. Note: Dont turn this on simultaneously for this file +// and JudyByCount.c because they export the same globals. +// +// Judy*Count() returns the "count of Indexes" (inclusive) between the two +// specified limits (Indexes). This code is remarkably fast. It traverses the +// "Judy array" data structure. +// +// This count code is the GENERIC untuned version (minimum code size). It +// might be possible to tuned to a specific architecture to be faster. +// However, in real applications, with a modern machine, it is expected that +// the instruction times will be swamped by cache line fills. +// **************************************************************************** + +#if (! (defined(JUDY1) || defined(JUDYL))) +#error: One of -DJUDY1 or -DJUDYL must be specified. +#endif + +#ifdef JUDY1 +#include "Judy1.h" +#else +#include "JudyL.h" +#endif + +#include "JudyPrivate1L.h" + + +// define a phoney that is for sure + +#define cJU_LEAFW cJU_JPIMMED_CAP + +// Avoid duplicate symbols since this file is multi-compiled: + +#ifdef SMARTMETRICS +#ifdef JUDY1 +Word_t jbb_upward = 0; // counts of directions taken: +Word_t jbb_downward = 0; +Word_t jbu_upward = 0; +Word_t jbu_downward = 0; +Word_t jlb_upward = 0; +Word_t jlb_downward = 0; +#else +extern Word_t jbb_upward; +extern Word_t jbb_downward; +extern Word_t jbu_upward; +extern Word_t jbu_downward; +extern Word_t jlb_upward; +extern Word_t jlb_downward; +#endif +#endif + + +// FORWARD DECLARATIONS (prototypes): + +static Word_t j__udy1LCountSM(const Pjp_t Pjp, const Word_t Index, + const Pjpm_t Pjpm); + +// Each of Judy1 and JudyL get their own private (static) version of this +// function: + +static int j__udyCountLeafB1(const Pjll_t Pjll, const Word_t Pop1, + const Word_t Index); + +// These functions are not static because they are exported to Judy*ByCount(): +// +// TBD: Should be made static for performance reasons? And thus duplicated? +// +// Note: There really are two different functions, but for convenience they +// are referred to here with a generic name. + +#ifdef JUDY1 +#define j__udyJPPop1 j__udy1JPPop1 +#else +#define j__udyJPPop1 j__udyLJPPop1 +#endif + +Word_t j__udyJPPop1(const Pjp_t Pjp); + + +// LOCAL ERROR HANDLING: +// +// The Judy*Count() functions are unusual because they return 0 instead of JERR +// for an error. In this source file, define C_JERR for clarity. + +#define C_JERR 0 + + +// **************************************************************************** +// J U D Y 1 C O U N T +// J U D Y L C O U N T +// +// See the manual entry for details. +// +// This code is written recursively, at least at first, because thats much +// simpler; hope its fast enough. + +#ifdef JUDY1 +FUNCTION Word_t Judy1Count +#else +FUNCTION Word_t JudyLCount +#endif + ( + Pcvoid_t PArray, // JRP to first branch/leaf in SM. + Word_t Index1, // starting Index. + Word_t Index2, // ending Index. + PJError_t PJError // optional, for returning error info. + ) +{ + jpm_t fakejpm; // local temporary for small arrays. + Pjpm_t Pjpm; // top JPM or local temporary for error info. + jp_t fakejp; // constructed for calling j__udy1LCountSM(). + Pjp_t Pjp; // JP to pass to j__udy1LCountSM(). + Word_t pop1; // total for the array. + Word_t pop1above1; // indexes at or above Index1, inclusive. + Word_t pop1above2; // indexes at or above Index2, exclusive. + int retcode; // from Judy*First() calls. +JUDYLCODE(PPvoid_t PPvalue); // from JudyLFirst() calls. + + +// CHECK FOR SHORTCUTS: +// +// As documented, return C_JERR if the Judy array is empty or Index1 > Index2. + + if ((PArray == (Pvoid_t) NULL) || (Index1 > Index2)) + { + JU_SET_ERRNO(PJError, JU_ERRNO_NONE); + return(C_JERR); + } + +// If Index1 == Index2, simply check if the specified Index is set; pass +// through the return value from Judy1Test() or JudyLGet() with appropriate +// translations. + + if (Index1 == Index2) + { +#ifdef JUDY1 + retcode = Judy1Test(PArray, Index1, PJError); + + if (retcode == JERRI) return(C_JERR); // pass through error. + + if (retcode == 0) + { + JU_SET_ERRNO(PJError, JU_ERRNO_NONE); + return(C_JERR); + } +#else + PPvalue = JudyLGet(PArray, Index1, PJError); + + if (PPvalue == PPJERR) return(C_JERR); // pass through error. + + if (PPvalue == (PPvoid_t) NULL) // Index is not set. + { + JU_SET_ERRNO(PJError, JU_ERRNO_NONE); + return(C_JERR); + } +#endif + return(1); // single index is set. + } + + +// CHECK JRP TYPE: +// +// Use an if/then for speed rather than a switch, and put the most common cases +// first. +// +// Note: Since even cJU_LEAFW types require counting between two Indexes, +// prepare them here for common code below that calls j__udy1LCountSM(), rather +// than handling them even more specially here. + + if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW + { + Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf. + Pjpm = & fakejpm; + Pjp = & fakejp; + Pjp->jp_Addr = (Word_t) Pjlw; + Pjp->jp_Type = cJU_LEAFW; + Pjpm->jpm_Pop0 = Pjlw[0]; // from first word of leaf. + pop1 = Pjpm->jpm_Pop0 + 1; + } + else + { + Pjpm = P_JPM(PArray); + Pjp = &(Pjpm->jpm_JP); + pop1 = (Pjpm->jpm_Pop0) + 1; // note: can roll over to 0. + +#if (defined(JUDY1) && (! defined(JU_64BIT))) + if (pop1 == 0) // rare special case of full array: + { + Word_t count = Index2 - Index1 + 1; // can roll over again. + + if (count == 0) + { + JU_SET_ERRNO(PJError, JU_ERRNO_FULL); + return(C_JERR); + } + return(count); + } +#else + assert(pop1); // JudyL or 64-bit cannot create a full array! +#endif + } + + +// COUNT POP1 ABOVE INDEX1, INCLUSIVE: + + assert(pop1); // just to be safe. + + if (Index1 == 0) // shortcut, pop1above1 is entire population: + { + pop1above1 = pop1; + } + else // find first valid Index above Index1, if any: + { +#ifdef JUDY1 + if ((retcode = Judy1First(PArray, & Index1, PJError)) == JERRI) + return(C_JERR); // pass through error. +#else + if ((PPvalue = JudyLFirst(PArray, & Index1, PJError)) == PPJERR) + return(C_JERR); // pass through error. + + retcode = (PPvalue != (PPvoid_t) NULL); // found a next Index. +#endif + +// If theres no Index at or above Index1, just return C_JERR (early exit): + + if (retcode == 0) + { + JU_SET_ERRNO(PJError, JU_ERRNO_NONE); + return(C_JERR); + } + +// If a first/next Index was found, call the counting motor starting with that +// known valid Index, meaning the return should be positive, not C_JERR except +// in case of a real error: + + if ((pop1above1 = j__udy1LCountSM(Pjp, Index1, Pjpm)) == C_JERR) + { + JU_COPY_ERRNO(PJError, Pjpm); // pass through error. + return(C_JERR); + } + } + + +// COUNT POP1 ABOVE INDEX2, EXCLUSIVE, AND RETURN THE DIFFERENCE: +// +// In principle, calculate the ordinal of each Index and take the difference, +// with caution about off-by-one errors due to the specified Indexes being set +// or unset. In practice: +// +// - The ordinals computed here are inverse ordinals, that is, the populations +// ABOVE the specified Indexes (Index1 inclusive, Index2 exclusive), so +// subtract pop1above2 from pop1above1, rather than vice-versa. +// +// - Index1s result already includes a count for Index1 and/or Index2 if +// either is set, so calculate pop1above2 exclusive of Index2. +// +// TBD: If Index1 and Index2 fall in the same expanse in the top-state +// branch(es), would it be faster to walk the SM only once, to their divergence +// point, before calling j__udy1LCountSM() or equivalent? Possibly a non-issue +// if a top-state pop1 becomes stored with each Judy1 array. Also, consider +// whether the first call of j__udy1LCountSM() fills the cache, for common tree +// branches, for the second call. +// +// As for pop1above1, look for shortcuts for special cases when pop1above2 is +// zero. Otherwise call the counting "motor". + + assert(pop1above1); // just to be safe. + + if (Index2++ == cJU_ALLONES) return(pop1above1); // Index2 at limit. + +#ifdef JUDY1 + if ((retcode = Judy1First(PArray, & Index2, PJError)) == JERRI) + return(C_JERR); +#else + if ((PPvalue = JudyLFirst(PArray, & Index2, PJError)) == PPJERR) + return(C_JERR); + + retcode = (PPvalue != (PPvoid_t) NULL); // found a next Index. +#endif + if (retcode == 0) return(pop1above1); // no Index above Index2. + +// Just as for Index1, j__udy1LCountSM() cannot return 0 (locally == C_JERR) +// except in case of a real error: + + if ((pop1above2 = j__udy1LCountSM(Pjp, Index2, Pjpm)) == C_JERR) + { + JU_COPY_ERRNO(PJError, Pjpm); // pass through error. + return(C_JERR); + } + + if (pop1above1 == pop1above2) + { + JU_SET_ERRNO(PJError, JU_ERRNO_NONE); + return(C_JERR); + } + + return(pop1above1 - pop1above2); + +} // Judy1Count() / JudyLCount() + + +// **************************************************************************** +// __ J U D Y 1 L C O U N T S M +// +// Given a pointer to a JP (with invalid jp_DcdPopO at cJU_ROOTSTATE), a known +// valid Index, and a Pjpm for returning error info, recursively visit a Judy +// array state machine (SM) and return the count of Indexes, including Index, +// through the end of the Judy array at this state or below. In case of error +// or a count of 0 (should never happen), return C_JERR with appropriate +// JU_ERRNO in the Pjpm. +// +// Note: This function is not told the current state because its encoded in +// the JP Type. +// +// Method: To minimize cache line fills, while studying each branch, if Index +// resides above the midpoint of the branch (which often consists of multiple +// cache lines), ADD the populations at or above Index; otherwise, SUBTRACT +// from the population of the WHOLE branch (available from the JP) the +// populations at or above Index. This is especially tricky for bitmap +// branches. +// +// Note: Unlike, say, the Ins and Del walk routines, this function returns the +// same type of returns as Judy*Count(), so it can use *_SET_ERRNO*() macros +// the same way. + +FUNCTION static Word_t j__udy1LCountSM( +const Pjp_t Pjp, // top of Judy (sub)SM. +const Word_t Index, // count at or above this Index. +const Pjpm_t Pjpm) // for returning error info. +{ + Pjbl_t Pjbl; // Pjp->jp_Addr masked and cast to types: + Pjbb_t Pjbb; + Pjbu_t Pjbu; + Pjll_t Pjll; // a Judy lower-level linear leaf. + + Word_t digit; // next digit to decode from Index. + long jpnum; // JP number in a branch (base 0). + int offset; // index ordinal within a leaf, base 0. + Word_t pop1; // total population of an expanse. + Word_t pop1above; // to return. + +// Common code to check Decode bits in a JP against the equivalent portion of +// Index; XOR together, then mask bits of interest; must be all 0: +// +// Note: Why does this code only assert() compliance rather than actively +// checking for outliers? Its because Index is supposed to be valid, hence +// always match any Dcd bits traversed. +// +// Note: This assertion turns out to be always true for cState = 3 on 32-bit +// and 7 on 64-bit, but its harmless, probably removed by the compiler. + +#define CHECKDCD(Pjp,cState) \ + assert(! JU_DCDNOTMATCHINDEX(Index, Pjp, cState)) + +// Common code to prepare to handle a root-level or lower-level branch: +// Extract a state-dependent digit from Index in a "constant" way, obtain the +// total population for the branch in a state-dependent way, and then branch to +// common code for multiple cases: +// +// For root-level branches, the state is always cJU_ROOTSTATE, and the +// population is received in Pjpm->jpm_Pop0. +// +// Note: The total population is only needed in cases where the common code +// "counts up" instead of down to minimize cache line fills. However, its +// available cheaply, and its better to do it with a constant shift (constant +// state value) instead of a variable shift later "when needed". + +#define PREPB_ROOT(Pjp,Next) \ + digit = JU_DIGITATSTATE(Index, cJU_ROOTSTATE); \ + pop1 = (Pjpm->jpm_Pop0) + 1; \ + goto Next + +#define PREPB(Pjp,cState,Next) \ + digit = JU_DIGITATSTATE(Index, cState); \ + pop1 = JU_JPBRANCH_POP0(Pjp, (cState)) + 1; \ + goto Next + + +// SWITCH ON JP TYPE: +// +// WARNING: For run-time efficiency the following cases replicate code with +// varying constants, rather than using common code with variable values! + + switch (JU_JPTYPE(Pjp)) + { + + +// ---------------------------------------------------------------------------- +// ROOT-STATE LEAF that starts with a Pop0 word; just count within the leaf: + + case cJU_LEAFW: + { + Pjlw_t Pjlw = P_JLW(Pjp->jp_Addr); // first word of leaf. + + assert((Pjpm->jpm_Pop0) + 1 == Pjlw[0] + 1); // sent correctly. + offset = j__udySearchLeafW(Pjlw + 1, Pjpm->jpm_Pop0 + 1, Index); + assert(offset >= 0); // Index must exist. + assert(offset < (Pjpm->jpm_Pop0) + 1); // Index be in range. + return((Pjpm->jpm_Pop0) + 1 - offset); // INCLUSIVE of Index. + } + +// ---------------------------------------------------------------------------- +// LINEAR BRANCH; count populations in JPs in the JBL ABOVE the next digit in +// Index, and recurse for the next digit in Index: +// +// Note: There are no null JPs in a JBL; watch out for pop1 == 0. +// +// Note: A JBL should always fit in one cache line => no need to count up +// versus down to save cache line fills. (PREPB() sets pop1 for no reason.) + + case cJU_JPBRANCH_L2: CHECKDCD(Pjp, 2); PREPB(Pjp, 2, BranchL); + case cJU_JPBRANCH_L3: CHECKDCD(Pjp, 3); PREPB(Pjp, 3, BranchL); + +#ifdef JU_64BIT + case cJU_JPBRANCH_L4: CHECKDCD(Pjp, 4); PREPB(Pjp, 4, BranchL); + case cJU_JPBRANCH_L5: CHECKDCD(Pjp, 5); PREPB(Pjp, 5, BranchL); + case cJU_JPBRANCH_L6: CHECKDCD(Pjp, 6); PREPB(Pjp, 6, BranchL); + case cJU_JPBRANCH_L7: CHECKDCD(Pjp, 7); PREPB(Pjp, 7, BranchL); +#endif + case cJU_JPBRANCH_L: PREPB_ROOT(Pjp, BranchL); + +// Common code (state-independent) for all cases of linear branches: + +BranchL: + + Pjbl = P_JBL(Pjp->jp_Addr); + jpnum = Pjbl->jbl_NumJPs; // above last JP. + pop1above = 0; + + while (digit < (Pjbl->jbl_Expanse[--jpnum])) // still ABOVE digit. + { + if ((pop1 = j__udyJPPop1((Pjbl->jbl_jp) + jpnum)) == cJU_ALLONES) + { + JU_SET_ERRNO_NONNULL(Pjpm, JU_ERRNO_CORRUPT); + return(C_JERR); + } + + pop1above += pop1; + assert(jpnum > 0); // should find digit. + } + + assert(digit == (Pjbl->jbl_Expanse[jpnum])); // should find digit. + + pop1 = j__udy1LCountSM((Pjbl->jbl_jp) + jpnum, Index, Pjpm); + if (pop1 == C_JERR) return(C_JERR); // pass error up. + + assert(pop1above + pop1); + return(pop1above + pop1); + + +// ---------------------------------------------------------------------------- +// BITMAP BRANCH; count populations in JPs in the JBB ABOVE the next digit in +// Index, and recurse for the next digit in Index: +// +// Note: There are no null JPs in a JBB; watch out for pop1 == 0. + + case cJU_JPBRANCH_B2: CHECKDCD(Pjp, 2); PREPB(Pjp, 2, BranchB); + case cJU_JPBRANCH_B3: CHECKDCD(Pjp, 3); PREPB(Pjp, 3, BranchB); +#ifdef JU_64BIT + case cJU_JPBRANCH_B4: CHECKDCD(Pjp, 4); PREPB(Pjp, 4, BranchB); + case cJU_JPBRANCH_B5: CHECKDCD(Pjp, 5); PREPB(Pjp, 5, BranchB); + case cJU_JPBRANCH_B6: CHECKDCD(Pjp, 6); PREPB(Pjp, 6, BranchB); + case cJU_JPBRANCH_B7: CHECKDCD(Pjp, 7); PREPB(Pjp, 7, BranchB); +#endif + case cJU_JPBRANCH_B: PREPB_ROOT(Pjp, BranchB); + +// Common code (state-independent) for all cases of bitmap branches: + +BranchB: + { + long subexp; // for stepping through layer 1 (subexpanses). + long findsub; // subexpanse containing Index (digit). + Word_t findbit; // bit representing Index (digit). + Word_t lowermask; // bits for indexes at or below Index. + Word_t jpcount; // JPs in a subexpanse. + Word_t clbelow; // cache lines below digits cache line. + Word_t clabove; // cache lines above digits cache line. + + Pjbb = P_JBB(Pjp->jp_Addr); + findsub = digit / cJU_BITSPERSUBEXPB; + findbit = digit % cJU_BITSPERSUBEXPB; + lowermask = JU_MASKLOWERINC(JU_BITPOSMASKB(findbit)); + clbelow = clabove = 0; // initial/default => always downward. + + assert(JU_BITMAPTESTB(Pjbb, digit)); // digit must have a JP. + assert(findsub < cJU_NUMSUBEXPB); // falls in expected range. + +// Shorthand for one subexpanse in a bitmap and for one JP in a bitmap branch: +// +// Note: BMPJP0 exists separately to support assertions. + +#define BMPJP0(Subexp) (P_JP(JU_JBB_PJP(Pjbb, Subexp))) +#define BMPJP(Subexp,JPnum) (BMPJP0(Subexp) + (JPnum)) + +#ifndef NOSMARTJBB // enable to turn off smart code for comparison purposes. + +// FIGURE OUT WHICH DIRECTION CAUSES FEWER CACHE LINE FILLS; adding the pop1s +// in JPs above Indexs JP, or subtracting the pop1s in JPs below Indexs JP. +// +// This is tricky because, while each set bit in the bitmap represents a JP, +// the JPs are scattered over cJU_NUMSUBEXPB subexpanses, each of which can +// contain JPs packed into multiple cache lines, and this code must visit every +// JP either BELOW or ABOVE the JP for Index. +// +// Number of cache lines required to hold a linear list of the given number of +// JPs, assuming the first JP is at the start of a cache line or the JPs in +// jpcount fit wholly within a single cache line, which is ensured by +// JudyMalloc(): + +#define CLPERJPS(jpcount) \ + ((((jpcount) * cJU_WORDSPERJP) + cJU_WORDSPERCL - 1) / cJU_WORDSPERCL) + +// Count cache lines below/above for each subexpanse: + + for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp) + { + jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp)); + +// When at the subexpanse containing Index (digit), add cache lines +// below/above appropriately, excluding the cache line containing the JP for +// Index itself: + + if (subexp < findsub) clbelow += CLPERJPS(jpcount); + else if (subexp > findsub) clabove += CLPERJPS(jpcount); + else // (subexp == findsub) + { + Word_t clfind; // cache line containing Index (digit). + + clfind = CLPERJPS(j__udyCountBitsB( + JU_JBB_BITMAP(Pjbb, subexp) & lowermask)); + + assert(clfind > 0); // digit itself should have 1 CL. + clbelow += clfind - 1; + clabove += CLPERJPS(jpcount) - clfind; + } + } +#endif // ! NOSMARTJBB + +// Note: Its impossible to get through the following "if" without setting +// jpnum -- see some of the assertions below -- but gcc -Wall doesnt know +// this, so preset jpnum to make it happy: + + jpnum = 0; + + +// COUNT POPULATION FOR A BITMAP BRANCH, in whichever direction should result +// in fewer cache line fills: +// +// Note: If the remainder of Index is zero, pop1above is the pop1 of the +// entire expanse and theres no point in recursing to lower levels; but this +// should be so rare that its not worth checking for; +// Judy1Count()/JudyLCount() never even calls the motor for Index == 0 (all +// bytes). + + +// COUNT UPWARD, subtracting each "below or at" JPs pop1 from the whole +// expanses pop1: +// +// Note: If this causes clbelow + 1 cache line fills including JPs cache +// line, thats OK; at worst this is the same as clabove. + + if (clbelow < clabove) + { +#ifdef SMARTMETRICS + ++jbb_upward; +#endif + pop1above = pop1; // subtract JPs at/below Index. + +// Count JPs for which to accrue pop1s in this subexpanse: +// +// TBD: If JU_JBB_BITMAP is cJU_FULLBITMAPB, dont bother counting. + + for (subexp = 0; subexp <= findsub; ++subexp) + { + jpcount = j__udyCountBitsB((subexp < findsub) ? + JU_JBB_BITMAP(Pjbb, subexp) : + JU_JBB_BITMAP(Pjbb, subexp) & lowermask); + + // should always find findbit: + assert((subexp < findsub) || jpcount); + +// Subtract pop1s from JPs BELOW OR AT Index (digit): +// +// Note: The pop1 for Indexs JP itself is partially added back later at a +// lower state. +// +// Note: An empty subexpanse (jpcount == 0) is handled "for free". +// +// Note: Must be null JP subexp pointer in empty subexpanse and non-empty in +// non-empty subexpanse: + + assert( jpcount || (BMPJP0(subexp) == (Pjp_t) NULL)); + assert((! jpcount) || (BMPJP0(subexp) != (Pjp_t) NULL)); + + for (jpnum = 0; jpnum < jpcount; ++jpnum) + { + if ((pop1 = j__udyJPPop1(BMPJP(subexp, jpnum))) + == cJU_ALLONES) + { + JU_SET_ERRNO_NONNULL(Pjpm, JU_ERRNO_CORRUPT); + return(C_JERR); + } + + pop1above -= pop1; + } + + jpnum = jpcount - 1; // make correct for digit. + } + } + +// COUNT DOWNWARD, adding each "above" JPs pop1: + + else + { + long jpcountbf; // below findbit, inclusive. +#ifdef SMARTMETRICS + ++jbb_downward; +#endif + pop1above = 0; // add JPs above Index. + jpcountbf = 0; // until subexp == findsub. + +// Count JPs for which to accrue pop1s in this subexpanse: +// +// This is more complicated than counting upward because the scan of digits +// subexpanse must count ALL JPs, to know where to START counting down, and +// ALSO note the offset of digits JP to know where to STOP counting down. + + for (subexp = cJU_NUMSUBEXPB - 1; subexp >= findsub; --subexp) + { + jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp)); + + // should always find findbit: + assert((subexp > findsub) || jpcount); + + if (! jpcount) continue; // empty subexpanse, save time. + +// Count JPs below digit, inclusive: + + if (subexp == findsub) + { + jpcountbf = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp) + & lowermask); + } + + // should always find findbit: + assert((subexp > findsub) || jpcountbf); + assert(jpcount >= jpcountbf); // proper relationship. + +// Add pop1s from JPs ABOVE Index (digit): + + // no null JP subexp pointers: + assert(BMPJP0(subexp) != (Pjp_t) NULL); + + for (jpnum = jpcount - 1; jpnum >= jpcountbf; --jpnum) + { + if ((pop1 = j__udyJPPop1(BMPJP(subexp, jpnum))) + == cJU_ALLONES) + { + JU_SET_ERRNO_NONNULL(Pjpm, JU_ERRNO_CORRUPT); + return(C_JERR); + } + + pop1above += pop1; + } + // jpnum is now correct for digit. + } + } // else. + +// Return the net population ABOVE the digits JP at this state (in this JBB) +// plus the population AT OR ABOVE Index in the SM under the digits JP: + + pop1 = j__udy1LCountSM(BMPJP(findsub, jpnum), Index, Pjpm); + if (pop1 == C_JERR) return(C_JERR); // pass error up. + + assert(pop1above + pop1); + return(pop1above + pop1); + + } // case. + + +// ---------------------------------------------------------------------------- +// UNCOMPRESSED BRANCH; count populations in JPs in the JBU ABOVE the next +// digit in Index, and recurse for the next digit in Index: +// +// Note: If the remainder of Index is zero, pop1above is the pop1 of the +// entire expanse and theres no point in recursing to lower levels; but this +// should be so rare that its not worth checking for; +// Judy1Count()/JudyLCount() never even calls the motor for Index == 0 (all +// bytes). + + case cJU_JPBRANCH_U2: CHECKDCD(Pjp, 2); PREPB(Pjp, 2, BranchU); + case cJU_JPBRANCH_U3: CHECKDCD(Pjp, 3); PREPB(Pjp, 3, BranchU); +#ifdef JU_64BIT + case cJU_JPBRANCH_U4: CHECKDCD(Pjp, 4); PREPB(Pjp, 4, BranchU); + case cJU_JPBRANCH_U5: CHECKDCD(Pjp, 5); PREPB(Pjp, 5, BranchU); + case cJU_JPBRANCH_U6: CHECKDCD(Pjp, 6); PREPB(Pjp, 6, BranchU); + case cJU_JPBRANCH_U7: CHECKDCD(Pjp, 7); PREPB(Pjp, 7, BranchU); +#endif + case cJU_JPBRANCH_U: PREPB_ROOT(Pjp, BranchU); + +// Common code (state-independent) for all cases of uncompressed branches: + +BranchU: + Pjbu = P_JBU(Pjp->jp_Addr); + +#ifndef NOSMARTJBU // enable to turn off smart code for comparison purposes. + +// FIGURE OUT WHICH WAY CAUSES FEWER CACHE LINE FILLS; adding the JPs above +// Indexs JP, or subtracting the JPs below Indexs JP. +// +// COUNT UPWARD, subtracting the pop1 of each JP BELOW OR AT Index, from the +// whole expanses pop1: + + if (digit < (cJU_BRANCHUNUMJPS / 2)) + { + pop1above = pop1; // subtract JPs below Index. +#ifdef SMARTMETRICS + ++jbu_upward; +#endif + for (jpnum = 0; jpnum <= digit; ++jpnum) + { + if ((Pjbu->jbu_jp[jpnum].jp_Type) <= cJU_JPNULLMAX) + continue; // shortcut, save a function call. + + if ((pop1 = j__udyJPPop1(Pjbu->jbu_jp + jpnum)) + == cJU_ALLONES) + { + JU_SET_ERRNO_NONNULL(Pjpm, JU_ERRNO_CORRUPT); + return(C_JERR); + } + + pop1above -= pop1; + } + } + +// COUNT DOWNWARD, simply adding the pop1 of each JP ABOVE Index: + + else +#endif // NOSMARTJBU + { + assert(digit < cJU_BRANCHUNUMJPS); +#ifdef SMARTMETRICS + ++jbu_downward; +#endif + pop1above = 0; // add JPs above Index. + + for (jpnum = cJU_BRANCHUNUMJPS - 1; jpnum > digit; --jpnum) + { + if ((Pjbu->jbu_jp[jpnum].jp_Type) <= cJU_JPNULLMAX) + continue; // shortcut, save a function call. + + if ((pop1 = j__udyJPPop1(Pjbu->jbu_jp + jpnum)) + == cJU_ALLONES) + { + JU_SET_ERRNO_NONNULL(Pjpm, JU_ERRNO_CORRUPT); + return(C_JERR); + } + + pop1above += pop1; + } + } + + if ((pop1 = j__udy1LCountSM(Pjbu->jbu_jp + digit, Index, Pjpm)) + == C_JERR) return(C_JERR); // pass error up. + + assert(pop1above + pop1); + return(pop1above + pop1); + + +// ---------------------------------------------------------------------------- +// LEAF COUNT MACROS: +// +// LEAF*ABOVE() are common code for different JP types (linear leaves, bitmap +// leaves, and immediates) and different leaf Index Sizes, which result in +// calling different leaf search functions. Linear leaves get the leaf address +// from jp_Addr and the Population from jp_DcdPopO, while immediates use Pjp +// itself as the leaf address and get Population from jp_Type. + +#define LEAFLABOVE(Func) \ + Pjll = P_JLL(Pjp->jp_Addr); \ + pop1 = JU_JPLEAF_POP0(Pjp) + 1; \ + LEAFABOVE(Func, Pjll, pop1) + +#define LEAFB1ABOVE(Func) LEAFLABOVE(Func) // different Func, otherwise same. + +#ifdef JUDY1 +#define IMMABOVE(Func,Pop1) \ + Pjll = (Pjll_t) Pjp; \ + LEAFABOVE(Func, Pjll, Pop1) +#else +// Note: For JudyL immediates with >= 2 Indexes, the index bytes are in a +// different place than for Judy1: + +#define IMMABOVE(Func,Pop1) \ + LEAFABOVE(Func, (Pjll_t) (Pjp->jp_LIndex), Pop1) +#endif + +// For all leaf types, the population AT OR ABOVE is the total pop1 less the +// offset of Index; and Index should always be found: + +#define LEAFABOVE(Func,Pjll,Pop1) \ + offset = Func(Pjll, Pop1, Index); \ + assert(offset >= 0); \ + assert(offset < (Pop1)); \ + return((Pop1) - offset) + +// IMMABOVE_01 handles the special case of an immediate JP with 1 index, which +// the search functions arent used for anyway: +// +// The target Index should be the one in this Immediate, in which case the +// count above (inclusive) is always 1. + +#define IMMABOVE_01 \ + assert((JU_JPDCDPOP0(Pjp)) == JU_TRIMTODCDSIZE(Index)); \ + return(1) + + +// ---------------------------------------------------------------------------- +// LINEAR LEAF; search the leaf for Index; size is computed from jp_Type: + +#if (defined(JUDYL) || (! defined(JU_64BIT))) + case cJU_JPLEAF1: LEAFLABOVE(j__udySearchLeaf1); +#endif + case cJU_JPLEAF2: LEAFLABOVE(j__udySearchLeaf2); + case cJU_JPLEAF3: LEAFLABOVE(j__udySearchLeaf3); + +#ifdef JU_64BIT + case cJU_JPLEAF4: LEAFLABOVE(j__udySearchLeaf4); + case cJU_JPLEAF5: LEAFLABOVE(j__udySearchLeaf5); + case cJU_JPLEAF6: LEAFLABOVE(j__udySearchLeaf6); + case cJU_JPLEAF7: LEAFLABOVE(j__udySearchLeaf7); +#endif + + +// ---------------------------------------------------------------------------- +// BITMAP LEAF; search the leaf for Index: +// +// Since the bitmap describes Indexes digitally rather than linearly, this is +// not really a search, but just a count. + + case cJU_JPLEAF_B1: LEAFB1ABOVE(j__udyCountLeafB1); + + +#ifdef JUDY1 +// ---------------------------------------------------------------------------- +// FULL POPULATION: +// +// Return the count of Indexes AT OR ABOVE Index, which is the total population +// of the expanse (a constant) less the value of the undecoded digit remaining +// in Index (its base-0 offset in the expanse), which yields an inclusive count +// above. +// +// TBD: This only supports a 1-byte full expanse. Should this extract a +// stored value for pop0 and possibly more LSBs of Index, to handle larger full +// expanses? + + case cJ1_JPFULLPOPU1: + return(cJU_JPFULLPOPU1_POP0 + 1 - JU_DIGITATSTATE(Index, 1)); +#endif + + +// ---------------------------------------------------------------------------- +// IMMEDIATE: + + case cJU_JPIMMED_1_01: IMMABOVE_01; + case cJU_JPIMMED_2_01: IMMABOVE_01; + case cJU_JPIMMED_3_01: IMMABOVE_01; +#ifdef JU_64BIT + case cJU_JPIMMED_4_01: IMMABOVE_01; + case cJU_JPIMMED_5_01: IMMABOVE_01; + case cJU_JPIMMED_6_01: IMMABOVE_01; + case cJU_JPIMMED_7_01: IMMABOVE_01; +#endif + + case cJU_JPIMMED_1_02: IMMABOVE(j__udySearchLeaf1, 2); + case cJU_JPIMMED_1_03: IMMABOVE(j__udySearchLeaf1, 3); +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_1_04: IMMABOVE(j__udySearchLeaf1, 4); + case cJU_JPIMMED_1_05: IMMABOVE(j__udySearchLeaf1, 5); + case cJU_JPIMMED_1_06: IMMABOVE(j__udySearchLeaf1, 6); + case cJU_JPIMMED_1_07: IMMABOVE(j__udySearchLeaf1, 7); +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_1_08: IMMABOVE(j__udySearchLeaf1, 8); + case cJ1_JPIMMED_1_09: IMMABOVE(j__udySearchLeaf1, 9); + case cJ1_JPIMMED_1_10: IMMABOVE(j__udySearchLeaf1, 10); + case cJ1_JPIMMED_1_11: IMMABOVE(j__udySearchLeaf1, 11); + case cJ1_JPIMMED_1_12: IMMABOVE(j__udySearchLeaf1, 12); + case cJ1_JPIMMED_1_13: IMMABOVE(j__udySearchLeaf1, 13); + case cJ1_JPIMMED_1_14: IMMABOVE(j__udySearchLeaf1, 14); + case cJ1_JPIMMED_1_15: IMMABOVE(j__udySearchLeaf1, 15); +#endif + +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_2_02: IMMABOVE(j__udySearchLeaf2, 2); + case cJU_JPIMMED_2_03: IMMABOVE(j__udySearchLeaf2, 3); +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_2_04: IMMABOVE(j__udySearchLeaf2, 4); + case cJ1_JPIMMED_2_05: IMMABOVE(j__udySearchLeaf2, 5); + case cJ1_JPIMMED_2_06: IMMABOVE(j__udySearchLeaf2, 6); + case cJ1_JPIMMED_2_07: IMMABOVE(j__udySearchLeaf2, 7); +#endif + +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_3_02: IMMABOVE(j__udySearchLeaf3, 2); +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_3_03: IMMABOVE(j__udySearchLeaf3, 3); + case cJ1_JPIMMED_3_04: IMMABOVE(j__udySearchLeaf3, 4); + case cJ1_JPIMMED_3_05: IMMABOVE(j__udySearchLeaf3, 5); + + case cJ1_JPIMMED_4_02: IMMABOVE(j__udySearchLeaf4, 2); + case cJ1_JPIMMED_4_03: IMMABOVE(j__udySearchLeaf4, 3); + + case cJ1_JPIMMED_5_02: IMMABOVE(j__udySearchLeaf5, 2); + case cJ1_JPIMMED_5_03: IMMABOVE(j__udySearchLeaf5, 3); + + case cJ1_JPIMMED_6_02: IMMABOVE(j__udySearchLeaf6, 2); + + case cJ1_JPIMMED_7_02: IMMABOVE(j__udySearchLeaf7, 2); +#endif + + +// ---------------------------------------------------------------------------- +// OTHER CASES: + + default: JU_SET_ERRNO_NONNULL(Pjpm, JU_ERRNO_CORRUPT); return(C_JERR); + + } // switch on JP type + + /*NOTREACHED*/ + +} // j__udy1LCountSM() + + +// **************************************************************************** +// J U D Y C O U N T L E A F B 1 +// +// This is a private analog of the j__udySearchLeaf*() functions for counting +// in bitmap 1-byte leaves. Since a bitmap leaf describes Indexes digitally +// rather than linearly, this is not really a search, but just a count of the +// valid Indexes == set bits below or including Index, which should be valid. +// Return the "offset" (really the ordinal), 0 .. Pop1 - 1, of Index in Pjll; +// if Indexs bit is not set (which should never happen, so this is DEBUG-mode +// only), return the 1s-complement equivalent (== negative offset minus 1). +// +// Note: The source code for this function looks identical for both Judy1 and +// JudyL, but the JU_JLB_BITMAP macro varies. +// +// Note: For simpler calling, the first arg is of type Pjll_t but then cast to +// Pjlb_t. + +FUNCTION static int j__udyCountLeafB1( +const Pjll_t Pjll, // bitmap leaf, as Pjll_t for consistency. +const Word_t Pop1, // Population of whole leaf. +const Word_t Index) // to which to count. +{ + Pjlb_t Pjlb = (Pjlb_t) Pjll; // to proper type. + Word_t digit = Index & cJU_MASKATSTATE(1); + Word_t findsub = digit / cJU_BITSPERSUBEXPL; + Word_t findbit = digit % cJU_BITSPERSUBEXPL; + int count; // in leaf through Index. + long subexp; // for stepping through subexpanses. + + +// COUNT UPWARD: +// +// The entire bitmap should fit in one cache line, but still try to save some +// CPU time by counting the fewest possible number of subexpanses from the +// bitmap. + +#ifndef NOSMARTJLB // enable to turn off smart code for comparison purposes. + + if (findsub < (cJU_NUMSUBEXPL / 2)) + { +#ifdef SMARTMETRICS + ++jlb_upward; +#endif + count = 0; + + for (subexp = 0; subexp < findsub; ++subexp) + { + count += ((JU_JLB_BITMAP(Pjlb, subexp) == cJU_FULLBITMAPL) ? + cJU_BITSPERSUBEXPL : + j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp))); + } + +// This count includes findbit, which should be set, resulting in a base-1 +// offset: + + count += j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, findsub) + & JU_MASKLOWERINC(JU_BITPOSMASKL(findbit))); + + DBGCODE(if (! JU_BITMAPTESTL(Pjlb, digit)) return(~count);) + assert(count >= 1); + return(count - 1); // convert to base-0 offset. + } +#endif // NOSMARTJLB + + +// COUNT DOWNWARD: +// +// Count the valid Indexes above or at Index, and subtract from Pop1. + +#ifdef SMARTMETRICS + ++jlb_downward; +#endif + count = Pop1; // base-1 for now. + + for (subexp = cJU_NUMSUBEXPL - 1; subexp > findsub; --subexp) + { + count -= ((JU_JLB_BITMAP(Pjlb, subexp) == cJU_FULLBITMAPL) ? + cJU_BITSPERSUBEXPL : + j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp))); + } + +// This count includes findbit, which should be set, resulting in a base-0 +// offset: + + count -= j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, findsub) + & JU_MASKHIGHERINC(JU_BITPOSMASKL(findbit))); + + DBGCODE(if (! JU_BITMAPTESTL(Pjlb, digit)) return(~count);) + assert(count >= 0); // should find Index itself. + return(count); // is already a base-0 offset. + +} // j__udyCountLeafB1() + + +// **************************************************************************** +// J U D Y J P P O P 1 +// +// This function takes any type of JP other than a root-level JP (cJU_LEAFW* or +// cJU_JPBRANCH* with no number suffix) and extracts the Pop1 from it. In some +// sense this is a wrapper around the JU_JP*_POP0 macros. Why write it as a +// function instead of a complex macro containing a trinary? (See version +// Judy1.h version 4.17.) We think its cheaper to call a function containing +// a switch statement with "constant" cases than to do the variable +// calculations in a trinary. +// +// For invalid JP Types return cJU_ALLONES. Note that this is an impossibly +// high Pop1 for any JP below a top level branch. + +FUNCTION Word_t j__udyJPPop1( +const Pjp_t Pjp) // JP to count. +{ + switch (JU_JPTYPE(Pjp)) + { +#ifdef notdef // caller should shortcut and not even call with these: + + case cJU_JPNULL1: + case cJU_JPNULL2: + case cJU_JPNULL3: return(0); +#ifdef JU_64BIT + case cJU_JPNULL4: + case cJU_JPNULL5: + case cJU_JPNULL6: + case cJU_JPNULL7: return(0); +#endif +#endif // notdef + + case cJU_JPBRANCH_L2: + case cJU_JPBRANCH_B2: + case cJU_JPBRANCH_U2: return(JU_JPBRANCH_POP0(Pjp,2) + 1); + + case cJU_JPBRANCH_L3: + case cJU_JPBRANCH_B3: + case cJU_JPBRANCH_U3: return(JU_JPBRANCH_POP0(Pjp,3) + 1); + +#ifdef JU_64BIT + case cJU_JPBRANCH_L4: + case cJU_JPBRANCH_B4: + case cJU_JPBRANCH_U4: return(JU_JPBRANCH_POP0(Pjp,4) + 1); + + case cJU_JPBRANCH_L5: + case cJU_JPBRANCH_B5: + case cJU_JPBRANCH_U5: return(JU_JPBRANCH_POP0(Pjp,5) + 1); + + case cJU_JPBRANCH_L6: + case cJU_JPBRANCH_B6: + case cJU_JPBRANCH_U6: return(JU_JPBRANCH_POP0(Pjp,6) + 1); + + case cJU_JPBRANCH_L7: + case cJU_JPBRANCH_B7: + case cJU_JPBRANCH_U7: return(JU_JPBRANCH_POP0(Pjp,7) + 1); +#endif + +#if (defined(JUDYL) || (! defined(JU_64BIT))) + case cJU_JPLEAF1: +#endif + case cJU_JPLEAF2: + case cJU_JPLEAF3: +#ifdef JU_64BIT + case cJU_JPLEAF4: + case cJU_JPLEAF5: + case cJU_JPLEAF6: + case cJU_JPLEAF7: +#endif + case cJU_JPLEAF_B1: return(JU_JPLEAF_POP0(Pjp) + 1); + +#ifdef JUDY1 + case cJ1_JPFULLPOPU1: return(cJU_JPFULLPOPU1_POP0 + 1); +#endif + + case cJU_JPIMMED_1_01: + case cJU_JPIMMED_2_01: + case cJU_JPIMMED_3_01: return(1); +#ifdef JU_64BIT + case cJU_JPIMMED_4_01: + case cJU_JPIMMED_5_01: + case cJU_JPIMMED_6_01: + case cJU_JPIMMED_7_01: return(1); +#endif + + case cJU_JPIMMED_1_02: return(2); + case cJU_JPIMMED_1_03: return(3); +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_1_04: return(4); + case cJU_JPIMMED_1_05: return(5); + case cJU_JPIMMED_1_06: return(6); + case cJU_JPIMMED_1_07: return(7); +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_1_08: return(8); + case cJ1_JPIMMED_1_09: return(9); + case cJ1_JPIMMED_1_10: return(10); + case cJ1_JPIMMED_1_11: return(11); + case cJ1_JPIMMED_1_12: return(12); + case cJ1_JPIMMED_1_13: return(13); + case cJ1_JPIMMED_1_14: return(14); + case cJ1_JPIMMED_1_15: return(15); +#endif + +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_2_02: return(2); + case cJU_JPIMMED_2_03: return(3); +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_2_04: return(4); + case cJ1_JPIMMED_2_05: return(5); + case cJ1_JPIMMED_2_06: return(6); + case cJ1_JPIMMED_2_07: return(7); +#endif + +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_3_02: return(2); +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_3_03: return(3); + case cJ1_JPIMMED_3_04: return(4); + case cJ1_JPIMMED_3_05: return(5); + + case cJ1_JPIMMED_4_02: return(2); + case cJ1_JPIMMED_4_03: return(3); + + case cJ1_JPIMMED_5_02: return(2); + case cJ1_JPIMMED_5_03: return(3); + + case cJ1_JPIMMED_6_02: return(2); + + case cJ1_JPIMMED_7_02: return(2); +#endif + + default: return(cJU_ALLONES); + } + + /*NOTREACHED*/ + +} // j__udyJPPop1() diff --git a/feeds/p4/libjudy/src/src/JudyCommon/JudyCreateBranch.c b/feeds/p4/libjudy/src/src/JudyCommon/JudyCreateBranch.c new file mode 100644 index 000000000..ffe6b3bde --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudyCommon/JudyCreateBranch.c @@ -0,0 +1,314 @@ +// Copyright (C) 2000 - 2002 Hewlett-Packard Company +// +// This program is free software; you can redistribute it and/or modify it +// under the term of the GNU Lesser 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 Lesser General Public License +// for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// _________________ + +// @(#) $Revision: 4.26 $ $Source: /judy/src/JudyCommon/JudyCreateBranch.c $ + +// Branch creation functions for Judy1 and JudyL. +// Compile with one of -DJUDY1 or -DJUDYL. + +#if (! (defined(JUDY1) || defined(JUDYL))) +#error: One of -DJUDY1 or -DJUDYL must be specified. +#endif + +#ifdef JUDY1 +#include "Judy1.h" +#else +#include "JudyL.h" +#endif + +#include "JudyPrivate1L.h" + + +// **************************************************************************** +// J U D Y C R E A T E B R A N C H L +// +// Build a BranchL from an array of JPs and associated 1 byte digits +// (expanses). Return with Pjp pointing to the BranchL. Caller must +// deallocate passed arrays, if necessary. +// +// We have no idea what kind of BranchL it is, so caller must set the jp_Type. +// +// Return -1 if error (details in Pjpm), otherwise return 1. + +FUNCTION int j__udyCreateBranchL( + Pjp_t Pjp, // Build JPs from this place + Pjp_t PJPs, // Array of JPs to put into Bitmap branch + uint8_t Exp[], // Array of expanses to put into bitmap + Word_t ExpCnt, // Number of above JPs and Expanses + Pvoid_t Pjpm) +{ + Pjbl_t PjblRaw; // pointer to linear branch. + Pjbl_t Pjbl; + + assert(ExpCnt <= cJU_BRANCHLMAXJPS); + + PjblRaw = j__udyAllocJBL(Pjpm); + if (PjblRaw == (Pjbl_t) NULL) return(-1); + Pjbl = P_JBL(PjblRaw); + +// Build a Linear Branch + Pjbl->jbl_NumJPs = ExpCnt; + +// Copy from the Linear branch from splayed leaves + JU_COPYMEM(Pjbl->jbl_Expanse, Exp, ExpCnt); + JU_COPYMEM(Pjbl->jbl_jp, PJPs, ExpCnt); + +// Pass back new pointer to the Linear branch in JP + Pjp->jp_Addr = (Word_t) PjblRaw; + + return(1); + +} // j__udyCreateBranchL() + + +// **************************************************************************** +// J U D Y C R E A T E B R A N C H B +// +// Build a BranchB from an array of JPs and associated 1 byte digits +// (expanses). Return with Pjp pointing to the BranchB. Caller must +// deallocate passed arrays, if necessary. +// +// We have no idea what kind of BranchB it is, so caller must set the jp_Type. +// +// Return -1 if error (details in Pjpm), otherwise return 1. + +FUNCTION int j__udyCreateBranchB( + Pjp_t Pjp, // Build JPs from this place + Pjp_t PJPs, // Array of JPs to put into Bitmap branch + uint8_t Exp[], // Array of expanses to put into bitmap + Word_t ExpCnt, // Number of above JPs and Expanses + Pvoid_t Pjpm) +{ + Pjbb_t PjbbRaw; // pointer to bitmap branch. + Pjbb_t Pjbb; + Word_t ii, jj; // Temps + uint8_t CurrSubExp; // Current sub expanse for BM + +// This assertion says the number of populated subexpanses is not too large. +// This function is only called when a BranchL overflows to a BranchB or when a +// cascade occurs, meaning a leaf overflows. Either way ExpCnt cant be very +// large, in fact a lot smaller than cJU_BRANCHBMAXJPS. (Otherwise a BranchU +// would be used.) Popping this assertion means something (unspecified) has +// gone very wrong, or else Judys design criteria have changed, although in +// fact there should be no HARM in creating a BranchB with higher actual +// fanout. + + assert(ExpCnt <= cJU_BRANCHBMAXJPS); + +// Get memory for a Bitmap branch + PjbbRaw = j__udyAllocJBB(Pjpm); + if (PjbbRaw == (Pjbb_t) NULL) return(-1); + Pjbb = P_JBB(PjbbRaw); + +// Get 1st "sub" expanse (0..7) of bitmap branch + CurrSubExp = Exp[0] / cJU_BITSPERSUBEXPB; + +// Index thru all 1 byte sized expanses: + + for (jj = ii = 0; ii <= ExpCnt; ii++) + { + Word_t SubExp; // Cannot be a uint8_t + +// Make sure we cover the last one + if (ii == ExpCnt) + { + SubExp = cJU_ALLONES; // Force last one + } + else + { +// Calculate the "sub" expanse of the byte expanse + SubExp = Exp[ii] / cJU_BITSPERSUBEXPB; // Bits 5..7. + +// Set the bit that represents the expanse in Exp[] + JU_JBB_BITMAP(Pjbb, SubExp) |= JU_BITPOSMASKB(Exp[ii]); + } +// Check if a new "sub" expanse range needed + if (SubExp != CurrSubExp) + { +// Get number of JPs in this sub expanse + Word_t NumJP = ii - jj; + Pjp_t PjpRaw; + Pjp_t Pjp; + + PjpRaw = j__udyAllocJBBJP(NumJP, Pjpm); + Pjp = P_JP(PjpRaw); + + if (PjpRaw == (Pjp_t) NULL) // out of memory. + { + +// Free any previous allocations: + + while(CurrSubExp--) + { + NumJP = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, + CurrSubExp)); + if (NumJP) + { + j__udyFreeJBBJP(JU_JBB_PJP(Pjbb, + CurrSubExp), NumJP, Pjpm); + } + } + j__udyFreeJBB(PjbbRaw, Pjpm); + return(-1); + } + +// Place the array of JPs in bitmap branch: + + JU_JBB_PJP(Pjbb, CurrSubExp) = PjpRaw; + +// Copy the JPs to new leaf: + + JU_COPYMEM(Pjp, PJPs + jj, NumJP); + +// On to the next bitmap branch "sub" expanse: + + jj = ii; + CurrSubExp = SubExp; + } + } // for each 1-byte expanse + +// Pass back some of the JP to the new Bitmap branch: + + Pjp->jp_Addr = (Word_t) PjbbRaw; + + return(1); + +} // j__udyCreateBranchB() + + +// **************************************************************************** +// J U D Y C R E A T E B R A N C H U +// +// Build a BranchU from a BranchB. Return with Pjp pointing to the BranchU. +// Free the BranchB and its JP subarrays. +// +// Return -1 if error (details in Pjpm), otherwise return 1. + +FUNCTION int j__udyCreateBranchU( + Pjp_t Pjp, + Pvoid_t Pjpm) +{ + jp_t JPNull; + Pjbu_t PjbuRaw; + Pjbu_t Pjbu; + Pjbb_t PjbbRaw; + Pjbb_t Pjbb; + Word_t ii, jj; + BITMAPB_t BitMap; + Pjp_t PDstJP; +#ifdef JU_STAGED_EXP + jbu_t BranchU; // Staged uncompressed branch +#else + +// Allocate memory for a BranchU: + + PjbuRaw = j__udyAllocJBU(Pjpm); + if (PjbuRaw == (Pjbu_t) NULL) return(-1); + Pjbu = P_JBU(PjbuRaw); +#endif + JU_JPSETADT(&JPNull, 0, 0, JU_JPTYPE(Pjp) - cJU_JPBRANCH_B2 + cJU_JPNULL1); + +// Get the pointer to the BranchB: + + PjbbRaw = (Pjbb_t) (Pjp->jp_Addr); + Pjbb = P_JBB(PjbbRaw); + +// Set the pointer to the Uncompressed branch +#ifdef JU_STAGED_EXP + PDstJP = BranchU.jbu_jp; +#else + PDstJP = Pjbu->jbu_jp; +#endif + for (ii = 0; ii < cJU_NUMSUBEXPB; ii++) + { + Pjp_t PjpA; + Pjp_t PjpB; + + PjpB = PjpA = P_JP(JU_JBB_PJP(Pjbb, ii)); + +// Get the bitmap for this subexpanse + BitMap = JU_JBB_BITMAP(Pjbb, ii); + +// NULL empty subexpanses + if (BitMap == 0) + { +// But, fill with NULLs + for (jj = 0; jj < cJU_BITSPERSUBEXPB; jj++) + { + PDstJP[jj] = JPNull; + } + PDstJP += cJU_BITSPERSUBEXPB; + continue; + } +// Check if Uncompressed subexpanse + if (BitMap == cJU_FULLBITMAPB) + { +// Copy subexpanse to the Uncompressed branch intact + JU_COPYMEM(PDstJP, PjpA, cJU_BITSPERSUBEXPB); + +// Bump to next subexpanse + PDstJP += cJU_BITSPERSUBEXPB; + +// Set length of subexpanse + jj = cJU_BITSPERSUBEXPB; + } + else + { + for (jj = 0; jj < cJU_BITSPERSUBEXPB; jj++) + { +// Copy JP or NULLJP depending on bit + if (BitMap & 1) { *PDstJP = *PjpA++; } + else { *PDstJP = JPNull; } + + PDstJP++; // advance to next JP + BitMap >>= 1; + } + jj = PjpA - PjpB; + } + +// Free the subexpanse: + + j__udyFreeJBBJP(JU_JBB_PJP(Pjbb, ii), jj, Pjpm); + + } // for each JP in BranchU + +#ifdef JU_STAGED_EXP + +// Allocate memory for a BranchU: + + PjbuRaw = j__udyAllocJBU(Pjpm); + if (PjbuRaw == (Pjbu_t) NULL) return(-1); + Pjbu = P_JBU(PjbuRaw); + +// Copy staged branch to newly allocated branch: +// +// TBD: I think this code is broken. + + *Pjbu = BranchU; + +#endif // JU_STAGED_EXP + +// Finally free the BranchB and put the BranchU in its place: + + j__udyFreeJBB(PjbbRaw, Pjpm); + + Pjp->jp_Addr = (Word_t) PjbuRaw; + Pjp->jp_Type += cJU_JPBRANCH_U - cJU_JPBRANCH_B; + + return(1); + +} // j__udyCreateBranchU() diff --git a/feeds/p4/libjudy/src/src/JudyCommon/JudyDecascade.c b/feeds/p4/libjudy/src/src/JudyCommon/JudyDecascade.c new file mode 100644 index 000000000..39a89eff1 --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudyCommon/JudyDecascade.c @@ -0,0 +1,1206 @@ +// Copyright (C) 2000 - 2002 Hewlett-Packard Company +// +// This program is free software; you can redistribute it and/or modify it +// under the term of the GNU Lesser 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 Lesser General Public License +// for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// _________________ + +// @(#) $Revision: 4.25 $ $Source: /judy/src/JudyCommon/JudyDecascade.c $ +// +// "Decascade" support functions for JudyDel.c: These functions convert +// smaller-index-size leaves to larger-index-size leaves, and also, bitmap +// leaves (LeafB1s) to Leaf1s, and some types of branches to smaller branches +// at the same index size. Some "decascading" occurs explicitly in JudyDel.c, +// but rare or large subroutines appear as functions here, and the overhead to +// call them is negligible. +// +// Compile with one of -DJUDY1 or -DJUDYL. Note: Function names are converted +// to Judy1 or JudyL specific values by external #defines. + +#if (! (defined(JUDY1) || defined(JUDYL))) +#error: One of -DJUDY1 or -DJUDYL must be specified. +#endif + +#ifdef JUDY1 +#include "Judy1.h" +#endif +#ifdef JUDYL +#include "JudyL.h" +#endif + +#include "JudyPrivate1L.h" + +DBGCODE(extern void JudyCheckSorted(Pjll_t Pjll, Word_t Pop1, long IndexSize);) + + +// **************************************************************************** +// __ J U D Y C O P Y 2 T O 3 +// +// Copy one or more 2-byte Indexes to a series of 3-byte Indexes. + +FUNCTION static void j__udyCopy2to3( + uint8_t * PDest, // to where to copy 3-byte Indexes. + uint16_t * PSrc, // from where to copy 2-byte indexes. + Word_t Pop1, // number of Indexes to copy. + Word_t MSByte) // most-significant byte, prefix to each Index. +{ + Word_t Temp; // for building 3-byte Index. + + assert(Pop1); + + do { + Temp = MSByte | *PSrc++; + JU_COPY3_LONG_TO_PINDEX(PDest, Temp); + PDest += 3; + } while (--Pop1); + +} // j__udyCopy2to3() + + +#ifdef JU_64BIT + +// **************************************************************************** +// __ J U D Y C O P Y 3 T O 4 +// +// Copy one or more 3-byte Indexes to a series of 4-byte Indexes. + +FUNCTION static void j__udyCopy3to4( + uint32_t * PDest, // to where to copy 4-byte Indexes. + uint8_t * PSrc, // from where to copy 3-byte indexes. + Word_t Pop1, // number of Indexes to copy. + Word_t MSByte) // most-significant byte, prefix to each Index. +{ + Word_t Temp; // for building 4-byte Index. + + assert(Pop1); + + do { + JU_COPY3_PINDEX_TO_LONG(Temp, PSrc); + Temp |= MSByte; + PSrc += 3; + *PDest++ = Temp; // truncates to uint32_t. + } while (--Pop1); + +} // j__udyCopy3to4() + + +// **************************************************************************** +// __ J U D Y C O P Y 4 T O 5 +// +// Copy one or more 4-byte Indexes to a series of 5-byte Indexes. + +FUNCTION static void j__udyCopy4to5( + uint8_t * PDest, // to where to copy 4-byte Indexes. + uint32_t * PSrc, // from where to copy 4-byte indexes. + Word_t Pop1, // number of Indexes to copy. + Word_t MSByte) // most-significant byte, prefix to each Index. +{ + Word_t Temp; // for building 5-byte Index. + + assert(Pop1); + + do { + Temp = MSByte | *PSrc++; + JU_COPY5_LONG_TO_PINDEX(PDest, Temp); + PDest += 5; + } while (--Pop1); + +} // j__udyCopy4to5() + + +// **************************************************************************** +// __ J U D Y C O P Y 5 T O 6 +// +// Copy one or more 5-byte Indexes to a series of 6-byte Indexes. + +FUNCTION static void j__udyCopy5to6( + uint8_t * PDest, // to where to copy 6-byte Indexes. + uint8_t * PSrc, // from where to copy 5-byte indexes. + Word_t Pop1, // number of Indexes to copy. + Word_t MSByte) // most-significant byte, prefix to each Index. +{ + Word_t Temp; // for building 6-byte Index. + + assert(Pop1); + + do { + JU_COPY5_PINDEX_TO_LONG(Temp, PSrc); + Temp |= MSByte; + JU_COPY6_LONG_TO_PINDEX(PDest, Temp); + PSrc += 5; + PDest += 6; + } while (--Pop1); + +} // j__udyCopy5to6() + + +// **************************************************************************** +// __ J U D Y C O P Y 6 T O 7 +// +// Copy one or more 6-byte Indexes to a series of 7-byte Indexes. + +FUNCTION static void j__udyCopy6to7( + uint8_t * PDest, // to where to copy 6-byte Indexes. + uint8_t * PSrc, // from where to copy 5-byte indexes. + Word_t Pop1, // number of Indexes to copy. + Word_t MSByte) // most-significant byte, prefix to each Index. +{ + Word_t Temp; // for building 6-byte Index. + + assert(Pop1); + + do { + JU_COPY6_PINDEX_TO_LONG(Temp, PSrc); + Temp |= MSByte; + JU_COPY7_LONG_TO_PINDEX(PDest, Temp); + PSrc += 6; + PDest += 7; + } while (--Pop1); + +} // j__udyCopy6to7() + +#endif // JU_64BIT + + +#ifndef JU_64BIT // 32-bit + +// **************************************************************************** +// __ J U D Y C O P Y 3 T O W +// +// Copy one or more 3-byte Indexes to a series of longs (words, always 4-byte). + +FUNCTION static void j__udyCopy3toW( + PWord_t PDest, // to where to copy full-word Indexes. + uint8_t * PSrc, // from where to copy 3-byte indexes. + Word_t Pop1, // number of Indexes to copy. + Word_t MSByte) // most-significant byte, prefix to each Index. +{ + assert(Pop1); + + do { + JU_COPY3_PINDEX_TO_LONG(*PDest, PSrc); + *PDest++ |= MSByte; + PSrc += 3; + } while (--Pop1); + +} // j__udyCopy3toW() + + +#else // JU_64BIT + +// **************************************************************************** +// __ J U D Y C O P Y 7 T O W +// +// Copy one or more 7-byte Indexes to a series of longs (words, always 8-byte). + +FUNCTION static void j__udyCopy7toW( + PWord_t PDest, // to where to copy full-word Indexes. + uint8_t * PSrc, // from where to copy 7-byte indexes. + Word_t Pop1, // number of Indexes to copy. + Word_t MSByte) // most-significant byte, prefix to each Index. +{ + assert(Pop1); + + do { + JU_COPY7_PINDEX_TO_LONG(*PDest, PSrc); + *PDest++ |= MSByte; + PSrc += 7; + } while (--Pop1); + +} // j__udyCopy7toW() + +#endif // JU_64BIT + + +// **************************************************************************** +// __ J U D Y B R A N C H B T O B R A N C H L +// +// When a BranchB shrinks to have few enough JPs, call this function to convert +// it to a BranchL. Return 1 for success, or -1 for failure (with details in +// Pjpm). + +FUNCTION int j__udyBranchBToBranchL( + Pjp_t Pjp, // points to BranchB to shrink. + Pvoid_t Pjpm) // for global accounting. +{ + Pjbb_t PjbbRaw; // old BranchB to shrink. + Pjbb_t Pjbb; + Pjbl_t PjblRaw; // new BranchL to create. + Pjbl_t Pjbl; + Word_t Digit; // in BranchB. + Word_t NumJPs; // non-null JPs in BranchB. + uint8_t Expanse[cJU_BRANCHLMAXJPS]; // for building jbl_Expanse[]. + Pjp_t Pjpjbl; // current JP in BranchL. + Word_t SubExp; // in BranchB. + + assert(JU_JPTYPE(Pjp) >= cJU_JPBRANCH_B2); + assert(JU_JPTYPE(Pjp) <= cJU_JPBRANCH_B); + + PjbbRaw = (Pjbb_t) (Pjp->jp_Addr); + Pjbb = P_JBB(PjbbRaw); + +// Copy 1-byte subexpanse digits from BranchB to temporary buffer for BranchL, +// for each bit set in the BranchB: +// +// TBD: The following supports variable-sized linear branches, but they are no +// longer variable; this could be simplified to save the copying. +// +// TBD: Since cJU_BRANCHLMAXJP == 7 now, and cJU_BRANCHUNUMJPS == 256, the +// following might be inefficient; is there a faster way to do it? At least +// skip wholly empty subexpanses? + + for (NumJPs = Digit = 0; Digit < cJU_BRANCHUNUMJPS; ++Digit) + { + if (JU_BITMAPTESTB(Pjbb, Digit)) + { + Expanse[NumJPs++] = Digit; + assert(NumJPs <= cJU_BRANCHLMAXJPS); // required of caller. + } + } + +// Allocate and populate the BranchL: + + if ((PjblRaw = j__udyAllocJBL(Pjpm)) == (Pjbl_t) NULL) return(-1); + Pjbl = P_JBL(PjblRaw); + + JU_COPYMEM(Pjbl->jbl_Expanse, Expanse, NumJPs); + + Pjbl->jbl_NumJPs = NumJPs; + DBGCODE(JudyCheckSorted((Pjll_t) (Pjbl->jbl_Expanse), NumJPs, 1);) + +// Copy JPs from each BranchB subexpanse subarray: + + Pjpjbl = P_JP(Pjbl->jbl_jp); // start at first JP in array. + + for (SubExp = 0; SubExp < cJU_NUMSUBEXPB; ++SubExp) + { + Pjp_t PjpRaw = JU_JBB_PJP(Pjbb, SubExp); // current Pjp. + Pjp_t Pjp; + + if (PjpRaw == (Pjp_t) NULL) continue; // skip empty subexpanse. + Pjp = P_JP(PjpRaw); + + NumJPs = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, SubExp)); + assert(NumJPs); + JU_COPYMEM(Pjpjbl, Pjp, NumJPs); // one subarray at a time. + + Pjpjbl += NumJPs; + j__udyFreeJBBJP(PjpRaw, NumJPs, Pjpm); // subarray. + } + j__udyFreeJBB(PjbbRaw, Pjpm); // BranchB itself. + +// Finish up: Calculate new JP type (same index size = level in new class), +// and tie new BranchB into parent JP: + + Pjp->jp_Type += cJU_JPBRANCH_L - cJU_JPBRANCH_B; + Pjp->jp_Addr = (Word_t) PjblRaw; + + return(1); + +} // j__udyBranchBToBranchL() + + +#ifdef notdef + +// **************************************************************************** +// __ J U D Y B R A N C H U T O B R A N C H B +// +// When a BranchU shrinks to need little enough memory, call this function to +// convert it to a BranchB to save memory (at the cost of some speed). Return +// 1 for success, or -1 for failure (with details in Pjpm). +// +// TBD: Fill out if/when needed. Not currently used in JudyDel.c for reasons +// explained there. + +FUNCTION int j__udyBranchUToBranchB( + Pjp_t Pjp, // points to BranchU to shrink. + Pvoid_t Pjpm) // for global accounting. +{ + assert(FALSE); + return(1); +} +#endif // notdef + + +#if (defined(JUDYL) || (! defined(JU_64BIT))) + +// **************************************************************************** +// __ J U D Y L E A F B 1 T O L E A F 1 +// +// Shrink a bitmap leaf (cJU_LEAFB1) to linear leaf (cJU_JPLEAF1). +// Return 1 for success, or -1 for failure (with details in Pjpm). +// +// Note: This function is different than the other JudyLeaf*ToLeaf*() +// functions because it receives a Pjp, not just a leaf, and handles its own +// allocation and free, in order to allow the caller to continue with a LeafB1 +// if allocation fails. + +FUNCTION int j__udyLeafB1ToLeaf1( + Pjp_t Pjp, // points to LeafB1 to shrink. + Pvoid_t Pjpm) // for global accounting. +{ + Pjlb_t PjlbRaw; // bitmap in old leaf. + Pjlb_t Pjlb; + Pjll_t PjllRaw; // new Leaf1. + uint8_t * Pleaf1; // Leaf1 pointer type. + Word_t Digit; // in LeafB1 bitmap. +#ifdef JUDYL + Pjv_t PjvNew; // value area in new Leaf1. + Word_t Pop1; + Word_t SubExp; +#endif + + assert(JU_JPTYPE(Pjp) == cJU_JPLEAF_B1); + assert(((JU_JPDCDPOP0(Pjp) & 0xFF) + 1) == cJU_LEAF1_MAXPOP1); + +// Allocate JPLEAF1 and prepare pointers: + + if ((PjllRaw = j__udyAllocJLL1(cJU_LEAF1_MAXPOP1, Pjpm)) == 0) + return(-1); + + Pleaf1 = (uint8_t *) P_JLL(PjllRaw); + PjlbRaw = (Pjlb_t) (Pjp->jp_Addr); + Pjlb = P_JLB(PjlbRaw); + JUDYLCODE(PjvNew = JL_LEAF1VALUEAREA(Pleaf1, cJL_LEAF1_MAXPOP1);) + +// Copy 1-byte indexes from old LeafB1 to new Leaf1: + + for (Digit = 0; Digit < cJU_BRANCHUNUMJPS; ++Digit) + if (JU_BITMAPTESTL(Pjlb, Digit)) + *Pleaf1++ = Digit; + +#ifdef JUDYL + +// Copy all old-LeafB1 value areas from value subarrays to new Leaf1: + + for (SubExp = 0; SubExp < cJU_NUMSUBEXPL; ++SubExp) + { + Pjv_t PjvRaw = JL_JLB_PVALUE(Pjlb, SubExp); + Pjv_t Pjv = P_JV(PjvRaw); + + if (Pjv == (Pjv_t) NULL) continue; // skip empty subarray. + + Pop1 = j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, SubExp)); // subarray. + assert(Pop1); + + JU_COPYMEM(PjvNew, Pjv, Pop1); // copy value areas. + j__udyLFreeJV(PjvRaw, Pop1, Pjpm); + PjvNew += Pop1; // advance through new. + } + + assert((((Word_t) Pleaf1) - (Word_t) P_JLL(PjllRaw)) + == (PjvNew - JL_LEAF1VALUEAREA(P_JLL(PjllRaw), cJL_LEAF1_MAXPOP1))); +#endif // JUDYL + + DBGCODE(JudyCheckSorted((Pjll_t) P_JLL(PjllRaw), + (((Word_t) Pleaf1) - (Word_t) P_JLL(PjllRaw)), 1);) + +// Finish up: Free the old LeafB1 and plug the new Leaf1 into the JP: +// +// Note: jp_DcdPopO does not change here. + + j__udyFreeJLB1(PjlbRaw, Pjpm); + + Pjp->jp_Addr = (Word_t) PjllRaw; + Pjp->jp_Type = cJU_JPLEAF1; + + return(1); + +} // j__udyLeafB1ToLeaf1() + +#endif // (JUDYL || (! JU_64BIT)) + + +// **************************************************************************** +// __ J U D Y L E A F 1 T O L E A F 2 +// +// Copy 1-byte Indexes from a LeafB1 or Leaf1 to 2-byte Indexes in a Leaf2. +// Pjp MUST be one of: cJU_JPLEAF_B1, cJU_JPLEAF1, or cJU_JPIMMED_1_*. +// Return number of Indexes copied. +// +// TBD: In this and all following functions, the caller should already be able +// to compute the Pop1 return value, so why return it? + +FUNCTION Word_t j__udyLeaf1ToLeaf2( + uint16_t * PLeaf2, // destination uint16_t * Index portion of leaf. +#ifdef JUDYL + Pjv_t Pjv2, // destination value part of leaf. +#endif + Pjp_t Pjp, // 1-byte-index object from which to copy. + Word_t MSByte, // most-significant byte, prefix to each Index. + Pvoid_t Pjpm) // for global accounting. +{ + Word_t Pop1; // Indexes in leaf. + Word_t Offset; // in linear leaf list. +JUDYLCODE(Pjv_t Pjv1Raw;) // source object value area. +JUDYLCODE(Pjv_t Pjv1;) + + switch (JU_JPTYPE(Pjp)) + { + + +// JPLEAF_B1: + + case cJU_JPLEAF_B1: + { + Pjlb_t Pjlb = P_JLB(Pjp->jp_Addr); + Word_t Digit; // in LeafB1 bitmap. + JUDYLCODE(Word_t SubExp;) // in LeafB1. + + Pop1 = JU_JPBRANCH_POP0(Pjp, 1) + 1; assert(Pop1); + +// Copy 1-byte indexes from old LeafB1 to new Leaf2, including splicing in +// the missing MSByte needed in the Leaf2: + + for (Digit = 0; Digit < cJU_BRANCHUNUMJPS; ++Digit) + if (JU_BITMAPTESTL(Pjlb, Digit)) + *PLeaf2++ = MSByte | Digit; + +#ifdef JUDYL + +// Copy all old-LeafB1 value areas from value subarrays to new Leaf2: + + for (SubExp = 0; SubExp < cJU_NUMSUBEXPL; ++SubExp) + { + Word_t SubExpPop1; + + Pjv1Raw = JL_JLB_PVALUE(Pjlb, SubExp); + if (Pjv1Raw == (Pjv_t) NULL) continue; // skip empty. + Pjv1 = P_JV(Pjv1Raw); + + SubExpPop1 = j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, SubExp)); + assert(SubExpPop1); + + JU_COPYMEM(Pjv2, Pjv1, SubExpPop1); // copy value areas. + j__udyLFreeJV(Pjv1Raw, SubExpPop1, Pjpm); + Pjv2 += SubExpPop1; // advance through new. + } +#endif // JUDYL + + j__udyFreeJLB1((Pjlb_t) (Pjp->jp_Addr), Pjpm); // LeafB1 itself. + return(Pop1); + + } // case cJU_JPLEAF_B1 + + +#if (defined(JUDYL) || (! defined(JU_64BIT))) + +// JPLEAF1: + + case cJU_JPLEAF1: + { + uint8_t * PLeaf1 = (uint8_t *) P_JLL(Pjp->jp_Addr); + + Pop1 = JU_JPBRANCH_POP0(Pjp, 1) + 1; assert(Pop1); + JUDYLCODE(Pjv1 = JL_LEAF1VALUEAREA(PLeaf1, Pop1);) + +// Copy all Index bytes including splicing in missing MSByte needed in Leaf2 +// (plus, for JudyL, value areas): + + for (Offset = 0; Offset < Pop1; ++Offset) + { + PLeaf2[Offset] = MSByte | PLeaf1[Offset]; + JUDYLCODE(Pjv2[Offset] = Pjv1[Offset];) + } + j__udyFreeJLL1((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm); + return(Pop1); + } +#endif // (JUDYL || (! JU_64BIT)) + + +// JPIMMED_1_01: +// +// Note: jp_DcdPopO has 3 [7] bytes of Index (all but most significant byte), +// so the assignment to PLeaf2[] truncates and MSByte is not needed. + + case cJU_JPIMMED_1_01: + { + PLeaf2[0] = JU_JPDCDPOP0(Pjp); // see above. + JUDYLCODE(Pjv2[0] = Pjp->jp_Addr;) + return(1); + } + + +// JPIMMED_1_0[2+]: + + case cJU_JPIMMED_1_02: + case cJU_JPIMMED_1_03: +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_1_04: + case cJU_JPIMMED_1_05: + case cJU_JPIMMED_1_06: + case cJU_JPIMMED_1_07: +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_1_08: + case cJ1_JPIMMED_1_09: + case cJ1_JPIMMED_1_10: + case cJ1_JPIMMED_1_11: + case cJ1_JPIMMED_1_12: + case cJ1_JPIMMED_1_13: + case cJ1_JPIMMED_1_14: + case cJ1_JPIMMED_1_15: +#endif + { + Pop1 = JU_JPTYPE(Pjp) - cJU_JPIMMED_1_02 + 2; assert(Pop1); + JUDYLCODE(Pjv1Raw = (Pjv_t) (Pjp->jp_Addr);) + JUDYLCODE(Pjv1 = P_JV(Pjv1Raw);) + + for (Offset = 0; Offset < Pop1; ++Offset) + { +#ifdef JUDY1 + PLeaf2[Offset] = MSByte | Pjp->jp_1Index[Offset]; +#else + PLeaf2[Offset] = MSByte | Pjp->jp_LIndex[Offset]; + Pjv2 [Offset] = Pjv1[Offset]; +#endif + } + JUDYLCODE(j__udyLFreeJV(Pjv1Raw, Pop1, Pjpm);) + return(Pop1); + } + + +// UNEXPECTED CASES, including JPNULL1, should be handled by caller: + + default: assert(FALSE); break; + + } // switch + + return(0); + +} // j__udyLeaf1ToLeaf2() + + +// ***************************************************************************** +// __ J U D Y L E A F 2 T O L E A F 3 +// +// Copy 2-byte Indexes from a Leaf2 to 3-byte Indexes in a Leaf3. +// Pjp MUST be one of: cJU_JPLEAF2 or cJU_JPIMMED_2_*. +// Return number of Indexes copied. +// +// Note: By the time this function is called to compress a level-3 branch to a +// Leaf3, the branch has no narrow pointers under it, meaning only level-2 +// objects are below it and must be handled here. + +FUNCTION Word_t j__udyLeaf2ToLeaf3( + uint8_t * PLeaf3, // destination "uint24_t *" Index part of leaf. +#ifdef JUDYL + Pjv_t Pjv3, // destination value part of leaf. +#endif + Pjp_t Pjp, // 2-byte-index object from which to copy. + Word_t MSByte, // most-significant byte, prefix to each Index. + Pvoid_t Pjpm) // for global accounting. +{ + Word_t Pop1; // Indexes in leaf. +#if (defined(JUDYL) && defined(JU_64BIT)) + Pjv_t Pjv2Raw; // source object value area. +#endif +JUDYLCODE(Pjv_t Pjv2;) + + switch (JU_JPTYPE(Pjp)) + { + + +// JPLEAF2: + + case cJU_JPLEAF2: + { + uint16_t * PLeaf2 = (uint16_t *) P_JLL(Pjp->jp_Addr); + + Pop1 = JU_JPLEAF_POP0(Pjp) + 1; assert(Pop1); + j__udyCopy2to3(PLeaf3, PLeaf2, Pop1, MSByte); +#ifdef JUDYL + Pjv2 = JL_LEAF2VALUEAREA(PLeaf2, Pop1); + JU_COPYMEM(Pjv3, Pjv2, Pop1); +#endif + j__udyFreeJLL2((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm); + return(Pop1); + } + + +// JPIMMED_2_01: +// +// Note: jp_DcdPopO has 3 [7] bytes of Index (all but most significant byte), +// so the "assignment" to PLeaf3[] is exact [truncates] and MSByte is not +// needed. + + case cJU_JPIMMED_2_01: + { + JU_COPY3_LONG_TO_PINDEX(PLeaf3, JU_JPDCDPOP0(Pjp)); // see above. + JUDYLCODE(Pjv3[0] = Pjp->jp_Addr;) + return(1); + } + + +// JPIMMED_2_0[2+]: + +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_2_02: + case cJU_JPIMMED_2_03: +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_2_04: + case cJ1_JPIMMED_2_05: + case cJ1_JPIMMED_2_06: + case cJ1_JPIMMED_2_07: +#endif +#if (defined(JUDY1) || defined(JU_64BIT)) + { + JUDY1CODE(uint16_t * PLeaf2 = (uint16_t *) (Pjp->jp_1Index);) + JUDYLCODE(uint16_t * PLeaf2 = (uint16_t *) (Pjp->jp_LIndex);) + + Pop1 = JU_JPTYPE(Pjp) - cJU_JPIMMED_2_02 + 2; assert(Pop1); + j__udyCopy2to3(PLeaf3, PLeaf2, Pop1, MSByte); +#ifdef JUDYL + Pjv2Raw = (Pjv_t) (Pjp->jp_Addr); + Pjv2 = P_JV(Pjv2Raw); + JU_COPYMEM(Pjv3, Pjv2, Pop1); + j__udyLFreeJV(Pjv2Raw, Pop1, Pjpm); +#endif + return(Pop1); + } +#endif // (JUDY1 || JU_64BIT) + + +// UNEXPECTED CASES, including JPNULL2, should be handled by caller: + + default: assert(FALSE); break; + + } // switch + + return(0); + +} // j__udyLeaf2ToLeaf3() + + +#ifdef JU_64BIT + +// **************************************************************************** +// __ J U D Y L E A F 3 T O L E A F 4 +// +// Copy 3-byte Indexes from a Leaf3 to 4-byte Indexes in a Leaf4. +// Pjp MUST be one of: cJU_JPLEAF3 or cJU_JPIMMED_3_*. +// Return number of Indexes copied. +// +// Note: By the time this function is called to compress a level-4 branch to a +// Leaf4, the branch has no narrow pointers under it, meaning only level-3 +// objects are below it and must be handled here. + +FUNCTION Word_t j__udyLeaf3ToLeaf4( + uint32_t * PLeaf4, // destination uint32_t * Index part of leaf. +#ifdef JUDYL + Pjv_t Pjv4, // destination value part of leaf. +#endif + Pjp_t Pjp, // 3-byte-index object from which to copy. + Word_t MSByte, // most-significant byte, prefix to each Index. + Pvoid_t Pjpm) // for global accounting. +{ + Word_t Pop1; // Indexes in leaf. +JUDYLCODE(Pjv_t Pjv3Raw;) // source object value area. +JUDYLCODE(Pjv_t Pjv3;) + + switch (JU_JPTYPE(Pjp)) + { + + +// JPLEAF3: + + case cJU_JPLEAF3: + { + uint8_t * PLeaf3 = (uint8_t *) P_JLL(Pjp->jp_Addr); + + Pop1 = JU_JPLEAF_POP0(Pjp) + 1; assert(Pop1); + j__udyCopy3to4(PLeaf4, (uint8_t *) PLeaf3, Pop1, MSByte); +#ifdef JUDYL + Pjv3 = JL_LEAF3VALUEAREA(PLeaf3, Pop1); + JU_COPYMEM(Pjv4, Pjv3, Pop1); +#endif + j__udyFreeJLL3((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm); + return(Pop1); + } + + +// JPIMMED_3_01: +// +// Note: jp_DcdPopO has 7 bytes of Index (all but most significant byte), so +// the assignment to PLeaf4[] truncates and MSByte is not needed. + + case cJU_JPIMMED_3_01: + { + PLeaf4[0] = JU_JPDCDPOP0(Pjp); // see above. + JUDYLCODE(Pjv4[0] = Pjp->jp_Addr;) + return(1); + } + + +// JPIMMED_3_0[2+]: + + case cJU_JPIMMED_3_02: +#ifdef JUDY1 + case cJ1_JPIMMED_3_03: + case cJ1_JPIMMED_3_04: + case cJ1_JPIMMED_3_05: +#endif + { + JUDY1CODE(uint8_t * PLeaf3 = (uint8_t *) (Pjp->jp_1Index);) + JUDYLCODE(uint8_t * PLeaf3 = (uint8_t *) (Pjp->jp_LIndex);) + + JUDY1CODE(Pop1 = JU_JPTYPE(Pjp) - cJU_JPIMMED_3_02 + 2;) + JUDYLCODE(Pop1 = 2;) + + j__udyCopy3to4(PLeaf4, PLeaf3, Pop1, MSByte); +#ifdef JUDYL + Pjv3Raw = (Pjv_t) (Pjp->jp_Addr); + Pjv3 = P_JV(Pjv3Raw); + JU_COPYMEM(Pjv4, Pjv3, Pop1); + j__udyLFreeJV(Pjv3Raw, Pop1, Pjpm); +#endif + return(Pop1); + } + + +// UNEXPECTED CASES, including JPNULL3, should be handled by caller: + + default: assert(FALSE); break; + + } // switch + + return(0); + +} // j__udyLeaf3ToLeaf4() + + +// Note: In all following j__udyLeaf*ToLeaf*() functions, JPIMMED_*_0[2+] +// cases exist for Judy1 (&& 64-bit) only. JudyL has no equivalent Immeds. + + +// ***************************************************************************** +// __ J U D Y L E A F 4 T O L E A F 5 +// +// Copy 4-byte Indexes from a Leaf4 to 5-byte Indexes in a Leaf5. +// Pjp MUST be one of: cJU_JPLEAF4 or cJU_JPIMMED_4_*. +// Return number of Indexes copied. +// +// Note: By the time this function is called to compress a level-5 branch to a +// Leaf5, the branch has no narrow pointers under it, meaning only level-4 +// objects are below it and must be handled here. + +FUNCTION Word_t j__udyLeaf4ToLeaf5( + uint8_t * PLeaf5, // destination "uint40_t *" Index part of leaf. +#ifdef JUDYL + Pjv_t Pjv5, // destination value part of leaf. +#endif + Pjp_t Pjp, // 4-byte-index object from which to copy. + Word_t MSByte, // most-significant byte, prefix to each Index. + Pvoid_t Pjpm) // for global accounting. +{ + Word_t Pop1; // Indexes in leaf. +JUDYLCODE(Pjv_t Pjv4;) // source object value area. + + switch (JU_JPTYPE(Pjp)) + { + + +// JPLEAF4: + + case cJU_JPLEAF4: + { + uint32_t * PLeaf4 = (uint32_t *) P_JLL(Pjp->jp_Addr); + + Pop1 = JU_JPLEAF_POP0(Pjp) + 1; assert(Pop1); + j__udyCopy4to5(PLeaf5, PLeaf4, Pop1, MSByte); +#ifdef JUDYL + Pjv4 = JL_LEAF4VALUEAREA(PLeaf4, Pop1); + JU_COPYMEM(Pjv5, Pjv4, Pop1); +#endif + j__udyFreeJLL4((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm); + return(Pop1); + } + + +// JPIMMED_4_01: +// +// Note: jp_DcdPopO has 7 bytes of Index (all but most significant byte), so +// the assignment to PLeaf5[] truncates and MSByte is not needed. + + case cJU_JPIMMED_4_01: + { + JU_COPY5_LONG_TO_PINDEX(PLeaf5, JU_JPDCDPOP0(Pjp)); // see above. + JUDYLCODE(Pjv5[0] = Pjp->jp_Addr;) + return(1); + } + + +#ifdef JUDY1 + +// JPIMMED_4_0[4+]: + + case cJ1_JPIMMED_4_02: + case cJ1_JPIMMED_4_03: + { + uint32_t * PLeaf4 = (uint32_t *) (Pjp->jp_1Index); + + Pop1 = JU_JPTYPE(Pjp) - cJ1_JPIMMED_4_02 + 2; + j__udyCopy4to5(PLeaf5, PLeaf4, Pop1, MSByte); + return(Pop1); + } +#endif // JUDY1 + + +// UNEXPECTED CASES, including JPNULL4, should be handled by caller: + + default: assert(FALSE); break; + + } // switch + + return(0); + +} // j__udyLeaf4ToLeaf5() + + +// **************************************************************************** +// __ J U D Y L E A F 5 T O L E A F 6 +// +// Copy 5-byte Indexes from a Leaf5 to 6-byte Indexes in a Leaf6. +// Pjp MUST be one of: cJU_JPLEAF5 or cJU_JPIMMED_5_*. +// Return number of Indexes copied. +// +// Note: By the time this function is called to compress a level-6 branch to a +// Leaf6, the branch has no narrow pointers under it, meaning only level-5 +// objects are below it and must be handled here. + +FUNCTION Word_t j__udyLeaf5ToLeaf6( + uint8_t * PLeaf6, // destination uint8_t * Index part of leaf. +#ifdef JUDYL + Pjv_t Pjv6, // destination value part of leaf. +#endif + Pjp_t Pjp, // 5-byte-index object from which to copy. + Word_t MSByte, // most-significant byte, prefix to each Index. + Pvoid_t Pjpm) // for global accounting. +{ + Word_t Pop1; // Indexes in leaf. +JUDYLCODE(Pjv_t Pjv5;) // source object value area. + + switch (JU_JPTYPE(Pjp)) + { + + +// JPLEAF5: + + case cJU_JPLEAF5: + { + uint8_t * PLeaf5 = (uint8_t *) P_JLL(Pjp->jp_Addr); + + Pop1 = JU_JPLEAF_POP0(Pjp) + 1; assert(Pop1); + j__udyCopy5to6(PLeaf6, PLeaf5, Pop1, MSByte); +#ifdef JUDYL + Pjv5 = JL_LEAF5VALUEAREA(PLeaf5, Pop1); + JU_COPYMEM(Pjv6, Pjv5, Pop1); +#endif + j__udyFreeJLL5((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm); + return(Pop1); + } + + +// JPIMMED_5_01: +// +// Note: jp_DcdPopO has 7 bytes of Index (all but most significant byte), so +// the assignment to PLeaf6[] truncates and MSByte is not needed. + + case cJU_JPIMMED_5_01: + { + JU_COPY6_LONG_TO_PINDEX(PLeaf6, JU_JPDCDPOP0(Pjp)); // see above. + JUDYLCODE(Pjv6[0] = Pjp->jp_Addr;) + return(1); + } + + +#ifdef JUDY1 + +// JPIMMED_5_0[2+]: + + case cJ1_JPIMMED_5_02: + case cJ1_JPIMMED_5_03: + { + uint8_t * PLeaf5 = (uint8_t *) (Pjp->jp_1Index); + + Pop1 = JU_JPTYPE(Pjp) - cJ1_JPIMMED_5_02 + 2; + j__udyCopy5to6(PLeaf6, PLeaf5, Pop1, MSByte); + return(Pop1); + } +#endif // JUDY1 + + +// UNEXPECTED CASES, including JPNULL5, should be handled by caller: + + default: assert(FALSE); break; + + } // switch + + return(0); + +} // j__udyLeaf5ToLeaf6() + + +// ***************************************************************************** +// __ J U D Y L E A F 6 T O L E A F 7 +// +// Copy 6-byte Indexes from a Leaf2 to 7-byte Indexes in a Leaf7. +// Pjp MUST be one of: cJU_JPLEAF6 or cJU_JPIMMED_6_*. +// Return number of Indexes copied. +// +// Note: By the time this function is called to compress a level-7 branch to a +// Leaf7, the branch has no narrow pointers under it, meaning only level-6 +// objects are below it and must be handled here. + +FUNCTION Word_t j__udyLeaf6ToLeaf7( + uint8_t * PLeaf7, // destination "uint24_t *" Index part of leaf. +#ifdef JUDYL + Pjv_t Pjv7, // destination value part of leaf. +#endif + Pjp_t Pjp, // 6-byte-index object from which to copy. + Word_t MSByte, // most-significant byte, prefix to each Index. + Pvoid_t Pjpm) // for global accounting. +{ + Word_t Pop1; // Indexes in leaf. +JUDYLCODE(Pjv_t Pjv6;) // source object value area. + + switch (JU_JPTYPE(Pjp)) + { + + +// JPLEAF6: + + case cJU_JPLEAF6: + { + uint8_t * PLeaf6 = (uint8_t *) P_JLL(Pjp->jp_Addr); + + Pop1 = JU_JPLEAF_POP0(Pjp) + 1; + j__udyCopy6to7(PLeaf7, PLeaf6, Pop1, MSByte); +#ifdef JUDYL + Pjv6 = JL_LEAF6VALUEAREA(PLeaf6, Pop1); + JU_COPYMEM(Pjv7, Pjv6, Pop1); +#endif + j__udyFreeJLL6((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm); + return(Pop1); + } + + +// JPIMMED_6_01: +// +// Note: jp_DcdPopO has 7 bytes of Index (all but most significant byte), so +// the "assignment" to PLeaf7[] is exact and MSByte is not needed. + + case cJU_JPIMMED_6_01: + { + JU_COPY7_LONG_TO_PINDEX(PLeaf7, JU_JPDCDPOP0(Pjp)); // see above. + JUDYLCODE(Pjv7[0] = Pjp->jp_Addr;) + return(1); + } + + +#ifdef JUDY1 + +// JPIMMED_6_02: + + case cJ1_JPIMMED_6_02: + { + uint8_t * PLeaf6 = (uint8_t *) (Pjp->jp_1Index); + + j__udyCopy6to7(PLeaf7, PLeaf6, /* Pop1 = */ 2, MSByte); + return(2); + } +#endif // JUDY1 + + +// UNEXPECTED CASES, including JPNULL6, should be handled by caller: + + default: assert(FALSE); break; + + } // switch + + return(0); + +} // j__udyLeaf6ToLeaf7() + +#endif // JU_64BIT + + +#ifndef JU_64BIT // 32-bit version first + +// **************************************************************************** +// __ J U D Y L E A F 3 T O L E A F W +// +// Copy 3-byte Indexes from a Leaf3 to 4-byte Indexes in a LeafW. Pjp MUST be +// one of: cJU_JPLEAF3 or cJU_JPIMMED_3_*. Return number of Indexes copied. +// +// Note: By the time this function is called to compress a level-L branch to a +// LeafW, the branch has no narrow pointers under it, meaning only level-3 +// objects are below it and must be handled here. + +FUNCTION Word_t j__udyLeaf3ToLeafW( + Pjlw_t Pjlw, // destination Index part of leaf. +#ifdef JUDYL + Pjv_t PjvW, // destination value part of leaf. +#endif + Pjp_t Pjp, // 3-byte-index object from which to copy. + Word_t MSByte, // most-significant byte, prefix to each Index. + Pvoid_t Pjpm) // for global accounting. +{ + Word_t Pop1; // Indexes in leaf. +JUDYLCODE(Pjv_t Pjv3;) // source object value area. + + switch (JU_JPTYPE(Pjp)) + { + + +// JPLEAF3: + + case cJU_JPLEAF3: + { + uint8_t * PLeaf3 = (uint8_t *) P_JLL(Pjp->jp_Addr); + + Pop1 = JU_JPLEAF_POP0(Pjp) + 1; + j__udyCopy3toW((PWord_t) Pjlw, PLeaf3, Pop1, MSByte); +#ifdef JUDYL + Pjv3 = JL_LEAF3VALUEAREA(PLeaf3, Pop1); + JU_COPYMEM(PjvW, Pjv3, Pop1); +#endif + j__udyFreeJLL3((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm); + return(Pop1); + } + + +// JPIMMED_3_01: +// +// Note: jp_DcdPopO has 3 bytes of Index (all but most significant byte), and +// MSByte must be ord in. + + case cJU_JPIMMED_3_01: + { + Pjlw[0] = MSByte | JU_JPDCDPOP0(Pjp); // see above. + JUDYLCODE(PjvW[0] = Pjp->jp_Addr;) + return(1); + } + + +#ifdef JUDY1 + +// JPIMMED_3_02: + + case cJU_JPIMMED_3_02: + { + uint8_t * PLeaf3 = (uint8_t *) (Pjp->jp_1Index); + + j__udyCopy3toW((PWord_t) Pjlw, PLeaf3, /* Pop1 = */ 2, MSByte); + return(2); + } +#endif // JUDY1 + + +// UNEXPECTED CASES, including JPNULL3, should be handled by caller: + + default: assert(FALSE); break; + + } // switch + + return(0); + +} // j__udyLeaf3ToLeafW() + + +#else // JU_64BIT + + +// **************************************************************************** +// __ J U D Y L E A F 7 T O L E A F W +// +// Copy 7-byte Indexes from a Leaf7 to 8-byte Indexes in a LeafW. +// Pjp MUST be one of: cJU_JPLEAF7 or cJU_JPIMMED_7_*. +// Return number of Indexes copied. +// +// Note: By the time this function is called to compress a level-L branch to a +// LeafW, the branch has no narrow pointers under it, meaning only level-7 +// objects are below it and must be handled here. + +FUNCTION Word_t j__udyLeaf7ToLeafW( + Pjlw_t Pjlw, // destination Index part of leaf. +#ifdef JUDYL + Pjv_t PjvW, // destination value part of leaf. +#endif + Pjp_t Pjp, // 7-byte-index object from which to copy. + Word_t MSByte, // most-significant byte, prefix to each Index. + Pvoid_t Pjpm) // for global accounting. +{ + Word_t Pop1; // Indexes in leaf. +JUDYLCODE(Pjv_t Pjv7;) // source object value area. + + switch (JU_JPTYPE(Pjp)) + { + + +// JPLEAF7: + + case cJU_JPLEAF7: + { + uint8_t * PLeaf7 = (uint8_t *) P_JLL(Pjp->jp_Addr); + + Pop1 = JU_JPLEAF_POP0(Pjp) + 1; + j__udyCopy7toW((PWord_t) Pjlw, PLeaf7, Pop1, MSByte); +#ifdef JUDYL + Pjv7 = JL_LEAF7VALUEAREA(PLeaf7, Pop1); + JU_COPYMEM(PjvW, Pjv7, Pop1); +#endif + j__udyFreeJLL7((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm); + return(Pop1); + } + + +// JPIMMED_7_01: +// +// Note: jp_DcdPopO has 7 bytes of Index (all but most significant byte), and +// MSByte must be ord in. + + case cJU_JPIMMED_7_01: + { + Pjlw[0] = MSByte | JU_JPDCDPOP0(Pjp); // see above. + JUDYLCODE(PjvW[0] = Pjp->jp_Addr;) + return(1); + } + + +#ifdef JUDY1 + +// JPIMMED_7_02: + + case cJ1_JPIMMED_7_02: + { + uint8_t * PLeaf7 = (uint8_t *) (Pjp->jp_1Index); + + j__udyCopy7toW((PWord_t) Pjlw, PLeaf7, /* Pop1 = */ 2, MSByte); + return(2); + } +#endif + + +// UNEXPECTED CASES, including JPNULL7, should be handled by caller: + + default: assert(FALSE); break; + + } // switch + + return(0); + +} // j__udyLeaf7ToLeafW() + +#endif // JU_64BIT diff --git a/feeds/p4/libjudy/src/src/JudyCommon/JudyDel.c b/feeds/p4/libjudy/src/src/JudyCommon/JudyDel.c new file mode 100644 index 000000000..ced4b5fb3 --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudyCommon/JudyDel.c @@ -0,0 +1,2146 @@ +// Copyright (C) 2000 - 2002 Hewlett-Packard Company +// +// This program is free software; you can redistribute it and/or modify it +// under the term of the GNU Lesser 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 Lesser General Public License +// for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// _________________ + +// @(#) $Revision: 4.68 $ $Source: /judy/src/JudyCommon/JudyDel.c $ +// +// Judy1Unset() and JudyLDel() functions for Judy1 and JudyL. +// Compile with one of -DJUDY1 or -DJUDYL. +// +// About HYSTERESIS: In the Judy code, hysteresis means leaving around a +// nominally suboptimal (not maximally compressed) data structure after a +// deletion. As a result, the shape of the tree for two identical index sets +// can differ depending on the insert/delete path taken to arrive at the index +// sets. The purpose is to minimize worst-case behavior (thrashing) that could +// result from a series of intermixed insertions and deletions. It also makes +// for MUCH simpler code, because instead of performing, "delete and then +// compress," it can say, "compress and then delete," where due to hysteresis, +// compression is not even attempted until the object IS compressible. +// +// In some cases the code has no choice and it must "ungrow" a data structure +// across a "phase transition" boundary without hysteresis. In other cases the +// amount (such as "hysteresis = 1") is indicated by the number of JP deletions +// (in branches) or index deletions (in leaves) that can occur in succession +// before compressing the data structure. (It appears that hysteresis <= 1 in +// all cases.) +// +// In general no hysteresis occurs when the data structure type remains the +// same but the allocated memory chunk for the node must shrink, because the +// relationship is hardwired and theres no way to know how much memory is +// allocated to a given data structure. Hysteresis = 0 in all these cases. +// +// TBD: Could this code be faster if memory chunk hysteresis were supported +// somehow along with data structure type hysteresis? +// +// TBD: Should some of the assertions here be converted to product code that +// returns JU_ERRNO_CORRUPT? +// +// TBD: Dougs code had an odd mix of function-wide and limited-scope +// variables. Should some of the function-wide variables appear only in +// limited scopes, or more likely, vice-versa? + +#if (! (defined(JUDY1) || defined(JUDYL))) +#error: One of -DJUDY1 or -DJUDYL must be specified. +#endif + +#ifdef JUDY1 +#include "Judy1.h" +#else +#include "JudyL.h" +#endif + +#include "JudyPrivate1L.h" + +DBGCODE(extern void JudyCheckPop(Pvoid_t PArray);) +DBGCODE(extern void JudyCheckSorted(Pjll_t Pjll, Word_t Pop1, long IndexSize);) + +#ifdef TRACEJP +#include "JudyPrintJP.c" +#endif + +// These are defined to generic values in JudyCommon/JudyPrivateTypes.h: +// +// TBD: These should be exported from a header file, but perhaps not, as they +// are only used here, and exported from JudyDecascade.c, which is a separate +// file for profiling reasons (to prevent inlining), but which potentially +// could be merged with this file, either in SoftCM or at compile-time: + +#ifdef JUDY1 + +extern int j__udy1BranchBToBranchL(Pjp_t Pjp, Pvoid_t Pjpm); +#ifndef JU_64BIT +extern int j__udy1LeafB1ToLeaf1(Pjp_t, Pvoid_t); +#endif +extern Word_t j__udy1Leaf1ToLeaf2(uint16_t *, Pjp_t, Word_t, Pvoid_t); +extern Word_t j__udy1Leaf2ToLeaf3(uint8_t *, Pjp_t, Word_t, Pvoid_t); +#ifndef JU_64BIT +extern Word_t j__udy1Leaf3ToLeafW(Pjlw_t, Pjp_t, Word_t, Pvoid_t); +#else +extern Word_t j__udy1Leaf3ToLeaf4(uint32_t *, Pjp_t, Word_t, Pvoid_t); +extern Word_t j__udy1Leaf4ToLeaf5(uint8_t *, Pjp_t, Word_t, Pvoid_t); +extern Word_t j__udy1Leaf5ToLeaf6(uint8_t *, Pjp_t, Word_t, Pvoid_t); +extern Word_t j__udy1Leaf6ToLeaf7(uint8_t *, Pjp_t, Word_t, Pvoid_t); +extern Word_t j__udy1Leaf7ToLeafW(Pjlw_t, Pjp_t, Word_t, Pvoid_t); +#endif + +#else // JUDYL + +extern int j__udyLBranchBToBranchL(Pjp_t Pjp, Pvoid_t Pjpm); +extern int j__udyLLeafB1ToLeaf1(Pjp_t, Pvoid_t); +extern Word_t j__udyLLeaf1ToLeaf2(uint16_t *, Pjv_t, Pjp_t, Word_t, Pvoid_t); +extern Word_t j__udyLLeaf2ToLeaf3(uint8_t *, Pjv_t, Pjp_t, Word_t, Pvoid_t); +#ifndef JU_64BIT +extern Word_t j__udyLLeaf3ToLeafW(Pjlw_t, Pjv_t, Pjp_t, Word_t, Pvoid_t); +#else +extern Word_t j__udyLLeaf3ToLeaf4(uint32_t *, Pjv_t, Pjp_t, Word_t, Pvoid_t); +extern Word_t j__udyLLeaf4ToLeaf5(uint8_t *, Pjv_t, Pjp_t, Word_t, Pvoid_t); +extern Word_t j__udyLLeaf5ToLeaf6(uint8_t *, Pjv_t, Pjp_t, Word_t, Pvoid_t); +extern Word_t j__udyLLeaf6ToLeaf7(uint8_t *, Pjv_t, Pjp_t, Word_t, Pvoid_t); +extern Word_t j__udyLLeaf7ToLeafW(Pjlw_t, Pjv_t, Pjp_t, Word_t, Pvoid_t); +#endif + +#endif // JUDYL + +// For convenience in the calling code; "M1" means "minus one": + +#ifndef JU_64BIT +#define j__udyLeafM1ToLeafW j__udyLeaf3ToLeafW +#else +#define j__udyLeafM1ToLeafW j__udyLeaf7ToLeafW +#endif + + +// **************************************************************************** +// __ J U D Y D E L W A L K +// +// Given a pointer to a JP, an Index known to be valid, the number of bytes +// left to decode (== level in the tree), and a pointer to a global JPM, walk a +// Judy (sub)tree to do an unset/delete of that index, and possibly modify the +// JPM. This function is only called internally, and recursively. Unlike +// Judy1Test() and JudyLGet(), the extra time required for recursion should be +// negligible compared with the total. +// +// Return values: +// +// -1 error; details in JPM +// +// 0 Index already deleted (should never happen, Index is known to be valid) +// +// 1 previously valid Index deleted +// +// 2 same as 1, but in addition the JP now points to a BranchL containing a +// single JP, which should be compressed into the parent branch (if there +// is one, which is not the case for a top-level branch under a JPM) + +DBGCODE(uint8_t parentJPtype;) // parent branch JP type. + +FUNCTION static int j__udyDelWalk( + Pjp_t Pjp, // current JP under which to delete. + Word_t Index, // to delete. + Word_t ParentLevel, // of parent branch. + Pjpm_t Pjpm) // for returning info to top level. +{ + Word_t pop1; // of a leaf. + Word_t level; // of a leaf. + uint8_t digit; // from Index, in current branch. + Pjll_t PjllnewRaw; // address of newly allocated leaf. + Pjll_t Pjllnew; + int offset; // within a branch. + int retcode; // return code: -1, 0, 1, 2. +JUDYLCODE(Pjv_t PjvRaw;) // value area. +JUDYLCODE(Pjv_t Pjv;) + + DBGCODE(level = 0;) + +ContinueDelWalk: // for modifying state without recursing. + +#ifdef TRACEJP + JudyPrintJP(Pjp, "d", __LINE__); +#endif + + switch (JU_JPTYPE(Pjp)) // entry: Pjp, Index. + { + + +// **************************************************************************** +// LINEAR BRANCH: +// +// MACROS FOR COMMON CODE: +// +// Check for population too high to compress a branch to a leaf, meaning just +// descend through the branch, with a purposeful off-by-one error that +// constitutes hysteresis = 1. In other words, do not compress until the +// branchs CURRENT population fits in the leaf, even BEFORE deleting one +// index. +// +// Next is a label for branch-type-specific common code. Variables pop1, +// level, digit, and Index are in the context. + +#define JU_BRANCH_KEEP(cLevel,MaxPop1,Next) \ + if (pop1 > (MaxPop1)) /* hysteresis = 1 */ \ + { \ + assert((cLevel) >= 2); \ + level = (cLevel); \ + digit = JU_DIGITATSTATE(Index, cLevel); \ + goto Next; \ + } + +// Support for generic calling of JudyLeaf*ToLeaf*() functions: +// +// Note: Cannot use JUDYLCODE() because this contains a comma. + +#ifdef JUDY1 +#define JU_PVALUEPASS // null. +#else +#define JU_PVALUEPASS Pjv, +#endif + +// During compression to a leaf, check if a JP contains nothing but a +// cJU_JPIMMED_*_01, in which case shortcut calling j__udyLeaf*ToLeaf*(): +// +// Copy the index bytes from the jp_DcdPopO field (with possible truncation), +// and continue the branch-JP-walk loop. Variables Pjp and Pleaf are in the +// context. + +#define JU_BRANCH_COPY_IMMED_EVEN(cLevel,Pjp,ignore) \ + if (JU_JPTYPE(Pjp) == cJU_JPIMMED_1_01 + (cLevel) - 2) \ + { \ + *Pleaf++ = JU_JPDCDPOP0(Pjp); \ + JUDYLCODE(*Pjv++ = (Pjp)->jp_Addr;) \ + continue; /* for-loop */ \ + } + +#define JU_BRANCH_COPY_IMMED_ODD(cLevel,Pjp,CopyIndex) \ + if (JU_JPTYPE(Pjp) == cJU_JPIMMED_1_01 + (cLevel) - 2) \ + { \ + CopyIndex(Pleaf, (Word_t) (JU_JPDCDPOP0(Pjp))); \ + Pleaf += (cLevel); /* index size = level */ \ + JUDYLCODE(*Pjv++ = (Pjp)->jp_Addr;) \ + continue; /* for-loop */ \ + } + +// Compress a BranchL into a leaf one index size larger: +// +// Allocate a new leaf, walk the JPs in the old BranchL and pack their contents +// into the new leaf (of type NewJPType), free the old BranchL, and finally +// restart the switch to delete Index from the new leaf. (Note that all +// BranchLs are the same size.) Variables Pjp, Pjpm, Pleaf, digit, and pop1 +// are in the context. + +#define JU_BRANCHL_COMPRESS(cLevel,LeafType,MaxPop1,NewJPType, \ + LeafToLeaf,Alloc,ValueArea, \ + CopyImmed,CopyIndex) \ + { \ + LeafType Pleaf; \ + Pjbl_t PjblRaw; \ + Pjbl_t Pjbl; \ + Word_t numJPs; \ + \ + if ((PjllnewRaw = Alloc(MaxPop1, Pjpm)) == 0) return(-1); \ + Pjllnew = P_JLL(PjllnewRaw); \ + Pleaf = (LeafType) Pjllnew; \ + JUDYLCODE(Pjv = ValueArea(Pleaf, MaxPop1);) \ + \ + PjblRaw = (Pjbl_t) (Pjp->jp_Addr); \ + Pjbl = P_JBL(PjblRaw); \ + numJPs = Pjbl->jbl_NumJPs; \ + \ + for (offset = 0; offset < numJPs; ++offset) \ + { \ + CopyImmed(cLevel, (Pjbl->jbl_jp) + offset, CopyIndex); \ + \ + pop1 = LeafToLeaf(Pleaf, JU_PVALUEPASS \ + (Pjbl->jbl_jp) + offset, \ + JU_DIGITTOSTATE(Pjbl->jbl_Expanse[offset], \ + cLevel), (Pvoid_t) Pjpm); \ + Pleaf = (LeafType) (((Word_t) Pleaf) + ((cLevel) * pop1)); \ + JUDYLCODE(Pjv += pop1;) \ + } \ + assert(((((Word_t) Pleaf) - ((Word_t) Pjllnew)) / (cLevel)) == (MaxPop1)); \ + JUDYLCODE(assert((Pjv - ValueArea(Pjllnew, MaxPop1)) == (MaxPop1));) \ + DBGCODE(JudyCheckSorted(Pjllnew, MaxPop1, cLevel);) \ + \ + j__udyFreeJBL(PjblRaw, Pjpm); \ + \ + Pjp->jp_Type = (NewJPType); \ + Pjp->jp_Addr = (Word_t) PjllnewRaw; \ + goto ContinueDelWalk; /* delete from new leaf */ \ + } + +// Overall common code for initial BranchL deletion handling: +// +// Assert that Index is in the branch, then see if the BranchL should be kept +// or else compressed to a leaf. Variables Index, Pjp, and pop1 are in the +// context. + +#define JU_BRANCHL(cLevel,MaxPop1,LeafType,NewJPType, \ + LeafToLeaf,Alloc,ValueArea,CopyImmed,CopyIndex) \ + \ + assert(! JU_DCDNOTMATCHINDEX(Index, Pjp, cLevel)); \ + assert(ParentLevel > (cLevel)); \ + \ + pop1 = JU_JPBRANCH_POP0(Pjp, cLevel) + 1; \ + JU_BRANCH_KEEP(cLevel, MaxPop1, BranchLKeep); \ + assert(pop1 == (MaxPop1)); \ + \ + JU_BRANCHL_COMPRESS(cLevel, LeafType, MaxPop1, NewJPType, \ + LeafToLeaf, Alloc, ValueArea, CopyImmed, CopyIndex) + + +// END OF MACROS, START OF CASES: + + case cJU_JPBRANCH_L2: + + JU_BRANCHL(2, cJU_LEAF2_MAXPOP1, uint16_t *, cJU_JPLEAF2, + j__udyLeaf1ToLeaf2, j__udyAllocJLL2, JL_LEAF2VALUEAREA, + JU_BRANCH_COPY_IMMED_EVEN, ignore); + + case cJU_JPBRANCH_L3: + + JU_BRANCHL(3, cJU_LEAF3_MAXPOP1, uint8_t *, cJU_JPLEAF3, + j__udyLeaf2ToLeaf3, j__udyAllocJLL3, JL_LEAF3VALUEAREA, + JU_BRANCH_COPY_IMMED_ODD, JU_COPY3_LONG_TO_PINDEX); + +#ifdef JU_64BIT + case cJU_JPBRANCH_L4: + + JU_BRANCHL(4, cJU_LEAF4_MAXPOP1, uint32_t *, cJU_JPLEAF4, + j__udyLeaf3ToLeaf4, j__udyAllocJLL4, JL_LEAF4VALUEAREA, + JU_BRANCH_COPY_IMMED_EVEN, ignore); + + case cJU_JPBRANCH_L5: + + JU_BRANCHL(5, cJU_LEAF5_MAXPOP1, uint8_t *, cJU_JPLEAF5, + j__udyLeaf4ToLeaf5, j__udyAllocJLL5, JL_LEAF5VALUEAREA, + JU_BRANCH_COPY_IMMED_ODD, JU_COPY5_LONG_TO_PINDEX); + + case cJU_JPBRANCH_L6: + + JU_BRANCHL(6, cJU_LEAF6_MAXPOP1, uint8_t *, cJU_JPLEAF6, + j__udyLeaf5ToLeaf6, j__udyAllocJLL6, JL_LEAF6VALUEAREA, + JU_BRANCH_COPY_IMMED_ODD, JU_COPY6_LONG_TO_PINDEX); + + case cJU_JPBRANCH_L7: + + JU_BRANCHL(7, cJU_LEAF7_MAXPOP1, uint8_t *, cJU_JPLEAF7, + j__udyLeaf6ToLeaf7, j__udyAllocJLL7, JL_LEAF7VALUEAREA, + JU_BRANCH_COPY_IMMED_ODD, JU_COPY7_LONG_TO_PINDEX); +#endif // JU_64BIT + +// A top-level BranchL is different and cannot use JU_BRANCHL(): Dont try to +// compress to a (LEAFW) leaf yet, but leave this for a later deletion +// (hysteresis > 0); and the next JP type depends on the system word size; so +// dont use JU_BRANCH_KEEP(): + + case cJU_JPBRANCH_L: + { + Pjbl_t Pjbl; + Word_t numJPs; + + level = cJU_ROOTSTATE; + digit = JU_DIGITATSTATE(Index, cJU_ROOTSTATE); + + // fall through: + + +// COMMON CODE FOR KEEPING AND DESCENDING THROUGH A BRANCHL: +// +// Come here with level and digit set. + +BranchLKeep: + Pjbl = P_JBL(Pjp->jp_Addr); + numJPs = Pjbl->jbl_NumJPs; + assert(numJPs > 0); + DBGCODE(parentJPtype = JU_JPTYPE(Pjp);) + +// Search for a match to the digit (valid Index => must find digit): + + for (offset = 0; (Pjbl->jbl_Expanse[offset]) != digit; ++offset) + assert(offset < numJPs - 1); + + Pjp = (Pjbl->jbl_jp) + offset; + +// If not at a (deletable) JPIMMED_*_01, continue the walk (to descend through +// the BranchL): + + assert(level >= 2); + if ((JU_JPTYPE(Pjp)) != cJU_JPIMMED_1_01 + level - 2) break; + +// At JPIMMED_*_01: Ensure the index is in the right expanse, then delete the +// Immed from the BranchL: +// +// Note: A BranchL has a fixed size and format regardless of numJPs. + + assert(JU_JPDCDPOP0(Pjp) == JU_TRIMTODCDSIZE(Index)); + + JU_DELETEINPLACE(Pjbl->jbl_Expanse, numJPs, offset, ignore); + JU_DELETEINPLACE(Pjbl->jbl_jp, numJPs, offset, ignore); + + DBGCODE(JudyCheckSorted((Pjll_t) (Pjbl->jbl_Expanse), + numJPs - 1, 1);) + +// If only one index left in the BranchL, indicate this to the caller: + + return ((--(Pjbl->jbl_NumJPs) <= 1) ? 2 : 1); + + } // case cJU_JPBRANCH_L. + + +// **************************************************************************** +// BITMAP BRANCH: +// +// MACROS FOR COMMON CODE: +// +// Note the reuse of common macros here, defined earlier: JU_BRANCH_KEEP(), +// JU_PVALUE*. +// +// Compress a BranchB into a leaf one index size larger: +// +// Allocate a new leaf, walk the JPs in the old BranchB (one bitmap subexpanse +// at a time) and pack their contents into the new leaf (of type NewJPType), +// free the old BranchB, and finally restart the switch to delete Index from +// the new leaf. Variables Pjp, Pjpm, Pleaf, digit, and pop1 are in the +// context. +// +// Note: Its no accident that the interface to JU_BRANCHB_COMPRESS() is +// identical to JU_BRANCHL_COMPRESS(). Only the details differ in how to +// traverse the branchs JPs. + +#define JU_BRANCHB_COMPRESS(cLevel,LeafType,MaxPop1,NewJPType, \ + LeafToLeaf,Alloc,ValueArea, \ + CopyImmed,CopyIndex) \ + { \ + LeafType Pleaf; \ + Pjbb_t PjbbRaw; /* BranchB to compress */ \ + Pjbb_t Pjbb; \ + Word_t subexp; /* current subexpanse number */ \ + BITMAPB_t bitmap; /* portion for this subexpanse */ \ + Pjp_t Pjp2Raw; /* one subexpanses subarray */ \ + Pjp_t Pjp2; \ + \ + if ((PjllnewRaw = Alloc(MaxPop1, Pjpm)) == 0) return(-1); \ + Pjllnew = P_JLL(PjllnewRaw); \ + Pleaf = (LeafType) Pjllnew; \ + JUDYLCODE(Pjv = ValueArea(Pleaf, MaxPop1);) \ + \ + PjbbRaw = (Pjbb_t) (Pjp->jp_Addr); \ + Pjbb = P_JBB(PjbbRaw); \ + \ + for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp) \ + { \ + if ((bitmap = JU_JBB_BITMAP(Pjbb, subexp)) == 0) \ + continue; /* empty subexpanse */ \ + \ + digit = subexp * cJU_BITSPERSUBEXPB; \ + Pjp2Raw = JU_JBB_PJP(Pjbb, subexp); \ + Pjp2 = P_JP(Pjp2Raw); \ + assert(Pjp2 != (Pjp_t) NULL); \ + \ + for (offset = 0; bitmap != 0; bitmap >>= 1, ++digit) \ + { \ + if (! (bitmap & 1)) \ + continue; /* empty sub-subexpanse */ \ + \ + ++offset; /* before any continue */ \ + \ + CopyImmed(cLevel, Pjp2 + offset - 1, CopyIndex); \ + \ + pop1 = LeafToLeaf(Pleaf, JU_PVALUEPASS \ + Pjp2 + offset - 1, \ + JU_DIGITTOSTATE(digit, cLevel), \ + (Pvoid_t) Pjpm); \ + Pleaf = (LeafType) (((Word_t) Pleaf) + ((cLevel) * pop1)); \ + JUDYLCODE(Pjv += pop1;) \ + } \ + j__udyFreeJBBJP(Pjp2Raw, /* pop1 = */ offset, Pjpm); \ + } \ + assert(((((Word_t) Pleaf) - ((Word_t) Pjllnew)) / (cLevel)) == (MaxPop1)); \ + JUDYLCODE(assert((Pjv - ValueArea(Pjllnew, MaxPop1)) == (MaxPop1));) \ + DBGCODE(JudyCheckSorted(Pjllnew, MaxPop1, cLevel);) \ + \ + j__udyFreeJBB(PjbbRaw, Pjpm); \ + \ + Pjp->jp_Type = (NewJPType); \ + Pjp->jp_Addr = (Word_t) PjllnewRaw; \ + goto ContinueDelWalk; /* delete from new leaf */ \ + } + +// Overall common code for initial BranchB deletion handling: +// +// Assert that Index is in the branch, then see if the BranchB should be kept +// or else compressed to a leaf. Variables Index, Pjp, and pop1 are in the +// context. + +#define JU_BRANCHB(cLevel,MaxPop1,LeafType,NewJPType, \ + LeafToLeaf,Alloc,ValueArea,CopyImmed,CopyIndex) \ + \ + assert(! JU_DCDNOTMATCHINDEX(Index, Pjp, cLevel)); \ + assert(ParentLevel > (cLevel)); \ + \ + pop1 = JU_JPBRANCH_POP0(Pjp, cLevel) + 1; \ + JU_BRANCH_KEEP(cLevel, MaxPop1, BranchBKeep); \ + assert(pop1 == (MaxPop1)); \ + \ + JU_BRANCHB_COMPRESS(cLevel, LeafType, MaxPop1, NewJPType, \ + LeafToLeaf, Alloc, ValueArea, CopyImmed, CopyIndex) + + +// END OF MACROS, START OF CASES: +// +// Note: Its no accident that the macro calls for these cases is nearly +// identical to the code for BranchLs. + + case cJU_JPBRANCH_B2: + + JU_BRANCHB(2, cJU_LEAF2_MAXPOP1, uint16_t *, cJU_JPLEAF2, + j__udyLeaf1ToLeaf2, j__udyAllocJLL2, JL_LEAF2VALUEAREA, + JU_BRANCH_COPY_IMMED_EVEN, ignore); + + case cJU_JPBRANCH_B3: + + JU_BRANCHB(3, cJU_LEAF3_MAXPOP1, uint8_t *, cJU_JPLEAF3, + j__udyLeaf2ToLeaf3, j__udyAllocJLL3, JL_LEAF3VALUEAREA, + JU_BRANCH_COPY_IMMED_ODD, JU_COPY3_LONG_TO_PINDEX); + +#ifdef JU_64BIT + case cJU_JPBRANCH_B4: + + JU_BRANCHB(4, cJU_LEAF4_MAXPOP1, uint32_t *, cJU_JPLEAF4, + j__udyLeaf3ToLeaf4, j__udyAllocJLL4, JL_LEAF4VALUEAREA, + JU_BRANCH_COPY_IMMED_EVEN, ignore); + + case cJU_JPBRANCH_B5: + + JU_BRANCHB(5, cJU_LEAF5_MAXPOP1, uint8_t *, cJU_JPLEAF5, + j__udyLeaf4ToLeaf5, j__udyAllocJLL5, JL_LEAF5VALUEAREA, + JU_BRANCH_COPY_IMMED_ODD, JU_COPY5_LONG_TO_PINDEX); + + case cJU_JPBRANCH_B6: + + JU_BRANCHB(6, cJU_LEAF6_MAXPOP1, uint8_t *, cJU_JPLEAF6, + j__udyLeaf5ToLeaf6, j__udyAllocJLL6, JL_LEAF6VALUEAREA, + JU_BRANCH_COPY_IMMED_ODD, JU_COPY6_LONG_TO_PINDEX); + + case cJU_JPBRANCH_B7: + + JU_BRANCHB(7, cJU_LEAF7_MAXPOP1, uint8_t *, cJU_JPLEAF7, + j__udyLeaf6ToLeaf7, j__udyAllocJLL7, JL_LEAF7VALUEAREA, + JU_BRANCH_COPY_IMMED_ODD, JU_COPY7_LONG_TO_PINDEX); +#endif // JU_64BIT + +// A top-level BranchB is different and cannot use JU_BRANCHB(): Dont try to +// compress to a (LEAFW) leaf yet, but leave this for a later deletion +// (hysteresis > 0); and the next JP type depends on the system word size; so +// dont use JU_BRANCH_KEEP(): + + case cJU_JPBRANCH_B: + { + Pjbb_t Pjbb; // BranchB to modify. + Word_t subexp; // current subexpanse number. + Word_t subexp2; // in second-level loop. + BITMAPB_t bitmap; // portion for this subexpanse. + BITMAPB_t bitmask; // with digits bit set. + Pjp_t Pjp2Raw; // one subexpanses subarray. + Pjp_t Pjp2; + Word_t numJPs; // in one subexpanse. + + level = cJU_ROOTSTATE; + digit = JU_DIGITATSTATE(Index, cJU_ROOTSTATE); + + // fall through: + + +// COMMON CODE FOR KEEPING AND DESCENDING THROUGH A BRANCHB: +// +// Come here with level and digit set. + +BranchBKeep: + Pjbb = P_JBB(Pjp->jp_Addr); + subexp = digit / cJU_BITSPERSUBEXPB; + bitmap = JU_JBB_BITMAP(Pjbb, subexp); + bitmask = JU_BITPOSMASKB(digit); + assert(bitmap & bitmask); // Index valid => digits bit is set. + DBGCODE(parentJPtype = JU_JPTYPE(Pjp);) + +// Compute digits offset into the bitmap, with a fast method if all bits are +// set: + + offset = ((bitmap == (cJU_FULLBITMAPB)) ? + digit % cJU_BITSPERSUBEXPB : + j__udyCountBitsB(bitmap & JU_MASKLOWEREXC(bitmask))); + + Pjp2Raw = JU_JBB_PJP(Pjbb, subexp); + Pjp2 = P_JP(Pjp2Raw); + assert(Pjp2 != (Pjp_t) NULL); // valid subexpanse pointer. + +// If not at a (deletable) JPIMMED_*_01, continue the walk (to descend through +// the BranchB): + + if (JU_JPTYPE(Pjp2 + offset) != cJU_JPIMMED_1_01 + level - 2) + { + Pjp = Pjp2 + offset; + break; + } + +// At JPIMMED_*_01: Ensure the index is in the right expanse, then delete the +// Immed from the BranchB: + + assert(JU_JPDCDPOP0(Pjp2 + offset) + == JU_TRIMTODCDSIZE(Index)); + +// If only one index is left in the subexpanse, free the JP array: + + if ((numJPs = j__udyCountBitsB(bitmap)) == 1) + { + j__udyFreeJBBJP(Pjp2Raw, /* pop1 = */ 1, Pjpm); + JU_JBB_PJP(Pjbb, subexp) = (Pjp_t) NULL; + } + +// Shrink JP array in-place: + + else if (JU_BRANCHBJPGROWINPLACE(numJPs - 1)) + { + assert(numJPs > 0); + JU_DELETEINPLACE(Pjp2, numJPs, offset, ignore); + } + +// JP array would end up too large; compress it to a smaller one: + + else + { + Pjp_t PjpnewRaw; + Pjp_t Pjpnew; + + if ((PjpnewRaw = j__udyAllocJBBJP(numJPs - 1, Pjpm)) + == (Pjp_t) NULL) return(-1); + Pjpnew = P_JP(PjpnewRaw); + + JU_DELETECOPY(Pjpnew, Pjp2, numJPs, offset, ignore); + j__udyFreeJBBJP(Pjp2Raw, numJPs, Pjpm); // old. + + JU_JBB_PJP(Pjbb, subexp) = PjpnewRaw; + } + +// Clear digits bit in the bitmap: + + JU_JBB_BITMAP(Pjbb, subexp) ^= bitmask; + +// If the current subexpanse alone is still too large for a BranchL (with +// hysteresis = 1), the delete is all done: + + if (numJPs > cJU_BRANCHLMAXJPS) return(1); + +// Consider shrinking the current BranchB to a BranchL: +// +// Check the numbers of JPs in other subexpanses in the BranchL. Upon reaching +// the critical number of numJPs (which could be right at the start; again, +// with hysteresis = 1), its faster to just watch for any non-empty subexpanse +// than to count bits in each subexpanse. Upon finding too many JPs, give up +// on shrinking the BranchB. + + for (subexp2 = 0; subexp2 < cJU_NUMSUBEXPB; ++subexp2) + { + if (subexp2 == subexp) continue; // skip current subexpanse. + + if ((numJPs == cJU_BRANCHLMAXJPS) ? + JU_JBB_BITMAP(Pjbb, subexp2) : + ((numJPs += j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp2))) + > cJU_BRANCHLMAXJPS)) + { + return(1); // too many JPs, cannot shrink. + } + } + +// Shrink current BranchB to a BranchL: +// +// Note: In this rare case, ignore the return value, do not pass it to the +// caller, because the deletion is already successfully completed and the +// caller(s) must decrement population counts. The only errors expected from +// this call are JU_ERRNO_NOMEM and JU_ERRNO_OVERRUN, neither of which is worth +// forwarding from this point. See also 4.1, 4.8, and 4.15 of this file. + + (void) j__udyBranchBToBranchL(Pjp, Pjpm); + return(1); + + } // case. + + +// **************************************************************************** +// UNCOMPRESSED BRANCH: +// +// MACROS FOR COMMON CODE: +// +// Note the reuse of common macros here, defined earlier: JU_PVALUE*. +// +// Compress a BranchU into a leaf one index size larger: +// +// Allocate a new leaf, walk the JPs in the old BranchU and pack their contents +// into the new leaf (of type NewJPType), free the old BranchU, and finally +// restart the switch to delete Index from the new leaf. Variables Pjp, Pjpm, +// digit, and pop1 are in the context. +// +// Note: Its no accident that the interface to JU_BRANCHU_COMPRESS() is +// nearly identical to JU_BRANCHL_COMPRESS(); just NullJPType is added. The +// details differ in how to traverse the branchs JPs -- +// +// -- and also, what to do upon encountering a cJU_JPIMMED_*_01 JP. In +// BranchLs and BranchBs the JP must be deleted, but in a BranchU its merely +// converted to a null JP, and this is done by other switch cases, so the "keep +// branch" situation is simpler here and JU_BRANCH_KEEP() is not used. Also, +// theres no code to convert a BranchU to a BranchB since counting the JPs in +// a BranchU is (at least presently) expensive, and besides, keeping around a +// BranchU is form of hysteresis. + +#define JU_BRANCHU_COMPRESS(cLevel,LeafType,MaxPop1,NullJPType,NewJPType, \ + LeafToLeaf,Alloc,ValueArea,CopyImmed,CopyIndex) \ + { \ + LeafType Pleaf; \ + Pjbu_t PjbuRaw = (Pjbu_t) (Pjp->jp_Addr); \ + Pjp_t Pjp2 = JU_JBU_PJP0(Pjp); \ + Word_t ldigit; /* larger than uint8_t */ \ + \ + if ((PjllnewRaw = Alloc(MaxPop1, Pjpm)) == 0) return(-1); \ + Pjllnew = P_JLL(PjllnewRaw); \ + Pleaf = (LeafType) Pjllnew; \ + JUDYLCODE(Pjv = ValueArea(Pleaf, MaxPop1);) \ + \ + for (ldigit = 0; ldigit < cJU_BRANCHUNUMJPS; ++ldigit, ++Pjp2) \ + { \ + /* fast-process common types: */ \ + if (JU_JPTYPE(Pjp2) == (NullJPType)) continue; \ + CopyImmed(cLevel, Pjp2, CopyIndex); \ + \ + pop1 = LeafToLeaf(Pleaf, JU_PVALUEPASS Pjp2, \ + JU_DIGITTOSTATE(ldigit, cLevel), \ + (Pvoid_t) Pjpm); \ + Pleaf = (LeafType) (((Word_t) Pleaf) + ((cLevel) * pop1)); \ + JUDYLCODE(Pjv += pop1;) \ + } \ + assert(((((Word_t) Pleaf) - ((Word_t) Pjllnew)) / (cLevel)) == (MaxPop1)); \ + JUDYLCODE(assert((Pjv - ValueArea(Pjllnew, MaxPop1)) == (MaxPop1));) \ + DBGCODE(JudyCheckSorted(Pjllnew, MaxPop1, cLevel);) \ + \ + j__udyFreeJBU(PjbuRaw, Pjpm); \ + \ + Pjp->jp_Type = (NewJPType); \ + Pjp->jp_Addr = (Word_t) PjllnewRaw; \ + goto ContinueDelWalk; /* delete from new leaf */ \ + } + +// Overall common code for initial BranchU deletion handling: +// +// Assert that Index is in the branch, then see if a BranchU should be kept or +// else compressed to a leaf. Variables level, Index, Pjp, and pop1 are in the +// context. +// +// Note: BranchU handling differs from BranchL and BranchB as described above. + +#define JU_BRANCHU(cLevel,MaxPop1,LeafType,NullJPType,NewJPType, \ + LeafToLeaf,Alloc,ValueArea,CopyImmed,CopyIndex) \ + \ + assert(! JU_DCDNOTMATCHINDEX(Index, Pjp, cLevel)); \ + assert(ParentLevel > (cLevel)); \ + DBGCODE(parentJPtype = JU_JPTYPE(Pjp);) \ + \ + pop1 = JU_JPBRANCH_POP0(Pjp, cLevel) + 1; \ + \ + if (pop1 > (MaxPop1)) /* hysteresis = 1 */ \ + { \ + level = (cLevel); \ + Pjp = P_JP(Pjp->jp_Addr) + JU_DIGITATSTATE(Index, cLevel);\ + break; /* descend to next level */ \ + } \ + assert(pop1 == (MaxPop1)); \ + \ + JU_BRANCHU_COMPRESS(cLevel, LeafType, MaxPop1, NullJPType, NewJPType, \ + LeafToLeaf, Alloc, ValueArea, CopyImmed, CopyIndex) + + +// END OF MACROS, START OF CASES: +// +// Note: Its no accident that the macro calls for these cases is nearly +// identical to the code for BranchLs, with the addition of cJU_JPNULL* +// parameters only needed for BranchUs. + + case cJU_JPBRANCH_U2: + + JU_BRANCHU(2, cJU_LEAF2_MAXPOP1, uint16_t *, + cJU_JPNULL1, cJU_JPLEAF2, + j__udyLeaf1ToLeaf2, j__udyAllocJLL2, JL_LEAF2VALUEAREA, + JU_BRANCH_COPY_IMMED_EVEN, ignore); + + case cJU_JPBRANCH_U3: + + JU_BRANCHU(3, cJU_LEAF3_MAXPOP1, uint8_t *, + cJU_JPNULL2, cJU_JPLEAF3, + j__udyLeaf2ToLeaf3, j__udyAllocJLL3, JL_LEAF3VALUEAREA, + JU_BRANCH_COPY_IMMED_ODD, JU_COPY3_LONG_TO_PINDEX); + +#ifdef JU_64BIT + case cJU_JPBRANCH_U4: + + JU_BRANCHU(4, cJU_LEAF4_MAXPOP1, uint32_t *, + cJU_JPNULL3, cJU_JPLEAF4, + j__udyLeaf3ToLeaf4, j__udyAllocJLL4, JL_LEAF4VALUEAREA, + JU_BRANCH_COPY_IMMED_EVEN, ignore); + + case cJU_JPBRANCH_U5: + + JU_BRANCHU(5, cJU_LEAF5_MAXPOP1, uint8_t *, + cJU_JPNULL4, cJU_JPLEAF5, + j__udyLeaf4ToLeaf5, j__udyAllocJLL5, JL_LEAF5VALUEAREA, + JU_BRANCH_COPY_IMMED_ODD, JU_COPY5_LONG_TO_PINDEX); + + case cJU_JPBRANCH_U6: + + JU_BRANCHU(6, cJU_LEAF6_MAXPOP1, uint8_t *, + cJU_JPNULL5, cJU_JPLEAF6, + j__udyLeaf5ToLeaf6, j__udyAllocJLL6, JL_LEAF6VALUEAREA, + JU_BRANCH_COPY_IMMED_ODD, JU_COPY6_LONG_TO_PINDEX); + + case cJU_JPBRANCH_U7: + + JU_BRANCHU(7, cJU_LEAF7_MAXPOP1, uint8_t *, + cJU_JPNULL6, cJU_JPLEAF7, + j__udyLeaf6ToLeaf7, j__udyAllocJLL7, JL_LEAF7VALUEAREA, + JU_BRANCH_COPY_IMMED_ODD, JU_COPY7_LONG_TO_PINDEX); +#endif // JU_64BIT + +// A top-level BranchU is different and cannot use JU_BRANCHU(): Dont try to +// compress to a (LEAFW) leaf yet, but leave this for a later deletion +// (hysteresis > 0); just descend through the BranchU: + + case cJU_JPBRANCH_U: + + DBGCODE(parentJPtype = JU_JPTYPE(Pjp);) + + level = cJU_ROOTSTATE; + Pjp = P_JP(Pjp->jp_Addr) + JU_DIGITATSTATE(Index, cJU_ROOTSTATE); + break; + + +// **************************************************************************** +// LINEAR LEAF: +// +// State transitions while deleting an Index, the inverse of the similar table +// that appears in JudyIns.c: +// +// Note: In JudyIns.c this table is not needed and does not appear until the +// Immed handling code; because once a Leaf is reached upon growing the tree, +// the situation remains simpler, but for deleting indexes, the complexity +// arises when leaves must compress to Immeds. +// +// Note: There are other transitions possible too, not shown here, such as to +// a leaf one level higher. +// +// (Yes, this is very terse... Study it and it will make sense.) +// (Note, parts of this diagram are repeated below for quick reference.) +// +// reformat JP here for Judy1 only, from word-1 to word-2 +// | +// JUDY1 && JU_64BIT JUDY1 || JU_64BIT | +// V +// (*) Leaf1 [[ => 1_15..08 ] => 1_07 => ... => 1_04 ] => 1_03 => 1_02 => 1_01 +// Leaf2 [[ => 2_07..04 ] => 2_03 => 2_02 ] => 2_01 +// Leaf3 [[ => 3_05..03 ] => 3_02 ] => 3_01 +// JU_64BIT only: +// Leaf4 [[ => 4_03..02 ]] => 4_01 +// Leaf5 [[ => 5_03..02 ]] => 5_01 +// Leaf6 [[ => 6_02 ]] => 6_01 +// Leaf7 [[ => 7_02 ]] => 7_01 +// +// (*) For Judy1 & 64-bit, go directly from a LeafB1 to cJU_JPIMMED_1_15; skip +// Leaf1, as described in Judy1.h regarding cJ1_JPLEAF1. +// +// MACROS FOR COMMON CODE: +// +// (De)compress a LeafX into a LeafY one index size (cIS) larger (X+1 = Y): +// +// This is only possible when the current leaf is under a narrow pointer +// ((ParentLevel - 1) > cIS) and its population fits in a higher-level leaf. +// Variables ParentLevel, pop1, PjllnewRaw, Pjllnew, Pjpm, and Index are in the +// context. +// +// Note: Doing an "uplevel" doesnt occur until the old leaf can be compressed +// up one level BEFORE deleting an index; that is, hysteresis = 1. +// +// Note: LeafType, MaxPop1, NewJPType, and Alloc refer to the up-level leaf, +// not the current leaf. +// +// Note: 010327: Fixed bug where the jp_DcdPopO next-uplevel digit (byte) +// above the current Pop0 value was not being cleared. When upleveling, one +// digit in jp_DcdPopO "moves" from being part of the Dcd subfield to the Pop0 +// subfield, but since a leaf maxpop1 is known to be <= 1 byte in size, the new +// Pop0 byte should always be zero. This is easy to overlook because +// JU_JPLEAF_POP0() "knows" to only use the LSB of Pop0 (for efficiency) and +// ignore the other bytes... Until someone uses cJU_POP0MASK() instead of +// JU_JPLEAF_POP0(), such as in JudyInsertBranch.c. +// +// TBD: Should JudyInsertBranch.c use JU_JPLEAF_POP0() rather than +// cJU_POP0MASK(), for efficiency? Does it know for sure its a narrow pointer +// under the leaf? Not necessarily. + +#define JU_LEAF_UPLEVEL(cIS,LeafType,MaxPop1,NewJPType,LeafToLeaf, \ + Alloc,ValueArea) \ + \ + assert(((ParentLevel - 1) == (cIS)) || (pop1 >= (MaxPop1))); \ + \ + if (((ParentLevel - 1) > (cIS)) /* under narrow pointer */ \ + && (pop1 == (MaxPop1))) /* hysteresis = 1 */ \ + { \ + Word_t D_cdP0; \ + if ((PjllnewRaw = Alloc(MaxPop1, Pjpm)) == 0) return(-1); \ + Pjllnew = P_JLL(PjllnewRaw); \ + JUDYLCODE(Pjv = ValueArea((LeafType) Pjllnew, MaxPop1);) \ + \ + (void) LeafToLeaf((LeafType) Pjllnew, JU_PVALUEPASS Pjp, \ + Index & cJU_DCDMASK(cIS), /* TBD, Doug says */ \ + (Pvoid_t) Pjpm); \ + DBGCODE(JudyCheckSorted(Pjllnew, MaxPop1, cIS + 1);) \ + \ + D_cdP0 = (~cJU_MASKATSTATE((cIS) + 1)) & JU_JPDCDPOP0(Pjp); \ + JU_JPSETADT(Pjp, (Word_t)PjllnewRaw, D_cdP0, NewJPType); \ + goto ContinueDelWalk; /* delete from new leaf */ \ + } + + +// For Leaf3, only support JU_LEAF_UPLEVEL on a 64-bit system, and for Leaf7, +// there is no JU_LEAF_UPLEVEL: +// +// Note: Theres no way here to go from Leaf3 [Leaf7] to LEAFW on a 32-bit +// [64-bit] system. Thats handled in the main code, because its different in +// that a JPM is involved. + +#ifndef JU_64BIT // 32-bit. +#define JU_LEAF_UPLEVEL64(cIS,LeafType,MaxPop1,NewJPType,LeafToLeaf, \ + Alloc,ValueArea) // null. +#else +#define JU_LEAF_UPLEVEL64(cIS,LeafType,MaxPop1,NewJPType,LeafToLeaf, \ + Alloc,ValueArea) \ + JU_LEAF_UPLEVEL (cIS,LeafType,MaxPop1,NewJPType,LeafToLeaf, \ + Alloc,ValueArea) +#define JU_LEAF_UPLEVEL_NONE(cIS,LeafType,MaxPop1,NewJPType,LeafToLeaf, \ + Alloc,ValueArea) // null. +#endif + +// Compress a Leaf* with pop1 = 2, or a JPIMMED_*_02, into a JPIMMED_*_01: +// +// Copy whichever Index is NOT being deleted (and assert that the other one is +// found; Index must be valid). This requires special handling of the Index +// bytes (and value area). Variables Pjp, Index, offset, and Pleaf are in the +// context, offset is modified to the undeleted Index, and Pjp is modified +// including jp_Addr. + + +#define JU_TOIMMED_01_EVEN(cIS,ignore1,ignore2) \ +{ \ + Word_t D_cdP0; \ + Word_t A_ddr = 0; \ + uint8_t T_ype = JU_JPTYPE(Pjp); \ + offset = (Pleaf[0] == JU_LEASTBYTES(Index, cIS)); /* undeleted Ind */ \ + assert(Pleaf[offset ? 0 : 1] == JU_LEASTBYTES(Index, cIS)); \ + D_cdP0 = (Index & cJU_DCDMASK(cIS)) | Pleaf[offset]; \ +JUDYLCODE(A_ddr = Pjv[offset];) \ + JU_JPSETADT(Pjp, A_ddr, D_cdP0, T_ype); \ +} + +#define JU_TOIMMED_01_ODD(cIS,SearchLeaf,CopyPIndex) \ + { \ + Word_t D_cdP0; \ + Word_t A_ddr = 0; \ + uint8_t T_ype = JU_JPTYPE(Pjp); \ + \ + offset = SearchLeaf(Pleaf, 2, Index); \ + assert(offset >= 0); /* Index must be valid */ \ + CopyPIndex(D_cdP0, & (Pleaf[offset ? 0 : cIS])); \ + D_cdP0 |= Index & cJU_DCDMASK(cIS); \ + JUDYLCODE(A_ddr = Pjv[offset ? 0 : 1];) \ + JU_JPSETADT(Pjp, A_ddr, D_cdP0, T_ype); \ + } + + +// Compress a Leaf* into a JPIMMED_*_0[2+]: +// +// This occurs as soon as its possible, with hysteresis = 0. Variables pop1, +// Pleaf, offset, and Pjpm are in the context. +// +// TBD: Explain why hysteresis = 0 here, rather than > 0. Probably because +// the insert code assumes if the population is small enough, an Immed is used, +// not a leaf. +// +// The differences between Judy1 and JudyL with respect to value area handling +// are just too large for completely common code between them... Oh well, some +// big ifdefs follow. + +#ifdef JUDY1 + +#define JU_LEAF_TOIMMED(cIS,LeafType,MaxPop1,BaseJPType,ignore1,\ + ignore2,ignore3,ignore4, \ + DeleteCopy,FreeLeaf) \ + \ + assert(pop1 > (MaxPop1)); \ + \ + if ((pop1 - 1) == (MaxPop1)) /* hysteresis = 0 */ \ + { \ + Pjll_t PjllRaw = (Pjll_t) (Pjp->jp_Addr); \ + DeleteCopy((LeafType) (Pjp->jp_1Index), Pleaf, pop1, offset, cIS); \ + DBGCODE(JudyCheckSorted((Pjll_t) (Pjp->jp_1Index), pop1-1, cIS);) \ + Pjp->jp_Type = (BaseJPType) - 1 + (MaxPop1) - 1; \ + FreeLeaf(PjllRaw, pop1, Pjpm); \ + return(1); \ + } + +#else // JUDYL + +// Pjv is also in the context. + +#define JU_LEAF_TOIMMED(cIS,LeafType,MaxPop1,BaseJPType,ignore1,\ + ignore2,ignore3,ignore4, \ + DeleteCopy,FreeLeaf) \ + \ + assert(pop1 > (MaxPop1)); \ + \ + if ((pop1 - 1) == (MaxPop1)) /* hysteresis = 0 */ \ + { \ + Pjll_t PjllRaw = (Pjll_t) (Pjp->jp_Addr); \ + Pjv_t PjvnewRaw; \ + Pjv_t Pjvnew; \ + \ + if ((PjvnewRaw = j__udyLAllocJV(pop1 - 1, Pjpm)) \ + == (Pjv_t) NULL) return(-1); \ + JUDYLCODE(Pjvnew = P_JV(PjvnewRaw);) \ + \ + DeleteCopy((LeafType) (Pjp->jp_LIndex), Pleaf, pop1, offset, cIS); \ + JU_DELETECOPY(Pjvnew, Pjv, pop1, offset, cIS); \ + DBGCODE(JudyCheckSorted((Pjll_t) (Pjp->jp_LIndex), pop1-1, cIS);) \ + FreeLeaf(PjllRaw, pop1, Pjpm); \ + Pjp->jp_Addr = (Word_t) PjvnewRaw; \ + Pjp->jp_Type = (BaseJPType) - 2 + (MaxPop1); \ + return(1); \ + } + +// A complicating factor for JudyL & 32-bit is that Leaf2..3, and for JudyL & +// 64-bit Leaf 4..7, go directly to an Immed*_01, where the value is stored in +// jp_Addr and not in a separate LeafV. For efficiency, use the following +// macro in cases where it can apply; it is rigged to do the right thing. +// Unfortunately, this requires the calling code to "know" the transition table +// and call the right macro. +// +// This variant compresses a Leaf* with pop1 = 2 into a JPIMMED_*_01: + +#define JU_LEAF_TOIMMED_01(cIS,LeafType,MaxPop1,ignore,Immed01JPType, \ + ToImmed,SearchLeaf,CopyPIndex, \ + DeleteCopy,FreeLeaf) \ + \ + assert(pop1 > (MaxPop1)); \ + \ + if ((pop1 - 1) == (MaxPop1)) /* hysteresis = 0 */ \ + { \ + Pjll_t PjllRaw = (Pjll_t) (Pjp->jp_Addr); \ + ToImmed(cIS, SearchLeaf, CopyPIndex); \ + FreeLeaf(PjllRaw, pop1, Pjpm); \ + Pjp->jp_Type = (Immed01JPType); \ + return(1); \ + } +#endif // JUDYL + +// See comments above about these: +// +// Note: Here "23" means index size 2 or 3, and "47" means 4..7. + +#if (defined(JUDY1) || defined(JU_64BIT)) +#define JU_LEAF_TOIMMED_23(cIS,LeafType,MaxPop1,BaseJPType,Immed01JPType, \ + ToImmed,SearchLeaf,CopyPIndex, \ + DeleteCopy,FreeLeaf) \ + JU_LEAF_TOIMMED( cIS,LeafType,MaxPop1,BaseJPType,ignore1, \ + ignore2,ignore3,ignore4, \ + DeleteCopy,FreeLeaf) +#else // JUDYL && 32-bit +#define JU_LEAF_TOIMMED_23(cIS,LeafType,MaxPop1,BaseJPType,Immed01JPType, \ + ToImmed,SearchLeaf,CopyPIndex, \ + DeleteCopy,FreeLeaf) \ + JU_LEAF_TOIMMED_01(cIS,LeafType,MaxPop1,ignore,Immed01JPType, \ + ToImmed,SearchLeaf,CopyPIndex, \ + DeleteCopy,FreeLeaf) +#endif + +#ifdef JU_64BIT +#ifdef JUDY1 +#define JU_LEAF_TOIMMED_47(cIS,LeafType,MaxPop1,BaseJPType,Immed01JPType, \ + ToImmed,SearchLeaf,CopyPIndex, \ + DeleteCopy,FreeLeaf) \ + JU_LEAF_TOIMMED( cIS,LeafType,MaxPop1,BaseJPType,ignore1, \ + ignore2,ignore3,ignore4, \ + DeleteCopy,FreeLeaf) +#else // JUDYL && 64-bit +#define JU_LEAF_TOIMMED_47(cIS,LeafType,MaxPop1,BaseJPType,Immed01JPType, \ + ToImmed,SearchLeaf,CopyPIndex, \ + DeleteCopy,FreeLeaf) \ + JU_LEAF_TOIMMED_01(cIS,LeafType,MaxPop1,ignore,Immed01JPType, \ + ToImmed,SearchLeaf,CopyPIndex, \ + DeleteCopy,FreeLeaf) +#endif // JUDYL +#endif // JU_64BIT + +// Compress a Leaf* in place: +// +// Here hysteresis = 0 (no memory is wasted). Variables pop1, Pleaf, and +// offset, and for JudyL, Pjv, are in the context. + +#ifdef JUDY1 +#define JU_LEAF_INPLACE(cIS,GrowInPlace,DeleteInPlace) \ + if (GrowInPlace(pop1 - 1)) /* hysteresis = 0 */ \ + { \ + DeleteInPlace(Pleaf, pop1, offset, cIS); \ + DBGCODE(JudyCheckSorted(Pleaf, pop1 - 1, cIS);) \ + return(1); \ + } +#else +#define JU_LEAF_INPLACE(cIS,GrowInPlace,DeleteInPlace) \ + if (GrowInPlace(pop1 - 1)) /* hysteresis = 0 */ \ + { \ + DeleteInPlace(Pleaf, pop1, offset, cIS); \ +/**/ JU_DELETEINPLACE(Pjv, pop1, offset, ignore); \ + DBGCODE(JudyCheckSorted(Pleaf, pop1 - 1, cIS);) \ + return(1); \ + } +#endif + +// Compress a Leaf* into a smaller memory object of the same JP type: +// +// Variables PjllnewRaw, Pjllnew, Pleafpop1, Pjpm, PleafRaw, Pleaf, and offset +// are in the context. + +#ifdef JUDY1 + +#define JU_LEAF_SHRINK(cIS,LeafType,DeleteCopy,Alloc,FreeLeaf,ValueArea) \ + if ((PjllnewRaw = Alloc(pop1 - 1, Pjpm)) == 0) return(-1); \ + Pjllnew = P_JLL(PjllnewRaw); \ + DeleteCopy((LeafType) Pjllnew, Pleaf, pop1, offset, cIS); \ + DBGCODE(JudyCheckSorted(Pjllnew, pop1 - 1, cIS);) \ + FreeLeaf(PleafRaw, pop1, Pjpm); \ + Pjp->jp_Addr = (Word_t) PjllnewRaw; \ + return(1) + +#else // JUDYL + +#define JU_LEAF_SHRINK(cIS,LeafType,DeleteCopy,Alloc,FreeLeaf,ValueArea) \ + { \ +/**/ Pjv_t Pjvnew; \ + \ + if ((PjllnewRaw = Alloc(pop1 - 1, Pjpm)) == 0) return(-1); \ + Pjllnew = P_JLL(PjllnewRaw); \ +/**/ Pjvnew = ValueArea(Pjllnew, pop1 - 1); \ + DeleteCopy((LeafType) Pjllnew, Pleaf, pop1, offset, cIS); \ +/**/ JU_DELETECOPY(Pjvnew, Pjv, pop1, offset, cIS); \ + DBGCODE(JudyCheckSorted(Pjllnew, pop1 - 1, cIS);) \ + FreeLeaf(PleafRaw, pop1, Pjpm); \ + Pjp->jp_Addr = (Word_t) PjllnewRaw; \ + return(1); \ + } +#endif // JUDYL + +// Overall common code for Leaf* deletion handling: +// +// See if the leaf can be: +// - (de)compressed to one a level higher (JU_LEAF_UPLEVEL()), or if not, +// - compressed to an Immediate JP (JU_LEAF_TOIMMED()), or if not, +// - shrunk in place (JU_LEAF_INPLACE()), or if none of those, then +// - shrink the leaf to a smaller chunk of memory (JU_LEAF_SHRINK()). +// +// Variables Pjp, pop1, Index, and offset are in the context. +// The *Up parameters refer to a leaf one level up, if there is any. + +#define JU_LEAF(cIS, \ + UpLevel, \ + LeafTypeUp,MaxPop1Up,LeafJPTypeUp,LeafToLeaf, \ + AllocUp,ValueAreaUp, \ + LeafToImmed,ToImmed,CopyPIndex, \ + LeafType,ImmedMaxPop1,ImmedBaseJPType,Immed01JPType, \ + SearchLeaf,GrowInPlace,DeleteInPlace,DeleteCopy, \ + Alloc,FreeLeaf,ValueArea) \ + { \ + Pjll_t PleafRaw; \ + LeafType Pleaf; \ + \ + assert(! JU_DCDNOTMATCHINDEX(Index, Pjp, cIS)); \ + assert(ParentLevel > (cIS)); \ + \ + PleafRaw = (Pjll_t) (Pjp->jp_Addr); \ + Pleaf = (LeafType) P_JLL(PleafRaw); \ + pop1 = JU_JPLEAF_POP0(Pjp) + 1; \ + \ + UpLevel(cIS, LeafTypeUp, MaxPop1Up, LeafJPTypeUp, \ + LeafToLeaf, AllocUp, ValueAreaUp); \ + \ + offset = SearchLeaf(Pleaf, pop1, Index); \ + assert(offset >= 0); /* Index must be valid */ \ + JUDYLCODE(Pjv = ValueArea(Pleaf, pop1);) \ + \ + LeafToImmed(cIS, LeafType, ImmedMaxPop1, \ + ImmedBaseJPType, Immed01JPType, \ + ToImmed, SearchLeaf, CopyPIndex, \ + DeleteCopy, FreeLeaf); \ + \ + JU_LEAF_INPLACE(cIS, GrowInPlace, DeleteInPlace); \ + \ + JU_LEAF_SHRINK(cIS, LeafType, DeleteCopy, Alloc, FreeLeaf, \ + ValueArea); \ + } + +// END OF MACROS, START OF CASES: +// +// (*) Leaf1 [[ => 1_15..08 ] => 1_07 => ... => 1_04 ] => 1_03 => 1_02 => 1_01 + +#if (defined(JUDYL) || (! defined(JU_64BIT))) + case cJU_JPLEAF1: + + JU_LEAF(1, + JU_LEAF_UPLEVEL, uint16_t *, cJU_LEAF2_MAXPOP1, cJU_JPLEAF2, + j__udyLeaf1ToLeaf2, j__udyAllocJLL2, JL_LEAF2VALUEAREA, + JU_LEAF_TOIMMED, ignore, ignore, + uint8_t *, cJU_IMMED1_MAXPOP1, + cJU_JPIMMED_1_02, cJU_JPIMMED_1_01, j__udySearchLeaf1, + JU_LEAF1GROWINPLACE, JU_DELETEINPLACE, JU_DELETECOPY, + j__udyAllocJLL1, j__udyFreeJLL1, JL_LEAF1VALUEAREA); +#endif + +// A complicating factor is that for JudyL & 32-bit, a Leaf2 must go directly +// to an Immed 2_01 and a Leaf3 must go directly to an Immed 3_01: +// +// Leaf2 [[ => 2_07..04 ] => 2_03 => 2_02 ] => 2_01 +// Leaf3 [[ => 3_05..03 ] => 3_02 ] => 3_01 +// +// Hence use JU_LEAF_TOIMMED_23 instead of JU_LEAF_TOIMMED in the cases below, +// and also the parameters ToImmed and, for odd index sizes, CopyPIndex, are +// required. + + case cJU_JPLEAF2: + + JU_LEAF(2, + JU_LEAF_UPLEVEL, uint8_t *, cJU_LEAF3_MAXPOP1, cJU_JPLEAF3, + j__udyLeaf2ToLeaf3, j__udyAllocJLL3, JL_LEAF3VALUEAREA, + JU_LEAF_TOIMMED_23, JU_TOIMMED_01_EVEN, ignore, + uint16_t *, cJU_IMMED2_MAXPOP1, + cJU_JPIMMED_2_02, cJU_JPIMMED_2_01, j__udySearchLeaf2, + JU_LEAF2GROWINPLACE, JU_DELETEINPLACE, JU_DELETECOPY, + j__udyAllocJLL2, j__udyFreeJLL2, JL_LEAF2VALUEAREA); + +// On 32-bit there is no transition to "uplevel" for a Leaf3, so use +// JU_LEAF_UPLEVEL64 instead of JU_LEAF_UPLEVEL: + + case cJU_JPLEAF3: + + JU_LEAF(3, + JU_LEAF_UPLEVEL64, uint32_t *, cJU_LEAF4_MAXPOP1, + cJU_JPLEAF4, + j__udyLeaf3ToLeaf4, j__udyAllocJLL4, JL_LEAF4VALUEAREA, + JU_LEAF_TOIMMED_23, + JU_TOIMMED_01_ODD, JU_COPY3_PINDEX_TO_LONG, + uint8_t *, cJU_IMMED3_MAXPOP1, + cJU_JPIMMED_3_02, cJU_JPIMMED_3_01, j__udySearchLeaf3, + JU_LEAF3GROWINPLACE, JU_DELETEINPLACE_ODD, + JU_DELETECOPY_ODD, + j__udyAllocJLL3, j__udyFreeJLL3, JL_LEAF3VALUEAREA); + +#ifdef JU_64BIT + +// A complicating factor is that for JudyL & 64-bit, a Leaf[4-7] must go +// directly to an Immed [4-7]_01: +// +// Leaf4 [[ => 4_03..02 ]] => 4_01 +// Leaf5 [[ => 5_03..02 ]] => 5_01 +// Leaf6 [[ => 6_02 ]] => 6_01 +// Leaf7 [[ => 7_02 ]] => 7_01 +// +// Hence use JU_LEAF_TOIMMED_47 instead of JU_LEAF_TOIMMED in the cases below. + + case cJU_JPLEAF4: + + JU_LEAF(4, + JU_LEAF_UPLEVEL, uint8_t *, cJU_LEAF5_MAXPOP1, cJU_JPLEAF5, + j__udyLeaf4ToLeaf5, j__udyAllocJLL5, JL_LEAF5VALUEAREA, + JU_LEAF_TOIMMED_47, JU_TOIMMED_01_EVEN, ignore, + uint32_t *, cJU_IMMED4_MAXPOP1, + cJ1_JPIMMED_4_02, cJU_JPIMMED_4_01, j__udySearchLeaf4, + JU_LEAF4GROWINPLACE, JU_DELETEINPLACE, JU_DELETECOPY, + j__udyAllocJLL4, j__udyFreeJLL4, JL_LEAF4VALUEAREA); + + case cJU_JPLEAF5: + + JU_LEAF(5, + JU_LEAF_UPLEVEL, uint8_t *, cJU_LEAF6_MAXPOP1, cJU_JPLEAF6, + j__udyLeaf5ToLeaf6, j__udyAllocJLL6, JL_LEAF6VALUEAREA, + JU_LEAF_TOIMMED_47, + JU_TOIMMED_01_ODD, JU_COPY5_PINDEX_TO_LONG, + uint8_t *, cJU_IMMED5_MAXPOP1, + cJ1_JPIMMED_5_02, cJU_JPIMMED_5_01, j__udySearchLeaf5, + JU_LEAF5GROWINPLACE, JU_DELETEINPLACE_ODD, + JU_DELETECOPY_ODD, + j__udyAllocJLL5, j__udyFreeJLL5, JL_LEAF5VALUEAREA); + + case cJU_JPLEAF6: + + JU_LEAF(6, + JU_LEAF_UPLEVEL, uint8_t *, cJU_LEAF7_MAXPOP1, cJU_JPLEAF7, + j__udyLeaf6ToLeaf7, j__udyAllocJLL7, JL_LEAF7VALUEAREA, + JU_LEAF_TOIMMED_47, + JU_TOIMMED_01_ODD, JU_COPY6_PINDEX_TO_LONG, + uint8_t *, cJU_IMMED6_MAXPOP1, + cJ1_JPIMMED_6_02, cJU_JPIMMED_6_01, j__udySearchLeaf6, + JU_LEAF6GROWINPLACE, JU_DELETEINPLACE_ODD, + JU_DELETECOPY_ODD, + j__udyAllocJLL6, j__udyFreeJLL6, JL_LEAF6VALUEAREA); + +// There is no transition to "uplevel" for a Leaf7, so use JU_LEAF_UPLEVEL_NONE +// instead of JU_LEAF_UPLEVEL, and ignore all of the parameters to that macro: + + case cJU_JPLEAF7: + + JU_LEAF(7, + JU_LEAF_UPLEVEL_NONE, ignore1, ignore2, ignore3, ignore4, + ignore5, ignore6, + JU_LEAF_TOIMMED_47, + JU_TOIMMED_01_ODD, JU_COPY7_PINDEX_TO_LONG, + uint8_t *, cJU_IMMED7_MAXPOP1, + cJ1_JPIMMED_7_02, cJU_JPIMMED_7_01, j__udySearchLeaf7, + JU_LEAF7GROWINPLACE, JU_DELETEINPLACE_ODD, + JU_DELETECOPY_ODD, + j__udyAllocJLL7, j__udyFreeJLL7, JL_LEAF7VALUEAREA); +#endif // JU_64BIT + + +// **************************************************************************** +// BITMAP LEAF: + + case cJU_JPLEAF_B1: + { +#ifdef JUDYL + Pjv_t PjvnewRaw; // new value area. + Pjv_t Pjvnew; + Word_t subexp; // 1 of 8 subexpanses in bitmap. + Pjlb_t Pjlb; // pointer to bitmap part of the leaf. + BITMAPL_t bitmap; // for one subexpanse. + BITMAPL_t bitmask; // bit set for Indexs digit. +#endif + assert(! JU_DCDNOTMATCHINDEX(Index, Pjp, 1)); + assert(ParentLevel > 1); + // valid Index: + assert(JU_BITMAPTESTL(P_JLB(Pjp->jp_Addr), Index)); + + pop1 = JU_JPLEAF_POP0(Pjp) + 1; + +// Like a Leaf1, see if its under a narrow pointer and can become a Leaf2 +// (hysteresis = 1): + + JU_LEAF_UPLEVEL(1, uint16_t *, cJU_LEAF2_MAXPOP1, cJU_JPLEAF2, + j__udyLeaf1ToLeaf2, j__udyAllocJLL2, + JL_LEAF2VALUEAREA); + +#if (defined(JUDY1) && defined(JU_64BIT)) + +// Handle the unusual special case, on Judy1 64-bit only, where a LeafB1 goes +// directly to a JPIMMED_1_15; as described in comments in Judy1.h and +// JudyIns.c. Copy 1-byte indexes from old LeafB1 to the Immed: + + if ((pop1 - 1) == cJU_IMMED1_MAXPOP1) // hysteresis = 0. + { + Pjlb_t PjlbRaw; // bitmap in old leaf. + Pjlb_t Pjlb; + uint8_t * Pleafnew; // JPIMMED as a pointer. + Word_t ldigit; // larger than uint8_t. + + PjlbRaw = (Pjlb_t) (Pjp->jp_Addr); + Pjlb = P_JLB(PjlbRaw); + Pleafnew = Pjp->jp_1Index; + + JU_BITMAPCLEARL(Pjlb, Index); // unset Indexs bit. + +// TBD: This is very slow, there must be a better way: + + for (ldigit = 0; ldigit < cJU_BRANCHUNUMJPS; ++ldigit) + { + if (JU_BITMAPTESTL(Pjlb, ldigit)) + { + *Pleafnew++ = ldigit; + assert(Pleafnew - (Pjp->jp_1Index) + <= cJU_IMMED1_MAXPOP1); + } + } + + DBGCODE(JudyCheckSorted((Pjll_t) (Pjp->jp_1Index), + cJU_IMMED1_MAXPOP1, 1);) + j__udyFreeJLB1(PjlbRaw, Pjpm); + + Pjp->jp_Type = cJ1_JPIMMED_1_15; + return(1); + } + +#else // (JUDYL || (! JU_64BIT)) + +// Compress LeafB1 to a Leaf1: +// +// Note: 4.37 of this file contained alternate code for Judy1 only that simply +// cleared the bit and allowed the LeafB1 to go below cJU_LEAF1_MAXPOP1. This +// was the ONLY case where a malloc failure was not fatal; however, it violated +// the critical assumption that the tree is always kept in least-compressed +// form. + + if (pop1 == cJU_LEAF1_MAXPOP1) // hysteresis = 1. + { + if (j__udyLeafB1ToLeaf1(Pjp, Pjpm) == -1) return(-1); + goto ContinueDelWalk; // delete Index in new Leaf1. + } +#endif // (JUDYL || (! JU_64BIT)) + +#ifdef JUDY1 + // unset Indexs bit: + + JU_BITMAPCLEARL(P_JLB(Pjp->jp_Addr), Index); +#else // JUDYL + +// This is very different from Judy1 because of the need to manage the value +// area: +// +// Get last byte to decode from Index, and pointer to bitmap leaf: + + digit = JU_DIGITATSTATE(Index, 1); + Pjlb = P_JLB(Pjp->jp_Addr); + +// Prepare additional values: + + subexp = digit / cJU_BITSPERSUBEXPL; // which subexpanse. + bitmap = JU_JLB_BITMAP(Pjlb, subexp); // subexps 32-bit map. + PjvRaw = JL_JLB_PVALUE(Pjlb, subexp); // corresponding values. + Pjv = P_JV(PjvRaw); + bitmask = JU_BITPOSMASKL(digit); // mask for Index. + + assert(bitmap & bitmask); // Index must be valid. + + if (bitmap == cJU_FULLBITMAPL) // full bitmap, take shortcut: + { + pop1 = cJU_BITSPERSUBEXPL; + offset = digit % cJU_BITSPERSUBEXPL; + } + else // compute subexpanse pop1 and value area offset: + { + pop1 = j__udyCountBitsL(bitmap); + offset = j__udyCountBitsL(bitmap & (bitmask - 1)); + } + +// Handle solitary Index remaining in subexpanse: + + if (pop1 == 1) + { + j__udyLFreeJV(PjvRaw, 1, Pjpm); + + JL_JLB_PVALUE(Pjlb, subexp) = (Pjv_t) NULL; + JU_JLB_BITMAP(Pjlb, subexp) = 0; + + return(1); + } + +// Shrink value area in place or move to a smaller value area: + + if (JL_LEAFVGROWINPLACE(pop1 - 1)) // hysteresis = 0. + { + JU_DELETEINPLACE(Pjv, pop1, offset, ignore); + } + else + { + if ((PjvnewRaw = j__udyLAllocJV(pop1 - 1, Pjpm)) + == (Pjv_t) NULL) return(-1); + Pjvnew = P_JV(PjvnewRaw); + + JU_DELETECOPY(Pjvnew, Pjv, pop1, offset, ignore); + j__udyLFreeJV(PjvRaw, pop1, Pjpm); + JL_JLB_PVALUE(Pjlb, subexp) = (Pjv_t) PjvnewRaw; + } + + JU_JLB_BITMAP(Pjlb, subexp) ^= bitmask; // clear Indexs bit. + +#endif // JUDYL + + return(1); + + } // case. + + +#ifdef JUDY1 + +// **************************************************************************** +// FULL POPULATION LEAF: +// +// Convert to a LeafB1 and delete the index. Hysteresis = 0; none is possible. +// +// Note: Earlier the second assertion below said, "== 2", but in fact the +// parent could be at a higher level if a fullpop is under a narrow pointer. + + case cJ1_JPFULLPOPU1: + { + Pjlb_t PjlbRaw; + Pjlb_t Pjlb; + Word_t subexp; + + assert(! JU_DCDNOTMATCHINDEX(Index, Pjp, 2)); + assert(ParentLevel > 1); // see above. + + if ((PjlbRaw = j__udyAllocJLB1(Pjpm)) == (Pjlb_t) NULL) + return(-1); + Pjlb = P_JLB(PjlbRaw); + +// Fully populate the leaf, then unset Indexs bit: + + for (subexp = 0; subexp < cJU_NUMSUBEXPL; ++subexp) + JU_JLB_BITMAP(Pjlb, subexp) = cJU_FULLBITMAPL; + + JU_BITMAPCLEARL(Pjlb, Index); + + Pjp->jp_Addr = (Word_t) PjlbRaw; + Pjp->jp_Type = cJU_JPLEAF_B1; + + return(1); + } +#endif // JUDY1 + + +// **************************************************************************** +// IMMEDIATE JP: +// +// If theres just the one Index in the Immed, convert the JP to a JPNULL* +// (should only happen in a BranchU); otherwise delete the Index from the +// Immed. See the state transitions table elsewhere in this file for a summary +// of which Immed types must be handled. Hysteresis = 0; none is possible with +// Immeds. +// +// MACROS FOR COMMON CODE: +// +// Single Index remains in cJU_JPIMMED_*_01; convert JP to null: +// +// Variables Pjp and parentJPtype are in the context. +// +// Note: cJU_JPIMMED_*_01 should only be encountered in BranchUs, not in +// BranchLs or BranchBs (where its improper to merely modify the JP to be a +// null JP); that is, BranchL and BranchB code should have already handled +// any cJU_JPIMMED_*_01 by different means. + +#define JU_IMMED_01(NewJPType,ParentJPType) \ + \ + assert(parentJPtype == (ParentJPType)); \ + assert(JU_JPDCDPOP0(Pjp) == JU_TRIMTODCDSIZE(Index)); \ + JU_JPSETADT(Pjp, 0, 0, NewJPType); \ + return(1) + +// Convert cJ*_JPIMMED_*_02 to cJU_JPIMMED_*_01: +// +// Move the undeleted Index, whichever does not match the least bytes of Index, +// from undecoded-bytes-only (in jp_1Index or jp_LIndex as appropriate) to +// jp_DcdPopO (full-field). Pjp, Index, and offset are in the context. + +#define JU_IMMED_02(cIS,LeafType,NewJPType) \ + { \ + LeafType Pleaf; \ + \ + assert((ParentLevel - 1) == (cIS)); \ + JUDY1CODE(Pleaf = (LeafType) (Pjp->jp_1Index);) \ + JUDYLCODE(Pleaf = (LeafType) (Pjp->jp_LIndex);) \ + JUDYLCODE(PjvRaw = (Pjv_t) (Pjp->jp_Addr);) \ + JUDYLCODE(Pjv = P_JV(PjvRaw);) \ + JU_TOIMMED_01_EVEN(cIS, ignore, ignore); \ + JUDYLCODE(j__udyLFreeJV(PjvRaw, 2, Pjpm);) \ + Pjp->jp_Type = (NewJPType); \ + return(1); \ + } + +#if (defined(JUDY1) || defined(JU_64BIT)) + +// Variation for "odd" cJ*_JPIMMED_*_02 JP types, which are very different from +// "even" types because they use leaf search code and odd-copy macros: +// +// Note: JudyL 32-bit has no "odd" JPIMMED_*_02 types. + +#define JU_IMMED_02_ODD(cIS,NewJPType,SearchLeaf,CopyPIndex) \ + { \ + uint8_t * Pleaf; \ + \ + assert((ParentLevel - 1) == (cIS)); \ + JUDY1CODE(Pleaf = (uint8_t *) (Pjp->jp_1Index);) \ + JUDYLCODE(Pleaf = (uint8_t *) (Pjp->jp_LIndex);) \ + JUDYLCODE(PjvRaw = (Pjv_t) (Pjp->jp_Addr);) \ + JUDYLCODE(Pjv = P_JV(PjvRaw);) \ + JU_TOIMMED_01_ODD(cIS, SearchLeaf, CopyPIndex); \ + JUDYLCODE(j__udyLFreeJV(PjvRaw, 2, Pjpm);) \ + Pjp->jp_Type = (NewJPType); \ + return(1); \ + } +#endif // (JUDY1 || JU_64BIT) + +// Core code for deleting one Index (and for JudyL, its value area) from a +// larger Immed: +// +// Variables Pleaf, pop1, and offset are in the context. + +#ifdef JUDY1 +#define JU_IMMED_DEL(cIS,DeleteInPlace) \ + DeleteInPlace(Pleaf, pop1, offset, cIS); \ + DBGCODE(JudyCheckSorted(Pleaf, pop1 - 1, cIS);) + +#else // JUDYL + +// For JudyL the value area might need to be shrunk: + +#define JU_IMMED_DEL(cIS,DeleteInPlace) \ + \ + if (JL_LEAFVGROWINPLACE(pop1 - 1)) /* hysteresis = 0 */ \ + { \ + DeleteInPlace( Pleaf, pop1, offset, cIS); \ + JU_DELETEINPLACE(Pjv, pop1, offset, ignore); \ + DBGCODE(JudyCheckSorted(Pleaf, pop1 - 1, cIS);) \ + } \ + else \ + { \ + Pjv_t PjvnewRaw; \ + Pjv_t Pjvnew; \ + \ + if ((PjvnewRaw = j__udyLAllocJV(pop1 - 1, Pjpm)) \ + == (Pjv_t) NULL) return(-1); \ + Pjvnew = P_JV(PjvnewRaw); \ + \ + DeleteInPlace(Pleaf, pop1, offset, cIS); \ + JU_DELETECOPY(Pjvnew, Pjv, pop1, offset, ignore); \ + DBGCODE(JudyCheckSorted(Pleaf, pop1 - 1, cIS);) \ + j__udyLFreeJV(PjvRaw, pop1, Pjpm); \ + \ + (Pjp->jp_Addr) = (Word_t) PjvnewRaw; \ + } +#endif // JUDYL + +// Delete one Index from a larger Immed where no restructuring is required: +// +// Variables pop1, Pjp, offset, and Index are in the context. + +#define JU_IMMED(cIS,LeafType,BaseJPType,SearchLeaf,DeleteInPlace) \ + { \ + LeafType Pleaf; \ + \ + assert((ParentLevel - 1) == (cIS)); \ + JUDY1CODE(Pleaf = (LeafType) (Pjp->jp_1Index);) \ + JUDYLCODE(Pleaf = (LeafType) (Pjp->jp_LIndex);) \ + JUDYLCODE(PjvRaw = (Pjv_t) (Pjp->jp_Addr);) \ + JUDYLCODE(Pjv = P_JV(PjvRaw);) \ + pop1 = (JU_JPTYPE(Pjp)) - (BaseJPType) + 2; \ + offset = SearchLeaf(Pleaf, pop1, Index); \ + assert(offset >= 0); /* Index must be valid */ \ + \ + JU_IMMED_DEL(cIS, DeleteInPlace); \ + --(Pjp->jp_Type); \ + return(1); \ + } + + +// END OF MACROS, START OF CASES: + +// Single Index remains in Immed; convert JP to null: + + case cJU_JPIMMED_1_01: JU_IMMED_01(cJU_JPNULL1, cJU_JPBRANCH_U2); + case cJU_JPIMMED_2_01: JU_IMMED_01(cJU_JPNULL2, cJU_JPBRANCH_U3); +#ifndef JU_64BIT + case cJU_JPIMMED_3_01: JU_IMMED_01(cJU_JPNULL3, cJU_JPBRANCH_U); +#else + case cJU_JPIMMED_3_01: JU_IMMED_01(cJU_JPNULL3, cJU_JPBRANCH_U4); + case cJU_JPIMMED_4_01: JU_IMMED_01(cJU_JPNULL4, cJU_JPBRANCH_U5); + case cJU_JPIMMED_5_01: JU_IMMED_01(cJU_JPNULL5, cJU_JPBRANCH_U6); + case cJU_JPIMMED_6_01: JU_IMMED_01(cJU_JPNULL6, cJU_JPBRANCH_U7); + case cJU_JPIMMED_7_01: JU_IMMED_01(cJU_JPNULL7, cJU_JPBRANCH_U); +#endif + +// Multiple Indexes remain in the Immed JP; delete the specified Index: + + case cJU_JPIMMED_1_02: + + JU_IMMED_02(1, uint8_t *, cJU_JPIMMED_1_01); + + case cJU_JPIMMED_1_03: +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_1_04: + case cJU_JPIMMED_1_05: + case cJU_JPIMMED_1_06: + case cJU_JPIMMED_1_07: +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_1_08: + case cJ1_JPIMMED_1_09: + case cJ1_JPIMMED_1_10: + case cJ1_JPIMMED_1_11: + case cJ1_JPIMMED_1_12: + case cJ1_JPIMMED_1_13: + case cJ1_JPIMMED_1_14: + case cJ1_JPIMMED_1_15: +#endif + JU_IMMED(1, uint8_t *, cJU_JPIMMED_1_02, + j__udySearchLeaf1, JU_DELETEINPLACE); + +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_2_02: + + JU_IMMED_02(2, uint16_t *, cJU_JPIMMED_2_01); + + case cJU_JPIMMED_2_03: +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_2_04: + case cJ1_JPIMMED_2_05: + case cJ1_JPIMMED_2_06: + case cJ1_JPIMMED_2_07: +#endif +#if (defined(JUDY1) || defined(JU_64BIT)) + JU_IMMED(2, uint16_t *, cJU_JPIMMED_2_02, + j__udySearchLeaf2, JU_DELETEINPLACE); + + case cJU_JPIMMED_3_02: + + JU_IMMED_02_ODD(3, cJU_JPIMMED_3_01, + j__udySearchLeaf3, JU_COPY3_PINDEX_TO_LONG); + +#endif + +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_3_03: + case cJ1_JPIMMED_3_04: + case cJ1_JPIMMED_3_05: + + JU_IMMED(3, uint8_t *, cJU_JPIMMED_3_02, + j__udySearchLeaf3, JU_DELETEINPLACE_ODD); + + case cJ1_JPIMMED_4_02: + + JU_IMMED_02(4, uint32_t *, cJU_JPIMMED_4_01); + + case cJ1_JPIMMED_4_03: + + JU_IMMED(4, uint32_t *, cJ1_JPIMMED_4_02, + j__udySearchLeaf4, JU_DELETEINPLACE); + + case cJ1_JPIMMED_5_02: + + JU_IMMED_02_ODD(5, cJU_JPIMMED_5_01, + j__udySearchLeaf5, JU_COPY5_PINDEX_TO_LONG); + + case cJ1_JPIMMED_5_03: + + JU_IMMED(5, uint8_t *, cJ1_JPIMMED_5_02, + j__udySearchLeaf5, JU_DELETEINPLACE_ODD); + + case cJ1_JPIMMED_6_02: + + JU_IMMED_02_ODD(6, cJU_JPIMMED_6_01, + j__udySearchLeaf6, JU_COPY6_PINDEX_TO_LONG); + + case cJ1_JPIMMED_7_02: + + JU_IMMED_02_ODD(7, cJU_JPIMMED_7_01, + j__udySearchLeaf7, JU_COPY7_PINDEX_TO_LONG); + +#endif // (JUDY1 && JU_64BIT) + + +// **************************************************************************** +// INVALID JP TYPE: + + default: JU_SET_ERRNO_NONNULL(Pjpm, JU_ERRNO_CORRUPT); return(-1); + + } // switch + + +// PROCESS JP -- RECURSIVELY: +// +// For non-Immed JP types, if successful, post-decrement the population count +// at this level, or collapse a BranchL if necessary by copying the remaining +// JP in the BranchL to the parent (hysteresis = 0), which implicitly creates a +// narrow pointer if there was not already one in the hierarchy. + + assert(level); + retcode = j__udyDelWalk(Pjp, Index, level, Pjpm); + assert(retcode != 0); // should never happen. + + if ((JU_JPTYPE(Pjp)) < cJU_JPIMMED_1_01) // not an Immed. + { + switch (retcode) + { + case 1: + { + jp_t JP = *Pjp; + Word_t DcdP0; + + DcdP0 = JU_JPDCDPOP0(Pjp) - 1; // decrement count. + JU_JPSETADT(Pjp, JP.jp_Addr, DcdP0, JU_JPTYPE(&JP)); + break; + } + case 2: // collapse BranchL to single JP; see above: + { + Pjbl_t PjblRaw = (Pjbl_t) (Pjp->jp_Addr); + Pjbl_t Pjbl = P_JBL(PjblRaw); + + *Pjp = Pjbl->jbl_jp[0]; + j__udyFreeJBL(PjblRaw, Pjpm); + retcode = 1; + } + } + } + + return(retcode); + +} // j__udyDelWalk() + + +// **************************************************************************** +// J U D Y 1 U N S E T +// J U D Y L D E L +// +// Main entry point. See the manual entry for details. + +#ifdef JUDY1 +FUNCTION int Judy1Unset +#else +FUNCTION int JudyLDel +#endif + ( + PPvoid_t PPArray, // in which to delete. + Word_t Index, // to delete. + PJError_t PJError // optional, for returning error info. + ) +{ + Word_t pop1; // population of leaf. + int offset; // at which to delete Index. + JUDY1CODE(int retcode;) // return code from Judy1Test(). +JUDYLCODE(PPvoid_t PPvalue;) // pointer from JudyLGet(). + + +// CHECK FOR NULL ARRAY POINTER (error by caller): + + if (PPArray == (PPvoid_t) NULL) + { + JU_SET_ERRNO(PJError, JU_ERRNO_NULLPPARRAY); + return(JERRI); + } + + +// CHECK IF INDEX IS INVALID: +// +// If so, theres nothing to do. This saves a lot of time. Pass through +// PJError, if any, from the "get" function. + +#ifdef JUDY1 + if ((retcode = Judy1Test(*PPArray, Index, PJError)) == JERRI) + return (JERRI); + + if (retcode == 0) return(0); +#else + if ((PPvalue = JudyLGet(*PPArray, Index, PJError)) == PPJERR) + return (JERRI); + + if (PPvalue == (PPvoid_t) NULL) return(0); +#endif + + +// **************************************************************************** +// PROCESS TOP LEVEL (LEAFW) BRANCHES AND LEAVES: + +// **************************************************************************** +// LEAFW LEAF, OTHER SIZE: +// +// Shrink or convert the leaf as necessary. Hysteresis = 0; none is possible. + + if (JU_LEAFW_POP0(*PPArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW + { + JUDYLCODE(Pjv_t Pjv;) // current value area. + JUDYLCODE(Pjv_t Pjvnew;) // value area in new leaf. + Pjlw_t Pjlw = P_JLW(*PPArray); // first word of leaf. + Pjlw_t Pjlwnew; // replacement leaf. + pop1 = Pjlw[0] + 1; // first word of leaf is pop0. + +// Delete single (last) Index from array: + + if (pop1 == 1) + { + j__udyFreeJLW(Pjlw, /* pop1 = */ 1, (Pjpm_t) NULL); + *PPArray = (Pvoid_t) NULL; + return(1); + } + +// Locate Index in compressible leaf: + + offset = j__udySearchLeafW(Pjlw + 1, pop1, Index); + assert(offset >= 0); // Index must be valid. + + JUDYLCODE(Pjv = JL_LEAFWVALUEAREA(Pjlw, pop1);) + +// Delete Index in-place: +// +// Note: "Grow in place from pop1 - 1" is the logical inverse of, "shrink in +// place from pop1." Also, Pjlw points to the count word, so skip that for +// doing the deletion. + + if (JU_LEAFWGROWINPLACE(pop1 - 1)) + { + JU_DELETEINPLACE(Pjlw + 1, pop1, offset, ignore); +#ifdef JUDYL // also delete from value area: + JU_DELETEINPLACE(Pjv, pop1, offset, ignore); +#endif + DBGCODE(JudyCheckSorted((Pjll_t) (Pjlw + 1), pop1 - 1, + cJU_ROOTSTATE);) + --(Pjlw[0]); // decrement population. + DBGCODE(JudyCheckPop(*PPArray);) + return(1); + } + +// Allocate new leaf for use in either case below: + + Pjlwnew = j__udyAllocJLW(pop1 - 1); + JU_CHECKALLOC(Pjlw_t, Pjlwnew, JERRI); + +// Shrink to smaller LEAFW: +// +// Note: Skip the first word = pop0 in each leaf. + + Pjlwnew[0] = (pop1 - 1) - 1; + JU_DELETECOPY(Pjlwnew + 1, Pjlw + 1, pop1, offset, ignore); + +#ifdef JUDYL // also delete from value area: + Pjvnew = JL_LEAFWVALUEAREA(Pjlwnew, pop1 - 1); + JU_DELETECOPY(Pjvnew, Pjv, pop1, offset, ignore); +#endif + DBGCODE(JudyCheckSorted(Pjlwnew + 1, pop1 - 1, cJU_ROOTSTATE);) + + j__udyFreeJLW(Pjlw, pop1, (Pjpm_t) NULL); + +//// *PPArray = (Pvoid_t) Pjlwnew | cJU_LEAFW); + *PPArray = (Pvoid_t) Pjlwnew; + DBGCODE(JudyCheckPop(*PPArray);) + return(1); + + } + else + + +// **************************************************************************** +// JRP BRANCH: +// +// Traverse through the JPM to do the deletion unless the population is small +// enough to convert immediately to a LEAFW. + + { + Pjpm_t Pjpm; + Pjp_t Pjp; // top-level JP to process. + Word_t digit; // in a branch. + JUDYLCODE(Pjv_t Pjv;) // to value area. + Pjlw_t Pjlwnew; // replacement leaf. + DBGCODE(Pjlw_t Pjlwnew_orig;) + + Pjpm = P_JPM(*PPArray); // top object in array (tree). + Pjp = &(Pjpm->jpm_JP); // next object (first branch or leaf). + + assert(((Pjpm->jpm_JP.jp_Type) == cJU_JPBRANCH_L) + || ((Pjpm->jpm_JP.jp_Type) == cJU_JPBRANCH_B) + || ((Pjpm->jpm_JP.jp_Type) == cJU_JPBRANCH_U)); + +// WALK THE TREE +// +// Note: Recursive code in j__udyDelWalk() knows how to collapse a lower-level +// BranchL containing a single JP into the parent JP as a narrow pointer, but +// the code here cant do that for a top-level BranchL. The result can be +// PArray -> JPM -> BranchL containing a single JP. This situation is +// unavoidable because a JPM cannot contain a narrow pointer; the BranchL is +// required in order to hold the top digit decoded, and it does not collapse to +// a LEAFW until the population is low enough. +// +// TBD: Should we add a topdigit field to JPMs so they can hold narrow +// pointers? + + if (j__udyDelWalk(Pjp, Index, cJU_ROOTSTATE, Pjpm) == -1) + { + JU_COPY_ERRNO(PJError, Pjpm); + return(JERRI); + } + + --(Pjpm->jpm_Pop0); // success; decrement total population. + + if ((Pjpm->jpm_Pop0 + 1) != cJU_LEAFW_MAXPOP1) + { + DBGCODE(JudyCheckPop(*PPArray);) + return(1); + } + +// COMPRESS A BRANCH[LBU] TO A LEAFW: +// + Pjlwnew = j__udyAllocJLW(cJU_LEAFW_MAXPOP1); + JU_CHECKALLOC(Pjlw_t, Pjlwnew, JERRI); + +// Plug leaf into root pointer and set population count: + +//// *PPArray = (Pvoid_t) ((Word_t) Pjlwnew | cJU_LEAFW); + *PPArray = (Pvoid_t) Pjlwnew; +#ifdef JUDYL // prepare value area: + Pjv = JL_LEAFWVALUEAREA(Pjlwnew, cJU_LEAFW_MAXPOP1); +#endif + *Pjlwnew++ = cJU_LEAFW_MAXPOP1 - 1; // set pop0. + DBGCODE(Pjlwnew_orig = Pjlwnew;) + + switch (JU_JPTYPE(Pjp)) + { + +// JPBRANCH_L: Copy each JPs indexes to the new LEAFW and free the old +// branch: + + case cJU_JPBRANCH_L: + { + Pjbl_t PjblRaw = (Pjbl_t) (Pjp->jp_Addr); + Pjbl_t Pjbl = P_JBL(PjblRaw); + + for (offset = 0; offset < Pjbl->jbl_NumJPs; ++offset) + { + pop1 = j__udyLeafM1ToLeafW(Pjlwnew, JU_PVALUEPASS + (Pjbl->jbl_jp) + offset, + JU_DIGITTOSTATE(Pjbl->jbl_Expanse[offset], + cJU_BYTESPERWORD), + (Pvoid_t) Pjpm); + Pjlwnew += pop1; // advance through indexes. + JUDYLCODE(Pjv += pop1;) // advance through values. + } + j__udyFreeJBL(PjblRaw, Pjpm); + + assert(Pjlwnew == Pjlwnew_orig + cJU_LEAFW_MAXPOP1); + break; // delete Index from new LEAFW. + } + +// JPBRANCH_B: Copy each JPs indexes to the new LEAFW and free the old +// branch, including each JP subarray: + + case cJU_JPBRANCH_B: + { + Pjbb_t PjbbRaw = (Pjbb_t) (Pjp->jp_Addr); + Pjbb_t Pjbb = P_JBB(PjbbRaw); + Word_t subexp; // current subexpanse number. + BITMAPB_t bitmap; // portion for this subexpanse. + Pjp_t Pjp2Raw; // one subexpanses subarray. + Pjp_t Pjp2; + + for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp) + { + if ((bitmap = JU_JBB_BITMAP(Pjbb, subexp)) == 0) + continue; // skip empty subexpanse. + + digit = subexp * cJU_BITSPERSUBEXPB; + Pjp2Raw = JU_JBB_PJP(Pjbb, subexp); + Pjp2 = P_JP(Pjp2Raw); + assert(Pjp2 != (Pjp_t) NULL); + +// Walk through bits for all possible sub-subexpanses (digits); increment +// offset for each populated subexpanse; until no more set bits: + + for (offset = 0; bitmap != 0; bitmap >>= 1, ++digit) + { + if (! (bitmap & 1)) // skip empty sub-subexpanse. + continue; + + pop1 = j__udyLeafM1ToLeafW(Pjlwnew, JU_PVALUEPASS + Pjp2 + offset, + JU_DIGITTOSTATE(digit, cJU_BYTESPERWORD), + (Pvoid_t) Pjpm); + Pjlwnew += pop1; // advance through indexes. + JUDYLCODE(Pjv += pop1;) // advance through values. + ++offset; + } + j__udyFreeJBBJP(Pjp2Raw, /* pop1 = */ offset, Pjpm); + } + j__udyFreeJBB(PjbbRaw, Pjpm); + + assert(Pjlwnew == Pjlwnew_orig + cJU_LEAFW_MAXPOP1); + break; // delete Index from new LEAFW. + + } // case cJU_JPBRANCH_B. + + +// JPBRANCH_U: Copy each JPs indexes to the new LEAFW and free the old +// branch: + + case cJU_JPBRANCH_U: + { + Pjbu_t PjbuRaw = (Pjbu_t) (Pjp->jp_Addr); + Pjbu_t Pjbu = P_JBU(PjbuRaw); + Word_t ldigit; // larger than uint8_t. + + for (Pjp = Pjbu->jbu_jp, ldigit = 0; + ldigit < cJU_BRANCHUNUMJPS; + ++Pjp, ++ldigit) + { + +// Shortcuts, to save a little time for possibly big branches: + + if ((JU_JPTYPE(Pjp)) == cJU_JPNULLMAX) // skip null JP. + continue; + +// TBD: Should the following shortcut also be used in BranchL and BranchB +// code? + +#ifndef JU_64BIT + if ((JU_JPTYPE(Pjp)) == cJU_JPIMMED_3_01) +#else + if ((JU_JPTYPE(Pjp)) == cJU_JPIMMED_7_01) +#endif + { // single Immed: + *Pjlwnew++ = JU_DIGITTOSTATE(ldigit, cJU_BYTESPERWORD) + | JU_JPDCDPOP0(Pjp); // rebuild Index. +#ifdef JUDYL + *Pjv++ = Pjp->jp_Addr; // copy value area. +#endif + continue; + } + + pop1 = j__udyLeafM1ToLeafW(Pjlwnew, JU_PVALUEPASS + Pjp, JU_DIGITTOSTATE(ldigit, cJU_BYTESPERWORD), + (Pvoid_t) Pjpm); + Pjlwnew += pop1; // advance through indexes. + JUDYLCODE(Pjv += pop1;) // advance through values. + } + j__udyFreeJBU(PjbuRaw, Pjpm); + + assert(Pjlwnew == Pjlwnew_orig + cJU_LEAFW_MAXPOP1); + break; // delete Index from new LEAFW. + + } // case cJU_JPBRANCH_U. + + +// INVALID JP TYPE in jpm_t struct + + default: JU_SET_ERRNO_NONNULL(Pjpm, JU_ERRNO_CORRUPT); + return(JERRI); + + } // end switch on sub-JP type. + + DBGCODE(JudyCheckSorted((Pjll_t) Pjlwnew_orig, cJU_LEAFW_MAXPOP1, + cJU_ROOTSTATE);) + +// FREE JPM (no longer needed): + + j__udyFreeJPM(Pjpm, (Pjpm_t) NULL); + DBGCODE(JudyCheckPop(*PPArray);) + return(1); + + } + /*NOTREACHED*/ + +} // Judy1Unset() / JudyLDel() diff --git a/feeds/p4/libjudy/src/src/JudyCommon/JudyFirst.c b/feeds/p4/libjudy/src/src/JudyCommon/JudyFirst.c new file mode 100644 index 000000000..aaf6639cf --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudyCommon/JudyFirst.c @@ -0,0 +1,213 @@ +// Copyright (C) 2000 - 2002 Hewlett-Packard Company +// +// This program is free software; you can redistribute it and/or modify it +// under the term of the GNU Lesser 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 Lesser General Public License +// for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// _________________ + +// @(#) $Revision: 4.12 $ $Source: /judy/src/JudyCommon/JudyFirst.c $ +// +// Judy*First[Empty]() and Judy*Last[Empty]() routines for Judy1 and JudyL. +// Compile with one of -DJUDY1 or -DJUDYL. +// +// These are inclusive versions of Judy*Next[Empty]() and Judy*Prev[Empty](). + +#if (! (defined(JUDY1) || defined(JUDYL))) +#error: One of -DJUDY1 or -DJUDYL must be specified. +#endif + +#ifdef JUDY1 +#include "Judy1.h" +#else +#include "JudyL.h" +#endif + + +// **************************************************************************** +// J U D Y 1 F I R S T +// J U D Y L F I R S T +// +// See the manual entry for details. + +#ifdef JUDY1 +FUNCTION int Judy1First +#else +FUNCTION PPvoid_t JudyLFirst +#endif + ( + Pcvoid_t PArray, // Judy array to search. + Word_t * PIndex, // starting point and result. + PJError_t PJError // optional, for returning error info. + ) +{ + if (PIndex == (PWord_t) NULL) // caller error: + { + JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX); + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + } + +#ifdef JUDY1 + switch (Judy1Test(PArray, *PIndex, PJError)) + { + case 1: return(1); // found *PIndex itself. + case 0: return(Judy1Next(PArray, PIndex, PJError)); + default: return(JERRI); + } +#else + { + PPvoid_t PValue; + + if ((PValue = JudyLGet(PArray, *PIndex, PJError)) == PPJERR) + return(PPJERR); + + if (PValue != (PPvoid_t) NULL) return(PValue); // found *PIndex. + + return(JudyLNext(PArray, PIndex, PJError)); + } +#endif + +} // Judy1First() / JudyLFirst() + + +// **************************************************************************** +// J U D Y 1 L A S T +// J U D Y L L A S T +// +// See the manual entry for details. + +#ifdef JUDY1 +FUNCTION int Judy1Last( +#else +FUNCTION PPvoid_t JudyLLast( +#endif + Pcvoid_t PArray, // Judy array to search. + Word_t * PIndex, // starting point and result. + PJError_t PJError) // optional, for returning error info. +{ + if (PIndex == (PWord_t) NULL) + { + JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX); // caller error. + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + } + +#ifdef JUDY1 + switch (Judy1Test(PArray, *PIndex, PJError)) + { + case 1: return(1); // found *PIndex itself. + case 0: return(Judy1Prev(PArray, PIndex, PJError)); + default: return(JERRI); + } +#else + { + PPvoid_t PValue; + + if ((PValue = JudyLGet(PArray, *PIndex, PJError)) == PPJERR) + return(PPJERR); + + if (PValue != (PPvoid_t) NULL) return(PValue); // found *PIndex. + + return(JudyLPrev(PArray, PIndex, PJError)); + } +#endif + +} // Judy1Last() / JudyLLast() + + +// **************************************************************************** +// J U D Y 1 F I R S T E M P T Y +// J U D Y L F I R S T E M P T Y +// +// See the manual entry for details. + +#ifdef JUDY1 +FUNCTION int Judy1FirstEmpty( +#else +FUNCTION int JudyLFirstEmpty( +#endif + Pcvoid_t PArray, // Judy array to search. + Word_t * PIndex, // starting point and result. + PJError_t PJError) // optional, for returning error info. +{ + if (PIndex == (PWord_t) NULL) // caller error: + { + JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX); + return(JERRI); + } + +#ifdef JUDY1 + switch (Judy1Test(PArray, *PIndex, PJError)) + { + case 0: return(1); // found *PIndex itself. + case 1: return(Judy1NextEmpty(PArray, PIndex, PJError)); + default: return(JERRI); + } +#else + { + PPvoid_t PValue; + + if ((PValue = JudyLGet(PArray, *PIndex, PJError)) == PPJERR) + return(JERRI); + + if (PValue == (PPvoid_t) NULL) return(1); // found *PIndex. + + return(JudyLNextEmpty(PArray, PIndex, PJError)); + } +#endif + +} // Judy1FirstEmpty() / JudyLFirstEmpty() + + +// **************************************************************************** +// J U D Y 1 L A S T E M P T Y +// J U D Y L L A S T E M P T Y +// +// See the manual entry for details. + +#ifdef JUDY1 +FUNCTION int Judy1LastEmpty( +#else +FUNCTION int JudyLLastEmpty( +#endif + Pcvoid_t PArray, // Judy array to search. + Word_t * PIndex, // starting point and result. + PJError_t PJError) // optional, for returning error info. +{ + if (PIndex == (PWord_t) NULL) + { + JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX); // caller error. + return(JERRI); + } + +#ifdef JUDY1 + switch (Judy1Test(PArray, *PIndex, PJError)) + { + case 0: return(1); // found *PIndex itself. + case 1: return(Judy1PrevEmpty(PArray, PIndex, PJError)); + default: return(JERRI); + } +#else + { + PPvoid_t PValue; + + if ((PValue = JudyLGet(PArray, *PIndex, PJError)) == PPJERR) + return(JERRI); + + if (PValue == (PPvoid_t) NULL) return(1); // found *PIndex. + + return(JudyLPrevEmpty(PArray, PIndex, PJError)); + } +#endif + +} // Judy1LastEmpty() / JudyLLastEmpty() diff --git a/feeds/p4/libjudy/src/src/JudyCommon/JudyFreeArray.c b/feeds/p4/libjudy/src/src/JudyCommon/JudyFreeArray.c new file mode 100644 index 000000000..34fac509e --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudyCommon/JudyFreeArray.c @@ -0,0 +1,363 @@ +// Copyright (C) 2000 - 2002 Hewlett-Packard Company +// +// This program is free software; you can redistribute it and/or modify it +// under the term of the GNU Lesser 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 Lesser General Public License +// for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// _________________ + +// @(#) $Revision: 4.51 $ $Source: /judy/src/JudyCommon/JudyFreeArray.c $ +// +// Judy1FreeArray() and JudyLFreeArray() functions for Judy1 and JudyL. +// Compile with one of -DJUDY1 or -DJUDYL. +// Return the number of bytes freed from the array. + +#if (! (defined(JUDY1) || defined(JUDYL))) +#error: One of -DJUDY1 or -DJUDYL must be specified. +#endif + +#ifdef JUDY1 +#include "Judy1.h" +#else +#include "JudyL.h" +#endif + +#include "JudyPrivate1L.h" + +DBGCODE(extern void JudyCheckPop(Pvoid_t PArray);) + + +// **************************************************************************** +// J U D Y 1 F R E E A R R A Y +// J U D Y L F R E E A R R A Y +// +// See the Judy*(3C) manual entry for details. +// +// This code is written recursively, at least at first, because thats much +// simpler. Hope its fast enough. + +#ifdef JUDY1 +FUNCTION Word_t Judy1FreeArray +#else +FUNCTION Word_t JudyLFreeArray +#endif + ( + PPvoid_t PPArray, // array to free. + PJError_t PJError // optional, for returning error info. + ) +{ + jpm_t jpm; // local to accumulate free statistics. + +// CHECK FOR NULL POINTER (error by caller): + + if (PPArray == (PPvoid_t) NULL) + { + JU_SET_ERRNO(PJError, JU_ERRNO_NULLPPARRAY); + return(JERR); + } + + DBGCODE(JudyCheckPop(*PPArray);) + +// Zero jpm.jpm_Pop0 (meaning the array will be empty in a moment) for accurate +// logging in TRACEMI2. + + jpm.jpm_Pop0 = 0; // see above. + jpm.jpm_TotalMemWords = 0; // initialize memory freed. + +// Empty array: + + if (P_JLW(*PPArray) == (Pjlw_t) NULL) return(0); + +// PROCESS TOP LEVEL "JRP" BRANCHES AND LEAF: + + if (JU_LEAFW_POP0(*PPArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW + { + Pjlw_t Pjlw = P_JLW(*PPArray); // first word of leaf. + + j__udyFreeJLW(Pjlw, Pjlw[0] + 1, &jpm); + *PPArray = (Pvoid_t) NULL; // make an empty array. + return (-(jpm.jpm_TotalMemWords * cJU_BYTESPERWORD)); // see above. + } + else + +// Rootstate leaves: just free the leaf: + +// Common code for returning the amount of memory freed. +// +// Note: In a an ordinary LEAFW, pop0 = *PPArray[0]. +// +// Accumulate (negative) words freed, while freeing objects. +// Return the positive bytes freed. + + { + Pjpm_t Pjpm = P_JPM(*PPArray); + Word_t TotalMem = Pjpm->jpm_TotalMemWords; + + j__udyFreeSM(&(Pjpm->jpm_JP), &jpm); // recurse through tree. + j__udyFreeJPM(Pjpm, &jpm); + +// Verify the array was not corrupt. This means that amount of memory freed +// (which is negative) is equal to the initial amount: + + if (TotalMem + jpm.jpm_TotalMemWords) + { + JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); + return(JERR); + } + + *PPArray = (Pvoid_t) NULL; // make an empty array. + return (TotalMem * cJU_BYTESPERWORD); + } + +} // Judy1FreeArray() / JudyLFreeArray() + + +// **************************************************************************** +// __ J U D Y F R E E S M +// +// Given a pointer to a JP, recursively visit and free (depth first) all nodes +// in a Judy array BELOW the JP, but not the JP itself. Accumulate in *Pjpm +// the total words freed (as a negative value). "SM" = State Machine. +// +// Note: Corruption is not detected at this level because during a FreeArray, +// if the code hasnt already core dumped, its better to remain silent, even +// if some memory has not been freed, than to bother the caller about the +// corruption. TBD: Is this true? If not, must list all legitimate JPNULL +// and JPIMMED above first, and revert to returning bool_t (see 4.34). + +FUNCTION void j__udyFreeSM( + Pjp_t Pjp, // top of Judy (top-state). + Pjpm_t Pjpm) // to return words freed. +{ + Word_t Pop1; + + switch (JU_JPTYPE(Pjp)) + { + +#ifdef JUDY1 + +// FULL EXPANSE -- nothing to free for this jp_Type. + + case cJ1_JPFULLPOPU1: + break; +#endif + +// JUDY BRANCH -- free the sub-tree depth first: + +// LINEAR BRANCH -- visit each JP in the JBLs list, then free the JBL: +// +// Note: There are no null JPs in a JBL. + + case cJU_JPBRANCH_L: + case cJU_JPBRANCH_L2: + case cJU_JPBRANCH_L3: +#ifdef JU_64BIT + case cJU_JPBRANCH_L4: + case cJU_JPBRANCH_L5: + case cJU_JPBRANCH_L6: + case cJU_JPBRANCH_L7: +#endif // JU_64BIT + { + Pjbl_t Pjbl = P_JBL(Pjp->jp_Addr); + Word_t offset; + + for (offset = 0; offset < Pjbl->jbl_NumJPs; ++offset) + j__udyFreeSM((Pjbl->jbl_jp) + offset, Pjpm); + + j__udyFreeJBL((Pjbl_t) (Pjp->jp_Addr), Pjpm); + break; + } + + +// BITMAP BRANCH -- visit each JP in the JBBs list based on the bitmap, also +// +// Note: There are no null JPs in a JBB. + + case cJU_JPBRANCH_B: + case cJU_JPBRANCH_B2: + case cJU_JPBRANCH_B3: +#ifdef JU_64BIT + case cJU_JPBRANCH_B4: + case cJU_JPBRANCH_B5: + case cJU_JPBRANCH_B6: + case cJU_JPBRANCH_B7: +#endif // JU_64BIT + { + Word_t subexp; + Word_t offset; + Word_t jpcount; + + Pjbb_t Pjbb = P_JBB(Pjp->jp_Addr); + + for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp) + { + jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp)); + + if (jpcount) + { + for (offset = 0; offset < jpcount; ++offset) + { + j__udyFreeSM(P_JP(JU_JBB_PJP(Pjbb, subexp)) + offset, + Pjpm); + } + j__udyFreeJBBJP(JU_JBB_PJP(Pjbb, subexp), jpcount, Pjpm); + } + } + j__udyFreeJBB((Pjbb_t) (Pjp->jp_Addr), Pjpm); + + break; + } + + +// UNCOMPRESSED BRANCH -- visit each JP in the JBU array, then free the JBU +// itself: +// +// Note: Null JPs are handled during recursion at a lower state. + + case cJU_JPBRANCH_U: + case cJU_JPBRANCH_U2: + case cJU_JPBRANCH_U3: +#ifdef JU_64BIT + case cJU_JPBRANCH_U4: + case cJU_JPBRANCH_U5: + case cJU_JPBRANCH_U6: + case cJU_JPBRANCH_U7: +#endif // JU_64BIT + { + Word_t offset; + Pjbu_t Pjbu = P_JBU(Pjp->jp_Addr); + + for (offset = 0; offset < cJU_BRANCHUNUMJPS; ++offset) + j__udyFreeSM((Pjbu->jbu_jp) + offset, Pjpm); + + j__udyFreeJBU((Pjbu_t) (Pjp->jp_Addr), Pjpm); + break; + } + + +// -- Cases below here terminate and do not recurse. -- + + +// LINEAR LEAF -- just free the leaf; size is computed from jp_Type: +// +// Note: cJU_JPLEAF1 is a special case, see discussion in ../Judy1/Judy1.h + +#if (defined(JUDYL) || (! defined(JU_64BIT))) + case cJU_JPLEAF1: + Pop1 = JU_JPLEAF_POP0(Pjp) + 1; + j__udyFreeJLL1((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm); + break; +#endif + + case cJU_JPLEAF2: + Pop1 = JU_JPLEAF_POP0(Pjp) + 1; + j__udyFreeJLL2((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm); + break; + + case cJU_JPLEAF3: + Pop1 = JU_JPLEAF_POP0(Pjp) + 1; + j__udyFreeJLL3((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm); + break; + +#ifdef JU_64BIT + case cJU_JPLEAF4: + Pop1 = JU_JPLEAF_POP0(Pjp) + 1; + j__udyFreeJLL4((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm); + break; + + case cJU_JPLEAF5: + Pop1 = JU_JPLEAF_POP0(Pjp) + 1; + j__udyFreeJLL5((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm); + break; + + case cJU_JPLEAF6: + Pop1 = JU_JPLEAF_POP0(Pjp) + 1; + j__udyFreeJLL6((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm); + break; + + case cJU_JPLEAF7: + Pop1 = JU_JPLEAF_POP0(Pjp) + 1; + j__udyFreeJLL7((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm); + break; +#endif // JU_64BIT + + +// BITMAP LEAF -- free sub-expanse arrays of JPs, then free the JBB. + + case cJU_JPLEAF_B1: + { +#ifdef JUDYL + Word_t subexp; + Word_t jpcount; + Pjlb_t Pjlb = P_JLB(Pjp->jp_Addr); + +// Free the value areas in the bitmap leaf: + + for (subexp = 0; subexp < cJU_NUMSUBEXPL; ++subexp) + { + jpcount = j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp)); + + if (jpcount) + j__udyLFreeJV(JL_JLB_PVALUE(Pjlb, subexp), jpcount, Pjpm); + } +#endif // JUDYL + + j__udyFreeJLB1((Pjlb_t) (Pjp->jp_Addr), Pjpm); + break; + + } // case cJU_JPLEAF_B1 + +#ifdef JUDYL + + +// IMMED*: +// +// For JUDYL, all non JPIMMED_*_01s have a LeafV which must be freed: + + case cJU_JPIMMED_1_02: + case cJU_JPIMMED_1_03: +#ifdef JU_64BIT + case cJU_JPIMMED_1_04: + case cJU_JPIMMED_1_05: + case cJU_JPIMMED_1_06: + case cJU_JPIMMED_1_07: +#endif + Pop1 = JU_JPTYPE(Pjp) - cJU_JPIMMED_1_02 + 2; + j__udyLFreeJV((Pjv_t) (Pjp->jp_Addr), Pop1, Pjpm); + break; + +#ifdef JU_64BIT + case cJU_JPIMMED_2_02: + case cJU_JPIMMED_2_03: + + Pop1 = JU_JPTYPE(Pjp) - cJU_JPIMMED_2_02 + 2; + j__udyLFreeJV((Pjv_t) (Pjp->jp_Addr), Pop1, Pjpm); + break; + + case cJU_JPIMMED_3_02: + j__udyLFreeJV((Pjv_t) (Pjp->jp_Addr), 2, Pjpm); + break; + +#endif // JU_64BIT +#endif // JUDYL + + +// OTHER JPNULL, JPIMMED, OR UNEXPECTED TYPE -- nothing to free for this type: +// +// Note: Lump together no-op and invalid JP types; see function header +// comments. + + default: break; + + } // switch (JU_JPTYPE(Pjp)) + +} // j__udyFreeSM() diff --git a/feeds/p4/libjudy/src/src/JudyCommon/JudyGet.c b/feeds/p4/libjudy/src/src/JudyCommon/JudyGet.c new file mode 100644 index 000000000..0bb9971cc --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudyCommon/JudyGet.c @@ -0,0 +1,1094 @@ +// Copyright (C) 2000 - 2002 Hewlett-Packard Company +// +// This program is free software; you can redistribute it and/or modify it +// under the term of the GNU Lesser 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 Lesser General Public License +// for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// _________________ + +// @(#) $Revision: 4.43 $ $Source: /judy/src/JudyCommon/JudyGet.c $ +// +// Judy1Test() and JudyLGet() functions for Judy1 and JudyL. +// Compile with one of -DJUDY1 or -DJUDYL. + +#if (! (defined(JUDY1) || defined(JUDYL))) +#error: One of -DJUDY1 or -DJUDYL must be specified. +#endif + +#ifdef JUDY1 +#include "Judy1.h" +#else +#include "JudyL.h" +#endif + +#include "JudyPrivate1L.h" + +#ifdef TRACEJPR // different macro name, for "retrieval" only. +#include "JudyPrintJP.c" +#endif + + +// **************************************************************************** +// J U D Y 1 T E S T +// J U D Y L G E T +// +// See the manual entry for details. Note support for "shortcut" entries to +// trees known to start with a JPM. + +#ifdef JUDY1 + +#ifdef JUDYGETINLINE +FUNCTION int j__udy1Test +#else +FUNCTION int Judy1Test +#endif + +#else // JUDYL + +#ifdef JUDYGETINLINE +FUNCTION PPvoid_t j__udyLGet +#else +FUNCTION PPvoid_t JudyLGet +#endif + +#endif // JUDYL + ( +#ifdef JUDYGETINLINE + Pvoid_t PArray, // from which to retrieve. + Word_t Index // to retrieve. +#else + Pcvoid_t PArray, // from which to retrieve. + Word_t Index, // to retrieve. + PJError_t PJError // optional, for returning error info. +#endif + ) +{ + Pjp_t Pjp; // current JP while walking the tree. + Pjpm_t Pjpm; // for global accounting. + uint8_t Digit; // byte just decoded from Index. + Word_t Pop1; // leaf population (number of indexes). + Pjll_t Pjll; // pointer to LeafL. + DBGCODE(uint8_t ParentJPType;) + +#ifndef JUDYGETINLINE + + if (PArray == (Pcvoid_t) NULL) // empty array. + { + JUDY1CODE(return(0);) + JUDYLCODE(return((PPvoid_t) NULL);) + } + +// **************************************************************************** +// PROCESS TOP LEVEL BRANCHES AND LEAF: + + if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW + { + Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf. + int posidx; // signed offset in leaf. + + Pop1 = Pjlw[0] + 1; + posidx = j__udySearchLeafW(Pjlw + 1, Pop1, Index); + + if (posidx >= 0) + { + JUDY1CODE(return(1);) + JUDYLCODE(return((PPvoid_t) (JL_LEAFWVALUEAREA(Pjlw, Pop1) + posidx));) + } + JUDY1CODE(return(0);) + JUDYLCODE(return((PPvoid_t) NULL);) + } + +#endif // ! JUDYGETINLINE + + Pjpm = P_JPM(PArray); + Pjp = &(Pjpm->jpm_JP); // top branch is below JPM. + +// **************************************************************************** +// WALK THE JUDY TREE USING A STATE MACHINE: + +ContinueWalk: // for going down one level; come here with Pjp set. + +#ifdef TRACEJPR + JudyPrintJP(Pjp, "g", __LINE__); +#endif + switch (JU_JPTYPE(Pjp)) + { + +// Ensure the switch table starts at 0 for speed; otherwise more code is +// executed: + + case 0: goto ReturnCorrupt; // save a little code. + + +// **************************************************************************** +// JPNULL*: +// +// Note: These are legitimate in a BranchU (only) and do not constitute a +// fault. + + case cJU_JPNULL1: + case cJU_JPNULL2: + case cJU_JPNULL3: +#ifdef JU_64BIT + case cJU_JPNULL4: + case cJU_JPNULL5: + case cJU_JPNULL6: + case cJU_JPNULL7: +#endif + assert(ParentJPType >= cJU_JPBRANCH_U2); + assert(ParentJPType <= cJU_JPBRANCH_U); + JUDY1CODE(return(0);) + JUDYLCODE(return((PPvoid_t) NULL);) + + +// **************************************************************************** +// JPBRANCH_L*: +// +// Note: The use of JU_DCDNOTMATCHINDEX() in branches is not strictly +// required,since this can be done at leaf level, but it costs nothing to do it +// sooner, and it aborts an unnecessary traversal sooner. + + case cJU_JPBRANCH_L2: + + if (JU_DCDNOTMATCHINDEX(Index, Pjp, 2)) break; + Digit = JU_DIGITATSTATE(Index, 2); + goto JudyBranchL; + + case cJU_JPBRANCH_L3: + +#ifdef JU_64BIT // otherwise its a no-op: + if (JU_DCDNOTMATCHINDEX(Index, Pjp, 3)) break; +#endif + Digit = JU_DIGITATSTATE(Index, 3); + goto JudyBranchL; + +#ifdef JU_64BIT + case cJU_JPBRANCH_L4: + + if (JU_DCDNOTMATCHINDEX(Index, Pjp, 4)) break; + Digit = JU_DIGITATSTATE(Index, 4); + goto JudyBranchL; + + case cJU_JPBRANCH_L5: + + if (JU_DCDNOTMATCHINDEX(Index, Pjp, 5)) break; + Digit = JU_DIGITATSTATE(Index, 5); + goto JudyBranchL; + + case cJU_JPBRANCH_L6: + + if (JU_DCDNOTMATCHINDEX(Index, Pjp, 6)) break; + Digit = JU_DIGITATSTATE(Index, 6); + goto JudyBranchL; + + case cJU_JPBRANCH_L7: + + // JU_DCDNOTMATCHINDEX() would be a no-op. + Digit = JU_DIGITATSTATE(Index, 7); + goto JudyBranchL; + +#endif // JU_64BIT + + case cJU_JPBRANCH_L: + { + Pjbl_t Pjbl; + int posidx; + + Digit = JU_DIGITATSTATE(Index, cJU_ROOTSTATE); + +// Common code for all BranchLs; come here with Digit set: + +JudyBranchL: + Pjbl = P_JBL(Pjp->jp_Addr); + + posidx = 0; + + do { + if (Pjbl->jbl_Expanse[posidx] == Digit) + { // found Digit; continue traversal: + DBGCODE(ParentJPType = JU_JPTYPE(Pjp);) + Pjp = Pjbl->jbl_jp + posidx; + goto ContinueWalk; + } + } while (++posidx != Pjbl->jbl_NumJPs); + + break; + } + + +// **************************************************************************** +// JPBRANCH_B*: + + case cJU_JPBRANCH_B2: + + if (JU_DCDNOTMATCHINDEX(Index, Pjp, 2)) break; + Digit = JU_DIGITATSTATE(Index, 2); + goto JudyBranchB; + + case cJU_JPBRANCH_B3: + +#ifdef JU_64BIT // otherwise its a no-op: + if (JU_DCDNOTMATCHINDEX(Index, Pjp, 3)) break; +#endif + Digit = JU_DIGITATSTATE(Index, 3); + goto JudyBranchB; + + +#ifdef JU_64BIT + case cJU_JPBRANCH_B4: + + if (JU_DCDNOTMATCHINDEX(Index, Pjp, 4)) break; + Digit = JU_DIGITATSTATE(Index, 4); + goto JudyBranchB; + + case cJU_JPBRANCH_B5: + + if (JU_DCDNOTMATCHINDEX(Index, Pjp, 5)) break; + Digit = JU_DIGITATSTATE(Index, 5); + goto JudyBranchB; + + case cJU_JPBRANCH_B6: + + if (JU_DCDNOTMATCHINDEX(Index, Pjp, 6)) break; + Digit = JU_DIGITATSTATE(Index, 6); + goto JudyBranchB; + + case cJU_JPBRANCH_B7: + + // JU_DCDNOTMATCHINDEX() would be a no-op. + Digit = JU_DIGITATSTATE(Index, 7); + goto JudyBranchB; + +#endif // JU_64BIT + + case cJU_JPBRANCH_B: + { + Pjbb_t Pjbb; + Word_t subexp; // in bitmap, 0..7. + BITMAPB_t BitMap; // for one subexpanse. + BITMAPB_t BitMask; // bit in BitMap for Indexs Digit. + + Digit = JU_DIGITATSTATE(Index, cJU_ROOTSTATE); + +// Common code for all BranchBs; come here with Digit set: + +JudyBranchB: + DBGCODE(ParentJPType = JU_JPTYPE(Pjp);) + Pjbb = P_JBB(Pjp->jp_Addr); + subexp = Digit / cJU_BITSPERSUBEXPB; + + BitMap = JU_JBB_BITMAP(Pjbb, subexp); + Pjp = P_JP(JU_JBB_PJP(Pjbb, subexp)); + + BitMask = JU_BITPOSMASKB(Digit); + +// No JP in subexpanse for Index => Index not found: + + if (! (BitMap & BitMask)) break; + +// Count JPs in the subexpanse below the one for Index: + + Pjp += j__udyCountBitsB(BitMap & (BitMask - 1)); + + goto ContinueWalk; + + } // case cJU_JPBRANCH_B* + + +// **************************************************************************** +// JPBRANCH_U*: +// +// Notice the reverse order of the cases, and falling through to the next case, +// for performance. + + case cJU_JPBRANCH_U: + + DBGCODE(ParentJPType = JU_JPTYPE(Pjp);) + Pjp = JU_JBU_PJP(Pjp, Index, cJU_ROOTSTATE); + +// If not a BranchU, traverse; otherwise fall into the next case, which makes +// this very fast code for a large Judy array (mainly BranchUs), especially +// when branches are already in the cache, such as for prev/next: + +#ifndef JU_64BIT + if (JU_JPTYPE(Pjp) != cJU_JPBRANCH_U3) goto ContinueWalk; +#else + if (JU_JPTYPE(Pjp) != cJU_JPBRANCH_U7) goto ContinueWalk; +#endif + +#ifdef JU_64BIT + case cJU_JPBRANCH_U7: + + // JU_DCDNOTMATCHINDEX() would be a no-op. + DBGCODE(ParentJPType = JU_JPTYPE(Pjp);) + Pjp = JU_JBU_PJP(Pjp, Index, 7); + + if (JU_JPTYPE(Pjp) != cJU_JPBRANCH_U6) goto ContinueWalk; + // and fall through. + + case cJU_JPBRANCH_U6: + + if (JU_DCDNOTMATCHINDEX(Index, Pjp, 6)) break; + DBGCODE(ParentJPType = JU_JPTYPE(Pjp);) + Pjp = JU_JBU_PJP(Pjp, Index, 6); + + if (JU_JPTYPE(Pjp) != cJU_JPBRANCH_U5) goto ContinueWalk; + // and fall through. + + case cJU_JPBRANCH_U5: + + if (JU_DCDNOTMATCHINDEX(Index, Pjp, 5)) break; + DBGCODE(ParentJPType = JU_JPTYPE(Pjp);) + Pjp = JU_JBU_PJP(Pjp, Index, 5); + + if (JU_JPTYPE(Pjp) != cJU_JPBRANCH_U4) goto ContinueWalk; + // and fall through. + + case cJU_JPBRANCH_U4: + + if (JU_DCDNOTMATCHINDEX(Index, Pjp, 4)) break; + DBGCODE(ParentJPType = JU_JPTYPE(Pjp);) + Pjp = JU_JBU_PJP(Pjp, Index, 4); + + if (JU_JPTYPE(Pjp) != cJU_JPBRANCH_U3) goto ContinueWalk; + // and fall through. + +#endif // JU_64BIT + + case cJU_JPBRANCH_U3: + +#ifdef JU_64BIT // otherwise its a no-op: + if (JU_DCDNOTMATCHINDEX(Index, Pjp, 3)) break; +#endif + DBGCODE(ParentJPType = JU_JPTYPE(Pjp);) + Pjp = JU_JBU_PJP(Pjp, Index, 3); + + if (JU_JPTYPE(Pjp) != cJU_JPBRANCH_U2) goto ContinueWalk; + // and fall through. + + case cJU_JPBRANCH_U2: + + if (JU_DCDNOTMATCHINDEX(Index, Pjp, 2)) break; + DBGCODE(ParentJPType = JU_JPTYPE(Pjp);) + Pjp = JU_JBU_PJP(Pjp, Index, 2); + +// Note: BranchU2 is a special case that must continue traversal to a leaf, +// immed, full, or null type: + + goto ContinueWalk; + + +// **************************************************************************** +// JPLEAF*: +// +// Note: Here the calls of JU_DCDNOTMATCHINDEX() are necessary and check +// whether Index is out of the expanse of a narrow pointer. + +#if (defined(JUDYL) || (! defined(JU_64BIT))) + + case cJU_JPLEAF1: + { + int posidx; // signed offset in leaf. + + if (JU_DCDNOTMATCHINDEX(Index, Pjp, 1)) break; + + Pop1 = JU_JPLEAF_POP0(Pjp) + 1; + Pjll = P_JLL(Pjp->jp_Addr); + + if ((posidx = j__udySearchLeaf1(Pjll, Pop1, Index)) < 0) break; + + JUDY1CODE(return(1);) + JUDYLCODE(return((PPvoid_t) (JL_LEAF1VALUEAREA(Pjll, Pop1) + posidx));) + } + +#endif // (JUDYL || (! JU_64BIT)) + + case cJU_JPLEAF2: + { + int posidx; // signed offset in leaf. + + if (JU_DCDNOTMATCHINDEX(Index, Pjp, 2)) break; + + Pop1 = JU_JPLEAF_POP0(Pjp) + 1; + Pjll = P_JLL(Pjp->jp_Addr); + + if ((posidx = j__udySearchLeaf2(Pjll, Pop1, Index)) < 0) break; + + JUDY1CODE(return(1);) + JUDYLCODE(return((PPvoid_t) (JL_LEAF2VALUEAREA(Pjll, Pop1) + posidx));) + } + case cJU_JPLEAF3: + { + int posidx; // signed offset in leaf. + +#ifdef JU_64BIT // otherwise its a no-op: + if (JU_DCDNOTMATCHINDEX(Index, Pjp, 3)) break; +#endif + + Pop1 = JU_JPLEAF_POP0(Pjp) + 1; + Pjll = P_JLL(Pjp->jp_Addr); + + if ((posidx = j__udySearchLeaf3(Pjll, Pop1, Index)) < 0) break; + + JUDY1CODE(return(1);) + JUDYLCODE(return((PPvoid_t) (JL_LEAF3VALUEAREA(Pjll, Pop1) + posidx));) + } +#ifdef JU_64BIT + case cJU_JPLEAF4: + { + int posidx; // signed offset in leaf. + + if (JU_DCDNOTMATCHINDEX(Index, Pjp, 4)) break; + + Pop1 = JU_JPLEAF_POP0(Pjp) + 1; + Pjll = P_JLL(Pjp->jp_Addr); + + if ((posidx = j__udySearchLeaf4(Pjll, Pop1, Index)) < 0) break; + + JUDY1CODE(return(1);) + JUDYLCODE(return((PPvoid_t) (JL_LEAF4VALUEAREA(Pjll, Pop1) + posidx));) + } + case cJU_JPLEAF5: + { + int posidx; // signed offset in leaf. + + if (JU_DCDNOTMATCHINDEX(Index, Pjp, 5)) break; + + Pop1 = JU_JPLEAF_POP0(Pjp) + 1; + Pjll = P_JLL(Pjp->jp_Addr); + + if ((posidx = j__udySearchLeaf5(Pjll, Pop1, Index)) < 0) break; + + JUDY1CODE(return(1);) + JUDYLCODE(return((PPvoid_t) (JL_LEAF5VALUEAREA(Pjll, Pop1) + posidx));) + } + + case cJU_JPLEAF6: + { + int posidx; // signed offset in leaf. + + if (JU_DCDNOTMATCHINDEX(Index, Pjp, 6)) break; + + Pop1 = JU_JPLEAF_POP0(Pjp) + 1; + Pjll = P_JLL(Pjp->jp_Addr); + + if ((posidx = j__udySearchLeaf6(Pjll, Pop1, Index)) < 0) break; + + JUDY1CODE(return(1);) + JUDYLCODE(return((PPvoid_t) (JL_LEAF6VALUEAREA(Pjll, Pop1) + posidx));) + } + case cJU_JPLEAF7: + { + int posidx; // signed offset in leaf. + + // JU_DCDNOTMATCHINDEX() would be a no-op. + Pop1 = JU_JPLEAF_POP0(Pjp) + 1; + Pjll = P_JLL(Pjp->jp_Addr); + + if ((posidx = j__udySearchLeaf7(Pjll, Pop1, Index)) < 0) break; + + JUDY1CODE(return(1);) + JUDYLCODE(return((PPvoid_t) (JL_LEAF7VALUEAREA(Pjll, Pop1) + posidx));) + } +#endif // JU_64BIT + + +// **************************************************************************** +// JPLEAF_B1: + + case cJU_JPLEAF_B1: + { + Pjlb_t Pjlb; +#ifdef JUDYL + int posidx; + Word_t subexp; // in bitmap, 0..7. + BITMAPL_t BitMap; // for one subexpanse. + BITMAPL_t BitMask; // bit in BitMap for Indexs Digit. + Pjv_t Pjv; +#endif + if (JU_DCDNOTMATCHINDEX(Index, Pjp, 1)) break; + + Pjlb = P_JLB(Pjp->jp_Addr); + +#ifdef JUDY1 + +// Simply check if Indexs bit is set in the bitmap: + + if (JU_BITMAPTESTL(Pjlb, Index)) return(1); + break; + +#else // JUDYL + +// JudyL is much more complicated because of value area subarrays: + + Digit = JU_DIGITATSTATE(Index, 1); + subexp = Digit / cJU_BITSPERSUBEXPL; + BitMap = JU_JLB_BITMAP(Pjlb, subexp); + BitMask = JU_BITPOSMASKL(Digit); + +// No value in subexpanse for Index => Index not found: + + if (! (BitMap & BitMask)) break; + +// Count value areas in the subexpanse below the one for Index: + + Pjv = P_JV(JL_JLB_PVALUE(Pjlb, subexp)); + assert(Pjv != (Pjv_t) NULL); + posidx = j__udyCountBitsL(BitMap & (BitMask - 1)); + + return((PPvoid_t) (Pjv + posidx)); + +#endif // JUDYL + + } // case cJU_JPLEAF_B1 + +#ifdef JUDY1 + +// **************************************************************************** +// JPFULLPOPU1: +// +// If the Index is in the expanse, it is necessarily valid (found). + + case cJ1_JPFULLPOPU1: + + if (JU_DCDNOTMATCHINDEX(Index, Pjp, 1)) break; + return(1); + +#ifdef notdef // for future enhancements +#ifdef JU_64BIT + +// Note: Need ? if (JU_DCDNOTMATCHINDEX(Index, Pjp, 1)) break; + + case cJ1_JPFULLPOPU1m15: + if (Pjp->jp_1Index[14] == (uint8_t)Index) break; + case cJ1_JPFULLPOPU1m14: + if (Pjp->jp_1Index[13] == (uint8_t)Index) break; + case cJ1_JPFULLPOPU1m13: + if (Pjp->jp_1Index[12] == (uint8_t)Index) break; + case cJ1_JPFULLPOPU1m12: + if (Pjp->jp_1Index[11] == (uint8_t)Index) break; + case cJ1_JPFULLPOPU1m11: + if (Pjp->jp_1Index[10] == (uint8_t)Index) break; + case cJ1_JPFULLPOPU1m10: + if (Pjp->jp_1Index[9] == (uint8_t)Index) break; + case cJ1_JPFULLPOPU1m9: + if (Pjp->jp_1Index[8] == (uint8_t)Index) break; + case cJ1_JPFULLPOPU1m8: + if (Pjp->jp_1Index[7] == (uint8_t)Index) break; +#endif + case cJ1_JPFULLPOPU1m7: + if (Pjp->jp_1Index[6] == (uint8_t)Index) break; + case cJ1_JPFULLPOPU1m6: + if (Pjp->jp_1Index[5] == (uint8_t)Index) break; + case cJ1_JPFULLPOPU1m5: + if (Pjp->jp_1Index[4] == (uint8_t)Index) break; + case cJ1_JPFULLPOPU1m4: + if (Pjp->jp_1Index[3] == (uint8_t)Index) break; + case cJ1_JPFULLPOPU1m3: + if (Pjp->jp_1Index[2] == (uint8_t)Index) break; + case cJ1_JPFULLPOPU1m2: + if (Pjp->jp_1Index[1] == (uint8_t)Index) break; + case cJ1_JPFULLPOPU1m1: + if (Pjp->jp_1Index[0] == (uint8_t)Index) break; + + return(1); // found, not in exclusion list + +#endif // JUDY1 +#endif // notdef + +// **************************************************************************** +// JPIMMED*: +// +// Note that the contents of jp_DcdPopO are different for cJU_JPIMMED_*_01: + + case cJU_JPIMMED_1_01: + case cJU_JPIMMED_2_01: + case cJU_JPIMMED_3_01: +#ifdef JU_64BIT + case cJU_JPIMMED_4_01: + case cJU_JPIMMED_5_01: + case cJU_JPIMMED_6_01: + case cJU_JPIMMED_7_01: +#endif + if (JU_JPDCDPOP0(Pjp) != JU_TRIMTODCDSIZE(Index)) break; + + JUDY1CODE(return(1);) + JUDYLCODE(return((PPvoid_t) &(Pjp->jp_Addr));) // immediate value area. + + +// Macros to make code more readable and avoid dup errors + +#ifdef JUDY1 + +#define CHECKINDEXNATIVE(LEAF_T, PJP, IDX, INDEX) \ +if (((LEAF_T *)((PJP)->jp_1Index))[(IDX) - 1] == (LEAF_T)(INDEX)) \ + return(1) + +#define CHECKLEAFNONNAT(LFBTS, PJP, INDEX, IDX, COPY) \ +{ \ + Word_t i_ndex; \ + uint8_t *a_ddr; \ + a_ddr = (PJP)->jp_1Index + (((IDX) - 1) * (LFBTS)); \ + COPY(i_ndex, a_ddr); \ + if (i_ndex == JU_LEASTBYTES((INDEX), (LFBTS))) \ + return(1); \ +} +#endif + +#ifdef JUDYL + +#define CHECKINDEXNATIVE(LEAF_T, PJP, IDX, INDEX) \ +if (((LEAF_T *)((PJP)->jp_LIndex))[(IDX) - 1] == (LEAF_T)(INDEX)) \ + return((PPvoid_t)(P_JV((PJP)->jp_Addr) + (IDX) - 1)) + +#define CHECKLEAFNONNAT(LFBTS, PJP, INDEX, IDX, COPY) \ +{ \ + Word_t i_ndex; \ + uint8_t *a_ddr; \ + a_ddr = (PJP)->jp_LIndex + (((IDX) - 1) * (LFBTS)); \ + COPY(i_ndex, a_ddr); \ + if (i_ndex == JU_LEASTBYTES((INDEX), (LFBTS))) \ + return((PPvoid_t)(P_JV((PJP)->jp_Addr) + (IDX) - 1)); \ +} +#endif + +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_1_15: CHECKINDEXNATIVE(uint8_t, Pjp, 15, Index); + case cJ1_JPIMMED_1_14: CHECKINDEXNATIVE(uint8_t, Pjp, 14, Index); + case cJ1_JPIMMED_1_13: CHECKINDEXNATIVE(uint8_t, Pjp, 13, Index); + case cJ1_JPIMMED_1_12: CHECKINDEXNATIVE(uint8_t, Pjp, 12, Index); + case cJ1_JPIMMED_1_11: CHECKINDEXNATIVE(uint8_t, Pjp, 11, Index); + case cJ1_JPIMMED_1_10: CHECKINDEXNATIVE(uint8_t, Pjp, 10, Index); + case cJ1_JPIMMED_1_09: CHECKINDEXNATIVE(uint8_t, Pjp, 9, Index); + case cJ1_JPIMMED_1_08: CHECKINDEXNATIVE(uint8_t, Pjp, 8, Index); +#endif +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_1_07: CHECKINDEXNATIVE(uint8_t, Pjp, 7, Index); + case cJU_JPIMMED_1_06: CHECKINDEXNATIVE(uint8_t, Pjp, 6, Index); + case cJU_JPIMMED_1_05: CHECKINDEXNATIVE(uint8_t, Pjp, 5, Index); + case cJU_JPIMMED_1_04: CHECKINDEXNATIVE(uint8_t, Pjp, 4, Index); +#endif + case cJU_JPIMMED_1_03: CHECKINDEXNATIVE(uint8_t, Pjp, 3, Index); + case cJU_JPIMMED_1_02: CHECKINDEXNATIVE(uint8_t, Pjp, 2, Index); + CHECKINDEXNATIVE(uint8_t, Pjp, 1, Index); + break; + +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_2_07: CHECKINDEXNATIVE(uint16_t, Pjp, 7, Index); + case cJ1_JPIMMED_2_06: CHECKINDEXNATIVE(uint16_t, Pjp, 6, Index); + case cJ1_JPIMMED_2_05: CHECKINDEXNATIVE(uint16_t, Pjp, 5, Index); + case cJ1_JPIMMED_2_04: CHECKINDEXNATIVE(uint16_t, Pjp, 4, Index); +#endif +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_2_03: CHECKINDEXNATIVE(uint16_t, Pjp, 3, Index); + case cJU_JPIMMED_2_02: CHECKINDEXNATIVE(uint16_t, Pjp, 2, Index); + CHECKINDEXNATIVE(uint16_t, Pjp, 1, Index); + break; +#endif + +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_3_05: + CHECKLEAFNONNAT(3, Pjp, Index, 5, JU_COPY3_PINDEX_TO_LONG); + case cJ1_JPIMMED_3_04: + CHECKLEAFNONNAT(3, Pjp, Index, 4, JU_COPY3_PINDEX_TO_LONG); + case cJ1_JPIMMED_3_03: + CHECKLEAFNONNAT(3, Pjp, Index, 3, JU_COPY3_PINDEX_TO_LONG); +#endif +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_3_02: + CHECKLEAFNONNAT(3, Pjp, Index, 2, JU_COPY3_PINDEX_TO_LONG); + CHECKLEAFNONNAT(3, Pjp, Index, 1, JU_COPY3_PINDEX_TO_LONG); + break; +#endif + +#if (defined(JUDY1) && defined(JU_64BIT)) + + case cJ1_JPIMMED_4_03: CHECKINDEXNATIVE(uint32_t, Pjp, 3, Index); + case cJ1_JPIMMED_4_02: CHECKINDEXNATIVE(uint32_t, Pjp, 2, Index); + CHECKINDEXNATIVE(uint32_t, Pjp, 1, Index); + break; + + case cJ1_JPIMMED_5_03: + CHECKLEAFNONNAT(5, Pjp, Index, 3, JU_COPY5_PINDEX_TO_LONG); + case cJ1_JPIMMED_5_02: + CHECKLEAFNONNAT(5, Pjp, Index, 2, JU_COPY5_PINDEX_TO_LONG); + CHECKLEAFNONNAT(5, Pjp, Index, 1, JU_COPY5_PINDEX_TO_LONG); + break; + + case cJ1_JPIMMED_6_02: + CHECKLEAFNONNAT(6, Pjp, Index, 2, JU_COPY6_PINDEX_TO_LONG); + CHECKLEAFNONNAT(6, Pjp, Index, 1, JU_COPY6_PINDEX_TO_LONG); + break; + + case cJ1_JPIMMED_7_02: + CHECKLEAFNONNAT(7, Pjp, Index, 2, JU_COPY7_PINDEX_TO_LONG); + CHECKLEAFNONNAT(7, Pjp, Index, 1, JU_COPY7_PINDEX_TO_LONG); + break; + +#endif // (JUDY1 && JU_64BIT) + + +// **************************************************************************** +// INVALID JP TYPE: + + default: + +ReturnCorrupt: + +#ifdef JUDYGETINLINE // Pjpm is known to be non-null: + JU_SET_ERRNO_NONNULL(Pjpm, JU_ERRNO_CORRUPT); +#else + JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); +#endif + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + + } // switch on JP type + +JUDY1CODE(return(0);) +JUDYLCODE(return((PPvoid_t) NULL);) + +} // Judy1Test() / JudyLGet() + + +#ifndef JUDYGETINLINE // only compile the following function once: +#ifdef DEBUG + +// **************************************************************************** +// J U D Y C H E C K P O P +// +// Given a pointer to a Judy array, traverse the entire array to ensure +// population counts add up correctly. This can catch various coding errors. +// +// Since walking the entire tree is probably time-consuming, enable this +// function by setting env parameter $CHECKPOP to first call at which to start +// checking. Note: This function is called both from insert and delete code. +// +// Note: Even though this function does nothing useful for LEAFW leaves, its +// good practice to call it anyway, and cheap too. +// +// TBD: This is a debug-only check function similar to JudyCheckSorted(), but +// since it walks the tree it is Judy1/JudyL-specific and must live in a source +// file that is built both ways. +// +// TBD: As feared, enabling this code for every insert/delete makes Judy +// deathly slow, even for a small tree (10K indexes). Its not so bad if +// present but disabled (<1% slowdown measured). Still, should it be ifdefd +// other than DEBUG and/or called less often? +// +// TBD: Should this "population checker" be expanded to a comprehensive tree +// checker? It currently detects invalid LEAFW/JP types as well as inconsistent +// pop1s. Other possible checks, all based on essentially redundant data in +// the Judy tree, include: +// +// - Zero LS bits in jp_Addr field. +// +// - Correct Dcd bits. +// +// - Consistent JP types (always descending down the tree). +// +// - Sorted linear lists in BranchLs and leaves (using JudyCheckSorted(), but +// ideally that function is already called wherever appropriate after any +// linear list is modified). +// +// - Any others possible? + +#include // for getenv() and atol(). + +static Word_t JudyCheckPopSM(Pjp_t Pjp, Word_t RootPop1); + +FUNCTION void JudyCheckPop( + Pvoid_t PArray) +{ +static bool_t checked = FALSE; // already checked env parameter. +static bool_t enabled = FALSE; // env parameter set. +static bool_t active = FALSE; // calls >= callsmin. +static Word_t callsmin; // start point from $CHECKPOP. +static Word_t calls = 0; // times called so far. + + +// CHECK FOR EXTERNAL ENABLING: + + if (! checked) // only check once. + { + char * value; // for getenv(). + + checked = TRUE; + + if ((value = getenv("CHECKPOP")) == (char *) NULL) + { +#ifdef notdef +// Take this out because nightly tests want to be flavor-independent; its not +// OK to emit special non-error output from the debug flavor: + + (void) puts("JudyCheckPop() present but not enabled by " + "$CHECKPOP env parameter; set it to the number of " + "calls at which to begin checking"); +#endif + return; + } + + callsmin = atol(value); // note: non-number evaluates to 0. + enabled = TRUE; + + (void) printf("JudyCheckPop() present and enabled; callsmin = " + "%lu\n", callsmin); + } + else if (! enabled) return; + +// Previously or just now enabled; check if non-active or newly active: + + if (! active) + { + if (++calls < callsmin) return; + + (void) printf("JudyCheckPop() activated at call %lu\n", calls); + active = TRUE; + } + +// IGNORE LEAFW AT TOP OF TREE: + + if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW + return; + +// Check JPM pop0 against tree, recursively: +// +// Note: The traversal code in JudyCheckPopSM() is simplest when the case +// statement for each JP type compares the pop1 for that JP to its subtree (if +// any) after traversing the subtree (thats the hard part) and adding up +// actual pop1s. A top branchs JP in the JPM does not have room for a +// full-word pop1, so pass it in as a special case. + + { + Pjpm_t Pjpm = P_JPM(PArray); + (void) JudyCheckPopSM(&(Pjpm->jpm_JP), Pjpm->jpm_Pop0 + 1); + return; + } + +} // JudyCheckPop() + + +// **************************************************************************** +// J U D Y C H E C K P O P S M +// +// Recursive state machine (subroutine) for JudyCheckPop(): Given a Pjp (other +// than JPNULL*; caller should shortcut) and the root population for top-level +// branches, check the subtrees actual pop1 against its nominal value, and +// return the total pop1 for the subtree. +// +// Note: Expect RootPop1 to be ignored at lower levels, so pass down 0, which +// should pop an assertion if this expectation is violated. + +FUNCTION static Word_t JudyCheckPopSM( + Pjp_t Pjp, // top of subtree. + Word_t RootPop1) // whole array, for top-level branches only. +{ + Word_t pop1_jp; // nominal population from the JP. + Word_t pop1 = 0; // actual population at this level. + Word_t offset; // in a branch. + +#define PREPBRANCH(cPopBytes,Next) \ + pop1_jp = JU_JPBRANCH_POP0(Pjp, cPopBytes) + 1; goto Next + +assert((((Word_t) (Pjp->jp_Addr)) & 7) == 3); + switch (JU_JPTYPE(Pjp)) + { + + case cJU_JPBRANCH_L2: PREPBRANCH(2, BranchL); + case cJU_JPBRANCH_L3: PREPBRANCH(3, BranchL); +#ifdef JU_64BIT + case cJU_JPBRANCH_L4: PREPBRANCH(4, BranchL); + case cJU_JPBRANCH_L5: PREPBRANCH(5, BranchL); + case cJU_JPBRANCH_L6: PREPBRANCH(6, BranchL); + case cJU_JPBRANCH_L7: PREPBRANCH(7, BranchL); +#endif + case cJU_JPBRANCH_L: pop1_jp = RootPop1; + { + Pjbl_t Pjbl; +BranchL: + Pjbl = P_JBL(Pjp->jp_Addr); + + for (offset = 0; offset < (Pjbl->jbl_NumJPs); ++offset) + pop1 += JudyCheckPopSM((Pjbl->jbl_jp) + offset, 0); + + assert(pop1_jp == pop1); + return(pop1); + } + + case cJU_JPBRANCH_B2: PREPBRANCH(2, BranchB); + case cJU_JPBRANCH_B3: PREPBRANCH(3, BranchB); +#ifdef JU_64BIT + case cJU_JPBRANCH_B4: PREPBRANCH(4, BranchB); + case cJU_JPBRANCH_B5: PREPBRANCH(5, BranchB); + case cJU_JPBRANCH_B6: PREPBRANCH(6, BranchB); + case cJU_JPBRANCH_B7: PREPBRANCH(7, BranchB); +#endif + case cJU_JPBRANCH_B: pop1_jp = RootPop1; + { + Word_t subexp; + Word_t jpcount; + Pjbb_t Pjbb; +BranchB: + Pjbb = P_JBB(Pjp->jp_Addr); + + for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp) + { + jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp)); + + for (offset = 0; offset < jpcount; ++offset) + { + pop1 += JudyCheckPopSM(P_JP(JU_JBB_PJP(Pjbb, subexp)) + + offset, 0); + } + } + + assert(pop1_jp == pop1); + return(pop1); + } + + case cJU_JPBRANCH_U2: PREPBRANCH(2, BranchU); + case cJU_JPBRANCH_U3: PREPBRANCH(3, BranchU); +#ifdef JU_64BIT + case cJU_JPBRANCH_U4: PREPBRANCH(4, BranchU); + case cJU_JPBRANCH_U5: PREPBRANCH(5, BranchU); + case cJU_JPBRANCH_U6: PREPBRANCH(6, BranchU); + case cJU_JPBRANCH_U7: PREPBRANCH(7, BranchU); +#endif + case cJU_JPBRANCH_U: pop1_jp = RootPop1; + { + Pjbu_t Pjbu; +BranchU: + Pjbu = P_JBU(Pjp->jp_Addr); + + for (offset = 0; offset < cJU_BRANCHUNUMJPS; ++offset) + { + if (((Pjbu->jbu_jp[offset].jp_Type) >= cJU_JPNULL1) + && ((Pjbu->jbu_jp[offset].jp_Type) <= cJU_JPNULLMAX)) + { + continue; // skip null JP to save time. + } + + pop1 += JudyCheckPopSM((Pjbu->jbu_jp) + offset, 0); + } + + assert(pop1_jp == pop1); + return(pop1); + } + + +// -- Cases below here terminate and do not recurse. -- +// +// For all of these cases except JPLEAF_B1, there is no way to check the JPs +// pop1 against the object itself; just return the pop1; but for linear leaves, +// a bounds check is possible. + +#define CHECKLEAF(MaxPop1) \ + pop1 = JU_JPLEAF_POP0(Pjp) + 1; \ + assert(pop1 >= 1); \ + assert(pop1 <= (MaxPop1)); \ + return(pop1) + +#if (defined(JUDYL) || (! defined(JU_64BIT))) + case cJU_JPLEAF1: CHECKLEAF(cJU_LEAF1_MAXPOP1); +#endif + case cJU_JPLEAF2: CHECKLEAF(cJU_LEAF2_MAXPOP1); + case cJU_JPLEAF3: CHECKLEAF(cJU_LEAF3_MAXPOP1); +#ifdef JU_64BIT + case cJU_JPLEAF4: CHECKLEAF(cJU_LEAF4_MAXPOP1); + case cJU_JPLEAF5: CHECKLEAF(cJU_LEAF5_MAXPOP1); + case cJU_JPLEAF6: CHECKLEAF(cJU_LEAF6_MAXPOP1); + case cJU_JPLEAF7: CHECKLEAF(cJU_LEAF7_MAXPOP1); +#endif + + case cJU_JPLEAF_B1: + { + Word_t subexp; + Pjlb_t Pjlb; + + pop1_jp = JU_JPLEAF_POP0(Pjp) + 1; + + Pjlb = P_JLB(Pjp->jp_Addr); + + for (subexp = 0; subexp < cJU_NUMSUBEXPL; ++subexp) + pop1 += j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp)); + + assert(pop1_jp == pop1); + return(pop1); + } + + JUDY1CODE(case cJ1_JPFULLPOPU1: return(cJU_JPFULLPOPU1_POP0);) + + case cJU_JPIMMED_1_01: return(1); + case cJU_JPIMMED_2_01: return(1); + case cJU_JPIMMED_3_01: return(1); +#ifdef JU_64BIT + case cJU_JPIMMED_4_01: return(1); + case cJU_JPIMMED_5_01: return(1); + case cJU_JPIMMED_6_01: return(1); + case cJU_JPIMMED_7_01: return(1); +#endif + + case cJU_JPIMMED_1_02: return(2); + case cJU_JPIMMED_1_03: return(3); +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_1_04: return(4); + case cJU_JPIMMED_1_05: return(5); + case cJU_JPIMMED_1_06: return(6); + case cJU_JPIMMED_1_07: return(7); +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_1_08: return(8); + case cJ1_JPIMMED_1_09: return(9); + case cJ1_JPIMMED_1_10: return(10); + case cJ1_JPIMMED_1_11: return(11); + case cJ1_JPIMMED_1_12: return(12); + case cJ1_JPIMMED_1_13: return(13); + case cJ1_JPIMMED_1_14: return(14); + case cJ1_JPIMMED_1_15: return(15); +#endif + +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_2_02: return(2); + case cJU_JPIMMED_2_03: return(3); +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_2_04: return(4); + case cJ1_JPIMMED_2_05: return(5); + case cJ1_JPIMMED_2_06: return(6); + case cJ1_JPIMMED_2_07: return(7); +#endif + +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_3_02: return(2); +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_3_03: return(3); + case cJ1_JPIMMED_3_04: return(4); + case cJ1_JPIMMED_3_05: return(5); + + case cJ1_JPIMMED_4_02: return(2); + case cJ1_JPIMMED_4_03: return(3); + case cJ1_JPIMMED_5_02: return(2); + case cJ1_JPIMMED_5_03: return(3); + case cJ1_JPIMMED_6_02: return(2); + case cJ1_JPIMMED_7_02: return(2); +#endif + + } // switch (JU_JPTYPE(Pjp)) + + assert(FALSE); // unrecognized JP type => corruption. + return(0); // to make some compilers happy. + +} // JudyCheckPopSM() + +#endif // DEBUG +#endif // ! JUDYGETINLINE diff --git a/feeds/p4/libjudy/src/src/JudyCommon/JudyIns.c b/feeds/p4/libjudy/src/src/JudyCommon/JudyIns.c new file mode 100644 index 000000000..f96df4101 --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudyCommon/JudyIns.c @@ -0,0 +1,1873 @@ +// Copyright (C) 2000 - 2002 Hewlett-Packard Company +// +// This program is free software; you can redistribute it and/or modify it +// under the term of the GNU Lesser 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 Lesser General Public License +// for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// _________________ + +// @(#) $Revision: 4.116 $ $Source: /judy/src/JudyCommon/JudyIns.c $ +// +// Judy1Set() and JudyLIns() functions for Judy1 and JudyL. +// Compile with one of -DJUDY1 or -DJUDYL. +// +// TBD: Should some of the assertions here be converted to product code that +// returns JU_ERRNO_CORRUPT? + +#if (! (defined(JUDY1) || defined(JUDYL))) +#error: One of -DJUDY1 or -DJUDYL must be specified. +#endif + +#ifdef JUDY1 +#include "Judy1.h" +#else +#include "JudyL.h" +#endif + +#include "JudyPrivate1L.h" + +// Note: Call JudyCheckPop() even before "already inserted" returns, to catch +// population errors; see fix in 4.84: + +DBGCODE(extern void JudyCheckPop(Pvoid_t PArray);) +DBGCODE(extern void JudyCheckSorted(Pjll_t Pjll, Word_t Pop1, long IndexSize);) + +#ifdef TRACEJP +#include "JudyPrintJP.c" +#endif + + +// These are defined to generic values in JudyCommon/JudyPrivateTypes.h: +// +// TBD: These should be exported from a header file, but perhaps not, as they +// are only used here, and exported from Judy*Decascade, which is a separate +// file for profiling reasons (to prevent inlining), but which potentially +// could be merged with this file, either in SoftCM or at compile-time. + +#ifdef JUDY1 +extern int j__udy1CreateBranchB(Pjp_t, Pjp_t, uint8_t *, Word_t, Pvoid_t); +extern int j__udy1CreateBranchU(Pjp_t, Pvoid_t); + +#ifndef JU_64BIT +extern int j__udy1Cascade1(Pjp_t, Pvoid_t); +#endif +extern int j__udy1Cascade2(Pjp_t, Pvoid_t); +extern int j__udy1Cascade3(Pjp_t, Pvoid_t); +#ifdef JU_64BIT +extern int j__udy1Cascade4(Pjp_t, Pvoid_t); +extern int j__udy1Cascade5(Pjp_t, Pvoid_t); +extern int j__udy1Cascade6(Pjp_t, Pvoid_t); +extern int j__udy1Cascade7(Pjp_t, Pvoid_t); +#endif +extern int j__udy1CascadeL(Pjp_t, Pvoid_t); + +extern int j__udy1InsertBranch(Pjp_t Pjp, Word_t Index, Word_t Btype, Pjpm_t); + +#else // JUDYL + +extern int j__udyLCreateBranchB(Pjp_t, Pjp_t, uint8_t *, Word_t, Pvoid_t); +extern int j__udyLCreateBranchU(Pjp_t, Pvoid_t); + +extern int j__udyLCascade1(Pjp_t, Pvoid_t); +extern int j__udyLCascade2(Pjp_t, Pvoid_t); +extern int j__udyLCascade3(Pjp_t, Pvoid_t); +#ifdef JU_64BIT +extern int j__udyLCascade4(Pjp_t, Pvoid_t); +extern int j__udyLCascade5(Pjp_t, Pvoid_t); +extern int j__udyLCascade6(Pjp_t, Pvoid_t); +extern int j__udyLCascade7(Pjp_t, Pvoid_t); +#endif +extern int j__udyLCascadeL(Pjp_t, Pvoid_t); + +extern int j__udyLInsertBranch(Pjp_t Pjp, Word_t Index, Word_t Btype, Pjpm_t); +#endif + + +// **************************************************************************** +// MACROS FOR COMMON CODE: +// +// Check if Index is an outlier to (that is, not a member of) this expanse: +// +// An outlier is an Index in-the-expanse of the slot containing the pointer, +// but not-in-the-expanse of the "narrow" pointer in that slot. (This means +// the Dcd part of the Index differs from the equivalent part of jp_DcdPopO.) +// Therefore, the remedy is to put a cJU_JPBRANCH_L* between the narrow pointer +// and the object to which it points, and add the outlier Index as an Immediate +// in the cJU_JPBRANCH_L*. The "trick" is placing the cJU_JPBRANCH_L* at a +// Level that is as low as possible. This is determined by counting the digits +// in the existing narrow pointer that are the same as the digits in the new +// Index (see j__udyInsertBranch()). +// +// Note: At some high Levels, cJU_DCDMASK() is all zeros => dead code; assume +// the compiler optimizes this out. + +#define JU_CHECK_IF_OUTLIER(Pjp, Index, cLevel, Pjpm) \ + if (JU_DCDNOTMATCHINDEX(Index, Pjp, cLevel)) \ + return(j__udyInsertBranch(Pjp, Index, cLevel, Pjpm)) + +// Check if an Index is already in a leaf or immediate, after calling +// j__udySearchLeaf*() to set Offset: +// +// A non-negative Offset means the Index already exists, so return 0; otherwise +// complement Offset to proceed. + +#ifdef JUDY1 +#define Pjv ignore // placeholder. +#define JU_CHECK_IF_EXISTS(Offset,ignore,Pjpm) \ + { \ + if ((Offset) >= 0) return(0); \ + (Offset) = ~(Offset); \ + } +#else +// For JudyL, also set the value area pointer in the Pjpm: + +#define JU_CHECK_IF_EXISTS(Offset,Pjv,Pjpm) \ + { \ + if ((Offset) >= 0) \ + { \ + (Pjpm)->jpm_PValue = (Pjv) + (Offset); \ + return(0); \ + } \ + (Offset) = ~(Offset); \ + } +#endif + + +// **************************************************************************** +// __ J U D Y I N S W A L K +// +// Walk the Judy tree to do a set/insert. This is only called internally, and +// recursively. Unlike Judy1Test() and JudyLGet(), the extra time required for +// recursion should be negligible compared with the total. +// +// Return -1 for error (details in JPM), 0 for Index already inserted, 1 for +// new Index inserted. + +FUNCTION static int j__udyInsWalk( + Pjp_t Pjp, // current JP to descend. + Word_t Index, // to insert. + Pjpm_t Pjpm) // for returning info to top Level. +{ + uint8_t digit; // from Index, current offset into a branch. + jp_t newJP; // for creating a new Immed JP. + Word_t exppop1; // expanse (leaf) population. + int retcode; // return codes: -1, 0, 1. + +#ifdef SUBEXPCOUNTS +// Pointer to BranchB/U subexpanse counter: +// +// Note: Very important for performance reasons (avoids cache fills). + + PWord_t PSubExp = (PWord_t) NULL; +#endif + +ContinueInsWalk: // for modifying state without recursing. + +#ifdef TRACEJP + JudyPrintJP(Pjp, "i", __LINE__); +#endif + + switch (JU_JPTYPE(Pjp)) // entry: Pjp, Index. + { + + +// **************************************************************************** +// JPNULL*: +// +// Convert JP in place from current null type to cJU_JPIMMED_*_01 by +// calculating new JP type. + + case cJU_JPNULL1: + case cJU_JPNULL2: + case cJU_JPNULL3: +#ifdef JU_64BIT + case cJU_JPNULL4: + case cJU_JPNULL5: + case cJU_JPNULL6: + case cJU_JPNULL7: +#endif + assert((Pjp->jp_Addr) == 0); + JU_JPSETADT(Pjp, 0, Index, JU_JPTYPE(Pjp) + cJU_JPIMMED_1_01 - cJU_JPNULL1); +#ifdef JUDYL + // value area is first word of new Immed_01 JP: + Pjpm->jpm_PValue = (Pjv_t) (&(Pjp->jp_Addr)); +#endif + return(1); + + +// **************************************************************************** +// JPBRANCH_L*: +// +// If the new Index is not an outlier to the branchs expanse, and the branch +// should not be converted to uncompressed, extract the digit and record the +// Immediate type to create for a new Immed JP, before going to common code. +// +// Note: JU_CHECK_IF_OUTLIER() is a no-op for BranchB3[7] on 32[64]-bit. + +#define JU_BRANCH_OUTLIER(DIGIT,POP1,cLEVEL,PJP,INDEX,PJPM) \ + JU_CHECK_IF_OUTLIER(PJP, INDEX, cLEVEL, PJPM); \ + (DIGIT) = JU_DIGITATSTATE(INDEX, cLEVEL); \ + (POP1) = JU_JPBRANCH_POP0(PJP, cLEVEL) + + case cJU_JPBRANCH_L2: + JU_BRANCH_OUTLIER(digit, exppop1, 2, Pjp, Index, Pjpm); + goto JudyBranchL; + + case cJU_JPBRANCH_L3: + JU_BRANCH_OUTLIER(digit, exppop1, 3, Pjp, Index, Pjpm); + goto JudyBranchL; + +#ifdef JU_64BIT + case cJU_JPBRANCH_L4: + JU_BRANCH_OUTLIER(digit, exppop1, 4, Pjp, Index, Pjpm); + goto JudyBranchL; + + case cJU_JPBRANCH_L5: + JU_BRANCH_OUTLIER(digit, exppop1, 5, Pjp, Index, Pjpm); + goto JudyBranchL; + + case cJU_JPBRANCH_L6: + JU_BRANCH_OUTLIER(digit, exppop1, 6, Pjp, Index, Pjpm); + goto JudyBranchL; + + case cJU_JPBRANCH_L7: + JU_BRANCH_OUTLIER(digit, exppop1, 7, Pjp, Index, Pjpm); + goto JudyBranchL; +#endif + +// Similar to common code above, but no outlier check is needed, and the Immed +// type depends on the word size: + + case cJU_JPBRANCH_L: + { + Pjbl_t PjblRaw; // pointer to old linear branch. + Pjbl_t Pjbl; + Pjbu_t PjbuRaw; // pointer to new uncompressed branch. + Pjbu_t Pjbu; + Word_t numJPs; // number of JPs = populated expanses. + int offset; // in branch. + + digit = JU_DIGITATSTATE(Index, cJU_ROOTSTATE); + exppop1 = Pjpm->jpm_Pop0; + + // fall through: + +// COMMON CODE FOR LINEAR BRANCHES: +// +// Come here with digit and exppop1 already set. + +JudyBranchL: + PjblRaw = (Pjbl_t) (Pjp->jp_Addr); + Pjbl = P_JBL(PjblRaw); + +// If population under this branch greater than: + + if (exppop1 > JU_BRANCHL_MAX_POP) + goto ConvertBranchLtoU; + + numJPs = Pjbl->jbl_NumJPs; + + if ((numJPs == 0) || (numJPs > cJU_BRANCHLMAXJPS)) + { + JU_SET_ERRNO_NONNULL(Pjpm, JU_ERRNO_CORRUPT); + return(-1); + } + +// Search for a match to the digit: + + offset = j__udySearchLeaf1((Pjll_t) (Pjbl->jbl_Expanse), numJPs, + digit); + +// If Index is found, offset is into an array of 1..cJU_BRANCHLMAXJPS JPs: + + if (offset >= 0) + { + Pjp = (Pjbl->jbl_jp) + offset; // address of next JP. + break; // continue walk. + } + +// Expanse is missing (not populated) for the passed Index, so insert an Immed +// -- if theres room: + + if (numJPs < cJU_BRANCHLMAXJPS) + { + offset = ~offset; // insertion offset. + + JU_JPSETADT(&newJP, 0, Index, + JU_JPTYPE(Pjp) + cJU_JPIMMED_1_01-cJU_JPBRANCH_L2); + + JU_INSERTINPLACE(Pjbl->jbl_Expanse, numJPs, offset, digit); + JU_INSERTINPLACE(Pjbl->jbl_jp, numJPs, offset, newJP); + + DBGCODE(JudyCheckSorted((Pjll_t) (Pjbl->jbl_Expanse), + numJPs + 1, /* IndexSize = */ 1);) + ++(Pjbl->jbl_NumJPs); +#ifdef JUDYL + // value area is first word of new Immed 01 JP: + Pjpm->jpm_PValue = (Pjv_t) ((Pjbl->jbl_jp) + offset); +#endif + return(1); + } + + +// MAXED OUT LINEAR BRANCH, CONVERT TO A BITMAP BRANCH, THEN INSERT: +// +// Copy the linear branch to a bitmap branch. +// +// TBD: Consider renaming j__udyCreateBranchB() to j__udyConvertBranchLtoB(). + + assert((numJPs) <= cJU_BRANCHLMAXJPS); + + if (j__udyCreateBranchB(Pjp, Pjbl->jbl_jp, Pjbl->jbl_Expanse, + numJPs, Pjpm) == -1) + { + return(-1); + } + +// Convert jp_Type from linear branch to equivalent bitmap branch: + + Pjp->jp_Type += cJU_JPBRANCH_B - cJU_JPBRANCH_L; + + j__udyFreeJBL(PjblRaw, Pjpm); // free old BranchL. + +// Having changed branch types, now do the insert in the new branch type: + + goto ContinueInsWalk; + + +// OPPORTUNISTICALLY CONVERT FROM BRANCHL TO BRANCHU: +// +// Memory efficiency is no object because the branchs pop1 is large enough, so +// speed up array access. Come here with PjblRaw set. Note: This is goto +// code because the previous block used to fall through into it as well, but no +// longer. + +ConvertBranchLtoU: + +// Allocate memory for an uncompressed branch: + + if ((PjbuRaw = j__udyAllocJBU(Pjpm)) == (Pjbu_t) NULL) + return(-1); + Pjbu = P_JBU(PjbuRaw); + +// Set the proper NULL type for most of the uncompressed branchs JPs: + + JU_JPSETADT(&newJP, 0, 0, + JU_JPTYPE(Pjp) - cJU_JPBRANCH_L2 + cJU_JPNULL1); + +// Initialize: Pre-set uncompressed branch to mostly JPNULL*s: + + for (numJPs = 0; numJPs < cJU_BRANCHUNUMJPS; ++numJPs) + Pjbu->jbu_jp[numJPs] = newJP; + +// Copy JPs from linear branch to uncompressed branch: + + { +#ifdef SUBEXPCOUNTS + Word_t popmask = cJU_POP0MASK(JU_JPTYPE(Pjp)) + - cJU_JPBRANCH_L2 - 2; + + for (numJPs = 0; numJPs < cJU_NUMSUBEXPU; ++numJPs) + Pjbu->jbu_subPop1[numJPs] = 0; +#endif + for (numJPs = 0; numJPs < Pjbl->jbl_NumJPs; ++numJPs) + { + Pjp_t Pjp1 = &(Pjbl->jbl_jp[numJPs]); + offset = Pjbl->jbl_Expanse[numJPs]; + Pjbu->jbu_jp[offset] = *Pjp1; +#ifdef SUBEXPCOUNTS + Pjbu->jbu_subPop1[offset/cJU_NUMSUBEXPU] += + JU_JPDCDPOP0(Pjp1) & popmask + 1; +#endif + } + } + j__udyFreeJBL(PjblRaw, Pjpm); // free old BranchL. + +// Plug new values into parent JP: + + Pjp->jp_Addr = (Word_t) PjbuRaw; + Pjp->jp_Type += cJU_JPBRANCH_U - cJU_JPBRANCH_L; // to BranchU. + +// Save global population of last BranchU conversion: + + Pjpm->jpm_LastUPop0 = Pjpm->jpm_Pop0; + goto ContinueInsWalk; + + } // case cJU_JPBRANCH_L. + + +// **************************************************************************** +// JPBRANCH_B*: +// +// If the new Index is not an outlier to the branchs expanse, extract the +// digit and record the Immediate type to create for a new Immed JP, before +// going to common code. +// +// Note: JU_CHECK_IF_OUTLIER() is a no-op for BranchB3[7] on 32[64]-bit. + + case cJU_JPBRANCH_B2: + JU_BRANCH_OUTLIER(digit, exppop1, 2, Pjp, Index, Pjpm); + goto JudyBranchB; + + case cJU_JPBRANCH_B3: + JU_BRANCH_OUTLIER(digit, exppop1, 3, Pjp, Index, Pjpm); + goto JudyBranchB; + +#ifdef JU_64BIT + case cJU_JPBRANCH_B4: + JU_BRANCH_OUTLIER(digit, exppop1, 4, Pjp, Index, Pjpm); + goto JudyBranchB; + + case cJU_JPBRANCH_B5: + JU_BRANCH_OUTLIER(digit, exppop1, 5, Pjp, Index, Pjpm); + goto JudyBranchB; + + case cJU_JPBRANCH_B6: + JU_BRANCH_OUTLIER(digit, exppop1, 6, Pjp, Index, Pjpm); + goto JudyBranchB; + + case cJU_JPBRANCH_B7: + JU_BRANCH_OUTLIER(digit, exppop1, 7, Pjp, Index, Pjpm); + goto JudyBranchB; +#endif + + case cJU_JPBRANCH_B: + { + Pjbb_t Pjbb; // pointer to bitmap branch. + Pjbb_t PjbbRaw; // pointer to bitmap branch. + Pjp_t Pjp2Raw; // 1 of N arrays of JPs. + Pjp_t Pjp2; // 1 of N arrays of JPs. + Word_t subexp; // 1 of N subexpanses in bitmap. + BITMAPB_t bitmap; // for one subexpanse. + BITMAPB_t bitmask; // bit set for Indexs digit. + Word_t numJPs; // number of JPs = populated expanses. + int offset; // in bitmap branch. + +// Similar to common code above, but no outlier check is needed, and the Immed +// type depends on the word size: + + digit = JU_DIGITATSTATE(Index, cJU_ROOTSTATE); + exppop1 = Pjpm->jpm_Pop0; + + // fall through: + + +// COMMON CODE FOR BITMAP BRANCHES: +// +// Come here with digit and exppop1 already set. + +JudyBranchB: + +// If population increment is greater than.. (300): + + if ((Pjpm->jpm_Pop0 - Pjpm->jpm_LastUPop0) > JU_BTOU_POP_INCREMENT) + { + +// If total population of array is greater than.. (750): + + if (Pjpm->jpm_Pop0 > JU_BRANCHB_MAX_POP) + { + +// If population under the branch is greater than.. (135): + + if (exppop1 > JU_BRANCHB_MIN_POP) + { + if (j__udyCreateBranchU(Pjp, Pjpm) == -1) return(-1); + +// Save global population of last BranchU conversion: + + Pjpm->jpm_LastUPop0 = Pjpm->jpm_Pop0; + + goto ContinueInsWalk; + } + } + } + +// CONTINUE TO USE BRANCHB: +// +// Get pointer to bitmap branch (JBB): + + PjbbRaw = (Pjbb_t) (Pjp->jp_Addr); + Pjbb = P_JBB(PjbbRaw); + +// Form the Int32 offset, and Bit offset values: +// +// 8 bit Decode | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | +// |SubExpanse | Bit offset | +// +// Get the 1 of 8 expanses from digit, Bits 5..7 = 1 of 8, and get the 32-bit +// word that may have a bit set: + + subexp = digit / cJU_BITSPERSUBEXPB; + bitmap = JU_JBB_BITMAP(Pjbb, subexp); + + Pjp2Raw = JU_JBB_PJP(Pjbb, subexp); + Pjp2 = P_JP(Pjp2Raw); + +// Get the bit position that represents the desired expanse, and get the offset +// into the array of JPs for the JP that matches the bit. + + bitmask = JU_BITPOSMASKB(digit); + offset = j__udyCountBitsB(bitmap & (bitmask - 1)); + +// If JP is already in this expanse, get Pjp and continue the walk: + + if (bitmap & bitmask) + { +#ifdef SUBEXPCOUNTS + PSubExp = &(Pjbb->jbb_Counts[subexp]); // ptr to subexp counts. +#endif + Pjp = Pjp2 + offset; + break; // continue walk. + } + + +// ADD NEW EXPANSE FOR NEW INDEX: +// +// The new expanse always an cJU_JPIMMED_*_01 containing just the new Index, so +// finish setting up an Immed JP. + + JU_JPSETADT(&newJP, 0, Index, + JU_JPTYPE(Pjp) + cJU_JPIMMED_1_01-cJU_JPBRANCH_B2); + +// Get 1 of the 8 JP arrays and calculate number of JPs in subexpanse array: + + Pjp2Raw = JU_JBB_PJP(Pjbb, subexp); + Pjp2 = P_JP(Pjp2Raw); + numJPs = j__udyCountBitsB(bitmap); + +// Expand branch JP subarray in-place: + + if (JU_BRANCHBJPGROWINPLACE(numJPs)) + { + assert(numJPs > 0); + JU_INSERTINPLACE(Pjp2, numJPs, offset, newJP); +#ifdef JUDYL + // value area is first word of new Immed 01 JP: + Pjpm->jpm_PValue = (Pjv_t) (Pjp2 + offset); +#endif + } + +// No room, allocate a bigger bitmap branch JP subarray: + + else + { + Pjp_t PjpnewRaw; + Pjp_t Pjpnew; + + if ((PjpnewRaw = j__udyAllocJBBJP(numJPs + 1, Pjpm)) == 0) + return(-1); + Pjpnew = P_JP(PjpnewRaw); + +// If there was an old JP array, then copy it, insert the new Immed JP, and +// free the old array: + + if (numJPs) + { + JU_INSERTCOPY(Pjpnew, Pjp2, numJPs, offset, newJP); + j__udyFreeJBBJP(Pjp2Raw, numJPs, Pjpm); +#ifdef JUDYL + // value area is first word of new Immed 01 JP: + Pjpm->jpm_PValue = (Pjv_t) (Pjpnew + offset); +#endif + } + +// New JP subarray; point to cJU_JPIMMED_*_01 and place it: + + else + { + assert(JU_JBB_PJP(Pjbb, subexp) == (Pjp_t) NULL); + Pjp = Pjpnew; + *Pjp = newJP; // copy to new memory. +#ifdef JUDYL + // value area is first word of new Immed 01 JP: + Pjpm->jpm_PValue = (Pjv_t) (&(Pjp->jp_Addr)); +#endif + } + +// Place new JP subarray in BranchB: + + JU_JBB_PJP(Pjbb, subexp) = PjpnewRaw; + + } // else + +// Set the new Indexs bit: + + JU_JBB_BITMAP(Pjbb, subexp) |= bitmask; + + return(1); + + } // case + + +// **************************************************************************** +// JPBRANCH_U*: +// +// Just drop through the JP for the correct digit. If the JP turns out to be a +// JPNULL*, thats OK, the memory is already allocated, and the next walk +// simply places an Immed in it. +// +#ifdef SUBEXPCOUNTS +#define JU_GETSUBEXP(PSubExp,Pjbu,Digit) \ + (PSubExp) = &((Pjbu)->jbu_subPop1[(Digit) / cJU_NUMSUBEXPU]) +#else +#define JU_GETSUBEXP(PSubExp,Pjbu,Digit) // null. +#endif + +#define JU_JBU_PJP_SUBEXP(Pjp,PSubExp,Index,Level) \ + { \ + uint8_t digit = JU_DIGITATSTATE(Index, Level); \ + Pjbu_t P_jbu = P_JBU((Pjp)->jp_Addr); \ + (Pjp) = &(P_jbu->jbu_jp[digit]); \ + JU_GETSUBEXP(PSubExp, P_jbu, digit); \ + } + + case cJU_JPBRANCH_U2: + JU_CHECK_IF_OUTLIER(Pjp, Index, 2, Pjpm); + JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 2); + break; + +#ifdef JU_64BIT + case cJU_JPBRANCH_U3: + JU_CHECK_IF_OUTLIER(Pjp, Index, 3, Pjpm); + JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 3); + break; + + case cJU_JPBRANCH_U4: + JU_CHECK_IF_OUTLIER(Pjp, Index, 4, Pjpm); + JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 4); + break; + + case cJU_JPBRANCH_U5: + JU_CHECK_IF_OUTLIER(Pjp, Index, 5, Pjpm); + JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 5); + break; + + case cJU_JPBRANCH_U6: + JU_CHECK_IF_OUTLIER(Pjp, Index, 6, Pjpm); + JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 6); + break; + + case cJU_JPBRANCH_U7: + JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 7); +#else + case cJU_JPBRANCH_U3: + JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 3); +#endif + break; + + case cJU_JPBRANCH_U: + JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, cJU_ROOTSTATE); + break; + + +// **************************************************************************** +// JPLEAF*: +// +// COMMON CODE FRAGMENTS TO MINIMIZE REDUNDANCY BELOW: +// +// These are necessary to support performance by function and loop unrolling +// while avoiding huge amounts of nearly identical code. +// +// Prepare to handle a linear leaf: Check for an outlier; set pop1 and pointer +// to leaf: + +#ifdef JUDY1 +#define JU_LEAFVALUE(Pjv) // null. +#define JU_LEAFPREPVALUE(Pjv, ValueArea) // null. +#else +#define JU_LEAFVALUE(Pjv) Pjv_t Pjv +#define JU_LEAFPREPVALUE(Pjv, ValueArea) (Pjv) = ValueArea(Pleaf, exppop1) +#endif + +#define JU_LEAFPREP(cIS,Type,MaxPop1,ValueArea) \ + Pjll_t PjllRaw; \ + Type Pleaf; /* specific type */ \ + int offset; \ + JU_LEAFVALUE(Pjv); \ + \ + JU_CHECK_IF_OUTLIER(Pjp, Index, cIS, Pjpm); \ + \ + exppop1 = JU_JPLEAF_POP0(Pjp) + 1; \ + assert(exppop1 <= (MaxPop1)); \ + PjllRaw = (Pjll_t) (Pjp->jp_Addr); \ + Pleaf = (Type) P_JLL(PjllRaw); \ + JU_LEAFPREPVALUE(Pjv, ValueArea) + +// Add to, or grow, a linear leaf: Find Index position; if the Index is +// absent, if theres room in the leaf, insert the Index [and value of 0] in +// place, otherwise grow the leaf: +// +// Note: These insertions always take place with whole words, using +// JU_INSERTINPLACE() or JU_INSERTCOPY(). + +#ifdef JUDY1 +#define JU_LEAFGROWVALUEADD(Pjv,ExpPop1,Offset) // null. +#else +#define JU_LEAFGROWVALUEADD(Pjv,ExpPop1,Offset) \ + JU_INSERTINPLACE(Pjv, ExpPop1, Offset, 0); \ + Pjpm->jpm_PValue = (Pjv) + (Offset) +#endif + +#ifdef JUDY1 +#define JU_LEAFGROWVALUENEW(ValueArea,Pjv,ExpPop1,Offset) // null. +#else +#define JU_LEAFGROWVALUENEW(ValueArea,Pjv,ExpPop1,Offset) \ + { \ + Pjv_t Pjvnew = ValueArea(Pleafnew, (ExpPop1) + 1); \ + JU_INSERTCOPY(Pjvnew, Pjv, ExpPop1, Offset, 0); \ + Pjpm->jpm_PValue = (Pjvnew) + (Offset); \ + } +#endif + +#define JU_LEAFGROW(cIS,Type,MaxPop1,Search,ValueArea,GrowInPlace, \ + InsertInPlace,InsertCopy,Alloc,Free) \ + \ + offset = Search(Pleaf, exppop1, Index); \ + JU_CHECK_IF_EXISTS(offset, Pjv, Pjpm); \ + \ + if (GrowInPlace(exppop1)) /* add to current leaf */ \ + { \ + InsertInPlace(Pleaf, exppop1, offset, Index); \ + JU_LEAFGROWVALUEADD(Pjv, exppop1, offset); \ + DBGCODE(JudyCheckSorted((Pjll_t) Pleaf, exppop1 + 1, cIS);) \ + return(1); \ + } \ + \ + if (exppop1 < (MaxPop1)) /* grow to new leaf */ \ + { \ + Pjll_t PjllnewRaw; \ + Type Pleafnew; \ + if ((PjllnewRaw = Alloc(exppop1 + 1, Pjpm)) == 0) return(-1); \ + Pleafnew = (Type) P_JLL(PjllnewRaw); \ + InsertCopy(Pleafnew, Pleaf, exppop1, offset, Index); \ + JU_LEAFGROWVALUENEW(ValueArea, Pjv, exppop1, offset); \ + DBGCODE(JudyCheckSorted((Pjll_t) Pleafnew, exppop1 + 1, cIS);) \ + Free(PjllRaw, exppop1, Pjpm); \ + (Pjp->jp_Addr) = (Word_t) PjllnewRaw; \ + return(1); \ + } \ + assert(exppop1 == (MaxPop1)) + +// Handle linear leaf overflow (cascade): Splay or compress into smaller +// leaves: + +#define JU_LEAFCASCADE(MaxPop1,Cascade,Free) \ + if (Cascade(Pjp, Pjpm) == -1) return(-1); \ + Free(PjllRaw, MaxPop1, Pjpm); \ + goto ContinueInsWalk + +// Wrapper around all of the above: + +#define JU_LEAFSET(cIS,Type,MaxPop1,Search,GrowInPlace,InsertInPlace, \ + InsertCopy,Cascade,Alloc,Free,ValueArea) \ + { \ + JU_LEAFPREP(cIS,Type,MaxPop1,ValueArea); \ + JU_LEAFGROW(cIS,Type,MaxPop1,Search,ValueArea,GrowInPlace, \ + InsertInPlace,InsertCopy,Alloc,Free); \ + JU_LEAFCASCADE(MaxPop1,Cascade,Free); \ + } + +// END OF MACROS; LEAFL CASES START HERE: +// +// 64-bit Judy1 does not have 1-byte leaves: + +#if (defined(JUDYL) || (! defined(JU_64BIT))) + + case cJU_JPLEAF1: + + JU_LEAFSET(1, uint8_t *, cJU_LEAF1_MAXPOP1, j__udySearchLeaf1, + JU_LEAF1GROWINPLACE, JU_INSERTINPLACE, JU_INSERTCOPY, + j__udyCascade1, j__udyAllocJLL1, j__udyFreeJLL1, + JL_LEAF1VALUEAREA); + +#endif // (JUDYL || ! JU_64BIT) + + case cJU_JPLEAF2: + + JU_LEAFSET(2, uint16_t *, cJU_LEAF2_MAXPOP1, j__udySearchLeaf2, + JU_LEAF2GROWINPLACE, JU_INSERTINPLACE, JU_INSERTCOPY, + j__udyCascade2, j__udyAllocJLL2, j__udyFreeJLL2, + JL_LEAF2VALUEAREA); + + case cJU_JPLEAF3: + + JU_LEAFSET(3, uint8_t *, cJU_LEAF3_MAXPOP1, j__udySearchLeaf3, + JU_LEAF3GROWINPLACE, JU_INSERTINPLACE3, JU_INSERTCOPY3, + j__udyCascade3, j__udyAllocJLL3, j__udyFreeJLL3, + JL_LEAF3VALUEAREA); + +#ifdef JU_64BIT + case cJU_JPLEAF4: + + JU_LEAFSET(4, uint32_t *, cJU_LEAF4_MAXPOP1, j__udySearchLeaf4, + JU_LEAF4GROWINPLACE, JU_INSERTINPLACE, JU_INSERTCOPY, + j__udyCascade4, j__udyAllocJLL4, j__udyFreeJLL4, + JL_LEAF4VALUEAREA); + + case cJU_JPLEAF5: + + JU_LEAFSET(5, uint8_t *, cJU_LEAF5_MAXPOP1, j__udySearchLeaf5, + JU_LEAF5GROWINPLACE, JU_INSERTINPLACE5, JU_INSERTCOPY5, + j__udyCascade5, j__udyAllocJLL5, j__udyFreeJLL5, + JL_LEAF5VALUEAREA); + + case cJU_JPLEAF6: + + JU_LEAFSET(6, uint8_t *, cJU_LEAF6_MAXPOP1, j__udySearchLeaf6, + JU_LEAF6GROWINPLACE, JU_INSERTINPLACE6, JU_INSERTCOPY6, + j__udyCascade6, j__udyAllocJLL6, j__udyFreeJLL6, + JL_LEAF6VALUEAREA); + + case cJU_JPLEAF7: + + JU_LEAFSET(7, uint8_t *, cJU_LEAF7_MAXPOP1, j__udySearchLeaf7, + JU_LEAF7GROWINPLACE, JU_INSERTINPLACE7, JU_INSERTCOPY7, + j__udyCascade7, j__udyAllocJLL7, j__udyFreeJLL7, + JL_LEAF7VALUEAREA); +#endif // JU_64BIT + + +// **************************************************************************** +// JPLEAF_B1: +// +// 8 bit Decode | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | +// |SubExpanse | Bit offset | +// +// Note: For JudyL, values are stored in 8 subexpanses, each a linear word +// array of up to 32 values each. + + case cJU_JPLEAF_B1: + { +#ifdef JUDYL + Pjv_t PjvRaw; // pointer to value part of the leaf. + Pjv_t Pjv; // pointer to value part of the leaf. + Pjv_t PjvnewRaw; // new value area. + Pjv_t Pjvnew; // new value area. + Word_t subexp; // 1 of 8 subexpanses in bitmap. + Pjlb_t Pjlb; // pointer to bitmap part of the leaf. + BITMAPL_t bitmap; // for one subexpanse. + BITMAPL_t bitmask; // bit set for Indexs digit. + int offset; // of index in value area. +#endif + + JU_CHECK_IF_OUTLIER(Pjp, Index, 1, Pjpm); + +#ifdef JUDY1 + +// If Index (bit) is already set, return now: + + if (JU_BITMAPTESTL(P_JLB(Pjp->jp_Addr), Index)) return(0); + +// If bitmap is not full, set the new Indexs bit; otherwise convert to a Full: + + if ((exppop1 = JU_JPLEAF_POP0(Pjp) + 1) + < cJU_JPFULLPOPU1_POP0) + { + JU_BITMAPSETL(P_JLB(Pjp->jp_Addr), Index); + } + else + { + j__udyFreeJLB1((Pjlb_t) (Pjp->jp_Addr), Pjpm); // free LeafB1. + Pjp->jp_Type = cJ1_JPFULLPOPU1; + Pjp->jp_Addr = 0; + } + +#else // JUDYL + +// This is very different from Judy1 because of the need to return a value area +// even for an existing Index, or manage the value area for a new Index, and +// because JudyL has no Full type: + +// Get last byte to decode from Index, and pointer to bitmap leaf: + + digit = JU_DIGITATSTATE(Index, 1); + Pjlb = P_JLB(Pjp->jp_Addr); + +// Prepare additional values: + + subexp = digit / cJU_BITSPERSUBEXPL; // which subexpanse. + bitmap = JU_JLB_BITMAP(Pjlb, subexp); // subexps 32-bit map. + PjvRaw = JL_JLB_PVALUE(Pjlb, subexp); // corresponding values. + Pjv = P_JV(PjvRaw); // corresponding values. + bitmask = JU_BITPOSMASKL(digit); // mask for Index. + offset = j__udyCountBitsL(bitmap & (bitmask - 1)); // of Index. + +// If Index already exists, get value pointer and exit: + + if (bitmap & bitmask) + { + assert(Pjv); + Pjpm->jpm_PValue = Pjv + offset; // existing value. + return(0); + } + +// Get the total bits set = expanse population of Value area: + + exppop1 = j__udyCountBitsL(bitmap); + +// If the value area can grow in place, do it: + + if (JL_LEAFVGROWINPLACE(exppop1)) + { + JU_INSERTINPLACE(Pjv, exppop1, offset, 0); + JU_JLB_BITMAP(Pjlb, subexp) |= bitmask; // set Indexs bit. + Pjpm->jpm_PValue = Pjv + offset; // new value area. + return(1); + } + +// Increase size of value area: + + if ((PjvnewRaw = j__udyLAllocJV(exppop1 + 1, Pjpm)) + == (Pjv_t) NULL) return(-1); + Pjvnew = P_JV(PjvnewRaw); + + if (exppop1) // have existing value area. + { + assert(Pjv); + JU_INSERTCOPY(Pjvnew, Pjv, exppop1, offset, 0); + Pjpm->jpm_PValue = Pjvnew + offset; + j__udyLFreeJV(PjvRaw, exppop1, Pjpm); // free old values. + } + else // first index, new value area: + { + Pjpm->jpm_PValue = Pjvnew; + *(Pjpm->jpm_PValue) = 0; + } + +// Set bit for new Index and place new leaf value area in bitmap: + + JU_JLB_BITMAP(Pjlb, subexp) |= bitmask; + JL_JLB_PVALUE(Pjlb, subexp) = PjvnewRaw; + +#endif // JUDYL + + return(1); + + } // case + + +#ifdef JUDY1 +// **************************************************************************** +// JPFULLPOPU1: +// +// If Index is not an outlier, then by definition its already set. + + case cJ1_JPFULLPOPU1: + + JU_CHECK_IF_OUTLIER(Pjp, Index, 1, Pjpm); + return(0); +#endif + + +// **************************************************************************** +// JPIMMED*: +// +// This is some of the most complex code in Judy considering Judy1 versus JudyL +// and 32-bit versus 64-bit variations. The following comments attempt to make +// this clearer. +// +// Of the 2 words in a JP, for immediate indexes Judy1 can use 2 words - 1 byte +// = 7 [15] bytes, but JudyL can only use 1 word - 1 byte = 3 [7] bytes because +// the other word is needed for a value area or a pointer to a value area. +// +// For both Judy1 and JudyL, cJU_JPIMMED_*_01 indexes are in word 2; otherwise +// for Judy1 only, a list of 2 or more indexes starts in word 1. JudyL keeps +// the list in word 2 because word 1 is a pointer (to a LeafV, that is, a leaf +// containing only values). Furthermore, cJU_JPIMMED_*_01 indexes are stored +// all-but-first-byte in jp_DcdPopO, not just the Index Sizes bytes. +// +// TBD: This can be confusing because Doug didnt use data structures for it. +// Instead he often directly accesses Pjp for the first word and jp_DcdPopO for +// the second word. It would be nice to use data structs, starting with +// jp_1Index and jp_LIndex where possible. +// +// Maximum Immed JP types for Judy1/JudyL, depending on Index Size (cIS): +// +// 32-bit 64-bit +// +// bytes: 7/ 3 15/ 7 (Judy1/JudyL) +// +// cIS +// 1_ 07/03 15/07 (as in: cJ1_JPIMMED_1_07) +// 2_ 03/01 07/03 +// 3_ 02/01 05/02 +// 4_ 03/01 +// 5_ 03/01 +// 6_ 02/01 +// 7_ 02/01 +// +// State transitions while inserting an Index, matching the above table: +// (Yes, this is very terse... Study it and it will make sense.) +// (Note, parts of this diagram are repeated below for quick reference.) +// +// +-- reformat JP here for Judy1 only, from word-2 to word-1 +// | +// | JUDY1 || JU_64BIT JUDY1 && JU_64BIT +// V +// 1_01 => 1_02 => 1_03 => [ 1_04 => ... => 1_07 => [ 1_08..15 => ]] Leaf1 (*) +// 2_01 => [ 2_02 => 2_03 => [ 2_04..07 => ]] Leaf2 +// 3_01 => [ 3_02 => [ 3_03..05 => ]] Leaf3 +// JU_64BIT only: +// 4_01 => [[ 4_02..03 => ]] Leaf4 +// 5_01 => [[ 5_02..03 => ]] Leaf5 +// 6_01 => [[ 6_02 => ]] Leaf6 +// 7_01 => [[ 7_02 => ]] Leaf7 +// +// (*) For Judy1 & 64-bit, go directly from cJU_JPIMMED_1_15 to a LeafB1; skip +// Leaf1, as described in Judy1.h regarding cJ1_JPLEAF1. + + +// COMMON CODE FRAGMENTS TO MINIMIZE REDUNDANCY BELOW: +// +// These are necessary to support performance by function and loop unrolling +// while avoiding huge amounts of nearly identical code. +// +// The differences between Judy1 and JudyL with respect to value area handling +// are just too large for completely common code between them... Oh well, some +// big ifdefs follow. However, even in the following ifdefd code, use cJU_*, +// JU_*, and Judy*() instead of cJ1_* / cJL_*, J1_* / JL_*, and +// Judy1*()/JudyL*(), for minimum diffs. +// +// Handle growth of cJU_JPIMMED_*_01 to cJU_JPIMMED_*_02, for an even or odd +// Index Size (cIS), given oldIndex, Index, and Pjll in the context: +// +// Put oldIndex and Index in their proper order. For odd indexes, must copy +// bytes. + +#ifdef JUDY1 + +#define JU_IMMSET_01_COPY_EVEN(ignore1,ignore2) \ + if (oldIndex < Index) { Pjll[0] = oldIndex; Pjll[1] = Index; } \ + else { Pjll[0] = Index; Pjll[1] = oldIndex; } + +#define JU_IMMSET_01_COPY_ODD(cIS,CopyWord) \ + if (oldIndex < Index) \ + { \ + CopyWord(Pjll + 0, oldIndex); \ + CopyWord(Pjll + (cIS), Index); \ + } \ + else \ + { \ + CopyWord(Pjll + 0, Index); \ + CopyWord(Pjll + (cIS), oldIndex); \ + } + +// The "real" *_01 Copy macro: +// +// Trim the high byte off Index, look for a match with the old Index, and if +// none, insert the new Index in the leaf in the correct place, given Pjp and +// Index in the context. +// +// Note: A single immediate index lives in the jp_DcdPopO field, but two or +// more reside starting at Pjp->jp_1Index. + +#define JU_IMMSET_01_COPY(cIS,LeafType,NewJPType,Copy,CopyWord) \ + { \ + LeafType Pjll; \ + Word_t oldIndex = JU_JPDCDPOP0(Pjp); \ + \ + Index = JU_TRIMTODCDSIZE(Index); \ + if (oldIndex == Index) return(0); \ + \ + Pjll = (LeafType) (Pjp->jp_1Index); \ + Copy(cIS,CopyWord); \ + DBGCODE(JudyCheckSorted(Pjll, 2, cIS);) \ + \ + Pjp->jp_Type = (NewJPType); \ + return(1); \ + } + +#else // JUDYL + +// Variations to also handle value areas; see comments above: +// +// For JudyL, Pjv (start of value area) and oldValue are also in the context; +// leave Pjv set to the value area for Index. + +#define JU_IMMSET_01_COPY_EVEN(cIS,CopyWord) \ + if (oldIndex < Index) \ + { \ + Pjll[0] = oldIndex; \ + Pjv [0] = oldValue; \ + Pjll[1] = Index; \ + ++Pjv; \ + } \ + else \ + { \ + Pjll[0] = Index; \ + Pjll[1] = oldIndex; \ + Pjv [1] = oldValue; \ + } + +#define JU_IMMSET_01_COPY_ODD(cIS,CopyWord) \ + if (oldIndex < Index) \ + { \ + CopyWord(Pjll + 0, oldIndex); \ + CopyWord(Pjll + (cIS), Index); \ + Pjv[0] = oldValue; \ + ++Pjv; \ + } \ + else \ + { \ + CopyWord(Pjll + 0, Index); \ + CopyWord(Pjll + (cIS), oldIndex); \ + Pjv[1] = oldValue; \ + } + +// The old value area is in the first word (*Pjp), and Pjv and Pjpm are also in +// the context. Also, unlike Judy1, indexes remain in word 2 (jp_LIndex), +// meaning insert-in-place rather than copy. +// +// Return jpm_PValue pointing to Indexs value area. If Index is new, allocate +// a 2-value-leaf and attach it to the JP. + +#define JU_IMMSET_01_COPY(cIS,LeafType,NewJPType,Copy,CopyWord) \ + { \ + LeafType Pjll; \ + Word_t oldIndex = JU_JPDCDPOP0(Pjp); \ + Word_t oldValue; \ + Pjv_t PjvRaw; \ + Pjv_t Pjv; \ + \ + Index = JU_TRIMTODCDSIZE(Index); \ + \ + if (oldIndex == Index) \ + { \ + Pjpm->jpm_PValue = (Pjv_t) Pjp; \ + return(0); \ + } \ + \ + if ((PjvRaw = j__udyLAllocJV(2, Pjpm)) == (Pjv_t) NULL) \ + return(-1); \ + Pjv = P_JV(PjvRaw); \ + \ + oldValue = Pjp->jp_Addr; \ + (Pjp->jp_Addr) = (Word_t) PjvRaw; \ + Pjll = (LeafType) (Pjp->jp_LIndex); \ + \ + Copy(cIS,CopyWord); \ + DBGCODE(JudyCheckSorted(Pjll, 2, cIS);) \ + \ + Pjp->jp_Type = (NewJPType); \ + *Pjv = 0; \ + Pjpm->jpm_PValue = Pjv; \ + return(1); \ + } + +// The following is a unique mix of JU_IMMSET_01() and JU_IMMSETCASCADE() for +// going from cJU_JPIMMED_*_01 directly to a cJU_JPLEAF* for JudyL: +// +// If Index is not already set, allocate a leaf, copy the old and new indexes +// into it, clear and return the new value area, and modify the current JP. +// Note that jp_DcdPop is set to a pop0 of 0 for now, and incremented later. + + +#define JU_IMMSET_01_CASCADE(cIS,LeafType,NewJPType,ValueArea, \ + Copy,CopyWord,Alloc) \ + { \ + Word_t D_P0; \ + LeafType PjllRaw; \ + LeafType Pjll; \ + Word_t oldIndex = JU_JPDCDPOP0(Pjp); \ + Word_t oldValue; \ + Pjv_t Pjv; \ + \ + Index = JU_TRIMTODCDSIZE(Index); \ + \ + if (oldIndex == Index) \ + { \ + Pjpm->jpm_PValue = (Pjv_t) (&(Pjp->jp_Addr)); \ + return(0); \ + } \ + \ + if ((PjllRaw = (LeafType) Alloc(2, Pjpm)) == (LeafType) NULL) \ + return(-1); \ + Pjll = (LeafType) P_JLL(PjllRaw); \ + Pjv = ValueArea(Pjll, 2); \ + \ + oldValue = Pjp->jp_Addr; \ + \ + Copy(cIS,CopyWord); \ + DBGCODE(JudyCheckSorted(Pjll, 2, cIS);) \ + \ + *Pjv = 0; \ + Pjpm->jpm_PValue = Pjv; \ + D_P0 = Index & cJU_DCDMASK(cIS); /* pop0 = 0 */ \ + JU_JPSETADT(Pjp, (Word_t)PjllRaw, D_P0, NewJPType); \ + \ + return(1); \ + } + +#endif // JUDYL + +// Handle growth of cJU_JPIMMED_*_[02..15]: + +#ifdef JUDY1 + +// Insert an Index into an immediate JP that has room for more, if the Index is +// not already present; given Pjp, Index, exppop1, Pjv, and Pjpm in the +// context: +// +// Note: Use this only when the JP format doesnt change, that is, going from +// cJU_JPIMMED_X_0Y to cJU_JPIMMED_X_0Z, where X >= 2 and Y+1 = Z. +// +// Note: Incrementing jp_Type is how to increase the Index population. + +#define JU_IMMSETINPLACE(cIS,LeafType,BaseJPType_02,Search,InsertInPlace) \ + { \ + LeafType Pjll; \ + int offset; \ + \ + exppop1 = JU_JPTYPE(Pjp) - (BaseJPType_02) + 2; \ + offset = Search((Pjll_t) (Pjp->jp_1Index), exppop1, Index); \ + \ + JU_CHECK_IF_EXISTS(offset, ignore, Pjpm); \ + \ + Pjll = (LeafType) (Pjp->jp_1Index); \ + InsertInPlace(Pjll, exppop1, offset, Index); \ + DBGCODE(JudyCheckSorted(Pjll, exppop1 + 1, cIS);) \ + ++(Pjp->jp_Type); \ + return(1); \ + } + +// Insert an Index into an immediate JP that has no room for more: +// +// If the Index is not already present, do a cascade (to a leaf); given Pjp, +// Index, Pjv, and Pjpm in the context. + + +#define JU_IMMSETCASCADE(cIS,OldPop1,LeafType,NewJPType, \ + ignore,Search,InsertCopy,Alloc) \ + { \ + Word_t D_P0; \ + Pjll_t PjllRaw; \ + Pjll_t Pjll; \ + int offset; \ + \ + offset = Search((Pjll_t) (Pjp->jp_1Index), (OldPop1), Index); \ + JU_CHECK_IF_EXISTS(offset, ignore, Pjpm); \ + \ + if ((PjllRaw = Alloc((OldPop1) + 1, Pjpm)) == 0) return(-1); \ + Pjll = P_JLL(PjllRaw); \ + \ + InsertCopy((LeafType) Pjll, (LeafType) (Pjp->jp_1Index), \ + OldPop1, offset, Index); \ + DBGCODE(JudyCheckSorted(Pjll, (OldPop1) + 1, cIS);) \ + \ + D_P0 = (Index & cJU_DCDMASK(cIS)) + (OldPop1) - 1; \ + JU_JPSETADT(Pjp, (Word_t)PjllRaw, D_P0, NewJPType); \ + return(1); \ + } + +#else // JUDYL + +// Variations to also handle value areas; see comments above: +// +// For JudyL, Pjv (start of value area) is also in the context. +// +// TBD: This code makes a true but weak assumption that a JudyL 32-bit 2-index +// value area must be copied to a new 3-index value area. AND it doesnt know +// anything about JudyL 64-bit cases (cJU_JPIMMED_1_0[3-7] only) where the +// value area can grow in place! However, this should not break it, just slow +// it down. + +#define JU_IMMSETINPLACE(cIS,LeafType,BaseJPType_02,Search,InsertInPlace) \ + { \ + LeafType Pleaf; \ + int offset; \ + Pjv_t PjvRaw; \ + Pjv_t Pjv; \ + Pjv_t PjvnewRaw; \ + Pjv_t Pjvnew; \ + \ + exppop1 = JU_JPTYPE(Pjp) - (BaseJPType_02) + 2; \ + offset = Search((Pjll_t) (Pjp->jp_LIndex), exppop1, Index); \ + PjvRaw = (Pjv_t) (Pjp->jp_Addr); \ + Pjv = P_JV(PjvRaw); \ + \ + JU_CHECK_IF_EXISTS(offset, Pjv, Pjpm); \ + \ + if ((PjvnewRaw = j__udyLAllocJV(exppop1 + 1, Pjpm)) \ + == (Pjv_t) NULL) return(-1); \ + Pjvnew = P_JV(PjvnewRaw); \ + \ + Pleaf = (LeafType) (Pjp->jp_LIndex); \ + \ + InsertInPlace(Pleaf, exppop1, offset, Index); \ + /* see TBD above about this: */ \ + JU_INSERTCOPY(Pjvnew, Pjv, exppop1, offset, 0); \ + DBGCODE(JudyCheckSorted(Pleaf, exppop1 + 1, cIS);) \ + j__udyLFreeJV(PjvRaw, exppop1, Pjpm); \ + Pjp->jp_Addr = (Word_t) PjvnewRaw; \ + Pjpm->jpm_PValue = Pjvnew + offset; \ + \ + ++(Pjp->jp_Type); \ + return(1); \ + } + +#define JU_IMMSETCASCADE(cIS,OldPop1,LeafType,NewJPType, \ + ValueArea,Search,InsertCopy,Alloc) \ + { \ + Word_t D_P0; \ + Pjll_t PjllRaw; \ + Pjll_t Pjll; \ + int offset; \ + Pjv_t PjvRaw; \ + Pjv_t Pjv; \ + Pjv_t Pjvnew; \ + \ + PjvRaw = (Pjv_t) (Pjp->jp_Addr); \ + Pjv = P_JV(PjvRaw); \ + offset = Search((Pjll_t) (Pjp->jp_LIndex), (OldPop1), Index); \ + JU_CHECK_IF_EXISTS(offset, Pjv, Pjpm); \ + \ + if ((PjllRaw = Alloc((OldPop1) + 1, Pjpm)) == 0) \ + return(-1); \ + Pjll = P_JLL(PjllRaw); \ + InsertCopy((LeafType) Pjll, (LeafType) (Pjp->jp_LIndex), \ + OldPop1, offset, Index); \ + DBGCODE(JudyCheckSorted(Pjll, (OldPop1) + 1, cIS);) \ + \ + Pjvnew = ValueArea(Pjll, (OldPop1) + 1); \ + JU_INSERTCOPY(Pjvnew, Pjv, OldPop1, offset, 0); \ + j__udyLFreeJV(PjvRaw, (OldPop1), Pjpm); \ + Pjpm->jpm_PValue = Pjvnew + offset; \ + \ + D_P0 = (Index & cJU_DCDMASK(cIS)) + (OldPop1) - 1; \ + JU_JPSETADT(Pjp, (Word_t)PjllRaw, D_P0, NewJPType); \ + return(1); \ + } + +#endif // JUDYL + +// Common convenience/shorthand wrappers around JU_IMMSET_01_COPY() for +// even/odd index sizes: + +#define JU_IMMSET_01( cIS, LeafType, NewJPType) \ + JU_IMMSET_01_COPY(cIS, LeafType, NewJPType, JU_IMMSET_01_COPY_EVEN, \ + ignore) + +#define JU_IMMSET_01_ODD( cIS, NewJPType, CopyWord) \ + JU_IMMSET_01_COPY(cIS, uint8_t *, NewJPType, JU_IMMSET_01_COPY_ODD, \ + CopyWord) + + +// END OF MACROS; IMMED CASES START HERE: + +// cJU_JPIMMED_*_01 cases: +// +// 1_01 always leads to 1_02: +// +// (1_01 => 1_02 => 1_03 => [ 1_04 => ... => 1_07 => [ 1_08..15 => ]] LeafL) + + case cJU_JPIMMED_1_01: JU_IMMSET_01(1, uint8_t *, cJU_JPIMMED_1_02); + +// 2_01 leads to 2_02, and 3_01 leads to 3_02, except for JudyL 32-bit, where +// they lead to a leaf: +// +// (2_01 => [ 2_02 => 2_03 => [ 2_04..07 => ]] LeafL) +// (3_01 => [ 3_02 => [ 3_03..05 => ]] LeafL) + +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_2_01: JU_IMMSET_01(2, uint16_t *, cJU_JPIMMED_2_02); + case cJU_JPIMMED_3_01: JU_IMMSET_01_ODD (3, cJU_JPIMMED_3_02, + JU_COPY3_LONG_TO_PINDEX); +#else + case cJU_JPIMMED_2_01: + JU_IMMSET_01_CASCADE(2, uint16_t *, cJU_JPLEAF2, JL_LEAF2VALUEAREA, + JU_IMMSET_01_COPY_EVEN, ignore, + j__udyAllocJLL2); + case cJU_JPIMMED_3_01: + JU_IMMSET_01_CASCADE(3, uint8_t *, cJU_JPLEAF3, JL_LEAF3VALUEAREA, + JU_IMMSET_01_COPY_ODD, + JU_COPY3_LONG_TO_PINDEX, j__udyAllocJLL3); +#endif + +#ifdef JU_64BIT + +// [4-7]_01 lead to [4-7]_02 for Judy1, and to leaves for JudyL: +// +// (4_01 => [[ 4_02..03 => ]] LeafL) +// (5_01 => [[ 5_02..03 => ]] LeafL) +// (6_01 => [[ 6_02 => ]] LeafL) +// (7_01 => [[ 7_02 => ]] LeafL) + +#ifdef JUDY1 + case cJU_JPIMMED_4_01: JU_IMMSET_01(4, uint32_t *, cJ1_JPIMMED_4_02); + case cJU_JPIMMED_5_01: JU_IMMSET_01_ODD(5, cJ1_JPIMMED_5_02, + JU_COPY5_LONG_TO_PINDEX); + case cJU_JPIMMED_6_01: JU_IMMSET_01_ODD(6, cJ1_JPIMMED_6_02, + JU_COPY6_LONG_TO_PINDEX); + case cJU_JPIMMED_7_01: JU_IMMSET_01_ODD(7, cJ1_JPIMMED_7_02, + JU_COPY7_LONG_TO_PINDEX); +#else // JUDYL + case cJU_JPIMMED_4_01: + JU_IMMSET_01_CASCADE(4, uint32_t *, cJU_JPLEAF4, JL_LEAF4VALUEAREA, + JU_IMMSET_01_COPY_EVEN, ignore, + j__udyAllocJLL4); + case cJU_JPIMMED_5_01: + JU_IMMSET_01_CASCADE(5, uint8_t *, cJU_JPLEAF5, JL_LEAF5VALUEAREA, + JU_IMMSET_01_COPY_ODD, + JU_COPY5_LONG_TO_PINDEX, j__udyAllocJLL5); + case cJU_JPIMMED_6_01: + JU_IMMSET_01_CASCADE(6, uint8_t *, cJU_JPLEAF6, JL_LEAF6VALUEAREA, + JU_IMMSET_01_COPY_ODD, + JU_COPY6_LONG_TO_PINDEX, j__udyAllocJLL6); + case cJU_JPIMMED_7_01: + JU_IMMSET_01_CASCADE(7, uint8_t *, cJU_JPLEAF7, JL_LEAF7VALUEAREA, + JU_IMMSET_01_COPY_ODD, + JU_COPY7_LONG_TO_PINDEX, j__udyAllocJLL7); +#endif // JUDYL +#endif // JU_64BIT + +// cJU_JPIMMED_1_* cases that can grow in place: +// +// (1_01 => 1_02 => 1_03 => [ 1_04 => ... => 1_07 => [ 1_08..15 => ]] LeafL) + + case cJU_JPIMMED_1_02: +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_1_03: + case cJU_JPIMMED_1_04: + case cJU_JPIMMED_1_05: + case cJU_JPIMMED_1_06: +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJU_JPIMMED_1_07: + case cJ1_JPIMMED_1_08: + case cJ1_JPIMMED_1_09: + case cJ1_JPIMMED_1_10: + case cJ1_JPIMMED_1_11: + case cJ1_JPIMMED_1_12: + case cJ1_JPIMMED_1_13: + case cJ1_JPIMMED_1_14: +#endif + JU_IMMSETINPLACE(1, uint8_t *, cJU_JPIMMED_1_02, j__udySearchLeaf1, + JU_INSERTINPLACE); + +// cJU_JPIMMED_1_* cases that must cascade: +// +// (1_01 => 1_02 => 1_03 => [ 1_04 => ... => 1_07 => [ 1_08..15 => ]] LeafL) + +#if (defined(JUDYL) && (! defined(JU_64BIT))) + case cJU_JPIMMED_1_03: + JU_IMMSETCASCADE(1, 3, uint8_t *, cJU_JPLEAF1, JL_LEAF1VALUEAREA, + j__udySearchLeaf1, JU_INSERTCOPY, + j__udyAllocJLL1); +#endif +#if (defined(JUDY1) && (! defined(JU_64BIT))) + case cJU_JPIMMED_1_07: + JU_IMMSETCASCADE(1, 7, uint8_t *, cJU_JPLEAF1, ignore, + j__udySearchLeaf1, JU_INSERTCOPY, + j__udyAllocJLL1); + +#endif +#if (defined(JUDYL) && defined(JU_64BIT)) + case cJU_JPIMMED_1_07: + JU_IMMSETCASCADE(1, 7, uint8_t *, cJU_JPLEAF1, JL_LEAF1VALUEAREA, + j__udySearchLeaf1, JU_INSERTCOPY, + j__udyAllocJLL1); + +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) +// Special case, as described above, go directly from Immed to LeafB1: + + case cJ1_JPIMMED_1_15: + { + Word_t DcdP0; + int offset; + Pjlb_t PjlbRaw; + Pjlb_t Pjlb; + + offset = j__udySearchLeaf1((Pjll_t) Pjp->jp_1Index, 15, Index); + + JU_CHECK_IF_EXISTS(offset, ignore, Pjpm); + +// Create a bitmap leaf (special case for Judy1 64-bit only, see usage): Set +// new Index in bitmap, copy an Immed1_15 to the bitmap, and set the parent JP +// EXCEPT jp_DcdPopO, leaving any followup to the caller: + + if ((PjlbRaw = j__udyAllocJLB1(Pjpm)) == (Pjlb_t) NULL) + return(-1); + Pjlb = P_JLB(PjlbRaw); + + JU_BITMAPSETL(Pjlb, Index); + + for (offset = 0; offset < 15; ++offset) + JU_BITMAPSETL(Pjlb, Pjp->jp_1Index[offset]); + +// Set jp_DcdPopO including the current pop0; incremented later: + DcdP0 = (Index & cJU_DCDMASK(1)) + 15 - 1; + JU_JPSETADT(Pjp, (Word_t)PjlbRaw, DcdP0, cJU_JPLEAF_B1); + + return(1); + } +#endif + +// cJU_JPIMMED_[2..7]_[02..15] cases that grow in place or cascade: +// +// (2_01 => [ 2_02 => 2_03 => [ 2_04..07 => ]] LeafL) + +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_2_02: +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJU_JPIMMED_2_03: + case cJ1_JPIMMED_2_04: + case cJ1_JPIMMED_2_05: + case cJ1_JPIMMED_2_06: +#endif +#if (defined(JUDY1) || defined(JU_64BIT)) + JU_IMMSETINPLACE(2, uint16_t *, cJU_JPIMMED_2_02, j__udySearchLeaf2, + JU_INSERTINPLACE); +#endif + +#undef OLDPOP1 +#if ((defined(JUDY1) && (! defined(JU_64BIT))) || (defined(JUDYL) && defined(JU_64BIT))) + case cJU_JPIMMED_2_03: +#define OLDPOP1 3 +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_2_07: +#define OLDPOP1 7 +#endif +#if (defined(JUDY1) || defined(JU_64BIT)) + JU_IMMSETCASCADE(2, OLDPOP1, uint16_t *, cJU_JPLEAF2, + JL_LEAF2VALUEAREA, j__udySearchLeaf2, + JU_INSERTCOPY, j__udyAllocJLL2); +#endif + +// (3_01 => [ 3_02 => [ 3_03..05 => ]] LeafL) + +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJU_JPIMMED_3_02: + case cJ1_JPIMMED_3_03: + case cJ1_JPIMMED_3_04: + + JU_IMMSETINPLACE(3, uint8_t *, cJU_JPIMMED_3_02, j__udySearchLeaf3, + JU_INSERTINPLACE3); +#endif + +#undef OLDPOP1 +#if ((defined(JUDY1) && (! defined(JU_64BIT))) || (defined(JUDYL) && defined(JU_64BIT))) + case cJU_JPIMMED_3_02: +#define OLDPOP1 2 +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_3_05: +#define OLDPOP1 5 +#endif +#if (defined(JUDY1) || defined(JU_64BIT)) + JU_IMMSETCASCADE(3, OLDPOP1, uint8_t *, cJU_JPLEAF3, + JL_LEAF3VALUEAREA, j__udySearchLeaf3, + JU_INSERTCOPY3, j__udyAllocJLL3); +#endif + +#if (defined(JUDY1) && defined(JU_64BIT)) + +// (4_01 => [[ 4_02..03 => ]] LeafL) + + case cJ1_JPIMMED_4_02: + + JU_IMMSETINPLACE(4, uint32_t *, cJ1_JPIMMED_4_02, j__udySearchLeaf4, + JU_INSERTINPLACE); + + case cJ1_JPIMMED_4_03: + + JU_IMMSETCASCADE(4, 3, uint32_t *, cJU_JPLEAF4, ignore, + j__udySearchLeaf4, JU_INSERTCOPY, + j__udyAllocJLL4); + +// (5_01 => [[ 5_02..03 => ]] LeafL) + + case cJ1_JPIMMED_5_02: + + JU_IMMSETINPLACE(5, uint8_t *, cJ1_JPIMMED_5_02, j__udySearchLeaf5, + JU_INSERTINPLACE5); + + case cJ1_JPIMMED_5_03: + + JU_IMMSETCASCADE(5, 3, uint8_t *, cJU_JPLEAF5, ignore, + j__udySearchLeaf5, JU_INSERTCOPY5, + j__udyAllocJLL5); + +// (6_01 => [[ 6_02 => ]] LeafL) + + case cJ1_JPIMMED_6_02: + + JU_IMMSETCASCADE(6, 2, uint8_t *, cJU_JPLEAF6, ignore, + j__udySearchLeaf6, JU_INSERTCOPY6, + j__udyAllocJLL6); + +// (7_01 => [[ 7_02 => ]] LeafL) + + case cJ1_JPIMMED_7_02: + + JU_IMMSETCASCADE(7, 2, uint8_t *, cJU_JPLEAF7, ignore, + j__udySearchLeaf7, JU_INSERTCOPY7, + j__udyAllocJLL7); + +#endif // (JUDY1 && JU_64BIT) + + +// **************************************************************************** +// INVALID JP TYPE: + + default: JU_SET_ERRNO_NONNULL(Pjpm, JU_ERRNO_CORRUPT); return(-1); + + } // switch on JP type + + { + +#ifdef SUBEXPCOUNTS + +// This code might seem strange here. However it saves some memory read time +// during insert (~70nS) because a pipelined processor does not need to "stall" +// waiting for the memory read to complete. Hope the compiler is not too smart +// or dumb and moves the code down to where it looks like it belongs (below a +// few lines). + + Word_t SubExpCount = 0; // current subexpanse counter. + + if (PSubExp != (PWord_t) NULL) // only if BranchB/U. + SubExpCount = PSubExp[0]; +#endif + +// PROCESS JP -- RECURSIVELY: +// +// For non-Immed JP types, if successful, post-increment the population count +// at this Level. + + retcode = j__udyInsWalk(Pjp, Index, Pjpm); + +// Successful insert, increment JP and subexpanse count: + + if ((JU_JPTYPE(Pjp) < cJU_JPIMMED_1_01) && (retcode == 1)) + { + jp_t JP; + Word_t DcdP0; +#ifdef SUBEXPCOUNTS + +// Note: Pjp must be a pointer to a BranchB/U: + + if (PSubExp != (PWord_t) NULL) PSubExp[0] = SubExpCount + 1; +#endif + + JP = *Pjp; + DcdP0 = JU_JPDCDPOP0(Pjp) + 1; + JU_JPSETADT(Pjp, JP.jp_Addr, DcdP0, JU_JPTYPE(&JP)); + } + } + return(retcode); + +} // j__udyInsWalk() + + +// **************************************************************************** +// J U D Y 1 S E T +// J U D Y L I N S +// +// Main entry point. See the manual entry for details. + +#ifdef JUDY1 +FUNCTION int Judy1Set +#else +FUNCTION PPvoid_t JudyLIns +#endif + ( + PPvoid_t PPArray, // in which to insert. + Word_t Index, // to insert. + PJError_t PJError // optional, for returning error info. + ) +{ +#ifdef JUDY1 +#define Pjv ignore // placeholders for macros. +#define Pjvnew ignore +#else + Pjv_t Pjv; // value area in old leaf. + Pjv_t Pjvnew; // value area in new leaf. +#endif + Pjpm_t Pjpm; // array-global info. + int offset; // position in which to store new Index. + Pjlw_t Pjlw; + + +// CHECK FOR NULL POINTER (error by caller): + + if (PPArray == (PPvoid_t) NULL) + { + JU_SET_ERRNO(PJError, JU_ERRNO_NULLPPARRAY); + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + } + + Pjlw = P_JLW(*PPArray); // first word of leaf. + +// **************************************************************************** +// PROCESS TOP LEVEL "JRP" BRANCHES AND LEAVES: + +// **************************************************************************** +// JRPNULL (EMPTY ARRAY): BUILD A LEAFW WITH ONE INDEX: + +// if a valid empty array (null pointer), so create an array of population == 1: + + if (Pjlw == (Pjlw_t)NULL) + { + Pjlw_t Pjlwnew; + + Pjlwnew = j__udyAllocJLW(1); + JUDY1CODE(JU_CHECKALLOC(Pjlw_t, Pjlwnew, JERRI );) + JUDYLCODE(JU_CHECKALLOC(Pjlw_t, Pjlwnew, PPJERR);) + + Pjlwnew[0] = 1 - 1; // pop0 = 0. + Pjlwnew[1] = Index; + + *PPArray = (Pvoid_t) Pjlwnew; + DBGCODE(JudyCheckPop(*PPArray);) + + JUDY1CODE(return(1); ) + JUDYLCODE(Pjlwnew[2] = 0; ) // value area. + JUDYLCODE(return((PPvoid_t) (Pjlwnew + 2)); ) + + } // NULL JRP + +// **************************************************************************** +// LEAFW, OTHER SIZE: + + if (JU_LEAFW_POP0(*PPArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW + { + Pjlw_t Pjlwnew; + Word_t pop1; + + Pjlw = P_JLW(*PPArray); // first word of leaf. + pop1 = Pjlw[0] + 1; + +#ifdef JUDYL + Pjv = JL_LEAFWVALUEAREA(Pjlw, pop1); +#endif + offset = j__udySearchLeafW(Pjlw + 1, pop1, Index); + + if (offset >= 0) // index is already valid: + { + DBGCODE(JudyCheckPop(*PPArray);) + JUDY1CODE(return(0); ) + JUDYLCODE(return((PPvoid_t) (Pjv + offset)); ) + } + + offset = ~offset; + +// Insert index in cases where no new memory is needed: + + if (JU_LEAFWGROWINPLACE(pop1)) + { + ++Pjlw[0]; // increase population. + + JU_INSERTINPLACE(Pjlw + 1, pop1, offset, Index); +#ifdef JUDYL + JU_INSERTINPLACE(Pjv, pop1, offset, 0); +#endif + DBGCODE(JudyCheckPop(*PPArray);) + DBGCODE(JudyCheckSorted(Pjlw + 1, pop1 + 1, cJU_ROOTSTATE);) + + JUDY1CODE(return(1); ) + JUDYLCODE(return((PPvoid_t) (Pjv + offset)); ) + } + +// Insert index into a new, larger leaf: + + if (pop1 < cJU_LEAFW_MAXPOP1) // can grow to a larger leaf. + { + Pjlwnew = j__udyAllocJLW(pop1 + 1); + JUDY1CODE(JU_CHECKALLOC(Pjlw_t, Pjlwnew, JERRI );) + JUDYLCODE(JU_CHECKALLOC(Pjlw_t, Pjlwnew, PPJERR);) + + Pjlwnew[0] = pop1; // set pop0 in new leaf. + + JU_INSERTCOPY(Pjlwnew + 1, Pjlw + 1, pop1, offset, Index); +#ifdef JUDYL + Pjvnew = JL_LEAFWVALUEAREA(Pjlwnew, pop1 + 1); + JU_INSERTCOPY(Pjvnew, Pjv, pop1, offset, 0); +#endif + DBGCODE(JudyCheckSorted(Pjlwnew + 1, pop1 + 1, cJU_ROOTSTATE);) + + j__udyFreeJLW(Pjlw, pop1, NULL); + + *PPArray = (Pvoid_t) Pjlwnew; + DBGCODE(JudyCheckPop(*PPArray);) + + JUDY1CODE(return(1); ) + JUDYLCODE(return((PPvoid_t) (Pjvnew + offset)); ) + } + + assert(pop1 == cJU_LEAFW_MAXPOP1); + +// Leaf at max size => cannot insert new index, so cascade instead: +// +// Upon cascading from a LEAFW leaf to the first branch, must allocate and +// initialize a JPM. + + Pjpm = j__udyAllocJPM(); + JUDY1CODE(JU_CHECKALLOC(Pjpm_t, Pjpm, JERRI );) + JUDYLCODE(JU_CHECKALLOC(Pjpm_t, Pjpm, PPJERR);) + + (Pjpm->jpm_Pop0) = cJU_LEAFW_MAXPOP1 - 1; + (Pjpm->jpm_JP.jp_Addr) = (Word_t) Pjlw; + + if (j__udyCascadeL(&(Pjpm->jpm_JP), Pjpm) == -1) + { + JU_COPY_ERRNO(PJError, Pjpm); + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + } + +// Note: No need to pass Pjpm for memory decrement; LEAFW memory is never +// counted in a JPM at all: + + j__udyFreeJLW(Pjlw, cJU_LEAFW_MAXPOP1, NULL); + *PPArray = (Pvoid_t) Pjpm; + + } // JU_LEAFW + +// **************************************************************************** +// BRANCH: + + { + int retcode; // really only needed for Judy1, but free for JudyL. + + Pjpm = P_JPM(*PPArray); + retcode = j__udyInsWalk(&(Pjpm->jpm_JP), Index, Pjpm); + + if (retcode == -1) + { + JU_COPY_ERRNO(PJError, Pjpm); + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + } + + if (retcode == 1) ++(Pjpm->jpm_Pop0); // incr total array popu. + + assert(((Pjpm->jpm_JP.jp_Type) == cJU_JPBRANCH_L) + || ((Pjpm->jpm_JP.jp_Type) == cJU_JPBRANCH_B) + || ((Pjpm->jpm_JP.jp_Type) == cJU_JPBRANCH_U)); + DBGCODE(JudyCheckPop(*PPArray);) + +#ifdef JUDY1 + assert((retcode == 0) || (retcode == 1)); + return(retcode); // == JU_RET_*_JPM(). +#else + assert(Pjpm->jpm_PValue != (Pjv_t) NULL); + return((PPvoid_t) Pjpm->jpm_PValue); +#endif + } + /*NOTREACHED*/ + +} // Judy1Set() / JudyLIns() diff --git a/feeds/p4/libjudy/src/src/JudyCommon/JudyInsArray.c b/feeds/p4/libjudy/src/src/JudyCommon/JudyInsArray.c new file mode 100644 index 000000000..f8e361f27 --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudyCommon/JudyInsArray.c @@ -0,0 +1,1178 @@ +// Copyright (C) 2000 - 2002 Hewlett-Packard Company +// +// This program is free software; you can redistribute it and/or modify it +// under the term of the GNU Lesser 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 Lesser General Public License +// for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// _________________ + +// TBD: It would probably be faster for the caller if the JudyL version took +// PIndex as an interleaved array of indexes and values rather than just +// indexes with a separate values array (PValue), especially considering +// indexes and values are copied here with for-loops anyway and not the +// equivalent of memcpy(). All code could be revised to simply count by two +// words for JudyL? Supports "streaming" the data to/from disk better later? +// In which case get rid of JU_ERRNO_NULLPVALUE, no longer needed, and simplify +// the API to this code. +// _________________ + +// @(#) $Revision: 4.21 $ $Source: /judy/src/JudyCommon/JudyInsArray.c $ +// +// Judy1SetArray() and JudyLInsArray() functions for Judy1 and JudyL. +// Compile with one of -DJUDY1 or -DJUDYL. + +#if (! (defined(JUDY1) || defined(JUDYL))) +#error: One of -DJUDY1 or -DJUDYL must be specified. +#endif + +#ifdef JUDY1 +#include "Judy1.h" +#else +#include "JudyL.h" +#endif + +#include "JudyPrivate1L.h" + +DBGCODE(extern void JudyCheckPop(Pvoid_t PArray);) + + +// IMMED AND LEAF SIZE AND BRANCH TYPE ARRAYS: +// +// These support fast and easy lookup by level. + +static uint8_t immed_maxpop1[] = { + 0, + cJU_IMMED1_MAXPOP1, + cJU_IMMED2_MAXPOP1, + cJU_IMMED3_MAXPOP1, +#ifdef JU_64BIT + cJU_IMMED4_MAXPOP1, + cJU_IMMED5_MAXPOP1, + cJU_IMMED6_MAXPOP1, + cJU_IMMED7_MAXPOP1, +#endif + // note: There are no IMMEDs for whole words. +}; + +static uint8_t leaf_maxpop1[] = { + 0, +#if (defined(JUDYL) || (! defined(JU_64BIT))) + cJU_LEAF1_MAXPOP1, +#else + 0, // 64-bit Judy1 has no Leaf1. +#endif + cJU_LEAF2_MAXPOP1, + cJU_LEAF3_MAXPOP1, +#ifdef JU_64BIT + cJU_LEAF4_MAXPOP1, + cJU_LEAF5_MAXPOP1, + cJU_LEAF6_MAXPOP1, + cJU_LEAF7_MAXPOP1, +#endif + // note: Root-level leaves are handled differently. +}; + +static uint8_t branchL_JPtype[] = { + 0, + 0, + cJU_JPBRANCH_L2, + cJU_JPBRANCH_L3, +#ifdef JU_64BIT + cJU_JPBRANCH_L4, + cJU_JPBRANCH_L5, + cJU_JPBRANCH_L6, + cJU_JPBRANCH_L7, +#endif + cJU_JPBRANCH_L, +}; + +static uint8_t branchB_JPtype[] = { + 0, + 0, + cJU_JPBRANCH_B2, + cJU_JPBRANCH_B3, +#ifdef JU_64BIT + cJU_JPBRANCH_B4, + cJU_JPBRANCH_B5, + cJU_JPBRANCH_B6, + cJU_JPBRANCH_B7, +#endif + cJU_JPBRANCH_B, +}; + +static uint8_t branchU_JPtype[] = { + 0, + 0, + cJU_JPBRANCH_U2, + cJU_JPBRANCH_U3, +#ifdef JU_64BIT + cJU_JPBRANCH_U4, + cJU_JPBRANCH_U5, + cJU_JPBRANCH_U6, + cJU_JPBRANCH_U7, +#endif + cJU_JPBRANCH_U, +}; + +// Subexpanse masks are similer to JU_DCDMASK() but without the need to clear +// the first digits bits. Avoid doing variable shifts by precomputing a +// lookup array. + +static Word_t subexp_mask[] = { + 0, + ~cJU_POP0MASK(1), + ~cJU_POP0MASK(2), + ~cJU_POP0MASK(3), +#ifdef JU_64BIT + ~cJU_POP0MASK(4), + ~cJU_POP0MASK(5), + ~cJU_POP0MASK(6), + ~cJU_POP0MASK(7), +#endif +}; + + +// FUNCTION PROTOTYPES: + +static bool_t j__udyInsArray(Pjp_t PjpParent, int Level, PWord_t PPop1, + PWord_t PIndex, +#ifdef JUDYL + Pjv_t PValue, +#endif + Pjpm_t Pjpm); + + +// **************************************************************************** +// J U D Y 1 S E T A R R A Y +// J U D Y L I N S A R R A Y +// +// Main entry point. See the manual entry for external overview. +// +// TBD: Until thats written, note that the function returns 1 for success or +// JERRI for serious error, including insufficient memory to build whole array; +// use Judy*Count() to see how many were stored, the first N of the total +// Count. Also, since it takes Count == Pop1, it cannot handle a full array. +// Also, "sorted" means ascending without duplicates, otherwise you get the +// "unsorted" error. +// +// The purpose of these functions is to allow rapid construction of a large +// Judy array given a sorted list of indexes (and for JudyL, corresponding +// values). At least one customer saw this as useful, and probably it would +// also be useful as a sufficient workaround for fast(er) unload/reload to/from +// disk. +// +// This code is written recursively for simplicity, until/unless someone +// decides to make it faster and more complex. Hopefully recursion is fast +// enough simply because the function is so much faster than a series of +// Set/Ins calls. + +#ifdef JUDY1 +FUNCTION int Judy1SetArray +#else +FUNCTION int JudyLInsArray +#endif + ( + PPvoid_t PPArray, // in which to insert, initially empty. + Word_t Count, // number of indexes (and values) to insert. +const Word_t * const PIndex, // list of indexes to insert. +#ifdef JUDYL +const Word_t * const PValue, // list of corresponding values. +#endif + PJError_t PJError // optional, for returning error info. + ) +{ + Pjlw_t Pjlw; // new root-level leaf. + Pjlw_t Pjlwindex; // first index in root-level leaf. + int offset; // in PIndex. + + +// CHECK FOR NULL OR NON-NULL POINTER (error by caller): + + if (PPArray == (PPvoid_t) NULL) + { JU_SET_ERRNO(PJError, JU_ERRNO_NULLPPARRAY); return(JERRI); } + + if (*PPArray != (Pvoid_t) NULL) + { JU_SET_ERRNO(PJError, JU_ERRNO_NONNULLPARRAY); return(JERRI); } + + if (PIndex == (PWord_t) NULL) + { JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX); return(JERRI); } + +#ifdef JUDYL + if (PValue == (PWord_t) NULL) + { JU_SET_ERRNO(PJError, JU_ERRNO_NULLPVALUE); return(JERRI); } +#endif + + +// HANDLE LARGE COUNT (= POP1) (typical case): +// +// Allocate and initialize a JPM, set the root pointer to point to it, and then +// build the tree underneath it. + +// Common code for unusual error handling when no JPM available: + + if (Count > cJU_LEAFW_MAXPOP1) // too big for root-level leaf. + { + Pjpm_t Pjpm; // new, to allocate. + +// Allocate JPM: + + Pjpm = j__udyAllocJPM(); + JU_CHECKALLOC(Pjpm_t, Pjpm, JERRI); + *PPArray = (Pvoid_t) Pjpm; + +// Set some JPM fields: + + (Pjpm->jpm_Pop0) = Count - 1; + // note: (Pjpm->jpm_TotalMemWords) is now initialized. + +// Build Judy tree: +// +// In case of error save the final Count, possibly modified, unless modified to +// 0, in which case free the JPM itself: + + if (! j__udyInsArray(&(Pjpm->jpm_JP), cJU_ROOTSTATE, &Count, + (PWord_t) PIndex, +#ifdef JUDYL + (Pjv_t) PValue, +#endif + Pjpm)) + { + JU_COPY_ERRNO(PJError, Pjpm); + + if (Count) // partial success, adjust pop0: + { + (Pjpm->jpm_Pop0) = Count - 1; + } + else // total failure, free JPM: + { + j__udyFreeJPM(Pjpm, (Pjpm_t) NULL); + *PPArray = (Pvoid_t) NULL; + } + + DBGCODE(JudyCheckPop(*PPArray);) + return(JERRI); + } + + DBGCODE(JudyCheckPop(*PPArray);) + return(1); + + } // large count + + +// HANDLE SMALL COUNT (= POP1): +// +// First ensure indexes are in sorted order: + + for (offset = 1; offset < Count; ++offset) + { + if (PIndex[offset - 1] >= PIndex[offset]) + { JU_SET_ERRNO(PJError, JU_ERRNO_UNSORTED); return(JERRI); } + } + + if (Count == 0) return(1); // *PPArray remains null. + + { + Pjlw = j__udyAllocJLW(Count + 1); + JU_CHECKALLOC(Pjlw_t, Pjlw, JERRI); + *PPArray = (Pvoid_t) Pjlw; + Pjlw[0] = Count - 1; // set pop0. + Pjlwindex = Pjlw + 1; + } + +// Copy whole-word indexes (and values) to the root-level leaf: + + JU_COPYMEM(Pjlwindex, PIndex, Count); +JUDYLCODE(JU_COPYMEM(JL_LEAFWVALUEAREA(Pjlw, Count), PValue, Count)); + + DBGCODE(JudyCheckPop(*PPArray);) + return(1); + +} // Judy1SetArray() / JudyLInsArray() + + +// **************************************************************************** +// __ J U D Y I N S A R R A Y +// +// Given: +// +// - a pointer to a JP +// +// - the JPs level in the tree, that is, the number of digits left to decode +// in the indexes under the JP (one less than the level of the JPM or branch +// in which the JP resides); cJU_ROOTSTATE on first entry (when JP is the one +// in the JPM), down to 1 for a Leaf1, LeafB1, or FullPop +// +// - a pointer to the number of indexes (and corresponding values) to store in +// this subtree, to modify in case of partial success +// +// - a list of indexes (and for JudyL, corresponding values) to store in this +// subtree +// +// - a JPM for tracking memory usage and returning errors +// +// Recursively build a subtree (immediate indexes, leaf, or branch with +// subtrees) and modify the JP accordingly. On the way down, build a BranchU +// (only) for any expanse with *PPop1 too high for a leaf; on the way out, +// convert the BranchU to a BranchL or BranchB if appropriate. Keep memory +// statistics in the JPM. +// +// Return TRUE for success, or FALSE with error information set in the JPM in +// case of error, in which case leave a partially constructed but healthy tree, +// and modify parent population counts on the way out. +// +// Note: Each call of this function makes all modifications to the PjpParent +// it receives; neither the parent nor child calls do this. + +FUNCTION static bool_t j__udyInsArray( + Pjp_t PjpParent, // parent JP in/under which to store. + int Level, // initial digits remaining to decode. + PWord_t PPop1, // number of indexes to store. + PWord_t PIndex, // list of indexes to store. +#ifdef JUDYL + Pjv_t PValue, // list of corresponding values. +#endif + Pjpm_t Pjpm) // for memory and errors. +{ + Pjp_t Pjp; // lower-level JP. + Word_t Pjbany; // any type of branch. + int levelsub; // actual, of Pjps node, <= Level. + Word_t pop1 = *PPop1; // fast local value. + Word_t pop1sub; // population of one subexpanse. + uint8_t JPtype; // current JP type. + uint8_t JPtype_null; // precomputed value for new branch. + jp_t JPnull; // precomputed for speed. + Pjbu_t PjbuRaw; // constructed BranchU. + Pjbu_t Pjbu; + int digit; // in BranchU. + Word_t digitmask; // for a digit in a BranchU. + Word_t digitshifted; // shifted to correct offset. + Word_t digitshincr; // increment for digitshifted. + int offset; // in PIndex, or a bitmap subexpanse. + int numJPs; // number non-null in a BranchU. + bool_t retval; // to return from this func. +JUDYLCODE(Pjv_t PjvRaw); // destination value area. +JUDYLCODE(Pjv_t Pjv); + + +// MACROS FOR COMMON CODE: +// +// Note: These use function and local parameters from the context. +// Note: Assume newly allocated memory is zeroed. + +// Indicate whether a sorted list of indexes in PIndex, based on the first and +// last indexes in the list using pop1, are in the same subexpanse between +// Level and L_evel: +// +// This can be confusing! Note that SAMESUBEXP(L) == TRUE means the indexes +// are the same through level L + 1, and it says nothing about level L and +// lower; they might be the same or they might differ. +// +// Note: In principle SAMESUBEXP needs a mask for the digits from Level, +// inclusive, to L_evel, exclusive. But in practice, since the indexes are all +// known to be identical above Level, it just uses a mask for the digits +// through L_evel + 1; see subexp_mask[]. + +#define SAMESUBEXP(L_evel) \ + (! ((PIndex[0] ^ PIndex[pop1 - 1]) & subexp_mask[L_evel])) + +// Set PjpParent to a null JP appropriate for the level of the node to which it +// points, which is 1 less than the level of the node in which the JP resides, +// which is by definition Level: +// +// Note: This can set the JPMs JP to an invalid jp_Type, but it doesnt +// matter because the JPM is deleted by the caller. + +#define SETJPNULL_PARENT \ + JU_JPSETADT(PjpParent, 0, 0, cJU_JPNULL1 + Level - 1); + +// Variation to set a specified JP (in a branch being built) to a precomputed +// null JP: + +#define SETJPNULL(Pjp) *(Pjp) = JPnull + +// Handle complete (as opposed to partial) memory allocation failure: Set the +// parent JP to an appropriate null type (to leave a consistent tree), zero the +// callers population count, and return FALSE: +// +// Note: At Level == cJU_ROOTSTATE this sets the JPMs JPs jp_Type to a bogus +// value, but it doesnt matter because the JPM should be deleted by the +// caller. + +#define NOMEM { SETJPNULL_PARENT; *PPop1 = 0; return(FALSE); } + +// Allocate a Leaf1-N and save the address in Pjll; in case of failure, NOMEM: + +#define ALLOCLEAF(AllocLeaf) \ + if ((PjllRaw = AllocLeaf(pop1, Pjpm)) == (Pjll_t) NULL) NOMEM; \ + Pjll = P_JLL(PjllRaw); + +// Copy indexes smaller than words (and values which are whole words) from +// given arrays to immediate indexes or a leaf: +// +// TBD: These macros overlap with some of the code in JudyCascade.c; do some +// merging? That file has functions while these are macros. + +#define COPYTOLEAF_EVEN_SUB(Pjll,LeafType) \ + { \ + LeafType * P_leaf = (LeafType *) (Pjll); \ + Word_t p_op1 = pop1; \ + PWord_t P_Index = PIndex; \ + \ + assert(pop1 > 0); \ + \ + do { *P_leaf++ = *P_Index++; /* truncates */\ + } while (--(p_op1)); \ + } + +#define COPYTOLEAF_ODD_SUB(cLevel,Pjll,Copy) \ + { \ + uint8_t * P_leaf = (uint8_t *) (Pjll); \ + Word_t p_op1 = pop1; \ + PWord_t P_Index = PIndex; \ + \ + assert(pop1 > 0); \ + \ + do { \ + Copy(P_leaf, *P_Index); \ + P_leaf += (cLevel); ++P_Index; \ + } while (--(p_op1)); \ + } + +#ifdef JUDY1 + +#define COPYTOLEAF_EVEN(Pjll,LeafType) COPYTOLEAF_EVEN_SUB(Pjll,LeafType) +#define COPYTOLEAF_ODD(cLevel,Pjll,Copy) COPYTOLEAF_ODD_SUB(cLevel,Pjll,Copy) + +#else // JUDYL adds copying of values: + +#define COPYTOLEAF_EVEN(Pjll,LeafType) \ + { \ + COPYTOLEAF_EVEN_SUB(Pjll,LeafType) \ + JU_COPYMEM(Pjv, PValue, pop1); \ + } + +#define COPYTOLEAF_ODD(cLevel,Pjll,Copy) \ + { \ + COPYTOLEAF_ODD_SUB( cLevel,Pjll,Copy) \ + JU_COPYMEM(Pjv, PValue, pop1); \ + } + +#endif + +// Set the JP type for an immediate index, where BaseJPType is JPIMMED_*_02: + +#define SETIMMTYPE(BaseJPType) (PjpParent->jp_Type) = (BaseJPType) + pop1 - 2 + +// Allocate and populate a Leaf1-N: +// +// Build MAKELEAF_EVEN() and MAKELEAF_ODD() using macros for common code. + +#define MAKELEAF_SUB1(AllocLeaf,ValueArea,LeafType) \ + ALLOCLEAF(AllocLeaf); \ + JUDYLCODE(Pjv = ValueArea(Pjll, pop1)) + + +#define MAKELEAF_SUB2(cLevel,JPType) \ +{ \ + Word_t D_cdP0; \ + assert(pop1 - 1 <= cJU_POP0MASK(cLevel)); \ + D_cdP0 = (*PIndex & cJU_DCDMASK(cLevel)) | (pop1 - 1); \ + JU_JPSETADT(PjpParent, (Word_t)PjllRaw, D_cdP0, JPType); \ +} + + +#define MAKELEAF_EVEN(cLevel,JPType,AllocLeaf,ValueArea,LeafType) \ + MAKELEAF_SUB1(AllocLeaf,ValueArea,LeafType); \ + COPYTOLEAF_EVEN(Pjll, LeafType); \ + MAKELEAF_SUB2(cLevel, JPType) + +#define MAKELEAF_ODD(cLevel,JPType,AllocLeaf,ValueArea,Copy) \ + MAKELEAF_SUB1(AllocLeaf,ValueArea,LeafType); \ + COPYTOLEAF_ODD(cLevel, Pjll, Copy); \ + MAKELEAF_SUB2(cLevel, JPType) + +// Ensure that the indexes to be stored in immediate indexes or a leaf are +// sorted: +// +// This check is pure overhead, but required in order to protect the Judy array +// against caller error, to avoid a later corruption or core dump from a +// seemingly valid Judy array. Do this check piecemeal at the leaf level while +// the indexes are already in the cache. Higher-level order-checking occurs +// while building branches. +// +// Note: Any sorting error in the expanse of a single immediate indexes JP or +// a leaf => save no indexes in that expanse. + +#define CHECKLEAFORDER \ + { \ + for (offset = 1; offset < pop1; ++offset) \ + { \ + if (PIndex[offset - 1] >= PIndex[offset]) \ + { \ + SETJPNULL_PARENT; \ + *PPop1 = 0; \ + JU_SET_ERRNO_NONNULL(Pjpm, JU_ERRNO_UNSORTED); \ + return(FALSE); \ + } \ + } \ + } + + +// ------ START OF CODE ------ + + assert( Level >= 1); + assert( Level <= cJU_ROOTSTATE); + assert((Level < cJU_ROOTSTATE) || (pop1 > cJU_LEAFW_MAXPOP1)); + + +// CHECK FOR TOP LEVEL: +// +// Special case: If at the top level (PjpParent is in the JPM), a top-level +// branch must be created, even if its a BranchL with just one JP. (The JPM +// cannot point to a leaf because the leaf would have to be a lower-level, +// higher-capacity leaf under a narrow pointer (otherwise a root-level leaf +// would suffice), and the JPMs JP cant handle a narrow pointer because the +// jp_DcdPopO field isnt big enough.) Otherwise continue to check for a pop1 +// small enough to support immediate indexes or a leaf before giving up and +// making a lower-level branch. + + if (Level == cJU_ROOTSTATE) + { + levelsub = cJU_ROOTSTATE; + goto BuildBranch2; + } + assert(Level < cJU_ROOTSTATE); + + +// SKIP JPIMMED_*_01: +// +// Immeds with pop1 == 1 should be handled in-line during branch construction. + + assert(pop1 > 1); + + +// BUILD JPIMMED_*_02+: +// +// The starting address of the indexes depends on Judy1 or JudyL; also, JudyL +// includes a pointer to a values-only leaf. + + if (pop1 <= immed_maxpop1[Level]) // note: always < root level. + { + JUDY1CODE(uint8_t * Pjll = (uint8_t *) (PjpParent->jp_1Index);) + JUDYLCODE(uint8_t * Pjll = (uint8_t *) (PjpParent->jp_LIndex);) + + CHECKLEAFORDER; // indexes to be stored are sorted. + +#ifdef JUDYL + if ((PjvRaw = j__udyLAllocJV(pop1, Pjpm)) == (Pjv_t) NULL) + NOMEM; + (PjpParent->jp_Addr) = (Word_t) PjvRaw; + Pjv = P_JV(PjvRaw); +#endif + + switch (Level) + { + case 1: COPYTOLEAF_EVEN(Pjll, uint8_t); + SETIMMTYPE(cJU_JPIMMED_1_02); + break; +#if (defined(JUDY1) || defined(JU_64BIT)) + case 2: COPYTOLEAF_EVEN(Pjll, uint16_t); + SETIMMTYPE(cJU_JPIMMED_2_02); + break; + case 3: COPYTOLEAF_ODD(3, Pjll, JU_COPY3_LONG_TO_PINDEX); + SETIMMTYPE(cJU_JPIMMED_3_02); + break; +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case 4: COPYTOLEAF_EVEN(Pjll, uint32_t); + SETIMMTYPE(cJ1_JPIMMED_4_02); + break; + case 5: COPYTOLEAF_ODD(5, Pjll, JU_COPY5_LONG_TO_PINDEX); + SETIMMTYPE(cJ1_JPIMMED_5_02); + break; + case 6: COPYTOLEAF_ODD(6, Pjll, JU_COPY6_LONG_TO_PINDEX); + SETIMMTYPE(cJ1_JPIMMED_6_02); + break; + case 7: COPYTOLEAF_ODD(7, Pjll, JU_COPY7_LONG_TO_PINDEX); + SETIMMTYPE(cJ1_JPIMMED_7_02); + break; +#endif + default: assert(FALSE); // should be impossible. + } + + return(TRUE); // note: no children => no *PPop1 mods. + + } // JPIMMED_*_02+ + + +// BUILD JPLEAF*: +// +// This code is a little tricky. The method is: For each level starting at +// the present Level down through levelsub = 1, and then as a special case for +// LeafB1 and FullPop (which are also at levelsub = 1 but have different +// capacity, see later), check if pop1 fits in a leaf (using leaf_maxpop1[]) +// at that level. If so, except for Level == levelsub, check if all of the +// current indexes to be stored are in the same (narrow) subexpanse, that is, +// the digits from Level to levelsub + 1, inclusive, are identical between the +// first and last index in the (sorted) list (in PIndex). If this condition is +// satisfied at any level, build a leaf at that level (under a narrow pointer +// if Level > levelsub). +// +// Note: Doing the search in this order results in storing the indexes in +// "least compressed form." + + for (levelsub = Level; levelsub >= 1; --levelsub) + { + Pjll_t PjllRaw; + Pjll_t Pjll; + +// Check if pop1 is too large to fit in a leaf at levelsub; if so, try the next +// lower level: + + if (pop1 > leaf_maxpop1[levelsub]) continue; + +// If pop1 fits in a leaf at levelsub, but levelsub is lower than Level, must +// also check whether all the indexes in the expanse to store can in fact be +// placed under a narrow pointer; if not, a leaf cannot be used, at this or any +// lower level (levelsub): + + if ((levelsub < Level) && (! SAMESUBEXP(levelsub))) + goto BuildBranch; // cant use a narrow, need a branch. + +// Ensure valid pop1 and all indexes are in fact common through Level: + + assert(pop1 <= cJU_POP0MASK(Level) + 1); + assert(! ((PIndex[0] ^ PIndex[pop1 - 1]) & cJU_DCDMASK(Level))); + + CHECKLEAFORDER; // indexes to be stored are sorted. + +// Build correct type of leaf: +// +// Note: The jp_DcdPopO and jp_Type assignments in MAKELEAF_* happen correctly +// for the levelsub (not Level) of the new leaf, even if its under a narrow +// pointer. + + switch (levelsub) + { +#if (defined(JUDYL) || (! defined(JU_64BIT))) + case 1: MAKELEAF_EVEN(1, cJU_JPLEAF1, j__udyAllocJLL1, + JL_LEAF1VALUEAREA, uint8_t); + break; +#endif + case 2: MAKELEAF_EVEN(2, cJU_JPLEAF2, j__udyAllocJLL2, + JL_LEAF2VALUEAREA, uint16_t); + break; + case 3: MAKELEAF_ODD( 3, cJU_JPLEAF3, j__udyAllocJLL3, + JL_LEAF3VALUEAREA, JU_COPY3_LONG_TO_PINDEX); + break; +#ifdef JU_64BIT + case 4: MAKELEAF_EVEN(4, cJU_JPLEAF4, j__udyAllocJLL4, + JL_LEAF4VALUEAREA, uint32_t); + break; + case 5: MAKELEAF_ODD( 5, cJU_JPLEAF5, j__udyAllocJLL5, + JL_LEAF5VALUEAREA, JU_COPY5_LONG_TO_PINDEX); + break; + case 6: MAKELEAF_ODD( 6, cJU_JPLEAF6, j__udyAllocJLL6, + JL_LEAF6VALUEAREA, JU_COPY6_LONG_TO_PINDEX); + break; + case 7: MAKELEAF_ODD( 7, cJU_JPLEAF7, j__udyAllocJLL7, + JL_LEAF7VALUEAREA, JU_COPY7_LONG_TO_PINDEX); + break; +#endif + default: assert(FALSE); // should be impossible. + } + + return(TRUE); // note: no children => no *PPop1 mods. + + } // JPLEAF* + + +// BUILD JPLEAF_B1 OR JPFULLPOPU1: +// +// See above about JPLEAF*. If pop1 doesnt fit in any level of linear leaf, +// it might still fit in a LeafB1 or FullPop, perhaps under a narrow pointer. + + if ((Level == 1) || SAMESUBEXP(1)) // same until last digit. + { + Pjlb_t PjlbRaw; // for bitmap leaf. + Pjlb_t Pjlb; + + assert(pop1 <= cJU_JPFULLPOPU1_POP0 + 1); + CHECKLEAFORDER; // indexes to be stored are sorted. + +#ifdef JUDY1 + +// JPFULLPOPU1: + + if (pop1 == cJU_JPFULLPOPU1_POP0 + 1) + { + Word_t Addr = PjpParent->jp_Addr; + Word_t DcdP0 = (*PIndex & cJU_DCDMASK(1)) + | cJU_JPFULLPOPU1_POP0; + JU_JPSETADT(PjpParent, Addr, DcdP0, cJ1_JPFULLPOPU1); + + return(TRUE); + } +#endif + +// JPLEAF_B1: + + if ((PjlbRaw = j__udyAllocJLB1(Pjpm)) == (Pjlb_t) NULL) + NOMEM; + Pjlb = P_JLB(PjlbRaw); + + for (offset = 0; offset < pop1; ++offset) + JU_BITMAPSETL(Pjlb, PIndex[offset]); + + retval = TRUE; // default. + +#ifdef JUDYL + +// Build subexpanse values-only leaves (LeafVs) under LeafB1: + + for (offset = 0; offset < cJU_NUMSUBEXPL; ++offset) + { + if (! (pop1sub = j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, offset)))) + continue; // skip empty subexpanse. + +// Allocate one LeafV = JP subarray; if out of memory, clear bitmaps for higher +// subexpanses and adjust *PPop1: + + if ((PjvRaw = j__udyLAllocJV(pop1sub, Pjpm)) + == (Pjv_t) NULL) + { + for (/* null */; offset < cJU_NUMSUBEXPL; ++offset) + { + *PPop1 -= j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, offset)); + JU_JLB_BITMAP(Pjlb, offset) = 0; + } + + retval = FALSE; + break; + } + +// Populate values-only leaf and save the pointer to it: + + Pjv = P_JV(PjvRaw); + JU_COPYMEM(Pjv, PValue, pop1sub); + JL_JLB_PVALUE(Pjlb, offset) = PjvRaw; // first-tier pointer. + PValue += pop1sub; + + } // for each subexpanse + +#endif // JUDYL + +// Attach new LeafB1 to parent JP; note use of *PPop1 possibly < pop1: + + JU_JPSETADT(PjpParent, (Word_t) PjlbRaw, + (*PIndex & cJU_DCDMASK(1)) | (*PPop1 - 1), cJU_JPLEAF_B1); + + return(retval); + + } // JPLEAF_B1 or JPFULLPOPU1 + + +// BUILD JPBRANCH_U*: +// +// Arriving at BuildBranch means Level < top level but the pop1 is too large +// for immediate indexes or a leaf, even under a narrow pointer, including a +// LeafB1 or FullPop at level 1. This implies SAMESUBEXP(1) == FALSE, that is, +// the indexes to be stored "branch" at level 2 or higher. + +BuildBranch: // come here directly if a leaf wont work. + + assert(Level >= 2); + assert(Level < cJU_ROOTSTATE); + assert(! SAMESUBEXP(1)); // sanity check, see above. + +// Determine the appropriate level for a new branch node; see if a narrow +// pointer can be used: +// +// This can be confusing. The branch is required at the lowest level L where +// the indexes to store are not in the same subexpanse at level L-1. Work down +// from Level to tree level 3, which is 1 above the lowest tree level = 2 at +// which a branch can be used. Theres no need to check SAMESUBEXP at level 2 +// because its known to be false at level 2-1 = 1. +// +// Note: Unlike for a leaf node, a narrow pointer is always used for a branch +// if possible, that is, maximum compression is always used, except at the top +// level of the tree, where a JPM cannot support a narrow pointer, meaning a +// top BranchL can have a single JP (fanout = 1); but that case jumps directly +// to BuildBranch2. +// +// Note: For 32-bit systems the only usable values for a narrow pointer are +// Level = 3 and levelsub = 2; 64-bit systems have many more choices; but +// hopefully this for-loop is fast enough even on a 32-bit system. +// +// TBD: If not fast enough, #ifdef JU_64BIT and handle the 32-bit case faster. + + for (levelsub = Level; levelsub >= 3; --levelsub) // see above. + if (! SAMESUBEXP(levelsub - 1)) // at limit of narrow pointer. + break; // put branch at levelsub. + +BuildBranch2: // come here directly for Level = levelsub = cJU_ROOTSTATE. + + assert(levelsub >= 2); + assert(levelsub <= Level); + +// Initially build a BranchU: +// +// Always start with a BranchU because the number of populated subexpanses is +// not yet known. Use digitmask, digitshifted, and digitshincr to avoid +// expensive variable shifts within JU_DIGITATSTATE within the loop. +// +// TBD: The use of digitmask, etc. results in more increment operations per +// loop, is there an even faster way? +// +// TBD: Would it pay to pre-count the populated JPs (subexpanses) and +// pre-compress the branch, that is, build a BranchL or BranchB immediately, +// also taking account of opportunistic uncompression rules? Probably not +// because at high levels of the tree there might be huge numbers of indexes +// (hence cache lines) to scan in the PIndex array to determine the fanout +// (number of JPs) needed. + + if ((PjbuRaw = j__udyAllocJBU(Pjpm)) == (Pjbu_t) NULL) NOMEM; + Pjbu = P_JBU(PjbuRaw); + + JPtype_null = cJU_JPNULL1 + levelsub - 2; // in new BranchU. + JU_JPSETADT(&JPnull, 0, 0, JPtype_null); + + Pjp = Pjbu->jbu_jp; // for convenience in loop. + numJPs = 0; // non-null in the BranchU. + digitmask = cJU_MASKATSTATE(levelsub); // see above. + digitshincr = 1UL << (cJU_BITSPERBYTE * (levelsub - 1)); + retval = TRUE; + +// Scan and populate JPs (subexpanses): +// +// Look for all indexes matching each digit in the BranchU (at the correct +// levelsub), and meanwhile notice any sorting error. Increment PIndex (and +// PValue) and reduce pop1 for each subexpanse handled successfully. + + for (digit = digitshifted = 0; + digit < cJU_BRANCHUNUMJPS; + ++digit, digitshifted += digitshincr, ++Pjp) + { + DBGCODE(Word_t pop1subprev;) + assert(pop1 != 0); // end of indexes is handled elsewhere. + +// Count indexes in digits subexpanse: + + for (pop1sub = 0; pop1sub < pop1; ++pop1sub) + if (digitshifted != (PIndex[pop1sub] & digitmask)) break; + +// Empty subexpanse (typical, performance path) or sorting error (rare): + + if (pop1sub == 0) + { + if (digitshifted < (PIndex[0] & digitmask)) + { SETJPNULL(Pjp); continue; } // empty subexpanse. + + assert(pop1 < *PPop1); // did save >= 1 index and decr pop1. + JU_SET_ERRNO_NONNULL(Pjpm, JU_ERRNO_UNSORTED); + goto AbandonBranch; + } + +// Non-empty subexpanse: +// +// First shortcut by handling pop1sub == 1 (JPIMMED_*_01) inline locally. + + if (pop1sub == 1) // note: can be at root level. + { + Word_t Addr = 0; + JUDYLCODE(Addr = (Word_t) (*PValue++);) + JU_JPSETADT(Pjp, Addr, *PIndex, cJU_JPIMMED_1_01 + levelsub -2); + + ++numJPs; + + if (--pop1) { ++PIndex; continue; } // more indexes to store. + + ++digit; ++Pjp; // skip JP just saved. + goto ClearBranch; // save time. + } + +// Recurse to populate one digits (subexpanses) JP; if successful, skip +// indexes (and values) just stored (performance path), except when expanse is +// completely stored: + + DBGCODE(pop1subprev = pop1sub;) + + if (j__udyInsArray(Pjp, levelsub - 1, &pop1sub, (PWord_t) PIndex, +#ifdef JUDYL + (Pjv_t) PValue, +#endif + Pjpm)) + { // complete success. + ++numJPs; + assert(pop1subprev == pop1sub); + assert(pop1 >= pop1sub); + + if ((pop1 -= pop1sub) != 0) // more indexes to store: + { + PIndex += pop1sub; // skip indexes just stored. + JUDYLCODE(PValue += pop1sub;) + continue; + } + // else leave PIndex in BranchUs expanse. + +// No more indexes to store in BranchUs expanse: + + ++digit; ++Pjp; // skip JP just saved. + goto ClearBranch; // save time. + } + +// Handle any error at a lower level of recursion: +// +// In case of partial success, pop1sub != 0, but it was reduced from the value +// passed to j__udyInsArray(); skip this JP later during ClearBranch. + + assert(pop1subprev > pop1sub); // check j__udyInsArray(). + assert(pop1 > pop1sub); // check j__udyInsArray(). + + if (pop1sub) // partial success. + { ++digit; ++Pjp; ++numJPs; } // skip JP just saved. + + pop1 -= pop1sub; // deduct saved indexes if any. + +// Same-level sorting error, or any lower-level error; abandon the rest of the +// branch: +// +// Arrive here with pop1 = remaining unsaved indexes (always non-zero). Adjust +// the *PPop1 value to record and return, modify retval, and use ClearBranch to +// finish up. + +AbandonBranch: + assert(pop1 != 0); // more to store, see above. + assert(pop1 <= *PPop1); // sanity check. + + *PPop1 -= pop1; // deduct unsaved indexes. + pop1 = 0; // to avoid error later. + retval = FALSE; + +// Error (rare), or end of indexes while traversing new BranchU (performance +// path); either way, mark the remaining JPs, if any, in the BranchU as nulls +// and exit the loop: +// +// Arrive here with digit and Pjp set to the first JP to set to null. + +ClearBranch: + for (/* null */; digit < cJU_BRANCHUNUMJPS; ++digit, ++Pjp) + SETJPNULL(Pjp); + break; // saves one more compare. + + } // for each digit + + +// FINISH JPBRANCH_U*: +// +// Arrive here with a BranchU built under Pjbu, numJPs set, and either: retval +// == TRUE and *PPop1 unmodified, or else retval == FALSE, *PPop1 set to the +// actual number of indexes saved (possibly 0 for complete failure at a lower +// level upon the first call of j__udyInsArray()), and the Judy error set in +// Pjpm. Either way, PIndex points to an index within the expanse just +// handled. + + Pjbany = (Word_t) PjbuRaw; // default = use this BranchU. + JPtype = branchU_JPtype[levelsub]; + +// Check for complete failure above: + + assert((! retval) || *PPop1); // sanity check. + + if ((! retval) && (*PPop1 == 0)) // nothing stored, full failure. + { + j__udyFreeJBU(PjbuRaw, Pjpm); + SETJPNULL_PARENT; + return(FALSE); + } + +// Complete or partial success so far; watch for sorting error after the +// maximum digit (255) in the BranchU, which is indicated by having more +// indexes to store in the BranchUs expanse: +// +// For example, if an index to store has a digit of 255 at levelsub, followed +// by an index with a digit of 254, the for-loop above runs out of digits +// without reducing pop1 to 0. + + if (pop1 != 0) + { + JU_SET_ERRNO_NONNULL(Pjpm, JU_ERRNO_UNSORTED); + *PPop1 -= pop1; // deduct unsaved indexes. + retval = FALSE; + } + assert(*PPop1 != 0); // branch (still) cannot be empty. + + +// OPTIONALLY COMPRESS JPBRANCH_U*: +// +// See if the BranchU should be compressed to a BranchL or BranchB; if so, do +// that and free the BranchU; otherwise just use the existing BranchU. Follow +// the same rules as in JudyIns.c (version 4.95): Only check local population +// (cJU_OPP_UNCOMP_POP0) for BranchL, and only check global memory efficiency +// (JU_OPP_UNCOMPRESS) for BranchB. TBD: Have the rules changed? +// +// Note: Because of differing order of operations, the latter compression +// might not result in the same set of branch nodes as a series of sequential +// insertions. +// +// Note: Allocating a BranchU only to sometimes convert it to a BranchL or +// BranchB is unfortunate, but attempting to work with a temporary BranchU on +// the stack and then allocate and keep it as a BranchU in many cases is worse +// in terms of error handling. + + +// COMPRESS JPBRANCH_U* TO JPBRANCH_L*: + + if (numJPs <= cJU_BRANCHLMAXJPS) // JPs fit in a BranchL. + { + Pjbl_t PjblRaw = (Pjbl_t) NULL; // new BranchL; init for cc. + Pjbl_t Pjbl; + + if ((*PPop1 > JU_BRANCHL_MAX_POP) // pop too high. + || ((PjblRaw = j__udyAllocJBL(Pjpm)) == (Pjbl_t) NULL)) + { // cant alloc BranchL. + goto SetParent; // just keep BranchU. + } + + Pjbl = P_JBL(PjblRaw); + +// Copy BranchU JPs to BranchL: + + (Pjbl->jbl_NumJPs) = numJPs; + offset = 0; + + for (digit = 0; digit < cJU_BRANCHUNUMJPS; ++digit) + { + if ((((Pjbu->jbu_jp) + digit)->jp_Type) == JPtype_null) + continue; + + (Pjbl->jbl_Expanse[offset ]) = digit; + (Pjbl->jbl_jp [offset++]) = Pjbu->jbu_jp[digit]; + } + assert(offset == numJPs); // found same number. + +// Free the BranchU and prepare to use the new BranchL instead: + + j__udyFreeJBU(PjbuRaw, Pjpm); + + Pjbany = (Word_t) PjblRaw; + JPtype = branchL_JPtype[levelsub]; + + } // compress to BranchL + + +// COMPRESS JPBRANCH_U* TO JPBRANCH_B*: +// +// If unable to allocate the BranchB or any JP subarray, free all related +// memory and just keep the BranchU. +// +// Note: This use of JU_OPP_UNCOMPRESS is a bit conservative because the +// BranchU is already allocated while the (presumably smaller) BranchB is not, +// the opposite of how its used in single-insert code. + + else + { + Pjbb_t PjbbRaw = (Pjbb_t) NULL; // new BranchB; init for cc. + Pjbb_t Pjbb; + Pjp_t Pjp2; // in BranchU. + + if ((*PPop1 > JU_BRANCHB_MAX_POP) // pop too high. + || ((PjbbRaw = j__udyAllocJBB(Pjpm)) == (Pjbb_t) NULL)) + { // cant alloc BranchB. + goto SetParent; // just keep BranchU. + } + + Pjbb = P_JBB(PjbbRaw); + +// Set bits in bitmap for populated subexpanses: + + Pjp2 = Pjbu->jbu_jp; + + for (digit = 0; digit < cJU_BRANCHUNUMJPS; ++digit) + if ((((Pjbu->jbu_jp) + digit)->jp_Type) != JPtype_null) + JU_BITMAPSETB(Pjbb, digit); + +// Copy non-null JPs to BranchB JP subarrays: + + for (offset = 0; offset < cJU_NUMSUBEXPB; ++offset) + { + Pjp_t PjparrayRaw; + Pjp_t Pjparray; + + if (! (numJPs = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, offset)))) + continue; // skip empty subexpanse. + +// If unable to allocate a JP subarray, free all BranchB memory so far and +// continue to use the BranchU: + + if ((PjparrayRaw = j__udyAllocJBBJP(numJPs, Pjpm)) + == (Pjp_t) NULL) + { + while (offset-- > 0) + { + if (JU_JBB_PJP(Pjbb, offset) == (Pjp_t) NULL) continue; + + j__udyFreeJBBJP(JU_JBB_PJP(Pjbb, offset), + j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, offset)), + Pjpm); + } + j__udyFreeJBB(PjbbRaw, Pjpm); + goto SetParent; // keep BranchU. + } + +// Set one JP subarray pointer and copy the subexpanses JPs to the subarray: +// +// Scan the BranchU for non-null JPs until numJPs JPs are copied. + + JU_JBB_PJP(Pjbb, offset) = PjparrayRaw; + Pjparray = P_JP(PjparrayRaw); + + while (numJPs-- > 0) + { + while ((Pjp2->jp_Type) == JPtype_null) + { + ++Pjp2; + assert(Pjp2 < (Pjbu->jbu_jp) + cJU_BRANCHUNUMJPS); + } + *Pjparray++ = *Pjp2++; + } + } // for each subexpanse + +// Free the BranchU and prepare to use the new BranchB instead: + + j__udyFreeJBU(PjbuRaw, Pjpm); + + Pjbany = (Word_t) PjbbRaw; + JPtype = branchB_JPtype[levelsub]; + + } // compress to BranchB + + +// COMPLETE OR PARTIAL SUCCESS: +// +// Attach new branch (under Pjp, with JPtype) to parent JP; note use of *PPop1, +// possibly reduced due to partial failure. + +SetParent: + (PjpParent->jp_Addr) = Pjbany; + (PjpParent->jp_Type) = JPtype; + + if (Level < cJU_ROOTSTATE) // PjpParent not in JPM: + { + Word_t DcdP0 = (*PIndex & cJU_DCDMASK(levelsub)) | (*PPop1 - 1); + + JU_JPSETADT(PjpParent ,Pjbany, DcdP0, JPtype); + } + + return(retval); + +} // j__udyInsArray() diff --git a/feeds/p4/libjudy/src/src/JudyCommon/JudyInsertBranch.c b/feeds/p4/libjudy/src/src/JudyCommon/JudyInsertBranch.c new file mode 100644 index 000000000..cfa16bd6d --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudyCommon/JudyInsertBranch.c @@ -0,0 +1,135 @@ +// Copyright (C) 2000 - 2002 Hewlett-Packard Company +// +// This program is free software; you can redistribute it and/or modify it +// under the term of the GNU Lesser 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 Lesser General Public License +// for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// _________________ + +// @(#) $Revision: 4.17 $ $Source: /judy/src/JudyCommon/JudyInsertBranch.c $ + +// BranchL insertion functions for Judy1 and JudyL. +// Compile with one of -DJUDY1 or -DJUDYL. + +#if (! (defined(JUDY1) || defined(JUDYL))) +#error: One of -DJUDY1 or -DJUDYL must be specified. +#endif + +#ifdef JUDY1 +#include "Judy1.h" +#else +#include "JudyL.h" +#endif + +#include "JudyPrivate1L.h" + +extern int j__udyCreateBranchL(Pjp_t, Pjp_t, uint8_t *, Word_t, Pvoid_t); + + +// **************************************************************************** +// __ J U D Y I N S E R T B R A N C H +// +// Insert 2-element BranchL in between Pjp and Pjp->jp_Addr. +// +// Return -1 if out of memory, otherwise return 1. + +FUNCTION int j__udyInsertBranch( + Pjp_t Pjp, // JP containing narrow pointer. + Word_t Index, // outlier to Pjp. + Word_t BranchLevel, // of what JP points to, mapped from JP type. + Pjpm_t Pjpm) // for global accounting. +{ + jp_t JP2 [2]; + jp_t JP; + Pjp_t PjpNull; + Word_t XorExp; + Word_t Inew, Iold; + Word_t DCDMask; // initially for original BranchLevel. + int Ret; + uint8_t Exp2[2]; + uint8_t DecodeByteN, DecodeByteO; + +// Get the current mask for the DCD digits: + + DCDMask = cJU_DCDMASK(BranchLevel); + +// Obtain Dcd bits that differ between Index and JP, shifted so the +// digit for BranchLevel is the LSB: + + XorExp = ((Index ^ JU_JPDCDPOP0(Pjp)) & (cJU_ALLONES >> cJU_BITSPERBYTE)) + >> (BranchLevel * cJU_BITSPERBYTE); + assert(XorExp); // Index must be an outlier. + +// Count levels between object under narrow pointer and the level at which +// the outlier diverges from it, which is always at least initial +// BranchLevel + 1, to end up with the level (JP type) at which to insert +// the new intervening BranchL: + + do { ++BranchLevel; } while ((XorExp >>= cJU_BITSPERBYTE)); + assert((BranchLevel > 1) && (BranchLevel < cJU_ROOTSTATE)); + +// Get the MSB (highest digit) that differs between the old expanse and +// the new Index to insert: + + DecodeByteO = JU_DIGITATSTATE(JU_JPDCDPOP0(Pjp), BranchLevel); + DecodeByteN = JU_DIGITATSTATE(Index, BranchLevel); + + assert(DecodeByteO != DecodeByteN); + +// Determine sorted order for old expanse and new Index digits: + + if (DecodeByteN > DecodeByteO) { Iold = 0; Inew = 1; } + else { Iold = 1; Inew = 0; } + +// Copy old JP into staging area for new Branch + JP2 [Iold] = *Pjp; + Exp2[Iold] = DecodeByteO; + Exp2[Inew] = DecodeByteN; + +// Create a 2 Expanse Linear branch +// +// Note: Pjp->jp_Addr is set by j__udyCreateBranchL() + + Ret = j__udyCreateBranchL(Pjp, JP2, Exp2, 2, Pjpm); + if (Ret == -1) return(-1); + +// Get Pjp to the NULL of where to do insert + PjpNull = ((P_JBL(Pjp->jp_Addr))->jbl_jp) + Inew; + +// Convert to a cJU_JPIMMED_*_01 at the correct level: +// Build JP and set type below to: cJU_JPIMMED_X_01 + JU_JPSETADT(PjpNull, 0, Index, cJU_JPIMMED_1_01 - 2 + BranchLevel); + +// Return pointer to Value area in cJU_JPIMMED_X_01 + JUDYLCODE(Pjpm->jpm_PValue = (Pjv_t) PjpNull;) + +// The old JP now points to a BranchL that is at higher level. Therefore +// it contains excess DCD bits (in the least significant position) that +// must be removed (zeroed); that is, they become part of the Pop0 +// subfield. Note that the remaining (lower) bytes in the Pop0 field do +// not change. +// +// Take from the old DCDMask, which went "down" to a lower BranchLevel, +// and zero any high bits that are still in the mask at the new, higher +// BranchLevel; then use this mask to zero the bits in jp_DcdPopO: + +// Set old JP to a BranchL at correct level + + Pjp->jp_Type = cJU_JPBRANCH_L2 - 2 + BranchLevel; + DCDMask ^= cJU_DCDMASK(BranchLevel); + DCDMask = ~DCDMask & JU_JPDCDPOP0(Pjp); + JP = *Pjp; + JU_JPSETADT(Pjp, JP.jp_Addr, DCDMask, JP.jp_Type); + + return(1); + +} // j__udyInsertBranch() diff --git a/feeds/p4/libjudy/src/src/JudyCommon/JudyMalloc.c b/feeds/p4/libjudy/src/src/JudyCommon/JudyMalloc.c new file mode 100644 index 000000000..09a20e399 --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudyCommon/JudyMalloc.c @@ -0,0 +1,87 @@ +// Copyright (C) 2000 - 2002 Hewlett-Packard Company +// +// This program is free software; you can redistribute it and/or modify it +// under the term of the GNU Lesser 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 Lesser General Public License +// for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// _________________ + +// @(#) $Revision: 4.33 $ $Source: /judy/src/JudyCommon/JudyMalloc.c $ +// ************************************************************************ // +// JUDY - Memory Allocater // +// -by- // +// Douglas L. Baskins // +// Hewlett Packard // +// Fort Collins, Co // +// (970) 229-2027 // +// // +// ************************************************************************ // + +// JUDY INCLUDE FILES +#include "Judy.h" + +// **************************************************************************** +// J U D Y M A L L O C +// +// Allocate RAM. This is the single location in Judy code that calls +// malloc(3C). Note: JPM accounting occurs at a higher level. + +Word_t JudyMalloc( + Word_t Words) +{ + Word_t Addr; + + Addr = (Word_t) malloc(Words * sizeof(Word_t)); + return(Addr); + +} // JudyMalloc() + + +// **************************************************************************** +// J U D Y F R E E + +void JudyFree( + void * PWord, + Word_t Words) +{ + (void) Words; + free(PWord); + +} // JudyFree() + + +// **************************************************************************** +// J U D Y M A L L O C +// +// Higher-level "wrapper" for allocating objects that need not be in RAM, +// although at this time they are in fact only in RAM. Later we hope that some +// entire subtrees (at a JPM or branch) can be "virtual", so their allocations +// and frees should go through this level. + +Word_t JudyMallocVirtual( + Word_t Words) +{ + return(JudyMalloc(Words)); + +} // JudyMallocVirtual() + + +// **************************************************************************** +// J U D Y F R E E + +void JudyFreeVirtual( + void * PWord, + Word_t Words) +{ + JudyFree(PWord, Words); + +} // JudyFreeVirtual() diff --git a/feeds/p4/libjudy/src/src/JudyCommon/JudyMallocIF.c b/feeds/p4/libjudy/src/src/JudyCommon/JudyMallocIF.c new file mode 100644 index 000000000..9a7d02f21 --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudyCommon/JudyMallocIF.c @@ -0,0 +1,782 @@ +// Copyright (C) 2000 - 2002 Hewlett-Packard Company +// +// This program is free software; you can redistribute it and/or modify it +// under the term of the GNU Lesser 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 Lesser General Public License +// for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// _________________ + +// @(#) $Revision: 4.45 $ $Source: /judy/src/JudyCommon/JudyMallocIF.c $ +// +// Judy malloc/free interface functions for Judy1 and JudyL. +// +// Compile with one of -DJUDY1 or -DJUDYL. +// +// Compile with -DTRACEMI (Malloc Interface) to turn on tracing of malloc/free +// calls at the interface level. (See also TRACEMF in lower-level code.) +// Use -DTRACEMI2 for a terser format suitable for trace analysis. +// +// There can be malloc namespace bits in the LSBs of "raw" addresses from most, +// but not all, of the j__udy*Alloc*() functions; see also JudyPrivate.h. To +// test the Judy code, compile this file with -DMALLOCBITS and use debug flavor +// only (for assertions). This test ensures that (a) all callers properly mask +// the namespace bits out before dereferencing a pointer (or else a core dump +// occurs), and (b) all callers send "raw" (unmasked) addresses to +// j__udy*Free*() calls. +// +// Note: Currently -DDEBUG turns on MALLOCBITS automatically. + +#if (! (defined(JUDY1) || defined(JUDYL))) +#error: One of -DJUDY1 or -DJUDYL must be specified. +#endif + +#ifdef JUDY1 +#include "Judy1.h" +#else +#include "JudyL.h" +#endif + +#include "JudyPrivate1L.h" + +// Set "hidden" global j__uMaxWords to the maximum number of words to allocate +// to any one array (large enough to have a JPM, otherwise j__uMaxWords is +// ignored), to trigger a fake malloc error when the number is exceeded. Note, +// this code is always executed, not #ifdefd, because its virtually free. +// +// Note: To keep the MALLOC macro faster and simpler, set j__uMaxWords to +// MAXINT, not zero, by default. + +Word_t j__uMaxWords = ~0UL; + +// This macro hides the faking of a malloc failure: +// +// Note: To keep this fast, just compare WordsPrev to j__uMaxWords without the +// complexity of first adding WordsNow, meaning the trigger point is not +// exactly where you might assume, but it shouldnt matter. + +#define MALLOC(MallocFunc,WordsPrev,WordsNow) \ + (((WordsPrev) > j__uMaxWords) ? 0UL : MallocFunc(WordsNow)) + +// Clear words starting at address: +// +// Note: Only use this for objects that care; in other cases, it doesnt +// matter if the objects memory is pre-zeroed. + +#define ZEROWORDS(Addr,Words) \ + { \ + Word_t Words__ = (Words); \ + PWord_t Addr__ = (PWord_t) (Addr); \ + while (Words__--) *Addr__++ = 0UL; \ + } + +#ifdef TRACEMI + +// TRACING SUPPORT: +// +// Note: For TRACEMI, use a format for address printing compatible with other +// tracing facilities; in particular, %x not %lx, to truncate the "noisy" high +// part on 64-bit systems. +// +// TBD: The trace macros need fixing for alternate address types. +// +// Note: TRACEMI2 supports trace analysis no matter the underlying malloc/free +// engine used. + +#include + +static Word_t j__udyMemSequence = 0L; // event sequence number. + +#define TRACE_ALLOC5(a,b,c,d,e) (void) printf(a, (b), c, d) +#define TRACE_FREE5( a,b,c,d,e) (void) printf(a, (b), c, d) +#define TRACE_ALLOC6(a,b,c,d,e,f) (void) printf(a, (b), c, d, e) +#define TRACE_FREE6( a,b,c,d,e,f) (void) printf(a, (b), c, d, e) + +#else + +#ifdef TRACEMI2 + +#include + +#define b_pw cJU_BYTESPERWORD + +#define TRACE_ALLOC5(a,b,c,d,e) \ + (void) printf("a %lx %lx %lx\n", (b), (d) * b_pw, e) +#define TRACE_FREE5( a,b,c,d,e) \ + (void) printf("f %lx %lx %lx\n", (b), (d) * b_pw, e) +#define TRACE_ALLOC6(a,b,c,d,e,f) \ + (void) printf("a %lx %lx %lx\n", (b), (e) * b_pw, f) +#define TRACE_FREE6( a,b,c,d,e,f) \ + (void) printf("f %lx %lx %lx\n", (b), (e) * b_pw, f) + +static Word_t j__udyMemSequence = 0L; // event sequence number. + +#else + +#define TRACE_ALLOC5(a,b,c,d,e) // null. +#define TRACE_FREE5( a,b,c,d,e) // null. +#define TRACE_ALLOC6(a,b,c,d,e,f) // null. +#define TRACE_FREE6( a,b,c,d,e,f) // null. + +#endif // ! TRACEMI2 +#endif // ! TRACEMI + + +// MALLOC NAMESPACE SUPPORT: + +#if (defined(DEBUG) && (! defined(MALLOCBITS))) // for now, DEBUG => MALLOCBITS: +#define MALLOCBITS 1 +#endif + +#ifdef MALLOCBITS +#define MALLOCBITS_VALUE 0x3 // bit pattern to use. +#define MALLOCBITS_MASK 0x7 // note: matches mask__ in JudyPrivate.h. + +#define MALLOCBITS_SET( Type,Addr) \ + ((Addr) = (Type) ((Word_t) (Addr) | MALLOCBITS_VALUE)) +#define MALLOCBITS_TEST(Type,Addr) \ + assert((((Word_t) (Addr)) & MALLOCBITS_MASK) == MALLOCBITS_VALUE); \ + ((Addr) = (Type) ((Word_t) (Addr) & ~MALLOCBITS_VALUE)) +#else +#define MALLOCBITS_SET( Type,Addr) // null. +#define MALLOCBITS_TEST(Type,Addr) // null. +#endif + + +// SAVE ERROR INFORMATION IN A Pjpm: +// +// "Small" (invalid) Addr values are used to distinguish overrun and no-mem +// errors. (TBD, non-zero invalid values are no longer returned from +// lower-level functions, that is, JU_ERRNO_OVERRUN is no longer detected.) + +#define J__UDYSETALLOCERROR(Addr) \ + { \ + JU_ERRID(Pjpm) = __LINE__; \ + if ((Word_t) (Addr) > 0) JU_ERRNO(Pjpm) = JU_ERRNO_OVERRUN; \ + else JU_ERRNO(Pjpm) = JU_ERRNO_NOMEM; \ + return(0); \ + } + + +// **************************************************************************** +// ALLOCATION FUNCTIONS: +// +// To help the compiler catch coding errors, each function returns a specific +// object type. +// +// Note: Only j__udyAllocJPM() and j__udyAllocJLW() return multiple values <= +// sizeof(Word_t) to indicate the type of memory allocation failure. Other +// allocation functions convert this failure to a JU_ERRNO. + + +// Note: Unlike other j__udyAlloc*() functions, Pjpms are returned non-raw, +// that is, without malloc namespace or root pointer type bits: + +FUNCTION Pjpm_t j__udyAllocJPM(void) +{ + Word_t Words = (sizeof(jpm_t) + cJU_BYTESPERWORD - 1) / cJU_BYTESPERWORD; + Pjpm_t Pjpm = (Pjpm_t) MALLOC(JudyMalloc, Words, Words); + + assert((Words * cJU_BYTESPERWORD) == sizeof(jpm_t)); + + if ((Word_t) Pjpm > sizeof(Word_t)) + { + ZEROWORDS(Pjpm, Words); + Pjpm->jpm_TotalMemWords = Words; + } + + TRACE_ALLOC5("0x%x %8lu = j__udyAllocJPM(), Words = %lu\n", + Pjpm, j__udyMemSequence++, Words, cJU_LEAFW_MAXPOP1 + 1); + // MALLOCBITS_SET(Pjpm_t, Pjpm); // see above. + return(Pjpm); + +} // j__udyAllocJPM() + + +FUNCTION Pjbl_t j__udyAllocJBL(Pjpm_t Pjpm) +{ + Word_t Words = sizeof(jbl_t) / cJU_BYTESPERWORD; + Pjbl_t PjblRaw = (Pjbl_t) MALLOC(JudyMallocVirtual, + Pjpm->jpm_TotalMemWords, Words); + + assert((Words * cJU_BYTESPERWORD) == sizeof(jbl_t)); + + if ((Word_t) PjblRaw > sizeof(Word_t)) + { + ZEROWORDS(P_JBL(PjblRaw), Words); + Pjpm->jpm_TotalMemWords += Words; + } + else { J__UDYSETALLOCERROR(PjblRaw); } + + TRACE_ALLOC5("0x%x %8lu = j__udyAllocJBL(), Words = %lu\n", PjblRaw, + j__udyMemSequence++, Words, (Pjpm->jpm_Pop0) + 2); + MALLOCBITS_SET(Pjbl_t, PjblRaw); + return(PjblRaw); + +} // j__udyAllocJBL() + + +FUNCTION Pjbb_t j__udyAllocJBB(Pjpm_t Pjpm) +{ + Word_t Words = sizeof(jbb_t) / cJU_BYTESPERWORD; + Pjbb_t PjbbRaw = (Pjbb_t) MALLOC(JudyMallocVirtual, + Pjpm->jpm_TotalMemWords, Words); + + assert((Words * cJU_BYTESPERWORD) == sizeof(jbb_t)); + + if ((Word_t) PjbbRaw > sizeof(Word_t)) + { + ZEROWORDS(P_JBB(PjbbRaw), Words); + Pjpm->jpm_TotalMemWords += Words; + } + else { J__UDYSETALLOCERROR(PjbbRaw); } + + TRACE_ALLOC5("0x%x %8lu = j__udyAllocJBB(), Words = %lu\n", PjbbRaw, + j__udyMemSequence++, Words, (Pjpm->jpm_Pop0) + 2); + MALLOCBITS_SET(Pjbb_t, PjbbRaw); + return(PjbbRaw); + +} // j__udyAllocJBB() + + +FUNCTION Pjp_t j__udyAllocJBBJP(Word_t NumJPs, Pjpm_t Pjpm) +{ + Word_t Words = JU_BRANCHJP_NUMJPSTOWORDS(NumJPs); + Pjp_t PjpRaw; + + PjpRaw = (Pjp_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words); + + if ((Word_t) PjpRaw > sizeof(Word_t)) + { + Pjpm->jpm_TotalMemWords += Words; + } + else { J__UDYSETALLOCERROR(PjpRaw); } + + TRACE_ALLOC6("0x%x %8lu = j__udyAllocJBBJP(%lu), Words = %lu\n", PjpRaw, + j__udyMemSequence++, NumJPs, Words, (Pjpm->jpm_Pop0) + 2); + MALLOCBITS_SET(Pjp_t, PjpRaw); + return(PjpRaw); + +} // j__udyAllocJBBJP() + + +FUNCTION Pjbu_t j__udyAllocJBU(Pjpm_t Pjpm) +{ + Word_t Words = sizeof(jbu_t) / cJU_BYTESPERWORD; + Pjbu_t PjbuRaw = (Pjbu_t) MALLOC(JudyMallocVirtual, + Pjpm->jpm_TotalMemWords, Words); + + assert((Words * cJU_BYTESPERWORD) == sizeof(jbu_t)); + + if ((Word_t) PjbuRaw > sizeof(Word_t)) + { + Pjpm->jpm_TotalMemWords += Words; + } + else { J__UDYSETALLOCERROR(PjbuRaw); } + + TRACE_ALLOC5("0x%x %8lu = j__udyAllocJBU(), Words = %lu\n", PjbuRaw, + j__udyMemSequence++, Words, (Pjpm->jpm_Pop0) + 2); + MALLOCBITS_SET(Pjbu_t, PjbuRaw); + return(PjbuRaw); + +} // j__udyAllocJBU() + + +#if (defined(JUDYL) || (! defined(JU_64BIT))) + +FUNCTION Pjll_t j__udyAllocJLL1(Word_t Pop1, Pjpm_t Pjpm) +{ + Word_t Words = JU_LEAF1POPTOWORDS(Pop1); + Pjll_t PjllRaw; + + PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words); + + if ((Word_t) PjllRaw > sizeof(Word_t)) + { + Pjpm->jpm_TotalMemWords += Words; + } + else { J__UDYSETALLOCERROR(PjllRaw); } + + TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL1(%lu), Words = %lu\n", PjllRaw, + j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2); + MALLOCBITS_SET(Pjll_t, PjllRaw); + return(PjllRaw); + +} // j__udyAllocJLL1() + +#endif // (JUDYL || (! JU_64BIT)) + + +FUNCTION Pjll_t j__udyAllocJLL2(Word_t Pop1, Pjpm_t Pjpm) +{ + Word_t Words = JU_LEAF2POPTOWORDS(Pop1); + Pjll_t PjllRaw; + + PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words); + + if ((Word_t) PjllRaw > sizeof(Word_t)) + { + Pjpm->jpm_TotalMemWords += Words; + } + else { J__UDYSETALLOCERROR(PjllRaw); } + + TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL2(%lu), Words = %lu\n", PjllRaw, + j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2); + MALLOCBITS_SET(Pjll_t, PjllRaw); + return(PjllRaw); + +} // j__udyAllocJLL2() + + +FUNCTION Pjll_t j__udyAllocJLL3(Word_t Pop1, Pjpm_t Pjpm) +{ + Word_t Words = JU_LEAF3POPTOWORDS(Pop1); + Pjll_t PjllRaw; + + PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words); + + if ((Word_t) PjllRaw > sizeof(Word_t)) + { + Pjpm->jpm_TotalMemWords += Words; + } + else { J__UDYSETALLOCERROR(PjllRaw); } + + TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL3(%lu), Words = %lu\n", PjllRaw, + j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2); + MALLOCBITS_SET(Pjll_t, PjllRaw); + return(PjllRaw); + +} // j__udyAllocJLL3() + + +#ifdef JU_64BIT + +FUNCTION Pjll_t j__udyAllocJLL4(Word_t Pop1, Pjpm_t Pjpm) +{ + Word_t Words = JU_LEAF4POPTOWORDS(Pop1); + Pjll_t PjllRaw; + + PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words); + + if ((Word_t) PjllRaw > sizeof(Word_t)) + { + Pjpm->jpm_TotalMemWords += Words; + } + else { J__UDYSETALLOCERROR(PjllRaw); } + + TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL4(%lu), Words = %lu\n", PjllRaw, + j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2); + MALLOCBITS_SET(Pjll_t, PjllRaw); + return(PjllRaw); + +} // j__udyAllocJLL4() + + +FUNCTION Pjll_t j__udyAllocJLL5(Word_t Pop1, Pjpm_t Pjpm) +{ + Word_t Words = JU_LEAF5POPTOWORDS(Pop1); + Pjll_t PjllRaw; + + PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words); + + if ((Word_t) PjllRaw > sizeof(Word_t)) + { + Pjpm->jpm_TotalMemWords += Words; + } + else { J__UDYSETALLOCERROR(PjllRaw); } + + TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL5(%lu), Words = %lu\n", PjllRaw, + j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2); + MALLOCBITS_SET(Pjll_t, PjllRaw); + return(PjllRaw); + +} // j__udyAllocJLL5() + + +FUNCTION Pjll_t j__udyAllocJLL6(Word_t Pop1, Pjpm_t Pjpm) +{ + Word_t Words = JU_LEAF6POPTOWORDS(Pop1); + Pjll_t PjllRaw; + + PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words); + + if ((Word_t) PjllRaw > sizeof(Word_t)) + { + Pjpm->jpm_TotalMemWords += Words; + } + else { J__UDYSETALLOCERROR(PjllRaw); } + + TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL6(%lu), Words = %lu\n", PjllRaw, + j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2); + MALLOCBITS_SET(Pjll_t, PjllRaw); + return(PjllRaw); + +} // j__udyAllocJLL6() + + +FUNCTION Pjll_t j__udyAllocJLL7(Word_t Pop1, Pjpm_t Pjpm) +{ + Word_t Words = JU_LEAF7POPTOWORDS(Pop1); + Pjll_t PjllRaw; + + PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words); + + if ((Word_t) PjllRaw > sizeof(Word_t)) + { + Pjpm->jpm_TotalMemWords += Words; + } + else { J__UDYSETALLOCERROR(PjllRaw); } + + TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL7(%lu), Words = %lu\n", PjllRaw, + j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2); + MALLOCBITS_SET(Pjll_t, PjllRaw); + return(PjllRaw); + +} // j__udyAllocJLL7() + +#endif // JU_64BIT + + +// Note: Root-level leaf addresses are always whole words (Pjlw_t), and unlike +// other j__udyAlloc*() functions, they are returned non-raw, that is, without +// malloc namespace or root pointer type bits (the latter are added later by +// the caller): + +FUNCTION Pjlw_t j__udyAllocJLW(Word_t Pop1) +{ + Word_t Words = JU_LEAFWPOPTOWORDS(Pop1); + Pjlw_t Pjlw = (Pjlw_t) MALLOC(JudyMalloc, Words, Words); + + TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLW(%lu), Words = %lu\n", Pjlw, + j__udyMemSequence++, Pop1, Words, Pop1); + // MALLOCBITS_SET(Pjlw_t, Pjlw); // see above. + return(Pjlw); + +} // j__udyAllocJLW() + + +FUNCTION Pjlb_t j__udyAllocJLB1(Pjpm_t Pjpm) +{ + Word_t Words = sizeof(jlb_t) / cJU_BYTESPERWORD; + Pjlb_t PjlbRaw; + + PjlbRaw = (Pjlb_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words); + + assert((Words * cJU_BYTESPERWORD) == sizeof(jlb_t)); + + if ((Word_t) PjlbRaw > sizeof(Word_t)) + { + ZEROWORDS(P_JLB(PjlbRaw), Words); + Pjpm->jpm_TotalMemWords += Words; + } + else { J__UDYSETALLOCERROR(PjlbRaw); } + + TRACE_ALLOC5("0x%x %8lu = j__udyAllocJLB1(), Words = %lu\n", PjlbRaw, + j__udyMemSequence++, Words, (Pjpm->jpm_Pop0) + 2); + MALLOCBITS_SET(Pjlb_t, PjlbRaw); + return(PjlbRaw); + +} // j__udyAllocJLB1() + + +#ifdef JUDYL + +FUNCTION Pjv_t j__udyLAllocJV(Word_t Pop1, Pjpm_t Pjpm) +{ + Word_t Words = JL_LEAFVPOPTOWORDS(Pop1); + Pjv_t PjvRaw; + + PjvRaw = (Pjv_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words); + + if ((Word_t) PjvRaw > sizeof(Word_t)) + { + Pjpm->jpm_TotalMemWords += Words; + } + else { J__UDYSETALLOCERROR(PjvRaw); } + + TRACE_ALLOC6("0x%x %8lu = j__udyLAllocJV(%lu), Words = %lu\n", PjvRaw, + j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2); + MALLOCBITS_SET(Pjv_t, PjvRaw); + return(PjvRaw); + +} // j__udyLAllocJV() + +#endif // JUDYL + + +// **************************************************************************** +// FREE FUNCTIONS: +// +// To help the compiler catch coding errors, each function takes a specific +// object type to free. + + +// Note: j__udyFreeJPM() receives a root pointer with NO root pointer type +// bits present, that is, they must be stripped by the caller using P_JPM(): + +FUNCTION void j__udyFreeJPM(Pjpm_t PjpmFree, Pjpm_t PjpmStats) +{ + Word_t Words = (sizeof(jpm_t) + cJU_BYTESPERWORD - 1) / cJU_BYTESPERWORD; + + // MALLOCBITS_TEST(Pjpm_t, PjpmFree); // see above. + JudyFree((Pvoid_t) PjpmFree, Words); + + if (PjpmStats != (Pjpm_t) NULL) PjpmStats->jpm_TotalMemWords -= Words; + +// Note: Log PjpmFree->jpm_Pop0, similar to other j__udyFree*() functions, not +// an assumed value of cJU_LEAFW_MAXPOP1, for when the caller is +// Judy*FreeArray(), jpm_Pop0 is set to 0, and the population after the free +// really will be 0, not cJU_LEAFW_MAXPOP1. + + TRACE_FREE6("0x%x %8lu = j__udyFreeJPM(%lu), Words = %lu\n", PjpmFree, + j__udyMemSequence++, Words, Words, PjpmFree->jpm_Pop0); + + +} // j__udyFreeJPM() + + +FUNCTION void j__udyFreeJBL(Pjbl_t Pjbl, Pjpm_t Pjpm) +{ + Word_t Words = sizeof(jbl_t) / cJU_BYTESPERWORD; + + MALLOCBITS_TEST(Pjbl_t, Pjbl); + JudyFreeVirtual((Pvoid_t) Pjbl, Words); + + Pjpm->jpm_TotalMemWords -= Words; + + TRACE_FREE5("0x%x %8lu = j__udyFreeJBL(), Words = %lu\n", Pjbl, + j__udyMemSequence++, Words, Pjpm->jpm_Pop0); + + +} // j__udyFreeJBL() + + +FUNCTION void j__udyFreeJBB(Pjbb_t Pjbb, Pjpm_t Pjpm) +{ + Word_t Words = sizeof(jbb_t) / cJU_BYTESPERWORD; + + MALLOCBITS_TEST(Pjbb_t, Pjbb); + JudyFreeVirtual((Pvoid_t) Pjbb, Words); + + Pjpm->jpm_TotalMemWords -= Words; + + TRACE_FREE5("0x%x %8lu = j__udyFreeJBB(), Words = %lu\n", Pjbb, + j__udyMemSequence++, Words, Pjpm->jpm_Pop0); + + +} // j__udyFreeJBB() + + +FUNCTION void j__udyFreeJBBJP(Pjp_t Pjp, Word_t NumJPs, Pjpm_t Pjpm) +{ + Word_t Words = JU_BRANCHJP_NUMJPSTOWORDS(NumJPs); + + MALLOCBITS_TEST(Pjp_t, Pjp); + JudyFree((Pvoid_t) Pjp, Words); + + Pjpm->jpm_TotalMemWords -= Words; + + TRACE_FREE6("0x%x %8lu = j__udyFreeJBBJP(%lu), Words = %lu\n", Pjp, + j__udyMemSequence++, NumJPs, Words, Pjpm->jpm_Pop0); + + +} // j__udyFreeJBBJP() + + +FUNCTION void j__udyFreeJBU(Pjbu_t Pjbu, Pjpm_t Pjpm) +{ + Word_t Words = sizeof(jbu_t) / cJU_BYTESPERWORD; + + MALLOCBITS_TEST(Pjbu_t, Pjbu); + JudyFreeVirtual((Pvoid_t) Pjbu, Words); + + Pjpm->jpm_TotalMemWords -= Words; + + TRACE_FREE5("0x%x %8lu = j__udyFreeJBU(), Words = %lu\n", Pjbu, + j__udyMemSequence++, Words, Pjpm->jpm_Pop0); + + +} // j__udyFreeJBU() + + +#if (defined(JUDYL) || (! defined(JU_64BIT))) + +FUNCTION void j__udyFreeJLL1(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm) +{ + Word_t Words = JU_LEAF1POPTOWORDS(Pop1); + + MALLOCBITS_TEST(Pjll_t, Pjll); + JudyFree((Pvoid_t) Pjll, Words); + + Pjpm->jpm_TotalMemWords -= Words; + + TRACE_FREE6("0x%x %8lu = j__udyFreeJLL1(%lu), Words = %lu\n", Pjll, + j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0); + + +} // j__udyFreeJLL1() + +#endif // (JUDYL || (! JU_64BIT)) + + +FUNCTION void j__udyFreeJLL2(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm) +{ + Word_t Words = JU_LEAF2POPTOWORDS(Pop1); + + MALLOCBITS_TEST(Pjll_t, Pjll); + JudyFree((Pvoid_t) Pjll, Words); + + Pjpm->jpm_TotalMemWords -= Words; + + TRACE_FREE6("0x%x %8lu = j__udyFreeJLL2(%lu), Words = %lu\n", Pjll, + j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0); + + +} // j__udyFreeJLL2() + + +FUNCTION void j__udyFreeJLL3(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm) +{ + Word_t Words = JU_LEAF3POPTOWORDS(Pop1); + + MALLOCBITS_TEST(Pjll_t, Pjll); + JudyFree((Pvoid_t) Pjll, Words); + + Pjpm->jpm_TotalMemWords -= Words; + + TRACE_FREE6("0x%x %8lu = j__udyFreeJLL3(%lu), Words = %lu\n", Pjll, + j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0); + + +} // j__udyFreeJLL3() + + +#ifdef JU_64BIT + +FUNCTION void j__udyFreeJLL4(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm) +{ + Word_t Words = JU_LEAF4POPTOWORDS(Pop1); + + MALLOCBITS_TEST(Pjll_t, Pjll); + JudyFree((Pvoid_t) Pjll, Words); + + Pjpm->jpm_TotalMemWords -= Words; + + TRACE_FREE6("0x%x %8lu = j__udyFreeJLL4(%lu), Words = %lu\n", Pjll, + j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0); + + +} // j__udyFreeJLL4() + + +FUNCTION void j__udyFreeJLL5(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm) +{ + Word_t Words = JU_LEAF5POPTOWORDS(Pop1); + + MALLOCBITS_TEST(Pjll_t, Pjll); + JudyFree((Pvoid_t) Pjll, Words); + + Pjpm->jpm_TotalMemWords -= Words; + + TRACE_FREE6("0x%x %8lu = j__udyFreeJLL5(%lu), Words = %lu\n", Pjll, + j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0); + + +} // j__udyFreeJLL5() + + +FUNCTION void j__udyFreeJLL6(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm) +{ + Word_t Words = JU_LEAF6POPTOWORDS(Pop1); + + MALLOCBITS_TEST(Pjll_t, Pjll); + JudyFree((Pvoid_t) Pjll, Words); + + Pjpm->jpm_TotalMemWords -= Words; + + TRACE_FREE6("0x%x %8lu = j__udyFreeJLL6(%lu), Words = %lu\n", Pjll, + j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0); + + +} // j__udyFreeJLL6() + + +FUNCTION void j__udyFreeJLL7(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm) +{ + Word_t Words = JU_LEAF7POPTOWORDS(Pop1); + + MALLOCBITS_TEST(Pjll_t, Pjll); + JudyFree((Pvoid_t) Pjll, Words); + + Pjpm->jpm_TotalMemWords -= Words; + + TRACE_FREE6("0x%x %8lu = j__udyFreeJLL7(%lu), Words = %lu\n", Pjll, + j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0); + + +} // j__udyFreeJLL7() + +#endif // JU_64BIT + + +// Note: j__udyFreeJLW() receives a root pointer with NO root pointer type +// bits present, that is, they are stripped by P_JLW(): + +FUNCTION void j__udyFreeJLW(Pjlw_t Pjlw, Word_t Pop1, Pjpm_t Pjpm) +{ + Word_t Words = JU_LEAFWPOPTOWORDS(Pop1); + + // MALLOCBITS_TEST(Pjlw_t, Pjlw); // see above. + JudyFree((Pvoid_t) Pjlw, Words); + + if (Pjpm) Pjpm->jpm_TotalMemWords -= Words; + + TRACE_FREE6("0x%x %8lu = j__udyFreeJLW(%lu), Words = %lu\n", Pjlw, + j__udyMemSequence++, Pop1, Words, Pop1 - 1); + + +} // j__udyFreeJLW() + + +FUNCTION void j__udyFreeJLB1(Pjlb_t Pjlb, Pjpm_t Pjpm) +{ + Word_t Words = sizeof(jlb_t) / cJU_BYTESPERWORD; + + MALLOCBITS_TEST(Pjlb_t, Pjlb); + JudyFree((Pvoid_t) Pjlb, Words); + + Pjpm->jpm_TotalMemWords -= Words; + + TRACE_FREE5("0x%x %8lu = j__udyFreeJLB1(), Words = %lu\n", Pjlb, + j__udyMemSequence++, Words, Pjpm->jpm_Pop0); + + +} // j__udyFreeJLB1() + + +#ifdef JUDYL + +FUNCTION void j__udyLFreeJV(Pjv_t Pjv, Word_t Pop1, Pjpm_t Pjpm) +{ + Word_t Words = JL_LEAFVPOPTOWORDS(Pop1); + + MALLOCBITS_TEST(Pjv_t, Pjv); + JudyFree((Pvoid_t) Pjv, Words); + + Pjpm->jpm_TotalMemWords -= Words; + + TRACE_FREE6("0x%x %8lu = j__udyLFreeJV(%lu), Words = %lu\n", Pjv, + j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0); + + +} // j__udyLFreeJV() + +#endif // JUDYL diff --git a/feeds/p4/libjudy/src/src/JudyCommon/JudyMemActive.c b/feeds/p4/libjudy/src/src/JudyCommon/JudyMemActive.c new file mode 100644 index 000000000..fb58d0e25 --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudyCommon/JudyMemActive.c @@ -0,0 +1,259 @@ +// Copyright (C) 2000 - 2002 Hewlett-Packard Company +// +// This program is free software; you can redistribute it and/or modify it +// under the term of the GNU Lesser 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 Lesser General Public License +// for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// _________________ + +// @(#) $Revision: 4.7 $ $Source: /judy/src/JudyCommon/JudyMemActive.c $ +// +// Return number of bytes of memory used to support a Judy1/L array. +// Compile with one of -DJUDY1 or -DJUDYL. + +#if (! (defined(JUDY1) || defined(JUDYL))) +#error: One of -DJUDY1 or -DJUDYL must be specified. +#endif + +#ifdef JUDY1 +#include "Judy1.h" +#else +#include "JudyL.h" +#endif + +#include "JudyPrivate1L.h" + +FUNCTION static Word_t j__udyGetMemActive(Pjp_t); + + +// **************************************************************************** +// J U D Y 1 M E M A C T I V E +// J U D Y L M E M A C T I V E + +#ifdef JUDY1 +FUNCTION Word_t Judy1MemActive +#else +FUNCTION Word_t JudyLMemActive +#endif + ( + Pcvoid_t PArray // from which to retrieve. + ) +{ + if (PArray == (Pcvoid_t)NULL) return(0); + + if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW + { + Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf. + Word_t Words = Pjlw[0] + 1; // population. +#ifdef JUDY1 + return((Words + 1) * sizeof(Word_t)); +#else + return(((Words * 2) + 1) * sizeof(Word_t)); +#endif + } + else + { + Pjpm_t Pjpm = P_JPM(PArray); + return(j__udyGetMemActive(&Pjpm->jpm_JP) + sizeof(jpm_t)); + } + +} // JudyMemActive() + + +// **************************************************************************** +// __ J U D Y G E T M E M A C T I V E + +FUNCTION static Word_t j__udyGetMemActive( + Pjp_t Pjp) // top of subtree. +{ + Word_t offset; // in a branch. + Word_t Bytes = 0; // actual bytes used at this level. + Word_t IdxSz; // bytes per index in leaves + + switch (JU_JPTYPE(Pjp)) + { + + case cJU_JPBRANCH_L2: + case cJU_JPBRANCH_L3: +#ifdef JU_64BIT + case cJU_JPBRANCH_L4: + case cJU_JPBRANCH_L5: + case cJU_JPBRANCH_L6: + case cJU_JPBRANCH_L7: +#endif + case cJU_JPBRANCH_L: + { + Pjbl_t Pjbl = P_JBL(Pjp->jp_Addr); + + for (offset = 0; offset < (Pjbl->jbl_NumJPs); ++offset) + Bytes += j__udyGetMemActive((Pjbl->jbl_jp) + offset); + + return(Bytes + sizeof(jbl_t)); + } + + case cJU_JPBRANCH_B2: + case cJU_JPBRANCH_B3: +#ifdef JU_64BIT + case cJU_JPBRANCH_B4: + case cJU_JPBRANCH_B5: + case cJU_JPBRANCH_B6: + case cJU_JPBRANCH_B7: +#endif + case cJU_JPBRANCH_B: + { + Word_t subexp; + Word_t jpcount; + Pjbb_t Pjbb = P_JBB(Pjp->jp_Addr); + + for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp) + { + jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp)); + Bytes += jpcount * sizeof(jp_t); + + for (offset = 0; offset < jpcount; ++offset) + { + Bytes += j__udyGetMemActive(P_JP(JU_JBB_PJP(Pjbb, subexp)) + + offset); + } + } + + return(Bytes + sizeof(jbb_t)); + } + + case cJU_JPBRANCH_U2: + case cJU_JPBRANCH_U3: +#ifdef JU_64BIT + case cJU_JPBRANCH_U4: + case cJU_JPBRANCH_U5: + case cJU_JPBRANCH_U6: + case cJU_JPBRANCH_U7: +#endif + case cJU_JPBRANCH_U: + { + Pjbu_t Pjbu = P_JBU(Pjp->jp_Addr); + + for (offset = 0; offset < cJU_BRANCHUNUMJPS; ++offset) + { + if (((Pjbu->jbu_jp[offset].jp_Type) >= cJU_JPNULL1) + && ((Pjbu->jbu_jp[offset].jp_Type) <= cJU_JPNULLMAX)) + { + continue; // skip null JP to save time. + } + + Bytes += j__udyGetMemActive(Pjbu->jbu_jp + offset); + } + + return(Bytes + sizeof(jbu_t)); + } + + +// -- Cases below here terminate and do not recurse. -- + +#if (defined(JUDYL) || (! defined(JU_64BIT))) + case cJU_JPLEAF1: IdxSz = 1; goto LeafWords; +#endif + case cJU_JPLEAF2: IdxSz = 2; goto LeafWords; + case cJU_JPLEAF3: IdxSz = 3; goto LeafWords; +#ifdef JU_64BIT + case cJU_JPLEAF4: IdxSz = 4; goto LeafWords; + case cJU_JPLEAF5: IdxSz = 5; goto LeafWords; + case cJU_JPLEAF6: IdxSz = 6; goto LeafWords; + case cJU_JPLEAF7: IdxSz = 7; goto LeafWords; +#endif +LeafWords: + +#ifdef JUDY1 + return(IdxSz * (JU_JPLEAF_POP0(Pjp) + 1)); +#else + return((IdxSz + sizeof(Word_t)) + * (JU_JPLEAF_POP0(Pjp) + 1)); +#endif + case cJU_JPLEAF_B1: + { +#ifdef JUDY1 + return(sizeof(jlb_t)); +#else + Bytes = (JU_JPLEAF_POP0(Pjp) + 1) * sizeof(Word_t); + + return(Bytes + sizeof(jlb_t)); +#endif + } + + JUDY1CODE(case cJ1_JPFULLPOPU1: return(0);) + +#ifdef JUDY1 +#define J__Mpy 0 +#else +#define J__Mpy sizeof(Word_t) +#endif + + case cJU_JPIMMED_1_01: return(0); + case cJU_JPIMMED_2_01: return(0); + case cJU_JPIMMED_3_01: return(0); +#ifdef JU_64BIT + case cJU_JPIMMED_4_01: return(0); + case cJU_JPIMMED_5_01: return(0); + case cJU_JPIMMED_6_01: return(0); + case cJU_JPIMMED_7_01: return(0); +#endif + + case cJU_JPIMMED_1_02: return(J__Mpy * 2); + case cJU_JPIMMED_1_03: return(J__Mpy * 3); +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_1_04: return(J__Mpy * 4); + case cJU_JPIMMED_1_05: return(J__Mpy * 5); + case cJU_JPIMMED_1_06: return(J__Mpy * 6); + case cJU_JPIMMED_1_07: return(J__Mpy * 7); +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_1_08: return(0); + case cJ1_JPIMMED_1_09: return(0); + case cJ1_JPIMMED_1_10: return(0); + case cJ1_JPIMMED_1_11: return(0); + case cJ1_JPIMMED_1_12: return(0); + case cJ1_JPIMMED_1_13: return(0); + case cJ1_JPIMMED_1_14: return(0); + case cJ1_JPIMMED_1_15: return(0); +#endif + +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_2_02: return(J__Mpy * 2); + case cJU_JPIMMED_2_03: return(J__Mpy * 3); +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_2_04: return(0); + case cJ1_JPIMMED_2_05: return(0); + case cJ1_JPIMMED_2_06: return(0); + case cJ1_JPIMMED_2_07: return(0); +#endif + +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_3_02: return(J__Mpy * 2); +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_3_03: return(0); + case cJ1_JPIMMED_3_04: return(0); + case cJ1_JPIMMED_3_05: return(0); + + case cJ1_JPIMMED_4_02: return(0); + case cJ1_JPIMMED_4_03: return(0); + case cJ1_JPIMMED_5_02: return(0); + case cJ1_JPIMMED_5_03: return(0); + case cJ1_JPIMMED_6_02: return(0); + case cJ1_JPIMMED_7_02: return(0); +#endif + + } // switch (JU_JPTYPE(Pjp)) + + return(0); // to make some compilers happy. + +} // j__udyGetMemActive() diff --git a/feeds/p4/libjudy/src/src/JudyCommon/JudyMemUsed.c b/feeds/p4/libjudy/src/src/JudyCommon/JudyMemUsed.c new file mode 100644 index 000000000..81e3a79ce --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudyCommon/JudyMemUsed.c @@ -0,0 +1,61 @@ +// Copyright (C) 2000 - 2002 Hewlett-Packard Company +// +// This program is free software; you can redistribute it and/or modify it +// under the term of the GNU Lesser 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 Lesser General Public License +// for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// _________________ + +// @(#) $Revision: 4.5 $ $Source: /judy/src/JudyCommon/JudyMemUsed.c $ +// +// Return number of bytes of memory used to support a Judy1/L array. +// Compile with one of -DJUDY1 or -DJUDYL. + +#if (! (defined(JUDY1) || defined(JUDYL))) +#error: One of -DJUDY1 or -DJUDYL must be specified. +#endif + +#ifdef JUDY1 +#include "Judy1.h" +#else +#include "JudyL.h" +#endif + +#include "JudyPrivate1L.h" + +#ifdef JUDY1 +FUNCTION Word_t Judy1MemUsed +#else // JUDYL +FUNCTION Word_t JudyLMemUsed +#endif + ( + Pcvoid_t PArray // from which to retrieve. + ) +{ + Word_t Words = 0; + + if (PArray == (Pcvoid_t) NULL) return(0); + + if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW + { + Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf. + Words = JU_LEAFWPOPTOWORDS(Pjlw[0] + 1); // based on pop1. + } + else + { + Pjpm_t Pjpm = P_JPM(PArray); + Words = Pjpm->jpm_TotalMemWords; + } + + return(Words * sizeof(Word_t)); // convert to bytes. + +} // Judy1MemUsed() / JudyLMemUsed() diff --git a/feeds/p4/libjudy/src/src/JudyCommon/JudyPrevNext.c b/feeds/p4/libjudy/src/src/JudyCommon/JudyPrevNext.c new file mode 100644 index 000000000..4bcdccf10 --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudyCommon/JudyPrevNext.c @@ -0,0 +1,1890 @@ +// Copyright (C) 2000 - 2002 Hewlett-Packard Company +// +// This program is free software; you can redistribute it and/or modify it +// under the term of the GNU Lesser 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 Lesser General Public License +// for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// _________________ + +// @(#) $Revision: 4.54 $ $Source: /judy/src/JudyCommon/JudyPrevNext.c $ +// +// Judy*Prev() and Judy*Next() functions for Judy1 and JudyL. +// Compile with one of -DJUDY1 or -DJUDYL. +// +// Compile with -DJUDYNEXT for the Judy*Next() function; otherwise defaults to +// Judy*Prev(). + +#if (! (defined(JUDY1) || defined(JUDYL))) +#error: One of -DJUDY1 or -DJUDYL must be specified. +#endif + +#ifndef JUDYNEXT +#ifndef JUDYPREV +#define JUDYPREV 1 // neither set => use default. +#endif +#endif + +#ifdef JUDY1 +#include "Judy1.h" +#else +#include "JudyL.h" +#endif + +#include "JudyPrivate1L.h" + + +// **************************************************************************** +// J U D Y 1 P R E V +// J U D Y 1 N E X T +// J U D Y L P R E V +// J U D Y L N E X T +// +// See the manual entry for the API. +// +// OVERVIEW OF Judy*Prev(): +// +// Use a reentrant switch statement (state machine, SM1 = "get") to decode the +// callers *PIndex-1, starting with the (PArray), through branches, if +// any, down to an immediate or a leaf. Look for *PIndex-1 in that leaf, and +// if found, return it. +// +// A dead end is either a branch that does not contain a JP for the appropriate +// digit in *PIndex-1, or a leaf that does not contain the undecoded digits of +// *PIndex-1. Upon reaching a dead end, backtrack through the leaf/branches +// that were just traversed, using a list (history) of parent JPs that is built +// while going forward in SM1Get. Start with the current leaf or branch. In a +// backtracked leaf, look for an Index less than *PIndex-1. In each +// backtracked branch, look "sideways" for the next JP, if any, lower than the +// one for the digit (from *PIndex-1) that was previously decoded. While +// backtracking, if a leaf has no previous Index or a branch has no lower JP, +// go to its parent branch in turn. Upon reaching the JRP, return failure, "no +// previous Index". The backtrack process is sufficiently different from +// SM1Get to merit its own separate reentrant switch statement (SM2 = +// "backtrack"). +// +// While backtracking, upon finding a lower JP in a branch, there is certain to +// be a "prev" Index under that JP (unless the Judy array is corrupt). +// Traverse forward again, this time taking the last (highest, right-most) JP +// in each branch, and the last (highest) Index upon reaching an immediate or a +// leaf. This traversal is sufficiently different from SM1Get and SM2Backtrack +// to merit its own separate reentrant switch statement (SM3 = "findlimit"). +// +// "Decode" bytes in JPs complicate this process a little. In SM1Get, when a +// JP is a narrow pointer, that is, when states are skipped (so the skipped +// digits are stored in jp_DcdPopO), compare the relevant digits to the same +// digits in *PIndex-1. If they are EQUAL, proceed in SM1Get as before. If +// jp_DcdPopOs digits are GREATER, treat the JP as a dead end and proceed in +// SM2Backtrack. If jp_DcdPopOs digits are LESS, treat the JP as if it had +// just been found during a backtrack and proceed directly in SM3Findlimit. +// +// Note that Decode bytes can be ignored in SM3Findlimit; they dont matter. +// Also note that in practice the Decode bytes are routinely compared with +// *PIndex-1 because thats simpler and no slower than first testing for +// narrowness. +// +// Decode bytes also make it unnecessary to construct the Index to return (the +// revised *PIndex) during the search. This step is deferred until finding an +// Index during backtrack or findlimit, before returning it. The first digit +// of *PIndex is derived (saved) based on which JP is used in a JRP branch. +// The remaining digits are obtained from the jp_DcdPopO field in the JP (if +// any) above the immediate or leaf containing the found (prev) Index, plus the +// remaining digit(s) in the immediate or leaf itself. In the case of a LEAFW, +// the Index to return is found directly in the leaf. +// +// Note: Theoretically, as described above, upon reaching a dead end, SM1Get +// passes control to SM2Backtrack to look sideways, even in a leaf. Actually +// its a little more efficient for the SM1Get leaf cases to shortcut this and +// take care of the sideways searches themselves. Hence the history list only +// contains branch JPs, and SM2Backtrack only handles branches. In fact, even +// the branch handling cases in SM1Get do some shortcutting (sideways +// searching) to avoid pushing history and calling SM2Backtrack unnecessarily. +// +// Upon reaching an Index to return after backtracking, *PIndex must be +// modified to the found Index. In principle this could be done by building +// the Index from a saved rootdigit (in the top branch) plus the Dcd bytes from +// the parent JP plus the appropriate Index bytes from the leaf. However, +// Immediates are difficult because their parent JPs lack one (last) digit. So +// instead just build the *PIndex to return "top down" while backtracking and +// findlimiting. +// +// This function is written iteratively for speed, rather than recursively. +// +// CAVEATS: +// +// Why use a backtrack list (history stack), since it has finite size? The +// size is small for Judy on both 32-bit and 64-bit systems, and a list (really +// just an array) is fast to maintain and use. Other alternatives include +// doing a lookahead (lookaside) in each branch while traversing forward +// (decoding), and restarting from the top upon a dead end. +// +// A lookahead means noting the last branch traversed which contained a +// non-null JP lower than the one specified by a digit in *PIndex-1, and +// returning to that point for SM3Findlimit. This seems like a good idea, and +// should be pretty cheap for linear and bitmap branches, but it could result +// in up to 31 unnecessary additional cache line fills (in extreme cases) for +// every uncompressed branch traversed. We have considered means of attaching +// to or hiding within an uncompressed branch (in null JPs) a "cache line map" +// or other structure, such as an offset to the next non-null JP, that would +// speed this up, but it seems unnecessary merely to avoid having a +// finite-length list (array). (If JudySL is ever made "native", the finite +// list length will be an issue.) +// +// Restarting at the top of the Judy array after a dead end requires a careful +// modification of *PIndex-1 to decrement the digit for the parent branch and +// set the remaining lower digits to all 1s. This must be repeated each time a +// parent branch contains another dead end, so even though it should all happen +// in cache, the CPU time can be excessive. (For JudySL or an equivalent +// "infinitely deep" Judy array, consider a hybrid of a large, finite, +// "circular" list and a restart-at-top when the list is backtracked to +// exhaustion.) +// +// Why search for *PIndex-1 instead of *PIndex during SM1Get? In rare +// instances this prevents an unnecessary decode down the wrong path followed +// by a backtrack; its pretty cheap to set up initially; and it means the +// SM1Get machine can simply return if/when it finds that Index. +// +// TBD: Wed like to enhance this function to make successive searches faster. +// This would require saving some previous state, including the previous Index +// returned, and in which leaf it was found. If the next call is for the same +// Index and the array has not been modified, start at the same leaf. This +// should be much easier to implement since this is iterative rather than +// recursive code. +// +// VARIATIONS FOR Judy*Next(): +// +// The Judy*Next() code is nearly a perfect mirror of the Judy*Prev() code. +// See the Judy*Prev() overview comments, and mentally switch the following: +// +// - "*PIndex-1" => "*PIndex+1" +// - "less than" => "greater than" +// - "lower" => "higher" +// - "lowest" => "highest" +// - "next-left" => "next-right" +// - "right-most" => "left-most" +// +// Note: SM3Findlimit could be called SM3Findmax/SM3Findmin, but a common name +// for both Prev and Next means many fewer ifdefs in this code. +// +// TBD: Currently this code traverses a JP whether its expanse is partially or +// completely full (populated). For Judy1 (only), since there is no value area +// needed, consider shortcutting to a "success" return upon encountering a full +// JP in SM1Get (or even SM3Findlimit?) A full JP looks like this: +// +// (((JU_JPDCDPOP0(Pjp) ^ cJU_ALLONES) & cJU_POP0MASK(cLevel)) == 0) + +#ifdef JUDY1 +#ifdef JUDYPREV +FUNCTION int Judy1Prev +#else +FUNCTION int Judy1Next +#endif +#else +#ifdef JUDYPREV +FUNCTION PPvoid_t JudyLPrev +#else +FUNCTION PPvoid_t JudyLNext +#endif +#endif + ( + Pcvoid_t PArray, // Judy array to search. + Word_t * PIndex, // starting point and result. + PJError_t PJError // optional, for returning error info. + ) +{ + Pjp_t Pjp, Pjp2; // current JPs. + Pjbl_t Pjbl; // Pjp->jp_Addr masked and cast to types: + Pjbb_t Pjbb; + Pjbu_t Pjbu; + +// Note: The following initialization is not strictly required but it makes +// gcc -Wall happy because there is an "impossible" path from Immed handling to +// SM1LeafLImm code that looks like Pjll might be used before set: + + Pjll_t Pjll = (Pjll_t) NULL; + Word_t state; // current state in SM. + Word_t digit; // next digit to decode from Index. + +// Note: The following initialization is not strictly required but it makes +// gcc -Wall happy because there is an "impossible" path from Immed handling to +// SM1LeafLImm code (for JudyL & JudyPrev only) that looks like pop1 might be +// used before set: + +#if (defined(JUDYL) && defined(JUDYPREV)) + Word_t pop1 = 0; // in a leaf. +#else + Word_t pop1; // in a leaf. +#endif + int offset; // linear branch/leaf, from j__udySearchLeaf*(). + int subexp; // subexpanse in a bitmap branch. + Word_t bitposmask; // bit in bitmap for Index. + +// History for SM2Backtrack: +// +// For a given histnum, APjphist[histnum] is a parent JP that points to a +// branch, and Aoffhist[histnum] is the offset of the NEXT JP in the branch to +// which the parent JP points. The meaning of Aoffhist[histnum] depends on the +// type of branch to which the parent JP points: +// +// Linear: Offset of the next JP in the JP list. +// +// Bitmap: Which subexpanse, plus the offset of the next JP in the +// subexpanses JP list (to avoid bit-counting again), plus for Judy*Next(), +// hidden one byte to the left, which digit, because Judy*Next() also needs +// this. +// +// Uncompressed: Digit, which is actually the offset of the JP in the branch. +// +// Note: Only branch JPs are stored in APjphist[] because, as explained +// earlier, SM1Get shortcuts sideways searches in leaves (and even in branches +// in some cases), so SM2Backtrack only handles branches. + +#define HISTNUMMAX cJU_ROOTSTATE // maximum branches traversable. + Pjp_t APjphist[HISTNUMMAX]; // list of branch JPs traversed. + int Aoffhist[HISTNUMMAX]; // list of next JP offsets; see above. + int histnum = 0; // number of JPs now in list. + + +// ---------------------------------------------------------------------------- +// M A C R O S +// +// These are intended to make the code a bit more readable and less redundant. + + +// "PUSH" AND "POP" Pjp AND offset ON HISTORY STACKS: +// +// Note: Ensure a corrupt Judy array does not overflow *hist[]. Meanwhile, +// underflowing *hist[] simply means theres no more room to backtrack => +// "no previous/next Index". + +#define HISTPUSH(Pjp,Offset) \ + APjphist[histnum] = (Pjp); \ + Aoffhist[histnum] = (Offset); \ + \ + if (++histnum >= HISTNUMMAX) \ + { \ + JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT) \ + JUDY1CODE(return(JERRI );) \ + JUDYLCODE(return(PPJERR);) \ + } + +#define HISTPOP(Pjp,Offset) \ + if ((histnum--) < 1) JU_RET_NOTFOUND; \ + (Pjp) = APjphist[histnum]; \ + (Offset) = Aoffhist[histnum] + +// How to pack/unpack Aoffhist[] values for bitmap branches: + +#ifdef JUDYPREV + +#define HISTPUSHBOFF(Subexp,Offset,Digit) \ + (((Subexp) * cJU_BITSPERSUBEXPB) | (Offset)) + +#define HISTPOPBOFF(Subexp,Offset,Digit) \ + (Subexp) = (Offset) / cJU_BITSPERSUBEXPB; \ + (Offset) %= cJU_BITSPERSUBEXPB +#else + +#define HISTPUSHBOFF(Subexp,Offset,Digit) \ + (((Digit) << cJU_BITSPERBYTE) \ + | ((Subexp) * cJU_BITSPERSUBEXPB) | (Offset)) + +#define HISTPOPBOFF(Subexp,Offset,Digit) \ + (Digit) = (Offset) >> cJU_BITSPERBYTE; \ + (Subexp) = ((Offset) & JU_LEASTBYTESMASK(1)) / cJU_BITSPERSUBEXPB; \ + (Offset) %= cJU_BITSPERSUBEXPB +#endif + + +// CHECK FOR NULL JP: + +#define JPNULL(Type) (((Type) >= cJU_JPNULL1) && ((Type) <= cJU_JPNULLMAX)) + + +// SEARCH A BITMAP: +// +// This is a weak analog of j__udySearchLeaf*() for bitmaps. Return the actual +// or next-left position, base 0, of Digit in the single uint32_t bitmap, also +// given a Bitposmask for Digit. +// +// Unlike j__udySearchLeaf*(), the offset is not returned bit-complemented if +// Digits bit is unset, because the caller can check the bitmap themselves to +// determine that. Also, if Digits bit is unset, the returned offset is to +// the next-left JP (including -1), not to the "ideal" position for the Index = +// next-right JP. +// +// Shortcut and skip calling j__udyCountBits*() if the bitmap is full, in which +// case (Digit % cJU_BITSPERSUBEXP*) itself is the base-0 offset. +// +// TBD for Judy*Next(): Should this return next-right instead of next-left? +// That is, +1 from current value? Maybe not, if Digits bit IS set, +1 would +// be wrong. + +#define SEARCHBITMAPB(Bitmap,Digit,Bitposmask) \ + (((Bitmap) == cJU_FULLBITMAPB) ? (Digit % cJU_BITSPERSUBEXPB) : \ + j__udyCountBitsB((Bitmap) & JU_MASKLOWERINC(Bitposmask)) - 1) + +#define SEARCHBITMAPL(Bitmap,Digit,Bitposmask) \ + (((Bitmap) == cJU_FULLBITMAPL) ? (Digit % cJU_BITSPERSUBEXPL) : \ + j__udyCountBitsL((Bitmap) & JU_MASKLOWERINC(Bitposmask)) - 1) + +#ifdef JUDYPREV +// Equivalent to search for the highest offset in Bitmap: + +#define SEARCHBITMAPMAXB(Bitmap) \ + (((Bitmap) == cJU_FULLBITMAPB) ? cJU_BITSPERSUBEXPB - 1 : \ + j__udyCountBitsB(Bitmap) - 1) + +#define SEARCHBITMAPMAXL(Bitmap) \ + (((Bitmap) == cJU_FULLBITMAPL) ? cJU_BITSPERSUBEXPL - 1 : \ + j__udyCountBitsL(Bitmap) - 1) +#endif + + +// CHECK DECODE BYTES: +// +// Check Decode bytes in a JP against the equivalent portion of *PIndex. If +// *PIndex is lower (for Judy*Prev()) or higher (for Judy*Next()), this JP is a +// dead end (the same as if it had been absent in a linear or bitmap branch or +// null in an uncompressed branch), enter SM2Backtrack; otherwise enter +// SM3Findlimit to find the highest/lowest Index under this JP, as if the code +// had already backtracked to this JP. + +#ifdef JUDYPREV +#define CDcmp__ < +#else +#define CDcmp__ > +#endif + +#define CHECKDCD(cState) \ + if (JU_DCDNOTMATCHINDEX(*PIndex, Pjp, cState)) \ + { \ + if ((*PIndex & cJU_DCDMASK(cState)) \ + CDcmp__(JU_JPDCDPOP0(Pjp) & cJU_DCDMASK(cState))) \ + { \ + goto SM2Backtrack; \ + } \ + goto SM3Findlimit; \ + } + + +// PREPARE TO HANDLE A LEAFW OR JRP BRANCH IN SM1: +// +// Extract a state-dependent digit from Index in a "constant" way, then jump to +// common code for multiple cases. + +#define SM1PREPB(cState,Next) \ + state = (cState); \ + digit = JU_DIGITATSTATE(*PIndex, cState); \ + goto Next + + +// PREPARE TO HANDLE A LEAFW OR JRP BRANCH IN SM3: +// +// Optionally save Dcd bytes into *PIndex, then save state and jump to common +// code for multiple cases. + +#define SM3PREPB_DCD(cState,Next) \ + JU_SETDCD(*PIndex, Pjp, cState); \ + SM3PREPB(cState,Next) + +#define SM3PREPB(cState,Next) state = (cState); goto Next + + +// ---------------------------------------------------------------------------- +// CHECK FOR SHORTCUTS: +// +// Error out if PIndex is null. Execute JU_RET_NOTFOUND if the Judy array is +// empty or *PIndex is already the minimum/maximum Index possible. +// +// Note: As documented, in case of failure *PIndex may be modified. + + if (PIndex == (PWord_t) NULL) + { + JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX); + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + } + +#ifdef JUDYPREV + if ((PArray == (Pvoid_t) NULL) || ((*PIndex)-- == 0)) +#else + if ((PArray == (Pvoid_t) NULL) || ((*PIndex)++ == cJU_ALLONES)) +#endif + JU_RET_NOTFOUND; + + +// HANDLE JRP: +// +// Before even entering SM1Get, check the JRP type. For JRP branches, traverse +// the JPM; handle LEAFW leaves directly; but look for the most common cases +// first. + +// ROOT-STATE LEAF that starts with a Pop0 word; just look within the leaf: +// +// If *PIndex is in the leaf, return it; otherwise return the Index, if any, +// below where it would belong. + + if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW + { + Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf. + pop1 = Pjlw[0] + 1; + + if ((offset = j__udySearchLeafW(Pjlw + 1, pop1, *PIndex)) + >= 0) // Index is present. + { + assert(offset < pop1); // in expected range. + JU_RET_FOUND_LEAFW(Pjlw, pop1, offset); // *PIndex is set. + } + +#ifdef JUDYPREV + if ((offset = ~offset) == 0) // no next-left Index. +#else + if ((offset = ~offset) >= pop1) // no next-right Index. +#endif + JU_RET_NOTFOUND; + + assert(offset <= pop1); // valid result. + +#ifdef JUDYPREV + *PIndex = Pjlw[offset--]; // next-left Index, base 1. +#else + *PIndex = Pjlw[offset + 1]; // next-right Index, base 1. +#endif + JU_RET_FOUND_LEAFW(Pjlw, pop1, offset); // base 0. + + } + else // JRP BRANCH + { + Pjpm_t Pjpm = P_JPM(PArray); + Pjp = &(Pjpm->jpm_JP); + +// goto SM1Get; + } + +// ============================================================================ +// STATE MACHINE 1 -- GET INDEX: +// +// Search for *PIndex (already decremented/incremented so as to be inclusive). +// If found, return it. Otherwise in theory hand off to SM2Backtrack or +// SM3Findlimit, but in practice "shortcut" by first sideways searching the +// current branch or leaf upon hitting a dead end. During sideways search, +// modify *PIndex to a new path taken. +// +// ENTRY: Pjp points to next JP to interpret, whose Decode bytes have not yet +// been checked. This JP is not yet listed in history. +// +// Note: Check Decode bytes at the start of each loop, not after looking up a +// new JP, so its easy to do constant shifts/masks, although this requires +// cautious handling of Pjp, offset, and *hist[] for correct entry to +// SM2Backtrack. +// +// EXIT: Return, or branch to SM2Backtrack or SM3Findlimit with correct +// interface, as described elsewhere. +// +// WARNING: For run-time efficiency the following cases replicate code with +// varying constants, rather than using common code with variable values! + +SM1Get: // return here for next branch/leaf. + + switch (JU_JPTYPE(Pjp)) + { + + +// ---------------------------------------------------------------------------- +// LINEAR BRANCH: +// +// Check Decode bytes, if any, in the current JP, then search for a JP for the +// next digit in *PIndex. + + case cJU_JPBRANCH_L2: CHECKDCD(2); SM1PREPB(2, SM1BranchL); + case cJU_JPBRANCH_L3: CHECKDCD(3); SM1PREPB(3, SM1BranchL); +#ifdef JU_64BIT + case cJU_JPBRANCH_L4: CHECKDCD(4); SM1PREPB(4, SM1BranchL); + case cJU_JPBRANCH_L5: CHECKDCD(5); SM1PREPB(5, SM1BranchL); + case cJU_JPBRANCH_L6: CHECKDCD(6); SM1PREPB(6, SM1BranchL); + case cJU_JPBRANCH_L7: CHECKDCD(7); SM1PREPB(7, SM1BranchL); +#endif + case cJU_JPBRANCH_L: SM1PREPB(cJU_ROOTSTATE, SM1BranchL); + +// Common code (state-independent) for all cases of linear branches: + +SM1BranchL: + Pjbl = P_JBL(Pjp->jp_Addr); + +// Found JP matching current digit in *PIndex; record parent JP and the next +// JPs offset, and iterate to the next JP: + + if ((offset = j__udySearchLeaf1((Pjll_t) (Pjbl->jbl_Expanse), + Pjbl->jbl_NumJPs, digit)) >= 0) + { + HISTPUSH(Pjp, offset); + Pjp = (Pjbl->jbl_jp) + offset; + goto SM1Get; + } + +// Dead end, no JP in BranchL for next digit in *PIndex: +// +// Get the ideal location of digits JP, and if theres no next-left/right JP +// in the BranchL, shortcut and start backtracking one level up; ignore the +// current Pjp because it points to a BranchL with no next-left/right JP. + +#ifdef JUDYPREV + if ((offset = (~offset) - 1) < 0) // no next-left JP in BranchL. +#else + if ((offset = (~offset)) >= Pjbl->jbl_NumJPs) // no next-right. +#endif + goto SM2Backtrack; + +// Theres a next-left/right JP in the current BranchL; save its digit in +// *PIndex and shortcut to SM3Findlimit: + + JU_SETDIGIT(*PIndex, Pjbl->jbl_Expanse[offset], state); + Pjp = (Pjbl->jbl_jp) + offset; + goto SM3Findlimit; + + +// ---------------------------------------------------------------------------- +// BITMAP BRANCH: +// +// Check Decode bytes, if any, in the current JP, then look for a JP for the +// next digit in *PIndex. + + case cJU_JPBRANCH_B2: CHECKDCD(2); SM1PREPB(2, SM1BranchB); + case cJU_JPBRANCH_B3: CHECKDCD(3); SM1PREPB(3, SM1BranchB); +#ifdef JU_64BIT + case cJU_JPBRANCH_B4: CHECKDCD(4); SM1PREPB(4, SM1BranchB); + case cJU_JPBRANCH_B5: CHECKDCD(5); SM1PREPB(5, SM1BranchB); + case cJU_JPBRANCH_B6: CHECKDCD(6); SM1PREPB(6, SM1BranchB); + case cJU_JPBRANCH_B7: CHECKDCD(7); SM1PREPB(7, SM1BranchB); +#endif + case cJU_JPBRANCH_B: SM1PREPB(cJU_ROOTSTATE, SM1BranchB); + +// Common code (state-independent) for all cases of bitmap branches: + +SM1BranchB: + Pjbb = P_JBB(Pjp->jp_Addr); + +// Locate the digits JP in the subexpanse list, if present, otherwise the +// offset of the next-left JP, if any: + + subexp = digit / cJU_BITSPERSUBEXPB; + assert(subexp < cJU_NUMSUBEXPB); // falls in expected range. + bitposmask = JU_BITPOSMASKB(digit); + offset = SEARCHBITMAPB(JU_JBB_BITMAP(Pjbb, subexp), digit, + bitposmask); + // right range: + assert((offset >= -1) && (offset < (int) cJU_BITSPERSUBEXPB)); + +// Found JP matching current digit in *PIndex: +// +// Record the parent JP and the next JPs offset; and iterate to the next JP. + +// if (JU_BITMAPTESTB(Pjbb, digit)) // slower. + if (JU_JBB_BITMAP(Pjbb, subexp) & bitposmask) // faster. + { + // not negative since at least one bit is set: + assert(offset >= 0); + + HISTPUSH(Pjp, HISTPUSHBOFF(subexp, offset, digit)); + + if ((Pjp = P_JP(JU_JBB_PJP(Pjbb, subexp))) == (Pjp_t) NULL) + { + JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + } + + Pjp += offset; + goto SM1Get; // iterate to next JP. + } + +// Dead end, no JP in BranchB for next digit in *PIndex: +// +// If theres a next-left/right JP in the current BranchB, shortcut to +// SM3Findlimit. Note: offset is already set to the correct value for the +// next-left/right JP. + +#ifdef JUDYPREV + if (offset >= 0) // next-left JP is in this subexpanse. + goto SM1BranchBFindlimit; + + while (--subexp >= 0) // search next-left subexpanses. +#else + if (JU_JBB_BITMAP(Pjbb, subexp) & JU_MASKHIGHEREXC(bitposmask)) + { + ++offset; // next-left => next-right. + goto SM1BranchBFindlimit; + } + + while (++subexp < cJU_NUMSUBEXPB) // search next-right subexps. +#endif + { + if (! JU_JBB_PJP(Pjbb, subexp)) continue; // empty subexpanse. + +#ifdef JUDYPREV + offset = SEARCHBITMAPMAXB(JU_JBB_BITMAP(Pjbb, subexp)); + // expected range: + assert((offset >= 0) && (offset < cJU_BITSPERSUBEXPB)); +#else + offset = 0; +#endif + +// Save the next-left/right JPs digit in *PIndex: + +SM1BranchBFindlimit: + JU_BITMAPDIGITB(digit, subexp, JU_JBB_BITMAP(Pjbb, subexp), + offset); + JU_SETDIGIT(*PIndex, digit, state); + + if ((Pjp = P_JP(JU_JBB_PJP(Pjbb, subexp))) == (Pjp_t) NULL) + { + JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + } + + Pjp += offset; + goto SM3Findlimit; + } + +// Theres no next-left/right JP in the BranchB: +// +// Shortcut and start backtracking one level up; ignore the current Pjp because +// it points to a BranchB with no next-left/right JP. + + goto SM2Backtrack; + + +// ---------------------------------------------------------------------------- +// UNCOMPRESSED BRANCH: +// +// Check Decode bytes, if any, in the current JP, then look for a JP for the +// next digit in *PIndex. + + case cJU_JPBRANCH_U2: CHECKDCD(2); SM1PREPB(2, SM1BranchU); + case cJU_JPBRANCH_U3: CHECKDCD(3); SM1PREPB(3, SM1BranchU); +#ifdef JU_64BIT + case cJU_JPBRANCH_U4: CHECKDCD(4); SM1PREPB(4, SM1BranchU); + case cJU_JPBRANCH_U5: CHECKDCD(5); SM1PREPB(5, SM1BranchU); + case cJU_JPBRANCH_U6: CHECKDCD(6); SM1PREPB(6, SM1BranchU); + case cJU_JPBRANCH_U7: CHECKDCD(7); SM1PREPB(7, SM1BranchU); +#endif + case cJU_JPBRANCH_U: SM1PREPB(cJU_ROOTSTATE, SM1BranchU); + +// Common code (state-independent) for all cases of uncompressed branches: + +SM1BranchU: + Pjbu = P_JBU(Pjp->jp_Addr); + Pjp2 = (Pjbu->jbu_jp) + digit; + +// Found JP matching current digit in *PIndex: +// +// Record the parent JP and the next JPs digit, and iterate to the next JP. +// +// TBD: Instead of this, just goto SM1Get, and add cJU_JPNULL* cases to the +// SM1Get state machine? Then backtrack? However, it means you cant detect +// an inappropriate cJU_JPNULL*, when it occurs in other than a BranchU, and +// return JU_RET_CORRUPT. + + if (! JPNULL(JU_JPTYPE(Pjp2))) // digit has a JP. + { + HISTPUSH(Pjp, digit); + Pjp = Pjp2; + goto SM1Get; + } + +// Dead end, no JP in BranchU for next digit in *PIndex: +// +// Search for a next-left/right JP in the current BranchU, and if one is found, +// save its digit in *PIndex and shortcut to SM3Findlimit: + +#ifdef JUDYPREV + while (digit >= 1) + { + Pjp = (Pjbu->jbu_jp) + (--digit); +#else + while (digit < cJU_BRANCHUNUMJPS - 1) + { + Pjp = (Pjbu->jbu_jp) + (++digit); +#endif + if (JPNULL(JU_JPTYPE(Pjp))) continue; + + JU_SETDIGIT(*PIndex, digit, state); + goto SM3Findlimit; + } + +// Theres no next-left/right JP in the BranchU: +// +// Shortcut and start backtracking one level up; ignore the current Pjp because +// it points to a BranchU with no next-left/right JP. + + goto SM2Backtrack; + + +// ---------------------------------------------------------------------------- +// LINEAR LEAF: +// +// Check Decode bytes, if any, in the current JP, then search the leaf for +// *PIndex. + +#define SM1LEAFL(Func) \ + Pjll = P_JLL(Pjp->jp_Addr); \ + pop1 = JU_JPLEAF_POP0(Pjp) + 1; \ + offset = Func(Pjll, pop1, *PIndex); \ + goto SM1LeafLImm + +#if (defined(JUDYL) || (! defined(JU_64BIT))) + case cJU_JPLEAF1: CHECKDCD(1); SM1LEAFL(j__udySearchLeaf1); +#endif + case cJU_JPLEAF2: CHECKDCD(2); SM1LEAFL(j__udySearchLeaf2); + case cJU_JPLEAF3: CHECKDCD(3); SM1LEAFL(j__udySearchLeaf3); + +#ifdef JU_64BIT + case cJU_JPLEAF4: CHECKDCD(4); SM1LEAFL(j__udySearchLeaf4); + case cJU_JPLEAF5: CHECKDCD(5); SM1LEAFL(j__udySearchLeaf5); + case cJU_JPLEAF6: CHECKDCD(6); SM1LEAFL(j__udySearchLeaf6); + case cJU_JPLEAF7: CHECKDCD(7); SM1LEAFL(j__udySearchLeaf7); +#endif + +// Common code (state-independent) for all cases of linear leaves and +// immediates: + +SM1LeafLImm: + if (offset >= 0) // *PIndex is in LeafL / Immed. +#ifdef JUDY1 + JU_RET_FOUND; +#else + { // JudyL is trickier... + switch (JU_JPTYPE(Pjp)) + { +#if (defined(JUDYL) || (! defined(JU_64BIT))) + case cJU_JPLEAF1: JU_RET_FOUND_LEAF1(Pjll, pop1, offset); +#endif + case cJU_JPLEAF2: JU_RET_FOUND_LEAF2(Pjll, pop1, offset); + case cJU_JPLEAF3: JU_RET_FOUND_LEAF3(Pjll, pop1, offset); +#ifdef JU_64BIT + case cJU_JPLEAF4: JU_RET_FOUND_LEAF4(Pjll, pop1, offset); + case cJU_JPLEAF5: JU_RET_FOUND_LEAF5(Pjll, pop1, offset); + case cJU_JPLEAF6: JU_RET_FOUND_LEAF6(Pjll, pop1, offset); + case cJU_JPLEAF7: JU_RET_FOUND_LEAF7(Pjll, pop1, offset); +#endif + + case cJU_JPIMMED_1_01: + case cJU_JPIMMED_2_01: + case cJU_JPIMMED_3_01: +#ifdef JU_64BIT + case cJU_JPIMMED_4_01: + case cJU_JPIMMED_5_01: + case cJU_JPIMMED_6_01: + case cJU_JPIMMED_7_01: +#endif + JU_RET_FOUND_IMM_01(Pjp); + + case cJU_JPIMMED_1_02: + case cJU_JPIMMED_1_03: +#ifdef JU_64BIT + case cJU_JPIMMED_1_04: + case cJU_JPIMMED_1_05: + case cJU_JPIMMED_1_06: + case cJU_JPIMMED_1_07: + case cJU_JPIMMED_2_02: + case cJU_JPIMMED_2_03: + case cJU_JPIMMED_3_02: +#endif + JU_RET_FOUND_IMM(Pjp, offset); + } + + JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // impossible? + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + + } // found *PIndex + +#endif // JUDYL + +// Dead end, no Index in LeafL / Immed for remaining digit(s) in *PIndex: +// +// Get the ideal location of Index, and if theres no next-left/right Index in +// the LeafL / Immed, shortcut and start backtracking one level up; ignore the +// current Pjp because it points to a LeafL / Immed with no next-left/right +// Index. + +#ifdef JUDYPREV + if ((offset = (~offset) - 1) < 0) // no next-left Index. +#else + if ((offset = (~offset)) >= pop1) // no next-right Index. +#endif + goto SM2Backtrack; + +// Theres a next-left/right Index in the current LeafL / Immed; shortcut by +// copying its digit(s) to *PIndex and returning it. +// +// Unfortunately this is pretty hairy, especially avoiding endian issues. +// +// The cJU_JPLEAF* cases are very similar to same-index-size cJU_JPIMMED* cases +// for *_02 and above, but must return differently, at least for JudyL, so +// spell them out separately here at the cost of a little redundant code for +// Judy1. + + switch (JU_JPTYPE(Pjp)) + { +#if (defined(JUDYL) || (! defined(JU_64BIT))) + case cJU_JPLEAF1: + + JU_SETDIGIT1(*PIndex, ((uint8_t *) Pjll)[offset]); + JU_RET_FOUND_LEAF1(Pjll, pop1, offset); +#endif + + case cJU_JPLEAF2: + + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(2))) + | ((uint16_t *) Pjll)[offset]; + JU_RET_FOUND_LEAF2(Pjll, pop1, offset); + + case cJU_JPLEAF3: + { + Word_t lsb; + JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (3 * offset)); + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb; + JU_RET_FOUND_LEAF3(Pjll, pop1, offset); + } + +#ifdef JU_64BIT + case cJU_JPLEAF4: + + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(4))) + | ((uint32_t *) Pjll)[offset]; + JU_RET_FOUND_LEAF4(Pjll, pop1, offset); + + case cJU_JPLEAF5: + { + Word_t lsb; + JU_COPY5_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (5 * offset)); + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(5))) | lsb; + JU_RET_FOUND_LEAF5(Pjll, pop1, offset); + } + + case cJU_JPLEAF6: + { + Word_t lsb; + JU_COPY6_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (6 * offset)); + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(6))) | lsb; + JU_RET_FOUND_LEAF6(Pjll, pop1, offset); + } + + case cJU_JPLEAF7: + { + Word_t lsb; + JU_COPY7_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (7 * offset)); + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(7))) | lsb; + JU_RET_FOUND_LEAF7(Pjll, pop1, offset); + } + +#endif // JU_64BIT + +#define SET_01(cState) JU_SETDIGITS(*PIndex, JU_JPDCDPOP0(Pjp), cState) + + case cJU_JPIMMED_1_01: SET_01(1); goto SM1Imm_01; + case cJU_JPIMMED_2_01: SET_01(2); goto SM1Imm_01; + case cJU_JPIMMED_3_01: SET_01(3); goto SM1Imm_01; +#ifdef JU_64BIT + case cJU_JPIMMED_4_01: SET_01(4); goto SM1Imm_01; + case cJU_JPIMMED_5_01: SET_01(5); goto SM1Imm_01; + case cJU_JPIMMED_6_01: SET_01(6); goto SM1Imm_01; + case cJU_JPIMMED_7_01: SET_01(7); goto SM1Imm_01; +#endif +SM1Imm_01: JU_RET_FOUND_IMM_01(Pjp); + +// Shorthand for where to find start of Index bytes array: + +#ifdef JUDY1 +#define PJI (Pjp->jp_1Index) +#else +#define PJI (Pjp->jp_LIndex) +#endif + + case cJU_JPIMMED_1_02: + case cJU_JPIMMED_1_03: +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_1_04: + case cJU_JPIMMED_1_05: + case cJU_JPIMMED_1_06: + case cJU_JPIMMED_1_07: +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_1_08: + case cJ1_JPIMMED_1_09: + case cJ1_JPIMMED_1_10: + case cJ1_JPIMMED_1_11: + case cJ1_JPIMMED_1_12: + case cJ1_JPIMMED_1_13: + case cJ1_JPIMMED_1_14: + case cJ1_JPIMMED_1_15: +#endif + JU_SETDIGIT1(*PIndex, ((uint8_t *) PJI)[offset]); + JU_RET_FOUND_IMM(Pjp, offset); + +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_2_02: + case cJU_JPIMMED_2_03: +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_2_04: + case cJ1_JPIMMED_2_05: + case cJ1_JPIMMED_2_06: + case cJ1_JPIMMED_2_07: +#endif +#if (defined(JUDY1) || defined(JU_64BIT)) + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(2))) + | ((uint16_t *) PJI)[offset]; + JU_RET_FOUND_IMM(Pjp, offset); +#endif + +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_3_02: +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_3_03: + case cJ1_JPIMMED_3_04: + case cJ1_JPIMMED_3_05: +#endif +#if (defined(JUDY1) || defined(JU_64BIT)) + { + Word_t lsb; + JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (3 * offset)); + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb; + JU_RET_FOUND_IMM(Pjp, offset); + } +#endif + +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_4_02: + case cJ1_JPIMMED_4_03: + + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(4))) + | ((uint32_t *) PJI)[offset]; + JU_RET_FOUND_IMM(Pjp, offset); + + case cJ1_JPIMMED_5_02: + case cJ1_JPIMMED_5_03: + { + Word_t lsb; + JU_COPY5_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (5 * offset)); + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(5))) | lsb; + JU_RET_FOUND_IMM(Pjp, offset); + } + + case cJ1_JPIMMED_6_02: + { + Word_t lsb; + JU_COPY6_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (6 * offset)); + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(6))) | lsb; + JU_RET_FOUND_IMM(Pjp, offset); + } + + case cJ1_JPIMMED_7_02: + { + Word_t lsb; + JU_COPY7_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (7 * offset)); + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(7))) | lsb; + JU_RET_FOUND_IMM(Pjp, offset); + } + +#endif // (JUDY1 && JU_64BIT) + + } // switch for not-found *PIndex + + JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // impossible? + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + + +// ---------------------------------------------------------------------------- +// BITMAP LEAF: +// +// Check Decode bytes, if any, in the current JP, then look in the leaf for +// *PIndex. + + case cJU_JPLEAF_B1: + { + Pjlb_t Pjlb; + CHECKDCD(1); + + Pjlb = P_JLB(Pjp->jp_Addr); + digit = JU_DIGITATSTATE(*PIndex, 1); + subexp = JU_SUBEXPL(digit); + bitposmask = JU_BITPOSMASKL(digit); + assert(subexp < cJU_NUMSUBEXPL); // falls in expected range. + +// *PIndex exists in LeafB1: + +// if (JU_BITMAPTESTL(Pjlb, digit)) // slower. + if (JU_JLB_BITMAP(Pjlb, subexp) & bitposmask) // faster. + { +#ifdef JUDYL // needs offset at this point: + offset = SEARCHBITMAPL(JU_JLB_BITMAP(Pjlb, subexp), digit, bitposmask); +#endif + JU_RET_FOUND_LEAF_B1(Pjlb, subexp, offset); +// == return((PPvoid_t) (P_JV(JL_JLB_PVALUE(Pjlb, subexp)) + (offset))); + } + +// Dead end, no Index in LeafB1 for remaining digit in *PIndex: +// +// If theres a next-left/right Index in the current LeafB1, which for +// Judy*Next() is true if any bits are set for higher Indexes, shortcut by +// returning it. Note: For Judy*Prev(), offset is set here to the correct +// value for the next-left JP. + + offset = SEARCHBITMAPL(JU_JLB_BITMAP(Pjlb, subexp), digit, + bitposmask); + // right range: + assert((offset >= -1) && (offset < (int) cJU_BITSPERSUBEXPL)); + +#ifdef JUDYPREV + if (offset >= 0) // next-left JP is in this subexpanse. + goto SM1LeafB1Findlimit; + + while (--subexp >= 0) // search next-left subexpanses. +#else + if (JU_JLB_BITMAP(Pjlb, subexp) & JU_MASKHIGHEREXC(bitposmask)) + { + ++offset; // next-left => next-right. + goto SM1LeafB1Findlimit; + } + + while (++subexp < cJU_NUMSUBEXPL) // search next-right subexps. +#endif + { + if (! JU_JLB_BITMAP(Pjlb, subexp)) continue; // empty subexp. + +#ifdef JUDYPREV + offset = SEARCHBITMAPMAXL(JU_JLB_BITMAP(Pjlb, subexp)); + // expected range: + assert((offset >= 0) && (offset < (int) cJU_BITSPERSUBEXPL)); +#else + offset = 0; +#endif + +// Save the next-left/right Indexess digit in *PIndex: + +SM1LeafB1Findlimit: + JU_BITMAPDIGITL(digit, subexp, JU_JLB_BITMAP(Pjlb, subexp), offset); + JU_SETDIGIT1(*PIndex, digit); + JU_RET_FOUND_LEAF_B1(Pjlb, subexp, offset); +// == return((PPvoid_t) (P_JV(JL_JLB_PVALUE(Pjlb, subexp)) + (offset))); + } + +// Theres no next-left/right Index in the LeafB1: +// +// Shortcut and start backtracking one level up; ignore the current Pjp because +// it points to a LeafB1 with no next-left/right Index. + + goto SM2Backtrack; + + } // case cJU_JPLEAF_B1 + +#ifdef JUDY1 +// ---------------------------------------------------------------------------- +// FULL POPULATION: +// +// If the Decode bytes match, *PIndex is found (without modification). + + case cJ1_JPFULLPOPU1: + + CHECKDCD(1); + JU_RET_FOUND_FULLPOPU1; +#endif + + +// ---------------------------------------------------------------------------- +// IMMEDIATE: + +#ifdef JUDYPREV +#define SM1IMM_SETPOP1(cPop1) +#else +#define SM1IMM_SETPOP1(cPop1) pop1 = (cPop1) +#endif + +#define SM1IMM(Func,cPop1) \ + SM1IMM_SETPOP1(cPop1); \ + offset = Func((Pjll_t) (PJI), cPop1, *PIndex); \ + goto SM1LeafLImm + +// Special case for Pop1 = 1 Immediate JPs: +// +// If *PIndex is in the immediate, offset is 0, otherwise the binary NOT of the +// offset where it belongs, 0 or 1, same as from the search functions. + +#ifdef JUDYPREV +#define SM1IMM_01_SETPOP1 +#else +#define SM1IMM_01_SETPOP1 pop1 = 1 +#endif + +#define SM1IMM_01 \ + SM1IMM_01_SETPOP1; \ + offset = ((JU_JPDCDPOP0(Pjp) < JU_TRIMTODCDSIZE(*PIndex)) ? ~1 : \ + (JU_JPDCDPOP0(Pjp) == JU_TRIMTODCDSIZE(*PIndex)) ? 0 : \ + ~0); \ + goto SM1LeafLImm + + case cJU_JPIMMED_1_01: + case cJU_JPIMMED_2_01: + case cJU_JPIMMED_3_01: +#ifdef JU_64BIT + case cJU_JPIMMED_4_01: + case cJU_JPIMMED_5_01: + case cJU_JPIMMED_6_01: + case cJU_JPIMMED_7_01: +#endif + SM1IMM_01; + +// TBD: Doug says it would be OK to have fewer calls and calculate arg 2, here +// and in Judy*Count() also. + + case cJU_JPIMMED_1_02: SM1IMM(j__udySearchLeaf1, 2); + case cJU_JPIMMED_1_03: SM1IMM(j__udySearchLeaf1, 3); +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_1_04: SM1IMM(j__udySearchLeaf1, 4); + case cJU_JPIMMED_1_05: SM1IMM(j__udySearchLeaf1, 5); + case cJU_JPIMMED_1_06: SM1IMM(j__udySearchLeaf1, 6); + case cJU_JPIMMED_1_07: SM1IMM(j__udySearchLeaf1, 7); +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_1_08: SM1IMM(j__udySearchLeaf1, 8); + case cJ1_JPIMMED_1_09: SM1IMM(j__udySearchLeaf1, 9); + case cJ1_JPIMMED_1_10: SM1IMM(j__udySearchLeaf1, 10); + case cJ1_JPIMMED_1_11: SM1IMM(j__udySearchLeaf1, 11); + case cJ1_JPIMMED_1_12: SM1IMM(j__udySearchLeaf1, 12); + case cJ1_JPIMMED_1_13: SM1IMM(j__udySearchLeaf1, 13); + case cJ1_JPIMMED_1_14: SM1IMM(j__udySearchLeaf1, 14); + case cJ1_JPIMMED_1_15: SM1IMM(j__udySearchLeaf1, 15); +#endif + +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_2_02: SM1IMM(j__udySearchLeaf2, 2); + case cJU_JPIMMED_2_03: SM1IMM(j__udySearchLeaf2, 3); +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_2_04: SM1IMM(j__udySearchLeaf2, 4); + case cJ1_JPIMMED_2_05: SM1IMM(j__udySearchLeaf2, 5); + case cJ1_JPIMMED_2_06: SM1IMM(j__udySearchLeaf2, 6); + case cJ1_JPIMMED_2_07: SM1IMM(j__udySearchLeaf2, 7); +#endif + +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_3_02: SM1IMM(j__udySearchLeaf3, 2); +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_3_03: SM1IMM(j__udySearchLeaf3, 3); + case cJ1_JPIMMED_3_04: SM1IMM(j__udySearchLeaf3, 4); + case cJ1_JPIMMED_3_05: SM1IMM(j__udySearchLeaf3, 5); + + case cJ1_JPIMMED_4_02: SM1IMM(j__udySearchLeaf4, 2); + case cJ1_JPIMMED_4_03: SM1IMM(j__udySearchLeaf4, 3); + + case cJ1_JPIMMED_5_02: SM1IMM(j__udySearchLeaf5, 2); + case cJ1_JPIMMED_5_03: SM1IMM(j__udySearchLeaf5, 3); + + case cJ1_JPIMMED_6_02: SM1IMM(j__udySearchLeaf6, 2); + + case cJ1_JPIMMED_7_02: SM1IMM(j__udySearchLeaf7, 2); +#endif + + +// ---------------------------------------------------------------------------- +// INVALID JP TYPE: + + default: JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + + } // SM1Get switch. + + /*NOTREACHED*/ + + +// ============================================================================ +// STATE MACHINE 2 -- BACKTRACK BRANCH TO PREVIOUS JP: +// +// Look for the next-left/right JP in a branch, backing up the history list as +// necessary. Upon finding a next-left/right JP, modify the corresponding +// digit in *PIndex before passing control to SM3Findlimit. +// +// Note: As described earlier, only branch JPs are expected here; other types +// fall into the default case. +// +// Note: If a found JP contains needed Dcd bytes, thats OK, theyre copied to +// *PIndex in SM3Findlimit. +// +// TBD: This code has a lot in common with similar code in the shortcut cases +// in SM1Get. Can combine this code somehow? +// +// ENTRY: List, possibly empty, of JPs and offsets in APjphist[] and +// Aoffhist[]; see earlier comments. +// +// EXIT: Execute JU_RET_NOTFOUND if no previous/next JP; otherwise jump to +// SM3Findlimit to resume a new but different downward search. + +SM2Backtrack: // come or return here for first/next sideways search. + + HISTPOP(Pjp, offset); + + switch (JU_JPTYPE(Pjp)) + { + + +// ---------------------------------------------------------------------------- +// LINEAR BRANCH: + + case cJU_JPBRANCH_L2: state = 2; goto SM2BranchL; + case cJU_JPBRANCH_L3: state = 3; goto SM2BranchL; +#ifdef JU_64BIT + case cJU_JPBRANCH_L4: state = 4; goto SM2BranchL; + case cJU_JPBRANCH_L5: state = 5; goto SM2BranchL; + case cJU_JPBRANCH_L6: state = 6; goto SM2BranchL; + case cJU_JPBRANCH_L7: state = 7; goto SM2BranchL; +#endif + case cJU_JPBRANCH_L: state = cJU_ROOTSTATE; goto SM2BranchL; + +SM2BranchL: +#ifdef JUDYPREV + if (--offset < 0) goto SM2Backtrack; // no next-left JP in BranchL. +#endif + Pjbl = P_JBL(Pjp->jp_Addr); +#ifdef JUDYNEXT + if (++offset >= (Pjbl->jbl_NumJPs)) goto SM2Backtrack; + // no next-right JP in BranchL. +#endif + +// Theres a next-left/right JP in the current BranchL; save its digit in +// *PIndex and continue with SM3Findlimit: + + JU_SETDIGIT(*PIndex, Pjbl->jbl_Expanse[offset], state); + Pjp = (Pjbl->jbl_jp) + offset; + goto SM3Findlimit; + + +// ---------------------------------------------------------------------------- +// BITMAP BRANCH: + + case cJU_JPBRANCH_B2: state = 2; goto SM2BranchB; + case cJU_JPBRANCH_B3: state = 3; goto SM2BranchB; +#ifdef JU_64BIT + case cJU_JPBRANCH_B4: state = 4; goto SM2BranchB; + case cJU_JPBRANCH_B5: state = 5; goto SM2BranchB; + case cJU_JPBRANCH_B6: state = 6; goto SM2BranchB; + case cJU_JPBRANCH_B7: state = 7; goto SM2BranchB; +#endif + case cJU_JPBRANCH_B: state = cJU_ROOTSTATE; goto SM2BranchB; + +SM2BranchB: + Pjbb = P_JBB(Pjp->jp_Addr); + HISTPOPBOFF(subexp, offset, digit); // unpack values. + +// If theres a next-left/right JP in the current BranchB, which for +// Judy*Next() is true if any bits are set for higher Indexes, continue to +// SM3Findlimit: +// +// Note: offset is set to the JP previously traversed; go one to the +// left/right. + +#ifdef JUDYPREV + if (offset > 0) // next-left JP is in this subexpanse. + { + --offset; + goto SM2BranchBFindlimit; + } + + while (--subexp >= 0) // search next-left subexpanses. +#else + if (JU_JBB_BITMAP(Pjbb, subexp) + & JU_MASKHIGHEREXC(JU_BITPOSMASKB(digit))) + { + ++offset; // next-left => next-right. + goto SM2BranchBFindlimit; + } + + while (++subexp < cJU_NUMSUBEXPB) // search next-right subexps. +#endif + { + if (! JU_JBB_PJP(Pjbb, subexp)) continue; // empty subexpanse. + +#ifdef JUDYPREV + offset = SEARCHBITMAPMAXB(JU_JBB_BITMAP(Pjbb, subexp)); + // expected range: + assert((offset >= 0) && (offset < cJU_BITSPERSUBEXPB)); +#else + offset = 0; +#endif + +// Save the next-left/right JPs digit in *PIndex: + +SM2BranchBFindlimit: + JU_BITMAPDIGITB(digit, subexp, JU_JBB_BITMAP(Pjbb, subexp), + offset); + JU_SETDIGIT(*PIndex, digit, state); + + if ((Pjp = P_JP(JU_JBB_PJP(Pjbb, subexp))) == (Pjp_t) NULL) + { + JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + } + + Pjp += offset; + goto SM3Findlimit; + } + +// Theres no next-left/right JP in the BranchB: + + goto SM2Backtrack; + + +// ---------------------------------------------------------------------------- +// UNCOMPRESSED BRANCH: + + case cJU_JPBRANCH_U2: state = 2; goto SM2BranchU; + case cJU_JPBRANCH_U3: state = 3; goto SM2BranchU; +#ifdef JU_64BIT + case cJU_JPBRANCH_U4: state = 4; goto SM2BranchU; + case cJU_JPBRANCH_U5: state = 5; goto SM2BranchU; + case cJU_JPBRANCH_U6: state = 6; goto SM2BranchU; + case cJU_JPBRANCH_U7: state = 7; goto SM2BranchU; +#endif + case cJU_JPBRANCH_U: state = cJU_ROOTSTATE; goto SM2BranchU; + +SM2BranchU: + +// Search for a next-left/right JP in the current BranchU, and if one is found, +// save its digit in *PIndex and continue to SM3Findlimit: + + Pjbu = P_JBU(Pjp->jp_Addr); + digit = offset; + +#ifdef JUDYPREV + while (digit >= 1) + { + Pjp = (Pjbu->jbu_jp) + (--digit); +#else + while (digit < cJU_BRANCHUNUMJPS - 1) + { + Pjp = (Pjbu->jbu_jp) + (++digit); +#endif + if (JPNULL(JU_JPTYPE(Pjp))) continue; + + JU_SETDIGIT(*PIndex, digit, state); + goto SM3Findlimit; + } + +// Theres no next-left/right JP in the BranchU: + + goto SM2Backtrack; + + +// ---------------------------------------------------------------------------- +// INVALID JP TYPE: + + default: JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + + } // SM2Backtrack switch. + + /*NOTREACHED*/ + + +// ============================================================================ +// STATE MACHINE 3 -- FIND LIMIT JP/INDEX: +// +// Look for the highest/lowest (right/left-most) JP in each branch and the +// highest/lowest Index in a leaf or immediate, and return it. While +// traversing, modify appropriate digit(s) in *PIndex to reflect the path +// taken, including Dcd bytes in each JP (which could hold critical missing +// digits for skipped branches). +// +// ENTRY: Pjp set to a JP under which to find max/min JPs (if a branch JP) or +// a max/min Index and return (if a leaf or immediate JP). +// +// EXIT: Execute JU_RET_FOUND* upon reaching a leaf or immediate. Should be +// impossible to fail, unless the Judy array is corrupt. + +SM3Findlimit: // come or return here for first/next branch/leaf. + + switch (JU_JPTYPE(Pjp)) + { +// ---------------------------------------------------------------------------- +// LINEAR BRANCH: +// +// Simply use the highest/lowest (right/left-most) JP in the BranchL, but first +// copy the Dcd bytes to *PIndex if there are any (only if state < +// cJU_ROOTSTATE - 1). + + case cJU_JPBRANCH_L2: SM3PREPB_DCD(2, SM3BranchL); +#ifndef JU_64BIT + case cJU_JPBRANCH_L3: SM3PREPB( 3, SM3BranchL); +#else + case cJU_JPBRANCH_L3: SM3PREPB_DCD(3, SM3BranchL); + case cJU_JPBRANCH_L4: SM3PREPB_DCD(4, SM3BranchL); + case cJU_JPBRANCH_L5: SM3PREPB_DCD(5, SM3BranchL); + case cJU_JPBRANCH_L6: SM3PREPB_DCD(6, SM3BranchL); + case cJU_JPBRANCH_L7: SM3PREPB( 7, SM3BranchL); +#endif + case cJU_JPBRANCH_L: SM3PREPB( cJU_ROOTSTATE, SM3BranchL); + +SM3BranchL: + Pjbl = P_JBL(Pjp->jp_Addr); + +#ifdef JUDYPREV + if ((offset = (Pjbl->jbl_NumJPs) - 1) < 0) +#else + offset = 0; if ((Pjbl->jbl_NumJPs) == 0) +#endif + { + JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + } + + JU_SETDIGIT(*PIndex, Pjbl->jbl_Expanse[offset], state); + Pjp = (Pjbl->jbl_jp) + offset; + goto SM3Findlimit; + + +// ---------------------------------------------------------------------------- +// BITMAP BRANCH: +// +// Look for the highest/lowest (right/left-most) non-null subexpanse, then use +// the highest/lowest JP in that subexpanse, but first copy Dcd bytes, if there +// are any (only if state < cJU_ROOTSTATE - 1), to *PIndex. + + case cJU_JPBRANCH_B2: SM3PREPB_DCD(2, SM3BranchB); +#ifndef JU_64BIT + case cJU_JPBRANCH_B3: SM3PREPB( 3, SM3BranchB); +#else + case cJU_JPBRANCH_B3: SM3PREPB_DCD(3, SM3BranchB); + case cJU_JPBRANCH_B4: SM3PREPB_DCD(4, SM3BranchB); + case cJU_JPBRANCH_B5: SM3PREPB_DCD(5, SM3BranchB); + case cJU_JPBRANCH_B6: SM3PREPB_DCD(6, SM3BranchB); + case cJU_JPBRANCH_B7: SM3PREPB( 7, SM3BranchB); +#endif + case cJU_JPBRANCH_B: SM3PREPB( cJU_ROOTSTATE, SM3BranchB); + +SM3BranchB: + Pjbb = P_JBB(Pjp->jp_Addr); +#ifdef JUDYPREV + subexp = cJU_NUMSUBEXPB; + + while (! (JU_JBB_BITMAP(Pjbb, --subexp))) // find non-empty subexp. + { + if (subexp <= 0) // wholly empty bitmap. + { + JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + } + } + + offset = SEARCHBITMAPMAXB(JU_JBB_BITMAP(Pjbb, subexp)); + // expected range: + assert((offset >= 0) && (offset < cJU_BITSPERSUBEXPB)); +#else + subexp = -1; + + while (! (JU_JBB_BITMAP(Pjbb, ++subexp))) // find non-empty subexp. + { + if (subexp >= cJU_NUMSUBEXPB - 1) // didnt find one. + { + JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + } + } + + offset = 0; +#endif + + JU_BITMAPDIGITB(digit, subexp, JU_JBB_BITMAP(Pjbb, subexp), offset); + JU_SETDIGIT(*PIndex, digit, state); + + if ((Pjp = P_JP(JU_JBB_PJP(Pjbb, subexp))) == (Pjp_t) NULL) + { + JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + } + + Pjp += offset; + goto SM3Findlimit; + + +// ---------------------------------------------------------------------------- +// UNCOMPRESSED BRANCH: +// +// Look for the highest/lowest (right/left-most) non-null JP, and use it, but +// first copy Dcd bytes to *PIndex if there are any (only if state < +// cJU_ROOTSTATE - 1). + + case cJU_JPBRANCH_U2: SM3PREPB_DCD(2, SM3BranchU); +#ifndef JU_64BIT + case cJU_JPBRANCH_U3: SM3PREPB( 3, SM3BranchU); +#else + case cJU_JPBRANCH_U3: SM3PREPB_DCD(3, SM3BranchU); + case cJU_JPBRANCH_U4: SM3PREPB_DCD(4, SM3BranchU); + case cJU_JPBRANCH_U5: SM3PREPB_DCD(5, SM3BranchU); + case cJU_JPBRANCH_U6: SM3PREPB_DCD(6, SM3BranchU); + case cJU_JPBRANCH_U7: SM3PREPB( 7, SM3BranchU); +#endif + case cJU_JPBRANCH_U: SM3PREPB( cJU_ROOTSTATE, SM3BranchU); + +SM3BranchU: + Pjbu = P_JBU(Pjp->jp_Addr); +#ifdef JUDYPREV + digit = cJU_BRANCHUNUMJPS; + + while (digit >= 1) + { + Pjp = (Pjbu->jbu_jp) + (--digit); +#else + + for (digit = 0; digit < cJU_BRANCHUNUMJPS; ++digit) + { + Pjp = (Pjbu->jbu_jp) + digit; +#endif + if (JPNULL(JU_JPTYPE(Pjp))) continue; + + JU_SETDIGIT(*PIndex, digit, state); + goto SM3Findlimit; + } + +// No non-null JPs in BranchU: + + JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + + +// ---------------------------------------------------------------------------- +// LINEAR LEAF: +// +// Simply use the highest/lowest (right/left-most) Index in the LeafL, but the +// details vary depending on leaf Index Size. First copy Dcd bytes, if there +// are any (only if state < cJU_ROOTSTATE - 1), to *PIndex. + +#define SM3LEAFLDCD(cState) \ + JU_SETDCD(*PIndex, Pjp, cState); \ + SM3LEAFLNODCD + +#ifdef JUDY1 +#define SM3LEAFL_SETPOP1 // not needed in any cases. +#else +#define SM3LEAFL_SETPOP1 pop1 = JU_JPLEAF_POP0(Pjp) + 1 +#endif + +#ifdef JUDYPREV +#define SM3LEAFLNODCD \ + Pjll = P_JLL(Pjp->jp_Addr); \ + SM3LEAFL_SETPOP1; \ + offset = JU_JPLEAF_POP0(Pjp); assert(offset >= 0) +#else +#define SM3LEAFLNODCD \ + Pjll = P_JLL(Pjp->jp_Addr); \ + SM3LEAFL_SETPOP1; \ + offset = 0; assert(JU_JPLEAF_POP0(Pjp) >= 0); +#endif + +#if (defined(JUDYL) || (! defined(JU_64BIT))) + case cJU_JPLEAF1: + + SM3LEAFLDCD(1); + JU_SETDIGIT1(*PIndex, ((uint8_t *) Pjll)[offset]); + JU_RET_FOUND_LEAF1(Pjll, pop1, offset); +#endif + + case cJU_JPLEAF2: + + SM3LEAFLDCD(2); + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(2))) + | ((uint16_t *) Pjll)[offset]; + JU_RET_FOUND_LEAF2(Pjll, pop1, offset); + +#ifndef JU_64BIT + case cJU_JPLEAF3: + { + Word_t lsb; + SM3LEAFLNODCD; + JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (3 * offset)); + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb; + JU_RET_FOUND_LEAF3(Pjll, pop1, offset); + } + +#else + case cJU_JPLEAF3: + { + Word_t lsb; + SM3LEAFLDCD(3); + JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (3 * offset)); + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb; + JU_RET_FOUND_LEAF3(Pjll, pop1, offset); + } + + case cJU_JPLEAF4: + + SM3LEAFLDCD(4); + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(4))) + | ((uint32_t *) Pjll)[offset]; + JU_RET_FOUND_LEAF4(Pjll, pop1, offset); + + case cJU_JPLEAF5: + { + Word_t lsb; + SM3LEAFLDCD(5); + JU_COPY5_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (5 * offset)); + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(5))) | lsb; + JU_RET_FOUND_LEAF5(Pjll, pop1, offset); + } + + case cJU_JPLEAF6: + { + Word_t lsb; + SM3LEAFLDCD(6); + JU_COPY6_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (6 * offset)); + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(6))) | lsb; + JU_RET_FOUND_LEAF6(Pjll, pop1, offset); + } + + case cJU_JPLEAF7: + { + Word_t lsb; + SM3LEAFLNODCD; + JU_COPY7_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (7 * offset)); + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(7))) | lsb; + JU_RET_FOUND_LEAF7(Pjll, pop1, offset); + } +#endif + + +// ---------------------------------------------------------------------------- +// BITMAP LEAF: +// +// Look for the highest/lowest (right/left-most) non-null subexpanse, then use +// the highest/lowest Index in that subexpanse, but first copy Dcd bytes +// (always present since state 1 < cJU_ROOTSTATE) to *PIndex. + + case cJU_JPLEAF_B1: + { + Pjlb_t Pjlb; + + JU_SETDCD(*PIndex, Pjp, 1); + + Pjlb = P_JLB(Pjp->jp_Addr); +#ifdef JUDYPREV + subexp = cJU_NUMSUBEXPL; + + while (! JU_JLB_BITMAP(Pjlb, --subexp)) // find non-empty subexp. + { + if (subexp <= 0) // wholly empty bitmap. + { + JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + } + } + +// TBD: Might it be faster to just use a variant of BITMAPDIGIT*() that yields +// the digit for the right-most Index with a bit set? + + offset = SEARCHBITMAPMAXL(JU_JLB_BITMAP(Pjlb, subexp)); + // expected range: + assert((offset >= 0) && (offset < cJU_BITSPERSUBEXPL)); +#else + subexp = -1; + + while (! JU_JLB_BITMAP(Pjlb, ++subexp)) // find non-empty subexp. + { + if (subexp >= cJU_NUMSUBEXPL - 1) // didnt find one. + { + JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + } + } + + offset = 0; +#endif + + JU_BITMAPDIGITL(digit, subexp, JU_JLB_BITMAP(Pjlb, subexp), offset); + JU_SETDIGIT1(*PIndex, digit); + JU_RET_FOUND_LEAF_B1(Pjlb, subexp, offset); +// == return((PPvoid_t) (P_JV(JL_JLB_PVALUE(Pjlb, subexp)) + (offset))); + + } // case cJU_JPLEAF_B1 + +#ifdef JUDY1 +// ---------------------------------------------------------------------------- +// FULL POPULATION: +// +// Copy Dcd bytes to *PIndex (always present since state 1 < cJU_ROOTSTATE), +// then set the highest/lowest possible digit as the LSB in *PIndex. + + case cJ1_JPFULLPOPU1: + + JU_SETDCD( *PIndex, Pjp, 1); +#ifdef JUDYPREV + JU_SETDIGIT1(*PIndex, cJU_BITSPERBITMAP - 1); +#else + JU_SETDIGIT1(*PIndex, 0); +#endif + JU_RET_FOUND_FULLPOPU1; +#endif // JUDY1 + + +// ---------------------------------------------------------------------------- +// IMMEDIATE: +// +// Simply use the highest/lowest (right/left-most) Index in the Imm, but the +// details vary depending on leaf Index Size and pop1. Note: There are no Dcd +// bytes in an Immediate JP, but in a cJU_JPIMMED_*_01 JP, the field holds the +// least bytes of the immediate Index. + + case cJU_JPIMMED_1_01: SET_01(1); goto SM3Imm_01; + case cJU_JPIMMED_2_01: SET_01(2); goto SM3Imm_01; + case cJU_JPIMMED_3_01: SET_01(3); goto SM3Imm_01; +#ifdef JU_64BIT + case cJU_JPIMMED_4_01: SET_01(4); goto SM3Imm_01; + case cJU_JPIMMED_5_01: SET_01(5); goto SM3Imm_01; + case cJU_JPIMMED_6_01: SET_01(6); goto SM3Imm_01; + case cJU_JPIMMED_7_01: SET_01(7); goto SM3Imm_01; +#endif +SM3Imm_01: JU_RET_FOUND_IMM_01(Pjp); + +#ifdef JUDYPREV +#define SM3IMM_OFFSET(cPop1) (cPop1) - 1 // highest. +#else +#define SM3IMM_OFFSET(cPop1) 0 // lowest. +#endif + +#define SM3IMM(cPop1,Next) \ + offset = SM3IMM_OFFSET(cPop1); \ + goto Next + + case cJU_JPIMMED_1_02: SM3IMM( 2, SM3Imm1); + case cJU_JPIMMED_1_03: SM3IMM( 3, SM3Imm1); +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_1_04: SM3IMM( 4, SM3Imm1); + case cJU_JPIMMED_1_05: SM3IMM( 5, SM3Imm1); + case cJU_JPIMMED_1_06: SM3IMM( 6, SM3Imm1); + case cJU_JPIMMED_1_07: SM3IMM( 7, SM3Imm1); +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_1_08: SM3IMM( 8, SM3Imm1); + case cJ1_JPIMMED_1_09: SM3IMM( 9, SM3Imm1); + case cJ1_JPIMMED_1_10: SM3IMM(10, SM3Imm1); + case cJ1_JPIMMED_1_11: SM3IMM(11, SM3Imm1); + case cJ1_JPIMMED_1_12: SM3IMM(12, SM3Imm1); + case cJ1_JPIMMED_1_13: SM3IMM(13, SM3Imm1); + case cJ1_JPIMMED_1_14: SM3IMM(14, SM3Imm1); + case cJ1_JPIMMED_1_15: SM3IMM(15, SM3Imm1); +#endif + +SM3Imm1: JU_SETDIGIT1(*PIndex, ((uint8_t *) PJI)[offset]); + JU_RET_FOUND_IMM(Pjp, offset); + +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_2_02: SM3IMM(2, SM3Imm2); + case cJU_JPIMMED_2_03: SM3IMM(3, SM3Imm2); +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_2_04: SM3IMM(4, SM3Imm2); + case cJ1_JPIMMED_2_05: SM3IMM(5, SM3Imm2); + case cJ1_JPIMMED_2_06: SM3IMM(6, SM3Imm2); + case cJ1_JPIMMED_2_07: SM3IMM(7, SM3Imm2); +#endif + +#if (defined(JUDY1) || defined(JU_64BIT)) +SM3Imm2: *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(2))) + | ((uint16_t *) PJI)[offset]; + JU_RET_FOUND_IMM(Pjp, offset); +#endif + +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_3_02: SM3IMM(2, SM3Imm3); +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_3_03: SM3IMM(3, SM3Imm3); + case cJ1_JPIMMED_3_04: SM3IMM(4, SM3Imm3); + case cJ1_JPIMMED_3_05: SM3IMM(5, SM3Imm3); +#endif + +#if (defined(JUDY1) || defined(JU_64BIT)) +SM3Imm3: + { + Word_t lsb; + JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (3 * offset)); + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb; + JU_RET_FOUND_IMM(Pjp, offset); + } +#endif + +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_4_02: SM3IMM(2, SM3Imm4); + case cJ1_JPIMMED_4_03: SM3IMM(3, SM3Imm4); + +SM3Imm4: *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(4))) + | ((uint32_t *) PJI)[offset]; + JU_RET_FOUND_IMM(Pjp, offset); + + case cJ1_JPIMMED_5_02: SM3IMM(2, SM3Imm5); + case cJ1_JPIMMED_5_03: SM3IMM(3, SM3Imm5); + +SM3Imm5: + { + Word_t lsb; + JU_COPY5_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (5 * offset)); + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(5))) | lsb; + JU_RET_FOUND_IMM(Pjp, offset); + } + + case cJ1_JPIMMED_6_02: SM3IMM(2, SM3Imm6); + +SM3Imm6: + { + Word_t lsb; + JU_COPY6_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (6 * offset)); + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(6))) | lsb; + JU_RET_FOUND_IMM(Pjp, offset); + } + + case cJ1_JPIMMED_7_02: SM3IMM(2, SM3Imm7); + +SM3Imm7: + { + Word_t lsb; + JU_COPY7_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (7 * offset)); + *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(7))) | lsb; + JU_RET_FOUND_IMM(Pjp, offset); + } +#endif // (JUDY1 && JU_64BIT) + + +// ---------------------------------------------------------------------------- +// OTHER CASES: + + default: JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); + JUDY1CODE(return(JERRI );) + JUDYLCODE(return(PPJERR);) + + } // SM3Findlimit switch. + + /*NOTREACHED*/ + +} // Judy1Prev() / Judy1Next() / JudyLPrev() / JudyLNext() diff --git a/feeds/p4/libjudy/src/src/JudyCommon/JudyPrevNextEmpty.c b/feeds/p4/libjudy/src/src/JudyCommon/JudyPrevNextEmpty.c new file mode 100644 index 000000000..4da43565d --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudyCommon/JudyPrevNextEmpty.c @@ -0,0 +1,1390 @@ +// Copyright (C) 2000 - 2002 Hewlett-Packard Company +// +// This program is free software; you can redistribute it and/or modify it +// under the term of the GNU Lesser 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 Lesser General Public License +// for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// _________________ + +// @(#) $Revision: 4.32 $ $Source: /judy/src/JudyCommon/JudyPrevNextEmpty.c $ +// +// Judy*PrevEmpty() and Judy*NextEmpty() functions for Judy1 and JudyL. +// Compile with one of -DJUDY1 or -DJUDYL. +// +// Compile with -DJUDYNEXT for the Judy*NextEmpty() function; otherwise +// defaults to Judy*PrevEmpty(). +// +// Compile with -DTRACEJPSE to trace JP traversals. +// +// This file is separate from JudyPrevNext.c because it differs too greatly for +// ifdefs. This might be a bit surprising, but there are two reasons: +// +// - First, down in the details, searching for an empty index (SearchEmpty) is +// remarkably asymmetric with searching for a valid index (SearchValid), +// mainly with respect to: No return of a value area for JudyL; partially- +// full versus totally-full JPs; and handling of narrow pointers. +// +// - Second, we chose to implement SearchEmpty without a backtrack stack or +// backtrack engine, partly as an experiment, and partly because we think +// restarting from the top of the tree is less likely for SearchEmpty than +// for SearchValid, because empty indexes are more likely than valid indexes. +// +// A word about naming: A prior version of this feature (see 4.13) was named +// Judy*Free(), but there were concerns about that being read as a verb rather +// than an adjective. After prolonged debate and based on user input, we +// changed "Free" to "Empty". + +#if (! (defined(JUDY1) || defined(JUDYL))) +#error: One of -DJUDY1 or -DJUDYL must be specified. +#endif + +#ifndef JUDYNEXT +#ifndef JUDYPREV +#define JUDYPREV 1 // neither set => use default. +#endif +#endif + +#ifdef JUDY1 +#include "Judy1.h" +#else +#include "JudyL.h" +#endif + +#include "JudyPrivate1L.h" + +#ifdef TRACEJPSE +#include "JudyPrintJP.c" +#endif + + +// **************************************************************************** +// J U D Y 1 P R E V E M P T Y +// J U D Y 1 N E X T E M P T Y +// J U D Y L P R E V E M P T Y +// J U D Y L N E X T E M P T Y +// +// See the manual entry for the API. +// +// OVERVIEW OF Judy*PrevEmpty() / Judy*NextEmpty(): +// +// See also for comparison the equivalent comments in JudyPrevNext.c. +// +// Take the callers *PIndex and subtract/add 1, but watch out for +// underflow/overflow, which means "no previous/next empty index found." Use a +// reentrant switch statement (state machine, see SMGetRestart and +// SMGetContinue) to decode Index, starting with the JRP (PArray), through a +// JPM and branches, if any, down to an immediate or a leaf. Look for Index in +// that immediate or leaf, and if not found (invalid index), return success +// (Index is empty). +// +// This search can result in a dead end where taking a different path is +// required. There are four kinds of dead ends: +// +// BRANCH PRIMARY dead end: Encountering a fully-populated JP for the +// appropriate digit in Index. Search sideways in the branch for the +// previous/next absent/null/non-full JP, and if one is found, set Index to the +// highest/lowest index possible in that JPs expanse. Then if the JP is an +// absent or null JP, return success; otherwise for a non-full JP, traverse +// through the partially populated JP. +// +// BRANCH SECONDARY dead end: Reaching the end of a branch during a sideways +// search after a branch primary dead end. Set Index to the lowest/highest +// index possible in the whole branchs expanse (one higher/lower than the +// previous/next branchs expanse), then restart at the top of the tree, which +// includes pre-decrementing/incrementing Index (again) and watching for +// underflow/overflow (again). +// +// LEAF PRIMARY dead end: Finding a valid (non-empty) index in an immediate or +// leaf matching Index. Search sideways in the immediate/leaf for the +// previous/next empty index; if found, set *PIndex to match and return success. +// +// LEAF SECONDARY dead end: Reaching the end of an immediate or leaf during a +// sideways search after a leaf primary dead end. Just as for a branch +// secondary dead end, restart at the top of the tree with Index set to the +// lowest/highest index possible in the whole immediate/leafs expanse. +// TBD: If leaf secondary dead end occurs, could shortcut and treat it as a +// branch primary dead end; but this would require remembering the parent +// branchs type and offset (a "one-deep stack"), and also wrestling with +// narrow pointers, at least for leaves (but not for immediates). +// +// Note some ASYMMETRIES between SearchValid and SearchEmpty: +// +// - The SearchValid code, upon descending through a narrow pointer, if Index +// is outside the expanse of the subsidiary node (effectively a secondary +// dead end), must decide whether to backtrack or findlimit. But the +// SearchEmpty code simply returns success (Index is empty). +// +// - Similarly, the SearchValid code, upon finding no previous/next index in +// the expanse of a narrow pointer (again, a secondary dead end), can simply +// start to backtrack at the parent JP. But the SearchEmpty code would have +// to first determine whether or not the parent JPs narrow expanse contains +// a previous/next empty index outside the subexpanse. Rather than keeping a +// parent state stack and backtracking this way, upon a secondary dead end, +// the SearchEmpty code simply restarts at the top of the tree, whether or +// not a narrow pointer is involved. Again, see the equivalent comments in +// JudyPrevNext.c for comparison. +// +// This function is written iteratively for speed, rather than recursively. +// +// TBD: Wed like to enhance this function to make successive searches faster. +// This would require saving some previous state, including the previous Index +// returned, and in which leaf it was found. If the next call is for the same +// Index and the array has not been modified, start at the same leaf. This +// should be much easier to implement since this is iterative rather than +// recursive code. + +#ifdef JUDY1 +#ifdef JUDYPREV +FUNCTION int Judy1PrevEmpty +#else +FUNCTION int Judy1NextEmpty +#endif +#else +#ifdef JUDYPREV +FUNCTION int JudyLPrevEmpty +#else +FUNCTION int JudyLNextEmpty +#endif +#endif + ( + Pcvoid_t PArray, // Judy array to search. + Word_t * PIndex, // starting point and result. + PJError_t PJError // optional, for returning error info. + ) +{ + Word_t Index; // fast copy, in a register. + Pjp_t Pjp; // current JP. + Pjbl_t Pjbl; // Pjp->jp_Addr masked and cast to types: + Pjbb_t Pjbb; + Pjbu_t Pjbu; + Pjlb_t Pjlb; + PWord_t Pword; // alternate name for use by GET* macros. + + Word_t digit; // next digit to decode from Index. + Word_t digits; // current state in SM = digits left to decode. + Word_t pop0; // in a leaf. + Word_t pop0mask; // precalculated to avoid variable shifts. + long offset; // within a branch or leaf (can be large). + int subexp; // subexpanse in a bitmap branch. + BITMAPB_t bitposmaskB; // bit in bitmap for bitmap branch. + BITMAPL_t bitposmaskL; // bit in bitmap for bitmap leaf. + Word_t possfullJP1; // JP types for possibly full subexpanses: + Word_t possfullJP2; + Word_t possfullJP3; + + +// ---------------------------------------------------------------------------- +// M A C R O S +// +// These are intended to make the code a bit more readable and less redundant. + + +// CHECK FOR NULL JP: +// +// TBD: In principle this can be reduced (here and in other *.c files) to just +// the latter clause since no Type should ever be below cJU_JPNULL1, but in +// fact some root pointer types can be lower, so for safety do both checks. + +#define JPNULL(Type) (((Type) >= cJU_JPNULL1) && ((Type) <= cJU_JPNULLMAX)) + + +// CHECK FOR A FULL JP: +// +// Given a JP, indicate if it is fully populated. Use digits, pop0mask, and +// possfullJP1..3 in the context. +// +// This is a difficult problem because it requires checking the Pop0 bits for +// all-ones, but the number of bytes depends on the JP type, which is not +// directly related to the parent branchs type or level -- the JPs child +// could be under a narrow pointer (hence not full). The simple answer +// requires switching on or otherwise calculating the JP type, which could be +// slow. Instead, in SMPREPB* precalculate pop0mask and also record in +// possfullJP1..3 the child JP (branch) types that could possibly be full (one +// level down), and use them here. For level-2 branches (with digits == 2), +// the test for a full child depends on Judy1/JudyL. +// +// Note: This cannot be applied to the JP in a JPM because it doesnt have +// enough pop0 digits. +// +// TBD: JPFULL_BRANCH diligently checks for BranchL or BranchB, where neither +// of those can ever be full as it turns out. Could just check for a BranchU +// at the right level. Also, pop0mask might be overkill, its not used much, +// so perhaps just call cJU_POP0MASK(digits - 1) here? +// +// First, JPFULL_BRANCH checks for a full expanse for a JP whose child can be a +// branch, that is, a JP in a branch at level 3 or higher: + +#define JPFULL_BRANCH(Pjp) \ + ((((JU_JPDCDPOP0(Pjp) ^ cJU_ALLONES) & pop0mask) == 0) \ + && ((JU_JPTYPE(Pjp) == possfullJP1) \ + || (JU_JPTYPE(Pjp) == possfullJP2) \ + || (JU_JPTYPE(Pjp) == possfullJP3))) + +#ifdef JUDY1 +#define JPFULL(Pjp) \ + ((digits == 2) ? \ + (JU_JPTYPE(Pjp) == cJ1_JPFULLPOPU1) : JPFULL_BRANCH(Pjp)) +#else +#define JPFULL(Pjp) \ + ((digits == 2) ? \ + (JU_JPTYPE(Pjp) == cJU_JPLEAF_B1) \ + && (((JU_JPDCDPOP0(Pjp) & cJU_POP0MASK(1)) == cJU_POP0MASK(1))) : \ + JPFULL_BRANCH(Pjp)) +#endif + + +// RETURN SUCCESS: +// +// This hides the need to set *PIndex back to the local value of Index -- use a +// local value for faster operation. Note that the callers *PIndex is ALWAYS +// modified upon success, at least decremented/incremented. + +#define RET_SUCCESS { *PIndex = Index; return(1); } + + +// RETURN A CORRUPTION: + +#define RET_CORRUPT { JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); return(JERRI); } + + +// SEARCH A BITMAP BRANCH: +// +// This is a weak analog of j__udySearchLeaf*() for bitmap branches. Return +// the actual or next-left position, base 0, of Digit in a BITMAPB_t bitmap +// (subexpanse of a full bitmap), also given a Bitposmask for Digit. The +// position is the offset within the set bits. +// +// Unlike j__udySearchLeaf*(), the offset is not returned bit-complemented if +// Digits bit is unset, because the caller can check the bitmap themselves to +// determine that. Also, if Digits bit is unset, the returned offset is to +// the next-left JP or index (including -1), not to the "ideal" position for +// the index = next-right JP or index. +// +// Shortcut and skip calling j__udyCountBitsB() if the bitmap is full, in which +// case (Digit % cJU_BITSPERSUBEXPB) itself is the base-0 offset. + +#define SEARCHBITMAPB(Bitmap,Digit,Bitposmask) \ + (((Bitmap) == cJU_FULLBITMAPB) ? (Digit % cJU_BITSPERSUBEXPB) : \ + j__udyCountBitsB((Bitmap) & JU_MASKLOWERINC(Bitposmask)) - 1) + +#ifdef JUDYPREV +// Equivalent to search for the highest offset in Bitmap, that is, one less +// than the number of bits set: + +#define SEARCHBITMAPMAXB(Bitmap) \ + (((Bitmap) == cJU_FULLBITMAPB) ? cJU_BITSPERSUBEXPB - 1 : \ + j__udyCountBitsB(Bitmap) - 1) +#endif + + +// CHECK DECODE BYTES: +// +// Check Decode bytes in a JP against the equivalent portion of Index. If they +// dont match, Index is outside the subexpanse of a narrow pointer, hence is +// empty. + +#define CHECKDCD(cDigits) \ + if (JU_DCDNOTMATCHINDEX(Index, Pjp, cDigits)) RET_SUCCESS + + +// REVISE REMAINDER OF INDEX: +// +// Put one digit in place in Index and clear/set the lower digits, if any, so +// the resulting Index is at the start/end of an expanse, or just clear/set the +// least digits. +// +// Actually, to make simple use of JU_LEASTBYTESMASK, first clear/set all least +// digits of Index including the digit to be overridden, then set the value of +// that one digit. If Digits == 1 the first operation is redundant, but either +// very fast or even removed by the optimizer. + +#define CLEARLEASTDIGITS(Digits) Index &= ~JU_LEASTBYTESMASK(Digits) +#define SETLEASTDIGITS( Digits) Index |= JU_LEASTBYTESMASK(Digits) + +#define CLEARLEASTDIGITS_D(Digit,Digits) \ + { \ + CLEARLEASTDIGITS(Digits); \ + JU_SETDIGIT(Index, Digit, Digits); \ + } + +#define SETLEASTDIGITS_D(Digit,Digits) \ + { \ + SETLEASTDIGITS(Digits); \ + JU_SETDIGIT(Index, Digit, Digits); \ + } + + +// SET REMAINDER OF INDEX AND THEN RETURN OR CONTINUE: + +#define SET_AND_RETURN(OpLeastDigits,Digit,Digits) \ + { \ + OpLeastDigits(Digit, Digits); \ + RET_SUCCESS; \ + } + +#define SET_AND_CONTINUE(OpLeastDigits,Digit,Digits) \ + { \ + OpLeastDigits(Digit, Digits); \ + goto SMGetContinue; \ + } + + +// PREPARE TO HANDLE A LEAFW OR JP BRANCH IN THE STATE MACHINE: +// +// Extract a state-dependent digit from Index in a "constant" way, then jump to +// common code for multiple cases. +// +// TBD: Should this macro do more, such as preparing variable-shift masks for +// use in CLEARLEASTDIGITS and SETLEASTDIGITS? + +#define SMPREPB(cDigits,Next,PossFullJP1,PossFullJP2,PossFullJP3) \ + digits = (cDigits); \ + digit = JU_DIGITATSTATE(Index, cDigits); \ + pop0mask = cJU_POP0MASK((cDigits) - 1); /* for branchs JPs */ \ + possfullJP1 = (PossFullJP1); \ + possfullJP2 = (PossFullJP2); \ + possfullJP3 = (PossFullJP3); \ + goto Next + +// Variations for specific-level branches and for shorthands: +// +// Note: SMPREPB2 need not initialize possfullJP* because JPFULL does not use +// them for digits == 2, but gcc -Wall isnt quite smart enough to see this, so +// waste a bit of time and space to get rid of the warning: + +#define SMPREPB2(Next) \ + digits = 2; \ + digit = JU_DIGITATSTATE(Index, 2); \ + pop0mask = cJU_POP0MASK(1); /* for branchs JPs */ \ + possfullJP1 = possfullJP2 = possfullJP3 = 0; \ + goto Next + +#define SMPREPB3(Next) SMPREPB(3, Next, cJU_JPBRANCH_L2, \ + cJU_JPBRANCH_B2, \ + cJU_JPBRANCH_U2) +#ifndef JU_64BIT +#define SMPREPBL(Next) SMPREPB(cJU_ROOTSTATE, Next, cJU_JPBRANCH_L3, \ + cJU_JPBRANCH_B3, \ + cJU_JPBRANCH_U3) +#else +#define SMPREPB4(Next) SMPREPB(4, Next, cJU_JPBRANCH_L3, \ + cJU_JPBRANCH_B3, \ + cJU_JPBRANCH_U3) +#define SMPREPB5(Next) SMPREPB(5, Next, cJU_JPBRANCH_L4, \ + cJU_JPBRANCH_B4, \ + cJU_JPBRANCH_U4) +#define SMPREPB6(Next) SMPREPB(6, Next, cJU_JPBRANCH_L5, \ + cJU_JPBRANCH_B5, \ + cJU_JPBRANCH_U5) +#define SMPREPB7(Next) SMPREPB(7, Next, cJU_JPBRANCH_L6, \ + cJU_JPBRANCH_B6, \ + cJU_JPBRANCH_U6) +#define SMPREPBL(Next) SMPREPB(cJU_ROOTSTATE, Next, cJU_JPBRANCH_L7, \ + cJU_JPBRANCH_B7, \ + cJU_JPBRANCH_U7) +#endif + + +// RESTART AFTER SECONDARY DEAD END: +// +// Set Index to the first/last index in the branch or leaf subexpanse and start +// over at the top of the tree. + +#ifdef JUDYPREV +#define SMRESTART(Digits) { CLEARLEASTDIGITS(Digits); goto SMGetRestart; } +#else +#define SMRESTART(Digits) { SETLEASTDIGITS( Digits); goto SMGetRestart; } +#endif + + +// CHECK EDGE OF LEAFS EXPANSE: +// +// Given the LSBs of the lowest/highest valid index in a leaf (or equivalently +// in an immediate JP), the level (index size) of the leaf, and the full index +// to return (as Index in the context) already set to the full index matching +// the lowest/highest one, determine if there is an empty index in the leafs +// expanse below/above the lowest/highest index, which is true if the +// lowest/highest index is not at the "edge" of the leafs expanse based on its +// LSBs. If so, return Index decremented/incremented; otherwise restart at the +// top of the tree. +// +// Note: In many cases Index is already at the right spot and calling +// SMRESTART instead of just going directly to SMGetRestart is a bit of +// overkill. +// +// Note: Variable shift occurs if Digits is not a constant. + +#ifdef JUDYPREV +#define LEAF_EDGE(MinIndex,Digits) \ + { \ + if (MinIndex) { --Index; RET_SUCCESS; } \ + SMRESTART(Digits); \ + } +#else +#define LEAF_EDGE(MaxIndex,Digits) \ + { \ + if ((MaxIndex) != JU_LEASTBYTES(cJU_ALLONES, Digits)) \ + { ++Index; RET_SUCCESS; } \ + SMRESTART(Digits); \ + } +#endif + +// Same as above except Index is not already set to match the lowest/highest +// index, so do that before decrementing/incrementing it: + +#ifdef JUDYPREV +#define LEAF_EDGE_SET(MinIndex,Digits) \ + { \ + if (MinIndex) \ + { JU_SETDIGITS(Index, MinIndex, Digits); --Index; RET_SUCCESS; } \ + SMRESTART(Digits); \ + } +#else +#define LEAF_EDGE_SET(MaxIndex,Digits) \ + { \ + if ((MaxIndex) != JU_LEASTBYTES(cJU_ALLONES, Digits)) \ + { JU_SETDIGITS(Index, MaxIndex, Digits); ++Index; RET_SUCCESS; } \ + SMRESTART(Digits); \ + } +#endif + + +// FIND A HOLE (EMPTY INDEX) IN AN IMMEDIATE OR LEAF: +// +// Given an index location in a leaf (or equivalently an immediate JP) known to +// contain a usable hole (an empty index less/greater than Index), and the LSBs +// of a minimum/maximum index to locate, find the previous/next empty index and +// return it. +// +// Note: "Even" index sizes (1,2,4[,8] bytes) have corresponding native C +// types; "odd" index sizes dont, but they are not represented here because +// they are handled completely differently; see elsewhere. + +#ifdef JUDYPREV + +#define LEAF_HOLE_EVEN(cDigits,Pjll,IndexLSB) \ + { \ + while (*(Pjll) > (IndexLSB)) --(Pjll); /* too high */ \ + if (*(Pjll) < (IndexLSB)) RET_SUCCESS /* Index is empty */ \ + while (*(--(Pjll)) == --(IndexLSB)) /* null, find a hole */;\ + JU_SETDIGITS(Index, IndexLSB, cDigits); \ + RET_SUCCESS; \ + } +#else +#define LEAF_HOLE_EVEN(cDigits,Pjll,IndexLSB) \ + { \ + while (*(Pjll) < (IndexLSB)) ++(Pjll); /* too low */ \ + if (*(Pjll) > (IndexLSB)) RET_SUCCESS /* Index is empty */ \ + while (*(++(Pjll)) == ++(IndexLSB)) /* null, find a hole */;\ + JU_SETDIGITS(Index, IndexLSB, cDigits); \ + RET_SUCCESS; \ + } +#endif + + +// SEARCH FOR AN EMPTY INDEX IN AN IMMEDIATE OR LEAF: +// +// Given a pointer to the first index in a leaf (or equivalently an immediate +// JP), the population of the leaf, and a first empty Index to find (inclusive, +// as Index in the context), where Index is known to fall within the expanse of +// the leaf to search, efficiently find the previous/next empty index in the +// leaf, if any. For simplicity the following overview is stated in terms of +// Judy*NextEmpty() only, but the same concepts apply symmetrically for +// Judy*PrevEmpty(). Also, in each case the comparisons are for the LSBs of +// Index and leaf indexes, according to the leafs level. +// +// 1. If Index is GREATER than the last (highest) index in the leaf +// (maxindex), return success, Index is empty. (Remember, Index is known +// to be in the leafs expanse.) +// +// 2. If Index is EQUAL to maxindex: If maxindex is not at the edge of the +// leafs expanse, increment Index and return success, there is an empty +// Index one higher than any in the leaf; otherwise restart with Index +// reset to the upper edge of the leafs expanse. Note: This might cause +// an extra cache line fill, but this is OK for repeatedly-called search +// code, and it saves CPU time. +// +// 3. If Index is LESS than maxindex, check for "dense to end of leaf": +// Subtract Index from maxindex, and back up that many slots in the leaf. +// If the resulting offset is not before the start of the leaf then compare +// the index at this offset (baseindex) with Index: +// +// 3a. If GREATER, the leaf must be corrupt, since indexes are sorted and +// there are no duplicates. +// +// 3b. If EQUAL, the leaf is "dense" from Index to maxindex, meaning there is +// no reason to search it. "Slide right" to the high end of the leaf +// (modify Index to maxindex) and continue with step 2 above. +// +// 3c. If LESS, continue with step 4. +// +// 4. If the offset based on maxindex minus Index falls BEFORE the start of +// the leaf, or if, per 3c above, baseindex is LESS than Index, the leaf is +// guaranteed "not dense to the end" and a usable empty Index must exist. +// This supports a more efficient search loop. Start at the FIRST index in +// the leaf, or one BEYOND baseindex, respectively, and search the leaf as +// follows, comparing each current index (currindex) with Index: +// +// 4a. If LESS, keep going to next index. Note: This is certain to terminate +// because maxindex is known to be greater than Index, hence the loop can +// be small and fast. +// +// 4b. If EQUAL, loop and increment Index until finding currindex greater than +// Index, and return success with the modified Index. +// +// 4c. If GREATER, return success, Index (unmodified) is empty. +// +// Note: These are macros rather than functions for speed. + +#ifdef JUDYPREV + +#define JSLE_EVEN(Addr,Pop0,cDigits,LeafType) \ + { \ + LeafType * PjllLSB = (LeafType *) (Addr); \ + LeafType IndexLSB = Index; /* auto-masking */ \ + \ + /* Index before or at start of leaf: */ \ + \ + if (*PjllLSB >= IndexLSB) /* no need to search */ \ + { \ + if (*PjllLSB > IndexLSB) RET_SUCCESS; /* Index empty */ \ + LEAF_EDGE(*PjllLSB, cDigits); \ + } \ + \ + /* Index in or after leaf: */ \ + \ + offset = IndexLSB - *PjllLSB; /* tentative offset */ \ + if (offset <= (Pop0)) /* can check density */ \ + { \ + PjllLSB += offset; /* move to slot */ \ + \ + if (*PjllLSB <= IndexLSB) /* dense or corrupt */ \ + { \ + if (*PjllLSB == IndexLSB) /* dense, check edge */ \ + LEAF_EDGE_SET(PjllLSB[-offset], cDigits); \ + RET_CORRUPT; \ + } \ + --PjllLSB; /* not dense, start at previous */ \ + } \ + else PjllLSB = ((LeafType *) (Addr)) + (Pop0); /* start at max */ \ + \ + LEAF_HOLE_EVEN(cDigits, PjllLSB, IndexLSB); \ + } + +// JSLE_ODD is completely different from JSLE_EVEN because its important to +// minimize copying odd indexes to compare them (see 4.14). Furthermore, a +// very complex version (4.17, but abandoned before fully debugged) that +// avoided calling j__udySearchLeaf*() ran twice as fast as 4.14, but still +// half as fast as SearchValid. Doug suggested that to minimize complexity and +// share common code we should use j__udySearchLeaf*() for the initial search +// to establish if Index is empty, which should be common. If Index is valid +// in a leaf or immediate indexes, odds are good that an empty Index is nearby, +// so for simplicity just use a *COPY* function to linearly search the +// remainder. +// +// TBD: Pathological case? Average performance should be good, but worst-case +// might suffer. When Search says the initial Index is valid, so a linear +// copy-and-compare is begun, if the caller builds fairly large leaves with +// dense clusters AND frequently does a SearchEmpty at one end of such a +// cluster, performance wont be very good. Might a dense-check help? This +// means checking offset against the index at offset, and then against the +// first/last index in the leaf. We doubt the pathological case will appear +// much in real applications because they will probably alternate SearchValid +// and SearchEmpty calls. + +#define JSLE_ODD(cDigits,Pjll,Pop0,Search,Copy) \ + { \ + Word_t IndexLSB; /* least bytes only */ \ + Word_t IndexFound; /* in leaf */ \ + \ + if ((offset = Search(Pjll, (Pop0) + 1, Index)) < 0) \ + RET_SUCCESS; /* Index is empty */ \ + \ + IndexLSB = JU_LEASTBYTES(Index, cDigits); \ + offset *= (cDigits); \ + \ + while ((offset -= (cDigits)) >= 0) \ + { /* skip until empty or start */ \ + Copy(IndexFound, ((uint8_t *) (Pjll)) + offset); \ + if (IndexFound != (--IndexLSB)) /* found an empty */ \ + { JU_SETDIGITS(Index, IndexLSB, cDigits); RET_SUCCESS; }\ + } \ + LEAF_EDGE_SET(IndexLSB, cDigits); \ + } + +#else // JUDYNEXT + +#define JSLE_EVEN(Addr,Pop0,cDigits,LeafType) \ + { \ + LeafType * PjllLSB = ((LeafType *) (Addr)) + (Pop0); \ + LeafType IndexLSB = Index; /* auto-masking */ \ + \ + /* Index at or after end of leaf: */ \ + \ + if (*PjllLSB <= IndexLSB) /* no need to search */ \ + { \ + if (*PjllLSB < IndexLSB) RET_SUCCESS; /* Index empty */\ + LEAF_EDGE(*PjllLSB, cDigits); \ + } \ + \ + /* Index before or in leaf: */ \ + \ + offset = *PjllLSB - IndexLSB; /* tentative offset */ \ + if (offset <= (Pop0)) /* can check density */ \ + { \ + PjllLSB -= offset; /* move to slot */ \ + \ + if (*PjllLSB >= IndexLSB) /* dense or corrupt */ \ + { \ + if (*PjllLSB == IndexLSB) /* dense, check edge */ \ + LEAF_EDGE_SET(PjllLSB[offset], cDigits); \ + RET_CORRUPT; \ + } \ + ++PjllLSB; /* not dense, start at next */ \ + } \ + else PjllLSB = (LeafType *) (Addr); /* start at minimum */ \ + \ + LEAF_HOLE_EVEN(cDigits, PjllLSB, IndexLSB); \ + } + +#define JSLE_ODD(cDigits,Pjll,Pop0,Search,Copy) \ + { \ + Word_t IndexLSB; /* least bytes only */ \ + Word_t IndexFound; /* in leaf */ \ + int offsetmax; /* in bytes */ \ + \ + if ((offset = Search(Pjll, (Pop0) + 1, Index)) < 0) \ + RET_SUCCESS; /* Index is empty */ \ + \ + IndexLSB = JU_LEASTBYTES(Index, cDigits); \ + offset *= (cDigits); \ + offsetmax = (Pop0) * (cDigits); /* single multiply */ \ + \ + while ((offset += (cDigits)) <= offsetmax) \ + { /* skip until empty or end */ \ + Copy(IndexFound, ((uint8_t *) (Pjll)) + offset); \ + if (IndexFound != (++IndexLSB)) /* found an empty */ \ + { JU_SETDIGITS(Index, IndexLSB, cDigits); RET_SUCCESS; } \ + } \ + LEAF_EDGE_SET(IndexLSB, cDigits); \ + } + +#endif // JUDYNEXT + +// Note: Immediate indexes never fill a single index group, so for odd index +// sizes, save time by calling JSLE_ODD_IMM instead of JSLE_ODD. + +#define j__udySearchLeafEmpty1(Addr,Pop0) \ + JSLE_EVEN(Addr, Pop0, 1, uint8_t) + +#define j__udySearchLeafEmpty2(Addr,Pop0) \ + JSLE_EVEN(Addr, Pop0, 2, uint16_t) + +#define j__udySearchLeafEmpty3(Addr,Pop0) \ + JSLE_ODD(3, Addr, Pop0, j__udySearchLeaf3, JU_COPY3_PINDEX_TO_LONG) + +#ifndef JU_64BIT + +#define j__udySearchLeafEmptyL(Addr,Pop0) \ + JSLE_EVEN(Addr, Pop0, 4, Word_t) + +#else + +#define j__udySearchLeafEmpty4(Addr,Pop0) \ + JSLE_EVEN(Addr, Pop0, 4, uint32_t) + +#define j__udySearchLeafEmpty5(Addr,Pop0) \ + JSLE_ODD(5, Addr, Pop0, j__udySearchLeaf5, JU_COPY5_PINDEX_TO_LONG) + +#define j__udySearchLeafEmpty6(Addr,Pop0) \ + JSLE_ODD(6, Addr, Pop0, j__udySearchLeaf6, JU_COPY6_PINDEX_TO_LONG) + +#define j__udySearchLeafEmpty7(Addr,Pop0) \ + JSLE_ODD(7, Addr, Pop0, j__udySearchLeaf7, JU_COPY7_PINDEX_TO_LONG) + +#define j__udySearchLeafEmptyL(Addr,Pop0) \ + JSLE_EVEN(Addr, Pop0, 8, Word_t) + +#endif // JU_64BIT + + +// ---------------------------------------------------------------------------- +// START OF CODE: +// +// CHECK FOR SHORTCUTS: +// +// Error out if PIndex is null. + + if (PIndex == (PWord_t) NULL) + { + JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX); + return(JERRI); + } + + Index = *PIndex; // fast local copy. + +// Set and pre-decrement/increment Index, watching for underflow/overflow: +// +// An out-of-bounds Index means failure: No previous/next empty index. + +SMGetRestart: // return here with revised Index. + +#ifdef JUDYPREV + if (Index-- == 0) return(0); +#else + if (++Index == 0) return(0); +#endif + +// An empty array with an in-bounds (not underflowed/overflowed) Index means +// success: +// +// Note: This check is redundant after restarting at SMGetRestart, but should +// take insignificant time. + + if (PArray == (Pvoid_t) NULL) RET_SUCCESS; + +// ---------------------------------------------------------------------------- +// ROOT-LEVEL LEAF that starts with a Pop0 word; just look within the leaf: +// +// If Index is not in the leaf, return success; otherwise return the first +// empty Index, if any, below/above where it would belong. + + if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW + { + Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf. + pop0 = Pjlw[0]; + +#ifdef JUDY1 + if (pop0 == 0) // special case. + { +#ifdef JUDYPREV + if ((Index != Pjlw[1]) || (Index-- != 0)) RET_SUCCESS; +#else + if ((Index != Pjlw[1]) || (++Index != 0)) RET_SUCCESS; +#endif + return(0); // no previous/next empty index. + } +#endif // JUDY1 + + j__udySearchLeafEmptyL(Pjlw + 1, pop0); + +// No return -- thanks ALAN + + } + else + +// ---------------------------------------------------------------------------- +// HANDLE JRP Branch: +// +// For JRP branches, traverse the JPM; handle LEAFW +// directly; but look for the most common cases first. + + { + Pjpm_t Pjpm = P_JPM(PArray); + Pjp = &(Pjpm->jpm_JP); + +// goto SMGetContinue; + } + + +// ============================================================================ +// STATE MACHINE -- GET INDEX: +// +// Search for Index (already decremented/incremented so as to be an inclusive +// search). If not found (empty index), return success. Otherwise do a +// previous/next search, and if successful modify Index to the empty index +// found. See function header comments. +// +// ENTRY: Pjp points to next JP to interpret, whose Decode bytes have not yet +// been checked. +// +// Note: Check Decode bytes at the start of each loop, not after looking up a +// new JP, so its easy to do constant shifts/masks. +// +// EXIT: Return, or branch to SMGetRestart with modified Index, or branch to +// SMGetContinue with a modified Pjp, as described elsewhere. +// +// WARNING: For run-time efficiency the following cases replicate code with +// varying constants, rather than using common code with variable values! + +SMGetContinue: // return here for next branch/leaf. + +#ifdef TRACEJPSE + JudyPrintJP(Pjp, "sf", __LINE__); +#endif + + switch (JU_JPTYPE(Pjp)) + { + + +// ---------------------------------------------------------------------------- +// LINEAR BRANCH: +// +// Check Decode bytes, if any, in the current JP, then search for a JP for the +// next digit in Index. + + case cJU_JPBRANCH_L2: CHECKDCD(2); SMPREPB2(SMBranchL); + case cJU_JPBRANCH_L3: CHECKDCD(3); SMPREPB3(SMBranchL); +#ifdef JU_64BIT + case cJU_JPBRANCH_L4: CHECKDCD(4); SMPREPB4(SMBranchL); + case cJU_JPBRANCH_L5: CHECKDCD(5); SMPREPB5(SMBranchL); + case cJU_JPBRANCH_L6: CHECKDCD(6); SMPREPB6(SMBranchL); + case cJU_JPBRANCH_L7: CHECKDCD(7); SMPREPB7(SMBranchL); +#endif + case cJU_JPBRANCH_L: SMPREPBL(SMBranchL); + +// Common code (state-independent) for all cases of linear branches: + +SMBranchL: + Pjbl = P_JBL(Pjp->jp_Addr); + +// First, check if Indexs expanse (digit) is below/above the first/last +// populated expanse in the BranchL, in which case Index is empty; otherwise +// find the offset of the lowest/highest populated expanse at or above/below +// digit, if any: +// +// Note: The for-loop is guaranteed to exit eventually because the first/last +// expanse is known to be a terminator. +// +// Note: Cannot use j__udySearchLeaf*Empty1() here because it only applies to +// leaves and does not know about partial versus full JPs, unlike the use of +// j__udySearchLeaf1() for BranchLs in SearchValid code. Also, since linear +// leaf expanse lists are small, dont waste time calling j__udySearchLeaf1(), +// just scan the expanse list. + +#ifdef JUDYPREV + if ((Pjbl->jbl_Expanse[0]) > digit) RET_SUCCESS; + + for (offset = (Pjbl->jbl_NumJPs) - 1; /* null */; --offset) +#else + if ((Pjbl->jbl_Expanse[(Pjbl->jbl_NumJPs) - 1]) < digit) + RET_SUCCESS; + + for (offset = 0; /* null */; ++offset) +#endif + { + +// Too low/high, keep going; or too high/low, meaning the loop passed a hole +// and the initial Index is empty: + +#ifdef JUDYPREV + if ((Pjbl->jbl_Expanse[offset]) > digit) continue; + if ((Pjbl->jbl_Expanse[offset]) < digit) RET_SUCCESS; +#else + if ((Pjbl->jbl_Expanse[offset]) < digit) continue; + if ((Pjbl->jbl_Expanse[offset]) > digit) RET_SUCCESS; +#endif + +// Found expanse matching digit; if its not full, traverse through it: + + if (! JPFULL((Pjbl->jbl_jp) + offset)) + { + Pjp = (Pjbl->jbl_jp) + offset; + goto SMGetContinue; + } + +// Common code: While searching for a lower/higher hole or a non-full JP, upon +// finding a lower/higher hole, adjust Index using the revised digit and +// return; or upon finding a consecutive lower/higher expanse, if the expanses +// JP is non-full, modify Index and traverse through the JP: + +#define BRANCHL_CHECK(OpIncDec,OpLeastDigits,Digit,Digits) \ + { \ + if ((Pjbl->jbl_Expanse[offset]) != OpIncDec digit) \ + SET_AND_RETURN(OpLeastDigits, Digit, Digits); \ + \ + if (! JPFULL((Pjbl->jbl_jp) + offset)) \ + { \ + Pjp = (Pjbl->jbl_jp) + offset; \ + SET_AND_CONTINUE(OpLeastDigits, Digit, Digits); \ + } \ + } + +// BranchL primary dead end: Expanse matching Index/digit is full (rare except +// for dense/sequential indexes): +// +// Search for a lower/higher hole, a non-full JP, or the end of the expanse +// list, while decrementing/incrementing digit. + +#ifdef JUDYPREV + while (--offset >= 0) + BRANCHL_CHECK(--, SETLEASTDIGITS_D, digit, digits) +#else + while (++offset < Pjbl->jbl_NumJPs) + BRANCHL_CHECK(++, CLEARLEASTDIGITS_D, digit, digits) +#endif + +// Passed end of BranchL expanse list after finding a matching but full +// expanse: +// +// Digit now matches the lowest/highest expanse, which is a full expanse; if +// digit is at the end of BranchLs expanse (no hole before/after), break out +// of the loop; otherwise modify Index to the next lower/higher digit and +// return success: + +#ifdef JUDYPREV + if (digit == 0) break; + --digit; SET_AND_RETURN(SETLEASTDIGITS_D, digit, digits); +#else + if (digit == JU_LEASTBYTES(cJU_ALLONES, 1)) break; + ++digit; SET_AND_RETURN(CLEARLEASTDIGITS_D, digit, digits); +#endif + } // for-loop + +// BranchL secondary dead end, no non-full previous/next JP: + + SMRESTART(digits); + + +// ---------------------------------------------------------------------------- +// BITMAP BRANCH: +// +// Check Decode bytes, if any, in the current JP, then search for a JP for the +// next digit in Index. + + case cJU_JPBRANCH_B2: CHECKDCD(2); SMPREPB2(SMBranchB); + case cJU_JPBRANCH_B3: CHECKDCD(3); SMPREPB3(SMBranchB); +#ifdef JU_64BIT + case cJU_JPBRANCH_B4: CHECKDCD(4); SMPREPB4(SMBranchB); + case cJU_JPBRANCH_B5: CHECKDCD(5); SMPREPB5(SMBranchB); + case cJU_JPBRANCH_B6: CHECKDCD(6); SMPREPB6(SMBranchB); + case cJU_JPBRANCH_B7: CHECKDCD(7); SMPREPB7(SMBranchB); +#endif + case cJU_JPBRANCH_B: SMPREPBL(SMBranchB); + +// Common code (state-independent) for all cases of bitmap branches: + +SMBranchB: + Pjbb = P_JBB(Pjp->jp_Addr); + +// Locate the digits JP in the subexpanse list, if present: + + subexp = digit / cJU_BITSPERSUBEXPB; + assert(subexp < cJU_NUMSUBEXPB); // falls in expected range. + bitposmaskB = JU_BITPOSMASKB(digit); + +// Absent JP = no JP matches current digit in Index: + +// if (! JU_BITMAPTESTB(Pjbb, digit)) // slower. + if (! (JU_JBB_BITMAP(Pjbb, subexp) & bitposmaskB)) // faster. + RET_SUCCESS; + +// Non-full JP matches current digit in Index: +// +// Iterate to the subsidiary non-full JP. + + offset = SEARCHBITMAPB(JU_JBB_BITMAP(Pjbb, subexp), digit, + bitposmaskB); + // not negative since at least one bit is set: + assert(offset >= 0); + assert(offset < (int) cJU_BITSPERSUBEXPB); + +// Watch for null JP subarray pointer with non-null bitmap (a corruption): + + if ((Pjp = P_JP(JU_JBB_PJP(Pjbb, subexp))) + == (Pjp_t) NULL) RET_CORRUPT; + + Pjp += offset; + if (! JPFULL(Pjp)) goto SMGetContinue; + +// BranchB primary dead end: +// +// Upon hitting a full JP in a BranchB for the next digit in Index, search +// sideways for a previous/next absent JP (unset bit) or non-full JP (set bit +// with non-full JP); first in the current bitmap subexpanse, then in +// lower/higher subexpanses. Upon entry, Pjp points to a known-unusable JP, +// ready to decrement/increment. +// +// Note: The preceding code is separate from this loop because Index does not +// need revising (see SET_AND_*()) if the initial index is an empty index. +// +// TBD: For speed, shift bitposmaskB instead of using JU_BITMAPTESTB or +// JU_BITPOSMASKB, but this shift has knowledge of bit order that really should +// be encapsulated in a header file. + +#define BRANCHB_CHECKBIT(OpLeastDigits) \ + if (! (JU_JBB_BITMAP(Pjbb, subexp) & bitposmaskB)) /* absent JP */ \ + SET_AND_RETURN(OpLeastDigits, digit, digits) + +#define BRANCHB_CHECKJPFULL(OpLeastDigits) \ + if (! JPFULL(Pjp)) \ + SET_AND_CONTINUE(OpLeastDigits, digit, digits) + +#define BRANCHB_STARTSUBEXP(OpLeastDigits) \ + if (! JU_JBB_BITMAP(Pjbb, subexp)) /* empty subexpanse, shortcut */ \ + SET_AND_RETURN(OpLeastDigits, digit, digits) \ + if ((Pjp = P_JP(JU_JBB_PJP(Pjbb, subexp))) == (Pjp_t) NULL) RET_CORRUPT + +#ifdef JUDYPREV + + --digit; // skip initial digit. + bitposmaskB >>= 1; // see TBD above. + +BranchBNextSubexp: // return here to check next bitmap subexpanse. + + while (bitposmaskB) // more bits to check in subexp. + { + BRANCHB_CHECKBIT(SETLEASTDIGITS_D); + --Pjp; // previous in subarray. + BRANCHB_CHECKJPFULL(SETLEASTDIGITS_D); + assert(digit >= 0); + --digit; + bitposmaskB >>= 1; + } + + if (subexp-- > 0) // more subexpanses. + { + BRANCHB_STARTSUBEXP(SETLEASTDIGITS_D); + Pjp += SEARCHBITMAPMAXB(JU_JBB_BITMAP(Pjbb, subexp)) + 1; + bitposmaskB = (1U << (cJU_BITSPERSUBEXPB - 1)); + goto BranchBNextSubexp; + } + +#else // JUDYNEXT + + ++digit; // skip initial digit. + bitposmaskB <<= 1; // note: BITMAPB_t. + +BranchBNextSubexp: // return here to check next bitmap subexpanse. + + while (bitposmaskB) // more bits to check in subexp. + { + BRANCHB_CHECKBIT(CLEARLEASTDIGITS_D); + ++Pjp; // previous in subarray. + BRANCHB_CHECKJPFULL(CLEARLEASTDIGITS_D); + assert(digit < cJU_SUBEXPPERSTATE); + ++digit; + bitposmaskB <<= 1; // note: BITMAPB_t. + } + + if (++subexp < cJU_NUMSUBEXPB) // more subexpanses. + { + BRANCHB_STARTSUBEXP(CLEARLEASTDIGITS_D); + --Pjp; // pre-decrement. + bitposmaskB = 1; + goto BranchBNextSubexp; + } + +#endif // JUDYNEXT + +// BranchB secondary dead end, no non-full previous/next JP: + + SMRESTART(digits); + + +// ---------------------------------------------------------------------------- +// UNCOMPRESSED BRANCH: +// +// Check Decode bytes, if any, in the current JP, then search for a JP for the +// next digit in Index. + + case cJU_JPBRANCH_U2: CHECKDCD(2); SMPREPB2(SMBranchU); + case cJU_JPBRANCH_U3: CHECKDCD(3); SMPREPB3(SMBranchU); +#ifdef JU_64BIT + case cJU_JPBRANCH_U4: CHECKDCD(4); SMPREPB4(SMBranchU); + case cJU_JPBRANCH_U5: CHECKDCD(5); SMPREPB5(SMBranchU); + case cJU_JPBRANCH_U6: CHECKDCD(6); SMPREPB6(SMBranchU); + case cJU_JPBRANCH_U7: CHECKDCD(7); SMPREPB7(SMBranchU); +#endif + case cJU_JPBRANCH_U: SMPREPBL(SMBranchU); + +// Common code (state-independent) for all cases of uncompressed branches: + +SMBranchU: + Pjbu = P_JBU(Pjp->jp_Addr); + Pjp = (Pjbu->jbu_jp) + digit; + +// Absent JP = null JP for current digit in Index: + + if (JPNULL(JU_JPTYPE(Pjp))) RET_SUCCESS; + +// Non-full JP matches current digit in Index: +// +// Iterate to the subsidiary JP. + + if (! JPFULL(Pjp)) goto SMGetContinue; + +// BranchU primary dead end: +// +// Upon hitting a full JP in a BranchU for the next digit in Index, search +// sideways for a previous/next null or non-full JP. BRANCHU_CHECKJP() is +// shorthand for common code. +// +// Note: The preceding code is separate from this loop because Index does not +// need revising (see SET_AND_*()) if the initial index is an empty index. + +#define BRANCHU_CHECKJP(OpIncDec,OpLeastDigits) \ + { \ + OpIncDec Pjp; \ + \ + if (JPNULL(JU_JPTYPE(Pjp))) \ + SET_AND_RETURN(OpLeastDigits, digit, digits) \ + \ + if (! JPFULL(Pjp)) \ + SET_AND_CONTINUE(OpLeastDigits, digit, digits) \ + } + +#ifdef JUDYPREV + while (digit-- > 0) + BRANCHU_CHECKJP(--, SETLEASTDIGITS_D); +#else + while (++digit < cJU_BRANCHUNUMJPS) + BRANCHU_CHECKJP(++, CLEARLEASTDIGITS_D); +#endif + +// BranchU secondary dead end, no non-full previous/next JP: + + SMRESTART(digits); + + +// ---------------------------------------------------------------------------- +// LINEAR LEAF: +// +// Check Decode bytes, if any, in the current JP, then search the leaf for the +// previous/next empty index starting at Index. Primary leaf dead end is +// hidden within j__udySearchLeaf*Empty*(). In case of secondary leaf dead +// end, restart at the top of the tree. +// +// Note: Pword is the name known to GET*; think of it as Pjlw. + +#define SMLEAFL(cDigits,Func) \ + Pword = (PWord_t) P_JLW(Pjp->jp_Addr); \ + pop0 = JU_JPLEAF_POP0(Pjp); \ + Func(Pword, pop0) + +#if (defined(JUDYL) || (! defined(JU_64BIT))) + case cJU_JPLEAF1: CHECKDCD(1); SMLEAFL(1, j__udySearchLeafEmpty1); +#endif + case cJU_JPLEAF2: CHECKDCD(2); SMLEAFL(2, j__udySearchLeafEmpty2); + case cJU_JPLEAF3: CHECKDCD(3); SMLEAFL(3, j__udySearchLeafEmpty3); + +#ifdef JU_64BIT + case cJU_JPLEAF4: CHECKDCD(4); SMLEAFL(4, j__udySearchLeafEmpty4); + case cJU_JPLEAF5: CHECKDCD(5); SMLEAFL(5, j__udySearchLeafEmpty5); + case cJU_JPLEAF6: CHECKDCD(6); SMLEAFL(6, j__udySearchLeafEmpty6); + case cJU_JPLEAF7: CHECKDCD(7); SMLEAFL(7, j__udySearchLeafEmpty7); +#endif + + +// ---------------------------------------------------------------------------- +// BITMAP LEAF: +// +// Check Decode bytes, if any, in the current JP, then search the leaf for the +// previous/next empty index starting at Index. + + case cJU_JPLEAF_B1: + + CHECKDCD(1); + + Pjlb = P_JLB(Pjp->jp_Addr); + digit = JU_DIGITATSTATE(Index, 1); + subexp = digit / cJU_BITSPERSUBEXPL; + bitposmaskL = JU_BITPOSMASKL(digit); + assert(subexp < cJU_NUMSUBEXPL); // falls in expected range. + +// Absent index = no index matches current digit in Index: + +// if (! JU_BITMAPTESTL(Pjlb, digit)) // slower. + if (! (JU_JLB_BITMAP(Pjlb, subexp) & bitposmaskL)) // faster. + RET_SUCCESS; + +// LeafB1 primary dead end: +// +// Upon hitting a valid (non-empty) index in a LeafB1 for the last digit in +// Index, search sideways for a previous/next absent index, first in the +// current bitmap subexpanse, then in lower/higher subexpanses. +// LEAFB1_CHECKBIT() is shorthand for common code to handle one bit in one +// bitmap subexpanse. +// +// Note: The preceding code is separate from this loop because Index does not +// need revising (see SET_AND_*()) if the initial index is an empty index. +// +// TBD: For speed, shift bitposmaskL instead of using JU_BITMAPTESTL or +// JU_BITPOSMASKL, but this shift has knowledge of bit order that really should +// be encapsulated in a header file. + +#define LEAFB1_CHECKBIT(OpLeastDigits) \ + if (! (JU_JLB_BITMAP(Pjlb, subexp) & bitposmaskL)) \ + SET_AND_RETURN(OpLeastDigits, digit, 1) + +#define LEAFB1_STARTSUBEXP(OpLeastDigits) \ + if (! JU_JLB_BITMAP(Pjlb, subexp)) /* empty subexp */ \ + SET_AND_RETURN(OpLeastDigits, digit, 1) + +#ifdef JUDYPREV + + --digit; // skip initial digit. + bitposmaskL >>= 1; // see TBD above. + +LeafB1NextSubexp: // return here to check next bitmap subexpanse. + + while (bitposmaskL) // more bits to check in subexp. + { + LEAFB1_CHECKBIT(SETLEASTDIGITS_D); + assert(digit >= 0); + --digit; + bitposmaskL >>= 1; + } + + if (subexp-- > 0) // more subexpanses. + { + LEAFB1_STARTSUBEXP(SETLEASTDIGITS_D); + bitposmaskL = (1UL << (cJU_BITSPERSUBEXPL - 1)); + goto LeafB1NextSubexp; + } + +#else // JUDYNEXT + + ++digit; // skip initial digit. + bitposmaskL <<= 1; // note: BITMAPL_t. + +LeafB1NextSubexp: // return here to check next bitmap subexpanse. + + while (bitposmaskL) // more bits to check in subexp. + { + LEAFB1_CHECKBIT(CLEARLEASTDIGITS_D); + assert(digit < cJU_SUBEXPPERSTATE); + ++digit; + bitposmaskL <<= 1; // note: BITMAPL_t. + } + + if (++subexp < cJU_NUMSUBEXPL) // more subexpanses. + { + LEAFB1_STARTSUBEXP(CLEARLEASTDIGITS_D); + bitposmaskL = 1; + goto LeafB1NextSubexp; + } + +#endif // JUDYNEXT + +// LeafB1 secondary dead end, no empty index: + + SMRESTART(1); + + +#ifdef JUDY1 +// ---------------------------------------------------------------------------- +// FULL POPULATION: +// +// If the Decode bytes do not match, Index is empty (without modification); +// otherwise restart. + + case cJ1_JPFULLPOPU1: + + CHECKDCD(1); + SMRESTART(1); +#endif + + +// ---------------------------------------------------------------------------- +// IMMEDIATE: +// +// Pop1 = 1 Immediate JPs: +// +// If Index is not in the immediate JP, return success; otherwise check if +// there is an empty index below/above the immediate JPs index, and if so, +// return success with modified Index, else restart. +// +// Note: Doug says its fast enough to calculate the index size (digits) in +// the following; no need to set it separately for each case. + + case cJU_JPIMMED_1_01: + case cJU_JPIMMED_2_01: + case cJU_JPIMMED_3_01: +#ifdef JU_64BIT + case cJU_JPIMMED_4_01: + case cJU_JPIMMED_5_01: + case cJU_JPIMMED_6_01: + case cJU_JPIMMED_7_01: +#endif + if (JU_JPDCDPOP0(Pjp) != JU_TRIMTODCDSIZE(Index)) RET_SUCCESS; + digits = JU_JPTYPE(Pjp) - cJU_JPIMMED_1_01 + 1; + LEAF_EDGE(JU_LEASTBYTES(JU_JPDCDPOP0(Pjp), digits), digits); + +// Immediate JPs with Pop1 > 1: + +#define IMM_MULTI(Func,BaseJPType) \ + JUDY1CODE(Pword = (PWord_t) (Pjp->jp_1Index);) \ + JUDYLCODE(Pword = (PWord_t) (Pjp->jp_LIndex);) \ + Func(Pword, JU_JPTYPE(Pjp) - (BaseJPType) + 1) + + case cJU_JPIMMED_1_02: + case cJU_JPIMMED_1_03: +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_1_04: + case cJU_JPIMMED_1_05: + case cJU_JPIMMED_1_06: + case cJU_JPIMMED_1_07: +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_1_08: + case cJ1_JPIMMED_1_09: + case cJ1_JPIMMED_1_10: + case cJ1_JPIMMED_1_11: + case cJ1_JPIMMED_1_12: + case cJ1_JPIMMED_1_13: + case cJ1_JPIMMED_1_14: + case cJ1_JPIMMED_1_15: +#endif + IMM_MULTI(j__udySearchLeafEmpty1, cJU_JPIMMED_1_02); + +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_2_02: + case cJU_JPIMMED_2_03: +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_2_04: + case cJ1_JPIMMED_2_05: + case cJ1_JPIMMED_2_06: + case cJ1_JPIMMED_2_07: +#endif +#if (defined(JUDY1) || defined(JU_64BIT)) + IMM_MULTI(j__udySearchLeafEmpty2, cJU_JPIMMED_2_02); +#endif + +#if (defined(JUDY1) || defined(JU_64BIT)) + case cJU_JPIMMED_3_02: +#endif +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_3_03: + case cJ1_JPIMMED_3_04: + case cJ1_JPIMMED_3_05: +#endif +#if (defined(JUDY1) || defined(JU_64BIT)) + IMM_MULTI(j__udySearchLeafEmpty3, cJU_JPIMMED_3_02); +#endif + +#if (defined(JUDY1) && defined(JU_64BIT)) + case cJ1_JPIMMED_4_02: + case cJ1_JPIMMED_4_03: + IMM_MULTI(j__udySearchLeafEmpty4, cJ1_JPIMMED_4_02); + + case cJ1_JPIMMED_5_02: + case cJ1_JPIMMED_5_03: + IMM_MULTI(j__udySearchLeafEmpty5, cJ1_JPIMMED_5_02); + + case cJ1_JPIMMED_6_02: + IMM_MULTI(j__udySearchLeafEmpty6, cJ1_JPIMMED_6_02); + + case cJ1_JPIMMED_7_02: + IMM_MULTI(j__udySearchLeafEmpty7, cJ1_JPIMMED_7_02); +#endif + + +// ---------------------------------------------------------------------------- +// INVALID JP TYPE: + + default: RET_CORRUPT; + + } // SMGet switch. + +} // Judy1PrevEmpty() / Judy1NextEmpty() / JudyLPrevEmpty() / JudyLNextEmpty() diff --git a/feeds/p4/libjudy/src/src/JudyCommon/JudyPrintJP.c b/feeds/p4/libjudy/src/src/JudyCommon/JudyPrintJP.c new file mode 100644 index 000000000..bf5dd8547 --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudyCommon/JudyPrintJP.c @@ -0,0 +1,401 @@ +// Copyright (C) 2000 - 2002 Hewlett-Packard Company +// +// This program is free software; you can redistribute it and/or modify it +// under the term of the GNU Lesser 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 Lesser General Public License +// for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// _________________ + +// @(#) $Revision: 4.13 $ $Source: /judy/src/JudyCommon/JudyPrintJP.c $ +// +// JudyPrintJP() debugging/tracing function for Judy1 or JudyL code. +// The caller should #include this file, with its static function (replicated +// in each compilation unit), in another *.c file, and compile with one of +// -DJUDY1 or -DJUDYL. +// +// The caller can set j__udyIndex and/or j__udyPopulation non-zero to have +// those values reported, and also to control trace-enabling (see below). +// +// Tracing is disabled by default unless one or both of two env parameters is +// set (regardless of value). If either value is set but null or evaluates to +// zero, tracing is immediately enabled. To disable tracing until a particular +// j__udy*Index value is seen, set STARTINDEX= in the env. To +// disable it until a particular j__udy*Population value is seen, set +// STARTPOP= in the env. Once either condition is met, +// tracing "latches on". +// +// Example: +// +// STARTPOP=0 // immediate tracing. +// STARTINDEX=f35430a8 // not until one of these is met. +// STARTPOP=1000000 +// +// Note: Trace-enabling does nothing unless the caller sets the appropriate +// global variable non-zero. + +#if (! (defined(JUDY1) || defined(JUDYL))) +#error: One of -DJUDY1 or -DJUDYL must be specified. +#endif + +#include // for getenv() and strtoul(). + + +// GLOBALS FROM CALLER: +// +// Note: This storage is declared once in each compilation unit that includes +// this file, but the linker should merge all cases into single locations, but +// ONLY if these are uninitialized, so ASSUME they are 0 to start. + +Word_t j__udyIndex; // current Index itself, optional from caller. +Word_t j__udyPopulation; // Indexes in array, optional from caller. + +// Other globals: + +static Word_t startindex = 0; // see usage below. +static Word_t startpop = 0; +static bool_t enabled = FALSE; // by default, unless env params set. + +// Shorthand for announcing JP addresses, Desc (in context), and JP types: +// +// Note: Width is at least one blank wider than any JP type name, and the line +// is left unfinished. +// +// Note: Use a format for address printing compatible with other tracing +// facilities; in particular, %x not %lx, to truncate the "noisy" high part on +// 64-bit systems. + +#define JPTYPE(Type) printf("0x%lx %s %-17s", (Word_t) Pjp, Desc, Type) + +// Shorthands for announcing expanse populations from DcdPopO fields: + +#define POP0 printf("Pop1 = 0 ") +#define POP1 printf("Pop1 = %ld ", (Word_t) ((JU_JPDCDPOP0(Pjp) & 0xff) + 1)) +#define POP2 printf("Pop1 = %ld ", (Word_t) ((JU_JPDCDPOP0(Pjp) & 0xffff) + 1)) +#define POP3 printf("Pop1 = %ld ", (Word_t) ((JU_JPDCDPOP0(Pjp) & 0xffffff) + 1)) +#ifdef JU_64BIT +#define POP4 printf("Pop1 = %ld ", (Word_t) ((JU_JPDCDPOP0(Pjp) & 0xffffffff) + 1)) +#define POP5 printf("Pop1 = %ld ", (Word_t) ((JU_JPDCDPOP0(Pjp) & 0xffffffffff) + 1)) +#define POP6 printf("Pop1 = %ld ", (Word_t) ((JU_JPDCDPOP0(Pjp) & 0xffffffffffff) + 1)) +#define POP7 printf("Pop1 = %ld ", (Word_t) ((JU_JPDCDPOP0(Pjp) & 0xffffffffffffff) + 1)) +#endif + +// Shorthands for announcing populations of Immeds: +// +// Note: Line up the small populations that often occur together, but beyond +// that, dont worry about it because populations can get arbitrarily large. + +#define POP_1 printf("Pop1 = 1 ") +#define POP_2 printf("Pop1 = 2 ") +#define POP_3 printf("Pop1 = 3 ") +#define POP_4 printf("Pop1 = 4 ") +#define POP_5 printf("Pop1 = 5 ") +#define POP_6 printf("Pop1 = 6 ") +#define POP_7 printf("Pop1 = 7 ") +#define POP_8 printf("Pop1 = 8 ") +#define POP_9 printf("Pop1 = 8 ") +#define POP_10 printf("Pop1 = 10 ") +#define POP_11 printf("Pop1 = 11 ") +#define POP_12 printf("Pop1 = 12 ") +#define POP_13 printf("Pop1 = 13 ") +#define POP_14 printf("Pop1 = 14 ") +#define POP_15 printf("Pop1 = 15 ") + +// Shorthands for other announcements: + +#define NUMJPSL printf("NumJPs = %d ", P_JBL(Pjp->jp_Addr)->jbl_NumJPs) +#define OOPS printf("-- OOPS, invalid Type\n"); exit(1) + +// This is harder to compute: + +#define NUMJPSB \ + { \ + Pjbb_t Pjbb = P_JBB(Pjp->jp_Addr); \ + Word_t subexp; \ + int numJPs = 0; \ + \ + for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp) \ + numJPs += j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp));\ + \ + printf("NumJPs = %d ", numJPs); \ + } + + +// **************************************************************************** +// J U D Y P R I N T J P +// +// Dump information about a JP, at least its address, type, population, and +// number of JPs, as appropriate. Error out upon any unexpected JP type. +// +// TBD: Dump more detailed information about the JP? + +FUNCTION static void JudyPrintJP( + Pjp_t Pjp, // JP to describe. + char * Desc, // brief description of caller, such as "i". + int Line) // callers source line number. +{ +static bool_t checked = FALSE; // set upon first entry and check for params. + char * value; // for getenv(). + + +// CHECK FOR EXTERNAL ENABLING: +// +// If a parameter is set, report the value, even if it is null or otherwise +// evaluates to zero, in which case enable tracing immediately; otherwise wait +// for the value to be hit. + +#define GETENV(Name,Value,Base) \ + if ((value = getenv (Name)) != (char *) NULL) \ + { \ + (Value) = strtoul (value, (char **) NULL, Base); \ + enabled |= ((Value) == 0); /* see above */ \ + \ + (void) printf ("JudyPrintJP(\"%s\"): $%s = %lu\n", \ + Desc, Name, Value); \ + } + + if (! checked) // only check once. + { + checked = TRUE; + + GETENV ("STARTINDEX", startindex, 16); + GETENV ("STARTPOP", startpop, 10); + + (void) printf ("JudyPrintJP(\"%s\"): Tracing present %s\n", Desc, + enabled ? "and immediately enabled" : + (startindex || startpop) ? + "but disabled until start condition met" : + "but not enabled by env parameter"); + } + + if (! enabled) // check repeatedly until latched enabled: + { + if (startindex && (startindex == j__udyIndex)) + { + (void) printf ("=== TRACING ENABLED (\"%s\"), " + "startindex = 0x%lx\n", Desc, startindex); + enabled = TRUE; + } + else if (startpop && (startpop == j__udyPopulation)) + { + (void) printf ("=== TRACING ENABLED (\"%s\"), " + "startpop = %lu\n", Desc, startpop); + enabled = TRUE; + } + else + { + return; // print nothing this time. + } + } + + +// SWITCH ON JP TYPE: + + switch (JU_JPTYPE(Pjp)) + { + +// Note: The following COULD be merged more tightly between Judy1 and JudyL, +// but we decided that the output should say cJ1*/cJL*, not cJU*, to be more +// specific. + +#ifdef JUDY1 + case cJ1_JPNULL1: JPTYPE("cJ1_JPNULL1"); POP0; break; + case cJ1_JPNULL2: JPTYPE("cJ1_JPNULL2"); POP0; break; + case cJ1_JPNULL3: JPTYPE("cJ1_JPNULL3"); POP0; break; +#ifdef JU_64BIT + case cJ1_JPNULL4: JPTYPE("cJ1_JPNULL4"); POP0; break; + case cJ1_JPNULL5: JPTYPE("cJ1_JPNULL5"); POP0; break; + case cJ1_JPNULL6: JPTYPE("cJ1_JPNULL6"); POP0; break; + case cJ1_JPNULL7: JPTYPE("cJ1_JPNULL7"); POP0; break; +#endif + + case cJ1_JPBRANCH_L2: JPTYPE("cJ1_JPBRANCH_L2"); POP2;NUMJPSL;break; + case cJ1_JPBRANCH_L3: JPTYPE("cJ1_JPBRANCH_L3"); POP3;NUMJPSL;break; +#ifdef JU_64BIT + case cJ1_JPBRANCH_L4: JPTYPE("cJ1_JPBRANCH_L4"); POP4;NUMJPSL;break; + case cJ1_JPBRANCH_L5: JPTYPE("cJ1_JPBRANCH_L5"); POP5;NUMJPSL;break; + case cJ1_JPBRANCH_L6: JPTYPE("cJ1_JPBRANCH_L6"); POP6;NUMJPSL;break; + case cJ1_JPBRANCH_L7: JPTYPE("cJ1_JPBRANCH_L7"); POP7;NUMJPSL;break; +#endif + case cJ1_JPBRANCH_L: JPTYPE("cJ1_JPBRANCH_L"); NUMJPSL;break; + + case cJ1_JPBRANCH_B2: JPTYPE("cJ1_JPBRANCH_B2"); POP2;NUMJPSB;break; + case cJ1_JPBRANCH_B3: JPTYPE("cJ1_JPBRANCH_B3"); POP3;NUMJPSB;break; +#ifdef JU_64BIT + case cJ1_JPBRANCH_B4: JPTYPE("cJ1_JPBRANCH_B4"); POP4;NUMJPSB;break; + case cJ1_JPBRANCH_B5: JPTYPE("cJ1_JPBRANCH_B5"); POP5;NUMJPSB;break; + case cJ1_JPBRANCH_B6: JPTYPE("cJ1_JPBRANCH_B6"); POP6;NUMJPSB;break; + case cJ1_JPBRANCH_B7: JPTYPE("cJ1_JPBRANCH_B7"); POP7;NUMJPSB;break; +#endif + case cJ1_JPBRANCH_B: JPTYPE("cJ1_JPBRANCH_B"); NUMJPSB;break; + + case cJ1_JPBRANCH_U2: JPTYPE("cJ1_JPBRANCH_U2"); POP2; break; + case cJ1_JPBRANCH_U3: JPTYPE("cJ1_JPBRANCH_U3"); POP3; break; +#ifdef JU_64BIT + case cJ1_JPBRANCH_U4: JPTYPE("cJ1_JPBRANCH_U4"); POP4; break; + case cJ1_JPBRANCH_U5: JPTYPE("cJ1_JPBRANCH_U5"); POP5; break; + case cJ1_JPBRANCH_U6: JPTYPE("cJ1_JPBRANCH_U6"); POP6; break; + case cJ1_JPBRANCH_U7: JPTYPE("cJ1_JPBRANCH_U7"); POP7; break; +#endif + case cJ1_JPBRANCH_U: JPTYPE("cJ1_JPBRANCH_U"); break; + +#ifndef JU_64BIT + case cJ1_JPLEAF1: JPTYPE("cJ1_JPLEAF1"); POP1; break; +#endif + case cJ1_JPLEAF2: JPTYPE("cJ1_JPLEAF2"); POP2; break; + case cJ1_JPLEAF3: JPTYPE("cJ1_JPLEAF3"); POP3; break; +#ifdef JU_64BIT + case cJ1_JPLEAF4: JPTYPE("cJ1_JPLEAF4"); POP4; break; + case cJ1_JPLEAF5: JPTYPE("cJ1_JPLEAF5"); POP5; break; + case cJ1_JPLEAF6: JPTYPE("cJ1_JPLEAF6"); POP6; break; + case cJ1_JPLEAF7: JPTYPE("cJ1_JPLEAF7"); POP7; break; +#endif + + case cJ1_JPLEAF_B1: JPTYPE("cJ1_JPLEAF_B1"); POP1; break; + case cJ1_JPFULLPOPU1: JPTYPE("cJ1_JPFULLPOPU1"); POP1; break; + + case cJ1_JPIMMED_1_01: JPTYPE("cJ1_JPIMMED_1_01"); POP_1; break; + case cJ1_JPIMMED_2_01: JPTYPE("cJ1_JPIMMED_2_01"); POP_1; break; + case cJ1_JPIMMED_3_01: JPTYPE("cJ1_JPIMMED_3_01"); POP_1; break; +#ifdef JU_64BIT + case cJ1_JPIMMED_4_01: JPTYPE("cJ1_JPIMMED_4_01"); POP_1; break; + case cJ1_JPIMMED_5_01: JPTYPE("cJ1_JPIMMED_5_01"); POP_1; break; + case cJ1_JPIMMED_6_01: JPTYPE("cJ1_JPIMMED_6_01"); POP_1; break; + case cJ1_JPIMMED_7_01: JPTYPE("cJ1_JPIMMED_7_01"); POP_1; break; +#endif + + case cJ1_JPIMMED_1_02: JPTYPE("cJ1_JPIMMED_1_02"); POP_2; break; + case cJ1_JPIMMED_1_03: JPTYPE("cJ1_JPIMMED_1_03"); POP_3; break; + case cJ1_JPIMMED_1_04: JPTYPE("cJ1_JPIMMED_1_04"); POP_4; break; + case cJ1_JPIMMED_1_05: JPTYPE("cJ1_JPIMMED_1_05"); POP_5; break; + case cJ1_JPIMMED_1_06: JPTYPE("cJ1_JPIMMED_1_06"); POP_6; break; + case cJ1_JPIMMED_1_07: JPTYPE("cJ1_JPIMMED_1_07"); POP_7; break; +#ifdef JU_64BIT + case cJ1_JPIMMED_1_08: JPTYPE("cJ1_JPIMMED_1_08"); POP_8; break; + case cJ1_JPIMMED_1_09: JPTYPE("cJ1_JPIMMED_1_09"); POP_9; break; + case cJ1_JPIMMED_1_10: JPTYPE("cJ1_JPIMMED_1_10"); POP_10; break; + case cJ1_JPIMMED_1_11: JPTYPE("cJ1_JPIMMED_1_11"); POP_11; break; + case cJ1_JPIMMED_1_12: JPTYPE("cJ1_JPIMMED_1_12"); POP_12; break; + case cJ1_JPIMMED_1_13: JPTYPE("cJ1_JPIMMED_1_13"); POP_13; break; + case cJ1_JPIMMED_1_14: JPTYPE("cJ1_JPIMMED_1_14"); POP_14; break; + case cJ1_JPIMMED_1_15: JPTYPE("cJ1_JPIMMED_1_15"); POP_15; break; +#endif + case cJ1_JPIMMED_2_02: JPTYPE("cJ1_JPIMMED_2_02"); POP_2; break; + case cJ1_JPIMMED_2_03: JPTYPE("cJ1_JPIMMED_2_03"); POP_3; break; +#ifdef JU_64BIT + case cJ1_JPIMMED_2_04: JPTYPE("cJ1_JPIMMED_2_04"); POP_4; break; + case cJ1_JPIMMED_2_05: JPTYPE("cJ1_JPIMMED_2_05"); POP_5; break; + case cJ1_JPIMMED_2_06: JPTYPE("cJ1_JPIMMED_2_06"); POP_6; break; + case cJ1_JPIMMED_2_07: JPTYPE("cJ1_JPIMMED_2_07"); POP_7; break; +#endif + + case cJ1_JPIMMED_3_02: JPTYPE("cJ1_JPIMMED_3_02"); POP_2; break; +#ifdef JU_64BIT + case cJ1_JPIMMED_3_03: JPTYPE("cJ1_JPIMMED_3_03"); POP_3; break; + case cJ1_JPIMMED_3_04: JPTYPE("cJ1_JPIMMED_3_04"); POP_4; break; + case cJ1_JPIMMED_3_05: JPTYPE("cJ1_JPIMMED_3_05"); POP_5; break; + case cJ1_JPIMMED_4_02: JPTYPE("cJ1_JPIMMED_4_02"); POP_2; break; + case cJ1_JPIMMED_4_03: JPTYPE("cJ1_JPIMMED_4_03"); POP_3; break; + case cJ1_JPIMMED_5_02: JPTYPE("cJ1_JPIMMED_5_02"); POP_2; break; + case cJ1_JPIMMED_5_03: JPTYPE("cJ1_JPIMMED_5_03"); POP_3; break; + case cJ1_JPIMMED_6_02: JPTYPE("cJ1_JPIMMED_6_02"); POP_2; break; + case cJ1_JPIMMED_7_02: JPTYPE("cJ1_JPIMMED_7_02"); POP_2; break; +#endif + case cJ1_JPIMMED_CAP: JPTYPE("cJ1_JPIMMED_CAP"); OOPS; + +#else // JUDYL =============================================================== + + case cJL_JPNULL1: JPTYPE("cJL_JPNULL1"); POP0; break; + case cJL_JPNULL2: JPTYPE("cJL_JPNULL2"); POP0; break; + case cJL_JPNULL3: JPTYPE("cJL_JPNULL3"); POP0; break; +#ifdef JU_64BIT + case cJL_JPNULL4: JPTYPE("cJL_JPNULL4"); POP0; break; + case cJL_JPNULL5: JPTYPE("cJL_JPNULL5"); POP0; break; + case cJL_JPNULL6: JPTYPE("cJL_JPNULL6"); POP0; break; + case cJL_JPNULL7: JPTYPE("cJL_JPNULL7"); POP0; break; +#endif + + case cJL_JPBRANCH_L2: JPTYPE("cJL_JPBRANCH_L2"); POP2;NUMJPSL;break; + case cJL_JPBRANCH_L3: JPTYPE("cJL_JPBRANCH_L3"); POP3;NUMJPSL;break; +#ifdef JU_64BIT + case cJL_JPBRANCH_L4: JPTYPE("cJL_JPBRANCH_L4"); POP4;NUMJPSL;break; + case cJL_JPBRANCH_L5: JPTYPE("cJL_JPBRANCH_L5"); POP5;NUMJPSL;break; + case cJL_JPBRANCH_L6: JPTYPE("cJL_JPBRANCH_L6"); POP6;NUMJPSL;break; + case cJL_JPBRANCH_L7: JPTYPE("cJL_JPBRANCH_L7"); POP7;NUMJPSL;break; +#endif + case cJL_JPBRANCH_L: JPTYPE("cJL_JPBRANCH_L"); NUMJPSL;break; + + case cJL_JPBRANCH_B2: JPTYPE("cJL_JPBRANCH_B2"); POP2;NUMJPSB;break; + case cJL_JPBRANCH_B3: JPTYPE("cJL_JPBRANCH_B3"); POP3;NUMJPSB;break; +#ifdef JU_64BIT + case cJL_JPBRANCH_B4: JPTYPE("cJL_JPBRANCH_B4"); POP4;NUMJPSB;break; + case cJL_JPBRANCH_B5: JPTYPE("cJL_JPBRANCH_B5"); POP5;NUMJPSB;break; + case cJL_JPBRANCH_B6: JPTYPE("cJL_JPBRANCH_B6"); POP6;NUMJPSB;break; + case cJL_JPBRANCH_B7: JPTYPE("cJL_JPBRANCH_B7"); POP7;NUMJPSB;break; +#endif + case cJL_JPBRANCH_B: JPTYPE("cJL_JPBRANCH_B"); NUMJPSB;break; + + case cJL_JPBRANCH_U2: JPTYPE("cJL_JPBRANCH_U2"); POP2; break; + case cJL_JPBRANCH_U3: JPTYPE("cJL_JPBRANCH_U3"); POP3; break; +#ifdef JU_64BIT + case cJL_JPBRANCH_U4: JPTYPE("cJL_JPBRANCH_U4"); POP4; break; + case cJL_JPBRANCH_U5: JPTYPE("cJL_JPBRANCH_U5"); POP5; break; + case cJL_JPBRANCH_U6: JPTYPE("cJL_JPBRANCH_U6"); POP6; break; + case cJL_JPBRANCH_U7: JPTYPE("cJL_JPBRANCH_U7"); POP7; break; +#endif + case cJL_JPBRANCH_U: JPTYPE("cJL_JPBRANCH_U"); break; + + case cJL_JPLEAF1: JPTYPE("cJL_JPLEAF1"); POP1; break; + case cJL_JPLEAF2: JPTYPE("cJL_JPLEAF2"); POP2; break; + case cJL_JPLEAF3: JPTYPE("cJL_JPLEAF3"); POP3; break; +#ifdef JU_64BIT + case cJL_JPLEAF4: JPTYPE("cJL_JPLEAF4"); POP4; break; + case cJL_JPLEAF5: JPTYPE("cJL_JPLEAF5"); POP5; break; + case cJL_JPLEAF6: JPTYPE("cJL_JPLEAF6"); POP6; break; + case cJL_JPLEAF7: JPTYPE("cJL_JPLEAF7"); POP7; break; +#endif + + case cJL_JPLEAF_B1: JPTYPE("cJL_JPLEAF_B1"); POP1; break; + + case cJL_JPIMMED_1_01: JPTYPE("cJL_JPIMMED_1_01"); POP_1; break; + case cJL_JPIMMED_2_01: JPTYPE("cJL_JPIMMED_2_01"); POP_1; break; + case cJL_JPIMMED_3_01: JPTYPE("cJL_JPIMMED_3_01"); POP_1; break; +#ifdef JU_64BIT + case cJL_JPIMMED_4_01: JPTYPE("cJL_JPIMMED_4_01"); POP_1; break; + case cJL_JPIMMED_5_01: JPTYPE("cJL_JPIMMED_5_01"); POP_1; break; + case cJL_JPIMMED_6_01: JPTYPE("cJL_JPIMMED_6_01"); POP_1; break; + case cJL_JPIMMED_7_01: JPTYPE("cJL_JPIMMED_7_01"); POP_1; break; +#endif + + case cJL_JPIMMED_1_02: JPTYPE("cJL_JPIMMED_1_02"); POP_2; break; + case cJL_JPIMMED_1_03: JPTYPE("cJL_JPIMMED_1_03"); POP_3; break; +#ifdef JU_64BIT + case cJL_JPIMMED_1_04: JPTYPE("cJL_JPIMMED_1_04"); POP_4; break; + case cJL_JPIMMED_1_05: JPTYPE("cJL_JPIMMED_1_05"); POP_5; break; + case cJL_JPIMMED_1_06: JPTYPE("cJL_JPIMMED_1_06"); POP_6; break; + case cJL_JPIMMED_1_07: JPTYPE("cJL_JPIMMED_1_07"); POP_7; break; + case cJL_JPIMMED_2_02: JPTYPE("cJL_JPIMMED_2_02"); POP_2; break; + case cJL_JPIMMED_2_03: JPTYPE("cJL_JPIMMED_2_03"); POP_3; break; + case cJL_JPIMMED_3_02: JPTYPE("cJL_JPIMMED_3_02"); POP_2; break; +#endif + case cJL_JPIMMED_CAP: JPTYPE("cJL_JPIMMED_CAP"); OOPS; + +#endif // JUDYL + + default: printf("Unknown Type = %d", JU_JPTYPE(Pjp)); OOPS; + } + + if (j__udyIndex) printf("Index = 0x%lx", j__udyIndex); + if (j__udyPopulation) printf("Pop = %lu", j__udyPopulation); + + printf("line = %d\n", Line); + +} // JudyPrintJP() diff --git a/feeds/p4/libjudy/src/src/JudyCommon/JudyPrivate.h b/feeds/p4/libjudy/src/src/JudyCommon/JudyPrivate.h new file mode 100644 index 000000000..350631f01 --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudyCommon/JudyPrivate.h @@ -0,0 +1,1613 @@ +#ifndef _JUDYPRIVATE_INCLUDED +#define _JUDYPRIVATE_INCLUDED +// _________________ +// +// Copyright (C) 2000 - 2002 Hewlett-Packard Company +// +// This program is free software; you can redistribute it and/or modify it +// under the term of the GNU Lesser 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 Lesser General Public License +// for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// _________________ + +// @(#) $Revision: 4.77 $ $Source: /judy/src/JudyCommon/JudyPrivate.h $ +// +// Header file for all Judy sources, for global but private (non-exported) +// declarations. + +#include "Judy.h" + +// **************************************************************************** +// A VERY BRIEF EXPLANATION OF A JUDY ARRAY +// +// A Judy array is, effectively, a digital tree (or Trie) with 256 element +// branches (nodes), and with "compression tricks" applied to low-population +// branches or leaves to save a lot of memory at the cost of relatively little +// CPU time or cache fills. +// +// In the actual implementation, a Judy array is level-less, and traversing the +// "tree" actually means following the states in a state machine (SM) as +// directed by the Index. A Judy array is referred to here as an "SM", rather +// than as a "tree"; having "states", rather than "levels". +// +// Each branch or leaf in the SM decodes a portion ("digit") of the original +// Index; with 256-way branches there are 8 bits per digit. There are 3 kinds +// of branches, called: Linear, Bitmap and Uncompressed, of which the first 2 +// are compressed to contain no NULL entries. +// +// An Uncompressed branch has a 1.0 cache line fill cost to decode 8 bits of +// (digit, part of an Index), but it might contain many NULL entries, and is +// therefore inefficient with memory if lightly populated. +// +// A Linear branch has a ~1.75 cache line fill cost when at maximum population. +// A Bitmap branch has ~2.0 cache line fills. Linear and Bitmap branches are +// converted to Uncompressed branches when the additional memory can be +// amortized with larger populations. Higher-state branches have higher +// priority to be converted. +// +// Linear branches can hold 28 elements (based on detailed analysis) -- thus 28 +// expanses. A Linear branch is converted to a Bitmap branch when the 29th +// expanse is required. +// +// A Bitmap branch could hold 256 expanses, but is forced to convert to an +// Uncompressed branch when 185 expanses are required. Hopefully, it is +// converted before that because of population growth (again, based on detailed +// analysis and heuristics in the code). +// +// A path through the SM terminates to a leaf when the Index (or key) +// population in the expanse below a pointer will fit into 1 or 2 cache lines +// (~31..255 Indexes). A maximum-population Leaf has ~1.5 cache line fill +// cost. +// +// Leaves are sorted arrays of Indexes, where the Index Sizes (IS) are: 0, 1, +// 8, 16, 24, 32, [40, 48, 56, 64] bits. The IS depends on the "density" +// (population/expanse) of the values in the Leaf. Zero bits are possible if +// population == expanse in the SM (that is, a full small expanse). +// +// Elements of a branches are called Judy Pointers (JPs). Each JP object +// points to the next object in the SM, plus, a JP can decode an additional +// 2[6] bytes of an Index, but at the cost of "narrowing" the expanse +// represented by the next object in the SM. A "narrow" JP (one which has +// decode bytes/digits) is a way of skipping states in the SM. +// +// Although counterintuitive, we think a Judy SM is optimal when the Leaves are +// stored at MINIMUM compression (narrowing, or use of Decode bytes). If more +// aggressive compression was used, decompression of a leaf be required to +// insert an index. Additional compression would save a little memory but not +// help performance significantly. + + +#ifdef A_PICTURE_IS_WORTH_1000_WORDS +******************************************************************************* + +JUDY 32-BIT STATE MACHINE (SM) EXAMPLE, FOR INDEX = 0x02040103 + +The Index used in this example is purposely chosen to allow small, simple +examples below; each 1-byte "digit" from the Index has a small numeric value +that fits in one column. In the drawing below: + + JRP == Judy Root Pointer; + + C == 1 byte of a 1..3 byte Population (count of Indexes) below this + pointer. Since this is shared with the Decode field, the combined + sizes must be 3[7], that is, 1 word less 1 byte for the JP Type. + + The 1-byte field jp_Type is represented as: + + 1..3 == Number of bytes in the population (Pop0) word of the Branch or Leaf + below the pointer (note: 1..7 on 64-bit); indicates: + - number of bytes in Decode field == 3 - this number; + - number of bytes remaining to decode. + Note: The maximum is 3, not 4, because the 1st byte of the Index is + always decoded digitally in the top branch. + -B- == JP points to a Branch (there are many kinds of Branches). + -L- == JP points to a Leaf (there are many kinds of Leaves). + + (2) == Digit of Index decoded by position offset in branch (really + 0..0xff). + + 4* == Digit of Index necessary for decoding a "narrow" pointer, in a + Decode field; replaces 1 missing branch (really 0..0xff). + + 4+ == Digit of Index NOT necessary for decoding a "narrow" pointer, but + used for fast traversal of the SM by Judy1Test() and JudyLGet() + (see the code) (really 0..0xff). + + 0 == Byte in a JPs Pop0 field that is always ignored, because a leaf + can never contain more than 256 Indexes (Pop0 <= 255). + + +----- == A Branch or Leaf; drawn open-ended to remind you that it could + | have up to 256 columns. + +----- + + | + | == Pointer to next Branch or Leaf. + V + + | + O == A state is skipped by using a "narrow" pointer. + | + + < 1 > == Digit (Index) shown as an example is not necessarily in the + position shown; is sorted in order with neighbor Indexes. + (Really 0..0xff.) + +Note that this example shows every possibly topology to reach a leaf in a +32-bit Judy SM, although this is a very subtle point! + + STATE or` + LEVEL + +---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+ + |RJP| |RJP| |RJP| |RJP| |RJP| |RJP| |RJP| |RJP| + L---+ B---+ B---+ B---+ B---+ B---+ B---+ B---+ + | | | | | | | | + | | | | | | | | + V V (2) V (2) V (2) V (2) V (2) V (2) V (2) + +------ +------ +------ +------ +------ +------ +------ +------ +Four |< 2 > | 0 | 4* | C | 4* | 4* | C | C +byte |< 4 > | 0 | 0 | C | 1* | C | C | C 4 +Index|< 1 > | C | C | C | C | C | C | C +Leaf |< 3 > | 3 | 2 | 3 | 1 | 2 | 3 | 3 + +------ +--L--- +--L--- +--B--- +--L--- +--B--- +--B--- +--B--- + | | | | | | | + / | / | | / / + / | / | | / / + | | | | | | | + V | V (4) | | V (4) V (4) + +------ | +------ | | +------ +------ + Three |< 4 > | | 4+ | | | 4+ | 4+ + byte Index|< 1 > O | 0 O O | 1* | C 3 + Leaf |< 3 > | | C | | | C | C + +------ | | 2 | | | 1 | 2 + / +----L- | | +----L- +----B- + / | | | | | + | / | / / / + | / | / / / + | / | | / / + | / | | / / + | | | | | | + V V | V(1) | V(1) + +------ +------ | +------ | +------ + Two byte |< 1 > |< 1 > | | 4+ | | 4+ + Index Leaf |< 3 > |< 3 > O | 1+ O | 1+ 2 + +------ +------ / | C | | C + / | 1 | | 1 + | +-L---- | +-L---- + | | | | + | / | / + | | | | + V V V V + +------ +------ +------ +------ + One byte Index Leaf |< 3 > |< 3 > |< 3 > |< 3 > 1 + +------ +------ +------ +------ + + +#endif // A_PICTURE_IS_WORTH_1000_WORDS + + +// **************************************************************************** +// MISCELLANEOUS GLOBALS: +// +// PLATFORM-SPECIFIC CONVENIENCE MACROS: +// +// These are derived from context (set by cc or in system header files) or +// based on JU_ macros from make_includes/platform.*.mk. We decided +// on 011018 that any macro reliably derivable from context (cc or headers) for +// ALL platforms supported by Judy is based on that derivation, but ANY +// exception means to stop using the external macro completely and derive from +// JU_ instead. + +// Other miscellaneous stuff: + +#ifndef _BOOL_T +#define _BOOL_T +typedef int bool_t; +#endif + +#define FUNCTION // null; easy to find functions. + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifdef TRACE // turn on all other tracing in the code: +#define TRACEJP 1 // JP traversals in JudyIns.c and JudyDel.c. +#define TRACEJPR 1 // JP traversals in retrieval code, JudyGet.c. +#define TRACECF 1 // cache fills in JudyGet.c. +#define TRACEMI 1 // malloc calls in JudyMallocIF.c. +#define TRACEMF 1 // malloc calls at a lower level in JudyMalloc.c. +#endif + + +// SUPPORT FOR DEBUG-ONLY CODE: +// +// By convention, use -DDEBUG to enable both debug-only code AND assertions in +// the Judy sources. +// +// Invert the sense of assertions, so they are off unless explicitly requested, +// in a uniform way. +// +// Note: It is NOT appropriate to put this in Judy.h; it would mess up +// application code. + +#ifndef DEBUG +#define NDEBUG 1 // must be 1 for "#if". +#endif + +// Shorthand notations to avoid #ifdefs for single-line conditional statements: +// +// Warning: These cannot be used around compiler directives, such as +// "#include", nor in the case where Code contains a comma other than nested +// within parentheses or quotes. + +#ifndef DEBUG +#define DBGCODE(Code) // null. +#else +#define DBGCODE(Code) Code +#endif + +#ifdef JUDY1 +#define JUDY1CODE(Code) Code +#define JUDYLCODE(Code) // null. +#endif + +#ifdef JUDYL +#define JUDYLCODE(Code) Code +#define JUDY1CODE(Code) // null. +#endif + +#include + +// **************************************************************************** +// FUNDAMENTAL CONSTANTS FOR MACHINE +// **************************************************************************** + +// Machine (CPU) cache line size: +// +// NOTE: A leaf size of 2 cache lines maximum is the target (optimal) for +// Judy. Its hard to obtain a machines cache line size at compile time, but +// if the machine has an unexpected cache line size, its not devastating if +// the following constants end up causing leaves that are 1 cache line in size, +// or even 4 cache lines in size. The assumed 32-bit system has 16-word = +// 64-byte cache lines, and the assumed 64-bit system has 16-word = 128-byte +// cache lines. + +#ifdef JU_64BIT +#define cJU_BYTESPERCL 128 // cache line size in bytes. +#else +#define cJU_BYTESPERCL 64 // cache line size in bytes. +#endif + +// Bits Per Byte: + +#define cJU_BITSPERBYTE 0x8 + +// Bytes Per Word and Bits Per Word, latter assuming sizeof(byte) is 8 bits: +// +// Expect 32 [64] bits per word. + +#define cJU_BYTESPERWORD (sizeof(Word_t)) +#define cJU_BITSPERWORD (sizeof(Word_t) * cJU_BITSPERBYTE) + +#define JU_BYTESTOWORDS(BYTES) \ + (((BYTES) + cJU_BYTESPERWORD - 1) / cJU_BYTESPERWORD) + +// A word that is all-ones, normally equal to -1UL, but safer with ~0: + +#define cJU_ALLONES (~0UL) + +// Note, these are forward references, but thats OK: + +#define cJU_FULLBITMAPB ((BITMAPB_t) cJU_ALLONES) +#define cJU_FULLBITMAPL ((BITMAPL_t) cJU_ALLONES) + + +// **************************************************************************** +// MISCELLANEOUS JUDY-SPECIFIC DECLARATIONS +// **************************************************************************** + +// ROOT STATE: +// +// State at the start of the Judy SM, based on 1 byte decoded per state; equal +// to the number of bytes per Index to decode. + +#define cJU_ROOTSTATE (sizeof(Word_t)) + + +// SUBEXPANSES PER STATE: +// +// Number of subexpanses per state traversed, which is the number of JPs in a +// branch (actual or theoretical) and the number of bits in a bitmap. + +#define cJU_SUBEXPPERSTATE 256 + + +// LEAF AND VALUE POINTERS: +// +// Some other basic object types are in declared in JudyPrivateBranch.h +// (Pjbl_t, Pjbb_t, Pjbu_t, Pjp_t) or are Judy1/L-specific (Pjlb_t). The +// few remaining types are declared below. +// +// Note: Leaf pointers are cast to different-sized objects depending on the +// leafs level, but are at least addresses (not just numbers), so use void * +// (Pvoid_t), not PWord_t or Word_t for them, except use Pjlw_t for whole-word +// (top-level, root-level) leaves. Value areas, however, are always whole +// words. +// +// Furthermore, use Pjll_t only for generic leaf pointers (for various size +// LeafLs). Use Pjlw_t for LeafWs. Use Pleaf (with type uint8_t *, uint16_t +// *, etc) when the leaf index size is known. + +typedef PWord_t Pjlw_t; // pointer to root-level leaf (whole-word indexes). +typedef Pvoid_t Pjll_t; // pointer to lower-level linear leaf. + +#ifdef JUDYL +typedef PWord_t Pjv_t; // pointer to JudyL value area. +#endif + + +// POINTER PREPARATION MACROS: +// +// These macros are used to strip malloc-namespace-type bits from a pointer + +// malloc-type word (which references any Judy mallocd object that might be +// obtained from other than a direct call of malloc()), prior to dereferencing +// the pointer as an address. The malloc-type bits allow Judy mallocd objects +// to come from different "malloc() namespaces". +// +// (root pointer) (JRP, see above) +// jp.jp_Addr generic pointer to next-level node, except when used +// as a JudyL Immed01 value area +// JU_JBB_PJP macro hides jbbs_Pjp (pointer to JP subarray) +// JL_JLB_PVALUE macro hides jLlbs_PValue (pointer to value subarray) +// +// When setting one of these fields or passing an address to j__udyFree*(), the +// "raw" memory address is used; otherwise the memory address must be passed +// through one of the macros below before its dereferenced. +// +// Note: After much study, the typecasts below appear in the macros rather +// than at the point of use, which is both simpler and allows the compiler to +// do type-checking. + + +#define P_JLW( ADDR) ((Pjlw_t) (ADDR)) // root leaf. +#define P_JPM( ADDR) ((Pjpm_t) (ADDR)) // root JPM. +#define P_JBL( ADDR) ((Pjbl_t) (ADDR)) // BranchL. +#define P_JBB( ADDR) ((Pjbb_t) (ADDR)) // BranchB. +#define P_JBU( ADDR) ((Pjbu_t) (ADDR)) // BranchU. +#define P_JLL( ADDR) ((Pjll_t) (ADDR)) // LeafL. +#define P_JLB( ADDR) ((Pjlb_t) (ADDR)) // LeafB1. +#define P_JP( ADDR) ((Pjp_t) (ADDR)) // JP. + +#ifdef JUDYL +#define P_JV( ADDR) ((Pjv_t) (ADDR)) // &value. +#endif + + +// LEAST BYTES: +// +// Mask for least bytes of a word, and a macro to perform this mask on an +// Index. +// +// Note: This macro has been problematic in the past to get right and to make +// portable. Its not OK on all systems to shift by the full word size. This +// macro should allow shifting by 1..N bytes, where N is the word size, but +// should produce a compiler warning if the macro is called with Bytes == 0. +// +// Warning: JU_LEASTBYTESMASK() is not a constant macro unless Bytes is a +// constant; otherwise it is a variable shift, which is expensive on some +// processors. + +#define JU_LEASTBYTESMASK(BYTES) \ + ((0x100UL << (cJU_BITSPERBYTE * ((BYTES) - 1))) - 1) + +#define JU_LEASTBYTES(INDEX,BYTES) ((INDEX) & JU_LEASTBYTESMASK(BYTES)) + + +// BITS IN EACH BITMAP SUBEXPANSE FOR BITMAP BRANCH AND LEAF: +// +// The bits per bitmap subexpanse times the number of subexpanses equals a +// constant (cJU_SUBEXPPERSTATE). You can also think of this as a compile-time +// choice of "aspect ratio" for bitmap branches and leaves (which can be set +// independently for each). +// +// A default aspect ratio is hardwired here if not overridden at compile time, +// such as by "EXTCCOPTS=-DBITMAP_BRANCH16x16 make". + +#if (! (defined(BITMAP_BRANCH8x32) || defined(BITMAP_BRANCH16x16) || defined(BITMAP_BRANCH32x8))) +#define BITMAP_BRANCH32x8 1 // 32 bits per subexpanse, 8 subexpanses. +#endif + +#ifdef BITMAP_BRANCH8x32 +#define BITMAPB_t uint8_t +#endif + +#ifdef BITMAP_BRANCH16x16 +#define BITMAPB_t uint16_t +#endif + +#ifdef BITMAP_BRANCH32x8 +#define BITMAPB_t uint32_t +#endif + +// Note: For bitmap leaves, BITMAP_LEAF64x4 is only valid for 64 bit: +// +// Note: Choice of aspect ratio mostly matters for JudyL bitmap leaves. For +// Judy1 the choice doesnt matter much -- the code generated for different +// BITMAP_LEAF* values choices varies, but correctness and performance are the +// same. + +#ifndef JU_64BIT + +#if (! (defined(BITMAP_LEAF8x32) || defined(BITMAP_LEAF16x16) || defined(BITMAP_LEAF32x8))) +#define BITMAP_LEAF32x8 // 32 bits per subexpanse, 8 subexpanses. +#endif + +#else // 32BIT + +#if (! (defined(BITMAP_LEAF8x32) || defined(BITMAP_LEAF16x16) || defined(BITMAP_LEAF32x8) || defined(BITMAP_LEAF64x4))) +#define BITMAP_LEAF64x4 // 64 bits per subexpanse, 4 subexpanses. + +#endif +#endif // JU_64BIT + +#ifdef BITMAP_LEAF8x32 +#define BITMAPL_t uint8_t +#endif + +#ifdef BITMAP_LEAF16x16 +#define BITMAPL_t uint16_t +#endif + +#ifdef BITMAP_LEAF32x8 +#define BITMAPL_t uint32_t +#endif + +#ifdef BITMAP_LEAF64x4 +#define BITMAPL_t uint64_t +#endif + + +// EXPORTED DATA AND FUNCTIONS: + +#ifdef JUDY1 +extern const uint8_t j__1_BranchBJPPopToWords[]; +#endif + +#ifdef JUDYL +extern const uint8_t j__L_BranchBJPPopToWords[]; +#endif + +// Fast LeafL search routine used for inlined code: + +#if (! defined(SEARCH_BINARY)) || (! defined(SEARCH_LINEAR)) +// default a binary search leaf method +#define SEARCH_BINARY 1 +//#define SEARCH_LINEAR 1 +#endif + +#ifdef SEARCH_LINEAR + +#define SEARCHLEAFNATIVE(LEAFTYPE,ADDR,POP1,INDEX) \ + LEAFTYPE *P_leaf = (LEAFTYPE *)(ADDR); \ + LEAFTYPE I_ndex = (INDEX); /* with masking */ \ + if (I_ndex > P_leaf[(POP1) - 1]) return(~(POP1)); \ + while(I_ndex > *P_leaf) P_leaf++; \ + if (I_ndex == *P_leaf) return(P_leaf - (LEAFTYPE *)(ADDR)); \ + return(~(P_leaf - (LEAFTYPE *)(ADDR))); + + +#define SEARCHLEAFNONNAT(ADDR,POP1,INDEX,LFBTS,COPYINDEX) \ +{ \ + uint8_t *P_leaf, *P_leafEnd; \ + Word_t i_ndex; \ + Word_t I_ndex = JU_LEASTBYTES((INDEX), (LFBTS)); \ + Word_t p_op1; \ + \ + P_leaf = (uint8_t *)(ADDR); \ + P_leafEnd = P_leaf + ((POP1) * (LFBTS)); \ + \ + do { \ + JU_COPY3_PINDEX_TO_LONG(i_ndex, P_leaf); \ + if (I_ndex <= i_ndex) break; \ + P_leaf += (LFBTS); \ + } while (P_leaf < P_leafEnd); \ + \ + p_op1 = (P_leaf - (uint8_t *) (ADDR)) / (LFBTS); \ + if (I_ndex == i_ndex) return(p_op1); \ + return(~p_op1); \ +} +#endif // SEARCH_LINEAR + +#ifdef SEARCH_BINARY + +#define SEARCHLEAFNATIVE(LEAFTYPE,ADDR,POP1,INDEX) \ + LEAFTYPE *P_leaf = (LEAFTYPE *)(ADDR); \ + LEAFTYPE I_ndex = (LEAFTYPE)INDEX; /* truncate hi bits */ \ + Word_t l_ow = cJU_ALLONES; \ + Word_t m_id; \ + Word_t h_igh = POP1; \ + \ + while ((h_igh - l_ow) > 1UL) \ + { \ + m_id = (h_igh + l_ow) / 2; \ + if (P_leaf[m_id] > I_ndex) \ + h_igh = m_id; \ + else \ + l_ow = m_id; \ + } \ + if (l_ow == cJU_ALLONES || P_leaf[l_ow] != I_ndex) \ + return(~h_igh); \ + return(l_ow) + + +#define SEARCHLEAFNONNAT(ADDR,POP1,INDEX,LFBTS,COPYINDEX) \ + uint8_t *P_leaf = (uint8_t *)(ADDR); \ + Word_t l_ow = cJU_ALLONES; \ + Word_t m_id; \ + Word_t h_igh = POP1; \ + Word_t I_ndex = JU_LEASTBYTES((INDEX), (LFBTS)); \ + Word_t i_ndex; \ + \ + I_ndex = JU_LEASTBYTES((INDEX), (LFBTS)); \ + \ + while ((h_igh - l_ow) > 1UL) \ + { \ + m_id = (h_igh + l_ow) / 2; \ + COPYINDEX(i_ndex, &P_leaf[m_id * (LFBTS)]); \ + if (i_ndex > I_ndex) \ + h_igh = m_id; \ + else \ + l_ow = m_id; \ + } \ + if (l_ow == cJU_ALLONES) return(~h_igh); \ + \ + COPYINDEX(i_ndex, &P_leaf[l_ow * (LFBTS)]); \ + if (i_ndex != I_ndex) return(~h_igh); \ + return(l_ow) + +#endif // SEARCH_BINARY + +// Fast way to count bits set in 8..32[64]-bit int: +// +// For performance, j__udyCountBits*() are written to take advantage of +// platform-specific features where available. +// + +#ifdef JU_NOINLINE + +extern BITMAPB_t j__udyCountBitsB(BITMAPB_t word); +extern BITMAPL_t j__udyCountBitsL(BITMAPL_t word); + +// Compiler supports inline + +#elif defined(JU_HPUX_IPF) + +#define j__udyCountBitsB(WORD) _Asm_popcnt(WORD) +#define j__udyCountBitsL(WORD) _Asm_popcnt(WORD) + +#elif defined(JU_LINUX_IPF) + +static inline BITMAPB_t j__udyCountBitsB(BITMAPB_t word) +{ + BITMAPB_t result; + __asm__ ("popcnt %0=%1" : "=r" (result) : "r" (word)); + return(result); +} + +static inline BITMAPL_t j__udyCountBitsL(BITMAPL_t word) +{ + BITMAPL_t result; + __asm__ ("popcnt %0=%1" : "=r" (result) : "r" (word)); + return(result); +} + + +#else // No instructions available, use inline code + +// **************************************************************************** +// __ J U D Y C O U N T B I T S B +// +// Return the number of bits set in "Word", for a bitmap branch. +// +// Note: Bitmap branches have maximum bitmap size = 32 bits. + +#ifdef JU_WIN +static __inline BITMAPB_t j__udyCountBitsB(BITMAPB_t word) +#else +static inline BITMAPB_t j__udyCountBitsB(BITMAPB_t word) +#endif +{ + word = (word & 0x55555555) + ((word & 0xAAAAAAAA) >> 1); + word = (word & 0x33333333) + ((word & 0xCCCCCCCC) >> 2); + word = (word & 0x0F0F0F0F) + ((word & 0xF0F0F0F0) >> 4); // >= 8 bits. +#if defined(BITMAP_BRANCH16x16) || defined(BITMAP_BRANCH32x8) + word = (word & 0x00FF00FF) + ((word & 0xFF00FF00) >> 8); // >= 16 bits. +#endif + +#ifdef BITMAP_BRANCH32x8 + word = (word & 0x0000FFFF) + ((word & 0xFFFF0000) >> 16); // >= 32 bits. +#endif + return(word); + +} // j__udyCountBitsB() + + +// **************************************************************************** +// __ J U D Y C O U N T B I T S L +// +// Return the number of bits set in "Word", for a bitmap leaf. +// +// Note: Bitmap branches have maximum bitmap size = 32 bits. + +// Note: Need both 32-bit and 64-bit versions of j__udyCountBitsL() because +// bitmap leaves can have 64-bit bitmaps. + +#ifdef JU_WIN +static __inline BITMAPL_t j__udyCountBitsL(BITMAPL_t word) +#else +static inline BITMAPL_t j__udyCountBitsL(BITMAPL_t word) +#endif +{ +#ifndef JU_64BIT + + word = (word & 0x55555555) + ((word & 0xAAAAAAAA) >> 1); + word = (word & 0x33333333) + ((word & 0xCCCCCCCC) >> 2); + word = (word & 0x0F0F0F0F) + ((word & 0xF0F0F0F0) >> 4); // >= 8 bits. +#if defined(BITMAP_LEAF16x16) || defined(BITMAP_LEAF32x8) + word = (word & 0x00FF00FF) + ((word & 0xFF00FF00) >> 8); // >= 16 bits. +#endif +#ifdef BITMAP_LEAF32x8 + word = (word & 0x0000FFFF) + ((word & 0xFFFF0000) >> 16); // >= 32 bits. +#endif + +#else // JU_64BIT + + word = (word & 0x5555555555555555) + ((word & 0xAAAAAAAAAAAAAAAA) >> 1); + word = (word & 0x3333333333333333) + ((word & 0xCCCCCCCCCCCCCCCC) >> 2); + word = (word & 0x0F0F0F0F0F0F0F0F) + ((word & 0xF0F0F0F0F0F0F0F0) >> 4); +#if defined(BITMAP_LEAF16x16) || defined(BITMAP_LEAF32x8) || defined(BITMAP_LEAF64x4) + word = (word & 0x00FF00FF00FF00FF) + ((word & 0xFF00FF00FF00FF00) >> 8); +#endif +#if defined(BITMAP_LEAF32x8) || defined(BITMAP_LEAF64x4) + word = (word & 0x0000FFFF0000FFFF) + ((word & 0xFFFF0000FFFF0000) >>16); +#endif +#ifdef BITMAP_LEAF64x4 + word = (word & 0x00000000FFFFFFFF) + ((word & 0xFFFFFFFF00000000) >>32); +#endif +#endif // JU_64BIT + + return(word); + +} // j__udyCountBitsL() + +#endif // Compiler supports inline + +// GET POP0: +// +// Get from jp_DcdPopO the Pop0 for various JP Types. +// +// Notes: +// +// - Different macros require different parameters... +// +// - There are no simple macros for cJU_BRANCH* Types because their +// populations must be added up and dont reside in an already-calculated +// place. (TBD: This is no longer true, now its in the JPM.) +// +// - cJU_JPIMM_POP0() is not defined because it would be redundant because the +// Pop1 is already encoded in each enum name. +// +// - A linear or bitmap leaf Pop0 cannot exceed cJU_SUBEXPPERSTATE - 1 (Pop0 = +// 0..255), so use a simpler, faster macro for it than for other JP Types. +// +// - Avoid any complex calculations that would slow down the compiled code. +// Assume these macros are only called for the appropriate JP Types. +// Unfortunately theres no way to trigger an assertion here if the JP type +// is incorrect for the macro, because these are merely expressions, not +// statements. + +#define JU_LEAFW_POP0(JRP) (*P_JLW(JRP)) +#define cJU_JPFULLPOPU1_POP0 (cJU_SUBEXPPERSTATE - 1) + +// GET JP Type: +// Since bit fields greater than 32 bits are not supported in some compilers +// the jp_DcdPopO field is expanded to include the jp_Type in the high 8 bits +// of the Word_t. +// First the read macro: + +#define JU_JPTYPE(PJP) ((PJP)->jp_Type) + +#define JU_JPLEAF_POP0(PJP) ((PJP)->jp_DcdP0[sizeof(Word_t) - 2]) + +#ifdef JU_64BIT + +#define JU_JPDCDPOP0(PJP) \ + ((Word_t)(PJP)->jp_DcdP0[0] << 48 | \ + (Word_t)(PJP)->jp_DcdP0[1] << 40 | \ + (Word_t)(PJP)->jp_DcdP0[2] << 32 | \ + (Word_t)(PJP)->jp_DcdP0[3] << 24 | \ + (Word_t)(PJP)->jp_DcdP0[4] << 16 | \ + (Word_t)(PJP)->jp_DcdP0[5] << 8 | \ + (Word_t)(PJP)->jp_DcdP0[6]) + + +#define JU_JPSETADT(PJP,ADDR,DCDPOP0,TYPE) \ +{ \ + (PJP)->jp_Addr = (ADDR); \ + (PJP)->jp_DcdP0[0] = (uint8_t)((Word_t)(DCDPOP0) >> 48); \ + (PJP)->jp_DcdP0[1] = (uint8_t)((Word_t)(DCDPOP0) >> 40); \ + (PJP)->jp_DcdP0[2] = (uint8_t)((Word_t)(DCDPOP0) >> 32); \ + (PJP)->jp_DcdP0[3] = (uint8_t)((Word_t)(DCDPOP0) >> 24); \ + (PJP)->jp_DcdP0[4] = (uint8_t)((Word_t)(DCDPOP0) >> 16); \ + (PJP)->jp_DcdP0[5] = (uint8_t)((Word_t)(DCDPOP0) >> 8); \ + (PJP)->jp_DcdP0[6] = (uint8_t)((Word_t)(DCDPOP0)); \ + (PJP)->jp_Type = (TYPE); \ +} + +#else // 32 Bit + +#define JU_JPDCDPOP0(PJP) \ + ((Word_t)(PJP)->jp_DcdP0[0] << 16 | \ + (Word_t)(PJP)->jp_DcdP0[1] << 8 | \ + (Word_t)(PJP)->jp_DcdP0[2]) + + +#define JU_JPSETADT(PJP,ADDR,DCDPOP0,TYPE) \ +{ \ + (PJP)->jp_Addr = (ADDR); \ + (PJP)->jp_DcdP0[0] = (uint8_t)((Word_t)(DCDPOP0) >> 16); \ + (PJP)->jp_DcdP0[1] = (uint8_t)((Word_t)(DCDPOP0) >> 8); \ + (PJP)->jp_DcdP0[2] = (uint8_t)((Word_t)(DCDPOP0)); \ + (PJP)->jp_Type = (TYPE); \ +} + +#endif // 32 Bit + +// NUMBER OF BITS IN A BRANCH OR LEAF BITMAP AND SUBEXPANSE: +// +// Note: cJU_BITSPERBITMAP must be the same as the number of JPs in a branch. + +#define cJU_BITSPERBITMAP cJU_SUBEXPPERSTATE + +// Bitmaps are accessed in units of "subexpanses": + +#define cJU_BITSPERSUBEXPB (sizeof(BITMAPB_t) * cJU_BITSPERBYTE) +#define cJU_NUMSUBEXPB (cJU_BITSPERBITMAP / cJU_BITSPERSUBEXPB) + +#define cJU_BITSPERSUBEXPL (sizeof(BITMAPL_t) * cJU_BITSPERBYTE) +#define cJU_NUMSUBEXPL (cJU_BITSPERBITMAP / cJU_BITSPERSUBEXPL) + + +// MASK FOR A SPECIFIED BIT IN A BITMAP: +// +// Warning: If BitNum is a variable, this results in a variable shift that is +// expensive, at least on some processors. Use with caution. +// +// Warning: BitNum must be less than cJU_BITSPERWORD, that is, 0 .. +// cJU_BITSPERWORD - 1, to avoid a truncated shift on some machines. +// +// TBD: Perhaps use an array[32] of masks instead of calculating them. + +#define JU_BITPOSMASKB(BITNUM) (1L << ((BITNUM) % cJU_BITSPERSUBEXPB)) +#define JU_BITPOSMASKL(BITNUM) (1L << ((BITNUM) % cJU_BITSPERSUBEXPL)) + + +// TEST/SET/CLEAR A BIT IN A BITMAP LEAF: +// +// Test if a byte-sized Digit (portion of Index) has a corresponding bit set in +// a bitmap, or set a byte-sized Digits bit into a bitmap, by looking up the +// correct subexpanse and then checking/setting the correct bit. +// +// Note: Mask higher bits, if any, for the convenience of the user of this +// macro, in case they pass a full Index, not just a digit. If the caller has +// a true 8-bit digit, make it of type uint8_t and the compiler should skip the +// unnecessary mask step. + +#define JU_SUBEXPL(DIGIT) (((DIGIT) / cJU_BITSPERSUBEXPL) & (cJU_NUMSUBEXPL-1)) + +#define JU_BITMAPTESTL(PJLB, INDEX) \ + (JU_JLB_BITMAP(PJLB, JU_SUBEXPL(INDEX)) & JU_BITPOSMASKL(INDEX)) + +#define JU_BITMAPSETL(PJLB, INDEX) \ + (JU_JLB_BITMAP(PJLB, JU_SUBEXPL(INDEX)) |= JU_BITPOSMASKL(INDEX)) + +#define JU_BITMAPCLEARL(PJLB, INDEX) \ + (JU_JLB_BITMAP(PJLB, JU_SUBEXPL(INDEX)) ^= JU_BITPOSMASKL(INDEX)) + + +// MAP BITMAP BIT OFFSET TO DIGIT: +// +// Given a digit variable to set, a bitmap branch or leaf subexpanse (base 0), +// the bitmap (BITMAP*_t) for that subexpanse, and an offset (Nth set bit in +// the bitmap, base 0), compute the digit (also base 0) corresponding to the +// subexpanse and offset by counting all bits in the bitmap until offset+1 set +// bits are seen. Avoid expensive variable shifts. Offset should be less than +// the number of set bits in the bitmap; assert this. +// +// If theres a better way to do this, I dont know what it is. + +#define JU_BITMAPDIGITB(DIGIT,SUBEXP,BITMAP,OFFSET) \ + { \ + BITMAPB_t bitmap = (BITMAP); int remain = (OFFSET); \ + (DIGIT) = (SUBEXP) * cJU_BITSPERSUBEXPB; \ + \ + while ((remain -= (bitmap & 1)) >= 0) \ + { \ + bitmap >>= 1; ++(DIGIT); \ + assert((DIGIT) < ((SUBEXP) + 1) * cJU_BITSPERSUBEXPB); \ + } \ + } + +#define JU_BITMAPDIGITL(DIGIT,SUBEXP,BITMAP,OFFSET) \ + { \ + BITMAPL_t bitmap = (BITMAP); int remain = (OFFSET); \ + (DIGIT) = (SUBEXP) * cJU_BITSPERSUBEXPL; \ + \ + while ((remain -= (bitmap & 1)) >= 0) \ + { \ + bitmap >>= 1; ++(DIGIT); \ + assert((DIGIT) < ((SUBEXP) + 1) * cJU_BITSPERSUBEXPL); \ + } \ + } + + +// MASKS FOR PORTIONS OF 32-BIT WORDS: +// +// These are useful for bitmap subexpanses. +// +// "LOWER"/"HIGHER" means bits representing lower/higher-valued Indexes. The +// exact order of bits in the word is explicit here but is hidden from the +// caller. +// +// "EXC" means exclusive of the specified bit; "INC" means inclusive. +// +// In each case, BitPos is either "JU_BITPOSMASK*(BitNum)", or a variable saved +// from an earlier call of that macro; either way, it must be a 32-bit word +// with a single bit set. In the first case, assume the compiler is smart +// enough to optimize out common subexpressions. +// +// The expressions depend on unsigned decimal math that should be universal. + +#define JU_MASKLOWEREXC( BITPOS) ((BITPOS) - 1) +#define JU_MASKLOWERINC( BITPOS) (JU_MASKLOWEREXC(BITPOS) | (BITPOS)) +#define JU_MASKHIGHERINC(BITPOS) (-(BITPOS)) +#define JU_MASKHIGHEREXC(BITPOS) (JU_MASKHIGHERINC(BITPOS) ^ (BITPOS)) + + +// **************************************************************************** +// SUPPORT FOR NATIVE INDEX SIZES +// **************************************************************************** +// +// Copy a series of generic objects (uint8_t, uint16_t, uint32_t, Word_t) from +// one place to another. + +#define JU_COPYMEM(PDST,PSRC,POP1) \ + { \ + Word_t i_ndex = 0; \ + assert((POP1) > 0); \ + do { (PDST)[i_ndex] = (PSRC)[i_ndex]; } \ + while (++i_ndex < (POP1)); \ + } + + +// **************************************************************************** +// SUPPORT FOR NON-NATIVE INDEX SIZES +// **************************************************************************** +// +// Copy a 3-byte Index pointed by a uint8_t * to a Word_t: +// +#define JU_COPY3_PINDEX_TO_LONG(DESTLONG,PINDEX) \ + DESTLONG = (Word_t)(PINDEX)[0] << 16; \ + DESTLONG += (Word_t)(PINDEX)[1] << 8; \ + DESTLONG += (Word_t)(PINDEX)[2] + +// Copy a Word_t to a 3-byte Index pointed at by a uint8_t *: + +#define JU_COPY3_LONG_TO_PINDEX(PINDEX,SOURCELONG) \ + (PINDEX)[0] = (uint8_t)((SOURCELONG) >> 16); \ + (PINDEX)[1] = (uint8_t)((SOURCELONG) >> 8); \ + (PINDEX)[2] = (uint8_t)((SOURCELONG)) + +#ifdef JU_64BIT + +// Copy a 5-byte Index pointed by a uint8_t * to a Word_t: +// +#define JU_COPY5_PINDEX_TO_LONG(DESTLONG,PINDEX) \ + DESTLONG = (Word_t)(PINDEX)[0] << 32; \ + DESTLONG += (Word_t)(PINDEX)[1] << 24; \ + DESTLONG += (Word_t)(PINDEX)[2] << 16; \ + DESTLONG += (Word_t)(PINDEX)[3] << 8; \ + DESTLONG += (Word_t)(PINDEX)[4] + +// Copy a Word_t to a 5-byte Index pointed at by a uint8_t *: + +#define JU_COPY5_LONG_TO_PINDEX(PINDEX,SOURCELONG) \ + (PINDEX)[0] = (uint8_t)((SOURCELONG) >> 32); \ + (PINDEX)[1] = (uint8_t)((SOURCELONG) >> 24); \ + (PINDEX)[2] = (uint8_t)((SOURCELONG) >> 16); \ + (PINDEX)[3] = (uint8_t)((SOURCELONG) >> 8); \ + (PINDEX)[4] = (uint8_t)((SOURCELONG)) + +// Copy a 6-byte Index pointed by a uint8_t * to a Word_t: +// +#define JU_COPY6_PINDEX_TO_LONG(DESTLONG,PINDEX) \ + DESTLONG = (Word_t)(PINDEX)[0] << 40; \ + DESTLONG += (Word_t)(PINDEX)[1] << 32; \ + DESTLONG += (Word_t)(PINDEX)[2] << 24; \ + DESTLONG += (Word_t)(PINDEX)[3] << 16; \ + DESTLONG += (Word_t)(PINDEX)[4] << 8; \ + DESTLONG += (Word_t)(PINDEX)[5] + +// Copy a Word_t to a 6-byte Index pointed at by a uint8_t *: + +#define JU_COPY6_LONG_TO_PINDEX(PINDEX,SOURCELONG) \ + (PINDEX)[0] = (uint8_t)((SOURCELONG) >> 40); \ + (PINDEX)[1] = (uint8_t)((SOURCELONG) >> 32); \ + (PINDEX)[2] = (uint8_t)((SOURCELONG) >> 24); \ + (PINDEX)[3] = (uint8_t)((SOURCELONG) >> 16); \ + (PINDEX)[4] = (uint8_t)((SOURCELONG) >> 8); \ + (PINDEX)[5] = (uint8_t)((SOURCELONG)) + +// Copy a 7-byte Index pointed by a uint8_t * to a Word_t: +// +#define JU_COPY7_PINDEX_TO_LONG(DESTLONG,PINDEX) \ + DESTLONG = (Word_t)(PINDEX)[0] << 48; \ + DESTLONG += (Word_t)(PINDEX)[1] << 40; \ + DESTLONG += (Word_t)(PINDEX)[2] << 32; \ + DESTLONG += (Word_t)(PINDEX)[3] << 24; \ + DESTLONG += (Word_t)(PINDEX)[4] << 16; \ + DESTLONG += (Word_t)(PINDEX)[5] << 8; \ + DESTLONG += (Word_t)(PINDEX)[6] + +// Copy a Word_t to a 7-byte Index pointed at by a uint8_t *: + +#define JU_COPY7_LONG_TO_PINDEX(PINDEX,SOURCELONG) \ + (PINDEX)[0] = (uint8_t)((SOURCELONG) >> 48); \ + (PINDEX)[1] = (uint8_t)((SOURCELONG) >> 40); \ + (PINDEX)[2] = (uint8_t)((SOURCELONG) >> 32); \ + (PINDEX)[3] = (uint8_t)((SOURCELONG) >> 24); \ + (PINDEX)[4] = (uint8_t)((SOURCELONG) >> 16); \ + (PINDEX)[5] = (uint8_t)((SOURCELONG) >> 8); \ + (PINDEX)[6] = (uint8_t)((SOURCELONG)) + +#endif // JU_64BIT + +// **************************************************************************** +// COMMON CODE FRAGMENTS (MACROS) +// **************************************************************************** +// +// These code chunks are shared between various source files. + + +// SET (REPLACE) ONE DIGIT IN AN INDEX: +// +// To avoid endian issues, use masking and ORing, which operates in a +// big-endian register, rather than treating the Index as an array of bytes, +// though that would be simpler, but would operate in endian-specific memory. +// +// TBD: This contains two variable shifts, is that bad? + +#define JU_SETDIGIT(INDEX,DIGIT,STATE) \ + (INDEX) = ((INDEX) & (~cJU_MASKATSTATE(STATE))) \ + | (((Word_t) (DIGIT)) \ + << (((STATE) - 1) * cJU_BITSPERBYTE)) + +// Fast version for single LSB: + +#define JU_SETDIGIT1(INDEX,DIGIT) (INDEX) = ((INDEX) & ~0xff) | (DIGIT) + + +// SET (REPLACE) "N" LEAST DIGITS IN AN INDEX: + +#define JU_SETDIGITS(INDEX,INDEX2,cSTATE) \ + (INDEX) = ((INDEX ) & (~JU_LEASTBYTESMASK(cSTATE))) \ + | ((INDEX2) & ( JU_LEASTBYTESMASK(cSTATE))) + +// COPY DECODE BYTES FROM JP TO INDEX: +// +// Modify Index digit(s) to match the bytes in jp_DcdPopO in case one or more +// branches are skipped and the digits are significant. Its probably faster +// to just do this unconditionally than to check if its necessary. +// +// To avoid endian issues, use masking and ORing, which operates in a +// big-endian register, rather than treating the Index as an array of bytes, +// though that would be simpler, but would operate in endian-specific memory. +// +// WARNING: Must not call JU_LEASTBYTESMASK (via cJU_DCDMASK) with Bytes = +// cJU_ROOTSTATE or a bad mask is generated, but there are no Dcd bytes to copy +// in this case anyway. In fact there are no Dcd bytes unless State < +// cJU_ROOTSTATE - 1, so dont call this macro except in those cases. +// +// TBD: It would be nice to validate jp_DcdPopO against known digits to ensure +// no corruption, but this is non-trivial. + +#define JU_SETDCD(INDEX,PJP,cSTATE) \ + (INDEX) = ((INDEX) & ~cJU_DCDMASK(cSTATE)) \ + | (JU_JPDCDPOP0(PJP) & cJU_DCDMASK(cSTATE)) + +// INSERT/DELETE AN INDEX IN-PLACE IN MEMORY: +// +// Given a pointer to an array of "even" (native), same-sized objects +// (indexes), the current population of the array, an offset in the array, and +// a new Index to insert, "shift up" the array elements (Indexes) above the +// insertion point and insert the new Index. Assume there is sufficient memory +// to do this. +// +// In these macros, "i_offset" is an index offset, and "b_off" is a byte +// offset for odd Index sizes. +// +// Note: Endian issues only arise fro insertion, not deletion, and even for +// insertion, they are transparent when native (even) objects are used, and +// handled explicitly for odd (non-native) Index sizes. +// +// Note: The following macros are tricky enough that there is some test code +// for them appended to this file. + +#define JU_INSERTINPLACE(PARRAY,POP1,OFFSET,INDEX) \ + assert((long) (POP1) > 0); \ + assert((Word_t) (OFFSET) <= (Word_t) (POP1)); \ + { \ + Word_t i_offset = (POP1); \ + \ + while (i_offset-- > (OFFSET)) \ + (PARRAY)[i_offset + 1] = (PARRAY)[i_offset]; \ + \ + (PARRAY)[OFFSET] = (INDEX); \ + } + + +// Variation for non-native Indexes, where cIS = Index Size +// and PByte must point to a uint8_t (byte); shift byte-by-byte: +// + +#define JU_INSERTINPLACE3(PBYTE,POP1,OFFSET,INDEX) \ +{ \ + Word_t i_off = POP1; \ + \ + while (i_off-- > (OFFSET)) \ + { \ + Word_t i_dx = i_off * 3; \ + (PBYTE)[i_dx + 0 + 3] = (PBYTE)[i_dx + 0]; \ + (PBYTE)[i_dx + 1 + 3] = (PBYTE)[i_dx + 1]; \ + (PBYTE)[i_dx + 2 + 3] = (PBYTE)[i_dx + 2]; \ + } \ + JU_COPY3_LONG_TO_PINDEX(&((PBYTE)[(OFFSET) * 3]), INDEX); \ +} + +#ifdef JU_64BIT + +#define JU_INSERTINPLACE5(PBYTE,POP1,OFFSET,INDEX) \ +{ \ + Word_t i_off = POP1; \ + \ + while (i_off-- > (OFFSET)) \ + { \ + Word_t i_dx = i_off * 5; \ + (PBYTE)[i_dx + 0 + 5] = (PBYTE)[i_dx + 0]; \ + (PBYTE)[i_dx + 1 + 5] = (PBYTE)[i_dx + 1]; \ + (PBYTE)[i_dx + 2 + 5] = (PBYTE)[i_dx + 2]; \ + (PBYTE)[i_dx + 3 + 5] = (PBYTE)[i_dx + 3]; \ + (PBYTE)[i_dx + 4 + 5] = (PBYTE)[i_dx + 4]; \ + } \ + JU_COPY5_LONG_TO_PINDEX(&((PBYTE)[(OFFSET) * 5]), INDEX); \ +} + +#define JU_INSERTINPLACE6(PBYTE,POP1,OFFSET,INDEX) \ +{ \ + Word_t i_off = POP1; \ + \ + while (i_off-- > (OFFSET)) \ + { \ + Word_t i_dx = i_off * 6; \ + (PBYTE)[i_dx + 0 + 6] = (PBYTE)[i_dx + 0]; \ + (PBYTE)[i_dx + 1 + 6] = (PBYTE)[i_dx + 1]; \ + (PBYTE)[i_dx + 2 + 6] = (PBYTE)[i_dx + 2]; \ + (PBYTE)[i_dx + 3 + 6] = (PBYTE)[i_dx + 3]; \ + (PBYTE)[i_dx + 4 + 6] = (PBYTE)[i_dx + 4]; \ + (PBYTE)[i_dx + 5 + 6] = (PBYTE)[i_dx + 5]; \ + } \ + JU_COPY6_LONG_TO_PINDEX(&((PBYTE)[(OFFSET) * 6]), INDEX); \ +} + +#define JU_INSERTINPLACE7(PBYTE,POP1,OFFSET,INDEX) \ +{ \ + Word_t i_off = POP1; \ + \ + while (i_off-- > (OFFSET)) \ + { \ + Word_t i_dx = i_off * 7; \ + (PBYTE)[i_dx + 0 + 7] = (PBYTE)[i_dx + 0]; \ + (PBYTE)[i_dx + 1 + 7] = (PBYTE)[i_dx + 1]; \ + (PBYTE)[i_dx + 2 + 7] = (PBYTE)[i_dx + 2]; \ + (PBYTE)[i_dx + 3 + 7] = (PBYTE)[i_dx + 3]; \ + (PBYTE)[i_dx + 4 + 7] = (PBYTE)[i_dx + 4]; \ + (PBYTE)[i_dx + 5 + 7] = (PBYTE)[i_dx + 5]; \ + (PBYTE)[i_dx + 6 + 7] = (PBYTE)[i_dx + 6]; \ + } \ + JU_COPY7_LONG_TO_PINDEX(&((PBYTE)[(OFFSET) * 7]), INDEX); \ +} +#endif // JU_64BIT + +// Counterparts to the above for deleting an Index: +// +// "Shift down" the array elements starting at the Index to be deleted. + +#define JU_DELETEINPLACE(PARRAY,POP1,OFFSET,IGNORE) \ + assert((long) (POP1) > 0); \ + assert((Word_t) (OFFSET) < (Word_t) (POP1)); \ + { \ + Word_t i_offset = (OFFSET); \ + \ + while (++i_offset < (POP1)) \ + (PARRAY)[i_offset - 1] = (PARRAY)[i_offset]; \ + } + +// Variation for odd-byte-sized (non-native) Indexes, where cIS = Index Size +// and PByte must point to a uint8_t (byte); copy byte-by-byte: +// +// Note: If cIS == 1, JU_DELETEINPLACE_ODD == JU_DELETEINPLACE. +// +// Note: There are no endian issues here because bytes are just shifted as-is, +// not converted to/from an Index. + +#define JU_DELETEINPLACE_ODD(PBYTE,POP1,OFFSET,cIS) \ + assert((long) (POP1) > 0); \ + assert((Word_t) (OFFSET) < (Word_t) (POP1)); \ + { \ + Word_t b_off = (((OFFSET) + 1) * (cIS)) - 1; \ + \ + while (++b_off < ((POP1) * (cIS))) \ + (PBYTE)[b_off - (cIS)] = (PBYTE)[b_off]; \ + } + + +// INSERT/DELETE AN INDEX WHILE COPYING OTHERS: +// +// Copy PSource[] to PDest[], where PSource[] has Pop1 elements (Indexes), +// inserting Index at PDest[Offset]. Unlike JU_*INPLACE*() above, these macros +// are used when moving Indexes from one memory object to another. + +#define JU_INSERTCOPY(PDEST,PSOURCE,POP1,OFFSET,INDEX) \ + assert((long) (POP1) > 0); \ + assert((Word_t) (OFFSET) <= (Word_t) (POP1)); \ + { \ + Word_t i_offset; \ + \ + for (i_offset = 0; i_offset < (OFFSET); ++i_offset) \ + (PDEST)[i_offset] = (PSOURCE)[i_offset]; \ + \ + (PDEST)[i_offset] = (INDEX); \ + \ + for (/* null */; i_offset < (POP1); ++i_offset) \ + (PDEST)[i_offset + 1] = (PSOURCE)[i_offset]; \ + } + +#define JU_INSERTCOPY3(PDEST,PSOURCE,POP1,OFFSET,INDEX) \ +assert((long) (POP1) > 0); \ +assert((Word_t) (OFFSET) <= (Word_t) (POP1)); \ +{ \ + Word_t o_ff; \ + \ + for (o_ff = 0; o_ff < (OFFSET); o_ff++) \ + { \ + Word_t i_dx = o_ff * 3; \ + (PDEST)[i_dx + 0] = (PSOURCE)[i_dx + 0]; \ + (PDEST)[i_dx + 1] = (PSOURCE)[i_dx + 1]; \ + (PDEST)[i_dx + 2] = (PSOURCE)[i_dx + 2]; \ + } \ + JU_COPY3_LONG_TO_PINDEX(&((PDEST)[(OFFSET) * 3]), INDEX); \ + \ + for (/* null */; o_ff < (POP1); o_ff++) \ + { \ + Word_t i_dx = o_ff * 3; \ + (PDEST)[i_dx + 0 + 3] = (PSOURCE)[i_dx + 0]; \ + (PDEST)[i_dx + 1 + 3] = (PSOURCE)[i_dx + 1]; \ + (PDEST)[i_dx + 2 + 3] = (PSOURCE)[i_dx + 2]; \ + } \ +} + +#ifdef JU_64BIT + +#define JU_INSERTCOPY5(PDEST,PSOURCE,POP1,OFFSET,INDEX) \ +assert((long) (POP1) > 0); \ +assert((Word_t) (OFFSET) <= (Word_t) (POP1)); \ +{ \ + Word_t o_ff; \ + \ + for (o_ff = 0; o_ff < (OFFSET); o_ff++) \ + { \ + Word_t i_dx = o_ff * 5; \ + (PDEST)[i_dx + 0] = (PSOURCE)[i_dx + 0]; \ + (PDEST)[i_dx + 1] = (PSOURCE)[i_dx + 1]; \ + (PDEST)[i_dx + 2] = (PSOURCE)[i_dx + 2]; \ + (PDEST)[i_dx + 3] = (PSOURCE)[i_dx + 3]; \ + (PDEST)[i_dx + 4] = (PSOURCE)[i_dx + 4]; \ + } \ + JU_COPY5_LONG_TO_PINDEX(&((PDEST)[(OFFSET) * 5]), INDEX); \ + \ + for (/* null */; o_ff < (POP1); o_ff++) \ + { \ + Word_t i_dx = o_ff * 5; \ + (PDEST)[i_dx + 0 + 5] = (PSOURCE)[i_dx + 0]; \ + (PDEST)[i_dx + 1 + 5] = (PSOURCE)[i_dx + 1]; \ + (PDEST)[i_dx + 2 + 5] = (PSOURCE)[i_dx + 2]; \ + (PDEST)[i_dx + 3 + 5] = (PSOURCE)[i_dx + 3]; \ + (PDEST)[i_dx + 4 + 5] = (PSOURCE)[i_dx + 4]; \ + } \ +} + +#define JU_INSERTCOPY6(PDEST,PSOURCE,POP1,OFFSET,INDEX) \ +assert((long) (POP1) > 0); \ +assert((Word_t) (OFFSET) <= (Word_t) (POP1)); \ +{ \ + Word_t o_ff; \ + \ + for (o_ff = 0; o_ff < (OFFSET); o_ff++) \ + { \ + Word_t i_dx = o_ff * 6; \ + (PDEST)[i_dx + 0] = (PSOURCE)[i_dx + 0]; \ + (PDEST)[i_dx + 1] = (PSOURCE)[i_dx + 1]; \ + (PDEST)[i_dx + 2] = (PSOURCE)[i_dx + 2]; \ + (PDEST)[i_dx + 3] = (PSOURCE)[i_dx + 3]; \ + (PDEST)[i_dx + 4] = (PSOURCE)[i_dx + 4]; \ + (PDEST)[i_dx + 5] = (PSOURCE)[i_dx + 5]; \ + } \ + JU_COPY6_LONG_TO_PINDEX(&((PDEST)[(OFFSET) * 6]), INDEX); \ + \ + for (/* null */; o_ff < (POP1); o_ff++) \ + { \ + Word_t i_dx = o_ff * 6; \ + (PDEST)[i_dx + 0 + 6] = (PSOURCE)[i_dx + 0]; \ + (PDEST)[i_dx + 1 + 6] = (PSOURCE)[i_dx + 1]; \ + (PDEST)[i_dx + 2 + 6] = (PSOURCE)[i_dx + 2]; \ + (PDEST)[i_dx + 3 + 6] = (PSOURCE)[i_dx + 3]; \ + (PDEST)[i_dx + 4 + 6] = (PSOURCE)[i_dx + 4]; \ + (PDEST)[i_dx + 5 + 6] = (PSOURCE)[i_dx + 5]; \ + } \ +} + +#define JU_INSERTCOPY7(PDEST,PSOURCE,POP1,OFFSET,INDEX) \ +assert((long) (POP1) > 0); \ +assert((Word_t) (OFFSET) <= (Word_t) (POP1)); \ +{ \ + Word_t o_ff; \ + \ + for (o_ff = 0; o_ff < (OFFSET); o_ff++) \ + { \ + Word_t i_dx = o_ff * 7; \ + (PDEST)[i_dx + 0] = (PSOURCE)[i_dx + 0]; \ + (PDEST)[i_dx + 1] = (PSOURCE)[i_dx + 1]; \ + (PDEST)[i_dx + 2] = (PSOURCE)[i_dx + 2]; \ + (PDEST)[i_dx + 3] = (PSOURCE)[i_dx + 3]; \ + (PDEST)[i_dx + 4] = (PSOURCE)[i_dx + 4]; \ + (PDEST)[i_dx + 5] = (PSOURCE)[i_dx + 5]; \ + (PDEST)[i_dx + 6] = (PSOURCE)[i_dx + 6]; \ + } \ + JU_COPY7_LONG_TO_PINDEX(&((PDEST)[(OFFSET) * 7]), INDEX); \ + \ + for (/* null */; o_ff < (POP1); o_ff++) \ + { \ + Word_t i_dx = o_ff * 7; \ + (PDEST)[i_dx + 0 + 7] = (PSOURCE)[i_dx + 0]; \ + (PDEST)[i_dx + 1 + 7] = (PSOURCE)[i_dx + 1]; \ + (PDEST)[i_dx + 2 + 7] = (PSOURCE)[i_dx + 2]; \ + (PDEST)[i_dx + 3 + 7] = (PSOURCE)[i_dx + 3]; \ + (PDEST)[i_dx + 4 + 7] = (PSOURCE)[i_dx + 4]; \ + (PDEST)[i_dx + 5 + 7] = (PSOURCE)[i_dx + 5]; \ + (PDEST)[i_dx + 6 + 7] = (PSOURCE)[i_dx + 6]; \ + } \ +} + +#endif // JU_64BIT + +// Counterparts to the above for deleting an Index: + +#define JU_DELETECOPY(PDEST,PSOURCE,POP1,OFFSET,IGNORE) \ + assert((long) (POP1) > 0); \ + assert((Word_t) (OFFSET) < (Word_t) (POP1)); \ + { \ + Word_t i_offset; \ + \ + for (i_offset = 0; i_offset < (OFFSET); ++i_offset) \ + (PDEST)[i_offset] = (PSOURCE)[i_offset]; \ + \ + for (++i_offset; i_offset < (POP1); ++i_offset) \ + (PDEST)[i_offset - 1] = (PSOURCE)[i_offset]; \ + } + +// Variation for odd-byte-sized (non-native) Indexes, where cIS = Index Size; +// copy byte-by-byte: +// +// Note: There are no endian issues here because bytes are just shifted as-is, +// not converted to/from an Index. +// +// Note: If cIS == 1, JU_DELETECOPY_ODD == JU_DELETECOPY, at least in concept. + +#define JU_DELETECOPY_ODD(PDEST,PSOURCE,POP1,OFFSET,cIS) \ + assert((long) (POP1) > 0); \ + assert((Word_t) (OFFSET) < (Word_t) (POP1)); \ + { \ + uint8_t *_Pdest = (uint8_t *) (PDEST); \ + uint8_t *_Psource = (uint8_t *) (PSOURCE); \ + Word_t b_off; \ + \ + for (b_off = 0; b_off < ((OFFSET) * (cIS)); ++b_off) \ + *_Pdest++ = *_Psource++; \ + \ + _Psource += (cIS); \ + \ + for (b_off += (cIS); b_off < ((POP1) * (cIS)); ++b_off) \ + *_Pdest++ = *_Psource++; \ + } + + +// GENERIC RETURN CODE HANDLING FOR JUDY1 (NO VALUE AREAS) AND JUDYL (VALUE +// AREAS): +// +// This common code hides Judy1 versus JudyL details of how to return various +// conditions, including a pointer to a value area for JudyL. +// +// First, define an internal variation of JERR called JERRI (I = int) to make +// lint happy. We accidentally shipped to 11.11 OEUR with all functions that +// return int or Word_t using JERR, which is type Word_t, for errors. Lint +// complains about this for functions that return int. So, internally use +// JERRI for error returns from the int functions. Experiments show that +// callers which compare int Foo() to (Word_t) JERR (~0UL) are OK, since JERRI +// sign-extends to match JERR. + +#define JERRI ((int) ~0) // see above. + +#ifdef JUDY1 + +#define JU_RET_FOUND return(1) +#define JU_RET_NOTFOUND return(0) + +// For Judy1, these all "fall through" to simply JU_RET_FOUND, since there is no +// value area pointer to return: + +#define JU_RET_FOUND_LEAFW(PJLW,POP1,OFFSET) JU_RET_FOUND + +#define JU_RET_FOUND_JPM(Pjpm) JU_RET_FOUND +#define JU_RET_FOUND_PVALUE(Pjv,OFFSET) JU_RET_FOUND +#ifndef JU_64BIT +#define JU_RET_FOUND_LEAF1(Pjll,POP1,OFFSET) JU_RET_FOUND +#endif +#define JU_RET_FOUND_LEAF2(Pjll,POP1,OFFSET) JU_RET_FOUND +#define JU_RET_FOUND_LEAF3(Pjll,POP1,OFFSET) JU_RET_FOUND +#ifdef JU_64BIT +#define JU_RET_FOUND_LEAF4(Pjll,POP1,OFFSET) JU_RET_FOUND +#define JU_RET_FOUND_LEAF5(Pjll,POP1,OFFSET) JU_RET_FOUND +#define JU_RET_FOUND_LEAF6(Pjll,POP1,OFFSET) JU_RET_FOUND +#define JU_RET_FOUND_LEAF7(Pjll,POP1,OFFSET) JU_RET_FOUND +#endif +#define JU_RET_FOUND_IMM_01(Pjp) JU_RET_FOUND +#define JU_RET_FOUND_IMM(Pjp,OFFSET) JU_RET_FOUND + +// Note: No JudyL equivalent: + +#define JU_RET_FOUND_FULLPOPU1 JU_RET_FOUND +#define JU_RET_FOUND_LEAF_B1(PJLB,SUBEXP,OFFSET) JU_RET_FOUND + +#else // JUDYL + +// JU_RET_FOUND // see below; must NOT be defined for JudyL. +#define JU_RET_NOTFOUND return((PPvoid_t) NULL) + +// For JudyL, the location of the value area depends on the JP type and other +// factors: +// +// TBD: The value areas should be accessed via data structures, here and in +// Dougs code, not by hard-coded address calculations. +// +// This is useful in insert/delete code when the value area is returned from +// lower levels in the JPM: + +#define JU_RET_FOUND_JPM(Pjpm) return((PPvoid_t) ((Pjpm)->jpm_PValue)) + +// This is useful in insert/delete code when the value area location is already +// computed: + +#define JU_RET_FOUND_PVALUE(Pjv,OFFSET) return((PPvoid_t) ((Pjv) + OFFSET)) + +#define JU_RET_FOUND_LEAFW(PJLW,POP1,OFFSET) \ + return((PPvoid_t) (JL_LEAFWVALUEAREA(PJLW, POP1) + (OFFSET))) + +#define JU_RET_FOUND_LEAF1(Pjll,POP1,OFFSET) \ + return((PPvoid_t) (JL_LEAF1VALUEAREA(Pjll, POP1) + (OFFSET))) +#define JU_RET_FOUND_LEAF2(Pjll,POP1,OFFSET) \ + return((PPvoid_t) (JL_LEAF2VALUEAREA(Pjll, POP1) + (OFFSET))) +#define JU_RET_FOUND_LEAF3(Pjll,POP1,OFFSET) \ + return((PPvoid_t) (JL_LEAF3VALUEAREA(Pjll, POP1) + (OFFSET))) +#ifdef JU_64BIT +#define JU_RET_FOUND_LEAF4(Pjll,POP1,OFFSET) \ + return((PPvoid_t) (JL_LEAF4VALUEAREA(Pjll, POP1) + (OFFSET))) +#define JU_RET_FOUND_LEAF5(Pjll,POP1,OFFSET) \ + return((PPvoid_t) (JL_LEAF5VALUEAREA(Pjll, POP1) + (OFFSET))) +#define JU_RET_FOUND_LEAF6(Pjll,POP1,OFFSET) \ + return((PPvoid_t) (JL_LEAF6VALUEAREA(Pjll, POP1) + (OFFSET))) +#define JU_RET_FOUND_LEAF7(Pjll,POP1,OFFSET) \ + return((PPvoid_t) (JL_LEAF7VALUEAREA(Pjll, POP1) + (OFFSET))) +#endif + +// Note: Here jp_Addr is a value area itself and not an address, so P_JV() is +// not needed: + +#define JU_RET_FOUND_IMM_01(PJP) return((PPvoid_t) (&((PJP)->jp_Addr))) + +// Note: Here jp_Addr is a pointer to a separately-mallocd value area, so +// P_JV() is required; likewise for JL_JLB_PVALUE: + +#define JU_RET_FOUND_IMM(PJP,OFFSET) \ + return((PPvoid_t) (P_JV((PJP)->jp_Addr) + (OFFSET))) + +#define JU_RET_FOUND_LEAF_B1(PJLB,SUBEXP,OFFSET) \ + return((PPvoid_t) (P_JV(JL_JLB_PVALUE(PJLB, SUBEXP)) + (OFFSET))) + +#endif // JUDYL + + +// GENERIC ERROR HANDLING: +// +// This is complicated by variations in the needs of the callers of these +// macros. Only use JU_SET_ERRNO() for PJError, because it can be null; use +// JU_SET_ERRNO_NONNULL() for Pjpm, which is never null, and also in other +// cases where the pointer is known not to be null (to save dead branches). +// +// Note: Most cases of JU_ERRNO_OVERRUN or JU_ERRNO_CORRUPT should result in +// an assertion failure in debug code, so they are more likely to be caught, so +// do that here in each macro. + +#define JU_SET_ERRNO(PJError, JErrno) \ + { \ + assert((JErrno) != JU_ERRNO_OVERRUN); \ + assert((JErrno) != JU_ERRNO_CORRUPT); \ + \ + if (PJError != (PJError_t) NULL) \ + { \ + JU_ERRNO(PJError) = (JErrno); \ + JU_ERRID(PJError) = __LINE__; \ + } \ + } + +// Variation for callers who know already that PJError is non-null; and, it can +// also be Pjpm (both PJError_t and Pjpm_t have je_* fields), so only assert it +// for null, not cast to any specific pointer type: + +#define JU_SET_ERRNO_NONNULL(PJError, JErrno) \ + { \ + assert((JErrno) != JU_ERRNO_OVERRUN); \ + assert((JErrno) != JU_ERRNO_CORRUPT); \ + assert(PJError); \ + \ + JU_ERRNO(PJError) = (JErrno); \ + JU_ERRID(PJError) = __LINE__; \ + } + +// Variation to copy error info from a (required) JPM to an (optional) +// PJError_t: +// +// Note: The assertions above about JU_ERRNO_OVERRUN and JU_ERRNO_CORRUPT +// should have already popped, so they are not needed here. + +#define JU_COPY_ERRNO(PJError, Pjpm) \ + { \ + if (PJError) \ + { \ + JU_ERRNO(PJError) = (uint8_t)JU_ERRNO(Pjpm); \ + JU_ERRID(PJError) = JU_ERRID(Pjpm); \ + } \ + } + +// For JErrno parameter to previous macros upon return from Judy*Alloc*(): +// +// The memory allocator returns an address of 0 for out of memory, +// 1..sizeof(Word_t)-1 for corruption (an invalid pointer), otherwise a valid +// pointer. + +#define JU_ALLOC_ERRNO(ADDR) \ + (((void *) (ADDR) != (void *) NULL) ? JU_ERRNO_OVERRUN : JU_ERRNO_NOMEM) + +#define JU_CHECKALLOC(Type,Ptr,Retval) \ + if ((Ptr) < (Type) sizeof(Word_t)) \ + { \ + JU_SET_ERRNO(PJError, JU_ALLOC_ERRNO(Ptr)); \ + return(Retval); \ + } + +// Leaf search routines + +#ifdef JU_NOINLINE + +int j__udySearchLeaf1(Pjll_t Pjll, Word_t LeafPop1, Word_t Index); +int j__udySearchLeaf2(Pjll_t Pjll, Word_t LeafPop1, Word_t Index); +int j__udySearchLeaf3(Pjll_t Pjll, Word_t LeafPop1, Word_t Index); + +#ifdef JU_64BIT + +int j__udySearchLeaf4(Pjll_t Pjll, Word_t LeafPop1, Word_t Index); +int j__udySearchLeaf5(Pjll_t Pjll, Word_t LeafPop1, Word_t Index); +int j__udySearchLeaf6(Pjll_t Pjll, Word_t LeafPop1, Word_t Index); +int j__udySearchLeaf7(Pjll_t Pjll, Word_t LeafPop1, Word_t Index); + +#endif // JU_64BIT + +int j__udySearchLeafW(Pjlw_t Pjlw, Word_t LeafPop1, Word_t Index); + +#else // complier support for inline + +#ifdef JU_WIN +static __inline int j__udySearchLeaf1(Pjll_t Pjll, Word_t LeafPop1, Word_t Index) +#else +static inline int j__udySearchLeaf1(Pjll_t Pjll, Word_t LeafPop1, Word_t Index) +#endif +{ SEARCHLEAFNATIVE(uint8_t, Pjll, LeafPop1, Index); } + +#ifdef JU_WIN +static __inline int j__udySearchLeaf2(Pjll_t Pjll, Word_t LeafPop1, Word_t Index) +#else +static inline int j__udySearchLeaf2(Pjll_t Pjll, Word_t LeafPop1, Word_t Index) +#endif +{ SEARCHLEAFNATIVE(uint16_t, Pjll, LeafPop1, Index); } + +#ifdef JU_WIN +static __inline int j__udySearchLeaf3(Pjll_t Pjll, Word_t LeafPop1, Word_t Index) +#else +static inline int j__udySearchLeaf3(Pjll_t Pjll, Word_t LeafPop1, Word_t Index) +#endif +{ SEARCHLEAFNONNAT(Pjll, LeafPop1, Index, 3, JU_COPY3_PINDEX_TO_LONG); } + +#ifdef JU_64BIT + +#ifdef JU_WIN +static __inline int j__udySearchLeaf4(Pjll_t Pjll, Word_t LeafPop1, Word_t Index) +#else +static inline int j__udySearchLeaf4(Pjll_t Pjll, Word_t LeafPop1, Word_t Index) +#endif +{ SEARCHLEAFNATIVE(uint32_t, Pjll, LeafPop1, Index); } + +#ifdef JU_WIN +static __inline int j__udySearchLeaf5(Pjll_t Pjll, Word_t LeafPop1, Word_t Index) +#else +static inline int j__udySearchLeaf5(Pjll_t Pjll, Word_t LeafPop1, Word_t Index) +#endif +{ SEARCHLEAFNONNAT(Pjll, LeafPop1, Index, 5, JU_COPY5_PINDEX_TO_LONG); } + +#ifdef JU_WIN +static __inline int j__udySearchLeaf6(Pjll_t Pjll, Word_t LeafPop1, Word_t Index) +#else +static inline int j__udySearchLeaf6(Pjll_t Pjll, Word_t LeafPop1, Word_t Index) +#endif +{ SEARCHLEAFNONNAT(Pjll, LeafPop1, Index, 6, JU_COPY6_PINDEX_TO_LONG); } + +#ifdef JU_WIN +static __inline int j__udySearchLeaf7(Pjll_t Pjll, Word_t LeafPop1, Word_t Index) +#else +static inline int j__udySearchLeaf7(Pjll_t Pjll, Word_t LeafPop1, Word_t Index) +#endif +{ SEARCHLEAFNONNAT(Pjll, LeafPop1, Index, 7, JU_COPY7_PINDEX_TO_LONG); } + +#endif // JU_64BIT + +#ifdef JU_WIN +static __inline int j__udySearchLeafW(Pjlw_t Pjlw, Word_t LeafPop1, Word_t Index) +#else +static inline int j__udySearchLeafW(Pjlw_t Pjlw, Word_t LeafPop1, Word_t Index) +#endif +{ SEARCHLEAFNATIVE(Word_t, Pjlw, LeafPop1, Index); } + +#endif // compiler support for inline + +#endif // ! _JUDYPRIVATE_INCLUDED diff --git a/feeds/p4/libjudy/src/src/JudyCommon/JudyPrivate1L.h b/feeds/p4/libjudy/src/src/JudyCommon/JudyPrivate1L.h new file mode 100644 index 000000000..5b4704899 --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudyCommon/JudyPrivate1L.h @@ -0,0 +1,485 @@ +#ifndef _JUDYPRIVATE1L_INCLUDED +#define _JUDYPRIVATE1L_INCLUDED +// _________________ +// +// Copyright (C) 2000 - 2002 Hewlett-Packard Company +// +// This program is free software; you can redistribute it and/or modify it +// under the term of the GNU Lesser 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 Lesser General Public License +// for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// _________________ + +// @(#) $Revision: 4.31 $ $Source: /judy/src/JudyCommon/JudyPrivate1L.h $ + +// **************************************************************************** +// Declare common cJU_* names for JP Types that occur in both Judy1 and JudyL, +// for use by code that ifdefs JUDY1 and JUDYL. Only JP Types common to both +// Judy1 and JudyL are #defined here with equivalent cJU_* names. JP Types +// unique to only Judy1 or JudyL are listed in comments, so the type lists +// match the Judy1.h and JudyL.h files. +// +// This file also defines cJU_* for other JP-related constants and functions +// that some shared JUDY1/JUDYL code finds handy. +// +// At least in principle this file should be included AFTER Judy1.h or JudyL.h. +// +// WARNING: This file must be kept consistent with the enums in Judy1.h and +// JudyL.h. +// +// TBD: You might think, why not define common cJU_* enums in, say, +// JudyPrivate.h, and then inherit them into superset enums in Judy1.h and +// JudyL.h? The problem is that the enum lists for each class (cJ1_* and +// cJL_*) must be numerically "packed" into the correct order, for two reasons: +// (1) allow the compiler to generate "tight" switch statements with no wasted +// slots (although this is not very big), and (2) allow calculations using the +// enum values, although this is also not an issue if the calculations are only +// within each cJ*_JPIMMED_*_* class and the members are packed within the +// class. + +#ifdef JUDY1 + +#define cJU_JRPNULL cJ1_JRPNULL +#define cJU_JPNULL1 cJ1_JPNULL1 +#define cJU_JPNULL2 cJ1_JPNULL2 +#define cJU_JPNULL3 cJ1_JPNULL3 +#ifdef JU_64BIT +#define cJU_JPNULL4 cJ1_JPNULL4 +#define cJU_JPNULL5 cJ1_JPNULL5 +#define cJU_JPNULL6 cJ1_JPNULL6 +#define cJU_JPNULL7 cJ1_JPNULL7 +#endif +#define cJU_JPNULLMAX cJ1_JPNULLMAX +#define cJU_JPBRANCH_L2 cJ1_JPBRANCH_L2 +#define cJU_JPBRANCH_L3 cJ1_JPBRANCH_L3 +#ifdef JU_64BIT +#define cJU_JPBRANCH_L4 cJ1_JPBRANCH_L4 +#define cJU_JPBRANCH_L5 cJ1_JPBRANCH_L5 +#define cJU_JPBRANCH_L6 cJ1_JPBRANCH_L6 +#define cJU_JPBRANCH_L7 cJ1_JPBRANCH_L7 +#endif +#define cJU_JPBRANCH_L cJ1_JPBRANCH_L +#define j__U_BranchBJPPopToWords j__1_BranchBJPPopToWords +#define cJU_JPBRANCH_B2 cJ1_JPBRANCH_B2 +#define cJU_JPBRANCH_B3 cJ1_JPBRANCH_B3 +#ifdef JU_64BIT +#define cJU_JPBRANCH_B4 cJ1_JPBRANCH_B4 +#define cJU_JPBRANCH_B5 cJ1_JPBRANCH_B5 +#define cJU_JPBRANCH_B6 cJ1_JPBRANCH_B6 +#define cJU_JPBRANCH_B7 cJ1_JPBRANCH_B7 +#endif +#define cJU_JPBRANCH_B cJ1_JPBRANCH_B +#define cJU_JPBRANCH_U2 cJ1_JPBRANCH_U2 +#define cJU_JPBRANCH_U3 cJ1_JPBRANCH_U3 +#ifdef JU_64BIT +#define cJU_JPBRANCH_U4 cJ1_JPBRANCH_U4 +#define cJU_JPBRANCH_U5 cJ1_JPBRANCH_U5 +#define cJU_JPBRANCH_U6 cJ1_JPBRANCH_U6 +#define cJU_JPBRANCH_U7 cJ1_JPBRANCH_U7 +#endif +#define cJU_JPBRANCH_U cJ1_JPBRANCH_U +#ifndef JU_64BIT +#define cJU_JPLEAF1 cJ1_JPLEAF1 +#endif +#define cJU_JPLEAF2 cJ1_JPLEAF2 +#define cJU_JPLEAF3 cJ1_JPLEAF3 +#ifdef JU_64BIT +#define cJU_JPLEAF4 cJ1_JPLEAF4 +#define cJU_JPLEAF5 cJ1_JPLEAF5 +#define cJU_JPLEAF6 cJ1_JPLEAF6 +#define cJU_JPLEAF7 cJ1_JPLEAF7 +#endif +#define cJU_JPLEAF_B1 cJ1_JPLEAF_B1 +// cJ1_JPFULLPOPU1 +#define cJU_JPIMMED_1_01 cJ1_JPIMMED_1_01 +#define cJU_JPIMMED_2_01 cJ1_JPIMMED_2_01 +#define cJU_JPIMMED_3_01 cJ1_JPIMMED_3_01 +#ifdef JU_64BIT +#define cJU_JPIMMED_4_01 cJ1_JPIMMED_4_01 +#define cJU_JPIMMED_5_01 cJ1_JPIMMED_5_01 +#define cJU_JPIMMED_6_01 cJ1_JPIMMED_6_01 +#define cJU_JPIMMED_7_01 cJ1_JPIMMED_7_01 +#endif +#define cJU_JPIMMED_1_02 cJ1_JPIMMED_1_02 +#define cJU_JPIMMED_1_03 cJ1_JPIMMED_1_03 +#define cJU_JPIMMED_1_04 cJ1_JPIMMED_1_04 +#define cJU_JPIMMED_1_05 cJ1_JPIMMED_1_05 +#define cJU_JPIMMED_1_06 cJ1_JPIMMED_1_06 +#define cJU_JPIMMED_1_07 cJ1_JPIMMED_1_07 +#ifdef JU_64BIT +// cJ1_JPIMMED_1_08 +// cJ1_JPIMMED_1_09 +// cJ1_JPIMMED_1_10 +// cJ1_JPIMMED_1_11 +// cJ1_JPIMMED_1_12 +// cJ1_JPIMMED_1_13 +// cJ1_JPIMMED_1_14 +// cJ1_JPIMMED_1_15 +#endif +#define cJU_JPIMMED_2_02 cJ1_JPIMMED_2_02 +#define cJU_JPIMMED_2_03 cJ1_JPIMMED_2_03 +#ifdef JU_64BIT +// cJ1_JPIMMED_2_04 +// cJ1_JPIMMED_2_05 +// cJ1_JPIMMED_2_06 +// cJ1_JPIMMED_2_07 +#endif +#define cJU_JPIMMED_3_02 cJ1_JPIMMED_3_02 +#ifdef JU_64BIT +// cJ1_JPIMMED_3_03 +// cJ1_JPIMMED_3_04 +// cJ1_JPIMMED_3_05 +// cJ1_JPIMMED_4_02 +// cJ1_JPIMMED_4_03 +// cJ1_JPIMMED_5_02 +// cJ1_JPIMMED_5_03 +// cJ1_JPIMMED_6_02 +// cJ1_JPIMMED_7_02 +#endif +#define cJU_JPIMMED_CAP cJ1_JPIMMED_CAP + +#else // JUDYL **************************************************************** + +#define cJU_JRPNULL cJL_JRPNULL +#define cJU_JPNULL1 cJL_JPNULL1 +#define cJU_JPNULL2 cJL_JPNULL2 +#define cJU_JPNULL3 cJL_JPNULL3 +#ifdef JU_64BIT +#define cJU_JPNULL4 cJL_JPNULL4 +#define cJU_JPNULL5 cJL_JPNULL5 +#define cJU_JPNULL6 cJL_JPNULL6 +#define cJU_JPNULL7 cJL_JPNULL7 +#endif +#define cJU_JPNULLMAX cJL_JPNULLMAX +#define cJU_JPBRANCH_L2 cJL_JPBRANCH_L2 +#define cJU_JPBRANCH_L3 cJL_JPBRANCH_L3 +#ifdef JU_64BIT +#define cJU_JPBRANCH_L4 cJL_JPBRANCH_L4 +#define cJU_JPBRANCH_L5 cJL_JPBRANCH_L5 +#define cJU_JPBRANCH_L6 cJL_JPBRANCH_L6 +#define cJU_JPBRANCH_L7 cJL_JPBRANCH_L7 +#endif +#define cJU_JPBRANCH_L cJL_JPBRANCH_L +#define j__U_BranchBJPPopToWords j__L_BranchBJPPopToWords +#define cJU_JPBRANCH_B2 cJL_JPBRANCH_B2 +#define cJU_JPBRANCH_B3 cJL_JPBRANCH_B3 +#ifdef JU_64BIT +#define cJU_JPBRANCH_B4 cJL_JPBRANCH_B4 +#define cJU_JPBRANCH_B5 cJL_JPBRANCH_B5 +#define cJU_JPBRANCH_B6 cJL_JPBRANCH_B6 +#define cJU_JPBRANCH_B7 cJL_JPBRANCH_B7 +#endif +#define cJU_JPBRANCH_B cJL_JPBRANCH_B +#define cJU_JPBRANCH_U2 cJL_JPBRANCH_U2 +#define cJU_JPBRANCH_U3 cJL_JPBRANCH_U3 +#ifdef JU_64BIT +#define cJU_JPBRANCH_U4 cJL_JPBRANCH_U4 +#define cJU_JPBRANCH_U5 cJL_JPBRANCH_U5 +#define cJU_JPBRANCH_U6 cJL_JPBRANCH_U6 +#define cJU_JPBRANCH_U7 cJL_JPBRANCH_U7 +#endif +#define cJU_JPBRANCH_U cJL_JPBRANCH_U +#define cJU_JPLEAF1 cJL_JPLEAF1 +#define cJU_JPLEAF2 cJL_JPLEAF2 +#define cJU_JPLEAF3 cJL_JPLEAF3 +#ifdef JU_64BIT +#define cJU_JPLEAF4 cJL_JPLEAF4 +#define cJU_JPLEAF5 cJL_JPLEAF5 +#define cJU_JPLEAF6 cJL_JPLEAF6 +#define cJU_JPLEAF7 cJL_JPLEAF7 +#endif +#define cJU_JPLEAF_B1 cJL_JPLEAF_B1 +#define cJU_JPIMMED_1_01 cJL_JPIMMED_1_01 +#define cJU_JPIMMED_2_01 cJL_JPIMMED_2_01 +#define cJU_JPIMMED_3_01 cJL_JPIMMED_3_01 +#ifdef JU_64BIT +#define cJU_JPIMMED_4_01 cJL_JPIMMED_4_01 +#define cJU_JPIMMED_5_01 cJL_JPIMMED_5_01 +#define cJU_JPIMMED_6_01 cJL_JPIMMED_6_01 +#define cJU_JPIMMED_7_01 cJL_JPIMMED_7_01 +#endif +#define cJU_JPIMMED_1_02 cJL_JPIMMED_1_02 +#define cJU_JPIMMED_1_03 cJL_JPIMMED_1_03 +#ifdef JU_64BIT +#define cJU_JPIMMED_1_04 cJL_JPIMMED_1_04 +#define cJU_JPIMMED_1_05 cJL_JPIMMED_1_05 +#define cJU_JPIMMED_1_06 cJL_JPIMMED_1_06 +#define cJU_JPIMMED_1_07 cJL_JPIMMED_1_07 +#define cJU_JPIMMED_2_02 cJL_JPIMMED_2_02 +#define cJU_JPIMMED_2_03 cJL_JPIMMED_2_03 +#define cJU_JPIMMED_3_02 cJL_JPIMMED_3_02 +#endif +#define cJU_JPIMMED_CAP cJL_JPIMMED_CAP + +#endif // JUDYL + + +// **************************************************************************** +// cJU*_ other than JP types: + +#ifdef JUDY1 + +#define cJU_LEAFW_MAXPOP1 cJ1_LEAFW_MAXPOP1 +#ifndef JU_64BIT +#define cJU_LEAF1_MAXPOP1 cJ1_LEAF1_MAXPOP1 +#endif +#define cJU_LEAF2_MAXPOP1 cJ1_LEAF2_MAXPOP1 +#define cJU_LEAF3_MAXPOP1 cJ1_LEAF3_MAXPOP1 +#ifdef JU_64BIT +#define cJU_LEAF4_MAXPOP1 cJ1_LEAF4_MAXPOP1 +#define cJU_LEAF5_MAXPOP1 cJ1_LEAF5_MAXPOP1 +#define cJU_LEAF6_MAXPOP1 cJ1_LEAF6_MAXPOP1 +#define cJU_LEAF7_MAXPOP1 cJ1_LEAF7_MAXPOP1 +#endif +#define cJU_IMMED1_MAXPOP1 cJ1_IMMED1_MAXPOP1 +#define cJU_IMMED2_MAXPOP1 cJ1_IMMED2_MAXPOP1 +#define cJU_IMMED3_MAXPOP1 cJ1_IMMED3_MAXPOP1 +#ifdef JU_64BIT +#define cJU_IMMED4_MAXPOP1 cJ1_IMMED4_MAXPOP1 +#define cJU_IMMED5_MAXPOP1 cJ1_IMMED5_MAXPOP1 +#define cJU_IMMED6_MAXPOP1 cJ1_IMMED6_MAXPOP1 +#define cJU_IMMED7_MAXPOP1 cJ1_IMMED7_MAXPOP1 +#endif + +#define JU_LEAF1POPTOWORDS(Pop1) J1_LEAF1POPTOWORDS(Pop1) +#define JU_LEAF2POPTOWORDS(Pop1) J1_LEAF2POPTOWORDS(Pop1) +#define JU_LEAF3POPTOWORDS(Pop1) J1_LEAF3POPTOWORDS(Pop1) +#ifdef JU_64BIT +#define JU_LEAF4POPTOWORDS(Pop1) J1_LEAF4POPTOWORDS(Pop1) +#define JU_LEAF5POPTOWORDS(Pop1) J1_LEAF5POPTOWORDS(Pop1) +#define JU_LEAF6POPTOWORDS(Pop1) J1_LEAF6POPTOWORDS(Pop1) +#define JU_LEAF7POPTOWORDS(Pop1) J1_LEAF7POPTOWORDS(Pop1) +#endif +#define JU_LEAFWPOPTOWORDS(Pop1) J1_LEAFWPOPTOWORDS(Pop1) + +#ifndef JU_64BIT +#define JU_LEAF1GROWINPLACE(Pop1) J1_LEAF1GROWINPLACE(Pop1) +#endif +#define JU_LEAF2GROWINPLACE(Pop1) J1_LEAF2GROWINPLACE(Pop1) +#define JU_LEAF3GROWINPLACE(Pop1) J1_LEAF3GROWINPLACE(Pop1) +#ifdef JU_64BIT +#define JU_LEAF4GROWINPLACE(Pop1) J1_LEAF4GROWINPLACE(Pop1) +#define JU_LEAF5GROWINPLACE(Pop1) J1_LEAF5GROWINPLACE(Pop1) +#define JU_LEAF6GROWINPLACE(Pop1) J1_LEAF6GROWINPLACE(Pop1) +#define JU_LEAF7GROWINPLACE(Pop1) J1_LEAF7GROWINPLACE(Pop1) +#endif +#define JU_LEAFWGROWINPLACE(Pop1) J1_LEAFWGROWINPLACE(Pop1) + +#define j__udyCreateBranchL j__udy1CreateBranchL +#define j__udyCreateBranchB j__udy1CreateBranchB +#define j__udyCreateBranchU j__udy1CreateBranchU +#define j__udyCascade1 j__udy1Cascade1 +#define j__udyCascade2 j__udy1Cascade2 +#define j__udyCascade3 j__udy1Cascade3 +#ifdef JU_64BIT +#define j__udyCascade4 j__udy1Cascade4 +#define j__udyCascade5 j__udy1Cascade5 +#define j__udyCascade6 j__udy1Cascade6 +#define j__udyCascade7 j__udy1Cascade7 +#endif +#define j__udyCascadeL j__udy1CascadeL +#define j__udyInsertBranch j__udy1InsertBranch + +#define j__udyBranchBToBranchL j__udy1BranchBToBranchL +#ifndef JU_64BIT +#define j__udyLeafB1ToLeaf1 j__udy1LeafB1ToLeaf1 +#endif +#define j__udyLeaf1ToLeaf2 j__udy1Leaf1ToLeaf2 +#define j__udyLeaf2ToLeaf3 j__udy1Leaf2ToLeaf3 +#ifndef JU_64BIT +#define j__udyLeaf3ToLeafW j__udy1Leaf3ToLeafW +#else +#define j__udyLeaf3ToLeaf4 j__udy1Leaf3ToLeaf4 +#define j__udyLeaf4ToLeaf5 j__udy1Leaf4ToLeaf5 +#define j__udyLeaf5ToLeaf6 j__udy1Leaf5ToLeaf6 +#define j__udyLeaf6ToLeaf7 j__udy1Leaf6ToLeaf7 +#define j__udyLeaf7ToLeafW j__udy1Leaf7ToLeafW +#endif + +#define jpm_t j1pm_t +#define Pjpm_t Pj1pm_t + +#define jlb_t j1lb_t +#define Pjlb_t Pj1lb_t + +#define JU_JLB_BITMAP J1_JLB_BITMAP + +#define j__udyAllocJPM j__udy1AllocJ1PM +#define j__udyAllocJBL j__udy1AllocJBL +#define j__udyAllocJBB j__udy1AllocJBB +#define j__udyAllocJBBJP j__udy1AllocJBBJP +#define j__udyAllocJBU j__udy1AllocJBU +#ifndef JU_64BIT +#define j__udyAllocJLL1 j__udy1AllocJLL1 +#endif +#define j__udyAllocJLL2 j__udy1AllocJLL2 +#define j__udyAllocJLL3 j__udy1AllocJLL3 +#ifdef JU_64BIT +#define j__udyAllocJLL4 j__udy1AllocJLL4 +#define j__udyAllocJLL5 j__udy1AllocJLL5 +#define j__udyAllocJLL6 j__udy1AllocJLL6 +#define j__udyAllocJLL7 j__udy1AllocJLL7 +#endif +#define j__udyAllocJLW j__udy1AllocJLW +#define j__udyAllocJLB1 j__udy1AllocJLB1 +#define j__udyFreeJPM j__udy1FreeJ1PM +#define j__udyFreeJBL j__udy1FreeJBL +#define j__udyFreeJBB j__udy1FreeJBB +#define j__udyFreeJBBJP j__udy1FreeJBBJP +#define j__udyFreeJBU j__udy1FreeJBU +#ifndef JU_64BIT +#define j__udyFreeJLL1 j__udy1FreeJLL1 +#endif +#define j__udyFreeJLL2 j__udy1FreeJLL2 +#define j__udyFreeJLL3 j__udy1FreeJLL3 +#ifdef JU_64BIT +#define j__udyFreeJLL4 j__udy1FreeJLL4 +#define j__udyFreeJLL5 j__udy1FreeJLL5 +#define j__udyFreeJLL6 j__udy1FreeJLL6 +#define j__udyFreeJLL7 j__udy1FreeJLL7 +#endif +#define j__udyFreeJLW j__udy1FreeJLW +#define j__udyFreeJLB1 j__udy1FreeJLB1 +#define j__udyFreeSM j__udy1FreeSM + +#define j__uMaxWords j__u1MaxWords + +#ifdef DEBUG +#define JudyCheckPop Judy1CheckPop +#endif + +#else // JUDYL **************************************************************** + +#define cJU_LEAFW_MAXPOP1 cJL_LEAFW_MAXPOP1 +#define cJU_LEAF1_MAXPOP1 cJL_LEAF1_MAXPOP1 +#define cJU_LEAF2_MAXPOP1 cJL_LEAF2_MAXPOP1 +#define cJU_LEAF3_MAXPOP1 cJL_LEAF3_MAXPOP1 +#ifdef JU_64BIT +#define cJU_LEAF4_MAXPOP1 cJL_LEAF4_MAXPOP1 +#define cJU_LEAF5_MAXPOP1 cJL_LEAF5_MAXPOP1 +#define cJU_LEAF6_MAXPOP1 cJL_LEAF6_MAXPOP1 +#define cJU_LEAF7_MAXPOP1 cJL_LEAF7_MAXPOP1 +#endif +#define cJU_IMMED1_MAXPOP1 cJL_IMMED1_MAXPOP1 +#define cJU_IMMED2_MAXPOP1 cJL_IMMED2_MAXPOP1 +#define cJU_IMMED3_MAXPOP1 cJL_IMMED3_MAXPOP1 +#ifdef JU_64BIT +#define cJU_IMMED4_MAXPOP1 cJL_IMMED4_MAXPOP1 +#define cJU_IMMED5_MAXPOP1 cJL_IMMED5_MAXPOP1 +#define cJU_IMMED6_MAXPOP1 cJL_IMMED6_MAXPOP1 +#define cJU_IMMED7_MAXPOP1 cJL_IMMED7_MAXPOP1 +#endif + +#define JU_LEAF1POPTOWORDS(Pop1) JL_LEAF1POPTOWORDS(Pop1) +#define JU_LEAF2POPTOWORDS(Pop1) JL_LEAF2POPTOWORDS(Pop1) +#define JU_LEAF3POPTOWORDS(Pop1) JL_LEAF3POPTOWORDS(Pop1) +#ifdef JU_64BIT +#define JU_LEAF4POPTOWORDS(Pop1) JL_LEAF4POPTOWORDS(Pop1) +#define JU_LEAF5POPTOWORDS(Pop1) JL_LEAF5POPTOWORDS(Pop1) +#define JU_LEAF6POPTOWORDS(Pop1) JL_LEAF6POPTOWORDS(Pop1) +#define JU_LEAF7POPTOWORDS(Pop1) JL_LEAF7POPTOWORDS(Pop1) +#endif +#define JU_LEAFWPOPTOWORDS(Pop1) JL_LEAFWPOPTOWORDS(Pop1) + +#define JU_LEAF1GROWINPLACE(Pop1) JL_LEAF1GROWINPLACE(Pop1) +#define JU_LEAF2GROWINPLACE(Pop1) JL_LEAF2GROWINPLACE(Pop1) +#define JU_LEAF3GROWINPLACE(Pop1) JL_LEAF3GROWINPLACE(Pop1) +#ifdef JU_64BIT +#define JU_LEAF4GROWINPLACE(Pop1) JL_LEAF4GROWINPLACE(Pop1) +#define JU_LEAF5GROWINPLACE(Pop1) JL_LEAF5GROWINPLACE(Pop1) +#define JU_LEAF6GROWINPLACE(Pop1) JL_LEAF6GROWINPLACE(Pop1) +#define JU_LEAF7GROWINPLACE(Pop1) JL_LEAF7GROWINPLACE(Pop1) +#endif +#define JU_LEAFWGROWINPLACE(Pop1) JL_LEAFWGROWINPLACE(Pop1) + +#define j__udyCreateBranchL j__udyLCreateBranchL +#define j__udyCreateBranchB j__udyLCreateBranchB +#define j__udyCreateBranchU j__udyLCreateBranchU +#define j__udyCascade1 j__udyLCascade1 +#define j__udyCascade2 j__udyLCascade2 +#define j__udyCascade3 j__udyLCascade3 +#ifdef JU_64BIT +#define j__udyCascade4 j__udyLCascade4 +#define j__udyCascade5 j__udyLCascade5 +#define j__udyCascade6 j__udyLCascade6 +#define j__udyCascade7 j__udyLCascade7 +#endif +#define j__udyCascadeL j__udyLCascadeL +#define j__udyInsertBranch j__udyLInsertBranch + +#define j__udyBranchBToBranchL j__udyLBranchBToBranchL +#define j__udyLeafB1ToLeaf1 j__udyLLeafB1ToLeaf1 +#define j__udyLeaf1ToLeaf2 j__udyLLeaf1ToLeaf2 +#define j__udyLeaf2ToLeaf3 j__udyLLeaf2ToLeaf3 +#ifndef JU_64BIT +#define j__udyLeaf3ToLeafW j__udyLLeaf3ToLeafW +#else +#define j__udyLeaf3ToLeaf4 j__udyLLeaf3ToLeaf4 +#define j__udyLeaf4ToLeaf5 j__udyLLeaf4ToLeaf5 +#define j__udyLeaf5ToLeaf6 j__udyLLeaf5ToLeaf6 +#define j__udyLeaf6ToLeaf7 j__udyLLeaf6ToLeaf7 +#define j__udyLeaf7ToLeafW j__udyLLeaf7ToLeafW +#endif + +#define jpm_t jLpm_t +#define Pjpm_t PjLpm_t + +#define jlb_t jLlb_t +#define Pjlb_t PjLlb_t + +#define JU_JLB_BITMAP JL_JLB_BITMAP + +#define j__udyAllocJPM j__udyLAllocJLPM +#define j__udyAllocJBL j__udyLAllocJBL +#define j__udyAllocJBB j__udyLAllocJBB +#define j__udyAllocJBBJP j__udyLAllocJBBJP +#define j__udyAllocJBU j__udyLAllocJBU +#define j__udyAllocJLL1 j__udyLAllocJLL1 +#define j__udyAllocJLL2 j__udyLAllocJLL2 +#define j__udyAllocJLL3 j__udyLAllocJLL3 +#ifdef JU_64BIT +#define j__udyAllocJLL4 j__udyLAllocJLL4 +#define j__udyAllocJLL5 j__udyLAllocJLL5 +#define j__udyAllocJLL6 j__udyLAllocJLL6 +#define j__udyAllocJLL7 j__udyLAllocJLL7 +#endif +#define j__udyAllocJLW j__udyLAllocJLW +#define j__udyAllocJLB1 j__udyLAllocJLB1 +// j__udyLAllocJV +#define j__udyFreeJPM j__udyLFreeJLPM +#define j__udyFreeJBL j__udyLFreeJBL +#define j__udyFreeJBB j__udyLFreeJBB +#define j__udyFreeJBBJP j__udyLFreeJBBJP +#define j__udyFreeJBU j__udyLFreeJBU +#define j__udyFreeJLL1 j__udyLFreeJLL1 +#define j__udyFreeJLL2 j__udyLFreeJLL2 +#define j__udyFreeJLL3 j__udyLFreeJLL3 +#ifdef JU_64BIT +#define j__udyFreeJLL4 j__udyLFreeJLL4 +#define j__udyFreeJLL5 j__udyLFreeJLL5 +#define j__udyFreeJLL6 j__udyLFreeJLL6 +#define j__udyFreeJLL7 j__udyLFreeJLL7 +#endif +#define j__udyFreeJLW j__udyLFreeJLW +#define j__udyFreeJLB1 j__udyLFreeJLB1 +#define j__udyFreeSM j__udyLFreeSM +// j__udyLFreeJV + +#define j__uMaxWords j__uLMaxWords + +#ifdef DEBUG +#define JudyCheckPop JudyLCheckPop +#endif + +#endif // JUDYL + +#endif // _JUDYPRIVATE1L_INCLUDED diff --git a/feeds/p4/libjudy/src/src/JudyCommon/JudyPrivateBranch.h b/feeds/p4/libjudy/src/src/JudyCommon/JudyPrivateBranch.h new file mode 100644 index 000000000..10295ba95 --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudyCommon/JudyPrivateBranch.h @@ -0,0 +1,788 @@ +#ifndef _JUDY_PRIVATE_BRANCH_INCLUDED +#define _JUDY_PRIVATE_BRANCH_INCLUDED +// _________________ +// +// Copyright (C) 2000 - 2002 Hewlett-Packard Company +// +// This program is free software; you can redistribute it and/or modify it +// under the term of the GNU Lesser 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 Lesser General Public License +// for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// _________________ + +// @(#) $Revision: 1.2 $ $Source: /home/doug/judy-1.0.5_min/test/../src/JudyCommon/RCS/JudyPrivateBranch.h,v $ +// +// Header file for all Judy sources, for global but private (non-exported) +// declarations specific to branch support. +// +// See also the "Judy Shop Manual" (try judy/doc/int/JudyShopManual.*). + + +// **************************************************************************** +// JUDY POINTER (JP) SUPPORT +// **************************************************************************** +// +// This "rich pointer" object is pivotal to Judy execution. +// +// JP CONTAINING OTHER THAN IMMEDIATE INDEXES: +// +// If the JP points to a linear or bitmap leaf, jp_DcdPopO contains the +// Population-1 in LSbs and Decode (Dcd) bytes in the MSBs. (In practice the +// Decode bits are masked off while accessing the Pop0 bits.) +// +// The Decode Size, the number of Dcd bytes available, is encoded in jpo_Type. +// It can also be thought of as the number of states "skipped" in the SM, where +// each state decodes 8 bits = 1 byte. +// +// TBD: Dont need two structures, except possibly to force jp_Type to highest +// address! +// +// Note: The jpo_u union is not required by HP-UX or Linux but Win32 because +// the cl.exe compiler otherwise refuses to pack a bitfield (DcdPopO) with +// anything else, even with the -Zp option. This is pretty ugly, but +// fortunately portable, and its all hide-able by macros (see below). + +typedef struct J_UDY_POINTER_OTHERS // JPO. + { + Word_t j_po_Addr; // first word: Pjp_t, Word_t, etc. + union { + Word_t j_po_Addr1; + uint8_t j_po_DcdP0[sizeof(Word_t) - 1]; + uint8_t j_po_Bytes[sizeof(Word_t)]; // last byte = jp_Type. + } jpo_u; + } jpo_t; + + +// JP CONTAINING IMMEDIATE INDEXES: +// +// j_pi_1Index[] plus j_pi_LIndex[] together hold as many N-byte (1..3-byte +// [1..7-byte]) Indexes as will fit in sizeof(jpi_t) less 1 byte for j_pi_Type +// (that is, 7..1 [15..1] Indexes). +// +// For Judy1, j_pi_1Index[] is used and j_pi_LIndex[] is not used. +// For JudyL, j_pi_LIndex[] is used and j_pi_1Index[] is not used. +// +// Note: Actually when Pop1 = 1, jpi_t is not used, and the least bytes of the +// single Index are stored in j_po_DcdPopO, for both Judy1 and JudyL, so for +// JudyL the j_po_Addr field can hold the target value. +// +// TBD: Revise this structure to not overload j_po_DcdPopO this way? The +// current arrangement works, its just confusing. + +typedef struct _JUDY_POINTER_IMMEDL + { + Word_t j_pL_Addr; + uint8_t j_pL_LIndex[sizeof(Word_t) - 1]; // see above. + uint8_t j_pL_Type; + } jpL_t; + +typedef struct _JUDY_POINTER_IMMED1 + { + uint8_t j_p1_1Index[(2 * sizeof(Word_t)) - 1]; + uint8_t j_p1_Type; + } jp1_t; + +// UNION OF JP TYPES: +// +// A branch is an array of cJU_BRANCHUNUMJPS (256) of this object, or an +// alternate data type such as: A linear branch which is a list of 2..7 JPs, +// or a bitmap branch which contains 8 lists of 0..32 JPs. JPs reside only in +// branches of a Judy SM. + +typedef union J_UDY_POINTER // JP. + { + jpo_t j_po; // other than immediate indexes. + jpL_t j_pL; // immediate indexes. + jp1_t j_p1; // immediate indexes. + } jp_t, *Pjp_t; + +// For coding convenience: +// +// Note, jp_Type has the same bits in jpo_t jpL_t and jp1_t. + +#define jp_1Index j_p1.j_p1_1Index // for storing Indexes in first word. +#define jp_LIndex j_pL.j_pL_LIndex // for storing Indexes in second word. +#define jp_Addr j_po.j_po_Addr +#define jp_Addr1 j_po.jpo_u.j_po_Addr1 +//#define jp_DcdPop0 j_po.jpo_u.j_po_DcdPop0 +#define jp_Addr1 j_po.jpo_u.j_po_Addr1 +//#define jp_Type j_po.jpo_u.j_po_Bytes[sizeof(Word_t) - 1] +#define jp_Type j_p1.j_p1_Type +#define jp_DcdP0 j_po.jpo_u.j_po_DcdP0 + + +// **************************************************************************** +// JUDY POINTER (JP) -- RELATED MACROS AND CONSTANTS +// **************************************************************************** + +// EXTRACT VALUES FROM JP: +// +// Masks for the bytes in the Dcd and Pop0 parts of jp_DcdPopO: +// +// cJU_DCDMASK() consists of a mask that excludes the (LSb) Pop0 bytes and +// also, just to be safe, the top byte of the word, since jp_DcdPopO is 1 byte +// less than a full word. +// +// Note: These are constant macros (cJU) because cPopBytes should be a +// constant. Also note cPopBytes == state in the SM. + +#define cJU_POP0MASK(cPopBytes) JU_LEASTBYTESMASK(cPopBytes) + +#define cJU_DCDMASK(cPopBytes) \ + ((cJU_ALLONES >> cJU_BITSPERBYTE) & (~cJU_POP0MASK(cPopBytes))) + +// Mask off the high byte from INDEX to it can be compared to DcdPopO: + +#define JU_TRIMTODCDSIZE(INDEX) ((cJU_ALLONES >> cJU_BITSPERBYTE) & (INDEX)) + +// Get from jp_DcdPopO the Pop0 for various branch JP Types: +// +// Note: There are no simple macros for cJU_BRANCH* Types because their +// populations must be added up and dont reside in an already-calculated +// place. + +#define JU_JPBRANCH_POP0(PJP,cPopBytes) \ + (JU_JPDCDPOP0(PJP) & cJU_POP0MASK(cPopBytes)) + +// METHOD FOR DETERMINING IF OBJECTS HAVE ROOM TO GROW: +// +// J__U_GROWCK() is a generic method to determine if an object can grow in +// place, based on whether the next population size (one more) would use the +// same space. + +#define J__U_GROWCK(POP1,MAXPOP1,POPTOWORDS) \ + (((POP1) != (MAXPOP1)) && (POPTOWORDS[POP1] == POPTOWORDS[(POP1) + 1])) + +#define JU_BRANCHBJPGROWINPLACE(NumJPs) \ + J__U_GROWCK(NumJPs, cJU_BITSPERSUBEXPB, j__U_BranchBJPPopToWords) + + +// DETERMINE IF AN INDEX IS (NOT) IN A JPS EXPANSE: + +#define JU_DCDNOTMATCHINDEX(INDEX,PJP,POP0BYTES) \ + (((INDEX) ^ JU_JPDCDPOP0(PJP)) & cJU_DCDMASK(POP0BYTES)) + + +// NUMBER OF JPs IN AN UNCOMPRESSED BRANCH: +// +// An uncompressed branch is simply an array of 256 Judy Pointers (JPs). It is +// a minimum cacheline fill object. Define it here before its first needed. + +#define cJU_BRANCHUNUMJPS cJU_SUBEXPPERSTATE + + +// **************************************************************************** +// JUDY BRANCH LINEAR (JBL) SUPPORT +// **************************************************************************** +// +// A linear branch is a way of compressing empty expanses (null JPs) out of an +// uncompressed 256-way branch, when the number of populated expanses is so +// small that even a bitmap branch is excessive. +// +// The maximum number of JPs in a Judy linear branch: +// +// Note: This number results in a 1-cacheline sized structure. Previous +// versions had a larger struct so a linear branch didnt become a bitmap +// branch until the memory consumed was even, but for speed, its better to +// switch "sooner" and keep a linear branch fast. + +#define cJU_BRANCHLMAXJPS 7 + + +// LINEAR BRANCH STRUCT: +// +// 1-byte count, followed by array of byte-sized expanses, followed by JPs. + +typedef struct J__UDY_BRANCH_LINEAR + { + uint8_t jbl_NumJPs; // num of JPs (Pjp_t), 1..N. + uint8_t jbl_Expanse[cJU_BRANCHLMAXJPS]; // 1..7 MSbs of pop exps. + jp_t jbl_jp [cJU_BRANCHLMAXJPS]; // JPs for populated exps. + } jbl_t, * Pjbl_t; + + +// **************************************************************************** +// JUDY BRANCH BITMAP (JBB) SUPPORT +// **************************************************************************** +// +// A bitmap branch is a way of compressing empty expanses (null JPs) out of +// uncompressed 256-way branch. This costs 1 additional cache line fill, but +// can save a lot of memory when it matters most, near the leaves, and +// typically there will be only one at most in the path to any Index (leaf). +// +// The bitmap indicates which of the cJU_BRANCHUNUMJPS (256) JPs in the branch +// are NOT null, that is, their expanses are populated. The jbb_t also +// contains N pointers to "mini" Judy branches ("subexpanses") of up to M JPs +// each (see BITMAP_BRANCHMxN, for example, BITMAP_BRANCH32x8), where M x N = +// cJU_BRANCHUNUMJPS. These are dynamically allocated and never contain +// cJ*_JPNULL* jp_Types. An empty subexpanse is represented by no bit sets in +// the corresponding subexpanse bitmap, in which case the corresponding +// jbbs_Pjp pointers value is unused. +// +// Note that the number of valid JPs in each 1-of-N subexpanses is determined +// by POPULATION rather than by EXPANSE -- the desired outcome to save memory +// when near the leaves. Note that the memory required for 185 JPs is about as +// much as an uncompressed 256-way branch, therefore 184 is set as the maximum. +// However, it is expected that a conversion to an uncompressed 256-way branch +// will normally take place before this limit is reached for other reasons, +// such as improving performance when the "wasted" memory is well amortized by +// the population under the branch, preserving an acceptable overall +// bytes/Index in the Judy array. +// +// The number of pointers to arrays of JPs in the Judy bitmap branch: +// +// Note: The numbers below are the same in both 32 and 64 bit systems. + +#define cJU_BRANCHBMAXJPS 184 // maximum JPs for bitmap branches. + +// Convenience wrappers for referencing BranchB bitmaps or JP subarray +// pointers: +// +// Note: JU_JBB_PJP produces a "raw" memory address that must pass through +// P_JP before use, except when freeing memory: + +#define JU_JBB_BITMAP(Pjbb, SubExp) ((Pjbb)->jbb_jbbs[SubExp].jbbs_Bitmap) +#define JU_JBB_PJP( Pjbb, SubExp) ((Pjbb)->jbb_jbbs[SubExp].jbbs_Pjp) + +#define JU_SUBEXPB(Digit) (((Digit) / cJU_BITSPERSUBEXPB) & (cJU_NUMSUBEXPB-1)) + +#define JU_BITMAPTESTB(Pjbb, Index) \ + (JU_JBB_BITMAP(Pjbb, JU_SUBEXPB(Index)) & JU_BITPOSMASKB(Index)) + +#define JU_BITMAPSETB(Pjbb, Index) \ + (JU_JBB_BITMAP(Pjbb, JU_SUBEXPB(Index)) |= JU_BITPOSMASKB(Index)) + +// Note: JU_BITMAPCLEARB is not defined because the code does it a faster way. + +typedef struct J__UDY_BRANCH_BITMAP_SUBEXPANSE + { + BITMAPB_t jbbs_Bitmap; + Pjp_t jbbs_Pjp; + + } jbbs_t; + +typedef struct J__UDY_BRANCH_BITMAP + { + jbbs_t jbb_jbbs [cJU_NUMSUBEXPB]; +#ifdef SUBEXPCOUNTS + Word_t jbb_subPop1[cJU_NUMSUBEXPB]; +#endif + } jbb_t, * Pjbb_t; + +#define JU_BRANCHJP_NUMJPSTOWORDS(NumJPs) (j__U_BranchBJPPopToWords[NumJPs]) + +#ifdef SUBEXPCOUNTS +#define cJU_NUMSUBEXPU 16 // number of subexpanse counts. +#endif + + +// **************************************************************************** +// JUDY BRANCH UNCOMPRESSED (JBU) SUPPORT +// **************************************************************************** + +// Convenience wrapper for referencing BranchU JPs: +// +// Note: This produces a non-"raw" address already passed through P_JBU(). + +#define JU_JBU_PJP(Pjp,Index,Level) \ + (&((P_JBU((Pjp)->jp_Addr))->jbu_jp[JU_DIGITATSTATE(Index, Level)])) +#define JU_JBU_PJP0(Pjp) \ + (&((P_JBU((Pjp)->jp_Addr))->jbu_jp[0])) + +typedef struct J__UDY_BRANCH_UNCOMPRESSED + { + jp_t jbu_jp [cJU_BRANCHUNUMJPS]; // JPs for populated exp. +#ifdef SUBEXPCOUNTS + Word_t jbu_subPop1[cJU_NUMSUBEXPU]; +#endif + } jbu_t, * Pjbu_t; + + +// **************************************************************************** +// OTHER SUPPORT FOR JUDY STATE MACHINES (SMs) +// **************************************************************************** + +// OBJECT SIZES IN WORDS: +// +// Word_ts per various JudyL structures that have constant sizes. +// cJU_WORDSPERJP should always be 2; this is fundamental to the Judy +// structures. + +#define cJU_WORDSPERJP (sizeof(jp_t) / cJU_BYTESPERWORD) +#define cJU_WORDSPERCL (cJU_BYTESPERCL / cJU_BYTESPERWORD) + + +// OPPORTUNISTIC UNCOMPRESSION: +// +// Define populations at which a BranchL or BranchB must convert to BranchU. +// Earlier conversion is possible with good memory efficiency -- see below. + +#ifndef NO_BRANCHU + +// Max population below BranchL, then convert to BranchU: + +#define JU_BRANCHL_MAX_POP 1000 + +// Minimum global population increment before next conversion of a BranchB to a +// BranchU: +// +// This is was done to allow malloc() to coalesce memory before the next big +// (~512 words) allocation. + +#define JU_BTOU_POP_INCREMENT 300 + +// Min/max population below BranchB, then convert to BranchU: + +#define JU_BRANCHB_MIN_POP 135 +#define JU_BRANCHB_MAX_POP 750 + +#else // NO_BRANCHU + +// These are set up to have conservative conversion schedules to BranchU: + +#define JU_BRANCHL_MAX_POP (-1UL) +#define JU_BTOU_POP_INCREMENT 300 +#define JU_BRANCHB_MIN_POP 1000 +#define JU_BRANCHB_MAX_POP (-1UL) + +#endif // NO_BRANCHU + + +// MISCELLANEOUS MACROS: + +// Get N most significant bits from the shifted Index word: +// +// As Index words are decoded, they are shifted left so only relevant, +// undecoded Index bits remain. + +#define JU_BITSFROMSFTIDX(SFTIDX, N) ((SFTIDX) >> (cJU_BITSPERWORD - (N))) + +// TBD: I have my doubts about the necessity of these macros (dlb): + +// Produce 1-digit mask at specified state: + +#define cJU_MASKATSTATE(State) (0xffL << (((State) - 1) * cJU_BITSPERBYTE)) + +// Get byte (digit) from Index at the specified state, right justified: +// +// Note: State must be 1..cJU_ROOTSTATE, and Digits must be 1..(cJU_ROOTSTATE +// - 1), but theres no way to assert these within an expression. + +#define JU_DIGITATSTATE(Index,cState) \ + ((uint8_t)((Index) >> (((cState) - 1) * cJU_BITSPERBYTE))) + +// Similarly, place byte (digit) at correct position for the specified state: +// +// Note: Cast digit to a Word_t first so there are no complaints or problems +// about shifting it more than 32 bits on a 64-bit system, say, when it is a +// uint8_t from jbl_Expanse[]. (Believe it or not, the C standard says to +// promote an unsigned char to a signed int; -Ac does not do this, but -Ae +// does.) +// +// Also, to make lint happy, cast the whole result again because apparently +// shifting a Word_t does not result in a Word_t! + +#define JU_DIGITTOSTATE(Digit,cState) \ + ((Word_t) (((Word_t) (Digit)) << (((cState) - 1) * cJU_BITSPERBYTE))) + +#endif // ! _JUDY_PRIVATE_BRANCH_INCLUDED + + +#ifdef TEST_INSDEL + +// **************************************************************************** +// TEST CODE FOR INSERT/DELETE MACROS +// **************************************************************************** +// +// To use this, compile a temporary *.c file containing: +// +// #define DEBUG +// #define JUDY_ASSERT +// #define TEST_INSDEL +// #include "JudyPrivate.h" +// #include "JudyPrivateBranch.h" +// +// Use a command like this: cc -Ae +DD64 -I. -I JudyCommon -o t t.c +// For best results, include +DD64 on a 64-bit system. +// +// This test code exercises some tricky macros, but the output must be studied +// manually to verify it. Assume that for even-index testing, whole words +// (Word_t) suffices. + +#include + +#define INDEXES 3 // in each array. + + +// **************************************************************************** +// I N I T +// +// Set up variables for next test. See usage. + +FUNCTION void Init ( + int base, + PWord_t PeIndex, + PWord_t PoIndex, + PWord_t Peleaf, // always whole words. +#ifndef JU_64BIT + uint8_t * Poleaf3) +#else + uint8_t * Poleaf3, + uint8_t * Poleaf5, + uint8_t * Poleaf6, + uint8_t * Poleaf7) +#endif +{ + int offset; + + *PeIndex = 99; + + for (offset = 0; offset <= INDEXES; ++offset) + Peleaf[offset] = base + offset; + + for (offset = 0; offset < (INDEXES + 1) * 3; ++offset) + Poleaf3[offset] = base + offset; + +#ifndef JU_64BIT + *PoIndex = (91 << 24) | (92 << 16) | (93 << 8) | 94; +#else + + *PoIndex = (91L << 56) | (92L << 48) | (93L << 40) | (94L << 32) + | (95L << 24) | (96L << 16) | (97L << 8) | 98L; + + for (offset = 0; offset < (INDEXES + 1) * 5; ++offset) + Poleaf5[offset] = base + offset; + + for (offset = 0; offset < (INDEXES + 1) * 6; ++offset) + Poleaf6[offset] = base + offset; + + for (offset = 0; offset < (INDEXES + 1) * 7; ++offset) + Poleaf7[offset] = base + offset; +#endif + +} // Init() + + +// **************************************************************************** +// P R I N T L E A F +// +// Print the byte values in a leaf. + +FUNCTION void PrintLeaf ( + char * Label, // for output. + int IOffset, // insertion offset in array. + int Indsize, // index size in bytes. + uint8_t * PLeaf) // array of Index bytes. +{ + int offset; // in PLeaf. + int byte; // in one word. + + (void) printf("%s %u: ", Label, IOffset); + + for (offset = 0; offset <= INDEXES; ++offset) + { + for (byte = 0; byte < Indsize; ++byte) + (void) printf("%2d", PLeaf[(offset * Indsize) + byte]); + + (void) printf(" "); + } + + (void) printf("\n"); + +} // PrintLeaf() + + +// **************************************************************************** +// M A I N +// +// Test program. + +FUNCTION main() +{ + Word_t eIndex; // even, to insert. + Word_t oIndex; // odd, to insert. + Word_t eleaf [ INDEXES + 1]; // even leaf, index size 4. + uint8_t oleaf3[(INDEXES + 1) * 3]; // odd leaf, index size 3. +#ifdef JU_64BIT + uint8_t oleaf5[(INDEXES + 1) * 5]; // odd leaf, index size 5. + uint8_t oleaf6[(INDEXES + 1) * 6]; // odd leaf, index size 6. + uint8_t oleaf7[(INDEXES + 1) * 7]; // odd leaf, index size 7. +#endif + Word_t eleaf_2 [ INDEXES + 1]; // same, but second arrays: + uint8_t oleaf3_2[(INDEXES + 1) * 3]; +#ifdef JU_64BIT + uint8_t oleaf5_2[(INDEXES + 1) * 5]; + uint8_t oleaf6_2[(INDEXES + 1) * 6]; + uint8_t oleaf7_2[(INDEXES + 1) * 7]; +#endif + int ioffset; // index insertion offset. + +#ifndef JU_64BIT +#define INIT Init( 0, & eIndex, & oIndex, eleaf, oleaf3) +#define INIT2 INIT; Init(50, & eIndex, & oIndex, eleaf_2, oleaf3_2) +#else +#define INIT Init( 0, & eIndex, & oIndex, eleaf, oleaf3, \ + oleaf5, oleaf6, oleaf7) +#define INIT2 INIT; Init(50, & eIndex, & oIndex, eleaf_2, oleaf3_2, \ + oleaf5_2, oleaf6_2, oleaf7_2) +#endif + +#define WSIZE sizeof (Word_t) // shorthand. + +#ifdef PRINTALL // to turn on "noisy" printouts. +#define PRINTLEAF(Label,IOffset,Indsize,PLeaf) \ + PrintLeaf(Label,IOffset,Indsize,PLeaf) +#else +#define PRINTLEAF(Label,IOffset,Indsize,PLeaf) \ + if (ioffset == 0) \ + PrintLeaf(Label,IOffset,Indsize,PLeaf) +#endif + + (void) printf( +"In each case, tests operate on an initial array of %d indexes. Even-index\n" +"tests set index values to 0,1,2...; odd-index tests set byte values to\n" +"0,1,2... Inserted indexes have a value of 99 or else byte values 91,92,...\n", + INDEXES); + + (void) puts("\nJU_INSERTINPLACE():"); + + for (ioffset = 0; ioffset <= INDEXES; ++ioffset) + { + INIT; + PRINTLEAF("Before", ioffset, WSIZE, (uint8_t *) eleaf); + JU_INSERTINPLACE(eleaf, INDEXES, ioffset, eIndex); + PrintLeaf("After ", ioffset, WSIZE, (uint8_t *) eleaf); + } + + (void) puts("\nJU_INSERTINPLACE3():"); + + for (ioffset = 0; ioffset <= INDEXES; ++ioffset) + { + INIT; + PRINTLEAF("Before", ioffset, 3, oleaf3); + JU_INSERTINPLACE3(oleaf3, INDEXES, ioffset, oIndex); + PrintLeaf("After ", ioffset, 3, oleaf3); + } + +#ifdef JU_64BIT + (void) puts("\nJU_INSERTINPLACE5():"); + + for (ioffset = 0; ioffset <= INDEXES; ++ioffset) + { + INIT; + PRINTLEAF("Before", ioffset, 5, oleaf5); + JU_INSERTINPLACE5(oleaf5, INDEXES, ioffset, oIndex); + PrintLeaf("After ", ioffset, 5, oleaf5); + } + + (void) puts("\nJU_INSERTINPLACE6():"); + + for (ioffset = 0; ioffset <= INDEXES; ++ioffset) + { + INIT; + PRINTLEAF("Before", ioffset, 6, oleaf6); + JU_INSERTINPLACE6(oleaf6, INDEXES, ioffset, oIndex); + PrintLeaf("After ", ioffset, 6, oleaf6); + } + + (void) puts("\nJU_INSERTINPLACE7():"); + + for (ioffset = 0; ioffset <= INDEXES; ++ioffset) + { + INIT; + PRINTLEAF("Before", ioffset, 7, oleaf7); + JU_INSERTINPLACE7(oleaf7, INDEXES, ioffset, oIndex); + PrintLeaf("After ", ioffset, 7, oleaf7); + } +#endif // JU_64BIT + + (void) puts("\nJU_DELETEINPLACE():"); + + for (ioffset = 0; ioffset < INDEXES; ++ioffset) + { + INIT; + PRINTLEAF("Before", ioffset, WSIZE, (uint8_t *) eleaf); + JU_DELETEINPLACE(eleaf, INDEXES, ioffset); + PrintLeaf("After ", ioffset, WSIZE, (uint8_t *) eleaf); + } + + (void) puts("\nJU_DELETEINPLACE_ODD(3):"); + + for (ioffset = 0; ioffset < INDEXES; ++ioffset) + { + INIT; + PRINTLEAF("Before", ioffset, 3, oleaf3); + JU_DELETEINPLACE_ODD(oleaf3, INDEXES, ioffset, 3); + PrintLeaf("After ", ioffset, 3, oleaf3); + } + +#ifdef JU_64BIT + (void) puts("\nJU_DELETEINPLACE_ODD(5):"); + + for (ioffset = 0; ioffset < INDEXES; ++ioffset) + { + INIT; + PRINTLEAF("Before", ioffset, 5, oleaf5); + JU_DELETEINPLACE_ODD(oleaf5, INDEXES, ioffset, 5); + PrintLeaf("After ", ioffset, 5, oleaf5); + } + + (void) puts("\nJU_DELETEINPLACE_ODD(6):"); + + for (ioffset = 0; ioffset < INDEXES; ++ioffset) + { + INIT; + PRINTLEAF("Before", ioffset, 6, oleaf6); + JU_DELETEINPLACE_ODD(oleaf6, INDEXES, ioffset, 6); + PrintLeaf("After ", ioffset, 6, oleaf6); + } + + (void) puts("\nJU_DELETEINPLACE_ODD(7):"); + + for (ioffset = 0; ioffset < INDEXES; ++ioffset) + { + INIT; + PRINTLEAF("Before", ioffset, 7, oleaf7); + JU_DELETEINPLACE_ODD(oleaf7, INDEXES, ioffset, 7); + PrintLeaf("After ", ioffset, 7, oleaf7); + } +#endif // JU_64BIT + + (void) puts("\nJU_INSERTCOPY():"); + + for (ioffset = 0; ioffset <= INDEXES; ++ioffset) + { + INIT2; + PRINTLEAF("Before, src ", ioffset, WSIZE, (uint8_t *) eleaf); + PRINTLEAF("Before, dest", ioffset, WSIZE, (uint8_t *) eleaf_2); + JU_INSERTCOPY(eleaf_2, eleaf, INDEXES, ioffset, eIndex); + PRINTLEAF("After, src ", ioffset, WSIZE, (uint8_t *) eleaf); + PrintLeaf("After, dest", ioffset, WSIZE, (uint8_t *) eleaf_2); + } + + (void) puts("\nJU_INSERTCOPY3():"); + + for (ioffset = 0; ioffset <= INDEXES; ++ioffset) + { + INIT2; + PRINTLEAF("Before, src ", ioffset, 3, oleaf3); + PRINTLEAF("Before, dest", ioffset, 3, oleaf3_2); + JU_INSERTCOPY3(oleaf3_2, oleaf3, INDEXES, ioffset, oIndex); + PRINTLEAF("After, src ", ioffset, 3, oleaf3); + PrintLeaf("After, dest", ioffset, 3, oleaf3_2); + } + +#ifdef JU_64BIT + (void) puts("\nJU_INSERTCOPY5():"); + + for (ioffset = 0; ioffset <= INDEXES; ++ioffset) + { + INIT2; + PRINTLEAF("Before, src ", ioffset, 5, oleaf5); + PRINTLEAF("Before, dest", ioffset, 5, oleaf5_2); + JU_INSERTCOPY5(oleaf5_2, oleaf5, INDEXES, ioffset, oIndex); + PRINTLEAF("After, src ", ioffset, 5, oleaf5); + PrintLeaf("After, dest", ioffset, 5, oleaf5_2); + } + + (void) puts("\nJU_INSERTCOPY6():"); + + for (ioffset = 0; ioffset <= INDEXES; ++ioffset) + { + INIT2; + PRINTLEAF("Before, src ", ioffset, 6, oleaf6); + PRINTLEAF("Before, dest", ioffset, 6, oleaf6_2); + JU_INSERTCOPY6(oleaf6_2, oleaf6, INDEXES, ioffset, oIndex); + PRINTLEAF("After, src ", ioffset, 6, oleaf6); + PrintLeaf("After, dest", ioffset, 6, oleaf6_2); + } + + (void) puts("\nJU_INSERTCOPY7():"); + + for (ioffset = 0; ioffset <= INDEXES; ++ioffset) + { + INIT2; + PRINTLEAF("Before, src ", ioffset, 7, oleaf7); + PRINTLEAF("Before, dest", ioffset, 7, oleaf7_2); + JU_INSERTCOPY7(oleaf7_2, oleaf7, INDEXES, ioffset, oIndex); + PRINTLEAF("After, src ", ioffset, 7, oleaf7); + PrintLeaf("After, dest", ioffset, 7, oleaf7_2); + } +#endif // JU_64BIT + + (void) puts("\nJU_DELETECOPY():"); + + for (ioffset = 0; ioffset < INDEXES; ++ioffset) + { + INIT2; + PRINTLEAF("Before, src ", ioffset, WSIZE, (uint8_t *) eleaf); + PRINTLEAF("Before, dest", ioffset, WSIZE, (uint8_t *) eleaf_2); + JU_DELETECOPY(eleaf_2, eleaf, INDEXES, ioffset, ignore); + PRINTLEAF("After, src ", ioffset, WSIZE, (uint8_t *) eleaf); + PrintLeaf("After, dest", ioffset, WSIZE, (uint8_t *) eleaf_2); + } + + (void) puts("\nJU_DELETECOPY_ODD(3):"); + + for (ioffset = 0; ioffset < INDEXES; ++ioffset) + { + INIT2; + PRINTLEAF("Before, src ", ioffset, 3, oleaf3); + PRINTLEAF("Before, dest", ioffset, 3, oleaf3_2); + JU_DELETECOPY_ODD(oleaf3_2, oleaf3, INDEXES, ioffset, 3); + PRINTLEAF("After, src ", ioffset, 3, oleaf3); + PrintLeaf("After, dest", ioffset, 3, oleaf3_2); + } + +#ifdef JU_64BIT + (void) puts("\nJU_DELETECOPY_ODD(5):"); + + for (ioffset = 0; ioffset < INDEXES; ++ioffset) + { + INIT2; + PRINTLEAF("Before, src ", ioffset, 5, oleaf5); + PRINTLEAF("Before, dest", ioffset, 5, oleaf5_2); + JU_DELETECOPY_ODD(oleaf5_2, oleaf5, INDEXES, ioffset, 5); + PRINTLEAF("After, src ", ioffset, 5, oleaf5); + PrintLeaf("After, dest", ioffset, 5, oleaf5_2); + } + + (void) puts("\nJU_DELETECOPY_ODD(6):"); + + for (ioffset = 0; ioffset < INDEXES; ++ioffset) + { + INIT2; + PRINTLEAF("Before, src ", ioffset, 6, oleaf6); + PRINTLEAF("Before, dest", ioffset, 6, oleaf6_2); + JU_DELETECOPY_ODD(oleaf6_2, oleaf6, INDEXES, ioffset, 6); + PRINTLEAF("After, src ", ioffset, 6, oleaf6); + PrintLeaf("After, dest", ioffset, 6, oleaf6_2); + } + + (void) puts("\nJU_DELETECOPY_ODD(7):"); + + for (ioffset = 0; ioffset < INDEXES; ++ioffset) + { + INIT2; + PRINTLEAF("Before, src ", ioffset, 7, oleaf7); + PRINTLEAF("Before, dest", ioffset, 7, oleaf7_2); + JU_DELETECOPY_ODD(oleaf7_2, oleaf7, INDEXES, ioffset, 7); + PRINTLEAF("After, src ", ioffset, 7, oleaf7); + PrintLeaf("After, dest", ioffset, 7, oleaf7_2); + } +#endif // JU_64BIT + + return(0); + +} // main() + +#endif // TEST_INSDEL diff --git a/feeds/p4/libjudy/src/src/JudyCommon/JudyTables.c b/feeds/p4/libjudy/src/src/JudyCommon/JudyTables.c new file mode 100644 index 000000000..cb8b13ff7 --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudyCommon/JudyTables.c @@ -0,0 +1,296 @@ +// Copyright (C) 2000 - 2002 Hewlett-Packard Company +// +// This program is free software; you can redistribute it and/or modify it +// under the term of the GNU Lesser 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 Lesser General Public License +// for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// _________________ + +// @(#) $Revision: 4.37 $ $Source: /judy/src/JudyCommon/JudyTables.c $ + +#ifndef JU_WIN +#include // unavailable on win_*. +#endif + +#include +#include + +#if (! (defined(JUDY1) || defined(JUDYL))) +#error: One of -DJUDY1 or -DJUDYL must be specified. +#endif + +#define TERMINATOR 999 // terminator for Alloc tables + +#define BPW sizeof(Word_t) // define bytes per word + +#ifdef JUDY1 +#include "Judy1.h" +#else +#include "JudyL.h" +#endif + +FILE *fd; + +// Definitions come from header files Judy1.h and JudyL.h: + +int AllocSizes[] = ALLOCSIZES; + +#define ROUNDUP(BYTES,BPW,OFFSETW) \ + ((((BYTES) + (BPW) - 1) / (BPW)) + (OFFSETW)) + + +// **************************************************************************** +// G E N T A B L E +// +// Note: "const" is required for newer compilers. + +FUNCTION void GenTable( + const char * TableName, // name of table string + const char * TableSize, // dimentioned size string + int IndexBytes, // bytes per Index + int LeafSize, // number elements in object + int ValueBytes, // bytes per Value + int OffsetWords) // 1 for LEAFW +{ + int * PAllocSizes = AllocSizes; + int OWord; + int CurWord; + int IWord; + int ii; + int BytesOfIndex; + int BytesOfObject; + int Index; + int LastWords; + int Words [1000] = { 0 }; + int Offset[1000] = { 0 }; + int MaxWords; + + MaxWords = ROUNDUP((IndexBytes + ValueBytes) * LeafSize, BPW, OffsetWords); + Words[0] = 0; + Offset[0] = 0; + CurWord = TERMINATOR; + +// Walk through all number of Indexes in table: + + for (Index = 1; /* null */; ++Index) + { + +// Calculate byte required for next size: + + BytesOfIndex = IndexBytes * Index; + BytesOfObject = (IndexBytes + ValueBytes) * Index; + +// Round up and calculate words required for next size: + + OWord = ROUNDUP(BytesOfObject, BPW, OffsetWords); + IWord = ROUNDUP(BytesOfIndex, BPW, OffsetWords); + +// Root-level leaves of population of 1 and 2 do not have the 1 word offset: + +// Save minimum value of offset: + + Offset[Index] = IWord; + +// Round up to next available size of words: + + while (OWord > *PAllocSizes) PAllocSizes++; + + if (Index == LeafSize) + { + CurWord = Words[Index] = OWord; + break; + } +// end of available sizes ? + + if (*PAllocSizes == TERMINATOR) + { + fprintf(stderr, "BUG, in %sPopToWords, sizes not big enough for object\n", TableName); + exit(1); + } + +// Save words required and last word: + + if (*PAllocSizes < MaxWords) { CurWord = Words[Index] = *PAllocSizes; } + else { CurWord = Words[Index] = MaxWords; } + + } // for each index + + LastWords = TERMINATOR; + +// Round up to largest size in each group of malloc sizes: + + for (ii = LeafSize; ii > 0; ii--) + { + if (LastWords > (Words[ii] - ii)) LastWords = Offset[ii]; + else Offset[ii] = LastWords; + } + +// Print the PopToWords[] table: + + fprintf(fd,"\n//\tobject uses %d words\n", CurWord); + fprintf(fd,"//\t%s = %d\n", TableSize, LeafSize); + + fprintf(fd,"const uint8_t\n"); + fprintf(fd,"%sPopToWords[%s + 1] =\n", TableName, TableSize); + fprintf(fd,"{\n\t 0,"); + + for (ii = 1; ii <= LeafSize; ii++) + { + +// 8 columns per line, starting with 1: + + if ((ii % 8) == 1) fprintf(fd,"\n\t"); + + fprintf(fd,"%2d", Words[ii]); + +// If not last number place comma: + + if (ii != LeafSize) fprintf(fd,", "); + } + fprintf(fd,"\n};\n"); + +// Print the Offset table if needed: + + if (! ValueBytes) return; + + fprintf(fd,"const uint8_t\n"); + fprintf(fd,"%sOffset[%s + 1] =\n", TableName, TableSize); + fprintf(fd,"{\n"); + fprintf(fd,"\t 0,"); + + for (ii = 1; ii <= LeafSize; ii++) + { + if ((ii % 8) == 1) fprintf(fd,"\n\t"); + + fprintf(fd,"%2d", Offset[ii]); + + if (ii != LeafSize) fprintf(fd,", "); + } + fprintf(fd,"\n};\n"); + +} // GenTable() + + +// **************************************************************************** +// M A I N + +FUNCTION int main() +{ + int ii; + +#ifdef JUDY1 + char *fname = "Judy1Tables.c"; +#else + char *fname = "JudyLTables.c"; +#endif + + if ((fd = fopen(fname, "w")) == NULL){ + perror("FATAL ERROR: could not write to Judy[1L]Tables.c file\n"); + return (-1); + } + + + fprintf(fd,"// @(#) From generation tool: $Revision: 4.37 $ $Source: /judy/src/JudyCommon/JudyTables.c $\n"); + fprintf(fd,"//\n\n"); + + +// ================================ Judy1 ================================= +#ifdef JUDY1 + + fprintf(fd,"#include \"Judy1.h\"\n"); + + fprintf(fd,"// Leave the malloc() sizes readable in the binary (via " + "strings(1)):\n"); + fprintf(fd,"const char * Judy1MallocSizes = \"Judy1MallocSizes ="); + + for (ii = 0; AllocSizes[ii] != TERMINATOR; ii++) + fprintf(fd," %d,", AllocSizes[ii]); + +#ifndef JU_64BIT + fprintf(fd," Leaf1 = %d\";\n\n", cJ1_LEAF1_MAXPOP1); +#else + fprintf(fd,"\";\n\n"); // no Leaf1 in this case. +#endif + +// ================================ 32 bit ================================ +#ifndef JU_64BIT + + GenTable("j__1_BranchBJP","cJU_BITSPERSUBEXPB", 8, cJU_BITSPERSUBEXPB,0,0); + + GenTable("j__1_Leaf1", "cJ1_LEAF1_MAXPOP1", 1, cJ1_LEAF1_MAXPOP1, 0, 0); + GenTable("j__1_Leaf2", "cJ1_LEAF2_MAXPOP1", 2, cJ1_LEAF2_MAXPOP1, 0, 0); + GenTable("j__1_Leaf3", "cJ1_LEAF3_MAXPOP1", 3, cJ1_LEAF3_MAXPOP1, 0, 0); + GenTable("j__1_LeafW", "cJ1_LEAFW_MAXPOP1", 4, cJ1_LEAFW_MAXPOP1, 0, 1); + +#endif + +// ================================ 64 bit ================================ +#ifdef JU_64BIT + GenTable("j__1_BranchBJP","cJU_BITSPERSUBEXPB",16, cJU_BITSPERSUBEXPB,0,0); + + GenTable("j__1_Leaf2", "cJ1_LEAF2_MAXPOP1", 2, cJ1_LEAF2_MAXPOP1, 0, 0); + GenTable("j__1_Leaf3", "cJ1_LEAF3_MAXPOP1", 3, cJ1_LEAF3_MAXPOP1, 0, 0); + GenTable("j__1_Leaf4", "cJ1_LEAF4_MAXPOP1", 4, cJ1_LEAF4_MAXPOP1, 0, 0); + GenTable("j__1_Leaf5", "cJ1_LEAF5_MAXPOP1", 5, cJ1_LEAF5_MAXPOP1, 0, 0); + GenTable("j__1_Leaf6", "cJ1_LEAF6_MAXPOP1", 6, cJ1_LEAF6_MAXPOP1, 0, 0); + GenTable("j__1_Leaf7", "cJ1_LEAF7_MAXPOP1", 7, cJ1_LEAF7_MAXPOP1, 0, 0); + GenTable("j__1_LeafW", "cJ1_LEAFW_MAXPOP1", 8, cJ1_LEAFW_MAXPOP1, 0, 1); +#endif +#endif // JUDY1 + + +// ================================ JudyL ================================= +#ifdef JUDYL + + fprintf(fd,"#include \"JudyL.h\"\n"); + + fprintf(fd,"// Leave the malloc() sizes readable in the binary (via " + "strings(1)):\n"); + fprintf(fd,"const char * JudyLMallocSizes = \"JudyLMallocSizes ="); + + for (ii = 0; AllocSizes[ii] != TERMINATOR; ii++) + fprintf(fd," %d,", AllocSizes[ii]); + + fprintf(fd," Leaf1 = %ld\";\n\n", (Word_t)cJL_LEAF1_MAXPOP1); + +#ifndef JU_64BIT +// ================================ 32 bit ================================ + GenTable("j__L_BranchBJP","cJU_BITSPERSUBEXPB", 8, cJU_BITSPERSUBEXPB, 0,0); + + GenTable("j__L_Leaf1", "cJL_LEAF1_MAXPOP1", 1, cJL_LEAF1_MAXPOP1, BPW,0); + GenTable("j__L_Leaf2", "cJL_LEAF2_MAXPOP1", 2, cJL_LEAF2_MAXPOP1, BPW,0); + GenTable("j__L_Leaf3", "cJL_LEAF3_MAXPOP1", 3, cJL_LEAF3_MAXPOP1, BPW,0); + GenTable("j__L_LeafW", "cJL_LEAFW_MAXPOP1", 4, cJL_LEAFW_MAXPOP1, BPW,1); + GenTable("j__L_LeafV", "cJU_BITSPERSUBEXPL", 4, cJU_BITSPERSUBEXPL, 0,0); +#endif // 32 BIT + +#ifdef JU_64BIT +// ================================ 64 bit ================================ + GenTable("j__L_BranchBJP","cJU_BITSPERSUBEXPB",16, cJU_BITSPERSUBEXPB, 0,0); + + GenTable("j__L_Leaf1", "cJL_LEAF1_MAXPOP1", 1, cJL_LEAF1_MAXPOP1, BPW,0); + GenTable("j__L_Leaf2", "cJL_LEAF2_MAXPOP1", 2, cJL_LEAF2_MAXPOP1, BPW,0); + GenTable("j__L_Leaf3", "cJL_LEAF3_MAXPOP1", 3, cJL_LEAF3_MAXPOP1, BPW,0); + GenTable("j__L_Leaf4", "cJL_LEAF4_MAXPOP1", 4, cJL_LEAF4_MAXPOP1, BPW,0); + GenTable("j__L_Leaf5", "cJL_LEAF5_MAXPOP1", 5, cJL_LEAF5_MAXPOP1, BPW,0); + GenTable("j__L_Leaf6", "cJL_LEAF6_MAXPOP1", 6, cJL_LEAF6_MAXPOP1, BPW,0); + GenTable("j__L_Leaf7", "cJL_LEAF7_MAXPOP1", 7, cJL_LEAF7_MAXPOP1, BPW,0); + GenTable("j__L_LeafW", "cJL_LEAFW_MAXPOP1", 8, cJL_LEAFW_MAXPOP1, BPW,1); + GenTable("j__L_LeafV", "cJU_BITSPERSUBEXPL", 8, cJU_BITSPERSUBEXPL, 0,0); +#endif // 64 BIT + +#endif // JUDYL + fclose(fd); + + return(0); + +} // main() diff --git a/feeds/p4/libjudy/src/src/JudyCommon/Makefile.am b/feeds/p4/libjudy/src/src/JudyCommon/Makefile.am new file mode 100644 index 000000000..fae0e67c3 --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudyCommon/Makefile.am @@ -0,0 +1,8 @@ +INCLUDES = -I. -I.. +AM_CFLAGS = @CFLAGS@ @WARN_CFLAGS@ + +noinst_LTLIBRARIES = libJudyMalloc.la + +libJudyMalloc_la_SOURCES = JudyMalloc.c + +DISTCLEANFILES = .deps Makefile diff --git a/feeds/p4/libjudy/src/src/JudyCommon/README b/feeds/p4/libjudy/src/src/JudyCommon/README new file mode 100644 index 000000000..b1d4300d1 --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudyCommon/README @@ -0,0 +1,66 @@ +# @(#) $Revision: 4.24 $ $Source: /judy/src/JudyCommon/README $ +# +# This tree contains sources for Judy common files. These include shared +# header files, ifdef'd common source files for Judy1/JudyL functions, and +# shared utility functions. + + +# SHARED HEADER FILES: + +JudyPrivate.h global private header file for all Judy internal + sources + +JudyPrivateBranch.h global private header file for all Judy internal + sources, specifically for branch-related + declarations + +JudyPrivate1L.h global private header file for Judy internal + sources that generate both Judy1 and JudyL + object files, via -DJUDY1 or -DJUDYL, using + common names for JP Types, plus some other + generic declarations too + + +# IFDEF'D COMMON SOURCE FILES FOR JUDY1/JUDYL FUNCTIONS: +# +# See Judy(3C) manual entry about these sources for exported functions. + +JudyGet.c common code for Judy1Test() and JudyLGet() +JudyIns.c common code for Judy1Set() and JudyLIns() +JudyDel.c common code for Judy1Unset() and JudyLDel() +JudyFirst.c common code for Judy1 and JudyL +JudyPrevNext.c common code for Judy1, JudyL; Judy*Prev(), Judy*Next() +JudyPrevNextEmpty.c common code for Judy1, JudyL; Judy*PrevEmpty(), + Judy*NextEmpty() +JudyCount.c common code for Judy1 and JudyL +JudyByCount.c common code for Judy1 and JudyL +JudyFreeArray.c common code for Judy1 and JudyL +JudyMemUsed.c common code for Judy1 and JudyL +JudyMemActive.c common code for Judy1 and JudyL + +JudyInsArray.c common code for Judy1 and JudyL + + +# SHARED UTILITY FUNCTIONS: + +JudyMalloc.c source file + +JudyTables.c static definitions of translation tables; a main + program is #ifdef-embedded to generate these tables + +# Common code for Judy1 and JudyL that is compiled twice with -DJUDY1 or +# -DJUDYL: + +JudyInsertBranch.c insert a linear branch between a branch and a leaf +JudyCreateBranch.c create and copy all types of branches + +JudyCascade.c handles overflow insertion of an Index, including + common Decode bytes and branch creation + +JudyDecascade.c handles underflow deletion of an Index, including + common Decode bytes and branch deletion + +JudyMallocIF.c a Judy malloc/free interface, for statistics and + debugging + +JudyPrintJP.c debug/trace code #included in other *.c files diff --git a/feeds/p4/libjudy/src/src/JudyHS/JudyHS.c b/feeds/p4/libjudy/src/src/JudyHS/JudyHS.c new file mode 100644 index 000000000..21191babc --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudyHS/JudyHS.c @@ -0,0 +1,771 @@ +// @(#) $Revision: 4.1 $ $Source: /judy/src/JudyHS/JudyHS.c +//======================================================================= +// Author Douglas L. Baskins, Dec 2003. +// Permission to use this code is freely granted, provided that this +// statement is retained. +// email - doug@sourcejudy.com -or- dougbaskins@yahoo.com +//======================================================================= + +#include // for memcmp(), memcpy() + +#include // for JudyL* routines/macros + +/* + This routine is a very fast "string" version of an ADT that stores + (JudyHSIns()), retrieves (JudyHSGet()), deletes (JudyHSDel()) and + frees the entire ADT (JudyHSFreeArray()) strings. It uses the "Judy + arrays" JudyL() API as the main workhorse. The length of the string + is included in the calling parameters so that strings with embedded + \0s can be used. The string lengths can be from 0 bytes to whatever + malloc() can handle (~2GB). + + Compile: + + cc -O JudyHS.c -c needs to link with -lJudy (libJudy.a) + + Note: in gcc version 3.3.1, -O2 generates faster code than -O + Note: in gcc version 3.3.2, -O3 generates faster code than -O2 + + NOTES: + +1) There may be some performance issues with 64 bit machines, because I + have not characterized that it yet. + +2) It appears that a modern CPU (>2Ghz) that the instruction times are + much faster that a RAM access, so building up a word from bytes takes + no longer that a whole word access. I am taking advantage of this to + make this code endian neutral. A side effect of this is strings do + not need to be aligned, nor tested to be on to a word boundry. In + older and in slow (RISC) machines, this may be a performance issue. + I have given up trying to optimize for machines that have very slow + mpy, mod, variable shifts and call returns. + +3) JudyHS is very scalable from 1 string to billions (with enough RAM). + The memory usage is also scales with population. I have attempted to + combine the best characteristics of JudyL arrays with Hashing methods + and well designed modern processors (such as the 1.3Ghz Intel + Centrino this is being written on). + + HOW JudyHS WORKS: ( 4[8] means 4 bytes in 32 bit machine and 8 in 64) + + A) A JudyL array is used to separate strings of equal lengths into + their own structures (a different hash table is used for each length + of string). The additional time overhead is very near zero because + of the CPU cache. The space efficiency is improved because the + length need not be stored with the string (ls_t). The "JLHash" ADT + in the test program "StringCompare" is verification of both these + assumptions. + + B) A 32 bit hash value is produced from the string. Many thanks to + the Internet and the author (Bob Jenkins) for coming up with a very + good and fast universal string hash. Next the 32 bit hash number is + used as an Index to another JudyL array. Notice that one (1) JudyL + array is used as a hash table per each string length. If there are + no hash collisions (normally) then the string is copied to a + structure (ls_t) along with room for storing a Value. A flag is + added to the pointer to note it is pointing to a ls_t structure. + Since the lengths of the strings are the same, there is no need to + stored length of string in the ls_t structure. This saves about a + word per string of memory. + + C) When there is a hashing collision (very rare), a JudyL array is + used to decode the next 4[8] bytes of the string. That is, the next + 4[8] bytes of the string are used as the Index. This process is + repeated until the remaining string is unique. The remaining string + (if any) is stored in a (now smaller) ls_t structure. If the + remaining string is less or equal to 4[8] bytes, then the ls_t + structure is not needed and the Value area in the JudyL array is + used. A compile option -DDONOTUSEHASH is available to test this + structure without using hashing (only the JudyL tree is used). This + is equivalent to having all strings hashed to the same bucket. The + speed is still better than all other tree based ADTs I have tested. + An added benefit of this is a very fast "hash collision" resolving. + It could foil hackers that exploit the slow synonym (linked-list) + collision handling property used with most hashing algorithms. If + this is not a necessary property, then a simpler ADT "JLHash" that is + documented the the test program "StringCompare.c" may be used with a + little loss of memory efficiency (because it includes the string + length with the ls_t structure). JudyHS was written to be the + fastest, very scalable, memory efficient, general purpose string ADT + possible. (However, I would like to eat those words someday). (dlb) + +*/ + +#ifdef EXAMPLE_CODE +#include +#include +#include + +#include + +//#include "JudyHS.h" // for Judy.h without JudyHS*() + +// By Doug Baskins Apr 2004 - for JudyHS man page + +#define MAXLINE 1000000 /* max length of line */ +char Index[MAXLINE]; // string to check + +int // Usage: CheckDupLines < file +main() +{ + Pvoid_t PJArray = (PWord_t)NULL; // Judy array. + PWord_t PValue; // ^ Judy array element. + Word_t Bytes; // size of JudyHS array. + Word_t LineNumb = 0; // current line number + Word_t Dups = 0; // number of duplicate lines + + while (fgets(Index, MAXLINE, stdin) != (char *)NULL) + { + LineNumb++; // line number + +// store string into array + JHSI(PValue, PJArray, Index, strlen(Index)); + if (*PValue) // check if duplicate + { + Dups++; // count duplicates + printf("Duplicate lines %lu:%lu:%s", *PValue, LineNumb, Index); + } + else + { + *PValue = LineNumb; // store Line number + } + } + printf("%lu Duplicates, free JudyHS array of %lu Lines\n", + Dups, LineNumb - Dups); + JHSFA(Bytes, PJArray); // free array + printf("The JudyHS array allocated %lu bytes of memory\n", Bytes); + return (0); +} +#endif // EXAMPLE_CODE + +// Note: Use JLAP_INVALID, which is non-zero, to mark pointers to a ls_t +// This makes it compatable with previous versions of JudyL() + +#define IS_PLS(PLS) (((Word_t) (PLS)) & JLAP_INVALID) +#define CLEAR_PLS(PLS) (((Word_t) (PLS)) & (~JLAP_INVALID)) +#define SET_PLS(PLS) (((Word_t) (PLS)) | JLAP_INVALID) + +#define WORDSIZE (sizeof(Word_t)) + +// this is the struct used for "leaf" strings. Note that +// the Value is followed by a "variable" length ls_String array. +// +typedef struct L_EAFSTRING +{ + Word_t ls_Value; // Value area (cannot change size) + uint8_t ls_String[WORDSIZE]; // to fill out to a Word_t size +} ls_t , *Pls_t; + +#define LS_STRUCTOVD (sizeof(ls_t) - WORDSIZE) + +// Calculate size of ls_t including the string of length of LEN. +// +#define LS_WORDLEN(LEN) (((LEN) + LS_STRUCTOVD + WORDSIZE - 1) / WORDSIZE) + +// Copy from 0..4[8] bytes from string to a Word_t +// NOTE: the copy in in little-endian order to take advantage of improved +// memory efficiency of JudyLIns() with smaller numbers +// +#define COPYSTRING4toWORD(WORD,STR,LEN) \ +{ \ + WORD = 0; \ + switch(LEN) \ + { \ + default: /* four and greater */ \ + case 4: \ + WORD += (Word_t)(((uint8_t *)(STR))[3] << 24); \ + case 3: \ + WORD += (Word_t)(((uint8_t *)(STR))[2] << 16); \ + case 2: \ + WORD += (Word_t)(((uint8_t *)(STR))[1] << 8); \ + case 1: \ + WORD += (Word_t)(((uint8_t *)(STR))[0]); \ + case 0: break; \ + } \ +} + +#ifdef JU_64BIT + +// copy from 0..8 bytes from string to Word_t +// +#define COPYSTRING8toWORD(WORD,STR,LEN) \ +{ \ + WORD = 0UL; \ + switch(LEN) \ + { \ + default: /* eight and greater */ \ + case 8: \ + WORD += ((Word_t)((uint8_t *)(STR))[7] << 56); \ + case 7: \ + WORD += ((Word_t)((uint8_t *)(STR))[6] << 48); \ + case 6: \ + WORD += ((Word_t)((uint8_t *)(STR))[5] << 40); \ + case 5: \ + WORD += ((Word_t)((uint8_t *)(STR))[4] << 32); \ + case 4: \ + WORD += ((Word_t)((uint8_t *)(STR))[3] << 24); \ + case 3: \ + WORD += ((Word_t)((uint8_t *)(STR))[2] << 16); \ + case 2: \ + WORD += ((Word_t)((uint8_t *)(STR))[1] << 8); \ + case 1: \ + WORD += ((Word_t)((uint8_t *)(STR))[0]); \ + case 0: break; \ + } \ +} + +#define COPYSTRINGtoWORD COPYSTRING8toWORD + +#else // JU_32BIT + +#define COPYSTRINGtoWORD COPYSTRING4toWORD + +#endif // JU_32BIT + +// set JError_t locally + +#define JU_SET_ERRNO(PJERROR, JERRNO) \ +{ \ + if (PJERROR != (PJError_t) NULL) \ + { \ + if (JERRNO) \ + JU_ERRNO(PJError) = (JERRNO); \ + JU_ERRID(PJERROR) = __LINE__; \ + } \ +} + +//======================================================================= +// This routine must hash string to 24..32 bits. The "goodness" of +// the hash is not as important as its speed. +//======================================================================= + +// hash to no more than 32 bits + +// extern Word_t gHmask; for hash bits experiments + +#define JUDYHASHSTR(HVALUE,STRING,LENGTH) \ +{ \ + uint8_t *p_ = (uint8_t *)(STRING); \ + uint8_t *q_ = p_ + (LENGTH); \ + uint32_t c_ = 0; \ + for (; p_ != q_; ++p_) \ + { \ + c_ = (c_ * 31) + *p_; \ + } \ +/* c_ &= gHmask; see above */ \ + (HVALUE) = c_; \ +} + +// Find String of Len in JudyHS structure, return pointer to associated Value + +PPvoid_t +JudyHSGet(Pcvoid_t PArray, // pointer (^) to structure + void * Str, // pointer to string + Word_t Len // length of string + ) +{ + uint8_t *String = (uint8_t *)Str; + PPvoid_t PPValue; // pointer to Value + Word_t Index; // 4[8] bytes of String + + JLG(PPValue, PArray, Len); // find hash table for strings of Len + if (PPValue == (PPvoid_t) NULL) + return ((PPvoid_t) NULL); // no strings of this Len + +// check for caller error (null pointer) +// + if ((String == (void *) NULL) && (Len != 0)) + return ((PPvoid_t) NULL); // avoid null-pointer dereference + +#ifndef DONOTUSEHASH + if (Len > WORDSIZE) // Hash table not necessary with short + { + uint32_t HValue; // hash of input string + JUDYHASHSTR(HValue, String, Len); // hash to no more than 32 bits + JLG(PPValue, *PPValue, (Word_t)HValue); // get ^ to hash bucket + if (PPValue == (PPvoid_t) NULL) + return ((PPvoid_t) NULL); // no entry in Hash table + } +#endif // DONOTUSEHASH + +/* + Each JudyL array decodes 4[8] bytes of the string. Since the hash + collisions occur very infrequently, the performance is not important. + However, even if the Hash code is not used this method still is + significantly faster than common tree methods (AVL, Red-Black, Splay, + b-tree, etc..). You can compare it yourself with #define DONOTUSEHASH + 1 or putting -DDONOTUSEHASH in the cc line. Use the "StringCompare.c" + code to compare (9Dec2003 dlb). +*/ + while (Len > WORDSIZE) // traverse tree of JudyL arrays + { + if (IS_PLS(*PPValue)) // ^ to JudyL array or ls_t struct? + { + Pls_t Pls; // ls_t struct, termination of tree + Pls = (Pls_t) CLEAR_PLS(*PPValue); // remove flag from ^ + +// if remaining string matches, return ^ to Value, else NULL + + if (memcmp(String, Pls->ls_String, Len) == 0) + return ((PPvoid_t) (&(Pls->ls_Value))); + else + return ((PPvoid_t) NULL); // string does not match + } + else + { + COPYSTRINGtoWORD(Index, String, WORDSIZE); + + JLG(PPValue, *PPValue, Index); // decode next 4[8] bytes + if (PPValue == (PPvoid_t) NULL) // if NULL array, bail out + return ((PPvoid_t) NULL); // string does not match + + String += WORDSIZE; // advance + Len -= WORDSIZE; + } + } + +// Get remaining 1..4[8] bytes left in string + + COPYSTRINGtoWORD(Index, String, Len); + JLG(PPValue, *PPValue, Index); // decode last 1-4[8] bytes + return (PPValue); +} + +// Add string to a tree of JudyL arrays (all lengths must be same) + +static PPvoid_t +insStrJudyLTree(uint8_t * String, // string to add to tree of JudyL arrays + Word_t Len, // length of string + PPvoid_t PPValue, // pointer to root pointer + PJError_t PJError // for returning error info + ) +{ + Word_t Index; // next 4[8] bytes of String + + while (Len > WORDSIZE) // add to JudyL tree + { +// CASE 1, pointer is to a NULL, make a new ls_t leaf + + if (*PPValue == (Pvoid_t)NULL) + { + Pls_t Pls; // memory for a ls_t + Pls = (Pls_t) JudyMalloc(LS_WORDLEN(Len)); + if (Pls == NULL) + { + JU_SET_ERRNO(PJError, JU_ERRNO_NOMEM); + return (PPJERR); + } + Pls->ls_Value = 0; // clear Value word + memcpy(Pls->ls_String, String, Len); // copy to new struct + *PPValue = (Pvoid_t)SET_PLS(Pls); // mark pointer + return ((PPvoid_t) (&Pls->ls_Value)); // return ^ to Value + } // no exit here +// CASE 2: is a ls_t, free (and shorten), then decode into JudyL tree + + if (IS_PLS(*PPValue)) // pointer to a ls_t? (leaf) + { + Pls_t Pls; // ^ to ls_t + uint8_t *String0; // ^ to string in ls_t + Word_t Index0; // 4[8] bytes in string + Word_t FreeLen; // length of ls_t + PPvoid_t PPsplit; + + FreeLen = LS_WORDLEN(Len); // length of ls_t + + Pls = (Pls_t) CLEAR_PLS(*PPValue); // demangle ^ to ls_t + String0 = Pls->ls_String; + if (memcmp(String, String0, Len) == 0) // check if match? + { + return ((PPvoid_t) (&Pls->ls_Value)); // yes, duplicate + } + + *PPValue = NULL; // clear ^ to ls_t and make JudyL + +// This do loop is technically not required, saves multiple JudyFree() +// when storing already sorted strings into structure + + do // decode next 4[8] bytes of string + { // with a JudyL array +// Note: string0 is always aligned + + COPYSTRINGtoWORD(Index0, String0, WORDSIZE); + String0 += WORDSIZE; + COPYSTRINGtoWORD(Index, String, WORDSIZE); + String += WORDSIZE; + Len -= WORDSIZE; + PPsplit = PPValue; // save for split below + PPValue = JudyLIns(PPValue, Index0, PJError); + if (PPValue == PPJERR) + { + JU_SET_ERRNO(PJError, 0); + return (PPJERR); + } + + } while ((Index0 == Index) && (Len > WORDSIZE)); + +// finish storing remainder of string that was in the ls_t + + PPValue = insStrJudyLTree(String0, Len, PPValue, PJError); + if (PPValue == PPJERR) + { + return (PPJERR); + } +// copy old Value to Value in new struct + + *(PWord_t)PPValue = Pls->ls_Value; + +// free the string buffer (ls_t) + + JudyFree((Pvoid_t)Pls, FreeLen); + PPValue = JudyLIns(PPsplit, Index, PJError); + if (PPValue == PPJERR) + { + JU_SET_ERRNO(PJError, 0); + return (PPValue); + } + +// finish remainder of newly inserted string + + PPValue = insStrJudyLTree(String, Len, PPValue, PJError); + return (PPValue); + } // no exit here +// CASE 3, more JudyL arrays, decode to next tree + + COPYSTRINGtoWORD(Index, String, WORDSIZE); + Len -= WORDSIZE; + String += WORDSIZE; + + PPValue = JudyLIns(PPValue, Index, PJError); // next 4[8] bytes + if (PPValue == PPJERR) + { + JU_SET_ERRNO(PJError, 0); + return (PPValue); + } + } +// this is done outside of loop so "Len" can be an unsigned number + + COPYSTRINGtoWORD(Index, String, Len); + PPValue = JudyLIns(PPValue, Index, PJError); // remaining 4[8] bytes + + return (PPValue); +} + + +// Insert string to JudyHS structure, return pointer to associated Value + +PPvoid_t +JudyHSIns(PPvoid_t PPArray, // ^ to JudyHashArray name + void * Str, // pointer to string + Word_t Len, // length of string + PJError_t PJError // optional, for returning error info + ) +{ + uint8_t * String = (uint8_t *)Str; + PPvoid_t PPValue; + +// string can only be NULL if Len is 0. + + if ((String == (uint8_t *) NULL) && (Len != 0UL)) + { + JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX); + return (PPJERR); + } + JLG(PPValue, *PPArray, Len); // JudyL hash table for strings of Len + if (PPValue == (PPvoid_t) NULL) // make new if missing, (very rare) + { + PPValue = JudyLIns(PPArray, Len, PJError); + if (PPValue == PPJERR) + { + JU_SET_ERRNO(PJError, 0); + return (PPJERR); + } + } +#ifndef DONOTUSEHASH + if (Len > WORDSIZE) + { + uint32_t HValue; // hash of input string + JUDYHASHSTR(HValue, String, Len); // hash to no more than 32 bits + PPValue = JudyLIns(PPValue, (Word_t)HValue, PJError); + if (PPValue == PPJERR) + { + JU_SET_ERRNO(PJError, 0); + return (PPJERR); + } + } +#endif // DONOTUSEHASH + + PPValue = insStrJudyLTree(String, Len, PPValue, PJError); // add string + return (PPValue); // ^ to Value +} + +// Delete string from tree of JudyL arrays (all Lens must be same) + +static int +delStrJudyLTree(uint8_t * String, // delete from tree of JudyL arrays + Word_t Len, // length of string + PPvoid_t PPValue, // ^ to hash bucket + PJError_t PJError // for returning error info + ) +{ + PPvoid_t PPValueN; // next pointer + Word_t Index; + int Ret; // -1=failed, 1=success, 2=quit del + + if (IS_PLS(*PPValue)) // is pointer to ls_t? + { + Pls_t Pls; + Pls = (Pls_t) CLEAR_PLS(*PPValue); // demangle pointer + JudyFree((Pvoid_t)Pls, LS_WORDLEN(Len)); // free the ls_t + + *PPValue = (Pvoid_t)NULL; // clean pointer + return (1); // successfully deleted + } + + if (Len > WORDSIZE) // delete from JudyL tree, not leaf + { + COPYSTRINGtoWORD(Index, String, WORDSIZE); // get Index + JLG(PPValueN, *PPValue, Index); // get pointer to next JudyL array + + String += WORDSIZE; // advance to next 4[8] bytes + Len -= WORDSIZE; + + Ret = delStrJudyLTree(String, Len, PPValueN, PJError); + if (Ret != 1) return(Ret); + + if (*PPValueN == (PPvoid_t) NULL) + { +// delete JudyL element from tree + + Ret = JudyLDel(PPValue, Index, PJError); + } + } + else + { + COPYSTRINGtoWORD(Index, String, Len); // get leaf element + +// delete last 1-4[8] bytes from leaf element + + Ret = JudyLDel(PPValue, Index, PJError); + } + return (Ret); +} + +// Delete string from JHS structure + +int +JudyHSDel(PPvoid_t PPArray, // ^ to JudyHashArray struct + void * Str, // pointer to string + Word_t Len, // length of string + PJError_t PJError // optional, for returning error info + ) +{ + uint8_t * String = (uint8_t *)Str; + PPvoid_t PPBucket, PPHtble; + int Ret; // return bool from Delete routine +#ifndef DONOTUSEHASH + uint32_t HValue = 0; // hash value of input string +#endif // DONOTUSEHASH + + if (PPArray == NULL) + return (0); // no pointer, return not found + +// This is a little slower than optimum method, but not much in new CPU +// Verify that string is in the structure -- simplifies future assumptions + + if (JudyHSGet(*PPArray, String, Len) == (PPvoid_t) NULL) + return (0); // string not found, return + +// string is in structure, so testing for absence is not necessary + + JLG(PPHtble, *PPArray, Len); // JudyL hash table for strings of Len + +#ifdef DONOTUSEHASH + PPBucket = PPHtble; // simulate below code +#else // USEHASH + if (Len > WORDSIZE) + { + JUDYHASHSTR(HValue, String, Len); // hash to no more than 32 bits + +// get pointer to hash bucket + + JLG(PPBucket, *PPHtble, (Word_t)HValue); + } + else + { + PPBucket = PPHtble; // no bucket to JLGet + } +#endif // USEHASH + +// delete from JudyL tree +// + Ret = delStrJudyLTree(String, Len, PPBucket, PJError); + if (Ret != 1) + { + JU_SET_ERRNO(PJError, 0); + return(-1); + } +// handle case of missing JudyL array from hash table and length table + + if (*PPBucket == (Pvoid_t)NULL) // if JudyL tree gone + { +#ifndef DONOTUSEHASH + if (Len > WORDSIZE) + { +// delete entry in Hash table + + Ret = JudyLDel(PPHtble, (Word_t)HValue, PJError); + if (Ret != 1) + { + JU_SET_ERRNO(PJError, 0); + return(-1); + } + } +#endif // USEHASH + if (*PPHtble == (PPvoid_t) NULL) // if Hash table gone + { +// delete entry from the String length table + + Ret = JudyLDel(PPArray, Len, PJError); + if (Ret != 1) + { + JU_SET_ERRNO(PJError, 0); + return(-1); + } + } + } + return (1); // success +} + +static Word_t +delJudyLTree(PPvoid_t PPValue, // ^ to JudyL root pointer + Word_t Len, // length of string + PJError_t PJError) // for returning error info +{ + Word_t bytes_freed = 0; // bytes freed at point + Word_t bytes_total = 0; // accumulated bytes freed + PPvoid_t PPValueN; + +// Pointer is to another tree of JudyL arrays or ls_t struct + + if (Len > WORDSIZE) // more depth to tree + { + Word_t NEntry; + +// Pointer is to a ls_t struct + + if (IS_PLS(*PPValue)) + { + Pls_t Pls; + Word_t freewords; + + freewords = LS_WORDLEN(Len); // calculate length + Pls = (Pls_t)CLEAR_PLS(*PPValue); // demangle pointer + +// *PPValue = (Pvoid_t)NULL; // clean pointer + JudyFree((Pvoid_t)Pls, freewords); // free the ls_t + + return(freewords * WORDSIZE); + } +// else +// Walk all the entrys in the JudyL array + + NEntry = 0; // start at beginning + for (PPValueN = JudyLFirst(*PPValue, &NEntry, PJError); + (PPValueN != (PPvoid_t) NULL) && (PPValueN != PPJERR); + PPValueN = JudyLNext(*PPValue, &NEntry, PJError)) + { +// recurse to the next level in the tree of arrays + + bytes_freed = delJudyLTree(PPValueN, Len - WORDSIZE, PJError); + if (bytes_freed == JERR) return(JERR); + bytes_total += bytes_freed; + } + if (PPValueN == PPJERR) return(JERR); + +// now free this JudyL array + + bytes_freed = JudyLFreeArray(PPValue, PJError); + if (bytes_freed == JERR) return(JERR); + bytes_total += bytes_freed; + + return(bytes_total); // return amount freed + } +// else + +// Pointer to simple JudyL array + + bytes_freed = JudyLFreeArray(PPValue, PJError); + + return(bytes_freed); +} + + +Word_t // bytes freed +JudyHSFreeArray(PPvoid_t PPArray, // ^ to JudyHashArray struct + PJError_t PJError // optional, for returning error info + ) +{ + Word_t Len; // start at beginning + Word_t bytes_freed; // bytes freed at this level. + Word_t bytes_total; // bytes total at all levels. + PPvoid_t PPHtble; + + if (PPArray == NULL) + return (0); // no pointer, return none + +// Walk the string length table for subsidary hash structs +// NOTE: This is necessary to determine the depth of the tree + + bytes_freed = 0; + bytes_total = 0; + Len = 0; // walk to length table + + for (PPHtble = JudyLFirst(*PPArray, &Len, PJError); + (PPHtble != (PPvoid_t) NULL) && (PPHtble != PPJERR); + PPHtble = JudyLNext(*PPArray, &Len, PJError)) + { + PPvoid_t PPValueH; + +#ifndef DONOTUSEHASH + if (Len > WORDSIZE) + { + Word_t HEntry = 0; // walk the hash tables + + for (PPValueH = JudyLFirst(*PPHtble, &HEntry, PJError); + (PPValueH != (PPvoid_t) NULL) && (PPValueH != PPJERR); + PPValueH = JudyLNext(*PPHtble, &HEntry, PJError)) + { + bytes_freed = delJudyLTree(PPValueH, Len, PJError); + if (bytes_freed == JERR) return(JERR); + bytes_total += bytes_freed; + } + + if (PPValueH == PPJERR) return(JERR); + +// free the Hash table for this length of string + + bytes_freed = JudyLFreeArray(PPHtble, PJError); + if (bytes_freed == JERR) return(JERR); + bytes_total += bytes_freed; + } + else +#endif // DONOTUSEHASH + { + PPValueH = PPHtble; // simulate hash table + + bytes_freed = delJudyLTree(PPValueH, Len, PJError); + if (bytes_freed == JERR) return(JERR); + bytes_total += bytes_freed; + } + } + if (PPHtble == PPJERR) return(JERR); + +// free the length table + + bytes_freed = JudyLFreeArray(PPArray, PJError); + if (bytes_freed == JERR) return(JERR); + + bytes_total += bytes_freed; + + return(bytes_total); // return bytes freed +} diff --git a/feeds/p4/libjudy/src/src/JudyHS/JudyHS.h b/feeds/p4/libjudy/src/src/JudyHS/JudyHS.h new file mode 100644 index 000000000..b40350164 --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudyHS/JudyHS.h @@ -0,0 +1,35 @@ +// **************************************************************************** +// Quick and dirty header file for use with old Judy.h without JudyHS defs +// May 2004 (dlb) - No copyright or license -- it is free period. + +#include + +// **************************************************************************** +// JUDYHSL MACROS: + +#define JHSI(PV, PArray, PIndex, Count) \ + J_2P(PV, (&(PArray)), PIndex, Count, JudyHSIns, "JudyHSIns") +#define JHSG(PV, PArray, PIndex, Count) \ + (PV) = (Pvoid_t) JudyHSGet(PArray, PIndex, Count) +#define JHSD(Rc, PArray, PIndex, Count) \ + J_2I(Rc, (&(PArray)), PIndex, Count, JudyHSDel, "JudyHSDel") +#define JHSFA(Rc, PArray) \ + J_0I(Rc, (&(PArray)), JudyHSFreeArray, "JudyHSFreeArray") + +// **************************************************************************** +// JUDY memory interface to malloc() FUNCTIONS: + +extern Word_t JudyMalloc(Word_t); // words reqd => words allocd. +extern Word_t JudyMallocVirtual(Word_t); // words reqd => words allocd. +extern void JudyFree(Pvoid_t, Word_t); // block to free and its size in words. +extern void JudyFreeVirtual(Pvoid_t, Word_t); // block to free and its size in words. + +// **************************************************************************** +// JUDYHS FUNCTIONS: + +extern PPvoid_t JudyHSGet( Pcvoid_t, void *, Word_t); +extern PPvoid_t JudyHSIns( PPvoid_t, void *, Word_t, P_JE); +extern int JudyHSDel( PPvoid_t, void *, Word_t, P_JE); +extern Word_t JudyHSFreeArray( PPvoid_t, P_JE); + +extern uint32_t JudyHashStr( void *, Word_t); diff --git a/feeds/p4/libjudy/src/src/JudyHS/Makefile.am b/feeds/p4/libjudy/src/src/JudyHS/Makefile.am new file mode 100644 index 000000000..44a278ebc --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudyHS/Makefile.am @@ -0,0 +1,8 @@ +INCLUDES = -I. -I.. -I../JudyCommon/ +AM_CFLAGS = @CFLAGS@ @WARN_CFLAGS@ + +noinst_LTLIBRARIES = libJudyHS.la + +libJudyHS_la_SOURCES = JudyHS.c + +DISTCLEANFILES = .deps Makefile diff --git a/feeds/p4/libjudy/src/src/JudyHS/README b/feeds/p4/libjudy/src/src/JudyHS/README new file mode 100644 index 000000000..93d7d070c --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudyHS/README @@ -0,0 +1,10 @@ +# @(#) $Revision: 4.22 $ $Source: /judy/src/JudyHS/README $ + +# This tree contains sources for the JudyHS*() functions. +# +# Note: At one time, all of the Judy sources were split between Judy1/ and +# JudyL/ variants, but now most of them are merged in JudyCommon/ and this +# directory is vestigal. + +JudyHS.h header for using JudyHS.c with older versions of Judy.h +JudyHS.c source of JudyHS functions diff --git a/feeds/p4/libjudy/src/src/JudyL/JudyL.h b/feeds/p4/libjudy/src/src/JudyL/JudyL.h new file mode 100644 index 000000000..d901969d6 --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudyL/JudyL.h @@ -0,0 +1,505 @@ +#ifndef _JUDYL_INCLUDED +#define _JUDYL_INCLUDED +// _________________ +// +// Copyright (C) 2000 - 2002 Hewlett-Packard Company +// +// This program is free software; you can redistribute it and/or modify it +// under the term of the GNU Lesser 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 Lesser General Public License +// for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// _________________ + +// @(#) $Revision: 4.41 $ $Source: /judy/src/JudyL/JudyL.h $ + +// **************************************************************************** +// JUDYL -- SMALL/LARGE AND/OR CLUSTERED/SPARSE ARRAYS +// +// -by- +// +// Douglas L. Baskins +// doug@sourcejudy.com +// +// Judy arrays are designed to be used instead of arrays. The performance +// suggests the reason why Judy arrays are thought of as arrays, instead of +// trees. They are remarkably memory efficient at all populations. +// Implemented as a hybrid digital tree (but really a state machine, see +// below), Judy arrays feature fast insert/retrievals, fast near neighbor +// searching, and contain a population tree for extremely fast ordinal related +// retrievals. +// +// CONVENTIONS: +// +// - The comments here refer to 32-bit [64-bit] systems. +// +// - BranchL, LeafL refer to linear branches and leaves (small populations), +// except LeafL does not actually appear as such; rather, Leaf1..3 [Leaf1..7] +// is used to represent leaf Index sizes, and LeafW refers to a Leaf with +// full (Long) word Indexes, which is also a type of linear leaf. Note that +// root-level LeafW (Leaf4 [Leaf8]) leaves are called LEAFW. +// +// - BranchB, LeafB1 refer to bitmap branches and leaves (intermediate +// populations). +// +// - BranchU refers to uncompressed branches. An uncompressed branch has 256 +// JPs, some of which could be null. Note: All leaves are compressed (and +// sorted), or else an expanse is full (FullPopu), so there is no LeafU +// equivalent to BranchU. +// +// - "Popu" is short for "Population". +// - "Pop1" refers to actual population (base 1). +// - "Pop0" refers to Pop1 - 1 (base 0), the way populations are stored in data +// structures. +// +// - Branches and Leaves are both named by the number of bytes in their Pop0 +// field. In the case of Leaves, the same number applies to the Index sizes. +// +// - The representation of many numbers as hex is a relatively safe and +// portable way to get desired bitpatterns as unsigned longs. +// +// - Some preprocessors cant handle single apostrophe characters within +// #ifndef code, so here, delete all instead. + + +#include "JudyPrivate.h" // includes Judy.h in turn. +#include "JudyPrivateBranch.h" // support for branches. + + +// **************************************************************************** +// JUDYL ROOT POINTER (JRP) AND JUDYL POINTER (JP) TYPE FIELDS +// **************************************************************************** + +typedef enum // uint8_t -- but C does not support this type of enum. +{ + +// JP NULL TYPES: +// +// There is a series of cJL_JPNULL* Types because each one pre-records a +// different Index Size for when the first Index is inserted in the previously +// null JP. They must start >= 8 (three bits). +// +// Note: These Types must be in sequential order for doing relative +// calculations between them. + + cJL_JPNULL1 = 1, + // Index Size 1[1] byte when 1 Index inserted. + cJL_JPNULL2, // Index Size 2[2] bytes when 1 Index inserted. + cJL_JPNULL3, // Index Size 3[3] bytes when 1 Index inserted. + +#ifndef JU_64BIT +#define cJL_JPNULLMAX cJL_JPNULL3 +#else + cJL_JPNULL4, // Index Size 4[4] bytes when 1 Index inserted. + cJL_JPNULL5, // Index Size 5[5] bytes when 1 Index inserted. + cJL_JPNULL6, // Index Size 6[6] bytes when 1 Index inserted. + cJL_JPNULL7, // Index Size 7[7] bytes when 1 Index inserted. +#define cJL_JPNULLMAX cJL_JPNULL7 +#endif + + +// JP BRANCH TYPES: +// +// Note: There are no state-1 branches; only leaves reside at state 1. + +// Linear branches: +// +// Note: These Types must be in sequential order for doing relative +// calculations between them. + + cJL_JPBRANCH_L2, // 2[2] bytes Pop0, 1[5] bytes Dcd. + cJL_JPBRANCH_L3, // 3[3] bytes Pop0, 0[4] bytes Dcd. + +#ifdef JU_64BIT + cJL_JPBRANCH_L4, // [4] bytes Pop0, [3] bytes Dcd. + cJL_JPBRANCH_L5, // [5] bytes Pop0, [2] bytes Dcd. + cJL_JPBRANCH_L6, // [6] bytes Pop0, [1] byte Dcd. + cJL_JPBRANCH_L7, // [7] bytes Pop0, [0] bytes Dcd. +#endif + + cJL_JPBRANCH_L, // note: DcdPopO field not used. + +// Bitmap branches: +// +// Note: These Types must be in sequential order for doing relative +// calculations between them. + + cJL_JPBRANCH_B2, // 2[2] bytes Pop0, 1[5] bytes Dcd. + cJL_JPBRANCH_B3, // 3[3] bytes Pop0, 0[4] bytes Dcd. + +#ifdef JU_64BIT + cJL_JPBRANCH_B4, // [4] bytes Pop0, [3] bytes Dcd. + cJL_JPBRANCH_B5, // [5] bytes Pop0, [2] bytes Dcd. + cJL_JPBRANCH_B6, // [6] bytes Pop0, [1] byte Dcd. + cJL_JPBRANCH_B7, // [7] bytes Pop0, [0] bytes Dcd. +#endif + + cJL_JPBRANCH_B, // note: DcdPopO field not used. + +// Uncompressed branches: +// +// Note: These Types must be in sequential order for doing relative +// calculations between them. + + cJL_JPBRANCH_U2, // 2[2] bytes Pop0, 1[5] bytes Dcd. + cJL_JPBRANCH_U3, // 3[3] bytes Pop0, 0[4] bytes Dcd. + +#ifdef JU_64BIT + cJL_JPBRANCH_U4, // [4] bytes Pop0, [3] bytes Dcd. + cJL_JPBRANCH_U5, // [5] bytes Pop0, [2] bytes Dcd. + cJL_JPBRANCH_U6, // [6] bytes Pop0, [1] byte Dcd. + cJL_JPBRANCH_U7, // [7] bytes Pop0, [0] bytes Dcd. +#endif + + cJL_JPBRANCH_U, // note: DcdPopO field not used. + + +// JP LEAF TYPES: + +// Linear leaves: +// +// Note: These Types must be in sequential order for doing relative +// calculations between them. +// +// Note: There is no full-word (4-byte [8-byte]) Index leaf under a JP because +// non-root-state leaves only occur under branches that decode at least one +// byte. Full-word, root-state leaves are under a JRP, not a JP. However, in +// the code a "fake" JP can be created temporarily above a root-state leaf. + + cJL_JPLEAF1, // 1[1] byte Pop0, 2 bytes Dcd. + cJL_JPLEAF2, // 2[2] bytes Pop0, 1[5] bytes Dcd. + cJL_JPLEAF3, // 3[3] bytes Pop0, 0[4] bytes Dcd. + +#ifdef JU_64BIT + cJL_JPLEAF4, // [4] bytes Pop0, [3] bytes Dcd. + cJL_JPLEAF5, // [5] bytes Pop0, [2] bytes Dcd. + cJL_JPLEAF6, // [6] bytes Pop0, [1] byte Dcd. + cJL_JPLEAF7, // [7] bytes Pop0, [0] bytes Dcd. +#endif + +// Bitmap leaf; Index Size == 1: +// +// Note: These are currently only supported at state 1. At other states the +// bitmap would grow from 256 to 256^2, 256^3, ... bits, which would not be +// efficient.. + + cJL_JPLEAF_B1, // 1[1] byte Pop0, 2[6] bytes Dcd. + +// Full population; Index Size == 1 virtual leaf: +// +// Note: JudyL has no cJL_JPFULLPOPU1 equivalent to cJ1_JPFULLPOPU1, because +// in the JudyL case this could result in a values-only leaf of up to 256 words +// (value areas) that would be slow to insert/delete. + + +// JP IMMEDIATES; leaves (Indexes) stored inside a JP: +// +// The second numeric suffix is the Pop1 for each type. As the Index Size +// increases, the maximum possible population decreases. +// +// Note: These Types must be in sequential order in each group (Index Size), +// and the groups in correct order too, for doing relative calculations between +// them. For example, since these Types enumerate the Pop1 values (unlike +// other JP Types where there is a Pop0 value in the JP), the maximum Pop1 for +// each Index Size is computable. +// +// All enums equal or above this point are cJL_JPIMMEDs. + + cJL_JPIMMED_1_01, // Index Size = 1, Pop1 = 1. + cJL_JPIMMED_2_01, // Index Size = 2, Pop1 = 1. + cJL_JPIMMED_3_01, // Index Size = 3, Pop1 = 1. + +#ifdef JU_64BIT + cJL_JPIMMED_4_01, // Index Size = 4, Pop1 = 1. + cJL_JPIMMED_5_01, // Index Size = 5, Pop1 = 1. + cJL_JPIMMED_6_01, // Index Size = 6, Pop1 = 1. + cJL_JPIMMED_7_01, // Index Size = 7, Pop1 = 1. +#endif + + cJL_JPIMMED_1_02, // Index Size = 1, Pop1 = 2. + cJL_JPIMMED_1_03, // Index Size = 1, Pop1 = 3. + +#ifdef JU_64BIT + cJL_JPIMMED_1_04, // Index Size = 1, Pop1 = 4. + cJL_JPIMMED_1_05, // Index Size = 1, Pop1 = 5. + cJL_JPIMMED_1_06, // Index Size = 1, Pop1 = 6. + cJL_JPIMMED_1_07, // Index Size = 1, Pop1 = 7. + + cJL_JPIMMED_2_02, // Index Size = 2, Pop1 = 2. + cJL_JPIMMED_2_03, // Index Size = 2, Pop1 = 3. + + cJL_JPIMMED_3_02, // Index Size = 3, Pop1 = 2. +#endif + +// This special Type is merely a sentinel for doing relative calculations. +// This value should not be used in switch statements (to avoid allocating code +// for it), which is also why it appears at the end of the enum list. + + cJL_JPIMMED_CAP + +} jpL_Type_t; + + +// RELATED VALUES: + +// Index Size (state) for leaf JP, and JP type based on Index Size (state): + +#define JL_LEAFINDEXSIZE(jpType) ((jpType) - cJL_JPLEAF1 + 1) +#define JL_LEAFTYPE(IndexSize) ((IndexSize) + cJL_JPLEAF1 - 1) + + +// MAXIMUM POPULATIONS OF LINEAR LEAVES: + +#ifndef JU_64BIT // 32-bit + +#define J_L_MAXB (sizeof(Word_t) * 64) +#define ALLOCSIZES { 3, 5, 7, 11, 15, 23, 32, 47, 64, TERMINATOR } // in words. +#define cJL_LEAF1_MAXWORDS (32) // max Leaf1 size in words. + +// Note: cJL_LEAF1_MAXPOP1 is chosen such that the index portion is less than +// 32 bytes -- the number of bytes the index takes in a bitmap leaf. + +#define cJL_LEAF1_MAXPOP1 \ + ((cJL_LEAF1_MAXWORDS * cJU_BYTESPERWORD)/(1 + cJU_BYTESPERWORD)) +#define cJL_LEAF2_MAXPOP1 (J_L_MAXB / (2 + cJU_BYTESPERWORD)) +#define cJL_LEAF3_MAXPOP1 (J_L_MAXB / (3 + cJU_BYTESPERWORD)) +#define cJL_LEAFW_MAXPOP1 \ + ((J_L_MAXB - cJU_BYTESPERWORD) / (2 * cJU_BYTESPERWORD)) + +#else // 64-bit + +#define J_L_MAXB (sizeof(Word_t) * 64) +#define ALLOCSIZES { 3, 5, 7, 11, 15, 23, 32, 47, 64, TERMINATOR } // in words. +#define cJL_LEAF1_MAXWORDS (15) // max Leaf1 size in words. + +#define cJL_LEAF1_MAXPOP1 \ + ((cJL_LEAF1_MAXWORDS * cJU_BYTESPERWORD)/(1 + cJU_BYTESPERWORD)) +#define cJL_LEAF2_MAXPOP1 (J_L_MAXB / (2 + cJU_BYTESPERWORD)) +#define cJL_LEAF3_MAXPOP1 (J_L_MAXB / (3 + cJU_BYTESPERWORD)) +#define cJL_LEAF4_MAXPOP1 (J_L_MAXB / (4 + cJU_BYTESPERWORD)) +#define cJL_LEAF5_MAXPOP1 (J_L_MAXB / (5 + cJU_BYTESPERWORD)) +#define cJL_LEAF6_MAXPOP1 (J_L_MAXB / (6 + cJU_BYTESPERWORD)) +#define cJL_LEAF7_MAXPOP1 (J_L_MAXB / (7 + cJU_BYTESPERWORD)) +#define cJL_LEAFW_MAXPOP1 \ + ((J_L_MAXB - cJU_BYTESPERWORD) / (2 * cJU_BYTESPERWORD)) + +#endif // 64-bit + + +// MAXIMUM POPULATIONS OF IMMEDIATE JPs: +// +// These specify the maximum Population of immediate JPs with various Index +// Sizes (== sizes of remaining undecoded Index bits). Since the JP Types enum +// already lists all the immediates in order by state and size, calculate these +// values from it to avoid redundancy. + +#define cJL_IMMED1_MAXPOP1 ((cJU_BYTESPERWORD - 1) / 1) // 3 [7]. +#define cJL_IMMED2_MAXPOP1 ((cJU_BYTESPERWORD - 1) / 2) // 1 [3]. +#define cJL_IMMED3_MAXPOP1 ((cJU_BYTESPERWORD - 1) / 3) // 1 [2]. + +#ifdef JU_64BIT +#define cJL_IMMED4_MAXPOP1 ((cJU_BYTESPERWORD - 1) / 4) // [1]. +#define cJL_IMMED5_MAXPOP1 ((cJU_BYTESPERWORD - 1) / 5) // [1]. +#define cJL_IMMED6_MAXPOP1 ((cJU_BYTESPERWORD - 1) / 6) // [1]. +#define cJL_IMMED7_MAXPOP1 ((cJU_BYTESPERWORD - 1) / 7) // [1]. +#endif + + +// **************************************************************************** +// JUDYL LEAF BITMAP (JLLB) SUPPORT +// **************************************************************************** +// +// Assemble bitmap leaves out of smaller units that put bitmap subexpanses +// close to their associated pointers. Why not just use a bitmap followed by a +// series of pointers? (See 4.27.) Turns out this wastes a cache fill on +// systems with smaller cache lines than the assumed value cJU_WORDSPERCL. + +#define JL_JLB_BITMAP(Pjlb, Subexp) ((Pjlb)->jLlb_jLlbs[Subexp].jLlbs_Bitmap) +#define JL_JLB_PVALUE(Pjlb, Subexp) ((Pjlb)->jLlb_jLlbs[Subexp].jLlbs_PValue) + +typedef struct J__UDYL_LEAF_BITMAP_SUBEXPANSE +{ + BITMAPL_t jLlbs_Bitmap; + Pjv_t jLlbs_PValue; + +} jLlbs_t; + +typedef struct J__UDYL_LEAF_BITMAP +{ + jLlbs_t jLlb_jLlbs[cJU_NUMSUBEXPL]; + +} jLlb_t, * PjLlb_t; + +// Words per bitmap leaf: + +#define cJL_WORDSPERLEAFB1 (sizeof(jLlb_t) / cJU_BYTESPERWORD) + + +// **************************************************************************** +// MEMORY ALLOCATION SUPPORT +// **************************************************************************** + +// ARRAY-GLOBAL INFORMATION: +// +// At the cost of an occasional additional cache fill, this object, which is +// pointed at by a JRP and in turn points to a JP_BRANCH*, carries array-global +// information about a JudyL array that has sufficient population to amortize +// the cost. The jpm_Pop0 field prevents having to add up the total population +// for the array in insert, delete, and count code. The jpm_JP field prevents +// having to build a fake JP for entry to a state machine; however, the +// jp_DcdPopO field in jpm_JP, being one byte too small, is not used. +// +// Note: Struct fields are ordered to keep "hot" data in the first 8 words +// (see left-margin comments) for machines with 8-word cache lines, and to keep +// sub-word fields together for efficient packing. + +typedef struct J_UDYL_POPULATION_AND_MEMORY +{ +/* 1 */ Word_t jpm_Pop0; // total population-1 in array. +/* 2 */ jp_t jpm_JP; // JP to first branch; see above. +/* 4 */ Word_t jpm_LastUPop0; // last jpm_Pop0 when convert to BranchU +/* 7 */ Pjv_t jpm_PValue; // pointer to value to return. +// Note: Field names match PJError_t for convenience in macros: +/* 8 */ char je_Errno; // one of the enums in Judy.h. +/* 8/9 */ int je_ErrID; // often an internal source line number. +/* 9/10 */ Word_t jpm_TotalMemWords; // words allocated in array. +} jLpm_t, *PjLpm_t; + + +// TABLES FOR DETERMINING IF LEAVES HAVE ROOM TO GROW: +// +// These tables indicate if a given memory chunk can support growth of a given +// object into wasted (rounded-up) memory in the chunk. Note: This violates +// the hiddenness of the JudyMalloc code. + +extern const uint8_t j__L_Leaf1PopToWords[cJL_LEAF1_MAXPOP1 + 1]; +extern const uint8_t j__L_Leaf2PopToWords[cJL_LEAF2_MAXPOP1 + 1]; +extern const uint8_t j__L_Leaf3PopToWords[cJL_LEAF3_MAXPOP1 + 1]; +#ifdef JU_64BIT +extern const uint8_t j__L_Leaf4PopToWords[cJL_LEAF4_MAXPOP1 + 1]; +extern const uint8_t j__L_Leaf5PopToWords[cJL_LEAF5_MAXPOP1 + 1]; +extern const uint8_t j__L_Leaf6PopToWords[cJL_LEAF6_MAXPOP1 + 1]; +extern const uint8_t j__L_Leaf7PopToWords[cJL_LEAF7_MAXPOP1 + 1]; +#endif +extern const uint8_t j__L_LeafWPopToWords[cJL_LEAFW_MAXPOP1 + 1]; +extern const uint8_t j__L_LeafVPopToWords[]; + +// These tables indicate where value areas start: + +extern const uint8_t j__L_Leaf1Offset [cJL_LEAF1_MAXPOP1 + 1]; +extern const uint8_t j__L_Leaf2Offset [cJL_LEAF2_MAXPOP1 + 1]; +extern const uint8_t j__L_Leaf3Offset [cJL_LEAF3_MAXPOP1 + 1]; +#ifdef JU_64BIT +extern const uint8_t j__L_Leaf4Offset [cJL_LEAF4_MAXPOP1 + 1]; +extern const uint8_t j__L_Leaf5Offset [cJL_LEAF5_MAXPOP1 + 1]; +extern const uint8_t j__L_Leaf6Offset [cJL_LEAF6_MAXPOP1 + 1]; +extern const uint8_t j__L_Leaf7Offset [cJL_LEAF7_MAXPOP1 + 1]; +#endif +extern const uint8_t j__L_LeafWOffset [cJL_LEAFW_MAXPOP1 + 1]; + +// Also define macros to hide the details in the code using these tables. + +#define JL_LEAF1GROWINPLACE(Pop1) \ + J__U_GROWCK(Pop1, cJL_LEAF1_MAXPOP1, j__L_Leaf1PopToWords) +#define JL_LEAF2GROWINPLACE(Pop1) \ + J__U_GROWCK(Pop1, cJL_LEAF2_MAXPOP1, j__L_Leaf2PopToWords) +#define JL_LEAF3GROWINPLACE(Pop1) \ + J__U_GROWCK(Pop1, cJL_LEAF3_MAXPOP1, j__L_Leaf3PopToWords) +#ifdef JU_64BIT +#define JL_LEAF4GROWINPLACE(Pop1) \ + J__U_GROWCK(Pop1, cJL_LEAF4_MAXPOP1, j__L_Leaf4PopToWords) +#define JL_LEAF5GROWINPLACE(Pop1) \ + J__U_GROWCK(Pop1, cJL_LEAF5_MAXPOP1, j__L_Leaf5PopToWords) +#define JL_LEAF6GROWINPLACE(Pop1) \ + J__U_GROWCK(Pop1, cJL_LEAF6_MAXPOP1, j__L_Leaf6PopToWords) +#define JL_LEAF7GROWINPLACE(Pop1) \ + J__U_GROWCK(Pop1, cJL_LEAF7_MAXPOP1, j__L_Leaf7PopToWords) +#endif +#define JL_LEAFWGROWINPLACE(Pop1) \ + J__U_GROWCK(Pop1, cJL_LEAFW_MAXPOP1, j__L_LeafWPopToWords) +#define JL_LEAFVGROWINPLACE(Pop1) \ + J__U_GROWCK(Pop1, cJU_BITSPERSUBEXPL, j__L_LeafVPopToWords) + +#define JL_LEAF1VALUEAREA(Pjv,Pop1) (((PWord_t)(Pjv)) + j__L_Leaf1Offset[Pop1]) +#define JL_LEAF2VALUEAREA(Pjv,Pop1) (((PWord_t)(Pjv)) + j__L_Leaf2Offset[Pop1]) +#define JL_LEAF3VALUEAREA(Pjv,Pop1) (((PWord_t)(Pjv)) + j__L_Leaf3Offset[Pop1]) +#ifdef JU_64BIT +#define JL_LEAF4VALUEAREA(Pjv,Pop1) (((PWord_t)(Pjv)) + j__L_Leaf4Offset[Pop1]) +#define JL_LEAF5VALUEAREA(Pjv,Pop1) (((PWord_t)(Pjv)) + j__L_Leaf5Offset[Pop1]) +#define JL_LEAF6VALUEAREA(Pjv,Pop1) (((PWord_t)(Pjv)) + j__L_Leaf6Offset[Pop1]) +#define JL_LEAF7VALUEAREA(Pjv,Pop1) (((PWord_t)(Pjv)) + j__L_Leaf7Offset[Pop1]) +#endif +#define JL_LEAFWVALUEAREA(Pjv,Pop1) (((PWord_t)(Pjv)) + j__L_LeafWOffset[Pop1]) + +#define JL_LEAF1POPTOWORDS(Pop1) (j__L_Leaf1PopToWords[Pop1]) +#define JL_LEAF2POPTOWORDS(Pop1) (j__L_Leaf2PopToWords[Pop1]) +#define JL_LEAF3POPTOWORDS(Pop1) (j__L_Leaf3PopToWords[Pop1]) +#ifdef JU_64BIT +#define JL_LEAF4POPTOWORDS(Pop1) (j__L_Leaf4PopToWords[Pop1]) +#define JL_LEAF5POPTOWORDS(Pop1) (j__L_Leaf5PopToWords[Pop1]) +#define JL_LEAF6POPTOWORDS(Pop1) (j__L_Leaf6PopToWords[Pop1]) +#define JL_LEAF7POPTOWORDS(Pop1) (j__L_Leaf7PopToWords[Pop1]) +#endif +#define JL_LEAFWPOPTOWORDS(Pop1) (j__L_LeafWPopToWords[Pop1]) +#define JL_LEAFVPOPTOWORDS(Pop1) (j__L_LeafVPopToWords[Pop1]) + + +// FUNCTIONS TO ALLOCATE OBJECTS: + +PjLpm_t j__udyLAllocJLPM(void); // constant size. + +Pjbl_t j__udyLAllocJBL( PjLpm_t); // constant size. +Pjbb_t j__udyLAllocJBB( PjLpm_t); // constant size. +Pjp_t j__udyLAllocJBBJP(Word_t, PjLpm_t); +Pjbu_t j__udyLAllocJBU( PjLpm_t); // constant size. + +Pjll_t j__udyLAllocJLL1( Word_t, PjLpm_t); +Pjll_t j__udyLAllocJLL2( Word_t, PjLpm_t); +Pjll_t j__udyLAllocJLL3( Word_t, PjLpm_t); + +#ifdef JU_64BIT +Pjll_t j__udyLAllocJLL4( Word_t, PjLpm_t); +Pjll_t j__udyLAllocJLL5( Word_t, PjLpm_t); +Pjll_t j__udyLAllocJLL6( Word_t, PjLpm_t); +Pjll_t j__udyLAllocJLL7( Word_t, PjLpm_t); +#endif + +Pjlw_t j__udyLAllocJLW( Word_t ); // no PjLpm_t needed. +PjLlb_t j__udyLAllocJLB1( PjLpm_t); // constant size. +Pjv_t j__udyLAllocJV( Word_t, PjLpm_t); + + +// FUNCTIONS TO FREE OBJECTS: + +void j__udyLFreeJLPM( PjLpm_t, PjLpm_t); // constant size. + +void j__udyLFreeJBL( Pjbl_t, PjLpm_t); // constant size. +void j__udyLFreeJBB( Pjbb_t, PjLpm_t); // constant size. +void j__udyLFreeJBBJP(Pjp_t, Word_t, PjLpm_t); +void j__udyLFreeJBU( Pjbu_t, PjLpm_t); // constant size. + +void j__udyLFreeJLL1( Pjll_t, Word_t, PjLpm_t); +void j__udyLFreeJLL2( Pjll_t, Word_t, PjLpm_t); +void j__udyLFreeJLL3( Pjll_t, Word_t, PjLpm_t); + +#ifdef JU_64BIT +void j__udyLFreeJLL4( Pjll_t, Word_t, PjLpm_t); +void j__udyLFreeJLL5( Pjll_t, Word_t, PjLpm_t); +void j__udyLFreeJLL6( Pjll_t, Word_t, PjLpm_t); +void j__udyLFreeJLL7( Pjll_t, Word_t, PjLpm_t); +#endif + +void j__udyLFreeJLW( Pjlw_t, Word_t, PjLpm_t); +void j__udyLFreeJLB1( PjLlb_t, PjLpm_t); // constant size. +void j__udyLFreeJV( Pjv_t, Word_t, PjLpm_t); +void j__udyLFreeSM( Pjp_t, PjLpm_t); // everything below Pjp. + +#endif // ! _JUDYL_INCLUDED diff --git a/feeds/p4/libjudy/src/src/JudyL/Makefile.am b/feeds/p4/libjudy/src/src/JudyL/Makefile.am new file mode 100644 index 000000000..715cd831e --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudyL/Makefile.am @@ -0,0 +1,114 @@ +INCLUDES = -I. -I.. -I../JudyCommon/ +AM_CFLAGS = -DJUDYL @WARN_CFLAGS@ + +noinst_LTLIBRARIES = libJudyL.la libnext.la libprev.la libcount.la libinline.la + +libJudyL_la_SOURCES = JudyLCascade.c JudyLTables.c JudyLCount.c JudyLCreateBranch.c JudyLDecascade.c JudyLDel.c JudyLFirst.c JudyLFreeArray.c JudyLGet.c JudyLInsArray.c JudyLIns.c JudyLInsertBranch.c JudyLMallocIF.c JudyLMemActive.c JudyLMemUsed.c + +libnext_la_SOURCES = JudyLNext.c JudyLNextEmpty.c +libnext_la_CFLAGS = $(AM_CFLAGS) -DJUDYNEXT + +libprev_la_SOURCES = JudyLPrev.c JudyLPrevEmpty.c +libprev_la_CFLAGS = $(AM_CFLAGS) -DJUDYPREV + +libcount_la_SOURCES = JudyLByCount.c +libcount_la_CFLAGS = $(AM_CFLAGS) -DNOSMARTJBB -DNOSMARTJBU -DNOSMARTJLB + +libinline_la_SOURCES = j__udyLGet.c +libinline_la_CFLAGS = $(AM_CFLAGS) -DJUDYGETINLINE + +JudyLTables.c: JudyLTablesGen.c + $(HOSTCC) $(INCLUDES) $(AM_CFLAGS) -DJU_64BIT $(HOSTCCFLAGS) -o JudyLTablesGen JudyLTablesGen.c; ./JudyLTablesGen + +JudyLByCount.c: ../JudyCommon/JudyByCount.c + cp -f ../JudyCommon/JudyByCount.c JudyLByCount.c + +JudyLCascade.c:../JudyCommon/JudyCascade.c + cp -f ../JudyCommon/JudyCascade.c JudyLCascade.c + +JudyLCount.c:../JudyCommon/JudyCount.c + cp -f ../JudyCommon/JudyCount.c JudyLCount.c + +JudyLCreateBranch.c:../JudyCommon/JudyCreateBranch.c + cp -f ../JudyCommon/JudyCreateBranch.c JudyLCreateBranch.c + +JudyLDecascade.c:../JudyCommon/JudyDecascade.c + cp -f ../JudyCommon/JudyDecascade.c JudyLDecascade.c + +JudyLDel.c:../JudyCommon/JudyDel.c + cp -f ../JudyCommon/JudyDel.c JudyLDel.c + +JudyLFirst.c:../JudyCommon/JudyFirst.c + cp -f ../JudyCommon/JudyFirst.c JudyLFirst.c + +JudyLFreeArray.c:../JudyCommon/JudyFreeArray.c + cp -f ../JudyCommon/JudyFreeArray.c JudyLFreeArray.c + +JudyLGet.c:../JudyCommon/JudyGet.c + cp -f ../JudyCommon/JudyGet.c JudyLGet.c + +j__udyLGet.c:../JudyCommon/JudyGet.c + cp -f ../JudyCommon/JudyGet.c j__udyLGet.c + +JudyLInsArray.c:../JudyCommon/JudyInsArray.c + cp -f ../JudyCommon/JudyInsArray.c JudyLInsArray.c + +JudyLIns.c:../JudyCommon/JudyIns.c + cp -f ../JudyCommon/JudyIns.c JudyLIns.c + +JudyLInsertBranch.c:../JudyCommon/JudyInsertBranch.c + cp -f ../JudyCommon/JudyInsertBranch.c JudyLInsertBranch.c + +JudyLMallocIF.c:../JudyCommon/JudyMallocIF.c + cp -f ../JudyCommon/JudyMallocIF.c JudyLMallocIF.c + +JudyLMemActive.c:../JudyCommon/JudyMemActive.c + cp -f ../JudyCommon/JudyMemActive.c JudyLMemActive.c + +JudyLMemUsed.c:../JudyCommon/JudyMemUsed.c + cp -f ../JudyCommon/JudyMemUsed.c JudyLMemUsed.c + +JudyLNext.c:../JudyCommon/JudyPrevNext.c + cp -f ../JudyCommon/JudyPrevNext.c JudyLNext.c + +JudyLPrev.c:../JudyCommon/JudyPrevNext.c + cp -f ../JudyCommon/JudyPrevNext.c JudyLPrev.c + +JudyLNextEmpty.c:../JudyCommon/JudyPrevNextEmpty.c + cp -f ../JudyCommon/JudyPrevNextEmpty.c JudyLNextEmpty.c + +JudyLPrevEmpty.c:../JudyCommon/JudyPrevNextEmpty.c + cp -f ../JudyCommon/JudyPrevNextEmpty.c JudyLPrevEmpty.c + +JudyLTablesGen.c:../JudyCommon/JudyTables.c + cp -f ../JudyCommon/JudyTables.c JudyLTablesGen.c + +DISTCLEANFILES = .deps Makefile + +CLEANFILES = JudyLByCount.c \ + JudyLCascade.c \ + JudyLCount.c \ + JudyLCreateBranch.c \ + JudyLDecascade.c \ + JudyLDel.c \ + JudyLFirst.c \ + JudyLFreeArray.c \ + JudyLGet.c \ + j__udyLGet.c \ + JudyLInsArray.c \ + JudyLIns.c \ + JudyLInsertBranch.c \ + JudyLMallocIF.c \ + JudyLMemActive.c \ + JudyLMemUsed.c \ + JudyLNext.c \ + JudyLPrev.c \ + JudyLNextEmpty.c \ + JudyLPrevEmpty.c \ + JudyLTablesGen.c \ + JudyLTables.c \ + JudyLTablesGen \ + .libs \ + *.o \ + *.lo \ + *.la diff --git a/feeds/p4/libjudy/src/src/JudyL/README b/feeds/p4/libjudy/src/src/JudyL/README new file mode 100644 index 000000000..bac5d511c --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudyL/README @@ -0,0 +1,8 @@ +# @(#) $Revision: 4.19 $ $Source: /judy/src/JudyL/README $ +# +# This tree contains sources for the JudyL*() functions. +# + +JudyL.h + +lint.waivers see usage in makefile diff --git a/feeds/p4/libjudy/src/src/JudySL/JudySL.c b/feeds/p4/libjudy/src/src/JudySL/JudySL.c new file mode 100644 index 000000000..d7314a736 --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudySL/JudySL.c @@ -0,0 +1,1127 @@ +// +// This program is free software; you can redistribute it and/or modify it +// under the term of the GNU Lesser 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 Lesser General Public License +// for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// _________________ + +// @(#) $Revision: 4.38 $ $Source: /judy/src/JudySL/JudySL.c $ +// +// JUDY FUNCTIONS FOR STRING INDEXES, where associated values are longs. One +// JudySL*() corresponds to each JudyL*() function (with exceptions). +// +// See the manual entry for details. +// +// METHOD: Break up each null-terminated Index (string) into chunks of W +// bytes, where W is the machines word size, with null-padding in the last +// word if necessary. Store strings as a tree of JudyL arrays, that is, array +// of array of array... where each level consumes W bytes (one word) as an +// index to the JudyL array at that level. Since strings can begin on +// arbitrary byte boundaries, copy each chunk of W bytes from Index into a +// word-aligned object before using it as a Judy index. +// +// The JudySL tree also supports "single-index shortcut leaves". A simple +// JudySL array (tree of JudyL arrays) would go as many levels deep as the +// Index (string) is long, which wastes time and memory when an Index is unique +// beyond a certain point. When theres just one Index under a pointer, given +// a reliable way to tell that the pointer is not a root pointer to another +// JudyL array, it should save a lot of time to instead point to a "leaf" +// object, similar to leaves in JudyL arrays. +// +// TBD: Multi-index leaves, like those in JudyL, are also worth considering, +// but their payback for JudySL is less certain. Likewise, shortcut branches +// are worth considering too. +// +// This code uses the Judy.h definitions and Doug Baskins convention of a "P" +// prefix for pointers, except no "P" for the first level of char * (strings). + +// IMPORTS: + +#include // for strcmp(), strlen(), strcpy() +#include + +#ifndef NDEDUG +#define NDEBUG 1 +#endif +#include + +//======================================================================= +// Compile: +// +// cc -O JudyHS.c -c +// +// Notes: +// 1) use -DJU_64BIT for 64 bit compiles (HP, Sun, IPF, Motorola/IBM? etc..) +// 2) In gcc version 3.3.1 for a Centrino, -O2 is faster than -O +// 3) In gcc version 3.3.2 for a Centrino, -O3 is faster than -O2 +//======================================================================= + +#define JU_SET_ERRNO(PJERROR, JERRNO) \ +{ \ + if (PJERROR != (PJError_t)NULL) \ + { \ + JU_ERRNO(PJERROR) = (JERRNO); \ + JU_ERRID(PJERROR) = __LINE__; \ + } \ +} + +#define JU_SET_ERRNO_NONNULL(PJERROR, JERRNO) \ +{ \ + JU_ERRNO(PJERROR) = (JERRNO); \ + JU_ERRID(PJERROR) = __LINE__; \ +} + +// SUPPORT FOR HANDLING WORDS: + +#define WORDSIZE (sizeof (Word_t)) // bytes in word = JudyL index. +#define WORDS(BYTES) (((BYTES) + WORDSIZE - 1) / WORDSIZE) // round up. + +// To mark a pointer is to a "short cut leaf", set least bit + +#define IS_PSCL(PSCL) (((Word_t) (PSCL)) & JLAP_INVALID) +#define CLEAR_PSCL(PSCL) ((Pscl_t)(((Word_t) (PSCL)) & (~JLAP_INVALID))) +#define SET_PSCL(PSCL) (((Word_t) (PSCL)) | JLAP_INVALID) + +// MISCELLANEOUS GLOBALS: + +// Get the Index (string) length in bytes, including the trailing \0, which +// is an integral part of the string: + +// A string is "in the last word" if a previously-set byte count is at or below +// the system word size, or in some cases if the last byte in the (null-padded) +// word is null (assume big-endian, including in a register on a little-endian +// machine): + +#define LASTWORD_BY_VALUE(WORD) (! ((WORD) & 0xffL)) + +#ifdef JU_64BIT + +// copy from 1..7 bytes from string to Word_t and test if \0 bytes +// +#define COPYSTRINGtoWORD(WORD,STR) \ +{ \ + do \ + { \ + uint8_t chr; \ + WORD = (Word_t)(STR)[0] << 56; \ + if (!(WORD)) break; \ + if (!(chr = (STR)[1])) break; \ + WORD += ((Word_t)(chr) << 48); \ + if (!(chr = (STR)[2])) break; \ + WORD += ((Word_t)(chr) << 40); \ + if (!(chr = (STR)[3])) break; \ + WORD += ((Word_t)(chr) << 32); \ + if (!(chr = (STR)[4])) break; \ + WORD += ((Word_t)(chr) << 24); \ + if (!(chr = (STR)[5])) break; \ + WORD += ((Word_t)(chr) << 16); \ + if (!(chr = (STR)[6])) break; \ + WORD += ((Word_t)(chr) << 8) + (STR)[7]; \ + } while(0); \ +} + +// copy Word_t from 1..8 bytes to string and test of \0 bytes +// +#define COPYWORDtoSTRING(STR,WORD) \ +{ \ + do \ + { \ + if (!((STR)[0] = (uint8_t)((WORD) >> 56))) break; \ + if (!((STR)[1] = (uint8_t)((WORD) >> 48))) break; \ + if (!((STR)[2] = (uint8_t)((WORD) >> 40))) break; \ + if (!((STR)[3] = (uint8_t)((WORD) >> 32))) break; \ + if (!((STR)[4] = (uint8_t)((WORD) >> 24))) break; \ + if (!((STR)[5] = (uint8_t)((WORD) >> 16))) break; \ + if (!((STR)[6] = (uint8_t)((WORD) >> 8))) break; \ + (STR)[7] = (uint8_t)(WORD); \ + } while(0); \ +} + +#else // JU_32BIT + +// copy from 1..4 bytes from string to Word_t and test if \0 bytes + +#define COPYSTRINGtoWORD(WORD,STR) \ +{ \ + do \ + { \ + uint8_t chr; \ + WORD = (STR)[0] << 24; \ + if (WORD == 0) break; \ + if (!(chr = (STR)[1])) break; \ + WORD += (Word_t)(chr << 16); \ + if (!(chr = (STR)[2])) break; \ + WORD += (Word_t)(chr << 8) + (STR)[3]; \ + } while(0); \ +} + +// copy Word_t from 1..4 bytes to string and test of \0 bytes + +#define COPYWORDtoSTRING(STR,WORD) \ +{ \ + do \ + { \ + if (!((STR)[0] = (uint8_t)((WORD) >> 24))) break; \ + if (!((STR)[1] = (uint8_t)((WORD) >> 16))) break; \ + if (!((STR)[2] = (uint8_t)((WORD) >> 8))) break; \ + (STR)[3] = (uint8_t)(WORD); \ + } while(0); \ +} +#endif // JU_32BIT + + +// SUPPORT FOR SINGLE-INDEX SHORTCUT LEAVES: + +typedef struct SHORCUTLEAF +{ + Pvoid_t scl_Pvalue; // callers value area. + uint8_t scl_Index[WORDSIZE]; // base Index string. +} scl_t , *Pscl_t; + +// overhead of the scl_Pvalue only, the scl_Index is calculate elsewhere + +#define STRUCTOVD (sizeof(scl_t) - WORDSIZE) + +// How big to malloc a shortcut leaf; stringlen should already include the +// trailing null char: + +#define SCLSIZE(LEN) (((LEN) + STRUCTOVD + WORDSIZE - 1) / WORDSIZE) + +// string routines, may replace with your own +// +#define STRCMP(S1,S2) strcmp((void *)(S1), (void *)(S2)) +#define STRCPY(S1,S2) strcpy((void *)(S1), (void *)(S2)) +#define STRLEN(S1) (strlen((void *)(S1)) + 1) + + +// Index and value area for a shortcut leaf, depending on how it matches the +// undecoded remainder of the Index, given a Pscl_t that includes type bits +// that must be cleared: +// +// PSCLINDEX() and PSCLVALUE() are also useful when Pscl contains uncleared +// TYPE bits. +// +// Note: SCLCMP() cannot take advantage of knowing the Index length because +// the scl_Index length is not pre-known when these macros are used. + +#define PSCLINDEX(PSCL) ((CLEAR_PSCL(PSCL))->scl_Index) +#define PSCLVALUE(PSCL) ((CLEAR_PSCL(PSCL))->scl_Pvalue) + +#define SCLCMP(INDEX,PSCL) STRCMP(INDEX, PSCLINDEX(PSCL)) + +#define PPSCLVALUE_EQ(INDEX,PSCL) \ + ((SCLCMP(INDEX, PSCL) == 0) ? &PSCLVALUE(PSCL) : (PPvoid_t)NULL) + +#define PPSCLVALUE_LT(INDEX,PSCL) \ + ((SCLCMP(INDEX, PSCL) < 0) ? &PSCLVALUE(PSCL) : (PPvoid_t)NULL) + +#define PPSCLVALUE_GT(INDEX,PSCL) \ + ((SCLCMP(INDEX, PSCL) > 0) ? &PSCLVALUE(PSCL) : (PPvoid_t)NULL) + +// Common in-lined code to append or free a shortcut leaf: +// +// See header comments about premature return(). Note that malloc() does not +// pre-zero the memory, so ensure scl_Pvalue is zeroed, just like a value area +// in a JudyL array. Hope strcpy() is fast enough in this context. + +#define APPEND_SCL(PSCL,PPARRAY,INDEX,LEN,PJERROR) \ +{ \ + if (((PSCL) = (Pscl_t) JudyMalloc(SCLSIZE(LEN))) == (Pscl_t)NULL) \ + { \ + JU_SET_ERRNO(PJERROR, JU_ERRNO_NOMEM); \ + return (PPJERR); \ + } \ + *(PPARRAY) = (Pvoid_t)SET_PSCL(PSCL); \ + ((PSCL)->scl_Pvalue) = (Pvoid_t)NULL; \ + (void)STRCPY((PSCL)->scl_Index, INDEX); \ +} + +// "FORWARD" DECLARATIONS: + +static void JudySLModifyErrno(PJError_t PJError, + Pcvoid_t PArray, Pcvoid_t PArrayOrig); +static int JudySLDelSub(PPvoid_t PPArray, PPvoid_t PPArrayOrig, + const uint8_t * Index, Word_t len, PJError_t PJError); +static PPvoid_t JudySLPrevSub(Pcvoid_t PArray, uint8_t * Index, int orig, + Word_t len, PJError_t PJError); +static PPvoid_t JudySLNextSub(Pcvoid_t PArray, uint8_t * Index, int orig, + Word_t len, PJError_t PJError); + +// **************************************************************************** +// J U D Y S L M O D I F Y E R R N O +// +// Common code for error translation: When a caller passes an invalid JAP +// ("not a JudyL pointer"), OR if the JudySL array is corrupted at a lower +// level, various JudyL*() calls return JU_ERRNO_NOTJUDYL. If the caller wants +// detailed error info, convert this particular error to JU_ERRNO_NOTJUDYSL if +// at the top of the tree, otherwise convert it to JU_ERRNO_CORRUPT, meaning +// there was a corruption (the only one even detectable outside JudyL) in the +// JudySL tree; but pass through any other errors unaltered. + +static void +JudySLModifyErrno(PJError_t PJError, // to modify if non-null. + Pcvoid_t PArray, // current JudyL array. + Pcvoid_t PArrayOrig // top-of-tree JudyL array. + ) +{ // map this Judy errno. + if ((PJError != PJE0) && (JU_ERRNO(PJError) == JU_ERRNO_NOTJUDYL)) + { + if (PArray == PArrayOrig) // callers fault. + { + JU_SET_ERRNO_NONNULL(PJError, JU_ERRNO_NOTJUDYSL); + } + else // lower level. + { + JU_SET_ERRNO_NONNULL(PJError, JU_ERRNO_CORRUPT); + } + } +} // JudySLModifyErrno() + +// **************************************************************************** +// J U D Y S L G E T +// +// See comments in file header and below. + +PPvoid_t +JudySLGet(Pcvoid_t PArray, const uint8_t * Index, PJError_t PJError) +{ + const uint8_t *pos = Index; // place in Index. + Word_t indexword; // buffer for aligned copy. + PPvoid_t PPValue; // from JudyL array. + +// CHECK FOR CALLER ERROR (NULL POINTER): + + if (Index == (uint8_t *) NULL) + { + JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX); + return (PPJERR); + } + +// SEARCH NEXT LEVEL JUDYL ARRAY IN TREE: +// +// Use or copy each word from the Index string and check for it in the next +// level JudyL array in the array tree, but first watch for shortcut leaves. +// Upon invalid Index or end of Index (string) in current word, return. + + do // until return. + { + if (IS_PSCL(PArray)) // a shortcut leaf. + return (PPSCLVALUE_EQ(pos, PArray)); + + COPYSTRINGtoWORD(indexword, pos); // copy next 4[8] bytes. + + JLG(PPValue, PArray, indexword); + + if ((PPValue == (PPvoid_t) NULL) || LASTWORD_BY_VALUE(indexword)) + return (PPValue); + +// CONTINUE TO NEXT LEVEL DOWN JUDYL ARRAY TREE: +// +// If a previous JudySLIns() ran out of memory partway down the tree, it left a +// null *PPValue; this is automatically treated here as a dead-end (not a core +// dump or assertion; see version 1.25). + + pos += WORDSIZE; + PArray = *PPValue; // each value -> next array. + } while(1); // forever +// NOTREACHED JudySLGet() +} + +// **************************************************************************** +// J U D Y S L I N S +// +// See also the comments in JudySLGet(), which is somewhat similar, though +// simpler. +// +// Theory of operation: +// +// Upon encountering a null pointer in the tree of JudyL arrays, insert a +// shortcut leaf -- including directly under a null root pointer for the first +// Index in the JudySL array. +// +// Upon encountering a pre-existing shortcut leaf, if the old Index is equal to +// the new one, return the old value area. Otherwise, "carry down" the old +// Index until the old and new Indexes diverge, at which point each Index +// either terminates in the last JudyL array or a new shortcut leaf is inserted +// under it for the Indexs remainder. +// +// TBD: Running out of memory below the starting point causes a premature +// return below (in several places) and leaves a dead-end in the JudySL tree. +// Ideally the code here would back this out rather than wasting a little +// memory, but in lieu of that, the get, delete, and search functions +// understand dead-ends and handle them appropriately. + +PPvoid_t +JudySLIns(PPvoid_t PPArray, const uint8_t * Index, PJError_t PJError) +{ + PPvoid_t PPArrayOrig = PPArray; // for error reporting. + const uint8_t *pos = Index; // place in Index. + const uint8_t *pos2 = (uint8_t *) NULL; // old Index (SCL being moved). + Word_t len; // bytes remaining. + +// Note: len2 is set when needed and only used when valid, but this is not +// clear to gcc -Wall, so initialize it here to avoid a warning: + + Word_t len2 = 0; // for old Index (SCL being moved). + Word_t scl2 = 0; // size in words of SCL + Word_t indexword; // buffer for aligned copy. + Word_t indexword2; // for old Index (SCL being moved). + PPvoid_t PPValue; // from JudyL array. + PPvoid_t PPValue2; // for old Index (SCL being moved). + Pscl_t Pscl = (Pscl_t) NULL; // shortcut leaf. + Pscl_t Pscl2; // for old Index (SCL being moved). + +// CHECK FOR CALLER ERROR (NULL POINTERS): + + if (PPArray == (PPvoid_t) NULL) + { + JU_SET_ERRNO(PJError, JU_ERRNO_NULLPPARRAY); + return (PPJERR); + } + if (Index == (uint8_t *) NULL) + { + JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX); + return (PPJERR); + } + + len = STRLEN(Index); // bytes remaining. + +// APPEND SHORTCUT LEAF: +// +// If PPArray, which is the root pointer to the first or next JudyL array in +// the tree, points to null (no next JudyL array), AND there is no shortcut +// leaf being carried down, append a shortcut leaf here for the new Index, no +// matter how much of the Index string remains (one or more bytes, including +// the trailing \0). + + while (1) // until return. + { + if (*PPArray == (Pvoid_t)NULL) // no next JudyL array. + { + if (Pscl == (Pscl_t) NULL) // no SCL being carried down. + { + APPEND_SCL(Pscl, PPArray, pos, len, PJError); // returns if error. + return (&(Pscl->scl_Pvalue)); + } + // else do nothing here; see below. + } + +// CARRY DOWN PRE-EXISTING SHORTCUT LEAF: +// +// When PPArray points to a pre-existing shortcut leaf, if its Index is equal +// to the Index to be inserted, meaning no insertion is required, return its +// value area; otherwise, "move it aside" and "carry it down" -- replace it +// (see below) with one or more levels of JudyL arrays. Moving it aside +// initially just means setting Pscl non-null, both as a flag and for later +// use, and clearing the pointer to the SCL in the JudyL array. + + else if (IS_PSCL(*PPArray)) + { + assert(Pscl == (Pscl_t) NULL); // no nested SCLs. + + Pscl = CLEAR_PSCL(*PPArray); + + pos2 = Pscl->scl_Index; // note: pos2 is always word-aligned. + len2 = STRLEN(pos2); // bytes remaining. + +// first check if string is already inserted + + if ((len == len2) && (STRCMP(pos, pos2) == 0)) + return (&(Pscl->scl_Pvalue)); + + *PPArray = (Pvoid_t)NULL; // disconnect SCL. + + scl2 = SCLSIZE(len2); // save for JudyFree + + // continue with *PPArray now clear, and Pscl, pos2, len2 set. + } + +// CHECK IF OLD AND NEW INDEXES DIVERGE IN THE CURRENT INDEX WORD: +// +// If a shortcut leaf is being carried down and its remaining Index chars now +// diverge from the remaining chars of the Index being inserted, that is, if +// the next words of each Index differ, "plug in" the old Index here, in a new +// JudyL array, before proceeding. +// +// Note: Call JudyLIns() for the SCL Index word before calling it for the new +// Index word, so PPValue remains correct for the latter. (JudyLIns() return +// values are not stable across multiple calls.) +// +// Note: Although pos2 is word-aligned, and a Pscl_t is a whole number of +// words in size, pos2 is not certain to be null-padded through a whole word, +// so copy it first to an index word for later use. +// +// See header comments about premature return(). + + COPYSTRINGtoWORD(indexword, pos); // copy next 4[8] bytes. + + if (Pscl != (Pscl_t) NULL) + { + COPYSTRINGtoWORD(indexword2, pos2); // copy next 4[8] bytes. + + if (indexword != indexword2) // SCL and new Indexes diverge. + { + assert(*PPArray == (Pvoid_t)NULL); // should be new JudyL array. + +// Note: If JudyLIns() returns JU_ERRNO_NOTJUDYL here, *PPArray should not be +// modified, so JudySLModifyErrno() can do the right thing. + + if ((PPValue2 = JudyLIns(PPArray, indexword2, PJError)) + == PPJERR) + { + JudySLModifyErrno(PJError, *PPArray, *PPArrayOrig); + return (PPJERR); + } + + assert(PPValue2 != (PPvoid_t) NULL); + +// If the old (SCL) Index terminates here, copy its value directly into the +// JudyL value area; otherwise create a new shortcut leaf for it, under +// *PPValue2 (skipping the word just inserted), and copy its value to the new +// SCL: + + if (len2 <= WORDSIZE) + { + *((PWord_t)PPValue2) = (Word_t)(Pscl->scl_Pvalue); + } + else + { + APPEND_SCL(Pscl2, PPValue2, pos2 + WORDSIZE, + len2 - WORDSIZE, PJError); + (Pscl2->scl_Pvalue) = Pscl->scl_Pvalue; + } +// old SCL no longer needed. + + JudyFree((void *)Pscl, scl2); + + Pscl = (Pscl_t) NULL; + } + } + +// APPEND NEXT LEVEL JUDYL ARRAY TO TREE: +// +// If a shortcut leaf was carried down and diverged at this level, the code +// above already appended the new JudyL array, but the next word of the new +// Index still must be inserted in it. +// +// See header comments about premature return(). +// +// Note: If JudyLIns() returns JU_ERRNO_NOTJUDYL here, *PPArray should not be +// modified, so JudySLModifyErrno() can do the right thing. + + if ((PPValue = JudyLIns(PPArray, indexword, PJError)) == PPJERR) + { + JudySLModifyErrno(PJError, *PPArray, *PPArrayOrig); + return (PPJERR); + } + + assert(PPValue != (PPvoid_t) NULL); + +// CHECK IF NEW INDEX TERMINATES: +// +// Note that if it does, and an old SCL was being carried down, it must have +// diverged by this point, and is already handled. + + if (len <= WORDSIZE) + { + assert(Pscl == (Pscl_t) NULL); + return (PPValue); // is value for whole Index string. + } + + pos += WORDSIZE; + len -= WORDSIZE; + pos2 += WORDSIZE; // useless unless Pscl is set. + len2 -= WORDSIZE; + + PPArray = PPValue; // each value -> next array. + } // while. +} // NOTREACHED, JudySLIns() + +// **************************************************************************** +// J U D Y S L D E L +// +// See the comments in JudySLGet(), which is somewhat similar. +// +// Unlike JudySLGet() and JudySLIns(), recurse downward through the tree of +// JudyL arrays to find and delete the given Index, if present, and then on the +// way back up, any of its parent arrays which ends up empty. +// +// TECHNICAL NOTES: +// +// Recursion seems bad, but this allows for an arbitrary-length Index. Also, a +// more clever iterative solution that used JudyLCount() (see below) would +// still require a function call per tree level, so why not just recurse? +// +// An earlier version (1.20) used a fixed-size stack, which limited the Index +// size. We were going to replace this with using JudyLCount(), in order to +// note and return to (read this carefully) the highest level JudyL array with +// a count of 1, all of whose descendant JudyL arrays also have a count of 1, +// and delete from that point downwards. This solution would traverse the +// array tree downward looking to see if the given Index is in the tree, then +// if so, delete layers downwards starting below the last one that contains +// other Indexes than the one being deleted. +// +// TBD: To save time coding, and to very likely save time overall during +// execution, this function does "lazy deletions", or putting it more nicely, +// it allows "hysteresis" in the JudySL tree, when shortcut leafs are present. +// It only removes the specified Index, and recursively any empty JudyL arrays +// above it, without fully reversing the effects of JudySLIns(). This is +// probably OK because any application that calls JudySLDel() is likely to call +// JudySLIns() again with the same or a neighbor Index. + +int +JudySLDel(PPvoid_t PPArray, const uint8_t * Index, PJError_t PJError) // optional, for returning error info. +{ + +// Check for caller error (null pointer): + + if (PPArray == (PPvoid_t) NULL) + { + JU_SET_ERRNO(PJError, JU_ERRNO_NULLPPARRAY); + return (JERR); + } + if (Index == (uint8_t *) NULL) + { + JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX); + return (JERR); + } + +// Do the deletion: + + return (JudySLDelSub(PPArray, PPArray, Index, STRLEN(Index), PJError)); + +} // JudySLDel() + +// **************************************************************************** +// J U D Y S L D E L S U B +// +// This is the "engine" for JudySLDel() that expects aligned and len to already +// be computed (only once). See the header comments for JudySLDel(). + +static int +JudySLDelSub(PPvoid_t PPArray, // in which to delete. + PPvoid_t PPArrayOrig, // for error reporting. + const uint8_t * Index, // to delete. + Word_t len, // bytes remaining. + PJError_t PJError) // optional, for returning error info. +{ + Word_t indexword; // next word to find. + PPvoid_t PPValue; // from JudyL array. + int retcode; // from lower-level call. + + assert(PPArray != (PPvoid_t) NULL); + assert(Index != (uint8_t *) NULL); + +// DELETE SHORTCUT LEAF: +// +// As described above, this can leave an empty JudyL array, or one containing +// only a single other Index word -- which could be, but is not, condensed into +// a higher-level shortcut leaf. More precisely, at this level it leaves a +// temporary "dead end" in the JudySL tree, similar to when running out of +// memory during JudySLIns(), and this is somewhat cleaned up by higher +// recursions of the same function (see below); but remaining shortcut leaves +// for other Indexes are not coalesced. + + if (IS_PSCL(*PPArray)) + { + Pscl_t Pscll = CLEAR_PSCL(*PPArray); + Word_t words; + + if (STRCMP(Index, Pscll->scl_Index)) + return (0); // incorrect index. + + words = SCLSIZE(STRLEN(Pscll->scl_Index)); + JudyFree((void *)Pscll, words); + + *PPArray = (Pvoid_t)NULL; + return (1); // correct index deleted. + } + +// DELETE LAST INDEX WORD, FROM CURRENT JUDYL ARRAY: +// +// When at the end of the full Index, delete the last word, if present, from +// the current JudyL array, and return the result all the way up. + + COPYSTRINGtoWORD(indexword, Index); // copy next 4[8] bytes. + + if (len <= WORDSIZE) + { + if ((retcode = JudyLDel(PPArray, indexword, PJError)) == JERR) + { + JudySLModifyErrno(PJError, *PPArray, *PPArrayOrig); + return (JERR); + } + return (retcode); + } + +// DELETE BELOW NON-LAST INDEX WORD IN CURRENT JUDYL ARRAY: +// +// If a word before the end of the full Index is present in the current JudyL +// array, recurse through its value, which must be a pointer to another JudyL +// array, to continue the deletion at the next level. Return the JudyLGet() +// return if the Indexs current word is not in the JudyL array, or if no +// delete occurs below this level, both of which mean the whole Index is not +// currently valid. +// + + JLG(PPValue, *PPArray, indexword); + if (PPValue == (PPvoid_t) NULL) + return (0); // Index not in JudySL array. +// If a previous JudySLIns() ran out of memory partway down the tree, it left a +// null *PPValue; this is automatically treated as a dead-end (not a core dump +// or assertion; see version 1.25). + if ((retcode = + JudySLDelSub(PPValue, PPArrayOrig, Index + WORDSIZE, + len - WORDSIZE, PJError)) != 1) + { + return (retcode); // no lower-level delete, or error. + } + +// DELETE EMPTY JUDYL ARRAY: +// +// A delete occurred below in the tree. If the child JudyL array became empty, +// delete the current Index word from the current JudyL array, which could +// empty the current array and null out *PPArray in turn (or pass through an +// error). Otherwise simply indicate that a deletion did occur. + + if (*PPValue == (Pvoid_t)NULL) + { + if ((retcode = JudyLDel(PPArray, indexword, PJError)) == JERR) + { + JudySLModifyErrno(PJError, *PPArray, *PPArrayOrig); + return (JERR); + } + + return (retcode); + } + + return (1); +} // JudySLDelSub() + +// **************************************************************************** +// J U D Y S L P R E V +// +// Recursively traverse the JudySL tree downward using JudyLGet() to look for +// each successive index word from Index in the JudyL array at each level. At +// the last level for the Index (LASTWORD_BY_LEN()), use JudyLPrev() instead of +// JudyLGet(), to exclude the initial Index. If this doesnt result in finding +// a previous Index, work back up the tree using JudyLPrev() at each higher +// level to search for a previous index word. Upon finding a previous index +// word, descend again if/as necessary, this time inclusively, to find and +// return the full previous Index. +// +// Also support shortcut leaves. +// +// Since this function is recursive and it also needs to know if its still +// looking for the original Index (to exclude it at the LASTWORD_BY_LEN() +// level) or for the remaining words of the previous Index (inclusive), +// actually call a subroutine that takes an additional parameter. +// +// See also the technical notes in JudySLDel() regarding the use of recursion +// rather than iteration. + +PPvoid_t +JudySLPrev(Pcvoid_t PArray, uint8_t * Index, PJError_t PJError) // optional, for returning error info. +{ +// Check for caller error (null pointer), or empty JudySL array: + + if (Index == (uint8_t *) NULL) + { + JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX); + return (PPJERR); + } + + if (PArray == (Pvoid_t)NULL) + return ((PPvoid_t) NULL); +// Do the search: + return (JudySLPrevSub(PArray, Index, /* original = */ 1, + STRLEN(Index), PJError)); +} // JudySLPrev() + +// **************************************************************************** +// J U D Y S L P R E V S U B +// +// This is the "engine" for JudySLPrev() that knows whether its still looking +// for the original Index (exclusive) or a neighbor index (inclusive), and that +// expects aligned and len to already be computed (only once). See the header +// comments for JudySLPrev(). + +static PPvoid_t +JudySLPrevSub(Pcvoid_t PArray, uint8_t * Index, int orig, + Word_t len, // bytes remaining. + PJError_t PJError) // optional, for returning error info. +{ + Word_t indexword; // next word to find. + PPvoid_t PPValue; // from JudyL array. +// ORIGINAL SEARCH: +// +// When at a shortcut leaf, copy its remaining Index (string) chars into Index +// and return its value area if the current Index is after (greater than) the +// SCLs index; otherwise return null. + if (orig) + { + if (IS_PSCL(PArray)) + { + if ((PPValue = PPSCLVALUE_GT(Index, PArray)) != (PPvoid_t) NULL) + (void)STRCPY(Index, PSCLINDEX(PArray)); + return (PPValue); + } + +// If the current Index word: +// - is not the last word in Index (end of string), +// - exists in the current JudyL array, and, +// - a previous Index is found below it, return that Indexs value area. + + COPYSTRINGtoWORD(indexword, Index); // copy next 4[8] bytes. + if (len > WORDSIZE) // not at end of Index. + { + JLG(PPValue, PArray, indexword); + if (PPValue != (PPvoid_t) NULL) + { + +// If a previous JudySLIns() ran out of memory partway down the tree, it left a +// null *PPValue; this is automatically treated as a dead-end (not a core dump +// or assertion; see version 1.25): + + PPValue = JudySLPrevSub(*PPValue, Index + WORDSIZE, + /* original = */ 1, + len - WORDSIZE, PJError); + if (PPValue == PPJERR) + return (PPJERR); // propagate error. + if (PPValue != (PPvoid_t) NULL) + return (PPValue); // see above. + } + } + +// Search for previous index word: +// +// One of the above conditions is false. Search the current JudyL array for +// the Index word, if any, prior to the current index word. If none is found, +// return null; otherwise fall through to common later code. + + if ((PPValue = JudyLPrev(PArray, &indexword, PJError)) == PPJERR) + { + JudySLModifyErrno(PJError, PArray, orig ? PArray : (Pvoid_t)NULL); + return (PPJERR); + } + + if (PPValue == (PPvoid_t) NULL) + return ((PPvoid_t) NULL); // no previous index word. + } // if. + +// SUBSEQUENT SEARCH: +// +// A higher level search already excluded the initial Index, then found a +// previous index word, and is now traversing down to determine the rest of the +// Index and to obtain its value area. If at a shortcut leaf, return its value +// area. Otherwise search the current JudyL array backward from the upper +// limit for its last index word. If no index word is found, return null -- +// should never happen unless the JudySL tree is corrupt; otherwise fall +// through to common later code. + + else + { + if (IS_PSCL(PArray)) // at shortcut leaf. + { + (void)STRCPY(Index, PSCLINDEX(PArray)); + return (&PSCLVALUE(PArray)); + } + + indexword = ~0UL; + if ((PPValue = JudyLLast(PArray, &indexword, PJError)) == PPJERR) + { + JudySLModifyErrno(PJError, PArray, orig ? PArray : (Pvoid_t)NULL); + return (PPJERR); + } + +// If a previous JudySLIns() ran out of memory partway down the tree, it left a +// null *PPValue; this is automatically treated as a dead-end (not a core dump +// or assertion; see version 1.25): + + if (PPValue == (PPvoid_t) NULL) + return ((PPvoid_t) NULL); // no previous index word. + } + +// FOUND PREVIOUS INDEX WORD: +// +// A previous (if original) or last (if subsequent) index word was located in +// the current JudyL array. Store it into the callers Index (string). Then +// if the found (previous) Index ends here, return its value area; otherwise do +// a subsequent search below this point, which should never fail unless the +// JudySL tree is corrupt, but this is detected at a lower level by the above +// assertion. +// +// Note: Treat Index as unaligned, even if it is aligned, to avoid writing +// past the end of allocated memory (in case its less than a whole number of +// words). + + COPYWORDtoSTRING(Index, indexword); // copy next 4[8] bytes. + if (LASTWORD_BY_VALUE(indexword)) + return (PPValue); +// If a previous JudySLIns() ran out of memory partway down the tree, it left a +// null *PPValue; this is automatically treated as a dead-end (not a core dump +// or assertion; see version 1.25): + return (JudySLPrevSub(*PPValue, Index + WORDSIZE, /* original = */ 0, + len - WORDSIZE, PJError)); +} // JudySLPrevSub() + +// **************************************************************************** +// J U D Y S L N E X T +// +// See the comments in JudySLPrev(), which is very similar. +// +// TBD: Could the two functions call a common engine function with various +// subfunctions and other constants specified? + +PPvoid_t +JudySLNext(Pcvoid_t PArray, uint8_t * Index, PJError_t PJError) // optional, for returning error info. +{ +// Check for caller error (null pointer), or empty JudySL array: + + if (Index == (uint8_t *) NULL) + { + JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX); + return (PPJERR); + } + + if (PArray == (Pvoid_t)NULL) + return ((PPvoid_t) NULL); +// Do the search: + return (JudySLNextSub(PArray, Index, /* original = */ 1, + STRLEN(Index), PJError)); +} // JudySLNext() + +// **************************************************************************** +// J U D Y S L N E X T S U B +// +// See the comments in JudySLPrevSub(), which is very similar. + +static PPvoid_t +JudySLNextSub(Pcvoid_t PArray, uint8_t * Index, int orig, + Word_t len, // bytes remaining. + PJError_t PJError) // optional, for returning error info. +{ + Word_t indexword; // next word to find. + PPvoid_t PPValue; // from JudyL array. + if (orig) + { + if (IS_PSCL(PArray)) + { + if ((PPValue = PPSCLVALUE_LT(Index, PArray)) != (PPvoid_t) NULL) + (void)STRCPY(Index, PSCLINDEX(PArray)); + return (PPValue); + } + + COPYSTRINGtoWORD(indexword, Index); // copy next 4[8] bytes. + + if (len > WORDSIZE) // not at end of Index. + { + JLG(PPValue, PArray, indexword); + if (PPValue != (PPvoid_t) NULL) + { +// If a previous JudySLIns() ran out of memory partway down the tree, it left a +// null *PPValue; this is automatically treated as a dead-end (not a core dump +// or assertion; see version 1.25): + + PPValue = JudySLNextSub(*PPValue, Index + WORDSIZE, + /* original = */ 1, + len - WORDSIZE, PJError); + if (PPValue == PPJERR) + return (PPJERR); // propagate error. + if (PPValue != (PPvoid_t) NULL) + return (PPValue); // see above. + } + } + + if ((PPValue = JudyLNext(PArray, &indexword, PJError)) == PPJERR) + { + JudySLModifyErrno(PJError, PArray, orig ? PArray : (Pvoid_t)NULL); + return (PPJERR); + } + + if (PPValue == (PPvoid_t) NULL) + return ((PPvoid_t) NULL); // no next index word. + } + else + { + if (IS_PSCL(PArray)) // at shortcut leaf. + { + (void)STRCPY(Index, PSCLINDEX(PArray)); + return (&PSCLVALUE(PArray)); + } + + indexword = 0; + if ((PPValue = JudyLFirst(PArray, &indexword, PJError)) == PPJERR) + { + JudySLModifyErrno(PJError, PArray, orig ? PArray : (Pvoid_t)NULL); + return (PPJERR); + } + +// If a previous JudySLIns() ran out of memory partway down the tree, it left a +// null *PPValue; this is automatically treated as a dead-end (not a core dump +// or assertion; see version 1.25): + + if (PPValue == (PPvoid_t) NULL) + return ((PPvoid_t) NULL); // no next index word. + } + + COPYWORDtoSTRING(Index, indexword); // copy next 4[8] bytes + if (LASTWORD_BY_VALUE(indexword)) + return (PPValue); +// If a previous JudySLIns() ran out of memory partway down the tree, it left a +// null *PPValue; this is automatically treated as a dead-end (not a core dump +// or assertion; see version 1.25): + return (JudySLNextSub(*PPValue, Index + WORDSIZE, /* original = */ 0, + len - WORDSIZE, PJError)); +} // JudySLNextSub() + +// **************************************************************************** +// J U D Y S L F I R S T +// +// Like JudyLFirst(), do a JudySLGet(), then if necessary a JudySLNext(). + +PPvoid_t +JudySLFirst(Pcvoid_t PArray, uint8_t * Index, PJError_t PJError) // optional, for returning error info. +{ + PPvoid_t PPValue; // from JudyL array. + if (Index == (uint8_t *) NULL) + { + JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX); + return (PPJERR); + } + + if ((PPValue = JudySLGet(PArray, Index, PJError)) == PPJERR) + return (PPJERR); // propagate serious error. + if ((PPValue == (PPvoid_t) NULL) // first try failed. + && ((PPValue = JudySLNext(PArray, Index, PJError)) == PPJERR)) + { + return (PPJERR); // propagate serious error. + } + + return (PPValue); +} // JudySLFirst() + +// **************************************************************************** +// J U D Y S L L A S T +// +// Like JudyLLast(), do a JudySLGet(), then if necessary a JudySLPrev(). + +PPvoid_t +JudySLLast(Pcvoid_t PArray, uint8_t * Index, PJError_t PJError) // optional, for returning error info. +{ + PPvoid_t PPValue; // from JudyL array. + if (Index == (uint8_t *) NULL) + { + JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX); + return (PPJERR); + } + + if ((PPValue = JudySLGet(PArray, Index, PJError)) == PPJERR) + return (PPJERR); // propagate serious error. + if ((PPValue == (PPvoid_t) NULL) // first try failed. + && ((PPValue = JudySLPrev(PArray, Index, PJError)) == PPJERR)) + { + return (PPJERR); // propagate serious error. + } + + return (PPValue); +} // JudySLLast() + +// **************************************************************************** +// J U D Y S L F R E E A R R A Y +// +// Walk the JudySL tree of JudyL arrays to free each JudyL array, depth-first. +// During the walk, ignore indexes (strings) that end in the current JudyL +// array to be freed. Just recurse through those indexes which do not end, +// that is, those whose associated value areas point to subsidiary JudyL +// arrays, except for those which point to shortcut leaves. Return the total +// bytes freed in all of the JudyL arrays at or below the current level. +// +// Like the JudyLFreeArray() and Judy1FreeArray() code, this is written +// recursively, which is probably fast enough, to allow indexes (strings) of +// arbitrary size. If recursion turns out to be a problem, consider instead +// doing some large, fixed number of iterative descents (like 100) using a +// fixed-size "stack" (array), then recursing upon overflow (relatively +// rarely). + +Word_t +JudySLFreeArray(PPvoid_t PPArray, PJError_t PJError) // optional, for returning error info. +{ + PPvoid_t PPArrayOrig = PPArray; // for error reporting. + Word_t indexword = 0; // word just found. + PPvoid_t PPValue; // from Judy array. + Word_t bytes_freed = 0; // bytes freed at this level. + Word_t bytes_total = 0; // bytes freed at all levels. + if (PPArray == (PPvoid_t) NULL) + { + JU_SET_ERRNO(PJError, JU_ERRNO_NULLPPARRAY); + return (JERR); + } + +// FREE SHORTCUT LEAF: + + if (IS_PSCL(*PPArray)) + { + Word_t freewords; + Pscl_t Pscl; + + Pscl = CLEAR_PSCL(*PPArray); + + freewords = SCLSIZE(STRLEN(Pscl->scl_Index)); + + JudyFree((void *)Pscl, freewords); + + *PPArray = (Pvoid_t)NULL; + + return (freewords * WORDSIZE); + } + +// FREE EACH SUB-ARRAY (DEPTH-FIRST): +// +// If a previous JudySLIns() ran out of memory partway down the tree, it left a +// null *PPValue. This is automatically treated correctly here as a dead-end. +// +// An Index (string) ends in the current word iff the last byte of the +// (null-padded) word is null. + + for (PPValue = JudyLFirst(*PPArray, &indexword, PJError); + (PPValue != (PPvoid_t) NULL) && (PPValue != PPJERR); + PPValue = JudyLNext(*PPArray, &indexword, PJError)) + { + if (!LASTWORD_BY_VALUE(indexword)) + { + if ((bytes_freed = JudySLFreeArray(PPValue, PJError)) == JERR) + return (JERR); // propagate serious error. + bytes_total += bytes_freed; + } + } + +// Check for a serious error in a JudyL*() call: + + if (PPValue == PPJERR) + { + JudySLModifyErrno(PJError, *PPArray, *PPArrayOrig); + return (JERR); + } + +// Now free the current array, which also nulls the pointer: +// +// Note: *PPArray can be null here for a totally null JudySL array => +// JudyLFreeArray() returns zero. + + if ((bytes_freed = JudyLFreeArray(PPArray, PJError)) == JERR) + { + JudySLModifyErrno(PJError, *PPArray, *PPArrayOrig); + return (JERR); + } + return (bytes_total + bytes_freed); +} // JudySLFreeArray() diff --git a/feeds/p4/libjudy/src/src/JudySL/Makefile.am b/feeds/p4/libjudy/src/src/JudySL/Makefile.am new file mode 100644 index 000000000..8d0d0d385 --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudySL/Makefile.am @@ -0,0 +1,8 @@ +INCLUDES = -I. -I.. -I../JudyCommon/ +AM_CFLAGS = @CFLAGS@ @WARN_CFLAGS@ + +noinst_LTLIBRARIES = libJudySL.la + +libJudySL_la_SOURCES = JudySL.c + +DISTCLEANFILES = .deps Makefile diff --git a/feeds/p4/libjudy/src/src/JudySL/README b/feeds/p4/libjudy/src/src/JudySL/README new file mode 100644 index 000000000..6ca44b9f7 --- /dev/null +++ b/feeds/p4/libjudy/src/src/JudySL/README @@ -0,0 +1,6 @@ +# @(#) $Revision: 4.3 $ $Source: /judy/src/JudySL/README $ +# +# This tree contains sources for the JudySL*() functions. + +JudySL.c source file +Note: JudySL.h is no longer needed (May 2004) diff --git a/feeds/p4/libjudy/src/src/Makefile.am b/feeds/p4/libjudy/src/src/Makefile.am new file mode 100644 index 000000000..9cfb2e948 --- /dev/null +++ b/feeds/p4/libjudy/src/src/Makefile.am @@ -0,0 +1,3 @@ +SUBDIRS = . JudyCommon JudyL Judy1 JudySL JudyHS obj + +DISTCLEANFILES = .deps Makefile diff --git a/feeds/p4/libjudy/src/src/README b/feeds/p4/libjudy/src/src/README new file mode 100644 index 000000000..5b2c858f3 --- /dev/null +++ b/feeds/p4/libjudy/src/src/README @@ -0,0 +1,20 @@ +# @(#) $Revision: 4.10 $ $Source: /judy/src/README $ + +# This tree contains sources for the Judy project. + +# For more on how to build Judy files, see make_includes/README. + +The 'sh_build' script to compiling Judy manually for other platforms + +# Current stuff: + +Judy.h exported header file for libJudy.a +Judy.h.check.c test program for Judy.h + +JudyCommon/ shared utility functions and common source files +Judy1/ Judy1.h +JudyL/ JudyL.h +JudySL/ JudySL*() +JudyHS/ JudyHS*() + +apps/ applications done or redone using Judy diff --git a/feeds/p4/libjudy/src/src/apps/README b/feeds/p4/libjudy/src/src/apps/README new file mode 100644 index 000000000..096a7b23b --- /dev/null +++ b/feeds/p4/libjudy/src/src/apps/README @@ -0,0 +1,21 @@ +# @(#) $Revision: 4.4 $ $Source: /judy/src/apps/README $ +# +# This tree contains sources for Judy-related applications, that is, for +# sources including a main() function, suitable for building an executable +# program. Some of these sources are packaged and delivered to Judy users +# as an optional package of example sources. + +benchmark/ sources for benchmarking programs, that is, demos that + yield performance metrics; including sources for metrics + displayed on the Judy website + +demo/ sources for programs that demonstrate the use of Judy + but are probably not useful as templates for writing + Judy-based applications + +# misc/ other sources; none exist at this time; and as they come + along, they might go in misc/ or in other, more-specific + directories + +noship/ other example sources we are not free to deliver to Judy + users, or which it's inappropriate or premature to deliver diff --git a/feeds/p4/libjudy/src/src/apps/demo/JudySort.c b/feeds/p4/libjudy/src/src/apps/demo/JudySort.c new file mode 100644 index 000000000..05b70b040 --- /dev/null +++ b/feeds/p4/libjudy/src/src/apps/demo/JudySort.c @@ -0,0 +1,34 @@ +#include +#include +#include + +#include + +// By Doug Baskins Aug 2002 - for JudySL man page + +int // Usage: JudySort < file_to_sort +main() +{ + Pvoid_t PJArray = (PWord_t)NULL; // Judy array. + PWord_t PValue; // Judy array element. + Word_t Bytes; // size of JudySL array. + char Index[BUFSIZ]; // string to sort. + + while (fgets(Index, sizeof(Index), stdin) != (char *)NULL) + { + JSLI(PValue, PJArray, Index); // store string into array + ++(*PValue); // count instances of string + } + Index[0] = '\0'; // start with smallest string. + JSLF(PValue, PJArray, Index); // get first string + while (PValue != NULL) + { + while ((*PValue)--) // print duplicates + printf("%s", Index); + JSLN(PValue, PJArray, Index); // get next string + } + JSLFA(Bytes, PJArray); // free array + + fprintf(stderr, "The JudySL array used %lu bytes of memory\n", Bytes); + return (0); +} diff --git a/feeds/p4/libjudy/src/src/apps/demo/Makefile_deliver b/feeds/p4/libjudy/src/src/apps/demo/Makefile_deliver new file mode 100644 index 000000000..ce84492a3 --- /dev/null +++ b/feeds/p4/libjudy/src/src/apps/demo/Makefile_deliver @@ -0,0 +1,52 @@ +# @(#) $Revision: 4.11 $ $Source: /judy/src/apps/demo/Makefile_deliver $ + +# Makefile for Judy demo programs. + +# Locations of Judy header file and library; correct if necessary: +# +# Note the use of the archive version (libJudy.a) for speed, although the +# difference from shared libs is not great on Linux. + +JUDY = /usr + +JUDY_INCDIR = $(JUDY)/include +JUDY_LIBDIR = $(JUDY)/lib +JUDY_HEADER = $(JUDY_INCDIR)/Judy.h +JUDY_LIBBASE = Judy +JUDY_LIB = $(JUDY_LIBDIR)/lib$(JUDY_LIBBASE).a + +DEBUG = -O +CFLAGS = $(DEBUG) +CC = cc + +# Place files locally by default: + +OBJS = interL.o interSL.o funhist.o JudySort.o +EXECS = interL interSL funhist JudySort + +# === RULES === + +all: $(EXECS) +debug:; make -f Makefile DEBUG='-g' + +# Unfortunately not all make programs understand filename generation via $(@F), +# or at least $$(@F) on a dependencies line, so spell out each $EXECS target +# separately: + +interL: interL.c $(JUDY_HEADER) $(JUDY_LIB) + $(CC) $(CFLAGS) -I $(JUDY_INCDIR) $(@F).c \ + -L$(JUDY_LIBDIR) -l$(JUDY_LIBBASE) -o $@ + +interSL: interSL.c $(JUDY_HEADER) $(JUDY_LIB) + $(CC) $(CFLAGS) -I $(JUDY_INCDIR) $(@F).c \ + -L$(JUDY_LIBDIR) -l$(JUDY_LIBBASE) -o $@ + +funhist: funhist.c $(JUDY_HEADER) $(JUDY_LIB) + $(CC) $(CFLAGS) -I $(JUDY_INCDIR) $(@F).c \ + -L$(JUDY_LIBDIR) -l$(JUDY_LIBBASE) -o $@ + +JudySort: JudySort.c $(JUDY_HEADER) $(JUDY_LIB) + $(CC) $(CFLAGS) -I $(JUDY_INCDIR) $(@F).c \ + -L$(JUDY_LIBDIR) -l$(JUDY_LIBBASE) -o $@ + +clean:; rm -rf core $(OBJS) $(EXECS) diff --git a/feeds/p4/libjudy/src/src/apps/demo/README b/feeds/p4/libjudy/src/src/apps/demo/README new file mode 100644 index 000000000..3e760c703 --- /dev/null +++ b/feeds/p4/libjudy/src/src/apps/demo/README @@ -0,0 +1,24 @@ +# @(#) $Revision: 4.8 $ $Source: /judy/src/apps/demo/README $ + +# Demo programs to be included with the Judy distribution. + +README_deliver delivered with files from this directory, renamed to "README" + +run_demo simple Judy example script; explains, shows source code, + compiles and runs it + +Makefile_deliver + delivered as "Makefile"; by default, makes all the demo + programs; the libJudy.a and Judy.h locations might have + to be changed (via cc -I options) + NOTE: This file contains "#ifdef" directives that look + to make like comments, but don't expect the makefile to + run prior to unifdef'ing in the makefile. That is, use + the constructed version for a given platform. + +funhist.c function histogram program + +interL.c interactive JudyL program +interSL.c interactive JudySL program + +JudySort.c JudySL version of "sort -u" diff --git a/feeds/p4/libjudy/src/src/apps/demo/README_deliver b/feeds/p4/libjudy/src/src/apps/demo/README_deliver new file mode 100644 index 000000000..8946fee26 --- /dev/null +++ b/feeds/p4/libjudy/src/src/apps/demo/README_deliver @@ -0,0 +1,17 @@ +# @(#) $Revision: 4.5 $ $Source: /judy/src/apps/demo/README_deliver $ + +# Demo programs to be included with the Judy distribution. + +run_demo Simple Judy example script; explains, shows source code, + compiles and runs it. + +Makefile By default, makes all the demo programs. The libJudy.a + and Judy.h locations might have to be changed (via cc -I + options). + +funhist.c Function histogram program. + +interL.c Interactive JudyL program. +interSL.c Interactive JudySL program. + +JudySort.c JudySL version of "sort -u". diff --git a/feeds/p4/libjudy/src/src/apps/demo/funhist.c b/feeds/p4/libjudy/src/src/apps/demo/funhist.c new file mode 100644 index 000000000..709e231ee --- /dev/null +++ b/feeds/p4/libjudy/src/src/apps/demo/funhist.c @@ -0,0 +1,243 @@ +// @(#) $Revision: 4.5 $ $Source: /judy/src/apps/demo/funhist.c $ +// +// FUNCTION HISTOGRAM; JUDYL DEMO PROGRAM +// +// This program uses JudyL to create a histogram of data generated by the +// function random(3M). Other functions could be substituted in. +// +// The program generates n random numbers, stores them in a JudyL array +// and then prints a histogram. All aspects of the generation and +// histogram are timed so the user can see how long various JudyL functions +// take. +// +// +// This demonstrates: +// JLI (JudyLIns) +// JLF (JudyLFirst) +// JLL (JudyLLast) +// JLN (JudyLNext) +// JLC (JudyLCount) +// JLBC (JudyLByCount) +// how to access a JudyL value. +// +// Notice that using JudyL gives you fast stores and lookups as with hashing +// but without having to define a hash function, initialize the hash table +// or having to predetermine a good hash table size. It also gives you a +// sorted list at the same time. +// Also notice that JudyLCount is much faster than you can sequentially +// count items in an array. +// + +#include // random() +#include // printf() +#include // gettimeofday() +#include // JL*() routines + +// Default number of iterations (number of random numbers generated) +// This may be overridden on the command line + +#define DEFAULT_ITER 1000000 + +// The number of buckets the histogram is divided into. + +#define DEFAULT_HISTO_BUCKETS 32 + +// Macro for correction english output for plurals + +#define PLURAL(count) ((count == 1) ? "" : "s") + +// timing routines + +struct timeval TBeg, TEnd; +#define STARTTm gettimeofday(&TBeg, NULL) +#define ENDTm gettimeofday(&TEnd, NULL) +#define DeltaUSec \ + ((double)(TEnd.tv_sec - TBeg.tv_sec) * 1E6 + \ + (TEnd.tv_usec - TBeg.tv_usec)) + +// End of timing routines + +int +main(int argc, char **argv) +{ + Pvoid_t PJArray = NULL; // main JudyL array + // key is random number, value is repeat count + Pvoid_t PJCount = NULL; // second JudyL array + // key is repeat count (from PJArray) + // value is count of items with the same + // repeat count + Word_t Index; // index in JudyLFirst/Next loop + PWord_t PValue; // pointer to Judy array value + PWord_t PGenCount; // pointer to generation count + Word_t num_vals; // number of randoms to generate + Word_t iter; // for loop iteration + Word_t unique_nums; // number of unique randoms generated + Word_t random_num; // random number + Word_t median; // random number + Word_t tmp1, tmp2; // temporary variable + double random_gen_time; // time to generate random numbers + Word_t histo_incr; // histogram increment + unsigned long long ran_sum = 0; // sum of all generated randoms + +// TITLE + + printf("\nJudyL demonstration: random(3M) histogram\n"); + +// SET NUMBER OF RANDOMS TO GENERATE + + if (argc != 2) + { + // SET TO DEFAULT_ITER + num_vals = DEFAULT_ITER; + printf("Usage: %s [numvals]\n", argv[0]); + printf(" Since you did not specify a number of values, %ld\n", + num_vals); + printf(" will be used as the number of random numbers to insert\n"); + printf(" into the Judy array\n"); + } + else + { +// OVERRIDE NUMBER OF RANDOMS TO GENERATE + + num_vals = atol(argv[1]); + } + +// TIME THE GENERATION OF ALL THE RANDOM NUMBERS. THIS TIME IS LATER +// +// This time is later subtracted from the insert loop time so that the +// time it takes to do the actual JudyLIns can be isolated from the +// total time. + + printf("\ntiming random number generation\n"); + STARTTm; + for (iter = num_vals; iter; iter--) + { + random(); + } /* end of random number generator time */ + ENDTm; + random_gen_time = DeltaUSec; + printf("It took %.3f sec to generate %ld random numbers\n", + random_gen_time / 1000000, num_vals); + printf(" (ie. %.3f uSec/number)\n\n", random_gen_time / num_vals); + +// REGENERATE RANDOMS AND INSERT THEM INTO A JUDYL ARRAY + + printf("Please wait while the random numbers are inserted into\n"); + printf("a JudyL array (with a usage count) ...\n"); + + STARTTm; + for (iter = num_vals; iter; iter--) + { + random_num = (Word_t)random(); + + JLI(PValue, PJArray, random_num); + + /* increment hit count */ + (*PValue)++; + + /* sum the random number */ + ran_sum += random_num; + } /* end of random number generator time */ + ENDTm; + printf("That took %.3f uSec/Index.\n", + (DeltaUSec - random_gen_time) / num_vals); + +// COUNT THE NUMBER OF ELEMENTS IN THE JUDYL ARRAY +// IE. COUNT THE NUMBER OF UNIQUE RANDOM NUMBERS + + JLC(unique_nums, PJArray, 0, -1); + printf("\nThere were %ld unique random numbers generated\n", unique_nums); + +// FIND HOW MANY NUMBERS WERE GENERATED ONCE, TWICE, ... +// +// Create a new JudyL array where the index is the count from PJArray +// and the value is a count of the number of elements with that count. + + if (unique_nums != num_vals) + { + printf("\nLooping through the entire Judy array to create a\n"); + printf("new Judy counting array (PJCount in the source code)\n"); + printf("...\n"); + + STARTTm; + Index = 0; + JLF(PValue, PJArray, Index); + while (PValue != (PWord_t)NULL) + { + JLI(PGenCount, PJCount, *PValue); + + (*PGenCount)++; // increment hit count + + JLN(PValue, PJArray, Index); + } + ENDTm; + + printf("That took %.3f Secs or %.3f uSec/Index\n\n", + DeltaUSec / 1000000, DeltaUSec / unique_nums); + +// PRINT DUPLICATES HISTOGRAM + + printf("Duplicates Histogram:\n"); + + Index = 0; + JLF(PValue, PJCount, Index); + while (PValue != (PWord_t)NULL) + { + printf(" %ld numbers were generated %ld time%s\n", + *PValue, Index, PLURAL(Index)); + + JLN(PValue, PJCount, Index); + } + } + +// PRINT DISTRIBUTION HISTOGRAM + + printf("\nCompute the random number distribution by counting index ranges\n"); + + histo_incr = ((Word_t)~0L / DEFAULT_HISTO_BUCKETS) >> 1; + + Index = 0L; + for (iter = 0; iter < DEFAULT_HISTO_BUCKETS; iter++) + { + Word_t Count; + + JLC(Count, PJArray, Index, Index + histo_incr); + printf(" %ld unique values from 0x%08lx - 0x%08lx\n", Count, + Index, Index + histo_incr); + + Index += histo_incr + 1; + + } + +// PRINT MEAN (average), +// MEDIAN (middle value, or average of two middle values) +// RANGE (low and high value) + + tmp1 = (Word_t)(ran_sum / (long long)num_vals); + printf(" mean: 0x%lx\n", tmp1); + +// If there were an even number of randoms generated, then average +// the two middle numbers. Otherwise, the mean is the middle value + if (num_vals & 1) + { + JLBC(PValue, PJArray, num_vals / 2, tmp1); + JLBC(PValue, PJArray, (num_vals / 2) + 1, tmp2); + median = (tmp1 + tmp2) / 2; + } + else + { + JLBC(PValue, PJArray, (num_vals + 1) / 2, median); + } + printf(" median: 0x%lx\n", median); + + Index = 0; + JLF(PValue, PJArray, Index); + printf("first random generated: 0x%lx\n", Index); + + Index = ~0; + JLL(PValue, PJArray, Index); + printf(" last random generated: 0x%lx\n", Index); + + return (0); + +} // main() diff --git a/feeds/p4/libjudy/src/src/apps/demo/interL.c b/feeds/p4/libjudy/src/src/apps/demo/interL.c new file mode 100644 index 000000000..9cad450a9 --- /dev/null +++ b/feeds/p4/libjudy/src/src/apps/demo/interL.c @@ -0,0 +1,31 @@ +#include +#include + +main() // Simple JudyL demo, see "run_demo" script; @(#) $Revision: 4.4 $ +{ + Pvoid_t Parray = (Pvoid_t) NULL; // empty JudyL array. + Word_t * Pvalue; // value for one index. + char line[BUFSIZ]; // input line. + Word_t index; // in JudyL array. + + printf("Interactive Judy demo program to input, sort, and list numbers.\n" + "Enter a number: "); // fflush(stdout); ? + + while (fgets(line, BUFSIZ, stdin)) // input. + { + index = strtoul(line, NULL, 0); // note: bad input => 0. + JLI(Pvalue, Parray, index); // insert index in JudyL array. + ++(*Pvalue); // count duplicates. + + printf(" Index Dups\n"); // print all saved indexes: + index = 0; // start search at zero. + JLF(Pvalue, Parray, index); // find first saved index. + + while (Pvalue != NULL) + { + printf("%12lu %5lu\n", index, *Pvalue); + JLN(Pvalue, Parray, index); // find next saved index. + } + printf("Next: "); // fflush(stdout); ? + } +} diff --git a/feeds/p4/libjudy/src/src/apps/demo/interSL.c b/feeds/p4/libjudy/src/src/apps/demo/interSL.c new file mode 100644 index 000000000..538a1dcdc --- /dev/null +++ b/feeds/p4/libjudy/src/src/apps/demo/interSL.c @@ -0,0 +1,135 @@ +// Copyright (C) 2000 - 2002 Hewlett-Packard Company +// +// This program is free software; you can redistribute it and/or modify it +// under the term of the GNU Lesser 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 Lesser General Public License +// for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// _________________ + +// @(#) $Revision: 4.5 $ $Source: /judy/src/apps/demo/interSL.c $ +// +// INTERACTIVE JUDYSL DEMO PROGRAM +// +// This program is a very simple interactive demonstration of JudySL. Text +// keywords are entered. The program uses that text as a key into a JudySL +// array and increments a usage count. +// +// Keys can be single keywords like, "mykey", or multiple words like, "now is +// the time for the quick brown fox to take the bull by the horns". +// +// The program recognizes the following keywords as special: +// +// CMD_LIST lists all the currently entered keys and their counts +// CMD_QUIT terminates the program +// +// This program demonstrates: +// +// JudySLIns +// JudySLFirst +// JudySLNext +// how to access a JudySL value +// +// Note: Using JudySL gives you fast lookups as with hashing but without +// having to define a hash function, and without having to predetermine the +// hash table size. It also gives you a sorted list at the same time. + +#include +#include +#include + +#include "Judy.h" + +// Commands recognized by the program: + +#define CMD_LIST "list" +#define CMD_QUIT "quit" + +#define PLURAL(count) ((count == 1) ? "" : "s") + +main() +{ + char Index [BUFSIZ]; // value from user. + void ** PPValue; // associated with Index. + void * PArray = (Pvoid_t) NULL; // JudySL array. + JError_t JError; // Judy error structure + char * Pc; // place in string. + +// EMIT INSTRUCTIONS: + + (void) puts ("JudySL interactive demonstration:"); + (void) puts ("When asked for input, enter some text or:"); + (void) printf ("- \"%s\" to list previously entered text or\n", CMD_LIST); + (void) printf ("- \"%s\" (or EOF) to quit the program\n\n", CMD_QUIT); + + +// ACCEPT COMMANDS: + + while (1) + { + (void) printf ("\nEnter key/list/quit: "); + (void) fflush (stdout); + + if (fgets (Index, BUFSIZ, stdin) == (char *) NULL) + break; + + if ((Pc = strchr (Index, '\n')) != (char *) NULL) + *Pc = '\0'; // strip trailing newline. + +// QUIT: + + if (! strcmp (Index, CMD_QUIT)) break; + + +// LIST ALL INPUT IN ALPHABETICAL ORDER: + + if (! strcmp (Index, CMD_LIST)) + { + Index[0] = '\0'; + + for (PPValue = JudySLFirst (PArray, Index, 0); + PPValue != (PPvoid_t) NULL; + PPValue = JudySLNext (PArray, Index, 0)) + { + (void) printf (" \"%s\" stored %lu time%s\n", + Index, *((PWord_t) PPValue), + PLURAL (*((PWord_t) PPValue))); + } + + continue; + } + + +// ALL OTHER VALUES ARE KEYS: +// +// Insert Index into the array. If Index already exists, JudySLIns() returns a +// pointer to the old value. If Index doesn't already exist, then a slot is +// created and a pointer to this slot (initialized to zero) is returned. + + if ((PPValue = JudySLIns (& PArray, Index, &JError)) == PPJERR) + { // assume out of memory. + (void) printf ("Error %d, cannot insert \"%s\" in array.\n", + JU_ERRNO(&JError), Index); + exit (1); + } + + ++(*((PWord_t) PPValue)); // increment usage count. + + (void) printf (" \"%s\" stored %ld time%s\n", + Index, *((PWord_t) PPValue), + PLURAL (*((PWord_t) PPValue))); + + } // while 1 (continuous loop until user quits) + + exit (0); + /*NOTREACHED*/ + +} // main() diff --git a/feeds/p4/libjudy/src/src/apps/demo/run_demo b/feeds/p4/libjudy/src/src/apps/demo/run_demo new file mode 100755 index 000000000..5a94b4595 --- /dev/null +++ b/feeds/p4/libjudy/src/src/apps/demo/run_demo @@ -0,0 +1,64 @@ +# @(#) $Revision: 4.4 $ $Source: /judy/src/apps/demo/run_demo $ + +# Simple Judy example script. See the first block of text below, or just run +# this with no arguments. + + BASE='interL' + PROGRAM="$BASE.c" + COMPILE="cc -I../.. -o $BASE $PROGRAM `find ../../ -name libJudy.a`" + + set -e # exit if anything goes wrong. + + +# GREET THE USER: + + cat <<-'EOF' + This script illustrates a simple program that calls the Judy library, + shows how to compile it, and then runs it for you. + + The program reads numbers from standard input and stores them in a + JudyL array as array indexes. The target value associated with each + number (index) is the number of times it was duplicated in the input. + Exit with ^D or ^C. + + Press RETURN to continue and view the program source code... + EOF + + read input + + +# SHOW THE SAMPLE C PROGRAM: + + echo '____________________________________' + echo + + cat $PROGRAM + + echo + echo 'Press RETURN to continue...' + read input + + +# COMPILE THE SAMPLE C PROGRAM: + + cat <<-EOF + + To compile this program with the Judy library already installed on your + system, the simplest command line is: + + $COMPILE + + Press RETURN to continue and compile the program source code... + EOF + + read input + $COMPILE + + +# RUN THE SAMPLE C PROGRAM: + + echo + echo "Press RETURN to run the sample program \"$BASE\"..." + read input + + ./$BASE diff --git a/feeds/p4/libjudy/src/src/build.bat b/feeds/p4/libjudy/src/src/build.bat new file mode 100755 index 000000000..7c7432f93 --- /dev/null +++ b/feeds/p4/libjudy/src/src/build.bat @@ -0,0 +1,185 @@ +@ECHO OFF + +echo Set Compiler +SET CC=cl + +echo Set Options +SET COPT=-DJU_WIN +SET O=-DJUDY1 +SET L=-DJUDYL +SET INC=-I.. -I..\JudyCommon + +echo Deleting Old Files +del JudyCommon\*.obj JudySL\*.obj JudyHS\*.obj Judy1\*.obj JudyL\*.obj *.dll + +echo Giving Judy1 the proper Names +copy JudyCommon\JudyByCount.c Judy1\Judy1ByCount.c +copy JudyCommon\JudyCascade.c Judy1\Judy1Cascade.c +copy JudyCommon\JudyCount.c Judy1\Judy1Count.c +copy JudyCommon\JudyCreateBranch.c Judy1\Judy1CreateBranch.c +copy JudyCommon\JudyDecascade.c Judy1\Judy1Decascade.c +copy JudyCommon\JudyDel.c Judy1\Judy1Unset.c +copy JudyCommon\JudyFirst.c Judy1\Judy1First.c +copy JudyCommon\JudyFreeArray.c Judy1\Judy1FreeArray.c +copy JudyCommon\JudyGet.c Judy1\Judy1Test.c +copy JudyCommon\JudyGet.c Judy1\j__udy1Test.c +copy JudyCommon\JudyInsArray.c Judy1\Judy1SetArray.c +copy JudyCommon\JudyIns.c Judy1\Judy1Set.c +copy JudyCommon\JudyInsertBranch.c Judy1\Judy1InsertBranch.c +copy JudyCommon\JudyMallocIF.c Judy1\Judy1MallocIF.c +copy JudyCommon\JudyMemActive.c Judy1\Judy1MemActive.c +copy JudyCommon\JudyMemUsed.c Judy1\Judy1MemUsed.c +copy JudyCommon\JudyPrevNext.c Judy1\Judy1Next.c +copy JudyCommon\JudyPrevNext.c Judy1\Judy1Prev.c +copy JudyCommon\JudyPrevNextEmpty.c Judy1\Judy1NextEmpty.c +copy JudyCommon\JudyPrevNextEmpty.c Judy1\Judy1PrevEmpty.c +copy JudyCommon\JudyTables.c Judy1\Judy1TablesGen.c + +echo Giving JudyL the proper Names +copy JudyCommon\JudyByCount.c JudyL\JudyLByCount.c +copy JudyCommon\JudyCascade.c JudyL\JudyLCascade.c +copy JudyCommon\JudyCount.c JudyL\JudyLCount.c +copy JudyCommon\JudyCreateBranch.c JudyL\JudyLCreateBranch.c +copy JudyCommon\JudyDecascade.c JudyL\JudyLDecascade.c +copy JudyCommon\JudyDel.c JudyL\JudyLDel.c +copy JudyCommon\JudyFirst.c JudyL\JudyLFirst.c +copy JudyCommon\JudyFreeArray.c JudyL\JudyLFreeArray.c +copy JudyCommon\JudyGet.c JudyL\JudyLGet.c +copy JudyCommon\JudyGet.c JudyL\j__udyLGet.c +copy JudyCommon\JudyInsArray.c JudyL\JudyLInsArray.c +copy JudyCommon\JudyIns.c JudyL\JudyLIns.c +copy JudyCommon\JudyInsertBranch.c JudyL\JudyLInsertBranch.c +copy JudyCommon\JudyMallocIF.c JudyL\JudyLMallocIF.c +copy JudyCommon\JudyMemActive.c JudyL\JudyLMemActive.c +copy JudyCommon\JudyMemUsed.c JudyL\JudyLMemUsed.c +copy JudyCommon\JudyPrevNext.c JudyL\JudyLNext.c +copy JudyCommon\JudyPrevNext.c JudyL\JudyLPrev.c +copy JudyCommon\JudyPrevNextEmpty.c JudyL\JudyLNextEmpty.c +copy JudyCommon\JudyPrevNextEmpty.c JudyL\JudyLPrevEmpty.c +copy JudyCommon\JudyTables.c JudyL\JudyLTablesGen.c + + +echo Compile JudyCommon\JudyMalloc - common to Judy1 and JudyL +cd JudyCommon +%CC% -I. -I.. -DJU_WIN -c JudyMalloc.c + +cd .. + +echo This table is constructed from Juudy1.h data to match malloc(3) needs +cd Judy1 +%CC% %INC% %COPT% %O% Judy1TablesGen.c -o Judy1TablesGen +del Judy1TablesGen.obj +Judy1TablesGen +%CC% %INC% %COPT% %O% -c Judy1Tables.c + +echo compile the main line Judy1 modules +echo %CC% %INC% %COPT% %O% -c Judy1Test.c +%CC% %INC% %COPT% %O% -c Judy1Test.c +echo %CC% %INC% %COPT% %O% -c -DJUDYGETINLINE j__udy1Test.c +%CC% %INC% %COPT% %O% -c -DJUDYGETINLINE j__udy1Test.c +echo %CC% %INC% %COPT% %O% -c Judy1Set.c +%CC% %INC% %COPT% %O% -c Judy1Set.c +echo %CC% %INC% %COPT% %O% -c Judy1SetArray.c +%CC% %INC% %COPT% %O% -c Judy1SetArray.c +echo %CC% %INC% %COPT% %O% -c Judy1Unset.c +%CC% %INC% %COPT% %O% -c Judy1Unset.c +echo %CC% %INC% %COPT% %O% -c Judy1First.c +%CC% %INC% %COPT% %O% -c Judy1First.c +echo %CC% %INC% %COPT% %O% -DJUDYNEXT -c Judy1Next.c +%CC% %INC% %COPT% %O% -DJUDYNEXT -c Judy1Next.c +echo %CC% %INC% %COPT% %O% -DJUDYPREV -c Judy1Prev.c +%CC% %INC% %COPT% %O% -DJUDYPREV -c Judy1Prev.c +echo %CC% %INC% %COPT% %O% -DJUDYNEXT -c Judy1NextEmpty.c +%CC% %INC% %COPT% %O% -DJUDYNEXT -c Judy1NextEmpty.c +echo %CC% %INC% %COPT% %O% -DJUDYPREV -c Judy1PrevEmpty.c +%CC% %INC% %COPT% %O% -DJUDYPREV -c Judy1PrevEmpty.c +echo %CC% %INC% %COPT% %O% -c Judy1Count.c +%CC% %INC% %COPT% %O% -c Judy1Count.c +echo %CC% %INC% %COPT% %O% -c -DNOSMARTJBB -DNOSMARTJBU -DNOSMARTJLB Judy1ByCount.c +%CC% %INC% %COPT% %O% -c -DNOSMARTJBB -DNOSMARTJBU -DNOSMARTJLB Judy1ByCount.c +echo %CC% %INC% %COPT% %O% -c Judy1FreeArray.c +%CC% %INC% %COPT% %O% -c Judy1FreeArray.c +echo %CC% %INC% %COPT% %O% -c Judy1MemUsed.c +%CC% %INC% %COPT% %O% -c Judy1MemUsed.c +echo %CC% %INC% %COPT% %O% -c Judy1MemActive.c +%CC% %INC% %COPT% %O% -c Judy1MemActive.c +echo %CC% %INC% %COPT% %O% -c Judy1Cascade.c +%CC% %INC% %COPT% %O% -c Judy1Cascade.c +echo %CC% %INC% %COPT% %O% -c Judy1Decascade.c +%CC% %INC% %COPT% %O% -c Judy1Decascade.c +echo %CC% %INC% %COPT% %O% -c Judy1CreateBranch.c +%CC% %INC% %COPT% %O% -c Judy1CreateBranch.c +echo %CC% %INC% %COPT% %O% -c Judy1InsertBranch.C +%CC% %INC% %COPT% %O% -c Judy1InsertBranch.C +echo %CC% %INC% %COPT% %O% -c Judy1MallocIF.c +%CC% %INC% %COPT% %O% -c Judy1MallocIF.c + +cd .. +cd JudyL + +echo This table is constructed from Juudy1.h data to match malloc(3) needs +%CC% %INC% %COPT% JudyLTablesGen.c %L% -o JudyLTablesGen +del JudyLTablesGen.obj +JudyLTablesGen +%CC% %INC% %COPT% %L% -c JudyLTables.c + +echo compile the main line JudyL modules +echo %CC% %INC% %COPT% %L% -c JudyLGet.c +%CC% %INC% %COPT% %L% -c JudyLGet.c +echo %CC% %INC% %COPT% %L% -c -DJUDYGETINLINE j__udyLGet.c +%CC% %INC% %COPT% %L% -c -DJUDYGETINLINE j__udyLGet.c +echo %CC% %INC% %COPT% %L% -c JudyLIns.c +%CC% %INC% %COPT% %L% -c JudyLIns.c +echo %CC% %INC% %COPT% %L% -c JudyLInsArray.c +%CC% %INC% %COPT% %L% -c JudyLInsArray.c +echo %CC% %INC% %COPT% %L% -c JudyLDel.c +%CC% %INC% %COPT% %L% -c JudyLDel.c +echo %CC% %INC% %COPT% %L% -c JudyLFirst.c +%CC% %INC% %COPT% %L% -c JudyLFirst.c +echo %CC% %INC% %COPT% %L% -c -DJUDYNEXT JudyLNext.c +%CC% %INC% %COPT% %L% -c -DJUDYNEXT JudyLNext.c +echo %CC% %INC% %COPT% %L% -c -DJUDYPREV JudyLPrev.c +%CC% %INC% %COPT% %L% -c -DJUDYPREV JudyLPrev.c +echo %CC% %INC% %COPT% %L% -c -DJUDYNEXT JudyLNextEmpty.c +%CC% %INC% %COPT% %L% -c -DJUDYNEXT JudyLNextEmpty.c +echo %CC% %INC% %COPT% %L% -c -DJUDYPREV JudyLPrevEmpty.c +%CC% %INC% %COPT% %L% -c -DJUDYPREV JudyLPrevEmpty.c +echo %CC% %INC% %COPT% %L% -c JudyLCount.c +%CC% %INC% %COPT% %L% -c JudyLCount.c +echo %CC% %INC% %COPT% %L% -c -DNOSMARTJBB -DNOSMARTJBU -DNOSMARTJLB JudyLByCount.c +%CC% %INC% %COPT% %L% -c -DNOSMARTJBB -DNOSMARTJBU -DNOSMARTJLB JudyLByCount.c +echo %CC% %INC% %COPT% %L% -c JudyLFreeArray.c +%CC% %INC% %COPT% %L% -c JudyLFreeArray.c +echo %CC% %INC% %COPT% %L% -c JudyLMemUsed.c +%CC% %INC% %COPT% %L% -c JudyLMemUsed.c +echo %CC% %INC% %COPT% %L% -c JudyLMemActive.c +%CC% %INC% %COPT% %L% -c JudyLMemActive.c +echo %CC% %INC% %COPT% %L% -c JudyLCascade.c +%CC% %INC% %COPT% %L% -c JudyLCascade.c +echo %CC% %INC% %COPT% %L% -c JudyLDecascade.c +%CC% %INC% %COPT% %L% -c JudyLDecascade.c +echo %CC% %INC% %COPT% %L% -c JudyLCreateBranch.c +%CC% %INC% %COPT% %L% -c JudyLCreateBranch.c +echo %CC% %INC% %COPT% %L% -c JudyLInsertBranch.c +%CC% %INC% %COPT% %L% -c JudyLInsertBranch.c +echo %CC% %INC% %COPT% %L% -c JudyLMallocIF.c +%CC% %INC% %COPT% %L% -c JudyLMallocIF.c + +cd .. +cd JudySL +echo Compile the JudySL routine +echo %CC% %INC% %COPT% -c JudySL.c +%CC% %INC% %COPT% -c JudySL.c + +cd .. +cd JudyHS +echo Compile the JudyHS routine +echo %CC% %INC% %COPT% -c JudyHS.c +%CC% %INC% %COPT% -c JudyHS.c + +cd .. +echo Make a Judy dll by linking all the objects togeather +link /DLL JudyCommon\*.obj Judy1\*.obj JudyL\*.obj JudySL\*.obj JudyHS\*.obj /OUT:Judy.dll + +echo Make a Judy archive library by linking all the objects togeather +link /LIB JudyCommon\*.obj Judy1\*.obj JudyL\*.obj JudySL\*.obj JudyHS\*.obj /OUT:Judy.lib diff --git a/feeds/p4/libjudy/src/src/obj/Makefile.am b/feeds/p4/libjudy/src/src/obj/Makefile.am new file mode 100644 index 000000000..7195238b0 --- /dev/null +++ b/feeds/p4/libjudy/src/src/obj/Makefile.am @@ -0,0 +1,15 @@ +AM_CFLAGS = @WARN_CFLAGS@ + +CLEANFILES = libJudy.la + +include_HEADERS = ../Judy.h + +lib_LTLIBRARIES = libJudy.la + +libJudy_la_SOURCES = + +libJudy_la_LIBADD = ../JudyCommon/*.lo ../JudyL/*.lo ../Judy1/*.lo ../JudyHS/*.lo ../JudySL/*.lo + +libJudy_la_LDFLAGS = @VERSION_INFO@ + +DISTCLEANFILES = .deps Makefile diff --git a/feeds/p4/libjudy/src/src/sh_build b/feeds/p4/libjudy/src/src/sh_build new file mode 100755 index 000000000..743fca297 --- /dev/null +++ b/feeds/p4/libjudy/src/src/sh_build @@ -0,0 +1,206 @@ +echo "--- This is a compile kit to suggest how to port to your machine" +echo "--- This script runs in 7 seconds on a 3.2Ghz Pentium P4C" +echo "--- Must be in the 'src' directory to execute this script" +echo "--- I normally run it like: COPT='-O3 -march=i686' sh_build" + +echo "--- Set Compiler" +CC='cc' + +echo "--- Set Optimization" +# COPT='-O' + +echo "--- Set Shared library option" +# CPIC='-fPIC +CPIC='' + +echo "--- Compile JudyMalloc - common to Judy1 and JudyL" +echo "--- cd JudyCommon" +cd JudyCommon +rm -f *.o +$CC $COPT $CPIC -I. -I.. -c JudyMalloc.c +echo "--- cd .." +cd .. + +echo "--- Give Judy1 the proper names" +echo "--- cd Judy1" +cd Judy1 +rm -f *.o +ln -sf ../JudyCommon/JudyByCount.c Judy1ByCount.c +ln -sf ../JudyCommon/JudyCascade.c Judy1Cascade.c +ln -sf ../JudyCommon/JudyCount.c Judy1Count.c +ln -sf ../JudyCommon/JudyCreateBranch.c Judy1CreateBranch.c +ln -sf ../JudyCommon/JudyDecascade.c Judy1Decascade.c +ln -sf ../JudyCommon/JudyDel.c Judy1Unset.c +ln -sf ../JudyCommon/JudyFirst.c Judy1First.c +ln -sf ../JudyCommon/JudyFreeArray.c Judy1FreeArray.c +ln -sf ../JudyCommon/JudyGet.c Judy1Test.c +ln -sf ../JudyCommon/JudyGet.c j__udy1Test.c +ln -sf ../JudyCommon/JudyInsArray.c Judy1SetArray.c +ln -sf ../JudyCommon/JudyIns.c Judy1Set.c +ln -sf ../JudyCommon/JudyInsertBranch.c Judy1InsertBranch.c +ln -sf ../JudyCommon/JudyMallocIF.c Judy1MallocIF.c +ln -sf ../JudyCommon/JudyMemActive.c Judy1MemActive.c +ln -sf ../JudyCommon/JudyMemUsed.c Judy1MemUsed.c +ln -sf ../JudyCommon/JudyPrevNext.c Judy1Next.c +ln -sf ../JudyCommon/JudyPrevNext.c Judy1Prev.c +ln -sf ../JudyCommon/JudyPrevNextEmpty.c Judy1NextEmpty.c +ln -sf ../JudyCommon/JudyPrevNextEmpty.c Judy1PrevEmpty.c +ln -sf ../JudyCommon/JudyTables.c Judy1TablesGen.c + + +echo "--- This table is constructed from Judy1.h data to match malloc(3) needs" +echo "--- $CC $COPT -I. -I.. -I../JudyCommon -DJUDY1 Judy1TablesGen.c -o Judy1TablesGen" +$CC $COPT -I. -I.. -I../JudyCommon -DJUDY1 Judy1TablesGen.c -o Judy1TablesGen +rm -f *.o +./Judy1TablesGen +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 Judy1Tables.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 Judy1Tables.c + +echo "--- Compile the main line Judy1 modules" +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 Judy1Test.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 Judy1Test.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 -DJUDYGETINLINE j__udy1Test.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 -DJUDYGETINLINE j__udy1Test.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 Judy1Set.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 Judy1Set.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 Judy1SetArray.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 Judy1SetArray.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 Judy1Unset.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 Judy1Unset.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 Judy1First.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 Judy1First.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 -DJUDYNEXT Judy1Next.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 -DJUDYNEXT Judy1Next.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 -DJUDYPREV Judy1Prev.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 -DJUDYPREV Judy1Prev.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 -DJUDYNEXT Judy1NextEmpty.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 -DJUDYNEXT Judy1NextEmpty.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 -DJUDYPREV Judy1PrevEmpty.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 -DJUDYPREV Judy1PrevEmpty.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 Judy1Count.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 Judy1Count.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 -DNOSMARTJBB -DNOSMARTJBU -DNOSMARTJLB Judy1ByCount.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 -DNOSMARTJBB -DNOSMARTJBU -DNOSMARTJLB Judy1ByCount.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 Judy1FreeArray.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 Judy1FreeArray.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 Judy1MemUsed.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 Judy1MemUsed.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 Judy1MemActive.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 Judy1MemActive.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 Judy1Cascade.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 Judy1Cascade.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 Judy1Decascade.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 Judy1Decascade.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 Judy1CreateBranch.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 Judy1CreateBranch.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 Judy1InsertBranch.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 Judy1InsertBranch.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 Judy1MallocIF.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDY1 Judy1MallocIF.c +echo "--- cd .." +cd .. + +echo "--- Give JudyL the proper names" +echo "--- cd JudyL" +cd JudyL +rm -f *.o +ln -sf ../JudyCommon/JudyByCount.c JudyLByCount.c +ln -sf ../JudyCommon/JudyCascade.c JudyLCascade.c +ln -sf ../JudyCommon/JudyCount.c JudyLCount.c +ln -sf ../JudyCommon/JudyCreateBranch.c JudyLCreateBranch.c +ln -sf ../JudyCommon/JudyDecascade.c JudyLDecascade.c +ln -sf ../JudyCommon/JudyDel.c JudyLDel.c +ln -sf ../JudyCommon/JudyFirst.c JudyLFirst.c +ln -sf ../JudyCommon/JudyFreeArray.c JudyLFreeArray.c +ln -sf ../JudyCommon/JudyGet.c JudyLGet.c +ln -sf ../JudyCommon/JudyGet.c j__udyLGet.c +ln -sf ../JudyCommon/JudyInsArray.c JudyLInsArray.c +ln -sf ../JudyCommon/JudyIns.c JudyLIns.c +ln -sf ../JudyCommon/JudyInsertBranch.c JudyLInsertBranch.c +ln -sf ../JudyCommon/JudyMallocIF.c JudyLMallocIF.c +ln -sf ../JudyCommon/JudyMemActive.c JudyLMemActive.c +ln -sf ../JudyCommon/JudyMemUsed.c JudyLMemUsed.c +ln -sf ../JudyCommon/JudyPrevNext.c JudyLNext.c +ln -sf ../JudyCommon/JudyPrevNext.c JudyLPrev.c +ln -sf ../JudyCommon/JudyPrevNextEmpty.c JudyLNextEmpty.c +ln -sf ../JudyCommon/JudyPrevNextEmpty.c JudyLPrevEmpty.c +ln -sf ../JudyCommon/JudyTables.c JudyLTablesGen.c + +echo "--- This table is constructed from JudyL.h data to match malloc(3) needs" +echo "--- $CC $COPT -I. -I.. -I../JudyCommon -DJUDYL JudyLTablesGen.c -o JudyLTablesGen" +$CC $COPT -I. -I.. -I../JudyCommon -DJUDYL JudyLTablesGen.c -o JudyLTablesGen +rm -f *.o +./JudyLTablesGen +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL JudyLTables.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL JudyLTables.c + +echo "--- Compile the main line JudyL modules" +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL JudyLGet.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL JudyLGet.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL -DJUDYGETINLINE j__udyLGet.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL -DJUDYGETINLINE j__udyLGet.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL JudyLIns.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL JudyLIns.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL JudyLIns.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL JudyLInsArray.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL JudyLDel.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL JudyLDel.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL JudyLFirst.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL JudyLFirst.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL -DJUDYNEXT JudyLNext.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL -DJUDYNEXT JudyLNext.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL -DJUDYPREV JudyLPrev.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL -DJUDYPREV JudyLPrev.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL -DJUDYNEXT JudyLNextEmpty.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL -DJUDYNEXT JudyLNextEmpty.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL -DJUDYPREV JudyLPrevEmpty.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL -DJUDYPREV JudyLPrevEmpty.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL JudyLCount.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL JudyLCount.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL -DNOSMARTJBB -DNOSMARTJBU -DNOSMARTJLB JudyLByCount.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL -DNOSMARTJBB -DNOSMARTJBU -DNOSMARTJLB JudyLByCount.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL JudyLFreeArray.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL JudyLFreeArray.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL JudyLMemUsed.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL JudyLMemUsed.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL JudyLMemActive.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL JudyLMemActive.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL JudyLCascade.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL JudyLCascade.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL JudyLDecascade.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL JudyLDecascade.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL JudyLCreateBranch.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL JudyLCreateBranch.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL JudyLInsertBranch.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL JudyLInsertBranch.c +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL JudyLMallocIF.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c -DJUDYL JudyLMallocIF.c +echo "--- cd .." +cd .. + +echo "--- Compile the JudySL routine" +echo "--- cd JudySL" +cd JudySL +rm -f *.o +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c JudySL.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c JudySL.c +echo "--- cd .." +cd .. +echo "--- Compile the JudyHS routine" +echo "--- cd JudyHS" +cd JudyHS +rm -f *.o +echo "--- $CC $COPT $CPIC -I. -I.. -I../JudyCommon -c JudyHS.c" +$CC $COPT $CPIC -I. -I.. -I../JudyCommon -c JudyHS.c +echo "--- cd .." +cd .. + +# Make a Judy shared library with CPIC='-fPIC' above +#ld -shared -o libJudy.so Judy*/*.o +# +# -OR- +# +echo "--- Make a Judy static library" +ar -r libJudy.a Judy*/*.o + +echo "--- Done" diff --git a/feeds/p4/libjudy/src/test/Centrino_1.3Mhz_Plots/Hash_CO.plot b/feeds/p4/libjudy/src/test/Centrino_1.3Mhz_Plots/Hash_CO.plot new file mode 100644 index 000000000..b4d2f0aac --- /dev/null +++ b/feeds/p4/libjudy/src/test/Centrino_1.3Mhz_Plots/Hash_CO.plot @@ -0,0 +1,565 @@ +# StringCompare -n14962357 -A Hash -H1048576 -P40 -L10 -C -M100000 /home/data/domnames.txt +# This file is in a format to input to 'jbgraph' +# XLABEL Stored +# YLABEL Microseconds / Index +# COLHEAD 1 Total Insert attempts +# COLHEAD 2 Number Gets +# COLHEAD 3 Duplicate strings +# COLHEAD 4 Insert Time (uS) +# COLHEAD 5 Get Time (uS) +# COLHEAD 6 Hash Chain Length +# COLHEAD 7 Average RAM/String +# Linux localhost 2.6.3-4mdkenterprise #1 SMP Tue Mar 2 07:00:53 CET 2004 i686 +# 32 Bit CPU +# Processor speed compiled at 1299 Mhz +# Hash record struct: sizeof(hrec_t) = 16 +# Allocate Hash table = 1048576 elements +# 11218731 (75.0%) non-Word_t aligned string buffers +# Ram used for input data = 372621771 bytes +# Average string length = 15.9 bytes +# 3200000 bytes malloc() for 'cached' strings for Get measurement +# Access Time = 0.103 uS average per string (mostly from Cache) +# HashStr() Time = 0.270 uS average per string (mostly from Cache) +# Access Time = 0.287 uS average per string (mostly from RAM) +# HashStr() Time = 0.477 uS average per string (mostly from RAM) +# Pass 0 +# TotInserts DeltaGets DupStrs InsTime GetTime HChainLen Ram/String +# 1 1 0 5775.911 1.182 1.000000 4194356.0 +# 2 2 0 3.406 0.417 1.000000 2097190.0 +# 3 3 0 1.251 0.374 1.000000 1398136.0 +# 4 4 0 1.465 0.380 1.000000 1048610.0 +# 5 5 0 1.154 0.363 1.000000 838893.6 +# 6 6 0 0.996 0.347 1.000000 699082.0 +# 7 7 0 1.109 0.356 1.000000 599217.7 +# 8 8 0 1.564 0.347 1.000000 524318.5 +# 9 9 0 1.189 0.355 1.000000 466064.4 +# 10 10 0 1.176 0.352 1.000000 419460.8 +# 11 11 0 1.268 0.359 1.000000 381330.9 +# 12 12 0 1.264 0.364 1.000000 349556.0 +# 13 13 0 1.357 0.363 1.000000 322669.2 +# 14 14 0 1.467 0.364 1.000000 299623.7 +# 15 15 0 1.070 0.366 1.000000 279650.9 +# 16 16 0 1.404 0.375 1.000000 262175.0 +# 17 17 0 1.544 0.367 1.000000 246754.4 +# 18 18 0 0.851 0.364 1.000000 233047.1 +# 19 19 0 1.139 0.366 1.000000 220783.2 +# 20 20 0 1.238 0.366 1.000000 209745.4 +# 21 21 0 1.195 0.363 1.000000 199758.9 +# 22 22 0 1.176 0.365 1.000000 190680.4 +# 23 23 0 13.957 0.366 1.000000 182391.1 +# 24 24 0 1.159 0.361 1.000000 174792.5 +# 25 25 0 1.288 0.356 1.000000 167801.8 +# 26 26 0 1.179 0.357 1.000000 161348.9 +# 27 27 0 1.204 0.361 1.000000 155374.4 +# 28 28 0 1.125 0.359 1.000000 149826.1 +# 29 29 0 1.052 0.359 1.000000 144660.8 +# 30 30 0 2.443 0.368 1.000000 139839.6 +# 31 31 0 1.527 0.368 1.000000 135330.2 +# 32 32 0 1.390 0.365 1.000000 131102.0 +# 34 34 0 1.179 0.365 1.000000 123391.6 +# 36 36 0 1.034 0.366 1.000000 116538.3 +# 38 38 0 1.010 0.368 1.000000 110406.4 +# 40 40 0 1.142 0.367 1.000000 104887.5 +# 42 42 0 0.941 0.366 1.000000 99894.2 +# 44 44 0 1.292 0.368 1.000000 95355.0 +# 46 46 0 1.072 0.369 1.000000 91210.5 +# 48 48 0 0.946 0.365 1.000000 87411.2 +# 50 50 0 1.057 0.375 1.000000 83916.0 +# 53 53 0 1.134 0.368 1.000000 79168.0 +# 56 56 0 1.022 0.367 1.000000 74928.4 +# 59 59 0 0.736 0.364 1.000000 71119.7 +# 62 62 0 1.059 0.364 1.000000 67680.0 +# 65 65 0 1.049 0.364 1.000000 64557.7 +# 69 69 0 1.011 0.365 1.000000 60816.9 +# 73 73 0 0.864 0.359 1.000000 57485.9 +# 77 77 0 0.998 0.359 1.000000 54501.0 +# 81 81 0 0.989 0.361 1.000000 51811.2 +# 85 85 0 0.977 0.362 1.000000 49374.4 +# 90 90 0 1.068 0.369 1.000000 46633.3 +# 95 95 0 0.741 0.366 1.000000 44180.3 +# 100 100 0 0.886 0.364 1.000000 41972.7 +# 106 106 0 0.892 0.362 1.000000 39598.4 +# 112 112 0 0.932 0.361 1.000000 37478.6 +# 118 118 0 0.902 0.363 1.000000 35574.5 +# 125 125 0 0.973 0.363 1.000000 33584.0 +# 132 132 0 1.011 0.362 1.000000 31804.5 +# 139 139 0 1.878 0.366 1.000000 30204.3 +# 147 147 0 0.888 0.361 1.000000 28562.1 +# 155 155 0 1.028 0.362 1.000000 27089.4 +# 164 164 0 0.903 2.031 1.000000 25604.5 +# 173 173 0 1.077 0.372 1.000000 24273.9 +# 183 183 0 0.920 0.362 1.000000 22949.1 +# 194 194 0 0.882 0.364 1.000000 21649.6 +# 205 205 0 0.909 0.363 1.000000 20489.5 +# 217 217 0 0.903 0.363 1.000000 19358.1 +# 230 230 0 0.888 0.362 1.000000 18265.5 +# 243 243 0 0.885 0.360 1.000000 17289.9 +# 257 257 0 1.200 0.360 1.000000 16349.6 +# 272 272 0 1.403 0.362 1.000000 15449.7 +# 288 288 0 0.915 0.368 1.000000 14593.1 +# 305 305 0 0.926 0.365 1.000000 13781.5 +# 323 323 0 0.933 0.366 1.000000 13015.2 +# 342 342 0 0.931 0.387 1.000000 12293.8 +# 362 362 0 0.889 0.367 1.000000 11616.2 +# 383 383 0 1.089 0.367 1.000000 10981.0 +# 405 405 0 0.866 0.368 1.000000 10386.1 +# 429 429 0 0.915 0.368 1.000000 9806.8 +# 454 454 0 0.875 0.369 1.000000 9268.3 +# 480 480 0 0.898 0.366 1.000000 8767.9 +# 508 508 0 1.044 0.380 1.000000 8286.3 +# 538 538 0 0.859 0.368 1.000000 7825.8 +# 569 569 0 0.917 0.366 1.000000 7401.0 +# 602 602 0 0.987 0.365 1.000000 6996.9 +# 637 637 0 0.888 0.364 1.000000 6614.1 +# 674 674 0 0.918 0.375 1.001484 6252.6 +# 714 714 0 0.983 0.367 1.001401 5904.0 +# 756 756 0 0.860 0.373 1.001323 5577.6 +# 800 800 0 0.874 0.365 1.001250 5272.5 +# 847 847 0 0.963 0.372 1.001181 4981.5 +# 897 897 0 0.883 0.363 1.001115 4705.5 +# 950 950 0 0.968 0.372 1.001053 4444.6 +# 1006 1006 0 0.911 0.364 1.000994 4198.8 +# 1065 1065 0 1.088 0.366 1.001878 3967.9 +# 1128 1128 0 0.888 0.369 1.001773 3747.9 +# 1194 1194 0 0.942 0.372 1.001675 3542.4 +# 1264 1264 0 0.864 0.365 1.001582 3347.8 +# 1339 1339 0 0.908 0.367 1.001494 3162.0 +# 1418 1418 0 0.913 0.366 1.001410 2987.4 +# 1502 1502 0 0.849 0.367 1.001332 2822.0 +# 1591 1591 0 0.922 0.369 1.001257 2665.8 +# 1685 1685 0 0.903 0.369 1.001187 2518.7 +# 1784 1784 0 0.880 0.370 1.001121 2380.6 +# 1884 1884 0 0.879 0.375 1.001062 2255.7 +# 1995 1995 0 0.921 0.388 1.001504 2131.9 +# 2113 2113 0 0.895 0.379 1.001420 2014.5 +# 2239 2239 0 0.858 0.380 1.001340 1902.7 +# 2371 2371 0 0.884 0.386 1.001265 1798.4 +# 2512 2512 0 0.918 0.392 1.001194 1699.1 +# 2661 2661 0 0.865 0.411 1.001503 1605.6 +# 2818 2818 0 0.897 0.407 1.002129 1517.8 +# 2985 2985 0 0.859 0.444 1.002010 1434.5 +# 3162 3162 0 0.931 0.439 1.001898 1355.9 +# 3350 3350 0 0.863 0.428 1.002388 1281.5 +# 3548 3548 0 0.879 0.434 1.002537 1211.6 +# 3758 3758 0 0.934 0.450 1.002661 1145.5 +# 3981 3981 0 0.908 0.459 1.002763 1083.0 +# 4217 4217 0 0.908 0.469 1.003083 1024.1 +# 4467 4467 0 0.905 0.477 1.002910 968.4 +# 4732 4732 0 0.869 0.487 1.002747 915.8 +# 5012 5012 0 0.918 0.499 1.003192 866.3 +# 5309 5309 0 0.868 0.508 1.003390 819.5 +# 5623 5623 0 0.887 0.515 1.003913 775.4 +# 5957 5957 0 0.906 0.520 1.004532 733.6 +# 6310 6310 0 0.887 0.559 1.004596 694.2 +# 6683 6683 0 0.916 0.532 1.004788 657.1 +# 7079 7079 0 0.897 0.535 1.004662 622.0 +# 7499 7499 0 0.904 0.544 1.004534 588.8 +# 7943 7943 0 0.911 0.618 1.004658 557.5 +# 8414 8414 0 0.918 0.559 1.004635 528.0 +# 8913 8913 0 1.030 0.614 1.004937 500.1 +# 9441 9441 0 0.989 0.551 1.005614 473.7 +# 10000 10000 0 0.930 0.552 1.005500 448.9 +# 10593 10593 0 0.923 0.629 1.005947 425.4 +# 11220 11220 0 0.929 0.556 1.005793 403.3 +# 11885 11885 0 0.914 0.574 1.005890 382.4 +# 12589 12589 0 0.906 0.583 1.006116 362.6 +# 13335 13335 0 0.919 0.561 1.006224 344.0 +# 14125 14125 0 0.912 0.576 1.006796 326.4 +# 14962 14962 0 1.057 0.565 1.007018 309.8 +# 15849 15849 0 0.903 0.568 1.007193 294.1 +# 16788 16788 0 0.896 0.575 1.007744 279.3 +# 17783 17783 0 1.004 0.572 1.008154 265.3 +# 18836 18836 0 0.908 0.575 1.008335 252.1 +# 19953 19953 0 0.918 0.593 1.008871 239.6 +# 21135 21135 0 0.913 0.580 1.009558 227.9 +# 22387 22387 0 0.911 0.593 1.010184 216.8 +# 23714 23714 0 0.910 0.598 1.010880 206.3 +# 25119 25119 0 0.901 0.605 1.011744 196.4 +# 26607 26607 0 0.919 0.590 1.012553 187.1 +# 28184 28184 0 0.896 0.598 1.013163 178.2 +# 29854 29854 0 0.888 0.603 1.013633 169.9 +# 31623 31623 0 1.012 0.597 1.014704 162.1 +# 33497 33497 0 0.889 0.608 1.015554 154.6 +# 35481 35481 0 0.902 0.617 1.016319 147.6 +# 37584 37584 0 0.895 0.605 1.017481 141.0 +# 39811 39811 0 0.896 0.617 1.018337 134.8 +# 42170 42170 0 0.892 0.609 1.019753 128.9 +# 44668 44668 0 0.893 0.617 1.021201 123.3 +# 47315 47315 0 0.895 0.613 1.022678 118.1 +# 50119 50119 0 0.894 0.627 1.024322 113.1 +# 53088 53088 0 0.891 0.618 1.025599 108.4 +# 56234 56234 0 0.937 0.632 1.026728 104.0 +# 59566 59566 0 0.886 0.625 1.027734 99.8 +# 63096 63096 0 1.071 0.627 1.029923 95.9 +# 66834 66834 0 0.927 0.635 1.031825 92.2 +# 70795 70795 0 0.883 0.634 1.033703 88.7 +# 74989 74989 0 0.914 0.631 1.035152 85.4 +# 79433 79433 0 0.879 0.632 1.037453 82.2 +# 84140 84140 0 0.887 0.635 1.039458 79.3 +# 89125 89125 0 0.884 0.636 1.042098 76.5 +# 94406 94406 0 0.885 0.638 1.044764 73.8 +# 100000 100000 0 0.881 0.639 1.047350 71.3 +# 105925 100000 0 0.884 0.640 1.050080 69.0 +# 112202 100000 0 0.919 0.662 1.053600 66.8 +# 118850 100000 0 0.897 0.647 1.057100 64.7 +# 125893 100000 0 0.901 0.652 1.059820 62.7 +# 133352 100000 0 0.884 0.651 1.063240 60.9 +# 141254 100000 0 0.888 0.650 1.067290 59.1 +# 149624 100000 0 0.916 0.653 1.071780 57.4 +# 158489 100000 0 0.940 0.657 1.075130 55.9 +# 167880 100000 0 0.913 0.659 1.082310 54.4 +# 177828 100000 0 0.899 0.671 1.085360 53.0 +# 188365 100000 0 0.897 0.664 1.090720 51.7 +# 199526 100000 0 0.915 0.668 1.096770 50.4 +# 211349 100000 0 0.928 0.665 1.101930 49.3 +# 223872 100000 0 0.934 0.670 1.108100 48.2 +# 237137 100000 0 0.926 0.667 1.113690 47.1 +# 251189 100000 0 0.955 0.675 1.119180 46.1 +# 266073 100000 0 0.911 0.693 1.128930 45.2 +# 281838 100000 0 0.918 0.676 1.136280 44.3 +# 298538 100000 0 0.929 0.685 1.145900 43.5 +# 316228 100000 0 0.922 0.686 1.153400 42.7 +# 334965 100000 0 0.936 0.688 1.162440 41.9 +# 354813 100000 0 0.956 0.694 1.172560 41.2 +# 375837 100000 0 0.958 0.692 1.183690 40.6 +# 398107 100000 0 0.959 0.699 1.193780 40.0 +# 421697 100000 0 0.942 0.702 1.204740 39.4 +# 446684 100000 0 0.955 0.700 1.215820 38.8 +# 473151 100000 0 0.952 0.713 1.228310 38.3 +# 501187 100000 0 0.962 0.713 1.241420 37.8 +# 530884 100000 0 0.964 0.714 1.257920 37.3 +# 562341 100000 0 0.979 0.711 1.272740 36.9 +# 595662 100000 0 1.003 0.714 1.289160 36.5 +# 630957 100000 0 1.015 0.722 1.303190 36.1 +# 668344 100000 0 1.020 0.730 1.322380 35.7 +# 707946 100000 0 1.026 0.737 1.341750 35.4 +# 749894 100000 0 1.015 0.743 1.368090 35.0 +# 794328 100000 0 1.019 0.744 1.384790 34.7 +# 841395 100000 0 1.030 0.746 1.408600 34.4 +# 891251 100000 0 1.045 0.753 1.434040 34.1 +# 944061 100000 0 1.049 0.778 1.456490 33.9 +# 1000000 100000 0 1.057 0.766 1.485870 33.6 +# 1059254 100000 0 1.066 0.768 1.513600 33.4 +# 1122018 100000 0 1.106 0.778 1.542830 33.2 +# 1188502 100000 0 1.090 0.790 1.577200 33.0 +# 1258925 100000 0 1.138 0.792 1.612530 32.8 +# 1333521 100000 0 1.121 0.811 1.645650 32.6 +# 1412538 100000 0 1.135 0.810 1.682130 32.4 +# 1496236 100000 0 1.159 0.820 1.722840 32.2 +# 1584893 100000 0 1.171 0.847 1.765690 32.1 +# 1678804 100000 0 1.185 0.844 1.817750 31.9 +# 1778279 100000 0 1.202 0.853 1.864700 31.8 +# 1883649 100000 0 1.222 0.867 1.912490 31.7 +# 1995262 100000 0 1.242 0.876 1.967780 31.5 +# 2113489 100000 0 1.263 0.896 2.020420 31.4 +# 2238721 100000 0 1.286 0.922 2.075790 31.3 +# 2371374 100000 0 1.320 0.929 2.146300 31.2 +# 2511886 100000 0 1.335 0.945 2.209570 31.1 +# 2660725 100000 0 1.363 0.944 2.293110 31.0 +# 2818383 100000 0 1.391 0.960 2.360800 30.9 +# 2985383 100000 0 1.422 0.978 2.446730 30.8 +# 3162278 100000 0 1.461 1.009 2.537540 30.8 +# 3349654 100000 0 1.501 1.016 2.622900 30.7 +# 3548134 100000 0 1.533 1.060 2.710860 30.6 +# 3758374 100000 0 1.578 1.062 2.824550 30.5 +# 3981072 100000 0 1.622 1.273 2.922530 30.5 +# 4216965 100000 0 1.673 1.115 3.041830 30.4 +# 4466836 100000 0 1.729 1.160 3.149510 30.4 +# 4731513 100000 0 1.784 1.178 3.292520 30.3 +# 5011872 100000 0 1.854 1.216 3.433090 30.3 +# 5308844 100000 0 1.946 1.262 3.576600 30.2 +# 5623413 100000 0 1.958 1.262 3.719150 30.2 +# 5956621 100000 0 2.022 1.496 3.885680 30.1 +# 6309573 100000 0 2.180 1.357 4.057750 30.1 +# 6683439 100000 0 2.196 1.383 4.250390 30.1 +# 7079458 100000 0 2.257 1.431 4.444160 30.0 +# 7498942 100000 0 2.340 1.482 4.640880 30.0 +# 7943282 100000 0 2.445 1.525 4.852800 29.9 +# 8413951 100000 0 2.547 1.595 5.074780 29.9 +# 8912509 100000 0 2.691 1.656 5.320130 29.9 +# 9440609 100000 0 2.798 1.696 5.560000 29.9 +# 10000000 100000 0 2.996 1.784 5.853460 29.8 +# 10592537 100000 0 3.087 1.862 6.153020 29.8 +# 11220185 100000 0 3.233 1.922 6.430500 29.8 +# 11885022 100000 0 3.384 2.104 6.773630 29.8 +# 12589254 100000 0 3.566 2.118 7.090330 29.7 +# 13335214 100000 0 3.768 2.197 7.450920 29.7 +# 14125375 100000 0 7.923 2.316 7.868460 29.7 +# 14962357 100000 0 4.145 2.436 8.259020 29.7 +# Total Duplicate strings = 0 +# Begin HashFreeArray()... +# returned 444133848 bytes +# Free 14962357 strings, 0.312 uSecs Ave/string + +# Pass 1 +# Pass 2 +# Pass 3 +# Pass 4 +# Pass 5 +# Pass 6 +# Pass 7 +# Pass 8 +# Pass 9 +# TotInserts 0 0 InsTime GetTime 0 Ram/String + 1 0 0 5775.911 0.901 0 4194352.000 + 2 0 0 1.096 0.317 0 2097190.000 + 3 0 0 0.883 0.309 0 1398134.667 + 4 0 0 0.846 0.311 0 1048607.000 + 5 0 0 0.776 0.305 0 838890.400 + 6 0 0 0.911 0.296 0 699079.333 + 7 0 0 0.796 0.306 0 599215.429 + 8 0 0 0.711 0.302 0 524316.500 + 9 0 0 0.817 0.292 0 466061.333 + 10 0 0 0.633 0.295 0 419458.000 + 11 0 0 0.701 0.297 0 381328.000 + 12 0 0 0.732 0.307 0 349553.333 + 13 0 0 0.829 0.312 0 322667.385 + 14 0 0 0.778 0.317 0 299621.429 + 15 0 0 0.659 0.312 0 279648.267 + 16 0 0 0.871 0.319 0 262172.250 + 17 0 0 0.845 0.317 0 246752.000 + 18 0 0 0.851 0.321 0 233045.111 + 19 0 0 0.889 0.324 0 220781.263 + 20 0 0 0.923 0.329 0 209743.800 + 21 0 0 0.697 0.333 0 199757.905 + 22 0 0 0.646 0.329 0 190679.455 + 23 0 0 0.773 0.326 0 182390.261 + 24 0 0 1.035 0.325 0 174791.833 + 25 0 0 0.833 0.321 0 167801.120 + 26 0 0 0.834 0.323 0 161348.462 + 27 0 0 0.705 0.328 0 155373.778 + 28 0 0 0.666 0.331 0 149825.714 + 29 0 0 0.752 0.341 0 144660.414 + 30 0 0 0.728 0.342 0 139839.333 + 31 0 0 0.814 0.339 0 135329.290 + 32 0 0 0.931 0.339 0 131101.125 + 34 0 0 0.895 0.336 0 123391.412 + 36 0 0 0.888 0.339 0 116537.889 + 38 0 0 0.784 0.344 0 110406.526 + 40 0 0 0.985 0.348 0 104887.900 + 42 0 0 0.843 0.351 0 99894.381 + 44 0 0 0.914 0.348 0 95355.364 + 46 0 0 0.801 0.348 0 91210.609 + 48 0 0 0.875 0.347 0 87411.500 + 50 0 0 0.831 0.347 0 83916.240 + 53 0 0 0.856 0.346 0 79167.698 + 56 0 0 0.932 0.348 0 74928.286 + 59 0 0 0.736 0.346 0 71119.932 + 62 0 0 0.787 0.348 0 67680.000 + 65 0 0 0.862 0.348 0 64557.723 + 69 0 0 0.814 0.349 0 60817.043 + 73 0 0 0.864 0.350 0 57486.521 + 77 0 0 0.787 0.347 0 54501.662 + 81 0 0 0.900 0.351 0 51811.556 + 85 0 0 0.938 0.348 0 49374.824 + 90 0 0 0.947 0.347 0 46633.333 + 95 0 0 0.741 0.348 0 44180.337 + 100 0 0 0.844 0.347 0 41972.760 + 106 0 0 0.812 0.343 0 39598.604 + 112 0 0 0.899 0.347 0 37478.893 + 118 0 0 0.854 0.351 0 35574.508 + 125 0 0 0.914 0.351 0 33583.840 + 132 0 0 0.937 0.349 0 31804.333 + 139 0 0 0.902 0.352 0 30204.259 + 147 0 0 0.877 0.357 0 28562.122 + 155 0 0 0.853 0.358 0 27089.394 + 164 0 0 0.875 0.359 0 25604.463 + 173 0 0 0.833 0.359 0 24273.873 + 183 0 0 0.873 0.358 0 22948.962 + 194 0 0 0.848 0.357 0 21649.381 + 205 0 0 0.908 0.356 0 20489.190 + 217 0 0 0.876 0.358 0 19357.862 + 230 0 0 0.853 0.358 0 18265.443 + 243 0 0 0.884 0.358 0 17289.745 + 257 0 0 0.893 0.359 0 16349.479 + 272 0 0 0.857 0.358 0 15449.441 + 288 0 0 0.897 0.357 0 14592.708 + 305 0 0 0.848 0.356 0 13780.997 + 323 0 0 0.862 0.356 0 13014.625 + 342 0 0 0.891 0.357 0 12293.158 + 362 0 0 0.882 0.355 0 11615.613 + 383 0 0 0.876 0.356 0 10980.261 + 405 0 0 0.866 0.353 0 10385.363 + 429 0 0 0.863 0.353 0 9805.874 + 454 0 0 0.875 0.352 0 9267.436 + 480 0 0 0.881 0.351 0 8766.933 + 508 0 0 0.893 0.352 0 8285.331 + 538 0 0 0.859 0.352 0 7824.952 + 569 0 0 0.885 0.352 0 7400.239 + 602 0 0 0.881 0.354 0 6996.252 + 637 0 0 0.869 0.354 0 6613.495 + 674 0 0 0.887 0.356 0 6252.095 + 714 0 0 0.896 0.355 0 5903.445 + 756 0 0 0.860 0.356 0 5577.132 + 800 0 0 0.874 0.356 0 5271.980 + 847 0 0 0.890 0.357 0 4981.096 + 897 0 0 0.883 0.358 0 4705.137 + 950 0 0 0.871 0.357 0 4444.261 + 1006 0 0 0.887 0.358 0 4198.489 + 1065 0 0 0.853 0.358 0 3967.485 + 1128 0 0 0.873 0.357 0 3747.500 + 1194 0 0 0.866 0.361 0 3541.889 + 1264 0 0 0.864 0.359 0 3347.323 + 1339 0 0 0.860 0.356 0 3161.422 + 1418 0 0 0.860 0.356 0 2986.928 + 1502 0 0 0.849 0.358 0 2821.534 + 1591 0 0 0.877 0.364 0 2665.373 + 1685 0 0 0.844 0.363 0 2518.345 + 1784 0 0 0.865 0.367 0 2380.206 + 1884 0 0 0.861 0.364 0 2255.410 + 1995 0 0 0.861 0.366 0 2131.501 + 2113 0 0 0.866 0.370 0 2014.101 + 2239 0 0 0.843 0.375 0 1902.385 + 2371 0 0 0.864 0.376 0 1798.111 + 2512 0 0 0.840 0.382 0 1698.838 + 2661 0 0 0.843 0.385 0 1605.371 + 2818 0 0 0.846 0.391 0 1517.550 + 2985 0 0 0.843 0.398 0 1434.277 + 3162 0 0 0.850 0.404 0 1355.667 + 3350 0 0 0.835 0.411 0 1281.236 + 3548 0 0 0.828 0.420 0 1211.372 + 3758 0 0 0.835 0.431 0 1145.315 + 3981 0 0 0.836 0.442 0 1082.816 + 4217 0 0 0.825 0.454 0 1023.862 + 4467 0 0 0.844 0.465 0 968.220 + 4732 0 0 0.843 0.479 0 915.636 + 5012 0 0 0.822 0.486 0 866.150 + 5309 0 0 0.841 0.494 0 819.341 + 5623 0 0 0.837 0.503 0 775.233 + 5957 0 0 0.843 0.511 0 733.438 + 6310 0 0 0.845 0.522 0 694.063 + 6683 0 0 0.846 0.525 0 656.970 + 7079 0 0 0.853 0.530 0 621.868 + 7499 0 0 0.859 0.533 0 588.692 + 7943 0 0 0.848 0.536 0 557.414 + 8414 0 0 0.856 0.540 0 527.846 + 8913 0 0 0.865 0.545 0 499.951 + 9441 0 0 0.861 0.548 0 473.625 + 10000 0 0 0.866 0.547 0 448.798 + 10593 0 0 0.863 0.553 0 425.316 + 11220 0 0 0.869 0.551 0 403.170 + 11885 0 0 0.867 0.557 0 382.254 + 12589 0 0 0.887 0.553 0 362.524 + 13335 0 0 0.876 0.556 0 343.869 + 14125 0 0 0.876 0.562 0 326.281 + 14962 0 0 0.867 0.565 0 309.669 + 15849 0 0 0.871 0.564 0 293.998 + 16788 0 0 0.870 0.565 0 279.188 + 17783 0 0 0.874 0.571 0 265.211 + 18836 0 0 0.875 0.569 0 252.031 + 19953 0 0 0.873 0.577 0 239.567 + 21135 0 0 0.877 0.575 0 227.808 + 22387 0 0 0.870 0.577 0 216.718 + 23714 0 0 0.866 0.581 0 206.233 + 25119 0 0 0.874 0.589 0 196.347 + 26607 0 0 0.876 0.590 0 187.010 + 28184 0 0 0.871 0.594 0 178.199 + 29854 0 0 0.865 0.593 0 169.872 + 31623 0 0 0.872 0.597 0 162.009 + 33497 0 0 0.873 0.603 0 154.597 + 35481 0 0 0.870 0.605 0 147.609 + 37584 0 0 0.865 0.605 0 140.993 + 39811 0 0 0.871 0.606 0 134.766 + 42170 0 0 0.864 0.609 0 128.870 + 44668 0 0 0.865 0.614 0 123.302 + 47315 0 0 0.860 0.613 0 118.054 + 50119 0 0 0.864 0.618 0 113.093 + 53088 0 0 0.862 0.618 0 108.425 + 56234 0 0 0.863 0.621 0 104.002 + 59566 0 0 0.863 0.625 0 99.831 + 63096 0 0 0.862 0.627 0 95.893 + 66834 0 0 0.862 0.631 0 92.175 + 70795 0 0 0.859 0.630 0 88.667 + 74989 0 0 0.860 0.631 0 85.352 + 79433 0 0 0.863 0.632 0 82.232 + 84140 0 0 0.862 0.635 0 79.274 + 89125 0 0 0.861 0.636 0 76.479 + 94406 0 0 0.864 0.638 0 73.849 + 100000 0 0 0.864 0.639 0 71.366 + 105925 0 0 0.865 0.640 0 69.019 + 112202 0 0 0.863 0.645 0 66.805 + 118850 0 0 0.863 0.647 0 64.713 + 125893 0 0 0.868 0.647 0 62.739 + 133352 0 0 0.867 0.651 0 60.869 + 141254 0 0 0.871 0.650 0 59.111 + 149624 0 0 0.868 0.653 0 57.449 + 158489 0 0 0.872 0.656 0 55.878 + 167880 0 0 0.874 0.656 0 54.398 + 177828 0 0 0.880 0.661 0 53.002 + 188365 0 0 0.880 0.664 0 51.683 + 199526 0 0 0.879 0.663 0 50.439 + 211349 0 0 0.884 0.665 0 49.262 + 223872 0 0 0.887 0.663 0 48.152 + 237137 0 0 0.890 0.667 0 47.102 + 251189 0 0 0.892 0.668 0 46.115 + 266073 0 0 0.895 0.675 0 45.180 + 281838 0 0 0.898 0.676 0 44.298 + 298538 0 0 0.896 0.679 0 43.463 + 316228 0 0 0.905 0.678 0 42.674 + 334965 0 0 0.909 0.686 0 41.935 + 354813 0 0 0.907 0.690 0 41.231 + 375837 0 0 0.913 0.689 0 40.570 + 398107 0 0 0.918 0.694 0 39.944 + 421697 0 0 0.925 0.696 0 39.353 + 446684 0 0 0.932 0.694 0 38.796 + 473151 0 0 0.939 0.698 0 38.271 + 501187 0 0 0.942 0.706 0 37.772 + 530884 0 0 0.949 0.704 0 37.306 + 562341 0 0 0.957 0.711 0 36.863 + 595662 0 0 0.960 0.714 0 36.446 + 630957 0 0 0.967 0.722 0 36.050 + 668344 0 0 0.974 0.724 0 35.680 + 707946 0 0 0.980 0.725 0 35.329 + 749894 0 0 0.999 0.738 0 35.001 + 794328 0 0 0.996 0.738 0 34.687 + 841395 0 0 1.010 0.744 0 34.392 + 891251 0 0 1.016 0.748 0 34.112 + 944061 0 0 1.032 0.753 0 33.849 + 1000000 0 0 1.036 0.760 0 33.601 + 1059254 0 0 1.044 0.768 0 33.363 + 1122018 0 0 1.063 0.778 0 33.143 + 1188502 0 0 1.076 0.787 0 32.933 + 1258925 0 0 1.090 0.789 0 32.737 + 1333521 0 0 1.105 0.802 0 32.550 + 1412538 0 0 1.122 0.810 0 32.374 + 1496236 0 0 1.135 0.820 0 32.206 + 1584893 0 0 1.159 0.831 0 32.048 + 1678804 0 0 1.165 0.844 0 31.900 + 1778279 0 0 1.184 0.849 0 31.760 + 1883649 0 0 1.212 0.864 0 31.628 + 1995262 0 0 1.233 0.876 0 31.503 + 2113489 0 0 1.246 0.890 0 31.386 + 2238721 0 0 1.268 0.905 0 31.276 + 2371374 0 0 1.294 0.914 0 31.171 + 2511886 0 0 1.322 0.923 0 31.073 + 2660725 0 0 1.340 0.944 0 30.980 + 2818383 0 0 1.382 0.960 0 30.890 + 2985383 0 0 1.408 0.978 0 30.807 + 3162278 0 0 1.434 1.008 0 30.728 + 3349654 0 0 1.485 1.016 0 30.654 + 3548134 0 0 1.529 1.043 0 30.583 + 3758374 0 0 1.560 1.062 0 30.518 + 3981072 0 0 1.601 1.090 0 30.455 + 4216965 0 0 1.660 1.114 0 30.397 + 4466836 0 0 1.703 1.136 0 30.341 + 4731513 0 0 1.751 1.163 0 30.289 + 5011872 0 0 1.809 1.199 0 30.239 + 5308844 0 0 1.869 1.229 0 30.192 + 5623413 0 0 1.942 1.260 0 30.148 + 5956621 0 0 2.013 1.299 0 30.106 + 6309573 0 0 2.076 1.338 0 30.067 + 6683439 0 0 2.155 1.376 0 30.030 + 7079458 0 0 2.244 1.420 0 29.994 + 7498942 0 0 2.320 1.474 0 29.961 + 7943282 0 0 2.421 1.519 0 29.929 + 8413951 0 0 2.526 1.576 0 29.900 + 8912509 0 0 2.640 1.630 0 29.871 + 9440609 0 0 2.759 1.694 0 29.845 + 10000000 0 0 2.886 1.759 0 29.820 + 10592537 0 0 3.012 1.844 0 29.798 + 11220185 0 0 3.169 1.917 0 29.776 + 11885022 0 0 3.336 2.002 0 29.756 + 12589254 0 0 3.493 2.081 0 29.737 + 13335214 0 0 3.697 2.178 0 29.718 + 14125375 0 0 3.867 2.272 0 29.700 + 14962357 0 0 4.091 2.388 0 29.683 diff --git a/feeds/p4/libjudy/src/test/Centrino_1.3Mhz_Plots/JLHash_CO.plot b/feeds/p4/libjudy/src/test/Centrino_1.3Mhz_Plots/JLHash_CO.plot new file mode 100644 index 000000000..9f988dc36 --- /dev/null +++ b/feeds/p4/libjudy/src/test/Centrino_1.3Mhz_Plots/JLHash_CO.plot @@ -0,0 +1,560 @@ +# StringCompare -n13335214 -A JLHash -P40 -L10 -C -M100000 /home/data/domnames.txt +# This file is in a format to input to 'jbgraph' +# XLABEL Stored +# YLABEL Microseconds / Index +# COLHEAD 1 Total Insert attempts +# COLHEAD 2 Number Gets +# COLHEAD 3 Duplicate strings +# COLHEAD 4 Insert Time (uS) +# COLHEAD 5 Get Time (uS) +# COLHEAD 6 Hash Chain Length +# COLHEAD 7 Average RAM/String +# Linux localhost 2.6.3-4mdkenterprise #1 SMP Tue Mar 2 07:00:53 CET 2004 i686 +# 32 Bit CPU +# Processor speed compiled at 1299 Mhz +# JLHash table virtual size = 4294967296 +# 9999673 (75.0%) non-Word_t aligned string buffers +# Ram used for input data = 333834600 bytes +# Average string length = 16.0 bytes +# 3400000 bytes malloc() for 'cached' strings for Get measurement +# Access Time = 0.102 uS average per string (mostly from Cache) +# HashStr() Time = 0.274 uS average per string (mostly from Cache) +# Access Time = 0.285 uS average per string (mostly from RAM) +# HashStr() Time = 0.474 uS average per string (mostly from RAM) +# Pass 0 +# TotInserts DeltaGets DupStrs InsTime GetTime HChainLen Ram/String +# 1 1 0 38.004 1.742 1.000000 108.0 +# 2 2 0 8.817 0.905 1.000000 74.0 +# 3 3 0 1.388 0.705 1.000000 60.0 +# 4 4 0 1.583 0.651 1.000000 58.0 +# 5 5 0 1.148 0.616 1.000000 52.8 +# 6 6 0 1.625 0.603 1.000000 52.7 +# 7 7 0 1.283 0.587 1.000000 50.3 +# 8 8 0 1.746 0.575 1.000000 52.0 +# 9 9 0 0.979 0.549 1.000000 48.9 +# 10 10 0 1.119 0.547 1.000000 47.6 +# 11 11 0 1.020 0.528 1.000000 45.8 +# 12 12 0 1.640 0.512 1.000000 46.7 +# 13 13 0 1.132 0.495 1.000000 45.2 +# 14 14 0 1.260 0.745 1.000000 44.3 +# 15 15 0 6.118 0.481 1.000000 42.9 +# 16 16 0 1.931 0.478 1.000000 45.8 +# 17 17 0 1.107 0.473 1.000000 44.5 +# 18 18 0 1.099 0.471 1.000000 44.0 +# 19 19 0 1.057 0.463 1.000000 42.9 +# 20 20 0 1.330 0.462 1.000000 42.2 +# 21 21 0 1.196 0.458 1.000000 41.5 +# 22 22 0 0.962 0.455 1.000000 40.7 +# 23 23 0 1.169 0.459 1.000000 40.5 +# 24 24 0 1.964 0.453 1.000000 42.5 +# 25 25 0 1.238 0.442 1.000000 41.8 +# 26 26 0 1.374 0.439 1.000000 41.1 +# 27 27 0 0.962 0.439 1.000000 40.6 +# 28 28 0 1.043 0.438 1.000000 40.1 +# 29 29 0 1.311 0.430 1.000000 39.6 +# 30 30 0 1.068 0.428 1.000000 38.9 +# 31 31 0 1.206 0.427 1.000000 38.5 +# 32 32 0 24.145 0.517 1.000000 44.2 +# 34 34 0 2.551 0.435 1.000000 43.9 +# 36 36 0 1.243 0.433 1.000000 43.7 +# 38 38 0 1.180 0.432 1.000000 43.3 +# 40 40 0 1.277 0.428 1.000000 42.9 +# 42 42 0 1.069 0.425 1.000000 42.5 +# 44 44 0 0.948 0.419 1.000000 42.0 +# 46 46 0 1.188 0.420 1.000000 41.9 +# 48 48 0 1.519 0.425 1.000000 42.0 +# 50 50 0 1.245 0.424 1.000000 42.2 +# 53 53 0 1.105 0.431 1.000000 42.3 +# 56 56 0 1.429 0.431 1.000000 43.0 +# 59 59 0 1.053 0.436 1.000000 42.6 +# 62 62 0 1.337 0.445 1.000000 43.2 +# 65 65 0 1.169 0.442 1.000000 43.6 +# 69 69 0 1.654 0.441 1.000000 42.8 +# 73 73 0 1.080 0.444 1.000000 42.5 +# 77 77 0 0.877 0.438 1.000000 41.9 +# 81 81 0 1.082 0.438 1.000000 41.8 +# 85 85 0 1.091 0.437 1.000000 41.7 +# 90 90 0 1.002 0.439 1.000000 41.2 +# 95 95 0 1.798 0.438 1.000000 42.1 +# 100 100 0 0.927 0.439 1.000000 41.8 +# 106 106 0 1.140 0.439 1.000000 42.4 +# 112 112 0 1.008 0.443 1.000000 42.5 +# 118 118 0 0.959 0.498 1.000000 42.0 +# 125 125 0 0.897 0.438 1.000000 41.5 +# 132 132 0 0.982 0.438 1.000000 41.1 +# 139 139 0 1.120 0.437 1.000000 41.7 +# 147 147 0 1.073 0.438 1.000000 41.8 +# 155 155 0 1.013 0.439 1.000000 41.8 +# 164 164 0 0.974 0.441 1.000000 41.7 +# 173 173 0 0.877 0.438 1.000000 41.3 +# 183 183 0 1.440 0.440 1.000000 41.7 +# 194 194 0 0.958 0.438 1.000000 41.5 +# 205 205 0 1.000 0.438 1.000000 41.6 +# 217 217 0 0.932 0.439 1.000000 41.4 +# 230 230 0 1.010 0.441 1.000000 41.7 +# 243 243 0 1.037 0.471 1.000000 41.8 +# 257 257 0 1.065 0.448 1.000000 41.7 +# 272 272 0 1.259 0.450 1.000000 41.8 +# 288 288 0 1.060 0.453 1.000000 42.3 +# 305 305 0 0.966 0.453 1.000000 42.0 +# 323 323 0 0.946 0.453 1.000000 41.6 +# 342 342 0 0.969 0.453 1.000000 41.7 +# 362 362 0 1.142 0.457 1.000000 41.5 +# 383 383 0 0.988 0.472 1.000000 41.4 +# 405 405 0 1.023 0.454 1.000000 41.3 +# 429 429 0 1.151 0.457 1.000000 41.4 +# 454 454 0 0.990 0.471 1.000000 41.4 +# 480 480 0 1.004 0.458 1.000000 41.3 +# 508 508 0 1.014 0.463 1.000000 41.4 +# 538 538 0 1.120 0.475 1.000000 41.2 +# 569 569 0 0.997 0.464 1.000000 41.1 +# 602 602 0 1.059 0.478 1.000000 40.9 +# 637 637 0 1.095 0.468 1.000000 40.7 +# 674 674 0 1.048 0.480 1.000000 40.6 +# 714 714 0 1.072 0.470 1.000000 40.4 +# 756 756 0 1.337 0.462 1.000000 40.2 +# 800 800 0 1.015 0.459 1.000000 40.1 +# 847 847 0 1.007 0.454 1.000000 40.0 +# 897 897 0 1.079 0.464 1.000000 39.9 +# 950 950 0 1.017 0.459 1.000000 39.8 +# 1006 1006 0 1.135 0.458 1.000000 39.9 +# 1065 1065 0 1.068 0.465 1.000000 39.9 +# 1128 1128 0 0.997 0.467 1.000000 39.8 +# 1194 1194 0 1.022 0.468 1.000000 39.5 +# 1264 1264 0 1.074 0.465 1.000000 39.5 +# 1339 1339 0 1.122 0.465 1.000000 39.3 +# 1418 1418 0 1.164 0.468 1.000000 39.3 +# 1502 1502 0 1.035 0.473 1.000000 39.2 +# 1591 1591 0 1.042 0.473 1.000000 39.2 +# 1685 1685 0 1.052 0.475 1.000000 39.2 +# 1784 1784 0 1.119 0.476 1.000000 39.2 +# 1884 1884 0 1.058 0.476 1.000000 39.1 +# 1995 1995 0 1.042 0.478 1.000000 39.1 +# 2113 2113 0 2.215 0.482 1.000000 38.9 +# 2239 2239 0 1.072 0.637 1.000000 38.8 +# 2371 2371 0 1.096 0.486 1.000000 38.7 +# 2512 2512 0 1.110 0.486 1.000000 38.8 +# 2661 2661 0 1.097 0.488 1.000000 38.8 +# 2818 2818 0 1.156 0.490 1.000000 38.7 +# 2985 2985 0 1.137 0.493 1.000000 38.7 +# 3162 3162 0 1.143 0.498 1.000000 38.7 +# 3350 3350 0 1.067 0.499 1.000000 38.5 +# 3548 3548 0 1.121 0.500 1.000000 38.5 +# 3758 3758 0 1.161 0.528 1.000000 38.6 +# 3981 3981 0 1.103 0.512 1.000000 38.5 +# 4217 4217 0 1.120 0.515 1.000000 38.5 +# 4467 4467 0 1.116 0.520 1.000000 38.4 +# 4732 4732 0 1.151 0.525 1.000000 38.4 +# 5012 5012 0 1.124 0.527 1.000000 38.3 +# 5309 5309 0 1.165 0.532 1.000000 38.3 +# 5623 5623 0 1.654 0.542 1.000000 38.2 +# 5957 5957 0 1.175 0.542 1.000000 38.2 +# 6310 6310 0 1.221 0.547 1.000000 38.2 +# 6683 6683 0 1.269 0.554 1.000000 38.3 +# 7079 7079 0 1.224 0.553 1.000000 38.3 +# 7499 7499 0 1.267 0.556 1.000000 38.4 +# 7943 7943 0 1.344 0.556 1.000000 38.6 +# 8414 8414 0 1.320 0.606 1.000000 38.8 +# 8913 8913 0 1.485 0.556 1.000000 39.2 +# 9441 9441 0 1.483 0.551 1.000000 39.7 +# 10000 10000 0 1.336 0.549 1.000000 40.0 +# 10593 10593 0 1.374 0.545 1.000000 40.3 +# 11220 11220 0 1.361 0.605 1.000000 40.7 +# 11885 11885 0 1.233 0.552 1.000000 40.8 +# 12589 12589 0 1.201 0.546 1.000000 40.9 +# 13335 13335 0 1.145 0.545 1.000000 40.9 +# 14125 14125 0 1.169 0.594 1.000000 40.8 +# 14962 14962 0 1.152 0.563 1.000000 40.8 +# 15849 15849 0 1.137 0.558 1.000000 40.7 +# 16788 16788 0 1.168 0.622 1.000000 40.7 +# 17783 17783 0 1.159 0.579 1.000000 40.6 +# 18836 18836 0 1.162 0.605 1.000000 40.5 +# 19953 19953 0 1.270 0.582 1.000000 40.5 +# 21135 21135 0 1.153 0.589 1.000000 40.4 +# 22387 22387 0 1.321 0.601 1.000000 40.3 +# 23714 23714 0 1.289 0.602 1.000000 40.3 +# 25119 25119 0 1.256 0.639 1.000000 40.2 +# 26607 26607 0 1.205 0.626 1.000000 40.1 +# 28184 28184 0 1.200 0.625 1.000000 40.1 +# 29854 29854 0 1.203 0.659 1.000000 40.2 +# 31623 31623 0 1.213 0.651 1.000000 40.2 +# 33497 33497 0 1.210 0.654 1.000000 40.4 +# 35481 35481 0 1.208 0.681 1.000000 40.5 +# 37584 37584 0 1.264 0.672 1.000000 40.6 +# 39811 39811 0 1.222 0.693 1.000000 40.7 +# 42170 42170 0 1.224 0.695 1.000000 40.7 +# 44668 44668 0 1.225 0.710 1.000000 40.8 +# 47315 47315 0 1.218 0.702 1.000000 40.8 +# 50119 50119 0 1.231 0.722 1.000000 40.8 +# 53088 53088 0 1.284 0.718 1.000000 40.8 +# 56234 56234 0 1.228 0.729 1.000000 40.8 +# 59566 59566 0 1.228 0.754 1.000000 40.7 +# 63096 63096 0 1.234 0.750 1.000000 40.7 +# 66834 66834 0 1.230 0.745 1.000000 40.6 +# 70795 70795 0 1.236 0.752 1.000000 40.5 +# 74989 74989 0 1.243 0.760 1.000000 40.4 +# 79433 79433 0 1.289 0.762 1.000000 40.3 +# 84140 84140 0 1.291 0.766 1.000000 40.2 +# 89125 89125 0 1.254 0.768 1.000000 40.1 +# 94406 94406 0 1.256 0.767 1.000011 40.0 +# 100000 100000 0 1.255 0.769 1.000010 39.9 +# 105925 100000 0 1.283 0.784 1.000010 39.8 +# 112202 100000 0 1.305 0.787 1.000010 39.7 +# 118850 100000 0 1.256 0.784 1.000010 39.5 +# 125893 100000 0 1.336 0.792 1.000010 39.4 +# 133352 100000 0 1.310 0.798 1.000010 39.3 +# 141254 100000 0 1.292 0.806 1.000000 39.3 +# 149624 100000 0 1.310 0.816 1.000000 39.2 +# 158489 100000 0 1.326 0.823 1.000000 39.1 +# 167880 100000 0 1.379 0.825 1.000010 39.1 +# 177828 100000 0 1.355 0.833 1.000000 39.0 +# 188365 100000 0 1.365 0.838 1.000010 38.9 +# 199526 100000 0 1.398 0.845 1.000030 38.9 +# 211349 100000 0 1.382 0.852 1.000030 38.8 +# 223872 100000 0 1.411 0.853 1.000010 38.8 +# 237137 100000 0 1.471 0.870 1.000030 38.7 +# 251189 100000 0 1.403 0.869 1.000030 38.6 +# 266073 100000 0 1.411 0.873 1.000020 38.6 +# 281838 100000 0 1.417 0.875 1.000050 38.5 +# 298538 100000 0 1.418 0.880 1.000040 38.4 +# 316228 100000 0 1.424 0.892 1.000020 38.3 +# 334965 100000 0 1.423 0.894 1.000040 38.3 +# 354813 100000 0 1.435 0.895 1.000020 38.2 +# 375837 100000 0 1.437 0.904 1.000070 38.1 +# 398107 100000 0 1.419 0.914 1.000070 38.0 +# 421697 100000 0 1.440 0.912 1.000100 37.9 +# 446684 100000 0 1.426 0.954 1.000080 37.8 +# 473151 100000 0 1.434 0.923 1.000080 37.7 +# 501187 100000 0 1.465 0.931 1.000150 37.7 +# 530884 100000 0 1.470 0.937 1.000060 37.6 +# 562341 100000 0 1.469 0.943 1.000100 37.6 +# 595662 100000 0 1.488 0.959 1.000100 37.5 +# 630957 100000 0 1.500 0.956 1.000130 37.5 +# 668344 100000 0 1.484 0.959 1.000070 37.4 +# 707946 100000 0 1.517 0.965 1.000110 37.4 +# 749894 100000 0 1.523 0.971 1.000070 37.3 +# 794328 100000 0 1.533 0.985 1.000130 37.3 +# 841395 100000 0 1.547 0.985 1.000180 37.3 +# 891251 100000 0 1.558 0.991 1.000100 37.2 +# 944061 100000 0 1.552 0.997 1.000130 37.2 +# 1000000 100000 0 1.577 1.004 1.000100 37.2 +# 1059254 100000 0 1.582 1.009 1.000140 37.1 +# 1122018 100000 0 1.588 1.011 1.000070 37.1 +# 1188502 100000 0 1.609 1.019 1.000130 37.1 +# 1258925 100000 0 1.594 1.032 1.000200 37.1 +# 1333521 100000 0 1.615 1.032 1.000130 37.1 +# 1412538 100000 0 1.610 1.036 1.000150 37.1 +# 1496236 100000 0 1.612 1.048 1.000150 37.1 +# 1584893 100000 0 1.627 1.049 1.000190 37.0 +# 1678804 100000 0 1.646 1.056 1.000210 37.0 +# 1778279 100000 0 1.646 1.060 1.000310 36.9 +# 1883649 100000 0 1.667 1.065 1.000230 36.9 +# 1995262 100000 0 1.699 1.069 1.000350 36.9 +# 2113489 100000 0 1.734 1.072 1.000300 37.0 +# 2238721 100000 0 1.790 1.086 1.000240 37.1 +# 2371374 100000 0 1.861 1.088 1.000250 37.4 +# 2511886 100000 0 1.925 1.092 1.000320 37.8 +# 2660725 100000 0 2.046 1.096 1.000320 38.4 +# 2818383 100000 0 1.983 1.109 1.000320 39.0 +# 2985383 100000 0 1.953 1.099 1.000460 39.6 +# 3162278 100000 0 1.883 1.098 1.000430 40.1 +# 3349654 100000 0 1.809 1.104 1.000420 40.4 +# 3548134 100000 0 1.725 1.110 1.000490 40.6 +# 3758374 100000 0 1.691 1.119 1.000330 40.6 +# 3981072 100000 0 1.663 1.132 1.000410 40.6 +# 4216965 100000 0 1.665 1.140 1.000460 40.6 +# 4466836 100000 0 1.672 1.135 1.000550 40.5 +# 4731513 100000 0 1.685 1.157 1.000490 40.5 +# 5011872 100000 0 1.688 1.180 1.000520 40.4 +# 5308844 100000 0 1.702 1.170 1.000580 40.3 +# 5623413 100000 0 1.715 1.181 1.000570 40.2 +# 5956621 100000 0 1.727 1.184 1.000820 40.2 +# 6309573 100000 0 1.734 1.203 1.000690 40.1 +# 6683439 100000 0 1.740 1.198 1.000910 40.0 +# 7079458 100000 0 1.742 1.214 1.000800 40.0 +# 7498942 100000 0 1.755 1.217 1.000750 40.0 +# 7943282 100000 0 1.767 1.223 1.000940 40.0 +# 8413951 100000 0 1.860 1.239 1.000920 40.1 +# 8912509 100000 0 1.795 1.249 1.001020 40.2 +# 9440609 100000 0 1.800 1.257 1.001150 40.3 +# 10000000 100000 0 1.798 1.257 1.000990 40.3 +# 10592537 100000 0 1.783 1.301 1.001150 40.4 +# 11220185 100000 0 1.845 1.295 1.001400 40.4 +# 11885022 100000 0 1.829 1.286 1.001310 40.4 +# 12589254 100000 0 10.482 1.917 1.001420 40.4 +# 13335214 100000 0 5.906 4.791 1.001610 40.3 +# Total Duplicate strings = 0 +# Begin JLHashFreeArray()... +# returned 538058560 bytes +# Free 13335214 strings, 1.065 uSecs Ave/string + +# Pass 1 +# Pass 2 +# Pass 3 +# Pass 4 +# Pass 5 +# Pass 6 +# Pass 7 +# Pass 8 +# Pass 9 +# TotInserts 0 0 InsTime GetTime 0 Ram/String + 1 0 0 3.635 0.601 0 48.000 + 2 0 0 2.086 0.268 0 40.000 + 3 0 0 0.989 0.349 0 41.333 + 4 0 0 0.952 0.324 0 42.000 + 5 0 0 0.765 0.330 0 39.200 + 6 0 0 1.010 0.354 0 39.333 + 7 0 0 0.748 0.363 0 37.714 + 8 0 0 1.226 0.362 0 41.500 + 9 0 0 0.823 0.364 0 40.889 + 10 0 0 0.774 0.373 0 40.400 + 11 0 0 0.794 0.365 0 40.000 + 12 0 0 1.554 0.366 0 42.333 + 13 0 0 0.743 0.370 0 41.231 + 14 0 0 0.817 0.375 0 40.286 + 15 0 0 0.798 0.384 0 38.933 + 16 0 0 1.259 0.382 0 42.000 + 17 0 0 0.716 0.382 0 41.647 + 18 0 0 0.751 0.380 0 41.333 + 19 0 0 0.785 0.383 0 40.211 + 20 0 0 0.875 0.382 0 39.800 + 21 0 0 0.798 0.380 0 39.619 + 22 0 0 0.875 0.381 0 39.273 + 23 0 0 0.751 0.388 0 39.130 + 24 0 0 1.964 0.388 0 41.167 + 25 0 0 0.880 0.382 0 40.480 + 26 0 0 0.908 0.387 0 39.846 + 27 0 0 0.740 0.389 0 39.556 + 28 0 0 0.842 0.388 0 39.429 + 29 0 0 0.895 0.390 0 39.034 + 30 0 0 0.877 0.387 0 38.800 + 31 0 0 0.781 0.388 0 38.452 + 32 0 0 7.634 0.424 0 43.375 + 34 0 0 0.995 0.398 0 43.294 + 36 0 0 0.886 0.409 0 42.667 + 38 0 0 0.915 0.413 0 42.421 + 40 0 0 0.905 0.416 0 42.200 + 42 0 0 0.895 0.417 0 42.857 + 44 0 0 0.769 0.418 0 42.727 + 46 0 0 0.858 0.416 0 42.435 + 48 0 0 1.019 0.414 0 42.250 + 50 0 0 0.946 0.415 0 41.920 + 53 0 0 0.985 0.413 0 42.340 + 56 0 0 1.024 0.417 0 42.643 + 59 0 0 0.876 0.415 0 42.712 + 62 0 0 0.992 0.412 0 43.097 + 65 0 0 0.931 0.419 0 43.077 + 69 0 0 0.884 0.424 0 42.899 + 73 0 0 0.967 0.422 0 42.685 + 77 0 0 0.831 0.428 0 42.857 + 81 0 0 0.860 0.416 0 42.864 + 85 0 0 0.864 0.416 0 43.529 + 90 0 0 0.866 0.419 0 43.156 + 95 0 0 0.968 0.422 0 42.653 + 100 0 0 0.927 0.425 0 42.160 + 106 0 0 0.997 0.427 0 42.075 + 112 0 0 0.880 0.430 0 42.250 + 118 0 0 0.959 0.429 0 42.373 + 125 0 0 0.897 0.428 0 42.656 + 132 0 0 0.982 0.430 0 42.364 + 139 0 0 0.892 0.430 0 41.899 + 147 0 0 1.004 0.437 0 42.395 + 155 0 0 0.962 0.433 0 42.348 + 164 0 0 0.945 0.436 0 42.146 + 173 0 0 0.877 0.438 0 41.734 + 183 0 0 0.890 0.440 0 41.727 + 194 0 0 0.958 0.438 0 41.794 + 205 0 0 1.000 0.438 0 41.795 + 217 0 0 0.923 0.439 0 41.604 + 230 0 0 0.996 0.441 0 42.070 + 243 0 0 0.991 0.452 0 42.091 + 257 0 0 0.939 0.448 0 41.696 + 272 0 0 0.981 0.450 0 41.559 + 288 0 0 1.022 0.453 0 41.667 + 305 0 0 0.966 0.453 0 41.902 + 323 0 0 0.946 0.453 0 41.895 + 342 0 0 0.969 0.453 0 42.058 + 362 0 0 1.064 0.457 0 42.188 + 383 0 0 0.988 0.464 0 42.057 + 405 0 0 1.023 0.454 0 42.272 + 429 0 0 1.066 0.457 0 42.256 + 454 0 0 0.990 0.468 0 41.947 + 480 0 0 1.004 0.458 0 41.917 + 508 0 0 1.014 0.463 0 41.819 + 538 0 0 1.068 0.471 0 41.465 + 569 0 0 0.997 0.464 0 41.244 + 602 0 0 1.059 0.478 0 41.143 + 637 0 0 1.095 0.468 0 41.017 + 674 0 0 1.048 0.480 0 40.914 + 714 0 0 1.062 0.470 0 40.734 + 756 0 0 1.337 0.462 0 40.439 + 800 0 0 1.015 0.459 0 40.220 + 847 0 0 1.007 0.454 0 40.142 + 897 0 0 1.016 0.464 0 40.143 + 950 0 0 1.017 0.459 0 40.029 + 1006 0 0 1.033 0.458 0 40.016 + 1065 0 0 1.033 0.465 0 39.985 + 1128 0 0 0.997 0.467 0 39.897 + 1194 0 0 1.007 0.467 0 39.863 + 1264 0 0 1.027 0.465 0 39.750 + 1339 0 0 1.022 0.465 0 39.555 + 1418 0 0 1.007 0.468 0 39.368 + 1502 0 0 1.035 0.473 0 39.204 + 1591 0 0 1.023 0.473 0 39.110 + 1685 0 0 1.027 0.475 0 39.119 + 1784 0 0 0.998 0.476 0 39.029 + 1884 0 0 1.028 0.476 0 39.096 + 1995 0 0 1.012 0.478 0 38.983 + 2113 0 0 1.023 0.482 0 39.000 + 2239 0 0 0.998 0.493 0 38.916 + 2371 0 0 1.006 0.486 0 38.962 + 2512 0 0 1.035 0.486 0 38.861 + 2661 0 0 1.027 0.488 0 38.825 + 2818 0 0 1.046 0.490 0 38.755 + 2985 0 0 1.029 0.493 0 38.596 + 3162 0 0 1.063 0.498 0 38.530 + 3350 0 0 1.036 0.499 0 38.427 + 3548 0 0 1.037 0.500 0 38.444 + 3758 0 0 1.068 0.528 0 38.506 + 3981 0 0 1.073 0.512 0 38.551 + 4217 0 0 1.079 0.515 0 38.367 + 4467 0 0 1.072 0.520 0 38.433 + 4732 0 0 1.083 0.525 0 38.343 + 5012 0 0 1.061 0.527 0 38.311 + 5309 0 0 1.085 0.532 0 38.320 + 5623 0 0 1.072 0.542 0 38.251 + 5957 0 0 1.103 0.542 0 38.209 + 6310 0 0 1.142 0.547 0 38.255 + 6683 0 0 1.096 0.554 0 38.122 + 7079 0 0 1.132 0.553 0 38.204 + 7499 0 0 1.208 0.556 0 38.365 + 7943 0 0 1.227 0.556 0 38.610 + 8414 0 0 1.225 0.588 0 38.839 + 8913 0 0 1.310 0.556 0 39.063 + 9441 0 0 1.319 0.551 0 39.620 + 10000 0 0 1.270 0.549 0 40.091 + 10593 0 0 1.271 0.545 0 40.405 + 11220 0 0 1.175 0.570 0 40.668 + 11885 0 0 1.125 0.552 0 40.855 + 12589 0 0 1.080 0.546 0 40.874 + 13335 0 0 1.057 0.545 0 40.788 + 14125 0 0 1.067 0.574 0 40.824 + 14962 0 0 1.061 0.563 0 40.771 + 15849 0 0 1.059 0.558 0 40.713 + 16788 0 0 1.057 0.585 0 40.635 + 17783 0 0 1.070 0.579 0 40.554 + 18836 0 0 1.071 0.598 0 40.488 + 19953 0 0 1.091 0.582 0 40.426 + 21135 0 0 1.099 0.589 0 40.368 + 22387 0 0 1.099 0.601 0 40.336 + 23714 0 0 1.104 0.602 0 40.275 + 25119 0 0 1.113 0.629 0 40.186 + 26607 0 0 1.126 0.626 0 40.160 + 28184 0 0 1.174 0.625 0 40.113 + 29854 0 0 1.152 0.656 0 40.181 + 31623 0 0 1.154 0.651 0 40.274 + 33497 0 0 1.156 0.654 0 40.354 + 35481 0 0 1.154 0.677 0 40.434 + 37584 0 0 1.159 0.672 0 40.553 + 39811 0 0 1.165 0.693 0 40.664 + 42170 0 0 1.164 0.695 0 40.727 + 44668 0 0 1.166 0.710 0 40.820 + 47315 0 0 1.167 0.702 0 40.855 + 50119 0 0 1.167 0.722 0 40.883 + 53088 0 0 1.169 0.718 0 40.892 + 56234 0 0 1.169 0.729 0 40.829 + 59566 0 0 1.169 0.748 0 40.793 + 63096 0 0 1.173 0.750 0 40.721 + 66834 0 0 1.169 0.745 0 40.633 + 70795 0 0 1.173 0.752 0 40.553 + 74989 0 0 1.176 0.760 0 40.462 + 79433 0 0 1.189 0.762 0 40.373 + 84140 0 0 1.187 0.766 0 40.280 + 89125 0 0 1.192 0.768 0 40.185 + 94406 0 0 1.199 0.767 0 40.075 + 100000 0 0 1.201 0.769 0 39.939 + 105925 0 0 1.195 0.784 0 39.811 + 112202 0 0 1.183 0.787 0 39.690 + 118850 0 0 1.192 0.784 0 39.577 + 125893 0 0 1.203 0.792 0 39.473 + 133352 0 0 1.213 0.798 0 39.383 + 141254 0 0 1.226 0.806 0 39.303 + 149624 0 0 1.243 0.816 0 39.233 + 158489 0 0 1.252 0.823 0 39.167 + 167880 0 0 1.267 0.825 0 39.100 + 177828 0 0 1.276 0.833 0 39.041 + 188365 0 0 1.284 0.838 0 38.987 + 199526 0 0 1.293 0.845 0 38.928 + 211349 0 0 1.304 0.852 0 38.867 + 223872 0 0 1.310 0.853 0 38.806 + 237137 0 0 1.320 0.870 0 38.750 + 251189 0 0 1.331 0.869 0 38.690 + 266073 0 0 1.329 0.873 0 38.620 + 281838 0 0 1.338 0.875 0 38.553 + 298538 0 0 1.339 0.880 0 38.477 + 316228 0 0 1.339 0.892 0 38.394 + 334965 0 0 1.349 0.894 0 38.310 + 354813 0 0 1.352 0.895 0 38.220 + 375837 0 0 1.348 0.904 0 38.126 + 398107 0 0 1.350 0.914 0 38.043 + 421697 0 0 1.359 0.912 0 37.948 + 446684 0 0 1.359 0.927 0 37.865 + 473151 0 0 1.372 0.923 0 37.786 + 501187 0 0 1.380 0.931 0 37.707 + 530884 0 0 1.385 0.937 0 37.640 + 562341 0 0 1.391 0.943 0 37.581 + 595662 0 0 1.403 0.953 0 37.533 + 630957 0 0 1.414 0.956 0 37.486 + 668344 0 0 1.427 0.959 0 37.438 + 707946 0 0 1.438 0.965 0 37.398 + 749894 0 0 1.449 0.971 0 37.357 + 794328 0 0 1.462 0.981 0 37.312 + 841395 0 0 1.481 0.985 0 37.273 + 891251 0 0 1.490 0.991 0 37.240 + 944061 0 0 1.509 0.997 0 37.206 + 1000000 0 0 1.522 1.004 0 37.181 + 1059254 0 0 1.532 1.009 0 37.168 + 1122018 0 0 1.538 1.011 0 37.153 + 1188502 0 0 1.544 1.019 0 37.148 + 1258925 0 0 1.555 1.028 0 37.151 + 1333521 0 0 1.557 1.031 0 37.142 + 1412538 0 0 1.566 1.036 0 37.120 + 1496236 0 0 1.571 1.044 0 37.091 + 1584893 0 0 1.582 1.049 0 37.050 + 1678804 0 0 1.591 1.056 0 36.997 + 1778279 0 0 1.597 1.060 0 36.944 + 1883649 0 0 1.628 1.065 0 36.896 + 1995262 0 0 1.667 1.069 0 36.898 + 2113489 0 0 1.697 1.072 0 36.960 + 2238721 0 0 1.750 1.085 0 37.110 + 2371374 0 0 1.819 1.086 0 37.407 + 2511886 0 0 1.867 1.090 0 37.835 + 2660725 0 0 1.901 1.094 0 38.385 + 2818383 0 0 1.905 1.091 0 39.012 + 2985383 0 0 1.867 1.089 0 39.605 + 3162278 0 0 1.805 1.089 0 40.094 + 3349654 0 0 1.727 1.092 0 40.422 + 3548134 0 0 1.657 1.096 0 40.599 + 3758374 0 0 1.610 1.106 0 40.658 + 3981072 0 0 1.588 1.111 0 40.640 + 4216965 0 0 1.578 1.122 0 40.590 + 4466836 0 0 1.587 1.130 0 40.530 + 4731513 0 0 1.595 1.134 0 40.461 + 5011872 0 0 1.607 1.145 0 40.391 + 5308844 0 0 1.625 1.154 0 40.316 + 5623413 0 0 1.642 1.167 0 40.240 + 5956621 0 0 1.652 1.176 0 40.164 + 6309573 0 0 1.669 1.188 0 40.084 + 6683439 0 0 1.710 1.198 0 40.011 + 7079458 0 0 1.711 1.208 0 39.956 + 7498942 0 0 1.719 1.217 0 39.961 + 7943282 0 0 1.727 1.223 0 40.035 + 8413951 0 0 1.727 1.233 0 40.119 + 8912509 0 0 1.726 1.243 0 40.194 + 9440609 0 0 1.737 1.248 0 40.263 + 10000000 0 0 1.723 1.251 0 40.323 + 10592537 0 0 1.718 1.259 0 40.370 + 11220185 0 0 1.715 1.265 0 40.399 + 11885022 0 0 1.710 1.270 0 40.407 + 12589254 0 0 1.704 1.276 0 40.389 + 13335214 0 0 1.697 1.277 0 40.347 diff --git a/feeds/p4/libjudy/src/test/Centrino_1.3Mhz_Plots/JudyHS_CO.plot b/feeds/p4/libjudy/src/test/Centrino_1.3Mhz_Plots/JudyHS_CO.plot new file mode 100644 index 000000000..ee87bfa9f --- /dev/null +++ b/feeds/p4/libjudy/src/test/Centrino_1.3Mhz_Plots/JudyHS_CO.plot @@ -0,0 +1,563 @@ +# StringCompare -n14962357 -A JudyHS -P40 -L10 -C -M100000 /home/data/domnames.txt +# This file is in a format to input to 'jbgraph' +# XLABEL Stored +# YLABEL Microseconds / Index +# COLHEAD 1 Total Insert attempts +# COLHEAD 2 Number Gets +# COLHEAD 3 Duplicate strings +# COLHEAD 4 Insert Time (uS) +# COLHEAD 5 Get Time (uS) +# COLHEAD 6 Hash Chain Length +# COLHEAD 7 Average RAM/String +# Linux localhost 2.6.3-4mdkenterprise #1 SMP Tue Mar 2 07:00:53 CET 2004 i686 +# 32 Bit CPU +# Processor speed compiled at 1299 Mhz +# 11218731 (75.0%) non-Word_t aligned string buffers +# Ram used for input data = 372621771 bytes +# Average string length = 15.9 bytes +# 3200000 bytes malloc() for 'cached' strings for Get measurement +# Access Time = 0.112 uS average per string (mostly from Cache) +# HashStr() Time = 0.271 uS average per string (mostly from Cache) +# Access Time = 0.295 uS average per string (mostly from RAM) +# HashStr() Time = 0.476 uS average per string (mostly from RAM) +# Pass 0 +# TotInserts DeltaGets DupStrs InsTime GetTime HChainLen Ram/String +# 1 1 0 30.232 2.608 0.000000 52.0 +# 2 2 0 8.020 0.314 0.000000 44.0 +# 3 3 0 1.616 0.268 0.000000 42.7 +# 4 4 0 1.424 0.267 0.000000 45.0 +# 5 5 0 1.166 0.252 0.000000 41.6 +# 6 6 0 1.122 0.251 0.000000 39.3 +# 7 7 0 1.511 0.256 0.000000 41.1 +# 8 8 0 1.346 0.258 0.000000 39.5 +# 9 9 0 1.476 0.245 0.000000 38.7 +# 10 10 0 1.397 0.252 0.000000 41.2 +# 11 11 0 1.299 0.256 0.000000 40.4 +# 12 12 0 1.287 0.248 0.000000 39.7 +# 13 13 0 0.999 0.256 0.000000 39.1 +# 14 14 0 1.191 0.261 0.000000 38.9 +# 15 15 0 1.197 0.259 0.000000 38.7 +# 16 16 0 7.658 0.264 0.000000 41.0 +# 17 17 0 1.427 0.258 0.000000 40.0 +# 18 18 0 1.255 0.262 0.000000 39.1 +# 19 19 0 1.232 0.263 0.000000 38.7 +# 20 20 0 1.085 0.265 0.000000 38.4 +# 21 21 0 1.185 0.254 0.000000 37.9 +# 22 22 0 1.178 0.259 0.000000 38.0 +# 23 23 0 1.135 0.265 0.000000 37.6 +# 24 24 0 1.072 0.265 0.000000 37.0 +# 25 25 0 1.267 0.264 0.000000 36.6 +# 26 26 0 1.329 0.262 0.000000 36.3 +# 27 27 0 1.260 0.267 0.000000 36.3 +# 28 28 0 1.308 0.499 0.000000 36.1 +# 29 29 0 1.189 0.262 0.000000 36.0 +# 30 30 0 1.219 0.263 0.000000 35.6 +# 31 31 0 1.200 0.270 0.000000 36.1 +# 32 32 0 1.320 0.265 0.000000 35.9 +# 34 34 0 0.967 0.264 0.000000 35.3 +# 36 36 0 1.090 0.266 0.000000 35.1 +# 38 38 0 1.500 0.274 0.000000 36.8 +# 40 40 0 0.915 0.266 0.000000 36.2 +# 42 42 0 1.145 0.268 0.000000 36.0 +# 44 44 0 1.169 0.270 0.000000 36.0 +# 46 46 0 0.990 0.272 0.000000 35.9 +# 48 48 0 0.995 0.271 0.000000 35.5 +# 50 50 0 1.040 0.268 0.000000 35.4 +# 53 53 0 0.925 0.274 0.000000 35.2 +# 56 56 0 1.202 0.270 0.000000 35.1 +# 59 59 0 0.744 0.270 0.000000 34.3 +# 62 62 0 0.926 0.270 0.000000 34.1 +# 65 65 0 0.920 0.267 0.000000 34.0 +# 69 69 0 0.838 0.271 0.000000 33.9 +# 73 73 0 0.921 0.270 0.000000 33.9 +# 77 77 0 0.833 0.270 0.000000 33.8 +# 81 81 0 0.939 0.268 0.000000 33.9 +# 85 85 0 0.811 0.272 0.000000 33.7 +# 90 90 0 0.995 0.272 0.000000 34.2 +# 95 95 0 0.739 0.270 0.000000 33.5 +# 100 100 0 0.883 0.273 0.000000 33.2 +# 106 106 0 0.860 0.270 0.000000 32.6 +# 112 112 0 0.828 0.271 0.000000 32.4 +# 118 118 0 1.276 0.273 0.000000 32.2 +# 125 125 0 0.982 0.278 0.000000 32.4 +# 132 132 0 1.076 0.275 0.000000 32.8 +# 139 139 0 0.839 0.279 0.000000 32.3 +# 147 147 0 0.931 0.277 0.000000 32.6 +# 155 155 0 0.918 0.280 0.000000 32.5 +# 164 164 0 0.929 0.282 0.000000 32.8 +# 173 173 0 0.832 0.281 0.000000 32.6 +# 183 183 0 0.912 0.284 0.000000 32.7 +# 194 194 0 0.903 0.287 0.000000 32.6 +# 205 205 0 0.886 0.286 0.000000 32.5 +# 217 217 0 1.086 0.286 0.000000 32.3 +# 230 230 0 0.886 0.286 0.000000 32.5 +# 243 243 0 0.821 0.287 0.000000 32.5 +# 257 257 0 0.804 0.287 0.000000 32.1 +# 272 272 0 0.876 0.315 0.000000 32.0 +# 288 288 0 0.867 0.289 0.000000 31.8 +# 305 305 0 0.849 0.289 0.000000 31.8 +# 323 323 0 2.211 0.299 0.000000 32.1 +# 342 342 0 1.446 0.301 0.000000 32.8 +# 362 362 0 1.032 0.320 0.000000 33.0 +# 383 383 0 1.079 0.301 0.000000 33.4 +# 405 405 0 0.983 0.304 0.000000 33.4 +# 429 429 0 1.005 0.304 0.000000 33.3 +# 454 454 0 0.850 0.321 0.000000 33.0 +# 480 480 0 1.039 0.306 0.000000 33.4 +# 508 508 0 0.984 0.307 0.000000 33.5 +# 538 538 0 1.059 0.320 0.000000 33.6 +# 569 569 0 0.857 0.307 0.000000 33.5 +# 602 602 0 0.997 0.306 0.000000 33.8 +# 637 637 0 0.935 0.320 0.000000 33.7 +# 674 674 0 0.946 0.307 0.000000 33.7 +# 714 714 0 0.940 0.309 0.000000 33.6 +# 756 756 0 1.174 0.308 0.000000 33.8 +# 800 800 0 0.925 0.307 0.000000 34.0 +# 847 847 0 0.908 0.310 0.000000 33.9 +# 897 897 0 0.931 0.308 0.000000 34.0 +# 950 950 0 0.904 0.310 0.000000 34.0 +# 1006 1006 0 0.891 0.318 0.000000 33.9 +# 1065 1065 0 0.842 0.310 0.000000 33.7 +# 1128 1128 0 0.880 0.318 0.000000 33.6 +# 1194 1194 0 0.875 0.312 0.000000 33.6 +# 1264 1264 0 1.027 0.314 0.000000 33.6 +# 1339 1339 0 0.867 0.314 0.000000 33.5 +# 1418 1418 0 0.857 0.320 0.000000 33.3 +# 1502 1502 0 0.962 0.424 0.000000 33.4 +# 1591 1591 0 0.899 0.324 0.000000 33.5 +# 1685 1685 0 0.935 0.323 0.000000 33.5 +# 1784 1784 0 0.936 0.323 0.000000 33.6 +# 1884 1884 0 0.961 0.324 0.000000 33.8 +# 1995 1995 0 0.894 0.325 0.000000 33.7 +# 2113 2113 0 0.883 0.323 0.000000 33.7 +# 2239 2239 0 0.851 0.324 0.000000 33.6 +# 2371 2371 0 0.901 0.329 0.000000 33.5 +# 2512 2512 0 0.937 0.328 0.000000 33.6 +# 2661 2661 0 1.014 0.423 0.000000 33.7 +# 2818 2818 0 1.001 0.423 0.000000 33.7 +# 2985 2985 0 0.983 0.424 0.000000 33.7 +# 3162 3162 0 1.056 0.431 0.000000 33.8 +# 3350 3350 0 0.995 0.431 0.000000 33.7 +# 3548 3548 0 1.012 0.434 0.000000 33.7 +# 3758 3758 0 0.997 0.435 0.000000 33.7 +# 3981 3981 0 1.122 0.600 0.000000 33.8 +# 4217 4217 0 1.111 0.427 0.000000 33.8 +# 4467 4467 0 1.000 0.423 0.000000 33.8 +# 4732 4732 0 1.023 0.429 0.000000 33.8 +# 5012 5012 0 1.016 0.435 0.000000 33.8 +# 5309 5309 0 1.012 0.491 0.000000 33.8 +# 5623 5623 0 1.489 0.473 0.000000 33.8 +# 5957 5957 0 1.029 0.456 0.000000 33.7 +# 6310 6310 0 1.056 0.456 0.000000 33.6 +# 6683 6683 0 1.093 0.463 0.000000 33.5 +# 7079 7079 0 1.102 0.469 0.000000 33.5 +# 7499 7499 0 1.040 0.472 0.000000 33.3 +# 7943 7943 0 1.069 0.425 0.000000 33.2 +# 8414 8414 0 1.042 0.427 0.000000 33.1 +# 8913 8913 0 1.375 0.433 0.000000 33.0 +# 9441 9441 0 1.063 0.434 0.000000 32.9 +# 10000 10000 0 1.042 0.437 0.000000 32.8 +# 10593 10593 0 1.068 0.499 0.000000 32.7 +# 11220 11220 0 1.071 0.437 0.000000 32.6 +# 11885 11885 0 1.010 0.459 0.000000 32.4 +# 12589 12589 0 1.064 0.444 0.000000 32.3 +# 13335 13335 0 1.042 0.445 0.000000 32.2 +# 14125 14125 0 1.053 0.456 0.000000 32.1 +# 14962 14962 0 1.092 0.448 0.000000 32.0 +# 15849 15849 0 1.049 0.449 0.000000 31.9 +# 16788 16788 0 1.065 0.495 0.000000 31.8 +# 17783 17783 0 1.087 0.478 0.000000 31.7 +# 18836 18836 0 1.064 0.458 0.000000 31.7 +# 19953 19953 0 1.059 0.467 0.000000 31.6 +# 21135 21135 0 1.087 0.469 0.000000 31.5 +# 22387 22387 0 1.091 0.507 0.000000 31.5 +# 23714 23714 0 1.116 0.504 0.000000 31.4 +# 25119 25119 0 1.108 0.483 0.000000 31.4 +# 26607 26607 0 1.093 0.499 0.000000 31.3 +# 28184 28184 0 1.104 0.524 0.000000 31.2 +# 29854 29854 0 1.129 0.517 0.000000 31.2 +# 31623 31623 0 1.115 0.516 0.000000 31.1 +# 33497 33497 0 1.230 0.520 0.000000 31.1 +# 35481 35481 0 1.110 0.544 0.000000 31.0 +# 37584 37584 0 1.147 0.542 0.000000 30.9 +# 39811 39811 0 1.141 0.574 0.000000 30.8 +# 42170 42170 0 1.134 0.552 0.000000 30.8 +# 44668 44668 0 1.232 0.600 0.000000 30.7 +# 47315 47315 0 1.183 0.604 0.000000 30.7 +# 50119 50119 0 1.230 0.601 0.000000 30.7 +# 53088 53088 0 1.216 0.589 0.000000 30.6 +# 56234 56234 0 1.176 0.621 0.000000 30.6 +# 59566 59566 0 1.178 0.601 0.000000 30.5 +# 63096 63096 0 1.183 0.616 0.000000 30.5 +# 66834 66834 0 1.205 0.643 0.000000 30.5 +# 70795 70795 0 1.207 0.644 0.000000 30.5 +# 74989 74989 0 1.214 0.634 0.000000 30.4 +# 79433 79433 0 1.270 0.643 0.000000 30.4 +# 84140 84140 0 1.263 0.652 0.000000 30.4 +# 89125 89125 0 1.269 0.660 0.000000 30.4 +# 94406 94406 0 1.342 0.683 0.000000 30.5 +# 100000 100000 0 1.403 0.699 0.000000 30.7 +# 105925 100000 0 1.350 0.699 0.000000 30.8 +# 112202 100000 0 1.378 0.705 0.000000 31.0 +# 118850 100000 0 1.390 0.700 0.000000 31.2 +# 125893 100000 0 1.405 0.710 0.000000 31.4 +# 133352 100000 0 1.534 0.727 0.000000 31.5 +# 141254 100000 0 1.375 0.730 0.000000 31.7 +# 149624 100000 0 1.378 0.739 0.000000 31.8 +# 158489 100000 0 1.603 0.740 0.000000 31.9 +# 167880 100000 0 1.325 0.751 0.000000 31.9 +# 177828 100000 0 1.322 0.755 0.000000 32.0 +# 188365 100000 0 1.333 0.760 0.000000 32.0 +# 199526 100000 0 1.312 0.760 0.000000 32.1 +# 211349 100000 0 1.326 0.768 0.000000 32.1 +# 223872 100000 0 1.320 0.787 0.000000 32.1 +# 237137 100000 0 1.304 0.778 0.000000 32.1 +# 251189 100000 0 1.368 0.769 0.000000 32.1 +# 266073 100000 0 1.324 0.795 0.000000 32.1 +# 281838 100000 0 1.323 0.800 0.000000 32.1 +# 298538 100000 0 1.336 0.827 0.000000 32.0 +# 316228 100000 0 1.349 0.812 0.000000 32.0 +# 334965 100000 0 1.330 0.816 0.000000 32.0 +# 354813 100000 0 1.330 0.816 0.000000 32.0 +# 375837 100000 0 1.358 0.798 0.000000 32.1 +# 398107 100000 0 1.483 0.827 0.000000 32.1 +# 421697 100000 0 1.354 0.832 0.000000 32.2 +# 446684 100000 0 1.353 0.837 0.000000 32.2 +# 473151 100000 0 1.365 0.839 0.000000 32.3 +# 501187 100000 0 1.542 0.846 0.000000 32.3 +# 530884 100000 0 1.345 0.844 0.000000 32.4 +# 562341 100000 0 1.357 0.825 0.000000 32.4 +# 595662 100000 0 1.338 0.830 0.000000 32.5 +# 630957 100000 0 1.349 0.818 0.000000 32.5 +# 668344 100000 0 1.338 0.825 0.000000 32.5 +# 707946 100000 0 1.328 0.817 0.000000 32.5 +# 749894 100000 0 1.331 0.821 0.000000 32.5 +# 794328 100000 0 1.327 0.818 0.000000 32.5 +# 841395 100000 0 1.342 0.820 0.000000 32.4 +# 891251 100000 0 1.318 0.813 0.000000 32.4 +# 944061 100000 0 1.326 0.814 0.000000 32.4 +# 1000000 100000 0 1.316 0.812 0.000000 32.3 +# 1059254 100000 0 1.310 0.810 0.000000 32.3 +# 1122018 100000 0 1.309 0.808 0.000000 32.2 +# 1188502 100000 0 1.506 0.932 0.000000 32.1 +# 1258925 100000 0 1.468 0.810 0.000000 32.0 +# 1333521 100000 0 1.493 0.919 0.000000 32.0 +# 1412538 100000 0 1.445 0.913 0.000000 31.9 +# 1496236 100000 0 1.428 0.908 0.000000 31.8 +# 1584893 100000 0 1.422 0.890 0.000000 31.7 +# 1678804 100000 0 1.396 0.884 0.000000 31.7 +# 1778279 100000 0 1.385 0.824 0.000000 31.6 +# 1883649 100000 0 1.434 0.876 0.000000 31.5 +# 1995262 100000 0 1.415 0.868 0.000000 31.5 +# 2113489 100000 0 1.364 0.850 0.000000 31.4 +# 2238721 100000 0 1.376 0.843 0.000000 31.3 +# 2371374 100000 0 1.380 0.838 0.000000 31.3 +# 2511886 100000 0 1.389 0.851 0.000000 31.2 +# 2660725 100000 0 1.380 0.847 0.000000 31.2 +# 2818383 100000 0 1.382 0.854 0.000000 31.1 +# 2985383 100000 0 1.388 0.861 0.000000 31.0 +# 3162278 100000 0 1.399 0.865 0.000000 31.0 +# 3349654 100000 0 1.425 0.872 0.000000 30.9 +# 3548134 100000 0 1.413 0.882 0.000000 30.8 +# 3758374 100000 0 1.431 0.885 0.000000 30.8 +# 3981072 100000 0 1.428 0.920 0.000000 30.7 +# 4216965 100000 0 1.444 0.902 0.000000 30.6 +# 4466836 100000 0 1.468 0.916 0.000000 30.5 +# 4731513 100000 0 1.466 0.924 0.000000 30.5 +# 5011872 100000 0 1.468 0.930 0.000000 30.4 +# 5308844 100000 0 1.476 0.944 0.000000 30.3 +# 5623413 100000 0 1.482 0.952 0.000000 30.2 +# 5956621 100000 0 1.484 0.962 0.000000 30.1 +# 6309573 100000 0 1.496 0.983 0.000000 30.1 +# 6683439 100000 0 1.530 0.976 0.000000 30.0 +# 7079458 100000 0 1.514 1.006 0.000000 29.9 +# 7498942 100000 0 1.564 1.007 0.000000 29.9 +# 7943282 100000 0 1.550 1.016 0.000000 29.8 +# 8413951 100000 0 1.575 1.036 0.000000 29.7 +# 8912509 100000 0 1.659 1.038 0.000000 29.7 +# 9440609 100000 0 1.630 1.045 0.000000 29.6 +# 10000000 100000 0 1.612 1.180 0.000000 29.6 +# 10592537 100000 0 1.629 1.073 0.000000 29.5 +# 11220185 100000 0 1.650 1.085 0.000000 29.5 +# 11885022 100000 0 1.663 1.101 0.000000 29.5 +# 12589254 100000 0 5.162 1.354 0.000000 29.4 +# 13335214 100000 0 1.689 1.138 0.000000 29.4 +# 14125375 100000 0 1.700 1.138 0.000000 29.3 +# 14962357 100000 0 1.695 1.149 0.000000 29.3 +# Total Duplicate strings = 0 +# Begin JudyHSFreeArray()... +# returned 438636072 bytes +# Free 14962357 strings, 0.621 uSecs Ave/string + +# Pass 1 +# Pass 2 +# Pass 3 +# Pass 4 +# Pass 5 +# Pass 6 +# Pass 7 +# Pass 8 +# Pass 9 +# TotInserts 0 0 InsTime GetTime 0 Ram/String + 1 0 0 6.463 1.451 0 48.000 + 2 0 0 2.444 0.246 0 44.000 + 3 0 0 0.955 0.235 0 41.333 + 4 0 0 0.855 0.227 0 42.000 + 5 0 0 0.794 0.230 0 38.400 + 6 0 0 0.836 0.230 0 36.000 + 7 0 0 0.910 0.230 0 35.429 + 8 0 0 0.887 0.227 0 34.000 + 9 0 0 0.791 0.225 0 32.889 + 10 0 0 0.724 0.232 0 34.400 + 11 0 0 0.818 0.227 0 33.818 + 12 0 0 0.838 0.232 0 34.000 + 13 0 0 0.856 0.242 0 36.923 + 14 0 0 0.705 0.238 0 36.000 + 15 0 0 0.855 0.238 0 35.467 + 16 0 0 0.866 0.240 0 35.500 + 17 0 0 0.858 0.239 0 35.059 + 18 0 0 0.724 0.249 0 35.111 + 19 0 0 0.824 0.248 0 34.947 + 20 0 0 0.924 0.245 0 34.800 + 21 0 0 0.828 0.247 0 35.238 + 22 0 0 0.690 0.246 0 35.091 + 23 0 0 0.827 0.246 0 36.522 + 24 0 0 0.848 0.248 0 36.167 + 25 0 0 0.687 0.252 0 36.000 + 26 0 0 0.712 0.250 0 35.846 + 27 0 0 0.812 0.249 0 36.000 + 28 0 0 0.813 0.249 0 35.714 + 29 0 0 0.858 0.258 0 35.862 + 30 0 0 0.747 0.252 0 35.600 + 31 0 0 0.744 0.253 0 35.097 + 32 0 0 0.789 0.254 0 34.875 + 34 0 0 0.879 0.251 0 35.059 + 36 0 0 0.858 0.258 0 34.667 + 38 0 0 0.807 0.258 0 35.158 + 40 0 0 0.785 0.260 0 35.300 + 42 0 0 0.741 0.263 0 34.667 + 44 0 0 0.852 0.263 0 36.364 + 46 0 0 0.855 0.262 0 36.261 + 48 0 0 0.846 0.267 0 35.750 + 50 0 0 0.752 0.264 0 35.520 + 53 0 0 0.805 0.265 0 34.868 + 56 0 0 0.857 0.269 0 35.071 + 59 0 0 0.744 0.268 0 34.847 + 62 0 0 0.776 0.269 0 35.032 + 65 0 0 0.866 0.267 0 34.646 + 69 0 0 0.744 0.269 0 34.493 + 73 0 0 0.835 0.270 0 35.397 + 77 0 0 0.833 0.268 0 35.273 + 81 0 0 0.857 0.268 0 34.667 + 85 0 0 0.811 0.272 0 34.494 + 90 0 0 0.797 0.269 0 34.489 + 95 0 0 0.739 0.270 0 33.979 + 100 0 0 0.787 0.269 0 33.800 + 106 0 0 0.789 0.270 0 33.547 + 112 0 0 0.828 0.271 0 33.643 + 118 0 0 0.864 0.271 0 33.797 + 125 0 0 0.789 0.276 0 33.248 + 132 0 0 0.809 0.273 0 33.030 + 139 0 0 0.839 0.278 0 32.835 + 147 0 0 0.884 0.276 0 33.252 + 155 0 0 0.857 0.278 0 32.955 + 164 0 0 0.850 0.282 0 32.756 + 173 0 0 0.832 0.281 0 32.462 + 183 0 0 0.806 0.282 0 31.825 + 194 0 0 0.844 0.284 0 31.918 + 205 0 0 0.803 0.282 0 31.493 + 217 0 0 0.903 0.285 0 31.982 + 230 0 0 0.867 0.286 0 31.948 + 243 0 0 0.821 0.287 0 31.802 + 257 0 0 0.804 0.287 0 31.658 + 272 0 0 0.876 0.291 0 31.721 + 288 0 0 0.866 0.287 0 31.792 + 305 0 0 0.848 0.287 0 31.921 + 323 0 0 0.998 0.296 0 31.554 + 342 0 0 0.991 0.291 0 32.281 + 362 0 0 1.032 0.296 0 32.829 + 383 0 0 0.924 0.297 0 32.595 + 405 0 0 0.983 0.298 0 32.523 + 429 0 0 0.934 0.299 0 32.606 + 454 0 0 0.850 0.313 0 33.172 + 480 0 0 1.039 0.306 0 33.008 + 508 0 0 0.984 0.306 0 33.535 + 538 0 0 1.012 0.306 0 33.375 + 569 0 0 0.857 0.307 0 33.230 + 602 0 0 0.913 0.306 0 33.289 + 637 0 0 0.876 0.306 0 33.300 + 674 0 0 0.946 0.307 0 33.193 + 714 0 0 0.935 0.309 0 33.395 + 756 0 0 1.006 0.308 0 33.302 + 800 0 0 0.925 0.307 0 33.255 + 847 0 0 0.908 0.310 0 33.818 + 897 0 0 0.913 0.308 0 33.779 + 950 0 0 0.901 0.310 0 33.625 + 1006 0 0 0.866 0.310 0 33.435 + 1065 0 0 0.842 0.310 0 33.510 + 1128 0 0 0.880 0.312 0 33.394 + 1194 0 0 0.875 0.312 0 33.320 + 1264 0 0 0.855 0.314 0 33.278 + 1339 0 0 0.845 0.313 0 33.177 + 1418 0 0 0.857 0.314 0 33.078 + 1502 0 0 0.903 0.318 0 33.190 + 1591 0 0 0.899 0.319 0 33.360 + 1685 0 0 0.924 0.320 0 33.496 + 1784 0 0 0.898 0.320 0 33.404 + 1884 0 0 0.917 0.322 0 33.231 + 1995 0 0 0.885 0.324 0 33.211 + 2113 0 0 0.883 0.323 0 33.304 + 2239 0 0 0.851 0.324 0 33.402 + 2371 0 0 0.901 0.329 0 33.407 + 2512 0 0 0.937 0.328 0 33.460 + 2661 0 0 0.965 0.420 0 33.514 + 2818 0 0 0.986 0.419 0 33.469 + 2985 0 0 0.983 0.422 0 33.324 + 3162 0 0 0.992 0.426 0 33.264 + 3350 0 0 0.971 0.430 0 33.398 + 3548 0 0 0.982 0.434 0 33.359 + 3758 0 0 0.997 0.435 0 33.420 + 3981 0 0 0.999 0.440 0 33.516 + 4217 0 0 0.981 0.427 0 33.525 + 4467 0 0 1.000 0.420 0 33.595 + 4732 0 0 0.957 0.425 0 33.515 + 5012 0 0 0.950 0.435 0 33.534 + 5309 0 0 0.993 0.439 0 33.481 + 5623 0 0 0.971 0.441 0 33.435 + 5957 0 0 0.948 0.446 0 33.427 + 6310 0 0 0.982 0.451 0 33.374 + 6683 0 0 0.968 0.458 0 33.235 + 7079 0 0 0.963 0.469 0 33.154 + 7499 0 0 0.999 0.468 0 33.120 + 7943 0 0 1.007 0.425 0 33.031 + 8414 0 0 0.977 0.427 0 32.928 + 8913 0 0 1.039 0.433 0 32.851 + 9441 0 0 1.031 0.434 0 32.744 + 10000 0 0 1.010 0.437 0 32.649 + 10593 0 0 1.050 0.487 0 32.585 + 11220 0 0 1.007 0.437 0 32.440 + 11885 0 0 1.010 0.437 0 32.312 + 12589 0 0 0.973 0.440 0 32.236 + 13335 0 0 0.991 0.445 0 32.098 + 14125 0 0 0.984 0.444 0 31.988 + 14962 0 0 1.092 0.447 0 31.878 + 15849 0 0 0.994 0.444 0 31.790 + 16788 0 0 0.985 0.447 0 31.697 + 17783 0 0 0.994 0.451 0 31.628 + 18836 0 0 1.007 0.455 0 31.562 + 19953 0 0 1.002 0.459 0 31.544 + 21135 0 0 1.016 0.469 0 31.482 + 22387 0 0 1.016 0.474 0 31.438 + 23714 0 0 1.019 0.475 0 31.371 + 25119 0 0 1.052 0.483 0 31.315 + 26607 0 0 1.026 0.493 0 31.245 + 28184 0 0 1.033 0.496 0 31.192 + 29854 0 0 1.048 0.499 0 31.114 + 31623 0 0 1.053 0.510 0 31.061 + 33497 0 0 1.092 0.520 0 31.005 + 35481 0 0 1.075 0.527 0 30.960 + 37584 0 0 1.095 0.535 0 30.904 + 39811 0 0 1.127 0.543 0 30.849 + 42170 0 0 1.089 0.552 0 30.757 + 44668 0 0 1.119 0.559 0 30.711 + 47315 0 0 1.113 0.566 0 30.671 + 50119 0 0 1.129 0.576 0 30.635 + 53088 0 0 1.144 0.589 0 30.635 + 56234 0 0 1.171 0.597 0 30.595 + 59566 0 0 1.146 0.601 0 30.567 + 63096 0 0 1.152 0.607 0 30.533 + 66834 0 0 1.155 0.617 0 30.465 + 70795 0 0 1.172 0.629 0 30.434 + 74989 0 0 1.214 0.634 0 30.390 + 79433 0 0 1.199 0.643 0 30.414 + 84140 0 0 1.219 0.652 0 30.395 + 89125 0 0 1.238 0.658 0 30.416 + 94406 0 0 1.272 0.671 0 30.521 + 100000 0 0 1.300 0.672 0 30.589 + 105925 0 0 1.326 0.699 0 30.778 + 112202 0 0 1.363 0.705 0 31.016 + 118850 0 0 1.353 0.698 0 31.189 + 125893 0 0 1.351 0.702 0 31.389 + 133352 0 0 1.334 0.710 0 31.545 + 141254 0 0 1.312 0.710 0 31.709 + 149624 0 0 1.314 0.719 0 31.804 + 158489 0 0 1.286 0.731 0 31.886 + 167880 0 0 1.292 0.724 0 31.953 + 177828 0 0 1.269 0.733 0 32.006 + 188365 0 0 1.277 0.739 0 32.049 + 199526 0 0 1.277 0.742 0 32.057 + 211349 0 0 1.275 0.742 0 32.075 + 223872 0 0 1.260 0.750 0 32.078 + 237137 0 0 1.267 0.765 0 32.081 + 251189 0 0 1.270 0.761 0 32.079 + 266073 0 0 1.271 0.769 0 32.075 + 281838 0 0 1.276 0.772 0 32.063 + 298538 0 0 1.277 0.778 0 32.058 + 316228 0 0 1.316 0.788 0 32.033 + 334965 0 0 1.286 0.784 0 32.016 + 354813 0 0 1.294 0.788 0 32.052 + 375837 0 0 1.306 0.791 0 32.083 + 398107 0 0 1.305 0.785 0 32.123 + 421697 0 0 1.349 0.797 0 32.168 + 446684 0 0 1.314 0.794 0 32.219 + 473151 0 0 1.336 0.805 0 32.273 + 501187 0 0 1.304 0.806 0 32.318 + 530884 0 0 1.341 0.812 0 32.371 + 562341 0 0 1.318 0.813 0 32.419 + 595662 0 0 1.308 0.816 0 32.453 + 630957 0 0 1.297 0.818 0 32.474 + 668344 0 0 1.283 0.823 0 32.484 + 707946 0 0 1.328 0.817 0 32.481 + 749894 0 0 1.282 0.821 0 32.470 + 794328 0 0 1.324 0.818 0 32.449 + 841395 0 0 1.318 0.820 0 32.417 + 891251 0 0 1.317 0.813 0 32.375 + 944061 0 0 1.319 0.814 0 32.329 + 1000000 0 0 1.294 0.812 0 32.282 + 1059254 0 0 1.310 0.810 0 32.222 + 1122018 0 0 1.303 0.808 0 32.158 + 1188502 0 0 1.302 0.823 0 32.085 + 1258925 0 0 1.267 0.810 0 32.009 + 1333521 0 0 1.246 0.813 0 31.930 + 1412538 0 0 1.254 0.819 0 31.848 + 1496236 0 0 1.250 0.819 0 31.772 + 1584893 0 0 1.257 0.827 0 31.698 + 1678804 0 0 1.261 0.822 0 31.623 + 1778279 0 0 1.278 0.824 0 31.553 + 1883649 0 0 1.280 0.871 0 31.491 + 1995262 0 0 1.325 0.844 0 31.428 + 2113489 0 0 1.325 0.841 0 31.372 + 2238721 0 0 1.298 0.843 0 31.313 + 2371374 0 0 1.314 0.838 0 31.254 + 2511886 0 0 1.319 0.851 0 31.196 + 2660725 0 0 1.330 0.847 0 31.136 + 2818383 0 0 1.332 0.854 0 31.073 + 2985383 0 0 1.356 0.861 0 31.009 + 3162278 0 0 1.375 0.865 0 30.943 + 3349654 0 0 1.374 0.872 0 30.874 + 3548134 0 0 1.370 0.882 0 30.803 + 3758374 0 0 1.388 0.885 0 30.729 + 3981072 0 0 1.378 0.894 0 30.654 + 4216965 0 0 1.382 0.902 0 30.578 + 4466836 0 0 1.394 0.904 0 30.500 + 4731513 0 0 1.421 0.924 0 30.422 + 5011872 0 0 1.431 0.930 0 30.343 + 5308844 0 0 1.437 0.944 0 30.265 + 5623413 0 0 1.443 0.952 0 30.188 + 5956621 0 0 1.453 0.962 0 30.113 + 6309573 0 0 1.444 0.974 0 30.042 + 6683439 0 0 1.459 0.976 0 29.974 + 7079458 0 0 1.480 0.985 0 29.909 + 7498942 0 0 1.489 1.007 0 29.848 + 7943282 0 0 1.506 1.016 0 29.789 + 8413951 0 0 1.519 1.017 0 29.731 + 8912509 0 0 1.527 1.038 0 29.677 + 9440609 0 0 1.547 1.045 0 29.624 + 10000000 0 0 1.553 1.061 0 29.573 + 10592537 0 0 1.576 1.073 0 29.527 + 11220185 0 0 1.590 1.082 0 29.484 + 11885022 0 0 1.603 1.086 0 29.444 + 12589254 0 0 1.603 1.103 0 29.407 + 13335214 0 0 1.621 1.105 0 29.373 + 14125375 0 0 1.636 1.120 0 29.343 + 14962357 0 0 1.646 1.137 0 29.316 diff --git a/feeds/p4/libjudy/src/test/Centrino_1.3Mhz_Plots/JudySL_CO.plot b/feeds/p4/libjudy/src/test/Centrino_1.3Mhz_Plots/JudySL_CO.plot new file mode 100644 index 000000000..b3377bb69 --- /dev/null +++ b/feeds/p4/libjudy/src/test/Centrino_1.3Mhz_Plots/JudySL_CO.plot @@ -0,0 +1,567 @@ +# StringCompare -n16788040 -A JudySL -P40 -L10 -C -M100000 /home/data/domnames.txt +# This file is in a format to input to 'jbgraph' +# XLABEL Stored +# YLABEL Microseconds / Index +# COLHEAD 1 Total Insert attempts +# COLHEAD 2 Number Gets +# COLHEAD 3 Duplicate strings +# COLHEAD 4 Insert Time (uS) +# COLHEAD 5 Get Time (uS) +# COLHEAD 6 Hash Chain Length +# COLHEAD 7 Average RAM/String +# Linux localhost 2.6.3-4mdkenterprise #1 SMP Tue Mar 2 07:00:53 CET 2004 i686 +# 32 Bit CPU +# Processor speed compiled at 1299 Mhz +# 12587648 (75.0%) non-Word_t aligned string buffers +# Ram used for input data = 418243455 bytes +# Average string length = 15.9 bytes +# 3200000 bytes malloc() for 'cached' strings for Get measurement +# Access Time = 0.101 uS average per string (mostly from Cache) +# HashStr() Time = 0.270 uS average per string (mostly from Cache) +# Access Time = 0.296 uS average per string (mostly from RAM) +# HashStr() Time = 0.482 uS average per string (mostly from RAM) +# Pass 0 +# TotInserts DeltaGets DupStrs InsTime GetTime HChainLen Ram/String +# 1 1 0 24.309 5.002 0.000000 16.0 +# 2 2 0 21.507 0.328 0.000000 26.0 +# 3 3 0 1.485 0.184 0.000000 25.3 +# 4 4 0 1.438 0.173 0.000000 28.0 +# 5 5 0 1.045 0.183 0.000000 25.6 +# 6 6 0 1.435 0.172 0.000000 27.3 +# 7 7 0 0.820 0.166 0.000000 25.1 +# 8 8 0 1.261 0.157 0.000000 27.5 +# 9 9 0 1.092 0.159 0.000000 26.2 +# 10 10 0 0.993 0.154 0.000000 25.6 +# 11 11 0 1.030 0.156 0.000000 24.4 +# 12 12 0 2.002 0.157 0.000000 26.7 +# 13 13 0 1.041 0.153 0.000000 25.5 +# 14 14 0 0.993 0.151 0.000000 25.1 +# 15 15 0 1.127 0.152 0.000000 24.5 +# 16 16 0 6.505 0.167 0.000000 28.5 +# 17 17 0 1.215 0.163 0.000000 28.0 +# 18 18 0 1.001 0.159 0.000000 27.3 +# 19 19 0 0.945 0.163 0.000000 26.5 +# 20 20 0 0.935 0.159 0.000000 25.8 +# 21 21 0 1.032 0.159 0.000000 25.5 +# 22 22 0 1.381 0.160 0.000000 25.3 +# 23 23 0 1.505 0.167 0.000000 25.4 +# 24 24 0 2.011 0.165 0.000000 27.5 +# 25 25 0 1.118 0.160 0.000000 27.0 +# 26 26 0 0.883 0.162 0.000000 26.8 +# 27 27 0 1.025 0.158 0.000000 26.4 +# 28 28 0 1.024 0.164 0.000000 25.9 +# 29 29 0 0.938 0.163 0.000000 25.9 +# 30 30 0 1.272 0.159 0.000000 25.9 +# 31 31 0 1.132 0.165 0.000000 25.4 +# 32 32 0 26.102 0.294 0.000000 31.5 +# 34 34 0 1.351 0.228 0.000000 31.2 +# 36 36 0 1.230 0.228 0.000000 31.0 +# 38 38 0 1.286 0.230 0.000000 31.3 +# 40 40 0 1.182 0.225 0.000000 31.1 +# 42 42 0 1.211 0.233 0.000000 31.4 +# 44 44 0 1.158 0.285 0.000000 31.0 +# 46 46 0 1.280 0.234 0.000000 30.8 +# 48 48 0 1.042 0.235 0.000000 30.6 +# 50 50 0 1.325 0.236 0.000000 30.8 +# 53 53 0 1.140 0.238 0.000000 30.6 +# 56 56 0 1.038 0.235 0.000000 30.3 +# 59 59 0 1.012 0.234 0.000000 30.2 +# 62 62 0 1.834 0.240 0.000000 30.5 +# 65 65 0 1.084 0.239 0.000000 30.4 +# 69 69 0 1.006 0.240 0.000000 30.2 +# 73 73 0 0.838 0.240 0.000000 29.6 +# 77 77 0 0.969 0.244 0.000000 29.8 +# 81 81 0 1.057 0.241 0.000000 29.7 +# 85 85 0 0.920 0.247 0.000000 29.6 +# 90 90 0 0.873 0.245 0.000000 29.1 +# 95 95 0 1.041 0.248 0.000000 29.1 +# 100 100 0 1.169 0.252 0.000000 29.0 +# 106 106 0 1.025 0.254 0.000000 29.4 +# 112 112 0 0.992 0.314 0.000000 29.0 +# 118 118 0 0.902 0.257 0.000000 28.6 +# 125 125 0 1.013 0.256 0.000000 28.8 +# 132 132 0 1.438 0.258 0.000000 28.7 +# 139 139 0 0.984 0.257 0.000000 28.8 +# 147 147 0 1.134 0.260 0.000000 29.5 +# 155 155 0 1.127 0.264 0.000000 29.5 +# 164 164 0 0.975 0.261 0.000000 29.1 +# 173 173 0 0.924 0.267 0.000000 28.6 +# 183 183 0 1.115 0.267 0.000000 28.6 +# 194 194 0 1.188 0.272 0.000000 29.1 +# 205 205 0 1.063 0.272 0.000000 28.7 +# 217 217 0 1.030 0.273 0.000000 28.7 +# 230 230 0 0.879 0.274 0.000000 28.2 +# 243 243 0 1.329 0.274 0.000000 28.1 +# 257 257 0 1.788 0.279 0.000000 28.9 +# 272 272 0 0.900 0.277 0.000000 28.6 +# 288 288 0 1.180 0.276 0.000000 28.8 +# 305 305 0 1.091 0.276 0.000000 28.6 +# 323 323 0 1.082 0.284 0.000000 28.4 +# 342 342 0 1.313 0.277 0.000000 28.9 +# 362 362 0 1.203 0.280 0.000000 28.8 +# 383 383 0 1.041 0.282 0.000000 28.8 +# 405 405 0 1.047 0.283 0.000000 28.9 +# 429 429 0 0.988 0.285 0.000000 28.7 +# 454 454 0 1.055 0.286 0.000000 28.5 +# 480 480 0 1.300 0.287 0.000000 28.8 +# 508 508 0 1.050 0.291 0.000000 28.6 +# 538 538 0 1.133 0.300 0.000000 28.5 +# 569 569 0 1.041 0.289 0.000000 28.3 +# 602 602 0 1.161 0.294 0.000000 28.3 +# 637 637 0 1.178 0.298 0.000000 28.5 +# 674 674 0 1.167 0.287 0.000000 28.5 +# 714 714 0 1.180 0.287 0.000000 28.5 +# 756 756 0 1.364 0.286 0.000000 28.7 +# 800 800 0 1.087 0.290 0.000000 28.4 +# 847 847 0 1.186 0.290 0.000000 28.3 +# 897 897 0 1.218 0.277 0.000000 30.2 +# 950 950 0 1.147 0.276 0.000000 30.1 +# 1006 1006 0 1.059 0.283 0.000000 29.9 +# 1065 1065 0 1.245 0.280 0.000000 29.7 +# 1128 1128 0 1.164 0.286 0.000000 29.5 +# 1194 1194 0 1.136 0.282 0.000000 29.3 +# 1264 1264 0 1.176 0.282 0.000000 29.3 +# 1339 1339 0 1.160 0.287 0.000000 30.5 +# 1418 1418 0 1.123 0.289 0.000000 30.3 +# 1502 1502 0 1.163 0.285 0.000000 30.0 +# 1591 1591 0 1.284 0.286 0.000000 30.0 +# 1685 1685 0 1.158 0.288 0.000000 30.0 +# 1784 1784 0 1.149 0.289 0.000000 30.7 +# 1884 1884 0 1.093 0.289 0.000000 30.4 +# 1995 1995 0 1.241 0.292 0.000000 30.2 +# 2113 2113 0 1.217 0.297 0.000000 30.1 +# 2239 2239 0 1.161 0.297 0.000000 30.6 +# 2371 2371 0 1.135 0.296 0.000000 30.4 +# 2512 2512 0 1.093 0.301 0.000000 30.2 +# 2661 2661 0 1.096 0.302 0.000000 30.0 +# 2818 2818 0 1.193 0.359 0.000000 30.4 +# 2985 2985 0 1.238 0.303 0.000000 30.2 +# 3162 3162 0 1.119 0.303 0.000000 29.9 +# 3350 3350 0 1.229 0.302 0.000000 30.3 +# 3548 3548 0 1.257 0.307 0.000000 30.1 +# 3758 3758 0 1.177 0.311 0.000000 29.9 +# 3981 3981 0 1.293 0.311 0.000000 30.3 +# 4217 4217 0 1.178 0.316 0.000000 30.0 +# 4467 4467 0 1.215 0.318 0.000000 30.2 +# 4732 4732 0 1.200 0.321 0.000000 30.0 +# 5012 5012 0 1.187 0.326 0.000000 29.7 +# 5309 5309 0 1.276 0.330 0.000000 29.9 +# 5623 5623 0 1.208 0.330 0.000000 30.0 +# 5957 5957 0 1.234 0.337 0.000000 29.8 +# 6310 6310 0 1.297 0.338 0.000000 30.0 +# 6683 6683 0 1.245 0.344 0.000000 29.8 +# 7079 7079 0 1.275 0.350 0.000000 29.9 +# 7499 7499 0 1.287 0.352 0.000000 29.6 +# 7943 7943 0 1.257 0.356 0.000000 29.7 +# 8414 8414 0 1.249 0.357 0.000000 29.7 +# 8913 8913 0 1.263 0.362 0.000000 29.5 +# 9441 9441 0 1.230 0.363 0.000000 29.3 +# 10000 10000 0 1.226 0.369 0.000000 29.1 +# 10593 10593 0 1.257 0.371 0.000000 28.9 +# 11220 11220 0 1.308 0.377 0.000000 28.8 +# 11885 11885 0 1.276 0.409 0.000000 28.6 +# 12589 12589 0 1.283 0.398 0.000000 28.4 +# 13335 13335 0 1.318 0.450 0.000000 28.5 +# 14125 14125 0 1.309 0.392 0.000000 28.5 +# 14962 14962 0 1.280 0.395 0.000000 28.3 +# 15849 15849 0 1.304 0.400 0.000000 28.2 +# 16788 16788 0 1.295 0.405 0.000000 28.0 +# 17783 17783 0 1.324 0.411 0.000000 27.9 +# 18836 18836 0 1.338 0.416 0.000000 27.8 +# 19953 19953 0 1.353 0.426 0.000000 27.8 +# 21135 21135 0 1.342 0.429 0.000000 27.8 +# 22387 22387 0 1.365 0.448 0.000000 27.8 +# 23714 23714 0 1.343 0.451 0.000000 27.8 +# 25119 25119 0 1.361 0.452 0.000000 27.8 +# 26607 26607 0 1.482 0.469 0.000000 27.7 +# 28184 28184 0 1.368 0.479 0.000000 27.7 +# 29854 29854 0 1.350 0.477 0.000000 27.6 +# 31623 31623 0 1.477 0.511 0.000000 27.6 +# 33497 33497 0 1.397 0.501 0.000000 27.5 +# 35481 35481 0 1.496 0.515 0.000000 27.5 +# 37584 37584 0 1.404 0.529 0.000000 27.4 +# 39811 39811 0 1.420 0.543 0.000000 27.4 +# 42170 42170 0 1.443 0.554 0.000000 27.4 +# 44668 44668 0 1.439 0.568 0.000000 27.3 +# 47315 47315 0 1.469 0.592 0.000000 27.3 +# 50119 50119 0 1.473 0.593 0.000000 27.3 +# 53088 53088 0 1.524 0.623 0.000000 27.2 +# 56234 56234 0 1.491 0.617 0.000000 27.2 +# 59566 59566 0 1.510 0.631 0.000000 27.1 +# 63096 63096 0 1.508 0.644 0.000000 27.1 +# 66834 66834 0 1.517 0.667 0.000000 27.0 +# 70795 70795 0 1.549 0.688 0.000000 26.9 +# 74989 74989 0 1.614 0.689 0.000000 26.9 +# 79433 79433 0 1.573 0.701 0.000000 26.8 +# 84140 84140 0 1.596 0.715 0.000000 26.8 +# 89125 89125 0 1.594 0.731 0.000000 26.8 +# 94406 94406 0 1.602 0.742 0.000000 26.7 +# 100000 100000 0 1.631 0.755 0.000000 26.7 +# 105925 100000 0 1.646 0.773 0.000000 26.6 +# 112202 100000 0 1.691 0.788 0.000000 26.6 +# 118850 100000 0 1.721 0.808 0.000000 26.5 +# 125893 100000 0 1.695 0.810 0.000000 26.5 +# 133352 100000 0 1.785 0.823 0.000000 26.5 +# 141254 100000 0 1.755 0.835 0.000000 26.4 +# 149624 100000 0 1.781 0.859 0.000000 26.4 +# 158489 100000 0 1.784 0.868 0.000000 26.4 +# 167880 100000 0 1.762 0.889 0.000000 26.3 +# 177828 100000 0 1.789 0.896 0.000000 26.3 +# 188365 100000 0 1.820 0.904 0.000000 26.2 +# 199526 100000 0 1.830 0.914 0.000000 26.1 +# 211349 100000 0 1.870 0.930 0.000000 26.1 +# 223872 100000 0 1.861 0.944 0.000000 26.0 +# 237137 100000 0 1.862 0.967 0.000000 26.0 +# 251189 100000 0 1.894 0.975 0.000000 25.9 +# 266073 100000 0 1.906 0.985 0.000000 25.9 +# 281838 100000 0 1.942 1.006 0.000000 25.8 +# 298538 100000 0 1.997 1.027 0.000000 25.8 +# 316228 100000 0 1.965 1.029 0.000000 25.7 +# 334965 100000 0 1.966 1.042 0.000000 25.7 +# 354813 100000 0 1.975 1.054 0.000000 25.6 +# 375837 100000 0 1.999 1.074 0.000000 25.6 +# 398107 100000 0 2.026 1.083 0.000000 25.6 +# 421697 100000 0 2.046 1.094 0.000000 25.5 +# 446684 100000 0 2.057 1.117 0.000000 25.5 +# 473151 100000 0 2.069 1.124 0.000000 25.4 +# 501187 100000 0 2.083 1.135 0.000000 25.4 +# 530884 100000 0 2.112 1.153 0.000000 25.3 +# 562341 100000 0 2.116 1.164 0.000000 25.3 +# 595662 100000 0 2.148 1.179 0.000000 25.2 +# 630957 100000 0 2.182 1.195 0.000000 25.2 +# 668344 100000 0 2.206 1.207 0.000000 25.2 +# 707946 100000 0 2.183 1.228 0.000000 25.1 +# 749894 100000 0 2.186 1.233 0.000000 25.1 +# 794328 100000 0 2.216 1.251 0.000000 25.0 +# 841395 100000 0 2.243 1.260 0.000000 25.0 +# 891251 100000 0 2.254 1.270 0.000000 25.0 +# 944061 100000 0 2.272 1.285 0.000000 24.9 +# 1000000 100000 0 2.274 1.304 0.000000 24.9 +# 1059254 100000 0 2.300 1.312 0.000000 24.8 +# 1122018 100000 0 2.307 1.339 0.000000 24.8 +# 1188502 100000 0 2.321 1.345 0.000000 24.7 +# 1258925 100000 0 2.341 1.349 0.000000 24.7 +# 1333521 100000 0 2.351 1.373 0.000000 24.7 +# 1412538 100000 0 2.367 1.383 0.000000 24.6 +# 1496236 100000 0 2.396 1.393 0.000000 24.6 +# 1584893 100000 0 2.407 1.404 0.000000 24.5 +# 1678804 100000 0 2.427 1.415 0.000000 24.5 +# 1778279 100000 0 2.432 1.432 0.000000 24.4 +# 1883649 100000 0 2.460 1.444 0.000000 24.4 +# 1995262 100000 0 2.459 1.461 0.000000 24.4 +# 2113489 100000 0 2.493 1.471 0.000000 24.3 +# 2238721 100000 0 2.502 1.496 0.000000 24.3 +# 2371374 100000 0 2.530 1.508 0.000000 24.3 +# 2511886 100000 0 2.538 1.516 0.000000 24.2 +# 2660725 100000 0 2.551 1.539 0.000000 24.2 +# 2818383 100000 0 2.578 1.543 0.000000 24.1 +# 2985383 100000 0 2.590 1.562 0.000000 24.1 +# 3162278 100000 0 2.617 1.576 0.000000 24.1 +# 3349654 100000 0 2.625 1.615 0.000000 24.0 +# 3548134 100000 0 2.650 1.621 0.000000 24.0 +# 3758374 100000 0 2.679 1.642 0.000000 23.9 +# 3981072 100000 0 2.701 1.659 0.000000 23.9 +# 4216965 100000 0 2.722 1.671 0.000000 23.9 +# 4466836 100000 0 2.752 1.690 0.000000 23.8 +# 4731513 100000 0 2.772 1.707 0.000000 23.8 +# 5011872 100000 0 2.792 1.730 0.000000 23.7 +# 5308844 100000 0 3.166 1.753 0.000000 23.7 +# 5623413 100000 0 2.819 1.757 0.000000 23.7 +# 5956621 100000 0 2.841 1.776 0.000000 23.6 +# 6309573 100000 0 2.864 1.804 0.000000 23.6 +# 6683439 100000 0 2.885 1.807 0.000000 23.5 +# 7079458 100000 0 2.910 1.849 0.000000 23.5 +# 7498942 100000 0 2.932 1.865 0.000000 23.4 +# 7943282 100000 0 2.956 1.880 0.000000 23.4 +# 8413951 100000 0 2.989 1.914 0.000000 23.3 +# 8912509 100000 0 3.009 1.928 0.000000 23.3 +# 9440609 100000 0 3.035 1.950 0.000000 23.2 +# 10000000 100000 0 3.067 1.981 0.000000 23.2 +# 10592537 100000 0 3.109 2.017 0.000000 23.1 +# 11220185 100000 0 3.118 2.044 0.000000 23.1 +# 11885022 100000 0 3.151 2.074 0.000000 23.0 +# 12589254 100000 0 3.184 2.092 0.000000 23.0 +# 13335214 100000 0 3.202 2.133 0.000000 22.9 +# 14125375 100000 0 3.230 2.148 0.000000 22.8 +# 14962357 100000 0 3.258 2.190 0.000000 22.8 +# 15848932 100000 0 3.281 2.220 0.000000 22.7 +# 16788040 100000 0 3.319 2.228 0.000000 22.6 +# Total Duplicate strings = 0 +# Begin JudySLFreeArray()... +# returned 380043160 bytes +# Free 16788040 strings, 0.615 uSecs Ave/string + +# Pass 1 +# Pass 2 +# Pass 3 +# Pass 4 +# Pass 5 +# Pass 6 +# Pass 7 +# Pass 8 +# Pass 9 +# TotInserts 0 0 InsTime GetTime 0 Ram/String + 1 0 0 4.734 0.951 0 20.000 + 2 0 0 4.802 0.251 0 24.000 + 3 0 0 0.851 0.143 0 26.667 + 4 0 0 0.893 0.150 0 28.000 + 5 0 0 0.708 0.151 0 28.000 + 6 0 0 0.871 0.145 0 28.667 + 7 0 0 0.661 0.151 0 26.286 + 8 0 0 1.261 0.149 0 30.000 + 9 0 0 0.634 0.150 0 28.000 + 10 0 0 0.647 0.151 0 28.000 + 11 0 0 0.634 0.143 0 26.909 + 12 0 0 1.137 0.149 0 29.000 + 13 0 0 0.640 0.153 0 28.308 + 14 0 0 0.634 0.148 0 27.429 + 15 0 0 0.644 0.149 0 27.200 + 16 0 0 1.163 0.161 0 30.750 + 17 0 0 0.707 0.153 0 30.353 + 18 0 0 0.669 0.152 0 29.556 + 19 0 0 0.694 0.155 0 29.053 + 20 0 0 0.675 0.153 0 28.800 + 21 0 0 0.664 0.155 0 28.762 + 22 0 0 0.732 0.160 0 28.000 + 23 0 0 0.631 0.154 0 27.478 + 24 0 0 0.905 0.158 0 29.500 + 25 0 0 0.661 0.158 0 28.960 + 26 0 0 0.681 0.159 0 28.615 + 27 0 0 0.695 0.158 0 28.148 + 28 0 0 0.706 0.156 0 27.714 + 29 0 0 0.672 0.161 0 27.172 + 30 0 0 0.663 0.159 0 27.067 + 31 0 0 0.686 0.159 0 26.710 + 32 0 0 0.978 0.177 0 33.625 + 34 0 0 0.814 0.174 0 33.294 + 36 0 0 0.962 0.218 0 33.111 + 38 0 0 0.774 0.222 0 32.632 + 40 0 0 0.839 0.220 0 32.000 + 42 0 0 0.798 0.225 0 32.190 + 44 0 0 0.848 0.226 0 31.636 + 46 0 0 0.844 0.229 0 30.957 + 48 0 0 0.828 0.226 0 31.167 + 50 0 0 0.802 0.230 0 30.480 + 53 0 0 0.811 0.230 0 30.415 + 56 0 0 0.897 0.234 0 29.714 + 59 0 0 0.863 0.233 0 29.492 + 62 0 0 0.925 0.236 0 29.742 + 65 0 0 0.858 0.235 0 29.231 + 69 0 0 0.848 0.238 0 29.449 + 73 0 0 0.784 0.240 0 29.151 + 77 0 0 0.855 0.237 0 28.883 + 81 0 0 0.887 0.241 0 29.185 + 85 0 0 0.894 0.247 0 29.271 + 90 0 0 0.873 0.245 0 29.289 + 95 0 0 0.849 0.248 0 29.600 + 100 0 0 0.859 0.252 0 29.640 + 106 0 0 0.943 0.254 0 29.547 + 112 0 0 0.872 0.258 0 29.071 + 118 0 0 0.902 0.257 0 29.119 + 125 0 0 0.833 0.256 0 28.960 + 132 0 0 0.873 0.258 0 28.515 + 139 0 0 0.918 0.257 0 28.259 + 147 0 0 0.888 0.260 0 27.918 + 155 0 0 0.869 0.264 0 28.077 + 164 0 0 0.936 0.261 0 28.000 + 173 0 0 0.907 0.267 0 27.838 + 183 0 0 0.870 0.267 0 27.366 + 194 0 0 0.916 0.272 0 27.485 + 205 0 0 0.950 0.272 0 28.078 + 217 0 0 0.915 0.273 0 28.111 + 230 0 0 0.879 0.274 0 27.826 + 243 0 0 0.973 0.274 0 27.934 + 257 0 0 0.944 0.279 0 28.000 + 272 0 0 0.900 0.277 0 27.676 + 288 0 0 0.999 0.276 0 27.444 + 305 0 0 0.918 0.276 0 27.370 + 323 0 0 1.051 0.284 0 27.641 + 342 0 0 1.090 0.277 0 28.082 + 362 0 0 1.065 0.280 0 27.878 + 383 0 0 1.041 0.282 0 28.010 + 405 0 0 1.026 0.283 0 28.425 + 429 0 0 0.988 0.285 0 28.177 + 454 0 0 1.055 0.286 0 28.467 + 480 0 0 1.094 0.287 0 28.042 + 508 0 0 1.050 0.291 0 28.126 + 538 0 0 1.096 0.298 0 28.416 + 569 0 0 1.041 0.289 0 28.359 + 602 0 0 1.161 0.294 0 28.332 + 637 0 0 1.178 0.298 0 28.509 + 674 0 0 1.167 0.287 0 28.641 + 714 0 0 1.170 0.287 0 28.958 + 756 0 0 1.270 0.286 0 28.841 + 800 0 0 1.087 0.290 0 28.610 + 847 0 0 1.186 0.290 0 28.434 + 897 0 0 1.218 0.277 0 30.100 + 950 0 0 1.106 0.276 0 30.097 + 1006 0 0 1.059 0.283 0 29.920 + 1065 0 0 1.129 0.280 0 29.923 + 1128 0 0 1.058 0.286 0 29.652 + 1194 0 0 1.067 0.282 0 29.471 + 1264 0 0 1.176 0.282 0 29.256 + 1339 0 0 1.092 0.287 0 29.028 + 1418 0 0 1.081 0.289 0 28.996 + 1502 0 0 1.093 0.285 0 30.088 + 1591 0 0 1.036 0.286 0 29.715 + 1685 0 0 1.063 0.288 0 29.550 + 1784 0 0 1.094 0.289 0 29.330 + 1884 0 0 1.084 0.289 0 29.246 + 1995 0 0 1.066 0.292 0 30.129 + 2113 0 0 1.097 0.297 0 29.925 + 2239 0 0 1.128 0.297 0 29.747 + 2371 0 0 1.103 0.296 0 29.545 + 2512 0 0 1.082 0.301 0 30.013 + 2661 0 0 1.080 0.302 0 29.844 + 2818 0 0 1.135 0.322 0 29.612 + 2985 0 0 1.074 0.303 0 29.994 + 3162 0 0 1.099 0.303 0 29.736 + 3350 0 0 1.100 0.302 0 29.586 + 3548 0 0 1.092 0.307 0 29.948 + 3758 0 0 1.133 0.311 0 29.824 + 3981 0 0 1.127 0.311 0 29.521 + 4217 0 0 1.144 0.316 0 29.796 + 4467 0 0 1.165 0.318 0 29.630 + 4732 0 0 1.137 0.321 0 29.863 + 5012 0 0 1.149 0.326 0 29.686 + 5309 0 0 1.137 0.330 0 29.922 + 5623 0 0 1.110 0.330 0 29.685 + 5957 0 0 1.152 0.337 0 29.730 + 6310 0 0 1.149 0.338 0 29.636 + 6683 0 0 1.169 0.344 0 29.757 + 7079 0 0 1.188 0.350 0 29.522 + 7499 0 0 1.172 0.352 0 29.485 + 7943 0 0 1.184 0.356 0 29.481 + 8414 0 0 1.177 0.357 0 29.364 + 8913 0 0 1.173 0.362 0 29.487 + 9441 0 0 1.176 0.363 0 29.274 + 10000 0 0 1.182 0.369 0 29.111 + 10593 0 0 1.205 0.371 0 28.880 + 11220 0 0 1.197 0.377 0 28.883 + 11885 0 0 1.200 0.409 0 28.710 + 12589 0 0 1.207 0.398 0 28.586 + 13335 0 0 1.224 0.420 0 28.478 + 14125 0 0 1.213 0.392 0 28.337 + 14962 0 0 1.224 0.395 0 28.230 + 15849 0 0 1.243 0.400 0 28.074 + 16788 0 0 1.244 0.405 0 27.968 + 17783 0 0 1.261 0.411 0 27.827 + 18836 0 0 1.272 0.416 0 27.712 + 19953 0 0 1.283 0.426 0 27.697 + 21135 0 0 1.265 0.429 0 27.584 + 22387 0 0 1.287 0.448 0 27.546 + 23714 0 0 1.296 0.451 0 27.511 + 25119 0 0 1.298 0.452 0 27.519 + 26607 0 0 1.313 0.469 0 27.518 + 28184 0 0 1.325 0.479 0 27.524 + 29854 0 0 1.323 0.477 0 27.444 + 31623 0 0 1.338 0.511 0 27.434 + 33497 0 0 1.346 0.501 0 27.402 + 35481 0 0 1.368 0.515 0 27.335 + 37584 0 0 1.365 0.529 0 27.333 + 39811 0 0 1.377 0.543 0 27.306 + 42170 0 0 1.382 0.554 0 27.303 + 44668 0 0 1.404 0.568 0 27.259 + 47315 0 0 1.414 0.592 0 27.225 + 50119 0 0 1.417 0.593 0 27.198 + 53088 0 0 1.448 0.619 0 27.141 + 56234 0 0 1.452 0.617 0 27.096 + 59566 0 0 1.447 0.631 0 27.072 + 63096 0 0 1.474 0.644 0 27.052 + 66834 0 0 1.487 0.667 0 27.033 + 70795 0 0 1.506 0.683 0 26.991 + 74989 0 0 1.518 0.689 0 26.935 + 79433 0 0 1.525 0.701 0 26.883 + 84140 0 0 1.546 0.715 0 26.842 + 89125 0 0 1.556 0.731 0 26.823 + 94406 0 0 1.565 0.742 0 26.731 + 100000 0 0 1.589 0.755 0 26.702 + 105925 0 0 1.608 0.773 0 26.692 + 112202 0 0 1.627 0.788 0 26.645 + 118850 0 0 1.634 0.807 0 26.616 + 125893 0 0 1.645 0.810 0 26.572 + 133352 0 0 1.658 0.823 0 26.512 + 141254 0 0 1.670 0.835 0 26.464 + 149624 0 0 1.688 0.857 0 26.408 + 158489 0 0 1.700 0.866 0 26.358 + 167880 0 0 1.730 0.882 0 26.324 + 177828 0 0 1.730 0.896 0 26.276 + 188365 0 0 1.749 0.904 0 26.217 + 199526 0 0 1.769 0.914 0 26.156 + 211349 0 0 1.780 0.930 0 26.109 + 223872 0 0 1.791 0.944 0 26.065 + 237137 0 0 1.809 0.961 0 26.013 + 251189 0 0 1.828 0.971 0 25.967 + 266073 0 0 1.840 0.984 0 25.922 + 281838 0 0 1.870 0.997 0 25.863 + 298538 0 0 1.883 1.009 0 25.818 + 316228 0 0 1.897 1.023 0 25.746 + 334965 0 0 1.913 1.037 0 25.691 + 354813 0 0 1.917 1.049 0 25.659 + 375837 0 0 1.939 1.061 0 25.606 + 398107 0 0 1.957 1.075 0 25.560 + 421697 0 0 1.977 1.086 0 25.502 + 446684 0 0 1.994 1.103 0 25.468 + 473151 0 0 2.009 1.113 0 25.425 + 501187 0 0 2.019 1.127 0 25.383 + 530884 0 0 2.036 1.139 0 25.343 + 562341 0 0 2.060 1.151 0 25.294 + 595662 0 0 2.073 1.162 0 25.255 + 630957 0 0 2.093 1.177 0 25.212 + 668344 0 0 2.100 1.189 0 25.170 + 707946 0 0 2.116 1.203 0 25.128 + 749894 0 0 2.139 1.216 0 25.089 + 794328 0 0 2.147 1.229 0 25.046 + 841395 0 0 2.163 1.239 0 25.009 + 891251 0 0 2.171 1.252 0 24.968 + 944061 0 0 2.196 1.267 0 24.935 + 1000000 0 0 2.206 1.283 0 24.885 + 1059254 0 0 2.215 1.293 0 24.840 + 1122018 0 0 2.237 1.304 0 24.795 + 1188502 0 0 2.254 1.318 0 24.749 + 1258925 0 0 2.268 1.332 0 24.703 + 1333521 0 0 2.285 1.346 0 24.658 + 1412538 0 0 2.303 1.357 0 24.623 + 1496236 0 0 2.314 1.371 0 24.592 + 1584893 0 0 2.333 1.383 0 24.544 + 1678804 0 0 2.354 1.402 0 24.498 + 1778279 0 0 2.366 1.415 0 24.459 + 1883649 0 0 2.388 1.426 0 24.411 + 1995262 0 0 2.407 1.435 0 24.367 + 2113489 0 0 2.417 1.451 0 24.324 + 2238721 0 0 2.434 1.464 0 24.292 + 2371374 0 0 2.448 1.481 0 24.247 + 2511886 0 0 2.467 1.494 0 24.212 + 2660725 0 0 2.486 1.511 0 24.176 + 2818383 0 0 2.499 1.522 0 24.141 + 2985383 0 0 2.521 1.541 0 24.100 + 3162278 0 0 2.541 1.556 0 24.056 + 3349654 0 0 2.564 1.572 0 24.010 + 3548134 0 0 2.584 1.589 0 23.966 + 3758374 0 0 2.603 1.610 0 23.929 + 3981072 0 0 2.624 1.633 0 23.896 + 4216965 0 0 2.646 1.645 0 23.859 + 4466836 0 0 2.668 1.656 0 23.822 + 4731513 0 0 2.688 1.681 0 23.792 + 5011872 0 0 2.714 1.702 0 23.741 + 5308844 0 0 2.739 1.724 0 23.701 + 5623413 0 0 2.757 1.747 0 23.659 + 5956621 0 0 2.783 1.766 0 23.619 + 6309573 0 0 2.806 1.785 0 23.568 + 6683439 0 0 2.830 1.805 0 23.533 + 7079458 0 0 2.873 1.838 0 23.488 + 7498942 0 0 2.891 1.861 0 23.440 + 7943282 0 0 2.911 1.880 0 23.395 + 8413951 0 0 2.936 1.904 0 23.344 + 8912509 0 0 2.962 1.928 0 23.296 + 9440609 0 0 2.983 1.950 0 23.243 + 10000000 0 0 3.010 1.981 0 23.191 + 10592537 0 0 3.039 2.016 0 23.139 + 11220185 0 0 3.070 2.043 0 23.082 + 11885022 0 0 3.096 2.068 0 23.025 + 12589254 0 0 3.121 2.092 0 22.965 + 13335214 0 0 3.144 2.124 0 22.904 + 14125375 0 0 3.165 2.148 0 22.842 + 14962357 0 0 3.191 2.176 0 22.777 + 15848932 0 0 3.212 2.209 0 22.712 + 16788040 0 0 3.284 2.226 0 22.637 diff --git a/feeds/p4/libjudy/src/test/CheckDupLines.c b/feeds/p4/libjudy/src/test/CheckDupLines.c new file mode 100644 index 000000000..bc5dcdfe2 --- /dev/null +++ b/feeds/p4/libjudy/src/test/CheckDupLines.c @@ -0,0 +1,44 @@ +#include +#include +#include + +#include + +//#include "JudyHS.h" // for Judy.h without JudyHS*() + +// By Doug Baskins Apr 2004 - for JudyHS man page + +#define MAXLINE 1000000 /* max length of line */ +char Index[MAXLINE]; // string to check + +int // Usage: CheckDupLines < file +main() +{ + Pvoid_t PJArray = (PWord_t)NULL; // Judy array. + PWord_t PValue; // Judy array element. + Word_t Bytes; // size of JudyHS array. + Word_t LineNumb = 0; // current line number + Word_t Dups = 0; // number of duplicate lines + + while (fgets(Index, MAXLINE, stdin) != (char *)NULL) + { + LineNumb++; // line number + +// store string into array + JHSI(PValue, PJArray, Index, strlen(Index)); + if (*PValue) // check if duplicate + { + Dups++; // yes, count + printf("Duplicate lines %lu:%lu:%s", *PValue, LineNumb, Index); + } + else + { + *PValue = LineNumb; // store Line number + } + } + printf("%lu Duplicates, free JudyHS array of %lu Lines\n", + Dups, LineNumb - Dups); + JHSFA(Bytes, PJArray); // free array + printf("The JudyHS array allocated %lu bytes of memory\n", Bytes); + return (0); +} diff --git a/feeds/p4/libjudy/src/test/Checkit b/feeds/p4/libjudy/src/test/Checkit new file mode 100755 index 000000000..b06083bc4 --- /dev/null +++ b/feeds/p4/libjudy/src/test/Checkit @@ -0,0 +1,104 @@ +#!/bin/sh +CC=${CC:-cc} + +echo +echo "=== +++++++++ This test runs in 15 seconds on a PIII 750Mhz +++++++" + +LIBJUDY=`find ../ -name libJudy.a` +JUDY_H=`find ../ -name Judy.h` + +echo "$CC -O SLcompare.c -DHASHMETHOD -o SL_Hash" + $CC -O SLcompare.c -DHASHMETHOD -o SL_Hash + +echo "$CC -O SLcompare.c -DSPLAYMETHOD -o SL_Splay" + $CC -O SLcompare.c -DSPLAYMETHOD -o SL_Splay + +echo "$CC -O SLcompare.c -DREDBLACKMETHOD -o SL_Redblack" + $CC -O SLcompare.c -DREDBLACKMETHOD -o SL_Redblack + +echo +echo Compiling with Judy library: $LIBJUDY +echo + +echo "$CC -O -I../src SLcompare.c -DJUDYMETHOD -o SL_Judy $LIBJUDY -lm" + $CC -O -I../src SLcompare.c -DJUDYMETHOD -o SL_Judy $LIBJUDY -lm +RET=$? +if [ $RET -ne 0 ] ; then +echo "=== $? Failed: $CC SLcompare.c -DJUDYMETHOD" +echo "=== $? Failed: $CC -O -I../src SLcompare.c -DJUDYMETHOD -o SL_Judy $LIBJUDY -lm" +exit $? +fi + +echo "$CC -O -I../src Judy1LHCheck.c -o Judy1LHCheck $LIBJUDY -lm" + $CC -O -I../src Judy1LHCheck.c -o Judy1LHCheck $LIBJUDY -lm +RET=$? +if [ $RET -ne 0 ] ; then +echo "=== $? Failed: $CC Judy1LHCheck.c" +exit $? +fi + + +echo "$CC -O -I../src Judy1LHTime.c -DNOINLINE -o Judy1LHTime $LIBJUDY -lm" + $CC -O -I../src Judy1LHTime.c -DNOINLINE -o Judy1LHTime $LIBJUDY -lm +RET=$? +if [ $RET -ne 0 ] ; then +echo "=== $? Failed: $CC Judy1LHTime.c" +exit $? +fi + +# -OR- if Judy is installed, these can be compiled from anywhere: +#cc -O SLcompare.c -DJUDYMETHOD -o SL_Judy -lJudy -lm +#cc -O Judy1LHCheck.c -o Judy1LHCheck -lJudy -lm +#cc -O Judy1LHTime.c -o Judy1LHTime -lJudy -lm +echo "=== Pass: Compile of tests" + +echo +echo " Validate Judy1/JudyL/JudyHS functions (except Judy*ByCount)" +./Judy1LHCheck -n 300000 -B20 > /dev/null +RET=$? +if [ $RET -ne 0 ] ; then +echo "=== $? Failed: Judy1/JudyL/JudyHS validate program" +exit $? +fi +echo "=== Pass: Judy1/JudyL/JudyHS validate program" + + +echo +echo " Do a few timings tests of Judy1/JudyL/JudyHS" +echo +# Pop1 is: current number of Indexes stored in Judy array +# Measmts is: lookups to make measurement +# J1 is: Judy1 +# JL is: JudyL +# /I is: per Index +# MU is: Memory Used (allocated thru malloc(3)) +# HEAP is: Memory change measured with sbrk(0) +echo " Pop1 Measmts J1S JLI J1T JLG J1MU/I JLMU/I HEAP/I" +./Judy1LHTime -n 2000000 -P1 -B19 | grep -v "^#" +echo "=== Pass: Judy1/JudyL/JudyHS performance program" + + + +echo +echo " Do a few timings tests of JudySL and friends" +echo +# lines is: number of lines in source file +# avg_linelen is: average bytes per line +# getline is: average time go get a line and remove white space +# StoreD is: number of unique lines stored into JudySL array +# RAMused/line is: Memory change measured with sbrk(0) +# store/ln is: average insert time (including duplicates) +# lookup/ln is: average lookup time in same order as inserts +# ADT is: Abstract Data Type method +echo " lines avg_linelen getline StoreD RAMused/line store/ln lookup/ln ADT" +./SL_Hash StringCompare.c | grep HASH +./SL_Splay StringCompare.c | grep SPLAY +./SL_Redblack StringCompare.c | grep REDBLACK +./SL_Judy StringCompare.c | grep JUDY +RET=$? +if [ $RET -ne 0 ] ; then +echo "=== $? Failed: JudySL if StoreD numbers are all the same" +exit $? +fi +echo "=== Pass: JudySL if StoreD numbers are all the same" +echo diff --git a/feeds/p4/libjudy/src/test/Judy1LCheck.c b/feeds/p4/libjudy/src/test/Judy1LCheck.c new file mode 100644 index 000000000..ad02f400c --- /dev/null +++ b/feeds/p4/libjudy/src/test/Judy1LCheck.c @@ -0,0 +1,908 @@ +// @(#) $Revision: 4.15 $ $Source: /judy/test/manual/Judy1LCheck.c $ +// This program tests the accuracy of a Judy1 with a JudyL Array. +// -by- +// Douglas L. Baskins (8/2001) doug@sourcejudy.com + +#ifndef JU_WIN_IA32 +#include // unavailable on Win32, and no getopt(). +#endif + +#include // calloc() +#include // pow() +#include // printf() + +#include + +// Common macro to handle a failure +#define FAILURE(STR, UL) \ +{ \ +printf( "Error: %s %lu, file='%s', 'function='%s', line %d\n", \ + STR, UL, __FILE__, __FUNCTI0N__, __LINE__); \ +fprintf(stderr, "Error: %s %lu, file='%s', 'function='%s', line %d\n", \ + STR, UL, __FILE__, __FUNCTI0N__, __LINE__); \ + exit(1); \ +} + +// Structure to keep track of times +typedef struct MEASUREMENTS_STRUCT +{ + Word_t ms_delta; +} +ms_t, *Pms_t; + +// Specify prototypes for each test routine +int +NextNumb(Word_t * PNumber, double *PDNumb, double DMult, Word_t MaxNumb); + +Word_t TestJudyIns(void **J1, void **JL, Word_t Seed, Word_t Elements); + +Word_t TestJudyDup(void **J1, void **JL, Word_t Seed, Word_t Elements); + +int TestJudyDel(void **J1, void **JL, Word_t Seed, Word_t Elements); + +Word_t TestJudyGet(void *J1, void *JL, Word_t Seed, Word_t Elements); + +int TestJudyCount(void *J1, void *JL, Word_t LowIndex, Word_t Elements); + +Word_t TestJudyNext(void *J1, void *JL, Word_t LowIndex, Word_t Elements); + +int TestJudyPrev(void *J1, void *JL, Word_t HighIndex, Word_t Elements); + +int +TestJudyNextEmpty(void *J1, void *JL, Word_t LowIndex, Word_t Elements); + +int +TestJudyPrevEmpty(void *J1, void *JL, Word_t HighIndex, Word_t Elements); + +Word_t MagicList[] = +{ + 0,0,0,0,0,0,0,0,0,0, // 0..9 + 0x27f, // 10 + 0x27f, // 11 + 0x27f, // 12 + 0x27f, // 13 + 0x27f, // 14 + 0x27f, // 15 + 0x1e71, // 16 + 0xdc0b, // 17 + 0xdc0b, // 18 + 0xdc0b, // 19 + 0xdc0b, // 20 + 0xc4fb, // 21 + 0xc4fb, // 22 + 0xc4fb, // 23 + 0x13aab, // 24 + 0x11ca3, // 25 + 0x11ca3, // 26 + 0x11ca3, // 27 + 0x13aab, // 28 + 0x11ca3, // 29 + 0xc4fb, // 30 + 0xc4fb, // 31 + 0x13aab, // 32 + 0x14e73, // 33 + 0x145d7, // 34 + 0x145f9, // 35 following tested with Seed=0xc1fc to 35Gig numbers + 0x151ed, // 36 .. 41 + 0x151ed, // 37 + 0x151ed, // 38 + 0x151ed, // 39 + 0x151ed, // 40 + 0x146c3, // 41 .. 64 + 0x146c3, // 42 + 0x146c3, // 43 + 0x146c3, // 44 + 0x146c3, // 45 + 0x146c3, // 46 + 0x146c3, // 47 + 0x146c3, // 48 + 0x146c3, // 49 + 0x146c3, // 50 + 0x146c3, // 51 + 0x146c3, // 52 + 0x146c3, // 53 + 0x146c3, // 54 + 0x146c3, // 55 + 0x146c3, // 56 + 0x146c3, // 57 + 0x146c3, // 58 + 0x146c3, // 59 + 0x146c3, // 60 + 0x146c3, // 61 + 0x146c3, // 62 + 0x146c3, // 63 + 0x146c3 // 64 +}; + +// Routine to "mirror" the input data word +static Word_t +Swizzle(Word_t word) +{ +// BIT REVERSAL, Ron Gutman in Dr. Dobb's Journal, #316, Sept 2000, pp133-136 +// + +#ifdef __LP64__ + word = ((word & 0x00000000ffffffff) << 32) | + ((word & 0xffffffff00000000) >> 32); + word = ((word & 0x0000ffff0000ffff) << 16) | + ((word & 0xffff0000ffff0000) >> 16); + word = ((word & 0x00ff00ff00ff00ff) << 8) | + ((word & 0xff00ff00ff00ff00) >> 8); + word = ((word & 0x0f0f0f0f0f0f0f0f) << 4) | + ((word & 0xf0f0f0f0f0f0f0f0) >> 4); + word = ((word & 0x3333333333333333) << 2) | + ((word & 0xcccccccccccccccc) >> 2); + word = ((word & 0x5555555555555555) << 1) | + ((word & 0xaaaaaaaaaaaaaaaa) >> 1); +#else // __LP64__ + word = ((word & 0x0000ffff) << 16) | ((word & 0xffff0000) >> 16); + word = ((word & 0x00ff00ff) << 8) | ((word & 0xff00ff00) >> 8); + word = ((word & 0x0f0f0f0f) << 4) | ((word & 0xf0f0f0f0) >> 4); + word = ((word & 0x33333333) << 2) | ((word & 0xcccccccc) >> 2); + word = ((word & 0x55555555) << 1) | ((word & 0xaaaaaaaa) >> 1); +#endif // __LP64__ + + return(word); +} + +Word_t dFlag = 1; +Word_t pFlag = 0; +Word_t CFlag = 0; +Word_t DFlag = 0; +Word_t SkipN = 0; // default == Random skip +Word_t nElms = 1000000; // Default = 1M +Word_t ErrorFlag = 0; +Word_t TotalIns = 0; +Word_t TotalPop = 0; +Word_t TotalDel = 0; + +// Stuff for LFSR (pseudo random number generator) +Word_t RandomBit = ~0UL / 2 + 1; +Word_t BValue = sizeof(Word_t) * 8; +Word_t Magic; +Word_t StartSeed = 0xc1fc; // default beginning number +Word_t FirstSeed; + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "Random" + +static Word_t // Placed here so INLINING compilers get to look at it. +Random(Word_t newseed) +{ + if (newseed & RandomBit) + { + newseed += newseed; + newseed ^= Magic; + } + else + { + newseed += newseed; + } + newseed &= RandomBit * 2 - 1; + if (newseed == FirstSeed) + { + printf("End of LFSR, Total Population = %lu\n", TotalPop); + exit(0); + } + return(newseed); +} + +static Word_t // Placed here so INLINING compilers get to look at it. +GetNextIndex(Word_t Index) +{ + if (SkipN) + Index += SkipN; + else + Index = Random(Index); + + return(Index); +} + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "main" + +int +main(int argc, char *argv[]) +{ +// Names of Judy Arrays + void *J1 = NULL; // Judy1 + void *JL = NULL; // JudyL + + double Mult; + Pms_t Pms; + Word_t Seed; + Word_t PtsPdec = 10; // points per decade + Word_t Groups; // Number of measurement groups + Word_t grp; + + int c; + extern char *optarg; + +////////////////////////////////////////////////////////////// +// PARSE INPUT PARAMETERS +////////////////////////////////////////////////////////////// + + while ((c = getopt(argc, argv, "n:S:P:b:L:B:pdDC")) != -1) + { + switch (c) + { + case 'n': // Number of elements + nElms = strtoul(optarg, NULL, 0); // Size of Linear Array + if (nElms == 0) + FAILURE("No tests: -n", nElms); + +// Check if more than a trillion (64 bit only) + if ((double)nElms > 1e12) + FAILURE("Too many Indexes=", nElms); + break; + + case 'S': // Step Size, 0 == Random + SkipN = strtoul(optarg, NULL, 0); + break; + + case 'P': // + PtsPdec = strtoul(optarg, NULL, 0); + break; + + case 'b': // May not work past 35 bits if changed + StartSeed = strtoul(optarg, NULL, 0); + break; + + case 'B': + BValue = strtoul(optarg, NULL, 0); + if ( + (BValue > (sizeof(Word_t) * 8)) + || + (MagicList[BValue] == 0) + ) + { + ErrorFlag++; + printf("\nIllegal number of random bits of %lu !!!\n", BValue); + } + break; + + case 'p': // Print test indexes + pFlag = 1; + break; + + case 'd': // Delete indexes + dFlag = 0; + break; + + case 'D': // Swizzle indexes + DFlag = 1; + break; + + case 'C': // Skip counting test. + CFlag = 1; + break; + + default: + ErrorFlag++; + break; + } + } + + if (ErrorFlag) + { + printf("\n%s -n# -S# -B# -P# -b # -DRCpd\n\n", argv[0]); + printf("Where:\n"); + printf("-n <#> number of indexes used in tests\n"); + printf("-C skip JudyCount tests\n"); + printf("-p print index set - for debug\n"); + printf("-d do not call JudyDel/Unset\n"); + printf("-D Swizzle data (mirror)\n"); + printf("-S <#> index skip amount, 0 = random\n"); + printf("-B <#> # bits-1 in random number generator\n"); + printf("-P <#> number measurement points per decade\n"); + printf("\n"); + + exit(1); + } +// Set number of Random bits in LFSR + RandomBit = 1UL << (BValue - 1); + Magic = MagicList[BValue]; + + if (nElms > ((RandomBit-2) * 2)) + { + printf("# Number = -n%lu of Indexes reduced to max expanse of Random numbers\n", nElms); + nElms = ((RandomBit-2) * 2); + } + + printf("\n%s -n%lu -S%lu -B%lu", argv[0], nElms, SkipN, BValue); + + if (DFlag) + printf(" -D"); + if (!dFlag) + printf(" -d"); + if (pFlag) + printf(" -p"); + if (CFlag) + printf(" -C"); + printf("\n\n"); + + if (sizeof(Word_t) == 8) + printf("%s 64 Bit version\n", argv[0]); + else if (sizeof(Word_t) == 4) + printf("%s 32 Bit version\n", argv[0]); + +////////////////////////////////////////////////////////////// +// CALCULATE NUMBER OF MEASUREMENT GROUPS +////////////////////////////////////////////////////////////// + +// Calculate Multiplier for number of points per decade + Mult = pow(10.0, 1.0 / (double)PtsPdec); + { + double sum; + Word_t numb, prevnumb; + +// Count number of measurements needed (10K max) + sum = numb = 1; + for (Groups = 2; Groups < 10000; Groups++) + if (NextNumb(&numb, &sum, Mult, nElms)) + break; + +// Get memory for measurements + Pms = (Pms_t) calloc(Groups, sizeof(ms_t)); + +// Now calculate number of Indexes for each measurement point + numb = sum = 1; + prevnumb = 0; + for (grp = 0; grp < Groups; grp++) + { + Pms[grp].ms_delta = numb - prevnumb; + prevnumb = numb; + + NextNumb(&numb, &sum, Mult, nElms); + } + } // Groups = number of sizes + +////////////////////////////////////////////////////////////// +// BEGIN TESTS AT EACH GROUP SIZE +////////////////////////////////////////////////////////////// + +// Get the kicker to test the LFSR + FirstSeed = Seed = StartSeed & (RandomBit * 2 - 1); + + printf("Total Pop Total Ins New Ins Total Del"); + printf(" J1MU/I JLMU/I\n"); + +#ifdef testLFSR +{ + Word_t Seed1 = Seed; + + while(1) + { + Seed1 = GetNextIndex(Seed1); + TotalPop++; + if (TotalPop > 40000000000) printf("Total = %lu\n", TotalPop), exit(1); + } +} +#endif // testLFSR + + for (grp = 0; grp < Groups; grp++) + { + Word_t LowIndex, HighIndex; + Word_t Delta; + Word_t NewSeed; + + Delta = Pms[grp].ms_delta; + +// Test JLI, J1S + NewSeed = TestJudyIns(&J1, &JL, Seed, Delta); + +// Test JLG, J1T + LowIndex = TestJudyGet(J1, JL, Seed, Delta); + +// Test JLI, J1S -dup + LowIndex = TestJudyDup(&J1, &JL, Seed, Delta); + +// Test JLC, J1C + if (!CFlag) + { + TestJudyCount(J1, JL, LowIndex, Delta); + } +// Test JLN, J1N + HighIndex = TestJudyNext(J1, JL, LowIndex, Delta); + +// Test JLP, J1P + TestJudyPrev(J1, JL, HighIndex, Delta); + +// Test JLNE, J1NE + TestJudyNextEmpty(J1, JL, LowIndex, Delta); + +// Test JLPE, J1PE + TestJudyPrevEmpty(J1, JL, HighIndex, Delta); + +// Test JLD, J1U + if (dFlag) + { + TestJudyDel(&J1, &JL, Seed, Delta); + } + + printf("%9lu %9lu %7lu %9lu", TotalPop, TotalIns, Delta, TotalDel); + { + Word_t Count1, CountL; + +// Print the number of bytes used per Index + J1C(Count1, J1, 0, ~0); + printf(" %6.3f", (double)Judy1MemUsed(J1) / (double)Count1); + JLC(CountL, JL, 0, ~0); + printf(" %6.3f", (double)JudyLMemUsed(JL) / (double)CountL); + } + printf("\n"); + +// Advance Index number set + Seed = NewSeed; + } + { + Word_t Count1, CountL; + Word_t Bytes; + + JLC(CountL, JL, 0, ~0); + J1C(Count1, J1, 0, ~0); + + if (CountL != TotalPop) + FAILURE("JudyLCount wrong", CountL); + + if (Count1 != TotalPop) + FAILURE("Judy1Count wrong", Count1); + + if (TotalPop) + { + J1FA(Bytes, J1); // Free the Judy1 Array + printf("Judy1FreeArray = %6.3f Bytes/Index\n", + (double)Bytes / (double)Count1); + + if (pFlag) { printf("J1FA: %8lu\tbytes = %lu\n", TotalPop, Bytes); } + + JLFA(Bytes, JL); // Free the JudyL Array + printf("JudyLFreeArray = %6.3f Bytes/Index\n", + (double)Bytes / (double)CountL); + + if (pFlag) { printf("JLFA: %8lu\tbytes = %lu\n", TotalPop, Bytes); } + + TotalPop = 0; + } + } + printf("Passed JudyL and Judy1 tests\n"); + exit(0); +} + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyIns" + +Word_t +TestJudyIns(void **J1, void **JL, Word_t Seed, Word_t Elements) +{ + Word_t TstIndex; + Word_t elm; + Word_t *PValue, *PValue1; + Word_t Seed1; + int Rcode; + + for (Seed1 = Seed, elm = 0; elm < Elements; elm++) + { + Seed1 = GetNextIndex(Seed1); + if (Seed1 == 0) + FAILURE("This command not robust if Index == 0", elm); + + if (DFlag) + TstIndex = Swizzle(Seed1); + else + TstIndex = Seed1; + + if (pFlag) { printf("Ins: %8lu\t0x%lx\n", elm, TstIndex); } + + J1S(Rcode, *J1, TstIndex); + if (Rcode == JERR) + FAILURE("Judy1Set failed at", elm); + if (Rcode == 0) + FAILURE("Judy1Set failed - DUP Index, population =", TotalPop); + + J1T(Rcode, *J1, TstIndex); + if (Rcode != 1) + FAILURE("Judy1Test failed - Index missing, population =", TotalPop); + + J1S(Rcode, *J1, TstIndex); + if (Rcode != 0) + FAILURE("Judy1Set failed - Index missing, population =", TotalPop); + + JLI(PValue, *JL, TstIndex); + if (PValue == PJERR) + FAILURE("JudyLIns failed at", elm); + if (*PValue == TstIndex) + FAILURE("JudyLIns failed - DUP Index, population =", TotalPop); + +// Save Index in Value + *PValue = TstIndex; + + JLG(PValue1, *JL, TstIndex); + if (PValue != PValue1) + FAILURE("JudyLGet failed - Index missing, population =", TotalPop); + + JLI(PValue1, *JL, TstIndex); + if (PValue != PValue1) + { + if (*PValue1 != TstIndex) + { + FAILURE("JudyLIns failed - Index missing, population =", TotalPop); + } + else + { +// not ready for this yet! printf("Index moved -- TotalPop = %lu\n", TotalPop); + } + } + TotalPop++; + TotalIns++; + } + return (Seed1); // New seed +} + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyGet" + +Word_t +TestJudyGet(void *J1, void *JL, Word_t Seed, Word_t Elements) +{ + Word_t LowIndex = ~0UL; + Word_t TstIndex; + Word_t elm; + Word_t *PValue; + Word_t Seed1; + int Rcode; + + for (Seed1 = Seed, elm = 0; elm < Elements; elm++) + { + Seed1 = GetNextIndex(Seed1); + + if (DFlag) + TstIndex = Swizzle(Seed1); + else + TstIndex = Seed1; + + if (TstIndex < LowIndex) + LowIndex = TstIndex; + + J1T(Rcode, J1, TstIndex); + if (Rcode != 1) + FAILURE("Judy1Test Rcode != 1", (Word_t) Rcode); + + JLG(PValue, JL, TstIndex); + if (PValue == (Word_t *) NULL) + FAILURE("JudyLGet ret PValue = NULL", 0L); + if (*PValue != TstIndex) + FAILURE("JudyLGet ret wrong Value at", elm); + } + + return(LowIndex); +} + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyDup" + +Word_t +TestJudyDup(void **J1, void **JL, Word_t Seed, Word_t Elements) +{ + Word_t LowIndex = ~0UL; + Word_t TstIndex; + Word_t elm; + Word_t *PValue; + Word_t Seed1; + int Rcode; + + for (Seed1 = Seed, elm = 0; elm < Elements; elm++) + { + Seed1 = GetNextIndex(Seed1); + + if (DFlag) + TstIndex = Swizzle(Seed1); + else + TstIndex = Seed1; + + if (TstIndex < LowIndex) + LowIndex = TstIndex; + + J1S(Rcode, *J1, TstIndex); + if (Rcode != 0) + FAILURE("Judy1Set Rcode != 0", (Word_t) Rcode); + + JLI(PValue, *JL, TstIndex); + if (PValue == (Word_t *) NULL) + FAILURE("JudyLIns ret PValue = NULL", 0L); + if (*PValue != TstIndex) + FAILURE("JudyLIns ret wrong Value at", elm); + } + + return(LowIndex); +} + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyCount" + +int +TestJudyCount(void *J1, void *JL, Word_t LowIndex, Word_t Elements) +{ + Word_t elm; + Word_t Count1, CountL; + Word_t TstIndex = LowIndex; + int Rcode; + + TstIndex = LowIndex; + for (elm = 0; elm < Elements; elm++) + { + J1C(Count1, J1, LowIndex, TstIndex); + if (Count1 == JERR) + FAILURE("Judy1Count ret JERR", (Word_t) Count1); + + if (Count1 != (elm + 1)) + { + J1C(CountL, J1, 0, -1); + printf("J1C(%lu, J1, 0, -1)\n", CountL); + + JLC(CountL, JL, 0, -1); + printf("JLC(%lu, JL, 0, -1)\n", CountL); + + printf("LowIndex = 0x%lx, TstIndex = 0x%lx, diff = %lu\n", LowIndex, + TstIndex, TstIndex - LowIndex); + JLC(CountL, JL, LowIndex, TstIndex); + printf("CountL = %lu, Count1 = %lu, should be: elm + 1 = %lu\n", CountL, Count1, elm + 1); + FAILURE("J1C at", elm); + } + + JLC(CountL, JL, LowIndex, TstIndex); + if (CountL == JERR) + FAILURE("JudyLCount ret JERR", (Word_t) CountL); + + if (CountL != (elm + 1)) FAILURE("JLC at", elm); + + J1N(Rcode, J1, TstIndex); + } + return(0); +} + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyNext" + +Word_t TestJudyNext(void *J1, void *JL, Word_t LowIndex, Word_t Elements) +{ + Word_t JLindex, J1index; + Word_t *PValue; + Word_t elm; + int Rcode; + +// Get an Index low enough for Elements + J1index = JLindex = LowIndex; + + JLF(PValue, JL, JLindex); + J1F(Rcode, J1, J1index); + + for (elm = 0; elm < Elements; elm++) + { + if (PValue == NULL) + FAILURE("JudyLNext ret NULL PValue at", elm); + if (Rcode != 1) + FAILURE("Judy1Next Rcode != 1 =", (Word_t) Rcode); + if (JLindex != J1index) + FAILURE("Judy1Next & Judy1Next ret different PIndex at", elm); + + JLN(PValue, JL, JLindex); // Get next one + J1N(Rcode, J1, J1index); // Get next one + } +// perhaps a check should be done here -- if I knew what to expect. + return(JLindex); // return last one +} + + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyPrev" + +int +TestJudyPrev(void *J1, void *JL, Word_t HighIndex, Word_t Elements) +{ + Word_t JLindex, J1index; + Word_t *PValue; + Word_t elm; + int Rcode; + +// Get an Index high enough for Elements + J1index = JLindex = HighIndex; + + JLL(PValue, JL, JLindex); + J1L(Rcode, J1, J1index); + + for (elm = 0; elm < Elements; elm++) + { + if (PValue == NULL) + FAILURE("JudyLPrev ret NULL PValue at", elm); + if (Rcode != 1) + FAILURE("Judy1Prev Rcode != 1 =", (Word_t) Rcode); + if (JLindex != J1index) + FAILURE("Judy1Prev & Judy1Prev ret different PIndex at", elm); + + JLP(PValue, JL, JLindex); // Get previous one + J1P(Rcode, J1, J1index); // Get previous one + } +// perhaps a check should be done here -- if I knew what to expect. + return(0); +} + + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyNextEmpty" + +int +TestJudyNextEmpty(void *J1, void *JL, Word_t LowIndex, Word_t Elements) +{ + Word_t elm; + Word_t JLindex, J1index; + Word_t Seed1; + int Rcode; // Return code + +// Set 1st search to .. + Seed1 = LowIndex; + J1index = JLindex = Seed1; + + for (elm = 0; elm < Elements; elm++) + { + Word_t *PValue; + +// Find next Empty Index, JLindex is modified by JLNE + JLNE(Rcode, JL, JLindex); // Rcode = JudyLNextEmpty(JL, &JLindex, PJE0) + if (Rcode != 1) + FAILURE("JudyLNextEmpty Rcode != 1 =", (Word_t) Rcode); + + if (pFlag) { printf("JNE: %8lu\t0x%lx\n", elm, JLindex); } + +// Find next Empty Index, J1index is modified by J1NE + J1NE(Rcode, J1, J1index); // Rcode = Judy1NextEmpty(J1, &J1index, PJE0) + if (Rcode != 1) + FAILURE("Judy1NextEmpty Rcode != 1 =", (Word_t) Rcode); + + if (J1index != JLindex) + FAILURE("JLNE != J1NE returned index at", elm); + + J1T(Rcode, J1, J1index); + if (Rcode != 0) + FAILURE("J1NE returned non-empty Index =", J1index); + + JLG(PValue, JL, JLindex); + if (PValue != (Word_t *) NULL) + FAILURE("JLNE returned non-empty Index =", JLindex); + + Seed1 = GetNextIndex(Seed1); + J1index = JLindex = Seed1; + } + return(0); +} + + +// Routine to JudyPrevEmpty routines + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyPrevEmpty" + +int +TestJudyPrevEmpty(void *J1, void *JL, Word_t HighIndex, Word_t Elements) +{ + Word_t elm; + Word_t JLindex, J1index; + Word_t Seed1; + int Rcode; + +// Set 1st search to .. + Seed1 = HighIndex; + J1index = JLindex = Seed1; + + for (elm = 0; elm < Elements; elm++) + { + Word_t *PValue; + + J1PE(Rcode, J1, J1index); // Rcode = Judy1PrevEmpty(J1, &J1index, PJE0) + if (Rcode != 1) + FAILURE("Judy1PrevEmpty Rcode != 1 =", (Word_t) Rcode); + + if (pFlag) { printf("JPE: %8lu\t0x%lx\n", elm, J1index); } + +// Find next Empty Index, JLindex is modified by JLPE + JLPE(Rcode, JL, JLindex); // Rcode = JudyLPrevEmpty(JL, &JLindex, PJE0) + if (Rcode != 1) + FAILURE("JudyLPrevEmpty Rcode != 1 =", (Word_t) Rcode); + + if (J1index != JLindex) + FAILURE("JLPE != J1PE returned index at", elm); + + J1T(Rcode, J1, J1index); + if (Rcode != 0) + FAILURE("J1PE returned non-empty Index =", J1index); + + JLG(PValue, JL, JLindex); + if (PValue != (Word_t *) NULL) + FAILURE("JLPE returned non-empty Index =", JLindex); + + Seed1 = GetNextIndex(Seed1); + J1index = JLindex = Seed1; + } + return(0); +} + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyDel" + +int +TestJudyDel(void **J1, void **JL, Word_t Seed, Word_t Elements) +{ + Word_t TstIndex; + Word_t elm; + Word_t Seed1; + int Rcode; + +// Only delete half of thoes inserted + for (Seed1 = Seed, elm = 0; elm < (Elements / 2); elm++) + { + Seed1 = GetNextIndex(Seed1); + + if (DFlag) + TstIndex = Swizzle(Seed1); + else + TstIndex = Seed1; + + if (pFlag) { printf("Del: %8lu\t0x%lx\n", elm, TstIndex); } + + TotalDel++; + + J1U(Rcode, *J1, TstIndex); + if (Rcode != 1) + FAILURE("Judy1Unset ret Rcode != 1", (Word_t) Rcode); + + JLD(Rcode, *JL, TstIndex); + if (Rcode != 1) + FAILURE("JudyLDel ret Rcode != 1", (Word_t) Rcode); + + TotalPop--; + } + return(0); +} + +// Routine to get next size of Indexes +int // return 1 if last number +NextNumb(Word_t * PNumber, // pointer to returned next number + double *PDNumb, // Temp double of above + double DMult, // Multiplier + Word_t MaxNumb) // Max number to return +{ + Word_t num; + +// Save prev number + Word_t PrevNumb = *PNumber; + +// Verify integer number increased + for (num = 0; num < 1000; num++) + { +// Calc next number + *PDNumb *= DMult; + +// Return it in integer format + *PNumber = (Word_t) (*PDNumb + 0.5); + + if (*PNumber != PrevNumb) + break; + } + +// Verify it did exceed max ulong + if ((*PDNumb + 0.5) > (double)(-1UL)) + { +// It did, so return max number + *PNumber = -1UL; + return (1); // flag it + } + +// Verify it did not exceed max number + if ((*PDNumb + 0.5) > (double)MaxNumb) + { +// it did, so return max + *PNumber = MaxNumb; + return(1); // flag it + } + return(0); // more available +} diff --git a/feeds/p4/libjudy/src/test/Judy1LHCheck.c b/feeds/p4/libjudy/src/test/Judy1LHCheck.c new file mode 100644 index 000000000..32149ab37 --- /dev/null +++ b/feeds/p4/libjudy/src/test/Judy1LHCheck.c @@ -0,0 +1,1018 @@ +// @(#) $Revision: 4.15 $ $Source: /judy/test/manual/Judy1LHCheck.c $ +// This program tests the accuracy of a Judy1 with a JudyL Array. +// -by- +// Douglas L. Baskins (8/2001) doug@sourcejudy.com + +#include // calloc() +#include // getopt() +#include // pow() +#include // printf() + +#include + +// Compile: +// # cc -O Judy1LHCheck.c -lm -lJudy -o Judy1LHCheck + +// Common macro to handle a failure +#define FAILURE(STR, UL) \ +{ \ +printf( "Error: %s %lu, file='%s', 'function='%s', line %d\n", \ + STR, (Word_t)(UL), __FILE__, __FUNCTI0N__, __LINE__); \ +fprintf(stderr, "Error: %s %lu, file='%s', 'function='%s', line %d\n", \ + STR, (Word_t)(UL), __FILE__, __FUNCTI0N__, __LINE__); \ + exit(1); \ +} + +// Structure to keep track of times +typedef struct MEASUREMENTS_STRUCT +{ + Word_t ms_delta; +} +ms_t, *Pms_t; + +// Specify prototypes for each test routine +int +NextNumb(Word_t * PNumber, double *PDNumb, double DMult, Word_t MaxNumb); + +Word_t TestJudyIns(void **J1, void **JL, void **JH, Word_t Seed, Word_t Elements); + +Word_t TestJudyDup(void **J1, void **JL, void **JH, Word_t Seed, Word_t Elements); + +int TestJudyDel(void **J1, void **JL, void **JH, Word_t Seed, Word_t Elements); + +Word_t TestJudyGet(void *J1, void *JL, void *JH, Word_t Seed, Word_t Elements); + +int TestJudyCount(void *J1, void *JL, Word_t LowIndex, Word_t Elements); + +Word_t TestJudyNext(void *J1, void *JL, Word_t LowIndex, Word_t Elements); + +int TestJudyPrev(void *J1, void *JL, Word_t HighIndex, Word_t Elements); + +int +TestJudyNextEmpty(void *J1, void *JL, Word_t LowIndex, Word_t Elements); + +int +TestJudyPrevEmpty(void *J1, void *JL, Word_t HighIndex, Word_t Elements); + +Word_t MagicList[] = +{ + 0,0,0,0,0,0,0,0,0,0, // 0..9 + 0x27f, // 10 + 0x27f, // 11 + 0x27f, // 12 + 0x27f, // 13 + 0x27f, // 14 + 0x27f, // 15 + 0x1e71, // 16 + 0xdc0b, // 17 + 0xdc0b, // 18 + 0xdc0b, // 19 + 0xdc0b, // 20 + 0xc4fb, // 21 + 0xc4fb, // 22 + 0xc4fb, // 23 + 0x13aab, // 24 + 0x11ca3, // 25 + 0x11ca3, // 26 + 0x11ca3, // 27 + 0x13aab, // 28 + 0x11ca3, // 29 + 0xc4fb, // 30 + 0xc4fb, // 31 + 0x13aab, // 32 + 0x14e73, // 33 + 0x145d7, // 34 + 0x145f9, // 35 following tested with Seed=0xc1fc to 35Gig numbers + 0x151ed, // 36 .. 41 + 0x151ed, // 37 + 0x151ed, // 38 + 0x151ed, // 39 fails at 549751488512 (549Gig) + 0x151ed, // 40 + 0x146c3, // 41 .. 64 + 0x146c3, // 42 + 0x146c3, // 43 + 0x146c3, // 44 + 0x146c3, // 45 + 0x146c3, // 46 + 0x146c3, // 47 + 0x146c3, // 48 + 0x146c3, // 49 + 0x146c3, // 50 + 0x146c3, // 51 + 0x146c3, // 52 + 0x146c3, // 53 + 0x146c3, // 54 + 0x146c3, // 55 + 0x146c3, // 56 + 0x146c3, // 57 + 0x146c3, // 58 + 0x146c3, // 59 + 0x146c3, // 60 + 0x146c3, // 61 + 0x146c3, // 62 + 0x146c3, // 63 + 0x146c3 // 64 +}; + +// Routine to "mirror" the input data word +static Word_t +Swizzle(Word_t word) +{ +// BIT REVERSAL, Ron Gutman in Dr. Dobb's Journal, #316, Sept 2000, pp133-136 +// + +#ifdef __LP64__ + word = ((word & 0x00000000ffffffff) << 32) | + ((word & 0xffffffff00000000) >> 32); + word = ((word & 0x0000ffff0000ffff) << 16) | + ((word & 0xffff0000ffff0000) >> 16); + word = ((word & 0x00ff00ff00ff00ff) << 8) | + ((word & 0xff00ff00ff00ff00) >> 8); + word = ((word & 0x0f0f0f0f0f0f0f0f) << 4) | + ((word & 0xf0f0f0f0f0f0f0f0) >> 4); + word = ((word & 0x3333333333333333) << 2) | + ((word & 0xcccccccccccccccc) >> 2); + word = ((word & 0x5555555555555555) << 1) | + ((word & 0xaaaaaaaaaaaaaaaa) >> 1); +#else // __LP64__ + word = ((word & 0x0000ffff) << 16) | ((word & 0xffff0000) >> 16); + word = ((word & 0x00ff00ff) << 8) | ((word & 0xff00ff00) >> 8); + word = ((word & 0x0f0f0f0f) << 4) | ((word & 0xf0f0f0f0) >> 4); + word = ((word & 0x33333333) << 2) | ((word & 0xcccccccc) >> 2); + word = ((word & 0x55555555) << 1) | ((word & 0xaaaaaaaa) >> 1); +#endif // __LP64__ + + return(word); +} + +Word_t dFlag = 1; +Word_t pFlag = 0; +Word_t CFlag = 0; +Word_t DFlag = 0; +Word_t SkipN = 0; // default == Random skip +Word_t nElms = 1000000; // Default = 1M +Word_t ErrorFlag = 0; +Word_t TotalIns = 0; +Word_t TotalPop = 0; +Word_t TotalDel = 0; + +// Stuff for LFSR (pseudo random number generator) +Word_t RandomBit = ~0UL / 2 + 1; +Word_t BValue = sizeof(Word_t) * 8; +Word_t Magic; +Word_t StartSeed = 0xc1fc; // default beginning number +Word_t FirstSeed; + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "Random" + +static Word_t // Placed here so INLINING compilers get to look at it. +Random(Word_t newseed) +{ + if (newseed & RandomBit) + { + newseed += newseed; + newseed ^= Magic; + } + else + { + newseed += newseed; + } + newseed &= RandomBit * 2 - 1; + if (newseed == FirstSeed) + { + printf("Passed (End of LFSR) Judy1, JudyL, JudyHS tests for %lu numbers with <= %ld bits\n", TotalPop, BValue); + exit(0); + } + return(newseed); +} + +static Word_t // Placed here so INLINING compilers get to look at it. +GetNextIndex(Word_t Index) +{ + if (SkipN) + Index += SkipN; + else + Index = Random(Index); + + return(Index); +} + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "main" + +int +main(int argc, char *argv[]) +{ +// Names of Judy Arrays + void *J1 = NULL; // Judy1 + void *JL = NULL; // JudyL + void *JH = NULL; // JudyHS + + double Mult; + Pms_t Pms; + Word_t Seed; + Word_t PtsPdec = 10; // points per decade + Word_t Groups; // Number of measurement groups + Word_t grp; + + int c; + extern char *optarg; + +////////////////////////////////////////////////////////////// +// PARSE INPUT PARAMETERS +////////////////////////////////////////////////////////////// + + while ((c = getopt(argc, argv, "n:S:P:b:L:B:pdDC")) != -1) + { + switch (c) + { + case 'n': // Number of elements + nElms = strtoul(optarg, NULL, 0); // Size of Linear Array + if (nElms == 0) + FAILURE("No tests: -n", nElms); + +// Check if more than a trillion (64 bit only) + if ((double)nElms > 1e12) + FAILURE("Too many Indexes=", nElms); + break; + + case 'S': // Step Size, 0 == Random + SkipN = strtoul(optarg, NULL, 0); + break; + + case 'P': // + PtsPdec = strtoul(optarg, NULL, 0); + break; + + case 'b': // May not work past 35 bits if changed + StartSeed = strtoul(optarg, NULL, 0); + break; + + case 'B': + BValue = strtoul(optarg, NULL, 0); + if ( + (BValue > (sizeof(Word_t) * 8)) + || + (MagicList[BValue] == 0) + ) + { + ErrorFlag++; + printf("\nIllegal number of random bits of %lu !!!\n", BValue); + } + break; + + case 'p': // Print test indexes + pFlag = 1; + break; + + case 'd': // Delete indexes + dFlag = 0; + break; + + case 'D': // Swizzle indexes + DFlag = 1; + break; + + case 'C': // Skip counting test. + CFlag = 1; + break; + + default: + ErrorFlag++; + break; + } + } + + if (ErrorFlag) + { + printf("\n%s -n# -S# -B# -P# -b # -DRCpd\n\n", argv[0]); + printf("Where:\n"); + printf("-n <#> number of indexes used in tests\n"); + printf("-C skip JudyCount tests\n"); + printf("-p print index set - for debug\n"); + printf("-d do not call JudyDel/Unset\n"); + printf("-D Swizzle data (mirror)\n"); + printf("-S <#> index skip amount, 0 = random\n"); + printf("-B <#> # bits-1 in random number generator\n"); + printf("-P <#> number measurement points per decade\n"); + printf("\n"); + + exit(1); + } +// Set number of Random bits in LFSR + RandomBit = 1UL << (BValue - 1); + Magic = MagicList[BValue]; + + if (nElms > ((RandomBit-2) * 2)) + { + printf("# Number = -n%lu of Indexes reduced to max expanse of Random numbers\n", nElms); + nElms = ((RandomBit-2) * 2); + } + + printf("\n%s -n%lu -S%lu -B%lu", argv[0], nElms, SkipN, BValue); + + if (DFlag) + printf(" -D"); + if (!dFlag) + printf(" -d"); + if (pFlag) + printf(" -p"); + if (CFlag) + printf(" -C"); + printf("\n\n"); + + if (sizeof(Word_t) == 8) + printf("%s 64 Bit version\n", argv[0]); + else if (sizeof(Word_t) == 4) + printf("%s 32 Bit version\n", argv[0]); + +////////////////////////////////////////////////////////////// +// CALCULATE NUMBER OF MEASUREMENT GROUPS +////////////////////////////////////////////////////////////// + +// Calculate Multiplier for number of points per decade + Mult = pow(10.0, 1.0 / (double)PtsPdec); + { + double sum; + Word_t numb, prevnumb; + +// Count number of measurements needed (10K max) + sum = numb = 1; + for (Groups = 2; Groups < 10000; Groups++) + if (NextNumb(&numb, &sum, Mult, nElms)) + break; + +// Get memory for measurements + Pms = (Pms_t) calloc(Groups, sizeof(ms_t)); + +// Now calculate number of Indexes for each measurement point + numb = sum = 1; + prevnumb = 0; + for (grp = 0; grp < Groups; grp++) + { + Pms[grp].ms_delta = numb - prevnumb; + prevnumb = numb; + + NextNumb(&numb, &sum, Mult, nElms); + } + } // Groups = number of sizes + +////////////////////////////////////////////////////////////// +// BEGIN TESTS AT EACH GROUP SIZE +////////////////////////////////////////////////////////////// + +// Get the kicker to test the LFSR + FirstSeed = Seed = StartSeed & (RandomBit * 2 - 1); + + printf("Total Pop Total Ins New Ins Total Del"); + printf(" J1MU/I JLMU/I\n"); + +#ifdef testLFSR +{ + Word_t Seed1 = Seed; + + printf("Begin test of LSFR, BValue = %lu\n", BValue); + while(1) + { + Seed1 = GetNextIndex(Seed1); + TotalPop++; + if (TotalPop == 0) printf("BUG!!!\n"); + } + exit(0); +} +#endif // testLFSR + + for (grp = 0; grp < Groups; grp++) + { + Word_t LowIndex, HighIndex; + Word_t Delta; + Word_t NewSeed; + + Delta = Pms[grp].ms_delta; + +// Test JLI, J1S + NewSeed = TestJudyIns(&J1, &JL, &JH, Seed, Delta); + +// Test JLG, J1T + LowIndex = TestJudyGet(J1, JL, JH, Seed, Delta); + +// Test JLI, J1S -dup + LowIndex = TestJudyDup(&J1, &JL, &JH, Seed, Delta); + +// Test JLC, J1C + if (!CFlag) + { + TestJudyCount(J1, JL, LowIndex, Delta); + } +// Test JLN, J1N + HighIndex = TestJudyNext(J1, JL, 0UL, TotalPop); + +// Test JLP, J1P + TestJudyPrev(J1, JL, ~0UL, TotalPop); + +// Test JLNE, J1NE + TestJudyNextEmpty(J1, JL, LowIndex, Delta); + +// Test JLPE, J1PE + TestJudyPrevEmpty(J1, JL, HighIndex, Delta); + +// Test JLD, J1U + if (dFlag) + { + TestJudyDel(&J1, &JL, &JH, Seed, Delta); + } + + printf("%9lu %9lu %7lu %9lu", TotalPop, TotalIns, Delta, TotalDel); + { + Word_t Count1, CountL; + +// Print the number of bytes used per Index + J1C(Count1, J1, 0, ~0); + printf(" %6.3f", (double)Judy1MemUsed(J1) / (double)Count1); + JLC(CountL, JL, 0, ~0); + printf(" %6.3f", (double)JudyLMemUsed(JL) / (double)CountL); + } + printf("\n"); + +// Advance Index number set + Seed = NewSeed; + } + { + Word_t Count1, CountL; + Word_t Bytes; + + JLC(CountL, JL, 0, ~0); + J1C(Count1, J1, 0, ~0); + + if (CountL != TotalPop) + FAILURE("JudyLCount wrong", CountL); + + if (Count1 != TotalPop) + FAILURE("Judy1Count wrong", Count1); + + if (TotalPop) + { + J1FA(Bytes, J1); // Free the Judy1 Array + printf("Judy1FreeArray = %6.3f Bytes/Index\n", + (double)Bytes / (double)Count1); + + if (pFlag) { printf("J1FA: %8lu\tbytes = %lu\n", TotalPop, Bytes); } + + JLFA(Bytes, JL); // Free the JudyL Array + printf("JudyLFreeArray = %6.3f Bytes/Index\n", + (double)Bytes / (double)CountL); + + if (pFlag) { printf("JLFA: %8lu\tbytes = %lu\n", TotalPop, Bytes); } + + JHSFA(Bytes, JH); // Free the JudyL Array + printf("JudyHSFreeArray = %6.3f Bytes/Index\n", + (double)Bytes / (double)TotalPop); // Count not available yet + + if (pFlag) { printf("JHSFA: %8lu\tbytes = %lu\n", TotalPop, Bytes); } + + TotalPop = 0; + } + } + printf("Passed Judy1, JudyL, JudyHS tests for %lu numbers with <= %ld bits\n", nElms, BValue); + exit(0); +} + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyIns" + +Word_t +TestJudyIns(void **J1, void **JL, void **JH, Word_t Seed, Word_t Elements) +{ + Word_t TstIndex; + Word_t elm; + Word_t *PValue, *PValue1; + Word_t Seed1; + int Rcode; + + for (Seed1 = Seed, elm = 0; elm < Elements; elm++) + { + Seed1 = GetNextIndex(Seed1); + if (Seed1 == 0) + FAILURE("This command not robust if Index == 0", elm); + + if (DFlag) + TstIndex = Swizzle(Seed1); + else + TstIndex = Seed1; + + if (pFlag) { printf("Ins: %8lu\t0x%lx\n", elm, TstIndex); } + +// Judy1 + + J1S(Rcode, *J1, TstIndex); + if (Rcode == JERR) + FAILURE("Judy1Set failed at", elm); + if (Rcode == 0) + FAILURE("Judy1Set failed - DUP Index, population =", TotalPop); + +#ifdef SKIPMACRO + Rcode = Judy1Test(*J1, TstIndex); +#else + J1T(Rcode, *J1, TstIndex); +#endif // SKIPMACRO + if (Rcode != 1) + FAILURE("Judy1Test failed - Index missing, population =", TotalPop); + + J1S(Rcode, *J1, TstIndex); + if (Rcode != 0) + FAILURE("Judy1Set failed - Index missing, population =", TotalPop); + +// JudyL + JLI(PValue, *JL, TstIndex); + if (PValue == PJERR) + FAILURE("JudyLIns failed at", elm); + if (*PValue == TstIndex) + FAILURE("JudyLIns failed - DUP Index, population =", TotalPop); + +// Save Index in Value + *PValue = TstIndex; + +#ifdef SKIPMACRO + PValue1 = (PWord_t)JudyLGet(*JL, TstIndex); +#else + JLG(PValue1, *JL, TstIndex); +#endif // SKIPMACRO + if (PValue != PValue1) + FAILURE("JudyLGet failed - Index missing, population =", TotalPop); + + JLI(PValue1, *JL, TstIndex); + if (PValue != PValue1) + { + if (*PValue1 != TstIndex) + { + FAILURE("JudyLIns failed - Index missing, population =", TotalPop); + } + else + { +// not ready for this yet! printf("Index moved -- TotalPop = %lu\n", TotalPop); + } + } +// JudyHS + JHSI(PValue, *JH, (void *)(&TstIndex), sizeof(Word_t)); + if (PValue == PJERR) + FAILURE("JudyHSIns failed at", elm); + if (*PValue == TstIndex) + FAILURE("JudyHSIns failed - DUP Index, population =", TotalPop); + +// Save Index in Value + *PValue = TstIndex; + + JHSG(PValue1, *JH, (void *)(&TstIndex), sizeof(Word_t)); + if (PValue != PValue1) + FAILURE("JudyHSGet failed - Index missing, population =", TotalPop); + + JHSI(PValue1, *JH, (void *)(&TstIndex), sizeof(Word_t)); + if (PValue != PValue1) + { + if (*PValue1 != TstIndex) + { + FAILURE("JudyHSIns failed - Index missing, population =", TotalPop); + } + else + { +// not ready for this yet! printf("Index moved -- TotalPop = %lu\n", TotalPop); + } + } + TotalPop++; + TotalIns++; + } + return (Seed1); // New seed +} + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyGet" + +Word_t +TestJudyGet(void *J1, void *JL, void *JH, Word_t Seed, Word_t Elements) +{ + Word_t LowIndex = ~0UL; + Word_t TstIndex; + Word_t elm; + Word_t *PValue; + Word_t Seed1; + int Rcode; + + for (Seed1 = Seed, elm = 0; elm < Elements; elm++) + { + Seed1 = GetNextIndex(Seed1); + + if (DFlag) + TstIndex = Swizzle(Seed1); + else + TstIndex = Seed1; + + if (TstIndex < LowIndex) + LowIndex = TstIndex; + +#ifdef SKIPMACRO + Rcode = Judy1Test(J1, TstIndex); +#else + J1T(Rcode, J1, TstIndex); +#endif // SKIPMACRO + if (Rcode != 1) + FAILURE("Judy1Test Rcode != 1", Rcode); + +#ifdef SKIPMACRO + PValue = (PWord_t)JudyLGet(JL, TstIndex); +#else + JLG(PValue, JL, TstIndex); +#endif // SKIPMACRO + if (PValue == (Word_t *) NULL) + FAILURE("JudyLGet ret PValue = NULL", 0L); + if (*PValue != TstIndex) + FAILURE("JudyLGet ret wrong Value at", elm); + + JHSG(PValue, JH, (void *)(&TstIndex), sizeof(Word_t)); + if (PValue == (Word_t *) NULL) + FAILURE("JudyHSGet ret PValue = NULL", 0L); + if (*PValue != TstIndex) + FAILURE("JudyHSGet ret wrong Value at", elm); + } + + return(LowIndex); +} + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyDup" + +Word_t +TestJudyDup(void **J1, void **JL, void **JH, Word_t Seed, Word_t Elements) +{ + Word_t LowIndex = ~0UL; + Word_t TstIndex; + Word_t elm; + Word_t *PValue; + Word_t Seed1; + int Rcode; + + for (Seed1 = Seed, elm = 0; elm < Elements; elm++) + { + Seed1 = GetNextIndex(Seed1); + + if (DFlag) + TstIndex = Swizzle(Seed1); + else + TstIndex = Seed1; + + if (TstIndex < LowIndex) + LowIndex = TstIndex; + + J1S(Rcode, *J1, TstIndex); + if (Rcode != 0) + FAILURE("Judy1Set Rcode != 0", Rcode); + + JLI(PValue, *JL, TstIndex); + if (PValue == (Word_t *) NULL) + FAILURE("JudyLIns ret PValue = NULL", 0L); + if (*PValue != TstIndex) + FAILURE("JudyLIns ret wrong Value at", elm); + + JHSI(PValue, *JH, &TstIndex, sizeof(Word_t)); + if (PValue == (Word_t *) NULL) + FAILURE("JudyHSIns ret PValue = NULL", 0L); + if (*PValue != TstIndex) + FAILURE("JudyHSIns ret wrong Value at", elm); + } + + return(LowIndex); +} + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyCount" + +int +TestJudyCount(void *J1, void *JL, Word_t LowIndex, Word_t Elements) +{ + Word_t elm; + Word_t Count1, CountL; + Word_t TstIndex = LowIndex; + int Rcode; + + TstIndex = LowIndex; + for (elm = 0; elm < Elements; elm++) + { + J1C(Count1, J1, LowIndex, TstIndex); + if (Count1 == JERR) + FAILURE("Judy1Count ret JERR", Count1); + + if (Count1 != (elm + 1)) + { + J1C(CountL, J1, 0, -1); + printf("J1C(%lu, J1, 0, -1)\n", CountL); + + JLC(CountL, JL, 0, -1); + printf("JLC(%lu, JL, 0, -1)\n", CountL); + + printf("LowIndex = 0x%lx, TstIndex = 0x%lx, diff = %lu\n", LowIndex, + TstIndex, TstIndex - LowIndex); + JLC(CountL, JL, LowIndex, TstIndex); + printf("CountL = %lu, Count1 = %lu, should be: elm + 1 = %lu\n", CountL, Count1, elm + 1); + FAILURE("J1C at", elm); + } + + JLC(CountL, JL, LowIndex, TstIndex); + if (CountL == JERR) + FAILURE("JudyLCount ret JERR", CountL); + + if (CountL != (elm + 1)) + { + printf("CountL = %lu, elm +1 = %lu\n", CountL, elm + 1); + FAILURE("JLC at", elm); + } + + J1N(Rcode, J1, TstIndex); + } + return(0); +} + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyNext" + +Word_t TestJudyNext(void *J1, void *JL, Word_t LowIndex, Word_t Elements) +{ + Word_t JLindex, J1index, JPindex = 0; + Word_t *PValue; + Word_t elm; + int Rcode; + +// Get an Index low enough for Elements + J1index = JLindex = LowIndex; + + JLF(PValue, JL, JLindex); + J1F(Rcode, J1, J1index); + + for (elm = 0; elm < Elements; elm++) + { + if (PValue == NULL) + FAILURE("JudyLNext ret NULL PValue at", elm); + if (Rcode != 1) + FAILURE("Judy1Next Rcode != 1 =", Rcode); + if (JLindex != J1index) + FAILURE("JudyLNext & Judy1Next ret different PIndex at", elm); + + JPindex = J1index; // save the last found index + + JLN(PValue, JL, JLindex); // Get next one + J1N(Rcode, J1, J1index); // Get next one + } + + if (PValue != NULL) + FAILURE("JudyLNext PValue != NULL", PValue); + if (Rcode != 0) + FAILURE("Judy1Next Rcode != 1 =", Rcode); + +// perhaps a check should be done here -- if I knew what to expect. + return(JPindex); // return last one +} + + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyPrev" + +int +TestJudyPrev(void *J1, void *JL, Word_t HighIndex, Word_t Elements) +{ + Word_t JLindex, J1index; + Word_t *PValue; + Word_t elm; + int Rcode; + +// Get an Index high enough for Elements + J1index = JLindex = HighIndex; + + JLL(PValue, JL, JLindex); + J1L(Rcode, J1, J1index); + + for (elm = 0; elm < Elements; elm++) + { + if (PValue == NULL) + FAILURE("JudyLPrev ret NULL PValue at", elm); + if (Rcode != 1) + FAILURE("Judy1Prev Rcode != 1 =", Rcode); + if (JLindex != J1index) + FAILURE("JudyLPrev & Judy1Prev ret different PIndex at", elm); + + JLP(PValue, JL, JLindex); // Get previous one + J1P(Rcode, J1, J1index); // Get previous one + } + if (PValue != NULL) + FAILURE("JudyLPrev PValue != NULL", PValue); + if (Rcode != 0) + FAILURE("Judy1Prev Rcode != 1 =", Rcode); +// perhaps a check should be done here -- if I knew what to expect. + return(0); +} + + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyNextEmpty" + +int +TestJudyNextEmpty(void *J1, void *JL, Word_t LowIndex, Word_t Elements) +{ + Word_t elm; + Word_t JLindex, J1index; + Word_t Seed1; + int Rcode1; // Return code + int RcodeL; // Return code + +// Set 1st search to .. + Seed1 = LowIndex; + J1index = JLindex = Seed1; + + for (elm = 0; elm < Elements; elm++) + { + Word_t *PValue; + + if (pFlag) { printf("JNE: %8lu\t0x%lx\n", elm, JLindex); } + +// Find next Empty Index, JLindex is modified by JLNE + JLNE(RcodeL, JL, JLindex); // Rcode = JudyLNextEmpty(JL, &JLindex, PJE0) + +// Find next Empty Index, J1index is modified by J1NE + J1NE(Rcode1, J1, J1index); // Rcode = Judy1NextEmpty(J1, &J1index, PJE0) + if ((Rcode1 != 1) || (RcodeL != 1)) + { + printf("RcodeL = %d, Rcode1 = %d, Index1 = 0x%lx, IndexL = 0x%lx\n", + RcodeL, Rcode1, J1index, JLindex); + FAILURE("Judy1NextEmpty Rcode != 1 =", Rcode1); + } + + if (J1index != JLindex) + FAILURE("JLNE != J1NE returned index at", elm); +#ifdef SKIPMACRO + Rcode1 = Judy1Test(J1, J1index); +#else + J1T(Rcode1, J1, J1index); +#endif // SKIPMACRO + if (Rcode1 != 0) + FAILURE("J1NE returned non-empty Index =", J1index); + +#ifdef SKIPMACRO + PValue = (PWord_t)JudyLGet(JL, JLindex); +#else + JLG(PValue, JL, JLindex); +#endif // SKIPMACRO + if (PValue != (Word_t *) NULL) + FAILURE("JLNE returned non-empty Index =", JLindex); + + Seed1 = GetNextIndex(Seed1); + J1index = JLindex = Seed1; + } + return(0); +} + + +// Routine to JudyPrevEmpty routines + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyPrevEmpty" + +int +TestJudyPrevEmpty(void *J1, void *JL, Word_t HighIndex, Word_t Elements) +{ + Word_t elm; + Word_t JLindex, J1index; + Word_t Seed1; + int Rcode1; + int RcodeL; + +// Set 1st search to .. + Seed1 = HighIndex; + J1index = JLindex = Seed1; + + for (elm = 0; elm < Elements; elm++) + { + Word_t *PValue; + Word_t JPIndex; + + JPIndex = J1index; + + if (pFlag) { printf("JPE: %8lu\t0x%lx\n", elm, JPIndex); } + + J1PE(Rcode1, J1, J1index); // Rcode = Judy1PrevEmpty(J1, &J1index, PJE0) + +// Find next Empty Index, JLindex is modified by JLPE + JLPE(RcodeL, JL, JLindex); // RcodeL = JudyLPrevEmpty(JL, &JLindex, PJE0) + if ((RcodeL != 1) || (Rcode1 != 1)) + { + printf("RcodeL = %d, Rcode1 = %d, Index1 = 0x%lx, IndexL = 0x%lx\n", + RcodeL, Rcode1, J1index, JLindex); + FAILURE("Judy*PrevEmpty Rcode* != 1 =", RcodeL); + } + + if (J1index != JLindex) + FAILURE("JLPE != J1PE returned index at", elm); + +#ifdef SKIPMACRO + Rcode1 = Judy1Test(J1, J1index); +#else + J1T(Rcode1, J1, J1index); +#endif // SKIPMACRO + if (Rcode1 != 0) + FAILURE("J1PE returned non-empty Index =", J1index); + +#ifdef SKIPMACRO + PValue = (PWord_t)JudyLGet(JL, JLindex); +#else + JLG(PValue, JL, JLindex); +#endif // SKIPMACRO + if (PValue != (Word_t *) NULL) + FAILURE("JLPE returned non-empty Index =", JLindex); + + Seed1 = GetNextIndex(Seed1); + J1index = JLindex = Seed1; + } + return(0); +} + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyDel" + +int +TestJudyDel(void **J1, void **JL, void **JH, Word_t Seed, Word_t Elements) +{ + Word_t TstIndex; + Word_t elm; + Word_t Seed1; + int Rcode; + +// Only delete half of those inserted + for (Seed1 = Seed, elm = 0; elm < (Elements / 2); elm++) + { + Seed1 = GetNextIndex(Seed1); + + if (DFlag) + TstIndex = Swizzle(Seed1); + else + TstIndex = Seed1; + + if (pFlag) { printf("Del: %8lu\t0x%lx\n", elm, TstIndex); } + + TotalDel++; + + J1U(Rcode, *J1, TstIndex); + if (Rcode != 1) + FAILURE("Judy1Unset ret Rcode != 1", Rcode); + + JLD(Rcode, *JL, TstIndex); + if (Rcode != 1) + FAILURE("JudyLDel ret Rcode != 1", Rcode); + + JHSD(Rcode, *JH, (void *)(&TstIndex), sizeof(Word_t)); + if (Rcode != 1) + FAILURE("JudyHSDel ret Rcode != 1", Rcode); + + TotalPop--; + } + return(0); +} + +// Routine to get next size of Indexes +int // return 1 if last number +NextNumb(Word_t * PNumber, // pointer to returned next number + double *PDNumb, // Temp double of above + double DMult, // Multiplier + Word_t MaxNumb) // Max number to return +{ + Word_t num; + +// Save prev number + Word_t PrevNumb = *PNumber; + +// Verify integer number increased + for (num = 0; num < 1000; num++) + { +// Calc next number + *PDNumb *= DMult; + +// Return it in integer format + *PNumber = (Word_t) (*PDNumb + 0.5); + + if (*PNumber != PrevNumb) + break; + } + +// Verify it did exceed max ulong + if ((*PDNumb + 0.5) > (double)(-1UL)) + { +// It did, so return max number + *PNumber = -1UL; + return (1); // flag it + } + +// Verify it did not exceed max number + if ((*PDNumb + 0.5) > (double)MaxNumb) + { +// it did, so return max + *PNumber = MaxNumb; + return(1); // flag it + } + return(0); // more available +} diff --git a/feeds/p4/libjudy/src/test/Judy1LHTime.c b/feeds/p4/libjudy/src/test/Judy1LHTime.c new file mode 100644 index 000000000..004036b49 --- /dev/null +++ b/feeds/p4/libjudy/src/test/Judy1LHTime.c @@ -0,0 +1,2235 @@ +// @(#) $Revision: 4.20 $ $Source: /judy/test/manual/Judy1LHTime.c $ +//======================================================================= +// This program measures the performance of a Judy1 and JudyL Array. +// -by- +// Author Douglas L. Baskins, Aug 2003. +// Permission to use this code is freely granted, provided that this +// statement is retained. +// email - dougbaskins@yahoo.com +//======================================================================= + +#include // sbrk() +#include // exit() +#include // printf(), setbuf() +#include // pow() +#include // gettimeofday() +#include // uname() + +#include // for Judy macros J*() +//#include // compiling with old Judy.h without JudyHS + +#ifdef NOINLINE /* this is the 21st century? */ +#define _INLINE_ static +#else +#define _INLINE_ inline +#endif + +//======================================================================= +// This program measures the performance of a Judy1, JudyL and +// limited to one size of string (sizeof Word_t) JudyHS Arrays. +// +// Compile: +// +// cc -O Judy1LHTime.c -lm -lJudy -o Judy1LHTime +// -or- +// cc -O -DCPUMHZ=2400 Judy1LHTime.c -lm -lJudy -o Judy1LHTime + +/* Notes: + 1) Use '-DCPUMHZ=2400' in cc line if better clock resolution is desired + and it compiles successfully. The 2400 is the cpu MHz : 2400 -or- + cat /proc/cpuinfo | grep "cpu MHz" in a Linux system. + 2) +*/ + +//======================================================================= +// T I M I N G M A C R O S +//======================================================================= + +double DeltaUSec; // Global for remembering delta times + +#ifdef CPUMHZ + +// For a 1.34 nS clock cycle processor (750Mhz) + +#define CPUSPEED (1.0 / (CPUMHZ)) + +//#define rdtscll(val) __asm__ __volatile__("rdtsc" : "=A" (val)) + +#define rdtscl(low) __asm__ __volatile__("rdtsc" : "=a" (low) : : "edx") + +static inline uint32_t +get_cycles(void) +{ + uint32_t ret = 0; + rdtscl(ret); + return (ret); +} + +#define STARTTm \ +{ \ + gettimeofday(&TVBeg__, NULL); \ + GCBeg__ = get_cycles(); \ +} + +#define ENDTm(D) \ +{ \ + uint32_t GCEnd__; \ + GCEnd__ = get_cycles(); \ + gettimeofday(&TVEnd__, NULL); \ + (D) = (double)(TVEnd__.tv_sec - TVBeg__.tv_sec) * 1E6 + \ + ((double)(TVEnd__.tv_usec - TVBeg__.tv_usec)); \ + if (D < 10000.0) D = (double)(GCEnd__ - GCBeg__) * CPUSPEED; \ +} + +#else // ! CPUMHZ + +#define STARTTm gettimeofday(&TVBeg__, NULL) + +#define ENDTm(D) \ +{ \ + gettimeofday(&TVEnd__, NULL); \ + (D) = (double)(TVEnd__.tv_sec - TVBeg__.tv_sec) * 1E6 + \ + ((double)(TVEnd__.tv_usec - TVBeg__.tv_usec)); \ +} + +#endif // ! CPUMHZ + +// **************************************************************************** +// J U D Y M A L L O C +// +// Allocate RAM. This is the single location in Judy code that calls +// malloc(3C). Note: JPM accounting occurs at a higher level. + +enum +{ + JudyMal1, + JudyMalL, + JudyMalHS +} MalFlag; + +static Word_t MalFreeCnt = 0; + +Word_t TotJudy1MemUsed = 0; +Word_t TotJudyLMemUsed = 0; +Word_t TotJudyHSMemUsed = 0; + +Word_t +JudyMalloc(Word_t Words) +{ + Word_t Addr; + Word_t IncWords; + + Addr = (Word_t)malloc(Words * sizeof(Word_t)); + + if (Addr) + { + IncWords = Words; + MalFreeCnt++; + +// Adjust for overhead of (dl)malloc + if (Words % 1) + IncWords += 1; + else + IncWords += 2; + + switch (MalFlag) + { + case JudyMal1: + TotJudy1MemUsed += IncWords; + break; + case JudyMalL: + TotJudyLMemUsed += IncWords; + break; + case JudyMalHS: + TotJudyHSMemUsed += IncWords; + break; + } + } + return (Addr); +} // JudyMalloc() + +// **************************************************************************** +// J U D Y F R E E + +void +JudyFree(void *PWord, Word_t Words) +{ + Word_t DecWords; + + if (Words == 0) + printf("OOps JudyFree called with 0 words\n"); + + free(PWord); + DecWords = Words; + MalFreeCnt++; + +// Adjust for overhead of (dl)malloc + if (Words % 1) + DecWords += 1; + else + DecWords += 2; + + switch (MalFlag) + { + case JudyMal1: + TotJudy1MemUsed -= DecWords; + break; + case JudyMalL: + TotJudyLMemUsed -= DecWords; + break; + case JudyMalHS: + TotJudyHSMemUsed -= DecWords; + break; + } +} // JudyFree() + +// **************************************************************************** +// J U D Y M A L L O C +// +// Higher-level "wrapper" for allocating objects that need not be in RAM, +// although at this time they are in fact only in RAM. Later we hope that some +// entire subtrees (at a JPM or branch) can be "virtual", so their allocations +// and frees should go through this level. + +Word_t +JudyMallocVirtual(Word_t Words) +{ + return (JudyMalloc(Words)); + +} // JudyMallocVirtual() + +// **************************************************************************** +// J U D Y F R E E + +void +JudyFreeVirtual(void *PWord, Word_t Words) +{ + JudyFree(PWord, Words); + +} // JudyFreeVirtual() + +//======================================================================= + +// Common macro to handle a failure +#define FAILURE(STR, UL) \ +{ \ +printf( "\nError: %s %lu, file='%s', 'function='%s', line %d\n", \ + STR, (Word_t)(UL), __FILE__, __FUNCTI0N__, __LINE__); \ +fprintf(stderr,"\nError: %s %lu, file='%s', 'function='%s', line %d\n", \ + STR, (Word_t)(UL), __FILE__, __FUNCTI0N__, __LINE__); \ + exit(1); \ +} + +// Interations without improvement +// Minimum of 2 loops, maximum of 1000000 +#define MINLOOPS 2 +#define MAXLOOPS 1000000 + +// Maximum or 10 loops with no improvement +#define ICNT 10 + +// Structure to keep track of times +typedef struct MEASUREMENTS_STRUCT +{ + Word_t ms_delta; +} +ms_t , *Pms_t; + +// Specify prototypes for each test routine +int NextNumb(Word_t *PNumber, double *PDNumb, double DMult, Word_t MaxN); + +Word_t TestJudyIns(void **J1, void **JL, void **JH, Word_t Seed, + Word_t Elems); + +Word_t TestJudyDup(void **J1, void **JL, void **JH, Word_t Seed, + Word_t Elems); + +int TestJudyDel(void **J1, void **JL, void **JH, Word_t Seed, + Word_t Elems); + +Word_t TestJudyGet(void *J1, void *JL, void *JH, Word_t Seed, Word_t Elems); + +int TestJudy1Copy(void *J1, Word_t Elem); + +int TestJudyCount(void *J1, void *JL, Word_t LowIndex, Word_t Elems); + +Word_t TestJudyNext(void *J1, void *JL, Word_t LowIndex, Word_t Elems); + +int TestJudyPrev(void *J1, void *JL, Word_t HighIndex, Word_t Elems); + +Word_t TestJudyNextEmpty(void *J1, void *JL, Word_t LowIndex, Word_t Elems); + +Word_t TestJudyPrevEmpty(void *J1, void *JL, Word_t HighIndex, Word_t Elems); + +//======================================================================= +// These are LFSF feedback taps for bitwidths of 10..64 sized numbers. +// Tested with Seed=0xc1fc to 35 billion numbers +//======================================================================= + +Word_t StartSeed = 0xc1fc; // default beginning number +Word_t FirstSeed; + +Word_t MagicList[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0..9 + 0x27f, // 10 + 0x27f, // 11 + 0x27f, // 12 + 0x27f, // 13 + 0x27f, // 14 + 0x27f, // 15 + 0x1e71, // 16 + 0xdc0b, // 17 + 0xdc0b, // 18 + 0xdc0b, // 19 + 0xdc0b, // 20 + 0xc4fb, // 21 + 0xc4fb, // 22 + 0xc4fb, // 23 + 0x13aab, // 24 + 0x11ca3, // 25 + 0x11ca3, // 26 + 0x11ca3, // 27 + 0x13aab, // 28 + 0x11ca3, // 29 + 0xc4fb, // 30 + 0xc4fb, // 31 + 0x13aab, // 32 + 0x14e73, // 33 + 0x145d7, // 34 + 0x145f9, // 35 following tested with Seed=0xc1fc to 35 billion numbers + 0x151ed, // 36 .. 41 + 0x151ed, // 37 + 0x151ed, // 38 + 0x151ed, // 39 + 0x151ed, // 40 + 0x146c3, // 41 .. 64 + 0x146c3, // 42 + 0x146c3, // 43 + 0x146c3, // 44 + 0x146c3, // 45 + 0x146c3, // 46 + 0x146c3, // 47 + 0x146c3, // 48 + 0x146c3, // 49 + 0x146c3, // 50 + 0x146c3, // 51 + 0x146c3, // 52 + 0x146c3, // 53 + 0x146c3, // 54 + 0x146c3, // 55 + 0x146c3, // 56 + 0x146c3, // 57 + 0x146c3, // 58 + 0x146c3, // 59 + 0x146c3, // 60 + 0x146c3, // 61 + 0x146c3, // 62 + 0x146c3, // 63 + 0x146c3 // 64 +}; + +// Routine to "mirror" the input data word +static Word_t +Swizzle(Word_t word) +{ +// BIT REVERSAL, Ron Gutman in Dr. Dobb's Journal, #316, Sept 2000, pp133-136 +// + +#ifdef __LP64__ + word = ((word & 0x00000000ffffffff) << 32) | + ((word & 0xffffffff00000000) >> 32); + word = ((word & 0x0000ffff0000ffff) << 16) | + ((word & 0xffff0000ffff0000) >> 16); + word = ((word & 0x00ff00ff00ff00ff) << 8) | + ((word & 0xff00ff00ff00ff00) >> 8); + word = ((word & 0x0f0f0f0f0f0f0f0f) << 4) | + ((word & 0xf0f0f0f0f0f0f0f0) >> 4); + word = ((word & 0x3333333333333333) << 2) | + ((word & 0xcccccccccccccccc) >> 2); + word = ((word & 0x5555555555555555) << 1) | + ((word & 0xaaaaaaaaaaaaaaaa) >> 1); +#else // not __LP64__ + word = ((word & 0x0000ffff) << 16) | ((word & 0xffff0000) >> 16); + word = ((word & 0x00ff00ff) << 8) | ((word & 0xff00ff00) >> 8); + word = ((word & 0x0f0f0f0f) << 4) | ((word & 0xf0f0f0f0) >> 4); + word = ((word & 0x33333333) << 2) | ((word & 0xcccccccc) >> 2); + word = ((word & 0x55555555) << 1) | ((word & 0xaaaaaaaa) >> 1); +#endif // not __LP64__ + + return (word); +} + +double DeltaUSec1 = 0.0; // Global for measuring delta times +double DeltaUSecL = 0.0; // Global for measuring delta times +double DeltaUSecHS = 0.0; // Global for measuring delta times +double DeltaMalFre1 = 0.0; // Delta mallocs/frees per inserted index +double DeltaMalFreL = 0.0; // Delta mallocs/frees per inserted index +double DeltaMalFreHS = 0.0; // Delta mallocs/frees per inserted index +double DeltaMalFre = 0.0; // Delta mallocs/frees per inserted index + +Word_t J1Flag = 0; // time Judy1 +Word_t JLFlag = 0; // time JudyL +Word_t JHFlag = 0; // time JudyHS +Word_t dFlag = 0; // time Judy1Unset JudyLDel +Word_t vFlag = 0; // time Searching +Word_t CFlag = 0; // time Counting +Word_t cFlag = 0; // time Copy of Judy1 array +Word_t IFlag = 0; // time duplicate inserts/sets +Word_t DFlag = 0; // bit reverse the data stream +Word_t lFlag = 0; // do not do multi-insert tests +Word_t SkipN = 0; // default == Random skip +Word_t TValues = 1000000; // Maximum retrieve tests for timing +Word_t nElms = 1000000; // Max population of arrays +Word_t ErrorFlag = 0; +Word_t PtsPdec = 40; // measurement points per decade + +// Stuff for LFSR (pseudo random number generator) +Word_t RandomBit = ~0UL / 2 + 1; +Word_t BValue = sizeof(Word_t) * 8; +Word_t Magic; + +// for error routines -- notice misspelling, name conflicts with some compilers +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "Random" + +_INLINE_ Word_t // so INLINING compilers get to look at it. +Random(Word_t newseed) +{ + if (newseed & RandomBit) + { + newseed += newseed; + newseed ^= Magic; + } + else + { + newseed += newseed; + } + newseed &= RandomBit * 2 - 1; + if (newseed == FirstSeed) + FAILURE("LFSR failed", newseed); + return (newseed); +} + +_INLINE_ Word_t // so INLINING compilers get to look at it. +GetNextIndex(Word_t Index) +{ + if (SkipN) + Index += SkipN; + else + Index = Random(Index); + + return (Index); +} + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "main" + +struct timeval TVBeg__, TVEnd__; + +#ifdef CPUMHZ +uint32_t GCBeg__; +#endif // CPUMHZ + +int +main(int argc, char *argv[]) +{ +// Names of Judy Arrays + void *J1 = NULL; // Judy1 + void *JL = NULL; // JudyL + void *JH = NULL; // JudyHS + + Word_t Count1, CountL; // , CountHS; + Word_t Bytes; + + double Mult; + Pms_t Pms; + Word_t Seed; + Word_t PtsPdec = 40; // points per decade + Word_t Groups; // Number of measurement groups + Word_t grp; + Word_t Pop1; + Word_t Meas; + int Col; + + int c; + extern char *optarg; + + setbuf(stdout, NULL); // unbuffer output + +//============================================================ +// PARSE INPUT PARAMETERS +//============================================================ + + while ((c = getopt(argc, argv, "n:S:T:P:b:B:dDcC1LHvIl")) != -1) + { + switch (c) + { + case 'n': // Max population of arrays + nElms = strtoul(optarg, NULL, 0); // Size of Linear Array + if (nElms == 0) + FAILURE("No tests: -n", nElms); + break; + + case 'S': // Step Size, 0 == Random + SkipN = strtoul(optarg, NULL, 0); + break; + + case 'T': // Maximum retrieve tests for timing + TValues = strtoul(optarg, NULL, 0); + break; + + case 'P': // measurement points per decade + PtsPdec = strtoul(optarg, NULL, 0); + break; + + case 'b': // May not work past 35 bits if changed + StartSeed = strtoul(optarg, NULL, 0); + break; + + case 'B': // expanse of data points (random only) + BValue = strtoul(optarg, NULL, 0); + if ((BValue > 64) + || (MagicList[BValue] == 0) || (BValue > (sizeof(Word_t) * 8))) + { + ErrorFlag++; + printf("\nIllegal number of random bits of %lu !!!\n", BValue); + } + break; + + case 'v': + vFlag = 1; // time Searching + break; + + case '1': // time Judy1 + J1Flag = 1; + break; + + case 'L': // time JudyL + JLFlag = 1; + break; + + case 'H': // time JudyHS + JHFlag = 1; + break; + + case 'd': // time Judy1Unset JudyLDel + dFlag = 1; + break; + + case 'D': // bit reverse the data stream + DFlag = 1; + break; + + case 'c': // time Copy Judy1 array + cFlag = 1; + break; + + case 'C': // time Counting + CFlag = 1; + break; + + case 'I': // time duplicate insert/set + IFlag = 1; + break; + + case 'l': // do not loop in tests + lFlag = 1; + break; + + default: + ErrorFlag++; + break; + } + } + + if (ErrorFlag) + { + printf("\n%s -n# -P# -S# -B# -T# -dDcCpdI\n\n", argv[0]); + printf("Where:\n"); + printf("-n <#> number of indexes (1000000) used in tests\n"); + printf("-P <#> number measurement points (40) per decade\n"); + printf("-S <#> index skip amount, 0 = random\n"); + printf("-B <#> # bits (10..%d) in random number generator\n", + (int)sizeof(Word_t) * 8); + printf("-L time JudyL\n"); + printf("-1 time Judy1\n"); + printf("-H time JudyHS\n"); + printf("-I time DUPLICATE Ins/Set times\n"); + printf("-c time copy Judy1 Array\n"); + printf("-C time JudyCount tests\n"); + printf("-v time Judy First/Last/Next/Prev tests\n"); + printf("-d time JudyDel/Unset\n"); + printf("-l do not loop on same Indexes\n"); + printf("-T <#> max number indexes in read times - 0 == MAX\n"); + printf("\n"); + + exit(1); + } + +// If none, then all + if (!JLFlag && !J1Flag && !JHFlag) + JHFlag = JLFlag = J1Flag = 1; + +// Set number of Random bits in LFSR + RandomBit = 1UL << (BValue - 1); + Magic = MagicList[BValue]; + + if (nElms > ((RandomBit - 2) * 2)) + { + printf + ("# Number = -n%lu of Indexes reduced to max expanse of Random numbers\n", + nElms); + nElms = ((RandomBit - 2) * 2); + } + + printf("# TITLE %s -n%lu -S%lu -T%lu -B%lu -P%lu", + argv[0], nElms, SkipN, TValues, BValue, PtsPdec); + +// case 'b': // May not work past 35 bits if changed + + if (J1Flag) + printf(" -1"); + if (JLFlag) + printf(" -L"); + if (JHFlag) + printf(" -H"); + if (DFlag) + printf(" -D"); + if (dFlag) + printf(" -d"); + if (cFlag) + printf(" -c"); + if (CFlag) + printf(" -C"); + if (IFlag) + printf(" -I"); + if (lFlag) + printf(" -l"); + if (vFlag) + printf(" -v"); + printf("\n"); + +// uname(2) strings describing the machine + { + struct utsname ubuf; // for system name + + if (uname(&ubuf) == -1) + printf("# Uname(2) failed\n"); + else + printf("# %s %s %s %s %s\n", ubuf.sysname, ubuf.nodename, + ubuf.release, ubuf.version, ubuf.machine); + } + if (sizeof(Word_t) == 8) + printf("# %s 64 Bit version\n", argv[0]); + else if (sizeof(Word_t) == 4) + printf("# %s 32 Bit version\n", argv[0]); + + printf("# XLABEL Population\n"); + printf("# YLABEL Microseconds / Index\n"); + +//============================================================ +// CALCULATE NUMBER OF MEASUREMENT GROUPS +//============================================================ + +// Calculate Multiplier for number of points per decade + Mult = pow(10.0, 1.0 / (double)PtsPdec); + { + double sum; + Word_t numb, prevnumb; + +// Count number of measurements needed (10K max) + sum = numb = 1; + for (Groups = 2; Groups < 10000; Groups++) + { + if (NextNumb(&numb, &sum, Mult, nElms)) + break; + } + +// Get memory for measurements + Pms = (Pms_t) calloc(Groups, sizeof(ms_t)); + +// Now calculate number of Indexes for each measurement point + numb = sum = 1; + prevnumb = 0; + for (grp = 0; grp < Groups; grp++) + { + Pms[grp].ms_delta = numb - prevnumb; + prevnumb = numb; + + NextNumb(&numb, &sum, Mult, nElms); + } + } // Groups = number of sizes + +//============================================================ +// PRINT HEADER TO PERFORMANCE TIMERS +//============================================================ + + Col = 1; + printf("# COLHEAD %d Population\n", Col++); + printf("# COLHEAD %d Measurments\n", Col++); + printf("# COLHEAD %d J1S - Judy1Set\n", Col++); + printf("# COLHEAD %d JLI - JudyLIns\n", Col++); + printf("# COLHEAD %d JHSI - JudyHSIns\n", Col++); + printf("# COLHEAD %d J1T - Judy1Test\n", Col++); + printf("# COLHEAD %d JLG - JudyLGet\n", Col++); + printf("# COLHEAD %d JHSG - JudyHSGet\n", Col++); + + if (IFlag) + { + printf("# COLHEAD %d J1S-dup\n", Col++); + printf("# COLHEAD %d JLI-dup\n", Col++); + printf("# COLHEAD %d JHSI-dup\n", Col++); + } + if (cFlag) + { + printf("# COLHEAD %d Copy J1T->J1S\n", Col++); + } + if (CFlag) + { + printf("# COLHEAD %d J1C\n", Col++); + printf("# COLHEAD %d JLC\n", Col++); + } + if (vFlag) + { + printf("# COLHEAD %d J1N\n", Col++); + printf("# COLHEAD %d JLN\n", Col++); + printf("# COLHEAD %d J1P\n", Col++); + printf("# COLHEAD %d JLP\n", Col++); + printf("# COLHEAD %d J1NE\n", Col++); + printf("# COLHEAD %d JLNE\n", Col++); + printf("# COLHEAD %d J1PE\n", Col++); + printf("# COLHEAD %d JLPE\n", Col++); + } + if (dFlag) + { + printf("# COLHEAD %d J1U\n", Col++); + printf("# COLHEAD %d JLD\n", Col++); + printf("# COLHEAD %d JHSD\n", Col++); + } + printf("# COLHEAD %d 1heap/I - Judy1 heap memery per Index\n", Col++); + printf("# COLHEAD %d Lheap/I - JudyL heap memery per Index\n", Col++); + printf("# COLHEAD %d HSheap/I - JudyHS heap memery per Index\n", Col++); + printf("# COLHEAD %d MF1/I - Judy1 malloc+free's per delta Indexes\n", + Col++); + printf("# COLHEAD %d MFL/I - JudyL malloc+free's per delta Indexes\n", + Col++); + printf("# COLHEAD %d MFHS/I - JudyHS malloc+free's per delta Indexes\n", + Col++); + +#ifdef CPUMHZ + printf("#\n# Compiled for processor speed of %d Mhz\n#\n", CPUMHZ); +#endif // CPUMHZ + + printf("# %s - Leaf sizes in Words\n", Judy1MallocSizes); + printf("# %s - Leaf sizes in Words\n#\n", JudyLMallocSizes); + + printf("# Pop1 Measmts J1S JLI JHSI J1T JLG JHSG"); + + if (IFlag) + printf(" dupJ1S dupJLI dupJHI"); + + if (cFlag) + printf(" CopyJ1"); + + if (CFlag) + printf(" J1C JLC"); + + if (vFlag) + printf(" J1N JLN J1P JLP J1NE JLNE J1PE JLPE"); + + if (dFlag) + printf(" J1U JLD JHSD"); + + printf(" 1heap/I Lheap/I HSheap/I"); + + printf(" MF1/I"); + printf(" MFL/I"); + printf(" MFHS/I"); + + printf("\n"); + +//============================================================ +// BEGIN TESTS AT EACH GROUP SIZE +//============================================================ + +// Get the kicker to test the LFSR + FirstSeed = Seed = StartSeed & (RandomBit * 2 - 1); + + for (Pop1 = grp = 0; grp < Groups; grp++) + { + Word_t LowIndex; + Word_t Delta; + Word_t NewSeed; + + Delta = Pms[grp].ms_delta; + +// Test J1S, JLI + NewSeed = TestJudyIns(&J1, &JL, &JH, Seed, Delta); + +// Accumulate the Total population of arrays + Pop1 += Delta; + Meas = Pop1; + +// Only test the maximum of TValues if not zero + if (TValues) + Meas = (Pop1 < TValues) ? Pop1 : TValues; + + printf("%10lu %9lu", Pop1, Meas); + printf(" %6.3f", DeltaUSec1); + printf(" %6.3f", DeltaUSecL); + printf(" %6.3f", DeltaUSecHS); + fflush(NULL); + +// Test J1T, JLG, JHSG + + LowIndex = TestJudyGet(J1, JL, JH, FirstSeed, Meas); + printf(" %6.3f", DeltaUSec1); + printf(" %6.3f", DeltaUSecL); + printf(" %6.3f", DeltaUSecHS); + fflush(NULL); + +// Test J1T, JLI, JHSI - duplicates + + if (IFlag) + { + LowIndex = TestJudyDup(&J1, &JL, &JH, FirstSeed, Meas); + printf(" %6.3f", DeltaUSec1); + printf(" %6.3f", DeltaUSecL); + printf(" %6.3f", DeltaUSecHS); + fflush(NULL); + } + if (cFlag) + { + TestJudy1Copy(J1, Meas); + printf(" %6.3f", DeltaUSec1); + fflush(NULL); + } + if (CFlag) + { + TestJudyCount(J1, JL, LowIndex, Meas); + printf(" %6.3f", DeltaUSec1); + printf(" %6.3f", DeltaUSecL); + fflush(NULL); + } + if (vFlag) + { +// Test J1N, JLN +// HighIndex = TestJudyNext(J1, JL, LowIndex, Meas); + TestJudyNext(J1, JL, 0, Meas); + printf(" %6.3f", DeltaUSec1); + printf(" %6.3f", DeltaUSecL); + fflush(NULL); + +// Test J1P, JLP + TestJudyPrev(J1, JL, ~0UL, Meas); +// TestJudyPrev(J1, JL, HighIndex, Meas); + printf(" %6.3f", DeltaUSec1); + printf(" %6.3f", DeltaUSecL); + fflush(NULL); + +// Test J1NE, JLNE + TestJudyNextEmpty(J1, JL, 0UL, Meas); + printf(" %6.3f", DeltaUSec1); + printf(" %6.3f", DeltaUSecL); + fflush(NULL); + +// Test J1PE, JLPE + TestJudyPrevEmpty(J1, JL, ~0UL, Meas); + printf(" %6.3f", DeltaUSec1); + printf(" %6.3f", DeltaUSecL); + fflush(NULL); + } + +// Test J1U, JLD, JHSD + if (dFlag) + { + TestJudyDel(&J1, &JL, &JH, FirstSeed, Meas); + printf(" %6.3f", DeltaUSec1); + printf(" %6.3f", DeltaUSecL); + printf(" %6.3f", DeltaUSecHS); + fflush(NULL); + +// Now put them back + TestJudyIns(&J1, &JL, &JH, FirstSeed, Meas); + } + +// Advance Index number set + Seed = NewSeed; + +// Print the number of bytes used per Index + printf(" %7.3f", + (double)TotJudy1MemUsed * sizeof(Word_t) / (double)Pop1); + printf(" %7.3f", + (double)TotJudyLMemUsed * sizeof(Word_t) / (double)Pop1); + printf(" %8.3f", + (double)TotJudyHSMemUsed * sizeof(Word_t) / (double)Pop1); + + printf(" %5.3f", DeltaMalFre1); + printf(" %5.3f", DeltaMalFreL); + printf(" %5.3f", DeltaMalFreHS); + + printf("\n"); + fflush(NULL); // assure data gets to file in case malloc fail + } + +#ifdef SKIPMACRO + Count1 = Judy1Count(J1, 0, -1, PJE0); + CountL = JudyLCount(JL, 0, -1, PJE0); +#else + JLC(CountL, JL, 0, -1); // get the counts + J1C(Count1, J1, 0, -1); +#endif // SKIPMACRO + + if (JLFlag && J1Flag) + { + if (CountL != Count1) + FAILURE("Judy1/LCount not equal", Count1); + } + +// if (Count1) + { + Word_t Cnt1 = Count1; + if (Cnt1 == 0) + Cnt1 = 1UL; + + STARTTm; + +#ifdef SKIPMACRO + Bytes = Judy1FreeArray(&J1, PJE0); +#else + J1FA(Bytes, J1); // Free the Judy1 Array +#endif // SKIPMACRO + + ENDTm(DeltaUSec1); + DeltaUSec1 /= (double)Cnt1; + + printf("# Judy1FreeArray: %lu, %0.3f bytes/Index, %0.3f USec/Index\n", + Count1, (double)Bytes / (double)Cnt1, DeltaUSec1); + } + +// if (CountL) + { + Word_t CntL = CountL; + if (CntL == 0) + CntL = 1UL; + + STARTTm; + +#ifdef SKIPMACRO + Bytes = JudyLFreeArray(&JL, PJE0); +#else + JLFA(Bytes, JL); // Free the JudyL Array +#endif // SKIPMACRO + + ENDTm(DeltaUSecL); + DeltaUSecL /= (double)CntL; + + printf("# JudyLFreeArray: %lu, %0.3f bytes/Index, %0.3f USec/Index\n", + CountL, (double)Bytes / (double)CntL, DeltaUSecL); + } +// if (CountHS) + { +// Word_t CntHS = CountHS; +// if (CntHS == 0) CntHS = 1UL; + + STARTTm; + +#ifdef SKIPMACRO + Bytes = JudyHSFreeArray(&JH, PJE0); // Free the JudyHS Array +#else + JHSFA(Bytes, JH); // Free the JudyHS Array +#endif // SKIPMACRO + + ENDTm(DeltaUSecHS); + DeltaUSecHS /= (double)nElms; // no Counts yet + + printf("# JudyHSFreeArray: %lu, %0.3f bytes/Index, %0.3f USec/Index\n", + nElms, (double)Bytes / (double)nElms, DeltaUSecHS); + } + exit(0); +} + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyIns" + +Word_t +TestJudyIns(void **J1, void **JL, void **JH, Word_t Seed, Word_t Elements) +{ + Word_t TstIndex; + Word_t elm; + Word_t *PValue; + Word_t Seed1 = 0; + int Rc; + + double DDel; + Word_t icnt; + Word_t lp; + Word_t Loops; + Word_t StartMallocs; + + if (Elements < 100) + Loops = (MAXLOOPS / Elements) + MINLOOPS; + else + Loops = 1; + + if (lFlag) + Loops = 1; + +// Judy1Set timings + + if (J1Flag) + { + MalFlag = JudyMal1; + for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++) + { + if (lp != 0) + { + for (Seed1 = Seed, elm = 0; elm < Elements; elm++) + { + Seed1 = GetNextIndex(Seed1); + + if (DFlag) + TstIndex = Swizzle(Seed1); + else + TstIndex = Seed1; +#ifdef SKIPMACRO + Rc = Judy1Unset(J1, TstIndex, PJE0); +#else + J1U(Rc, *J1, TstIndex); +#endif // SKIPMACRO + } + } + + StartMallocs = MalFreeCnt; + STARTTm; + for (Seed1 = Seed, elm = 0; elm < Elements; elm++) + { + Seed1 = GetNextIndex(Seed1); + + if (DFlag) + TstIndex = Swizzle(Seed1); + else + TstIndex = Seed1; + + J1S(Rc, *J1, TstIndex); + if (Rc == 0) + FAILURE("Judy1Set failed - DUP Index at", elm); +#ifdef DIAG + Rc = Judy1Test(*J1, TstIndex, PJE0); + if (Rc != 1) + FAILURE("Judy1Test failed at", elm); +#endif // DIAG + } + ENDTm(DeltaUSec1); + DeltaMalFre1 = (double)(MalFreeCnt - StartMallocs) / Elements; + + if (DDel > DeltaUSec1) + { + icnt = ICNT; + DDel = DeltaUSec1; + } + else + { + if (--icnt == 0) + break; + } + } + DeltaUSec1 = DDel / (double)Elements; + } + +// JudyLIns timings + + if (JLFlag) + { + MalFlag = JudyMalL; + for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++) + { + if (lp != 0) + { + for (Seed1 = Seed, elm = 0; elm < Elements; elm++) + { + Seed1 = GetNextIndex(Seed1); + + if (DFlag) + TstIndex = Swizzle(Seed1); + else + TstIndex = Seed1; +#ifdef SKIPMACRO + Rc = JudyLDel(JL, TstIndex, PJE0); +#else + JLD(Rc, *JL, TstIndex); +#endif // SKIPMACRO + } + } + + StartMallocs = MalFreeCnt; + STARTTm; + for (Seed1 = Seed, elm = 0; elm < Elements; elm++) + { + Seed1 = GetNextIndex(Seed1); + + if (DFlag) + TstIndex = Swizzle(Seed1); + else + TstIndex = Seed1; + + JLI(PValue, *JL, TstIndex); + if (*PValue == TstIndex) + { + printf("Index = 0x%0lx, ", TstIndex); + FAILURE("JudyLIns failed - DUP Index", TstIndex); + } + *PValue = TstIndex; // save Index in Value +#ifdef DIAG + PValue = (PWord_t)JudyLGet(*JL, TstIndex, PJE0); + if (PValue == NULL) + { + printf("Index = 0x%0lx, ", TstIndex); + FAILURE("JudyLGet failed", TstIndex); + } +#endif // DIAG + } + ENDTm(DeltaUSecL); + DeltaUSecL /= Elements; + DeltaMalFreL = (double)(MalFreeCnt - StartMallocs) / Elements; + + if (DDel > DeltaUSecL) + { + icnt = ICNT; + DDel = DeltaUSecL; + } + else + { + if (--icnt == 0) + break; + } + } + } + +// JudyHSIns timings + + if (JHFlag) + { + MalFlag = JudyMalHS; + for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++) + { + if (lp != 0) + { + for (Seed1 = Seed, elm = 0; elm < Elements; elm++) + { + Seed1 = GetNextIndex(Seed1); + + if (DFlag) + TstIndex = Swizzle(Seed1); + else + TstIndex = Seed1; + + JHSD(Rc, *JH, &TstIndex, sizeof(Word_t)); + } + } + + StartMallocs = MalFreeCnt; + STARTTm; + for (Seed1 = Seed, elm = 0; elm < Elements; elm++) + { + Seed1 = GetNextIndex(Seed1); + + if (DFlag) + TstIndex = Swizzle(Seed1); + else + TstIndex = Seed1; + + JHSI(PValue, *JH, &TstIndex, sizeof(Word_t)); + if (*PValue == TstIndex) + FAILURE("JudyHSIns failed - DUP Index", TstIndex); + + *PValue = TstIndex; // save Index in Value + } + ENDTm(DeltaUSecHS); + DeltaUSecHS /= Elements; + DeltaMalFreHS = (double)(MalFreeCnt - StartMallocs) / Elements; + + if (DDel > DeltaUSecHS) + { + icnt = ICNT; + DDel = DeltaUSecHS; + } + else + { + if (--icnt == 0) + break; + } + } + } + return (Seed1); // New seed +} + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyDup" + +Word_t +TestJudyDup(void **J1, void **JL, void **JH, Word_t Seed, Word_t Elements) +{ + Word_t LowIndex = ~0UL; + Word_t TstIndex; + Word_t elm; + Word_t *PValue; + Word_t Seed1; + int Rc; + + double DDel; + Word_t icnt; + Word_t lp; + Word_t Loops; + + Loops = (MAXLOOPS / Elements) + MINLOOPS; + if (lFlag) + Loops = 1; + + if (J1Flag) + { + MalFlag = JudyMal1; + LowIndex = ~0UL; + for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++) + { + STARTTm; + for (Seed1 = Seed, elm = 0; elm < Elements; elm++) + { + Seed1 = GetNextIndex(Seed1); + + if (DFlag) + TstIndex = Swizzle(Seed1); + else + TstIndex = Seed1; + + if (TstIndex < LowIndex) + LowIndex = TstIndex; + + J1S(Rc, *J1, TstIndex); + if (Rc != 0) + FAILURE("Judy1Test Rc != 0", Rc); + } + ENDTm(DeltaUSec1); + + if (DDel > DeltaUSec1) + { + icnt = ICNT; + DDel = DeltaUSec1; + } + else + { + if (--icnt == 0) + break; + } + } + DeltaUSec1 = DDel / (double)Elements; + } + + icnt = ICNT; + + if (JLFlag) + { + MalFlag = JudyMalL; + LowIndex = ~0UL; + for (DDel = 1e40, lp = 0; lp < Loops; lp++) + { + STARTTm; + for (Seed1 = Seed, elm = 0; elm < Elements; elm++) + { + Seed1 = GetNextIndex(Seed1); + + if (DFlag) + TstIndex = Swizzle(Seed1); + else + TstIndex = Seed1; + + if (TstIndex < LowIndex) + LowIndex = TstIndex; + + JLI(PValue, *JL, TstIndex); + if (PValue == (Word_t *)NULL) + FAILURE("JudyLGet ret PValue = NULL", 0L); + if (*PValue != TstIndex) + FAILURE("JudyLGet ret wrong Value at", elm); + } + ENDTm(DeltaUSecL); + + if (DDel > DeltaUSecL) + { + icnt = ICNT; + DDel = DeltaUSecL; + } + else + { + if (--icnt == 0) + break; + } + } + DeltaUSecL = DDel / (double)Elements; + } + + icnt = ICNT; + + if (JHFlag) + { + MalFlag = JudyMalHS; + LowIndex = ~0UL; + for (DDel = 1e40, lp = 0; lp < Loops; lp++) + { + STARTTm; + for (Seed1 = Seed, elm = 0; elm < Elements; elm++) + { + Seed1 = GetNextIndex(Seed1); + + if (DFlag) + TstIndex = Swizzle(Seed1); + else + TstIndex = Seed1; + + if (TstIndex < LowIndex) + LowIndex = TstIndex; + + JHSI(PValue, *JH, &TstIndex, sizeof(Word_t)); + if (PValue == (Word_t *)NULL) + FAILURE("JudyHSGet ret PValue = NULL", 0L); + if (*PValue != TstIndex) + FAILURE("JudyHSGet ret wrong Value at", elm); + } + ENDTm(DeltaUSecHS); + + if (DDel > DeltaUSecHS) + { + icnt = ICNT; + DDel = DeltaUSecHS; + } + else + { + if (--icnt == 0) + break; + } + } + DeltaUSecHS = DDel / (double)Elements; + } + return (LowIndex); +} + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyGet" + +Word_t +TestJudyGet(void *J1, void *JL, void *JH, Word_t Seed, Word_t Elements) +{ + Word_t LowIndex = ~0UL; + Word_t TstIndex; + Word_t elm; + Word_t *PValue; + Word_t Seed1; + int Rc; + + double DDel; + Word_t icnt; + Word_t lp; + Word_t Loops; + + Loops = (MAXLOOPS / Elements) + MINLOOPS; + + if (lFlag) + Loops = 1; + + if (J1Flag) + { + MalFlag = JudyMal1; + LowIndex = ~0UL; + for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++) + { + STARTTm; + for (Seed1 = Seed, elm = 0; elm < Elements; elm++) + { + Seed1 = GetNextIndex(Seed1); + + if (DFlag) + TstIndex = Swizzle(Seed1); + else + TstIndex = Seed1; + + if (TstIndex < LowIndex) + LowIndex = TstIndex; +#ifdef SKIPMACRO + Rc = Judy1Test(J1, TstIndex, PJE0); +#else + J1T(Rc, J1, TstIndex); +#endif // SKIPMACRO + if (Rc != 1) + { + printf + ("\nJudy1Test wrong Rc = %d, Index = 0x%lx, elm = %lu", + Rc, TstIndex, elm); + FAILURE("Judy1Test Rc != 1", Rc); + } + } + ENDTm(DeltaUSec1); + + if (DDel > DeltaUSec1) + { + icnt = ICNT; + DDel = DeltaUSec1; + } + else + { + if (--icnt == 0) + break; + } + } + DeltaUSec1 = DDel / (double)Elements; + } + + icnt = ICNT; + + if (JLFlag) + { + MalFlag = JudyMalL; + LowIndex = ~0UL; + for (DDel = 1e40, lp = 0; lp < Loops; lp++) + { + STARTTm; + for (Seed1 = Seed, elm = 0; elm < Elements; elm++) + { + Seed1 = GetNextIndex(Seed1); + + if (DFlag) + TstIndex = Swizzle(Seed1); + else + TstIndex = Seed1; + + if (TstIndex < LowIndex) + LowIndex = TstIndex; +#ifdef SKIPMACRO + PValue = (PWord_t)JudyLGet(JL, TstIndex, PJE0); +#else + JLG(PValue, JL, TstIndex); +#endif // SKIPMACRO + + if (PValue == (Word_t *)NULL) + { + printf("\nJudyGet Index = 0x%lx", TstIndex); + FAILURE("JudyLGet ret PValue = NULL", 0L); + } + if (*PValue != TstIndex) + { + printf("JudyLGet returned Value=0x%lx, should be=0x%lx\n", + *PValue, TstIndex); + FAILURE("JudyLGet ret wrong Value at", elm); + } + } + ENDTm(DeltaUSecL); + + if (DDel > DeltaUSecL) + { + icnt = ICNT; + DDel = DeltaUSecL; + } + + { + if (--icnt == 0) + break; + } + } + DeltaUSecL = DDel / (double)Elements; + } + + icnt = ICNT; + + if (JHFlag) + { + MalFlag = JudyMalHS; + LowIndex = ~0UL; + for (DDel = 1e40, lp = 0; lp < Loops; lp++) + { + STARTTm; + for (Seed1 = Seed, elm = 0; elm < Elements; elm++) + { + Seed1 = GetNextIndex(Seed1); + + if (DFlag) + TstIndex = Swizzle(Seed1); + else + TstIndex = Seed1; + + if (TstIndex < LowIndex) + LowIndex = TstIndex; + + JHSG(PValue, JH, &TstIndex, sizeof(Word_t)); + if (PValue == (Word_t *)NULL) + FAILURE("JudyHSGet ret PValue = NULL", 0L); + if (*PValue != TstIndex) + FAILURE("JudyHSGet ret wrong Value at", elm); + } + ENDTm(DeltaUSecHS); + + if (DDel > DeltaUSecHS) + { + icnt = ICNT; + DDel = DeltaUSecHS; + } + else + { + if (--icnt == 0) + break; + } + } + DeltaUSecHS = DDel / (double)Elements; + } + return (LowIndex); +} + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudy1Copy" + +int +TestJudy1Copy(void *J1, Word_t Elements) +{ + Pvoid_t J1a; // Judy1 new array + Word_t elm = 0; + Word_t Bytes; + + double DDel; + Word_t icnt; + Word_t lp; + Word_t Loops; + + Loops = (MAXLOOPS / Elements) + MINLOOPS; + if (lFlag) + Loops = 1; + + MalFlag = JudyMal1; + for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++) + { + Word_t NextIndex; + int Rc; + + STARTTm; + J1a = NULL; // Initialize To array + + NextIndex = 0; // Start at the beginning + elm = 0; + +#ifdef SKIPMACRO + Rc = Judy1First(J1, &NextIndex, PJE0); + while (Rc == 1) + { + if (elm++ == Elements) break; + + Rc = Judy1Set(&J1a, NextIndex, PJE0); + if (Rc != 1) + FAILURE("Judy1Set at", elm); + Rc = Judy1Next(J1, &NextIndex, PJE0); + } +#else + J1F(Rc, J1, NextIndex); // return first Index + while (Rc == 1) + { + if (elm++ == Elements) break; + + J1S(Rc, J1a, NextIndex); + if (Rc != 1) + FAILURE("J1S at", elm); + J1N(Rc, J1, NextIndex); + } +#endif // SKIPMACRO + + ENDTm(DeltaUSec1); + +#ifdef SKIPMACRO + Bytes = Judy1FreeArray(&J1a, PJE0); +#else + J1FA(Bytes, J1a); // no need to keep it around +#endif // SKIPMACRO + if (DDel > DeltaUSec1) + { + icnt = ICNT; + DDel = DeltaUSec1; + } + else + { + if (--icnt == 0) + break; + } + } + DeltaUSec1 = DDel / (double)elm; + + return (0); +} + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyCount" + +int +TestJudyCount(void *J1, void *JL, Word_t LowIndex, Word_t Elements) +{ + Word_t elm; + Word_t Count1, CountL; + Word_t TstIndex = LowIndex; + int Rc; + + double DDel; + Word_t icnt; + Word_t lp; + Word_t Loops; + + Loops = (MAXLOOPS / Elements) + MINLOOPS; + if (lFlag) + Loops = 1; + + if (J1Flag) + { + MalFlag = JudyMal1; + for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++) + { + TstIndex = LowIndex; + STARTTm; + for (elm = 0; elm < Elements; elm++) + { +#ifdef SKIPMACRO + Count1 = Judy1Count(J1, LowIndex, TstIndex, PJE0); +#else + J1C(Count1, J1, LowIndex, TstIndex); +#endif // SKIPMACRO + + if (Count1 != (elm + 1)) + { + printf("Count1 = %lu, elm +1 = %lu\n", Count1, elm + 1); + FAILURE("J1C at", elm); + } +#ifdef SKIPMACRO + Rc = Judy1Next(J1, &TstIndex, PJE0); +#else + J1N(Rc, J1, TstIndex); +#endif // SKIPMACRO + + } + ENDTm(DeltaUSec1); + + if (DDel > DeltaUSec1) + { + icnt = ICNT; + DDel = DeltaUSec1; + } + else + { + if (--icnt == 0) + break; + } + } + DeltaUSec1 = DDel / (double)Elements; + } + + if (JLFlag) + { + MalFlag = JudyMalL; + for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++) + { + TstIndex = LowIndex; + STARTTm; + for (elm = 0; elm < Elements; elm++) + { + PWord_t PValue; +#ifdef SKIPMACRO + CountL = JudyLCount(JL, LowIndex, TstIndex, PJE0); +#else + JLC(CountL, JL, LowIndex, TstIndex); +#endif // SKIPMACRO + if (CountL != (elm + 1)) + { + printf("CountL = %lu, elm +1 = %lu\n", CountL, elm + 1); + FAILURE("JLC at", elm); + } +#ifdef SKIPMACRO + PValue = (PWord_t)JudyLNext(JL, &TstIndex, PJE0); +#else + JLN(PValue, JL, TstIndex); +#endif // SKIPMACRO + } + ENDTm(DeltaUSecL); + + if (DDel > DeltaUSecL) + { + icnt = ICNT; + DDel = DeltaUSecL; + } + else + { + if (--icnt == 0) + break; + } + } + DeltaUSecL = DDel / (double)Elements; + } + + return (0); +} + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyNext" + +Word_t +TestJudyNext(void *J1, void *JL, Word_t LowIndex, Word_t Elements) +{ + Word_t elm; + + double DDel; + Word_t icnt; + Word_t lp; + Word_t Loops; + Word_t JLindex; + Word_t J1index; + + Loops = (MAXLOOPS / Elements) + MINLOOPS; + if (lFlag) + Loops = 1; + + if (J1Flag) + { + MalFlag = JudyMal1; + for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++) + { + int Rc; + + J1index = LowIndex; + + STARTTm; +#ifdef SKIPMACRO + Rc = Judy1First(J1, &J1index, PJE0); +#else + J1F(Rc, J1, J1index); +#endif // SKIPMACRO + for (elm = 0; elm < Elements; elm++) + { + if (Rc != 1) + { + printf("\nElements = %lu, elm = %lu\n", Elements, elm); + FAILURE("Judy1Next Rc != 1 =", Rc); + } +#ifdef SKIPMACRO + Rc = Judy1Next(J1, &J1index, PJE0); +#else + J1N(Rc, J1, J1index); // Get next one +#endif // SKIPMACRO + } + ENDTm(DeltaUSec1); + + if ((TValues == 0) && (Rc != 0)) + { + FAILURE("Judy1Next Rc != 0", Rc); + } + + if (DDel > DeltaUSec1) + { + icnt = ICNT; + DDel = DeltaUSec1; + } + else + { + if (--icnt == 0) + break; + } + } + DeltaUSec1 = DDel / (double)Elements; + } + + if (JLFlag) + { + MalFlag = JudyMalL; + for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++) + { + Word_t *PValue; + +// Get an Index low enough for Elements + JLindex = LowIndex; + + STARTTm; + JLF(PValue, JL, JLindex); + + for (elm = 0; elm < Elements; elm++) + { + Word_t Prev; + if (PValue == NULL) + { + printf("\nElements = %lu, elm = %lu\n", Elements, elm); + FAILURE("JudyLNext ret NULL PValue at", elm); + } + if (*PValue != JLindex) + { + printf("\n*PValue=0x%lx, JLindex=0x%lx\n", *PValue, + JLindex); + FAILURE("JudyLNext ret bad *PValue at", elm); + } + Prev = JLindex; +#ifdef SKIPMACRO + PValue = (PWord_t)JudyLNext(JL, &JLindex, PJE0); +#else + JLN(PValue, JL, JLindex); // Get next one +#endif // SKIPMACRO + if (JLindex == Prev) + { + printf("OOPs, JLN did not advance 0x%lx\n", Prev); + FAILURE("JudyLNext ret did not advance", Prev); + } + } + ENDTm(DeltaUSecL); + + if ((TValues == 0) && (PValue != NULL)) + { + FAILURE("JudyLNext PValue != NULL", PValue); + } + + if (DDel > DeltaUSecL) + { + icnt = ICNT; + DDel = DeltaUSecL; + } + else + { + if (--icnt == 0) + break; + } + } + DeltaUSecL = DDel / (double)Elements; + } + +// perhaps a check should be done here -- if I knew what to expect. + if (JLFlag) + return (JLindex); + if (J1Flag) + return (J1index); + return (-1); +} + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyPrev" + +int +TestJudyPrev(void *J1, void *JL, Word_t HighIndex, Word_t Elements) +{ + Word_t elm; + + double DDel; + Word_t icnt; + Word_t lp; + Word_t Loops; + Word_t J1index; + Word_t JLindex; + + Loops = (MAXLOOPS / Elements) + MINLOOPS; + if (lFlag) + Loops = 1; + + if (J1Flag) + { + MalFlag = JudyMal1; + for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++) + { + J1index = HighIndex; + int Rc; + + STARTTm; +#ifdef SKIPMACRO + Rc = Judy1Last(J1, &J1index, PJE0); +#else + J1L(Rc, J1, J1index); +#endif // SKIPMACRO + + for (elm = 0; elm < Elements; elm++) + { + if (Rc != 1) + FAILURE("Judy1Prev Rc != 1, is: ", Rc); +#ifdef SKIPMACRO + Rc = Judy1Prev(J1, &J1index, PJE0); +#else + J1P(Rc, J1, J1index); // Get previous one +#endif // SKIPMACRO + + } + ENDTm(DeltaUSec1); + + if ((TValues == 0) && (Rc != 0)) + { + FAILURE("Judy1Prev Rc != 0", Rc); + } + + if (DDel > DeltaUSec1) + { + icnt = ICNT; + DDel = DeltaUSec1; + } + else + { + if (--icnt == 0) + break; + } + } + DeltaUSec1 = DDel / (double)Elements; + } + + if (JLFlag) + { + MalFlag = JudyMalL; + for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++) + { + Word_t *PValue; + JLindex = HighIndex; + + STARTTm; + JLL(PValue, JL, JLindex); + + for (elm = 0; elm < Elements; elm++) + { + if (PValue == NULL) + { + printf("\nElements = %lu, elm = %lu\n", Elements, elm); + FAILURE("JudyLPrev ret NULL PValue at", elm); + } + if (*PValue != JLindex) + FAILURE("JudyLPrev ret bad *PValue at", elm); + + JLP(PValue, JL, JLindex); // Get previous one + } + ENDTm(DeltaUSecL); + + if ((TValues == 0) && (PValue != NULL)) + FAILURE("JudyLPrev PValue != NULL", PValue); + + if (DDel > DeltaUSecL) + { + icnt = ICNT; + DDel = DeltaUSecL; + } + else + { + if (--icnt == 0) + break; + } + } + DeltaUSecL = DDel / (double)Elements; + } + +// perhaps a check should be done here -- if I knew what to expect. + return (0); +} + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyNextEmpty" + +// Returns number of consecutive Indexes +Word_t +TestJudyNextEmpty(void *J1, void *JL, Word_t LowIndex, Word_t Elements) +{ + Word_t elm; + + double DDel; + Word_t icnt; + Word_t lp; + Word_t Loops; + int Rc; // Return code + + Loops = (MAXLOOPS / Elements) + MINLOOPS; + if (lFlag) + Loops = 1; + + if (J1Flag) + { + MalFlag = JudyMal1; + for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++) + { + Word_t Seed1 = LowIndex; + + STARTTm; + for (elm = 0; elm < Elements; elm++) + { + Word_t J1index; + J1index = Seed1; + +#ifdef SKIPMACRO + Rc = Judy1NextEmpty(J1, &J1index, PJE0); +#else + J1NE(Rc, J1, J1index); +#endif // SKIPMACRO + + if (Rc != 1) + FAILURE("Judy1NextEmpty Rcode != 1 =", Rc); + + Seed1 = GetNextIndex(Seed1); + } + ENDTm(DeltaUSec1); + + if (DDel > DeltaUSec1) + { + icnt = ICNT; + DDel = DeltaUSec1; + } + else + { + if (--icnt == 0) + break; + } + } + DeltaUSec1 = DDel / (double)Elements; + } + + if (JLFlag) + { + MalFlag = JudyMalL; + for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++) + { + Word_t Seed1 = LowIndex; + + STARTTm; + for (elm = 0; elm < Elements; elm++) + { + Word_t JLindex; + JLindex = Seed1; +#ifdef SKIPMACRO + Rc = JudyLNextEmpty(JL, &JLindex, PJE0); +#else + JLNE(Rc, JL, JLindex); +#endif // SKIPMACRO + if (Rc != 1) + FAILURE("JudyLNextEmpty Rcode != 1 =", Rc); + + Seed1 = GetNextIndex(Seed1); + } + ENDTm(DeltaUSecL); + + if (DDel > DeltaUSecL) + { + icnt = ICNT; + DDel = DeltaUSecL; + } + else + { + if (--icnt == 0) + break; + } + } + DeltaUSecL = DDel / (double)Elements; + } + + return (0); +} + +// Routine to time and test JudyPrevEmpty routines + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyPrevEmpty" + +Word_t +TestJudyPrevEmpty(void *J1, void *JL, Word_t HighIndex, Word_t Elements) +{ + Word_t elm; + + double DDel; + Word_t icnt; + Word_t lp; + Word_t Loops; + int Rc; + + Loops = (MAXLOOPS / Elements) + MINLOOPS; + if (lFlag) + Loops = 1; + + if (J1Flag) + { + MalFlag = JudyMal1; + for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++) + { + Word_t Seed1 = HighIndex; + + STARTTm; + for (elm = 0; elm < Elements; elm++) + { + Word_t J1index; + J1index = Seed1; + +#ifdef SKIPMACRO + Rc = Judy1PrevEmpty(J1, &J1index, PJE0); +#else + J1PE(Rc, J1, J1index); +#endif // SKIPMACRO + + if (Rc != 1) + FAILURE("Judy1PrevEmpty Rc != 1 =", Rc); + + Seed1 = GetNextIndex(Seed1); + } + ENDTm(DeltaUSec1); + + if (DDel > DeltaUSec1) + { + icnt = ICNT; + DDel = DeltaUSec1; + } + else + { + if (--icnt == 0) + break; + } + } + DeltaUSec1 = DDel / (double)Elements; + } + + if (JLFlag) + { + MalFlag = JudyMalL; + for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++) + { + Word_t Seed1 = HighIndex; + + STARTTm; + for (elm = 0; elm < Elements; elm++) + { + Word_t JLindex; + JLindex = Seed1; + + JLPE(Rc, JL, JLindex); // Rc = JudyLPrevEmpty(JL, &JLindex,PJE0) + + if (Rc != 1) + FAILURE("JudyLPrevEmpty Rcode != 1 =", Rc); + + Seed1 = GetNextIndex(Seed1); + } + ENDTm(DeltaUSecL); + + if (DDel > DeltaUSecL) + { + icnt = ICNT; + DDel = DeltaUSecL; + } + else + { + if (--icnt == 0) + break; + } + } + DeltaUSecL = DDel / (double)Elements; + } + + return (0); +} + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyDel" + +int +TestJudyDel(void **J1, void **JL, void **JH, Word_t Seed, Word_t Elements) +{ + Word_t TstIndex; + Word_t elm; + Word_t Seed1; + int Rc; + + if (J1Flag) + { + MalFlag = JudyMal1; + STARTTm; + for (Seed1 = Seed, elm = 0; elm < Elements; elm++) + { + Seed1 = GetNextIndex(Seed1); + + if (DFlag) + TstIndex = Swizzle(Seed1); + else + TstIndex = Seed1; + +#ifdef SKIPMACRO + Rc = Judy1Unset(J1, TstIndex, PJE0); +#else + J1U(Rc, *J1, TstIndex); +#endif // SKIPMACRO + if (Rc != 1) + FAILURE("Judy1Unset ret Rcode != 1", Rc); + } + ENDTm(DeltaUSec1); + DeltaUSec1 /= Elements; + } + + if (JLFlag) + { + MalFlag = JudyMalL; + STARTTm; + for (Seed1 = Seed, elm = 0; elm < Elements; elm++) + { + Seed1 = GetNextIndex(Seed1); + + if (DFlag) + TstIndex = Swizzle(Seed1); + else + TstIndex = Seed1; + +#ifdef SKIPMACRO + Rc = JudyLDel(JL, TstIndex, PJE0); +#else + JLD(Rc, *JL, TstIndex); +#endif // SKIPMACRO + if (Rc != 1) + FAILURE("JudyLDel ret Rcode != 1", Rc); + } + ENDTm(DeltaUSecL); + DeltaUSecL /= Elements; + } + + if (JHFlag) + { + MalFlag = JudyMalHS; + STARTTm; + for (Seed1 = Seed, elm = 0; elm < Elements; elm++) + { + Seed1 = GetNextIndex(Seed1); + + if (DFlag) + TstIndex = Swizzle(Seed1); + else + TstIndex = Seed1; + + JHSD(Rc, *JH, &TstIndex, sizeof(Word_t)); + if (Rc != 1) + FAILURE("JudyHSDel ret Rcode != 1", Rc); + } + ENDTm(DeltaUSecHS); + DeltaUSecHS /= Elements; + } + return (0); +} + +// Routine to get next size of Indexes +int // return 1 if last number +NextNumb(Word_t *PNumber, // pointer to returned next number + double *PDNumb, // Temp double of above + double DMult, // Multiplier + Word_t MaxNumb) // Max number to return +{ +// Save prev number + double PrevPDNumb = *PDNumb; + double DDiff; + +// Calc next number >= 1.0 beyond previous + do + { + *PDNumb *= DMult; + DDiff = *PDNumb - PrevPDNumb; + + } while (DDiff < 0.5); + +// Return it in integer format + if (DDiff < 100.0) + *PNumber += (Word_t)(DDiff + 0.5); + else + *PNumber = *PDNumb + 0.5; + +// Verify it did not exceed max number + if (*PNumber >= MaxNumb) + { +// it did, so return max + *PNumber = MaxNumb; + return (1); // flag it + } + return (0); // more available +} diff --git a/feeds/p4/libjudy/src/test/Judy1LTime.c b/feeds/p4/libjudy/src/test/Judy1LTime.c new file mode 100644 index 000000000..b85b1990e --- /dev/null +++ b/feeds/p4/libjudy/src/test/Judy1LTime.c @@ -0,0 +1,1620 @@ +// @(#) $Revision: 4.20 $ $Source: /judy/test/manual/Judy1LTime.c $ +//======================================================================= +// This program measures the performance of a Judy1 and JudyL Array. +// -by- +// Douglas L. Baskins (8/2001) doug@sourcejudy.com +//======================================================================= + +#include // sbrk() +#include // exit() +#include // printf() +#include // pow() +#include // gettimeofday() +#include // for Judy macros J*() + +#ifdef NOINLINE /* this is the 21st century? */ +#define _INLINE_ static +#else +#define _INLINE_ inline +#endif + + +//======================================================================= +// C O M P I L E D: +//======================================================================= +// +// cc -static -O3 Judy1LTime.c -lJudy -lm +// +// the -static is for a little better performace on some platforms +// +// if optional high-resolution timers are desired: +// +// cc -static -O3 -DJU_LINUX_IA32 Judy1LTime.c -lJudy -lm +// +// and read below: +// +//======================================================================= +// T I M I N G M A C R O S +//======================================================================= +// if your machine is one of the supported types in the following header +// file then uncomment this corresponding to what the header file says. +// This will give very high timing resolution. +// +// #define JU_xxxxxxx 1 // read timeit.h +// #define JU_LINUX_IA32 1 // I.E. IA32 Linux +// +#include "timeit.h" // optional for high resolution times + +double DeltaUSec; // Global for remembering delta times + +#ifndef _TIMEIT_H + +// Note: I have found some Linux systems (2.4.18-6mdk) have bugs in the +// gettimeofday() routine. Sometimes the difference of two consective calls +// returns a negative ~2840 microseconds instead of 0 or 1. If you use the +// above #include "timeit.h" and compile with timeit.c and use +// -DJU_LINUX_IA32, that problem will be eliminated. This is because for +// delta times less than .1 sec, the hardware free running timer is used +// instead of gettimeofday(). I have found the negative time problem +// appears about 40-50 times per second with numerous gettimeofday() calls. +// You should just ignore negative times output. + +#define TIMER_vars(T) struct timeval __TVBeg_##T, __TVEnd_##T + +#define STARTTm(T) gettimeofday(&__TVBeg_##T, NULL) + +#define ENDTm(D,T) \ +{ \ + gettimeofday(&__TVEnd_##T, NULL); \ + (D) = (double)(__TVEnd_##T.tv_sec - __TVBeg_##T.tv_sec) * 1E6 + \ + ((double)(__TVEnd_##T.tv_usec - __TVBeg_##T.tv_usec)); \ +} + +#endif // _TIMEIT_H + +//======================================================================= +// M E M O R Y S I Z E M A C R O S +//======================================================================= +// Most mallocs have mallinfo() +// However, the size is an int, so just about worthless in 64 bit +// machines with more than 4Gb ram. But needed on 32 bit machines +// that have more than a 1Gbyte of memory, because malloc stops +// using sbrk() about at that time (runs out of heap -- use mmap()). + +// un-define this if your malloc has mallinfo(); see above + +#define NOMALLINFO 1 + +double DeltaMem; + +#ifndef NOMALLINFO + +#include // mallinfo() + +struct mallinfo malStart; + +#define STARTmem malStart = mallinfo() /* works with some mallocs */ +#define ENDmem \ +{ \ + struct mallinfo malEnd = mallinfo(); \ +/* strange little dance from signed to unsigned to double */ \ + unsigned int _un_int = malEnd.arena - malStart.arena; \ + DeltaMem = _un_int; /* to double */ \ +} + +#else // MALLINFO + +// this usually works for machines with less than 1-2Gb RAM. +// (it does not include memory ACQUIRED by mmap()) + +char *malStart; + +#define STARTmem (malStart = (char *)sbrk(0)) +#define ENDmem \ +{ \ + char *malEnd = (char *)sbrk(0); \ + DeltaMem = malEnd - malStart; \ +} + +#endif // MALLINFO + +//======================================================================= + +// Common macro to handle a failure +#define FAILURE(STR, UL) \ +{ \ +printf( "Error: %s %lu, file='%s', 'function='%s', line %d\n", \ + STR, UL, __FILE__, __FUNCTI0N__, __LINE__); \ +fprintf(stderr, "Error: %s %lu, file='%s', 'function='%s', line %d\n", \ + STR, UL, __FILE__, __FUNCTI0N__, __LINE__); \ + exit(1); \ +} + +// Interations without improvement +// Minimum of 2 loops, maximum of 1000000 +#define MINLOOPS 2 +#define MAXLOOPS 1000000 + +// Maximum or 10 loops with no improvement +#define ICNT 10 + +// Structure to keep track of times +typedef struct MEASUREMENTS_STRUCT +{ + Word_t ms_delta; +} +ms_t , *Pms_t; + +// Specify prototypes for each test routine +int NextNumb(Word_t *PNumber, double *PDNumb, double DMult, + Word_t MaxN); + +Word_t TestJudyIns(void **J1, void **JL, Word_t Seed, Word_t Elems); + +Word_t TestJudyDup(void **J1, void **JL, Word_t Seed, Word_t Elems); + +int TestJudyDel(void **J1, void **JL, Word_t Seed, Word_t Elems); + +Word_t TestJudyGet(void *J1, void *JL, Word_t Seed, Word_t Elems); + +int TestJudyCount(void *J1, void *JL, Word_t LowIndex, Word_t Elems); + +Word_t TestJudyNext(void *J1, void *JL, Word_t LowIndex, Word_t Elems); + +int TestJudyPrev(void *J1, void *JL, Word_t HighIndex, Word_t Elems); + +Word_t TestJudyNextEmpty(void *J1, void *JL, Word_t LowIndex, + Word_t Elems); + +Word_t TestJudyPrevEmpty(void *J1, void *JL, Word_t HighIndex, + Word_t Elems); + +//======================================================================= +// These are LFSF feedback taps for bitwidths of 10..64 sized numbers. +// Tested with Seed=0xc1fc to 35 billion numbers +//======================================================================= + +Word_t StartSeed = 0xc1fc; // default beginning number +Word_t FirstSeed; + +Word_t MagicList[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0..9 + 0x27f, // 10 + 0x27f, // 11 + 0x27f, // 12 + 0x27f, // 13 + 0x27f, // 14 + 0x27f, // 15 + 0x1e71, // 16 + 0xdc0b, // 17 + 0xdc0b, // 18 + 0xdc0b, // 19 + 0xdc0b, // 20 + 0xc4fb, // 21 + 0xc4fb, // 22 + 0xc4fb, // 23 + 0x13aab, // 24 + 0x11ca3, // 25 + 0x11ca3, // 26 + 0x11ca3, // 27 + 0x13aab, // 28 + 0x11ca3, // 29 + 0xc4fb, // 30 + 0xc4fb, // 31 + 0x13aab, // 32 + 0x14e73, // 33 + 0x145d7, // 34 + 0x145f9, // 35 following tested with Seed=0xc1fc to 35 billion numbers + 0x151ed, // 36 .. 41 + 0x151ed, // 37 + 0x151ed, // 38 + 0x151ed, // 39 + 0x151ed, // 40 + 0x146c3, // 41 .. 64 + 0x146c3, // 42 + 0x146c3, // 43 + 0x146c3, // 44 + 0x146c3, // 45 + 0x146c3, // 46 + 0x146c3, // 47 + 0x146c3, // 48 + 0x146c3, // 49 + 0x146c3, // 50 + 0x146c3, // 51 + 0x146c3, // 52 + 0x146c3, // 53 + 0x146c3, // 54 + 0x146c3, // 55 + 0x146c3, // 56 + 0x146c3, // 57 + 0x146c3, // 58 + 0x146c3, // 59 + 0x146c3, // 60 + 0x146c3, // 61 + 0x146c3, // 62 + 0x146c3, // 63 + 0x146c3 // 64 +}; + +// Routine to "mirror" the input data word +static Word_t +Swizzle(Word_t word) +{ +// BIT REVERSAL, Ron Gutman in Dr. Dobb's Journal, #316, Sept 2000, pp133-136 +// + +#ifdef __LP64__ + word = ((word & 0x00000000ffffffff) << 32) | + ((word & 0xffffffff00000000) >> 32); + word = ((word & 0x0000ffff0000ffff) << 16) | + ((word & 0xffff0000ffff0000) >> 16); + word = ((word & 0x00ff00ff00ff00ff) << 8) | + ((word & 0xff00ff00ff00ff00) >> 8); + word = ((word & 0x0f0f0f0f0f0f0f0f) << 4) | + ((word & 0xf0f0f0f0f0f0f0f0) >> 4); + word = ((word & 0x3333333333333333) << 2) | + ((word & 0xcccccccccccccccc) >> 2); + word = ((word & 0x5555555555555555) << 1) | + ((word & 0xaaaaaaaaaaaaaaaa) >> 1); +#else // not __LP64__ + word = ((word & 0x0000ffff) << 16) | ((word & 0xffff0000) >> 16); + word = ((word & 0x00ff00ff) << 8) | ((word & 0xff00ff00) >> 8); + word = ((word & 0x0f0f0f0f) << 4) | ((word & 0xf0f0f0f0) >> 4); + word = ((word & 0x33333333) << 2) | ((word & 0xcccccccc) >> 2); + word = ((word & 0x55555555) << 1) | ((word & 0xaaaaaaaa) >> 1); +#endif // not __LP64__ + + return (word); +} + +double DeltaUSec1 = 0.0; // Global for measuring delta times +double DeltaUSecL = 0.0; // Global for measuring delta times + +Word_t J1Flag = 0; // time Judy1 +Word_t JLFlag = 0; // time JudyL +Word_t dFlag = 0; // time Judy1Unset JudyLDel +Word_t vFlag = 0; // time Searching +Word_t CFlag = 0; // time Counting +Word_t IFlag = 0; // time duplicate inserts/sets +Word_t DFlag = 0; // bit reverse the data stream +Word_t lFlag = 0; // do not do multi-insert tests +Word_t aFlag = 0; // output active memory in array +Word_t SkipN = 0; // default == Random skip +Word_t TValues = 100000; // Maximum retrieve tests for timing +Word_t nElms = 1000000; // Max population of arrays +Word_t ErrorFlag = 0; +Word_t PtsPdec = 40; // measurement points per decade + +// Stuff for LFSR (pseudo random number generator) +Word_t RandomBit = ~0UL / 2 + 1; +Word_t BValue = sizeof(Word_t) * 8; +Word_t Magic; + +// for error routines -- notice misspelling, name conflicts with some compilers +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "Random" + +_INLINE_ Word_t // so INLINING compilers get to look at it. +Random(Word_t newseed) +{ + if (newseed & RandomBit) + { + newseed += newseed; + newseed ^= Magic; + } + else + { + newseed += newseed; + } + newseed &= RandomBit * 2 - 1; + if (newseed == FirstSeed) + FAILURE("LFSR failed", newseed); + return (newseed); +} + +_INLINE_ Word_t // so INLINING compilers get to look at it. +GetNextIndex(Word_t Index) +{ + if (SkipN) + Index += SkipN; + else + Index = Random(Index); + + return (Index); +} + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "main" + +int +main(int argc, char *argv[]) +{ +// Names of Judy Arrays + void *J1 = NULL; // Judy1 + void *JL = NULL; // JudyL + + TIMER_vars(tm1); // declare timer variables + Word_t Count1, CountL; + Word_t Bytes; + + double Mult; + Pms_t Pms; + Word_t Seed; + Word_t PtsPdec = 40; // points per decade + Word_t Groups; // Number of measurement groups + Word_t grp; + Word_t Pop1; + Word_t Meas; + int Col; + + int c; + extern char *optarg; + +//============================================================ +// PARSE INPUT PARAMETERS +//============================================================ + + while ((c = getopt(argc, argv, "n:S:T:P:b:B:dDC1LvIla")) != -1) + { + switch (c) + { + case 'n': // Max population of arrays + nElms = strtoul(optarg, NULL, 0); // Size of Linear Array + if (nElms == 0) + FAILURE("No tests: -n", nElms); + +// Check if more than a trillion (64 bit only) + if ((double)nElms > 1e12) + FAILURE("Too many Indexes=", nElms); + break; + + case 'S': // Step Size, 0 == Random + SkipN = strtoul(optarg, NULL, 0); + break; + + case 'T': // Maximum retrieve tests for timing + TValues = strtoul(optarg, NULL, 0); + break; + + case 'P': // measurement points per decade + PtsPdec = strtoul(optarg, NULL, 0); + break; + + case 'b': // May not work past 35 bits if changed + StartSeed = strtoul(optarg, NULL, 0); + break; + + case 'B': // expanse of data points (random only) + BValue = strtoul(optarg, NULL, 0); + if ((BValue > 64) + || + (MagicList[BValue] == 0) || (BValue > (sizeof(Word_t) * 8))) + { + ErrorFlag++; + printf("\nIllegal number of random bits of %lu !!!\n", + BValue); + } + break; + + case 'v': + vFlag = 1; // time Searching + break; + + case '1': // time Judy1 + J1Flag = 1; + break; + + case 'L': // time JudyL + JLFlag = 1; + break; + + case 'd': // time Judy1Unset JudyLDel + dFlag = 1; + break; + + case 'D': // bit reverse the data stream + DFlag = 1; + break; + + case 'C': // time Counting + CFlag = 1; + break; + + case 'I': // time duplicate insert/set + IFlag = 1; + break; + + case 'l': // do not loop in tests + lFlag = 1; + break; + + case 'a': // output active memory in Judy array + aFlag = 1; + break; + + default: + ErrorFlag++; + break; + } + } + + if (ErrorFlag) + { + printf("\n%s -n# -P# -S# -B# -T# -b # -DCpdI\n\n", argv[0]); + printf("Where:\n"); + printf("-n <#> number of indexes used in tests\n"); + printf("-P <#> number measurement points per decade\n"); + printf("-S <#> index skip amount, 0 = random\n"); + printf("-B <#> # bits (10..%d) in random number generator\n", + (int)sizeof(Word_t) * 8); + printf("-L time JudyL\n"); + printf("-1 time Judy1\n"); + printf("-I time DUPLICATE Ins/Set times\n"); + printf("-C time JudyCount tests\n"); + printf("-v time Judy Search tests\n"); + printf("-d time JudyDel/Unset instead of JudyFreeArray\n"); + printf("-l do not loop on same Indexes\n"); + printf("-T <#> max number indexes in read times - 0 == MAX\n"); + printf("\n"); + + exit(1); + } + +// If none, then both + if (!JLFlag && !J1Flag) + JLFlag = J1Flag = 1; + +// Set number of Random bits in LFSR + RandomBit = 1UL << (BValue - 1); + Magic = MagicList[BValue]; + + if (nElms > ((RandomBit - 2) * 2)) + { + printf + ("# Number = -n%lu of Indexes reduced to max expanse of Random numbers\n", + nElms); + nElms = ((RandomBit - 2) * 2); + } + + printf("# TITLE %s -n%lu -S%lu -T%lu -B%lu -P%lu", + argv[0], nElms, SkipN, TValues, BValue, PtsPdec); + if (J1Flag) + printf(" -1"); + if (JLFlag) + printf(" -L"); + if (DFlag) + printf(" -D"); + if (dFlag) + printf(" -d"); + if (CFlag) + printf(" -C"); + if (IFlag) + printf(" -I"); + if (lFlag) + printf(" -l"); + if (aFlag) + printf(" -a"); + printf("\n"); + + if (sizeof(Word_t) == 8) + printf("#%s 64 Bit version\n", argv[0]); + else if (sizeof(Word_t) == 4) + printf("#%s 32 Bit version\n", argv[0]); + + printf("# XLABEL Population\n"); + printf("# YLABEL Microseconds / Index\n"); + +//============================================================ +// CALCULATE NUMBER OF MEASUREMENT GROUPS +//============================================================ + +// Calculate Multiplier for number of points per decade + Mult = pow(10.0, 1.0 / (double)PtsPdec); + { + double sum; + Word_t numb, prevnumb; + +// Count number of measurements needed (10K max) + sum = numb = 1; + for (Groups = 2; Groups < 10000; Groups++) + { + if (NextNumb(&numb, &sum, Mult, nElms)) break; + } + +// Get memory for measurements + Pms = (Pms_t) calloc(Groups, sizeof(ms_t)); + +// Now calculate number of Indexes for each measurement point + numb = sum = 1; + prevnumb = 0; + for (grp = 0; grp < Groups; grp++) + { + Pms[grp].ms_delta = numb - prevnumb; + prevnumb = numb; + + NextNumb(&numb, &sum, Mult, nElms); + } + } // Groups = number of sizes + +//============================================================ +// PRINT HEADER TO PERFORMANCE TIMERS +//============================================================ + + printf("# COLHEAD 1 Population\n"); + printf("# COLHEAD 2 Measurments\n"); + printf("# COLHEAD 3 J1S\n"); + printf("# COLHEAD 4 JLI\n"); + printf("# COLHEAD 5 J1T\n"); + printf("# COLHEAD 6 JLG\n"); + + Col = 7; + if (IFlag) + { + printf("# COLHEAD %d J1S-dup\n", Col++); + printf("# COLHEAD %d JLI-dup\n", Col++); + } + if (CFlag) + { + printf("# COLHEAD %d J1C\n", Col++); + printf("# COLHEAD %d JLC\n", Col++); + } + if (vFlag) + { + printf("# COLHEAD %d J1N\n", Col++); + printf("# COLHEAD %d JLN\n", Col++); + printf("# COLHEAD %d J1P\n", Col++); + printf("# COLHEAD %d JLP\n", Col++); + printf("# COLHEAD %d J1NE\n", Col++); + printf("# COLHEAD %d JLNE\n", Col++); + printf("# COLHEAD %d J1PE\n", Col++); + printf("# COLHEAD %d JLPE\n", Col++); + } + if (dFlag) + { + printf("# COLHEAD %d J1U\n", Col++); + printf("# COLHEAD %d JLD\n", Col++); + } + printf("# COLHEAD %d J1MU/I\n", Col++); + printf("# COLHEAD %d JLMU/I\n", Col++); + if (aFlag) + { + printf("# COLHEAD %d J1MA/I\n", Col++); + printf("# COLHEAD %d JLMA/I\n", Col++); + } + printf("# COLHEAD %d HEAP/I\n", Col++); + + printf("# %s\n", Judy1MallocSizes); + printf("# %s\n", JudyLMallocSizes); + + printf("# Pop1 Measmts J1S JLI J1T JLG"); + + if (IFlag) + printf(" dupJ1S dupJLI"); + + if (CFlag) + printf(" J1C JLC"); + + if (vFlag) + printf(" J1N JLN J1P JLP J1NE JLNE J1PE JLPE"); + + if (dFlag) + printf(" J1U JLD"); + + printf(" J1MU/I JLMU/I"); + if (aFlag) + { + printf(" J1MA/I JLMA/I"); + } + + printf(" HEAP/I"); + + printf("\n"); + +//============================================================ +// BEGIN TESTS AT EACH GROUP SIZE +//============================================================ + +// Get the kicker to test the LFSR + FirstSeed = Seed = StartSeed & (RandomBit * 2 - 1); + + STARTmem; + for (Pop1 = grp = 0; grp < Groups; grp++) + { + Word_t LowIndex, HighIndex; + Word_t Delta; + Word_t NewSeed; + + Delta = Pms[grp].ms_delta; + +// Test J1S, JLI + NewSeed = TestJudyIns(&J1, &JL, Seed, Delta); + +// Accumulate the Total population of arrays + Pop1 += Delta; + Meas = Pop1; + +// Only test the maximum of TValues if not zero + if (TValues) + Meas = (Pop1 < TValues) ? Pop1 : TValues; + + printf("%10lu %9lu", Pop1, Meas); + printf(" %6.3f", DeltaUSec1); + printf(" %6.3f", DeltaUSecL); + +// Test J1T, JLG + + LowIndex = TestJudyGet(J1, JL, FirstSeed, Meas); + printf(" %6.3f", DeltaUSec1); + printf(" %6.3f", DeltaUSecL); + +// Test J1T, JLI - duplicates + + if (IFlag) + { + LowIndex = TestJudyDup(&J1, &JL, FirstSeed, Meas); + printf(" %6.3f", DeltaUSec1); + printf(" %6.3f", DeltaUSecL); + } + if (CFlag) + { + TestJudyCount(J1, JL, LowIndex, Meas); + printf(" %6.3f", DeltaUSec1); + printf(" %6.3f", DeltaUSecL); + } + if (vFlag) + { +// Test J1N, JLN + HighIndex = TestJudyNext(J1, JL, LowIndex, Meas); + printf(" %6.3f", DeltaUSec1); + printf(" %6.3f", DeltaUSecL); + +// Test J1P, JLP + TestJudyPrev(J1, JL, HighIndex, Meas); + printf(" %6.3f", DeltaUSec1); + printf(" %6.3f", DeltaUSecL); + +// Test J1NE, JLNE + TestJudyNextEmpty(J1, JL, LowIndex, Meas); + printf(" %6.3f", DeltaUSec1); + printf(" %6.3f", DeltaUSecL); + +// Test J1PE, JLPE + TestJudyPrevEmpty(J1, JL, HighIndex, Meas); + printf(" %6.3f", DeltaUSec1); + printf(" %6.3f", DeltaUSecL); + } + +// Test J1U, JLD + if (dFlag) + { + TestJudyDel(&J1, &JL, FirstSeed, Meas); + printf(" %6.3f", DeltaUSec1); + printf(" %6.3f", DeltaUSecL); + +// Now put them back + TestJudyIns(&J1, &JL, FirstSeed, Meas); + } + +// Advance Index number set + Seed = NewSeed; + +// Print the number of bytes used per Index + printf(" %6.3f", (double)Judy1MemUsed(J1) / (double)Pop1); + printf(" %6.3f", (double)JudyLMemUsed(JL) / (double)Pop1); + if (aFlag) + { + printf(" %6.3f", (double)Judy1MemActive(J1) / (double)Pop1); + printf(" %6.3f", (double)JudyLMemActive(JL) / (double)Pop1); + } + + ENDmem; + printf(" %6.3f", DeltaMem / (double)Pop1); + printf("\n"); + fflush(NULL); // assure data gets to file in case malloc fail + } + + JLC(CountL, JL, 0, -1); // get the counts + J1C(Count1, J1, 0, -1); + + if (JLFlag && J1Flag) + { + if (CountL != Count1) + FAILURE("Judy1/LCount not equal", Count1); + } + + if (Count1) + { + STARTTm(tm1); + J1FA(Bytes, J1); // Free the Judy1 Array + ENDTm(DeltaUSec1, tm1); + DeltaUSec1 /= (double)Count1; + + printf("# Judy1FreeArray: %lu, %0.3f bytes/Index, %0.3f USec/Index\n", + Count1, (double)Bytes / (double)Count1, DeltaUSec1); + } + + if (CountL) + { + STARTTm(tm1); + JLFA(Bytes, JL); // Free the JudyL Array + ENDTm(DeltaUSecL, tm1); + DeltaUSecL /= (double)CountL; + + printf("# JudyLFreeArray: %lu, %0.3f bytes/Index, %0.3f USec/Index\n", + CountL, (double)Bytes / (double)CountL, DeltaUSecL); + } + exit(0); +} + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyIns" + +Word_t +TestJudyIns(void **J1, void **JL, Word_t Seed, Word_t Elements) +{ + TIMER_vars(tm1); // declare timer variables + Word_t TstIndex; + Word_t elm; + Word_t *PValue; + Word_t Seed1 = 0; + int Rc; + + double DDel; + Word_t icnt; + Word_t lp; + Word_t Loops; + + if (Elements < 100) + Loops = (MAXLOOPS / Elements) + MINLOOPS; + else + Loops = 1; + + if (lFlag) + Loops = 1; + +// Judy1Set timings + + if (J1Flag) + { + for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++) + { + if (lp != 0) + { + for (Seed1 = Seed, elm = 0; elm < Elements; elm++) + { + Seed1 = GetNextIndex(Seed1); + + if (DFlag) + TstIndex = Swizzle(Seed1); + else + TstIndex = Seed1; + + J1U(Rc, *J1, TstIndex); + } + } + + STARTTm(tm1); + for (Seed1 = Seed, elm = 0; elm < Elements; elm++) + { + Seed1 = GetNextIndex(Seed1); + + if (DFlag) + TstIndex = Swizzle(Seed1); + else + TstIndex = Seed1; + + J1S(Rc, *J1, TstIndex); + if (Rc == 0) + FAILURE("Judy1Set failed - DUP Index at", elm); + } + ENDTm(DeltaUSec1, tm1); + + if (DDel > DeltaUSec1) + { + icnt = ICNT; + DDel = DeltaUSec1; + } + else + { + if (--icnt == 0) + break; + } + } + DeltaUSec1 = DDel / (double)Elements; + } + +// JudyLIns timings + + if (JLFlag) + { + for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++) + { + if (lp != 0) + { + for (Seed1 = Seed, elm = 0; elm < Elements; elm++) + { + Seed1 = GetNextIndex(Seed1); + + if (DFlag) + TstIndex = Swizzle(Seed1); + else + TstIndex = Seed1; + + JLD(Rc, *JL, TstIndex); + } + } + + STARTTm(tm1); + for (Seed1 = Seed, elm = 0; elm < Elements; elm++) + { + Seed1 = GetNextIndex(Seed1); + + if (DFlag) + TstIndex = Swizzle(Seed1); + else + TstIndex = Seed1; + + JLI(PValue, *JL, TstIndex); + if (*PValue == TstIndex) + FAILURE("JudyLIns failed - DUP Index", TstIndex); + + *PValue = TstIndex; // save Index in Value + } + ENDTm(DeltaUSecL, tm1); + DeltaUSecL /= Elements; + + if (DDel > DeltaUSecL) + { + icnt = ICNT; + DDel = DeltaUSecL; + } + else + { + if (--icnt == 0) + break; + } + } + } + return (Seed1); // New seed +} + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyDup" + +Word_t +TestJudyDup(void **J1, void **JL, Word_t Seed, Word_t Elements) +{ + TIMER_vars(tm1); // declare timer variables + Word_t LowIndex = ~0UL; + Word_t TstIndex; + Word_t elm; + Word_t *PValue; + Word_t Seed1; + int Rc; + + double DDel; + Word_t icnt; + Word_t lp; + Word_t Loops; + + Loops = (MAXLOOPS / Elements) + MINLOOPS; + + if (J1Flag) + { + LowIndex = ~0UL; + for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++) + { + STARTTm(tm1); + for (Seed1 = Seed, elm = 0; elm < Elements; elm++) + { + Seed1 = GetNextIndex(Seed1); + + if (DFlag) + TstIndex = Swizzle(Seed1); + else + TstIndex = Seed1; + + if (TstIndex < LowIndex) + LowIndex = TstIndex; + + J1S(Rc, *J1, TstIndex); + if (Rc != 0) + FAILURE("Judy1Test Rc != 0", (Word_t)Rc); + } + ENDTm(DeltaUSec1, tm1); + + if (DDel > DeltaUSec1) + { + icnt = ICNT; + DDel = DeltaUSec1; + } + else + { + if (--icnt == 0) + break; + } + } + DeltaUSec1 = DDel / (double)Elements; + } + + icnt = ICNT; + + if (JLFlag) + { + LowIndex = ~0UL; + for (DDel = 1e40, lp = 0; lp < Loops; lp++) + { + STARTTm(tm1); + for (Seed1 = Seed, elm = 0; elm < Elements; elm++) + { + Seed1 = GetNextIndex(Seed1); + + if (DFlag) + TstIndex = Swizzle(Seed1); + else + TstIndex = Seed1; + + if (TstIndex < LowIndex) + LowIndex = TstIndex; + + JLI(PValue, *JL, TstIndex); + if (PValue == (Word_t *)NULL) + FAILURE("JudyLGet ret PValue = NULL", 0L); + if (*PValue != TstIndex) + FAILURE("JudyLGet ret wrong Value at", elm); + } + ENDTm(DeltaUSecL, tm1); + + if (DDel > DeltaUSecL) + { + icnt = ICNT; + DDel = DeltaUSecL; + } + else + { + if (--icnt == 0) + break; + } + } + DeltaUSecL = DDel / (double)Elements; + } + + return (LowIndex); +} + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyGet" + +Word_t +TestJudyGet(void *J1, void *JL, Word_t Seed, Word_t Elements) +{ + TIMER_vars(tm1); // declare timer variables + Word_t LowIndex = ~0UL; + Word_t TstIndex; + Word_t elm; + Word_t *PValue; + Word_t Seed1; + int Rc; + + double DDel; + Word_t icnt; + Word_t lp; + Word_t Loops; + + Loops = (MAXLOOPS / Elements) + MINLOOPS; + + if (J1Flag) + { + LowIndex = ~0UL; + for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++) + { + STARTTm(tm1); + for (Seed1 = Seed, elm = 0; elm < Elements; elm++) + { + Seed1 = GetNextIndex(Seed1); + + if (DFlag) + TstIndex = Swizzle(Seed1); + else + TstIndex = Seed1; + + if (TstIndex < LowIndex) + LowIndex = TstIndex; + + J1T(Rc, J1, TstIndex); + if (Rc != 1) + FAILURE("Judy1Test Rc != 1", (Word_t)Rc); + } + ENDTm(DeltaUSec1, tm1); + + if (DDel > DeltaUSec1) + { + icnt = ICNT; + DDel = DeltaUSec1; + } + else + { + if (--icnt == 0) + break; + } + } + DeltaUSec1 = DDel / (double)Elements; + } + + icnt = ICNT; + + if (JLFlag) + { + LowIndex = ~0UL; + for (DDel = 1e40, lp = 0; lp < Loops; lp++) + { + STARTTm(tm1); + for (Seed1 = Seed, elm = 0; elm < Elements; elm++) + { + Seed1 = GetNextIndex(Seed1); + + if (DFlag) + TstIndex = Swizzle(Seed1); + else + TstIndex = Seed1; + + if (TstIndex < LowIndex) + LowIndex = TstIndex; + + JLG(PValue, JL, TstIndex); + if (PValue == (Word_t *)NULL) + FAILURE("JudyLGet ret PValue = NULL", 0L); + if (*PValue != TstIndex) + FAILURE("JudyLGet ret wrong Value at", elm); + } + ENDTm(DeltaUSecL, tm1); + + if (DDel > DeltaUSecL) + { + icnt = ICNT; + DDel = DeltaUSecL; + } + else + { + if (--icnt == 0) + break; + } + } + DeltaUSecL = DDel / (double)Elements; + } + + return (LowIndex); +} + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyCount" + +int +TestJudyCount(void *J1, void *JL, Word_t LowIndex, Word_t Elements) +{ + TIMER_vars(tm1); // declare timer variables + Word_t elm; + Word_t Count1, CountL; + Word_t TstIndex = LowIndex; + int Rc; + + double DDel; + Word_t icnt; + Word_t lp; + Word_t Loops; + + Loops = (MAXLOOPS / Elements) + MINLOOPS; + + if (J1Flag) + { + for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++) + { + TstIndex = LowIndex; + STARTTm(tm1); + for (elm = 0; elm < Elements; elm++) + { + J1C(Count1, J1, LowIndex, TstIndex); + + if (Count1 != (elm + 1)) + FAILURE("J1C at", elm); + + J1N(Rc, J1, TstIndex); + } + ENDTm(DeltaUSec1, tm1); + + if (DDel > DeltaUSec1) + { + icnt = ICNT; + DDel = DeltaUSec1; + } + else + { + if (--icnt == 0) + break; + } + } + DeltaUSec1 = DDel / (double)Elements; + } + + if (JLFlag) + { + for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++) + { + TstIndex = LowIndex; + STARTTm(tm1); + for (elm = 0; elm < Elements; elm++) + { + Word_t *PValue; + + JLC(CountL, JL, LowIndex, TstIndex); + + if (CountL != (elm + 1)) + FAILURE("JLC at", elm); + + JLN(PValue, JL, TstIndex); + } + ENDTm(DeltaUSecL, tm1); + + if (DDel > DeltaUSecL) + { + icnt = ICNT; + DDel = DeltaUSecL; + } + else + { + if (--icnt == 0) + break; + } + } + DeltaUSecL = DDel / (double)Elements; + } + + return (0); +} + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyNext" + +Word_t +TestJudyNext(void *J1, void *JL, Word_t LowIndex, Word_t Elements) +{ + TIMER_vars(tm1); // declare timer variables + Word_t elm; + + double DDel; + Word_t icnt; + Word_t lp; + Word_t Loops; + Word_t Jindex; + + Loops = (MAXLOOPS / Elements) + MINLOOPS; + + if (J1Flag) + { + for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++) + { + int Rc; + Jindex = LowIndex; + + STARTTm(tm1); + J1F(Rc, J1, Jindex); + + for (elm = 0; elm < Elements; elm++) + { + if (Rc != 1) + FAILURE("Judy1Next Rc != 1 =", (Word_t)Rc); + + J1N(Rc, J1, Jindex); // Get next one + } + ENDTm(DeltaUSec1, tm1); + + if (DDel > DeltaUSec1) + { + icnt = ICNT; + DDel = DeltaUSec1; + } + else + { + if (--icnt == 0) + break; + } + } + DeltaUSec1 = DDel / (double)Elements; + } + + if (JLFlag) + { + for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++) + { + Word_t *PValue; + +// Get an Index low enough for Elements + Jindex = LowIndex; + + STARTTm(tm1); + JLF(PValue, JL, Jindex); + + for (elm = 0; elm < Elements; elm++) + { + if (PValue == NULL) + FAILURE("JudyLNext ret NULL PValue at", elm); + + JLN(PValue, JL, Jindex); // Get next one + } + ENDTm(DeltaUSecL, tm1); + + if (DDel > DeltaUSecL) + { + icnt = ICNT; + DDel = DeltaUSecL; + } + else + { + if (--icnt == 0) + break; + } + } + DeltaUSecL = DDel / (double)Elements; + } + +// perhaps a check should be done here -- if I knew what to expect. + return (Jindex); // return last one +} + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyPrev" + +int +TestJudyPrev(void *J1, void *JL, Word_t HighIndex, Word_t Elements) +{ + TIMER_vars(tm1); // declare timer variables + Word_t elm; + + double DDel; + Word_t icnt; + Word_t lp; + Word_t Loops; + + Loops = (MAXLOOPS / Elements) + MINLOOPS; + + if (J1Flag) + { + for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++) + { + Word_t J1index = HighIndex; + int Rc; + + STARTTm(tm1); + J1L(Rc, J1, J1index); + + for (elm = 0; elm < Elements; elm++) + { + if (Rc != 1) + FAILURE("Judy1Prev Rc != 1 =", (Word_t)Rc); + + J1P(Rc, J1, J1index); // Get previous one + } + ENDTm(DeltaUSec1, tm1); + + if (DDel > DeltaUSec1) + { + icnt = ICNT; + DDel = DeltaUSec1; + } + else + { + if (--icnt == 0) + break; + } + } + DeltaUSec1 = DDel / (double)Elements; + } + + if (JLFlag) + { + for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++) + { + Word_t *PValue; + Word_t JLindex = HighIndex; + + STARTTm(tm1); + JLL(PValue, JL, JLindex); + + for (elm = 0; elm < Elements; elm++) + { + if (PValue == NULL) + FAILURE("JudyLPrev ret NULL PValue at", elm); + + JLP(PValue, JL, JLindex); // Get previous one + } + ENDTm(DeltaUSecL, tm1); + + if (DDel > DeltaUSecL) + { + icnt = ICNT; + DDel = DeltaUSecL; + } + else + { + if (--icnt == 0) + break; + } + } + DeltaUSecL = DDel / (double)Elements; + } + +// perhaps a check should be done here -- if I knew what to expect. + return (0); +} + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyNextEmpty" + +// Returns number of consecutive Indexes +Word_t +TestJudyNextEmpty(void *J1, void *JL, Word_t LowIndex, Word_t Elements) +{ + TIMER_vars(tm1); // declare timer variables + Word_t elm; + + double DDel; + Word_t icnt; + Word_t lp; + Word_t Loops; + int Rc; // Return code + + Loops = (MAXLOOPS / Elements) + MINLOOPS; + + if (J1Flag) + { + for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++) + { + Word_t Seed1 = LowIndex; + + STARTTm(tm1); + for (elm = 0; elm < Elements; elm++) + { + Word_t J1index; + J1index = Seed1; + +// Find next Empty Index, J1index is modified by J1NE + J1NE(Rc, J1, J1index); // Rc = Judy1NextEmpty(J1, &J1index,PJE0) + + if (Rc != 1) + FAILURE("Judy1NextEmpty Rcode != 1 =", (Word_t)Rc); + + Seed1 = GetNextIndex(Seed1); + } + ENDTm(DeltaUSec1, tm1); + + if (DDel > DeltaUSec1) + { + icnt = ICNT; + DDel = DeltaUSec1; + } + else + { + if (--icnt == 0) + break; + } + } + DeltaUSec1 = DDel / (double)Elements; + } + + if (JLFlag) + { + for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++) + { + Word_t Seed1 = LowIndex; + + STARTTm(tm1); + for (elm = 0; elm < Elements; elm++) + { + Word_t JLindex; + JLindex = Seed1; + +// Find next Empty Index, JLindex is modified by JLNE + JLNE(Rc, JL, JLindex); // Rc = JudyLNextEmpty(JL, &JLindex,PJE0) + + if (Rc != 1) + FAILURE("JudyLNextEmpty Rcode != 1 =", (Word_t)Rc); + + Seed1 = GetNextIndex(Seed1); + } + ENDTm(DeltaUSecL, tm1); + + if (DDel > DeltaUSecL) + { + icnt = ICNT; + DDel = DeltaUSecL; + } + else + { + if (--icnt == 0) + break; + } + } + DeltaUSecL = DDel / (double)Elements; + } + + return (0); +} + +// Routine to time and test JudyPrevEmpty routines + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyPrevEmpty" + +Word_t +TestJudyPrevEmpty(void *J1, void *JL, Word_t HighIndex, Word_t Elements) +{ + TIMER_vars(tm1); // declare timer variables + Word_t elm; + + double DDel; + Word_t icnt; + Word_t lp; + Word_t Loops; + int Rc; + + Loops = (MAXLOOPS / Elements) + MINLOOPS; + + if (J1Flag) + { + for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++) + { + Word_t Seed1 = HighIndex; + + STARTTm(tm1); + for (elm = 0; elm < Elements; elm++) + { + Word_t J1index; + J1index = Seed1; + + J1PE(Rc, J1, J1index); // Rc = Judy1PrevEmpty(J1, &J1index,PJE0) + + if (Rc != 1) + FAILURE("Judy1PrevEmpty Rc != 1 =", (Word_t)Rc); + + Seed1 = GetNextIndex(Seed1); + } + ENDTm(DeltaUSec1, tm1); + + if (DDel > DeltaUSec1) + { + icnt = ICNT; + DDel = DeltaUSec1; + } + else + { + if (--icnt == 0) + break; + } + } + DeltaUSec1 = DDel / (double)Elements; + } + + if (JLFlag) + { + for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++) + { + Word_t Seed1 = HighIndex; + + STARTTm(tm1); + for (elm = 0; elm < Elements; elm++) + { + Word_t JLindex; + JLindex = Seed1; + +// Find next Empty Index, JLindex is modified by JLPE + JLPE(Rc, JL, JLindex); // Rc = JudyLPrevEmpty(JL, &JLindex,PJE0) + + if (Rc != 1) + FAILURE("JudyLPrevEmpty Rcode != 1 =", (Word_t)Rc); + + Seed1 = GetNextIndex(Seed1); + } + ENDTm(DeltaUSecL, tm1); + + if (DDel > DeltaUSecL) + { + icnt = ICNT; + DDel = DeltaUSecL; + } + else + { + if (--icnt == 0) + break; + } + } + DeltaUSecL = DDel / (double)Elements; + } + + return (0); +} + +#undef __FUNCTI0N__ +#define __FUNCTI0N__ "TestJudyDel" + +int +TestJudyDel(void **J1, void **JL, Word_t Seed, Word_t Elements) +{ + TIMER_vars(tm1); // declare timer variables + Word_t TstIndex; + Word_t elm; + Word_t Seed1; + int Rc; + + if (J1Flag) + { + STARTTm(tm1); + for (Seed1 = Seed, elm = 0; elm < Elements; elm++) + { + Seed1 = GetNextIndex(Seed1); + + if (DFlag) + TstIndex = Swizzle(Seed1); + else + TstIndex = Seed1; + + J1U(Rc, *J1, TstIndex); + if (Rc != 1) + FAILURE("Judy1Unset ret Rcode != 1", (Word_t)Rc); + } + ENDTm(DeltaUSec1, tm1); + DeltaUSec1 /= Elements; + } + + STARTTm(tm1); + if (JLFlag) + { + for (Seed1 = Seed, elm = 0; elm < Elements; elm++) + { + Seed1 = GetNextIndex(Seed1); + + if (DFlag) + TstIndex = Swizzle(Seed1); + else + TstIndex = Seed1; + + JLD(Rc, *JL, TstIndex); + if (Rc != 1) + FAILURE("JudyLDel ret Rcode != 1", (Word_t)Rc); + } + ENDTm(DeltaUSecL, tm1); + DeltaUSecL /= Elements; + } + return (0); +} + +// Routine to get next size of Indexes +int // return 1 if last number +NextNumb(Word_t *PNumber, // pointer to returned next number + double *PDNumb, // Temp double of above + double DMult, // Multiplier + Word_t MaxNumb) // Max number to return +{ +// Save prev number + double PrevPDNumb = *PDNumb; + double DDiff; + +// Calc next number >= 1.0 beyond previous + do { + *PDNumb *= DMult; + DDiff = *PDNumb - PrevPDNumb; + + } while (DDiff < 0.5); + +// Return it in integer format + if (DDiff < 100.0) *PNumber += (Word_t)(DDiff + 0.5); + else *PNumber = *PDNumb + 0.5; + +// Verify it did not exceed max number + if (*PNumber >= MaxNumb) + { +// it did, so return max + *PNumber = MaxNumb; + return (1); // flag it + } + return (0); // more available +} diff --git a/feeds/p4/libjudy/src/test/JudyString.c b/feeds/p4/libjudy/src/test/JudyString.c new file mode 100644 index 000000000..7f1fca9a5 --- /dev/null +++ b/feeds/p4/libjudy/src/test/JudyString.c @@ -0,0 +1,106 @@ +#include +#include +#include + +#include + +#define MAXLENSTR 1000000 + +char Index[MAXLENSTR]; // string to store. + +Pvoid_t PJHArray = (PWord_t)NULL; // Judy array. + +// By Doug Baskins Apr 2004 - for JudyHS man page -- but too long + +int // Usage: JudyString file_to_store +main(int argc, char *argv[]) +{ + Pvoid_t PJHArray = (PWord_t)NULL; // Judy array. + PWord_t PValue; // Judy array element. + Word_t Bytes; // size of JudySL array. + Word_t Len; // length of string + FILE *fid = NULL; // stream id + int Chr; // next char + long Lines; // number of lines input file + Word_t Dups; // Count duplicate lines + + if (argc < 2) + { + printf("Must supply input file in arg\n"); + exit(2); + } + if ((fid = fopen(argv[1], "r")) == NULL) + { + printf("Failed to open '%s'\n", argv[1]); + exit(2); + } + printf("Open '%s' and store strings in JudyHS array\n", argv[1]); + + Lines = 0; + Len = 0; + Dups = 0; + while ((Chr = fgetc(fid)) != EOF) + { + if (Chr == '\n' && Len) + { + Index[Len] = '\0'; + +//printf("%3lu,%lu: %s\n", Lines, Len, Index); +//printf("%s\n", Index); + + JHSI(PValue, PJHArray, Index, Len); // store string into array + if (*PValue != 0) Dups++; + *PValue += 1; + Lines++; + Len = 0; + } + else if (Len < MAXLENSTR) + { + Index[Len] = Chr; + Len++; + } + } + + fclose(fid); + fid = NULL; + + printf("'%s' has %lu lines, %lu duplicate lines\n", argv[1], Lines, Dups); + + printf("Re-open '%s' and verify each string is in JudyHS array\n", argv[1]); + + if ((fid = fopen(argv[1], "r")) == NULL) + { + printf("Failed to re-open '%s'\n", argv[1]); + exit(2); + } + + Lines = 0; + Len = 0; + while ((Chr = fgetc(fid)) != EOF) + { + if (Len < MAXLENSTR) Index[Len] = Chr; + + if (Chr == '\n' && Len) + { + Index[Len] = '\0'; + + JHSG(PValue, PJHArray, Index, Len); // store string into array + if (PValue == NULL) + { + printf("'%s'\n", Index); + printf("JHSG() failed at Line %lu\n", Lines); + exit(1); + } + Len = 0; + Lines++; + } + else Len++; + } + + printf("Begin JHSFA (JudyHSFreeArray)\n"); + + JHSFA(Bytes, PJHArray); // free array + + fprintf(stderr, "JHSFA() free'ed %lu bytes of memory\n", Bytes); + return (0); +} diff --git a/feeds/p4/libjudy/src/test/Makefile.am b/feeds/p4/libjudy/src/test/Makefile.am new file mode 100644 index 000000000..1b3256d54 --- /dev/null +++ b/feeds/p4/libjudy/src/test/Makefile.am @@ -0,0 +1,8 @@ +EXTRA_DIST = $(TESTS) + +TEST_ENVIRONMENT = top_builddir=$(top_builddir) + +TESTS = Checkit + +DISTCLEANFILES = .deps Makefile +CLEANFILES = Judy1LHCheck Judy1LHTime Makefile SL_Hash SL_Judy SL_Redblack SL_Splay diff --git a/feeds/p4/libjudy/src/test/README b/feeds/p4/libjudy/src/test/README new file mode 100644 index 000000000..2176d1abd --- /dev/null +++ b/feeds/p4/libjudy/src/test/README @@ -0,0 +1,22 @@ +StringCompare.c Program to compare JudyHS with other ADT's +Centrino_1.3Mhz_Plots/ Contains output of "StringCompare" on 1.3Mhz Centrino +Checkit Script to validate Judy works before installing +Judy1LHCheck.c Updated to include JudyHS() +Judy1LHTime.c Updated to include JudyHS() +jbgraph Script interface to 'gnuplot' to plot output of *Time.c progs. +testjbgraph Demo script to show how to use jbgraph (1+ Minute) +malloc-pre2.8a.c Only known malloc() (my me) that does not have performance + problem, See: for later version. + See: for further + information. +JudyMalloc.c For testing Judy free()s all memory that it malloc()ed. +CheckDupLines.c For the JudyHS manual example +JudyString.c For the JudyHS manual, but too long + +-- The following are obsolete. + +Judy1LCheck.c Program to test functionality of Judy API. (obsolete) +Judy1LTime.c Program to time common Judy functions. (obsolete) +SLcompare.c Program to compare JudySL performance with others (obsolete) +timeit.c High resolution timers for certain platforms (obsolete) +timeit.h High resolution timers for certain platforms (obsolete) diff --git a/feeds/p4/libjudy/src/test/SLcompare.c b/feeds/p4/libjudy/src/test/SLcompare.c new file mode 100644 index 000000000..fdcea6f00 --- /dev/null +++ b/feeds/p4/libjudy/src/test/SLcompare.c @@ -0,0 +1,1079 @@ +// @(#) $Revision: 4.1 $ $Source: /judy/test/manual/SLcompare.c $ +//======================================================================= +// Author Douglas L. Baskins, June 2002. +// Permission to use this code is freely granted, provided that this +// statement is retained. +// email - doug@sourcejudy.com +//======================================================================= + +// Compile for choice of algorithm: + +// cc -static -O -o Judy -DJUDYMETHOD SLcompare.c -lJudy +// cc -static -O -o Hash -DHASHMETHOD SLcompare.c +// cc -static -O -o Splay -DSPLAYMETHOD SLcompare.c +// cc -static -O -o Redblack -DREDBLACKMETHOD SLcompare.c +// +// Note: -static will generally get better performance because string +// routines are slower with shared librarys. +// +// Usage: +// +// Judy +// Hash +// Splay +// Redblack +/* + +This program will give you a chance to measure the speed/space +performance of 4 different string store/lookup algorithms on your data +set. All are very fast and generally can scale to very large data sets. +The memory efficiency is usually best with the Judy algorithm because it +uses the opportunity to compress data in a digital tree. The Hashing is +generally the fastest algorithm, however it looses its advantage when +the number of stored exceeds about 5X the size of the hash table. +Many thanks to J. Zobel for supplying the code for Hash, Splay and +Redblack algorithms. + +I will be including more algorithms as people donate code for testing. + +The Judy code is available at: +9/2002 (dlb). + +This is the output of this program when run on a 750Mhz P3 laptop. + +This output is using a file available from www.google.com. It looks +like 'http' web pages and was one of the files used in a March 2002 +contest by www.google.com + + wc google/data/repos.00 + 3440314 14613027 162822437 google/data/repos.00 + + lines avg_linelen getline stored RAMused/line store/ln lookup/ln ADT + 2807737 58.0 byts 0.856 uS 1455201 104.0 byts 4.859 uS 4.566 uS SPLAY + 2807737 58.0 byts 0.862 uS 1455201 96.0 byts 2.523 uS 2.101 uS HASH + 2807737 58.0 byts 0.856 uS 1455201 104.0 byts 4.601 uS 4.001 uS REDBLK + 2807737 58.0 byts 0.875 uS 1455201 78.7 byts 3.898 uS 2.687 uS JUDY + +With = 1.46 million lines stored and 2.81 million non-blank lines, +all the algorithms seem to keep their performance. The hash table is a +perfect size for this data set. I suspect only the HASH algorithm will +slow down with larger data sets unless the hash table is increased larger +than 2**20 million entrys. I have now tried a data set with about 10 +million unique lines on a 64 bit machine (google/data/repos.*). +The speeds are about the same. Lookup times are in the 2-4 uSec range +and this is probably insignificant compared to the application needing +the data. I think all four methods are fine for speed, and Judy is a +standout for its memory efficiency -- frequently using less memory than +the strings alone. + +I plan on tuning JudySL in the near future. This should improve the +performance of JudySL with short (a text word) strings. I have a data +base of all (28.8 million) domain names on the internet as a test case. + +wc /data/domnames.txt +28826508 28826508 488227095 /data/domnames.txt + +For the curious, JudySL (I.E JSLI/G macros in this program) is simply an +application subroutine that uses JudyL to the work. JudyL is a very +scaleable word to word (or pointer) mapper. JudySL is implemented as a +digital tree using JudyL arrays as 2^32 (or 2^64 in 64 bit machines) +wide (virtual) nodes. Each level in the digital tree decodes the next 4 +(or 8) bytes of the line/string until only one entry would be in the +node. Then the remaining undecoded portion of the line is stored as a +string from the parent node. A digital tree does not need rotation or +balancing. In practice, digital trees are rarely use because of their +poor memory efficiency in the nodes and a tendency to have large depths. +These problems are solved in the Judy algorithm. For more details see +application notes on: www.sourcejudy.com. And for the really curious, +a technical paper is available in the application section. If you would +like to be a reviewer, contact Doug Baskins at + +*/ + +#include +#include +#include // printf +#include +#include +#include // errno +#include // mmap() +#include // stat() +#include // gettimeofday() + +// remove all uses of this in production code. +int gDupCnt = 0; // counter for duplicate strings + +//======================================================================= +// T I M I N G M A C R O S +//======================================================================= +// if your machine is one of the supported types in the following header +// file then uncomment this corresponding to what the header file says. +// This will give very high timing resolution. +// +// #define JU_xxxxxxx 1 // read timeit.h +// #define JU_LINUX_IA32 1 // I.E. IA32 Linux +// +// +// optional for high resolution times and compile with timeit.c +// cc -static -O -o Judy -DJUDYMETHOD SLcompare.c timeit.c -lJudy +// +//#include "timeit.h" + +double DeltaUSec; // Global for remembering delta times + +#ifndef _TIMEIT_H + +// Note: I have found some Linux systems (2.4.18-6mdk) to have bugs in the +// gettimeofday() routine. Sometimes it returns a negative ~2840 microseconds +// instead of 0 or 1. If you use the above #include "timeit.h" and compile with +// timeit.c and use -DJU_LINUX_IA32, that problem will be eliminated. This is +// because for delta times less than .1 sec, the hardware free running timer +// is used instead of gettimeofday(). I have found the negative time problem +// appears about 40-50 times per second with consecutive gettimeofday() calls. + +#define TIMER_vars(T) struct timeval __TVBeg_##T, __TVEnd_##T + +#define STARTTm(T) gettimeofday(&__TVBeg_##T, NULL) + +#define ENDTm(D,T) \ +{ \ + gettimeofday(&__TVEnd_##T, NULL); \ + (D) = (double)(__TVEnd_##T.tv_sec - __TVBeg_##T.tv_sec) * 1E6 + \ + ((double)(__TVEnd_##T.tv_usec - __TVBeg_##T.tv_usec)); \ +} + +#endif // _TIMEIT_H + +//======================================================================= +// M E M O R Y S I Z E M A C R O S +//======================================================================= +// Most mallocs have mallinfo() + +// define this if your malloc does not have mallinfo(); +#define NOMALLINFO 1 + +double DeltaMem; // for remembering + +#ifndef NOMALLINFO + +#include // mallinfo() + +struct mallinfo malStart; + +#define STARTmem malStart = mallinfo() /* works with some mallocs */ +#define ENDmem \ +{ \ + struct mallinfo malEnd = mallinfo(); \ +/* strange little dance from signed to unsigned to double */ \ + unsigned int _un_int = malEnd.arena - malStart.arena; \ + DeltaMem = _un_int; /* to double */ \ +} + +#else // MALLINFO + +// this usually works for machines with less than 1-2Gb RAM. +// (it does not include memory ACQUIRED by mmap()) + +char *malStart; + +#define STARTmem (malStart = (char *)sbrk(0)) +#define ENDmem \ +{ \ + char *malEnd = (char *)sbrk(0); \ + DeltaMem = malEnd - malStart; \ +} + +#endif // MALLINFO + + +//======================================================================= +// G E T S T R I N G F R O M mmap() F I L E M A C R O +//======================================================================= +// +// From memory map POINTER store next '\n' terminated string to BUFFER +// Delete spaces, tabs, returns and resulting blank lines. + +// POINTER must be check to be within memory mapped file range +// +// NOTE: This code will core-dump if a corrupt text file because +// POINTER is not checked to exceed end of file. + +#define MAXLINE 10000 // max length line + +#define GETLINE(BUFFER,POINTER) \ +{ \ + char _chr; \ + int _count = 0; \ + for (;;) /* forever */ \ + { \ + switch (_chr = *POINTER++) \ + { \ + case ' ': /* eat spaces */ \ + case '\t': /* eat tabs */ \ + case '\r': /* eat returns */ \ + continue; \ + case '\n': /* eat blank lines */ \ + if (_count == 0) continue; \ + case '\0': /* Done */ \ + BUFFER[_count++] = '\0'; \ + break; \ + default: /* copy char */ \ + if (_count == (MAXLINE - 1)) \ + { /* cut into 2 lines */ \ + BUFFER[_count++] = '\0'; \ + POINTER--; \ + break; \ + } \ + BUFFER[_count++] = _chr; \ + continue; \ + } \ + break; \ + } \ +} + + +//======================================================================= +// J U D Y M E T H O D +//======================================================================= + +#ifdef JUDYMETHOD +#define ADTMETHOD "JUDY" + +#include + +#define MEMOVD 0 /* no overhead in Judy */ +#define INITARRAY Pvoid_t JudyArray = NULL + +// store string into array +#define STORESTRING(STRING) \ +{ \ + PWord_t _PValue; \ + JSLI(_PValue, JudyArray, (uint8_t *) STRING); \ + if (++(*_PValue) != 1) gDupCnt++; /* count dup strings */ \ +} + +// get pointer to Value associated with string + +#define GETSTRING(STRING) \ +{ \ + PWord_t _PValue; \ + JSLG(_PValue, JudyArray, (uint8_t *) STRING); \ + if (_PValue == NULL) /* not found -- bug */ \ + { \ + printf("GETSTRING failed(Judy) -- BUG!\n\n"); \ + exit(1); \ + } \ +} + +#endif // JUDYMETHOD + +// Note: this optimization by J. Zobel should not be necessary +// with the -static compile option (linux). (dlb) + +#ifdef SLOW_STRCMP +int +scmp(char *s1, char *s2) +{ + while (*s1 != '\0' && *s1 == *s2) + { + s1++; + s2++; + } + return (*s1 - *s2); +} +#else // ! SLOW_STRCMP + +#define scmp strcmp + +#endif // ! SLOW_STRCMP + +//======================================================================= +// H A S H M E T H O D +//======================================================================= + +#ifdef HASHMETHOD +#define ADTMETHOD "HASH" + +#define MEMOVD (sizeof(ht)) /* the hash table is overhead */ + +#define STORESTRING(STRING) hashinsert(ht, STRING) + +#define GETSTRING(STRING) \ +{ \ + HASHREC *_return; \ + _return = hashsearch(ht, STRING); \ + if (_return == NULL) /* not found -- bug */ \ + { \ + printf("GETSTRING(hash) failed -- BUG!\n\n"); \ + exit(1); \ + } \ +} + +/* Author J. Zobel, April 2001. + Permission to use this code is freely granted, provided that this + statement is retained. */ + +#define TSIZE (1LU << 20) /* many processors need this to be a pwr of 2 */ +#define SEED 1159241 +#define HASHFN bitwisehash + +#define INITARRAY static HASHREC *ht[TSIZE] +#define SIZEOFINIT sizeof(ht[TSIZE]) + +typedef struct hashrec +{ + char *word; + struct hashrec *next; +} +HASHREC; + +/* Bitwise hash function. Note that tsize does not have to be prime. */ +unsigned int +bitwisehash(char *word, int tsize, unsigned int seed) +{ + char c; + unsigned int h; + + h = seed; + for (; (c = *word) != '\0'; word++) + { + h ^= ((h << 5) + c + (h >> 2)); + } + return ((unsigned int)((h & 0x7fffffff) % tsize)); +} + +#ifdef notdef // not needed if a static definition used in UNIX +/* Create hash table, initialise ptrs to NULL */ +HASHREC ** +inithashtable() +{ + int i; + HASHREC **ht; + + ht = (HASHREC **) malloc(sizeof(HASHREC *) * TSIZE); + + for (i = 0; i < TSIZE; i++) + ht[i] = (HASHREC *) NULL; + + return (ht); +} +#endif // notdef + +/* Search hash table for given string, return record if found, else NULL */ +HASHREC * +hashsearch(HASHREC ** ht, char *w) +{ + HASHREC *htmp, *hprv; + unsigned int hval = HASHFN(w, TSIZE, SEED); + + for (hprv = NULL, htmp = ht[hval]; + htmp != NULL && scmp(htmp->word, w) != 0; + hprv = htmp, htmp = htmp->next) + { + ; + } + + if (hprv != NULL && htmp != NULL) /* move to front on access */ + { + hprv->next = htmp->next; + htmp->next = ht[hval]; + ht[hval] = htmp; + } + + return (htmp); +} + +/* Search hash table for given string, insert if not found */ +void +hashinsert(HASHREC ** ht, char *w) +{ + HASHREC *htmp, *hprv; + unsigned int hval = HASHFN(w, TSIZE, SEED); + + for (hprv = NULL, htmp = ht[hval]; + htmp != NULL && scmp(htmp->word, w) != 0; + hprv = htmp, htmp = htmp->next) + { + ; + } + + if (htmp == NULL) + { + htmp = (HASHREC *) malloc(sizeof(HASHREC)); + htmp->word = (char *)malloc(strlen(w) + 1); + strcpy(htmp->word, w); + htmp->next = NULL; + if (hprv == NULL) + ht[hval] = htmp; + else + hprv->next = htmp; + + /* new records are not moved to front */ + } + else + { + if (hprv != NULL) /* move to front on access */ + { + hprv->next = htmp->next; + htmp->next = ht[hval]; + ht[hval] = htmp; + } + gDupCnt++; /* count duplicate strings */ + } + + return; +} + +#endif // HASHMETHOD + +//======================================================================= +// S P L A Y M E T H O D +//======================================================================= + +#ifdef SPLAYMETHOD +#define ADTMETHOD "SPLAY" + +#define MEMOVD 0 /* not enough overhead to count */ + +/* Author J. Zobel, April 2001. + Permission to use this code is freely granted, provided that this + statement is retained. */ + +#define ROTATEFAC 11 + +typedef struct wordrec +{ + char *word; + struct wordrec *left, *right; + struct wordrec *par; +} +TREEREC; + +typedef struct ansrec +{ + struct wordrec *root; + struct wordrec *ans; +} +ANSREC; + +#define ONELEVEL(PAR,CURR,DIR,RID) \ + { \ + PAR->DIR = CURR->RID; \ + if(PAR->DIR!=NULL) \ + PAR->DIR->PAR = PAR; \ + CURR->RID = PAR; \ + PAR->PAR = CURR; \ + CURR->PAR = NULL; \ + } + +#define ZIGZIG(GPAR,PAR,CURR,DIR,RID) \ + { \ + CURR->PAR = GPAR->PAR; \ + if (CURR->PAR != NULL) \ + { \ + if (CURR->PAR->DIR == GPAR) \ + CURR->PAR->DIR = CURR; \ + else \ + CURR->PAR->RID = CURR; \ + } \ + GPAR->DIR = PAR->RID; \ + if (GPAR->DIR != NULL) \ + GPAR->DIR->PAR = GPAR; \ + PAR->DIR = CURR->RID; \ + if (CURR->RID != NULL) \ + CURR->RID->PAR = PAR; \ + CURR->RID = PAR; \ + PAR->PAR = CURR; \ + PAR->RID = GPAR; \ + GPAR->PAR = PAR; \ + } + +#define ZIGZAG(GPAR,PAR,CURR,DIR,RID) \ + { \ + CURR->PAR = GPAR->PAR; \ + if (CURR->PAR != NULL) \ + { \ + if (CURR->PAR->DIR == GPAR) \ + CURR->PAR->DIR = CURR; \ + else \ + CURR->PAR->RID = CURR; \ + } \ + PAR->RID = CURR->DIR; \ + if (PAR->RID != NULL) \ + PAR->RID->PAR = PAR; \ + GPAR->DIR = CURR->RID; \ + if (GPAR->DIR != NULL) \ + GPAR->DIR->PAR = GPAR; \ + CURR->DIR = PAR; \ + PAR->PAR = CURR; \ + CURR->RID = GPAR; \ + GPAR->PAR = CURR; \ + } + +int scount = ROTATEFAC; + +/* Search for word in a splay tree. If word is found, bring it to + root, possibly intermittently. Structure ans is used to pass + in the root, and to pass back both the new root (which may or + may not be changed) and the looked-for record. */ +void +splaysearch(ANSREC * ans, char *word) +{ + TREEREC *curr = ans->root, *par, *gpar; + int val; + + scount--; + + if (ans->root == NULL) + { + ans->ans = NULL; + return; + } + while (curr != NULL && (val = scmp(word, curr->word)) != 0) + { + if (val > 0) + curr = curr->right; + else + curr = curr->left; + } + + ans->ans = curr; + + if (curr == ans->root) + { + return; + } + + if (scount <= 0 && curr != NULL) /* Move node towards root */ + { + scount = ROTATEFAC; + + while ((par = curr->par) != NULL) + { + if (par->left == curr) + { + if ((gpar = par->par) == NULL) + { + ONELEVEL(par, curr, left, right); + } + else if (gpar->left == par) + { + ZIGZIG(gpar, par, curr, left, right); + } + else + { + ZIGZAG(gpar, par, curr, right, left); + } + } + else + { + if ((gpar = par->par) == NULL) + { + ONELEVEL(par, curr, right, left); + } + else if (gpar->left == par) + { + ZIGZAG(gpar, par, curr, left, right); + } + else + { + ZIGZIG(gpar, par, curr, right, left); + } + } + } + ans->root = curr; + } + + return; +} + +/* Insert word into a splay tree. If word is already present, bring it to + root, possibly intermittently. Structure ans is used to pass + in the root, and to pass back both the new root (which may or + may not be changed) and the looked-for record. */ + +void +splayinsert(ANSREC * ans, char *word) +{ + TREEREC *curr = ans->root, *par, *gpar, *prev = NULL, *wcreate(); + int val = 0; + + scount--; + + if (ans->root == NULL) + { + ans->ans = ans->root = wcreate(word, NULL); + return; + } + + while (curr != NULL && (val = scmp(word, curr->word)) != 0) + { + prev = curr; + if (val > 0) + curr = curr->right; + else + curr = curr->left; + } + + if (curr == NULL) + { + if (val > 0) + curr = prev->right = wcreate(word, prev); + else + curr = prev->left = wcreate(word, prev); + } + else + gDupCnt++; /* count duplicate strings */ + + ans->ans = curr; + + if (scount <= 0) /* Move node towards root */ + { + scount = ROTATEFAC; + + while ((par = curr->par) != NULL) + { + if (par->left == curr) + { + if ((gpar = par->par) == NULL) + { + ONELEVEL(par, curr, left, right); + } + else if (gpar->left == par) + { + ZIGZIG(gpar, par, curr, left, right); + } + else + { + ZIGZAG(gpar, par, curr, right, left); + } + } + else + { + if ((gpar = par->par) == NULL) + { + ONELEVEL(par, curr, right, left); + } + else if (gpar->left == par) + { + ZIGZAG(gpar, par, curr, left, right); + } + else + { + ZIGZIG(gpar, par, curr, right, left); + } + } + } + ans->root = curr; + } + return; +} + +/* Create a node to hold a word */ +TREEREC * +wcreate(char *word, TREEREC * par) +{ + TREEREC *tmp; + + tmp = (TREEREC *) malloc(sizeof(TREEREC)); + tmp->word = (char *)malloc(strlen(word) + 1); + strcpy(tmp->word, word); + tmp->left = tmp->right = NULL; + + tmp->par = par; + + return (tmp); +} + +#define INITARRAY ANSREC ans = {0} + +#define STORESTRING(STRING) splayinsert(&ans, STRING) + +#define GETSTRING(STRING) splaysearch(&ans, STRING) + +#endif // SPLAYMETHOD + +//======================================================================= +// R E D B L A C K M E T H O D +//======================================================================= + +#ifdef REDBLACKMETHOD +#define ADTMETHOD "REDBLACK" + +#define MEMOVD 0 /* not enough overhead to count */ + +/* Author J. Zobel, April 2001. + Permission to use this code is freely granted, provided that this + statement is retained. */ + +typedef struct wordrec +{ + char *word; + struct wordrec *left, *right; + struct wordrec *par; + char colour; +} +TREEREC; + +typedef struct ansrec +{ + struct wordrec *root; + struct wordrec *ans; +} +ANSREC; + +#define RED 0 +#define BLACK 1 + +/* Find word in a redblack tree */ + +void +redblacksearch(ANSREC * ans, char *word) +{ + TREEREC *curr = ans->root; + int val; + + if (ans->root != NULL) + { + while (curr != NULL && (val = scmp(word, curr->word)) != 0) + { + if (val > 0) + curr = curr->right; + else + curr = curr->left; + } + } + + ans->ans = curr; + + return; +} + +/* Rotate the right child of par upwards */ +/* Could be written as a macro, but not really necessary +as it is only called on insertion */ + +void +leftrotate(ANSREC * ans, TREEREC * par) +{ + TREEREC *curr, *gpar; + + if ((curr = par->right) != NULL) + { + par->right = curr->left; + if (curr->left != NULL) + curr->left->par = par; + curr->par = par->par; + if ((gpar = par->par) == NULL) + ans->root = curr; + else + { + if (par == gpar->left) + gpar->left = curr; + else + gpar->right = curr; + } + curr->left = par; + par->par = curr; + } +} + +/* Rotate the left child of par upwards */ +void +rightrotate(ANSREC * ans, TREEREC * par) +{ + TREEREC *curr, *gpar; + + if ((curr = par->left) != NULL) + { + par->left = curr->right; + if (curr->right != NULL) + curr->right->par = par; + curr->par = par->par; + if ((gpar = par->par) == NULL) + ans->root = curr; + else + { + if (par == gpar->left) + gpar->left = curr; + else + gpar->right = curr; + } + curr->right = par; + par->par = curr; + } +} + +/* Insert word into a redblack tree */ +void +redblackinsert(ANSREC * ans, char *word) +{ + TREEREC *curr = ans->root, *par, *gpar, *prev = NULL, *wcreate(); + int val; + + if (ans->root == NULL) + { + ans->ans = ans->root = wcreate(word, NULL); + return; + } + while (curr != NULL && (val = scmp(word, curr->word)) != 0) + { + prev = curr; + if (val > 0) + curr = curr->right; + else + curr = curr->left; + } + + ans->ans = curr; + + if (curr == NULL) + /* Insert a new node, rotate up if necessary */ + { + if (val > 0) + curr = prev->right = wcreate(word, prev); + else + curr = prev->left = wcreate(word, prev); + + curr->colour = RED; + while ((par = curr->par) != NULL + && (gpar = par->par) != NULL && curr->par->colour == RED) + { + if (par == gpar->left) + { + if (gpar->right != NULL && gpar->right->colour == RED) + { + par->colour = BLACK; + gpar->right->colour = BLACK; + gpar->colour = RED; + curr = gpar; + } + else + { + if (curr == par->right) + { + curr = par; + leftrotate(ans, curr); + par = curr->par; + } + par->colour = BLACK; + if ((gpar = par->par) != NULL) + { + gpar->colour = RED; + rightrotate(ans, gpar); + } + } + } + else + { + if (gpar->left != NULL && gpar->left->colour == RED) + { + par->colour = BLACK; + gpar->left->colour = BLACK; + gpar->colour = RED; + curr = gpar; + } + else + { + if (curr == par->left) + { + curr = par; + rightrotate(ans, curr); + par = curr->par; + } + par->colour = BLACK; + if ((gpar = par->par) != NULL) + { + gpar->colour = RED; + leftrotate(ans, gpar); + } + } + } + } + if (curr->par == NULL) + ans->root = curr; + ans->root->colour = BLACK; + } + else + gDupCnt++; /* count duplicate strings */ + + return; +} + +/* Create a node to hold a word */ +TREEREC * +wcreate(char *word, TREEREC * par) +{ + TREEREC *tmp; + + tmp = (TREEREC *) malloc(sizeof(TREEREC)); + tmp->word = (char *)malloc(strlen(word) + 1); + strcpy(tmp->word, word); + tmp->left = tmp->right = NULL; + + tmp->par = par; + + return (tmp); +} + +#define INITARRAY ANSREC ans = {0} + +#define STORESTRING(STRING) redblackinsert(&ans, STRING) + +#define GETSTRING(STRING) redblacksearch(&ans, STRING) + +#endif // REDBLACKMETHOD + +//======================================================================= +// M A I N P R O G R A M -by- Doug Baskins +//======================================================================= + +// error routine for system routines for accessing file + +#define FILERROR \ +{ \ + printf("%s: Cannot open file \"%s\": %s " \ + "(errno = %d)\n", argv[0], argv[1], strerror(errno), \ + errno); \ + fprintf(stderr, "%s: Cannot open file \"%s\": %s " \ + "(errno = %d)\n", argv[0], argv[1], strerror(errno), \ + errno); \ + exit(1); \ +} + + +//======================================================================= +// M E A S U R E A D T S P E E D and M E M O R Y U S A G E +//======================================================================= + +int +main(int argc, char *argv[]) +{ + TIMER_vars(tm); // declare timer variables + int fd; // to read file. + struct stat statbuf; // to get size of file + char *Pfile; // ram address of file + size_t fsize; // file size in bytes + char *FSmap; // start address of mapped file + char *FEmap; // end address+1 of mapped file + char String[MAXLINE]; // input buffer + int StrCnt; // line counter + int ii; // temp + + INITARRAY; + +// CHECK FOR REQUIRED INPUT FILE PARAMETER: + + if (argc != 2) + { + printf("Usage: %s \n", argv[0]); + exit(1); + } + +// GET FILE SIZE + + if (stat(argv[1], &statbuf) == -1) + FILERROR; + + fsize = statbuf.st_size; + +// OPEN INPUT FILE: + + if ((fd = open(argv[1], O_RDONLY)) == -1) + FILERROR; + +// MEMORY MAP FILE + + Pfile = + (char *)mmap(NULL, fsize, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + if (Pfile == (char *)-1) + FILERROR; + + FEmap = Pfile + fsize; // set end+1 address + +// print command name + run arguments + + printf("# "); + for (ii = 0; ii < argc; ii++) + printf("%s ", argv[ii]); + printf("\n"); + fflush(stdout); + +// file is in RAM, read again to measure time + + STARTTm(tm); // start timer + + for (StrCnt = 0, FSmap = Pfile; FSmap < FEmap; ) + { + GETLINE(String, FSmap); // 'read' next string + + StrCnt++; + } + ENDTm(DeltaUSec, tm); // end timer +// +// print header - 6 fields + + printf("# lines avg_linelen getline stored"); + printf(" RAMused/line store/ln lookup/ln ADT\n"); + +// print numb lines filesize/line + + printf("%8u", StrCnt); // Number of lines + printf(" %6.1f byts", (double)fsize / (double)StrCnt); // filesize/line + fflush(stdout); + +// print time to read a line + + printf(" %5.3f uS", DeltaUSec / (double)StrCnt); + fflush(stdout); + +// INPUT/STORE LOOP: + +// read each input line into String and store into ADT + + STARTmem; // current malloc() mem usage + STARTTm(tm); // start timer + + for (FSmap = Pfile; FSmap < FEmap; ) + { + GETLINE(String, FSmap); // 'read' next string + + STORESTRING(String); + } + ENDTm(DeltaUSec, tm); // end timer + ENDmem; // current malloc() mem usage + +// print number of non-duplicate lines + + printf(" %8u", StrCnt - gDupCnt); // duplicate lines + +// print RAM used by malloc() by ADT to store data + + printf(" %7.1f byts", (double)(DeltaMem + MEMOVD) / + (double)(StrCnt - gDupCnt)); + +// print time per line to store the data + + printf(" %6.3f uS", DeltaUSec / (double)StrCnt); + fflush(stdout); + +// READ BACK LOOP + + STARTTm(tm); // start timer + + for (FSmap = Pfile; FSmap < FEmap; ) + { + GETLINE(String, FSmap); // 'read' next string + + GETSTRING(String); + } + ENDTm(DeltaUSec, tm); // end timer + +// print time per line to lookup the data from the ADT + + printf(" %6.3f uS", DeltaUSec / (double)StrCnt); // store time/line + printf(" %s\n", ADTMETHOD); + + return (0); // done + +} // main() diff --git a/feeds/p4/libjudy/src/test/StringCompare.c b/feeds/p4/libjudy/src/test/StringCompare.c new file mode 100644 index 000000000..67f7bf0b3 --- /dev/null +++ b/feeds/p4/libjudy/src/test/StringCompare.c @@ -0,0 +1,2551 @@ +// @(#) $Revision: 4.1 $ $Source: /judy/test/manual/StringCompare.c $ +//======================================================================= +// Author Douglas L. Baskins, Jan 2003. +// Permission to use this code is freely granted, provided that this +// statement is retained. +// email - dougbaskins .at, yahoo.com +//======================================================================= + +//======================================================================= +// +// This program will time various ADTs that store and retrieve strings. +// Currently there are 7 ADTs implemented: + +/* + 1) Hash - this is the fastest one when table size matches data size + 2) JudyHS - 2nd in speed and very scaleable. + 3) JLHash - this uses a JudyL() array instead of hash table and is + very scaleable because the hash table size is ~4 billion. + 4) JudySL - ordered and requires null terminated strings. + 5) Ternary - code borrowed from Mr Dobbs, perhaps 2000 + 6) Redblack - code borrowed from J. Zobel, April 2001. + 7) Splay - code borrowed from J. Zobel, April 2001. + + Note: Splay, Redblack and Ternary methods are not very fast, so they + have not been completed and made bug free. I.E. no Delete and Free + Array routines. Ternary is fastest retrieve of these three, but uses + an extraordinary amount of memory. +*/ +//======================================================================= +// +// Compile: +// +// cc -O StringCompare.c -lm -lJudy -o StringCompare +// -or- +// cc -O -DCPUMHZ=1299 StringCompare.c -lm -lJudy -o StringCompare + +/* Notes: + 1) Use '-DCPUMHZ=1299' in cc line if better clock resolution is desired + and it compiles successfully. The 1299 is the cpu MHz : 1298.916 from + cat /proc/cpuinfo in a Linux system. + + 2) -static will generally get better performance because memcmp(), + memcpy() routines are usually slower with shared librarys. +*/ + +// Usage: +// +// StringCompare -A Hash textfile +// StringCompare -A JudyHS textfile +// StringCompare -A JLHash textfile +// StringCompare -A JudySL textfile +// StringCompare -A Ternary textfile +// StringCompare -A Redblack textfile +// StringCompare -A Splay textfile + +#include // malloc(3) +#include // getopt(3) +#include // printf(3) +#include // open(2) +#include // memcmp(3), memcpy(3) +#include // errno(3) +#include // mmap(2) +#include // gettimeofday(2) +#include // pow(3) +#include // uname(2) +#include // Judy arrays + +//======================================================================= +// D e f i n e: T O T U R N O F F A S S E R T I O N S !!!!!!!! +//======================================================================= +//#define NDEBUG 1 +#include // assert(3) + +//======================================================================= +// G L O B A L D A T A +//======================================================================= + +int foolflag = 0; // fool compiler from optimizing +static Word_t gStored = 0; // number of strings inserted +static Word_t gChainln = 0; // links traversed during RETRIVE + +static Word_t PtsPdec = 40; // default measurement points per decade + +#define INFSTRGS 1000000000 // 1 billion strings is infinity + +static Word_t nStrg = INFSTRGS; // infinity -- measure all strings +static Word_t TValues = 100000; // max measure points for RETRIVE tests +static int pFlag = 0; // pre-fault hash table pages into RAM +static int rFlag = 0; // do not randomize input file +static int aFlag = 0; // word align string buffers +static int DFlag = 0; // do the delete measurement +static int CFlag = 0; // build sequential Get buffers +static Word_t aCount = 0; // Count of missaligned string buffers + +// define the maximum length of a string allowed +#define MAXSTRLEN (100000) +static int MLength = MAXSTRLEN; +static Word_t HTblsz; // 1M default hash table size +static int fileidx; // argv[fileidx] == file string + +// for saving input string data +typedef struct STRING_ +{ + int dt_strlen; + uint8_t *dt_string; + +} dt_t , *Pdt_t; + +static Pdt_t PdtS_ = NULL; // memory for Cache access Gets +static uint8_t *Strbuf_ = NULL; +static Word_t Strsiz_ = 0; + +// Roundup BYTES to an even number of words + +/* + On Linux 2.6.3-4mdkenterprise (Mandrake 10.0 Community) printing (even + to a file) makes the timings inaccurate. So, use -L2 or greater to + average (actually save min times) and print results after all tests are + completed. +*/ +#define Printf if (Pass == 0) printf + +#define ROUNDUPWORD(BYTES) (((BYTES) + sizeof(Word_t) - 1) & (-sizeof(Word_t))) +#define BYTES2WORDS(BYTES) (((BYTES) + sizeof(Word_t) - 1) / (sizeof(Word_t))) + +//======================================================================= +// T I M I N G M A C R O S +//======================================================================= + +static double DeltaUSec; // Global for remembering delta times + +// Some operating systems have get_cycles() in /usr/include/asm/timex.h + +#ifdef CPUMHZ + +// For a 1.34 nS clock cycle processor (750Mhz) + +#define CPUSPEED (1.0 / (CPUMHZ)) + +#include + +#define TIMER_vars(T) cycles_t __TVBeg_##T + +#define STARTTm(T) __TVBeg_##T = get_cycles() + +#define ENDTm(D,T) { (D) = (double)(get_cycles() - __TVBeg_##T) * CPUSPEED; } + +#else // ! CPUMHZ + +#define TIMER_vars(T) struct timeval __TVBeg_##T, __TVEnd_##T + +#define STARTTm(T) gettimeofday(&__TVBeg_##T, NULL) + +#define ENDTm(D,T) \ +{ \ + gettimeofday(&__TVEnd_##T, NULL); \ + (D) = (double)(__TVEnd_##T.tv_sec - __TVBeg_##T.tv_sec) * 1E6 + \ + ((double)(__TVEnd_##T.tv_usec - __TVBeg_##T.tv_usec)); \ +} + +#endif // ! CPUMHZ + +//======================================================================= +// M E M O R Y S I Z E M A C R O S +//======================================================================= + +// use mallinfo() instead of sbrk() for memory usage measurements +// this should include the RAM that was mmap()ed in malloc() + +static Word_t DeltaMem; // for remembering + +// Some mallocs have mallinfo() +// #define MALLINFO 1 + +#ifdef MALLINFO +#include // mallinfo() + +static struct mallinfo malStart; + +#define STARTmem malStart = mallinfo() +#define ENDmem(DELTAMEM) \ +{ \ + struct mallinfo malEnd = mallinfo(); \ +/* strange little dance from signed to unsigned to double */ \ + unsigned int _un_int = malEnd.arena - malStart.arena; \ + (DELTAMEM) = (double)_un_int; /* to double */ \ +} +#else // NO MALLINFO + +// this usually works for machines with less than 1-2Gb RAM. +// (it does NOT include memory ACQUIRED by mmap()) + +static char *malStart; + +#define STARTmem (malStart = (char *)sbrk(0)) +#define ENDmem(DELTAMEM) \ +{ \ + char *malEnd = (char *)sbrk(0); \ + (DELTAMEM) = (double)(malEnd - malStart); \ +} +#endif // NO MALLINFO + +//======================================================================= +// F I L E O P E N and M A L L O C F A I L M A C R O S +//======================================================================= + +#define FILERROR \ +{ \ + printf("\n !! OOps - Open file error \"%s\": %s (errno = %d)\n", \ + argv[fileidx], strerror(errno), errno); \ + fprintf(stderr, " OOps - Open file error \"%s\": %s (errno = %d)\n",\ + argv[fileidx], strerror(errno), errno); \ + exit(1); \ +} + +#define MALLOCERROR \ +{ \ + printf("\n !! OOps - malloc failed at Line = %d\n", __LINE__); \ + fprintf(stderr, " OOps - malloc failed at Line = %d\n", __LINE__); \ + exit(1); \ +} + +//======================================================================= +// This alternate form of JudyMalloc() is used to keep track how much ram is +// used on some of the below ADT's +//======================================================================= + +// JUDY INCLUDE FILES +//#include "Judy.h" + +// **************************************************************************** +// J U D Y M A L L O C +// +// Allocate RAM. This is the single location in Judy code that calls +// malloc(3C). Note: JPM accounting occurs at a higher level. + +static Word_t TotalJudyMalloc = 0; + +Word_t +JudyMalloc(Word_t Words) +{ + Word_t Addr; + + Addr = (Word_t)malloc(Words * sizeof(Word_t)); + + if (Addr) + TotalJudyMalloc += Words; + + return (Addr); + +} // JudyMalloc() + +// **************************************************************************** +// J U D Y F R E E + +void +JudyFree(void *PWord, Word_t Words) +{ + free(PWord); + assert((long)(TotalJudyMalloc - Words) >= 0L); + + TotalJudyMalloc -= Words; + +} // JudyFree() + +// **************************************************************************** +// J U D Y M A L L O C +// +// Higher-level "wrapper" for allocating objects that need not be in RAM, +// although at this time they are in fact only in RAM. Later we hope that some +// entire subtrees (at a JPM or branch) can be "virtual", so their allocations +// and frees should go through this level. + +Word_t +JudyMallocVirtual(Word_t Words) +{ + return (JudyMalloc(Words)); + +} // JudyMallocVirtual() + +// **************************************************************************** +// J U D Y F R E E + +void +JudyFreeVirtual(void *PWord, Word_t Words) +{ + JudyFree(PWord, Words); + +} // JudyFreeVirtual() + +//======================================================================= +// Routine to get next size of Indexes +//======================================================================= + +static int +NextNumb(Word_t *PNumber, // pointer to returned next number + double *PDNumb, // Temp double of above + double DMult, // Multiplier + Word_t MaxNumb) // Max number to return +{ +// Save prev number + double PrevPDNumb = *PDNumb; + double DDiff; + +// Calc next number >= 1.0 beyond previous + do + { + *PDNumb *= DMult; + DDiff = *PDNumb - PrevPDNumb; + } + while (DDiff < 0.5); + +// Return it in integer format + if (DDiff < 100.0) + *PNumber += (Word_t)(DDiff + 0.5); + else + *PNumber = (Word_t)(*PDNumb + 0.5); + +// Verify it did not exceed max number + if (*PNumber >= MaxNumb) + { + *PNumber = MaxNumb; // it did, so return max + return (1); // flag it + } + return (0); // more available +} + +//======================================================================= +// M E A S U R E M E N T S T R U C T U R E +//======================================================================= + +typedef struct _MEASUREMENTS_STRUCT *Pms_t; +typedef struct _MEASUREMENTS_STRUCT +{ + Word_t ms_delta; // number of points in current group + double ms_Bytes; // average allocated memory/per string + double ms_mininsert; // Min Retrive number + double ms_minretrive; // Min Retrive number +} ms_t; + +static Pms_t Pms; // array of MEASUREMENTS_STRUCT + +// Method type + +typedef enum +{ + M_invalid, + M_Print, + M_Hash, + M_JLHash, + M_JudySL, + M_JudyHS, + M_Splay, + M_Redblack, + M_Ternary +} Method_t; + +//======================================================================= +// R a n d o m i z e i n p u t s t r i n g s +//======================================================================= + +static void +Randomize(Pdt_t Pstrstr, Word_t Len) +{ + Word_t ii; + +// swap the "random" index with the sequential one + for (ii = 1; ii < Len; ii++) + { + dt_t dttemp; + Word_t swapii; + +// get "random" index + swapii = (Word_t)rand() % Len; + +// and swap + dttemp = Pstrstr[ii]; + Pstrstr[ii] = Pstrstr[swapii]; + Pstrstr[swapii] = dttemp; + } +} + +//======================================================================= +// B u i l d s e q u e n c i a l s t r i n g b u f f e r +//======================================================================= + +Pdt_t +BuildSeqBuf(Pdt_t Pstrstr, Word_t Len) +{ + Word_t SumStrings = 0; + Word_t ii; + Word_t Strlen; + uint8_t *string; + + assert(Len <= TValues); + +// calculate how much memory needed for strings + for (ii = 0; ii < Len; ii++) + { + Strlen = Pstrstr[ii].dt_strlen; + if (aFlag) + SumStrings += ROUNDUPWORD(Strlen + 1); + else + SumStrings += Strlen + 1; + } +// check if old string buffer is big enough + if (SumStrings > Strsiz_) + { + if (Strbuf_) + free(Strbuf_); + else + SumStrings += SumStrings / 5; // bump 20% + + Strbuf_ = (uint8_t *) malloc(SumStrings); + if (Strbuf_ == NULL) + MALLOCERROR; + Strsiz_ = SumStrings; + } + for (ii = 0, string = Strbuf_; ii < Len; ii++) + { + Strlen = Pstrstr[ii].dt_strlen; + + PdtS_[ii].dt_strlen = Strlen; + PdtS_[ii].dt_string = string; + + memcpy(string, Pstrstr[ii].dt_string, Strlen + 1); + + if (aFlag) + string += ROUNDUPWORD(Strlen + 1); + else + string += Strlen + 1; + } + return (PdtS_); +} + +//======================================================================= +// H A S H M E T H O D S T R U C T U R E S +//======================================================================= + +// These structures are used in Hash() and JLHash() ADTs + +// for storing length of string + +// Hash chain structure (varible length depending on string) +// static part of the length +#define HSTRUCTOVD (sizeof(hrec_t) - sizeof(int)) +typedef struct HASHREC_ *Phrec_t; +typedef struct HASHREC_ +{ + Phrec_t hr_Next; // collision chain link pointer + Word_t hr_Value; // Data associated with string + int hr_Strlen; // length of string 2 billion max + uint8_t hr_String[sizeof(int)]; // string is allocated with struct + +} hrec_t; + +// hash head structure to keep hash array information +typedef struct HASHINFO_ +{ + Pvoid_t hi_Htbl; // Hash table + Word_t hi_tblsize; // Hash table size (Words) + Word_t hi_TotalWords; // Hash array total words + Word_t hi_Pop1; // Hash array total population + +} hinfo_t, *Phinfo_t; + +// size in words of the header structure +#define HASHHEADSZ (sizeof(hinfo_t) / sizeof(Word_t)) + +//======================================================================= +// H A S H A L G O R I T H M +//======================================================================= +// +// For CPUs with a slow mod (%) use table size a power of 2. A test is +// made to see if the SIZE is a power of 2, and if so an .AND.(&) is used +// instead of a .MOD.(%) to trim the hash return size. Note: a SIZE == 0, +// results in no trimming of hash return size. + +#define HASHSTR(STRING,LENGTH,SIZE) \ + ((SIZE) == ((SIZE) & -(SIZE))) ? \ + (HashStr(STRING, LENGTH) & ((SIZE) -1)) : \ + (HashStr(STRING, LENGTH) % (SIZE)) + +// String hash function. Hash string to a unsigned int (uint32_t) This +// one needs a fast 32 bit mpy, which is often very slow on older(RISC) +// machines. If you are sure you will not over populate the hash table, +// then a poorer/faster hash algorithm should be used. Replace with your +// own, milage may vary. This program measures the speed, whether used +// or not. + +static uint32_t +HashStr(void *Str, Word_t Len) +{ + uint32_t A = 31415; + uint32_t hashv = Len; + uint8_t *k = (uint8_t *) Str; + + while (Len--) + { + hashv = (A * hashv) + *k++; + A *= 27183; + } + return (hashv); +} + +//======================================================================= +// S T O R E and R E T R I V E R O U T I N E S +//======================================================================= + +//======================================================================= +// H A S H M E T H O D U S I N G J U D Y L A S H A S H T A B L E +//======================================================================= + +PWord_t +JLHashGet(Pvoid_t JLHash, uint8_t * String, Word_t Strlen) +{ + Phinfo_t PHash = (Phinfo_t) JLHash; + Phrec_t Phrec, *PPhrec; + uint32_t hval; + + if (PHash == NULL) + return (NULL); + +// get hash value, if mod(%) is slow (in some CPUs), make it a power of 2 + hval = HASHSTR(String, Strlen, PHash->hi_tblsize); + + JLG(PPhrec, PHash->hi_Htbl, hval); // use JudyL to get &pointer + + if (PPhrec == NULL) + return (NULL); // no table entry + +// search for matching string + for (Phrec = *PPhrec; Phrec != NULL; Phrec = Phrec->hr_Next) + { + gChainln++; // Hash chain length + if (Phrec->hr_Strlen == Strlen) // length match? + { + if (memcmp(Phrec->hr_String, String, Strlen) == 0) + return (&(Phrec->hr_Value)); // match! pointer to Value + } + } + return (NULL); +} + +// Return pointer to struct hrec_t associated with string + +PWord_t +JLHashIns(PPvoid_t PPHash, uint8_t * String, Word_t Strlen, Word_t TblSize) +{ + Phrec_t Phrec, *PPhrec; + Phinfo_t PHash; + Word_t Len; + uint32_t hval; + + PHash = (Phinfo_t) * PPHash; // core-dump if calling error + if (PHash == NULL) // if hash table not allocated + { +// allocate the header + PHash = (Phinfo_t) JudyMalloc(HASHHEADSZ); + if (PHash == NULL) + MALLOCERROR; + +// Initialize the header struct + PHash->hi_tblsize = TblSize; + PHash->hi_TotalWords = HASHHEADSZ; + PHash->hi_Pop1 = 0; // none yet + PHash->hi_Htbl = NULL; + *PPHash = (Pvoid_t)PHash; // return header to caller + } +// get hash value, if mod(%) is slow (in some CPUs), make it a power of 2 + hval = HASHSTR(String, Strlen, PHash->hi_tblsize); + +// get pointer to hash table entry + JLI(PPhrec, PHash->hi_Htbl, hval); // JLI will exit if out of memory + +// search for matching string + for (Phrec = *PPhrec; Phrec != NULL; Phrec = Phrec->hr_Next) + { + if (Phrec->hr_Strlen == Strlen) // string length match? + { + if (memcmp(Phrec->hr_String, String, Strlen) == 0) + { + return (&(Phrec->hr_Value)); // match! pointer to Value + } + } + } + +// String match not found, so do an insert + + Len = BYTES2WORDS(Strlen + HSTRUCTOVD); + Phrec = (Phrec_t) JudyMalloc(Len); // get memory for storing string + if (Phrec == NULL) + MALLOCERROR; + + PHash->hi_TotalWords += Len; // keep track of total mallocs + + Phrec->hr_Strlen = Strlen; // set string length + memcpy(Phrec->hr_String, String, Strlen); + + Phrec->hr_Next = *PPhrec; // pointer to synonym + *PPhrec = Phrec; // place new struct in front of list + (PHash->hi_Pop1)++; // add one to population + Phrec->hr_Value = (Word_t)0; // zero the associated Value + + return (&(Phrec->hr_Value)); // return pointer to Value +} + +// Return 1 if successful, else 0 + +int +JLHashDel(PPvoid_t PPHash, uint8_t * String, Word_t Strlen) +{ + Phrec_t Phrec, *PPhrec, *PPhrec1; + Phinfo_t PHash; + uint32_t hval; + +// avoid an core dump here + if (PPHash == NULL) + return (0); + PHash = (Phinfo_t) (*PPHash); // get header + if (PHash == NULL) + return (0); // not found + +// get hash value, if mod(%) is slow (in some CPUs), make it a power of 2 + hval = HASHSTR(String, Strlen, PHash->hi_tblsize); + +// get pointer hash table entry + JLG(PPhrec, PHash->hi_Htbl, hval); + if (PPhrec == NULL) + return (0); // hash entry not found + + PPhrec1 = PPhrec; // save head hash entry ^ + +// search for matching string + for (Phrec = *PPhrec; Phrec != NULL; Phrec = Phrec->hr_Next) + { + if (Phrec->hr_Strlen == Strlen) // string length match? + { + if (memcmp(Phrec->hr_String, String, Strlen) == 0) // string match? + { + int Rc; // not used + Word_t Len; + + *PPhrec = Phrec->hr_Next; // put next in previous + + Len = BYTES2WORDS(Strlen + HSTRUCTOVD); + JudyFree(Phrec, Len); + PHash->hi_TotalWords -= Len; // ram usage accounting + + (PHash->hi_Pop1)--; // Decrement population + + if (*PPhrec1 == NULL) // no chain left + { +// delete hash table entry + JLD(Rc, PHash->hi_Htbl, hval); + assert(Rc == 1); + } +// If last element, free everything + if (PHash->hi_Pop1 == 0) + { + assert(PHash->hi_TotalWords == HASHHEADSZ); + + JudyFree(PHash, HASHHEADSZ); // the header table + *PPHash = NULL; // from caller + } + return (1); // successful + } + } + PPhrec = &(Phrec->hr_Next); // previous = current + } + return (0); // string not found +} + +// Free the whole JLHash structure + +Word_t +JLHashFreeArray(PPvoid_t PPHash) +{ + Phrec_t Phrec, *PPhrec; + Phinfo_t PHash; + Word_t DeletedWords, Bytes; + Word_t Index = 0; // for First, Next loop + +// avoid an core dump here + if (PPHash == NULL) + return ((Word_t)0); + PHash = (Phinfo_t) (*PPHash); // get header + if (PHash == NULL) + return ((Word_t)0); // not found + +// get bytes of memory usage in (JudyL) Hash table + JLMU(Bytes, PHash->hi_Htbl); + + DeletedWords = HASHHEADSZ; // start with header + +// Get 1st table entry in Hash table + JLF(PPhrec, PHash->hi_Htbl, Index); + +// found an entry in hash table? + while (PPhrec != NULL) + { + int Rc; // not used + Phrec = *PPhrec; + +// walk the synonym linked list + while (Phrec != NULL) + { + Word_t Len; + Phrec_t Phrecfree = Phrec; + +// number of words to free -- struct hrec_t + Len = BYTES2WORDS(Phrec->hr_Strlen + HSTRUCTOVD); + +// sum total length of mallocs in words + DeletedWords += Len; + + (PHash->hi_Pop1)--; // Decrement population + +// get pointer to next synonym on list + Phrec = Phrec->hr_Next; + +// free the struct hrec_t + JudyFree(Phrecfree, Len); + } +// delete hash table entry + JLD(Rc, PHash->hi_Htbl, Index); + assert(Rc == 1); + +// get next hash table entry + JLN(PPhrec, PHash->hi_Htbl, Index); + } + assert(PHash->hi_TotalWords == DeletedWords); + assert(PHash->hi_Pop1 == 0); + + JudyFree(PHash, HASHHEADSZ); // the header table + *PPHash = NULL; // set pointer null + +// return total bytes freed + return ((DeletedWords * sizeof(Word_t)) + Bytes); +} + +//======================================================================= +// H A S H M E T H O D +//======================================================================= + +PWord_t +HashGet(Phinfo_t PHash, uint8_t * String, Word_t Strlen) +{ + Phrec_t Phrec, *Htbl; + uint32_t hval; + +// avoid an core dump here + if (PHash == NULL) + return (NULL); + +// get hash value, if mod(%) is slow (in some CPUs), make it a power of 2 + hval = HASHSTR(String, Strlen, PHash->hi_tblsize); + +// type Hash table pointer + Htbl = (Phrec_t *) PHash->hi_Htbl; + +// search for matching string + for (Phrec = Htbl[hval]; Phrec != NULL; Phrec = Phrec->hr_Next) + { + gChainln++; // Hash chain length + if (Phrec->hr_Strlen == Strlen) // length match? + { + if (memcmp(Phrec->hr_String, String, Strlen) == 0) + return (&(Phrec->hr_Value)); // match! pointer to Value + } + } + return (NULL); +} + +// Return pointer to struct hrec_t associated with string + +Pvoid_t +HashIns(Phinfo_t * PPHash, uint8_t * String, Word_t Strlen, Word_t TblSize) +{ + Phrec_t Phrec, *Htbl; + Phinfo_t PHash; + Word_t Len; + uint32_t hval; + + PHash = *PPHash; // core-dump if calling error + if (PHash == NULL) // if hash table not allocated + { +// allocate the header + PHash = (Phinfo_t) JudyMalloc(HASHHEADSZ); + if (PHash == NULL) + MALLOCERROR; + +// allocate the hash table + PHash->hi_Htbl = (Pvoid_t)JudyMalloc(TblSize); + if (PHash->hi_Htbl == NULL) + MALLOCERROR; + +// you cant beat this with modern compilers/librarys + memset(PHash->hi_Htbl, 0, TblSize * sizeof(Word_t)); + +// Initialize the header struct + PHash->hi_tblsize = TblSize; + PHash->hi_TotalWords = TblSize + HASHHEADSZ; + PHash->hi_Pop1 = 0; // none yet + *PPHash = PHash; // return header to caller + } +// get hash value, if mod(%) is slow (in some CPUs), make it a power of 2 + hval = HASHSTR(String, Strlen, TblSize); + +// type Hash table pointer + Htbl = (Phrec_t *) PHash->hi_Htbl; + +// search for matching string in hash table entry + for (Phrec = Htbl[hval]; Phrec != NULL; Phrec = Phrec->hr_Next) + { + if (Phrec->hr_Strlen == Strlen) // string length match? + { + if (memcmp(Phrec->hr_String, String, Strlen) == 0) // string match? + { + return (&(Phrec->hr_Value)); // match! pointer to Value + } + } + } +// string not found, so do an insert + Len = BYTES2WORDS(Strlen + HSTRUCTOVD); + Phrec = (Phrec_t) JudyMalloc(Len); + if (Phrec == NULL) + MALLOCERROR; + PHash->hi_TotalWords += Len; // keep track of total mallocs + + Phrec->hr_Strlen = Strlen; // set string length + memcpy(Phrec->hr_String, String, Strlen); // copy it + +// place new allocation first in chain + Phrec->hr_Next = Htbl[hval]; + Htbl[hval] = Phrec; + + (PHash->hi_Pop1)++; // add one to population + Phrec->hr_Value = (Word_t)0; // zero the associated Value + + return (&(Phrec->hr_Value)); // return pointer to Value +} + +// Delete entry in hash array, return 1 if successful, else 0 + +int +HashDel(Phinfo_t * PPHash, uint8_t * String, Word_t Strlen) +{ + Phrec_t Phrec, *PPhrec, *Htbl; + Phinfo_t PHash; + uint32_t hval; + +// avoid an core dump here + if (PPHash == NULL) + return (0); + PHash = *PPHash; // get header + if (PHash == NULL) + return (0); // not found + +// get hash value, if mod(%) is slow (in some CPUs), make it a power of 2 + hval = HASHSTR(String, Strlen, PHash->hi_tblsize); + +// type Hash table pointer + Htbl = (Phrec_t *) PHash->hi_Htbl; + +// get pointer hash table entry + PPhrec = &Htbl[hval]; + +// search for matching string + for (Phrec = *PPhrec; Phrec != NULL; Phrec = Phrec->hr_Next) + { + if (Phrec->hr_Strlen == Strlen) // length match? + { + if (memcmp(Phrec->hr_String, String, Strlen) == 0) + { + Word_t Len; + +// put next hrec_t in previous hrec_t + *PPhrec = Phrec->hr_Next; + + Len = BYTES2WORDS(Strlen + HSTRUCTOVD); + JudyFree(Phrec, Len); + PHash->hi_TotalWords -= Len; + (PHash->hi_Pop1)--; // Decrement population + +// If last element, free everything + if (PHash->hi_Pop1 == 0) + { + assert(PHash->hi_TotalWords == + (HASHHEADSZ + PHash->hi_tblsize)); + + JudyFree(Htbl, PHash->hi_tblsize); // hash table + JudyFree(PHash, HASHHEADSZ); // header struct + *PPHash = NULL; // from caller + } + return (1); // successful + } + } + PPhrec = &(Phrec->hr_Next); // previous = current + } + return (0); // not found +} + +Word_t +HashFreeArray(Phinfo_t * PPHash) +{ + int ii; + Phrec_t Phrec, *Htbl; + Phinfo_t PHash; + Word_t DeletedWords; + +// avoid an core dump here + if (PPHash == NULL) + return ((Word_t)0); + PHash = (Phinfo_t) (*PPHash); // get header + if (PHash == NULL) + return ((Word_t)0); + +// start accumulator of deleted memory + DeletedWords = HASHHEADSZ + PHash->hi_tblsize; + +// type Hash table pointer + Htbl = (Phrec_t *) PHash->hi_Htbl; + +// walk thru all table entrys + for (ii = 0; ii < PHash->hi_tblsize; ii++) + { + Phrec = Htbl[ii]; // next hash table entry + + while (Phrec != NULL) // walk the synonym linked list + { + Word_t Len; + Phrec_t Phrecfree; + +// get pointer to next synonym on list + Phrecfree = Phrec; + Phrec = Phrec->hr_Next; + + (PHash->hi_Pop1)--; // Decrement population + +// number of words to free -- struct hrec_t + Len = BYTES2WORDS(Phrecfree->hr_Strlen + HSTRUCTOVD); + DeletedWords += Len; // sum words freed + +// free the struct hrec_t + JudyFree(Phrecfree, Len); + } + } + +// and free the hash table + JudyFree(Htbl, PHash->hi_tblsize); + assert(PHash->hi_TotalWords == DeletedWords); + assert(PHash->hi_Pop1 == 0); + + JudyFree(PHash, HASHHEADSZ); // the header table + *PPHash = NULL; // set pointer null + +// return total bytes freed + return (DeletedWords * sizeof(Word_t)); +} + +//======================================================================= +// S P L A Y M E T H O D +//======================================================================= + +/* Author J. Zobel, April 2001. + Permission to use this code is freely granted, provided that this + statement is retained. */ + +#define ROTATEFAC 11 + +typedef struct spwordrec +{ + char *word; + struct spwordrec *left, *right; + struct spwordrec *par; +} SPTREEREC; + +typedef struct spansrec +{ + struct spwordrec *root; + struct spwordrec *ans; +} SPANSREC; + +SPANSREC spans = { 0 }; + +#define ONELEVEL(PAR,CURR,DIR,RID) \ + { \ + PAR->DIR = CURR->RID; \ + if(PAR->DIR!=NULL) \ + PAR->DIR->PAR = PAR; \ + CURR->RID = PAR; \ + PAR->PAR = CURR; \ + CURR->PAR = NULL; \ + } + +#define ZIGZIG(GPAR,PAR,CURR,DIR,RID) \ + { \ + CURR->PAR = GPAR->PAR; \ + if (CURR->PAR != NULL) \ + { \ + if (CURR->PAR->DIR == GPAR) \ + CURR->PAR->DIR = CURR; \ + else \ + CURR->PAR->RID = CURR; \ + } \ + GPAR->DIR = PAR->RID; \ + if (GPAR->DIR != NULL) \ + GPAR->DIR->PAR = GPAR; \ + PAR->DIR = CURR->RID; \ + if (CURR->RID != NULL) \ + CURR->RID->PAR = PAR; \ + CURR->RID = PAR; \ + PAR->PAR = CURR; \ + PAR->RID = GPAR; \ + GPAR->PAR = PAR; \ + } + +#define ZIGZAG(GPAR,PAR,CURR,DIR,RID) \ + { \ + CURR->PAR = GPAR->PAR; \ + if (CURR->PAR != NULL) \ + { \ + if (CURR->PAR->DIR == GPAR) \ + CURR->PAR->DIR = CURR; \ + else \ + CURR->PAR->RID = CURR; \ + } \ + PAR->RID = CURR->DIR; \ + if (PAR->RID != NULL) \ + PAR->RID->PAR = PAR; \ + GPAR->DIR = CURR->RID; \ + if (GPAR->DIR != NULL) \ + GPAR->DIR->PAR = GPAR; \ + CURR->DIR = PAR; \ + PAR->PAR = CURR; \ + CURR->RID = GPAR; \ + GPAR->PAR = CURR; \ + } + +int scount = ROTATEFAC; + +/* Create a node to hold a word */ + +static SPTREEREC * +spwcreate(char *word, SPTREEREC * par) +{ + SPTREEREC *tmp; + + tmp = (SPTREEREC *) malloc(sizeof(SPTREEREC)); + tmp->word = (char *)malloc(strlen(word) + 1); + strcpy(tmp->word, word); + tmp->left = tmp->right = NULL; + + tmp->par = par; + + gStored++; // count stored + + return (tmp); +} + +/* Search for word in a splay tree. If word is found, bring it to + root, possibly intermittently. Structure ans is used to pass + in the root, and to pass back both the new root (which may or + may not be changed) and the looked-for record. */ + +static void +splaysearch(SPANSREC * ans, char *word) +{ + SPTREEREC *curr = ans->root, *par, *gpar; + int val; + + scount--; + + if (ans->root == NULL) + { + ans->ans = NULL; + return; + } + while (curr != NULL && (val = strcmp(word, curr->word)) != 0) + { + if (val > 0) + curr = curr->right; + else + curr = curr->left; + } + + ans->ans = curr; + + if (curr == ans->root) + { + return; + } + + if (scount <= 0 && curr != NULL) /* Move node towards root */ + { + scount = ROTATEFAC; + + while ((par = curr->par) != NULL) + { + if (par->left == curr) + { + if ((gpar = par->par) == NULL) + { + ONELEVEL(par, curr, left, right); + } + else if (gpar->left == par) + { + ZIGZIG(gpar, par, curr, left, right); + } + else + { + ZIGZAG(gpar, par, curr, right, left); + } + } + else + { + if ((gpar = par->par) == NULL) + { + ONELEVEL(par, curr, right, left); + } + else if (gpar->left == par) + { + ZIGZAG(gpar, par, curr, left, right); + } + else + { + ZIGZIG(gpar, par, curr, right, left); + } + } + } + ans->root = curr; + } + + return; +} + +/* Insert word into a splay tree. If word is already present, bring it to + root, possibly intermittently. Structure ans is used to pass + in the root, and to pass back both the new root (which may or + may not be changed) and the looked-for record. */ + +static void +splayinsert(SPANSREC * ans, char *word) +{ + SPTREEREC *curr = ans->root, *par, *gpar, *prev = NULL, *spwcreate(); + int val = 0; + + scount--; + + if (ans->root == NULL) + { + ans->ans = ans->root = spwcreate(word, NULL); + return; + } + + while (curr != NULL && (val = strcmp(word, curr->word)) != 0) + { + prev = curr; + if (val > 0) + curr = curr->right; + else + curr = curr->left; + } + + if (curr == NULL) + { + if (val > 0) + curr = prev->right = spwcreate(word, prev); + else + curr = prev->left = spwcreate(word, prev); + } + + ans->ans = curr; + + if (scount <= 0) /* Move node towards root */ + { + scount = ROTATEFAC; + + while ((par = curr->par) != NULL) + { + if (par->left == curr) + { + if ((gpar = par->par) == NULL) + { + ONELEVEL(par, curr, left, right); + } + else if (gpar->left == par) + { + ZIGZIG(gpar, par, curr, left, right); + } + else + { + ZIGZAG(gpar, par, curr, right, left); + } + } + else + { + if ((gpar = par->par) == NULL) + { + ONELEVEL(par, curr, right, left); + } + else if (gpar->left == par) + { + ZIGZAG(gpar, par, curr, left, right); + } + else + { + ZIGZIG(gpar, par, curr, right, left); + } + } + } + ans->root = curr; + } + return; +} + +//======================================================================= +// R E D B L A C K M E T H O D +//======================================================================= + +/* Author J. Zobel, April 2001. + Permission to use this code is freely granted, provided that this + statement is retained. */ + +typedef struct rbwordrec +{ + char *word; + struct rbwordrec *left, *right; + struct rbwordrec *par; + char colour; +} RBTREEREC; + +typedef struct rbansrec +{ + struct rbwordrec *root; + struct rbwordrec *ans; +} BRANSREC; + +BRANSREC rbans = { 0 }; + +#define RED 0 +#define BLACK 1 + +/* Find word in a redblack tree */ + +static void +redblacksearch(BRANSREC * ans, char *word) +{ + RBTREEREC *curr = ans->root; + int val; + + if (ans->root != NULL) + { + while (curr != NULL && (val = strcmp(word, curr->word)) != 0) + { + if (val > 0) + curr = curr->right; + else + curr = curr->left; + } + } + + ans->ans = curr; + + return; +} + +/* Rotate the right child of par upwards */ + +/* Could be written as a macro, but not really necessary +as it is only called on insertion */ + +void +leftrotate(BRANSREC * ans, RBTREEREC * par) +{ + RBTREEREC *curr, *gpar; + + if ((curr = par->right) != NULL) + { + par->right = curr->left; + if (curr->left != NULL) + curr->left->par = par; + curr->par = par->par; + if ((gpar = par->par) == NULL) + ans->root = curr; + else + { + if (par == gpar->left) + gpar->left = curr; + else + gpar->right = curr; + } + curr->left = par; + par->par = curr; + } +} + +/* Rotate the left child of par upwards */ +void +rightrotate(BRANSREC * ans, RBTREEREC * par) +{ + RBTREEREC *curr, *gpar; + + if ((curr = par->left) != NULL) + { + par->left = curr->right; + if (curr->right != NULL) + curr->right->par = par; + curr->par = par->par; + if ((gpar = par->par) == NULL) + ans->root = curr; + else + { + if (par == gpar->left) + gpar->left = curr; + else + gpar->right = curr; + } + curr->right = par; + par->par = curr; + } +} + +/* Create a node to hold a word */ + +RBTREEREC * +rbwcreate(char *word, RBTREEREC * par) +{ + RBTREEREC *tmp; + + tmp = (RBTREEREC *) malloc(sizeof(RBTREEREC)); + tmp->word = (char *)malloc(strlen(word) + 1); + strcpy(tmp->word, word); + tmp->left = tmp->right = NULL; + + tmp->par = par; + + gStored++; // count stored + + return (tmp); +} + +/* Insert word into a redblack tree */ + +void +redblackinsert(BRANSREC * ans, char *word) +{ + RBTREEREC *curr = ans->root, *par, *gpar, *prev = NULL, *rbwcreate(); + int val = 0; + + if (ans->root == NULL) + { + ans->ans = ans->root = rbwcreate(word, NULL); + return; + } + while (curr != NULL && (val = strcmp(word, curr->word)) != 0) + { + prev = curr; + if (val > 0) + curr = curr->right; + else + curr = curr->left; + } + + ans->ans = curr; + + if (curr == NULL) + /* Insert a new node, rotate up if necessary */ + { + if (val > 0) + curr = prev->right = rbwcreate(word, prev); + else + curr = prev->left = rbwcreate(word, prev); + + curr->colour = RED; + while ((par = curr->par) != NULL + && (gpar = par->par) != NULL && curr->par->colour == RED) + { + if (par == gpar->left) + { + if (gpar->right != NULL && gpar->right->colour == RED) + { + par->colour = BLACK; + gpar->right->colour = BLACK; + gpar->colour = RED; + curr = gpar; + } + else + { + if (curr == par->right) + { + curr = par; + leftrotate(ans, curr); + par = curr->par; + } + par->colour = BLACK; + if ((gpar = par->par) != NULL) + { + gpar->colour = RED; + rightrotate(ans, gpar); + } + } + } + else + { + if (gpar->left != NULL && gpar->left->colour == RED) + { + par->colour = BLACK; + gpar->left->colour = BLACK; + gpar->colour = RED; + curr = gpar; + } + else + { + if (curr == par->left) + { + curr = par; + rightrotate(ans, curr); + par = curr->par; + } + par->colour = BLACK; + if ((gpar = par->par) != NULL) + { + gpar->colour = RED; + leftrotate(ans, gpar); + } + } + } + } + if (curr->par == NULL) + ans->root = curr; + ans->root->colour = BLACK; + } + + return; +} + +//======================================================================= +// T E R N A R Y M E T H O D +//======================================================================= + +typedef struct tnode *Tptr; +typedef struct tnode +{ + uint8_t splitchar; + Tptr lokid, eqkid, hikid; +} +Tnode; + +void +TernaryIns(Tptr * p, uint8_t * s, int Len) +{ + int d; + uint8_t *instr = s; + Tptr pp; + while ((pp = *p) != NULL) + { + if ((d = *s - pp->splitchar) == 0) + { + if (*s++ == 0) + { + printf("Oops duplicate Ternary string %s\n", instr); + return; + } + p = &(pp->eqkid); + } + else if (d < 0) + p = &(pp->lokid); + else + p = &(pp->hikid); + } + for (;;) + { + *p = (Tptr) malloc(sizeof(Tnode)); + pp = *p; + pp->splitchar = *s; + pp->lokid = pp->eqkid = pp->hikid = 0; + if (*s++ == 0) + { + pp->eqkid = (Tptr) instr; + gStored++; // number of strings stored + return; + } + p = &(pp->eqkid); + } +} + +int +TernaryGet(Tptr p, uint8_t * s, int Len) +{ + while (p) + { + if (*s < p->splitchar) + p = p->lokid; + else if (*s == p->splitchar) + { + if (*s++ == 0) + return 1; + p = p->eqkid; + } + else + p = p->hikid; + } + return 0; +} + +//======================================================================= +// M E A S U R E A D T S P E E D and M E M O R Y U S A G E +//======================================================================= + +//Word_t TotalJudyMalloc; + +#define GETSTRING(PCurStr, Strlen) + +int +main(int argc, char *argv[]) +{ + TIMER_vars(tm); // declare timer variables + FILE *fid; // to read file. + int Chr; // char read from fgetc + Pdt_t Pdt, Pdts; // array of lengths and pointers to str + uint8_t *PCurStr; // Current string pointer + Word_t LineCnt; // line counter + int Strlen; // = strlen(); + Word_t StrTot; // Total len of strings + Word_t StrNumb; // current line number + Word_t ReadLin; // strings to read + double Mult; // multiplier between groups + Word_t Groups; // number of measurement groups + Word_t grp; // current group + Pvoid_t JudySL = NULL; // JudySL root pointer + Pvoid_t JudyHS = NULL; // JudyHS root pointer + Pvoid_t JLHash = NULL; // JLHash root pointer + Phinfo_t HRoot = NULL; // hash table root pointer + Tptr Ternary = { 0 }; // Ternary struct root pointer + + Method_t Method = M_invalid; // the method to measure + Word_t lines = 0; // to shut up compiler + Word_t Bytes = 0; // Bytes deallocated from FreeArray + Word_t StringMemory; // Bytes allocated for input data + int Pass; + int Passes = 1; + + int Opt; + extern char *optarg; + int ErrorFlag = 0; + +// un-buffer output + setbuf(stdout, NULL); + +//============================================================ +// PARSE INPUT PARAMETERS +//============================================================ + + while ((Opt = getopt(argc, argv, "A:H:L:n:T:P:M:praDC")) != -1) + { + switch (Opt) + { + case 'A': + if (Method != M_invalid) + { + printf("\nOnly ONE '-A' is allowed!!!!!!\n"); + ErrorFlag++; + break; + } + if (strcmp(optarg, "Print") == 0) + Method = M_Print; + if (strcmp(optarg, "Hash") == 0) + { + Method = M_Hash; + HTblsz = 1LU << 20; // default 1.0+ million + } + if (strcmp(optarg, "JLHash") == 0) + { + Method = M_JLHash; + HTblsz = 0; // max 2^32 + } + if (strcmp(optarg, "JudySL") == 0) + Method = M_JudySL; + if (strcmp(optarg, "Splay") == 0) + Method = M_Splay; + if (strcmp(optarg, "Redblack") == 0) + Method = M_Redblack; + if (strcmp(optarg, "JudyHS") == 0) + Method = M_JudyHS; + if (strcmp(optarg, "Ternary") == 0) + Method = M_Ternary; + break; + + case 'H': // Size of Hash table + HTblsz = strtoul(optarg, NULL, 0); + break; + + case 'L': // Number of Loops + Passes = atoi(optarg); + if (Passes <= 0) + { + printf("\n !! OOps - Number of Loops must be > 0\n"); + ErrorFlag++; + } + break; + + case 'n': // Max population of arrays + nStrg = strtoul(optarg, NULL, 0); // Size of Linear Array + if (nStrg == 0) + { + printf("\n !! OOps - Number of strings must be > 0\n"); + ErrorFlag++; + } + break; + + case 'T': // Maximum retrieve tests for timing + TValues = strtoul(optarg, NULL, 0); + break; + + case 'P': // measurement points per decade + PtsPdec = strtoul(optarg, NULL, 0); + break; + + case 'M': // maximum length of input string + MLength = atoi(optarg); + break; + + case 'p': // pre-initialize Hash table + pFlag = 1; + break; + + case 'r': // do not randomize input + if (CFlag) + { + printf + ("\n !! OOps '-r' and '-C' flag are mutually exclusive\n"); + ErrorFlag++; + break; + } + rFlag = 1; + break; + + case 'a': // word align string buffers + aFlag = 1; + break; + + case 'D': // do a delete at end + DFlag = 1; + break; + + case 'C': // build sequential Get string buffers + if (rFlag) + { + printf + ("\n !! OOps '-C' and '-r' flag are mutually exclusive\n"); + ErrorFlag++; + break; + } + CFlag = 1; + break; + + default: + ErrorFlag++; + break; + } + } + if (Method == -1) + { + printf + ("\n !! OOps -- '-A ' I.E. '-AHash' or '-AJudyHS' is a required option\n"); + ErrorFlag++; + } + + fileidx = optind; + if (optind >= argc) + { + printf("\n !! OOps -- No input file specified\n"); + ErrorFlag++; + } + + if (ErrorFlag) + { + printf("\n"); + printf("$ %s -A -n# -H# -P# -T# -p -r -a InputStringFile\n\n", + argv[0]); + printf("Where: "); + printf("'InputStringFile' is text file of strings to use in test\n\n"); + printf + ("-A is Hash|JLHash|JudySL|JudyHS|Splay|Redblack|Ternary|Print\n"); + printf("\n"); + printf("-n <#> max number of strings to use in tests (all)\n"); + printf("-H <#> is number elements in Hash table\n"); + printf("-P <#> number of measurement points per decade (40)\n"); + printf + ("-T <#> Change the 'Get' number_of_strings to measure per data point\n"); + printf("-D Use 'Delete' routine instead of 'FreeArray' routine\n"); + printf("-p pre-zero hash table to fault in all pages\n"); + printf("-r Do not randomize Insert and Get order of strings\n"); + printf("-C Build contigious string buffers for 'Get' tests\n"); + printf("-a Word_t align the start address of input strings\n"); + printf("-M <#> Change the maximum 'strlen(String)' of input Strings\n"); + printf("\n\n"); + + exit(1); + } + +// calculate max number mask used in hash routine + +//============================================================ +// PRINT COMMAND NAME + RUN ARGUMENTS +//============================================================ + + printf("# %s", argv[0]); + if (nStrg != INFSTRGS) + printf(" -n%lu", nStrg); + switch (Method) + { + case M_Hash: + printf(" -A Hash"); + break; + case M_JLHash: + printf(" -A JLHash"); + break; + case M_JudySL: + printf(" -A JudySL"); + break; + case M_JudyHS: + printf(" -A JudyHS"); + break; + case M_Splay: + printf(" -A Splay"); + break; + case M_Redblack: + printf(" -A Redblack"); + break; + case M_Ternary: + printf(" -A Ternary"); + break; + default: + break; + } + if (HTblsz) + printf(" -H%lu", HTblsz); + printf(" -P%lu", PtsPdec); + printf(" -L%d", Passes); + if (pFlag) + printf(" -p"); + if (rFlag) + printf(" -r"); + if (DFlag) + printf(" -D"); + if (CFlag) + printf(" -C"); + printf(" -M%d", MLength); + printf(" %s", argv[fileidx]); + printf("\n"); + +// print some header + + printf("# This file is in a format to input to 'jbgraph'\n"); + printf("# XLABEL Stored\n"); + printf("# YLABEL Microseconds / Index\n"); + printf("# COLHEAD 1 Total Insert attempts\n"); + printf("# COLHEAD 2 Number Gets\n"); + printf("# COLHEAD 3 Duplicate strings\n"); + printf("# COLHEAD 4 Insert Time (uS)\n"); + printf("# COLHEAD 5 Get Time (uS)\n"); + printf("# COLHEAD 6 Hash Chain Length\n"); + printf("# COLHEAD 7 Average RAM/String\n"); + +// uname(2) strings describing the machine + { + struct utsname ubuf; // for system name + + if (uname(&ubuf) == -1) + printf("# Uname(2) failed\n"); + else + printf("# %s %s %s %s %s\n", ubuf.sysname, ubuf.nodename, + ubuf.release, ubuf.version, ubuf.machine); + } + if (sizeof(Word_t) == 8) + printf("# 64 Bit CPU\n"); + else if (sizeof(Word_t) == 4) + printf("# 32 Bit CPU\n"); +#ifdef CPUMHZ + printf("# Processor speed compiled at %d Mhz\n", CPUMHZ); +#endif // CPUMHZ + + if (Method == M_Hash) + printf("# Hash record struct: sizeof(hrec_t) = %d\n", sizeof(hrec_t)); + if (Method == M_Ternary) + printf("# Ternary record struct: sizeof(Tnode) = %d\n", sizeof(Tnode)); + +// OPEN INPUT FILE: + + if ((fid = fopen(argv[fileidx], "r")) == NULL) + FILERROR; + + for (StrTot = Strlen = LineCnt = 0; (Chr = fgetc(fid)) != EOF;) + { + if (Chr == '\n') + { + if (Strlen) // eat zero length lines + { + if (Strlen > MLength) + Strlen = MLength; + LineCnt++; // increase string count + Strlen++; // add a \0 for JudySL + + if (aFlag) // for word alignment + StrTot += ROUNDUPWORD(Strlen); + else + StrTot += Strlen; // memory needed to store strings + + if (LineCnt == nStrg) // shorten if required by -n option + break; + + Strlen = 0; + } + } + else + { + Strlen++; + } + } + fclose(fid); + fid = NULL; + nStrg = LineCnt; // adj if necessary + +// get struct to keep track of the strings + StringMemory = sizeof(dt_t) * nStrg; + Pdt = (Pdt_t) malloc(sizeof(dt_t) * nStrg); + if (Pdt == NULL) + MALLOCERROR; + +// get memory to store the strings + StringMemory += StrTot; + PCurStr = (uint8_t *) malloc(StrTot); + if (PCurStr == NULL) + MALLOCERROR; + +// BRING FILE INTO RAM, COUNT LINES and CHECK LENGTH + +//============================================================ +// CALCULATE NUMBER OF MEASUREMENT GROUPS -- points per decade +//============================================================ + +// Calculate Multiplier for number of points per decade + Mult = pow(10.0, 1.0 / (double)PtsPdec); + { + double sum; + Word_t numb, prevnumb; + +// Count number of measurements needed (10K max) + sum = numb = 1; + for (Groups = 2; Groups < 10000; Groups++) + if (NextNumb(&numb, &sum, Mult, nStrg)) + break; + +// Get memory for measurements + Pms = (Pms_t) calloc(Groups, sizeof(ms_t)); + if (Pms == NULL) + MALLOCERROR; + +// Now calculate number of Indexes for each measurement point + numb = sum = 1; + prevnumb = 0; + for (grp = 0; grp < Groups; grp++) + { + Pms[grp].ms_delta = numb - prevnumb; + Pms[grp].ms_mininsert = 10000000.0; // infinity + Pms[grp].ms_minretrive = 10000000.0; // infinity + Pms[grp].ms_Bytes = 0.0; + + prevnumb = numb; + + NextNumb(&numb, &sum, Mult, nStrg); + } + } // Groups = number of sizes + +// print remaining header + + if (Method == M_Hash) + { + printf("# Allocate Hash table = %lu elements\n", HTblsz); + } + if (Method == M_JLHash) + { + if (HTblsz) + printf("# JLHash table virtual size = %lu\n", HTblsz); + else + printf("# JLHash table virtual size = 4294967296\n"); + } + +//======================================================================= +// Read text input file into RAM +//======================================================================= + + if ((fid = fopen(argv[fileidx], "r")) == NULL) + FILERROR; + + for (Strlen = LineCnt = 0; LineCnt < nStrg;) + { + Chr = fgetc(fid); + if (Chr == '\n') + { + if (Strlen) // eat zero length lines + { + if (Strlen > MLength) + Strlen = MLength; + Pdt[LineCnt].dt_string = PCurStr - Strlen; + Pdt[LineCnt].dt_strlen = Strlen; + LineCnt++; + + Strlen = 0; + *PCurStr++ = '\0'; // for JudySL + if (aFlag) // for word alignment + PCurStr = (uint8_t *) ROUNDUPWORD((Word_t)PCurStr); + + if ((Word_t)PCurStr % sizeof(Word_t)) + aCount++; + } + } + else + { + if (Strlen < MLength) + { + Strlen++; + if (Chr == '\0') + Chr = ' '; // for JudySL + *PCurStr++ = (uint8_t) Chr; + } + } + } + fclose(fid); + fid = NULL; + assert(nStrg == LineCnt); + + printf("# %lu (%.1f%%) non-Word_t aligned string buffers\n", + aCount, (double)aCount / (double)LineCnt * 100.0); + + printf("# Ram used for input data = %lu bytes\n", StringMemory); + + printf("# Average string length = %.1f bytes\n", + (double)(StrTot - LineCnt) / LineCnt); + +// Allocate memory for Cached assess to 'Get' (largest delta). This flag +// will put the 'randomized' 'Get' order strings in a sequential buffer. +// Modern processors will 'read ahead' with an access to RAM is sequential +// -- thus saving the 'Get' having to bring the string into cache. + if (CFlag) + { + PdtS_ = (Pdt_t) malloc(TValues * sizeof(dt_t)); + if (PdtS_ == NULL) + MALLOCERROR; + +// now guess how much memory will be needed for the strings + Strsiz_ = ((StrTot / nStrg) * TValues); + Strsiz_ += Strsiz_; // bump %20 + + Strbuf_ = (uint8_t *) malloc(Strsiz_); + if (Strbuf_ == NULL) + MALLOCERROR; + + printf + ("# %lu bytes malloc() for 'cached' strings for Get measurement\n", + Strsiz_); + } + +//======================================================================= +// TIME GETSTRING() from Cache (most of the time) +//======================================================================= + + STARTTm(tm); // start timer + for (LineCnt = 0; LineCnt < nStrg; LineCnt++) + { + GETSTRING(PCurStr, Strlen); + Strlen = Pdt[LineCnt].dt_strlen; + PCurStr = Pdt[LineCnt].dt_string; + + if (strlen(PCurStr) != Strlen) // bring string into Cache + { +// necessary to prevent cc from optimizing out + printf(" !! OOps Bug, wrong string length\n"); + exit(1); + } + } + ENDTm(DeltaUSec, tm); // end timer + + printf + ("# Access Time = %6.3f uS average per string (mostly from Cache)\n", + DeltaUSec / nStrg); + +//======================================================================= +// TIME GETSTRING() + HASHSTR() from Cache (most of the time) +//======================================================================= + + STARTTm(tm); // start timer + for (LineCnt = 0; LineCnt < nStrg; LineCnt++) + { + uint32_t hval; + GETSTRING(PCurStr, Strlen); + PCurStr = Pdt[LineCnt].dt_string; + Strlen = Pdt[LineCnt].dt_strlen; + hval = HASHSTR(PCurStr, Strlen, HTblsz); + if (foolflag) + printf("OOps foolflag is set, hval = %d\n", hval); + } + ENDTm(DeltaUSec, tm); // end timer + + printf + ("# HashStr() Time = %6.3f uS average per string (mostly from Cache)\n", + DeltaUSec / nStrg); + +// randomize the input strings (adjacent strings will not be on same page) + + if (rFlag == 0) + { + Randomize(Pdt, nStrg); // Randomize ALL to be stored + +//======================================================================= +// TIME GETSTRING() from RAM (most of the time) +//======================================================================= + + STARTTm(tm); // start timer + for (LineCnt = 0; LineCnt < nStrg; LineCnt++) + { + GETSTRING(PCurStr, Strlen); + Strlen = Pdt[LineCnt].dt_strlen; + PCurStr = Pdt[LineCnt].dt_string; + + if (strlen(PCurStr) != Strlen) // bring string into Cache + { +// necessary to prevent cc from optimizing out + printf(" !! OOps Bug, wrong string length\n"); + exit(1); + } + } + ENDTm(DeltaUSec, tm); // end timer + + printf + ("# Access Time = %6.3f uS average per string (mostly from RAM)\n", + DeltaUSec / nStrg); + +//======================================================================= +// TIME GETSTRING() + HASHSTR() from RAM (most of the time) +//======================================================================= + + STARTTm(tm); // start timer + for (LineCnt = 0; LineCnt < nStrg; LineCnt++) + { + uint32_t hval; + GETSTRING(PCurStr, Strlen); + Strlen = Pdt[LineCnt].dt_strlen; + PCurStr = Pdt[LineCnt].dt_string; + hval = HASHSTR(PCurStr, Strlen, HTblsz); + if (foolflag) + printf("OOps foolflag is set, hval = %u\n", hval); + } + ENDTm(DeltaUSec, tm); // end timer + + printf + ("# HashStr() Time = %6.3f uS average per string (mostly from RAM)\n", + DeltaUSec / nStrg); + } + +//======================================================================= +// Insert, Get and Delete loops +//======================================================================= + + for (Pass = 0; Pass < Passes; Pass++) + { + printf("# Pass %d\n", Pass); + +// heading of table + Printf + ("# TotInserts DeltaGets DupStrs InsTime GetTime HChainLen Ram/String\n"); + gStored = 0; // number of strings inserted + StrNumb = 0; // number of attempted strings inserted + + STARTmem; // current malloc() mem usage + for (grp = 0; grp < Groups; grp++) + { + PWord_t PValue; + Word_t Begin = gStored; // remember current STOREed + Word_t Delta = Pms[grp].ms_delta; + + switch (Method) + { + case M_Print: + { + STARTTm(tm); // start timer + for (lines = 0; lines < Delta; lines++, StrNumb++) + { + GETSTRING(PCurStr, Strlen); + PCurStr = Pdt[StrNumb].dt_string; + Printf("%s\n", (char *)PCurStr); + } + ENDTm(DeltaUSec, tm); // end timer + break; + } + case M_Hash: + { + STARTTm(tm); // start timer + for (lines = 0; lines < Delta; lines++, StrNumb++) + { + GETSTRING(PCurStr, Strlen); + Strlen = Pdt[StrNumb].dt_strlen; + PCurStr = Pdt[StrNumb].dt_string; + + PValue = HashIns(&HRoot, PCurStr, Strlen, HTblsz); + if ((*PValue)++ == 0) + gStored++; // number of strings stored + } + ENDTm(DeltaUSec, tm); // end timer + break; + } + case M_JLHash: + { + STARTTm(tm); // start timer + for (lines = 0; lines < Delta; lines++, StrNumb++) + { + GETSTRING(PCurStr, Strlen); + Strlen = Pdt[StrNumb].dt_strlen; + PCurStr = Pdt[StrNumb].dt_string; + PValue = JLHashIns(&JLHash, PCurStr, Strlen, HTblsz); + if ((*PValue)++ == 0) + gStored++; // number of strings stored + } + ENDTm(DeltaUSec, tm); // end timer + break; + } + case M_JudySL: + { + STARTTm(tm); // start timer + for (lines = 0; lines < Delta; lines++, StrNumb++) + { + GETSTRING(PCurStr, Strlen); + PCurStr = Pdt[StrNumb].dt_string; + + JSLI(PValue, JudySL, PCurStr); // insert string + if ((*PValue)++ == 0) + gStored++; // number of strings stored + } + ENDTm(DeltaUSec, tm); // end timer + break; + } + case M_JudyHS: + { + STARTTm(tm); // start timer + for (lines = 0; lines < Delta; lines++, StrNumb++) + { + GETSTRING(PCurStr, Strlen); + Strlen = Pdt[StrNumb].dt_strlen; + PCurStr = Pdt[StrNumb].dt_string; + + JHSI(PValue, JudyHS, PCurStr, Strlen); // insert string + if ((*PValue)++ == 0) + gStored++; // number of strings stored + } + ENDTm(DeltaUSec, tm); // end timer + break; + } + +// NOTE: the ADT's below here are so slow, that I did not add much effort +// to clean them up. (dlb) + + case M_Splay: + { + STARTTm(tm); // start timer + for (lines = 0; lines < Delta; lines++, StrNumb++) + { + GETSTRING(PCurStr, Strlen); + PCurStr = Pdt[StrNumb].dt_string; + + splayinsert(&spans, (char *)PCurStr); + } + ENDTm(DeltaUSec, tm); // end timer + break; + } + case M_Redblack: + { + STARTTm(tm); // start timer + for (lines = 0; lines < Delta; lines++, StrNumb++) + { + GETSTRING(PCurStr, Strlen); + PCurStr = Pdt[StrNumb].dt_string; + + redblackinsert(&rbans, (char *)PCurStr); + } + ENDTm(DeltaUSec, tm); // end timer + break; + } + case M_Ternary: + { + STARTTm(tm); // start timer + for (lines = 0; lines < Delta; lines++, StrNumb++) + { + GETSTRING(PCurStr, Strlen); + Strlen = Pdt[StrNumb].dt_strlen; + PCurStr = Pdt[StrNumb].dt_string; + + TernaryIns(&Ternary, PCurStr, Strlen); + } + ENDTm(DeltaUSec, tm); // end timer + break; + } + default: + assert(0); // cant happen + break; + } + ENDmem(DeltaMem); // current malloc() mem usage + + ReadLin = StrNumb; // adjust delta + if (ReadLin > TValues) + ReadLin = TValues; +// if (Delta > TValues) +// ReadLin = Delta; // use the Delta + + Printf(" %11lu", StrNumb); // Total stored + Printf(" %10lu", ReadLin); // Number to read back + Begin = gStored - Begin; // actual STORED + assert(lines == Delta); + Printf(" %8lu", Delta - Begin); // Duplicate strings + +// Average time per line to store (including duplicate strings) + Mult = DeltaUSec / (double)Delta; + + if (Mult < Pms[grp].ms_mininsert) + Pms[grp].ms_mininsert = Mult; + + Printf(" %7.3f", Mult); + +// Bytes allocated thru malloc() + if (TotalJudyMalloc == 0) + Pms[grp].ms_Bytes = (double)DeltaMem; + else + Pms[grp].ms_Bytes = (double)(TotalJudyMalloc * sizeof(Word_t)); + + Pms[grp].ms_Bytes /= (double)gStored; + + fflush(stdout); + +//======================================================================= +// READ BACK LOOP +//======================================================================= + + Pdts = Pdt; // Strings to 'Get' + gChainln = 0; // total chain lengths + + if (rFlag == 0) + { + Randomize(Pdt, StrNumb); // Randomize ONLY those stored + + if (CFlag) + { +// Allocate and make sequencial string buffer + Pdts = BuildSeqBuf(Pdt, ReadLin); + } + } + switch (Method) + { + case M_Print: + break; + case M_Hash: + { + STARTTm(tm); // start timer + for (lines = 0; lines < ReadLin; lines++) + { + GETSTRING(PCurStr, Strlen); + Strlen = Pdts[lines].dt_strlen; + PCurStr = Pdts[lines].dt_string; + + PValue = HashGet(HRoot, PCurStr, Strlen); // get string + assert(PValue != NULL); + assert(*PValue > 0); + } + ENDTm(DeltaUSec, tm); // end timer + break; + } + case M_JLHash: + { + STARTTm(tm); // start timer + for (lines = 0; lines < ReadLin; lines++) + { + GETSTRING(PCurStr, Strlen); + Strlen = Pdts[lines].dt_strlen; + PCurStr = Pdts[lines].dt_string; + + PValue = JLHashGet(JLHash, PCurStr, Strlen); // get string + assert(PValue != NULL); + assert(*PValue > 0); + } + ENDTm(DeltaUSec, tm); // end timer + break; + } + case M_JudySL: + { + STARTTm(tm); // start timer + for (lines = 0; lines < ReadLin; lines++) + { + GETSTRING(PCurStr, Strlen); + PCurStr = Pdts[lines].dt_string; + + JSLG(PValue, JudySL, PCurStr); // get string + assert(PValue != NULL); + assert(*PValue > 0); + } + ENDTm(DeltaUSec, tm); // end timer + break; + } + case M_JudyHS: + { + STARTTm(tm); // start timer + for (lines = 0; lines < ReadLin; lines++) + { + GETSTRING(PCurStr, Strlen); + Strlen = Pdts[lines].dt_strlen; + PCurStr = Pdts[lines].dt_string; + + JHSG(PValue, JudyHS, PCurStr, Strlen); // get string + assert(PValue != NULL); + assert(*PValue > 0); + } + ENDTm(DeltaUSec, tm); // end timer + break; + } + +// NOTE: the ADT's below here are so slow, that I did not add much effort +// to clean them up. (dlb) + + case M_Splay: + { + STARTTm(tm); // start timer + for (lines = 0; lines < ReadLin; lines++) + { + GETSTRING(PCurStr, Strlen); + PCurStr = Pdts[lines].dt_string; + + splaysearch(&spans, (char *)PCurStr); + } + ENDTm(DeltaUSec, tm); // end timer + break; + } + case M_Redblack: + { + STARTTm(tm); // start timer + for (lines = 0; lines < ReadLin; lines++) + { + GETSTRING(PCurStr, Strlen); + PCurStr = Pdts[lines].dt_string; + + redblacksearch(&rbans, (char *)PCurStr); + } + ENDTm(DeltaUSec, tm); // end timer + break; + } + case M_Ternary: + { + STARTTm(tm); // start timer + for (lines = 0; lines < ReadLin; lines++) + { + GETSTRING(PCurStr, Strlen); + Strlen = Pdts[lines].dt_strlen; + PCurStr = Pdts[lines].dt_string; + + if (TernaryGet(Ternary, PCurStr, Strlen) == 0) + { + printf("\n OOps - Ternary Bug at Line = %d\n", + __LINE__); + exit(1); + } + } + ENDTm(DeltaUSec, tm); // end timer + break; + } + default: + assert(0); // cant happen + break; + } + Mult = DeltaUSec / (double)ReadLin; + +// save least value + if (Mult < Pms[grp].ms_minretrive) + Pms[grp].ms_minretrive = Mult; + + Printf(" %7.3f", Mult); // RETRIVE per string + Printf(" %9.6f", (double)gChainln / (double)ReadLin); + +// RAM USED PER STRING TO STORE DATA + + Printf(" %13.1f", (double)Pms[grp].ms_Bytes); + Printf("\n"); + fflush(stdout); + } + if (Method == M_Print) + exit(0); + + Printf("# Total Duplicate strings = %lu\n", nStrg - gStored); + +//======================================================================= +// Delete loop +//======================================================================= + + DeltaUSec = -1.0; // set deleted flag + + if (rFlag == 0) + { + Randomize(Pdt, StrNumb); // Randomize ONLY those stored + } + switch (Method) + { + case M_JudySL: + { + if (DFlag) + { + Printf("# Begin JudySLDel() loop...\n"); + STARTTm(tm); // start timer + for (lines = 0; lines < nStrg; lines++) + { + int Rc; + GETSTRING(PCurStr, Strlen); + PCurStr = Pdt[lines].dt_string; + JSLD(Rc, JudySL, PCurStr); // delete string + assert(Rc != JERR); + } + ENDTm(DeltaUSec, tm); // end timer + } + else + { + Printf("# Begin JudySLFreeArray()...\n"); + STARTTm(tm); // start timer + JSLFA(Bytes, JudySL); + ENDTm(DeltaUSec, tm); // end timer + } + break; + } + case M_JudyHS: + { + if (DFlag) + { + int Rc; + Printf("# Begin JudyHSDel() loop..."); + STARTTm(tm); // start timer + for (lines = 0; lines < nStrg; lines++) + { + GETSTRING(PCurStr, Strlen); + Strlen = Pdt[lines].dt_strlen; + PCurStr = Pdt[lines].dt_string; + JHSD(Rc, JudyHS, PCurStr, Strlen); // Delete string + assert(Rc != JERR); + } + ENDTm(DeltaUSec, tm); // end timer + } + else + { + Printf("# Begin JudyHSFreeArray()...\n"); + STARTTm(tm); // start timer + JHSFA(Bytes, JudyHS); + ENDTm(DeltaUSec, tm); // end timer + } + break; + } + case M_Hash: + { + if (DFlag) + { + Printf("# Begin HashDel() loop...\n"); + STARTTm(tm); // start timer + for (lines = 0; lines < nStrg; lines++) + { + GETSTRING(PCurStr, Strlen); + Strlen = Pdt[lines].dt_strlen; + PCurStr = Pdt[lines].dt_string; + HashDel(&HRoot, PCurStr, Strlen); // Delete string + } + ENDTm(DeltaUSec, tm); // end timer + } + else + { + Printf("# Begin HashFreeArray()...\n"); + STARTTm(tm); // start timer + Bytes = HashFreeArray(&HRoot); + ENDTm(DeltaUSec, tm); // end timer + } + break; + } + case M_JLHash: + { + if (DFlag) + { + Printf("# Begin JLHashDel() loop...\n"); + STARTTm(tm); // start timer + for (lines = 0; lines < nStrg; lines++) + { + GETSTRING(PCurStr, Strlen); + Strlen = Pdt[lines].dt_strlen; + PCurStr = Pdt[lines].dt_string; + JLHashDel(&JLHash, PCurStr, Strlen); // Delete string + } + ENDTm(DeltaUSec, tm); // end timer + } + else + { + Printf("# Begin JLHashFreeArray()...\n"); + STARTTm(tm); // start timer + Bytes = JLHashFreeArray(&JLHash); + ENDTm(DeltaUSec, tm); // end timer + } + break; + } + default: + printf("# Delete not implemented yet, so quit\n"); + Passes = 1; // No, delete, so quit + break; + } +// average time per line to delete (including duplicate strings) + if (Bytes) // Measured freed bytes? + { + Printf("# returned %lu bytes\n", Bytes); + } + if (TotalJudyMalloc) // Any bytes left after free? + { + printf + ("# !!! BUG, %lu bytes not deleted in *Free()\n", + TotalJudyMalloc * sizeof(Word_t)); + } + if (DeltaUSec != -1.0) // Measured how long to free? + { + Printf("# Free %lu strings, %0.3f uSecs Ave/string\n", + gStored, DeltaUSec / (double)gStored); + } + Printf("\n"); + } + + if (Passes != 1) + { + printf("# TotInserts 0 0 InsTime GetTime 0 Ram/String\n"); + StrNumb = 0; + for (grp = 0; grp < Groups; grp++) + { + StrNumb += Pms[grp].ms_delta; + + printf(" %11lu", StrNumb); // Total stored + printf(" 0 0"); // place holder + printf(" %7.3f", Pms[grp].ms_mininsert); + printf(" %7.3f", Pms[grp].ms_minretrive); + printf(" 0"); // place holder + printf(" %7.3f", Pms[grp].ms_Bytes); + printf("\n"); + } + } + exit(0); // done +} // main() diff --git a/feeds/p4/libjudy/src/test/jbgraph b/feeds/p4/libjudy/src/test/jbgraph new file mode 100755 index 000000000..564b2d889 --- /dev/null +++ b/feeds/p4/libjudy/src/test/jbgraph @@ -0,0 +1,1022 @@ +#!/bin/sh + +# THIS SCRIPT IS A "WRAPPER" FOR: gnuplot +# +# - The data used is in "gnuplot" format to compare and contrast +# - information for analysis in the Judy project. Circa: 05/12/2000. + +# Author: Bob Gobeille, # Original functionality. +# Jer/ Eberhard, # Ongoing maintenance, added functionality. + + RCS_SCRIPT=' +# @(#) $Revision: 2.24 $ $Source: /judy/src/apps/benchmark/jbgraph $ +' + + +# SET VERBOSE TO QUIET, SILENT (DEFAULT): +# +# - then find out if verbose mode is to be set. + + OPT_v="${OPT_v:--q}" # Set verbose off, (default). + v='eval #' # Set verbose off, (quiet). + + VERBOSE="`echo ${*} | tr ' ' '\012' | grep -- -v`" + if [ "${VERBOSE}" = "-v" ]; then # -v verbose mode on. + OPT_v="${VERBOSE}" # Will be "-v". + v="" # Set verbose on. + fi + unset VERBOSE # Unset after last use. + + +# CREATE NAMESPACE: +# +# - Set names of OUTPUT and WORK directories and files. + + C="`basename ${0:-jbgraph}`" # Command name of this script. + C_PATH="${0}" # Called via this path. + C_rc=".${C}.rc" # .rc file, local or ${HOME}. + OUTPUT_DIR=./tmp/`echo ${C} | tr "[a-z]" "[A-Z]"` # output name in caps + + mkdir -p ${OUTPUT_DIR} # Create output directory. + if [ ! -d "${OUTPUT_DIR}" ]; then # Ensure dir exists. + echo "${C}.${0}: ERROR, unable to: mkdir -p ${OUTPUT_DIR}" + exit 3 + fi + + +# UNCOMMENT THE DATE_TIME FORMAT YOU WANT TO USE: + + #DATE_TIME="`date +%y%m`" # Monthly Date/Time stamp. + #DATE_TIME="`date +%y%m%d`" # Daily Date/Time stamp. + DATE_TIME="`date +%y%m%d.%H%M`" # HourMinute Date/Time stamp. + + COMMAND="${OUTPUT_DIR}/${DATE_TIME}" # Output filename date/time stamp. + WORK1="${COMMAND}.WORK1.$$" # Work file 1. + WORK2="${COMMAND}.WORK2.$$" # Work file 2. + WORK3="${COMMAND}.WORK3.$$" # Work file 3. + WORK4="${COMMAND}.WORK4.$$" # Work file 4. + + +# CREATE AND DISPLAY SCRIPT DEFAULTS AND INFO: + + export GNU_CMDFILE="${GNU_CMDFILE:-$COMMAND.GNU_CMDFILE}" # GNU_CMDFILE name + ${v}touch ${COMMAND} # Ensure the output file exists. + # Produce sample monitor and print commands. + INFO="`echo \"${C}: follow output, or print by: + rerun by executing the first commented line in: + ${GNU_CMDFILE} + head -1 ${GNU_CMDFILE} # or + tail -f ${COMMAND} # tail and follow log file or + tail ${COMMAND} # tail log file or print: + fold -80 ${COMMAND} | + pr -f -l66 -h${COMMAND} | + remsh jerslash -l jer lp -odouble -o2\"`" + if [ "${OPT_v}" = "-v" ]; then # -v verbose mode. + echo "${INFO}" + fi + + +# DEFINE DEFAULTS, CONSTANTS, VARIABLES: +# +# - 80 Column line---------------------------------------------------01234567890 + +# Break line: BL is 70 columns of "-". + + BL="----------------------------------------------------------------------" + + EXT_OPT="${EXT_OPT:-}" # Allow external option setting. + +# GNU_GEOMETRY default: +# - Note, this will respect an environment variable, which could be set as: +# - export OPT_JBGRAPH_geometry="600x450+20+20" # 4x3 aspect ratio. + + OPT_JBGRAPH_geometry="${OPT_JBGRAPH_geometry:-1000x750+20+20}" + GNU_GEOMETRY_DEF="1000x750+20+20" # 4x3 aspect ratio, default. + GNU_GEOMETRY="-geometry ${OPT_JBGRAPH_geometry:-$GNU_GEOMETRY_DEF}" + +# GNU_PSFILE name, (default): + + GNU_PSFILE="${OPT_JBGRAPH_psfile:-$COMMAND.GNU_PSFILE}" + + LP_DEV_DEF="${LP_DEV:-pastel}" # Printer device (default). + LP_OPT_DEF="${LP_OPT:--olandscape}" # Printer options (default). + +# PLOT AXIS NAMES: + + XLABEL="${XLABEL:-Population}" # Set default. + YLABEL_MALLOC="${YLABEL:-Bytes}" # Set default. + YLABEL_TIME="${YLABEL:-USec/index}" # Set default. + YLABEL="${YLABEL:-$YLABEL_TIME}" # Set default. + +# ARRAY OF COLUMN NAMES: +# +# - Add column names here (from benchutils.c). +# - These are the column names displayed on "gnuplot". + + CHA[0]="CHA=COLUMN HEADINGS ARRAY" + CHA[1]="index number" + CHA[2]="insert time per index" + CHA[3]="dT/dI insert" + CHA[4]="retrieve time per index" + CHA[5]="dT/dI retrieve" + CHA[6]="bytes used" + CHA[8]="bytes free" + CHA[9]="bytes alloced" + CHA[7]="dM/dI change in memory per index" + CHA[10]="leaf count" + CHA[11]="leaf average size" + CHA[12]="leaf memory used per index" + CHA[13]="branch count" + CHA[14]="branch average size" + CHA[15]="branch memory used per index" + CHA[16]="" + CHA[17]="" + CHA[18]="" + CHA[19]="" + CHA[21]="" + CHA[22]="" + CHA[23]="" + CHA[24]="" + CHA[25]="" + CHA[26]="" + CHA[27]="" + CHA[28]="" + CHA[29]="" + CHA[30]="" + CHA[31]="" + CHA[32]="" + CHA[33]="" + CHA[34]="" + CHA[35]="" + CHA[36]="" + CHA[37]="" + CHA[38]="" + CHA[39]="" + CHA[40]="" + CHA[41]="" + CHA[42]="" + CHA[43]="" + CHA[44]="" + CHA[45]="" + CHA[46]="" + CHA[47]="" + CHA[48]="" + CHA[49]="" + CHA[50]="" + + CMN="0" # Column number for CHA data. + +# +# SET DEFAULT OPTIONS: +# + + OPT_E="-E" # -E use embedded options + OPT_L="-L" # -L set logscale axis + OPT_L_xaxis="x" # -L set logscale x axis + OPT_L_yaxis="y" # -L set logscale y axis + OPT_H="-H" # -H default column headings. + + +# M A I N: MAIN PROGRAM: +# +# - Begin main script, functions first. + +{ + +FUNCTION__getopt() # Use function getopt. +{ +# PARSE THE COMMAND LINE FOR OPTIONS, USING GETOPT: +# +# - define USAGE message. +# - use getopts. +# Note: FUNCTION__getopt is run twice, in order to support: +# FUNCTION_TITLE_COLHEAD() # Set Column headings from file. + + ${v}echo "${C}.${0}: beginning at `date`" # beginning of function + + USAGE="${C} [ -E -G -H -I -M -S -V -i -l -m -q -r -u -v ] + [ -C GNU_CMDFILE ] + [ -D LP_DEV ] + [ -L axis ] + [ -N not option ] (turn off option), Example: -NL + [ -P GNU_PSFILE ] + [ -c COLUMN_NUMBER ] + [ -d differential_type ] + [ -g GNU_GEOMETRY ] + [ -o LP_OPT ] + [ -x xRANGE ] + [ -y yRANGE ] + + ${C}: wrapper for gnuplot + + -c plot column number. This is useful to plot by column number. + -i plot insert; default if no other plots selected. CMN=2 + -r plot retrievals; default if no other plots selected. CMN=4 + -I plot memory used / index. CMN=12 + -m plot memory malloced. CMN=9 + -M plot memory used and free. CMN=8 + -l plot leaf data. CMN=11 + -d plot derivative data. Useful with -i, -r, -m. CMN=2,4,9 + + -x xRANGE, scale range; example: -x [1000:5000] or -x1000:5000 + -y yRANGE, scale range; example: -y [1M:10M] or -y1M:10M + 1[kK] = 1,000; 1[mM] = 1,000,000; 1[gG] = 1,000,000,000. + + -n number plot descriptions; Use column numbers before the description. + -L set logscale axis; default, + Example: Turn off logscale with -NL, then turn on, on only one axis: + \"-NL -Lx\" or \"-NL -Ly\", Turn off both with -NL + -G grid lines on. + -H default column headings. + -g geometry description. + default=\"${GNU_GEOMETRY_DEF}\", # 4x3 aspect ratio. + + -E use embedded options, default, Turn off with -NE. + Sets TITLE, COLHEAD, GETOPT from the FIRST data file encountered. + Example: embedded options in the data file begin in column 1: + # TITLE This is the title to pass to gnuplot + # COLHEAD 1 This is the heading for column 1. + # XLABEL This is the x-axis label + # YLABEL This is the y-axis label + # GETOPT -c2 -c3 -G # These are the options to use. + + -p print the plot. + -o LP_OPT printer option(s); default \"${LP_OPT_DEF}\". + Example: \"-ootray2\" will print on clear slides, emits \"-otray2\" + Example: \"-on2\" will print two copies, emits \"-n2\" + -D LP_DEV printer device; default \"${LP_DEV_DEF}\". + + -C GNU_CMDFILE name; default is generated and removed: + ${OUTPUT_DIR}/{DATE_TIME}.GNU_CMDFILE + Useful to do your own gnuplot command editing and debugging. + -P GNU_PSFILE name. default is generated and removed: + ${OUTPUT_DIR}/{DATE_TIME}.GNU_PSFILE + -S Save files. + Generated and working file names are deleted unless -S or -C is on. + User provided file names are not deleted in any case (-C, -P). + + -q quiet mode, verbose mode off; default. + -v verbose mode on. + + -V vi the plot file. + quit using \"q\" + + -N not option; Turn specified option off. Example: -NL + Note, -N is not available for all options. + -NL Turn off: -L set logscale axis; default + -NH Turn off: -H default column headings. + + -u Usage message. + + Sample usage: + ${C} -i -f data/datafile # -i is the same as -c1. + ${C} -c1 -f data/datafile # -i is the same as -c1. + + " + + ${v}echo "${C}.${0}: OPTIONS=${*}" + +# Parse options, using getopt: +# +# - "a" option, no parameter; "b:" indicates a parameter. +# - Order of options is "man 5 ascii". + + getopt_PARM="?C:D:EGIL:MN:P:SVc:d:g:ilmno:prsuvx:y:" + set -- `getopt ${getopt_PARM} $*` # Place options in argc/argv. + if [ "${?}" != "0" ]; then # If getopt returns an errror. + ${v}echo "${C}.${0}: \${?}=${?}, USAGE message from return code." + echo "${USAGE}" + exit 1 + fi + + while [ ${#} -gt 0 ] # while there are options... + do # ( for vi parenthesis matching + ${v}echo "${C}.${0}: parsing option \"${1}\", then \"${2}\"" + case ${1} in + + -C) + OPT_C="${1}" + OPT_C_PARM="${2}" # GNU_CMDFILE name. + ${v}echo "${C}.${0}: OPT_C=${OPT_C}, # -C GNU_CMDFILE name." + ${v}echo "${C}.${0}: OPT_C_PARM=${OPT_C_PARM}, # GNU_CMDFILE name." + export GNU_CMDFILE="${OPT_C_PARM}" + MSG="# GNU_CMDFILE name." + ${v}echo "${C}.${0}: GNU_CMDFILE=${GNU_CMDFILE}, ${MSG}" + shift + ;; # ( for vi parenthesis matching + + -D) + OPT_D="${1}" + OPT_D_PARM="${2}" # LP_DEV name. + ${v}echo "${C}.${0}: OPT_D=${OPT_D}, # -D LP_DEV printer device." + #${v}echo "${C}.${0}: OPT_D_PARM=${OPT_D_PARM}, # LP_DEV name." + LP_DEV="${OPT_D_PARM}" + ${v}echo "${C}.${0}: LP_DEV=${LP_DEV}, # LP_DEV name." + shift + ;; # ( for vi parenthesis matching + + -E) + OPT_E="${1}" + ${v}echo "${C}.${0}: OPT_E=${OPT_E}, # -E use embedded options" + ;; # ( for vi parenthesis matching + + -G) + OPT_G="${1}" + ${v}echo "${C}.${0}: OPT_G=${OPT_G}, # -G grid lines on." + ;; # ( for vi parenthesis matching + + -H) + OPT_H="${1}" + ${v}echo "${C}.${0}: OPT_H=${OPT_H}, # -H default column headings." + ;; # ( for vi parenthesis matching + + -I) + OPT_I="${1}" + ${v}echo "${C}.${0}: OPT_I=${OPT_I}, # -I Memory used / index." + CMN="12" + COL[$CMN]="${CMN}" + ${v}echo "${C}.${0}: COL[$CMN]=${COL[$CMN]}" + ;; # ( for vi parenthesis matching + + -L) + OPT_L="${1}" + ${v}echo "${C}.${0}: OPT_L=${OPT_L}, -L set logscale axis" + OPT_L_PARM="${2}" # axis name, x or y + if [ ${OPT_L_PARM} = "x" ]; then + OPT_L_xaxis="${OPT_L_PARM}" + elif [ ${OPT_L_PARM} = "y" ]; then + OPT_L_yaxis="${OPT_L_PARM}" + else + MSG="must be either \"x\" or \"y\" axis. exit 5" + echo "${C}.${0}: ERROR, OPT_L_PARM=${OPT_L_PARM} ${MSG}" + exit 5 + fi + OPT_NL="" # -L turn off -NL. + shift + ;; # ( for vi parenthesis matching + + -M) + OPT_M="${1}" + ${v}echo "${C}.${0}: OPT_M=${OPT_M}, # -M Memory used and free." + CMN="8" + COL[$CMN]="${CMN}" + ${v}echo "${C}.${0}: COL[$CMN]=${COL[$CMN]}" + ;; # ( for vi parenthesis matching + + -N) + OPT_N="${1}" + OPT_N_PARM="${2}" # LP_DEV name. + ${v}echo "${C}.${0}: OPT_N=${OPT_N}, # -N not option" + ${v}echo "${C}.${0}: OPT_N_PARM=${OPT_N_PARM}, # Turn option off." + if [ "${OPT_N_PARM}" = "E" ]; then + OPT_E="" # -E use embedded options + OPT_NE="-NE" # -NE turn off -E. + elif [ "${OPT_N_PARM}" = "L" ]; then + OPT_L="" # -L set logscale axis + OPT_L_xaxis="" + OPT_L_yaxis="" + OPT_NL="-NL" # -NL turn off -L. + elif [ "${OPT_N_PARM}" = "G" ]; then + OPT_G="" # -G grid lines on. + OPT_NG="-NG" # -NG turn off -G. + elif [ "${OPT_N_PARM}" = "H" ]; then + OPT_H="" # -H default column headings. + OPT_NH="-NH" # -NH turn off -H. + fi + shift + ;; # ( for vi parenthesis matching + + -P) + OPT_P="${1}" + OPT_P_PARM="${2}" # GNU_PSFILE name. + ${v}echo "${C}.${0}: OPT_P=${OPT_P}, # -P GNU_PSFILE name." + #${v}echo "${C}.${0}: OPT_P_PARM=${OPT_P_PARM}, # GNU_PSFILE name." + GNU_PSFILE="${OPT_P_PARM}" + ${v}echo "${C}.${0}: GNU_PSFILE=${GNU_PSFILE}, # GNU_PSFILE name." + shift + ;; # ( for vi parenthesis matching + + -S) + OPT_S="${1}" + ${v}echo "${C}.${0}: OPT_S=${OPT_S}, # -S save files." + ;; # ( for vi parenthesis matching + + -V) + OPT_V="${1}" + ${v}echo "${C}.${0}: OPT_V=${OPT_V}, # -V vi the plot file." + ;; # ( for vi parenthesis matching + + -c) + OPT_c="${1}" + OPT_c_PARM="${2}" # COLUMN_NUMBER. + ${v}echo "${C}.${0}: OPT_c=${OPT_c}, # -c plot column number." + ${v}echo "${C}.${0}: OPT_c_PARM=${OPT_c_PARM}, # COLUMN_NUMBER." + if [ ${OPT_c_PARM} -ge ${#CHA[*]} ] || + [ ${OPT_c_PARM} -le 0 ]; then + MSG="must be greater than 0 and less than ${#CHA[*]}. exit 6" + echo "${C}.${0}: ERROR, OPT_c_PARM=${OPT_c_PARM} ${MSG}" + exit 6 + fi + CMN="${OPT_c_PARM}" + COL[$CMN]="${CMN}" + ${v}echo "${C}.${0}: COL[$CMN]=${COL[$CMN]}" + shift + ;; # ( for vi parenthesis matching + + -d) + OPT_d="${1}" + OPT_d_PARM="${2}" # DERIVATIVE_TYPE + ${v}echo "${C}.${0}: OPT_d=${OPT_d}, # -d plot derivative type." + ${v}echo "${C}.${0}: OPT_d_PARM=${OPT_d_PARM}, # DERIVITIVE_TYPE" + if [ "${OPT_d_PARM}" = "i" ]; then + OPT_di="${OPT_d_PARM}" + CMN="3" + elif [ "${OPT_d_PARM}" = "m" ]; then + OPT_dm="${OPT_d_PARM}" + CMN="7" + elif [ "${OPT_d_PARM}" = "r" ]; then + OPT_dr="${OPT_d_PARM}" + CMN="5" + else + echo "${C}.${0}: ERROR, ${OPT_d_PARM} must be one of i, m, r." + fi + COL[$CMN]="${CMN}" + ${v}echo "${C}.${0}: COL[$CMN]=${COL[$CMN]}" + shift + ;; # ( for vi parenthesis matching + + -g) + OPT_g="${1}" + OPT_g_PARM="${2}" # Option parameter + ${v}echo "${C}.${0}: OPT_g=${OPT_g}, # -g geometry description." + ${v}echo "${C}.${0}: OPT_g_PARM=${OPT_g_PARM}, # window geometry" + GNU_GEOMETRY="-geometry ${OPT_g_PARM}" # Environment geometry. + MSG="# window geometry" + ${v}echo "${C}.${0}: GNU_GEOMETRY=${GNU_GEOMETRY}, ${MSG}" + shift + ;; # ( for vi parenthesis matching + + -i) + OPT_i="${1}" + ${v}echo "${C}.${0}: OPT_i=${OPT_i}, # -i plot insert." + CMN="2" + COL[$CMN]="${CMN}" + ${v}echo "${C}.${0}: COL[$CMN]=${COL[$CMN]}" + ;; # ( for vi parenthesis matching + + -l) + OPT_l="${1}" + ${v}echo "${C}.${0}: OPT_l=${OPT_l}, # -l plot leaf data." + CMN="10" + COL[$CMN]="${CMN}" + ${v}echo "${C}.${0}: COL[$CMN]=${COL[$CMN]}" + CMN="11" + COL[$CMN]="${CMN}" + ${v}echo "${C}.${0}: COL[$CMN]=${COL[$CMN]}" + ;; # ( for vi parenthesis matching + + -m) + OPT_m="${1}" + ${v}echo "${C}.${0}: OPT_m=${OPT_m}, # -m plot memory malloced." + CMN="9" + COL[$CMN]="${CMN}" + ${v}echo "${C}.${0}: COL[$CMN]=${COL[$CMN]}" + ;; # ( for vi parenthesis matching + + -n) + OPT_n="${1}" + MSG="# -n number plot descriptions." + ${v}echo "${C}.${0}: OPT_n=${OPT_n}, ${MSG}" + ;; # ( for vi parenthesis matching + + -o) + OPT_o="${1}" + OPT_o_PARM="${2}" # Option parameter + MSG="# -o LP_OPT printer option(s)." + ${v}echo "${C}.${0}: OPT_o=${OPT_o}, ${MSG}" + MSG="# -o LP_OPT printer option(s)." + ${v}echo "${C}.${0}: OPT_o_PARM=${OPT_o_PARM}, ${MSG}" + # Check for duplicates, only add to LP_OPT if not a duplicate. + LP_SET="`echo ${LP_OPT} | adjust -m1 | grep -- -${OPT_o_PARM}`" + if [ "${LP_SET}" != "-${OPT_o_PARM}" ]; + then + LP_OPT="${LP_OPT} -${OPT_o_PARM}" + fi + unset LP_SET + ${v}echo "${C}.${0}: LP_OPT=${LP_OPT}, # LP_OPT printer option(s)." + shift + ;; # ( for vi parenthesis matching + + -p) + OPT_p="${1}" + ${v}echo "${C}.${0}: OPT_p=${OPT_p}, # -p print the plot." + ;; # ( for vi parenthesis matching + + -q) + OPT_v="${1}" + v='eval #' # Set verbose off (quiet). + ${v}echo "${C}.${0}: OPT_v=${OPT_v}, # -q quiet mode." + ;; # ( for vi parenthesis matching + + -r) + OPT_r="${1}" + ${v}echo "${C}.${0}: OPT_r=${OPT_r}, # -r plot retrieve." + CMN="4" + COL[$CMN]="${CMN}" + ${v}echo "${C}.${0}: COL[$CMN]=${COL[$CMN]}" + ;; # ( for vi parenthesis matching + + -v) + OPT_v="${1}" + v="" # Set verbose on. + ${v}echo "${C}.${0}: OPT_v=${OPT_v}, # -v verbose mode." + ${v}echo + ;; # ( for vi parenthesis matching + + -x) + OPT_x="${1}" + OPT_x_PARM="${2}" # Option parameter + ${v}echo "${C}.${0}: OPT_x=${OPT_x}, # -x xRANGE, scale range." + #${v}echo "${C}.${0}: OPT_x_PARM=${OPT_x_PARM}, # parameter desc." + xRANGE="${OPT_x_PARM}" + ${v}echo "${C}.${0}: xRANGE=${xRANGE}, # parameter desc." + shift + ;; # ( for vi parenthesis matching + + -y) + OPT_y="${1}" + OPT_y_PARM="${2}" # Option parameter + ${v}echo "${C}.${0}: OPT_y=${OPT_y}, # -y yRANGE, scale range." + #${v}echo "${C}.${0}: OPT_y_PARM=${OPT_y_PARM}, # parameter desc." + yRANGE="${OPT_y_PARM}" + ${v}echo "${C}.${0}: yRANGE=${yRANGE}, # parameter desc." + shift + ;; # ( for vi parenthesis matching + + -u) + OPT_u="-u" + ${v}echo "${C}.${0}: OPT_u=${OPT_u}, # -u Usage message." + echo "${USAGE}" + exit 4 + ;; # ( for vi parenthesis matching + + -a) + OPT_a="${1}" + ${v}echo "${C}.${0}: OPT_a=${OPT_a}, # -a Option description." + ;; # ( for vi parenthesis matching + + -b) + OPT_b="${1}" + OPT_b_PARM="${2}" # Option parameter + ${v}echo "${C}.${0}: OPT_b=${OPT_b}, # -b Option description." + ${v}echo "${C}.${0}: OPT_b_PARM=${OPT_b_PARM}, # parameter desc." + shift + ;; # ( for vi parenthesis matching + + --) + shift # Remove the "--". + break + ;; # ( for vi parenthesis matching + + *) + echo "${C}.${0}: Option not understood. \"${1}\"" + echo "USAGE message follows: " + echo "${USAGE}" # USAGE message + exit 2 + ;; + + esac + shift + done + +# The rest of the command line parameters are files: + + # If FILES is already set, leave it alone, else set it. + # This is necessary due running getopt twice, to support parameters + # embedded in the data files. + if [ "${FILES}" = "" ]; then + FILES="${FILES} ${*}" # May result in a blank, " ". + if [ "${FILES}" = " " ]; then # If blank, " ", make it empty. + FILES="" # Make FILES empty again. + fi + ${v}echo "${C}.${0}: FILES=${FILES}" + fi + +# Set default options, if no applicable plot options were set. + COL_CTR="${#COL[*]}" # Columns were turned on. + ${v}echo "COL_CTR=${COL_CTR}, COL=${COL[*]}" + + if [ "${COL_CTR}" = "0" ]; then # Option not set + ${v}echo "${C}.${0}: Setting default options." + FUNCTION__getopt -c2 -c4 # Set default, if no options set. + fi + if [ "${OPT_C}" = "-C" ] || # If -C or -P, ensure -S. + [ "${OPT_P}" = "-P" ]; then + if [ "${OPT_S}" != "-S" ]; then + FUNCTION__getopt -S # -S save files. + fi + fi + +# Save a shar copy of this script, if -S and -v are both on. +# Turned off, may be useful later. + +# if [ ! -z "${OPT_S}" ] && # -S save files. +# [ "${OPT_v}" = "-v" ]; then # -v verbose mode. +# ${v}echo "${C}.${0}: start of shar of script" +# shar -b ${C_PATH} >>${COMMAND}.shar +# ${v}echo "${C}.${0}: end of shar of script\n" +# fi + + ${v}echo "${C}.${0}: completed at `date`\n" # end of function +} # FUNCTION__getopt() # Use function getopt. + +FUNCTION_gnuplot_init() # Initialize gnuplot command file. +{ +# INITIALIZE GNU_CMDFILE +# +# - Pass options to gnuplot. +# - Some options for gnuplot are set here (logscale, autoscale). + + ${v}echo "${C}.${0}: beginning at `date`" # beginning of function + { + echo "# ${C_PATH} ${*}" + echo "# gnuplot ${GNU_GEOMETRY} ${GNU_CMDFILE}" + if [ "${OPT_L}" = "-L" ]; then # -L set logscale axis + echo "set logscale ${OPT_L_xaxis}${OPT_L_yaxis}" + fi + echo "set autoscale xy" + echo "set data style lines" + if [ ! -z "${OPT_G}" ]; then # Turn on grids. + echo "set grid" + fi + +# Naming convention... build some kind of TITLE name, if none given. + + TITLE="${TITLE:-JUDY BENCHMARK: $CMD_LINE }" # Set default. + + echo "set title \"${TITLE}\" 0,0 " + if [ "${xRANGE}" != "" ]; then + echo "set xrange `FUNCTION_units ${xRANGE}`" + XLABEL="${XLABEL} ${xRANGE}" + fi + if [ "${yRANGE}" != "" ]; then + echo "set yrange `FUNCTION_units ${yRANGE}`" + YLABEL="${YLABEL} ${yRANGE}" + fi + echo "set xlabel \"${XLABEL}\" 0,0" + echo "set ylabel \"${YLABEL}\" 0,0" + echo "set label \"${XLOG}\" at 1,1" + } >> ${GNU_CMDFILE} + + ${v}echo "${C}.${0}: completed at `date`\n" # end of function +} # FUNCTION_gnuplot_init() # Initialize gnuplot command file. + +FUNCTION_gnuplot_plot() # Plot these files. +{ +# FORMAT THE PLOT AND REPLOT COMMANDS +# +# - output to GNU_CMDFILE. + + ${v}echo "${C}.${0}: beginning at `date`" # beginning of function + ${v}echo "${C}.${0}: FILES=${*}" + + Fgp_PARM="${*}" # Save what was passed in. + Fgp_FILES="" # Initialize list of good files. + for i in ${Fgp_PARM} + do + if [ -r "$i" ]; then # Check that files are readable. + Fgp_FILES="${Fgp_FILES} ${i}" # Extend the list of good files. + else + echo "${C}.${0}: WARNING: file: ${i} cannot be read, ignored." + fi + done + + let j=1 + while [ ${j} -lt ${#CHA[*]} ] # For each type of plot. + do + for i in ${Fgp_FILES} # For each file. + do + CMN="${COL[$j]}" + if [ ! -z "${CMN}" ]; then + { + MSG="`basename ${i}`" + if [ "${OPT_H}" = "-H" ]; then + echo "${FIRST}plot \"${i}\" using 1:${CMN} t \"${CHA[${CMN}]} ${MSG}\"" + elif [ "${OPT_NH}" = "-NH" ]; then + echo "${FIRST}plot \"${i}\" using 1:${CMN} t \"${MSG}\"" + fi + } >> ${GNU_CMDFILE} + FIRST="re" + fi + done + let j=j+1 + done + +# A bug in gnuplot sometimes prevents all replots from appearing. +# This particularly happens when xrange is used. +# Doing an extra replot will plot everything. + echo replot >> ${GNU_CMDFILE} + + ${v}echo "${C}.${0}: completed at `date`\n" # end of function +} # FUNCTION_gnuplot_plot() # Plot these files. + +FUNCTION_gnuplot_display() # Plots the datapoints. +{ +# DISPLAY PLOT TO SCREEN: + + ${v}echo "${C}.${0}: beginning at `date`" # beginning of function + + if [ "${OPT_V}" = "-V" ]; then + echo "hpterm -e vi -c \"vi ${GNU_CMDFILE} \"" + hpterm -e vi -cvi ${GNU_CMDFILE} & + fi + + if [ "${OPT_v}" = "-v" ]; then # -v verbose mode. + echo "${C}.${0}: executing command: "; echo "\n\ + gnuplot ${GNU_GEOMETRY} ${GNU_CMDFILE}" + fi + +# Add additional parameters as necessary to setup for printing: + if [ "${OPT_p}" = "-p" ]; then + { + echo set terminal postscript landscape color + echo set output \"${GNU_PSFILE}\" + echo replot + } >> ${GNU_CMDFILE} + fi + + LINE="" # External response + while [ "${LINE}" != "q" ] + do + gnuplot ${GNU_GEOMETRY} ${GNU_CMDFILE} + LINE="q" # Setup for quit. + if [ "${OPT_V}" = "-V" ]; then + echo "Pause: press return to vi again, \"q\" to quit ${C}" + read -r LINE + fi + done + + ${v}echo "${C}.${0}: completed at `date`\n" # end of function +} # FUNCTION_gnuplot_display() # Plots the datapoints. + +FUNCTION_gnuplot_print() # -p print the plot. +{ +# +# PRINT THE PLOT. +# +# - uses gnuplot command "replot". + + ${v}echo "${C}.${0}: beginning at `date`" # beginning of function + ${v}echo "${C}.${0}: OPT_p=${OPT_p}, # -p print the plot." + ${v}echo "${C}.${0}: OPT_P=${OPT_P}, # GNU_PSFILE name." + GNU_PSFILE="${GNU_PSFILE:-$GNU_PSFILE_DEF}" + ${v}echo "${C}.${0}: GNU_PSFILE=${GNU_PSFILE}, # GNU_PSFILE name." + + LP_DEV_PARM="-d ${LP_DEV:-$LP_DEV_DEF}" # Printer device parameter. + LP_OPT_PARM="${LP_OPT:-$LP_OPT_DEF}" # Printer option parameters. + + echo "${C}.${0}: executing command: "; echo "\n\ + echo lp ${LP_DEV_PARM} ${LP_OPT_PARM} ${GNU_PSFILE}" + + lp ${LP_DEV_PARM} ${LP_OPT_PARM} ${GNU_PSFILE} + + ${v}echo "${C}.${0}: completed at `date`\n" # end of function +} # FUNCTION_gnuplot_print() # Print the plot. + +FUNCTION_TITLE_COLHEAD() # Set Column headings from file. +{ +# +# Parse the TITLE and COLUMN HEADINGS (CHA) from the data, if available. +# Also parse other settable parameters, if available. +# + + ${v}echo "${C}.${0}: beginning at `date`" # beginning of function + FTC_FILES="${*}" # Local list of file names. + ${v}echo "${C}.${0}: FTC_FILES=${FTC_FILES}" + + # Choose the first readable file. + unset FTC_FILE # Hold the first readable filename. + for F in ${FTC_FILES} /dev/null # /dev/null ensures there is a file. + do + if [ -r "${F}" ] && # Is this file readable? + [ "${FTC_FILE}" = "" ]; then # We do not have one yet? + FTC_FILE="${F}" # Hold the first readable filename. + fi + done + + # If FTC_FILE got set, use it to find TITLE, COLHEAD, XLABEL, YLABEL, et.al. + if [ "${FTC_FILE}" != "" ]; then # Use this file. + # Grab the FIRST TITLE line (head -1) and use it. + TITLE="`grep '^# *TITLE' ${FTC_FILE} | head -1 | + sed -e 's/^# *TITLE *//g'`" + ${v}echo "${C}.${0}: TITLE=${TITLE}" + + # Grab the FIRST XLABEL line (head -1) and use it. + XLABEL="`grep '^# *XLABEL' ${FTC_FILE} | head -1 | + sed -e 's/^# *XLABEL *//g'`" + ${v}echo "${C}.${0}: XLABEL=${XLABEL}" + + # Grab the FIRST YLABEL line (head -1) and use it. + YLABEL="`grep '^# *YLABEL' ${FTC_FILE} | head -1 | + sed -e 's/^# *YLABEL *//g'`" + ${v}echo "${C}.${0}: YLABEL=${YLABEL}" + + # Find each COLHEAD, and put it in the correct CHA[INDEX]. + let i=0 + while [ ${i} -lt ${#CHA[*]} ] # For each COLHEAD + do + # Grab one COLHEAD line at a time, put it into CHA[]. + # Note, "@" not allowed in COLHEAD string. + LINE="`grep \"^#.*COLHEAD\" ${FTC_FILE} | # Find COLHEAD. + sed -e 's/^#.*COLHEAD*//g' \ + -e 's/^ *//g' \ + -e 's/@//g' | # Remove COLHEAD. + expand | sed -e 's/^0*//g' | # Remove leading zeros. + grep ^${i} | # Find a line matching ${i}. + head -1 `" # Make sure there is only 1. + + # Grab the INDEX number, could do numeric check if problems. + INDEX="`echo ${LINE} | cut -d\" \" -f1`" # field 1 is number. + + # If INDEX is not empty, save this COLHEAD. + if [ "${INDEX}" != "" ]; then + # Grab the rest of the line and save it into CHA. + REMAINDER="`echo ${LINE} | sed -e \"s@^${INDEX} *@@g\"`" + CHA[${INDEX}]="${REMAINDER}" + ${v}echo "${C}.${0}: CHA[${INDEX}]=\"${CHA[${INDEX}]}\"" + fi + + let i=i+1 + done + + # GETOPT, pull in options to be set for this data. + GETOPT="`grep '^# *GETOPT' ${FTC_FILE} | head -1 | + sed -e 's/^# *GETOPT *//g'`" + if [ "${GETOPT}" != "" ]; then + FUNCTION__getopt ${GETOPT} # Parse the options. + fi + unset GETOPT + + fi + + ${v}echo "${C}.${0}: completed at `date`\n" # end of function +} # FUNCTION_TITLE_COLHEAD() # Set Column headings from file. + +FUNCTION_n() # -n number plot descriptions. +{ +# ADD COLUMN NUMBER TO EACH ELEMENT IN CHA: +# +# - This is done for comparing plots, and/or debugging. + + ${v}echo "${C}.${0}: beginning at `date`" # beginning of function + ${v}echo "${C}.${0}: OPT_n=${OPT_n}, # -n number plot descriptions" + + let i=0 + while [ ${i} -lt ${#CHA[*]} ] + do + CHA[${i}]="${i} ${CHA[${i}]}" + ${v}echo "${C}.${0}: CHA[${i}]=\"${CHA[${i}]}\"" + let i=i+1 + done + ${v}echo "${C}.${0}: completed at `date`\n" # end of function +} # FUNCTION_n() # -n number plot descriptions. + +FUNCTION_units() # Resolve units. +{ +# +# Expand units of the form 1K to 1000, 1M to 1000000, et.al. +# Used to format the gnuplot parameters xRANGE and yRANGE. +# gnuplot data format: "set xrange [1:1000000]" +# + + Fu_IN="${1}" # Units in. + echo "["${Fu_IN}"]" | + sed -e "s/[kK]/000/g" | # 1,000 + sed -e "s/[mM]/000000/g" | # 1,000,000 + sed -e "s/[gG]/000000000/g" | # 1,000,000,000 + sed -e "s/^\[\[/\["/g | # Ensure single leading bracket. + sed -e "s/\]\]$/\]"/g # Ensure single trailing bracket. +} + +FUNCTION_a() # -a Option description. +{ +# +# Replace with description of this function. +# + + ${v}echo "${C}.${0}: beginning at `date`" # beginning of function + ${v}echo "${C}.${0}: OPT_a=${OPT_a}, # -a Option description." + ${v}echo "${C}.${0}: completed at `date`\n" # end of function +} # + +FUNCTION_b() # -b Option description. +{ +# +# Replace with description of this function. +# + + ${v}echo "${C}.${0}: beginning at `date`" # beginning of function + ${v}echo "${C}.${0}: OPT_b=${OPT_b}, # -b Option description." + MSG="# -b Parameter description." + ${v}echo "${C}.${0}: OPT_b_PARM=${OPT_b_PARM}, ${MSG}" + + if [ -r "${OPT_b_PARM}" ]; then # Ensure this is a file. + echo ${OPT_b_PARM} | + while read -r FILE; do + ${v}echo "${C}.${0}: FILE=${FILE}" + done + else # Or use elif (form of elseif). + ${v}echo "${C}.${0}: ERROR, ${OPT_b_PARM} is not a readable file." + fi + + ${v}echo "${C}.${0}: completed at `date`\n" # end of function +} # + + +# +# MAIN: Main driver, main processing occurs here. +# + + + ${v}echo " \n${C}: beginning at `date`" # page overflow with each start. + + CMD_LINE="${0} ${*}" # Save command called and options. + + FUNCTION__getopt ${*} # Parse the options. + + if [ -z "${OPT_NE}" ] && # Not E is not turned on and E is... + [ ! -z "${OPT_E}" ]; then # -E use embedded options + FUNCTION_TITLE_COLHEAD ${FILES} # Set Column headings from file. + fi + + FUNCTION__getopt ${*} >/dev/null 2>&1 # Parse the options. + + type banner >/dev/null 2>&1 # Check if banner exists. + RC="${?}" # Save return code. + if [ "${RC}" = "0" ]; then # if RC=0, banner exists. + ${v}banner ${C} + fi + + ${v}echo "${C}: RCS_SCRIPT=${RCS_SCRIPT}" + ${v}echo "${C}: PWD=${PWD}" + + if [ ! -z "${OPT_n}" ]; then + FUNCTION_n # -n number plot descriptions. + fi + + # If GNU_CMDFILE exists, use it, do not create it. + if [ ! -f ${GNU_CMDFILE} ]; then # ! -f = if this is not a file. + if [ "${FILES}" = "" ]; then # If no files available + MSG="and GNU_CMDFILE is not a file exit 7" + echo "${C}: ERROR: no FILES to plot! ${MSG}" + exit 7 + break + fi + FUNCTION_gnuplot_init ${*} # Initialize gnuplot command file. + + FUNCTION_gnuplot_plot ${FILES} # Plot these files. + + echo pause -1 \'Pause: press return to continue.\' >> ${GNU_CMDFILE} + echo # Place blank line in log file. + fi + + FUNCTION_gnuplot_display # Plots the datapoints. + + + if [ ! -z "${OPT_p}" ]; then + FUNCTION_gnuplot_print # -p print the plot. + fi + + +# REMOVE FILES, CLEANUP: +# +# Remove the working files and filenames, unless "-S" is on. + + if [ "${OPT_S}" = "-S" ]; then # -S save files. + echo "${C}: saving ${COMMAND}" + echo "${C}: saving ${GNU_CMDFILE}" + if [ "${OPT_p}" = "-p" ]; then + echo "${C}: saving ${GNU_PSFILE}" + fi + else + rm -f ${COMMAND} # Remove generated log file. + rm -f ${GNU_CMDFILE} # Remove generated command file. + rm -f ${GNU_PSFILE} # Remove generated .ps file. + fi + + rm -fr ${COMMAND}.WORK*.$$ # Remove generated work files. + + ${v}echo "${C}: completed at `date`\n^L" + +# Message if -v (verbose): + + if [ "${OPT_v}" = "-v" ]; then # -v verbose mode. + echo "${INFO}" + fi + +# DONE: +# +# - If a log file needs to be kept, uncomment the corresponding (): + +} 2>&1 | tee -a ${COMMAND} # Use during testing. +#) >>${COMMAND} 2>&1 & # Use for production. diff --git a/feeds/p4/libjudy/src/test/malloc-pre2.8a.c b/feeds/p4/libjudy/src/test/malloc-pre2.8a.c new file mode 100644 index 000000000..d2de33718 --- /dev/null +++ b/feeds/p4/libjudy/src/test/malloc-pre2.8a.c @@ -0,0 +1,5387 @@ +/* + [insert usage description etc here] + + preliminary version 2.8.x +*/ + +/* + WIN32 sets up defaults for MS environment and compilers. + Otherwise defaults are for unix. +*/ + +/* #define WIN32 */ + +#ifdef WIN32 + +#define WIN32_LEAN_AND_MEAN +#include + +/* No-op failure action */ +#define MALLOC_FAILURE_ACTION + +/* Win32 doesn't supply or need the following headers */ +#define LACKS_UNISTD_H +#define LACKS_SYS_PARAM_H +#define LACKS_SYS_MMAN_H + +/* Use the supplied emulation of sbrk */ +#define MORECORE sbrk +#define MORECORE_CONTIGUOUS 1 +#define MORECORE_FAILURE ((void*)(-1)) + +/* Use the supplied emulation of mmap and munmap */ +#define HAVE_MMAP 1 +#define MUNMAP_FAILURE (-1) +#define MMAP_CLEARS 1 + +/* These values don't really matter in windows mmap emulation */ +#define MAP_PRIVATE 1 +#define MAP_ANONYMOUS 2 +#define PROT_READ 1 +#define PROT_WRITE 2 + +/* Emulation functions defined at the end of this file */ + +/* If USE_MALLOC_LOCK, use supplied critical-section-based lock functions */ +#ifdef USE_MALLOC_LOCK +static int slwait(int *sl); +static int slrelease(int *sl); +#endif + +static long getpagesize(void); +static long getregionsize(void); +static void *sbrk(long size); +static void *mmap(void *ptr, long size, long prot, long type, long handle, long arg); +static long munmap(void *ptr, long size); + +static void vminfo (unsigned long*free, unsigned long*reserved, unsigned long*committed); +static int cpuinfo (int whole, unsigned long*kernel, unsigned long*user); + +#endif + + +#include + +/* + Void_t* is the pointer type that malloc should say it returns +*/ + +#ifndef Void_t +#define Void_t void +#endif /*Void_t*/ + +#include /* for size_t */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* define LACKS_UNISTD_H if your system does not have a . */ + +/* #define LACKS_UNISTD_H */ + +#ifndef LACKS_UNISTD_H +#include +#endif + +/* define LACKS_SYS_PARAM_H if your system does not have a . */ + +/* #define LACKS_SYS_PARAM_H */ + + +#include /* needed for malloc_stats */ +#include /* needed for optional MALLOC_FAILURE_ACTION */ + + +/* + Debugging: + + Because freed chunks may be overwritten with bookkeeping fields, this + malloc will often die when freed memory is overwritten by user + programs. This can be very effective (albeit in an annoying way) + in helping track down dangling pointers. + + If you compile with -DDEBUG, a number of assertion checks are + enabled that will catch more memory errors. You probably won't be + able to make much sense of the actual assertion errors, but they + should help you locate incorrectly overwritten memory. The + checking is fairly extensive, and will slow down execution + noticeably. Calling malloc_stats or mallinfo with DEBUG set will + attempt to check every non-mmapped allocated and free chunk in the + course of computing the summmaries. (By nature, mmapped regions + cannot be checked very much automatically.) + + Setting DEBUG may also be helpful if you are trying to modify + this code. The assertions in the check routines spell out in more + detail the assumptions and invariants underlying the algorithms. + + Setting DEBUG does NOT provide an automated mechanism for checking + that all accesses to malloced memory stay within their + bounds. However, there are several add-ons and adaptations of this + or other mallocs available that do this. +*/ + +#if DEBUG +#include +/* #define assert(x) if(!(x)) abort() */ + +#else +#define assert(x) ((void)0) +#endif + +/* + The unsigned integer type used for comparing any two chunk sizes. + This should be at least as wide as size_t, but should not be signed. +*/ + +#ifndef CHUNK_SIZE_T +#define CHUNK_SIZE_T unsigned long +#endif + +#define MAX_CHUNK_SIZE ((CHUNK_SIZE_T)(-1UL)) + +/* + The unsigned integer type used to hold addresses when they are are + manipulated as integers. Except that it is not defined on all + systems, intptr_t would suffice. +*/ +#ifndef PTR_UINT +#define PTR_UINT unsigned long +#endif + + +/* + INTERNAL_SIZE_T is the word-size used for internal bookkeeping + of chunk sizes. + + The default version is the same as size_t. + + While not strictly necessary, it is best to define this as an + unsigned type, even if size_t is a signed type. This may avoid some + artificial size limitations on some systems. + + On a 64-bit machine, you may be able to reduce malloc overhead by + defining INTERNAL_SIZE_T to be a 32 bit `unsigned int' at the + expense of not being able to handle more than 2^32 of malloced + space. If this limitation is acceptable, you are encouraged to set + this unless you are on a platform requiring 16byte alignments. In + this case the alignment requirements turn out to negate any + potential advantages of decreasing size_t word size. + + Implementors: Beware of the possible combinations of: + - INTERNAL_SIZE_T might be signed or unsigned, might be 32 or 64 bits, + and might be the same width as int or as long + - size_t might have different width and signedness as INTERNAL_SIZE_T + - int and long might be 32 or 64 bits, and might be the same width + To deal with this, most comparisons and difference computations + among INTERNAL_SIZE_Ts should cast them to CHUNK_SIZE_T, being + aware of the fact that casting an unsigned int to a wider long does + not sign-extend. (This also makes checking for negative numbers + awkward.) Some of these casts result in harmless compiler warnings + on some systems. +*/ + +#ifndef INTERNAL_SIZE_T +#define INTERNAL_SIZE_T size_t +#endif + +/* The corresponding word size */ +#define SIZE_SZ (sizeof(INTERNAL_SIZE_T)) + + + +/* + MALLOC_ALIGNMENT is the minimum alignment for malloc'ed chunks. + It must be a power of two at least 2 * SIZE_SZ, even on machines + for which smaller alignments would suffice. It may be defined as + larger than this though. Note however that code and data structures + are optimized for the case of 8-byte alignment. +*/ + + +#ifndef MALLOC_ALIGNMENT +#define MALLOC_ALIGNMENT (2 * SIZE_SZ) +#endif + +/* The corresponding bit mask value */ +#define MALLOC_ALIGN_MASK (MALLOC_ALIGNMENT - 1) + + + +/* + REALLOC_ZERO_BYTES_FREES should be set if a call to + realloc with zero bytes should be the same as a call to free. + Some people think it should. Otherwise, since this malloc + returns a unique pointer for malloc(0), so does realloc(p, 0). +*/ + +/* #define REALLOC_ZERO_BYTES_FREES */ + +/* + TRIM_FASTBINS controls whether free() of a very small chunk can + immediately lead to trimming. Setting to true (1) can reduce memory + footprint, but will almost always slow down programs that use a lot + of small chunks. + + Define this only if you are willing to give up some speed to more + aggressively reduce system-level memory footprint when releasing + memory in programs that use many small chunks. You can get + essentially the same effect by setting MXFAST to 0, but this can + lead to even greater slowdowns in programs using many small chunks. + TRIM_FASTBINS is an in-between compile-time option, that disables + only those chunks bordering topmost memory from being placed in + fastbins. +*/ + +#ifndef TRIM_FASTBINS +#define TRIM_FASTBINS 0 +#endif + + +/* + USE_DL_PREFIX will prefix all public routines with the string 'dl'. + This is necessary when you only want to use this malloc in one part + of a program, using your regular system malloc elsewhere. +*/ + +/* #define USE_DL_PREFIX */ + + +/* + USE_MALLOC_LOCK causes wrapper functions to surround each + callable routine with pthread mutex lock/unlock. + + USE_MALLOC_LOCK forces USE_PUBLIC_MALLOC_WRAPPERS to be defined +*/ + +/* #define USE_MALLOC_LOCK */ + + +/* + If USE_PUBLIC_MALLOC_WRAPPERS is defined, every public routine is + actually a wrapper function that first calls MALLOC_PREACTION, then + calls the internal routine, and follows it with + MALLOC_POSTACTION. This is needed for locking, but you can also use + this, without USE_MALLOC_LOCK, for purposes of interception, + instrumentation, etc. It is a sad fact that using wrappers often + noticeably degrades performance of malloc-intensive programs. +*/ + +#ifdef USE_MALLOC_LOCK +#define USE_PUBLIC_MALLOC_WRAPPERS +#else +/* #define USE_PUBLIC_MALLOC_WRAPPERS */ +#endif + + +/* + Two-phase name translation. + All of the actual routines are given mangled names. + When wrappers are used, they become the public callable versions. + When DL_PREFIX is used, the callable names are prefixed. +*/ + +#ifndef USE_PUBLIC_MALLOC_WRAPPERS +#define cALLOc public_cALLOc +#define fREe public_fREe +#define cFREe public_cFREe +#define mALLOc public_mALLOc +#define mEMALIGn public_mEMALIGn +#define rEALLOc public_rEALLOc +#define vALLOc public_vALLOc +#define pVALLOc public_pVALLOc +#define mALLINFo public_mALLINFo +#define mALLOPt public_mALLOPt +#define mTRIm public_mTRIm +#define mSTATs public_mSTATs +#define mUSABLe public_mUSABLe +#define iCALLOc public_iCALLOc +#define iCOMALLOc public_iCOMALLOc +#endif + +#ifdef USE_DL_PREFIX +#define public_cALLOc dlcalloc +#define public_fREe dlfree +#define public_cFREe dlcfree +#define public_mALLOc dlmalloc +#define public_mEMALIGn dlmemalign +#define public_rEALLOc dlrealloc +#define public_vALLOc dlvalloc +#define public_pVALLOc dlpvalloc +#define public_mALLINFo dlmallinfo +#define public_mALLOPt dlmallopt +#define public_mTRIm dlmalloc_trim +#define public_mSTATs dlmalloc_stats +#define public_mUSABLe dlmalloc_usable_size +#define public_iCALLOc dlindependent_calloc +#define public_iCOMALLOc dlindependent_comalloc +#else /* USE_DL_PREFIX */ +#define public_cALLOc calloc +#define public_fREe free +#define public_cFREe cfree +#define public_mALLOc malloc +#define public_mEMALIGn memalign +#define public_rEALLOc realloc +#define public_vALLOc valloc +#define public_pVALLOc pvalloc +#define public_mALLINFo mallinfo +#define public_mALLOPt mallopt +#define public_mTRIm malloc_trim +#define public_mSTATs malloc_stats +#define public_mUSABLe malloc_usable_size +#define public_iCALLOc independent_calloc +#define public_iCOMALLOc independent_comalloc +#endif /* USE_DL_PREFIX */ + + +/* + HAVE_MEMCPY should be defined if you are not otherwise using + ANSI STD C, but still have memcpy and memset in your C library + and want to use them in calloc and realloc. Otherwise simple + macro versions are defined below. + + USE_MEMCPY should be defined as 1 if you actually want to + have memset and memcpy called. People report that the macro + versions are faster than libc versions on some systems. + + Even if USE_MEMCPY is set to 1, loops to copy/clear small chunks + (of <= 36 bytes) are manually unrolled in realloc and calloc. +*/ + +#define HAVE_MEMCPY + +#ifndef USE_MEMCPY +#ifdef HAVE_MEMCPY +#define USE_MEMCPY 1 +#else +#define USE_MEMCPY 0 +#endif +#endif + + +#if (defined(HAVE_MEMCPY)) +#ifdef WIN32 +/* On Win32 memset and memcpy are already declared in windows.h */ +#else +void* memset(void*, int, size_t); +void* memcpy(void*, const void*, size_t); +#endif +#endif + +/* + MALLOC_FAILURE_ACTION is the action to take before "return 0" when + malloc fails to be able to return memory, either because memory is + exhausted or because of illegal arguments. + + By default, sets errno if running on STD_C platform, else does nothing. +*/ + +#ifndef MALLOC_FAILURE_ACTION +#define MALLOC_FAILURE_ACTION \ + errno = ENOMEM; +#endif + +/* + MORECORE-related declarations. By default, rely on sbrk +*/ + + +#ifdef LACKS_UNISTD_H +#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) +extern Void_t* sbrk(ptrdiff_t); +#endif +#endif + +/* + MORECORE is the name of the routine to call to obtain more memory + from the system. See below for general guidance on writing + alternative MORECORE functions, as well as a version for WIN32 and a + sample version for pre-OSX macos. +*/ + +#ifndef MORECORE +#define MORECORE sbrk +#endif + +/* + MORECORE_FAILURE is the value returned upon failure of MORECORE + as well as mmap. Since it cannot be an otherwise valid memory address, + and must reflect values of standard sys calls, you probably ought not + try to redefine it. +*/ + +#ifndef MORECORE_FAILURE +#define MORECORE_FAILURE (-1) +#endif + +/* + If MORECORE_CONTIGUOUS is true, take advantage of fact that + consecutive calls to MORECORE with positive arguments always return + contiguous increasing addresses. This is true of unix sbrk. Even + if not defined, when regions happen to be contiguous, malloc will + permit allocations spanning regions obtained from different + calls. But defining this when applicable enables some stronger + consistency checks and space efficiencies. +*/ + +#ifndef MORECORE_CONTIGUOUS +#define MORECORE_CONTIGUOUS 1 +#endif + +/* + Define MORECORE_CANNOT_TRIM if your version of MORECORE + cannot release space back to the system when given negative + arguments. This is generally necessary only if you are using + a hand-crafted MORECORE function that cannot handle negative arguments. +*/ + +/* #define MORECORE_CANNOT_TRIM */ + + +/* + Define HAVE_MMAP as true to optionally make malloc() use mmap() to + allocate very large blocks. These will be returned to the + operating system immediately after a free(). Also, if mmap + is available, it is used as a backup strategy in cases where + MORECORE fails to provide space from system. + + This malloc is best tuned to work with mmap for large requests. + If you do not have mmap, operations involving very large chunks (1MB + or so) may be slower than you'd like. +*/ + +#define HAVE_MMAP 0 + +#ifndef HAVE_MMAP +#define HAVE_MMAP 1 +#endif + +#if HAVE_MMAP +/* + Standard unix mmap using /dev/zero clears memory so calloc doesn't + need to. +*/ + +#ifndef MMAP_CLEARS +#define MMAP_CLEARS 1 +#endif + +#else /* no mmap */ +#ifndef MMAP_CLEARS +#define MMAP_CLEARS 0 +#endif +#endif + + +/* + MMAP_AS_MORECORE_SIZE is the minimum mmap size argument to use if + sbrk fails, and mmap is used as a backup (which is done only if + HAVE_MMAP). The value must be a multiple of page size. This + backup strategy generally applies only when systems have "holes" in + address space, so sbrk cannot perform contiguous expansion, but + there is still space available on system. On systems for which + this is known to be useful (i.e. most linux kernels), this occurs + only when programs allocate huge amounts of memory. Between this, + and the fact that mmap regions tend to be limited, the size should + be large, to avoid too many mmap calls and thus avoid running out + of kernel resources. +*/ + +#ifndef MMAP_AS_MORECORE_SIZE +#define MMAP_AS_MORECORE_SIZE (1024 * 1024) +#endif + +/* + Define HAVE_MREMAP to make realloc() use mremap() to re-allocate + large blocks. This is currently only possible on Linux with + kernel versions newer than 1.3.77. +*/ + +#ifndef HAVE_MREMAP +#ifdef linux +#define HAVE_MREMAP 1 +#else +#define HAVE_MREMAP 0 +#endif + +#endif /* HAVE_MMAP */ + + +/* + The system page size. To the extent possible, this malloc manages + memory from the system in page-size units. Note that this value is + cached during initialization into a field of malloc_state. So even + if malloc_getpagesize is a function, it is only called once. + + The following mechanics for getpagesize were adapted from bsd/gnu + getpagesize.h. If none of the system-probes here apply, a value of + 4096 is used, which should be OK: If they don't apply, then using + the actual value probably doesn't impact performance. +*/ + +#ifndef malloc_getpagesize + +#ifndef LACKS_UNISTD_H +# include +#endif + +# ifdef _SC_PAGESIZE /* some SVR4 systems omit an underscore */ +# ifndef _SC_PAGE_SIZE +# define _SC_PAGE_SIZE _SC_PAGESIZE +# endif +# endif + +# ifdef _SC_PAGE_SIZE +# define malloc_getpagesize sysconf(_SC_PAGE_SIZE) +# else +# if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE) + extern size_t getpagesize(); +# define malloc_getpagesize getpagesize() +# else +# ifdef WIN32 /* use supplied emulation of getpagesize */ +# define malloc_getpagesize getpagesize() +# else +# ifndef LACKS_SYS_PARAM_H +# include +# endif +# ifdef EXEC_PAGESIZE +# define malloc_getpagesize EXEC_PAGESIZE +# else +# ifdef NBPG +# ifndef CLSIZE +# define malloc_getpagesize NBPG +# else +# define malloc_getpagesize (NBPG * CLSIZE) +# endif +# else +# ifdef NBPC +# define malloc_getpagesize NBPC +# else +# ifdef PAGESIZE +# define malloc_getpagesize PAGESIZE +# else /* just guess */ +# define malloc_getpagesize (4096) +# endif +# endif +# endif +# endif +# endif +# endif +# endif +#endif + +/* + This version of malloc supports the standard SVID/XPG mallinfo + routine that returns a struct containing usage properties and + statistics. It should work on any SVID/XPG compliant system that has + a /usr/include/malloc.h defining struct mallinfo. (If you'd like to + install such a thing yourself, cut out the preliminary declarations + as described above and below and save them in a malloc.h file. But + there's no compelling reason to bother to do this.) + + The main declaration needed is the mallinfo struct that is returned + (by-copy) by mallinfo(). The SVID/XPG malloinfo struct contains a + bunch of fields that are not even meaningful in this version of + malloc. These fields are are instead filled by mallinfo() with + other numbers that might be of interest. + + HAVE_USR_INCLUDE_MALLOC_H should be set if you have a + /usr/include/malloc.h file that includes a declaration of struct + mallinfo. If so, it is included; else an SVID2/XPG2 compliant + version is declared below. These must be precisely the same for + mallinfo() to work. The original SVID version of this struct, + defined on most systems with mallinfo, declares all fields as + ints. But some others define as unsigned long. If your system + defines the fields using a type of different width than listed here, + you must #include your system version and #define + HAVE_USR_INCLUDE_MALLOC_H. +*/ + +/* #define HAVE_USR_INCLUDE_MALLOC_H */ + +#ifdef HAVE_USR_INCLUDE_MALLOC_H +#include "/usr/include/malloc.h" +#else + +/* SVID2/XPG mallinfo structure */ + +struct mallinfo { + int arena; /* non-mmapped space allocated from system */ + int ordblks; /* number of free chunks */ + int smblks; /* number of fastbin blocks */ + int hblks; /* number of mmapped regions */ + int hblkhd; /* space in mmapped regions */ + int usmblks; /* maximum total allocated space */ + int fsmblks; /* space available in freed fastbin blocks */ + int uordblks; /* total allocated space */ + int fordblks; /* total free space */ + int keepcost; /* top-most, releasable (via malloc_trim) space */ +}; + +/* + SVID/XPG defines four standard parameter numbers for mallopt, + normally defined in malloc.h. Only one of these (M_MXFAST) is used + in this malloc. The others (M_NLBLKS, M_GRAIN, M_KEEP) don't apply, + so setting them has no effect. But this malloc also supports other + options in mallopt described below. +*/ +#endif + + +/* ---------- description of public routines ------------ */ + +/* + malloc(size_t n) + Returns a pointer to a newly allocated chunk of at least n bytes, or null + if no space is available. Additionally, on failure, errno is + set to ENOMEM on ANSI C systems. + + If n is zero, malloc returns a minumum-sized chunk. (The minimum + size is 16 bytes on most 32bit systems, and 24 or 32 bytes on 64bit + systems.) On most systems, size_t is an unsigned type, so calls + with negative arguments are interpreted as requests for huge amounts + of space, which will often fail. The maximum supported value of n + differs across systems, but is in all cases less than the maximum + representable value of a size_t. +*/ +Void_t* public_mALLOc(size_t); + +/* + free(Void_t* p) + Releases the chunk of memory pointed to by p, that had been previously + allocated using malloc or a related routine such as realloc. + It has no effect if p is null. It can have arbitrary (i.e., bad!) + effects if p has already been freed. + + Unless disabled (using mallopt), freeing very large spaces will + when possible, automatically trigger operations that give + back unused memory to the system, thus reducing program footprint. +*/ +void public_fREe(Void_t*); + +/* + calloc(size_t n_elements, size_t element_size); + Returns a pointer to n_elements * element_size bytes, with all locations + set to zero. +*/ +Void_t* public_cALLOc(size_t, size_t); + +/* + realloc(Void_t* p, size_t n) + Returns a pointer to a chunk of size n that contains the same data + as does chunk p up to the minimum of (n, p's size) bytes, or null + if no space is available. + + The returned pointer may or may not be the same as p. The algorithm + prefers extending p when possible, otherwise it employs the + equivalent of a malloc-copy-free sequence. + + If p is null, realloc is equivalent to malloc. + + If space is not available, realloc returns null, errno is set (if on + ANSI) and p is NOT freed. + + if n is for fewer bytes than already held by p, the newly unused + space is lopped off and freed if possible. Unless the #define + REALLOC_ZERO_BYTES_FREES is set, realloc with a size argument of + zero (re)allocates a minimum-sized chunk. + + Large chunks that were internally obtained via mmap will always + be reallocated using malloc-copy-free sequences unless + the system supports MREMAP (currently only linux). + + The old unix realloc convention of allowing the last-free'd chunk + to be used as an argument to realloc is not supported. +*/ + +Void_t* public_rEALLOc(Void_t*, size_t); + +/* + memalign(size_t alignment, size_t n); + Returns a pointer to a newly allocated chunk of n bytes, aligned + in accord with the alignment argument. + + The alignment argument should be a power of two. If the argument is + not a power of two, the nearest greater power is used. + 8-byte alignment is guaranteed by normal malloc calls, so don't + bother calling memalign with an argument of 8 or less. + + Overreliance on memalign is a sure way to fragment space. +*/ +Void_t* public_mEMALIGn(size_t, size_t); + +/* + valloc(size_t n); + Equivalent to memalign(pagesize, n), where pagesize is the page + size of the system. If the pagesize is unknown, 4096 is used. +*/ +Void_t* public_vALLOc(size_t); + + +/* + mallopt(int parameter_number, int parameter_value) + Sets tunable parameters The format is to provide a + (parameter-number, parameter-value) pair. mallopt then sets the + corresponding parameter to the argument value if it can (i.e., so + long as the value is meaningful), and returns 1 if successful else + 0. SVID/XPG/ANSI defines four standard param numbers for mallopt, + normally defined in malloc.h. Only one of these (M_MXFAST) is used + in this malloc. The others (M_NLBLKS, M_GRAIN, M_KEEP) don't apply, + so setting them has no effect. But this malloc also supports four + other options in mallopt. See below for details. Briefly, supported + parameters are as follows (listed defaults are for "typical" + configurations). + + Symbol param # default allowed param values + M_MXFAST 1 64 0-64 (0 disables fastbins) + M_TRIM_THRESHOLD -1 256*1024 any (-1U disables trimming) + M_TOP_PAD -2 0 any + M_MMAP_THRESHOLD -3 256*1024 any (or 0 if no MMAP support) + M_MMAP_MAX -4 65536 any (0 disables use of mmap) +*/ +int public_mALLOPt(int, int); + + +/* + mallinfo() + Returns (by copy) a struct containing various summary statistics: + + arena: current total non-mmapped bytes allocated from system + ordblks: the number of free chunks + smblks: the number of fastbin blocks (i.e., small chunks that + have been freed but not use resused or consolidated) + hblks: current number of mmapped regions + hblkhd: total bytes held in mmapped regions + usmblks: the maximum total allocated space. This will be greater + than current total if trimming has occurred. + fsmblks: total bytes held in fastbin blocks + uordblks: current total allocated space (normal or mmapped) + fordblks: total free space + keepcost: the maximum number of bytes that could ideally be released + back to system via malloc_trim. ("ideally" means that + it ignores page restrictions etc.) + + Because these fields are ints, but internal bookkeeping may + be kept as longs, the reported values may wrap around zero and + thus be inaccurate. +*/ +struct mallinfo public_mALLINFo(void); + +/* + independent_calloc(size_t n_elements, size_t element_size, Void_t* chunks[]); + + independent_calloc is similar to calloc, but instead of returning a + single cleared space, it returns an array of pointers to n_elements + independent elements that can hold contents of size elem_size, each + of which starts out cleared, and can be independently freed, + realloc'ed etc. The elements are guaranteed to be adjacently + allocated (this is not guaranteed to occur with multiple callocs or + mallocs), which may also improve cache locality in some + applications. + + The "chunks" argument is optional (i.e., may be null, which is + probably the most typical usage). If it is null, the returned array + is itself dynamically allocated and should also be freed when it is + no longer needed. Otherwise, the chunks array must be of at least + n_elements in length. It is filled in with the pointers to the + chunks. + + In either case, independent_calloc returns this pointer array, or + null if the allocation failed. If n_elements is zero and "chunks" + is null, it returns a chunk representing an array with zero elements + (which should be freed if not wanted). + + Each element must be individually freed when it is no longer + needed. If you'd like to instead be able to free all at once, you + should instead use regular calloc and assign pointers into this + space to represent elements. (In this case though, you cannot + independently free elements.) + + independent_calloc simplifies and speeds up implementations of many + kinds of pools. It may also be useful when constructing large data + structures that initially have a fixed number of fixed-sized nodes, + but the number is not known at compile time, and some of the nodes + may later need to be freed. For example: + + struct Node { int item; struct Node* next; }; + + struct Node* build_list() { + struct Node** pool; + int n = read_number_of_nodes_needed(); + if (n <= 0) return 0; + pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0); + if (pool == 0) die(); + // organize into a linked list... + struct Node* first = pool[0]; + for (i = 0; i < n-1; ++i) + pool[i]->next = pool[i+1]; + free(pool); // Can now free the array (or not, if it is needed later) + return first; + } +*/ +Void_t** public_iCALLOc(size_t, size_t, Void_t**); + +/* + independent_comalloc(size_t n_elements, size_t sizes[], Void_t* chunks[]); + + independent_comalloc allocates, all at once, a set of n_elements + chunks with sizes indicated in the "sizes" array. It returns + an array of pointers to these elements, each of which can be + independently freed, realloc'ed etc. The elements are guaranteed to + be adjacently allocated (this is not guaranteed to occur with + multiple callocs or mallocs), which may also improve cache locality + in some applications. + + The "chunks" argument is optional (i.e., may be null). If it is null + the returned array is itself dynamically allocated and should also + be freed when it is no longer needed. Otherwise, the chunks array + must be of at least n_elements in length. It is filled in with the + pointers to the chunks. + + In either case, independent_comalloc returns this pointer array, or + null if the allocation failed. If n_elements is zero and chunks is + null, it returns a chunk representing an array with zero elements + (which should be freed if not wanted). + + Each element must be individually freed when it is no longer + needed. If you'd like to instead be able to free all at once, you + should instead use a single regular malloc, and assign pointers at + particular offsets in the aggregate space. (In this case though, you + cannot independently free elements.) + + independent_comallac differs from independent_calloc in that each + element may have a different size, and also that it does not + automatically clear elements. + + independent_comalloc can be used to speed up allocation in cases + where several structs or objects must always be allocated at the + same time. For example: + + struct Head { ... } + struct Foot { ... } + + void send_message(char* msg) { + int msglen = strlen(msg); + size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) }; + void* chunks[3]; + if (independent_comalloc(3, sizes, chunks) == 0) + die(); + struct Head* head = (struct Head*)(chunks[0]); + char* body = (char*)(chunks[1]); + struct Foot* foot = (struct Foot*)(chunks[2]); + // ... + } + + In general though, independent_comalloc is worth using only for + larger values of n_elements. For small values, you probably won't + detect enough difference from series of malloc calls to bother. + + Overuse of independent_comalloc can increase overall memory usage, + since it cannot reuse existing noncontiguous small chunks that + might be available for some of the elements. +*/ +Void_t** public_iCOMALLOc(size_t, size_t*, Void_t**); + + +/* + pvalloc(size_t n); + Equivalent to valloc(minimum-page-that-holds(n)), that is, + round up n to nearest pagesize. + */ +Void_t* public_pVALLOc(size_t); + +/* + cfree(Void_t* p); + Equivalent to free(p). + + cfree is needed/defined on some systems that pair it with calloc, + for odd historical reasons (such as: cfree is used in example + code in the first edition of K&R). +*/ +void public_cFREe(Void_t*); + +/* + malloc_trim(size_t pad); + + If possible, gives memory back to the system (via negative + arguments to sbrk) if there is unused memory at the `high' end of + the malloc pool. You can call this after freeing large blocks of + memory to potentially reduce the system-level memory requirements + of a program. However, it cannot guarantee to reduce memory. Under + some allocation patterns, some large free blocks of memory will be + locked between two used chunks, so they cannot be given back to + the system. + + The `pad' argument to malloc_trim represents the amount of free + trailing space to leave untrimmed. If this argument is zero, + only the minimum amount of memory to maintain internal data + structures will be left (one page or less). Non-zero arguments + can be supplied to maintain enough trailing space to service + future expected allocations without having to re-obtain memory + from the system. + + Malloc_trim returns 1 if it actually released any memory, else 0. + On systems that do not support "negative sbrks", it will always + rreturn 0. +*/ +int public_mTRIm(size_t); + +/* + malloc_usable_size(Void_t* p); + + Returns the number of bytes you can actually use in + an allocated chunk, which may be more than you requested (although + often not) due to alignment and minimum size constraints. + You can use this many bytes without worrying about + overwriting other allocated objects. This is not a particularly great + programming practice. malloc_usable_size can be more useful in + debugging and assertions, for example: + + p = malloc(n); + assert(malloc_usable_size(p) >= 256); + +*/ +size_t public_mUSABLe(Void_t*); + +/* + malloc_stats(); + Prints on stderr the amount of space obtained from the system (both + via sbrk and mmap), the maximum amount (which may be more than + current if malloc_trim and/or munmap got called), and the current + number of bytes allocated via malloc (or realloc, etc) but not yet + freed. Note that this is the number of bytes allocated, not the + number requested. It will be larger than the number requested + because of alignment and bookkeeping overhead. Because it includes + alignment wastage as being in use, this figure may be greater than + zero even when no user-level chunks are allocated. + + The reported current and maximum system memory can be inaccurate if + a program makes other calls to system memory allocation functions + (normally sbrk) outside of malloc. + + malloc_stats prints only the most commonly interesting statistics. + More information can be obtained by calling mallinfo. + +*/ +void public_mSTATs(); + +/* mallopt tuning options */ + +/* + M_MXFAST is the maximum request size used for "fastbins", special bins + that hold returned chunks without consolidating their spaces. This + enables future requests for chunks of the same size to be handled + very quickly, but can increase fragmentation, and thus increase the + overall memory footprint of a program. + + This malloc manages fastbins very conservatively yet still + efficiently, so fragmentation is rarely a problem for values less + than or equal to the default. The maximum supported value of MXFAST + is 64 (also the default). You wouldn't want it any higher than this + anyway. Fastbins are designed especially for use with many small + structs, objects or strings -- the default handles + structs/objects/arrays with sizes up to 16 4byte fields, or small + strings representing words, tokens, etc. Using fastbins for larger + objects normally worsens fragmentation without improving speed. + + M_MXFAST is set in REQUEST size units. It is internally used in + chunksize units, which adds padding and alignment. You can reduce + M_MXFAST to 0 to disable all use of fastbins. This causes the malloc + algorithm to be a closer approximation of fifo-best-fit in all cases, + not just for larger requests, but will generally cause it to be + slower. +*/ + + +/* M_MXFAST is a standard SVID/XPG tuning option, usually listed in malloc.h */ +#ifndef M_MXFAST +#define M_MXFAST 1 +#endif + +#ifndef DEFAULT_MXFAST +#define DEFAULT_MXFAST 64 +#endif + + +/* + M_TRIM_THRESHOLD is the maximum amount of unused top-most memory + to keep before releasing via malloc_trim in free(). + + Automatic trimming is mainly useful in long-lived programs. + Because trimming via sbrk can be slow on some systems, and can + sometimes be wasteful (in cases where programs immediately + afterward allocate more large chunks) the value should be high + enough so that your overall system performance would improve by + releasing this much memory. + + The trim threshold and the mmap control parameters (see below) + can be traded off with one another. Trimming and mmapping are + two different ways of releasing unused memory back to the + system. Between these two, it is often possible to keep + system-level demands of a long-lived program down to a bare + minimum. For example, in one test suite of sessions measuring + the XF86 X server on Linux, using a trim threshold of 128K and a + mmap threshold of 192K led to near-minimal long term resource + consumption. + + If you are using this malloc in a long-lived program, it should + pay to experiment with these values. As a rough guide, you + might set to a value close to the average size of a process + (program) running on your system. Releasing this much memory + would allow such a process to run in memory. Generally, it's + worth it to tune for trimming rather tham memory mapping when a + program undergoes phases where several large chunks are + allocated and released in ways that can reuse each other's + storage, perhaps mixed with phases where there are no such + chunks at all. And in well-behaved long-lived programs, + controlling release of large blocks via trimming versus mapping + is usually faster. + + However, in most programs, these parameters serve mainly as + protection against the system-level effects of carrying around + massive amounts of unneeded memory. Since frequent calls to + sbrk, mmap, and munmap otherwise degrade performance, the default + parameters are set to relatively high values that serve only as + safeguards. + + The trim value must be greater than page size to have any useful + effect. To disable trimming completely, you can set to + (unsigned long)(-1) + + Trim settings interact with fastbin (MXFAST) settings: Unless + TRIM_FASTBINS is defined, automatic trimming never takes place upon + freeing a chunk with size less than or equal to MXFAST. Trimming is + instead delayed until subsequent freeing of larger chunks. However, + you can still force an attempted trim by calling malloc_trim. + + Also, trimming is not generally possible in cases where + the main arena is obtained via mmap. + + Note that the trick some people use of mallocing a huge space and + then freeing it at program startup, in an attempt to reserve system + memory, doesn't have the intended effect under automatic trimming, + since that memory will immediately be returned to the system. +*/ + +#define M_TRIM_THRESHOLD -1 + +#ifndef DEFAULT_TRIM_THRESHOLD + +#define DEFAULT_TRIM_THRESHOLD (-1U) +/* #define DEFAULT_TRIM_THRESHOLD (256 * 1024) */ +#endif + +/* + M_TOP_PAD is the amount of extra `padding' space to allocate or + retain whenever sbrk is called. It is used in two ways internally: + + * When sbrk is called to extend the top of the arena to satisfy + a new malloc request, this much padding is added to the sbrk + request. + + * When malloc_trim is called automatically from free(), + it is used as the `pad' argument. + + In both cases, the actual amount of padding is rounded + so that the end of the arena is always a system page boundary. + + The main reason for using padding is to avoid calling sbrk so + often. Having even a small pad greatly reduces the likelihood + that nearly every malloc request during program start-up (or + after trimming) will invoke sbrk, which needlessly wastes + time. + + Automatic rounding-up to page-size units is normally sufficient + to avoid measurable overhead, so the default is 0. However, in + systems where sbrk is relatively slow, it can pay to increase + this value, at the expense of carrying around more memory than + the program needs. +*/ + +#define M_TOP_PAD -2 + +#ifndef DEFAULT_TOP_PAD +#define DEFAULT_TOP_PAD (0) +#endif + +/* + M_MMAP_THRESHOLD is the request size threshold for using mmap() + to service a request. Requests of at least this size that cannot + be allocated using already-existing space will be serviced via mmap. + (If enough normal freed space already exists it is used instead.) + + Using mmap segregates relatively large chunks of memory so that + they can be individually obtained and released from the host + system. A request serviced through mmap is never reused by any + other request (at least not directly; the system may just so + happen to remap successive requests to the same locations). + + Segregating space in this way has the benefits that: + + 1. Mmapped space can ALWAYS be individually released back + to the system, which helps keep the system level memory + demands of a long-lived program low. + 2. Mapped memory can never become `locked' between + other chunks, as can happen with normally allocated chunks, which + means that even trimming via malloc_trim would not release them. + 3. On some systems with "holes" in address spaces, mmap can obtain + memory that sbrk cannot. + + However, it has the disadvantages that: + + 1. The space cannot be reclaimed, consolidated, and then + used to service later requests, as happens with normal chunks. + 2. It can lead to more wastage because of mmap page alignment + requirements + 3. It causes malloc performance to be more dependent on host + system memory management support routines which may vary in + implementation quality and may impose arbitrary + limitations. Generally, servicing a request via normal + malloc steps is faster than going through a system's mmap. + + The advantages of mmap nearly always outweigh disadvantages for + "large" chunks, but the value of "large" varies across systems. The + default is an empirically derived value that works well in most + systems. +*/ + +#define M_MMAP_THRESHOLD -3 + +#ifndef DEFAULT_MMAP_THRESHOLD +#define DEFAULT_MMAP_THRESHOLD (-1U) +/*#define DEFAULT_MMAP_THRESHOLD (128 * 1024) */ +#endif + +/* + M_MMAP_MAX is the maximum number of requests to simultaneously + service using mmap. This parameter exists because +. Some systems have a limited number of internal tables for + use by mmap, and using more than a few of them may degrade + performance. + + The default is set to a value that serves only as a safeguard. + Setting to 0 disables use of mmap for servicing large requests. If + HAVE_MMAP is not set, the default value is 0, and attempts to set it + to non-zero values in mallopt will fail. +*/ + +#define M_MMAP_MAX -4 + +#ifndef DEFAULT_MMAP_MAX +#if HAVE_MMAP +#define DEFAULT_MMAP_MAX (65536) +#else +#define DEFAULT_MMAP_MAX (0) +#endif +#endif + +#ifdef __cplusplus +}; /* end of extern "C" */ +#endif + +/* + ======================================================================== + To make a fully customizable malloc.h header file, cut everything + above this line, put into file malloc.h, edit to suit, and #include it + on the next line, as well as in programs that use this malloc. + ======================================================================== +*/ + +/* #include "malloc.h" */ + +/* --------------------- public wrappers ---------------------- */ + +#ifdef USE_PUBLIC_MALLOC_WRAPPERS + +/* Declare all routines as internal */ +static Void_t* mALLOc(size_t); +static void fREe(Void_t*); +static Void_t* rEALLOc(Void_t*, size_t); +static Void_t* mEMALIGn(size_t, size_t); +static Void_t* vALLOc(size_t); +static Void_t* pVALLOc(size_t); +static Void_t* cALLOc(size_t, size_t); +static Void_t** iCALLOc(size_t, size_t, Void_t**); +static Void_t** iCOMALLOc(size_t, size_t*, Void_t**); +static void cFREe(Void_t*); +static int mTRIm(size_t); +static size_t mUSABLe(Void_t*); +static void mSTATs(); +static int mALLOPt(int, int); +static struct mallinfo mALLINFo(void); + +/* + MALLOC_PREACTION and MALLOC_POSTACTION should be + defined to return 0 on success, and nonzero on failure. + The return value of MALLOC_POSTACTION is currently ignored + in wrapper functions since there is no reasonable default + action to take on failure. +*/ + + +#ifdef USE_MALLOC_LOCK + +#ifdef WIN32 + +static int mALLOC_MUTEx; +#define MALLOC_PREACTION slwait(&mALLOC_MUTEx) +#define MALLOC_POSTACTION slrelease(&mALLOC_MUTEx) + +#else + +#include + +static pthread_mutex_t mALLOC_MUTEx = PTHREAD_MUTEX_INITIALIZER; + +#define MALLOC_PREACTION pthread_mutex_lock(&mALLOC_MUTEx) +#define MALLOC_POSTACTION pthread_mutex_unlock(&mALLOC_MUTEx) + +#endif /* USE_MALLOC_LOCK */ + +#else + +/* Substitute anything you like for these */ + +#define MALLOC_PREACTION (0) +#define MALLOC_POSTACTION (0) + +#endif + +Void_t* public_mALLOc(size_t bytes) { + Void_t* m; + if (MALLOC_PREACTION != 0) { + return 0; + } + m = mALLOc(bytes); + if (MALLOC_POSTACTION != 0) { + } + return m; +} + +void public_fREe(Void_t* m) { + if (MALLOC_PREACTION != 0) { + return; + } + fREe(m); + if (MALLOC_POSTACTION != 0) { + } +} + +Void_t* public_rEALLOc(Void_t* m, size_t bytes) { + if (MALLOC_PREACTION != 0) { + return 0; + } + m = rEALLOc(m, bytes); + if (MALLOC_POSTACTION != 0) { + } + return m; +} + +Void_t* public_mEMALIGn(size_t alignment, size_t bytes) { + Void_t* m; + if (MALLOC_PREACTION != 0) { + return 0; + } + m = mEMALIGn(alignment, bytes); + if (MALLOC_POSTACTION != 0) { + } + return m; +} + +Void_t* public_vALLOc(size_t bytes) { + Void_t* m; + if (MALLOC_PREACTION != 0) { + return 0; + } + m = vALLOc(bytes); + if (MALLOC_POSTACTION != 0) { + } + return m; +} + +Void_t* public_pVALLOc(size_t bytes) { + Void_t* m; + if (MALLOC_PREACTION != 0) { + return 0; + } + m = pVALLOc(bytes); + if (MALLOC_POSTACTION != 0) { + } + return m; +} + +Void_t* public_cALLOc(size_t n, size_t elem_size) { + Void_t* m; + if (MALLOC_PREACTION != 0) { + return 0; + } + m = cALLOc(n, elem_size); + if (MALLOC_POSTACTION != 0) { + } + return m; +} + + +Void_t** public_iCALLOc(size_t n, size_t elem_size, Void_t** chunks) { + Void_t** m; + if (MALLOC_PREACTION != 0) { + return 0; + } + m = iCALLOc(n, elem_size, chunks); + if (MALLOC_POSTACTION != 0) { + } + return m; +} + +Void_t** public_iCOMALLOc(size_t n, size_t sizes[], Void_t** chunks) { + Void_t** m; + if (MALLOC_PREACTION != 0) { + return 0; + } + m = iCOMALLOc(n, sizes, chunks); + if (MALLOC_POSTACTION != 0) { + } + return m; +} + +void public_cFREe(Void_t* m) { + if (MALLOC_PREACTION != 0) { + return; + } + cFREe(m); + if (MALLOC_POSTACTION != 0) { + } +} + +int public_mTRIm(size_t s) { + int result; + if (MALLOC_PREACTION != 0) { + return 0; + } + result = mTRIm(s); + if (MALLOC_POSTACTION != 0) { + } + return result; +} + +size_t public_mUSABLe(Void_t* m) { + size_t result; + if (MALLOC_PREACTION != 0) { + return 0; + } + result = mUSABLe(m); + if (MALLOC_POSTACTION != 0) { + } + return result; +} + +void public_mSTATs() { + if (MALLOC_PREACTION != 0) { + return; + } + mSTATs(); + if (MALLOC_POSTACTION != 0) { + } +} + +struct mallinfo public_mALLINFo() { + struct mallinfo m; + if (MALLOC_PREACTION != 0) { + struct mallinfo nm = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + return nm; + } + m = mALLINFo(); + if (MALLOC_POSTACTION != 0) { + } + return m; +} + +int public_mALLOPt(int p, int v) { + int result; + if (MALLOC_PREACTION != 0) { + return 0; + } + result = mALLOPt(p, v); + if (MALLOC_POSTACTION != 0) { + } + return result; +} + +#endif + + + +/* ------------- Optional versions of memcopy ---------------- */ + + +#if USE_MEMCPY + +/* + Note: memcpy is ONLY invoked with non-overlapping regions, + so the (usually slower) memmove is not needed. +*/ + +#define MALLOC_COPY(dest, src, nbytes) memcpy(dest, src, nbytes) +#define MALLOC_ZERO(dest, nbytes) memset(dest, 0, nbytes) + +#else /* !USE_MEMCPY */ + +/* Use Duff's device for good zeroing/copying performance. */ + +#define MALLOC_ZERO(charp, nbytes) \ +do { \ + INTERNAL_SIZE_T* mzp = (INTERNAL_SIZE_T*)(charp); \ + CHUNK_SIZE_T mctmp = (nbytes)/sizeof(INTERNAL_SIZE_T); \ + long mcn; \ + if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp %= 8; } \ + switch (mctmp) { \ + case 0: for(;;) { *mzp++ = 0; \ + case 7: *mzp++ = 0; \ + case 6: *mzp++ = 0; \ + case 5: *mzp++ = 0; \ + case 4: *mzp++ = 0; \ + case 3: *mzp++ = 0; \ + case 2: *mzp++ = 0; \ + case 1: *mzp++ = 0; if(mcn <= 0) break; mcn--; } \ + } \ +} while(0) + +#define MALLOC_COPY(dest,src,nbytes) \ +do { \ + INTERNAL_SIZE_T* mcsrc = (INTERNAL_SIZE_T*) src; \ + INTERNAL_SIZE_T* mcdst = (INTERNAL_SIZE_T*) dest; \ + CHUNK_SIZE_T mctmp = (nbytes)/sizeof(INTERNAL_SIZE_T); \ + long mcn; \ + if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp %= 8; } \ + switch (mctmp) { \ + case 0: for(;;) { *mcdst++ = *mcsrc++; \ + case 7: *mcdst++ = *mcsrc++; \ + case 6: *mcdst++ = *mcsrc++; \ + case 5: *mcdst++ = *mcsrc++; \ + case 4: *mcdst++ = *mcsrc++; \ + case 3: *mcdst++ = *mcsrc++; \ + case 2: *mcdst++ = *mcsrc++; \ + case 1: *mcdst++ = *mcsrc++; if(mcn <= 0) break; mcn--; } \ + } \ +} while(0) + +#endif + +/* ------------------ MMAP support ------------------ */ + + +#if HAVE_MMAP + +#include +#ifndef LACKS_SYS_MMAN_H +#include +#endif + +#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) +#define MAP_ANONYMOUS MAP_ANON +#endif + +/* + Nearly all versions of mmap support MAP_ANONYMOUS, + so the following is unlikely to be needed, but is + supplied just in case. +*/ + +#ifndef MAP_ANONYMOUS + +static int dev_zero_fd = -1; /* Cached file descriptor for /dev/zero. */ + +#define MMAP(addr, size, prot, flags) ((dev_zero_fd < 0) ? \ + (dev_zero_fd = open("/dev/zero", O_RDWR), \ + mmap((addr), (size), (prot), (flags), dev_zero_fd, 0)) : \ + mmap((addr), (size), (prot), (flags), dev_zero_fd, 0)) + +#else + +#define MMAP(addr, size, prot, flags) \ + (mmap((addr), (size), (prot), (flags)|MAP_ANONYMOUS, -1, 0)) + +#endif + + +#endif /* HAVE_MMAP */ + + +/* + ----------------------- Chunk representations ----------------------- +*/ + + +/* + This struct declaration is misleading (but accurate and necessary). + It declares a "view" into memory allowing access to necessary + fields at known offsets from a given base. See explanation below. +*/ + +struct malloc_chunk { + + INTERNAL_SIZE_T prev_size; /* Size of previous chunk (if free). */ + INTERNAL_SIZE_T size; /* Size in bytes, including overhead. */ + + struct malloc_chunk* fd; /* double links -- used only if free. */ + struct malloc_chunk* bk; +}; + + +typedef struct malloc_chunk* mchunkptr; + +/* conversion from malloc headers to user pointers, and back */ +#define chunk2mem(p) ((Void_t*)((char*)(p) + 2*SIZE_SZ)) +#define mem2chunk(mem) ((mchunkptr)((char*)(mem) - 2*SIZE_SZ)) + +/* + malloc_chunk details: + + (The following includes lightly edited explanations by Colin Plumb.) + + Chunks of memory are maintained using a `boundary tag' method as + described in e.g., Knuth or Standish. (See the paper by Paul + Wilson ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a + survey of such techniques.) Sizes of free chunks are stored both + in the front of each chunk and at the end. This makes + consolidating fragmented chunks into bigger chunks very fast. The + size fields also hold bits representing whether chunks are free or + in use. + + An allocated chunk looks like this: + + + chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Size of previous chunk, if allocated | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Size of chunk, in bytes |P| + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | User data starts here... . + . . + . (malloc_usable_space() bytes) . + . | +nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + `foot:' | Size of chunk | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + + Where "chunk" is the front of the chunk for the purpose of most of + the malloc code, but "mem" is the pointer that is returned to the + user. "Nextchunk" is the beginning of the next contiguous chunk. + + Chunks always begin on even word boundries, so the mem portion + (which is returned to the user) is also on an even word boundary, and + thus at least double-word aligned. + + + The P (PREV_INUSE) bit, stored in the unused low-order bit of the + chunk size (which is always a multiple of two words), is an in-use + bit for the *previous* chunk. If that bit is *clear*, then the + word before the current chunk size contains the previous chunk + size, and can be used to find the front of the previous chunk. + The very first chunk allocated always has this bit set, + preventing access to non-existent (or non-owned) memory. If + prev_inuse is set for any given chunk, then you CANNOT determine + the size of the previous chunk, and might even get a memory + addressing fault when trying to do so. + + Note that the `foot' of the current chunk is actually represented + as the prev_size of the NEXT chunk. This makes it easier to + deal with alignments etc but can be very confusing when trying + to extend or adapt this code. + + The two exceptions to all this are + + 1. The special chunk `top' doesn't bother using the + trailing size field since there is no next contiguous chunk + that would have to index off it. After initialization, `top' + is forced to always exist. If it would become less than + MINSIZE bytes long, it is replenished. + + 2. Chunks allocated via mmap, which have the second-lowest-order + bit (IS_MMAPPED) set in their size fields. Because they are + allocated one-by-one, each must contain its own trailing size field. + +*/ + + + +/* + --------------- Operations on size fields --------------- +*/ + + +/* size field is or'ed with PREV_INUSE when previous adjacent chunk in use */ +#define PREV_INUSE 0x1 + +#if HAVE_MMAP +/* size field is or'ed with IS_MMAPPED if the chunk was obtained with mmap */ +#define IS_MMAPPED 0x2 +#else +#define IS_MMAPPED 0 +#endif + +/* extract inuse bit of previous chunk */ +#define prev_inuse(p) ((p)->size & PREV_INUSE) + +/* check for mmap()'ed chunk */ +#define chunk_is_mmapped(p) ((p)->size & IS_MMAPPED) + +/* + Bits to mask off when extracting size + + Note: IS_MMAPPED is intentionally not masked off from size field in + macros for which mmapped chunks should never be seen. This should + cause helpful core dumps to occur if it is tried by accident by + people extending or adapting this malloc. +*/ +#define SIZE_BITS (PREV_INUSE|IS_MMAPPED) + +/* Get size, ignoring use bits */ +#define chunksize(p) ((CHUNK_SIZE_T)((p)->size & ~(SIZE_BITS))) + + +/* Ptr to next physical malloc_chunk. */ +#define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->size & ~PREV_INUSE))) + +/* Ptr to previous physical malloc_chunk */ +#define prev_chunk(p) ((mchunkptr)( ((char*)(p)) - ((p)->prev_size) )) + +/* Treat space at ptr + offset as a chunk */ +#define chunk_at_offset(p, s) ((mchunkptr)(((char*)(p)) + (s))) + +/* extract p's inuse bit */ +#define inuse(p)\ +((((mchunkptr)(((char*)(p))+((p)->size & ~PREV_INUSE)))->size) & PREV_INUSE) + +/* set/clear chunk as being inuse without otherwise disturbing */ +#define set_inuse(p)\ +((mchunkptr)(((char*)(p)) + ((p)->size & ~PREV_INUSE)))->size |= PREV_INUSE + +#define clear_inuse(p)\ +((mchunkptr)(((char*)(p)) + ((p)->size & ~PREV_INUSE)))->size &= ~(PREV_INUSE) + + +/* check/set/clear inuse bits in known places */ +#define inuse_bit_at_offset(p, s)\ + (((mchunkptr)(((char*)(p)) + (s)))->size & PREV_INUSE) + +#define inuse_addr_at_offset(p, s)\ + (INTERNAL_SIZE_T*)(&(((mchunkptr)(((char*)(p)) + (s)))->size)) + +#define set_inuse_bit_at_offset(p, s)\ + (((mchunkptr)(((char*)(p)) + (s)))->size |= PREV_INUSE) + +#define clear_inuse_bit_at_offset(p, s)\ + (((mchunkptr)(((char*)(p)) + (s)))->size &= ~(PREV_INUSE)) + + +/* Set size at head, without disturbing its use bit */ +#define set_head_size(p, s) ((p)->size = (((p)->size & PREV_INUSE) | (s))) + +/* Set size/use field */ +#define set_head(p, s) ((p)->size = (s)) + +/* Set size at footer (only when chunk is not in use) */ +#define set_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_size = (s)) + + +/* + ---------- Size and alignment checks and conversions ---------- +*/ + + +/* The smallest possible chunk */ +#define MIN_CHUNK_SIZE (sizeof(struct malloc_chunk)) + +/* The smallest size we can malloc is an aligned minimal chunk */ + +#define MINSIZE \ + (CHUNK_SIZE_T)(((MIN_CHUNK_SIZE+MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK)) + +/* Check if m has acceptable alignment */ + +#define aligned_OK(m) (((PTR_UINT)((m)) & (MALLOC_ALIGN_MASK)) == 0) + + +/* + Check if a request is so large that it would wrap around zero when + padded and aligned. To simplify some other code, the bound is made + low enough so that adding MINSIZE will also not wrap around sero. +*/ + +#define MAX_REQUEST_SIZE ((CHUNK_SIZE_T)(INTERNAL_SIZE_T)(-2 * MINSIZE)) + +#define request_out_of_range(req) \ + ((CHUNK_SIZE_T)(req) >= MAX_REQUEST_SIZE) + +/* pad request bytes into a usable size -- internal version */ + +#define request2size(req) \ + (((req) + SIZE_SZ + MALLOC_ALIGN_MASK < MINSIZE) ? \ + MINSIZE : \ + ((req) + SIZE_SZ + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK) + + +#define pad_request(req) \ + (((req) + SIZE_SZ + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK) + +/* Same, except also perform argument check */ + +#define checked_request2size(req, sz) \ + if (request_out_of_range(req)) { \ + MALLOC_FAILURE_ACTION; \ + return 0; \ + } \ + (sz) = request2size(req); + + +typedef CHUNK_SIZE_T bin_index_t; +typedef unsigned int bitmap_t; + + +/* + ---------- Overlaid Data types ---------- +*/ + + +/* + "Small" chunks are stored in circular doubly-linked lists, and look + like this: + + chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Size of previous chunk | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + `head:' | Size of chunk, in bytes |P| + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Forward pointer to next chunk in list | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Back pointer to previous chunk in list | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Unused space (may be 0 bytes long) . + . . + . | +nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + `foot:' | Size of chunk, in bytes | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Larger chunks are kept in a form of bitwise digital trees (aka tries) + keyed on chunksizes, in which + + * As seen as trees, they contains no duplicates (i.e., no + duplicate sizes). If a chunk with the same size an an existing + node is inserted, it is linked off the existing node using + pointers that work in the same way as fd/bk pointers + of small chunks + + * The decision to go left or right when searching is based on a + sliding bit, starting at the most significant bit distinguishing + sizes in the tree, and sliding right each level. All left + children of a node are smaller than all right children, but not + necessarily smaller than the node. + + The worst case number of steps to add or remove a node is thus + bounded by the number of bits differentiating chunks within + bins. Under current bin calculations, this ranges from 6 up to 21 + (for 32 bit sizes) or up to 53 (for 64 bit sizes). The typical case + is of course much better. + + Tree chunks are overlaid in the same way as small chunks. Because + malloc_tree_chunks are only for free chunks greater than 256 bytes, their + zie doesn;t impose any constraints on user chunk sizes. + + chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Size of previous chunk | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + `head:' | Size of chunk, in bytes |P| + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Forward pointer to next chunk of same size | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Back pointer to previous chunk of same size | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Pointer to left child (child[0]) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Pointer to right child (child[1]) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Pointer to parent | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | bin index of this chunk | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Unused space . + . | +nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + `foot:' | Size of chunk, in bytes | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +*/ + + +struct malloc_tree_chunk { + INTERNAL_SIZE_T prev_size; /* same as in malloc_chunk */ + INTERNAL_SIZE_T size; + + struct malloc_tree_chunk* fd; /* double links -- used only if free. */ + struct malloc_tree_chunk* bk; + + struct malloc_tree_chunk* child[2]; + struct malloc_tree_chunk* parent; + + bin_index_t index; +}; + +typedef struct malloc_tree_chunk* tchunkptr; + +typedef struct malloc_tree_chunk* tbinptr; + + + + +/* + -------------------- Internal data structures -------------------- + + All internal state is held in an instance of malloc_state defined + below. There are no other static variables, except in two optional + cases: + * If USE_MALLOC_LOCK is defined, the mALLOC_MUTEx declared above. + * If HAVE_MMAP is true, but mmap doesn't support + MAP_ANONYMOUS, a dummy file descriptor for mmap. + + Beware of lots of tricks that minimize the total bookkeeping space + requirements. The result is a little under 1K bytes (for 4byte + pointers and size_t.) +*/ + +/* + SmallBins + + An array of bin headers for free chunks. Most bins hold sizes that are + unusual as malloc request sizes, but are more usual for fragments + and consolidated sets of chunks, which is what these bins hold, so + they can be found quickly. All procedures maintain the invariant + that no consolidated chunk physically borders another one, so each + chunk in a list is known to be preceeded and followed by either + inuse chunks or the ends of memory. + + To simplify use in double-linked lists, each bin header acts as a + malloc_chunk pointing to the real first node, if it exists (else + juct pointing to itself). This avoids special-casing for headers. + But to conserve space and improve locality, we allocate only the + fd/bk pointers of bins, and then use repositioning tricks to treat + these as the fields of a malloc_chunk*. + +*/ + +typedef struct malloc_chunk* mbinptr; + +/* addressing */ +#define bin_at(m, i) ((mbinptr)((char*)&((m)->bins[(i)<<1]) - (SIZE_SZ<<1))) + +/* analog of ++bin */ +#define next_bin(b) ((mbinptr)((char*)(b) + (sizeof(mchunkptr)<<1))) + +/* inverse of bin_at */ +#define bin2idx(m, b) \ + ( ((int) (((char*)(b)) - (char*)(bin_at(m,0)))) / (2 * sizeof(mchunkptr))) + +/* + Indexing + + Bins for sizes < MIN_TREEBIN_SIZE bytes contain chunks of all the + same size, spaced 8 bytes apart. Larger bins are approximately + logarithmically spaced. +*/ + +#define NBINS 32 +#define SMALLBIN_WIDTH 8 +#define MIN_TREEBIN_SIZE 256 +/* bit-shift corresponding to MIN_TREEBIN_SIZE */ +#define TREE_BIN_SHIFT 8 + +#define in_smallbin_range(sz) \ + ((CHUNK_SIZE_T)(sz) <= (CHUNK_SIZE_T)(MIN_TREEBIN_SIZE-1)) + + +#define MAX_SMALL_REQUEST (MIN_TREEBIN_SIZE-(SIZE_SZ+MALLOC_ALIGNMENT)) + +#define smallbin_index(sz) (bin_index_t)((sz) >> 3) + +#define size_for_smallindex(i) ((CHUNK_SIZE_T)(i) << 3) + +#define MIN_SMALLBIN_INDEX (smallbin_index(MINSIZE)) + +#define MIN_SMALLBIN_BIT (idx2bit(smallbin_index(MINSIZE))) + + +/* + There are 2 equally spaced treebins for each power of two from + TREE_BIN_SHIFT to TREE_BIN_SHIFT+16. The last bin holds anything + larger. +*/ + + +static bin_index_t treebin_index(CHUNK_SIZE_T sz) { + unsigned int m; + unsigned int x = sz >> TREE_BIN_SHIFT; + if (x == 0) + return 0; + if (x > 0xFFFF) + return NBINS-1; + + /* On intel, use BSRL instruction to find highest bit */ +#if defined(__GNUC__) && defined(i386) + + __asm__("bsrl %1,%0\n\t" + : "=r" (m) + : "g" (x)); + return (m << 1) + ((sz >> (m + (TREE_BIN_SHIFT-1)) & 1)); + +#else + { + /* + Based on branch-free nlz algorithm in chapter 5 of Henry + S. Warren Jr's book "Hacker's Delight". + */ + + unsigned int n = ((x - 0x100) >> 16) & 8; + x <<= n; + m = ((x - 0x1000) >> 16) & 4; + n += m; + x <<= m; + m = ((x - 0x4000) >> 16) & 2; + n += m; + x = (x << m) >> 14; + m = 13 - n + (x & ~(x>>1)); + /* shift up n and use the next bit to make finer-granularity bins. */ + return (m << 1) + ((sz >> (m + (TREE_BIN_SHIFT-1)) & 1)); + } +#endif +} + +static bin_index_t bit2idx(bitmap_t x) { +#if defined(__GNUC__) && defined(i386) + int r; + __asm__("bsfl %1,%0\n\t" + : "=r" (r) : "g" (x)); + return (bin_index_t)r; +#else + return (bin_index_t)(ffs(x)-1); +#endif +} + + + +#define bin_index(sz) \ + ((in_smallbin_range(sz)) ? smallbin_index(sz) : treebin_index(sz)) + +/* + The most significant bit distinguishing nodes in the tree + associated with a given bin +*/ + +#define CHUNK_SIZE_BITS (sizeof(CHUNK_SIZE_T) * 8) + +#define bitshift_for_index(idx) \ + (idx == NBINS-1)? \ + CHUNK_SIZE_BITS-1 : \ + (((idx) >> 1) + TREE_BIN_SHIFT-2) + +#define tbin_at(m,i) (&((m)->treebins[i])) + +#define minsize_for_treeindex(i) \ + (((CHUNK_SIZE_T)(1) << (((i) >> 1) + TREE_BIN_SHIFT)) | \ + (((CHUNK_SIZE_T)((i) & 1)) << \ + ( ( (i) >> 1) + TREE_BIN_SHIFT - 1))) + + + +#define is_tbin(M, P) ((tbinptr*)(P) >= &((M)->treebins[0]) && \ + (tbinptr*)(P) < &((M)->treebins[NBINS])) + +#define leftmost_child(t) \ + (((t)->child[0] != 0)? ((t)->child[0]) : ((t)->child[1])) + + +/* + Fastbins + + An array of lists holding recently freed small chunks. Fastbins + are not doubly linked. It is faster to single-link them, and + since chunks are never removed from the middles of these lists, + double linking is not necessary. Also, unlike regular bins, they + are not even processed in FIFO order (they use faster LIFO) since + ordering doesn't much matter in the transient contexts in which + fastbins are normally used. + + Chunks in fastbins keep their inuse bit set, so they cannot + be consolidated with other free chunks. malloc_consolidate + releases all chunks in fastbins and consolidates them with + other free chunks. +*/ + +typedef struct malloc_chunk* mfastbinptr; + +#define fastbin_at(m,i) (&((m)->fastbins[i])) + +/* offset 2 to use otherwise unindexable first 2 bins */ +#define fastbin_index(sz) ((((unsigned int)(sz)) >> 3) - 2) + + +/* The maximum fastbin request size we support */ +#define MAX_FAST_REQUEST 64 + +#define MAX_FAST_SIZE (request2size(MAX_FAST_REQUEST)) + +#define NFASTBINS (fastbin_index(MAX_FAST_SIZE)+1) + +/* + FASTCHUNKS_BIT held in max_fast indicates that there are probably + some fastbin chunks. It is set true on entering a chunk into any + fastbin, and cleared only in malloc_consolidate. +*/ + +#define FASTCHUNKS_BIT (2U) + +#define have_fastchunks(M) (((M)->max_fast & FASTCHUNKS_BIT)) +#define set_fastchunks(M) ((M)->max_fast |= (FASTCHUNKS_BIT)) +#define clear_fastchunks(M) ((M)->max_fast &= ~(FASTCHUNKS_BIT)) + +/* + Set value of max_fast. + Use impossibly small value if 0. +*/ + +#define set_max_fast(M, s) \ + (M)->max_fast = (((s) == 0)? SMALLBIN_WIDTH: request2size(s)) | \ + ((M)->max_fast & (FASTCHUNKS_BIT)) + +#define get_max_fast(M) \ + ((M)->max_fast & ~(FASTCHUNKS_BIT)) + + +/* + Top + + The top-most available chunk (i.e., the one bordering the end of + available memory) is treated specially. It is never included in + any bin, is used only if no other chunk is available, and is + released back to the system if it is very large (see + M_TRIM_THRESHOLD). + + Top initially points to a dummy bin with zero size, thus forcing + extension on the first malloc request, so we avoid having any + special code in malloc to check whether it even exists yet. +*/ + + +/* + Binmap + + To help compensate for the large number of bins, a one-level index + structure is used for bin-by-bin searching. `binmap' is a + bitvector recording whether bins are definitely empty so they can + be skipped over during during traversals. +*/ + +/* Conservatively use 32 bits per map word, even if on 64bit system */ + +#define idx2bit(i) ((bitmap_t)(1) << (i)) + +#define mark_smallbin(m,i) ((m)->smallbits |= idx2bit(i)) +#define mark_treebin(m,i) ((m)->treebits |= idx2bit(i)) + +#define clear_smallbin(m,i) ((m)->smallbits &= ~idx2bit(i)) +#define clear_treebin(m,i) ((m)->treebits &= ~idx2bit(i)) + + +/* isolate the least set bit of a bitmap */ + +#define least_bit(x) ((x) & -(x)) + +/* create mask with all bits to left of least bit of x on */ + +#define left_bits(x) ((x<<1) | -(x<<1)) + +/* create mask with all bits to left of or equal to least bit of x on */ + +#define same_or_left_bits(x) ((x) | -(x)) + + +/* + sysctl is a status word holding dynamically discovered + or controlled properties of the morecore function +*/ + +#define MORECORE_CONTIGUOUS_BIT (1U) +#define TRIM_DISABLE_BIT (2U) +#define MMAP_DISABLE_BIT (4U) + +#define contiguous(M) \ + (((M)->sysctl & MORECORE_CONTIGUOUS_BIT)) +#define set_contiguous(M) \ + ((M)->sysctl |= MORECORE_CONTIGUOUS_BIT) +#define set_noncontiguous(M) \ + ((M)->sysctl &= ~MORECORE_CONTIGUOUS_BIT) + +#define disable_trim(M) \ + ((M)->sysctl |= TRIM_DISABLE_BIT) +#define enable_trim(M) \ + ((M)->sysctl &= ~TRIM_DISABLE_BIT) +#define trim_disabled(M) \ + ((M)->sysctl & TRIM_DISABLE_BIT) + +#define enable_mmap(M) \ + ((M)->sysctl &= ~MMAP_DISABLE_BIT) +#define disable_mmap(M) \ + ((M)->sysctl |= MMAP_DISABLE_BIT) +#define mmap_disabled(M) \ + ((M)->sysctl & MMAP_DISABLE_BIT) + + + + +/* + ----------- Internal state representation and initialization ----------- +*/ + +struct malloc_state { + /* The maximum chunk size to be eligible for fastbin */ + CHUNK_SIZE_T max_fast; + + /* Bitmap of bins */ + bitmap_t smallbits; + bitmap_t treebits; + + /* Base of the topmost chunk -- not otherwise kept in a bin */ + mchunkptr top; + + /* Fastbins */ + mfastbinptr fastbins[NFASTBINS]; + + /* Smallbins packed as described above */ + mchunkptr bins[NBINS * 2]; + + /* Treebins */ + tbinptr treebins[NBINS]; + + /* Padding to allow addressing past end of treebin array */ + struct malloc_tree_chunk initial_top; + + /* Tunable parameters */ + CHUNK_SIZE_T trim_threshold; + INTERNAL_SIZE_T top_pad; + INTERNAL_SIZE_T mmap_threshold; + + /* Memory map support */ + int n_mmaps; + int n_mmaps_max; + int max_n_mmaps; + + /* Cache malloc_getpagesize */ + unsigned int pagesize; + + /* Track properties of MORECORE */ + unsigned int sysctl; + + /* Statistics */ + INTERNAL_SIZE_T mmapped_mem; + INTERNAL_SIZE_T sbrked_mem; + INTERNAL_SIZE_T max_sbrked_mem; + INTERNAL_SIZE_T max_mmapped_mem; + INTERNAL_SIZE_T max_total_mem; +}; + +typedef struct malloc_state *mstate; + +/* + There is exactly one instance of this struct in this malloc. + If you are adapting this malloc in a way that does NOT use a static + malloc_state, you MUST explicitly zero-fill it before using. This + malloc relies on the property that malloc_state is initialized to + all zeroes (as is true of C statics). +*/ + +static struct malloc_state av_; /* never directly referenced */ + +/* + All uses of av_ are via get_malloc_state(). + At most one "call" to get_malloc_state is made per invocation of + the public versions of malloc and free, but other routines + that in turn invoke malloc and/or free may call more then once. + Also, it is called in check* routines if DEBUG is set. +*/ + +#define get_malloc_state() (&(av_)) + +/* + Initialize a malloc_state struct. This is called only + in sysmalloc, to avoid it being inlined everywhere else, + which causes useless code bloat. +*/ + +static void malloc_init_state(mstate av) { + int i; + mbinptr bin; + + /* Establish circular links for bins */ + for (i = 0; i < NBINS; ++i) { + bin = bin_at(av,i); + bin->fd = bin->bk = bin; + } + + av->top_pad = DEFAULT_TOP_PAD; + av->n_mmaps_max = DEFAULT_MMAP_MAX; + av->mmap_threshold = DEFAULT_MMAP_THRESHOLD; + av->trim_threshold = DEFAULT_TRIM_THRESHOLD; + +#if MORECORE_CONTIGUOUS + set_contiguous(av); +#else + set_noncontiguous(av); +#endif + + set_max_fast(av, DEFAULT_MXFAST); + + av->top = (mchunkptr)(&(av->initial_top)); + av->pagesize = malloc_getpagesize; +} + +#define ensure_initialization(M) \ + if ((M)->top == 0) sysmalloc(M, 0); + + +/* + Other internal utilities +*/ + +static Void_t* sysmalloc(mstate, CHUNK_SIZE_T); +static int systrim(mstate, size_t); +static Void_t** iALLOc(size_t, size_t*, int, Void_t**); +static void insert_treenode(mstate, tchunkptr, CHUNK_SIZE_T); +#if 0 +static void unlink_treenode(mstate, tchunkptr); +static void unlink_small_chunk(mstate av, mchunkptr p, CHUNK_SIZE_T size); +#endif +static void transfer_tree_links(tchunkptr oldt, tchunkptr newt); +static tchunkptr find_replacement(tchunkptr t); +static void unlink_chained_node(tchunkptr t); +static void insert_small_chunk(mstate av, mchunkptr p, CHUNK_SIZE_T nb); +static void insert_chunk(mstate av, mchunkptr p, CHUNK_SIZE_T nb); +static mchunkptr take_from_smallbin(mstate av, mchunkptr bin, bitmap_t bit); +static void unlink_chunk(mstate av, mchunkptr p, CHUNK_SIZE_T size); +static void malloc_consolidate(mstate); + + +#pragma no_inline(systrim) + + +#if HAVE_MMAP +static mchunkptr mmap_malloc(mstate, INTERNAL_SIZE_T); +#endif + +/* + Debugging support + + These routines make a number of assertions about the states + of data structures that should be true at all times. If any + are not true, it's very likely that a user program has somehow + trashed memory. (It's also possible that there is a coding error + in malloc. In which case, please report it!) +*/ + + +#if ! DEBUG + +#define check_chunk(P) +#define check_free_chunk(P) +#define check_inuse_chunk(P) +#define check_remalloced_chunk(P,N) +#define check_malloced_chunk(P,N) +#define check_malloc_state(M) +#define check_tree(P) + +#else +#define check_chunk(P) do_check_chunk(P) +#define check_free_chunk(P) do_check_free_chunk(P) +#define check_inuse_chunk(P) do_check_inuse_chunk(P) +#define check_remalloced_chunk(P,N) do_check_remalloced_chunk(P,N) +#define check_malloced_chunk(P,N) do_check_malloced_chunk(P,N) +#define check_tree(P) do_check_tree(P) +#define check_malloc_state(M) do_check_malloc_state(M) + +static void do_check_malloc_state(mstate); + +/* + Find x in a treebin. Used in other check functions. +*/ + +static tchunkptr tree_find(tchunkptr x) { + mstate av = get_malloc_state(); + CHUNK_SIZE_T nb = chunksize(x); + bin_index_t idx = treebin_index(nb); + tbinptr* bin = tbin_at(av, idx); + tchunkptr t = *bin; + bin_index_t shift = bitshift_for_index(idx); + CHUNK_SIZE_T allbits = 0; + + if (t == 0) + return 0; + + while (t != 0) { + CHUNK_SIZE_T size; + if (t == x) + return t; + size = chunksize(t); + assert((size & allbits) == allbits); + if (size == nb) { + tchunkptr p = t->bk; + for (;;) { + if (p == x) + return p; + else if (p == t) + return 0; + else + p = p->bk; + } + } + if (((nb >> shift) & 1) == 0) { + t = t->child[0]; + } + else { + t = t->child[1]; + allbits |= 1U << shift; + } + + --shift; + } + return 0; +} + +/* + Properties of all chunks +*/ + +static void do_check_chunk(mchunkptr p) { + mstate av = get_malloc_state(); + CHUNK_SIZE_T sz = chunksize(p); + /* min and max possible addresses assuming contiguous allocation */ + char* max_address = (char*)(av->top) + chunksize(av->top); + char* min_address = max_address - av->sbrked_mem; + + if (!chunk_is_mmapped(p)) { + + /* Has legal address ... */ + if (p != av->top) { + if (contiguous(av)) { + assert(((char*)p) >= min_address); + assert(((char*)p + sz) <= ((char*)(av->top))); + } + } + else { + /* top size is always at least MINSIZE */ + assert((CHUNK_SIZE_T)(sz) >= MINSIZE); + /* top predecessor always marked inuse */ + assert(prev_inuse(p)); + } + + } + else { +#if HAVE_MMAP + /* address is outside main heap */ + if (contiguous(av) && av->top != (mchunkptr)(&(av->initial_top))) { + assert(((char*)p) < min_address || ((char*)p) > max_address); + } + /* chunk is page-aligned */ + assert(((p->prev_size + sz) & (av->pagesize-1)) == 0); + /* mem is aligned */ + assert(aligned_OK(chunk2mem(p))); +#else + /* force an appropriate assert violation if debug set */ + assert(!chunk_is_mmapped(p)); +#endif + } +} + +static void check_all_less(tchunkptr t, CHUNK_SIZE_T nb) { + if (t == 0) + return; + assert(chunksize(t) < nb); + check_all_less(t->child[0], nb); + check_all_less(t->child[1], nb); +} + +static void check_all_greater(tchunkptr t, CHUNK_SIZE_T nb) { + if (t == 0) + return; + assert(chunksize(t) >= nb); + check_all_greater(t->child[0], nb); + check_all_greater(t->child[1], nb); +} + + +static INTERNAL_SIZE_T check_tree_fields(tchunkptr t) { + INTERNAL_SIZE_T size = chunksize(t); + assert(size >= MIN_TREEBIN_SIZE); + do_check_chunk(((mchunkptr)t)); + assert(!inuse(t)); + assert(t->fd->bk == t); + assert(t->bk->fd == t); + assert(t->parent != t); + assert(t->child[0] != t); + assert(t->child[1] != t); + if (t->child[0] != 0 && t->child[1] != 0) { + check_all_less(t->child[0], chunksize(t->child[1])); + check_all_greater(t->child[1], chunksize(t->child[0])); + } + return size; +} + +static INTERNAL_SIZE_T do_check_tree(tchunkptr t) { + tchunkptr p; + tchunkptr h; + INTERNAL_SIZE_T total = check_tree_fields(t); + + /* If t is on a same-sized list, another node on list must have a parent */ + if (t->parent == 0) { + h = t->bk; + while (h != t && h->parent == 0) + h = h->bk; + assert(h != t); + } + else + h = t; + + assert (h->parent->child[0] == h || + h->parent->child[1] == h || + *((tbinptr*)(h->parent)) == h); + + + /* only one node on a same-sized list has parent or children */ + p = h->bk; + while (p != h) { + assert(p->child[0] == 0); + assert(p->child[1] == 0); + assert(p->parent == 0); + assert(chunksize(p) == chunksize(h)); + total += check_tree_fields(p); + p = p->bk; + } + + if (h->child[0] != 0) { + assert(h->child[0]->parent == h); + total += do_check_tree(h->child[0]); + } + + if (h->child[1] != 0) { + assert(h->child[1]->parent == h); + total += do_check_tree(h->child[1]); + } + + return total; +} + +static void do_check_links(mchunkptr p) { + if (in_smallbin_range(chunksize(p))) { + assert(p->fd->bk == p); + assert(p->bk->fd == p); + } + else { + do_check_tree((tchunkptr)p); + } +} + +/* + Properties of free chunks +*/ + +static void do_check_free_chunk(mchunkptr p) { + mstate av = get_malloc_state(); + + INTERNAL_SIZE_T sz = p->size & ~PREV_INUSE; + mchunkptr next = chunk_at_offset(p, sz); + + do_check_chunk(p); + + /* Chunk must claim to be free ... */ + assert(!inuse(p)); + assert (!chunk_is_mmapped(p)); + + /* Unless a special marker, must have OK fields */ + if ((CHUNK_SIZE_T)(sz) >= MINSIZE) + { + assert((sz & MALLOC_ALIGN_MASK) == 0); + assert(aligned_OK(chunk2mem(p))); + /* ... matching footer field */ + assert(next->prev_size == sz); + /* ... and is fully consolidated */ + assert(prev_inuse(p)); + assert (next == av->top || inuse(next)); + + do_check_links(p); + } + else /* markers are always of size SIZE_SZ */ + assert(sz == SIZE_SZ); +} + +/* + Properties of inuse chunks +*/ + +static void do_check_inuse_chunk(mchunkptr p) { + mstate av = get_malloc_state(); + mchunkptr next; + do_check_chunk(p); + + if (chunk_is_mmapped(p)) + return; /* mmapped chunks have no next/prev */ + + /* Check whether it claims to be in use ... */ + assert(inuse(p)); + + next = next_chunk(p); + + /* ... and is surrounded by OK chunks. + Since more things can be checked with free chunks than inuse ones, + if an inuse chunk borders them and debug is on, it's worth doing them. + */ + if (!prev_inuse(p)) { + /* Note that we cannot even look at prev unless it is not inuse */ + mchunkptr prv = prev_chunk(p); + assert(next_chunk(prv) == p); + do_check_free_chunk(prv); + } + + if (next == av->top) { + assert(prev_inuse(next)); + assert(chunksize(next) >= MINSIZE); + } + else if (!inuse(next)) + do_check_free_chunk(next); +} + + +static void do_check_remalloced_chunk(mchunkptr p, INTERNAL_SIZE_T s) { + INTERNAL_SIZE_T sz = p->size & ~PREV_INUSE; + + do_check_inuse_chunk(p); + + /* Legal size ... */ + assert((sz & MALLOC_ALIGN_MASK) == 0); + assert((CHUNK_SIZE_T)(sz) >= MINSIZE); + /* ... and alignment */ + assert(aligned_OK(chunk2mem(p))); + /* chunk is less than MINSIZE more than request */ + assert((long)(sz) - (long)(s) >= 0); + assert((long)(sz) - (long)(s + MINSIZE) < 0); +} + +/* + Properties of nonrecycled chunks at the point they are malloced +*/ + +static void do_check_malloced_chunk(mchunkptr p, INTERNAL_SIZE_T s) { + /* same as recycled case ... */ + do_check_remalloced_chunk(p, s); +#if 0 + do_check_malloc_state(get_malloc_state()); +#endif + + /* + ... plus, must obey implementation invariant that prev_inuse is + always true of any allocated chunk; i.e., that each allocated + chunk borders either a previously allocated and still in-use + chunk, or the base of its memory arena. This is ensured + by making all allocations from the the `lowest' part of any found + chunk. + */ + + assert(prev_inuse(p)); +} + + +static CHUNK_SIZE_T do_check_smallbin(mstate av, int i, mbinptr b) { + mchunkptr p = b->bk; + mchunkptr q; + bin_index_t idx; + INTERNAL_SIZE_T size; + CHUNK_SIZE_T total = 0; + unsigned int empty = (av->smallbits & (1 << i)) == 0; + + if (i >= 2) { + if (empty) + assert(p == b); + if (p == b) + assert(empty); + + if (p != b) + assert(!empty); + } + + for (; p != b; p = p->bk) { + /* each chunk claims to be free */ + do_check_free_chunk(p); + size = chunksize(p); + total += size; + if (i >= 2) { + /* chunk belongs in bin */ + idx = smallbin_index(size); + assert(idx == i); + assert(p->bk == b || + (CHUNK_SIZE_T)chunksize(p->bk) == + (CHUNK_SIZE_T)chunksize(p)); + } + /* chunk is followed by a legal chain of inuse chunks */ + for (q = next_chunk(p); + (q != av->top && inuse(q) && + (CHUNK_SIZE_T)(chunksize(q)) >= MINSIZE); + q = next_chunk(q)) + do_check_inuse_chunk(q); + } + + return total; +} + +/* + Properties of malloc_state. + + This may be useful for debugging malloc, as well as detecting user + programmer errors that somehow write into malloc_state. + + If you are extending or experimenting with this malloc, you can + probably figure out how to hack this routine to print out or + display chunk addresses, sizes, bins, and other instrumentation. +*/ + +static void do_check_malloc_state(mstate av) { + int i; + mbinptr b; + CHUNK_SIZE_T total = 0; + tchunkptr t; + unsigned int empty; + tbinptr* tb; + int max_fast_bin; + mchunkptr p; + + /* internal size_t must be no wider than pointer type */ + assert(sizeof(INTERNAL_SIZE_T) <= sizeof(char*)); + + /* alignment is a power of 2 */ + assert((MALLOC_ALIGNMENT & (MALLOC_ALIGNMENT-1)) == 0); + + /* cannot run remaining checks until fully initialized */ + if (av->top == 0 || av->top == (mchunkptr)(&(av->initial_top))) + return; + + /* pagesize is a power of 2 */ + assert((av->pagesize & (av->pagesize-1)) == 0); + + /* check smallbins */ + for (i = 1; i < NBINS; ++i) { + b = bin_at(av, i); + total += do_check_smallbin(av, i, b); + } + + /* check treebins */ + for (i = 0; i < NBINS; ++i) { + tb = tbin_at(av, i); + t = *tb; + empty = (av->treebits & (1 << i)) == 0; + if (t == 0) + assert(empty); + else if (t != 0) { + assert(!empty); + total += do_check_tree(t); + } + } + + + /* top chunk is OK */ + check_chunk(av->top); + /* top not in tree */ + if (!in_smallbin_range(chunksize(av->top))) + assert(tree_find((tchunkptr)(av->top)) == 0); + + /* max_fast is in allowed range */ + assert(get_max_fast(av) <= request2size(MAX_FAST_SIZE)); + + max_fast_bin = fastbin_index(av->max_fast); + + for (i = 0; i < NFASTBINS; ++i) { + p = av->fastbins[i]; + + /* all bins past max_fast are empty */ + if (i > max_fast_bin) + assert(p == 0); + + while (p != 0) { + /* each chunk claims to be inuse */ + do_check_inuse_chunk(p); + total += chunksize(p); + /* chunk belongs in this bin */ + assert(fastbin_index(chunksize(p)) == i); + p = p->fd; + } + } + + /* sanity checks for statistics */ + + assert(total <= (CHUNK_SIZE_T)(av->max_total_mem)); + + assert(av->n_mmaps >= 0); + assert(av->n_mmaps <= av->n_mmaps_max); + assert(av->n_mmaps <= av->max_n_mmaps); + + assert((CHUNK_SIZE_T)(av->sbrked_mem) <= + (CHUNK_SIZE_T)(av->max_sbrked_mem)); + + assert((CHUNK_SIZE_T)(av->mmapped_mem) <= + (CHUNK_SIZE_T)(av->max_mmapped_mem)); + + assert((CHUNK_SIZE_T)(av->max_total_mem) >= + (CHUNK_SIZE_T)(av->mmapped_mem) + (CHUNK_SIZE_T)(av->sbrked_mem)); +} +#endif + + + +/* + ----------- Operations on trees ----------- +*/ + +/* + Insert chunk into corresponding list or tree +*/ + +static void insert_treenode(mstate av, tchunkptr x, + CHUNK_SIZE_T nb) { + bin_index_t idx = treebin_index(nb); + tbinptr* bin = tbin_at(av, idx); + tchunkptr t = *bin; + + x->child[0] = 0; + x->child[1] = 0; + x->index = idx; + + if (t == 0) { + av->treebits |= idx2bit(idx); + *bin = x; + x->parent = (tchunkptr)bin; + x->fd = x; + x->bk = x; + } + else { + bin_index_t shift = bitshift_for_index(idx); + tchunkptr b; + check_tree(t); + + while (chunksize(t) != nb) { + tchunkptr* pchild = &(t->child[(nb >> shift--) & 1]); + if (*pchild != 0) { + t = *pchild; + } + else { + *pchild = x; + x->parent = t; + x->fd = x; + x->bk = x; + return; + } + } + /* Link in same-sized node */ + b = t->bk; + x->parent = 0; + x->fd = t; + x->bk = b; + b->fd = t->bk = x; + } +} + +static void transfer_tree_links(tchunkptr oldt, tchunkptr newt) { + tchunkptr p = oldt->parent; + newt->parent = p; + + if (p->child[0] == oldt) + p->child[0] = newt; + else if (p->child[1] == oldt) + p->child[1] = newt; + else + *((tbinptr*)p) = newt; + + if ( (newt->child[0] = oldt->child[0]) != 0) + newt->child[0]->parent = newt; + + if ( (newt->child[1] = oldt->child[1]) != 0) + newt->child[1]->parent = newt; +} + +static tchunkptr find_replacement(tchunkptr t) { + /* + Unless t is itself a leaf node, we must replace t with a leaf + node (not merely one with an open left or right, as with binary + search trees), to make sure that lefts and rights of descendents + correspond properly to bit masks. We use the leftmost leaf of + right child, or, if there is no right child, the rightmost leaf + of left child. We could use any other leaf, but these choices + will tend to maintain nicer trees. + */ + tchunkptr* cp; + tchunkptr c; + if ((c = *(cp = &(t->child[1]))) == 0) + if ((c = *(cp = &(t->child[0]->child[1]))) == 0) + c = *(cp = &(t->child[0])); + + assert(c != 0); + for (;;) { + if (c->child[0] != 0) + c = *(cp = &(c->child[0])); + else if (c->child[1] != 0) + c = *(cp = &(c->child[1])); + else { + *cp = 0; /* unlink from parent */ + return c; + } + } +} + +static void unlink_leaf_node(mstate av, tchunkptr t) { + tchunkptr p = t->parent; + if (p->child[0] == t) + p->child[0] = 0; + else if (p->child[1] == t) + p->child[1] = 0; + else { + assert(is_tbin(av, p)); + *((tbinptr*)p) = 0; + av->treebits &= ~idx2bit(t->index); + } +} + +static void unlink_chained_node(tchunkptr t) { + tchunkptr bck = t->bk; + tchunkptr fwd = t->fd; + fwd->bk = bck; + bck->fd = fwd; + /* t's parent is nonnull if t was head of chain */ + if (t->parent != 0) + transfer_tree_links(t, fwd); + check_tree(fwd); +} + + + +/* + ----------- other helper functions ----------- + We expect these to be inlined +*/ + + +static void insert_small_chunk(mstate av, mchunkptr p, CHUNK_SIZE_T nb) { + bin_index_t idx = smallbin_index(nb); + mchunkptr bck = bin_at(av, idx); + mchunkptr fwd = bck->fd; + mark_smallbin(av, idx); + p->fd = fwd; + p->bk = bck; + fwd->bk = bck->fd = p; + + assert(in_smallbin_range(nb)); +} + +static void insert_chunk(mstate av, mchunkptr p, CHUNK_SIZE_T nb) { + if (in_smallbin_range(nb)) + insert_small_chunk(av, p, nb); + else + insert_treenode(av, (tchunkptr)p, nb); +} + + +static mchunkptr take_from_smallbin(mstate av, mchunkptr bin, bitmap_t bit) { + mchunkptr p = bin->bk; + mchunkptr bck = p->bk; + assert(p != bin); + bin->bk = bck; + bck->fd = bin; + if (bck == bin) + av->smallbits &= ~bit; + return p; +} + +static void unlink_chunk(mstate av, mchunkptr q, CHUNK_SIZE_T size) { + mchunkptr fwd = q->fd; + mchunkptr bck = q->bk; + fwd->bk = bck; + bck->fd = fwd; + if (fwd == bck && in_smallbin_range(size)) { + clear_smallbin(av, smallbin_index(size)); + } + else if (!in_smallbin_range(size)) { + tchunkptr t = (tchunkptr)q; + tchunkptr c = (tchunkptr)fwd; + if (c == t) { + if (t->child[0] == t->child[1]) { + unlink_leaf_node(av, t); + return; + } + else { + c = find_replacement(t); + } + } + else { + if (t->parent == 0) { + return; + } + } + + transfer_tree_links(t, c); + check_tree(c); + } +} + +static Void_t* use_treechunk(mstate av, + CHUNK_SIZE_T nb, + tchunkptr bestchunk, + CHUNK_SIZE_T bestsize, + tchunkptr leaf) { + + CHUNK_SIZE_T rsize; + + if (bestchunk->bk != bestchunk) + unlink_chained_node(bestchunk); + else { + unlink_leaf_node(av, leaf); + if (leaf != bestchunk) + transfer_tree_links(bestchunk, leaf); + } + + rsize = bestsize - nb; + if (rsize >= MINSIZE) { + mchunkptr rem = chunk_at_offset(bestchunk, nb); + set_head(bestchunk, nb | PREV_INUSE); + set_head(rem, rsize | PREV_INUSE); + set_foot(rem, rsize); + insert_chunk(av, rem, rsize); + } + else { + set_inuse_bit_at_offset(bestchunk, bestsize); + } + check_malloced_chunk((mchunkptr)(bestchunk), nb); + return chunk2mem(bestchunk); +} + + +/* + ------------------------------ malloc ------------------------------ +*/ + +Void_t* mALLOc(size_t bytes) { + mstate av = get_malloc_state(); + CHUNK_SIZE_T nb; + + checked_request2size(bytes, nb); + + if (nb <= (CHUNK_SIZE_T)(av->max_fast)) { + mfastbinptr* fb = &(av->fastbins[(fastbin_index(nb))]); + mchunkptr fp = *fb; + if (fp != 0) { + *fb = fp->fd; + check_remalloced_chunk(fp, nb); + return chunk2mem(fp); + } + } + + + for (;;) { + if (in_smallbin_range(nb)) { + bin_index_t sidx = smallbin_index(nb); + bitmap_t sbit = idx2bit(sidx); + + if (sbit <= av->smallbits) { + mchunkptr p; + if ((sbit & av->smallbits) != 0) { + p = take_from_smallbin(av, bin_at(av,sidx), sbit); + set_inuse_bit_at_offset(p, nb); + } + else { + bitmap_t nbit = least_bit(left_bits(sbit) & av->smallbits); + bin_index_t nidx = bit2idx(nbit); + CHUNK_SIZE_T psize = size_for_smallindex(nidx); + CHUNK_SIZE_T qsize = psize - nb; + p = take_from_smallbin(av, bin_at(av, nidx), nbit); + if (qsize < MINSIZE) { + set_inuse_bit_at_offset(p, psize); + } + else { + mchunkptr q = chunk_at_offset(p, nb); + set_head(p, nb | PREV_INUSE); + set_head(q, qsize | PREV_INUSE); + set_foot(q, qsize); + insert_small_chunk(av, q, qsize); + } + } + check_malloced_chunk(p, nb); + return chunk2mem(p); + } + + if (av->treebits != 0) { + bitmap_t vbit = least_bit(av->treebits); + bin_index_t vidx = bit2idx(vbit); + tbinptr* vbin = tbin_at(av, vidx); + tchunkptr bestchunk = *vbin; + tchunkptr c = leftmost_child(bestchunk); + CHUNK_SIZE_T bestsize = chunksize(bestchunk); + tchunkptr leaf; + CHUNK_SIZE_T rsize; + + /* Fast path if remainder will replace bestchunk */ + if (c == 0) { + rsize = bestsize - nb; + leaf = bestchunk; + + if (rsize >= minsize_for_treeindex(vidx) && + bestchunk->bk == bestchunk) { + tchunkptr r = (tchunkptr)(chunk_at_offset(bestchunk, nb)); + + set_head(bestchunk, nb | PREV_INUSE); + set_head(r, rsize | PREV_INUSE); + set_foot(r, rsize); + *vbin = r; + r->fd = r; + r->bk = r; + r->child[0] = 0; + r->child[1] = 0; + r->parent = (tchunkptr)vbin; + r->index = vidx; + check_malloced_chunk((mchunkptr)bestchunk, nb); + return chunk2mem(bestchunk); + } + } + else { + do { + CHUNK_SIZE_T csize = chunksize(c); + if (csize < bestsize) { + bestchunk = c; + bestsize = csize; + } + leaf = c; + c = leftmost_child(c); + } while (c != 0); + } + return use_treechunk(av, nb, bestchunk, bestsize, leaf); + } + } + else { + bin_index_t tidx = treebin_index(nb); + bitmap_t tbit = idx2bit(tidx); + + if (tbit <= av->treebits) { + tchunkptr bestchunk = 0; + CHUNK_SIZE_T bestsize = MAX_CHUNK_SIZE; + tchunkptr leaf; + bitmap_t vbit; + + for (;;) { + if ((tbit & av->treebits) != 0) { + tchunkptr t = *tbin_at(av, tidx); + bin_index_t shift = bitshift_for_index(tidx); + for (;;) { + int dir; + CHUNK_SIZE_T tsize = chunksize(t); + leaf = t; + if (tsize >= nb && tsize < bestsize) { + bestchunk = t; + bestsize = tsize; + if (tsize == nb && t->bk != t) + break; + } + + dir = (shift == 0)? 0 : (nb >> shift--) & 1; + t = leaf->child[dir]; + if (t == 0) { + shift = 0; /* if forced right, go leftmost from now on */ + t = leaf->child[1-dir]; + if (t == 0) + break; + } + } + if (bestchunk != 0) + return use_treechunk(av, nb, bestchunk, bestsize, leaf); + } + if (have_fastchunks(av)) + malloc_consolidate(av); + else + break; + } + + vbit = least_bit(left_bits(tbit) & av->treebits); + if (vbit != 0) { + bin_index_t vidx = bit2idx(vbit); + tbinptr* vbin = tbin_at(av, vidx); + tchunkptr c = *vbin; + do { + CHUNK_SIZE_T csize = chunksize(c); + leaf = c; + if (csize < bestsize) { + bestchunk = c; + bestsize = csize; + } + c = leftmost_child(c); + } while (c != 0); + return use_treechunk(av, nb, bestchunk, bestsize, leaf); + } + } + } + + /* + If large enough, split off the chunk bordering the end of memory + (held in av->top). This is called in accord with the best-fit + search rule. In effect, av->top is treated as larger (and thus + less well fitting) than any other available chunk since it can + be extended to be as large as necessary (up to system + limitations). + + We require that av->top always exists (i.e., has size >= + MINSIZE) after initialization, so if it would otherwise be + exhuasted by current request, it is replenished. (The main + reason for ensuring it exists is that we may need MINSIZE space + to put in fenceposts in sysmalloc.) + */ + + if (av->top != 0) { + mchunkptr topchunk = av->top; + CHUNK_SIZE_T topsize = chunksize(topchunk); + + if (topsize >= nb + MINSIZE) { + CHUNK_SIZE_T remainder_size = topsize - nb; + mchunkptr remainder = chunk_at_offset(topchunk, nb); + + av->top = remainder; + set_head(topchunk, nb | PREV_INUSE); + set_head(remainder, remainder_size | PREV_INUSE); + + check_malloced_chunk(topchunk, nb); + return chunk2mem(topchunk); + } + else if (have_fastchunks(av)) { + malloc_consolidate(av); + } + else + break; + } + else + break; + } + return sysmalloc(av, nb); +} + +/* + ------------------------------ free ------------------------------ +*/ + + +void fREe(Void_t* mem) { + mstate av = get_malloc_state(); + + mchunkptr p = mem2chunk(mem); + + if (mem != 0) { + INTERNAL_SIZE_T rawsize = p->size; + CHUNK_SIZE_T size = chunksize(p); + check_inuse_chunk(p); + + /* + If eligible, place chunk on a fastbin so it can be found + and used quickly in malloc. + */ + + if ((CHUNK_SIZE_T)(size) <= (CHUNK_SIZE_T)(av->max_fast) + +#if TRIM_FASTBINS + /* + If TRIM_FASTBINS set, don't place chunks + bordering top into fastbins + */ + && (chunk_at_offset(p, size) != av->top) +#endif + ) { + + mfastbinptr* fb; + set_fastchunks(av); + fb = &(av->fastbins[fastbin_index(size)]); + p->fd = *fb; + *fb = p; + } + + else if ((rawsize & IS_MMAPPED) == 0) { + mchunkptr nextchunk = chunk_at_offset(p, size); + CHUNK_SIZE_T nextsize; + + if ((rawsize & PREV_INUSE) == 0) { + CHUNK_SIZE_T prevsize = p->prev_size; + size += prevsize; + p = chunk_at_offset(p, -((long) prevsize)); + unlink_chunk(av, p, prevsize); + } + + nextsize = chunksize(nextchunk); + if (nextchunk == av->top) { + size += nextsize; + set_head(p, size | PREV_INUSE); + av->top = p; + if (size >= av->trim_threshold) { + systrim(av, av->top_pad); + } + } + else { + if (!inuse_bit_at_offset(nextchunk, nextsize)) { + size += nextsize; + unlink_chunk(av, nextchunk, nextsize); + } + else + set_head(nextchunk, nextsize); + + set_head(p, size | PREV_INUSE); + set_foot(p, size); + insert_chunk(av, p, size); + } + } + else { +#if HAVE_MMAP + int ret; + INTERNAL_SIZE_T offset = p->prev_size; + av->n_mmaps--; + av->mmapped_mem -= (size + offset); + ret = munmap((char*)p - offset, size + offset); + /* munmap returns non-zero on failure */ + assert(ret == 0); +#endif + } + } +} + +/* + ------------------------- malloc_consolidate ------------------------- + + malloc_consolidate tears down chunks held in fastbins. +*/ + +static void malloc_consolidate(mstate av) { + int i; + clear_fastchunks(av); + + for (i = 0; i < NFASTBINS; ++i) { + mfastbinptr* fb = &(av->fastbins[i]); + mchunkptr p = *fb; + + if (p != 0) { + *fb = 0; + do { + mchunkptr nextp = p->fd; + INTERNAL_SIZE_T rawsize = p->size; + CHUNK_SIZE_T size = chunksize(p); + mchunkptr nextchunk = chunk_at_offset(p, size); + CHUNK_SIZE_T nextsize; + + if ((rawsize & PREV_INUSE) == 0) { + CHUNK_SIZE_T prevsize = p->prev_size; + size += prevsize; + p = chunk_at_offset(p, -((long) prevsize)); + unlink_chunk(av, p, prevsize); + } + + nextsize = chunksize(nextchunk); + if (nextchunk == av->top) { + size += nextsize; + set_head(p, size | PREV_INUSE); + av->top = p; + } + else { + if (!inuse_bit_at_offset(nextchunk, nextsize)) { + size += nextsize; + unlink_chunk(av, nextchunk, nextsize); + } + else + set_head(nextchunk, nextsize); + + set_head(p, size | PREV_INUSE); + set_foot(p, size); + + insert_chunk(av, p, size); + } + p = nextp; + } while (p != 0); + } + } +} + + +/* + ------------------------------ realloc ------------------------------ +*/ + + +Void_t* rEALLOc(Void_t* oldmem, size_t bytes) { + mstate av = get_malloc_state(); + + INTERNAL_SIZE_T nb; /* padded request size */ + + mchunkptr oldp; /* chunk corresponding to oldmem */ + CHUNK_SIZE_T oldsize; /* its size */ + + mchunkptr newp; /* chunk to return */ + CHUNK_SIZE_T newsize; /* its size */ + Void_t* newmem; /* corresponding user mem */ + + mchunkptr next; /* next contiguous chunk after oldp */ + + mchunkptr remainder; /* extra space at end of newp */ + CHUNK_SIZE_T remainder_size; /* its size */ + + CHUNK_SIZE_T copysize; /* bytes to copy */ + unsigned int ncopies; /* INTERNAL_SIZE_T words to copy */ + INTERNAL_SIZE_T* s; /* copy source */ + INTERNAL_SIZE_T* d; /* copy destination */ + + +#ifdef REALLOC_ZERO_BYTES_FREES + if (bytes == 0) { + fREe(oldmem); + return 0; + } +#endif + + /* realloc of null is supposed to be same as malloc */ + if (oldmem == 0) return mALLOc(bytes); + + checked_request2size(bytes, nb); + + oldp = mem2chunk(oldmem); + oldsize = chunksize(oldp); + + check_inuse_chunk(oldp); + + if (!chunk_is_mmapped(oldp)) { + + if ((CHUNK_SIZE_T)(oldsize) >= (CHUNK_SIZE_T)(nb)) { + /* already big enough; split below */ + newp = oldp; + newsize = oldsize; + } + + else { + next = chunk_at_offset(oldp, oldsize); + + /* Try to expand forward into top */ + if (next == av->top && + (CHUNK_SIZE_T)(newsize = oldsize + chunksize(next)) >= + (CHUNK_SIZE_T)(nb + MINSIZE)) { + set_head_size(oldp, nb); + av->top = chunk_at_offset(oldp, nb); + set_head(av->top, (newsize - nb) | PREV_INUSE); + return chunk2mem(oldp); + } + + /* Try to expand forward into next chunk; split off remainder below */ + else if (next != av->top && + !inuse(next) && + (CHUNK_SIZE_T)(newsize = oldsize + chunksize(next)) >= + (CHUNK_SIZE_T)(nb)) { + newp = oldp; + unlink_chunk(av, next, chunksize(next)); + } + + /* allocate, copy, free */ + else { + newmem = mALLOc(nb - MALLOC_ALIGN_MASK); + if (newmem == 0) + return 0; /* propagate failure */ + + newp = mem2chunk(newmem); + newsize = chunksize(newp); + + /* + Avoid copy if newp is next chunk after oldp. + */ + if (newp == next) { + newsize += oldsize; + newp = oldp; + } + else { + /* + Unroll copy of <= 36 bytes (72 if 8byte sizes) + We know that contents have an odd number of + INTERNAL_SIZE_T-sized words; minimally 3. + */ + + copysize = oldsize - SIZE_SZ; + s = (INTERNAL_SIZE_T*)(oldmem); + d = (INTERNAL_SIZE_T*)(newmem); + ncopies = copysize / sizeof(INTERNAL_SIZE_T); + assert(ncopies >= 3); + + if (ncopies > 9) + MALLOC_COPY(d, s, copysize); + + else { + *(d+0) = *(s+0); + *(d+1) = *(s+1); + *(d+2) = *(s+2); + if (ncopies > 4) { + *(d+3) = *(s+3); + *(d+4) = *(s+4); + if (ncopies > 6) { + *(d+5) = *(s+5); + *(d+6) = *(s+6); + if (ncopies > 8) { + *(d+7) = *(s+7); + *(d+8) = *(s+8); + } + } + } + } + + fREe(oldmem); + check_inuse_chunk(newp); + return chunk2mem(newp); + } + } + } + + /* If possible, free extra space in old or extended chunk */ + + assert((CHUNK_SIZE_T)(newsize) >= (CHUNK_SIZE_T)(nb)); + + remainder_size = newsize - nb; + + if (remainder_size < MINSIZE) { /* not enough extra to split off */ + set_head_size(newp, newsize); + set_inuse_bit_at_offset(newp, newsize); + } + else { /* split remainder */ + remainder = chunk_at_offset(newp, nb); + set_head_size(newp, nb); + set_head(remainder, remainder_size | PREV_INUSE); + /* Mark remainder as inuse so free() won't complain */ + set_inuse_bit_at_offset(remainder, remainder_size); + fREe(chunk2mem(remainder)); + } + + check_inuse_chunk(newp); + return chunk2mem(newp); + } + + /* + Handle mmap cases + */ + + else { +#if HAVE_MMAP + +#if HAVE_MREMAP + INTERNAL_SIZE_T offset = oldp->prev_size; + size_t pagemask = av->pagesize - 1; + char *cp; + CHUNK_SIZE_T sum; + + /* Note the extra SIZE_SZ overhead */ + newsize = (nb + offset + SIZE_SZ + pagemask) & ~pagemask; + + /* don't need to remap if still within same page */ + if (oldsize == newsize - offset) + return oldmem; + + cp = (char*)mremap((char*)oldp - offset, oldsize + offset, newsize, 1); + + if (cp != (char*)MORECORE_FAILURE) { + + newp = (mchunkptr)(cp + offset); + set_head(newp, (newsize - offset)|IS_MMAPPED); + + assert(aligned_OK(chunk2mem(newp))); + assert((newp->prev_size == offset)); + + /* update statistics */ + sum = av->mmapped_mem += newsize - oldsize; + if (sum > (CHUNK_SIZE_T)(av->max_mmapped_mem)) + av->max_mmapped_mem = sum; + sum += av->sbrked_mem; + if (sum > (CHUNK_SIZE_T)(av->max_total_mem)) + av->max_total_mem = sum; + + return chunk2mem(newp); + } +#endif + + /* Note the extra SIZE_SZ overhead. */ + if ((CHUNK_SIZE_T)(oldsize) >= (CHUNK_SIZE_T)(nb + SIZE_SZ)) + newmem = oldmem; /* do nothing */ + else { + /* Must alloc, copy, free. */ + newmem = mALLOc(nb - MALLOC_ALIGN_MASK); + if (newmem != 0) { + MALLOC_COPY(newmem, oldmem, oldsize - 2*SIZE_SZ); + fREe(oldmem); + } + } + return newmem; + +#else + /* If !HAVE_MMAP, but chunk_is_mmapped, user must have overwritten mem */ + check_malloc_state(av); + MALLOC_FAILURE_ACTION; + return 0; +#endif + } +} + +/* + ------------------------------ memalign ------------------------------ +*/ + +Void_t* mEMALIGn(size_t alignment, size_t bytes) { + INTERNAL_SIZE_T nb; /* padded request size */ + char* m; /* memory returned by malloc call */ + mchunkptr p; /* corresponding chunk */ + char* brk; /* alignment point within p */ + mchunkptr newp; /* chunk to return */ + INTERNAL_SIZE_T newsize; /* its size */ + INTERNAL_SIZE_T leadsize; /* leading space before alignment point */ + mchunkptr remainder; /* spare room at end to split off */ + CHUNK_SIZE_T remainder_size; /* its size */ + INTERNAL_SIZE_T size; + + /* If need less alignment than we give anyway, just relay to malloc */ + + if (alignment <= MALLOC_ALIGNMENT) return mALLOc(bytes); + + /* Otherwise, ensure that it is at least a minimum chunk size */ + + if (alignment < MINSIZE) alignment = MINSIZE; + + /* Make sure alignment is power of 2 (in case MINSIZE is not). */ + if ((alignment & (alignment - 1)) != 0) { + size_t a = MALLOC_ALIGNMENT * 2; + while ((CHUNK_SIZE_T)a < (CHUNK_SIZE_T)alignment) a <<= 1; + alignment = a; + } + + checked_request2size(bytes, nb); + + /* + Strategy: find a spot within that chunk that meets the alignment + request, and then possibly free the leading and trailing space. + */ + + + /* Call malloc with worst case padding to hit alignment. */ + + m = (char*)(mALLOc(nb + alignment + MINSIZE)); + + if (m == 0) return 0; /* propagate failure */ + + p = mem2chunk(m); + + if ((((PTR_UINT)(m)) % alignment) != 0) { /* misaligned */ + + /* + Find an aligned spot inside chunk. Since we need to give back + leading space in a chunk of at least MINSIZE, if the first + calculation places us at a spot with less than MINSIZE leader, + we can move to the next aligned spot -- we've allocated enough + total room so that this is always possible. + */ + + brk = (char*)mem2chunk((PTR_UINT)(((PTR_UINT)(m + alignment - 1)) & + -((signed long) alignment))); + if ((CHUNK_SIZE_T)(brk - (char*)(p)) < MINSIZE) + brk += alignment; + + newp = (mchunkptr)brk; + leadsize = brk - (char*)(p); + newsize = chunksize(p) - leadsize; + + /* For mmapped chunks, just adjust offset */ + if (chunk_is_mmapped(p)) { + newp->prev_size = p->prev_size + leadsize; + set_head(newp, newsize|IS_MMAPPED); + return chunk2mem(newp); + } + + /* Otherwise, give back leader, use the rest */ + set_head(newp, newsize | PREV_INUSE); + set_inuse_bit_at_offset(newp, newsize); + set_head_size(p, leadsize); + fREe(chunk2mem(p)); + p = newp; + + assert (newsize >= nb && + (((PTR_UINT)(chunk2mem(p))) % alignment) == 0); + } + + /* Also give back spare room at the end */ + if (!chunk_is_mmapped(p)) { + size = chunksize(p); + if ((CHUNK_SIZE_T)(size) > (CHUNK_SIZE_T)(nb + MINSIZE)) { + remainder_size = size - nb; + remainder = chunk_at_offset(p, nb); + set_head(remainder, remainder_size | PREV_INUSE); + set_head_size(p, nb); + fREe(chunk2mem(remainder)); + } + } + + check_inuse_chunk(p); + return chunk2mem(p); +} + +/* + ------------------------------ calloc ------------------------------ +*/ + +Void_t* cALLOc(size_t n_elements, size_t elem_size) { + Void_t* mem = mALLOc(n_elements * elem_size); + + if (mem != 0) { + mchunkptr p = mem2chunk(mem); + INTERNAL_SIZE_T* d = (INTERNAL_SIZE_T*)mem; + + if (!chunk_is_mmapped(p)) + { + /* + Unroll clear of <= 36 bytes (72 if 8byte sizes) + We know that contents have an odd number of + INTERNAL_SIZE_T-sized words; minimally 3. + */ + + CHUNK_SIZE_T clearsize = chunksize(p) - SIZE_SZ; + CHUNK_SIZE_T nclears = clearsize / sizeof(INTERNAL_SIZE_T); + assert(nclears >= 3); + + if (nclears > 9) + MALLOC_ZERO(d, clearsize); + + else { + *(d+0) = 0; + *(d+1) = 0; + *(d+2) = 0; + if (nclears > 4) { + *(d+3) = 0; + *(d+4) = 0; + if (nclears > 6) { + *(d+5) = 0; + *(d+6) = 0; + if (nclears > 8) { + *(d+7) = 0; + *(d+8) = 0; + } + } + } + } + } +#if ! MMAP_CLEARS + else + { + /* + Note the additional SIZE_SZ + */ + CHUNK_SIZE_T clearsize = chunksize(p) - 2*SIZE_SZ; + MALLOC_ZERO(d, clearsize); + } +#endif + } + return mem; +} + +/* + ------------------------------ cfree ------------------------------ +*/ + +void cFREe(Void_t *mem) { + fREe(mem); +} + +/* + ------------------------- independent_calloc ------------------------- +*/ + + +Void_t** iCALLOc(size_t n_elements, size_t elem_size, Void_t* chunks[]) { + size_t sz = elem_size; /* serves as 1-element array */ + /* opts arg of 3 means all elements are same size, and should be cleared */ + return iALLOc(n_elements, &sz, 3, chunks); +} + +/* + ------------------------- independent_comalloc ------------------------- +*/ + +Void_t** iCOMALLOc(size_t n_elements, size_t sizes[], Void_t* chunks[]) { + return iALLOc(n_elements, sizes, 0, chunks); +} + + +/* + ------------------------------ ialloc ------------------------------ + ialloc provides common support for independent_X routines, handling all of + the combinations that can result. + + The opts arg has: + bit 0 set if all elements are same size (using sizes[0]) + bit 1 set if elements should be zeroed +*/ + + +static Void_t** iALLOc(size_t n_elements, + size_t* sizes, + int opts, + Void_t* chunks[]) { + mstate av = get_malloc_state(); + INTERNAL_SIZE_T element_size; /* chunksize of each element, if all same */ + INTERNAL_SIZE_T contents_size; /* total size of elements */ + INTERNAL_SIZE_T array_size; /* request size of pointer array */ + Void_t* mem; /* malloced aggregate space */ + mchunkptr p; /* corresponding chunk */ + CHUNK_SIZE_T remainder_size; /* remaining bytes while splitting */ + Void_t** marray; /* either "chunks" or malloced ptr array */ + mchunkptr array_chunk; /* chunk for malloced ptr array */ + unsigned int mprops; /* to disable mmap */ + CHUNK_SIZE_T size; + size_t i; + + ensure_initialization(av); + + /* compute array length, if needed */ + if (chunks != 0) { + if (n_elements == 0) + return chunks; /* nothing to do */ + marray = chunks; + array_size = 0; + } + else { + /* if empty req, must still return chunk representing empty array */ + if (n_elements == 0) + return (Void_t**) mALLOc(0); + marray = 0; + array_size = request2size(n_elements * (sizeof(Void_t*))); + } + + /* compute total element size */ + if (opts & 0x1) { /* all-same-size */ + element_size = request2size(*sizes); + contents_size = n_elements * element_size; + } + else { /* add up all the sizes */ + element_size = 0; + contents_size = 0; + for (i = 0; i != n_elements; ++i) + contents_size += request2size(sizes[i]); + } + + /* subtract out alignment bytes from total to minimize overallocation */ + size = contents_size + array_size - MALLOC_ALIGN_MASK; + + /* + Allocate the aggregate chunk. + But first disable mmap so malloc won't use it, since + we would not be able to later free/realloc space internal + to a segregated mmap region. + */ + + mprops = av->sysctl; /* disable mmap */ + disable_mmap(av); + mem = mALLOc(size); + av->sysctl = mprops; /* reset mmap */ + if (mem == 0) + return 0; + + p = mem2chunk(mem); + assert(!chunk_is_mmapped(p)); + remainder_size = chunksize(p); + + + if (opts & 0x2) { /* optionally clear the elements */ + MALLOC_ZERO(mem, remainder_size - SIZE_SZ - array_size); + } + + /* If not provided, allocate the pointer array as final part of chunk */ + if (marray == 0) { + array_chunk = chunk_at_offset(p, contents_size); + marray = (Void_t**) (chunk2mem(array_chunk)); + set_head(array_chunk, (remainder_size - contents_size) | PREV_INUSE); + remainder_size = contents_size; + } + + /* split out elements */ + for (i = 0; ; ++i) { + marray[i] = chunk2mem(p); + if (i != n_elements-1) { + if (element_size != 0) + size = element_size; + else + size = request2size(sizes[i]); + remainder_size -= size; + set_head(p, size | PREV_INUSE); + p = chunk_at_offset(p, size); + } + else { /* the final element absorbs any overallocation slop */ + set_head(p, remainder_size | PREV_INUSE); + break; + } + } + +#if DEBUG + if (marray != chunks) { + /* final element must have exactly exhausted chunk */ + if (element_size != 0) + assert(remainder_size == element_size); + else + assert(remainder_size == request2size(sizes[i])); + check_inuse_chunk(mem2chunk(marray)); + } + + for (i = 0; i != n_elements; ++i) + check_inuse_chunk(mem2chunk(marray[i])); +#endif + + return marray; +} + + +/* + ------------------------------ valloc ------------------------------ +*/ + +Void_t* vALLOc(size_t bytes) { + mstate av = get_malloc_state(); + ensure_initialization(av); + return mEMALIGn(av->pagesize, bytes); +} + +/* + ------------------------------ pvalloc ------------------------------ +*/ + + +Void_t* pVALLOc(size_t bytes) { + mstate av = get_malloc_state(); + size_t pagesz; + + ensure_initialization(av); + pagesz = av->pagesize; + return mEMALIGn(pagesz, (bytes + pagesz - 1) & ~(pagesz - 1)); +} + + +/* + ------------------------------ malloc_trim ------------------------------ +*/ + +int mTRIm(size_t pad) { + mstate av = get_malloc_state(); + return systrim(av, pad); +} + + +/* + ------------------------- malloc_usable_size ------------------------- +*/ + +size_t mUSABLe(Void_t* mem) { + mchunkptr p; + if (mem != 0) { + p = mem2chunk(mem); + if (chunk_is_mmapped(p)) + return chunksize(p) - 2*SIZE_SZ; + else if (inuse(p)) + return chunksize(p) - SIZE_SZ; + } + return 0; +} + +/* + ------------------------------ mallinfo ------------------------------ +*/ + +/* + Recursive helper function for mallinfo +*/ + +static void count_tree_blocks(tchunkptr t, int* pcount, INTERNAL_SIZE_T* pavail) { + while (t != 0) { + tchunkptr p = t->bk; + do { + (*pcount)++; + *pavail += chunksize(p); + p = p->bk; + } while (p != t); + if (t->child[0] != 0) + count_tree_blocks(t->child[0], pcount, pavail); + t = t->child[1]; + } +} + + + +struct mallinfo mALLINFo() +{ + mstate av = get_malloc_state(); + struct mallinfo mi; + INTERNAL_SIZE_T avail; + INTERNAL_SIZE_T topsize; + int nblocks; + INTERNAL_SIZE_T fastavail; + int nfastblocks; + mchunkptr p; + + if (av->top == 0) { + avail = 0; + topsize = 0; + nblocks = 0; + } + else { + int i; + check_malloc_state(av); + + topsize = chunksize(av->top); + avail = topsize; + nblocks = 1; /* top always exists */ + + /* traverse fastbins */ + nfastblocks = 0; + fastavail = 0; + + for (i = 0; i < NFASTBINS; ++i) { + for (p = av->fastbins[i]; p != 0; p = p->fd) { + ++nfastblocks; + fastavail += chunksize(p); + } + } + + avail += fastavail; + + /* traverse small bins */ + for (i = 2; i < NBINS; ++i) { + mbinptr b = bin_at(av, i); + mchunkptr p; + for (p = b->bk; p != b; p = p->bk) { + ++nblocks; + avail += chunksize(p); + } + } + + /* traverse tree bins */ + for (i = 0; i < NBINS; ++i) { + tchunkptr t = *(tbin_at(av, i)); + if (t != 0) + count_tree_blocks(t, &nblocks, &avail); + } + } + + mi.smblks = nfastblocks; + mi.smblks = 0; + mi.ordblks = nblocks; + mi.fordblks = avail; + mi.uordblks = av->sbrked_mem - avail; + mi.arena = av->sbrked_mem; + mi.hblks = av->n_mmaps; + mi.hblkhd = av->mmapped_mem; + mi.fsmblks = 0; + mi.keepcost = topsize; + mi.usmblks = av->max_total_mem; + return mi; +} + +/* + ------------------------------ malloc_stats ------------------------------ +*/ + +void mSTATs() { + struct mallinfo mi = mALLINFo(); + +#ifdef WIN32 + { + CHUNK_SIZE_T free, reserved, committed; + vminfo (&free, &reserved, &committed); + fprintf(stderr, "free bytes = %10lu\n", + free); + fprintf(stderr, "reserved bytes = %10lu\n", + reserved); + fprintf(stderr, "committed bytes = %10lu\n", + committed); + } +#endif + + + fprintf(stderr, "max system bytes = %10lu\n", + (CHUNK_SIZE_T)(mi.usmblks)); + fprintf(stderr, "system bytes = %10lu\n", + (CHUNK_SIZE_T)(mi.arena + mi.hblkhd)); + fprintf(stderr, "in use bytes = %10lu\n", + (CHUNK_SIZE_T)(mi.uordblks + mi.hblkhd)); + +#if 0 + fprintf(stderr, "n0 = %10u\n", n0); + fprintf(stderr, "n1 = %10u\n", n1); + fprintf(stderr, "n2 = %10u\n", n2); + fprintf(stderr, "n3 = %10u\n", n3); + fprintf(stderr, "n4 = %10u\n", n4); + fprintf(stderr, "n5 = %10u\n", n5); + fprintf(stderr, "n6 = %10u\n", n6); + fprintf(stderr, "n7 = %10u\n", n7); + fprintf(stderr, "n8 = %10u\n", n8); +#endif + + +#ifdef WIN32 + { + CHUNK_SIZE_T kernel, user; + if (cpuinfo (TRUE, &kernel, &user)) { + fprintf(stderr, "kernel ms = %10lu\n", + kernel); + fprintf(stderr, "user ms = %10lu\n", + user); + } + } +#endif +} + + +/* + ------------------------------ mallopt ------------------------------ +*/ + +int mALLOPt(int param_number, int value) { + mstate av = get_malloc_state(); + + ensure_initialization(av); + + switch(param_number) { + case M_MXFAST: + malloc_consolidate(av); + if (value >= 0 && value <= MAX_FAST_SIZE) { + set_max_fast(av, value); + return 1; + } + else + return 0; + + case M_TRIM_THRESHOLD: + av->trim_threshold = value; + return 1; + + case M_TOP_PAD: + av->top_pad = value; + return 1; + + case M_MMAP_THRESHOLD: + av->mmap_threshold = value; + return 1; + + case M_MMAP_MAX: +#if !HAVE_MMAP + if (value != 0) + return 0; +#endif + av->n_mmaps_max = value; + return 1; + + default: + return 0; + } +} + +/* ----------- Routines dealing with system allocation -------------- */ + +#if HAVE_MMAP +static mchunkptr mmap_malloc(mstate av, INTERNAL_SIZE_T nb) { + char* mm; /* return value from mmap call*/ + CHUNK_SIZE_T sum; /* for updating stats */ + mchunkptr p; /* the allocated/returned chunk */ + long size; + INTERNAL_SIZE_T front_misalign; /* unusable bytes at front of new space */ + long correction; + size_t pagemask = av->pagesize - 1; + + /* + Round up size to nearest page. For mmapped chunks, the overhead + is one SIZE_SZ unit larger than for normal chunks, because there + is no following chunk whose prev_size field could be used. + */ + size = (nb + SIZE_SZ + MALLOC_ALIGN_MASK + pagemask) & ~pagemask; + + /* Don't try if size wraps around 0 */ + if ((CHUNK_SIZE_T)(size) > (CHUNK_SIZE_T)(nb)) { + + mm = (char*)(MMAP(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE)); + + if (mm != (char*)(MORECORE_FAILURE)) { + + /* + The offset to the start of the mmapped region is stored + in the prev_size field of the chunk. This allows us to adjust + returned start address to meet alignment requirements here + and in memalign(), and still be able to compute proper + address argument for later munmap in free() and realloc(). + */ + + front_misalign = (INTERNAL_SIZE_T)chunk2mem(mm) & MALLOC_ALIGN_MASK; + if (front_misalign > 0) { + correction = MALLOC_ALIGNMENT - front_misalign; + p = (mchunkptr)(mm + correction); + p->prev_size = correction; + set_head(p, (size - correction) |IS_MMAPPED); + } + else { + p = (mchunkptr)mm; + p->prev_size = 0; + set_head(p, size|IS_MMAPPED); + } + + /* update statistics */ + + if (++av->n_mmaps > av->max_n_mmaps) + av->max_n_mmaps = av->n_mmaps; + + sum = av->mmapped_mem += size; + if (sum > (CHUNK_SIZE_T)(av->max_mmapped_mem)) + av->max_mmapped_mem = sum; + sum += av->sbrked_mem; + if (sum > (CHUNK_SIZE_T)(av->max_total_mem)) + av->max_total_mem = sum; + + check_chunk(p); + + return p; + } + } + return 0; +} +#endif + + +/* + sysmalloc handles malloc cases requiring more memory from the system. + On entry, it is assumed that av->top does not have enough + space to service request for nb bytes, thus requiring that av->top + be extended or replaced. +*/ + +static Void_t* sysmalloc(mstate av, CHUNK_SIZE_T nb) { + mchunkptr old_top; /* incoming value of av->top */ + INTERNAL_SIZE_T old_size; /* its size */ + char* old_end; /* its end address */ + + long size; /* arg to first MORECORE or mmap call */ + char* brk; /* return value from MORECORE */ + + long correction; /* arg to 2nd MORECORE call */ + char* snd_brk; /* 2nd return val */ + + INTERNAL_SIZE_T front_misalign; /* unusable bytes at front of new space */ + INTERNAL_SIZE_T end_misalign; /* partial page left at end of new space */ + char* aligned_brk; /* aligned offset into brk */ + + mchunkptr p; /* the allocated/returned chunk */ + mchunkptr remainder; /* remainder from allocation */ + CHUNK_SIZE_T remainder_size; /* its size */ + + CHUNK_SIZE_T sum; /* for updating stats */ + + size_t pagemask; + + /* + Initialize av if necessary + */ + if (av->top == 0) { + malloc_init_state(av); + /* to allow call solely for initialization */ + if (nb == 0) + return 0; + } + + +#if HAVE_MMAP + /* + If have mmap, and the request size meets the mmap threshold, and + the system supports mmap, and there are few enough currently + allocated mmapped regions, try to directly map this request + rather than expanding top. + */ + + if ((CHUNK_SIZE_T)(nb) >= (CHUNK_SIZE_T)(av->mmap_threshold) && + (av->n_mmaps < av->n_mmaps_max) && + !mmap_disabled(av)) { + Void_t* mp = mmap_malloc(av, nb); + if (mp != 0) + return chunk2mem(mp); + } +#endif + + + pagemask = av->pagesize - 1; + + /* Record incoming configuration of top */ + + old_top = av->top; + old_size = chunksize(old_top); + old_end = (char*)(chunk_at_offset(old_top, old_size)); + + brk = snd_brk = (char*)(MORECORE_FAILURE); + + /* + If not the first time through, we require old_size to be + at least MINSIZE and to have prev_inuse set. + */ + + assert((old_top == (mchunkptr)(&(av->initial_top)) && old_size == 0) || + ((CHUNK_SIZE_T) (old_size) >= MINSIZE && + prev_inuse(old_top))); + + /* Precondition: not enough current space to satisfy nb request */ + assert((CHUNK_SIZE_T)(old_size) < (CHUNK_SIZE_T)(nb + MINSIZE)); + + /* Request enough space for nb + pad + overhead */ + + size = nb + av->top_pad + MINSIZE; + + /* + If contiguous, we can subtract out existing space that we hope to + combine with new space. We add it back later only if + we don't actually get contiguous space. + */ + + if (contiguous(av)) + size -= old_size; + + /* + Round to a multiple of page size. + If MORECORE is not contiguous, this ensures that we only call it + with whole-page arguments. And if MORECORE is contiguous and + this is not first time through, this preserves page-alignment of + previous calls. Otherwise, we correct to page-align below. + */ + + size = (size + pagemask) & ~pagemask; + + /* + Don't try to call MORECORE if argument is so big as to appear + negative. Note that since mmap takes size_t arg, it may succeed + below even if we cannot call MORECORE. + */ + + if (size > 0) + brk = (char*)(MORECORE(size)); + + /* + If have mmap, try using it as a backup when MORECORE fails or + cannot be used. This is worth doing on systems that have "holes" in + address space, so sbrk cannot extend to give contiguous space, but + space is available elsewhere. Note that we ignore mmap max count + and threshold limits, since the space will not be used as a + segregated mmap region. + */ + +#if HAVE_MMAP + if (brk == (char*)(MORECORE_FAILURE)) { + + /* Cannot merge with old top, so add its size back in */ + if (contiguous(av)) + size = (size + old_size + pagemask) & ~pagemask; + + /* If we are relying on mmap as backup, then use larger units */ + if ((CHUNK_SIZE_T)(size) < (CHUNK_SIZE_T)(MMAP_AS_MORECORE_SIZE)) + size = MMAP_AS_MORECORE_SIZE; + + /* Don't try if size wraps around 0 */ + if ((CHUNK_SIZE_T)(size) > (CHUNK_SIZE_T)(nb)) { + + brk = (char*)(MMAP(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE)); + + if (brk != (char*)(MORECORE_FAILURE)) { + + /* We do not need, and cannot use, another sbrk call to find end */ + snd_brk = brk + size; + + /* + Record that we no longer have a contiguous sbrk region. + After the first time mmap is used as backup, we do not + ever rely on contiguous space since this could incorrectly + bridge regions. + */ + set_noncontiguous(av); + } + } + } +#endif + + if (brk != (char*)(MORECORE_FAILURE)) { + av->sbrked_mem += size; + + /* + If MORECORE extends previous space, we can likewise extend top size. + */ + + if (brk == old_end && snd_brk == (char*)(MORECORE_FAILURE)) { + set_head(old_top, (size + old_size) | PREV_INUSE); + } + + /* + Otherwise, make adjustments: + + * If the first time through or noncontiguous, we need to call sbrk + just to find out where the end of memory lies. + + * We need to ensure that all returned chunks from malloc will meet + MALLOC_ALIGNMENT + + * If there was an intervening foreign sbrk, we need to adjust sbrk + request size to account for fact that we will not be able to + combine new space with existing space in old_top. + + * Almost all systems internally allocate whole pages at a time, in + which case we might as well use the whole last page of request. + So we allocate enough more memory to hit a page boundary now, + which in turn causes future contiguous calls to page-align. + */ + + else { + front_misalign = 0; + end_misalign = 0; + correction = 0; + aligned_brk = brk; + + /* + If MORECORE returns an address lower than we have seen before, + we know it isn't really contiguous. This and some subsequent + checks help cope with non-conforming MORECORE functions and + the presence of "foreign" calls to MORECORE from outside of + malloc or by other threads. We cannot guarantee to detect + these in all cases, but cope with the ones we do detect. + */ + if (contiguous(av) && old_size != 0 && brk < old_end) { + set_noncontiguous(av); + } + + /* handle contiguous cases */ + if (contiguous(av)) { + + /* + We can tolerate forward non-contiguities here (usually due + to foreign calls) but treat them as part of our space for + stats reporting. + */ + if (old_size != 0) + av->sbrked_mem += brk - old_end; + + /* Guarantee alignment of first new chunk made from this space */ + + front_misalign = (INTERNAL_SIZE_T)chunk2mem(brk) & MALLOC_ALIGN_MASK; + if (front_misalign > 0) { + + /* + Skip over some bytes to arrive at an aligned position. + We don't need to specially mark these wasted front bytes. + They will never be accessed anyway because + prev_inuse of av->top (and any chunk created from its start) + is always true after initialization. + */ + + correction = MALLOC_ALIGNMENT - front_misalign; + aligned_brk += correction; + } + + /* + If this isn't adjacent to existing space, then we will not + be able to merge with old_top space, so must add to 2nd request. + */ + + correction += old_size; + + /* Extend the end address to hit a page boundary */ + end_misalign = (INTERNAL_SIZE_T)(brk + size + correction); + correction += ((end_misalign + pagemask) & ~pagemask) - end_misalign; + + assert(correction >= 0); + snd_brk = (char*)(MORECORE(correction)); + + if (snd_brk == (char*)(MORECORE_FAILURE)) { + /* + If can't allocate correction, try to at least find out current + brk. It might be enough to proceed without failing. + */ + correction = 0; + snd_brk = (char*)(MORECORE(0)); + } + else if (snd_brk < brk) { + /* + If the second call gives noncontiguous space even though + it says it won't, the only course of action is to ignore + results of second call, and conservatively estimate where + the first call left us. Also set noncontiguous, so this + won't happen again, leaving at most one hole. + + Note that this check is intrinsically incomplete. Because + MORECORE is allowed to give more space than we ask for, + there is no reliable way to detect a noncontiguity + producing a forward gap for the second call. + */ + snd_brk = brk + size; + correction = 0; + set_noncontiguous(av); + } + + } + + /* handle non-contiguous cases */ + else { + /* MORECORE/mmap must correctly align */ + assert(aligned_OK(chunk2mem(brk))); + + /* Find out current end of memory */ + if (snd_brk == (char*)(MORECORE_FAILURE)) { + snd_brk = (char*)(MORECORE(0)); + av->sbrked_mem += snd_brk - brk - size; + } + } + + /* Adjust top based on results of second sbrk */ + if (snd_brk != (char*)(MORECORE_FAILURE)) { + av->top = (mchunkptr)aligned_brk; + set_head(av->top, (snd_brk - aligned_brk + correction) | PREV_INUSE); + av->sbrked_mem += correction; + + /* + If not the first time through, we either have a + gap due to foreign sbrk or a non-contiguous region. Insert a + double fencepost at old_top to prevent consolidation with space + we don't own. These fenceposts are artificial chunks that are + marked as inuse and are in any case too small to use. We need + two to make sizes and alignments work out. + */ + + if (old_size != 0) { + /* + Shrink old_top to insert fenceposts, keeping size a + multiple of MALLOC_ALIGNMENT. We know there is at least + enough space in old_top to do this. + */ + old_size = (old_size - 3*SIZE_SZ) & ~MALLOC_ALIGN_MASK; + set_head(old_top, old_size | PREV_INUSE); + + /* + Note that the following assignments completely overwrite + old_top when old_size was previously MINSIZE. This is + intentional. We need the fencepost, even if old_top + otherwise gets lost. + */ + chunk_at_offset(old_top, old_size )->size = + SIZE_SZ|PREV_INUSE; + + chunk_at_offset(old_top, old_size + SIZE_SZ)->size = + SIZE_SZ|PREV_INUSE; + + /* + If possible, release the rest, suppressing trimming. + */ + if (old_size >= MINSIZE) { + unsigned int mprops = av->sysctl; + disable_trim(av); + fREe(chunk2mem(old_top)); + av->sysctl = mprops; + } + } + } + } + + /* Update statistics */ + sum = av->sbrked_mem; + if (sum > (CHUNK_SIZE_T)(av->max_sbrked_mem)) + av->max_sbrked_mem = sum; + + sum += av->mmapped_mem; + if (sum > (CHUNK_SIZE_T)(av->max_total_mem)) + av->max_total_mem = sum; + + + /* finally, do the allocation */ + + p = av->top; + size = chunksize(p); + + /* check that one of the above allocation paths succeeded */ + if ((CHUNK_SIZE_T)(size) >= (CHUNK_SIZE_T)(nb + MINSIZE)) { + remainder_size = size - nb; + remainder = chunk_at_offset(p, nb); + av->top = remainder; + set_head(p, nb | PREV_INUSE); + set_head(remainder, remainder_size | PREV_INUSE); + check_malloced_chunk(p, nb); + check_malloc_state(av); + return chunk2mem(p); + } + + } + + /* catch all failure paths */ + check_malloc_state(av); + MALLOC_FAILURE_ACTION; + return 0; +} + + +/* + systrim is an inverse of sorts to sysmalloc. It gives memory back + to the system (via negative arguments to sbrk) if there is unused + memory at the `high' end of the malloc pool. It is called + automatically by free() when top space exceeds the trim + threshold. It is also called by the public malloc_trim routine. It + returns 1 if it actually released any memory, else 0. +*/ + +static int systrim(mstate av, size_t pad) { + long top_size; /* Amount of top-most memory */ + long extra; /* Amount to release */ + long released; /* Amount actually released */ + char* current_brk; /* address returned by pre-check sbrk call */ + char* new_brk; /* address returned by post-check sbrk call */ + size_t pagesz; + + ensure_initialization(av); + + if (have_fastchunks(av)) + malloc_consolidate(av); + + if (!trim_disabled(av)) { + +#ifndef MORECORE_CANNOT_TRIM + + pagesz = av->pagesize; + top_size = chunksize(av->top); + + /* Release in pagesize units, keeping at least one page */ + extra = ((top_size - pad - MINSIZE + (pagesz-1)) / pagesz - 1) * pagesz; + + if (extra > 0) { + + /* + Only proceed if end of memory is where we last set it. + This avoids problems if there were foreign sbrk calls. + */ + current_brk = (char*)(MORECORE(0)); + if (current_brk == (char*)(av->top) + top_size) { + + /* + Attempt to release memory. We ignore MORECORE return value, + and instead call again to find out where new end of memory is. + This avoids problems if first call releases less than we asked, + of if failure somehow altered brk value. (We could still + encounter problems if it altered brk in some very bad way, + but the only thing we can do is adjust anyway, which will cause + some downstream failure.) + */ + + MORECORE(-extra); + new_brk = (char*)(MORECORE(0)); + + if (new_brk != (char*)MORECORE_FAILURE) { + released = (long)(current_brk - new_brk); + + if (released != 0) { + /* Success. Adjust top. */ + av->sbrked_mem -= released; + set_head(av->top, (top_size - released) | PREV_INUSE); + check_malloc_state(av); + return 1; + } + } + } + } + } +#endif + return 0; +} + + +/* + -------------------- Alternative MORECORE functions -------------------- +*/ + + +/* + General Requirements for MORECORE. + + The MORECORE function must have the following properties: + + If MORECORE_CONTIGUOUS is false: + + * MORECORE must allocate in multiples of pagesize. It will + only be called with arguments that are multiples of pagesize. + + * MORECORE(0) must return an address that is at least + MALLOC_ALIGNMENT aligned. (Page-aligning always suffices.) + + else (i.e. If MORECORE_CONTIGUOUS is true): + + * Consecutive calls to MORECORE with positive arguments + return increasing addresses, indicating that space has been + contiguously extended. + + * MORECORE need not allocate in multiples of pagesize. + Calls to MORECORE need not have args of multiples of pagesize. + + * MORECORE need not page-align. + + In either case: + + * MORECORE may allocate more memory than requested. (Or even less, + but this will generally result in a malloc failure.) + + * MORECORE must not allocate memory when given argument zero, but + instead return one past the end address of memory from previous + nonzero call. This malloc does NOT call MORECORE(0) + until at least one call with positive arguments is made, so + the initial value returned is not important. + + * Even though consecutive calls to MORECORE need not return contiguous + addresses, it must be OK for malloc'ed chunks to span multiple + regions in those cases where they do happen to be contiguous. + + * MORECORE need not handle negative arguments -- it may instead + just return MORECORE_FAILURE when given negative arguments. + Negative arguments are always multiples of pagesize. MORECORE + must not misinterpret negative args as large positive unsigned + args. You can suppress all such calls from even occurring by defining + MORECORE_CANNOT_TRIM, + + There is some variation across systems about the type of the + argument to sbrk/MORECORE. If size_t is unsigned, then it cannot + actually be size_t, because sbrk supports negative args, so it is + normally the signed type of the same width as size_t (sometimes + declared as "intptr_t", and sometimes "ptrdiff_t"). It doesn't much + matter though. Internally, we use "long" as arguments, which should + work across all reasonable possibilities. + + Additionally, if MORECORE ever returns failure for a positive + request, and HAVE_MMAP is true, then mmap is used as a noncontiguous + system allocator. This is a useful backup strategy for systems with + holes in address spaces -- in this case sbrk cannot contiguously + expand the heap, but mmap may be able to map noncontiguous space. + + If you'd like mmap to ALWAYS be used, you can define MORECORE to be + a function that always returns MORECORE_FAILURE. + + Malloc only has limited ability to detect failures of MORECORE + to supply contiguous space when it says it can. In particular, + multithreaded programs that do not use locks may result in + rece conditions across calls to MORECORE that result in gaps + that cannot be detected as such, and subsequent corruption. + + If you are using this malloc with something other than sbrk (or its + emulation) to supply memory regions, you probably want to set + MORECORE_CONTIGUOUS as false. As an example, here is a custom + allocator kindly contributed for pre-OSX macOS. It uses virtually + but not necessarily physically contiguous non-paged memory (locked + in, present and won't get swapped out). You can use it by + uncommenting this section, adding some #includes, and setting up the + appropriate defines above: + + #define MORECORE osMoreCore + #define MORECORE_CONTIGUOUS 0 + + There is also a shutdown routine that should somehow be called for + cleanup upon program exit. + + #define MAX_POOL_ENTRIES 100 + #define MINIMUM_MORECORE_SIZE (64 * 1024) + static int next_os_pool; + void *our_os_pools[MAX_POOL_ENTRIES]; + + void *osMoreCore(int size) + { + void *ptr = 0; + static void *sbrk_top = 0; + + if (size > 0) + { + if (size < MINIMUM_MORECORE_SIZE) + size = MINIMUM_MORECORE_SIZE; + if (CurrentExecutionLevel() == kTaskLevel) + ptr = PoolAllocateResident(size + RM_PAGE_SIZE, 0); + if (ptr == 0) + { + return (void *) MORECORE_FAILURE; + } + // save ptrs so they can be freed during cleanup + our_os_pools[next_os_pool] = ptr; + next_os_pool++; + ptr = (void *) ((((CHUNK_SIZE_T) ptr) + RM_PAGE_MASK) & ~RM_PAGE_MASK); + sbrk_top = (char *) ptr + size; + return ptr; + } + else if (size < 0) + { + // we don't currently support shrink behavior + return (void *) MORECORE_FAILURE; + } + else + { + return sbrk_top; + } + } + + // cleanup any allocated memory pools + // called as last thing before shutting down driver + + void osCleanupMem(void) + { + void **ptr; + + for (ptr = our_os_pools; ptr < &our_os_pools[MAX_POOL_ENTRIES]; ptr++) + if (*ptr) + { + PoolDeallocate(*ptr); + *ptr = 0; + } + } + +*/ + + +/* + -------------------------------------------------------------- + + Emulation of sbrk for win32. + Donated by J. Walter . + For additional information about this code, and malloc on Win32, see + http://www.genesys-e.de/jwalter/ +*/ + + +#ifdef WIN32 + +#ifdef _DEBUG +/* #define TRACE */ +#endif + +/* Support for USE_MALLOC_LOCK */ +#ifdef USE_MALLOC_LOCK + +/* Wait for spin lock */ +static int slwait (int *sl) { + while (InterlockedCompareExchange ((void **) sl, (void *) 1, (void *) 0) != 0) + Sleep (0); + return 0; +} + +/* Release spin lock */ +static int slrelease (int *sl) { + InterlockedExchange (sl, 0); + return 0; +} + +#ifdef NEEDED +/* Spin lock for emulation code */ +static int g_sl; +#endif + +#endif /* USE_MALLOC_LOCK */ + +/* getpagesize for windows */ +static long getpagesize (void) { + static long g_pagesize = 0; + if (! g_pagesize) { + SYSTEM_INFO system_info; + GetSystemInfo (&system_info); + g_pagesize = system_info.dwPageSize; + } + return g_pagesize; +} +static long getregionsize (void) { + static long g_regionsize = 0; + if (! g_regionsize) { + SYSTEM_INFO system_info; + GetSystemInfo (&system_info); + g_regionsize = system_info.dwAllocationGranularity; + } + return g_regionsize; +} + +/* A region list entry */ +typedef struct _region_list_entry { + void *top_allocated; + void *top_committed; + void *top_reserved; + long reserve_size; + struct _region_list_entry *previous; +} region_list_entry; + +/* Allocate and link a region entry in the region list */ +static int region_list_append (region_list_entry **last, void *base_reserved, long reserve_size) { + region_list_entry *next = HeapAlloc (GetProcessHeap (), 0, sizeof (region_list_entry)); + if (! next) + return FALSE; + next->top_allocated = (char *) base_reserved; + next->top_committed = (char *) base_reserved; + next->top_reserved = (char *) base_reserved + reserve_size; + next->reserve_size = reserve_size; + next->previous = *last; + *last = next; + return TRUE; +} +/* Free and unlink the last region entry from the region list */ +static int region_list_remove (region_list_entry **last) { + region_list_entry *previous = (*last)->previous; + if (! HeapFree (GetProcessHeap (), sizeof (region_list_entry), *last)) + return FALSE; + *last = previous; + return TRUE; +} + +#define CEIL(size,to) (((size)+(to)-1)&~((to)-1)) +#define FLOOR(size,to) ((size)&~((to)-1)) + +#define SBRK_SCALE 0 +/* #define SBRK_SCALE 1 */ +/* #define SBRK_SCALE 2 */ +/* #define SBRK_SCALE 4 */ + +/* sbrk for windows */ +static void *sbrk (long size) { + static long g_pagesize, g_my_pagesize; + static long g_regionsize, g_my_regionsize; + static region_list_entry *g_last; + void *result = (void *) MORECORE_FAILURE; +#ifdef TRACE + printf ("sbrk %d\n", size); +#endif +#if defined (USE_MALLOC_LOCK) && defined (NEEDED) + /* Wait for spin lock */ + slwait (&g_sl); +#endif + /* First time initialization */ + if (! g_pagesize) { + g_pagesize = getpagesize (); + g_my_pagesize = g_pagesize << SBRK_SCALE; + } + if (! g_regionsize) { + g_regionsize = getregionsize (); + g_my_regionsize = g_regionsize << SBRK_SCALE; + } + if (! g_last) { + if (! region_list_append (&g_last, 0, 0)) + goto sbrk_exit; + } + /* Assert invariants */ + assert (g_last); + assert ((char *) g_last->top_reserved - g_last->reserve_size <= (char *) g_last->top_allocated && + g_last->top_allocated <= g_last->top_committed); + assert ((char *) g_last->top_reserved - g_last->reserve_size <= (char *) g_last->top_committed && + g_last->top_committed <= g_last->top_reserved && + (unsigned) g_last->top_committed % g_pagesize == 0); + assert ((unsigned) g_last->top_reserved % g_regionsize == 0); + assert ((unsigned) g_last->reserve_size % g_regionsize == 0); + /* Allocation requested? */ + if (size >= 0) { + /* Allocation size is the requested size */ + long allocate_size = size; + /* Compute the size to commit */ + long to_commit = (char *) g_last->top_allocated + allocate_size - (char *) g_last->top_committed; + /* Do we reach the commit limit? */ + if (to_commit > 0) { + /* Round size to commit */ + long commit_size = CEIL (to_commit, g_my_pagesize); + /* Compute the size to reserve */ + long to_reserve = (char *) g_last->top_committed + commit_size - (char *) g_last->top_reserved; + /* Do we reach the reserve limit? */ + if (to_reserve > 0) { + /* Compute the remaining size to commit in the current region */ + long remaining_commit_size = (char *) g_last->top_reserved - (char *) g_last->top_committed; + if (remaining_commit_size > 0) { + /* Assert preconditions */ + assert ((unsigned) g_last->top_committed % g_pagesize == 0); + assert (0 < remaining_commit_size && remaining_commit_size % g_pagesize == 0); { + /* Commit this */ + void *base_committed = VirtualAlloc (g_last->top_committed, remaining_commit_size, + MEM_COMMIT, PAGE_READWRITE); + /* Check returned pointer for consistency */ + if (base_committed != g_last->top_committed) + goto sbrk_exit; + /* Assert postconditions */ + assert ((unsigned) base_committed % g_pagesize == 0); +#ifdef TRACE + printf ("Commit %p %d\n", base_committed, remaining_commit_size); +#endif + /* Adjust the regions commit top */ + g_last->top_committed = (char *) base_committed + remaining_commit_size; + } + } { + /* Now we are going to search and reserve. */ + int contiguous = -1; + int found = FALSE; + MEMORY_BASIC_INFORMATION memory_info; + void *base_reserved; + long reserve_size; + do { + /* Assume contiguous memory */ + contiguous = TRUE; + /* Round size to reserve */ + reserve_size = CEIL (to_reserve, g_my_regionsize); + /* Start with the current region's top */ + memory_info.BaseAddress = g_last->top_reserved; + /* Assert preconditions */ + assert ((unsigned) memory_info.BaseAddress % g_pagesize == 0); + assert (0 < reserve_size && reserve_size % g_regionsize == 0); + while (VirtualQuery (memory_info.BaseAddress, &memory_info, sizeof (memory_info))) { + /* Assert postconditions */ + assert ((unsigned) memory_info.BaseAddress % g_pagesize == 0); +#ifdef TRACE + printf ("Query %p %d %s\n", memory_info.BaseAddress, memory_info.RegionSize, + memory_info.State == MEM_FREE ? "FREE": + (memory_info.State == MEM_RESERVE ? "RESERVED": + (memory_info.State == MEM_COMMIT ? "COMMITTED": "?"))); +#endif + /* Region is free, well aligned and big enough: we are done */ + if (memory_info.State == MEM_FREE && + (unsigned) memory_info.BaseAddress % g_regionsize == 0 && + memory_info.RegionSize >= (unsigned) reserve_size) { + found = TRUE; + break; + } + /* From now on we can't get contiguous memory! */ + contiguous = FALSE; + /* Recompute size to reserve */ + reserve_size = CEIL (allocate_size, g_my_regionsize); + memory_info.BaseAddress = (char *) memory_info.BaseAddress + memory_info.RegionSize; + /* Assert preconditions */ + assert ((unsigned) memory_info.BaseAddress % g_pagesize == 0); + assert (0 < reserve_size && reserve_size % g_regionsize == 0); + } + /* Search failed? */ + if (! found) + goto sbrk_exit; + /* Assert preconditions */ + assert ((unsigned) memory_info.BaseAddress % g_regionsize == 0); + assert (0 < reserve_size && reserve_size % g_regionsize == 0); + /* Try to reserve this */ + base_reserved = VirtualAlloc (memory_info.BaseAddress, reserve_size, + MEM_RESERVE, PAGE_NOACCESS); + if (! base_reserved) { + int rc = GetLastError (); + if (rc != ERROR_INVALID_ADDRESS) + goto sbrk_exit; + } + /* A null pointer signals (hopefully) a race condition with another thread. */ + /* In this case, we try again. */ + } while (! base_reserved); + /* Check returned pointer for consistency */ + if (memory_info.BaseAddress && base_reserved != memory_info.BaseAddress) + goto sbrk_exit; + /* Assert postconditions */ + assert ((unsigned) base_reserved % g_regionsize == 0); +#ifdef TRACE + printf ("Reserve %p %d\n", base_reserved, reserve_size); +#endif + /* Did we get contiguous memory? */ + if (contiguous) { + long start_size = (char *) g_last->top_committed - (char *) g_last->top_allocated; + /* Adjust allocation size */ + allocate_size -= start_size; + /* Adjust the regions allocation top */ + g_last->top_allocated = g_last->top_committed; + /* Recompute the size to commit */ + to_commit = (char *) g_last->top_allocated + allocate_size - (char *) g_last->top_committed; + /* Round size to commit */ + commit_size = CEIL (to_commit, g_my_pagesize); + } + /* Append the new region to the list */ + if (! region_list_append (&g_last, base_reserved, reserve_size)) + goto sbrk_exit; + /* Didn't we get contiguous memory? */ + if (! contiguous) { + /* Recompute the size to commit */ + to_commit = (char *) g_last->top_allocated + allocate_size - (char *) g_last->top_committed; + /* Round size to commit */ + commit_size = CEIL (to_commit, g_my_pagesize); + } + } + } + /* Assert preconditions */ + assert ((unsigned) g_last->top_committed % g_pagesize == 0); + assert (0 < commit_size && commit_size % g_pagesize == 0); { + /* Commit this */ + void *base_committed = VirtualAlloc (g_last->top_committed, commit_size, + MEM_COMMIT, PAGE_READWRITE); + /* Check returned pointer for consistency */ + if (base_committed != g_last->top_committed) + goto sbrk_exit; + /* Assert postconditions */ + assert ((unsigned) base_committed % g_pagesize == 0); +#ifdef TRACE + printf ("Commit %p %d\n", base_committed, commit_size); +#endif + /* Adjust the regions commit top */ + g_last->top_committed = (char *) base_committed + commit_size; + } + } + /* Adjust the regions allocation top */ + g_last->top_allocated = (char *) g_last->top_allocated + allocate_size; + result = (char *) g_last->top_allocated - size; + /* Deallocation requested? */ + } else if (size < 0) { + long deallocate_size = - size; + /* As long as we have a region to release */ + while ((char *) g_last->top_allocated - deallocate_size < (char *) g_last->top_reserved - g_last->reserve_size) { + /* Get the size to release */ + long release_size = g_last->reserve_size; + /* Get the base address */ + void *base_reserved = (char *) g_last->top_reserved - release_size; + /* Assert preconditions */ + assert ((unsigned) base_reserved % g_regionsize == 0); + assert (0 < release_size && release_size % g_regionsize == 0); { + /* Release this */ + int rc = VirtualFree (base_reserved, 0, + MEM_RELEASE); + /* Check returned code for consistency */ + if (! rc) + goto sbrk_exit; +#ifdef TRACE + printf ("Release %p %d\n", base_reserved, release_size); +#endif + } + /* Adjust deallocation size */ + deallocate_size -= (char *) g_last->top_allocated - (char *) base_reserved; + /* Remove the old region from the list */ + if (! region_list_remove (&g_last)) + goto sbrk_exit; + } { + /* Compute the size to decommit */ + long to_decommit = (char *) g_last->top_committed - ((char *) g_last->top_allocated - deallocate_size); + if (to_decommit >= g_my_pagesize) { + /* Compute the size to decommit */ + long decommit_size = FLOOR (to_decommit, g_my_pagesize); + /* Compute the base address */ + void *base_committed = (char *) g_last->top_committed - decommit_size; + /* Assert preconditions */ + assert ((unsigned) base_committed % g_pagesize == 0); + assert (0 < decommit_size && decommit_size % g_pagesize == 0); { + /* Decommit this */ + int rc = VirtualFree ((char *) base_committed, decommit_size, + MEM_DECOMMIT); + /* Check returned code for consistency */ + if (! rc) + goto sbrk_exit; +#ifdef TRACE + printf ("Decommit %p %d\n", base_committed, decommit_size); +#endif + } + /* Adjust deallocation size and regions commit and allocate top */ + deallocate_size -= (char *) g_last->top_allocated - (char *) base_committed; + g_last->top_committed = base_committed; + g_last->top_allocated = base_committed; + } + } + /* Adjust regions allocate top */ + g_last->top_allocated = (char *) g_last->top_allocated - deallocate_size; + /* Check for underflow */ + if ((char *) g_last->top_reserved - g_last->reserve_size > (char *) g_last->top_allocated || + g_last->top_allocated > g_last->top_committed) { + /* Adjust regions allocate top */ + g_last->top_allocated = (char *) g_last->top_reserved - g_last->reserve_size; + goto sbrk_exit; + } + result = g_last->top_allocated; + } + /* Assert invariants */ + assert (g_last); + assert ((char *) g_last->top_reserved - g_last->reserve_size <= (char *) g_last->top_allocated && + g_last->top_allocated <= g_last->top_committed); + assert ((char *) g_last->top_reserved - g_last->reserve_size <= (char *) g_last->top_committed && + g_last->top_committed <= g_last->top_reserved && + (unsigned) g_last->top_committed % g_pagesize == 0); + assert ((unsigned) g_last->top_reserved % g_regionsize == 0); + assert ((unsigned) g_last->reserve_size % g_regionsize == 0); + +sbrk_exit: +#if defined (USE_MALLOC_LOCK) && defined (NEEDED) + /* Release spin lock */ + slrelease (&g_sl); +#endif + return result; +} + +/* mmap for windows */ +static void *mmap (void *ptr, long size, long prot, long type, long handle, long arg) { + static long g_pagesize; + static long g_regionsize; +#ifdef TRACE + printf ("mmap %d\n", size); +#endif +#if defined (USE_MALLOC_LOCK) && defined (NEEDED) + /* Wait for spin lock */ + slwait (&g_sl); +#endif + /* First time initialization */ + if (! g_pagesize) + g_pagesize = getpagesize (); + if (! g_regionsize) + g_regionsize = getregionsize (); + /* Assert preconditions */ + assert ((unsigned) ptr % g_regionsize == 0); + assert (size % g_pagesize == 0); + /* Allocate this */ + ptr = VirtualAlloc (ptr, size, + MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE); + if (! ptr) { + ptr = (void *) MORECORE_FAILURE; + goto mmap_exit; + } + /* Assert postconditions */ + assert ((unsigned) ptr % g_regionsize == 0); +#ifdef TRACE + printf ("Commit %p %d\n", ptr, size); +#endif +mmap_exit: +#if defined (USE_MALLOC_LOCK) && defined (NEEDED) + /* Release spin lock */ + slrelease (&g_sl); +#endif + return ptr; +} + +/* munmap for windows */ +static long munmap (void *ptr, long size) { + static long g_pagesize; + static long g_regionsize; + int rc = MUNMAP_FAILURE; +#ifdef TRACE + printf ("munmap %p %d\n", ptr, size); +#endif +#if defined (USE_MALLOC_LOCK) && defined (NEEDED) + /* Wait for spin lock */ + slwait (&g_sl); +#endif + /* First time initialization */ + if (! g_pagesize) + g_pagesize = getpagesize (); + if (! g_regionsize) + g_regionsize = getregionsize (); + /* Assert preconditions */ + assert ((unsigned) ptr % g_regionsize == 0); + assert (size % g_pagesize == 0); + /* Free this */ + if (! VirtualFree (ptr, 0, + MEM_RELEASE)) + goto munmap_exit; + rc = 0; +#ifdef TRACE + printf ("Release %p %d\n", ptr, size); +#endif +munmap_exit: +#if defined (USE_MALLOC_LOCK) && defined (NEEDED) + /* Release spin lock */ + slrelease (&g_sl); +#endif + return rc; +} + +static void vminfo (CHUNK_SIZE_T *free, CHUNK_SIZE_T *reserved, CHUNK_SIZE_T *committed) { + MEMORY_BASIC_INFORMATION memory_info; + memory_info.BaseAddress = 0; + *free = *reserved = *committed = 0; + while (VirtualQuery (memory_info.BaseAddress, &memory_info, sizeof (memory_info))) { + switch (memory_info.State) { + case MEM_FREE: + *free += memory_info.RegionSize; + break; + case MEM_RESERVE: + *reserved += memory_info.RegionSize; + break; + case MEM_COMMIT: + *committed += memory_info.RegionSize; + break; + } + memory_info.BaseAddress = (char *) memory_info.BaseAddress + memory_info.RegionSize; + } +} + +static int cpuinfo (int whole, CHUNK_SIZE_T *kernel, CHUNK_SIZE_T *user) { + if (whole) { + __int64 creation64, exit64, kernel64, user64; + int rc = GetProcessTimes (GetCurrentProcess (), + (FILETIME *) &creation64, + (FILETIME *) &exit64, + (FILETIME *) &kernel64, + (FILETIME *) &user64); + if (! rc) { + *kernel = 0; + *user = 0; + return FALSE; + } + *kernel = (CHUNK_SIZE_T) (kernel64 / 10000); + *user = (CHUNK_SIZE_T) (user64 / 10000); + return TRUE; + } else { + __int64 creation64, exit64, kernel64, user64; + int rc = GetThreadTimes (GetCurrentThread (), + (FILETIME *) &creation64, + (FILETIME *) &exit64, + (FILETIME *) &kernel64, + (FILETIME *) &user64); + if (! rc) { + *kernel = 0; + *user = 0; + return FALSE; + } + *kernel = (CHUNK_SIZE_T) (kernel64 / 10000); + *user = (CHUNK_SIZE_T) (user64 / 10000); + return TRUE; + } +} + +#endif /* WIN32 */ + +/* ------------------------------------------------------------ +History: + V2.8.0 (not yet released) + * Use trees for non-small bins + Also requiring different size->bin algorithm + + V2.7.1 Thu Jul 25 10:58:03 2002 Doug Lea (dl at gee) + * Allow tuning of FIRST_SORTED_BIN_SIZE + * Use PTR_UINT as type for all ptr->int casts. Thanks to John Belmonte. + * Better detection and support for non-contiguousness of MORECORE. + Thanks to Andreas Mueller, Conal Walsh, and Wolfram Gloger + * Bypass most of malloc if no frees. Thanks To Emery Berger. + * Fix freeing of old top non-contiguous chunk im sysmalloc. + * Raised default trim and map thresholds to 256K. + * Fix mmap-related #defines. Thanks to Lubos Lunak. + * Fix copy macros; added LACKS_FCNTL_H. Thanks to Neal Walfield. + * Branch-free bin calculation + * Default trim and mmap thresholds now 256K. + + V2.7.0 Sun Mar 11 14:14:06 2001 Doug Lea (dl at gee) + * Introduce independent_comalloc and independent_calloc. + Thanks to Michael Pachos for motivation and help. + * Make optional .h file available + * Allow > 2GB requests on 32bit systems. + * new WIN32 sbrk, mmap, munmap, lock code from . + Thanks also to Andreas Mueller , + and Anonymous. + * Allow override of MALLOC_ALIGNMENT (Thanks to Ruud Waij for + helping test this.) + * memalign: check alignment arg + * realloc: don't try to shift chunks backwards, since this + leads to more fragmentation in some programs and doesn't + seem to help in any others. + * Collect all cases in malloc requiring system memory into sysmalloc + * Use mmap as backup to sbrk + * Place all internal state in malloc_state + * Introduce fastbins (although similar to 2.5.1) + * Many minor tunings and cosmetic improvements + * Introduce USE_PUBLIC_MALLOC_WRAPPERS, USE_MALLOC_LOCK + * Introduce MALLOC_FAILURE_ACTION, MORECORE_CONTIGUOUS + Thanks to Tony E. Bennett and others. + * Include errno.h to support default failure action. + + V2.6.6 Sun Dec 5 07:42:19 1999 Doug Lea (dl at gee) + * return null for negative arguments + * Added Several WIN32 cleanups from Martin C. Fong + * Add 'LACKS_SYS_PARAM_H' for those systems without 'sys/param.h' + (e.g. WIN32 platforms) + * Cleanup header file inclusion for WIN32 platforms + * Cleanup code to avoid Microsoft Visual C++ compiler complaints + * Add 'USE_DL_PREFIX' to quickly allow co-existence with existing + memory allocation routines + * Set 'malloc_getpagesize' for WIN32 platforms (needs more work) + * Use 'assert' rather than 'ASSERT' in WIN32 code to conform to + usage of 'assert' in non-WIN32 code + * Improve WIN32 'sbrk()' emulation's 'findRegion()' routine to + avoid infinite loop + * Always call 'fREe()' rather than 'free()' + + V2.6.5 Wed Jun 17 15:57:31 1998 Doug Lea (dl at gee) + * Fixed ordering problem with boundary-stamping + + V2.6.3 Sun May 19 08:17:58 1996 Doug Lea (dl at gee) + * Added pvalloc, as recommended by H.J. Liu + * Added 64bit pointer support mainly from Wolfram Gloger + * Added anonymously donated WIN32 sbrk emulation + * Malloc, calloc, getpagesize: add optimizations from Raymond Nijssen + * malloc_extend_top: fix mask error that caused wastage after + foreign sbrks + * Add linux mremap support code from HJ Liu + + V2.6.2 Tue Dec 5 06:52:55 1995 Doug Lea (dl at gee) + * Integrated most documentation with the code. + * Add support for mmap, with help from + Wolfram Gloger (Gloger@lrz.uni-muenchen.de). + * Use last_remainder in more cases. + * Pack bins using idea from colin@nyx10.cs.du.edu + * Use ordered bins instead of best-fit threshhold + * Eliminate block-local decls to simplify tracing and debugging. + * Support another case of realloc via move into top + * Fix error occuring when initial sbrk_base not word-aligned. + * Rely on page size for units instead of SBRK_UNIT to + avoid surprises about sbrk alignment conventions. + * Add mallinfo, mallopt. Thanks to Raymond Nijssen + (raymond@es.ele.tue.nl) for the suggestion. + * Add `pad' argument to malloc_trim and top_pad mallopt parameter. + * More precautions for cases where other routines call sbrk, + courtesy of Wolfram Gloger (Gloger@lrz.uni-muenchen.de). + * Added macros etc., allowing use in linux libc from + H.J. Lu (hjl@gnu.ai.mit.edu) + * Inverted this history list + + V2.6.1 Sat Dec 2 14:10:57 1995 Doug Lea (dl at gee) + * Re-tuned and fixed to behave more nicely with V2.6.0 changes. + * Removed all preallocation code since under current scheme + the work required to undo bad preallocations exceeds + the work saved in good cases for most test programs. + * No longer use return list or unconsolidated bins since + no scheme using them consistently outperforms those that don't + given above changes. + * Use best fit for very large chunks to prevent some worst-cases. + * Added some support for debugging + + V2.6.0 Sat Nov 4 07:05:23 1995 Doug Lea (dl at gee) + * Removed footers when chunks are in use. Thanks to + Paul Wilson (wilson@cs.texas.edu) for the suggestion. + + V2.5.4 Wed Nov 1 07:54:51 1995 Doug Lea (dl at gee) + * Added malloc_trim, with help from Wolfram Gloger + (wmglo@Dent.MED.Uni-Muenchen.DE). + + V2.5.3 Tue Apr 26 10:16:01 1994 Doug Lea (dl at g) + + V2.5.2 Tue Apr 5 16:20:40 1994 Doug Lea (dl at g) + * realloc: try to expand in both directions + * malloc: swap order of clean-bin strategy; + * realloc: only conditionally expand backwards + * Try not to scavenge used bins + * Use bin counts as a guide to preallocation + * Occasionally bin return list chunks in first scan + * Add a few optimizations from colin@nyx10.cs.du.edu + + V2.5.1 Sat Aug 14 15:40:43 1993 Doug Lea (dl at g) + * faster bin computation & slightly different binning + * merged all consolidations to one part of malloc proper + (eliminating old malloc_find_space & malloc_clean_bin) + * Scan 2 returns chunks (not just 1) + * Propagate failure in realloc if malloc returns 0 + * Add stuff to allow compilation on non-ANSI compilers + from kpv@research.att.com + + V2.5 Sat Aug 7 07:41:59 1993 Doug Lea (dl at g.oswego.edu) + * removed potential for odd address access in prev_chunk + * removed dependency on getpagesize.h + * misc cosmetics and a bit more internal documentation + * anticosmetics: mangled names in macros to evade debugger strangeness + * tested on sparc, hp-700, dec-mips, rs6000 + with gcc & native cc (hp, dec only) allowing + Detlefs & Zorn comparison study (in SIGPLAN Notices.) + + Trial version Fri Aug 28 13:14:29 1992 Doug Lea (dl at g.oswego.edu) + * Based loosely on libg++-1.2X malloc. (It retains some of the overall + structure of old version, but most details differ.) + +*/ + + diff --git a/feeds/p4/libjudy/src/test/simple.c b/feeds/p4/libjudy/src/test/simple.c new file mode 100644 index 000000000..33e7fbf12 --- /dev/null +++ b/feeds/p4/libjudy/src/test/simple.c @@ -0,0 +1,24 @@ +#include + +int main() +{ + int Rc_int; + + int i; + + // Judy array to hold cached addresses + Pvoid_t addrArray = (Pvoid_t) NULL; + + for(i = 0; i < 100000; i++) + J1S(Rc_int, addrArray, (Word_t) i); + + for(i = 0; i < 100000; i++){ + J1T(Rc_int, addrArray, (Word_t) i); + if(!Rc_int){ + printf("Something bad happened\n"); + return -1; + } + } + + return 0; +} diff --git a/feeds/p4/libjudy/src/test/testjbgraph b/feeds/p4/libjudy/src/test/testjbgraph new file mode 100755 index 000000000..a6bc84a35 --- /dev/null +++ b/feeds/p4/libjudy/src/test/testjbgraph @@ -0,0 +1,22 @@ +# run timing program to measure Judy1, JudyL and JudyHS performance +# use jbgraph script to format output suitable for 'gnuplot' +echo +echo "This script takes 1 Minute to plot output on a 3.2Ghz Pentium P4C" + +# On Linux, higher resolution of times with -DCPUMHZ=3200 on 3.2Ghz +# cc -O2 -DCPUMHZ=3200 Judy1LHTime.c -lJudy -lm -o Judy1LHTime + +# up to 1000000 population of random numbers with Judy1, JudyL, JudyHS +./Judy1LHTime -n 1000000 -1 -L -H > Judy1LHTime.plot + +# Plot the results: y-axis == uSec per Index, x-axis == number of Indexes +# -NL == Plot No Log axis +# -Lx == Plot Log in x axis +# -y:1 == default min scale, 1 microsecond max scale +# -x100: == 100 min scale, default max scale +# -c6 -c7 -c8 == plot column 6,7,8 (J1T, JLG, JHSG) +# Judy1LHTime.plot == file to plot +./jbgraph -NL -Lx -y:1 -x100: -c6 -c7 -c8 Judy1LHTime.plot + +# Performance of other ADT's can be explored with StringCompare.c, +# but you should have a very large (>100MB) text file to input. diff --git a/feeds/p4/libjudy/src/test/timeit.c b/feeds/p4/libjudy/src/test/timeit.c new file mode 100644 index 000000000..c92a38c12 --- /dev/null +++ b/feeds/p4/libjudy/src/test/timeit.c @@ -0,0 +1,311 @@ +// @(#) $Revision: 4.12 $ $Source: /judy/judy/src/apps/benchmark/timeit.c,v $ +// +// Timer functions. +// +// YOU MUST COMPILE THIS WITH ONE OF THESE DEFINED: +// +// JU_HPUX_PA +// JU_HPUX_IPF +// JU_LINUX_IA32 +// JU_LINUX_IPF +// JU_WIN_IA32 +// +// If NONE of these are defined, this whole code section is ifdef'd out to +// avoid compile/link errors due to usage here of objects not defined in +// timeit.h. See end of file. +// +// TBD: Improve on this; possibly it's OK now not to ifdef this out, and get +// default, low-res timing behavior; see timeit.h. +// +// Compile with -D_TIMEIT_TEST to include a main program for testing; see +// main() below. + +#if (JU_HPUX_PA || JU_LINUX_IA32 || JU_LINUX_IPF) +#define _TIMEIT_HIGHRES +#endif + +#ifdef _TIMEIT_HIGHRES + +#include // Win32 uses a whole different paradigm. +#include // for getopt(), which Win32 lacks. +#include +#include "timeit.h" + +double USecPerClock; // usec per control register count. + + +// **************************************************************************** +// F I N D C P U S P E E D +// +// Return microseconds per control/timer register count. Examples: +// +// 0.002 for 500 MHz processor +// 0.001 for 1 GHz processor + +double find_CPU_speed(void) +{ + double DeltaUSec; // Timing result in uSec. + TIMER_vars(tm); // creates __TVBeg_tm, ... + // (used for consistency with __START_HRTm) + + gettimeofday(&__TVBeg_tm, NULL); // get low-res time. + __START_HRTm(tm); // get __start_tm (high-res). + sleep(1); // time passes; 1 sec suffices. + __END_HRTm(tm); // get __stop_tm (high-res). + gettimeofday(&__TVEnd_tm, NULL); // get low-res time. + +// gettimeofday() returns usec; compute elapsed time: + + DeltaUSec = (((double) __TVEnd_tm.tv_sec * ((double) 1E6)) + + (double) __TVEnd_tm.tv_usec) + - (((double) __TVBeg_tm.tv_sec * ((double) 1E6)) + + (double) __TVBeg_tm.tv_usec); + +// Control register returns ticks, and the ratio can now be computed: + + return (DeltaUSec / ((double) (__stop_tm - __start_tm))); + +} // find_CPU_speed() + +#else // _TIMEIT_HIGHRES +void dummy() {} // avoid "empty source file" warnings when no _TIMEIT_TEST. +#endif + + +// **************************************************************************** +// +// Ifdef the test main() separately, including #includes, for platforms that do +// not define find_CPU_speed() above. + +#ifdef _TIMEIT_TEST + +#include // Win32 uses a whole different paradigm. +#include // for getopt(), which Win32 lacks. +#include +#include +#include +#include +//#include // for MAXDOUBLE +#define MAXDOUBLE (10e99) +#include "timeit.h" + + +// **************************************************************************** +// M A I N +// +// Example code for timeit: +// +// To compile and test this program on HP-UX, run the next lines as commands. +// +// cc -Wl,-a,archive -DJU_HPUX_PA -D__HPUX__ -D_TIMEIT_TEST -o timeit timeit.c +// timeit # run test program. +// rm -f timeit # clean up after test. + +int main(int argc, char **argv) +{ + int i = 0; // loop index. + long i_max = 10; // number of loops. + int preload = 1; // loops to throw away (preload cache). + double ztime; // timer overhead. + double usec[4]; // for early timing tests. + double DeltaUSec; // timing result in usec. + double prevtime; // from previous loop. + double mintime; // minimum event time. + struct timeval tmjunk; // for throw-away syscall. + TIMER_vars(tm1); // overall timer variables. + TIMER_vars(tm2); // misc + loop timer variables. + + +// INITIALIZE: + + STARTTm(tm1); // whole program timer. + + i_max += preload; + +// The first arg is the number of iterations (default is i_max): + + if (argc > 1) + { + i = atoi(argv[1]) + preload; + if (i > 0) i_max = (long)i; + } + +// Calculate timer overhead (ztime): + +#ifdef _TIMEIT_HIGHRES + (void) puts("Possible slight delay here due to find_CPU_speed()..."); +#else + (void) puts("No high-res clock or find_CPU_speed() for this platform."); +#endif + + ztime = 0.0; + + for (i = 0; i < 100; ++i) // average many runs. + { + STARTTm(tm2); + ENDTm(DeltaUSec, tm2); + ztime += DeltaUSec; + } + ztime = ztime / ((double) i); + + +// SIMPLE TESTS OF TIMER OVERHEAD: +// +// Make two passes at both the high-res (if any) and slower timers. + + (void) puts("\nTiming timers themselves: start, end, end"); + +#define PRINTPASS(Desc,Pass) \ + (void) printf("%-8s pass %d: %f - %f = %f usec\n", Desc, Pass, \ + usec[((Pass) * 2) - 1], usec[((Pass) * 2) - 2], \ + usec[((Pass) * 2) - 1] - usec[((Pass) * 2) - 2]) + +#ifdef _TIMEIT_HIGHRES + START_HRTm(tm2); + END_HRTm(usec[0], tm2); // throw away in case of sleep(1) here. + + START_HRTm(tm2); + END_HRTm(usec[0], tm2); + END_HRTm(usec[1], tm2); + + START_HRTm(tm2); + END_HRTm(usec[2], tm2); + END_HRTm(usec[3], tm2); + + PRINTPASS("High-res", 1); + PRINTPASS("High-res", 2); +#endif + + STARTTm(tm2); + ENDTm(usec[0], tm2); // throw away in case of sleep(1) here. + + STARTTm(tm2); + ENDTm(usec[0], tm2); + ENDTm(usec[1], tm2); + + STARTTm(tm2); + ENDTm(usec[2], tm2); + ENDTm(usec[3], tm2); + + PRINTPASS("Non-HR", 1); + PRINTPASS("Non-HR", 2); + + +// PRINT INITIAL INFO: + +#ifdef _TIMEIT_HIGHRES + +// Print the CPU speed: +// +// Note: USecPerClock is a global set by the first instance of STARTTm. You +// can also get this number by calling find_CPU_speed(). + + (void) printf("\nClock step = %.3f nsec => %.1f MHz.\n", + USecPerClock * 1000.0, 1.0 / USecPerClock); +#endif + +// Print timer overhead even though it's been subtracted from the reported +// results. + + (void) printf("Timer overhead subtracted from the times below = %f " + "usec.\n", ztime); + + +// DO A FAST TIMER CHECK: + + (void) puts("\nCheck timer precision by repeating the same action:"); + (void) puts("Times in each group should be close together."); + (void) puts("\nTiming something very fast: \"++i\":"); + + mintime = MAXDOUBLE; + + for (i = 1; i <= i_max; ++i) + { + prevtime = DeltaUSec; + STARTTm(tm2); // start the timer. + ++i; // statement to time. + ENDTm(DeltaUSec, tm2); // stop the timer. + DeltaUSec -= ztime; // remove timer overhead. + +// Throw away the first loop iteration to warm up the cache: + + if (--i > preload) + { + if (mintime == MAXDOUBLE) mintime = DeltaUSec; + + (void) printf("%3d. %8.3f nanosec,\tmintime diff %8.1f %%\n", + i - preload, DeltaUSec * 1000.0, + ((DeltaUSec - mintime) * 100) / mintime); + + if (DeltaUSec < mintime) mintime = DeltaUSec; + } + } + + +// TIME A FUNCTION CALL: + + (void) puts("\nTiming a function: \"gettimeofday()\":"); + mintime = MAXDOUBLE; + + for (i = 1; i <= i_max; ++i) + { + prevtime = DeltaUSec; + STARTTm(tm2); // start the timer. + gettimeofday(&tmjunk, NULL); // burn some cycles. + ENDTm(DeltaUSec, tm2); // stop the timer. + DeltaUSec -= ztime; // remove timer overhead. + +// Throw away the first loop iteration to warm up the cache: + + if (i > preload) + { + if (mintime == MAXDOUBLE) mintime = DeltaUSec; + + (void) printf("%3d. %8.3f usec,\tmintime diff %8.1f %%\n", + i - preload, DeltaUSec, + ((DeltaUSec - mintime) * 100) / mintime); + + if (DeltaUSec < mintime) mintime = DeltaUSec; + } + } + + +// TIME SOMETHING SLOW: + + (void) puts("\nTiming something slow: \"sleep(1)\":"); + mintime = MAXDOUBLE; + + for (i = 1; i <= i_max; ++i) + { + prevtime = DeltaUSec; + STARTTm(tm2); // start the timer. + sleep(1); + ENDTm(DeltaUSec, tm2); // stop the timer. + DeltaUSec -= ztime; // remove timer overhead. + +// Throw away the first loop iteration to warm up the cache: + + if (i > preload) + { + if (mintime == MAXDOUBLE) mintime = DeltaUSec; + + (void) printf("%3d. %8.3f sec,\tmintime diff %8.1f %%\n", + i - preload, DeltaUSec/1E6, + ((DeltaUSec - mintime) * 100) / mintime); + + if (DeltaUSec < mintime) mintime = DeltaUSec; + } + } + + +// FINISH UP: +// +// Print program execution time: + + ENDTm(DeltaUSec, tm1); + (void) printf("\nProgram execution time: %.3f sec\n", DeltaUSec / 1E6); + return(0); + +} // main() + +#endif // #ifdef _TIMEIT_TEST diff --git a/feeds/p4/libjudy/src/test/timeit.h b/feeds/p4/libjudy/src/test/timeit.h new file mode 100644 index 000000000..4e27c0480 --- /dev/null +++ b/feeds/p4/libjudy/src/test/timeit.h @@ -0,0 +1,221 @@ +#ifndef _TIMEIT_H +#define _TIMEIT_H + +// @(#) $Revision: 4.14 $ $Source: /judy/src/apps/benchmark/timeit.h $ +// +// Timing and timers header file with example program. +// +// You should compile with one of these defined: +// +// JU_HPUX_PA # control register available (via asm()). +// JU_HPUX_IPF # TBD, see below. +// JU_LINUX_IA32 # control register available (via get_cycles()). +// JU_LINUX_IPF # control register available (via get_cycles()). +// JU_WIN_IA32 # uses clock(). +// +// Otherwise default (low-res) timing code using gettimeofday() results. This +// mode is only accurate to usecs, and fuzzy due to syscall overhead. +// +// Public macros; the *_HRTm() forms are much faster than the others: +// +// TIMER_vars(T) - declare variables to use for timers +// STARTTm(T) - start the timer with variable T +// ENDTm(D,T) - compute usec from last STARTTm(T), save result in double D +// START_HRTm(T) - high-res for short intervals (< 2^32[64] clock ticks) only +// END_HRTm(D,T) - high-res for short intervals (< 2^32[64] clock ticks) only +// +// Private macros: +// +// __START_HRTm(T) - read high-res control register, save in T +// __END_HRTm(T) - read high-res control register, save in T +// __HRONLY(D,T) - use high-res clock only +// +// Note: The __*_HRTm and __HRONLY macros are only available on platforms with +// control registers for high-res clocks. On hpux_pa this is a 32-bit register +// and gettimeofday() must be used to handle rollover; on linux_* this is a +// 64-bit register. + +#ifndef JU_WIN_IA32 +#include // Win32 uses a whole different paradigm. +#include // for getopt(), which Win32 lacks. +#endif + +#include + +// Public variables: + +extern double USecPerClock; // defined in timeit.c. + +// __HRONLY is used for multiple platforms, but only in cases where there is a +// high-res clock and find_CPU_speed() is available from timeit.c: + +#define __HRONLY(D,T) \ + { \ + if (USecPerClock == 0.0) USecPerClock = find_CPU_speed(); \ + (D) = ((double) (__stop_##T - __start_##T)) * USecPerClock; \ + } + + +// TIMING ROUTINES: + + +// ********************* HPUX PA **************************** +// +// Define __START_HRTm and __END_HRTm only, and let later common code add +// STARTTm and ENDTm. +// +// TBD: On hpux_pa or hpux_ipf 64-bit, is CR_IT a 64-bit register? If so, it's +// unnecessary and wasteful to use gettimeofday() later to watch for rollover. +// +// TBD: JU_HPUX_IPF does not recognize CR_IT ("Undeclared variable 'CR_IT'"), +// so for now treat that platform as having no high-res clock and do not +// included it in this section. + +#if (JU_HPUX_PA) +#include +#include + +double find_CPU_speed(void); + +// Note: On hpux_*, at least older compilers, it is neither necessary nor even +// allowed to mark the __start_* and __stop_* variables as volatile; the +// compiler does not optimize out the code even without it: + +#define TIMER_vars(T) \ + register unsigned long __start_##T, __stop_##T; \ + struct timeval __TVBeg_##T, __TVEnd_##T + +#define __START_HRTm(T) _asm("MFCTL", CR_IT, __start_##T) +#define __END_HRTm(T) _asm("MFCTL", CR_IT, __stop_##T ) + +#endif // (JU_HPUX_PA) + +// ********************* LINUX IA32 ************************** +// +#ifdef JU_LINUX_IA32 +#include + +double find_CPU_speed(void); + +#define TIMER_vars(T) \ + register unsigned long __start_##T, __stop_##T; \ + struct timeval __TVBeg_##T, __TVEnd_##T + +#define __START_HRTm(T) rdtscl(__start_##T) +#define __END_HRTm(T) rdtscl(__stop_##T) + +#endif // JU_LINUX_IA32 + +// ********************* LINUX_IPF ************************** +// +// Define __START_HRTm and __END_HRTm, and also STARTTm and ENDTm in terms of +// the former (no need for gettimeofday()). + +#ifdef JU_LINUX_IPF + +#include + +double find_CPU_speed(void); + +// Using cycles_t rather than unsigned long [long] should be more portable; +// and, it appears necessary to mark __start_* and __end_* as volatile so the +// gcc compiler does not optimize out the register access: + +#define TIMER_vars(T) \ + register volatile cycles_t __start_##T, __stop_##T; \ + struct timeval __TVBeg_##T, __TVEnd_##T + +// This seems required for linux_ia32: + + +// Older code (see 4.13) used rdtscl(), but this is not portable and does not +// result in a 64-bit value, unlike get_cycles(), which apparently takes +// advantage of a 64-bit control register on both IA32 and IPF => always +// high-res timing with no rollover issues. Note, cycles_t is unsigned, so the +// math works even in case of a rollover. + +#define __START_HRTm(T) __start_##T = get_cycles() +#define __END_HRTm(T) __stop_##T = get_cycles() + +#define STARTTm(T) __START_HRTm(T) +#define ENDTm(D,T) { __END_HRTm(T); __HRONLY(D,T); } + +#endif // JU_LINUX_IPF + + +// ********************* WIN IA32 ***************************** +// +// WIN IA32 has no way to access the control register (?), so define STARTTm +// and ENDTm directly using clock(): + +#ifdef JU_WIN_IA32 + +clock_t TBeg, TEnd; + +#define TIMER_vars(T) struct timeval __TVBeg_##T, __TVEnd_##T + +#define STARTTm(T) __TVBeg_##T = clock() +#define ENDTm(D,T) { __TVEnd_##T = clock(); \ + (D) = ((double) (__TVEnd_##T - __TVBeg_##T)); } + +#endif // JU_WIN_IA32 + + +// ********************* OTHER ***************************** +// +// Default to using the low-res, slow-access clock only. + +#ifndef TIMER_vars + +#define TIMER_vars(T) struct timeval __TVBeg_##T, __TVEnd_##T + +#define STARTTm(T) gettimeofday(&__TVBeg_##T, NULL) + +#define ENDTm(D,T) gettimeofday(&__TVEnd_##T, NULL); \ + (D) = (((double) __TVEnd_##T.tv_sec * ((double) 1E6)) \ + + (double) __TVEnd_##T.tv_usec) \ + - (((double) __TVBeg_##T.tv_sec * ((double) 1E6)) \ + + (double) __TVBeg_##T.tv_usec) +#endif // ! TIMER_vars + + +// COMMON CODE FOR SYSTEMS WITH HIGH-RES CLOCKS (CONTROL REGISTERS): + +#ifdef __START_HRTm + +// Platforms that define __START_HRTm but not STARTTm (presently only hpux_pa) +// use gettimeofday() for the low-res clock and __START_HRTm/__END_HRTm for +// the high-res clock. If the low-res clock did not "roll over", use the +// high-res clock; see __HRONLY. +// +// Note: Rollover is defined conservatively as 1E5 usec (= 1/10 sec). This +// would require a 40 GHz 32-bit system to be violated. + +#ifndef STARTTm +#define STARTTm(T) \ + { \ + gettimeofday(&__TVBeg_##T, NULL); __START_HRTm(T); \ + } + +#define ENDTm(D,T) \ + { \ + __END_HRTm(T); gettimeofday(&__TVEnd_##T, NULL); \ + \ + (D) = (((double) __TVEnd_##T.tv_sec * ((double) 1E6)) \ + + (double) __TVEnd_##T.tv_usec) \ + - (((double) __TVBeg_##T.tv_sec * ((double) 1E6)) \ + + (double) __TVBeg_##T.tv_usec); \ + \ + if ((D) < 1E5) __HRONLY(D,T); \ + } +#endif // ! STARTTm + +// Faster forms for heavy/frequent use in code loops where intervals are less +// than 2^32[64] clock ticks: + +#define START_HRTm(T) __START_HRTm(T) +#define END_HRTm(D,T) { __END_HRTm(T); __HRONLY(D,T); } + +#endif // __START_HRTm + +#endif // #ifndef _TIMEIT_H diff --git a/feeds/p4/libjudy/src/tool/Makefile.am b/feeds/p4/libjudy/src/tool/Makefile.am new file mode 100644 index 000000000..33d218aad --- /dev/null +++ b/feeds/p4/libjudy/src/tool/Makefile.am @@ -0,0 +1,8 @@ +INCLUDES = -I. +AM_CFLAGS = @CFLAGS@ @WARN_CFLAGS@ + +noinst_PROGRAMS = jhton + +jhton_SOURCES = jhton.c + +DISTCLEANFILES = .deps Makefile diff --git a/feeds/p4/libjudy/src/tool/README b/feeds/p4/libjudy/src/tool/README new file mode 100644 index 000000000..1bd48ea46 --- /dev/null +++ b/feeds/p4/libjudy/src/tool/README @@ -0,0 +1,134 @@ + +# @(#) $Revision: 4.2 $ + +# CHECK README FILES AGAINST DIRECTORIES. + +# Usage: + + +<%=striptags( (boardinfo.hostname or "?") .. ( (node and node.title) and ' - ' .. translate(node.title) or '')) %> - LuCI + + + + + + + + + +
    + + +
    + <%- if luci.sys.process.info("uid") == 0 and luci.sys.user.getuser("root") and not luci.sys.user.getpasswd("root") and category ~= "failsafe" and path ~= "admin-system-admin-password" then -%> +
    +

    <%:No password set!%>

    +

    <%:There is no password set on this router. Please configure a root password to protect the web interface and enable SSH.%>

    + <% if disp.lookup("admin/system/admin") then %> + + <% end %> +
    + <%- end -%> + + diff --git a/feeds/ucentral/luci/luci-theme-ucentral/root/etc/uci-defaults/30_luci-theme-ucentral b/feeds/ucentral/luci/luci-theme-ucentral/root/etc/uci-defaults/30_luci-theme-ucentral new file mode 100755 index 000000000..dc5e3ad3b --- /dev/null +++ b/feeds/ucentral/luci/luci-theme-ucentral/root/etc/uci-defaults/30_luci-theme-ucentral @@ -0,0 +1,11 @@ +#!/bin/sh + +if [ "$PKG_UPGRADE" != 1 ]; then + uci batch <<-EOF + set luci.themes.ucentral=/luci-static/ucentral + set luci.main.mediaurlbase=/luci-static/ucentral + commit luci + EOF +fi + +exit 0 diff --git a/feeds/ucentral/luci/luci.mk b/feeds/ucentral/luci/luci.mk new file mode 100644 index 000000000..452fc0899 --- /dev/null +++ b/feeds/ucentral/luci/luci.mk @@ -0,0 +1,294 @@ +# +# Copyright (C) 2008-2015 The LuCI Team +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +LUCI_NAME?=$(notdir ${CURDIR}) +LUCI_TYPE?=$(word 2,$(subst -, ,$(LUCI_NAME))) +LUCI_BASENAME?=$(patsubst luci-$(LUCI_TYPE)-%,%,$(LUCI_NAME)) +LUCI_LANGUAGES:=$(sort $(filter-out templates,$(notdir $(wildcard ${CURDIR}/po/*)))) +LUCI_DEFAULTS:=$(notdir $(wildcard ${CURDIR}/root/etc/uci-defaults/*)) +LUCI_PKGARCH?=$(if $(realpath src/Makefile),,all) + +# Language code titles +LUCI_LANG.bg=българÑки (Bulgarian) +LUCI_LANG.bn_BD=বাংলা (Bengali) +LUCI_LANG.ca=Català (Catalan) +LUCI_LANG.cs=ÄŒeÅ¡tina (Czech) +LUCI_LANG.de=Deutsch (German) +LUCI_LANG.el=Ελληνικά (Greek) +LUCI_LANG.en=English +LUCI_LANG.es=Español (Spanish) +LUCI_LANG.fr=Français (French) +LUCI_LANG.he=עִבְרִית (Hebrew) +LUCI_LANG.hi=हिंदी (Hindi) +LUCI_LANG.hu=Magyar (Hungarian) +LUCI_LANG.it=Italiano (Italian) +LUCI_LANG.ja=日本語 (Japanese) +LUCI_LANG.ko=한국어 (Korean) +LUCI_LANG.mr=MarÄá¹­hÄ« (Marathi) +LUCI_LANG.ms=Bahasa Melayu (Malay) +LUCI_LANG.nb_NO=Norsk (Norwegian) +LUCI_LANG.pl=Polski (Polish) +LUCI_LANG.pt_BR=Português do Brasil (Brazilian Portuguese) +LUCI_LANG.pt=Português (Portuguese) +LUCI_LANG.ro=Română (Romanian) +LUCI_LANG.ru=РуÑÑкий (Russian) +LUCI_LANG.sk=SlovenÄina (Slovak) +LUCI_LANG.sv=Svenska (Swedish) +LUCI_LANG.tr=Türkçe (Turkish) +LUCI_LANG.uk=УкраїнÑька (Ukrainian) +LUCI_LANG.vi=Tiếng Việt (Vietnamese) +LUCI_LANG.zh_Hans=简体中文 (Chinese Simplified) +LUCI_LANG.zh_Hant=ç¹é«”中文 (Chinese Traditional) + +# Submenu titles +LUCI_MENU.col=1. Collections +LUCI_MENU.mod=2. Modules +LUCI_MENU.app=3. Applications +LUCI_MENU.theme=4. Themes +LUCI_MENU.proto=5. Protocols +LUCI_MENU.lib=6. Libraries + +# Language aliases +LUCI_LC_ALIAS.bn_BD=bn +LUCI_LC_ALIAS.nb_NO=no +LUCI_LC_ALIAS.pt_BR=pt-br +LUCI_LC_ALIAS.zh_Hans=zh-cn +LUCI_LC_ALIAS.zh_Hant=zh-tw + + +PKG_NAME?=$(LUCI_NAME) + + +# 1: everything expect po subdir or only po subdir +define findrev + $(shell \ + if git log -1 >/dev/null 2>/dev/null; then \ + set -- $$(git log -1 --format="%ct %h" --abbrev=7 -- $(if $(1),. ':(exclude)po',po)); \ + if [ -n "$$1" ]; then + secs="$$(($$1 % 86400))"; \ + yday="$$(date --utc --date="@$$1" "+%y.%j")"; \ + printf 'git-%s.%05d-%s' "$$yday" "$$secs" "$$2"; \ + else \ + echo "unknown"; \ + fi; \ + else \ + ts=$$(find . -type f $(if $(1),-not) -path './po/*' -printf '%T@\n' 2>/dev/null | sort -rn | head -n1 | cut -d. -f1); \ + if [ -n "$$ts" ]; then \ + secs="$$(($$ts % 86400))"; \ + date="$$(date --utc --date="@$$ts" "+%y%m%d")"; \ + printf '%s.%05d' "$$date" "$$secs"; \ + else \ + echo "unknown"; \ + fi; \ + fi \ + ) +endef + +PKG_PO_VERSION?=$(if $(DUMP),x,$(strip $(call findrev))) +PKG_SRC_VERSION?=$(if $(DUMP),x,$(strip $(call findrev,1))) + +PKG_GITBRANCH?=$(if $(DUMP),x,$(strip $(shell \ + variant="LuCI"; \ + if git log -1 >/dev/null 2>/dev/null; then \ + branch="$$(git branch --remote --verbose --no-abbrev --contains 2>/dev/null | \ + sed -rne 's|^[^/]+/([^ ]+) [a-f0-9]{40} .+$$|\1|p' | head -n1)"; \ + if [ "$$branch" != "master" ]; then \ + variant="LuCI $$branch branch"; \ + else \ + variant="LuCI Master"; \ + fi; \ + fi; \ + echo "$$variant" \ +))) + +PKG_RELEASE?=1 +PKG_INSTALL:=$(if $(realpath src/Makefile),1) +PKG_BUILD_DEPENDS += lua/host luci-base/host LUCI_CSSTIDY:csstidy/host LUCI_SRCDIET:luasrcdiet/host $(LUCI_BUILD_DEPENDS) +PKG_CONFIG_DEPENDS += CONFIG_LUCI_SRCDIET CONFIG_LUCI_JSMIN CONFIG_LUCI_CSSTIDY + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) + +include $(INCLUDE_DIR)/package.mk + +define Package/$(PKG_NAME) + SECTION:=luci + CATEGORY:=LuCI + SUBMENU:=$(if $(LUCI_MENU.$(LUCI_TYPE)),$(LUCI_MENU.$(LUCI_TYPE)),$(LUCI_MENU.app)) + TITLE:=$(if $(LUCI_TITLE),$(LUCI_TITLE),LuCI $(LUCI_NAME) $(LUCI_TYPE)) + DEPENDS:=$(LUCI_DEPENDS) + VERSION:=$(if $(PKG_VERSION),$(PKG_VERSION),$(PKG_SRC_VERSION)) + $(if $(LUCI_EXTRA_DEPENDS),EXTRA_DEPENDS:=$(LUCI_EXTRA_DEPENDS)) + $(if $(LUCI_PKGARCH),PKGARCH:=$(LUCI_PKGARCH)) +endef + +ifneq ($(LUCI_DESCRIPTION),) + define Package/$(PKG_NAME)/description + $(strip $(LUCI_DESCRIPTION)) + endef +endif + +# Language selection for luci-base +ifeq ($(PKG_NAME),luci-base) + define Package/luci-base/config + config LUCI_SRCDIET + bool "Minify Lua sources" + default n + + config LUCI_JSMIN + bool "Minify JavaScript sources" + default y + + config LUCI_CSSTIDY + bool "Minify CSS files" + default y + + menu "Translations"$(foreach lang,$(LUCI_LANGUAGES), + + config LUCI_LANG_$(lang) + tristate "$(shell echo '$(LUCI_LANG.$(lang))' | sed -e 's/^.* (\(.*\))$$/\1/') ($(lang))") + + endmenu + endef +endif + +define Build/Prepare + for d in luasrc htdocs root src; do \ + if [ -d ./$$$$d ]; then \ + mkdir -p $(PKG_BUILD_DIR)/$$$$d; \ + $(CP) ./$$$$d/* $(PKG_BUILD_DIR)/$$$$d/; \ + fi; \ + done + $(call Build/Prepare/Default) +endef + +define Build/Configure +endef + +ifneq ($(wildcard ${CURDIR}/src/Makefile),) + MAKE_PATH := src/ + MAKE_VARS += FPIC="$(FPIC)" LUCI_VERSION="$(PKG_SRC_VERSION)" LUCI_GITBRANCH="$(PKG_GITBRANCH)" + + define Build/Compile + $(call Build/Compile/Default,clean compile) + endef +else + define Build/Compile + endef +endif + +HTDOCS = /www +LUA_LIBRARYDIR = /usr/lib/lua +LUCI_LIBRARYDIR = $(LUA_LIBRARYDIR)/luci + +define SrcDiet + $(FIND) $(1) -type f -name '*.lua' | while read src; do \ + if LUA_PATH="$(STAGING_DIR_HOSTPKG)/lib/lua/5.1/?.lua" luasrcdiet --noopt-binequiv -o "$$$$src.o" "$$$$src"; \ + then mv "$$$$src.o" "$$$$src"; fi; \ + done +endef + +define JsMin + $(FIND) $(1) -type f -name '*.js' | while read src; do \ + if jsmin < "$$$$src" > "$$$$src.o"; \ + then mv "$$$$src.o" "$$$$src"; fi; \ + done +endef + +define CssTidy + $(FIND) $(1) -type f -name '*.css' | while read src; do \ + if csstidy "$$$$src" --template=highest --remove_last_semicolon=true "$$$$src.o"; \ + then mv "$$$$src.o" "$$$$src"; fi; \ + done +endef + +define SubstituteVersion + $(FIND) $(1) -type f -name '*.htm' | while read src; do \ + $(SED) 's/<%# *\([^ ]*\)PKG_VERSION *%>/\1$(if $(PKG_VERSION),$(PKG_VERSION),$(PKG_SRC_VERSION))/g' \ + -e 's/"\(<%= *\(media\|resource\) *%>[^"]*\.\(js\|css\)\)"/"\1?v=$(if $(PKG_VERSION),$(PKG_VERSION),$(PKG_SRC_VERSION))"/g' \ + "$$$$src"; \ + done +endef + +define Package/$(PKG_NAME)/install + if [ -d $(PKG_BUILD_DIR)/luasrc ]; then \ + $(INSTALL_DIR) $(1)$(LUCI_LIBRARYDIR); \ + cp -pR $(PKG_BUILD_DIR)/luasrc/* $(1)$(LUCI_LIBRARYDIR)/; \ + $(FIND) $(1)$(LUCI_LIBRARYDIR)/ -type f -name '*.luadoc' | $(XARGS) rm; \ + $(if $(CONFIG_LUCI_SRCDIET),$(call SrcDiet,$(1)$(LUCI_LIBRARYDIR)/),true); \ + $(call SubstituteVersion,$(1)$(LUCI_LIBRARYDIR)/); \ + else true; fi + if [ -d $(PKG_BUILD_DIR)/htdocs ]; then \ + $(INSTALL_DIR) $(1)$(HTDOCS); \ + cp -pR $(PKG_BUILD_DIR)/htdocs/* $(1)$(HTDOCS)/; \ + $(if $(CONFIG_LUCI_JSMIN),$(call JsMin,$(1)$(HTDOCS)/),true); \ + $(if $(CONFIG_LUCI_CSSTIDY),$(call CssTidy,$(1)$(HTDOCS)/),true); \ + else true; fi + if [ -d $(PKG_BUILD_DIR)/root ]; then \ + $(INSTALL_DIR) $(1)/; \ + cp -pR $(PKG_BUILD_DIR)/root/* $(1)/; \ + else true; fi + if [ -d $(PKG_BUILD_DIR)/src ]; then \ + $(call Build/Install/Default) \ + $(CP) $(PKG_INSTALL_DIR)/* $(1)/; \ + else true; fi +endef + +ifndef Package/$(PKG_NAME)/postinst +define Package/$(PKG_NAME)/postinst +[ -n "$${IPKG_INSTROOT}" ] || {$(foreach script,$(LUCI_DEFAULTS), + (. /etc/uci-defaults/$(script)) && rm -f /etc/uci-defaults/$(script)) + rm -f /tmp/luci-indexcache + rm -rf /tmp/luci-modulecache/ + killall -HUP rpcd 2>/dev/null + exit 0 +} +endef +endif + + +LUCI_BUILD_PACKAGES := $(PKG_NAME) + +# 1: LuCI language code +# 2: BCP 47 language tag +define LuciTranslation + define Package/luci-i18n-$(LUCI_BASENAME)-$(1) + SECTION:=luci + CATEGORY:=LuCI + TITLE:=$(PKG_NAME) - $(1) translation + HIDDEN:=1 + DEFAULT:=LUCI_LANG_$(2)||(ALL&&m) + DEPENDS:=$(PKG_NAME) + VERSION:=$(PKG_PO_VERSION) + PKGARCH:=all + endef + + define Package/luci-i18n-$(LUCI_BASENAME)-$(1)/description + Translation for $(PKG_NAME) - $(LUCI_LANG.$(2)) + endef + + define Package/luci-i18n-$(LUCI_BASENAME)-$(1)/install + $$(INSTALL_DIR) $$(1)/etc/uci-defaults + echo "uci set luci.languages.$(subst -,_,$(1))='$(LUCI_LANG.$(2))'; uci commit luci" \ + > $$(1)/etc/uci-defaults/luci-i18n-$(LUCI_BASENAME)-$(1) + $$(INSTALL_DIR) $$(1)$(LUCI_LIBRARYDIR)/i18n + $(foreach po,$(wildcard ${CURDIR}/po/$(2)/*.po), \ + po2lmo $(po) \ + $$(1)$(LUCI_LIBRARYDIR)/i18n/$(basename $(notdir $(po))).$(1).lmo;) + endef + + define Package/luci-i18n-$(LUCI_BASENAME)-$(1)/postinst + [ -n "$$$${IPKG_INSTROOT}" ] || { + (. /etc/uci-defaults/luci-i18n-$(LUCI_BASENAME)-$(1)) && rm -f /etc/uci-defaults/luci-i18n-$(LUCI_BASENAME)-$(1) + exit 0 + } + endef + + LUCI_BUILD_PACKAGES += luci-i18n-$(LUCI_BASENAME)-$(1) + +endef + +$(foreach lang,$(LUCI_LANGUAGES),$(eval $(call LuciTranslation,$(firstword $(LUCI_LC_ALIAS.$(lang)) $(lang)),$(lang)))) +$(foreach pkg,$(LUCI_BUILD_PACKAGES),$(eval $(call BuildPackage,$(pkg)))) diff --git a/feeds/ucentral/poco/Makefile b/feeds/ucentral/poco/Makefile new file mode 100644 index 000000000..910c0af36 --- /dev/null +++ b/feeds/ucentral/poco/Makefile @@ -0,0 +1,110 @@ +# +# Copyright (C) 2007-2016 OpenWrt.org +# Copyright (C) 2017 Daniel Engberg +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=poco +PKG_RELEASE:=2 +PKG_VERSION:=1.10.1 + +ifeq ($(BUILD_VARIANT),all) +_PKG_VERSION:=${PKG_VERSION}-all +PKG_HASH:=2cde4b50778013ab3b7a522aa59bccaa7e85a8ccfc654a354c4d9611b6ce1758 +else +_PKG_VERSION:=${PKG_VERSION} +PKG_HASH:=a0a5a03d87c585f1a43def33bfc52c0c34a528e43a7b13bc83841a7c00adde39 +endif + +PKG_SOURCE:=$(PKG_NAME)-$(_PKG_VERSION).tar.bz2 +PKG_SOURCE_URL:=https://pocoproject.org/releases/$(PKG_NAME)-$(PKG_VERSION) + +PKG_LICENSE:=BSL-1.0 +PKG_LICENSE_FILES:=LICENSE +PKG_CPE_ID:=cpe:/a:pocoproject:poco + +PKG_BUILD_PARALLEL:=1 +PKG_INSTALL:=1 +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(_PKG_VERSION) + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk + +define Package/poco + SECTION:=libs + CATEGORY:=Libraries + TITLE:=Poco C++ libraries + URL:=https://www.pocoproject.org/ + DEPENDS:=+libstdcpp +libpthread +librt @!arc + MAINTAINER:=Jean-Michel Julien + VARIANT:=minimal +endef + +define Package/poco/description + POrtable COmponents, a modern and powerful open source C++ class libraries + and frameworks for building network and internet-based applications that + run on desktop, server and embedded systems. +endef + +define Package/poco-all + $(call Package/poco) + SECTION:=libs + CATEGORY:=Libraries + TITLE+=(Complete Edition) + DEPENDS+=+libopenssl + VARIANT:=all +endef + +define Package/poco-all/description + POrtable COmponents, a modern and powerful open source C++ class libraries + and frameworks for building network and internet-based applications that + run on desktop, server and embedded systems. The Complete Edition contains + all libraries. +endef + +CONFIGURE_ARGS += \ + --config=Linux \ + --no-tests \ + --no-samples \ + --no-fpenvironment \ + --no-sharedmemory \ + --no-wstring \ + --shared + +ifeq ($(BUILD_VARIANT),all) + CONFIGURE_ARGS += \ + --typical + POCO_LIBS={Foundation,XML,JSON,Net,Util,Crypto,NetSSL,Encodings,Util,Data,DataSQLite} +else + CONFIGURE_ARGS += \ + --poquito \ + --minimal + POCO_LIBS={Foundation,XML,JSON,Net,Util} +endif + +define Package/poco/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libPoco$(POCO_LIBS).so* $(1)/usr/lib/ +endef + +define Package/poco-all/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libPoco$(POCO_LIBS).so* $(1)/usr/lib/ +endef + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include + $(CP) $(PKG_INSTALL_DIR)/usr/include/Poco $(1)/usr/include/ + + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libPoco$(POCO_LIBS).so* $(1)/usr/lib/ + $(CP) $(PKG_INSTALL_DIR)/usr/lib/cmake $(1)/usr/lib/ +endef + + +$(eval $(call BuildPackage,poco)) +$(eval $(call BuildPackage,poco-all)) diff --git a/feeds/ucentral/poco/patches/100-configure.patch b/feeds/ucentral/poco/patches/100-configure.patch new file mode 100644 index 000000000..01ceb6767 --- /dev/null +++ b/feeds/ucentral/poco/patches/100-configure.patch @@ -0,0 +1,15 @@ +--- a/configure ++++ b/configure +@@ -237,9 +237,9 @@ while [ $# -ge 1 ]; do + ;; + + *) +- showhelp +- exit 1 +- ;; ++# showhelp ++# exit 1 ++# ;; + esac + + shift diff --git a/feeds/ucentral/poco/patches/200-strerror.patch b/feeds/ucentral/poco/patches/200-strerror.patch new file mode 100644 index 000000000..0ff0ce5ed --- /dev/null +++ b/feeds/ucentral/poco/patches/200-strerror.patch @@ -0,0 +1,11 @@ +--- a/Foundation/src/Error.cpp ++++ b/Foundation/src/Error.cpp +@@ -70,7 +70,7 @@ namespace Poco { + + #if (_XOPEN_SOURCE >= 600) || POCO_OS == POCO_OS_ANDROID || __APPLE__ + setMessage(strerror_r(err, _buffer, sizeof(_buffer))); +-#elif _GNU_SOURCE ++#elif (_GNU_SOURCE && (defined __GLIBC__ || defined __UCLIBC__)) + setMessage(strerror_r(err, _buffer, sizeof(_buffer))); + #else + setMessage(strerror(err)); diff --git a/feeds/ucentral/rtty/Makefile b/feeds/ucentral/rtty/Makefile new file mode 100644 index 000000000..091d0201b --- /dev/null +++ b/feeds/ucentral/rtty/Makefile @@ -0,0 +1,71 @@ +# +# Copyright (C) 2018 Jianhui Zhao +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=rtty +PKG_VERSION:=7.1.4 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL=https://github.com/zhaojh329/rtty/releases/download/v$(PKG_VERSION) +PKG_HASH:=f0b8cf4c4d3d4b34d10097fe430d32ab1576edbf41131d27b6b964e078be1716 +CMAKE_INSTALL:=1 + +PKG_LICENSE:=MIT +PKG_LICENSE_FILES:=LICENSE + +PKG_MAINTAINER:=Jianhui Zhao + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk + +define Package/rtty/Default + TITLE:=Access your terminals from anywhere via the web + SECTION:=utils + CATEGORY:=Utilities + SUBMENU:=Terminal + URL:=https://github.com/zhaojh329/rtty + DEPENDS:=+libev $(2) + VARIANT:=$(1) + PROVIDES:=rtty +endef + +Package/rtty-openssl=$(call Package/rtty/Default,openssl,+PACKAGE_rtty-openssl:libopenssl) +Package/rtty-wolfssl=$(call Package/rtty/Default,wolfssl,+PACKAGE_rtty-wolfssl:libwolfssl) +Package/rtty-mbedtls=$(call Package/rtty/Default,mbedtls,+PACKAGE_rtty-mbedtls:libmbedtls +PACKAGE_rtty-mbedtls:zlib) +Package/rtty-nossl=$(call Package/rtty/Default,nossl) + +define Package/rtty-openssl/conffiles +/etc/config/rtty +endef + +Package/rtty-wolfssl/conffiles = $(Package/rtty-openssl/conffiles) +Package/rtty-mbedtls/conffiles = $(Package/rtty-openssl/conffiles) +Package/rtty-nossl/conffiles = $(Package/rtty-openssl/conffiles) + +ifeq ($(BUILD_VARIANT),openssl) + CMAKE_OPTIONS += -DRTTY_USE_OPENSSL=ON +else ifeq ($(BUILD_VARIANT),wolfssl) + CMAKE_OPTIONS += -DRTTY_USE_WOLFSSL=ON +else ifeq ($(BUILD_VARIANT),mbedtls) + CMAKE_OPTIONS += -DRTTY_USE_MBEDTLS=ON +else + CMAKE_OPTIONS += -DRTTY_SSL_SUPPORT=OFF +endif + +define Package/rtty-$(BUILD_VARIANT)/install + $(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/init.d $(1)/etc/config + $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/rtty $(1)/usr/sbin + $(INSTALL_BIN) ./files/rtty.init $(1)/etc/init.d/rtty + $(INSTALL_CONF) ./files/rtty.config $(1)/etc/config/rtty +endef + +$(eval $(call BuildPackage,rtty-openssl)) +$(eval $(call BuildPackage,rtty-wolfssl)) +$(eval $(call BuildPackage,rtty-mbedtls)) +$(eval $(call BuildPackage,rtty-nossl)) diff --git a/feeds/ucentral/rtty/files/rtty.config b/feeds/ucentral/rtty/files/rtty.config new file mode 100644 index 000000000..b9952ce1d --- /dev/null +++ b/feeds/ucentral/rtty/files/rtty.config @@ -0,0 +1,14 @@ +# You must specify an interface or id, +# If the id is not specified, RTTY will uses the MAC address +# of the interface you specify as its ID, otherwise the id +# you specify is used as its ID + +#config rtty +# option interface 'lan' +# option id 'My-Device' +# option description 'Description of my device' +# option host 'your-server-host' # Server host +# option port '5912' # Server Port +# option ssl 1 # Whether to use ssl +# option token 'your-token' # generated by rttys +# option verbose '1' # verbose log diff --git a/feeds/ucentral/rtty/files/rtty.init b/feeds/ucentral/rtty/files/rtty.init new file mode 100644 index 000000000..94b4c364b --- /dev/null +++ b/feeds/ucentral/rtty/files/rtty.init @@ -0,0 +1,65 @@ +#!/bin/sh /etc/rc.common + +USE_PROCD=1 +START=99 + +BIN=/usr/sbin/rtty + +validate_rtty_section() { + uci_load_validate rtty rtty "$1" "$2" \ + 'interface:uci("network", "@interface"):lan' \ + 'id:maxlength(63)' \ + 'description:maxlength(126)' \ + 'host:host' \ + 'port:port' \ + 'ssl:bool:0' \ + 'token:maxlength(32)' \ + 'verbose:bool:0' +} + +start_rtty() { + . /lib/functions/network.sh + + local ifname + + [ "$2" = 0 ] || { + echo "validation failed" >&2 + return 1 + } + + [ -n "$interface" ] && network_get_device ifname "$interface" + + [ -z "$ifname" -a -z "$id" ] && { + echo "You must specify an interface or ID" >&2 + return 1 + } + + [ -z "$host" ] && { + echo "host required" >&2 + return 1 + } + + [ -z "$id" ] && { + id=$(sed 's/://g' /sys/class/net/$ifname/address | tr 'a-z' 'A-Z') + } + + procd_open_instance + procd_set_param command $BIN -h $host -I "$id" -a + [ -n "$port" ] && procd_append_param command -p "$port" + [ -n "$description" ] && procd_append_param command -d "$description" + [ "$ssl" = "1" ] && procd_append_param command -s + [ -n "$token" ] && procd_append_param command -t "$token" + [ "$verbose" = "1" ] && procd_append_param command -v + procd_set_param respawn + procd_close_instance +} + +start_service() { + config_load rtty + config_foreach validate_rtty_section rtty start_rtty +} + +service_triggers() { + procd_add_reload_trigger "rtty" + procd_add_validation validate_rtty_section +} diff --git a/feeds/ucentral/rtty/patches/100-oneshot.patch b/feeds/ucentral/rtty/patches/100-oneshot.patch new file mode 100644 index 000000000..59258c385 --- /dev/null +++ b/feeds/ucentral/rtty/patches/100-oneshot.patch @@ -0,0 +1,65 @@ +Index: rtty-7.1.4/src/rtty.c +=================================================================== +--- rtty-7.1.4.orig/src/rtty.c ++++ rtty-7.1.4/src/rtty.c +@@ -308,7 +308,8 @@ static void parse_msg(struct rtty *rtty) + + case MSG_TYPE_LOGOUT: + tty_logout(rtty, buffer_pull_u8(rb)); +- break; ++ exit(1); ++ break; + + case MSG_TYPE_TERMDATA: + write_data_to_tty(rtty, buffer_pull_u8(rb), msglen - 1); +@@ -429,12 +430,12 @@ static void rtty_timer_cb(struct ev_loop + return; + } + +- if (now - rtty->active > RTTY_HEARTBEAT_INTEVAL * 3 / 2) { ++/* if (now - rtty->active > RTTY_HEARTBEAT_INTEVAL * 3 / 2) { + log_err("Inactive too long time\n"); + rtty_exit(rtty); + return; + } +- ++*/ + if (now - rtty->last_heartbeat > RTTY_HEARTBEAT_INTEVAL - 1) { + rtty->last_heartbeat = now; + rtty_send_msg(rtty, MSG_TYPE_HEARTBEAT, NULL, 0); +Index: rtty-7.1.4/src/main.c +=================================================================== +--- rtty-7.1.4.orig/src/main.c ++++ rtty-7.1.4/src/main.c +@@ -95,7 +95,7 @@ int main(int argc, char **argv) + int c; + + while (true) { +- c = getopt_long(argc, argv, "I:h:p:d:asDt:f:RS:vV", long_options, &option_index); ++ c = getopt_long(argc, argv, "I:h:p:d:asDt:f:RS:vVT:", long_options, &option_index); + if (c == -1) + break; + +@@ -109,6 +109,9 @@ int main(int argc, char **argv) + case 'p': + rtty.port = atoi(optarg); + break; ++ case 'T': ++ rtty.timeout = atoi(optarg); ++ break; + case 'd': + if (strlen(optarg) > 126) { + log_err("Description too long\n"); +Index: rtty-7.1.4/src/rtty.h +=================================================================== +--- rtty-7.1.4.orig/src/rtty.h ++++ rtty-7.1.4/src/rtty.h +@@ -79,6 +79,8 @@ struct rtty { + void *ssl; /* Context wrap of openssl, wolfssl and mbedtls */ + struct tty *ttys[RTTY_MAX_TTY]; + struct file_context file_context; ++ int timeout; ++ struct ev_timer kill_timer; + }; + + int rtty_start(struct rtty *rtty); diff --git a/feeds/ucentral/ucentral-client/Makefile b/feeds/ucentral/ucentral-client/Makefile new file mode 100644 index 000000000..dc8d7908c --- /dev/null +++ b/feeds/ucentral/ucentral-client/Makefile @@ -0,0 +1,37 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=ucentral-client +PKG_RELEASE:=1 + +PKG_SOURCE_URL=https://github.com/blogic/ucentral-client.git +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2021-02-15 +PKG_SOURCE_VERSION:=cf6333e0934f1b83fdb5cc8368cea2421c97d90b + +PKG_LICENSE:=BSD-3-Clause +PKG_MAINTAINER:=John Crispin + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk + +define Package/ucentral-client + SECTION:=ucentral + CATEGORY:=uCentral + TITLE:=OpenWrt uCentral websocket client + DEPENDS:=+ucentral-jsonschema +ucentral-schema \ + +ucode +ucode-mod-fs +ucode-mod-ubus +ucode-mod-uci \ + +libubox +libwebsockets-openssl +libblobmsg-json +libubus +endef + +define Package/ucentral-client/conffiles +/etc/ucentral/ +/etc/config-shadow/ +endef + +define Package/ucentral-client/install + $(INSTALL_DIR) $(1)/usr/sbin/ + $(INSTALL_BIN) $(PKG_BUILD_DIR)/ucentral $(1)/usr/sbin/ + $(CP) ./files/* $(1) +endef + +$(eval $(call BuildPackage,ucentral-client)) diff --git a/feeds/ucentral/ucentral-client/files/etc/config/ucentral b/feeds/ucentral/ucentral-client/files/etc/config/ucentral new file mode 100644 index 000000000..764c47942 --- /dev/null +++ b/feeds/ucentral/ucentral-client/files/etc/config/ucentral @@ -0,0 +1,5 @@ +config ucentral config + option serial '00:11:22:33:44:55' + option server '192.168.178.9' + option port '11783' + option reporting 10 diff --git a/feeds/ucentral/ucentral-client/files/etc/config/ustats b/feeds/ucentral/ucentral-client/files/etc/config/ustats new file mode 100644 index 000000000..ffc5e9cae --- /dev/null +++ b/feeds/ucentral/ucentral-client/files/etc/config/ustats @@ -0,0 +1,10 @@ +config stats stats + option interval 0 + option neighbours 0 + option traffic 0 + option wifiiface 0 + option wifistation 0 + option pids 0 + option serviceprobe 0 + option lldp 0 + option system 0 diff --git a/feeds/ucentral/ucentral-client/files/etc/init.d/ucentral b/feeds/ucentral/ucentral-client/files/etc/init.d/ucentral new file mode 100644 index 000000000..9df33a74d --- /dev/null +++ b/feeds/ucentral/ucentral-client/files/etc/init.d/ucentral @@ -0,0 +1,33 @@ +#!/bin/sh /etc/rc.common + +START=99 + +USE_PROCD=1 +PROG=/usr/sbin/ucentral + +service_triggers() { + procd_add_reload_trigger ucentral +} + +start_service() { + [ -f /etc/ucentral/capabilities.json ] || { + ucode -m ubus -E board=/etc/board.json /usr/share/ucentral/capabilities.uc > /etc/ucentral/capabilities.json + } + + . /lib/functions.sh + config_load 'ucentral' + config_get serial 'config' 'serial' + config_get server 'config' 'server' + config_get port 'config' 'port' + config_get debug 'config' 'debug' 0 + + procd_open_instance + procd_set_param command "$PROG" + [ -n "$serial" ] && procd_append_param command -S $serial + [ -n "$server" ] && procd_append_param command -s $server + [ -n "$port" ] && procd_append_param command -P $port + [ -n "$reporting" ] && procd_append_param command -r $reporting + [ "$debug" -eq 0 ] || procd_append_param command -d + procd_set_param respawn 3600 5 0 + procd_close_instance +} diff --git a/feeds/ucentral/ucentral-client/files/etc/init.d/ustats b/feeds/ucentral/ucentral-client/files/etc/init.d/ustats new file mode 100644 index 000000000..e21326152 --- /dev/null +++ b/feeds/ucentral/ucentral-client/files/etc/init.d/ustats @@ -0,0 +1,23 @@ +#!/bin/sh /etc/rc.common + +START=99 + +USE_PROCD=1 +PROG=/usr/libexec/ucentral/ucentral_state.sh + +service_triggers() { + procd_add_reload_trigger ustats +} + +start_service() { + . /lib/functions.sh + config_load 'ustats' + config_get interval 'stats' 'interval' 0 + + [ "$interval" -eq 0 ] && return 0 + + procd_open_instance + procd_set_param command "$PROG" + procd_set_param respawn 1 $interval 0 + procd_close_instance +} diff --git a/feeds/ucentral/ucentral-client/files/etc/ucentral/ucentral.failsafe b/feeds/ucentral/ucentral-client/files/etc/ucentral/ucentral.failsafe new file mode 100644 index 000000000..9f4315fc5 --- /dev/null +++ b/feeds/ucentral/ucentral-client/files/etc/ucentral/ucentral.failsafe @@ -0,0 +1,60 @@ +{ + "uuid": 1, + "phy": [ + { + "band": "2", + "cfg": { + "disabled": 0 + } + }, + { + "band": "5", + "cfg": { + "disabled": 0 + } + }, + { + "band": "5u", + "cfg": { + "disabled": 0 + } + }, + { + "band": "5l", + "cfg": { + "disabled": 0 + } + } + ], + "ssid": [ + { + "band": [ + "2" + ], + "cfg": { + "ssid": "Maverick", + "encryption": "none", + "mode": "ap", + "network": "lan" + } + }, + { + "band": [ + "5", "5u", "5l" + ], + "cfg": { + "ssid": "Maverick", + "encryption": "none", + "mode": "ap", + "network": "lan" + } + } + ], + "network": [ + { + "mode": "wan", + "cfg": { + "proto": "dhcp" + } + }] +} diff --git a/feeds/ucentral/ucentral-client/files/etc/uci-defaults/zzz-ucentral b/feeds/ucentral/ucentral-client/files/etc/uci-defaults/zzz-ucentral new file mode 100644 index 000000000..b7c112319 --- /dev/null +++ b/feeds/ucentral/ucentral-client/files/etc/uci-defaults/zzz-ucentral @@ -0,0 +1,25 @@ +#!/bin/sh + +[ -d /etc/config-shadow/ ] && exit 0 + +hname=$(cat /sys/class/net/eth0/address | tr -d : | awk '{print tolower($0)}') +uci set system.@system[-1].hostname=$hname +uci set ucentral.config.serial=$hname +uci set network.wan6.ifname=@wan +uci set network.wan.type=bridge +uci commit + +cp -r /etc/config/ /etc/config-shadow/ + +. /lib/functions.sh + +UCI_CONFIG_DIR=/etc/config-shadow + +iface_del() { + uci -c $UCI_CONFIG_DIR delete wireless.$1 +} + +config_load wireless +config_foreach iface_del wifi-iface + +uci -c $UCI_CONFIG_DIR commit diff --git a/feeds/ucentral/ucentral-client/files/usr/libexec/ucentral/ucentral_apply.sh b/feeds/ucentral/ucentral-client/files/usr/libexec/ucentral/ucentral_apply.sh new file mode 100755 index 000000000..69aa8eb2a --- /dev/null +++ b/feeds/ucentral/ucentral-client/files/usr/libexec/ucentral/ucentral_apply.sh @@ -0,0 +1,39 @@ +#!/bin/sh + +config=$1 + +echo config:$config + +[ -f "$config" ] || { + logger "ucentral_apply: invalid paramters" + exit 1 +} + +ucode -m ubus -m uci -m fs -E capab=/etc/ucentral/capabilities.json -E cfg=$1 -i /usr/share/ucentral/ucentral.uc > /tmp/ucentral.uci + +[ $? -eq 0 ] || { + logger "ucentral_apply: applying $1 failed" + exit 1 +} + +active=$(readlink /etc/ucentral/ucentral.active) +[ -n "$active" -a -f "$active" ] && { + rm -f /etc/ucentral/ucentral.old + ln -s $active /etc/ucentral/ucentral.old +} + +rm -f /etc/ucentral/ucentral.active +ln -s $config /etc/ucentral/ucentral.active + +rm -rf /tmp/config-shadow +cp -r /etc/config-shadow /tmp +cat /tmp/ucentral.uci | uci -c /tmp/config-shadow batch 2> /dev/null +uci -c /tmp/config-shadow commit + +cp /tmp/config-shadow/* /etc/config/ + +reload_config + +rm -rf /tmp/config-shadow + +return 0 diff --git a/feeds/ucentral/ucentral-client/files/usr/libexec/ucentral/ucentral_cmd.sh b/feeds/ucentral/ucentral-client/files/usr/libexec/ucentral/ucentral_cmd.sh new file mode 100755 index 000000000..dfb916140 --- /dev/null +++ b/feeds/ucentral/ucentral-client/files/usr/libexec/ucentral/ucentral_cmd.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +cmd=$1 +id=$2 + +[ -f "$cmd" -a -n "$id" ] || { + logger "ucentral_cmd: invalid paramters" + exit 1 +} + +ucode -m uci -m fs -m ubus -E capab=/etc/ucentral/capabilities.json -E cmd=$cmd -e "{\"id\":$id}" -i /usr/share/ucentral/cmd.uc > /tmp/ucentral.cmd + +[ $? -eq 0 ] || { + logger "ucentral_cmd: executing $cmd failed" + exit 1 +} + +return 0 diff --git a/feeds/ucentral/ucentral-client/files/usr/libexec/ucentral/ucentral_factory.sh b/feeds/ucentral/ucentral-client/files/usr/libexec/ucentral/ucentral_factory.sh new file mode 100644 index 000000000..dbeca3b77 --- /dev/null +++ b/feeds/ucentral/ucentral-client/files/usr/libexec/ucentral/ucentral_factory.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +tar czf /sysupgrade.tgz /etc/config/ucentral /etc/ucentral/*.pem /etc/ucentral/*.crt /etc/ucentral/ucentral.active $(readlink /etc/ucentral/ucentral.active) +jffs2reset -r -y -k diff --git a/feeds/ucentral/ucentral-client/files/usr/libexec/ucentral/ucentral_failsafe.sh b/feeds/ucentral/ucentral-client/files/usr/libexec/ucentral/ucentral_failsafe.sh new file mode 100755 index 000000000..4dae48463 --- /dev/null +++ b/feeds/ucentral/ucentral-client/files/usr/libexec/ucentral/ucentral_failsafe.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +cp /etc/ucentral/ucentral.failsafe /etc/ucentral/ucentral.cfg.0000000001 diff --git a/feeds/ucentral/ucentral-client/files/usr/libexec/ucentral/ucentral_led_blink.sh b/feeds/ucentral/ucentral-client/files/usr/libexec/ucentral/ucentral_led_blink.sh new file mode 100755 index 000000000..bc6a92623 --- /dev/null +++ b/feeds/ucentral/ucentral-client/files/usr/libexec/ucentral/ucentral_led_blink.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +. /etc/diag.sh +set_state upgrade +sleep 60 +status_led_off +set_state done diff --git a/feeds/ucentral/ucentral-client/files/usr/libexec/ucentral/ucentral_state.sh b/feeds/ucentral/ucentral-client/files/usr/libexec/ucentral/ucentral_state.sh new file mode 100755 index 000000000..785766dca --- /dev/null +++ b/feeds/ucentral/ucentral-client/files/usr/libexec/ucentral/ucentral_state.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +ucode -m fs -m uci -m ubus -i /usr/share/ucentral/state.uc -E cfg=/etc/ucentral/ucentral.active diff --git a/feeds/ucentral/ucentral-client/files/usr/libexec/ucentral/ucentral_sysupgrade.sh b/feeds/ucentral/ucentral-client/files/usr/libexec/ucentral/ucentral_sysupgrade.sh new file mode 100644 index 000000000..df8cec3d8 --- /dev/null +++ b/feeds/ucentral/ucentral-client/files/usr/libexec/ucentral/ucentral_sysupgrade.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +tar czf /tmp/sysupgrade.tgz /etc/config/ucentral /etc/ucentral/*.pem /etc/ucentral/*.crt /etc/ucentral/ucentral.active $(readlink /etc/ucentral/ucentral.active) +sysupgrade -f /tmp/sysupgrade.tgz $1 diff --git a/feeds/ucentral/ucentral-client/files/usr/libexec/ucentral/ucentral_verify.sh b/feeds/ucentral/ucentral-client/files/usr/libexec/ucentral/ucentral_verify.sh new file mode 100755 index 000000000..ec2e3253c --- /dev/null +++ b/feeds/ucentral/ucentral-client/files/usr/libexec/ucentral/ucentral_verify.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +config=$1 +uuid=$2 + +[ -f "$config" -a -n "$uuid" ] || { + logger "ucentral_verify: invalid paramters" + exit 1 +} + +jsonschema $1 /usr/share/ucentral/ucentral.schema.json > /tmp/ucentral.verify + +[ $? -eq 0 ] || { + ubus call ucentral log "{\"error\": \"schema failed\", \"uuid\": $uuid}" + logger "ucentral_verify: schema failed" + exit 1 +} + +cp $config /etc/ucentral/ucentral.cfg.$uuid + +return 0 diff --git a/feeds/ucentral/ucentral-client/git-src b/feeds/ucentral/ucentral-client/git-src new file mode 120000 index 000000000..dae7ac789 --- /dev/null +++ b/feeds/ucentral/ucentral-client/git-src @@ -0,0 +1 @@ +/ucentral/ucentral-client/.git \ No newline at end of file diff --git a/feeds/ucentral/ucentral-defaults/Makefile b/feeds/ucentral/ucentral-defaults/Makefile new file mode 100644 index 000000000..c3cec9dde --- /dev/null +++ b/feeds/ucentral/ucentral-defaults/Makefile @@ -0,0 +1,34 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=ucentral-defaults +PKG_RELEASE:=1 + +PKG_LICENSE:=BSD-3-Clause +PKG_MAINTAINER:=John Crispin + +include $(INCLUDE_DIR)/package.mk + +define Package/ucentral-defaults + SECTION:=ucentral + CATEGORY:=uCentral + TITLE:=ucentral-defaults +endef + +define Package/ucentral-defaults/description + The default configuration of the AP. +endef + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) +endef + +define Build/Compile/Default + +endef +Build/Compile = $(Build/Compile/Default) + +define Package/ucentral-defaults/install + $(CP) ./files/* $(1) +endef + +$(eval $(call BuildPackage,ucentral-defaults)) diff --git a/feeds/ucentral/ucentral-defaults/files/etc/uci-defaults/99-ucentral-lldp b/feeds/ucentral/ucentral-defaults/files/etc/uci-defaults/99-ucentral-lldp new file mode 100755 index 000000000..bd3f23eb0 --- /dev/null +++ b/feeds/ucentral/ucentral-defaults/files/etc/uci-defaults/99-ucentral-lldp @@ -0,0 +1,13 @@ +#!/bin/sh + +uci set lldpd.config.enable_cdp=0 +uci set lldpd.config.enable_fdp=0 +uci set lldpd.config.enable_sonmp=0 +uci set lldpd.config.enable_edp=0 +uci set lldpd.config.description="TIP/OpenAP" +uci set lldpd.config.lldp_hostname="$(cat /tmp/sysinfo/model)" +uci del lldpd.config.lldp_location +uci del lldpd.config.interface +uci add_list lldpd.config.interface=wan +uci add_list lldpd.config.interface=lan +uci commit lldpd diff --git a/feeds/ucentral/ucentral-defaults/files/etc/uci-defaults/99-ucentral-rtty b/feeds/ucentral/ucentral-defaults/files/etc/uci-defaults/99-ucentral-rtty new file mode 100755 index 000000000..b84cb09b3 --- /dev/null +++ b/feeds/ucentral/ucentral-defaults/files/etc/uci-defaults/99-ucentral-rtty @@ -0,0 +1,7 @@ +#!/bin/sh +uci add rtty rtty +uci set rtty.@rtty[-1].id=$(cat /sys/class/net/eth0/address | tr -d :) +uci set rtty.@rtty[-1].description="$(cat /tmp/sysinfo/model)" +uci set rtty.@rtty[-1].ssl=1 +uci set rtty.@rtty[-1].port='5912' +uci commit rtty diff --git a/feeds/ucentral/ucentral-jsonschema/Makefile b/feeds/ucentral/ucentral-jsonschema/Makefile new file mode 100644 index 000000000..8baf3be0b --- /dev/null +++ b/feeds/ucentral/ucentral-jsonschema/Makefile @@ -0,0 +1,29 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=ucentral-jsonschema +PKG_RELEASE:=1 + +PKG_SOURCE_URL=https://github.com/blogic/ucentral-jsonschema.git +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2022-11-19 +PKG_SOURCE_VERSION:=98765ffecc5f6ec82ca7023a8ab6f036b359fe38 + +PKG_LICENSE:=BSD-3-Clause +PKG_MAINTAINER:=John Crispin + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk + +define Package/ucentral-jsonschema + SECTION:=ucentral + CATEGORY:=uCentral + TITLE:=JSON Schema Validator + DEPENDS:=+libjson-c +endef + +define Package/ucentral-jsonschema/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/jsonschema $(1)/usr/sbin/ +endef + +$(eval $(call BuildPackage,ucentral-jsonschema)) diff --git a/feeds/ucentral/ucentral-mqtt/Makefile b/feeds/ucentral/ucentral-mqtt/Makefile new file mode 100644 index 000000000..e77327b10 --- /dev/null +++ b/feeds/ucentral/ucentral-mqtt/Makefile @@ -0,0 +1,32 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=ucentral-mqtt +PKG_RELEASE:=1 + +PKG_SOURCE_URL=https://github.com/blogic/ucentral-mqtt.git +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2022-11-27 +PKG_SOURCE_VERSION:=6323938ad7f6b1b9dc172cdf6831dd7085c30100 + +PKG_MAINTAINER:=John Crispin +PKG_LICENSE:=BSD-3-Clause + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk + +define Package/ucentral-mqtt + SECTION:=ucentral + CATEGORY:=uCentral + TITLE:=OpenWrt uCentral mqtt client + DEPENDS:=+libubox +libubus +libblobmsg-json +libmosquitto-ssl +endef + +define Package/ucentral-mqtt/install + $(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/init.d $(1)/etc/config/ + $(INSTALL_BIN) $(PKG_BUILD_DIR)/ucentral-mqtt $(1)/usr/sbin/ + $(INSTALL_BIN) ./files/ucentral-mqtt $(1)/etc/init.d/ + $(INSTALL_BIN) ./files/umqtt.config $(1)/etc/config/umqtt + $(INSTALL_BIN) ./files/ucentral_stats.sh $(1)/usr/sbin +endef + +$(eval $(call BuildPackage,ucentral-mqtt)) diff --git a/feeds/ucentral/ucentral-mqtt/files/ucentral-mqtt b/feeds/ucentral/ucentral-mqtt/files/ucentral-mqtt new file mode 100644 index 000000000..b07f30169 --- /dev/null +++ b/feeds/ucentral/ucentral-mqtt/files/ucentral-mqtt @@ -0,0 +1,39 @@ +#!/bin/sh /etc/rc.common + +START=80 + +USE_PROCD=1 +PROG=/usr/sbin/ucentral-mqtt + +service_triggers() { + procd_add_reload_trigger ucentral umqtt +} + +start_service() { + . /lib/functions.sh + + config_load 'ucentral' + config_get serial 'config' 'serial' + config_get venue 'config' 'venue' + + config_load 'umqtt' + config_get username 'mqtt' 'username' + config_get password 'mqtt' 'password' + config_get server 'mqtt' 'server' + config_get port 'mqtt' 'port' + config_get debug 'mqtt' 'debug' 0 + config_get debug 'mqtt' 'enable' 0 + + [ "$enable" -eq 1 ] || return 0 + procd_open_instance + procd_set_param command "$PROG" + [ -n "$serial" ] && procd_append_param command -S $serial + [ -n "$username" ] && procd_append_param command -u $username + [ -n "$password" ] && procd_append_param command -p $password + [ -n "$server" ] && procd_append_param command -s $server + [ -n "$port" ] && procd_append_param command -P $port + [ -n "$venue" ] && procd_append_param command -v $venue + [ "$debug" -eq 0 ] || procd_append_param command -d + procd_set_param respawn + procd_close_instance +} diff --git a/feeds/ucentral/ucentral-mqtt/files/ucentral_stats.sh b/feeds/ucentral/ucentral-mqtt/files/ucentral_stats.sh new file mode 100755 index 000000000..34c03d4f9 --- /dev/null +++ b/feeds/ucentral/ucentral-mqtt/files/ucentral_stats.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +ucode -m ubus -i /usr/share/ucentral/state.uc -E cfg=/etc/ucentral/ucentral.active > /tmp/ucentral.stats + diff --git a/feeds/ucentral/ucentral-mqtt/files/umqtt.config b/feeds/ucentral/ucentral-mqtt/files/umqtt.config new file mode 100644 index 000000000..fd6267177 --- /dev/null +++ b/feeds/ucentral/ucentral-mqtt/files/umqtt.config @@ -0,0 +1,6 @@ +config ucentral mqtt + option enable 0 + option username 'test' + option password 'test' + option server '192.168.178.9' + option port '8883' diff --git a/feeds/ucentral/ucentral-schema/Makefile b/feeds/ucentral/ucentral-schema/Makefile new file mode 100644 index 000000000..183798a21 --- /dev/null +++ b/feeds/ucentral/ucentral-schema/Makefile @@ -0,0 +1,34 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=ucentral-schema +PKG_RELEASE:=1 + +PKG_SOURCE_URL=https://github.com/blogic/ucentral-schema.git +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2021-02-15 +PKG_SOURCE_VERSION:=16d19ac0a02b29828c92479fdba69f0d7a96cb03 + +PKG_MAINTAINER:=John Crispin +PKG_LICENSE:=BSD-3-Clause + +include $(INCLUDE_DIR)/package.mk + +define Package/ucentral-schema + SECTION:=ucentral + CATEGORY:=uCentral + TITLE:=OpenWrt uCentral schema +endef + +define Build/Compile + +endef + +define Package/ucentral-schema/install + $(INSTALL_DIR) $(1)/usr/share/ucentral + $(INSTALL_DATA) $(PKG_BUILD_DIR)/ucentral.schema.json $(1)/usr/share/ucentral + $(INSTALL_DATA) $(PKG_BUILD_DIR)/sys/*.uc $(1)/usr/share/ucentral + $(INSTALL_DATA) $(PKG_BUILD_DIR)/cmd/*.uc $(1)/usr/share/ucentral + $(INSTALL_DATA) $(PKG_BUILD_DIR)/cfg/*.uc $(1)/usr/share/ucentral +endef + +$(eval $(call BuildPackage,ucentral-schema)) diff --git a/feeds/ucentral/ucentral-tools/Makefile b/feeds/ucentral/ucentral-tools/Makefile new file mode 100644 index 000000000..9de1b2a79 --- /dev/null +++ b/feeds/ucentral/ucentral-tools/Makefile @@ -0,0 +1,29 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=ucentral-tools +PKG_RELEASE:=1 + +PKG_SOURCE_URL=https://github.com/blogic/ucentral-tools.git +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2021-01-28 +PKG_SOURCE_VERSION:=f828db9248fe1f25a8065195083e81faaab3bd3e + +PKG_MAINTAINER:=John Crispin +PKG_LICENSE:=BSD-3-Clause + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk + +define Package/ucentral-tools + SECTION:=ucentral + CATEGORY:=uCentral + TITLE:=ucentral tools collection + DEPENDS:=+libubox +libcurl +libradcli +libopenssl +endef + +define Package/ucentral-tools/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/{dhcpdiscover,dnsprobe,firstcontact,radiusprobe,ip-collide} $(1)/usr/sbin/ +endef + +$(eval $(call BuildPackage,ucentral-tools)) diff --git a/feeds/ucentral/ucentral-tools/files/etc/hotplug.d/iface/90-ip-collide b/feeds/ucentral/ucentral-tools/files/etc/hotplug.d/iface/90-ip-collide new file mode 100644 index 000000000..5f0dc48a7 --- /dev/null +++ b/feeds/ucentral/ucentral-tools/files/etc/hotplug.d/iface/90-ip-collide @@ -0,0 +1,4 @@ +[ ifup = "$ACTION" ] && { + ip-collide + [ $? -eq 0 ] || ubus call ucentral send '{"error": "ip/domain collision detected"}' +} diff --git a/feeds/ucentral/ucentral-wifi/Makefile b/feeds/ucentral/ucentral-wifi/Makefile new file mode 100644 index 000000000..8354194b9 --- /dev/null +++ b/feeds/ucentral/ucentral-wifi/Makefile @@ -0,0 +1,34 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=ucentral-wifi +PKG_RELEASE:=1 + +PKG_SOURCE_URL=https://github.com/blogic/ucentral-wifi.git +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2021-02-15 +PKG_SOURCE_VERSION:=34fa9c0fff6e271b7013a2d177513154de7ec105 + +PKG_MAINTAINER:=John Crispin +PKG_LICENSE:=BSD-3-Clause + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk + +define Package/ucentral-wifi + SECTION:=ucentral + CATEGORY:=uCentral + TITLE:=OpenWrt wifi status daemon + DEPENDS:=+libubox +libubus +libnl-tiny +endef + +TARGET_CFLAGS += \ + -I$(STAGING_DIR)/usr/include \ + -I$(STAGING_DIR)/usr/include/libnl-tiny + +define Package/ucentral-wifi/install + $(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/init.d + $(INSTALL_BIN) $(PKG_BUILD_DIR)/ucentral-wifi $(1)/usr/sbin/ + $(INSTALL_BIN) ./files/ucentral-wifi $(1)/etc/init.d/ +endef + +$(eval $(call BuildPackage,ucentral-wifi)) diff --git a/feeds/ucentral/ucentral-wifi/files/ucentral-wifi b/feeds/ucentral/ucentral-wifi/files/ucentral-wifi new file mode 100644 index 000000000..36959c17b --- /dev/null +++ b/feeds/ucentral/ucentral-wifi/files/ucentral-wifi @@ -0,0 +1,13 @@ +#!/bin/sh /etc/rc.common + +START=80 + +USE_PROCD=1 +PROG=/usr/sbin/ucentral-wifi + +start_service() { + procd_open_instance + procd_set_param command "$PROG" + procd_set_param respawn + procd_close_instance +} diff --git a/feeds/ucentral/ucentral-wifi/git-src b/feeds/ucentral/ucentral-wifi/git-src new file mode 120000 index 000000000..472c95277 --- /dev/null +++ b/feeds/ucentral/ucentral-wifi/git-src @@ -0,0 +1 @@ +/ucentral/ucentral-wifi/.git \ No newline at end of file diff --git a/feeds/ucentral/ucentralgw/Makefile b/feeds/ucentral/ucentralgw/Makefile new file mode 100644 index 000000000..6a15ea42e --- /dev/null +++ b/feeds/ucentral/ucentralgw/Makefile @@ -0,0 +1,43 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=ucentralgw +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL=git@github.com:stephb9959/ucentralgw.git +PKG_SOURCE_DATE:=2021-03-22 +PKG_SOURCE_VERSION:=d4ae407d8b2fabc6ea4ba555061adf3e11025188 +#PKG_MIRROR_HASH:=3f6569a5e63fdfd032976ac0f79d736d3935101ac1b97fb370514b013c5e6bb6 +CMAKE_INSTALL:=1 + +PKG_LICENSE:=BSD-3-Clause +PKG_MAINTAINER:=John Crispin + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk + +HOST_BUILD_PREFIX:=$(STAGING_DIR_HOST) + +define Package/ucentralgw + SECTION:=ucentral + CATEGORY:=uCentral + DEPENDS:=+libstdcpp +poco-all +boost +boost-system +libyaml-cpp +zlib + TITLE:= uCentral Gateway +endef + +CMAKE_OPTIONS += \ + -DSMALL_BUILD=1 + +ifeq ($(ARCH),aarch64) + CMAKE_OPTIONS+=-DCMAKE_SYSTEM_PROCESSOR=aarch64 +endif + +define Package/ucentralgw/install + $(INSTALL_DIR) $(1)/usr/bin $(1)/usr/libexec/ucentral/ + + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/ucentral $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/cert_scripts/* $(1)/usr/libexec/ucentral/ + $(CP) ./files/* $(1) +endef + +$(eval $(call BuildPackage,ucentralgw)) diff --git a/feeds/ucentral/ucentralgw/files/etc/init.d/ucentralgw b/feeds/ucentral/ucentralgw/files/etc/init.d/ucentralgw new file mode 100755 index 000000000..e70f37291 --- /dev/null +++ b/feeds/ucentral/ucentralgw/files/etc/init.d/ucentralgw @@ -0,0 +1,14 @@ +#!/bin/sh /etc/rc.common + +START=80 + +USE_PROCD=1 +PROG=/usr/bin/ucentral + +start_service() { + procd_open_instance + procd_set_param command "$PROG" + procd_append_param command --file /etc/ucentral/ucentral.properties + procd_set_param respawn 3600 5 0 + procd_close_instance +} diff --git a/feeds/ucentral/ucentralgw/files/etc/ucentral/ucentral.properties b/feeds/ucentral/ucentralgw/files/etc/ucentral/ucentral.properties new file mode 100644 index 000000000..dfb8fc7f1 --- /dev/null +++ b/feeds/ucentral/ucentralgw/files/etc/ucentral/ucentral.properties @@ -0,0 +1,155 @@ +######################################################################## +######################################################################## +######################################################################## +######################################################################## +# +# TIP Portal API access. To be ignored in non TIP uCentral deployments +# +######################################################################## +######################################################################## +######################################################################## +tip.certs.key = /etc/ucentral/certs/clientkey.pem +tip.certs.cert = /etc/ucentral/certs/clientcert.pem +tip.certs.ca = /etc/ucentral/certs/clientcert.pem +tip.certs.password = mypassword +tip.api.login.username = support@example.com +tip.api.login.password = support +tip.api.host = debfarm1-node-a1.arilia.com +tip.api.port = 9051 +tip.gateway.host.0.address = * +tip.gateway.host.0.port = 9031 +tip.gateway.host.0.key = /etc/ucentral/certs/ws-key.pem +tip.gateway.host.0.cert = /etc/ucentral/certs/ws-cert.pem +tip.gateway.host.0.password = mypassword +# +# uCentral - TIP Gateway Bridge +# +ucentral.tipgateway.host.0.address = * +ucentral.tipgateway.host.0.port = 14001 +ucentral.tipgateway.host.0.cert = /etc/ucentral/certs/server-cert.pem +ucentral.tipgateway.host.0.key = /etc/ucentral/certs/server-key.pem +ucentral.tipgateway.host.0.key.password = mypassword +######################################################################## +######################################################################## +######################################################################## + +######################################################################## +######################################################################## +# +# Thw following sections apply to the uCentral service +# +# Logging: please leave as is for now. +# +######################################################################## +######################################################################## + +logging.formatters.f1.class = PatternFormatter +logging.formatters.f1.pattern = %s: [%p] %t +logging.formatters.f1.times = UTC +logging.channels.c1.class = ConsoleChannel +logging.channels.c1.formatter = f1 +logging.channels.c2.class = FileChannel +# This is where the logs will be written. This path MUST exist +logging.channels.c2.path = /tmp/ucentral.log +logging.channels.c2.formatter.class = PatternFormatter +logging.channels.c2.formatter.pattern = %Y-%m-%d %H:%M:%S %s: [%p] %t +logging.channels.c3.class = ConsoleChannel +logging.channels.c3.pattern = %s: [%p] %t +# External Channel +logging.loggers.root.channel = c2 +logging.loggers.root.level = information +# Inline Channel with PatternFormatter +# logging.loggers.l1.name = logger1 +# logging.loggers.l1.channel.class = ConsoleChannel +# logging.loggers.l1.channel.pattern = %s: [%p] %t +# logging.loggers.l1.level = information +# SplitterChannel +# logging.channels.splitter.class = SplitterChannel +# logging.channels.splitter.channels = l1,l2 +# logging.loggers.l2.name = logger2 +# logging.loggers.l2.channel = splitter +openSSL.client.privateKeyFile = /etc/ucentral/certs/clientkey.pem +openSSL.client.certificateFile = /etc/ucentral/certs/clientcert.pem +openSSL.client.caConfig = /etc/ucentral/certs/cacert.pem +openSSL.client.verificationMode = once +openSSL.client.verificationDepth = 9 +openSSL.client.loadDefaultCAFile = true +openSSL.client.cypherList = ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH +openSSL.client.privateKeyPassphraseHandler.name = KeyFileHandler +openSSL.client.privateKeyPassphraseHandler.options.password = mypassword +openSSL.client.invalidCertificateHandler = AcceptCertificateHandler +openSSL.client.invalidCertificateHandler.options.ignoreError = true +openSSL.client.extendedVerification = false +openSSL.client.cacheSessions = true +openSSL.client.requireTLSv1 = true + +# +# uCentral protocol server for devices. This is where you point +# all your devices. +# +ucentral.websocket.host.0.address = * +ucentral.websocket.host.0.port = 15002 +ucentral.websocket.host.0.cert = /etc/ucentral/certs/server-cert.pem +ucentral.websocket.host.0.key = /etc/ucentral/certs/server-key.pem +ucentral.websocket.host.0.key.password = mypassword +ucentral.websocket.maxreactors = 5 + +# +# REST API access +# +ucentral.restapi.host.0.address = * +ucentral.restapi.host.0.port = 16001 +ucentral.restapi.host.0.cert = /etc/ucentral/certs/server-cert.pem +ucentral.restapi.host.0.key = /etc/ucentral/certs/server-key.pem +ucentral.restapi.host.0.key.password = mypassword + +# +# This section descrive how to do autoprovisioning +# When enabled, it will allow devices that are not in the system +# to be managed and serviced +# +ucentral.autoprovisioning = true +ucentral.autoprovisioning.type.0 = AP:ea8300,edge +ucentral.autoprovisioning.type.1 = IOT:ea8301,edge2 +ucentral.autoprovisioning.type.2 = AP:ea8302,edge6 + + +# +# This section select which form of persistence you need +# Only one selected at a time. If you select multiple, this service will die if a horrible +# death and might make your beer flat. +# +storage.type = sqlite +#storage.type = postgresql +#storage.type = mysql +#storage.type = odbc + +storage.type.sqlite.db = /etc/ucentral/devices.db +storage.type.sqlite.idletime = 120 +storage.type.sqlite.maxsessions = 128 + +storage.type.postgresql.maxsessions = 64 +storage.type.postgresql.idletime = 60 +storage.type.postgresql.host = localhost +storage.type.postgresql.username = stephb +storage.type.postgresql.password = snoopy99 +storage.type.postgresql.database = ucentral +storage.type.postgresql.port = 5432 +storage.type.postgresql.connectiontimeout = 60 + +storage.type.mysql.maxsessions = 64 +storage.type.mysql.idletime = 60 +storage.type.mysql.host = localhost +storage.type.mysql.username = stephb +storage.type.mysql.password = snoopy99 +storage.type.mysql.database = ucentral +storage.type.mysql.port = 3306 +storage.type.mysql.connectiontimeout = 60 + +# +# Authentication +# +authentication.enabled = true +authentication.default.username = support@example.com +authentication.default.password = support +authentication.service.type = internal diff --git a/feeds/ucentral/ucentralgw/patches/100-cmake.patch b/feeds/ucentral/ucentralgw/patches/100-cmake.patch new file mode 100644 index 000000000..9c314547b --- /dev/null +++ b/feeds/ucentral/ucentralgw/patches/100-cmake.patch @@ -0,0 +1,22 @@ +Index: ucentralgw-2021-03-22-220dd3aa/CMakeLists.txt +=================================================================== +--- ucentralgw-2021-03-22-220dd3aa.orig/CMakeLists.txt ++++ ucentralgw-2021-03-22-220dd3aa/CMakeLists.txt +@@ -54,6 +54,10 @@ add_executable( ucentral + src/RESTAPI_default_configuration.h src/RESTAPI_default_configurations.cpp src/RESTAPI_default_configurations.h src/RESTAPI_commands.cpp + src/RESTAPI_commands.h src/uCommandManager.cpp src/uCommandManager.h src/RESTAPI_command.cpp src/RESTAPI_command.h) + ++INSTALL(TARGETS ucentral ++ RUNTIME DESTINATION /usr/bin ++) ++ + if(SMALL_BUILD) + target_link_libraries(ucentral PRIVATE yaml-cpp + ${Poco_LIBRARIES} ${Boost_LIBRARIES} ${ZLIB_LIBRARIES}) +@@ -61,4 +65,4 @@ else() + target_link_libraries(ucentral PRIVATE yaml-cpp + ${Poco_LIBRARIES} ${Boost_LIBRARIES} ${PostgreSQL_LIBRARIES} + ${MySQL_LIBRARIES} ${ODBC_LIBRARIES} ${ZLIB_LIBRARIES}) +-endif() +\ No newline at end of file ++endif() diff --git a/feeds/ucentral/ucode/Makefile b/feeds/ucentral/ucode/Makefile new file mode 100644 index 000000000..d5ad9c4bc --- /dev/null +++ b/feeds/ucentral/ucode/Makefile @@ -0,0 +1,121 @@ +# +# Copyright (C) 2020 Jo-Philipp Wich +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=ucode +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL=https://github.com/jow-/ucode.git +PKG_SOURCE_DATE:=2021-03-15 +PKG_SOURCE_VERSION:=091ae1b198e019430f342ae1444c68d6517e077e +PKG_MIRROR_HASH:= +PKG_MAINTAINER:=Jo-Philipp Wich +PKG_LICENSE:=ISC + +PKG_ASLR_PIE_REGULAR:=1 +PKG_BUILD_DEPENDS = ustream-ssl +PKG_CONFIG_DEPENDS:= CONFIG_ucode_lua + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk +include $(INCLUDE_DIR)/version.mk + +define Package/ucode/default + SECTION:=utils + CATEGORY:=Utilities + TITLE:=ucode - Tiny template language +endef + +define Package/ucode + $(Package/ucode/default) + DEPENDS:=+libjson-c +endef + +define Package/ucode/description + ucode is a tiny script interpreter featuring an ECMAScript oriented + script language and Jinja-inspired templating. +endef + + +define Package/ucode-mod-fs + $(Package/ucode/default) + TITLE+= (filesystem module) + DEPENDS:=ucode +endef + +define Package/ucode-mod-fs/description + The filesystem plugin module allows interaction with the local file system. +endef + + +define Package/ucode-mod-math + $(Package/ucode/default) + TITLE+= (math module) + DEPENDS:=ucode +endef + +define Package/ucode-mod-math/description + The math plugin provides access to various procedures. +endef + + +define Package/ucode-mod-ubus + $(Package/ucode/default) + TITLE+= (ubus module) + DEPENDS:=ucode +libubus +libblobmsg-json +endef + +define Package/ucode-mod-ubus/description + The ubus module allows ucode template scripts to enumerate and invoke ubus + procedures. +endef + + +define Package/ucode-mod-uci + $(Package/ucode/default) + TITLE+= (uci module) + DEPENDS:=ucode +libuci +endef + +define Package/ucode-mod-uci/description + The uci module allows templates to read and modify uci configuration. +endef + + +define Package/ucode/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/ucode $(1)/usr/bin/ucode +endef + +define Package/ucode-mod-fs/install + $(INSTALL_DIR) $(1)/usr/lib/ucode + $(INSTALL_BIN) $(PKG_BUILD_DIR)/lib/fs.so $(1)/usr/lib/ucode/ +endef + +define Package/ucode-mod-math/install + $(INSTALL_DIR) $(1)/usr/lib/ucode + $(INSTALL_BIN) $(PKG_BUILD_DIR)/lib/math.so $(1)/usr/lib/ucode/ +endef + +define Package/ucode-mod-ubus/install + $(INSTALL_DIR) $(1)/usr/lib/ucode + $(INSTALL_BIN) $(PKG_BUILD_DIR)/lib/ubus.so $(1)/usr/lib/ucode/ +endef + +define Package/ucode-mod-uci/install + $(INSTALL_DIR) $(1)/usr/lib/ucode + $(INSTALL_BIN) $(PKG_BUILD_DIR)/lib/uci.so $(1)/usr/lib/ucode/ +endef + + +$(eval $(call BuildPackage,ucode)) +$(eval $(call BuildPackage,ucode-mod-fs)) +$(eval $(call BuildPackage,ucode-mod-math)) +$(eval $(call BuildPackage,ucode-mod-ubus)) +$(eval $(call BuildPackage,ucode-mod-uci)) diff --git a/feeds/ucentral/ucode/patches/000-fix.patch b/feeds/ucentral/ucode/patches/000-fix.patch new file mode 100644 index 000000000..b681c446f --- /dev/null +++ b/feeds/ucentral/ucode/patches/000-fix.patch @@ -0,0 +1,13 @@ +diff --git a/lib/uci.c b/lib/uci.c +index 86bf247..3906b6b 100644 +--- a/lib/uci.c ++++ b/lib/uci.c +@@ -706,7 +706,7 @@ uc_uci_pkg_command(struct uc_state *s, uint32_t off, struct json_object *args, e + struct uci_element *e, *tmp; + struct uci_package *p; + struct uci_ptr ptr = {}; +- int rv, res = UCI_OK; ++ int rv = 0, res = UCI_OK; + + if (cmd != CMD_REVERT && conf) + err_return(UCI_ERR_INVAL); diff --git a/feeds/ucentral/udevmand/Makefile b/feeds/ucentral/udevmand/Makefile new file mode 100644 index 000000000..13e8e2512 --- /dev/null +++ b/feeds/ucentral/udevmand/Makefile @@ -0,0 +1,37 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=udevmand +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL=https://github.com/blogic/udevmand.git +PKG_SOURCE_DATE:=20200623 +PKG_SOURCE_VERSION:=7f0726ba03fff9d02c0d7f3a98b016ed6e93ef8f +CMAKE_INSTALL:=1 + +PKG_LICENSE:=LGPL-2.1 +PKG_LICENSE_FILES:= + +PKG_MAINTAINER:=John Crispin + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk + +define Package/udevmand + SECTION:=ucentral + CATEGORY:=uCentral + DEPENDS:=+libubus +libblobmsg-json +ubusd +libjson-c +libnl-tiny +libuci + TITLE:=Network devman mapping daemon +endef + +TARGET_CFLAGS += \ + -I$(STAGING_DIR)/usr/include \ + -I$(STAGING_DIR)/usr/include/libnl-tiny + +define Package/udevmand/install + $(INSTALL_DIR) $(1)/usr/sbin + $(CP) ./files/* $(1)/ + $(CP) $(PKG_INSTALL_DIR)/usr/sbin/udevmand $(1)/usr/sbin/ +endef + +$(eval $(call BuildPackage,udevmand)) diff --git a/feeds/ucentral/udevmand/files/etc/init.d/udevmand b/feeds/ucentral/udevmand/files/etc/init.d/udevmand new file mode 100755 index 000000000..83ff50d1b --- /dev/null +++ b/feeds/ucentral/udevmand/files/etc/init.d/udevmand @@ -0,0 +1,11 @@ +#!/bin/sh /etc/rc.common +START=80 + +USE_PROCD=1 +PROG=/usr/sbin/udevmand + +start_service() { + procd_open_instance + procd_set_param command "$PROG" + procd_close_instance +} diff --git a/feeds/ucentral/udevmand/git-src b/feeds/ucentral/udevmand/git-src new file mode 120000 index 000000000..d7b9f63c5 --- /dev/null +++ b/feeds/ucentral/udevmand/git-src @@ -0,0 +1 @@ +/projects/udevmand/.git/ \ No newline at end of file diff --git a/feeds/ucentral/usteer/Makefile b/feeds/ucentral/usteer/Makefile new file mode 100644 index 000000000..9ab8fff73 --- /dev/null +++ b/feeds/ucentral/usteer/Makefile @@ -0,0 +1,33 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=usteer +PKG_RELEASE:=1 + +PKG_SOURCE_URL=https://github.com/blogic/usteer.git +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2022-11-19 +PKG_SOURCE_VERSION:=d10731f8060d3937ef562858f5a52ca7f910da31 + +PKG_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk + +define Package/usteer + SECTION:=net + CATEGORY:=Network + DEPENDS:=+libubox +libubus +libblobmsg-json +libnl-tiny +libpcap + TITLE:=OpenWrt AP roaming assist daemon +endef + +define Package/usteer/conffiles +/etc/config/usteer +endef + +define Package/usteer/install + $(INSTALL_DIR) $(1)/sbin $(1)/etc/init.d $(1)/etc/config + $(CP) ./files/* $(1)/ + $(CP) $(PKG_BUILD_DIR)/{usteerd,ap-monitor} $(1)/sbin/ +endef + +$(eval $(call BuildPackage,usteer)) diff --git a/feeds/ucentral/usteer/files/etc/config/usteer b/feeds/ucentral/usteer/files/etc/config/usteer new file mode 100644 index 000000000..9be3d85ac --- /dev/null +++ b/feeds/ucentral/usteer/files/etc/config/usteer @@ -0,0 +1,4 @@ +config usteer + option 'network' 'lan' + option 'syslog' '1' + option 'debug_level' '2' diff --git a/feeds/ucentral/usteer/files/etc/init.d/usteer b/feeds/ucentral/usteer/files/etc/init.d/usteer new file mode 100755 index 000000000..a3eec2b5b --- /dev/null +++ b/feeds/ucentral/usteer/files/etc/init.d/usteer @@ -0,0 +1,120 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2013 OpenWrt.org + +START=50 +USE_PROCD=1 + +NAME=usteer +PROG=/sbin/usteerd + +. /lib/functions/network.sh +. /usr/share/libubox/jshn.sh +. /lib/functions.sh + +load_ifaces() { + local network="$(uci get usteer.@usteer[-1].network)" + for n in $network; do + local device + json_load "$(ifstatus $n)" + json_get_var device l3_device + echo -n "$device " + done +} + +uci_option_to_json_bool() { + local cfg="$1" + local option="$2" + local val + + config_get_bool val "$cfg" $option + [ -n "$val" ] && json_add_boolean $option $val +} + +uci_option_to_json_string() { + local cfg="$1" + local option="$2" + local val + + config_get val "$cfg" "$option" + [ -n "$val" ] && json_add_string $option "$val" +} + +uci_option_to_json() { + local cfg="$1" + local option="$2" + local val + + config_get val "$cfg" $option + [ -n "$val" ] && json_add_int $option $val +} + +uci_usteer() { + local cfg="$1" + + uci_option_to_json_bool "$cfg" syslog + uci_option_to_json_bool "$cfg" load_kick_enabled + uci_option_to_json_string "$cfg" node_up_script + + for opt in \ + debug_level \ + sta_block_timeout local_sta_timeout local_sta_update \ + max_retry_band seen_policy_timeout \ + load_balancing_threshold band_steering_threshold \ + remote_update_interval \ + min_connect_snr min_snr signal_diff_threshold \ + initial_connect_delay \ + roam_kick_delay roam_scan_tries \ + roam_scan_snr roam_scan_interval \ + roam_trigger_snr roam_trigger_interval \ + load_kick_threshold load_kick_delay load_kick_min_clients \ + load_kick_reason_code + do + uci_option_to_json "$cfg" "$opt" + done +} + + +load_config() { + [ "$ENABLED" -gt 0 ] || return + + ubus -t 10 wait_for usteer + + json_init + json_add_array interfaces + for i in $(load_ifaces); do + json_add_string "" "$i" + done + json_close_array + + config_load usteer + config_foreach uci_usteer usteer + + ubus call usteer set_config "$(json_dump)" +} + +reload_service() { + start + load_config +} + +service_started() { + load_config +} + +service_triggers() { + procd_add_reload_trigger usteer + procd_add_raw_trigger "interface.*" 2000 /etc/init.d/usteer reload +} + +start_service() +{ + local network="$(uci -q get usteer.@usteer[-1].network)" + ENABLED="$(uci -q get usteer.@usteer[-1].enabled)" + ENABLED="${ENABLED:-1}" + + [ "$ENABLED" -gt 0 ] || return + + procd_open_instance + procd_set_param command "$PROG" + procd_close_instance +} diff --git a/feeds/wifi-ax/ath11k-firmware/Makefile b/feeds/wifi-ax/ath11k-firmware/Makefile new file mode 100644 index 000000000..bb77ad917 --- /dev/null +++ b/feeds/wifi-ax/ath11k-firmware/Makefile @@ -0,0 +1,71 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=ath11k-firmware +PKG_VERSION:=19 + +PKG_MAINTAINER:=John Crispin + +include $(INCLUDE_DIR)/package.mk + +define Package/ath11k-firmware-default + SECTION:=firmware + CATEGORY:=Firmware + URL:=$(PKG_SOURCE_URL) + DEPENDS:= +endef + +define Package/ath11k-firmware-ipq60xx +$(Package/ath11k-firmware-default) + TITLE:=ath11k firmware for IPQ60xx devices + DEPENDS:=@TARGET_ipq807x_ipq60xx +endef + +define Package/ath11k-firmware-ipq807x +$(Package/ath11k-firmware-default) + TITLE:=ath11k firmware for IPQ807x devices + DEPENDS:=@TARGET_ipq807x_ipq807x +endef + +define Package/ath11k-firmware-qcn9000 +$(Package/ath11k-firmware-default) + TITLE:=ath11k firmware for QCN9000 devices + DEPENDS:=@TARGET_ipq807x +endef + +define Package/ath11k-firmware-ipq60xx/description +Standard ath11k firmware for IPQ60xx from QCA +endef + +define Package/ath11k-firmware-ipq807x/description +Standard ath11k firmware for IPQ807x from QCA +endef + +define Package/ath11k-firmware-qcn9000/description +Standard ath11k firmware for QCN9000 from QCA +endef + +define Build/Compile + +endef + +define Package/ath11k-firmware-ipq60xx/install + $(INSTALL_DIR) $(1)/lib/firmware/IPQ6018 + $(INSTALL_DATA) ./files/IPQ6018/* \ + $(1)/lib/firmware/IPQ6018/ +endef + +define Package/ath11k-firmware-ipq807x/install + $(INSTALL_DIR) $(1)/lib/firmware/IPQ8074 + $(INSTALL_DATA) ./files/IPQ8074/* \ + $(1)/lib/firmware/IPQ8074 +endef + +define Package/ath11k-firmware-qcn9000/install + $(INSTALL_DIR) $(1)/lib/firmware/qcn9000 + $(INSTALL_DATA) ./files/QCN9000/* \ + $(1)/lib/firmware/qcn9000 +endef + +$(eval $(call BuildPackage,ath11k-firmware-ipq60xx)) +$(eval $(call BuildPackage,ath11k-firmware-ipq807x)) +$(eval $(call BuildPackage,ath11k-firmware-qcn9000)) diff --git a/feeds/wifi-ax/ath11k-firmware/files/IPQ6018/Notice.txt b/feeds/wifi-ax/ath11k-firmware/files/IPQ6018/Notice.txt new file mode 100644 index 000000000..665d813b7 --- /dev/null +++ b/feeds/wifi-ax/ath11k-firmware/files/IPQ6018/Notice.txt @@ -0,0 +1,795 @@ +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. + +-------------------- + + /* + * WPA definitions shared between hostapd and wpa_supplicant + * Copyright (c) 2002-2018, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +-------------------- + + /* WPA/RSN - Shared functions for supplicant and authenticator + * EAP common peer/server definitions + * EAP peer state machines (RFC 4137) + * Copyright (c) 2002-2018, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +-------------------- + +/* + * Copyright (c) 2011 Qualcomm Atheros, Inc. + * All Rights Reserved. + * Qualcomm Atheros Confidential and Proprietary. + * Notifications and licenses are retained for attribution purposes only. + */ +/* + * For this file, which was received with alternative licensing options for + * distribution, Qualcomm Atheros, Inc. has selected the BSD license. + */ + +/* + * AES-based functions + * + * + * - AES Key Wrap Algorithm (128-bit KEK) (RFC3394) + * - One-Key CBC MAC (OMAC1) hash with AES-128 + * - AES-128 CTR mode encryption + * - AES-128 EAX mode encryption/decryption + * - AES-128 CBC + * + * Copyright (c) 2003-2005, Jouni Malinen + * + * 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. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +-------------------- + +/* + * Copyright (c) 2011 Qualcomm Atheros, Inc. + * All Rights Reserved. + * Qualcomm Atheros Confidential and Proprietary. + * Notifications and licenses are retained for attribution purposes only. + */ +/* + * For this file, which was received with alternative licensing options for + * distribution, Qualcomm Atheros, Inc. has selected the BSD license. + */ + +/* + * SHA1 hash implementation and interface functions + * Copyright (c) 2003-2005, Jouni Malinen + * + * 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. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +-------------------- + +/* + * Copyright (c) 2011 Qualcomm Atheros, Inc. + * All Rights Reserved. + * Qualcomm Atheros Confidential and Proprietary. + * Notifications and licenses are retained for attribution purposes only. + */ +/* + * For this file, which was received with alternative licensing options for + * distribution, Qualcomm Atheros, Inc. has selected the BSD license. + */ + +/* + * WPA Supplicant / wrapper functions for crypto libraries + * Copyright (c) 2004-2005, Jouni Malinen + * + * 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. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + * + * This file defines the cryptographic functions that need to be implemented + * for wpa_supplicant and hostapd. When TLS is not used, internal + * implementation of MD5, SHA1, and AES is used and no external libraries are + * required. When TLS is enabled (e.g., by enabling EAP-TLS or EAP-PEAP), the + * crypto library used by the TLS implementation is expected to be used for + * non-TLS needs, too, in order to save space by not implementing these + * functions twice. + * + * Wrapper code for using each crypto library is in its own file (crypto*.c) + * and one of these files is build and linked in to provide the functions + * defined here. + */ + +-------------------- + +/* + * For this file, which was received with alternative licensing options for + * distribution, Qualcomm Atheros, Inc. has selected the BSD license. + */ + +/* + * WPA Supplicant - Common definitions + * Copyright (c) 2004-2005, Jouni Malinen + * + * 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. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +-------------------- + +/* + * For this file, which was received with alternative licensing options for + * distribution, Qualcomm Atheros, Inc. has selected the BSD license. + */ + +/* + * WPA Supplicant - WPA state machine and EAPOL-Key processing + * Copyright (c) 2003-2005, Jouni Malinen + * + * 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. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +-------------------- + +/* + * For this file, which was received with alternative licensing options for + * distribution, Qualcomm Atheros, Inc. has selected the BSD license. + */ + +/* + * WPA Supplicant / Configuration file structures + * Copyright (c) 2003-2005, Jouni Malinen + * + * 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. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +-------------------- + + /* + * Copyright (c) 2008, Atheros Communications Inc. + * + * Copyright (c) 2011 Qualcomm Atheros, Inc. + * Qualcomm Atheros, Inc. has chosen to take madwifi subject to the BSD license and terms. + * + */ + +-------------------- + +/* + * For this file, which was received with alternative licensing options for + * distribution, Qualcomm Atheros, Inc. has selected the BSD license. + */ + +/* + * wpa_supplicant - Internal WPA state machine definitions + * Copyright (c) 2004-2005, Jouni Malinen + * + * 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. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +-------------------- + +/* + * For this file, which was received with alternative licensing options for + * distribution, Qualcomm Atheros, Inc. has selected the BSD license. + */ + +/* + * wpa_supplicant - WPA definitions + * Copyright (c) 2003-2005, Jouni Malinen + * + * 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. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +-------------------- + +/* + * For this file, which was received with alternative licensing options for + * distribution, Qualcomm Atheros, Inc. has selected the BSD license. + */ + +/* + * wpa_supplicant/hostapd / common helper functions, etc. + * Copyright (c) 2002-2005, Jouni Malinen + * + * 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. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +-------------------- + + * Australian Public Licence B (OZPLB) + * + * Version 1-0 + * + * Copyright (c) 2004, National ICT Australia + * Copyright (c) 2007, Open Kernel Labs, Inc. + * + * All rights reserved. + * + * Developed by: Embedded, Real-time and Operating Systems Program (ERTOS) + * National ICT Australia + * http://www.ertos.nicta.com.au + * + * Permission is granted by National ICT Australia, free of charge, to + * any person obtaining a copy of this software and any associated + * documentation files (the "Software") to deal with the Software without + * restriction, including (without limitation) the rights to use, copy, + * modify, adapt, merge, publish, distribute, communicate to the public, + * sublicense, and/or sell, lend or rent out copies of the Software, and + * to permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimers. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimers in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of National ICT Australia, nor the names of its + * contributors, may be used to endorse or promote products derived + * from this Software without specific prior written permission. + * + * EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT + * PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND + * NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS, + * WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS + * REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE, + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, + * THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF + * ERRORS, WHETHER OR NOT DISCOVERABLE. + * + * TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL + * NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL + * THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER + * LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR + * OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS + * OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR + * OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT, + * CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN + * CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER + * DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS + * CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS, + * DAMAGES OR OTHER LIABILITY. + * + * If applicable legislation implies representations, warranties, or + * conditions, or imposes obligations or liability on National ICT + * Australia or one of its contributors in respect of the Software that + * cannot be wholly or partly excluded, restricted or modified, the + * liability of National ICT Australia or the contributor is limited, to + * the full extent permitted by the applicable legislation, at its + * option, to: + * a. in the case of goods, any one or more of the following: + * i. the replacement of the goods or the supply of equivalent goods; + * ii. the repair of the goods; + * iii. the payment of the cost of replacing the goods or of acquiring + * equivalent goods; + * iv. the payment of the cost of having the goods repaired; or + * b. in the case of services: + * i. the supplying of the services again; or + * ii. the payment of the cost of having the services supplied again. + * + * The construction, validity and performance of this licence is governed + * by the laws in force in New South Wales, Australia. + +-------------------- + + * Copyright (c) 2002-2004, Karlsruhe University + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + +-------------------- + + /* + * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or + * code or tables extracted from it, as desired without restriction. + * + * First, the polynomial itself and its table of feedback terms. The + * polynomial is + * X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 + * + * Note that we take it "backwards" and put the highest-order term in + * the lowest-order bit. The X^32 term is "implied"; the LSB is the + * X^31 term, etc. The X^0 term (usually shown as "+1") results in + * the MSB being 1 + * + * Note that the usual hardware shift register implementation, which + * is what we're using (we're merely optimizing it by doing eight-bit + * chunks at a time) shifts bits into the lowest-order term. In our + * implementation, that means shifting towards the right. Why do we + * do it this way? Because the calculated CRC must be transmitted in + * order from highest-order term to lowest-order term. UARTs transmit + * characters in order from LSB to MSB. By storing the CRC this way + * we hand it to the UART in the order low-byte to high-byte; the UART + * sends each low-bit to hight-bit; and the result is transmission bit + * by bit from highest- to lowest-order term without requiring any bit + * shuffling on our part. Reception works similarly + * + * The feedback terms table consists of 256, 32-bit entries. Notes + * + * The table can be generated at runtime if desired; code to do so + * is shown later. It might not be obvious, but the feedback + * terms simply represent the results of eight shift/xor opera + * tions for all combinations of data and CRC register values + * + * The values must be right-shifted by eight bits by the "updcrc + * logic; the shift must be unsigned (bring in zeroes). On some + * hardware you could probably optimize the shift in assembler by + * using byte-swap instructions + * polynomial $edb88320 + * + * + * CRC32 code derived from work by Gary S. Brown. + */ + +-------------------- + + * AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/ + * + * Copyright (c) 2000-2001, Aaron D. Gifford + * 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. Neither the name of the copyright holder nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``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 AUTHOR OR CONTRIBUTOR(S) 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. + +-------------------- + + * Copyright (c) 1988, 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. + +-------------------- + + * Copyright (c) 1982, 1986, 1990, 1991, 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. 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. + +-------------------- + +# Copyright (c) 2012-2015 Qualcomm Atheros, Inc. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +-------------------- + + * Copyright (c) 1988, 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. + +-------------------- + +/* $OpenBSD: string.h,v 1.17 2006/01/06 18:53:04 millert Exp $ */ +/* $NetBSD: string.h,v 1.6 1994/10/26 00:56:30 cgd Exp $ */ + +/*- + * Copyright (c) 1990 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. 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. + * + * @(#)string.h 5.10 (Berkeley) 3/9/91 + */ + +-------------------- + + // Copyright (c) 1991, 1993 + // The Regents of the University of California. All rights reserved. + // $ATH_LICENSE_NULL$ + // + // 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. + +-------------------- + + * Copyright (c) 1998, 2010 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +-------------------- + +/* + * Copyright (c) 1998 Todd C. Miller + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 AUTHOR 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. + */ + +-------------------- + +** Copyright (c) 2004-2010, Atheros Communications Inc. +** +** Permission to use, copy, modify, and/or distribute this software for any +** purpose with or without fee is hereby granted, provided that the above +** copyright notice and this permission notice appear in all copies. +** +** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +** WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +** MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +** ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +** WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 module is the Atheros specific ioctl/iwconfig/iwpriv interface +** to the ATH object, normally instantiated as wifiX, where X is the +** instance number (e.g. wifi0, wifi1). +** +** This provides a mechanism to configure the ATH object within the +** Linux OS enviornment. This file is OS specific. + +-------------------- + +/* + * Copyright (c) 2012 Qualcomm Atheros, Inc. + * All Rights Reserved. + * Qualcomm Atheros Confidential and Proprietary. + */ + +/* + * For this file, which was received with alternative licensing options for + * distribution, Qualcomm Atheros, Inc. has selected the BSD license. + */ + +//- +// Copyright (c) 2002-2004 Sam Leffler, Errno Consulting +// All rights reserved. +// $ATH_LICENSE_NULL$ +// +// 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, +// without modification. +// 2. Redistributions in binary form must reproduce at minimum a disclaimer +// similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any +// redistribution must be conditioned upon including a substantially +// similar Disclaimer requirement for further binary redistribution. +// 3. Neither the names of the above-listed copyright holders nor the names +// of any contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// Alternatively, this software may be distributed under the terms of the +// GNU General Public License ("GPL") version 2 as published by the Free +// Software Foundation. +// +// NO WARRANTY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY +// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES. + +-------------------- + + /* + * AES SIV (RFC 5297) + * Copyright (c) 2013 Cozybit, Inc. + * + * This software may be distributed under the terms of the BSD license. + */ + +-------------------- + + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + +-------------------- + +/* ===== start - public domain SHA256 implementation ===== */ + +/* This is based on SHA256 implementation in LibTomCrypt that was released into + * public domain by Tom St Denis. */ + +-------------------- + +// This code implements the MD5 message-digest algorithm. +// The algorithm is due to Ron Rivest. This code was +// written by Colin Plumb in 1993, no copyright is claimed. +// This code is in the public domain; do with it what you wish. +// +// Equivalent code is available from RSA Data Security, Inc. +// This code has been tested against that, and is equivalent, +// except that you don't need to include two pages of legalese +// with every copy. +// + +-------------------- diff --git a/feeds/wifi-ax/ath11k-firmware/files/IPQ6018/m3_fw.b00 b/feeds/wifi-ax/ath11k-firmware/files/IPQ6018/m3_fw.b00 new file mode 100644 index 0000000000000000000000000000000000000000..b000539b79c8220d5563324a73cae0233d3b21e6 GIT binary patch literal 148 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 literal 0 HcmV?d00001 diff --git a/feeds/wifi-ax/ath11k-firmware/files/IPQ6018/m3_fw.b02 b/feeds/wifi-ax/ath11k-firmware/files/IPQ6018/m3_fw.b02 new file mode 100644 index 0000000000000000000000000000000000000000..0f307492db7b34d9738bcd17941d095ef55da18a GIT binary patch literal 294912 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

    f6 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

    &pFW%Kcl){ch#{MR?+?cT>7sUG#ekezBrf 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 literal 0 HcmV?d00001 diff --git a/feeds/wifi-ax/ath11k-firmware/files/IPQ6018/q6_fw.b02 b/feeds/wifi-ax/ath11k-firmware/files/IPQ6018/q6_fw.b02 new file mode 100644 index 0000000000000000000000000000000000000000..c93589adb3826478055e2744e3eddd63d45320ac GIT binary patch literal 4696 zcmeHKdu&tZ6+id-+A$#_CQ3Jx@vxmVWK1eu*Hs14_Sy-M%yFT>2C=f$OS@&QQW`3Z zZc$g;fxyR>bI#{Ef;Q1tj}Y!Oi%RV@L|TQwEa(8eD}KOQSXR8882eRAID@|=6yVTDfWF;%6YBq*o|sg;D|6%y(z z*T)^LSDrnrd|mzIs6ls1kCm$7xsr&-NR@&l;vR+T@L%Hn`-714sUBYe-Hi2=9(SA- z(FdmY;cI&Q{^A;R_hH?~JSjb96=Z|1WhBDes&US?Qc6VGPQymn5MB+stX#u&e|bIm z`%)ZS&eJ#AXxx z6d9@CW5{IrkauIB!9F{FjL+CU`MMsbv@}_oC7Tm`ON3O=RX93SPr>gi@D0|*?A2p) z4BgG$@1HYoHIJI7NW8Sxuroc=PBbSYW<)Y%R;q?y2yxNoq@_x!Mas!za;`?C64d6d ztWi@5>!28zK&<7_rpLMO$wJPNXp3PTTrQ~9iFH6oK?~Ml%pYa*tu>-6wi4r~7$l~3 z8Z%ERV@hr&?HusbW-L*wumtMFV1mLFvYr?kcqgB4sZAHpcTS&o52SJ4oFV@r#LLY7 z5$50~$hh$h*vrT%R#k_LtP5$1FyuKGXr%ixHnb422 zo@GL+P%dUFtzyv7^D^{weY@LX=#|l5{w;jal_LM&|JmgCL$~Z{(td}zb-dZoGxA}t z&p9GR8T+Q84VpvjNN}t;K9W%HzXE>7mnpv_=W@cX~Z`e>wf5X_;Lg2ta?!bExuTw^CF?lek=65(Jg*RXKM8lAc)*63A5z{Hk%8i#{ng!|$L|3S znp%!1vUk}V9Cr)w)2+(MovJ0dTkT3X&Kw;0rjQ<69PUb3v9`D^N!cwY7pq+{>CD0Y zcF@>yzC_Rsn&MrF+8v`aFG7d?>l*nRV%ZxG(Um|SYFEMML|q4d+iPH3aeq7Zwb(l) z2Q9|>TUZ-*2@1XVtV|33%KZa&VzB>b#)*Bw=l8(Y-Yphw(b%Hg!m))o>osVX&WNcY z1O7DdiJEx>n}MfnMO-qCy^;IEyr9c#k5)I^ql#wI%)+7_@HXt(F|u-x>`q4+PmF8E z9P<=tt8PjwzCbGryp?9~zP|?jdj-|eO1elV9$wFPS5doJr!4LY`u;}qWGE`7r5vBh z(|N_;=H4PbId&u8@D@QGkUN;4YxZTn|9H%>_ltMTf43^zILB!?;k%>J(Mp4!;1cwA z8Fho-9ktDJRB=<%oRX4uwKhN=E0v%Y(sAjaRhR-KQhlpbk!VC8wyjDH*wBZIdqQ8f z?JAt{x3Zyg`2VYQn#J}`Qaj6MyGdgVK8N=kYE+pG@!|7wYDLE>8U6ZDFt0!qKky$k-dA0~klA1pAA;;!C_q?0&ubJjor2;?Zui_`* zusH5R58m;F9_L&N3qAfdVX{@iXY4;|)ze35us(=BY;$Eyc$>%p<2}T06TF4keuGcl z?_)WU4|n?>1g)c)qRwV1nh%-iAISSD)%2L`rX2fT5%nE*VYclO4bg_-ox@5>i7Ka* zNsCY_%g!sem0qITEWne4>wd=4p<=EMo06zPfMCtMDy)D0=W2|F`!^P`_66{+)AUc>+J+kD8b zg757tyP-Z__Y7ULViD#2d-%cI0L?)#aFuV`MsM%5jdazt>X7-z}+o zy{^GiKa4kB%sgT0DHZ0*vdnJVVzne`&FmVm4(%G?yr_4$9jwpi{tG}}@xKD81-vNl H9c%tKE&ruk literal 0 HcmV?d00001 diff --git a/feeds/wifi-ax/ath11k-firmware/files/IPQ6018/q6_fw.b03 b/feeds/wifi-ax/ath11k-firmware/files/IPQ6018/q6_fw.b03 new file mode 100644 index 0000000000000000000000000000000000000000..ab8fdfddb0fcb093dfae2bffe4ae775fd04fc90b GIT binary patch literal 2514704 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%0AjKtXc&Ia||< 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%0DZg%87o=#Qiyt$pk8)(?JqIAcY|wRHKo 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 z⪼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%0DtI1oK=WSMX`j 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�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

    QFUe!}rDc&F?C<2&v|>`k>lh^@`v(>gx-5dW*# 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

    )Thj}MX`FiOof5L8={;ie1b+md4^K}Y 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

    Oy!~a<|4u&fP zD_|&BVQ4!Do(uW!W~}wlXGHd$hZ}5`fTo%B8=P7vjU~xZ6>?;plPFD{|AfoMDoq(E z9%H>gt$%!-N;=l12pwFb&XM*;=~QV;Et6>F4b#EX9f3v*>3)l3-f%P4fduTIiC#ss z*y1_br>sd1@NkNA1jH7abA*4lIzLceV(!IT%Gc=kRT>L90weK^YFaBEbW4xo|F>IU zLoZZSvsiZ>GE-vc(j?hv{c(<4e=trouW9X}y)xCaoa(_mD?k}KgYlqGf{G``TscJR zvj*$4+b^~=!b3mo!#q!ft;)@En!@YnQ{FByZ;twHQp!U1f^JY*+fj#7{<3LI`9w9p z!soliJe~SY@Ifw?Slk7O9}qJZ<9zU#C9*G`2KfSZS6JimhRkQ_*u&!9Uhqb5eF58^ z4w=UUdF>_Go!^EvDcP(|@?f8z4ta?^3_U`S9ri3UNv5~(6FncijD06-epWgTUF;j{ zCzghnIiy=qJ~3-JlNC->Zw1W=K~XsqDLuuDZJ_4ze1Ipl^tk`^+a2{tF8qYlXf-Ce?Y*hO`P zn)y?Foepz>Imy>PB3leW_#q^nK+xt^bfZVvg)DCsTUgwaw?LoRk2ZKEw+0wb-Z0STn{`L*l*-{E{)h`;`S0Q{y zXtref@wa8PKiz8Q>!#q_CL}{P)YQ&eK`ZD)dZXe`sB_Hv%kv0&IwIWjf3%8GG zzn@-3D@um$ytXE`3`Z}Yl0 z<=$zREhmr%dZI)q9Nq@!OHwnD#`0Q#XlIQM1!zWSoY($;rZ=bXK7qjVSU z%Xi>E2mcK=*hS(_Y=z&}BCoZ+Uyr-Y4$RXq_(>Ytp)-)1@SlcvXfR$*@Ly*I-ms;8 zdfQUG*N(mD8i9ciHr6on*gkJ9=3-_*G;GBGRP1Y^JG1ZZA{|nS^f=<2n5V%fV9P*f zba;!DJ((>fcC$$u=)5<;XJY(VD&*3T5$>8npAoh(kw+~=mL6*ztUwONvJ$^g( z!rI~b&h%Uh_VzQtUn$>IH6QI$*2%X?XDy_+r~6Ub$@HEQf2m<#I-Lz1OwYr9wLJLV z)-9xae5}A!KD{Ef#^it2QU@IY?XTH7cXlfDhBPk8*k1>*@2(HPZ$8QI2xo(aNGAO4 zqw%H5C)1^{J+%(9lv9_QII^TNIqJd6KTamVf zzO{#+w5MY4urBnxWVb?=MPG;>7?h3kL)Rt7b)|zRd<=d-ILG{9rrP6@=*`yYXoKX! zxUU-b;f%bFksFIm{zXzF;CK|c76Rfd+Uqj{QyW(XpRxy^RNj+ucg2y+TCRtDXEHC6 z;z*uFK1!$cl?}v&N7692DeaYao|JxtGCKpf0RMUBE>-^_Sq&p$|%Zosl%^msTzFD#7j7hIzGp%1do1 z@P>3@(gjc&)k9^*=jUVF?&1mFa!##_kF6`fhbg`d=f$*_N(T&7))L}EgaZ%!X>Gu` zEP*Y_9AQN=+r7j>ZPMG2uMqA!IHhjlYb^XGNB0?N1ivctSO%xJiz3%P=dYZXu|{}d z;N5IR{`=~@raW@SF=rVgni>q?9dCd>On1qJ0q96fpk;RLK-nyuJ&KP{Z|{R1PlSIN zMTU6$=cvQobrSn_?8_L-nV;9-hD=@1&mrBCcL;mxM*~0i&IP{pSo120zPiL&b}>$& zFMZig=^*ImD9Sea^$LAWknOp1fdf5oMENLv8PelI`tV2^`c7%T0{tALvK@MbzDCm3 zvXoAG{Wy8F>?A51h-+5b?3e`linKR_${>EZl7EIuUn(qP%IK9ca{yx;;`0N#W`bcG zXjO~zKBBKV=x@HLYo<9u_31#blr|e>h$d|TZS!%&H+1MgU$#g*@>2W?#B1d!ec5uU z9-=SGzpaDlF+Vp0^-vt0QBr(8=rlrK)<_!aqBQC|cpm7>ntMQ{uaUAHd`Ky4u9qGp z`UIqNNMlv~ zU@YwgAZHTYL}~BO-PfhPWl`D-J@}7l@A-mj(_S;$ilx0$^ih8e+ItVM{v+DE2kFtRQ4LQr?hzu+AC7>Uz_$KWxh*$1jF@ckLtS??fn(;*P^{*#9xc{DF3x+ zkK(UKd(`(R?R5%k3|Jp69y`}wkA0CLKzc0R;FPU6^U)f0qSgq#V7o2z)-;2lt*Adf z-Kmq)r4q;}O!>B2E!M1sv}O%$gD#`7ctwY9%5wac;#YuQK7LmGMEnH&a`DT-FB`ul z_$|h75q=Bt%fj#GceTa^JzC@ZqgrF;F|BdVajh}qgw|+!Piss&sWs00tJXN4f%P8$&u3l1Q zWXSH42YbHykVCTkPo+dY8A-N!1oC@l&}y*4<_cqJuV0-m^1;l_CjWavT@`e6u)kdgO57hI#r%sI7l zOI<;Sq^-btJGegJRGP$ZNmL_1MUYaus~+X0-qo`*W_r@ zn=nWE0JBN7d|GkVQ)>!AX7e*!5)0WR_F|wqx<=7Ci8~n4)r{$LfbGTjKxQ3HqqUas z#Q|R|&Uou_c6uj$3)(Q#nbDx6nYkMJ_xL?EI+^sTuwen+)9)P4?NcCMJ8(Xm(+hk- zCt`&yK;P0zNyHwX7u=Esd%}fcM$6I3vo$QfZHNzJ-sNLIIPF2)fe7E|O&Mo1wi`BM z9BjsJUI`xxn_)L5?5<0}{WEHh@DawEp8%K&fcM4NlT9CX75=JVuk<|5B+1r<5hm2K z@;tld9(Th`=>Ex0MQgv?S${aakn{}2nZwIG*1sM$32Zxa=p`>Ja)ZkGIL?DLko%UR z44wZ4puaNV%o+Nm!Sn#mT?*Ld44m7LzK-g&p-vOpW(!O$RQ|rqOUsDg*NcBW%mi&- z*20gemta}skJzj?jFc5e%2GMvvkFW>evri(;LP4)+5>Gq40`$z_FxNyW@(athx8Eo zn{)6{=+`v04&gSOb)Jw8Socbt*W;aL&XU>kUsylW{JS?3J;V!lzrP6Y3?$l2 zJ9NwAcCeQ34>CB@`mp4l?GE^F$$9`bydUoKZUl`GEiv-++794xDf+ez|M~c@WO{gh zxuxZP#-!nw+jkT|-y_P~q^U$#1x>Y;!Zu0o-)5n9_rsp}es;BH3f@x_@g^jL`Z>^h znhf9L1ee*h`QZuc`A<;(Fv`7*e{DW=B!^-DXorm@&e*s@yoG?dunBeamJF2XvA?FW zNH?NR_jT%~_M<$H_|!D2TXw^SW)j0fADeOw zc$6~g9+T`Z(sAE!W|++|3AGALYzI4-0bbCCw1gr)>2~1M6Xt5TuY#||@<%GG!#ym* zHR-uY2Nyg6y)X1sS3pnc@aMpFaD(XuT=VAxcxT2B|G3>)Z^Vp-0i^fmyX{zm>au)h7d#Dxf>V>3)LmQ!w;p$c( zOun&9McQT^-cMnLj%s=zJnkLbOU1jYTo>qYIcO7kUU+Yy>^JbOB|4~r2^e{olNV2HZ=qD4S07FTrbgGr+#tPxr44*9m-Qq731f-uw)K z59?t=*rBy*GO)*d8F*d*+_IR%9Pp><+~@sfHSQ|`r-VzroM?Cl-&Ef9g>e&&aROvb z;)`t0Iz{0cA)Q4?99q`N}hwaOGIn+LEu?T@1lF9 z+R!uhIR)Bg@aI~c+)#7&w62cy$G!J7)NVT)x>W;x+J4mAE9;KB&W7$Zx!87IwziXe zvKl@f+n@^}dFDtszLfOeyv+nXKj{g1)sIrfK1QssJqwwLJM@HVl~IoJvGr!5UQMSx zk8E;cQdluV77ASTi5Nf0S2b= zpw33?wqE{a%_~9e_DoCMc8X63yzI51-?N2|=5?Tx*|15h01a)0jo2#gb4Hs#dsqiq zrJ=LqcrwcC*zdAxQvbKUWy?#(nU}%J zCh;=pLXEHQvgMLK=Ebn-G}n!J0lsZQ-$`FiyxV1u!+OEiDL$qw8Ytgj1LVj19tDtH zWwxDN#qG$4K2U$`_g>T8;tndyfZtrTUzrq!jJFtRVrW$^@h%R0Aq6tzdpOI(HwXIw zr`xhydL8Qx2f1&1znFF)xLcw-TRd!h>I>4;`&xW0kGZK8vcc1^??*Z4$edJuF8F+! z&{R85Zv6Q{`Dy8(|7pBEj^Du_NcH&>4nxOUK2L6{VG1w~0bToriqjb9A5_zQ$UhOE zfZyi^$VCpTqeTm!0moJjl%?yF&j%iuDjEE2Mi}ph8f7she*a@0}=USdJj$m@jcx< zCG5aDkqlfe0FUkUe_#>(jEi{DB>4lc31f&jsn1-|67UP#gMRb&Nr4Z%RK}?8JGWvz zA1~|VP+RIbxmyO!U=KGfrVm?#*Dm9ZErT=RF=f#2Yqq1xCrUd7W6NmBh6?ij$bJ}m zKY}f)H&@EQR=^6_aL!}b;(VIJyy}BY%!-v#NQRtgvF*^qHmy?5u=fSII-<*7;b)uc zF$OOI&$E|8ju6&W+iklgeFyrw8RyQ+bf-SC?v@td`y9^CNVe5N#-)7*FWBDKLFOgd zmxb^2NA80U46K=LsEffq&Df3mrhc|A9cyzO*0>7wyoUM!S{}h`bk5RP<6M4_<}A(O zlCYR&T?)Gaz(-|7*n7|EXH9|H@SB{>y+$^uy>_vd^ig~TvzhWRXov9!C0BrdYZ1nt zzV)zqfA#3Z(iK1Ww2b;Jd^E*r#kqv5ldb(Hz`PHp3SG6KKSs!gfgxAn1t#r*o554)j#EhJu{Fy*Hs$UZ_8(!qC-Exem3$!}ZI=U* z=fT@>@2OS#WGUAALy-CMA+umF#gYt&vCGU4;ZkYTWwVdcG&1G4xdxI1wh>e>Ka z7li&Ifb;!~Zjxm)8c3h%k<%e7rZ*HL9F-N%KQz7c4$u|JiX?;0hVOhH@{*0@IhzS` z9qgo$-_W^k$Y`B2OfuP?%uDk!LaQN@@uwO>FF_{Lj>=@vDMn?onSg`(=)yjUeDZ5i z?;OZsLENoK#a=8M@Gr!^h~%$CgcW@B88_7~hpj5^GdM)dWz<2u$o;Nc;c1QlXbSM^ z!K)~q?TN(S0oX}i6H$ibM-h2UHnt^kXq3;GFy3yJ&nR}!MPtwL*`r~l4J8dS^@VQi zCxt1s;)*AwC8+cELY-#4=-QGV_&MI7;LhB->2SgU$hszr_-W98r_BW4jGHSal_wqh zlb6bnoI2Yke#%*<48MT3d;PeBov&@Kf3m;*R(x|fYbX7X`w(|VguRKvS8=}F2R{*g zYq`2tF`hQ`i_Uj>AzgapEc`BF{%1gk!{H1UXSEXU^GLn8PnuD|Y~gzwYB<~*rm`#H z8?+v45y9Pm8a{$RqrGc++?ycX_)behi0j38GYui-j0Jq%mY2}YCuN{tq;qN*u(exp zPD67j^uQ8n0o4PW*vwDZ*;X}=C$PSqY)xh;>w+b(!OHbgpOt!5*__HIUZV`naSP7K z`mgrANpi(P&=~xa!$m-SZ3g(=$LMDS-;i-oXS&VuDG&Q`t(+}ged;Q6WL^5HZTYiL zkL`bB4IAKx!+5ic=$i|;Pb+7+IDaMFGDTBichM@nyz*+9`);;f*?-H=ZuZ!wwga;{{FPMI#sFHGN&+dsPirjmxKhr^@$&nx_Azz_<50`I?ZgDOw-$ zxv!H?|36i}nrMCB7Wf{!PQE7OtBBTze5KKR=pXUS67&k#*pHa4vZ zX>2sDD6`>8AzNPc);_!bgC<@pS~Ne2>J`u_3k&q?M~_v9vjj#_m`Ie|mGivOmbeT`9^#cy7Yj32HfgU^L$> z&`w2cKHz!5HR@O92yD;j+(SRmjMCiMD&HT+ z!O#>7!$+{f1^yqcV;rw+I#lI*GMYBNZIpX7nl_GKH65<XV3EIwzsk7;WD&HJ6P2c?w>Og;zW9mqZt>a*ok5|*i^Q$HmF5*|T z4=swBCwk!dymG#cwMcC{nvaRi2b{o1gfdpK^%K9+1O84mO%FKaXg<&&$!6728vOex z4Jth9BF10MJHn$rjp_fG@dO_lsPeU{`H5b({{Uxf(e-Vp%2z+GuBO^EIA#ZLp4mijTB}eAqrLq0j4_Eo- ztNEh+Z$jJ%t&i(})8`m}H9z$~F$U(QFERe(>e63|scT&S^{DHjBI9E2q5pWNcm$VC zm#ciI)U;^-o7B3f|2?sEfp)vc<<+D7U(`5Sv;L^ASFeK(6q)hrI6R!I^1ZC){}*Mg zYLRGf@pNaCbg@P`!^(mnzI zkEV^`2Q79z%B_p00k;*g`1o6uZ?&36b6)>Jv!wqxg4=GuN9XVp5JzxLus07y@~dY z)fU`ug1(H#w-dB78E-?%y-c|xpMMdN+l^+6K{<~fw4tmmZ?@o8=B$7|X%96>4d1SB ze_5d`TV6v<9<;6KMJbQ=%KG-*YMyMr#jqYUpF!nm&-Kx0y>#DB$$w!z_N2Bvbx$_Z z?npY?r1Y0+U4@U}tU!-?_M*Kep-EbIws@BDt%;?7toXF-TdZrY3pY8HdU~(X&Znd8 zXotR=-T=6jKG(Sl7ss@t7n`Ikv=crwv2>f-j{LWqoGB`<8ZM32H4WvIKKUEkBXbk| zx;&a5uckL3oxKi@wC7{wMptZE6%D1?3pU; z%%>3?Y5#VOcD@*Gr(q1->R1IL?P!6c7h~FKvNcJ+Ks!Zf=hE89SO}lp+8s-GFhR6K22u+5s0qL_hp zUEjV!nHMU3^?kPv?Z9Xq+TqdkMQR-lsAEA)9on;_c}DO*I9f+TOdVu%tk46-2m5u* z^9UT;uOoHzZ|Q$?{X26c?LFGMH8>l{C){-KNrj+g{wtc3^~Drd6tXMlx9-nG-(kG1 zt>{sJQ+7b~g<`(lpNhUetKZP8Fcl&P|D1|`#qL>|E>WBiVogEZF(N&NatBkctlooo z(vuK;Cd_%1Vd#Dq-6_8bVGehyb}IG4j*i*|9P}1A!9jTqQJCSsieQfD5Lw(e2MqmU z#764xqVKU-Sicf|8)ClMFGb%P^;<-_s&TMWT*3bVyB0nuGXOvFU>8AuB=hfr!>CR=sT(G5AAu4e}7or zpWE}s=ZibssP510d2wGo?E8yaW_-RzoM;d)q(ehUw_Bqrr$x9JDJS`PN290~S5$g#09oi-_ zE9Q>eWr_9c}c@h^8%@+c33& zEe9^`aUV2FjYvyW)8ei^e0{irjlQpx{n|C)3N-pIM$^W_g|t)AwDEBH8+}KjX@Ki6 z?h=f^g|vX0_MLGD{$5kl8UgcfuahsXr_r}xO^cHoea~MfUnBB0N9#krZEDyK+MR)M z*Fz>G8lXKm?GF?h`1>dgD0uv+(f5d2j^v>@=vU%SU2mM5>~Y~nb$>n{pH240GmYy0 z9BE_liE>C=thU39!6(vs8-1D4G~hEM7N1C)rlt`-6_^2^VO(6?=|-P!TwEjKzESpT z_B_G^?bR!yc(^o*huFCu_fDg_KgS&Y=3(E5YWeSsCGx$arZpm8_jU5c{ZFIsk7`=n zw-5VXyH37FndbV{>-6uvM&HJ0`Hn_) ze{RnkKi3DOZbCerH14#R8qq;vw8fd_T zI}*`36^C+D)jAsi^L61m*r@K$uK^d*;O9BQpT^K8+U{;t_vhDutES5qGlD_ZKxSuCvki#&z;FB41>Gjsf0(>v^8_Tt3G7k3Rz*XN|$*W<1M_J-gawv@iR* zdkGge?@7Pz-e%l`O^Z6NgbQ5^7hD_{Bj3kG!r$+s{2|6a{_HwjY(9tmKmH83cok<@SLZt3>xeyz<09eg<~`3}cW*Q9 zZN2VZ0_tsw-6MM7iPM5h*Wuvu<~^=hxvMz9y}yftk8yzj@bx zloKvUM^*z_;Mb~c%T3LJ^Q`*S!|5q1-v_^8S}!E0lYd;o`*yXCn~0Cad&F}l>;unn zeobI|Y_27oxmM<9kU!PuAFT;^W6w#BrMfnsx>l|sRxaVfn!w|+a+~|FJ%2d<{Npu& zsBX-D_tkpNT`NcVo9TNA!)pQy;`RLH+H)!X{IfNI`Pa24;rz97x5mnCzOp6&yGa#~ z2_Id1o*jSw`I$Lm3vhB0L}k16w5 zyq&vRj#HpAwB@?@M=+{>zFrO>HGv z(09tJ)@R0grMB>hhrwT{MO)ziNzX4upOXwu&*^&{zDIIl2jt2_v3f|R^uca-ALPlM zo#P$z?~BTlY-pNWt*8HQeCOk9-{FV;`a52?4&jN~v&q^d*AeZ4uPed27%ax%CMo*d2sp0Wc^JAKYA+x8>-PFSxz=9anD#D; z<7LztfNliij94v%yMe#1gTHjG4u1GrpUKuk9ZS?<8B+&;_OI*kUA|U_Z%iFm$480U z=a{Nn)x5An67o2O$=(P7-hqe8gIo^9OJNi*WhCQ_Ra`F9{X9i7I^kPE|MSrvij~6e zliYhkT-XF#&_}Qb#AD2=c`aPtcG7Ev*HB)&1{dZy^3Atf{}hACCo~WDwjwTx2X>YR zM?bAH?qijqFL$(g7kK4zJa-LnMzecITS0^~V!wm``!dyjW+H5^DQ`hd>2vj&${qGx z2jZ59oEx!MT}Jx<4jZ`*Io}=@e=l&~JlCE~xquNfH~n5V5pA%0F;5Rhb|6-JG$!ty zh$Yb!iJb07yjB{YgJ191O@3^t(7||-lUm!i$8Y*#N1G3}C@!=m{vP$ye96>KaW-nu zo+*HRU;N^iwY@&X;^o5JBG^R%2i}kFkQc!|DhNA0_E7#hifbdS__oT5xHh>Iw?(|e zZc;pU!aHA4>^9MJjEObEopCC#F+{v}ip3Gfc?as&z%FvmhEJ>7D6Y$UeeP@pG0SV5 zCn*lLX8(41phwdnQhg`Q?cczT2RS8AvmWHb0v>qX?{AiKVcmJ|xs9;kj09ZlJmZ_@$hqy30$pkspJnT&U-d@AB)>Uyn_w&kB1aKJ4)~ zbt8^?2ys3np`PqE1=U8)vwp(*(Fuc?3)F7gN!Srff*OCiiR=^YmgbsXR^0^qRH4YG z#=`6Z-n2!wZ90_K?WgbR)c8N0_Z$R_U{aj!_(?Y?03p6tb=3TZ;GbZpt~aMO?yi zx^WNwCzi0#f^Sq>XfER$#YsXb`Ot(rSKIjnQ$w)aww3xb2ee7m?=~>^zuA__6HidS zWn(qzTKju$tWU)?t9N_~Th8@Jz0<45u5ERG!|!M=WajU!Z7Ub9CA&wgZ=$QTzEe;S z*+A0V9?mnZr8Qo@EIPl*=auNKrQc?Wukn9mecPUit?v_k?jg+Y0nKkU6z?aDxm}!Q zOFnDWHsoU7XlrV*j^FS%S#5GsY`zojX#9EP#IfvsSmqDewuO-I)>!mhz2QFCuOeoT zUSZXgTa!O@TYLWp=F>03Zq@8wbyADEc*O9UE2fcuw@fir&*ga@eF)=LjNEy5BEF>= zwvx@I{5Fau|tdeV%;$7LqlDU=fGB&VsG;6w5vVy=Yu}*;=S(A?b-(A zDDvjq$M=Ys1DgKHbyJQ^Fzh+H*g)UrPx8a&d(4O}^M;>MJh78(*t_2Z8|w(x&l~=J z^o?R8pFx%k`Re+!9Y9XauodrfI9{MdEl-V^o&E^1Od-$ ziZbhih~Gr^xq8@I6AsA-7;oX}#!EUXXDA^3+poao33KgsZIz!*}S?8M_tM!Yc^UwTIW>1x8hll6gQ5!P$m)}ky~!Z&VAw%wy^DPF8=;l+ntyz#mTum% z31h|Cs4FI>cAn^JVPuVf}64sXb;FAhp zdC(||_soMvg+H;#(p~v0ai&+zt@6&-f>!xLcNDiGAExTB4;}}0V`PtSi6H*jCge*u z5wB94zb+GFU_cHZGw9bG<>&IbCD-^CJ^jVjydv@HnytY#;q_aq>+g#S5<^iGqOiZme-zD&7r56ADd3KmT&6f$= z=-f-YQrJfO;vn|sP?>FO{69UX|Gu(1c^vYIaENO`^hCft4*mDq>WXOJ<$CIhwLuSj z(K8!z0oNdo7~y^Z{!_&FaF=}G`Ap6GaBc$sO#90Vn$#Z97@o><3*d~RlQBJ z&&G#8)l_SE0R3I|+YEGkA^FVvc+peDA-;o?s2v$`p@}_4?`=a^iL4 ze*|$;JkBWJCB(*%_^$s6-}%K)V&iwD&%G1vzA?rl`K*qs`ww_bb^qZ)rpxBN^)h$J zx=lkk#k}VhN?T}emasR|ct8%TbmBja1A|`<&RwfH#Oe2}j<)yJ@@stJ|D?UUV(n#p zeeS~l2kniw)r&T3(dG_Zi5Cjunt*ErS3Ry=(RO(pt|nX)>3-QVoL1jdf$yGit_ zT-9;LRUKz3HqN-xI0r$)*(1@pyJ&15F(&^l{x9CQ-aa>- zO~w5qIzS)DC*Q=90IwaqY} z1r03bo5|;i{Q7xO;|@a)MLa?c{A}RivOXLC;lt{l9J|t<#*4gK&ahul^Idx&^B6&2 zdCWhZT2AZc6`gxC@eYuEs2ygs!(#;v-p`-DJ0>5;?}N`%+e&53o%|M499G+BZVsOZ z%_ln3JURC60P6KxYt^=KC>OCo_M>m(KUeIPZ;1Uj;eS%>9WQi|$)p#v*2=p( zDc=e757v(1@$|gNDO);$SFDfRq?{iJ#pi}QP=>c!)R+wx__3M8){pr^h^Ji6Z&TmF zx6H)H@536b47Sic4en_sq)k9xI-b45pB~*XEs5qcj~vqDF%O;l(LRi!_l!x_lyKW7 z;GKtX&-=-A`06^h8Dg;WorlyhCiwev7doC|b8~rY{p|*?I344G_{o;Pr{}o?a&QOH zz=xyr_rSty^Vd`30j>D&&)+}SN9V8S%foKSt(9gLT+mUO>)7}fAJ}>Cw^i&=#s~+Q zgk+j8?uq8!dSju0*uGgK9rtS+|1x#OU0IL~ zK0C7s@kTb5a>zqWdhf_rxoss54mlGVT$&T+Hu6PGv<6eK4w&4A zW!2QL?jk$&At^lqx>Rk2KVi5=+t^`fW5lN!V|7v7V5;vB=tW!(LTp&M_U~Ag5Pa9{@y``W@-DzMHvJo%^+NG++0uQ=k3Ceyjbv*m_5{rZ z!Igwt##)2-+l=sCK4&{FOYgP&$8R!*t8)5!1IgdX@p zUW(Ivxw>C6^6-W3u!80zuZYwuZE?calwy?hcX{jY!9K`g?_i3zA`AI(1dJK$E-gqc zivHK&KVlWA_c{D`qMcNR$N%`8nU8jI;ixY^(f8f>wzb!~g<>;#?0kLdCC~Z{lJ}9f zS3_mHO;%Atj;~9a^(1#uKgGUwG1bM~YJ4*2(T46C(9<0E+EXHYr5SlopvSQaJsG{M zdN*)G@uySE`dUceO8pwdJ^g@WOkL2|LUr&MZy)FgL*5sX-wjlk^1Ph`?&v=YJ}+jM zPOmmd8AAjc0Y8ttSQ@NB<;?Slzt-2n?wd5?E6SjF%Bl{4^b$>v&XIk{tEnlrG^dKq zbreU9FYZ(Gg@|44wo4Cl4(d-)sNKfOGe;s=H`I?vcS^*uhI35ES|;0bvKiI9CEZOl z12%-1Pw6A6N}cPwBIY1}amro#$F9+pNAB95;#*pAhK0Fi9dv1TpbmB@ZDioVXw2yh z$f91f5qN-)ykyzAV5j^Q{HW)M>46_W=UQ`FvTW}>B|D#x+o+7Ok2B3^_^wJseoPLr z+k7RIe^iE#rK#DZU~G|Rp7Pay(?420r3kqi@Q$~)wfHy7wa6iaeWxMGF)sgxJP!11 zSMAJoLPgq$N4dY?fyN}X3x4aMn=dV34*%_*d{a62zSD@qW;G3OS1K%*N>9msy{F{Y zaovfl8&?Oe$W6cVPs2%$nzE18eDUI6GTg5Nu8hMUXSiPlTn<>xHFzn*{W9Rv7%X1S zaQ_0Z7=t}S8SWi`?*Ob|ekd0f zSosig1mN?4)%U;4a2EjXkHN}lhIJf#ZVTYv`17tz_Y}ZN z{CRh#J00+wfGHjt+nec50vw3J;=W9`0QfgC*t0*={moF4V;5kGhs2I#x~~9!9x%mP zVDD$TF9L3j!JgBZ?m@uM0#<$f2Q%I81NOvVD|lb&&vqXG?25rGlI;!y zUJF?DQTTM4`%i#t0Fw={=gKtq>wqf()7hOeblCkW;PM#Et{is147e09>3G<&KKCyG zi-21R|J{A=9f0ouOuU@<#bI{~;QaXepC5KN0nP(_^JdImTgC1=z*#Yv zyAUBgv;f`y8Pg)+uGiI;?t`Cq`s_8UB?~C z7+Hw&m+T*__t*u*t^j;K28$nMx=WNChoOiYX`OQAqcp57s%viIT^HQQajRW%$}gNa z<==(>p8TZzSJmtI{GH-BL#k5adJ(kMusnSzy`Qb`SRl*k5y@i0nx;GvJ3$jd$Q$t@ zuHGIm=onXjRPoy1czmY(JYwXxy|dzsbo%G=fya^@x6vLcP7Mq^eLLcg&|Z^X&qGJ2 zwNCZx5I<7Dl?A1OJn$SjVqLK=G^d!W$mkCXp#-9FTv1xYT+Bo7h;xhLoGm?_h(lrL zhj{Fxe6djHD{iV2^^NCw=+n5cd0TK{3B@(60UA# zZV#k9a(iIXm$wJfl%KkiF$SzJZ6p=rPx1&K%#=BCkL&S)3L{sQF`xLBT}y5Zx2{fd zq`a3g%#@UZ%gFbZk37>a99wecHN*~k1ay{@Cd#=eOJnIn8(8VY0)5|9f0{mL_!i*U zQ)DX8bV>zrJX1N!2~Bto<;~11Bs{N;;+gW!vIn!&+^&mUpH_W?f|JjrhY{ZpW6Q7?P6Qr`&^AVV?0fh7U%EKnaf^a8e#ImIh4QnD9>|x- zmG)$kBeDQI9RB~UKKan6qd!ESmPPyY^kd^4W9vPkxD2WE&7%`X<|~r}fwiO6#^B`o zR+0TsSHR^_`))=1Ug(m}>@I3Xo?414RqGNYEza8{%OG+!ZdNwQn>!P>*p;4^iOUm) zH!awt?!!9qUIX}x%86K;nqF;zrkgJyzT`XX(dkDmmraQKM)SypxPCM@JnnB zOt^-=q%VDh#%B`7QC~6DpLlGlU$e5^?+I}QIjIHbiH=M{oK`AByef_33m8Wq)@?oD z?Uy^tR#4y7@qD3y#&gmsjHfbB=7M+3XVRP=iowr`8HiVgGtpJZ5s5v$HDAcnC>aIw z#7TiqW{xwBY#8~k^Jp{I_jv$%knQ|Y^JNz5h>meF?m?Cma9;>nF!s^=WMjY~=cEU8 z<+kjC!ke;hEp%f&I+W;|yc6xCd2W_6VNYW+R>k1mfVTqP{@v)xqgZ!MkZt;=9bt1d zua)mv$~iPAa@$`16!gFN<0|S;4f^v7z#?G6A&X?Wk^gC=9BZ-(c+rZjh{uVzLid`R zJ8aD|Lq7S{)@Ip*YmuSkQrIr5_j1a)77bz_X%XMGR=@oGtyrT1U{=95&j5}_e@c1> z#5oLdChwU+6%PZ5WpWh{_)h;ZSuVZ*Ml~0^58u{c9Jtv140uPhZx)9G)rMN`X01> zTt)f3S#OqGM88w8c9Ih(USP*h`Mo`|44N;8I}w9XgkA;nm(Iu`i@8l=9nK66gI=4q zOk6TkJ_P=qVi?l75Y5{sp?k>~HnlG-=Tb6Auhqk;@dq=mnA$VT3;}L$KF$xKc^sHH zvA%}*%9_+VDb#9Dw0&JQIoRr#tQjpE@r<5(hSI*}7G*{#ZXIadx3%wNgh^MX>kIi= zZ?K3dL4Q!0BWrA2^R0W4lMZ7u1MM|IXQV+4E(`8G89G!9xwrDhzC(WD9puhCEE)95 zy#@hop&TQWpO!yi+D18FZJ1w7;p^3QLO-0*YpkA_J*6-qJGqef&RuBl7Hqn6yrZ*oyL?ICad4)%L;k}jb7XVYKkJy4Z@#0HRRvj*(X5pMd0a_kc|v)5%I{}IhO4(~*8&PDHV-+0@(zi_IZ9m(Pa1NZqk zl%e{$eNV^(WlzYUeawY5$3zVSooZl5(npAo@s`NYovAWB`tqdfvoLcAz(ZX(b2t&( znCyn>+{=V9iN4D<&^?BG9cjChBgh{lRL+yfqYfj^ed~ZD4fNakC%&w@13XM7)=(14 zXQBL1+OS&Q3LPD-32xZiE`_*o2y%5Dbg7cyK}Mb{s0}w z>-xUEw<;WRYuCC$k0Vy>NzfIH1IHaw5pvwY=UPDCE3#h+ec~z804GkIH*)Apc)!~| zvccJ42sRAeres9mQ&9cfansj?A6E2>#$OcxKhSqIV^1dBIPqt~Rl0(+NaUrX?|CUsG;qaH`%C$Tj+K)G8&4q4r(!jb{+4h@cAAlQCxg~; zcXKD^U5)v+3O=<&7YFZIsru&H{N`O_BcBLep2YjMvs>jyC>4a@ly z4zbV9BJL>REhK3_Xo^?@R^)P0?WfVlc&s&wv#2a?s@Gohsx~!z39r8MvczvK?$Wl9 z&N}YLtF{GwB->gVH@;hFm}28k8_sh%6yub>WiG<$`Dt4~Qs`UY#c@xA{swU@H&O-F36p?N^-J{Wq!t_K}Y@8nVl z*QBS$S)z;Ti6s z{|?AlY?;)P1pM5AHK0Gr84166Ur0s{xdk)vGu$#gPd7RaGLxt0Hz;Q*r(DrbxY7!O z3vwzmT5?M>TAmPM#nd`q@VR0MF*%E{FHD4P(4$NZWMbd=`2itvVEs4;r@Z5$?><(_s^=-~cGPwH z{kgx-Pb--epuEcyl@qSx_rPupdk2TT!_Sm*Rx&AaaDT4jwqCI@_o%*Za^R`sK@p$V0ZlSvSFyF;@u&1f|e7BZlxeenSXGLuT zeJ>~bmcq>J?7}-@dI|9_Nshtw7o)nOi<$0x%(GPRnB!;YT`L|Y- z`MMJ-^nsdLwkLF+wJrwPQ+kbHQ50Vf@9Nj^Y&tJ&aBxn@1ap7poZReWM_u%8|YOb0&4XQvn1)|e}aKPP<) z;mH7A{MN+VE(nlwa!_WrxLvM;ZTfM@4W8~coYN{PlC4dqJf);-)qde^@3wY@<91UIlWFor51c>|>OCJMoTF zK=bu>E`@A8D0d^-MsT5wVXl!=X{QO_&_It@`{B;Eoekes)qq!dPBa8eWo`1az>OI= zq4OMG;Tsyk2h!OM!&!w@@mlHpgf9xUJlP|m9Awvf1SWu&e++FAI*}hnu>^!A+HKQI zbGGP@2K>qrPuasCaMN?ZkC?co1d6k3TP(Cp)NeY-8i{YVoor6?a%9gtOaE|ZxU_hy zsqA5yTs>bmq8qcBcQn(yE%)}Va_lKyi;62db(a38!S5W;RB4tZe`{ww&^v)yS zK-UJ`n}B=TgG^)aI8-0SqdFcE*ZefbLt8^Jw0GFm@vP+JC$ZP0FIXoJ?_DPwmaS9w zidFZ(ei(G|{S?VNf) zC5FG>tN4rSQAl<*PK~Vr(dk;B*nENXWy#o^#$#_vf;{@~h;Mqd=Q%m8BC~%t{JKa- zn^u&L975*i2SAHCv90*`oo#X(&YKTBl;oI&`M5*6@60_nA6Z)fU2lr215T+Qc-qvK zcDUUSUa$JD&{Th${>nniC1k|;Eei<+1JG{-zcRIv?zaj5wIQq(i67!tL+6{eN#ljy zH+Nj+Um$PFpLQ^F`Qky~syeC*fj$DV z7|ZYqtn^N_)m!v$YM>f{LOxpZ1w)le#}+-kx^<0kX~o|n7%w-XNEsfgNt&s(v|w6JKpZkLOke< z@K5D~c&^1bdaNfAPx~ZzSJUN$BJ<^@N0Dy@F?5+tXy$8n)=j|L6>#=TV-vQv*Xg>! zo0LoqcyHNtOE}0JnOHko$Ur905G!)G5>I^}?$NvxY+OSU=KQRAcjw)XH4(jsyd3vU z4*0rXRC)7TXnj>p4%`VE#g-dJ$d88yjnJaa0`^C3p8uH>5_3#Motmn4Ki7GGf%nnW zKn8uI;7mTX%?bYSG}ilni0$$T@F50qv7tDRUn}i>5xy|s&(Nk7Yr*pz1AmA8Az1vP zoPm4vJvs}0dG6W#O|kEC>D=~Vs?l-`wXC;sNbr9U!b;3$V<+98Q-Mu zy*X@l=xbObeZPzP1s@J?=fA0T=}nj`rSJopsDKy2dwc;aNLq3J2#@>>Ol;|!QE9Ah zSv&6AX3*}W6X%c6z4TuCWBJ^QSn9TUMDL^4h!#^5fZj ze)gWDAYPWrb*!U#=XRxkIVV7SpccP={7e`N(y0id*WU5TEO|$fbf$pLq7P%t$tM*0 zINJMI|MPVQ;8R$UIWn_wli;;7$9R2BC)G(feG>Ig>@gL7_awffxPil(N9jI8Ug>0! zL*J37xKkp&*T9tiN0})83+*{8s9h+p)TFKBurE`)ny{X~P?+PPfMW_>VMP- zzMp~bZ_aKhd@6f=;hW&$UySkaFAgR-3ZK4MMRK3#>rD4{z;k1;@(s>R%Y4vpa+cKwbq{jL&AbsdBG{9mZ}~H>zI|r-O{*`(tUP2VdQN*Z91>x%<^L&c;s;ve82Y5q=2p}DWKn<6yU`lx)Oex6kzw<5@1SlJ<(sj zh>NUJSoN)#ul-_j{i|Y={1)m0U22S=o?gVgciOoyJNRrL=}7fTuvpj68s}p!vyz}c z`9R2@4EX#({SoL({k=sYInrsC&mYJ;l7}+SM!N5e*Yyh3RZMklQtQ&i>PnB*H9l6? zxr4eRtUKs`C05tD1Gz^wMSAZvpb{d5*y|reA2qnP40hc)fcxCNxsH~B zo;!)BW6CcpJX6knWUy*R(y^D_mRN8hwU`^ZX~w-ShV#s)A0XQ9!8}c?|B-(C8DZH} zzxGI!rt_fbTG;wbkl=X|X>QZA}EOcVD|g|ghq zfcL~;F`VVjm6&@Hc!sasr+%G?cDb(w#Bs;UUaJ1|6vV zP?xhI&a3r3hrO5TTV9|!_8e^2 z78)kK^So*UUmLtM{dM@GoC+#E06M1QGPeBlX0zu4YdjOvNz(t4|x{!^bFT=xQ1{|#B~7I8*t^3 z<0A=IGp^%twc?tLYb~x5=()WPJR_dtIvrOlt|nY-aW&)W!_|W8Zd`M44dI%L>j17d z;mWTJw%E|FiKy$w(DQylOmP`&=B_hgj%L31yni+J#4J2(#x?y2#@7b@h=P14ON4Fd z$Z2`w(Kr3^`7!wtXIz-g3JSA}3y)*Yy@@%O?lM=ti2p>3>OO$}=c(vk!oJINFU&T4 zuk3d}zE+mb+YDGYboNhYZs|7d2%Wp}6?K<|rS+HpSAjRl2)>TiI49O#<~vtiW+l$c z8hhz_iv~g>x;)Nt$x>GjzY7`k#(@ zJ$V82BuhX~U>Cqah9Y~6XEom4-u$G~M5}uHlN^sVL}`^r$#SO=T|_+w;BHIejtiSa z9pZ#)M>ZsGy1*@>98jxVYaZ~FO$Co|u?+f^n%s57rycL1eE=qJ^SHc4=rbqoC}zm( zRtq_9Vwh{NLGL;r>urDwasqM>X+V>tkPv=x$#_RUcs`Ey5$KJRz|)Z3j3_2$c#CRa z_xzv!`L)P10v@9YyazO_hG4ICD+f7`SB$dnFyAnPXz>!h-fT5m(?dq<(NgPH%t3XZ z=t$R9Q@xZc2y`0xnV*y+d*RmxJ(~!6Nat}>mw6%IqU+}@f|8WM2cN;3o>;F19(={E z@+zDO>O{7l{9|5{%Kg7QS`MEj$b;xNt3ezI@ah_rrF+DK>Xk$C=;F}{=b-DOd@-~q z@)e;LW(Tj_+kD3@p;mtgXOLgHzO0&~&+p`lmLS%>H`n{2A@HbTy1T=A%}$SU7;eel zQMe&{lX^b-)yEdl&GucAQlsW{OnnQw>My3ctwC#dV#t?5zP)sY$CQq88s8IVus_yE z*Nr%uiG78uFWKuud^6yT`k?35dud|UDWWObZPx^k5?pduiC)(gWe}Y?{#Zv zk>~$})@;*R7oSZ$u=p(L!gQtMM)b-fE?sERhv#~AN3Pv_)TKKRy_Xx-d2a2N{1N0+ zC4M12%vlWO9P%wqw+~qPhFR~x4z*?+#sFhs)%DE49z0pp8Y1v7HzU6n`62LbC;W1M z1z8Ao$M-m8Ov3404e8WqpZ#Tp6fP=MpY3Hp( zRb=BUD*q<$E6UFx`<7V>bEjcn4k)uM^!-xvV|-@1O@<{k-7qh2c)An8!JLLwNgiQ4~|>_8Zp|PeeFp;Kh=I zUc(f~RT-dRS-^u4?=|3mYA8A5JL@cichp-)XCg_!dm`}uyLC~#i=St?A3-0vWf>#v z5YE%V>uA9LNWd-W2&(DX@-fd8v3at1M_q?_pL`Vj8?}?pE`mjpoR2e&xuG4hNx^tj znN&HEVi|Z5r^M7xwAL#-F;^@o_vfXbt9}$$%U5vCzXcD}54y1x^Hl1bYyBC{LU^>< zDbAJO#atQ$Zy7oFLR&odC4a@zZjt!#^iI>=R>W>tCECC%r&>ZH7a1HK{4W-^`W0m^ zbWq0TuRyCg_)w7D%plH2R9$zNzpCp_eGA_~S>j(8K(^~gzQz#z9&E}BGRcCOeNFS3 z`13kCXXf$4{I5RJ5f<8sgwY6CUvzf1{ zUB}=?on>|7bn@o&-O{h}EBNstdDTHEAEs119#)0GH$bRzP(&A?TUYhw9q_=UIo z7XWtdo9cgr_uusPGssVO%AenJzyAWh^)UFBb5>nL4|t7pC7$k?;%1rcqwjDG`mP2I^stMb z_@avIZuk2zUtYd>yGC1V*^;E5qiDyRqvW)oeNezTb1Q7zilHmRSwYBlwl@(5=idt(JT>QN*$?HkeZThKtklV*U($n3v@Yk1I0|GbI7OMV4Xh zzE}Lco%UiT?sYxf>z&?}7EV5gGa#F$xHPd`mtxZ_cj$U_s!gBvN^W~1=`zFG6pH`- z@?g#xUa=LfTAC8JhEiIflViL!EiwqdPRbW9fIiwlLlQAQ0`SWEc0(`Riaqyb|FfD| zbSzuIls5SetCC^@4?yR4;xt`h_et#ku8UPYq^J8L%l&7-&KRtGndN>1upUfB)Mo_e+4K`1{{wfyUFhCDF&&x#f@3uqJRG&8A_soLdfY1uy|r!TQlaH6^5z-DVgud{e2c4%kmZcAP=N~~_D?`ofz@EM~`SG=+?}V*-Xk3a^ zkrK`m6Ae7(wQx9XcrW2)@gz3~I$RO*`n8pF+W7Y^ZCh8uCRl-9>ORm6%;EK`K#OtS zO!Pmp#MA9NJv-opeFL{7ZP=5~=bZ>~y9wvNS!=Fjz~qX!6;xh8z&S6)Xrg?ANw}{JY%C$!nq)!ZXSW`O zj}>%x^nU>7kXylX(b=pA_L8i$V#}@2<856%&T-R>SDzv|(TVr=9hIijIool2t4ub$ z!pS-9ToGuOEn~RZn`zoNTTN^!F zBD=seDI>y^r(C25%0^%3;~rwXSlJR&PcnFv)_ap2G>;g*=Y?JM1HgODySVq`i&g5F z?VsdMEqJ?}c;TnIGa@|nWYs~*D6L2j(^xwkH#m--0zU*C44{uM7URq#ls;mfl3HLw z-_j)LGmp0WQ%GO&n%$6HdMxJ$YHNP zYfRfa(DwLVO)}eeCz2c;k4O6;?wjQP4DgFFSUE7sJrDh9eR%ph1Lm~QsCR5!*V;yU z)5(af2hFdWJDfk;B*Kn;!KHw3IB+M~2&IQ46XD7L-2u11vutQ#Y`x(ghce6h;h~L!?i6^`S4S(m~Hjr}D>z@X=G&fyXxlyx4cgv*Lmt z!VN`4$w^2d*ylDiG;>Y=$D6$CCy9`GHQlX#opO)i70JGhY;+TFw)r7q{UjVs=pT7H zAl!8FruJ8Y_H7B}-H4SC@b@S)<%G(FhGn3yOw6cf%e0JQurF+ zO$}UetAAWiIdm_u(G9oSgr2#w#%gI!+^gn#t^De#Q5Njt8mRpy#n+GwTWmA*=(VBR zExZ(JnH!cYSkKjb&)i~WH8<-q$4%gCb!aDaxGik$sD}9P4Y=BfcZPrdgm9~$6TH8R+fmb8i|)@guy4t7c`+`e1K3^Um461hv<|-T zWLJk+dd!zBl+M=8(+qYlEfn^`78&%1bTv%z*>`=EM;d&1f&l{y>S~3)%Llw%}((NBb4W}47@z`xf8Z~@q4}KKWw73 z(3S7e|9+D%?{%J)S+|)((4UF@m=B%?ecx;FW1pq&58P2s9Z!?P)UFG)`Cpby;0s>! z8)2`=my6rj!f=c3=xhEDYs?J+^TvNMtoq<|dSOPnVXf};2mQ4tS;^`lzJGJwYq{fJ zB0SA`2mXJLU98$iYx?jc_bq@A#bB{-lG_5fHwJr-OmdgUbdV`nGZ~3fFKEP+dY>?( zd^Tj3j3S)jE?Mf=^|kpYLUuG@uc3Y8Pp(|}r`NkQ;1?$-OZ{}l)&btI1i0cVW?m+L zBMD?EnMd-L_Tj*vn_=Wz}=ox~EMxuEhp?(4K0-*-e3spUC$@CdYhED#ANT zQ+?!2_`k@GG#};6isYU_We!ElTq=!~8MXY$bPv~(O?8!F{{{WZpmLSW9sCgXps3Ga z<<$BBVE&0(PnbI+1e;{ooA~3f1@Ii;nC?vua-jW^fov#i@!i>p zCXE3+${g@dSMS|m(&S@q(fvEd-cOE}#ku*lvUnf+n_BjJb^NWes5f4xHakhxn-ZTx z`=w9tCePED#?ySf&_B-MO%qC^xTm3Jq(7XrQ%gV}qN z+%~}HW3c%CB-Lk&`b_-J;D!y2Ucr-`sQV|)O!OUdp>a3K?C5(9XqE8f>OBGHX8nqAgzDQBduGJhIF+Y< zu!FM-oa;Pg7OEF*J|9FZW$_s^d{kp!-*S|+T zcO9V$i~(0ai|T`J^?a~GB%Vf`mRwkK1pI$&96hI^^Olur>S^tpakgjcfw+`@c z0UsdVqJNUxgSMu^j@D4jtG2X5_kLBCUL=f=O|5sumsR9%m4>-F2>iY#>`5*JJ$vPW z*j}5QRDL_g!Myi&HO32_XRiWoO}e%f%;u}-SHVvI6nyujRYSZY*QF?C=s+jd3rmKE zo#Jf7EdEdMB;vm?QF+u{_LR(y|EHhk*c+NZa3o_whIo3pe%5);wtHBB-sr$G*jSE{ zhkO`Msq5$RLo`>x`w5WO$u9N%dm!7vU#uU#;$G+=Oo`?jc+uMMEaWk7=Q`Ppy_Qot zTs-zby5EHR_*P>-tv%>}X|2(G^TKyagEbTRA?GmR8*EwH$a6{>&NZX<0&_u+y~=Dm zlT6L&_^(;=#=MP(-k3M~%;*Fs@yx3IE9sk~_OH{ItneHAR`^YaSNN&_1E1GHR|p;* zK9@$Si|GG#HnXWjYpFiSCL7D=7HAI7#k?iE+H3XB5K9dl;u%K1JM&lH94qUM{m=C! zIbK;4od@CvliXh&PI9~ygFTT+v3f|45^ej~cZv6k`ac-kF2(#G&XNB^d2Y|G=!Zc5 z4@H*dyk1uAvl_zi;ZXe@2(MEVjluho3G<(8$O0^&f2p|l^dncQQuKzS$?twwCDa(! zO$WZYxqRLiYsSGwd}=_PmZa+U3?e_0Drr>xo@*h+SX$-s*-``CP+J?VQ?7J4Kr*XQ zX_GRP?O1F4c8eke;y&qg24GhB01HKV(PZeyDISX#=XcjX>wv!n-{+Fe7Rzzyed>#G zmYaoj$rld{bD*gqJSQH>KW)3#);QS_LhLM7o-#su7syts-enQ+I`nW9&&mMN2+au5 z2Mg>zf{JW6!}pKQ7OXvZmtvjMJXj;wY0k-Yygen*)SVKz;MODdgEkN4L5o~2p-|Qq zZWvX4RcZgE@kp&Ptw;*?rfhelt%ZV|VwmiTz=Z?7phBZgf$4_TA^ zGJ?>D(Em2BgA>M_lj{((Up*&(Vzeqnsc}hUr`i~!r#Q>jMYx>zVPCg>hL86aaa%T~ zdv*mk)Sk?TywAfPU7V&ZG+=+Eex_^E1h&l5JRkiELKjQ>2cl{>doee5L*`qLIbh;u zC#Be|TQmpxEmANg++7s?z6d$Sqw%)-6!vuOsPiNX8X&{sY_yZ#M*lk=p#8`wOVlsK zOeTE;3kOuX=R@7)sGIa#3vq2W%wge9VM}iSm49=0dTIgP`Rlt?G zn?=ayl@R=vnXXp#3qrQOOl7hN$ zO{_0Wn%S&TT0v84iuDK{9v?UIRoBj#;krc`XON1c{?4y1CEdjnh-X+MCk;s^zRxsF z`nRv4gXr(E))OCSsBjK>BeT9H+t+V!pD9v(u*f4@`b2*aV^Z_b%yo&EY{ocG%3l5I!LiY}=n9z7@1Tzf%(BnG{auN8t^;49RhAHpsF8@iH((+BHy5WZEAI#70 z4|5czd|Ag-+ zR%+xcAI`Gq0JDcS|MH@7ff~Tt z^EqGU$G&?*|F}Am=Y$0}oW68uWA~*Et_JP?oXdH@PdRk3|GMDd0ao_oAy=_SPQlzU zEHrFsQ^p1Ub?-ghsrzSsx_znPfC+Sj9o_A}Xa6`g&itd$wci2W^8Hm8tKK3$^5P_S zN%f}gq=hq}(@z}s^f!RdTdj^E?dv9#?T(cdKbjQvQL8boBOf(YZWk#=IM;9xJWR3( zn%n8JkKOnFjJBo(`C%q*L^;fN%_i7JHuv0uK3l|1h}oHMErAUvuXMY1AJT0-S0rtL zZj>d!mnlV2WfU#}F{+`XYHsRmvXi{a^*h%QojlyR%FcCj!!xbir!9nQiph_6K78+I&5v>q*2}^mAXd{*v?x^q)VX zar>mD^59YUVFS*eXTA9s7|V$gTR%~0s*{%-J(e!|5YrmIr8Y}5tu^QY?FVU0;FnGG z%Up&SHht~>dGI$rbnmBC#FHd0NSf%qoccAJRx~GL83l?bRjK8vycr2lzq8$D(puw1LZeCPeWWV7A zf4nRt8OhI`Xq-g*!ZK6yf?mkO7-#16yXAAM43#G``WuCG-U<)vxaCbOu zB)UaI*&}=0&l3K*7+xkpjQ~%jhliZ=C?a9Qim!RLA zxXv|wuTwUm9ZAE|bgxt=>xa4Nq4B|_*5K}Av{%K?eH73G>L)`#oM=ZPXanun_QXXO zvT9g$LM6^2VYlMNGs-Q5c7d+L&qI=M-jNF14AuzUW8?4hbd8fmO=BAB*`B5^CH{$g z@>7RR?S#9?gEuyiKYwz+&0<>eWfeWse6hV9^RIGp9R6;5`>o)$ot;Lz6SyLO)VQ2U z`bd(k&DcL^?6l%h*KBSMpRqz1PVeG}$!5foWd1=`r7)a%A3r=@m!nNvsvVxVTr;e6 zI%UHlHhiaYV}RQ6$FF9YB4;q)r599xOKuHx)xgOIXC^h!nDXKY*QDhc!>S)M;y@4$ zgTBiCHsQL{+o**vp-B^7K|V(bhuZ!3>bdie>Tf-Nn||r}9Sbq=g8;?Z5`)grCCLmUT2>WWThSgQf*W^*$15a1*m{vIg z*&4CM?+Lb;FqepClFX2m-BI8K561v&~joi-SI z|6s7C!RJvtRwAG8aCZSI{ zrO$6bPOkKz&44~uUQo*KP6`W#q>#-(I`Q*>b-4Zo*N^b~E%@#{$!pLa@AE(2$r(B% z$z=?fw-TMyvS5+2?N>#dTZ2z##sIHZ_2{VR+|IE6KeqPH&z_RD(Clm})A+6hk9j|NIQT zxm=b%=$tKsj;Zg>#r0#npL%snWqA;7(iCX&M4Pvd<`UZH))zIUaF7=`)KBf=>3g74 zh6h=S2|Uf%@BD1ccL=A{KKhNtMGeL;)k?Cnp!$ZVgN9SAmCP9v){>9-@AQ4iq_-OA z-YJXF0iItm&QS^4^e*-g!k1P$kU}z7pTkurTG8S_U`dbRcZg|%HByD+EUW= zLMazRdZ99?r658rWoIY7fPke%C~1+>BBJO_gtSIvAS5m7ye)K7P)F^&q~N^%=FD$? z5p|BQXWrMHq!&<}fpQVcEu;kz6_vIOUOC@qCsp*!?|jZb=Z}1L*4k^Y>$9Hqtmm3` z->K#`zwytfvYO5#fLWXki=mfw5cjerry##zn+F-EQVD#M0Q{@2dC}30bx6CfvsqJo z#5-L+B81TgTCatliJ4R%t&cD^ZN$6yOXH0m+`C*dc@1_OH+J(hvg-OfP>9@p+C#8-?iw=7blm^`=yPx>7E()gwT(S8r2r^1u|7I z>p9R({faLH7vd!F&FPr?5&sG5)5wDlhOCAr#f~lhkS4Ln%wK5iTjR5KYC2Vjvrc6! zR=!h0G7h}BeB6nzL#|~yvs5l?KUBBufkQTad*=OZ0z4sdzvyA#OA zIGiB+sV0)qoQdXuGs3cRrQngfvAC$U)zs^J~}q zew@p-h;Pvt;5*fe8>JkqW8ov@9FLA$8}7nUJY_-j4xO)_Gh zfInk_{%1m1G=}lN4*zxd@BUQp!?`z)H-CtIP;dWh73!1qQYQ54yr3Ov+!}d5>{m3` z_|OZECm}b5zGV|9jCIhxXRP3MxKSU2o%q-g?}; zI&16;mYwy^2QEs3ZfpwRrWCNEHA~VQf4f&(nJvx4Ivm0r+PlS+kAxQ`HO{y$^Y5Y8 z`Frr(nUTeE|9r~*m$Bgx? zx<|@DK8N{6+s+KY^LN3q(9Z^M2lnFnelfFu{dDQCVZ@cg^DR90;rS+>%zSqf@#XG- zoe>Y89KeB2uF@o>1=W-L;YYcD72lwT{}$2-$v|KIA5B+yIhTHWvx@wv?-Eh~KPsjd z^bKavL`+O+qPwfLqTM?Ue9P?lp+Zq+h{oR3B)d^>MkAaw2w^ zk?)zHuTRLiSE+Y~z_#RKUicM>KB5oz&iV3J+e*`XRM(wB`d)ZWFt>Yya;3Lce9>EU z3O3Xaw0pDBkGq$(dkYc2hx8rpIo9sogz+&Uz5ZCY1e^TS;qj0!*Os(P1+d%A{D|2I zUm1jBb{_o;@O#U|AlE5^esa|eRV9Hwb$8ByA1dVGzX+IlS74-rZX$h%RP-ka_4$UR zV(#EfDF7TnddQ9n_=}OB2E0Qzrxbf1bq_w^mfi&25iUmTDV(JXP(RU*ybNCUGW^Hc zl>}YzaCf_uhi{%a*e>}rZ)n$`uVFuQ`BqGqE}VeBe<4Ha?wc;%crx9_y4!(opSEY9 zAA0Z>L7P;*jJ6VT_#E!w45dH6M}GyJKO(LDlCr0djV1%DZ9(~Z3-Vm@i^Q-qfs^NQQOlRs+rem5%g$)kd*x&Zdp zDS-O`^!_?9f3!#6?j2?O82#7!E2YrZwe|JtjS25)D^;{d-^LxZ6VG($XYLkeOUt|5 z@U`A5WuXqj^ZyCEYn-zz=+7`S!~`OK_5h^=M(}cZMgM}{i+&Sg_L&rYkq-2`rbnFD zfid{uCz}JV+_!iQXkoYXM%_g3dW_Q}PrL@)pfTei^X1HlucqYj z_39AkP|E>F$H{!~7~P05XsjL|+N0pp@xaAA$_A9OpnF2Fr4~DzlSN}S(QJDT7Nh<> zQt-6XhK-n45%22!dn7OR7?rWY4o$Nm!moG`Wwkj6?9@&< z#=8t@s!yA9(N5`o!Y)bt0Dj=hcweK;OR1t&zcjz-o>Cg$`G?wh$o!eCuDA3jL5GxW zA=*y8+T*b1=gvv!)g;bDxu#=OPJ?oq`u)MAPBqGTY8oAud|?jRqjt(3Nxh8QSxWN= zKA9W-ZG$~8NP6N^FXmb-crOO^oj&*^S9sOJk>)>QO#cgWo&)_|bx~3X{(__u^jCwk zQKj3c$?D|4sPGqg>A%U!f06MIRdePMle8atpH{)rw=DoUsnsZ1uFqBc;Psycze*JQ z4&W@<&{I6`4b-0vyv<{ep1{5joV**fBYd-ib{y=gn8%rUUmEbk9BaEY3+=vy^}>7u zo&<%jp9LJipGu+l2K59R{J=!g6RC6s_}To>L?507hN83(`SlwB-ZG;Nf|=HeHSL{{ zOf33$d#Kl z@FQu#So*;iA^Wjf!QDW49W)2fts%abV8z)EdT>i%`MiBydoVYi9-5nBq}`}L&}nJ` zE{9J8;kkwyQ}wTa8ykyQlt{&q;d!bCMgp$a?gVtCIv0ZImS7${5=F};hw@b;m!+rpIFcV|ig?*6% zosrqN+mOG*0P1@7648X{KlFXv=zs3x?Zx&Z?Zx_q(8D~`?wxY`eP`)xcLz^N_Xf^- z)p%+}$XA0|Up1F!*owN(dK>5Z%G{v6Q#*n8AbF_oin8R#DvbU$^qiF%(Wegh#3%m>M$lSD@O+NcLQe_L&S+UC zgHH~h7j&Ns6u+pfkrnG@0sTw-o-p!ap@Yp;rTN(D%7S}f-|SwW;+p__;5D${FA>|N z+i~BI$5RKKaRhg^5AY;^-)g{XMt5ro_G`7tx<(>=y(iFKbO~_Cn=Q}@ac5in_29|v zI}tAvUze+=d-Gd>Gb+=MJ?h0bSmR786O%o(IJ+@i!%y4v1mIVzd0Y8aGo*typ@M8FJmb(3x{uh^DYzT^w8PJ*R{vQS1 zv~Ed;tz+@i(i>sOz5xei=!Z!?En%N|w{$Pg=Nj0IT7YZE0miQ^9t9r=h(SC$woL5i zTK*ephPsl_UnY#Nmvh*6Z;{~GcE6Psh;51ZtA$56(L`Aidz;EuD=E<;Yp zolYBmbPb&oxOX2LJ6tQgELpJkJdi)C4zU6*=<;5|_)PM>%GoSpe%x}lLQ9a$0sFk9 zPJY>SJ`) zkjy@SJ0!or(lTO$CL%70Ntem-LG|a!!9adI&o`k-Np}keIb&HM-Zr#6Dr3I{9cRSx&L!CC$-=lZ6u;7JA#f&eSat|H>L+=Te0iMnW%Qq78`C}CG4Y22s*h-5s&g#r z%HGnrx$bf2scfSJP zc?x_NVtj5TzO|_-2mkBjT^7>e$y1wt)OY$3w!3%tW=3I~;5tv8@nabUuDk!g!!?bK zS96>j@XQ}~dDCs&AO|>C;>-cR=Y1oZ^uicD%{|SfG6%>{#ypf^4ruOeNI%+#Gj;C& zVr;=Z%Gpl&v>!P2;C)<>`-xEwGQfdkmv zlMLJ{wwKffo(DdzS+ALxIhXEcT9hL`qYCGg2K6dwdG&e|^a;4-rmsxcE93__a0u`O zzk_7A?}l&R0l;w}5Xqx))FMx$G9_G70(?Tzp2_`kWij1*jvZO)r8`h+aoQmHqa=E* zjcD5J1HgH4M<`&#i1NIt+IS9t@SI<-n zPkH>i&FTQ}$gz3^7AP+WE^e2e1l~3Xyq?MMF%1|M>AWYMRlK9~{z=@=8*m?|Iz7OL z3_ME~6z7<*#-ZCSj!|xM4gRlv9V}6`+Ao~E`?FS96q=W9s zM&Rhke>t&wafXfJcK0jm2;CRlDd|iAo&&EN{*}?seDu@A%}CG^%}@Ai?hI9hU48!6 zeu_bDCkMKh?f|)B$`^n768dz0=$Qz)Qc|GI+W{VpiqfFW7co~vYtHtIng4)ItW#dBr+Z)kKFEpx zpchrw*y*El{mRIA2YE?sm#8P4+z&dJ?o{Qp&N8I$p8)Ttw8=6^dUngdldBK0^;p}_i$yRZ_VW_TX^fWcjIw?Y);yB zh`Zs=Hwh+bIp_!t%Ce>D!!#D+$Nzcb%_=qS4BU#uVfvQ4ANPa+_~xL`6~1|(qJ;L4 ztCFkl@ZV#Jh3)=L^e2qH8%AI64(#z#yP`Q!^3a~be)7zRpJVu^t?Aw)QS1cLU%x{* z>unBC^bVA;O^AJ6zqc6vZv1ykG=D9~cM1A}9Tz8h%hyiymLW|#jumSrdhf)3_zH7i zT9K&SZ|l%zEaoYMybjzW)IoRR$bWeGQT*5MEjn9*cO?UmO@unxu}*oVm+t%~z!1@E z?r!MiVSZ^(TW}|V;oLlTV7jy)e7gbM_n5Wrng-?gaJz$^h#6A9FdN0QI}0JLVsQZ8i4L4 z8aZoF)0I8QgrfR^)ocrU&o)N`-cbq4lWadmo-(K{$sUA%wakHsO&eYB*$QxXvulM; zyEY&iHv~1wBXrl4A{*}3Ht=p6dkhC-s_mGk*=VbA0p<()=V#6{SWMxF8lMP zOQo*vX~3E4qJhDfKy&_-;@iJ41pa*Q?Z}%CTVgl9o89@GR}KDfKJ-u2-!!&2Ueuj0 z0#BXfqnd7ANaI(B*C0*29<@IUXP8={71hO4z9Kwr!W^gro_hm;tw{t!*k9?#z;guN zQ0O1{c7)Dl<}cTt*8SZ5@TnJAGLQJ*9QfZ_@V~#oK1&9kyBBibY2eek34XAbNFO1x zmo_SUDH-s@5G#)0n%buRb=VRmEuQt*C$z`LgH9q?y>O^a+KaP|2h3>}!X_T~^|fZ$ zpP-M$=r7+5`2%2^6@%Z6JKKBpfNA6b4wZYyfg(EJ=V0udLVrM}pq$GuS@R^5A9x$* zI^oWb(Pjo@q_rp;hAxN}F%CREz?r8+y(xfm1?A|>qBC3Uo{MpCO=Z9b41KJ$;3?H0PI1og?F;)|JX$jbWBr{Rg z&TneT4FR zVrBu>naNMt^)dsGbR6y#&{z0{&BG#$hxDU)A#9(DyZsTIITU*$WAPKvUEe4rL!YBi zmvQ;Qr>|D2K@Z;AhT%FlnZ706XIh5=)I~HD{ik|m&}_u_q8JxDO4=>quJ)1yAvQHh zhL3iP>u>kN<^xXy^kH{ko_^w!8LRQFg}$vV)mGPn)}T10TAXwL#9BXKPHEzF?s}4kr^zV}+@qS~KgM15oFZqbRAAtviG?(0ld#w5 zoK~alKnY@2g6GF?$!M4XI5C0tYZS%v;M+FWp2r&CyyHWSjsyJ@71>OhaKb_71M%&d zAU;=z_o&;+eQJd7c~jHgQrLbGEk^JQy5>csX&;$-?o{O7tw?u(4^H>i4A3CkEuKUk z`rFBZkMPFB$ zj=wB%_-0#fMh?zSrV_`68Eiko$TxO<4Z0b6!+38&KLf~9%9zK6Q}HcqsC+8(h4nOs zaK+0~@)a>lC~24GbYh=k9cBaOt3Zd)I#HXgsGGmaJ4v60&R6g|O9ZSFl?_4$IZ~Dd z_?~1LvCi;)h~@}7g<9y?+*aCN}q$~f^K2c=$ajlDZ(?-Bbfj70`V^yTl>MCMcUQd z?SDqPqTi-O9%Sv0WCJ+8keO8ZCZ#sf#<=xcG68GzB8Rc zVr~9;(oL{eXW3j>Cl2$Xx&#{r#NYB_%tWhmz{!a*Mok8AA>qh!ocj!XAg&I06a1Ld z=w~a+?Q={79FdF{_XEUsGXZyq^F;|~K(-2H^N^nQTdXtWUkpz_eUJY%w-xx_BTiTJ z*o()#u8CRLD6R2Nm+DYAkG3|#=b{_!TQIk3lz#|y5#El$+%MN~6Qzq8-t~b-J)#$sy2ccu#jL4lqvl9}{RZqSq>EZ^&&H z9`_@n9XPZ(8Q-eGMPHEOBPPS6|Y;8M-G+&`UO)?YU$1V3Goh!t_-z01@L7$SGrL{!k zqw<}{YTHT2HVZPVlyBVa*t1)<2i4z(iqkujKZv)riMI26d3vbvA<%B8;jd4X<%!vv z)u6*z_#U@6CfJrwetk0Kl0Jqs<|Lo*<6DA#wjFez3<7rPeKvIJg)Q?~hL&IFGNXS& z%7sq6Q{qbWs2k+1^OzcCwD^Yn+^OE@3e=sJb9^u2OxO{7%3svSce%YB;D}&s2jUyn zG`QPVLyj>D@bgEZ4ZQ9Mj6ZCK@0!EdGk`;az1M_n!pq(gtjWWG7asp(utq98w*eLj z-eN5J!Aq-jzOtMe`>(Mdx%q&@?ilY|*pI(Mn;j>?XM|j0!(~bt1i^161)Bc8SzW$C|w|6TBN zs0A*jxypjAz;u*tIvXjQ2Ko@Tz+NqARKy8XzG3+09+c@SuY)dXqqJSngrD1>a>nDm z20Cd}&+S5KA8a_`%k0(v1A33BpKZwjkCPSWD0_wQ%d_$`C6{}24R;ATpE|JLtGox! zBcAlg`|nVW1$5_hA)W88QeCrVq+Dr^av!=~ZY;?;2>(2rc?4S0ogC+i^l{}O%; z=J(xIrfXIm-|yAQtg^c_6FiIi>+ucF8iHFxcm+JtWtK<}jqV``W@p?*xy1m6T<=SG*Djd=COrkX>ndcl0$ z!Q~zGi$VXeZ+Ema*;Q_oUy+PK20x0%mc`ibqdWI|DX#|UVx$vpNf#nLhSI_-(l*RX zO^>mK)vWHzL%tgQy0xwxw_s=-n$%UU)ZNVJN|GeKxb+5jq zZXWZZjG@HXv<71+kB;Gf8pB|84EV;6Z;U-PEvi!EPT-wNE%oPT`NB@?NWP3Qm(;Wr zAU!_XC*um%On0yel*V@#ZmEyP5)-ZOr+i`OgpvGceS|M>!}kZT$Jrjkn6_d}>}!mP z-lP6Bz~^49M{Q6}D!z3b(Y2^Xx$jCQv@AtES*T|uy%6c_ThcU+DU?P(1@Ond>zU9p zp{Ayf=$BaZbL6{Rq;J3FI~vE-Thg>9ze3uM{w7EJD|~ama~;z0(X{K^`<>K|@s@T* zVNLFICHTgCFvgd#W{NZh?-FVr$DaO;o#1oyp=YGg2k&SZUGta%>y#$j9sR-4=g9ZO z=OvN7vTb0Bq(Z+Z-0vOK(fmfsO%Q}W9ok@}i*`;%9@{(y$jGeZO+h-QQni!bPf>8j zl%}$StooBxqZ$?xe#73l2Y4X||3Sk!bwWu4rS$>Ms1subW4bh;DRlMmJvv{){FuSp zg;C%|G;bVzXi9$kqIloV&Kzm9bqwsT{^G5HKP>&n#&e;kFgB#`DE^??4BuFHb*q|3 zm)@`BtwXx>BVEfED|E^?Ie?qbSLqs#e{#U6^si(}(=zmr#y?8XHIzsDcsJp$Tlxst zW9vrx*!}Sc;Fs%xcSyJ6ZH!5*hAt)k>rPg9Q)N>j+FuAPlw&M=M@B{|8-1DPK8D0)As@0ntR`>jphVv^d3$ zBYyI(Gc%;Zm07kF_~js;v;I3zyGbTJ3~GyUJia*}p6Kl;dR{8R9fSBn#4|3&|HgAD z2OBBSql_n>il9b$7ugB2n*Mg{z}7F{1x^9&$ejO%yMzjQfzWFJ4Z)bJzr8rqjB{JK z*HMT54D_TlWTa(mZz^qE%7j{3-ky@L=@V zp8@cs;=xN%BhC-b0w+$fVXiN6xC3%gntyea222JGcrVdnxRWV-GWc@IdMN!o@oA@M zmZ`OsQ+BH1!RX25NzJ0YQ zy)#;uipr@_?rzl8bh55pC1~n3XpfnV>xqxn^;6j&>s$+d)(mPJG-^8PWtO$q_%)hu zX^!J%9)7nXeKl!js??Q`ufz9V5@3a76{eL*(o2{>9=By{Qg-x6p}~q&=~( zYqSerl%By|i|$v&@R7y?N6@`agY_Xjw<)k`qgXCl=$sr54OJzW6H-6K+)>>Inp5au zQvD{(L##OicP)oq;f)h4!)LN*WroxUonaP@v*5ni2>X|x+gv}0@2=#^xlFhlJRVhb z1KKCQ`fNpnSI5H!%5#!{jv!6OngKBR8^4qs`0IOv|YLvd?n)V|FyVLszZ7($b&-!<0uLgPl23+_& zV4)CuBnvRP3u~zPcA~FU(4?}XSp`1q!9OCNb_(RrvoLnLWAddlBsF~K=8Ala7O_6> zQ%%)`Zwr>5s+;Kj2>Z_|K(`h?G&%I)Y3M@*&G1|MUahnl_EuK|E4}BwgxmoVk%A&r;KcsPZE;eC3>Ll`O4muC9m^j3`DBfXo#MwT-B^DFu zE>V16B`!ST7v-(ze~iVHApErMp0oET>;A9S{MPu`Yogy|S}~`PlM-)(WMo(6^wh2* zhm>&TzrYiq*c8l3danCn>&fnm`289OxbOZb5jaU(KL`IwFZTJw|4WlnmgL(FKMDf) z4uZJ5{u{u!3i?3cH&xGrZW-P4wy$us6TgM@{bNpO2VH_TO#U$$?pDO(zXU%GthlL% zcoEy-7p&;-n&$39Sv%R*7@YM*eevKA6fZ{n!}5%#Z8(oEVy*C9{N*A|1ALY78o5b% z>Tm~)!F}%#-V=UP2{;$6@au+kFDn5D5_)Y+aIsX_bV6njQ(HX0Pb2Sh@Wow-t;p0I z{Jd!owRtli3^wDA?p4DMK)rCNDy9?vu@=zh8dd>bn4B-Y_K%?|_??jM#P|ZlKX`x} zBz!~s2ELMSQNcF>?bCGd{Ah2{*^vran_HM+t^!|{?xBI+$ajR(_^s!ineZJEgkK=5 zUo513hO!dfa|=p1z4d9=mJs-R#Is4oew>Z(gC`vA?t1=P5jvg3pHp}WkgwAHg~2Bz zhjp}85xxLzA-m>}yr(ql1&0*+*Yq9n6BNJc3vuS7-v@p>SjC~g#5X2AP&LYPa=Ya^ z^2rwoo#(`t`1DJNu_eAq@<){t+Z1uC{vp0e|4A>KtHC)3 zSuf5s778q}=0eZgR04Se=E{vWIm8?#egf6A?Wj2KXyE1Z9As~e&|CWi`lTB5dq37G zOVqT?KtJ|_mTO#yxT&F}jkL}eOU5@4&6WXt+ErY(gYXjnttY<-vFa^)>zAT__rZY$ zYotFOenOg3s%`FspRO-ES9-fjtvhsqHmLzRbJMW*8(|xB5IXGt183*uM<#lo22S{@ zXr*`H`b6)gwG+J`e>~CqBHB*-X;F>e(3xS_pbEbKz+6F+j0?j$FL#J#));( z*N`i2rnQ4VO%MD&lDvX&M5b!`&td{jdIWf)26F@7E2JCen}1f?b?B_*z;hX%v++#F zlWaESFXC)#iax6%y2JJDIOp3)S0hbw2=McqKBSi--HWvFVY>4*q!%K66lwV%>CU}K zTchvU(RAmFNEeKh?@f2MB0Upn#n;Wnan5Ivo)%5JK8Eibq%)Bw{V8^3oYRT)gy{FK zW9d#i(#g@Zd_3K`4(a%4nw?B{)*!7$n))krraLQ<{?7VYRU`aS*IX)dmLWZav@)Ka zbZ05jpCNq{ly7lm7vsdRg>lZF$dc+HH z3iDj00(khf*uTYyDOrR69r!QczYG6O_~qk&_-dSOJL)<{V?UGboM5)-^Ky>l z23fBWGz@*0iLwIz(|42bzZ>5@8vV|7Hr>h0wbv${0xU$^fj-0JP_!MLUz|*E@@ITg z7X3y(hi~AcV#G%n;Rng0cPP(5tK%x2FF3DrWI?aOer19rkxqOVdVZ|;b#F3cLnP19 z9hF2~w)zjQE}?+h*n~DFjr8kOx^n~4sUvNEl8nXspw6@WeMdH4c> z3~Uz8k6QoalHj98DHnEfWWTp8%)I;Xei9rg*ZC(~8u2b2@gPF*-C}~z)TRBA_YC^} zWTT2QCHt?C&e|G9H{rD)D}Im4!Z!_-@9y7_srcH3pJAL|%FkcqIbTM0#JE$D@5iPy zS<-fKGU#A;ra{o^^U&W|f3ZG35SzLtpw;W@wE7L`i?)j!%=<7~YBOs>R`~FNJ!pM0 z$|e%A#RB*(&Fh(sekRIoC9!7E?xDm6E#?B}U1g1&GEWVA z3<1wfk>>cQ12~kqKWr`fVa;Hb3cObicCMxX+u5scwTIz1ClJk774+(BMYfadM<&C* z4l*?95Lk|FGm=W}nci*al|82ZRQ(7BkFx zDbVAVw&&(PB`shMX}-&0l{JN{&8>7}=MNYIjT*Y>4Np zJPD?SMS2tN=eaoVO;|4j&SB3OH_NX{x2X^#A#?(I{eYoMfENxr&(`%c7P}qysUP#+ zc|6u8birN-azc`ua)N2FPDD(4^od8j+*j}|d}4(d#YU-NTZDOKHa-0JrwD88iGY>g z#5P<>g{^iPXtemsv)(biXT5QKXT80U0Um)(6xl-MV-9QJW1DQ$7<>=8A)D_*d!T!s z`>15M(tkDf!n3~yZ&sFyXfCV#(Dhk#uM+pd1pAse(BeG&hGoExpLFIE6rK4ei6*RM zV%;?kc1PqVr5`agMx)O)z)eJll5Xs;X04gVEbgAY>#%>iJLdq`Y@QQqzH)o)^ef|H zCtn${>4n~fk$45}l^^+V9|erUmKSxclSL!<;77h3Vj!_ZUlzos@ zr-1%R7uMP5<~Z#!pby>UkfEbYI_P7u;z`6I_%G7IsI136Y((5NKm4tbUu>Q7UA=v7 z!82ug=y>p;(F2&fTI}mE&xqyy9gIZQQvpyhSZ~QK<)ASV! z>{EOjl3ojwb@gPAnTG$I|M?QK>of#$pG2G*URF6pKiBMrZvbW8a9)@~*c&q5;XTu8KRBH0;7$0*0E7VE)OblyE)a zMpw`7618QbPtt5#IdlO$Gx2Ukjze=Vnve`>c8KNv$_3(zV@j-Z7%FDw~RS~ZX=D42hCawAGfql8xU_n+rue-S|c&5 zQ$_zbWTHvz2LyRwCFqe zy>x{Z5`cSC;I}&Kpi8>6O4INs@YCF-%-84#Z4=OT^2N2%D+8SAAwlC)t2pgNl&QfP z`i$U4Tu-+|`Ut(?teIV5sb!$Iw1e9rquO3>@M}`_0ZnQ`P?H+psY#9P(xj%M@9%8= zRH2cD57M1{32PRc@u#tP6 zM}=Dt>SH;1dnY50e6`cKIecq64?ZgN2pqtf0?tHNa7jT1#_h2r`q)vAm-ggaRBG$e(XJUk+r1& z{Z${#kY)ut6RA$RpAVS9k4}DBv+%ww8%O8XF~czF(uA=ulsOh7V?Kbrsy|}zvERli zXDbJOJDssNHpkiG0=vAqe#1}W31I)zcmj#ue!-*kJyE8+{1b{lCt9!YWzhdyK2_*{ zb{cmvB~}jT4>Ldf-?3d+aGq}#LC2@ytW7-$KNawElWaTdO*)0xqM*eLc=DC`QX-yM z$duGI6CHZ|KVsc|p7?hz#MGgC%Gk}GcIix}^x4rYTVrXGF9UoDH`(_J5#IC^%S7)O ze23Fe!JP^C?>+~fAaqHv=3JC7%{bWw->vP|OI!c>E?+j$7kXfiG!biK6t>rMizoV; zV!ayTRbyW|W1z3N&YufB_=NpAF&BFF;9W1pdc!8LME9G^d?|E+U^i6&`9ZGbtn_7f zyY;^(brqfz5lb?F7^ZmA9F<{?hJO3$kM}M3f@-i}PGSS%WTNY6d<;6?1?y-{+V?8y zdGh?e?>}8ZcrXl_fc$0=O-1*l#jy`usmC7O23d`6*;#K4#!5c3(yke54>hqCmo8tase zJbK4P^H`v=U_vxcsW;l5A=)05y|o`B-+3sX@K$;9a2WmpKf`=#1LfZL9tO_}b3pvL z5biY;&-8->nA_`q=A^x8oHJ$`t??#- zSJqg-8YcqTn_xx+TRqxDkORavj) z1#0lsBkP6lkT;~i{$;YVe#;|p5nVs{4@ezMy#D1#TOQQK$_*jOQhwez=k;8IM+SHd zpC7X&0rPbwZ1H}!c4X}~C~HS|&2P4T^X``a&DzmDEDSnipg(A#%shFj59-Za_RhXDy9Kd4EwnK>uexz;K>p=N?HK?!cO{lgGU4VB?`)*XG#W z-{#0LCt@Qe+94OCeu*hogIwCQm-mV5Qmk6>hKU z_{&~)R6nd2ldf^Nx3JT_a|HMl5+GmMgUupOrRrpOu#4ISbD;JiqCRoQDSop#QV!(<(Z9LKo7VGSX|1 zCVnpQT3nzZ3_>05>$Ud3#J+Wf;{P(iP@fE#C%VC1!>ZE-*A@fLkQmTk&s!osAt&dU zHgAUyXoi?;Ch*Pmu|YrIjdKCCcL8Lh0`{1z&-y;AboJ)11J;v!OSJb*^z9mDs&2G3 z1}*46x6GaI3KSO@5o7%XzKcbB%nF)M==F}m{|lhqba*O$D)A&dr^eF+pCPAvz}JEQ zO(qr>R2|*zT^`)+T>~2n*QodXs#QroBkXcmu(;rfQR_beeNjCQeZO?HVqX8M^oG5f z+C_yp3%9|Kv3hwD^zovtXjM{M)n1^Ey71kO0z!9B3Qg6~4mK74&}{zl1t zXd`$J+9B1Vm?2&9=%G&>reT;9q5VtwJpjOI&4h!};>qkr! zQ(3!rGGwel$V2N(CVFqfI_-K0G6iv^_g>h0ZALkgf4I>$f9hVyM(cJ4AsgLa{gZ6; zGsh301?uhg0)Lr0#5R-vuEoZkrvEOzS?&6CEXf@=1OB`t`p#rmQdmKIUA@^@;4Rx- zkMjZYtPS}8)}+4`{>P-h6gojq+5(Y1l-(a^d(Ro!L&pAe=Om;9(R9r~x^p$1g->b_ zr`xig&L~Z6{1vV;w~b=qgrNgnHl51{k0K#xi~uR zy%*D+{Wm|1*7;Ms4yq%<8&?gN{MM&VojQ8m81TqxK8|BPf|w8T-?i{8WL$`u7M8h& zw*uUG(4p{0gf!mMd~U!`nX}{3I8T_bz~Lo3@ ztJ4Q?cFJEZtEV#8LwT9S@XJYl=4svy@LMFxI3Ir*zk~Qc(0?Xf9g{p$vEL#Y_gt(m z7uxOkWgobrA)g2J{Bm7hTlZC!8Ea1C2kgE^V@a)!gHL|&a^;!IJ&SBWz^i58&6e!4 zsKG;ZOV{h-6kdTEXPB#Q`bJ$2XJ7CreYX;}c9Fi_`dtIQ6YyPM^gH^7zNPQ(jD9DU z4EfkUkNfO3CYu?sNIo7Ee~It|r?mv&Z&dGa{cy8tNlA=zFV=#?I`B(o<^vujlbLVX zR7Y#lC~-$;<}|wA~oD84o-Jz>hwC(|{djjA>IP-J3fV|q z46}Pj>ZFNCKTJgBtrt3~&DA zN^k60#JDA!FWDu10-p&S_y` zx?pRO(|xX0y1MFWm1?nApgJuU90rfB1Ad6!Lm5>!SKwaYmVN-eE+c=$e<$6)jhJ8R z+m{a;H|EuD-ORxAC%;`2Kt~Ni&Jx6ZCS&%2Tx$CQ_0K%LX9zx8BD~qwlCa;^y`)_H zqOmvKHh{WEeCY#6I#=UI@+ZAqV<-B5K`rR~ucS6kh8+uFD;H~ryAI9kXpNt}K zAo$6&*BIhZd>6V|{U_SfxEK5!rrm()R!8dhH>I7Lai!f1d6vcyE;c`r)Vax9*3x`+nLF2Y@Fz?1!?4#@HC@BwREC zw;OK32fs5%_Vv}(|4)1%g70C+Swc7=VN#012fVdC*Du;rp}n=y`_srgd9e4>!T+PZ zZwi4IjJ;7Sz;6t2>4jB^4TM8D+_maHZfo27oA0V>fRlAHtGot0F(EqVi48M+`bTH@ zHehZ!A!4uHR}tZpf!A3uT}brlt$N=z*xO$Roc$R82Xm&5&YA18$bP2%NV3V1J)H!4 z%Z{-h?`c!`GomF)s>UAXg1~{W4P1)3(g02Z;Lk4%1`@?yeWwU`E`=VW=}em>Vl1VQ z_mmgun^Q23)Fa7*aVVc+Ne)Agn;C-e%377$Mmi@hrOzAegl}BJE1S8>8EqNBfpm_k zt7o;*-p_%4U&DjgOSmVJ?{Cu4z#KWbGqc(_i+FL;G3XS06lW8U>pTBbz&$}uDY$h{ zacJLNWoo-|GcT(j^_r&tE|>bV3;hYne0>7lg98TdRJ1{|gOk*kFZIC1dGO87HJl0O zWzo2{2obml*8nb7>6^)3iujkI$MQC+akddm#v33r7w6{))6YnhqoV7o=B5)BQ+if=2$Yqq~$kjaaJ=)IA}@WfqpIsBd1qp``5;BSdZh#JYCE6ExINdojiUW$x3viy? zt;GBz*%jfW>z!k4o2yMWngjOr3EvN^zOSkQUNXtd`3h)Y?>(;EpKwCttR*;c!@rpO zliD}vjyn{BQ&EYz+GUn$D4`yVBa3| z5zR<6CechpQ-Wt2i4O|8QK1(tf#xIMjZ^5wj@zIf?Sx@`}5Y_zwg-$p&p=;x+@u&*G_Ife&lL^&EPyLIFV(@!ALH>+`Oj*8qEDw{51Zr}76u#t*|>*r zml@(|{d|t-8=_&~To$2W7gS-*zCPxon54gK7c!yBk@BxZ%Nqgjq=zzQQfgru&Mu-e zszE2R4beUP&ve9i!WjVkv%BhQ)rW-tZlpWu$u^}s6U^Y>L)T!(>FB$sBYCPotJE0H zW511-L*6Fj*+=U6A>Db3>Ji36Z;CNhz%D(C_mt-{NAk?btBK|@OC)a_@|KO1vqtj# z$Xhs4t~gp>&@PE1Bp-$!0WK&?o`eguS;7nJgPSTVP1j%PhR!!1+n7E|-viMBYy|mKZ8934Lz34MRU%(U; zKR3b;4wa){t3sEpw$F;4dqo3$qVS8BxFqry8gl?X4k^|(s1?zbg))anHq z%Q+`_gw7eNgwi)L#wS9JFC-RmU+j^SePd`<&J zAr1PkwAUzRhzdHN`S9Ve#fEzgWLOM)TqO%l9Q*(x21L&UoR?{SR^8w0>dq(s8`-SQi;q%bCHlpYBjxbI?4t*lJ!L&qDbZN-8?ZXoIAE&v6{4W*b z>nMLgGF%glHuROsJBMFr3kkE2y^a35gco~vTxQi23)2Ic>AkUeacV(qKnxor=D)Ho zm@9Q6UsIadqJ>|0jr^)zBNR0pxWpMVPN_kUF=r=uzzOgr(HQezWtm;-76v{0l#ts& zbOeX@&-?9=WB)w1W(MkHOEZ)^LTxa&q!V<}RMfE_ea%K+Gc9`Dt+`BEV^54ce=_1h zG=6lo3T34X;LzegIpl{=*n`CT2c9Mz&Ef8JL3DKserBWkO{J;LU#&`QXi92~dA&4s z2PdWu=7Bd+jCWKoGw#@W`84jx$o>=NG6{qb^8xBK$-syN#i(3m54 zO?N_Y{(oXV+*Z;VPW+k9u(|^G&NYk)epf>$aPG+Z5v?%}x+{judWVhZe(V2%G6m8HtkuRjoBG$}{V|`rC=$vBcPfuB@ZJv$#w%=FW64UwcSM0tR#TSdV zt2kvU>dfiZr0B#nAIbZ+!)7i9-QUXy&({`~mrE?SGEW%{ZC->5SGB4}To$(UeZ~QM@dYSzz3oQ_fimw+Z0M z_*WKOtN)?OWnNi8^)TR(hbBE%xO~!sg|neYL+9LO&_2z-{ZP@C2aJ$Ks&*y^_IktkmIEvp^%*MPLpR4TKR-5E)C}iN zxP&-htL+BpVvdeYzLH(GK;Ifp_UQ#RXt%Z!4!Sh)0WtH>>*H*fsV(f0T_NkMw^<*iZ};IGpIpgP zti5XTR|-1VtSYs%DC;PLmm<1)iDsMt{a5#wul#$8Kczt&Ao_!A(yZR&(4sF{{+X5p z#A!4MkVOJ629W3Od;>XoH_Xv z*E|9bcFYI-2M*s6JM&7apn-00ot?+IM{;%2L7gzyt))JXp8IdAI{66+^e5v*zF{%i zPnXpO_%+bGK@V}~po5A2v%f=s1M~o`r|Vn&M%%KhRcY`8HFEZ=ao*3A$LLAdkbF|< zo-#~)J2&h}vTwph26*CcOSYB1dt_TF%@gU7j>JJ?>*Fdb zBWHW-sgrTG&5uQ3N$4AoyX;0ggFnNWg%?=%q&o^5P_9xwE0wRmu>$bYDx>_GXnEJU z@y^K(@_WLi65J6_%K$ncW$NvA6JlYSY&U?{YVB#leFmbhA-&jQz&I^M(2vCX1Z%o2 z5obZ@1kr0`uO~F60Va}#SiK2&@7A(6EWapAG?CD_DW%XeCj3KPp9p(C;!BM|EK`DO z;w9*<9O885V?2I4@ge$F+^E_(S;lg72c!Nj}Z0;vF&P8GPrpIy9?<9jxe?9xr?iB+JI?FmRjnMY89p|A7eKsDlOPuzxQt>$W zWPY)Q3rK)7yZvst?d5Ga$8r~@6qJTi3by__rQqh(lmgd%DFy8Pl!9$FNPnJE5UTvT zYAc@V6<=4GK?@STMLZ{IXzS3sVdw~@KyROXi3jjM3I99rG~nsRGZ9Z7We?WetWLJ1 zc=bq!AJ`>P+&*ogNu{@9{mG{(@+`;$?uNgA+!v#Hb;zTAGm<|W`LsU&$y{Z-(XVZC zqVH`y&1UG{pJiTOvr}zAP z;zMq<6TPgi%xmM%%xrsh>D8(;gs)eRcV2*ujre$K^p$j9IlSk<$ICwy2mO7l9oClk zl`)eN3Oni|ybd*J;nyCG>{I#tc;{Y%Z-MLzR@)0>i>@rSaHuP>o_H9<`#6Ac4S-k1 zFU`&G=xvjz?U3-h%}wSfU>niy4VyJBI$iSR4BdjurRZC&ZpCF0=a>M$ogL+EQsGyk z(NHtPx5xj4^kr>?CSxUcH>q;CoD}HRmy41&6iC`vf#(H0m*N@5^8q~j@l1p~wWNFc zygh+7ujy2)H2Xp5j)5nUugv`h;I=2QFNLOefS0(X`ux8FH@dL*Nq4}FHdQ^QCeB>5 zUiTjKRn4LGe>?;nh%u=Iwq+m2gFU7H!y!vDR{|a4HF{tC;n%%;jz-$zqHSe9_!;pEE57_y_~M&?w9xnq`<1$1}IgYUh)74W?Wx|+tq9oOeW=caySEDU22Xv{Sm zHgd;(_x7I$3;^B~JzUItCgy<$f1G@cPeQqumSg{`kIv78d}tf!a9W!>obN=_@70+) z6`DRc(fjs_F*ZYBrB{zRBsy*eVAB-Hkdkq}gjR9&lvW2aN{S{e1YfqW@CuZ)#;^Xl#MKS_1e+4v6Tma{K@x1mi~euc-afpkD%&4F zIVVZeQp#zPriJoS(zFz1w1A@4h$rVHX$loed8=)e+7`soxzmxhlTn0_vYwHCVkTTsx5%>*MDQBZ&d6Bum-BtHi}p2 zoCutsH96D%bY({CzD}H10A|xt+*ds|MWKGDzCT5Ib=kP`Ifjx;-`D4!h4DU1_ZWj6 zfSu@_Q*D#O;*ype*t1ZdHeq}N-CSdhDxQpnwXLF*(>gdXv0OqqE6N!A*ersJ`qzi@ zgBvEomLmf`II`tQZ!+nG=cId$or{2GiI6YZ&wXto;+%^izq|)L?gYM>Ggrl11PtskaFMyYmN>h8YCmZc#!#K%diSi;h$RK`%UIlG-JTFiBT+BL! zcrGa@yBBs|dxa*Mf0xbrT6jVJ3TIYHN5_@F^5B&U!dc-;rnjMS9{h_y$AtQHA&aaP z{#ciMp3S;#^jVH*k@xqDSzkmjwky&j+{&~e&<*d~I1~EhUB9xi7qMz4XWRAa0zSD2 zcLGD)VD4yo9`INJ&u+j${`~2TmhA8SU#5M{oM4^oL-X2kj|zGbb_W;9hMszN%&u@g zaE5Sr5bX@EIsqO8dVzY6_AF`nx6&lw0Ag-nJZPN1dII|MuyL5iBnp^KBIf-a;Cm@_ z0hs&Oa295SZ8-6#vH2gvcWPtKtjF?t7GVBMvjzzNYfy(s^BMY2r6SMxLF&En`gWim zPHIz3p()qu@qcIS?4^2+W(^R$R`mTG`~bhalyuu08&Y_K35@c)i7l z^J+!?b*P)_48?TwRL8gFSn36hoP{+tqhk|nd|#}~6AbM$)hA!z-N}Oo)UEOX#3-V) z=oo&XncIrOiNWTg&i6j*JzM$r^=0-EoQgX zdog<*)zy2Hc^CUkWo*xod}LgC`|2wd7qIr3fyvNyG1u-7>s@Sb3Go^1wP^22cZm05 zkLofPmXIAU#p!abW6#d$(tXMT?@WR=nzbZBo{up}b94oF-I0tKg2Gn1Gs7-R8xlxv zkLW(_2mR8(59Zh%Alhqkn%&w6^d~%Yq)d0{4iRP7pd55u!?!@UZFS6*Q;vz#seQj{ zlTU0Mxi=0&b=&`)V>?5(Hne^S{z6d`x&(l;LY&OMKo~oU$(Rv90|jI_=QR?W}_VXme;t;5`L_dNP9f}8x~=f( z;6F7!v`1luAK?xZrBC9n&>rPw&@~-=S|-ywhi-^H98hu=;+r?G|K^d=Z??w1*%A9D z@7r(Q#y9^%JKpQt0qw{w(X}Tm(Y3RPpGI?M6?9Qgp(dj5$St6}ZnfrAHF#3)DBOO> zgShjxM-hcBF&IivU$dAKhXM8dPSmw;mg4p87Ijg&ho8_fqrmUfwXa1zGYYqyBA@=_ zBYTv?5yYx-=!cpeYhrb>5BLjcEJ)sM7PDe?s)w=vuf0<7Iq{^vsgODTcVnXy;^Wf! z3D&DSCw9kiPe*p)dC|I!>e{95SYIuQ+e`*4Vx?;@eRB_FXz&5ToiY5OdrIwy7f!ka z(jmK(mcib*x-J2_7d><@hef8G;-^xqUAnvC!deYwCYCTF8?zhBflh&RjL*S;kq$J{ zjPcBX>_>X$0>rf0&y4r!N6w=!nAyBFhLm#}1;>VhX zI}QCMucOW1-j^dMhF(>^dJD3{b?+XLzJ2!*-d)BxropfEh0(M==2z#Zb!uW?$p`O@ zxBLQmiZ#X@OCLUl^0VN}NV`HGYm1&8JTl&*p|c{y>|h~R|58o2JA2dZA<&-?)~I<2 z#nSc5%c1)pN*(0MUr;;RVnQpFvF`?qR<-uJZ@wytf0G8{n57VNLG=4Nznv-ox3F>2D`(2K@zWdHo6n|IzPu?{Z$KTEWC-30H zIaX)>KY8bd?Jl)v#k&Q|$hT2^4kn!(Z($ZgH;R1;?VA|v|42`$?X}cjgSQ;}I(+*@ zgegyh>{n(ex&+?}*sslQz65${6wGoz=q#Ogz|PU@g=|rd`3gmDmm9p zEbQ|{!7A^AoX6t(KJs0FSlVW^O?B{xMH}6VCVed3^}bX-pw@)U)C}slkBb3Hdzay^}TESy!En?Bt|b3o%CTm6Cj5(>))8b z35ktK2b!=i78nkGnz{gASI1^KTg9)a2KVrr;M+K7U}R(WgwJq?I4RtubmGiKiQFZx zhW&f*xtudT^4*L2Lfx8HDz8HOVoK|krag!NHJw#DzT?OfUHr;S**eJa;zha8jrS#}%EDcPCdv<`R7aUO)_ipDzEr8zSud>Q>f!_RR7v(UIy}G-nlDryGf@8a!*yvZgMy1cft)nsM`k{ z)}_!PT03?W{sOjtH<5e>-)uw||BSI-2AjaFjyc$WGeJJ|NBBXAzk6&^oc{f~6f^;` zpLQ2BMMl6xwr>*FZ!*qj$X|fF$wgvwh^8*}f6!Mx-OqqipOo+n-L|5u?SVCua_|D`dYZOiP%5{NT9q z$EvPW{1sy@^iT61M*h*!yzl%pZx`}E9L=j2-~)+dPt1WC`o}crSHHjSJ^8%F6g05bc{o zaW+p_!3(SEXg>6yy)R+xwK)68#vEDi;AeIxiYsY9n-G1nz;NhEIZrgmYf;7^B*?W$ zw~DvOUFw4}^*va(wT;rP16$kHET7eCKpS19MJ-p3=fUsvjm?vb;yxe>-@L6*BhF|J z9>}WnlqUoWPbDBWy};;I&q+pLGzR!-*H?7M&bJI@dC*z2w&bF$$_L=9H{rkxDX$(e zd!cXXI$hYJujmRUWBwtN$&_b=T^hZ*xp78`KA0ou+I^UBwrh_yZNGF@-*|DAwlR2Vj1p2Ak*^%ht7oQp z+mT;}JdGpMhjk0NU+cDRqdglB`Hk$kH^FwpSnDfrs=Pf)e7eIp?7-R&;jEU{YkP4V z9|EajtYn-c>*mMs59jA5?0r&_(k`1(|4Pg^;a`iPDbZNpRPe8z zSl`eqYI{@dK3e-iHGHt9+EwD|5$24|!vs@72lgJH2YtV-Ie_!Hx_1IjX}PZ`7kE)s zR!ZlExzHWLHYi=ezOqacN>{9=?39~;ujk;GBMaw~WA8O$x>Eh;9m-(pXS@m-%7{6o zvKjxZEb0-ROfVZiI`=Sk{ZTQ6Q$dsB{m&om|1yk?5421J`tJjN$L0hw9fLb!kiX;% z!~tTQkXPW(j%+9N9mzc5QWDMwS=b}c9I=D`HeZNsA3IMVSvod;w0CsshGXLgyVHal zTIvET7%$Dkvx&zUeOK^qcD{QRT5D(oBuh6{GoW|)8?w^g)p-$*aYCms& z+8JRZwa|rWjwHtlXdsQhwvHF`NBs{NUNyR_?et!lc}tD*4oD6J^3}K=Y+Ro zzwsN+dPf$1Jt4)-cvDb6jkzB6J_36u9_PO%?6X!T-G8~TG&M-~9}~+?D+cU8$ZrwZ zW33kFLeDT)KHzb+Ou+v<{D0fyX)!EI*!EZCRmztXwWyxTmM4*a8ToEcaf{}j2?NQv zv$+zsRNW;)%MU!7;JC76*?@if4W5MHghdku%!MY!qM8)L;=F;2QbME2Wl~b#GAWQ< zy=ej!=&tS1?8jI$5=~KBiSMs99d|x3s+3`g~)SmZos#| zWH)u16i&(;Fn61jT*Pq6_HaQyY*LJF)Q^;PSIdEppUX*v2W9EQpXGgXdJ^bx6ZFba z^dXEs&|ZRMU>EXhkni-kTNvycsE;oq-;FWQ~xbP1KW&oG65zEXhp+9(Mg)KoU#v!c>@Zp&W&n_%t%E|9k z=>2@z5@Hmqm@g+nuTC~*tdK8p0%G^Ujtlo|>xW@S#edCCC*3N+J4rINPYi?iI}i&1 z^5t`m%wDEEb2!@pS@T4j@^y9e)a`CA`k29ZsZ`7ik{#Cbj`a3_51ZP%s;wvH37U38 z(j%A1|60H`rTt~QKap9MI-GvgU$Eh)IGe}4P|OdbMO!RnG!F83Y~O+Nx?iF_#>oy^ zALQyIp(kMXr9EqXGf>YhVTYE9wKDULwO}8`1B0&GiMaLdVkQ{cc;~ZwM(%u;#(OpX zKZ*a?=L1KbCp)oTzKLf3t`lP`m6?OlkuTo3Tli)|f1&H7(=##n_4&--F~U@aS#CZv z;|Sti3t5QI?L3)-SZ{y3nE5;IK5c6PWVgS@%4rzJJ@E`9J~$Xre=2ju+SVMb{jd8` z?%u9Xzd;#m4;QooU;c_VONHr`e?wZk5dL-`$1|bV6}I~>Is6u496@dYA7b(&qO~6| zvxqUQE#z89qW}K8nqglND{}Cg{_lz{l#lVyHYZ^}#$o?%1s$%2>{@*SHrlwuM`db3 zvn`<65zwew=%D&xcX}RomBN-d7COnbMqy*O1NM;5IWpSwLz%zl zm$QRI_D`1FP<6KQefWIWI@(+lj{T=%m}<0ViqnT4o6OoLiKd}rkpExDo=B2XgL|u- z>u$wdg`Bq{4py2yTE;fckHEh*_AR-ge^m(gDDE2V4+0f@?B4YTitkm1d)fAPOXBa@ z<~bhtAQb0HQfRIebu_@)4*Y}{`5S7nE_C=GhL6x({P*KOt)G4P-%bB9pRjr*9D1w| z`4HZ9gExdq3R|+@=?r3DS(X61Yr+XFzR5wE2pLctVi5SZ5x{GL{JF4P=`%(4KUx z!3^wapOZ|^7duVP8B4l@>7W@@HV<{(h`KHKmIqxidO%Cw#J7l}a0xipi~a|pKhhK$qCUSp!eu9=Qo?o!XlTm~J8%QI>F(=v?Yyld=nQ zL(dje3w|m~-*TQC2T~WI?E|2jsE@ukqhG6+!}l%9CwG@xT@hE8R(da$_Mzu5G8>+Q zz1SDv5u2|@+D11174cRe`@7hImjNqVm_3l-whj0ecNCesFkVEPFh11392zV1H;vjs z8#iH0XJQOeF&-AcLU5V@=LGbV;yYYCo7va{7^rOVQjgz)@l1=Dl*x-{4VVBkjm6C+ zlY=*ve-Nxhc^Y#6PD-H+g`z?Th+FDTY?f2}0+yR1%=q}BFjP9bZCiKOK=fF3dCxI4&SFzY5 zjp?Kg7RF_{k*W;Hml=>V@r!2INd_IM#{b?7=&zoQ$$hVmmOZf$>*PfG@HH9z38k}``Xr$sVL{qX zey&r7v$DV589sa_BAAC2aj!Kv`=^D%7Us_IP8F)m7~yljSV z$1%S?8IVWy<+y(WJAl{LGUfj@<)ynE4s-i+h8>CNRsMoaZl(r2 zp%VQjA5|o4=s||40(y6}69wE6 z^kHNp$24P|ZAN|%@-zlSqtMR;gNm34=yM_7J%o4NkR7!6&#Lh8;L;Dw!vAWl%?M;D zu~P6e%PqqrupiJC7q;r9oB@kuZZ}6>1zfgkaM?(Pz%zo+guZ8k{}FtwCwCw%Y>qv* zpbz@@+LYH9kZb|J@{%c-u2$8Bowv!_u5^3f3BwUTCI-i30?CsWWI8RN=OhzMJY(yL%LEhQCwzK|E~trE6!t#wX2=(e zJM9eHVNtR$c475#nJwm8drhztey{6Oq7&90HW*Fq+s}61C5OQC`yeL)mzcVvqBQ_p z2(FNA)rMYEUK1?s&7Jq%ouqwme=UoH5W zgz}e9iB@OW*%g%{F}~IhzDB(4Bdjr^b-t_NHqNOV*hf6gVI82gI9|veFn7Irji)6S zj~^g9L455d(2X=2L$q^q+4!KnWPC7nQGC6Bh50i92IB{2MMc|G#=TSkKa10qekj-l{>2|MD=B4nwi-{Fl`Y_>)R(dEJ>}niZ}7|lFEcAM%M3xj z$E;+Q&1}u9=n0w*#J?{B>{JI+{?H)R;R6g*-d*u+9jrSK{LHLOM_&kkdAz4Rs!0Ic zm zW?{2@FZlEd2{DFLquplc>QbSH|6Gdi?R}7qHSh~y_Qd%S;V|u0szvBTL$K4r8ggN; zdja`w7_r=_*L}UW>KSSt7=G5bghIEIi;ZG%mz@Xk4^d zLkY-d;a#^!fGiEYZIKQ5x?f2smRi#yXxlR*1{>i`7T_}yoWy^^c<07C27EF4iD#C` ze$XkSLT8k$z|&cR?UFj)GI!mfA*8EYvtnJheIl(Lb;&ZHoR0{w#1O?6%XhY3{6j zbF6=y@`$~~4Vgl#mWbF}P6Q8Oj`71`=N+=9YvMJz;(m-ZyK>@iZfK%%d?kE`R>5`% za50}uTo-lxO!k0g(B5$q@b9<4zYfTOgqtq>?*wiVUgqIH>0O9d>V>WAX1?bu>ISc5 zgv5qEypQ001o)nXeVa)%g1#HUBc0%xxqq<$cXfiV-i&ogJaY#46W@vd;FCtI?bL4L zD6cer%PS?LyFFqY<(2zKc_r|7WsNKes;}a9IG8&NXY`W8g^|;57r@SuuIQs7x-K)tXb@8D#Ex ze9(Bv80VKC7!|66>h+Yn{bS$gJdk-&S036Xn3Bu#T5~EogDQBgsV80+)sc$tH{*M1 zN2rLy5TjQ@{Ciq+M6YyS5(=HtBa z!j*LJLGq_inN)b0Y^ElHPm)i#B%DQ%zMK59zJNVixkHxe9Cmq(FY@;Px@))o7K8Qh zS|PrN_2Jxtbn#orZUg%?sni_QLpNLv-J%nED%ztY;C~MOcVq3*KF$N3@rTIkuxIPW zIy!{+0pt%sUe&u32L6D&F~Wm)+|#0mZI(&o70V&yu}@1c;uXG&hy0}vW2xg;-%ewahdj}pF38)Y<4s5X3DEBrS1$6iPCf7w z?GrrW4+c2sci6+H0S^~U6M4mqzFN_Lf{D%=Qt^x@IFTQOjm?h@J0hZFzP1-*zq1$f zf)B;{C;Y^Ke;xt<+>!Y1%FI500qwK=nDdn5@E?YlI@m`w8^K2*t1*Gd>_Wd&+@?MB z0{kLrhr;e``IV@c^{Yol_hR>&|8Xz247_ofwZI78cocX-ywMcfiy8lydoj~>e9?Fv zUo>6Yi<$oEUd;H<_hLuCpD&I_A4^V%)-S?S#>6UA$xR{4=y@6J88J6{?A63k zU29cY1$?21xio%s&b4>r)oW*BWb06U^aY$}y&z|stSLKV?>L;7;Xe52xz{|0rJVu2 z)POE+1+Uz}pI*`jIyVpdzRMUl_TKouk9Y$4R;dLJxqw5o=hGukIAx9Dl-RNea`Gkm z4?gw@_E`t;{{V1}WI`Ws&5yj`T;zXQ%$L)9cqIgRl#{ZsU*Z*GC-OLZnFai^9N=-z zigSfg{7NgtI>TE017vs;a8Q)Sx6(7hJ<=DZ7RSH0V4YIEX5ga}W%;hS4l(IE9b!y> z=#8|!0vU2lhse3Of#BPuL$pGNm_0!B*xc2wkS>DcKfap>zl`e;(*Y~35&JbABIp2M zH==FR2Uts_LsS`W55bE3BIpmtzDX#&X&}uNhwmonA7_+z$LiLX-PCG4j6Q(FC}z|8@($CDI-O3jD8v&C@td*gevcEv0)X*R&lh1&mnUWKz8vdgpC zH>c7b?n!=sG3{~IfWQ6QLy(cX-QT-+%lj&+{LtcW`BN71k?Ng!EcxAS($i_4f`~v6t;rkIlhCuos+Z! zBe>VhhOGnak`QExc7^oiCQ5^{#Mm9FEDgM0&6&=@?*{Q4V=rsF3ctD<=ru*?-h>12tqQ$Q z%&v=UmOvL-^uZ5#n)F_Dht@wg<=1S*4!IO^xqn0SPZp%)L+S6&zyBDsab>PMZ~mwD z68%2-KQsA1V$s$w=QFA(m?QL{GO zM6hFR5Ppr>8T|Ee!X>|qJKQoWA`TP&8yphPM2&y5s7!g1%9QQVPcNZ!{|m9QK6woG ze9&A5ckaj@gR!%9u$kgB1PvcnHx-6aJ_~2_lQ1u*e=;(`;9%3C$JoC6YErp-QQU@1 z{cx)HdF1Dh=9w!~y*rSfH<}kdn)L@Vn>mD`9}f1onR|ag|qPt@bmo-k1Kb8 zCschAcpCb}vT^Em<;ClsQJ(DQMlLe;-M9yiScZyrzF)T+c9i3B@11lk%h2}Kdq(Zs zK8?4133vLZR5A>2PkU%`8Fxk_OKVC>1}#sx~#_?1FNWw6gjlPA)ZL-1GlP~9#exgkk?sE!4mEf)3BUlr-2Y*)2>xSBn?)uE3rL0swy>aTD=hGCvU zo?E#8u>|$UxPP;?-tBtsvFV6EnGD%s3(C>m&LYwG7_0tJ?gx$|R^a+Pm3ip!#-?YJ zKN7RX3vbnZI@0v)%?HMRI$r&89pMR@i7~h&uyB{i{poG!+ulx z3w&Klar;F6rys{`0yoWLZe)ZbF}uB(t&fw#-D~Yy6UM0z_fU2`oLW8z-+uYpr%S5U zN4Jo#a`I(44{;SF)Y()WI@4F;>oQ`E;BJ;yi|?Ro)#|W@>AkZ$d`2$_Kc}-LM!3Y0 z+?zaqE@PG0D~vEnYd|?RB3@xT@eAp%u-!;|*ekI6`8myR?UzaAWaq&wo93lE7VJG& zV)xmz#7(DsP9J>yw(a6D4>b}~A3e)9_QR(Zr~2wMin1y9GL|ok=ljlb zjUk8BveyY(9u}tycW136o37Hg5%b5XEBNchN3-^JIM1*l+rZd6XZQ8*YOlRJ4}5jL zjd4SKGO`_QT1;mSTw^X`jgNgFD|6(!G9~dcli&TeOh4U8bq2b#da^1*NBoV{Ztv2$ zd<1oWP&t>^;`{&jBB{J;wBPE{Y2H_nFGKz>G{$dF^S+FH$>@9G$TTlMmLW-q8CBMzgdOB-)BPrQqgPr+A%+D ztTSL^{mgZGvG3Ygm%+w*?ll|hvY3ta(|>1UO=mTHNVG*!S2Ap^L$H6E=Zv4z%mnnfzRF z?FQh9l_(@3Iwq||2J$G@9dMYr9r2~Y_H*}g!UGQ{FJvm0 zAAnyke0LS)EuZ<@qPN|YN9C9fktct~RDTNMkLBV&wefGbgTWwuZaAsjzVJ!~eJ6BI z^J*OD9yXUUUipp*H|kZ~m2ymfc#;a+X|eiY?BN)LSj49vBs;A5Gw=hZDqO^CMC-%m zWsEod7|{*K*3V$$AvXAm5|00;l39}eF@uwvL0(aI#ZK0#3d3!l(}iwbW8a1gZS*s4rio8d$7K25jJ=`#*uL%?%Y>TZir&Otgwdz|1PtV4;(*iKPkLuI|NT7f82d4F;PC&O8O?r2 z`Z&9j3$82cHu5W=5li%SM}Js6tPTc zI+|h60o|ngrcIAC8*JeWrE``0q;{EaLvG}Ch1y9Iafc1_NwOZ%7$1BYXv8)}3m-#7 zw=?R}|GWu)kjQ6R@6g9FI;0BQ*T3$-oz)YVYr{R4DhxMYI=b#-*t@qWv3?%oywf3% z^{ukBPgn{#-pQ~Nj8@oMS^D`R^HjL-LPVTqYP5xKhM;Ds=?WMRE zuX#8HWx|o$rEJi1&JhmMxD)KjVJDv?x%g}E#BeYdc2Jsot=-|+U8uO;o^!Mn;*Ln6 z3Ah{UpSp8B=*PA_z0x`!GG`j@M3HZSM*)Az5!kV*b#-ySa64qWv&3S3mv(G;h~c36BIwJ3O;2ChnT{|a>}Pt>`0V-+Rm0}3lZ56_NO}7l0heaj(i5`zG`lJ z=UDU86l+Xd+SE2R?6-wR`rmNjn>8U8_x!Ycdxw)3B|f+bavq~TP`68DqjhiPlsl`L zGkaCw-^Ttoc7@m+C(6t((lB$hX`bKIGK>cIAsKP?Ablq~we1Y-CYz<7KUNZ|fi7M* zq=m1i-c{P@0@Nj9-;jbM!5t!Vf^cq62h9oAWrz*#k@#&k!heB_=73gKfp2Jgo9msB z!=#WlNHIOCafc@Wzi4lk1&}2TNv2yfk6ux%z)tuz{3iBZ--hF8$)XI@Sz;oy)f;uH8$`4Jlq!< z%7(udii?-MMEaN)_UgRq;K{e66LQpZ zeZD`CpT@C#JLN~;`C{*wjTDP#1>`v%dfp7&Q&<9BZwX`#sU#ypHmb`?Pb*6io2L|e z?A7=CirQdLyV-EZxFOt+vVo=)fH$yZx!7YoFEb0UzZa_OazIx&_v~#Q4pV~_`;LCZ zt;ZVo-sl8v!8^9bUtqzR>MVS}?&y6=Nbt+I!)Au;*>A)D8IV`#SvuMxTgX7@S?Ek~ z&k%gvzt$>G!}HypJHeY7mW3TCY|m}%35zU%XU)M~MUs1NL3>%?SN!6I{1nu;JJKf8 zT{|%*6SED+u-{t-9v;A5F{T>+7!Z?9gL!ChEZLS3WMq zG0^kZMM+*1pNaX*NyGSx-EC4T)sML?MnC93Xt>u^*oGMC+vSUey2c#jn;yw08BbOn z2@RV%5*qXu0tJvgD)ompLk@y(Ffq4&bJxE5&2Q`56P)^?74w$Q=G@hTh3X9Xa?ROF z){`(eyLU;w1?wr=%{F2m-;gTg7a|_5M6w8rH6}-_j*vJ~;k#>p{`mZfd5mhrnisa_ zV!Tzy(+${XFiRZsT$ACKf#iX;4qBJK4O4NZ%q(TQZ&_=ol+YisiegBkpLj;F&BHj) zL;g$bX^fDedzU{iE06{0?(+*jgP-9Q>BE`8qb=%C1=&J{g=gew#~t!!C&u7i`1iow z;&Z^Ext1fku8v%J_X88-cM>r!bRUsdf2rKQV5njj>I6=#r!j0^@p!=vfJ^Vv4O|moaO4(02#D{(s^XXe6*_oq~-B*hAUCF)&b!a=ep&ZZ*-%_Xj2av00 zx)C=;J*{L3rxj~=oAO!G)yvcIJW`3X7ue1{GjGq$bZ3->e}oB!DVIdtwfW`jf1mx? zLVKD)-T8aK1UL~3^hBCs1s+}qi+BG7ecO$;vP8LIuM2z^bIm&0p}vDPkPWjcOT(hF z5@nvloPQ-UWh;HR^{go!qyv?~Urv%K6$3F7?aM z%DY+MHnkssKFbFBLvV1wwT!+g=ue;_2kUcE{}hGku-dh1Gw#SRk8uv0Y>ED-!XZD) zH20l}wNsQ#lz9zsq~kl1t2opH+>QBvN&=3@V8A?6+tlW2ytg^x=QkQ@_24AbL2b|) zv7t?BznOP4SweGz-jN$?FIS+L0ZsA@!3KYHxPR=b8KgcHs(TUte1@D3m>`=ngmW4< zYoB;w3duW_nMk8(*AU`(?4cR#Yhpg~jQH=R|7bHd7NEI$tg)YBT!v|EK$i&~Xd0%| zGmhv0#{68z%DYK+uRWY?r*cUSF?AhM;1yFgS~t}ROLY$mdSZocgka0X_)t5dz?&ZEB@L5|Sz6)S2cZOl(BI$;RPP0`r*EtV7FJFK^Ax}w;tOH#1 zTw85D6HEI%Ub0spc`H}cH!?jB4!WGWAZ$)5X>Y$v-P+*5ne+^%3VV#EdY!s!1N&j1 zU`8kVDaN$y#qRr{ulu&_#k=C=e%JXVXeQZ3Cp0FYyo5Sa1TF5v_zMNp7qcM`Cw!Wq zR@YG-@EyUhXpiuT#^V(s)k5R$2aO)XJ;H-p!QV*!LC0{AsWLFtqQ9{Q-)WEGImX!_ zwaIB1GvW{COH&jU^!~TNW!7Ph;R3A<7Hibk!zzB@?hLFC260lKgbTl1fva~Tc5)8z znFDR0vG3b>@r{M1q9I-~3^G-OA6k1xbc#av*-94K?32zV`s@G-V-6Ft0 z9e5amEumk<36n8-NG~S9>5*A zYfhOj%!0>b9n)DE`qPN9g-m7h6OQ1wo9=6g@z}yRTP>q8r127CW15Bi4aNs!a|!rI zV@2ak?e$@dXl|E3}-uW7mo`}tmc{~X$3j>7jM>ZLOD9km}6G%+0d z2LJ2vtG@59nB9(Vbe*wP8ZV@%JTJbdwM4Lfh;kvo16qJP16h?n94)(Mbgi!rf7?eY zUyg67Et=2Woqm}qVHw=Bir-tue+F`cUwy8S@Sqxa5beMo!5NC}EmI*gG7GHDHxZ2! z>KIxRSW)MqQk9>d6 z?RWdpk4;_HYjZ+))eF25!T*!Mb3#t*w&Z@ljSsWDITF8**pI#>cOvdym&ii~D7%0> z=wR7-q`(!_WoZx=b`(8+>^`Lm^l=*Mx%vqCV>@0~=4AK`tPe}?FY8l38kKF}2Y(mv zc&;kHaQN_01=-Y)p1a&Zcf_jes&UqvjacXKrqB5Wwvh|}5EK|5rJ_h+cVLOEUh6lc>2nm=&*bIc|{^RJ}z1vxKw;yoYA-4dYm~LHn|CIJ7 z$P_G6tQpJ$d}cyE=)m`ykj}n+=J~*l z0?g-!D62*6npxP}(SG3u#7wysa{@HU3LK1v+9=+HY(;$}pRv&?_4M71roaIf=L!M% z(-lEer+`LQSJkY`0=*-7Z#w87+JlVB#&D6o@l*d$FX1Z5ZI4nPRAxPm17MY7`aIAx zR(dCx{H6%HhG!*gqaM#{vF5T=#Lb4h_-o)?7RL5Dzz%sLM#GNi*mD1}$RVu?`C}E% zY5RvNwiKgZDlai=@5A(6k|6RE@!dYOovC{3$WJhMIL@=%WX3i4%)H?Jg^qD zg26qCd3l>p>oGo>F2waidn{64`IPpM;|{t0@Dnon<~=D+Q62$ZnEDf4`K=-NwglcU z=$)dVZZF9{3xO9TpIgz-osg+XPTvK(N&1`Q1Hg--M4oVt=+2r;)p8W{iul^TL)L9n ze_&Z=`=fxT7I2NjnF}M@x+h~^bZSlE(et{qy6|dwGWwxYarYW}AjoQHg;spqhx+kf?v=2HU^7B~)>o_k z#wAF(0!WSa+TmT(*OcyU33)Xx8Enfup~}-JG@HpAVg$2_GWQ z%5GPitj8R1g>4E8dt43TYHJZ=+vmIw@k;R%E+P3LHCRKjN!D! zV;hav^?V_AQi%V#T`tBREdyiHaqpCNGiWvOtq|sb#_7c$#r+7A%#^L(E~hyB{8S0| zSx?cPjpc7saTe48J`$Q>;YF5z7W?Jo8kYZQN4~W7a#DG+aHV1d`wZdgwAg-kVp%M1 zwzuNXQ`#+ z2~7=w#KNVQRwdNus(}}B-ImByHLG&E@MME?!5W#KF%Cl&J!c}-gUKD36UeY*?{YWC zpR;OHy>xI5=C^tfnz(xMGeP!PH5g+ioC`!-eE}Mv%E~;PU%%4#sBMCv z#%%Z5*qB0Q@K`GsIok?fQlBY&MR*1}<2Koa-!|bUc`@+ucIad6=xYNXln|cvY5D*9FsZzHFS zvDX#OEcX5i8JJN!& z#Qx5)eSK{~$sKtf?J2^={#E+M{-cZTW{VByVE4lbcj)sHrA6(gDvkHXqBdo`3LFyD zhcCfz@$(BhijskM`Xx9w5waNq}bmOa^@FXSldl^2IZIlnH=~b2E=+x!Yi$30<;b=)=@X z;PJsWWx|_if0@18vljlN9?^JfL6g~Xb8pk}`m<8kPWdzPO@nnd=jdywN1f0IJxX|$ z#w)$QVm=#cDxmk-h}jvq53=Gh*iyj<$=EZl79)_ znQ#&Gb11X>x@R2fPs6k7(P#9X3EvTq9&0aL$#{Q&GS*SJ39i{FQ$3oWi~L;V{lLHU z&;13_Rq2iSy`s%QvH*Um!oSoJ4L$n6K!r*DQQhv9PsnbJ9nqL{58IjoeVz*4`=>b5 zis9;mrge7ElO*I>&|MmTnzJj=O`Cc(-brFIA5~kVd`Ge|+S4N0gyLALT_kRk4!6i$ ziMI98qpv6d_%o!lkg&R9KE2yB`mO=*vN4{4k?ffMeJaXm(7&~pu>Ln(u2>ITReKjB zp85#KLAK3?ZQ;d(*L@>|gBtXgMV)=yN3+{(s`-Cz4dhF z`)s)D5b%_9;aR}3Qx-xi?sit1gQR!g(tFf9vT=mb6^bXDkNu>eXSMF^#c}$@Ba6=& z`U?wBCJ4O-u8V7QimT-pfg61e=Sf!R3F_-N7jU7Suoum34LPb?$K$_tfoR@zsrUT~Kq z9r;O)tjdh;oysoY3i0feqO8i=18q`Hq`75pL>D2x-9Msjbe_CRwsmWRkq%djQ_==? zpr!i&$3@^N;r&d&I|Xe|K-&+(?#CeTOuCA7w?Oj{mFtCVp8H64D_7hV)ZYW!56p2m zyi?{}iLF!dT_65aJ-Jxp(?;{$A#Q-XCmf`_-nml_qpiD%h7>yC3+A&4I@Nu$Yk{*R zJF-*$a^nQ%OWY4Gg+Sc~wtc#rR z_%|cIHT+lk3@0;(^Bg|EM%6cGIT)W_&8yd|yXu+E6Neet5BUV2FS%|S(}y~@Vof<0 zFu{EoQ;lkF_$;R1a-N(HI3>Um9}nrIbu=#>xdZ(U2Pt2J_xklUCxeg)vH`~etjYfZ ze~VyDTots>&F}_B>#$)gZ1`p-bUXTcT(Rd|F*h&+c57?Z%`&$r9HjTsxt3U)L?4p| zUr`(nU`^va(T3ha$4NKJCw=}(?97dI`xLInr}V-;gkutvwTM;Uy3k_(b#KZZi<2p< z01asZEN;M(Ab9=`7K(Ff1Iz^9*xXS2fs^s}Y3`1JR#+a;F#BM0LC*<>i zPws%Szbl|Th<2+net|bFcI^`*_Z|+V>~W&qLbR(FO8)zHF_zSB-@Ea4XQ18Rpnl3z zdl%3i<$qoRTmc-v#(yi?T7xzZuOGR06Z-p2G(|C7NGgB%@i_frqM%>M?;XtxeT%*1 zgOgx954vztl zACU9ES4Mn#tVs4e%{ zOUe%bcL{WMSoqBeCzY?xOFxMx&{A8jROMLmozilFTVmf&I zB&^5e#EBnH>Pl#>Rv+7v4H?1z$hh_!NlvOv4Nk*Yi7QisS&*L~S8tt)l4Tnp8SvNG9W9YLq_Kbm)cXOM9&N=GT2md*=5il}CSex#9`ntnb6`$`sdqKPpqu`g=3<(w@WN zq&*~GoX2=^Z&Q0DU+5rTyrf8whluw#3A;ALWDT#iF>tD;AS6|^%y+Occ_RW}jC<7< zS+mmCJQaPGaBh8JROZkf&1uV3_3alSL-TN|s&PFyI0%_TSG5m&6wrsWy2c%yU5DJ2 znZb@#8?|&tmSm3kn2SWn84p4RA(@6`j0=!4UPM0as7293uFx#EH8&$~09|3Rrb(U% z9sN-o$sq=}>m=#I6Cg{l3)vx|3Nj$-jzBIs?~qP*Io7mZ7_a;BZ&rN+zZuSxy2qOf z#(|e-dvaP?tl=NJcREubZ)Eqt*H1+_m<&1OGm)u$AiUE_GRXP6vNg2sMN#w6m>kl% zw4#NBoUs|W%&pIE)UVHlEVNU;1l|joYJx#@p1g?s0eX))pnEk2;^W}QspuQ_8cc0R zQ)66)DLT1U;#!S>f#lJCz-}qpsiXr&vwNq)1D=eYoywk3-aiv-m}Cgb$M_5AJmtg4 zYr!+g=58v+v2V0It$8Q-#kA39V?2rEg)u%%Wybh0;rvzb2FjB>VFMq-o@YWcWS8Cz z>I4q4L$rmFpzc`i04MaaY3#hZaV=AMPIy6bcAS<-*G76ruWGar?T=#oz~9!_ z0Jp2)bM=?qChS>-twigq&>tq`>&AX1rk5i1BQss;y&TS?N%y@Q zb!&ykVOz!w>5;;ZT|=(KemYfUDt%$MoyEFp!rAd2j4$Z}vrmyeP`Y~tzFWsW%KemS z(1@H%DP*MGqz}Y8^lC8feURy+u!Z}bBOu#CkIFTRo{%4cEcY^GILNi~=h#23y$}94 zp#LF#5&0|IS3F~z7P=x0_Uv3ScqQh^hnOk8$bI&IanXELUaCU782jdA(00HiLDwx= z1g(W|G5ZwzX&+!y(XJo&A4o4my0u3eV26rSt7?YF&aJX5*iZLmhG0$1DN4c-odg)j z*Ll#1^MaGGn^+Lnua5a6DUMDdU05@nJ>FA;Gc@F>E}A1wnmDwZ&OcVM?F{@bs=yN} zOa7=Z2NKN-k9*VKSAI9f>Vb}Dx)P2Fb1 zr~5xR|DzZnYoU|jFkUwr3NIaZ4^`X-AJn98V=%6C2C-AM0GIRS*REQpC#y^u^wAy( zV`$2&Ic=f7LQYZ9eoc%n3e8!NeX0RJ?V+;p+(pk3kA~u+_z$tEeRLN8H$Uu_{iS3# z%%1YePRw~yA3L4x75CR+UDEvp_O!VFhok?$Th4!3++R8R&VNzdzvBDKoe}qY#>$-% z_lw_Cj{Q*F54)FmyBEa$wD%_%$bZ-kSQ`W*`;oZcI#vdK%m~BZW(fBYpcAC`{&V7f zkipv*oR)VSJT2EF zU4is=q?3@6-4aj)MDDs<;CtZlIf3f!@@*76; z%*DmtqsTWRPjZcLX|eYp^8a$(_lG{Vmiw#O*x3i!ieXH>I>hnjDz?i%>E14X?!o=t z_oV&o{XFg&u(m$jRxNAk9XeL%Ij=laNZtYmsu{?eaLJHOT9b29WBJ z?m?PB&+$GPX&C8vq}dU~ia|CR{`%zkez<&Lc(Mg#YG5~v zd(^1Qs|&$LDCXAb49KZyyB4Vi>0YEpq!FYnQmrc>n~>U&a!6~Dnvpgk)gtXjszVw< znugTo4#+7;ok%AjtwoxQv}}M!LxmMmh05T#vqJmYL`r>cLP{|2MXINANNEf>j9~)O@AjqsJAL_|=8(C=pC>@ppf$LK=e+DZ!>49Sa*$ z8UrU%>U%9x>T>`o%^%_97+t|#g*qO1$pbG_&=(H4#$3o=w*dDb{3`TGqcmiu$UMa2 z42pwYi1rlL-s7-ycLf>^M|b}|@VIk-(_6Lsn;&m_mVr*RbA8jZ2}pI&saTM@;3t0y z(k7p_-H$W#a3B9;AI4zci*dgNWyktNxF#WgeV?i@{^W;YYEsT+7B;x^ zu&zbi>1#l2>|1)+ZDfbiyUN@^^JD3njk9!X^XPv^AM{v{g74Bf`W)!-8EI$tBFM_; z?wAleKPUR4!FeVFnVo^m2YcC=yvA0U>)GCC>rK_q6yQ7CFA$rWU1}U=5TDvEKoR^C z{%`D%@o&~|Mk;Q(F8@4YBFwrjzyGfz6}Id0Nq9e*@@gCGW`x)|Ey-zJU(B)gQ2cB7 zv0$N7OhOs9%2>|~@PD%)K5K@`@L5&)>#XQ|&eU1+)2B|Izv0JU#qOk$E%ewk4|IVs z8u*>EYsbn$?^{%<3F;*lzL?u~ttb5OFlRQQ-elYt#(tP%5Qm`$GNmt+i?bKlhTyKO zPKC_t$~&_QzJPTH|5Ldn(Y|;V{HkH>mN7JZjc=9b%AXv3MDBLq)6xpr{)YE+W%wPD z-AKo~5w{EWq73YxwKykBUNA-B4&SF-UB;GcE2k)l-BV)sDnrn15+5KrVF_eaTS&C# z2~7D@249I(k{V%MuuaH|=CNH_t#ih0|4H;X{7Jdk=By>WdsBG(9W46OTU+YHp66O@ zqz$K%%B?@ST#>aJF|0$*vHI7t9X>f`d*ZS-PXI_+RS%`a z;$bAI0#80*^WoFui-9>-9&4@_e#^#ag>Mu`E!Z30nl$6GZrN$XO@Pe^?8uFfAJ{UZ zJUJ@b2zO)lD<1d444lpH?!=ulfnizLThShY{xh&kW_tPh*AeHvpo(4pw2N=|=Ld~* zs*JcZ%dBU6&Go%^jE~{(af}z?ub;+2g53)0z`nE49GaZYUiBA9Z&%AHHSeafy}ziB zE>FUJBHcqyZ=ks0TD7{4c&%3DqUaOudphq9 zcRULna6l&cj8d{WC;2QB<@}volw@Lxo0NrpK3nyRdaR|wvGvq~H40nPLJ9rf0$bBQ z*n}h?&dpS&%T|!1 z>hN6Gco07GCt)wpoY9ni0qypnTs2@~o!A?vcYDs`SpvReT(yI`Ds8>4*I#eIJ!)ww z7r{7r&!djwesMbXNo9|!(%lmJAH`U_f_fse8}ppE-I`Bhp+~$E#@RR+>pS4bw;Ry+ z`t#^R*puCQ;VfvG1G11K&}i)c)18ca^&qtc{3xULh_;wdWL47m(pa~kek zy{?cO@oK7Yp4 zo925V+m);Fea%bnCzUVy@#TtatkYd5oZkPByEhMS;!5*IOI5Ng8DeC4!4M#_BpZbx zv@wJ&3Y1EcB?uwL5MpGL2xFGe2_s@#QD`>^8IxtqQZ~?ZX!lq^mgz6kpNGlx^w-^A zr!2_}WHV-M!lKxQ7@BmzgzO3T_m-rDq^IZhz5m?jyMO2@ovJ#g&Uw#!-t+EfKgz|4 za_mob|BEQkPL%cU+5Jr@PfL_NXYKwMP@a^mf6nd?qFj)yf8Orjfbuw$O+*J`cK=f- z=OoIW_w9b72mMP7qJjKfah^&J`p>`@jLyoTzO%YxE<4Xg4f1%1SNP}BVK_&I;!6&G zeQW9W_NgW3LJF*Z2J3$budF+Pb^3ztpVYK|M|-e_p;P)L)(`ov)}Ne$wQFo(p&JK1 zt~kyI0duUW&Pqp3B%GmIOzYO~^|Tj?VR{!a6|LRSCxq|(-WvWT<~Y8Fu@@%Ru!we) z(c9NB^0ob~HQXLw!z5n?L38xd=vo_MqzWW`h0p$Awh8CZ5$-T9fE4As#Lu+$8_>FM*rukmn^R!^zM<@u6(H*69hC%t?pcX#i`1a56$T zX{&;73|FHDF1}DS@t5Pq<$EnB&tYG=8++qwoX1jtGuRe(JTFonel_TCHO9bwJig^QX*1^7Ec-)#AT`+nh1xYN z<}(fc(u!lkoGxdoFC99hRGd%4IL3qK!>?WHnfXOKlk@~j2tG>+UU9&Pd zj8tN|yR$*mSm%oA*mLadcJb~7R#A<3W!OyR=Lb6)MCMVG%#WN*++*gcW}dVu;~mKTemJvOgx@Utn(dBk+=uJU>=EU~Zr@Lm7{L_8Q(v zML%A}Jq76V9*NZ{Y~}{aC7?bMbiVp$Ix|JxphkH-#EF1TFAyYTzbBy5dF~t9uwv3$|19r11$_X4d5Txd6m#T3Z@{&z`$>o z`~cZ&fsH@x)71Z>Pde(;NnwrwePxy!8t8mQwwrt)*jl}Z*@$_andCpdvKGqon502E z@OQ*7n?U0z|8(EOqWCfB$5R60hQe7l89uWXF!M8u$A%QgV3)KuJ6Pxt369~8O2_L9 zL36^(LZC-j?-}QnyaIgbPH{Qv5Kma3sGqAUD`-Z{Lr4@>?NADk`4PXSEn$(fp7=r0 zr^GYjOZmIT&E^mz8}A#PLGJO&ynKR2-mn%@Jdoj0oD1~vi6#+o+Z&1gWw(pa(`1Ww z%wu>S&Kd{2S>#+h+0`UctTfK6$ya`YG1!z{MSx9^{D|TENb?|sCp#H|Z79I~{aBxd zvrUL|iJz@Sy1d}IlWnXuh`g18o;`oEZ6ux%UlRt5>M=$G@hI)-h*RUbh&M!g^8Ask z5tn0|oWWzl>%{Yvh8NDMbOEl5GjC=~jDHQ*1kocyH|P=0k0AeiExws6F?B@$!`5u% z_h(IvhhfOq>@@NizidVQT+0Q7fW`Y;S!or*nJbxi3kEC==@%;Tbt`<7u|ckH8!={Nco;i zwKpfuZYsH*wnjI`<&N$XY3?U}e5JgAXzQnTzl3rX%HwIz{oL;VEy@*%vgZrCUy1&z zct$>J^wy>~M)Y+tb>p!Qr-q-M<$8BDcw=>g*`=@Ol%BQG*>45XR#A0W)uxtIP3nmH zI@A5Kyrw&G4(IxT)KK!BJyBH%b>#EnsLsz&R)H=)JXz3_&9moXQ6BBvwCA%p6N>VS z5bxx$fnNs!i@^1m{F`jfY;`+%OBc z(Jeje>_(1Qv-BM3{IhbN?z`8G7x#o;4dF~##2RU8H4>~UJj49^wOYIzIg_q} z=S)4UZX^66+NzdPo77=5#`lUmzBJ68d@o94j^C?Co}z~*uhOSNZuvuEJPhQ!`U<8E z@?|Uaoz@Is?AOj@&G{HB<%>u`&ets9W5HkYMZn%ao^O!tMxCH{N%(d47KrOFrGz5U zEf*NX6Fgg)FOKOH@@{{>1MhdVHy~!9LA=zPFA`r=oRP9~0C0TkVv&LNTIo3Ee{FpJ zTfel&&jLgKDxFOs=dYr?RkT+0u7U@SL!M_G`i5zM!3ofsLOu<;ik(h6pKxM3Y$nK= zzzN{bV83A;ob3D0B2Fs|Ivd1~=xtif9qv{<*Fj!0@+v>sS*ZOjZ?Ag5l$QVO4(Q4w z@Z}>)V@ zlHh^4Ok0xX?gcEB9z`AbRyW<%%uG|%mki)68pY{?=KYQr;a5$2lCdGTo2jU>vUQvb zavSzJAN373t7M%ci8?{}88M}XhN+m_h&97G(D|bCAqQgUAaCD$ zoQEISAV$zW#gMA{gZkCr)#Y!YZS_sTH2rjLBbAGw`|88Jtj`1!_A!6=DQ)PkF%vC^ zc-ZBji=%kbXK>|)_8}h+;BtyJjXP=6+TI%(wMq4IEK4r>%J2ckg!%_M5QC5TB|1uL zI0E=a(H9kLlGKOM#}PC3CadL&XKWjdv(K?kZPdrCenC&TKyhyAzzx+2kVGckKXcptxr4v{CH8 z)&B;~E$uOpQ_bRa0W`+WLH=b;6eoNG<%Y-#QK}p`zo0|VQ~sCOW5HUwFZ9>f6d{%b zc+=K@%kZ-qwn#?sr@@*54rAHJ$;>n!-^gQj2) z!B|!!ew@xYAKoDtG~Mj1;ruJ!FD^f&S4mi-lFCBum?ZK?=6o^4kjeKEi$Z$~OZWmC zcHt14&z_#r+y^`!)fsMlT|P_g8L#^>=t+Syl&@ZiGfL>4Q4w~>JM5fj zWtJ@qnY+h^=FNlmm3?gJ?#{6x>bGi$H9UzmAYna$F336_;JlN0kd@^;EzWHvI++d{ zWX9U3J&ie*anm3{hJwE$`O1ET{ZoIFHPBimdZq1SO}DSt65trES92gCiS0kOc0F>pTXH~=oj&MvoY_( zrH8cpAx|uZZi`*3ZQFZ?{uysr6WY%*SOAa${z=835S%xrTQt7w~0x25&pPp;`l>39#@WgV)i5B9-TeI3VlR-Tpv+L z`!j4!s{IjP4E|CDsHp~Y*DKwM+Lcg;0T==ZIXRm$fncO(QNw-o^g1V(%vL? zoXp4b6j_hWxFE-)J_|YeV7n$qVI}`8rH}FwG2O_0!w-1X(68)4eFf?(`6Ai=KAca< zNwur}1!!+8uWF<7M0HWYpa%YSgP(OtYw(Tdx;`GfP~k_r8Gt46W+m{SP#$Kr>$(K3 z0d>KXiO2B^<2+R2$#T|zQ=Z2MMZO~_7V)q@NzKms2zWR?kji0ii^Dqry8~ByAQH4O z9u4%)*wego7!LlrW58bp;Uh)3QppS8?ZO4Yc}>t|2&O)qY05xHhjz;*g9b1d^8}2G zbROY(&0@jFSl_S#Q$M1vpg0b742Og8M>2@)L#!_c<;fUF3SVMTbm}ZDXb{n~naFL# zeidv9USpBNTR@4^vHNVs3@rE_H$h_CoAIy8RhO zA^6^aG==aM?1Dy|CgE`^t!P-3+n`?xVY?S&$v~(@eQk)NTkK$0t6MpQuCo;$e zB#v>h=Z!?~L5KHe9B30xa#4z}pnY&S_CbD$O)E%2*{8^YJ@7!sF35@z#MCxBJ-`vr zS)UR8>BD^`U+H}*hhJ(y&Q!|TGT>xu`lTsWoU`FgyC~!x?A%5EWgq5Zosn#?I=pC( zY#V`1f%ejfROAf5S##TdzGx1eDIA7g6F8FhXa&|rY35DpJH`Co&X4}_9mIcC#raXs zExTU@-d~HeM9Hpd3d6@7@YHrQ74^uqN%=Wn#{2W|z8NxOtK@(mh}WBsaVTeR$uc6p zv)Ps^=Lc1~xVGnPTpJ7AXaMaXc(VLz@8igiqwe5B9!Uuw9h>ES?CT2nN-?(0q15i3 zArtmR<>f82j?{fE``#!b8JJ(-n`5$t2`{wF#X2Ux44PxDpoG36E~}(YxZfKD&Dtsn z1)NnYvhRTh2F{*zHi@5tk09P?^E<+vFlhG#;A$3N9*kzTA%3Wd_I@U^UzX+A?oa;e z-WK$QZ8xE>Y&+bi`#n)TQ-7 za$eBNAkJ1W72+QFMX@->%4c2CUNKxfOhf0WpQLlLB%hpMCa49CSHB@LvXei{vT~`k&Ox zwOY6}^i9YaHyvs7uS`#yeI=#rTu2F-un~4wMWiLP5wi3Q$Uwlsy8HMRu@1QXV*A*( zPZq#_g0)5Pl3`;V+vYj4M|1-&DSuiPQYPRs3~(8EOkJleZw@J>MV7cMqB|c3&&##D zEd+x@V{DK2&HD-bXWbU9un0ayi!4F37jR9nq#i#OQY}7)bMlUb)VQXgtOQ(kqVCqa z?23!1r#x+HZUVeg%kC4?zlB$mPsQISssPKVgLP}2V?!hG>?`!|J6P-yp_6kH49NDb zfPAFFcxjwXSbL6f^Jh;VH+%MPVLNycHU!dX$h4nu1ba5&Hk~Jr!~NW+pqC_hnfAp# z%){@1>;I1HA;61;K9BMYyaqZaAYZ_%z}KL4ig*xLAQw%xvj<%BEydZpYU}FO>9B`J*^q$-) z@Z__AyrxX=e}sy8_!CIeodcd!@ZRxn5byoPKYsTO((7d{#W@>iGAS1`c%z-*jd1?V z+RV0p0&lc`uj!CaYL(N$nHn}#GsQ-o51=E1OMcb2h-fAyM7LyDO0RpmLt+TuCSoL^cYhInXS%Hyhj{3;*(*% z75~#a&xJbY`NWFOWuet$`zMl|_cF@LPG@KpP!s5SQT_DW~(B1L2iBzOuni zU%;(JqegW>Y2zP)_*^BUg$X=<+DS|BiWXKHQTZ{mK}Q7lO0-uYnik= zBwSbu{6Wq~e7~=2n$sW7w$oYZWyj^0bQf5+17 zHkSXHIFj-oz%Pa5TwB*3r*gyI=HdO&Grsq8G1w!#o>LOn335WF%rhO3^OkV(`yBH4 zFiuXk7cr&vGH*qDDZUN=XVgC`y#C2U@%rrPnKHj?0l(XNGx)FcT!A%9{nbT+rhe$f z?HIcW`jd$f@{j&GbO+c=PYH9zMOm$(BYuxXpW?bnoVAK~1mxYk2AHt$3(?|z`5Eq$ z4nhGQN$$tH@j9c>KI?7?QNB_C#fL34S2KVILDVN38}T13ei>L-nGd#vD4(eT{_n)c z_F=Eh{XBSIz>4$lkOQKU-y4b`@6fP6<%R@l!?%0{?Kx_UpVl_XcH#CHZDY`v{g2In zpXdJ$5wDQ^Nto9>{A|#rahP8t^5LgNvP1uwcz3%iw~g~bo@{?n_7Ms~7m(VEv#J3z zHEdF3GdkbRR`g?C>E3Axby!~%d%Nnz1J(wtmls98nA>K;dZ0LmVc5%~_&*%~yBDXr zC!-&k7;D5z`MCCqDxn2BM%dNn?G>dnn_b{ju~*CzDYrqN4f{yiqCvHj%_usCJd&V6 znI8vRu0Hd1ITM>z{S%D24Dyyj+TdlZg$>^O_b<3p;-5G9zb@Azz9S9aB>rb|bUknx zangW|p>vOuwF=m?!Uewpe6}Laj^NyB8G3*b#I7TFM*}%)IB;^Zgmb=;9EA4YAFTC3*$Y&=g z7!CXgQeBGc;FaqXuC2Y7pd;3R{~iuH$rcBCmC}!DMo7^b1K_V9Tk2f20r+frXPQ${ zY-;E`oLZqMV}Ed8*>Do~%?mmj6;|Y9Hn*MKYUO-tKEEbv4Tx#*W7Anp+cxv6S`A`U zQZWakmopU$=CxQC9BFYV;HTl5tFKU1{lfRk;TGpS!1GDq#4CWQVD*axTV`S9PzL;V z#=!O&Kz}sAw|>A>mUoP7@e;IDP;Wnkt4c3-0>D0X+6;>96Vvab!(|=!>^UW z>cE55s9V@BznYU5D)>2C_WaZzJ#>BOA}~ZrF99Q>HyZco6SOuwepr>g%kY%4sN5 z|AhHm;~4mw5DeA8g#*Z4VMdN=DzlR7Oz@~0dIpSTA##3t)HQw3tEt(ujUBYO@gBh~*Vdb%Ih=oe z;%cmGd?yp%O*z{V`Z2~v>zjLm^d7)-exFz(?Slw_&y;mw{@8K#mLP8u^A4|o{9oy# zyb4P^pOhPmghCDI$KaS!OW0nzJqf4e7#^~=h*UoXyaCH!_8R#Y#Y~Kc!CIOD9U%H_ zV;m_BTAG(}i!HEcLXLxeKhlvwwD}_JCN|7<8s<6+_jHMS3~-n1H}sql@@1bDr9IkM z^%gTHCE5~-$T`Z4-@e1T4mZX&Rn{6IbE+jh&i=J+w|8^MA2Hw^Ed>keFQ|Q4bM+O9 zrChD;0lls2O}&jPGwo=w>BWN)y%_0nY>$-Lw-uwZL&FU~21w z+%4lN@Ma_W`3H=8H6K%!?5la)Lk#*h*Bb7B+yY_1U)i|edVmL>Mi9QS}%&Q zGBgJGlY}Maw~XMp1~6wG;YRyy?-8CQ-ve#^_B~odlvgS_r-b8#Pel^e3TPe856v^> zg+zTT=EQ2oIyT{XJz|P7F{eFag2+=EX%xV}Y3Gi)nRmESthn$AaL5a}r`k(>BHSK> zF}*tPr}DfKt_H1Yd96-Be`qbRQn!~qPk9Dm%XnCz^f*a+1l%WS~ds%5PkvlgXD(=z@O`As}lQ!8vGfJA7v4z6pv8z z&-p$d6SfG)ky9DAJ*`JmQxARf{!;j^cCq>-%#!Pm@SN&yK`to{zdp!&{MN14VSY_Akq z59_0MW!#cj@7P@>1gj*xZR;)A_0_Xrc*gllnt^58Dp<0o~y2HTe~l z(kvT|gQ*$ie?P+dbkPrGJfZJUKa$@V9P`xu0(7tJCWB9Xjr3zo8R1ayF||*olQic? z*;<03`UAl<;-PmN$3)LICUcev5BbH6vt^+j$W_DG_H_+x8nIE^T^1tSV`XuR!`9j2 zz*WRmOaU)KdCWNY(bC>gCDr=~@9%ud=^tLcH#F?sy~vx_B5J|6rOn+N(nR-$(!+b< z6R;b;MXWeGR%#+XtQWjn1bo;QzFxc!dLScctO@qMcU|@3+4d?iANMz4o(^^v0Uo9X z((x)mmvP>Xb0z98!T((7M-Sk=Rp`gXO$vV{_;?%kCfF%!xjL?fc+7_4ptz);HRLZ) zMvL(qjvP{VfWIJ~n0c(%Pkdzb0mxhMfmv0lb}KqpiYdT9d4AwmmW%HK-nM$_MO(=l z$l=JjNWA4rjFHx*9Y=~s6EP>I$*a@*&Sy{k2vGDcP|Q*gB0_IKIGS=h$hf?o0V&H z5T3l1-p3&ye@8!efrH(a>yBWb2hK^bQxo0taJ6zjV$8;5ABo1v_dt`EhaZMMV~fZ< z7|(@Ti8APzpFKSdI@-QB(jxY3@}&fC{yfQ0I`Ct^=wh`mf_^ZGe33frNy*%I`!R1v z7Noj8fFp}`Yy&eyd}CH3R$i-7-J;+)CBg!{JL0zLr@N z<}%E%Pv6t;5%1}^qcQN%w%R*9ch=kip6rgf_spVqT*n2&-Mpr4l4Rbu?HB1g^x@b3 zM-Jej5tKIuK?CR=9`6id4;f+CSVn|37PY;*aYU!a!gOmOtH1^gJM`0&4U<8iHj@0j zK9(EOp>KraMt-k2ypL$_cewz=y#{eT#xA@IJ_37z0elX@(g2x_b$~P-9ZiXQ_dNgn#3>_*fgu%NCrat&5GoBgMkw0aNzkT?d za;3*s%}KRHkKtdGBO2gmzySw9PabFA+AAulZJVi!_QVuVea)7B_Dj+qykyJnD|o;p zZoxV!h;DgLDW%Ld1~~X~F`LL2I*9g0KEhu2BkyGtc36rhcA(xGeuVaOJY$5BvizTK zL9eYNWj&TbLJlT^tL@zk7XQf?rWCl*?+eT=KplmBYZvLo3K0(lf1--L{d?@OlS}4Q z^<^V|Wtunuy9N1qr^9w!{xrb0LKTsPb1 z>Q0S52R}T}J;(!UAK7D8p{*}5{%*T|?!QF!bJg8!P!blx3Vq@U$adCM~ih zBL#M(n(4m60puem8ROe>G|>43WA{*H#&LOuY#UR#tJ+lunCfFs($Kudk z;}wds@y!KjQ@Qe1Ih_wl`i@@R>7mV$Y}h;FzEb3?Lj5pd9eeOC)C-;je*<4zJzy7}hdjhl)J>b{f4 zcwHA$@pe^!=!vt_#*{rO*+K$;uc(AR@gU}!Sz?m?+$OFuLKc2@wPNe^AdPe81kLWIf15yiag6f=;c(xg7MJ z0oZ}DH!<3`1w)p=ja)(BANc)!4E*y+9-{ZZaG{UkCx=$di+|%$jE86)i?Og6({$7? zX&3UDrP()iz=@Yv-6|hESt`$$4K#t`(YO-qr_jv+2Wr;zH`y6G;(@?>zFoy^6r_8_ z19%VTH=2$ozD0dJh_%H==^HD&%D#Q~DZ|;2!-}9ojARgQO~ZHf=r{Fc%Ua|nz`L}k zEBp7|mwe8A`}{HaIXyezXaX;X^aGMl z3eY~;+^PMPV&e|v5p83!9&-S{6O8SV4?uSY`-}2=!%P{$V`>5(`YPDn6EG1lJ{87y zEdiJC(rht@*5xVic(6N?Y!XD?R5k33mwK+2*!~ohYWZ> z2{+om2sZZbJ^K!32kHCsO%3bt&0_FufS=8V__+qG z_QiO2e-Z~S?z=BY?}m-D?2{`CDX-;Q9~2pK3FfY7<2}8Hpqsr{r2VfoiZhh}lNDC7 zO(I?o^TeWjRM)nK0c;rH(l5W!xCOw*0NChH+WlO+eVa{+G!9@c4gEr15)ZJBn6m$e zco3gcL&K3ZkUe6%YrYw{RUU=jh31p?AeJ93=7PWf@T6@{k|w;m#vrdT!g~+a8R6Qm zP>1?jOfUc*+=ITTvCcXkSb@Ach*f_OYYOplTX0_~1%3Aj^`SKb_4bQ66NBOoD7P=k zY49DAZP_f=;5~?ovVV(HphLhZipwLMN&!yQP(Pwi4twc@^_Z{~yQy)WLoCJr8_3sayRt^`CJ*F{Hu0=g^kA+c;|w@t0cQ z(?se=*ONov!zJJytzp6^!Xp+q)#)h8W~Ei$YZ6mNw8M<=ufg|;wh%5=;hQ?FEyAN- z;L%x(lfio7toCh6&=SHOYO5ExlL8u|blJC28$^FrgND%emC$?8yrzPNsFBO!IAeT- z+9&=c6>aqc_lT}AVKw|Bl)e~f%B$2Ld^-#~UR4cp_W*y?h?zwE7km_zwOn6dBh6I| zHVa0`whW8x4sEt&TOO5!&(A4^cYuOIJ;N@{5{~<0-a5ENWpUrHpDv_5$|M^0vl(cf2pv66fTd`yCRfn zjj(_x&4H2nN%{i#7gY(opR?{3haLZq5RJDt>)Ma^JCK6{<73L%1_8XA0k}l?mnvk3 zXuo~!D~-FP^h)_SqJN**{In+-mIUTf?0xCcH1|X+wmn*t;1?#q2P91V2khy@pMx)U zhQTXDWS$*9>9_|NI*rJ;fqesh_Td5p&O#))l!a_$fL%g$jm`HGoWTFgu)&WC>kPib zHi!UNgPgAj^j?WQ#{ql8G3_f0?8rA;&<{H2QZ}YWQ*R7jQ2I20<6UU8q+7_-6z5-8 z<9r?}6Ae;%RBcaBwokqa+&C;e@6!$b{=Q3VE>tjYtr#M@LGRIicx6pqg%W6-!9_7$o`3lB!tK9C%tyaJmyB~UTq9-iq4)K=kDcDg-f7lIM z5O{HteV2C#bBJ&KhWOT%@O4?p_zUk>xQ2Uj+EQhD2cNeKu$l6lmUMJk$n#Fuh85Xu z3X9ULgC1h=!kxa9?uoOe;C!7|@g1ty|Ja>A(!ssZr_8^B|MivGvP{Mun>ee;&NXhp zx0O!aji;yQPrn2>u7RJL(w=`K19h|SFIh@w)6)8oI(GAnV@p>F=AFu|r+4$8!cOx( z>WsgeJ*VZZJ_Dn1@xsWcA9!L%9Ly-l-M?O!=GMPIvwAf6W)r^kvRs}~&GJkg#rdbW zk=y1}AT*iJXajA=S%gw(bCj_#w$aF4&s)OXyG1=CEkEnIRZ$EZZqmP?ul!zFCrIb) zHA2R6;@3RgFdhDNH!gq=BRwJIx=Y2_em{Atnc(moVnj&K@$VxJ-SHLlqj9}KU?W{g zXQe&C4FzF~$^BB}{zFN^x8an-ud-*}a7~{+UFjNr<1+T+H6I9hX_8ax5L!eR*1Plc z?obMJ%*x{NH*|no>;m!STe{|Bey>|od~}b!-}VUd0Qy+Kh8Hrv2ct1RfKk?MFrvH_ z+`>R8?jB0zN|__)q9PldFkltny)e(2+Dg zo#rMS-&r`qTm$_>iIvGH10843FRlHYI21W2el+fr*?Vm`cM|`}R|>i~zX3iw^lcV? z2Uj-TT1vhEuYay_mpv56W9GQS{~F3AD3c7xbn^a#D7#Q5+okm3DE}`|=20d+Gkj1m!SN`f_UHg6Au3Zl!p@Kz)6R{809M{ z+o4<+m0gnuo{ze1Vv9JKb?{oj11aqmx*WBqpjCn&#|DC;lU{eMBZ zDN*)ZvimQg{6ez+2X_B?l!GXfY|{FU-G3704Jga}_))w69h9F+ls&z6e<#Xo6Xn)p zcK;tyu1u6;$L;>#pzKb*f6DIvHOi$ZQ~RE`?f#cho`*8!Yw<+v{$HXjB+9K(yMGVL zvl8W4huyy&<)TDc-(~l2MR@|sa(mr&|3;JziE`^k?)CTZsQh zISpm{eoR9AKgul1ccHBR%;sN$@)r-r%bw3|{skxxCCaT|*!;yPUrCf>U)ub$QSM8W z^tpAP8KMCdDWc^z+7T55n8uzM1zXR_%{0iKQwC9Nt=rI}x1^Jv$iox#1 zIHsU~Vfg=6f`=o&mSjGJ4EVEXV?}M9jyyN5#W47o)?Vc1N$P<3pja6b^a6b7Dk9;G z@St8kR|+xnq~~P>8;iIS$XBrAQr-;O_XH^;D!^ZI8fbb<$hg2A)!o>?ASlMd2M$nu ziqlVXF%?$Owm-CgRbB}A5l=+-mgC+b+$*4auz%4#1@66ydt>MxbjBp(la7MdKE)5q$woUHa4!q>_i58y0(E&&PX+#ZV**`U?ZK4G9LG}R*groNHwIwd#2ORin#*b>#Q77 z^QvkMztUT*tu4vojWs&_s6N$EG^>X=*azu-HQu3T^iGPj+RI5e%SFOofi|-|T#XJt zPFm?zV*h3AIL`*Ta#+9&=cNv1<5?zt*~nRxDK*t7pwlDY(56S5#p7MgVt1L*9q87z z+2C`{Qv3&>9; z20yvFkVoNv^~Tt5ZHm3NWueU|bC6?Rt{xj=dP^*Uhf6G*-&ts3=BnMV^p6ceuJZ>4 zQQRXf3sqPJZ3FJHZ%-Cy!IqM}N?W77s;zmnnsf7q_lnd$*(-+?2L9pGMS;#dg{A;4F7JLroTW;e(qK$OO8DST=j#iHB*KE(=?rfzp)RM z>)>ayM_7D8Rhku3dPdY`;GEqRa+^YTsApxa8#Z`<-v&c7WM;L`U^B)X2-~51!-8RL+Hf}+D=T5Xa4F2mkH+}vFgIo=3mrzV}tv6WSb|M$} ztysWrTLBvxa}sBH;T%Kqw^5$T4Xt>G-NE7vdJeYm60ZhyRup|y7yV$4XW!&DUhu=O zQnZ7{+N{F%Ag;hE^+m)kvE5u-N-4XIE9pRvsMZjjX?U^Seuj+(LRC%?JRoa2STR{_ zI6GP7dXzgNF2{Cy&$w)|n0gNP%Es@wgy-#e9_cBDpN(}p<#P<8ul=yAk=<)w^!IO! z7DnF~cr4Smr~fH^-=-UH_^mDCs59_^yny^tkeSIx{9f>T|ErzO0YF|2Yj$7oHtT77H<~m90rARDs&)RZB#Ie7sF=6h&i_B@DZZb8x4r5%qlbN zNX7Zes?xw*va#gZmCzm4*BnUOdu0slWjd_aijHNWkzvCQEojhie4FH;krA`=l+7&m zMa<$zw4s)uy`%r94Li(F48>!8fM0z$Lk2RdpPdWe6RcsvwF<c=$mrL%$rz`be|_&g@@ZxN`o5>ATG6v`&aOvu-S6X^K7xU?9KLR4 zx|^(o^+T~`=p%D_)J?;J@A4$;B*Apec@F%;Iq`K|_u%Ts)r~939*yk=w}5(jisQms zBA&@uwo`0Ak9cg!h<&4Sh`~O?VBeV_F>W1b@_t*hm__^o(OMq4a1cu+`y_2bPCmq( z2HsipZO)xSyz?Bz$bc_VlosBgy<6tl<^<;L9J;zxi}onS?X`_6_fhQEYk5XHcq>qY zKGo6QoQJ*Eg!4v=u|LzEJpS|+(ZD}ndv(+0H&oCi<>OhQyg#oP8lTvo&A6wv4)-WZ zXm1`bjz9feVsBnCq`}@i9Q$qxotq|&7g?Mk%^(MtqC_)9^^}1py!1Zp->hV+QNmYK z-jmT5?Y~Ow$0?{MpE>PGk^NGb5^jjYGY&qgY0&RzrE|{M3FxAQ+%mv;XU~wvUE{h^ zJ_)?4^l_XwO~Tqx5r_2#+#lKL>wUWk(+U_ zkfNh!=EgUX8yYyMc9dA|IJ#5LiS7eXE4g}(Wz%6$y5JtHyN&+z{Rt>y>( zPxC$(;9CH`hxi}jgHn*&(j+zSn+n(x+!;sZPyt|{@-6?<9Or*ZQ-0`N0A#Q$^< z|C0j#r^>rhTT_xjybtOsO4ZP7QYfWSp!^WAIiiz1kkar%<$J87xF59vbc@* z0?NYxAA=8Re;9~uuQOmjV2)P}86;-oI>C`048uZ<{aT;UyYkoRz=PtfEM-DWRQ=Du?D(`j|DH!AXk>{H}jB#`;pAH&ESn_-`xE6B8%eKqB*oq za?zeTyfd_Q5$oomH&J4qL*S`oJ__}yP8#k}3?KL)e=?5t&~=S_i8GEn%qI^2uTWl) zDD$5>{QFTZM)^m;t-xmv|BEQkPL!q39sVYirzOhFmkxg%FP4MvgwFwR<2dpt&HZVc zGNb$X2d>nq+?j}dwBcEjH#SJSWZX#d#`&jVSH_x*^T+wXkzL=ezkJ{a@yFwF?>pW& zU(8S9M(2tIZ(QYF0^HE?hWOfBM7XhQ9}C=|cL_J>8Q}(d8&9nBur(}n_KUR);$q-a zC9gT+hq)mZJ~RxUQJYs56zk8^*#&u6!wjQrSH_IR|E4UisA|bM(iWoss%2FzBNP9X z7phwHwk_N5T30yZuIq&}V4JTn@r-Xc;>4UVJ0)zSI>2et5ksAArwXTPRQB=2ZS^^IV4CUy_{95}D3=Fuvv9oV2l5 zD7S8o2j`Guk7U5p(!P7txl`N)`WqCHdw^PP^>~4-VJo^bk19r>o%b6_uFTPm5808cr6Q` zo})Orc+L{sKVbWr7>rQ7P9T-^{}V~>CAyo_CA_=wE9Ck?oSXENHw$f3dz3510N**%vrk8Ro6%=#liF6CT0AEW zISR&(GtC|`E@yTwAK%vqM!OvueJtgg#(62Q*ECW7D#Sk};)}1#d+hBo$D4c5H_&4d zus^ggPLB(p(YQ(WAsL9|pD6O|C*_}CrUkso?@oM1Q9 z{-Sn2{^0*qX1N~p2l^&g?`qe+@0$M&^cRcg5YCWYq$tK9{(yg8g?%;^veRZfJGk`o z@<1idkd}a7*sFE#v!)nqjS+T&%LrcvJ#cstuh_sIe;x7`Q#Jwn-XeV4Yl*O=w=P}I zY%Il`7hErm;4|Fd5yr?!~(Vwv9{JdQmRpFh|I|BvL$w3t6F=5GwI){^dIjTj&Rwgg6#%9eIVZ$(*J1}azjjb zXYnM|{XNe5zVv2cc5OofE&Q`$*2gE&#rl zggAWpj_>g9pg)dx|9==at-0j5f43n%?#`>w|0l*B==^Tn=G(>%+U@`EWFg|mld@1M zc<^s!A?FJ4>J4HlAK3UE%}gDlcM6iSP#4KUso%;%so=L|SqOD+mxbv4+hw6t3H(+` z>TR+R_;d&HV&BO^N>31c8uoJdV9-8{bDEtP3j^CJc(nL=E_w^QhFiLM?y4~3noPVa z-&i+A%?!Twe#{15b8jLM2*Ab1Ny(j~G>T!%U?NgO3 z%U??9wWolmCb>C}-&$)r-7J2v>Czi1&{Z38pY~Uh^++}&eRo{0d$zVf=H1mE#X=e{ z>9x0hE7zq$u2b_XybkRO@a|LMa^1qzA*z!ZSOcB*R>UAosaa7ty)YBJyDZb89i1l= zI_eePBAUDP8Swii8wu&Nxwt-iAv;96>rC+QO>3`~7ox9PkBB$bG}Yn%|bRh z^aygm;u@nIgs4OGG7cZr>}!Be2KeeHC!~2vFFXqR!8YW9rF=&A)f#u8n5iSYB)E|u zhYM{_CESY@`_sd4%T1J-zGDByo~F>W#YT4!=VUSy73LV?O$ER?3-Rfn*#&K-B-#*f zRLfxxj)0~UJy%0-i~AIZRBOY1BYXwvUXwXkb+ z;(dedJAIl~5=>8ytC>wa`oLw4`?*b*<2ck`?7#GBo?Ee$@s|J(3CBpjOUiX7oar8W zc&GSpT|4FT-)yiaP?>#ar+B{dTKNdG!t7rXm(iAEu45;5ibbHA0_E|64>{S;h<|xu z@#p0p@GoE3bKMIdLuGzC*I!iy+`b5&bnQ?%)ia~mMsa1-DC>L`_;1Aj z_HNtu_7eN{y>A-befZvdd{+;h1}k~IFR!^;PU}1{#8xY73)}t|6Yx@7j!z1kQyhqC zM;m6e5q7z@7vukG{O@!*w}&8i9l-a(n2#;US0`fK?MJ<=8|`yvB2NN+$AE7{=aYR9 zJk>+&wye)t!@9)xn2&YUI`o5dvPAo7+{80a+H|U%S)6^-5M%1d7w0_ACAp6C?iIbw zA!_q4kAK&9SF-On*=m}{H&1VNxjdLRyk|$7@qIi#XG+Z3RQM>T%{pLar5djuYxQH~ z$i%r~PBzTlAYC)oEb~73+gYb|4Z*K1DU0`81D(Y4FDbQs6gZLVj=}drVMPusj5i5$ z25`v-d{*EpLEjz)%q775{1MDmNybfr4F`CcV3!#e=0aOnrn>Knav_?(q)eKWg^#bk zx^xQB-V4a<0^EFUt;S8cn^Hh0Dd%@39~2RXU$aTZJFMTn-c&> zqR*teEdiY)ou&bK6B+o{wXTOA3v?{4P`I1ZDy}KD>@~@V;h z=_-{1AL4of=;v*AT-f^R+m~Z3Tq7qPfbQ?0SIOIb+K8Z!K#xPd^}24-M<70mXLIQL z1%t5v|MYVC{WPx2PSV-S{kk?bz6a>A{w}3`cqI$`2I+dve?S|QCOhd| zXqJ3VrJSbt`2oL?^(*OChUQDjO0CG_|NUpTp1wsn%oBAuoH-D$qXV8%U*uSK7uGrG z-4E*y=kL(6lKQW{$9dBI%Wac^Z|h|rR`L-i|MD4#BaJ+!@EPDs!SU^l%1B0=9%sfH zS7g+1u`M+m&&fKPz>ks79Xh8yYuF0-|JAcr=|{Cjhqo`CMm2uMH3;->;$VVyls`B9G4=-qnQ^n$?2d$Hd3z^@qZF*DHCIy+PL ziG;ioa^Js?FImMcp^>l;9$cewXF6I!e-GXqdMtrA3EZr2=i2(vf2G7VDZ{4gO!R;} z|CoE0cKUsJkR()z@w<$A?1*RP{YS@--qKu4bP9z_3W%{FH?rT5!7tT%(gq}c`B zt`w<{_iF5yOVH13+uzYoM1V(ASlUZnNm_5i; z+_I^e=DR~&jd7T|rs5vwFm4MXmq>qv#>O@&BQ&dzPar{i(df4=oJkCpmE&z_WBa}A%wgxGl7yc#Whp*~TM(yym?79?2}>0E`}KK5AdHZO9MW@&*`>%1Ver)?uVJ1 zLlXaOe!|v^PnlfRXbXE3`Ek48>%(AteAKVe5ys7&9rJxru1HI}g0a_84mPzp%e?X9FUmU~ zi^Gox{Knw>YoMc{eO(FI(fl;_@fL!mvP23o@P#hL_*+%OTt&$9o{9S$e!JMVrH~ye zQU(XS#^Xxl;816 z)sW3|HB$knoQF-&?l<|N`9r4iYL zCpp#}-;eIeyC)X@qWlZs3A<#*^-1^^aK(QoYz2DYN=ag@ge#-am)qxC#+5UCC>4Ir zs?&jx`n^Et>|=3!`5AaFI#)S{xnf|SueES4#Ox;4(@Qd~2=dv!CnUi{G>r6`6iZ{k z_-(kaLqF<43kBq7Wd!6a!MDR51{+=XcNiQ+c$acjT?CE8x>U31Gl%x$dr`do+*4R1 zux%Rv?^g8x%A;SDkBf>SGvY_{z` zLGYt91Si2Z#A3XZGm9-A+ja-8L1~Xje5z40I0=>%f2r&X*7PfHEvyG^Quh7^dkR-; zcI*+DuwXfWHjkT&T8|CyQx3o4Db26yh#b4X~4FC2W^GF z!&g?=au9b!{h_|pb;JJyxx{H*QCzjc(lL<%t=f!tXT$EJp!4O)2V;GFz0!EbE&jTE zC*nRw&b3YzJ`(a zl$>_rl^K5*kDLhT8|xU`Mt({Jdk(zlRIH_`T7we%Ov4wD36y>HHCuV)D(n~ZxxAoN zhWCW_qizc30x@qn6eqnE@yHCGvy~||rAqxXXn&(QyoaA!`1Jaffb;9-Mc|)zi#>@s z8pEe*Rb4G1yjMpsKRNuR`2_!Gk)xX7QxQv8Jd@zhCSbo|6KrlM2hm0ZdCkZ+2)Rq8bjY#Mlj@FxAO{h=Xzo9e41RvX6iiBhR4`F&ZQ zz#IqgJ^GG-@6q=+T6%|L&DPZecgEp;jt_@eDIAI+FPQ@W8T_X<2^Z>btW9=Rc~$DG@>6oZ2Ug^?fo#d3IEm^ zgXb!mzPz=Rcnk~r@k1V?2>1Tq@E9^I0W<6!j57Amb+nHp*V7)@PE!(d+UNLAXW;{F zWgydhIPT-w7sg$hU1mEc&WgnCq`~(!?t-V|Jijzh?B9U$xI~$`RP28W%7G8h`YkBOP$v4xUq9=git=fc>D&C(V*f;xdlKcqhsAyq%H4^w^p|3P!AE&+ z(vgyHjSg##>@w3pKQqBs3LVfNoDGVd0*l-qL6PLfz}n2}ro!QcWwEQ}7Rbaw$n&k2 zrdCUZY@tzWx~9)CTvPM}aaOliRN90P*BcBej|M}ebDX+1?(<6W^nxc;ZaRyV=7Myy zKJF^Yb&xLV#1A~zJ)ZTn7JcRTXaA1=X~UnsWr3HmE5J^^hA zdj%;V?t#y66UVvi$Wu%4xU?=-LYI3nlH%hW^_?c1(@f*q0vus%Te<=+_ftp~+2e7h2TmcSXqSghBvjZ`sDi9|1UhK? z-@_bQXh-`Bz=_&D{qa-!q#dvKg2wHuP3S4EI{imbUY98IA0m}1%BvFPz+aql9(Sti zdpbU*LwLR<@m%_d;+;HR(l6?uzsYcF+epWFZYYlj178g6zt1bM z_b8yB(q)d(#A)A@t{lvZ0XfO|E!m&zOPFMwbC8I9blKR&F4hiK%Q^9LKGqo)n z`fP$zC;E9>cSz#wkgdapZF?fN3-#^wVj1=n4p$Bl{1nH=mc!Q}in!k!hSzI=KNK6q zg^^SVPjH<86iAG7gFzNsC^u zznQr?jMsDS%sF#*chVLaR4fIt2#sk$z?Y#dpyLbtzRzyzFrK;Rk9=0vep!31XRYRTc^2>JNUKiv5ZaljO^7J&U9oL%QYXe8BJ6M5X zX3A`w6>=p@_ipLN>R>MU(Xqmll5+50L*g>z`<0(Wj5pS3^Y|Mhk(D8;+u@tZD4ii5 z&)E`R6{tvL_azOUOIF!XU-D93*QEA zf86`A{FL<8`=BlDOo|C}%)$rcpa;0tU^;7Zns-pHK@K_K+r*k3LGZlH3Jo(Rw>5mU zQd8jpy-RboGuxEquSl*)f^3LjUx0o3&+^L>tXYEfMgGk{V^0#Sy;yIw?lO~qa-PF{ zv&Rwd7;?1u0~7N-YyDrr0|un!qr2L-3pW|5FDB>3unRc0Et{G9`oo`9evEied7f{O zvu6GiLM;1<_|?Z7IN1bRnB+hERa*ESjCWSn_3KH`6F6FVh;j}s9WrGsK|7N%Pgt}a zhka5Eym>Y7^=7$j&MM%>4bYuvzV>%ygZ?7k@n+0h(9TQ5SI&q8Q(52;l5-M2L9$G( z2Xx0HyV^59+9{BE&#okqr6~ema)x? zvF230=EpD8kz9S+Z5Mw$JjB7rpEC|W9jxnt4EPM{x?bJ*0`x=Ijl3g}E07F0c6CQ% zpujowNsqtRA-Mkfs%^V;CYEDeC+k3)>Fb$Z-QCSgo29QYKgX_KeJI_=RQR)hbQ^u= zE6^KX4&B)B7-AXm;1QV%rtiLd`pf_P5dDnfI;-5Ievj?ufg>09eSz;SP+oMsXcvcO z!gh@MJkxeloa8kYPf)d|g8T;Gg-v7M;N8QJiAyQ)gR>`s`CBRaLzM&mP`o==s;_23Dj75TfC?vf5+yloh7Ioj0JD@hS zs6PPSa-`qBQlq3F}{Z2=NbQmWR+=&_57x~o>@F2B98qGthoap!QT%29i4YSnZ0ny zk7j2sDTl3EF7&&Z=sU@@e|VjAO#AWPgPYG)(q8g^=k~pUdU2vIUvc|7Q7=H9`tI*8 zRDEaWL!PdE_?GY;WhXcWh)e;uNtwV;LF=S3v$e1>`!|s z<0Ct!-6O%@A$Bm%@IYTOV8x2?HM21c69e9R^hEe4l^w8c?11kDvz2ndRA*hciT&F> zVRqw*Fnb%fo~=C*PC}dPnp?ujD9N5(N^U#580(MixkshB)p(X?m_}CCf?vNm!4v;U zh1-D`;Bh3m;;(bZHbCyNmBm=jinoMjA3GVk8WZytp>MIHi2I8;r6Ru1!vAePY^Px- zF6nHNlrkdD;ot+`iMk%JRrN8^jPV-K4=JZbp0j6+zm~Yi^>X7}BxBs@)Q*u1$JQIb zxvAM?#JE!wZu(uoD~`WWj#8^S*8^9%MkC@$Xpb*yACa{U+L88L$mXiHop9vy=ofM& zs`!bGx90{%*)ZWx@(2DLcA6sUQwx}Khs@_Im-e)i+`tF=!UP$_S4-0?G>_a8J_`JO z2d;a;?|$%hhg6MN>6>xhq=Sd1{0Qs-J8CLKZ21d_0hy>LqrPpFt&iJG4LPzYTp^1l z25=+T?V8fYwQGLGZUv(s`PX*rGse@` zArL-#rhZSm1JCrLY>hq~^4RpJo)aGq{g0l9L#)u-(h@;Td;v0q@jdP93b-Bqho@Ay z!1r!N8=yx|ap0*5E^DxNX+3BGAJTO^zXJSp9hMYg+Yib=`hILn+|cuEW$W>do&2E# z$CN)140-g?tLhWjhDZ2R|k}f_w-~hzH~E zr#ORS=uhAi*rj}+{DIa4wMoD1wa{_NPkML1!`wIt&llF;QN>iV^@4cP6#zW4(RP6X z-9F&u1S~|91QQ;m9VLg7;25F%2RfvJrCiIc&}G%SA(KZvU@zG5?bA1;oObCNvXo!L zU(^M;UJ}E~1%p;s&5opk^*iiBXJ$7Vb?GfB&VvSi4`(*Nd5b|}lx;-}~=CB6v9OxYt9_(qX z&&mIZb5>o)xK6NosdfTZ(`Ao01Mtj3-Y*XABR)YZQ^++NVdIE3hgiw}#_xa=xjy(q z0QP&|4c7lV&W^qB(7ZC`f_k0@JHTU?kzP9%73+TsxxpL9S)&Q}pTjlif$D+NnLytj z`)^P;_ptRZq4XbR>$3)@R2=%*xypL9HfTk_W#YFWKQH+&I&HDI5T->wrfnH0C(sE;;>?0}DD71uJ3 z`|Gr&;+;7`fu4pePQNpx=AtpG(7brXe}{r+X|IiyPN$vW?Eaa#~}*MP0EW zuEHm*RXMk(JqSNwRgZB1dl@#_z(3{Wlgz;fi}I&^ykSo}J=gd#V!7d39Jq3wJH5he z{M=1)^2NX{RAvco<8&GR!cSd&i0~;rOL&Q7C#;~f`w*senH~>TN3Zj7qH)C z;Bv@1Vn@mEasn4~7lR$(qpCt!14bn%ZH}ZvXT$h@yc~KP*rT2oMk^W6e}rqZ66c`? z_&q64lQ)`t?)=Ai_G-+A7(b(xXS;8K?FF7+mkrw=OZ2jp|59ianL`Ty4 zPIqGcN5y>LM#lXxYn%z%YC6{P;q{s-;V%?l`Hm|22wQ(1@8t-)C9k|&N_FJ4<^l$P z!2eyi_5jKN_>3~(fohb?QHm%_QSvBDP_ihCsr=-Y@Okh7e&z3ZKv>{@#M!~V1`UsW zePucJwPRvmM~J@YGc{a992@!{bFuYi;KwZ<@~e8>OK0%3;w0bWkooNF>5#(EtHCpq z(E?_SL+o1u80f_gmlN@Jn?%0VeuRtadYrA>dz?eP&J5`s#_f%=d^7Y=6$0|Pqtp#* zhqa&s)q8+<6ui@UJV$*0KIp0T2~CnI&YD>nal0-};D@T?;7J}kSJ^=Oa;(_*SS9Fv z=qs4_XI|n!tBZiq%}%kE+B8Q*o@m+;*re3Jw*OAt%Rzi?#$oSEgKuFC>KX?kJNBoI z`EA}!B~Ou-(_wF}Z)%TTYHFWZh;a$pH&dO{$C_jN>a@kW9U58Ntb>n;Zcx8N zE5BNo0iS(sceDj-vRsE4PvD6ete!q5m*Y7TE@6vv7CM-br=5~HJhel&k^1b32(qx-i&_z3;HyPGmZjh{0VIn&iElcp!rD5 zziea5cVeDgz#TQP3nv)F0Rt1p2|do3Ml_Al_nE_~keSGvG;;SQf46ay#?EX?ejBoM z6(=xT=3*VSX^>I4oNu2Cz2D?o-u5|1^J<^hwZcB+Z~PVnj|;X zdB`@Jmtu?}a>Ai(2JOT=4cZL)7QG{5l=xuu!AE{_z-^;Rh@G-n*q(aBh`$k$iJxe3 zR~?$-Fod&YL-gYX^Gyeo}Y^O#IVfA^T^@$|-^=RJx z+1NA1RfnE0c;_g+ulGM+mn8qT&WdLlIjR1c-ssUJSzpJN@}nQ456B7I9ypM+BOqFK z{PFUQ6@azWzXs>f^68h(R^Af2=V(VL73WcWb!tN{@pkv##Wnowwgv+b0@Cx;1jRK_3RfDYdcvkG#=xyq7TQ={vzuZr1kuDACfKLq%xSVI1i0y~J?aDJQ7Ht9ps4w$Pr!S+k)FX27v z#{kBYg*jyKUn3*Oh|OHZt}r1dC*uph)8Q0h^AdJ;NORFn+mcYp1sXs2h*wVU>`KEJ zXix6PHEOR7Jk2}VY*rT5$z0GZli#KDtqXk%jOcx=XwRis80>~%`w8?P^PL&rIPpIl zam@ppBHx>}t1Vf1O~*v>A>p&a=1Fk;6^ec5Qs=e`0qnbd508Q`GFKF8{O0OIQj~mC}L9o{Y=@0^TbqqAL!cM zQsk<}$41yuqJ@M;$mJfN`5ha(sqWPAZz>_^R?owaOn6^!jYJeze`oP!Y6ErQSlS^~5Wc#~0F5B9Kek|E9n%|kpjtp!$w9M1uN|4Qh_ zMzk5h!;wFT5jIL^5Yf@>k%-FET)SR0h#xnA`*eQu_@<)~xHON+YhNxNVj%;ZgE`EQ zPvT5?R>PLEr)W+ssB18v%ql&@;2kUKcJLb)KqFWM`yh>z6OMRYD>_1j1Hdo9O9c;f zgxsLR{FSEfuCBG^Edw9l=t-%vmvw|3N=L|wc|E%vc(uPH#NB&cX|Qzp5a}q?c;1k& z6HYb2mWs~KX&;ME6tAK^YPvKH`0#e&I;?k!8^HKztxVvA?tj1uz;|{P<}qgLOTY=t zNv48uhzuMeR>Y3b+4)xdMCi@C4gn{mP2dFi39m@&4SSfsD|E-5fO{Z9a)dzh-1YOS zm~Ya*Tk$aDQP309eyw?QPx~Cu;HjWZ91Ym7@1%x46l)lHr^G2z=v@GmYX#(CYXm^c&r$&RJVag*|#x?u#oCUTYE76xU(6(2fym|xAj2Cq}0fJ&pYs$Hj9+~e97ebO}*`8vUe`I!ED^1$OtuU|e9`gSE#UIspi_9^iwHF?B? z+4D4V1axa8#GwR_0z1nH^s*6kzfumSYQUO{R^F2g`S)9%6Cw97+W3?W{~YTasxdP2`rcxU4d269C5%<-#JFgjm)}Orkdya9Mu1p0 zfTJ1vxuy?$)nRE()XjUGr9*7_f_5!dnb_+if!}TZY)^Z1i>`ec zcuNQ3>JWZqu>WWeW??_x3LHyyt+7*n-_n&lsnwr&ACI6l*zp_QzGdpyTPf8S9P4wf9Wm zcM9wa=vw-qXs#S=3w5GSu<67ar0a%=Xzu#LBx!}Pcd{OYzwv+Io>u{WhVDWDJSdk2 zYs-`x;`>9lf}UZaD=9}DW0g-70)5O%#Nd$IT!6!3l*q5ehHobvh5sDl;gdZs{SV@N z&Bp&4$j0ZR9JU3dCX8X&t=(}0*8aR+zz1-lep0@nYRn7I%qwM%hzDN&22=f8q9V=ri?=aY1j7 zHMRrz3jXD)jtu`N@=AXuTD#;O(*HtyjB?;XPTt_Z&xz0~ZuAzYVzT^2nz zJo$X@&GD#V_$>P2vlMoOZi9^`*)XxTo8vcQ?umwYMz}eCDT`arqyCJc^V}%T5f=0E zplR02+okRI>BEJ%ZYs@??D5V}2Ig3|xj8ov*N)50 zk{|d#1u**waFkwLEB)pmoi?VViGS~h$@2x4CarKQe5XxZC=(0%SesHispJ?V>*A9KUs$F$s2xJ%M~bgvZs z#o9sb>a=hs=&rjUH`O`BLA^~sN@rRh_9|#19rZa=*exvp{gZ9iBcBXYWRt30R5Udn7uKNuFU=SRQsv-bwx=U11Rienvy*y^ELtVh%6RSee?GZs_vk ze1*pD4;g#?{~zHN-hQ~n4wzNgAqSB;Rex_pjw0gwSX=2}7S;oOzw_Ram8w3oMmzL6 z#sm7?>P&q948A`DvQ3@bqkf<2Q+rr*lT#bBM|Op@Ha1?+|0eL~E#YDGX)pFzZTAkz zfB$IZHo+|2jq#H#gLP*X3Fs3Go|WVrM3U|5tMUL4x`LO$pODpjt?Fs`RWC*UxK~7M7+d8 z=+NWPrBa`QMVUouagn!Ry(r-Qh*vjYz5QaCg^me(Y>>?(I1=s*2o`B7VBry!@e;&R)58tEfES{T1&*A<77jos{jG%Yv{H1s4y|`Ue z-ve$`-z&uRdFYqnlcwB&I8WLr-u%=9QPg4;w-uhy)PrDfKQo%_`qEFHk+~G zw;x0H4Vdf&OtSjf48q$>aOQ1awYDQ2eM}Mx8jSGo(BEf@aZ&xa-o?df4eDj4F(~W9 zui(9Gfips;?plQRnm=6I(In{NkPnSBvaVi(eWs0>8+B35#oyprpR6;QVB?e7%^GLH zuCaMQ7hW`FA!{wtw%oc*-$M2sR+%YpF4u+cqU$Shy*Q~wkLwnOyAandPwA!3#TFY}Idt-wP}lHeW$zLE-xbuE69 z#}wdf5ef!p$mXhBSLs?_#xtc6*vfct{vAm=MKMhDvTINe-&Mvraw-GQOzYhh8nM|2 z-{?sTadv*ke$1Wq(3{9ph`gzX4B-uO(#I`tKbpG_^W$0BQlGT$*}9)V&O&{mbv9+g zGr0xtt&{G%kB#=MO&OxT&XT97_T013KTX+f%}JmCL@LJEuUCL$-PFgz!S!NNt3I+; zn$msi4(j(5xp?s1zWdbUgGC8xJ6l5Y}zAy!apDpPHcmO^w|XE~qrCHbx5M$$R_vsQ7^w0+JXL&1Aop z7g170(bQrAuA;M-wJ~wK1M3htCxV!!GwqR73*_oVyV&iZ-v}NNiiv7zCb=(%wvw@r zcK#GLBCwB2!x{~i@0p12(0}uIQzh3?~c6zC|N@LIULROOe^qq9q0h~LPxOcU zyh}1g;{oKPD_kL^pua41+%>@Gnf5@)-&2xTjXW*S(fH&oQXIOeCj7TRH>o7fXOi)= z@$I=i6t~uup~g@IZeZY}4Lz_`dKCE|IHENG1G1;B#+WH)&M?|qh4{A?x+ikY<+#^{ zvs4Sd+XFcRVCi=sTne}m3VeehfD~kK93-mf);(N{j90o2wg}7=N{Rq0dC*R9OvU4H=w@@Gz%H+GHol>AA(*)7TUIM zcR}tRflV85CdF3xpNJE*9%~vL3u7#ra*E&<=ws{7t#%HcwHq2($M(8jz?IKhXXKYA zwPYIDv)|eoMu!}}_Zu8%O+|?HB6fr{pzTBjcA(JTEkr*#5BNjG5+MGRc*To%=(617 zx{4;OClS155PTvlTE=gMkF!z;-X>9>OFq)zKO>3yZK%f~!{|!XA6H8Avk=Sd+O=$< z^LK@%d0;)+7QX1pkzcg8VVuukEJUCDE9eZ1vROKe@&&}8uV2qguS8%|D{fZl=BTYr z>cN@5#c6G|gN9Xrx0?jJu_-pQ&X2J$!pwSVHzV5NlF)7hwkssh;$hb?(AO+EqGIpO zfO9f%d$ORNq3)?Zvgf~(;ST9qD^%DAw(^Ew9n!#lg#o{^!f@x=x}~30YQdlIm>;DN z>jXJT=p5%xV7_5rNVbwAPwr@}=?S>FWn3#;2_5-24l~JFxG34KP56Wj!*7O%k6ECC zJM<&iDv^wO%D}(CmYuJ+_bp#Sup%0Y=qcdLD%Q5ssp5fhUdl!;)U4&;=a;8nVg`(t zzK1KG<*|lltLu4YJqP<-ioKuywrCXxV9N%4ph3Jv3-E=3-Y-kPB=-fS@81WG!FMFW zF}EW&pYkBD$|tqN8_VxWO-Gv|W_jcY{)dJ^BS$0fC4p@>?fYh$PY2=}uGQ5APd8)l z1|>h{lISTdeEmj1Z!pmbU%wd&_8VwK&NIDk!fvvmgOgzo)x*W^im-o;M`5=D8=^mB zk4!~BnGbKc^j5)CBaJ_R{3ZL*=I>oojllaZ7WR*CyaPN2`J8eLbAbFMotOj2a9u=u zD8lrZ_CsShVAsZb@3+9V7qssn_-==;`8ho2iUwV4|MDW%Mp8ZPM}rMK(*SbB;ViKT zOk>jVEa`Pw7b~>sTa4~?W65V7bL=u?hUo8^tDpSm8N~HY?q)Oe@0by{tw7D0mWEsr zXAVu&3D;)c#}tzM*ay9WUUnMQ|53fsh1`*}CZDxy!}`xm;fOH(V=HJ_oxp-u3@pxc zCjHeS8{$cj8{8@+g&Ej`o?V^PK(SZO*^(Me$dR&L(1#bycV%fDkBnKNr_|Uyo6esb zs+x&)@M<*ac@Dm~oGo&cY)i@JPz(7*GH|rTWJPQ}rhJZx9}9xFdIU0Qg5~3o#W;{7 zig23pP_|SDemQ`-ZhCt&Xu*ES&Ov)SIwZ0OQn0TYqYsDR+kt#;yZTACV21se!_g+u zxmFv6Ttv_|Yu+!r8~fcxw2BtKzl25-@el67FS zRE2ea6Zi`Y&L=zYr`BO_rE_4m;DArki!S=69=cx<=PaGk4pAG`K+kW+-elpk=1giT zeSlqQNOJ0j%g=pVITbLWceIej(lg68AZ9q(1;m&w$=!_63Ofg0NSQ%0S~KKu?CBif zM&!Z6xL76Io_5VW@&i$0m|i|91^_=jVEGu%itDpdvgjLRLlls)|Db0e{+e|ukO_xF zX$R87$t#KOsPi(wu^Qmowv>w{EO4)0R-{{dPlf_(zpdmDLpd4wA9AB70o&*L&4Bq_ z$lhiF@;KkIt>zY-sDW zXr9vha_DS#hYfUDdFg?d1%t4``%B@M5`%m6oT1uKr|o?|)zgzm9y&(7#Uf zkKhL1!ur(Pu6zWTz+N#}H|5~TP_oP!8O5F#1WfR5d9o4=1@J%lSOD_%!`^i0P{9wX zup=Ey8s^7_`}>Q&shpY>^)}%@Z);M0?XZ8!=h{w6*`Ozed$AADmWX?ILB8pCIP#K@ zHH9YcZ+;N#0sb~KDmISZcw*CNVADbtu!1^@r-q%R;jT`a?BXW3XG1 znq5uOqnNW&%sK7VZBFEtSJq0M@;3N1;H>O*gmkKmX}cUEnnN%m<{6>iWX^JdoC+#aTFU9!#8t zbiUjG*fR2A#FV5nCXO@aa3~J?umM2Eq)w2EYgY_Za^622lVXs_o% zcQM%049-9g*2e_h`(j;iQ!02aF@FQ_+aioMw>?63#BJM5OUY(^d1{WTr?Xbe&A zuRP+a+79!OC-_x);sWEs)W`wH^S=T8LHoi2-;bB^pJ-x|1+(#BF43szqmW799Sh`s z9L_&&1bm1c?I<z&%u2tV_d-ZFOY{>$H063<2FCDEcm z;OSbxe=*jIRjg6vjSNbXKN@Z6VG%Z?B!3}VnP_Qxheu9v3vj(kvm|KjtYPd?(9L{; zZk|Q`@=Q_b=D^aICioxNez3AJ;rkX=?Q^|GOo zgKy$L$I$ojZ64odVV5~8#+s`kQ;b6{Np{iPKWSh1LHjJ=A0%3!z|y=QuwjwU$cJ}X z*zmFnt^;NiBcVF7*hTuujnGdL&X0f(v|>J?Gn0sC9KasS!MPK^CU?ek@Q&q=fS-e& ziq4Rw&}S2zQ)3ImvsX;;lVbmLH5bM#@P6#kv~jMIZ71IFO#wMkKH}TOf$35H1B_2G zk5?m$vCAit&(VMEMc4yE9*927I@lH32YH+Wd=l&E9G{Bws}uErjg|C(;X0)vKY+I6 zqYp`JH|A30n_0-l=hWg4JQ z7(_0Piv?3Ed_~A12fZHIo$Q~r@!nlax|k6UVxa-{nHX36Yree~Iq5aWGuy=v)598> z%^zku86LQH-=~X!e;$WPctipoU;@BHjLq77L12%Vz%!|5p3nxoOniHeGXlEM4;Zni zU${^v(%Hv$@3yVR`GXR>7w$C&dfV*uz1QPyLI7v$oj6Yd zRi^MBXL@)jZ;IO}^Gjfdq|VQm3KtJNlrCBEzBeXj1~5*hHlXUNEe?FQd$*nLWjom! zhm?N{X=1m8zkT9LWlV-n1=n#l7^{Kv*(cd{3+n4toRF*fTu|MOy6(fp(v|gEfXJG>{CDPx-}+-z0a+C2-j-McXku6`cq)VZL|Ks(rmNv~(; znyuJ#=({WUS+Ly#JW?ZKJswQYvqJYeRbj1W%3le*qdAyc;Ilbws5?Jbh1%DbX@`H-WJM!sT;Xg;qPX30C$4dmZG)X5NJ$BCuiXNtCcAJ zQ8IieHYw%#2QbDo^nDj{AT)dWea!kBd~-=pRl^POn%b#R$a~_TF`MkQu%AB(9#H!^ z$#)q+Jl$V~9Ek-Eecfbk#_c4FrMdXw}k7tR#o{GL3h0SB& z)m{8BXjhqy@gm!@<)S!;Y=h#!QDx{)r+q>PMz#kG;wh_Z6?~+6#^PPF-O(Hq^Bsae z6|i@~hEfu`f!l?}QeKSZs|40a<4VplWNG0O!vntXKg(5sgIM^TP4NDf?|J{Tmkbq@ z3z421gB{!CvjIF$=Oe+2+Wu%PXU^?1V%{iIDjqFASD6KwM6BD1_#jv#-KPK2?!Tkm z0CdsR2E9-1{1`ZdzEutQP#=ef*oHX1d1aXAsL4T@Uw-PU!I_pAqN03OvX;xX;s1vpmsTj{x3GrB(GYWzk-+Z?h|kwuYY` z{!jf#z)bgtF@EU1eLn^-x2T^>O+%hkEASTAyRemX{v7;DiFdYFve9WcgMqio)6nm1 z?5#Si2+=O*RbV2#gzpdOn>;8N9c9$9l9i|yH z1_5$V!dH+_F`hU(hw#fqv@!Ds?{}eZi}8M3=uq1-bPL9RyQYn5v|&-t2d=qzJ<+o2 zx#XIZ8#{pC)co5;)@By>J(oHPhWm^SDFb#Ra)Bw9k`Gcrb9p55qjOj8u=L0s0hdx44kPTrcx(< z2bSp(2LQfAcEnbK?b>aaKOVlIc0rZpnt6P0(hit-TSp(w555f@C1kz-a6gKB3~ZY_ zD;I;tPM3Ir4O{SSjnL^msicP(yJpPmL4I?r^Zm&8rUP$8&o;@}6RX+qp_vt`z>qnvdaE0XP{2HXeoS_Kim`SDHbGk?hwFfA*<_pk2 zin6+weLn9EFe;@KdcrL$Z})F}r$#m5+S85^o`Z!kMOYwiGN%r3GUvA*nU@f|JJ zEl0H3k&aMEoLF<-(JPfHpifx3hclb{AYguxYi|Z{oR9kcXYWMc4X}qccnaa`ve{b; zpO@cdPsy^bSf=85GmJXH$Jnv17#1*{C5zU{?=8P&a~{cQ&4)_n#B|GLPh2|dpm@flv=tC{=8f3AcGkD2ykj=n3 z>%+V7BQb;Lc)_k!c`j@7BFvirT1kUnwanE6?py4Ty>arsx*Az%ioeAu@0q$@$9bC4*XjP<3t~GZLgiXQhB?50%qicOEDd?(JtB0 zMbR!R)F384azo%dlem@ardY%)2-5c=fe?L{^gujhDx7V%DszbtE$HH!$%l9&;6%^x z=#LrmOg8c>kG&Og;QFCRdT1A5u92C11-P26-jhr7NA#aS>jiqbJghasWs4E_pXhQ9 zJRbC3)=uJeA&;Dg@e=M7yBE6%FI$0=LGMbu2X+!)fp<^v_W|%@g!?QikB_(sQEoJa zczJw#N-)=MGo@UL%$Sa-Phn$z+_W^l9u)bn|&trg1J=Pe($cFNe zoE|z1zK6m3PnHo=H)7+ta96Z(Gz5w|2DHY?89W||) z{>06|k^efY`ra|4g_-21a$?U&v#TfgDax_Z3A_r(Xy#RHO;rgod`;r51>=&Zc}A3 zJY+#c?-Q<8@C)F_<5yLcQn45Gg%N$CJ*yDy34d|2UkZHH@Cxyu$ZqOT#|ycYfNv8& zLvyp3@Wo*NXIuz0&_`K2R zesv#$u9x<$(L6!(t*$Bbd7>|wOeT2AYV?KH=tlIT%h0Kv0lSMP(B)}>rxk1a+I}xn z`;GGvb5lnBzHcIL5z)MzJwZEvpVC6KgLYs)4#Jy)hli=JVJ-sq$0zWXppKySwr`sgZ_^AE=x@I#pU$4GW>A<%%$1~c=H;HJT zVLBs9=F7-1)(<)2@r2S*>j_Kqf9<9+dnA?!V||=wA!` zs(wwUG`r3mY(`tK<;44ZaWBrcS7GzASjxQ10Uro$L+nfrPv3(bev8#MF&A{skRDH_ zz3E_^S>|x5PT;l>j_5>x3I4AkZvx4pdPT^#;2TD=Ei>{268*m$_mc92+h~nV`bDs? zv8O$F``P!@m=Awzym~_x;AJd8-twN4(tz`%^cKq9D7T=b_!P{Vs}H>bzkyZX7@)tN z@X3yyFZMl%`q!lsb@OM%zGBqJ67{`b6l1>!5vzv{i%%Nh!z$*FB<{ujI&qJ^$c7gt z?j6HD@+mcsCf>ungVhtUX?V2To4CJsyx2Dr^*<--v5Un%6Y6hGzJIycmyG)F6Lrs* zXb<(*Q2#mF-}_au@9VD(6~9T;V}C35jiLTRqHg}C*moZF=M#0$x5d6V>f2FYiT8!? zmih)!Z%owvSC;zvQEy1p<*Q452T^|v^>RGVbQk#))Ym2If>PxBBkHRXb$_JDw;%Nf z6LmRSq`Wi+r7^7fin2SLAyM^(Cm2t%?6Yk*^K)MTxrnc9HKn)NfDJnZFeI z0;p%APBwP_kz(H#)MqE^^66sVX4Ge(zM1U0J}CBWM1ATt^=j1hsFU57|6-}H0`)5; z6W?dvE%KG2ei?PLzhL@{d`nUPB2gEP6!}Ed&m`*pfg)cn>ZcNQ`Dl?Z2lZob1$&fn1#M!ymUKK^ErqR>*h`-j#=2CnDeyj$sQ$+|0#2`yjnxrS+TEliL;p~KLjwzptd=;l5i%ZQb zD2>?}Mgx0G(wDE5w>40`d5V5LQ_!U9yJ*gs5r5;puRg65ew4CAfv%Io*=gwo4QsQ* zk0X#NRm~`w_iYL~AJXi!eYa4WA zLE>w{7i+@n;0K{qK)V+2TQe* z8?iz$Z>-QC(#ZWGElLh0gWqc4=eInELp8%YyVwmoA^VmjqsWcL;SaVDaAZby7Eo!9 zmpUfn7}9z<^Yjf{-^kW%)rx3SL0c$UlpKDm0nfLp(I$MDuWeIp?~_D(XG$HR$L2_s z0|)0S;?L=p#L-9Eb2|aY!16#Z<;BxIcrv6#d?OC=jVS&cw_#y8L)j$}Y_tl+f11z> zsqvU#hx8`Sv>9cov7>nQSK{&^(iP3HO^+{7AS3cj=sFPlTcr{FeaG&Go;mcdwil#a z%qzvYI__b&Zb43B@?$drjse?^h<6GeP62HUSo2sn)gHeZC+os@6M10g*n{bO=TrdiQd~Db;!{Mj z=4buh3p=j$j2d_53}^}J%Qitn-VC~Xq=kCr72%P(F+D5Xv6J*PZFy6*9;J zp_F9j5suU9}!)yXmr9nE%(VKvS&|F=cHLDU-)b@{s@HC`vt2h-;=TjNjcZ09cSY`20Z zHzWtTA)kTmT+J9GoD97(va_oK{RuisrE=h>VaUBW*&@!}0+*=4p!uzmC1nv(gJMBDj=8Qq#Lj7ETF>izKcInd-aXr}>aMtPzVGc58 z(q&m-<3DM~stDi};A`s7*32`3_hWFLTt>co9(^@q9&mmD-%Okxuf%qC5&c2ydKJda zV%%E+huE1CAM2RYN^tih_8?ov#*8v(qAgsz19sdrFOCRnCA`aaGx4%@h=qf5Ur4~e z0PyEv3t*SIXbtHLVSAnh+K2owN$y5EpJe#g&>YRg9uET++HUv>lMTBw1NQKU-S)2C zh+I%ovNG`;=o9rhBjOZI&Yc#0etqdgpUuN1zHcuYD)uJoo{U&R@_|A6Q z@`um++qLdUONuR+y7J=QE-UDa=8gXL*-_Elv{6raXbjNLHt6Izl0NFm-R{)wNRIBk zCvzpgV~(&*S~0e_i|7HpL%3(4T3y1P<$o6%xt%6T;=;F~A zv2GT^zUighJF#XuagHzp(=S=%UrC+NkIcn<2oaWdpw5)lj%n<*W3X=;*Y;b-VZ#c4 z_q~m5gdLv-pP!02%V+%z@WQ+vfwvfg{lN-BmmTk_dfKv@v1ywv-)NLyg>+?>@qM^H zEvg$Qnu_A*vDKDua1FVVEaPmH9nUUer^}v&_{Kt)Du?|x(6Q~Pm|wOEXC2~jFH7`Q zL_br;#5vkBe!L59(!5TKXve4Z^Wzq}7Z-Wf&a2;}d(<`?;m2>q*vx+srw0;oz6lPK z-_d+1<}V%J<}OEjJhkx^+7K6i-#(2QJpOo1;vQ#T{C)eWQEognvUuDePMOZecGsm8 z6;5xE5j%9;P_d=(T;;Pr1&te7?laT?*0582I_vRA!`N5DICBZlOwI={(tbz0f>KK> z`OY+frt1>5&+o&&<`CO!r<<=bMr+25u*vqrkG%Sy^fMLxOhrH6qHked|GTkxsXg)W zv7*s!?q&GV8X(vjhFRViVbfAD1`fUfG;fe6kLxjS{zJj~ZIK7^UxI$ec;xXh)kYJ1 z#WLU>EuOPGOi`0u?PWJN!&yWnBt{*)A+S1wRTh_bG z3^T0{fio&{hpQ8~=N8n3NFa3@^aRbd*w=r{4rdDOd#b_v@NPX~jOm-xp|iz%Ro}uc z>NUi=BYC&r+OD24fw;f%dBhK+n0JTA3>9_mbCpjLZv3dkM|_X|%67!R+g?UCB{7Fs z&wazz-HdOR%dGM2@y$kB3#_v=*MK-ZI?&vtLpzOgcslhrrewZ`HkYE!Eof`+u@chj z`+y4>&oDdZ!1}9doV>~RiN2=yiB}v>OobU>0Cn{N>KB?Mi0r+l^W6)YtXBEdTb3+hPw2tkNB`)*yGJxf@g4G4Q0qhRDZ=$^hcgY=VLQ~M zUSHfRn&~=ppQ$5&f%**WxwNaJEm?q@PW0xkyd3Ttd0N-d41P$DUmx0y7TTXT3(rU? zO8A}?IO{m!R*C3`83#&3O-^pddI9zhxTihxY{(-Q$~z6XfHg-ozkKY`XkS%aWE_ej=^NKy9RAyJxXhk186nsxW;Ngdtiu*>)6ZC7UEP|dlEEA?{W6aj& zqv>uqWI?bR4a3!Y}ln z);Ej!TYwlcG>3*G!O%v?5U7ofXoKc1etu_r;40)Jq{{^^_``Mk=dp<2%E?CG4EXRd z!VCQufEy#g#|yJ9ZlYmd6^+u25$G2oqjF;3(lrMDZd}AX9)&+5@IJ%zh`j3OsL5DC zxs`?0?NY@1l$ z1Xr@dNJ0DS2gEt7K(c(mdBE`(b$yeb)0>8vUQA=tKvQIw59=lhdJVjYy2h_vGj+Rj zx5DO+){6qzEX#fWZtcb0xmMU^6dY*^k>3u+EIra~&wq^ih&_BQ9$zP$R5(}5ZJA7B zkI){!9`m#wxv>bwh%=gBs=jN}nIaHmP>uS8C0bl$v)(G*oi++BkQaQI1K9k@p zAn&|?mYB!NZFOW9b`)o5DcPfA-#KS5TXNUzB}@Jd@Oue+j`)k)|7xh{cTCVz{+{K? z^YIW39~1Y5=yKmw)c2$QOQOdPEcfYAe+T<*J!`b(&*dV%kXeP5v7mZ-YvIg{_dQ{vl>`rOI)-z)JoqRyjE z^n~YdiLU|mnTh(|_e*?_p>9glWBnz*b*LvN>gItG-zwDE$@hgN-6&tQpf3F`65`=?5Lew;fb)8(co%kjg|Q3iQA0Xd6{15|Lfn}`g?6sxwV6Z ze%d7`MO~3+q-@Y}N%AvNj%YJJg?E_qB|f)}jdf!^Cb=KUC7wz&tUNmnKBE;s{j`$l z?NDV5Q|+3G=RZfE(e~`GX1_r1`#%K_Y}a05^4F9u{QT3029Zlay?(aDN9(!xr?7v; z_<&1%?XaIUWcz=7Tu7=&U36U*YzvSZq14Cru`#l()vgG1u;ef75KrGOYmIMgd?UFA zvK}fOJ;()V7fu_Z!f6xv`XfJ`NnY>OM{J**>DM3m`?U>Tebn|ztW1AoKkRDF?=pVB z(ALj+Om$q$U*|{eu*T0Vt3`^tV8=xA4t9G#E+rJtSNY+blk%LKtAQ0~gOvQxSpa6Vn!oYEEbH!?@W z(+2eYQt?;U>#_=NODPaeQ~U~pLw89lKk7AL3}>T;BY(g4Q?H@G_K99LZjIr(`5291 zdp}ppG)|6T7RF$j>Mtd_fqusywN!lETP?W}-(TyoJh292G3L$ieudmEYype2{oy>C zkL`Gl=7aL$nq-eR0$<)P$R27C7k|G`2Rf(5i>1+!jrFh)G8Q|^_?fnL5k3yLgJ-U$ zJcD-Ft{-5kRzc1}@>!hgzSswT_zp1T?K9f66hCGG`h;_;%I|o>)+Rq8xf9RQb5{BO z5G%`GrmT95Yz5c4G@!!_H`02AEU-g`HSDHXv>^^}8ybdfDbY&yZcS`hX5-?>wxKyB zhlJe7ZqvlXGxQ7_A3-eJ%aA9F@ohsSdzgbWW$NU3Wz8j$3AU9Pp)1%4TRVnHb+C0T z^u~)GfPM;dJr(%6x};QE3c1wA&!GPk&s9E+H7@+E#AkJ|WKZjB*R(M&u)8>tKfcCx zg*usiU2V)R7Jj*XS>@29;A}kY@b_8~qqE4ZW%S?+NiUS%qrGuwse#c0o=ib=p9yEa z4*!L_EsIG0u>Gk!8rSC9v$rdI8=Is0Z?-y1Lr*HDp{F9HA?s(Ba>`3Wa;EJb$We|O z!$zDL{*$HZoKD_L#q|cdFF)?hMrlPKNq5G7-d#w~Z%aJiv}s}u%*>vW{n*bgRhr*^ zT$(2)8>t;0xg#C6rA8_(B_icZwsQS!*c9Qy^H!s6@9(sJWX*V9 zvbOl!3;1Up++->Lrmr-g+8{f3vL&YL>a!(+nxEu_t5+-Oz0{*@cxIyCyAtII zy!-m6mh#&ZeH9^pDusOo+doHIhLVSjX(?<|+E9`lEt$pv|Ik!Cr;Y=DzYMN1;L|%b z^WBy*9`-AK$>8Er=U~nGg9<&y2*SfB$m8h8!Z-76a7)QHBYc|d7d z`t27F%|Tf}<%3F#h*E=c3Cb&=JA4t%3@X3bGb6UaQUM+DUb3q`_|w0`upcl~ zP$w7?{I=0KDL=cleQMkF4qJ6Ak6#Axt;NQ*YH;4(X|SB#w*hA@WS8L6E9m(^QK?Uk z^h3miO)`i5)tPEg}tI)Fa$B{h=my&B1L?$d`TAE@8M zL*Cf2*J9JQ@~}ClTv?sA+E&V=yB^==4LN7&Z1CY-^=!a+s(&z^io|%h6*=JmWE4{n zCvWEcz?(746H(aem<0pVb_3^rujWg{gb)X}9fFPqXZH=F6x!BZrtunv2TU1fyapegg^XR_R}TET7O^+(hwUvRXpry(vX!+> zxn;1MXY5QL$)i@hS1Wyczuic%YeJ5eo3Xb7s|;H;&?Wf4^cNbsC*~qrQtFGLjy5Xj z8FsaHt44<3FLH#R!W_hrH+@hRt#tMyo`Z`QOm)y(ILX%iUC3~|vaMOC!MDvF6U{p0 zcgDKRiCfLKXchCQ&OT>!Z}hP9x7g>I(ZeCFh-;BK zqcZ@b4AcW}FV7==2DLj7&*67tPn`xFUO2>NaJ`h@S>N{{#+V8HJ^d$Ltq%BPdn8~F zh=}EYz157f>PeK(RP6AbLF`q7e8wAldVRgYqpLH-o`Ef>zS$5x}WXv zsm~AY@cnnso`DY-#Sw_PxO$Ai6}$TMRz_$p%YbjRezm^E&}$x@(mMydFRmRp47n&| zgLoGB%=IeHeHs44Bu~x3{ymMh^x#9$j$~M^Yf0&0Mz24h8D$Du`px);EGTyPpX4mi zXSySxV-%9J3E9%DGa|1QWN*#kYUG?~0*#GWJrS;jlbO08e4saL6W(D22Dyc6)pJ{Dlf54_&qM<(}}<`ORy8lTe#ZZKkANOw3JqsEnSFZa>GD4 zbp8n)d^flT{v*G1s!)Uf$Pf6Kp<)fzvK;XPHz2m}($p4uhdYvkvxCkl$KVZ!*N}`p zdmw*UwFa`%W$X;|alb@%8QbxFeFA5BH_@5tg|9I1ZUXnO!?j7g#rEf@_Bb@Q;okW! z@_8_TPS)5y-ZU5Mjcm8crj+ZOxOW-0hrw=~yU0CG`VY`ZjJ9_H-qSXp#l4Ah)~sHy z!F7#o%_cqC(e!Z53}VH@Mx|K?o8%PeyYW36gP0ohJ>-nv#MAd+n@fHGz{{@7k^QLw zd`oXvQe~VyUqr&G3~Yx;K2G1Qrtbr~I6gXmO7(T6Swajf>5Sv*{rBWF|t) zdEG2+@<0gXIFyg(+g?xmiWf3N7V@k>-rQK;nXpZIP05=zkb^xi13$Z^)%9gckfy~MGrh}6 zur;WJB6;;c_ld>lzbadYxI+7bY=rBM^7yl3bLc&=cA)`pE9k+i(b>apoGYw9^rk-@ z@&SwJYhL?tw7g4!smjeO^Ay@L0pHdie$)RDwTnHqE%v<;?KIMQbMe)okJkDopzZzV z!8d`oP3H8Bdr}vN}ZtdNb*LH)E&$Q}yy+NQ6YP5j0(Z}INqJoH3fTj;n3>HML+0)@s< zZZ6d`3cf^Zjn-oVAHgj08l3w$Y47_;-dMm{)shGQkKjLOm-9p14+!B6xFq~HGIh5Ll;5mh}0JSDjFebB+69u?xU%TwTyjTRs5YrTRIdM={{ zc#5~KjTZj0r%i5z-EsE#1iPDKuMD2hA3th!2Ef zFlL@GTe6Goe$O%FT?ROg1D;~Eb<}Km2W7l={O>{;vUdP&JS>0@Sov(>1l-|S{h2n3 zuM31l@jnifJ^9CghAm)=;Ge+}Ss7h3qH|**(e80HCnBq#3?88+qK53{cB|x)1xsMB zr#kALmsq6bb%iqm=16l5y(0}Ssc`mZnb3XiY86li>%#kWkU^)@oIP@bq|_IRukWV0 zEB4GIn{Jv>#p)7Zl8)ld1h@Xb;Vdrs`xp6^>Eic{ZcK4&eD z&L_1=a8sL;1&-&#xQ9^eokx17{l~s2PXQeNY(upCYa8^9>O9d8{olHQ==%HIF3}p! z5;npYbu0GE7fU#%-pzlok*B_}6&rh}uq@69*^Ncw)KcGj!=R}$a7t92{Ug$03v zk}Cscul}Djdtm|6v@(VlFvrUx(DlWVov}Rg&_0!o3>QmZuE=zzp)P$c){u=GxxoxK zphbV?Z^E6v)IyR!s@)Sqspmp~VFF-E!qnX>VUhi*LI49pN0;2yHDLEKGiLu4~SD%V&hI;W|2C&*#H4dbo` z{Ci+WqK>Sn1}$^waEB{Rq z;6p6a1G^fTZLonJB;oE>QuuLQV*Yp@zNsooupej;E4Q+nL?c}0b>Grzk=nW-vaamxYt8-k&8O=P=|)*E8k>^hy7qC{36^D z`d>fJ+$~AKFJ{#>&Boc97iT$CCJuE{+qu*>$~9(-r&0SM0 zv%@$0J^52C?7$SuxZGX-q>d&(E1F`NfV#0KR?NqD&PM*Y&?a~tHR}Hv*Kz^Z(uO(g zqlP&g@GKE{)+(IvnSxLI?1`o?RLJXHOk+~*<`3E|?}8>}0)`5}zeo`HrGl<56aGlK z?x*oy6z*07mj}TA5UpvJpY}6LU@p!-D^xfm6j4qEJIUr>x0byQ8lx_3saBuZ<-Y>E zC=N2^G|&zc>N7-O_wjRHPgwwY8-!*hZ+|TBWaQo4m+5#5d&)ghbR8Q-;!n}Kzg#S(S4L@ZNZ92|4~kiw?dAY)#XT6%voO{=@e7>L z3|nh1s~%;Iv9iX|VyOo4G{l=xmrE{@2=`Pdzs_Q+h`(1Km&0W zku1Dz%;dfH+35Rw%QKzhK(i|E_Y~fMxjicGg6}>qD-hbH@aA|+!Pkm-@*&vC3fp|I zqJP?Z`9M7AL^uyJK&UGUQ@*Ch`fuFr%&P5+!WQsH)|s4o$crK5+XLOY2J)qO?iBM& z_i46n5_a>Y( zLtd>Mnv`hz(g|K&6uYcRn0HnI5cnPRbDcrIVXEo{O(+Qc&8PG(rZW!z zC!mfW*L|JT2mL}4Y;tgJhqod1BlMo~Zq&2l4DOD@HtH5x%-VDovfEj$GyBmft{ATr zOZA8wWAWCjn1966VsY1x#ZujOMrA*05Il;_IurKTRq;4`0gsi!k~zpFBQ$puw-kd+ zjHnE}CGJscN!(c;b~HpQXkXPF)C6?P8|OhUWm#PgnspQ}$bn`NF0x{7g!a$bX!}&% zfWoVOR>GJA{9A?$pLO8n+=AMm!GGRz(;uVzXG8Bs`R0H*UR`h`A3O!dT!Zx^+{#<@ zsON8}hj6$xSR#2`na%{@6feL|$pTHUfcKlN`iLI(m`YtWExpMh);CCYdB~HPc(B8i zyWQ6yyM0>l1DRU(WzspV6ML?M9iQnl2`unR=xu+BE2n;PKIF{l_h$mNwUD)<<;CY(KrV{-$^uce^he;D7btlSAz*Ve?`gqi*!F!q;k1t)|fL#vhM-zoa z-W1tUqdHzUbZU8T#YC(b>}!zw*m_f_$GR6f;iKIf3-V+Ai-by~F+6K@Wjb`B9)IE( zj}g=T8zFaXR&>d`T4_w!0)EldO9N%69>{c#r*R3XMruBIoPPxTf9ly?H8dtER$W9H zn?7G}ipcu@hIg~3#Xo6>EsN6U^oX}!?f5kME;wuvW$;)>r+2BAU<{40_afTpm1}*E zX~lsJefL@>B8|xtq1O-|k0;uRz3eOOdsAcM)N0O{o{Vuy$2gI^%s#0bT7AX!7@bJzKRzI~)+a1U~QB63bsZk}4`;zpFH0Q0D^IKpCSf=H^Oaz~H2yHwPYa?=? zL<;q0I^+d>fxLhfyr<|_ceVPId1)?ijtrC$KS%Os(zMFcqE+PSj%(y@u1+`teOCD9 zKp3`EbT5JI+a3d5t_&UZ{Y+ z!Fsc%*6Kh0)tel2AFjkTU&0ol=CyH-FXMqL^lr83n_D3p&TLX+{^*@i-9eRflQ^kQ z0IvQU=|UroFK+$~aCLih#ht5D3^}+Q#o-`AU*q`-*Haexk>lx&h0VtXLLfH zTUB&(V7&0De-e1I6SzZ~2EIU#bv_v1XEzIsS6lS~QBJONTfof$PY(mXfwQ*7fTc~L z4Rd|A63toeAQx~FpLfnXkCPvDPYUVIaryA49?3C{m3@QO2J{bipzO;io2=Yz_{YB}pVsGoZCv3%g+hzA`L=?duAR(V zppSwtNz{+JJ+Sv6SXXz_9{G&VFbF%)T-+U7L_8IA-xwdZM(c!rRnlVrzFz>%lo|QR zf?PkTF9-AeE$DTCZCtz>^*2l&vJf7ppuUUNYQFCyu1*YTQ@-ASeGK?`0y-1I;q#-T zW&QLW>p&yVwTT#)Ab4mS@ZeY7_xaTa)d3xRz|3)AoIpnftULI|iTQ|oN4cvN!Mk7^ zr*pS=D|(o^u!zEM85 zV6ebBJWwWL?C8D|=@(SMN0MPGVAoKHF=X(`kce>uPD{kYG5F4;y>lnpqdJUBu{LQh zMLmZ5qO|M{&=|V={oDuRbi~i>l*J5MC%AhUp}ILy-A8eCzppnlx6zjcIgsQo8+b)J zYxaafzDOJENs&W}{HBz}zHkk;AF>R;pujf=+P_*A>+kUr$rfU5UC=={S`{CKMgeuL zL|y%DUz7*IFDrI>=tIJx|MlMizjKfmYH6P=Ai4&elyN@ILH|kXmCk4aW%Q08o#DFO zXXQWQ-ar%&N#|;Wj6pc52aby14+&;9+M~PY#IG0uV-jGbZ*&eu_l=&0J}U#dv_as@ z7(59*_xTBi!#Fqp9Puiqo%XO?o>PLKYEFL*gBArIugZMTY`;#ToanL=` zb@**_DZ25=A9#5hH!1A`5^8{VC)+Ye^GuV53(s_a)$FOn$H00EsfRd z`nW{eiF&=lHt86`%^wPuPK2yTu=F6j_+>P#cu25xAU^#I!Sbu6uWKA@qT#X6qoMu5 zXn6R1G%Q#xSUy4i!^r=?2;Fx@!_LEk<{`VO9<(jm4fBJ z5uOYSmUj@Q*#yh;2ww|D!!$8kPuE$&@+{INYqY(#hya@MVhNSWT7v)3{mJD~nMJF; z&7J|>s-92Qh45Yk-t5jYhH$?{SnKm15T~??(D~rJEd}#g+1cz{k9W>zLZ{2YM%4y> z-HSUIq#LLA0Q5*t3?>>9F_v$v9Vq_`=1AyVCcPpTF9;R8eH!R(sg4xr%{iB^W_ifG zPz!#-GpPH?)5e^7wDA_;^8C8R{PIEO5DJ@pTe0V<2WijSW1lUL=gqlMIu#GT&3hI; z+F%D)3H_=KxS9_6U!TVZX2>}I1I{&AY3&kDu60v+%BRoM2gq*bBF?S61a8CpTKLob=?#%Hr^ z74S?|tp7*oAoQB>uhRFqr)Jw>{Zrg!Q(a0pwB@ZrjAtM8nV=8M&W+rjlljpw-ab(s zQ*@us%wN1FUD$Bp{co`*?gtECJEQZIZq}N0VRK;9Z?JEI-oBdC>^1?;bilyG7QeN- z*+1~bt&U@{{6v5F@QlDC$nP;HW}6Cpihh~yw$NI&f{roh7mg_Px!oTt>n}0YhBeA? z&qQnWh??dSTxH`)wXDS58^9P|8GOA zfc$xQZ8rs&oL2jOcB`$AupGlmCM z_4+V3@@fIuOs{kkZ&xQb*H6T}LEGqLwmSobT|4}J^uPU1$le+C8t24-CvstB|5)a4#lBdTyUf2kybL-l_}aia@Zvt~G|;k!l6Gm4yu+_vw#z>g@km6p zY{a)@ZC{vSjR*%JUqHv@eQ07p4Id{qnVWyLEYm^vD4R!`UvEZ#l`|c>YbdKQ2e>nA zB^eyL5G!;L_;1AjH2EN}XANop`&Rv-JRR9Xp`RhSzlzhrMkyR^4?)GhYs=)Wb|tpOZFUvd=~ zqcS;z-Zz)lP)tVGU>p=X4eU>}pC;pMMumNLI>x>P>z8aa4x5 z{i2cD3=1=rwQs^X$qVFK6SDYX>Wp%VIu9Qmgj_5q=f$zLcHFBrSq`xJ<#j63wf9dw?+Y0ixh6@&MjROzK zW4`J8ozOqW3Ghn;+zZ=tw>F*4!I}3IvR?Q2sK}kV~b~ ztb51k7VHtTZ^~W)oXqLtOkBGz!imlEref~w=XAa5;0j+3-gqJ(<;keaPI^GVwCbL; zbjIo@nO+Y*qEe~9%IyP>MQ3|vjKf9bp>Yr{mP$vyhF%2pf$j?}2A}t?lE2vUj-uBY zm)aVukLW}T=mcy9M~v{ZLi^Zm_V0?0LO^^sOSDseCs+^Zh$k^&PRI{D@pfuO5532p z6g;RCm2}9F*QK97k?D9C?GVpFbW#t!8Q(r5piy9f4V0{}WwP)%?wVD=UdwM1tCTSg zV|^R@a2L{A@^gF*=CF@=!qQ?NbY2;ugRo;;>OD{adPnQVd%(Al;-#IiEmqFn*SbkR zM*iNtXLW&m(2nKcHC-_|D1~^7bMOcLFL%3fX9RZ&Lt7G|uj~`5@rK1r3-L!>2UkZt zbHbsw{VzChPXKmwBunvve#mnn`KO0*7m0Z6YzcfLzHLDsvXPGbHm4f!)!&rOxg%sF z*t5%T#F!AS4ffyaP`OBUjmkc=M@P$Nfls0Sv_h`A1OJoopJbeD{5K-ZihZa5x5WMn z_@5U0@4|m7?{S%{Nv=)8{woo`D}QTH;gwPrr^IilLKhW3=pgp0f48^|UM=v~1pWw5+K*Ec}zV%#3{_S~h28l$LSOHJu9^>R|Jr z>N;mS!-XadYk&v2;l>Wu7JZ+CLmisnW1#1zrb_v-g?;yUI`~joF4dRV&za6`sI1dq zY;1Dw{H6Db-)-M;@%`;Qo+8J-y#xEgb29nk&kYzsV^pCx;WJ`9f4}WLezsr;+|+(k zAksUrZrX9!uDDn==`BphihXL}wxKU%yheA>AS2)$gck>N*ylN>HLJ3fdrm=*{}tR% zBDtRA-uKBv-kw?KvQ*7l8H_q=*-`Gpv$(E z75<{hjJ2`~``Pq1(KsbF%g}~7(*)IhadNGDBK9@njT+=tK22`s@a4!`S&xt&XemEp zH;3IvHjIM4u-X}r15+-v{E`h%mgyKc2K~=NQM$~AOQq+JWjaq>87*50 zc%%FjWG=w`Ti8o%JN0DY#S>a5kN$ek!rln$#Q62h>O^jwUyuJ<7I4d`llWH-cyXI{ z-oPf%YZZI}???JP)JeSRge4mloo8j2s%^%HUY`MLJ`=e7n{K>M3>@yPjN%yKmF^(X zWnJJ7;9UXHW<`D)mzol*>kk6^jTUkjcai4U`)7TN8uk)w1IciEm3q)u^mjMvNkScb zH#fWobVk4DDRc&g(qqeJu*8rAVf(<$c#^>s9qI!_lQzeofa+ef? zZ#QTg*ToGdSwlMJ(%0M-^7-R2ekc2Gby%psD0?PWHu6b{q>I@L@z^^fbgvGyh4d-3 zFJvL_OSCsWT&n1~LSJBCfZUp;+NPp64p~^^SJ^avO~_=){C~D{>RioJ3A7Jm?1+9~ zj#-+hN>#~BT7!PsElbz%BE#G*clU)w)1APde&C53`~b>GPfYT9^>*=09C)#YjICQ{ zB8}brAwl2K<;Q zCu7d>)-8O5UKXl&!#(QZ@!e^Du3aDDLcV#TwbJ+632#R6qx#;Jo!ArbgzF;EDfk%z z|HUc(9UBB`VV^85H05$zQlRH;M_r0f1#!yo^oh$kvp(YrS)i?@2wdqC){A)mP$P0`(tt8yHZJu_-lw0Kj9fH zh3?etwu--0>LhyzlIc!%XF4u+!~aJtpM0TIsze*g`nCc`Fo&hkp;W_X8|jwb<6p4b zhf{FB#tr&X=YDe>=X~heX!&lOdolPZCVNftB}00ozI)*hC-hgpP1pe)@UjIa2kdWg z4@7h5uYO)8{nj$&eBK1v!lcXO!<{13@9Nqd*d-f;rxjghWzYcM#QWWc`f`k2<`#E6 z=xVjq5O@@0%sp%CtK z2hsMIxc32DjOoysnUME9Y#nIL8KGw;J(i5U*MzY21l~UD&U9}2X|zl)C-N(h=6%TQ zD@C0Q?@to{K>9K7<;^b=k7dDlx>1*mJ-iZQH>)JmQ3~30s5r*cf=AnfIvzSIW`LjO ziEqt>ZjbP@P0`QofelfE!b?(rmf)>c&mi}cy-L^ne{^xciRGajpZ6^F!=(6E<;c$~ z)(hEFb1}Y1-2<8zj_!x_wn}BN%BSp^D>Bb$LNkwJz2n{*-xt}ivbI00gN?$>A352x zetf6|d%L=YYx8!nP}Hy3*z`XlaMN6waA!Uf_Z!K+*i5kFzaIS7gz5KX zrvPTM0}rX5MSZ2P#WDFT&|lfB)xB!SO@t4uD|zH=+05q%`asIi)4w_ozYwfVU+Z}k zxRHzd?Kqn}EzdL1xEn%ZhJ88LTY!DgV{S381ngSO>qC?mdkW=sBJCmcX9D^|dJW+k z)&%15vAAcn6#TQxJ*H13{QEz1gLO3rb#&RIb3R8wa4z{Tg~K)t3jP1qeMG4oFtg za~iGSQK;oDgOcWEW`b8@Vo#*das zZp2d%e--t)x|T`*Kk8DKpzNhp1Ld!wY~<`RX%XVz#^T0v%Ouerg_XXu1?EMO&j!lw zp!er%^CW^x4Y;Nt%w(Q5)IYMrC7x1;`JsHxBTYpN`zq}ZG?wb$wG>%p&^yopuc}iZ zefrSoP!{o%#5d48F)MHe)3Lx@mIZo3Zy>D1-3VrFRBZPI`j0sq1P@3)Sk~PgqfZLW zuXNuN?9_Rkuw4WHk-nJtd93G^q%+4EoX7&lV3SH`7+$oYZiCJSHiF9keE9qVf28~` zfPLWD|3zGYAN#+U3#5$wU%~~_#{S#6z~r(2CGa^j_8+qKO0;v#wy{9n?e%A|+x*Yn zjXS({ufGT9=-WTiI_Jd3y7jYVu<=~(R(PL?sru@YsN6(4Ka$aIL4WFzUvC}Hzk#_B zu-8lwqyIf;+4>aJ^E%DZcgv&+pAD2J;dd{_o&4&%t}Dm-|5;A>jIF=Ca-f{*lZTc` zL;VBggZOP#y;;^jy-(G$q5u6%-EI6)$Q4ucUR*WF+lu|MB4w=I^Pcq^X+3Jk4S?=B z=4;ajE@NK)li;|#Orj9?f9uC-=MR|hZR?S*6d%~|AtHIzJMUxif7xdjYn{Z0`@o0O z{Cg^AR8P=ukvHF~b!tjsD}XcDZ;xQiFgA6lTfo@Re>eUc@qZo0DazBYbO)98p0C%3 z)FVyP8&yrv|18w!^K-PhM@dgOQ9Es*!@h9q;w88zp`2I3&Kb1x73hz)qaM;fv+gI0 zHh~r`K|HF1Uhb{{?j~&rX!M^4r8@Xkge|zDd#!|>IQfENf~}U`P9gfI20rZ%M&-y5 zjYAb*ofUHXTKYA;T&T_O%{BXyf&bs$1sG(z#hc43XP}4CU*W+S)n3?H&^VC4O5)ox z%-O9+@QuMO(uO4sVtkeW(nFb!u7OGQn!&>3eZM zXt|BsLgS#$mk6>O)oV0Um1btZOjQ^5Nln01hW zk2F?LeZF?j`Ye{oW!oB4ra(uF$eiuloYhO_=0{C`%)`6utm-{^ zjO|jT6#NhJq~#jUQXc-h5~)Ymt=}fx`R7FFw0b&iTYK!{)oc^38L&(tGuJ>5)t!J)pnz=C4xZDmUdxLA{$VWjGhhSc~Wnv+;pF77jLw zyN?@7QomC{R$ux14Cm8m+tYUJb*|1gkKlNxXZ!1PpUJZdcVQxi8fsS)+I6eMJof4WrG^?A_4(Ogq9qsW!0z{4bPoCR+%5PS_Vt!CfVF0qhK6yHT?EtMWZGAW!S_fPt+R1(I-Nj^Y3AN){<&bcZOO<~3tMb*r zYo+Z69g?WBag$M>N^bNyk={;uaWBgT74)O38Gs+~BnDE7To*i7Fw(eDex z6Scn_&?1khojNclmPZ!0Ql2==5^4EX6Fne2%m zbF2U@Fdb>|ZN|HJyUpp~8OO?)P)1yk0Xx@Be5d?X$WQH28F5L2&kesjl%MLQHYhK( zV~gc?!ne_0#F=e}a$ip6+EG)Ew za=@;_8FK`Bl*u7GPv4yfq2pOYXVdiV{d2zg!(4`laNaOys+6De&5}dVX>zUx{O5w| zz_|_HXR?Py`9OIG=8;`+NZyUGe}Ycv@7M>^(S}l1hV7jE-}Xb8^S>|pO3CXPO0H(;!&~O$ zf1`EyO6}9HQyBR1>DSZSPL{{ZjK3o&@Veu>{CiN3i1FVV<}x0}p6p$9gOoFO{%yda zidk^Jduf2J_jYl(zu@&X1NN!bljTNNay2*a?dj8@KhxnY%4vY}h-;wy0N|8=a7d5D z;9wV%tBGb2t|bn0M$@$f?5`*NdgT8b@>9P&BMvDM@i$`SJ(nF)2sTigA#*0#XPl%u zTZNYTUt+Ggd+~nPC%gO>?f8L8w4niAoK}kcZJA-@klAY{{YedAd>VFBSv46>`PW`E z6H@}DfBnd)+r^b__p7?M`!&DIzfApI5GyK7IQUKPBa|(DZzOaV@$9rFbdDt zTe4eDv!&7Yv(PpN+d{SQ2k7Mf+phohJNJ#%LH&FK<*Dpa=;sRL#MI{w!TulpQ|L*= zA+;brI~EttI;1BMzXNfFu6&DmMto{4E`R5c)**fi;xrcQM~75}xM3`Q%^`8PEA>LY z*1>T1?H$NHJosYb$2E|{h{q*&l{{HQck_~@(K76h&0Nssy9%0svxz$8 zz2S(umhOX-Z4Y$8(X}Fqw+Z@Vz(#G@oxZTe1(QOdd2^-x7@A^s#0 z>mrBv2a1C?(dLiSW#PU*SFAa3$06{wR$~Q~Io8p-J{LHi1^CH^mC_Qkr%y}4I@p3b z_(hOogRC|ed{0zIRAZsc#j&4HQCBRpQ5^xod-WUq0MXji^$l^ z@ZX~D;D^+f(HJ=_b7L1G7o#! ztBTbJ;t#Tl4EXPA$Q5fE1+hk*8>-RBp_+8SCl|W)2dVF!WfIPXtFg{pkF*u2U5&vI($%qdII`xB0~(A~-k(_+th9{LsB0XUG@ ziF4wr3@71IYn-Z}5cr)2{AM^?CAu`V5WYiXy}$GRfpUVybEr(3jB$|>r}317W#Hws z&Ua$pg@a`hWQQ9a(7iMlL}j1sqUhX`&r&*1E3kqlEgV<$>StV*v*0VGUiL6w&A|sw zOM>4{_~~`&YP@~E8smn4lpC4X-VD5d80R0Ht!K-2$n%7&jiBu`Z-)pj!Bfu_@A7+s z_gUtn&UCGIfX0w~EHhy*=sx-fx<8gTJ$t-ctNqnLHu7>ucljr`kxhFM?**M2J5M+d zna23}%xdD}D}j$>pL83`_E(}`9OS_BN41U${HHqEFkgN8z*l8`I4h0vn?9diDMNg{ z&v$Ae+Ch0G?09c9L8(FJYZ^k$HS^bIKqrTH-hWJRs%@zO z4t3msJRbSv>uQwA#hEadyZiX$hp^v=Q$|F@>3gf_cwKkG?iW!%n6SuOs?1`~D!hp& zc?zkGcS4P?#|sVBO_1v-{$5_=>!I_Wg5zBq3q-748aK~6ef37Hw{zez)lU7B3~#c| z6yP%hKAE!cPU#e!XKd@`YBHfKCcT<=X|uq>$^HiL7W?&YzpZLd_Fv4$J_Q>E29w~o zlGO!FFf(A<8T~oVI7XKhnhY5<`v7#e!#J}#06ibZlw{FXtSLH!C%Oa%hWPwM|mqE{jwk`ajxBLb%ej?G0#&C(Hal_F2Q)b$-wQ`)RX|(@+7ks2@{-^(a z)Z@Q)u5q9G$6g8Y`Z-$TB##h1aamy(jJL4!2Q!?PppzzeHvjrB)4=EPIC}{^0lnHQ zm4YQ6dYqyBOh+H`EBAI|v}d3L=YJJZ+3%tJ=-APiY0YmCJsf&1Pl5l1~=LPGapZAzIn@Bf%^+Jy6?;V+rRJ-EC)NlvtB%MP)&RdQ`zZ2J{ z8*U0sfsSg*fhy3&t`(XypM_bS2I-C9&skp9fz{yW=x##u<*hGjLVO@u*0j+166@Kk z*t@HQN_QjP>(~NYGkRy*YukHVzm&Vc!G7YerTVse+V$`OQj0rS4gc}#8scYHxc7)N zpX5$#pBDFT5 zWD~tBnrm$6uLft(ns650;)v?pgIHTc&%Dsf4CZCx4xHClcUbGl#yE7B-s<=U>x6yx zsnm!5XF>b-iy1Sk)w${mijEWhu+Jf#6IQrq#owtpk2B2AN6)_>*Pd{J<*piv%gY*0 z01hQYHr2!(h#Mxp-Lm=Z_+O3x2J8=IP^|G+dVr$oI**n@R#i37eZE+V^d$ca_9rbG9SkCM>Z^O$Ju$8+x zKs*oeDm`l2y;yGmh5)T@;F<87{WqYP`C3FU_+?VWB@>&89?T-C#Jzpk0ANwEq zyi7WECfS*If3kyMOKfMnrj79j7O2aB*5Ohc{I~4$ zN35G_S?2>wf3c9h?egtA5Z|^oL-#!8rT?1HLjTx*we3&-Z_$^{eVbl4;rs4Td|Q7= zoImz|RrsI(2k<`=dG>_kl`&f0W}8oZ*ju^LwQz^ks+<)}gH2`%_QGn=^PEp;47d5> zk8#7{(M`{=yBieyG*!^Nkb@s}qLuxW4mtEe)hd>tT^%CdSSrZu+rg`oon=34lP}Aabp4aA0B;FaE;Eoq3gT`Kh7fjj`gkeKb9?55lUYtFM5b4Ad5q#7KlrLKa zdHsc0pGbB{Z1?cSAmdwMd%-$4EDa$~dOqw#s)L0q=`N8qn%-(Jo|1fjBV2k!~2>8dBym0qa@H{l`zHa!{lyTmSGud?XV`$V|O?N@~^J10^ zm}Qws4LCCpVJqbgZR;SLK(fgk9IP^a9ft29)JwFPU}#=$tZo5p`vIFlcDqHK%_e>3 z&BA)-)7nM85@Uopb?_Y=&v%Nv%y$j8@_|9{x(=*g%T=5YYw&%`VdkWB-9EJO3fd52 zZO~q=yZ0`M&mN!6LH0Ib?AD?W%|%NjhI@T#$cXA5pZ{=qvQrz<`Qs~+of_aVTfyqR z!J7luknUNI|DZ#c@t@ujV&_=Bd9ogNF1V%=0s4;vW}6B6QLe-|%$FP$SiepnT|^jd zJ*{fG0luz=sE8MahC=< zuKB>vzpoBx8mpd>TCemJ{c z79VcX8H6}P1p5MLi4>O|`o*7wO>~Ywb(0VmUT4tB3Mgp3t%QCAA11i|SzQ z4T{V;kT*LupIL=F#Hf7Y#$0dDUjn`dc8S=RNbl6RLM?p|A7*;2eWFpsSI}5%Wboy{ zC1z`Bdb!hB;e!s9TkM?h*4!I#??ZT8k2z)n{3bzPjC|5M;5wa6w3w5p=cC;24a4up zpXH`p44Dn{;gfUmw2f!_X1KK7r~X`_P+*_WMucJo*9PYvh1f zYX}+ww`8+54WP@w&N3DJV4LL9`C5V-=c(l1iVv+FN)$K)>)!7-13nJ$kq)2_{~2&O z{@8x-zJj8=<3WoYPOJ;udr6D+FA@D)qNEwKL1!IF)X%Fsp1BGbMCc<(9*qqBb>EGO ztf@`Ch;x>m_YRa3j(CR4q#A4V?l{ehK6i;k?~1R0Z-Q}{8v%ZdbS}?&@)=0$NuTXn z$4(_XEohJ4&QjK8nAOih++&Td$vg00S(8ZDNw?zuE4^_a(#=ue9ejTp;5}28>=ZCx zX~?V8VN)qJ#ywA)UjT*GV@j^%(GW#mvbj3;8}$7kfX^EB!6tyRmLE zY3%x2d^*@M(Or249~d;>g;-;%Yt6e}8UL5oWTgFt`^!s}u+>S#dr!32&^q0H<3HDF zR&1Rzd-Cv&Z7qH=*l<=^r^igY@=;D3V*g>ZCx7=J;HO*6!Q1PwMpZe&!zSom$9xgQ zN4Ts-9~qtVgPD#tA+|5U7Q}4p)Ky`elX3P~0{Lzl)}aVqo#;91e&KEr{doAN(en8S zzr~%dBQyr!1@`9O3c64QULSrWPHyu}g?vtZ!u8{BfcYd}Za3nakPRXp1|eg6_*D!grvI^-p^x=#9|<`3-Gl2UUEQVCCDehrzcX z%GoE(%!$vQ3mUf%G)^OEhEqCT`c;Ey>xjUnf1FDtX*(L{spahN!oaOB7TQkfJNEu6 zp`+D>4<1~Y8)x=Z;XlzHSyfB*#|iO$3GMO2Jaj%3j|Y!=6+8{= zRGrBPa!+Llwo`Q0XAE*@OtS4%!|3W$YI(K$?}faR(VZ8|(pJuOqr?>~o1kuk9IW zga4_yif>u#!q$)GMeQFgfXf}Lo9v>g?mHmU4Z&8Y6Y*@+-+_?y zNmTz4k?ODhx&FiWM)j8}cLm4N^)==L%o#!YY^B|5_o-OBKcU?M*j?U%Hp%a24(cO) zB=`!PmAKr{XJu_c+A#PPJKEli`nMzgF>o)*e8cU;Pda~_;rs+N%ynf}HIIH?#+$Mw*W8*kYsSEO{GEd1h+4x4|7*N`;RobWjCfN0}?v#-;_|_aNb22uTmzDOl zsm*AgaAOPnn9}@J05`tGe+SweKsbgQgMjaP-1rvXsLi*a|2dBFWZ&jgPY@Wd!d$!( zOLHMD5in*T&7{D#*4>RVJ7eEve7}hCv*P>KSeo&>oa!%;wj61Vu{00TqJ7oXOb;_> z0Ci+5{i$-l8tczUtUt!scxC}!(0Rq?elpI0u+KOzK%bN%@QOX%I>1kTqw{7jzER(j zl=0+iJovT-zi)vDS8*;O0FI-vK58+yFC+h(zic*t3pjFO-(+4Of+uz6ac5k5fn!Wy%Se{5M&)=@g1O6N5AYMNg%fp7F_3XVa z&l||2MxMdnMBDPj^0Zu+=XvCTj>>-~md7{}t%v$J1`qrym&GB^;aDE|QZ&ya*X5Cr zhwQ1|9n155G*88KdEf)NECG35L7pD;UA`R6v*@}!rO2a2o~L7ZB0og)%(*TPd@h%b zL!QQ19^uDmo~hU6F(XeR@>Iq0v|f$oNx3c$?oE`9M;_N0JU>PAaM$HYLY^e#Vb&-P zXfWr0=F``F1$?qY$9}m!x;|U!JM09N`@O)Mdw@5Vf<#>@cq_7f7VuN#-q9B2T)P^$ zw~5Mp2>t^8<>o_gmjL^2lK?Fw-Zl0d7A@NW2YoZgzCq{ah_e<$b`veH;SGe<_)hXs zbHekxuPmOI>N$lyIaq8V`H}9sJj)($#hP=dj-p=J#v;J$PHBCt&n*IIf=qIC z)JBGQBK_U09%C&14SKORS+hM2xc!9M>rIzMejWIac+d?GLal7~S0N;tD1bmTH8B24)M|cEur4nhhx9}F-nk2MIdMWaav;_SpoL%1Q zRP0IU9FK>7g$L}^Cj&y`qp3Xwhu` z+^D*S+PZ{%B&QI(U)KzjD|qz7r&1;Q#AKa?%G=PlPhe-qh1ByPPuEf&9(Oz#bj&nP z3g1_4tY#RKIHAF3z#QXF<(ri#OSXqJ=gJ#MA%Kk_MnAN^xSS!1A(4{8h&;Db)Gl^4__@sLp`nircxb6d=i2_I*W z(dev_wa1UpTGasWjv>@z|F03o^F;(d-t4;@VGuGil_8n?3}lRzSPQ2S7UNsmU5lh7 z^NrbcWvRWj&eUEGcP=^m2|=|XQB2}(s4FSFnB*!}3BLfzF0N)lCy>wA-uD?q-E{XR|r}SyxPsqkxh4 z-OX%g>-2RdhpMaDA9(CKcq_T;$$+;c1~1t$YQ^z7ePrYMRw1QU=;6i6>tL9#zyLn? z|04`TKbRaJ0R|xk!_wUE6QtWw0_V4Yo#Gbo&$;+UYiJM06}ICp%PqJ^SSj+o zX27bkY-4u<&a1G+faS)SjL8NIcfak_4!|0AiEC8Ol%iq2%x6&QM;H z0D1twAmNj_fIkfQ-}E1h!4F&Q8~KpNK>L@7IpXl9+yvP9zXq7eM|M2cZvgT=?PWxl zTaiwYamnk3oK?ddbKeMd&xE}*&5{u2G3VzJ%PN6eD>3fYHEKk z>N^3RZ2x7G!<5ItCU&{|Bdlfaa@2lMkNH)H)B)my)NSej@k{Cs>{S$Yssrjn>OdOq zA9(Nv#Z|eQr~PCC`ax^nM17Z|{0$Fy7o%;W6EgMLmJ7^VUi7eW)lImmY! z`Ocm#m(tOnYq37lo>q!J>uszayq%PVe8eM7LzywY=L-0qeDuW-Ys)n>qxuN=64Wat z#nRaDjOsR|iAdvOX{|_Ob91ua1&sqtLY9QJ*vNYF^4`MJhJo_ z#&9-xQI(AauHp`H7V6Bu7%aT{z~s6$_`e1Jw^uxW@(uhyg#W73yZp_6%y`Cd)|<5i zG+!r&g9oJeOa6co z?)7&m;j4a?Tx6Ln>~YVWVa=?kcY#Bbhs+quWQ(_84noq)sBLVR#?%X+N346VzY_gS zf7IkK>x>tkL%-ia`~<>_2tAl<{iDG`^Y_8R#=A#v1m8mYdu={+VchrHA}jbT*=1bM zBCVkJ3_7J3OCk&7>Ux2j3F|z&z@OlbyLY4BWuKr4{fXX1`22yFYc{p-tELD4MsV5WYKu^+OpU)s~D8t>0uER&8Nc zl`E}i`bp3v$t*Yd_#%FIqVR}YUy(R`6m>AjXJ*{Lo`L`LO?OB)eCz9!5s|GTcD znJCj`f2b$9D0#RBc?OU1J=X?%_B9Jnp-hucWv?3273qe}?rA^rk@spw2Yvgf9UbZ# zA08iof1YO&pU@4{I3yib4Znvv2>yzzoRRvo{OZ+DN(t_Y2Zs_}t?O^^Y+7guP2Q4m zSH(AJr>CDZFIH_K8AdDfuJIM)hpCJYeeOa%(}ctT>-u;9?SQ`-ar&Nv&}`LzcWvlD z_T3IR#-AQPd~M)^egA-y2Jnw2sWQP1S? z9zXUy_w0yGZGP$vG1MUoon>7dt1IH%I6^97=ZD%on8BE$u- zUz+xH#I-#r{K7CloPtTBOKh73Y;^gXK=u%^7Z#lFQ<*KLW}6mMw9z3yY` zVG(O(b|3kazBwS9b<^4X>b_Ti_q2ag+f)blsJ3XVjDYn__{O&5et*1?BtEJj5 zDY*4bS5Z9dn;7^S4tEVSLV7*>gOOcOkSJdaKQ$)^18OR$J*l1RvhM|ElFlWqNe9CY}mNm8sE8ajZbIe zzM=M6ck&2y9~f7TmP!$LtGmXTgTM_Tbt375alS{MdUjWM6PV|^g(bQg&vAKMomBNM&pLOSk(ejBRUSfw|Rnp1)9k|Cp zH`6d4oO~2Ap0}Iy6uN2L8iK(K+DK#V`Kr0dcpu5N=mYXn8vDAdh?76{KPMdG(=hgL zt0HA#TPoyq$fCgc1l$j!|CHD8a95EU@fxh>O@M*$l9MI(Hevtq^kr$oXJwKvtxcrU zpf|e=k>_g6mK$Lc9hD`47jwUb%)s4~I>OK2Z@))|?X+uVH9wy#xC#6`cOrEpBBb>= zamG-9Z)0oF)F);oJdnIa3z*}DYWF0-|MGna;IAdOT3F*=1iS5cTl|*3MO+V!o95J{ zk*Tylz<#Dufk|xAV?3yRhB9ycn#qkUP`KlY>)n9>=hdsTF1T%u-ky_NIDb9EE05>Vq5RhvFG^!>b2S&4 zQB7+~xho1dNYC{Q)*jAQQjI7}lrFZ>k;HA-BrtM-D%?6!l^^|51AY%)<$(GG&X5& zR;|YQaBg^~j}x;lcrf;7U_+6SJ#Nh;z@f(veTA-Xr?U2Wz)No<7!jxY5smPR({Zg! z;TxK;Ry4WuhO^~oecN(hIv#Px_l(1xhTZsnsettmz7l>iq zutr?Kxm@&#?rjndkxn(;nLJEBG&0d<81#sj-EMXw#PxFUUwM68-E&M_o)Bj^_u_}LwZPLKle*UKUA_~!M_8i znLIAF-)&OfRiL?}dxYQ-q^*$QsSjzmC&majK$|vNclwAfU4zWn8rc`TZInk# z!TvxvlPxZbYcD&lx6sm|#}l_Wx4$?(t1k>HhG_-nmg~NiP({ifJ0K zUN20FixPfZka7?k`~b^+O!oo9`Q7VaeN*1R~cuFN?bBVI4Y--claCK0fB3OGT!E9_ueUn=MZ;RW%((fIeD z2ro*&vli2LoZGOTeahfrX7r8t-2nQNg7@&GgXS-22p;Te2qv`qO-cEjiT1qtVY|uL zHYmNMgEP&6e&Su(W3nyiTQd1-QBs;|ZyAWw9C33?RGUF8I}x~E9~_Ck_z@bxtF|B{ z+0R<^N#$4eH3Y4g1HX>B;L9dxjM^=@8-)#$}6itZLYYj4L#n?Yz7ZN z^v8c&elFnsUig7@3-V~+rEv|<-IvYdyo|e-X67*0W?lk88tUO7OCM-!H_8jhgKopEx@qqp7;7QMO8aQA;!^A3 zX#Gwa(>J&iwc|enX-+T&XGHPVNI>3|R<(>4xX-PxZ?s@e=#1#c8F35hV&5K`$((XG z-8oP?aHIa;NN3P2_zQ=(`wPRc??UCx$|lKwTYb@I>l=wq?Z$UHKjJN&G==69WioHp zH@4i?pIp%H@NNGUzV9!a0vJSZ%Ugv!f*}Xk4fOfQ4e(A1^gM3Md*vqhCzP|_mREvz z0?Ee`z(>L^A^LRb3;68NaLY-iVnG|dfC0g9*Kcn>r@BN|WO`SH75+nGNWmF6PaNr? z@ea!VD7(eWB$Cz00{jR<@8oa%A9(}m`U38~tLt}uce#G&_9#TJB@z$#SH{IaVDZSy%TW-;>VlbcD!p~GM%;P&D+0~7%@J&-=hCF zTsBvd&!gfi_Dl|Q{~wxG!`6K0*M+};pU@Xfw6A9>jSjjCAX@pZCehUvPC4C#Gh7Ru z;gE-WnCM9C1ueO`*+(BqIZZk^W5M6hd57rNxSW69hkY4VAJeYh1^&L9*G!KVk2oBG zrAMtj@2U>^h7HcYA7$`mF*YA(Su_`7%r!^cbEf!nw9#R`$ z$2fbbGz5JVyOCc{_yzt=+Z|iyDqoK>*TL6630gM=vcNY{pGt>8A4g)m1Pk_G^*hpt zkHI;E<}(Gdw>hXQ6>E%mES2BNmVKkI_m?e4Jx0`{%JR|F*b2I$E0pd1s1Y3kv)pt^11G@(Di= zd}HwV?7d|X^igRm7s>w|4?J(RX_nJ{65;v$v0W>8^eeyyt-AgQ_6XQf#s0!5Pb(xy zo51Vgye2U(V~xhZa=&0|)#S+8R3;H+D7*vhvZA>*zn_!wAwxmba;KAsjj%Hfk~)N-<^q^}O*{M!*U3mrlAjgs(sG4XPcO`2$&?xzYmt2=H75TIfh<`e?s3;;c>oPg{^6 z>Q#SJM$j_QS&Ur+y*n{CDJ*~1PlC^+WZGZ7(Y6M1J0s44G_Q0n zJQ!q7e>dS^MEL^u$Np|>7b}f zg7nmQTK=M3Y(RQ)JguB67Y%?Dv*~>L0$oJTudR9b^& z70+UBhFq%ML1pfEYL>VRVbY~pB7HaD`wWEH2gl4rU1#XqpewUPro2?5K^xri7xVbu zEqPSOeNO++~R{>J7VW+(Su&0a%m56V|2d7Jgh-q2%;b{h1O+^HWu z7rIe^I~jayej4{WM_vzoiMm>rmx~3sm#`rJ9+YQx$dnM*MhzhW@_v%1Q#r?z<*-GD zvG%^0NA=%}w@6Ic6yla|$+O`9pMWl!guNlIz0gMG&!RlDZwk%8y#U==(0{DoBPKRM&juQQg*+<>DBWnU6Xe;Jd68 z`Ak@#jx7uSSFon3Tm|cRl4P4So?S}}q2Hq1IwzmL-2Pl>B8^qReFVN?%o4%Fg7&58 zpVT%gR+Wq6P-fbyJD4B*#**-Jp+)!+JgA@4A1U4+?QhG)htQvE=+6w)zY+O7>b(!; zILwb0FiQZO4t#A0S)2*qQQx#rm5WaUZrbI~=dtjn&^U~Bjq|zClXPe|}p&;E+~c z8=}y(zc#cV<=Ctjx@UkkoJ6@f=*KuAsdZ5Mpw@5>LxL z3&ldDFT~Tz*@fa8%VRncqw!uzl}TVOSwtflf$M(&O!@2=#}aP83f%q%^ZO3gOakVT zXvBWoU>D8x*O+Uf2WjXN;p|^QD`?H!8BafkHFAc1{bnj;qWU?l@KK8S$-y@n^*A-WixVJ6$B*a)&4m_mq8~c6N8|K^zD%)i4V`RH4^1f8 z8k*d(HMCqZcpgOF2<2F4#A$;kx7XsyIc;$F0{8GXI-NuRh~EUQhybsvnD5V8E#%aT z(T^I3|7{B8Hvij9L_YQ&hP$Fg$osGZdEiA?xLC5q#%0rd8-9{^5Z?1oyF?elO?#(f zA9$|B3Y_Kl@!NabIxtRLTY~htFX*{Ryn3+=GF!3mJPj}1Cc7&Y31?k(R zj<;td?%_;CUnA!Yo|0kh}FBCbXUypxRE-n<; zEsLEmXpY$fgR*fpDd#$2W0-V`fQJ{(89Xlz{Qswg;?xeiDS$rtXCw!6JKhaVf^4C{ zmXW=R=6l}69eLe$OO_pWj>ExV;NbiN^oE^mEpA?;1>JzYz)3kM;cid<$P(meY=EIL zo0F#C&OipgO!pdzirwnpKR!tB`Fmh1=g8IF=GV?y+`G^hSG+I6&kMy@krt5tx0TS( zy>VDfh>wNtLAb(1@f`SOI>%F(wmL&xh(4x%H&di{liQ>@YB==gIpPQZ%=EzSL@>!~ zHzf<(inz~VUjsC=rwnhZy8jwt;cX$SkSM0Zj#gL~klEa&SJ?8@wS0S12xrG~IxiT& zi>C;|e{d+rFfMlN@1bPG2icoKUaYqcnwj%It-=Ku$tYlj(Kb#I;q(1mb_g_ed z4tJ(<=MqJLucoxt$sfXtc9nV6eW^96$8O;P8){RN(=m28WFCZHTc3^N*UdS2SK0vE0i2cS`Dykw^Uon& zIn^Ga7)5=DF$VVO%OQ4nYlzycD8hGVN-OD-QW`$6V1GRI>R}dbroLF5DZz25?{AQO zdle?;fKD>h$3bp-Z})pUHMX4^$UCY=I+}K>^ei%XhDkA()7@GU))wb%Qe|E8<0C!t z%%;{%)G-coI0vvJ89zH@>N|PX;{N8W!BfBPygDaLStNc*d?9E%)mgvRiZ^C*utuou z++>GegM9cjh7Apu0N*@H;nc7@=HqM*wXtZt+6Li&dA!dlMBCBlo%lsCKOINj4bdIt z$97c~qUtTah4zclKGBT_=iyCr7yKXtZ)j|!j|4umoEvNOhrnHfLRVPi>FK*y;ZkXR<1@@`qC*#LI4hT>x(OFXawA{#98saNLp;7-PYE zrGfhBevWhu?6;Mj0$YL=x0Q)RE$;I522U7!wK-?**cQNM;Q!6H)q4Qtm|$X@msL7f zYrqrlXuhN1nr;;MwM{djrwf~F&lT~lZ%i)~D}+GM1pRouz==5B1%# zv>XpLhvWZ`hwMl^9S^yqv9v!P=5*ACmQsI@Ic*fOPh+7R583f}Iv%pm;^}zEPQ=sk zQ1f{#oisDkv$4!+(}W$WJr?y$06Ivt+X|fJicCQp?MI)QTFp9?n26#uj;pi2h#|T>=8|fk0sSMdE_!rS$5l<`I)w2-QI~?^+#ePQZOab4F z^=u-V?mq+G`|0y#SBQ2VTqLeTdSpDU99ks4`FpZClQ^{y?GjI%n$2aS4)OKrT{8%IUmzq5svT%Aol{ocHZ(P<7|LX*+!MSz!^-OPS)Pt691zfmGkio)M z;3nAM;k_E%@g98O=+s=T`bwgzK(r(7~qu?elJvw_7VWI8B|s%wyF8Y(n90B7gX4> ztI3rFTdpWA=xnoF?HDhEt=0U)O*?aGUlwqWK(GfdI`5mR)??n09&==3z>aeVXA;%wU<=Qlo7W3i<-5Qjj zxsc@KlUdklBif=tKA$bG_yA`%4s=<-nVI@3L;v4oUY|g zep=?;Q{Om%qYQT;`y(UWe_aUM(u#H%^zQo-fG=j~Q-&AE?u$sa*5ET&CgbfxeOF`a z4~uACe7ep7GzCaW{WQxN+wR)Rm9%$zL`G z8_?d`V+J>L=<0Z!WpuxR=|Z$oW9Ls5Q5fwwmC#w3T!^!^a#~-NtLRLE!rZhj^!=N5 zKz3ZxIjy*KGGK2ObX6w7@c>ht51i}&@;{$L8zatfnHl)c=sg7{T?JcTn3w#347lhp z@1xsPJq>pu`*ky|BfKBVOhG-U!-hI+X7F#LypL5v01Ta#T_J4;fL;H_Qm6?lpIPw@Vx(%|_O{!`1IpD|FTmeaZ-$oDE*i7!lU z<>r{6^YcY;8T=j-{OCNAvew|PP&85!LVJWs32Mky>JeIyzOg7aC&Xt(!8>Fhv}gJY zOp!pFCPFscppUd8)#1;x0>3Kkn$rS&yo}L|*^rT#Nnw z3hpYepR%}X2F3~96g$o^pv9S!a7RP;P48cl-==dD@u%EPc?WaY_hzHMlyCgL@dvp& zKYTE%{hR0CF`U*J!R3aj(qE8#rlyT+twBiR*VxHsH0(`)uO3VA0j(q7z5hV_AD+TI z#mC0)sc=)F#%H?R6uqp~q*EHYkwuFcRoM%f%R*#})2D+gS9Qs~cV8R%67^CUT8{o+`VIBG_nDA~VuFsO( zHwWWews55T_kbTe{;=r%VkGP;LXQ(L_M^{)-)j9w{X3>CqJ3>g^N+v@HqGZccJ+K| z82(`?FAY9S767(>pS&ZXjWcT%jVVR3n$~`c!P5}`fAh)3;yI*Wh^Hf8EEazcpK2>{ujT)2wiv)2d&0-S(E#)a z<9GKl`f9i7IUQS8s5||fAP1ksc`+Lyw{KJEiNZmrA7e{Hx-U0BsDTf>3ieowrhOCS z7XMbVu}zq!M0 za{}P_&SJ>RaPFdWYx)6}%n6FG=j*|uJ?!XAYKNXU@bPE-pTn7r!S};}%;G7GHwELR zZ}P>(kRNz`*PiV!RU(j0Ada_yr2@$*$Sx@6DRG}&T{mpKyo31ZQ|o_L?LW^zJr~!+ z>QTO1EZUJihxASA^X0{$P4LlzeTMp%0sn5xSA35%0Qdpe&(==$O&4HG(Gnlml_w0U zoR#oa3wkO;_WK=VD`wcZgH4{&W~A3r*=2YKYm=WO9ba0T3f9#|;Gyo5Vv+E1VvhDc z&|^;kas49bbKxxy;n1~{2G4f%O@se8ACN^CY+d)gxkN%5Gn2VWvF(*Xq}{E?db&#^osrx+FEeunc9LoBYUw% zv^WosT#B}ZI;n6b_P+CzD`{;QeF>u3KF?-un`dKPjUi1@V~Fb6-dX#$-o7J9@uu$D zw<(m%VqwjpSXdWNZ$4Q2HeRiiQJH%DPk3T-<<%u<>zR~FYPaELf7z$#C%0jQNHmkb z*|cLb%A38DE49MYzEaS##~;S`r%)bgcI?hR5&t0_&g)m#SSjx&>hrHosWhYCWA<02R7Q}VgEGre=1)(*1vtDS$x-|dX}=R~ zgGX*g+Tx=43lhT^sPB{TAM!Jv1=;z!s6F!q;KSz|-qOlna8eE8*URCT>7YSckNAHr zMEoa%v<~s}vtZ-t`#Yqyh%1Q8ok`MDh##W--Xv)`;=9o<>&})c5Z_7hAG4)$#CIVs zcaD)3AZ{-3wUF# zd{8VeqxHVVrxmJvq?4Cwi?SKmPwPK7cqXlm;c?_+S=@|tPCRY?r!2}yTao5~=iY;| zSPXe6ttroXydhO|(gK9d2$#Xvn+?DHWd;we3BlHSYfTBbw|j}!)Xll#^YJxBa}cC8 zHK*j(nwo*OF8X3^H6M~e)3N7(etbgb45A;1cOgzP&lyh0OwbOqu@$uLV{2S1oyHo6 zZhm}?Yb8JW!>j!%R{KNuI_YTV1GHnH{O{2YY_7dZ{fo{Mx5fKMyu%La-&6C{{w?#w zW+o=MX_*uXW(s;;RoP*?RUS&`ssx4C)dL!nbt{Ucr5Sc z$7J{2P5t0MPf%$Ly`BE=^g#5zKzUgE9V=t&PK!4kGV;90`(Z_F{ZU>u@*>Flomx(o zC~p<=*scG@@+y!gKQ_5?k6NxqE$2p_fV@Y2RNrPbZw~Uj$cw7wUQ_d&$kRfH%{)-2 zQYYob^O}*Te->j^UX*g{6C0>d^JK^hWJ&$fqj-KdE;^U=S<0i_>a;_~59D*gHE?-1{rtkR#qQM_-mg!7Q+c?am^#T;n@ z;?3BD{#gB%cH_5AViVRS$?PXBjnO4OPM4yrqxdHFR_A91Pw!K)H7frgi#DVq@ihBc z786zaqnC^-{n1OKf9x;)33lmUD22|My51uzX-}v1J`(>8$Nwwb1Wf}ydY#rg{HC|W z*83O}=+PUr-tCX5>;1-OgWV@kC()c2p8@>=FO!A!?LV7^w^jC9;-$#O&8{Bq|9lLZ zw9|N3e%GY-GQ9 zAM5&~emctRX$p;lU9fgdM+==7Q_J><;zY|<^fejRNNc?5n8Z{&-;C>OyQ#M_hd*PBK~Xe z0P?<((%%q22fUQ8j+EX({0-zYWxVtT;)}4}*nbU`b|HR0<)5%fuOdFMp0*}OUx(vTU5Aye~ZD{Qt6$N7%KyVF^ZzpZUybEfA( zUd9CP%9S}ovNIyFd%G6FD9V)@yupI)OS~tu<9>|$6n4d7-%E`@>d&J$<)nwggyB^d zrJ;yqC9=}}023lBx50Ky3!5oS5r(%Ok4~`c1dN$|$(0#sb8C;hzD4urVk$qI(h+$* zf2;xba={P>-?TJN3-uR2_-78at9d(%3ASr;__6;yyNAd3>yICml1l~ zL6W_YuMN*-+2w;Cg=*^&dph_fzfI_VD9y;Bddp=f8Z*FY#lz>o{n~n#1{+a6zQKGF#40pJDJ2t=Bw!k7(`T ziKkJ&v3%HVh5kllzrpkBW7Lk%M>HbLqo!kLU%iQM~5xJz~o-=zp#{ zUzPwGq#W5OzJm1Bc$yvCC^jHH8R@04lPsK>CBA_4xOiHQ&Jz7dkB+C6o>}5Lq(>tC z|Ij&a-yuT`JA_ zK1N$3)%~Sj(AM`sH$9VNOx0r6ui&zB9x zH}8p!So0e3x9CG^&h%{c%wMd^#M!0;0g2!|Kx55ehwWLEGyZmn3g1C{hKR-a4x9GC zj?gp6->wU+B>p7@d=&XXYhq11HPeCDUBS>1>|>4EZLc3hcsniZLi%=Eh;yVWzftMo z4|hu)NY4>LKaMeJH{xByuP;OYuqNLeNEd1(tij+rNKbeMwBs-*y^1)=frwVhKXXzu z(toCJKWn8I5xwX_-e&r)5V zjFvW`>~-w<^3fscS)>pAojgk`(OVSa2YM*&;iU@D;}WD>@|pM*<$cFX?>ri#Z!fqF z9&?2Wd^+Swi2DI^ISRiqi>{U_@J|p%zKDG9Qd6Y`^-MxOhkBZO;1>pQ8D%)+XCrP# z8H!utWrVY)%8}j}?h`B;n05xO8%@Cwk>-+pJ4B44Zgo%jAz!3W`%DZs=Re(FN_Zjn z>M95FRr_@3Gb;;k`*!krf2j*|q$wB#olb7~kJvL!>&%tfvHWtE3vI)OIoT8RV;mW% zf8!Dd{D;iN{ejPy6{!zSrZPWgy{kOT*q6A6v3l!+cC1?~;ILX?%($l}Gz#T@Qp=5c zSFK~IL(D?C@b~icbjm-)zf0vuAAbRvzoV_1by+fMg0+Nqf+XF)lV z!`xhSwUkXWvu~Ht`A0L1&9}fV!H#AJ+HHC~v$6uVsE0vzQSUH_4yj&aupSM|W22GX*Fk6x^(4Zi(p zZBU2w<^n!CXnM}o&yc=j_PDD*JX#wZg0l2YkN+l?-hb5=PeVU1I%7#~@UG*r@5%V@ zkg~B?lTO%RPo6PI9i!UmwITL#ZHRxk7P^?V@Wojh8Uz{l5T$799m?FPiHd9L(rPp8 zDHcx6qH)X%_J1&R^;B9o2lh_A2?BvB>b}8|ME^GM{;O+aJ=qEL)5&`<6e=cqnMy z|4>lp%Gxr<&DDLFZF%|*mt#xLalS6?(R+`l6k|QF*%1_O>+#p znqCB5nC@+P$@7L?H53lJ$`@?QTdLFthq{Jc9bPi*YU17nw^*wt7+wn`5C*TNs+3WWOLx&H0j zig1tbQksHa^}n)>d}12Vj>VW7^NEQ!Qk#sA^mfMUiPiC{T`Rp= zO}MhgTD#CFl8yD9pqGTNOd2Hmzu?rhOKI&Me;&On&T8lDobZdl0r%4Ov^DRE=dcU%d!rQvirpP@WZ(nR*POF5R1^eZ+aT;`&{>2$05-Zp zNpo(LnQbXKbbmX)+u*tJ#Q8FUt=zLwyo2U%)kaZ3op0b9?eQnU@OQQXDp3>8{j9( zk-mNJr#)X@beHrS)a(DbP;{d{k{uErkbHn$r*S~f6tr;)WSB?h#rEu0oISkQvuRIz z6Y&a^_hLWZg}8wI*pB=P+}je*Nquf$H8TmunzBdLxnN&DDvo{xcZ>KI__jb?e#qcS z#Jmo{d@B7LMK97?q)kY(Hor*aw5wwK@@C)|%`Lka;~9yMeC1Z2wvyz3!>`5g@xbc- z(q`Zz-T@AQ&KmecPNF!@AK()?iRu^ZeieTj8eSku~nzOL+2ox7dMDcg`(#mN1cI=7d{`z^yxgTN>bw2Dqc0O*AMNnrytc zR}a3B@MkID4cPrR93sAnaAsgWiEmQpFMd8I8Sd?K_z=PHsiIr_8`hx8ztOz)VBP0n z-gd9)FDt+qQ@)TTT`7spVS_45@%g62=Ep_j)GUsTg<&iUFqecEf&M~q`$63QFFRkB z3V1c2@Qd|GPl~4_pZi5Br(GYLpZC}FmlEvctGdeh@CQe-5F^b4_$`TB9=7Xgl<&2v7CUYy6nzVO6Q9 z#rtc5y$&*u{gem)egkvD0p4m}aj7^od;1@09%wzwfTsrEq&VEw_59i0s{H+S-h9>n zm#O_A{(v)$d}Fk93GwX|@4QzkL|yACUKv~0B!8zl zSLe0wF3`!?9F4|$t3o;U@nGpX@@Sngth4uUUZb@|<7vQojzSH_HI@2wrAQRP{tc-nl;FB1M}e;1p(6PPE0x!kX-tiBSPyRkmp!+E*N zFJPD0SbZI5=^f1^JNFOFpQ6D&JRrYw^#MK@2hz*o6N%C|PtiF& z9ATB$FgNTBk9m#dL35(=0`lZ@eC4_LybY|?Q%K*wR+VMrZ^^D)nE$zGGtf0d+>dg9 zwxj*h*gg?PdIIRJT&!2={0B(izQ*b7H;?G?vs(2#o&D7GLYoP$k7aXWDC4Sc&m zbzjp+wEqm;InmzJk`H=%I7Qlu_@e^qyOAO_AU<#xMf=adUDPJT2jsc5MrJxt=Lx3X zQB5a#)x|;T8u=CS*~NP#S|5|B%wDr9BmP&)|9*-pBX&~!OS5`M^&1-J55H0GsI-fa z-}8VfBVL96$nANO3-!E4^&EOgdbK#V4#c_84Fc{rM@*G#5Le(&%z`~87jj!#2Q-%r ztOGuMH>qPyQVCF`hPi z*fZn*`fxsDtUEch8)s=v$uY4M>G4Pt4aquLA56?gUk>xFR{VEVdF)K6`Lw_`3g3>a z-*l~O(Uuu{HS2!*u`~toR$I#Q*Jk713%;Q{9>y3I=(%7YOw65~V}>2%35@yn%`%-toirx-p8@d%zL{XZ z{3Mk>S0?sQ+0*4>pdd}vG10;=Sz|%k83nY0)^$4Wg3S48RXWJB^`8N*XrJgoakgf; z+5U))WJhvG;B7s4Zi?3-uFa3d>%;&3UTSmvUaF}$elN8r@b+5*D;Iv&LrA`w*q}^-q5~*Iy1iOFB|3<);bCG zorT=otiH__YJHHi3UT}2KP`{-Pm6oOX79vGk_YuLZsyI4=p)i<-}N=F>rcUV-(%qE z_Lqxl{nKZNEIP6B0`lpe*N;79Am5DqQ}KN6%U|-n$nQpeJL=*3O_d}^uUd+A`N>e} z6U6_WXh8pi64mqWn3`Kp>i2NOi;zqo)BKY-a!qdIbn^4;V+}0j2c!pP;FUz1c zcs3v^1AW%ixL!qDG#;+=UqtgjzM;ldkNp2_EH&{y4~%6z`k?mpv|Fskx7OT1Ziz75 zIrCpKRW7?YaIXezJU_8=5y}trk>=IE&IH|niIpX{D#@lk@{=K0#a}U4}DSsSEKT zpyTpMo790g=Rle3cS-+1{MWz-_EDDfKH?6F-^^3xn0?rv*ntNntUu3Ul$VcBQ}?Rr zv?qQ1E9o`l{{wPj`DmK79r6F9_)lr-UiCX__vc?pb;w^!@wRai?NvKyU-@o~M0?e1 z6hAgr-K)G*=ic9_d(~0Y!#>KDd?@oc?p@he(HIRX~g)y$NYrBdiBB6Y2HwwESg2>_)meo>tBU z#QjJ=75_i$4Tw$O^p}2s-_~#YOUuERWfQ-x7$l0D5SJ0Bw&WE7_1u&AQEWexz;CYw z4NZPL#&6R;#)Fq4p6h4OX@2?Qm@NG8NQroFI=>JtZq)0R|3u%ti^WdRZG)l_f28!n z#o~5dV@nZa;iI#gc6tEwMom-m0))5o)vE~>Gv?gF`}bD;!bi8G4|MLd;Xk+YLw9*` z*Hg}mOX*HJ%%mKJc{a_8^UQI0Q=b}O9iIB4L0?u;JCWJq1xy;NtUT zBMBb=6%egRcOiWb(#nm1NPVk$GR70kTGd}l@L^x-DskUldJZriE-(}A`8@VICg>$C zLM~#IjNjw#7_!;FMc|hgVYu3_z9*aNyHplYn3#uw&rJwzwhJM4P!4g2Y}Z#s-aH}~1%gZfTCWTy;zk#_LGq|eUm^?S)aRT9bv6uD?4{3;S( z842U<2hIj|z(Dnr0{@IT(=Bf9$nIbA@Gh5w{W7}{4CbIs;=icB8R)O(fAp91hN-^^ z@&1w>GwPG3edDb@S@8cXyva4j+b7>cm%8A4#}%8W*H^%PK4chHobTFDHX%2h-JHwi za>f3T9`~EgD5p8(4_Uhn?(+D5w0ZCpDbxoE9?9*vFL=TqoPe%zHw07Fxm!6$Y-F4(XC)6@2n4%CgQuAVi#g!sE|?ffkGve=KzYesj8D|6$?zGBd5+y)~+Sr$v#2cDzLtpm&-r zXiS5ckt6)!ipB?V*KOtJdV`aqcC!_5Zpa950lV`6=6LiO=!6qYvQ7qqlb~Zvc;asx zA0&Qm1o)bYw&JN&p4qeZreUnH@+oThjClEm4Bq1p2RiL2OZP16i(+pR$sh7+*v_+| zeS)pY0l(Flt0YG_xlZ#3wh`|i=CYyL>F*cwmQQ(7qz z--xFhkmin*;Eb@^Cm$`bMd2foV80H1BHsSJy%zTpwCNQz>HesuawPhc7(1g##@wYj zRR#5sC4Uj(gvWejduU8T=7ptRy4Pn~dS}2otv2#^l#?5{5BgiJ0ep+RyMSb~r5u>`g5Q7<*xE%4E82_AOYU$i*2b%*bt%JIgj zz0tx8WkH;2EXKQfrz)^5jIsY3@MnUqcH%)@oyIY$);OJ&JG+(?Sv$0_0Y9oX75$+$ zn(+o{6z<@&T&Z;x!jgjXN>y+)?&;q}ed$6|aQNZ7LvxIV-n-y8m4i%uT*uv^T>IUj zJKOILy^eP8FSt82z7w_s+M!#q2WO*`{@~f=*!O`qf&7VEYV%X8yY&gh+Wd+w*oP>Ku;o{7F1;*WJh#W!->`%(^aJlPSu|cTfo(3AP;X>#PLzKz6s;fQ`r-` zDt25~b*X()8kfK1rMZx$QW^cRztWwcn+eH`hp*T-s6N4jeT1*#l}V18e7-uni?hD! zbegzReD!wveuS%v!TB}mqm*vlsC;gVMZo+0``c4f3$tFb7`45VFvdqw|6Rsk_eSwX zspKkWUPtW|Wz~wnU9B6o1y6I;%o*5gL>jUk)1#ot!`mkXd)kIqGlymGSoHg_eNvG{ znN);y?OFSzU=(@@sc!2_*gML#v$-wi!*=s7hh58mkfCOe_;;Rxw6_vw4xb)%3j0S zlY@^(dbf%9>DE_&XZEx{6wXbXJIM5Z+54e{lIfo z>X(b5UtE>H&Fo;XsXp@f$gKg;j7+py#20A%z^C6B3&VfHf3%<E0p@*U{dLtm(GK%UV8SeQUNTc`Jx$%rR_Pq4%0H0^84 z6oYD$nrPc_jEDRW(VPy-Wn&xIE1FZz3uT$p*93ig@V*{zTsY7;|N7{EF6!h)ZA4#* zPIGa8Gi?glxx#xe^u1~L%lznk?G}0`U=_60+VFqiEUvH872X{Z_SD;l&w!2bJ@w87 zfLV-I`h2uE6Rm9c8GenBFMz&g?pqV2{6xU-y){EU7PJ{TDhIW|efi>#W&iWPYw_P4 z{MX)&J1F?C9t(EEi`kCXK|mUCv+dMGt$%WHZA8Kga_((6x;A3V+ZEo_=8O zCLBluyj}*c$Um7PQd#b}r7?;%9yrFGAsTwAgWmDNr|?{VXfSZ(9ct&GKQ!SJ1Kx1O zWJ|PHz*b*y3Fy+e_V(l~_$absPvh|xGKz1(&U(DT9%S+YkJB(_3&w6bXg9ZDUYCF- zB;d`U-@#Su@y!Q&Ko{s7jydtt_=umwJTCiK=cf70M*Fnab6(gP%1y|nwo}{T&pDjh zdh)lBIl-Pewb|6!fOnsXXfyVv*#df-)E#Tn2)ywN4MF`8&ip3Y`v&dJ$6f@x4A7yj zhdu4!zj6V~Wn*{ipLg@Ti@|4r1-ur+8@u60{!+Ne3IB15y#9hC{uUf>G}mA~bkNv< zJF>7<+IfEqmkM~K8h4+ZV&r=N;Q*~Uv?KId{vcDd|I&Z*1-Z3vD$`9GM{X^HZPgb2 z5*KGTLGO}mU=70%~=Mw?rUH6YF2EDE2ou=AB3UrU=^Di;Q@jPFYTdOHF)pEig z;RnU*<56CY3sj^LicX)44`%;T)qb_bk>`>%rru z0dBtr+$;n)+}Xd?uJQ+B3eH$E`T@FrYA5)*Y3orZ{4ndl2fuEWo*~d^2=idIa#lJ$CD4@N}7z z{kdGxwK7(bTbTwrpa+dfOh|Dxb=wbQ5!^fkH>?@d^Pc@e*+%fwy(;`j_mrz8{!0%W z9)P`rd|84X6^*SP>WLin2f=qq6(aP7 zB8uxAd@PXt;$tPWpdFERc8ovo@mYhowLLCuo3fU z11tsXISr6s3979S*r_1f{orF6`l*DAr_no8opMlpOGWbdBl&Uq40|7`$`W4#@bQBJ z8vB}{tIL>7Z4%5l*l%TuzoZiBcUg-DI)5hU!v`Jh=l|NG?gaz> z+8OqU(T>3;`Eu&dwl?ey*h|7_gPR|&)8np@hdy*mzT+i=1KmT?H_L6`qWFe$pZd*& zc7`}({$$SJEod}u>tzJSOR{!?1KDv(q%lKYGz+@r1P_b%H1t!UBU8{<77iCr)dRjHB!DcCZ%mW4{jH!*zA|JWQ_k=r4^&N7Hdnml<78%)^ zhm1Q7WmDjHr$L|T`UPeaRG1O`8t9A%-fuAAVul}_0h|b8yvLj|91iFkinSO6Y|Js% zrajfa;m09o_c~7KVaN8B6+e~{ZbbLuMiO{Md$8S+tLnC~0!wZGhI^8tPrw!_-tsO( zKRJc1|3HZ23}8;}w8Yynij$mxbb^6v@b##j%5kZW(wWxExZ*i>qnmXw__C-_*EyY$>lO0t z1>U4kr_w{G53CAL9K@5(b;-e~}HD9;#P8YhO#P{Kt>iN{=CL;Org!=~`($ z(zp+6KC(`)u4S?1zOZ_yOy z^IK}}w`5p~b#)APaDJreE{+rS_|lB_Ue|`N$}GkOy~Lx_8w`3w&0}6_4)N7v>6~y# zTV*}S*DQvWPHtLthroE<~TL{L0A+19Wp%rpUx<6&bkf8zQ6erxLx)?&j0Sa>v4$v2M>=+;6 zUO=fY%7Pq>5jnW2fcB@T8?~={@kZk`_r&KQ#}h& zpGIL$n_&;nuM24DZ0^Ue=Keg*&Wt~BX~r?V1xCJiDaK3l8k@%$KSQu4`ypB2pQ-;# zz)z`dJ7RNj{AQ+`>Xuj3i2nOS8I!0E&?mo6E{>kTePc(su8#TvxgBVnI|K1MfRD7V z5RIE*zg8Bh7+;wOeDUjt6mwzwmNj@=o^r#o!-jA4rXWhTtAy3Q#N5HzR_rlJ*>_}9 zn+o{u!2Nz*i-X(ZaB_7u`FW6U?g+7R;!PYU=0N6fpYfsI8_#}KrbB-8r_Hpm-lm}a;h>!Yc!WjIYH=qb`i7!kIrzp74ee_|UVUy-E~iuhpQe1*rA)Ar4s0rZ zkq5YJ2Ht(Q@zvgXtk(qG)6yLnJDA?**9|WAL;k?#ruJDPPOHb>R~GF*EsiYeE2H+< zq0~Mj#<41&OQ-q~ba zIyaYZ-okg8w=kEHX%BLzAg8)aywBhj{X;~BOP`s~o*cKXWiYS%^$e~fYYX<~Rtx;4 z7?fo`OFLKhM4SK2y%-yJ{N5eRo(WqX=JL@I{aPlo4cOB+z-Df`v&&G|j(fAS>RG5+ zwdX3KFN5N1>v^qTZ@1gGOu@RM^)wXgsY#&qG_)^|-p64*>1;{4FDinm1^WQ4g@%NL z;uF8eJcU!hvwD4G--2+J>zx7m(EH<8W$Az&o15Ne@eZw|xnIz!b5r?d;Z-Rr z_=2Dr(@;-PgZ1zr{`<-Azbey~0MFVM+NS)J>E>OSbIf-XyZ{R?xy2RvC>EvY4s$HnlVszZvM>D#xwjtvjiM@b%O=~x{jW43T zS$5Qd)&`90(QjIp(MXKW5{-@REg4g1;q5w|t73i*Go}vgo$#Fp8&|XkYWjZJ17DE> zM!yz&e0=X4)4K?Lp}ih^qmi3yx!UtnRyF5nuZwJ`sM3MIEe2no9j0qOl*_#{gb#}#WecZ)w=@Iy94etGPd$d>e;ZZ?@V^gQ2eN!i|{AsP(p-d=QO>L|2*}9&8!u5%IK-d!ZM%#{vy_~?kk-8?+wz~0JcbK6Z64u?E+^>s?FDT@!#d_Fv|K=G3{0p)^{(eqt1^;T< zR}oamZ}=?kR85;T7$*PUv-p=B!ec>pBotDFKvj!?`^fH4NUu-f#$w;mc5V!*=cFG4 z>N$zt@p7n3hcZhPe~?ouf}A6ImGX6{;|643S;&W7D7B2)l$Ff8&A9i9eJ7ml#aRh( zh0Uei%VoPxGI%v2pQF!t5BG7bXko|)deW>Es&?H5_!c|xkj?_h_$A?A2tOuu*R8? zQU$5)CD|$1=sq|RZn_-ejH!4amTm(~vvZcf>*d-UkmeK~_in zSQgGAJou*9R-kXdmo&v_y7DZw=YxCzetGtq>8)rjhkX?FyLG6mIa)6Ok43d!oC%3{ zi#!t>!|-z4jpoDd63&0ezaD$wbvbHwfm>Xw+XH>~yDf%mT*&efW^FNaJA zU;gv(dBEYL;JZ;5>2KAv8{8ivPJFrv@_)L|w1956pnueM17JgEAR6oLnZY3T5Gx0G zZ^qghkilD&dPe~El6Qem6Y!mQ6!_bzHuiGX1cgs0IdT^ACW2=GEY=UtcbWv$O>)Pj zuqjllOLL_uI+OJo&{r2z_i1jP`LZ1}e!jxoB?@P{WS^A&N3=Uj;Z5ymXGRBS&H%3F z0$wD;qw|jUh@)y!7jMd=zRl&U97=HQj$MCl~>r=nmA@4?2c&EgWpdmvCDy_DnE0e4pty zn7FV%KVQXX?nraU-Uj&+&Lni_Zo&9_aOci>9hLO<$+KxI=SlkHLYEX zIe0oa3c7L;DK-c7?X|%vtMqt-275SI!-RWAM>yFGd}*DzEm)1d(i&hTmRegEEB9gT zza!%OFqieI>;Ic{k`;;m{PgOIF1xi{nQf{w`u%JkSL;UKHg*()<}hg&`9^_UYYyr- zTVg$|k4%tc=cevLlu_x?IlPmGER_SFwdlrIWnIAY;jphfNtkU4EKaWme;^W!BL^K- zdd!2$AMWF;V*4-lCfM>aqwcpbW;!qU07q4(bcnCIjyGiNGro#BlWVWQPi9YBa&-@E zQfGD9UyQG%y4E}4cZ1`SOZi8`b(T*_&JDl2 zL|@zG5Yb7}uOYj`le@W5s_eici!?`kzh9-r#BVdmBm8@0-2XDShT>f^$vtCn*r!3e zZjSO{ABIBim@G2vVwDnV z_ur!qv%n7vE8gHhx&N)6Yp6$+B@NW2$U(Yq9B4`As@eUh((i`e&^N=?w% z&0zQI-%9SIy&ZPLlxYI!9y7HR$*LYt7N7D66PEZ0mI1U?V`sr1qHE05&;OUOcaM*% zI`_ucUVCOTi2-*eLx>1EnFKmw>N^Cg7$fZ2Gr0lM5D|w-fRJ#r<@gTd;?$D^lSu-I z5wZidytY^dt@ZTn&o{MwdwSZQy5~ZOh&CjMlnM+<2w*LRaH*v#zwfgrQBU9Z{C

    DsJEJFm((CgB3!h`21o{N*uCyVhM$8$;YxvvDzIQyDxm$KYur3u44GoOCJq`QqZwtRY8_E* zgpW+lbJ?`K;+x=EBv+aAFkn(c{sBiXR8h<)Xvx;ZS*Gjyb}qV5^>u>T<@Nxr3lZ}~ z^AQ4kpo5uV#yK0UG4ks+bX(5y>1%N|`wX;2u(M+>u(v{H`(b58G>9C2fEUgzHlU7e zQJcE0B-E3Oc{4@~>a(&@QZVNwM-B5vww`}$E#8~suOfeHv9%rL#r{_zpA}O+B5(US zLxV|P>u;A)KXifgzoGxNunGSg2TctI#3#pHZqtiPtQk3p z$wz|fG7O7=%^Lq2v`2N(|6>1-P?tw)J7;W2MUG0*t?0fo!|-Ez#T8Psj~+x_ZmSz* zCqO@%CA;;yT1R*T>4n{>>+{5B8~xAGZxj9((dUWCA8St$D!l8!|IN3F4+8$D7G9{D z3;5dN+XD~axqs}r=Fs-Q3_Kqhdp^*!9rPnhw zM&Ge#bi=2v26UL#7-BH1R4u4}Dt||!ad4M}b*SXMyez5DTDdfN9q(h`0Q0_#I+d|H z54^KIa8F~Bcls07MCYNPnh~Kh+~AAhs!*pUaPBI~&m1eCIJ!NsiFhlte+By)ax+xT zG}_pw^0S~noBhLp!P7T#ywp#s540QW9Xu`iT2e`|P^{T3{;cel96*1Q_M$TlIr>?J z#N$!Ucr*CDT`O(i6{dA3>*!Q7PzUKM`_^MTn4|BDYMKFjgblhcF`wU`jk+^r%BxXX z#NwyJA8Y?C%|t)iQ1?U~{xvw)0=ZY6w)`5@-2xlF;Fvg*YfWktc7L&k1%5ZkbBI^w zuB`5#m4X+6UWs&6pqBvw_jZiC67+d+Rdy5k3|otNf^;u~TX%2y_rslT1@wdJ&GgOL z|B%+{3Oyd`A^HC%-0(_t;89@b%&Fb96=zz+abnYcz3wAA0d3ll}X*~{ZQBt z{U2fBaN+!5)S3#r|( z8QXej4`aRvV7+Jw<{WVEdo(w{4LN=pbUc(l#;!f64grqUg9Y}P*K@o}ubX_Il#k*0 zd)os9N4`jcF9~F~BL~8D;1dM!n`^X)D#W$$D|j~GxmB^j{%S`b4ZE#?L#`{3 z8vZenN7eLbxdhvh6s`?!X+b_?p(yz9oId15LEVe4nS58uF6ey<_HPfwH|O}YBE##1;Kapn?y4=`#JhyK^sJCA4K^PyvLeto?zHieoOur z(62`SjQB#x*BOm-@98fpf}bl(vtOjTBB<*_e?gWA8ukF5PrN-Vi|QdBO9XsqO{5uG z%76QN=KBP+liHhteq=*;dNATI9ViM`@Um#f-=PZ{E`@Ik^nD!sM-$f5glI+hW8eeP z&+gG2@8@!}boBSLvKai#ren{XhcMh+B z?JM48baT~lLdnCmdq&KzPFZM@*c$d3A2NO>m410|DJhYd2Q({YywN)*CvfnD#8(%L zU1`7akD7eev3b)5uwNC4%|?v3_dCII)^i%V@HKwmUtpwm2l6oO59fnt-=P&39l}|0 z#1B(0ai;yK!T@?D&zCF4`Ly?-b0vL2QVx+Nd!$?`tcRKDD2e&*zYd~XLyjL$R z-?=HN4<>n)@Qz_kDpfY$1c%_*MmpgB%o`T0=NafXFDXzhah~@n<_r8#z>a6_a-`gP zl4Pm9{T9&n&1Eecec$>md?b0AKH%BVzs3<^wUJ^A8Ssk$*GUwy94Nx75SqxQ2v+T+jinvfV_Xd z<6TF#+~ohgGu4s4;EqYInrRKoa0dHLd5bi9d-N^8mYUUEZnpBz|N2&=rp%-B*@?E> z@e8@^>Sv?>_G5bY(hBIp@opG)Z^{R!$d5uMeN^S%T#PrXu^rE^;5k}Ryi2N>^>-6= z0nwB0U7rtr@5fR6H#AoEHtGvS=VI@fah1+b4<4Eee=^n-t#I$6=N5X72ropJB%kU3 zyl8M&u4ZV8RwmyaRG?Qz*;-cseB!@_qw+rRp8po6aemJ;xm$7JjC(xqAe%G!FIHq+ z6BBBKKG#*CfulkoaOG0fcIW~skZ1fw{}??54pu-1du(;5Za);hBLwvMsooyoC!KpL z{gP;)XexNg%=ode9kHf!E0g|_zxay!`+ArNaP(*9--1a~-`b%_| z{NC*!s_LyJ$+iPyZJVj>3~GCp-ZmG4{%5~q($_laIg&JlXhDtN4V=|hLykcoY!R2F zx3Ok>Am<1Vto+NRxoz*Y*BErbsnH;C4g4+g{t5lkd^2zPpA0cV1gq@-p2U4W+Mv2r#1VMVP9^Z0_LYxt z1~~0I+_glVi~T(0vFI}05d7#A7vhiNZ-$Z2+iFMoH24^1$%-!1@$;4jI!l4{7woEH zqyGiSk0$&dN{9`2M7zQVQ`Cy5k#n5JLiAc63v4naf64KB{$lc7^jxUY;q|BOfg(I7 z#-6p0zm(}}HN-_l;Ohl_fC7Ho4LR)?=DP@eZ|TpNugep~A$>oO;XV0n^Rf(;c(PXb z8-(6j0@^AzVm&@ALjJjDklQ%uY8-2Y|sgc$zcWI@Lgj%vMddxGp z%GyM@{t5a-`jaP$D563;w5SR6}`XqcDa{TkN1(_ zNceXQ_(%TiQO_(@?9EW~Wf6QOc!=oF!mK8vVb2^opWaq20G2ZW%VfX$)ai)PdJ}!g zj2;VLN58*HYigkrCm!IFv9r>Hk;d$#h=eoW z7|sUES_r-!HWQKu<$LGM`^i6z*-JFx#?KGKN8dGDZN9*#|E}qFRfo`BLAvP8x=dzi zr1L99O@%L|`|w7*Gs&;`LqmHS!1F(4&~OHbY*07!aGRmU0RDt+HED({($%bk?B2cx zvU_6lj5UfOejfUs1sU#cy{=-n9)}^x#;m>KLr)C;+2q^izECv}>s!0JJuqE1cBkX} zZENxU1(N-ZaUmW;9#`m|h+hZqp7vytkI#HZ3W%%0?<$$ys`H@pb*w`}?D4PxGB3xR z=9K$!w%8oC4Eci1;HeA1pHMsO8moW#&pF;#(RLZy)@jS-?SUWQSsr_q|FS)>7teFY z`WC!`y$kv3BWB+$2m&;!tSIxL&E2O{r^ zfwsThuA;U5xvO5vAR3$C4JR7`8*P@V#}Yw5#BgSB1KzQ|WDLef(3Lck9v*&YgYd%$ z;(vxZ7D1Mx>rWtC>HS3?XkC4^&yMjvKZCvUxEP>*LVv6GjruDZY!&;^);Z*gqdku7 zNaQn>I18O2>RyRF$g7_a1M>+V{M@gSS|Oqy zv605BU>>QyLexicZ1Q_mJ%H~?u31Jf0A7&pmLoSJ>B)ju*k|-D*%$0$u3_1;Ntr=G zUqTf-^mCraihbFgLtWfu39GNJr{ zs2HwsoV&u{AF}mAZc)2p=oaG6`Nd9gBX{BaHPe!^cGH>z41O*KtxcU%jI*)I*XVI7 zl)G%pw{v_n9%qrVA(y3!w8xSBPx4JS`nwdcDL}hETy3B|M2ATRjGzx@^MPm^3zg-) zy+$>oUIA?c&nzk8u1eL3^0coW1YI;A#lG6BSV`|jzWd|*YG^RIuO393>#~xCirSQ0#n9e{V(8$&x?T$l##~Xv8~`w zM#Mk}@5~shZfBLrcDvf2-Eg~#=6|-QWJZQ)l(=tC2N=}Cv%4;Yel*@3Ag<039rlWon z&gpg*eFJUP`cv^8d&rP4$Pw_oLNi-*I?Rur4hy)l-f7`G(k5MeS#L8{|33JwaT`3p zF~u3WU#HVJKZC|UXK9jFTS2#(V(li{s5&zp?`9wA{+%1LWXu{CORQKITbrXscf|5vg=S^*{(R~700@=I&X;Em%<)yzUTY-C<8tw)KBr0A+5meUcfsn*A!dp!p-U$?6n+zcnaQ8ymujJ zT${F}NCaQfg8#d;0##WcbfjJ5b{;9v%RzVLt;D$sWb@|(Hk|8Pa1H)RUNxg@xJEt( zns^%fcd*~uYpdRqf6(ed-8f_R|7hA3y8 z)Fp82cSMs~4~5i9z+)D7G7I3b4LQL`w+kD9L}l1j%V)pB_hBhi@j7w{e0(X#+kGj= zw*hpW_z~#fQ+5Pazpd*lUOb3BuMV`p0{!!pQbppC95--7j|Y4cx)njm zfvxDCPP_*^lkb0m_goRW>Ak*&>v%oge|qtfzK^_8+M@3f)c3aHq^&7W4(ah^HLwqn zoVNw>2(%{6hSkt#CH3(pz?kCoP57Vawqc$<+mE*3$9jY6XBZ>-$XUP}kPhoUC(Hj; zr49Tie8o$RXKc8% zT%Wt19f9f%N!%lQc+YV@{b90YFW4T)M_b}wllJhq4BiFrL)W(leusNE-JjkO_!aKU z=w5p+@Fwmbqx(zG1%8VA1#~~~T;Mg_7whkL1PKJXImtLXj@&jMh`Z@xTZ@tgz_qzj4xR>cZz9X;%_&oe=_y)lb zrvN^L#IJ`Iv2wz>g*b0Kxa#e|5PZ)m=AXNAU&xK*zVNFH(4~+}T4rxA>4k4PVp4Lz z$6-HU9K6^(4SW6}RsHz~BpdEge_54`bK<~XgVwJOYk32*C)Dr29+ao`mnP^Lw19jy zE*-9z&kxV0_0V(&)z`xlKclObIas6d`P4VErLA0lscI4W$5y``puVMHZpptup>ZAG z5zw#i?|{xZ>0fZ`LXMX`nc@W>%wP#>rg7>#Tv^gKcX>VSQ`rY7B<5-4eLQE zbE<8~1I;Rw-2$HLdLb8jg8gJ$WC^Ju3L0$InD+tb!WH~C2)`ur5M*z%Hv$h2dL-TU zPwR8su4g`qH9>Y^^3_0{)DOxH;gs2y;X^?ebbsCUgspzcQxrqJ20VPy_NIS>?`D<= z8T5@E-{PBq3wUR^)&f6_wo2>M_ZWxWEWklGgyS}{og|cZgmd<|@@IQ7@0bD@9e@o* zKSvO@2ej`E_1ch=*__2|Z1vPO`k;Qe;Xk+iCA^YxV$Y6^&#%XglbnGc#yIEqU;6iR z?6Zk6`c$DY-w$+M{g-9)-eKN3V`Ir18;9{0#v!*?eu{a_c0}+0{~HfrppWM>ln*`q z!vKwI7~^Wgn3#O9LV!(pBIbw2M`NQg()c$1B-i1obzpC4a}18#c_b3%}YAZ17Etb_{(A|5e1E z=6c}Qgm?ixwsg$b<~K1GPV(AQnmdbx4FvNbcpgvMoXB?9>F!?}szd#4{N`ST3; z!*2r|Jn$uw@Ab?JVUM9T5(F&U&{wll$|oG9zBY7gx3#S|`bs^WVRyU}^%lW@ceTD&H|sEmK1)L#z&EO|hxR+njT`k^ zW*V5`WZs@(=$k!WO>hx%ho(E%F+@{98CA-L{bPf2Q_A<;f*2tlXl3mPG zH|hpGH=GEEK}V|XTB|FHGB}HHI_3*|IebQ=En~h=Si6{W@7m-(Fi&<-KAn1nVrQ0! z;71Urh5pdm+=HAh~ZqPz%{2cs#)|2hFP0a^iG#7l)IBl>gF3^-DZOg_uXzt;2uqC~` z1+m#J4IVt_MRDeppJ&Z-+~=?#5v2Tg1gQ{fB<)0tbWgt^%{k$c?kP#l0-T#IAK?Gx zh_9=YKI5QwT9oe!qqSkU*0z5Z z?upiM=rCqUZ7iMaJCOB=_kIBU$vl~P&%fiG|19;RPrQ+@!?9BZjqx7B`<3+G4WC`~ z(Lv*e-Zv|rnq?|U%UTWpq#WnB96c1@0vr>H{?$qJ{S7>qqy6ATUQgr7#kfSwXY3sO zcfJ@`t7_9&AU=$}2KYfZ(}Qu@x1M`zd`^~D@(kv<%i%^{{1)*Fp~^O)m5FjI&h>Vx z8=5@-bW^MD8AFn$)=ABN1%wD!vMJ|QbDVwh|O z-VqLgPBgomPdOmde}PM1g?Yyp{Y}DL-(SaIei$&X-SQ>Oy^E4CFD97(Jqhy^xf6P1 z*oyfxfc-kiuQ46|JtTv=9Dx7&FW~xTgcI0f2zO|nzKUaZjIjkcW&@68Xf^(MW#}_>U1_js--GfO z(Rbvip))JI1!H4o!x{Ck^#%SBZ+dYC7|B#$UDL#y`HeV_W3_=dV+NJMit^pqgUoS@f^eC5wKA1|dw+fS&dD!X-1M~p2&JTeG8p&@# zUXQlh)!&{=@ouS2`Zq|>A$vE7z7A7RAbT+KTQ$B2U*jx--HFLJg3G!POK;Qf6O|7R zOv1R1Hrsss_@o<&e%pXS>kG4G!TyPmO_56pyq>L^$|R0w>Hh^QgZ&A)V1V|rA*>6J z3n`>zR!{wgerk8LF1a?Y0Cwbuwh{dzdI%cnP0mjZcu21MRZ`3g>s|GDE9%mDvJ&1j z89p?EK4xA)IxM31)-@?!qW1<_Q-`9fA)m!E44z1M>v>lZt+&5JPGK6Kj2u$x9r)gk zz03rk8#{b(3{fo{!gCs)L&Y|=HJSrnUfi7zpBu{kLC*?&(Di4;jL~yw{26gD$@0nn z2UmzqE%d$OIz{v?AG{>jR{MvdwWi}@H{Y8engTL_K`;9O8{>rcdO12(`9@NC#r=yaaK_XI=ICvqkVv!~`Uw^!^S z9bBx}vrB{z5$*G>@GV*wfgfYZ;zutc&kR$F;j=bP*J+X76?}pU z-HuxO0qj_i_h~MvE*jI1Ty-jVD#%I3_CoMs1`U1cQ*IN=F*&_`2J}Q}a;cP3!?tuBy3fsA`R!kWoRubfB*XYSCA~cl?>>|_OCgl0 zg?|0yZR9+5na(iH)L61IWp}A&Y$Dv6QCfV8=*I;3g_^Y#3)8kfo~D&bgg>7W{wRjY z=g>Cc(uQ8pEhlr-!Oui;w`SBrf7LVJwmepBS3?*tQ^fXL7tdDHen;Q;*Ccr%Nry=? zK89d219a#^;@hz9-*ovwZ#vZimyPl*{T9(m(Gmj;_!@b(@ z;i+`rP>*wd_PHGIf$XQQj!r&hXH^>5-o)8(s!1uxw%XgI&#W&1XZux~S2 zd5)968T=E02RK&)XQ3cA$ASAD!t+M*iOeYa4Pr!HdR#e!z6Cjv-3KF^RH73Un|uVY zpl9R==$JtM0`eyRUop3X@H?7twQub1QYgzp=%^ z9sNDC=FQN@w8?)FWxtik@%|@S1#}_z_L!`K{hmj^lvOqWek7~(txEc`kS`he*6<<$ z`rl3dv^2{{GSNQhdiJgreFvQBPNKth$mws?AxEoL>z@kWsSw2>A#RUk6q|OslxQv4 zLzI7tl)nm@o8nl49;wlUbwKpif<8{H0dG|(6b>quf#G<;KoEL^LCrA0@gDZe20`A| zzmc`-YDV^{oMG>>zYrPvg1~eW2VV2M>24HjD+<$jGUH_moqGL*72G)T(Vd zjvIBDOYZiJ9a^+BShlUd5_51xZUBC*@s~iaTL9mj6x7kCMO7B>3$FuhL0NUA*EAsX z^o3gwfi57{BM)O~g?&3+gANZg)_|Cna?mTA_O^PN^dE~mu-`x@ugw^c7bWw$ENCI5%iULqG8zfiZ)y{d9%;vc(X8`UpI_Y zEg(MZ{pSKNq71FwgRUA?jM#J@HIB7Fwrt`*h$f42yki#Vjsba`hzH2R8l4cA!ixQW zhS*4|(^ir3Sr6*r$O}ceD(D^qafHxEfnb4oI&<#&@@LQF_;&vB`trGWpTtpKp9y}s ze|1o;z}OFXx^!OyvfY!-KnCn=3Ep^lNCdAX+%UqfY;fVMM9{J~H0G;Ac_+;S_7j6# zr=}&i?H2X}5$goGD(1EA+Q{^v#t-K^{lWlP)QH1MOp7g1AA}20(L; zg<%6wwIe*laX$*&@`Fw$R*dskHU3TUPPGJdR-XsN4TsoE6`Me>^c-t4Z^|t%z#4*& ziQ`ATvyprFrz?^%wqze0fqiu$%^&hn%wPuJ5d6|8*W8aB_j7~1t#}>qf}S~W&ZDd; z<~??teKVt&A=cfBe3IKx7v;@5BmXn-tls}y;Cb4a953aO(7xT$C~iFGuZ;(Rf3<$n z6=LrKTx9ju&}JL$ReEd-aEA7I;ybM~^ERddjtQcN73@X@Y!lGyyjXwwwz$yi*d#i3cFt*yd9d0()|PN13wwGEo@rl@2u_u@0cAl3 zV$)dQI?jb7UOf}MdirVTe$oCLW9`d_cLog5>(e}^W3LK<2OgI%Y>Hox$pUTC^$!`x zoa*NozW{y#?;45sAet~(3YlYGu;K*#XW9ImWyA}KEA49S;SlN)Yo=(T#AMt9zuZJ; z$`A*IIVB!AR}Shr!q8Y;5#~+jk#cLGmqk5>FX}O%9>W*)q(_)FkG_S>@1Z)~p2NgX z{$oAlH!zOd3UFJ*H@D7xiQD$KZE6g9=yLG)tx?uZx&_kb8+vjfH?(Dl5wV-O^4f2L zf1{WL;(^P-$J5%lT$P-!OeZqadOB4ZeaQlRSd8Bw{%G*qfZJ6i#{&3`!6~rgm=tD; zdUz(rKL|Q|M$Z8bzYy#LA+&#W>(#d)ttJZKcQ44t{6UvoWP)EC;RCM-hTrU!i;R-t zN-JoJlW8?)YHq_W06pM`@U#8UqsiAX z)|U46&Oi-dLHX<8r*gvr+p5LItV>}pp*>0l%-K1`##i%(e6D>5d^PwvRVG=JErtD{ zPgOYR--ip4*BNv4CexNDZV$eNK0too6F%iCg3hi}eeI7q-u&@)0ACe--Md8UuE$tB z7|U-_2M+f@%>EHwU!ql%4uvvR>-V6XFH z|7)~e?^MVyj%Yu_|8@9ZgfAW0`9tS;gAK9Yp_FjNHuN=!zV?8BJO!G+LFQQm=W4)( zjlqSzvomlR<;MNH(S~G)-NY=U9uQ8lq8iMH0N#W}b@x_u8b`IrEiQrz(%PQi4HsToE&}7pfBW2R#yd1?RZNc*aqsnM5 z$X1&MIGR!aPyJ)K@-Er{UrzBkBKD6pE5)Xv55*?Y1Kukd2MuX!pthYc9wxgl{JfDn zENP1wmtp>I{Wy-e81mmEpBm~%A^Op2Z26)eG|u=blW)UVKeYF#AMhbTAL>q{eeixx zSNeo?2BpczbV2|FVp8tQaxQnOEzp4)=GoY(^-13&g6C9>NBi%|@yN$^23#lke23WS@1VT7 z_`hTMxF3ap{kPWNDi^3Vk$RQv3%|Z*^Jx#8L007Fux_d;pEsQ|^BUHSL1SJS*EcA3 z2RV;9_E!dZ;ziK09da;;F*k>F{|2&66OTWj24VY4^w2)UJ4~|qdP*eqdctEGcmwSa z&%~koz<K3-{We_BKvJJsJ4%V+CrW!aC4ZZv%~K^b_x5ui4rx zX$_+z6}ADoHxwFYwUxwBd??D zx}f9mV4sP)!@RoWR15XfO!u*@iB^>Tay8aH%4cfO^#f*!Rhc@U$PYJ`9^gV*CHnD( zg;F5snge~WU)_g35e_tu z++N-T`X?jTz|ygP5>3ch;#3Qu@7uK*`yq01;&PM!=Z@1$n0xbRE_`uC=sP|} zJ_0E=X_RoKUf!dQAXnColR4g(F(&f!Bt2<5=zZr&lTTmcOOy2Ufy*PyyAW$jG78p^ zF(2!L?3159ncT;wI8&Vs@K2WDUj*4E??colfIc1-gT_qs|0d*tPtY&QIn$N$vx+S^ zznJze(%smVB|2YXIho_@gU`$Y^k;nE&4UhO2Y;@D_sl|WglL8;bTNrwjBm&3GySK> zKtiuTIgp*uku*PHTry#5S$cv|bE4>$$Bq;@55+AHET0N6F0@Kf$z3%!Ms2YnjO zN^YG-80@V|mKy}mkw|;lKfE-l zLuT(v-LIiO0Xl`fAHe_j1Ni^`(-{5!U}u0o#=5s&v=sq&A%`JGVOetQkOiBwoq~hW zegV4m9@h94*pFzw;1h|no@@M3j4K~=aR9PeOYaisSSj9*1zzIH!Z&4`Zx3je4`V(6 z8*K>VYZt5Kel3*J7C`kke{=TXI={~nv@`%oU8@>r>@w1tn-%KHjz(E`?Sa8Xu5iHKkL zHT3vxzEtFX6|`qS`&{i7&`Ru6W8YpYSKa|-jwO8{QjyU;S6m`; zgTL8e{~%cw>#aHs^?qaNp1-gYjj)wZO6)>gWGkodYB4^lTkp%*H+P`^ZtT+xe8Pbf zIo{u%F!^dWj#NEPywAy<@TUp(WUUf1h>zz*DGsK%&x>b8=z3QBO)>r#2E7jDvLb%` zq* z|5UDQteoalhunPkMBo@JMLxOsFT!@5D4!Qht(cz5vMi@V3)2Y}xky5-g2H#cZZ zBD$H0UrdT-#Bk=tFyhygV#98#<4%QSJ5leu9sI@vSRb3^K2?Lhk?cA%u%`@;M#>L7 zgmr~AmEDVH^8eBAZPn|@R)#t#7dw}O0g_XRAGbs;SH1YJ#n_2h1;o00Egg1mW`_~| z&n>fbr**&=9uarj5MxL8&X{=SmD{za=-CdvHNB&AwL_Zwlr5GK z&V@az7Vjwcpcql~a)T>yCcs!Z9!-{`y(n=U`5(TOguU(0JM~-?)GqD6q9&*%w2%Bf zw~^>rtHWxkrSlWqhIW%H_^eT@^BY}!H-r2{a`M4aV^gU{cD7RBem8U{IqEh|IYs}~ zmL%V8NBI)GPf<$rGQ(A-CMsvZdP#%MgvGnVwlc8;x+*W?c&k_ha;*m0J0aIoe-Zzp z^9CHT4P-AM{W;-H5P6hV!!Fb_0KFOgH?dd|iaban z${#Fs?~>4G`u3p0G0)v$M~q9BD3=N&3V0g$xmde0$rr9OW3NTSd}9dO}5*o9|yPB`N_?LKu-Zf(-}RXyiG61J-mKg(QF zx1wdJpMb{mL@n7mp=+Dvru^SHD_tfTiRO)!aD5J#raes01Y0w;iFj9g|o&c8}Yfn-`;4Br6kN{rox-x2YZTB&YHlh@{&Vg zq32MT;mRZJ;l~Y?ucUd3u@AQ6XVm@Rn+Hrj+fyS|G~dCiJIMwapteMZ!C^#xos^g< z5ic>FO(``LTCjG%hWKvi8EoruMNW9zc6x>mKUWjGM}QL_oiDKKbOO9QY>Y*(SLXOq zupebr==RNkn8_y&x<$n5htwK{He7BLl^s(g!uy+uoeDwjj2&)OiDu8{ zb|Dl&>@vP1y%zBP1+GQ?ZsgY)2H)o~ySXtc{@Hk_t*{_=D8mrrLrSC-vCH5yA#>Q` zxrm#WcNOEl4)=$8-Mc8J`8AA*>d$qW%Gk5HjW;odZ@BGlQ_Sv$Yz#gjAuOILg5HaV z^?qFlZkeR9z$o<6lQAZORdye1z6G4ShId&GzCn!f#2*xXR&?K0NId^iIT_KT^-f{T%h`MjXpybg@taNy^(_DG*Zxc1VL9OT-k zydIQOVzvM7*otr=YXhzS9|`z!NKtq?j2C+a((Jzm7+)MgXt;Ya9$F$Q|?K9mvf znbzH6I8Z^ja0q8{(0|#WYxkKSxyUI7CBCAFxmOegV=IbQHjY-YodmrG zlN+IzVF9YA74?w(PP~oiHvE~pj(23pyg|}38<3Z>;n?rpyA%y)Wy{$Nx=x&%h5ZBf zK}~GDz4eE84q@#jajLT)^)LhIju?}!ioRG!hGs;LP{VchWHR@70(d`+HbbzVPB}+> zKxe;!#`d>JIaj2s^j}fDE6jaSd~0ZsqT=Dt*fmYbdYoYhsAO2`rn$P5(7Ut0vp!3#wlz)r##Nv@4!PT{IF8MnNx&A(O%G+CgkwK7;`wNhCYRUW3kOs&Y#&wy(O{$@hoRt`N#Ht_nzbyEX( zRO}BEe)nU4u>fu|aJmzDH>|*CzO1vbR-c2-e#$w$o3|M3$_E{Ho#=d|llWlx#3IK@ zyUBOF!wA?f1udd^=knyHIP$Epe&Y>#CZ2`X$o50ix=r#g8kh&TfAVzLDw`UDSOa`u zKVsrm6rHLct;$M!=%OxDB)S@Az$U{Ioei(QFCvC?Ry*mTX#P2LG6{_jK;Eb}Vvo+N z$f5K4<~QBGU1it6v*MYfkNgO9J%3fewef_`fD!|9G$kiW>rI<$4q_Y`f<_vyT5roB?3K=*g^dO^;u-{*L% zQ8&)h_U9QyD04)_Zw1v0sM8D{AV0yXXGSxn1+K@X^LQr>vxdLAg0N>t)yfT|SDM^7 zi1$3Mx#vdi&FBK2%+)N=1Hymgi8l3?2HQ{Nv!iX&bYry(IkT{DFArsplvvd$`Gaz0@ zfPE+U%~0c%8cV|z;3{&!SAVv2$awJZfi1a@P3f4i$;NC&uikHpy3d3+OUx;OWKrB0mV zWkG#hZuYw)OH`p|SA(l?*2A|xwEAAGvij^)KXNJE4S1w4rLl=+M(l~{?ofC_>_xr* z9AmUEjCS1F|I6^pi{XEA3h{8zMHwDH@bg$xp4tu^$pPMpa$3O73YLEjb*`&n&+ajY zE|$o)EjoUe2E!)UwT(Ud!)3^wQKK2=2j0u^9(>Q_D_JvARsT=m(N8T7yoBd@W6$y* z7Y7Et_JKheV?Cs)qrj)mZ^Ca9`i2m$<9%O>df*SB?>iH~cN&5J7x9f035MyK9>soq za{8Vj#B9TtCC(8ymUzD%dB3-*S2m#Th%g!Y9#zD-X;cQXWjulNie6k{^$O8ewdb+q zo=kcO4n15dbWvHL=~lG451F0cNBqDk{>Si^XYTch$G;oq_%9cFsKooAX@JWk=3{-S zOIL)={VT%z7GJIsBFpAV=ogP6#)S4O_={X_z6IU9v)+uc&|X6M#f`un!Klp{B01U3K-gs|J~JWb(XX_)Vr^&(Fiv5Q%rl$jJcRcSCCswoi?19YX9sbB7L- z&GsJuy@;7t?lWuP1&esTIgNb;I$abbSs%Q`)Oo_9q}_w!b!v1!Rp`L5pLRBYhfz7? zO#9>T%>b?XM|x-m-V!~ulMfZ-CX!u*J2`u)+Ug}(J_s1 z*@%3d7tV@JruA)wg=o7>+XkM4!xzciVpkYx`mt}Y~-I2LcQWv9- zu>b0OY7_P>vGK)16Z%m2HlOT)j6r?RL;T1mlph%PHqC&2n>P}C#Yn3v0B_|I#wOR; zwoFdEg8ZYP`OrD4%D=rI{2==N$#qFz0t@hj>~np1rgNAwK%Z|yZ#{VX`dgCn%&0Xn zx#9GzE+_HZ+O^HLeT#Cue}&!nlVjMw(PxsU$dB2GKC|fQ@Dbz+oea1?i$2r27M5pT zD*QF-UrumEKS3V@#P4x0zxu`}ij6O~6#fL`qJDGaBBC)+zpdCmt*{a0Q@@U9z{dhP zvG8qF#+iYCc=M6j6_88c=IvP;@OvIFBffJU%Idz+*r&Rj2FIDTWV2f1=Lyz40$-J( zRVLlP)SzWHQ63bU$NNhx;R*4|FydkUY?mkNHhVMnw!DXCITO8XfN(5Z>kk`OI@M*v zN>1G@tK&R!BpTPgR9J#>m1xLm>or}KF&5KuV`0(QSWFS*KZWlNjU@$RNl9#Lpg2O3 zOQoeLqp6?=KX$Fv>D>LubDvU@x_e~n$Xi)|Fh0VTnErgB)N{(AA!h*gIC0+WC5aLS zUz!d63Gw1^vQLM?(lW!S0re2h8P7P?5$H*O0h#v^`R?vP$m4%qb$643e15OKlLMbg z=$IL=5Wyc%UJJ0&$e&>sn42TFMKaF&yqh&a@}&G~&zvs~_DJCO3^V8W`|1p5SZv*> zAue1q0ngWJ9{tSXSKk2-3cACv?mXv4mQP)nlrbd4I!|$?gAbJ&gIeFi;M?`wg-q+4 z%U5RTwkMJ~fZu_}!>T%THnT~r`)(oGUEO224H>@4I=(J}%QpCzq8{CM1>gDD0ODfK z%u?rQ*6!Sgelu$rxeLz>71%2mf@UD!COh6$g8VB@!x$5-{b5hAhwQ~Hx^}d0NIWCP zl4Dt;xj{32SUGQDlArdGu4#U-?8C&!^3DZ0zPZ3}1Fgea_y>{= z{e*1Ji%Bj-EEVW8`1ZzuY0*b5fN>Yw6P~-^QWfUXfqwTU=8n0>z@A5>{*0k^xk|(u^X$!rjZzOoy3eCq>o@F(+^*P-HvZ; z^#@PxFQKz!vMNN_2eHo#?kmg!?_M->!iL1MIRpFFU_C)LBHlvOPKS5V^QpUUBz(33 z4w$5#Ivu{X40wrt+<~>vuypmAdj9n9c~8A`DE4ZEe82?I1OdL1DFk-&1mAa z|D$k&KG$Tk){9s(seuhd3$m6@x}nnu@UU|t;62Ca#1yQp zDWDU6^o^ae-rzplHBo-X??agf^>=sQpnU&U_>G;YOWLq`PsIyEz>OKuYb*zR`D4!q zI-RS(J_UP9P=2XDAs50=H@kr+zT1#c;NzwV&9-+~FbLf``8Lxx%HrfV>!2g1Ty^{m zaviM7XzIdxTL5`T*fg#CU!65yCq4l`iM|P5U|WjtU*zjGUk46L#-eP;>txdh|J*n; z@=x%!sH*vT{L9_YY8yAFD-zQhw<>N&^>I7796co}T`(1na>4-SYuhU*Jrd=e+#0yvv}PvJZx zaAPiDJ?ya!u!PV&;~hgVi1Qv(fKNK^-pHyq$=MAiZF|Eg{11kEFIC-yjKNP@Zd@!& z;y3$iR{dS5hlBr2JkhD%0o5m12CT7K;GPk1GFKa$F2#&Zj+nW_+>7;4?l?@g6!V49 z>=GpEc;a(*@{k-n&>}j{~2Yu*Ny&@W7*HhaLInash9ySPG}XFZ37SQD|IKk=F(MSD@$X zDURjEDTsaEroN2z@wL>FOYo0u--)$x_3T|u4f+~^|HIXN1x1KcoeVxYUTgE|@;31M zZaLu3#=J%CA1Kf>!VCUxcwb0EZ=28FBkUOGh2rO}xJk zcG3CSatGg-DkVi26+O(2Kk+-ApnOP+^vK7`` zD9AAZ_MNOt&{F#^!G;pxN-T6__NEvc6dV^OJijgW>_u4zp2PzL=s+t1-ttKz>_92F_7S{?~nQUVmb703lBS7vTU7yLL!R8cH zXP6BiQr>%lkIAheNAdpf$@SbPqFv(isjRftR!?@GIq!--f)kJQVcmxMDF-n9uf+VN zV^@`Ues-*{koeQ`a5XsJA$5V{U2eU5JArk$NFZE#QDI- z@F$YXI*@l1>qP@kRl)}hh#lA8FWS*haW*LX$e;qhTkr+ct_`sU9Pc{FR)_Y|kXMa- z6+c`g`t<&vx7FkSLZYo+)Z21rh}B??lgvTB5y}6$biZJR*g?c}RO$6b^?D0Qk3i3R zV}3PpoTJ??*hXzQ->~lyTDulkr%L}X!T+Y!*dyQ%L-uU(82__WDUOn?b*qNn^BcBB z%t|@5uJ`2lrqW&jJF6b+0DoSt@n+kR`WefC+j6>FvH6@StZ&vf%yhDm{d+i^izax7<2r;krDDOxsW7XQ(P$PJ4 z-PhWLzWK-Qjf898iIh`Y4#<0h*xyC~BkISxrL@-9>GRfxF+Gd1jQ8==BOfpSX-|$< zU-vkN((};lhwSFmi`J4$RkO|3i!bB9sVGl#dwHSgBY&wRkB2-1XiLY-rJ;VyNs3Px z)5QVj645yWLChKXRfmwrB~c089Qx}`*nD{lSdb?;&RPleCzi4SQAUoQ1o?LCX&@Y~ zF3IuIIHvYjgnwN;7UP4xX$tg{S$~@v_zC(!aa=?n2QkK>_f@q3^oM+e3AY&P9_*hp zU_Zi>dpqDp_5*>|$%)Rw1jSe`ou=a#@99$yDB1vz_Z9vsstp9adv$-$#L~F~Brd;2jC~UD#9DFy zM+raq@o9ngum^pzEPEh3ivD=J`pL$VajbLp7OLymSK3&TY-6+jp5K`0ywmYXf7U=- zagLXH@6v4)Q%_Wcp?mPxLGQT+KIW~E`&nIE;Y^*MLkyxj23EC*w zn*cxR1nyA`Lp5mb6laIyryB?cQyT9BZ%TN3{Ot3v1HGh90M3x@i{9-$^L(I+a;xB7 z4c;*i@@RwCr+ErMPHlMlUSB5qP_zDCUq}I7{Lyk_Cgtt|Y&Vs5s(%~kB>!bymf?_r zzlA!)r>1r1$+qS@5K}`kj>$36L3}~V2DOmn`upVV>H@%}T=#9{$gP^H$IcKhY}3*k z`|8YRK6aa$SnrzAj~4}d%)R2ZMK!kSjau0}_T+u-q(df|!gjv1BvWp0*x_2Q%aJpq zDPf0V-%WHcHL@K#fYe4^##K^~=dCnMyiL0Hul1K!;>?MU6`Q%dx8p%Mt2_PZkHa%$ zQ+Env$cvDXe|n+7{^Y7ob?WiE!^EEwpEXE&C}r!0Cxt&xtcwho}=V12$zP=^mQ=R?y*0?D_oo_aW1! zLtp<=LtnY*OF0F*0^mln$Sr(ViSpbBJ|27_$sUFpq4_TQ4zkFMg)AtZ+!GGse5PS< z)<6o{PsoM=(;uf?zuChE=HOcfS!oi=&%pP`kz=291RQk}o&<@Ofj6dnID!}ZI`-I~ zxGz-|m>;-kkj;UEjAEJ60&R}m?+~vsWvO^w1dddIFWm$F0d}RruR*r4f|mnrW#YO0 z4S9)7@Vu}3^T1<#O>X_Zx&KH1^Aqf)Qq(lM?is+Q0&)uYwfn%A7?E;(-Wbkshsj}B z*Q(oTiw~JP?6G);39!zN^1P|863Mit-Jg=kZYX)&6gQ8kg|A08s22~Ln^KmV|1uG< z=f__Qk3jA>;XmRTvQPAc^IV1w;!DqfS2DisEL{4K9r7V>dT+SE{$?G=*vx^Tvn8Le zo7O!Hy*|yg>rS`ehFtY{q4VJvE3CdH;CEh!4<`M$C6?oTJ!bMPT0R25u?GJ^+?U{< zU?~qG_Y}Bw^dw}#KqRbHJ}>?jMF%@zd^t^old*Mv?il_ zc$J~)u!&);J(k3jNRI)jQgj-P(SRV-DHO)`eUw~7EXgtTPm&-aIFS!lyVID45K;T5b|x- zx&-7+Po71=&|mN*S(Rvy^ti;I3_gLlhm+6?!xmTwy)7RN?KivbL`)Ox0pINJ;P}~) z&z|PJ0pAI**A5PRyqt1R2atO@R0H3&{u;;*t%ps$tol9Z4M*{_jkf_kP;yM#OdG`> z1E;X(F%dqtgJ*Yd;fi>Tp2=_ai0cw^je@tKZ!tFVt+bs~)!JJVy~@_aTR1m*I*nx| zV8pJ3a7Gj>``9%OJK=_cvj8aX_?9@%gTo$>b(v4^eV6;BBg`5C4mr#ZU(_DsJ~}HD zYsJ^1Azu;T^tl|6w1}zM5GDSBc{h3(n|qXJ9YEb=$Ddm)__Cd8&X<%062%p9)J5z6 zakOVX@gHIP=1i4Ea*H0s`p?tSn}5kO%ThcubpMoz(G)4qg}C@()899^QdHZZl2OR1 zmhu6_TdeyQ>=9Z$^v6uClzEKdf!wYT5V z$F@?spLF9_?rD-0x}u_9=6e(Rh?9S3zJBQCY45M;ks1e4U+^R^qAU9&FRH~g-_3ph za-4^MjXI%=3K0IT0WU{m%fWZA4DoO=^sFrL-S3Gf*i}7$#OVM2asD&R=fe9fXy+w- z%fJ)UH+lG`7T>#ZzJjQKBVH9F$T>0e-5+iQHTXtc#sjqt52hI_;@t;ng`$8&`u-DMCg1T*LTSt zgF{?wnD1IYjh8?64OIefknQ2p9O#v;QAGkD=MBF9jd>5%W}IcX(wy@{cGd3TO=Q#f z>0#zui8k2d)*EytH`PNh;*W9Ysx5hhCwzn>mY8|T9#8*?kJ;7Fu`gbBxg`$$t`)Et zhXeKTzk&t9f%^adQuglgQC0We@S3&vBtxWhXA&ZM5GON3jFfUhL@sFxd-hB&AY!=b zFo`-$0wPiy$fc3ygkevDK7JyHNvyU#qD(^7_S2_lN`3qG>D$^pGr0hw4It?8STalk zL`4e;SZZx~zrQ^*nELiS?{of`&)&24y072*t>1m|$oGN~8U0Tv*3UL1`%itNwycTl z;V<{mgFddI^#)x33OLRO7%luzvEN=ewea+(liKz!Xi%{Z`dpwN3gpX1tcUTm@v?-du)oM@*C^^LwG^cDc`P@k!c4kQ1Ogq5i+SU14PQ}|Bpnb6)*M`_*z8en}= z{%e2<1IjdFAF@;*A5WDj7**_h&_8YCT@5rRG)Fd+B{&h$FY&Z^ne>iq^n0%?#vY{f zT;R{F5yk%O!v@6MzN>+kloryw(Ee~ipDzz`sRnhjwdSkoIsdQbdm8GbIj1@cP-i3B zCYaUhyTXG9Ajb{iTuAKtYFpy^zqWbMX1?ZcBbxCU8M?#|g3BQrbNeu7Z%Y1p!oaC&`x6niIe7&;`Bi$Bbp=IJ>0 zsh3>xv^-GNvOLO-xeT^-*350wp8hFbOtlXIQb~_5n4|b zrRQH!LqEkmN&@m*;e9s1B3D|bJ z)*wz__aNmvq%8bAN-TBM~oZqkZHFg)2W&V-c_%UMif2C4+=4H3A_bVo8 zY!vZb9>Mxq9PO={@9z(NwbJ^`yh>B&*s!Vj&dO!c)FF&B_n9r+6}&7T>>$DcUpsYV4jq-@SBE>w+nF& z=pNcfOxCgcO~x^@$s!ud^w+U!^{*B;@Kh7vuZ{opU+K=z2T1moTh85n#3qX)mKEKj zNAw!SP9)g+v1DbhRv@kg_L$I^30$$G-iP!|*sdk;^q)@R#`lnio#Ca353a)&*+3W; zX+`|q1>G;;J+AR)@Q}{`cX%noz0fYS zsqd|8dtTD#L7M@)SW69Pg*H9^#3I!79*VC$V>EZeuu;%h3l5?lkA`s7uKHelhw% zWrZuOjmAfH`Oz1j%-X1bf%sD|&6V?U=Q*6%Jwiz?bjw!cqr7y6)(r|e4drwQu#1FW z*eJJ99rT^*9YMQO(dN9U5OP80Nps=@ZcV@ko%{msKpC&BHce0U5%jKG#2l@M|0b;g zl@~p{gb(l%NfF0=I7<}drTVD;1`TKGu1miI&Clu)Ba>(!dUy9LI-LjZUN3tTv<2v) z@d=crc_rE~J^$(c41kCKa(~F*l+&6a#xU74C(G=8iN^R1w10NVHwtUL*x#_TRMA(V z9PPcwOGxjY&f7_J%^7vEr&5uefZHDQF?MAUcub|4C*?#dl0|7LJ=bcYT<NYKR1>6R+bE0i%>=Dni!l%_ zP4+n4sfg!UFg&gRzt18&lNpt7`9iI}gO^fywR+tV;YdH#kn^nKoc@{r&~OpWM{ z{436z@(9)${4gy9qv*>i#1kgCO2Y+}`7&%w--L4yYkY$G0T`in^1c4HBCHej%fDss zOM3sto_a~sSWRqrM)PirVRAinfH6DDWJRF&aad~R^)dKzF!$XnLD!W>g&n{G)K!dr%8nVy`MCDfOEkA56+B2XQhJZ!op1!b_f}Z-eX~1aC0PUTAkHmk z{=`)9oYNdpoNxO>>GmwtCfcC18F*iR59pa4HwWu*_V<)x7ikn5Nd6x;p&Yf@{)z44Oh;!xNN~Ax7XF^`GFQR-7)JJD)HTHLP!aYp( zk5q9~7wuAq}T={TTh#GT0i)RMzd1UeFjT+wPp>5)G?SEySLh!f+_%E&Yj_dp<_{tsC zsvhs-24CRG3lY1#}ZSPC2 zBhc3`$6YslLWpqS*EJ#3a~`yx4|^2z?R>(&oX$A$vyOW=)$Cs0bJ-TWKhwpY9Jh5d zB~$nJnT@fNKIoB=K#*h&^uJE08=h;;{FhqjAOpcWDlJP2PNDSwG=kpuf|Bka|D_~pkBv~le~+Z?PD$(>d>*rObC)Fbb0twVYL zDSPQWjIX_Z_PrhWugUFAM#VT0bHLUvW&{r8VLRw5sXb#Haa)%(E8u0KxYLN{75$;J zlKN!*4}-f0wge36)VBoH{Uu)ge$c@Gg8q(zjwM+`_5f=E&eqG&7>F;Lc9h$vfiIfo zQUDjMEgVV4C57#(4l|8-{_pwx;PX0fhIQsSs{G2~YMIBOk1 zU4`EU{G$Idel(viVxHpISN#fPB(foo_-GaBy)Iuj?Vt8RYtROI?Ht*k;lB_6IeeuB zr+p$Lp;*WUit2$impgwI4>Q<*oWmR$K);b+1lfWS&uX8r1zly1KW0SimqqR6#vhCd zp>rs=r`)LXGD+EN`(PHW+j|{L$R>!rXIwIO1@wCw;)^#5I^WC?V~_zK0pI)&vxC)8 ztid9T@4$bumSQ}y7VJRmrdFbp?KJKPWOy2Q0&PF^8gd82lWTH^s8veje-ZL!d^b_E zdpX6#3OOuo{xU1Y#@e?tVsIl`68J5Kn0em%(=uq!IBz(iarY43wZWTOHN>PM-UVrI#xi}|C=ETbOH4%SCIJA`h_o+>sY}#azO)1POg-SLQX znFZx%qddhj*#ukT8SqPMudoLf9_kA0xFYU7Eb`SK;wvz|x zY`|Q#jNGpVkB=f|5PU3ZaQc(Xmhu#1zy3eCn{Wa4CGB%cW9xai8Funb;4Kv7Ju$*V zS&m8xu%drga4!V$gBIHBN8r!&H{7|6a{C^G4f`LkN1(T$|M^-pREs^}?{k*+0td%@ zLXhNI)K9)zx|$E3NdjEbn8~(q+ou?Z%v*u;bst@-1N64u7R?`MrdC_3kKzLu5BkNl zgH_{yW}fH1WAHF9YfuwH>tXDNWB5G_T{G>E@1uY8E}u2Dj$zMeZ?G21L;G6253)4C z-D#xD7z?GfV$Oeq|9<>`o$}+U;mIIRqdt`#SM{@H<#8eO{}~r#^yzVt?1e4U?zwVx zY{Mns3|fCGPwPVG^q1FV8`_|K1{u{qT#MH4B-euKcyBA_`l>Zd{q^@Lr5@@Z`f0^j zPe9K&rH~b#zIMHO9qPIt-)JmuJZUU?UW{e(_$iN!Z|U)~N2atUP&dUB5kNzy&(Is| zhjG$bO6#YO^P$d`{GB!(x3prsA3+zg81bhpz{~V*!Mh*0hTct-p29mnY%{p!5#I0| zp6r;U`q&=ga%{nyYQ zok6IZ`mWY>1+6HvYQmt$kEjQZ=5jXCdj)lnmtGzQ|3LH?^b5t1H%|pUCIL4^V;p#u zH`Sw_pMYk8t^dsd%uym%+dT@N!>%cI;v?d)Lm*nL2Q=hNz%IQjcqe%g)pM{S$S-&`*0sLjvz*k`0W$5GPE3<=hSCmU)yu5+R!)Ha`dn5;^|1U>u!2wsTelEWP z{@5hHT%UJ=TM7jdTFM@)>6p{alAn>lwjq=_WjXwnlkxM22lOe8uf&g<)7Wx@laF zLHL?OzM9706qAME%UUN53);^ip8*X~CI$49Cw?!!W99_0L0bstp+ zaX-Bz%aVY((90(z{al>8nun;&*MY|gFaGjDf}{NhrXnx#xK_+1t%viX(7gtF=N(V{ zObi@f)gsc|gXh3rk{I~4^1dWJ^&*}X@VO)zG5;{QycT)^vWc@RxZ?u&XIhj=vm&xY z``iaT0{K$5JCih16~-03H+jFH`-s54TOb&3QWf6 zi18B+EYX;>9evyZ__w2;Ie%at1#@AJ^ZdExrtBWzDrHC+D1dAPbL8HXqOBE&x$~}u zV^e#9_w{%&3h&I-nA^0%l+91@7FNXv$xiKz0-6f*3mBEuzd_c7m_UaoEbekWp4a{Z zrcapXQcbcize1j_3+-*ML0;8R!CR(7b`{k3$abACN33i6DE7SI1ud4~`RGrJa4Ne* zT$f!EhFqZ6wY^(BIlqMHOp;j|Ps}e7`wBo~&Ym~`xe&oN)RIBaSC9(|O$y-Ing|AM zU{AC>Y;W-v|~g&t*GZ9+A*RXd!^WU0lNMSv}5eQV?uNl zOl<2{EJM)G5T7Sv+{~p8>h@QtSB-3UdT>`a?Nh>C7ENkegT6$yq+a^qU^dpZr`|lu zEt}uReb$b8DR52H&kB;YJOvtv=7Zw7P=99MZ7w99UIGrFe$K=E^q_A7`bK%q0k4SY z8;zew?GrO;+>kMmu7hL{BF1IJeSRvQL_aXd2DgHrqxVPqlg~^o5E|QIL5x!1HJuLk z>he%KXuvYieIt-<<@NK~4)FZ7sE2s3jB5e#UVGL|Z8qdNF;?PrLvKPBMQexufQ6PP z(MILA%x*g8tXgJXWhHCzgJz>W`sm;t6}u}Vr}9$kQ5kuptPt|!iw~Q0-r>o?JAzY= z%$>-ryklbYgB_L&cZ!8siXdfN5dUI_OnPd}DP`bHI!N-F^1AUo7a>!_dQ*HPd&bq} zV!8OS1^Ck5@A}wQCU&BKHAeVdHhuuu#~!2j6whAbA==O5+mmM($%yIvQqk{5&|~W$ zbFIg73eGFSSxH=D9$pW*^j+(wHxs{(ak?#Wa|6TgvmFMHH7c|shQebOdAYe*o8C

    zR4CkJJJq!^BVgX2fm6!-fFC+XGZD80woUs$3#;#YoPA-c7BY1w-FYx^c@~@#&M_q1ER!Ax`$XemCpO7id;Ui1qdv%?j}|sd zJJ1J1pzn3nrE`=6-|4!b|BW_%fcB16HpxNAIp~bbcNTbliB^?GwVNR$R?-5&g%R3{ zIhy2(LrrocWLt!bzW?}H=+k)C4W>7ir^)+&AYJWEQWwf%pKOv>t9fg&C&8B89?I`r zr=C4L^sMv+@+1XQDF8$8*|-Mf;}e?I6qYK!LtNIy>2yYP0Vs5Uw7qajH=q7%QGtDH=E1q)jOuEa>Eu7<> zo!0s9?BwUYvvb46l)&)nltA%7N`NW#C4c*s&Ov2q-Lb^8F^hS;Wa!=`8z1JXYfI(? za(gz(oGsWuX$ir1?;~!kCtl>HgKqi;r!rL*0q)R>dmJtC+46Wyze4c-vrC;1WUnqX^XOHy9&$9 zcLG~Oo3;}yly(PTA^l4&U@2E%KOSYkhSem?)9#(wSUcGd6HR9|S)n_hf;770XRSK2 zlXoB4$$gKH?)xj*QqC8AHE(Ngz&&+31F};;kgk^z|1KfAZ7n#lT ztx0yI$-;>=`Jn}nfkIYdM7@4X=_$9!@TT5hpzF?gD=^kE7;B;dEaGpyOj%pPR^nW> z4YUdRHP4nt_IFwB{`*Y*n&ct_&ghNM%UO&zufv_Kmr%S#*GwbK^YqS^Rl({R5^4E{Yc}AN4ykTlf9ARjeE2& zaYexf@GSOQ058EP`8Kf0G1crr}8Mey*V%F&Nk+w zZT7mLZjuf01#K@&Jjs_3Ufk9s>56PG(3t`0h##!ZIcYq|H)z`%^D*b`{-AaebauXG zD|EoExZm1&pJbtN$30~s$W8KNeaGNlNqwd7!7*6>w0AN`d4D$MMQrdsX~SdR?T%mh z-R>ZG9N*zI(-fQ=H#ooBoeP}g>q`5-biI3gQ&rYKyw6FRhEnV4m4a168ki2l_zMLQ zF~Z47dI1qjxtO-7As{k}PNWx)Of6~JI_O)lr$rR!!6C)Dyffpx_3}8*JoD&D(i@0Q zDVIS8Ax#T*97HITK~(yF*GW3!{GR8Jd`|X#?X}lld+oK?UfXsr-eNU~zPd2dm7z)K zM?y^}`$@5}qEXSKt>WIqPMaON7j-N4Y{qKn_={N2RwwE%_-QyXLVTv9^rx?Pe*V(0 z4sUwtSD~{n{VE8W`s>A)esu)jL!d3n^Y)^jzW(vwkp|ck?S_k4;PJ9*}tHM4x!J+>m19?tVzVxdeLP7B_pfCgZz!ZuG*k9w1yfUZt`%A2&GWsd(Bmb*vNBfhG+ zYE}mi``B|AH(BVOok^WsUGIA1h*@Q>bB}*kp{lS^u-$0QR{OnY5N41!lK#Rn$N!Jl zlMmZhUhLQEAvy8%ed!&#Wm7M*r9Qk_uE`HFJ3p=FaG|a|L9GB^gIx^f5#4#+`spUT zJ9eZ4va|dpaF`D~q=$NB{ql^9yf{ml0Uq93BAwEM#`uV_7WV^KLZL;W@A@ta>^7jE z^-McSVJE_Rr{UtQ_|J+GYJ%9ePO|I2=!ZY^Wb9e#j4=Jd*&Rn=f5?6`33te8f83b2 z6>o4b&{JP-{%*_T3D^UMygm=~kbq|&>Y9hOJUbrmkH^^%M{AT7GLm_2M&5e#%|Pwq z?ScvPbqKZlweXI>$k~MQD;pEaeM@F&amgr4a5MYXTB?5z!V%d~_?lpQG!b*jbI`ndkI3q1T@@e$+y*{(73Ka5 zx=s`B4%5C)k9{5KiddfR2OjJjS^v8MzxMq@pk4dE6*y?iHeE9pAq0hPNx6n(hTUBoHiYFtMd-%Y*W@;1nnt!ugz4=lfKohUwt?2 z!J;j%zlie+(p3%r?dCu|{@)21!WYW4wL@3Ipidc(t4AE=*{Q|9^sjh-JpOqtzD@B% zXRDQguCNNa%er_y9yc%Fi8xB5_)XW>qv;iQDN)Ibt(9i8s)Pox4b(AQwxmRh=G1aXzm3|3PS%P4 z#if~nfi2gYJ4jXJOwa<@p83# zx)VC!yO-wcJm=v6eJ$NPw6DpL5g@*n7v7%<(J z@W7n6$PVsK#EXzAtbm`naaa5#a8j&e8g5qLeZ5|cFVYAXtn5YX;a&vI;XmvFhH8V0 z7L4u+eDD6(_0MkZ)ckzpMj8|y=&#|?*Y#(gaM)OPOW-p0>tyd~1l<39c$c=vy8~ge z`C(-{0`DV^Xkie0a^f@m=7!yO;oEVk;dRPqg?=5OM5;D7ZI4sT>}8copuWUK!NJFfy~fWPo?eeruJLw1vT*iD9D z>!?G2qM~0Z>i=Wl!pdC=y{Q_-J~l5;5%eDE)SLEKltaN+lpXl4#CLANd}TiRJZYqU zw;48@^Hj3}%@!QpuROk1%&swm4-YxgYo>|mH3kQCshV7@DD>YFBpEsOKd;0e$TkxurrCKYN+QbX03UtX;aGY4-w=<}_kSBl=P8tC#MvO#Gl9y6{gCt6 zjkzk`hp~s7DK4A#BSc=RO=_$Qlr3Y!s5zb@>- z`eC^)+>U-uyDlst|Mcs^9)!PlUD%Is-gV)2guj1XIE3(w>%ydmoq1h2iu4~`7nT4I z-5n)(J>_3$@7&!Dn>x0!NV`v~^&#X}CWdy!Y>-vIa<<@V#g8crnhOu?!kFl)CFFTR zG-*0K-oDG8g!J=Kzp_)LHM#|QP`5W_#Y~tgJ2IJGk6t3AY7Gu`axk^5$=qRj=#y_psW* zAD;PP2x|jdqpMAfa5Am^wxS0DPofWfYN4$I`5NJC-XOMspSJ~~I6Gj4H`Jc_{@~-& z0T-?Pw{}BsaWCGlg?-5^vy4|}?fj1NqwMriTc_@Ze=!nV`buwzyR(V z^v~TjE4P=2J%P^qnnT)dcECsV;kSR=`;btcxjge?gJ`gRhY$XM;rPq1!ruzGb05Q^cEahZ`~qe9O(M zoN|i(W393H)t!n|^@z7scN|L68Xuc)p4CW-^Tc-;G|f(<^! z8$~AE3j0(G$}#ucO8y}Bx`2&G{k{Q4x?~z=0qm2CpPZ<8*#bCoTG_zCLK0OYui-%uRRHH}4+-HrEUb%c@D z4*VvGM*|GHv2bW7?yAMUI-FZEyTg`)y10^6wki1Dg?0~YTxFZ|*VzB_pRcm%fD4DJ zU(f(~+=lcWL5Iz}3jPfKx;tRPo@F|8qBCHpxmIjdVB_+$uV3^33jQvCt3&^s1<+do z?;+T!)7=NJ$O}5>?jpccM1IVN;_;%Y7bxAT!j}hlIsG?%z)$o0aL$S|)=A5=@FotE z-$Y;B`0izVG5Pl3zHZpv=-^In+=us1sXXvVwtWudxh7n>;48S_#!di7u#Y$QzY~b! zn~N{++>P}LUy=>rH-Kc5X(5a~`j7w}oEhogN4kXX41DWXud=aER@oZ1w7wMT+^zgZ zB)NOHG8O%mx^`>!2``D0I_^Ln4)nR>%lxS`L%LL_q-)N%p7|l>C~LGA{;fO2pG;Vm z)j{+wcEdM9m>YG5rl0&?cheUXCrCfdAl&ejzaT66u-UR<9ox=7X!q%8=O-jpg-J|Pah?or90998=Ac(3Za}{w%Eq{oY>3^qf>*BSl zbAiq^yX^w}K@URaNkd~Hw3Z{-{M9fIQ?Pl5gv<(-cA6X?C_mHb?eiH2&u z(~rI4-askVbsqLtPUsGn1|^FK*=GlrP^_Xp=tJbhF8#&D67(7NM&${$XrTpd=@Iw1 z>eT+T?#B5=DyvBpdz#a_U%QLa6A_1ZJ!%r|Jt&q6z{#h`~`VtqHCXj3*m zPIfVVr4Mp;s_ORYvHxL@&Z@+I(`&(*j!%8S_A2hovyYg3qUt8i&Uga$pUB5}H}X2> z)GoZx7T9qW?Sc>K?@jG!VQ+f<4?%8#y#l*;ne8UL!Q6WdKE4Z5J7mPaX|?C62>Tyh z-oc&;F7kb_%*HLoy?cBohzA4gz%pC7r%joSHgbcx%3#>nZN2Aa7uh+wKH$s0c1J7L zL1yp`9*|2Az7!9uLkHwygwGzom(c02oJ@>zAu)^^AJ9P@OGrD=a`(~_6UpH1pe4!or3XyNuTJ-b4A(@Y`%8v?pmph`X z9Dk3N=!w7P$DLI2F982Ts=ttY7g*uX(qM-!4t^T{kn{iA^6;Ph(0|Wp7``edm6IQO z20v;HZ=-`wUEK>=S@aRSkpZ1A-G%K~bh_*jj4``*Kt8bYTmPL{AK`oRl$?yWK}jF6 z?qvO<+vm=nMgIGQF84^n>BjlfT}{fB^P5aOeDg-JuO(YW@(m;*e=hE0>TssR9G(&0 zt*atF?(gIy&I0t~q<=T~7Z@$d00!!t@QA6B{D$&k%#Ut1`KrKr&ttAIyd}^Di2|Gwk**!5a5A`o$nmlFu9`!hGD9`8ZC^Sl8wu zz7@8Kuul?jN1%um^G!MEE6GcKRViwIjC4+Z<@`Ok3lN{b?jPq@!oI`nERD@yx?5nz z*$M}J7v0JEzuG~0y0iP6eK)(_S(a2j{`Osm_TR3(U8kac0q2;6iz%W}AYSn!8lMfR zpapB&Q1R&s!Zj})Y|c0!S-gNRvIf3Of%o$t8Ck6ap6(B2D(hSHp-kbR z`k~y3@^rU#1M(#!pH}w=AIcxC_;&2g7<=Mr_>$}^uf^D>4mHfTxG*+-yvZ`xJd5tA z3Z3qeWcX>{jykn=mV794{ZB$(eG+@L7%hzZI=}E~i?Wm6ALvT$@JkBWgIS{Z(%C~Y zji>7ME{T8Z!JmkZUWJb}x^pf72UNc1y7J^7HH7l{C||Yyas}N_F~LTSaI^t^83B&S zXQNQ+9(hrGL+>a0JDN7Y;SAr2K523}{KWDf!Pf)cGa?3mIDmt-qU4= zd%x>r|H32WTNd&&+D6|kGvhE3EHtMGZt=0p6(-!1X-AzJe#Mt-iRWG|I$cKNlt11t z&?D`GQ=jrHkD@Lfb&!t*!nx*m5IB8^T2@F5S6`I@0h7V^t$j%=yLJak07$s@TTya!&I+cO@%$040NU8b0J&2^^<7XhB&OL>KgCJr|_vAOzT)c z^?)w@QmaC5gF}u*_(`wifL|oiBSDfq5JvY0gcwI!d&u`|+iFOZT zz7a3GQWzUY-zZFN>Qo_cwWWpgs-G`#+QwU8{bm z`*ei?a40%o$vK?=CXcs;yXYgI`jq8i_)}3Q3Xf5LT_4K-#r{~bA8oek6`cqC^Ah+q z`6@quX%qHbPkP(9R^r3e#~iH^_6CJ*td(QXpVd4?IBLcDD%qe*)#PuI>SXX4*yldA zIxW;1cpk9q2MiKm?1fJ#@|Wgb1o;NATm&q%K9xG)vlg^i1sF7#{s#IDw*h}if(J6a z@qz?+T9pS6^Ono715ZPnZ)D(^r8NM6mQF;y`A%&L%i~k9;Wm#aEOy zIFoJeI$a^y;JF?Cjp#g>zuYpLk4Tkkkv{)R$pk(wP~JJ0BufU~%Xxm;SjAN}qb3V^ zh2!p#&#pi>2K%`2y~iJ-(kW-BUx}#tL(q-DPuuJ^FUnj(nLl_|oT4^_!|st?ebR#Y zz`^5yCnwLBXMpT81?{{EJV^0)-=pvsqE>n7eLW+5|Nh6CTA@7rV$lybLr<$FPg(+8 zrD*F9H+l)<<(GD7`jBkkLxQjIEc|rg9ZHp$j`tLVj$LKz4QHT}deN|B!uQa!1d9qE1QU8c3FJRyXy(O+DhGI!5#cmP_W{fIf7shEMHdx5w68b8u3}TIgGnL;TdJBMo;yB+HC_4=j8hKRKK-^_A(bntmQn6T=wjES-7Kx#`s#*nZmbg=hD@FM zu=nBF4(lV-)@iimh_&TI83B5gRapC;z<3CE+l#4xbBAI7gFdAe-P}R_at2v>=;_h- zsehg5UqLXlLx=l7-RN6UVP?nHZzj~<02yf`=Js^79of9G`i6+E>YOvV!!*pBN%p(} zaI<|IM?N1r`#!xN!0z2Jas%MHL0s>B;+eDWryw7#!K`2j{0%_a7>_)<09 zObkA5(G``I(|_9Uhp^xH$Z@*Dlb7qII1}Qci0ee$rg)r4dI8|%Pl$UG^yx?ZqnJNL zS7%`3*#&;$B-#RP^N|Ml$eZ3n`vUkAR<@!H)w?E7d~AMjLRJ)ac{SPt?;t!;KO6(~ zRiV0p_YL43UgZBV!6x&S@Rb-ag(hSXolMBnV?hA?m)WHGQ1jXGUyLmXE)@LEtO|b zGV{TVjt&~eFotQ%*h!#*+xb3Oasi5cA4LtZoXSWy{rJ9Jan7YM%d>EASd zJywx2-iNyMO44`lfc@eH`0yG6uQ9+^5y=oopBi6_HhKM6i*|-@cC7=B$tO9@FSm!) ztXs@nQZDt(mYc(%cvBuD|D)6vMBtGQBbtIDHlC??;H!@bGnN<)f&V z@GICx){Zo%*waQ1=(RHo$+v z)u!E+t

    }D%)~?Y+cP0fZt0rFd)Ew2G{Ae`Z(0**7iZbHRC&5><>H5c1Ne#4w_$W z!T(hJ7ezjc@Nlr$xjhV@T&lwiA2nv>V2NY9+AD2;8~#l=` z<2zF?<`%PN_(*%xlAikp)75P>N{=;wFk&g+^zVIr-zUpLi*qXczXo+ zBUy@kL%AgxWxx3XWA%8o!$LqnjRl=A;-r64G%ky2)3Mw1f*C#)V@Qiqv{iRQy37Rycjn_b5 z%xf^{@(g*8;4R=!alT+Y$xmZN2F;&aVxdXN=;AGOzYc4ZJORA+d)+3*c z27L-&%3mN~ZvtQtuuf;I#!1(pH}&GJzHxdX+!=6o#3C(K*lUz?g+hlvg?CX>LDbx?YB6ax{EA`|xiT;=`cVk~HK}MBCe>drKJos@L5jK z9`&^obZx?3g@;`AOZ?ve8XOKAYq;X6J=R5Rb@EbE(f2>QCN@IU1#Z0ypQc^7CN9MEXjT0(yQH)wCT z#dwp=8QUv^rsaktz9bFjBxam2uY>MuD6FqZ!1~8^ntR|+vkEVjC|6Jq;qewR_VyA3 zzSA7~(I4Vn$rWGFS&7?g#@<^%y>wp0FU#CEMf@<8#v;1H*PV=glL@#Q+cGwB6l<~P z!;%Hywcmz6Dp^2l3cY(6>EWxXj1grBztICF3!=zRu&x5#Y{Ix+LOS{G8@unz8%BFF zp~DlOn}l?F&xC{RDUUGuoIf|=A0-~#ErgM1A4dEnDP$zTjNrT#RAgxe4-o$T*N2lp^UbFL%u%) zcW)s5U3^<%13CvZnGSySHp1_KHqE&Eo{hWpbKrC9_o^hA?QPnA%JT&IN@`PR-qs-R zpy=zipuZ18rZ^o=s9^<`9-1e($q2viyd?$va~l5RT|W!nH4qAdcni&uaG^#ee~o_S z4Ctu@eW3c6qQ3m=>M#6X>Ys}-nOwqWG}(&3%P_%-zaZYiO9+FHIUVbG5^6%&-( z;_!6?zA2FR^`&W}{Br1_50bycO0U$_qTNfKi8LSfb7`nI9s4}Z_fPQUBDdqs)NJTo zS3}RJ#jDxX=db0slE=96jup|0CXyG<^~rjKe;p5tU-Ze1b@0)GJzI_)dQ{9AT35{{ zT9n_pWBOat0aKWGj7P+s*b(0JswSg-y9TF-r8WjX?t6v6`70v$9rO-6Q7`G_ey!gV z$nND`+pp!|T_EP_#QDkwv`>6i?eCMPBi}fU>;!(4GOXYD-VPcjIw2a_j_`ZzO>RRM zFEn;ag6na<{H0YnGSLN{r4kRgf^~?-l=NZqfg8fhWUPr2>`#-zq0|S-Z|`4Uo{za) zeJA#HQLGW!g)b|YfNwM4GNBCB#elcTD)=qR2`DGU%Oyddw(fta;~dq2wn@iD`*5-Y zPelFx?v^6zGwD?+4(9@l#~SHhvGM?|N7FHf{;zR9+M>)yJdJU(nj%D#|54({*y7H6 zQJq*Pq~i{q9^+~P9y^!E@W>ALksZF05#&ueb-kB-W?dV=IRnOv&IfxIn&4|0XCUFG zKrC(#^zHF;k#M6#vaRo#7##>fHrfhbOC(37;f$L_(yD&>5S_(Qn3eCbPPAGzePE@= z3x2O64rNh>fifhla2S1J>C-FkLC-zzfUIo>As|M@P<-~ z^Bw7v31^ms+zDpmG=ttad$V_X@paIKHJRkmO{kaT zv=-pogZE!ZpG-W8WVlxW!+8EY%rW9|VwBa*i{sGuk3RV|>rE$^xV)(yys6!8*i7$D z{1PxS><^q&cbrFcckwRU*VG5*%I=R=oc{@Y%4xbR$Pru4Y5INhBCm1~_D;tUCRxLe z`yjeQvpPaO;sU3dyKouSDBpn+8@so}=KHY3HWPY(_ECv#?7p#y2HVvi(7q)%{reLJ z!@3&g$nT-G-huZz^A3j!lN=4H+Mf_DISH~)n0Y^CKS8`!D>*#7w_F(S0_ctgf z)u#ms>*yY=2gd=U9li>7BCj9+$N8uqeCSicxfAwt_)mN^b3@Bp#7kx3QQnrfUOt*5 zzYm@|GYlV>AxZfCqp@|CcqxCZWq$Y5glms?0i6+vHQrqCw>029O7Td~NBmn8q9tTo z$VW1(NZw~F%sqL%3{Ksc>)CjHd@%Or8t+D)$j(?kk?+Ysz8&$pEYt?-C)xJRc-$1k z?Zi5BJ%9AGH%iDi!*38DL1Teh2Ij1}kG{k@lLDY@T zva;JZ}A2KWCaWN*NUV_XjK?WsRk7QUa44F0U zI+=C6oDt`SykbMuo4 zf4fd*ozvsO7`>&*th%OB{Ete$?l92->SSf`OI=KIYy-}IV|zFW;|IAmzL#vPI(y|? zxt7*Nl55#2f6q+(-;1>wRNDh=YBDbP>FQfRHzdna9@1kukcZMqrWGI)lH3|X`uM)g z23p}E8)M#Sqm|jUWPtz`iWlTN*U~W_WDiIBtlzD@sr>xi{u$)6`I_Nt_?O0A zVE9p_eMgdXe;^UQ;;y1@BkmBlhj~}&Rj&NR1p(Siu?PT);0Dq*afASCOCNi=VQ(i>F?wlb<1; z_N1~F{46@Q7V>CY&y-&1B%zNNY;TrGrH(I9ZxiH~)wJ#tpX6-~Rs+W9Rp^LXtPNJu zH=Km*bNtI3*U~twg2<0%!FT^^>wIe=cogCF*@_rmYf+BynhCtpIre)vzuAa#geUbv zpS=1n(Xz`P_*H-}91i{z`f(n`sVi-S_fv+xzzN;S_887r0_QIVs7)jM&kl!pS2q6B zyOZyt48f2Fdo*f?&UTBTTj4P$X`K-@Sp15gCCAns;#({E5&sbA5qN}7ZZ*z21HY4i z>*$4;G!1&i$fBWSj>+$xFjmLh$!8b1I zfXpm5X>Zz5saA&emDDc>LYuhNJvI{?j>lvm$q4BejY1l^MuKdn+sS3OwMy z1$!AAc(g`O(AD}4&n4{0X)vZ4n|f}?8z;^3PzA#sczkv=;mByOvUygn~R<;6hR1dpstrQVQ zxTQTf!M5X5=;DZHK`%kL%K+|({xn*o`lW^*Ch0CvnC>(Qpe3q9qg$l&NTdIhc1hhN zMDf1`XV>S%c>>n;BElc>nCRFGbxQ#U8?sh{$GIBuKMH!L@MqBVmQY;WilHT2>Xzg$5lb^@D;L-jd%3P`;IUIIB;FoAOalGC6@pc;$V7sQ# zZKd~rYFmo8ogy+9wcm&_WXsb=qgvl$?Os-YBJ8Jl%%l1;=;w|q$`s&;WYis3#>(D7 z+E$u7u(c`vXO648CdQ-I<4iscyk7wCkMSt@*4KDctHz_wxoG^LtNAw`#s3?RT1|WH z>v@zr#-oTo`S7N~%`-zYmPT$WzYXo_z@v^Q{Oy-M`$`)Rp4rD8!#kKU9!0VQ1CQ$d zW~}1uWCwt%2{|AEU4Nzzqjoe6m%VL3BuK^4U?0|0u>k4uh}fpgi-T@im#BVMO}|ZB4H7 z9upp^jw*5nqzkg{xLz}WX7(7W=ffMh{x012i}$q-{hW#Vo+Ccqdr;2# zAX@g$gVa~Nos{RF(TX#@L>2b(@SX5?T_n)))a&}>;41WY6Z*R%+cO(*InkqIrUO4Sq-a{hf=W zWrP>D|De1n4&U53d{v0&{~3epwm2*nl#}4gdS*OKvV1DRHqp;R*VM#epV$fg40E&1 zo811*X0=f}TY)dj3W5Oh9pr6!7!hd6mwQQ4{*ZMX-1|{+Sg{o-` zVtu6kiRfQJ)Bc5{c}(;<-8&Jiuof?js_)0h+Lgh?G2x$+f@ zq7_7g;s*!iUnBeuczlL7*59QGoI7fJ!W0dE9%X{T&#|J|`I!MQv4~K$7-gT0_fddu z!Jil|&XqmK6Cr!@%V)vI{3ozuGsos7+RBQz?K^N#9@&(GvpvW?;2WL?eT#0!`3|+2 zk1;!36XQSQZJM!%8gElTn@i$tW}r=-+bH|L-8f+r3RSwnmMWd7gY7Nx8L~N)EbY!xB@gfr%w)&>=lHm0E#fAV9!c*@J%D>o*GpHKbMk7NA9fO(z< z{y{v&ACH4gX$^y}1$clFP!TXPY_|;gJ&fPCk+l?l>=d2dcLd6C2i-`=}H%DRZcq` z$8}U6{ADKKt4rc1^3vc%;{W=?fq*gIN5Z?&8ufKzee0h!-gT6W$?>UVN7zGwoYu zqq9MhF+^?e?)ClYcui;$mv0a{a^^~Pw0t-y^RaYIW)_pkC0~_J--EsqC|q{XlgLH|v_2T%M7u=f9Rtc>~>kE^A)y31o_ z{hAE{m-S9H^x;sMph9tm# z{l4|lAdh<>lF*Dgb_}vQ`cBCE!4J+=o~sb;UgZej^Q&&fi2j&Ci|YU<`F?6J@;Zl8 z`ofGkU_9IrsE5gr}F?F~Ax|#QW47hOj)jy%p$ejM3 z1-+)#$)aBH52b!nZ}27Tz&xb=vKjaX+`<{`4RpXirIC#w@iXSktcGk`6o7o&3LKJ- z=ERR_pSj7q^!!*E!9O|g|CzA|V^04wq6cLe`RKpzQ{eY}j>~wSEB{?V6ucO3|6yK> zq+3F}671B6d--WM;GTBsMouOkPWPs^Q(5mpnPkt9y#(hDyyZc{56<4M$4x)YQ=Q)c z-r2Js@OA~gMcb&X_XM+-kJ(5lRo$PH-2(0?*l{kLQm|y4_bos2KYWzxfgC~gtd8@JTFkc> z&_26D`nsG2$zS07--&yN6!&+GC(b_TOflsg?9fDym-6Z^#_rV;PgsreEtGe_TuEW# z9ma=v7x50_Nkltj&%FnF^9+26_pGWMtDrqFol6A}J_8wzc#-dDiFPkZeB#^rHv-)M z4&~CL>A0&#x@`ExEW}!Xej38zR9X{^1H5HK-7M@Ro`Lio-G1eYY7-9dAC|a9=2`_G zc;_bky`=G>(FzusRcV53v9@qlk<>k_C{*m&&I)HKmhM@KN;Z!8e+K`<#f96|5^4J{ z5Uxi!*junY2%E>5XhVlMC*l~+b==seJdCgz;ZCxTES9!+BYYZRdc#zOkKkV+9IK-U zbrfzdhF;Sd=CQxl2_kG1%*D(%bc)rag!Ka1%WAeLU3$TQwAa)+;T6cve%OhAt>#TyP^1ugM?!Ib;Xz;~}JCbJOJiHbBj>o+6474a* zm$c9exf%44^;v`~{|I~_19$z%hPB;pf;?Bhi1#$iCw^?Sb3z2Z8dePmkimXlx(;6& z(-w^FLD=h>u`U&3z7%6Up|>_8M_QBxq9}xe&o~GkuCrez+s;<}&%Z;>6F(oSp#R+R ze!11^oq3ze$|>xtvQ|=l9{C|}l~>J7pUJsl$BFf`w(3*(S;d;Q=~KvSA|v^f!dm@K z)Pr*DXuo{*EaoNB#9N&UKD&0K>$b<^>(!d6m1z>+(WbJF;f+HTZ!lj8*$k+2PpYp-2zRGW2aiq}z+Erg!91fHY6?|DrvdLLlHDZs zk!3`0tlOvj8TFDqFwFrb@(j93_}1JTpmRbBJM;Kr3*M3yI(30$&$WtFd@1jVjWHb` zt*PVqT#fd?n=8igSqglHfX`gmJ1Xewntic8&$vVV!OLiu=0zLgxw05e8^^{fY+{l? zc|8NZI!a@;*2?smRWr9EjqK>#!*?sbC48i>JEy#133w#0zu&J)HIn4$&KU}s2+xX@ z+wfjx4EIZ){Ir6`gYd4wu&7_AdVQbt%L{<_M?g;^=;`cPuDnHxR%mI*`{lL3!??|3 zzU0VcUj7@0>T}S&e7(cEZP0;hXRulJpLFjQq(s$NJ7>V*u+DPUc7 z=@FL_Oi2AjSlFiTO!(XkpN&S$#kFCfhR3_b4EHoh7Wf_7FG2fM=bq6CvIp(w1f{9G z!?aC^`Yma8*r=#F=-)b>U~ISSmoKx_LIHL&r2!nTTS6Wz#XrT;@Cp9_*yVp zrmo{o!4_CvPf>;?+Mdr8I^&T<9&>L22qXwrpzC4vd*U(k~~02N{DpLD$0~ z4Gunve!G%Yod6xPkP(i>>m)v!LHv&Lz&AO$P2!6tRp#8FE}tRc=LT~O2{tw3e6of7c!ijz|(w+u&V4Z zC$u9^GV+A}!IiH^UtQFn&_tQ?zKgik@ij{#JtjKZiu$QN(Sf=Vo{sT~l>9|`*CfqKh!Vl``0NJyvIbkm*5kP)sx(&x=E3}Rg>^Wbg=jS?Q>{98eD;Q zE{uY)^S(4c+B0*dt>%Mqyh}A8#ue`N_@z^MCc&kCBEwtfVempzlmc)rXb}%TR^~ z4HB)H51Dr}?0LyXh7aFfB-yc!VqI!j2K{9}e6-@OOG+=&0QcXpKZy3=tmmFkGtn`{ znLh|MKZJBKT9x^Zja6#3$c%ZTt#-lOalF? zy6Qpr(n?Y#3;gaeUi8;ce=Wf!f=Ps3hU=QvK6q@?mEp0~xto29vMDdsgZ)FJ3Ldn4 z-3Zmip)Mv4JZ1#!(NOLS)V^bp(EMq<57{E^4IRg`9>w}~_>I8K&$#lwEd$zIQM)F} zul*=)!(eBlgr^rV_cM!xfjQ{&@nYBw?w_MP|2XX#pVZDd)BERO?>xIH34Mun=i^M( z{g?qb!rImZc%PHR7Zn;4FUkmLI}`9y+4k;y;MlB{o2u@1FxVcG{JA<_Hy=j5_E>rd zYb({O;r=A#Rn)C35+X_By@DA&a2ejRCw=fVk&{h#zJ2?^mUY!JezJBqv$Mx?&@SPL z$9v1rqgM0bhetH~+2E$f&|k=&Z1XMXH=QF0PTgoa=K2kWBn}r71?^4g(bR9IK-cEK zpUKTC)`mC@!Mg-_^;>~9*3Oy3*!$AhVO+<`FkVHD7Vk&g+-|-(1!oJB)Ji1-z7V2nR?S|=B&xpu6q=g^&`BAs z3B?oTdVL#ddC{)|x`bVo8C)o(!kRL|An99Pocx$@uF z#b}82Oq6+qe~B>F%l1!{S8d2Cp9tKhfu@MxEU`BIAQd<^i5b-|8sGWI3Y(bQ*|z#C z1=Y$sAKZ?8G3LGWqWuq{7nPSne>k!oc8fS~5?b}S#k5}GPK&wjM_*L9H(>7>zPTfW z`SsFY+mApFlX=h^!Dz1Hwf#TEY30VE?=$!>ni6@bN^;)Z(cpkT%@nR!zXg3(TN3!_B1P(I+nrh4rxd0|FJlb#_Me<2c(S0I zrS=J?j+BEXr1xt;pLo=92jG!mlc@3Nu}PJ>inNPSjh8s^?!zmAur`LdO=%dzwUV?g zDw(%wW2v^*CL3=a?s$akG-nU%R;FF#AoKAnvql?_=>qQ+LYISm6w!{~F{vi^{(QxH zq!n+=G<4q%+Za8?<4*8+zm7|3fj@@R0u}I!^a^}hQ{R3!nm=_2_sPiS=QMb5<^DGV z%-PW6M?aR^V2y>d2p;wPdN9qY!`IiH=3D~)(EvWu{V8mvKIO`HJQJf4@q>wS=_4_| zlLp%!Aq+bQ>=`CujaiKSd+B4uZ>p4Q#BW!mj~-EBi;Q$L;+#k$J3=F5UOwb2nj^9- zor-k`cZPU;Z-Y%OG3jG-ChgnmG#BVR?83e|lCch>X3hxNzqfK7tFhW!5NH#hDk+mAH6 zUb~;2Ea?TEh93uB25-i@&gKg_D9^A)W8YGp zjl6;#^o2UIRlu<9SaTBOqG-@p6xrfIdP7wQ`)E}s?nrR3-DYn2_#ohK|KzEEtzmfk z1nU;=f1$nXW9AFl>ak`I+A29BO(oizg!Ml#^G&=_2D_cF%!;%uvvX*ruR9lc{!>j2 zX!N%wtJ1ns3G{_i1GmBMnCSD5&eTBiF@GQz`T63b%|uU);f$Jum8lo$KM$U3RUHAM zC!gC{8NO$>(ir+hz)0(!o3B2Oy6tM|LZTsB$2abOBhbAb>k{5?jhun~Z*821d^C~X zuogm{ViA>%oZ_nuB4oerHARrcSM6UPlf5^_^NW9(C>tQ7kxcuGpcwd5JiVOw(L%A< z_4Pp6c=~Hd|IK&OBgMtnrB6rtE8j`?Et+>-`uC9j{CCn#i}R4q{+t=-D-D|cZMYO~kcA|3g9`crPhg-ml7YeEx9vq-=a$I(IpBG@ z__9lhGS(G2CoE0ProG7s-g1)g?ah(l1599jx5{kY6m3sp!dk~diSh#ApLNFSYm~VxmnLB^H5qpyaF<=>71ZGpV3%evU&g(@FX2}uUH#a5ESiqD*RZcR>bbzL=4(h+dIhkMKK$H$cV(uj zPkWP9;_I+O6aQ4g`qD=)iB@5BthGvh81$ze@oq1JPi32a1Ihn9@G|sFaFO8}e0GVD zDn(x->Am?v{lVU`o61dMWGm$(T}*b6pC*dFY8vN+LKeaO$jHz`T#W!9eNsr@Y3|Z} zL3BxeZ)l8ptB^-_*mMSwD>f?AF;AzbClsG?7;224^3y8emoDMbvpDkt{Xkx#dd>SR zc!Qa5BK|COH5P^b=|R}s<3FwY>NAYBsmENP?V-@lT+nCaA+DPGK=bf?Xpdx$|BnPk zC&3bnXWIWekY5z*Aw$9!RnS-1nuirix)|M6XJ z$Z0<>6;X$4-B20P3p+JY_DJ?^Ye830tli-4W?qGT-(UEXycz;8!yPlwsd2z3QQ4_M zA8c>1|HFS1bc4|?1Miy$_-TBvTOl|GG3GfT-bDOGlcDh?Udej5EZ27poE$vG)eMHE zjG*juB%@jm?;eWG|PV5IN7_;)h3i?AsiYjY;r9B+>=a4V~WEWmJ{O86gd zTQ72QN|-n4MP5$AH~HUS(Veg#A8<&=souOe9J&X&n&?`lJV5o;nX9=%T{YqVN)XaJ z^3ne;7*EiSR? zj#+Vr#4+%Dnbwy?;NG{S#5Sd~C7^?zS9fTwk{i}FGsnXtJo);;9H(!%3v*jts|>mm z<#~>hfDd;I&TL7PZ$;gO@TonH4|X5!Abe0_gJrfXBHz@WmcRhuHX$ENTzYHDpD$Oc>4UTNa?c z_|^)Qe8H38aj?1Z#O}RZ4#oJGzKGQfp2NMFu)di&*N%{1dR;f>j>=WhS%wMxRb5z8 zUV^@pew2JBd3teAC5U7dg${p1?Xqjfdnt(FBZdtx#d z4>}<_GFp8<5TTzR==N&9*?7qLG@h-UEy@GvZ{~)Hau#4o$2+LlQ^+q74}i_$9JTsq z&jL5(y9M%5b*g(umH+Un`AIkfGe@$k*s-TZ&ca6#$vphBmbd7HdSjFS1IT^*I=PzK!ySpyU*G+<^*z|w z<*X-~dRj5};7lCnMCUe~T3sgYa`@HOq7*I7qr3?mF#}f|g-%@*U##W}nX(gW%OL2- ze`u3NH^duhPWj_=D}=c<8U8pj#gBobR^=_+Gye>-KBrcDNtX2hpT9XIP4!jB<^3(0 zm2`*J4_#q?grBM_Vv)q+!_9@rXGU4t-|7$HTxF3(TL*~uobH)d#Cpw5T*3O0#K@eg z4E3i~tk}|||LAZtx76IES2GazTGb`e3l!o_T2(rpfiao0D!ns`dm9;*FWqH5qy+vL zN)4C+V+Q&ZMZHpZlV;;U|9P=gTSud$55k^;=8oSnxkk4<^&(SOXtJK)Emd~jlMh*M zZ{RrUI z?x}$any2jaMEPBWSI5KRnThheH96&lz^w^7{H{m1Q>p4&uTT7`G6TBQv?4A-bWH1) z?!0d|bON7G0j%(+0w2o>(Ydf6r1y~cg4BqDGi)clV}Sb;@K^jf@r;&G$B|^{w;6mP z)S_Jz+9lajJqq53wQ5}7XjP$8m2`q$6=b8`fv-`P`uNUu-O>X8KR|!5F)|S!==K&} zuOlU#lb%7-A4Q&{@zLICo7akefUC$e1DZYu2aFjKh15f)B)~GJ*<{3xAxqIer1W3Uj9((Mg5_)`H4u| ziMNjZGOuI|@g@z%+Vo24j@&yIxQ8kx9ZI{%t9Rfogi2z;Ec1|o2Uq%( zzyJ$a;ji3KGOXF_;hw>scguz={E#efMjl@a?Tx`#hrv?`Uf4m*^euud zmIpLGlgkUMcjMeoz?&%0eTa8sKI6@3@fyy*yk4&px^9FCKfik@X5-r#ug8dbB-H1I z&D|#SeehIT4aq3EsxBfRPdeb@2o81AR)agowJ<8|O~CxgfIJAg>Tv(HzMA;3y72rx zA;^D2IIsCy9kC>-%tdQTXP)Q#O+gk-2sSC$$1CA8?3BU&taA2rzDBbQvY~#7?=7NH z((Pj&xRO~Hb2SGOHQNZcP*#OZq2Rk>j2p`$_ z&kpPjkSsd>e@48|X%aVTgFW?>wK2KE&rK+yIvkKKN^y2v;z&*n!+(Ze9E2a!&~&m9 z@FAV_sfDU!@hn}gh*)<@kHarLY-IRC+%?16V?M-p)&N%=&N|30z5PfD#&g6wBg&i1 zkXQT%{cq8F$m495LFY-dlz@8eVQ-NS<$N4pYyiG!4HKX*r1Lm4@NUBT{Ca;$z;G(3 zd?U_$7o5s*?RhX}KR+3CO@1s~)*o6;sLKUfrEf9L`NF~0qUrZf?l6lD3dNCK-;^bj zVPgzGGGe}R1^dz=*zMg^IJrXye_UtaGlR|$Y}xPYp=;%`L_^JN!yh4Y;J%G<`S4Zs z7J>NtTS9vZ{F`ZZWSo0f72${UhbHdhk_^~u@$fZpILKU&dI-NB$S#|p2R12LWJB3M zd6X~6-A486Rmc^Rz9+ett^U|*$peoVJvlm7@ea!B;(6Lr^zid#=^?v;G{7+xGN7*5 zPBsJ6EhwJ~{RGuHgfmwvuPd-C2Bck5=Va-EI1?$-#o$E$bwN`R^ENakp}n`QA6tF! znZ|#dI@(}Qt&t<87F}m{jipQ1YzeQ}ZVWf3ZdB6+eelNA4d}PY@P__3o3Iudrw(Uh zY;Qt+dB7*NZ^jsXU0PrK&yVYiNruS)f5y5YUpZ7?Of-A>5w4c4fKDYeIk3(lD;xL! zF`zG+hqdvKf!7eOM7R;*lL-I$zR7_<{AF_BzwrG}eE*2=yZF9?@1OAXxyoz|?+h_~ z>Aj&BArINb%xZmMwzghBk9p&O?ojW@?r@0k>xTa(v7x%ax*)I6c_ZG@Gp$a%FZ<$z zUZvnUX*TYsGBywWNQS>R@Mbx$`+G_b&TV*lXV0zH-O#7NFTK&dEqFsmin>wx@LbBN z`$PXfW8WU%RF&<&b57ERS|CkJUsP^M3s#3a6AGf#44j;#51ytig^;3_g2*U3fj)># zg^;xPxCMH6D2UAT6i4TJ=Xx`aGuLtM)zc&tM8wh}R8%Nw!TN@lDuW8Y?>b4rAt78-Hh6p)GbInaFp=9)^cXS+QA0~lC! zMhyp@;-7%m&k=h*3%n>w-#*%l!JeAS)nY9t9uR~)#4SyNAAnCvg)B?+lIpt4(mXG+ zX;VWLU}lJ^N<7ZHF5_FSSE{A&vNwEDxf1U=wee}`{Hw1~yKr6#oBi+Mx) z{+xMyGxV~^^DX9bC8n*kK0bx~vhRogB9rXGIZgZD!@S|#x}Bu^EJ0tzi<98ry8}A6 zsNZ{d1+Uuj72ut(j}NHwdIk1L;Hz5F*A?cf{(-&N$7#FoRnJE!_i`p1_FRTuF4zCo z!%_nJQFY2+#~tE(efG3SDsTf@kcbve_3>wI!4;~WoyVR_-B)5y5IpbQ*bKWo$|pS$ zb{=b#rE+A6cg_yT+XohB1hAHSQk@wA4(ACb=$y`D&72H+WQCIt-H!Hj%7)@o=XGZb zgZHX+$0@q{Td>~ISWw*lIAx!W|h2p*bf&S1@~2VZ$j z8Ee>KP3v738k=M+%82v`X}!dszdpn~>GLxp8szMVZ2Ic;Thaas0X(#4zx>tO74JC~ zbK%S-{E!azmw($d{5nUrg~;uh4S45+_Gx^{e_X!qc}k5JS;+>O;*=xE?OCm4&dT`e z$vfJv?|AC^!*q_#VGh0|j}b>FIhFLl4)~1vSy$-^!ndt%a2)m?Gtu@-m;-z8nX1R=CwM%RSiThV#_ufdNClU97k@Dvg zJzCuVZlwH$M9(*ng<40-f0*dGjQc&fzn9j4fke-zxNnKwvyT%!CdhdP>{lZ2u@?*2 zOzd-@U;a%QmG_<&_n&Y@Wn{X?9%jzEi|3Y3c4fITAQSgN*O4w%yC)!q%q7^<8oQ@S zEoBGZ$yAJ3kC{gZc1y3-pwEc&ViLy~((o(=u|(1o*qsY0y(te((5=iHy4hsoK3h%g zDO(zH&T`GXJ$RIIX#Px}H4x|OubigW4}1=KydYjNaG+^lUve$-s8{8hS4=7NHX`@P zf&b7pob{aFw64BpN?cx({op%Voax~V!+G%fz4h58aVZtkY}r`*+$DB>crwriZfNs;!lw!LvpaU&}4=zjV z+f`sY!H4^<`=8=Z@k0mB^4rqd`Q~Kw@nqSJ0cP21zOw0&hQC4vPQN8#^}O!8WbM2A z3L^Jt>sR3Hs!-&%nu1(2D}>&nx3P8w^lx0xzJmLJ2i;Zw{EJ#K>N30%%xZ0_fIxymk@8^70@eUQ}CCe%jqurIb;_u_avUB zV=URpWSkYg{Ej+a$XTyBxnKT?-ZGF6_$b!F5Xz^(4)RNsXCvhowf;l-OqAE4{5RLG zFMZR)ATN(fi-XRvr~dj_@J&^}oCw;Y*o=ouZ<2(w+$6FWP{dJZ1o4oh@4iWTuvi~H zCamhV2>QUD;Pdh?g!!i*AUd_SG#HN^lH(WstJHRIw48W%@#&k2w#ssNv>dr7tG=~( zw5)~yGAr4SwH&#~7VejIh%;KJUpa8h3Apf%_GYw)f8QC^*^SbrJ3>WkrNy0`X@?E= zC?Vur3FZ$a+q6SdE{dj!825bq{DN0f@a{l~Un+bHSDZ8C+K?+Ttt=otC8oH9?9X2lDJyvST>XLA-O}^|tGxbM-zM0D8pkB_w4TU?_N?D>L zQ;dMQIBy=W&l^|=xOIU05OC>M64I{pXk5=cbgq)V_kJ+i6I_rjg*vLB->~bhXOF19gFd#EgQe)$CYa}fkK_)W<@+B@6f`zofX08pP?u8S=*VIR-rc5cMBc zypnxxiSMWLu(zt`Xe8`o!-R#tQx7PGeHkyObn^0KSE4sxOz;}Zd3iV5{ps99?_^hk_l6=~w!X<*%w-AQ{J9C<(I`La z7%xvLOZ3uwE0}Qm>+MBzwXl13Ypi0`zpJym`Cot=el9JqueFMAr>Hm zT@mRb7{<%=MyJGr-mYwcZ4mw?an`R-XBw@80Ldy!H} z$_pYF0nTDIXd|c`w@ruc2kWip0N!zD)=JZuSwm-@d1$8t&vM(3OYyLI$riRqac^VK zFFfyHnD^;;uf@3z$+BE6?8`B~M9c{z?yYy1N|P~vxgzllQ=W4Sc9qJ$GD%8}^_Av3 zqD><03l>_GowfwyK=D3XiwQgacM>sM)F8;ix~^U-=5=wV<%nIOrM7(4o@%R$*Ji z^M{+H=aomLfd!9B8C}oI_lu9pzvy^Wo?v@a-Wq;X<_|Z@CflQsp(gDN72PLYc06JAyJr2Kx*Vp)Wq=)UqN<&&L@L)GQ>Lr6 zKUMZ3=Nrj!oJEtj$C)Z`>q(V;cxMcsRL4z0{O}whsXlV_NlCltt05Eg^LHU`h8=Ru zuPdT9LJ23coGH)|8AaqaQ=kuC&Qu!CS{#+PUV9)m4=#*`{jgo7BFVLChjyT)u2WdWHt@ojPV~`7E*>_^S^vOQ7 zn}cUQ$T-xVQNQa5kNDzK&_^CJ`it+t9};jA|3>b_;RAs8C9H>ycN(Qk@Etl=S%I^7 zCX8iT+OMHKE%rXz9_`lan=X#+hfUuN*u&Fz7K+u_pHq`42!d82$3*YyW? z$YMp7^AW`eyTU5fX1P`6Rq)ZfGfCYum=vt@;HN%}Gx(j1wbDgpsK4|Kkgt9O=Qi{V za|CfXKERpe_vJ|z`2c-!hc&6$WGjF(aW#kX#m)P9J151#zlM0Y7QEp=iC0>s1SNW} z742sZK>{3$QzNG5x>v@3Ezh7GMG+D+1n zvH#U!lcck9+gowZ@UA+XEr|+O-*!*o>5*p)?W)fq)82=*gX-|1j<-hYfNcnPh0_E& z`S8dAIXh;rK`=6$_h8(<>%-@D3>ybcDu=iZY9Cj}gQtMEg9fJQa+%Jqm7Jg*Tm#@8 zum{&!C@*7Ndq_Gggrq6BevT`D^dNLI2W8E%gEBjOP^L0l26Lo|9Xj=Y$1wUF`yYq? z-xr=F#arXH=fGZy%Esf_Dm;7cEPP6Y;?pC~w+uzg7K`7PeeQ2L@K4go9KP#&ALn9_ zosw-LOVtg1GLV0p?~@Ho#2Z& zQ+Jm~Z8@o|(WV*x_ZwgTc`Ck5v2(*2u%~$y`1p%e^!}|b;~Uw?4aWqW8h-_bi+v+O0XtQ3^r#}Nwvm)d+rRt6ITM>cX~#E^&)Sia#DUsUE>-X zsIDBqZ+JNA3}~p{mUrKoS+KXfQbs;gKN}!>PObv67#zvN9CQa0)_zvWPJSTI?N-mE zTq^(iBB|zStfBf4OZ{_K|I$Q7V=zHaLTfkVO2(1Rb8xer#x5JrUoMN;Z6Q`$I^y?_ zF;B~zBuLVeAw-iTfBjz>-|29rJ?astG6!nkQj;6du8V~yN)WOVv*P0QyK0}k|YRClNTn}GS z@NSH^wlFim1)+CvXt!_v=BwBF&|cYt`nJxB@dlZZ4(i53I5=_fZq~fY}yT{cgnAHk^RZJ zO6sF`aJ0H!86YE&?a5l4A!-4msfsmB)J)<9;O|xB&17dM?e~_lQ^YI1Gr2sjlWnK? zDlFJyCmu-SbduTcVSQ;DIu#hhTKIyFk0y9+op zIiQchz8P|Q^qE80rg27}=@sVc>Jhg68|tjWKA4HDN!10qy&HX>ZmuQ$F}paiuF7Vu z>-_@f=L0_M#eY*qGFES?!727~H6%Apo!NNv^*b43MVd3rDq2|BC-XLL1CRWt8pu9; zPd4I`LANUK7;~(>C)(tv9f%P$LYG$U@a^CkBzKsg-yRLV3EdD>rnYf^Pi^DZPi~rC6ZK@R2_Y|G(7jnB-9D_}_qj=j* z4!)V@m!dq=(BZUgI~vBR}@uT1f+4hxQQs>Gd-PmO1(> zwKzv4`Gj;kiJ{SkPBj)U?1_FLr*w=w`;nZozN(_84Qqt~-*Q;9Gy?ckp&9ufkP{Go z8%4GSMy%NlPhLa*6y-Shldp?xC%N|H#q|GntVzElz5u(0&ygp{PG_~CaYgHMXc0%v z1RSugwBau?hvLJ>VRteQaW1Oh`+2;Wbb6Oj=Luz9cl?Rt^4-6HPHM4Xn1i2QAG{!%w^=Seg_d zUiS2oG{`2qW#SQhkN277r;YS;%s8T&UJgmC%e>swr^`l6!n)!+eTe(gkIz(Ww#VLI-@%taNPo$ zt5*<%U~xe~!jYK;hi!AWIWb26g=dFL?%cM+S=g}*WzulJPjpMV_X`RRJ1V#Rq-1>a zi@+CuYG#4XIc@voqJ^Jv%l69}(9S`dZQJz1xaQe3GEWN?xMh zI#<7J;HMaaIN+D~;QOOa|L(nn_y1!HVmk2R%mS`sX2Ci5i`WmEr3Bz~60Q;K|JtnB zXLtQcRxqw=zaAOw>Exx=5j@x8Inj^~ed4UgrGEU61arINaG#6&4&3*LCwHgYO+)eF z-EthB9mccIh2zpK?Z>6W@~P5W$EQl#xzO=JUuM#$4)B-@`lI{h_yvIT*nauMLck2Y zuDbsK?X>~VDt#hXp4d?_tL^YwDG}`*#FaY;{)zwR@5H=>E`f7MlI~zZL3}a#7c3|^ zXe-_}2hR@CJLk>Y50=c?M(;Y#t(Ag!mk0gRA=}iQPj^aE5d6Lg8WP?G{GLWki4yJ6 z@r!g@Dc?l$5^n1gfQuu#ElnTRSMHWao!%|q;My%GbnljfX#Y91F@o1>oPUH-?{7m> zcRqtNRiZ0JEC1bmS_qn@`9yO`#2Ax(HtB`00AH9}QV-3kp5yY%_d#cmy)Zjz7$h6u;?F%n`N=xuiE}!~gV4Vs@sIVBm=N2nQTqjqF%>EK7}zOLei(7*7%IpIy+e z*6r<2s+om*vR7&}^LfxwxVCogmZ#$x>Bia=pR{PB##!~YPujL13;tx(XMWfyqMv3> z9@!H;2l@JzUk+6Mx6lL`ehYX*RQ_+BLvo#H8M6R9MuF{#bqDx#aI!PjFV-=JbWhkP zjWTE~Nt7eIq2u@-X%!tP3eP!64}bJ6-C3i4{?Ua}yaQiet=uS^O7f*&;Cf;{m9KVxOg5Q- z_kKL{6+!N)%CEUHs`Dd^o2Soq8}dithu96eGPm?M*faVCZ6NF5e)$^OGsAxANns9r z{SZ62eVUCE-)Yt;DRo|jtK;E6nD8cSnacJ^qtVCJpiw5+9yeN}YhkD*69`e!gg66lM1dk^=z%$678#(w* z>2_@^uOnk za)gY?Ht_%VkG>+)`o&Q>$ioz$EH2z5ZvlS7;Lky&2lh+8u72dnK{xcjZ zHk*pWlO;>G5gxgJ)&A>yB}=yvF4KzA1B6c;?rtj|W&3CVylZpVZuub|BX~x5q_vRf ztOK|V1D6+yXf15)`U_-{QNbQL0NQ*9|4TZ01PyF)C@y3s&2ie_;ydUuVcX%|cm(B4 zO6x|VKT~^;qy%fbX)JiiF;?3hQg!GK=`zhd=x0gJp}0>prnF~g3w{ncXOFZ8_}h#1 zoW@`Z-Zx^5d6ap{GO0whb;DkCvTYC6HR$0)*!^Q3ty=z{+8r0z#+A4l!>~11UUC?Y zu(WkVuZ}Su!gmSe*U#U~avq%r`QYaXdGs#Z`dC9y=z$))N1BY-{~Ptq1FQ&R2D%V& zW~IUUp~KvA&x76#=U8nsyk;%v$OF1QjJgIPS3bG?Ty)MH9pmB9kBRsl0M8iFmA{N~ z#OHj)Q8=JmalL?N9QZWZbmpOM2Af^lhmj2@#m(T&xn}jbMNpsXao!LIe_m!ObL;Jz zq(Ynl68xhOTM~{4ZYKP@gDZ|3)+nph@;{vyllQ5ODxNiptbu5f*5OA1AH{Gc9{C)2 z#>Jl5h|@$gVBY`F35st|U1y8uweQ*c$=g7ZDS2?4g}<3*y-L z7A8ZVFtx_}OEctp4Qn&o@_r9qofq0EvvTO(NY56;S;f38CyzL+@6U~$IoRQ69)rmU zen&VX8TGltbbg>=Yji~=w<7mxGIE8!XZQdxRRE^lfN56@rg4C2xBRFI)1Tz$2&RtR za*+ztIKY%&Lv8z^YxOO{{c*#v9dPlX-I!nSlfpX*ZMGfUEv6K_r@|95@8ZLJN;2`@| zEbglB2Jv#zHx&&b9@zYw84tL~e(Hz&91YzIn?ciUat^LMuC({D;lCFD--H}(Xy;Q? zfkTSVl?*ybf<4<7^urk8Ccbz?K6;jR99p zrfYPbChv#x5cbCZL>@A$@=*Sos5}&;J=>4uAq$?>0H-7JP%h*KAr_CFY-h3%V?KhB&(E^!hM7~hoKur5sz3ja)o>y?6I;UT4$NP<; zCV=}KjO8wK{uD3DZ3A6CN8f4CDqV@BvtgXa&cpt_?7duf@5H!w|3{r}`E= z{9Btt4c^WWt#0fI7342@uUXW!O}Q+&yImzF!C$mXR?_k{<0bQ()jI0n=vpB z&oVj!SZiw~?rP+99&vSk-Orhvc5TB`qA@T!?}ohbc$Nd(eHU~SoN$}e@}71gJj9oI z-xKR@!L>Kc)os8YTv^K1dHW5uDGy}2E}37-b3+#BJ!+V3L7CR~xVqISL%zR5DTB$J zGiUqd)ZuYKN8z?}C=+zrx4BS$4RmZiAx%md5OaODzrN#t*btzcEo5u&6aVs#CivgL z6+hbtc<3GZYzm)0eI2`Os+$a0u#yep`{HbZ zxreK3L%FPom>a}39pfLtH3e6$))1JeFwb)AwaYL^dygWI0C2}4-(73OAaj)kLusee zh6rcwNdBbAJJ_Sa&(qh=^=f|=fUeK9KOHs;qF_|@A|Ax)B|Q^^KAY_L$AXp{j~HCU zLx@LfYt7&j`z0gfiHWf35s@#KKVruEz&8=ihDGGG3nGsy;*7=FOt2X-Ngaq~8OFXZ z1$tB+a5o*YKDDt~$2ok(SigmdL$$;o&yDf4Vy$UYyi#aBVlRfdNh`5VF`M>~>oDx| z?&PG!>U?FM&Y66k2D)Z7UZQeqVNmeZ65pU_8pw1x%Cth8;;-dIeu(VsDAp*+X<|X{ zjB3P8p=VDbhRPEUk$)8UrK;=W8fdS;A5Y!RLc2igQQd`VN7}oq_Ds@o$CY1XxJNBOPJ9r~0U;i=b4~_x#Js;@Dm1I3yXA7`aQGXi_WvR5z&W!O;UYR)cIea7V zoOlHBhjZAMk&Y>VxZU2jF_su#Z^!}vBX0KQljhmvb2w5~gSkuV+S4d2pezeJESgi% zGIX{}^|b+?H1A2bNp;V_mFNS0rcD%k=BI$cXKpd8G!qIo6U{K2smX+QRR08&kMfGO z?p0`q>L9r29kscP-~@aGC$+D_8H1s@D9bfY-2+x*{ee#{Z03Bn8v|+h-&(R$nh`Ri zo*7L{NNvhSyve^{+;`YB0#k+5dfF}=9h>EUWkOP2QsIq(Ki=5(bFJX3(Fy*V?!16|Z_-Nx&*~2j zya0RNpzC2N6}pm01?*t4HhS*E-W9SM;fZWP)8J3x!2Z-g?SqecgQb>ThJ7C`#J;FZ zyiqR2JL2mR%_Dncy}C!C}AardX!Y|e69GOu2*EClRY;JQ_y{qbLb6QN0i zGo$n7`Y9%LZ}%73h&^{T=#pra_NKH~YP{=VX;4`T-GH{a6|`{$HpXto2_>*h5h%tIREz73ZOX~=tBwZMSiK%pdG&MrUiSYF!)HE@M>+7 z?tp{q=m74wfR{b*Sa~qZNqFV%8{;9kU&j8+g=Zu4f5bkB`xWeRF;A}+8eIO3N$|_c zhs>uL?q4WL7og+P3y29))l#bu9#`$pBEiYsEZ8Wo*#Nm0{A7xt`McQu590iV_B=g^ zKSpOx?qa-G5XZrT{J@xl|CaIuqxuP_WRJrir#;zE241lDSL$K&u?{?f_UM8F`5Stn zKY;&`ob@dBw8RG^khe(Yhy+FGNXjJW9J0N!cY4?X(sw=KEEjUOE**pZX2ZV53|>a( zv8oLg>eIXlU8Vqib)lhFy>_(J?x-U>64hV8AkL+Ak@D|Yn?hAwtqnQp64f;~XEvUL z_N`66UJkjYOyH?0vs~ya*NNP=9GqSUyv&`;_+ zdoT&-Pqq7|Vt;yNV4Z6JD}t`_2DyoJ{(&>#+=~z5OcVQxz|TkJrGwUw!w!YYq@qj` zuH4*g=;VC11TSQG z-!MWGy5)|5xEgvsJmlienl6V1UzXAb1zXmNDlbC3R~Es zdnx}gWI~Lw{!PSkaf*ob5zPTjbix7t4qMD7hh+B^oTnamARFdg%S!{vWm5~do~b+g zHr3QeaAvI?+EtK)^P-AHd|0<)SAhn6>vq`6JZX#CUyTt;3UZ33V%MHT^p7k{r@XLjOeKm49oD*c1P_?8MGs^Oh4IR+>b;T4!E+34%f- zxJXAqbsH3BFvr?H6Jjokk3?-xj@6w{@8B0lJbr%cS$eGe0Lps^ue4@3r|slmJ4G~; zuAe!uMU2vip2iU8l%^i9DzkFOx!&7~{-EVLx&5rF8fUMF;SD-u)tUy9bw2&u737>0 z43~o%*Tbm0b^cg2PU4Op?716mW4z8+VinR6mr=u}nzgH^8S*c(pkJnZOI)X4K9BaN z^V}~c3%UT=gC2hPipn1m+oawgRIBpTnrrcph4mP7R>xOCKN56cEHxWg$RYc3wP$EN z4PqAT1W5OdIK$v2ly4yow2wLI`3vMGlJ9(PL$*L{w1Sd}%ZNAEhWFZN{r&^WbfZjK z5INqFXXsy!BfbJ+v$YqKj4;}qh-V7UhG{>yf#~njxSA7Iinm(tzG}Nm^_8M|<7)^1 z=^=kClSFu%0laC?1ozvD_o`5Ru-MjPni30I@Zx!62y2t&#|zMn=JEJW@2CHaZ^3q16wdg zHwLDKe*6Ke{Ig>rIz5v9P_Fy-_pBgf8q^ABFBNK47#O19<{` z>|k4~dBZV#K=th@n%z{C+&ezZ4{;9Nc74}h|6|O0>@(;Q_B$9lAYf1S`@c@8$ZM8`Qq14|n{ zj|%&xew<6Hwo2CcbMs2Hj7L2!4n2#*l@;!jHC_8;u56#oodtR)T z61x5>AHwwpTptBJK4yjA;3;krE72Y@(%MnNA8J;waac>Tm&FOp8GnR%;?c&^*I>iLU+%IyM0}dhF?+86q7~ zr%d?q3cm(_ynQE+@g)BE6Zk%Sxv38}U|9nu%w;|3u@U8UD6gkEAdIi`UQGM;wQmvk zMEpJv3aw2RCChp2GW4yFXrOO)yM1G|C7ew>--u@)!{^7TAg5o&xk{C4s0c;kHCN_?JetlmW9kDNIqyB&5!&k7(XcpTMz1cN? z>;p|=F0T#mEdJdiB&)%m1vx~?hMw$QejR&OjTiu9u$Hi@q}l@Lr?ES5wJSFU=sEX6 z`K+g@+;QXZeBeQy!xdva)E`P?fskHAm1gi$QNMpeyC*rqXT$fGfgtP|_UT3aV zBe*&>7CG9Wla1B&D~#JHvyex!(AAB7mFE<$-lM`JfqyWA^MuAlIAqA_^TbC6HK%+t z+4>$X4QyQaS!FBvK47j;J7Y%h2RjR&;85l0omNd?M`B_L<@gv3g2yla8_p%yxhD!c z_qDZ4(sU&y;DcWA%ggx_zg{1Wsh+>^v!zro#l;FVK<@7~)tra!+Kl{JBXGBZKT%xE zi*J2aX(YT^90k-DUm}}BvHEw#`aS>)WHBmp^%CtX_qSeKFxJ(J*cSBc%7U>@`hVii&zCYggZ(4(lx!UD z%0xMm`Dt&n0&De6SgYxbGK@3mzN_9jNdjZoZyI*%OWNtb0lMQ`A>Y$~T5EG~*31fd z_^N1@rG3;=J3lUasRg>OJ$I$hoM2+RxsY?zs(Z8s;6f3$G-x4nG_~J~IjyZ9r!O1G z)7u6TfL~5uFmQd-*J@m0UP;@*2l-1Z^xv&ld#}SM9lT#j-@$^fw0?tozUr*Ui=1s@ zWRZLndQ@AuY!<~6I&N*zW)MTY9_~HFTz&&_ zB@})K7dBmD!2?lPd(V1Az+;-TTg^`>4%A8}$im{sFJqq%T`is?ZXxEAo^hy019_pZ zdl$}?$+k?-aGIBwVBatQ270(}7JgoN1J-)#KlPO>+bxv+qem(xkBX znP}yjCs}pPiO^x2aBsr>bod2wPVXEu%D-|2cA$hmC5k^LXjK}B;yLF#Jd<94#)(nv zE!52fFZ-iempA2+zDjG-ZwKg}VD_5jDK8%Tyz(g7L4lVMKIyw&VMhba{Rr^Yo%O6n zbaKr)jDHd6B#3+s)AdCIx9BSd9@3`|7*HqqqHxe7nT`;Dggro2axLhOWp}rTJaj}~ zZCX*E6sj4#O-YW-K%9dA?#}r-Ll7V59E+rUtQXNX_cZvew@M@JrX%jaz0iSa!}t{z zZYLNn+_hFBdntk;uK2OSrZHsDvCuej(6`W7t_!kdPu}|sH3yQPolkR>=3}3YuTOx!XBpu9qh7rD2$c~U8%%SNs}}v@%1uMlV5hYT z?@jvg0~bmWdq&|rGr)7N;lB@Sf6Ej(@29vA&hcepoYn3E_bzv=}{!<^l z!9{Xuutkp8zh8$_u?}zfX1ufQ8|Er1J6B1(k)0juc^db#a8LafddGU6Ig;U`+!sdV z0|;G@_q4q!kj{3HuhMMHfi8p2AnytZ(3K&+BXFbMBmN%`8l<_AC}<3Epds#@A36?k z)@1N((@{TUHO@d+E#@HUzz@RTHLIV?&V^l|5oNgGvqQO^T=U4gF?dJ#*LG^paN)M0 z<=8Jp@%{wPt@pRu=Ob?w>N7du!z={d)AjtobH5_|Cl3(MCHOjK8ao=xp`+rcF$59{$NC z*zHWm+3rrm4vo4ecKi32h>ZEMzon}dSKg+*qy-%K^Xf zp04HzNTE*P-Vq%%>&maz+H_tRT=@j0@^H#!CMXdR--?rSbNST$j8o8T!xKho!AY-Mw4UPWo>k>W4DK#gpQBIrqEFw^ z;hBnAt>{-p3`dc0#jJaQqn22o7&^@sXPglWGn#WiYZ+DIX?qdyrexM}CHB*k+LN2Z z*23-V$h56gR4Wvowx49p=dEme(c9Cu(wd}$51ep3uDRbjdAsk8%{GCZ%0qyt^k6)duz%lWfzAntug_x&A_dlQ?e`t4Mq>QV- zFGfGrXDep)0yj%WaC5L?)_uSY7sE~DE5mp6z6E`c6erhzNc3_~lwRoD>aKsJ_lW23 z`AZhjd&zC8|G)^1@b)Oo+HjPwQeU&X+GIB8wkA5O9x3OKm23P#xm+q|wQaQ{PDK6! z#ANBp20uoe_#pBK2pssT{j@e*cACw-t;vJBATzM0-rc~fmhI5EOQohmmojx_D57}7?tH!!$E$#h~ zd{v@6JdbcZFUkwCm(oKY>lt}Rb4;ZV)I+?5>JovMA)I3pedv~t3sleBEj^&p1s5Pa zRuy0zLfoQ|M-Vrkd>5dPxn2{6m4hwVrvxk39r|wQNANcM2wpS6>-c`n zu@Ws|%_$^WqBVzTsa&0VD(_Zl&$hcZ4m61Mz7XTGjNoUm(R0UOcLVmS5qdfjgCYp zzJpt5kHYPb!EFNE*=TQV4DPjndwC4*NDS`&`Y4U~6zz9#XQS^v%z;Y;cX1SMs;BzY zKf)c3eNXg3aI0(Og4>$%F#h1rs%+vb@~iaR*a4X{%w1waZj85R>#wh8V|QvV&%+$h z8j-^_2e$3nlm0u1x6{0z4%v^D-PYuY(VIGcSbJ&wv{-v7eh2i&O=P>1Eb{e#3-R?$ zE61s^t;G4erFClGqjLoHHLL>;s)2)=H!Eh*99bEI|N6XWKZ(8u@eP%w`7ne&|4^ox z|D*ou-vxb@N9Tj?JnR{l$Af3}&LcQUCL=f-V{m3H-Nk%; z722!;d^y-7*8qkUfRpC-Pz=^FBe3478Ov4uhHTS3Lnuez5v(;m6|b|4;m4%^$(9f_Cd;@YVy4RU`O)D~jK^5qK-VhxbdAqwiGw z{u6jVt^Ip?NGEug#PIv!kMJ9Vw{ZmCe}-ScJA&U{w7WhA?|Q&--w1wV@V*#p`}#fK z!}}G=(RV6-PyZu+cl`+7EP~hdBYuGOQpGFQOO+qk{3<`F0gZmu4t{W7j2|r6Ep0%1 zG{0zm2sYNR0r1`rIBT%)B7U%J1jYxx=Lc8u4V6`K3K)OL59~jJFYlBO@jen@n8`fX zYWga#Ko(}b#u}1$l5mz|EX}#3>3UfT3w==#*9Npx3cCY;kp!PPF84LSOZ$4ZCaH!G z`=u{8VXp#TwEOX{8hVc*>>2Mq#7zp~8(;b2qfR{c*^=uQ!MC3BM`YCQ+`p$ol6ry} zXWPL0N^rIvTo0dg#AD5{W%OP~>~FH)66iaW;~^umMgBvyR`g?UoncRpOggCDx>DFH zWuE7xK~1ci|yp^H&Tyn$)Ybv9(9cL;g`wqH(%$5 zE+6LvDZ}~D*k;Kzi! z>uf1!tKbVly5VNLJ72|Z*bF?i3Xe7TI$ER`xm~(2{5Uwsz8Ao2{Gk=d9ee)un}i+k zUHM=6LXo#45jm8T3%7J=!_f1U)ND@&oILbcdBKH-HUWF)b`j^bDZTW)FE}njcDUrD z>PP)rj0G#VN8?H1oY;FY`CDyy?xk#;PnRgn<)A(yw+PM^oCJ@G*K)sF-s?{Ow*UI} zjW&Dv7Zf``8~(Z!a~<{-vIaTZMD#OT@YUr7rJ~?{@V~aMIC?;`&DyTQJtX5dnQ?!Ld|TqTuJ4jViZs{d1~UB}g=noDnSJ$!AcsdsWs z%R|@4IutJTC48&;IV+msftLz3gXlAmCUYCVMZay$^`JGx6dD8F-XD1`J{Put zWXo(S1g#*>$;X4^odbi+)eLxjMCaWG&vOJ5bmHqe#aV4Q|KiZ^k#h{P$@viD!9<%( z<1#&HlL;pVqHEZYEL)**Dd&9Ti)Rq=-E`PY{S^J*ytc{XeOs{5Sd4lEawcM0dyk5i zM%;Vfut%>Q(Q8(yQKsjqv8y3=O~94Lp1p0esMn*h>l?9aNA&7H7Q4P_vvk}W9X}4d zXXK3P!rG|bjAFq*1{@Q8H{$9m0xY=Btp|;x|4)9I<+&gKz2;G7(qWh39Ox;u-?;W# zW$*R;ni;s#`856Kgl;!)e@f~PA-2ZC((QyJolqxD#=YOZa(nRZ!fo-3>tJiLUk=?} zv@Li~@ixLY{P7xi#LU~Xwy$yra=TKzIh9_^dLw(&rfcOwVh(2pFG z{b6rMQmC66^j$_cj+c1Vk(!+xWj3Hy7YxVVI z-Y#Pu!N&;|68Xq+iz^DUaP7J@-l@X0-cTdqdja)|Hc46$!d%3B(kzJC(4jop)%l5D z9*&m1gpaf!Rz>M^GoF$COYmXxrT;*(EY~=ds#9Xfy zovWm_ydM}mPh3PSZ|tS?;2|yUC=XfJ@NFfnXC>Iz8U**C8E5O>i;cgbE0;%psW`h_ zvAKjrHp4HCa?vv=L^KUt@8%L;DeU+>umS7zVjTwWge{Y|RIuby9#;6wHlp1fAA$zK z8~xR#1q5q#DHqPc9PdRO)fV_h*lC_e9`lf$#Klb)UnhIBS1*otzH*VdmI3xAqLVqP3Gi#SMLUkFNgm&`T3JoSjqMX&)IpbWMN2;Gz0b&m-nOeEt)}>}8EYPc1`C-|2`M z(u5eTyhUTtBlce_>b^;c4@?%~0wqG@zBx+MzQhT!Nt^yxkE^%s$| z8+6>T1@`Un$SK*3?+6}(t615x@6itlrud-&*u7px+36zxg$Cz9*@al|u%?k6+2+EO z-aO#F3cP5duwS|vv8y=6+Qcn11~LQ%HblxscC5@Y0cTk^26xESr;@@Z?8oN=x0Eky zbHrV+!kHAFDIh*E&ed|TFWiB5oBP}am+r}^{}}BewhYe7tWBxV4{)$ESy91-$tJ@G zJ2xti^H8;X1ojz(yAhku6wDX3{7H-{$|Z`-Mc+}~RQ5~MZ92F^s;*8si@9$Kd@d``-Q;+t3%gn+;0Kym5T4u!l*X zzzJUU99RolwO8Z(05m~o93}pDihzrLi!e3O$ot2F}n-O%A+^O{tZKnuvo}fTB zfaz*ZM19`1pZFXV1tMsatJ*wg7OuBd7{W=wdphu#1iSDZaV-w$+3FbTraD?Ld;iO$ zAiw#~cIpPL;%ToP=dHG>7S@COvhn-+DSioJ@E~R;au*!=Z|rA$s(mHZ-vc_Q@zG$- zxPQTaX<66SdEdN$rP3@I0Wzu+yc_-}M(IyJ|bWj^|(#$<#YCfNy;W6Y|{ z4dF#0L-Q^nIYNHxBJQ~pKDk0PG`C?-l7e+6o%l}B*o(Q(b{8c_V9yLYJ@|q_cFhJ} z(gkDHF0bT(~Z5ervq4(^hfmu(`Sp|zKc zXN53gzu1x^*FIye8p!(&*a=^G@c)K0r8qgl4n^S{8-p_fIE{dly%mEIW#<1MF!FEw z0LBH_L;e54I5#=+d%(CBFzNy0Gk}rK@(hpz=fbChDXd{!aS$8+0`9zF?7zT6hc*qpzUh}K7VXJJpq=Eptcnzwg%(-he~S5oc-6L)z!Y}0 znq-Se)%9hX;Lm5f-AQLB6cJtB81RMirJ#tMHq>W~In5=$G~MHaUC~dm269TytcL(6 z>^st2fK#Po*!vh@>(0YQNu;?7AB}u7*Dwn-oUG?Qwgru0;h-ODnqW|2wI}tK2aV)E z!IBHP$g|&&ZNN@hZ%wKqS(Es+|LTtY{Gm{@cab*`XX65hy@s*pELk=V{Shs>=!>tA z3#8_Wt?HP^`tfREv>$6?FzNwgRHm+S`viw-*9m#lxf^Y;&yAilo^RFMDYWj0=x=&2 z&es*}-{6xKd7G;rI?Dx)qRgeU$@Tef2;-hz(^vTz{2%E{5@e2S@G^p%A;wd(Eh(@wP6Y0egAe|s z`py>7eiC+(p;C)44BMMhpPbvhL#FRO29LV@>3AmxS!NaLRM+2MM(v1b-Zn$VH9~d@ z+VZ6@kBiwy*?;P6I45S6IjTQY0dTO3aIn&dJ>*)q`p%IP&5?94znI>U&9eVp_{Cz3 zeeKB+4Sch>!hFe2HV9%)K?rn~i}P<2>PkS&QC|plKJ8pR@zmBM+@w?+;;y3}?i&1k z6<^t_kVB3eS{+^iaXy3NkY5kK_6o}mj3vW0Z7zIn59UkWC0zKWt7$I2824z8g~}|| zAz0mD?POgz<3ky`*PM+0=P+kg*ka#mzfN;S;eV!qpA)S!3_NhboPvDVB}nd|q~DE+XHjUI1TxrO31c&!x{ijS(|4fr!) z?lU}NZ;rFP|H*jgrw=e!&!D$t8@{FfD-k1|vDRf6?g5Aob5%r!UG2jLT==hwIwWB1-qjh@4>i>GoYKki#< zcp%EpGhiFJ2KBbwyLHYK%!^u}=vj>Wt3vc%7&dzP?0!k# z^~e8cSb+HkTYe5O(Hh-ynK@s$Kf1p$U|n2-Hg}3?fz&x^0a_!;2BiXP)VL#Qk;Ml^%6rky)$*_1oT6x;2*EXo~yj2-sqvdiAK3yT62G2CC1;TSZ@k#!amsXw6H=sFz^}?c!Ix#VAEC6!peNRk zQ-<(#oX1cfoUuM|RmnAK9Sug0rgKI?YOD`)f6xb?@b`Tvi1op1XUv2?*wH4{(MmSI zju{1f=d^-ked0g?_I=;{0{cGrS-pTc&<3B|yv`KaHlGVj5K?6BIQSpV;U_uy=4`AX z-gePKvGLiRoW=V#WQlp4CFdX~o9vuCF~rGbSU=L0#I!2lOFM$EuZ z<9E6c4t$mTwIS)d4>gUf9#_{J2wIadS#br}0!d5dkg=~MhcGxok4lQ^s@kx>o zQu1zT^zib65wvB{S>YJbX*OaBIuR|O_)o*m29IQ^1wp; z=d9k1kexSjA@+rWT-l}&L!5WEOnJyxcK|lVEBaV1XovYa;v3f3SPE>V$C~=Q8(j)N zjw`Bqeecp$aedIo=7hMlhR-rI-l={uh@9`X1Im+{5Z~jE^*dh8p zC9mcd6<#VA4jo0mmo&m}iz$kGMWy#O(_+93`cAoJT0IL@58i-%Pc7)upgiCf*CCG3 ztj*Y$VNVRaWS?iXUZL$B8cPwmfyO{iiyUDAiYKrP?+;d0_t2a%<9phxFbi9cvMuy1 z6Lx+acxAevsiGVN{jkf96IQw>DcSo9gB@QGO=zz+?azH|%Qmb*neHO;JPY*1uH3yW;9tQ4 zL~{nfNb6uydAg?a9lvK^vCL!;`Gb+vyGocvo8CQbX zp#}~%5eM6GMgW~oJ!FiY)#uN!W4wiU(T&)PhQK2SA;bC=holuE?ls^`gmVr&iu?r| z6vz*NiR_Ip0KU)FHV}&iyv`&bZz|yOgTH|>xfh2x6I%gXE0B>PJL7q=FPQVSK3Hb= zp$z;2XHj41tRWq=MRn3W>Ad(i5c7xh61XqHc>xm;Tc8uNcdQ)2bReNEkMx!%%pd9( z=Fd_N`kd(>Lf&fVt^9Z5n{SQtOu>C;>|QuF&XbG#!?Ans+v7Z0xL0uh0?I3$<2;c$ zun|RHiN0^I1Dy@9z!R&+!^b6hjPJn1m#bNeEF~ax~bM!3JT5$TAJaOokAmfbA&Yf{;z7 z%8EtC3#CPdq-oRS@20)Ixw-u}$Fe*y1dJI%2yuiUgr-RjvSUg!`Tdq8r^9>i|Gnq$ z^LNhH*~8jvuf6u#Yp=Z)t*3fCc|561*N;`Ref&>6^N=R`RDnJV_yeAwBR23}UCJdT z)*TISm0MhJ(1&%xKzqt%kca#B(j9ovF!19mo$mymGf)S$0X|gNjVIl2CcP@%LG4z0 zuQPmYnPgJq{ug}?>ne_9{7av2kM>y)T0{I?@EqY^ z=!*q?v7oOY&wNZcYJ+Z-?mAFi4DPn%d>g3C&@)OO_(IwMqm1xBHSCYrp29x;7lnuy zt?%u)#K9lI&8wyGC8IWf?<>tXu`aSVCs+WSooM(&^Ff?r znRL*H`JeMXBQVyC%2O^nV<24?@$}N-?`~yIHR4_x|FnQTH|Z8xypx~EZd(5!hhVIg z(mt$}ST||hG@yq=67|8nbBy=W3Fe1;-sIx|`ld?axB3RhP7T)buXcU)?sVL-W|luc zcmZbx5?|^4(lyGS?%57A3)r2)R*weyfZr?Lx`ly0eu~Da&n)@OqH$fKnn(eT={K4? zL=U9z_Tia^rxeeQQ#MZ#WHZ^Vb5<1g$;Ed6E4XXf7p4=^J6`#0YvD7WoAvyol~Uo+%02pmZ+x(WCVOoK-)|%P>%uGg zd`@3D{$kuqvpBze9C~G&YK+yy2>mvua_g8ZplYUf+(or86&uF5z@Fxtv~HO;;9E>H zNBJ;jT!XBcgPpkyGwZIS2!q;mlzRM}w zjVp|G-}VR|g<~1^FOl9GO*8Lh*s<>kg!Mia{Q=rD(K~w@I-p+W5(k-{cwYhJR>t4% zEkIg=JKO4#g5we&{2%-B=c|?ZnA?aQ6PC}MVf*_yo?)1^k~U=-+w^$@WU5;fO&rb| zXf0s)o{w9h10o%%!p9cg0InUFQ?!Pv*GBet;rXVQBF5BeTL-?$!t+fQoo^iGTSs$i zl;&@QpO4zC70kx?0(OYeZw=FCoF?HAD`0Nn9D~I?kix&Mk>p&&YT8q7^9=OaJToe! zVmthGa8))>e^tDXWPml8=R#@qJ3>;O=C5 zaUP{)^}{Yd;3awXpV!bS9>)QP!WBJ#oM;p{lVd!8^LTWgoXoJl1)dkPB*UJjOif`B z7h1|oZ5gTQsy_H?a`!RKeM9ALuA%^b4i0+L(^Avv`v83R_gTu_pU`ut!W~;qb{Y7d zm6}c8D|#c}*U=N-W%$nGdq!UBH2OZI%lCX9&Qsy0_T{HD?0rKfw-I-~6x9VGDe{7M zZzTWKdYz*!VY0U>*<|WuOvRmfe3R|c$BI^p?LFLDHk$m%6Iv$lgm$qh*_C(k39Yf_ zq?l(a>rB3c_v3*5G{$-uo=oZl*1nVFhMqpQ*-8@FnA2x~L%JE@zrK z$ZCg>*A*>y4DVl1x%1WTzM+Ng73iO|rXVCk{}}#y^5=r1Eze}=l$Z)&+qT9QFKo0$ z`lTNIY?ZV%@7pJ|Ri-@HwI{YnRzIQ56VRvXBVsK2$835+8z;@SFp)Z1maDRDbXARPXi_P>Ls&Pv(W^(lD5c0b4 zTOx4Qhv$39^Eo}?XXrBIYBSnqt8WXDJptiS8m8Op$;ZQZ&;t(|;Gyx~@PIpW|6lN6 z=oR~P%ud3EWZ++M!Hm4=C0t1GoWh0l%$x8Lu3nkPKh+%H^puV5cYB5VOUw-DEN-Z{ zbBey02H^R#C$x0-NA$H4<3V_f|LYUlc+;(&y5ko`ok0)}PP$*xojfY$EnFSy-Q|9X z3)kOceXj&bBf4cM5`1Z)9AsU3RsXlozwT z%3ud#ipn9+4o*5>V#8$KGZbSg?^Kv( zbS}SVMM*n?b;aAOnfWulvlKCWuLTb<))%e8S=(#aN@gDJIfT~s_#qtP0_53d>olHMdo_^Bb zn5sMTOf{XKtx~kcUvg?Cz}XZol}Jb4XO5<#zt0*?7N@=!k4~&gZ2juv zgjSVlc4w~Xw$9I2CAG#Lacb{HY=gO=!Bmu&j5)O{EqN}rDc+?pIkl>9oZ8#K2Nzo6 zUGfU2HfGSNH6zAB!e*y7eZr}2sv8y;S(068%}&s?Q@gR|gt&giMKO_2vE>P=wmZxc z*Bo;yV)jaG_rMPJPIHQ@)U1M^C6(>#$vrPM)%J=T_+#SvU3*^2#rKViPlyXmX)eY4 zO`#1--V@g^y(lJqxG|)*B)H~U;#`U6*M}CE;#_x~PjeMo(p~1Ebl1Zxj*81o39f_- z8$z3x9TT_shs7qxS&``AH{iX=z@HrWYWQeD}=`E$TolhrTY3Y`81?;Dm2V(D;-t4ViJ+_>mHaiz45-B5d6 zT)*(7n6z|bNO80&#GA5RT1%!YVafVX;+YMhdo9_n2TYkRnP1j(wYJ;QG!YF1Fh-IJ zsh2q^^-|q=eANY6xl?;bm{-m0)WJvM4UAnn=-`pcBVrn8f@#3G3>@;#G$*_6!MMqQ zcNx;uwuE1PAq>xr;?a2+V`}UEG95kJwS#+;jt^$2ib3@c1JHv=3j zLc3e6{bC~MBGQ){^d-p^j~I_L%t@|%OOlJ-fih_C&aAobP@Rd05wRBK*780v8E57i zoSo-`MiTvpylSGGUa42PD%X-ENWH>?kv)rXVF3OEBomHN=pX~kwltjcIzp=N^oCT| zE#FMm$LSm?O89nQ5SM$wu|PeCc~b_R%gt7XX~5Yl3ty=ngAUJUSPLz^T;{xEfx5lX zx-UObUD_geJL&p;(L>Q@GZp$ZIDo{SiJP2)F2-} zT=qapHQ^Kae$CJDY=M96L`%Z6$wM|!cz?XI!7-Pa*w zEkK&aNokUd9znhlq-ksu`NbCskZ(PeH!X12V657}{}njDqVEZO&4r~%$6>ATLRLOv zs&(Ir^ykQ5g1V{BWW)mTU>r8--V?V~42tgo{x-;O4-NN;cm5=$Gp#oTaYY%1sY+|$ z4Job|!lP+HXAJNsiynP3m)M(;%a$Ot*AOX}!Swjxo*oLAK#Ob!z8<7yoTlYAenE7^EvKv94ad1{*W!y#Z3%eIJj~NHKEswOsBE)Lv97y8(}7iStvTSYkC;CY zOU*GZ4!BPUIkhu!j$**MN@!Q-OS#~;TdD@c5_5(toA1PVJL+G4Ol+&{6XzoR{$%G% zTWbB{BbL)5cWQO0&3s1W5nDw1z?M+V2akkiSaMwVS#n*m=h{M6Q;w_ne1dCjy&zT$ zCAg}w&fIc7&b7fbAg<}ZAZ~mHR!7k_B?&UNg5O}PD7m{N*<|cYFjaxK#J0u*UpbJy zBRDJ`jr(E!oiUn>xlj1cGgbbuepB2RrKzyV!Y6}1-#aoWu4!H?@Wc89`;vfE;+BXser#WL%(^!Ap4O` zo2B@pH7!>Vb6e9t%>dnr zg?Oqe`nw*#bpw_)qmC-ppc$Vn=nFpvA7=zE^DF4-sB9zhd>MUr;{96my&Lbr=(`W^ z7o+b%yr09qh01aP#9#VLmURvG=TZSWb3wYFgKkZRcz;EMGS|Rvqnm@yseqUEOkO?o zt1D*MeeP;(x!jA`#=3U59`{%g>#>=1K*`V_J|!?4Sw7!Wfb$l%y)mTld0!`;Y+ijX z{Q6+cflfz)b9wS}-iSVJfi1w^ViV+?hi?uor(7wg_2q%FmR1 zTEkl<$;AbNbARSb(sAMi^BV8jhIPpPd*-)Hh9Pa7MZIx<)9050hgrg7wsZmhEwCqI zebagh_`A?AjVGx(DP3w<3%@Mg-n)hLp0t*|TIs}d+Kj%mag75$_E9hSeqqi(K4t`L zte$)^>1JnrfAif7h!-E|eYxdkZ)U3mdL25eWy`usN{}xuj{WSxu-2M%Voel}}i$ED{rT0>=@i_W_kf46rLp8Rad?62TcorRu=&Q5RO zJ$zn)J{N#q)&jRuW5Ku*^l}dLViDNPOyKG*;HsPdaYlwOZG7xnmX$NG6Z!aES(bq{ z3N~T*mmxk<@#JJZo%vK-b75CNHrw#m4tZhrZK_*2#FkA*zIE^obT4RGZiFpFpm5t* zTeg+P;CChJ+rBm6H^fDd6svB%ir*RJ|6K_?3-ZQB-@xr{{mL^+nPFXs)2|IF{C{|z z=8D3f{`zxEfK!U|Q#GyUF6fDtR7oWzw{N-i&DL*|?t%Wl5bYJgA6xxXE)%pMayX_|1sy}0k&`@a5et|&bsR&=k#RbLHA_H7VCN0UT%$E>F01R)L6lG zDxn`Q5D=S`Z^yh~TOJz{M;{olqiA+E7~07}4KgS4)OT6;z&`JFbFnxUf$7v}z)4NZ+a) zN=Pq3d2flY1ZR$svgW(SRcBP=M<*xi4gz)-x`FB6W?L%oJ{{wF2lm2JDa&#sm+9Ap ziXijkLEmev=ogbK8bdKi-wvF|tc)2~K$la>@AlN;yJu5tB3Bs`%&lX`XCMYiO(o|_ zs+Eoh@!gK^Z`2vx3H*B7G}&~HvB<~cDiX&vitGW?;-jLHZ?)xAYzk>$msnDfD1P*y zD``ld6in;g?J-mkp--abh|wyH)>Em zEj}}$+6s9bGU1bmXWggMvzraM!T1G@Avx|C$@Os)N09#w)St5?b|M~jBNFVPKEZFX zsH1#I0?rH8*%FZVmBrO=1>h@0e6Zx91759OCT2i>BOX}oKj0}u`}gt(Jn86jkBH~dGH0KM*23;UH?Y(Z4K@=}Qbg zFc{U#a8!F^vvyeNfiUND#-PW2~7SYvx|+Y5^R!BoH}1ANd; z0k#KRdW|kaPY11FV(8Hd|qzQY6?j0ed!RVPN$K$s6>NU_Sbk zZ%~T*<1w!8GnMWbtg|!wQ^lGG2E`n}pR{g6+BTd|)N>#Rd! zF5=~=&HK4~jgp{_>M2hZ4d=35hmO{{V*%@|LAe-j+89zo=UhK{OnkwVBdbRce_uqsAo_lIojLCZ2%=cI^7qpuo zY_M5tJ`}$}-s$!GldR>E;C)89*h^)rWTN3rj_c5IEBd(x{RI4#O@O}%^X!l1izV0Jvul$w2p; zLlTUC-OvSbU*$82_X@c|&4EVN+KP^_Vtn=bP%7Zp9XTe7 zi+`FVfzH-&M&deDt#j*;Kfj9lx5hT}I45RSYyeI+*p?oDU%aPsI(yof9ekYX#FmbSD7b*+^%ie>v#i(xLaorA^DZ-wx&+a^t95<*0p5p-P0{2~&tf&CI#RD=i6Mf4;-yu(G12!>i0Z2`W(Jj@`H~~4B4;+9?Ezee%{A`C{>D&=ozg?+w??(Ro@|Xzk8Ojl56_14C4C_N8exJYNe{(Z14{m$-p=1gAcZVTC ztUM+Iyu@EN*k<%4h>7S=X2rTt9M&7kmuOT5Z>fk8;{p4vLyX8C)1B=eu8GXgffzBz z_*f_jyyhO{5AFPGd`?An@Sc8Ftbaep^*>csw-vu@jk)OG4)l)|B|}?6-#q*@+sh{h zllu>Nrr?(Nn?j|g1oUsSt-zm){;dwhqkq3N{w7H`7#G3oa-G}PwkXjHIkU__ecWIx z8UoA}4~4S()`#fZ8?fsPg@*4Ak ze?p${m;*MtBda#Wpbs0+hd43OU<+lM)`b2(xu!L3Byr-d3Rb+kTqTZIeJx>eeoxQD z%CsQ6Tz_^1^>l+C(uFqL-Q~GhM;mQB@Y{XHII*;k6^n*qFqV&na`^SO&vvbE{Tsg3 zJ-Q&_6@PlL>V28(*GJ0T_f*7!E;pjDthl|dUrgfH+5S4YuJ!4)`s97Ye+F_~hc8$o zb9f+D+_K;}IQe*aJ@_oa^s@<)?g2hS~X&#PuIW)0{wC)yScL8s7U`}<^5 ztK0nFao7E-p#CKI^eMCZ4ik(1Hrfh~Gh)lKKJjbx)v@SE^4+iz&gjdSxTl;GE6%37 zUOl!Pd}h6E7I;T%-4QXD-)Q^mu8pmApn(k!FPFCpnSd|Db=bPXJr}>tHONKcB{Iy5 z8L-vZ0bQvQ{rL+0DcyEmQSZwFths=--ko30h;e}R7VsL|!lQt7lkIPln_5rp`aZd5 zF!={q?_9u&WV=z?Pq2=NS&)Ihp4{5{*bmk4z=3Pfw(GI;wE^r>0 zT;KZl)nChR_GSalEa1`No?8*+Dopc}86m=~p=EF~3`SM&BBRt`KWnsOW#rGLHRvcQ2yC-K}^|mgJ z+V8f%vaHV9Tx$yUb7cRg!q~0_{&Io8Z4dn{)(@YSxH~vOJ{G8-u4T>g zLbOf(7@l1Cb+SnP?`0u~4A&FA;-*9e~d z-Vk;udFYIs&;>}V5&stV))?cuv8%h*wi@q@Dc+!$KMP&Zb_Qo`6;JX53g4mEHE5Gy zR?g19MGM^dATzR)Y%A%&n44@1wL#xi#lO4dI`*q9_WKglojqGQTZ8;Pq{|WD_jFfd zYsW54E7|X@fnO8O@6j4yBW-9mqMe@C8x8-!8SUM72C}T1fVb;QrtSkuCM3XhTuDOl zbFhbhMSe)O)}ZvaR7g8zXWsHEVeeHyXY<49<1*~wCH(5KgDt7wl=SU2zJfh`kq-Wf zkS`51CxM+?Ycq{^Gwe;V=LRnbE?(YBx+f+2rS#dxNWVa~kdiYgGr=| z;Z}@vzn%qM3gvMQusu@PX03(&0O__~+39>~{r7n9UlWoJtO*suCfmQ;;CAxJ2cH+O z>6wj*z_nDu;S6q#O~J3V$)EyA#(F20K46w$jhLy=!x?B3&RAC4lCYNEQlH?GEZP`~ z$C^UXAs3i|y9MapK^EE3v=Dc`kVF)u&&R75Bvl-^O?)0zS#n#GaY@ z1f02UuqC3-WRw|vu-bileWEL_x-C>J?B0K(yv7~3coX&v58GxfND`B<2EX~MFXY9> z*kG*ih>hxsrMk|vZhMBr5@*YHL>Bkj+QTS4?YOF4(-GpiyOaV zWt^A?xW?ZMDV{Pw=7D@O1zX~1Vo!0s0{Y_(uuUM?Hrj^DSGr>stq#S4C(qO;x#CW4 z2+dxgKpz*mllZo9|6_jkYQm5{A(#NzI1@K6T`3)JnU^t-T?~DlM1F{4WZfLyp@$Al z%BUC?x)rjyN|mq@*3cNXuS#X{hj+52N|CZsR@WFJJ*pITM_uNK{e()7Gdcq^K`}E( z-*LB5<(e+Ag?}m;EjdH_K=@=a5`Dq{1JOdswulbS0i9qP=H`uEH{QJt`{~`M)BS91 z>UiNLeZEScKOR4unVmy@p!g%X|dy{!L1QJpci_!(u=UgU79jJfq6oA zjF{z`@V)9y(Y7acO}wi>J9_YlSkPrM#%43pGm)nAI>r<`nh1I$+Ki-=N5jvd#K_Z> zG^TV=k|P$qdyVeLo-4wSJttsCG6OM)FYUU!r4ebeYnnNPxCS_vDbv9| z%lE&-=hLw`KfYs0vP%+8C-T)7;CpmW-bh=B&I6O+|MHG1nM>9;BSe0-%c@{6Q!zWl zT%5)i>Etfnq;SO;XJYTS&K5b7RE*9fLfIK*BB%GIu(T$#Y*yuvrlI|ug_P1m;;{`>fS`B9ej!pU4q z)8dG1K=;+iF0l=C#v*nb`TZwb!aD_a9?qj_ebC^1 zvjDa(od2L#gR`_kQ;I9LkMZW?tdm8*aH9U71vnSua$^5SnkD(;4(P{W=b8ywCfo<+ zMvnc4P@3`c6PN4W#6Qj=5PU$A(HM{*-jsS-6qJdFYvylt(J4qqvl|XoQ9^E`woQhSNG~XCBXHQeD1i{ml0{b{;nDPS_0; znJ(9g;n8s2f#^6Pty45GZBG79kNPuq2JHQn zjE-%vlYb!t({>fHJy?Ir_#xO$VoucGbqG*P z>T;bUDBVW=2L3aq`lS_OmC_&jBW?ND{)E#yIr`I%{>(#vp20nm$I%xVVw%5(`sqFY zUaq)XNa;}s(uREW%OGg>OAx>GE`eDo4XpmNROqwKt72AO`n0`e5&EHqp8f+GPuSFP zQ~mclc22>o=w+33Hb;2jdtYp$ynOHTZP#J*$3ixq!pZZHTiUwaL24;cBb4bDb9H;+Zs;O9fhN5+sP)G#_=7T8B+{8f}O#gH$~0m`fxvB zZ#{)C*w808^|Be?i zo#SIPe<=N$-}gpfgR_MhTD3HsZ;fV@$}s_^Eu4S&U-LVVpXMQ36X9hgxQDM?&1?(z z19quBtyuH=ahH~!3nH|_2+y}E7pGiO^(%W+crNK>?6d|-KuaY1hjxYDrFd{Dh@n@D zZ~O2qKm5(Je{9!S_*>q3#I-~01)5XLW#u;Qd%2dLH7Dw-(LVF(({>j2KU43;pPUHu z6s5pq(4A}IwfY^7D#`FiUInjLGKeFk=9vtM0Qnc|Z-GQ@*7)G}40hvcUfIGUFDrZm zo5pF)g#y_&9%wG)CEJVoI*{j8GlOsZj}qn+?oGW+hO$i3Mr9b^M_xJnGK9zIeu;^d zNUAmPZyB*iXXaDBifBFsU!g1vM8}iz0)DjDvq92emiIjwZioL7GoRK2_-nVbCCcK< zx<-%O&#DLSFRAMmoE~1QzL&;=;xtRSLKB@KXZZCR-2YD20Dr8UZQIqzm&tk^-Wa{Z z%lHNCPkvb|!E;|VWE$|yvc^FD1){U}b8(MzZP>P!=01n=3Y<;R{coAjWK#(Jo@>71 z)4b`45js2P8um0lCG4pj!a3VSR#8mdW_cWqHD$lq8;0a^+n(KOFWZVNP+w z9XJ;>mr}G_+W+(QtNyDs~c$WD%WBqD%p#BozLF{Y03F*(HY35j-U04{| zU!`RFSi<#KY*>J^CTUmqnS8Xc_)^9&D$$7R8z2ii#7AHK+^wtSI8~ zj`?p%7R+A72`1$z?qoQwJKhNP+B~2O;H44wf^dfo^blOeoNfg@c9a|}DO|)@OTTec z#Ui$%W6kAJ4szRDfQcEAPK=zCSgsw*wWyFs$qQjTa)K$1`gP?PW2HVhY5)(?&P#zh zYqT#)o|{nlq!ZK^+^8=kh`k7wH7pTvIG z>47m6&b_5Q%t&`dH*g^bzfT)vFHvlF_<0QX<3Y4XG{%@IUOVn{fCsASH_*V_HGo+_ zZ15<4dfxkg$4?h;Vcur;Omk z{~@znz`bG2SsFXc!?s;Pb6Md+@(VKTh3sN^0Js5M8S|;nz$x+Usea$}f9Q8wwBH0@ zf}k&ANXLRc(|GdW*JDQ+>x&Ih+C7nHuUHU~)!)JIWEVhfoyT0#3-GfC*nR`wDrp#x zbq{oT*T3K8rF!oMj4#$IdlY-R_LE)~` zywN#w5cBZ}XxKm2{=d5Uy`E!u9~${@Q`q+k_N@%=*zO9}miaN~?~IPuHzg|ABnmG3 zB8im)oiLz@0PI7$5zku{+;?Ahb(iN5=72Q#;(hd6E%|~8?!S-SM(}O5-33??=i~lv znO9Ez(f7ko0LpX>414tTtUn+Wo@NB6m&!^T_iI7hg&ORS*U^1nVt{XPSql$A;+?{4 zngBb{WiO9x##uhmofABk;ADZfG{PJ2!#%sm7<_&t*E03qRRh0}Sc8K2EdgWJvno&@ zB)&MDXXlW9Et=*}<=LxrxWjey>4ngDDK7*aCN;%ZE=y_BfbN`_kAx4BF=>uEAAizr zUGoO#7(Nz$wl6L}d8={);E zq>WSkI-6%#S4HMOc%i)!bdkmTl)b|a6Sb9M&9)~r{EpijkdP1L{dAv<`bBU_gxdRW z484_R2d)gzX{{$(En_#$2k(r9-!H}G-KH&*@TG*c{5a|=4E{$Lo&fO4mUFbWz`jb| zw!ND8#DRl3=<^2whbiwpiIwb?7$L506FvFtw!Z`f)7tQRY1?Ob|118fZ(8&vJU;is z$ayqSw;sMvsIIpF!$EfGbF8k~NSH;CTUQdhSJ94L#}z z()4@==>|NHB27;x(mebU_>iXOcKVLzJMV@ydNxvioJ)06 zemsvO%?OgVeMs|wZ$&r_IFM$L{!=*3wmpNi1L+E+52BnCX?haQ1w6MSP0zVV2k_jA zG(E#ME|AAIAvz!&6-*wfP^v{4RWle6|ceEGBm)GY54YkO>aJ-cRZ>2H3(R_K@_aei^~PgJ zzr4EZ4f5I5umV0(U<<)PW}*Ail$X75qQ*JQ9rNKE>pSIT^HR%-Hr}jfprb8;>_+sH zGsIZ`{F6ZaWxykRoM%T|M(ZDuCioo3r-k`7tqru-C7)$-Dv$lN9`v3ttk0j4)v@oe z&>BBB2>y@qpHlg+^XywIqrPgu_o>Vp=$GQ5UwV5;pU$q{UG>}R`h3l$-BqkjuYDDK z=^Wu1^8Yg>cg}u~=DM+V^ik+yNSCk~-)Szgmn8O7f!#YtNbO-xcZcJiz1({&h3b0| zu|f9%k7S$63@mMFMBRwqtepmg@t>}%&wX=aU4S&iN7t|Mmt}KkPgh>%Rts2y+_bL4vp%L-S z8HN?u)>A&c+X0?Kyqm-LYS6|E@Y$(0CALQG4D#12ykc(D{X=hdJ7}nQFxOIqaXGp& zGA_b5dG_f@`=V*)yF7aa((gpm{P%hGB&6SprX7=cb~)0&LHZiei7?HsIGbf%%VRxP zs;)Z(U0DQXCJeI#a@%E|ZI#3K)+g{MTVRm8nDVt_ng-mTKj-y!WB-P;1Dt>C_WpA@ zr=RWA8(G+8K{h|*4d3x48URmiVg=2(8sFps_yhD56&1Nwf<;{>*|-HXLu;I( zUR6(_5px0SxKmK|(3(d+KWjk~4ab+Z*w1BJ4dtYtvDu2g6RNBz$CW!r!_RYl2d-ef zb{L-+Nx=O5F=*|Hn?t_@U$#hk_4ohl@5g@$o?zJ>{at~zT2A?V`ulg|e@$(wKW)o& z+2O#mZ6z`DUX^1V$K7miks$9W^vl0cf6TdeQ0VN3yEe8h2c0XVgIl>*Nc{}%9+Lc%Uo4fd(S0U| zc}RTd9OR$v(RzjcY4$Ua%ctO?zBew<43Dw$v#0IFcqjbq<0Tu}^(8%0tOvLw-BZBK zdDMwHLVT*$9H=MQ*ey~!&36sjp>M@#Ke#2^8m24W(Z*hp*jdnV1OBC$cRIb)H3YwT zVV(>Fn(cuGH9I9I|fO%3%4C$c2*z1Y zXIgNMx03mQZ#mQZNu6XB9Pj9Ario_MMCoaixctl|jGyG^b}m zvOY;jFBqQ+4(h``X=p#hmNCT)WN6ZV=mq^#4D38F zEQa4=V+9V+-iM5cCCK+OE8}>hGKn{~a)3Pxb0Nvk^dz0<?I5t}nM7{P0`DqSj<1 zWB&wp=f;)B0p{W(V;p!vg3ysN19q(CLq_oxLFN(-<*j53@a)O%v&O~c1FZgzac1$F zG3G?_IJHe>s9nVZW+lPkzcjfr5$7qA3fD+N6~!`wzW&O=oxer=WUNbe;wNV42-t7c ztr%-2xaQ!8w0B!pk!g{9ThPk3savHw2DaV@4hGj83V&;=&9u@t$R4i|eTMV&GUHR< zXGhCE2pO0u_T5^bXFZ^;BJy2;^TI;4&Hx>;)8O|tdUAM9d0B8)VvpOn2i}T* zJ=+W)1MvCd^BR#~inu*pkRMgnx86>@y7a%;@<>}1mStmq7R2 zyR7UOckGpIhLX;slB0*VlI&?%2Hghyf>xM2S+jDF4(GsXA+?1SPBlw)UE3A-){Zml zn7-$|XZmt27y20M&bmN7(fPp-rrAf3ZjGh`7pB=400-oM20C}#vtz>X;6sBxm$%I26X7-R7X~%>Hq(%f_I_cQ4H~=)xCDLMlg_egwn1W7oz<)H%|pBz zvA`F-#? zfjFyp(w;aI_Q1}P*y6t7`+yw}tYU++ zKgzK-3i~{P=C3|f;|zuT$Yd|ObDU|oXPflgJ6?8K*0^ls9dE^E=rUnXoYrfdFV`(l zGJnhdt`U0V62x(r^jYtZ>x)yeru0??V7R;DtV`aPoRQhP&$DSkavBrJXeKzxZx5@> z?O_lrTykc=HvqW~zINu*K29p&H`MdI&pN*e{rtKlP|^fG)`)k)W1!@zTUEGs{+XF@ zu+`?oUQ7zV8q4$6mKj%YuJV;Km($MKY0YQ&ZyCB%N_+G)!7zVvmlXQLWfz{5wlf?0 zq#rZyw|lQbMk|xd?UrI6Tp(aB>ZN0B1I{?$XQ!C(?CbKXaAso{k~5$1!I!EfP)}pU z_@>*lPC=$Nxxap$lA;^ocZC;P^Y_vSThJ2jb zY%I=Nx}ZPjK-=noblVwSuJu;Xdbo{>>2|ueLj6vG{J9u=h^KUy>uKCo3z;?>?k7<` z0X_?TyPkXL^5k?gRgzDwJ=2RA%1H+ zaK)k?sp9!wkB$u#DxUMrK{+SNkk3Oio|M;dbh>>W&VbUOLnx_Ekj{a8v1vA2T%b>L zW$+0~4mJq|rwv~e_@u6m1?`uh7b^V4&S3o?Ti)d2iX9KJ;KAweW%32;@;x%mULch0 zuO?fa<*ISX+U4-mcEEcVkNcm?nQ_vAUx5DMzfhKWe1)Bb3{7%&>-WKWMHC+9_;l>W zVdE2&nu1mTkag*d_)jOZtgrRvTH=7q*}x^8^@RISGu=*S#Dvcb;FJ6;RiWKc{&M{e z$bh1>vx))#WZ*9@3A_;gYrS#s6;10lJMy32VbJF=GwjVmyxLU!ra?@U#?PIFG#=Sa zxpv5i*po2!d)KfZbLDK{OZ3%w9cw)DUxI(Qx!m2dInsON((r9CXm*A1y96N z8;`>|PU=z)=jtzbudGUI?eOW;8J0onR)|=dgE6`YOshi!ir1<4anCS-L{j$sxANCcvDkn0rkM zcnR(^fcZ=Kh>;k zBQ`c*WzPJk_f6lN^dyWIjVB|fZo}GXAC?Sv|BM+vsQD*4ptaR0`8-cHH6=p%Kw00GvEz(zT$>6tqSm|6ZHGoe?SI_ z$kgAT%(N5^XIkiYWvhA{$&BZYf|uZ)An`^HJg1v?;?7Brmm79^o#0JaUo0}bKgB)u z%FAl*7h!n>a+$I$t%=S``caqs^OtM>{mi5Y>(bQT0J>s~JIO-I7M3SJS^7eT7an5m zlCTds8F&!ehf_Ap3)*8OVW0KZ@<2V|j2W43zXExO`tJDX*&4tD{(FGVqF+RvmQOGT zl#k?vaYFh35GR;4|>;LJ!@t@wQt%hAV(?WemP(SVAG}tSV3?;>rY*45!?N2jc zch+EIv6rKC9M3BuXSO*cPR6P4=zC@;)4Cn?(7tcecNvy9Cvz;sUjsWP>l(mY7jI#} z$0ZqlpTx4cPhu&GwyA7jwuR{d{Yt=mH#5Ad9V+-%tjM$; zlz7Z4j1437n9I;dEy|2W%Q!Cb_AeiXE(+(Mhj#)-)WerK9%@4VKj zHVNp|-`C|ydDPtV9)8=i@dNu{KhCKdOQ2tW)VAhIm-k)#p1$*aJC%L$lMn3caQ>#+ zr0hwxnR|{PFKEhsba|I|=vkhaJzq# zwDlXhJP)9(73C}_SK8d=tsCg_PDlBM4PD;VsDrVZdkDU%GIsQZVDg>m^2WV?qV65c z)hW8>1V%|T^hd}cQ*&&^nLyoZ;XIflm|u{2CYVNb5AET8aqdJN{IVRR^G=#K4CW2# ztN;0Y@)^wYr~bYCCMH~dC(4t}pqyX=eoMel{`Avecnwi~^sGGH;-ktjSI&9|Ess@5;av^pdy)%$+<&9NY7*@=4Q zGi6T(J%c4ZDtcZp_t+4B{YtbR(hCW|?W2gHPB?jcAk(_j1R2Jn>``J)j0uk`Rppsh zoHKj2((jA1?B6zO?XT{OF9Dm{Mqu=FN&e53# z#sX_>3v)kf)eDYt@`=b|o)^X!#9e8){GqI`aGc@GTYT6*Ie7LP+8>#I3f!aIAIYy7 z^3q*i!a1`fr60@0qKP4BXJ5`3%9y<3> z!w)HoC&`NWcqg9w_QFhSE#B$3-!pH;fgd4W2RjxAAA~885wfZ=w}IEl-ky(~Q(k(m zdH%N<*13R>=}qm?f{r$QH(8&wG!VhzU-_^;H6^Ogx$rGwgTZ!WlYtriE&B3wjN?_d zO4)OnXL=kQ3q5Y5O|q+?HKkJ7Bl8b?ebE1N#$m6l7xMspAYMm)Q<-DtGUCN$;Bh5k zJ+$VbG+v*+J20*J_8T-WNZ)=S9E(X+rZi~;pUbS(+)HJ00Nw)Z zc4^)`jqz6AY(H>5eCB7fsi8wr`(u^=H~l1ZeObW&Z(1kA`a$N?l5LcSflg8hJ@d^4 znHIFwb>07Xc&-}Yugc%I+w)V@?=ZH%LC+3f`x{2w=k)nFKec->;0*uH*0vu|V4q9l zPWd<^KMKCy2D?Xzv)tLomhiS``ZFzhKjWhB(pu*Mdb)a@Zw$ab0J=k4xSU@<%J5z@ z)2k2Ts;Dip<`551excsRR(isI^TO*^FQYUVl`hhwX`n}Yro>r7`MAc$(MVmjqqN5$ zof@UtrR@iBMu+tjF`e*~^wySb`8LP08RM&r;@0s6Hf7>u*gs3R)M2J}nvlN2m!5u( zahmf057VcdIM^$(XfQ`ho_b4DIjg&EnwbO0hgnZcd*x41C;E9p^ z-Qj%ta6Vr&ALd6G9tHZrz^+{WEt4Uys!|>tWbB6#SMCp}heaELf#lq?UW?`H(<5;S zrW{N51mPp_G25bnY|L5C!hgb9Z%-MlzyV7J^tGwQ3B}x3d$k?CT!1rnX%l>`x@_*8 zJ8!_2L%D3}SQ_+LkXP+-kejDB!N&T`(y=AAY5pI@WnZJQCz(wU&U)G*H{+D(wB*7^ zURyo;aZX>C)^WjjjIlUINH2U7@|za(K*R5cpHfw!W9{-DqTv^<&c1=G+173y{Hda? zKSAEO9pg|7Tc@mA4r|GN4?EJLb@s9W&G~dO4fBg)6o=cU-_dTz>5e{)C0$hb&w3>| zXa48>^R`UZ@4BQf%feZ3%=xok9`$L2{TS13^DX$6D>T@y@bgYXhHIm^xMfp%&OM2_IqaBAJlz z+ie_R+lE+zh0y6qVgJt6F29fU?eVg;En1#v3cib3euqtp@ds}282}IB`T7$n&`^f6e>4%#7b!`H#whOWh*Cp~mlo*F~T+(%0leUz4#tST6@J z(@2;F`@mBPo`Yp76Vdt)^*@jwdJ*e$DaM7`c=_we`ZDN?shneiw^N%9(KZ!=dgXNF zL%SYoE5|;$(t&SCS0Zh&uK4=2lD^{`z0=bJ|FX279UJe?zmsS>O8;?y*#R5Mt%$V- zy-8g|)kft(q&FdLMS2@Ei zbN21^Wm>Wx&xypD!5*Lb>x_5DGWv|M>;}iqT>MKBuW|r1LwiUC_EYx>xjlvj9*_JR zz2+U*tDOk1q44LA`7sZ^=E!~|uqvx1O#e8yNVTMOlE13wSk|N|FL*W+x-Zq%-}U5- z$?U;Zx(n>N%!zBLBV%kyj|pXYKC9(QAia5Km^R^)1M#tbF2FA?wR4NZ_9C8S>q0UE z{KikP7arBN`q+<)n}yI0ZPe9VV-nKKr9dVjZpbNBOziFu~St1M^79RA^Zr`r8|+y6tm zM($&&&|>?cT_d&om@O&XuJMO1!!6jboPc5fw~mPOe)Ao9kO;g`Msg@@8^SlEy-(A;H3bv=`i+Av5-&aKZdyh znXcE@<(UhaobrUp=yifKT5?p(6>)f#7Kj{PeC5 zw0ouaoiQ|wh2=1zCoEI_0ec4t;vI%%TeQ!E7D3N-!ecpBd3YU{Ok_gF%JR!5{*2g% zL~r|GQ~X)pw`I3LW}ZtjDd5ME zTrG6bSnufm#9r{Cd6)|sr<6S_&}Y&W2m8A`d;6Rz%eG^@k!CF^oy2?PShJOvorP~v zKEBnKg>qXljx)=1vmeLz@M74;UlgoA7-e z(%r~wz?1B$roLJ6Egfg<^li;Qm05(}xn=1S^t*mhrt30d0Uj>z@|2T2zKUU_@Pj9< z<~o4~kEVRav#R&{ToRMdbvx*h#T_Vuo8Xh8dxE*@uhZX4CZJ>QS zpK0~&>a7y6=WTurV~snHKmQxnoti*B(Gug+*`G&xUNp`3>Fg}@Q*b04rXguycQg6E zrn97upl~1UA=`QIcF09!6L$#jbk7a*Abg&=1$C*SbvgVx`^DCOjD5P$XnO|ZUMh4| zmJSl`RbvH76Wt$C3YFNqq4NjN@T>NuAWF8HXGO2ONdpa6)^t@gX%7LosP}ewUIrjLj4FRy-f6+ur9K# z3k=lWpQ>YnYTUgf`hEV3mus$K>{vd_KCSFYcA#ASEW*K@n&#CM zp5H;9SQ@|k)h6rlK%EwNCS4Ng2TWMYoEZN(pd}U3@nJy)jA?9nERLH>)ogkB3j5 z>BJMU$5)P|j@<<~Xg}`5eAP~7Sk?p1IP`^JbsRxokY=N4;i%4@cO%F8^0)Bo-I8NX z0{j`^J6YfnrV?$59(hT=4xm3-8z<|F6*Yl4 zq>%l?HZbK`0cHLBE(!W`bpky1G0>$TnF!W0ry2N4$yjuvp2{%|SX+4qlZAQ{;9n)c z-*s9AIVh$MI_WbXd1a9ANM4shkI7=r35ePI)b|ZH*z=f zNzSK*5G#5l4)`ktPr8>sxHCQA*q$rsp8jLgWPO&f1NGQ##H;8$EX$%^nH6Am&YI7e z0z7-#S7tDi4P*jvnia@y_SKxI&!289OGo~9pl1^hHyHa^oTUNgK-RXmgdZy#gvdT4 z3%t{exC2QjtLC#?R&Q|Z1iY1b)hFr$$diD%aUT9Ki}9rRVU!2?J%j_cj4j6b)kZnw z#u(7+6F&YJ1A7o9>V%KUN~hk@NBUwr!2le{QHRD6@#nSR8paf3!aztU5FCZ`U0+0a@9Q=H8vOYnG*j5yy&f^OrZ3`!Lc6WK8j`rg; zN6gsg7l9Yiy+86JnY1NP&*< zfAvAkk1^#o2JMnw?TUuGBFTcf(f&LGn1Yr|wc<$>MU8#La}D;;LCUtr2pyhrhSAn1Ricxy)3W&|;p!ec~m zu%pk`P&or&fX$cs7b{4I!`m^Y@L3nJYnr|-BYZZ%eDxppe~07kC>(16hX!z%qHr7n z9M38DrW9iRlNeLH$I-_5fbWe@;8#&`S+BVP`BL~xO3!GtJmM>Q3Wiu$a24B{bXl*q z5*&Jlq4~?=f2EHx5$=i32nOcpy?1ZrY}$gS;UP7@&GeQADP~?oQfDcrB=A6&@V}I6K zd)=RPd)9MXPMXJLYik4MSQ2D+XrI*Oh(@Aw(417w=N5kVlZn_lV7=DQ26FSK+3xVO zkR$&)=&?WsFW*D{9WyI5z!%A$90%FICeX7y_eGqI;1ly=vZ62Jg*+7`cJkF$E}#Wp zEWvire>f=Rdyw|JZIA_QU^UNyMmh_7#kBAp{xqyd(-hgf*qX^%UOqnI{LUU*GxG5Q zw*%pe2v0|QyFM#$m-c{vg?*;$!PwbQ1pcA^A-h74ZM*!8+wfk*>0u_jvX8igTF`R+ zLyrzSjqmrYG}7Jz7%;ibDum>eIgoXy@b7X07BlE=+j>Zs=Q#)FU%3kZdDY?7TYE?c z=#ZllcXiczeSq3wyraN97jFzL+coTb2yYNC`fjazsRZ2QllA~Rt`FP^KX@Yk8|WWs z$xo8Iy&bgYJm?KEcgG^Vk*RS-guk)_qRjV z_R9_K)^kzk%pYMKO04e2936O5prsDBA8NZN;@lE!KO|sGy@lYRB8?}fV8MHzr#*g#Io0g62Zr-oMe9Ok%%8rj!j#4hh8u`hu;6B{{Tt{UjLnbx? zxCHWB#ew38a~8FA)QWSLHBdi0*gGW>Mw8x*&5=LR=l=1iUe+3_EMXHR%UmJAx*UoyijRPg^zhk^Yvt!BNd;dy1@mn%<1@9dhCF7TN3@+^YHPbVySl`~L&w|8}dI-kSoe zk~5PnXgA(2A-77zn_ejY2<%g&p+Ai|5zAq$c?14YpQhaxYga4U_a^2x_0I}eV2{LG z@62t>;Vnk7rOwm?86em@)`I7Ho!tB%+M??&Kz|5$6yD1L9wh-LO`soKm$+fwnZldX z$re-yX(!9sHdzkR{XdnX{k|MiG5DtI!tM@~*Az4X4_CW?{m9Ge=DYT}4Y;#NXlDw( zbSw6uaGU=LmG?ETn5xW)8K7OJ4Q&1C7P+$y@&He8*z;x;0Ph>6u@CCgLm+s|9b*LF<2qInAR#^w8T+hC1TqtL0X}(}?~2 z2_HMr>8~$OTxYV3Ba<| zZz}?x1DS&ZD2MX4BYj(S%-;(CX{?uAcP#(kT(NpHQCAt-Kty?~kVk17;?quZMkChSWV@0O zmx=SA+B{iS^IgAiH`L$Hxv*DgvF&CDd6Em(Z^p z--0@dd%pia5C66O+Hsd$w4$HgzV7s}ranQu&iCT!yg4%=k9BBMX4nMSFzY_(fyU+^ z@RRaUyhmt*E+3E20T^LFRxufG?ZVZ_NMFb+FyW)WfPSNA*W8|LpSo8)u7bUun+&hA z=faucBIMQdYVofye^E*yr|Hp*vkzPRxoPmr@Z-M*duZB-WG=)$4E=ZW&8bBkwU_no z@h_oteHtbIT%;rU?8O;{93P^8*8I_)ZN9DYn&r#HtN@Qa@$2ENdbOCXyb)0Kp)^N$ zbYc_r@hIqNYUi+%c#?YTA1>_0YPrpyQ%*924^$^vRF;bshzGt-ci9Bc04bdXa%Hq1 zkv_ZuY1?k)=CjI0HT3Uytg?jUVwY4xRt)DIQdF?85FlJGrAP?SUKK*Uc(-Pp^n>Rv zKD|)0dv3kHtj(VaSpmMFB}%y42-3|7JAlhQP;Du5__O;Qeja?)0-NA33=4i+ncx?X z3;tYue^mW}X$v%g=cG2w%QnBZxXn*_y>~~PsYQ?n1WwolJwy-W4*RfId#@aD=R9nH zU6Ti@S0H~>Y)dhr?XJ_1BdlibxjzZ0ncUn!Zt6W@_d>X72zPCqS@F(}fI8)~XWY-i z&usbtw@_v2grD1nv3K2AGZU~<14bU4)6;KnhyB)ee{k*B&MbRc!0?w&x{ost?yQN3 zGa&9Y#QhNSEMrw#V4GaAg5pI{)sV5N-9P>PcK>sT$GmfIlQ+iVT&f1jM`@o$Tq4p? z9;3)LP+gSnN&Kh0%6}L4&-C6Y>0Kh*FTRq0okOVf}En>1AK4U`vcqOv&THHz8>9l~h{n-P~)Na@N~7+u{%g!DCMKYN0HiqrTv4e?aQi^wCCxBC-5?nGPF?ka>`VsPc`flfbU{h`CbHJrge zJ%uqR9*2K{z0;rE2bpRKdZPHRv$p%Lhm7?Zgl8c<0M`Jw3jYPTFCu&c+;pka|8J;A z>x8T}=F$wf$$;fdz~Fzpk9^#_&tH3cr#~D1_f!KfPKVz(*y(?lz4ua%qtm|-XLt(! zrNT`^_y-?!`ZExoiE!4&PX8RVA;`b{a-zM{KMnqnI{4dbi;nqcg^&4{qR&5&kNIs4 zh6)$xE@^Pt2bllhrz-Ee!X1)&DPZSi@}IZ=Nsu-CMJd%wbc-g$wf)86P6Azr$wF5W(K=iOZVB}9fVY(3B z?c2{LeEWmzta}^DT?KnUe+9jw1wAQ2n zw)v!JJ~ofL*`erKAv{?w|IpbP@(N)kl_$ggSj0y3OVGhUqoDgRyJA^I`pEJM&&oYm zlk;S0j@HT|#rSvNl;>rFGwr>P%X?lX_kbD2rA#K~;*)_%iRyPaycy|xm zwC z%s<*?@_7D((vdAD3H4x)2CW#f<*+}WEJ7D1?DL;In^isv-FjN*-0@fZU(0zy*IAO~ zV&!cU6PwEKHIx%fjW{1S#M^uk^fR(4NbPR_>l)I_6`Ic*zcooIt>DF(t*9$Y)};#~ z=Q4zv(@dT=w4>|S)XrF4;BOp<4L#5dcA~ELP)}k>7HEY;$8PtLtZEo^NDl4gpoiCv zHVXOrsvn^~vGS=B23siv-#|}WgIDcg*t>DobK?SRxR9*+*O0%X^>Ou{7>uc%`n%V- z1=t-TSydhGt0X@~dk5+H9RQ4Zs;f^QIEi&cx@u~yA$nsv8~-OB@V>wx>w9(7`@(9p zh2Xw;QPB8}qef8X7w`%#`r-XNy6FwnNph%EXWHGS8hZOF1#;JF+_w@@-p~G7@9+IX zT&8^i?(m-Rw11SKzmLQIAIZdVMd<(?VW}#`LD#$1ObY zKA-D+fM78&7B~cX`>yU)Z5_)o1_G@SQF3!GYt8m>+o5fRZHKn@w;f8pC+e&$YCE(g z*mlUX>T9PFbv9ME;j91*^Zg6*AA}7#@s51L4=WKj5N%V+ee)heg^_Gi;GcKO|0=Z0 z7|E@%pEZ6be*Vkwr6q=jm9U z0uYj!_`JiamU!A9pPy2O9XuZ%xckZ&8p1FW+_OR>uB#U!8N5*cuorn)q1 zvY`_Ar&hKKcz4oZg1?#8F6K1&U;TRQ&3en7mTDWTp!(Paq2}((vAXP7dxyc7UV{4k zD#1PrbS)*#140ee8G`;_8S=4E2jr@vN`E{dNjd8#+dB_sDE%yy+})}}+ybNnO&_*C zn0qpf5#_7#_D47Ks|HXX`T(8~^k1<5f0j9PXfoZ8?;XMVuB+yyBsV)MTmr3A_&Inr zQXH0^KFMvvJjQ%B=mAq&Qwtj*sA}I??Tie%fX;{^kIU>BT{hN11v1$qT`3*xYgPKiIhbHqvQ;tF7gEeQD7^uSHqv`>k$0T)YW((1Lpj{i|Fk&S!FK>8r@2#aMe_ zBarxWa}ejT+uRX^7gXUsUBcBF@sB~qiW4=y#8Jr%yKx<}zto$((DBU#4T|2ErGLZ+ znnh_(TivyY8^bwaLVs=?dfuJ38h`9pgUw&KG(*d5&y(LWLYVb`CF&sm-InkICT^?Nig#C28-t&7#>2>e8u4oM$AEoBDGU58*wWiHo7!;Riv9#! zUp&p3QGazK4-%yzThl4R4SQ~pS>#Rgt|tWB4#?iR@Z zxmLpV9^kkw-X2pNhKVORQxVes8y2p@CIp=8% zKZk9d$#TB6y1N}Mq?2oo!ZpL?*0uPIaEmZ!P8PNJIJ~*X6$D%Lqnx<__OUAa$bJIk zUkf7llH6tx`E(J|L&3hSFP?(`WK~0Tlj`l4|nPD z?J?OE!msr^=hOh#0&c?^G~l(S)uaa0HH$kK_FbC|HVq)luf2buS1JBbYD@w zIB0uWJ-)cZ7FM@X_*X|`VF}?x;Gp#HrC#sL$&kCkd~Ur?0{d$Ar0`sKs3bFzqmcC{6IAIkOA$69$y!=SMQorQ;vGl zPH_#H7|%$NP-k#4_myGV!^J0zHldE>ZOBhDJ=R_O_P>F-Qu*-tKlS}Xnj8Je`9JC3 z;pV2H4cryzK4X95uGa0>O3CTmId63t@VqXG&rsSpA=ChG-4y(;Za?YvMB$!;+l}*3ZvP)nP!UAC<1Syu#sdUAS+FKGx+16<&z&YeEEGVm%CI16KWgaw3$ znW>*!xSF(FK9|E@oVzH`|KVu#pEfs=vHmEHCu(zd-2?o_iuT|>5X4#xARX|82437! zO>NT>&uW1V@}`o2vqj0rPTCaPL&Rt9c}wX>IoU!cf6q#+g&eh|E8J+$1|4*7h}n~n zFKM|)k)`#Z{C@y97teEso2?VqR1ffm*SBU>Y{i`Cwy2c5cOvXB?_4vp;z9IX7-S9Y zEY%MBo&Xy*ST~UEvFZbSD0bJEcZc?$o(RFVHyw(wSDSk+;1#Ru+JFpO6Jw)U4kYz9`dMi&M!QIvPw{vOR-(4x-^&ITxD~UoxsFI z{aLmZb1wX;{~P3CVc;|1ZAq|w@1Z+sA9FW|(*>zVUrh9YH2G%@OVDrPZKeOUvvv{g zVKsyk6{IVAA6~jM9pjAYkEaJ1bR*I+uc$t@GqvW{I-6SVNv#{Kj4JoI17okE&%zjDm$WbjA+m5x4a=DzQ`Lpr=rOMd25ImA@eR3fu>U|Q24W-LssGb zxB+duCq8GqXrKNeQw?`Yg}s^h~4nKm_9fP znuplvTM*@pdbFz@_8WP*vGC0;@phnF1x`~g_h(747 zdVgj}@6U#OgaALKGlo+Ar;+A4%`XqpU32y*>9?`ECX_{Mn>*?AX(aPF)%{#TceP5? z)EQ4vnmPB*bAj#v-dvH`*Ggs0=}Ywow~aVwo%Z?XAg|Jn@M2#H`bq8dT(G&%jbxR( zw#4qJ1h2IF=G5q6V_pbzmyCeT(`#-I+;H*txStxj=zI_`mQ)UNsTw%MXUOQ|XV76_ z!`%|XH;l#7-idWReOd5k;dnasc}bX@A4A+AyZH9Zick063BP529g5@qe#j-MM0JVqA65R77S)312D8?vg^tKj zAP?_s5**oOn|lxLdyOP>F5?Y`BcNxvh5}{LcF;MvE(^}v?$yj)Hg*`{)Gpqd5@^@> zcpLU;f~DEI$j5pX`GUw7%aht=!2P!q^Ia)3C%S<8HW~K`{(CU~WaB>)fxP~dve_Eq zM_{d6Q+#C?Q6F$j4*jID4Mz|Cmg;|l))D5P=L~cJ-~GN^+OsGx7kWV1xAbRJn|T)_ zT^qJE2wF1A35MG{Y+JdSkEBNX$068Vg8cP$vgSXouDn?|Gn`QW4Ri@uSXW1KVPtFf z^M@X*&4!%!=fl(L*~)EW2`6>6#J6YtTL0MYfEs$L4IJhW`CWOsou^mMtRR1qW%~S^ zuou6fdZX(#{}AXW9mC^2`G#Om zgFy0B|HX7AoSX}MOKLHre;n4DcQes_P{t`$gK{T}uZzFPjrQ74u#aw2F@l@v>;!!k3krUZV_h=cL891;)jh$LqF_Al5*+8tomar4wdQ+3|D&_eE44J_BA>Y* z{M(Rv{F|ul1@hmxls6R!(s>5@qbOL zO<``jM`A2LxW~^R*U^T$O(+L?lKFHly6(E-90slu0e%iyH1Kku6!^>TBcSr2)=wa45USaUpR4WNOQRwADGP=AQe@rQ%I zDe(PVtFbCh$*emNXe$l&BkNiP4?lR${c+gzS7hP^Y z6h#?o*oqf=NcL1+*H~GR+=R2qB%7=x7X$fXu~Bj+n^LSRe;f<@52AhEv&V4Gbvqgp zJdn*}<(E+o2iciBp;MTF`ypR&v#%_wpZg48@0R!DetW>j!^V$y7r$Rb8ZGR=5Nyt8 zawXhGHloF+v8M*Y6HWUwtJr3jt+~$P^6V-`+kv+#u$XqG`Je{rnEXU(6n3j-MM}*a zcmkPlyYEh@pz`vtb0woa%fbnUr2`3uC4&iu8zTvZ9ng{G(Ed^6Q-OB50B}ke1aF4i z2y@?q_%Zk?o)2wnsfg!L6x|HDSUL(9OnM(gLv1#eU6PpOf zC!E)N`rlVAzY}uSpk3(i$in^NU>D)Gvn{O)Q^eZpeU%pjy_Y+2E~a;F#JFRha5o2E z_4i(h{i{T{ckERqo;^|)_yNMM%bors_ZceM;eP@=@w+0O{@$@zdOE|H1bo!uU6?I0 zcB3_g^i$cbp%lM>|1;rFfuH`(kH@7W{Hwm16;T;=MPudgSf6Wk!9gZHIM$8z);rpH z=;6vvzXta)YHQ2=WdSw5v)~c%A6)A;Y=@oXYRRqG!v6R+_e_L!mf$_lZXR(G90K5f z@Vy89rk?NX(4!5RID5RPYqF0YZqYW7tajGh&$xTPj$(J5uVg#Q#zc(j|~67LUpf2R-pHM0r-C+p(kWu3TpvMg`CG&TNjo!}b> zQ@m6D-FWASQ@*#;w*_{y}n4hqVuxdHx z2V3{h*o>lA)HciX1$fVVMEuEb)V|y%ORDVIRa-Nof_OKZE0Ze%xrw~|8Nsd zk&1Ci?3pH1ti!)bw#&J!?G_dCh(GylQULRtZ1?JpAO7{}M>D}!f3TW6rXMFBD#P3E z8WDQt`Qcm|f7nz|=7Bm0nLGTSR`jXA>qMiyG;#jtnb3=x4w_|fO20TU&8Lk@=9AEO zh)(&x7I+yun-$=&Hu@&l0Ol(%Mytys-gzdpX%f~yhmHopB!4YrDsbOjP%te;i1=!0 z9df&U2T5O|`Qp)osb~-R`3t^-&?opZ0y&60kqc<#*ngYU_8G}Mkj~@V7iU&b{x=@< z;SG{Dziz{XbCI~r$3DpN??8RT2PQc@Zirp-Rz#iG(LLhte2w(q+RJRFmaAtz+uS{6 z-3S#U&Oxm4pJ8tyotGqxYtly}&ft_Z$3KG14W*Mjz6(JQWHoOQIPBeY?=f=OtXn4i zfo=!UK%ZG`H%frVl`t zXd=K51>o3>jb_x6{S{YE!NN{EZ>WU30k)!4n0wq`v3H`6WUJ1zBdW@PGN~EVHAWD!|o*f2!-N7gnK7xZgs~UzgEAF#AOBK7f2m zJNpXVBK#iE+~`iQ1aR@*{)*ZYZf@YW;C>2!!2+-4urh}r4}!9^@^nEjt`=CNz4n*L z`>)cUnV8sg=F{Yg1xU{@E>Blp2~d0fJod*!Fo>nx$+ht@@)Q@k)595o?=UF_%)LnlO_1ZQ5bF)3v}=7A?l{K{v1x-X=;UDbJp zTaZ5g;VVvg_cQxPCZ5?Jft@@a@lp7X{Aj}216M$wpXr$y$otEL^Tdybom38ctI%El zA?zl~tbEHrhmUMh436ZPXgv~4sXsGIG6LP8qs>G8Nw9s_6yzezdSDsVjn{Jx52Nna zp!cqE?OUdfJhLp1TcUQLPIZy_!eV}r>UWwW>!N7S>CrrscS^ZY_z%Uy$vELD=-&#;B9R9-JMA@1KM6nk*-Y zmkvF3dROx+=r^bfK|@6v8Tt+HLH~b7u8Zs*3!E#hmW`$ULxv8$oU>&?`;IvVZsew# z567=KhmeovYiE4E9tUiz65VH$l{uT%^=iD{S2UiI=TK%B<|yce!m}u=>-u#I?%R&G zT;DWb!rY>~B(HJ07V8^({c|W=l`k)R9QhIyxR6}+F>3?zMsj)w7F((ACm$M(O0$ z!g17RynfNbQoxX3gLBk=ZQ#{h&QAALZd&)}^FWJc1#|ORPj>$6;>-$K7bCe{*Dn)A zL8%M!+yT__65>?5HU`-Bl@?Z-eu>?}Sq>GkNA$pT=ZV;3K+8>h1m`x=jO12YD6cHG zH+b*g@3Rg+)ScY7N;FMtEJ?Qm|-Dx!ONuwM{P!K}9wkSohGZ96W&egI(4ZMmt&btbQ-4`rJG zm%m^fywNM*D{x)vden_^eGPH6zbUk#{2BAh7wD@#itigg+Yoi;psrU`9y`$!i3X8p zS!j73vQBK(wE;iq(;tn;_87Vw(Z23SJGpo8wlCU!&iX?G@jtw%`$o)zk1od6x`c4z zMQ+aNDdj{qjX1li@@gt^c67@qH{OO;d6r-l)9P?GxV@M6cjzTfScrb=LNi4{lmugh z?b`L{VdwJu6Dy3!rv-fKZyUy$#N0n#cf~2Ju1MBn{dXbn+M`#TZ+>>gnFe`nq78k_ z-nH*`Ph4{ucxxukFiAY%n|;b_o`<*Z?(3BVZ~gv`o#?Zz^onvGMfz9+{d3{pviLv9 zbTn*0ookCYr7eyDNqFhbE70#g;48uZN|cE=2F;dgv@fD+_z-RCLfekRmEjJ;jlj)B zJe|)Bc>I&~Gb)Ur5fL5j;zRKFdwq$!V*g6wZuQj}72Rly_M~J!jDBs9Z(mMzksRN5 zh;tzwyV(8$?YUpQH|%@^Ffmd+NV9kRLE{_vPkY6__+Ifb=0=jTPo#GpxIH%Ro@gQ9 zIUVwqtFgy*6erVo;eBEi#$7^LA1h;&-o;_;7{<!QdvSMQHg6q`lNj7z#Bcs% zfOsUdw{ysMa`%D#6Jv*7Aor0z$!r3CDNlU3|7s-kLKy$9B93@}nbu73|CWMJb;z$q z{?pOCIY-LBugfF?Z-9+V|Mk3OZS{n+Ds-*iJEdI&|KvfHkZ?UR^_t=jfoGR zHKU*RBtCF`%86zkoO69H7U*e9XT_S$o&+f;brpN^Pd@t3~n9s;~ z_WcRx@_UD4IP!$e-Hz}QgbB~_gbLkHB76hF%DHi(&@G|w1YcF~zx-m^6{jd4^9|t) zyIK~vI{{jR3py$vOI=@!D-J&&f;JjwpEtMho&`75-SY-A|BKO1EEDeuu(c_gbsvhMmpeL#r^ z?@o#T%lGj^6#ro?em(lY+1q`e$Pb!>Be66?(D%|u^no|g7Xf{Kb!QwV-`T($is|c{ zz+V)Alh4L{!kTfHppRblO1sk5M{MpGpA_;lAw0=fMlxrhPkyj2Fh}NAFxin$ad?pwFrkiGH{)pNoe(E5{W) z^S!a(DQE8|>tpK>mza`yxL+hLyx#J(Bh{C5iZefXALf({`DL-II_okAy-8Y=F`kAF z<7&ctzsZotYDYRBGnQoHoUcPYrI_CzVg41^K!?h8<-B*PL#fM*^&@Trza?~SKsuhK ztdsT|J<1u=7)-e(`8@7A>Cdu(U@GWr&~rG+neFHB4xgN=@PV6Awj@5_d+*}!4$)h~ zEadIi$ZXd@FVX{#$SY1vffSFM=07Xt`X50XbHXJ8=*;fP{&wR2K0Dqo!r`dw_oA`( zapGcyKkmYrcNwxo9B47ZiPS@r@mj3KH_UzTFzuyv}aaMNoRyje?uWRa zs&eE7-BZeY_E?r8<2zaJC}2f6J;5qHQdvWJjgY5ce}TLbaMHsf!a+d|Hxm#CUqA{GazZcqAx)vdnGqa@gMr-Os%>;S5fRQ_6@) z<_KsWFCp$moVP@45Z-#mO)#1)BMP3EX-fDG;9A_->F#ZCy-cd|s=BKt(`JP}hn=GD z^LnTH(T~hilDWI!`+lUMeK!!y&f^@s5W6o-mi09DL0ti7h{5TV5>^@G71KDKeUEIa zFkF_wFN0m2D8e*myx8XN!v13{z`L9AeQ0)R+`brSC3^5qvO&KvVZP4GpAI~=v)_QT zlp{J@8Fztfn>O)Yjs>|(DPsC4-;+8TxR_bdr22GSSwUJWy?1>U_n-TQvdSME!o9v~ z*twqC|5*v}jqmxq3(+PobpJiD2fYipb}7nFyAS-rWBN-~aP^pTfn0ws?XBP`HF#Ci z9SrYhpYun+;fF!p8J5B~BtazK+_-c&*Gf+mJ?$G$LH>ZEMofPTY85UN9+x`nsXO(7II2 z3>-mUqj-<@@})c@$vbnFX%@Eb#(p~2lyW1c8eU8p&HXmBA{%WZ8vYpa&>XLn9n1I9 z7~&o5ZGeqpt4UT}G6DWZz*!$*c=x%zKW!5JrQC(AN%$+}rjDvnt_kIq7U&h&pNpbB z6A#qCx-P3+LivHC6V9@`hn=@$47$#gC^}o+u+>pP@L4zERA`dDrLb`feBfTp72JDg zxWEmUS$;QccYGjoikmHRiaxA&>Enxbk4*kE`Mx=SSdqz;(Vtw}KQNzj;JV;i;CkSi z;da4Q_806)vk*4I&4kNv|HJrI7~x{RRzy%v5?l}BMWSEfoK(gDF3oG&i>O`M;2Gw_ z9xcwraS3h1c+cB*m!V>^Ka_??oK@uM&M+@qU?pbQE+9EBilcm7i2J8sLV3VJOo#tl z8A|!G$%nT=>gmkZ0iG}Ih`}@Rc?o3bVgE56HhzIHXv~B|H{ZRxVb3sE|D2@Vt19&N z^AR4pl}6$vmT#AvYt}kqYXPue8qxZZfc-U1<}c|b^`+BRA&`spv7{I8uFLh+>dJ!8 z)bGaZUcHX-m)04=hBD#HCg`O>=dMoP_Lh!gcvP>}zx+{j8foc2f^NIOJJ3 zdo~FFpmnnC?97U;BVrmW$Wz{=icVbo6D#xf{}OVHhKq)8*;>XptRr$WWPLr8+WWOw zJJ5qREWItG)fCy?;QcUkgz|I}p7o)pkJ`_R>GdkHzWR3L`ORwVGsm(ojFx-))M8mZ zEG*`NCK8R@#YZ(Ft4)OM_7)rWcTTj{pTDJXFF=e+GO(qv%cI9UI_Vq(d3~*0YlCuk46Slk-WJ<;U1%@qR-|HXlkLWCdb=1piaPX-XoO#XYN+5~^KmI;&`fY4i)Pvl zxDRe!{8==VTF)O7#;rlnnWgOh8!(omuy2#PQixszFHsu`rJQ$XR(QF#I~edhZ%><# z9rZ%q(Xk@wXq&%QUcY>@K9Xmp`u6@gtGp9!T^etzC%nqtdK+XxFL>-XO!lvLm3#T0 zvnsMaGn7ZSc(7j_?BaSnkRiu=D{^q&n^mB7a7Kr?f^GOQ%GwH;uocFVABm6>gJs;G4DSJI31ezOg9w zK~{oyk}+@UC;JRrVycj1#cv=3GzWbiwX*ssba%);WQWz;_uK?*h!QMEjh}I{FuwjR zX}MS3q!A?Rm?hX&Gzpu@vFJwICg+|W@It(m6`7Q|`VG$5pKlvh`s(>~wfiCL?RI%u z2IDv#C#psj9ZiCh=<(%YPLIN74@|?`jRkxw+5AX@{)jfxysSvv<1_YfMpm$6Oyly@ z@)1_6g$)8@fwpz*RNfp7(iDm@ujV`}&!fQHQe%d===kioXYr zz}3x!+~<{H=;e!|F16X{-(!QG-|8i{SuWH6gOg9x0!OU4 ziu>bI;4Msk#-D*Q_vCt>Ps1IVb3I+_xtQ_~0cp-54G&&c&`PZ_T0+IP4yGI?`Nk#J6dqkJ7;3|3dNrZKNF2OSJ1C8=8>4oa1X+}MWDA7 zs>hl@ugVMa2COS3%?(InqBzl^q?_3NQ>7feQcks!=3F?>i1Qg~JW3kKlPUir_|L>H zO9W-UtwS4tfmX>INlsbpS%yId`osPCi~^pd7j^hesSVMz)PQjof7Qx z4?VMt>^PAvB4(|`-4^kY{k2;$Kgb@3x-u4TCR<(BZDS_%rRo0=Cn3(di3_XcXTZBq z3$|%DG38y*!fj(2h}(vIB#S)t|IPT{{LlZ3nPO84^=!m{D8W{b-j!Le$Gt)e{1bSI zTPNQpLC9w z;WuEMya)piH2)mo?U>&#IXOcYF@%PRNk)v-MkxQ4qM z`-u(vN0PNMg~M5x-J`-Alh*o^ck%UkkZEStIW0?XzQs~13BV_WI(-3)GI`6r9QIYR z(+Zxn&w#pbgza$->wsu5LVh<>LB}B)GWl4TYheY(dlRv*wu^d27yj&p7!JD)Z3Qhi zLqdBP_5wZRQcO4pMuGd#JC|1QKh*_Iz9i^je`jTkleu~$-OaJbm?1kBgYT9xHTEs& z#BBua#woytHQ{>FQ5F_)R+B#P>LcK*V=ohTtX6Qsvm?WsRDd(#hnrz5wC`W#L!SFBs&tC{MQ3n(1PsoIXWZ9%b{wO$SY?^->TR?SG8r>xt(y0GppU% z1FBZ$!nruGdp+U6d~vD!t~HCh03O7bblQx!2JSzdvXmM*f{wI;ZMig zYUDoxf9m>}|84lw%3^-~5F5W)ℑB%BcV7>pYWMLSLdDcdO>9LwmV@e=d2~Ri}2S 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 z zXBQ^k6ASx6ZQjM`n{=G_z90SkT~JJVmc0-A-dKyde(1{!_gAo6G$YiW*ozHqwwq%w znDO;qe)XkPxGAp3vo8+4`cf#={8Gx&$Fr~Ee{i7rCFCzk>3KYx+MiO_(1ts0I$J&w zb9+OD`R0@hGe1nZkP5dK`PhNyvoDr4zZ60~w)FW(8Rt-5&-2;r(`MiIc<(Y^xUN$# zSUV?vIk9uxUE?}6rJBx|(wNR>Ij(c>J^gD*PSe<(0^0EJ3KzhR8NGMu#QSqRc)&++ zSKN&HssBtH<6-9lD;F~8duXm?HP4L96Yao1Y@4I=gbQUYoMw&8lZf3Wnj=Jy3y)rT zmx*(FY#4KlzcNSSG3I-4CnJ8fn-8xbx+Be%e}-AswERHy-N?O^=F3>#pU;=4qVwgc z|8c(Ts9dSMBNCqf&741j$HyPxhO#f4ir#>YHoVoW?A!Xx?N%e!riZ_v?AvObvuOWL z^m7B-wv3h%z0>e%TAK;`74gP7+mYFHCM{Cd80aC8-2rv7#8foZrw!swsWLr37xSsj`lR9_e`v%B5G{srcPISaIn+D@~Ov%r0D|AJ{UWUD@m<)?hKjDLpmy>}FH zJUCN38X(&-sVUSysiuo)xps3Cb2=6<*|ESabS-cPyA}|=|13T&WRyARbrN4y2j1D9 z%-yqBgXbCpeE>D$%kd2d7J2gtm*TBHE9x`n#PY_?`!oq>-F3;qWjx^tR+d?*!JN?U zUj#b~l@%MsMP8DVWcJ%^imrixn`n2NFMrrnGzi{oBJ%GX@kn9(UqfYm)*w;ab;YXM zL7b6h$gGCOQfJqL4u1CV^1<0K6nHQCFuOnjXj2(l$ zQ;a>)%k2v_St`g>)7Zw?SzX3}YKuxxHPJfP;!LBF+v{i?WBl$q>i3wu#(w>QG&|%; zf{DNG{BW<0o?`aN3O7; ztrqUf!G?YGo{?Gr9)*sQC&$rE@UxLemb%ZR{;W*nW>bk`&jY$Ke(a;;Gt;ejW`^|MRf~?F5t-oEF6B;2Vq^wOps|z~S z!8G6y&HiBX7o&KyH#fD1XcgPeYX2Uyb=&UmhkpN34BnQ~z}8`aeb!#ttK6>_DmXq3(0$inixMBC# zLwjD*Zf!svaP1A=IJ{M*t!vnQnf#!AXvhy+rwMQy!1E^F^l7DTty1^**sFPw#?kJqMCc1@zdB^Zo=R&~jd_t6nZ&w+a%+M z9534=;Wtp&U$;qgPG`c41q^zEbnm+g{6KNqbK9gqg{g#O<086SOj;$6Q}C#9DXS&j zL`SZ=dAf23+c5MD&XPOtX0_xd9spiMA1UV|SsS{(i@OjWy^Osrvu8H?-y`qHQ$x>^ z4~u3G=uO1qt_43&IgfT9m69=klrtmZNXIx;2F&)ddsX1SZwAiE3gPW8KU-TtJiz0L zm&qb>)n_U=Y|p_feUb?jE!s{!m(AN$~_MEi;vav2=r{q(yY4`n9d$ItA^i|^G1;+6m&*VX;Aock+$FixCd}!0 z+{0sW);EV(-3|Io?9W=|zCSjf!vu#vGM`(19T^KFYzXprcPIht<{rEum5jF0dY!cN zsKfzhIbr97aMnER<8|4;P~c&5V(13oEb1>=c%gQ@_4~>N`k8~v^^*th`*mNb_E?)@ zgHVsN649d*@Ye0KNb43FYmaJ<#98!5ptFp<5%+~vNKd+GD#B;NQ(pZ5&B3Rybc@Bi=3|R@A>2f`xz4{S=O`1_@g$t1 z0wnjG+oUP` z^Z9u6XEyndJR&7xzu}kX^8);dXIY&9J!mGpSwJ|1gZ?M+V0FL79qu^q8v-6#OzB1* zQD_h>v*DgB)m)|((=S<2&oo)fdyX*l2M2lyWcZ*@qXr%0S|O%Wv%fK0=ghdo@LsHT zxwf+rJoVTfF_p^HfbS(QF&Bu)H^b?yvC8Z6KHu6eWdMely0h<2kk@&eoZSbpMkKxK z{P0)(<8Z#;RB`@}xSIH{M9cP@a}LG@Ck)?w^YU)OGjvyu1OHQhMzk~^T$imscwjib z?)yK!T6_KuO=p~3=H2EzaL_8_9kcGZOXu&HP?P>KH+`b;UWFO_|LcT_!GDt{cFq(g zbgG;ahGz)lI&Jd(&!u#yTxwpHa`5~es+xGDw+RzF*~jHWUzhc-oha8<{2S7LgErG! zKofpA|L*o%dJd)t2P*Ujb6$zhkH5rsr3}q3h;M#B1ers?_-ug@?_IHxkA7t;8HYJ( zg#JbXYz;4l-pjLB@P;|wK<6=b-Ljq!g6=dQ@>%~4Jdhkr3UOFVf4qfcTlnzXxaXY0 zdz6l;g^Tp7ihVIBiha73#Xj|s$v*DZ$v$?t80Wob@Xq!#K8-(e>? zm*!gt_Fis-eVbYODTCX8)mK`s&mSb5!wE?tI@=lF`$!^JUFd1k9{DdH#TkX90VV7c zOIu18>Waz+5MR1OekN}%%2DPrZ0T5Fb3uoE4bCj@)WCm5({fE~kv1Sd<2YPo2omn0 zHhGq=8l6*gcUFl-i{hGY7y!8Tf?vS4H#-4{<1#EUc zW}aoHGgJ`xy5hX4=;D2mcA3$xy`!VW-`y9%p;Itkq!aSC%=ouQMoZtsnDJ;6jTs9Z z?vIR@=xvv|3<@(i4Izq;w3&sChYch2p9MZ6xh9!~kFDf`WQT-g+=%v+C(l)24Z+T2 zP}RjjX0@Vw;{NM4K}VB=j`KKs71~FZr=UKM}5OSJ1QltFpks!Ub1^hG9YxP1ubl1ea}t>rT`Oe zT8(nX;^|CB@dG_KdY()C9yq0R?U~84Z zg?A+amDz5{eG@$@)B}3k*!(&Gn@;F+D$_l{SMp!?6?cAZDsmx=RY=^dd*<_y?v$L97AUo?2umEdhy+F(Eq|OQWnQU&WqqB zxW{0m`+YgmQ(5)%g;^o!_ftL1us0?^2bTJ02Y4v-1|!MzCSYxG_#eC*_Y3hh@NS@c zjx-M3p#u0A_M+8(RY{Q@vSfv(5#wz2>~i5@Z^9wa7vS=TIE&t&kNYTi6?YhFri8fk z+tH^Bz_T$UOhlS^q~+v?y?X3_JZ#O8oo9wQ`SxEi{$vM@_I8Z@)41c1T$bK1@a;IO z6=eGsmVBftsX`jEt?&ZYt%m*=88__|I*yZGJ&!kyct^rOfox3A_oo<^1$aY;(BgH$ z--bRg3+`Icy8galqGuMrAYFl*e#T*&16hQt_ z{w4~Bfg!{vpLjuZs$qEJ~iy#iziFEbGtkSOK(yzO@J=RG0_aY8-=ENjcoDC zkgsZ7cjIZp-#yu3&_=Qjb3v0(=)DejNw=P8R`f1d>QAbwW!bS2hT`IswUnl zCoF`V%VzJLtGQqXc&i%WH{OQu>KnsCV%C1Mkgb;N`d74$aJ<(VUiL;B$vI?$F9 z^>KqF5Ae;LC(Sns*L1$~U6v&T8_C3r^Y9Hy`_<*1{xqAfpcQndX5cByIpX)UwFj1) zm&OOUbTA-!5$F7x0CQOYx5EEhcBwQKYr;~-YUKy~ODSx*+(S5Jmx%VO=Xd_hPB77b z=-ld-xqY{k<9;iv5-nxsN?H@l#_sV1_8ez;>njfZ=RkgaKumq~fl&oV>CRm({lnJY zQd%GGuZ~Ku*Fi1=Z6{n3C%k8HZHi$Az}GIb>hvl#Gsy0`%b#K#3(UiyK@NfEFdQB& zui@l|DqehG$c(kBSzJ&;u$J8&z2}0Tf%RS+J3GUQv-L;}(LN4*=3{vqhZyjT3jb=r zg}Y&;%5j^I3&IA8!)W8M?_EK^DQ)ZG_Qe5bis%y+a8XNUqqV!dzf|9qWvcQ>R)FRg`wgol zH%o4=wY_%=Ps!*I>=J@-!c9+t43RnG0NhXs+c`AJJ+4`m1ju=bMQ5`7ni)gtb z`k45~ddQtLEBqf&c(F#@nT4}Lkj+)e+>-C$l3l6U(X{5fO-197e!)-b`g9X;B=EuI zA4ZG$udbH9QP*4g0^!1Mk4lf*830fvlDi3d;!nVZo=#%#C00cL3_2eamkAvZa?Q~5 zyL|}nRO4R{-uGj0r30!&C*JMmzH~|HENxuS&YtYT$BuP?-t@b|aj=oWWBh48rEKae z{T=N^j6r939IwJV2BHhPw*z7-*}6%>9Ok~SS7dN#pQ5zx-yBtJC;#weUvVbdLi^U+ z_k~Maad)Bn=AUJr55UhLm;0u`E4sW)Z0&h{F!DxHqHX+4dNY?VGga}}YX)KOg!mH&%v61X9e`uLUZu`r2DqULiBOK>$4!d4*zD*hsg#J`D@@8 z;D;`o;=dpMGWcO1MDcHg-wi)xK@|V(@VCQHvP6`BHT*LCx~P9S{2};bqW)a?*}BY1 zngf)6G5luuX^hD~4}Jmu*r@+H_{-oQAN6Oz?}k4v>YoOGJNy%({zUj?_~WDgc=$u` zPmKC?@H6l?q2I04_rnU*55FPmzXHDizcK3n2L3YmO;P_B@Vntpi26^%-wywzsQ(1~ zGW>~A|3~nL;7^MByWwZ+A-f*+zXQJ+{>f4QoA3+pPl@{f2!9#;*F^olhu;lfa832>xG0{oCMY8!{_lcSLD_9sFkaQ=|SG_yzbaQUCq$m%*PF z^>2jV4S#yne>?o`@K2BWSHmyEpAq#hhd%^A=;um(x$v_)Gb^o8|6=&f@Xv_)=fN+) zKQrpT4*oLuXGQ%P@Vnuk9raIxza9QxM*WHK%kWTjn`sl-dNX2g$pU`T__x>Uggq6cZ=~Pv zeC0c$-+=CWq>pU5L(W5FiL{@!Ku(eHf*E*W0dQ!ztgWgm)K=AwaI$k{0X%Nd?#{@I zyybF>Jt!>lX2701;qnZtcIF`7rP`mT?@vU%bnh_Bk5)6+#-SLj@fi79FYPV#F94>O z!;kDslhvJHLO%bCvzt?eU&Jjg_(}a%;PW`x0TAVuJi_ClJGkmGcywK`qk|7Pzo;+@ z8|?)ITL3T(0KT;d|39F~G~E1@R0de7eDhDr&qVpovK5uoPxQVgopmNz8)oT*7ZqDI z`e4J4{WJw|jMY8m|D(QigzrXu>e|*H>l=j5=~#dMZ|(U6>DcG>OQ}8Q=pTLkukE>v z@SW724gV}(IbYwWsw6zl;ax=BnUwQ{-p?6kHMG;$|_?0oQ3Y8X37VdB;B2n zJ%riZ_b|v(5gjJ|&M3bJ_XZ||-ivc7<{I>D{^HZ1Edz9S!G274iD8Tx*&B!tj86hT zvxM$7k@!q+7;#52o^!i6L)Hh}q#JNHj(5JMnQe`oWjw_V>`CzOOspE>Fs~8;6ECX4 zQ;5nOz|YBrphsV-pnK)>%dv-mkHeiJy|4)eW3jQ*B2Vh%k5&(T3VPEdxx7O7+*Bk+ z`-9d2@f{ds3JqoID$<2?FKo?J&c)^7)3LIdY+*rnLbN5Ke+g!Drn@5E4gwNnLby|0 zh+utV1-Fmf&O_opnupw-^~#*1{tF)#mJ0b?wHjx%G}t$z{rO3UfH&+_;6t&ZE1Mzv z7Tv2Y4nuP;tqZh^>>j;_b>9&-RLuhnkOS)^IW(f%w&!@NIq-jHQn<`I)qj8O9ktw5 zLHXRP8>;_+d}`QQ@36D&Q&2}a^aj%LW|kWE60V-jvV<>r-$|RtS*a{`OG9;xz*zW8 zchwsM;nV4MmdFCU&(n7pWd;;|YV!vT)z1`f)bZBJnU*f@eA*pcv&GLfr!C{cL{nwK zPT%1AzS0hy9oUGWlFn2#C&{KDwT=3N-gJPTInQwJhfe0*)L-0cR;!gSRcN5ImI6Bb zv}oNm;K3zg-cbK}_#Lap`kDJwY>T7%Ks%s2ti{cBs!u8J(kS(51i6`bYig{uvv+79 zE7w$=3Vs{$E>w_d2(H698ToSV(`_OCYfgT99dvG$GZWj-`7Wd1^iD3(4){5oo#P0` zh0a-8z(H?W>I64r{Th7}5MB`WyF|cZ{i5Eb7lCW!`UoEDM}0D9^BjTw%sZld;ou&n zj&y!*=cDVRGDmnPZCH_$;cKQ1bE&k}6Y^EHMp>>Po#f*J*H3o`TI)3baTm{I@@oY| z_X&fhaB+BZ>L+KQ69w3uu(wQWy8*cF$)MmW0qwRWAh>8AYie07xw?Nu<>al; zB*N3<(N9cqa2jmMNJ3@EzJMoSSjRA8u*KUOV{&?J3{CBIl&+!(G9y}`-aLhHa z`9p;JGth@Ljv8C+Oa?hAALgiP#*vw?uLiC-)aDy1;QP1Sf`7P=07tBbGJGZYo2H_ z-w$P3Vg(ofds-h@w+F+f5?8pdm_vRy@+*9E-2Z5u%*EX(LBKt!Y--g&Xlm6(+(X82 z>FqzkrEv$xCq1g%MKZm^z@Nu}M+=5I*m_|SXb&Zw^Z#3cAxnY5RP+7i&8arv0+JD% zWNTT-fUl{~ch;yR5pXl;uIU0(eKD|;*M-+rm{_UcT(SrFQ=CgUhUk-?o>dCojRW3I zM|~tOLT%0pfqy1|R(UF7^P=qFB-ry=#&h7EH-OJdIKsX97<5Bm2R5Xx>RksOmh7&p z3Y&_)TW2aMuxTm?E+gP7za4ZkjHj_!GoUWkD7copq5`bAzaWkJb_d>n7tw*pG8662c^6WufJ}Yw>@c%mMF#&(?#M>4Qnn$!h-Gy^z;Cfpo;Ah7^Q{Fs^ zgwIjJsa=KwW2bJWeiJ8nA)m~pyHU=IG>+%_O47s5g#5sjq0Q-L^n1DR^Er}okuTAs zUH70}nqtgNWu9;&^bXWLLD4c_R5gE&`|p*nK9vfDiTw58Z&G`ci;HXMOqc+k-}Q20 z=ajNv0xuAK&sbypjQkd-H?6O24?jIVSCbKRfD|FQ6XV z`b`$0-a8F^DT`k)tVda(%cjQVaJ&O}lk6{q`qkCM8=G=QOjYirmm_*1bS9y7L;96; zhJ7Q{SFEg~C2ZO6qyO$|)Um|AlKdZ)nM&wg-!hx$ZrIKAGQrXG!hy)WRKVL5Btt>C z!+5Vsc@NkG`sKz=tR#(}y-D7Hc_6p?mj4R+JaVCLS;=Ur8mqBhFJnqNZpS?Xb36|4V_ixC{~~W)@o4Fk zfYG-FF0G*y+31t-Px05_e{(c^8vdu^YY&08gZ?D^WE|slhs?P9T*C*z-zMHR*-A{r zo=STO+p?<-a-->sv40cJdJy}PS%5B1@GrjaU~_@TS(Ww@u5MRb9Matfdv(g03bx=F zXaOU@Vcf|=3s*czS?fvPs-&diNdvUj-#EeTOG8=o-}!#WK9B!;oZBKcP(6;s(4S^} z?4bUB8#KX$POvpqrgQU_?@nn02-hcGzNxi&j?Gs01y}cIG-qsJ$)? zzybAAJwh>ZeH8>4#rfFVW;w*raFLYC{JhEu6;)T8lMVjWqbxmC-|wG{=SiP-X|nU{Z~sEi9C5|XDA zY|}T9tPAf{kIc@zCesMJlt%P7!NIn)wzU8^AAsCuWUs8O*oONp_QgC+u}PUr@_p5T&1W0hrsu3WPkgUmrG9%;O0E`mBDBpa zc~Uj;RTK6AZTt zzY)BbJ1gRIa(!|8bA1!>k!?0T_}mllA6EoB{&|~*2JIUi75j5@dDmS-65MSLV~FOo z_N+>3au^5bUw7NaHsdAHLUlHvPLiL1jjLhRe#?@3u%2R9-U-9RgAP+kto( zF5}HJ3KLM?SlH$UrEVpyh_r!7S~cXVHN-n~ijlelYNc+%=h|PZq?d6PB)uGxxz}O+ z)A>P*{nP=O2GCa^`}ZQ&iW~3JzX)7DwKEU@9RBZutA_gsTn*fIxCe1gpmN=g=WDe> zlR__N`JegB!31`h4YH4n$E0=m}6R; zRYB`7OI@h7uAYDEoIIy4nA@cb#t7T0GGzC23^tb-^z@SL96tycR@gaq0Qgyx6Ij{} zKb7egTWY!4ju}%hw=}TnrV4%rTGG_c^=K!hp|(*v=4h;KdY_l{Ip8b4r?C;u|82|> z*8SQ42z&6aJob;@6`F4|K_9EFooqExA5KCawm_y7cVQ+(Y5NB3n?&2EFq$VKWU1(% z9pt7bKrYw>+aEONG}y?9>|vyD1ztUl?qaN8?n8^Hbbg(Kr?2_6DGP40v^bHwN}gl=l$e-)l|#m1bP} zSHzEF{tR0U?8GzwwKjswEj(M>;C$HY2|Vm={1mbh$jc#5%OcG$FP^}e!Fik46MWbk zXYVr9Bh6;i7eqc5>Xq(8efPkx792Gc<{s#k$`O`>FMJbc!DzYm=su_hMY>$b7^w&b0Xwm)DFmv;Qb>VV5R#N@#@0CMP85i zr{m}TmX%8HOFV`90oOxeZyx_>C@VGWhg|1MoXJYNl``F5@|Ce@lgY`4$TbG}fnX`= z;cl+juhfZiG17AOa9k$h>;U;2GCAC<=y?NHvPyB}dx4*R-SD#BTt{>lCWcrfD=^p?Q&dduMB zNJH(WxDeiK5|6cdImnTx8`BIK3DYN8OxNT(bFN+jD%|E!v?v~X#0)A~Te!98c-iW}!$i#MC_ z{db?Z%_F~=<9@9X-`5VkPCv3YZWnJlooxHx{^_Z_`@D{=MzyX$WzW-&E zt-eI~y`fNd2C^LBlegggg%rgduec=p(?jrp{yjsVIe4z5uaxYajPdL2;Ky|%OiA;% zUg_27Kl^*H^u_(a30N0Dt_RRQIjn~cz;@*mQ^`l?M~lbeD10Zv&mp`u{PXZf5q=us zkN-<}Ey9l={F`t7nV#sYR8|Gzf{1JRk`;jmocLyVw6qRq4h7D$?z-i8TkJar-lqVs zFmT~2?9U4PILsx_$Mv_Y!?_dmf}%Koy^F)TGozo`7vRbK>YLIy@H*?!=2*e5l*PVa zbyk#BfUz2D%NPvT0R|6Xc*n0VszLpWK|3s5)WVOwb4&J(HY5JcEbNwz~2O~j)UDcD)-f} z>c?^^O$cdfJ|Uhv*#Y|JXGA`;P5qD?XJfKS*$`^{9qfxrMip*=PEXGOc*m2Iv)MH4 zlgtU8h}>HBd(+FtL$C|Fcg`N3?C%-2pJC>hwmGMq5A)=LkBpg zbz!b7;fj@gkodUc(%5vdt2sjqHWME=W89>Ahh6(5=_{nk^_oKk26aSMnHxw6JkDF~u{@RG22Jj?xCL?p#P45Msg!$DuT*txkMBya zsbpJkUvUa-#8dqH&MitFT9=fz4muBKk){f1IN%1lC%rY$vhNdw-GeYnL*ZLd)*-Y< zsqbK~v=(tJueE9KVE@|HMSZ18_^*vPpToYKE33(ZdCOpP@aeCpoGyE^3Ji>pQ&V5syi2jhNE#1A+iC$CD_mmcCT+uwONK1JxqF;0IPj~v*%*mNM zAj9pB&XI^LmuW!4{vKa|^A5_c08UFdY8qLK_A}V(Z-*`@gRMJiXQOz-X>v8;xu-L5 zpIzmGE*j#te+c@C-QZmh-QT^~Pbf`$muVj>YpFWM%nt<-&VoCAXW`m_3%&}vT??o! zq0Gvv_eYEGM}ER_JJhWjdIzYB9c$l&_I(v_yOcKm(=QlvnyR`4)MGKkK8M1@IL4szh-+{P~F@iHVhC? z?bG*t`!=nK$R(Czy%k`e7+YUs>vwEjj;&v+$Nlh0$-*0cT%*}2gVxB)e$T#&H4%EV z8|#hcdva#%%z5bh1mKg60fEoKxw>BEaZx#`%)MzB(x*WlZyfMQ;>kYXgiP-$jQ0^y z-4A%ujlc<>+37AV`!WjK1LslGcz2fX*hlWmXLjs+{9v^IYEMdgKm%52zu>n~Jonv>HYb%&;|IU` z`yFkcoaigAI%z7Rz9M`wB|1OHa2@fzXvOxBKCV4OZ8ey z+j==?iAq>sk%PF|h%4%2MefxR`X#q96*4Ss?HNwSpToHDhdz^B;4`&Cw+sg3m3>TU z2hL65t*y{=Yk5u-TA!nH?>M{xn!7q;*M|1CZ_aH_7qPFUgH9xT#ZBJ`oxd2skpqA0 z**!N#%Gp+XC;TyITW(bC-{vEl66x`7ba26j@`h|K+>)K8FZWMDxfa;X*?YoN6v@|I zo35JV(jwpgoM(fdAx}E;JdQlH=g}NBsUU>}IVIYE($IdIpVWUp6ys$m@UoiA!CS}K zkYr*1LgOVrTWfI@xX<<*pj*z@a5y_3yES6NPxwW`VvC4%i~gc@OM65jj7&d^_XZgK3qbKk9^G0QlYT(-Mv^2WBR+aY62yr?NC+lq4^ z>>BtA1a>zUT2L9fg#&$cO9gb|J9jp)51<>^slZV;sghfjh_|y&`GUv#N{fVKMK>%t zz@?K;@MQbs&bjg_Z}^rZg`WE?>ZE+`TCP$T0IdXfV=d%L-I@N`Bwxhg4R`Rd`H9*ZnKeYmkNBEjnVwH zeknhV8`bHzxm}CV=C_WSic;QVC2zn@9)tJPN$FMi%P?+Z@*X6^;Ncon`Ytt3e36&K z4UkdLET(@$&S%owD3f7rC7?c%xr028m%_}Taj4+eufjP6>F2JB>^s*1uNvfa6)m{e z&^pV!D5hRn*;lHRgL|Zi{hDwbt+^ds>@p+Ce-@Mv4R*QluD82x*S&OS+gw3zXdtUH z7v++F+h0eE-*B-KrJN%tarQD5EkGRk-NSt4TSxnfH35b-{=34p*eAT}eyi}jGjYEA z1M2@TN(Y`?9ONxi=`4zOE+~wBX|AL64*P4BVVT>alqZ1i4;x9)B;cD@M)d|(nqc#_ zt)1Q{WSGavnVuO{4;xCzKhFC2jNRDxVh@wdK4k0d6AcD?rguF2)XvDcDQSS>i00dP z#|Yj{B3m4+_SE0pOP!coCis)F&T+SrR>I}vXS`{>c+*UVuC}9ch-jwCx2O}6LH}2u zeYT<;Wn>FeI-ijzcbYv=vektaZ==85 zE7{dgtj4$F1BFR-FCv?UE;#7nyi_K4%VjChx#r@2YI6Z_8V zKD7{2C5w&K6IU92e2>wGI@W4)(=JU28hz;klZdvU`vLE1%G(N!u&vGqG>P$ezalQE zNsQgENz`|15_LVAM9l$BVmjnh4ahfLoc;s{UE(lg(#`@F0lb?pw_bXe-WN+eVnO>F zddz4u?4Q)E2W;xR^+Vvf0k@dz{v&AG0$$={smP-fxZh~V?tvga#!%i)yzi9!`4POU zdS}J0qPcF#{NK(ZoF?ME56A}i5<%CX^Jp62<}i=6$6ogljm`;Plvb9!FFLeO5HBqT zx|9nAZKqlWp1M^XigRd&$)>35xVnwz);4EMc$~1Y0{Svo-;9leKQE{b>V(It9@+oM z4xOB#yd9}MlF^nc#xz@y=9;`XZvyW4I@C9~^~)dMBHVW9uD0BO4t75nYg~V(pD(_1 zs7!{A0dSpa_2ePV%Jtc9_?h^?z0+Nq<|%lCCC!l(R3ZLajJNju-ilJ8r}@Q%RW%yt zmg8Dy_OKT3TIAl6wnGP(=8O(=Y0sAqML$%x(bKPYY&ov(${r5ig1yw~8rpVGhBpS| z&YZd?oC?>@?b2Q*o9?OWaJLFQRYiQa_F#RrImKk7dYOMc=>Dnqk{;GHqfZZ@`)0ZSF4`w#qnS0ABd-ltaa}1=z1(`zQftinq{q zS!k^#T@bx~k)nsVYz6EMV*f~%^Z7)1JkMFg*dC^|>omM5nRca#MD;{BJjF@W5Ax&;*GVB zQ{ZBNi#ZGf@xV<4kJ6?skXgh3wnKfzVXPC);`-#p5639-M>KxMOq119%!-6{mdXda zn2WQkya~upYxt-40J7gkXC%E$XVKpk+94;CEUS`I21kp>?lNQdzOlQ^*u9VXxd40F z#pNp8wJIv!q`rQTSK!J9Tx0nY0$h3zY;sV%yZVGg`U%{}c*_cXWXCz0=tWB2suNNg z-I4k<(h&5vERc<3*x%Ackyqje+;wpx<5T5&M?CJ1ppg}MZgVe9#hXcSqAF>!z25b; z-|aG}jGXe1ySI{WiLmsCkNb*G2brR8GPWlZ{1(8EJ7LZ1kYS*;@*f1_uOn^fMIK{8 zgzi9hBqQ!zE6{(-LtLsCcf1WhJ5w44)?(hYIt>HmNE3@R`u)%uk_&BuFg{U`3zyJ- zYEm0HCRm#Ga4*VQJNINGwI8_kI?N4qu+XP=rd=XF?yRhfz{d?egk${SwyK@^D#%(C z&Q87=YYqFMi2Y}s|6#8Y^M}gyK!26$P#tac37~%(h4PAom4&`ZM+<#Qo3NH9>pT2p zOME}}wepZ@BO33XrhkFV2Vul(wkC-J|%F88$V$(a4R%h%qaeR6_)SH-WEx-Mwp zPVd(}sg)n8x-muQ@ zO6o=Uw@TTNrW927(pye3GAA8G_yr}sw)Q&E8fnbO#yB%9LUy04S&#A3_*Gty6R!y3 ztOH(mHT5^cc}jDW+&ujQxmlMlH>cs#$S+pu@>s1$+sxS;9dkj?yuIb8Rj3 z;#f4DQDi2|f%-g}xAADxw2RYrE)+udm$T7|L$Xv`eGdscyP8TdX2(A zIw6hqOC09DlJC$7>Cb@(4pH*1p!s51(-4fjFRMA-(6$%zO6i9qd-eryj?Arj)X%t+ zlI#x7)zX49Vk+z;*JS^UMx-9d!WwCCs+IRnw7lvjC+HbemJa38xmIP@4s`p|BjtBD z>?=n+(Ir|?*VjuUdV2SvT?+gkMB23>>SrHD{DR>A@t&25J8~zrHHXf%Ep`#G;Z5#T zoK=e`ob{ZL%5X0s7(86#O+3=8Lk$&8fHD1yx?c-B5ue*FPg0*T(2ARIzd&E5Q~m7y z6H*5HiuNmNs}d%AYL&c~)ctDYJ%hZYtM37=FCK3`%)Ys=)PsGG(wYTNZ3q4*23BA{ z^=PL>`!X&%PFErKs=(-vw2LhUYU)W!K8g8Lh|)Hee9SAi+S>YfJ7^zX)*q80ytr2i|&p%)N= zzYg^)VHb}}S*V}xku+w+Td0V}v7zHqI^t-|48V`H?~@G6J%CZkJA7OsS?xJtj^3Lq zdH{RH+Grdb`Dfe;gcE!gqDf+%0v9WH=XA_nt6lw*^OAbNg7WuKzy4Z{b4$IKWFhI! z?nE1a3tB9IjpE(sjw`qzCF*BiM{s%aSp4~jzbHSV588pcjmo_}OQ|~^?RY2BxfD|f_J{%g@RqN~n;9xZ5+ zN_u7!?xy)e=h9fTB?YjPOlchcKUvpZY$;>4>;wPO1(+v9{{$V?LGrl7|H$-<{MBWB z#k7aA&rjg(5LJlQMCwA%tj~W_x8>zBwk5`?+M)}3vd87@#=*@;|>Td_P*Y`^*XH(AfVMC#3I|MQBd*0MiV}{L!6> zcn`{%8+Rt6EzL&%y(Q9}X*10gKEV#1vNCtwN_mI(N_7n0LNtviw4wJ;N<7B%wMXhjE4N((+P6)AU;yKt{qSf6H}D;-7iq_M9V(1%Ir6{pa70&p5H7=eXw;7kaw6PP z+=+o3va1Y={Fr9uqxX7p@s8#dlhnXGdtY7=Q{tJ>@PG7ji!X5%_6XpUdr&^;rR{Fv zN+}OLn_QG-yh!q94^(u(Rx`;miwC&o`|Vd?C#uz#=HT(pIcN}}eu?F!HLVA!ljM{; z90l7QcK(T&u2$cAG4qMNnmsSCckxf`)$MsP-NiSnVdK1=+xv(1rRKG&0!{Teq$3*q zvj@28B)ibEk=2si12^hvd!OdW%2OCuPvMEBeWeHB*IV7Q@(71MtPa_@G!`?q7sjWt9K83HZcL|VzfUTiKigSN( zN>b9?d`cpD1n&WjGzIuZiCZ2CYdOGb>0V2;eWh)OPD$kIt+JKcZs^fSCrl5Rw z$m^px_o`D;7&08HkXU(Qsi|Zlnr9lPBc%6H^?2=NgVP(w`>WIyF4pRR_K|_ zj*!kKbo!9ytx(H84&eu>9idaweVAiZe*MW)ioO%2X)Mn?O?ZOqOO{fG4JA)i?$dZ! z!_r-FHJgt}0f8|de3soxc-J!Wrvzam66XO*vvWYS(f>2}SKoY8NuP}L6h?V2hyNMh z5RErS0r8!v(;AJZ`sdV>Y6`tfu{xf7xBZ?pLyCiIm_z^a?Ogrw4u#-Q8d$k zW3b~i=B!tLNi>Ua&BL6T6()>uw;Dz?D-%a_fi^FtOSttjDZ~2hrwgoKd>W6w)j=kU z%JdxLf>zaxcC&g`$F%oMMUMlv30P-kD@flHwxS&x*ay3_VqodYYNEqfA1y*{qu>k;(zMr& z2fZ*#S47%&$djv(w!Ka*d#ZNo-GedMr!My=)LiMmriQIf==nh!U3+8bxhk3qlOR`r z1^Dopu0)9yKb1WNd$;>e749;iJqr(3?Cv`L`VYaYrAg2Qp}H?J_Rt{i${(PgeZX&5 zR=c~uf51=@n5nWNT*0Z_si(3h2%N7AtGq)H~}5CX&UH#?vz#={TJX4ABO(tGPrENsalyMcb$@yHk>*oeFB{*4muEv zv1T_?n)glBbIDz00#CrqIGhdXU0m}qQ+18fM#w=4M=BCAjsz>ieN_T{^shSHpuq3K zeJcKh+LvG#coBAu1^Dp}R0a0lYP2H@^uHoiP+UNH%KeVTZe={DP+a!9Zf*$^szGCD z^HLw`<)?5)XC?G+7AFZh|E&v>g{-5c9pGp=XoglMB>W{!oVdm-|MoTFy8DUd;`idK|zgUj;N$Qnl@6J5SSpvB4 zHNxiobs^47y4;@9@lxnqLp7IM_U`qS2jljDW^U;c&wuaaP7_W{6j_3JoJoPdwZD^w z_ink5Pe`OA?Eb2un$mL%j#??bCBQYqrrnzEt)rzM0~Yr~tdh>W%{^C3GjHov!r0$W zN#Ep}N)i!HxNidb!ist8fef%2JkwT3qGW)s9`%t4c&PKDp(MO@_}!iRx#>zD{rZ$d z`-=Lir!BFZ)y_eGUxRbWzjfw$L(LEqJRe>vUVv`1Fe<80##(WAGv5 zd-~4g&Ii#?R4zAkO4^v)S4#8H{0~c|=hv|kSKQ{);QcOjVN169WSegf%FT9glemF4 zMW>fwD-uOpyg;Fjum=O3eI}RPOZopV zY40B&MUm!@*L2TJh8Uq|5@JN~CX;}pa$E@LB0H`d(=`S8QQ|NIQrwL=}VC6|+1{dC-w4GV>FxZ4bV#lT3% z!rR~n7JOLWBm3JTm-~+^V+dmp_gRvU_+2f&{BByKdf0yj&Kg>^8+Ry($rj2#5%SfE zZ!I|%dpY2w%C-J0a((;z`SE_I`A`3kst&BS`W9{*u6abYv{(M^JQ zhZ!`qiO3JXu?u?*1+<;c*pDB`>#2(Bf8xyVT0c7va}xT87_=i9DB!#V;0DSt2*-C;SHHnOiu~g)7EdTZtKuJV{*IFD$fL=pJESL@GZ-UdwM<# zy}2F!Ft=NNpGB~DD2lsOI;;;tPCiC(&%U_2^zgdrM~vc)c;ae&oih=%h2xNic}ce8+j)=@nM+ zAa_6RRfl}E$1p$7)2H`;tjD^gPFbVkA08LjhO*YXa4!V%Qa%&%fsVzL&lja}k{JT7f%dP={Wu zkdh;?UFe^XnQrTrvj%0pw8EqQLp~S#Bo2U%rW~8S|4H9-Cd}#6M4yy=z-0^J-*~`y z(h=p-eW2YL@{xT8-!InX@NaG1zXR58$Y|w^hC5lB5A}s&8|TJ5xYZk6JC8QX=5{J` z8vhOJF*nbMBwuwQI#>9WQpWG6a|{XYmhNC}#Uj>8d-JoDwd|~BS~JUr?!j8XRWu$* z?lg7>rAoOmk9CGTpgaGCJGGSVp5KrUS }6-lr&82+(yW$&iFT+u0kP5B3Rl72`* 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

    pEJ5dhtle`Cwe>IIe zGw-D@@okIDw|0*jG+m4EW$?u>yZPi+w^I@c4{7BLXUwUy+;mRKw5a~1iwqTO!z--MrFj#8g) zbZ0gr?l$6@9fdfP4DrG&nHRJ^_np3QFTeA^i5h*5>Z4i7Z2h`;IFp6?5Skd%w&VRhi%E$RRJ(gX+eheT~69VQ)E;_7%3?9$apEJg5uDoYt-<55s zx4}j&ga4|sz-O4Rtm%63=NimeV<0C6S1`;PJKpq$yB7FR^G&dYdH7H~=$#GQ;1u74 z^lan@+{$V6KgAz}PKDYMh$C1#KC0(5hMP6iHY5|Y#Y(m)p`%-lyPED2sx$5pUR{bk z63h?Xg@OCnI_!h!pu-ZH@4SHdP6y^(9azgpU=44;y)~u?XUX1|B)&;6j>Ws5EM(yh z*dJrCX4d({-|H|>r8z|?5Bbaw`vG)*+Flqui}qGY!;2Z_MY>ag{TDh{ac!yjZvO@J zp}3fT)`0(@yLF;EV{qFAMGx7tUrujLAIwz3&JV*`t7kyAQ@hnyoE1uxdyQyiR^k4| zN$63Wl=g9`8~jT6HAvsNEvbAWSM{q@Z}qR%^2*)4^L6DP&)1fRwZ#nV$aXZ>WZRqR zEKBFjnMrNZ_;O|@;XelYJ5;BU+iHXva7TD+g*e1>t00%~P6q3J1oh#oGg_I#zh+_o zxaj+(m`e+3=!Y!!JU>CbROi{P8ZZ8_B%)4TPieU|CAzK|rKx!LPLaL3|I=-{(n#12 z0bf3~BZnz`5q6?1UU%6(FO!$TY3k!_arNqUb$wTRx!xq#=}*!=2lhC)y?CqlkCF*4 z)klSQ()gfX2Y+$U9|6BB=-0!)Kj@Ev-xu`9!QUP9$HO0*f6MxxnD2RU=5&W9*1-Tx z@Fq9W#N_-b?BKukd(wZvxOImIhVBUs10T8kntJG)$S|Y_S_xfG(!X?$+b;KW>XQWL zgswQ=R9J3<&Sz{6*>njjGrp&ZR$yMGZ%ZtU;+`&vhn;Nb7%AF&9zGv+Drz9!JAdY6 zX9RTWBkLdZ4zH*C-CAB-zr(AmXL9iFlf1XXY|DdO>|75WB0iuK7su&~^tearf*tyv zZS-cZ>sQe09gyL%exW&XY(YRS{GI;8o0vxIqw~2&zaIO+IN@<>soqfSb;V;ul ze~0j7@~=%Rb%BR4J{A-M#}886wY1V-BJ2uFd$}w#D>W>YLH%hzj&zKoAx}w9hU9->UT*V1FD9eU!r;9aTc;Cc z$M_CqI)RhW+H5V16&OqohFPy#N&#N>I_=r-e|FOE=GO` z-*+vj#axWVJCLl`SHdpxxhb3mo9^XkBdtxp#TvkhJyOP@U?!m*FQffU+g8Z3kM^6t z)Axa_^JxdjKDrZYVK4SR4gl^>|H*|8G{!82Pcsk+oRK|g-KoAidYOr6s{*(S$M_t{ zS@aBWZ^a%9k2Uh&p&KVProkRMlUKgHqkwezoS)PRJZMJyy0jjq_2P8YEu>dhjB#o# z=A8@he_`++<}*X-Rh*kKPk|59*+Ra^u$e6qVUH_1m2`P1k4^tjLq8#qpAq>LE)VFY z=wZLnXv6sxuf9ojdzA~*!{(Os?Ne6@_UO~+Jcm2VuY&G>#GTSOZ@Tz87pZsN(tmUG zc9WPVRpU(yX&4nKh^Cpbzp@!H6xugD>t)dONK|&O2Q^y=`zg%xPy6*{pEE0hi92P49*a`;pEeY0*+y-%>FZ zkCeWoXB}bSA%#VGvGeq`f|Eehwyc2;>wG2(TI zXBX>l{!D*rnF?o!%p%QA1#BrXu$6S>+E)dmgLO?oyFvGSnVz553S$wD2&Qex>nM=% z)K@DQ5zhp1_e?O}d81a)Ab#zcj^$hPhT&|n?v>;@eFgDp;c10{p)*zfpuDbc93=9dy>RdLqOZKm*svFT*Cy`(AL{*(F>n#<3-c%>krLd}QB+??W z_s)f_yh?J7@^&8CA=uVmLESf%9Jaot8l8Jucobtj+gdBcqQ0YTu@|c*N2T_IXGSgk zweUP-(+FSezyQL^<-Zobg3Dd9nZJNLgSVOKU*`w0Z|bnG_a)+9@3EN)wq&KvOyOjN z$=zQZ_-7B^f~NG|BAfXZ+&}sQZbnwX-PdHp-Q|&fmG^K-632?+em>FmK|ymerz(%^ zVv~QitRsMYIr<(~2FvA&Q*i%3ksDcty-&f5JCEY|RdqM8cO$nQ z=T{y2qYKvLEB&`t#FR&-PJ8wW>}e>$Z)@{4{)LLzUe~JpOvXP#GI496gEPS_pgfaq zd50a-Q_3UU$oj*dZc6UjwrwlReP5*ZyL^9q^Xpl}=dkJ1-I@6V*!`^H&zxt$ zTg2-}&<7dcK4}c=b)0qul6|_HcG40IKAWq-gA-t`3<_7z+%wz0_c)uV^ z+5PFsYXv6MU4e6cXIflpH^K`L=8KrEocTZXOxCmgDvVuAGAs}NB=>`W%xPD@IfL5n zohlM<9@bal?*Fs>G@nlDW}%yD5+lH$Jn>~0Q}Gb=GtR6F@aDoJeXtX8PJ9t{Q*fpM zf?-bV5R4xT%QJrfyPF%^1O3L2ILLkK!_IGO1s3Vy2+RG;yF>W;^sqb@`F;uaTi`*C zZ`>h#j&P4`yVJCefjw3D1(xhCqHbi1fNaDhlKs}cy}va{q3;}A!A?gt)qs1x~3UT1}`OD$9(Zz_jfUN>J2dnAFf@II}M>D_@cl+YLDQ3l!h z`#n+s=Vc@ z8;bky+E!emhPxc#5BClUJd9BefbZxK!dyrnEl20t|hd5io>p#7?gDuL)1qMaJ!O$g^E z)RE|?@c(!IWpQS}nUhMXonEf;4&GLGsRS$Vrn+5OH#Fbx@V2T%4La=bB46#U3oZl{B=ExBfrMXJT=nO&YmAOXT{%7W0sPwz^~r^gNd7 z%6sKM zToUy!czpjh#nwIM5v7z*qc!UT`k!ek?x*l7$V7c=>_*Ci@^m6k>L&xb*sHAfJA0%g zrwD$J`Otsbg8ANC=lkKFgRR4_N?_~0K^aT!zJm27$|xcHSEK%f@5&EB!;t($JdH(P>PB28 zJ68AB?>6$v!`gPaOowUfDgm!gHOe?7x9x)|E z$6CNsJ*rWUr=#_~0bW{D5{3Sv_a{iPVWwUs_-c>WepjCf<+aB=avkBC^3pdX$o=rM^@jKOLk9p#qJaqpe549C*tsq~KJi52v#33KdqhPDA?v)*=%lOoa0bkr_9Kw7F_w?9UrQA2h z%XyNn1m&s6f0rywMUpN+TgvBEyr&T82fSI9BPc70NzCPk%t^>L?;gyb=>LhRQ|#oM zlVyGl;*;XFkR4M}Z)_x z{W!~_w@#>y)L&^#9iL{{IJA#aez&lPRf2iNP~LlGh^$LQUN-Qaon+mu|0(YU#+g@! z$U4fm68Snv*7g1WA7|+QFxU=|`ylvleCo)5+Xthdw`kRkysEI;%`bZ$=+k%iLCSBB zxp{p^UWR1Dy|i_6HggnsZwkrHd-yJp$Hes{Z);GeP#z&33&^|GB_!iWzKjU_s@G}B zGVhV+2zT=t<+VQ8zFOqBV@Q7Y%9#<+#fpLaBv}(`r<1pv_x;OuE?fWa##I&Sr$ImX zS8|l(6$75>md6`5Hqh>q8)z<}PwkiKKs;xFyrVW#|F81$ca0CkdoyI5Yt|9I#;1O9 z-@f$k@J)L3o;PE2U_%M}))d}xWzU;* z-@V(;2o&DawdYN`(@p+Yy7#RRgP`|0xi^~-*!z?QUY zvx1t}%!d=qTllCJkWludVHo%;Q`tQR(#A4y6jyeP5uRdzWm=)H&0(4QEO z_Cb!zIB;I9e3Q!GQ5l8U{4b3=+GLP*303@Cj__WqDzKLG_&hg z^L^M;nbKPXm*$H!zmJY*W!u2&_+;~?ZL7ipCl)Xv45J} z#!ldUvP~4o^*S*LamH@!&&8X}-P?-G37+*O4P3(>C+Ws2u|B5!yD1ENu@ojcrg4_? zbWTwoctf6Hm|6Ps^oBf(y>}ze)HA2g$@WL0@t%efW7;%t)z+m)4DQ2>-f`W+FnxBu z^Y1yR$H}*)P~4X-d}lqy`CdZZUKDwYNwybl!oCZ0YIA=#-mxEnGnJul#WP-J8=Z|X zW`k_|hxQgi`_rxjXFS;iknb(voYI?X^}Gg}-Z^_DeJ$*-)BR1dr=lo=yl<)&e}MXu z%?1|lxlvpy_Uft4-P^{=dRx>+vVoEa{;MLpCCEdzM801T9C}vht_2^ctdtq|~Z_5SV9FmlG&A0%3)wYs;{3D`HdF?GIH*<4?3+#huK^6(!q(GUqtvbt zzV5;c@Fn8}u&x%IUBIsQV&Iwf-W(?n%~9bDPepAD>d4W4KIz8?bmMVHfX+Nx)HvVf zXV&2Su9@h7GYdcT_sFgc;Z@O8Bjb8MY}m4Ri#r+l%lL-98){S6koyNZEHXgXAihu+4)mb*26$F+liD(3((HBNB?<<6heBky_FBy8JsIrz zm|e#6K6n3|jshA#ogW)ZS37W4h4EsDoe&;>0<=8={yfsA%;&8J zxAHvR#=$)cwuh-0LG85~yOq3gzzANYuo7=?CpBAlk=#7fqt9mjco(OcN0=>3gUs#f z)@M^&S1(}eFVAP|Q{pC$JZsVFdrq+RR;$MU2k$by&8G1udNpNPSsFj~f(zF|H*2DI zf>pVZ?m;`nCB~()ohuEWwVUGPH-+KW;2og}-el2k%tktF3GsG0oorweoYv|TlVP7~ zs*&tu!R`=m-Ms<(YLpgtG5}M$pFUp7swZrz`+d=;&2Gc8%UWK<5R^cNVKxxUrG-Z=hJh0d#`s6fTPD>4@ zxw4#MPxE-_1N23)99y1ZA1^9e#*5T9=?(#FG2I~9Px(zoTZld(S`qCsFgHcJEUSa` zS_FN{d+9}SL@#phM=y#edXalSdaVO4DUIkQ=W!1|P#n>UT+My(Nby7~a{m>rD2-?( z=W!oeQ9RL#-22gr;)zz|YVSiUiYHo;doQghj%Y>hy|kh@q7}LSx3nTyq7{wjG$zU4 z76r2d`}!ESw~~Hr6!cjlFc(v_V{Am4ic{3HlTtol1l$papTXF=`xyl@9C9WmwdhAA zr?r?%QTk4t>#j#wgMEh|psYwA;_ZrompNt&_RP!T3n$;8F(tx_`+7wT?5adDx9wPq zd0!Su_FqFjk@FM-h3$A-yXb;2e6C{PuX!f%-7_ZG#+dCXfnS8by>)@7J-5(fd{4@p z1-%NZcOJgEGnI3;XY?Wcwk7Z$b|bIfZ9FPvQoP|qlQpnS z^E!=fcmvt7J!8Hc#~^Ngr?FMad}X;wY(<k} zfoz4}3IAE>jWwdZgzE^(2k}Q_m|31r;Mbo8j#_g8Gh2qyQ$B?zaRK5R9Sb}j_HLvy1IBoHzA|4ifRiI3yhtIK{gt9QFWwCvXFeew_wSbsh%=lq?0P@1(342| zZS%KhG(tb?VTaP44*N=ez$E1=-OcZ_QWNYbDUTwZSMF*74Ec%2yX<(koA?`HC7-mb zHJCnJO+On>XeT9v{SuM$M;aL&1RlpBQek+jjArU>;2Ocl8|v?6-g+{w5d&r6C{H5E$j9 z{Sw=Qa=28A5#=X;gdFZh{w67L~lEiQcSHS1r*n)qCL;`dB;+y~=M zmC)Rs>4_;l4;>?;h1cWG1;)(aoZi1vV1xcdZr|1zq$!_>F5eHmqS3NF1ZCNz240`) zjnLB_{m?q6iq@2v(|U7x&qf=Q&w8INiS;shF+N^z{5P;mgRu2M8#)Z$eJw$s+3qv^ zAad*oylbJINi=3LZ&YUUySnGI<->iF#Mmm!l%S`wODXSz3~N+KOv05@nQ& zZ^*TK9zZ_xkxv`)^ySX=6e9f*q<;Wic0b1Q2X(z?yt&If>J=)tIV`hxqm{`g8-~Wk zbrN&roYbEaTmS6r*!tvzDUW3>)cdm+=>4m5ri-dRL*_)>&7JH}xpyLb)<0c*FjwVH z&QrOuzLaWh)A5#>MruU6QgLUu2;o-&D@pcu{dw zBV9xthXJ+$^Phvr`-8UW&_Q43nT0$aKztkQfi>dp!fQ)`lheQ@*02p|ix%NaXsaJ( z(7x^@gl8lD2=e(k{LjFD9QpV$Kbah6zIq(@HK^U0x(9osE=0ON=W&Pn_&KR}PHg?! zd9n4ye4QB9FkQ4c^!}`Dy?<$H(zz70Wg_aYEYW0Y+v_9~aKJ!+O@p%>wojKy@`~h$ z-H`n@$&qD7{xH8F%)c~x(OcGqVg6Cz=TA`=)d$nXqgb2Jzgq5`WcUz!k8q>mPFOZw z3_o2bWy7_3O|t&|lblIR#oFyC+D+{nzJ5xE4tu-DFh65fM7XCKABpZ;FnJfvUBcF< zXPEF`8}M=r{4xyh42D4;s15jSUx0ZF^l$&tI73{rAi^E9Vz@h&3%hAVxnnMbx#PGG zOJ;QPCN?kbGgaQQ%Ws=M&eib?E;Ia+%Nj4vste+-hn-}vD{|TE-F{t1e>2`+D6z^=6!Xd7xZgIJ>s7>XCxv0EM)Nn@YIuhov3-Q zPCA?G@Jt3zu}?>3Dw|Z&mkSbiCFN<|W4Ns)>`|5UK&}>VooitKf^|=DXx+o+;mrNB z$V}x5#?2enyrozX@6KJoxY-Cm&j#l>}y>{cxv zar0Ne{U6N395)um*1u+lOlqP2X!rCuri(24E$N4+q7To5zZEj63osF_BnRezjtk*aKg$!sV?QcyBrbcGB3-7SCec7n?Ig z8pFKBiRWjW56_=M{CX1lu8@I!pzrg@XK{hve+qt8UuMR#C3=6O(PyALkZZYVqPp+< z88o;4%Ghu4qpuOY31@3@ub>6-ut!kU1UbyLGR`YEP}uD#LCZ)E^J889hGW4t3J9`cu9zBGJscxvg&VXS72FFv zVL2x%`_eOL9ubLtRfV>uLJl;dAJ}=7TUC;ok?Nf$PRO!<=0{vu$@eoRqMn5N3B1}Z zG@u_eskku~wdC>hmlEF{Ie-yN8LmR1F9psxI zYoQ6*%FnvCtuNcz8}?6yMeR;mp>}s|TU}PwtNLfkJjM0YyfC+_Z%k$q#*3nDtIBkc z*UHwB((5bKo(zm5%ElPX!&Gh^SF<^+WJD(086!RD2y{zZ8dl5KZNPr?eQ4^}w+abDN2i z=AUPC^DZ+>7hN6&x~or~lVb8lUDm9~bFvt(l?&poD?W(6uFTe7AH8CslVn27!l@rC z3SzInhCU6mj2+Wc`E#oaK~wYz7JK@trOPjCau;6Kapz!{w@y?q8+Bc~z<8a~8Si#U zofCUq+o`{P$)D2Uz<)&V?~gUloH+KOnF9XF_ns4r@gMBm%kxJA>Ph#K>3;IlG#|mf z$|2udz!7Y)gZE$e!w<5qnT=B*ZkbT|ZqeWbSu2I(}%{UiJ|w*6*eUE^k}fu$N|$Z5t%Sb{{szqB$UY+D z>nM=(U9?lUh&1*z($K$>mZpm~_(L}RKWzxWIT!B~RwB(6ggXGge+b-}ARMz4`5}${ zAei4Wp?Brim0co7%X1r!XFI^ls;0f^p9Loq_^mOgF}#zgjv9 zlHjL3ZkqSge$%%l=MKSc>MNv|{qRD(s|@~na4FttK66g`9{4LXhrMH~9c`b6J6$I9 zCE7chhI{2ME?tahXD878o6)J(2N>LsPU}^{-gQE~sTey^=&Ce-IY6_!5&{}s=R zsV`p;Q-212l5f7$!Kba}oPc0>Je3d7aFC4Ea4cLwd4|8lsqz!asG;yg)kCDhCA9q*)=kQEAfikeK6UM80e&YL^q_rx0$X>0&rWvSd{+rYUS(t)8 z;6@s)y{VribLx5*bZ}^|!(&U3cDBHeK0if_ zE}jLC1Fjfw)VC_(e--{vUziz$b8bR@XnPXcOZiR3-MI$9UZVek{WTS^8JO1*jb4g= zG4N)eVXr=9)0SD3+(PdT9%!huo7x@|m9X7I^vwZom=2}%HSUZ}_2Nz*Xs9L{&Us8+ zca&)8@U+Z&OuTyJF;VV=g*yeuY|!*wq6_ZBf=+IPC4`THE=S=11b&+Lw*vpe5l%w* z80xLdQujn6--nU!ajc12uqN7x@b3|B1N;%tlHS-*__YJgn16&@RXtCjej1+bNy$^Y zms%2Fi!%W-RgJeVl#K{zGal#Dio;PL@Chw>}hDY%e!0BIpQS`c21aEOjJz|Mf(c-E@?OocHs3v_=H zbf_2C=RGFgCO_r}N2xy{ukpu; z78Z}rrs@d;?0+C{qQz0r;$iw1_@nh|1h4FQ2Dm3WOgy7{dwRw)E9mX-Y)|kLVaO7!lg*3zOWgvPSE7`k53eAL!Pos zTMzuA{@tiQ(Lss2C!_8m{PuoxLY95ZQ=k{pijgMM3;tJ!z?}@jIX6P4p}k3HZ-@>J zfW1Wj1!dab0o#nbSd6XyS{SFuIeQk|ii zLwk9Fd)vmAgPAii=TUNe`4o&-qmdWO9Vkhm@zdwRy_@2)sk)c@Sx#B%Y%-X;pl324 zZO%deaxE#U3&VVia1su8V8!TilAXVEu!Z_X#r>qxAn4{z$B+vgaxNVT&HfmujZefpJm)v&K#RPKy@r%f*|W96oP2-cSsO zP9i=Fg*E143mqXh#d&*Yr8~0aDT~$_dmA|M$tJNxjikm&L*CCqN<$s zrBybzp5W6OT@u}CyncUl>oD^@nR#JFZ_C;1})L+6rr;^3z^c@Nx=w-3CH zCCc_jw|wS<_+_vuAm`z8iMOp$5i%co8{HHa6Uyt}G~`KX)uao9J&a1+(WQ0mrcKa) zZ1)JX)>{j|y3Z{H-ciPTUneRv=&j=`EwI;e3_4*8D>ErA@l>TmY4pa&RoDZkI1Szt z3-h<%Vd$d-n}~bhw1+GA;iIq<$X!xs zL1&8lCHf=iqg8XZ&TYb=;x_VOxP1x@(p5(*Gbx{Hocl)MKPpd!yV--=u4}KiM3qP7 zz2`O_Js`sPNC-gQYj2g6`aEBp}W zw-Jk68C{q!MJ$ZirSPZAXKHh1;a+~n{>+GZu8a+ci*U@^eQjHd5OX{b_lX?$)NbgQ zFvE~fDE@~{1pDyrD6~5i*M&HyXk+Jb$OVd{Iz-@|i`D-iMIgUf zUdK#bn=3>2p>CJ%@m9C7ZGR?(2Um1yKe0P-W{fa+R$DU2e1`B`yjdB8`cfS9YO(j= z=#1nd0&ySWKiu<=LY(o#{h6>5BjZQ6+?6p2^SN#4SE}sr^SH~Y=xx!JQ&`8%l3|D8 z-)-Eticjr$V*>x`5Y{fy?Iypr6MY8%4Cm~f#?C;v2jP!fwB_1aE$&d*1RTp4z}EfB>GDzDfz<&)q)g7oZJlkTLqAWpMbv+MV8$u?5W ztl4s!+UCm01}_X+DwxZ#6LL8_Ww+74Ka=895U)O^-gPiLTaHs%T^Y5AQ)O#+8yoj$ zQg|)G{%nmLUWNJce#mWx>r+C*=REo~?1b^2E0Ehf@J?eE&NFt`!tY1l?s?DNx%4?U zpW2z)QYFE%S^1}Q-U55f|FG2AjlMcN@ktH%!-X>>!gUw;jLwlxB3~L4sQ+A~{_`V@ zkAP#iD+;BT5l*(-JZyfD;*yVdOMl|ouV1RehePaQ` zHn2Bf9}9GRCzI_!_yoI)U5;=E!uXf?;$!G48b1t#l}lLg#XFe_%12n)X>5Kc(+T~y zJ9>tYY1<)}N!QTaKUh$*33e4A_ep;=8hbt$;lH0=qH18UfZElAwh|20jovw?_IE=U zF&_NNas}W)luc`E$S1k}R`v$9uM+rxZC1c6lwsJ$KwB8}9hO_xX>5E)?vs_k7qyGl z>R+KOY9HnA+=l%WE>CXfnIH^%iiJMew+a^TCsCV!hVfp`_m-)=+rFgp3)C|P`TiMg zq`d$mUnl+pV{IPCZLv_A$HVQtXd7u*XRa)5rRU`T?Y;n@OPvupW zPbdQa!#|BNtWy=Sf(1H`WFLawIl;Y3`Mndp-z8C41$|Rh?l?hCgNz}!isCjdmE%;w zI2B~krEM4FIFdyy-6cU8IEO8#_wE?zRN#y`kIG^3ZWDz!Z3x(j@NIZZ?70@0=T^ag z5Ps^j`uGWEde38mS6v_b+~9J#|NEUdOAef^PJ>;b@iNYW@6*sf+2_RmCcLeJ|4wF| z6aNVRKDb-pGDT=J-u4LXebN3Gi}MeGBe~9OEyq5Xcj;TI7;c|Xy7-**EcU=CJPP5m z+;h_A6X&E&*c&Usz8Gv38ab}2?6M_bbBoS?suxXr$Ijs%g72Jk2=NcWJ&JYdlbo$Q zoj)f%OktcAB;!6!8p1Ohuot_ow&eTpPemH*I4?|tKQiwv)yutj9~^UF<>sA2ucJ;Z zfNk>>j@4@fQ@!1rYFFCBdTMOh&A@NH#@k$?y<*Rp$ZOrqk%JP_MP*A^Pj-vOpW@9H zHQwy<6kg*deQcV~D2^YL^uSve@(s7ZUen3{CBqNgD{Tci1#a7lo6S&Acje3{3GM<7v9_w9tzjGtv8J|jC7d#FBGf2yT zy8*5l?qhH{qvdS{U~Ih6P5W~!>;o-^&4=a|*c&wz>uJtk6urjS1YI9`=Z*LC%{TCl z%?#f#J+mmiB@KHuRCl)V7j~-S@Kogk#f_{#X26w^m^)mrDwB?a~!Q?Qo+J26m^pz)*?;}zK|N`YSszPhyHH(Lpp+9qASu1z;E z0r-!^UZ4&07^~MlGaKKR$eZ=HWKDBn-YP^XDdv}l@m%f2b zFTB~7#NlmQIiIYVUkCpmk2!QL)+Jr2Bjy0wb--)iw(C)AQJ21L-$t!Ln3dlhh2A>+ zJHex`Ho(>$>R-$q7sg|bRn^1@ZIB^Kemm8aAupRGA`bVJ-wwWr~ zh9=nwg!@Ex~d7*FVgH09e zAD?civlIPQtF~=@60n09GrKW{DsgvO-K3S*WtuFlyiU+IXzK^(4@UJOo$`u9UV7M{ zfGv)C*s@^q`dHH=C==)M!Ybso0QADTygm*(pi~FE?OPuUKRf?c{Rp@Vzz>u@68;A0 ztt;p56WG;pZ$F5zifepZ%~k%1EuHc9DEjBeGY%(W4Oo_{EMnKqI6RrJlQfOkUoVaO z&+oyn^Vdo2s<^{5;GabPd2xqh&_?!0x88~-clE8eFb_l7!dnKoe?*^TA7Gzy@oaq* z@^@{Ddnc00DVy=1W5`{6=J05WUq9pRapZ28@%C79SH-Q8_k zaqz>IvEGV)Lb8JuD(e{EVR^5I&a0I0)1C&~Xq2FLk*Dw(rH~xFL9#@zbC9fIOJVN` z=eCLXht7JHew^jf9-u!~It<&(EFUX{lYDL8D~}^ej3Y$Xk)SK{QKiIVelFt)b_+hA zGG+f~#_Rn|bF7*44p{EzBHzxBxAA(nEEA)PbC=O?|sPOU&Ds<%h7fHefSS{r*E1#y*Ll;N&IN9REYMOii%6AeK9BAkvvNw zUq8p(2yg_Gd}=S+mlkN>ZCBkpNY6!l8pfC3Edwm(w%vml&{x=cCE5y^I9`eSJG9pN z8oH8Lt1V|v9+qg#F>x%tFPHqgJd_FC(74rr`sqPm6YQ(WeFf(@a1le`+K0ehLHP>kmVJmZ@JrOoXL(fY zX?RrLpR0oZApG)q0_GmEurtFfjk(EkkBUj&0E`X(HSiM*+5EqD20Vf{ew3Slx22Sef{#BwKEVUKo zKQyEs>71cHRF}U3-&7y!XAbv6bT9kG(mo^hCj*(07^VV@g@rg-UyZ z$=_pqEB7c|xeUO>Bd=-D3k?4s(9H^3tp=^=jt0?i0{pVxA@CS^AG)~_7oywV{{h_= zgYJaW`{BMGX+O(HyYE9c?*BlyRQ&rYa6Oc6#7nl1z)x_q?x9<^%rCsmFPrgi{*ZEq z(urh6h)$b{mY|b!Q-CJUtpS>>eLO%DHbfJwO{w3Sah67O@j)hp`tpXYf%CPipnDD% zCPqLOa9mi~gXphe=+j|cm77U6T(!^XWKJB0Y_ZQ=?6v>Ef$==dTPsy?4koWR=Kg~-S$Z?YEuNV(t?rD^^KL`6W%q94t`8(n?d`u=MUc$c##{0A=R*KIDj7xn=2m)sES zpTT3y2fVq6>W#5Qp66$G3YSr@7SI)IlC2BJEy7(z-m@fOv21I;EV|rCYcbMydd{#3 z>j=BNZ?0Od8dv~a&^rJRXF&%E^;C2F#B7}1$3X7c_!zev<0j2}^(WW#|GP1_4`c2# z{BS*uwak*VmbI;T-!L~)mY-Kpx8WzwNUIWxAe(XKQWR4fn!nTff7%+ngT5s8=5%jt z{guJNaZqY z+BIdy#%6Tt*r*=p~)5C)4=aD|*_>N5K!?d;*;L_g0 z&)|OFJEDFI+-cCSP-E`t#XV#tmnXa*&p)=GPrpFraM-hX;Pl_5#<>QM1#v48PKA!- zEAXq($BS@IG7;$#!eIz+M>qvxo-_DqT#m*(XaeAQi@~3Wv}E!l%>sW?Fn&owm$_+{ z!84vSls^}*d8`@!me~eREB2F27$1CqZ$&r}Wm6xgvg3K!Q^1-!19M%)Lf9tbqJ%`i z(%hH9+&3e;PD(&Jlf(Adml!1*Y=C6h>oA@gF|Hb=%%(btvqHBO;V;m46b<-nY)_)K zPJ9<Y#Z*7@gWDrC~lf8*(YlG5pSa;tcwf!dq4%k4Y7$h5gY7jKr5L?uEZ0rXEGS5;UrTq#fcLeOes*+!o|FwAz8usf$W6sHw=mWXNn=0f- z^96PQZ}^Xxlm%DWxKEyUy7-qwnum}sIt#j0%6FT;)2}Cf{N-61 zckZvNzWFrdzdTnn%JT&}U!*o+u2fM)_jWNh?gwsE;1fDuq`EL=xE}zXa_~ww=U2uY zihd3K5qiJe6mhb5iWqp?6K@rFnM!jUInBiHI$x)7wIQrL(Wlij_6J&G!Q&(&BN|__ zyFcBLLGmf$3wK?_QT4#&Cb#&8eayv@YNSnsfB*!tw6%dWgT-2@uv1iU)7!Uyg4S_xpnwe|uYyvy=A;jUL)-W_) z(lS2lXuG!6?oQV3_T5k4?Jx`%jTAvm$qS;Sxe+dtZ5KDb&)0!5w@;tX=lA<#9`E=2 z%sKDt>-~Da?r+~gxA8%&5zZZxfHmsf?cOot1&My!K5N@e`fVH5V=vLt$0Dv1EtJY@ zJvln&{{N{SYUju5T93M(nXD^N&l!VF8XJv^_Obx}h{j&;-HyA0Uk|Q;{NMx3xAr@G zYm$&ZLcYQU9j&f=a2M(_k$q-SR!9`_pZmrmHdKJ;jp`MW+A-&H-r&;0=R+YHTymd$ zMBbqo-D{CMuZ@qdJc&E?WQfZM+fv86OH9e^Y`&WIg&uu)>dC%RTHmt^`IJ74H{#k; zs0*?tORMXr$6MV=+Mh&_pLe?$>lrfCb@I^l(ivOdz8!PxwNhXEPyMpBl4l1gudLnG zS_GbOK5vMKI3@prVkWT5mq~VJC%dAmiT7jkx1A?hwhOWjyEohuhk9a83P}S`2A8~W z*M(H|BVu^nm&~_)==TfvTu3E+O0-Yisr)qh?sR4pVxEKd@PQ^kf9!`_T}I3gtx+!8 zmfAeAjAD5+?DB2r?a%t(&%$%+U*m(nY^BtD;+L)9NhN-e1wLE?c*J??$ODd{@eQ`y z`RwJO%b{B|9+VPbg<*NJ{|x61Ti?%#YbHcWtaVtc~|`FQ2rUp ztM%+THSf2s30^+WsOQcpmJIvjvOn<$iDTAq$SPG9);5#{872Ceqn~~b@N_PeAGSt| zqt^NQm~*kFAV)a=m9-f7HOi!REX6m9wL!KOkT1y4?lk;%mu99#T*^!{U=Eb9aZ(HH z^_G*FX>rJh35h2d6iq3 znpLR(DC(Vtx)7V+I$gv)0VYm5dqW_5Py#mY0*+;}m19hKUG3b#S1Q$r8^5{m&UffO zOSN8Et^}>dOzOh5B2&DTS9>-C&uaM1i1)k&dJWCxF^p3!K5kX>%&>8xDM8&PyZo1u z?*6)xEq!5w%F3Q`!pAK37xo3l6o35p?%C+u(!+>9l83wTaK`4sub{;suHqt;vKPGT(3A1o%y|L^ufU+EW!NMib+s7^g>3FEeP; zwJ(Wv>Jw{A>b`7GqnOM0@o^rq+oL_Vm)}t%V9v>Bn&ppL*;1V61Fi0i^?jujXI4

    Wi`8Ixr8oQ@v(2#zk=KT_Shx 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Ë}s*{Dw@ZX}yI3-@zqX`{`o%T^Wvx`7A%9yq`y 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 =X-sGG&X7Lu(|Y`Q+fI9TpHJzF z183B=_)F`N_vy#>&>C0QzmQJP5B&>_S~3Qm3XM@V>{Iaani^J~QOk0iwf$HdyWHH_ z)9>=7w9ljOzbB&{mGuJErCeF_{=Y#_i}6Sw>EGb#B=^idR+3pj`qwtaUN!lV zE{Eh?9_^WAaO3-ilRU7K1YL#$dyHIpZf!2)Z_-yXU-jTx=wS0M_|B2eXIxak*x$BC zNa7(w`LxOQn8v@SmLr{^(bF~jhn|$?6zr)6o#4|f@^!c4FZ4FmaaCMxxJT#= z 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 literal 0 HcmV?d00001 diff --git a/feeds/wifi-ax/ath11k-firmware/files/IPQ6018/q6_fw.b04 b/feeds/wifi-ax/ath11k-firmware/files/IPQ6018/q6_fw.b04 new file mode 100644 index 0000000000000000000000000000000000000000..3113c3c7788f25f3ee0a2224aeaeb383f6f3a792 GIT binary patch literal 459904 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

    ;2d|C+g~;t8^hEvT)heH)b;^oe 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�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

    S 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 tFhzY) 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

    )OY-#I`yexjWljs!42nA?t&6 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 U*{^3MT!TzP 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 F{9itYEU5qh literal 0 HcmV?d00001 diff --git a/feeds/wifi-ax/ath11k-firmware/files/IPQ6018/q6_fw.b07 b/feeds/wifi-ax/ath11k-firmware/files/IPQ6018/q6_fw.b07 new file mode 100644 index 0000000000000000000000000000000000000000..c5a21cbf311d3ee22d8d5d01c5d5c050ddeb6ea2 GIT binary patch literal 9320 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 QKvoQR#S9`kQ;kvo2YNVq?EnA( literal 0 HcmV?d00001 diff --git a/feeds/wifi-ax/ath11k-firmware/files/IPQ6018/q6_fw.flist b/feeds/wifi-ax/ath11k-firmware/files/IPQ6018/q6_fw.flist new file mode 100644 index 000000000..1746604cb --- /dev/null +++ b/feeds/wifi-ax/ath11k-firmware/files/IPQ6018/q6_fw.flist @@ -0,0 +1,8 @@ +build/ms/bin/6018.wlanfw.eval/PIL_IMAGES/q6_fw.b00 +build/ms/bin/6018.wlanfw.eval/PIL_IMAGES/q6_fw.b01 +build/ms/bin/6018.wlanfw.eval/PIL_IMAGES/q6_fw.b02 +build/ms/bin/6018.wlanfw.eval/PIL_IMAGES/q6_fw.b03 +build/ms/bin/6018.wlanfw.eval/PIL_IMAGES/q6_fw.b04 +build/ms/bin/6018.wlanfw.eval/PIL_IMAGES/q6_fw.b05 +build/ms/bin/6018.wlanfw.eval/PIL_IMAGES/q6_fw.b07 +build/ms/bin/6018.wlanfw.eval/PIL_IMAGES/q6_fw.b08 diff --git a/feeds/wifi-ax/ath11k-firmware/files/IPQ6018/q6_fw.mdt b/feeds/wifi-ax/ath11k-firmware/files/IPQ6018/q6_fw.mdt new file mode 100644 index 0000000000000000000000000000000000000000..98805947ff5cc17d447ab27691caab93811cd087 GIT binary patch literal 7340 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 literal 0 HcmV?d00001 diff --git a/feeds/wifi-ax/ath11k-firmware/files/IPQ8074/Notice.txt b/feeds/wifi-ax/ath11k-firmware/files/IPQ8074/Notice.txt new file mode 100644 index 000000000..665d813b7 --- /dev/null +++ b/feeds/wifi-ax/ath11k-firmware/files/IPQ8074/Notice.txt @@ -0,0 +1,795 @@ +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. + +-------------------- + + /* + * WPA definitions shared between hostapd and wpa_supplicant + * Copyright (c) 2002-2018, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +-------------------- + + /* WPA/RSN - Shared functions for supplicant and authenticator + * EAP common peer/server definitions + * EAP peer state machines (RFC 4137) + * Copyright (c) 2002-2018, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +-------------------- + +/* + * Copyright (c) 2011 Qualcomm Atheros, Inc. + * All Rights Reserved. + * Qualcomm Atheros Confidential and Proprietary. + * Notifications and licenses are retained for attribution purposes only. + */ +/* + * For this file, which was received with alternative licensing options for + * distribution, Qualcomm Atheros, Inc. has selected the BSD license. + */ + +/* + * AES-based functions + * + * + * - AES Key Wrap Algorithm (128-bit KEK) (RFC3394) + * - One-Key CBC MAC (OMAC1) hash with AES-128 + * - AES-128 CTR mode encryption + * - AES-128 EAX mode encryption/decryption + * - AES-128 CBC + * + * Copyright (c) 2003-2005, Jouni Malinen + * + * 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. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +-------------------- + +/* + * Copyright (c) 2011 Qualcomm Atheros, Inc. + * All Rights Reserved. + * Qualcomm Atheros Confidential and Proprietary. + * Notifications and licenses are retained for attribution purposes only. + */ +/* + * For this file, which was received with alternative licensing options for + * distribution, Qualcomm Atheros, Inc. has selected the BSD license. + */ + +/* + * SHA1 hash implementation and interface functions + * Copyright (c) 2003-2005, Jouni Malinen + * + * 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. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +-------------------- + +/* + * Copyright (c) 2011 Qualcomm Atheros, Inc. + * All Rights Reserved. + * Qualcomm Atheros Confidential and Proprietary. + * Notifications and licenses are retained for attribution purposes only. + */ +/* + * For this file, which was received with alternative licensing options for + * distribution, Qualcomm Atheros, Inc. has selected the BSD license. + */ + +/* + * WPA Supplicant / wrapper functions for crypto libraries + * Copyright (c) 2004-2005, Jouni Malinen + * + * 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. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + * + * This file defines the cryptographic functions that need to be implemented + * for wpa_supplicant and hostapd. When TLS is not used, internal + * implementation of MD5, SHA1, and AES is used and no external libraries are + * required. When TLS is enabled (e.g., by enabling EAP-TLS or EAP-PEAP), the + * crypto library used by the TLS implementation is expected to be used for + * non-TLS needs, too, in order to save space by not implementing these + * functions twice. + * + * Wrapper code for using each crypto library is in its own file (crypto*.c) + * and one of these files is build and linked in to provide the functions + * defined here. + */ + +-------------------- + +/* + * For this file, which was received with alternative licensing options for + * distribution, Qualcomm Atheros, Inc. has selected the BSD license. + */ + +/* + * WPA Supplicant - Common definitions + * Copyright (c) 2004-2005, Jouni Malinen + * + * 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. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +-------------------- + +/* + * For this file, which was received with alternative licensing options for + * distribution, Qualcomm Atheros, Inc. has selected the BSD license. + */ + +/* + * WPA Supplicant - WPA state machine and EAPOL-Key processing + * Copyright (c) 2003-2005, Jouni Malinen + * + * 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. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +-------------------- + +/* + * For this file, which was received with alternative licensing options for + * distribution, Qualcomm Atheros, Inc. has selected the BSD license. + */ + +/* + * WPA Supplicant / Configuration file structures + * Copyright (c) 2003-2005, Jouni Malinen + * + * 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. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +-------------------- + + /* + * Copyright (c) 2008, Atheros Communications Inc. + * + * Copyright (c) 2011 Qualcomm Atheros, Inc. + * Qualcomm Atheros, Inc. has chosen to take madwifi subject to the BSD license and terms. + * + */ + +-------------------- + +/* + * For this file, which was received with alternative licensing options for + * distribution, Qualcomm Atheros, Inc. has selected the BSD license. + */ + +/* + * wpa_supplicant - Internal WPA state machine definitions + * Copyright (c) 2004-2005, Jouni Malinen + * + * 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. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +-------------------- + +/* + * For this file, which was received with alternative licensing options for + * distribution, Qualcomm Atheros, Inc. has selected the BSD license. + */ + +/* + * wpa_supplicant - WPA definitions + * Copyright (c) 2003-2005, Jouni Malinen + * + * 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. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +-------------------- + +/* + * For this file, which was received with alternative licensing options for + * distribution, Qualcomm Atheros, Inc. has selected the BSD license. + */ + +/* + * wpa_supplicant/hostapd / common helper functions, etc. + * Copyright (c) 2002-2005, Jouni Malinen + * + * 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. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +-------------------- + + * Australian Public Licence B (OZPLB) + * + * Version 1-0 + * + * Copyright (c) 2004, National ICT Australia + * Copyright (c) 2007, Open Kernel Labs, Inc. + * + * All rights reserved. + * + * Developed by: Embedded, Real-time and Operating Systems Program (ERTOS) + * National ICT Australia + * http://www.ertos.nicta.com.au + * + * Permission is granted by National ICT Australia, free of charge, to + * any person obtaining a copy of this software and any associated + * documentation files (the "Software") to deal with the Software without + * restriction, including (without limitation) the rights to use, copy, + * modify, adapt, merge, publish, distribute, communicate to the public, + * sublicense, and/or sell, lend or rent out copies of the Software, and + * to permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimers. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimers in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of National ICT Australia, nor the names of its + * contributors, may be used to endorse or promote products derived + * from this Software without specific prior written permission. + * + * EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT + * PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND + * NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS, + * WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS + * REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE, + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, + * THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF + * ERRORS, WHETHER OR NOT DISCOVERABLE. + * + * TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL + * NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL + * THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER + * LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR + * OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS + * OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR + * OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT, + * CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN + * CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER + * DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS + * CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS, + * DAMAGES OR OTHER LIABILITY. + * + * If applicable legislation implies representations, warranties, or + * conditions, or imposes obligations or liability on National ICT + * Australia or one of its contributors in respect of the Software that + * cannot be wholly or partly excluded, restricted or modified, the + * liability of National ICT Australia or the contributor is limited, to + * the full extent permitted by the applicable legislation, at its + * option, to: + * a. in the case of goods, any one or more of the following: + * i. the replacement of the goods or the supply of equivalent goods; + * ii. the repair of the goods; + * iii. the payment of the cost of replacing the goods or of acquiring + * equivalent goods; + * iv. the payment of the cost of having the goods repaired; or + * b. in the case of services: + * i. the supplying of the services again; or + * ii. the payment of the cost of having the services supplied again. + * + * The construction, validity and performance of this licence is governed + * by the laws in force in New South Wales, Australia. + +-------------------- + + * Copyright (c) 2002-2004, Karlsruhe University + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + +-------------------- + + /* + * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or + * code or tables extracted from it, as desired without restriction. + * + * First, the polynomial itself and its table of feedback terms. The + * polynomial is + * X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 + * + * Note that we take it "backwards" and put the highest-order term in + * the lowest-order bit. The X^32 term is "implied"; the LSB is the + * X^31 term, etc. The X^0 term (usually shown as "+1") results in + * the MSB being 1 + * + * Note that the usual hardware shift register implementation, which + * is what we're using (we're merely optimizing it by doing eight-bit + * chunks at a time) shifts bits into the lowest-order term. In our + * implementation, that means shifting towards the right. Why do we + * do it this way? Because the calculated CRC must be transmitted in + * order from highest-order term to lowest-order term. UARTs transmit + * characters in order from LSB to MSB. By storing the CRC this way + * we hand it to the UART in the order low-byte to high-byte; the UART + * sends each low-bit to hight-bit; and the result is transmission bit + * by bit from highest- to lowest-order term without requiring any bit + * shuffling on our part. Reception works similarly + * + * The feedback terms table consists of 256, 32-bit entries. Notes + * + * The table can be generated at runtime if desired; code to do so + * is shown later. It might not be obvious, but the feedback + * terms simply represent the results of eight shift/xor opera + * tions for all combinations of data and CRC register values + * + * The values must be right-shifted by eight bits by the "updcrc + * logic; the shift must be unsigned (bring in zeroes). On some + * hardware you could probably optimize the shift in assembler by + * using byte-swap instructions + * polynomial $edb88320 + * + * + * CRC32 code derived from work by Gary S. Brown. + */ + +-------------------- + + * AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/ + * + * Copyright (c) 2000-2001, Aaron D. Gifford + * 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. Neither the name of the copyright holder nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``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 AUTHOR OR CONTRIBUTOR(S) 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. + +-------------------- + + * Copyright (c) 1988, 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. + +-------------------- + + * Copyright (c) 1982, 1986, 1990, 1991, 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. 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. + +-------------------- + +# Copyright (c) 2012-2015 Qualcomm Atheros, Inc. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +-------------------- + + * Copyright (c) 1988, 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. + +-------------------- + +/* $OpenBSD: string.h,v 1.17 2006/01/06 18:53:04 millert Exp $ */ +/* $NetBSD: string.h,v 1.6 1994/10/26 00:56:30 cgd Exp $ */ + +/*- + * Copyright (c) 1990 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. 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. + * + * @(#)string.h 5.10 (Berkeley) 3/9/91 + */ + +-------------------- + + // Copyright (c) 1991, 1993 + // The Regents of the University of California. All rights reserved. + // $ATH_LICENSE_NULL$ + // + // 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. + +-------------------- + + * Copyright (c) 1998, 2010 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +-------------------- + +/* + * Copyright (c) 1998 Todd C. Miller + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 AUTHOR 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. + */ + +-------------------- + +** Copyright (c) 2004-2010, Atheros Communications Inc. +** +** Permission to use, copy, modify, and/or distribute this software for any +** purpose with or without fee is hereby granted, provided that the above +** copyright notice and this permission notice appear in all copies. +** +** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +** WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +** MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +** ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +** WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 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 module is the Atheros specific ioctl/iwconfig/iwpriv interface +** to the ATH object, normally instantiated as wifiX, where X is the +** instance number (e.g. wifi0, wifi1). +** +** This provides a mechanism to configure the ATH object within the +** Linux OS enviornment. This file is OS specific. + +-------------------- + +/* + * Copyright (c) 2012 Qualcomm Atheros, Inc. + * All Rights Reserved. + * Qualcomm Atheros Confidential and Proprietary. + */ + +/* + * For this file, which was received with alternative licensing options for + * distribution, Qualcomm Atheros, Inc. has selected the BSD license. + */ + +//- +// Copyright (c) 2002-2004 Sam Leffler, Errno Consulting +// All rights reserved. +// $ATH_LICENSE_NULL$ +// +// 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, +// without modification. +// 2. Redistributions in binary form must reproduce at minimum a disclaimer +// similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any +// redistribution must be conditioned upon including a substantially +// similar Disclaimer requirement for further binary redistribution. +// 3. Neither the names of the above-listed copyright holders nor the names +// of any contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// Alternatively, this software may be distributed under the terms of the +// GNU General Public License ("GPL") version 2 as published by the Free +// Software Foundation. +// +// NO WARRANTY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY +// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES. + +-------------------- + + /* + * AES SIV (RFC 5297) + * Copyright (c) 2013 Cozybit, Inc. + * + * This software may be distributed under the terms of the BSD license. + */ + +-------------------- + + * Copyright 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + +-------------------- + +/* ===== start - public domain SHA256 implementation ===== */ + +/* This is based on SHA256 implementation in LibTomCrypt that was released into + * public domain by Tom St Denis. */ + +-------------------- + +// This code implements the MD5 message-digest algorithm. +// The algorithm is due to Ron Rivest. This code was +// written by Colin Plumb in 1993, no copyright is claimed. +// This code is in the public domain; do with it what you wish. +// +// Equivalent code is available from RSA Data Security, Inc. +// This code has been tested against that, and is equivalent, +// except that you don't need to include two pages of legalese +// with every copy. +// + +-------------------- diff --git a/feeds/wifi-ax/ath11k-firmware/files/IPQ8074/m3_fw.b00 b/feeds/wifi-ax/ath11k-firmware/files/IPQ8074/m3_fw.b00 new file mode 100644 index 0000000000000000000000000000000000000000..27a76ace6cec818d2ab8a64626cf0f19603165da GIT binary patch literal 148 zcmb<-^>JflWMqH=CI)5(5RZ|Cfx!eO2&7FI6o4`sNFoU46a`nMh+7{tZjB>6OQJPmMu9Ex%@)4w}5`g tldlUwYVm=ycH!c2yo*nzzO1N>*c@-&SNi2g-ij2N&1L^@P2bC{1^^XhAGrVk literal 0 HcmV?d00001 diff --git a/feeds/wifi-ax/ath11k-firmware/files/IPQ8074/m3_fw.b02 b/feeds/wifi-ax/ath11k-firmware/files/IPQ8074/m3_fw.b02 new file mode 100644 index 0000000000000000000000000000000000000000..9f36236a37b9bc5f2c3e10fd83c2ef388f0de6c1 GIT binary patch literal 327680 zcmeEv4SbW;z5h8+o}@`BZPFGf2$=MR7DP-7B04snq-|QTkhB!2iX(kNqT@y1Ft|)3z=BlD&o6Z7y#SLu4ZbQemRJ#p@-P<`ffx7MKLz_LkNdDjRBxwWG$<(`h z@8^F~&in8De!ufQ?=J~*L?l!sWIoL0|Aa9KI*q=I>IgR+1KtMyZ?=I2ikbXMA;c{c zO1-P(bxx;uz1J=45t=VQ9=SsP>qq%=0o=$(mU7Z(rt6Q&X+d>HXre5prF8u5gfZ~9 z6Q;lwa`?x|3F+mbpjy#`)b+Fh>FXU0e%BSU{NuA95HkKSC82Ig_=h9F5#R`L1ULd5 z0geDifFr;W;0SO8I0762jsQo1Bft^h2yg^A0vrL307rl$z!BgGa0EC490861M}Q;1 z5#R`L1ULd50geDifFr;W;0SO8I0762jsQo1Bft^h2yg^A0vrL307rl$z!BgGa0EC4 z90861M}Q;15#R`L1ULd50geDifFr;W;0SO8I0762jsQo1Bft^h2yg^A0vrL307rl$ zz!BgGa0EC490861M}Q;15#R`L1ULd50geDifFr;W;0SO8I0762jsQo1Bft^h2yg^A z0vrL307rl$z!BgGa0EC490861M}Q;15#R`L1ULd50geDifFr;W;0SO8I0762jsQo1 zBft^h2yg^A0vrL307rl$z!BgGa0EC490861M}Q;15#R`L1ULd50geDifFr;W;0SO8 zI0762jsQo1Bft^h2yg^A0vrL307rl$z!BgGa0EC490861M}Q;15#R`L1ULd50geDi zfFr;W;0SO8I0762jsQo1Bft^h2yg^A0vrL307rl$z!BgGa0EC490861M}Q;15#R`L z1ULd50geDifFr;W;0SO8I0762jsQo1Bft^h2yg^A0vrL307rl$z!BgGa0EC490861 zM}Q;15#R`L1ULd50geDifFr;W;0SO8I0762jsQo1Bft^h2yg^A0vrL307rl$z!BgG za0EC490861M}Q;15#R`L1ULd50geDifFr;W;0SO8I0762jsQo1Bft^h2yg^A0vrL3 z07rl$z!BgGa0EC490861M}Q;15#R`L1ULd50geDifFr;W;0SO8I0762jsQo1Bft^h z2yg^A0vrL307rl$z!BgGa0EC490861M}Q;15#R`L1ULd50geDifFr;W;0SO8I0762 zjsQo1Bft^h2yg^A0vrL307rl$z!4Z8fhE)JS0|<{sc_|5426S4qPm21Eu4@ZpaDTlNY}y%=`sHF9R3Im6OL)nMxYE-ic-Y%IX4_l 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

    7#TQz@Zet)Q+%igL5twVN!R?aLq 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¨CWvr~Gv&f9*NtuO)3Kl#hG6 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 H+ynmy_Y5Sh literal 0 HcmV?d00001 diff --git a/feeds/wifi-ax/ath11k-firmware/files/IPQ8074/m3_fw.flist b/feeds/wifi-ax/ath11k-firmware/files/IPQ8074/m3_fw.flist new file mode 100644 index 000000000..f03566eeb --- /dev/null +++ b/feeds/wifi-ax/ath11k-firmware/files/IPQ8074/m3_fw.flist @@ -0,0 +1,3 @@ +build/ms/bin/8074.wlanfw.eval_v2/PIL_IMAGES/m3_fw.b00 +build/ms/bin/8074.wlanfw.eval_v2/PIL_IMAGES/m3_fw.b01 +build/ms/bin/8074.wlanfw.eval_v2/PIL_IMAGES/m3_fw.b02 diff --git a/feeds/wifi-ax/ath11k-firmware/files/IPQ8074/m3_fw.mdt b/feeds/wifi-ax/ath11k-firmware/files/IPQ8074/m3_fw.mdt new file mode 100644 index 0000000000000000000000000000000000000000..dc77aaba5e634e36fe39fb014d4c6bfa0a13f769 GIT binary patch literal 284 zcmb<-^>JflWMqH=CI)5(5RZ|Cfx!eO2&7FI6o4`sNFoU46az>E#~Wt943BP+w96F z9L*suTXG_D`Gsn40sW9CUl)S(;sa;x!o}lw7oSRfSy36WIo`Uj^vjRD6)7^C%l_Y* IzL#4K0A5lgyZ`_I literal 0 HcmV?d00001 diff --git a/feeds/wifi-ax/ath11k-firmware/files/IPQ8074/q6_fw.b00 b/feeds/wifi-ax/ath11k-firmware/files/IPQ8074/q6_fw.b00 new file mode 100644 index 0000000000000000000000000000000000000000..13f932d8c9ac75ff784debd718e6093c3c9776a3 GIT binary patch literal 340 zcmb<-^>JflWMqH=CWa*p5T1ay2~?03NSiPyFmN(xz?7lTAqeg4a0vk*%b?#Iggrp= zAU=Zv6Nm;YR{-$^yg@iZh=Cyih(Y$ieue}a28IA1ZxBARiJ5_62Qvd3vb=-?0|Q5ZHyDG&Zy2D;D*)vgI)Lu$ c@V=l5WEwD_$_D`D4S@1M{OL2uWOlgy0Bd0%hX4Qo literal 0 HcmV?d00001 diff --git a/feeds/wifi-ax/ath11k-firmware/files/IPQ8074/q6_fw.b01 b/feeds/wifi-ax/ath11k-firmware/files/IPQ8074/q6_fw.b01 new file mode 100644 index 0000000000000000000000000000000000000000..3d96f675bdf916516c1bcf532a709912ca042555 GIT binary patch literal 328 zcmZQzU|?VcVi-_hWMBYc55sWd&Bt`c|I5 zc`epbYuZT$=4AU7G3VNLcK@8LH*?jU&37+qzMObIC-8d3Q-_8xN!q9Pwb{QgoV@+^ NqGYv~ADX%T0040wbCv)A literal 0 HcmV?d00001 diff --git a/feeds/wifi-ax/ath11k-firmware/files/IPQ8074/q6_fw.b02 b/feeds/wifi-ax/ath11k-firmware/files/IPQ8074/q6_fw.b02 new file mode 100644 index 0000000000000000000000000000000000000000..ef6f5ea1bd596827824ed74aa0bd06fc35342a63 GIT binary patch literal 4696 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

    OoeFlo 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%0A2wh6ccRNI_`bh+{%}Xy8DoD6Z2fHE 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�JtuMAow?sP#NDoKyNtU{ z>b)KAl4n;!AN~3Utha>aB6O!Kg37e0e}+>Q?7klw^^` zVN(Lz5|-$~6L*c!yBvg_NtaAIFDK@UY_~}cWsC8-Da0I;<17)5hr+FnaM%nyT#G)? zJcU^B&La4Zll;#hIdQgtEywaA&-RIt`rz`iopd)+NBhDOR3Gw)AU#asv4?Ikd!H|d(%rFj4fo~J)rMlQBT-&8jGu`X2)It96 zqsD!(MH#3eRBCLzn2 z;1hl4y08}mw;WyJY0%XWo-IZ`!Z8u^&yfu_U`#gFY-qdBo+|M;65=9)_3ao7%|FFG z_?|8_k^Bq`Cl#^tuDPClcX#bvf;q}M-W2JDACDQZCLVM;ViUd8{EDD?$P@@pproLuOw|FvMJJM1Q;(JI@ed2|D~)sr6pY^pJlw16?2+Ng4Ys z5BhTT;(GIopqCnqZG1gooNk&o+Ow!Ws)Myn3Uu*LF}EM*g%)R9*cj4~zd6wk+OrMd z`5EM-BIY9-@ZPM@eIZ!K@I!DREr|bArw!vKT+n0v8bFKYpf76u?UMpwV{gG!)c^cM zOC#+aCC-qZt=-`haJDVZu%Bu`_Qx2!y*fC zk@gKc+A_n=;OUPn?$vO#y87x0zZCfZ1CCpMP3*&=)PZ~S92m-(tK_){VFlx7EfF1nQP9>Ano z)Rmq1IoeU%{oABKR(wMKi}o5Ci9Lq>nrpC1qlt;as@|=(M&es&blamI$;-ygGYQWH37PI4&(y!XIJZM7MppRjm zImPse>oDS@Nqv|j&|=&%JQ4S}a31cH34hodNyQB(H1e?skFmex@WUt39}eQVF0nmA z^BdgAwHM2sD^t>AoH} zdrS(>S6HV+=jc0?CD=Owdl|Zl7iF`@FrjOB9(+hB59(6${`OLxJAkxt+$Y+ak>aeh z7Nt$MfVOZQw3qJztqtDCsrN(^UVqtn3vgP~JWfxh63sxrX)GEet8c-&C;GG%x}FJ~ zzV@2*s7QA1<1{4o#dY=0#a7T5DjPp!38!#3O&;dJ0UEjGp2Fz4rp;>1LSAOk20Ld@ z-z&bC;?`}a{pAf;nx3ZG>eLv+pmUdLk9YxV`&nIZVn<7n=k>nl!Y1H6;iwrn`YO&p zMvRBX`6Tv`dG)5CLB&x+&+@y0e~re=gr_FdMfjP0i7Tu{I^k$)B411Cb1=WT_}z@3 z4BQ-YSDYYR$?)8K8F)GWP`wc1<-ALB?A~w^`^-vw<4@&XD)6vRvK;2-6l~xyS8iSj z03N*mb!CH7wWEEfWkg0>{LHhey?W}wJRiT1-IqEO^zp~@K5-t#-PuyyJHd&w7;M8# zz^zQgZ%LlaIH8e_!Ok7A&Kw&M!-eQL^J`Y_^|j)EHun5pJn3%hbl49+sAMx1X`!Y)^Kv5 zv*B?3Tqvvy5S^>D#{Yeqa0B6Wdun@R4aWZQ`t*Lg^qW^#sPQpCBdrSf zSX?Y7LiZro1b3F8|9R*iYcO1uilqjyt&SbbDTz6?S);_l~)|1dOzvZtAd+hjkaRlccAZNyG{H11@Q7aaqpJ_zOAN~^0rMxC!Au~ z3OL+bmD`gi?NWWBGWve6pZCDk6&L3Q?QbWMAh! z0m=`%0J`tqdIh`~>S5P;_f({3p#MLSn0hZ*9`^H{k4*~X-pQgn>R7Y_^Z@u8(4MGR zumH9=A;0(qwTJ#~3fE_r_w@7atP=hJ~7QuS^>*JN6-7-JS}yzOqRtF7!MR{u_wiTntQ zU`OF9t2b|lt?`Gj(YSQ3+)@tMQC&FKmr&VKlm$FHD8I03`vSw@t6%5wBsdN&(W0DNf9P7jq^&R?u^R}YtXbhu-R z@P_q?0TusnpLz*mp6u{udKT((hbxfh)4*7sLtNIaEfIbnO9p4vPLCfV;5=iw8+POqG|! z`6A4#=P({;1aosH@OFz5tRXtj!++yo=b1pp6Lz!dkAn>fDhJO58c? z#_%vscjQih|D8_MfWO!-1}{9^e04<R~&Q5G*+xLAFu;XA_P$X?`)56XSrz&qXYpaTc-=^sDje_4^Jj67O@?YkH{v znK2o0?}EttqsBqhZ3Z7k`M`70`Kd;S??p)O>WA%y%y(11V4`2#OgPdT@p{v1WDUjvzZsm9v4<%vOuDXQE$83R!hE}+r{wfawK8yFDeQQR z&|^}*9NS$slTra5#pkt1`Kjs?vW1iK!*hVsk7C`EJ+cgY%ks;dr9jRf^(gt#$+-WH z;=@~{DJjc)vV~;2;?ceYGA5_g&H%3&I?6%Hf>+N0FDx$au0p1V&CH ze$EuoQ6Ji*wq-oo$+nT-AUz-HonF#`7}{GgCOZ3m6L1m~Rzte0 z^~`Xw(Qep!tj3S>X5y!XK1!!N;I&CYNIy7QIrdm zf5;U+fVwiOg;C3FtC`AXqU;QmwW4e$%95ULYM+pgd@1@?gC{$8jD<}_obAZqE zjoPdo`}T(VZ7uYx_6D(1yEX&3pKCKcjJ30S_jl_&6i>tCf?NZ(#c}jQf;@+Z+>>a$ zBJLZ}fRAr?%nrL_v%~)j&lm8tH`aRofcL-Q{e3rNwAfRkkkS4Xa4N&NkHdD3JI%GL zI?JP+KLvQP!<_$}TKBdmAG>g%7qZ{e7r4UKB=|LHz)Ln=Pq-*v@6F!m{3cu6?b!w% zm2FA>s3Sgb-?of*Ef+2D^UDM5YNX8Q!1dt+9LimRJy|c>Ykefs(?xsN=VIH>0RtVr zeSC&%e{<9DftQbPmI+E`cvqdd`LBS*+1d&IP}1D_9oUB7t;~X6<0kJ9@cuvW{ zZFSNN&=I`j?(`LJRv()5*1uf5r|zCZM?Y9^rn@b3-2d|I;dj=XKdK8J(!8}{WWt+s zM{m7r!sq|?*4)oEuBZBc3w`+`EkE`>ll-wyma?OZF}7?ua};YKaFg=2@Fe9s-hYvD zQqmFGGD*q_+cBmNDJM$w@gC`>Xen@M(mgq&@X3o#RVu?8rNdh&vDDPJWed)@;Vg_J zQm^ql2ADHT`Zuo`^0f|pr+f~2{_(pbLo4A2sI2sU2klUM_u#2{>){av={d@Gy>z~1 z%F@b@K#SS$cSS_hsZl2QEy|2A#X+O9LwxP<2eOixTHIfr-z!dDyP=8V7EZ|D{YZK* z7r_${-)iXNAV(4_1*~7;H0%Sh4srLnpKSSPov_1#eL zY}lmI**!I*)J*Y12_MWT6W{ddf$66>3(h=gzhuxK<}-f5!G7%Luq)+3dksm>s^ScM zeY(V6uY~ppcYPRV0OKSWoNE2_gJp^-b^OR3`J#lgAY=*TV|62LuO7qg?#Irmc-?~d z0+TCs@V`9hZA3r2T#RBq*=itbhJ8nL==zN3vL%OGoLFVT2rg@>skc(^v!S%+>iVG{wx;~4atDr2=N3qDKlm2lPzoT z)Jbc+gzvR@XVL_}Jt_J=uAY^fsjO9b_Qbh!A5hK8L`=xiV`FAUwfSlQrNW7|UX{SolHz4eeUf$t>v zl3ZkJ19Tp+oxj7-T001tRXn$#Hq_)iLTxffPls@d8|`X3dZZXOdAw7&_+!({1`c;% zQ#>>+V(O8-rw;Et;sh_%RS$EuI9K%JPIBF};Sk!-#5v&+%$Edvi>2r{$v+LS`xBEw zn*{#|%vH^eb2Vpdu2x|TyD%?=TjiLq(C23l5MJ3ZUq!ILq;tSHPF)3@reJ*KbH6qx zvFY-Gym%U~OzON4UKzgNM)hB;zJ7g07I53%66`F3{qw`4PT4 zkV+l?`j`!9TJ~-RuSj%jD)znJ&x4&ED8pfHN%mwl7O8Py%(=yg15>rF?>%W7cwjec z;77>Dfy$Arj&Q0K<27M!h*u+fawqgSlX0%=62I2KpXS?rYe6TD^8PiCQ2mTC_-v(y zt!?0mAYUPWFoTue|I>C9v2vxS=uVbidj(=gSi+47gT>j%eefvg=T+dC3+rq@@=8O7 z!Z6a3NGmevYhUP#9SJ$5LpPx;2b&-s`+JczIaPYR(ZWlUVK>`oy|fJYT00FoI>Su5 zI|OZYXRoEZYszY5)R}R`Pr$sMV@`I(K!uRw}3_$ zDs!EL>%rAxVAMEbAUoKczhrt&0-re2f1<5XePKh$*?a2A-`A>Zk*yH}7xmm-SI%d8 z6y$Rtmdgs<`_qo^4z!VS*u%sx@+-K}7tu$~#a-mz=P$-_E~K@yh-^3kvk>lVu_awr zYTxYmVaJCxcZ64=o)_`#?!O~ETeoJoAMb1MF5^l1pL?ORYSWbrGx&3nkJ(Z5p%Z;5 zfemGIe4_YJ>`t+p#v^U%7&XRqvP^dFzlsR4U17oDg5Gy;gk;Wg3+vQC2Eaamd}(-# z_va5m=8A7_)D;3>w;X4bR`mVfbzghG9epaO#yJbVNgV2-`bqajb;FJmGyt)*bmhas zvUGhG+rR&D3+nTu{Lv{#bX;sH=85w=(I%e^`9`YhpudH$q{Q44l%)}B4|7x^w6G3I zIu&lkJ{61$zcb)Fr<{t+LtWG+``Fl~L;otr{*UODdJFnSJRu*?ADw0VmxjK;l@Bst z1GPi^>ylRB4&jg!PrcOYW%2bRC#5sZla*CoT5r+XGvE<9zizC)vvY&DS-ujF&-Yoi zXYpU^+?D}N51lF4QqIo}ZT6<1_sAHOi;3^1Gx%2YPxH6XUaTqi@I&ddgyCLE<VJ_dnMAa4xwX_7Zn26WjtLgbJa3g$U|wZ zNXs5eBbr8hCdK`sy))GcnJs8*@Eed7v}jbhU4F~`PQrp7;aD5j(d9Gtl`ChwXX}g%H%+B0D4Hs!D*d# zK+aSM7!&PlN4ueS>^tM9xCGZHSMI?3l0yc>kIhXTZXy}hIxlFbs)x96vcyB*W6KN) z8S*kY4&5Q-S5xkrr0OT{2Cu}hw_p9J&a(|RI!~Yn3t>KdeT{{r zd$hvVlJ?|5_;Tp)(;dl>V<8`_GO2?;HEC9s55x_Mad7&&SgB4Pwm* zlm_@w{Q_W3?@q`86ZkJzb3J_zbcJ71wuGy>MYaaOv?9nQQgb<#1ZgD?^SKzIRMz+%5TXcy$abA+@_r=kZxrv z^j{{xON;quOZAs=54n+pZn(tpJmSp3hZekViOw|qgS!Ar8F7^nmrIX%>rFnlQ>AOT zC#_5hb`JD~T;uXg8b=J{p!yAN!iTOf-L>IFxjfiKO7ZnLr%n(n6}w2Xv2i$T1Z^O^ zBRb3^yv11qQt{PHi9)77;kg@8|m>lr+n`D;W|&n zi4wOBeJm*p{=LuC-|=zB&{w&SQ`bS~TI?C1b35Lh6`Tf|@2Q-LjW_6}ypEbx5nGX_s~HCI85+NUJ`Sp{8Xl-@2E49-ly3&7n*+Ewf?9 zUW%1hjQQqubB4`;l>mM=D1+r`DQla$FkW|c^)ywk#h++7V1;hCrLN15n1+)qgF#;$ zG<*yE2CYfXY&ppHQ2aMmAM(F~@7$juTd8h2FstoI_Wl@rbo%5^uDKA;9Wb~t&4N2} z$ZnJ9F`e;=Zw#F-@emA@dc7*UUHHERcf&Ezw>6n+y2j3C1~CqTiBN4m{W9i$DeM?X zZbmpqb1Gx5>HG72q5rXYIsOyPk~N8R8O>?Z$q@be&GJdm%b0cJGUQ_ix9{9IhG*0V z+)o&g4lY^rFxn=$I>AN)KNzpq1gMTHem*VtL;sIf1!3PovdPV1ixlsHZ<=+fS{Ly1 zV1uf=Z+LJ__NKIWk71pX?Fff8aSP#cr@f8tvumuox}x!;uJD|(e!M#NoN^E3@IqP+ ze|voU{@y>=xep;OOdr}MIbxZv{NG6aB^`7wqWwgNwn$DalDrw`?|Hywf?K)5#COp) z*-23>@^O5Yv5tRs>%TLT^o}?FKq%Y@+cMvZODl4L*OrF79?~;jgMNyE&p=#~%N)*9 zmnLW%o-l3|1=ykH>#W0xJFT7xz$F=dqdT}$pndGFF6kLv>jcQ5Lcu_vs= z9V5y);N8Ly*MfK2pUDOWvZZ1Lexf(p!W_TTidZ6{@XKrJRG%8sd5hqkkBrUzK8%a@ zxKvXx`~!@w95UpIh;6_%UR^=@4XkBR?ladg*j3OS6ddHGB>$bBlC53uu$_Vw^%h`H zo(&v2378TeQ;3-A-Ul*0)c4>!`oP0WK!YS7=5y&Hiup0#-qF$W!WP5}ZeBIb6FjHs zFk+p12)+%)?6-)m`#l;mTP z+G?^hTJ0qpqn;2Fw-N&lu#LR`5P=c>k#3 z5^Q}A%T}qKIad`LEoNU`5BNIJZWVY3PF6M4p{{^?+Na1*;=N0t;YV}8<3pB>iQn=a z)p(Ei4)EN}aF{h-Rd|kJ3ePbf^oLs>YPI)X#FAdqX!$iN6R+>(Iw7 zG@q;VwKT2)eq+AEZ=46ekp~(##P3Z0-ghSqewX%B!@HcnpT7I{aOJzihvvc#6uW4 z7*dxE;~mTQYYguk@tc>H4&3*!^%tR=p*}HTf0+Q^vAfV8uF6;2=K7;1-nrks49}-l z53ErhK5A1Y>20r+U9V`#GfWa`4a$#~Oo1%C4!*hM!};mMYHtKO+utSaE{h7YrEYmP z_F(H(jbpZCiQwL4z3QT?Y`seNqz@U5^AM}?KiQc~=&J$G6syX^M!iQHENd=ql7zQw zq>D$IrPWTO*Adw${pW_8EA~yFGU-N7sb~6?T*bGD6E;eze}nxEdDh5}%k(J2*BGE1w?V#6 zw1==Nrr`4U&&Tf|cqed<7ujb?pPvoA0{LX!NEBF!X7<7!^V`982!8|iR9&9R z_SEoy(^w%l(|2|Y+ZsFgSGC!ow=VqX%-?%(&9Pb689}?p)+EE{1Twd13`gOYtu5j7 z9C8|pvSH4|$H#*Hk$t*A+J!S3=eZ!~W1Q15CS(w)C7qKp7Q|F!_LO>$B$7P~0q`8mjOA}8Q$r^n651bj|&=}10RGsnnPQPO^kDKNd%5!tR0cHQVMKP?5gpb;;*h% zl!N!9_X-3zy(;8on98ggA81$(#=%E@ebf%|mJ7J~szP9%jcR<4ZK%e#uB{sA3+v%)y?9mwmSo?b z%Jwg3^4_vCl)bYm*|QC8ux^9@P<1Kj6nGHuAK6FvEuRuR%hdJio)%x<&F;5$%dPdG z^G|&Q*pfd0y{G=76}erS${p~_(Suf9u2+NZ>ca&B^fj_ROyy>jpH<4u;R#B)St(CP z`8!H^dYE(sLCg)+H=#VLl$(@Xxk2Q3pmHP1UsKAB;UIhgsf=W0nh)ab$;UV4(QDv& z*7|nI3^Ya$zYy9#;7=Iga(LOv*I<9%B6F6Mh{y-eA@q=*9jJ;5!4O$qb?H}%fbAo9Oo=KD7&i*`C&mH z4L0@<+7p)nKOMYyB{=A}C%U*e!7b@#Ydi5)OxRRT`;>l?VUis%2*{9G@cu^pnuHzj zZ+SD6hw_czD~C&r=GVe@iOxw#!`TTV;^Qa>0O0rCyL;dZF%s_@P~L=cwjz5I#gu*5 zcAL_6Gya?NPMTLplzNV@0-v#vu>kV=5e==AEtT8RS0wf>-Oue)y;qg&tpSZ`f#16o zSGz3oMC+{34^#mb_?Dmc6`VylF&%rR1wI;bev{7&URFf?U=j8q*p4>B7EV4vtWs4! zbhaUPI#{R&9OM%6-CFA-nnAgHw!wBg@C~bU7W;LMjPc+*6Tz=sfv#&m*HktU?US!# z@ZiQ$YFo)6`n|Tr=m1|u?Y9iJuZ2y5d^Rip-d}O-VyS2Rd$5tO(RgXR>?4DJ0$?$X z)`FnE4t)n=*;o09mbqMfd^2>fJ5Vnm2O84_oMCl$GtT(EGxU7XouTJ&)#0`3#+hzr}tQQU_J2N-)pn2X@kE!&7I3RE>wj0_E`c$tkejekBs0y z7G^8;1K6hu4>Ru)^m96{Ww?S6tQjp!(kK}+R3-FtrHJphschk+h)q}n-7xY7b?8*? zYQfz2{_$X&M!p?q2h{ZGVGAPr+KZ^CtC;NFh`LOE%x4vh_2oy~CDQ`KGlr<8k`wxT zDaa>Ix-!Z)F$3?=bvdr)JN~3;u9nU#`7z=D$HeW2>1?=>@Y^EV3g0m}jS^3f{W%I8 zIU$r{-7_2bO𘖭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

    ~Gqw$b`K+hLCu7;1|s}UEidx&Vh9`*8| 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

    Sf)l{hV^rj=Fd-2zhsaem%x`wuA>vcYf5Z8IGo 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

    HuMw~3^-{lg!-q46;0_p4o`%mG7t@&_5%W(t z!$L}s;Q27>v!cGY2)8~R@1uGszxZgxNA<|4!%zO8A$FPiPTzztzFAkBR#z$NN{-jX zK1W@cSE?_&H&N8;3PDnU`gE8Fl2xawI`MhR!%Z5E!kTeEf>>ss^xQs-DpRI&s00=o0Gf{v0|&diHH|xgv^e~D{4(x z3kJykNltJS;}G7!o{az4<0}33Jnfuq>~9rGMrXRZv*SSg{tdr+NXZJfrIp(=o0lUt zP@b)8Iq{ARGNKz0Z)P*>$4?ZcMQI(8Jd)P$*!h%R^74{`$1aFpa-^S<5Mx69i9-Io7U*?E#PUKvO8kzp{bb*P6WhQi zu;cO9W_;O*_s(!*SRXkAy5UpEPoBVor64y)=?@d{j`zKe^oDp^{c=3c5Ok+bXHeGe&gl$R;Yo6S8ShEP zPxAdL{3rQ7(W;Q-SIk&9S$3X5^OCATQYwu#nwG{DdFv$!PBc z=15W}_yYKDq`KnYwK^C0HNIi|b#?B#uFmIChVC$<`pQw?_;~->weh|#d|Qk9=$jYo zFCBXpt-&eKJ!D}0?ZjFXAUEe&gA~Vt$;)bWkeO#n{*A-V?aHyBmDJXuvuxmP*BO9z)Fpoa35%n49*V9MJJYUtX)Ad>r(Mp2DMz ziT!Q-6=KN9RW^)zP<*1$d$XBrdP(>Yu=epC$lWjqhJ z1=|pplgq9kt*eJop21(z0DpPQl8ngkrUc(O)#p7US1AFUee}ojF9{3uEp*S-c=Yk} zQw=p)>vAgD$*PNHtaVz`L`VE5%l9+L%P5|2VsD2m0X|&%o%ehskWVz_L)8FzYm>HK z0+62$flng2h=ehZMc+#?<`v&E=8K?-G~Vm!%qC(z?wrSkwfHySe$1Q;;M#j8F zY&!3^$Hr~GZoF5BE?~U+c)J;B*L?zKvHN4Vr1nqnJ?(xvT#9j!%#VeZ->$9)ydb+_ zhchl`;rzlp<7%Snk4uKWFn}-loi`8sX?~B1gU5E>i2#4ZY# z^`GdD8m|Nf5|6)l#Bl6iL!kW>Gl|al#$#n((`~;QzZW21kF-1mACv_Qum{Xo7Dy((B@B7Mb9C4rxz3E%i?D?L@kK zq+`>h@tprb?9AxjKf!knoaK#0}rmgDZiz4tE72=nyG7?VDX zdrv@v&Zv#bd(kGGWng#cXqs(?jKkdH3{rnA(;YdqhOD4*mbr*uk3C+OXgc>vInKA> zAx7jAtI+2_UmJL?iQO*D`Hg53Hr<-MLO{H_4IaoUTsr3I@z+tm=nN-H{IX%{cy9yB z4IgdT{=@>&?SXyDMvvKThi+n&wX2}p%B|45+Wb8h8?)o7;)!40UN7V`a*z*j?ET=M zA!pf4__7VA_rq}sd7%0v>0{*Pt~;EWzhK6^e^H_D`8e_oAm0U**S%V`0GWGkmuaCRFAVccxa5n zde3JS?-0NI9<)=7nk_^NT#9x+z&pdv8)ki-z=&_mGhk;=(ZQ>H5==7SVxhboyrV+(jpR(bihrg|qcw)M^r}$rKj9DOgocjzPw4kE$mT-_ypa0^y7^+=wjn#p zO1iqW2fBl$sEg)+sjT*ixn`p4Skt)UEz&c0HpXPB_s=~B*i9+9!R<#pF*>iprXFl5 z=)OI@I|$jtD^}f2^Y`B}r>)fN{txl>Uv9#?MxR)1@yw`ZeM@crRo3c+;`Hu5_~vG= z$aKGDe6UmNr-$SgZz)^K{b3#KJ}jZLM*`H}&|AUO#hGrYr%m$#^MK~~&!>GU9XGhg zQQKJi+>=qm@b1r`*@jSt?F{^3VaKB7Pkc|#&v#(2!5k3$Gf~Ea{$5=U+`_vIywmM_ zEocGF{uJ-EGemJfxkzKe8eA|Jx?SM!8I-#j$QA{0 z^exnm9J)i9rOGEW!GFzKVsNWf*6IM(JCzNUWY+odKepGgxwH=0nwf)qKH`q3pgYjj zXG&c))IZ&uZ0>mQ*c^9;Coj7@$a?Z^9 zZS$Txln`*;F(g-ymv+{4^*pJt`Oq^%Ha%ADaHMzyk)F~1@pa=Dg_@I~;~s4r7)^PY zEA6ty!+frzcNae(Gj}=aha6iBg*+t|obN4?`(!3~&mr_VPa0pB+w-Vm>D4t)Lc3x3 zLDDw^U`c(qfTtJ&-s=bl)z@6uOGUk^t0!C`{9Ws`wB*6ZmGDmX#S}_qa=WTg4`DQwxS;YX~@|k=Z-X{Gah4($rGZr&8Oz2ae&YawIspIm99_tXy#xa|f{7F$DzXHY`t?rJZsBU(dG z_W&=|nMxG)f!Gh2s~39?oo&v?&Ndw1wm1gT2$%PPFQWax4_-2@N9@*PJ&_!c$7LBL z4|s6Dbq?W+0KDX~F3{L!ig;V$P5jc&lmF1_DDHqCe zrO$RVMkv+Y42S&hdmAJCqv1AO#PxT zv$V(|_YH@ki*Oe83*dXXgKKvRy5eR39DmY!M=ZsBDr-Vns;3J2M}p59TDM`juL^qM z+3<;q(HoscZ=TU;rdn-jf6Sq?o-l@TMf7KI7NR?1CYzy8!xJ zPPj3P<{9#|^Tq#@W~Qk44*Vkg8==93d*cBs!Z*URR^(|^GnABwUOa<1sayNxd_C|$ zXU}g6?4`AtQ;D=a*%8t3;u(xLe3PkkJ<90`cRjqG=6c78#;_&y323Hq|0_#D+dww~ zdy#PI=pv$ZrprWoi4JQt`BSla#gR<+BGl6^?eM4BxGnpgQSQt*Jkd{um$3`N5#0rw zgmIug+LLZWoJi{5jBsO`6EJ2&3H7x0&O|o%NhGPT3eZ|V!Jw=Ly?FbBQQkDNWyx-5o6N9k;UG2NN%Ec{;ftiq?k=WK}cwxt7* z|E#{E?X~O-XN*TW zl-^)G4SO7B&(rQiVLh+hPHSpZ0e|Qj@O6fe$@U@f;gO8)kvoLA6!eDs{7ORz@)4;) z^+$WA?$EnI_~%!&Vb4s%yP0S|-JaGx(ATb* zfir|VJL1nS#8?t9$Ttu>0_LG&e+)Ki2r+bu_a~}2qm~8+*q(cr>ap&p;3wMBek@>r zA^wuVu8Q?d#2vSJwinbq+ezq0^&x@I{hB;e<1KL(C)@Sci)f#GL^;xj`yP7y3R`Gt zlJ~I6LfCZ5@^-~`Ue4)59y(KjcY$w_AA3TK77(xUzy|P6D_U??^?GynKBDaSug@w- zHk%Dt{gTQp5ih49KfyEu@75gwUwnvN_OJY`;z5*Up9mtnup$Nv>HhP~B_M!)Bag9(7a+0b?c`)9oq z`w}ZKJalNml2+!KQf(Z#8*qQsrS0=liOq26?%>4ie8^8T3q2Z6;%*d2EGA%zY8C_g ztV*JzJx#{AnVmQ3&ymem)XUU?DLK&V@TI29+rZl@Unz61{^VN4O!Vt~NwR2HCw32_ zzj;pRcrMYIX1kILd9^m@plzgEBHR$8Z4!rUBn-S{$QMRFBgtuShUCM%hQ0@uh~0LK z$q&0`Qv-I z*r>`{tX!V%SddRR7y8ej5o0g{w{-Z~oxJ5FVBojP(;ik?`3%I>F2rr0 zW6Ykp#!!I8cVeW3JAv{$9(IGDrIlmQ&hMO8Jw^7VKX;O9};irgoM0T}=pSt7k z;>`4jatmY=DNeon7}nJJCD8M#bY6mPKYm^sua@Pku#3&&Vsjed$$-AiB_EgjI?=|D z!Hb*-jS<^>#)x03i^YIsQm$g1S^8(fhbYjr9%qHSLQ2WIbY@vM!DsJTK8LF_l+%k5 z^Avbx3EiR$UpxI5iqS1XmYxT9!w1{4|2rl6C=xm>roenT%{``uQURl%pAtO zsw%}tk)eB;;iz(i(!jGg!sySLpql5a`!*sZmX^ctEah`1z72^ClDV%W1EIP2c#LwRQRq=32`wM zv011O$?>w!q3rWF@lrGLC8F+;wxZ})^jcM&jJBv=;;T;J95hld(WEiinVRnRmj})6 zhwhE@e1n;nvN)W&FJkuB-1yMsoRRmS8jGdl$Ea?8}% z`6o}#Q&K+}IsaIc@8kS44(FfW&7MYO!aKy+Y8d!SZKa06EuEycK zRWYG_gX7u8Oz2PXLP=)6)aG?%XUtRk0qXy~0sdOrk9d;PptD3X zBzv1OAAGvrfxWcHVjEa!a0@cGiQ$RCwLd2L@5JuSqCZ)hlog``&;b$+I089|3A{T8 z4S*lH@AVMw5h8i-9_;nnTzIv;FhT#>?{Ui#r_f?SThnLcPowjW zfB6KTUcNh++%qxQxg7K)q_@3{xX&@#oOb!U8o!!$xeaaGQI_8Ot@+dP0N+IH6+0#;fr(Ui68D)tl<$7T_5&f=$&cfc4*J3>OS%tl4>6{UM!wP&e0q;gnP4s>u5g+CS zAJ(RO2FG`=U_AN&Vv86Mgz2$ z!Y+wqaRT;m#ObQhtGrzw&cDDSU7eo~U8@|4^+-M@#8+-z_F09t?*29bXV;0{GJbS^ z&;!r8Gd8Dvwbv@FI2#b%q4hUOhAhDIi~14%i}+ZI$-HHy*lhy;I}($b7m3{&9$kGV z&i#i0CsssjGtcH!rxen84feu{i|C)^gMI)u6up)fM@VRv!p{9{nSa2tC#TZyXbPmpQpn@ogVfW7Sf*lK$orPHBaFEI_iJBygRuaEOfW2U(mL8Hi~0DNHm zVbG14aoW8e=Z*2M(c-03W9wcAzrqfsUk-qt$VX#m;pC{CADxH2#Feh?TXf!eclxxP z^j`RbZW^bZOG>5K`J}rZ&jH9w-genW>;#C`iD-X1&Rwr>614q+&Rr(d8*oS(A0U+K zeO-`+DLOv4SqATe`6JzWKE<}Scm6xc?{!61)&QR@;yXl5Ckb08jK!%M3Nx2wxL-qg z#&o4LUcwI=bFq{t(wIXSuZ;2fwD!HqQuqj&Kqrnu_8-FBj>Uh=VIKUh3$da5ca+dw zTT_6C8n6B7Gr!u8;VcjUNd$*3|-7XAtHYHN}U zr*Urr;PuPt|A2=_gU1Z?1$Y3xorh%ojCc^T33(W?@B@7w5Bmo9#L;j7LEJS7X4#=m)#Yt&Kb)aNRSlZ8=TLzN%uu3}5 zl6~8hLrLOU)C=1h#Kgi~8`#@PCP_A6emy)K_UOT%N}|+LHi!Cl8Zi`2huedWeQk;+ z{|Pk&Uj`3DKExwyeaiwfWL&ZM(R81n4)6$}?C`R-?Zz--Y_T1>Wr@~sQNikWoH+mQ z*f8Fmm&iYqCgm3rJ)?bAk3Ni@n&hRu`)Ss$gH2MckeGL_1~iV@Cu@ARCS$`ry<|T? zIN<9gveAnUo=d?~i-vsPgCaNF!y&CmkZ^nJUa!|&)h_# zY`4h~zmm%~ud=0;gsRz%@Bk$r~97XYA z%`QWoYze=7EAX6j3lC!)ts97jqJKye9Wce~_g|RctHd0?%rCABEbTg$2mU$)+h2-9 zPI6-C4-QOM*#GvOcQ_4={4VstXL&*Uy@Q!)u>KJaf}hc>aE z6&icsft9|^xC?cMg#88O9>JZZR4%>f_xiv)f%$9=*=7Ht%r!gjcIsam&e=qFaXzeg zJb!bLOKF#wSxirR2aw&abF8jxxD_k}~o|uq!LDwsRUxFX$H|Hn=-z@WYX#FoBI|^shV#4uPSH54tAp0TNzoim96=W%t zm;7DzWv-y^NE^<&#DBv-=<7Z<3?_tK!QY@?I@ocI^b=>Pa*nd#RU!_^f!wGctX!mV zPlIxw)Tqekd2T**(0bf+0eM{R@Z1I^wTI`6szZDhx`TVluT-2Oy#IWH4?Lnfhi!IE zMV(opx#Bc}_x=F%QcTnx@&~D%JlI_gZyNr~63CeZtd?PWKMm#NjLAKo;oir~E;ao+=7-i6q zWQ-AZaFC;QxoB=~Lz&O-x>E5G#?krri9Xm-RX9Kg#+EYh+Z|+!xswm+e1ct4QbKYL z!#5fW;Ri#E0dooARY&Iu)bTOZadl#>UF4BNEOK!Z@PAK0yTgd+Ey-;zZaU?oevurs z3bqRrf5UVrlnY!HX@ATSzoYJx$GAu4>3rypaU`E5eEAOcMe5T#eP;J_X!AVU#Qi-! zmqu&(mVuwl zfn0GMWD4a+WlKP?H|)I`BU);XZPDzZ&B>0Gi1h zJA>aj9tiH53x5yPPx?i|aeaTF1hz;{`rkPmkmwuTX(`~o9Oh_f$_M|?4mHTXwBI>S zkTxrefFmQa2s3zg8gmuKoF9kt(3cZ^Zltr~>6~j5ePu{z#9`9elkF40(^22@N`+?U zT8lFM4Db%^pII~fcAg4*m_z!yp~a2Rf&QY5`sE+y#V*V*t#!zo6-x7g*eca2w%zI}Cmea`Ky?I%=j#FX@M(vEu8*77Y;zhb4@PnOHUW+5L61*049-wa;O_aktG8=U&sM8y-Q(xGotyd4~ zv&8G`>>H_%4?%W>`gE5^>LVRWCU`1ZW3+ClP7!ssqt1HN$(Nv?W#VNk_(W-vp>QVZ zy|O$$-hR|;3*3+Um&Vfg99YKk3s{Red$WD1 zNFR!)J^QkKda@0(ZPx65)?iJ6vOJIqK5_G~zovX4^!EiqK?HqE2>Z4AK8l##-6QoK zq%lHYgz*v0;276OlB}I&Xg=9}x_Wr(6(sjyOu*fB9)IbkA<4$=W;$~t4n3v1}BRq6tPQ*>V4j=GK(gy;oY^Y zz^f~LEXcw)+PHMTwj2IeH3#2ip@~@l%;Pt;_&FQ4`>vqJgnVM6YlZbiw0B!k8VVkJpo>}~7i=pR7na?qQr;uKATDA?+ z`xVe@zeASASpnSM7s7HR|gZl0jhZ=(^ zHD>o+eU0FgV|{|mq;e(vd&;o~j_h@R4V&G+Sr)^o&i&cGGf3}_r-u$?``$tNxp><1 zX14Dr(mRnR_;eo1_8maFHJ%%ZKxxBZcJ~;*kWoDZnj5NXE7cWp%yFVF26&6`b9v%>|DqGWgzRB;TD3N(V&Zu! zFO~{}qr~L%VHb3oPD-Z@GQf7&(V)Rtn{Tlp9rK;>BIdgQ^PL-qYd&B}aLsdI-Z9_F zOZ~yj0V#MPKJQNSV>8AyA|EIFRHCixLT2~WrB^BlPdoQd@_CT9ApI%Qp595ma-_${ z)17^jd@iI-@$^vtBws1g$?@_zdnfrMqz>tG(5Fc>Q zSK~CgD&YP7@a>~@j&)nF(S!32oA!Jl{`@HRJo9k;`QP#9s`zs__FS_jo{q-TtK-j+ z^xF9Mv+?)$$I~CgpWgWUOAcG=#&K@y!GAMbAiyjh0d z6uO1;dGJYX3+lmp>A%Xa(}xgq9ezl8C`0cI;P>AB=<7Jwl}mTG!$KT>Rf#TH3l}-1bcJmkqh*w*DIBTGi>w z!P14TJ55ifXC^*%*pPVRIRSCi$p@!-?q{&$=)hVNyXjoG3-MF-5&OS=Y~iv_a1i;rTz z9I{rw6VLZ4Jz+C36SRTqO@qIxsW zsg(2wo&ycF)Gm#Y;eK2?w-J3e59xD$KXK9_aJ**++HQxO0DjP}If*K)5J2-8 z&h^Bj5)4T;NHFBr!La5VF!Tb3)DOQk28U9#y)=Z_n`#>Qb3U#^j5RK)-dRU@4#8Nz zl>bc#r4I`cf^#h9W)5s24`Qx!Ad5&QnhU=r@_$3xVZD~%Cb-Q*z0>1x1CM`^a53G( zHu@uFx2MM1EII%_ojXjLeBdnLN%NYI^D=X>%QE^TW6X&|h_8IWWYa~;<~$V7V+1dF z^{1G#J52>6vcTV68|U`9u2g(UYwp}6UozSdaaS$P0dqZak-Mf}5R*;O!3fm=KWEvvgRGTN@AL)KP3j(!0Lmf31^o8aq?UO)9CCRpMz7Zh1 zr1d@}4%0U4zuc5wWI7%A5@!?Qk(baosud$-sJa8`w$0(Cn!I#G7F>xwXUF@@KAhxR zhID2;E&cZ-#P1+kaZFwg{mqb|4#mzIcgY>uVL6BT892~f582{rE>$Vxu_tSIgtd~5 zK0N>!QNMv5njRq^^`BiFgOUHQlYCi75608#-zNDokUkzyvyUhF8Wu1g;gvs*SKm#( z^+P@EG&K0EsOlIk!B#uoCaq5`jdqF0CmvD&4|y3pb^4F8eH?NNX>Wt#i1Jf**!>bu zO}wxPu*rrwE!eruAI@P(_)w-)x1upQdiMtT_F2FF+k9``^;Onqo!f&WL^m&Z3% zrTw4Wn}oJjNYiwoET(CSm0`3jB6JGe+$3#^2o(@(TC}!|;yQsYMy8fDZQUjm(jqQn zW(alEah6YB$C=l6elz23k}jZ*r7U6<2q`M#j1Cl0RFvQMxlOcnbVfRV+|N1Z-us;8 zInVQ)=Pb{2Nuv5W2hvbhE@d`;hqh(gE!hP=eOKkJoFI5D! z20iqR7R-;0y~-`-A>~nvQ0*<-tIe$znz5gtH9m;FQ_?w%L2dej7(bT+FJBOC4PWAP z+0wSO+OFI(B&5}=yR^oSu$JU4E1#%?Zu2L|^7NtWos~j~M)5ArZlVs3d*D+5b2jo_ zIZMdW+&%2FJtEd^S-oMQedi+g_tLAbJKBu4wTRllwC)^kU!IB&>X zwSlCA&-)XguRJg--4-k@Zu{Q7(0OmPI+ON4@9(+EI>=RSe>52~$|bHWRD|078gUNf ze!HK>GBvHOLI<0;2jfk5yMJ{N?d5NSp(=CkLSOOd3;FDX&{@iYZtrtJF1-qPJJBT? zo8UX0+AuNJ2C6sl%W?Gcuw$X!jqfZnrzYM8s=rZ43s4&dK^xQt1|JT5H}2dPus(vd zpWspp)_XhsEzlENgG%gi=C%$%en`cbx8b}i*>YfA;|OOloJvC7tI&pv5XRehaqr4P z(lN1D5nxtV@1FqMg7bo;&ncGyXI&{C!qp6FpUGW65wL_KYA@ko66J-pAi|YCIH#~v z@zl2%On&o4^A5#;oh(+d}0I{k8a@8U+}qenhOQ^LthoNJKIjHO+t zE^#hLT7xvL$3@Oga~2_;5KHSno#tGOG>fGxKbz*9kM!AVJ}M`=aJ^}DUXJw1SXz3^ z>YRb}iTL-UR_Ao2BS=#_q=?m-j`X2ennkV7iAeXy(!!9{sYbdlmUbPtI=?uVVVC0Y zZ(B#s)qpN&PoCyy&*SVC4_WboNu!x9 z{|plRrC|T&4;v@hU7$gdJIxvH^z+1Xn1{Efwa9u2opX3#+Wk{|Y{hM1_&MvtT;ww7 z=*#dZmO%%CPdrwFy8{QXc5nTp+?X)`L`xC$Wt`85yfeGzu^%mz<4N#?VSs*5Hd<5{ zT3ez0Ch~(xdl7P-zylN))_0X~LGYC{;1>Ziub0cEe&f!L?5`~VToP!hMOs-nCl+r- zd{!)eKjNUpGA;gTLR=qH-bMvy4`-jLm#Pzu0inWh+m5MLBNC%e+Tgp{yzx#XOMmr>DTd% z;9m!P(m}vm03RNKXNb>0T%z(3e;4t1-JeFf3F)p_`BeXlP=C&v@6G8Rfxj7X0dc9% z1ie&f%S8WF73F))J(Q2wb}8a&#C!UR+j;;AtWL$f(@OmBp5~e=p}vDR7TCL}Zkr=7 zjnKNMLD@Cn&B6b!zpgBtDz^K{_I+Lgf8xf3Whb6AV_#|?XdL>72>CR_iuKCDvA#BG zye1i)0$z-d+0oVQ9jVas)f-0mYyPS!ns!}6DQJ$_2Cmj9Ne&1t4ILTnGHpGQwp~6` z^fcxn4`LqDhdv>GGb4Q)(ji+(o7-mDvSa$Amk=*1S1Y$9iFe>0d7Qz4T~esSAH_d(4+Ik!&*MxT{o66QJ(KA7 zkty4=!hKfI4%RaUe&_d2Yo8jlnc5z?WZQH}elN5s@tzZB!+wV5VnSOn;h({3bf*+$`si{p(@aEax>=1o7wcUz%5#mIXLEvQq!Q)-0{N3Dk z3~>qZI87%IyanZlN6Nny@gl_I@QDPEcb)Qgz#}dp9*0jNcq_{9j+Kvi5#n+9iwGX? zI_2+xM_fWY4xdc$MJT@~RzBiIh{xeCCV0H-l)nQWaS3sP=avdvC*nKN<~rzaO^3xL zL|f#8avjPsqa2#c8gM>j2GS~|yFptIAj}gmCx-tSZ9?&hJn@tA+=RI&2$q?)HH6T{ z<7gwn?vVSksBQbSN2Yco{TAr%9njrd$j5^Cdc?z+H+Pp-v`s+Y%s}7t;v4n(Ql!@- zy$9d#NBozF_kfmrOP99wA^kqmeW2fD^vPxDlUMMqr_|QA0_nSuehuFqLi|^V@3vjt z_DboBw!b3%KGHNNzXkzL;{D5su+pFM-G|byy zF1-%)@@Kyi{J=w3ApV%}s?Yzd>63D@#hYRNSH75k=Llc8g;j-Ypac8nv#}2ayAFYC zCHikcI&{=B$c4Y1?mJ|<2R~fmo!%wWz3EH3&jAjIt_9%ZR>UQlZiRoL`yPBhhVMPH zEH3(z?sI?(g0BQ#iV^RX`J(t==>8pi@51*knXgP(a~Prf9NhdM!X4eg6{%8<8+?`T9WGz`l?1;LS1<1UuD4#O9*2I&bL&E*4fr|-LtL1KF9&w zWkB=li*OF|BH)jBgLr^wSaC#LQY+GY&oM@SqxA~m8r%hr^M@5(OjFRHv;Rc%P|6x9 zF-;5IAA55F_>rh2J%YJL*5;BWR`w~@>*q-BpVE5~`_#kd-H%51w|5lW9h1vzu9nX) z65YFgC^(zb+_K)&n$eOj%dLL!j)~ji5=e*V>eEp-4(l37DWFxQJCXX4(fN44^E{U&IP+JCZE{WPQ(*#3r$x%ET=dT7n)8U+XVp=B6 zWg^>Z6AO~^dhkvGT#%nHoB=mbJNmHR-H!cVHsCHei8+0|ZGXc12-+7f2lQDNKR-wN z7deu{YFNg5?#5irJ+noVg0o!`Y-+Ya=}>B{cgKt(}lxQ5WEHdf?|1d8Ggkp*=!d zid5}jub#yMJ z`Rw+elisKxUlLe@sr@*^KHv6Hxh%8Z6`Xe>eL2!9^d$^Uo$HXE5lg%NCO9jQo*qj} z?+NnUmewm;HlLMY*gpj4Z#Rt8k?KTsdm z1AVJu|FW`;HB7?znp%I$dbGccF`Pqz&0~ru=^J$UR9Tnr=;*(5gr>tdPf7ZBV*ZBj z9lGr+{hRG;m-T5)kTWK9aj=h}wIn(_yKo=WLkVI##|42Z4UHW`c{niEr`d*@(HAi;az9!dl%vn#N+S@ z_|8GE&4FG^@V6pfgm`=`q;+?3G=m;Zaxa7GfV2haFw&VwcOu;qOHW362WfbpHH`oy`McfrkY*-zS zM-v;CBYqA2v-_fk=QfP&v(WyEE23xsJ!@{qe#?#Pv9AFBbw`+dwyyF_hTTv!A{W>{ z1?SYIw7!MCap>&&V{W5f;xu_(qGscfiT1s;#`pKl4N9E7gU%F~h_f5KSs7?O-}2~3 zd+RhzvJ_6;^G-SOcv28N)Gcb(08SfwSBf}&v!m^58dFYkHI&xE21bwlJX-hEVVdvEZA&&x3uBH!(P4)x|{!e1oqf1^!Y$l&d9>g=a6u1tSfNHa=HHM^EF=gfXF zTMId0c)h9QN*iOrV8_vsu>EKz;DS~CN7=yte7P?i`7p!2%leUAA2uvF4?j~L-IKZ-Mx4EFvLiWHHepwd%fRfaj_|A1Bh<^<^$S|4QFZ2m*) zkSh9sNfnI-T|Jlev44_1ag|iEcnCH_W~o>X(;;8XQqf|{rYG3{9-qCeCacWt=yM=kOJeNW=Ap21li+M_6@zLxmH zUtE;Ut6=2n`6?ibTKal|;YtnnciNqMxfs#2hctFLt@SiTH;FpT(U;2Co8P z2|^CxZ3uaU4IKM$b-p$#F2a6LjE;e!a32v?)cBXCdqXV1-8 zzYMUy5oTdOX_og#2rCfIM3{__Ekhk&MID!;j<3b)xF^w{2$*EyGP#bk5KEGU<3umz}#d)Snz1JYT9N{E{&mdG4 ztNqH|YRpB|e(qJZU$I>6XRoRKYP4~JFaveo<-Zi60%0*i4&ki`d4vxjR3Z$T`M}eN zs}N^GLY*3V=J76Ny=I;IS6{#uFG1oLs0DZJ)(E$N6K-*|fJUk!oKZxmMw`ll>WnJT z%R3Ukqy^OZa)5!Hpm$;CIlWhfBYpIzGuD5WnW&T)QIRqE^>dZu~g-`)TZ*d z1$BURtNkvMx{wR2{rUK==vDhK#doFfLx(c_wEygS3+|;?c{uz>FiLCKQ$6R_-`}de zWf=Tfwl3w?0R3;IZ}^}7WmdI+XP3IL3jeswYV5zL{VL=eMqiMhMI*-ZnU!4Oa}lo4 zs5K6`VBf`eaj+fW3Y8LkoAnvD(A-QkaRKEkII~viesdoFX~*~H07w5GL|QS#6%t?l zubC^HiM;Zmmyk^lC&4Eo_?b5wyaT;%?VgjOmOq|N6$v)7`02UvQt?PGMr&q1z(HOb}#L9BoB$% zQT(Gpzlb;+OXsZ#CV}XS^gisJtc$_2&pMp6@1}qb&tbpfTFC63Whvo5>@R?>pAv|| z#`%xICL8&AFD;HeCIi};b8cD*V(l{lAZ3AXgG z@W{DD!*!+aQ`xNB<1|3$5A1Ot>o;qT)R$ak|16}bZ!UklNB(a0IJy3m(}(ar6ciV4 zcVr!1hdAMva3qI6?rVBRWfw z*2dCOuQ=v>$8)zomsIt`%?*0or$c9|8)qioL3F08?r`3d)cW4VWrzLApgqzR^dUF= zR(QR+k}_ZnS>HEyDLpt7eT>FpWsxefeOPsrVAX3{eE&dOD6YJ|#rF=*Xd1BoNat`k zgv9TJk9N>qzwIhJ(YWSQw{MrSgVB3_W3w+4bFn$2@Q1ZGXX|v&;(MkyE`HI3I~BV| z+Nw4iP9F#DTBUZch0bM%b5EyP45u^S;S6Dv1$*ilG#6LPdsyp+;oqT%M;qjFhMRq9 zA;ak}PzSkxh?a##ntMRU$=Lg+e$6WOIHUWvc?maDtldt-gdBwebBg?hx!*U!2QLqw zL`Li>8l|0$9M&Cw4S%1SWftr=ZY!4M4RoA$1in58vL`>v<>H-lFY^1}gpMAaK=!ma z+luuX9`B=q*Lx9c3u(?`z}|LK=-P#4L7x!4DY<@SK5H;g9ysTiiEoM0VgL5q)JH91 zvWM!a3VEEOsP-I%44JUG+?jy2=+33d5n)ZThuWt2q{C@8sl!^7)0{VP{m!N8$fXwU zpVbMaCvp+Cm=mLuux6BkJAo2JP1KQ4bmA8YkDf@j`1}*0>t2Gg%Wx+X;evQ{2KvyA zyEZt;3+R_d$U~g7nN#yf;f8ByZKDWxTuhc)y>zdEO1R&fjy6U`pLaU)$;1CUMOJn= zuj+6W{-eC<-JasB>~UTj!kO*i!X%r!i;K8}nrM!|2MU8+t`g?xa(F>1>)U+(22r16I610LwRnH$qIQ;!KDZeDKK1X=XP2=p{AaY&csEjn%!p7nT_!#uR1A9MtpK;NZ`K{37Tg+CRHEZd84DCvj zT5CDvhc%kO5M-_kJ}Y>@^AUF~3r)ebtuQRXjlHf zD~H>whaG^}S_`>ui0r84OQr>KzmK!HK`w>PUTY-LNNZN)t1mgkX_82`NttzeiIvg$ z8Hz)PaEgT!ZA7=+putBpa1-MEDz}e9tP9B@x7zJX#Tg|rQU5n_cUe8gr%Dd~K5-AL zqJPM6gcDV#`Cw~-7Cr`Yns^W0U$;QW3=oaUZ|J$(du~J^GT&ItzG^ zzM~F}u=A-SzBhDtJJSS1?Fjs1wU-^_gap*rwJg1Eegrl}lDqa8@G1iKG2k`9ENYaI z$u$f<*6BRUW1^^WpV58J;1j(gp`Cw9^veEo!muAIO10{W1tZQE7@?~hy-y+R)`frH ztL^z6=~4=t&d+x1{0GwZYhF(|nEIe_CGO3oJFj(q4)6IQ9rizT{;;O|_gALO(_EE0 zU;Cht(9NIbCV9L2=fadkJ+Q^_yu{#t-k_)*HT(n%`bq>-GVgh zywmL>zkvRI_!z$cV;b9G9!V!5P3>a6W{a|Nat(K#?o9ec+e%$zv)AMEC%wutXfH|u zTe|vBh^{LgO4xq4^KX@D%VK`PARoDCYAwUv3y)RtIAa%-|4CkO@dEexc{P2)Dosvh zbFDj~t8IoHQA#zAAl`AubhVw34K3%7I>W+hP4nhSjc&Y45_tK47S+`fZ6>_V{mOto zN=9EkTL~T)Y8;B)vq8JCAIE#rD>SRBhPld)+9sqQ+vhD>_r^jy@fIhh1V0K=~w_Z76ei{=B@L zrJQG7c%^~Xs*i^<>Nlew`iF94T}pMN*~f5C`AqO1w~7BO{~x$lhj_sxI%S!-+vKc0 zbGDrHDAEIET|yL{bg!iXetYfsHhdm@{C?@I2S>D zeET9-$zb>@`?{%Vi&m*tDlN=#tp+|(pvTuL#a4e_u(e3H9zM@4)x-2ZBVPdBSJ_q9 zDxBukILjOKc_W)QGj?^xksK-H`S_;m2KhyEZnz3<+WAJaU}PP#uaaEcE2t96oGk42 zD=z zyu^ecQ%LvM=kVFTAh|H33%;REYTQ?id5aKo&^uQ8(j;E64yGq6a1LKx$LdgPs-xNNe{4!pQQZ*iT0@Zk5EPT^5rx&^= z_gZ^NQq72-8P^GoQx_GgAk+T=+&ui_^Eb?rk^}mGWZ0t(XXLpQ``F~nM0yZuS+;&^ zaxQ2DPldT(<(4Tu7Ms#TV|hZ)u3ydn;`|M{WxU4>TO^~Pl;6$6yR(1Ku>UazFMMHg zo<#cjSlV^o`*ayZ)8eO^xIM7QDHd$D(+YwQ!<$jecUH87lu<(6pzNjMMu zmz!wL2A;efA#{_J9!-GW8Sy`h&aQdlPP~V`Z9jcS-Wud7#qxZN-l3ddVw*kNv;jUA z;D5Qe>Bz(HeO@kNooxVlXy3tIm9RlDbZzjO(U%EPF*^@3hwQDQD_G#-yo>TQID@=g zUbm!ka0;yBLuW(!e02LWr*AS1UWqeTno><5Rq6@}Bpx&2P#BPJn>|^8?oyGRC zNO!b~ihvq6KNF-LhXypwSc~uWG?Iv&C8&9F|7eq#e5yS2m2J7N2R>gQSz7fFfWR& z3vjrv=nuDN$ZL^YQEG(f;>AeEZ;0*{YurAP`H_vWdE;xMvjAhk6DualbC;d@uY9lB zmKtHWH#NAgy~8+>Tk5i<9;129i{a+qgz#?GH3jyjFU&76i!MO_(03!=DX!iX;IL<8 zug$Q#frp)cn_aUG@dUQbaX0)BH()KescNe;vYR>MIM#yhU8R`UVJ#u`$4b~X8sCfC zHKt*$gcBa|hW9<;QPa#d=PD}G|sD00#@yh8Zk*4>7?ve1Z0c!Un zUefs#IGa~{i_$K@cV!gs+!&*#0-teRk*mVF#z<3Rv!L9BJFJ}dM7MWR{c|y&Gn=hF zNuXWD{-?07!kqUEZ||hJ(&ph8WV!ZW)cYF|Z8YFaOht5LAMfm{N4!D6hf&VTA zQ`uh27PjZRUui!!lfDPFXUMi5yyl!Z%w-!8DtgKasg9eYk9TrNGo&d_{lqq=$bRYW z8GgL;(1x?+B$FN-e)Km~KgB+`yrz?axi;l9gm)=Lnq!^N748c%j0=2S4t!^k{e_7>_%SQOL;!$3!FQIR^$Gf!%Yth2JILq1X_Ol|lzY_ZnSdS{B z@x?W?U5NJ`-BZJ$0~^o>goDZ|m#rbPy;J999_`n1LKg~PZrVPsBE{7QUFXa7i!SHYH!aQPD^mB_qX(NRKkYc4d` zI}tej5c>yQk1j&=#~pP0;HyJ(zfBh*`s8la)^zXd=y2O~$66XiXDik*db?V^tw_^% z^^yC1H$Wz-duNP64~NiP)o5U`-?ib<}?% zmAr^M)UeKWrp1&NaKm3Ve@C$s`$@8`;my75wg+4s`iT#?i&FzF#c2WlWt$V@3p4e7 z^^L#I=4`nd@GqwZ=v(&gQQxk|w`=h2)sb&Gd%pUnTem9UE=8HZH|)MNDxCQb0|)aK z%$HdgzA?b_}#u$wicn+I82-@@FJ!cTTO?D&{;ko=$Cpexk{Xl&N@YXf#W%}p52 zY0Rr(gl7J-~MY*abg+17Bb-R7lbgU2w--jja{H`${fAw8i5L&%Gt=Hd;4p9?%4c zhB%A*7=_BP`q&7Mssd%;(dIHuptXz(v_x&rIPdDfqa%Fg9m8kxI?5s>2PKn;TV(&4R!F^Zy(?-0H^9A9n7yl#zpDN>A*z5c>%l34TsYf}95vGkRl=s$Em{*A% zm(MjJkM>5`o?*PDwPXgr=Ol}%UU?F$n1TNDVr>)W3Agare;}O_J{`9zVT-TaAMmG3 z7L5XQY!FiFsoflSx&EdRdj%2u^XgDAMPHn6SKhx-FTz%WsNVd21U3d4{aua0n6XpUa*wblnuLq=g8B9+$H%IC^{*{&cx>FoVKH!5@3rL*VOU|;v8u!=?tJvB77?SgmdqF zAMgGFpC!uuuv^3(Fp02JJozJ?o$Ty(#qxN+5pBlViRKCJgw~{%#M}hkiNIZF%lU*k zC*nBjT#bDlNraydu5JkYhOwIM47n|F|939pQQR>|{!{6UuO0Itvdvj9F4c70vaOct zKNmF236evLJN1$+oQCk4u$04@WafN$xu`jf@Yn0kmk08b@;Ga1WD{(0$c`rMjVhlc zJp!K+!b4d9t)P3fh(?Gu#9&%D;l>evAk?=^^7=ox9(Eu&ughWmWDWE-CHj>~*B1T( zd6S>#oiW*31=&jHrf5$@fiaEpimn~WYh^62KIBDm^w1T0uh3IE>wuUo;=lCQ-380ZkDyfV7?$!iqOij|bsuMN7s1cd zLHKsU-CSCfPyRqg+hlA%o?%~8ccy$M(c}TE(}VPKq_fR0DA}uFr~F=cvY|?<^%|g4 z@K|@_z(;Ojt$f$PU++AN`Qh3^y2oVT{P`Ok)JHg1p~aeSy`>A;e-Q@iJ%|x=Gisy@7>Uddn&VVM}z@w zI$nFGJdJqrgeco9WySK!L|*gX!P>z7?HxRHajZS+X9}!r9%Spx*n6|Amxy}MMVSuo zKOM@j|0$NA@V9@>Z{jF89rF7Sdtg(f*Bx9X_G~`WW)A}XNx-L5ea?tZoj^2uz%hJ$ zj`0cVUfb1NQ16OJQ^LTdZIGA`H(^f`Tbal}BbA%JA@(oKy54 zFKocM;az_6yJB3)`E$ED|D_?$UtRgYqj`95Eag3yVl8B5c;uh&^>Y5p@SPXxy@nWE z4uz!|m~+oB%&}#7E;n<2*3T8XO1Z*WuXFw@ia7uG0n>o>i4^Il&@WkoaOdorX2zA? zeJ9o|%p*R^7I$IK-45= z2t4>gBX(tlF}pH4_f{BQl}5H$6vxu( zD%*?$oPUBXVXGczGAK`l(Cg9D*$)Z+I!tc=41_uT8J=~OkI8hY$9i3MsnT;9=+cPw zJ3Z)bW*6uGUYPuQjL@c$*7QJ|OqgHj0zJ;U9<+D>v0O4LIY#3;m8Pq1F2f8XIx8mX)fGly{|jGFPV_vzATvv}^{C!Cqz+ z_5{-M=F~)P{`d&lBWUGL6=Uo7Z_kP8aw2TQ)`Ud5!<3+*Qt1;6J;n-jXPFU%1Zc#i}{gBw0G zxb6)2NOb!JsxRhAgMIKHvMT2kty^Gj^rcKa2wuOF~~v4hi05og>z254Ox)`UMxUfM(}4Y&QC1}X83<#$?z{k*-4Ni6F^Un;Pp$O zE0uKvmNN%E3sKJklt=&3|MZ^dj1%s0gsfM2k9UuhPxayj-Z2aLGqF{sJ^r7dJ*l(Q zQTV|s>W5^^W1cvZ_1XLg>^~i6$}a_3q{5lc&ZVgHGAB$j6T zVE>8qp;%hjZ*{sc57NW_w+i7@$fXe--{su}o!BC|yl(iSdmMWxmH7SyXh5e(Wps|~ zr)I2?;r$0U(b~Ij=WmgxY?FG(>ZCIQ0(7Egp}B|V4{0+`-VxV#Y0gl2m(FgM=M3=A zh`EAn<7~G&Y0mKJts`@WB8iptBb^e0kC%H$CztODPv(I?f_Wa_%v~!NHzWN^%`+!m zT`LQ#j=%$hx|_p)+yUgkK~)m1Imv zJu!&7a0yqQi2ELp+W@?fU%sj?oOQHvt!nU{gn65^L}MHMeb;`>j|A?N8hjZ4&f>mX z5OSz@82qcmn8TSkhB>q|xhR>1B=DpqfwjiICxl(_yQ5@cEKPoP)MhoiIhNKSon%d7 zPsh@_ZkM0(%`6%Tr@~%9Q=(&0d>@kMMtt2+HESHgIU1#zKckSUp&zT6@;Vjlw^5(J zDv!{<1o_-|0`Vx=h=*L;3;4hS)sQsh)aXkGvnjgmlKZYN_E>FHgKN3I2@pqwg z(1Z5Voa4WNAH&CAufHq@lrg!k8jxGv;hJVHZKbn6owEswc zjNzXP?05j{!d#|3l+|AC3R&3#>nt|KH%B;K#`Sanygb9y^}; z8%OKW7ubH1KcnT>h2o#!$Bf?>*nWZ^Gk#y7{2=-pQ~zOY!(FBJb&|Ize2bb;+B{cTMB#{oaO{^KeCzpeim{u@XANAur! z>OY46#!>zl`X2}UX!^fU{rN2Vf3*HF9{ADv$9Uk!j2{;`f1vu0q2F=9kD=djz>lHd zalntE-><{V>#>->&^pS2*m~xueJW}{(JzHYtm8yuX91(wABjd>jcSp@epgj&ze^EY z7gb|j^noLMPxdLkH|G@m9-Sh1qQf|R71nVs6rSiX4j&x{JjvlWd==JlF0}l4qu`_C zfM4)m!WWK$uR=dwNc}$n{@H&CPkj6({>D*0@$r8HPkcOHc-mhl9B6PhDZXd?eeCyh zw_BakGMqc=W`U&=yX`o97=JX}`HZ`X3pC@L7}?;Hox{*(g)@Zz+^~%^R;9}EOzZ=9 zuY*m@Ep(@ftAL&&oa3hd_z(-Ig&q$lveUZY&L2=2daKLdg)pJZ*i+WyVFx??R!Ll}z;~5Nv6aq>NJ|V1``-4?Hy(cGKKWb@d{5zA zN<-;k|0bM^#Ccbo0jzS|i?caS-20Y_eC~li3m(29_V#b`*b#R%Obht)3^P-uO2-^Ww%w=MR+_%zf0cY)&>4NrN477F z7t)R;54bh+|H^3+UgI>&aJC?SAE&YH7d2Hkt@Re*A3E#rwlu@H8T>@w#OgK2U?1E# zE#SuY1^D)vxK_SL`EtO{3d3&vru)3+qxX3=@F&1S&*wke+6Y{fac1uHxjldOH;>9I z9eHV1aheGz$NkQhba=>ahqDN>*8|%0Gtvm&gN)X z<+j=%K#o55YPxI#F;_|r?E34rj{eP`;S8U_d&qK;UBDe#6Z5~9mx=xW?LMpdQMR4@ zRZ{$Jt6KhUK>k^v1%mw}!A1-<(aoQ}#0i<&H7orskSYMMZ!H8?X2e(Jd=4Owsq{j8AqIwswG2i1L0$godB z-8tmJ&^NAwz9RTIsd%+&t^bwiTK})_qP|^FW1z5X@|lUmu7^?t>3AY7g) zeEyklto8p*^!fk(I{diYqqjc@8`38H_sN>yE7=z=ABS^FBFQG48z*@B_V??3e*54w zKjl?b>1yx@=E5|{4a%qd;55Ik%;%qld^y}hPCh|6&~& zct)AmJd;@#_8J6bphdztT5(~o3jR#V_Jr+gwlLVv8fLG`Z-xI9wy)K~FP#=3Un+(O z3!bGC@Tx;N0D!O5a;mh>All!timO{vG76Z^@UNptLN`G00+QB z0`Qm@Ts>Ac>D?R%Bg*BJh6)21P?6-(#$Kr81COMW4 znvBbp)38e?`dm=S8Z$|ToKLs!!FgxupNW@o>;Dh@`z~l9Ra)qMa&x*p{qz$B`7@t) z>;_*byTv1u&~G^N4qE(~H%I!Jmt=EIqM?guGZWv^Atzp0o?%~=DE^HD9-1LPU&x=G z#{|Z+w{Rw@Tff!5W}=Le1XKA zRXAHs?MMR7W~?Tg@`c_O;FroJ8h1&Ldxvkywl|+%6mTP+3OPtJVruMP8h^5c)JOv0 zXY|3tJ;A#8F4ayp*W1D@*KkN3(LY||=zNeA8~gt}5L z-}pVy#N3*uefknNeC{x@sW$<2Vv&y8yH9@)bh61Y7d$|DS5|X`{v&RZ6>1KUn9o z(}mnpCU*3a4;vM5GX2Jp`nzNQ=K-f&B&&8c_(~zvIH;_tu!*7mCw%Loqsgv zv}*cTg^|x;dM;OSjdh!UIs7QBux#@$gFTe;`uqYBI?{32a}TZXdE;YS7STq~CtgA4 zym7B5mzQ?9yR@v0&NJ)shVRHpC_FJ0?O&N-Jwd)*=)awkr$IjN3|llEz9-|mn2>Yg z#UJC&8sMI6$i&JfIZl32NRQxA{yqIZ?}r%MauK@4c}H2Ls*XjpwU^@Tsu;m}(crwJ z&sORyX7s!Ld%n=x3(ln2cLt}XEU3~Q{n>g}q1j(K++*f2{$v8Gsx7Kz=B)zh{rLDxa+&DQ9@vYJe^iX|y$4U6uh>?afV{Z+e+V^X z!`N^fIG7Y_@ed(<;YV7#20m>5V*adL=wc0jM7T4;8XiUnx^mu+km!i;@#1H=`w2KY zo!5T@@L!<~iJio6k)vsK%(PZxKz%sr9`kYNUBh`RY}IcD|3dxO3|q!rk@w^vpLDA- zE%&3A#&vJH|DqJa4ox>_h?2ZR9tQZacq@iqKJTWy9Tr_g19{EC)(dB>;Y%em`i21i zr?6vS!sI$uw4fjb?@bubIp{7gmVH)EdY3|gedjWa>z}uj7?@sBEmS@jgdZ;0bHR3m zuZxdI6wX(Xlrwhl9Xl zHDD@HSI|zZ{yE+_@8bF|??QYBeK|W(PEJ&Jl(QHL(m&?(gai0)iqba`xKzEK?mu}w z^0AEMU(_;-e_=oCg06cFt6o|p9j+%s(C)CiTIgFe9YTVWF2I_z9+43gX zwK2#8wUnfJ&Xi*JPj!`Qm%^e8^g(u!Yy}s+T$Uqrj-54F@m~9yDjI2k?8SE)r)D)K zA&$HID)A3=KBB$kKG<7ZIQRk+jk-JZb_sKWKi&ITxk9LSkgl3wQbTSsrvM)+B*Q+0 zZm5sV8@RhQa(+(nB6(aQe=eEQMH+4+?il^PB5xPwMlM+wqq!c9Kcr(a=g(HAqOTkd z^JS*HphtHwv!Rvrp*-L&CA6)$8vl}fBKfjiBP?a`aipkJ)+(T%1pCjH|GJ#?t_=<~ zWKh2yx)z$>#2q=Amh|VbguyNtna3uAIW^J&Tqo$PW_iQ&YNB z@Qo}yq{aVg@K$mct4I7P_b*DYgFrs5T3{$ha|ccn zJ@2kP2V01Qkn&fXs?zKnzM;=qJy)?I9q-t{Daeb$DN>| zQuP@}%s*v6*=%BdLB1^3B&~h#cj&MEnE%}FBw07tdpE+sqQw09(0xdT&>T2f5H!^9 z4F2K>50HD1*MG)cu|)fkJIF2vwh;c+_a)hhjz79jWj6qp;)rJvu4dWA5C zx`B^YVOroRWhYO1=`(0+59X{M%mbq$kK9*u z?;~!ytUcI`w!)rv?eukvg-g~fzGO4}1bmURf|(4kg}^`X^K-mt#3p18mAk~Xbm!}5 zZlM2C8bc#@v3I2el737$b2xUIGVCVl+9e$PC1t?|-9U2rPTn3du?BYVfBgJ?3a1jd z;K`o&jmi?vEWZ8gO(U>31CDIfDQ`_IZ}P`Mbs=6P8J`8-{pb$lhw+T^Vz@JSbYAx( zFD2SZa9mf=e=!)a#raT+^tqL50LWL}z-#_+BNS zC@FRB0&oHyk|dPZv~YGO=Ee4gbA4zzY-7>-6XsTcxYy|6x@uD?tA)q6ip>U{4fNgeMQVP~f40WHE0J#U{DuwKFCDQ2BDXsJ$jV!cjm$TDYb5L<)gJhb?_HK zI6x031fK~e1%Ek9)WH^ZJA6=X_iKVW;6-1NjI`Ut2h=E=D>Pprmy7Z#KcZ7A|1$6b zl^adE<>Wxp;Cub{ugbQg?BfD-H`wXVz?vvm^i^JR9$&UaTrvT9#PhpF6Mc{JdXDlc z9%;usW}kOrL^K$HBW_jL$q$1z!~Brqh-C@&YXaKe zs%T-<2ZV!c^uxZSH{YXnPc1^9hHQnaKZtRbxDviuz=rUWAJXZ0L^RNj^A|R%2c|1>bBlx%C{@OB&&)_hRUr)Rwfn zHMKbj{aHrg}$iK>3xn*0KRtbBAxHPxPeIw%%eNr+TzFzbdCqUcbp88_q zp^LEwRx5Dnv`>)Rb)|QyIh?X@%0QN}m)6o-S}kbfyZB#Ow8JaB&1El(m8(S`g3lQz zauJ!v_kqTdc1wJe1-tf>|oJF`gJ$N+@>v~7JN9Z8y>+~rqht`FB-X`R0PALJ6n%m5&qE_x3 z(0cAoDW2yS1#XB!7BvSAUIp$oN-oh?{O)RBF~8eU3_l)azXSXfk+G-D@Vyt}^h!wy z+0Dun7JfK4qHoMan-nX#51F0&FuB|3f6S`0lb>{IV>0B)rNFJy%o?6sbg&dMsEp(Z z;r+Qq%_ThQrxxlQ@;@Qg(9|O?Vax7solvQ8Hgj%XxQ6rm;A-BJVsd!%F_$HK^b|oD z94zs9XNQq)V37CagS>Ta!4*i;7%<0zwOH&iEyg@%I_4&!F5IzD%%55SU8A{sn|Dqq zlu`tI1yR3mqXjNT3s00_9g1}O12&ouLk>ch0ew(hylleyOz0@lyh-ahyuSQ8qEOzxpN3lC+XF63jLbebVr7^fS$Hvk(*Zt zlUqTBSj&Nqj`{WNCVfQ;)+4ySIVSgBuHHcU`d;{BHfwSBKyXH9$~+shn0r-Hr{mb> zAJ&z@`VML!zy6C3^#*4ah0 z>Fq_lO=GPbrgoi1yR_h4w7HSy-PG<02z3~L;UImGGt`RNUcB z4lDIayvMyt`lp~bSbB_G_%MI^@%M5F_i`Tee?H1gwFN!QHlsC!|1;mDy-2Qh5aX}5 zbc$1R+Gm*}>~+jSIn*u#_`+QTzIc<<--te;wA3|4_FwKUZe2mPRucTuc$~e!0y|{bcCJTR2GlR!rnpRrl1w2z0%i3VpDi~N?>a~DLAck8J}>f+ z%Lnetvdn`XO5cd~a(m~SSaC+H0y-uWvhP^a$119DzuC%DqH%Pcl2NB3^tD_k2{JgO zvsWSSO!PgUHz_X*-!x^F!@o28%#$F0zRo+8Cfb=o{Q+Lu@iOkoAU+T?kJ!6_v3l1*2S$mRjaH&!yIH68UG3}T%57W_Bu!#It9xdYl$ zS->f);WEOjAj{$gOzv#+0S3z!)kBbFm$nQ|T zHxuLSFA#4=Tve8{mBt+R4f);$Z&2E>l}DI~_iDUf(9glQPNv5IpC4CYu5qB}&;A_v z0HJ%Cs9gi$Kl}CA8`x)_=HGv4nt!i|y=Cwt$;F9Q@K*OU|9}H$H;U2&rYoxQ43N<~ z7O@+427MN;R9!CsHVJe(T~JhTmD>7A7{hjSU7|@v-7BRP8jPs+?o)o@O(X+@4w8TGY~bwr-Id-{O13ryD$Pgf2yOAz3g5b>Flb>ys$w5Y|jam(w4eqYno0e++*ZlgqwojHbNfd94Os zn%=T5aY;M8GqDazIDg@5X&Vdw{J}UfL=&%U*GqYzCA`h#J-oItxag_{86~%g3#CGcJXMJyVe!;6%~zYm!UXc zZWr}mGT{hqdUKj)5w%N=c5%h~;LlTNrSbV3i`*shy2~NU zl0SZyZf{t2Mjo%(pv@Tq{mL{AT{(S-)Bgph1{i$Og9e=0pb?@^1!%u5mcJ-&liSOd zVI0MHa3f?KkM$;Z8P;(6I=tCfBg`&c+4j*f&Q5ud4kFhPvgA(4g+Kg=XsK#Mz5v&> zP8t6Px>Fg^Ww7fp8HT+Izd-0OPKY{|Mcgy=XdCeo(VPJ?f_RGfmF7Or7XN2@+kt-+ zhoKW+YiO10M(vC70M=qEuE3ZhJ4zEfS}^h5knI;y_k#M|^g@lGNBYeJoaH$&bZ znid$tyOPkl5OsKVDRe3+qwXn^anS9!uK8xxL%P+mJL*wyqGQnnS&sTOe(@C!=X?!^ z>QQz2HlF>k2srGqE~$hJr~Rfok^g9!xDI2B7J4m>Eu`1(xMyT+nG8N9zH-OvNOf8e z$I&<7M?yL1qXxpkzr)Y3@n6#+>k{q1$?J*lnAiQ3*BhV@)IUE~&lKoe$M5_1eR=zL z%zq93Qy_o$o`v2S*rR#z^RN2i>+~#)%JbX$;__I2;_iiBtTW1MO>M|C44#P3KgO)P zzGYeRfhne|m)o4#yYB@bel_OiLk4G#8go~Ez}asBeUsdwzBZt*^+lMA^yU}uz!+fY z@tK=J_wCrbA^LBNibl7P5#al=rz4H^9o7im7I*8hF7HmM>RN!al7`m$K33trUfy@a z-U-$=K+7L|#Nm!@ra>8I=`PSb-lI%!K6If9$e=4AkIF`sy(U(6Daz(?-&3?3=TpGD zUoU?#$ri{WYDWS3_WyJC?(tDoSKs)VeI}Dh)jNm8|HS|(8IYkho1u{^%EZ+kM6kZ7rm0nwsBm_(#_ zDFhI!RDR!e&KZc~(7vDFALp~LXYaMwUVH7e*Is*XJ?M|t2UI_mPjv@J)$NU`dzw;r z#;Cd{Ds}7sP2IqgKM&;*-(y`y^c8El3%Epl@y$y70Q$^|e92*N3dvn0zgc@>XAC-V zLDq_uXYO&Bz9Y}9LmbI7(f>2?KUb95Qbu^boa&_YqHaK0D@OJ41JK7GEn9q4km-Uu z=8)D*Q676EXrgA6415>LiSpnf$Otqq>1-%7J2Cr|{o0t-;6L8VOY1Ckbe&~UM~JVH z?xG)gqw6bEiIwJo882*>d4&PIf_PQ-zk%7K!0b8xZJ4uAw{{fFnZRdAeA3UC@IiYB z?^Hp5sUBoo6Yv&hLU-0Vu19_g6Y_VX4LZgJ=m$+vcn9f4%1{<7#Csmy$7qkBC5gg< zuVFI6JoZMW+VOrtq(d;4Jm}9rocF*}emmNc8aCxkL_3JCz1FAvw$M|4ynfe0ckiko z+k{|)HpRlN+ZBGwo_PXmE%cKC{o@tA#olhV^B1HC`3knP!oUvg5bUselXdE@CAwxyh*zHfO^lY76i8%n{@Kwk%xnC>vc_@ZH4}m^==PahN>Uwhl#xKLXrjum*1k^V; z^pu?!(_4A6(+&T2_g7d)%*R+yMtQkJ?{UhT0bDep%rC!6bsDdehxD~d%6J;>8Z)4xo#jWXW2Cg`>Ws*=;vrnu4+a#>5N!OW-e4Oo;7U$Ay5`t6)Xu3@EBio_9$wVCV{v#ZU`?iSEt4ABrtHoqz6o6j z)@sx5qk0yi9$Ig&{ugC8k&d7G40~9lM}Vv((P?a5F5D|A$MIMDumZSa$nQe?(*eWo zDf&emtz$&27ojtvJ*$cTqHY!50eeI#qY7oPF03Cg=S&0~Ch@7_(gVq{vYM<7(Y#+Rf|2sv-L!)yM-N%CeW$(?#XqN1#WAemYrq-?yy`7 zIUhP$_0~%j40?6o$ZvuUl=gG=Cs`Kpd4iw%goPH_xH7MFXXgg+BNOOW|JTTQuA1Xk z!uEy@ERy7r)oAl75mI;AoR(7bmjIlR9#I!>ZF0iC7uW?j=irXh{xr?6Jl2TQ2^ZK)Za#o_YkJIip3sIT)Z4~7 zxs}FqH0MO;Ez&RSvg!>q|InI==mP7rb#pKu-w|rV9n}*gcu#+MeR!L&hfR4+CAEGV z;D-JNa55QAtf6ND&Uv(0oUddKH6Yyrf znF(C;QeV*AKx6F%8SjWkUxBB0g4VqMsx8;SJ@J*%xEC9~i+jM}C!7=RsSlbD_^#r< z=>MTT2f?eU&uJZ)34ImWtMGVJ3ww5EX}tye4O%~uJVJUok{^g?1tF(K*9SYQW!Z}Q zQsg(d)`&S!EZ-C(*=r))r;hQ$c+mq&Gn>$`Fq3AozH+)2z@W zvk#r0YwZXSoz4eNh&JQ(bCe!syj-KnHy)MyIZA)6i!vRNF4i!Nv9=62FAX!3x|``H z_E~jA+f$VGF~AYV`q~V8EbodczX01pO}|>lieZlf|HG#lWHUkc56Hj}(*kcMzV*T~=$XdYkOtU0u?C+G8NrJG9`BtR;2frwJjk7Tyl+Z( zZHJ3n{TWCfBaAnsLKnqKLeR}~?tS=7Soe-A;b3<%sUG(xyQ}&hD#kwEIkL6c2bwZM z{)4>i{`jVvV>0gkkg1gZsd;nR`vW^ zSDY3|K>R(MWjluZdtt`_yMd1YFWL8y%@N5w8E9MQMVYSR;jHOh>*C$ueVf4lNj~bw zo4UDJLo?E$VlLvK&zJ(doCb}C4m|8P&>9x&YwUMRdi32`1F+(EBwgZ5*oX0Aj5ER7 zLi;&`CA>3ocS?hJa$zmldC(DWn|v;9*lHYtO(NNZdyeq+#HYn~_ltFtP3$ZtqYcENQTrG>$&y>ny^{`L#W9G!V0ee`8 z<4QU38diV*Mw&a^{s8bt>uu6?(i-ChXNOh%pu?IBK2?#e&nDbXK|4b?{r54ha6!vH z%q@_gIH45p#=*~oLpx~Rz60f?!zN;41?1=|bVW%59=h8VHcF0xMZq}U) zJXP4depBDi3%PPriv#$Xhw>(3-<=817H1r|wb&YY<^*qHk}lvStOtg+4gFDzcPN7O zH#)fwGA?!sr8@M9jmDoIZK@J(DGqi0yclaG*y?eO#P|KsWsU*Pqy8bhFG_Nq3AzY% z<(%5}fLRc*HpN+m&UeN-UqD{YHot|=8K{>{miEHOi8h@Y@yT$rFvn-2Pt}E)J8|aO zWCuIG;3<&1|Og)VJk>>giFu zg#cd_&ax3s&oYyWtsLt#K}H~4M)6Ja-o(NibfjC*;$5t-{%&yoUbt96vbgvW){Ver zBk~YknjCm@_AJXfi*llHPsDtVezl=rZB);zi)Lq2T?b3A)%7;)_@niqef}ujEQc%= zr5S72E&iWE_r|aPc^%OR$%ZDC8tZy5#t*rM=jzfF7#D_y#S~Av>TI-+<_MxKqqQWBfi5CAPbSX+te)T`T_({pzZ7;t1HTLK zw5}}7Y)M9&j28SWc=6WI?*e-8Qg7cag~S7B4b23kbuB6;{Rg%GUes$s-)S%&Hjy85 z28Z|WDD8&`6AseJ&e?vezlGYf)r9@WgnH`hh{bu-3_AI!BBQ}k;AOha>^KuY2(ZSg zqpauXjv))Zhvcne2Y(k}x98@WdnO0=+R#sL{Vw3L!=4Z2VSKN71Mje&G z;r*hU;MYJtAp2*)>|T!WkB~M(T;= zN7@70JK6(D@3#k%*R}^{9Zd_2sX&>3fh6>)mSRfns8_--%cp=(#^*vO`?qKI=&ZDyn ziv>H}jfxtF{`eQ6Go*>B_Ljxe{$EgiGr!bagtq{Ayu) zT~XhzLT=Rz$u5ZYMH2xJ>95I#GEvYs(A#1+_U8DxnjcHD99KT0rDhGct~G?YdsTvT z_IFIzTPY-yB;em<(Q3X6ctE;8D^#@eqirAk5pSGll`C;AkYy4I3wLTSTeFrZal%R! zr@>g_3N^iCI|Tl&(m*buFwM&-t9UN*3YLU=`=GjxbjI^x=abMg`CL{>!j9xq%=D{2 z0Y=6&F<-!2NWgh!Z>ELx-ZuljO!4Q~uO~Z9@Kln|;O9iX-fL$&IZ;zj`fvt)ICPTh zeo6kLrVirm>X7=p&bnblg^$NsaPzR~YqhYaZU*{%hNV!4F&3D4fb>~U`v*~{x5(t5 z7P6YRR7Pn_aPwUp_KWydb;yi&ZREMn%k#@4D_Fx#pj}muEkE-2f4#0_A$eWL;T^SX z)WcOm2adHfTg7&+2F(8fI@dx5V8S#0&!C$nok`;Dro72GOF}k5&}DR){1{{z{stS4LXziy@)n2O5VBFLCobEB9bx<+>n*n?6 zJ@C`I=f~h(jCdY+8`*Nx+Gn;yuA-@*sA9r{7dsMx@uDlm(De$^J5%1c4VsL62FH}&wJfAt-+`s8VywN1D z%@zGZ7-efnuYmc%iuy@sV1k=W=XcPKBytg+6-txV*mSO^6aO%{jM@j6<^VePL-HJ* z0UEtNlhV{?iIw(c~iH?~eRK$wOye!nrK3kd;3l>%tbJ_}*eOB5lFN8TRQfzB~@xxJDu zq8PH%pah#t0TGSv4$&ag@gY$upD`GN*>R!!(D{17U5SL@z1*kcLBm&w2Y4( z?)eCR`LIkI!fA*5W`xfwVb9+j?imOZ-H7+XMh0!_0xy0Q>8z{Df1qoDQ?^Hf-uQ>G zVFRC~c~6*f;**Bzt`fct#fwXM0N-ueY48kGxc zVN=Nd8Quls`iJSgM#wzf=@R{dx4KO@A4Pm|OO?kl0cSq<4txIF^VzjM3(yP4LaBrF zpEo4`x8?SQPA|?LaEJ95)obA5JWziC^j#d?$8bVC0;UVv|aLp>{Fm^MH zQF_-aaoV_oZ|=Rk7X7#DvA-FdOB7s+pJUwN?4A|#=<9dNdfLcV?Dt&dx%8Hp%yS{r zzt9AEg7#lH)yUGP?@L=lVz-b;OtV(Ft`!c5y;V!fDUeuPv%g2YNmJ z#6os{`@NdrM^`@jBj-r0zfsf#lMtsBeo#a6C)bS@KbBN~qo56H#OfN8z=E6y=M1~G z0@2*ffcfl07b=Q~#?Ct2M%1`ye~Zt=Sj!De=Lv&*^2ZM zo?@I;0B;tnjq5xlTVvj1kej9>e@&m&JOy|YyK4L?Sf6^k zt+*?T@6}=6j#xYgjCfa=^yx#uIcN3t8W7I_j|%tsG;=-{w(&c&pxZTIPAau?&a#m@8SxE;Fp72%oI;~1>}7aHr}0hBl`%>Z-wEHz#oR+ zZp-nz!ia}{up40>u+f>LOvFz>{CgPZUR7}1d!_cr$67X?;reg1$5P z-heZ{!zW2g-(=$plDJjX5LkDEciCbTt-Gkk@3LzH9?uI|iO!ox?P zjeC%mU@zS1b7-D0mu&D`MSme*n0ZdyeP`hQO$KMKcGYRDxupHUR+X&;ZFGAvj-`FU z!}7l1mo?affvhfcc^XoYw?<4dm{4{G^wXweY=r*@k6V{E3O%u?WPF3#sSrFl3CJ3vQF^b}(S z+3-`8!yUx>w(^8qo0C+XhjXZ*ZlQqq{l1)?H}RH~C!RiKHCHY-?aahGjTyM%DFy2f zJ>~{cOs!`YJ$O#5KO6Kv)Qf!@OL)iPfgtWR(4t?zZF|KI&(8DSo9a9V9wXUAyi++M z^Zyiy|Ff?2$PCERw6B(Fjh3T}Th3idIg%V1Q;rwqP#MOO8h->ZZOOJ)|G~+e9Gn@n;Vm_O%r)3ZOGpeGf2w%Qu%Pi+qO{mu7Zs%S$0wG{{Vkv{)#D9<25Z;XC# z!2J8P$hq$l#=+iG=XT&9kF~^YDrxZ3Kg&PARN+8djc+#inS~36POM%`W14@D>{1k7 zfqwYIrc~!Y&?X6gxVuK~he=XDT*F@j@b{!&v!)}E2;MdY7asu#39a@gAzt4l>5x2b3sY=mn3 zc9c^>xa})(d*8=B8ZmRqT&qoI%S+0paZI#x88%J*OL*t{rJQ>=?=3Z>Zl;uxl+E2V z1>wD$RZdS%Qnms9&+oiakpfz!d4=fwi_MoRUPgV~rQ6*a@VU1jr%+zHuc2kyj)DiL zZ7q1+BFo+{4jY`C>t#7eIOlM8BD_Hfdqy1YXAoYegvIj?cPql>N|?LoaQ_tHWzqk? zaJan)+oS(qa<~iNC%O{9bhzt~HeU$~Upw5J5x!XodoGjQ$Zcb^t`SPzmAH>1DLL!R zB-KRD41SoBJn4)&IqNjT-oTCMPZl=$b=9fPk?7dMK7TgZau34>fYL+ylSFr{k|#do zZa&>rqJk|PXZH+DguY=3;pZf`b@iv0DrP)F@1su*=3)(L0!+ho7b+-Sc(=q|1YDBe zQ&!?mf!uS?N0%#f;K^x_eFpB5WuMtXO7IJeH#Pn}p!~}nE^$9obc>T=U)__VnpM4# z?wPBp$(lB+faK2_$cQP#+d(JKC;!(OEAFwl5%bGCt<`9|J9)kK$uh<;ab|2m2_Bk5maC8o)oV zB7H|H{xgVrT-YbW$Q??#Nb6o-qF18_tgmwW0z|W-@O0yLu9anCj@}Te@jq`j?TiSl zVMcb#pG-JEoTjy&UX8bY2k*O7!GU*$Ea?sX!6tAp%u|7xr=Fs63TQf0fW zrT#(Ke!h5zZ2L)YG^e+K*QeJ1OuMhkR8j@oNuOUMuo{v9s@^{;Mipn)jJap7#kS>af{QHbGx)#@t^m&;2BO(|YN(S*=WkeM+v_ zE7{YTL^bT`j9bIP?yV~93Gkw4Ynlb;PI1zS&Kiz$pvJP$`M;*U zhI@&gFX)V5{MTNP`PH95!w9ca!s5XacPql>(e%HRxEFpk-znXlgMOqtq3C{`1l-qR z6>I#jgxStd?@2}7xZ}byHHdkv@phrce;DgGZYjsj&tcU$aH&6%ll5oD2+2B|Hsg#s zoUD5cwy#>GG4QoEOZrZ`BYg+06E=bd>HKzrU_WYGhW$j)g5IVJx{&rfaEv`6PA%Au zQvWB0jeh31=ZP<%D=S2L0%T53Nao0%HxcLQ&u&b0lKx7Xn^!C2c(;@2f2d?(H-7fce1oN0{Kvyub zRO_U&?FAwuzBPZ^BJ|6D792Tga6Y|7=1ZO2U`rc#|eo|C7Z`Q~;S zSFRe;DUd8Ls&?Lywwlfk*4Knsa%nZ}AMe3kMIk=b;l15O_D28`}D!Ghvp$~ZOxT!+r~$5 z_E63P8JwBMt-Kgr2Kmcg8+Yl19K^4Uyn z=OJ3>vHnK`TS_OR@1_Q(PQw<$_Y4I^z>ikJkN94Ry8vMh;ibgq|5_r=CpxTCreRKD zpieKx(;T#`)6#}}h?x1NrN33DIeOd%(C7eU1ru=3tv(!39XX8qe9~}#56-${Y;|_E z`OP<|*69Uq%?8Xx7b*-+qY(0^ch~yWw{z#i<3rzP2Mtf~2iX(2|2;_cd&HkMvSsQg z)XUU6`GcS}4; znJ{gdH1~}5)BIrs4H29PGr4<@RLe5)@DJ!7s2WKoPQln&2prLVgPvA#Doc=|!2=`A&@(EoH-s!6Q<*8Y74_V0Z{YS4?dHR(zux_22a<`#j@1_fL8ATf(+mYd^*q?zOY+<<;-yXabi@}LAyc3))Zl{=tob(rU!PjE zkh@`*QLGEnI+?>AX=gv4wzrdhnF7GaWVWBOl?0mFh26;vT*+OMjx{22w9B z3@7Q5`;v5Hr=>~#q&}FW`>OvToyo0|?!H?u{Eu4y))@B~H!be`f+O=BezRm zN3ao0ye-F1ayQZMFy^#W&?);;S8KK>0^fJ$N6RPoo2^$QJtM>XLi9>)+p=8a^n7Hh z6=;nO-pMWDxQJD@foXoL+g&9J1yViX9RCpZnE1o|;O}uKcIJ`Hjv=H$M}s?1J%LQP zJX{-GHQXw=32=RIHE{R9O@teUtA#rRHwiA^)r_+{9?U1M8oFn0G;C(T#+@?NJ`dQ` z(D_O5VJ zb!l@4yI$JL<_`XPX=TkF^nOa*GFLTsBwR18ytzYjy|mk#I})##wz|24-dl-V-yO{z zN!LqT)7+7Ky|lH>9XDJr&Dq>R@3X|MucEnQ?Df*tHFu1QlV(Zy7mMNtH*D2Ra z1FrSgO9QS`ua^c~(_2k(>jSRSua^c~8?KiITu-=O8gNZ-JH@RJxSn*qG~hbpdTGG* zx`whmV#%UG1Xp<^3zq&6aSlWltulAeuy`Yq%`zH zym2I@p&#OnBPk925N{kwY3PS|<48(FKg1hHQX2Xp-Z+xd&=2v(k(7phh&PU;H1tEf zaU`XoAL5N8DGj_Q-guayjEC`Y`c_KAc!)Pvq%`zHys;vsp&w|h#L@(%@rQjKsn?+i zaS7(wVN)&E*w^MU2kjrmpU0%~Fz3XZ$D}mOIq~K(DGhT@ym?GY!<-Xu9+T2Q)A8mp zDeZXtc}z+>5q};doeAIXljgB_bIyF=go~JJ=a0sTjpI76gA=K|cjDtjN*joe6DjSG zjFWh9jFiNOBlNG}c=unx0r?|d-$-yk{-C~z2gl0<$B?PEY!p6Jg^+c`_%tGw2bm=v zjYw&rpX&_&0xZr6Nu7pM`&%;=lRIl?rV%5BxJkoTtZ~&?ZIJ z?tfFW=G3x9NU77TxQE3W-5Y?1V4PI|=^X8!HZ2Ql^$7*zLMolMOQq{wti!tj zzbsR|CFGNvq_|_r#eLX1$om5NX@K_7VOKFyzN_tRWv#AW*5ju2aKfK@+^aY%NB(uT zmgVGb2(>KlUA3!??qkvk8Uw8{xWm5+ijtjI%K0`z`8}T=dP9wK|LUz*1J7H_0=Hwomuy0W?~N;tjtH}n1H8S_k*qQejL{Ey@*e9uW^q(igi5*b|TjMoS@}0&@Q5xfOg;MS8<;` zkG*Be%b)di)Z@G$=@F8!x4*Soy>2qrSkO6fV((M+?7j4Jq|Y1ti?x0;(zrfvJ?S>s z*Yer+D=XxCBKsoV=|kHR-4DZERt=l)QU+TQj`M|f*>KN|o6e~@Ld?ix-+T%D*&!?R z9aDqrEu4D~;CWr3`|dOS4-;-mSGeij0{(-XyptHW1Nmm1dbmB$0bEu6so8JAKlEl> zvIXye=t9dn>8!TR)S~ahdjO?3I_V9zCdBZu0rU?1eniRKxHJPYy81>NaS=?&`ND{qitjd zf%UmN2W2fpxCn0P+txH{=XA(^)K0t7&PS-7YvZ@`@ZFaxG7mQU7oseJI}BTVs zZkS+Alwe&>unJ7dzX<rj z?d>B5=PtlTWpZa$xZkMe*WsSnkthv+UY)s)TYD`$Fe`A=U8CW+KRz6v-*u_N_Gh^- zK|^^_8dBk|!f4-8o2vmA`n2UW)Jr(q4tN}ZXDh*Tc7^*6%Y+?szqzv3j5<}o%WmDk zvIc5@?ee%|`yFYN{3%u2+<8nRF0PC}H)@Gc|K zH{I>aNKk{wJg;Jk3pg$ja&ySUu_(<5J3 zER@Gw?$x%wXI&fu4fFl@teNLCd*sQ5ZI#&Rj>hA)M@4F1K^RH((j|_lAUM42I%5xKA<`V#9Z^Y z==Lu%-4YyQQ17?uMA}KTFPeWPo}EFro5xF^~#mC1Q)?VeAd_P^@l^|C+ICS zuAi?bSos59*gf$LM(hh^c4zLihWKuZ_adI?H4XH-67@(lI~w+jEC{?yuzw$8irI92 z+P|ZGM1MHzBhj(<0Bq`kx7B@_>u6k<@E!x%%S{3QUkF?S{%f?Ww3l!}@=q?xr8}5t zjGAB@O#cxs=slm%iU&=SjktvODlSTQr!rSsi--&gPA2v8kH(sb9+7!N7?v~~Z zz)f^J^HG_eDb2GjKHa{t4s!|*rEiWWWa|eynX`mObgh}Tl=nY7+ZH)F2jrS(d z=gZ~toCq1Ao@5&b?gb^>;G9-Vi2eucGvc&S_5Qbc#Y>}cjDPmxUnANU*>Iu4P2;W$ zd=hOMp*R0TlOOvDy6NjZ-IM|&*9vF>7_8AM#QfQCpEh4Z6+ds#- zC4P#rNc1;N!A+ERkzHx)A?*JuxDi4t+)ebw_n=PVf6{+SJ2)ZJ-~G9#M?&_CrKB zj`(F4pzN?xw)9_2*}qWAZb#VzvmVH99#y8NBz~D`D02v94*&4l9AH*tLqVb`@FCb2 zr+s5Jd)DXHev1x1XTcBeptYWLu|tHN(JFadSrz)^a5jwP>>sZ5};#Xinf@^HNzoUE=FhU$o3hrOeez zT`EO>wT`Z9b^N*p)G$0zr3=R@J@V_=y$IY{|w@(k1b04b|qd~ zd##I)cLVTl1Ky)Df}tAk^vUbLT$SbIeLsPI=RcOExc8$T?lz9Yc}_Ro%eFT>Hkbg{ zYa8pQu}JrMWWfFlw$W}a>|}ll9DI5rp`p=%`^ye)8ew=-O@;rtd|S2^=dw$a*PIcO z9cL27V}TjC56LIsO`-$7yi>o_G-wApe`7+Nrox+-_<=W%pK4m9!TmM`4jb;+ZL1?W z3~T&)tvJ6}d%7)8dqE4k0LNm4{n|eDd6lSLoFya#wZeS=Pr_sUWBSy2Z{RLwUCEe{ zqzyl*(GGH3Iid2tTX3dU?NFc3fXxYX2Y5qHo$t{O_ooWIHR|EEyyo-j;0%G}EBj(< zALZBL3`7FzQTM3NQ+_r4SMy&`2gfP-DeqOBh`lvh$hp0kmqnqyF@5TAzBT)c4-MJ5 z$L8TJRo9wJcym>Kn$ib_XBt;6is`ke?f=-%JN*mvGRRK<03#;$4Cq@bsu|ZB(u|;KXI_CR+6be$3&A7?J4xS z#x2w9@=G#Zu2<+XPl=c4^6vO_`PLm+m&B}RrFnaOA{WLPf+$~|b=oNL)o9t%l(N%M zr^K6-I`vAtR)Hm;#9w$&hEZDgZ;TI1Gho>h0}G8;erw`YIL`LTa74>Js+8ORg$zfR zQs3K3d^h4TKi~A45|-BX_rzZ+&Ku3 zAS~%lKEv3N?2Oje(7SVsadwStOh}Kh8*eNx8aNh6fsKbAcQJmnWEX7z@60#h%yx!0 z>GVCTFIAXu4mR@EF8=|nbs5%IeJ+FZj>Ex#rVI1U%3W>0$J(VCHmUTUD)kNa;QXW~ zpmF-ZEC!owf%{2zLbbVUYJhAK2k+23J$7~eePnamZ;)(oB8PXixv&O!-G+DAMORHU z%&lZ2WTT@&x%yL6iFf?O+wIw^hm58Hzk2!(*uX_**U}jh58!xFSm@ln$U1Wzc>9Yv zT;l@aSRfDl`xdwh;m*f*UPyK-;`mvuVMrak-BV6OSOq4CZOSWCNX$xdS= zr&euGa2j1XwMlsEG_q~*kD4x)l_5e5#Ci_v6)rQoIXhY8)@dyQ?m;CT3(gI}UfWPf z?`~qf0a`V^z003mob2>0(%)nT-pF2!&gyYU?=L>)f3;V(abNgn^#7d~D$=(>KKwl7 z&OvwtVM$kYUhaRQ0s6>Bkmw*EbU^8zx)ts`&;a#u`R(X$=v2x73-DrwdB{m0C5mjtzUZ(%mEA@3?cMBOtD({>rVT z|H*dqRo(xb-LKns_BGva&l2Ab>Rvhf2KsF-`fDEb7u*GK=iocD+~7&8ABQx+VH%*dNk#-x+YP);nv^7aI{@23N9uKZx-k#s3#8 z+|>xrMA(4-5if?^QJch+r8&WbnHe=RHju5{12t`^FUs@i&Vzke_YakM4p@b~a5m~;jA#CVhYx%K&fc=QY*oTNRwZ{AMnty@7aF+rLH0Gglm= z%SD|fR*p+M#ckaOTEe*jKY!Sphn;3_2yeObrQsblSZk*p?!1-aUR9l6$_}&h8xUs` ztp$4@{-(l+f1rIZWfN_Ru^u7i++My}N8b0zdWQ{OZl5Cj>lc z^;3iCBjeo}mbBocji%s4*!NN%AMlxvGdovN2+G~r>K_dFcPBpSrO z>*3NkTz$gmBwnwB{cf)FG2G+~{!QYk> zWO=)Dyzh7qEJR;eMO(psHEXrTS5eDxkl_$;m(|>-r8P>bu;b) zC%S6x#+hA=Ss(O@Iifc}{k-`$`K&0d%XBL%M{WYHSnsZ4c2pi`8ezPS!~5NJed*3! zj${5UeaHOeaOcCF2=^;xp4|^zvM*ixN~fIqq!0Z#e&&w*W@5iQy{yMQHQ9WI>@JAs zlKnQtPblwklMM!VshO>mX$kY3n?EvJvRx||Y$wVtFK}|81%^11UmpXl>Rdm&)f0K| zR{iSPd32uMiMjYoQQx3NJM<#n$y+&bP-+X_Nh`OmIguJ}&npvM{<@Wyq&eU7U@H1= zOAVbF(Vn*&$(}uTgc+kSjILjg`Wfokf_ms|mFtew?$+~9-ReWQe;Lk`hOL2e>#7ra z!X54m=LUdN)G$L3v20p_kgAZ{Q<8yH)Q_aDrAj&&ixx+%upX#yL+Dh>_Of=)Yg`=?YFNHuF0<9`A2}$%GtH-?PT`_ly&gI1m{?SWe9JV<4zHh7f&Hy z6Wxoln&*N!wKJ>4vVtFiW-?)$Z~^DV#ZSlM{;;%$TM@_X>HfKWkK(=~Q@v&x3kGx2 zv$aL+!Z7|14bL2>v!v&DY(04sDG+ojdvTsbKLrHYXG_@j>rF0b^^*iUFbQ$ z)nwKO@!!R}wGBMx-z?BQe>cBFV^d!k?#DekHp2yWIQ`<|R3`4OBKknQpRGR^A{*NVq zBNZ@u9aDq8ZrqRHxIwoaY3eY$m@H^?r><VN3C$lRx|>a>_V9Z=LX=K;F7(k6)xF!y5N!>rxz~SY)0UceI~QE`pFj4 z3YYAcU2w@(*$bEKFr#pLanA+WUPi+VI!Cg%3?U!cRz~2G9VNs41!P}LcU_Pzu@x@a z4ZGlyjj$Ik*#mdNCEMQ+T(a{u+3EgWg*y#y1n&3XGThf| zglmF39j+Cw39bunCR{IEGlfxJ7TivRXTUY#{~IZc_GiOo2;Zc{&xGp&9={LQ3wIXW zPPqR8Hw5=)3M2mcBlp{x!(o^!7lI=d4Sw&bgyU>D_eZ?69C;*K z+%UVA%C;h}>XTQ4-YS{zo}&E4Dy~Y&pO5^WYOJF{r?ZfE7<0|O_2APO4-%g)#a(p@ zpWc0Xq0>zH0Z%{5PNT99^#cy?l2*Japu!$hsTRyHXMQ+WXY$D_7PI;@?#3hi>l&IJ<^>c~p=WNq^

    )T;gqIv-A27`P+!+aIUsIdV6PzTjp`ze}Ioy?%L0zA83scLOxHA zHJ{wMpi3?6D5Cx`ivJ$G%S3!G4dEH+Ck8&}smiH+t=I48F_-2d>_8pdJ)mpoK1t{1 zf=tK;WSM3(-!p;FMv&Hx`sV2De`2tMAV1Zuw&0A?z@Dq&W`sRqTmJlO^eh1EsP;Dw{o5l$Hu zRu?yeH;zh2I8_M~Txy{iyi!h=;6!+a5+;5^|EG@%HzRCN!V>(*KVeiD_X>iyUaOCA zGig+qaFa1AtOj08qr!wI^Qf>Ibd`nhedw!Zdpr2E>{l1IgGVdz@K24#7qx>|EAjAu zFB)Im4xTN;Rf#iyQojM$(-F4@VTS&t{@2%nN1TEktyozz6LoR|ubT(^lk}6Gt*T`l zXGK0bucjWl!%gwH^Sm)_nF{w%*a~P&Ol(|(cQ<7EQAeyNOxWWhx{1a~dtz84Fw{Fb z&V)EVCeDgDqN~yQT!>4cIMk^@J;S1=f%a530Ph;atED)#6t@>~i7|2Ah||Wz4I?fo zCXV_oIVR4GxEo^P?1&@!6CY9HpN@%VA-Ue?V&Y9o{O*`|s}jFA zCf=pQzYr7eRpMWYiSJb6gE8?TCI0s@@e#z&2Yx&;@wCrM@y#*uCM7-=pH?M47N0I9 zJ{F%|B|a9Pol1NxK0``;EIuPjd@Md0?6e5}SbUn4_*i^emH1eEx|H}>e0r7m*JAL~ zsl>k?6CYCIzk`3oFNlZ#9y$Iy_*de;gMTIdJNQ@Pzk`1z{yX?r;$!g{QsQIr8ByY6 z@yW2CPwk4ur%8#A#gA2qkHwD*@eAYN$E(E0;-^!IkHtesiI2rYM2U~ZgB7->RBtT3 zxs>==Jb0D(SUhwp@v(S_DDkm$#rouWW9iDI#D52GO8j^5hWK0J;Z2GE4&IdbSh@-+ z@v-=fDDmIM=hM)~$n{G2ya)H^ffqCIYO*oqhn~(0*?^5|3zuhcw3ho|6ELb zSc%^q6Hj-J;=@Y(3o-Gwu$=!TiWl5938?!cF`*&hqo?yW_OwW41$& zO8jex|FMS!TSRpb`lU5AAD+T|s5#}!Qwtkw819_Z*th4Ay~?MMZ)tv3KfK1>R3o=v zh4y!1K9}3tmS|+>ku^j2gE4!>e(h$v4d%H!q*&?3QG{ zR{|c~hryu#BK=zUZ%rj%RxWfVhy8(vQ4bGV&0)u`;(-CHe#F;1}R$@UMoy5`G^3QusaatKnY)|8Dpb;J3ps!mok90RBPv6X9P7 zKL^`ME&RFg8{toae-``#{K@dofWH#{8{jv>?}2{|{2B1?hJP&lY4D5ikAr_4{Dbh1 zhhGan=gO_s!_VM1!k-HNa@>F}S0-vhq^{xk6JhJOP5!|;pnXTX0P z{z3RB!~Z_~TvcxE6!-_=H^M&^{)6xf@K1yP0Q{Bke-C~Ueh>V(zccU#{JY_w4*zTL zi}0J^e;NKk_;CkJ;05@(4Y{>u_&eb@!k-2IbMOoB&w&3)_$%SR5&m89d*IK8|EKWp zhW{q`o8cGXzZw3m@DIZOpYXfk=Qifn=D@!Nek1&|;ol6u0Dmt0_rPBX{~Y)$;rGBl z7k(%FyWz*(YJqb2Mfm5#pA4EZfxmH}{RIe<&XiN)NM{WJ zCc+xHHn@p!tKh=UFW`fl40jLQB)HF`zA*eZ!2de<5W_t>#t^rOba%||mDU zY;OS@k2Sm#@6=+wN$tN7nlqu9UA_6srh#78%E+ z+Zor->vmgw^>b#cv(=)v@Jr~=z0gHzyFI_LEB~*d|10GGf8NDyqB6ot8KdF%;lI)F zoAEzG-*X@5Naw^=Kjb(s^p@3j)h5!{-H0?6&Xx9u_;NPr?c##c-88E+rMndP2UCK# zkdDTN{a@0Fj>1(l>@0ble40@Qen?BT*Ji5noR6fnNg+&@Apm=d4mly8n>KpNyD2JJocotf>j6J>o)hA zinU1R3e7Eha0X&F+BA%}!VF=nX%5nVk=U_&kCZR+Lv?q2l~Y*~iyRyBmsR;rgj-~vo^SGIB8FyOHj z+W$^xjU|{4b_VF2arPtWz(vRI(@W(tJzuYIlOB=AJ&kvo_a@T3SIRIiaqcj5YU=x; zBmM`!--fx3^no)m=6{Yp!`^b>Jo1zY@?3ed?X8ql>@{ZGi++N=(*W|0!m)Q`)ah>-86(-h?_ZZjOU)p8zcBr`qeNjtJ_Y^2yGJ%7;$sTjf)^8>~V;)j|7G z>)wQ22bDDpI}?=EbRa!g2YA@FpFKtJnBYqLGH_{M#s!!5Wn99~qi!mKI za@*_)nefvd&67&GJEU^cg7s3l?Mk`rO1bSyx$R21#EWP@f_M=2LEuuk4=4O_8}ot7iDGl(S=<*m zCj8TsT#J6kEyASW#CsxB-0!8+$%F#}H1jk3ji| zj^_fe{F;pOo{c%Rb-=6Hine3DyI}16aW|^wJYi1A+%tn^?H&GsTsGMis6=-SkG&^` zK4=m$B6Lq0*4horDi-4YRL^e==)>)(CrW=F_@nd}y(e%X?v~3CW!t^hFVmgnB{H8B zFN05Fe<(g}`X!#p*Ot0d{!!{~#k_U@J9?wnF7wcC?2WnZLwm#6BMRqDD98POM9b+C zt=2u}>%ut%g;pYo;aA$xED!#)D{ z8qi*FKFZJ^_2y9@Xi$a+`-Vi@wO467N1|=Ru>FKtH2WpGUMtfzk3Ce9t1=}%0r?3o z$x~HuiEe#xiC*`>CArF1xJ9DRA%ux8dGHjX$4s~+Q_|Q(YifLM5NNu>V&K8!-j$xt6pY&j=a8TZPHNNrRJuhjEsD1ph_%Yd?kGgn88n znLpk*`R0psr&z4)rG7(useHW}>jxe9ICsCfmgXte>#@8HcbART!IlIzTHZnp%FUv< z9&g=Tz{fBSW*2drc-W7tIaaEw052_UZZJar;}p4YWg)i-Yvv%|AG|78--I~6q2?9V zhr7y^d=|>L1o^(Kc_kXhFy1&pzQb^|Y&ihga&-7`O!!Dl_XTtNo1%n=V^lZ33 z9HnvK$g`?8sjAhS3vl>8031t<{}K-K7T;5w0Y`U(@2UN8H$38dieQPtwFLf13|wl0 zYvc9dQeOuyRuiPPj9;}x#o3fG6AwS5*CS`Kp3;Es^nx1l>}Q{F8)wwgy}_E~v@`u1 z5}aw`#u~5E2P)V|h_`fR6W(R|Y?bKKca=Wd3W+v-h2FZPBv$RPCF!*No`5-&q_f#{ z-IZM>x@PnR$w_Jp&EvZR&2ULRQe&e`4l>enM5M48QFh*%!yE%E@88zfB9`Y80ytM%1-HLgt0rueY`q)nCo|(JT zr8`b19LTY8qN#-ke&DwZ!Hy~yXN;bP9_$UwQRi-%naj}`wL3N3t+f6Y^{_h=exici zKiU2}sVPbc?&V;xKQuu11zhQ?6>hQ9`0l=V~saR za$gGI3WLYK@q-0U&-p#Ck}ZGaL`nmXGZ-^NWz(6fHBY+FNXc)5j&?8Q{md8q6zksE zVoDG&NM}1H0e9@TUu)8_Lg4dg}Owx>p_n-6SGB{m)qM zD?Eq7mfOI0mR5rA)LrE}Qai@}|P5I|;-0zixe`nG@ zy^`)7l|F!UBhoWQ{f~2OYnn%ebqFVq`k!=4`$wfaaX!T*!p1JlQf6A2E)8pF$qupn zp%JwLM;dr?M)8=GW`sR}%ZT!aRN|=Ij2@Q4Su=X+ zje|6--N`Q1V{fmImh}~2ap6A${-d)6R93X_X|4Tx+_k$1Vj-DsfG4p~pCOigV^PRq*^$&FZ+6O*Pd{V9O@8m02)^>05{VX0o z9i5kWDu=wnC|lRZlYe&Ruw>`@+EqK(+zYqRp@cVGb zIdtQa4GBXyIu58_i=Er#y&Lkzg_Nt~fa0fP?(y9e-eQE;rM#jBEljbibzP^Y z)@=fD72(fkze zCmUNe?)e(V+f4i;DgPg1-yR=TarS@qoXutv0-oJmxQfdrq!FnN5fL$lvu8IqK-dI= zVG|@IXwiCEa&x5-HYW*Qn#7z$K-9F^VAa;zuGE*ewYQVqO+d5=5h;ef$3YIG?$knP+C6nR(`!XP$ZH4ISPC<)Ir(I>g z(Mp9ghQ=Yr50e)ITD3QK_Qmf(M>eizd|6!e_|whRr`L?H9gp?Hogep3OixT$M|Q8O zBYWSR2Gh_QE$+GD?hWXZ7R}QA&Nh7 zxk=TPO%;-_=*q@h;=S)e=T_Qm^fo+d^kOV~qekYup|j3;fyxlC! zMwzd_Rwg`EbE6Q0yTG$^8D;$K!}vE_i1U7581H5FkGG}aO}Q<=dy^^G6u>{uf^lrJ znFiN}_E9?Y%g6AO40-GH7op47n$>tkM!55}3%-r$$5Zl(!o3 zYJE_Lny{bC*(SFm%>qgfm_LJGtsBz+D(r9Y(>qFB&7HtQ@^M2oxm=H2O}d7p*S_Kd z+;wM)o%E9tdE4{{i~>@#jo#C^>wC)PX{dt~A{wkYBJB*-ooTDmz7OKQuziwAE3k8>^#x+dcCz4&9c?HIT(XE^Mr}U>$7OFJD=|Zl`de z?3IQyuEa^jpa;bTs-Adhu8k);MR^-)H>h!&KqENBvBSpd`((@EUw#e$-G#N4{tcHkY+rZHzZdbZOK7Yi+7u-;U|xy0 zzlbp&q3cYqWQ))>Bj(SOm|uUtXUq2AjQ;$UCLv0tab&lV?(5Kdj!(jk&^e|osxAY# z)>^iK$K2)Npi}?kEbaQZJR48rUm7x2(;g{R0I&IhjPmimJ@`HMus@_@pB>h*w?)-N z9dG(ybnJDn9YLA4Iie|2&-th)tz9En%U*)q=?q+3euI1w?(kjMlK=-1H|6dI`3S;+ zk_LGI?z%GMgR8w4`Nq06$d7OYFE2e7+S~M9#@(8wcext&pY>|RZ3{@QhxLGI#P}!P z?jM*}7*ECY?+kFDMH~MC_YC66-{i{hZgCZQqkA}SgkCZh+;{M8yJbm^K0t3qGfGSi z!F;NBo2=4((8ic@_okK+?$Y>z@fa7s^2F_lI{)uGSf65qd!3B3Br}2| z9dJanRUdfjwLZ8+JEO&DZ`9r>FRR|y056=WolSkB$2!Dg4Kk@~QQE2XwkXsqiq{R8 ztJM0~qH7psZ|->9k+@Mw#aa|o6IT{f9e4Vv>eHXb)w*-z-ihvszOoJxUsQy3gXSrn zCwtSQ(yDWCR|EGnwBL_QV|y#r^{27yKd(P?g#@o?`ibclv`;Fn^fn9?T$z`&29M=` z=uGC5d#=jUj=*oi`J!22T=d4y&!)eeRV;>NX>=|_XNpm?Vx42p6sbQCt-VUi6~f`_ zD2EPXnRu67;Jc+W8@!r_HH_b{z5&9lT|_)fVETMlqr+GL5-~LMcFa^_BCKf`Ym$qGfidLnY6hU~9O zqa2ecu1~6N6!`%M#sJBN*c`m6QUkqo4R^nGpJ5Pm@P2MFgSGss?1c6xO^-Kjzkqu5 zZfe|q32qbUunzjT5m^Q4*OEN)WZ>3`Q!IL3TME2j%+j1r5%PHLA?y*ud%7tE5Baqr z9pBf^A&;g0KE};98HryLv?1uBd zzw@PZQGjiMGGjIE{pKUyJP=<+wji+|veF*>=DkcQ(fr$#iC*@>(EY^7URzs+`PpOr z)?VA}6R+;I!|7?S{lyxj?W?%5*WQo5jO?xU!fyr+#>x@tE(XyBc}3ToBrl|Mo$F(*CP^Z;H2ocaVyZzW>|lEub&bD#RbYCLZ*Ga{$hNFGOf(TL8#l{1T#W>sH+%?r^xHWz1TpmS!pkHcl_ z7;g&lZRs->^D#zf_F=_~2^X z{S@aw+enaIyMewAlRL3DhHHZGCeQPP!0Fvjhe`l)KBEOi!f+wv2Puf&N z_MLR#omxPPbV_4(Bj`zl=VAIJoA>hNRb%^e*ERTl^P2E(gx%NhmvkTb3d}M5C5^3X z_szdVT3Ua&WHy<2>lv5_+~3g$VVXyA#HVxj%U-s}^sV?Agqs|bmpghjy~-<8Lxwdv z=gkO=?;6vXyDs)ox#N*h+?{*K;7vwfK8?O>c+lj{hW{t<(^|@-eCjKb0o^W**5RA~C;s1X<=5jc%Z4R5PL)mLFZySyquC!Z?v!dNgP2L9RDMji- z@fOsvVf7rZbo45oh;CUxiyGD<{*!OV&wzYTx({$p%(((br3vc^_SLxW!k+{=Ay>D- zyY6vWZU(Ms+)-O&$KdP#l9>>`B5hS^BkIFl*l?vTSLk9n`uLE1C7$ZY70X`f)YbNU zR~-+py2=k8fZwdr`>XmaW5@a4Yh(fMUK2iWO?dt_^C0t@uy9S-c1<|%n(%kg#lj6_ zW2>`^XzW-&=_Qb?{8~9V(Yf-0!W6n!96W@xYrKPud(+S*Bmz3tf8cVr`3N5!XWTI7gG& zMQqE{&}rcUZjXj#Ut+*JMrXc0>*C$+zH@J1XCQt-1Ad{~*C8`^vwJeYH~1g@t#&eW zB6e6N9*={}Jww@nGh(Cn`OD^7=D?Km8vDv;<{yc241)KPHh=XOoW;+`mj zv3F6h@fKx=)xSh+Wnq&;f2iv<<MvKGti${)CU_EbPpHoZ1Fdz?Ei0pTOT;VtVK?v@ zu7&E5pg^XM^i*ym_B#j21#C0YvH@uUyNqoi{JY*+p2cG>tNa?q+%F*`r!kiVe3O1d z5@5I&Eze}$S)NH_^7-(89sWmn{cVV&w?Mv2&Ydul=s4^Os`q1s%gbDG2=7PO4LrCN zyGx63UpTDv*j`4(p8E?md`u0iG7^H-SD=Pt@&6?X|9yq4p@%&_PvLkw#trF=%z>K@ zcNFJ5hgU{9NcX3HkCAM-@}!%sfo%_Ib4IOJamx*x2mjKIH+Bi1sd!&?8jXb|p|Rjt z4*mvqm{`zQ;^!m#q9^~J=vWkPH{-Xv+z5-|un@4TZ?S1BW>lF3u?BB8sP@(FjJ2Km zLF~L!=#x@yG0xaI p@$VFU}fDGYK{l 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

    @v$E4(^CZtb}mV;m!3%5Wy;IU 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%0AFHL8EtS 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 z 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

    vjiVW+Kap4SCs{M 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 z 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

    L4?50a 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�~ch&SDmXq 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 M<9m7T=!3ZIC>w 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 R> (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", "